commit d5ca351c2080bc18f401ff9993e09d0289352dde Author: torger Date: Fri Jul 10 12:00:36 2015 +0200 Issue 2134: removed obsolete raw highlight preservation setting from GUI (still left in procparams for backwards compatilibility) diff --git a/.hgignore b/.hgignore new file mode 100644 index 000000000..7d0ba4c7a --- /dev/null +++ b/.hgignore @@ -0,0 +1,33 @@ +syntax: glob + +*~ +*.orig + +.cproject +.project +.settings +.directory + +CMakeFiles +Makefile +cmake_install.cmake +CMakeCache.txt + +Debug +RelWithDebInfo +MinSizeRel +Release + +rtdata/rawtherapee.desktop +rtengine/librtengine.a +rtexif/librtexif.a +rtgui/config.h +rtgui/version.h +rtgui/rawtherapee +rtgui/rawtherapee.exe +install_manifest.txt +AboutThisBuild.txt +clean + +syntax: regexp +^Win32CMakeOptions-MK1\.txt$ diff --git a/AUTHORS.txt b/AUTHORS.txt new file mode 100644 index 000000000..62b67501e --- /dev/null +++ b/AUTHORS.txt @@ -0,0 +1,58 @@ + +Project initiator: + + Gábor Horváth + +Developement contributors, in last name alphabetical order: + + Martin Burri + Javier Celaya + Jacques Desmis + Pavlov Dmitry + Oliver Duis + Maciek Dworak + Michael Ezra + Jean-Christophe Frisch + Ilias Giarimis + Steve Herrell + Philippe Hupé + Wolfgang Kuehnel + Guokai Ma + Emil Martinec + Wyatt Olson + Jacek Poplawski + Ilia Popov + Adam Reichold + Philip Rinn + Jan Rinze + Ben S. + Andrey Skvortsov + Fabio Suprani + Anders Torger + Ingo Weyrich + Makoto Yoshida + +Other contributors (profiles, ideas, mockups, testing, forum activity, translations, etc.), in last name/nickname alphabetical order: + + Marcin Bajor + Thorsten Bartolomäus + Patrik Brunner + Fernando Carello + Rodrigo Nuno Bragança da Cunha + Pat David + Reine Edvardsson + André Gauthier + Sébastien Guyader + M. Dávid Gyurkó + Arturs Jekabsons + Marián Kyral + Oscar de Lama + Lebarhon + Karl Loncarek + Jie Luo + Paul Matthijsse + Wim ter Meer + Alberto Righetto + Kostia (Kildor) Romanov + Johan Thor + Colin Walker diff --git a/AboutThisBuild.cmake b/AboutThisBuild.cmake new file mode 100644 index 000000000..330086838 --- /dev/null +++ b/AboutThisBuild.cmake @@ -0,0 +1,51 @@ +# cmakefile executed within a makefile target + +# If we find ReleaseInfo.cmake we use the info from there and don't need Mercurial to be installed +find_file(REL_INFO_FILE ReleaseInfo.cmake PATHS "${PROJECT_SOURCE_DIR}" NO_DEFAULT_PATH) +if (REL_INFO_FILE STREQUAL REL_INFO_FILE-NOTFOUND) + # we look for the hg command in this paths by order of preference + if (WIN32) + find_file(HG_CMD hg.exe HINTS ENV Path PATH_SUFFIXES ../) + elseif (APPLE) + find_file(HG_CMD hg PATHS "/opt/local/bin" "/usr/local/bin" "/usr/bin") + find_file(HG_CMD hg) + set (SHELL "/bin/bash") + else (WIN32) # Linux + find_file(HG_CMD hg) + set (SHELL "/bin/bash") + endif (WIN32) + + # Fail if Mercurial is not installed + if (HG_CMD STREQUAL HG_CMD-NOTFOUND) + message(FATAL_ERROR "hg command not found!") + else () + message(STATUS "hg command found: ${HG_CMD}") + endif () + + execute_process(COMMAND ${HG_CMD} -R "${PROJECT_SOURCE_DIR}" branch OUTPUT_VARIABLE HG_BRANCH OUTPUT_STRIP_TRAILING_WHITESPACE) + execute_process(COMMAND ${HG_CMD} -R "${PROJECT_SOURCE_DIR}" parents --template={latesttag}.{latesttagdistance} WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" OUTPUT_VARIABLE HG_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) + execute_process(COMMAND ${HG_CMD} -R "${PROJECT_SOURCE_DIR}" parents --template={node|short} WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" OUTPUT_VARIABLE HG_CHANGESET OUTPUT_STRIP_TRAILING_WHITESPACE) + execute_process(COMMAND ${HG_CMD} -R "${PROJECT_SOURCE_DIR}" parents --template={latesttagdistance} WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" OUTPUT_VARIABLE HG_TAGDISTANCE OUTPUT_STRIP_TRAILING_WHITESPACE) + if (NOT DEFINED CACHE_NAME_SUFFIX) + execute_process(COMMAND ${HG_CMD} -R "${PROJECT_SOURCE_DIR}" parents --template={latesttag} WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" OUTPUT_VARIABLE CACHE_NAME_SUFFIX OUTPUT_STRIP_TRAILING_WHITESPACE) + message(STATUS "CACHE_NAME_SUFFIX was not defined, it is now \"${CACHE_NAME_SUFFIX}\"") + elseif (CACHE_NAME_SUFFIX STREQUAL "latesttag") + execute_process(COMMAND ${HG_CMD} -R "${PROJECT_SOURCE_DIR}" parents --template={latesttag} WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" OUTPUT_VARIABLE CACHE_NAME_SUFFIX OUTPUT_STRIP_TRAILING_WHITESPACE) + message(STATUS "CACHE_NAME_SUFFIX was \"latesttag\", it is now \"${CACHE_NAME_SUFFIX}\"") + else () + message(STATUS "CACHE_NAME_SUFFIX is \"${CACHE_NAME_SUFFIX}\"") + endif () +else (REL_INFO_FILE STREQUAL REL_INFO_FILE-NOTFOUND) + include("${PROJECT_SOURCE_DIR}/ReleaseInfo.cmake") +endif (REL_INFO_FILE STREQUAL REL_INFO_FILE-NOTFOUND) + +if (VERSION_SUFFIX STREQUAL "") + set (HG_VERSION_SUFFIX "${HG_VERSION}") +else () + set (HG_VERSION_SUFFIX "${HG_VERSION} ${VERSION_SUFFIX}") +endif () + +# build version.h from template +configure_file ("${PROJECT_SOURCE_DIR}/rtgui/version.h.in" "${CMAKE_BINARY_DIR}/rtgui/version.h") +# build AboutThisBuild.txt from template +configure_file ("${PROJECT_SOURCE_DIR}/AboutThisBuild.txt.in" "${CMAKE_BINARY_DIR}/AboutThisBuild.txt") diff --git a/AboutThisBuild.txt.in b/AboutThisBuild.txt.in new file mode 100644 index 000000000..2d8cf207e --- /dev/null +++ b/AboutThisBuild.txt.in @@ -0,0 +1,14 @@ +Branch: ${HG_BRANCH} +Version: ${HG_VERSION_SUFFIX} +Changeset: ${HG_CHANGESET} +Compiler: ${COMPILER_INFO} +Processor: ${PROC_LABEL} +System: ${SYSTEM} +Bit depth: ${PROC_BIT_DEPTH} +Gtkmm: V${GTKMM_VERSION} +Build type: ${BUILD_TYPE} +Build flags: ${CXX_FLAGS} +Link flags: ${LFLAGS} +OpenMP support: ${OPTION_OMP} +MMAP support: ${WITH_MYFILE_MMAP} + diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000..55d8ef011 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,373 @@ +if (WIN32) + cmake_minimum_required(VERSION 2.8.4) + cmake_policy(SET CMP0015 OLD) +else (WIN32) + cmake_minimum_required(VERSION 2.6) +endif (WIN32) + +PROJECT(RawTherapee) + +# the default target is 'Debug' +if (CMAKE_BUILD_TYPE STREQUAL "") + set (CMAKE_BUILD_TYPE Debug CACHE STRING "One of: None Debug Release RelWithDebInfo MinSizeRel." FORCE) +endif () + +string (TOUPPER ${CMAKE_BUILD_TYPE} UPPER_CMAKE_BUILD_TYPE) + +if (UPPER_CMAKE_BUILD_TYPE STREQUAL "DEBUG") + add_definitions (-D_DEBUG) +else () + add_definitions (-DNDEBUG) + add_definitions (-D_DNDEBUG) +endif () + +message(STATUS "CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}") + +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/modules/") + +# Examples: "" = ~/.config/RawTherapee, "latesttag" = ~/.config/RawTherapee4.2, "_testing" = ~/.config/RawTherapee_testing +set (CACHE_NAME_SUFFIX "" CACHE STRING "RawTherapee's cache folder suffix") + +# By default, we don't use specific processor target, so PROC_TARGET_NUMBER is set to 0. If can specify other values to select specific +# processor targets, which list can be found in ProcessorTargets.cmake. +set (PROC_TARGET_NUMBER 0 CACHE STRING "Selected target processor from the list above (taken from ProcessorTargets.cmake)") + +# The following line set special compilation flags for RTEngine, and will be added to CMAKE_CXX_FLAGS +set (RTENGINE_CXX_FLAGS "" CACHE STRING "Special compilation flags for RTEngine") + +#loading the processor targets list +include (ProcessorTargets.cmake) +set (PROC_LABEL "undefined" CACHE STRING "Target processor label, unused if PROC_TARGET_NUMBER = 0 or 2") +set (PROC_FLAGS "" CACHE STRING "Target processor related build/link flags") +if ((NOT(PROC_TARGET_NUMBER EQUAL 0)) AND (NOT(PROC_TARGET_NUMBER EQUAL 2))) + set (PROC_LABEL ${PROC_TARGET_${PROC_TARGET_NUMBER}_LABEL}) +endif () +if (NOT(PROC_TARGET_NUMBER EQUAL 0)) + set (PROC_FLAGS ${PROC_TARGET_${PROC_TARGET_NUMBER}_FLAGS}) +endif () + +# if it exists, the PROC_FORCED_LABEL value is loaded in PROC_LABEL to override the one of ProcessorTargets +if (DEFINED PROC_FORCED_LABEL) + set (PROC_LABEL ${PROC_FORCED_LABEL}) +endif (DEFINED PROC_FORCED_LABEL) + +# adding the proc flags to the build flags +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${PROC_FLAGS}") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${PROC_FLAGS}") +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${PROC_FLAGS}") + +#stop compile on typos like std:swap (missing colon will be detected as unused label) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=unused-label") + +if (WIN32) + # we additionnally look in the MinGW path first then in the Gtkmm path, + # so if you wish to build some dependant library, you have to install them in MinGW to use them + set(CMAKE_PREFIX_PATH $ENV{MINGW_BASEPATH} $ENV{GTKMM_BASEPATH} CACHE STRING "Additional search paths") +endif (WIN32) + +if (APPLE) + if (CMAKE_CXX_COMPILER MATCHES "g\\+\\+-mp-4.[5-8]" OR + CMAKE_CXX_COMPILER_ARG1 MATCHES "g\\+\\+-mp-4.[5-8]") + set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /usr/lib/libstdc++.6.dylib") + message (STATUS "CMAKE_CXX_COMPILER is MacPorts GCC.\n CMAKE_EXE_LINKER_FLAGS: ${CMAKE_EXE_LINKER_FLAGS}") + endif () +endif (APPLE) + +option(USE_EXPERIMENTAL_LANG_VERSIONS "Build RT with -std=c++0x" OFF) +option (BUILD_SHARED "Build rawtherapee with shared libraries" OFF) +option (WITH_BZIP "Build with Bzip2 support" ON) +option (WITH_MYFILE_MMAP "Build using memory mapped file" ON) +option (OPTION_OMP "Build with OpenMP support" ON) +option (PROTECT_VECTORS "Protect critical vectors by custom R/W Mutex, recommanded even if your std::vector is thread safe" ON) +option (STRICT_MUTEX "True (recommended): MyMutex will behave like POSIX Mutex; False: MyMutex will behave like POSIX RecMutex; Note: forced to ON for Debug builds" ON) +option (TRACE_MYRWMUTEX "Trace RT's custom R/W Mutex (Debug builds only); redirecting std::out to a file is strongly recommended!" OFF) +option (AUTO_GDK_FLUSH "Use gdk_flush on all gdk_thread_leave other than the GUI thread; set it ON if you experience X Server warning/errors" OFF) + +# set install directories +if (WIN32 OR APPLE) + set (BUILD_BUNDLE ON FORCE) +endif(WIN32 OR APPLE) + +if (NOT DEFINED BUNDLE_BASE_INSTALL_DIR) + set (BUNDLE_BASE_INSTALL_DIR "${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE}") +endif (NOT DEFINED BUNDLE_BASE_INSTALL_DIR) + +if (BUILD_BUNDLE) + set (BINDIR .) + set (CMAKE_INSTALL_PREFIX "${BUNDLE_BASE_INSTALL_DIR}") +endif (BUILD_BUNDLE) + +if (NOT DEFINED BINDIR) + set (BINDIR "${CMAKE_INSTALL_PREFIX}/bin") +endif (NOT DEFINED BINDIR) + +if (NOT DEFINED DATADIR) + if (BUILD_BUNDLE) + set (DATADIR .) + else (BUILD_BUNDLE) + set (DATADIR "${CMAKE_INSTALL_PREFIX}/share/rawtherapee") + endif (BUILD_BUNDLE) +endif (NOT DEFINED DATADIR) + +if (NOT DEFINED LIBDIR) + if (BUILD_BUNDLE) + set (LIBDIR .) + else (BUILD_BUNDLE) + # Respect CMAKE_INSTALL_LIBDIR if set + if (DEFINED CMAKE_INSTALL_LIBDIR) + if (IS_ABSOLUTE "${LIBDIR}") + set (LIBDIR "${CMAKE_INSTALL_LIBDIR}") + else (IS_ABSOLUTE "${LIBDIR}") + set (LIBDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}") + endif (IS_ABSOLUTE "${LIBDIR}") + else (DEFINED CMAKE_INSTALL_LIBDIR) + set (LIBDIR "${CMAKE_INSTALL_PREFIX}/lib") + endif (DEFINED CMAKE_INSTALL_LIBDIR) + endif (BUILD_BUNDLE) +endif (NOT DEFINED LIBDIR) + +if (NOT DEFINED DOCDIR) + if (BUILD_BUNDLE) + set (DOCDIR ./doc) + else (BUILD_BUNDLE) + set (DOCDIR "${CMAKE_INSTALL_PREFIX}/share/doc/rawtherapee") + endif (BUILD_BUNDLE) +endif (NOT DEFINED DOCDIR) + +if (NOT DEFINED CREDITSDIR) + if (BUILD_BUNDLE) + set (CREDITSDIR .) + else (BUILD_BUNDLE) + set (CREDITSDIR "${CMAKE_INSTALL_PREFIX}/share/doc/rawtherapee") + endif (BUILD_BUNDLE) +endif (NOT DEFINED CREDITSDIR) + +if (NOT DEFINED LICENCEDIR) + if (BUILD_BUNDLE) + set (LICENCEDIR .) + else (BUILD_BUNDLE) + set (LICENCEDIR "${CMAKE_INSTALL_PREFIX}/share/doc/rawtherapee") + endif (BUILD_BUNDLE) +endif (NOT DEFINED LICENCEDIR) + +if (NOT DEFINED DESKTOPDIR) + if (UNIX) + set (DESKTOPDIR "${CMAKE_INSTALL_PREFIX}/share/applications") + endif (UNIX) +endif (NOT DEFINED DESKTOPDIR) + +if (NOT DEFINED ICONSDIR) + if (UNIX) + set (ICONSDIR "${CMAKE_INSTALL_PREFIX}/share/icons") + endif (UNIX) +endif (NOT DEFINED ICONSDIR) + +if (NOT DEFINED APPDATADIR) + if (UNIX) + set (APPDATADIR "${CMAKE_INSTALL_PREFIX}/share/appdata") + endif (UNIX) +endif (NOT DEFINED APPDATADIR) + +# non-bundle builds has to use absolute paths +if (NOT BUILD_BUNDLE AND + NOT (IS_ABSOLUTE "${BINDIR}" AND IS_ABSOLUTE "${DATADIR}" AND IS_ABSOLUTE "${LIBDIR}" AND + IS_ABSOLUTE "${DOCDIR}" AND IS_ABSOLUTE "${CREDITSDIR}" AND IS_ABSOLUTE "${LICENCEDIR}")) + message (FATAL_ERROR "The paths has to be absolute or use -DBUILD_BUNDLE=ON") +endif () + +# MyMutex +if (STRICT_MUTEX OR UPPER_CMAKE_BUILD_TYPE STREQUAL "DEBUG") + add_definitions (-DSTRICT_MUTEX=1) +else (STRICT_MUTEX OR UPPER_CMAKE_BUILD_TYPE STREQUAL "DEBUG") + add_definitions (-DSTRICT_MUTEX=0) +endif (STRICT_MUTEX OR UPPER_CMAKE_BUILD_TYPE STREQUAL "DEBUG") + +# MyRWMutex +if (PROTECT_VECTORS) + add_definitions (-DPROTECT_VECTORS=1) +else (PROTECT_VECTORS) + add_definitions (-DPROTECT_VECTORS=0) +endif (PROTECT_VECTORS) +if (TRACE_MYRWMUTEX) + # Note: it will be set to 0 for Debug builds (rtgui/guiutils.h) + add_definitions (-DTRACE_MYRWMUTEX=1) +else (TRACE_MYRWMUTEX) + add_definitions (-DTRACE_MYRWMUTEX=0) +endif (TRACE_MYRWMUTEX) + +if (AUTO_GDK_FLUSH) + add_definitions (-DAUTO_GDK_FLUSH=1) +else (AUTO_GDK_FLUSH) + add_definitions (-DAUTO_GDK_FLUSH=0) +endif (AUTO_GDK_FLUSH) + +# check for libraries +find_package(PkgConfig) +pkg_check_modules (GTK REQUIRED gtk+-2.0>=2.12) +pkg_check_modules (GLIB2 REQUIRED glib-2.0>=2.16) +pkg_check_modules (GLIBMM REQUIRED glibmm-2.4>=2.16) +pkg_check_modules (GTKMM REQUIRED gtkmm-2.4>=2.22) +pkg_check_modules (GIO REQUIRED gio-2.0>=2.16) +pkg_check_modules (GIOMM REQUIRED giomm-2.4>=2.12) +pkg_check_modules (GTHREAD REQUIRED gthread-2.0>=2.16) +pkg_check_modules (GOBJECT REQUIRED gobject-2.0>=2.16) +pkg_check_modules (SIGC REQUIRED sigc++-2.0) +# NOTE: The new mechanism has been tested with BUILD_SHARED = OFF +if (WIN32) + add_definitions (-DWIN32) + add_definitions (-D_WIN32) + if (MINGW) + add_definitions (-D__MINGW32__) + endif (MINGW) + if (CMAKE_SIZEOF_VOID_P EQUAL 4) + add_definitions (-DWINVER=0x0501) + endif (CMAKE_SIZEOF_VOID_P EQUAL 4) + set (EXTRA_LIB "-lws2_32 -lshlwapi") +endif (WIN32) +# you may need lcms v1.xx for older version : pkg_check_modules (LCMS REQUIRED lcms<=1.99) +pkg_check_modules (LCMS REQUIRED lcms2) +find_package (EXPAT REQUIRED expat>=2.0) +pkg_check_modules (FFTW3F REQUIRED fftw3f) +pkg_check_modules (IPTCDATA REQUIRED libiptcdata) +pkg_check_modules(FFTW3 fftw3) +find_package (JPEG REQUIRED) +find_package (PNG REQUIRED) +find_package (TIFF REQUIRED) +find_package (ZLIB REQUIRED) + +# link witz bzip +if (WITH_BZIP) + find_package(BZip2) + if (BZIP2_FOUND) + add_definitions (-DBZIP_SUPPORT) + set (EXTRA_INCDIR ${EXTRA_LIB} ${BZIP2_INCLUDE_DIR}) + set (EXTRA_LIB ${EXTRA_LIB} ${BZIP2_LIBRARIES}) + endif (BZIP2_FOUND) +endif (WITH_BZIP) + +#Check for libcanberra-gtk (sound events on Linux) +if (UNIX AND (NOT APPLE)) + pkg_check_modules (CANBERRA-GTK REQUIRED libcanberra-gtk) +endif (UNIX AND (NOT APPLE)) + +if (WITH_MYFILE_MMAP) + add_definitions (-DMYFILE_MMAP) +endif (WITH_MYFILE_MMAP) + +if (OPTION_OMP) + find_package(OpenMP) + if (OPENMP_FOUND) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS} -Werror=unknown-pragmas") + endif (OPENMP_FOUND) +endif (OPTION_OMP) + +if(USE_EXPERIMENTAL_LANG_VERSIONS) + SET (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu1x") + SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++0x") +endif (USE_EXPERIMENTAL_LANG_VERSIONS) + +# 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) +set (OUT_OF_SOURCE_BUILD TRUE) +if (ABS_SOURCE_DIR STREQUAL ABS_BINARY_DIR) + set (OUT_OF_SOURCE_BUILD FALSE) + message (WARNING "You are performing an in-source build. This is discouraged. For an explanation and the advantages of out-of-source builds, please refer to http://www.cmake.org/Wiki/CMake_FAQ#What_is_an_.22out-of-source.22_build.3F") +endif () + +# XXX remove files triggering the below check to prevent every developer from +# needing manual manual work. We will remove this after some time to have a +# clean build system without file modifications in the source tree again. +set(OOSB_FILES "${PROJECT_SOURCE_DIR}/rtdata/rawtherapee.desktop" "${PROJECT_SOURCE_DIR}/rtgui/version.h" "${PROJECT_SOURCE_DIR}/rtgui/config.h" "${PROJECT_SOURCE_DIR}/AboutThisBuild.txt") +if (OUT_OF_SOURCE_BUILD) + foreach(f ${OOSB_FILES}) + file (REMOVE "${f}") + endforeach(f) +endif () + +# check for generated files in the source tree which should not be there when +# doing out of source builds. Without checking for this it might happen that old +# versions are used for the compilation +if (OUT_OF_SOURCE_BUILD) + foreach(f ${OOSB_FILES}) + if (EXISTS "${f}") + message (SEND_ERROR "Generated \"${f}\" found inside the source tree. Please remove it as it is a relic of the old build system and prevents valid compilation now.") + endif () + endforeach(f) +endif () + +## BEGIN: Generating AboutThisBuild.txt +# set the bit number information of the platform +if (CMAKE_SIZEOF_VOID_P EQUAL 4) + set(PROC_BIT_DEPTH 32 bits) +elseif (CMAKE_SIZEOF_VOID_P EQUAL 8) + set(PROC_BIT_DEPTH 64 bits) +endif (CMAKE_SIZEOF_VOID_P EQUAL 4) + +# Get comiler name and version +# only cmake > 2.8.7 knows CMAKE_*_COMPILER_VERSION +if (CMAKE_VERSION VERSION_GREATER 2.8.7) + get_filename_component(COMPILER_INFO ${CMAKE_C_COMPILER} NAME_WE) + set(COMPILER_INFO "${COMPILER_INFO} ${CMAKE_C_COMPILER_VERSION}") +else () + execute_process(COMMAND gcc -dumpversion OUTPUT_VARIABLE GCC_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) + set(COMPILER_INFO "gcc ${GCC_VERSION}") +endif () + +# Get c++ and linker flags for rtengine (the gui's c++ flags may have less flags) +set(CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${UPPER_CMAKE_BUILD_TYPE}} ${RTENGINE_CXX_FLAGS}") +set(LFLAGS "${CMAKE_EXE_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS_${UPPER_CMAKE_BUILD_TYPE}}") + +set(ABOUT_COMMAND_WITH_ARGS ${CMAKE_COMMAND} + -DPROJECT_SOURCE_DIR:STRING=${PROJECT_SOURCE_DIR} + -DCACHE_NAME_SUFFIX:STRING=${CACHE_NAME_SUFFIX} + -DPROC_LABEL:STRING="${PROC_LABEL}" + -DPROC_BIT_DEPTH:STRING="${PROC_BIT_DEPTH}" + -DBUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} + -DVERSION_SUFFIX:STRING=${VERSION_SUFFIX} + -DGTKMM_VERSION:STRING=${GTKMM_VERSION} + -DOPTION_OMP:STRING=${OPTION_OMP} + -DWITH_MYFILE_MMAP:STRING=${WITH_MYFILE_MMAP}) + +if (WIN32) + list(APPEND ABOUT_COMMAND_WITH_ARGS -DSYSTEM:STRING=Windows + -DCXX_FLAGS:STRING="${CXX_FLAGS}" + -DLFLAGS:STRING="${LFLAGS}" + -DCOMPILER_INFO:STRING="${COMPILER_INFO}") +elseif (APPLE) + list(APPEND ABOUT_COMMAND_WITH_ARGS -DSYSTEM:STRING=Apple + -DCXX_FLAGS:STRING=${CXX_FLAGS} + -DLFLAGS:STRING=${LFLAGS} + -DCOMPILER_INFO:STRING=${COMPILER_INFO}) +else (WIN32) + list(APPEND ABOUT_COMMAND_WITH_ARGS -DSYSTEM:STRING=Linux + -DCXX_FLAGS:STRING=${CXX_FLAGS} + -DLFLAGS:STRING=${LFLAGS} + -DCOMPILER_INFO:STRING=${COMPILER_INFO}) +endif (WIN32) + +list(APPEND ABOUT_COMMAND_WITH_ARGS -P "${PROJECT_SOURCE_DIR}/AboutThisBuild.cmake") + +add_custom_target(AboutFile ALL + COMMAND ${ABOUT_COMMAND_WITH_ARGS} + COMMENT "Creating the about file") + +add_dependencies(AboutFile Debug Release MinSizeRel RelWithDebInfo) +## END: Generating AboutThisBuild.txt + +install (FILES AUTHORS.txt DESTINATION "${CREDITSDIR}") +install (FILES LICENSE.txt DESTINATION "${LICENCEDIR}") +install (FILES "${CMAKE_BINARY_DIR}/AboutThisBuild.txt" DESTINATION "${CREDITSDIR}") +install (FILES RELEASE_NOTES.txt DESTINATION "${CREDITSDIR}" OPTIONAL) +if (WIN32) + install (DIRECTORY "licenses" DESTINATION "${LICENCEDIR}") +endif (WIN32) +if (UNIX) + install (FILES "${PROJECT_SOURCE_DIR}/doc/manpage/rawtherapee.1" DESTINATION "${CMAKE_INSTALL_PREFIX}/share/man/man1") + install (FILES rawtherapee.appdata.xml DESTINATION "${APPDATADIR}") +endif (UNIX) + +add_subdirectory (rtexif) +add_subdirectory (rtengine) +add_subdirectory (rtgui) +add_subdirectory (rtdata) diff --git a/COMPILE.txt b/COMPILE.txt new file mode 100644 index 000000000..ca92350d8 --- /dev/null +++ b/COMPILE.txt @@ -0,0 +1,500 @@ +If you have problems with the compilation, please ask on the appropriate +RawTherapee forum: http://www.rawtherapee.com/forum/viewforum.php?f=10 + +PREAMBLE +-------- + + Some commands span multiple lines, each line of such a command except for the + last one will end in a backslash character, "\". + When copying code, be sure to copy all lines from the first one that ends in \ + till the last line that does not end in a \ character. + + Some parts of code contain . Replace these with whatever + value is needed, e.g. + + CMake is actually used to create the makefiles (scripts that handle the build + process) or specific Integrated Developement Environement (IDE) projects. It + is designed to find all necessary compilation flags for your specific machine, + but everything can be overriden. + + RawTherapee's build mechanism will generate a build information file, named + "AboutThisBuild.txt", and require some parameters that can't be set by CMake, + so it's done in our build script, and may be overridden at your own will. The + build process also enables some sort of cross-compiling, since you can only + choose a specific processor variation of the same type (e.g. core2, athlon64, + which are both an x86 architecture). Real cross-compiling (e.g. building the + Windows version on a Linux platform) has not been tested. + + By default, no processor is specified, so CMake/GCC will build RT for your + machine's processor. You can specify that the build is to be made for a + generic processor by using the -DPROC_TARGET_NUMBER="1" CMake option. + Developers who are providing builds for download from the RawTherapee website + have to set the processor label (a human-readable description of the + processor, set to "undefined" by default) manually with the -DPROC_LABEL="foo" + CMake parameter. + + Note for developers that handle an automated build system: Mercurial is + required in order to produce the build information file, but your build system + will certainly only use the source code without any access to a Mercurial + repository. To generate the needed information, run the script: + ./tools/generateReleaseInfo + After that, you can delete .hg* (the example below uses "-X *.hg*" to exclude + those files and folders instead of deleting them - the end result is the same) + and continue with the normal compile instructions without the need for + mercurial. + + In short, once you cd into your clone of the RawTherapee source code + repository, using version "4.1" as an example: + 1. Check out the desired hg tag: hg update "4.1" + 2. Run tools/generateReleaseInfo to generate ReleaseInfo.cmake: + ./tools/generateReleaseInfo + 3. The repository is now ready to be made into a public tarball: + ./tools/generateSourceTarball + + The build system especially encourages to perform out-of-source builds. This + means that the CMake project is generated in a folder which is not in the + source tree of RawTherapee. This way the source tree stays clean all the time + and multiple different compilation settings can be maintained in parallel + using different binary folders. Further information about out-of-source builds + can be found here: + http://www.cmake.org/Wiki/CMake_FAQ#What_is_an_.22out-of-source.22_build.3F + + If an in-source build is performed, the CMake logic now warns about this but + does not fail. Especially important for clean out-of-source builds is that the + CMake code does not generate files inside the source tree, e.g. when using + configure_file. Please keep this in mind when altering the CMake files. + + +DEPENDENCIES +------------ + + PACKAGE URL + BZIP2 bzip2>-1.0.4 http://www.bzip.org/ + EXIV2 exiv2>=0.19 http://www.exiv2.org/ + EXPAT expat>=2.1.0 http://expat.sourceforge.net/ + FFTW fftw>=3.2.2 http://fftw.org/ + GCC gcc>=4.7 http://gcc.gnu.org/ + GLIB2 glib-2.0>=2.24 http://www.gtk.org/ + GLIBMM glibmm-2.4>=2.24 http://www.gtkmm.org + GTK+ gtk+-2.0>=2.24.18 http://www.gtk.org/ + GTK2-Engines gtk-engines-2.20.2 http://www.gtk.org/ + GTKMM gtkmm-2.4>=2.22 http://www.gtkmm.org + JPEG libjpeg>=6b http://libjpeg-turbo.virtualgl.org/ + http://jpegclub.org/ + http://www.ijg.org/ + LCMS2 lcms>=2.0a http://www.littlecms.com/ + LIBCANBERRA libcanberra-gtk http://0pointer.de/lennart/projects/libcanberra/ (Linux only) + LIBIPTCDATA libiptcdata>=1.0.2 http://libiptcdata.sourceforge.net + PNG libpng>=1.2.44 http://www.libpng.org/ + SIGC sigc++-2.0 http://libsigc.sourceforge.net/ + TIFF libtiff>=3.9.4 http://www.remotesensing.org/libtiff/ + ZLIB zlib>=1.2.3 http://www.zlib.net/ + + +WINDOWS +------- + + OPTIONAL + + - TortoiseHG + You can make your life a little easier by using a graphical client for + working with Mercurial. One such free and open-soure cross-platform + client is TortoiseHG, you can get it bundled with Mercurial from: + http://tortoisehg.bitbucket.org/ + + - Weird compressed archive formats? + You might need to unpack archives in formats which Windows does not + handle by default. That's no problem, there are a few free programs out + there which handle many more formats than Windows does, and faster too. + We recommend: + http://www.7-zip.org/ + http://peazip.sourceforge.net/ + + + THE TOOLCHAIN + + This document assumes that you install MinGW, CMake and gtkmm respectively + to "C:\MinGW64" (or "C:\MinGW32" for 32-bit), "C:\CMake", and "C:\gtkmm64" (or + "C:\gtkmm" for 32-bit). + These packages must be installed in paths that DO NOT CONTAIN SPACES. + + INSTALL THE TOOLCHAIN + - TDM-GCC On-Demand Installer + http://tdm-gcc.tdragon.net/download + GCC 4.9 is recommended for Win64 builds, as under some conditions older + versions of GCC can cause artifacts. + Download the "tdm-gcc-webdl" option. Run it, select "Create a new + TDM-GCC installation" and choose the appropriate option for your + machine: "MinGW/TDM (32-bit)" if you use a 32-bit machine, or + "MinGW-w64/TDM64 Experimental (32-bit and 64-bit)" if you use a 64-bit + machine. Even though the 64-bit version contains a 32-bit version too, + we had no luck making 32-bit RT builds using it at the time of writing. + Be sure to install with OpenMP support (Components > gcc > openmp). + + - CMake + http://www.cmake.org/cmake/resources/software.html + Use "Windows (Win32 Installer)", the newest version. + + - >=GTK+ 2.24.18 + http://hexchat.github.io/gtk-win32/ + + - gtkmm-2.24 + http://sourceforge.net/projects/gtk-mingw/files/gtkmm2/ + + + INSTALL THE DEPENDENCIES + + RawTherapee depends on additional build-time libraries. There are two ways + you can get these libraries: + - The easy way, you can use the pre-compiled ones available from: + http://www.rawtherapee.com/releases_head/windows/dependencies_for_creating_builds/ + Just unzip them to the base installation dir of MinGW, which should be + C:\MinGW64 if you followed the instructions to the letter. + + Note that this archive might not contain all of the required + libraries. If compilation fails due to missing libraries, then see the + dependency list at the beginning of this document, find the missing + ones, and see below for instructions on where to download them from + and how to install them. Please notify us so that we may update the + archive. + + - The hard way, you will need to download the source code for each and + compile each yourself. See further below for instructions. + + + SET UP THE TOOLCHAIN ENVIRONMENT VARIABLES + + The toolchain installers should have set up some environment variables + for you automatically, but some will be missing. Fire up: + System Properties > Advanced > Environment Variables + + Make sure you have the relevant ones, and that they point to the correct + places: + GTKMM_BASEPATH = "C:\gtkmm" + GTKMM64_BASEPATH = "C:\gtkmm64" + MINGW_BASEPATH = "C:\MinGW64" + PKG_CONFIG_PATH = "C:\MinGW64\lib\pkgconfig;c:\gtkmm64\lib\pkgconfig" + and that PATH contains "C:\gtkmm64\bin;C:\MinGW64\bin;C:\CMake\bin;" + (or the 32-bit counteparts) + + Restart your console to be sure the changes took effect. + + + COMPILE + - Clone or update the RawTherapee repository + You can use TortoiseHG to clone and update the repository, or you can + do it from the command line: + hg clone https://rawtherapee.googlecode.com/hg/ "C:\rtrepo" + If you have already cloned it before, update it: + cd C:\rtrepo + hg pull + hg update -C default + + - Tailor the buildRT.bat batch file to your needs + Copy C:\rtrepo\tools\buildRT.bat to C:\buildRT.bat so that you can make + changes to it and not lose them when you update the repository. + + Edit C:\buildRT.bat and customize as follows: + - If you are building RT for yourself, use + "-DPROC_TARGET_NUMBER:STRING=2" + - If you are building RT to be distributed to other people, use + "-DPROC_TARGET_NUMBER:STRING=1" + - If you want to upload a build, you should set some additional + information about your processor. There are two possibilities: + 1. You pick up a target processor from "ProcessorTargets.cmake". + All you have to do is set the PROC_TARGET_NUMBER parameter + to the desired target number. If you choose the "native" + solution, you have to set the processor label manually + by setting the PROC_LABEL parameter. Please provide a short name, + like "core i5" or "athlon64". Processor frequency is of no use. + 2. You don't need specific processor flags, so you'll let + PROC_TARGET_NUMBER default to 0, but you have to set the + PROC_LABEL parameter. Please provide a short name, like "core i5" + or "athlon64". Specifying the processor frequency is of no use. + + - Run buildRT.bat to compile RawTherapee + C:\buildRT.bat + + + DEPENDENCIES - THE HARD WAY + + The MSYS package is required to build the libraries. Before building them, + check if they are already installed in your gtkmm and MinGW directories. + There shouldn't be two versions of the same library in different places. + + Open an MSYS console, that will create a Linux environment, and compile + the dependencies in the following order: + zlib: + If you have gtkmm-2.22 installed, you should skip this zlib section. + - Download: http://zlib.net/ + - How to build: + cd to the directory you unpacked zlib-1.2.5 to, + make -f win32/Makefile.gcc + + Then, manually copy the files as follows (tip: you can individually + copy the lines below and paste them in MSYS' prompt with the middle + mouse button): + cp -iv zlib1.dll /mingw/bin + cp -iv zconf.h zlib.h /mingw/include + cp -iv libz.a /mingw/lib + cp -iv libzdll.a /mingw/lib/libz.dll.a + + libpng: + If you have gtkmm-2.22 installed, you should skip this libpng section. + - Download: http://sourceforge.net/projects/libpng/files/ + - How to build: + cd to the directory you unpacked lpng144 to. + There are two methods of building libpng: + 1. gtkmm doesn't provide zlib so compile it yourself: + cmake -G "MSYS Makefiles" -DCMAKE_INSTALL_PREFIX:PATH=/mingw -DCMAKE_BUILD_TYPE:STRING=Release + 2. gtkmm provides zlib so you can reuse it (assuming that you + hadn't compiled zlib as explained above): + cmake -G "MSYS Makefiles" -DCMAKE_INSTALL_PREFIX:PATH=/mingw -DCMAKE_PREFIX_PATH:PATH=C:/gtkmm -DCMAKE_BUILD_TYPE:STRING=Release + + Then build and install: + make + make install + + libjpeg: + - Download: http://www.ijg.org/ + - How to build: + cd to the directory you unpacked jpeg-8b to. + ./configure --prefix=/mingw + Copy jconfig.txt to jconfig.h (overwrite the existing file). + make + make install + + libtiff: + - Download: ftp://ftp.remotesensing.org/pub/libtiff/ + - How to build: + In the configure process below, set the zlib include and lib path to + the right folder. We're assuming that you're using the one provided + in the gtkmm bundle. + ./configure --prefix=/mingw --with-zlib-include-dir=/c/gtkmm/include --with-zlib-lib-dir=/c/gtkmm/lib + make + cd libtiff + make install + + libiptcdata: + - Download: http://libiptcdata.sourceforge.net/ + - How to build: + ./configure --prefix=/mingw + + Edit the "Makefile" file from the root dir of libiptcdata and + search for "DIST_SUBDIRS =" and "SUBDIRS =". You should only find + one line for each search. From these lines, remove "iptc", then: + make + make install + + LCMS: + - Download LCMS2 + http://sourceforge.net/projects/lcms/files/ + - How to build: + ./configure --prefix=/mingw + make + make install + + Expat: + - Download: http://expat.sourceforge.net/ + - Install + + FFTW: + - Instructions: http://www.fftw.org/install/windows.html + - Specific instructions more suitable for RawTherapee purposes: + 1. Download the official FFTW-64 DLL package from + http://www.fftw.org/download.html + Unpack it to C:\fftw3\ + 2. Start MSYS console and go to your FFTW3 directory + cd /c/fftw3 + 2. In MSYS console, execute: + dlltool --def libfftw3f-3.def --dllname libfftw3f-3.dll --output-lib libfftw3f-3.a + dlltool --def libfftw3l-3.def --dllname libfftw3l-3.dll --output-lib libfftw3l-3.a + dlltool --def libfftw3-3.def --dllname libfftw3-3.dll --output-lib libfftw3-3.a + 3. Copy files: + cp libfftw3f-3.dll /c/MinGW64/bin + cp libfftw3l-3.dll /c/MinGW64/bin + cp libfftw3-3.dll /c/MinGW64/bin + cp libfftw3f-3.a /c/MinGW64/lib + cp fftw3.h /c/MinGW64/include + 4. Create a new text file MinGW64/lib/pkgconfig/fftw3f.pc with the + following contents: + prefix=/mingw64 + exec_prefix=${prefix} + libdir=${exec_prefix}/lib + includedir=${prefix}/include + Name: fftw3f + Description: FFTW3 Float + Version: 3.3 + Libs: -L${libdir} -lfftw3f-3 -lm + Cflags: -I${includedir} + + + IMPORTANT + + Make sure that the lcms.pc and libiptcdata.pc files located in the + pkgconfig dir have the first line like this: + prefix=/mingw + + If everything has been installed correctly, you should see lines like + the following when running the cmake command (see "COMPILE" below): + -- checking for module 'libiptcdata' + -- found libiptcdata, version 1.0.4 + -- checking for module 'lcms2' + -- found lcms2, version 2.3 + -- Found JPEG: C:/mingw/lib/libjpeg.dll.a + -- Found ZLIB: C:/gtkmm/lib/libz.dll.a + -- Found PNG: C:/gtkmm/lib/libpng.lib + -- Found TIFF: C:/mingw/lib/libtiff.dll.a + + +LINUX +----- + + DEPENDENCIES + + See the list of dependencies at the beginning of this document. + + In Arch, run: + sudo pacman -S bzip2 exiv2 expat fftw glib2 glibmm gtk gtkmm lcms2 \ + libcanberra libiptcdata libjpeg-turbo libpng libsigc++ libtiff zlib + + In Fedora, run: + sudo yum install bzip2-devel cmake exiv2-devel expat-devel fftw-devel \ + gcc-c++ glib2-devel glibmm24-devel gtk+-devel gtk2-engines gtkmm24-devel \ + lcms2-devel libcanberra-devel libiptcdata-devel libjpeg-turbo-devel \ + libpng-devel libsigc++20-devel libtiff-devel zlib-devel + + In Gentoo, run: + sudo emerge -uva app-arch/bzip2 dev-cpp/glibmm dev-cpp/gtkmm \ + dev-libs/expat dev-libs/glib dev-libs/libsigc++ dev-vcs/mercurial \ + media-gfx/exiv2 media-libs/lcms media-libs/libcanberra \ + media-libs/libiptcdata media-libs/libjpeg-turbo media-libs/libpng \ + media-libs/tiff net-misc/curl sci-libs/fftw sys-libs/zlib x11-libs/gtk+ \ + x11-themes/gtk-engines + + In openSUSE, run: + sudo zypper in cmake fftw3-devel gcc-c++ glib2-devel glibmm2-devel \ + gtk2-devel gtkmm2-devel libbz2-devel libcanberra-devel libexpat-devel \ + libiptcdata-devel libjpeg-devel liblcms2-devel libpng-devel \ + libsigc++2-devel libtiff-devel zlib-devel + + In Ubuntu/Debian the requirements can be installed by running: + sudo apt-get update && sudo apt-get install build-essential cmake curl \ + libbz2-dev libcanberra-gtk-dev libexiv2-dev libexpat-dev libfftw3-dev \ + libglibmm-2.4-dev libgtk2.0-dev libgtkmm-2.4-dev libiptcdata0-dev \ + libjpeg8-dev liblcms2-dev libpng12-dev libsigc++-2.0-dev libtiff4-dev \ + mercurial zlib1g-dev + + + COMPILE + + The Automatic Way: + The easiest way compile RawTherapee is by using the buildRT script, read + all about it in the forum: + http://rawtherapee.com/forum/viewtopic.php?p=22213#p22213 + + The Manual Way: + - Create and enter a new empty folder outside RawTherapee's source + directory: + mkdir ~/rt-build + cd ~/rt-build + - Type: + cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=./release \ + -DBINDIR=. -DDATADIR=. -DLIBDIR=. + Developers who want to provide a public build have to set the PROC_LABEL + to their processor name, e.g.: + cmake -DPROC_LABEL:STRING=athlon64 -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=./release -DBINDIR=. -DDATADIR=. -DLIBDIR=. \ + + - Type: + make install + - You'll find the compiled program in the subdirectory named like the + value of CMAKE_BUILD_TYPE ("Release" in this example). You can copy it + anywhere you want. By changing the cmake flags, you can change where + the release will compile to. By removing all flags it should go to the + standard system install location. + + You're done. + + + Using Eclipse under Linux: + + Eclipse mercurial plugin: Click "Help > Install New Software". + The Eclipse Update Site for MercurialEclipse is available at this URL: + http://cbes.javaforge.com/update + + Import the RawTherapee Mercurial repository: + "File > new > other > mercurial > Clone existing repository" + Enter this URL: + https://rawtherapee.googlecode.com/hg + + Create and enter a new empty folder outside RawTherapee's source directory. + Configure the source for Eclipse with: + cmake -G "Eclipse CDT4 - Unix Makefiles" -DCMAKE_INSTALL_PREFIX=./release -DBINDIR=. -DDATADIR=. -DLIBDIR=. -DCMAKE_BUILD_TYPE=Release + + If you want to upload a build, you should set some additional information + about your processor. There are two possibilities: + 1. You pick up a target processor from "ProcessorTargets.cmake". All you + have to do is set "-D PROC_TARGET_NUMBER:STRING=number" in cmake's + command line to the desired target number. If you choose the 'native' + solution, you have to set the processor label manually by setting "-D + PROC_LABEL:STRING=procLabel" in cmake's command line. Please provide a + short name, like "core i5" or "athlon64" (without double quotes). + Processor frequency is of no use. + 2. You don't need specific processor flags, so you'll let + PROC_TARGET_NUMBER default to 0, but you still have to set the + PROC_LABEL parameter (see point 1 righ above). + + Eclipse does not do 'make install', but only 'make all'. + There are two ways to compile: + 1. type 'make install' in the console or, + 2. in "Project > properties > C/C++ Make Project > Build (incremental + build)" change 'all' to 'install'. + +OS X +---- + + REQUIREMENTS + + - XCode Development Tools (you only need a subset of these, but it is + probably easier to just install all of them) + - MacPorts + - To install the dependencies, run: + sudo port install cairo +quartz -x11 pango +quartz -x11 gdk-pixbuf2 -x11 gtk2 +quartz libsigcxx2 gtk-osx-application +no_python + - gtkmm port will fail to install. Use `-s’ option. + sudo port -s install gtkmm + - To install other dependencies and tools. + sudo port install gtk-engines2 lcms2 libiptcdata fftw-3-single cmake gcc47 + - If you don't already have Mercurial installed, run: + sudo port install mercurial + + + COMPILE + + - Make build directory. + mkdir build + cd build + - To enable OpenMP, assuming you have installed gcc47), type: + cmake -D CMAKE_C_COMPILER=gcc-mp-4.7 -D CMAKE_CXX_COMPILER=g++-mp-4.7 \ + + + If you want to upload a build, you should set some additional information + about your processor. There are two possibilities: + 1. You pick up a target processor from "ProcessorTargets.cmake". All you + have to do is set "-D PROC_TARGET_NUMBER:STRING=number" in cmake's + command line to the desired target number. If you choose the 'native' + solution, you have to set the processor label manually by setting "-D + PROC_LABEL:STRING=procLabel" in cmake's command line. Please provide a + short name, like "core i5" or "athlon64" (without double quotes). + Processor frequency is of no use. + 2. You don't need specific processor flags, so you'll let + PROC_TARGET_NUMBER default to 0, but you still have to set the + PROC_LABEL parameter (see point 1 righ above). + + - Type: + make install + - Type: + make macosx_bundle + - You will find a disk image in the build directory; this is the + distribution release and can be run on any machine which meets the + architecture requirements you specified in variants.conf earlier. diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 000000000..cb8d823a1 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,640 @@ + + RawTherapee + + +Copyright ©2004-2012 Gábor Horváth + +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 below for more details. + + + + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + + Copyright ©2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS diff --git a/ProcessorTargets.cmake b/ProcessorTargets.cmake new file mode 100644 index 000000000..aa06b29ee --- /dev/null +++ b/ProcessorTargets.cmake @@ -0,0 +1,36 @@ +# We have to create a label variable if we want to display it in AboutThisBuild.txt... + +# This first choice should be used for official releases +set(PROC_TARGET_1_LABEL generic x86 CACHE STRING "Processor-1 label - should be used for official Windows release") +set(PROC_TARGET_1_FLAGS "-mtune=generic" CACHE STRING "Processor-1 flags") + +# This second choice should be used for your own build only +set(PROC_TARGET_2_LABEL native CACHE STRING "Processor-2 label - use it for your own build") +set(PROC_TARGET_2_FLAGS "-march=native" CACHE STRING "Processor-2 flags") + +# The later choices is intended to be used if you want to provide specific builds, but it should match your own processor +# You can cross compile but you have to know what you're doing, this mechanism has not been designed for that + +set(PROC_TARGET_3_LABEL pentium CACHE STRING "Processor-3 label - use it to provide a pentium optimized build, if you have this processor") +set(PROC_TARGET_3_FLAGS "-march=pentium" CACHE STRING "Processor-3 flags") + +set(PROC_TARGET_4_LABEL pentium4 CACHE STRING "Processor-4 label - use it to provide a pentium4 optimized build, if you have this processor") +set(PROC_TARGET_4_FLAGS "-march=pentium4" CACHE STRING "Processor-4 flags") + +set(PROC_TARGET_5_LABEL core2 CACHE STRING "Processor-5 label - use it to provide a core2 optimized build, if you have this processor") +set(PROC_TARGET_5_FLAGS "-march=core2" CACHE STRING "Processor-5 flags") + +set(PROC_TARGET_6_LABEL corei7 CACHE STRING "Processor-6 label - use it to provide a corei7 optimized build, if you have this processor") +set(PROC_TARGET_6_FLAGS "-march=corei7" CACHE STRING "Processor-6 flags") + +set(PROC_TARGET_7_LABEL athlon-4 CACHE STRING "Processor-7 label - use it to provide a athlon-4 optimized build, if you have this processor") +set(PROC_TARGET_7_FLAGS "-march=athlon-4" CACHE STRING "Processor-7 flags") + +set(PROC_TARGET_8_LABEL athlon64 CACHE STRING "Processor-8 label - use it to provide a athlon64 optimized build, if you have this processor") +set(PROC_TARGET_8_FLAGS "-march=athlon64" CACHE STRING "Processor-8 flags") + +set(PROC_TARGET_9_LABEL phenomX4 CACHE STRING "Processor-9 label - use it to provide a phenomX4 optimized build, if you have this processor") +set(PROC_TARGET_9_FLAGS "-march=amdfam10" CACHE STRING "Processor-9 flags") + +#set(PROC_TARGET__LABEL procLabel CACHE STRING "Processor- label") +#set(PROC_TARGET__FLAGS "procFlags" CACHE STRING "Processor- flags") diff --git a/RELEASE_NOTES.txt b/RELEASE_NOTES.txt new file mode 100644 index 000000000..d64b336c7 --- /dev/null +++ b/RELEASE_NOTES.txt @@ -0,0 +1,48 @@ +RAWTHERAPEE DEVELOPMENT RELEASE NOTES +------------------------------------- + +This is a development version of RawTherapee. We update the code every day, which means the smallest number in the version changes every day, and every few months when new features are finalized and known bugs are fixed we release a stable version. Every minor version in-between those stable versions is known as a "development" version, and this build is one of them. + +While we only commit tested and relatively stable code and so the development versions should be fairly stable, you should be aware that: +- They only had limited testing, so there may be bugs unknown to us. +- You should report these bugs so they get fixed for the stable release. See www.rawpedia.rawtherapee.com/How_to_write_useful_bug_reports The way tools work in the development versions is likely to change as we tweak and tune them, so your processing profiles may produce different results when used in a future stable versions. +- Bugs present in the stable versions get fixed, and until a new stable version is released these fixes are present in these development versions, thereby making the development version "more stable" than the previous stable version. At the same time, new features may introduce new bugs :) This is a trade-off you should be aware of. + +In order to use RawTherapee efficiently you should know that: +- You can scroll all panels using the mouse scroll-wheel. +- You can right-click on a tool's name to automatically expand it while collapsing all others. +- To change slider values or drop-down list items with the mouse scroll-wheel, hold the Shift key. This is so that you can safely scroll the panels without accidentally changing a slider or other tool setting. +- 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! + +Refer to RawPedia for information about RawTherapee's tools and how to use them. + +DOCUMENTATION +------------- +http://rawtherapee.com/documentation +http://rawpedia.rawtherapee.com/ + +REPORTING BUGS +-------------- +Find out how to write good bug reports and get stack-backtraces here: +http://rawpedia.rawtherapee.com/How_to_write_useful_bug_reports + +LIVE CHAT WITH USERS AND DEVELOPERS +-------------------------------------- + Network: freenode + Server: chat.freenode.net + Channel #rawtherapee +Or use freenode webchat to chat without installing anything: +http://webchat.freenode.net/?randomnick=1&channels=rawtherapee&prompt=1 +More information here: http://rawpedia.rawtherapee.com/IRC + +SOCIAL NETWORKS +--------------- +Google+ +http://plus.google.com/106783532637761598368 + +REVISION HISTORY +---------------- +The complete changelog is available at: +https://code.google.com/p/rawtherapee/source/list + diff --git a/WindowsEnvironmentSetup.html b/WindowsEnvironmentSetup.html new file mode 100644 index 000000000..113a8dc6a --- /dev/null +++ b/WindowsEnvironmentSetup.html @@ -0,0 +1,43 @@ +

Building RawTherapee in Windows 64

+12 November 2011
+
+
+This short guide outlines setting up a development environment for building RawTherapee (64 bit) in Windows.
+Apology and warning: the procedure is convoluted. Prepare for frustration if you deviate even one bit. Sorry.
+
+Step 0:
+Use TortoiseHg to grab the latest RawTherapee, put it in a directory whose name doesn't contain spaces. This is more or less simple but well documented, please figure it out yourself.
+
+Step 1:
+Download the latest CMake. Install it into C:\CMake.
+
+Step 2:
+Download a rather specific version of gtkmm64. Install it into C:\gtkmm64.
+
+Step 3:
+Download a rather specific build of MinGW. When installing, uncheck "Check for updated files...", check "Experimental (32 and 64 bit)", check the "openmp" component under Components->gcc, install into C:\MinGW64.
+
+Step 4:
+Download the latest Precompiled package for 64bit Windows. Unzip the file contents (already organized into several subdirectories) into C:\MinGW64.
+
+Step 5:
+Download a rather specific build of MSYS. Install to C:\msys. At the end it asks for your MinGW directory, make sure you give it C:/MinGW64. That's a forward slash, and it matters.
+
+Step 6:
+Create a file named build.bat in your RawTherapee source directory with the following content:
+
+set GTKMM_BASEPATH=C:\gtkmm64
+set GTKMM64_BASEPATH=C:\gtkmm64
+set MINGW_BASEPATH=C:\MinGW64
+set PATH=%PATH%;C:\gtkmm64\bin;C:\MinGW64\bin;C:\CMake\bin
+set PKG_CONFIG_PATH=C:\MinGW64\lib\pkgconfig;c:\gtkmm64\lib\pkgconfig
+
+cmake -DCMAKE_BUILD_TYPE=Release -G "MinGW Makefiles" -DPROC_TARGET_NUMBER:STRING=2
+mingw32-make -j2 install
+pause
+
+
+
+Running the batch file above after completing all steps properly should slowly but flawlessly build RawTherapee.
+If it doesn't work, please tell us about it at the RawTherapee forum. Maybe this document needs updating.
+Do not rest until it builds. A complicated build sucks, but out of date or inaccurate build documentation is unacceptable.
diff --git a/clean.bat b/clean.bat new file mode 100755 index 000000000..6a549821e --- /dev/null +++ b/clean.bat @@ -0,0 +1,27 @@ +@echo off +del .\CMakeCache.txt +del .\install_manifest.txt + +rmdir /s /q .\CMakeFiles +rmdir /s /q .\rtengine\CMakeFiles +rmdir /s /q .\rtexif\CMakeFiles +rmdir /s /q .\rtgui\CMakeFiles +rmdir /s /q .\rtdata\CMakeFiles + +del .\cmake_* +del .\rtengine\cmake_* +del .\rtexif\cmake_* +del .\rtgui\cmake_* +del .\rtdata\cmake_* + +del .\Makefile +del .\rtengine\Makefile +del .\rtexif\Makefile +del .\rtgui\Makefile +del .\rtdata\Makefile + +del .\rtengine\librtengine.so +del .\rtengine\librtengine.a +del .\rtgui\rawtherapee +del .\rtexif\librtexif.so +del .\rtexif\librtexif.a diff --git a/clean.sh b/clean.sh new file mode 100755 index 000000000..5500bf28e --- /dev/null +++ b/clean.sh @@ -0,0 +1,28 @@ +#!/bin/sh +find -name CMakeCache.txt -delete +rm install_manifest.txt + +rm -r ./CMakeFiles +rm -r ./rtengine/CMakeFiles +rm -r ./rtexif/CMakeFiles +rm -r ./rtgui/CMakeFiles +rm -r ./rtdata/CMakeFiles + +rm ./cmake* +rm ./rtengine/cmake* +rm ./rtexif/cmake* +rm ./rtgui/cmake* +rm ./rtdata/cmake* + +rm ./Makefile +rm ./rtengine/Makefile +rm ./rtexif/Makefile +rm ./rtgui/Makefile +rm ./rtdata/Makefile + +rm ./rtengine/librtengine.so +rm ./rtengine/librtengine.a +rm ./rtgui/rawtherapee +rm ./rtexif/librtexif.so +rm ./rtexif/librtexif.a +exit 0 diff --git a/cmake/modules/FindMacIntegration.cmake b/cmake/modules/FindMacIntegration.cmake new file mode 100644 index 000000000..9518dfa8a --- /dev/null +++ b/cmake/modules/FindMacIntegration.cmake @@ -0,0 +1,32 @@ +# - Find the native GtkOSXApplication includes and library +# +# This module defines +# MACINTEGRATION_INCLUDE_DIR, where to find gtkosxapplication.h, etc. +# MACINTEGRATION_LIBRARIES, the libraries to link against to use GtkOSXApplication. +# MACINTEGRATION_FOUND, If false, do not try to use GtkOSXApplication. +# also defined, but not for general use are +# MACINTEGRATION_LIBRARY, where to find the GtkOSXApplication library. + + +#============================================================================= +# Copyright 2010 henrik andersson +#============================================================================= + +SET(MACINTEGRATION_FIND_REQUIRED ${MacIntegration_FIND_REQUIRED}) + +find_path(MACINTEGRATION_INCLUDE_DIR gtkosxapplication.h PATH_SUFFIXES gtkmacintegration gtkmacintegration-gtk2) +mark_as_advanced(MACINTEGRATION_INCLUDE_DIR) + +set(MACINTEGRATION_NAMES ${MACINTEGRATION_NAMES} gtkmacintegration libgtkmacintegration gtkmacintegration-gtk2 libgtkmacintegration-gtk2) +find_library(MACINTEGRATION_LIBRARY NAMES ${MACINTEGRATION_NAMES}) +mark_as_advanced(MACINTEGRATION_LIBRARY) + +# handle the QUIETLY and REQUIRED arguments and set MACINTEGRATION_FOUND to TRUE if +# all listed variables are TRUE +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(MACINTEGRATION DEFAULT_MSG MACINTEGRATION_LIBRARY MACINTEGRATION_INCLUDE_DIR) + +IF(MACINTEGRATION_FOUND) + SET(MacIntegration_LIBRARIES ${MACINTEGRATION_LIBRARY}) + SET(MacIntegration_INCLUDE_DIRS ${MACINTEGRATION_INCLUDE_DIR}) +ENDIF(MACINTEGRATION_FOUND) diff --git a/doc/manpage/rawtherapee.1 b/doc/manpage/rawtherapee.1 new file mode 100644 index 000000000..a626fd0bf --- /dev/null +++ b/doc/manpage/rawtherapee.1 @@ -0,0 +1,86 @@ +.TH RAWTHERAPEE 1 "July 31, 2012" +.SH NAME +rawtherapee \- an advanced cross-platform program for developing raw photos. +.SH SYNOPSIS +\fBrawtherapee\fP [directory|image\-file] +.br +\fBrawtherapee\fP [\-o|\-O ] [\-s|\-S] [\-p ] [\-d] +[\-j[1\-100]|\-t|\-t1|\-n] [\-Y] \-c +.SH DESCRIPTION +\fBRawTherapee\fP is an advanced program for developing raw photos and for +processing non-raw photos. It is non-destructive, makes use of OpenMP, supports +all the cameras supported by dcraw and carries out its calculations in a high +precision 32bit floating point engine. +.SH OPTIONS +.TP +\-o | +select output directory. +.TP +\-O | + select output directory and copy the PP3 file into it. +.TP +\-s +use the PP3 processing profile located next to the input file (which shares +same name as the input file) when building the processing parameters, e.g.: for +IMG001.NEF there should be a IMG001.NEF.pp3 in the same directory. If such a +file is not found, the default values are used. +.TP +\-S +like \-s but skip processing that image if its corresponding PP3 file is not +found. +.TP +\-p +specify a PP3 processing profile to be used for all conversions. You can +specify as many \-p options as you like (see note below). +.TP +\-d +use the default raw or non-raw PP3 file to build the image's parameters +(specified in the options file). +.TP +\-j[1\-100] +specify output to be JPEG (default). The compression value can be in the range +1-100. If none was specified, the default compression value is 90, balanced +subsampling (4:2:2). +.TP +\-t +specify output to be uncompressed 8 bit per channel TIFF. +.TP +\-t1 +specify output to be zip-compressed 8 bit per channel TIFF. +.TP +\-n +specify output to be 8 bit per channel PNG with a compression value of 6. +.TP +\-Y +overwrite output if present. + +.P +.B Note: +.br +You can use partial PP3 files, in which case RawTherapee will set the +missing values as follows: +.br + The PP3 file is first built with internal default values; +.br + then overridden by those found in the "default raw" or "default non-raw" photo +profile (if \-d has been set); +.br + then overridden by those found in the PP3 files provided by \-p, each one +overriding the previous values; +.br + then overridden by the sidecar file if \-s is set and if the file exists; +.br + the time when the sidecar file is used depends of the position of the \-s +switch in the command line relative to the \-p parameters +(e.g. "\-p first.pp3 \-p second.pp3 \-s \-p fourth.pp3"). +.SH SEE ALSO +You can find the documentation, including a detailed user manual, on the +project's website: +http://rawtherapee.com/blog/documentation +.SH AUTHOR +\fBRawTherapee\fP was originally written by Gabor Horvath of Budapest, +Hungary, before being relicensed as free and open-source software in January +2010 and being maintained by a team of people since. +.br +The RawTherapee Development Team comprises of passionate people from all around +the world. diff --git a/header b/header new file mode 100644 index 000000000..c42b87574 --- /dev/null +++ b/header @@ -0,0 +1,18 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ diff --git a/licenses/DroidSansMonoDotted.txt b/licenses/DroidSansMonoDotted.txt new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/licenses/DroidSansMonoDotted.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/licenses/README b/licenses/README new file mode 100644 index 000000000..8f94e37db --- /dev/null +++ b/licenses/README @@ -0,0 +1,2 @@ +This folder contains the licenses and supporting documentation for third party components of RawTherapee. +Filename of each license file corresponds to the related component. diff --git a/licenses/jdatasrc b/licenses/jdatasrc new file mode 100644 index 000000000..da0c488f6 --- /dev/null +++ b/licenses/jdatasrc @@ -0,0 +1,325 @@ +The Independent JPEG Group's JPEG software +========================================== + +README for release 8a of 28-Feb-2010 +==================================== + +This distribution contains the eighth public release of the Independent JPEG +Group's free JPEG software. You are welcome to redistribute this software and +to use it for any purpose, subject to the conditions under LEGAL ISSUES, below. + +This software is the work of Tom Lane, Guido Vollbeding, Philip Gladstone, +Bill Allombert, Jim Boucher, Lee Crocker, Bob Friesenhahn, Ben Jackson, +Julian Minguillon, Luis Ortiz, George Phillips, Davide Rossi, Ge' Weijers, +and other members of the Independent JPEG Group. + +IJG is not affiliated with the official ISO JPEG standards committee. + + +DOCUMENTATION ROADMAP +===================== + +This file contains the following sections: + +OVERVIEW General description of JPEG and the IJG software. +LEGAL ISSUES Copyright, lack of warranty, terms of distribution. +REFERENCES Where to learn more about JPEG. +ARCHIVE LOCATIONS Where to find newer versions of this software. +ACKNOWLEDGMENTS Special thanks. +FILE FORMAT WARS Software *not* to get. +TO DO Plans for future IJG releases. + +Other documentation files in the distribution are: + +User documentation: + install.txt How to configure and install the IJG software. + usage.txt Usage instructions for cjpeg, djpeg, jpegtran, + rdjpgcom, and wrjpgcom. + *.1 Unix-style man pages for programs (same info as usage.txt). + wizard.txt Advanced usage instructions for JPEG wizards only. + change.log Version-to-version change highlights. +Programmer and internal documentation: + libjpeg.txt How to use the JPEG library in your own programs. + example.c Sample code for calling the JPEG library. + structure.txt Overview of the JPEG library's internal structure. + filelist.txt Road map of IJG files. + coderules.txt Coding style rules --- please read if you contribute code. + +Please read at least the files install.txt and usage.txt. Some information +can also be found in the JPEG FAQ (Frequently Asked Questions) article. See +ARCHIVE LOCATIONS below to find out where to obtain the FAQ article. + +If you want to understand how the JPEG code works, we suggest reading one or +more of the REFERENCES, then looking at the documentation files (in roughly +the order listed) before diving into the code. + + +OVERVIEW +======== + +This package contains C software to implement JPEG image encoding, decoding, +and transcoding. JPEG (pronounced "jay-peg") is a standardized compression +method for full-color and gray-scale images. + +This software implements JPEG baseline, extended-sequential, and progressive +compression processes. Provision is made for supporting all variants of these +processes, although some uncommon parameter settings aren't implemented yet. +We have made no provision for supporting the hierarchical or lossless +processes defined in the standard. + +We provide a set of library routines for reading and writing JPEG image files, +plus two sample applications "cjpeg" and "djpeg", which use the library to +perform conversion between JPEG and some other popular image file formats. +The library is intended to be reused in other applications. + +In order to support file conversion and viewing software, we have included +considerable functionality beyond the bare JPEG coding/decoding capability; +for example, the color quantization modules are not strictly part of JPEG +decoding, but they are essential for output to colormapped file formats or +colormapped displays. These extra functions can be compiled out of the +library if not required for a particular application. + +We have also included "jpegtran", a utility for lossless transcoding between +different JPEG processes, and "rdjpgcom" and "wrjpgcom", two simple +applications for inserting and extracting textual comments in JFIF files. + +The emphasis in designing this software has been on achieving portability and +flexibility, while also making it fast enough to be useful. In particular, +the software is not intended to be read as a tutorial on JPEG. (See the +REFERENCES section for introductory material.) Rather, it is intended to +be reliable, portable, industrial-strength code. We do not claim to have +achieved that goal in every aspect of the software, but we strive for it. + +We welcome the use of this software as a component of commercial products. +No royalty is required, but we do ask for an acknowledgement in product +documentation, as described under LEGAL ISSUES. + + +LEGAL ISSUES +============ + +In plain English: + +1. We don't promise that this software works. (But if you find any bugs, + please let us know!) +2. You can use this software for whatever you want. You don't have to pay us. +3. You may not pretend that you wrote this software. If you use it in a + program, you must acknowledge somewhere in your documentation that + you've used the IJG code. + +In legalese: + +The authors make NO WARRANTY or representation, either express or implied, +with respect to this software, its quality, accuracy, merchantability, or +fitness for a particular purpose. This software is provided "AS IS", and you, +its user, assume the entire risk as to its quality and accuracy. + +This software is copyright (C) 1991-2010, Thomas G. Lane, Guido Vollbeding. +All Rights Reserved except as specified below. + +Permission is hereby granted to use, copy, modify, and distribute this +software (or portions thereof) for any purpose, without fee, subject to these +conditions: +(1) If any part of the source code for this software is distributed, then this +README file must be included, with this copyright and no-warranty notice +unaltered; and any additions, deletions, or changes to the original files +must be clearly indicated in accompanying documentation. +(2) If only executable code is distributed, then the accompanying +documentation must state that "this software is based in part on the work of +the Independent JPEG Group". +(3) Permission for use of this software is granted only if the user accepts +full responsibility for any undesirable consequences; the authors accept +NO LIABILITY for damages of any kind. + +These conditions apply to any software derived from or based on the IJG code, +not just to the unmodified library. If you use our work, you ought to +acknowledge us. + +Permission is NOT granted for the use of any IJG author's name or company name +in advertising or publicity relating to this software or products derived from +it. This software may be referred to only as "the Independent JPEG Group's +software". + +We specifically permit and encourage the use of this software as the basis of +commercial products, provided that all warranty or liability claims are +assumed by the product vendor. + + +ansi2knr.c is included in this distribution by permission of L. Peter Deutsch, +sole proprietor of its copyright holder, Aladdin Enterprises of Menlo Park, CA. +ansi2knr.c is NOT covered by the above copyright and conditions, but instead +by the usual distribution terms of the Free Software Foundation; principally, +that you must include source code if you redistribute it. (See the file +ansi2knr.c for full details.) However, since ansi2knr.c is not needed as part +of any program generated from the IJG code, this does not limit you more than +the foregoing paragraphs do. + +The Unix configuration script "configure" was produced with GNU Autoconf. +It is copyright by the Free Software Foundation but is freely distributable. +The same holds for its supporting scripts (config.guess, config.sub, +ltmain.sh). Another support script, install-sh, is copyright by X Consortium +but is also freely distributable. + +The IJG distribution formerly included code to read and write GIF files. +To avoid entanglement with the Unisys LZW patent, GIF reading support has +been removed altogether, and the GIF writer has been simplified to produce +"uncompressed GIFs". This technique does not use the LZW algorithm; the +resulting GIF files are larger than usual, but are readable by all standard +GIF decoders. + +We are required to state that + "The Graphics Interchange Format(c) is the Copyright property of + CompuServe Incorporated. GIF(sm) is a Service Mark property of + CompuServe Incorporated." + + +REFERENCES +========== + +We recommend reading one or more of these references before trying to +understand the innards of the JPEG software. + +The best short technical introduction to the JPEG compression algorithm is + Wallace, Gregory K. "The JPEG Still Picture Compression Standard", + Communications of the ACM, April 1991 (vol. 34 no. 4), pp. 30-44. +(Adjacent articles in that issue discuss MPEG motion picture compression, +applications of JPEG, and related topics.) If you don't have the CACM issue +handy, a PostScript file containing a revised version of Wallace's article is +available at http://www.ijg.org/files/wallace.ps.gz. The file (actually +a preprint for an article that appeared in IEEE Trans. Consumer Electronics) +omits the sample images that appeared in CACM, but it includes corrections +and some added material. Note: the Wallace article is copyright ACM and IEEE, +and it may not be used for commercial purposes. + +A somewhat less technical, more leisurely introduction to JPEG can be found in +"The Data Compression Book" by Mark Nelson and Jean-loup Gailly, published by +M&T Books (New York), 2nd ed. 1996, ISBN 1-55851-434-1. This book provides +good explanations and example C code for a multitude of compression methods +including JPEG. It is an excellent source if you are comfortable reading C +code but don't know much about data compression in general. The book's JPEG +sample code is far from industrial-strength, but when you are ready to look +at a full implementation, you've got one here... + +The best currently available description of JPEG is the textbook "JPEG Still +Image Data Compression Standard" by William B. Pennebaker and Joan L. +Mitchell, published by Van Nostrand Reinhold, 1993, ISBN 0-442-01272-1. +Price US$59.95, 638 pp. The book includes the complete text of the ISO JPEG +standards (DIS 10918-1 and draft DIS 10918-2). +Although this is by far the most detailed and comprehensive exposition of +JPEG publicly available, we point out that it is still missing an explanation +of the most essential properties and algorithms of the underlying DCT +technology. +If you think that you know about DCT-based JPEG after reading this book, +then you are in delusion. The real fundamentals and corresponding potential +of DCT-based JPEG are not publicly known so far, and that is the reason for +all the mistaken developments taking place in the image coding domain. + +The original JPEG standard is divided into two parts, Part 1 being the actual +specification, while Part 2 covers compliance testing methods. Part 1 is +titled "Digital Compression and Coding of Continuous-tone Still Images, +Part 1: Requirements and guidelines" and has document numbers ISO/IEC IS +10918-1, ITU-T T.81. Part 2 is titled "Digital Compression and Coding of +Continuous-tone Still Images, Part 2: Compliance testing" and has document +numbers ISO/IEC IS 10918-2, ITU-T T.83. +IJG JPEG 8 introduces an implementation of the JPEG SmartScale extension +which is specified in a contributed document at ITU and ISO with title "ITU-T +JPEG-Plus Proposal for Extending ITU-T T.81 for Advanced Image Coding", April +2006, Geneva, Switzerland. The latest version of the document is Revision 3. + +The JPEG standard does not specify all details of an interchangeable file +format. For the omitted details we follow the "JFIF" conventions, revision +1.02. JFIF 1.02 has been adopted as an Ecma International Technical Report +and thus received a formal publication status. It is available as a free +download in PDF format from +http://www.ecma-international.org/publications/techreports/E-TR-098.htm. +A PostScript version of the JFIF document is available at +http://www.ijg.org/files/jfif.ps.gz. There is also a plain text version at +http://www.ijg.org/files/jfif.txt.gz, but it is missing the figures. + +The TIFF 6.0 file format specification can be obtained by FTP from +ftp://ftp.sgi.com/graphics/tiff/TIFF6.ps.gz. The JPEG incorporation scheme +found in the TIFF 6.0 spec of 3-June-92 has a number of serious problems. +IJG does not recommend use of the TIFF 6.0 design (TIFF Compression tag 6). +Instead, we recommend the JPEG design proposed by TIFF Technical Note #2 +(Compression tag 7). Copies of this Note can be obtained from +http://www.ijg.org/files/. It is expected that the next revision +of the TIFF spec will replace the 6.0 JPEG design with the Note's design. +Although IJG's own code does not support TIFF/JPEG, the free libtiff library +uses our library to implement TIFF/JPEG per the Note. + + +ARCHIVE LOCATIONS +================= + +The "official" archive site for this software is www.ijg.org. +The most recent released version can always be found there in +directory "files". This particular version will be archived as +http://www.ijg.org/files/jpegsrc.v8a.tar.gz, and in Windows-compatible +"zip" archive format as http://www.ijg.org/files/jpegsr8a.zip. + +The JPEG FAQ (Frequently Asked Questions) article is a source of some +general information about JPEG. +It is available on the World Wide Web at http://www.faqs.org/faqs/jpeg-faq/ +and other news.answers archive sites, including the official news.answers +archive at rtfm.mit.edu: ftp://rtfm.mit.edu/pub/usenet/news.answers/jpeg-faq/. +If you don't have Web or FTP access, send e-mail to mail-server@rtfm.mit.edu +with body + send usenet/news.answers/jpeg-faq/part1 + send usenet/news.answers/jpeg-faq/part2 + + +ACKNOWLEDGMENTS +=============== + +Thank to Juergen Bruder for providing me with a copy of the common DCT +algorithm article, only to find out that I had come to the same result +in a more direct and comprehensible way with a more generative approach. + +Thank to Istvan Sebestyen and Joan L. Mitchell for inviting me to the +ITU JPEG (Study Group 16) meeting in Geneva, Switzerland. + +Thank to Thomas Wiegand and Gary Sullivan for inviting me to the +Joint Video Team (MPEG & ITU) meeting in Geneva, Switzerland. + +Thank to John Korejwa and Massimo Ballerini for inviting me to +fruitful consultations in Boston, MA and Milan, Italy. + +Thank to Hendrik Elstner, Roland Fassauer, Simone Zuck, Guenther +Maier-Gerber, and Walter Stoeber for corresponding business development. + +Thank to Nico Zschach and Dirk Stelling of the technical support team +at the Digital Images company in Halle for providing me with extra +equipment for configuration tests. + +Thank to Richard F. Lyon (then of Foveon Inc.) for fruitful +communication about JPEG configuration in Sigma Photo Pro software. + +Thank to Andrew Finkenstadt for hosting the ijg.org site. + +Last but not least special thank to Thomas G. Lane for the original +design and development of this singular software package. + + +FILE FORMAT WARS +================ + +The ISO JPEG standards committee actually promotes different formats like +"JPEG 2000" or "JPEG XR" which are incompatible with original DCT-based +JPEG and which are based on faulty technologies. IJG therefore does not +and will not support such momentary mistakes (see REFERENCES). +We have little or no sympathy for the promotion of these formats. Indeed, +one of the original reasons for developing this free software was to help +force convergence on common, interoperable format standards for JPEG files. +Don't use an incompatible file format! +(In any case, our decoder will remain capable of reading existing JPEG +image files indefinitely.) + + +TO DO +===== + +Version 8 is the first release of a new generation JPEG standard +to overcome the limitations of the original JPEG specification. +More features are being prepared for coming releases... + +Please send bug reports, offers of help, etc. to jpeg-info@uc.ag. diff --git a/rawtherapee.appdata.xml b/rawtherapee.appdata.xml new file mode 100644 index 000000000..72029c913 --- /dev/null +++ b/rawtherapee.appdata.xml @@ -0,0 +1,44 @@ + + + + rawtherapee.desktop + CC-BY-SA-4.0 + GPL-3.0+ + RawTherapee + A powerful cross-platform raw image processing program + +

+ RawTherapee is a powerful raw image processing program. All the internal calculations are done in a high precision 32-bit floating point engine which facilitates non-destructive editing. Images are opened directly without the hassle of having to import them. Adjustments made by the user are immediately reflected in the preview and saved to a separate sidecar file. These adjustments are then applied during the export process, or can be copied (fully and partially) onto other images, thereby allowing easy batch image processing. +

+

+ All aspects of RawTherapee are documented in the RawPedia wiki. There is also an active forum and IRC channel for interaction with the developers and other users. +

+

+ Supported input formats: +

+
    +
  • Most raw formats including those from Bayer and X-Trans type sensors
  • +
  • HDR DNG 1.4 with floating-point data
  • +
  • 8-bit, 16-bit and 32-bit TIFF (RGB)
  • +
  • 8-bit and 16-bit PNG (RGB)
  • +
  • JPEG
  • +
+

+ Supported output formats: +

+
    +
  • JPEG
  • +
  • 8-bit and 16-bit TIFF
  • +
  • 8-bit and 16-bit PNG
  • +
+
+ + http://rawtherapee.com/images/screenshots/rt-42_07-hdr-landscape.jpg + http://rawtherapee.com/images/screenshots/rt-42_03-macro-detail-toning.jpg + http://rawtherapee.com/images/screenshots/rt-42_05-cow-bw-toning.jpg + http://rawtherapee.com/images/screenshots/rt-42_08-fb-metadata.jpg + http://rawtherapee.com/images/screenshots/rt-42_09-queue.jpg + + http://rawtherapee.com/ + contactus_at_rawtherapee.com +
diff --git a/rawtherapee.astylerc b/rawtherapee.astylerc new file mode 100644 index 000000000..9c10d81cb --- /dev/null +++ b/rawtherapee.astylerc @@ -0,0 +1,5 @@ +style=1tbs +indent=spaces=4 +break-blocks +pad-oper +convert-tabs diff --git a/rtdata/CMakeLists.txt b/rtdata/CMakeLists.txt new file mode 100644 index 000000000..81620221d --- /dev/null +++ b/rtdata/CMakeLists.txt @@ -0,0 +1,101 @@ + +file (GLOB LANGUAGEFILES "languages/*") +file (GLOB SOUNDFILES "sounds/*") +file (GLOB INPUTICCFILES "iccprofiles/input/*") +file (GLOB OUTPUTICCFILES "iccprofiles/output/*") +file (GLOB DCPFILES "dcpprofiles/*") +file (GLOB FONTS "fonts/*") +set (PROFILESDIR "profiles") +# THEMEDIR includes subfolders for image resources for some themes; doing the normal glob won't work. +set (THEMEDIR "themes") +set (IMAGESDIR "images") + +if (WIN32) + set(OPTIONSFILE "options/options.win") +elseif (APPLE) + set(OPTIONSFILE "options/options.osx") +else (WIN32) + set(OPTIONSFILE "options/options.lin") +endif (WIN32) + +if (WIN32) + find_file(HG_CMD hg.exe HINTS ENV Path PATH_SUFFIXES ../) + # Fail if Mercurial is not installed + if (HG_CMD STREQUAL HG_CMD-NOTFOUND) + message(FATAL_ERROR "hg command not found!") + else (HG_CMD STREQUAL HG_CMD-NOTFOUND) + message(STATUS "hg command found: ${HG_CMD}") + execute_process(COMMAND ${HG_CMD} -R "${PROJECT_SOURCE_DIR}" parents --template={latesttag} WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" OUTPUT_VARIABLE HG_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE) + execute_process(COMMAND ${HG_CMD} -R "${PROJECT_SOURCE_DIR}" parents --template={latesttagdistance} WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" OUTPUT_VARIABLE HG_TAGDISTANCE OUTPUT_STRIP_TRAILING_WHITESPACE) + endif (HG_CMD STREQUAL HG_CMD-NOTFOUND) + + if (CMAKE_SIZEOF_VOID_P EQUAL 4) + set(BUILD_BIT_DEPTH 32) + # 32 bits builds has to be installable on 64 bits system, to support WinXP/64. + set(ARCHITECTURE_ALLOWED "x86 x64 ia64") + # installing in 32 bits mode even on 64 bits OS and architecture + set(INSTALL_MODE "") + # set part of the output archive name + set(SYSTEM_NAME "WinXP") + elseif (CMAKE_SIZEOF_VOID_P EQUAL 8) + set(BUILD_BIT_DEPTH 64) + # Restricting the 64 bits builds to 64 bits systems only + set(ARCHITECTURE_ALLOWED "x64 ia64") + # installing in 64 bits mode for all 64 bits processors, even for itanium architecture + set(INSTALL_MODE "x64 ia64") + # set part of the output archive name + set(SYSTEM_NAME "WinVista") + endif (CMAKE_SIZEOF_VOID_P EQUAL 4) + configure_file ("${CMAKE_CURRENT_SOURCE_DIR}/win/InnoSetup/WindowsInnoSetup.iss.in" "${CMAKE_CURRENT_BINARY_DIR}/WindowsInnoSetup.iss") + install (FILES "${CMAKE_CURRENT_BINARY_DIR}/WindowsInnoSetup.iss" DESTINATION ${BINDIR}) +endif (WIN32) + +if (UNIX) + configure_file ("${CMAKE_CURRENT_SOURCE_DIR}/icons/rawtherapee.desktop.in" "${CMAKE_CURRENT_BINARY_DIR}/rawtherapee.desktop") + install (FILES "${CMAKE_CURRENT_BINARY_DIR}/rawtherapee.desktop" DESTINATION ${DESKTOPDIR}) + install (FILES "${CMAKE_CURRENT_SOURCE_DIR}/icons/hi16-app-rawtherapee.png" DESTINATION "${ICONSDIR}/hicolor/16x16/apps" RENAME rawtherapee.png) + install (FILES "${CMAKE_CURRENT_SOURCE_DIR}/icons/hi24-app-rawtherapee.png" DESTINATION "${ICONSDIR}/hicolor/24x24/apps" RENAME rawtherapee.png) + install (FILES "${CMAKE_CURRENT_SOURCE_DIR}/icons/hi32-app-rawtherapee.png" DESTINATION "${ICONSDIR}/hicolor/32x32/apps" RENAME rawtherapee.png) + install (FILES "${CMAKE_CURRENT_SOURCE_DIR}/icons/hi48-app-rawtherapee.png" DESTINATION "${ICONSDIR}/hicolor/48x48/apps" RENAME rawtherapee.png) + install (FILES "${CMAKE_CURRENT_SOURCE_DIR}/icons/hi128-app-rawtherapee.png" DESTINATION "${ICONSDIR}/hicolor/128x128/apps" RENAME rawtherapee.png) + install (FILES "${CMAKE_CURRENT_SOURCE_DIR}/icons/hi256-app-rawtherapee.png" DESTINATION "${ICONSDIR}/hicolor/256x256/apps" RENAME rawtherapee.png) +endif (UNIX) + +install (FILES ${IMAGEFILES} DESTINATION "${DATADIR}/images") +install (FILES ${LANGUAGEFILES} DESTINATION "${DATADIR}/languages") +install (FILES ${SOUNDFILES} DESTINATION "${DATADIR}/sounds") +install (FILES ${INPUTICCFILES} DESTINATION "${DATADIR}/iccprofiles/input") +install (FILES ${OUTPUTICCFILES} DESTINATION "${DATADIR}/iccprofiles/output") +install (FILES ${DCPFILES} DESTINATION "${DATADIR}/dcpprofiles") +if (WIN32) + install (FILES ${FONTS} DESTINATION "${DATADIR}/fonts") +endif (WIN32) +install (DIRECTORY ${PROFILESDIR} DESTINATION "${DATADIR}" FILES_MATCHING PATTERN "*.pp3") +install (DIRECTORY ${THEMEDIR} DESTINATION "${DATADIR}") +install (DIRECTORY ${IMAGESDIR} DESTINATION "${DATADIR}" FILES_MATCHING PATTERN "index.theme") +install (DIRECTORY ${IMAGESDIR} DESTINATION "${DATADIR}" FILES_MATCHING PATTERN "*.png") +install (FILES ${OPTIONSFILE} DESTINATION "${DATADIR}" PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ RENAME options) + +if (WIN32) + install (FILES "${PROJECT_SOURCE_DIR}/doc/manpage/rawtherapee.1" DESTINATION "${CMAKE_INSTALL_PREFIX}/share/man/man1") +endif (WIN32) + +if (APPLE) + # CMake escapes first item quote character. Do not remove 'DUMMY_VARIABLE='. + set (MACOSX_BUNDLE_COMMAND DUMMY_VARIABLE= + PROJECT_NAME="${PROJECT_NAME}" + PROJECT_SOURCE_DIR="${PROJECT_SOURCE_DIR}" + CMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE}" + GTK_PREFIX="${GTK_PREFIX}") + if (PROC_BIT_DEPTH MATCHES 32) + list (APPEND MACOSX_BUNDLE_COMMAND PROC_BIT_DEPTH=32) + elseif (PROC_BIT_DEPTH MATCHES 64) + list (APPEND MACOSX_BUNDLE_COMMAND PROC_BIT_DEPTH=64) + endif (PROC_BIT_DEPTH MATCHES 32) + list (APPEND MACOSX_BUNDLE_COMMAND sh "${PROJECT_SOURCE_DIR}/rtdata/osx/macosx_bundle.sh") + + add_custom_target(macosx_bundle + COMMAND ${MACOSX_BUNDLE_COMMAND} + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" + COMMENT "Creating Mac OS X bundle") +endif (APPLE) diff --git a/rtdata/dcpprofiles/Canon EOS 20D.dcp b/rtdata/dcpprofiles/Canon EOS 20D.dcp new file mode 100644 index 000000000..0dfc1c80b Binary files /dev/null and b/rtdata/dcpprofiles/Canon EOS 20D.dcp differ diff --git a/rtdata/dcpprofiles/Canon EOS 400D.dcp b/rtdata/dcpprofiles/Canon EOS 400D.dcp new file mode 100644 index 000000000..f598507a6 Binary files /dev/null and b/rtdata/dcpprofiles/Canon EOS 400D.dcp differ diff --git a/rtdata/dcpprofiles/Canon EOS 40D.dcp b/rtdata/dcpprofiles/Canon EOS 40D.dcp new file mode 100644 index 000000000..98cf8ce09 Binary files /dev/null and b/rtdata/dcpprofiles/Canon EOS 40D.dcp differ diff --git a/rtdata/dcpprofiles/Canon EOS 450D.dcp b/rtdata/dcpprofiles/Canon EOS 450D.dcp new file mode 100644 index 000000000..1db7ee1cd Binary files /dev/null and b/rtdata/dcpprofiles/Canon EOS 450D.dcp differ diff --git a/rtdata/dcpprofiles/Canon EOS 550D.dcp b/rtdata/dcpprofiles/Canon EOS 550D.dcp new file mode 100644 index 000000000..4f286ec90 Binary files /dev/null and b/rtdata/dcpprofiles/Canon EOS 550D.dcp differ diff --git a/rtdata/dcpprofiles/Canon EOS 5D Mark III.dcp b/rtdata/dcpprofiles/Canon EOS 5D Mark III.dcp new file mode 100644 index 000000000..476676755 Binary files /dev/null and b/rtdata/dcpprofiles/Canon EOS 5D Mark III.dcp differ diff --git a/rtdata/dcpprofiles/Canon EOS 5D.dcp b/rtdata/dcpprofiles/Canon EOS 5D.dcp new file mode 100644 index 000000000..11fab1900 Binary files /dev/null and b/rtdata/dcpprofiles/Canon EOS 5D.dcp differ diff --git a/rtdata/dcpprofiles/Canon EOS 7D.dcp b/rtdata/dcpprofiles/Canon EOS 7D.dcp new file mode 100644 index 000000000..f6425f3c5 Binary files /dev/null and b/rtdata/dcpprofiles/Canon EOS 7D.dcp differ diff --git a/rtdata/dcpprofiles/Canon EOS D60.dcp b/rtdata/dcpprofiles/Canon EOS D60.dcp new file mode 100644 index 000000000..903c62743 Binary files /dev/null and b/rtdata/dcpprofiles/Canon EOS D60.dcp differ diff --git a/rtdata/dcpprofiles/Canon EOS Digital Rebel XSi.dcp b/rtdata/dcpprofiles/Canon EOS Digital Rebel XSi.dcp new file mode 100644 index 000000000..1db7ee1cd Binary files /dev/null and b/rtdata/dcpprofiles/Canon EOS Digital Rebel XSi.dcp differ diff --git a/rtdata/dcpprofiles/Canon EOS Digital Rebel XTi.dcp b/rtdata/dcpprofiles/Canon EOS Digital Rebel XTi.dcp new file mode 100644 index 000000000..f598507a6 Binary files /dev/null and b/rtdata/dcpprofiles/Canon EOS Digital Rebel XTi.dcp differ diff --git a/rtdata/dcpprofiles/Canon EOS Rebel T2i.dcp b/rtdata/dcpprofiles/Canon EOS Rebel T2i.dcp new file mode 100644 index 000000000..4f286ec90 Binary files /dev/null and b/rtdata/dcpprofiles/Canon EOS Rebel T2i.dcp differ diff --git a/rtdata/dcpprofiles/Canon EOS-1D Mark III.dcp b/rtdata/dcpprofiles/Canon EOS-1D Mark III.dcp new file mode 100644 index 000000000..0bbaceb2c Binary files /dev/null and b/rtdata/dcpprofiles/Canon EOS-1D Mark III.dcp differ diff --git a/rtdata/dcpprofiles/Canon PowerShot G10.dcp b/rtdata/dcpprofiles/Canon PowerShot G10.dcp new file mode 100644 index 000000000..17a36f6fb Binary files /dev/null and b/rtdata/dcpprofiles/Canon PowerShot G10.dcp differ diff --git a/rtdata/dcpprofiles/Canon PowerShot G12.dcp b/rtdata/dcpprofiles/Canon PowerShot G12.dcp new file mode 100644 index 000000000..aa7d680f7 Binary files /dev/null and b/rtdata/dcpprofiles/Canon PowerShot G12.dcp differ diff --git a/rtdata/dcpprofiles/Canon PowerShot S110.dcp b/rtdata/dcpprofiles/Canon PowerShot S110.dcp new file mode 100644 index 000000000..50c65cd8d Binary files /dev/null and b/rtdata/dcpprofiles/Canon PowerShot S110.dcp differ diff --git a/rtdata/dcpprofiles/Fujifilm FinePix S9500.dcp b/rtdata/dcpprofiles/Fujifilm FinePix S9500.dcp new file mode 100644 index 000000000..baf8199f2 Binary files /dev/null and b/rtdata/dcpprofiles/Fujifilm FinePix S9500.dcp differ diff --git a/rtdata/dcpprofiles/Leaf Aptus 75.dcp b/rtdata/dcpprofiles/Leaf Aptus 75.dcp new file mode 100644 index 000000000..aa52642b3 Binary files /dev/null and b/rtdata/dcpprofiles/Leaf Aptus 75.dcp differ diff --git a/rtdata/dcpprofiles/Nikon D200.dcp b/rtdata/dcpprofiles/Nikon D200.dcp new file mode 100644 index 000000000..3a31735d3 Binary files /dev/null and b/rtdata/dcpprofiles/Nikon D200.dcp differ diff --git a/rtdata/dcpprofiles/Nikon D300.dcp b/rtdata/dcpprofiles/Nikon D300.dcp new file mode 100644 index 000000000..3b1100b9d Binary files /dev/null and b/rtdata/dcpprofiles/Nikon D300.dcp differ diff --git a/rtdata/dcpprofiles/Nikon D3000.dcp b/rtdata/dcpprofiles/Nikon D3000.dcp new file mode 100644 index 000000000..7a6d79fa5 Binary files /dev/null and b/rtdata/dcpprofiles/Nikon D3000.dcp differ diff --git a/rtdata/dcpprofiles/Nikon D3100.dcp b/rtdata/dcpprofiles/Nikon D3100.dcp new file mode 100644 index 000000000..776ad4c52 Binary files /dev/null and b/rtdata/dcpprofiles/Nikon D3100.dcp differ diff --git a/rtdata/dcpprofiles/Nikon D3S.dcp b/rtdata/dcpprofiles/Nikon D3S.dcp new file mode 100644 index 000000000..e5c5f6ab8 Binary files /dev/null and b/rtdata/dcpprofiles/Nikon D3S.dcp differ diff --git a/rtdata/dcpprofiles/Nikon D50.dcp b/rtdata/dcpprofiles/Nikon D50.dcp new file mode 100644 index 000000000..0b8a082f4 Binary files /dev/null and b/rtdata/dcpprofiles/Nikon D50.dcp differ diff --git a/rtdata/dcpprofiles/Nikon D5100.dcp b/rtdata/dcpprofiles/Nikon D5100.dcp new file mode 100644 index 000000000..1cbb35ec6 Binary files /dev/null and b/rtdata/dcpprofiles/Nikon D5100.dcp differ diff --git a/rtdata/dcpprofiles/Nikon D700.dcp b/rtdata/dcpprofiles/Nikon D700.dcp new file mode 100644 index 000000000..969c6b964 Binary files /dev/null and b/rtdata/dcpprofiles/Nikon D700.dcp differ diff --git a/rtdata/dcpprofiles/Nikon D7000.dcp b/rtdata/dcpprofiles/Nikon D7000.dcp new file mode 100644 index 000000000..e672b803c Binary files /dev/null and b/rtdata/dcpprofiles/Nikon D7000.dcp differ diff --git a/rtdata/dcpprofiles/Nikon D750.dcp b/rtdata/dcpprofiles/Nikon D750.dcp new file mode 100644 index 000000000..ad9cd5679 Binary files /dev/null and b/rtdata/dcpprofiles/Nikon D750.dcp differ diff --git a/rtdata/dcpprofiles/Nikon D800.dcp b/rtdata/dcpprofiles/Nikon D800.dcp new file mode 100644 index 000000000..c0a4a5586 Binary files /dev/null and b/rtdata/dcpprofiles/Nikon D800.dcp differ diff --git a/rtdata/dcpprofiles/Olympus E-1.dcp b/rtdata/dcpprofiles/Olympus E-1.dcp new file mode 100644 index 000000000..f44ee579f Binary files /dev/null and b/rtdata/dcpprofiles/Olympus E-1.dcp differ diff --git a/rtdata/dcpprofiles/Olympus E-510.dcp b/rtdata/dcpprofiles/Olympus E-510.dcp new file mode 100644 index 000000000..14de9a405 Binary files /dev/null and b/rtdata/dcpprofiles/Olympus E-510.dcp differ diff --git a/rtdata/dcpprofiles/Olympus E-520.dcp b/rtdata/dcpprofiles/Olympus E-520.dcp new file mode 100644 index 000000000..5b093c5d8 Binary files /dev/null and b/rtdata/dcpprofiles/Olympus E-520.dcp differ diff --git a/rtdata/dcpprofiles/Olympus E-M5.dcp b/rtdata/dcpprofiles/Olympus E-M5.dcp new file mode 100644 index 000000000..af04b134c Binary files /dev/null and b/rtdata/dcpprofiles/Olympus E-M5.dcp differ diff --git a/rtdata/dcpprofiles/Olympus E-P2.dcp b/rtdata/dcpprofiles/Olympus E-P2.dcp new file mode 100644 index 000000000..bdc25cb0c Binary files /dev/null and b/rtdata/dcpprofiles/Olympus E-P2.dcp differ diff --git a/rtdata/dcpprofiles/Olympus XZ-1.dcp b/rtdata/dcpprofiles/Olympus XZ-1.dcp new file mode 100644 index 000000000..9c4a14ae6 Binary files /dev/null and b/rtdata/dcpprofiles/Olympus XZ-1.dcp differ diff --git a/rtdata/dcpprofiles/Panasonic DMC-FZ150.dcp b/rtdata/dcpprofiles/Panasonic DMC-FZ150.dcp new file mode 100644 index 000000000..5bd3646f6 Binary files /dev/null and b/rtdata/dcpprofiles/Panasonic DMC-FZ150.dcp differ diff --git a/rtdata/dcpprofiles/Panasonic DMC-FZ35.dcp b/rtdata/dcpprofiles/Panasonic DMC-FZ35.dcp new file mode 100644 index 000000000..e8bd00d37 Binary files /dev/null and b/rtdata/dcpprofiles/Panasonic DMC-FZ35.dcp differ diff --git a/rtdata/dcpprofiles/Panasonic DMC-FZ38.dcp b/rtdata/dcpprofiles/Panasonic DMC-FZ38.dcp new file mode 100644 index 000000000..e8bd00d37 Binary files /dev/null and b/rtdata/dcpprofiles/Panasonic DMC-FZ38.dcp differ diff --git a/rtdata/dcpprofiles/Panasonic DMC-G1.dcp b/rtdata/dcpprofiles/Panasonic DMC-G1.dcp new file mode 100644 index 000000000..aee19766b Binary files /dev/null and b/rtdata/dcpprofiles/Panasonic DMC-G1.dcp differ diff --git a/rtdata/dcpprofiles/Panasonic DMC-G3.dcp b/rtdata/dcpprofiles/Panasonic DMC-G3.dcp new file mode 100644 index 000000000..9247f6df7 Binary files /dev/null and b/rtdata/dcpprofiles/Panasonic DMC-G3.dcp differ diff --git a/rtdata/dcpprofiles/Panasonic DMC-G5.dcp b/rtdata/dcpprofiles/Panasonic DMC-G5.dcp new file mode 100644 index 000000000..614dbf0f2 Binary files /dev/null and b/rtdata/dcpprofiles/Panasonic DMC-G5.dcp differ diff --git a/rtdata/dcpprofiles/Panasonic DMC-GH1.dcp b/rtdata/dcpprofiles/Panasonic DMC-GH1.dcp new file mode 100644 index 000000000..c7aa00ef1 Binary files /dev/null and b/rtdata/dcpprofiles/Panasonic DMC-GH1.dcp differ diff --git a/rtdata/dcpprofiles/Panasonic DMC-GH2.dcp b/rtdata/dcpprofiles/Panasonic DMC-GH2.dcp new file mode 100644 index 000000000..fda7ef83a Binary files /dev/null and b/rtdata/dcpprofiles/Panasonic DMC-GH2.dcp differ diff --git a/rtdata/dcpprofiles/Pentax K-5 II.dcp b/rtdata/dcpprofiles/Pentax K-5 II.dcp new file mode 100644 index 000000000..a9cfd8e54 Binary files /dev/null and b/rtdata/dcpprofiles/Pentax K-5 II.dcp differ diff --git a/rtdata/dcpprofiles/Pentax K-5.dcp b/rtdata/dcpprofiles/Pentax K-5.dcp new file mode 100644 index 000000000..f505634d9 Binary files /dev/null and b/rtdata/dcpprofiles/Pentax K-5.dcp differ diff --git a/rtdata/dcpprofiles/Pentax K-r.dcp b/rtdata/dcpprofiles/Pentax K-r.dcp new file mode 100644 index 000000000..1316e08d6 Binary files /dev/null and b/rtdata/dcpprofiles/Pentax K-r.dcp differ diff --git a/rtdata/dcpprofiles/Pentax K10D.dcp b/rtdata/dcpprofiles/Pentax K10D.dcp new file mode 100644 index 000000000..e45e01cce Binary files /dev/null and b/rtdata/dcpprofiles/Pentax K10D.dcp differ diff --git a/rtdata/dcpprofiles/Pentax K200D.dcp b/rtdata/dcpprofiles/Pentax K200D.dcp new file mode 100644 index 000000000..c1a5b7933 Binary files /dev/null and b/rtdata/dcpprofiles/Pentax K200D.dcp differ diff --git a/rtdata/dcpprofiles/Sony DSLR-A700.dcp b/rtdata/dcpprofiles/Sony DSLR-A700.dcp new file mode 100644 index 000000000..2dad1052e Binary files /dev/null and b/rtdata/dcpprofiles/Sony DSLR-A700.dcp differ diff --git a/rtdata/dcpprofiles/Sony DSLR-A900.dcp b/rtdata/dcpprofiles/Sony DSLR-A900.dcp new file mode 100644 index 000000000..828682205 Binary files /dev/null and b/rtdata/dcpprofiles/Sony DSLR-A900.dcp differ diff --git a/rtdata/dcpprofiles/Sony NEX-5N.dcp b/rtdata/dcpprofiles/Sony NEX-5N.dcp new file mode 100644 index 000000000..263733b04 Binary files /dev/null and b/rtdata/dcpprofiles/Sony NEX-5N.dcp differ diff --git a/rtdata/dcpprofiles/Sony SLT-A55V.dcp b/rtdata/dcpprofiles/Sony SLT-A55V.dcp new file mode 100644 index 000000000..ce07b30f6 Binary files /dev/null and b/rtdata/dcpprofiles/Sony SLT-A55V.dcp differ diff --git a/rtdata/fonts/DroidSansMonoSlashed.ttf b/rtdata/fonts/DroidSansMonoSlashed.ttf new file mode 100644 index 000000000..8c44b47ed Binary files /dev/null and b/rtdata/fonts/DroidSansMonoSlashed.ttf differ diff --git a/rtdata/iccprofiles/input/Canon EOS 20D.icc b/rtdata/iccprofiles/input/Canon EOS 20D.icc new file mode 100644 index 000000000..53b65e090 Binary files /dev/null and b/rtdata/iccprofiles/input/Canon EOS 20D.icc differ diff --git a/rtdata/iccprofiles/input/Canon EOS 40D.icc b/rtdata/iccprofiles/input/Canon EOS 40D.icc new file mode 100644 index 000000000..957053f93 Binary files /dev/null and b/rtdata/iccprofiles/input/Canon EOS 40D.icc differ diff --git a/rtdata/iccprofiles/input/Canon EOS 450D.icc b/rtdata/iccprofiles/input/Canon EOS 450D.icc new file mode 100644 index 000000000..e3229b821 Binary files /dev/null and b/rtdata/iccprofiles/input/Canon EOS 450D.icc differ diff --git a/rtdata/iccprofiles/input/Canon EOS 550D.icc b/rtdata/iccprofiles/input/Canon EOS 550D.icc new file mode 100644 index 000000000..c6b37c6c4 Binary files /dev/null and b/rtdata/iccprofiles/input/Canon EOS 550D.icc differ diff --git a/rtdata/iccprofiles/input/Canon EOS 5D.icc b/rtdata/iccprofiles/input/Canon EOS 5D.icc new file mode 100644 index 000000000..9d9080f8b Binary files /dev/null and b/rtdata/iccprofiles/input/Canon EOS 5D.icc differ diff --git a/rtdata/iccprofiles/input/Canon EOS Digital Rebel XSi.icc b/rtdata/iccprofiles/input/Canon EOS Digital Rebel XSi.icc new file mode 100644 index 000000000..e3229b821 Binary files /dev/null and b/rtdata/iccprofiles/input/Canon EOS Digital Rebel XSi.icc differ diff --git a/rtdata/iccprofiles/input/Canon EOS Rebel T2i.icc b/rtdata/iccprofiles/input/Canon EOS Rebel T2i.icc new file mode 100644 index 000000000..c6b37c6c4 Binary files /dev/null and b/rtdata/iccprofiles/input/Canon EOS Rebel T2i.icc differ diff --git a/rtdata/iccprofiles/input/Canon EOS-1D Mark III.icc b/rtdata/iccprofiles/input/Canon EOS-1D Mark III.icc new file mode 100644 index 000000000..11271982a Binary files /dev/null and b/rtdata/iccprofiles/input/Canon EOS-1D Mark III.icc differ diff --git a/rtdata/iccprofiles/input/Canon PowerShot G10.icc b/rtdata/iccprofiles/input/Canon PowerShot G10.icc new file mode 100644 index 000000000..5a3656568 Binary files /dev/null and b/rtdata/iccprofiles/input/Canon PowerShot G10.icc differ diff --git a/rtdata/iccprofiles/input/Canon PowerShot G12.icc b/rtdata/iccprofiles/input/Canon PowerShot G12.icc new file mode 100644 index 000000000..efc495d50 Binary files /dev/null and b/rtdata/iccprofiles/input/Canon PowerShot G12.icc differ diff --git a/rtdata/iccprofiles/input/Nikon D200.icc b/rtdata/iccprofiles/input/Nikon D200.icc new file mode 100644 index 000000000..ac5fc4070 Binary files /dev/null and b/rtdata/iccprofiles/input/Nikon D200.icc differ diff --git a/rtdata/iccprofiles/input/Nikon D3000.icc b/rtdata/iccprofiles/input/Nikon D3000.icc new file mode 100644 index 000000000..8bbecb681 Binary files /dev/null and b/rtdata/iccprofiles/input/Nikon D3000.icc differ diff --git a/rtdata/iccprofiles/input/Nikon D3100.icc b/rtdata/iccprofiles/input/Nikon D3100.icc new file mode 100644 index 000000000..eafd85f7e Binary files /dev/null and b/rtdata/iccprofiles/input/Nikon D3100.icc differ diff --git a/rtdata/iccprofiles/input/Nikon D3S.icc b/rtdata/iccprofiles/input/Nikon D3S.icc new file mode 100644 index 000000000..d2d6ac6c9 Binary files /dev/null and b/rtdata/iccprofiles/input/Nikon D3S.icc differ diff --git a/rtdata/iccprofiles/input/Nikon D700.icc b/rtdata/iccprofiles/input/Nikon D700.icc new file mode 100644 index 000000000..01192d7fb Binary files /dev/null and b/rtdata/iccprofiles/input/Nikon D700.icc differ diff --git a/rtdata/iccprofiles/input/Nikon D7000.icc b/rtdata/iccprofiles/input/Nikon D7000.icc new file mode 100644 index 000000000..14ba843c4 Binary files /dev/null and b/rtdata/iccprofiles/input/Nikon D7000.icc differ diff --git a/rtdata/iccprofiles/input/Olympus E-P2.icc b/rtdata/iccprofiles/input/Olympus E-P2.icc new file mode 100644 index 000000000..114118fa2 Binary files /dev/null and b/rtdata/iccprofiles/input/Olympus E-P2.icc differ diff --git a/rtdata/iccprofiles/input/Panasonic DMC-FZ150.icc b/rtdata/iccprofiles/input/Panasonic DMC-FZ150.icc new file mode 100644 index 000000000..d29e2bbea Binary files /dev/null and b/rtdata/iccprofiles/input/Panasonic DMC-FZ150.icc differ diff --git a/rtdata/iccprofiles/input/Panasonic DMC-FZ35.icc b/rtdata/iccprofiles/input/Panasonic DMC-FZ35.icc new file mode 100644 index 000000000..6d29190a0 Binary files /dev/null and b/rtdata/iccprofiles/input/Panasonic DMC-FZ35.icc differ diff --git a/rtdata/iccprofiles/input/Panasonic DMC-FZ38.icc b/rtdata/iccprofiles/input/Panasonic DMC-FZ38.icc new file mode 100644 index 000000000..6d29190a0 Binary files /dev/null and b/rtdata/iccprofiles/input/Panasonic DMC-FZ38.icc differ diff --git a/rtdata/iccprofiles/input/Panasonic DMC-G1.icc b/rtdata/iccprofiles/input/Panasonic DMC-G1.icc new file mode 100644 index 000000000..ebab93cdd Binary files /dev/null and b/rtdata/iccprofiles/input/Panasonic DMC-G1.icc differ diff --git a/rtdata/iccprofiles/input/Panasonic DMC-G3.icc b/rtdata/iccprofiles/input/Panasonic DMC-G3.icc new file mode 100644 index 000000000..8f751e75c Binary files /dev/null and b/rtdata/iccprofiles/input/Panasonic DMC-G3.icc differ diff --git a/rtdata/iccprofiles/input/Panasonic DMC-GH1.icc b/rtdata/iccprofiles/input/Panasonic DMC-GH1.icc new file mode 100644 index 000000000..38329a521 Binary files /dev/null and b/rtdata/iccprofiles/input/Panasonic DMC-GH1.icc differ diff --git a/rtdata/iccprofiles/input/Panasonic DMC-GH2.icc b/rtdata/iccprofiles/input/Panasonic DMC-GH2.icc new file mode 100644 index 000000000..103b2ef9f Binary files /dev/null and b/rtdata/iccprofiles/input/Panasonic DMC-GH2.icc differ diff --git a/rtdata/iccprofiles/input/Pentax K200D.icc b/rtdata/iccprofiles/input/Pentax K200D.icc new file mode 100644 index 000000000..b6d61c1a4 Binary files /dev/null and b/rtdata/iccprofiles/input/Pentax K200D.icc differ diff --git a/rtdata/iccprofiles/input/Sony DSLR-A700.icc b/rtdata/iccprofiles/input/Sony DSLR-A700.icc new file mode 100644 index 000000000..831470c8c Binary files /dev/null and b/rtdata/iccprofiles/input/Sony DSLR-A700.icc differ diff --git a/rtdata/iccprofiles/input/Sony DSLR-A900.icc b/rtdata/iccprofiles/input/Sony DSLR-A900.icc new file mode 100644 index 000000000..983b55681 Binary files /dev/null and b/rtdata/iccprofiles/input/Sony DSLR-A900.icc differ diff --git a/rtdata/iccprofiles/input/Sony SLT-A55V.icc b/rtdata/iccprofiles/input/Sony SLT-A55V.icc new file mode 100644 index 000000000..c85972b85 Binary files /dev/null and b/rtdata/iccprofiles/input/Sony SLT-A55V.icc differ diff --git a/rtdata/iccprofiles/input/sd14-bl15-crop-matrix-gamma-wp10.icm b/rtdata/iccprofiles/input/sd14-bl15-crop-matrix-gamma-wp10.icm new file mode 100644 index 000000000..ac3cf1274 Binary files /dev/null and b/rtdata/iccprofiles/input/sd14-bl15-crop-matrix-gamma-wp10.icm differ diff --git a/rtdata/iccprofiles/input/sd14-bl15-crop-matrix-gamma-wp11.icm b/rtdata/iccprofiles/input/sd14-bl15-crop-matrix-gamma-wp11.icm new file mode 100644 index 000000000..b609e3e5a Binary files /dev/null and b/rtdata/iccprofiles/input/sd14-bl15-crop-matrix-gamma-wp11.icm differ diff --git a/rtdata/iccprofiles/input/sd14-bl15-crop-matrix-gamma-wp12.icm b/rtdata/iccprofiles/input/sd14-bl15-crop-matrix-gamma-wp12.icm new file mode 100644 index 000000000..79a44e113 Binary files /dev/null and b/rtdata/iccprofiles/input/sd14-bl15-crop-matrix-gamma-wp12.icm differ diff --git a/rtdata/iccprofiles/input/sd1_merrill_cloudy8140-CROP-WP10.icm b/rtdata/iccprofiles/input/sd1_merrill_cloudy8140-CROP-WP10.icm new file mode 100644 index 000000000..5d4cdaf03 Binary files /dev/null and b/rtdata/iccprofiles/input/sd1_merrill_cloudy8140-CROP-WP10.icm differ diff --git a/rtdata/iccprofiles/input/sd1_merrill_cloudy8140-CROP-WP11.icm b/rtdata/iccprofiles/input/sd1_merrill_cloudy8140-CROP-WP11.icm new file mode 100644 index 000000000..58ea30140 Binary files /dev/null and b/rtdata/iccprofiles/input/sd1_merrill_cloudy8140-CROP-WP11.icm differ diff --git a/rtdata/iccprofiles/input/sd1_merrill_sunny8161-crop-wp10.icm b/rtdata/iccprofiles/input/sd1_merrill_sunny8161-crop-wp10.icm new file mode 100644 index 000000000..48d0225cd Binary files /dev/null and b/rtdata/iccprofiles/input/sd1_merrill_sunny8161-crop-wp10.icm differ diff --git a/rtdata/iccprofiles/input/sd1_merrill_sunny8161-crop-wp11.icm b/rtdata/iccprofiles/input/sd1_merrill_sunny8161-crop-wp11.icm new file mode 100644 index 000000000..1f613eda6 Binary files /dev/null and b/rtdata/iccprofiles/input/sd1_merrill_sunny8161-crop-wp11.icm differ diff --git a/rtdata/iccprofiles/input/sd1_merrill_tungsten8130-CROP-WP10.icm b/rtdata/iccprofiles/input/sd1_merrill_tungsten8130-CROP-WP10.icm new file mode 100644 index 000000000..7a5c322b3 Binary files /dev/null and b/rtdata/iccprofiles/input/sd1_merrill_tungsten8130-CROP-WP10.icm differ diff --git a/rtdata/iccprofiles/input/sd1_merrill_tungsten8130-CROP-WP11.icm b/rtdata/iccprofiles/input/sd1_merrill_tungsten8130-CROP-WP11.icm new file mode 100644 index 000000000..bb55e3a86 Binary files /dev/null and b/rtdata/iccprofiles/input/sd1_merrill_tungsten8130-CROP-WP11.icm differ diff --git a/rtdata/iccprofiles/output/RT_Large_g10.icc b/rtdata/iccprofiles/output/RT_Large_g10.icc new file mode 100644 index 000000000..1889a5457 Binary files /dev/null and b/rtdata/iccprofiles/output/RT_Large_g10.icc differ diff --git a/rtdata/iccprofiles/output/RT_Large_gBT709.icc b/rtdata/iccprofiles/output/RT_Large_gBT709.icc new file mode 100644 index 000000000..bd9785f14 Binary files /dev/null and b/rtdata/iccprofiles/output/RT_Large_gBT709.icc differ diff --git a/rtdata/iccprofiles/output/RT_Large_gsRGB.icc b/rtdata/iccprofiles/output/RT_Large_gsRGB.icc new file mode 100644 index 000000000..11be3c733 Binary files /dev/null and b/rtdata/iccprofiles/output/RT_Large_gsRGB.icc differ diff --git a/rtdata/iccprofiles/output/RT_Medium_gsRGB.icc b/rtdata/iccprofiles/output/RT_Medium_gsRGB.icc new file mode 100644 index 000000000..6c6233d74 Binary files /dev/null and b/rtdata/iccprofiles/output/RT_Medium_gsRGB.icc differ diff --git a/rtdata/iccprofiles/output/RT_sRGB.icm b/rtdata/iccprofiles/output/RT_sRGB.icm new file mode 100644 index 000000000..3d0822ef7 Binary files /dev/null and b/rtdata/iccprofiles/output/RT_sRGB.icm differ diff --git a/rtdata/iccprofiles/output/RT_sRGB_g10.icm b/rtdata/iccprofiles/output/RT_sRGB_g10.icm new file mode 100644 index 000000000..f8afb8e17 Binary files /dev/null and b/rtdata/iccprofiles/output/RT_sRGB_g10.icm differ diff --git a/rtdata/iccprofiles/output/RT_sRGB_gBT709.icm b/rtdata/iccprofiles/output/RT_sRGB_gBT709.icm new file mode 100644 index 000000000..c5c44b7a4 Binary files /dev/null and b/rtdata/iccprofiles/output/RT_sRGB_gBT709.icm differ diff --git a/rtdata/icons/hi128-app-rawtherapee.png b/rtdata/icons/hi128-app-rawtherapee.png new file mode 100644 index 000000000..979183116 Binary files /dev/null and b/rtdata/icons/hi128-app-rawtherapee.png differ diff --git a/rtdata/icons/hi16-app-rawtherapee.png b/rtdata/icons/hi16-app-rawtherapee.png new file mode 100644 index 000000000..8c4731848 Binary files /dev/null and b/rtdata/icons/hi16-app-rawtherapee.png differ diff --git a/rtdata/icons/hi24-app-rawtherapee.png b/rtdata/icons/hi24-app-rawtherapee.png new file mode 100644 index 000000000..f6c8ef1a0 Binary files /dev/null and b/rtdata/icons/hi24-app-rawtherapee.png differ diff --git a/rtdata/icons/hi256-app-rawtherapee.png b/rtdata/icons/hi256-app-rawtherapee.png new file mode 100644 index 000000000..5cb7d751f Binary files /dev/null and b/rtdata/icons/hi256-app-rawtherapee.png differ diff --git a/rtdata/icons/hi32-app-rawtherapee.png b/rtdata/icons/hi32-app-rawtherapee.png new file mode 100644 index 000000000..380429e13 Binary files /dev/null and b/rtdata/icons/hi32-app-rawtherapee.png differ diff --git a/rtdata/icons/hi48-app-rawtherapee.png b/rtdata/icons/hi48-app-rawtherapee.png new file mode 100644 index 000000000..fc82d5ae3 Binary files /dev/null and b/rtdata/icons/hi48-app-rawtherapee.png differ diff --git a/rtdata/icons/mime-types b/rtdata/icons/mime-types new file mode 100644 index 000000000..c232119ee --- /dev/null +++ b/rtdata/icons/mime-types @@ -0,0 +1,36 @@ +# Add all image extensions supported by RT to this file, using the image/x- format. +# Convert this human-readable list into a desktop file format using +# tr -d '\n' < mime-types +image/jpeg; +image/png; +image/tiff; +image/x-adobe-dng; +image/x-canon-cr2; +image/x-canon-crf; +image/x-canon-crw; +image/x-fuji-raf; +image/x-jpg; +image/x-kodak-dcr; +image/x-kodak-k25; +image/x-kodak-kdc; +image/x-mamiya-mef; +image/x-minolta-mrw; +image/x-nikon-nef; +image/x-nikon-nrw; +image/x-olympus-orf; +image/x-panasonic-raw; +image/x-panasonic-rw2; +image/x-pentax-pef; +image/x-pentax-raw; +image/x-raw; +image/x-rwz; +image/x-samsung-srw; +image/x-sony-arw; +image/x-sony-sr2; +image/x-sony-srf; +image/x-hasselblad-3fr; +image/x-hasselblad-fff; +image/x-leaf-mos; +image/x-phaseone-iiq; +image/x-tif; +inode/directory; diff --git a/rtdata/icons/rawtherapee.desktop.in b/rtdata/icons/rawtherapee.desktop.in new file mode 100644 index 000000000..9ef7db566 --- /dev/null +++ b/rtdata/icons/rawtherapee.desktop.in @@ -0,0 +1,17 @@ +[Desktop Entry] +Type=Application +Version=1.0 +Name=RawTherapee +GenericName=Raw photo editor +GenericName[cs]=Editor raw obrázků +GenericName[fr]=Éditeur d'images raw +GenericName[pl]=Edytor zdjęć raw +Comment=An advanced photo development program +Comment[cs]=Program pro konverzi a zpracování digitálních raw fotografií. +Comment[fr]=Logiciel de conversion et de traitement de photos numériques de format raw (but de capteur). +Comment[pl]=Zaawansowany program do wywoływania zdjęć +Icon=rawtherapee +Exec=rawtherapee %f +Terminal=false +MimeType=image/jpeg;image/png;image/tiff;image/x-adobe-dng;image/x-canon-cr2;image/x-canon-crf;image/x-canon-crw;image/x-fuji-raf;image/x-jpg;image/x-kodak-dcr;image/x-kodak-k25;image/x-kodak-kdc;image/x-mamiya-mef;image/x-minolta-mrw;image/x-nikon-nef;image/x-nikon-nrw;image/x-olympus-orf;image/x-panasonic-raw;image/x-panasonic-rw2;image/x-pentax-pef;image/x-pentax-raw;image/x-raw;image/x-rwz;image/x-samsung-srw;image/x-sony-arw;image/x-sony-sr2;image/x-sony-srf;image/x-hasselblad-3fr;image/x-hasselblad-fff;image/x-leaf-mos;image/x-phaseone-iiq;image/x-tif; +Categories=Photography;Graphics;2DGraphics;RasterGraphics;GTK; diff --git a/rtdata/images/Chanmixer-B.png b/rtdata/images/Chanmixer-B.png new file mode 100644 index 000000000..0e12209f2 Binary files /dev/null and b/rtdata/images/Chanmixer-B.png differ diff --git a/rtdata/images/Chanmixer-BB.png b/rtdata/images/Chanmixer-BB.png new file mode 100644 index 000000000..6804bdf4a Binary files /dev/null and b/rtdata/images/Chanmixer-BB.png differ diff --git a/rtdata/images/Chanmixer-BG.png b/rtdata/images/Chanmixer-BG.png new file mode 100644 index 000000000..58012aa55 Binary files /dev/null and b/rtdata/images/Chanmixer-BG.png differ diff --git a/rtdata/images/Chanmixer-BR.png b/rtdata/images/Chanmixer-BR.png new file mode 100644 index 000000000..1c3457e14 Binary files /dev/null and b/rtdata/images/Chanmixer-BR.png differ diff --git a/rtdata/images/Chanmixer-BY.png b/rtdata/images/Chanmixer-BY.png new file mode 100644 index 000000000..c630ffb29 Binary files /dev/null and b/rtdata/images/Chanmixer-BY.png differ diff --git a/rtdata/images/Chanmixer-C.png b/rtdata/images/Chanmixer-C.png new file mode 100644 index 000000000..15aa0c08c Binary files /dev/null and b/rtdata/images/Chanmixer-C.png differ diff --git a/rtdata/images/Chanmixer-G.png b/rtdata/images/Chanmixer-G.png new file mode 100644 index 000000000..566babb8b Binary files /dev/null and b/rtdata/images/Chanmixer-G.png differ diff --git a/rtdata/images/Chanmixer-GB.png b/rtdata/images/Chanmixer-GB.png new file mode 100644 index 000000000..cfceceaea Binary files /dev/null and b/rtdata/images/Chanmixer-GB.png differ diff --git a/rtdata/images/Chanmixer-GG.png b/rtdata/images/Chanmixer-GG.png new file mode 100644 index 000000000..00f928236 Binary files /dev/null and b/rtdata/images/Chanmixer-GG.png differ diff --git a/rtdata/images/Chanmixer-GR.png b/rtdata/images/Chanmixer-GR.png new file mode 100644 index 000000000..827210e97 Binary files /dev/null and b/rtdata/images/Chanmixer-GR.png differ diff --git a/rtdata/images/Chanmixer-M.png b/rtdata/images/Chanmixer-M.png new file mode 100644 index 000000000..b10dc5790 Binary files /dev/null and b/rtdata/images/Chanmixer-M.png differ diff --git a/rtdata/images/Chanmixer-O.png b/rtdata/images/Chanmixer-O.png new file mode 100644 index 000000000..8f90ae8bb Binary files /dev/null and b/rtdata/images/Chanmixer-O.png differ diff --git a/rtdata/images/Chanmixer-P.png b/rtdata/images/Chanmixer-P.png new file mode 100644 index 000000000..c3c412807 Binary files /dev/null and b/rtdata/images/Chanmixer-P.png differ diff --git a/rtdata/images/Chanmixer-R.png b/rtdata/images/Chanmixer-R.png new file mode 100644 index 000000000..5a75d9f88 Binary files /dev/null and b/rtdata/images/Chanmixer-R.png differ diff --git a/rtdata/images/Chanmixer-RB.png b/rtdata/images/Chanmixer-RB.png new file mode 100644 index 000000000..42cf9bd1b Binary files /dev/null and b/rtdata/images/Chanmixer-RB.png differ diff --git a/rtdata/images/Chanmixer-RG.png b/rtdata/images/Chanmixer-RG.png new file mode 100644 index 000000000..f74600517 Binary files /dev/null and b/rtdata/images/Chanmixer-RG.png differ diff --git a/rtdata/images/Chanmixer-RR.png b/rtdata/images/Chanmixer-RR.png new file mode 100644 index 000000000..300b0429e Binary files /dev/null and b/rtdata/images/Chanmixer-RR.png differ diff --git a/rtdata/images/Chanmixer-Y.png b/rtdata/images/Chanmixer-Y.png new file mode 100644 index 000000000..98d9b6f83 Binary files /dev/null and b/rtdata/images/Chanmixer-Y.png differ diff --git a/rtdata/images/Dark/actions/Chanmixer-Bgamma.png b/rtdata/images/Dark/actions/Chanmixer-Bgamma.png new file mode 100644 index 000000000..8698988a9 Binary files /dev/null and b/rtdata/images/Dark/actions/Chanmixer-Bgamma.png differ diff --git a/rtdata/images/Dark/actions/Chanmixer-Ggamma.png b/rtdata/images/Dark/actions/Chanmixer-Ggamma.png new file mode 100644 index 000000000..d0539758c Binary files /dev/null and b/rtdata/images/Dark/actions/Chanmixer-Ggamma.png differ diff --git a/rtdata/images/Dark/actions/Chanmixer-Rgamma.png b/rtdata/images/Dark/actions/Chanmixer-Rgamma.png new file mode 100644 index 000000000..b1b7fb604 Binary files /dev/null and b/rtdata/images/Dark/actions/Chanmixer-Rgamma.png differ diff --git a/rtdata/images/Dark/actions/PanelEnding.png b/rtdata/images/Dark/actions/PanelEnding.png new file mode 100644 index 000000000..be7729164 Binary files /dev/null and b/rtdata/images/Dark/actions/PanelEnding.png differ diff --git a/rtdata/images/Dark/actions/ajd-ca-blue1.png b/rtdata/images/Dark/actions/ajd-ca-blue1.png new file mode 100644 index 000000000..7a47267df Binary files /dev/null and b/rtdata/images/Dark/actions/ajd-ca-blue1.png differ diff --git a/rtdata/images/Dark/actions/ajd-ca-blue2.png b/rtdata/images/Dark/actions/ajd-ca-blue2.png new file mode 100644 index 000000000..dfb458300 Binary files /dev/null and b/rtdata/images/Dark/actions/ajd-ca-blue2.png differ diff --git a/rtdata/images/Dark/actions/ajd-ca-red1.png b/rtdata/images/Dark/actions/ajd-ca-red1.png new file mode 100644 index 000000000..1e45c5035 Binary files /dev/null and b/rtdata/images/Dark/actions/ajd-ca-red1.png differ diff --git a/rtdata/images/Dark/actions/ajd-ca-red2.png b/rtdata/images/Dark/actions/ajd-ca-red2.png new file mode 100644 index 000000000..e5da9e005 Binary files /dev/null and b/rtdata/images/Dark/actions/ajd-ca-red2.png differ diff --git a/rtdata/images/Dark/actions/ajd-wb-bluered1.png b/rtdata/images/Dark/actions/ajd-wb-bluered1.png new file mode 100644 index 000000000..3c8473451 Binary files /dev/null and b/rtdata/images/Dark/actions/ajd-wb-bluered1.png differ diff --git a/rtdata/images/Dark/actions/ajd-wb-bluered2.png b/rtdata/images/Dark/actions/ajd-wb-bluered2.png new file mode 100644 index 000000000..0f06a770e Binary files /dev/null and b/rtdata/images/Dark/actions/ajd-wb-bluered2.png differ diff --git a/rtdata/images/Dark/actions/ajd-wb-green1.png b/rtdata/images/Dark/actions/ajd-wb-green1.png new file mode 100644 index 000000000..4f33551d6 Binary files /dev/null and b/rtdata/images/Dark/actions/ajd-wb-green1.png differ diff --git a/rtdata/images/Dark/actions/ajd-wb-green2.png b/rtdata/images/Dark/actions/ajd-wb-green2.png new file mode 100644 index 000000000..a9a7e8553 Binary files /dev/null and b/rtdata/images/Dark/actions/ajd-wb-green2.png differ diff --git a/rtdata/images/Dark/actions/ajd-wb-temp1.png b/rtdata/images/Dark/actions/ajd-wb-temp1.png new file mode 100644 index 000000000..3c8473451 Binary files /dev/null and b/rtdata/images/Dark/actions/ajd-wb-temp1.png differ diff --git a/rtdata/images/Dark/actions/ajd-wb-temp2.png b/rtdata/images/Dark/actions/ajd-wb-temp2.png new file mode 100644 index 000000000..2b0c7c0ef Binary files /dev/null and b/rtdata/images/Dark/actions/ajd-wb-temp2.png differ diff --git a/rtdata/images/Dark/actions/beforeafter.png b/rtdata/images/Dark/actions/beforeafter.png new file mode 100644 index 000000000..cd4e1a792 Binary files /dev/null and b/rtdata/images/Dark/actions/beforeafter.png differ diff --git a/rtdata/images/Dark/actions/cglabel0.png b/rtdata/images/Dark/actions/cglabel0.png new file mode 100644 index 000000000..af4abc914 Binary files /dev/null and b/rtdata/images/Dark/actions/cglabel0.png differ diff --git a/rtdata/images/Dark/actions/cglabel1.png b/rtdata/images/Dark/actions/cglabel1.png new file mode 100644 index 000000000..6337a6476 Binary files /dev/null and b/rtdata/images/Dark/actions/cglabel1.png differ diff --git a/rtdata/images/Dark/actions/cglabel2.png b/rtdata/images/Dark/actions/cglabel2.png new file mode 100644 index 000000000..a5b843c0c Binary files /dev/null and b/rtdata/images/Dark/actions/cglabel2.png differ diff --git a/rtdata/images/Dark/actions/cglabel3.png b/rtdata/images/Dark/actions/cglabel3.png new file mode 100644 index 000000000..a3f3da7a9 Binary files /dev/null and b/rtdata/images/Dark/actions/cglabel3.png differ diff --git a/rtdata/images/Dark/actions/cglabel4.png b/rtdata/images/Dark/actions/cglabel4.png new file mode 100644 index 000000000..3e048f36c Binary files /dev/null and b/rtdata/images/Dark/actions/cglabel4.png differ diff --git a/rtdata/images/Dark/actions/cglabel5.png b/rtdata/images/Dark/actions/cglabel5.png new file mode 100644 index 000000000..323be0cb9 Binary files /dev/null and b/rtdata/images/Dark/actions/cglabel5.png differ diff --git a/rtdata/images/Dark/actions/clabel0.png b/rtdata/images/Dark/actions/clabel0.png new file mode 100644 index 000000000..5c2484a36 Binary files /dev/null and b/rtdata/images/Dark/actions/clabel0.png differ diff --git a/rtdata/images/Dark/actions/clabel1.png b/rtdata/images/Dark/actions/clabel1.png new file mode 100644 index 000000000..87bd0ea83 Binary files /dev/null and b/rtdata/images/Dark/actions/clabel1.png differ diff --git a/rtdata/images/Dark/actions/clabel2.png b/rtdata/images/Dark/actions/clabel2.png new file mode 100644 index 000000000..b8ca4f72b Binary files /dev/null and b/rtdata/images/Dark/actions/clabel2.png differ diff --git a/rtdata/images/Dark/actions/clabel3.png b/rtdata/images/Dark/actions/clabel3.png new file mode 100644 index 000000000..d9dced467 Binary files /dev/null and b/rtdata/images/Dark/actions/clabel3.png differ diff --git a/rtdata/images/Dark/actions/clabel4.png b/rtdata/images/Dark/actions/clabel4.png new file mode 100644 index 000000000..2afb44650 Binary files /dev/null and b/rtdata/images/Dark/actions/clabel4.png differ diff --git a/rtdata/images/Dark/actions/clabel5.png b/rtdata/images/Dark/actions/clabel5.png new file mode 100644 index 000000000..aef022fce Binary files /dev/null and b/rtdata/images/Dark/actions/clabel5.png differ diff --git a/rtdata/images/Dark/actions/closedhand.png b/rtdata/images/Dark/actions/closedhand.png new file mode 100644 index 000000000..e9560f5a7 Binary files /dev/null and b/rtdata/images/Dark/actions/closedhand.png differ diff --git a/rtdata/images/Dark/actions/colour.png b/rtdata/images/Dark/actions/colour.png new file mode 100644 index 000000000..e518dfa3a Binary files /dev/null and b/rtdata/images/Dark/actions/colour.png differ diff --git a/rtdata/images/Dark/actions/crop-auto.png b/rtdata/images/Dark/actions/crop-auto.png new file mode 100644 index 000000000..8cb57e799 Binary files /dev/null and b/rtdata/images/Dark/actions/crop-auto.png differ diff --git a/rtdata/images/Dark/actions/crop.png b/rtdata/images/Dark/actions/crop.png new file mode 100644 index 000000000..a9a339020 Binary files /dev/null and b/rtdata/images/Dark/actions/crop.png differ diff --git a/rtdata/images/Dark/actions/crossed-arrows-in.png b/rtdata/images/Dark/actions/crossed-arrows-in.png new file mode 100644 index 000000000..b2a2d8820 Binary files /dev/null and b/rtdata/images/Dark/actions/crossed-arrows-in.png differ diff --git a/rtdata/images/Dark/actions/crossed-arrows-out.png b/rtdata/images/Dark/actions/crossed-arrows-out.png new file mode 100644 index 000000000..e552d55ca Binary files /dev/null and b/rtdata/images/Dark/actions/crossed-arrows-out.png differ diff --git a/rtdata/images/Dark/actions/curveType-NURBS.png b/rtdata/images/Dark/actions/curveType-NURBS.png new file mode 100644 index 000000000..b891c89c7 Binary files /dev/null and b/rtdata/images/Dark/actions/curveType-NURBS.png differ diff --git a/rtdata/images/Dark/actions/curveType-controlPoints.png b/rtdata/images/Dark/actions/curveType-controlPoints.png new file mode 100644 index 000000000..54dbcc540 Binary files /dev/null and b/rtdata/images/Dark/actions/curveType-controlPoints.png differ diff --git a/rtdata/images/Dark/actions/curveType-flatLinear.png b/rtdata/images/Dark/actions/curveType-flatLinear.png new file mode 100644 index 000000000..6049e658c Binary files /dev/null and b/rtdata/images/Dark/actions/curveType-flatLinear.png differ diff --git a/rtdata/images/Dark/actions/curveType-linear.png b/rtdata/images/Dark/actions/curveType-linear.png new file mode 100644 index 000000000..67ff4390c Binary files /dev/null and b/rtdata/images/Dark/actions/curveType-linear.png differ diff --git a/rtdata/images/Dark/actions/curveType-parametric.png b/rtdata/images/Dark/actions/curveType-parametric.png new file mode 100644 index 000000000..dcf7b02b5 Binary files /dev/null and b/rtdata/images/Dark/actions/curveType-parametric.png differ diff --git a/rtdata/images/Dark/actions/curveType-spline.png b/rtdata/images/Dark/actions/curveType-spline.png new file mode 100644 index 000000000..b9c0527d3 Binary files /dev/null and b/rtdata/images/Dark/actions/curveType-spline.png differ diff --git a/rtdata/images/Dark/actions/detail.png b/rtdata/images/Dark/actions/detail.png new file mode 100644 index 000000000..b1af89c9e Binary files /dev/null and b/rtdata/images/Dark/actions/detail.png differ diff --git a/rtdata/images/Dark/actions/distorsion.png b/rtdata/images/Dark/actions/distorsion.png new file mode 100644 index 000000000..fc5200391 Binary files /dev/null and b/rtdata/images/Dark/actions/distorsion.png differ diff --git a/rtdata/images/Dark/actions/distortion-auto.png b/rtdata/images/Dark/actions/distortion-auto.png new file mode 100644 index 000000000..cc5ced965 Binary files /dev/null and b/rtdata/images/Dark/actions/distortion-auto.png differ diff --git a/rtdata/images/Dark/actions/distortion-barrel.png b/rtdata/images/Dark/actions/distortion-barrel.png new file mode 100644 index 000000000..0a19ac097 Binary files /dev/null and b/rtdata/images/Dark/actions/distortion-barrel.png differ diff --git a/rtdata/images/Dark/actions/distortion-pincushion.png b/rtdata/images/Dark/actions/distortion-pincushion.png new file mode 100644 index 000000000..cfdcfaf63 Binary files /dev/null and b/rtdata/images/Dark/actions/distortion-pincushion.png differ diff --git a/rtdata/images/Dark/actions/document-open-recent.png b/rtdata/images/Dark/actions/document-open-recent.png new file mode 100644 index 000000000..f2c126cb7 Binary files /dev/null and b/rtdata/images/Dark/actions/document-open-recent.png differ diff --git a/rtdata/images/Dark/actions/document-open.png b/rtdata/images/Dark/actions/document-open.png new file mode 100644 index 000000000..6d2ea0f34 Binary files /dev/null and b/rtdata/images/Dark/actions/document-open.png differ diff --git a/rtdata/images/Dark/actions/edit-copy.png b/rtdata/images/Dark/actions/edit-copy.png new file mode 100644 index 000000000..4736313a2 Binary files /dev/null and b/rtdata/images/Dark/actions/edit-copy.png differ diff --git a/rtdata/images/Dark/actions/edit-find.png b/rtdata/images/Dark/actions/edit-find.png new file mode 100644 index 000000000..d560c644b Binary files /dev/null and b/rtdata/images/Dark/actions/edit-find.png differ diff --git a/rtdata/images/Dark/actions/edit-paste.png b/rtdata/images/Dark/actions/edit-paste.png new file mode 100644 index 000000000..38871deec Binary files /dev/null and b/rtdata/images/Dark/actions/edit-paste.png differ diff --git a/rtdata/images/Dark/actions/edited-small.png b/rtdata/images/Dark/actions/edited-small.png new file mode 100644 index 000000000..f25997a59 Binary files /dev/null and b/rtdata/images/Dark/actions/edited-small.png differ diff --git a/rtdata/images/Dark/actions/edited.png b/rtdata/images/Dark/actions/edited.png new file mode 100644 index 000000000..95d058454 Binary files /dev/null and b/rtdata/images/Dark/actions/edited.png differ diff --git a/rtdata/images/Dark/actions/editedg-small.png b/rtdata/images/Dark/actions/editedg-small.png new file mode 100644 index 000000000..9eb229e75 Binary files /dev/null and b/rtdata/images/Dark/actions/editedg-small.png differ diff --git a/rtdata/images/Dark/actions/editednot-small.png b/rtdata/images/Dark/actions/editednot-small.png new file mode 100644 index 000000000..410bff81b Binary files /dev/null and b/rtdata/images/Dark/actions/editednot-small.png differ diff --git a/rtdata/images/Dark/actions/editednotg-small.png b/rtdata/images/Dark/actions/editednotg-small.png new file mode 100644 index 000000000..55bc28f2b Binary files /dev/null and b/rtdata/images/Dark/actions/editednotg-small.png differ diff --git a/rtdata/images/Dark/actions/editmodehand.png b/rtdata/images/Dark/actions/editmodehand.png new file mode 100644 index 000000000..2b231db06 Binary files /dev/null and b/rtdata/images/Dark/actions/editmodehand.png differ diff --git a/rtdata/images/Dark/actions/expanderClosed.png b/rtdata/images/Dark/actions/expanderClosed.png new file mode 100644 index 000000000..1de089570 Binary files /dev/null and b/rtdata/images/Dark/actions/expanderClosed.png differ diff --git a/rtdata/images/Dark/actions/expanderDisabled.png b/rtdata/images/Dark/actions/expanderDisabled.png new file mode 100644 index 000000000..1593dc5b5 Binary files /dev/null and b/rtdata/images/Dark/actions/expanderDisabled.png differ diff --git a/rtdata/images/Dark/actions/expanderEnabled.png b/rtdata/images/Dark/actions/expanderEnabled.png new file mode 100644 index 000000000..a3d16f51c Binary files /dev/null and b/rtdata/images/Dark/actions/expanderEnabled.png differ diff --git a/rtdata/images/Dark/actions/expanderInconsistent.png b/rtdata/images/Dark/actions/expanderInconsistent.png new file mode 100644 index 000000000..06619ca10 Binary files /dev/null and b/rtdata/images/Dark/actions/expanderInconsistent.png differ diff --git a/rtdata/images/Dark/actions/expanderOpened.png b/rtdata/images/Dark/actions/expanderOpened.png new file mode 100644 index 000000000..176e99dae Binary files /dev/null and b/rtdata/images/Dark/actions/expanderOpened.png differ diff --git a/rtdata/images/Dark/actions/exposure.png b/rtdata/images/Dark/actions/exposure.png new file mode 100644 index 000000000..f6abf8b87 Binary files /dev/null and b/rtdata/images/Dark/actions/exposure.png differ diff --git a/rtdata/images/Dark/actions/filter.png b/rtdata/images/Dark/actions/filter.png new file mode 100644 index 000000000..bd5dcb5f4 Binary files /dev/null and b/rtdata/images/Dark/actions/filter.png differ diff --git a/rtdata/images/Dark/actions/filterclear.png b/rtdata/images/Dark/actions/filterclear.png new file mode 100644 index 000000000..28c93061e Binary files /dev/null and b/rtdata/images/Dark/actions/filterclear.png differ diff --git a/rtdata/images/Dark/actions/fullscreen-exit.png b/rtdata/images/Dark/actions/fullscreen-exit.png new file mode 100644 index 000000000..55eb8e06d Binary files /dev/null and b/rtdata/images/Dark/actions/fullscreen-exit.png differ diff --git a/rtdata/images/Dark/actions/fullscreen.png b/rtdata/images/Dark/actions/fullscreen.png new file mode 100644 index 000000000..963409e9a Binary files /dev/null and b/rtdata/images/Dark/actions/fullscreen.png differ diff --git a/rtdata/images/Dark/actions/grayrated.png b/rtdata/images/Dark/actions/grayrated.png new file mode 100644 index 000000000..6866bc1d6 Binary files /dev/null and b/rtdata/images/Dark/actions/grayrated.png differ diff --git a/rtdata/images/Dark/actions/gtk-add.png b/rtdata/images/Dark/actions/gtk-add.png new file mode 100644 index 000000000..80abd6bfd Binary files /dev/null and b/rtdata/images/Dark/actions/gtk-add.png differ diff --git a/rtdata/images/Dark/actions/gtk-apply.png b/rtdata/images/Dark/actions/gtk-apply.png new file mode 100644 index 000000000..4790895e7 Binary files /dev/null and b/rtdata/images/Dark/actions/gtk-apply.png differ diff --git a/rtdata/images/Dark/actions/gtk-cancel.png b/rtdata/images/Dark/actions/gtk-cancel.png new file mode 100644 index 000000000..c76033ee9 Binary files /dev/null and b/rtdata/images/Dark/actions/gtk-cancel.png differ diff --git a/rtdata/images/Dark/actions/gtk-close-small.png b/rtdata/images/Dark/actions/gtk-close-small.png new file mode 100644 index 000000000..7abb7a95a Binary files /dev/null and b/rtdata/images/Dark/actions/gtk-close-small.png differ diff --git a/rtdata/images/Dark/actions/gtk-close.png b/rtdata/images/Dark/actions/gtk-close.png new file mode 100644 index 000000000..c76033ee9 Binary files /dev/null and b/rtdata/images/Dark/actions/gtk-close.png differ diff --git a/rtdata/images/Dark/actions/gtk-color-picker-small.png b/rtdata/images/Dark/actions/gtk-color-picker-small.png new file mode 100644 index 000000000..f10b7f0fe Binary files /dev/null and b/rtdata/images/Dark/actions/gtk-color-picker-small.png differ diff --git a/rtdata/images/Dark/actions/gtk-color-picker.png b/rtdata/images/Dark/actions/gtk-color-picker.png new file mode 100644 index 000000000..c79c3f3e9 Binary files /dev/null and b/rtdata/images/Dark/actions/gtk-color-picker.png differ diff --git a/rtdata/images/Dark/actions/gtk-copy.png b/rtdata/images/Dark/actions/gtk-copy.png new file mode 100644 index 000000000..4736313a2 Binary files /dev/null and b/rtdata/images/Dark/actions/gtk-copy.png differ diff --git a/rtdata/images/Dark/actions/gtk-edit.png b/rtdata/images/Dark/actions/gtk-edit.png new file mode 100644 index 000000000..8eabf5f09 Binary files /dev/null and b/rtdata/images/Dark/actions/gtk-edit.png differ diff --git a/rtdata/images/Dark/actions/gtk-find.png b/rtdata/images/Dark/actions/gtk-find.png new file mode 100644 index 000000000..d560c644b Binary files /dev/null and b/rtdata/images/Dark/actions/gtk-find.png differ diff --git a/rtdata/images/Dark/actions/gtk-media-play.png b/rtdata/images/Dark/actions/gtk-media-play.png new file mode 100644 index 000000000..2bd7ded54 Binary files /dev/null and b/rtdata/images/Dark/actions/gtk-media-play.png differ diff --git a/rtdata/images/Dark/actions/gtk-media-stop.png b/rtdata/images/Dark/actions/gtk-media-stop.png new file mode 100644 index 000000000..9d3b25ba0 Binary files /dev/null and b/rtdata/images/Dark/actions/gtk-media-stop.png differ diff --git a/rtdata/images/Dark/actions/gtk-ok.png b/rtdata/images/Dark/actions/gtk-ok.png new file mode 100644 index 000000000..4790895e7 Binary files /dev/null and b/rtdata/images/Dark/actions/gtk-ok.png differ diff --git a/rtdata/images/Dark/actions/gtk-open.png b/rtdata/images/Dark/actions/gtk-open.png new file mode 100644 index 000000000..6d2ea0f34 Binary files /dev/null and b/rtdata/images/Dark/actions/gtk-open.png differ diff --git a/rtdata/images/Dark/actions/gtk-paste.png b/rtdata/images/Dark/actions/gtk-paste.png new file mode 100644 index 000000000..38871deec Binary files /dev/null and b/rtdata/images/Dark/actions/gtk-paste.png differ diff --git a/rtdata/images/Dark/actions/gtk-preferences.png b/rtdata/images/Dark/actions/gtk-preferences.png new file mode 100644 index 000000000..1d3c0f398 Binary files /dev/null and b/rtdata/images/Dark/actions/gtk-preferences.png differ diff --git a/rtdata/images/Dark/actions/gtk-remove.png b/rtdata/images/Dark/actions/gtk-remove.png new file mode 100644 index 000000000..b789b5130 Binary files /dev/null and b/rtdata/images/Dark/actions/gtk-remove.png differ diff --git a/rtdata/images/Dark/actions/gtk-save-large.png b/rtdata/images/Dark/actions/gtk-save-large.png new file mode 100644 index 000000000..9b1ba463e Binary files /dev/null and b/rtdata/images/Dark/actions/gtk-save-large.png differ diff --git a/rtdata/images/Dark/actions/gtk-save.png b/rtdata/images/Dark/actions/gtk-save.png new file mode 100644 index 000000000..d72b9a2ad Binary files /dev/null and b/rtdata/images/Dark/actions/gtk-save.png differ diff --git a/rtdata/images/Dark/actions/gtk-undo-ltr-small.png b/rtdata/images/Dark/actions/gtk-undo-ltr-small.png new file mode 100644 index 000000000..b0dbf0b98 Binary files /dev/null and b/rtdata/images/Dark/actions/gtk-undo-ltr-small.png differ diff --git a/rtdata/images/Dark/actions/gtk-undo-ltr.png b/rtdata/images/Dark/actions/gtk-undo-ltr.png new file mode 100644 index 000000000..f66791abb Binary files /dev/null and b/rtdata/images/Dark/actions/gtk-undo-ltr.png differ diff --git a/rtdata/images/Dark/actions/gtk-undo-rtl-small.png b/rtdata/images/Dark/actions/gtk-undo-rtl-small.png new file mode 100644 index 000000000..7ef3d5f67 Binary files /dev/null and b/rtdata/images/Dark/actions/gtk-undo-rtl-small.png differ diff --git a/rtdata/images/Dark/actions/gtk-undo-rtl.png b/rtdata/images/Dark/actions/gtk-undo-rtl.png new file mode 100644 index 000000000..1c6fc0537 Binary files /dev/null and b/rtdata/images/Dark/actions/gtk-undo-rtl.png differ diff --git a/rtdata/images/Dark/actions/gtk-undoall-ltr.png b/rtdata/images/Dark/actions/gtk-undoall-ltr.png new file mode 100644 index 000000000..00c61c2a8 Binary files /dev/null and b/rtdata/images/Dark/actions/gtk-undoall-ltr.png differ diff --git a/rtdata/images/Dark/actions/gtk-undoall-rtl.png b/rtdata/images/Dark/actions/gtk-undoall-rtl.png new file mode 100644 index 000000000..cf92a7017 Binary files /dev/null and b/rtdata/images/Dark/actions/gtk-undoall-rtl.png differ diff --git a/rtdata/images/Dark/actions/gtk-zoom-100-small.png b/rtdata/images/Dark/actions/gtk-zoom-100-small.png new file mode 100644 index 000000000..43abd73a4 Binary files /dev/null and b/rtdata/images/Dark/actions/gtk-zoom-100-small.png differ diff --git a/rtdata/images/Dark/actions/gtk-zoom-100.png b/rtdata/images/Dark/actions/gtk-zoom-100.png new file mode 100644 index 000000000..a00a78d68 Binary files /dev/null and b/rtdata/images/Dark/actions/gtk-zoom-100.png differ diff --git a/rtdata/images/Dark/actions/gtk-zoom-crop.png b/rtdata/images/Dark/actions/gtk-zoom-crop.png new file mode 100644 index 000000000..f20e826ba Binary files /dev/null and b/rtdata/images/Dark/actions/gtk-zoom-crop.png differ diff --git a/rtdata/images/Dark/actions/gtk-zoom-fit.png b/rtdata/images/Dark/actions/gtk-zoom-fit.png new file mode 100644 index 000000000..670515eb4 Binary files /dev/null and b/rtdata/images/Dark/actions/gtk-zoom-fit.png differ diff --git a/rtdata/images/Dark/actions/gtk-zoom-in-small.png b/rtdata/images/Dark/actions/gtk-zoom-in-small.png new file mode 100644 index 000000000..291c8ecac Binary files /dev/null and b/rtdata/images/Dark/actions/gtk-zoom-in-small.png differ diff --git a/rtdata/images/Dark/actions/gtk-zoom-in.png b/rtdata/images/Dark/actions/gtk-zoom-in.png new file mode 100644 index 000000000..ee8688d43 Binary files /dev/null and b/rtdata/images/Dark/actions/gtk-zoom-in.png differ diff --git a/rtdata/images/Dark/actions/gtk-zoom-out-small.png b/rtdata/images/Dark/actions/gtk-zoom-out-small.png new file mode 100644 index 000000000..93b771182 Binary files /dev/null and b/rtdata/images/Dark/actions/gtk-zoom-out-small.png differ diff --git a/rtdata/images/Dark/actions/gtk-zoom-out.png b/rtdata/images/Dark/actions/gtk-zoom-out.png new file mode 100644 index 000000000..aeec6b0fc Binary files /dev/null and b/rtdata/images/Dark/actions/gtk-zoom-out.png differ diff --git a/rtdata/images/Dark/actions/histBar.png b/rtdata/images/Dark/actions/histBar.png new file mode 100644 index 000000000..24ef6b45f Binary files /dev/null and b/rtdata/images/Dark/actions/histBar.png differ diff --git a/rtdata/images/Dark/actions/histBarg.png b/rtdata/images/Dark/actions/histBarg.png new file mode 100644 index 000000000..89d20ccff Binary files /dev/null and b/rtdata/images/Dark/actions/histBarg.png differ diff --git a/rtdata/images/Dark/actions/histBlue.png b/rtdata/images/Dark/actions/histBlue.png new file mode 100644 index 000000000..53c447a1c Binary files /dev/null and b/rtdata/images/Dark/actions/histBlue.png differ diff --git a/rtdata/images/Dark/actions/histBlueg.png b/rtdata/images/Dark/actions/histBlueg.png new file mode 100644 index 000000000..ac205219d Binary files /dev/null and b/rtdata/images/Dark/actions/histBlueg.png differ diff --git a/rtdata/images/Dark/actions/histChro.png b/rtdata/images/Dark/actions/histChro.png new file mode 100644 index 000000000..021a18222 Binary files /dev/null and b/rtdata/images/Dark/actions/histChro.png differ diff --git a/rtdata/images/Dark/actions/histChrog.png b/rtdata/images/Dark/actions/histChrog.png new file mode 100644 index 000000000..342311f5f Binary files /dev/null and b/rtdata/images/Dark/actions/histChrog.png differ diff --git a/rtdata/images/Dark/actions/histFull.png b/rtdata/images/Dark/actions/histFull.png new file mode 100644 index 000000000..78f9ee96c Binary files /dev/null and b/rtdata/images/Dark/actions/histFull.png differ diff --git a/rtdata/images/Dark/actions/histFullg.png b/rtdata/images/Dark/actions/histFullg.png new file mode 100644 index 000000000..ffbbe1c2b Binary files /dev/null and b/rtdata/images/Dark/actions/histFullg.png differ diff --git a/rtdata/images/Dark/actions/histGreen.png b/rtdata/images/Dark/actions/histGreen.png new file mode 100644 index 000000000..54eebe37e Binary files /dev/null and b/rtdata/images/Dark/actions/histGreen.png differ diff --git a/rtdata/images/Dark/actions/histGreeng.png b/rtdata/images/Dark/actions/histGreeng.png new file mode 100644 index 000000000..33c138cae Binary files /dev/null and b/rtdata/images/Dark/actions/histGreeng.png differ diff --git a/rtdata/images/Dark/actions/histRaw.png b/rtdata/images/Dark/actions/histRaw.png new file mode 100644 index 000000000..36e1a5a31 Binary files /dev/null and b/rtdata/images/Dark/actions/histRaw.png differ diff --git a/rtdata/images/Dark/actions/histRawg.png b/rtdata/images/Dark/actions/histRawg.png new file mode 100644 index 000000000..1b9d286b3 Binary files /dev/null and b/rtdata/images/Dark/actions/histRawg.png differ diff --git a/rtdata/images/Dark/actions/histRed.png b/rtdata/images/Dark/actions/histRed.png new file mode 100644 index 000000000..ce7fddcd3 Binary files /dev/null and b/rtdata/images/Dark/actions/histRed.png differ diff --git a/rtdata/images/Dark/actions/histRedg.png b/rtdata/images/Dark/actions/histRedg.png new file mode 100644 index 000000000..b75a66995 Binary files /dev/null and b/rtdata/images/Dark/actions/histRedg.png differ diff --git a/rtdata/images/Dark/actions/histValue.png b/rtdata/images/Dark/actions/histValue.png new file mode 100644 index 000000000..451004889 Binary files /dev/null and b/rtdata/images/Dark/actions/histValue.png differ diff --git a/rtdata/images/Dark/actions/histValueg.png b/rtdata/images/Dark/actions/histValueg.png new file mode 100644 index 000000000..31d6f63e5 Binary files /dev/null and b/rtdata/images/Dark/actions/histValueg.png differ diff --git a/rtdata/images/Dark/actions/image-editor.png b/rtdata/images/Dark/actions/image-editor.png new file mode 100644 index 000000000..cf87bc311 Binary files /dev/null and b/rtdata/images/Dark/actions/image-editor.png differ diff --git a/rtdata/images/Dark/actions/info.png b/rtdata/images/Dark/actions/info.png new file mode 100644 index 000000000..6ce41bad3 Binary files /dev/null and b/rtdata/images/Dark/actions/info.png differ diff --git a/rtdata/images/Dark/actions/list-add-small.png b/rtdata/images/Dark/actions/list-add-small.png new file mode 100644 index 000000000..15002fe13 Binary files /dev/null and b/rtdata/images/Dark/actions/list-add-small.png differ diff --git a/rtdata/images/Dark/actions/list-add.png b/rtdata/images/Dark/actions/list-add.png new file mode 100644 index 000000000..80abd6bfd Binary files /dev/null and b/rtdata/images/Dark/actions/list-add.png differ diff --git a/rtdata/images/Dark/actions/list-remove-red-small.png b/rtdata/images/Dark/actions/list-remove-red-small.png new file mode 100644 index 000000000..71650328f Binary files /dev/null and b/rtdata/images/Dark/actions/list-remove-red-small.png differ diff --git a/rtdata/images/Dark/actions/list-remove.png b/rtdata/images/Dark/actions/list-remove.png new file mode 100644 index 000000000..b789b5130 Binary files /dev/null and b/rtdata/images/Dark/actions/list-remove.png differ diff --git a/rtdata/images/Dark/actions/lock-off.png b/rtdata/images/Dark/actions/lock-off.png new file mode 100644 index 000000000..c4dbfe1af Binary files /dev/null and b/rtdata/images/Dark/actions/lock-off.png differ diff --git a/rtdata/images/Dark/actions/lock-on.png b/rtdata/images/Dark/actions/lock-on.png new file mode 100644 index 000000000..23366d571 Binary files /dev/null and b/rtdata/images/Dark/actions/lock-on.png differ diff --git a/rtdata/images/Dark/actions/media-usb.png b/rtdata/images/Dark/actions/media-usb.png new file mode 100644 index 000000000..5c46c9464 Binary files /dev/null and b/rtdata/images/Dark/actions/media-usb.png differ diff --git a/rtdata/images/Dark/actions/meta.png b/rtdata/images/Dark/actions/meta.png new file mode 100644 index 000000000..5c9c05d3f Binary files /dev/null and b/rtdata/images/Dark/actions/meta.png differ diff --git a/rtdata/images/Dark/actions/nav-next.png b/rtdata/images/Dark/actions/nav-next.png new file mode 100644 index 000000000..a3e8ed0b0 Binary files /dev/null and b/rtdata/images/Dark/actions/nav-next.png differ diff --git a/rtdata/images/Dark/actions/nav-prev.png b/rtdata/images/Dark/actions/nav-prev.png new file mode 100644 index 000000000..cd621d372 Binary files /dev/null and b/rtdata/images/Dark/actions/nav-prev.png differ diff --git a/rtdata/images/Dark/actions/nav-sync.png b/rtdata/images/Dark/actions/nav-sync.png new file mode 100644 index 000000000..cbad9711e Binary files /dev/null and b/rtdata/images/Dark/actions/nav-sync.png differ diff --git a/rtdata/images/Dark/actions/new-detail-window.png b/rtdata/images/Dark/actions/new-detail-window.png new file mode 100644 index 000000000..43b39decf Binary files /dev/null and b/rtdata/images/Dark/actions/new-detail-window.png differ diff --git a/rtdata/images/Dark/actions/openhand.png b/rtdata/images/Dark/actions/openhand.png new file mode 100644 index 000000000..66c13d890 Binary files /dev/null and b/rtdata/images/Dark/actions/openhand.png differ diff --git a/rtdata/images/Dark/actions/panel-to-bottom.png b/rtdata/images/Dark/actions/panel-to-bottom.png new file mode 100644 index 000000000..7e4905a9c Binary files /dev/null and b/rtdata/images/Dark/actions/panel-to-bottom.png differ diff --git a/rtdata/images/Dark/actions/panel-to-left.png b/rtdata/images/Dark/actions/panel-to-left.png new file mode 100644 index 000000000..97f7494a1 Binary files /dev/null and b/rtdata/images/Dark/actions/panel-to-left.png differ diff --git a/rtdata/images/Dark/actions/panel-to-right.png b/rtdata/images/Dark/actions/panel-to-right.png new file mode 100644 index 000000000..d6af36001 Binary files /dev/null and b/rtdata/images/Dark/actions/panel-to-right.png differ diff --git a/rtdata/images/Dark/actions/panel-to-top.png b/rtdata/images/Dark/actions/panel-to-top.png new file mode 100644 index 000000000..d628cc598 Binary files /dev/null and b/rtdata/images/Dark/actions/panel-to-top.png differ diff --git a/rtdata/images/Dark/actions/perspective-h1.png b/rtdata/images/Dark/actions/perspective-h1.png new file mode 100644 index 000000000..ea470842d Binary files /dev/null and b/rtdata/images/Dark/actions/perspective-h1.png differ diff --git a/rtdata/images/Dark/actions/perspective-h2.png b/rtdata/images/Dark/actions/perspective-h2.png new file mode 100644 index 000000000..5cd371dfc Binary files /dev/null and b/rtdata/images/Dark/actions/perspective-h2.png differ diff --git a/rtdata/images/Dark/actions/perspective-v1.png b/rtdata/images/Dark/actions/perspective-v1.png new file mode 100644 index 000000000..e42755116 Binary files /dev/null and b/rtdata/images/Dark/actions/perspective-v1.png differ diff --git a/rtdata/images/Dark/actions/perspective-v2.png b/rtdata/images/Dark/actions/perspective-v2.png new file mode 100644 index 000000000..489e3bd02 Binary files /dev/null and b/rtdata/images/Dark/actions/perspective-v2.png differ diff --git a/rtdata/images/Dark/actions/popuparrow.png b/rtdata/images/Dark/actions/popuparrow.png new file mode 100644 index 000000000..6e67d45b4 Binary files /dev/null and b/rtdata/images/Dark/actions/popuparrow.png differ diff --git a/rtdata/images/Dark/actions/previewmodeB-off.png b/rtdata/images/Dark/actions/previewmodeB-off.png new file mode 100644 index 000000000..1ff087b4d Binary files /dev/null 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 new file mode 100644 index 000000000..6403fc722 Binary files /dev/null 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 new file mode 100644 index 000000000..05a75ee25 Binary files /dev/null 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 new file mode 100644 index 000000000..a1f462cb2 Binary files /dev/null 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 new file mode 100644 index 000000000..d5071108a Binary files /dev/null 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 new file mode 100644 index 000000000..f71b27965 Binary files /dev/null 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 new file mode 100644 index 000000000..5c9b2d0e8 Binary files /dev/null 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 new file mode 100644 index 000000000..8f5b9207e Binary files /dev/null and b/rtdata/images/Dark/actions/previewmodeBC2-on.png differ diff --git a/rtdata/images/Dark/actions/previewmodeF-off.png b/rtdata/images/Dark/actions/previewmodeF-off.png new file mode 100644 index 000000000..519de02bc Binary files /dev/null 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 new file mode 100644 index 000000000..3910e6a20 Binary files /dev/null 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 new file mode 100644 index 000000000..e25911324 Binary files /dev/null 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 new file mode 100644 index 000000000..db31667ed Binary files /dev/null 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 new file mode 100644 index 000000000..d24dea76f Binary files /dev/null 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 new file mode 100644 index 000000000..11b745e09 Binary files /dev/null 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 new file mode 100644 index 000000000..9aef77301 Binary files /dev/null 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 new file mode 100644 index 000000000..5fb0f996e Binary files /dev/null and b/rtdata/images/Dark/actions/previewmodeR-on.png differ diff --git a/rtdata/images/Dark/actions/processing-pause.png b/rtdata/images/Dark/actions/processing-pause.png new file mode 100644 index 000000000..967c4a339 Binary files /dev/null and b/rtdata/images/Dark/actions/processing-pause.png differ diff --git a/rtdata/images/Dark/actions/processing-play.png b/rtdata/images/Dark/actions/processing-play.png new file mode 100644 index 000000000..d959d4a7c Binary files /dev/null and b/rtdata/images/Dark/actions/processing-play.png differ diff --git a/rtdata/images/Dark/actions/processing-thumbnail.png b/rtdata/images/Dark/actions/processing-thumbnail.png new file mode 100644 index 000000000..15a8af3f1 Binary files /dev/null and b/rtdata/images/Dark/actions/processing-thumbnail.png differ diff --git a/rtdata/images/Dark/actions/processing.png b/rtdata/images/Dark/actions/processing.png new file mode 100644 index 000000000..78592c44a Binary files /dev/null and b/rtdata/images/Dark/actions/processing.png differ diff --git a/rtdata/images/Dark/actions/profile-filled.png b/rtdata/images/Dark/actions/profile-filled.png new file mode 100644 index 000000000..8e39de5f2 Binary files /dev/null and b/rtdata/images/Dark/actions/profile-filled.png differ diff --git a/rtdata/images/Dark/actions/profile-partial.png b/rtdata/images/Dark/actions/profile-partial.png new file mode 100644 index 000000000..70c77fdff Binary files /dev/null and b/rtdata/images/Dark/actions/profile-partial.png differ diff --git a/rtdata/images/Dark/actions/rated.png b/rtdata/images/Dark/actions/rated.png new file mode 100644 index 000000000..ff1b949d2 Binary files /dev/null and b/rtdata/images/Dark/actions/rated.png differ diff --git a/rtdata/images/Dark/actions/ratednot.png b/rtdata/images/Dark/actions/ratednot.png new file mode 100644 index 000000000..82af59b91 Binary files /dev/null and b/rtdata/images/Dark/actions/ratednot.png differ diff --git a/rtdata/images/Dark/actions/ratednotg.png b/rtdata/images/Dark/actions/ratednotg.png new file mode 100644 index 000000000..4bf6f1a0c Binary files /dev/null and b/rtdata/images/Dark/actions/ratednotg.png differ diff --git a/rtdata/images/Dark/actions/raw.png b/rtdata/images/Dark/actions/raw.png new file mode 100644 index 000000000..d42599483 Binary files /dev/null and b/rtdata/images/Dark/actions/raw.png differ diff --git a/rtdata/images/Dark/actions/refresh-red.png b/rtdata/images/Dark/actions/refresh-red.png new file mode 100644 index 000000000..8850fe544 Binary files /dev/null and b/rtdata/images/Dark/actions/refresh-red.png differ diff --git a/rtdata/images/Dark/actions/refresh-white.png b/rtdata/images/Dark/actions/refresh-white.png new file mode 100644 index 000000000..40f625275 Binary files /dev/null and b/rtdata/images/Dark/actions/refresh-white.png differ diff --git a/rtdata/images/Dark/actions/rotate-left-1.png b/rtdata/images/Dark/actions/rotate-left-1.png new file mode 100644 index 000000000..937598ca3 Binary files /dev/null and b/rtdata/images/Dark/actions/rotate-left-1.png differ diff --git a/rtdata/images/Dark/actions/rotate-left-2.png b/rtdata/images/Dark/actions/rotate-left-2.png new file mode 100644 index 000000000..20b3ff5da Binary files /dev/null and b/rtdata/images/Dark/actions/rotate-left-2.png differ diff --git a/rtdata/images/Dark/actions/rotate-left-3.png b/rtdata/images/Dark/actions/rotate-left-3.png new file mode 100644 index 000000000..635a50da6 Binary files /dev/null and b/rtdata/images/Dark/actions/rotate-left-3.png differ diff --git a/rtdata/images/Dark/actions/rotate-left.png b/rtdata/images/Dark/actions/rotate-left.png new file mode 100644 index 000000000..2f28a8cff Binary files /dev/null and b/rtdata/images/Dark/actions/rotate-left.png differ diff --git a/rtdata/images/Dark/actions/rotate-right-1.png b/rtdata/images/Dark/actions/rotate-right-1.png new file mode 100644 index 000000000..5bd9960ad Binary files /dev/null and b/rtdata/images/Dark/actions/rotate-right-1.png differ diff --git a/rtdata/images/Dark/actions/rotate-right-2.png b/rtdata/images/Dark/actions/rotate-right-2.png new file mode 100644 index 000000000..5da99f01e Binary files /dev/null and b/rtdata/images/Dark/actions/rotate-right-2.png differ diff --git a/rtdata/images/Dark/actions/rotate-right-3.png b/rtdata/images/Dark/actions/rotate-right-3.png new file mode 100644 index 000000000..9d2dd0e4f Binary files /dev/null and b/rtdata/images/Dark/actions/rotate-right-3.png differ diff --git a/rtdata/images/Dark/actions/rotate-right.png b/rtdata/images/Dark/actions/rotate-right.png new file mode 100644 index 000000000..b28d601c5 Binary files /dev/null and b/rtdata/images/Dark/actions/rotate-right.png differ diff --git a/rtdata/images/Dark/actions/rtwindow.png b/rtdata/images/Dark/actions/rtwindow.png new file mode 100644 index 000000000..8fcc7a7c4 Binary files /dev/null and b/rtdata/images/Dark/actions/rtwindow.png differ diff --git a/rtdata/images/Dark/actions/stock-flip-horizontal.png b/rtdata/images/Dark/actions/stock-flip-horizontal.png new file mode 100644 index 000000000..a963c9d6f Binary files /dev/null and b/rtdata/images/Dark/actions/stock-flip-horizontal.png differ diff --git a/rtdata/images/Dark/actions/stock-flip-vertical.png b/rtdata/images/Dark/actions/stock-flip-vertical.png new file mode 100644 index 000000000..65779151a Binary files /dev/null and b/rtdata/images/Dark/actions/stock-flip-vertical.png differ diff --git a/rtdata/images/Dark/actions/stock-rotate-270.png b/rtdata/images/Dark/actions/stock-rotate-270.png new file mode 100644 index 000000000..cb6d50093 Binary files /dev/null and b/rtdata/images/Dark/actions/stock-rotate-270.png differ diff --git a/rtdata/images/Dark/actions/stock-rotate-90.png b/rtdata/images/Dark/actions/stock-rotate-90.png new file mode 100644 index 000000000..bb697dc3a Binary files /dev/null and b/rtdata/images/Dark/actions/stock-rotate-90.png differ diff --git a/rtdata/images/Dark/actions/straighten-small.png b/rtdata/images/Dark/actions/straighten-small.png new file mode 100644 index 000000000..b7a2be89e Binary files /dev/null and b/rtdata/images/Dark/actions/straighten-small.png differ diff --git a/rtdata/images/Dark/actions/straighten.png b/rtdata/images/Dark/actions/straighten.png new file mode 100644 index 000000000..a1bfdf507 Binary files /dev/null and b/rtdata/images/Dark/actions/straighten.png differ diff --git a/rtdata/images/Dark/actions/toleftend.png b/rtdata/images/Dark/actions/toleftend.png new file mode 100644 index 000000000..a37b37d41 Binary files /dev/null and b/rtdata/images/Dark/actions/toleftend.png differ diff --git a/rtdata/images/Dark/actions/torightend.png b/rtdata/images/Dark/actions/torightend.png new file mode 100644 index 000000000..3ae0d4edd Binary files /dev/null and b/rtdata/images/Dark/actions/torightend.png differ diff --git a/rtdata/images/Dark/actions/transform.png b/rtdata/images/Dark/actions/transform.png new file mode 100644 index 000000000..ed030de57 Binary files /dev/null and b/rtdata/images/Dark/actions/transform.png differ diff --git a/rtdata/images/Dark/actions/trash-hide-deleted.png b/rtdata/images/Dark/actions/trash-hide-deleted.png new file mode 100644 index 000000000..59137cf35 Binary files /dev/null and b/rtdata/images/Dark/actions/trash-hide-deleted.png differ diff --git a/rtdata/images/Dark/actions/trash-show-empty.png b/rtdata/images/Dark/actions/trash-show-empty.png new file mode 100644 index 000000000..0c5da5cda Binary files /dev/null and b/rtdata/images/Dark/actions/trash-show-empty.png differ diff --git a/rtdata/images/Dark/actions/trash-show-full.png b/rtdata/images/Dark/actions/trash-show-full.png new file mode 100644 index 000000000..cc374db46 Binary files /dev/null and b/rtdata/images/Dark/actions/trash-show-full.png differ diff --git a/rtdata/images/Dark/actions/trash-thumbnail.png b/rtdata/images/Dark/actions/trash-thumbnail.png new file mode 100644 index 000000000..fad0363e0 Binary files /dev/null and b/rtdata/images/Dark/actions/trash-thumbnail.png differ diff --git a/rtdata/images/Dark/actions/trash.png b/rtdata/images/Dark/actions/trash.png new file mode 100644 index 000000000..0c5da5cda Binary files /dev/null and b/rtdata/images/Dark/actions/trash.png differ diff --git a/rtdata/images/Dark/actions/undelete-rtl.png b/rtdata/images/Dark/actions/undelete-rtl.png new file mode 100644 index 000000000..c8e052aed Binary files /dev/null and b/rtdata/images/Dark/actions/undelete-rtl.png differ diff --git a/rtdata/images/Dark/actions/undelete-thumbnail-rtl.png b/rtdata/images/Dark/actions/undelete-thumbnail-rtl.png new file mode 100644 index 000000000..adcf65e9a Binary files /dev/null and b/rtdata/images/Dark/actions/undelete-thumbnail-rtl.png differ diff --git a/rtdata/images/Dark/actions/undelete-thumbnail.png b/rtdata/images/Dark/actions/undelete-thumbnail.png new file mode 100644 index 000000000..adcf65e9a Binary files /dev/null and b/rtdata/images/Dark/actions/undelete-thumbnail.png differ diff --git a/rtdata/images/Dark/actions/undelete.png b/rtdata/images/Dark/actions/undelete.png new file mode 100644 index 000000000..c8e052aed Binary files /dev/null and b/rtdata/images/Dark/actions/undelete.png differ diff --git a/rtdata/images/Dark/actions/warnhl.png b/rtdata/images/Dark/actions/warnhl.png new file mode 100644 index 000000000..4ca870ec5 Binary files /dev/null and b/rtdata/images/Dark/actions/warnhl.png differ diff --git a/rtdata/images/Dark/actions/warnsh.png b/rtdata/images/Dark/actions/warnsh.png new file mode 100644 index 000000000..d8d558ccf Binary files /dev/null and b/rtdata/images/Dark/actions/warnsh.png differ diff --git a/rtdata/images/Dark/actions/wavelet.png b/rtdata/images/Dark/actions/wavelet.png new file mode 100644 index 000000000..97f4ce673 Binary files /dev/null and b/rtdata/images/Dark/actions/wavelet.png differ diff --git a/rtdata/images/Dark/actions/wb-auto.png b/rtdata/images/Dark/actions/wb-auto.png new file mode 100644 index 000000000..be4114604 Binary files /dev/null and b/rtdata/images/Dark/actions/wb-auto.png differ diff --git a/rtdata/images/Dark/actions/wb-camera.png b/rtdata/images/Dark/actions/wb-camera.png new file mode 100644 index 000000000..372fd14bb Binary files /dev/null and b/rtdata/images/Dark/actions/wb-camera.png differ diff --git a/rtdata/images/Dark/actions/wb-cloudy.png b/rtdata/images/Dark/actions/wb-cloudy.png new file mode 100644 index 000000000..cdef40096 Binary files /dev/null and b/rtdata/images/Dark/actions/wb-cloudy.png differ diff --git a/rtdata/images/Dark/actions/wb-custom.png b/rtdata/images/Dark/actions/wb-custom.png new file mode 100644 index 000000000..cc7b6ef3c Binary files /dev/null and b/rtdata/images/Dark/actions/wb-custom.png differ diff --git a/rtdata/images/Dark/actions/wb-flash.png b/rtdata/images/Dark/actions/wb-flash.png new file mode 100644 index 000000000..e8115b3d4 Binary files /dev/null and b/rtdata/images/Dark/actions/wb-flash.png differ diff --git a/rtdata/images/Dark/actions/wb-fluorescent.png b/rtdata/images/Dark/actions/wb-fluorescent.png new file mode 100644 index 000000000..4861c54b4 Binary files /dev/null and b/rtdata/images/Dark/actions/wb-fluorescent.png differ diff --git a/rtdata/images/Dark/actions/wb-lamp.png b/rtdata/images/Dark/actions/wb-lamp.png new file mode 100644 index 000000000..5086e362b Binary files /dev/null and b/rtdata/images/Dark/actions/wb-lamp.png differ diff --git a/rtdata/images/Dark/actions/wb-led.png b/rtdata/images/Dark/actions/wb-led.png new file mode 100644 index 000000000..749b2e703 Binary files /dev/null and b/rtdata/images/Dark/actions/wb-led.png differ diff --git a/rtdata/images/Dark/actions/wb-shade.png b/rtdata/images/Dark/actions/wb-shade.png new file mode 100644 index 000000000..3b908909c Binary files /dev/null and b/rtdata/images/Dark/actions/wb-shade.png differ diff --git a/rtdata/images/Dark/actions/wb-sun.png b/rtdata/images/Dark/actions/wb-sun.png new file mode 100644 index 000000000..880fd13f0 Binary files /dev/null and b/rtdata/images/Dark/actions/wb-sun.png differ diff --git a/rtdata/images/Dark/actions/wb-tungsten.png b/rtdata/images/Dark/actions/wb-tungsten.png new file mode 100644 index 000000000..48aef24a3 Binary files /dev/null and b/rtdata/images/Dark/actions/wb-tungsten.png differ diff --git a/rtdata/images/Dark/actions/wb-water.png b/rtdata/images/Dark/actions/wb-water.png new file mode 100644 index 000000000..196869abf Binary files /dev/null and b/rtdata/images/Dark/actions/wb-water.png differ diff --git a/rtdata/images/Dark/actions/zoom-100-identifier.png b/rtdata/images/Dark/actions/zoom-100-identifier.png new file mode 100644 index 000000000..45d8f2bef Binary files /dev/null and b/rtdata/images/Dark/actions/zoom-100-identifier.png differ diff --git a/rtdata/images/Dark/devices/computer.png b/rtdata/images/Dark/devices/computer.png new file mode 100644 index 000000000..4bd0885b7 Binary files /dev/null and b/rtdata/images/Dark/devices/computer.png differ diff --git a/rtdata/images/Dark/devices/drive-harddisk.png b/rtdata/images/Dark/devices/drive-harddisk.png new file mode 100644 index 000000000..4bd0885b7 Binary files /dev/null and b/rtdata/images/Dark/devices/drive-harddisk.png differ diff --git a/rtdata/images/Dark/devices/drive-optical.png b/rtdata/images/Dark/devices/drive-optical.png new file mode 100644 index 000000000..b4d20cc2e Binary files /dev/null and b/rtdata/images/Dark/devices/drive-optical.png differ diff --git a/rtdata/images/Dark/devices/drive-removable-media.png b/rtdata/images/Dark/devices/drive-removable-media.png new file mode 100644 index 000000000..ee41f6a5c Binary files /dev/null and b/rtdata/images/Dark/devices/drive-removable-media.png differ diff --git a/rtdata/images/Dark/devices/gtk-cdrom.png b/rtdata/images/Dark/devices/gtk-cdrom.png new file mode 100644 index 000000000..b4d20cc2e Binary files /dev/null and b/rtdata/images/Dark/devices/gtk-cdrom.png differ diff --git a/rtdata/images/Dark/devices/media-flash.png b/rtdata/images/Dark/devices/media-flash.png new file mode 100644 index 000000000..4bd0885b7 Binary files /dev/null and b/rtdata/images/Dark/devices/media-flash.png differ diff --git a/rtdata/images/Dark/devices/media-floppy.png b/rtdata/images/Dark/devices/media-floppy.png new file mode 100644 index 000000000..ee41f6a5c Binary files /dev/null and b/rtdata/images/Dark/devices/media-floppy.png differ diff --git a/rtdata/images/Dark/devices/media-optical-bd.png b/rtdata/images/Dark/devices/media-optical-bd.png new file mode 100644 index 000000000..b4d20cc2e Binary files /dev/null and b/rtdata/images/Dark/devices/media-optical-bd.png differ diff --git a/rtdata/images/Dark/devices/media-optical-dvd.png b/rtdata/images/Dark/devices/media-optical-dvd.png new file mode 100644 index 000000000..b4d20cc2e Binary files /dev/null and b/rtdata/images/Dark/devices/media-optical-dvd.png differ diff --git a/rtdata/images/Dark/devices/media-optical.png b/rtdata/images/Dark/devices/media-optical.png new file mode 100644 index 000000000..b4d20cc2e Binary files /dev/null and b/rtdata/images/Dark/devices/media-optical.png differ diff --git a/rtdata/images/Dark/devices/media-tape.png b/rtdata/images/Dark/devices/media-tape.png new file mode 100644 index 000000000..4bd0885b7 Binary files /dev/null and b/rtdata/images/Dark/devices/media-tape.png differ diff --git a/rtdata/images/Dark/index.theme b/rtdata/images/Dark/index.theme new file mode 100644 index 000000000..8912f3f5d --- /dev/null +++ b/rtdata/images/Dark/index.theme @@ -0,0 +1,42 @@ +[Icon Theme] +Name=RawTherapee-Dark +Comment=Dark theme for RawTherapee +Inherits=hicolor +Example=folder + +Directories=actions,apps,categories,devices,emblems,places,status + +[actions] +Size=22 +Context=Actions +Type=Fixed + +[apps] +Size=22 +Context=Applications +Type=Fixed + +[categories] +Size=22 +Context=Categories +Type=Fixed + +[devices] +Size=22 +Context=Devices +Type=Fixed + +[emblems] +Size=22 +Context=Emblems +Type=Fixed + +[places] +Size=22 +Context=Places +Type=Fixed + +[status] +Size=22 +Context=Status +Type=Fixed diff --git a/rtdata/images/Dark/places/folder.png b/rtdata/images/Dark/places/folder.png new file mode 100644 index 000000000..cc268ed89 Binary files /dev/null and b/rtdata/images/Dark/places/folder.png differ diff --git a/rtdata/images/Dark/places/gtk-directory.png b/rtdata/images/Dark/places/gtk-directory.png new file mode 100644 index 000000000..cc268ed89 Binary files /dev/null and b/rtdata/images/Dark/places/gtk-directory.png differ diff --git a/rtdata/images/Dark/places/user-desktop.png b/rtdata/images/Dark/places/user-desktop.png new file mode 100644 index 000000000..e973ac169 Binary files /dev/null and b/rtdata/images/Dark/places/user-desktop.png differ diff --git a/rtdata/images/Dark/places/user-home.png b/rtdata/images/Dark/places/user-home.png new file mode 100644 index 000000000..93d09835d Binary files /dev/null and b/rtdata/images/Dark/places/user-home.png differ diff --git a/rtdata/images/Light/actions/Chanmixer-Bgamma.png b/rtdata/images/Light/actions/Chanmixer-Bgamma.png new file mode 100644 index 000000000..95503a367 Binary files /dev/null and b/rtdata/images/Light/actions/Chanmixer-Bgamma.png differ diff --git a/rtdata/images/Light/actions/Chanmixer-Ggamma.png b/rtdata/images/Light/actions/Chanmixer-Ggamma.png new file mode 100644 index 000000000..13f937ae0 Binary files /dev/null and b/rtdata/images/Light/actions/Chanmixer-Ggamma.png differ diff --git a/rtdata/images/Light/actions/Chanmixer-Rgamma.png b/rtdata/images/Light/actions/Chanmixer-Rgamma.png new file mode 100644 index 000000000..5e423fe18 Binary files /dev/null and b/rtdata/images/Light/actions/Chanmixer-Rgamma.png differ diff --git a/rtdata/images/Light/actions/PanelEnding.png b/rtdata/images/Light/actions/PanelEnding.png new file mode 100644 index 000000000..d7c3cc37d Binary files /dev/null and b/rtdata/images/Light/actions/PanelEnding.png differ diff --git a/rtdata/images/Light/actions/ajd-ca-blue1.png b/rtdata/images/Light/actions/ajd-ca-blue1.png new file mode 100644 index 000000000..7a47267df Binary files /dev/null and b/rtdata/images/Light/actions/ajd-ca-blue1.png differ diff --git a/rtdata/images/Light/actions/ajd-ca-blue2.png b/rtdata/images/Light/actions/ajd-ca-blue2.png new file mode 100644 index 000000000..dfb458300 Binary files /dev/null and b/rtdata/images/Light/actions/ajd-ca-blue2.png differ diff --git a/rtdata/images/Light/actions/ajd-ca-red1.png b/rtdata/images/Light/actions/ajd-ca-red1.png new file mode 100644 index 000000000..1e45c5035 Binary files /dev/null and b/rtdata/images/Light/actions/ajd-ca-red1.png differ diff --git a/rtdata/images/Light/actions/ajd-ca-red2.png b/rtdata/images/Light/actions/ajd-ca-red2.png new file mode 100644 index 000000000..e5da9e005 Binary files /dev/null and b/rtdata/images/Light/actions/ajd-ca-red2.png differ diff --git a/rtdata/images/Light/actions/ajd-wb-bluered1.png b/rtdata/images/Light/actions/ajd-wb-bluered1.png new file mode 100644 index 000000000..3c8473451 Binary files /dev/null and b/rtdata/images/Light/actions/ajd-wb-bluered1.png differ diff --git a/rtdata/images/Light/actions/ajd-wb-bluered2.png b/rtdata/images/Light/actions/ajd-wb-bluered2.png new file mode 100644 index 000000000..0f06a770e Binary files /dev/null and b/rtdata/images/Light/actions/ajd-wb-bluered2.png differ diff --git a/rtdata/images/Light/actions/ajd-wb-green1.png b/rtdata/images/Light/actions/ajd-wb-green1.png new file mode 100644 index 000000000..4f33551d6 Binary files /dev/null and b/rtdata/images/Light/actions/ajd-wb-green1.png differ diff --git a/rtdata/images/Light/actions/ajd-wb-green2.png b/rtdata/images/Light/actions/ajd-wb-green2.png new file mode 100644 index 000000000..a9a7e8553 Binary files /dev/null and b/rtdata/images/Light/actions/ajd-wb-green2.png differ diff --git a/rtdata/images/Light/actions/ajd-wb-temp1.png b/rtdata/images/Light/actions/ajd-wb-temp1.png new file mode 100644 index 000000000..3c8473451 Binary files /dev/null and b/rtdata/images/Light/actions/ajd-wb-temp1.png differ diff --git a/rtdata/images/Light/actions/ajd-wb-temp2.png b/rtdata/images/Light/actions/ajd-wb-temp2.png new file mode 100644 index 000000000..2b0c7c0ef Binary files /dev/null and b/rtdata/images/Light/actions/ajd-wb-temp2.png differ diff --git a/rtdata/images/Light/actions/beforeafter.png b/rtdata/images/Light/actions/beforeafter.png new file mode 100644 index 000000000..cdbc49dc4 Binary files /dev/null and b/rtdata/images/Light/actions/beforeafter.png differ diff --git a/rtdata/images/Light/actions/cglabel0.png b/rtdata/images/Light/actions/cglabel0.png new file mode 100644 index 000000000..72cb8f15b Binary files /dev/null and b/rtdata/images/Light/actions/cglabel0.png differ diff --git a/rtdata/images/Light/actions/cglabel1.png b/rtdata/images/Light/actions/cglabel1.png new file mode 100644 index 000000000..6337a6476 Binary files /dev/null and b/rtdata/images/Light/actions/cglabel1.png differ diff --git a/rtdata/images/Light/actions/cglabel2.png b/rtdata/images/Light/actions/cglabel2.png new file mode 100644 index 000000000..a5b843c0c Binary files /dev/null and b/rtdata/images/Light/actions/cglabel2.png differ diff --git a/rtdata/images/Light/actions/cglabel3.png b/rtdata/images/Light/actions/cglabel3.png new file mode 100644 index 000000000..a3f3da7a9 Binary files /dev/null and b/rtdata/images/Light/actions/cglabel3.png differ diff --git a/rtdata/images/Light/actions/cglabel4.png b/rtdata/images/Light/actions/cglabel4.png new file mode 100644 index 000000000..3e048f36c Binary files /dev/null and b/rtdata/images/Light/actions/cglabel4.png differ diff --git a/rtdata/images/Light/actions/cglabel5.png b/rtdata/images/Light/actions/cglabel5.png new file mode 100644 index 000000000..323be0cb9 Binary files /dev/null and b/rtdata/images/Light/actions/cglabel5.png differ diff --git a/rtdata/images/Light/actions/clabel0.png b/rtdata/images/Light/actions/clabel0.png new file mode 100644 index 000000000..64de8ead0 Binary files /dev/null and b/rtdata/images/Light/actions/clabel0.png differ diff --git a/rtdata/images/Light/actions/clabel1.png b/rtdata/images/Light/actions/clabel1.png new file mode 100644 index 000000000..73e267c2a Binary files /dev/null and b/rtdata/images/Light/actions/clabel1.png differ diff --git a/rtdata/images/Light/actions/clabel2.png b/rtdata/images/Light/actions/clabel2.png new file mode 100644 index 000000000..3e6eca725 Binary files /dev/null and b/rtdata/images/Light/actions/clabel2.png differ diff --git a/rtdata/images/Light/actions/clabel3.png b/rtdata/images/Light/actions/clabel3.png new file mode 100644 index 000000000..e291a0df6 Binary files /dev/null and b/rtdata/images/Light/actions/clabel3.png differ diff --git a/rtdata/images/Light/actions/clabel4.png b/rtdata/images/Light/actions/clabel4.png new file mode 100644 index 000000000..89066bc43 Binary files /dev/null and b/rtdata/images/Light/actions/clabel4.png differ diff --git a/rtdata/images/Light/actions/clabel5.png b/rtdata/images/Light/actions/clabel5.png new file mode 100644 index 000000000..9944eaf69 Binary files /dev/null and b/rtdata/images/Light/actions/clabel5.png differ diff --git a/rtdata/images/Light/actions/closedhand.png b/rtdata/images/Light/actions/closedhand.png new file mode 100644 index 000000000..a1aea95f2 Binary files /dev/null and b/rtdata/images/Light/actions/closedhand.png differ diff --git a/rtdata/images/Light/actions/colour.png b/rtdata/images/Light/actions/colour.png new file mode 100644 index 000000000..d473e8a0b Binary files /dev/null and b/rtdata/images/Light/actions/colour.png differ diff --git a/rtdata/images/Light/actions/crop-auto.png b/rtdata/images/Light/actions/crop-auto.png new file mode 100644 index 000000000..a4c6c897e Binary files /dev/null and b/rtdata/images/Light/actions/crop-auto.png differ diff --git a/rtdata/images/Light/actions/crop.png b/rtdata/images/Light/actions/crop.png new file mode 100644 index 000000000..16ca56996 Binary files /dev/null and b/rtdata/images/Light/actions/crop.png differ diff --git a/rtdata/images/Light/actions/crossed-arrows-in.png b/rtdata/images/Light/actions/crossed-arrows-in.png new file mode 100644 index 000000000..da0e44b8b Binary files /dev/null and b/rtdata/images/Light/actions/crossed-arrows-in.png differ diff --git a/rtdata/images/Light/actions/crossed-arrows-out.png b/rtdata/images/Light/actions/crossed-arrows-out.png new file mode 100644 index 000000000..8bc1a8819 Binary files /dev/null and b/rtdata/images/Light/actions/crossed-arrows-out.png differ diff --git a/rtdata/images/Light/actions/curveType-NURBS.png b/rtdata/images/Light/actions/curveType-NURBS.png new file mode 100644 index 000000000..2a025b1ba Binary files /dev/null and b/rtdata/images/Light/actions/curveType-NURBS.png differ diff --git a/rtdata/images/Light/actions/curveType-controlPoints.png b/rtdata/images/Light/actions/curveType-controlPoints.png new file mode 100644 index 000000000..eae5a3875 Binary files /dev/null and b/rtdata/images/Light/actions/curveType-controlPoints.png differ diff --git a/rtdata/images/Light/actions/curveType-flatLinear.png b/rtdata/images/Light/actions/curveType-flatLinear.png new file mode 100644 index 000000000..6fb01eba8 Binary files /dev/null and b/rtdata/images/Light/actions/curveType-flatLinear.png differ diff --git a/rtdata/images/Light/actions/curveType-linear.png b/rtdata/images/Light/actions/curveType-linear.png new file mode 100644 index 000000000..f58b3ab51 Binary files /dev/null and b/rtdata/images/Light/actions/curveType-linear.png differ diff --git a/rtdata/images/Light/actions/curveType-parametric.png b/rtdata/images/Light/actions/curveType-parametric.png new file mode 100644 index 000000000..287a37ab0 Binary files /dev/null and b/rtdata/images/Light/actions/curveType-parametric.png differ diff --git a/rtdata/images/Light/actions/curveType-spline.png b/rtdata/images/Light/actions/curveType-spline.png new file mode 100644 index 000000000..e3e5e08d9 Binary files /dev/null and b/rtdata/images/Light/actions/curveType-spline.png differ diff --git a/rtdata/images/Light/actions/detail.png b/rtdata/images/Light/actions/detail.png new file mode 100644 index 000000000..1fc314fd3 Binary files /dev/null and b/rtdata/images/Light/actions/detail.png differ diff --git a/rtdata/images/Light/actions/distorsion.png b/rtdata/images/Light/actions/distorsion.png new file mode 100644 index 000000000..18b4a01df Binary files /dev/null and b/rtdata/images/Light/actions/distorsion.png differ diff --git a/rtdata/images/Light/actions/distortion-auto.png b/rtdata/images/Light/actions/distortion-auto.png new file mode 100644 index 000000000..759c8e463 Binary files /dev/null and b/rtdata/images/Light/actions/distortion-auto.png differ diff --git a/rtdata/images/Light/actions/distortion-barrel.png b/rtdata/images/Light/actions/distortion-barrel.png new file mode 100644 index 000000000..836be0ac2 Binary files /dev/null and b/rtdata/images/Light/actions/distortion-barrel.png differ diff --git a/rtdata/images/Light/actions/distortion-pincushion.png b/rtdata/images/Light/actions/distortion-pincushion.png new file mode 100644 index 000000000..f64574151 Binary files /dev/null and b/rtdata/images/Light/actions/distortion-pincushion.png differ diff --git a/rtdata/images/Light/actions/document-open-recent.png b/rtdata/images/Light/actions/document-open-recent.png new file mode 100644 index 000000000..5ef8724f2 Binary files /dev/null and b/rtdata/images/Light/actions/document-open-recent.png differ diff --git a/rtdata/images/Light/actions/document-open.png b/rtdata/images/Light/actions/document-open.png new file mode 100644 index 000000000..f7b57849a Binary files /dev/null and b/rtdata/images/Light/actions/document-open.png differ diff --git a/rtdata/images/Light/actions/edit-copy.png b/rtdata/images/Light/actions/edit-copy.png new file mode 100644 index 000000000..12e49387f Binary files /dev/null and b/rtdata/images/Light/actions/edit-copy.png differ diff --git a/rtdata/images/Light/actions/edit-find.png b/rtdata/images/Light/actions/edit-find.png new file mode 100644 index 000000000..d15687e7d Binary files /dev/null and b/rtdata/images/Light/actions/edit-find.png differ diff --git a/rtdata/images/Light/actions/edit-paste.png b/rtdata/images/Light/actions/edit-paste.png new file mode 100644 index 000000000..d7e924562 Binary files /dev/null and b/rtdata/images/Light/actions/edit-paste.png differ diff --git a/rtdata/images/Light/actions/edited-small.png b/rtdata/images/Light/actions/edited-small.png new file mode 100644 index 000000000..f25997a59 Binary files /dev/null and b/rtdata/images/Light/actions/edited-small.png differ diff --git a/rtdata/images/Light/actions/edited.png b/rtdata/images/Light/actions/edited.png new file mode 100644 index 000000000..95d058454 Binary files /dev/null and b/rtdata/images/Light/actions/edited.png differ diff --git a/rtdata/images/Light/actions/editedg-small.png b/rtdata/images/Light/actions/editedg-small.png new file mode 100644 index 000000000..9eb229e75 Binary files /dev/null and b/rtdata/images/Light/actions/editedg-small.png differ diff --git a/rtdata/images/Light/actions/editednot-small.png b/rtdata/images/Light/actions/editednot-small.png new file mode 100644 index 000000000..410bff81b Binary files /dev/null and b/rtdata/images/Light/actions/editednot-small.png differ diff --git a/rtdata/images/Light/actions/editednotg-small.png b/rtdata/images/Light/actions/editednotg-small.png new file mode 100644 index 000000000..55bc28f2b Binary files /dev/null and b/rtdata/images/Light/actions/editednotg-small.png differ diff --git a/rtdata/images/Light/actions/editmodehand.png b/rtdata/images/Light/actions/editmodehand.png new file mode 100644 index 000000000..a3ec816bb Binary files /dev/null and b/rtdata/images/Light/actions/editmodehand.png differ diff --git a/rtdata/images/Light/actions/expanderClosed.png b/rtdata/images/Light/actions/expanderClosed.png new file mode 100644 index 000000000..90d1269aa Binary files /dev/null and b/rtdata/images/Light/actions/expanderClosed.png differ diff --git a/rtdata/images/Light/actions/expanderDisabled.png b/rtdata/images/Light/actions/expanderDisabled.png new file mode 100644 index 000000000..27b1ed1d7 Binary files /dev/null and b/rtdata/images/Light/actions/expanderDisabled.png differ diff --git a/rtdata/images/Light/actions/expanderEnabled.png b/rtdata/images/Light/actions/expanderEnabled.png new file mode 100644 index 000000000..402d4aae2 Binary files /dev/null and b/rtdata/images/Light/actions/expanderEnabled.png differ diff --git a/rtdata/images/Light/actions/expanderInconsistent.png b/rtdata/images/Light/actions/expanderInconsistent.png new file mode 100644 index 000000000..9f87059dc Binary files /dev/null and b/rtdata/images/Light/actions/expanderInconsistent.png differ diff --git a/rtdata/images/Light/actions/expanderOpened.png b/rtdata/images/Light/actions/expanderOpened.png new file mode 100644 index 000000000..e53435263 Binary files /dev/null and b/rtdata/images/Light/actions/expanderOpened.png differ diff --git a/rtdata/images/Light/actions/exposure.png b/rtdata/images/Light/actions/exposure.png new file mode 100644 index 000000000..8675d8e15 Binary files /dev/null and b/rtdata/images/Light/actions/exposure.png differ diff --git a/rtdata/images/Light/actions/filter.png b/rtdata/images/Light/actions/filter.png new file mode 100644 index 000000000..7c69d18ee Binary files /dev/null and b/rtdata/images/Light/actions/filter.png differ diff --git a/rtdata/images/Light/actions/filterclear.png b/rtdata/images/Light/actions/filterclear.png new file mode 100644 index 000000000..bd4f651f8 Binary files /dev/null and b/rtdata/images/Light/actions/filterclear.png differ diff --git a/rtdata/images/Light/actions/fullscreen-exit.png b/rtdata/images/Light/actions/fullscreen-exit.png new file mode 100644 index 000000000..01df3044c Binary files /dev/null and b/rtdata/images/Light/actions/fullscreen-exit.png differ diff --git a/rtdata/images/Light/actions/fullscreen.png b/rtdata/images/Light/actions/fullscreen.png new file mode 100644 index 000000000..e08067584 Binary files /dev/null and b/rtdata/images/Light/actions/fullscreen.png differ diff --git a/rtdata/images/Light/actions/grayrated.png b/rtdata/images/Light/actions/grayrated.png new file mode 100644 index 000000000..813af1cee Binary files /dev/null and b/rtdata/images/Light/actions/grayrated.png differ diff --git a/rtdata/images/Light/actions/gtk-add.png b/rtdata/images/Light/actions/gtk-add.png new file mode 100644 index 000000000..9a982056c Binary files /dev/null and b/rtdata/images/Light/actions/gtk-add.png differ diff --git a/rtdata/images/Light/actions/gtk-apply.png b/rtdata/images/Light/actions/gtk-apply.png new file mode 100644 index 000000000..e1224bca3 Binary files /dev/null and b/rtdata/images/Light/actions/gtk-apply.png differ diff --git a/rtdata/images/Light/actions/gtk-cancel.png b/rtdata/images/Light/actions/gtk-cancel.png new file mode 100644 index 000000000..65740aaf1 Binary files /dev/null and b/rtdata/images/Light/actions/gtk-cancel.png differ diff --git a/rtdata/images/Light/actions/gtk-close-small.png b/rtdata/images/Light/actions/gtk-close-small.png new file mode 100644 index 000000000..ef2ac03d8 Binary files /dev/null and b/rtdata/images/Light/actions/gtk-close-small.png differ diff --git a/rtdata/images/Light/actions/gtk-close.png b/rtdata/images/Light/actions/gtk-close.png new file mode 100644 index 000000000..65740aaf1 Binary files /dev/null and b/rtdata/images/Light/actions/gtk-close.png differ diff --git a/rtdata/images/Light/actions/gtk-color-picker-small.png b/rtdata/images/Light/actions/gtk-color-picker-small.png new file mode 100644 index 000000000..834848607 Binary files /dev/null and b/rtdata/images/Light/actions/gtk-color-picker-small.png differ diff --git a/rtdata/images/Light/actions/gtk-color-picker.png b/rtdata/images/Light/actions/gtk-color-picker.png new file mode 100644 index 000000000..f2fbc5cf9 Binary files /dev/null and b/rtdata/images/Light/actions/gtk-color-picker.png differ diff --git a/rtdata/images/Light/actions/gtk-copy.png b/rtdata/images/Light/actions/gtk-copy.png new file mode 100644 index 000000000..12e49387f Binary files /dev/null and b/rtdata/images/Light/actions/gtk-copy.png differ diff --git a/rtdata/images/Light/actions/gtk-edit.png b/rtdata/images/Light/actions/gtk-edit.png new file mode 100644 index 000000000..d76e57227 Binary files /dev/null and b/rtdata/images/Light/actions/gtk-edit.png differ diff --git a/rtdata/images/Light/actions/gtk-find.png b/rtdata/images/Light/actions/gtk-find.png new file mode 100644 index 000000000..d15687e7d Binary files /dev/null and b/rtdata/images/Light/actions/gtk-find.png differ diff --git a/rtdata/images/Light/actions/gtk-media-play.png b/rtdata/images/Light/actions/gtk-media-play.png new file mode 100644 index 000000000..2f97b3fec Binary files /dev/null and b/rtdata/images/Light/actions/gtk-media-play.png differ diff --git a/rtdata/images/Light/actions/gtk-media-stop.png b/rtdata/images/Light/actions/gtk-media-stop.png new file mode 100644 index 000000000..ea1b0e8a1 Binary files /dev/null and b/rtdata/images/Light/actions/gtk-media-stop.png differ diff --git a/rtdata/images/Light/actions/gtk-ok.png b/rtdata/images/Light/actions/gtk-ok.png new file mode 100644 index 000000000..e1224bca3 Binary files /dev/null and b/rtdata/images/Light/actions/gtk-ok.png differ diff --git a/rtdata/images/Light/actions/gtk-open.png b/rtdata/images/Light/actions/gtk-open.png new file mode 100644 index 000000000..f7b57849a Binary files /dev/null and b/rtdata/images/Light/actions/gtk-open.png differ diff --git a/rtdata/images/Light/actions/gtk-paste.png b/rtdata/images/Light/actions/gtk-paste.png new file mode 100644 index 000000000..d7e924562 Binary files /dev/null and b/rtdata/images/Light/actions/gtk-paste.png differ diff --git a/rtdata/images/Light/actions/gtk-preferences.png b/rtdata/images/Light/actions/gtk-preferences.png new file mode 100644 index 000000000..edb354e1a Binary files /dev/null and b/rtdata/images/Light/actions/gtk-preferences.png differ diff --git a/rtdata/images/Light/actions/gtk-remove.png b/rtdata/images/Light/actions/gtk-remove.png new file mode 100644 index 000000000..f198bce68 Binary files /dev/null and b/rtdata/images/Light/actions/gtk-remove.png differ diff --git a/rtdata/images/Light/actions/gtk-save-large.png b/rtdata/images/Light/actions/gtk-save-large.png new file mode 100644 index 000000000..a55dfe04c Binary files /dev/null and b/rtdata/images/Light/actions/gtk-save-large.png differ diff --git a/rtdata/images/Light/actions/gtk-save.png b/rtdata/images/Light/actions/gtk-save.png new file mode 100644 index 000000000..64f9e44a2 Binary files /dev/null and b/rtdata/images/Light/actions/gtk-save.png differ diff --git a/rtdata/images/Light/actions/gtk-undo-ltr-small.png b/rtdata/images/Light/actions/gtk-undo-ltr-small.png new file mode 100644 index 000000000..86d0fa28f Binary files /dev/null and b/rtdata/images/Light/actions/gtk-undo-ltr-small.png differ diff --git a/rtdata/images/Light/actions/gtk-undo-ltr.png b/rtdata/images/Light/actions/gtk-undo-ltr.png new file mode 100644 index 000000000..ee15060e9 Binary files /dev/null and b/rtdata/images/Light/actions/gtk-undo-ltr.png differ diff --git a/rtdata/images/Light/actions/gtk-undo-rtl-small.png b/rtdata/images/Light/actions/gtk-undo-rtl-small.png new file mode 100644 index 000000000..f8b4d4586 Binary files /dev/null and b/rtdata/images/Light/actions/gtk-undo-rtl-small.png differ diff --git a/rtdata/images/Light/actions/gtk-undo-rtl.png b/rtdata/images/Light/actions/gtk-undo-rtl.png new file mode 100644 index 000000000..22c6f2212 Binary files /dev/null and b/rtdata/images/Light/actions/gtk-undo-rtl.png differ diff --git a/rtdata/images/Light/actions/gtk-undoall-ltr.png b/rtdata/images/Light/actions/gtk-undoall-ltr.png new file mode 100644 index 000000000..dca3f3d01 Binary files /dev/null and b/rtdata/images/Light/actions/gtk-undoall-ltr.png differ diff --git a/rtdata/images/Light/actions/gtk-undoall-rtl.png b/rtdata/images/Light/actions/gtk-undoall-rtl.png new file mode 100644 index 000000000..ac051c8e6 Binary files /dev/null and b/rtdata/images/Light/actions/gtk-undoall-rtl.png differ diff --git a/rtdata/images/Light/actions/gtk-zoom-100-small.png b/rtdata/images/Light/actions/gtk-zoom-100-small.png new file mode 100644 index 000000000..23e694f6e Binary files /dev/null and b/rtdata/images/Light/actions/gtk-zoom-100-small.png differ diff --git a/rtdata/images/Light/actions/gtk-zoom-100.png b/rtdata/images/Light/actions/gtk-zoom-100.png new file mode 100644 index 000000000..656274a75 Binary files /dev/null and b/rtdata/images/Light/actions/gtk-zoom-100.png differ diff --git a/rtdata/images/Light/actions/gtk-zoom-crop.png b/rtdata/images/Light/actions/gtk-zoom-crop.png new file mode 100644 index 000000000..c83bac4fe Binary files /dev/null and b/rtdata/images/Light/actions/gtk-zoom-crop.png differ diff --git a/rtdata/images/Light/actions/gtk-zoom-fit.png b/rtdata/images/Light/actions/gtk-zoom-fit.png new file mode 100644 index 000000000..7f3452eed Binary files /dev/null and b/rtdata/images/Light/actions/gtk-zoom-fit.png differ diff --git a/rtdata/images/Light/actions/gtk-zoom-in-small.png b/rtdata/images/Light/actions/gtk-zoom-in-small.png new file mode 100644 index 000000000..f5e381ca8 Binary files /dev/null and b/rtdata/images/Light/actions/gtk-zoom-in-small.png differ diff --git a/rtdata/images/Light/actions/gtk-zoom-in.png b/rtdata/images/Light/actions/gtk-zoom-in.png new file mode 100644 index 000000000..0cafb1e36 Binary files /dev/null and b/rtdata/images/Light/actions/gtk-zoom-in.png differ diff --git a/rtdata/images/Light/actions/gtk-zoom-out-small.png b/rtdata/images/Light/actions/gtk-zoom-out-small.png new file mode 100644 index 000000000..4605917bc Binary files /dev/null and b/rtdata/images/Light/actions/gtk-zoom-out-small.png differ diff --git a/rtdata/images/Light/actions/gtk-zoom-out.png b/rtdata/images/Light/actions/gtk-zoom-out.png new file mode 100644 index 000000000..f3d914d93 Binary files /dev/null and b/rtdata/images/Light/actions/gtk-zoom-out.png differ diff --git a/rtdata/images/Light/actions/histBar.png b/rtdata/images/Light/actions/histBar.png new file mode 100644 index 000000000..84bbecad8 Binary files /dev/null and b/rtdata/images/Light/actions/histBar.png differ diff --git a/rtdata/images/Light/actions/histBarg.png b/rtdata/images/Light/actions/histBarg.png new file mode 100644 index 000000000..789ee931c Binary files /dev/null and b/rtdata/images/Light/actions/histBarg.png differ diff --git a/rtdata/images/Light/actions/histBlue.png b/rtdata/images/Light/actions/histBlue.png new file mode 100644 index 000000000..53c447a1c Binary files /dev/null and b/rtdata/images/Light/actions/histBlue.png differ diff --git a/rtdata/images/Light/actions/histBlueg.png b/rtdata/images/Light/actions/histBlueg.png new file mode 100644 index 000000000..ac205219d Binary files /dev/null and b/rtdata/images/Light/actions/histBlueg.png differ diff --git a/rtdata/images/Light/actions/histChro.png b/rtdata/images/Light/actions/histChro.png new file mode 100644 index 000000000..efbf75aa5 Binary files /dev/null and b/rtdata/images/Light/actions/histChro.png differ diff --git a/rtdata/images/Light/actions/histChrog.png b/rtdata/images/Light/actions/histChrog.png new file mode 100644 index 000000000..8349d5089 Binary files /dev/null and b/rtdata/images/Light/actions/histChrog.png differ diff --git a/rtdata/images/Light/actions/histFull.png b/rtdata/images/Light/actions/histFull.png new file mode 100644 index 000000000..edabaa2bd Binary files /dev/null and b/rtdata/images/Light/actions/histFull.png differ diff --git a/rtdata/images/Light/actions/histFullg.png b/rtdata/images/Light/actions/histFullg.png new file mode 100644 index 000000000..ce3cf8ddc Binary files /dev/null and b/rtdata/images/Light/actions/histFullg.png differ diff --git a/rtdata/images/Light/actions/histGreen.png b/rtdata/images/Light/actions/histGreen.png new file mode 100644 index 000000000..54eebe37e Binary files /dev/null and b/rtdata/images/Light/actions/histGreen.png differ diff --git a/rtdata/images/Light/actions/histGreeng.png b/rtdata/images/Light/actions/histGreeng.png new file mode 100644 index 000000000..33c138cae Binary files /dev/null and b/rtdata/images/Light/actions/histGreeng.png differ diff --git a/rtdata/images/Light/actions/histRaw.png b/rtdata/images/Light/actions/histRaw.png new file mode 100644 index 000000000..36e1a5a31 Binary files /dev/null and b/rtdata/images/Light/actions/histRaw.png differ diff --git a/rtdata/images/Light/actions/histRawg.png b/rtdata/images/Light/actions/histRawg.png new file mode 100644 index 000000000..1b9d286b3 Binary files /dev/null and b/rtdata/images/Light/actions/histRawg.png differ diff --git a/rtdata/images/Light/actions/histRed.png b/rtdata/images/Light/actions/histRed.png new file mode 100644 index 000000000..ce7fddcd3 Binary files /dev/null and b/rtdata/images/Light/actions/histRed.png differ diff --git a/rtdata/images/Light/actions/histRedg.png b/rtdata/images/Light/actions/histRedg.png new file mode 100644 index 000000000..b75a66995 Binary files /dev/null and b/rtdata/images/Light/actions/histRedg.png differ diff --git a/rtdata/images/Light/actions/histValue.png b/rtdata/images/Light/actions/histValue.png new file mode 100644 index 000000000..7f807ec9b Binary files /dev/null and b/rtdata/images/Light/actions/histValue.png differ diff --git a/rtdata/images/Light/actions/histValueg.png b/rtdata/images/Light/actions/histValueg.png new file mode 100644 index 000000000..28f5dbe18 Binary files /dev/null and b/rtdata/images/Light/actions/histValueg.png differ diff --git a/rtdata/images/Light/actions/image-editor.png b/rtdata/images/Light/actions/image-editor.png new file mode 100644 index 000000000..3061ad89e Binary files /dev/null and b/rtdata/images/Light/actions/image-editor.png differ diff --git a/rtdata/images/Light/actions/info.png b/rtdata/images/Light/actions/info.png new file mode 100644 index 000000000..db3f654de Binary files /dev/null and b/rtdata/images/Light/actions/info.png differ diff --git a/rtdata/images/Light/actions/list-add-small.png b/rtdata/images/Light/actions/list-add-small.png new file mode 100644 index 000000000..9d06f0303 Binary files /dev/null and b/rtdata/images/Light/actions/list-add-small.png differ diff --git a/rtdata/images/Light/actions/list-add.png b/rtdata/images/Light/actions/list-add.png new file mode 100644 index 000000000..9a982056c Binary files /dev/null and b/rtdata/images/Light/actions/list-add.png differ diff --git a/rtdata/images/Light/actions/list-remove-red-small.png b/rtdata/images/Light/actions/list-remove-red-small.png new file mode 100644 index 000000000..866a2b2d2 Binary files /dev/null and b/rtdata/images/Light/actions/list-remove-red-small.png differ diff --git a/rtdata/images/Light/actions/list-remove.png b/rtdata/images/Light/actions/list-remove.png new file mode 100644 index 000000000..f198bce68 Binary files /dev/null and b/rtdata/images/Light/actions/list-remove.png differ diff --git a/rtdata/images/Light/actions/lock-off.png b/rtdata/images/Light/actions/lock-off.png new file mode 100644 index 000000000..af4489e34 Binary files /dev/null and b/rtdata/images/Light/actions/lock-off.png differ diff --git a/rtdata/images/Light/actions/lock-on.png b/rtdata/images/Light/actions/lock-on.png new file mode 100644 index 000000000..3c664e73e Binary files /dev/null and b/rtdata/images/Light/actions/lock-on.png differ diff --git a/rtdata/images/Light/actions/media-usb.png b/rtdata/images/Light/actions/media-usb.png new file mode 100644 index 000000000..e8b990a03 Binary files /dev/null and b/rtdata/images/Light/actions/media-usb.png differ diff --git a/rtdata/images/Light/actions/meta.png b/rtdata/images/Light/actions/meta.png new file mode 100644 index 000000000..a2f61665a Binary files /dev/null and b/rtdata/images/Light/actions/meta.png differ diff --git a/rtdata/images/Light/actions/nav-next.png b/rtdata/images/Light/actions/nav-next.png new file mode 100644 index 000000000..d68e1df60 Binary files /dev/null and b/rtdata/images/Light/actions/nav-next.png differ diff --git a/rtdata/images/Light/actions/nav-prev.png b/rtdata/images/Light/actions/nav-prev.png new file mode 100644 index 000000000..ad37367ba Binary files /dev/null and b/rtdata/images/Light/actions/nav-prev.png differ diff --git a/rtdata/images/Light/actions/nav-sync.png b/rtdata/images/Light/actions/nav-sync.png new file mode 100644 index 000000000..eb8445a40 Binary files /dev/null and b/rtdata/images/Light/actions/nav-sync.png differ diff --git a/rtdata/images/Light/actions/new-detail-window.png b/rtdata/images/Light/actions/new-detail-window.png new file mode 100644 index 000000000..23ae12faf Binary files /dev/null and b/rtdata/images/Light/actions/new-detail-window.png differ diff --git a/rtdata/images/Light/actions/openhand.png b/rtdata/images/Light/actions/openhand.png new file mode 100644 index 000000000..28da9e5e6 Binary files /dev/null and b/rtdata/images/Light/actions/openhand.png differ diff --git a/rtdata/images/Light/actions/panel-to-bottom.png b/rtdata/images/Light/actions/panel-to-bottom.png new file mode 100644 index 000000000..cc3b45b64 Binary files /dev/null and b/rtdata/images/Light/actions/panel-to-bottom.png differ diff --git a/rtdata/images/Light/actions/panel-to-left.png b/rtdata/images/Light/actions/panel-to-left.png new file mode 100644 index 000000000..2562b8f00 Binary files /dev/null and b/rtdata/images/Light/actions/panel-to-left.png differ diff --git a/rtdata/images/Light/actions/panel-to-right.png b/rtdata/images/Light/actions/panel-to-right.png new file mode 100644 index 000000000..3e05a3813 Binary files /dev/null and b/rtdata/images/Light/actions/panel-to-right.png differ diff --git a/rtdata/images/Light/actions/panel-to-top.png b/rtdata/images/Light/actions/panel-to-top.png new file mode 100644 index 000000000..ff453efac Binary files /dev/null and b/rtdata/images/Light/actions/panel-to-top.png differ diff --git a/rtdata/images/Light/actions/perspective-h1.png b/rtdata/images/Light/actions/perspective-h1.png new file mode 100644 index 000000000..c857a1df5 Binary files /dev/null and b/rtdata/images/Light/actions/perspective-h1.png differ diff --git a/rtdata/images/Light/actions/perspective-h2.png b/rtdata/images/Light/actions/perspective-h2.png new file mode 100644 index 000000000..0fb23ea9c Binary files /dev/null and b/rtdata/images/Light/actions/perspective-h2.png differ diff --git a/rtdata/images/Light/actions/perspective-v1.png b/rtdata/images/Light/actions/perspective-v1.png new file mode 100644 index 000000000..eb94f4b9b Binary files /dev/null and b/rtdata/images/Light/actions/perspective-v1.png differ diff --git a/rtdata/images/Light/actions/perspective-v2.png b/rtdata/images/Light/actions/perspective-v2.png new file mode 100644 index 000000000..1b983a78d Binary files /dev/null and b/rtdata/images/Light/actions/perspective-v2.png differ diff --git a/rtdata/images/Light/actions/popuparrow.png b/rtdata/images/Light/actions/popuparrow.png new file mode 100644 index 000000000..ba3956421 Binary files /dev/null and b/rtdata/images/Light/actions/popuparrow.png differ diff --git a/rtdata/images/Light/actions/previewmodeB-off.png b/rtdata/images/Light/actions/previewmodeB-off.png new file mode 100644 index 000000000..1ff087b4d Binary files /dev/null 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 new file mode 100644 index 000000000..6403fc722 Binary files /dev/null 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 new file mode 100644 index 000000000..05a75ee25 Binary files /dev/null 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 new file mode 100644 index 000000000..a1f462cb2 Binary files /dev/null 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 new file mode 100644 index 000000000..d5071108a Binary files /dev/null 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 new file mode 100644 index 000000000..f71b27965 Binary files /dev/null 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 new file mode 100644 index 000000000..5c9b2d0e8 Binary files /dev/null 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 new file mode 100644 index 000000000..8f5b9207e Binary files /dev/null and b/rtdata/images/Light/actions/previewmodeBC2-on.png differ diff --git a/rtdata/images/Light/actions/previewmodeF-off.png b/rtdata/images/Light/actions/previewmodeF-off.png new file mode 100644 index 000000000..519de02bc Binary files /dev/null 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 new file mode 100644 index 000000000..3910e6a20 Binary files /dev/null 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 new file mode 100644 index 000000000..e25911324 Binary files /dev/null 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 new file mode 100644 index 000000000..db31667ed Binary files /dev/null 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 new file mode 100644 index 000000000..d24dea76f Binary files /dev/null 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 new file mode 100644 index 000000000..11b745e09 Binary files /dev/null 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 new file mode 100644 index 000000000..9aef77301 Binary files /dev/null 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 new file mode 100644 index 000000000..5fb0f996e Binary files /dev/null and b/rtdata/images/Light/actions/previewmodeR-on.png differ diff --git a/rtdata/images/Light/actions/processing-pause.png b/rtdata/images/Light/actions/processing-pause.png new file mode 100644 index 000000000..36660d7e6 Binary files /dev/null and b/rtdata/images/Light/actions/processing-pause.png differ diff --git a/rtdata/images/Light/actions/processing-play.png b/rtdata/images/Light/actions/processing-play.png new file mode 100644 index 000000000..5e1acbac7 Binary files /dev/null and b/rtdata/images/Light/actions/processing-play.png differ diff --git a/rtdata/images/Light/actions/processing-thumbnail.png b/rtdata/images/Light/actions/processing-thumbnail.png new file mode 100644 index 000000000..c95ce2ffa Binary files /dev/null and b/rtdata/images/Light/actions/processing-thumbnail.png differ diff --git a/rtdata/images/Light/actions/processing.png b/rtdata/images/Light/actions/processing.png new file mode 100644 index 000000000..28a598856 Binary files /dev/null and b/rtdata/images/Light/actions/processing.png differ diff --git a/rtdata/images/Light/actions/profile-filled.png b/rtdata/images/Light/actions/profile-filled.png new file mode 100644 index 000000000..7e5ae44bf Binary files /dev/null and b/rtdata/images/Light/actions/profile-filled.png differ diff --git a/rtdata/images/Light/actions/profile-partial.png b/rtdata/images/Light/actions/profile-partial.png new file mode 100644 index 000000000..9bb666ae3 Binary files /dev/null and b/rtdata/images/Light/actions/profile-partial.png differ diff --git a/rtdata/images/Light/actions/rated.png b/rtdata/images/Light/actions/rated.png new file mode 100644 index 000000000..6b238da70 Binary files /dev/null and b/rtdata/images/Light/actions/rated.png differ diff --git a/rtdata/images/Light/actions/ratednot.png b/rtdata/images/Light/actions/ratednot.png new file mode 100644 index 000000000..33bc1935f Binary files /dev/null and b/rtdata/images/Light/actions/ratednot.png differ diff --git a/rtdata/images/Light/actions/ratednotg.png b/rtdata/images/Light/actions/ratednotg.png new file mode 100644 index 000000000..ff55f1646 Binary files /dev/null and b/rtdata/images/Light/actions/ratednotg.png differ diff --git a/rtdata/images/Light/actions/raw.png b/rtdata/images/Light/actions/raw.png new file mode 100644 index 000000000..bf3e8f631 Binary files /dev/null and b/rtdata/images/Light/actions/raw.png differ diff --git a/rtdata/images/Light/actions/refresh-red.png b/rtdata/images/Light/actions/refresh-red.png new file mode 100644 index 000000000..157c4bd70 Binary files /dev/null and b/rtdata/images/Light/actions/refresh-red.png differ diff --git a/rtdata/images/Light/actions/refresh-white.png b/rtdata/images/Light/actions/refresh-white.png new file mode 100644 index 000000000..4536ce00d Binary files /dev/null and b/rtdata/images/Light/actions/refresh-white.png differ diff --git a/rtdata/images/Light/actions/rotate-left-1.png b/rtdata/images/Light/actions/rotate-left-1.png new file mode 100644 index 000000000..869c9ed4a Binary files /dev/null and b/rtdata/images/Light/actions/rotate-left-1.png differ diff --git a/rtdata/images/Light/actions/rotate-left-2.png b/rtdata/images/Light/actions/rotate-left-2.png new file mode 100644 index 000000000..7aa5bd1ba Binary files /dev/null and b/rtdata/images/Light/actions/rotate-left-2.png differ diff --git a/rtdata/images/Light/actions/rotate-left-3.png b/rtdata/images/Light/actions/rotate-left-3.png new file mode 100644 index 000000000..5bf87bb2b Binary files /dev/null and b/rtdata/images/Light/actions/rotate-left-3.png differ diff --git a/rtdata/images/Light/actions/rotate-left.png b/rtdata/images/Light/actions/rotate-left.png new file mode 100644 index 000000000..f3851ba12 Binary files /dev/null and b/rtdata/images/Light/actions/rotate-left.png differ diff --git a/rtdata/images/Light/actions/rotate-right-1.png b/rtdata/images/Light/actions/rotate-right-1.png new file mode 100644 index 000000000..9d4d477cb Binary files /dev/null and b/rtdata/images/Light/actions/rotate-right-1.png differ diff --git a/rtdata/images/Light/actions/rotate-right-2.png b/rtdata/images/Light/actions/rotate-right-2.png new file mode 100644 index 000000000..bb4d98c66 Binary files /dev/null and b/rtdata/images/Light/actions/rotate-right-2.png differ diff --git a/rtdata/images/Light/actions/rotate-right-3.png b/rtdata/images/Light/actions/rotate-right-3.png new file mode 100644 index 000000000..4bf41091c Binary files /dev/null and b/rtdata/images/Light/actions/rotate-right-3.png differ diff --git a/rtdata/images/Light/actions/rotate-right.png b/rtdata/images/Light/actions/rotate-right.png new file mode 100644 index 000000000..f9a728b8a Binary files /dev/null and b/rtdata/images/Light/actions/rotate-right.png differ diff --git a/rtdata/images/Light/actions/rtwindow.png b/rtdata/images/Light/actions/rtwindow.png new file mode 100644 index 000000000..19dfa521a Binary files /dev/null and b/rtdata/images/Light/actions/rtwindow.png differ diff --git a/rtdata/images/Light/actions/stock-flip-horizontal.png b/rtdata/images/Light/actions/stock-flip-horizontal.png new file mode 100644 index 000000000..af8b4ac95 Binary files /dev/null and b/rtdata/images/Light/actions/stock-flip-horizontal.png differ diff --git a/rtdata/images/Light/actions/stock-flip-vertical.png b/rtdata/images/Light/actions/stock-flip-vertical.png new file mode 100644 index 000000000..baf393fed Binary files /dev/null and b/rtdata/images/Light/actions/stock-flip-vertical.png differ diff --git a/rtdata/images/Light/actions/stock-rotate-270.png b/rtdata/images/Light/actions/stock-rotate-270.png new file mode 100644 index 000000000..ae46db66d Binary files /dev/null and b/rtdata/images/Light/actions/stock-rotate-270.png differ diff --git a/rtdata/images/Light/actions/stock-rotate-90.png b/rtdata/images/Light/actions/stock-rotate-90.png new file mode 100644 index 000000000..a125fe413 Binary files /dev/null and b/rtdata/images/Light/actions/stock-rotate-90.png differ diff --git a/rtdata/images/Light/actions/straighten-small.png b/rtdata/images/Light/actions/straighten-small.png new file mode 100644 index 000000000..5090d70f9 Binary files /dev/null and b/rtdata/images/Light/actions/straighten-small.png differ diff --git a/rtdata/images/Light/actions/straighten.png b/rtdata/images/Light/actions/straighten.png new file mode 100644 index 000000000..3810c5e8a Binary files /dev/null and b/rtdata/images/Light/actions/straighten.png differ diff --git a/rtdata/images/Light/actions/toleftend.png b/rtdata/images/Light/actions/toleftend.png new file mode 100644 index 000000000..3fae3eae5 Binary files /dev/null and b/rtdata/images/Light/actions/toleftend.png differ diff --git a/rtdata/images/Light/actions/torightend.png b/rtdata/images/Light/actions/torightend.png new file mode 100644 index 000000000..a6b33af2d Binary files /dev/null and b/rtdata/images/Light/actions/torightend.png differ diff --git a/rtdata/images/Light/actions/transform.png b/rtdata/images/Light/actions/transform.png new file mode 100644 index 000000000..48f23e0b6 Binary files /dev/null and b/rtdata/images/Light/actions/transform.png differ diff --git a/rtdata/images/Light/actions/trash-hide-deleted.png b/rtdata/images/Light/actions/trash-hide-deleted.png new file mode 100644 index 000000000..95aaecdba Binary files /dev/null and b/rtdata/images/Light/actions/trash-hide-deleted.png differ diff --git a/rtdata/images/Light/actions/trash-show-empty.png b/rtdata/images/Light/actions/trash-show-empty.png new file mode 100644 index 000000000..dd35e4b30 Binary files /dev/null and b/rtdata/images/Light/actions/trash-show-empty.png differ diff --git a/rtdata/images/Light/actions/trash-show-full.png b/rtdata/images/Light/actions/trash-show-full.png new file mode 100644 index 000000000..fd6eff338 Binary files /dev/null and b/rtdata/images/Light/actions/trash-show-full.png differ diff --git a/rtdata/images/Light/actions/trash-thumbnail.png b/rtdata/images/Light/actions/trash-thumbnail.png new file mode 100644 index 000000000..4adf53ebf Binary files /dev/null and b/rtdata/images/Light/actions/trash-thumbnail.png differ diff --git a/rtdata/images/Light/actions/trash.png b/rtdata/images/Light/actions/trash.png new file mode 100644 index 000000000..dd35e4b30 Binary files /dev/null and b/rtdata/images/Light/actions/trash.png differ diff --git a/rtdata/images/Light/actions/undelete-rtl.png b/rtdata/images/Light/actions/undelete-rtl.png new file mode 100644 index 000000000..27f273bd6 Binary files /dev/null and b/rtdata/images/Light/actions/undelete-rtl.png differ diff --git a/rtdata/images/Light/actions/undelete-thumbnail-rtl.png b/rtdata/images/Light/actions/undelete-thumbnail-rtl.png new file mode 100644 index 000000000..7c26653a8 Binary files /dev/null and b/rtdata/images/Light/actions/undelete-thumbnail-rtl.png differ diff --git a/rtdata/images/Light/actions/undelete-thumbnail.png b/rtdata/images/Light/actions/undelete-thumbnail.png new file mode 100644 index 000000000..7c26653a8 Binary files /dev/null and b/rtdata/images/Light/actions/undelete-thumbnail.png differ diff --git a/rtdata/images/Light/actions/undelete.png b/rtdata/images/Light/actions/undelete.png new file mode 100644 index 000000000..27f273bd6 Binary files /dev/null and b/rtdata/images/Light/actions/undelete.png differ diff --git a/rtdata/images/Light/actions/warnhl.png b/rtdata/images/Light/actions/warnhl.png new file mode 100644 index 000000000..066241abc Binary files /dev/null and b/rtdata/images/Light/actions/warnhl.png differ diff --git a/rtdata/images/Light/actions/warnsh.png b/rtdata/images/Light/actions/warnsh.png new file mode 100644 index 000000000..5621b88b4 Binary files /dev/null and b/rtdata/images/Light/actions/warnsh.png differ diff --git a/rtdata/images/Light/actions/wavelet.png b/rtdata/images/Light/actions/wavelet.png new file mode 100644 index 000000000..3de85a8f1 Binary files /dev/null and b/rtdata/images/Light/actions/wavelet.png differ diff --git a/rtdata/images/Light/actions/wb-auto.png b/rtdata/images/Light/actions/wb-auto.png new file mode 100644 index 000000000..fa5c582ad Binary files /dev/null and b/rtdata/images/Light/actions/wb-auto.png differ diff --git a/rtdata/images/Light/actions/wb-camera.png b/rtdata/images/Light/actions/wb-camera.png new file mode 100644 index 000000000..e3f4b9a01 Binary files /dev/null and b/rtdata/images/Light/actions/wb-camera.png differ diff --git a/rtdata/images/Light/actions/wb-cloudy.png b/rtdata/images/Light/actions/wb-cloudy.png new file mode 100644 index 000000000..a04cc56b5 Binary files /dev/null and b/rtdata/images/Light/actions/wb-cloudy.png differ diff --git a/rtdata/images/Light/actions/wb-custom.png b/rtdata/images/Light/actions/wb-custom.png new file mode 100644 index 000000000..2cc95a999 Binary files /dev/null and b/rtdata/images/Light/actions/wb-custom.png differ diff --git a/rtdata/images/Light/actions/wb-flash.png b/rtdata/images/Light/actions/wb-flash.png new file mode 100644 index 000000000..35f643e46 Binary files /dev/null and b/rtdata/images/Light/actions/wb-flash.png differ diff --git a/rtdata/images/Light/actions/wb-fluorescent.png b/rtdata/images/Light/actions/wb-fluorescent.png new file mode 100644 index 000000000..f0da5ba72 Binary files /dev/null and b/rtdata/images/Light/actions/wb-fluorescent.png differ diff --git a/rtdata/images/Light/actions/wb-lamp.png b/rtdata/images/Light/actions/wb-lamp.png new file mode 100644 index 000000000..47f12d904 Binary files /dev/null and b/rtdata/images/Light/actions/wb-lamp.png differ diff --git a/rtdata/images/Light/actions/wb-led.png b/rtdata/images/Light/actions/wb-led.png new file mode 100644 index 000000000..5c2ef46d7 Binary files /dev/null and b/rtdata/images/Light/actions/wb-led.png differ diff --git a/rtdata/images/Light/actions/wb-shade.png b/rtdata/images/Light/actions/wb-shade.png new file mode 100644 index 000000000..617123893 Binary files /dev/null and b/rtdata/images/Light/actions/wb-shade.png differ diff --git a/rtdata/images/Light/actions/wb-sun.png b/rtdata/images/Light/actions/wb-sun.png new file mode 100644 index 000000000..115c8a0cb Binary files /dev/null and b/rtdata/images/Light/actions/wb-sun.png differ diff --git a/rtdata/images/Light/actions/wb-tungsten.png b/rtdata/images/Light/actions/wb-tungsten.png new file mode 100644 index 000000000..61ad022c4 Binary files /dev/null and b/rtdata/images/Light/actions/wb-tungsten.png differ diff --git a/rtdata/images/Light/actions/wb-water.png b/rtdata/images/Light/actions/wb-water.png new file mode 100644 index 000000000..a1ae414af Binary files /dev/null and b/rtdata/images/Light/actions/wb-water.png differ diff --git a/rtdata/images/Light/actions/zoom-100-identifier.png b/rtdata/images/Light/actions/zoom-100-identifier.png new file mode 100644 index 000000000..390fdebf2 Binary files /dev/null and b/rtdata/images/Light/actions/zoom-100-identifier.png differ diff --git a/rtdata/images/Light/devices/computer.png b/rtdata/images/Light/devices/computer.png new file mode 100644 index 000000000..5969fae78 Binary files /dev/null and b/rtdata/images/Light/devices/computer.png differ diff --git a/rtdata/images/Light/devices/drive-harddisk.png b/rtdata/images/Light/devices/drive-harddisk.png new file mode 100644 index 000000000..5969fae78 Binary files /dev/null and b/rtdata/images/Light/devices/drive-harddisk.png differ diff --git a/rtdata/images/Light/devices/drive-optical.png b/rtdata/images/Light/devices/drive-optical.png new file mode 100644 index 000000000..5e4ba680d Binary files /dev/null and b/rtdata/images/Light/devices/drive-optical.png differ diff --git a/rtdata/images/Light/devices/drive-removable-media.png b/rtdata/images/Light/devices/drive-removable-media.png new file mode 100644 index 000000000..378f0cbbe Binary files /dev/null and b/rtdata/images/Light/devices/drive-removable-media.png differ diff --git a/rtdata/images/Light/devices/gtk-cdrom.png b/rtdata/images/Light/devices/gtk-cdrom.png new file mode 100644 index 000000000..5e4ba680d Binary files /dev/null and b/rtdata/images/Light/devices/gtk-cdrom.png differ diff --git a/rtdata/images/Light/devices/media-flash.png b/rtdata/images/Light/devices/media-flash.png new file mode 100644 index 000000000..5969fae78 Binary files /dev/null and b/rtdata/images/Light/devices/media-flash.png differ diff --git a/rtdata/images/Light/devices/media-floppy.png b/rtdata/images/Light/devices/media-floppy.png new file mode 100644 index 000000000..378f0cbbe Binary files /dev/null and b/rtdata/images/Light/devices/media-floppy.png differ diff --git a/rtdata/images/Light/devices/media-optical-bd.png b/rtdata/images/Light/devices/media-optical-bd.png new file mode 100644 index 000000000..5e4ba680d Binary files /dev/null and b/rtdata/images/Light/devices/media-optical-bd.png differ diff --git a/rtdata/images/Light/devices/media-optical-dvd.png b/rtdata/images/Light/devices/media-optical-dvd.png new file mode 100644 index 000000000..5e4ba680d Binary files /dev/null and b/rtdata/images/Light/devices/media-optical-dvd.png differ diff --git a/rtdata/images/Light/devices/media-optical.png b/rtdata/images/Light/devices/media-optical.png new file mode 100644 index 000000000..5e4ba680d Binary files /dev/null and b/rtdata/images/Light/devices/media-optical.png differ diff --git a/rtdata/images/Light/devices/media-tape.png b/rtdata/images/Light/devices/media-tape.png new file mode 100644 index 000000000..5969fae78 Binary files /dev/null and b/rtdata/images/Light/devices/media-tape.png differ diff --git a/rtdata/images/Light/index.theme b/rtdata/images/Light/index.theme new file mode 100644 index 000000000..1188aa465 --- /dev/null +++ b/rtdata/images/Light/index.theme @@ -0,0 +1,42 @@ +[Icon Theme] +Name=RawTherapee-Light +Comment=Light theme for RawTherapee +Inherits=hicolor +Example=folder + +Directories=actions,apps,categories,devices,emblems,places,status + +[actions] +Size=22 +Context=Actions +Type=Fixed + +[apps] +Size=22 +Context=Applications +Type=Fixed + +[categories] +Size=22 +Context=Categories +Type=Fixed + +[devices] +Size=22 +Context=Devices +Type=Fixed + +[emblems] +Size=22 +Context=Emblems +Type=Fixed + +[places] +Size=22 +Context=Places +Type=Fixed + +[status] +Size=22 +Context=Status +Type=Fixed diff --git a/rtdata/images/Light/places/folder.png b/rtdata/images/Light/places/folder.png new file mode 100644 index 000000000..19ea93f4c Binary files /dev/null and b/rtdata/images/Light/places/folder.png differ diff --git a/rtdata/images/Light/places/gtk-directory.png b/rtdata/images/Light/places/gtk-directory.png new file mode 100644 index 000000000..19ea93f4c Binary files /dev/null and b/rtdata/images/Light/places/gtk-directory.png differ diff --git a/rtdata/images/Light/places/user-desktop.png b/rtdata/images/Light/places/user-desktop.png new file mode 100644 index 000000000..e11d7388e Binary files /dev/null and b/rtdata/images/Light/places/user-desktop.png differ diff --git a/rtdata/images/Light/places/user-home.png b/rtdata/images/Light/places/user-home.png new file mode 100644 index 000000000..69868e8d5 Binary files /dev/null and b/rtdata/images/Light/places/user-home.png differ diff --git a/rtdata/images/PanelEnding.png b/rtdata/images/PanelEnding.png new file mode 100644 index 000000000..b540adc66 Binary files /dev/null and b/rtdata/images/PanelEnding.png differ diff --git a/rtdata/images/beforeafter.png b/rtdata/images/beforeafter.png new file mode 100644 index 000000000..a4b3fac7b Binary files /dev/null and b/rtdata/images/beforeafter.png differ diff --git a/rtdata/images/cglabel0.png b/rtdata/images/cglabel0.png new file mode 100644 index 000000000..f3f0a3b27 Binary files /dev/null and b/rtdata/images/cglabel0.png differ diff --git a/rtdata/images/cglabel1.png b/rtdata/images/cglabel1.png new file mode 100644 index 000000000..3d5d745b2 Binary files /dev/null and b/rtdata/images/cglabel1.png differ diff --git a/rtdata/images/cglabel2.png b/rtdata/images/cglabel2.png new file mode 100644 index 000000000..f0bfb2e02 Binary files /dev/null and b/rtdata/images/cglabel2.png differ diff --git a/rtdata/images/cglabel3.png b/rtdata/images/cglabel3.png new file mode 100644 index 000000000..84aeceb47 Binary files /dev/null and b/rtdata/images/cglabel3.png differ diff --git a/rtdata/images/cglabel4.png b/rtdata/images/cglabel4.png new file mode 100644 index 000000000..c6d2286ed Binary files /dev/null and b/rtdata/images/cglabel4.png differ diff --git a/rtdata/images/cglabel5.png b/rtdata/images/cglabel5.png new file mode 100644 index 000000000..48568972d Binary files /dev/null and b/rtdata/images/cglabel5.png differ diff --git a/rtdata/images/clabel0.png b/rtdata/images/clabel0.png new file mode 100644 index 000000000..65410ff22 Binary files /dev/null and b/rtdata/images/clabel0.png differ diff --git a/rtdata/images/clabel1.png b/rtdata/images/clabel1.png new file mode 100644 index 000000000..39d679aaa Binary files /dev/null and b/rtdata/images/clabel1.png differ diff --git a/rtdata/images/clabel2.png b/rtdata/images/clabel2.png new file mode 100644 index 000000000..b9316398a Binary files /dev/null and b/rtdata/images/clabel2.png differ diff --git a/rtdata/images/clabel3.png b/rtdata/images/clabel3.png new file mode 100644 index 000000000..e804d36a1 Binary files /dev/null and b/rtdata/images/clabel3.png differ diff --git a/rtdata/images/clabel4.png b/rtdata/images/clabel4.png new file mode 100644 index 000000000..5ac41db81 Binary files /dev/null and b/rtdata/images/clabel4.png differ diff --git a/rtdata/images/clabel5.png b/rtdata/images/clabel5.png new file mode 100644 index 000000000..dbe190966 Binary files /dev/null and b/rtdata/images/clabel5.png differ diff --git a/rtdata/images/closedhand.png b/rtdata/images/closedhand.png new file mode 100644 index 000000000..a08542071 Binary files /dev/null and b/rtdata/images/closedhand.png differ diff --git a/rtdata/images/colour.png b/rtdata/images/colour.png new file mode 100644 index 000000000..e38094f02 Binary files /dev/null and b/rtdata/images/colour.png differ diff --git a/rtdata/images/crop-auto.png b/rtdata/images/crop-auto.png new file mode 100644 index 000000000..015a9555e Binary files /dev/null and b/rtdata/images/crop-auto.png differ diff --git a/rtdata/images/crop.png b/rtdata/images/crop.png new file mode 100644 index 000000000..345fa209e Binary files /dev/null and b/rtdata/images/crop.png differ diff --git a/rtdata/images/cross.png b/rtdata/images/cross.png new file mode 100644 index 000000000..6be9dde06 Binary files /dev/null and b/rtdata/images/cross.png differ diff --git a/rtdata/images/crossed-arrows-out.png b/rtdata/images/crossed-arrows-out.png new file mode 100644 index 000000000..d4b8c2f8f Binary files /dev/null and b/rtdata/images/crossed-arrows-out.png differ diff --git a/rtdata/images/curveType-NURBS.png b/rtdata/images/curveType-NURBS.png new file mode 100644 index 000000000..b18128159 Binary files /dev/null and b/rtdata/images/curveType-NURBS.png differ diff --git a/rtdata/images/curveType-controlPoints.png b/rtdata/images/curveType-controlPoints.png new file mode 100644 index 000000000..b8c4f447e Binary files /dev/null and b/rtdata/images/curveType-controlPoints.png differ diff --git a/rtdata/images/curveType-flatLinear.png b/rtdata/images/curveType-flatLinear.png new file mode 100644 index 000000000..ad061ef27 Binary files /dev/null and b/rtdata/images/curveType-flatLinear.png differ diff --git a/rtdata/images/curveType-linear.png b/rtdata/images/curveType-linear.png new file mode 100644 index 000000000..a76331321 Binary files /dev/null and b/rtdata/images/curveType-linear.png differ diff --git a/rtdata/images/curveType-parametric.png b/rtdata/images/curveType-parametric.png new file mode 100644 index 000000000..e1df7b699 Binary files /dev/null and b/rtdata/images/curveType-parametric.png differ diff --git a/rtdata/images/curveType-spline.png b/rtdata/images/curveType-spline.png new file mode 100644 index 000000000..a179b901d Binary files /dev/null and b/rtdata/images/curveType-spline.png differ diff --git a/rtdata/images/curveType-unchanged.png b/rtdata/images/curveType-unchanged.png new file mode 100644 index 000000000..825b94b4b Binary files /dev/null and b/rtdata/images/curveType-unchanged.png differ diff --git a/rtdata/images/default-settings-ltr.png b/rtdata/images/default-settings-ltr.png new file mode 100644 index 000000000..cb1cfbe12 Binary files /dev/null and b/rtdata/images/default-settings-ltr.png differ diff --git a/rtdata/images/default-settings-rtl.png b/rtdata/images/default-settings-rtl.png new file mode 100644 index 000000000..cb1cfbe12 Binary files /dev/null and b/rtdata/images/default-settings-rtl.png differ diff --git a/rtdata/images/detail.png b/rtdata/images/detail.png new file mode 100644 index 000000000..f4ad6e440 Binary files /dev/null and b/rtdata/images/detail.png differ diff --git a/rtdata/images/distortion-auto.png b/rtdata/images/distortion-auto.png new file mode 100644 index 000000000..a0b9c114d Binary files /dev/null and b/rtdata/images/distortion-auto.png differ diff --git a/rtdata/images/distortion.png b/rtdata/images/distortion.png new file mode 100644 index 000000000..2d606c4e7 Binary files /dev/null and b/rtdata/images/distortion.png differ diff --git a/rtdata/images/edited-small.png b/rtdata/images/edited-small.png new file mode 100644 index 000000000..7d6ecdede Binary files /dev/null and b/rtdata/images/edited-small.png differ diff --git a/rtdata/images/edited.png b/rtdata/images/edited.png new file mode 100644 index 000000000..85c81b2e1 Binary files /dev/null and b/rtdata/images/edited.png differ diff --git a/rtdata/images/editedg-small.png b/rtdata/images/editedg-small.png new file mode 100644 index 000000000..1de271128 Binary files /dev/null and b/rtdata/images/editedg-small.png differ diff --git a/rtdata/images/editednot-small.png b/rtdata/images/editednot-small.png new file mode 100644 index 000000000..c1a0299ed Binary files /dev/null and b/rtdata/images/editednot-small.png differ diff --git a/rtdata/images/editednotg-small.png b/rtdata/images/editednotg-small.png new file mode 100644 index 000000000..fa0de4fdf Binary files /dev/null and b/rtdata/images/editednotg-small.png differ diff --git a/rtdata/images/empty.png b/rtdata/images/empty.png new file mode 100644 index 000000000..fc5838fdb Binary files /dev/null and b/rtdata/images/empty.png differ diff --git a/rtdata/images/exposure.png b/rtdata/images/exposure.png new file mode 100644 index 000000000..0579cdd75 Binary files /dev/null and b/rtdata/images/exposure.png differ diff --git a/rtdata/images/filter.png b/rtdata/images/filter.png new file mode 100644 index 000000000..1059a8122 Binary files /dev/null and b/rtdata/images/filter.png differ diff --git a/rtdata/images/filterclear.png b/rtdata/images/filterclear.png new file mode 100644 index 000000000..47b3f2725 Binary files /dev/null and b/rtdata/images/filterclear.png differ diff --git a/rtdata/images/folder.png b/rtdata/images/folder.png new file mode 100644 index 000000000..551db978a Binary files /dev/null and b/rtdata/images/folder.png differ diff --git a/rtdata/images/fullscreen-exit.png b/rtdata/images/fullscreen-exit.png new file mode 100644 index 000000000..2946010be Binary files /dev/null and b/rtdata/images/fullscreen-exit.png differ diff --git a/rtdata/images/fullscreen.png b/rtdata/images/fullscreen.png new file mode 100644 index 000000000..3d9fccc28 Binary files /dev/null and b/rtdata/images/fullscreen.png differ diff --git a/rtdata/images/grayrated.png b/rtdata/images/grayrated.png new file mode 100644 index 000000000..c71a6d0c0 Binary files /dev/null and b/rtdata/images/grayrated.png differ diff --git a/rtdata/images/gtk-add.png b/rtdata/images/gtk-add.png new file mode 100644 index 000000000..21fc43cf3 Binary files /dev/null and b/rtdata/images/gtk-add.png differ diff --git a/rtdata/images/gtk-apply.png b/rtdata/images/gtk-apply.png new file mode 100644 index 000000000..f0bb96bfe Binary files /dev/null and b/rtdata/images/gtk-apply.png differ diff --git a/rtdata/images/gtk-close-small.png b/rtdata/images/gtk-close-small.png new file mode 100644 index 000000000..b92be85b1 Binary files /dev/null and b/rtdata/images/gtk-close-small.png differ diff --git a/rtdata/images/gtk-close.png b/rtdata/images/gtk-close.png new file mode 100644 index 000000000..a25b8c29a Binary files /dev/null and b/rtdata/images/gtk-close.png differ diff --git a/rtdata/images/gtk-color-picker-small.png b/rtdata/images/gtk-color-picker-small.png new file mode 100644 index 000000000..2f7b6cc87 Binary files /dev/null and b/rtdata/images/gtk-color-picker-small.png differ diff --git a/rtdata/images/gtk-color-picker.png b/rtdata/images/gtk-color-picker.png new file mode 100644 index 000000000..0ad9bc4f6 Binary files /dev/null and b/rtdata/images/gtk-color-picker.png differ diff --git a/rtdata/images/gtk-open.png b/rtdata/images/gtk-open.png new file mode 100644 index 000000000..5e6286c37 Binary files /dev/null and b/rtdata/images/gtk-open.png differ diff --git a/rtdata/images/gtk-save-large.png b/rtdata/images/gtk-save-large.png new file mode 100644 index 000000000..11170bd22 Binary files /dev/null and b/rtdata/images/gtk-save-large.png differ diff --git a/rtdata/images/gtk-undo-ltr.png b/rtdata/images/gtk-undo-ltr.png new file mode 100644 index 000000000..343eda063 Binary files /dev/null and b/rtdata/images/gtk-undo-ltr.png differ diff --git a/rtdata/images/gtk-undo-rtl.png b/rtdata/images/gtk-undo-rtl.png new file mode 100644 index 000000000..404ec98a5 Binary files /dev/null and b/rtdata/images/gtk-undo-rtl.png differ diff --git a/rtdata/images/gtk-undoall-ltr.png b/rtdata/images/gtk-undoall-ltr.png new file mode 100644 index 000000000..4a9a30d39 Binary files /dev/null and b/rtdata/images/gtk-undoall-ltr.png differ diff --git a/rtdata/images/gtk-undoall-rtl.png b/rtdata/images/gtk-undoall-rtl.png new file mode 100644 index 000000000..35303720e Binary files /dev/null and b/rtdata/images/gtk-undoall-rtl.png differ diff --git a/rtdata/images/gtk-zoom-100.png b/rtdata/images/gtk-zoom-100.png new file mode 100644 index 000000000..c7fae09c3 Binary files /dev/null and b/rtdata/images/gtk-zoom-100.png differ diff --git a/rtdata/images/gtk-zoom-fit.png b/rtdata/images/gtk-zoom-fit.png new file mode 100644 index 000000000..799a99ba0 Binary files /dev/null and b/rtdata/images/gtk-zoom-fit.png differ diff --git a/rtdata/images/gtk-zoom-in.png b/rtdata/images/gtk-zoom-in.png new file mode 100644 index 000000000..913e61968 Binary files /dev/null and b/rtdata/images/gtk-zoom-in.png differ diff --git a/rtdata/images/gtk-zoom-out.png b/rtdata/images/gtk-zoom-out.png new file mode 100644 index 000000000..298138baa Binary files /dev/null and b/rtdata/images/gtk-zoom-out.png differ diff --git a/rtdata/images/histBar.png b/rtdata/images/histBar.png new file mode 100644 index 000000000..8ebdf4fab Binary files /dev/null and b/rtdata/images/histBar.png differ diff --git a/rtdata/images/histBlue.png b/rtdata/images/histBlue.png new file mode 100644 index 000000000..b49a01dc7 Binary files /dev/null and b/rtdata/images/histBlue.png differ diff --git a/rtdata/images/histGreen.png b/rtdata/images/histGreen.png new file mode 100644 index 000000000..559b7d78a Binary files /dev/null and b/rtdata/images/histGreen.png differ diff --git a/rtdata/images/histRaw.png b/rtdata/images/histRaw.png new file mode 100644 index 000000000..30e10cf09 Binary files /dev/null and b/rtdata/images/histRaw.png differ diff --git a/rtdata/images/histRed.png b/rtdata/images/histRed.png new file mode 100644 index 000000000..91bb9f2f5 Binary files /dev/null and b/rtdata/images/histRed.png differ diff --git a/rtdata/images/histValue.png b/rtdata/images/histValue.png new file mode 100644 index 000000000..36d47564e Binary files /dev/null and b/rtdata/images/histValue.png differ diff --git a/rtdata/images/image-editor.png b/rtdata/images/image-editor.png new file mode 100644 index 000000000..9f9a335dc Binary files /dev/null and b/rtdata/images/image-editor.png differ diff --git a/rtdata/images/info.png b/rtdata/images/info.png new file mode 100644 index 000000000..94245aefd Binary files /dev/null and b/rtdata/images/info.png differ diff --git a/rtdata/images/list-add-small.png b/rtdata/images/list-add-small.png new file mode 100644 index 000000000..d26852798 Binary files /dev/null and b/rtdata/images/list-add-small.png differ diff --git a/rtdata/images/list-remove-red-small.png b/rtdata/images/list-remove-red-small.png new file mode 100644 index 000000000..ea67d1221 Binary files /dev/null and b/rtdata/images/list-remove-red-small.png differ diff --git a/rtdata/images/list-remove.png b/rtdata/images/list-remove.png new file mode 100644 index 000000000..85e1c30b3 Binary files /dev/null and b/rtdata/images/list-remove.png differ diff --git a/rtdata/images/lock-off.png b/rtdata/images/lock-off.png new file mode 100644 index 000000000..976af2977 Binary files /dev/null and b/rtdata/images/lock-off.png differ diff --git a/rtdata/images/lock-on.png b/rtdata/images/lock-on.png new file mode 100644 index 000000000..9c4bcd046 Binary files /dev/null and b/rtdata/images/lock-on.png differ diff --git a/rtdata/images/logoicon-wind.png b/rtdata/images/logoicon-wind.png new file mode 100644 index 000000000..39e2819da Binary files /dev/null and b/rtdata/images/logoicon-wind.png differ diff --git a/rtdata/images/media-usb.png b/rtdata/images/media-usb.png new file mode 100644 index 000000000..e9a279da1 Binary files /dev/null and b/rtdata/images/media-usb.png differ diff --git a/rtdata/images/meta.png b/rtdata/images/meta.png new file mode 100644 index 000000000..6f0c4185d Binary files /dev/null and b/rtdata/images/meta.png differ diff --git a/rtdata/images/move-1D-h.png b/rtdata/images/move-1D-h.png new file mode 100644 index 000000000..44babcfb4 Binary files /dev/null and b/rtdata/images/move-1D-h.png differ diff --git a/rtdata/images/move-1D-v.png b/rtdata/images/move-1D-v.png new file mode 100644 index 000000000..cbc1c7e68 Binary files /dev/null and b/rtdata/images/move-1D-v.png differ diff --git a/rtdata/images/move-2D.png b/rtdata/images/move-2D.png new file mode 100644 index 000000000..27e7c1e67 Binary files /dev/null and b/rtdata/images/move-2D.png differ diff --git a/rtdata/images/move-rotate.png b/rtdata/images/move-rotate.png new file mode 100644 index 000000000..70309972b Binary files /dev/null and b/rtdata/images/move-rotate.png differ diff --git a/rtdata/images/network.png b/rtdata/images/network.png new file mode 100644 index 000000000..8a77e5d92 Binary files /dev/null and b/rtdata/images/network.png differ diff --git a/rtdata/images/nocolorlabel.png b/rtdata/images/nocolorlabel.png new file mode 100644 index 000000000..be61570b0 Binary files /dev/null and b/rtdata/images/nocolorlabel.png differ diff --git a/rtdata/images/notrated.png b/rtdata/images/notrated.png new file mode 100644 index 000000000..f6b897b12 Binary files /dev/null and b/rtdata/images/notrated.png differ diff --git a/rtdata/images/openhand.png b/rtdata/images/openhand.png new file mode 100644 index 000000000..e52a28067 Binary files /dev/null and b/rtdata/images/openhand.png differ diff --git a/rtdata/images/panel-to-bottom.png b/rtdata/images/panel-to-bottom.png new file mode 100644 index 000000000..4e3b6057d Binary files /dev/null and b/rtdata/images/panel-to-bottom.png differ diff --git a/rtdata/images/panel-to-left.png b/rtdata/images/panel-to-left.png new file mode 100644 index 000000000..99821881d Binary files /dev/null and b/rtdata/images/panel-to-left.png differ diff --git a/rtdata/images/panel-to-right.png b/rtdata/images/panel-to-right.png new file mode 100644 index 000000000..6037c1fa9 Binary files /dev/null and b/rtdata/images/panel-to-right.png differ diff --git a/rtdata/images/panel-to-top.png b/rtdata/images/panel-to-top.png new file mode 100644 index 000000000..b129e9d4c Binary files /dev/null and b/rtdata/images/panel-to-top.png differ diff --git a/rtdata/images/popuparrow.png b/rtdata/images/popuparrow.png new file mode 100644 index 000000000..f933a71ca Binary files /dev/null and b/rtdata/images/popuparrow.png differ diff --git a/rtdata/images/processing-pause.png b/rtdata/images/processing-pause.png new file mode 100644 index 000000000..dc3c6b633 Binary files /dev/null and b/rtdata/images/processing-pause.png differ diff --git a/rtdata/images/processing-play.png b/rtdata/images/processing-play.png new file mode 100644 index 000000000..e653de0f1 Binary files /dev/null and b/rtdata/images/processing-play.png differ diff --git a/rtdata/images/processing.png b/rtdata/images/processing.png new file mode 100644 index 000000000..2a602d656 Binary files /dev/null and b/rtdata/images/processing.png differ diff --git a/rtdata/images/rated.png b/rtdata/images/rated.png new file mode 100644 index 000000000..99d6b73ba Binary files /dev/null and b/rtdata/images/rated.png differ diff --git a/rtdata/images/ratednot.png b/rtdata/images/ratednot.png new file mode 100644 index 000000000..ed7c561df Binary files /dev/null and b/rtdata/images/ratednot.png differ diff --git a/rtdata/images/ratednotg.png b/rtdata/images/ratednotg.png new file mode 100644 index 000000000..2f619d755 Binary files /dev/null and b/rtdata/images/ratednotg.png differ diff --git a/rtdata/images/raw.png b/rtdata/images/raw.png new file mode 100644 index 000000000..aa8d0bb6d Binary files /dev/null and b/rtdata/images/raw.png differ diff --git a/rtdata/images/recent-save.png b/rtdata/images/recent-save.png new file mode 100644 index 000000000..be5de85d9 Binary files /dev/null and b/rtdata/images/recent-save.png differ diff --git a/rtdata/images/refresh-red.png b/rtdata/images/refresh-red.png new file mode 100644 index 000000000..24dc27e64 Binary files /dev/null and b/rtdata/images/refresh-red.png differ diff --git a/rtdata/images/refresh-white.png b/rtdata/images/refresh-white.png new file mode 100644 index 000000000..c4143da34 Binary files /dev/null and b/rtdata/images/refresh-white.png differ diff --git a/rtdata/images/resize.png b/rtdata/images/resize.png new file mode 100644 index 000000000..4d3f0e681 Binary files /dev/null and b/rtdata/images/resize.png differ diff --git a/rtdata/images/rt-logo-large.png b/rtdata/images/rt-logo-large.png new file mode 100644 index 000000000..3639139da Binary files /dev/null and b/rtdata/images/rt-logo-large.png differ diff --git a/rtdata/images/rt-logo.png b/rtdata/images/rt-logo.png new file mode 100644 index 000000000..c56193604 Binary files /dev/null and b/rtdata/images/rt-logo.png differ diff --git a/rtdata/images/saved.png b/rtdata/images/saved.png new file mode 100644 index 000000000..2a465c0f2 Binary files /dev/null and b/rtdata/images/saved.png differ diff --git a/rtdata/images/savedg.png b/rtdata/images/savedg.png new file mode 100644 index 000000000..6855b7c2e Binary files /dev/null and b/rtdata/images/savedg.png differ diff --git a/rtdata/images/savednot.png b/rtdata/images/savednot.png new file mode 100644 index 000000000..532e8b366 Binary files /dev/null and b/rtdata/images/savednot.png differ diff --git a/rtdata/images/savednotg.png b/rtdata/images/savednotg.png new file mode 100644 index 000000000..c6079a1ed Binary files /dev/null and b/rtdata/images/savednotg.png differ diff --git a/rtdata/images/splash.png b/rtdata/images/splash.png new file mode 100644 index 000000000..2dbec173e Binary files /dev/null and b/rtdata/images/splash.png differ diff --git a/rtdata/images/stock-flip-horizontal.png b/rtdata/images/stock-flip-horizontal.png new file mode 100644 index 000000000..9c42f276e Binary files /dev/null and b/rtdata/images/stock-flip-horizontal.png differ diff --git a/rtdata/images/stock-flip-vertical.png b/rtdata/images/stock-flip-vertical.png new file mode 100644 index 000000000..2b838c15b Binary files /dev/null and b/rtdata/images/stock-flip-vertical.png differ diff --git a/rtdata/images/stock-rotate-270.png b/rtdata/images/stock-rotate-270.png new file mode 100644 index 000000000..2c6e23d37 Binary files /dev/null and b/rtdata/images/stock-rotate-270.png differ diff --git a/rtdata/images/stock-rotate-90.png b/rtdata/images/stock-rotate-90.png new file mode 100644 index 000000000..31cd17760 Binary files /dev/null and b/rtdata/images/stock-rotate-90.png differ diff --git a/rtdata/images/straighten-small.png b/rtdata/images/straighten-small.png new file mode 100644 index 000000000..c750356ab Binary files /dev/null and b/rtdata/images/straighten-small.png differ diff --git a/rtdata/images/straighten.png b/rtdata/images/straighten.png new file mode 100644 index 000000000..955af8f0a Binary files /dev/null and b/rtdata/images/straighten.png differ diff --git a/rtdata/images/toleftend.png b/rtdata/images/toleftend.png new file mode 100644 index 000000000..4dfd61fec Binary files /dev/null and b/rtdata/images/toleftend.png differ diff --git a/rtdata/images/torightend.png b/rtdata/images/torightend.png new file mode 100644 index 000000000..2c5204f74 Binary files /dev/null and b/rtdata/images/torightend.png differ diff --git a/rtdata/images/transform.png b/rtdata/images/transform.png new file mode 100644 index 000000000..fc2f66cef Binary files /dev/null and b/rtdata/images/transform.png differ diff --git a/rtdata/images/trash-show-empty.png b/rtdata/images/trash-show-empty.png new file mode 100644 index 000000000..08fcdfc93 Binary files /dev/null and b/rtdata/images/trash-show-empty.png differ diff --git a/rtdata/images/trash-show-full.png b/rtdata/images/trash-show-full.png new file mode 100644 index 000000000..c9bd50e51 Binary files /dev/null and b/rtdata/images/trash-show-full.png differ diff --git a/rtdata/images/trash.png b/rtdata/images/trash.png new file mode 100644 index 000000000..08fcdfc93 Binary files /dev/null and b/rtdata/images/trash.png differ diff --git a/rtdata/images/uncolorlabel.png b/rtdata/images/uncolorlabel.png new file mode 100644 index 000000000..b060306bf Binary files /dev/null and b/rtdata/images/uncolorlabel.png differ diff --git a/rtdata/images/undelete.png b/rtdata/images/undelete.png new file mode 100644 index 000000000..10b5d94fd Binary files /dev/null and b/rtdata/images/undelete.png differ diff --git a/rtdata/images/unrated.png b/rtdata/images/unrated.png new file mode 100644 index 000000000..2f619d755 Binary files /dev/null and b/rtdata/images/unrated.png differ diff --git a/rtdata/images/warnhl.png b/rtdata/images/warnhl.png new file mode 100644 index 000000000..98dddeb92 Binary files /dev/null and b/rtdata/images/warnhl.png differ diff --git a/rtdata/images/warnsh.png b/rtdata/images/warnsh.png new file mode 100644 index 000000000..ee2c31e08 Binary files /dev/null and b/rtdata/images/warnsh.png differ diff --git a/rtdata/languages/Catala b/rtdata/languages/Catala new file mode 100644 index 000000000..1a7d82545 --- /dev/null +++ b/rtdata/languages/Catala @@ -0,0 +1,1852 @@ +#01 2009-10-10 JMG + +ABOUT_TAB_BUILD;Versió +ABOUT_TAB_CREDITS;Crèdits +ABOUT_TAB_LICENSE;Llicència +ABOUT_TAB_RELEASENOTES;Notes de la versió +ABOUT_TAB_SPLASH;Splash +ADJUSTER_RESET_TO_DEFAULT;Restaura predeterminats +BATCHQUEUE_AUTOSTART;Auto engega +BATCH_PROCESSING;Processament per lots +CURVEEDITOR_CURVES;Corbes +CURVEEDITOR_CURVE;Corba +CURVEEDITOR_CUSTOM;A mida +CURVEEDITOR_DARKS;Foscos +CURVEEDITOR_HIGHLIGHTS;Clars intensos +CURVEEDITOR_LIGHTS;Clars +CURVEEDITOR_LINEAR;Lineal +CURVEEDITOR_LOADDLGLABEL;Carrega corba... +CURVEEDITOR_MINMAXCPOINTS;Mínima/Màxima punts de control +CURVEEDITOR_NURBS;Gàbia de control +CURVEEDITOR_PARAMETRIC;Paramètric +CURVEEDITOR_SAVEDLGLABEL;Desa corba... +CURVEEDITOR_SHADOWS;Ombres +CURVEEDITOR_TOOLTIPCOPY;Copia la corba actual al portap. +CURVEEDITOR_TOOLTIPLINEAR;Restaura corba lineal (recta) +CURVEEDITOR_TOOLTIPLOAD;Carrega corba de fitxer +CURVEEDITOR_TOOLTIPPASTE;Enganxa corba del portap. +CURVEEDITOR_TOOLTIPSAVE;Desa la corba actual +CURVEEDITOR_TYPE;Tipus: +DIRBROWSER_FOLDERS;Carpetes +EDITWINDOW_TITLE;Edita imatge +EXIFFILTER_APERTURE;Obertura +EXIFFILTER_CAMERA;Càmera +EXIFFILTER_EXPOSURECOMPENSATION;Compensació d'exposició (EV) +EXIFFILTER_FILETYPE;Tipus de fitxer +EXIFFILTER_FOCALLEN;Distància focal +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Objectiu +EXIFFILTER_METADATAFILTER;Empra filtres Metadata +EXIFFILTER_SHUTTER;Temps d'exposició +EXIFPANEL_ADDEDITHINT;Afegir nou atribut o editar-lo +EXIFPANEL_ADDEDIT;Afegir/Editar +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Entrar valor +EXIFPANEL_ADDTAGDLG_SELECTTAG;Selecciona atribut +EXIFPANEL_ADDTAGDLG_TITLE;Afegir/Editar atribut +EXIFPANEL_KEEPHINT;Conserva atributs seleccionats en escriure un nou fitxer +EXIFPANEL_KEEP;Guarda +EXIFPANEL_REMOVEHINT;Esborra atributs seleccionats en escriure un nou fitxer +EXIFPANEL_REMOVE;Esborra +EXIFPANEL_RESETALLHINT;Reinicialitza atributs als valors originals +EXIFPANEL_RESETALL;Reinic. tot +EXIFPANEL_RESETHINT;Reinic. atributs seleccionats als valors originals +EXIFPANEL_RESET;Reinicialitza +EXIFPANEL_SUBDIRECTORY;Subdirectori +EXPORT_BYPASS_ALL;Selecciona / Deselecciona tot +EXPORT_BYPASS_DEFRINGE;Salta desserrellar +EXPORT_BYPASS_DIRPYRDENOISE;Salta reducció de soroll +EXPORT_BYPASS_DIRPYREQUALIZER;Salta contrast per nivells de detall +EXPORT_BYPASS_RAW_CA;Salta [raw] correcció d'aberració cromàtica +EXPORT_BYPASS_RAW_CCSTEPS;Salta [raw] supressió de fals color +EXPORT_BYPASS_RAW_DCB_ENHANCE;Salta [raw] passos de millora DCB +EXPORT_BYPASS_RAW_DCB_ITERATIONS;Salta [raw] iteracions DCB +EXPORT_BYPASS_RAW_DF;Salta [raw] marc fosc +EXPORT_BYPASS_RAW_FF;Salta [raw] camp pla +EXPORT_BYPASS_RAW_GREENTHRESH;Salta [raw] equilibri de verd +EXPORT_BYPASS_RAW_LINENOISE;Salta [raw] línia de filtre de soroll +EXPORT_BYPASS_SHARPENEDGE;Salta afinar vores +EXPORT_BYPASS_SHARPENING;Salta reenfocar +EXPORT_BYPASS_SHARPENMICRO;Salta microcontrast +EXPORT_BYPASS_SH_HQ;Salta ombres/clars intensos (alta qualitat) +EXPORT_FASTEXPORTOPTIONS;Opcions d'exportació ràpida +EXPORT_INSTRUCTIONS;Les opcions d'exportació ràpida permeten estalviar temps i recursos obviant els ajustos establerts de desenvolupament i processar la cua amb més celeritat. Es recomana aquest mètode per a una ràpida generació d'imatges de baixa resolució quan cal prioritzar la rapidesa o en canvis de tamany d'una o diverses imatges sense modificar els seus paràmetres de desenvolupament desats. +EXPORT_MAXHEIGHT;Alçada màxima: +EXPORT_MAXWIDTH;Ample màxim: +EXPORT_PUTTOQUEUEFAST; Posa a la cua per a export. ràpida +EXPORT_RAW_DMETHOD;Mètode de demosaicar +EXTPROGTARGET_1;raw +EXTPROGTARGET_2;cua processada +FILEBROWSER_ADDDELTEMPLATE;Afeg/Treu plantilles... +FILEBROWSER_APPLYPROFILE;Aplica +FILEBROWSER_APPLYPROFILE_PARTIAL;Aplica - parcial +FILEBROWSER_AUTODARKFRAME;Auto marc fosc +FILEBROWSER_AUTOFLATFIELD;Auto camp pla +FILEBROWSER_BROWSEPATHBUTTONHINT;Clic per navegar al path escollit +FILEBROWSER_BROWSEPATHHINT;Escriviu path on buscar.\nCtrl-O dirigir-se al path de la finestra de text.\nEnter / Ctrl-Enter (en el gestor de fitxers) per a navegar allí;\n\nPath dreceres:\n ~ - directori home de l'usuari\n ! - directori de fotografies de l'usuari +FILEBROWSER_CACHECLEARFROMFULL;Esborra el cau - tot +FILEBROWSER_CACHECLEARFROMPARTIAL;Esborra el cau - part +FILEBROWSER_CACHE;Cau +FILEBROWSER_CLEARPROFILE;Neteja +FILEBROWSER_COPYPROFILE;Copia +FILEBROWSER_CURRENT_NAME;Nom actual: +FILEBROWSER_DARKFRAME;Marc fosc +FILEBROWSER_DELETEDLGLABEL;Confirmació d'esborrar fitxer +FILEBROWSER_DELETEDLGMSGINCLPROC;Segur que voleu suprimir els fitxers %1 seleccionats incloent la versió processada a la cua? +FILEBROWSER_DELETEDLGMSG;Segur que voleu esborrar els %1 fitxers? +FILEBROWSER_EMPTYTRASHHINT;Buida permanentment la paperera +FILEBROWSER_EMPTYTRASH;Buida paperera +FILEBROWSER_EXEC_CPB;Constructor de perfils propis +FILEBROWSER_EXTPROGMENU;Obre amb +FILEBROWSER_FLATFIELD;Camp pla +FILEBROWSER_MOVETODARKFDIR;Canvia al directori de camps foscos +FILEBROWSER_MOVETOFLATFIELDDIR;Canvia al directori de camps plans +FILEBROWSER_NEW_NAME;Nou nom: +FILEBROWSER_OPENDEFAULTVIEWER;Visor per omissió (cua-processat) +FILEBROWSER_PARTIALPASTEPROFILE;Enganxa - parcialment +FILEBROWSER_PASTEPROFILE;Enganxa +FILEBROWSER_POPUPCANCELJOB;Cancel·la treball +FILEBROWSER_POPUPCOLORLABEL;Color d'etiqueta +FILEBROWSER_POPUPCOPYTO;Copia a... +FILEBROWSER_POPUPFILEOPERATIONS;Operacions amb fitxers +FILEBROWSER_POPUPMOVEEND;Mou a la fi de la cua +FILEBROWSER_POPUPMOVEHEAD;Mou a l'inici de la cua +FILEBROWSER_POPUPMOVETO;Mou cap a... +FILEBROWSER_POPUPOPENINEDITOR;Obrir en Editor +FILEBROWSER_POPUPOPEN;Obre +FILEBROWSER_POPUPPROCESSFAST;Posa a la cua (export. ràpida) +FILEBROWSER_POPUPPROCESS;Posa a la cua +FILEBROWSER_POPUPPROFILEOPERATIONS;Processant operacions de perfil +FILEBROWSER_POPUPRANK;Rang +FILEBROWSER_POPUPREMOVEINCLPROC;Esborra amb sortida de la cua +FILEBROWSER_POPUPREMOVE;Esborra el fitxer +FILEBROWSER_POPUPRENAME;Reanomena +FILEBROWSER_POPUPSELECTALL;Selec. tot +FILEBROWSER_POPUPTRASH;Llença a la paperera +FILEBROWSER_POPUPUNRANK;Treu el rang +FILEBROWSER_POPUPUNTRASH;Recup. de la paperera +FILEBROWSER_QUERYBUTTONHINT;Neteja la recerca +FILEBROWSER_QUERYHINT;Escriviu part del nom d'un fitxer a cercar o bé llista amb comes com a separadort.\nE.g. 1001,1004,1199 \n\nCtrl-F entra a la finestra de text a cercar (en el gestor de fitxers).\nEnter comença a buscar.\nEscape neteja. +FILEBROWSER_QUERYLABEL; Cerca: +FILEBROWSER_RENAMEDLGLABEL;Reanomena fitxer +FILEBROWSER_RENAMEDLGMSG;Reanomena fitxer "%1" a: +FILEBROWSER_SELECTDARKFRAME;Selecc. marc fosc... +FILEBROWSER_SELECTFLATFIELD;Selecc. camp pla... +FILEBROWSER_SHOWCOLORLABEL1HINT;Mostra imatges etiqueta vermella.\nDrecera: Alt-1 +FILEBROWSER_SHOWCOLORLABEL2HINT;Mostra imatges etiqueta groga.\nDrecera: Alt-2 +FILEBROWSER_SHOWCOLORLABEL3HINT;Mostra imatges etiqueta verda.\nDrecera: Alt-3 +FILEBROWSER_SHOWCOLORLABEL4HINT;Mostra imatges etiqueta blava.\nDrecera: Alt-4 +FILEBROWSER_SHOWCOLORLABEL5HINT;Mostra imatges etiqueta porpra.\nDrecera: Alt-5 +FILEBROWSER_SHOWDIRHINT;Neteja tots els filtres.\nDrecera: D +FILEBROWSER_SHOWEDITEDHINT;Mostra imatges editades.\nDrecera: 7 +FILEBROWSER_SHOWEDITEDNOTHINT;Mostra imatges no editades.\nDrecera: 6 +FILEBROWSER_SHOWEXIFINFO;Mostra dades EXIF.\nDrecera: i +FILEBROWSER_SHOWRANK1HINT;Exposa imatges d' 1 estrella.\nDrecera: 1 +FILEBROWSER_SHOWRANK2HINT;Exposa imatges de 2 estrelles.\nDrecera: 2 +FILEBROWSER_SHOWRANK3HINT;Exposa imatges de 3 estrelles.\nDrecera: 3 +FILEBROWSER_SHOWRANK4HINT;Exposa imatges de 4 estrelles.\nDrecera: 4 +FILEBROWSER_SHOWRANK5HINT;Exposa imatges de 5 estrelles.\nDrecera: 5 +FILEBROWSER_SHOWRECENTLYSAVEDHINT;Mostra últimes imatges desades.\nDrecera: Alt-7 +FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Mostra imatges no recentment desades.\nDrecera: Alt-6 +FILEBROWSER_SHOWTRASHHINT;Veure què hi ha a la paperera.\nDrecera: Ctrl-t +FILEBROWSER_SHOWUNCOLORHINT;Mostra imatges sense etiqueta de color.\nDrecera: Alt-0 +FILEBROWSER_SHOWUNRANKHINT;Mostra imatges sense rang.\nDrecera: 0 +FILEBROWSER_STARTPROCESSINGHINT;Inicia el processament de les imatges de la cua +FILEBROWSER_STARTPROCESSING;Inicia procés +FILEBROWSER_STOPPROCESSINGHINT;Atura processament d'imatges de la cua +FILEBROWSER_STOPPROCESSING;Atura processament +FILEBROWSER_THUMBSIZE;Tamany minifoto +FILEBROWSER_TOOLTIP_STOPPROCESSING;Inicia processat automàticament en rebre un nou treball +FILEBROWSER_ZOOMINHINT;Engrandir minifoto.\nDrecera: + +FILEBROWSER_ZOOMOUTHINT;Reduïr minifoto.\nDrecera: - +GENERAL_ABOUT;Respecte a +GENERAL_AFTER;Després +GENERAL_BEFORE;Abans +GENERAL_CANCEL;Cancel·la +GENERAL_DISABLED;Inactivat +GENERAL_DISABLE;Inactiva +GENERAL_ENABLED;Activat +GENERAL_ENABLE;Activa +GENERAL_FILE;Fitxer +GENERAL_LANDSCAPE;Horitzontal +GENERAL_NA;n/a +GENERAL_NONE;No cap +GENERAL_NO;No +GENERAL_OK;OK +GENERAL_PORTRAIT;Vertical +GENERAL_SAVE;Desa +GENERAL_UNCHANGED;(No canviat) +GENERAL_WARNING;Avís +HISTOGRAM_TOOLTIP_BAR;Mostra/amaga la barra indicadora RGB\nClic botó dret a la previsualització per a congelar/descongelar +HISTOGRAM_TOOLTIP_B;Mostra/amaga l'histograma BLAU +HISTOGRAM_TOOLTIP_FULL;Canvia entre histograma complet o escalat +HISTOGRAM_TOOLTIP_G;Mostra/amaga l'histograma VERD +HISTOGRAM_TOOLTIP_L;Mostra/amaga l'histograma de luminància CIELAB +HISTOGRAM_TOOLTIP_RAW;Mostra/Amaga l'histograma RAW +HISTOGRAM_TOOLTIP_R;Mostra/amaga l'histograma VERMELL +HISTORY_CHANGED;Canviat +HISTORY_CUSTOMCURVE;Corba particular +HISTORY_DELSNAPSHOT;Esborra +HISTORY_FROMCLIPBOARD;Del portapapers +HISTORY_LABEL;Història +HISTORY_MSG_1;Imatge oberta +HISTORY_MSG_2;PP3 carregat +HISTORY_MSG_3;PP3 canviat +HISTORY_MSG_4;Repassant la història +HISTORY_MSG_5;Brillantor +HISTORY_MSG_6;Contrast +HISTORY_MSG_7;Negre +HISTORY_MSG_8;Compensació d'exposició +HISTORY_MSG_9;Compressió de clars intensos +HISTORY_MSG_10;Compressió de foscos +HISTORY_MSG_11;Corba de to 1 +HISTORY_MSG_12;Exposició automàtica +HISTORY_MSG_13;Pèrdua per exposició +HISTORY_MSG_14;Luminància: Brillantor +HISTORY_MSG_15;Luminància: Contrast +HISTORY_MSG_16;Luminància: Negre +HISTORY_MSG_17;Luminància: Compressió de clars +HISTORY_MSG_18;Luminància: Compressió de foscos +HISTORY_MSG_19;Corba 'L' +HISTORY_MSG_20;Enfocant +HISTORY_MSG_21;Enfocant -Radi +HISTORY_MSG_22;Enfocant -Quantitat +HISTORY_MSG_23;Enfocant -Llindar +HISTORY_MSG_24;Enfocar només vores +HISTORY_MSG_25;Enfocant -Radi detecció de vora +HISTORY_MSG_26;Enfocant -Tolerància vora +HISTORY_MSG_27;Enfocant -Control de halo +HISTORY_MSG_28;Control de halo -quantitat +HISTORY_MSG_29;Mètode d'enfocar +HISTORY_MSG_30;Deconvolució: Radi +HISTORY_MSG_31;Deconvolució: Quantitat +HISTORY_MSG_32;Deconvolució: Ablaniment +HISTORY_MSG_33;Deconvolució: Iteracions +HISTORY_MSG_34;Correcció distorsió LCP +HISTORY_MSG_35;Correcció vorafosc LCP +HISTORY_MSG_36;Correcció A.C. LCP +HISTORY_MSG_37;Nivells automàtics +HISTORY_MSG_38;Mètode de balanç de blancs +HISTORY_MSG_39;Temperatura de color +HISTORY_MSG_40;Tint de balanç de blancs +HISTORY_MSG_41;Corba de to mode 1 +HISTORY_MSG_42;Corba de to 2 +HISTORY_MSG_43;Corba de to mode 2 +HISTORY_MSG_44;Lumin. dessoroll Radi +HISTORY_MSG_45;Lumin. dessoroll, tolerància vores +HISTORY_MSG_46;Dessorollant color +HISTORY_MSG_47;Barreja clars intensos ICC amb la matriu +HISTORY_MSG_48;Usa corba de to DCP +HISTORY_MSG_49;Dessoroll de color, sensib. de vores +HISTORY_MSG_50;Foscos/clars intensos +HISTORY_MSG_51;Clars intensos +HISTORY_MSG_52;Foscos +HISTORY_MSG_53;Amplada de to de clars +HISTORY_MSG_54;Amplada de to de foscos +HISTORY_MSG_55;Contrast local +HISTORY_MSG_56;Radi foscos/clars intensos +HISTORY_MSG_57;Rotació tosca +HISTORY_MSG_58;Inversió horitzontal +HISTORY_MSG_59;Inversió vertical +HISTORY_MSG_60;Rotació +HISTORY_MSG_61;Auto-omple +HISTORY_MSG_62;Correcció distorsió de l'objectiu +HISTORY_MSG_63;Instantània seleccionada +HISTORY_MSG_64;Cropa foto +HISTORY_MSG_65;Correcció A.C. +HISTORY_MSG_66;Recuperació de clars intensos +HISTORY_MSG_67;Recup. de clars: quantitat +HISTORY_MSG_68;Recup. de clars: mètode +HISTORY_MSG_69;Espai de color de treball +HISTORY_MSG_70;Espai de color de sortida +HISTORY_MSG_71;Espai de color d'entrada +HISTORY_MSG_72;Correcció del vorafosc +HISTORY_MSG_73;Barrejador de canals +HISTORY_MSG_74;Canviar l'escala +HISTORY_MSG_75;Mètode de canvi d'escala +HISTORY_MSG_76;Metadades Exif +HISTORY_MSG_77;Metadades IPTC +HISTORY_MSG_78;Especificacions per a escalar +HISTORY_MSG_79;Variar amplada +HISTORY_MSG_80;Variar alçada +HISTORY_MSG_81;Escalat activat +HISTORY_MSG_82;Perfil canviat +HISTORY_MSG_83;Alta qual. ombres/clars intensos +HISTORY_MSG_84;Correcció de perspectiva +HISTORY_MSG_85;Perfil de correcció de la lent +HISTORY_MSG_86;Equalitzador d'ónula +HISTORY_MSG_87;Impuls de Reduc. de Soroll +HISTORY_MSG_88;Llindar impuls RS +HISTORY_MSG_89;Reducció de soroll +HISTORY_MSG_90;RS - luminància +HISTORY_MSG_91;RS - crominància +HISTORY_MSG_92;RS - gama +HISTORY_MSG_93;Intens. de contrast per grau de detall +HISTORY_MSG_94;Contrast per grau de detall +HISTORY_MSG_95;Cromaticitat +HISTORY_MSG_96;corba 'a' +HISTORY_MSG_97;corba 'b' +HISTORY_MSG_98;Mètode demosaicat +HISTORY_MSG_99;Filtre píxels cremats/morts +HISTORY_MSG_100;Saturació RGB +HISTORY_MSG_101;HSV EQ -- Hue +HISTORY_MSG_102;HSV EQ -- Saturació +HISTORY_MSG_103;HSV EQ -- Valor +HISTORY_MSG_104;HSV Equalitzador +HISTORY_MSG_105;Desserrellant +HISTORY_MSG_106;Desserrellar, radi +HISTORY_MSG_107;Desserrellar, llindar +HISTORY_MSG_108;Llindar compr. clars intensos +HISTORY_MSG_109;Escala capsa d'inclusió +HISTORY_MSG_110;L'escalat s'aplica a +HISTORY_MSG_111;Evita estralls de color +HISTORY_MSG_112;--no usat-- +HISTORY_MSG_113;Protecció de tons vermell i pell +HISTORY_MSG_114;Iteracions DCB +HISTORY_MSG_115;Iteracions fals color +HISTORY_MSG_116;DCB ampliat +HISTORY_MSG_117;Correcció CA vermell +HISTORY_MSG_118;Correcció CA blau +HISTORY_MSG_119;Línia dessoroll +HISTORY_MSG_120;Llindar equil. verd +HISTORY_MSG_121;Raw auto CA +HISTORY_MSG_122;Auto marc fosc +HISTORY_MSG_123;Fitxer de camp fosc +HISTORY_MSG_124;Correc. expo. linear +HISTORY_MSG_125;Correc. exposició preservant HL +HISTORY_MSG_126;Fitxer de camp pla +HISTORY_MSG_127;Auto-sel. camp pla +HISTORY_MSG_128;Camp pla borrós - radi +HISTORY_MSG_129;Camp pla borrós - tipus +HISTORY_MSG_130;Auto-distorsió +HISTORY_MSG_131;Dessoroll de luminància +HISTORY_MSG_132;Dessoroll de crominància +HISTORY_MSG_133;Gama +HISTORY_MSG_134;Posició Gama +HISTORY_MSG_135;Gama lliure +HISTORY_MSG_136;Pendent de Gama +HISTORY_MSG_137;Negre nivell verd 1 +HISTORY_MSG_138;Negre nivell roig +HISTORY_MSG_139;Negre nivell blau +HISTORY_MSG_140;Negre nivell verd 2 +HISTORY_MSG_141;Negre nivell verd junts +HISTORY_MSG_142;Afinant vores - iteracions +HISTORY_MSG_143;Afinant vores - quantitat +HISTORY_MSG_144;Microcontrast - quantitat +HISTORY_MSG_145;Microcontrast - uniformitat +HISTORY_MSG_146;Afinament de vores +HISTORY_MSG_147;Afinant vores - només luminància +HISTORY_MSG_148;Microcontrast +HISTORY_MSG_149;Microcontrast - matriu 3x3 +HISTORY_MSG_150;Artefactes en post-demosaicat/reducció de soroll +HISTORY_MSG_151;Vibrància +HISTORY_MSG_152;Vibrància - tons pastel +HISTORY_MSG_153;Vibrància - tons saturats +HISTORY_MSG_154;Vibrància - protecció de tons de pell +HISTORY_MSG_155;Vibrància - Evita pèrdua de color +HISTORY_MSG_156;Vibrància - Enllaç de tons pastel-saturats +HISTORY_MSG_157;Vibrància - llindar pastel/saturat +HISTORY_MSG_158;Intensitat +HISTORY_MSG_159;Parada a les vores +HISTORY_MSG_160;Escala +HISTORY_MSG_161;Iteracions de ponderació +HISTORY_MSG_162;Mapejant tons +HISTORY_MSG_163;RGB corbes - R +HISTORY_MSG_164;RGB corbes - G +HISTORY_MSG_165;RGB corbes - B +HISTORY_MSG_166;Nivells neutrals +HISTORY_MSG_167;N&B tons +HISTORY_MSG_168;Corba 'CC' +HISTORY_MSG_169;Corba 'CH' +HISTORY_MSG_170;Vibrància - corba +HISTORY_MSG_171;Corba 'LC' +HISTORY_MSG_172;Restriccció LC als tons vermell i pell +HISTORY_MSG_173;RS - Detall de la luminància +HISTORY_NEWSNAPSHOT;Afegeix +HISTORY_SNAPSHOTS;Instantànies +HISTORY_SNAPSHOT;Instantània +IPTCPANEL_AUTHORSPOSITIONHINT;Títol del(s) creador(s) de l'objecte (By-line Title). +IPTCPANEL_AUTHORSPOSITION;Tractament o títol de l'autor +IPTCPANEL_AUTHOR;Autor +IPTCPANEL_CAPTIONHINT;Un text de descripció de les dades (Caption - Abstract). +IPTCPANEL_CAPTIONWRITERHINT;Nom de qui ha escrit, editat o corregit la imatge o la descripció (Writer - Editor). +IPTCPANEL_CAPTIONWRITER;Autor de la descripció +IPTCPANEL_CAPTION;Text descriptiu +IPTCPANEL_CATEGORYHINT;Classificació de la imatge, segons el proveïdor (Category). +IPTCPANEL_CATEGORY;Classificació +IPTCPANEL_CITYHINT;Ciutat d'origen de la imatge (City). +IPTCPANEL_CITY;Ciutat +IPTCPANEL_COPYHINT;Copiar dades actuals IPTC al portapapers +IPTCPANEL_COPYRIGHTHINT;Qualsevol notificació necessària sobre copyright (Copyright Notice). +IPTCPANEL_COPYRIGHT;Copyright +IPTCPANEL_COUNTRYHINT;Nom del país o lloc on va ser creada la imatge (Country - Primary Location Name). +IPTCPANEL_COUNTRY;País +IPTCPANEL_CREDITHINT;Identitat del proveïdor de la imatge, no necessàriament el propietari/creador (Credit). +IPTCPANEL_CREDIT;Crèdit +IPTCPANEL_DATECREATEDHINT;Data en què va ser creat el contingut intel·lectual de la imatge; Format: AAAAMMDD (Date Created). +IPTCPANEL_DATECREATED;Data de creació +IPTCPANEL_EMBEDDEDHINT;Restaurar les dades IPTC encastades al fitxer d'imatge +IPTCPANEL_EMBEDDED;Encastat +IPTCPANEL_HEADLINEHINT;Una nota publicable que és una sinopsi dels continguts de la imatge (Headline). +IPTCPANEL_HEADLINE;Capçalera +IPTCPANEL_INSTRUCTIONSHINT;Altres instruccions editorials sobre l'ús de la imatge (Special Instructions). +IPTCPANEL_INSTRUCTIONS;Instruccions +IPTCPANEL_KEYWORDSHINT;Paraules clau que faciliten la recerca de la imatge (Keywords). +IPTCPANEL_KEYWORDS;Paraules clau +IPTCPANEL_PASTEHINT;Enganxa les dades IPTC del portapapers +IPTCPANEL_PROVINCEHINT;Regió/Estat d'origen de la imatge (Province-State). +IPTCPANEL_PROVINCE;Regió +IPTCPANEL_RESETHINT;Reinici perfil per omissió +IPTCPANEL_RESET;Reinici +IPTCPANEL_SOURCEHINT;Propietari original del contingut intel·lectual de la imatge (Source). +IPTCPANEL_SOURCE;Font +IPTCPANEL_SUPPCATEGORIESHINT;Precisió sobre el tema de la imatge (Supplemental Categories). +IPTCPANEL_SUPPCATEGORIES;Classif. detallada +IPTCPANEL_TITLEHINT;Referència breu de la imatge (Object Name). +IPTCPANEL_TITLE;Títol +IPTCPANEL_TRANSREFERENCEHINT;Codi que indica el lloc de la transmissió original (Original Transmission Reference). +IPTCPANEL_TRANSREFERENCE;Refer. transmissió +MAIN_BUTTON_FULLSCREEN;Pantalla sencera +MAIN_BUTTON_PREFERENCES;Preferències +MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Afeg. imatge actual a la cua de procés.\nDrecera: Ctrl+B +MAIN_BUTTON_SAVE_TOOLTIP;Desa la imatge actual.\nDrecera: Ctrl+S +MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Edita la imatge actual a un editor extern.\nDrecera: Ctrl+E +MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Mostra/amaga panells laterals.\nDrecera: m +MAIN_BUTTON_UNFULLSCREEN;Fi pantalla sencera +MAIN_FRAME_BATCHQUEUE;Cua de procés +MAIN_FRAME_BATCHQUEUE_TOOLTIP; Cua de procés.\nDrecera: Ctrl-F3 +MAIN_FRAME_EDITOR;Editor +MAIN_FRAME_EDITOR_TOOLTIP; Editor.\nDrecera: Ctrl-F4 +MAIN_FRAME_FILEBROWSER;Gestor de fitxers +MAIN_FRAME_FILEBROWSER_TOOLTIP; Gestor de fitxers.\nDrecera: Ctrl-F2 +MAIN_FRAME_PLACES;Llocs +MAIN_FRAME_PLACES_ADD;Afeg +MAIN_FRAME_PLACES_DEL;Treu +MAIN_FRAME_RECENT;Carpetes recents +MAIN_MSG_ALREADYEXISTS;Fitxer ja existent. +MAIN_MSG_CANNOTLOAD;No es pot carregar la imatge +MAIN_MSG_CANNOTSAVE;Error desant el fitxer +MAIN_MSG_CANNOTSTARTEDITOR;No es pot iniciar l'editor +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Poseu el path correcte en el diàleg "Preferències". +MAIN_MSG_EMPTYFILENAME;Nom de fitxer no indicat! +MAIN_MSG_IMAGEUNPROCESSED;Això requereix que totes les imatges seleccionades siguin abans processades a la cua. +MAIN_MSG_NAVIGATOR;Navegador +MAIN_MSG_QOVERWRITE;El voleu sobreescriure? +MAIN_TAB_COLOR;Color +MAIN_TAB_COLOR_TOOLTIP;Drecera: Alt-C +MAIN_TAB_DETAIL;Detall +MAIN_TAB_DETAIL_TOOLTIP;Drecera: Alt-D +MAIN_TAB_DEVELOP;Desenv. +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPORT; Exporta +MAIN_TAB_EXPOSURE;Exposició +MAIN_TAB_EXPOSURE_TOOLTIP;Drecera: Alt-E +MAIN_TAB_FILTER;Filtre +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadades +MAIN_TAB_METADATA_TOOLTIP;Drecera: Alt-M +MAIN_TAB_RAW;RAW +MAIN_TAB_RAW_TOOLTIP;Drecera: Alt-R +MAIN_TAB_TRANSFORM;Transforma +MAIN_TAB_TRANSFORM_TOOLTIP;Drecera: Alt-T +MAIN_TOOLTIP_BACKCOLOR0;Color de fons de la vista prèvia: basat en tema\nDrecera: 8 +MAIN_TOOLTIP_BACKCOLOR1;Color de fons de la vista prèvia: Negre\nDrecera: 9 +MAIN_TOOLTIP_BACKCOLOR2;Color de fons de la vista prèvia: Blanc\nDrecera: 0 +MAIN_TOOLTIP_BEFOREAFTERLOCK;Bloca / Desbloca el abans vista\n\nBloca: conserva la abans vista sense canvis.\nütil per a valorar l'efecte acumulatiu de moltes eines.\nA més, es poden fer comparacions amb qualsevol punt de la història\n\nDesbloca: el abans la vista romandrà després vista d'un pas enrera, mostrant la imatge abans de l'efecte de l'eina present. +MAIN_TOOLTIP_HIDEHP;Mostra/amaga panell esquerre (incloent la història).\nDrecera: 1 +MAIN_TOOLTIP_INDCLIPPEDH;Indicador de pèrdues en clars.\nDrecera: < +MAIN_TOOLTIP_INDCLIPPEDS;Indicador de pèrdues en foscos.\nDrecera: > +MAIN_TOOLTIP_PREVIEWB;Previsualitza Canal blau.\nDrecera: b +MAIN_TOOLTIP_PREVIEWFOCUSMASK;Previsualitza reenfocament.\nDrecera: Majús-F\n\nMés pecís en imatges amb poca profunditat de camp, poc soroll i gran zoom\n\nPer a millorar la precisa detecció en imatges amb soroll proveu amb zoom més petit: 10-30%\n\nLa vista prèvia surt més lenta amb el reenfocament activat. +MAIN_TOOLTIP_PREVIEWG;Previsualitza Canal verd.\nDrecera: g +MAIN_TOOLTIP_PREVIEWL;Previsualitza Lluminositat.\nDrecera: v\n\n0.299*R + 0.587*G + 0.114*B +MAIN_TOOLTIP_PREVIEWR;Previsualitza Canal vermell.\nDrecera: r +MAIN_TOOLTIP_QINFO;Info breu de la imatge.\nDrecera: i +MAIN_TOOLTIP_SHOWHIDELP1;Mostra/amaga panell esquerre.\nDrecera: 1 +MAIN_TOOLTIP_SHOWHIDERP1;Mostra/amaga panell dret.\nDrecera: Alt-L +MAIN_TOOLTIP_SHOWHIDETP1;Mostra/amaga panell superior.\nDrecera: Majús-L +MAIN_TOOLTIP_THRESHOLD;Llindar +MAIN_TOOLTIP_TOGGLE;Alterna vista abans/després.\nDrecera: Majús-B +NAVIGATOR_XY_FULL;Amplada = %1, Altura = %2 +NAVIGATOR_XY_NA;x = n/a, y = n/a +OPTIONS_DEFIMG_MISSING;No es troba el perfil per omissió per a fotografies no-raw o no s'ha especificat.\n\nReviseu el directori de perfils, potser falta o està fet malbé.\n\nEs faran servir els valors interns per omissió. +OPTIONS_DEFRAW_MISSING;No es troba el perfil per omissió per a fotografies raw.\n\nReviseu el directori de perfils, potser falta o està fet malbé.\n\nEs faran servir els valors interns per omissió. +PARTIALPASTE_BASICGROUP;Ajustos bàsics +PARTIALPASTE_CACORRECTION;Correcció A. C.(Aberració Cromàtica) +PARTIALPASTE_CHANNELMIXER;Barrejador de canals +PARTIALPASTE_COARSETRANS;Rotació 90 graus/ inversió +PARTIALPASTE_COLORGROUP;Ajustos de color +PARTIALPASTE_COMMONTRANSFORMPARAMS;Auto-omple +PARTIALPASTE_COMPOSITIONGROUP;Ajustos de composició +PARTIALPASTE_CROP;Cropa +PARTIALPASTE_DARKFRAMEAUTOSELECT;Auto-sel. marc fosc +PARTIALPASTE_DARKFRAMEFILE;Fitxer de marc fosc +PARTIALPASTE_DEFRINGE;Desserrella +PARTIALPASTE_DETAILGROUP;Ajustos de detall +PARTIALPASTE_DIALOGLABEL;Enganxa parcialment al perfil de procés +PARTIALPASTE_DIRPYRDENOISE;Reducció de soroll +PARTIALPASTE_DIRPYREQUALIZER;Contrast per grau de detall +PARTIALPASTE_DISTORTION;Correcció de distorsió +PARTIALPASTE_EPD;Mapejant tons +PARTIALPASTE_EVERYTHING;Tot plegat +PARTIALPASTE_EXIFCHANGES;Canvis a les dades Exif +PARTIALPASTE_EXPOSURE;Exposició +PARTIALPASTE_FLATFIELDAUTOSELECT;Auto-sel. Camp Pla +PARTIALPASTE_FLATFIELDBLURRADIUS;Radi borrositat CP +PARTIALPASTE_FLATFIELDBLURTYPE;Tipus borrositat CP +PARTIALPASTE_FLATFIELDFILE;Fitxer de camp pla +PARTIALPASTE_HSVEQUALIZER;Equalitzador HSV +PARTIALPASTE_ICMGAMMA;Sortida gama +PARTIALPASTE_ICMSETTINGS;Ajustos gestió de color +PARTIALPASTE_IMPULSEDENOISE;Impuls de reducció de soroll +PARTIALPASTE_IPTCINFO;Dades IPTC +PARTIALPASTE_LABCURVE;Ajustos Lab +PARTIALPASTE_LENSGROUP;Ajustos de l'objectiu +PARTIALPASTE_LENSPROFILE;Perfil de correcció de l'objectiu +PARTIALPASTE_METAGROUP;Ajustos Metadades +PARTIALPASTE_PERSPECTIVE;Perspectiva +PARTIALPASTE_PREPROCESS_GREENEQUIL;Equilibri verd +PARTIALPASTE_PREPROCESS_LINEDENOISE;Filtre línia de soroll +PARTIALPASTE_RAWCACORR_AUTO;Auto-correcció AC +PARTIALPASTE_RAWCACORR_CABLUE;AC blau +PARTIALPASTE_RAWCACORR_CARED;AC vermell +PARTIALPASTE_RAWEXPOS_BLACK;Nivell negre +PARTIALPASTE_RAWEXPOS_LINEAR;Factor de corr. linear de punt blanc +PARTIALPASTE_RAWEXPOS_PRESER;Corr. punt blanc preservant HL (EV) +PARTIALPASTE_RAWGROUP;Ajustos raw +PARTIALPASTE_RAW_DCBENHANCE;Aplica pas de millora DCB +PARTIALPASTE_RAW_DCBITERATIONS;Nombre d'iteracions DCB +PARTIALPASTE_RAW_DMETHOD;Mètode demosaicat +PARTIALPASTE_RAW_FALSECOLOR;Passos de supressió de fals color demosaicant +PARTIALPASTE_RESIZE;Canviar tamany +PARTIALPASTE_RGBCURVES;Corbes RGB +PARTIALPASTE_ROTATION;Rotació +PARTIALPASTE_SHADOWSHIGHLIGHTS;Foscos/clars intensos +PARTIALPASTE_SHARPENEDGE;Vores +PARTIALPASTE_SHARPENING;Enfocant (USM/RL) +PARTIALPASTE_SHARPENMICRO;Microcontrast +PARTIALPASTE_VIBRANCE;Vibrància +PARTIALPASTE_VIGNETTING;Correcció del vorafosc +PARTIALPASTE_WHITEBALANCE;Balanç de blancs +PREFERENCES_ADD;AFEG +PREFERENCES_APPLNEXTSTARTUP;Efectiu en reiniciar +PREFERENCES_AUTOMONPROFILE;Usa els perfils dels monitors dels sist. operatius automàticament +PREFERENCES_BATCH_PROCESSING;Process. per lots +PREFERENCES_BEHAVIOR;Comportament +PREFERENCES_CACHECLEARALL;Esborrar tot +PREFERENCES_CACHECLEARPROFILES;Esborrar perfils +PREFERENCES_CACHECLEARTHUMBS;Esborra minifotos +PREFERENCES_CACHEMAXENTRIES;Màxim nombre d'entrades a la mem. cau +PREFERENCES_CACHEOPTS;Opcions memòria cau +PREFERENCES_CACHETHUMBHEIGHT;Màxima alçada de minifoto +PREFERENCES_CLIPPINGIND;Indicador de pèrdues +PREFERENCES_CMETRICINTENT;Intent colorimètric +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_CUSTPROFBUILD;Constructor de perfils de procés particulars +PREFERENCES_CUTOVERLAYBRUSH;Cropa màscara color/transparència +PREFERENCES_DARKFRAMEFOUND;Trobat +PREFERENCES_DARKFRAMESHOTS;trets +PREFERENCES_DARKFRAMETEMPLATES;plantilles +PREFERENCES_DARKFRAME;Marc fosc +PREFERENCES_DATEFORMATHINT;Podeu fer servir les següents cadenes formatades:\n%y : any\n%m : mes\n%d : dia\n\nPer exemple, el format de data hongarès és:\n%y/%m/%d +PREFERENCES_DATEFORMAT;Format de data +PREFERENCES_DEFAULTLANG;Idioma per omissió +PREFERENCES_DEFAULTTHEME;Tema per omissió +PREFERENCES_DIRDARKFRAMES;Carpeta de marcs foscos +PREFERENCES_DIRHOME;directori home +PREFERENCES_DIRLAST;Últim directori usat +PREFERENCES_DIROTHER;Un altre +PREFERENCES_DIRSELECTDLG;Selecc. directori d'inici... +PREFERENCES_DIRSOFTWARE;Instal·lació al directori +PREFERENCES_EDITORCMDLINE;Una altra línia de comandament +PREFERENCES_EDITORLAYOUT;Sortida d'editor +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_FLATFIELDFOUND;Trobat +PREFERENCES_FLATFIELDSDIR;Carpeta de camps plans +PREFERENCES_FLATFIELDSHOTS;trets +PREFERENCES_FLATFIELDTEMPLATES;plantilles +PREFERENCES_FLATFIELD;Camp pla +PREFERENCES_FORIMAGE;Per a imatge no raw +PREFERENCES_FORRAW;Per fitxers RAW +PREFERENCES_GIMPPATH;Directori d'instal. del GIMP +PREFERENCES_HISTOGRAMPOSITIONLEFT;Histograma al panell esquerre +PREFERENCES_HLTHRESHOLD;Llindar pèrdues en clars +PREFERENCES_ICCDIR;Directori dels perfils de color +PREFERENCES_IMPROCPARAMS;Paràm. per omissió de procés d'imatge +PREFERENCES_INTENT_ABSOLUTE;Colorimètric absolut +PREFERENCES_INTENT_PERCEPTUAL;Perceptual +PREFERENCES_INTENT_RELATIVE;Colorimètric relatiu +PREFERENCES_INTENT_SATURATION;Saturació +PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Mostra la mini JPEG encastada si el raw no està editat +PREFERENCES_LANGAUTODETECT;Usa idioma del sistema +PREFERENCES_MENUGROUPEXTPROGS;Grup "Obrir amb" +PREFERENCES_MENUGROUPFILEOPERATIONS;Grup "Operacions amb fitxers" +PREFERENCES_MENUGROUPLABEL;Grup "Etiqueta de color" +PREFERENCES_MENUGROUPPROFILEOPERATIONS;Grup "Operacions de procés de perfils" +PREFERENCES_MENUGROUPRANK;Grup "Rang" +PREFERENCES_MENUOPTIONS;Opcions del menú +PREFERENCES_METADATA;Metadata +PREFERENCES_MONITORICC;Perfil de color del monitor +PREFERENCES_MULTITABDUALMON;Mode multitreball en segon monitor, si se'n té un +PREFERENCES_MULTITAB;Mode multitreball +PREFERENCES_OUTDIRFOLDERHINT;Posa les imatges desades al directori seleccionat +PREFERENCES_OUTDIRFOLDER;Desa al directori +PREFERENCES_OUTDIRTEMPLATEHINT;Podeu fer servir les següents cadenes de format:\n%f, %d1, %d2, ..., %p1, %p2, ..., %r\n\nAquest format es basa en les diferents parts del path d'una fotografia o bé alguns dels seus atributs.\n\nPer exemple, si la foto en curs està localitzada a:\n/home/tom/fotos/2010-10-31/dsc0042.nef\nel significat de les cadenes de format és:\n%d4 = home\n%d3 = tom\n%d2 = fotos\n%d1 = 2010-10-31\n%f = dsc0042\n%p1 = /home/tom/fotos/2010-10-31/\n%p2 = /home/tom/fotos/\n%p3 = /home/tom/\n%p4 = /home/\n\n%r es canviarà pel rang de la foto. Si la foto no té rang, %r es convertirà en un '0'. Si la foto és a la paperera bin, %r es convertirà en 'x'.\n\nSi desitgeu desar la imatge actual on hi ha l'original, escriviu:\n%p1/%f\n\nSi desitgeu desar la imatge actual en un directori de nom "refetes" sota el directori de la imatge oberta, escriviu:\n%p1/refetes/%f\n\nSi desitgeu desar la imatge actual en un directori de nom "/home/tom/photos/refetes/2010-10-31", escriviu:\n%p2/refetes/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Usar plantilla +PREFERENCES_OUTDIR;Directori de sortida +PREFERENCES_OVERLAY_FILENAMES;Sobreposar noms de fitxer a les minifotos +PREFERENCES_OVERWRITEOUTPUTFILE;Sobrescriu fitxers en desar-los +PREFERENCES_PANFACTORLABEL;Factor +PREFERENCES_PARSEDEXTADDHINT;Escriu una extensió i prem aquí per veure la llista +PREFERENCES_PARSEDEXTADD;Afegir extensió +PREFERENCES_PARSEDEXTDELHINT;Esborrar l'extensió seleccionada de la llista +PREFERENCES_PARSEDEXT;Extensions analitzades +PREFERENCES_PROFILEHANDLING;Ficant mà als perfils de procés +PREFERENCES_PROFILELOADPR;Prioritat de càrrega de perfils +PREFERENCES_PROFILEPRCACHE;Perfil a la mem. cau +PREFERENCES_PROFILEPRFILE;Perfil juntament amb el fitxer +PREFERENCES_PROFILESAVECACHE;Desa els paràmetres de procés a la memòria cau +PREFERENCES_PROFILESAVEINPUT;Desa els paràm. de procés juntament amb la imatge +PREFERENCES_PROPERTY;Propietat +PREFERENCES_PSPATH;Directori d'instal. d'Adobe Photoshop +PREFERENCES_SELECTFONT;Selec. font +PREFERENCES_SELECTLANG;Seleccionar idioma +PREFERENCES_SELECTTHEME;Seleccionar tema +PREFERENCES_SET;Fixa +PREFERENCES_SHOWBASICEXIF;Mostra principals dades Exif +PREFERENCES_SHOWDATETIME;Indica data i hora +PREFERENCES_SHOWEXPOSURECOMPENSATION;Mostra compensació d'exposició +PREFERENCES_SHTHRESHOLD;Llindar pèrdues en foscos +PREFERENCES_SINGLETABVERTAB;Mode simple treball, vistes verticals +PREFERENCES_SINGLETAB;Mode simple treball +PREFERENCES_SLIMUI;Interfície senzilla +PREFERENCES_SND_BATCHQUEUEDONE;Procs. de la cua fets +PREFERENCES_SND_HELP;Poseu el path o bé no res (res=silenci). A Windows useu "SystemDefault", "SystemAsterisk" etc. pels sons del sistema. +PREFERENCES_SND_LNGEDITPROCDONE;Process. d'editor fet +PREFERENCES_SND_TRESHOLDSECS;després d'uns segons +PREFERENCES_STARTUPIMDIR;Directori inicial de les imatges +PREFERENCES_TAB_BROWSER;Gestor de fitxers +PREFERENCES_TAB_COLORMGR;Gestió del color +PREFERENCES_TAB_GENERAL;General +PREFERENCES_TAB_IMPROC;Processament de la imatge +PREFERENCES_TAB_SOUND;Sons +PREFERENCES_TP_LABEL;Panell d'eines: +PREFERENCES_TP_USEICONORTEXT;Usa les icones tab en comptes de text +PREFERENCES_TP_VSCROLLBAR;Amaga la barra d'eines vertical +PREFERENCES_TUNNELMETADATA;Copia IPTC/XMP sense canvis al fitxer de sortida (en treball amb altres progs.) +PREFERENCES_USESYSTEMTHEME; Usa tema del sistema +PREFERENCES_WORKFLOW;Flux de treball +PROFILEPANEL_COPYPPASTE;Paràmetres a copiar +PROFILEPANEL_LABEL;Perfils de postprocés +PROFILEPANEL_LOADDLGLABEL;Carrega paràm. de postprocés... +PROFILEPANEL_LOADPPASTE;Paràmetres a carregar +PROFILEPANEL_PASTEPPASTE;Paràmetres a afegir +PROFILEPANEL_PCUSTOM;Especial +PROFILEPANEL_PFILE;Del fitxer +PROFILEPANEL_PLASTSAVED;Darrera desada +PROFILEPANEL_SAVEDLGLABEL;Desar paràm. de postprocés... +PROFILEPANEL_SAVEPPASTE;Paràmetres a desar +PROFILEPANEL_TOOLTIPCOPY;Copia perfil actual al portapapers.\nCtrl-click per seleccionar els paràmetres a copiar +PROFILEPANEL_TOOLTIPLOAD;Carrega perfil d'un fitxer.\nCtrl-click per seleccionar els paràmetres a carregar +PROFILEPANEL_TOOLTIPPASTE; Enganxa perfil del portapapers.\nCtrl-click per seleccionar els paràmetres a enganxar +PROFILEPANEL_TOOLTIPSAVE;Desa l'actual com a perfil.\nCtrl-click per seleccionar els paràmetres a desar +PROGRESSBAR_LOADINGTHUMBS;Carregant minifotos... +PROGRESSBAR_LOADING;Carregant imatge... +PROGRESSBAR_LOADJPEG;Carregant fitxer JPEG... +PROGRESSBAR_LOADPNG;Carregant fitxer PNG... +PROGRESSBAR_LOADTIFF;Carregant fitxer TIFF... +PROGRESSBAR_PROCESSING;Processant imatge... +PROGRESSBAR_PROCESSING_PROFILESAVED;Desat el perfil de procés +PROGRESSBAR_READY;A punt +PROGRESSBAR_SAVEJPEG;Desant fitxer JPEG... +PROGRESSBAR_SAVEPNG;Desant fitxer PNG... +PROGRESSBAR_SAVETIFF;Desant fitxer TIFF... +PROGRESSDLG_PROFILECHANGEDINBROWSER;Processant perfil canviat al navegador +QINFO_ISO;ISO +QINFO_NOEXIF;No hi ha dades Exif. +SAVEDLG_AUTOSUFFIX;Afegeix automàticament un sufix si el fitxer ja hi és +SAVEDLG_FILEFORMAT;Format del fitxer +SAVEDLG_JPEGQUAL;Qualitat JPEG +SAVEDLG_PNGCOMPR;Compressió PNG +SAVEDLG_PUTTOQUEUEHEAD;Posa al principi de la cua de procés +SAVEDLG_PUTTOQUEUETAIL;Posa a la fi de la cua de procés +SAVEDLG_PUTTOQUEUE;Posa a la cua de procés +SAVEDLG_SAVEIMMEDIATELY;Desa ara mateix +SAVEDLG_SAVESPP;Desa els paràmetres de procés amb la imatge +SAVEDLG_SUBSAMP;Submostreig +SAVEDLG_SUBSAMP_1;Millor compressió +SAVEDLG_SUBSAMP_2;Equilibrat +SAVEDLG_SUBSAMP_3;Millor qualitat +SAVEDLG_SUBSAMP_TOOLTIP;Gran compressió: 4:1:1\nEquilibrat: 4:2:2\nMillor qualitat: 4:4:4 +SAVEDLG_TIFFUNCOMPRESSED;TIFF no comprimit +SAVEDLG_WARNFILENAME;El fitxer es dirà +SHCSELECTOR_TOOLTIP;Clic al botó dret per a restaurar\nla posició dels 3 nivells. +THRESHOLDSELECTOR_BL;Baix-esquerra +THRESHOLDSELECTOR_BR;Baix-dreta +THRESHOLDSELECTOR_B;Baix +THRESHOLDSELECTOR_HINT;Prement la tecla Majús per a moure punts individuals de control. +THRESHOLDSELECTOR_TL;Dalt-esquerra +THRESHOLDSELECTOR_TR;Dalt-dreta +THRESHOLDSELECTOR_T;Dalt +TOOLBAR_TOOLTIP_CROP;Cropar selecció.\nDrecera: c +TOOLBAR_TOOLTIP_HAND;Eina mà.\nDrecera: h +TOOLBAR_TOOLTIP_STRAIGHTEN;Dreçar / rotació fina.\nDrecera: s\n\nIndica la vertical o horitzontal dibuixant una línia de guia sobre la previsualització de la imatge. L'angle de rotació es mostrarà junt a la guia. El centre de rotació és el centre geomètric de la imatge. +TOOLBAR_TOOLTIP_WB;Afina balanç de blancs.\nDrecera: w +TP_CACORRECTION_BLUE;Blau +TP_CACORRECTION_LABEL;Correcció A. C. (Aberració Cromàtica) +TP_CACORRECTION_RED;Vermell +TP_CHMIXER_BLUE;Canal blau +TP_CHMIXER_GREEN;Canal verd +TP_CHMIXER_LABEL;Barrejador de canals +TP_CHMIXER_RED;Canal vermell +TP_CHROMATABERR_LABEL;Aberració cromàtica +TP_COARSETRAF_TOOLTIP_HFLIP;Inversió horitzontal +TP_COARSETRAF_TOOLTIP_ROTLEFT;Rotació esquerra.\nDrecera: [ +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Rotació dreta.\nDrecera: ] +TP_COARSETRAF_TOOLTIP_VFLIP;Inversió vertical +TP_CROP_FIXRATIO;Fixa proporció: +TP_CROP_GTDIAGONALS;Regla de diagonals +TP_CROP_GTEPASSPORT;Passaport biomètric +TP_CROP_GTFRAME;Marc +TP_CROP_GTGRID;Graella +TP_CROP_GTNONE;No cap +TP_CROP_GTRULETHIRDS;Regla dels terços +TP_CROP_GUIDETYPE;Tipus de guia: +TP_CROP_H;Alt +TP_CROP_LABEL;Cropa +TP_CROP_PPI;PPI= +TP_CROP_SELECTCROP;Selecc. cropar +TP_CROP_W;Ample +TP_CROP_X;x +TP_CROP_Y;y +TP_DARKFRAME_AUTOSELECT;Auto-selecció +TP_DARKFRAME_LABEL;Marc fosc +TP_DEFRINGE_LABEL;Desserrella +TP_DEFRINGE_RADIUS;Radi +TP_DEFRINGE_THRESHOLD;Llindar +TP_DIRPYRDENOISE_CHROMA;Crominància +TP_DIRPYRDENOISE_GAMMA;Gama +TP_DIRPYRDENOISE_LABEL;Reducció de soroll (només imatges raw) +TP_DIRPYRDENOISE_LDETAIL;Detall de luminància +TP_DIRPYRDENOISE_LUMA;Luminància +TP_DIRPYREQUALIZER_LABEL;Contrast per grau de detall +TP_DIRPYREQUALIZER_LUMACOARSEST;Més bast +TP_DIRPYREQUALIZER_LUMACONTRAST_MINUS;Contrast- +TP_DIRPYREQUALIZER_LUMACONTRAST_PLUS;Contrast+ +TP_DIRPYREQUALIZER_LUMAFINEST;Més fi +TP_DIRPYREQUALIZER_LUMANEUTRAL;Neutral +TP_DIRPYREQUALIZER_THRESHOLD;Llindar +TP_DISTORTION_AMOUNT;Quantitat +TP_DISTORTION_AUTO;Auto correcció de distorsió +TP_DISTORTION_AUTO_TIP;(Experimental) Correc. automàtica de distorsió de lent per algunes càmeres (M4/3, algunes compactes DC, etc.) +TP_DISTORTION_LABEL;Distorsió +TP_EPD_EDGESTOPPING;Aturant a les vores +TP_EPD_LABEL;Mapejant tons +TP_EPD_REWEIGHTINGITERATES;Iteracions de ponderació +TP_EPD_SCALE;Escala +TP_EPD_STRENGTH;Intensitat +TP_EXPOSURE_AUTOLEVELS;Nivells automàtics +TP_EXPOSURE_AUTOLEVELS_TIP;Activa auto-nivells per a ajustar automàticament els valors dels paràmetres segons anàlisi de la imatge +TP_EXPOSURE_BLACKLEVEL;Negre +TP_EXPOSURE_BRIGHTNESS;Brillantor +TP_EXPOSURE_CLIP;Retall +TP_EXPOSURE_CLIP_TIP;Conjunt de píxels que es retallaran en l'anivellament automàtic +TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Llindar recup. clars intensos +TP_EXPOSURE_COMPRHIGHLIGHTS;Quantitat recuperació de clars +TP_EXPOSURE_COMPRSHADOWS;Recuperació de foscos +TP_EXPOSURE_CONTRAST;Contrast +TP_EXPOSURE_CURVEEDITOR1;Corba de to 1 +TP_EXPOSURE_CURVEEDITOR2;Corba de to 2 +TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Mireu aquesta secció del manual per aconseguir els millors resultats amb dobles corbes:\nThe Toolbox > Exposure Tab > Exposure Panel > Tone Curve +TP_EXPOSURE_EXPCOMP;Compens. d'exposició +TP_EXPOSURE_LABEL;Exposició +TP_EXPOSURE_SATURATION;Saturació +TP_EXPOSURE_TCMODE_FILMLIKE;Com a film +TP_EXPOSURE_TCMODE_LABEL1;Corba mode 1 +TP_EXPOSURE_TCMODE_LABEL2;Corba mode 2 +TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Saturació i valor de mescla +TP_EXPOSURE_TCMODE_STANDARD;Estàndard +TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Regulació std +TP_FLATFIELD_AUTOSELECT;Auto selecció +TP_FLATFIELD_BLURRADIUS;Radi borrositat +TP_FLATFIELD_BLURTYPE;Tipus borrositat +TP_FLATFIELD_BT_AREA;Àrea +TP_FLATFIELD_BT_HORIZONTAL;Horitzontal +TP_FLATFIELD_BT_VERTHORIZ;Vert. + Horitz. +TP_FLATFIELD_BT_VERTICAL;Vertical +TP_FLATFIELD_LABEL;Camp pla +TP_GAMMA_CURV;gama +TP_GAMMA_FREE;Lliure gama +TP_GAMMA_OUTPUT;Sortida gama +TP_GAMMA_SLOP;Inclinació (linear) +TP_HLREC_BLEND;Barreja +TP_HLREC_CIELAB;Superposició CIELab +TP_HLREC_COLOR;Propagació de color +TP_HLREC_LABEL;Recuperació de clars +TP_HLREC_LUMINANCE;Recuperació de luminància +TP_HLREC_METHOD;Mètode: +TP_HSVEQUALIZER_CHANNEL;Canal HSV +TP_HSVEQUALIZER_HUE;H +TP_HSVEQUALIZER_LABEL;HSV Equalitzador +TP_HSVEQUALIZER_SAT;S +TP_HSVEQUALIZER_VAL;V +TP_ICM_BLENDCMSMATRIX;Barreja clars intensos del perfil de color amb la matriu +TP_ICM_BLENDCMSMATRIX_TOOLTIP;Habilita la recuperació de clars intensos quan s'usen els perfils ICC basats en LUT +TP_ICM_INPUTCAMERAICC;Perfil de color del model de càmera detectada. +TP_ICM_INPUTCAMERAICC_TOOLTIP;Usa d'entrada el perfil de color DCP o ICC específic de càmera de RawTherapee. Aquests perfils són més precisos que els de simple matriu. Disponible per a algunes càmeres. Aquests perfils són als directoris /iccprofiles/input i /dcpprofiles i es carreguen automàticament segons un nom de fitxer que coincideix exactament amb el nom de model de la càmera. +TP_ICM_INPUTCAMERA;Propi de la càmera +TP_ICM_INPUTCAMERA_TOOLTIP;Usa matriu de simple color per dcraw, versió RawTherapee ampliada (qualsevol sigui disponible segons model de càmera) o inclòs dins DNG. +TP_ICM_INPUTCUSTOM;Especial +TP_ICM_INPUTCUSTOM_TOOLTIP;Selecccionar un propi fitxer de perfil de color per a la càmera +TP_ICM_INPUTDLGLABEL;Selecc. perfil d'entrada ICC... +TP_ICM_INPUTEMBEDDED;Usar l'encastat si és possible +TP_ICM_INPUTEMBEDDED_TOOLTIP;Aplica perfil de color inclòs en fitxers no raw. +TP_ICM_INPUTNONE;Sense perfil +TP_ICM_INPUTNONE_TOOLTIP;No aplicar perfil de color d'entrada tret de casos especials. +TP_ICM_INPUTPROFILE;Perfil d'entrada +TP_ICM_LABEL;Gestió de color +TP_ICM_NOICM;No cap ICM: Sortida sRGB +TP_ICM_OUTPUTPROFILE;Perfil de sortida +TP_ICM_SAVEREFERENCE;Desa com a imatge de ref. als perfils +TP_ICM_TONECURVE;Usa la corba de to DCP. +TP_ICM_TONECURVE_TOOLTIP;Habilita l'ús de corbes de to incloses en els perfils DCP. +TP_ICM_WORKINGPROFILE;Perfil de treball +TP_IMPULSEDENOISE_LABEL;Impuls Reducció de Soroll +TP_IMPULSEDENOISE_THRESH;Llindar d'impuls RS +TP_LABCURVE_AVOIDCOLORSHIFT;Evita alteració de color +TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fica colors al gamut de l'espai de color de treball\ni aplica la correcció Munsell +TP_LABCURVE_BRIGHTNESS;Brillantor +TP_LABCURVE_CHROMATICITY;Cromaticitat +TP_LABCURVE_CONTRAST;Contrast +TP_LABCURVE_CURVEEDITOR;Corba de luminància +TP_LABCURVE_CURVEEDITOR_A_RANGE1;Verd saturat +TP_LABCURVE_CURVEEDITOR_A_RANGE2;Verd pastel +TP_LABCURVE_CURVEEDITOR_A_RANGE3;Roig pastel +TP_LABCURVE_CURVEEDITOR_A_RANGE4;Roig saturat +TP_LABCURVE_CURVEEDITOR_B_RANGE1;Blau saturat +TP_LABCURVE_CURVEEDITOR_B_RANGE2;Blau pastel +TP_LABCURVE_CURVEEDITOR_B_RANGE3;Groc pastel +TP_LABCURVE_CURVEEDITOR_B_RANGE4;Groc saturat +TP_LABCURVE_CURVEEDITOR_CC;CC +TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutral +TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Mat +TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastel +TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Saturat +TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Cromaticitat segons la cromaticitat +TP_LABCURVE_CURVEEDITOR_CH;CH +TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Cromaticitat segons el Hue +TP_LABCURVE_CURVEEDITOR_LC;LC +TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Cromaticitat segons la luminància +TP_LABCURVE_LABEL;Ajustos Lab +TP_LABCURVE_LCREDSK;LC limitat als tons vermell i pell +TP_LABCURVE_LCREDSK_TIP;Si habilitat, la corba LC (luminància segons cromaticitat) es limita als tons vermell i de pell\nSi no ho està, s'aplica a tots els tons +TP_LABCURVE_RSTPROTECTION;Protecció de tons vermells i de pell +TP_LABCURVE_RSTPRO_TOOLTIP;Es maneja amb el control de cromaticitat i la corba CC. +TP_LENSGEOM_AUTOCROP;Auto cropa +TP_LENSGEOM_FILL;Auto omple +TP_LENSGEOM_LABEL;Lent / Geometria +TP_LENSPROFILE_LABEL;Perfil de correcció de lent +TP_LENSPROFILE_USECA;Usa correcció AC +TP_LENSPROFILE_USEDIST;Correcció de distorsió +TP_LENSPROFILE_USEVIGN;Correcció de vores fosques +TP_NEUTRAL;Neutral +TP_NEUTRAL_TIP;Torna els controls d'exposició a valors neutrals +TP_PERSPECTIVE_HORIZONTAL;Horitzontal +TP_PERSPECTIVE_LABEL;Perspectiva +TP_PERSPECTIVE_VERTICAL;Vertical +TP_PREPROCESS_GREENEQUIL;Equilibri verd +TP_PREPROCESS_LABEL;Preprocessant +TP_PREPROCESS_LINEDENOISE;Filtre línia dessoroll +TP_PREPROCESS_NO_FOUND;No trobat +TP_RAWCACORR_AUTO;Auto correcció +TP_RAWCACORR_CABLUE;Blau +TP_RAWCACORR_CARED;Vermell +TP_RAWEXPOS_BLACKS;Nivells negres +TP_RAWEXPOS_LINEAR;Punt blanc: factor de correcció linear +TP_RAWEXPOS_PRESER;Punt blanc: correc. clars preservant (EV) +TP_RAWEXPOS_TWOGREEN;Dos verds junts +TP_RAW_DCBENHANCE;Aplica pas de millora DCB +TP_RAW_DCBITERATIONS;Nombre d'iteracions DCB +TP_RAW_DMETHOD;Mètode +TP_RAW_FALSECOLOR;Passos de supressió del fals color +TP_RAW_LABEL;Demosaicant +TP_RESIZE_APPLIESTO;S'aplica a: +TP_RESIZE_CROPPEDAREA;Àrea cropada +TP_RESIZE_FITBOX;Capsa d'inclusió +TP_RESIZE_FULLIMAGE;Imatge sencera +TP_RESIZE_HEIGHT;Alt +TP_RESIZE_H;A: +TP_RESIZE_LABEL;Canviar tamany +TP_RESIZE_LANCZOS;Lanczos +TP_RESIZE_METHOD;Mètode: +TP_RESIZE_NEAREST;Més proper +TP_RESIZE_SCALE;Escala +TP_RESIZE_SPECIFY;Especifica: +TP_RESIZE_WIDTH;Ample +TP_RESIZE_W;L: +TP_RGBCURVES_BLUE;B +TP_RGBCURVES_CHANNEL;Canal +TP_RGBCURVES_GREEN;V +TP_RGBCURVES_LABEL;Corbes RGB +TP_RGBCURVES_RED;R +TP_ROTATE_DEGREE;Graus +TP_ROTATE_LABEL;Rota +TP_ROTATE_SELECTLINE;Selecc. línia recta +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Clars intensos +TP_SHADOWSHLIGHTS_HLTONALW;Amplada de to per Clars I. +TP_SHADOWSHLIGHTS_LABEL;Foscos/Clars intensos +TP_SHADOWSHLIGHTS_LOCALCONTR;Contrast local +TP_SHADOWSHLIGHTS_RADIUS;Radi +TP_SHADOWSHLIGHTS_SHADOWS;Foscos +TP_SHADOWSHLIGHTS_SHTONALW;Amplada de to per Foscos +TP_SHARPENEDGE_AMOUNT;Quantitat +TP_SHARPENEDGE_LABEL;Vores +TP_SHARPENEDGE_PASSES;Iteracions +TP_SHARPENEDGE_THREE;Només luminància +TP_SHARPENING_AMOUNT;Quantitat +TP_SHARPENING_EDRADIUS;Radi +TP_SHARPENING_EDTOLERANCE;Tolerància vores +TP_SHARPENING_HALOCONTROL;Control de halo +TP_SHARPENING_HCAMOUNT;Quantitat +TP_SHARPENING_LABEL;Enfocant +TP_SHARPENING_METHOD;Mètode +TP_SHARPENING_ONLYEDGES;Enfocar només vores +TP_SHARPENING_RADIUS;Radi +TP_SHARPENING_RLD;RL Deconvolució +TP_SHARPENING_RLD_AMOUNT;Quantitat +TP_SHARPENING_RLD_DAMPING;Ablaniment +TP_SHARPENING_RLD_ITERATIONS;Iteracions +TP_SHARPENING_THRESHOLD;Llindar +TP_SHARPENING_USM;Màscara d'enfocament +TP_SHARPENMICRO_AMOUNT;Quantitat +TP_SHARPENMICRO_LABEL;Microcontrast +TP_SHARPENMICRO_MATRIX;matriu 3×3 en lloc de 5×5 +TP_SHARPENMICRO_UNIFORMITY;Uniformitat +TP_VIBRANCE_AVOIDCOLORSHIFT;Evita alteració de color +TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH +TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Tons de pell +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Vermell/porpra +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Vermell +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Vermell/groc +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Groc +TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Hue segons el Hue +TP_VIBRANCE_LABEL;Vibrància +TP_VIBRANCE_PASTELS;Tons pastel +TP_VIBRANCE_PASTSATTOG;Enllaç de tons pastel i saturats +TP_VIBRANCE_PROTECTSKINS;Protecció dels tons de pell +TP_VIBRANCE_PSTHRESHOLD;Llindar tons pastel/saturats +TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Llindar de saturació +TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;L'eix vertical representa tons pastel a baix i tons saturats a dalt. L'horitzontal representa el grau de saturació. +TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Regulant la transició pastel/saturat +TP_VIBRANCE_SATURATED;Tons saturats +TP_VIGNETTING_AMOUNT;Quantitat +TP_VIGNETTING_CENTER;Centre +TP_VIGNETTING_CENTER_X;Centre X +TP_VIGNETTING_CENTER_Y;Centre Y +TP_VIGNETTING_LABEL;Correcció vorafosc +TP_VIGNETTING_RADIUS;Radi +TP_VIGNETTING_STRENGTH;Força +TP_WBALANCE_AUTO;Auto +TP_WBALANCE_CAMERA;Càmera +TP_WBALANCE_CLOUDY;Núvols +TP_WBALANCE_CUSTOM;Especial +TP_WBALANCE_DAYLIGHT;Llum de dia (sol) +TP_WBALANCE_FLASH55;Leica +TP_WBALANCE_FLASH60;Standard, Canon, Pentax, Olympus +TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta +TP_WBALANCE_FLASH_HEADER;Flash +TP_WBALANCE_FLUO1;F1 - Llum de dia +TP_WBALANCE_FLUO2;F2 - Blanc fred +TP_WBALANCE_FLUO3;F3 - Blanc +TP_WBALANCE_FLUO4;F4 - Blanc càl·lid +TP_WBALANCE_FLUO5;F5 - Llum de dia +TP_WBALANCE_FLUO6;F6 - Blanc menor +TP_WBALANCE_FLUO7;F7 - D65 simulador llum de dia +TP_WBALANCE_FLUO8;F8 - D50 / Sylvania F40 Design +TP_WBALANCE_FLUO9;F9 - Blanc fred de luxe +TP_WBALANCE_FLUO10;F10 - Philips TL85 +TP_WBALANCE_FLUO11;F11 - Philips TL84 +TP_WBALANCE_FLUO12;F12 - Philips TL83 +TP_WBALANCE_FLUO_HEADER;Fluorescent +TP_WBALANCE_GREEN;Tint +TP_WBALANCE_GTI;GTI +TP_WBALANCE_HMI;HMI +TP_WBALANCE_JUDGEIII;JudgeIII +TP_WBALANCE_LABEL;Balanç de blancs +TP_WBALANCE_LAMP_HEADER;Làmpara +TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 +TP_WBALANCE_LED_HEADER;LED +TP_WBALANCE_LED_LSI;LSI Lumelex 2040 +TP_WBALANCE_METHOD;Mètode +TP_WBALANCE_SHADE;Ombra +TP_WBALANCE_SIZE;Tamany: +TP_WBALANCE_SOLUX35;Solux 3500K +TP_WBALANCE_SOLUX41;Solux 4100K +TP_WBALANCE_SOLUX47;Solux 4700K (vendor) +TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) +TP_WBALANCE_SPOTWB;Punt b. blancs +TP_WBALANCE_TEMPERATURE;Temperatura +TP_WBALANCE_TUNGSTEN;Tungstèn +ZOOMPANEL_100;(100%) +ZOOMPANEL_NEWCROPWINDOW;Obre una altra finestra de detall +ZOOMPANEL_ZOOM100;Zoom 100%\nDrecera: z +ZOOMPANEL_ZOOMFITSCREEN;Ajusta a la finestra\nDrecera: f +ZOOMPANEL_ZOOMIN;Apropa\nDrecera: + +ZOOMPANEL_ZOOMOUT;Allunya\nDrecera: - + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!BATCHQUEUE_DESTFILENAME;Path and file name +!CURVEEDITOR_AXIS_IN;I: +!CURVEEDITOR_AXIS_LEFT_TAN;LT: +!CURVEEDITOR_AXIS_OUT;O: +!CURVEEDITOR_AXIS_RIGHT_TAN;RT: +!CURVEEDITOR_EDITPOINT_HINT;Enable edition of node in/out values.\n\nRight-click on a node to select it.\nRight-click on empty space to de-select the node. +!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. +!EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels +!EXPORT_BYPASS_RAW_LMMSE_ITERATIONS;Bypass [raw] LMMSE Enhancement Steps +!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_POPUPCOLORLABEL0;Label: None +!FILEBROWSER_POPUPCOLORLABEL1;Label: Red +!FILEBROWSER_POPUPCOLORLABEL2;Label: Yellow +!FILEBROWSER_POPUPCOLORLABEL3;Label: Green +!FILEBROWSER_POPUPCOLORLABEL4;Label: Blue +!FILEBROWSER_POPUPCOLORLABEL5;Label: Purple +!FILEBROWSER_POPUPRANK0;Unrank +!FILEBROWSER_POPUPRANK1;Rank 1 * +!FILEBROWSER_POPUPRANK2;Rank 2 ** +!FILEBROWSER_POPUPRANK3;Rank 3 *** +!FILEBROWSER_POPUPRANK4;Rank 4 **** +!FILEBROWSER_POPUPRANK5;Rank 5 ***** +!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_SHOWNOTTRASHHINT;Show only non-deleted images. +!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_ASIMAGE;As Image +!GENERAL_AUTO;Automatic +!GENERAL_CLOSE;Close +!HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram. +!HISTORY_MSG_174;CIECAM02 +!HISTORY_MSG_175;CAM02 - CAT02 adaptation +!HISTORY_MSG_176;CAM02 - Viewing surround +!HISTORY_MSG_177;CAM02 - Scene luminosity +!HISTORY_MSG_178;CAM02 - Viewing luminosity +!HISTORY_MSG_179;CAM02 - White-point model +!HISTORY_MSG_180;CAM02 - Lightness (J) +!HISTORY_MSG_181;CAM02 - Chroma (C) +!HISTORY_MSG_182;CAM02 - Automatic CAT02 +!HISTORY_MSG_183;CAM02 - Contrast (J) +!HISTORY_MSG_184;CAM02 - Scene surround +!HISTORY_MSG_185;CAM02 - Gamut control +!HISTORY_MSG_186;CAM02 - Algorithm +!HISTORY_MSG_187;CAM02 - Red/skin prot. +!HISTORY_MSG_188;CAM02 - Brightness (Q) +!HISTORY_MSG_189;CAM02 - Contrast (Q) +!HISTORY_MSG_190;CAM02 - Saturation (S) +!HISTORY_MSG_191;CAM02 - Colorfulness (M) +!HISTORY_MSG_192;CAM02 - Hue (h) +!HISTORY_MSG_193;CAM02 - Tone curve 1 +!HISTORY_MSG_194;CAM02 - Tone curve 2 +!HISTORY_MSG_195;CAM02 - Tone curve 1 +!HISTORY_MSG_196;CAM02 - Tone curve 2 +!HISTORY_MSG_197;CAM02 - Color curve +!HISTORY_MSG_198;CAM02 - Color curve +!HISTORY_MSG_199;CAM02 - Output histograms +!HISTORY_MSG_200;CAM02 - Tone mapping +!HISTORY_MSG_201;NR - Chrominance - R&G +!HISTORY_MSG_202;NR - Chrominance - B&Y +!HISTORY_MSG_203;NR - Method +!HISTORY_MSG_204;LMMSE enhancement steps +!HISTORY_MSG_205;CAM02 - Hot/bad pixel filter +!HISTORY_MSG_206;CAT02 - Auto scene luminosity +!HISTORY_MSG_207;Defringe - Hue curve +!HISTORY_MSG_208;WB - B/R equalizer +!HISTORY_MSG_210;GF - Angle +!HISTORY_MSG_211;Graduated Filter +!HISTORY_MSG_212;VF - Strength +!HISTORY_MSG_213;Vignette Filter +!HISTORY_MSG_214;Black-and-White +!HISTORY_MSG_215;B&W - CM - Red +!HISTORY_MSG_216;B&W - CM - Green +!HISTORY_MSG_217;B&W - CM - Blue +!HISTORY_MSG_218;B&W - Gamma - Red +!HISTORY_MSG_219;B&W - Gamma - Green +!HISTORY_MSG_220;B&W - Gamma - Blue +!HISTORY_MSG_221;B&W - Color filter +!HISTORY_MSG_222;B&W - Presets +!HISTORY_MSG_223;B&W - CM - Orange +!HISTORY_MSG_224;B&W - CM - Yellow +!HISTORY_MSG_225;B&W - CM - Cyan +!HISTORY_MSG_226;B&W - CM - Magenta +!HISTORY_MSG_227;B&W - CM - Purple +!HISTORY_MSG_228;B&W - Luminance equalizer +!HISTORY_MSG_229;B&W - Luminance equalizer +!HISTORY_MSG_230;B&W - Mode +!HISTORY_MSG_231;B&W - 'Before' curve +!HISTORY_MSG_232;B&W - 'Before' curve type +!HISTORY_MSG_233;B&W - 'After' curve +!HISTORY_MSG_234;B&W - 'After' curve type +!HISTORY_MSG_235;B&W - Auto channel mixer +!HISTORY_MSG_236;--unused-- +!HISTORY_MSG_237;B&W - Mixer +!HISTORY_MSG_238;GF - Feather +!HISTORY_MSG_239;GF - Strength +!HISTORY_MSG_240;GF - Center +!HISTORY_MSG_241;VF - Feather +!HISTORY_MSG_242;VF - Roundness +!HISTORY_MSG_243;VC - Radius +!HISTORY_MSG_244;VC - Strength +!HISTORY_MSG_245;VC - Center +!HISTORY_MSG_246;L*a*b* - CL curve +!HISTORY_MSG_247;L*a*b* - LH curve +!HISTORY_MSG_248;L*a*b* - HH curve +!HISTORY_MSG_249;CbDL - Threshold +!HISTORY_MSG_250;NR - Enhanced +!HISTORY_MSG_251;B&W - Algorithm +!HISTORY_MSG_252;CbDL - Skin tar/prot +!HISTORY_MSG_253;CbDL - Reduce artifacts +!HISTORY_MSG_254;CbDL - Skin hue +!HISTORY_MSG_255;NR - Median filter +!HISTORY_MSG_256;NR - Median type +!HISTORY_MSG_257;Color Toning +!HISTORY_MSG_258;CT - Color curve +!HISTORY_MSG_259;CT - Opacity curve +!HISTORY_MSG_260;CT - a*[b*] opacity +!HISTORY_MSG_261;CT - Method +!HISTORY_MSG_262;CT - b* opacity +!HISTORY_MSG_263;CT - Shadows - Red +!HISTORY_MSG_264;CT - Shadows - Green +!HISTORY_MSG_265;CT - Shadows - Blue +!HISTORY_MSG_266;CT - Mid - Red +!HISTORY_MSG_267;CT - Mid - Green +!HISTORY_MSG_268;CT - Mid - Blue +!HISTORY_MSG_269;CT - High - Red +!HISTORY_MSG_270;CT - High - Green +!HISTORY_MSG_271;CT - High - Blue +!HISTORY_MSG_272;CT - Balance +!HISTORY_MSG_273;CT - Reset +!HISTORY_MSG_274;CT - Sat. Shadows +!HISTORY_MSG_275;CT - Sat. Highlights +!HISTORY_MSG_276;CT - Opacity +!HISTORY_MSG_277;--unused-- +!HISTORY_MSG_278;CT - Preserve luminance +!HISTORY_MSG_279;CT - Shadows +!HISTORY_MSG_280;CT - Highlights +!HISTORY_MSG_281;CT - Sat. strength +!HISTORY_MSG_282;CT - Sat. threshold +!HISTORY_MSG_283;CT - Strength +!HISTORY_MSG_284;CT - Auto sat. protection +!HISTORY_MSG_285;NR - Median - Method +!HISTORY_MSG_286;NR - Median - Type +!HISTORY_MSG_287;NR - Median - Iterations +!HISTORY_MSG_288;Flat Field - Clip control +!HISTORY_MSG_289;Flat Field - Clip control - Auto +!HISTORY_MSG_290;Black Level - Red +!HISTORY_MSG_291;Black Level - Green +!HISTORY_MSG_292;Black Level - Blue +!HISTORY_MSG_293;Film Simulation +!HISTORY_MSG_294;Film Simulation - Strength +!HISTORY_MSG_295;Film Simulation - Film +!HISTORY_MSG_296;NR - Luminance curve +!HISTORY_MSG_297;NR - Quality +!HISTORY_MSG_298;Dead pixel filter +!HISTORY_MSG_299;NR - Chrominance curve +!HISTORY_MSG_300;- +!HISTORY_MSG_301;NR - Luma control +!HISTORY_MSG_302;NR - Chroma method +!HISTORY_MSG_303;NR - Chroma method +!HISTORY_MSG_304;W - Contrast levels +!HISTORY_MSG_305;Wavelet Levels +!HISTORY_MSG_306;W - Preview +!HISTORY_MSG_307;W - Preview +!HISTORY_MSG_308;W - Preview direction +!HISTORY_MSG_309;W - ES - Detail +!HISTORY_MSG_310;W - Residual - Sky tar/prot +!HISTORY_MSG_311;W - Wavelet levels +!HISTORY_MSG_312;W - Residual - Shadows threshold +!HISTORY_MSG_313;W - Chroma - Sat/past +!HISTORY_MSG_314;W - Gamut - Reduce artifacts +!HISTORY_MSG_315;W - Residual - Contrast +!HISTORY_MSG_316;W - Gamut - Skin tar/prot +!HISTORY_MSG_317;W - Gamut - Skin hue +!HISTORY_MSG_318;W - Contrast - Highlight levels +!HISTORY_MSG_319;W - Contrast - Highlight range +!HISTORY_MSG_320;W - Contrast - Shadow range +!HISTORY_MSG_321;W - Contrast - Shadow levels +!HISTORY_MSG_322;W - Gamut - Avoid color shift +!HISTORY_MSG_323;W - ES - Local contrast +!HISTORY_MSG_324;W - Chroma - Pastel +!HISTORY_MSG_325;W - Chroma - Saturated +!HISTORY_MSG_326;W - Chroma - Method +!HISTORY_MSG_327;W - Contrast - Apply to +!HISTORY_MSG_328;W - Chroma - Link strength +!HISTORY_MSG_329;W - Toning - Opacity RG +!HISTORY_MSG_330;W - Toning - Opacity BY +!HISTORY_MSG_331;W - Contrast levels - Extra +!HISTORY_MSG_332;W - Tiling method +!HISTORY_MSG_333;W - Residual - Shadows +!HISTORY_MSG_334;W - Residual - Chroma +!HISTORY_MSG_335;W - Residual - Highlights +!HISTORY_MSG_336;W - Residual - Highlights threshold +!HISTORY_MSG_337;W - Residual - Sky hue +!HISTORY_MSG_338;W - ES - Radius +!HISTORY_MSG_339;W - ES - Strength +!HISTORY_MSG_340;W - Strength +!HISTORY_MSG_341;W - Edge performance +!HISTORY_MSG_342;W - ES - First level +!HISTORY_MSG_343;W - Chroma levels +!HISTORY_MSG_344;W - Meth chroma sl/cur +!HISTORY_MSG_345;W - ES - Local contrast +!HISTORY_MSG_346;W - ES - Local contrast method +!HISTORY_MSG_347;W - Denoise - Level 0 +!HISTORY_MSG_348;W - Denoise - Level 1 +!HISTORY_MSG_349;W - Denoise - Level 2 +!HISTORY_MSG_350;W - ES - Edge detection +!HISTORY_MSG_351;W - Residual - HH curve +!HISTORY_MSG_352;W - Background +!HISTORY_MSG_353;W - ES - Gradient sensitivity +!HISTORY_MSG_354;W - ES - Enhance +!HISTORY_MSG_355;W - ES - Threshold low +!HISTORY_MSG_356;W - ES - Threshold high +!HISTORY_MSG_357;W - Denoise - Link with ES +!HISTORY_MSG_358;W - Gamut - CH +!HISTORY_MSG_359;Hot/Dead - Threshold +!HISTORY_MSG_360;TM Gamma +!HISTORY_MSG_361;W - Final - Chroma balance +!HISTORY_MSG_362;W - Residual - Compression method +!HISTORY_MSG_363;W - Residual - Compression strength +!HISTORY_MSG_364;W - Final - Contrast balance +!HISTORY_MSG_365;W - Final - Delta balance +!HISTORY_MSG_366;W - Residual - Compression gamma +!HISTORY_MSG_367;W - ES - Local contrast curve +!HISTORY_MSG_368;W - Final - Contrast balance +!HISTORY_MSG_369;W - Final - Balance method +!HISTORY_MSG_370;W - Final - Local contrast curve +!HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s +!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). +!MAIN_MSG_OPERATIONCANCELLED;Operation cancelled +!MAIN_MSG_PATHDOESNTEXIST;The path\n\n%1\n\ndoes not exist. Please set a correct path in Preferences. +!MAIN_MSG_SETPATHFIRST;You first have to set a target path in Preferences in order to use this function! +!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_INSPECT; Inspect +!MAIN_TAB_WAVELET;Wavelet +!MAIN_TAB_WAVELET_TOOLTIP;Shortcut: Alt-w +!NAVIGATOR_B;B: +!NAVIGATOR_G;G: +!NAVIGATOR_H;H: +!NAVIGATOR_LAB_A;a*: +!NAVIGATOR_LAB_B;b*: +!NAVIGATOR_LAB_L;L*: +!NAVIGATOR_NA; -- +!NAVIGATOR_R;R: +!NAVIGATOR_S;S: +!NAVIGATOR_V;V: +!PARTIALPASTE_CHANNELMIXERBW;Black-and-White +!PARTIALPASTE_COLORAPP;CIECAM02 +!PARTIALPASTE_COLORTONING;Color Toning +!PARTIALPASTE_EQUALIZER;Wavelet Equalizer +!PARTIALPASTE_FILMSIMULATION;Film Simulation +!PARTIALPASTE_FLATFIELDCLIPCONTROL;Flat-field clip control +!PARTIALPASTE_GRADIENT;Graduated filter +!PARTIALPASTE_PCVIGNETTE;Vignette filter +!PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter +!PARTIALPASTE_PREPROCESS_HOTPIXFILT;Hot pixel filter +!PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!PARTIALPASTE_WAVELETGROUP;Wavelet processing +!PREFERENCES_AUTLISLOW;Low +!PREFERENCES_AUTLISMAX;Max - Average of all tiles +!PREFERENCES_AUTLISSTD;High +!PREFERENCES_AUTLISVLOW;None +!PREFERENCES_AUTLOW;Low +!PREFERENCES_AUTSTD;Standard +!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_BEHADDALL;All to 'Add' +!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_BEHSETALL;All to 'Set' +!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_CURVEBBOXPOS;Position of curve copypasta buttons +!PREFERENCES_CURVEBBOXPOS_ABOVE;Above +!PREFERENCES_CURVEBBOXPOS_BELOW;Below +!PREFERENCES_CURVEBBOXPOS_LEFT;Left +!PREFERENCES_CURVEBBOXPOS_RIGHT;Right +!PREFERENCES_CUSTPROFBUILDKEYFORMAT;Keys format +!PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME;Name +!PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;TagID +!PREFERENCES_D50;5000K +!PREFERENCES_D55;5500K +!PREFERENCES_D60;6000K +!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_EXPAUT;Expert +!PREFERENCES_FILMSIMULATION;Film Simulation +!PREFERENCES_FLUOF2;Fluorescent F2 +!PREFERENCES_FLUOF7;Fluorescent F7 +!PREFERENCES_FLUOF11;Fluorescent F11 +!PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT;Same thumbnail height between the Editor's panel 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_GREY05;Yb=05 CIE L#30 +!PREFERENCES_GREY10;Yb=10 CIE L#40 +!PREFERENCES_GREY15;Yb=15 CIE L#45 +!PREFERENCES_GREY18;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_GREYSC18;Yb=18 CIE L#50 +!PREFERENCES_GREYSCA;Automatic +!PREFERENCES_GREYSC;Scene Yb luminance (%) +!PREFERENCES_GREY;Output device's Yb luminance (%) +!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_LEVAUTDN;Denoising level +!PREFERENCES_LEVDN;Cell size +!PREFERENCES_LISS;Auto multi-zone smoothing +!PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders +!PREFERENCES_MAX;Maxi (Tile) +!PREFERENCES_MED;Medium (Tile/2) +!PREFERENCES_MIN;Mini (100x115) +!PREFERENCES_NAVGUIDEBRUSH;Navigator guide color +!PREFERENCES_NAVIGATIONFRAME;Navigation +!PREFERENCES_NOISE;Noise Reduction +!PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Overlay filenames on thumbnails in the editor pannel +!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_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_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_SHOWFILMSTRIPTOOLBAR;Show filmstrip toolbar +!PREFERENCES_SIMPLAUT;Tool mode +!PREFERENCES_SMA;Small (250x287) +!PREFERENCES_STDAUT;Standard +!PREFERENCES_TAB_PERFORMANCE;Performance & Quality +!PREFERENCES_TIMAX;High +!PREFERENCES_TINB;Number of tiles +!PREFERENCES_TISTD;Standard +!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 +!PROFILEPANEL_GLOBALPROFILES;Bundled profiles +!PROFILEPANEL_MODE_TIP;Processing profile fill mode.\n\nButton pressed: partial profiles will be converted to full profiles; the missing values will be replaced with hard-coded defaults.\n\nButton released: profiles will be applied as they are, altering only those values which they contain. +!PROFILEPANEL_MYPROFILES;My profiles +!PROFILEPANEL_PINTERNAL;Neutral +!PROGRESSBAR_NOIMAGES;No images found +!PROGRESSBAR_SNAPSHOT_ADDED;Snapshot added +!SAVEDLG_FORCEFORMATOPTS;Force saving options +!TP_BWMIX_ALGO;Algorithm OYCPM +!TP_BWMIX_ALGO_LI;Linear +!TP_BWMIX_ALGO_SP;Special effects +!TP_BWMIX_ALGO_TOOLTIP;Linear: will produce a normal linear response.\nSpecial effects: will produce special effects by mixing channels non-linearly. +!TP_BWMIX_AUTOCH;Auto +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing Channel Mixer. +!TP_BWMIX_CC_ENABLED;Adjust complementary color +!TP_BWMIX_CC_TOOLTIP;Enable to allow automatic adjustment of complementary colors in ROYGCBPM mode. +!TP_BWMIX_CHANNEL;Luminance equalizer +!TP_BWMIX_CURVEEDITOR1;'Before' curve +!TP_BWMIX_CURVEEDITOR2;'After' curve +!TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Tone curve, after B&W conversion, at the end of treatment. +!TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Tone curve, just before B&W conversion.\nMay take into account the color components. +!TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H).\nPay attention to extreme values as they may cause artifacts. +!TP_BWMIX_FILTER;Color Filter +!TP_BWMIX_FILTER_BLUEGREEN;Blue-Green +!TP_BWMIX_FILTER_BLUE;Blue +!TP_BWMIX_FILTER_GREENYELLOW;Green-Yellow +!TP_BWMIX_FILTER_GREEN;Green +!TP_BWMIX_FILTER_NONE;None +!TP_BWMIX_FILTER_PURPLE;Purple +!TP_BWMIX_FILTER_REDYELLOW;Red-Yellow +!TP_BWMIX_FILTER_RED;Red +!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. +!TP_BWMIX_FILTER_YELLOW;Yellow +!TP_BWMIX_GAMMA;Gamma Correction +!TP_BWMIX_GAM_TOOLTIP;Correct gamma for each RGB channel. +!TP_BWMIX_LABEL;Black-and-White +!TP_BWMIX_MET;Method +!TP_BWMIX_MET_CHANMIX;Channel Mixer +!TP_BWMIX_MET_DESAT;Desaturation +!TP_BWMIX_MET_LUMEQUAL;Luminance Equalizer +!TP_BWMIX_MIXC;Mixer +!TP_BWMIX_NEUTRAL;Reset mixer +!TP_BWMIX_NEUTRAL_TIP;Reset all values (Color Filter, Channel Mixer) to default. +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all the mixer options.\n"Total" displays the sum of the RGB values:\n- always 100% in relative mode\n- higher (lighter) or lower (darker) than 100% in absolute mode. +!TP_BWMIX_RGB_TOOLTIP;Mix the RGB channels. Use presets for guidance.\nPay attention to negative values that may cause artifacts or erratic behavior. +!TP_BWMIX_SETTING;Presets +!TP_BWMIX_SETTING_TOOLTIP;Different presets (film, landscape, etc.) or manual Channel Mixer settings. +!TP_BWMIX_SET_HIGHCONTAST;High contrast +!TP_BWMIX_SET_HIGHSENSIT;High Sensitivity +!TP_BWMIX_SET_HYPERPANCHRO;Hyper Panchromatic +!TP_BWMIX_SET_INFRARED;Infrared +!TP_BWMIX_SET_LANDSCAPE;Landscape +!TP_BWMIX_SET_LOWSENSIT;Low Sensitivity +!TP_BWMIX_SET_LUMINANCE;Luminance +!TP_BWMIX_SET_NORMCONTAST;Normal Contrast +!TP_BWMIX_SET_ORTHOCHRO;Orthochromatic +!TP_BWMIX_SET_PANCHRO;Panchromatic +!TP_BWMIX_SET_PORTRAIT;Portrait +!TP_BWMIX_SET_RGBABS;Absolute RGB +!TP_BWMIX_SET_RGBREL;Relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Relative ROYGCBPM +!TP_BWMIX_TCMODE_FILMLIKE;B&W Film-like +!TP_BWMIX_TCMODE_SATANDVALBLENDING;B&W Saturation and Value Blending +!TP_BWMIX_TCMODE_STANDARD;B&W Standard +!TP_BWMIX_TCMODE_WEIGHTEDSTD;B&W Weighted Standard +!TP_BWMIX_VAL;L +!TP_COLORAPP_ADAPTSCENE;Scene luminosity +!TP_COLORAPP_ADAPTSCENE_TOOLTIP;Absolute luminance of the scene environement (cd/m²).\n1) Calculated from the Exif data:\nShutter speed - ISO speed - F number - camera exposure correction.\n2) Calculated from the raw white point and RT's Exposure Compensation slider. +!TP_COLORAPP_ADAPTVIEWING;Viewing luminosity (cd/m²) +!TP_COLORAPP_ADAPTVIEWING_TOOLTIP;Absolute luminance of the viewing environnement\n(usually 16cd/m²). +!TP_COLORAPP_ADAP_AUTO_TOOLTIP;If the checkbox is checked (recommended) RawTherapee calculates an optimum value from Exif data.\nTo set the value manually, uncheck the checkbox first. +!TP_COLORAPP_ALGO;Algorithm +!TP_COLORAPP_ALGO_ALL;All +!TP_COLORAPP_ALGO_JC;Lightness + Chroma (JC) +!TP_COLORAPP_ALGO_JS;Lightness + Saturation (JS) +!TP_COLORAPP_ALGO_QM;Brightness + Colorfulness (QM) +!TP_COLORAPP_ALGO_TOOLTIP;Lets you choose between parameter subsets or all parameters. +!TP_COLORAPP_BADPIXSL;Hot/bad pixel filter +!TP_COLORAPP_BADPIXSL_TOOLTIP;Suppression of hot/bad (brightly colored) pixels.\n0 = No effect\n1 = Median\n2 = Gaussian.\nAlternatively, adjust the image to avoid very dark shadows.\n\nThese artifacts are due to limitations of CIECAM02. +!TP_COLORAPP_BRIGHT;Brightness (Q) +!TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from L*a*b* and RGB brightness. +!TP_COLORAPP_CHROMA;Chroma (C) +!TP_COLORAPP_CHROMA_M;Colorfulnes (M) +!TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM02 differs from L*a*b* and RGB colorfulness. +!TP_COLORAPP_CHROMA_S;Saturation (S) +!TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from L*a*b* and RGB saturation. +!TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from L*a*b* and RGB chroma. +!TP_COLORAPP_CIECAT_DEGREE;CAT02 adaptation +!TP_COLORAPP_CONTRAST;Contrast (J) +!TP_COLORAPP_CONTRAST_Q;Contrast (Q) +!TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrast in CIECAM02 for the Q slider; it differs from L*a*b* and RGB contrast. +!TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from L*a*b* and RGB contrast. +!TP_COLORAPP_CURVEEDITOR1;Tone curve 1 +!TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L* (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of J or Q after CIECAM02.\n\nJ and Q are not shown in the main histogram panel.\n\nFor final output refer to the main histogram panel. +!TP_COLORAPP_CURVEEDITOR2;Tone curve 2 +!TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Same usage as with the second exposure tone curve. +!TP_COLORAPP_CURVEEDITOR3;Color curve +!TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Adjust either chroma, saturation or colorfulness.\n\nShows the histogram of chromaticity (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of C, s or M after CIECAM02.\n\nC, s and M are not shown in the main histogram panel.\nFor final output refer to the main histogram panel. +!TP_COLORAPP_DATACIE;CIECAM02 output histograms in curves +!TP_COLORAPP_DATACIE_TOOLTIP;When enabled, histograms in CIECAM02 curves show approximate values/ranges for J or Q, and C, s or M after the CIECAM02 adjustments.\nThis selection does not impact the main histogram panel.\n\nWhen disabled, histograms in CIECAM02 curves show L*a*b* values before CIECAM02 adjustments. +!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RawTherapee calculates an optimum value, which is then used by CAT02, and also for the entire CIECAM02.\nTo set the value manually, uncheck the check-box first (values above 65 are recommended). +!TP_COLORAPP_DEGREE_TOOLTIP;Amount of CIE Chromatic Adaptation Transform 2002. +!TP_COLORAPP_GAMUT;Gamut control (L*a*b*) +!TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in L*a*b* mode. +!TP_COLORAPP_HUE;Hue (h) +!TP_COLORAPP_HUE_TOOLTIP;Hue (h) - angle between 0° and 360°. +!TP_COLORAPP_LABEL;CIE Color Appearance Model 2002 +!TP_COLORAPP_LABEL_CAM02;Image Adjustments +!TP_COLORAPP_LABEL_SCENE;Scene Conditions +!TP_COLORAPP_LABEL_VIEWING;Viewing Conditions +!TP_COLORAPP_LIGHT;Lightness (J) +!TP_COLORAPP_LIGHT_TOOLTIP;Lightness in CIECAM02 differs from L*a*b* and RGB lightness. +!TP_COLORAPP_MODEL;WP Model +!TP_COLORAPP_MODEL_TOOLTIP;White-Point Model.\n\nWB [RT] + [output]: RT's white balance is used for the scene, CIECAM02 is set to D50, and the output device's white balance is set in Preferences > Color Management.\n\nWB [RT+CAT02] + [output]: RT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences - Color Management. +!TP_COLORAPP_RSTPRO;Red & skin-tones protection +!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin-tones protection affects both sliders and curves. +!TP_COLORAPP_SHARPCIE;--unused-- +!TP_COLORAPP_SHARPCIE_TOOLTIP;--unused-- +!TP_COLORAPP_SURROUND;Surround +!TP_COLORAPP_SURROUND_AVER;Average +!TP_COLORAPP_SURROUND_DARK;Dark +!TP_COLORAPP_SURROUND_DIM;Dim +!TP_COLORAPP_SURROUND_EXDARK;Extremly Dark (Cutsheet) +!TP_COLORAPP_SURROUND_TOOLTIP;Changes tones and colors to take into account the viewing conditions of the output device.\n\nAverage: Average light environment (standard). The image will not change.\n\nDim: Dim environment (TV). The image will become slighty dark.\n\nDark: Dark environment (projector). The image will become more dark.\n\nExtremly Dark: Extremly dark environment (cutsheet). The image will become very dark. +!TP_COLORAPP_SURSOURCE;Dark surround +!TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if image has a dark border. +!TP_COLORAPP_TCMODE_BRIGHTNESS;Brightness +!TP_COLORAPP_TCMODE_CHROMA;Chroma +!TP_COLORAPP_TCMODE_COLORF;Colorfulness +!TP_COLORAPP_TCMODE_LABEL1;Curve mode 1 +!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_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] +!TP_COLORAPP_WBRT;WB [RT] + [output] +!TP_COLORTONING_AB;o C/L +!TP_COLORTONING_AUTOSAT;Automatic +!TP_COLORTONING_BALANCE;Balance +!TP_COLORTONING_BY;o C/L +!TP_COLORTONING_CHROMAC;Opacity +!TP_COLORTONING_COLOR;Color +!TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;Chroma opacity as a function of luminance oC=f(L) +!TP_COLORTONING_HIGHLIGHT;Highlights +!TP_COLORTONING_HUE;Hue +!TP_COLORTONING_LABEL;Color Toning +!TP_COLORTONING_LAB;L*a*b* blending +!TP_COLORTONING_LUMAMODE;Preserve luminance +!TP_COLORTONING_LUMAMODE_TOOLTIP;If enabled, when you change color (red, green, cyan, blue, etc.) the luminance of each pixel is preserved. +!TP_COLORTONING_LUMA;Luminance +!TP_COLORTONING_METHOD;Method +!TP_COLORTONING_METHOD_TOOLTIP;"L*a*b* blending", "RGB sliders" and "RGB curves" use interpolated color blending.\n"Color balance (Shadows/Midtones/Highlights)" and "Saturation 2 colors" use direct colors.\n\nThe Black-and-White tool can be enabled when using any color toning method, which allows for color toning. +!TP_COLORTONING_MIDTONES;Midtones +!TP_COLORTONING_NEUTRAL;Reset sliders +!TP_COLORTONING_NEUTRAL_TIP;Reset all values (Shadows, Midtones, Highlights) to default. +!TP_COLORTONING_OPACITY;Opacity +!TP_COLORTONING_RGBCURVES;RGB - Curves +!TP_COLORTONING_RGBSLIDERS;RGB - Sliders +!TP_COLORTONING_SATURATEDOPACITY;Strength +!TP_COLORTONING_SATURATIONTHRESHOLD;Threshold +!TP_COLORTONING_SA;Saturation Protection +!TP_COLORTONING_SHADOWS;Shadows +!TP_COLORTONING_SPLITCOCO;Color Balance Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITCO;Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITLR;Saturation 2 colors +!TP_COLORTONING_STRENGTH;Strength +!TP_COLORTONING_STR;Strength +!TP_COLORTONING_TWO2;Special chroma '2 colors' +!TP_COLORTONING_TWOALL;Special chroma +!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_GTHARMMEANS;Harmonic Means +!TP_CROP_GTTRIANGLE1;Golden Triangles 1 +!TP_CROP_GTTRIANGLE2;Golden Triangles 2 +!TP_DIRPYRDENOISE_33;3×3 strong +!TP_DIRPYRDENOISE_55SOFT;5×5 +!TP_DIRPYRDENOISE_55;5×5 strong +!TP_DIRPYRDENOISE_77;7×7 (slow) +!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_ABM;Chroma only +!TP_DIRPYRDENOISE_AUTO;Automatic global +!TP_DIRPYRDENOISE_AUTO_TOOLTIP;Try to evaluate chroma noise\nBe careful, this calculation is average, and is quite subjective ! +!TP_DIRPYRDENOISE_AUT;Automatic global +!TP_DIRPYRDENOISE_BLUE;Chrominance - Blue-Yellow +!TP_DIRPYRDENOISE_C2TYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CCCURVE;Chrominance curve +!TP_DIRPYRDENOISE_CHROMAFR;Chrominance +!TP_DIRPYRDENOISE_CTYPE;Auto method +!TP_DIRPYRDENOISE_CTYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nAutomatic multi-zones\nNo preview - works only during saving, but using the "Preview" method by matching the tile size and center to the preview size and center you can get an idea of the expected results.\nThe image is divided into tiles (about 10 to 70 depending on image size) and each tile receives its own chrominance noise reduction settings.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CURVEEDITOR_CC;Chroma +!TP_DIRPYRDENOISE_CURVEEDITOR_CC_TOOLTIP;Increase (multiply) the value of all chrominance sliders.\nThis curve lets you adjust the strength of chromatic noise reduction as a function of chromaticity, for instance to increase the action in areas of low saturation and to decrease it in those of high saturation. +!TP_DIRPYRDENOISE_CURVEEDITOR_L_TOOLTIP;Modulates action of 'Luminance' denoise +!TP_DIRPYRDENOISE_CUR;Curve +!TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on the gamma of the input color profile. An sRGB gamma is assumed, thus if the image uses an input color profile of a different gamma, the effects of luminance noise reduction will differ. +!TP_DIRPYRDENOISE_ENH;Enhanced mode +!TP_DIRPYRDENOISE_ENH_TOOLTIP;Increases noise reduction quality at the expense of a 20% processing time increase. +!TP_DIRPYRDENOISE_GAMMA_TOOLTIP;Gamma varies noise reduction strength across the range of tones. Smaller values will target shadows, while larger values will stretch the effect to the brighter tones. +!TP_DIRPYRDENOISE_LABM;L*a*b* +!TP_DIRPYRDENOISE_LCURVE;Luminance curve +!TP_DIRPYRDENOISE_LM;Luminance only +!TP_DIRPYRDENOISE_LPLABM;Weighted L* (little) + a*b* (normal) +!TP_DIRPYRDENOISE_LTYPE;Luminance control +!TP_DIRPYRDENOISE_LUMAFR;Luminance +!TP_DIRPYRDENOISE_LUMAFR_TOOLTIP;Wavelet on luminance and Fourier transform for luminance detail +!TP_DIRPYRDENOISE_MANU;Manual +!TP_DIRPYRDENOISE_MAN;Manual +!TP_DIRPYRDENOISE_MEDMETHOD;Median method +!TP_DIRPYRDENOISE_MEDTYPE;Median type +!TP_DIRPYRDENOISE_MED;Median Filter +!TP_DIRPYRDENOISE_MED_TOOLTIP;Enabled median denoising +!TP_DIRPYRDENOISE_METHOD11;Quality +!TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. +!TP_DIRPYRDENOISE_METHOD;Method +!TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or L*a*b* methods can be used.\n\nFor non-raw images the L*a*b* method will be used, regardless of the selection. +!TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - +!TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 +!TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. +!TP_DIRPYRDENOISE_PASSES;Median iterations +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PON;Auto multi-zones +!TP_DIRPYRDENOISE_PREVLABEL;Preview size=%1, Center: Px=%2 Py=%3 +!TP_DIRPYRDENOISE_PREV;Preview +!TP_DIRPYRDENOISE_PRE;Preview multi-zones +!TP_DIRPYRDENOISE_RED;Chrominance - Red-Green +!TP_DIRPYRDENOISE_RGBM;RGB +!TP_DIRPYRDENOISE_RGB;RGB +!TP_DIRPYRDENOISE_SHALBI;High +!TP_DIRPYRDENOISE_SHAL;Standard +!TP_DIRPYRDENOISE_SLI;Slider +!TP_DIRPYRDENOISE_SOFT;3x3 +!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_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_EPD_GAMMA;Gamma +!TP_EPD_TOOLTIP;Tone mapping is possible in L*a*b* mode (standard) and CIECAM02 mode.\n\nWhen in L*a*b* mode, tone mapping can also be used on the residual image of the Wavelet Levels tool.\n\nTo engage CIECAM02 tone mapping mode enable the following settings:\n1. CIECAM02\n2. Algorithm="Brightness + Colorfulness (QM)"\n3. "Tone mapping using CIECAM02 brightness (Q)" +!TP_EXPOSURE_TCMODE_LUMINANCE;Luminance +!TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points +!TP_EXPOS_WHITEPOINT_LABEL;Raw White Points +!TP_FILMSIMULATION_LABEL;Film Simulation +!TP_FILMSIMULATION_STRENGTH;Strength +!TP_FILMSIMULATION_ZEROCLUTSFOUND;Set HaldCLUT directory in Preferences +!TP_FLATFIELD_CLIPCONTROL;Clip control +!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. +!TP_GENERAL_11SCALE_TOOLTIP;The effects of this tool are only visible or only accurate at a preview scale of 1:1. +!TP_GRADIENT_CENTER;Center +!TP_GRADIENT_CENTER_X;Center X +!TP_GRADIENT_CENTER_X_TOOLTIP;Shift gradient to the left (negative values) or right (positive values). +!TP_GRADIENT_CENTER_Y;Center Y +!TP_GRADIENT_CENTER_Y_TOOLTIP;Shift gradient up (negative values) or down (positive values). +!TP_GRADIENT_DEGREE;Angle +!TP_GRADIENT_DEGREE_TOOLTIP;Rotation angle in degrees. +!TP_GRADIENT_FEATHER;Feather +!TP_GRADIENT_FEATHER_TOOLTIP;Gradient width in percent of the image diagonal. +!TP_GRADIENT_LABEL;Graduated Filter +!TP_GRADIENT_STRENGTH;Strength +!TP_GRADIENT_STRENGTH_TOOLTIP;Filter strength in stops. +!TP_HLREC_ENA_TOOLTIP;Could be activated by Auto Levels. +!TP_ICM_DCPILLUMINANT;Illuminant +!TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolated +!TP_ICM_DCPILLUMINANT_TOOLTIP;Select which embedded DCP illuminant to employ. Default is "interpolated" which is a mix between the two based on white balance. The setting is only enabled if a Dual-Illuminant DCP with interpolation support is selected. +!TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance +!TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. The result can be used for calibration purposes and generation of a camera profile. +!TP_LABCURVE_CHROMA_TOOLTIP;To apply B&W toning, set Chromaticity to -100. +!TP_LABCURVE_CURVEEDITOR_CL;CL +!TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Chromaticity according to luminance C=f(L) +!TP_LABCURVE_CURVEEDITOR_HH;HH +!TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Hue according to hue H=f(H) +!TP_LABCURVE_CURVEEDITOR_LH;LH +!TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H) +!TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminance according to luminance L=f(L) +!TP_PCVIGNETTE_FEATHER;Feather +!TP_PCVIGNETTE_FEATHER_TOOLTIP;Feathering:\n0 = corners only,\n50 = halfway to center,\n100 = to center. +!TP_PCVIGNETTE_LABEL;Vignette Filter +!TP_PCVIGNETTE_ROUNDNESS;Roundness +!TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness:\n0 = rectangle,\n50 = fitted ellipse,\n100 = circle. +!TP_PCVIGNETTE_STRENGTH;Strength +!TP_PCVIGNETTE_STRENGTH_TOOLTIP;Filter strength in stops (reached in corners). +!TP_PFCURVE_CURVEEDITOR_CH;Hue +!TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Controls defringe strength by color.\nHigher = more,\nLower = less. +!TP_PREPROCESS_DEADPIXFILT;Dead pixel filter +!TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Tries to suppress dead pixels. +!TP_PREPROCESS_HOTPIXFILT;Hot pixel filter +!TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Tries to suppress hot pixels. +!TP_RAWEXPOS_BLACK_0;Green 1 (lead) +!TP_RAWEXPOS_BLACK_1;Red +!TP_RAWEXPOS_BLACK_2;Blue +!TP_RAWEXPOS_BLACK_3;Green 2 +!TP_RAWEXPOS_BLACK_BLUE;Blue +!TP_RAWEXPOS_BLACK_GREEN;Green +!TP_RAWEXPOS_BLACK_RED;Red +!TP_RAWEXPOS_RGB;Red, Green, Blue +!TP_RAW_DMETHOD_PROGRESSBAR;%1 demosaicing... +!TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Demosaicing refinement... +!TP_RAW_DMETHOD_TOOLTIP;Note: IGV and LMMSE are dedicated to high ISO images to aid in noise reduction without leading to maze patterns, posterization or a washed-out look. +!TP_RAW_HD;Threshold +!TP_RAW_HD_TOOLTIP;Lower values make hot/dead pixel detection more aggressive, but false positives may lead to artifacts. If you notice any artifacts appearing when enabling the Hot/Dead Pixel Filters, gradually increase the threshold value until they disappear. +!TP_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!TP_RAW_LMMSE_TOOLTIP;Adds gamma (step 1), median (steps 2-4) and refinement (steps 5-6) to reduce artifacts and improve the signal-to-noise ratio. +!TP_RAW_SENSOR_BAYER_LABEL;Sensor with Bayer Matrix +!TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;3-pass gives best results (recommended for low ISO images).\n1-pass is almost undistinguishable from 3-pass for high ISO images and is faster. +!TP_RAW_SENSOR_XTRANS_LABEL;Sensor with X-Trans Matrix +!TP_RGBCURVES_LUMAMODE;Luminosity mode +!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_SHARPENING_TOOLTIP;Expect a slightly different effect when using with CIECAM02. If difference is observed, adjust to taste. +!TP_WAVELET_1;Level 1 +!TP_WAVELET_2;Level 2 +!TP_WAVELET_3;Level 3 +!TP_WAVELET_4;Level 4 +!TP_WAVELET_5;Level 5 +!TP_WAVELET_6;Level 6 +!TP_WAVELET_7;Level 7 +!TP_WAVELET_8;Level 8 +!TP_WAVELET_9;Level 9 +!TP_WAVELET_ALL;All levels in all directions +!TP_WAVELET_APPLYTO;Apply To +!TP_WAVELET_AVOID;Avoid color shift +!TP_WAVELET_B0;Black +!TP_WAVELET_B1;Grey +!TP_WAVELET_B2;Residual +!TP_WAVELET_BACUR;Curve +!TP_WAVELET_BALANCE;Contrast balance d/v-h +!TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chromaticity or residual tone mapping are activated, the effect due to balance is amplified. +!TP_WAVELET_BALCHRO;Chroma balance +!TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chromaticity balance. +!TP_WAVELET_BANONE;None +!TP_WAVELET_BASLI;Slider +!TP_WAVELET_BATYPE;Contrast balance method +!TP_WAVELET_CCURVE;Local contrast +!TP_WAVELET_CH1;Whole chromaticity range +!TP_WAVELET_CH2;Saturated/pastel +!TP_WAVELET_CH3;Link contrast levels +!TP_WAVELET_CHCU;Curve +!TP_WAVELET_CHRO;Saturated/pastel threshold +!TP_WAVELET_CHRO_TOOLTIP;Sets the wavelet level which will be the threshold between saturated and pastel colors.\n1-x: saturated\nx-9: pastel\n\nIf the value exceeds the amount of wavelet levels you are using then it will be ignored. +!TP_WAVELET_CHR;Chroma-contrast link strength +!TP_WAVELET_CHR_TOOLTIP;Adjusts chromaticity as a function of "contrast levels" and "chroma-contrast link strength" +!TP_WAVELET_CHSL;Sliders +!TP_WAVELET_CHTYPE;Chrominance method +!TP_WAVELET_COLORT;Opacity Red-Green +!TP_WAVELET_COMBOTH;Both +!TP_WAVELET_COMPCONT;Contrast +!TP_WAVELET_COMPGAMMA;Compression gamma +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjusting the gamma of the residual image allow you to equilibrate the data and histogram. +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjust gamma for residual image and compression.\nAllow to equilibrate data and histogram +!TP_WAVELET_COMPTM;Tone mapping +!TP_WAVELET_CONTEDIT;'After' Contrast curve +!TP_WAVELET_CONTEDIT;'After' contrast curve +!TP_WAVELET_CONTRAST_MINUS;Contrast - +!TP_WAVELET_CONTRAST_PLUS;Contrast + +!TP_WAVELET_CONTRA;Contrast +!TP_WAVELET_CONTRA_TOOLTIP;Changes contrast of the residual image. +!TP_WAVELET_CONTR;Gamut +!TP_WAVELET_CTYPE;Chrominance control +!TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modifies local contrast as a function of the original local contrast (absciss)\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 100..300)\n66% absciss represents standard deviation of local contrast (real value about 300..800)\n100% represents maximum (real value about 3000..8000) +!TP_WAVELET_CURVEEDITOR_CH;Contrast levels=f(Hue) +!TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modifies each level's contrast as a function oh hue.\nTake care not to overwrite changes made with the Gamut Hue controls.\nThe curve will only have an effect when wavelet contrast level sliders are non-zero. +!TP_WAVELET_CURVEEDITOR_CL;L +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Applies a final contrast luminance curve at the end of the wavelet treatment. +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Apply a contrast luminance curve at the end of wavelet level threatment +!TP_WAVELET_CURVEEDITOR_HH;HH +!TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modifies the residual image's hue as a function of hue. +!TP_WAVELET_DALL;All directions +!TP_WAVELET_DAUB;Edge performance +!TP_WAVELET_DAUB_TOOLTIP;Changes Daubechies coefficients:\nD4 = Standard,\nD14 = Often best performance, 10% more time-intensive.\n\nAffects edge detection as well as the general quality of the firsts levels. However the quality is not strictly related to this coefficient and can vary with images and uses. +!TP_WAVELET_DISP;Preview Settings +!TP_WAVELET_DONE;Vertical +!TP_WAVELET_DTHR;Diagonal +!TP_WAVELET_DTWO;Horizontal +!TP_WAVELET_EDCU;Curve +!TP_WAVELET_EDGCONT;Local contrast +!TP_WAVELET_EDGCONT_TOOLTIP;Adjusting the points to the left decreases contrast, and to the right increases it.\nBottom-left, Top-Left, Top-Right, Bottom-right represent respectively local contast for low values, mean, mean+stdev, maxima +!TP_WAVELET_EDGEDETECTTHR2;Threshold high (detection) +!TP_WAVELET_EDGEDETECTTHR;Threshold low (noise) +!TP_WAVELET_EDGEDETECTTHR_TOOLTIP;This adjuster lets you target edge detection for example to avoid applying edge sharpness to fine details, such as noise in the sky. +!TP_WAVELET_EDGEDETECT;Gradient sensitivity +!TP_WAVELET_EDGEDETECT_TOOLTIP;Moving the slider to the right increases edge sensitivity. This affects local contrast, edge settings and noise. +!TP_WAVELET_EDGE;Edge Sharpness +!TP_WAVELET_EDGREINF_TOOLTIP;Reinforce or reduce the action of the first level, do the opposite to the second level, and leave the rest unchanged. +!TP_WAVELET_EDGTHRESH;Detail +!TP_WAVELET_EDGTHRESH_TOOLTIP;Change the repartition between the first levels and the others. The higher the threshold the more the action is centred on the first levels. Be careful with negative values, they increase the action of high levels and can introduce artifacts. +!TP_WAVELET_EDRAD;Radius +!TP_WAVELET_EDRAD_TOOLTIP;This radius adjustment is very different from those in other sharpening tools. Its value is compared to each level through a complex function. In this sense, a value of zero still has an effect. +!TP_WAVELET_EDSL;Threshold Sliders +!TP_WAVELET_EDTYPE;Local contrast method +!TP_WAVELET_EDVAL;Strength +!TP_WAVELET_FINAL;Final Touchup +!TP_WAVELET_FINEST;Finest +!TP_WAVELET_HIGHLIGHT;Highlight luminance range +!TP_WAVELET_HS1;Whole luminance range +!TP_WAVELET_HS2;Shadows/Highlights +!TP_WAVELET_HUESKIN;Skin hue +!TP_WAVELET_HUESKIN_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_HUESKY;Sky hue +!TP_WAVELET_HUESKY_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_INF;Below or equal the level +!TP_WAVELET_ITER;Delta balance levels +!TP_WAVELET_ITER_TOOLTIP;Left: increase low levels and reduce high levels,\nRight: reduce low levels and increase high levels. +!TP_WAVELET_LABEL;Wavelet levels +!TP_WAVELET_LARGEST;Coarsest +!TP_WAVELET_LEVCH;Chromaticity +!TP_WAVELET_LEVELS;Wavelet levels +!TP_WAVELET_LEVELS_TOOLTIP;Choose the number of detail levels the image is to be decomposed into. More levels require more RAM and require a longer processing time. +!TP_WAVELET_LEVF;Contrast +!TP_WAVELET_LEVLABEL;Preview maximum possible levels = %1 +!TP_WAVELET_LEVONE;Level 2 +!TP_WAVELET_LEVTWO;Level 3 +!TP_WAVELET_LEVZERO;Level 1 +!TP_WAVELET_LINKEDG;Link with Edge Sharpness' Strength +!TP_WAVELET_LIPST;Enhanced algorithm +!TP_WAVELET_LIPST_TOOLTIP;This algorithm uses Lipschitz regularity to increase edge detection quality at a cost of increased processing time and memory requirements. +!TP_WAVELET_LOWLIGHT;Shadow luminance range +!TP_WAVELET_MEDGREINF;First level +!TP_WAVELET_MEDILEV;Edge detection +!TP_WAVELET_MEDI;Reduce artifacts in blue sky +!TP_WAVELET_NEUTRAL;Neutral +!TP_WAVELET_NOISE;Denoise and Refine +!TP_WAVELET_NOIS;Denoise +!TP_WAVELET_ONE;One level +!TP_WAVELET_OPACITYWL;Final local contrast +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify final local contrast in function of last local contrast (absciss) for all levels decomposition\nTake into account: \na)contrast levels \nb)edge sharpness \nc)contrast balance\nd)decomposition-recomposition\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 200..1000)\n66% absciss represents standard deviation of local contrast (real value about 1000..2000)\n100% represents maximum (real value about 5000..13000) +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify the final local contrast at the end of the wavelet treatment.\n\nThe left side represents the smallest local contrast, progressing to the largest local contrast on the right. +!TP_WAVELET_OPACITYW;Contrast balance d/v-h curve +!TP_WAVELET_OPACITY;Opacity Blue-Yellow +!TP_WAVELET_PASTEL;Pastel chromaticity +!TP_WAVELET_PREVIEWBACK;Background +!TP_WAVELET_PREVIEWLEVELS;Preview +!TP_WAVELET_RE1;Reinforced +!TP_WAVELET_RE2;Unchanged +!TP_WAVELET_RE3;Reduced +!TP_WAVELET_RESCHRO;Chromaticity +!TP_WAVELET_RESCONH;Highlights +!TP_WAVELET_RESCON;Shadows +!TP_WAVELET_RESID;Residual image +!TP_WAVELET_SAT;Saturated chromaticity +!TP_WAVELET_SETTINGS;Wavelet Settings +!TP_WAVELET_SKIN;Skin targetting/protection +!TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected. +!TP_WAVELET_SKY;Sky targetting/protection +!TP_WAVELET_SKY_TOOLTIP;At -100 sky-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 sky-tones are protected while all other tones are affected. +!TP_WAVELET_STRENGTH;Strength +!TP_WAVELET_STREN;Strength +!TP_WAVELET_SUPE;Extra +!TP_WAVELET_SUP;Above the level +!TP_WAVELET_THRESHOLD2;Shadow levels +!TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels between 9 and 9 minus the value will be affected by the shadow luminance range. Other levels will be fully treated. The highest level possible is limited by the highlight level value (9 minus highlight level value). +!TP_WAVELET_THRESHOLD;Highlight levels +!TP_WAVELET_THRESHOLD_TOOLTIP;Only levels beyond the chosen value will be affected by the highlight luminance range. Other levels will be fully treated. The chosen value here limits the highest possible value of the shadow levels. +!TP_WAVELET_THRH;Highlights threshold +!TP_WAVELET_THR;Shadows threshold +!TP_WAVELET_TILESBIG;Big tiles +!TP_WAVELET_TILESFULL;Full image +!TP_WAVELET_TILESIZE;Tiling method +!TP_WAVELET_TILESLIT;Little tiles +!TP_WAVELET_TILES_TOOLTIP;Processing the full image leads to better quality and is the recommended option, while using tiles is a fall-back solution for users with little RAM. Refer to RawPedia for memory requirements. +!TP_WAVELET_TMHIGH;High +!TP_WAVELET_TMLOWHIGH;Low+High +!TP_WAVELET_TMNONE;None +!TP_WAVELET_TMSTD;Standard +!TP_WAVELET_TMSTRENGTH;Compression strength +!TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image. When the value is different from 0, the Strength and Gamma sliders of the Tone Mapping tool in the Exposure tab will become grayed out. +!TP_WAVELET_TMTYPE;Compression method +!TP_WAVELET_TON;Toning +!TP_WAVELET_daub2;D2 - low +!TP_WAVELET_daub4;D4 - standard +!TP_WAVELET_daub6;D6 - standard plus +!TP_WAVELET_daub10;D10 - medium +!TP_WAVELET_daub14;D14 - high +!TP_WBALANCE_EQBLUERED;Blue/Red equalizer +!TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behavior of "white balance" by modulating the blue/red balance.\nThis can be useful when shooting conditions:\na) are far from the standard illuminant (e.g. underwater),\nb) are far from conditions where calibrations were performed,\nc) where the matrices or ICC profiles are unsuitable. +!TP_WBALANCE_WATER1;UnderWater 1 +!TP_WBALANCE_WATER2;UnderWater 2 +!TP_WBALANCE_WATER_HEADER;UnderWater +!ZOOMPANEL_ZOOMFITCROPSCREEN;Fit crop to screen\nShortcut: Alt-f diff --git a/rtdata/languages/Chinese (Simplified) b/rtdata/languages/Chinese (Simplified) new file mode 100644 index 000000000..c70062163 --- /dev/null +++ b/rtdata/languages/Chinese (Simplified) @@ -0,0 +1,1855 @@ +#00 Chinese (Simplified) +#01 2008-02-13 Forrest Sun +#02 2008-11-06 Yang Gao (grantyale) +#03 2013-10-20 Jiero +#04 2014-10-24 Jie Luo + +ABOUT_TAB_BUILD;版本 +ABOUT_TAB_CREDITS;感谢 +ABOUT_TAB_LICENSE;授权协议 +ABOUT_TAB_RELEASENOTES;发布说明 +ABOUT_TAB_SPLASH;Splash +ADJUSTER_RESET_TO_DEFAULT;重置缺省参数 +BATCHQUEUE_AUTOSTART;自动开始 +BATCHQUEUE_DESTFILENAME;路径和文件名 +BATCH_PROCESSING;批量处理 +CURVEEDITOR_CURVES;曲线 +CURVEEDITOR_CURVE;曲线 +CURVEEDITOR_CUSTOM;自定义 +CURVEEDITOR_DARKS;暗 +CURVEEDITOR_HIGHLIGHTS;高亮 +CURVEEDITOR_LIGHTS;光 +CURVEEDITOR_LINEAR;线性 +CURVEEDITOR_LOADDLGLABEL;正读取曲线... +CURVEEDITOR_SAVEDLGLABEL;正保存曲线... +CURVEEDITOR_SHADOWS;阴影 +CURVEEDITOR_TOOLTIPLINEAR;重置曲线 +CURVEEDITOR_TOOLTIPLOAD;读取曲线 +CURVEEDITOR_TOOLTIPSAVE;保存曲线 +CURVEEDITOR_TYPE;类型: +DIRBROWSER_FOLDERS;文件夹 +EDITWINDOW_TITLE;图片修改 +EXIFFILTER_APERTURE;光圈 +EXIFFILTER_CAMERA;相机 +EXIFFILTER_FILETYPE;文件类型 +EXIFFILTER_FOCALLEN;焦距 +EXIFFILTER_ISO;感光度 +EXIFFILTER_LENS;镜头 +EXIFFILTER_SHUTTER;快门 +EXIFPANEL_ADDEDITHINT;添加/编辑标签 +EXIFPANEL_ADDEDIT;添加/编辑 +EXIFPANEL_ADDTAGDLG_ENTERVALUE;输入内容 +EXIFPANEL_ADDTAGDLG_SELECTTAG;选择标签 +EXIFPANEL_ADDTAGDLG_TITLE;添加/编辑标签 +EXIFPANEL_KEEPHINT;输出文件时保留“已选”标签 +EXIFPANEL_KEEP;保留 +EXIFPANEL_REMOVEHINT;输出文件时移除“已选”标签 +EXIFPANEL_REMOVE;移除 +EXIFPANEL_RESETALLHINT;重置所有标签内容 +EXIFPANEL_RESETALL;全部重置 +EXIFPANEL_RESETHINT;重置所选标签内容 +EXIFPANEL_RESET;重置 +EXIFPANEL_SUBDIRECTORY;子文件夹 +EXPORT_BYPASS_ALL;(取消)选择全部 +EXPORT_BYPASS_RAW_FF;Bypass [raw] 平场 +EXPORT_BYPASS_RAW_LINENOISE;Bypass [raw] 线噪过滤 +EXPORT_FASTEXPORTOPTIONS;快速导出选项 +EXPORT_MAXHEIGHT;最大高度 +EXPORT_MAXWIDTH;最大宽度 +EXPORT_PUTTOQUEUEFAST; 放入快速导出序列 +EXTPROGTARGET_1;raw +FILEBROWSER_APPLYPROFILE;应用配置 +FILEBROWSER_CACHECLEARFROMFULL;清空缓存 +FILEBROWSER_CACHECLEARFROMPARTIAL;清理缓存 +FILEBROWSER_CACHE;缓存 +FILEBROWSER_CLEARPROFILE;清空配置 +FILEBROWSER_COPYPROFILE;复制配置 +FILEBROWSER_CURRENT_NAME;当前名称: +FILEBROWSER_DELETEDLGLABEL;确认删除 +FILEBROWSER_DELETEDLGMSG;确定删除所选的%1个文件? +FILEBROWSER_EMPTYTRASHHINT;永久清空垃圾箱 +FILEBROWSER_EMPTYTRASH;清空垃圾箱 +FILEBROWSER_EXEC_CPB;自定义档案制作工具 +FILEBROWSER_EXTPROGMENU;调用程序... +FILEBROWSER_NEW_NAME;新名称: +FILEBROWSER_OPENDEFAULTVIEWER;Windows 默认阅览工具 (序列) +FILEBROWSER_PARTIALPASTEPROFILE;选择性粘贴 +FILEBROWSER_PASTEPROFILE;粘贴配置 +FILEBROWSER_POPUPCANCELJOB;取消任务 +FILEBROWSER_POPUPCOLORLABEL;彩色标帖 +FILEBROWSER_POPUPCOPYTO;复制至... +FILEBROWSER_POPUPFILEOPERATIONS;文件操作 +FILEBROWSER_POPUPMOVEEND;移动到队列尾部 +FILEBROWSER_POPUPMOVEHEAD;移动到队列头部 +FILEBROWSER_POPUPMOVETO;移动至... +FILEBROWSER_POPUPOPENINEDITOR;打开在编辑器 +FILEBROWSER_POPUPOPEN;打开 +FILEBROWSER_POPUPPROCESSFAST;放入序列(快速导出) +FILEBROWSER_POPUPPROCESS;放入队列 +FILEBROWSER_POPUPPROFILEOPERATIONS;处理色彩档案 +FILEBROWSER_POPUPRANK1;评 1 星 +FILEBROWSER_POPUPRANK2;评 2 星 +FILEBROWSER_POPUPRANK3;评 3 星 +FILEBROWSER_POPUPRANK4;评 4 星 +FILEBROWSER_POPUPRANK5;评 5 星 +FILEBROWSER_POPUPREMOVEINCLPROC;删除序列输出 +FILEBROWSER_POPUPREMOVE;从文件系统中移除 +FILEBROWSER_POPUPRENAME;重命名 +FILEBROWSER_POPUPSELECTALL;全部选中 +FILEBROWSER_POPUPTRASH;移动到垃圾箱 +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_RENAMEDLGLABEL;文件重命名 +FILEBROWSER_RENAMEDLGMSG;将"%1"更名为: +FILEBROWSER_SELECTDARKFRAME;选择暗幅... +FILEBROWSER_SELECTFLATFIELD;选择平场…… +FILEBROWSER_SHOWDIRHINT;显示文件夹中所有图片 +FILEBROWSER_SHOWEXIFINFO;显示Exif 信息\n\n快捷:\ni - 多编辑标签页模式,\nAlt-i - 单编辑标签模式 +FILEBROWSER_SHOWRANK1HINT;显示1星图片 +FILEBROWSER_SHOWRANK2HINT;显示2星图片 +FILEBROWSER_SHOWRANK3HINT;显示3星图片 +FILEBROWSER_SHOWRANK4HINT;显示4星图片 +FILEBROWSER_SHOWRANK5HINT;显示5星图片 +FILEBROWSER_SHOWRECENTLYSAVEDHINT;显示保存的图片\n快捷: Alt-7 +FILEBROWSER_SHOWTRASHHINT;显示垃圾箱内容 +FILEBROWSER_SHOWUNRANKHINT;显示未评星图片 +FILEBROWSER_STARTPROCESSINGHINT;开始处理或保存队列中的图片 +FILEBROWSER_STARTPROCESSING;开始处理 +FILEBROWSER_STOPPROCESSINGHINT;停止处理图片 +FILEBROWSER_STOPPROCESSING;停止处理 +FILEBROWSER_THUMBSIZE;缩略图大小 +FILEBROWSER_ZOOMINHINT;增大缩略图 +FILEBROWSER_ZOOMOUTHINT;减小缩略图 +GENERAL_ABOUT;关于 +GENERAL_AFTER;之后 +GENERAL_AUTO;自动 +GENERAL_BEFORE;之前 +GENERAL_CANCEL;取消 +GENERAL_CLOSE;关闭 +GENERAL_DISABLED;禁用 +GENERAL_DISABLE;禁用 +GENERAL_ENABLED;开启 +GENERAL_ENABLE;启用 +GENERAL_FILE;文件 +GENERAL_LANDSCAPE;横向 +GENERAL_NA;不适用 +GENERAL_NONE;无 +GENERAL_NO;否 +GENERAL_OK;确定 +GENERAL_PORTRAIT;纵向 +GENERAL_SAVE;保存 +GENERAL_UNCHANGED;(未改变) +GENERAL_WARNING;警告 +HISTOGRAM_TOOLTIP_B;显示/隐藏 蓝色直方图 +HISTOGRAM_TOOLTIP_G;显示/隐藏 绿色直方图 +HISTOGRAM_TOOLTIP_L;显示/隐藏 CIELAB 亮度直方图 +HISTOGRAM_TOOLTIP_R;显示/隐藏 红色直方图 +HISTORY_CHANGED;已更改 +HISTORY_CUSTOMCURVE;自定义曲线 +HISTORY_DELSNAPSHOT;移除快照 +HISTORY_FROMCLIPBOARD;从剪贴板 +HISTORY_LABEL;历史 +HISTORY_MSG_1;图片加载完 +HISTORY_MSG_2;配置加载完 +HISTORY_MSG_3;配置改变 +HISTORY_MSG_4;历史浏览 +HISTORY_MSG_5;亮度 +HISTORY_MSG_6;对比度 +HISTORY_MSG_7;黑 +HISTORY_MSG_8;曝光补偿 +HISTORY_MSG_9;高光压缩 +HISTORY_MSG_10;阴影压缩 +HISTORY_MSG_11;影调曲线 +HISTORY_MSG_12;自动曝光 +HISTORY_MSG_13;曝光溢出 +HISTORY_MSG_14;亮度亮度 +HISTORY_MSG_15;亮度对比度 +HISTORY_MSG_16;亮度黑 +HISTORY_MSG_17;亮度高光压缩 +HISTORY_MSG_18;亮度阴影压缩 +HISTORY_MSG_19;亮度曲线 +HISTORY_MSG_20;锐化 +HISTORY_MSG_21;锐化半径 +HISTORY_MSG_22;锐化程度 +HISTORY_MSG_23;锐化阈值 +HISTORY_MSG_24;仅锐化边缘 +HISTORY_MSG_25;锐化边缘半径 +HISTORY_MSG_26;锐化边缘容差 +HISTORY_MSG_27;锐化光晕控制 +HISTORY_MSG_28;光晕控制量 +HISTORY_MSG_29;锐化方式 +HISTORY_MSG_30;重叠半径 +HISTORY_MSG_31;重叠程度 +HISTORY_MSG_32;重叠衰减 +HISTORY_MSG_33;重叠次数 +HISTORY_MSG_34;避免色彩溢出 +HISTORY_MSG_35;饱和度限制器 +HISTORY_MSG_36;饱和度限制 +HISTORY_MSG_37;色彩增强 +HISTORY_MSG_38;拍平衡方式 +HISTORY_MSG_39;色温 +HISTORY_MSG_40;白平衡微调 +HISTORY_MSG_41;色彩偏移 "A" +HISTORY_MSG_42;色彩偏移 "B" +HISTORY_MSG_43;亮度降噪 +HISTORY_MSG_44;亮度降噪半径 +HISTORY_MSG_45;亮度降噪边缘容差 +HISTORY_MSG_46;色彩降噪 +HISTORY_MSG_47;色彩降噪半径 +HISTORY_MSG_48;色彩降噪边缘容差 +HISTORY_MSG_49;色彩降噪边缘敏感度 +HISTORY_MSG_50;阴影/高光工具 +HISTORY_MSG_51;高光增强 +HISTORY_MSG_52;阴影增强 +HISTORY_MSG_53;高光色度范围 +HISTORY_MSG_54;阴影色度范围 +HISTORY_MSG_55;局部对比度 +HISTORY_MSG_56;阴影/高光半径 +HISTORY_MSG_57;粗略旋转 +HISTORY_MSG_58;水平翻转 +HISTORY_MSG_59;竖直翻转 +HISTORY_MSG_60;旋转 +HISTORY_MSG_61;旋转 +HISTORY_MSG_62;镜头失真矫正 +HISTORY_MSG_63;设置书签 +HISTORY_MSG_64;剪切图片 +HISTORY_MSG_65;色散矫正 +HISTORY_MSG_66;高光还原 +HISTORY_MSG_67;高光还原程度 +HISTORY_MSG_68;高光还原方式 +HISTORY_MSG_69;工作色彩空间 +HISTORY_MSG_70;输出色彩空间 +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_79;调整宽度 +HISTORY_MSG_80;调整高度 +HISTORY_MSG_81;调整尺寸开启 +HISTORY_MSG_83;S/H - 锐度蒙板 +HISTORY_MSG_84;视角矫正 +HISTORY_MSG_85;LCP +HISTORY_MSG_89;降噪 +HISTORY_MSG_90;降噪 - 亮度 +HISTORY_MSG_92;降噪 - 伽马 +HISTORY_MSG_103;HSV - 数值 +HISTORY_MSG_111;Lab - 避免色彩偏移 +HISTORY_MSG_113;Lab - 保护 +HISTORY_MSG_114;DCB 迭代 +HISTORY_MSG_119;线性消噪 +HISTORY_MSG_122;自动暗幅 +HISTORY_MSG_123;暗幅文件 +HISTORY_MSG_124;线性曝光修正 +HISTORY_MSG_126;平场文件 +HISTORY_MSG_127;平场自动选择 +HISTORY_MSG_128;平场模糊半径 +HISTORY_MSG_129;平场模糊类型 +HISTORY_MSG_130;自动扭曲纠正 +HISTORY_MSG_146;边缘锐化 +HISTORY_MSG_147;边缘锐化 - 单纯亮度 +HISTORY_MSG_155;Vib - 避免色彩偏移 +HISTORY_MSG_158;力度 +HISTORY_MSG_159;边缘停止 +HISTORY_MSG_160;拉伸 +HISTORY_MSG_162;色阶映射 +HISTORY_MSG_173;降噪 - 亮度细节 +HISTORY_MSG_174;CIECAM02 +HISTORY_MSG_183;CAM02 - 对比度 (J) +HISTORY_MSG_210;渐变 - 角度 +HISTORY_MSG_211;渐变滤镜 +HISTORY_MSG_212;暗角 - 力度 +HISTORY_MSG_213;暗角滤镜 +HISTORY_MSG_239;GF - 力度 +HISTORY_MSG_244;VC - 力度 +HISTORY_MSG_245;VC - 中心 +HISTORY_NEWSNAPSHOT;新建快照 +HISTORY_NEWSNAPSHOT_TOOLTIP;快捷键:Alt-s +HISTORY_SNAPSHOTS;系列快照 +HISTORY_SNAPSHOT;快照 +IPTCPANEL_AUTHORSPOSITIONHINT;作者头衔 +IPTCPANEL_AUTHORSPOSITION;作者职位 +IPTCPANEL_AUTHOR;作者 +IPTCPANEL_CAPTIONHINT;文字说明 +IPTCPANEL_CAPTIONWRITERHINT;参与创作人员 +IPTCPANEL_CAPTIONWRITER;说明作者 +IPTCPANEL_CAPTION;标题 +IPTCPANEL_CATEGORYHINT;提供者所认为的作品类别 +IPTCPANEL_CATEGORY;类别 +IPTCPANEL_CITYHINT;图片来自城市 +IPTCPANEL_CITY;城市 +IPTCPANEL_COPYHINT;将IPTC设置复制到剪贴板 +IPTCPANEL_COPYRIGHTHINT;版权信息 +IPTCPANEL_COPYRIGHT;版权 +IPTCPANEL_COUNTRYHINT;图片来自国家 +IPTCPANEL_COUNTRY;国家 +IPTCPANEL_CREDITHINT;图片提供者,未必是作者 +IPTCPANEL_CREDIT;提供者 +IPTCPANEL_DATECREATEDHINT;图片创作日期,格式:年月日补零(YYYYMMDD) +IPTCPANEL_DATECREATED;创作日期 +IPTCPANEL_EMBEDDEDHINT;将IPTC数据重置为图片内嵌数据 +IPTCPANEL_EMBEDDED;内嵌 +IPTCPANEL_HEADLINEHINT;可发布的内容简介 +IPTCPANEL_HEADLINE;摘要 +IPTCPANEL_INSTRUCTIONSHINT;写给编辑的特殊要求 +IPTCPANEL_INSTRUCTIONS;指令 +IPTCPANEL_KEYWORDSHINT;用于信息索引 +IPTCPANEL_KEYWORDS;关键词 +IPTCPANEL_PASTEHINT;粘贴剪贴板内的IPTC设置 +IPTCPANEL_PROVINCEHINT;图片来自省份 +IPTCPANEL_PROVINCE;省份 +IPTCPANEL_RESETHINT;重置为默认配置 +IPTCPANEL_RESET;重置 +IPTCPANEL_SOURCEHINT;图片内容知识产权所有人 +IPTCPANEL_SOURCE;来源 +IPTCPANEL_SUPPCATEGORIESHINT;进一步细分类别 +IPTCPANEL_SUPPCATEGORIES;附加类别 +IPTCPANEL_TITLEHINT;作品的名称 +IPTCPANEL_TITLE;标题 +IPTCPANEL_TRANSREFERENCEHINT;原始发送地点代码 +IPTCPANEL_TRANSREFERENCE;传输基准 +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_SENDTOEDITOR;发送到编辑器 +MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;使用外部工具编辑当前图像。\n快捷键:Ctrl+E +MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;显示/隐藏全部侧边栏\n快捷键: m +MAIN_BUTTON_UNFULLSCREEN;退出全屏 +MAIN_FRAME_BATCHQUEUE;批量处理序列 +MAIN_FRAME_BATCHQUEUE_TOOLTIP;处理序列\n快捷键: Ctrl-F3 +MAIN_FRAME_EDITOR;编辑器 +MAIN_FRAME_EDITOR_TOOLTIP;编辑器.\n快捷键: Ctrl-F4 +MAIN_FRAME_FILEBROWSER;文件浏览 +MAIN_FRAME_FILEBROWSER_TOOLTIP;文件浏览\n快捷键: Ctrl-F2 +MAIN_FRAME_PLACES;位置 +MAIN_FRAME_PLACES_ADD;添加 +MAIN_FRAME_PLACES_DEL;删除 +MAIN_FRAME_RECENT;最近使用的文件夹 +MAIN_MSG_ALREADYEXISTS;该文件已存在 +MAIN_MSG_CANNOTLOAD;无法加载图片 +MAIN_MSG_CANNOTSAVE;文件保存中出错 +MAIN_MSG_CANNOTSTARTEDITOR;无法启动编辑器 +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_EXIF;Exif +MAIN_TAB_EXPORT; 快速导出 +MAIN_TAB_EXPOSURE;曝光 +MAIN_TAB_FILTER;滤镜 +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;元数据 +MAIN_TAB_RAW;Raw +MAIN_TAB_RAW_TOOLTIP;快捷键:Alt-R +MAIN_TAB_TRANSFORM;转换 +MAIN_TOOLTIP_HIDEHP;显示/隐藏左面板 (包含历史, 快捷键: H) +MAIN_TOOLTIP_INDCLIPPEDH;高光溢出提示 +MAIN_TOOLTIP_INDCLIPPEDS;阴影不足提示 +MAIN_TOOLTIP_PREVIEWR;Preview the Red channel.\nShortcut: 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 +NAVIGATOR_B;B: +NAVIGATOR_G;G: +NAVIGATOR_H;H: +NAVIGATOR_LAB_A;a: +NAVIGATOR_LAB_B;b: +NAVIGATOR_LAB_L;L: +NAVIGATOR_NA; -- +NAVIGATOR_R;R: +NAVIGATOR_S;S: +NAVIGATOR_V;V: +NAVIGATOR_XY_FULL;宽 = %1, 高 = %2 +NAVIGATOR_XY_NA;x = n/a, y = n/a +PARTIALPASTE_BASICGROUP;基本设置 +PARTIALPASTE_CACORRECTION;色彩校正 +PARTIALPASTE_CHANNELMIXERBW;黑白 +PARTIALPASTE_CHANNELMIXER;通道混合器 +PARTIALPASTE_COARSETRANS;90度旋转/翻转 +PARTIALPASTE_COLORAPP;CIECAM02 国际照明协会色彩显示框架2002 +PARTIALPASTE_COLORGROUP;色彩相关设定 +PARTIALPASTE_COMMONTRANSFORMPARAMS;自动填充 +PARTIALPASTE_COMPOSITIONGROUP;构图设置 +PARTIALPASTE_CROP;剪裁 +PARTIALPASTE_DARKFRAMEAUTOSELECT;暗幅自动选择 +PARTIALPASTE_DARKFRAMEFILE;暗幅文件 +PARTIALPASTE_DETAILGROUP;细节设置 +PARTIALPASTE_DIALOGLABEL;选择性粘贴配置 +PARTIALPASTE_DIRPYRDENOISE;降噪 +PARTIALPASTE_DISTORTION;畸变校正 +PARTIALPASTE_EPD;色调映射 +PARTIALPASTE_EVERYTHING;全部 +PARTIALPASTE_EXIFCHANGES;对exif所做的修改 +PARTIALPASTE_EXPOSURE;曝光 +PARTIALPASTE_GRADIENT;渐变过滤 +PARTIALPASTE_HSVEQUALIZER;HSV均衡 +PARTIALPASTE_ICMGAMMA;到处伽吗值 +PARTIALPASTE_ICMSETTINGS;ICM 设置 +PARTIALPASTE_IPTCINFO;IPTC 信息 +PARTIALPASTE_LABCURVE;Lab调整 +PARTIALPASTE_LENSGROUP;镜头相关设置 +PARTIALPASTE_LENSPROFILE;镜片修正档案 +PARTIALPASTE_METAGROUP;元数据 +PARTIALPASTE_PCVIGNETTE;暗角滤镜 +PARTIALPASTE_PERSPECTIVE;视角 +PARTIALPASTE_PREPROCESS_GREENEQUIL;绿平衡 +PARTIALPASTE_PREPROCESS_LINEDENOISE;线性噪点滤镜 +PARTIALPASTE_RAWCACORR_AUTO;CA自动更正 +PARTIALPASTE_RAWCACORR_CABLUE;CA蓝 +PARTIALPASTE_RAWCACORR_CARED;CA红 +PARTIALPASTE_RAWGROUP;Raw设置 +PARTIALPASTE_RESIZE;缩放 +PARTIALPASTE_RGBCURVES;RGB曲线 +PARTIALPASTE_ROTATION;旋转 +PARTIALPASTE_SHADOWSHIGHLIGHTS;阴影/高光 +PARTIALPASTE_SHARPENEDGE;边缘 +PARTIALPASTE_SHARPENING;锐化 +PARTIALPASTE_SHARPENMICRO;微处对比 +PARTIALPASTE_VIBRANCE;震动 +PARTIALPASTE_VIGNETTING;暗角修正 +PARTIALPASTE_WHITEBALANCE;白平衡 +PREFERENCES_ADD;添加 +PREFERENCES_APPLNEXTSTARTUP;下次启动生效 +PREFERENCES_AUTOMONPROFILE;使用操作系统主显示器的色彩档案 +PREFERENCES_BATCH_PROCESSING;批处理 +PREFERENCES_BEHADDALL;全 '添加' +PREFERENCES_BEHAVIOR;行为 +PREFERENCES_BEHSETALL;全 '设定' +PREFERENCES_CACHECLEARALL;全部清除 +PREFERENCES_CACHECLEARPROFILES;清除配置 +PREFERENCES_CACHECLEARTHUMBS;清除缩略图 +PREFERENCES_CACHEMAXENTRIES;最大缓存数量 +PREFERENCES_CACHEOPTS;缓存选项 +PREFERENCES_CACHETHUMBHEIGHT;最大缩略图高度 +PREFERENCES_CLIPPINGIND;高光溢出提示 +PREFERENCES_CMETRICINTENT;色彩模式 +PREFERENCES_D50;5000K +PREFERENCES_D55;5500K +PREFERENCES_D60;6000K +PREFERENCES_D65;6500K +PREFERENCES_DATEFORMATHINT;可以使用下列控制符:\n%y : 年\n%m : 月h\n%d : 日\n\n例如,中文日期格式:\n%y/%m/%d +PREFERENCES_DATEFORMAT;日期格式 +PREFERENCES_DEFAULTLANG;缺省语言 +PREFERENCES_DEFAULTTHEME;默认主题 +PREFERENCES_DIRHOME;用户文件路径 +PREFERENCES_DIRLAST;上次访问路径 +PREFERENCES_DIROTHER;其他 +PREFERENCES_DIRSELECTDLG;启动时选择图片路径... +PREFERENCES_DIRSOFTWARE;软件安装路径 +PREFERENCES_EDITORCMDLINE;其他命令行 +PREFERENCES_EXTERNALEDITOR;外部编辑器 +PREFERENCES_FBROWSEROPTS;文件浏览选项 +PREFERENCES_FILEFORMAT;文件格式 +PREFERENCES_FLATFIELDFOUND;找到 +PREFERENCES_FLATFIELD;平场 +PREFERENCES_FORIMAGE;用于图片文件 +PREFERENCES_FORRAW;用于Raw文件 +PREFERENCES_GIMPPATH;GIMP安装文件夹 +PREFERENCES_HLTHRESHOLD;高光溢出阈值 +PREFERENCES_ICCDIR;ICC配置路径 +PREFERENCES_IMPROCPARAMS;缺省图片处理参数 +PREFERENCES_INTENT_ABSOLUTE;绝对色彩模式 +PREFERENCES_INTENT_PERCEPTUAL;感知模式 +PREFERENCES_INTENT_RELATIVE;相对色彩模式 +PREFERENCES_INTENT_SATURATION;饱和度 +PREFERENCES_MENUGROUPRANK;组 "评价" +PREFERENCES_MONITORICC;显示器配置 +PREFERENCES_OUTDIRFOLDERHINT;将已寸图片放至所选文件夹 +PREFERENCES_OUTDIRFOLDER;保存至文件夹 +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_OUTDIRTEMPLATE;使用模板 +PREFERENCES_OUTDIR;输出路径 +PREFERENCES_PARSEDEXTADDHINT;输入扩展名并按此按钮将其添加至列表 +PREFERENCES_PARSEDEXTADD;添加扩展名 +PREFERENCES_PARSEDEXTDELHINT;从列表中删除选中的扩展名 +PREFERENCES_PARSEDEXT;已知扩展名 +PREFERENCES_PROFILEHANDLING;图片处理配置管理 +PREFERENCES_PROFILELOADPR;配置文件读取优先级 +PREFERENCES_PROFILEPRCACHE;缓存中的配置文件 +PREFERENCES_PROFILEPRFILE;与图片并列存放的配置文件 +PREFERENCES_PROFILESAVECACHE;将配置文件写至缓存 +PREFERENCES_PROFILESAVEINPUT;将配置文件与图片并列存放 +PREFERENCES_PROPERTY;属性 +PREFERENCES_PSPATH;Adobe Photoshop安装路径 +PREFERENCES_SELECTLANG;选择语言 +PREFERENCES_SELECTTHEME;选择主题 +PREFERENCES_SHOWBASICEXIF;显示基本Exif信息 +PREFERENCES_SHOWDATETIME;显示时间日期 +PREFERENCES_SHTHRESHOLD;阴影过暗阈值 +PREFERENCES_STARTUPIMDIR;启动时路径 +PREFERENCES_TAB_BROWSER;文件浏览器 +PREFERENCES_TAB_COLORMGR;色彩管理 +PREFERENCES_TAB_GENERAL;一般 +PREFERENCES_TAB_IMPROC;图片处理 +PREFERENCES_TAB_SOUND;音效 +PREFERENCES_TP_LABEL;工具栏 +PREFERENCES_USESYSTEMTHEME;使用系统主题 +PREFERENCES_WORKFLOW;排版 +PROFILEPANEL_LABEL;处理参数配置 +PROFILEPANEL_LOADDLGLABEL;加载处理参数为... +PROFILEPANEL_MYPROFILES;我的档案 +PROFILEPANEL_PCUSTOM;自定义 +PROFILEPANEL_PFILE;由文件 +PROFILEPANEL_PLASTSAVED;上次保存 +PROFILEPANEL_SAVEDLGLABEL;保存处理参数为... +PROFILEPANEL_TOOLTIPCOPY;将当前配置复制到剪贴板 +PROFILEPANEL_TOOLTIPLOAD;由文件加载配置 +PROFILEPANEL_TOOLTIPPASTE;从剪贴板粘贴配置 +PROFILEPANEL_TOOLTIPSAVE;保存当前配置 +PROGRESSBAR_LOADINGTHUMBS;正在读取缩略图…… +PROGRESSBAR_LOADING;图片加载中... +PROGRESSBAR_LOADJPEG;JPEG文件加载中... +PROGRESSBAR_LOADPNG;PNG文件加载中... +PROGRESSBAR_LOADTIFF;TIFF文件加载中... +PROGRESSBAR_NOIMAGES;没找到图片 +PROGRESSBAR_PROCESSING;图片处理中... +PROGRESSBAR_READY;就绪 +PROGRESSBAR_SAVEJPEG;JPEG文件保存中... +PROGRESSBAR_SAVEPNG;PNG文件保存中... +PROGRESSBAR_SAVETIFF;TIFF文件保存中... +QINFO_ISO;感光度 +QINFO_NOEXIF;Exif数据不可用. +SAVEDLG_AUTOSUFFIX;自动加后缀到已经存在的文件 +SAVEDLG_FILEFORMAT;文件格式 +SAVEDLG_FORCEFORMATOPTS;强制保存选项 +SAVEDLG_JPEGQUAL;JPEG质量 +SAVEDLG_PNGCOMPR;PNG压缩 +SAVEDLG_PUTTOQUEUEHEAD;放在处理序列首位 +SAVEDLG_PUTTOQUEUETAIL;放在处理序列末位 +SAVEDLG_PUTTOQUEUE;放入队列 +SAVEDLG_SAVEIMMEDIATELY;立即保存 +SAVEDLG_SAVESPP;随图片保存处理参数 +SAVEDLG_SUBSAMP;二次抽样 +SAVEDLG_SUBSAMP_1;极限压缩 +SAVEDLG_SUBSAMP_2;平衡 +SAVEDLG_SUBSAMP_3;质量至优 +SAVEDLG_TIFFUNCOMPRESSED;未压缩的TIFF +SAVEDLG_WARNFILENAME;文件将被命名 +TOOLBAR_TOOLTIP_CROP;剪裁选择 (快捷键: C) +TOOLBAR_TOOLTIP_HAND;手形工具 (快捷键: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;基准线选择 (快捷键: S) +TOOLBAR_TOOLTIP_WB;白平衡采样 (快捷键: W) +TP_BWMIX_ALGO_LI;线性 +TP_BWMIX_ALGO_SP;特定效果 +TP_BWMIX_AUTOCH;自动 +TP_BWMIX_FILTER;色彩过滤 +TP_BWMIX_FILTER_BLUEGREEN;蓝-绿 +TP_BWMIX_FILTER_BLUE;蓝 +TP_BWMIX_FILTER_GREENYELLOW;绿-黄 +TP_BWMIX_FILTER_GREEN;绿 +TP_BWMIX_FILTER_NONE;无 +TP_BWMIX_FILTER_PURPLE;紫 +TP_BWMIX_FILTER_REDYELLOW;红-黄 +TP_BWMIX_FILTER_RED;红 +TP_BWMIX_FILTER_YELLOW;黄 +TP_BWMIX_GAMMA;伽马矫正 +TP_BWMIX_GAM_TOOLTIP;矫正红绿蓝三色通道(RGB)伽马 +TP_BWMIX_LABEL;黑白 +TP_BWMIX_MET;方式 +TP_BWMIX_MET_DESAT;淡化饱和度 +TP_BWMIX_MET_LUMEQUAL;明亮度平衡工具 +TP_BWMIX_MIXC;混合工具 +TP_BWMIX_NEUTRAL;重置混合工具 +TP_BWMIX_NEUTRAL_TIP;重置所有混合工具(色彩过滤、通道混合) +TP_BWMIX_SETTING;预设 +TP_BWMIX_SETTING_TOOLTIP;不同预设 (影片、水平排布等)或手动通道混合工具设置 +TP_BWMIX_SET_HIGHCONTAST;高对比度 +TP_BWMIX_SET_HIGHSENSIT;高灵敏度 +TP_BWMIX_SET_INFRARED;红外 +TP_BWMIX_SET_LANDSCAPE;水平排布(风景) +TP_BWMIX_SET_LOWSENSIT;低灵敏度 +TP_BWMIX_SET_LUMINANCE;光亮度 +TP_BWMIX_SET_PANCHRO;全色的 +TP_BWMIX_SET_PORTRAIT;垂直排布(肖像) +TP_BWMIX_TCMODE_FILMLIKE;黑白电影样式 +TP_BWMIX_TCMODE_STANDARD;黑白电影标准 +TP_BWMIX_VAL;L +TP_CACORRECTION_BLUE;蓝 +TP_CACORRECTION_LABEL;色散矫正 +TP_CACORRECTION_RED;红 +TP_CHMIXER_BLUE;蓝 +TP_CHMIXER_GREEN;绿 +TP_CHMIXER_LABEL;通道混合 +TP_CHMIXER_RED;红 +TP_COARSETRAF_TOOLTIP_HFLIP;水平翻转 +TP_COARSETRAF_TOOLTIP_ROTLEFT;左转 +TP_COARSETRAF_TOOLTIP_ROTRIGHT;右转 +TP_COARSETRAF_TOOLTIP_VFLIP;竖直翻转 +TP_COLORAPP_LABEL_CAM02;图像调整 +TP_COLORAPP_LIGHT;光度 (J) +TP_COLORAPP_LIGHT_TOOLTIP; CIECAM02、Lab 、RGB中光度意义各不同 +TP_COLORAPP_SURROUND_AVER;平均 +TP_COLORAPP_SURROUND_DARK;暗 +TP_COLORAPP_SURROUND_DIM;暗淡 +TP_COLORAPP_TCMODE_BRIGHTNESS;亮度 +TP_COLORAPP_TCMODE_LIGHTNESS;光度 +TP_COLORAPP_TCMODE_SATUR;色彩饱和度 +TP_CROP_FIXRATIO;比例: +TP_CROP_GTDIAGONALS;对角线法则 +TP_CROP_GTFRAME;框架 +TP_CROP_GTGRID;方格 +TP_CROP_GTNONE;无 +TP_CROP_GTRULETHIRDS;1/3法则 +TP_CROP_GUIDETYPE;辅助方式: +TP_CROP_H;高 +TP_CROP_LABEL;剪裁 +TP_CROP_PPI;PPI= +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_RADIUS;半径 +TP_DIRPYRDENOISE_LABEL;降噪 +TP_DIRPYRDENOISE_LDETAIL;明亮度细节 +TP_DIRPYRDENOISE_LUMA;光亮度/发光度 +TP_DIRPYRDENOISE_RGB;RGB +TP_DIRPYREQUALIZER_LUMAFINEST;最佳 +TP_DIRPYREQUALIZER_LUMANEUTRAL;自然 +TP_DIRPYREQUALIZER_THRESHOLD;阀值 +TP_DISTORTION_AMOUNT;程度 +TP_DISTORTION_AUTO;自动畸变矫正 +TP_DISTORTION_AUTO_TIP;自动进行一些相机的镜头畸变矫正 +TP_DISTORTION_LABEL;畸变 +TP_EPD_LABEL;色阶映射 +TP_EPD_SCALE;拉伸 +TP_EPD_STRENGTH;力度 +TP_EXPOSURE_AUTOLEVELS;自动色阶 +TP_EXPOSURE_BLACKLEVEL;黑 +TP_EXPOSURE_BRIGHTNESS;亮度 +TP_EXPOSURE_CLIP;高光溢出 +TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;高光压缩阀值 +TP_EXPOSURE_COMPRHIGHLIGHTS;高光压缩 +TP_EXPOSURE_COMPRSHADOWS;阴影压缩 +TP_EXPOSURE_CONTRAST;对比度 +TP_EXPOSURE_CURVEEDITOR1;色调曲线 1 +TP_EXPOSURE_CURVEEDITOR2;色调曲线 2 +TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;请从 “曝光 > 色调曲线” (Exposure > Tone Curve) RawPedia 文章中学到使用2条色调曲线获得好效果 +TP_EXPOSURE_CURVEEDITOR;影调曲线 +TP_EXPOSURE_EXPCOMP;曝光补偿 +TP_EXPOSURE_LABEL;曝光 +TP_EXPOSURE_SATURATION;色彩饱和度 +TP_EXPOSURE_TCMODE_FILMLIKE;电影样式 +TP_EXPOSURE_TCMODE_LABEL1;曲线模式1 +TP_EXPOSURE_TCMODE_LABEL2;曲线模式2 +TP_EXPOSURE_TCMODE_SATANDVALBLENDING;饱和度和混合值 +TP_EXPOSURE_TCMODE_STANDARD;标准 +TP_EXPOSURE_TCMODE_WEIGHTEDSTD;倾向于标准 +TP_FLATFIELD_AUTOSELECT;自动选择 +TP_FLATFIELD_BLURRADIUS;模糊半径 +TP_FLATFIELD_BLURTYPE;模糊种类 +TP_FLATFIELD_BT_AREA;区域 +TP_FLATFIELD_BT_HORIZONTAL;水平 +TP_FLATFIELD_BT_VERTHORIZ;垂直 + 水平 +TP_FLATFIELD_BT_VERTICAL;垂直 +TP_FLATFIELD_LABEL;平场 +TP_GAMMA_CURV;伽马 +TP_GAMMA_FREE;自由伽马 +TP_GAMMA_OUTPUT;导出伽马 +TP_GAMMA_SLOP;斜率 (线性) +TP_GRADIENT_CENTER;中心 +TP_GRADIENT_CENTER_X;中心 X +TP_GRADIENT_CENTER_Y;中心 Y +TP_GRADIENT_DEGREE;角度 +TP_GRADIENT_DEGREE_TOOLTIP;转动角度数 +TP_GRADIENT_FEATHER;羽化 +TP_GRADIENT_FEATHER_TOOLTIP;图像对角比例表示渐变宽度 +TP_GRADIENT_LABEL;渐变过滤 +TP_GRADIENT_STRENGTH;延展 +TP_HLREC_BLEND;混合 +TP_HLREC_CIELAB;CIELab模式混合 +TP_HLREC_COLOR;色彩延伸 +TP_HLREC_LABEL;高光还原 +TP_HLREC_LUMINANCE;亮度还原 +TP_HLREC_METHOD;方式: +TP_HSVEQUALIZER_CHANNEL;频道 +TP_HSVEQUALIZER_HUE;H +TP_HSVEQUALIZER_LABEL;HSV 平衡 +TP_HSVEQUALIZER_SAT;S +TP_HSVEQUALIZER_VAL;V +TP_ICM_INPUTCAMERA;相机缺省 +TP_ICM_INPUTCUSTOM;自定义 +TP_ICM_INPUTCUSTOM_TOOLTIP;选择你自己的 DCP/ICC 色彩档案 +TP_ICM_INPUTDLGLABEL;选择输入ICC配置... +TP_ICM_INPUTEMBEDDED;如可能,使用内置 +TP_ICM_INPUTEMBEDDED_TOOLTIP;使用色彩档案嵌入非raw文件 +TP_ICM_INPUTNONE;无档案 +TP_ICM_INPUTPROFILE;输入配置 +TP_ICM_LABEL;ICM +TP_ICM_NOICM;No ICM: sRGB配置 +TP_ICM_OUTPUTPROFILE;输出配置 +TP_ICM_SAVEREFERENCE;保存参考图片用于生成配置信息 +TP_ICM_TONECURVE;使用 DCP 色调曲线 +TP_ICM_WORKINGPROFILE;当前配置 +TP_IMPULSEDENOISE_LABEL;降低电磁干扰 +TP_IMPULSEDENOISE_THRESH;阈值 +TP_LABCURVE_AVOIDCOLORSHIFT;避免色彩偏移 +TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;使色彩适应当前色彩空间范围,并使用Munsell色矫正。 +TP_LABCURVE_BRIGHTNESS;光度 +TP_LABCURVE_CHROMATICITY;色度 CIE +TP_LABCURVE_CONTRAST;对比度 +TP_LABCURVE_CURVEEDITOR;明亮度曲线 +TP_LABCURVE_LABEL;Lab调整 +TP_LENSGEOM_AUTOCROP;自动剪切 +TP_LENSGEOM_FILL;自动填充 +TP_LENSGEOM_LABEL;镜头 / 几何 +TP_LENSPROFILE_LABEL;镜头矫正档案 +TP_LENSPROFILE_USECA;CA 矫正 +TP_LENSPROFILE_USEDIST;畸变矫正 +TP_LENSPROFILE_USEVIGN;暗角矫正 +TP_NEUTRAL;自然 +TP_PCVIGNETTE_FEATHER;羽化 +TP_PCVIGNETTE_LABEL;暗角滤镜 +TP_PCVIGNETTE_ROUNDNESS;圆度 +TP_PCVIGNETTE_STRENGTH;力度 +TP_PCVIGNETTE_STRENGTH_TOOLTIP;滤镜的力度刻度 (到达角落) +TP_PERSPECTIVE_HORIZONTAL;水平 +TP_PERSPECTIVE_LABEL;视角 +TP_PERSPECTIVE_VERTICAL;垂直 +TP_PREPROCESS_LABEL;处理中 +TP_PREPROCESS_LINEDENOISE;线性噪点过滤 +TP_PREPROCESS_NO_FOUND;没发现 +TP_RAWCACORR_AUTO;自动修正 +TP_RAWCACORR_CABLUE;蓝 +TP_RAWCACORR_CARED;红 +TP_RESIZE_CROPPEDAREA;切出的部分 +TP_RESIZE_FITBOX;Bounding Box 包围盒 +TP_RESIZE_FULLIMAGE;全图 +TP_RESIZE_HEIGHT;高度 +TP_RESIZE_H;高: +TP_RESIZE_LABEL;调整大小 +TP_RESIZE_LANCZOS;Lanczos算法 +TP_RESIZE_METHOD;方式: +TP_RESIZE_NEAREST;最近点 +TP_RESIZE_SCALE;比例 +TP_RESIZE_SPECIFY;指定: +TP_RESIZE_WIDTH;宽度 +TP_RESIZE_W;宽: +TP_RGBCURVES_BLUE;B +TP_RGBCURVES_CHANNEL;频道 +TP_RGBCURVES_GREEN;G +TP_RGBCURVES_LABEL;RGB曲线 +TP_RGBCURVES_LUMAMODE;光度模式 +TP_RGBCURVES_LUMAMODE_TOOLTIP;光度模式 允许改变R、G、B三种通道光量但不影响色彩。 +TP_RGBCURVES_RED;R +TP_ROTATE_DEGREE;角度 +TP_ROTATE_LABEL;旋转 +TP_ROTATE_SELECTLINE; 选择基准线 +TP_SAVEDIALOG_OK_TIP;快捷键: Ctrl-Enter +TP_SHADOWSHLIGHTS_HIGHLIGHTS;高光 +TP_SHADOWSHLIGHTS_HLTONALW;影调范围 +TP_SHADOWSHLIGHTS_LABEL;阴影/高光 +TP_SHADOWSHLIGHTS_LOCALCONTR;局部对比度 +TP_SHADOWSHLIGHTS_RADIUS;半径 +TP_SHADOWSHLIGHTS_SHADOWS;阴影 +TP_SHADOWSHLIGHTS_SHARPMASK;锐度蒙板 +TP_SHADOWSHLIGHTS_SHTONALW;影调范围 +TP_SHARPENEDGE_AMOUNT;数量 +TP_SHARPENEDGE_LABEL;边缘 +TP_SHARPENEDGE_PASSES;迭代次数 +TP_SHARPENEDGE_THREE;仅光度 +TP_SHARPENING_AMOUNT;程度 +TP_SHARPENING_EDRADIUS;半径 +TP_SHARPENING_EDTOLERANCE;边缘容差 +TP_SHARPENING_HALOCONTROL;光晕控制 +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_DAMPING;衰减 +TP_SHARPENING_RLD_ITERATIONS;迭代 +TP_SHARPENING_THRESHOLD;阈值 +TP_SHARPENING_USM;虚像屏蔽 +TP_SHARPENMICRO_AMOUNT;数量 +TP_VIGNETTING_AMOUNT;程度 +TP_VIGNETTING_CENTER;中心 +TP_VIGNETTING_CENTER_X;中心 X +TP_VIGNETTING_CENTER_Y;中心 Y +TP_VIGNETTING_LABEL;暗角矫正 +TP_VIGNETTING_RADIUS;半径 +TP_VIGNETTING_STRENGTH;力度 +TP_WBALANCE_AUTO;自动 +TP_WBALANCE_CAMERA;相机 +TP_WBALANCE_CLOUDY;阴天 +TP_WBALANCE_CUSTOM;自定义 +TP_WBALANCE_DAYLIGHT;晴天 +TP_WBALANCE_EQBLUERED;蓝红平衡 +TP_WBALANCE_FLASH55;莱卡Leica +TP_WBALANCE_FLASH_HEADER;闪光 +TP_WBALANCE_GREEN;色度 +TP_WBALANCE_LABEL;白平衡 +TP_WBALANCE_LED_HEADER;LED +TP_WBALANCE_METHOD;方式 +TP_WBALANCE_SHADE;阴影 +TP_WBALANCE_SIZE;大小: +TP_WBALANCE_SOLUX35;Solux 3500K +TP_WBALANCE_SOLUX41;Solux 4100K +TP_WBALANCE_SPOTWB;白平衡采样 +TP_WBALANCE_TEMPERATURE;色温 +TP_WBALANCE_WATER1;水下 1 +TP_WBALANCE_WATER2;水下 2 +TP_WBALANCE_WATER_HEADER;水下 +ZOOMPANEL_100;(100%) +ZOOMPANEL_NEWCROPWINDOW;开启(新)细节窗口 +ZOOMPANEL_ZOOM100;缩放到100%\n快捷键: z +ZOOMPANEL_ZOOMFITSCREEN;适应屏幕\n快捷键: f +ZOOMPANEL_ZOOMIN;缩放拉近\n快捷键: + +ZOOMPANEL_ZOOMOUT;缩放拉远\n快捷键: - + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!CURVEEDITOR_AXIS_IN;I: +!CURVEEDITOR_AXIS_LEFT_TAN;LT: +!CURVEEDITOR_AXIS_OUT;O: +!CURVEEDITOR_AXIS_RIGHT_TAN;RT: +!CURVEEDITOR_EDITPOINT_HINT;Enable edition of node in/out values.\n\nRight-click on a node to select it.\nRight-click on empty space to de-select the node. +!CURVEEDITOR_MINMAXCPOINTS;Equalizer +!CURVEEDITOR_NURBS;Control cage +!CURVEEDITOR_PARAMETRIC;Parametric +!CURVEEDITOR_TOOLTIPCOPY;Copy current curve to clipboard. +!CURVEEDITOR_TOOLTIPPASTE;Paste curve from clipboard. +!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 +!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_RAW_DMETHOD;Demosaic method +!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_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_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 +!FILEBROWSER_SHOWCOLORLABEL4HINT;Show images labeled Blue.\nShortcut: Alt-4 +!FILEBROWSER_SHOWCOLORLABEL5HINT;Show images labeled Purple.\nShortcut: Alt-5 +!FILEBROWSER_SHOWEDITEDHINT;Show edited images.\nShortcut: 7 +!FILEBROWSER_SHOWEDITEDNOTHINT;Show not edited images.\nShortcut: 6 +!FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show unsaved images.\nShortcut: Alt-6 +!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_ASIMAGE;As Image +!HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar.\nRight-click on image preview to freeze/unfreeze. +!HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram. +!HISTOGRAM_TOOLTIP_FULL;Toggle full (off) or scaled (on) histogram. +!HISTOGRAM_TOOLTIP_RAW;Show/Hide raw histogram. +!HISTORY_MSG_82;Profile changed +!HISTORY_MSG_86;RGB curves - Luminosity mode +!HISTORY_MSG_87;Impulse noise reduction +!HISTORY_MSG_88;Impulse NR threshold +!HISTORY_MSG_91;NR - Chrominance master +!HISTORY_MSG_93;CbDL - Value +!HISTORY_MSG_94;Contrast by Detail Levels +!HISTORY_MSG_95;L*a*b* - Chromaticity +!HISTORY_MSG_96;L*a*b* - a* curve +!HISTORY_MSG_97;L*a*b* - b* curve +!HISTORY_MSG_98;Demosaicing method +!HISTORY_MSG_99;Hot pixel filter +!HISTORY_MSG_100;RGB Saturation +!HISTORY_MSG_101;HSV - Hue +!HISTORY_MSG_102;HSV - Saturation +!HISTORY_MSG_104;HSV Equalizer +!HISTORY_MSG_105;Defringe +!HISTORY_MSG_106;Defringe - Radius +!HISTORY_MSG_107;Defringe - Threshold +!HISTORY_MSG_108;Highlight Compr. Threshold +!HISTORY_MSG_109;Resize - Bounding box +!HISTORY_MSG_110;Resize - Applies to +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_115;False color suppression +!HISTORY_MSG_116;DCB enhancement +!HISTORY_MSG_117;Raw CA correction - Red +!HISTORY_MSG_118;Raw CA correction - Blue +!HISTORY_MSG_120;Green equilibration +!HISTORY_MSG_121;Raw CA Correction - Auto +!HISTORY_MSG_125;Highlight preservation +!HISTORY_MSG_131;NR - Luma +!HISTORY_MSG_132;NR - Chroma +!HISTORY_MSG_133;Output gamma +!HISTORY_MSG_134;Free gamma +!HISTORY_MSG_135;Free gamma +!HISTORY_MSG_136;Free gamma slope +!HISTORY_MSG_137;Black level - Green 1 +!HISTORY_MSG_138;Black level - Red +!HISTORY_MSG_139;Black level - Blue +!HISTORY_MSG_140;Black level - Green 2 +!HISTORY_MSG_141;Black level - Link greens +!HISTORY_MSG_142;ES - Iterations +!HISTORY_MSG_143;ES - Quantity +!HISTORY_MSG_144;Microcontrast - Quantity +!HISTORY_MSG_145;Microcontrast - Uniformity +!HISTORY_MSG_148;Microcontrast +!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_150;Post-demosaic artifact/noise red. +!HISTORY_MSG_151;Vibrance +!HISTORY_MSG_152;Vib - Pastel tones +!HISTORY_MSG_153;Vib - Saturated tones +!HISTORY_MSG_154;Vib - Protect skin-tones +!HISTORY_MSG_156;Vib - Link pastel/saturated +!HISTORY_MSG_157;Vib - P/S threshold +!HISTORY_MSG_161;TM - Reweighting iterates +!HISTORY_MSG_163;RGB curves - Red +!HISTORY_MSG_164;RGB curves - Green +!HISTORY_MSG_165;RGB curves - Blue +!HISTORY_MSG_166;Neutral levels +!HISTORY_MSG_167;--unused-- +!HISTORY_MSG_168;L*a*b* - CC curve +!HISTORY_MSG_169;L*a*b* - CH curve +!HISTORY_MSG_170;Vibrance - HH curve +!HISTORY_MSG_171;L*a*b* - LC curve +!HISTORY_MSG_172;L*a*b* - Restrict LC +!HISTORY_MSG_175;CAM02 - CAT02 adaptation +!HISTORY_MSG_176;CAM02 - Viewing surround +!HISTORY_MSG_177;CAM02 - Scene luminosity +!HISTORY_MSG_178;CAM02 - Viewing luminosity +!HISTORY_MSG_179;CAM02 - White-point model +!HISTORY_MSG_180;CAM02 - Lightness (J) +!HISTORY_MSG_181;CAM02 - Chroma (C) +!HISTORY_MSG_182;CAM02 - Automatic CAT02 +!HISTORY_MSG_184;CAM02 - Scene surround +!HISTORY_MSG_185;CAM02 - Gamut control +!HISTORY_MSG_186;CAM02 - Algorithm +!HISTORY_MSG_187;CAM02 - Red/skin prot. +!HISTORY_MSG_188;CAM02 - Brightness (Q) +!HISTORY_MSG_189;CAM02 - Contrast (Q) +!HISTORY_MSG_190;CAM02 - Saturation (S) +!HISTORY_MSG_191;CAM02 - Colorfulness (M) +!HISTORY_MSG_192;CAM02 - Hue (h) +!HISTORY_MSG_193;CAM02 - Tone curve 1 +!HISTORY_MSG_194;CAM02 - Tone curve 2 +!HISTORY_MSG_195;CAM02 - Tone curve 1 +!HISTORY_MSG_196;CAM02 - Tone curve 2 +!HISTORY_MSG_197;CAM02 - Color curve +!HISTORY_MSG_198;CAM02 - Color curve +!HISTORY_MSG_199;CAM02 - Output histograms +!HISTORY_MSG_200;CAM02 - Tone mapping +!HISTORY_MSG_201;NR - Chrominance - R&G +!HISTORY_MSG_202;NR - Chrominance - B&Y +!HISTORY_MSG_203;NR - Method +!HISTORY_MSG_204;LMMSE enhancement steps +!HISTORY_MSG_205;CAM02 - Hot/bad pixel filter +!HISTORY_MSG_206;CAT02 - Auto scene luminosity +!HISTORY_MSG_207;Defringe - Hue curve +!HISTORY_MSG_208;WB - B/R equalizer +!HISTORY_MSG_214;Black-and-White +!HISTORY_MSG_215;B&W - CM - Red +!HISTORY_MSG_216;B&W - CM - Green +!HISTORY_MSG_217;B&W - CM - Blue +!HISTORY_MSG_218;B&W - Gamma - Red +!HISTORY_MSG_219;B&W - Gamma - Green +!HISTORY_MSG_220;B&W - Gamma - Blue +!HISTORY_MSG_221;B&W - Color filter +!HISTORY_MSG_222;B&W - Presets +!HISTORY_MSG_223;B&W - CM - Orange +!HISTORY_MSG_224;B&W - CM - Yellow +!HISTORY_MSG_225;B&W - CM - Cyan +!HISTORY_MSG_226;B&W - CM - Magenta +!HISTORY_MSG_227;B&W - CM - Purple +!HISTORY_MSG_228;B&W - Luminance equalizer +!HISTORY_MSG_229;B&W - Luminance equalizer +!HISTORY_MSG_230;B&W - Mode +!HISTORY_MSG_231;B&W - 'Before' curve +!HISTORY_MSG_232;B&W - 'Before' curve type +!HISTORY_MSG_233;B&W - 'After' curve +!HISTORY_MSG_234;B&W - 'After' curve type +!HISTORY_MSG_235;B&W - Auto channel mixer +!HISTORY_MSG_236;--unused-- +!HISTORY_MSG_237;B&W - Mixer +!HISTORY_MSG_238;GF - Feather +!HISTORY_MSG_240;GF - Center +!HISTORY_MSG_241;VF - Feather +!HISTORY_MSG_242;VF - Roundness +!HISTORY_MSG_243;VC - Radius +!HISTORY_MSG_246;L*a*b* - CL curve +!HISTORY_MSG_247;L*a*b* - LH curve +!HISTORY_MSG_248;L*a*b* - HH curve +!HISTORY_MSG_249;CbDL - Threshold +!HISTORY_MSG_250;NR - Enhanced +!HISTORY_MSG_251;B&W - Algorithm +!HISTORY_MSG_252;CbDL - Skin tar/prot +!HISTORY_MSG_253;CbDL - Reduce artifacts +!HISTORY_MSG_254;CbDL - Skin hue +!HISTORY_MSG_255;NR - Median filter +!HISTORY_MSG_256;NR - Median type +!HISTORY_MSG_257;Color Toning +!HISTORY_MSG_258;CT - Color curve +!HISTORY_MSG_259;CT - Opacity curve +!HISTORY_MSG_260;CT - a*[b*] opacity +!HISTORY_MSG_261;CT - Method +!HISTORY_MSG_262;CT - b* opacity +!HISTORY_MSG_263;CT - Shadows - Red +!HISTORY_MSG_264;CT - Shadows - Green +!HISTORY_MSG_265;CT - Shadows - Blue +!HISTORY_MSG_266;CT - Mid - Red +!HISTORY_MSG_267;CT - Mid - Green +!HISTORY_MSG_268;CT - Mid - Blue +!HISTORY_MSG_269;CT - High - Red +!HISTORY_MSG_270;CT - High - Green +!HISTORY_MSG_271;CT - High - Blue +!HISTORY_MSG_272;CT - Balance +!HISTORY_MSG_273;CT - Reset +!HISTORY_MSG_274;CT - Sat. Shadows +!HISTORY_MSG_275;CT - Sat. Highlights +!HISTORY_MSG_276;CT - Opacity +!HISTORY_MSG_277;--unused-- +!HISTORY_MSG_278;CT - Preserve luminance +!HISTORY_MSG_279;CT - Shadows +!HISTORY_MSG_280;CT - Highlights +!HISTORY_MSG_281;CT - Sat. strength +!HISTORY_MSG_282;CT - Sat. threshold +!HISTORY_MSG_283;CT - Strength +!HISTORY_MSG_284;CT - Auto sat. protection +!HISTORY_MSG_285;NR - Median - Method +!HISTORY_MSG_286;NR - Median - Type +!HISTORY_MSG_287;NR - Median - Iterations +!HISTORY_MSG_288;Flat Field - Clip control +!HISTORY_MSG_289;Flat Field - Clip control - Auto +!HISTORY_MSG_290;Black Level - Red +!HISTORY_MSG_291;Black Level - Green +!HISTORY_MSG_292;Black Level - Blue +!HISTORY_MSG_293;Film Simulation +!HISTORY_MSG_294;Film Simulation - Strength +!HISTORY_MSG_295;Film Simulation - Film +!HISTORY_MSG_296;NR - Luminance curve +!HISTORY_MSG_297;NR - Quality +!HISTORY_MSG_298;Dead pixel filter +!HISTORY_MSG_299;NR - Chrominance curve +!HISTORY_MSG_300;- +!HISTORY_MSG_301;NR - Luma control +!HISTORY_MSG_302;NR - Chroma method +!HISTORY_MSG_303;NR - Chroma method +!HISTORY_MSG_304;W - Contrast levels +!HISTORY_MSG_305;Wavelet Levels +!HISTORY_MSG_306;W - Preview +!HISTORY_MSG_307;W - Preview +!HISTORY_MSG_308;W - Preview direction +!HISTORY_MSG_309;W - ES - Detail +!HISTORY_MSG_310;W - Residual - Sky tar/prot +!HISTORY_MSG_311;W - Wavelet levels +!HISTORY_MSG_312;W - Residual - Shadows threshold +!HISTORY_MSG_313;W - Chroma - Sat/past +!HISTORY_MSG_314;W - Gamut - Reduce artifacts +!HISTORY_MSG_315;W - Residual - Contrast +!HISTORY_MSG_316;W - Gamut - Skin tar/prot +!HISTORY_MSG_317;W - Gamut - Skin hue +!HISTORY_MSG_318;W - Contrast - Highlight levels +!HISTORY_MSG_319;W - Contrast - Highlight range +!HISTORY_MSG_320;W - Contrast - Shadow range +!HISTORY_MSG_321;W - Contrast - Shadow levels +!HISTORY_MSG_322;W - Gamut - Avoid color shift +!HISTORY_MSG_323;W - ES - Local contrast +!HISTORY_MSG_324;W - Chroma - Pastel +!HISTORY_MSG_325;W - Chroma - Saturated +!HISTORY_MSG_326;W - Chroma - Method +!HISTORY_MSG_327;W - Contrast - Apply to +!HISTORY_MSG_328;W - Chroma - Link strength +!HISTORY_MSG_329;W - Toning - Opacity RG +!HISTORY_MSG_330;W - Toning - Opacity BY +!HISTORY_MSG_331;W - Contrast levels - Extra +!HISTORY_MSG_332;W - Tiling method +!HISTORY_MSG_333;W - Residual - Shadows +!HISTORY_MSG_334;W - Residual - Chroma +!HISTORY_MSG_335;W - Residual - Highlights +!HISTORY_MSG_336;W - Residual - Highlights threshold +!HISTORY_MSG_337;W - Residual - Sky hue +!HISTORY_MSG_338;W - ES - Radius +!HISTORY_MSG_339;W - ES - Strength +!HISTORY_MSG_340;W - Strength +!HISTORY_MSG_341;W - Edge performance +!HISTORY_MSG_342;W - ES - First level +!HISTORY_MSG_343;W - Chroma levels +!HISTORY_MSG_344;W - Meth chroma sl/cur +!HISTORY_MSG_345;W - ES - Local contrast +!HISTORY_MSG_346;W - ES - Local contrast method +!HISTORY_MSG_347;W - Denoise - Level 0 +!HISTORY_MSG_348;W - Denoise - Level 1 +!HISTORY_MSG_349;W - Denoise - Level 2 +!HISTORY_MSG_350;W - ES - Edge detection +!HISTORY_MSG_351;W - Residual - HH curve +!HISTORY_MSG_352;W - Background +!HISTORY_MSG_353;W - ES - Gradient sensitivity +!HISTORY_MSG_354;W - ES - Enhance +!HISTORY_MSG_355;W - ES - Threshold low +!HISTORY_MSG_356;W - ES - Threshold high +!HISTORY_MSG_357;W - Denoise - Link with ES +!HISTORY_MSG_358;W - Gamut - CH +!HISTORY_MSG_359;Hot/Dead - Threshold +!HISTORY_MSG_360;TM Gamma +!HISTORY_MSG_361;W - Final - Chroma balance +!HISTORY_MSG_362;W - Residual - Compression method +!HISTORY_MSG_363;W - Residual - Compression strength +!HISTORY_MSG_364;W - Final - Contrast balance +!HISTORY_MSG_365;W - Final - Delta balance +!HISTORY_MSG_366;W - Residual - Compression gamma +!HISTORY_MSG_367;W - ES - Local contrast curve +!HISTORY_MSG_368;W - Final - Contrast balance +!HISTORY_MSG_369;W - Final - Balance method +!HISTORY_MSG_370;W - Final - Local contrast curve +!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). +!MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue-processed first. +!MAIN_MSG_PATHDOESNTEXIST;The path\n\n%1\n\ndoes not exist. Please set a correct path in Preferences. +!MAIN_MSG_SETPATHFIRST;You first have to set a target path in Preferences in order to use this function! +!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_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%. +!MAIN_TOOLTIP_PREVIEWG;Preview the Green channel.\nShortcut: g +!MAIN_TOOLTIP_PREVIEWL;Preview the Luminosity.\nShortcut: v\n\n0.299*R + 0.587*G + 0.114*B +!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 Equalizer +!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_RAWEXPOS_BLACK;Black levels +!PARTIALPASTE_RAWEXPOS_LINEAR;White point correction +!PARTIALPASTE_RAWEXPOS_PRESER;Highlight preservation +!PARTIALPASTE_RAW_DCBENHANCE;DCB enhancement +!PARTIALPASTE_RAW_DCBITERATIONS;Number of DCB iterations +!PARTIALPASTE_RAW_DMETHOD;Demosaic method +!PARTIALPASTE_RAW_FALSECOLOR;Demosaic false color suppression steps +!PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!PARTIALPASTE_WAVELETGROUP;Wavelet processing +!PREFERENCES_AUTLISLOW;Low +!PREFERENCES_AUTLISMAX;Max - Average of all tiles +!PREFERENCES_AUTLISSTD;High +!PREFERENCES_AUTLISVLOW;None +!PREFERENCES_AUTLOW;Low +!PREFERENCES_AUTSTD;Standard +!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_CURVEBBOXPOS;Position of curve copypasta buttons +!PREFERENCES_CURVEBBOXPOS_ABOVE;Above +!PREFERENCES_CURVEBBOXPOS_BELOW;Below +!PREFERENCES_CURVEBBOXPOS_LEFT;Left +!PREFERENCES_CURVEBBOXPOS_RIGHT;Right +!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_CUSTPROFBUILD;Custom Processing Profile Builder +!PREFERENCES_CUTOVERLAYBRUSH;Crop mask color/transparency +!PREFERENCES_DARKFRAMEFOUND;Found +!PREFERENCES_DARKFRAMESHOTS;shots +!PREFERENCES_DARKFRAMETEMPLATES;templates +!PREFERENCES_DARKFRAME;Dark-Frame +!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 (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 Editor's panel 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_GREY05;Yb=05 CIE L#30 +!PREFERENCES_GREY10;Yb=10 CIE L#40 +!PREFERENCES_GREY15;Yb=15 CIE L#45 +!PREFERENCES_GREY18;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_GREYSC18;Yb=18 CIE L#50 +!PREFERENCES_GREYSCA;Automatic +!PREFERENCES_GREYSC;Scene Yb luminance (%) +!PREFERENCES_GREY;Output device's Yb luminance (%) +!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_LANGAUTODETECT;Use system language +!PREFERENCES_LEVAUTDN;Denoising level +!PREFERENCES_LEVDN;Cell size +!PREFERENCES_LISS;Auto multi-zone smoothing +!PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders +!PREFERENCES_MAX;Maxi (Tile) +!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_MULTITABDUALMON;Multiple Editor Tabs In Own Window Mode +!PREFERENCES_MULTITAB;Multiple Editor Tabs 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_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_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 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_SINGLETABVERTAB;Single Editor Tab Mode, Vertical Tabs +!PREFERENCES_SINGLETAB;Single Editor Tab Mode +!PREFERENCES_SLIMUI;Slim interface +!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_PERFORMANCE;Performance & Quality +!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 IPTC/XMP unchanged to output file (when tagging with other program) +!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 +!PROFILEPANEL_COPYPPASTE;Parameters to copy +!PROFILEPANEL_GLOBALPROFILES;Bundled profiles +!PROFILEPANEL_LOADPPASTE;Parameters to load +!PROFILEPANEL_MODE_TIP;Processing profile fill mode.\n\nButton pressed: partial profiles will be converted to full profiles; the missing values will be replaced with hard-coded defaults.\n\nButton released: profiles will be applied as they are, altering only those values which they contain. +!PROFILEPANEL_PASTEPPASTE;Parameters to paste +!PROFILEPANEL_PINTERNAL;Neutral +!PROFILEPANEL_SAVEPPASTE;Parameters to save +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing profile saved +!PROGRESSBAR_SNAPSHOT_ADDED;Snapshot added +!PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!SAVEDLG_SUBSAMP_TOOLTIP;Best compression: 4:1:1\nBalanced: 4:2:2\nBest quality: 4:4:4 +!SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. +!THRESHOLDSELECTOR_BL;Bottom-left +!THRESHOLDSELECTOR_BR;Bottom-right +!THRESHOLDSELECTOR_B;Bottom +!THRESHOLDSELECTOR_HINT;Hold the Shift key to move individual control points. +!THRESHOLDSELECTOR_TL;Top-left +!THRESHOLDSELECTOR_TR;Top-right +!THRESHOLDSELECTOR_T;Top +!TP_BWMIX_ALGO_TOOLTIP;Linear: will produce a normal linear response.\nSpecial effects: will produce special effects by mixing channels non-linearly. +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing Channel Mixer. +!TP_BWMIX_CC_ENABLED;Adjust complementary color +!TP_BWMIX_CC_TOOLTIP;Enable to allow automatic adjustment of complementary colors in ROYGCBPM mode. +!TP_BWMIX_CHANNEL;Luminance equalizer +!TP_BWMIX_CURVEEDITOR1;'Before' curve +!TP_BWMIX_CURVEEDITOR2;'After' curve +!TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Tone curve, after B&W conversion, at the end of treatment. +!TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Tone curve, just before B&W conversion.\nMay take into account the color components. +!TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H).\nPay attention to extreme values as they may cause artifacts. +!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. +!TP_BWMIX_MET_CHANMIX;Channel Mixer +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all the mixer options.\n"Total" displays the sum of the RGB values:\n- always 100% in relative mode\n- higher (lighter) or lower (darker) than 100% in absolute mode. +!TP_BWMIX_RGB_TOOLTIP;Mix the RGB channels. Use presets for guidance.\nPay attention to negative values that may cause artifacts or erratic behavior. +!TP_BWMIX_SET_HYPERPANCHRO;Hyper Panchromatic +!TP_BWMIX_SET_NORMCONTAST;Normal Contrast +!TP_BWMIX_SET_ORTHOCHRO;Orthochromatic +!TP_BWMIX_SET_RGBABS;Absolute RGB +!TP_BWMIX_SET_RGBREL;Relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Relative ROYGCBPM +!TP_BWMIX_TCMODE_SATANDVALBLENDING;B&W Saturation and Value Blending +!TP_BWMIX_TCMODE_WEIGHTEDSTD;B&W Weighted Standard +!TP_CHROMATABERR_LABEL;Chromatic Aberration +!TP_COLORAPP_ADAPTSCENE;Scene luminosity +!TP_COLORAPP_ADAPTSCENE_TOOLTIP;Absolute luminance of the scene environement (cd/m²).\n1) Calculated from the Exif data:\nShutter speed - ISO speed - F number - camera exposure correction.\n2) Calculated from the raw white point and RT's Exposure Compensation slider. +!TP_COLORAPP_ADAPTVIEWING;Viewing luminosity (cd/m²) +!TP_COLORAPP_ADAPTVIEWING_TOOLTIP;Absolute luminance of the viewing environnement\n(usually 16cd/m²). +!TP_COLORAPP_ADAP_AUTO_TOOLTIP;If the checkbox is checked (recommended) RawTherapee calculates an optimum value from Exif data.\nTo set the value manually, uncheck the checkbox first. +!TP_COLORAPP_ALGO;Algorithm +!TP_COLORAPP_ALGO_ALL;All +!TP_COLORAPP_ALGO_JC;Lightness + Chroma (JC) +!TP_COLORAPP_ALGO_JS;Lightness + Saturation (JS) +!TP_COLORAPP_ALGO_QM;Brightness + Colorfulness (QM) +!TP_COLORAPP_ALGO_TOOLTIP;Lets you choose between parameter subsets or all parameters. +!TP_COLORAPP_BADPIXSL;Hot/bad pixel filter +!TP_COLORAPP_BADPIXSL_TOOLTIP;Suppression of hot/bad (brightly colored) pixels.\n0 = No effect\n1 = Median\n2 = Gaussian.\nAlternatively, adjust the image to avoid very dark shadows.\n\nThese artifacts are due to limitations of CIECAM02. +!TP_COLORAPP_BRIGHT;Brightness (Q) +!TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from L*a*b* and RGB brightness. +!TP_COLORAPP_CHROMA;Chroma (C) +!TP_COLORAPP_CHROMA_M;Colorfulnes (M) +!TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM02 differs from L*a*b* and RGB colorfulness. +!TP_COLORAPP_CHROMA_S;Saturation (S) +!TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from L*a*b* and RGB saturation. +!TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from L*a*b* and RGB chroma. +!TP_COLORAPP_CIECAT_DEGREE;CAT02 adaptation +!TP_COLORAPP_CONTRAST;Contrast (J) +!TP_COLORAPP_CONTRAST_Q;Contrast (Q) +!TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrast in CIECAM02 for the Q slider; it differs from L*a*b* and RGB contrast. +!TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from L*a*b* and RGB contrast. +!TP_COLORAPP_CURVEEDITOR1;Tone curve 1 +!TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L* (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of J or Q after CIECAM02.\n\nJ and Q are not shown in the main histogram panel.\n\nFor final output refer to the main histogram panel. +!TP_COLORAPP_CURVEEDITOR2;Tone curve 2 +!TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Same usage as with the second exposure tone curve. +!TP_COLORAPP_CURVEEDITOR3;Color curve +!TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Adjust either chroma, saturation or colorfulness.\n\nShows the histogram of chromaticity (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of C, s or M after CIECAM02.\n\nC, s and M are not shown in the main histogram panel.\nFor final output refer to the main histogram panel. +!TP_COLORAPP_DATACIE;CIECAM02 output histograms in curves +!TP_COLORAPP_DATACIE_TOOLTIP;When enabled, histograms in CIECAM02 curves show approximate values/ranges for J or Q, and C, s or M after the CIECAM02 adjustments.\nThis selection does not impact the main histogram panel.\n\nWhen disabled, histograms in CIECAM02 curves show L*a*b* values before CIECAM02 adjustments. +!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RawTherapee calculates an optimum value, which is then used by CAT02, and also for the entire CIECAM02.\nTo set the value manually, uncheck the check-box first (values above 65 are recommended). +!TP_COLORAPP_DEGREE_TOOLTIP;Amount of CIE Chromatic Adaptation Transform 2002. +!TP_COLORAPP_GAMUT;Gamut control (L*a*b*) +!TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in L*a*b* mode. +!TP_COLORAPP_HUE;Hue (h) +!TP_COLORAPP_HUE_TOOLTIP;Hue (h) - angle between 0° and 360°. +!TP_COLORAPP_LABEL_SCENE;Scene Conditions +!TP_COLORAPP_LABEL_VIEWING;Viewing Conditions +!TP_COLORAPP_MODEL;WP Model +!TP_COLORAPP_MODEL_TOOLTIP;White-Point Model.\n\nWB [RT] + [output]: RT's white balance is used for the scene, CIECAM02 is set to D50, and the output device's white balance is set in Preferences > Color Management.\n\nWB [RT+CAT02] + [output]: RT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences - Color Management. +!TP_COLORAPP_RSTPRO;Red & skin-tones protection +!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin-tones protection affects both sliders and curves. +!TP_COLORAPP_SHARPCIE;--unused-- +!TP_COLORAPP_SHARPCIE_TOOLTIP;--unused-- +!TP_COLORAPP_SURROUND_EXDARK;Extremly Dark (Cutsheet) +!TP_COLORAPP_SURROUND_TOOLTIP;Changes tones and colors to take into account the viewing conditions of the output device.\n\nAverage: Average light environment (standard). The image will not change.\n\nDim: Dim environment (TV). The image will become slighty dark.\n\nDark: Dark environment (projector). The image will become more dark.\n\nExtremly Dark: Extremly dark environment (cutsheet). The image will become very dark. +!TP_COLORAPP_SURSOURCE;Dark surround +!TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if image has a dark border. +!TP_COLORAPP_TCMODE_CHROMA;Chroma +!TP_COLORAPP_TCMODE_COLORF;Colorfulness +!TP_COLORAPP_TCMODE_LABEL1;Curve mode 1 +!TP_COLORAPP_TCMODE_LABEL2;Curve mode 2 +!TP_COLORAPP_TCMODE_LABEL3;Curve chroma mode +!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] +!TP_COLORAPP_WBRT;WB [RT] + [output] +!TP_COLORTONING_AB;o C/L +!TP_COLORTONING_AUTOSAT;Automatic +!TP_COLORTONING_BALANCE;Balance +!TP_COLORTONING_BY;o C/L +!TP_COLORTONING_CHROMAC;Opacity +!TP_COLORTONING_COLOR;Color +!TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;Chroma opacity as a function of luminance oC=f(L) +!TP_COLORTONING_HIGHLIGHT;Highlights +!TP_COLORTONING_HUE;Hue +!TP_COLORTONING_LABEL;Color Toning +!TP_COLORTONING_LAB;L*a*b* blending +!TP_COLORTONING_LUMAMODE;Preserve luminance +!TP_COLORTONING_LUMAMODE_TOOLTIP;If enabled, when you change color (red, green, cyan, blue, etc.) the luminance of each pixel is preserved. +!TP_COLORTONING_LUMA;Luminance +!TP_COLORTONING_METHOD;Method +!TP_COLORTONING_METHOD_TOOLTIP;"L*a*b* blending", "RGB sliders" and "RGB curves" use interpolated color blending.\n"Color balance (Shadows/Midtones/Highlights)" and "Saturation 2 colors" use direct colors.\n\nThe Black-and-White tool can be enabled when using any color toning method, which allows for color toning. +!TP_COLORTONING_MIDTONES;Midtones +!TP_COLORTONING_NEUTRAL;Reset sliders +!TP_COLORTONING_NEUTRAL_TIP;Reset all values (Shadows, Midtones, Highlights) to default. +!TP_COLORTONING_OPACITY;Opacity +!TP_COLORTONING_RGBCURVES;RGB - Curves +!TP_COLORTONING_RGBSLIDERS;RGB - Sliders +!TP_COLORTONING_SATURATEDOPACITY;Strength +!TP_COLORTONING_SATURATIONTHRESHOLD;Threshold +!TP_COLORTONING_SA;Saturation Protection +!TP_COLORTONING_SHADOWS;Shadows +!TP_COLORTONING_SPLITCOCO;Color Balance Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITCO;Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITLR;Saturation 2 colors +!TP_COLORTONING_STRENGTH;Strength +!TP_COLORTONING_STR;Strength +!TP_COLORTONING_TWO2;Special chroma '2 colors' +!TP_COLORTONING_TWOALL;Special chroma +!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_33;3×3 strong +!TP_DIRPYRDENOISE_55SOFT;5×5 +!TP_DIRPYRDENOISE_55;5×5 strong +!TP_DIRPYRDENOISE_77;7×7 (slow) +!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_ABM;Chroma only +!TP_DIRPYRDENOISE_AUTO;Automatic global +!TP_DIRPYRDENOISE_AUTO_TOOLTIP;Try to evaluate chroma noise\nBe careful, this calculation is average, and is quite subjective ! +!TP_DIRPYRDENOISE_AUT;Automatic global +!TP_DIRPYRDENOISE_BLUE;Chrominance - Blue-Yellow +!TP_DIRPYRDENOISE_C2TYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CCCURVE;Chrominance curve +!TP_DIRPYRDENOISE_CHROMAFR;Chrominance +!TP_DIRPYRDENOISE_CHROMA;Chrominance - Master +!TP_DIRPYRDENOISE_CTYPE;Auto method +!TP_DIRPYRDENOISE_CTYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nAutomatic multi-zones\nNo preview - works only during saving, but using the "Preview" method by matching the tile size and center to the preview size and center you can get an idea of the expected results.\nThe image is divided into tiles (about 10 to 70 depending on image size) and each tile receives its own chrominance noise reduction settings.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CURVEEDITOR_CC;Chroma +!TP_DIRPYRDENOISE_CURVEEDITOR_CC_TOOLTIP;Increase (multiply) the value of all chrominance sliders.\nThis curve lets you adjust the strength of chromatic noise reduction as a function of chromaticity, for instance to increase the action in areas of low saturation and to decrease it in those of high saturation. +!TP_DIRPYRDENOISE_CURVEEDITOR_L_TOOLTIP;Modulates action of 'Luminance' denoise +!TP_DIRPYRDENOISE_CUR;Curve +!TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on the gamma of the input color profile. An sRGB gamma is assumed, thus if the image uses an input color profile of a different gamma, the effects of luminance noise reduction will differ. +!TP_DIRPYRDENOISE_ENH;Enhanced mode +!TP_DIRPYRDENOISE_ENH_TOOLTIP;Increases noise reduction quality at the expense of a 20% processing time increase. +!TP_DIRPYRDENOISE_GAMMA;Gamma +!TP_DIRPYRDENOISE_GAMMA_TOOLTIP;Gamma varies noise reduction strength across the range of tones. Smaller values will target shadows, while larger values will stretch the effect to the brighter tones. +!TP_DIRPYRDENOISE_LABM;L*a*b* +!TP_DIRPYRDENOISE_LCURVE;Luminance curve +!TP_DIRPYRDENOISE_LM;Luminance only +!TP_DIRPYRDENOISE_LPLABM;Weighted L* (little) + a*b* (normal) +!TP_DIRPYRDENOISE_LTYPE;Luminance control +!TP_DIRPYRDENOISE_LUMAFR;Luminance +!TP_DIRPYRDENOISE_LUMAFR_TOOLTIP;Wavelet on luminance and Fourier transform for luminance detail +!TP_DIRPYRDENOISE_MANU;Manual +!TP_DIRPYRDENOISE_MAN;Manual +!TP_DIRPYRDENOISE_MEDMETHOD;Median method +!TP_DIRPYRDENOISE_MEDTYPE;Median type +!TP_DIRPYRDENOISE_MED;Median Filter +!TP_DIRPYRDENOISE_MED_TOOLTIP;Enabled median denoising +!TP_DIRPYRDENOISE_METHOD11;Quality +!TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. +!TP_DIRPYRDENOISE_METHOD;Method +!TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or L*a*b* methods can be used.\n\nFor non-raw images the L*a*b* method will be used, regardless of the selection. +!TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - +!TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 +!TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. +!TP_DIRPYRDENOISE_PASSES;Median iterations +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PON;Auto multi-zones +!TP_DIRPYRDENOISE_PREVLABEL;Preview size=%1, Center: Px=%2 Py=%3 +!TP_DIRPYRDENOISE_PREV;Preview +!TP_DIRPYRDENOISE_PRE;Preview multi-zones +!TP_DIRPYRDENOISE_RED;Chrominance - Red-Green +!TP_DIRPYRDENOISE_RGBM;RGB +!TP_DIRPYRDENOISE_SHALBI;High +!TP_DIRPYRDENOISE_SHAL;Standard +!TP_DIRPYRDENOISE_SLI;Slider +!TP_DIRPYRDENOISE_SOFT;3x3 +!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_EPD_EDGESTOPPING;Edge stopping +!TP_EPD_GAMMA;Gamma +!TP_EPD_REWEIGHTINGITERATES;Reweighting iterates +!TP_EPD_TOOLTIP;Tone mapping is possible in L*a*b* mode (standard) and CIECAM02 mode.\n\nWhen in L*a*b* mode, tone mapping can also be used on the residual image of the Wavelet Levels tool.\n\nTo engage CIECAM02 tone mapping mode enable the following settings:\n1. CIECAM02\n2. Algorithm="Brightness + Colorfulness (QM)"\n3. "Tone mapping using CIECAM02 brightness (Q)" +!TP_EXPOSURE_AUTOLEVELS_TIP;Toggles execution of Auto Levels to automatically set Exposure slider values based on an image analysis.\nEnables Highlight Reconstruction if necessary. +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in Auto Levels operation. +!TP_EXPOSURE_TCMODE_LUMINANCE;Luminance +!TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points +!TP_EXPOS_WHITEPOINT_LABEL;Raw White Points +!TP_FILMSIMULATION_LABEL;Film Simulation +!TP_FILMSIMULATION_STRENGTH;Strength +!TP_FILMSIMULATION_ZEROCLUTSFOUND;Set HaldCLUT directory in Preferences +!TP_FLATFIELD_CLIPCONTROL;Clip control +!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. +!TP_GENERAL_11SCALE_TOOLTIP;The effects of this tool are only visible or only accurate at a preview scale of 1:1. +!TP_GRADIENT_CENTER_X_TOOLTIP;Shift gradient to the left (negative values) or right (positive values). +!TP_GRADIENT_CENTER_Y_TOOLTIP;Shift gradient up (negative values) or down (positive values). +!TP_GRADIENT_STRENGTH_TOOLTIP;Filter strength in stops. +!TP_HLREC_ENA_TOOLTIP;Could be activated by Auto Levels. +!TP_ICM_BLENDCMSMATRIX;Blend ICC highlights with matrix +!TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover clipped highlights when using LUT-based ICC profiles. +!TP_ICM_DCPILLUMINANT;Illuminant +!TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolated +!TP_ICM_DCPILLUMINANT_TOOLTIP;Select which embedded DCP illuminant to employ. Default is "interpolated" which is a mix between the two based on white balance. The setting is only enabled if a Dual-Illuminant DCP with interpolation support is selected. +!TP_ICM_INPUTCAMERAICC;Auto-matched camera profile +!TP_ICM_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input color profiles. These profiles are more precise than simpler matrix ones. They are not available for all cameras. These profiles are stored in the /iccprofiles/input and /dcpprofiles folders and are automatically retrieved based on a file name matching to the exact model name of the camera. +!TP_ICM_INPUTCAMERA_TOOLTIP;Use a simple color matrix from dcraw, an enhanced RawTherapee version (whichever is available based on camera model) or one embedded in the DNG. +!TP_ICM_INPUTNONE_TOOLTIP;Use no input color profile at all.\nUse only in special cases. +!TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance +!TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. The result can be used for calibration purposes and generation of a camera profile. +!TP_ICM_TONECURVE_TOOLTIP;Employ the embedded DCP tone curve. The setting is only enabled if the selected DCP has a tone curve. +!TP_LABCURVE_CHROMA_TOOLTIP;To apply B&W toning, set Chromaticity to -100. +!TP_LABCURVE_CURVEEDITOR_A_RANGE1;Green Saturated +!TP_LABCURVE_CURVEEDITOR_A_RANGE2;Green Pastel +!TP_LABCURVE_CURVEEDITOR_A_RANGE3;Red Pastel +!TP_LABCURVE_CURVEEDITOR_A_RANGE4;Red Saturated +!TP_LABCURVE_CURVEEDITOR_B_RANGE1;Blue Saturated +!TP_LABCURVE_CURVEEDITOR_B_RANGE2;Blue Pastel +!TP_LABCURVE_CURVEEDITOR_B_RANGE3;Yellow Pastel +!TP_LABCURVE_CURVEEDITOR_B_RANGE4;Yellow Saturated +!TP_LABCURVE_CURVEEDITOR_CC;CC +!TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutral +!TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Dull +!TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastel +!TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Saturated +!TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Chromaticity according to chromaticity C=f(C) +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to hue C=f(H) +!TP_LABCURVE_CURVEEDITOR_CL;CL +!TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Chromaticity according to luminance C=f(L) +!TP_LABCURVE_CURVEEDITOR_HH;HH +!TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Hue according to hue H=f(H) +!TP_LABCURVE_CURVEEDITOR_LC;LC +!TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminance according to chromaticity L=f(C) +!TP_LABCURVE_CURVEEDITOR_LH;LH +!TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H) +!TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminance according to luminance L=f(L) +!TP_LABCURVE_LCREDSK;Restrict LC to red and skin-tones +!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_NEUTRAL_TIP;Resets exposure sliders to neutral values.\nApplies to the same controls that Auto Levels applies to, regardless of whether you used Auto Levels or not. +!TP_PCVIGNETTE_FEATHER_TOOLTIP;Feathering:\n0 = corners only,\n50 = halfway to center,\n100 = to center. +!TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness:\n0 = rectangle,\n50 = fitted ellipse,\n100 = circle. +!TP_PFCURVE_CURVEEDITOR_CH;Hue +!TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Controls defringe strength by color.\nHigher = more,\nLower = less. +!TP_PREPROCESS_DEADPIXFILT;Dead pixel filter +!TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Tries to suppress dead pixels. +!TP_PREPROCESS_GREENEQUIL;Green equilibration +!TP_PREPROCESS_HOTPIXFILT;Hot pixel filter +!TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Tries to suppress hot pixels. +!TP_RAWEXPOS_BLACKS;Black Levels +!TP_RAWEXPOS_BLACK_0;Green 1 (lead) +!TP_RAWEXPOS_BLACK_1;Red +!TP_RAWEXPOS_BLACK_2;Blue +!TP_RAWEXPOS_BLACK_3;Green 2 +!TP_RAWEXPOS_BLACK_BLUE;Blue +!TP_RAWEXPOS_BLACK_GREEN;Green +!TP_RAWEXPOS_BLACK_RED;Red +!TP_RAWEXPOS_LINEAR;White-point correction +!TP_RAWEXPOS_PRESER;Highlight preservation +!TP_RAWEXPOS_RGB;Red, Green, Blue +!TP_RAWEXPOS_TWOGREEN;Link greens +!TP_RAW_DCBENHANCE;DCB enhancement +!TP_RAW_DCBITERATIONS;Number of DCB iterations +!TP_RAW_DMETHOD;Method +!TP_RAW_DMETHOD_PROGRESSBAR;%1 demosaicing... +!TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Demosaicing refinement... +!TP_RAW_DMETHOD_TOOLTIP;Note: IGV and LMMSE are dedicated to high ISO images to aid in noise reduction without leading to maze patterns, posterization or a washed-out look. +!TP_RAW_FALSECOLOR;False color suppression steps +!TP_RAW_HD;Threshold +!TP_RAW_HD_TOOLTIP;Lower values make hot/dead pixel detection more aggressive, but false positives may lead to artifacts. If you notice any artifacts appearing when enabling the Hot/Dead Pixel Filters, gradually increase the threshold value until they disappear. +!TP_RAW_LABEL;Demosaicing +!TP_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!TP_RAW_LMMSE_TOOLTIP;Adds gamma (step 1), median (steps 2-4) and refinement (steps 5-6) to reduce artifacts and improve the signal-to-noise ratio. +!TP_RAW_SENSOR_BAYER_LABEL;Sensor with Bayer Matrix +!TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;3-pass gives best results (recommended for low ISO images).\n1-pass is almost undistinguishable from 3-pass for high ISO images and is faster. +!TP_RAW_SENSOR_XTRANS_LABEL;Sensor with X-Trans Matrix +!TP_RESIZE_APPLIESTO;Applies to: +!TP_SHARPENING_TOOLTIP;Expect a slightly different effect when using with CIECAM02. If difference is observed, adjust to taste. +!TP_SHARPENMICRO_LABEL;Microcontrast +!TP_SHARPENMICRO_MATRIX;3×3 matrix instead of 5×5 +!TP_SHARPENMICRO_UNIFORMITY;Uniformity +!TP_VIBRANCE_AVOIDCOLORSHIFT;Avoid color shift +!TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Red/Purple +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Red +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Red/Yellow +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Yellow +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Hue according to hue H=f(H) +!TP_VIBRANCE_LABEL;Vibrance +!TP_VIBRANCE_PASTELS;Pastel Tones +!TP_VIBRANCE_PASTSATTOG;Link pastel and saturated tones +!TP_VIBRANCE_PROTECTSKINS;Protect skin-tones +!TP_VIBRANCE_PSTHRESHOLD;Pastel/saturated tones threshold +!TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Saturation threshold +!TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;The vertical axis represents pastel tones at the bottom and saturated tones at the top.\nThe horizontal axis represents the saturation range. +!TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Pastel/saturated transition's weighting +!TP_VIBRANCE_SATURATED;Saturated Tones +!TP_WAVELET_1;Level 1 +!TP_WAVELET_2;Level 2 +!TP_WAVELET_3;Level 3 +!TP_WAVELET_4;Level 4 +!TP_WAVELET_5;Level 5 +!TP_WAVELET_6;Level 6 +!TP_WAVELET_7;Level 7 +!TP_WAVELET_8;Level 8 +!TP_WAVELET_9;Level 9 +!TP_WAVELET_ALL;All levels in all directions +!TP_WAVELET_APPLYTO;Apply To +!TP_WAVELET_AVOID;Avoid color shift +!TP_WAVELET_B0;Black +!TP_WAVELET_B1;Grey +!TP_WAVELET_B2;Residual +!TP_WAVELET_BACUR;Curve +!TP_WAVELET_BALANCE;Contrast balance d/v-h +!TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chromaticity or residual tone mapping are activated, the effect due to balance is amplified. +!TP_WAVELET_BALCHRO;Chroma balance +!TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chromaticity balance. +!TP_WAVELET_BANONE;None +!TP_WAVELET_BASLI;Slider +!TP_WAVELET_BATYPE;Contrast balance method +!TP_WAVELET_CCURVE;Local contrast +!TP_WAVELET_CH1;Whole chromaticity range +!TP_WAVELET_CH2;Saturated/pastel +!TP_WAVELET_CH3;Link contrast levels +!TP_WAVELET_CHCU;Curve +!TP_WAVELET_CHRO;Saturated/pastel threshold +!TP_WAVELET_CHRO_TOOLTIP;Sets the wavelet level which will be the threshold between saturated and pastel colors.\n1-x: saturated\nx-9: pastel\n\nIf the value exceeds the amount of wavelet levels you are using then it will be ignored. +!TP_WAVELET_CHR;Chroma-contrast link strength +!TP_WAVELET_CHR_TOOLTIP;Adjusts chromaticity as a function of "contrast levels" and "chroma-contrast link strength" +!TP_WAVELET_CHSL;Sliders +!TP_WAVELET_CHTYPE;Chrominance method +!TP_WAVELET_COLORT;Opacity Red-Green +!TP_WAVELET_COMBOTH;Both +!TP_WAVELET_COMPCONT;Contrast +!TP_WAVELET_COMPGAMMA;Compression gamma +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjusting the gamma of the residual image allow you to equilibrate the data and histogram. +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjust gamma for residual image and compression.\nAllow to equilibrate data and histogram +!TP_WAVELET_COMPTM;Tone mapping +!TP_WAVELET_CONTEDIT;'After' Contrast curve +!TP_WAVELET_CONTEDIT;'After' contrast curve +!TP_WAVELET_CONTRAST_MINUS;Contrast - +!TP_WAVELET_CONTRAST_PLUS;Contrast + +!TP_WAVELET_CONTRA;Contrast +!TP_WAVELET_CONTRA_TOOLTIP;Changes contrast of the residual image. +!TP_WAVELET_CONTR;Gamut +!TP_WAVELET_CTYPE;Chrominance control +!TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modifies local contrast as a function of the original local contrast (absciss)\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 100..300)\n66% absciss represents standard deviation of local contrast (real value about 300..800)\n100% represents maximum (real value about 3000..8000) +!TP_WAVELET_CURVEEDITOR_CH;Contrast levels=f(Hue) +!TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modifies each level's contrast as a function oh hue.\nTake care not to overwrite changes made with the Gamut Hue controls.\nThe curve will only have an effect when wavelet contrast level sliders are non-zero. +!TP_WAVELET_CURVEEDITOR_CL;L +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Applies a final contrast luminance curve at the end of the wavelet treatment. +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Apply a contrast luminance curve at the end of wavelet level threatment +!TP_WAVELET_CURVEEDITOR_HH;HH +!TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modifies the residual image's hue as a function of hue. +!TP_WAVELET_DALL;All directions +!TP_WAVELET_DAUB;Edge performance +!TP_WAVELET_DAUB_TOOLTIP;Changes Daubechies coefficients:\nD4 = Standard,\nD14 = Often best performance, 10% more time-intensive.\n\nAffects edge detection as well as the general quality of the firsts levels. However the quality is not strictly related to this coefficient and can vary with images and uses. +!TP_WAVELET_DISP;Preview Settings +!TP_WAVELET_DONE;Vertical +!TP_WAVELET_DTHR;Diagonal +!TP_WAVELET_DTWO;Horizontal +!TP_WAVELET_EDCU;Curve +!TP_WAVELET_EDGCONT;Local contrast +!TP_WAVELET_EDGCONT_TOOLTIP;Adjusting the points to the left decreases contrast, and to the right increases it.\nBottom-left, Top-Left, Top-Right, Bottom-right represent respectively local contast for low values, mean, mean+stdev, maxima +!TP_WAVELET_EDGEDETECTTHR2;Threshold high (detection) +!TP_WAVELET_EDGEDETECTTHR;Threshold low (noise) +!TP_WAVELET_EDGEDETECTTHR_TOOLTIP;This adjuster lets you target edge detection for example to avoid applying edge sharpness to fine details, such as noise in the sky. +!TP_WAVELET_EDGEDETECT;Gradient sensitivity +!TP_WAVELET_EDGEDETECT_TOOLTIP;Moving the slider to the right increases edge sensitivity. This affects local contrast, edge settings and noise. +!TP_WAVELET_EDGE;Edge Sharpness +!TP_WAVELET_EDGREINF_TOOLTIP;Reinforce or reduce the action of the first level, do the opposite to the second level, and leave the rest unchanged. +!TP_WAVELET_EDGTHRESH;Detail +!TP_WAVELET_EDGTHRESH_TOOLTIP;Change the repartition between the first levels and the others. The higher the threshold the more the action is centred on the first levels. Be careful with negative values, they increase the action of high levels and can introduce artifacts. +!TP_WAVELET_EDRAD;Radius +!TP_WAVELET_EDRAD_TOOLTIP;This radius adjustment is very different from those in other sharpening tools. Its value is compared to each level through a complex function. In this sense, a value of zero still has an effect. +!TP_WAVELET_EDSL;Threshold Sliders +!TP_WAVELET_EDTYPE;Local contrast method +!TP_WAVELET_EDVAL;Strength +!TP_WAVELET_FINAL;Final Touchup +!TP_WAVELET_FINEST;Finest +!TP_WAVELET_HIGHLIGHT;Highlight luminance range +!TP_WAVELET_HS1;Whole luminance range +!TP_WAVELET_HS2;Shadows/Highlights +!TP_WAVELET_HUESKIN;Skin hue +!TP_WAVELET_HUESKIN_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_HUESKY;Sky hue +!TP_WAVELET_HUESKY_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_INF;Below or equal the level +!TP_WAVELET_ITER;Delta balance levels +!TP_WAVELET_ITER_TOOLTIP;Left: increase low levels and reduce high levels,\nRight: reduce low levels and increase high levels. +!TP_WAVELET_LABEL;Wavelet levels +!TP_WAVELET_LARGEST;Coarsest +!TP_WAVELET_LEVCH;Chromaticity +!TP_WAVELET_LEVELS;Wavelet levels +!TP_WAVELET_LEVELS_TOOLTIP;Choose the number of detail levels the image is to be decomposed into. More levels require more RAM and require a longer processing time. +!TP_WAVELET_LEVF;Contrast +!TP_WAVELET_LEVLABEL;Preview maximum possible levels = %1 +!TP_WAVELET_LEVONE;Level 2 +!TP_WAVELET_LEVTWO;Level 3 +!TP_WAVELET_LEVZERO;Level 1 +!TP_WAVELET_LINKEDG;Link with Edge Sharpness' Strength +!TP_WAVELET_LIPST;Enhanced algorithm +!TP_WAVELET_LIPST_TOOLTIP;This algorithm uses Lipschitz regularity to increase edge detection quality at a cost of increased processing time and memory requirements. +!TP_WAVELET_LOWLIGHT;Shadow luminance range +!TP_WAVELET_MEDGREINF;First level +!TP_WAVELET_MEDILEV;Edge detection +!TP_WAVELET_MEDI;Reduce artifacts in blue sky +!TP_WAVELET_NEUTRAL;Neutral +!TP_WAVELET_NOISE;Denoise and Refine +!TP_WAVELET_NOIS;Denoise +!TP_WAVELET_ONE;One level +!TP_WAVELET_OPACITYWL;Final local contrast +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify final local contrast in function of last local contrast (absciss) for all levels decomposition\nTake into account: \na)contrast levels \nb)edge sharpness \nc)contrast balance\nd)decomposition-recomposition\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 200..1000)\n66% absciss represents standard deviation of local contrast (real value about 1000..2000)\n100% represents maximum (real value about 5000..13000) +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify the final local contrast at the end of the wavelet treatment.\n\nThe left side represents the smallest local contrast, progressing to the largest local contrast on the right. +!TP_WAVELET_OPACITYW;Contrast balance d/v-h curve +!TP_WAVELET_OPACITY;Opacity Blue-Yellow +!TP_WAVELET_PASTEL;Pastel chromaticity +!TP_WAVELET_PREVIEWBACK;Background +!TP_WAVELET_PREVIEWLEVELS;Preview +!TP_WAVELET_RE1;Reinforced +!TP_WAVELET_RE2;Unchanged +!TP_WAVELET_RE3;Reduced +!TP_WAVELET_RESCHRO;Chromaticity +!TP_WAVELET_RESCONH;Highlights +!TP_WAVELET_RESCON;Shadows +!TP_WAVELET_RESID;Residual image +!TP_WAVELET_SAT;Saturated chromaticity +!TP_WAVELET_SETTINGS;Wavelet Settings +!TP_WAVELET_SKIN;Skin targetting/protection +!TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected. +!TP_WAVELET_SKY;Sky targetting/protection +!TP_WAVELET_SKY_TOOLTIP;At -100 sky-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 sky-tones are protected while all other tones are affected. +!TP_WAVELET_STRENGTH;Strength +!TP_WAVELET_STREN;Strength +!TP_WAVELET_SUPE;Extra +!TP_WAVELET_SUP;Above the level +!TP_WAVELET_THRESHOLD2;Shadow levels +!TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels between 9 and 9 minus the value will be affected by the shadow luminance range. Other levels will be fully treated. The highest level possible is limited by the highlight level value (9 minus highlight level value). +!TP_WAVELET_THRESHOLD;Highlight levels +!TP_WAVELET_THRESHOLD_TOOLTIP;Only levels beyond the chosen value will be affected by the highlight luminance range. Other levels will be fully treated. The chosen value here limits the highest possible value of the shadow levels. +!TP_WAVELET_THRH;Highlights threshold +!TP_WAVELET_THR;Shadows threshold +!TP_WAVELET_TILESBIG;Big tiles +!TP_WAVELET_TILESFULL;Full image +!TP_WAVELET_TILESIZE;Tiling method +!TP_WAVELET_TILESLIT;Little tiles +!TP_WAVELET_TILES_TOOLTIP;Processing the full image leads to better quality and is the recommended option, while using tiles is a fall-back solution for users with little RAM. Refer to RawPedia for memory requirements. +!TP_WAVELET_TMHIGH;High +!TP_WAVELET_TMLOWHIGH;Low+High +!TP_WAVELET_TMNONE;None +!TP_WAVELET_TMSTD;Standard +!TP_WAVELET_TMSTRENGTH;Compression strength +!TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image. When the value is different from 0, the Strength and Gamma sliders of the Tone Mapping tool in the Exposure tab will become grayed out. +!TP_WAVELET_TMTYPE;Compression method +!TP_WAVELET_TON;Toning +!TP_WAVELET_daub2;D2 - low +!TP_WAVELET_daub4;D4 - standard +!TP_WAVELET_daub6;D6 - standard plus +!TP_WAVELET_daub10;D10 - medium +!TP_WAVELET_daub14;D14 - high +!TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behavior of "white balance" by modulating the blue/red balance.\nThis can be useful when shooting conditions:\na) are far from the standard illuminant (e.g. underwater),\nb) are far from conditions where calibrations were performed,\nc) where the matrices or ICC profiles are unsuitable. +!TP_WBALANCE_FLASH60;Standard, Canon, Pentax, Olympus +!TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta +!TP_WBALANCE_FLUO1;F1 - Daylight +!TP_WBALANCE_FLUO2;F2 - Cool White +!TP_WBALANCE_FLUO3;F3 - White +!TP_WBALANCE_FLUO4;F4 - Warm White +!TP_WBALANCE_FLUO5;F5 - Daylight +!TP_WBALANCE_FLUO6;F6 - Lite White +!TP_WBALANCE_FLUO7;F7 - D65 Daylight Simulator +!TP_WBALANCE_FLUO8;F8 - D50 / Sylvania F40 Design +!TP_WBALANCE_FLUO9;F9 - Cool White Deluxe +!TP_WBALANCE_FLUO10;F10 - Philips TL85 +!TP_WBALANCE_FLUO11;F11 - Philips TL84 +!TP_WBALANCE_FLUO12;F12 - Philips TL83 +!TP_WBALANCE_FLUO_HEADER;Fluorescent +!TP_WBALANCE_GTI;GTI +!TP_WBALANCE_HMI;HMI +!TP_WBALANCE_JUDGEIII;JudgeIII +!TP_WBALANCE_LAMP_HEADER;Lamp +!TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 +!TP_WBALANCE_LED_LSI;LSI Lumelex 2040 +!TP_WBALANCE_SOLUX47;Solux 4700K (vendor) +!TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) +!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) new file mode 100644 index 000000000..4eb4ff3ed --- /dev/null +++ b/rtdata/languages/Chinese (Traditional) @@ -0,0 +1,1858 @@ +#00 Chinese (Traditional) +#01 2008-07-29 Mingjui Liao + +ADJUSTER_RESET_TO_DEFAULT;重置預設參數 +BATCHQUEUE_AUTOSTART;Auto start +CURVEEDITOR_LINEAR;線性 +CURVEEDITOR_LOADDLGLABEL;正載入曲線... +CURVEEDITOR_SAVEDLGLABEL;正儲存曲線... +CURVEEDITOR_TOOLTIPLINEAR;重置曲線 +CURVEEDITOR_TOOLTIPLOAD;載入曲線 +CURVEEDITOR_TOOLTIPSAVE;儲存曲線 +DIRBROWSER_FOLDERS;文件夾 +EXIFFILTER_APERTURE;Aperture +EXIFFILTER_CAMERA;Camera +EXIFFILTER_FOCALLEN;Focal Length +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Lens +EXIFFILTER_SHUTTER;Shutter +EXIFPANEL_ADDEDITHINT;Add new tag or edit tag +EXIFPANEL_ADDEDIT;Add/Edit +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Enter value +EXIFPANEL_ADDTAGDLG_SELECTTAG;Select tag +EXIFPANEL_ADDTAGDLG_TITLE;Add/Edit Tag +EXIFPANEL_KEEPHINT;Keep the selected tags when writing output file +EXIFPANEL_KEEP;Keep +EXIFPANEL_REMOVEHINT;Remove the selected tags when writing output file +EXIFPANEL_REMOVE;Remove +EXIFPANEL_RESETALLHINT;Reset all tags to their original values +EXIFPANEL_RESETALL;Reset All +EXIFPANEL_RESETHINT;Reset the selected tags to their original values +EXIFPANEL_RESET;Reset +EXIFPANEL_SUBDIRECTORY;Subdirectory +FILEBROWSER_APPLYPROFILE;Apply profile +FILEBROWSER_CLEARPROFILE;Clear profile +FILEBROWSER_COPYPROFILE;Copy profile +FILEBROWSER_DELETEDLGLABEL;File delete confirmation +FILEBROWSER_DELETEDLGMSG;Are you sure you want to delete the selected %1 files? +FILEBROWSER_EMPTYTRASHHINT;Permanently delete the files of the trash +FILEBROWSER_EMPTYTRASH;Empty Trash +FILEBROWSER_PARTIALPASTEPROFILE;Partial paste +FILEBROWSER_PASTEPROFILE;Paste profile +FILEBROWSER_POPUPCANCELJOB;Cancel job +FILEBROWSER_POPUPMOVEEND;Move to end of queue +FILEBROWSER_POPUPMOVEHEAD;Move to head of queue +FILEBROWSER_POPUPOPENINEDITOR;Open in Editor +FILEBROWSER_POPUPOPEN;Open +FILEBROWSER_POPUPPROCESS;Put to processing queue +FILEBROWSER_POPUPREMOVE;Remove from filesystem +FILEBROWSER_POPUPRENAME;Rename +FILEBROWSER_POPUPSELECTALL;Select all +FILEBROWSER_POPUPTRASH;Move to trash +FILEBROWSER_POPUPUNRANK;Unrank +FILEBROWSER_POPUPUNTRASH;Remove from trash +FILEBROWSER_RENAMEDLGLABEL;Rename file +FILEBROWSER_RENAMEDLGMSG;Rename file "%1" to: +FILEBROWSER_SHOWDIRHINT;Show all images of the directory +FILEBROWSER_SHOWRANK1HINT;Show images ranked as 1 star +FILEBROWSER_SHOWRANK2HINT;Show images ranked as 2 star +FILEBROWSER_SHOWRANK3HINT;Show images ranked as 3 star +FILEBROWSER_SHOWRANK4HINT;Show images ranked as 4 star +FILEBROWSER_SHOWRANK5HINT;Show images ranked as 5 star +FILEBROWSER_SHOWTRASHHINT;Show content of the trash +FILEBROWSER_SHOWUNRANKHINT;Show unranked images +FILEBROWSER_STARTPROCESSINGHINT;Start processing/saving of images in the queue +FILEBROWSER_STARTPROCESSING;Start Processing +FILEBROWSER_STOPPROCESSINGHINT;Stop processing of images +FILEBROWSER_STOPPROCESSING;Stop processing +FILEBROWSER_THUMBSIZE;Thumb. size +FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives +FILEBROWSER_ZOOMINHINT;Increase thumbnail size +FILEBROWSER_ZOOMOUTHINT;Decrease thumbnail size +GENERAL_ABOUT;關於 +GENERAL_AFTER;After +GENERAL_BEFORE;Before +GENERAL_CANCEL;取消 +GENERAL_DISABLED;已關閉 +GENERAL_DISABLE;關閉 +GENERAL_ENABLED;已開啟 +GENERAL_ENABLE;啟用 +GENERAL_LANDSCAPE;橫向 +GENERAL_NA;不適用 +GENERAL_NO;否 +GENERAL_OK;確定 +GENERAL_PORTRAIT;縱向 +GENERAL_SAVE;儲存存 +GENERAL_UNCHANGED;(Unchanged) +HISTOGRAM_TOOLTIP_B;顯示/隱藏 藍色直方圖 +HISTOGRAM_TOOLTIP_G;顯示/隱藏 綠色直方圖 +HISTOGRAM_TOOLTIP_L;顯示/隱藏e CIELAB 亮度直方圖 +HISTOGRAM_TOOLTIP_R;顯示/隱藏 紅色直方圖 +HISTORY_CHANGED;Changed +HISTORY_CUSTOMCURVE;自定義曲線 +HISTORY_DELSNAPSHOT;移除快照 +HISTORY_FROMCLIPBOARD;From clipboard +HISTORY_LABEL;歷史 +HISTORY_MSG_1;圖片載入完 +HISTORY_MSG_2;配置載入完 +HISTORY_MSG_3;配置改變 +HISTORY_MSG_4;歷史流覽 +HISTORY_MSG_5;亮度 +HISTORY_MSG_6;對比度 +HISTORY_MSG_7;黑 +HISTORY_MSG_8;曝光補償 +HISTORY_MSG_9;亮部壓縮 +HISTORY_MSG_10;暗部壓縮 +HISTORY_MSG_11;色調曲線 +HISTORY_MSG_12;自動曝光 +HISTORY_MSG_13;曝光溢出 +HISTORY_MSG_14;光強亮度 +HISTORY_MSG_15;光強對比度 +HISTORY_MSG_16;光強黑 +HISTORY_MSG_17;光強亮部壓縮 +HISTORY_MSG_18;光強暗部壓縮 +HISTORY_MSG_19;光強曲線 +HISTORY_MSG_20;銳化 +HISTORY_MSG_21;銳化半徑 +HISTORY_MSG_22;銳化程度 +HISTORY_MSG_23;銳化闕值 +HISTORY_MSG_24;僅銳化邊緣 +HISTORY_MSG_25;銳化邊緣半徑 +HISTORY_MSG_26;銳化邊緣容差 +HISTORY_MSG_27;銳化光暈控制 +HISTORY_MSG_28;光暈控制量 +HISTORY_MSG_29;銳化方式 +HISTORY_MSG_30;重疊半徑 +HISTORY_MSG_31;重疊程度 +HISTORY_MSG_32;重疊衰減 +HISTORY_MSG_33;重疊次數 +HISTORY_MSG_34;避免色彩溢出 +HISTORY_MSG_35;飽和度限制器 +HISTORY_MSG_36;飽和度限制 +HISTORY_MSG_37;色彩增益 +HISTORY_MSG_38;拍平衡方式 +HISTORY_MSG_39;色溫 +HISTORY_MSG_40;白平衡微調 +HISTORY_MSG_41;色彩偏移 "A" +HISTORY_MSG_42;色彩偏移 "B" +HISTORY_MSG_43;光強降噪 +HISTORY_MSG_44;光強降噪半徑 +HISTORY_MSG_45;光強降噪邊緣容差 +HISTORY_MSG_46;色彩降噪 +HISTORY_MSG_47;色彩降噪半徑 +HISTORY_MSG_48;色彩降噪邊緣容差 +HISTORY_MSG_49;色彩降噪邊緣敏感度 +HISTORY_MSG_50;暗部/亮部工具 +HISTORY_MSG_51;亮部增益 +HISTORY_MSG_52;暗部增益 +HISTORY_MSG_53;亮部色度範圍 +HISTORY_MSG_54;暗部色度範圍 +HISTORY_MSG_55;局部對比度 +HISTORY_MSG_56;暗部/亮部半徑 +HISTORY_MSG_57;粗略旋轉 +HISTORY_MSG_58;水準翻轉 +HISTORY_MSG_59;豎直翻轉 +HISTORY_MSG_60;旋轉 +HISTORY_MSG_61;旋轉 +HISTORY_MSG_62;鏡頭失真矯正 +HISTORY_MSG_63;設置書簽 +HISTORY_MSG_64;剪切圖片 +HISTORY_MSG_65;C/A矯正 +HISTORY_MSG_66;高光還原 +HISTORY_MSG_67;高光還原程度 +HISTORY_MSG_68;高光還原方式 +HISTORY_MSG_69;工作色彩空間 +HISTORY_MSG_70;輸出色彩空間 +HISTORY_MSG_71;輸入色參空間 +HISTORY_MSG_72;邊暈矯正 +HISTORY_MSG_73;通道混合器 +HISTORY_MSG_74;調整大小比例 +HISTORY_MSG_75;調整大小方式 +HISTORY_MSG_76;Exif Metadata +HISTORY_MSG_77;IPTC Metadata +HISTORY_MSG_78;Data specified for resize +HISTORY_MSG_79;Resize width +HISTORY_MSG_80;Resize height +HISTORY_MSG_81;Resize enabled +HISTORY_NEWSNAPSHOT;新建快照 +HISTORY_SNAPSHOTS;系列快照 +HISTORY_SNAPSHOT;快照 +IPTCPANEL_AUTHORSPOSITIONHINT;Title of the creator or creators of the object (By-line Title). +IPTCPANEL_AUTHORSPOSITION;Author's position +IPTCPANEL_AUTHOR;Author +IPTCPANEL_CAPTIONHINT;A textual description of the data (Caption - Abstract) +IPTCPANEL_CAPTIONWRITERHINT;The name of the person involved in the writing, editing or correcting the image or caption/abstract (Writer - Editor +IPTCPANEL_CAPTIONWRITER;Caption Writer +IPTCPANEL_CAPTION;Caption +IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider (Category). +IPTCPANEL_CATEGORY;Category +IPTCPANEL_CITYHINT;City of image origin (City). +IPTCPANEL_CITY;City +IPTCPANEL_COPYHINT;Copy IPTC settings to clipboard +IPTCPANEL_COPYRIGHTHINT;Any necessary copyright notice (Copyright Notice). +IPTCPANEL_COPYRIGHT;Copyright +IPTCPANEL_COUNTRYHINT;The name of the country/primary location where the image was created (Country - Primary Location Name). +IPTCPANEL_COUNTRY;Country +IPTCPANEL_CREDITHINT;Identifies the provider of the image, not necessarily the owner/creator (Credit). +IPTCPANEL_CREDIT;Credit +IPTCPANEL_DATECREATEDHINT;The date the intellectual content of the image was created; Format: JJJJMMTT (Date Created). +IPTCPANEL_DATECREATED;Date Created +IPTCPANEL_EMBEDDEDHINT;Reset to IPTC data embedded in the image file +IPTCPANEL_EMBEDDED;Embedded +IPTCPANEL_HEADLINEHINT;A publishable entry providing a synopsis of the contents of the image (Headline). +IPTCPANEL_HEADLINE;Headline +IPTCPANEL_INSTRUCTIONSHINT;Other editorial instructions concerning the use of the image (Special Instructions). +IPTCPANEL_INSTRUCTIONS;Instructions +IPTCPANEL_KEYWORDSHINT;Used to indicate specific information retrieval words (keywords). +IPTCPANEL_KEYWORDS;Keywords +IPTCPANEL_PASTEHINT;Paste IPTC settings from clipboard +IPTCPANEL_PROVINCEHINT;The Province/State where the image originates (Province-State). +IPTCPANEL_PROVINCE;Province +IPTCPANEL_RESETHINT;Reset to profile default +IPTCPANEL_RESET;Reset +IPTCPANEL_SOURCEHINT;The original owner of the intellectual content of the image (Source). +IPTCPANEL_SOURCE;Source +IPTCPANEL_SUPPCATEGORIESHINT;Further refines the subject of the image (Supplemental Categories). +IPTCPANEL_SUPPCATEGORIES;Suppl. Categories +IPTCPANEL_TITLEHINT;A shorthand reference for the image (Object Name). +IPTCPANEL_TITLE;Title +IPTCPANEL_TRANSREFERENCEHINT;A code representing the location of original transmission (Original Transmission Reference). +IPTCPANEL_TRANSREFERENCE;Trans. Reference +MAIN_BUTTON_PREFERENCES;參數設置 +MAIN_BUTTON_PUTTOQUEUE;Put to queue +MAIN_BUTTON_SAVE;儲存圖片 +MAIN_BUTTON_SENDTOEDITOR;Send to editor +MAIN_FRAME_BATCHQUEUE;Batch Queue +MAIN_FRAME_FILEBROWSER;File Browser +MAIN_FRAME_PLACES;Places +MAIN_FRAME_PLACES_ADD;Add +MAIN_FRAME_PLACES_DEL;Del +MAIN_FRAME_RECENT;Recent Folders +MAIN_MSG_ALREADYEXISTS;該文件已存在. +MAIN_MSG_CANNOTLOAD;無法載入圖片 +MAIN_MSG_CANNOTSAVE;檔儲存中出錯 +MAIN_MSG_CANNOTSTARTEDITOR;Can not start editor. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Please set the correct path in the "Preferences" dialog. +MAIN_MSG_NAVIGATOR;Navigator +MAIN_MSG_QOVERWRITE;是否覆蓋? +MAIN_TAB_COLOR;Color +MAIN_TAB_DETAIL;Detail +MAIN_TAB_DEVELOP;Develop +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;Exposure +MAIN_TAB_FILTER;Filter +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadata +MAIN_TAB_TRANSFORM;轉換 +MAIN_TOOLTIP_HIDEHP;顯示/隱藏左面板 (包含歷史, shortcut key: H)) +MAIN_TOOLTIP_INDCLIPPEDH;高光溢出提示 +MAIN_TOOLTIP_INDCLIPPEDS;暗部不足提示 +MAIN_TOOLTIP_QINFO;圖片快捷資訊 +MAIN_TOOLTIP_TOGGLE;Toggle before/after view +PARTIALPASTE_BASICGROUP;Basic settings +PARTIALPASTE_CACORRECTION;C/A correction +PARTIALPASTE_COARSETRANS;90 deg rotation / flipping +PARTIALPASTE_COLORGROUP;Color related settings +PARTIALPASTE_COMPOSITIONGROUP;Composition settings +PARTIALPASTE_CROP;Crop +PARTIALPASTE_DIALOGLABEL;Partial paste processing profile +PARTIALPASTE_DISTORTION;Distortion correction +PARTIALPASTE_EXIFCHANGES;Changes to exif data +PARTIALPASTE_EXPOSURE;Exposure +PARTIALPASTE_ICMSETTINGS;ICM settings +PARTIALPASTE_IPTCINFO;IPTC info +PARTIALPASTE_LENSGROUP;Lens related settings +PARTIALPASTE_METAGROUP;Metadata +PARTIALPASTE_RESIZE;Resize +PARTIALPASTE_ROTATION;Rotation +PARTIALPASTE_SHADOWSHIGHLIGHTS;Shadows/Highlights +PARTIALPASTE_SHARPENING;Sharpening +PARTIALPASTE_VIGNETTING;Vignetting correction +PARTIALPASTE_WHITEBALANCE;White balance +PREFERENCES_APPLNEXTSTARTUP;下次啟動生效 +PREFERENCES_CACHECLEARALL;Clear All +PREFERENCES_CACHECLEARPROFILES;Clear Profiles +PREFERENCES_CACHECLEARTHUMBS;Clear Thumbnails +PREFERENCES_CACHEMAXENTRIES;Maximal Number of Cache Entries +PREFERENCES_CACHEOPTS;Cache Options +PREFERENCES_CACHETHUMBHEIGHT;Maximal Thumbnail Height +PREFERENCES_CLIPPINGIND;高光提示 +PREFERENCES_CMETRICINTENT;色彩模式 +PREFERENCES_DATEFORMATHINT;You can use the following formatting strings:\n%y : year\n%m : month\n%d : day\n\nFor example, the hungarian date format is:\n%y/%m/%d +PREFERENCES_DATEFORMAT;日期格式 +PREFERENCES_DEFAULTLANG;預設語言 +PREFERENCES_DEFAULTTHEME;Default theme +PREFERENCES_DIRHOME;用戶檔路徑 +PREFERENCES_DIRLAST;上次訪問路徑 +PREFERENCES_DIROTHER;其他 +PREFERENCES_DIRSELECTDLG;啟動時選擇圖片路徑... +PREFERENCES_DIRSOFTWARE;軟體安裝路徑 +PREFERENCES_EDITORCMDLINE;Other command line +PREFERENCES_EXTERNALEDITOR;External editor +PREFERENCES_FBROWSEROPTS;檔流覽選項 +PREFERENCES_FILEFORMAT;檔格式 +PREFERENCES_FORIMAGE;用於圖片檔 +PREFERENCES_FORRAW;用於Raw文件 +PREFERENCES_GIMPPATH;GIMP installation directory +PREFERENCES_HLTHRESHOLD;高光溢出闕值 +PREFERENCES_ICCDIR;ICC配置路徑 +PREFERENCES_IMPROCPARAMS;預設圖片處理參數 +PREFERENCES_INTENT_ABSOLUTE;絕對色彩模式 +PREFERENCES_INTENT_PERCEPTUAL;感知模式 +PREFERENCES_INTENT_RELATIVE;相對色彩模式 +PREFERENCES_INTENT_SATURATION;飽和度 +PREFERENCES_MONITORICC;顯示器配置 +PREFERENCES_OUTDIRFOLDERHINT;Put the saved images to the seledted folder +PREFERENCES_OUTDIRFOLDER;Save to folder +PREFERENCES_OUTDIRTEMPLATEHINT;You can use the following formatting strings:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nThese formatting strings refer to the directories and sub-paths of the path of the raw file.\n\nFor example, if /home/tom/image/02-09-2006/dsc0012.nefhas been opened, the meaning of the formatting strings are:\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\nIf you want to save the output image where the original is, write:\n%p1/%f\n\nIf you want to save the output image in a directory 'converted' located the directory of the original, write:\n%p1/converted/%f\n\nIf you want to save the output image in directory '/home/tom/converted' with keeping the same subdirectory of dates, write:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Use Template +PREFERENCES_OUTDIR;輸出路徑 +PREFERENCES_PARSEDEXTADDHINT;Type an extension and press this button to append list +PREFERENCES_PARSEDEXTADD;Add Extension +PREFERENCES_PARSEDEXTDELHINT;Delete selected extension from the list +PREFERENCES_PARSEDEXT;Parsed Extensions +PREFERENCES_PROFILEHANDLING;Processing Profile Handling +PREFERENCES_PROFILELOADPR;Profile Loading Priority +PREFERENCES_PROFILEPRCACHE;Profile in Cache +PREFERENCES_PROFILEPRFILE;Profile Next to the Input File +PREFERENCES_PROFILESAVECACHE;Save Processing Parameters to the Cache +PREFERENCES_PROFILESAVEINPUT;Save Processing Parameters Next to the Input File +PREFERENCES_PSPATH;Adobe Photoshop installation directory +PREFERENCES_SELECTLANG;選擇語言 +PREFERENCES_SELECTTHEME;Select theme +PREFERENCES_SHOWBASICEXIF;顯示基本Exif資訊 +PREFERENCES_SHOWDATETIME;顯示時間日期 +PREFERENCES_SHTHRESHOLD;暗部不足闕值 +PREFERENCES_STARTUPIMDIR;啟動時路徑 +PREFERENCES_TAB_BROWSER;檔流覽器 +PREFERENCES_TAB_COLORMGR;色彩管理 +PREFERENCES_TAB_GENERAL;一般 +PREFERENCES_TAB_IMPROC;圖片處理 +PROFILEPANEL_LABEL;處理參數配置 +PROFILEPANEL_LOADDLGLABEL;載入處理參數為... +PROFILEPANEL_PCUSTOM;自定義 +PROFILEPANEL_PFILE;由文件 +PROFILEPANEL_PLASTSAVED;上次儲存 +PROFILEPANEL_SAVEDLGLABEL;儲存處理參數為... +PROFILEPANEL_TOOLTIPCOPY;Copy current profile to clipboard +PROFILEPANEL_TOOLTIPLOAD;由檔載入配置 +PROFILEPANEL_TOOLTIPPASTE; Paste profile from clipboard +PROFILEPANEL_TOOLTIPSAVE;儲存當前配置 +PROGRESSBAR_LOADING;圖片載入中... +PROGRESSBAR_LOADJPEG;JPEG載入中... +PROGRESSBAR_LOADPNG;PNG載入中... +PROGRESSBAR_LOADTIFF;TIFF載入中... +PROGRESSBAR_PROCESSING;圖片處理中... +PROGRESSBAR_READY;就緒 +PROGRESSBAR_SAVEJPEG;JPEG儲存中... +PROGRESSBAR_SAVEPNG;PNG儲存中... +PROGRESSBAR_SAVETIFF;TIFF儲存中... +QINFO_ISO;ISO +QINFO_NOEXIF;Exif資料不可用. +SAVEDLG_FILEFORMAT;檔格式 +SAVEDLG_JPEGQUAL;JPEG品質 +SAVEDLG_PNGCOMPR;PNG壓縮 +SAVEDLG_PUTTOQUEUEHEAD;Put to the head of the processing queue +SAVEDLG_PUTTOQUEUETAIL;Put to the end of the processing queue +SAVEDLG_PUTTOQUEUE;Put into processing queue +SAVEDLG_SAVEIMMEDIATELY;Save immediately +SAVEDLG_SAVESPP;隨圖片儲存處理參數 +TOOLBAR_TOOLTIP_CROP;剪裁選擇 (shortcut key: C) +TOOLBAR_TOOLTIP_HAND;手形工具 (shortcut key: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;基準線選擇 (shortcut key: S) +TOOLBAR_TOOLTIP_WB;白平衡點 (shortcut key: W) +TP_CACORRECTION_BLUE;藍 +TP_CACORRECTION_LABEL;C/A 矯正 +TP_CACORRECTION_RED;紅 +TP_CHMIXER_BLUE;藍 +TP_CHMIXER_GREEN;綠 +TP_CHMIXER_LABEL;通道混合 +TP_CHMIXER_RED;紅 +TP_COARSETRAF_TOOLTIP_HFLIP;水準翻轉 +TP_COARSETRAF_TOOLTIP_ROTLEFT;左轉 +TP_COARSETRAF_TOOLTIP_ROTRIGHT;右轉 +TP_COARSETRAF_TOOLTIP_VFLIP;豎直翻轉 +TP_CROP_FIXRATIO;比例: +TP_CROP_GTDIAGONALS;對角線法則 +TP_CROP_GTNONE;無 +TP_CROP_GTRULETHIRDS;1/3法則 +TP_CROP_GUIDETYPE;輔助方式: +TP_CROP_H;高 +TP_CROP_LABEL;剪裁 +TP_CROP_SELECTCROP; 選擇預設 +TP_CROP_W;寬 +TP_CROP_X;x +TP_CROP_Y;y +TP_DISTORTION_AMOUNT;程度 +TP_DISTORTION_LABEL;畫面歪曲像差 +TP_EXPOSURE_AUTOLEVELS;自動色階 +TP_EXPOSURE_BLACKLEVEL;黑 +TP_EXPOSURE_BRIGHTNESS;亮度 +TP_EXPOSURE_CLIP;高光 +TP_EXPOSURE_COMPRHIGHLIGHTS;亮部壓縮 +TP_EXPOSURE_COMPRSHADOWS;暗部壓縮 +TP_EXPOSURE_CONTRAST;對比度 +TP_EXPOSURE_CURVEEDITOR;色調曲線 +TP_EXPOSURE_EXPCOMP;曝光補償 +TP_EXPOSURE_LABEL;曝光 +TP_HLREC_CIELAB;CIELab Blending +TP_HLREC_COLOR;色彩延伸 +TP_HLREC_LABEL;高光挽回 +TP_HLREC_LUMINANCE;亮度挽回 +TP_HLREC_METHOD;方式: +TP_ICM_INPUTCAMERA;相機預設 +TP_ICM_INPUTCUSTOM;自定義 +TP_ICM_INPUTDLGLABEL;選擇輸入ICC配置... +TP_ICM_INPUTEMBEDDED;如可能,使用內置 +TP_ICM_INPUTPROFILE;輸入配置 +TP_ICM_LABEL;ICM +TP_ICM_NOICM;No ICM: sRGB配置 +TP_ICM_OUTPUTPROFILE;輸出配置 +TP_ICM_SAVEREFERENCE;Save reference image for profiling +TP_ICM_WORKINGPROFILE;當前配置 +TP_RESIZE_HEIGHT;Height +TP_RESIZE_H;高: +TP_RESIZE_LABEL;調整大小 +TP_RESIZE_METHOD;方式: +TP_RESIZE_NEAREST;最近點 +TP_RESIZE_SCALE;比例 +TP_RESIZE_SPECIFY;Specify: +TP_RESIZE_WIDTH;Width +TP_RESIZE_W;寬: +TP_ROTATE_DEGREE;角度 +TP_ROTATE_LABEL;旋轉 +TP_ROTATE_SELECTLINE; 選擇基準線 +TP_SHADOWSHLIGHTS_HIGHLIGHTS;亮部 +TP_SHADOWSHLIGHTS_HLTONALW;色調範圍 +TP_SHADOWSHLIGHTS_LABEL;暗部/亮部 +TP_SHADOWSHLIGHTS_LOCALCONTR;局部對比度 +TP_SHADOWSHLIGHTS_RADIUS;半徑 +TP_SHADOWSHLIGHTS_SHADOWS;陰影 +TP_SHADOWSHLIGHTS_SHTONALW;色調範圍 +TP_SHARPENING_AMOUNT;程度 +TP_SHARPENING_EDRADIUS;半徑 +TP_SHARPENING_EDTOLERANCE;邊緣容差 +TP_SHARPENING_HALOCONTROL;光暈控制 +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_DAMPING;衰減 +TP_SHARPENING_RLD_ITERATIONS;迭代 +TP_SHARPENING_THRESHOLD;闕值 +TP_SHARPENING_USM;銳化 +TP_VIGNETTING_AMOUNT;程度 +TP_VIGNETTING_LABEL;邊暈矯正 +TP_VIGNETTING_RADIUS;半徑 +TP_WBALANCE_AUTO;自動 +TP_WBALANCE_CAMERA;相機 +TP_WBALANCE_CUSTOM;自定義 +TP_WBALANCE_GREEN;色度 +TP_WBALANCE_LABEL;白平衡 +TP_WBALANCE_METHOD;方式 +TP_WBALANCE_SIZE;大小: +TP_WBALANCE_SPOTWB;WB點 +TP_WBALANCE_TEMPERATURE;色溫 + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!ABOUT_TAB_BUILD;Version +!ABOUT_TAB_CREDITS;Credits +!ABOUT_TAB_LICENSE;License +!ABOUT_TAB_RELEASENOTES;Release Notes +!ABOUT_TAB_SPLASH;Splash +!BATCHQUEUE_DESTFILENAME;Path and file name +!BATCH_PROCESSING;Batch Processing +!CURVEEDITOR_AXIS_IN;I: +!CURVEEDITOR_AXIS_LEFT_TAN;LT: +!CURVEEDITOR_AXIS_OUT;O: +!CURVEEDITOR_AXIS_RIGHT_TAN;RT: +!CURVEEDITOR_CURVES;Curves +!CURVEEDITOR_CURVE;Curve +!CURVEEDITOR_CUSTOM;Custom +!CURVEEDITOR_DARKS;Darks +!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_HIGHLIGHTS;Highlights +!CURVEEDITOR_LIGHTS;Lights +!CURVEEDITOR_MINMAXCPOINTS;Equalizer +!CURVEEDITOR_NURBS;Control cage +!CURVEEDITOR_PARAMETRIC;Parametric +!CURVEEDITOR_SHADOWS;Shadows +!CURVEEDITOR_TOOLTIPCOPY;Copy current curve to clipboard. +!CURVEEDITOR_TOOLTIPPASTE;Paste curve from clipboard. +!CURVEEDITOR_TYPE;Type: +!EDITWINDOW_TITLE;Image Edit +!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_FILETYPE;File type +!EXIFFILTER_METADATAFILTER;Enable metadata filters +!EXPORT_BYPASS_ALL;Select / Unselect All +!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_FF;Bypass [raw] Flat-Field +!EXPORT_BYPASS_RAW_GREENTHRESH;Bypass [raw] Green Equilibration +!EXPORT_BYPASS_RAW_LINENOISE;Bypass [raw] Line Noise Filter +!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_FASTEXPORTOPTIONS;Fast Export Options +!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_MAXHEIGHT;Maximum height: +!EXPORT_MAXWIDTH;Maximum width: +!EXPORT_PUTTOQUEUEFAST; Put to queue for fast export +!EXPORT_RAW_DMETHOD;Demosaic method +!EXTPROGTARGET_1;raw +!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_CACHECLEARFROMFULL;Clear from cache - full +!FILEBROWSER_CACHECLEARFROMPARTIAL;Clear from cache - partial +!FILEBROWSER_CACHE;Cache +!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_CURRENT_NAME;Current name: +!FILEBROWSER_DARKFRAME;Dark-frame +!FILEBROWSER_DELETEDLGMSGINCLPROC;Are you sure you want to delete the selected %1 files including a queue-processed version? +!FILEBROWSER_EXEC_CPB;Custom Profile Builder +!FILEBROWSER_EXTPROGMENU;Open with +!FILEBROWSER_FLATFIELD;Flat-Field +!FILEBROWSER_MOVETODARKFDIR;Move to dark-frames directory +!FILEBROWSER_MOVETOFLATFIELDDIR;Move to flat-fields directory +!FILEBROWSER_NEW_NAME;New name: +!FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) +!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_POPUPCOLORLABEL;Color label +!FILEBROWSER_POPUPCOPYTO;Copy to... +!FILEBROWSER_POPUPFILEOPERATIONS;File operations +!FILEBROWSER_POPUPMOVETO;Move to... +!FILEBROWSER_POPUPPROCESSFAST;Put to queue (Fast export) +!FILEBROWSER_POPUPPROFILEOPERATIONS;Processing profile operations +!FILEBROWSER_POPUPRANK0;Unrank +!FILEBROWSER_POPUPRANK1;Rank 1 * +!FILEBROWSER_POPUPRANK2;Rank 2 ** +!FILEBROWSER_POPUPRANK3;Rank 3 *** +!FILEBROWSER_POPUPRANK4;Rank 4 **** +!FILEBROWSER_POPUPRANK5;Rank 5 ***** +!FILEBROWSER_POPUPRANK;Rank +!FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!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_QUERYLABEL; Find: +!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_SELECTDARKFRAME;Select dark-frame... +!FILEBROWSER_SELECTFLATFIELD;Select flat-field... +!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 +!FILEBROWSER_SHOWCOLORLABEL4HINT;Show images labeled Blue.\nShortcut: Alt-4 +!FILEBROWSER_SHOWCOLORLABEL5HINT;Show images labeled Purple.\nShortcut: Alt-5 +!FILEBROWSER_SHOWEDITEDHINT;Show edited images.\nShortcut: 7 +!FILEBROWSER_SHOWEDITEDNOTHINT;Show not edited images.\nShortcut: 6 +!FILEBROWSER_SHOWEXIFINFO;Show Exif info.\n\nShortcuts:\ni - Multiple Editor Tabs Mode,\nAlt-i - Single Editor Tab Mode. +!FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!FILEBROWSER_SHOWRECENTLYSAVEDHINT;Show saved images.\nShortcut: Alt-7 +!FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show unsaved images.\nShortcut: Alt-6 +!FILEBROWSER_SHOWUNCOLORHINT;Show images without a color label.\nShortcut: Alt-0 +!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_ASIMAGE;As Image +!GENERAL_AUTO;Automatic +!GENERAL_CLOSE;Close +!GENERAL_FILE;File +!GENERAL_NONE;None +!GENERAL_WARNING;Warning +!HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar.\nRight-click on image preview to freeze/unfreeze. +!HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram. +!HISTOGRAM_TOOLTIP_FULL;Toggle full (off) or scaled (on) histogram. +!HISTOGRAM_TOOLTIP_RAW;Show/Hide raw histogram. +!HISTORY_MSG_82;Profile changed +!HISTORY_MSG_83;S/H - Sharp mask +!HISTORY_MSG_84;Perspective correction +!HISTORY_MSG_85;LCP +!HISTORY_MSG_86;RGB curves - Luminosity mode +!HISTORY_MSG_87;Impulse noise reduction +!HISTORY_MSG_88;Impulse NR threshold +!HISTORY_MSG_89;Noise Reduction +!HISTORY_MSG_90;NR - Luminance +!HISTORY_MSG_91;NR - Chrominance master +!HISTORY_MSG_92;NR - Gamma +!HISTORY_MSG_93;CbDL - Value +!HISTORY_MSG_94;Contrast by Detail Levels +!HISTORY_MSG_95;L*a*b* - Chromaticity +!HISTORY_MSG_96;L*a*b* - a* curve +!HISTORY_MSG_97;L*a*b* - b* curve +!HISTORY_MSG_98;Demosaicing method +!HISTORY_MSG_99;Hot pixel filter +!HISTORY_MSG_100;RGB Saturation +!HISTORY_MSG_101;HSV - Hue +!HISTORY_MSG_102;HSV - Saturation +!HISTORY_MSG_103;HSV - Value +!HISTORY_MSG_104;HSV Equalizer +!HISTORY_MSG_105;Defringe +!HISTORY_MSG_106;Defringe - Radius +!HISTORY_MSG_107;Defringe - Threshold +!HISTORY_MSG_108;Highlight Compr. Threshold +!HISTORY_MSG_109;Resize - Bounding box +!HISTORY_MSG_110;Resize - Applies to +!HISTORY_MSG_111;L*a*b* - Avoid color shift +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;L*a*b* - Red/skin prot. +!HISTORY_MSG_114;DCB iterations +!HISTORY_MSG_115;False color suppression +!HISTORY_MSG_116;DCB enhancement +!HISTORY_MSG_117;Raw CA correction - Red +!HISTORY_MSG_118;Raw CA correction - Blue +!HISTORY_MSG_119;Line noise filter +!HISTORY_MSG_120;Green equilibration +!HISTORY_MSG_121;Raw CA Correction - Auto +!HISTORY_MSG_122;Dark-Frame - Auto-selection +!HISTORY_MSG_123;Dark-Frame - File +!HISTORY_MSG_124;White point correction +!HISTORY_MSG_125;Highlight preservation +!HISTORY_MSG_126;Flat-Field - File +!HISTORY_MSG_127;Flat-Field - Auto-selection +!HISTORY_MSG_128;Flat-Field - Blur radius +!HISTORY_MSG_129;Flat-Field - Blur type +!HISTORY_MSG_130;Auto distorion correction +!HISTORY_MSG_131;NR - Luma +!HISTORY_MSG_132;NR - Chroma +!HISTORY_MSG_133;Output gamma +!HISTORY_MSG_134;Free gamma +!HISTORY_MSG_135;Free gamma +!HISTORY_MSG_136;Free gamma slope +!HISTORY_MSG_137;Black level - Green 1 +!HISTORY_MSG_138;Black level - Red +!HISTORY_MSG_139;Black level - Blue +!HISTORY_MSG_140;Black level - Green 2 +!HISTORY_MSG_141;Black level - Link greens +!HISTORY_MSG_142;ES - Iterations +!HISTORY_MSG_143;ES - Quantity +!HISTORY_MSG_144;Microcontrast - Quantity +!HISTORY_MSG_145;Microcontrast - Uniformity +!HISTORY_MSG_146;Edge sharpening +!HISTORY_MSG_147;ES - Luminance only +!HISTORY_MSG_148;Microcontrast +!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_150;Post-demosaic artifact/noise red. +!HISTORY_MSG_151;Vibrance +!HISTORY_MSG_152;Vib - Pastel tones +!HISTORY_MSG_153;Vib - Saturated tones +!HISTORY_MSG_154;Vib - Protect skin-tones +!HISTORY_MSG_155;Vib - Avoid color shift +!HISTORY_MSG_156;Vib - Link pastel/saturated +!HISTORY_MSG_157;Vib - P/S threshold +!HISTORY_MSG_158;TM - Strength +!HISTORY_MSG_159;TM - Edge stopping +!HISTORY_MSG_160;TM - Scale +!HISTORY_MSG_161;TM - Reweighting iterates +!HISTORY_MSG_162;Tone Mapping +!HISTORY_MSG_163;RGB curves - Red +!HISTORY_MSG_164;RGB curves - Green +!HISTORY_MSG_165;RGB curves - Blue +!HISTORY_MSG_166;Neutral levels +!HISTORY_MSG_167;--unused-- +!HISTORY_MSG_168;L*a*b* - CC curve +!HISTORY_MSG_169;L*a*b* - CH curve +!HISTORY_MSG_170;Vibrance - HH curve +!HISTORY_MSG_171;L*a*b* - LC curve +!HISTORY_MSG_172;L*a*b* - Restrict LC +!HISTORY_MSG_173;NR - Luminance detail +!HISTORY_MSG_174;CIECAM02 +!HISTORY_MSG_175;CAM02 - CAT02 adaptation +!HISTORY_MSG_176;CAM02 - Viewing surround +!HISTORY_MSG_177;CAM02 - Scene luminosity +!HISTORY_MSG_178;CAM02 - Viewing luminosity +!HISTORY_MSG_179;CAM02 - White-point model +!HISTORY_MSG_180;CAM02 - Lightness (J) +!HISTORY_MSG_181;CAM02 - Chroma (C) +!HISTORY_MSG_182;CAM02 - Automatic CAT02 +!HISTORY_MSG_183;CAM02 - Contrast (J) +!HISTORY_MSG_184;CAM02 - Scene surround +!HISTORY_MSG_185;CAM02 - Gamut control +!HISTORY_MSG_186;CAM02 - Algorithm +!HISTORY_MSG_187;CAM02 - Red/skin prot. +!HISTORY_MSG_188;CAM02 - Brightness (Q) +!HISTORY_MSG_189;CAM02 - Contrast (Q) +!HISTORY_MSG_190;CAM02 - Saturation (S) +!HISTORY_MSG_191;CAM02 - Colorfulness (M) +!HISTORY_MSG_192;CAM02 - Hue (h) +!HISTORY_MSG_193;CAM02 - Tone curve 1 +!HISTORY_MSG_194;CAM02 - Tone curve 2 +!HISTORY_MSG_195;CAM02 - Tone curve 1 +!HISTORY_MSG_196;CAM02 - Tone curve 2 +!HISTORY_MSG_197;CAM02 - Color curve +!HISTORY_MSG_198;CAM02 - Color curve +!HISTORY_MSG_199;CAM02 - Output histograms +!HISTORY_MSG_200;CAM02 - Tone mapping +!HISTORY_MSG_201;NR - Chrominance - R&G +!HISTORY_MSG_202;NR - Chrominance - B&Y +!HISTORY_MSG_203;NR - Method +!HISTORY_MSG_204;LMMSE enhancement steps +!HISTORY_MSG_205;CAM02 - Hot/bad pixel filter +!HISTORY_MSG_206;CAT02 - Auto scene luminosity +!HISTORY_MSG_207;Defringe - Hue curve +!HISTORY_MSG_208;WB - B/R equalizer +!HISTORY_MSG_210;GF - Angle +!HISTORY_MSG_211;Graduated Filter +!HISTORY_MSG_212;VF - Strength +!HISTORY_MSG_213;Vignette Filter +!HISTORY_MSG_214;Black-and-White +!HISTORY_MSG_215;B&W - CM - Red +!HISTORY_MSG_216;B&W - CM - Green +!HISTORY_MSG_217;B&W - CM - Blue +!HISTORY_MSG_218;B&W - Gamma - Red +!HISTORY_MSG_219;B&W - Gamma - Green +!HISTORY_MSG_220;B&W - Gamma - Blue +!HISTORY_MSG_221;B&W - Color filter +!HISTORY_MSG_222;B&W - Presets +!HISTORY_MSG_223;B&W - CM - Orange +!HISTORY_MSG_224;B&W - CM - Yellow +!HISTORY_MSG_225;B&W - CM - Cyan +!HISTORY_MSG_226;B&W - CM - Magenta +!HISTORY_MSG_227;B&W - CM - Purple +!HISTORY_MSG_228;B&W - Luminance equalizer +!HISTORY_MSG_229;B&W - Luminance equalizer +!HISTORY_MSG_230;B&W - Mode +!HISTORY_MSG_231;B&W - 'Before' curve +!HISTORY_MSG_232;B&W - 'Before' curve type +!HISTORY_MSG_233;B&W - 'After' curve +!HISTORY_MSG_234;B&W - 'After' curve type +!HISTORY_MSG_235;B&W - Auto channel mixer +!HISTORY_MSG_236;--unused-- +!HISTORY_MSG_237;B&W - Mixer +!HISTORY_MSG_238;GF - Feather +!HISTORY_MSG_239;GF - Strength +!HISTORY_MSG_240;GF - Center +!HISTORY_MSG_241;VF - Feather +!HISTORY_MSG_242;VF - Roundness +!HISTORY_MSG_243;VC - Radius +!HISTORY_MSG_244;VC - Strength +!HISTORY_MSG_245;VC - Center +!HISTORY_MSG_246;L*a*b* - CL curve +!HISTORY_MSG_247;L*a*b* - LH curve +!HISTORY_MSG_248;L*a*b* - HH curve +!HISTORY_MSG_249;CbDL - Threshold +!HISTORY_MSG_250;NR - Enhanced +!HISTORY_MSG_251;B&W - Algorithm +!HISTORY_MSG_252;CbDL - Skin tar/prot +!HISTORY_MSG_253;CbDL - Reduce artifacts +!HISTORY_MSG_254;CbDL - Skin hue +!HISTORY_MSG_255;NR - Median filter +!HISTORY_MSG_256;NR - Median type +!HISTORY_MSG_257;Color Toning +!HISTORY_MSG_258;CT - Color curve +!HISTORY_MSG_259;CT - Opacity curve +!HISTORY_MSG_260;CT - a*[b*] opacity +!HISTORY_MSG_261;CT - Method +!HISTORY_MSG_262;CT - b* opacity +!HISTORY_MSG_263;CT - Shadows - Red +!HISTORY_MSG_264;CT - Shadows - Green +!HISTORY_MSG_265;CT - Shadows - Blue +!HISTORY_MSG_266;CT - Mid - Red +!HISTORY_MSG_267;CT - Mid - Green +!HISTORY_MSG_268;CT - Mid - Blue +!HISTORY_MSG_269;CT - High - Red +!HISTORY_MSG_270;CT - High - Green +!HISTORY_MSG_271;CT - High - Blue +!HISTORY_MSG_272;CT - Balance +!HISTORY_MSG_273;CT - Reset +!HISTORY_MSG_274;CT - Sat. Shadows +!HISTORY_MSG_275;CT - Sat. Highlights +!HISTORY_MSG_276;CT - Opacity +!HISTORY_MSG_277;--unused-- +!HISTORY_MSG_278;CT - Preserve luminance +!HISTORY_MSG_279;CT - Shadows +!HISTORY_MSG_280;CT - Highlights +!HISTORY_MSG_281;CT - Sat. strength +!HISTORY_MSG_282;CT - Sat. threshold +!HISTORY_MSG_283;CT - Strength +!HISTORY_MSG_284;CT - Auto sat. protection +!HISTORY_MSG_285;NR - Median - Method +!HISTORY_MSG_286;NR - Median - Type +!HISTORY_MSG_287;NR - Median - Iterations +!HISTORY_MSG_288;Flat Field - Clip control +!HISTORY_MSG_289;Flat Field - Clip control - Auto +!HISTORY_MSG_290;Black Level - Red +!HISTORY_MSG_291;Black Level - Green +!HISTORY_MSG_292;Black Level - Blue +!HISTORY_MSG_293;Film Simulation +!HISTORY_MSG_294;Film Simulation - Strength +!HISTORY_MSG_295;Film Simulation - Film +!HISTORY_MSG_296;NR - Luminance curve +!HISTORY_MSG_297;NR - Quality +!HISTORY_MSG_298;Dead pixel filter +!HISTORY_MSG_299;NR - Chrominance curve +!HISTORY_MSG_300;- +!HISTORY_MSG_301;NR - Luma control +!HISTORY_MSG_302;NR - Chroma method +!HISTORY_MSG_303;NR - Chroma method +!HISTORY_MSG_304;W - Contrast levels +!HISTORY_MSG_305;Wavelet Levels +!HISTORY_MSG_306;W - Preview +!HISTORY_MSG_307;W - Preview +!HISTORY_MSG_308;W - Preview direction +!HISTORY_MSG_309;W - ES - Detail +!HISTORY_MSG_310;W - Residual - Sky tar/prot +!HISTORY_MSG_311;W - Wavelet levels +!HISTORY_MSG_312;W - Residual - Shadows threshold +!HISTORY_MSG_313;W - Chroma - Sat/past +!HISTORY_MSG_314;W - Gamut - Reduce artifacts +!HISTORY_MSG_315;W - Residual - Contrast +!HISTORY_MSG_316;W - Gamut - Skin tar/prot +!HISTORY_MSG_317;W - Gamut - Skin hue +!HISTORY_MSG_318;W - Contrast - Highlight levels +!HISTORY_MSG_319;W - Contrast - Highlight range +!HISTORY_MSG_320;W - Contrast - Shadow range +!HISTORY_MSG_321;W - Contrast - Shadow levels +!HISTORY_MSG_322;W - Gamut - Avoid color shift +!HISTORY_MSG_323;W - ES - Local contrast +!HISTORY_MSG_324;W - Chroma - Pastel +!HISTORY_MSG_325;W - Chroma - Saturated +!HISTORY_MSG_326;W - Chroma - Method +!HISTORY_MSG_327;W - Contrast - Apply to +!HISTORY_MSG_328;W - Chroma - Link strength +!HISTORY_MSG_329;W - Toning - Opacity RG +!HISTORY_MSG_330;W - Toning - Opacity BY +!HISTORY_MSG_331;W - Contrast levels - Extra +!HISTORY_MSG_332;W - Tiling method +!HISTORY_MSG_333;W - Residual - Shadows +!HISTORY_MSG_334;W - Residual - Chroma +!HISTORY_MSG_335;W - Residual - Highlights +!HISTORY_MSG_336;W - Residual - Highlights threshold +!HISTORY_MSG_337;W - Residual - Sky hue +!HISTORY_MSG_338;W - ES - Radius +!HISTORY_MSG_339;W - ES - Strength +!HISTORY_MSG_340;W - Strength +!HISTORY_MSG_341;W - Edge performance +!HISTORY_MSG_342;W - ES - First level +!HISTORY_MSG_343;W - Chroma levels +!HISTORY_MSG_344;W - Meth chroma sl/cur +!HISTORY_MSG_345;W - ES - Local contrast +!HISTORY_MSG_346;W - ES - Local contrast method +!HISTORY_MSG_347;W - Denoise - Level 0 +!HISTORY_MSG_348;W - Denoise - Level 1 +!HISTORY_MSG_349;W - Denoise - Level 2 +!HISTORY_MSG_350;W - ES - Edge detection +!HISTORY_MSG_351;W - Residual - HH curve +!HISTORY_MSG_352;W - Background +!HISTORY_MSG_353;W - ES - Gradient sensitivity +!HISTORY_MSG_354;W - ES - Enhance +!HISTORY_MSG_355;W - ES - Threshold low +!HISTORY_MSG_356;W - ES - Threshold high +!HISTORY_MSG_357;W - Denoise - Link with ES +!HISTORY_MSG_358;W - Gamut - CH +!HISTORY_MSG_359;Hot/Dead - Threshold +!HISTORY_MSG_360;TM Gamma +!HISTORY_MSG_361;W - Final - Chroma balance +!HISTORY_MSG_362;W - Residual - Compression method +!HISTORY_MSG_363;W - Residual - Compression strength +!HISTORY_MSG_364;W - Final - Contrast balance +!HISTORY_MSG_365;W - Final - Delta balance +!HISTORY_MSG_366;W - Residual - Compression gamma +!HISTORY_MSG_367;W - ES - Local contrast curve +!HISTORY_MSG_368;W - Final - Contrast balance +!HISTORY_MSG_369;W - Final - Balance method +!HISTORY_MSG_370;W - Final - Local contrast curve +!HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s +!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 +!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). +!MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Put current image to processing queue.\nShortcut: Ctrl+b +!MAIN_BUTTON_SAVE_TOOLTIP;Save current image.\nShortcut: Ctrl+s +!MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Edit current image in external editor.\nShortcut: Ctrl+e +!MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Show/hide all side panels.\nShortcut: m +!MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen +!MAIN_FRAME_BATCHQUEUE_TOOLTIP;Processing queue.\nShortcut: Ctrl-F3 +!MAIN_FRAME_EDITOR;Editor +!MAIN_FRAME_EDITOR_TOOLTIP;Editor.\nShortcut: Ctrl-F4 +!MAIN_FRAME_FILEBROWSER_TOOLTIP;File browser.\nShortcut: Ctrl-F2 +!MAIN_MSG_EMPTYFILENAME;Filename unspecified! +!MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue-processed first. +!MAIN_MSG_OPERATIONCANCELLED;Operation cancelled +!MAIN_MSG_PATHDOESNTEXIST;The path\n\n%1\n\ndoes not exist. Please set a correct path in Preferences. +!MAIN_MSG_SETPATHFIRST;You first have to set a target path in Preferences in order to use this function! +!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_EXPORT; Fast Export +!MAIN_TAB_EXPOSURE_TOOLTIP;Shortcut: Alt-e +!MAIN_TAB_INSPECT; Inspect +!MAIN_TAB_METADATA_TOOLTIP;Shortcut: Alt-m +!MAIN_TAB_RAW;Raw +!MAIN_TAB_RAW_TOOLTIP;Shortcut: Alt-r +!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_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%. +!MAIN_TOOLTIP_PREVIEWG;Preview the Green channel.\nShortcut: g +!MAIN_TOOLTIP_PREVIEWL;Preview the Luminosity.\nShortcut: v\n\n0.299*R + 0.587*G + 0.114*B +!MAIN_TOOLTIP_PREVIEWR;Preview the Red channel.\nShortcut: r +!MAIN_TOOLTIP_SHOWHIDELP1;Show/Hide the left panel.\nShortcut: l +!MAIN_TOOLTIP_SHOWHIDERP1;Show/Hide the right panel.\nShortcut: Alt-l +!MAIN_TOOLTIP_SHOWHIDETP1;Show/Hide the top panel.\nShortcut: Shift-l +!MAIN_TOOLTIP_THRESHOLD;Threshold +!NAVIGATOR_B;B: +!NAVIGATOR_G;G: +!NAVIGATOR_H;H: +!NAVIGATOR_LAB_A;a*: +!NAVIGATOR_LAB_B;b*: +!NAVIGATOR_LAB_L;L*: +!NAVIGATOR_NA; -- +!NAVIGATOR_R;R: +!NAVIGATOR_S;S: +!NAVIGATOR_V;V: +!NAVIGATOR_XY_FULL;Width: %1, Height: %2 +!NAVIGATOR_XY_NA;x: --, y: -- +!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_CHANNELMIXERBW;Black-and-White +!PARTIALPASTE_CHANNELMIXER;Channel mixer +!PARTIALPASTE_COLORAPP;CIECAM02 +!PARTIALPASTE_COLORTONING;Color Toning +!PARTIALPASTE_COMMONTRANSFORMPARAMS;Auto-fill +!PARTIALPASTE_DARKFRAMEAUTOSELECT;Dark-frame auto-selection +!PARTIALPASTE_DARKFRAMEFILE;Dark-frame file +!PARTIALPASTE_DEFRINGE;Defringe +!PARTIALPASTE_DETAILGROUP;Detail Settings +!PARTIALPASTE_DIRPYRDENOISE;Noise reduction +!PARTIALPASTE_DIRPYREQUALIZER;Contrast by detail levels +!PARTIALPASTE_EPD;Tone mapping +!PARTIALPASTE_EQUALIZER;Wavelet Equalizer +!PARTIALPASTE_EVERYTHING;Everything +!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_GRADIENT;Graduated filter +!PARTIALPASTE_HSVEQUALIZER;HSV equalizer +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction +!PARTIALPASTE_LABCURVE;L*a*b* adjustments +!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_PCVIGNETTE;Vignette filter +!PARTIALPASTE_PERSPECTIVE;Perspective +!PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter +!PARTIALPASTE_PREPROCESS_GREENEQUIL;Green equilibration +!PARTIALPASTE_PREPROCESS_HOTPIXFILT;Hot pixel filter +!PARTIALPASTE_PREPROCESS_LINEDENOISE;Line noise filter +!PARTIALPASTE_RAWCACORR_AUTO;CA auto-correction +!PARTIALPASTE_RAWCACORR_CABLUE;CA blue +!PARTIALPASTE_RAWCACORR_CARED;CA red +!PARTIALPASTE_RAWEXPOS_BLACK;Black levels +!PARTIALPASTE_RAWEXPOS_LINEAR;White point correction +!PARTIALPASTE_RAWEXPOS_PRESER;Highlight preservation +!PARTIALPASTE_RAWGROUP;Raw Settings +!PARTIALPASTE_RAW_DCBENHANCE;DCB enhancement +!PARTIALPASTE_RAW_DCBITERATIONS;Number of DCB iterations +!PARTIALPASTE_RAW_DMETHOD;Demosaic method +!PARTIALPASTE_RAW_FALSECOLOR;Demosaic false color suppression steps +!PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!PARTIALPASTE_RGBCURVES;RGB curves +!PARTIALPASTE_SHARPENEDGE;Edges +!PARTIALPASTE_SHARPENMICRO;Microcontrast +!PARTIALPASTE_VIBRANCE;Vibrance +!PARTIALPASTE_WAVELETGROUP;Wavelet processing +!PREFERENCES_ADD;Add +!PREFERENCES_AUTLISLOW;Low +!PREFERENCES_AUTLISMAX;Max - Average of all tiles +!PREFERENCES_AUTLISSTD;High +!PREFERENCES_AUTLISVLOW;None +!PREFERENCES_AUTLOW;Low +!PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +!PREFERENCES_AUTSTD;Standard +!PREFERENCES_BATCH_PROCESSING;Batch Processing +!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_BEHADDALL;All to 'Add' +!PREFERENCES_BEHAVIOR;Behavior +!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_BEHSETALL;All to 'Set' +!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_CURVEBBOXPOS;Position of curve copypasta buttons +!PREFERENCES_CURVEBBOXPOS_ABOVE;Above +!PREFERENCES_CURVEBBOXPOS_BELOW;Below +!PREFERENCES_CURVEBBOXPOS_LEFT;Left +!PREFERENCES_CURVEBBOXPOS_RIGHT;Right +!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_CUSTPROFBUILD;Custom Processing Profile Builder +!PREFERENCES_CUTOVERLAYBRUSH;Crop mask color/transparency +!PREFERENCES_D50;5000K +!PREFERENCES_D55;5500K +!PREFERENCES_D60;6000K +!PREFERENCES_D65;6500K +!PREFERENCES_DARKFRAMEFOUND;Found +!PREFERENCES_DARKFRAMESHOTS;shots +!PREFERENCES_DARKFRAMETEMPLATES;templates +!PREFERENCES_DARKFRAME;Dark-Frame +!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 (de-select for low resolution display) +!PREFERENCES_FILMSIMULATION;Film Simulation +!PREFERENCES_FLATFIELDFOUND;Found +!PREFERENCES_FLATFIELDSDIR;Flat-fields directory +!PREFERENCES_FLATFIELDSHOTS;shots +!PREFERENCES_FLATFIELDTEMPLATES;templates +!PREFERENCES_FLATFIELD;Flat-Field +!PREFERENCES_FLUOF2;Fluorescent F2 +!PREFERENCES_FLUOF7;Fluorescent F7 +!PREFERENCES_FLUOF11;Fluorescent F11 +!PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT;Same thumbnail height between the Editor's panel 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_GREY05;Yb=05 CIE L#30 +!PREFERENCES_GREY10;Yb=10 CIE L#40 +!PREFERENCES_GREY15;Yb=15 CIE L#45 +!PREFERENCES_GREY18;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_GREYSC18;Yb=18 CIE L#50 +!PREFERENCES_GREYSCA;Automatic +!PREFERENCES_GREYSC;Scene Yb luminance (%) +!PREFERENCES_GREY;Output device's Yb luminance (%) +!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_LANGAUTODETECT;Use system language +!PREFERENCES_LEVAUTDN;Denoising level +!PREFERENCES_LEVDN;Cell size +!PREFERENCES_LISS;Auto multi-zone smoothing +!PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders +!PREFERENCES_MAX;Maxi (Tile) +!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_MENUGROUPRANK;Group "Rank" +!PREFERENCES_MENUOPTIONS;Context Menu Options +!PREFERENCES_METADATA;Metadata +!PREFERENCES_MIN;Mini (100x115) +!PREFERENCES_MULTITABDUALMON;Multiple Editor Tabs In Own Window Mode +!PREFERENCES_MULTITAB;Multiple Editor Tabs 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_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_PROPERTY;Property +!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 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_SINGLETABVERTAB;Single Editor Tab Mode, Vertical Tabs +!PREFERENCES_SINGLETAB;Single Editor Tab Mode +!PREFERENCES_SLIMUI;Slim interface +!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_PERFORMANCE;Performance & Quality +!PREFERENCES_TAB_SOUND;Sounds +!PREFERENCES_TIMAX;High +!PREFERENCES_TINB;Number of tiles +!PREFERENCES_TISTD;Standard +!PREFERENCES_TP_LABEL;Tool panel: +!PREFERENCES_TP_USEICONORTEXT;Use tab icons instead of text +!PREFERENCES_TP_VSCROLLBAR;Hide vertical scrollbar +!PREFERENCES_TUNNELMETADATA;Copy IPTC/XMP unchanged to output file (when tagging with other program) +!PREFERENCES_USEBUNDLEDPROFILES;Use bundled profiles +!PREFERENCES_USESYSTEMTHEME;Use system theme +!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_WORKFLOW;Layout +!PROFILEPANEL_COPYPPASTE;Parameters to copy +!PROFILEPANEL_GLOBALPROFILES;Bundled profiles +!PROFILEPANEL_LOADPPASTE;Parameters to load +!PROFILEPANEL_MODE_TIP;Processing profile fill mode.\n\nButton pressed: partial profiles will be converted to full profiles; the missing values will be replaced with hard-coded defaults.\n\nButton released: profiles will be applied as they are, altering only those values which they contain. +!PROFILEPANEL_MYPROFILES;My profiles +!PROFILEPANEL_PASTEPPASTE;Parameters to paste +!PROFILEPANEL_PINTERNAL;Neutral +!PROFILEPANEL_SAVEPPASTE;Parameters to save +!PROGRESSBAR_LOADINGTHUMBS;Loading thumbnails... +!PROGRESSBAR_NOIMAGES;No images found +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing profile saved +!PROGRESSBAR_SNAPSHOT_ADDED;Snapshot added +!PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists +!SAVEDLG_FORCEFORMATOPTS;Force saving options +!SAVEDLG_SUBSAMP;Subsampling +!SAVEDLG_SUBSAMP_1;Best compression +!SAVEDLG_SUBSAMP_2;Balanced +!SAVEDLG_SUBSAMP_3;Best quality +!SAVEDLG_SUBSAMP_TOOLTIP;Best compression: 4:1:1\nBalanced: 4:2:2\nBest quality: 4:4:4 +!SAVEDLG_TIFFUNCOMPRESSED;Uncompressed TIFF +!SAVEDLG_WARNFILENAME;File will be named +!SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. +!THRESHOLDSELECTOR_BL;Bottom-left +!THRESHOLDSELECTOR_BR;Bottom-right +!THRESHOLDSELECTOR_B;Bottom +!THRESHOLDSELECTOR_HINT;Hold the Shift key to move individual control points. +!THRESHOLDSELECTOR_TL;Top-left +!THRESHOLDSELECTOR_TR;Top-right +!THRESHOLDSELECTOR_T;Top +!TP_BWMIX_ALGO;Algorithm OYCPM +!TP_BWMIX_ALGO_LI;Linear +!TP_BWMIX_ALGO_SP;Special effects +!TP_BWMIX_ALGO_TOOLTIP;Linear: will produce a normal linear response.\nSpecial effects: will produce special effects by mixing channels non-linearly. +!TP_BWMIX_AUTOCH;Auto +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing Channel Mixer. +!TP_BWMIX_CC_ENABLED;Adjust complementary color +!TP_BWMIX_CC_TOOLTIP;Enable to allow automatic adjustment of complementary colors in ROYGCBPM mode. +!TP_BWMIX_CHANNEL;Luminance equalizer +!TP_BWMIX_CURVEEDITOR1;'Before' curve +!TP_BWMIX_CURVEEDITOR2;'After' curve +!TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Tone curve, after B&W conversion, at the end of treatment. +!TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Tone curve, just before B&W conversion.\nMay take into account the color components. +!TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H).\nPay attention to extreme values as they may cause artifacts. +!TP_BWMIX_FILTER;Color Filter +!TP_BWMIX_FILTER_BLUEGREEN;Blue-Green +!TP_BWMIX_FILTER_BLUE;Blue +!TP_BWMIX_FILTER_GREENYELLOW;Green-Yellow +!TP_BWMIX_FILTER_GREEN;Green +!TP_BWMIX_FILTER_NONE;None +!TP_BWMIX_FILTER_PURPLE;Purple +!TP_BWMIX_FILTER_REDYELLOW;Red-Yellow +!TP_BWMIX_FILTER_RED;Red +!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. +!TP_BWMIX_FILTER_YELLOW;Yellow +!TP_BWMIX_GAMMA;Gamma Correction +!TP_BWMIX_GAM_TOOLTIP;Correct gamma for each RGB channel. +!TP_BWMIX_LABEL;Black-and-White +!TP_BWMIX_MET;Method +!TP_BWMIX_MET_CHANMIX;Channel Mixer +!TP_BWMIX_MET_DESAT;Desaturation +!TP_BWMIX_MET_LUMEQUAL;Luminance Equalizer +!TP_BWMIX_MIXC;Mixer +!TP_BWMIX_NEUTRAL;Reset mixer +!TP_BWMIX_NEUTRAL_TIP;Reset all values (Color Filter, Channel Mixer) to default. +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all the mixer options.\n"Total" displays the sum of the RGB values:\n- always 100% in relative mode\n- higher (lighter) or lower (darker) than 100% in absolute mode. +!TP_BWMIX_RGB_TOOLTIP;Mix the RGB channels. Use presets for guidance.\nPay attention to negative values that may cause artifacts or erratic behavior. +!TP_BWMIX_SETTING;Presets +!TP_BWMIX_SETTING_TOOLTIP;Different presets (film, landscape, etc.) or manual Channel Mixer settings. +!TP_BWMIX_SET_HIGHCONTAST;High contrast +!TP_BWMIX_SET_HIGHSENSIT;High Sensitivity +!TP_BWMIX_SET_HYPERPANCHRO;Hyper Panchromatic +!TP_BWMIX_SET_INFRARED;Infrared +!TP_BWMIX_SET_LANDSCAPE;Landscape +!TP_BWMIX_SET_LOWSENSIT;Low Sensitivity +!TP_BWMIX_SET_LUMINANCE;Luminance +!TP_BWMIX_SET_NORMCONTAST;Normal Contrast +!TP_BWMIX_SET_ORTHOCHRO;Orthochromatic +!TP_BWMIX_SET_PANCHRO;Panchromatic +!TP_BWMIX_SET_PORTRAIT;Portrait +!TP_BWMIX_SET_RGBABS;Absolute RGB +!TP_BWMIX_SET_RGBREL;Relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Relative ROYGCBPM +!TP_BWMIX_TCMODE_FILMLIKE;B&W Film-like +!TP_BWMIX_TCMODE_SATANDVALBLENDING;B&W Saturation and Value Blending +!TP_BWMIX_TCMODE_STANDARD;B&W Standard +!TP_BWMIX_TCMODE_WEIGHTEDSTD;B&W Weighted Standard +!TP_BWMIX_VAL;L +!TP_CHROMATABERR_LABEL;Chromatic Aberration +!TP_COLORAPP_ADAPTSCENE;Scene luminosity +!TP_COLORAPP_ADAPTSCENE_TOOLTIP;Absolute luminance of the scene environement (cd/m²).\n1) Calculated from the Exif data:\nShutter speed - ISO speed - F number - camera exposure correction.\n2) Calculated from the raw white point and RT's Exposure Compensation slider. +!TP_COLORAPP_ADAPTVIEWING;Viewing luminosity (cd/m²) +!TP_COLORAPP_ADAPTVIEWING_TOOLTIP;Absolute luminance of the viewing environnement\n(usually 16cd/m²). +!TP_COLORAPP_ADAP_AUTO_TOOLTIP;If the checkbox is checked (recommended) RawTherapee calculates an optimum value from Exif data.\nTo set the value manually, uncheck the checkbox first. +!TP_COLORAPP_ALGO;Algorithm +!TP_COLORAPP_ALGO_ALL;All +!TP_COLORAPP_ALGO_JC;Lightness + Chroma (JC) +!TP_COLORAPP_ALGO_JS;Lightness + Saturation (JS) +!TP_COLORAPP_ALGO_QM;Brightness + Colorfulness (QM) +!TP_COLORAPP_ALGO_TOOLTIP;Lets you choose between parameter subsets or all parameters. +!TP_COLORAPP_BADPIXSL;Hot/bad pixel filter +!TP_COLORAPP_BADPIXSL_TOOLTIP;Suppression of hot/bad (brightly colored) pixels.\n0 = No effect\n1 = Median\n2 = Gaussian.\nAlternatively, adjust the image to avoid very dark shadows.\n\nThese artifacts are due to limitations of CIECAM02. +!TP_COLORAPP_BRIGHT;Brightness (Q) +!TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from L*a*b* and RGB brightness. +!TP_COLORAPP_CHROMA;Chroma (C) +!TP_COLORAPP_CHROMA_M;Colorfulnes (M) +!TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM02 differs from L*a*b* and RGB colorfulness. +!TP_COLORAPP_CHROMA_S;Saturation (S) +!TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from L*a*b* and RGB saturation. +!TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from L*a*b* and RGB chroma. +!TP_COLORAPP_CIECAT_DEGREE;CAT02 adaptation +!TP_COLORAPP_CONTRAST;Contrast (J) +!TP_COLORAPP_CONTRAST_Q;Contrast (Q) +!TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrast in CIECAM02 for the Q slider; it differs from L*a*b* and RGB contrast. +!TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from L*a*b* and RGB contrast. +!TP_COLORAPP_CURVEEDITOR1;Tone curve 1 +!TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L* (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of J or Q after CIECAM02.\n\nJ and Q are not shown in the main histogram panel.\n\nFor final output refer to the main histogram panel. +!TP_COLORAPP_CURVEEDITOR2;Tone curve 2 +!TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Same usage as with the second exposure tone curve. +!TP_COLORAPP_CURVEEDITOR3;Color curve +!TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Adjust either chroma, saturation or colorfulness.\n\nShows the histogram of chromaticity (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of C, s or M after CIECAM02.\n\nC, s and M are not shown in the main histogram panel.\nFor final output refer to the main histogram panel. +!TP_COLORAPP_DATACIE;CIECAM02 output histograms in curves +!TP_COLORAPP_DATACIE_TOOLTIP;When enabled, histograms in CIECAM02 curves show approximate values/ranges for J or Q, and C, s or M after the CIECAM02 adjustments.\nThis selection does not impact the main histogram panel.\n\nWhen disabled, histograms in CIECAM02 curves show L*a*b* values before CIECAM02 adjustments. +!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RawTherapee calculates an optimum value, which is then used by CAT02, and also for the entire CIECAM02.\nTo set the value manually, uncheck the check-box first (values above 65 are recommended). +!TP_COLORAPP_DEGREE_TOOLTIP;Amount of CIE Chromatic Adaptation Transform 2002. +!TP_COLORAPP_GAMUT;Gamut control (L*a*b*) +!TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in L*a*b* mode. +!TP_COLORAPP_HUE;Hue (h) +!TP_COLORAPP_HUE_TOOLTIP;Hue (h) - angle between 0° and 360°. +!TP_COLORAPP_LABEL;CIE Color Appearance Model 2002 +!TP_COLORAPP_LABEL_CAM02;Image Adjustments +!TP_COLORAPP_LABEL_SCENE;Scene Conditions +!TP_COLORAPP_LABEL_VIEWING;Viewing Conditions +!TP_COLORAPP_LIGHT;Lightness (J) +!TP_COLORAPP_LIGHT_TOOLTIP;Lightness in CIECAM02 differs from L*a*b* and RGB lightness. +!TP_COLORAPP_MODEL;WP Model +!TP_COLORAPP_MODEL_TOOLTIP;White-Point Model.\n\nWB [RT] + [output]: RT's white balance is used for the scene, CIECAM02 is set to D50, and the output device's white balance is set in Preferences > Color Management.\n\nWB [RT+CAT02] + [output]: RT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences - Color Management. +!TP_COLORAPP_RSTPRO;Red & skin-tones protection +!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin-tones protection affects both sliders and curves. +!TP_COLORAPP_SHARPCIE;--unused-- +!TP_COLORAPP_SHARPCIE_TOOLTIP;--unused-- +!TP_COLORAPP_SURROUND;Surround +!TP_COLORAPP_SURROUND_AVER;Average +!TP_COLORAPP_SURROUND_DARK;Dark +!TP_COLORAPP_SURROUND_DIM;Dim +!TP_COLORAPP_SURROUND_EXDARK;Extremly Dark (Cutsheet) +!TP_COLORAPP_SURROUND_TOOLTIP;Changes tones and colors to take into account the viewing conditions of the output device.\n\nAverage: Average light environment (standard). The image will not change.\n\nDim: Dim environment (TV). The image will become slighty dark.\n\nDark: Dark environment (projector). The image will become more dark.\n\nExtremly Dark: Extremly dark environment (cutsheet). The image will become very dark. +!TP_COLORAPP_SURSOURCE;Dark surround +!TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if image has a dark border. +!TP_COLORAPP_TCMODE_BRIGHTNESS;Brightness +!TP_COLORAPP_TCMODE_CHROMA;Chroma +!TP_COLORAPP_TCMODE_COLORF;Colorfulness +!TP_COLORAPP_TCMODE_LABEL1;Curve mode 1 +!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_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] +!TP_COLORAPP_WBRT;WB [RT] + [output] +!TP_COLORTONING_AB;o C/L +!TP_COLORTONING_AUTOSAT;Automatic +!TP_COLORTONING_BALANCE;Balance +!TP_COLORTONING_BY;o C/L +!TP_COLORTONING_CHROMAC;Opacity +!TP_COLORTONING_COLOR;Color +!TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;Chroma opacity as a function of luminance oC=f(L) +!TP_COLORTONING_HIGHLIGHT;Highlights +!TP_COLORTONING_HUE;Hue +!TP_COLORTONING_LABEL;Color Toning +!TP_COLORTONING_LAB;L*a*b* blending +!TP_COLORTONING_LUMAMODE;Preserve luminance +!TP_COLORTONING_LUMAMODE_TOOLTIP;If enabled, when you change color (red, green, cyan, blue, etc.) the luminance of each pixel is preserved. +!TP_COLORTONING_LUMA;Luminance +!TP_COLORTONING_METHOD;Method +!TP_COLORTONING_METHOD_TOOLTIP;"L*a*b* blending", "RGB sliders" and "RGB curves" use interpolated color blending.\n"Color balance (Shadows/Midtones/Highlights)" and "Saturation 2 colors" use direct colors.\n\nThe Black-and-White tool can be enabled when using any color toning method, which allows for color toning. +!TP_COLORTONING_MIDTONES;Midtones +!TP_COLORTONING_NEUTRAL;Reset sliders +!TP_COLORTONING_NEUTRAL_TIP;Reset all values (Shadows, Midtones, Highlights) to default. +!TP_COLORTONING_OPACITY;Opacity +!TP_COLORTONING_RGBCURVES;RGB - Curves +!TP_COLORTONING_RGBSLIDERS;RGB - Sliders +!TP_COLORTONING_SATURATEDOPACITY;Strength +!TP_COLORTONING_SATURATIONTHRESHOLD;Threshold +!TP_COLORTONING_SA;Saturation Protection +!TP_COLORTONING_SHADOWS;Shadows +!TP_COLORTONING_SPLITCOCO;Color Balance Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITCO;Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITLR;Saturation 2 colors +!TP_COLORTONING_STRENGTH;Strength +!TP_COLORTONING_STR;Strength +!TP_COLORTONING_TWO2;Special chroma '2 colors' +!TP_COLORTONING_TWOALL;Special chroma +!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_GTFRAME;Frame +!TP_CROP_GTGRID;Grid +!TP_CROP_GTHARMMEANS;Harmonic Means +!TP_CROP_GTTRIANGLE1;Golden Triangles 1 +!TP_CROP_GTTRIANGLE2;Golden Triangles 2 +!TP_CROP_PPI;PPI= +!TP_DARKFRAME_AUTOSELECT;Auto-selection +!TP_DARKFRAME_LABEL;Dark-Frame +!TP_DEFRINGE_LABEL;Defringe +!TP_DEFRINGE_RADIUS;Radius +!TP_DEFRINGE_THRESHOLD;Threshold +!TP_DIRPYRDENOISE_33;3×3 strong +!TP_DIRPYRDENOISE_55SOFT;5×5 +!TP_DIRPYRDENOISE_55;5×5 strong +!TP_DIRPYRDENOISE_77;7×7 (slow) +!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_ABM;Chroma only +!TP_DIRPYRDENOISE_AUTO;Automatic global +!TP_DIRPYRDENOISE_AUTO_TOOLTIP;Try to evaluate chroma noise\nBe careful, this calculation is average, and is quite subjective ! +!TP_DIRPYRDENOISE_AUT;Automatic global +!TP_DIRPYRDENOISE_BLUE;Chrominance - Blue-Yellow +!TP_DIRPYRDENOISE_C2TYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CCCURVE;Chrominance curve +!TP_DIRPYRDENOISE_CHROMAFR;Chrominance +!TP_DIRPYRDENOISE_CHROMA;Chrominance - Master +!TP_DIRPYRDENOISE_CTYPE;Auto method +!TP_DIRPYRDENOISE_CTYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nAutomatic multi-zones\nNo preview - works only during saving, but using the "Preview" method by matching the tile size and center to the preview size and center you can get an idea of the expected results.\nThe image is divided into tiles (about 10 to 70 depending on image size) and each tile receives its own chrominance noise reduction settings.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CURVEEDITOR_CC;Chroma +!TP_DIRPYRDENOISE_CURVEEDITOR_CC_TOOLTIP;Increase (multiply) the value of all chrominance sliders.\nThis curve lets you adjust the strength of chromatic noise reduction as a function of chromaticity, for instance to increase the action in areas of low saturation and to decrease it in those of high saturation. +!TP_DIRPYRDENOISE_CURVEEDITOR_L_TOOLTIP;Modulates action of 'Luminance' denoise +!TP_DIRPYRDENOISE_CUR;Curve +!TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on the gamma of the input color profile. An sRGB gamma is assumed, thus if the image uses an input color profile of a different gamma, the effects of luminance noise reduction will differ. +!TP_DIRPYRDENOISE_ENH;Enhanced mode +!TP_DIRPYRDENOISE_ENH_TOOLTIP;Increases noise reduction quality at the expense of a 20% processing time increase. +!TP_DIRPYRDENOISE_GAMMA;Gamma +!TP_DIRPYRDENOISE_GAMMA_TOOLTIP;Gamma varies noise reduction strength across the range of tones. Smaller values will target shadows, while larger values will stretch the effect to the brighter tones. +!TP_DIRPYRDENOISE_LABEL;Noise Reduction +!TP_DIRPYRDENOISE_LABM;L*a*b* +!TP_DIRPYRDENOISE_LAB;L*a*b* +!TP_DIRPYRDENOISE_LCURVE;Luminance curve +!TP_DIRPYRDENOISE_LDETAIL;Luminance - Detail +!TP_DIRPYRDENOISE_LM;Luminance only +!TP_DIRPYRDENOISE_LPLABM;Weighted L* (little) + a*b* (normal) +!TP_DIRPYRDENOISE_LTYPE;Luminance control +!TP_DIRPYRDENOISE_LUMAFR;Luminance +!TP_DIRPYRDENOISE_LUMAFR_TOOLTIP;Wavelet on luminance and Fourier transform for luminance detail +!TP_DIRPYRDENOISE_LUMA;Luminance +!TP_DIRPYRDENOISE_MANU;Manual +!TP_DIRPYRDENOISE_MAN;Manual +!TP_DIRPYRDENOISE_MEDMETHOD;Median method +!TP_DIRPYRDENOISE_MEDTYPE;Median type +!TP_DIRPYRDENOISE_MED;Median Filter +!TP_DIRPYRDENOISE_MED_TOOLTIP;Enabled median denoising +!TP_DIRPYRDENOISE_METHOD11;Quality +!TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. +!TP_DIRPYRDENOISE_METHOD;Method +!TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or L*a*b* methods can be used.\n\nFor non-raw images the L*a*b* method will be used, regardless of the selection. +!TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - +!TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 +!TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. +!TP_DIRPYRDENOISE_PASSES;Median iterations +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PON;Auto multi-zones +!TP_DIRPYRDENOISE_PREVLABEL;Preview size=%1, Center: Px=%2 Py=%3 +!TP_DIRPYRDENOISE_PREV;Preview +!TP_DIRPYRDENOISE_PRE;Preview multi-zones +!TP_DIRPYRDENOISE_RED;Chrominance - Red-Green +!TP_DIRPYRDENOISE_RGBM;RGB +!TP_DIRPYRDENOISE_RGB;RGB +!TP_DIRPYRDENOISE_SHALBI;High +!TP_DIRPYRDENOISE_SHAL;Standard +!TP_DIRPYRDENOISE_SLI;Slider +!TP_DIRPYRDENOISE_SOFT;3x3 +!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_LUMAFINEST;Finest +!TP_DIRPYREQUALIZER_LUMANEUTRAL;Neutral +!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_THRESHOLD;Threshold +!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;Auto Distortion Correction +!TP_DISTORTION_AUTO_TIP;Correct lens distortion automatically for some cameras (Micro 4/3, some compact digital cameras, etc.). +!TP_EPD_EDGESTOPPING;Edge stopping +!TP_EPD_GAMMA;Gamma +!TP_EPD_LABEL;Tone Mapping +!TP_EPD_REWEIGHTINGITERATES;Reweighting iterates +!TP_EPD_SCALE;Scale +!TP_EPD_STRENGTH;Strength +!TP_EPD_TOOLTIP;Tone mapping is possible in L*a*b* mode (standard) and CIECAM02 mode.\n\nWhen in L*a*b* mode, tone mapping can also be used on the residual image of the Wavelet Levels tool.\n\nTo engage CIECAM02 tone mapping mode enable the following settings:\n1. CIECAM02\n2. Algorithm="Brightness + Colorfulness (QM)"\n3. "Tone mapping using CIECAM02 brightness (Q)" +!TP_EXPOSURE_AUTOLEVELS_TIP;Toggles execution of Auto Levels to automatically set Exposure slider values based on an image analysis.\nEnables Highlight Reconstruction if necessary. +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in Auto Levels operation. +!TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Highlight compression threshold +!TP_EXPOSURE_CURVEEDITOR1;Tone curve 1 +!TP_EXPOSURE_CURVEEDITOR2;Tone curve 2 +!TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Please refer to the "Exposure > Tone Curves" RawPedia article to learn how to achieve the best results by using two tone curves. +!TP_EXPOSURE_SATURATION;Saturation +!TP_EXPOSURE_TCMODE_FILMLIKE;Film-like +!TP_EXPOSURE_TCMODE_LABEL1;Curve mode 1 +!TP_EXPOSURE_TCMODE_LABEL2;Curve mode 2 +!TP_EXPOSURE_TCMODE_LUMINANCE;Luminance +!TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Saturation and Value Blending +!TP_EXPOSURE_TCMODE_STANDARD;Standard +!TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard +!TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points +!TP_EXPOS_WHITEPOINT_LABEL;Raw White Points +!TP_FILMSIMULATION_LABEL;Film Simulation +!TP_FILMSIMULATION_STRENGTH;Strength +!TP_FILMSIMULATION_ZEROCLUTSFOUND;Set HaldCLUT directory in Preferences +!TP_FLATFIELD_AUTOSELECT;Auto-selection +!TP_FLATFIELD_BLURRADIUS;Blur radius +!TP_FLATFIELD_BLURTYPE;Blur type +!TP_FLATFIELD_BT_AREA;Area +!TP_FLATFIELD_BT_HORIZONTAL;Horizontal +!TP_FLATFIELD_BT_VERTHORIZ;Vertical + Horizontal +!TP_FLATFIELD_BT_VERTICAL;Vertical +!TP_FLATFIELD_CLIPCONTROL;Clip control +!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. +!TP_FLATFIELD_LABEL;Flat-Field +!TP_GAMMA_CURV;Gamma +!TP_GAMMA_FREE;Free gamma +!TP_GAMMA_OUTPUT;Output gamma +!TP_GAMMA_SLOP;Slope (linear) +!TP_GENERAL_11SCALE_TOOLTIP;The effects of this tool are only visible or only accurate at a preview scale of 1:1. +!TP_GRADIENT_CENTER;Center +!TP_GRADIENT_CENTER_X;Center X +!TP_GRADIENT_CENTER_X_TOOLTIP;Shift gradient to the left (negative values) or right (positive values). +!TP_GRADIENT_CENTER_Y;Center Y +!TP_GRADIENT_CENTER_Y_TOOLTIP;Shift gradient up (negative values) or down (positive values). +!TP_GRADIENT_DEGREE;Angle +!TP_GRADIENT_DEGREE_TOOLTIP;Rotation angle in degrees. +!TP_GRADIENT_FEATHER;Feather +!TP_GRADIENT_FEATHER_TOOLTIP;Gradient width in percent of the image diagonal. +!TP_GRADIENT_LABEL;Graduated Filter +!TP_GRADIENT_STRENGTH;Strength +!TP_GRADIENT_STRENGTH_TOOLTIP;Filter strength in stops. +!TP_HLREC_BLEND;Blend +!TP_HLREC_ENA_TOOLTIP;Could be activated by Auto Levels. +!TP_HSVEQUALIZER_CHANNEL;Channel +!TP_HSVEQUALIZER_HUE;H +!TP_HSVEQUALIZER_LABEL;HSV Equalizer +!TP_HSVEQUALIZER_SAT;S +!TP_HSVEQUALIZER_VAL;V +!TP_ICM_BLENDCMSMATRIX;Blend ICC highlights with matrix +!TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover clipped highlights when using LUT-based ICC profiles. +!TP_ICM_DCPILLUMINANT;Illuminant +!TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolated +!TP_ICM_DCPILLUMINANT_TOOLTIP;Select which embedded DCP illuminant to employ. Default is "interpolated" which is a mix between the two based on white balance. The setting is only enabled if a Dual-Illuminant DCP with interpolation support is selected. +!TP_ICM_INPUTCAMERAICC;Auto-matched camera profile +!TP_ICM_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input color profiles. These profiles are more precise than simpler matrix ones. They are not available for all cameras. These profiles are stored in the /iccprofiles/input and /dcpprofiles folders and are automatically retrieved based on a file name matching to the exact model name of the camera. +!TP_ICM_INPUTCAMERA_TOOLTIP;Use a simple color matrix from dcraw, an enhanced RawTherapee version (whichever is available based on camera model) or one embedded in the DNG. +!TP_ICM_INPUTCUSTOM_TOOLTIP;Select your own DCP/ICC color profile file for the camera. +!TP_ICM_INPUTEMBEDDED_TOOLTIP;Use color profile embedded in non-raw files. +!TP_ICM_INPUTNONE;No profile +!TP_ICM_INPUTNONE_TOOLTIP;Use no input color profile at all.\nUse only in special cases. +!TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance +!TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. The result can be used for calibration purposes and generation of a camera profile. +!TP_ICM_TONECURVE;Use DCP's tone curve +!TP_ICM_TONECURVE_TOOLTIP;Employ the embedded DCP tone curve. The setting is only enabled if the selected DCP has a tone curve. +!TP_IMPULSEDENOISE_LABEL;Impulse Noise Reduction +!TP_IMPULSEDENOISE_THRESH;Threshold +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid color shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction. +!TP_LABCURVE_BRIGHTNESS;Lightness +!TP_LABCURVE_CHROMATICITY;Chromaticity +!TP_LABCURVE_CHROMA_TOOLTIP;To apply B&W toning, set Chromaticity to -100. +!TP_LABCURVE_CONTRAST;Contrast +!TP_LABCURVE_CURVEEDITOR;Luminance Curve +!TP_LABCURVE_CURVEEDITOR_A_RANGE1;Green Saturated +!TP_LABCURVE_CURVEEDITOR_A_RANGE2;Green Pastel +!TP_LABCURVE_CURVEEDITOR_A_RANGE3;Red Pastel +!TP_LABCURVE_CURVEEDITOR_A_RANGE4;Red Saturated +!TP_LABCURVE_CURVEEDITOR_B_RANGE1;Blue Saturated +!TP_LABCURVE_CURVEEDITOR_B_RANGE2;Blue Pastel +!TP_LABCURVE_CURVEEDITOR_B_RANGE3;Yellow Pastel +!TP_LABCURVE_CURVEEDITOR_B_RANGE4;Yellow Saturated +!TP_LABCURVE_CURVEEDITOR_CC;CC +!TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutral +!TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Dull +!TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastel +!TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Saturated +!TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Chromaticity according to chromaticity C=f(C) +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to hue C=f(H) +!TP_LABCURVE_CURVEEDITOR_CL;CL +!TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Chromaticity according to luminance C=f(L) +!TP_LABCURVE_CURVEEDITOR_HH;HH +!TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Hue according to hue H=f(H) +!TP_LABCURVE_CURVEEDITOR_LC;LC +!TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminance according to chromaticity L=f(C) +!TP_LABCURVE_CURVEEDITOR_LH;LH +!TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H) +!TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminance according to luminance L=f(L) +!TP_LABCURVE_LABEL;L*a*b* Adjustments +!TP_LABCURVE_LCREDSK;Restrict LC to red and skin-tones +!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_LENSGEOM_AUTOCROP;Auto-Crop +!TP_LENSGEOM_FILL;Auto-fill +!TP_LENSGEOM_LABEL;Lens / Geometry +!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_USECA;Chromatic aberration correction +!TP_LENSPROFILE_USEDIST;Distortion correction +!TP_LENSPROFILE_USEVIGN;Vignetting correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Resets exposure sliders to neutral values.\nApplies to the same controls that Auto Levels applies to, regardless of whether you used Auto Levels or not. +!TP_PCVIGNETTE_FEATHER;Feather +!TP_PCVIGNETTE_FEATHER_TOOLTIP;Feathering:\n0 = corners only,\n50 = halfway to center,\n100 = to center. +!TP_PCVIGNETTE_LABEL;Vignette Filter +!TP_PCVIGNETTE_ROUNDNESS;Roundness +!TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness:\n0 = rectangle,\n50 = fitted ellipse,\n100 = circle. +!TP_PCVIGNETTE_STRENGTH;Strength +!TP_PCVIGNETTE_STRENGTH_TOOLTIP;Filter strength in stops (reached in corners). +!TP_PERSPECTIVE_HORIZONTAL;Horizontal +!TP_PERSPECTIVE_LABEL;Perspective +!TP_PERSPECTIVE_VERTICAL;Vertical +!TP_PFCURVE_CURVEEDITOR_CH;Hue +!TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Controls defringe strength by color.\nHigher = more,\nLower = less. +!TP_PREPROCESS_DEADPIXFILT;Dead pixel filter +!TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Tries to suppress dead pixels. +!TP_PREPROCESS_GREENEQUIL;Green equilibration +!TP_PREPROCESS_HOTPIXFILT;Hot pixel filter +!TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Tries to suppress hot pixels. +!TP_PREPROCESS_LABEL;Preprocessing +!TP_PREPROCESS_LINEDENOISE;Line noise filter +!TP_PREPROCESS_NO_FOUND;None found +!TP_RAWCACORR_AUTO;Auto-correction +!TP_RAWCACORR_CABLUE;Blue +!TP_RAWCACORR_CARED;Red +!TP_RAWEXPOS_BLACKS;Black Levels +!TP_RAWEXPOS_BLACK_0;Green 1 (lead) +!TP_RAWEXPOS_BLACK_1;Red +!TP_RAWEXPOS_BLACK_2;Blue +!TP_RAWEXPOS_BLACK_3;Green 2 +!TP_RAWEXPOS_BLACK_BLUE;Blue +!TP_RAWEXPOS_BLACK_GREEN;Green +!TP_RAWEXPOS_BLACK_RED;Red +!TP_RAWEXPOS_LINEAR;White-point correction +!TP_RAWEXPOS_PRESER;Highlight preservation +!TP_RAWEXPOS_RGB;Red, Green, Blue +!TP_RAWEXPOS_TWOGREEN;Link greens +!TP_RAW_DCBENHANCE;DCB enhancement +!TP_RAW_DCBITERATIONS;Number of DCB iterations +!TP_RAW_DMETHOD;Method +!TP_RAW_DMETHOD_PROGRESSBAR;%1 demosaicing... +!TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Demosaicing refinement... +!TP_RAW_DMETHOD_TOOLTIP;Note: IGV and LMMSE are dedicated to high ISO images to aid in noise reduction without leading to maze patterns, posterization or a washed-out look. +!TP_RAW_FALSECOLOR;False color suppression steps +!TP_RAW_HD;Threshold +!TP_RAW_HD_TOOLTIP;Lower values make hot/dead pixel detection more aggressive, but false positives may lead to artifacts. If you notice any artifacts appearing when enabling the Hot/Dead Pixel Filters, gradually increase the threshold value until they disappear. +!TP_RAW_LABEL;Demosaicing +!TP_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!TP_RAW_LMMSE_TOOLTIP;Adds gamma (step 1), median (steps 2-4) and refinement (steps 5-6) to reduce artifacts and improve the signal-to-noise ratio. +!TP_RAW_SENSOR_BAYER_LABEL;Sensor with Bayer Matrix +!TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;3-pass gives best results (recommended for low ISO images).\n1-pass is almost undistinguishable from 3-pass for high ISO images and is faster. +!TP_RAW_SENSOR_XTRANS_LABEL;Sensor with X-Trans Matrix +!TP_RESIZE_APPLIESTO;Applies to: +!TP_RESIZE_CROPPEDAREA;Cropped Area +!TP_RESIZE_FITBOX;Bounding Box +!TP_RESIZE_FULLIMAGE;Full Image +!TP_RESIZE_LANCZOS;Lanczos +!TP_RGBCURVES_BLUE;B +!TP_RGBCURVES_CHANNEL;Channel +!TP_RGBCURVES_GREEN;G +!TP_RGBCURVES_LABEL;RGB Curves +!TP_RGBCURVES_LUMAMODE;Luminosity mode +!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_RGBCURVES_RED;R +!TP_SAVEDIALOG_OK_TIP;Shortcut: Ctrl-Enter +!TP_SHADOWSHLIGHTS_SHARPMASK;Sharp mask +!TP_SHARPENEDGE_AMOUNT;Quantity +!TP_SHARPENEDGE_LABEL;Edges +!TP_SHARPENEDGE_PASSES;Iterations +!TP_SHARPENEDGE_THREE;Luminance only +!TP_SHARPENING_TOOLTIP;Expect a slightly different effect when using with CIECAM02. If difference is observed, adjust to taste. +!TP_SHARPENMICRO_AMOUNT;Quantity +!TP_SHARPENMICRO_LABEL;Microcontrast +!TP_SHARPENMICRO_MATRIX;3×3 matrix instead of 5×5 +!TP_SHARPENMICRO_UNIFORMITY;Uniformity +!TP_VIBRANCE_AVOIDCOLORSHIFT;Avoid color shift +!TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Red/Purple +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Red +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Red/Yellow +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Yellow +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Hue according to hue H=f(H) +!TP_VIBRANCE_LABEL;Vibrance +!TP_VIBRANCE_PASTELS;Pastel Tones +!TP_VIBRANCE_PASTSATTOG;Link pastel and saturated tones +!TP_VIBRANCE_PROTECTSKINS;Protect skin-tones +!TP_VIBRANCE_PSTHRESHOLD;Pastel/saturated tones threshold +!TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Saturation threshold +!TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;The vertical axis represents pastel tones at the bottom and saturated tones at the top.\nThe horizontal axis represents the saturation range. +!TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Pastel/saturated transition's weighting +!TP_VIBRANCE_SATURATED;Saturated Tones +!TP_VIGNETTING_CENTER;Center +!TP_VIGNETTING_CENTER_X;Center X +!TP_VIGNETTING_CENTER_Y;Center Y +!TP_VIGNETTING_STRENGTH;Strength +!TP_WAVELET_1;Level 1 +!TP_WAVELET_2;Level 2 +!TP_WAVELET_3;Level 3 +!TP_WAVELET_4;Level 4 +!TP_WAVELET_5;Level 5 +!TP_WAVELET_6;Level 6 +!TP_WAVELET_7;Level 7 +!TP_WAVELET_8;Level 8 +!TP_WAVELET_9;Level 9 +!TP_WAVELET_ALL;All levels in all directions +!TP_WAVELET_APPLYTO;Apply To +!TP_WAVELET_AVOID;Avoid color shift +!TP_WAVELET_B0;Black +!TP_WAVELET_B1;Grey +!TP_WAVELET_B2;Residual +!TP_WAVELET_BACUR;Curve +!TP_WAVELET_BALANCE;Contrast balance d/v-h +!TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chromaticity or residual tone mapping are activated, the effect due to balance is amplified. +!TP_WAVELET_BALCHRO;Chroma balance +!TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chromaticity balance. +!TP_WAVELET_BANONE;None +!TP_WAVELET_BASLI;Slider +!TP_WAVELET_BATYPE;Contrast balance method +!TP_WAVELET_CCURVE;Local contrast +!TP_WAVELET_CH1;Whole chromaticity range +!TP_WAVELET_CH2;Saturated/pastel +!TP_WAVELET_CH3;Link contrast levels +!TP_WAVELET_CHCU;Curve +!TP_WAVELET_CHRO;Saturated/pastel threshold +!TP_WAVELET_CHRO_TOOLTIP;Sets the wavelet level which will be the threshold between saturated and pastel colors.\n1-x: saturated\nx-9: pastel\n\nIf the value exceeds the amount of wavelet levels you are using then it will be ignored. +!TP_WAVELET_CHR;Chroma-contrast link strength +!TP_WAVELET_CHR_TOOLTIP;Adjusts chromaticity as a function of "contrast levels" and "chroma-contrast link strength" +!TP_WAVELET_CHSL;Sliders +!TP_WAVELET_CHTYPE;Chrominance method +!TP_WAVELET_COLORT;Opacity Red-Green +!TP_WAVELET_COMBOTH;Both +!TP_WAVELET_COMPCONT;Contrast +!TP_WAVELET_COMPGAMMA;Compression gamma +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjusting the gamma of the residual image allow you to equilibrate the data and histogram. +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjust gamma for residual image and compression.\nAllow to equilibrate data and histogram +!TP_WAVELET_COMPTM;Tone mapping +!TP_WAVELET_CONTEDIT;'After' Contrast curve +!TP_WAVELET_CONTEDIT;'After' contrast curve +!TP_WAVELET_CONTRAST_MINUS;Contrast - +!TP_WAVELET_CONTRAST_PLUS;Contrast + +!TP_WAVELET_CONTRA;Contrast +!TP_WAVELET_CONTRA_TOOLTIP;Changes contrast of the residual image. +!TP_WAVELET_CONTR;Gamut +!TP_WAVELET_CTYPE;Chrominance control +!TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modifies local contrast as a function of the original local contrast (absciss)\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 100..300)\n66% absciss represents standard deviation of local contrast (real value about 300..800)\n100% represents maximum (real value about 3000..8000) +!TP_WAVELET_CURVEEDITOR_CH;Contrast levels=f(Hue) +!TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modifies each level's contrast as a function oh hue.\nTake care not to overwrite changes made with the Gamut Hue controls.\nThe curve will only have an effect when wavelet contrast level sliders are non-zero. +!TP_WAVELET_CURVEEDITOR_CL;L +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Applies a final contrast luminance curve at the end of the wavelet treatment. +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Apply a contrast luminance curve at the end of wavelet level threatment +!TP_WAVELET_CURVEEDITOR_HH;HH +!TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modifies the residual image's hue as a function of hue. +!TP_WAVELET_DALL;All directions +!TP_WAVELET_DAUB;Edge performance +!TP_WAVELET_DAUB_TOOLTIP;Changes Daubechies coefficients:\nD4 = Standard,\nD14 = Often best performance, 10% more time-intensive.\n\nAffects edge detection as well as the general quality of the firsts levels. However the quality is not strictly related to this coefficient and can vary with images and uses. +!TP_WAVELET_DISP;Preview Settings +!TP_WAVELET_DONE;Vertical +!TP_WAVELET_DTHR;Diagonal +!TP_WAVELET_DTWO;Horizontal +!TP_WAVELET_EDCU;Curve +!TP_WAVELET_EDGCONT;Local contrast +!TP_WAVELET_EDGCONT_TOOLTIP;Adjusting the points to the left decreases contrast, and to the right increases it.\nBottom-left, Top-Left, Top-Right, Bottom-right represent respectively local contast for low values, mean, mean+stdev, maxima +!TP_WAVELET_EDGEDETECTTHR2;Threshold high (detection) +!TP_WAVELET_EDGEDETECTTHR;Threshold low (noise) +!TP_WAVELET_EDGEDETECTTHR_TOOLTIP;This adjuster lets you target edge detection for example to avoid applying edge sharpness to fine details, such as noise in the sky. +!TP_WAVELET_EDGEDETECT;Gradient sensitivity +!TP_WAVELET_EDGEDETECT_TOOLTIP;Moving the slider to the right increases edge sensitivity. This affects local contrast, edge settings and noise. +!TP_WAVELET_EDGE;Edge Sharpness +!TP_WAVELET_EDGREINF_TOOLTIP;Reinforce or reduce the action of the first level, do the opposite to the second level, and leave the rest unchanged. +!TP_WAVELET_EDGTHRESH;Detail +!TP_WAVELET_EDGTHRESH_TOOLTIP;Change the repartition between the first levels and the others. The higher the threshold the more the action is centred on the first levels. Be careful with negative values, they increase the action of high levels and can introduce artifacts. +!TP_WAVELET_EDRAD;Radius +!TP_WAVELET_EDRAD_TOOLTIP;This radius adjustment is very different from those in other sharpening tools. Its value is compared to each level through a complex function. In this sense, a value of zero still has an effect. +!TP_WAVELET_EDSL;Threshold Sliders +!TP_WAVELET_EDTYPE;Local contrast method +!TP_WAVELET_EDVAL;Strength +!TP_WAVELET_FINAL;Final Touchup +!TP_WAVELET_FINEST;Finest +!TP_WAVELET_HIGHLIGHT;Highlight luminance range +!TP_WAVELET_HS1;Whole luminance range +!TP_WAVELET_HS2;Shadows/Highlights +!TP_WAVELET_HUESKIN;Skin hue +!TP_WAVELET_HUESKIN_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_HUESKY;Sky hue +!TP_WAVELET_HUESKY_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_INF;Below or equal the level +!TP_WAVELET_ITER;Delta balance levels +!TP_WAVELET_ITER_TOOLTIP;Left: increase low levels and reduce high levels,\nRight: reduce low levels and increase high levels. +!TP_WAVELET_LABEL;Wavelet levels +!TP_WAVELET_LARGEST;Coarsest +!TP_WAVELET_LEVCH;Chromaticity +!TP_WAVELET_LEVELS;Wavelet levels +!TP_WAVELET_LEVELS_TOOLTIP;Choose the number of detail levels the image is to be decomposed into. More levels require more RAM and require a longer processing time. +!TP_WAVELET_LEVF;Contrast +!TP_WAVELET_LEVLABEL;Preview maximum possible levels = %1 +!TP_WAVELET_LEVONE;Level 2 +!TP_WAVELET_LEVTWO;Level 3 +!TP_WAVELET_LEVZERO;Level 1 +!TP_WAVELET_LINKEDG;Link with Edge Sharpness' Strength +!TP_WAVELET_LIPST;Enhanced algorithm +!TP_WAVELET_LIPST_TOOLTIP;This algorithm uses Lipschitz regularity to increase edge detection quality at a cost of increased processing time and memory requirements. +!TP_WAVELET_LOWLIGHT;Shadow luminance range +!TP_WAVELET_MEDGREINF;First level +!TP_WAVELET_MEDILEV;Edge detection +!TP_WAVELET_MEDI;Reduce artifacts in blue sky +!TP_WAVELET_NEUTRAL;Neutral +!TP_WAVELET_NOISE;Denoise and Refine +!TP_WAVELET_NOIS;Denoise +!TP_WAVELET_ONE;One level +!TP_WAVELET_OPACITYWL;Final local contrast +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify final local contrast in function of last local contrast (absciss) for all levels decomposition\nTake into account: \na)contrast levels \nb)edge sharpness \nc)contrast balance\nd)decomposition-recomposition\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 200..1000)\n66% absciss represents standard deviation of local contrast (real value about 1000..2000)\n100% represents maximum (real value about 5000..13000) +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify the final local contrast at the end of the wavelet treatment.\n\nThe left side represents the smallest local contrast, progressing to the largest local contrast on the right. +!TP_WAVELET_OPACITYW;Contrast balance d/v-h curve +!TP_WAVELET_OPACITY;Opacity Blue-Yellow +!TP_WAVELET_PASTEL;Pastel chromaticity +!TP_WAVELET_PREVIEWBACK;Background +!TP_WAVELET_PREVIEWLEVELS;Preview +!TP_WAVELET_RE1;Reinforced +!TP_WAVELET_RE2;Unchanged +!TP_WAVELET_RE3;Reduced +!TP_WAVELET_RESCHRO;Chromaticity +!TP_WAVELET_RESCONH;Highlights +!TP_WAVELET_RESCON;Shadows +!TP_WAVELET_RESID;Residual image +!TP_WAVELET_SAT;Saturated chromaticity +!TP_WAVELET_SETTINGS;Wavelet Settings +!TP_WAVELET_SKIN;Skin targetting/protection +!TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected. +!TP_WAVELET_SKY;Sky targetting/protection +!TP_WAVELET_SKY_TOOLTIP;At -100 sky-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 sky-tones are protected while all other tones are affected. +!TP_WAVELET_STRENGTH;Strength +!TP_WAVELET_STREN;Strength +!TP_WAVELET_SUPE;Extra +!TP_WAVELET_SUP;Above the level +!TP_WAVELET_THRESHOLD2;Shadow levels +!TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels between 9 and 9 minus the value will be affected by the shadow luminance range. Other levels will be fully treated. The highest level possible is limited by the highlight level value (9 minus highlight level value). +!TP_WAVELET_THRESHOLD;Highlight levels +!TP_WAVELET_THRESHOLD_TOOLTIP;Only levels beyond the chosen value will be affected by the highlight luminance range. Other levels will be fully treated. The chosen value here limits the highest possible value of the shadow levels. +!TP_WAVELET_THRH;Highlights threshold +!TP_WAVELET_THR;Shadows threshold +!TP_WAVELET_TILESBIG;Big tiles +!TP_WAVELET_TILESFULL;Full image +!TP_WAVELET_TILESIZE;Tiling method +!TP_WAVELET_TILESLIT;Little tiles +!TP_WAVELET_TILES_TOOLTIP;Processing the full image leads to better quality and is the recommended option, while using tiles is a fall-back solution for users with little RAM. Refer to RawPedia for memory requirements. +!TP_WAVELET_TMHIGH;High +!TP_WAVELET_TMLOWHIGH;Low+High +!TP_WAVELET_TMNONE;None +!TP_WAVELET_TMSTD;Standard +!TP_WAVELET_TMSTRENGTH;Compression strength +!TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image. When the value is different from 0, the Strength and Gamma sliders of the Tone Mapping tool in the Exposure tab will become grayed out. +!TP_WAVELET_TMTYPE;Compression method +!TP_WAVELET_TON;Toning +!TP_WAVELET_daub2;D2 - low +!TP_WAVELET_daub4;D4 - standard +!TP_WAVELET_daub6;D6 - standard plus +!TP_WAVELET_daub10;D10 - medium +!TP_WAVELET_daub14;D14 - high +!TP_WBALANCE_CLOUDY;Cloudy +!TP_WBALANCE_DAYLIGHT;Daylight (sunny) +!TP_WBALANCE_EQBLUERED;Blue/Red equalizer +!TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behavior of "white balance" by modulating the blue/red balance.\nThis can be useful when shooting conditions:\na) are far from the standard illuminant (e.g. underwater),\nb) are far from conditions where calibrations were performed,\nc) where the matrices or ICC profiles are unsuitable. +!TP_WBALANCE_FLASH55;Leica +!TP_WBALANCE_FLASH60;Standard, Canon, Pentax, Olympus +!TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta +!TP_WBALANCE_FLASH_HEADER;Flash +!TP_WBALANCE_FLUO1;F1 - Daylight +!TP_WBALANCE_FLUO2;F2 - Cool White +!TP_WBALANCE_FLUO3;F3 - White +!TP_WBALANCE_FLUO4;F4 - Warm White +!TP_WBALANCE_FLUO5;F5 - Daylight +!TP_WBALANCE_FLUO6;F6 - Lite White +!TP_WBALANCE_FLUO7;F7 - D65 Daylight Simulator +!TP_WBALANCE_FLUO8;F8 - D50 / Sylvania F40 Design +!TP_WBALANCE_FLUO9;F9 - Cool White Deluxe +!TP_WBALANCE_FLUO10;F10 - Philips TL85 +!TP_WBALANCE_FLUO11;F11 - Philips TL84 +!TP_WBALANCE_FLUO12;F12 - Philips TL83 +!TP_WBALANCE_FLUO_HEADER;Fluorescent +!TP_WBALANCE_GTI;GTI +!TP_WBALANCE_HMI;HMI +!TP_WBALANCE_JUDGEIII;JudgeIII +!TP_WBALANCE_LAMP_HEADER;Lamp +!TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 +!TP_WBALANCE_LED_HEADER;LED +!TP_WBALANCE_LED_LSI;LSI Lumelex 2040 +!TP_WBALANCE_SHADE;Shade +!TP_WBALANCE_SOLUX35;Solux 3500K +!TP_WBALANCE_SOLUX41;Solux 4100K +!TP_WBALANCE_SOLUX47;Solux 4700K (vendor) +!TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) +!TP_WBALANCE_TUNGSTEN;Tungsten +!TP_WBALANCE_WATER1;UnderWater 1 +!TP_WBALANCE_WATER2;UnderWater 2 +!TP_WBALANCE_WATER_HEADER;UnderWater +!ZOOMPANEL_100;(100%) +!ZOOMPANEL_NEWCROPWINDOW;Open (new) detail window +!ZOOMPANEL_ZOOM100;Zoom to 100%\nShortcut: z +!ZOOMPANEL_ZOOMFITCROPSCREEN;Fit crop to screen\nShortcut: Alt-f +!ZOOMPANEL_ZOOMFITSCREEN;Fit whole image to screen\nShortcut: f +!ZOOMPANEL_ZOOMIN;Zoom In\nShortcut: + +!ZOOMPANEL_ZOOMOUT;Zoom Out\nShortcut: - diff --git a/rtdata/languages/Czech b/rtdata/languages/Czech new file mode 100644 index 000000000..40c28ce7e --- /dev/null +++ b/rtdata/languages/Czech @@ -0,0 +1,1885 @@ +#00 Czech +#01 2008-01-20 translated by absolution +#02 2008-02-21 updated by mkyral (typos and some missing strings) +#03 2008-04-24 updated by mkyral (for version 2.4m1) +#04 2008-10-28 updated by mkyral (for version 2.4 beta1) +#05 2010-11-25 updated by mkyral (for version 3.0) +#06 2011-03-06 updated by mkyral (default branch) +#07 2011-03-20 updated by mkyral (default branch) +#08 2011-05-01 updated by mkyral +#09 2011-05-18 updated by mkyral +#10 2011-06-04 updated by mkyral +#11 2011-06-12 updated by mkyral +#12 2011-06-16 updated by mkyral +#13 2011-07-03 updated by mkyral +#14 2011-07-08 updated by mkyral +#15 2011-09-04 updated by mkyral +#16 2011-09-06 updated by mkyral +#17 2011-11-12 updated by mkyral +#18 2011-12-29 updated by mkyral +#19 2012-02-22 updated by mkyral +#20 2012-04-28 updated by mkyral +#21 2012-10-10 updated by mkyral +#22 2012-11-27 updated by mkyral +#23 2013-03-12 updated by mkyral +#24 2013-04-12 updated by mkyral +#25 2013-09-12 updated by mkyral +#26 2013-09-17 updated by mkyral +#27 2013-12-09 updated by mkyral +#28 2014-01-07 updated by mkyral +#29 2014-04-08 updated by mkyral +#30 2014-04-30 updated by mkyral +#31 2014-05-12 updated by mkyral +#32 2014-10-24 updated by mkyral +#33 2015-02-22 updated by mkyral + +ABOUT_TAB_BUILD;Verze +ABOUT_TAB_CREDITS;Zásluhy +ABOUT_TAB_LICENSE;Licence +ABOUT_TAB_RELEASENOTES;Poznámky k vydání +ABOUT_TAB_SPLASH;Úvodní obrazovka +ADJUSTER_RESET_TO_DEFAULT;Vrátit se k původnímu +BATCHQUEUE_AUTOSTART;Automatický start +BATCHQUEUE_DESTFILENAME;Cesta a název souboru +BATCH_PROCESSING;Dávkové zpracování +CURVEEDITOR_CURVES;Křivky +CURVEEDITOR_CURVE;Křivka +CURVEEDITOR_CUSTOM;Vlastní +CURVEEDITOR_DARKS;Tmavé +CURVEEDITOR_HIGHLIGHTS;Světla +CURVEEDITOR_LIGHTS;Světlé +CURVEEDITOR_LINEAR;Lineární +CURVEEDITOR_LOADDLGLABEL;Načíst křivku... +CURVEEDITOR_MINMAXCPOINTS;Korekce +CURVEEDITOR_NURBS;Kontrolní síť +CURVEEDITOR_PARAMETRIC;Parametrická +CURVEEDITOR_SAVEDLGLABEL;Uložit křivku... +CURVEEDITOR_SHADOWS;Stíny +CURVEEDITOR_TOOLTIPCOPY;Uložit aktuální křivku do schránky. +CURVEEDITOR_TOOLTIPLINEAR;Vrátit se k lineární křivce. +CURVEEDITOR_TOOLTIPLOAD;Načíst křivku ze souboru. +CURVEEDITOR_TOOLTIPPASTE;Vložit křivku ze schránky. +CURVEEDITOR_TOOLTIPSAVE;Uložit současnou křivku. +CURVEEDITOR_TYPE;Typ +DIRBROWSER_FOLDERS;Složky +EDITWINDOW_TITLE;Editace obrázku +EDIT_OBJECT_TOOLTIP;V náhledovém okně zobrazí widget umožňující přizpůsobení nástroje. +EDIT_PIPETTE_TOOLTIP;Pro přidání bodu na křivku, podržte klávesu Ctrl a klikněte levým tlačítkem na vybraný bod v náhledu obrázku.\nPro úpravu bodu podržte klávesu Ctrl a klikněte levým tlačítkem na odpovídající oblast v náhledu, následně uvolněte klávesu Ctrl (pokud si přejete jemné změny) a za stálého držení levého tlačítka myši pohybujte myší nahoru a dolů což bude posouvat bod na křivce nahoru a dolů. +EXIFFILTER_APERTURE;Clona +EXIFFILTER_CAMERA;Fotoaparát +EXIFFILTER_EXPOSURECOMPENSATION;Kompenzace expozice (EV) +EXIFFILTER_FILETYPE;Typ souboru +EXIFFILTER_FOCALLEN;Ohnisková vzdálenost +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Objektiv +EXIFFILTER_METADATAFILTER;Povolit filtr metadat +EXIFFILTER_SHUTTER;Rychlost závěrky +EXIFPANEL_ADDEDITHINT;Přidat nebo upravit štítek. +EXIFPANEL_ADDEDIT;Přidat/Změnit +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Vložit hodnotu +EXIFPANEL_ADDTAGDLG_SELECTTAG;Vybrat štítek +EXIFPANEL_ADDTAGDLG_TITLE;Přidat/Změnit štítek +EXIFPANEL_KEEPHINT;Zachovat vybrané štítky při zápisu do souboru. +EXIFPANEL_KEEP;Zachovat +EXIFPANEL_REMOVEHINT;Odstranit vybrané štítky při zápisu do souboru. +EXIFPANEL_REMOVE;Smazat +EXIFPANEL_RESETALLHINT;Obnoví původní hodnoty u všech štítků. +EXIFPANEL_RESETALL;Obnovit vše +EXIFPANEL_RESETHINT;Obnoví původní hodnoty u vybraných štítků. +EXIFPANEL_RESET;Obnovit +EXIFPANEL_SUBDIRECTORY;Podadresář +EXPORT_BYPASS_ALL;Vybrat / Zrušit výběr všeho +EXPORT_BYPASS_DEFRINGE;Vynechat odstranění lemu +EXPORT_BYPASS_DIRPYRDENOISE;Vynechat redukci šumu +EXPORT_BYPASS_DIRPYREQUALIZER;Vynechat kontrast dle detailu úrovní +EXPORT_BYPASS_EQUALIZER;Vynechat úrovně vlnky +EXPORT_BYPASS_RAW_CA;Vynechat [raw] korekci Chromatické aberace +EXPORT_BYPASS_RAW_CCSTEPS;Vynechat [raw] potlačení chybných barev +EXPORT_BYPASS_RAW_DCB_ENHANCE;Vynechat [raw] kroky vylepšení DCB +EXPORT_BYPASS_RAW_DCB_ITERATIONS;Vynechat [raw] průchody DCB +EXPORT_BYPASS_RAW_DF;Vynechat [raw] tmavé snímky +EXPORT_BYPASS_RAW_FF;Vynechat [raw] Flat Field +EXPORT_BYPASS_RAW_GREENTHRESH;Vynechat [raw] vyrovnání zelené +EXPORT_BYPASS_RAW_LINENOISE;Vynechat [raw] filtrování linkového rušení +EXPORT_BYPASS_RAW_LMMSE_ITERATIONS;Vynechat [raw] kroky vylepšení LMMSE +EXPORT_BYPASS_SHARPENEDGE;Vynechat doostření hran +EXPORT_BYPASS_SHARPENING;Vynechat doostření +EXPORT_BYPASS_SHARPENMICRO;Vynechat mikrokontrast +EXPORT_BYPASS_SH_HQ;Vynechat masku ostrosti stínů a světel +EXPORT_FASTEXPORTOPTIONS;Volby rychlého exportu +EXPORT_INSTRUCTIONS;Volba rychlého exportu umožňuje potlačit vybrané nastavení procesu vyvolání a zkrátit tak čas a zdroje potřebné pro zpracování fronty tím, že se pro vyvolání použije nastavení rychlého exportu. Tato metoda je doporučována pro rychlejší vyvolání obrázků v nižším rozlišení v případě, že je důležitá rychlost, nebo pokud je požadováno vyvolání jednoho nebo více obrázků v nižším rozlišení bez změny uložených parametrů vyvolání. +EXPORT_MAXHEIGHT;Maximální výška: +EXPORT_MAXWIDTH;Maximální šířka: +EXPORT_PUTTOQUEUEFAST; Vložit do fronty pro rychlý export +EXPORT_RAW_DMETHOD;Metoda demozajkování +EXTPROGTARGET_1;raw +EXTPROGTARGET_2;Zpracování fronty +FILEBROWSER_ADDDELTEMPLATE;Přidat/Smazat šablony... +FILEBROWSER_APPLYPROFILE;Použít +FILEBROWSER_APPLYPROFILE_PARTIAL;Aplikovat - částečně +FILEBROWSER_AUTODARKFRAME;Automatický tmavý snímek +FILEBROWSER_AUTOFLATFIELD;Auto Flat Field +FILEBROWSER_BROWSEPATHBUTTONHINT;Klikněte pro výběr cesty. +FILEBROWSER_BROWSEPATHHINT;Vložte cestu pro procházení.\n\nKlávesové zkratky:\nCtrl-o pro přepnutí do adresního řádku.\nEnter/ Ctrl-Enter pro procházení ;\nEsc pro zrušení změn.\nShift-Esc pro zrušení přepnutí.\n\nZkratky pro cesty:\n~\t- domácí složka uživatele.\n!\t- složka s obrázky uživatele. +FILEBROWSER_CACHECLEARFROMFULL;Vymazat z mezipaměti - úplně +FILEBROWSER_CACHECLEARFROMPARTIAL;Vymazat z mezipaměti - částečně +FILEBROWSER_CACHE;Metipaměť +FILEBROWSER_CLEARPROFILE;Smazat +FILEBROWSER_COLORLABEL_TOOLTIP;Barevný štítek.\n\nPoužijte výběr ze seznamu nebo klávesové zkratky:\nShift-Ctrl-0 Bez barvy\nShift-Ctrl-1 Červený\nShift-Ctrl-2 Žlutý\nShift-Ctrl-3 Zelený\nShift-Ctrl-4 Modrý\nShift-Ctrl-5 Nachový +FILEBROWSER_COPYPROFILE;Kopírovat +FILEBROWSER_CURRENT_NAME;Současné jméno: +FILEBROWSER_DARKFRAME;Tmavý snímek +FILEBROWSER_DELETEDLGLABEL;Potvrzení smazání souboru +FILEBROWSER_DELETEDLGMSGINCLPROC;Jste si jisti, že chcete vymazat %1 vybraných souborů včetně výstupů dávkového zpracování? +FILEBROWSER_DELETEDLGMSG;Jste si jisti, že chcete vymazat %1 vybraných souborů? +FILEBROWSER_EMPTYTRASHHINT;Trvale smazat soubory z koše, +FILEBROWSER_EMPTYTRASH;Vysypat koš +FILEBROWSER_EXEC_CPB;Vlastní generátor profilu +FILEBROWSER_EXTPROGMENU;Otevřít pomocí +FILEBROWSER_FLATFIELD;Flat Field +FILEBROWSER_MOVETODARKFDIR;Přesunout do složky tmavých snímků +FILEBROWSER_MOVETOFLATFIELDDIR;Přesunout do složky Flat Field +FILEBROWSER_NEW_NAME;Nové jméno: +FILEBROWSER_OPENDEFAULTVIEWER;Výchozí prohlížeč Windows (fronta zpracována) +FILEBROWSER_PARTIALPASTEPROFILE;Vložit - částečně +FILEBROWSER_PASTEPROFILE;Vložit +FILEBROWSER_POPUPCANCELJOB;Zrušit úlohu +FILEBROWSER_POPUPCOLORLABEL0;Štítek: Žádný +FILEBROWSER_POPUPCOLORLABEL1;Štítek: Červený +FILEBROWSER_POPUPCOLORLABEL2;Štítek: Žlutý +FILEBROWSER_POPUPCOLORLABEL3;Štítek: Zelený +FILEBROWSER_POPUPCOLORLABEL4;Štítek: Modrý +FILEBROWSER_POPUPCOLORLABEL5;Štítek: Nachový +FILEBROWSER_POPUPCOLORLABEL;Barevný štítek +FILEBROWSER_POPUPCOPYTO;Kopírovat do... +FILEBROWSER_POPUPFILEOPERATIONS;Souborové operace +FILEBROWSER_POPUPMOVEEND;Přesunout na konec fronty +FILEBROWSER_POPUPMOVEHEAD;Přesunout na začátek fronty +FILEBROWSER_POPUPMOVETO;Přesunout do... +FILEBROWSER_POPUPOPENINEDITOR;Otevřít v editoru +FILEBROWSER_POPUPOPEN;Otevřít +FILEBROWSER_POPUPPROCESSFAST;Vložit do fronty (Rychlý export) +FILEBROWSER_POPUPPROCESS;Vložit do fronty +FILEBROWSER_POPUPPROFILEOPERATIONS;Operace profilů zpracování +FILEBROWSER_POPUPRANK0;Odstranit hodnocení +FILEBROWSER_POPUPRANK1;Hodnocení 1 * +FILEBROWSER_POPUPRANK2;Hodnocení 2 ** +FILEBROWSER_POPUPRANK3;Hodnocení 3 *** +FILEBROWSER_POPUPRANK4;Hodnocení 4 **** +FILEBROWSER_POPUPRANK5;Hodnocení 5 ***** +FILEBROWSER_POPUPRANK;Hodnocení +FILEBROWSER_POPUPREMOVEINCLPROC;Smazat včetně výstupů z fronty +FILEBROWSER_POPUPREMOVE;Smazat +FILEBROWSER_POPUPRENAME;Přejmenovat +FILEBROWSER_POPUPSELECTALL;Vybrat vše +FILEBROWSER_POPUPTRASH;Přesunout do koše +FILEBROWSER_POPUPUNRANK;Odstranit hodnocení +FILEBROWSER_POPUPUNTRASH;Vymazat z koše +FILEBROWSER_QUERYBUTTONHINT;Smaže vyhledávací dotaz +FILEBROWSER_QUERYHINT;Napište názvy hledaných souborů. Podporuje částečná jména souborů. Hledané termíny oddělte čárkami. Například:\n1001,1004,1199\n\nPro vyřazení výsledků z hledání použijte != před hledaný výraz.\nNapříklad: \n!=1001,1004,1199\n\nZkratky:\nCtrl-F pro přepnutí do pole hledání ,\nEnter pro zahájení hledání,\nEsc pro vyčištění,\nShift-Esc pro zrušení přepnutí. +FILEBROWSER_QUERYLABEL; Najít: +FILEBROWSER_RANK1_TOOLTIP;Hodnocení 1 *\nZkratka: Shift-1 +FILEBROWSER_RANK2_TOOLTIP;Hodnocení 2 *\nZkratka: Shift-2 +FILEBROWSER_RANK3_TOOLTIP;Hodnocení 3 *\nZkratka: Shift-3 +FILEBROWSER_RANK4_TOOLTIP;Hodnocení 4 *\nZkratka: Shift-4 +FILEBROWSER_RANK5_TOOLTIP;Hodnocení 5 *\nZkratka: Shift-5 +FILEBROWSER_RENAMEDLGLABEL;Přejmenování souboru +FILEBROWSER_RENAMEDLGMSG;Přejmenovat soubor "%1" na: +FILEBROWSER_SELECTDARKFRAME;Výběr tmavého snímku... +FILEBROWSER_SELECTFLATFIELD;Výběr Flat Field... +FILEBROWSER_SHOWCOLORLABEL1HINT;Ukázat obrázky s červeným štítkem.\nZkratka: Alt-1 +FILEBROWSER_SHOWCOLORLABEL2HINT;Ukázat obrázky se žlutým štítkem.\nZkratka: Alt-2 +FILEBROWSER_SHOWCOLORLABEL3HINT;Ukázat obrázky se zeleným štítkem.\nZkratka: Alt-3 +FILEBROWSER_SHOWCOLORLABEL4HINT;Ukázat obrázky s modrým štítkem.\nZkratka: Alt-4 +FILEBROWSER_SHOWCOLORLABEL5HINT;Ukázat obrázky s nachovým štítkem.\nZkratka: Alt-5 +FILEBROWSER_SHOWDIRHINT;Smazat všechny filtry.\nZkratka: d +FILEBROWSER_SHOWEDITEDHINT;Ukázat upravené obrázky.\nZkratka: 7 +FILEBROWSER_SHOWEDITEDNOTHINT;Ukázat neupravené obrázky.\nZkratka: 6 +FILEBROWSER_SHOWEXIFINFO;Zobrazit Exif informace.\n\nZkratky:\ni - režim více karet editoru,\nAlt-i - režim jedné karty editoru. +FILEBROWSER_SHOWRANK1HINT;Ukázat obrázky hodnocené jednou hvězdičkou.\nZkratka: 1 +FILEBROWSER_SHOWRANK2HINT;Ukázat obrázky hodnocené dvěma hvězdičkami.\nZkratka: 2 +FILEBROWSER_SHOWRANK3HINT;Ukázat obrázky hodnocené třemi hvězdičkami.\nZkratka: 3 +FILEBROWSER_SHOWRANK4HINT;Ukázat obrázky hodnocené čtyřmi hvězdičkami.\nZkratka: 4 +FILEBROWSER_SHOWRANK5HINT;Ukázat obrázky hodnocené pěti hvězdičkami.\nZkratka: 5 +FILEBROWSER_SHOWRECENTLYSAVEDHINT;Ukázat uložené obrázky.\nZkratka: Alt-7 +FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Ukázat neuložené obrázky.\nZkratka: Alt-6 +FILEBROWSER_SHOWTRASHHINT;Ukázat obsah koše.\nZkratka: Ctrl-t +FILEBROWSER_SHOWUNCOLORHINT;Ukázat obrázky bez barevného štítku.\nZkratka: Alt-0 +FILEBROWSER_SHOWUNRANKHINT;Ukázat nehodnocené obrázky.\nZkratka: 0 +FILEBROWSER_STARTPROCESSINGHINT;Spustit zpracování obrázků ve frontě. +FILEBROWSER_STARTPROCESSING;Spustit zpracování +FILEBROWSER_STOPPROCESSINGHINT;Zastavit zpracování obrázků ve frontě. +FILEBROWSER_STOPPROCESSING;Zastavit zpracovávaní +FILEBROWSER_THUMBSIZE;Velikost náhledu +FILEBROWSER_TOOLTIP_STOPPROCESSING;Automatické spuštění zpracování po vložení nové úlohy. +FILEBROWSER_UNRANK_TOOLTIP;Zrušit hodnocení.\nZkratka: Shift - 0 +FILEBROWSER_ZOOMINHINT;Zvětšit velikosti náhledů.\n\nZkratky:\n+ - režim více karet editoru,\nAlt-+ - režim jedné karty editoru. +FILEBROWSER_ZOOMOUTHINT;Zmenšit velikosti náhledů.\n\nZkratky:\n- - režim více karet editoru,\nAlt-- - režim jedné karty editoru. +GENERAL_ABOUT;O programu +GENERAL_AFTER;Poté +GENERAL_AUTO;Automaticky +GENERAL_BEFORE;Před +GENERAL_CANCEL;Zrušit +GENERAL_CLOSE;Zavřít +GENERAL_DISABLED;Vypnuto +GENERAL_DISABLE;Vypnout +GENERAL_ENABLED;Zapnuto +GENERAL_ENABLE;Zapnout +GENERAL_FILE;Soubor +GENERAL_LANDSCAPE;Na šířku +GENERAL_NA;n/a +GENERAL_NONE;Nic +GENERAL_NO;Ne +GENERAL_OK;OK +GENERAL_PORTRAIT;Na výšku +GENERAL_SAVE;Uložit +GENERAL_UNCHANGED;(Beze změny) +GENERAL_WARNING;Varování +HISTOGRAM_TOOLTIP_BAR;Skrýt/Zobrazit řádek RGB indikátoru\nKlikněte pravým tlačítkem myši na náhled pro zmrazení/uvolnění. +HISTOGRAM_TOOLTIP_B;Skrýt/Zobrazit histogram modré. +HISTOGRAM_TOOLTIP_CHRO;Skrýt/Zobrazit histogram barevnosti. +HISTOGRAM_TOOLTIP_FULL;Plný (zapnuto) nebo přiblížený (vypnuto) histogram. +HISTOGRAM_TOOLTIP_G;Skrýt/Zobrazit histogram zelené. +HISTOGRAM_TOOLTIP_L;Skrýt/Zobrazit CIELab histogram jasu. +HISTOGRAM_TOOLTIP_RAW;Skrýt/Zobrazit raw histogram. +HISTOGRAM_TOOLTIP_R;Skrýt/Zobrazit histogram červené. +HISTORY_CHANGED;Změněno +HISTORY_CUSTOMCURVE;Vlastní křivka +HISTORY_DELSNAPSHOT;Odstranit +HISTORY_FROMCLIPBOARD;Ze schránky +HISTORY_LABEL;Historie +HISTORY_MSG_1;Fotka načtena +HISTORY_MSG_2;PP3 načten +HISTORY_MSG_3;PP3 změněn +HISTORY_MSG_4;Prohlížení historie +HISTORY_MSG_5;Světlost +HISTORY_MSG_6;Kontrast +HISTORY_MSG_7;Černá +HISTORY_MSG_8;Kompenzace expozice +HISTORY_MSG_9;Komprese světel +HISTORY_MSG_10;Komprese stínů +HISTORY_MSG_11;Tónová křivka 1 +HISTORY_MSG_12;Automatické úrovně +HISTORY_MSG_13;Oříznutí expozice +HISTORY_MSG_14;L*a*b* - Světlost +HISTORY_MSG_15;L*a*b* - Kontrast +HISTORY_MSG_16;- +HISTORY_MSG_17;- +HISTORY_MSG_18;- +HISTORY_MSG_19;L*a*b* - L* křivka +HISTORY_MSG_20;Doostření +HISTORY_MSG_21;Doostření - Poloměr +HISTORY_MSG_22;Doostření - Míra +HISTORY_MSG_23;Doostření - Práh +HISTORY_MSG_24;Doostření - Pouze okraje +HISTORY_MSG_25;Doostření - Poloměr detekce okrajů +HISTORY_MSG_26;Doostření - Tolerance okrajů +HISTORY_MSG_27;Doostření - Omezení haló art. +HISTORY_MSG_28;Doostření - Míra omezení haló art. +HISTORY_MSG_29;Metoda doostření +HISTORY_MSG_30;RLD - Poloměr +HISTORY_MSG_31;RLD - Míra +HISTORY_MSG_32;RLD - Útlum +HISTORY_MSG_33;RLD - Průchody +HISTORY_MSG_34;LCP korekce zkreslení +HISTORY_MSG_35;LCP korekce vinětace +HISTORY_MSG_36;LCP korekce CA +HISTORY_MSG_37;Automatické úrovně +HISTORY_MSG_38;Metoda vyvážení bílé +HISTORY_MSG_39;VB - Teplota +HISTORY_MSG_40;VB - Odstín +HISTORY_MSG_41;Tónová křivka - mód 1 +HISTORY_MSG_42;Tónová křivka 2 +HISTORY_MSG_43;Tónová křivka - mód 2 +HISTORY_MSG_44;Poloměr redukce šumu v jasech +HISTORY_MSG_45;Okrajová tolerance redukce šumu v jasech +HISTORY_MSG_46;Redukce barevného šumu +HISTORY_MSG_47;Smísení ICC světel s matici +HISTORY_MSG_48;Použita tónová křivka DCP +HISTORY_MSG_49;DCP osvětlení +HISTORY_MSG_50;Stíny/Světla +HISTORY_MSG_51;S/S - Světla +HISTORY_MSG_52;S/S - Stíny +HISTORY_MSG_53;S/S - Tónový rozsah světel +HISTORY_MSG_54;S/S - Tónový rozsah stínů +HISTORY_MSG_55;S/S - Místní kontrast +HISTORY_MSG_56;S/S - Poloměr +HISTORY_MSG_57;Hrubé otáčení +HISTORY_MSG_58;Horizontální překlopení +HISTORY_MSG_59;Vertikální překlopení +HISTORY_MSG_60;Otočení +HISTORY_MSG_61;Automatické vyplnění +HISTORY_MSG_62;Korekce zkreslení +HISTORY_MSG_63;Snímek vybrán +HISTORY_MSG_64;Ořez +HISTORY_MSG_65;Korekce CA +HISTORY_MSG_66;Rekonstrukce světel +HISTORY_MSG_67;Míra rekonstrukce světel +HISTORY_MSG_68;Metoda rekonstrukce světel +HISTORY_MSG_69;Pracovní barevný prostor +HISTORY_MSG_70;Výstupní barevný prostor +HISTORY_MSG_71;Vstupní barevný prostor +HISTORY_MSG_72;Vínětace - Míra +HISTORY_MSG_73;Míchání kanálů +HISTORY_MSG_74;Změna rozměrů - Míra +HISTORY_MSG_75;Změna rozměrů - Metoda +HISTORY_MSG_76;Exif metadata +HISTORY_MSG_77;IPTC metadata +HISTORY_MSG_78;- +HISTORY_MSG_79;Změna velikosti - šířka +HISTORY_MSG_80;Změna velikosti - délka +HISTORY_MSG_81;Změna velikosti +HISTORY_MSG_82;Profil změněn +HISTORY_MSG_83;S/S - Maska ostrosti +HISTORY_MSG_84;Korekce perspektivy +HISTORY_MSG_85;LCP +HISTORY_MSG_86;RGB křivky - Režim svítivost +HISTORY_MSG_87;Redukce impulzního šumu +HISTORY_MSG_88;Redukce impulzního šumu - práh +HISTORY_MSG_89;Redukce šumu +HISTORY_MSG_90;Redukce šumu - Jas +HISTORY_MSG_91;Redukce šumu - Hlavní barevnost +HISTORY_MSG_92;Redukce šumu - Gama +HISTORY_MSG_93;KdDÚ - Hodnota +HISTORY_MSG_94;Kontrast dle detailu úrovní +HISTORY_MSG_95;L*a*b* - Barevnost +HISTORY_MSG_96;L*a*b* - CC křivka +HISTORY_MSG_97;L*a*b* - CC křivka +HISTORY_MSG_98;Metoda demozajkování +HISTORY_MSG_99;Filtr vypálených pixelů +HISTORY_MSG_100;Sytost RGB +HISTORY_MSG_101;HSV - Odstín +HISTORY_MSG_102;HSV - Sytost +HISTORY_MSG_103;HSV - Hodnota +HISTORY_MSG_104;HSV korekce +HISTORY_MSG_105;Odstranění lemu +HISTORY_MSG_106;Odstr. lemu - Poloměr +HISTORY_MSG_107;Odstr. lemu - Práh +HISTORY_MSG_108;Práh komprese světel +HISTORY_MSG_109;Změna rozměrů - výřez +HISTORY_MSG_110;Změna rozměrů - aplikována na +HISTORY_MSG_111;L*a*b* - Zabránit posunu barev +HISTORY_MSG_112;--nepoužito-- +HISTORY_MSG_113;L*a*b* - Ochrana +HISTORY_MSG_114;Průchody DCB +HISTORY_MSG_115;Potlačení chybných barev +HISTORY_MSG_116;Vylepšení DCB +HISTORY_MSG_117;Raw korekce CA - červená +HISTORY_MSG_118;Raw korekce CA - modrá +HISTORY_MSG_119;Filtrovat linkové rušení +HISTORY_MSG_120;Vyrovnání zelené +HISTORY_MSG_121;Raw korekce CA - automatická +HISTORY_MSG_122;Tmavé snímky - Automatický výběr +HISTORY_MSG_123;Tmavé snímky - Soubor +HISTORY_MSG_124;Korekce bílého bodu +HISTORY_MSG_125;Zachování světel +HISTORY_MSG_126;Flat Field - Soubor +HISTORY_MSG_127;Flat Field - Automatický výběr +HISTORY_MSG_128;Flat Field - Poloměr rozostření +HISTORY_MSG_129;Flat Field - Typ rozostření +HISTORY_MSG_130;Automatická korekce zkreslení +HISTORY_MSG_131;Redukce šumu - Jas +HISTORY_MSG_132;Redukce šumu - Barevnost +HISTORY_MSG_133;Výstupní gama +HISTORY_MSG_134;Volná gama +HISTORY_MSG_135;Volná gama +HISTORY_MSG_136;Sklon volné gamy +HISTORY_MSG_137;Úroveň černé - Zelená 1 +HISTORY_MSG_138;Úroveň černé - Červená +HISTORY_MSG_139;Úroveň černé - Modrá +HISTORY_MSG_140;Úroveň černé - Zelená 2 +HISTORY_MSG_141;Úroveň černé - Spojit zelené +HISTORY_MSG_142;DH - Průchody +HISTORY_MSG_143;DH - Kvantita +HISTORY_MSG_144;Mikrokontrast - Kvantita +HISTORY_MSG_145;Mikrokontrast - Jednolitost +HISTORY_MSG_146;Doostření hran +HISTORY_MSG_147;DH - Pouze jas +HISTORY_MSG_148;Mikrokontrast +HISTORY_MSG_149;Mikrokontrast - Matice 3×3 +HISTORY_MSG_150;Redukce artefaktů/šumu po demozajkování +HISTORY_MSG_151;Živost +HISTORY_MSG_152;Živost - Pastelové tóny +HISTORY_MSG_153;Živost - Saturované tóny +HISTORY_MSG_154;Živost - Zachování tónů pleti +HISTORY_MSG_155;Živost - Vyvarovat se posunu barev +HISTORY_MSG_156;Živost - Propojit past. a sat. tóny +HISTORY_MSG_157;Živost - P/S práh +HISTORY_MSG_158;MT - Síla +HISTORY_MSG_159;MT - Míra zachování hran +HISTORY_MSG_160;MT - Měřítko +HISTORY_MSG_161;MT - Počet průchodů převážení +HISTORY_MSG_162;Mapování tónů +HISTORY_MSG_163;RGB křivky - Červená +HISTORY_MSG_164;RGB křivky - Zelená +HISTORY_MSG_165;RGB křivky - Modrá +HISTORY_MSG_166;Neutrální úrovně +HISTORY_MSG_167;--nepoužito-- +HISTORY_MSG_168;L*a*b* - CC křivka +HISTORY_MSG_169;L*a*b* - CH Křivka +HISTORY_MSG_170;Živost - HH křivka +HISTORY_MSG_171;L*a*b* - LC křivka +HISTORY_MSG_172;L*a*b* - Omezení LC +HISTORY_MSG_173;Redukce šumu - Jas detailu +HISTORY_MSG_174;CIECAM02 +HISTORY_MSG_175;CAM02 - CAT02 přizpůsobení +HISTORY_MSG_176;CAM02 - Okolí pro prohlížení +HISTORY_MSG_177;CAM02 - Svítivost scény +HISTORY_MSG_178;CAM02 - Svítivost prohlížení +HISTORY_MSG_179;CAM02 - Model bílého bodu +HISTORY_MSG_180;CAM02 - Světlost (J) +HISTORY_MSG_181;CAM02 - Chroma (C) +HISTORY_MSG_182;CAM02 - Automatická CAT02 +HISTORY_MSG_183;CAM02 - Kontrast (J) +HISTORY_MSG_184;CAM02 - Okolí scény +HISTORY_MSG_185;CAM02 - Kontrola palety +HISTORY_MSG_186;CAM02 - Algoritmus +HISTORY_MSG_187;CAM02 - Ochrana červ. a pleť. tónů +HISTORY_MSG_188;CAM02 - Světlost (Q) +HISTORY_MSG_189;CAM02 - Kontrast (Q) +HISTORY_MSG_190;CAM02 - Sytost (S) +HISTORY_MSG_191;CAM02 - Pestrobarevnost (M) +HISTORY_MSG_192;CAM02 - Odstín (h) +HISTORY_MSG_193;CAM02 - Tónová křivka 1 +HISTORY_MSG_194;CAM02 - Tónová křivka 2 +HISTORY_MSG_195;CAM02 - Tónová křivka 1 +HISTORY_MSG_196;CAM02 - Tónová křivka 2 +HISTORY_MSG_197;CAM02 - Barevná křivka +HISTORY_MSG_198;CAM02 - Barevná křivka +HISTORY_MSG_199;CAM02 - Výstupní histogramy +HISTORY_MSG_200;CAM02 - Mapování tónů +HISTORY_MSG_201;Redukce šumu - Barevnost Č a Z +HISTORY_MSG_202;Redukce šumu - Barevnost M a Ž +HISTORY_MSG_203;Redukce šumu - Metoda +HISTORY_MSG_204;Kroky rozšíření LMMSE +HISTORY_MSG_205;CAM02 - Filtr vypálených/špatných pixelů +HISTORY_MSG_206;CAT02 - Automatická svítivost scény +HISTORY_MSG_207;Odstr. lemu - Křivka odstínu +HISTORY_MSG_208;ČB - Korekce Modrá/červená +HISTORY_MSG_210;PF - Úhel +HISTORY_MSG_211;Přechodový filtr +HISTORY_MSG_212;Viněta - Síla +HISTORY_MSG_213;Viněta +HISTORY_MSG_214;Černobílá +HISTORY_MSG_215;ČB - MK - Červená +HISTORY_MSG_216;ČB - MK - Zelená +HISTORY_MSG_217;ČB - MK - Modrá +HISTORY_MSG_218;ČB - Gama červená +HISTORY_MSG_219;ČB - Gama červená +HISTORY_MSG_220;ČB - Gama červená +HISTORY_MSG_221;ČB - Barevný filtr +HISTORY_MSG_222;ČB - Předvolby +HISTORY_MSG_223;ČB - MK - Oranžová +HISTORY_MSG_224;ČB - MK - Žlutá +HISTORY_MSG_225;ČB - MK - Tyrkysová +HISTORY_MSG_226;ČB - MK - Purpurová +HISTORY_MSG_227;ČB - MK - Nachová +HISTORY_MSG_228;ČB - Jasová korekce +HISTORY_MSG_229;ČB - Jasová korekce +HISTORY_MSG_230;ČB - Mód +HISTORY_MSG_231;ČB - Křivka 'Před' +HISTORY_MSG_232;ČB - Typ křivky 'Před' +HISTORY_MSG_233;ČB - Křivka 'Po' +HISTORY_MSG_234;ČB - Typ křivky 'Po' +HISTORY_MSG_235;ČB - Automatické míchání kanálů +HISTORY_MSG_236;--nepoužito-- +HISTORY_MSG_237;ČB - Míchání +HISTORY_MSG_238;PF - Rozptyl +HISTORY_MSG_239;PF - Síla +HISTORY_MSG_240;PF - Střed +HISTORY_MSG_241;Viněta - Rozptyl +HISTORY_MSG_242;Viněta - Zaoblení +HISTORY_MSG_243;Vinětace - Poloměr +HISTORY_MSG_244;Vínětace - Síla +HISTORY_MSG_245;Vínětace - Střed +HISTORY_MSG_246;L*a*b* - CL křivka +HISTORY_MSG_247;L*a*b* - LH Křivka +HISTORY_MSG_248;L*a*b* - HH Křivka +HISTORY_MSG_249;KdDÚ - Práh +HISTORY_MSG_250;Redukce šumu - Vylepšení +HISTORY_MSG_251;ČB - Algoritmus +HISTORY_MSG_252;KdDÚ - Tóny pleti +HISTORY_MSG_253;KdDÚ - Omezení vzniku artefaktů +HISTORY_MSG_254;KdDÚ - Tóny pleti +HISTORY_MSG_255;Redukce šumu - Medián +HISTORY_MSG_256;Redukce šumu - Typ mediánu +HISTORY_MSG_257;Barevné tónování +HISTORY_MSG_258;Barevní tónování - Barevná křivka +HISTORY_MSG_259;Barevné tónování - Křivka neprůhlednosti +HISTORY_MSG_260;Barevné tónování - a*[b*] neprůhlednost +HISTORY_MSG_261;Barevné tónování - Metoda +HISTORY_MSG_262;Barevné tónování - b* neprůhlednost +HISTORY_MSG_263;Barevné tónování - Stíny - červená +HISTORY_MSG_264;Barevné tónování - Stíny - zelená +HISTORY_MSG_265;Barevné tónování - Stíny - modrá +HISTORY_MSG_266;Barevné tónování - Střední tóny - červená +HISTORY_MSG_267;Barevné tónování - Střední tóny - zelená +HISTORY_MSG_268;Barevné tónování - Střední tóny - modrá +HISTORY_MSG_269;Barevné tónování - Světla - červená +HISTORY_MSG_270;Barevné tónování - Světla - zelená +HISTORY_MSG_271;Barevné tónování - Světla - modrá +HISTORY_MSG_272;Barevné tónování - Vyvážení +HISTORY_MSG_273;Barevné tónování - Obnovení +HISTORY_MSG_274;Barevné tónování - Saturace stínů +HISTORY_MSG_275;Barevné tónování - Saturace světel +HISTORY_MSG_276;Barevné tónování - Neprůhlednost +HISTORY_MSG_277;--nepoužito-- +HISTORY_MSG_278;Barevné tónování - Zachování jasu +HISTORY_MSG_279;Barevné tónování - Stíny +HISTORY_MSG_280;Barevné tónování - Světla +HISTORY_MSG_281;Barevné tónování - Síla saturace +HISTORY_MSG_282;Barevné tónování - Práh saturace +HISTORY_MSG_283;Barevné tónování - Síla +HISTORY_MSG_284;Barevné tónování - Aut. ochrana saturace +HISTORY_MSG_285;Redukce šumu - Medián - Metoda +HISTORY_MSG_286;Redukce šumu - Medián - Typ +HISTORY_MSG_287;Redukce šumu - Medián - Průchody +HISTORY_MSG_288;Flat Field - kontrola oříznutí +HISTORY_MSG_289;Flat Field - kontrola oříznutí - Auto +HISTORY_MSG_290;Úroveň černé - Červená +HISTORY_MSG_291;Úroveň černé - Zelená 1 +HISTORY_MSG_292;Úroveň černé - Modrá +HISTORY_MSG_293;Simulace filmu +HISTORY_MSG_294;Simulace filmu - Síla +HISTORY_MSG_295;Simulace filmu - Film +HISTORY_MSG_296;Redukce šumu - Křivka jasů +HISTORY_MSG_297;Redukce šumu - Kvalita +HISTORY_MSG_298;Filtr mrtvých pixelů +HISTORY_MSG_299;Redukce šumu - Křivka barevnosti +HISTORY_MSG_300;- +HISTORY_MSG_301;Redukce šumu - Nastavení jasu +HISTORY_MSG_302;Redukce šumu - Metoda barevnosti +HISTORY_MSG_303;Redukce šumu - Metoda barevnosti +HISTORY_MSG_304;Úrovně vlnky +HISTORY_MSG_305;Úrovně vlnky +HISTORY_MSG_306;Vlnka N° úroveň +HISTORY_MSG_307;Vlnka - úroveň barevnosti +HISTORY_MSG_308;Vlnka - směr +HISTORY_MSG_309;Vlnka - práh hrany +HISTORY_MSG_310;Vlnka - tóny oblohy +HISTORY_MSG_311;Vlnka - maximální úrovně +HISTORY_MSG_312;Vlnka - práh stínů +HISTORY_MSG_313;Vlnka - saturované pastely +HISTORY_MSG_314;Vlnka - artefakty modré oblohy +HISTORY_MSG_315;Vlnka - kontrast zůstatku +HISTORY_MSG_316;Vlnka - tóny pleti +HISTORY_MSG_317;Vlnka - Odstín pleti +HISTORY_MSG_318;Vlnka - úrovně světel +HISTORY_MSG_319;Vlnka - rozsah světel +HISTORY_MSG_320;Vlnka - rozsah stínů +HISTORY_MSG_321;Vlnka - úrovně stínů +HISTORY_MSG_322;Vlnka - zabránit posunu barev +HISTORY_MSG_323;Vlnka - úroveň barevnosti +HISTORY_MSG_324;Vlnka - pastely barevnost +HISTORY_MSG_325;Vlnka - nasycení barev +HISTORY_MSG_326;Vlnka - metoda barevnosti +HISTORY_MSG_327;Vlnka - metoda kontrastu +HISTORY_MSG_328;Vlnka - propojení barev +HISTORY_MSG_329;Vlnka - neprůhlednost Č/Z +HISTORY_MSG_330;Vlnka - neprůhlednost M/Ž +HISTORY_MSG_331;Vlnka - extra +HISTORY_MSG_332;Vlnka - metoda dlaždic +HISTORY_MSG_333;Vlnka - stíny zůstatku +HISTORY_MSG_334;Vlnka - barevnost +HISTORY_MSG_335;Vlnka - světla zůstatku +HISTORY_MSG_336;Vlnka - práh světel +HISTORY_MSG_337;Vlnka - rozsah odstínů +HISTORY_MSG_338;Vlnka - poloměr hrany +HISTORY_MSG_339;Vlnka - hodnota hrany +HISTORY_MSG_340;Vlnka - síla +HISTORY_NEWSNAPSHOT;Přidat +HISTORY_NEWSNAPSHOT_TOOLTIP;Zkratka: Alt-s +HISTORY_SNAPSHOTS;Snímky +HISTORY_SNAPSHOT;Snímek +IPTCPANEL_AUTHORSPOSITIONHINT;Titul/pozice autora nebo autorů obrázku (By-line Title). +IPTCPANEL_AUTHORSPOSITION;Autorova pozice +IPTCPANEL_AUTHOR;Autor +IPTCPANEL_CAPTIONHINT;Textový popis dat (Popis - Shrnutí) +IPTCPANEL_CAPTIONWRITERHINT;Jméno osoby, která vložila, změnila nebo opravila obrázek nebo popis/shrnutí (Autor - Editor) +IPTCPANEL_CAPTIONWRITER;Popisovač +IPTCPANEL_CAPTION;Popis +IPTCPANEL_CATEGORYHINT;Obsah obrázku dle názoru dodavatele (Kategorie). +IPTCPANEL_CATEGORY;Kategorie +IPTCPANEL_CITYHINT;Místo vzniku obrázku (Město). +IPTCPANEL_CITY;Město +IPTCPANEL_COPYHINT;Zkopíruj IPTC nastavení do schránky. +IPTCPANEL_COPYRIGHTHINT;Autorská práva (Copyright Notice). +IPTCPANEL_COPYRIGHT;Copyright +IPTCPANEL_COUNTRYHINT;Jméno země/lokace kde byl obrázek vytvořen (Země - Lokace). +IPTCPANEL_COUNTRY;Země +IPTCPANEL_CREDITHINT;Dodavatel obrázku, ne nutně vlastník/autor (Credit). +IPTCPANEL_CREDIT;Zásluhy +IPTCPANEL_DATECREATEDHINT;Datum kdy byl duševní obsah obrázku vytvořen; Formát: RRRRMMDD (Datum vytvoření). +IPTCPANEL_DATECREATED;Datum vytvoření +IPTCPANEL_EMBEDDEDHINT;Obnov IPTC data z obrázku. +IPTCPANEL_EMBEDDED;Uložené +IPTCPANEL_HEADLINEHINT;Zveřejnitelný krátký popis obrázku (Nadpis). +IPTCPANEL_HEADLINE;Nadpis +IPTCPANEL_INSTRUCTIONSHINT;Další instrukce vztahující se k obrázku (Speciální instrukce). +IPTCPANEL_INSTRUCTIONS;Instrukce +IPTCPANEL_KEYWORDSHINT;Jednoslovná hesla popisující obrázek (Klíčová slova). +IPTCPANEL_KEYWORDS;Klíčová slova +IPTCPANEL_PASTEHINT;Vložit IPTC nastavení ze schránky. +IPTCPANEL_PROVINCEHINT;Kraj/stát kde byl obrázek vytvořen (Kraj-Stát). +IPTCPANEL_PROVINCE;Kraj +IPTCPANEL_RESETHINT;Obnovit výchozí profil. +IPTCPANEL_RESET;Obnovit +IPTCPANEL_SOURCEHINT;Původní vlastník intelektuálního obsahu obrázku (Zdroj). +IPTCPANEL_SOURCE;Zdroj +IPTCPANEL_SUPPCATEGORIESHINT;Upřesňující popis obsahu obrázku (Dodatečné kategorie). +IPTCPANEL_SUPPCATEGORIES;Dodat. kategorie +IPTCPANEL_TITLEHINT;Zkrácený popis obrázku (Jméno obrázku). +IPTCPANEL_TITLE;Titulek +IPTCPANEL_TRANSREFERENCEHINT;Kód místa, odkud byl převzat originální obrázek (Original Transmission Reference). +IPTCPANEL_TRANSREFERENCE;Trans. reference +MAIN_BUTTON_FULLSCREEN;Celá obrazovka +MAIN_BUTTON_NAVNEXT_TOOLTIP;Přejít k dalšímu obrázku relativnímu k obrázku otevřenému v editoru.\nZkratka: Shift-F4\n\nPřejít k dalšímu obrázku relativnímu k vybranému náhledu v prohlížeči souborů nebo na filmovém pásu:\nZkratka: F4 +MAIN_BUTTON_NAVPREV_TOOLTIP;Přejít k předchozímu obrázku relativnímu k obrázku otevřenému v editoru.\nZkratka: Shift-F3\n\nPřejít k předchozímu obrázku relativnímu k vybranému náhledu v prohlížeči souborů nebo na filmovém pásu:\nZkratka: F3 +MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchronizovat prohlížeč souborů s editorem pro zobrazení náhledu aktuálně otevřeného obrázku a smazání filtrů v prohlížeči souborů.\nZkratka: x\n\nStejně jako výše, ale bez smazání filtrů v prohlížeči souborů:\nZkratka: y\n(Náhled otevřeného obrázku nebude zobrazen pokud je filtrován). +MAIN_BUTTON_PREFERENCES;Volby +MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Vložit současný obrázek do fronty zpracování.\nZkratka: Ctrl+b +MAIN_BUTTON_SAVE_TOOLTIP;Uložit současný obrázek.\nZkratka: Ctrl+s +MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Editovat současný obrázek v externím editoru.\nZkratka: Ctrl+e +MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Zobrazit/skrýt všechny postranní panely.\nZkratka: m +MAIN_BUTTON_UNFULLSCREEN;Ukončit mód celé obrazovky +MAIN_FRAME_BATCHQUEUE;Fronta +MAIN_FRAME_BATCHQUEUE_TOOLTIP;Fronta zpracování.\nZkratka: Ctrl-F3 +MAIN_FRAME_EDITOR;Editor +MAIN_FRAME_EDITOR_TOOLTIP;Editor.\nZkratka: Ctrl-F4 +MAIN_FRAME_FILEBROWSER;Prohlížeč souborů +MAIN_FRAME_FILEBROWSER_TOOLTIP;Prohlížeč souborů.\nZkratka: Ctrl-F2 +MAIN_FRAME_PLACES;Místa +MAIN_FRAME_PLACES_ADD;Přidat +MAIN_FRAME_PLACES_DEL;Odstranit +MAIN_FRAME_RECENT;Poslední složky +MAIN_MSG_ALREADYEXISTS;Soubor již existuje. +MAIN_MSG_CANNOTLOAD;Nepodařilo se načíst obrázek +MAIN_MSG_CANNOTSAVE;Chyba při ukládání souboru. +MAIN_MSG_CANNOTSTARTEDITOR;Editor nelze spustit. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Nastavte prosím správnou cestu v okně "Volby". +MAIN_MSG_EMPTYFILENAME;Název souboru nebyl zadán! +MAIN_MSG_IMAGEUNPROCESSED;Tento příkaz vyžaduje aby byly všechny vybrané obrázky nejprve zpracovány ve frontě. +MAIN_MSG_NAVIGATOR;Navigátor +MAIN_MSG_OPERATIONCANCELLED;Operace zrušena +MAIN_MSG_PATHDOESNTEXIST;Cesta\n\n%1\n\nneexistuje. Nastavte prosím správnou cestu v okně "Volby". +MAIN_MSG_QOVERWRITE;Chcete jej přepsat? +MAIN_MSG_SETPATHFIRST;K použití této funkce musíte nejprve zadat cílovou cestu\nv okně "Volby"! +MAIN_MSG_WRITEFAILED;Chyba zápisu\n"%1"\n\nUjistěte se, že složka existuje a máte práva do ní zapisovat. +MAIN_TAB_COLOR;Barvy +MAIN_TAB_COLOR_TOOLTIP;Zkratka: Alt-c +MAIN_TAB_DETAIL;Detaily +MAIN_TAB_DETAIL_TOOLTIP;Zkratka: Alt-d +MAIN_TAB_DEVELOP; Vyvolání +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPORT; Rychlý export +MAIN_TAB_EXPOSURE;Expozice +MAIN_TAB_EXPOSURE_TOOLTIP;Zkratka: Alt-e +MAIN_TAB_FILTER; Filtr +MAIN_TAB_INSPECT; Prohlížení +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadata +MAIN_TAB_METADATA_TOOLTIP;Zkratka: Alt-m +MAIN_TAB_RAW;Raw +MAIN_TAB_RAW_TOOLTIP;Zkratka: Alt-r +MAIN_TAB_TRANSFORM;Transformace +MAIN_TAB_TRANSFORM_TOOLTIP;Zkratka: Alt-t +MAIN_TOOLTIP_BACKCOLOR0;Barva pozadí náhledu: Dle motivu\nZkratka: 9 +MAIN_TOOLTIP_BACKCOLOR1;Barva pozadí náhledu: Černá\nZkratka: 9 +MAIN_TOOLTIP_BACKCOLOR2;Barva pozadí náhledu: Bílá\nZkratka: 9 +MAIN_TOOLTIP_BEFOREAFTERLOCK;Zamknout / Odemknout pohled Před\n\nZamknout: ponechá pohled Před nezměněn.\nUžitečné pro posouzení výsledného efektu po použití více nástrojů.\nNavíc může být porovnání provedeno proti kterémukoli stavu v historii.\n\nOdemknout: pohled Před bude následovat pohled Poté, vždy jen o jeden krok zpět, představí vliv právě použitého nástroje. +MAIN_TOOLTIP_HIDEHP;Zobrazit či schovat levý panel (obsahující historii).\nZkratka: l +MAIN_TOOLTIP_INDCLIPPEDH;Zvýraznit oříznutá světla.\nZkratka: < +MAIN_TOOLTIP_INDCLIPPEDS;Zvýraznit oříznuté stíny.\nZkratka: > +MAIN_TOOLTIP_PREVIEWB;Náhled modrého kanálu.\nZkratka: b +MAIN_TOOLTIP_PREVIEWFOCUSMASK;Náhled Masky zaostření.\nZkratka: Shift-f\n\nVíce přesné u snímků s nízkou hloubkou ostrosti, nízkým šumem a na vyšších úrovních zvětšení.\n\nPro zlepšení přesnosti detekce u zašuměných snímků použijte menší zvětšení, mezi 10 až 30%. +MAIN_TOOLTIP_PREVIEWG;Náhled zeleného kanálu.\nZkratka: g +MAIN_TOOLTIP_PREVIEWL;Náhled Svítivost.\nZkratka: v\n\n0.299*R + 0.587*G + 0.114*B +MAIN_TOOLTIP_PREVIEWR;Náhled červeného kanálu.\nZkratka: r +MAIN_TOOLTIP_QINFO;Stručné informace o obrázku.\nZkratka: i +MAIN_TOOLTIP_SHOWHIDELP1;Zobrazit/skrýt levý panel.\nZkratka: l +MAIN_TOOLTIP_SHOWHIDERP1;Zobrazit/skrýt pravý panel.\nZkratka: Alt-l +MAIN_TOOLTIP_SHOWHIDETP1;Zobrazit/skrýt horní panel.\nZkratka: Shift-l +MAIN_TOOLTIP_THRESHOLD;Práh +MAIN_TOOLTIP_TOGGLE;Přepnout pohled Před a Po.\nZkratka: Shift-b +NAVIGATOR_B;B: +NAVIGATOR_G;G: +NAVIGATOR_H;H: +NAVIGATOR_LAB_A;a*: +NAVIGATOR_LAB_B;b*: +NAVIGATOR_LAB_L;L*: +NAVIGATOR_NA; -- +NAVIGATOR_R;R: +NAVIGATOR_S;S: +NAVIGATOR_V;V: +NAVIGATOR_XY_FULL;Šířka: %1, Výška: %2 +NAVIGATOR_XY_NA;x: --, y: -- +OPTIONS_DEFIMG_MISSING;Výchozí profil pro ne raw fotky nelze nalézt nebo nastavit.\n\nZkontrolujte prosím vaši složku s profily, buď chybí nebo je poškozena.\n\nBudou použity výchozí přednastavené hodnoty. +OPTIONS_DEFRAW_MISSING;Výchozí profil pro raw fotky nelze nalézt nebo nastavit.\n\nZkontrolujte prosím vaši složku s profily, buď chybí nebo je poškozena.\n\nBudou použity výchozí přednastavené hodnoty. +PARTIALPASTE_BASICGROUP;Základní nastavení +PARTIALPASTE_CACORRECTION;Korekce chromatické aberace +PARTIALPASTE_CHANNELMIXERBW;Černobílá +PARTIALPASTE_CHANNELMIXER;Míchání kanálů +PARTIALPASTE_COARSETRANS;Hrubá rotace a překlopení +PARTIALPASTE_COLORAPP;CIECAM02 +PARTIALPASTE_COLORGROUP;Nastavení barev +PARTIALPASTE_COLORTONING;Barevné tónování +PARTIALPASTE_COMMONTRANSFORMPARAMS;Automatické vyplnění +PARTIALPASTE_COMPOSITIONGROUP;Nastavení kompozice +PARTIALPASTE_CROP;Ořez +PARTIALPASTE_DARKFRAMEAUTOSELECT;Automatický výběr tmavých snímků +PARTIALPASTE_DARKFRAMEFILE;Soubor tmavého snímku +PARTIALPASTE_DEFRINGE;Odstranění lemu +PARTIALPASTE_DETAILGROUP;Nastavení detailů +PARTIALPASTE_DIALOGLABEL;Částečné vložení profilu zpracování +PARTIALPASTE_DIRPYRDENOISE;Redukce šumu +PARTIALPASTE_DIRPYREQUALIZER;Kontrast dle detailu úrovní +PARTIALPASTE_DISTORTION;Korekce zkreslení +PARTIALPASTE_EPD;Mapování tónů +PARTIALPASTE_EQUALIZER;Vlnka - korekce +PARTIALPASTE_EVERYTHING;Vše +PARTIALPASTE_EXIFCHANGES;Exif +PARTIALPASTE_EXPOSURE;Expozice +PARTIALPASTE_FILMSIMULATION;Simulace filmu +PARTIALPASTE_FLATFIELDAUTOSELECT;Automatický výběr Flat Field +PARTIALPASTE_FLATFIELDBLURRADIUS;Poloměr rozostření Flat Field +PARTIALPASTE_FLATFIELDBLURTYPE;Typ rozostření Flat Field +PARTIALPASTE_FLATFIELDCLIPCONTROL;Flat-field kontrola oříznutí +PARTIALPASTE_FLATFIELDFILE;Flat Field soubor +PARTIALPASTE_GRADIENT;Přechodový filtr +PARTIALPASTE_HSVEQUALIZER;HSV korekce +PARTIALPASTE_ICMGAMMA;Výstupní gama +PARTIALPASTE_ICMSETTINGS;Nastavení správy barev +PARTIALPASTE_IMPULSEDENOISE;Redukce impulzního šumu +PARTIALPASTE_IPTCINFO;IPTC +PARTIALPASTE_LABCURVE;L*a*b* úpravy +PARTIALPASTE_LENSGROUP;Nastavení související s objektivy +PARTIALPASTE_LENSPROFILE;Korekční profil objektivu +PARTIALPASTE_METAGROUP;Nastavení metadat a správy barev +PARTIALPASTE_PCVIGNETTE;Viněta +PARTIALPASTE_PERSPECTIVE;Perspektiva +PARTIALPASTE_PREPROCESS_DEADPIXFILT;Filtr mrtvých pixelů +PARTIALPASTE_PREPROCESS_GREENEQUIL;Vyrovnání zelené +PARTIALPASTE_PREPROCESS_HOTPIXFILT;Filtr vypálených pixelů +PARTIALPASTE_PREPROCESS_LINEDENOISE;Filtrovat linkové rušení +PARTIALPASTE_RAWCACORR_AUTO;Automatická korekce CA +PARTIALPASTE_RAWCACORR_CABLUE;CA modrá +PARTIALPASTE_RAWCACORR_CARED;CA červená +PARTIALPASTE_RAWEXPOS_BLACK;Úrovně černé +PARTIALPASTE_RAWEXPOS_LINEAR;Korekce bílého bodu +PARTIALPASTE_RAWEXPOS_PRESER;Zachování světel +PARTIALPASTE_RAWGROUP;Nastavení Raw +PARTIALPASTE_RAW_DCBENHANCE;Vylepšení DCB +PARTIALPASTE_RAW_DCBITERATIONS;Počet průchodů DCB +PARTIALPASTE_RAW_DMETHOD;Metoda demozajkování +PARTIALPASTE_RAW_FALSECOLOR;Kroky potlačení falešných barev demozajkování +PARTIALPASTE_RAW_LMMSEITERATIONS;Kroky rozšíření LMMSE +PARTIALPASTE_RESIZE;Změna velikosti +PARTIALPASTE_RGBCURVES;RGB křivky +PARTIALPASTE_ROTATION;Otočení +PARTIALPASTE_SHADOWSHIGHLIGHTS;Stíny/Světla +PARTIALPASTE_SHARPENEDGE;Hrany +PARTIALPASTE_SHARPENING;Doostření (USM/RL) +PARTIALPASTE_SHARPENMICRO;Mikrokontrast +PARTIALPASTE_VIBRANCE;Živost +PARTIALPASTE_VIGNETTING;Korekce vinětace +PARTIALPASTE_WHITEBALANCE;Nastavení bílé +PREFERENCES_ADD;Přidat +PREFERENCES_APPLNEXTSTARTUP;vyžaduje restart aplikace +PREFERENCES_AUTLISLOW;Nízké +PREFERENCES_AUTLISMAX;Maximální - průměr všech dlaždic +PREFERENCES_AUTLISSTD;Vysoké +PREFERENCES_AUTLISVLOW;Ne +PREFERENCES_AUTLOW;Nízká +PREFERENCES_AUTOMONPROFILE;Použít barevný profil hlavního monitoru z operačního systému +PREFERENCES_AUTSTD;Běžná +PREFERENCES_BATCH_PROCESSING;Dávkové zpracování +PREFERENCES_BEHADDALLHINT;Nastaví všechny parametry do módu Přidat.\nZměna parametrů v panelu dávkového zpracování se aplikuje jako rozdíl k uloženým hodnotám. +PREFERENCES_BEHADDALL;Vše do 'Přidat' +PREFERENCES_BEHAVIOR;Režim +PREFERENCES_BEHSETALLHINT;Nastaví všechny parametry do módu Nastavit.\nZměna parametrů v panelu dávkového zpracování se aplikuje jako absolutní, budou zobrazeny aktuální hodnoty. +PREFERENCES_BEHSETALL;Vše do 'Nastavit' +PREFERENCES_BLACKBODY;Wolfram +PREFERENCES_CACHECLEARALL;Vymazat vše +PREFERENCES_CACHECLEARPROFILES;Smazat profily zpracování +PREFERENCES_CACHECLEARTHUMBS;Vymazat náhledy +PREFERENCES_CACHEMAXENTRIES;Maximální počet záznamů v mezipaměti +PREFERENCES_CACHEOPTS;Vlastnosti mezipaměti +PREFERENCES_CACHETHUMBHEIGHT;Maximální výška náhledu +PREFERENCES_CIEART;CIECAM02 optimalizace +PREFERENCES_CIEART_FRAME;CIECAM0 2 -Specifická nastavení +PREFERENCES_CIEART_LABEL;Použít jednoduchou přesnost místo dvojnásobné +PREFERENCES_CIEART_TOOLTIP;Pokud je povoleno, budou pro CIECAM02 výpočty použita reálná čísla s jednoduchou přesností místo čísel s dvojnásobnou přesností. Tím se dosáhne mírného zrychlení výpočtů za cenu nepatrné ztráty kvality. +PREFERENCES_CLIPPINGIND;Indikace oříznutí +PREFERENCES_CLUTSCACHE;Mezipaměť HaldCLUT +PREFERENCES_CLUTSCACHE_LABEL;Maximální počet přednačtených CLUTů +PREFERENCES_CLUTSDIR;Složka HaldCLUT +PREFERENCES_CMETRICINTENT;Kolorimetrický záměr +PREFERENCES_CUSTPROFBUILDHINT;Program (nebo skript) spuštěný v případě, že má být vygenerován nový profil pro obrázek.\n\nCesta k souboru s parametry (styl *.ini, neboli "soubor klíčů") je přidán jako parametr do příkazové řádky. Soubor obsahuje mnoho různých parametrů vyžadovaných skripty a Exif data, což umožní skriptu vygenerovat správný profil pro zpracování.\n\nVAROVÁNÍ: Pokud používáte cesty obsahující mezery, musíte je sami uzavřít do dvojitých uvozovek. +PREFERENCES_CUSTPROFBUILDKEYFORMAT;Formát klíče +PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME;Jméno +PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;TagID +PREFERENCES_CUSTPROFBUILDPATH;Cesta k programu +PREFERENCES_CUSTPROFBUILD;Vlastní generátor profilu zpracování +PREFERENCES_CUTOVERLAYBRUSH;Barva masky ořezu/průhlednosti +PREFERENCES_D50;5000K +PREFERENCES_D55;5500K +PREFERENCES_D60;6000K +PREFERENCES_D65;6500K +PREFERENCES_DARKFRAMEFOUND;Nalezeno +PREFERENCES_DARKFRAMESHOTS;snímků +PREFERENCES_DARKFRAMETEMPLATES;šablon +PREFERENCES_DARKFRAME;Tmavý snímek +PREFERENCES_DATEFORMATHINT;Lze použít následující formátovací řetězce:\n%y\t- rok (year)\n%m\t- měsíc (month)\n%d\t- den (day)\n\nNapříklad český formát data:\n%d. %m. %y +PREFERENCES_DATEFORMAT;Formát data +PREFERENCES_DAUB_LABEL;Použít D6 Daubechiesové vlnky namísto D4 +PREFERENCES_DAUB_TOOLTIP;Nástroje Redukce šumu a Úrovně vlnky používají Daubechiesové mateřskou vlnku. Pokud místo D4 vyberete D6 zvýší se počet ortogonálních Daubechiesové koeficientů a pravděpodobně zvýší kvalitu úrovní malého měřítka. Není zde rozdíl ve spotřebě paměti nebo délce zpracování. +PREFERENCES_DEFAULTLANG;Výchozí jazyk +PREFERENCES_DEFAULTTHEME;Výchozí vzhled +PREFERENCES_DIRDARKFRAMES;Složka tmavých snímků +PREFERENCES_DIRHOME;Domovská složka +PREFERENCES_DIRLAST;Poslední navštívená složka +PREFERENCES_DIROTHER;Jiná +PREFERENCES_DIRSELECTDLG;Zvolte složku s obrázky při spuštění... +PREFERENCES_DIRSOFTWARE;Instalační složka +PREFERENCES_EDITORCMDLINE;Jiný příkaz +PREFERENCES_EDITORLAYOUT;Rozvržení editoru +PREFERENCES_EXPAUT;Expert +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ů (vypněte na nízkých rozlišeních) +PREFERENCES_FILEFORMAT;Formát souboru +PREFERENCES_FILMSIMULATION;Simulace filmu +PREFERENCES_FLATFIELDFOUND;Nalezeno +PREFERENCES_FLATFIELDSDIR;Složka Flat Field souborů +PREFERENCES_FLATFIELDSHOTS;snímků +PREFERENCES_FLATFIELDTEMPLATES;šablon +PREFERENCES_FLATFIELD;Flat Field +PREFERENCES_FLUOF2;Fluorescenční F2 +PREFERENCES_FLUOF7;Fluorescenční F7 +PREFERENCES_FLUOF11;Fluorescenční F11 +PREFERENCES_FORIMAGE;Pro ostatní fotografie +PREFERENCES_FORRAW;Pro raw fotografie +PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT;Stejná velikost náhledu v panelu Editoru a v Prohlížeči souborů +PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT_HINT;Rozdílné velikosti náhledů znamenají delší dobu zpracování při přepínání mezi obrázkem v záložce Editoru a Prohlížečem souborů. +PREFERENCES_GIMPPATH;GIMP instalační složka +PREFERENCES_GREY05;Yb=05 CIE L#30 +PREFERENCES_GREY10;Yb=10 CIE L#40 +PREFERENCES_GREY15;Yb=15 CIE L#45 +PREFERENCES_GREY18;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_GREYSC18;Yb=18 CIE L#50 +PREFERENCES_GREYSCA;Automaticky +PREFERENCES_GREYSC;Yb svítivost scény (%) +PREFERENCES_GREY;Yb svítivost výstupního zařízení (%) +PREFERENCES_HISTOGRAMPOSITIONLEFT;Histogram v levém panelu +PREFERENCES_HISTOGRAMWORKING;Navigátor a hlavní histogram používají pracovní profil +PREFERENCES_HISTOGRAM_TOOLTIP;Pokud je povoleno, používá se pracovní profil pro vykreslení hlavního histogramu a v navigačním panelu. V opačném případě je použit výstupní profil s aplikovanou gama korekcí. +PREFERENCES_HLTHRESHOLD;Práh oříznutých světel +PREFERENCES_ICCDIR;Složka obsahující barevné profily +PREFERENCES_IMG_RELOAD_NEEDED;Tyto změny se projeví až po novém načtení již otevřeného obrázku (nebo po otevření nového obrázku) +PREFERENCES_IMPROCPARAMS;Výchozí profil zpracování +PREFERENCES_INSPECT_LABEL;Prohlížení +PREFERENCES_INSPECT_MAXBUFFERS_LABEL;Maximální počet obrázků v mezipaměti +PREFERENCES_INSPECT_MAXBUFFERS_TOOLTIP;Nastavení maximálního počtu obrázků, které jsou ukládány do mezipaměti při zkoumání v Prohlížeči souborů. Na systémech s nedostatkem pamětí (2GB) nastavte hodnotu 1 nebo 2. +PREFERENCES_INTENT_ABSOLUTE;Absolutní kolorimetrie +PREFERENCES_INTENT_PERCEPTUAL;Vnímání +PREFERENCES_INTENT_RELATIVE;Relativní kolorimetrie +PREFERENCES_INTENT_SATURATION;Sytost +PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Ukázat vložené JPEG náhledy u needitovaných snímků +PREFERENCES_LANGAUTODETECT;Použít systémový jazyk +PREFERENCES_LEVAUTDN;Úroveň odšumění +PREFERENCES_LEVDN;Velikost buňky +PREFERENCES_LISS;Automatické více zónové vyhlazení +PREFERENCES_MAX;Velká (dlaždice) +PREFERENCES_MED;Střední (Poloviční dlaždice) +PREFERENCES_MENUGROUPEXTPROGS;Skupina "Otevřít pomocí" +PREFERENCES_MENUGROUPFILEOPERATIONS;Skupina "Souborové operace" +PREFERENCES_MENUGROUPLABEL;Skupina "Barevné štítky" +PREFERENCES_MENUGROUPPROFILEOPERATIONS;Skupina "Operace s profily zpracování" +PREFERENCES_MENUGROUPRANK;Skupina "Hodnocení" +PREFERENCES_MENUOPTIONS;Volby místní nabídky +PREFERENCES_METADATA;Metadata +PREFERENCES_MIN;Velmi malá (100x115) +PREFERENCES_MONITORICC;Barevný profil monitoru +PREFERENCES_MULTITABDUALMON;Mód více karet editoru ve vlastním okně +PREFERENCES_MULTITAB;Mód více karet editoru +PREFERENCES_NAVGUIDEBRUSH;Barva vodítek navigátoru +PREFERENCES_NOISE;Redukce šumu +PREFERENCES_OUTDIRFOLDERHINT;Uložit obrázky do vybrané složky. +PREFERENCES_OUTDIRFOLDER;Ulož do souboru +PREFERENCES_OUTDIRTEMPLATEHINT;Lze použít následující formátovací řetězce:\n%f, %d1, %d2, ..., %p1, %p2, ..., %r, %s1, %s2, ...\n\nTyto formátovací řetězce reprezentují různé části cesty k uložené fotografii, některé vlastnosti fotografie nebo pořadí v dávce.\n\nNapříklad pokud má zpracovávaná fotografie následující cestu:\n/home/tomas/fotky/2010-10-31/dsc0042.nef,\nmají jednotlivé formátovací řetězce tento význam:\n%d4 = home\n%d3 = tomas\n%d2 = fotky\n%d1 = 2010-10-31\n%f = dsc0042\n%p1 = /home/tomas/fotky/2010-10-31/\n%p2 = /home/tomas/fotky/\n%p3 = /home/tomas/\n%p4 = /home/\n\n%r bude nahrazeno hodnocením fotografie. Pokud není fotografie ohodnocena, bude %r nahrazeno '0'. Pokud je fotografie v koši, bude %r nahrazeno 'x'.\n\n%s1, %s2, atd. bude nahrazeno pořadím v dávce doplněném na 1 až 9 číslic. Každé spuštění zpracování fronty jej vždy nastaví na jedna a po každé zpracované fotografii se o jedna zvýší .\n\nPokud si přejete uložit výstupní obrázek vedle originálu, napište:\n%p1/%f\n\nPokud si jej ale přejete uložit do adresáře "zpracovano" ve stejném adresáři jako otevřený obrázek, napište:\n%p1/zpracovano/%f\n\nPro uložení výstupního obrázku do adresáře "/home/tom/fotky/zpracovano/2010-10-31", napište:\n%p2/zpracovano/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Použít šablonu +PREFERENCES_OUTDIR;Výstupní složka +PREFERENCES_OVERLAY_FILENAMES;Překrýt jména souborů na náhledech v prohlížeči souborů +PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Překrýt jména souborů na náhledech v editoru +PREFERENCES_OVERWRITEOUTPUTFILE;Přepsat existující soubory +PREFERENCES_PANFACTORLABEL;Násobitel +PREFERENCES_PARSEDEXTADDHINT;Vymazat označenou příponu ze seznamu. +PREFERENCES_PARSEDEXTADD;Přidat příponu +PREFERENCES_PARSEDEXTDELHINT;Vymazat označenou příponu ze seznamu. +PREFERENCES_PARSEDEXT;Zachytávané přípony +PREFERENCES_PREVDEMO;Metoda demozajkování náhledu +PREFERENCES_PREVDEMO_FAST;Rychlá +PREFERENCES_PREVDEMO_LABEL;Metoda demozajkování pro náhled při přiblížení menším než 100%: +PREFERENCES_PREVDEMO_SIDECAR;Stejná jako v PP3 +PREFERENCES_PROFILEHANDLING;Řízení profilů zpracování +PREFERENCES_PROFILELOADPR;Priorita nahrávání profilů zpracování +PREFERENCES_PROFILEPRCACHE;Profil v mezipaměti +PREFERENCES_PROFILEPRFILE;Profil uložený se zdrojovým souborem +PREFERENCES_PROFILESAVECACHE;Ukládat parametry zpracování do mezipaměti +PREFERENCES_PROFILESAVEINPUT;Ukládat parametry zpracování spolu se zdrojovým souborem +PREFERENCES_PROPERTY;Vlastnost +PREFERENCES_PSPATH;Instalační složka Adobe Photoshop +PREFERENCES_RGBDTL_LABEL;Maximální počet vláken pro redukci šumu a úrovně vlnky +PREFERENCES_RGBDTL_TOOLTIP;Pro automatické nastavení maximálního možného počtu vláken ponechte nastaveno na "0". Čím více vláken běží paralelně, tím rychlejší je výpočet. Paměťové nároky najdete na RawPedii. +PREFERENCES_SELECTFONT;Vybrat písmo +PREFERENCES_SELECTLANG;Volba jazyka +PREFERENCES_SELECTTHEME;Zvolit vzhled +PREFERENCES_SET;Nastavit +PREFERENCES_SHOWBASICEXIF;Zobrazovat základní Exif informace +PREFERENCES_SHOWDATETIME;Zobrazovat datum a čas +PREFERENCES_SHOWEXPOSURECOMPENSATION;Přidat kompenzaci expozice +PREFERENCES_SHOWFILMSTRIPTOOLBAR;Zobrazit lištu s filmovým pásem +PREFERENCES_SHTHRESHOLD;Práh oříznutých stínů +PREFERENCES_SIMPLAUT;Režim nástrojů +PREFERENCES_SINGLETABVERTAB;Mód jedné karty editoru, svislé karty +PREFERENCES_SINGLETAB;Mód jedné karty editoru +PREFERENCES_SLIMUI;Štíhlé rozhraní +PREFERENCES_SMA;Malá (250x287) +PREFERENCES_SND_BATCHQUEUEDONE;Zpracování fronty dokončeno +PREFERENCES_SND_HELP;Vložte cestu k souboru pro nastavení zvuku nebo ponechte prázdné (bez zvuku).\nVe Windows zadejte "SystemDefault", "SystemAsterisk" a podobně.\nNa Linuxu použijte "complete", "window-attention" a další. +PREFERENCES_SND_LNGEDITPROCDONE;Zpracování v editoru dokončeno +PREFERENCES_SND_TRESHOLDSECS;Po sekundách +PREFERENCES_STARTUPIMDIR;Složka obrázků při spuštění +PREFERENCES_STDAUT;Běžný +PREFERENCES_TAB_BROWSER;Prohlížeč souborů +PREFERENCES_TAB_COLORMGR;Správa barev +PREFERENCES_TAB_GENERAL;Obecné +PREFERENCES_TAB_IMPROC;Zpracování obrázku +PREFERENCES_TAB_PERFORMANCE;Výkon a kvalita +PREFERENCES_TAB_SOUND;Zvuky +PREFERENCES_TIMAX;Vysoký +PREFERENCES_TINB;Počet dlaždic +PREFERENCES_TISTD;Běžný +PREFERENCES_TP_LABEL;Panel nástrojů: +PREFERENCES_TP_USEICONORTEXT;V záhlaví karty zobrazit ikonu namísto textu +PREFERENCES_TP_VSCROLLBAR;Skrýt svislou posuvnou lištu +PREFERENCES_TUNNELMETADATA;Přenést nezměněná IPTC/XMP metadata do výstupního souboru +PREFERENCES_USEBUNDLEDPROFILES;Použít přiložené profily +PREFERENCES_USESYSTEMTHEME;Použít systémový motiv +PREFERENCES_VIEW;Nastavení vyvážení bílé výstupních zařízení (monitor, TV, projektor, rámeček a jiné) +PREFERENCES_WAVLEV;Zvýšit úroveň vlnkové transformace v nejvyšší kvalitě +PREFERENCES_WLONE;Jedna úroveň +PREFERENCES_WLTWO;Dvě úrovně +PREFERENCES_WLZER;Ne +PREFERENCES_WORKFLOW;Rozvržení +PROFILEPANEL_COPYPPASTE;Parametry pro kopírování +PROFILEPANEL_GLOBALPROFILES;Přiložené profily +PROFILEPANEL_LABEL;Profily zpracování +PROFILEPANEL_LOADDLGLABEL;Načíst parametry zpracování... +PROFILEPANEL_LOADPPASTE;Parametry nahrávání +PROFILEPANEL_MODE_TIP;Režim uplatnění profilu zpracování.\n\nTlačítko je stisknuto: částečné profily budou aplikovány jako kompletní; chybějící hodnoty budou doplněny přednastavenými hodnotami.\n\nTlačítko není stisknuto: profily budou aplikovány tak jak jsou, změní se pouze v profilu obsažené hodnoty. +PROFILEPANEL_MYPROFILES;Mé profily +PROFILEPANEL_PASTEPPASTE;Parametry pro vložení +PROFILEPANEL_PCUSTOM;Vlastní +PROFILEPANEL_PFILE;Ze souboru +PROFILEPANEL_PINTERNAL;Neutrální +PROFILEPANEL_PLASTSAVED;Poslední uschovaný +PROFILEPANEL_SAVEDLGLABEL;Uložit parametry zpracování... +PROFILEPANEL_SAVEPPASTE;Parametry ukládání +PROFILEPANEL_TOOLTIPCOPY;Kopírovat současný profil do schránky.\nCtrl-klik umožní vybrat parametry pro kopírování. +PROFILEPANEL_TOOLTIPLOAD;Nahrát profil ze souboru.\nCtrl-klik umožní vybrat parametry pro nahrání. +PROFILEPANEL_TOOLTIPPASTE;Vložit profil ze schránky.\nCtrl-klik umožní vybrat parametry pro vložení. +PROFILEPANEL_TOOLTIPSAVE;Uložit současný profil.\nCtrl-klik umožní vybrat parametry pro uložení. +PROGRESSBAR_LOADINGTHUMBS;Načítání náhledů... +PROGRESSBAR_LOADING;Načítání obrázku... +PROGRESSBAR_LOADJPEG;Načítání JPEG... +PROGRESSBAR_LOADPNG;Načítání PNG... +PROGRESSBAR_LOADTIFF;Načítání TIFF... +PROGRESSBAR_NOIMAGES;Složka neobsahuje obrázky +PROGRESSBAR_PROCESSING;Zpracovávaní obrázku... +PROGRESSBAR_PROCESSING_PROFILESAVED;Profil zpracování uložen +PROGRESSBAR_READY;Připraven +PROGRESSBAR_SAVEJPEG;Ukládání JPEG souboru... +PROGRESSBAR_SAVEPNG;Ukládání PNG souboru... +PROGRESSBAR_SAVETIFF;Ukládání TIFF souboru... +PROGRESSBAR_SNAPSHOT_ADDED;Snímek přidán +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profil upracování změněn v prohlížeči +QINFO_ISO;ISO +QINFO_NOEXIF;Exif údaje nejsou k dispozici. +SAVEDLG_AUTOSUFFIX;Automaticky přidat příponu pokud soubor již existuje +SAVEDLG_FILEFORMAT;Formát souboru +SAVEDLG_FORCEFORMATOPTS;Vynutit volby uložení +SAVEDLG_JPEGQUAL;Kvalita JPEG +SAVEDLG_PNGCOMPR;PNG Komprese +SAVEDLG_PUTTOQUEUEHEAD;Vložit na začátek fronty +SAVEDLG_PUTTOQUEUETAIL;Vložit na konec fronty +SAVEDLG_PUTTOQUEUE;Vložit soubor do fronty +SAVEDLG_SAVEIMMEDIATELY;Okamžitě uložit +SAVEDLG_SAVESPP;Uschovat parametry zpracování s obrázkem +SAVEDLG_SUBSAMP;Podvzorkování +SAVEDLG_SUBSAMP_1;Nejlepší komprese +SAVEDLG_SUBSAMP_2;Vyvážené +SAVEDLG_SUBSAMP_3;Nejlepší kvalita +SAVEDLG_SUBSAMP_TOOLTIP;Nejlepší komprese: 4:1:1\nVyvážená: 4:2:2\nNejlepší kvalita: 4:4:4 +SAVEDLG_TIFFUNCOMPRESSED;Nekomprimovaný TIFF +SAVEDLG_WARNFILENAME;Soubor bude pojmenován +SHCSELECTOR_TOOLTIP;Klikněte pravým tlačítkem myši pro obnovení výchozí pozice těchto tří posuvníků. +THRESHOLDSELECTOR_BL;Dole vlevo +THRESHOLDSELECTOR_BR;Dole vpravo +THRESHOLDSELECTOR_B;Dole +THRESHOLDSELECTOR_HINT;Držte klávesu Shift pro přesun individuálních kontrolních bodů.. +THRESHOLDSELECTOR_TL;Nahoře vlevo +THRESHOLDSELECTOR_TR;Nahoře vpravo +THRESHOLDSELECTOR_T;Nahoře +TOOLBAR_TOOLTIP_CROP;Oříznutí výběru.\nZkratka: c\nOblast výřezu posunete pomocí Shift + tažení myši +TOOLBAR_TOOLTIP_HAND;Nástroj ruka.\nZkratka: h +TOOLBAR_TOOLTIP_STRAIGHTEN;Vyznačení roviny / rotace.\nZkratka: s\n\nZobrazení míry rotace pomocí vodící linky na náhledu snímky. Úhel rotace je zobrazen vedle vodící linky. Střed rotace je geometrický střed snímku. +TOOLBAR_TOOLTIP_WB;Bodové vyvážení bílé.\nZkratka: w +TP_BWMIX_ALGO;Algoritmus OYCPM +TP_BWMIX_ALGO_LI;Lineární +TP_BWMIX_ALGO_SP;Speciální efekty +TP_BWMIX_ALGO_TOOLTIP;Lineární: výstupem bude běžná lineární odpověď.\nSpeciální efekty: výstupem budou speciální efekty pomocí míchání kanálů (nelineární odpověď). +TP_BWMIX_AUTOCH;Automaticky +TP_BWMIX_AUTOCH_TIP;Spočítá optimální hodnoty pro míchání kanálů. +TP_BWMIX_CC_ENABLED;Úpravy doplňkových barev +TP_BWMIX_CC_TOOLTIP;Povolením zapnete automatické korekce doplňkových barev v režimu ROYGCBPM. +TP_BWMIX_CHANNEL;Korekce jasu +TP_BWMIX_CURVEEDITOR1;Křivka 'Před' +TP_BWMIX_CURVEEDITOR2;Křivka 'Po' +TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Tónová křivka na konci úprav - po převodu na černobílou fotografii. +TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Tónová křivka před převodem na černobílou fotografii\nmůže vzít v potaz barevné složky. +TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Změní jas dle odstínu L=f(H).\nUvědomte si, že extrémní hodnoty mohou způsobovat artefakty. +TP_BWMIX_FILTER;Barevný filtr +TP_BWMIX_FILTER_BLUEGREEN;Tyrkysový +TP_BWMIX_FILTER_BLUE;Modrý +TP_BWMIX_FILTER_GREENYELLOW;Žlutozelený +TP_BWMIX_FILTER_GREEN;Zelený +TP_BWMIX_FILTER_NONE;Žádný +TP_BWMIX_FILTER_PURPLE;Nachový +TP_BWMIX_FILTER_REDYELLOW;Oranžový +TP_BWMIX_FILTER_RED;Červený +TP_BWMIX_FILTER_TOOLTIP;Efekt barevného filtru je podobný focení na film s nasazeným barevným filtrem. Barevný filtr omezuje průchod specifického rozsahu barev a způsobuje tak jejich zesvětlení. Například červený filtr způsobí ztmavení modré oblohy. +TP_BWMIX_FILTER_YELLOW;Žlutý +TP_BWMIX_GAMMA;Gama korekce +TP_BWMIX_GAM_TOOLTIP;Gama korekce pro každý R, G, B kanál. +TP_BWMIX_LABEL;Černobílá +TP_BWMIX_MET;Metoda +TP_BWMIX_MET_CHANMIX;Míchání kanálů +TP_BWMIX_MET_DESAT;Odbarvení +TP_BWMIX_MET_LUMEQUAL;Korekce jasu +TP_BWMIX_MIXC;Míchání +TP_BWMIX_NEUTRAL;Vrátit míchání +TP_BWMIX_NEUTRAL_TIP;Vrátí všechny hodnoty (filtry, mixéry kanálů) na výchozí pozice. +TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Celkem: %4%% +TP_BWMIX_RGBLABEL_HINT;Výsledné RGB faktory po započtení všech mixérů\n"Celkem" zobrazí souček aktuálně aplikovaných RGB hodnot:\n- vždy 100% v relativním režimu\n- více (světlejší) nebo méně (tmavší) než 100% v absolutním režimu. +TP_BWMIX_RGB_TOOLTIP;Mísení RGB kanálů. Jako vodítko můžete použít uložená přednastavení.\nPovšimněte si prosím, že záporné hodnoty mohou vést ke vzniku artefaktů nebo chybnému chování. +TP_BWMIX_SETTING;Uložené předvolby +TP_BWMIX_SETTING_TOOLTIP;Různá přednastavení (filmy, krajina, ...) nebo vlastní míchání kanálů. +TP_BWMIX_SET_HIGHCONTAST;Vysoký kontrast +TP_BWMIX_SET_HIGHSENSIT;Vysoká citlivost +TP_BWMIX_SET_HYPERPANCHRO;Hyper Panchromatic +TP_BWMIX_SET_INFRARED;Infračervená +TP_BWMIX_SET_LANDSCAPE;Na šířku +TP_BWMIX_SET_LOWSENSIT;Nízká citlivost +TP_BWMIX_SET_LUMINANCE;Jas +TP_BWMIX_SET_NORMCONTAST;Normální kontrast +TP_BWMIX_SET_ORTHOCHRO;Orthochromatic +TP_BWMIX_SET_PANCHRO;Panchromatic +TP_BWMIX_SET_PORTRAIT;Na výšku +TP_BWMIX_SET_RGBABS;Absolutní RGB +TP_BWMIX_SET_RGBREL;Relativní RGB +TP_BWMIX_SET_ROYGCBPMABS;Úplné ROYGCBPM +TP_BWMIX_SET_ROYGCBPMREL;Relativní ROYGCBPM +TP_BWMIX_TCMODE_FILMLIKE;ČB Jako film +TP_BWMIX_TCMODE_SATANDVALBLENDING;ČB Mísení saturace a hodnoty +TP_BWMIX_TCMODE_STANDARD;ČB Běžný +TP_BWMIX_TCMODE_WEIGHTEDSTD;ČB Běžný vážený +TP_BWMIX_VAL;L +TP_CACORRECTION_BLUE;Modrá +TP_CACORRECTION_LABEL;Korekce chromatické aberace +TP_CACORRECTION_RED;Červená +TP_CHMIXER_BLUE;Modrý kanál +TP_CHMIXER_GREEN;Zelený kanál +TP_CHMIXER_LABEL;Míchání kanálů +TP_CHMIXER_RED;Červený kanál +TP_CHROMATABERR_LABEL;Chromatická aberace +TP_COARSETRAF_TOOLTIP_HFLIP;Překlopit horizontálně. +TP_COARSETRAF_TOOLTIP_ROTLEFT;Otočit doleva.\n\nZkratky:\n[ - režim více karet editoru,\nAlt-[- režim jedné karty editoru. +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Otočit doprava.\n\nZkratky:\n] - režim více karet editoru,\nAlt-]- režim jedné karty editoru. +TP_COARSETRAF_TOOLTIP_VFLIP;Překlopit vertikálně. +TP_COLORAPP_ADAPTSCENE;Svítivost scény +TP_COLORAPP_ADAPTSCENE_TOOLTIP;Absolutní jas scény prostředí(cd/m²).\n 1) Vypočítáno z Exifu:\nRychlost závěrky - citlivost - clona - expoziční korekce fotoaparátu.\n 2) Vypočítáno z hodnoty raw bílého bodu a expoziční kompenzace Rawtherapee. +TP_COLORAPP_ADAPTVIEWING;Svítivost prohlížení (cd/m²) +TP_COLORAPP_ADAPTVIEWING_TOOLTIP;Absolutní jas prostředí prohlížení\n(obvykle 16cd/m²). +TP_COLORAPP_ADAP_AUTO_TOOLTIP;Pokud je povoleno (doporučeno), RT vypočítá optimální hodnotu z Exif dat.\nPokud si přejete zadat hodnotu ručně, nejprve zrušte zatržení tohoto pole. +TP_COLORAPP_ALGO;Algoritmus +TP_COLORAPP_ALGO_ALL;Vše +TP_COLORAPP_ALGO_JC;Světlost + Barevnost (JC) +TP_COLORAPP_ALGO_JS;Světlost + Nasycení (JS) +TP_COLORAPP_ALGO_QM;Jas a pestrobarevnost (QM) +TP_COLORAPP_ALGO_TOOLTIP;Umožňuje vybrat mezi podmnožinou nebo všemi parametry. +TP_COLORAPP_BADPIXSL;Filtr vypálených/mrtvých pixelů +TP_COLORAPP_BADPIXSL_TOOLTIP;Potlačení vypálených/mrtvých (jasně zabarvených) pixelů.\n0 = Bez efektu\n1 = Medián\n2 = Gaussový.\nPopřípadě obrázek upravte tak, aby jste se vyhnuli velmi tmavým stínům.\n\nTyto artefakty vznikají díky omezením CIECAM02. +TP_COLORAPP_BRIGHT;Jas (O) +TP_COLORAPP_BRIGHT_TOOLTIP;Jas v CIECAM02 bere v potaz svítivost bílé a rozdíly jasů mezi L*a*b* a RGB. +TP_COLORAPP_CHROMA;Barevnost (C) +TP_COLORAPP_CHROMA_M;Barevnost (M) +TP_COLORAPP_CHROMA_M_TOOLTIP;Pestrobarevnost se v CIECAM02 liší od pestrobarevnosti L*a*b* a RGB. +TP_COLORAPP_CHROMA_S;Sytost (S) +TP_COLORAPP_CHROMA_S_TOOLTIP;Nasycení se v CIECAM02 liší od nasycení L*a*b* a RGB. +TP_COLORAPP_CHROMA_TOOLTIP;Barevnost se v CIECAM02 liší od barevnosti L*a*b* a RGB. +TP_COLORAPP_CIECAT_DEGREE;CAT02 přizpůsobení +TP_COLORAPP_CONTRAST;Kontrast (I) +TP_COLORAPP_CONTRAST_Q;Kontrast (O) +TP_COLORAPP_CONTRAST_Q_TOOLTIP;Kontrast pro posuvník Q se v CIECAM02 liší od kontrastu L*a*b* a RGB. +TP_COLORAPP_CONTRAST_TOOLTIP;Kontrast pro posuvník J se v CIECAM02 liší od kontrastu L*a*b* a RGB. +TP_COLORAPP_CURVEEDITOR1;Tónová křivka 1 +TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Zobrazuje histogram L* (L*a*b*) křivky před CIECAM02.\nPokud je volba "Zobrazit CIECAM02 histogramy výstupu v křivkách" povolena, zobrazí histogram J nebo Q po CIECAM02 .\n\nJ a Q histogramy nejsou na hlavním panelu zobrazeny.\n\nHistogram konečného výsledku je zobrazen na hlavním panelu. +TP_COLORAPP_CURVEEDITOR2;Tónová křivka 2 +TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Stejné použití jako u druhé expoziční tónové křivky. +TP_COLORAPP_CURVEEDITOR3;Barevná křivka +TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Upravte barevnost, saturaci nebo pestrobarevnost.\n\nZobrazí histogram barevnosti (L*a*b*) před CIECAM02.\nPokud je volba "Zobrazit CIECAM02 histogramy výstupu v křivkách" povolena, zobrazí histogram C, S nebo M po CIECAM02 .\n\nC, S a M histogramy nejsou na hlavním panelu zobrazeny.\nHistogram konečného výsledku je zobrazen na hlavním panelu. +TP_COLORAPP_DATACIE;CIECAM02 histogramy výstupu v křivkách +TP_COLORAPP_DATACIE_TOOLTIP;Pokud je povoleno, zobrazuje histogram v CIECAM02 křivkách přibližné hodnoty/rozsahy po CIECAM02 úpravách J nebo Q, a C, S nebo M.\nVýběr neovlivňuje histogram na hlavním panelu.\n\nPokud je zakázáno, zobrazuje histogram v CIECAM02 křivkách L*a*b* hodnoty před CIECAM02 úpravami. +TP_COLORAPP_DEGREE_AUTO_TOOLTIP;Pokud je povoleno (doporučeno), RawTherapee vypočítá optimální hodnotu, jenž následně používá jak CAT02 tak i celý CIECAM02.\nZakažte, pokud si přejete zadat hodnotu ručně (doporučeny jsou hodnoty nad 65). +TP_COLORAPP_DEGREE_TOOLTIP;Míra CIE Chromatic Adaptation Transform 2002. +TP_COLORAPP_GAMUT;Kontrola palety (L*a*b*) +TP_COLORAPP_GAMUT_TOOLTIP;Povolí kontrolu palety v L*a*b* režimu. +TP_COLORAPP_HUE;Odstín (h) +TP_COLORAPP_HUE_TOOLTIP;Odstín (h) - úhel mezi 0° a 360°. +TP_COLORAPP_LABEL;CIE model přizpůsobení barev 2002 +TP_COLORAPP_LABEL_CAM02;Úpravy obrázku +TP_COLORAPP_LABEL_SCENE;Podmínky scény +TP_COLORAPP_LABEL_VIEWING;Podmínky zobrazení +TP_COLORAPP_LIGHT;Světlost (I) +TP_COLORAPP_LIGHT_TOOLTIP;Světlost v CIECAM02 se liší od světlosti v L*a*b* a RGB. +TP_COLORAPP_MODEL;VB - Model +TP_COLORAPP_MODEL_TOOLTIP;Model bílého bodu.\n\nWB [RT] + [výstup]: Pro scénu je použito vyvážení bílé RT , CIECAM02 je nastaven na D50 a vyvážení bílé výstupního zařízení je nastaveno ve Volby > Správa barev.\n\nWB [RT+CAT02] + [výstup]: CAT02 používá RT nastavení vyvážení bílé a vyvážení bílé výstupního zařízení je nastaveno ve Volby > Správa barev. +TP_COLORAPP_RSTPRO;Ochrana červených a pleťových tónů +TP_COLORAPP_RSTPRO_TOOLTIP;Ochrana červených a pleťových tónů (posuvníky a křivky). +TP_COLORAPP_SHARPCIE;--nepoužito-- +TP_COLORAPP_SHARPCIE_TOOLTIP;--nepoužito-- +TP_COLORAPP_SURROUND;Okolí +TP_COLORAPP_SURROUND_AVER;Průměrné +TP_COLORAPP_SURROUND_DARK;Tmavé +TP_COLORAPP_SURROUND_DIM;Tlumené +TP_COLORAPP_SURROUND_EXDARK;Velmi tmavé +TP_COLORAPP_SURROUND_TOOLTIP;Změní tóny a barvy dle podmínek prohlížení na výstupním zařízení\n\nPrůměrné: Průměrné osvětlení prostředí (standardní). Obrázek nebude změněn.\n\nTlumené: Tlumené prostředí (TV). Obrázek bude mírně ztmaven.\n\nTmavé: Tmavé prostředí (projektor). Obrázek bude více tmavý.\n\nVelmi tmavé: Velmi tmavé prostředí (cutsheet). Obrázek bude velmi tmavý. +TP_COLORAPP_SURSOURCE;Tmavé okolí +TP_COLORAPP_SURSOURCE_TOOLTIP;Může být použito pokud má zdrojový obrázek tmavý okraj. +TP_COLORAPP_TCMODE_BRIGHTNESS;Jas +TP_COLORAPP_TCMODE_CHROMA;Barevnost +TP_COLORAPP_TCMODE_COLORF;Pestrobarevnost +TP_COLORAPP_TCMODE_LABEL1;Mód křivky 1 +TP_COLORAPP_TCMODE_LABEL2;Mód křivky 2 +TP_COLORAPP_TCMODE_LABEL3;Mód barevné křivky +TP_COLORAPP_TCMODE_LIGHTNESS;Světlost +TP_COLORAPP_TCMODE_SATUR;Sytost +TP_COLORAPP_TONECIE;Mapování tónů pomocí CIECAM02 +TP_COLORAPP_TONECIE_TOOLTIP;Pokud je volba zakázána, probíhá mapování tónů v prostoru L*a*b*.\nPokud je volba povolena. probíhá mapování tónů pomocí CIECAM02.\nAby měla tato volba efekt, musí být povolen nástroj Mapování tónů. +TP_COLORAPP_WBCAM;WB [RT+CAT02] + [výstup] +TP_COLORAPP_WBRT;WB [RT] + [výstup] +TP_COLORTONING_AB;o C/L +TP_COLORTONING_AUTOSAT;Automaticky +TP_COLORTONING_BALANCE;Vyvážené +TP_COLORTONING_BY;o C/L +TP_COLORTONING_CHROMAC;Neprůhlednost +TP_COLORTONING_COLOR;Barvy +TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;Barevná neprůhlednost dle jasu oC=f(L) +TP_COLORTONING_HIGHLIGHT;Světla +TP_COLORTONING_HUE;Odstín +TP_COLORTONING_LABEL;Barevné tónování +TP_COLORTONING_LAB;Mísení L*a*b* +TP_COLORTONING_LUMAMODE;Zachování jasu +TP_COLORTONING_LUMAMODE_TOOLTIP;Pokud je povoleno, je při změně barvy (červená, zelená, tyrkysová, modrá...) zachován jas každého pixelu. +TP_COLORTONING_LUMA;Jas +TP_COLORTONING_METHOD;Metoda +TP_COLORTONING_METHOD_TOOLTIP;"Mísení L*a*b*", "RGB posuvníky" a "RGB křivky" používají interpolované mísení barev.\n"Vyvážení barev (Stíny, střední tóny a světla)" a "Saturace dvou barev" používají přímé barvy.\n\nNástroj Černobílá může být povolen při použití kterékoli metody barevného tónování. +TP_COLORTONING_MIDTONES;Střední tóny +TP_COLORTONING_NEUTRAL;Vrátit posuvníky +TP_COLORTONING_NEUTRAL_TIP;Vrátí všechny hodnoty (stíny, střední tóny a světla) na výchozí pozice. +TP_COLORTONING_OPACITY;Neprůhlednost +TP_COLORTONING_RGBCURVES;RGB - křivky +TP_COLORTONING_RGBSLIDERS;RGB - Posuvníky +TP_COLORTONING_SATURATEDOPACITY;Síla +TP_COLORTONING_SATURATIONTHRESHOLD;Práh +TP_COLORTONING_SA;Ochrana nasycení +TP_COLORTONING_SHADOWS;Stíny +TP_COLORTONING_SPLITCOCO;Vysoká kvalita stínů, středních tónů a světel +TP_COLORTONING_SPLITCO;Stíny, střední tóny a světla +TP_COLORTONING_SPLITLR;Sytost dvou barev +TP_COLORTONING_STRENGTH;Síla +TP_COLORTONING_STR;Síla +TP_COLORTONING_TWO2;Speciální barevnost "2 barvy" +TP_COLORTONING_TWOALL;Speciální barevnost +TP_COLORTONING_TWOBY;Speciální a* a b* +TP_COLORTONING_TWOCOLOR_TOOLTIP;Standardní barevnost:\nLineární průběh, a* = b*.\n\nSpeciální barevnost:\nLineární průběh, a* = b*, ale nespojitě - vyzkoušejte pro úhlopříčky.\n\nSpeciální a* a b*:\nLineární nespojitý průběh s oddělenými křivkami pro a* a b*. Vhodné pro speciální efekty.\n\nSpeciální barevnost dvou barev:\nVíce předvídatelné. +TP_COLORTONING_TWOSTD;Standardní barevnost +TP_CROP_FIXRATIO;Zamknout poměr +TP_CROP_GTDIAGONALS;Pravidlo diagonál +TP_CROP_GTEPASSPORT;Biometrický pas +TP_CROP_GTFRAME;Snímek +TP_CROP_GTGRID;Mřížka +TP_CROP_GTNONE;Nic +TP_CROP_GTRULETHIRDS;Pravidlo třetin +TP_CROP_GUIDETYPE;Druh vodítek: +TP_CROP_H;Výška +TP_CROP_LABEL;Ořez +TP_CROP_PPI;PPI= +TP_CROP_SELECTCROP;Vyznačit výřez +TP_CROP_W;Šířka +TP_CROP_X;X +TP_CROP_Y;Y +TP_DARKFRAME_AUTOSELECT;Automatický výběr +TP_DARKFRAME_LABEL;Tmavý snímek +TP_DEFRINGE_LABEL;Odstranění lemu +TP_DEFRINGE_RADIUS;Poloměr +TP_DEFRINGE_THRESHOLD;Práh +TP_DIRPYRDENOISE_33;3×3 silný +TP_DIRPYRDENOISE_55SOFT;5×5 +TP_DIRPYRDENOISE_55;5×5 silný +TP_DIRPYRDENOISE_77;7×7 (pomalý) +TP_DIRPYRDENOISE_99;9x9 (velmi pomalé) +TP_DIRPYRDENOISE_ABM;Pouze barevnost +TP_DIRPYRDENOISE_AUTO;Automatická celková +TP_DIRPYRDENOISE_AUTO_TOOLTIP;Zkusí odhadnout barevný šum\nPozor, tento výpočet je zprůměrován a zcela subjektivní! +TP_DIRPYRDENOISE_AUT;Automatická celková +TP_DIRPYRDENOISE_BLUE;Barevnost - Modrá a žlutá +TP_DIRPYRDENOISE_C2TYPE_TOOLTIP;Ručně\nOvlivňuje celý obrázek.\nVolby redukce šumu nastavujete ručně.\n\nCelková automatika\nOvlivňuje celý obrázek.\nPro výpočet parametrů celkové redukce barevného šumu je použito 9 zón.\n\nNáhled\nOvlivňuje celý obrázek.\nPro výpočet celkového nastavení redukce barevného šumu je použita viditelná část obrázku. +TP_DIRPYRDENOISE_CCCURVE;Křivka barevnosti +TP_DIRPYRDENOISE_CHROMAFR;Barevnost +TP_DIRPYRDENOISE_CHROMA;Barevnost - Hlavní +TP_DIRPYRDENOISE_CTYPE;Metoda aut. zpracování +TP_DIRPYRDENOISE_CTYPE_TOOLTIP;Ručně\nOvlivňuje celý obrázek.\nVolby redukce šumu nastavujete ručně.\n\nCelková automazika\nOvlivňuje celý obrázek.\nPro výpočet parametrů celkové redukce barevného šumu je použito 9 zón.\n\nVíce zónová automatika\nBez náhledu - funguje pouze při ukládání, přesto je možné pomocí funkce "Náhled" získat alespoň částečnou představu o výsledku, Nastavení jsou aplikována na centrální dlaždici.\nObrázek je rozdělen na dlaždice (V závislosti na velikosti obrázku jich bude 10 až 70) a pro každou dlaždici bude vypočítáno vhodné nastavení redukce barevného šumu.\n\nNáhled\nOvlivňuje celý obrázek.\nPro výpočet celkového nastavení redukce barevného šumu je použita viditelná část obrázku. +TP_DIRPYRDENOISE_CURVEEDITOR_CC;Barevnost +TP_DIRPYRDENOISE_CURVEEDITOR_CC_TOOLTIP;Zvýší (násobí) hodnoty všech barevných posuvníků.\nKřivka vám umožní nastavit sílu redukce barevného šumu jako funkci barvy. Například pro zvýšení účinku v oblastech s nízkou saturací a snížení v oblastech s vysokou saturací. +TP_DIRPYRDENOISE_CURVEEDITOR_L_TOOLTIP;Moduluje akci 'jasového' odstranění šumu +TP_DIRPYRDENOISE_CUR;Křivka +TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Může být použito jak pro raw tak i pro ostatní obrázky.\n\nPokud je použito pro ostatní obrázky, závisí redukce šumu dle jasu na gamě vstupního barevného profilu. Předpokládá se sRGB gama a proto se může výsledek u obrázků s rozdílnou gamou barevného profilu lišit. +TP_DIRPYRDENOISE_ENH;Vylepšený režim +TP_DIRPYRDENOISE_ENH_TOOLTIP;Zvýší kvalitu odstranění šumu, ale zároveň prodlouží dobu zpracování o 20%. +TP_DIRPYRDENOISE_GAMMA;Gama +TP_DIRPYRDENOISE_GAMMA_TOOLTIP;Gama ovlivňuje sílu redukce šumu v rozsahu tónů. Menší hodnoty ovlivňují stíny, kdežto vysoké hodnoty zesílí efekt v jasných tónech. +TP_DIRPYRDENOISE_LABEL;Redukce šumu +TP_DIRPYRDENOISE_LABM;L*a*b* +TP_DIRPYRDENOISE_LAB;L*a*b* +TP_DIRPYRDENOISE_LCURVE;Křivka jasů +TP_DIRPYRDENOISE_LDETAIL;Jas - Detail +TP_DIRPYRDENOISE_LM;Pouze jas +TP_DIRPYRDENOISE_LPLABM;Vyvážená L* (trochu) + a*b* (normální) +TP_DIRPYRDENOISE_LTYPE;Ovládání jasu +TP_DIRPYRDENOISE_LUMAFR;Jas +TP_DIRPYRDENOISE_LUMAFR_TOOLTIP;Vlnková transformace na svítivost a Fourierova transformace pro detail svítivosti +TP_DIRPYRDENOISE_LUMA;Jas +TP_DIRPYRDENOISE_MANU;Ručně +TP_DIRPYRDENOISE_MAN;Ručně +TP_DIRPYRDENOISE_MEDMETHOD;Metoda mediánu +TP_DIRPYRDENOISE_MEDTYPE;Typ mediánu +TP_DIRPYRDENOISE_MED;Filtr medián +TP_DIRPYRDENOISE_MED_TOOLTIP;Povolit odstranění šumu Medián +TP_DIRPYRDENOISE_METHOD11;Kvalita +TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Kvalita může být přizpůsobena vzoru šumu. Nastavení "Vysoká" vylepší efekt redukce šumu za cenu navýšení času zpracování. +TP_DIRPYRDENOISE_METHOD;Metoda +TP_DIRPYRDENOISE_METHOD_TOOLTIP;Pro raw obrázky může být použita jak RGB tak i L*a*b* metoda.\n\nPro ostatní obrázky bude vždy použita metoda L*a*b* bez ohledu na výběr. +TP_DIRPYRDENOISE_METM_TOOLTIP;Pokud je použito 'Pouze Jas' a 'L*a*b*' metody, bude při odstranění šumu použit filtr medián hned po vlnkové transformaci.\nPokud je použit "RGB" mód, bude filtr použit až na úplný závěr procesu redukce šumu. +TP_DIRPYRDENOISE_MET_TOOLTIP;Aplikuje filtr medián požadované velikosti. Čím větší velikost, tím déle to trvá.\n\n3×3 jemný: upraví 5 pixelů v rozsahu jednoho pixelu.\n3×3: upraví 9 pixelů v rozsahu jednoho pixelu.\n5×5 jemný; upraví 13 pixelů v rozsahu dvou pixelů.\n5×5: upraví 25 pixelů v rozsahu dvou pixelů.\n7×7: upraví 49 pixelů v rozsahu tří pixelů.\n9×9: upraví 81 pixelů v rozsahu čtyř pixelů.\n\nV některých případech může být větší kvality dosaženo pomocí několika průběhů s menším rozsahem než jedním průběhem s velkým rozsahem. +TP_DIRPYRDENOISE_NOISELABELEMPTY;Náhled šumu: Střed= - Výšky= - +TP_DIRPYRDENOISE_NOISELABEL;Náhled šumu: Střed=%1 Výšky=%2 +TP_DIRPYRDENOISE_NRESID_TOOLTIP;Zobrazuje zbývající úroveň zašumění části obrázku viditelného v náhledu po vlnkové transformaci.\n\n>300 Hodně šumu\n100-300 Šum\n50-100 Málo šumu\n<50 Velmi málo šumu\n\nUpozornění: hodnoty RGB a L*a*b* režimu se budou lišit. Protože v RGB režimu nedochází ke kompletnímu oddělení jasu a barev jsou RGB hodnoty jméně přesné +TP_DIRPYRDENOISE_PASSES;Počet průchodů mediánu +TP_DIRPYRDENOISE_PASSES_TOOLTIP;Aplikování medián filtru 3×3 se třemi průchody často vede k lepšímu výsledku než jednou aplikovaný filtr 7×7. +TP_DIRPYRDENOISE_PON;Více zónová automatika +TP_DIRPYRDENOISE_PREVLABEL;Velikost náhledu=%1, Střed: Px=%2 Py=%3 +TP_DIRPYRDENOISE_PREV;Náhled +TP_DIRPYRDENOISE_PRE;Více zónový náhled +TP_DIRPYRDENOISE_RED;Barevnost - Červená a zelená +TP_DIRPYRDENOISE_RGBM;RGB +TP_DIRPYRDENOISE_RGB;RGB +TP_DIRPYRDENOISE_SHALBI;Vysoká +TP_DIRPYRDENOISE_SHAL;Běžná +TP_DIRPYRDENOISE_SLI;Posuvník +TP_DIRPYRDENOISE_SOFT;3×3 +TP_DIRPYRDENOISE_TILELABEL;Velikost dlaždice=%1, Střed: Tx=%2 Ty=%3 +TP_DIRPYREQUALIZER_ALGO;Rozsah pleťových tónů +TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Jemný: blíž k barvám pleti, minimalizuje zásahy na ostatních barvách.\nVelký: více zabrání vzniku artefaktů. +TP_DIRPYREQUALIZER_HUESKIN;Odstín pleti +TP_DIRPYREQUALIZER_HUESKIN_TOOLTIP;Pyramida je pro horní část, kde je algoritmus nejvíce efektivní.\nKe spodní části, tranzitním zónám.\nPokud potřebujete posunout oblast hodně doleva nebo doprava - nebo pokud se vyskytnou artefakty = vyvážení bílé není správné, můžete mírně zmenšit zónu aby jste zabránili ovlivnění ostatních částí obrázku. +TP_DIRPYREQUALIZER_LABEL;Kontrast dle detailu úrovní +TP_DIRPYREQUALIZER_LUMACOARSEST;Nejhrubší +TP_DIRPYREQUALIZER_LUMACONTRAST_MINUS;Kontrast - +TP_DIRPYREQUALIZER_LUMACONTRAST_PLUS;Kontrast + +TP_DIRPYREQUALIZER_LUMAFINEST;Nejjemnější +TP_DIRPYREQUALIZER_LUMANEUTRAL;Neutrální +TP_DIRPYREQUALIZER_SKIN;Ochrana a zaměření na pleťové tóny +TP_DIRPYREQUALIZER_SKIN_TOOLTIP;Hodnota -100: zaměřeno na tóny pokožky.\nHodnota 0: se všemi tóny je zacházeno stejně.\nHodnota +100: tóny pokožky jsou chráněny a ovlivněny jsou všechny ostatní tóny. +TP_DIRPYREQUALIZER_THRESHOLD;Práh +TP_DIRPYREQUALIZER_TOOLTIP;Počet pokusů pro redukci artefaktů vzniklých přenosem barvy (odstín, barevnost a jas) pokožky na zbytek obrázku. +TP_DISTORTION_AMOUNT;Míra +TP_DISTORTION_AUTO;Automatická korekce zkreslení +TP_DISTORTION_AUTO_TIP;Automatická korekce zkreslení objektivu pro některé fotoaparáty (Micro 4/3, některé kompakty a jiné). +TP_DISTORTION_LABEL;Korekce zkreslení +TP_EPD_EDGESTOPPING;Zachování okrajů +TP_EPD_LABEL;Mapování tónů +TP_EPD_REWEIGHTINGITERATES;Počet průchodů převážení +TP_EPD_SCALE;Měřítko +TP_EPD_STRENGTH;Síla +TP_EPD_TOOLTIP;Mapování tónů je dostupné v Lab (standard) a CIECAM02 módu.\n\nPro zapnutí CIECAM02 mu mapování tónů povolte prosím následující nastavení:\n1. CIECAM02\n2. Algoritmus="Jas a pestrobarevnost (QM)"\n3. "Mapování tónů pomocí jasu CIECAM02 (Q)" +TP_EXPOSURE_AUTOLEVELS;Automatické úrovně +TP_EXPOSURE_AUTOLEVELS_TIP;Přepne provedení Automatické úrovně na automatickou sadu hodnot parametrů založených na analýze obrázku\nPokud to je nezbytné, povolí rekonstrukci světel. +TP_EXPOSURE_BLACKLEVEL;Černá +TP_EXPOSURE_BRIGHTNESS;Světlost +TP_EXPOSURE_CLIP;Oříznutí % +TP_EXPOSURE_CLIP_TIP;Podíl klipujících bodů v automatických operacích úrovní. +TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Práh komprese světel +TP_EXPOSURE_COMPRHIGHLIGHTS;Komprese světel +TP_EXPOSURE_COMPRSHADOWS;Komprese stínů +TP_EXPOSURE_CONTRAST;Kontrast +TP_EXPOSURE_CURVEEDITOR1;Tónová křivka 1 +TP_EXPOSURE_CURVEEDITOR2;Tónová křivka 2 +TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Podívejte se prosím na článek "Exposure > Tone Curves" na RawPedii, kde se můžete naučit. jak pomocí dvou tónových křivek dosáhnout ten nejlepší výsledek. +TP_EXPOSURE_EXPCOMP;Kompenzace expozice +TP_EXPOSURE_LABEL;Expozice +TP_EXPOSURE_SATURATION;Sytost +TP_EXPOSURE_TCMODE_FILMLIKE;Jako film +TP_EXPOSURE_TCMODE_LABEL1;Mód křivky 1 +TP_EXPOSURE_TCMODE_LABEL2;Mód křivky 2 +TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Mísení saturace a hodnoty +TP_EXPOSURE_TCMODE_STANDARD;Běžný +TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Běžný vážený +TP_EXPOS_BLACKPOINT_LABEL;Raw černé body +TP_EXPOS_WHITEPOINT_LABEL;Raw bílé body +TP_FILMSIMULATION_LABEL;Simulace filmu +TP_FILMSIMULATION_STRENGTH;Síla +TP_FILMSIMULATION_ZEROCLUTSFOUND;Nastavte složku HaldCLUT v nastaveních +TP_FLATFIELD_AUTOSELECT;Automatický výběr +TP_FLATFIELD_BLURRADIUS;Poloměr rozostření +TP_FLATFIELD_BLURTYPE;Typ rozostření +TP_FLATFIELD_BT_AREA;Oblast +TP_FLATFIELD_BT_HORIZONTAL;Vodorovně +TP_FLATFIELD_BT_VERTHORIZ;Vodorovně a svisle +TP_FLATFIELD_BT_VERTICAL;Svisle +TP_FLATFIELD_CLIPCONTROL;Kontrola oříznutí +TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Kontrola oříznutí zabrání oříznutí světel po aplikaci Flat Field. Pokud byly světla oříznuta ještě před aplikací Flat field, může se objevit barevný nádech. +TP_FLATFIELD_LABEL;Flat Field +TP_GAMMA_CURV;Gama +TP_GAMMA_FREE;Volná gama +TP_GAMMA_OUTPUT;Výstupní gama +TP_GAMMA_SLOP;Sklon (lineární) +TP_GENERAL_11SCALE_TOOLTIP;Efekt tohoto nástroje je viditelný pouze při přiblížení 1:1. +TP_GRADIENT_CENTER;Střed +TP_GRADIENT_CENTER_X;Střed X +TP_GRADIENT_CENTER_X_TOOLTIP;Posune přechod doleva (záporné hodnoty) nebo napravo (kladné hodnoty). +TP_GRADIENT_CENTER_Y;Střed Y +TP_GRADIENT_CENTER_Y_TOOLTIP;Posune přechod nahoru (záporné hodnoty) nebo dolů (kladné hodnoty). +TP_GRADIENT_DEGREE;Úhel +TP_GRADIENT_DEGREE_TOOLTIP;Úhel otočení ve stupních. +TP_GRADIENT_FEATHER;Rozptyl +TP_GRADIENT_FEATHER_TOOLTIP;Šíře přechodu v procentech uhlopříčky obrázku. +TP_GRADIENT_LABEL;Přechodový filtr +TP_GRADIENT_STRENGTH;Síla +TP_GRADIENT_STRENGTH_TOOLTIP;Síla filtru v expozičních stupních. +TP_HLREC_BLEND;Mísení +TP_HLREC_CIELAB;Mísení CIELab +TP_HLREC_COLOR;Propagace barev +TP_HLREC_ENA_TOOLTIP;Může být aktivováno automatickou expozicí. +TP_HLREC_LABEL;Rekonstrukce světel +TP_HLREC_LUMINANCE;Obnovení jasů +TP_HLREC_METHOD;Metoda: +TP_HSVEQUALIZER_CHANNEL;Kanál +TP_HSVEQUALIZER_HUE;H +TP_HSVEQUALIZER_LABEL;HSV korekce +TP_HSVEQUALIZER_SAT;S +TP_HSVEQUALIZER_VAL;V +TP_ICM_BLENDCMSMATRIX;Smísení ICC světel s matici +TP_ICM_BLENDCMSMATRIX_TOOLTIP;Povolit obnovení vypálených jasů při použití ICC profilů založených na LUT. +TP_ICM_DCPILLUMINANT;Osvětlení +TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolované +TP_ICM_DCPILLUMINANT_TOOLTIP;Vyberte které vložené DCP osvětlení se má použít. Ve výchozím stavu se použije "interpolované", což je mix mezi dvěma osvětleními založenými na vyvážení bílé. Nastavené je dostupné pouze v případě, že je povoleno dvojité DCP osvětlení s podporou interpolace. +TP_ICM_INPUTCAMERAICC;Automatický dohledaný profil fotoaparátu +TP_ICM_INPUTCAMERAICC_TOOLTIP;Použít RawTherapee specifický DCP nebo ICC vstupní barevný profil fotoaparátu jenž je mnohem přesnější než zjednodušená matice. Není dostupné pro všechny fotoaparáty. Profily jsou uloženy ve složkách /iccprofiles/input a /dcpprofiles a jsou automaticky vybrány dle jména souboru shodného s fotoaparátem. +TP_ICM_INPUTCAMERA;Standard fotoaparátu +TP_ICM_INPUTCAMERA_TOOLTIP;Použít jednoduchou matici barev dcraw, rozšířenou verzi RawTherapee (kterýkoli dostupný, založený na modelu fotoaparátu) nebo vložený v DNG. +TP_ICM_INPUTCUSTOM;Vlastní +TP_ICM_INPUTCUSTOM_TOOLTIP;Vyberte vlastní DCP/ICC soubor barevného profilu pro fotoaparát. +TP_ICM_INPUTDLGLABEL;Vybrat vstupní DCP/ICC profil... +TP_ICM_INPUTEMBEDDED;Použít vložený profil, pokud je k dispozici +TP_ICM_INPUTEMBEDDED_TOOLTIP;Použít barevný profil vložený do ostatních souborů. +TP_ICM_INPUTNONE;Bez profilu +TP_ICM_INPUTNONE_TOOLTIP;Nikdy nepoužívat vstupní barevný profil.\nPoužijte pouze ve speciálních případech. +TP_ICM_INPUTPROFILE;Vstupní profil +TP_ICM_LABEL;Správa barev +TP_ICM_NOICM;Bez ICM: sRGB výstup +TP_ICM_OUTPUTPROFILE;Výstupní barevný prostor +TP_ICM_SAVEREFERENCE;Uložit referenční obrázek pro profilování +TP_ICM_SAVEREFERENCE_TOOLTIP;Uloží lineární TIFF obrázek před aplikováním vstupního profilu. Výsledek může být použit pro kalibraci a generování profilu fotoaparátu. +TP_ICM_TONECURVE;Použita tónová křivka DCP +TP_ICM_TONECURVE_TOOLTIP;Použije vloženou DCP tónovou křivku. Nastavení je dostupné pouze v případě, že DCP obsahuje tónovou křivku. +TP_ICM_WORKINGPROFILE;Pracovní barevný prostor +TP_IMPULSEDENOISE_LABEL;Redukce impulzního šumu +TP_IMPULSEDENOISE_THRESH;Práh +TP_LABCURVE_AVOIDCOLORSHIFT;Zabránit posunu barev +TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Přizpůsobit barvy palety barevného pracovního prostoru a aplikovat Munsellovu korekci. +TP_LABCURVE_BRIGHTNESS;Světlost +TP_LABCURVE_CHROMATICITY;Barevnost +TP_LABCURVE_CHROMA_TOOLTIP;Pro černobílé tónování nastavte barevnost na -100. +TP_LABCURVE_CONTRAST;Kontrast +TP_LABCURVE_CURVEEDITOR;Křivka jasů +TP_LABCURVE_CURVEEDITOR_A_RANGE1;Sytě zelená +TP_LABCURVE_CURVEEDITOR_A_RANGE2;Pastelově zelená +TP_LABCURVE_CURVEEDITOR_A_RANGE3;Pastelově červená +TP_LABCURVE_CURVEEDITOR_A_RANGE4;Sytě červená +TP_LABCURVE_CURVEEDITOR_B_RANGE1;Sytě modrá +TP_LABCURVE_CURVEEDITOR_B_RANGE2;Pastelově modrá +TP_LABCURVE_CURVEEDITOR_B_RANGE3;Pastelově žlutá +TP_LABCURVE_CURVEEDITOR_B_RANGE4;Sytě žlutá +TP_LABCURVE_CURVEEDITOR_CC;CC +TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutrální +TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Matné +TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastelové +TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Saturované +TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Barevnost dle barevnosti C=f(C) +TP_LABCURVE_CURVEEDITOR_CH;CH +TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Barevnost dle odstínu C=f(H) +TP_LABCURVE_CURVEEDITOR_CL;CL +TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Barevnost dle jasu C=f(L) +TP_LABCURVE_CURVEEDITOR_HH;HH +TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Odstín dle odstínu H=f(H) +TP_LABCURVE_CURVEEDITOR_LC;LC +TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Jas dle barevnosti L=f(C) +TP_LABCURVE_CURVEEDITOR_LH;LH +TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Jas dle jasu odstínu L=f(H) +TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Jas dle jasu L=f(L) +TP_LABCURVE_LABEL;L*a*b* úpravy +TP_LABCURVE_LCREDSK;Omezit LC na tóny červené a pleti +TP_LABCURVE_LCREDSK_TIP;Pokud je povoleno, je LC křivka omezena pouze na červené a pleťové tóny\nPokud je zakázáno, aplikuje se na všechny tóny +TP_LABCURVE_RSTPROTECTION;Ochrana červených a pleťových tónů +TP_LABCURVE_RSTPRO_TOOLTIP;Pracuje s posuvníkem barevnosti a CC křivkou. +TP_LENSGEOM_AUTOCROP;Automatický ořez +TP_LENSGEOM_FILL;Automatické vyplnění +TP_LENSGEOM_LABEL;Objektiv / Geometrie +TP_LENSPROFILE_LABEL;Korekční profil objektivu +TP_LENSPROFILE_USECA;Korekce chromatické aberace +TP_LENSPROFILE_USEDIST;Korekce zkreslení +TP_LENSPROFILE_USEVIGN;Korekce vinětace +TP_NEUTRAL;Neutrální +TP_NEUTRAL_TIP;Nastaví posuvníky expozice na neutrální hodnoty,\nPoužije stejné kontroly jako volba "Automatické úrovně" bez ohledu na to, zda jsou nebo nejsou Automatické úrovně použity. +TP_PCVIGNETTE_FEATHER;Rozptyl +TP_PCVIGNETTE_FEATHER_TOOLTIP;Rozptyl:\n0 = pouze rohy,\n50 = napůl do středu,\n100 = do středu. +TP_PCVIGNETTE_LABEL;Viněta +TP_PCVIGNETTE_ROUNDNESS;Zaoblení +TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Zaoblení:\n0 = čtverec,\n50 = elipsa,\n100 = kruh. +TP_PCVIGNETTE_STRENGTH;Síla +TP_PCVIGNETTE_STRENGTH_TOOLTIP;Síla filtru v expozičních stupních (v rozích). +TP_PERSPECTIVE_HORIZONTAL;Vodorovně +TP_PERSPECTIVE_LABEL;Perspektiva +TP_PERSPECTIVE_VERTICAL;Svisle +TP_PFCURVE_CURVEEDITOR_CH;Odstín +TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Upravuje sílu odstranění lemu dle barvy.\nVyšší = více,\nnižší = méně. +TP_PREPROCESS_DEADPIXFILT;Filtr mrtvých pixelů +TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Zkusí potlačit mrtvé pixely. +TP_PREPROCESS_GREENEQUIL;Vyrovnání zelené +TP_PREPROCESS_HOTPIXFILT;Filtr vypálených pixelů +TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Zkusí potlačit vypálené pixely. +TP_PREPROCESS_LABEL;Předzpracování +TP_PREPROCESS_LINEDENOISE;Filtrovat linkové rušení +TP_PREPROCESS_NO_FOUND;Nic nenalezeno +TP_RAWCACORR_AUTO;Automatická korekce +TP_RAWCACORR_CABLUE;Modrá +TP_RAWCACORR_CARED;Červená +TP_RAWEXPOS_BLACKS;Úrovně černé +TP_RAWEXPOS_BLACK_0;Zelená 1 (řídící) +TP_RAWEXPOS_BLACK_1;Červená +TP_RAWEXPOS_BLACK_2;Modrá +TP_RAWEXPOS_BLACK_3;Zelená 2 +TP_RAWEXPOS_BLACK_BLUE;Modrá +TP_RAWEXPOS_BLACK_GREEN;Zelená +TP_RAWEXPOS_BLACK_RED;Červená +TP_RAWEXPOS_LINEAR;Korekce bílého bodu +TP_RAWEXPOS_PRESER;Zachování světel +TP_RAWEXPOS_RGB;Červená, telená, modrá +TP_RAWEXPOS_TWOGREEN;Spojit zelené +TP_RAW_DCBENHANCE;Vylepšení DCB +TP_RAW_DCBITERATIONS;Počet průchodů DCB +TP_RAW_DMETHOD;Metoda +TP_RAW_DMETHOD_PROGRESSBAR;%1 demozajkování... +TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Vylepšení demozajkování... +TP_RAW_DMETHOD_TOOLTIP;Poznámka: IGV a LMMSE jsou určeny pro obrázky s vysokým ISO, kde pomáhají redukci šumu minimalizovat posterizaci a vyžehlený vzhled. +TP_RAW_FALSECOLOR;Počet kroků potlačování chybných barev +TP_RAW_LABEL;Demozajkování +TP_RAW_LMMSEITERATIONS;Kroky rozšíření LMMSE +TP_RAW_LMMSE_TOOLTIP;Přidá gamu (krok 1) - přidá mediány (kroky 2, až 4) a následně přidá (kroky 5 a 6) vyčištění artefaktů a vylepšení poměru signálu a šumu. +TP_RAW_SENSOR_BAYER_LABEL;Snímač s Bayerovou maskou +TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;Tří průchodová dává lepší výsledky (doporučeno pro fotky s níským ISO).\nJednoprůchodová je téměř k nerozeznání od tří průchodové pro vysoké ISO a je rychlejší. +TP_RAW_SENSOR_XTRANS_LABEL;Senzory s X-Trans maticí +TP_RESIZE_APPLIESTO;Aplikovat na: +TP_RESIZE_CROPPEDAREA;Oblast ořezu +TP_RESIZE_FITBOX;Výřez +TP_RESIZE_FULLIMAGE;Celý obrázek +TP_RESIZE_HEIGHT;Výška +TP_RESIZE_H;Výška: +TP_RESIZE_LABEL;Změna velikosti +TP_RESIZE_LANCZOS;Lanczos +TP_RESIZE_METHOD;Metoda: +TP_RESIZE_NEAREST;Nejbližší +TP_RESIZE_SCALE;Měřítko +TP_RESIZE_SPECIFY;Zvolte: +TP_RESIZE_WIDTH;Šířka +TP_RESIZE_W;Šířka: +TP_RGBCURVES_BLUE;B +TP_RGBCURVES_CHANNEL;Kanál +TP_RGBCURVES_GREEN;G +TP_RGBCURVES_LABEL;RGB křivky +TP_RGBCURVES_LUMAMODE;Mód svítivosti +TP_RGBCURVES_LUMAMODE_TOOLTIP;Mód svítivosti umožňuje odlišit podíl jednotlivých R, G, B kanálů na svítivosti obrázku bez změny barvy obrázku. +TP_RGBCURVES_RED;R +TP_ROTATE_DEGREE;Stupně +TP_ROTATE_LABEL;Otočení +TP_ROTATE_SELECTLINE;Vyznačit rovinu +TP_SAVEDIALOG_OK_TIP;Zkratka: Ctrl-Enter +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Světla +TP_SHADOWSHLIGHTS_HLTONALW;Tonální rozsah světel +TP_SHADOWSHLIGHTS_LABEL;Stíny/Světla +TP_SHADOWSHLIGHTS_LOCALCONTR;Místní kontrast +TP_SHADOWSHLIGHTS_RADIUS;Poloměr +TP_SHADOWSHLIGHTS_SHADOWS;Stíny +TP_SHADOWSHLIGHTS_SHARPMASK;Maska ostrosti +TP_SHADOWSHLIGHTS_SHTONALW;Tonální rozsah stínů +TP_SHARPENEDGE_AMOUNT;Kvantita +TP_SHARPENEDGE_LABEL;Hrany +TP_SHARPENEDGE_PASSES;Počet průchodů +TP_SHARPENEDGE_THREE;Pouze jas +TP_SHARPENING_AMOUNT;Míra +TP_SHARPENING_EDRADIUS;Poloměr +TP_SHARPENING_EDTOLERANCE;Zachování okrajů +TP_SHARPENING_HALOCONTROL;Omezení haló artefatů +TP_SHARPENING_HCAMOUNT;Míra +TP_SHARPENING_LABEL;Doostření +TP_SHARPENING_METHOD;Metoda +TP_SHARPENING_ONLYEDGES;Doostřit pouze okraje +TP_SHARPENING_RADIUS;Poloměr +TP_SHARPENING_RLD;RL Dekonvoluce +TP_SHARPENING_RLD_AMOUNT;Míra +TP_SHARPENING_RLD_DAMPING;Útlum +TP_SHARPENING_RLD_ITERATIONS;Počet průchodů +TP_SHARPENING_THRESHOLD;Práh +TP_SHARPENING_TOOLTIP;S CIECAM02 očekávejte mírně odlišný efekt. Pokud pozorujete rozdíly, upravte dle potřeby. +TP_SHARPENING_USM;Maskování rozostření +TP_SHARPENMICRO_AMOUNT;Kvantita +TP_SHARPENMICRO_LABEL;Mikrokontrast +TP_SHARPENMICRO_MATRIX;Matice 3×3 namísto 5×5 +TP_SHARPENMICRO_UNIFORMITY;Jednolitost +TP_VIBRANCE_AVOIDCOLORSHIFT;Zabránit posunu barev +TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH +TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Tóny pleti +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Červená/Nachová +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Červená +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Červená/Žlutá +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Žlutá +TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Odstín dle odstínu H=f(H) +TP_VIBRANCE_LABEL;Živost +TP_VIBRANCE_PASTELS;Pastelové tóny +TP_VIBRANCE_PASTSATTOG;Propojit pastelové a saturované tóny +TP_VIBRANCE_PROTECTSKINS;Zachovat tóny pleti +TP_VIBRANCE_PSTHRESHOLD;Práh mezi pastelovými a saturovanými tóny +TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Práh saturace +TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;Spodní vodorovná osa představuje pastelové a horní saturované tóny..\nSvislá osa představuje rozsah saturace. +TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Váha přechodu mezi pastelovými a saturovanými tóny +TP_VIBRANCE_SATURATED;Saturované tóny +TP_VIGNETTING_AMOUNT;Míra +TP_VIGNETTING_CENTER;Střed +TP_VIGNETTING_CENTER_X;Střed X +TP_VIGNETTING_CENTER_Y;Střed Y +TP_VIGNETTING_LABEL;Úprava vinětace +TP_VIGNETTING_RADIUS;Poloměr +TP_VIGNETTING_STRENGTH;Síla +TP_WAVELET_1;Úroveň 1 +TP_WAVELET_2;Úroveň 2 +TP_WAVELET_3;Úroveň 3 +TP_WAVELET_4;Úroveň 4 +TP_WAVELET_5;Úroveň 5 +TP_WAVELET_6;Úroveň 6 +TP_WAVELET_7;Úroveň 7 +TP_WAVELET_8;Úroveň 8 +TP_WAVELET_9;Úroveň 9 +TP_WAVELET_ALL;Všechny úrovně ve všech směrech +TP_WAVELET_APPLYTO;Použít na +TP_WAVELET_AVOID;Zabránit posunu barev +TP_WAVELET_CH1;Všechny barvy +TP_WAVELET_CH2;Pastelové - Saturované +TP_WAVELET_CH3;Propojit kontrast úrovní +TP_WAVELET_CHRO;Saturované - Pastelové +TP_WAVELET_CHRO_TOOLTIP;Hranice mezi pastely a nasycením\n 1 - x úroveň nasycení\n x - 9 úroveň pastelů +TP_WAVELET_CHR;Propojení barev +TP_WAVELET_CHR_TOOLTIP;Přizpůsobí barevnost jako funkci:\na - kontrast úrovní\nb - síla posuvníku propojení barev +TP_WAVELET_COLORT;Neprůhlednost červená-zelená Úrovně +TP_WAVELET_CONTRAST_MINUS;Kontrast - +TP_WAVELET_CONTRAST_PLUS;Kontrast + +TP_WAVELET_CONTRA;Kontrast +TP_WAVELET_CONTRA_TOOLTIP;Změní kontrast zůstatku obrazu\nFunkce maximálních úrovní +TP_WAVELET_CONTR;Paleta - nastavení +TP_WAVELET_DALL;Všechny směry +TP_WAVELET_DISP;Nastavení náhledu +TP_WAVELET_DONE;Svisle +TP_WAVELET_DTHR;Napříč +TP_WAVELET_DTWO;Vodorovně +TP_WAVELET_EDGE;Doostření hran (jas) +TP_WAVELET_EDGTHRESH;Práh +TP_WAVELET_EDRAD;Poloměr +TP_WAVELET_EDVAL;Hodnota +TP_WAVELET_FINEST;Nejjemnější +TP_WAVELET_HIGHLIGHT;Zvýrazněný rozsah jasů +TP_WAVELET_HS1;Celý rozsah jasů +TP_WAVELET_HS2;Stíny/Světla +TP_WAVELET_HUESKIN;Rozsah odstínů (pleť) +TP_WAVELET_HUESKIN_TOOLTIP;Pyramida je pro horní část, kde je algoritmus nejvíce efektivní.\nKe spodní části, tranzitním zónám.\nPokud potřebujete posunout oblast hodně doleva nebo doprava - nebo pokud se vyskytnou artefakty = vyvážení bílé není správné, můžete mírně zmenšit zónu aby jste zabránili ovlivnění ostatních částí obrázku. +TP_WAVELET_HUESKY;Rozsah odstínů (obloha) +TP_WAVELET_HUESKY_TOOLTIP;Pyramida je pro horní část, kde je algoritmus nejvíce efektivní.\nKe spodní části, tranzitním zónám.\nPokud potřebujete posunout oblast hodně doleva nebo doprava - nebo pokud se vyskytnou artefakty = vyvážení bílé není správné, můžete mírně zmenšit zónu aby jste zabránili ovlivnění ostatních částí obrázku. +TP_WAVELET_INF;Méně nebo shodně s úrovní +TP_WAVELET_LABEL;Úrovně vlnky +TP_WAVELET_LARGEST;Nejhrubší +TP_WAVELET_LEVCH;Barevnost +TP_WAVELET_LEVELS;Úrovně vlnky +TP_WAVELET_LEVELS_TOOLTIP;Vyberte počet úrovní detailu mezi které bude obrázek rozložen. Více úrovní potřebuje více paměti a zpracování trvá déle. +TP_WAVELET_LEVF;Kontrast +TP_WAVELET_LEVLABEL;Náhled maximálně dostupné úrovně=%1 +TP_WAVELET_LOWLIGHT;Rozsah projasnění stínů +TP_WAVELET_MEDI;Omezení artefaktů na modré obloze +TP_WAVELET_NEUTRAL;Neutrální +TP_WAVELET_ONE;Jedna úroveň +TP_WAVELET_OPACITY;Neprůhlednost modrá-žlutá Úrovně +TP_WAVELET_PASTEL;Barevnost pastelů +TP_WAVELET_PREVIEWLEVELS;Náhled +TP_WAVELET_RESCHRO;Barevnost +TP_WAVELET_RESCONH;Světla +TP_WAVELET_RESCON;Stíny +TP_WAVELET_RESID;Zůstatek obrazu +TP_WAVELET_SAT;Saturovaná barevnost +TP_WAVELET_SETTINGS;Nastavení vlnky +TP_WAVELET_SKIN;Ochrana a zaměření na tóny pleti +TP_WAVELET_SKIN_TOOLTIP;Hodnota -100: zaměřeno na tóny pokožky.\nHodnota 0: se všemi tóny je zacházeno stejně.\nHodnota +100: tóny pokožky jsou chráněny a ovlivněny jsou všechny ostatní tóny. +TP_WAVELET_SKY;Ochrana a zaměření na tóny oblohy +TP_WAVELET_SKY_TOOLTIP;Zvýšení/snížení barevnosti rozsahu odstínu vstupu/výstupu\nPro eliminaci artefaktů v modré obloze - mikrokontrasr, mikrobarevnost,... +TP_WAVELET_STRENGTH;Síla +TP_WAVELET_SUPE;Extra +TP_WAVELET_SUP;Nad úrovní +TP_WAVELET_THRESHOLD2;Úrovně stínů +TP_WAVELET_THRESHOLD2_TOOLTIP;Pokud tuto hodnotu změníte, bude na úrovně mezi úrovní 9 a 9 - hodnota použita pouze funkce projasnění stínů.\nNa ostatní úrovně budou použity všechny funkce.\nMaximální úroveň stínů je ovlivněna hodnotou světel (9 - úroveň světel)světelnost +TP_WAVELET_THRESHOLD;Úrovně světel +TP_WAVELET_THRESHOLD_TOOLTIP;Pokud tuto hodnotu změníte, bude funkce zvýraznění jasů použita pouze u úrovní nad touto hodnotou .\nNa ostatní úrovně budou použity všechny funkce. +TP_WAVELET_THRH;Práh světel +TP_WAVELET_THR;Práh stínů +TP_WAVELET_TILESBIG;Velké dlaždice +TP_WAVELET_TILESFULL;Celý obrázek +TP_WAVELET_TILESIZE;Velikost dlaždice +TP_WAVELET_TILESLIT;Malé dlaždice +TP_WAVELET_TILES_TOOLTIP;Zpracování celého obrázku vede k lepší kvalitě a je doporučováno. Naproti tomu dlaždice jsou náhradní řešení pro uživatele s nedostatkem paměti. Paměťové nároky najdete na RawPedii. +TP_WAVELET_TON;Tónování +TP_WBALANCE_AUTO;Automaticky +TP_WBALANCE_CAMERA;Fotoaparát +TP_WBALANCE_CLOUDY;Zataženo +TP_WBALANCE_CUSTOM;Vlastní +TP_WBALANCE_DAYLIGHT;Denní světlo (slunečno) +TP_WBALANCE_EQBLUERED;Korekce modrá/červená +TP_WBALANCE_EQBLUERED_TOOLTIP;Umožňuje odchýlení se od normálního chování "vyvážení bílé" pomocí změny vyvážení modré a červené.\nToto může být užitečné v těchto případech:\na) podmínky jsou velmi odlišné od standardních (například pod vodou),\nb) podmínky se velmi liší od podmínek za kterých probíhala kalibrace,\nc) nevhodné snímače nebo ICC profily. +TP_WBALANCE_FLASH55;Leica +TP_WBALANCE_FLASH60;Standard, Canon, Pentax, Olympus +TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta +TP_WBALANCE_FLASH_HEADER;Blesk +TP_WBALANCE_FLUO1;F1 - Denní světlo +TP_WBALANCE_FLUO2;F2 - Studená bílá +TP_WBALANCE_FLUO3;F3 - Bílá +TP_WBALANCE_FLUO4;F4 - Teplá bílá +TP_WBALANCE_FLUO5;F5 - Denní světlo +TP_WBALANCE_FLUO6;F6 - Lehká bílá +TP_WBALANCE_FLUO7;F7 - D65 Simulace denního světla +TP_WBALANCE_FLUO8;F8 - D50 / Sylvania F40 Design +TP_WBALANCE_FLUO9;F9 - Studená bílá deluxe +TP_WBALANCE_FLUO10;F10 - Philips TL85 +TP_WBALANCE_FLUO11;F11 - Philips TL84 +TP_WBALANCE_FLUO12;F12 - Philips TL83 +TP_WBALANCE_FLUO_HEADER;Fluorescenční +TP_WBALANCE_GREEN;Odstín +TP_WBALANCE_GTI;GTI +TP_WBALANCE_HMI;HMI +TP_WBALANCE_JUDGEIII;JudgeIII +TP_WBALANCE_LABEL;Vyvážení bílé +TP_WBALANCE_LAMP_HEADER;Žárovka +TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 +TP_WBALANCE_LED_HEADER;LED +TP_WBALANCE_LED_LSI;LSI Lumelex 2040 +TP_WBALANCE_METHOD;Metoda +TP_WBALANCE_SHADE;Stín +TP_WBALANCE_SIZE;Rozměr: +TP_WBALANCE_SOLUX35;Solux 3500K +TP_WBALANCE_SOLUX41;Solux 4100K +TP_WBALANCE_SOLUX47;Solux 4700K (vendor) +TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) +TP_WBALANCE_SPOTWB;Bodové vyvážení +TP_WBALANCE_TEMPERATURE;Teplota +TP_WBALANCE_TUNGSTEN;Wolfram +TP_WBALANCE_WATER1;Pod vodou 1 +TP_WBALANCE_WATER2;Pod vodou 2 +TP_WBALANCE_WATER_HEADER;Pod vodou +ZOOMPANEL_100;(100%) +ZOOMPANEL_NEWCROPWINDOW;Otevřít (nové) okno detailu +ZOOMPANEL_ZOOM100;Zvětšit na 100%\nZkratka: z +ZOOMPANEL_ZOOMFITSCREEN;Přizpůsobit obrazovce\nZkratka: f +ZOOMPANEL_ZOOMIN;Přiblížit\nZkratka: + +ZOOMPANEL_ZOOMOUT;Oddálit\nZkratka: - + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!CURVEEDITOR_AXIS_IN;I: +!CURVEEDITOR_AXIS_LEFT_TAN;LT: +!CURVEEDITOR_AXIS_OUT;O: +!CURVEEDITOR_AXIS_RIGHT_TAN;RT: +!CURVEEDITOR_EDITPOINT_HINT;Enable edition of node in/out values.\n\nRight-click on a node to select it.\nRight-click on empty space to de-select the node. +!FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!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_ASIMAGE;As Image +!HISTORY_MSG_341;W - Edge performance +!HISTORY_MSG_342;W - ES - First level +!HISTORY_MSG_343;W - Chroma levels +!HISTORY_MSG_344;W - Meth chroma sl/cur +!HISTORY_MSG_345;W - ES - Local contrast +!HISTORY_MSG_346;W - ES - Local contrast method +!HISTORY_MSG_347;W - Denoise - Level 0 +!HISTORY_MSG_348;W - Denoise - Level 1 +!HISTORY_MSG_349;W - Denoise - Level 2 +!HISTORY_MSG_350;W - ES - Edge detection +!HISTORY_MSG_351;W - Residual - HH curve +!HISTORY_MSG_352;W - Background +!HISTORY_MSG_353;W - ES - Gradient sensitivity +!HISTORY_MSG_354;W - ES - Enhance +!HISTORY_MSG_355;W - ES - Threshold low +!HISTORY_MSG_356;W - ES - Threshold high +!HISTORY_MSG_357;W - Denoise - Link with ES +!HISTORY_MSG_358;W - Gamut - CH +!HISTORY_MSG_359;Hot/Dead - Threshold +!HISTORY_MSG_360;TM Gamma +!HISTORY_MSG_361;W - Final - Chroma balance +!HISTORY_MSG_362;W - Residual - Compression method +!HISTORY_MSG_363;W - Residual - Compression strength +!HISTORY_MSG_364;W - Final - Contrast balance +!HISTORY_MSG_365;W - Final - Delta balance +!HISTORY_MSG_366;W - Residual - Compression gamma +!HISTORY_MSG_367;W - ES - Local contrast curve +!HISTORY_MSG_368;W - Final - Contrast balance +!HISTORY_MSG_369;W - Final - Balance method +!HISTORY_MSG_370;W - Final - Local contrast curve +!MAIN_TAB_WAVELET;Wavelet +!MAIN_TAB_WAVELET_TOOLTIP;Shortcut: Alt-w +!PARTIALPASTE_WAVELETGROUP;Wavelet processing +!PREFERENCES_CURVEBBOXPOS;Position of curve copypasta buttons +!PREFERENCES_CURVEBBOXPOS_ABOVE;Above +!PREFERENCES_CURVEBBOXPOS_BELOW;Below +!PREFERENCES_CURVEBBOXPOS_LEFT;Left +!PREFERENCES_CURVEBBOXPOS_RIGHT;Right +!PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders +!PREFERENCES_NAVIGATIONFRAME;Navigation +!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_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. +!TP_CROP_GTHARMMEANS;Harmonic Means +!TP_CROP_GTTRIANGLE1;Golden Triangles 1 +!TP_CROP_GTTRIANGLE2;Golden Triangles 2 +!TP_DIRPYREQUALIZER_ARTIF;Reduce artifacts +!TP_EPD_GAMMA;Gamma +!TP_EXPOSURE_TCMODE_LUMINANCE;Luminance +!TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance +!TP_RAW_HD;Threshold +!TP_RAW_HD_TOOLTIP;Lower values make hot/dead pixel detection more aggressive, but false positives may lead to artifacts. If you notice any artifacts appearing when enabling the Hot/Dead Pixel Filters, gradually increase the threshold value until they disappear. +!TP_WAVELET_B0;Black +!TP_WAVELET_B1;Grey +!TP_WAVELET_B2;Residual +!TP_WAVELET_BACUR;Curve +!TP_WAVELET_BALANCE;Contrast balance d/v-h +!TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chromaticity or residual tone mapping are activated, the effect due to balance is amplified. +!TP_WAVELET_BALCHRO;Chroma balance +!TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chromaticity balance. +!TP_WAVELET_BANONE;None +!TP_WAVELET_BASLI;Slider +!TP_WAVELET_BATYPE;Contrast balance method +!TP_WAVELET_CCURVE;Local contrast +!TP_WAVELET_CHCU;Curve +!TP_WAVELET_CHSL;Sliders +!TP_WAVELET_CHTYPE;Chrominance method +!TP_WAVELET_COMBOTH;Both +!TP_WAVELET_COMPCONT;Contrast +!TP_WAVELET_COMPGAMMA;Compression gamma +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjusting the gamma of the residual image allow you to equilibrate the data and histogram. +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjust gamma for residual image and compression.\nAllow to equilibrate data and histogram +!TP_WAVELET_COMPTM;Tone mapping +!TP_WAVELET_CONTEDIT;'After' Contrast curve +!TP_WAVELET_CONTEDIT;'After' contrast curve +!TP_WAVELET_CTYPE;Chrominance control +!TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modifies local contrast as a function of the original local contrast (absciss)\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 100..300)\n66% absciss represents standard deviation of local contrast (real value about 300..800)\n100% represents maximum (real value about 3000..8000) +!TP_WAVELET_CURVEEDITOR_CH;Contrast levels=f(Hue) +!TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modifies each level's contrast as a function oh hue.\nTake care not to overwrite changes made with the Gamut Hue controls.\nThe curve will only have an effect when wavelet contrast level sliders are non-zero. +!TP_WAVELET_CURVEEDITOR_CL;L +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Applies a final contrast luminance curve at the end of the wavelet treatment. +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Apply a contrast luminance curve at the end of wavelet level threatment +!TP_WAVELET_CURVEEDITOR_HH;HH +!TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modifies the residual image's hue as a function of hue. +!TP_WAVELET_DAUB;Edge performance +!TP_WAVELET_DAUB_TOOLTIP;Changes Daubechies coefficients:\nD4 = Standard,\nD14 = Often best performance, 10% more time-intensive.\n\nAffects edge detection as well as the general quality of the firsts levels. However the quality is not strictly related to this coefficient and can vary with images and uses. +!TP_WAVELET_EDCU;Curve +!TP_WAVELET_EDGCONT;Local contrast +!TP_WAVELET_EDGCONT_TOOLTIP;Adjusting the points to the left decreases contrast, and to the right increases it.\nBottom-left, Top-Left, Top-Right, Bottom-right represent respectively local contast for low values, mean, mean+stdev, maxima +!TP_WAVELET_EDGEDETECTTHR2;Threshold high (detection) +!TP_WAVELET_EDGEDETECTTHR;Threshold low (noise) +!TP_WAVELET_EDGEDETECTTHR_TOOLTIP;This adjuster lets you target edge detection for example to avoid applying edge sharpness to fine details, such as noise in the sky. +!TP_WAVELET_EDGEDETECT;Gradient sensitivity +!TP_WAVELET_EDGEDETECT_TOOLTIP;Moving the slider to the right increases edge sensitivity. This affects local contrast, edge settings and noise. +!TP_WAVELET_EDGREINF_TOOLTIP;Reinforce or reduce the action of the first level, do the opposite to the second level, and leave the rest unchanged. +!TP_WAVELET_EDGTHRESH_TOOLTIP;Change the repartition between the first levels and the others. The higher the threshold the more the action is centred on the first levels. Be careful with negative values, they increase the action of high levels and can introduce artifacts. +!TP_WAVELET_EDRAD_TOOLTIP;This radius adjustment is very different from those in other sharpening tools. Its value is compared to each level through a complex function. In this sense, a value of zero still has an effect. +!TP_WAVELET_EDSL;Threshold Sliders +!TP_WAVELET_EDTYPE;Local contrast method +!TP_WAVELET_FINAL;Final Touchup +!TP_WAVELET_ITER;Delta balance levels +!TP_WAVELET_ITER_TOOLTIP;Left: increase low levels and reduce high levels,\nRight: reduce low levels and increase high levels. +!TP_WAVELET_LEVONE;Level 2 +!TP_WAVELET_LEVTWO;Level 3 +!TP_WAVELET_LEVZERO;Level 1 +!TP_WAVELET_LINKEDG;Link with Edge Sharpness' Strength +!TP_WAVELET_LIPST;Enhanced algorithm +!TP_WAVELET_LIPST_TOOLTIP;This algorithm uses Lipschitz regularity to increase edge detection quality at a cost of increased processing time and memory requirements. +!TP_WAVELET_MEDGREINF;First level +!TP_WAVELET_MEDILEV;Edge detection +!TP_WAVELET_NOISE;Denoise and Refine +!TP_WAVELET_NOIS;Denoise +!TP_WAVELET_OPACITYWL;Final local contrast +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify final local contrast in function of last local contrast (absciss) for all levels decomposition\nTake into account: \na)contrast levels \nb)edge sharpness \nc)contrast balance\nd)decomposition-recomposition\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 200..1000)\n66% absciss represents standard deviation of local contrast (real value about 1000..2000)\n100% represents maximum (real value about 5000..13000) +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify the final local contrast at the end of the wavelet treatment.\n\nThe left side represents the smallest local contrast, progressing to the largest local contrast on the right. +!TP_WAVELET_OPACITYW;Contrast balance d/v-h curve +!TP_WAVELET_PREVIEWBACK;Background +!TP_WAVELET_RE1;Reinforced +!TP_WAVELET_RE2;Unchanged +!TP_WAVELET_RE3;Reduced +!TP_WAVELET_TMHIGH;High +!TP_WAVELET_TMLOWHIGH;Low+High +!TP_WAVELET_TMNONE;None +!TP_WAVELET_TMSTD;Standard +!TP_WAVELET_TMSTRENGTH;Compression strength +!TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image. When the value is different from 0, the Strength and Gamma sliders of the Tone Mapping tool in the Exposure tab will become grayed out. +!TP_WAVELET_TMTYPE;Compression method +!TP_WAVELET_daub2;D2 - low +!TP_WAVELET_daub4;D4 - standard +!TP_WAVELET_daub6;D6 - standard plus +!TP_WAVELET_daub10;D10 - medium +!TP_WAVELET_daub14;D14 - high +!ZOOMPANEL_ZOOMFITCROPSCREEN;Fit crop to screen\nShortcut: Alt-f diff --git a/rtdata/languages/Dansk b/rtdata/languages/Dansk new file mode 100644 index 000000000..a335bdf3d --- /dev/null +++ b/rtdata/languages/Dansk @@ -0,0 +1,1857 @@ +#01 2009-06-27 krengbo + +ADJUSTER_RESET_TO_DEFAULT;Nulstil til standard +CURVEEDITOR_LINEAR;Lineær +CURVEEDITOR_LOADDLGLABEL;Indlæs kurve... +CURVEEDITOR_SAVEDLGLABEL;Gem kurve... +CURVEEDITOR_TOOLTIPLINEAR;Nulstil kurve til lineær +CURVEEDITOR_TOOLTIPLOAD;Indlæs kurve fra fil +CURVEEDITOR_TOOLTIPSAVE;Gem nuværende kurve +DIRBROWSER_FOLDERS;Mapper +EXIFFILTER_APERTURE;Blænde +EXIFFILTER_CAMERA;Kamera +EXIFFILTER_FOCALLEN;Brændvidde +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Objektiv +EXIFFILTER_SHUTTER;Lukkertid +EXIFPANEL_ADDEDITHINT;Tilføj nyt tags eller rediger tags +EXIFPANEL_ADDEDIT;Tilføj/Rediger +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Indtast værdi +EXIFPANEL_ADDTAGDLG_SELECTTAG;Vælg tags +EXIFPANEL_ADDTAGDLG_TITLE;Tilføj/Rediger tags +EXIFPANEL_KEEPHINT;Bevar de valgte tags under skrivning af fil +EXIFPANEL_KEEP;Bevar +EXIFPANEL_REMOVEHINT;Fjern de valgte tags under skrivning af fil +EXIFPANEL_REMOVE;Fjern +EXIFPANEL_RESETALLHINT;Gendan alle tags til de oprindelige værdier +EXIFPANEL_RESETALL;Gendan alt +EXIFPANEL_RESETHINT;Gendan valgte tags til de oprindelige værdier +EXIFPANEL_RESET;Gendan +EXIFPANEL_SUBDIRECTORY;Undermappe +FILEBROWSER_APPLYPROFILE;Anvend profil +FILEBROWSER_CLEARPROFILE;Ryd profil +FILEBROWSER_COPYPROFILE;Kopier profil +FILEBROWSER_DELETEDLGLABEL;Bekræft sletning af fil +FILEBROWSER_DELETEDLGMSG;Er du sikker på, at du vil slette de %1 valgte filer? +FILEBROWSER_EMPTYTRASHHINT;Slet filerne i papirkurv permanent +FILEBROWSER_EMPTYTRASH;Tøm papirkurv +FILEBROWSER_PARTIALPASTEPROFILE;Indsæt delvist +FILEBROWSER_PASTEPROFILE;Indsæt profil +FILEBROWSER_POPUPCANCELJOB;Annuler opgave +FILEBROWSER_POPUPMOVEEND;Flyt til slutning af køen +FILEBROWSER_POPUPMOVEHEAD;Flyt til starten af køen +FILEBROWSER_POPUPOPENINEDITOR;Åbn i Editor +FILEBROWSER_POPUPOPEN;Åbn +FILEBROWSER_POPUPPROCESS;Sæt i opgavekø +FILEBROWSER_POPUPREMOVE;fjern fra filsystem +FILEBROWSER_POPUPRENAME;Omdøb +FILEBROWSER_POPUPSELECTALL;Vælg alt +FILEBROWSER_POPUPTRASH;Flyt til papirkurv +FILEBROWSER_POPUPUNRANK;Fjern vurdering +FILEBROWSER_POPUPUNTRASH;Fjern fra papirkurv +FILEBROWSER_RENAMEDLGLABEL;Omdøb fil +FILEBROWSER_RENAMEDLGMSG;Omdøb filen "%1" til: +FILEBROWSER_SHOWDIRHINT;Vis alle billeder i mappen +FILEBROWSER_SHOWRANK1HINT;Vis billeder vurderet med 1 stjerne +FILEBROWSER_SHOWRANK2HINT;Vis billeder vurderet med 2 stjerner +FILEBROWSER_SHOWRANK3HINT;Vis billeder vurderet med 3 stjerner +FILEBROWSER_SHOWRANK4HINT;Vis billeder vurderet med 4 stjerner +FILEBROWSER_SHOWRANK5HINT;Vis billeder vurderet med 5 stjerner +FILEBROWSER_SHOWTRASHHINT;Vis indhold i papirkurven +FILEBROWSER_SHOWUNRANKHINT;Vis billeder uden vurdering +FILEBROWSER_STARTPROCESSINGHINT;Begynd at bearbejde/gemme billeder i køen +FILEBROWSER_STARTPROCESSING;Begynd bearbejdning +FILEBROWSER_STOPPROCESSINGHINT;Stop bearbejdningen af billeder +FILEBROWSER_STOPPROCESSING;Stop bearbejdning +FILEBROWSER_THUMBSIZE;Miniaturestr. +FILEBROWSER_ZOOMINHINT;Gør miniaturer større +FILEBROWSER_ZOOMOUTHINT;Gør miniaturer mindre +GENERAL_ABOUT;Om +GENERAL_CANCEL;Annuler +GENERAL_DISABLED;Fravalgt +GENERAL_DISABLE;Fravælg +GENERAL_ENABLED;Valgt +GENERAL_ENABLE;Vælg +GENERAL_LANDSCAPE;Bredformat +GENERAL_NA;Ikke muligt +GENERAL_NO;Nej +GENERAL_OK;OK +GENERAL_PORTRAIT;Højformat +GENERAL_SAVE;Gem +HISTOGRAM_TOOLTIP_B;Vis/skjul blåt histogram +HISTOGRAM_TOOLTIP_G;Vis/skjul grønt histogram +HISTOGRAM_TOOLTIP_L;Vis/skjul CIELAB histogram +HISTOGRAM_TOOLTIP_R;Vis/skjul rødt histogram +HISTORY_CHANGED;Ændret +HISTORY_CUSTOMCURVE;Tilpasset kurve +HISTORY_DELSNAPSHOT;Slet +HISTORY_FROMCLIPBOARD;Fra udklipsholder +HISTORY_LABEL;Historie +HISTORY_MSG_1;Foto indlæst +HISTORY_MSG_2;Profil indlæst +HISTORY_MSG_3;Profil ændret +HISTORY_MSG_4;Gennemse historie +HISTORY_MSG_5;Lysstyrke +HISTORY_MSG_6;Kontrast +HISTORY_MSG_7;Sort +HISTORY_MSG_8;Eksponeringskompensation +HISTORY_MSG_9;Kompensation af højlys +HISTORY_MSG_10;Skyggereduktion +HISTORY_MSG_11;Tonekurve +HISTORY_MSG_12;Autoeksponering +HISTORY_MSG_13;Eksponeringsadvarsel +HISTORY_MSG_14;Lysstyrke +HISTORY_MSG_15;Kontrast +HISTORY_MSG_16;Sort +HISTORY_MSG_17;Reduktion af højlys. +HISTORY_MSG_18;Reduktion af skygger +HISTORY_MSG_19;Kurve +HISTORY_MSG_20;Skarphed +HISTORY_MSG_21;Skarphed radius +HISTORY_MSG_22;Skarphed mængde +HISTORY_MSG_23;Skarphed tærskel +HISTORY_MSG_24;Gør kun kanter skarpere +HISTORY_MSG_25;Skarphed kantdetektion radius +HISTORY_MSG_26;Skarphed kantolerance +HISTORY_MSG_27;Skarphed halo-kontrol +HISTORY_MSG_28;Halo-kontrol mængde +HISTORY_MSG_29;Skarphedsmetode +HISTORY_MSG_30;Udfoldning radius +HISTORY_MSG_31;Udfoldning mængde +HISTORY_MSG_32;Udfoldning dæmpning +HISTORY_MSG_33;Udfoldning gentagelser +HISTORY_MSG_34;Undgå farveklipning +HISTORY_MSG_35;Mætningsbegrænser +HISTORY_MSG_36;Mætningsgrænse +HISTORY_MSG_37;Forstærk farver +HISTORY_MSG_38;Hvidbalancemetode +HISTORY_MSG_39;Farvetemoeratur +HISTORY_MSG_40;Hvidbalance nuance +HISTORY_MSG_41;Farveskift "A" +HISTORY_MSG_42;Farveskift "B" +HISTORY_MSG_43;Begræns lysstøj +HISTORY_MSG_44;Lysstøj radius +HISTORY_MSG_45;Lysstæj kanttolerance +HISTORY_MSG_46;Begræns farvestøj +HISTORY_MSG_47;Farvestøj radius +HISTORY_MSG_48;Farvestøj kanttolerance +HISTORY_MSG_49;Kantfølsomhed farvestøj +HISTORY_MSG_50;Skygger/højlys værktøj +HISTORY_MSG_51;Forstærk højlys +HISTORY_MSG_52;Forstærk skygger +HISTORY_MSG_53;Højlys toneomfang +HISTORY_MSG_54;Skygger toneomfang +HISTORY_MSG_55;Lokal kontrast +HISTORY_MSG_56;Skygger/højlys radius +HISTORY_MSG_57;Grov rotering +HISTORY_MSG_58;Vend vandret +HISTORY_MSG_59;Vend lodret +HISTORY_MSG_60;Roter +HISTORY_MSG_61;Roter +HISTORY_MSG_62;Ret objektivfejl +HISTORY_MSG_63;Snapshot valgt +HISTORY_MSG_64;Beskær billede +HISTORY_MSG_65;Kromatisk aberration +HISTORY_MSG_66;Red højlys +HISTORY_MSG_67;Red højlys mængde +HISTORY_MSG_68;Red højlys metode +HISTORY_MSG_69;Nuværende farverum +HISTORY_MSG_70;Output farverum +HISTORY_MSG_71;Input farverum +HISTORY_MSG_72;Vignettering +HISTORY_MSG_73;Kanalmixer +HISTORY_MSG_74;Skift størrelse mål +HISTORY_MSG_75;Skift størrelse metode +HISTORY_MSG_76;Exif metadata +HISTORY_MSG_77;IPTC metadata +HISTORY_MSG_78;Data specified for resize +HISTORY_MSG_79;Resize width +HISTORY_MSG_80;Resize height +HISTORY_MSG_81;Resize enabled +HISTORY_NEWSNAPSHOT;Tilføj... +HISTORY_SNAPSHOTS;Snapshots +HISTORY_SNAPSHOT;Snapshot +IPTCPANEL_AUTHORSPOSITIONHINT;Stillingsbetegnelse for skaberen eller skaberne af objektet (byline titel). +IPTCPANEL_AUTHORSPOSITION;Forfatterens stilling +IPTCPANEL_AUTHOR;Forfatter +IPTCPANEL_CAPTIONHINT;En beskrivelse af informationerne i tekstform. +IPTCPANEL_CAPTIONWRITERHINT;Navnet på den person, der har været indblandet i at skrive, redigere eller korrekturlæse billedet eller billedteksten. +IPTCPANEL_CAPTIONWRITER;Skribent på billedtekst +IPTCPANEL_CAPTION;Billedtekst +IPTCPANEL_CATEGORYHINT;Identificerer billedets emne efter skaberens mening. +IPTCPANEL_CATEGORY;Kategori +IPTCPANEL_CITYHINT;Byen, hvor billedet er taget.. +IPTCPANEL_CITY;By +IPTCPANEL_COPYHINT;Kopier IPTC-indstillinger til udklipsholder. +IPTCPANEL_COPYRIGHTHINT;Enhver nødvendig copyright-oplysning. +IPTCPANEL_COPYRIGHT;Copyright +IPTCPANEL_COUNTRYHINT;Navnet på det land, hvor billedet blev taget. +IPTCPANEL_COUNTRY;Land +IPTCPANEL_CREDITHINT;Identificerer den, der stiller billedet til rådighed, ikke nødvendigvis ejeren/skaberen. +IPTCPANEL_CREDIT;Anerkendelse +IPTCPANEL_DATECREATEDHINT;Den dato, hvor det intellektuelle indhold i billedet blev skabt; Format: ÅÅÅÅMMDD (Date Created). +IPTCPANEL_DATECREATED;Dato skabt +IPTCPANEL_EMBEDDEDHINT;Genskab til indlejrede IPTC-data i billedfilen +IPTCPANEL_EMBEDDED;Indlejret +IPTCPANEL_HEADLINEHINT;En indførsel, som kan udgives og giver en opsummering af billedets indhold. +IPTCPANEL_HEADLINE;Overskrift +IPTCPANEL_INSTRUCTIONSHINT;Andre redaktionelle instruktioner angående billedets brug. +IPTCPANEL_INSTRUCTIONS;Instruktioner +IPTCPANEL_KEYWORDSHINT;Bruges til at angive særlige søgbare ord. +IPTCPANEL_KEYWORDS;Søgeord +IPTCPANEL_PASTEHINT;Indsæt IPTC-indstillinger fra udklipsholder +IPTCPANEL_PROVINCEHINT;Provinsen/delstaten, hvor billedet stammer fra. +IPTCPANEL_PROVINCE;Provins +IPTCPANEL_RESETHINT;Genskab til profilstandard +IPTCPANEL_RESET;Genskab +IPTCPANEL_SOURCEHINT;Den originale ejer af billedets intellektuelle indhold. +IPTCPANEL_SOURCE;Kilde +IPTCPANEL_SUPPCATEGORIESHINT;Yderligere angivelse af billedets emne. +IPTCPANEL_SUPPCATEGORIES;Suppl. katergorier +IPTCPANEL_TITLEHINT;En kort beskrivelse af billedet. +IPTCPANEL_TITLE;Titel +IPTCPANEL_TRANSREFERENCEHINT;En kode, der repræsenterer placeringen for den originale overlevering. +IPTCPANEL_TRANSREFERENCE;Overleveringsreference +MAIN_BUTTON_PREFERENCES;Indstillinger +MAIN_BUTTON_SAVE;Gem billede +MAIN_BUTTON_SENDTOEDITOR;Send til redigeringsprogram +MAIN_FRAME_BATCHQUEUE;Batch Queue +MAIN_FRAME_FILEBROWSER;File Browser +MAIN_FRAME_PLACES;Places +MAIN_FRAME_PLACES_ADD;Add +MAIN_FRAME_PLACES_DEL;Del +MAIN_FRAME_RECENT;Recent Folders +MAIN_MSG_ALREADYEXISTS;Filen eksisterer allerede. +MAIN_MSG_CANNOTLOAD;Kan ikke indlæse billede +MAIN_MSG_CANNOTSAVE;Kan ikke gemme filen +MAIN_MSG_CANNOTSTARTEDITOR;Kan ikke starte redigeringsprogram. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Brug venligst den korrekte sti i dialogboksen "Indstillinger". +MAIN_MSG_QOVERWRITE;Vil du overskrive? +MAIN_TAB_COLOR;Farver +MAIN_TAB_DETAIL;Detaljer +MAIN_TAB_DEVELOP;Develop +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;Eksponering +MAIN_TAB_FILTER;Filter +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadata +MAIN_TAB_TRANSFORM;Justér +MAIN_TOOLTIP_HIDEHP;Vis/skjul panelet til venstre (heriblandt Historie, genvejstast: H) +MAIN_TOOLTIP_INDCLIPPEDH;Markér udbrændte højlys +MAIN_TOOLTIP_INDCLIPPEDS;Markér udbrændte skygger +MAIN_TOOLTIP_QINFO;Udvalgte oplysninger om billedet +PARTIALPASTE_BASICGROUP;Grundlæggende indstillinger +PARTIALPASTE_CACORRECTION;Kromatisk aberration +PARTIALPASTE_COARSETRANS;Drej/vend 90 grader +PARTIALPASTE_COLORGROUP;Farverelaterede indstillinger +PARTIALPASTE_COMPOSITIONGROUP;Kompositionsindstillinger +PARTIALPASTE_CROP;Beskær +PARTIALPASTE_DIALOGLABEL;Delvist indsætte bearbejdningsprofil +PARTIALPASTE_DISTORTION;Fortegning +PARTIALPASTE_EXIFCHANGES;Ændringer til exif-data +PARTIALPASTE_EXPOSURE;Eksponering +PARTIALPASTE_ICMSETTINGS;ICM-indstillinger +PARTIALPASTE_IPTCINFO;IPTC-info +PARTIALPASTE_LENSGROUP;Objektivrelaterede indstillinger +PARTIALPASTE_METAGROUP;Metadata +PARTIALPASTE_RESIZE;Ret størrelse +PARTIALPASTE_ROTATION;Rotér +PARTIALPASTE_SHADOWSHIGHLIGHTS;Skygger/Højlys +PARTIALPASTE_SHARPENING;Skarphed +PARTIALPASTE_VIGNETTING;Vignettering +PARTIALPASTE_WHITEBALANCE;Hvidbalance +PREFERENCES_APPLNEXTSTARTUP;Anvendes ved næste opstart +PREFERENCES_CACHECLEARALL;Ryd alt +PREFERENCES_CACHECLEARPROFILES;Ryd profiler +PREFERENCES_CACHECLEARTHUMBS;Ryd miniaturer +PREFERENCES_CACHEMAXENTRIES;Maksimalt antal indskrivninger i cache +PREFERENCES_CACHEOPTS;Cache-indstillinger +PREFERENCES_CACHETHUMBHEIGHT;Maksimal miniaturehøjde +PREFERENCES_CLIPPINGIND;Indikator for udbrændte områder +PREFERENCES_CMETRICINTENT;Colorimetrisk fortsæt +PREFERENCES_DATEFORMATHINT;Du kan bruge følgende formatindstillinger:\n%y : år\n%m : måned\n%d : dag\n\nDet typiske datoformat i danmark er:\n%d/%m/%y +PREFERENCES_DATEFORMAT;Datoformat +PREFERENCES_DEFAULTLANG;Sprog +PREFERENCES_DEFAULTTHEME;Tema +PREFERENCES_DIRHOME;Standardmappe +PREFERENCES_DIRLAST;Sidst anvendte mappe +PREFERENCES_DIROTHER;Andet +PREFERENCES_DIRSELECTDLG;Vælg startmappe... +PREFERENCES_DIRSOFTWARE;Installationsmappe +PREFERENCES_EDITORCMDLINE;Anden kommandostreng +PREFERENCES_EXTERNALEDITOR;Eksternt redigeringsprogram +PREFERENCES_FBROWSEROPTS;Indstllinger til filbrowser +PREFERENCES_FILEFORMAT;Filformat +PREFERENCES_FORIMAGE;Til billedfiler +PREFERENCES_FORRAW;Til RAW-filer +PREFERENCES_GIMPPATH;Installationsmappe til GIMP +PREFERENCES_HLTHRESHOLD;Tærskel for udbrændte højlys +PREFERENCES_ICCDIR;Mappe med ICC-profiler +PREFERENCES_IMPROCPARAMS;Normale billedbehandlingsparametre +PREFERENCES_INTENT_ABSOLUTE;Absolut Colorimetrisk +PREFERENCES_INTENT_PERCEPTUAL;Opfattelsesorienteret +PREFERENCES_INTENT_RELATIVE;Relativ Colorimetrisk +PREFERENCES_INTENT_SATURATION;Mætning +PREFERENCES_MONITORICC;Skærmprofil +PREFERENCES_OUTDIRFOLDERHINT;Læg det gemte billede i den valgte mappe +PREFERENCES_OUTDIRFOLDER;Gem i mappe +PREFERENCES_OUTDIRTEMPLATEHINT;Du kan benytte følgende formatstrenge:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nDisse formatstrenge henviser til mapperne og undermapperne for RAW-filens sti.\n\nFx, hvis filen /Users\Peter\Pictures/02-09-2006/dsc0012.nefer blevet åbnet, er betydningen af formatstrengen:\n%f=dsc0012, %d1=02-09-2006, %d2=image, ...\n%p1=/Users\Peter\Pictures/02-09-2006, %p2=/Users\Peter\Pictures, p3=/Users\Peter\Pictures, ...\n\nhvis du vil gemme output-billedet i samme mappe som originalen, skal du skrive:\n%p1/%f\n\nHvis du vil gemme output-billedet i en mappe, der hedder 'konverteret', som er placeret i originalens mappe, skal du skrive:\n%p1/konverteret/%f\n\nHvis du vil gemme output-billedet i mappen Users\Peter\Pictures\konverteret og beholde den samme undermappe med dato, skal du skrive:\n%p2/konverteret/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Brug skabelon +PREFERENCES_OUTDIR;Output-mappe +PREFERENCES_PARSEDEXTADDHINT;Indtast en filendelse, og klik her for at tilføje til listen +PREFERENCES_PARSEDEXTADD;Tilføj filtype +PREFERENCES_PARSEDEXTDELHINT;Slet valgte filtype fra listen +PREFERENCES_PARSEDEXT;Indlæste filtyper +PREFERENCES_PROFILEHANDLING;Bearbejder profilbehandling +PREFERENCES_PROFILELOADPR;Profilindlæsningsrækkefølge +PREFERENCES_PROFILEPRCACHE;Profil i cache +PREFERENCES_PROFILEPRFILE;Profil sammen med input-filen +PREFERENCES_PROFILESAVECACHE;Gem bearbejdningsparametre i cache +PREFERENCES_PROFILESAVEINPUT;Gem bearbejdningsparametre sammen med input-filen +PREFERENCES_PSPATH;Installationsmappe til Adobe Photoshop +PREFERENCES_SELECTLANG;Vælg sprog +PREFERENCES_SELECTTHEME;Vælg tema +PREFERENCES_SHOWBASICEXIF;Vis grundlæggende exif-data +PREFERENCES_SHOWDATETIME;Vis dato og tid +PREFERENCES_SHTHRESHOLD;Tærskel for udbrændte skygger +PREFERENCES_STARTUPIMDIR;Billedmappe ved opstart +PREFERENCES_TAB_BROWSER;Filbrowser +PREFERENCES_TAB_COLORMGR;Farvestyring +PREFERENCES_TAB_GENERAL;Generelt +PREFERENCES_TAB_IMPROC;Billedbehandling +PROFILEPANEL_LABEL;Efterbehandlingsprofiler +PROFILEPANEL_LOADDLGLABEL;Indlæs efterbehandlingsparametre... +PROFILEPANEL_PCUSTOM;Brugervalgt +PROFILEPANEL_PFILE;Fra fil +PROFILEPANEL_PLASTSAVED;Senest gemte +PROFILEPANEL_SAVEDLGLABEL;Gem efterbehandlingsparametre... +PROFILEPANEL_TOOLTIPCOPY;Kopier nuværende profil til udklipsholder +PROFILEPANEL_TOOLTIPLOAD;Indlæs en profil fra fil +PROFILEPANEL_TOOLTIPPASTE; Indsæt profil fra udklipsholder +PROFILEPANEL_TOOLTIPSAVE;Gem nuværende profil +PROGRESSBAR_LOADING;Indlæser billede... +PROGRESSBAR_LOADJPEG;Indlæser JPEG-fil... +PROGRESSBAR_LOADPNG;Indlæser PNG-fil... +PROGRESSBAR_LOADTIFF;Indlæser TIFF-fil... +PROGRESSBAR_PROCESSING;bearbejder billede... +PROGRESSBAR_READY;Klar +PROGRESSBAR_SAVEJPEG;Gemmer JPEG-fil... +PROGRESSBAR_SAVEPNG;Gemmer PNG-fil... +PROGRESSBAR_SAVETIFF;Gemmer TIFF-fil... +QINFO_ISO;ISO +QINFO_NOEXIF;Exif-data ikke tilgængelig. +SAVEDLG_FILEFORMAT;Filformat +SAVEDLG_JPEGQUAL;JPEG-kvalitet +SAVEDLG_PNGCOMPR;PNG-komprimering +SAVEDLG_PUTTOQUEUEHEAD;Sæt i begyndelsen af bearbejdningskøen +SAVEDLG_PUTTOQUEUETAIL;Sæt i enden af bearbejdningskøen +SAVEDLG_PUTTOQUEUE;Sæt i bearbejdningskø +SAVEDLG_SAVEIMMEDIATELY;Gem med det samme +SAVEDLG_SAVESPP;Gem bearbejdningsparametre med billede +TOOLBAR_TOOLTIP_CROP;Beskær markering (Genvejstast: C) +TOOLBAR_TOOLTIP_HAND;Håndværktøj (Genvejstast: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;Ret op (Genvejstast: S) +TOOLBAR_TOOLTIP_WB;Vælg hvidbalance (Genvejstast: W) +TP_CACORRECTION_BLUE;Blå +TP_CACORRECTION_LABEL;Kromatisk aberration +TP_CACORRECTION_RED;Rød +TP_CHMIXER_BLUE;Blå +TP_CHMIXER_GREEN;Grøn +TP_CHMIXER_LABEL;Kanalmixer +TP_CHMIXER_RED;Rød +TP_COARSETRAF_TOOLTIP_HFLIP;Vend vandret +TP_COARSETRAF_TOOLTIP_ROTLEFT;Rotér mod uret +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Rotér med uret +TP_COARSETRAF_TOOLTIP_VFLIP;Vend lodret +TP_CROP_FIXRATIO;Fasthold sideforhold: +TP_CROP_GTDIAGONALS;Reglen om diagonaler +TP_CROP_GTNONE;Ingen +TP_CROP_GTRULETHIRDS;Reglen om tredjedele +TP_CROP_GUIDETYPE;Hjælpelinjer: +TP_CROP_H;H +TP_CROP_LABEL;Beskær +TP_CROP_SELECTCROP; Vælg beskæring +TP_CROP_W;B +TP_CROP_X;x +TP_CROP_Y;y +TP_DISTORTION_AMOUNT;Mængde +TP_DISTORTION_LABEL;Fortegning +TP_EXPOSURE_AUTOLEVELS;Auto-niveauer +TP_EXPOSURE_BLACKLEVEL;Sort +TP_EXPOSURE_BRIGHTNESS;Lysstyrke +TP_EXPOSURE_CLIP;Klip +TP_EXPOSURE_COMPRHIGHLIGHTS;Komprimering af højlys +TP_EXPOSURE_COMPRSHADOWS;Komprimering af skygger +TP_EXPOSURE_CONTRAST;Kontrast +TP_EXPOSURE_CURVEEDITOR;Tonekurve +TP_EXPOSURE_EXPCOMP;Eksp. komp. +TP_EXPOSURE_LABEL;Eksponering +TP_HLREC_CIELAB;CIELab blanding +TP_HLREC_COLOR;Farveudbredelse +TP_HLREC_LABEL;Red højlys +TP_HLREC_LUMINANCE;Red lysforhold +TP_HLREC_METHOD;Metode: +TP_ICM_INPUTCAMERA;Kamerastandard +TP_ICM_INPUTCUSTOM;Brugervalgt +TP_ICM_INPUTDLGLABEL;Vælg input ICC-profil... +TP_ICM_INPUTEMBEDDED;Brug indlejrede, hvis muligt +TP_ICM_INPUTPROFILE;Input profil +TP_ICM_LABEL;ICM +TP_ICM_NOICM;No ICM: sRGB output +TP_ICM_OUTPUTPROFILE;Output profil +TP_ICM_SAVEREFERENCE;Gem referencebillede til profilering +TP_ICM_WORKINGPROFILE;Arbejdsprofil +TP_RAW_DMETHOD;Metode +TP_RAW_FALSECOLOR;Antal trin til undertrykkelse af forkert farve +TP_RESIZE_H;H: +TP_RESIZE_LABEL;Skift størrelse +TP_RESIZE_METHOD;Metode: +TP_RESIZE_NEAREST;Nærmeste +TP_RESIZE_SCALE;Skalér +TP_RESIZE_W;B: +TP_ROTATE_DEGREE;Grader +TP_ROTATE_LABEL;Rotér +TP_ROTATE_SELECTLINE;Vælg lige linie +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Højlys +TP_SHADOWSHLIGHTS_HLTONALW;Toneomfang +TP_SHADOWSHLIGHTS_LABEL;Skygger/højlys +TP_SHADOWSHLIGHTS_LOCALCONTR;Local kontrast +TP_SHADOWSHLIGHTS_RADIUS;Radius +TP_SHADOWSHLIGHTS_SHADOWS;Skygger +TP_SHADOWSHLIGHTS_SHTONALW;Toneomfang +TP_SHARPENING_AMOUNT;Mængde +TP_SHARPENING_EDRADIUS;Radius +TP_SHARPENING_EDTOLERANCE;Kanttolerance +TP_SHARPENING_HALOCONTROL;Halo-kontrol +TP_SHARPENING_HCAMOUNT;Mængde +TP_SHARPENING_LABEL;Skarphed +TP_SHARPENING_METHOD;Metode +TP_SHARPENING_ONLYEDGES;Gør kun kanter skarpere +TP_SHARPENING_RADIUS;Radius +TP_SHARPENING_RLD;RL Udfoldning +TP_SHARPENING_RLD_AMOUNT;Mængde +TP_SHARPENING_RLD_DAMPING;Dæmpning +TP_SHARPENING_RLD_ITERATIONS;Gentagelser +TP_SHARPENING_THRESHOLD;Tærskel +TP_SHARPENING_USM;Uskarp maske +TP_VIGNETTING_AMOUNT;Mængde +TP_VIGNETTING_LABEL;Vignettering +TP_VIGNETTING_RADIUS;Radius +TP_WBALANCE_AUTO;Auto +TP_WBALANCE_CAMERA;Kamera +TP_WBALANCE_CUSTOM;Brugervalgt +TP_WBALANCE_GREEN;Nuance +TP_WBALANCE_LABEL;Hvidbalance +TP_WBALANCE_METHOD;Metode +TP_WBALANCE_SIZE;Størrelse: +TP_WBALANCE_SPOTWB;Mål WB +TP_WBALANCE_TEMPERATURE;Temperatur +ADJUSTER_RESET_TO_DEFAULT;Nulstil til standard + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!ABOUT_TAB_BUILD;Version +!ABOUT_TAB_CREDITS;Credits +!ABOUT_TAB_LICENSE;License +!ABOUT_TAB_RELEASENOTES;Release Notes +!ABOUT_TAB_SPLASH;Splash +!BATCHQUEUE_AUTOSTART;Auto-start +!BATCHQUEUE_DESTFILENAME;Path and file name +!BATCH_PROCESSING;Batch Processing +!CURVEEDITOR_AXIS_IN;I: +!CURVEEDITOR_AXIS_LEFT_TAN;LT: +!CURVEEDITOR_AXIS_OUT;O: +!CURVEEDITOR_AXIS_RIGHT_TAN;RT: +!CURVEEDITOR_CURVES;Curves +!CURVEEDITOR_CURVE;Curve +!CURVEEDITOR_CUSTOM;Custom +!CURVEEDITOR_DARKS;Darks +!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_HIGHLIGHTS;Highlights +!CURVEEDITOR_LIGHTS;Lights +!CURVEEDITOR_MINMAXCPOINTS;Equalizer +!CURVEEDITOR_NURBS;Control cage +!CURVEEDITOR_PARAMETRIC;Parametric +!CURVEEDITOR_SHADOWS;Shadows +!CURVEEDITOR_TOOLTIPCOPY;Copy current curve to clipboard. +!CURVEEDITOR_TOOLTIPPASTE;Paste curve from clipboard. +!CURVEEDITOR_TYPE;Type: +!EDITWINDOW_TITLE;Image Edit +!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_FILETYPE;File type +!EXIFFILTER_METADATAFILTER;Enable metadata filters +!EXPORT_BYPASS_ALL;Select / Unselect All +!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_FF;Bypass [raw] Flat-Field +!EXPORT_BYPASS_RAW_GREENTHRESH;Bypass [raw] Green Equilibration +!EXPORT_BYPASS_RAW_LINENOISE;Bypass [raw] Line Noise Filter +!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_FASTEXPORTOPTIONS;Fast Export Options +!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_MAXHEIGHT;Maximum height: +!EXPORT_MAXWIDTH;Maximum width: +!EXPORT_PUTTOQUEUEFAST; Put to queue for fast export +!EXPORT_RAW_DMETHOD;Demosaic method +!EXTPROGTARGET_1;raw +!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_CACHECLEARFROMFULL;Clear from cache - full +!FILEBROWSER_CACHECLEARFROMPARTIAL;Clear from cache - partial +!FILEBROWSER_CACHE;Cache +!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_CURRENT_NAME;Current name: +!FILEBROWSER_DARKFRAME;Dark-frame +!FILEBROWSER_DELETEDLGMSGINCLPROC;Are you sure you want to delete the selected %1 files including a queue-processed version? +!FILEBROWSER_EXEC_CPB;Custom Profile Builder +!FILEBROWSER_EXTPROGMENU;Open with +!FILEBROWSER_FLATFIELD;Flat-Field +!FILEBROWSER_MOVETODARKFDIR;Move to dark-frames directory +!FILEBROWSER_MOVETOFLATFIELDDIR;Move to flat-fields directory +!FILEBROWSER_NEW_NAME;New name: +!FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) +!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_POPUPCOLORLABEL;Color label +!FILEBROWSER_POPUPCOPYTO;Copy to... +!FILEBROWSER_POPUPFILEOPERATIONS;File operations +!FILEBROWSER_POPUPMOVETO;Move to... +!FILEBROWSER_POPUPPROCESSFAST;Put to queue (Fast export) +!FILEBROWSER_POPUPPROFILEOPERATIONS;Processing profile operations +!FILEBROWSER_POPUPRANK0;Unrank +!FILEBROWSER_POPUPRANK1;Rank 1 * +!FILEBROWSER_POPUPRANK2;Rank 2 ** +!FILEBROWSER_POPUPRANK3;Rank 3 *** +!FILEBROWSER_POPUPRANK4;Rank 4 **** +!FILEBROWSER_POPUPRANK5;Rank 5 ***** +!FILEBROWSER_POPUPRANK;Rank +!FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!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_QUERYLABEL; Find: +!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_SELECTDARKFRAME;Select dark-frame... +!FILEBROWSER_SELECTFLATFIELD;Select flat-field... +!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 +!FILEBROWSER_SHOWCOLORLABEL4HINT;Show images labeled Blue.\nShortcut: Alt-4 +!FILEBROWSER_SHOWCOLORLABEL5HINT;Show images labeled Purple.\nShortcut: Alt-5 +!FILEBROWSER_SHOWEDITEDHINT;Show edited images.\nShortcut: 7 +!FILEBROWSER_SHOWEDITEDNOTHINT;Show not edited images.\nShortcut: 6 +!FILEBROWSER_SHOWEXIFINFO;Show Exif info.\n\nShortcuts:\ni - Multiple Editor Tabs Mode,\nAlt-i - Single Editor Tab Mode. +!FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!FILEBROWSER_SHOWRECENTLYSAVEDHINT;Show saved images.\nShortcut: Alt-7 +!FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show unsaved images.\nShortcut: Alt-6 +!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_AFTER;After +!GENERAL_ASIMAGE;As Image +!GENERAL_AUTO;Automatic +!GENERAL_BEFORE;Before +!GENERAL_CLOSE;Close +!GENERAL_FILE;File +!GENERAL_NONE;None +!GENERAL_UNCHANGED;(Unchanged) +!GENERAL_WARNING;Warning +!HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar.\nRight-click on image preview to freeze/unfreeze. +!HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram. +!HISTOGRAM_TOOLTIP_FULL;Toggle full (off) or scaled (on) histogram. +!HISTOGRAM_TOOLTIP_RAW;Show/Hide raw histogram. +!HISTORY_MSG_82;Profile changed +!HISTORY_MSG_83;S/H - Sharp mask +!HISTORY_MSG_84;Perspective correction +!HISTORY_MSG_85;LCP +!HISTORY_MSG_86;RGB curves - Luminosity mode +!HISTORY_MSG_87;Impulse noise reduction +!HISTORY_MSG_88;Impulse NR threshold +!HISTORY_MSG_89;Noise Reduction +!HISTORY_MSG_90;NR - Luminance +!HISTORY_MSG_91;NR - Chrominance master +!HISTORY_MSG_92;NR - Gamma +!HISTORY_MSG_93;CbDL - Value +!HISTORY_MSG_94;Contrast by Detail Levels +!HISTORY_MSG_95;L*a*b* - Chromaticity +!HISTORY_MSG_96;L*a*b* - a* curve +!HISTORY_MSG_97;L*a*b* - b* curve +!HISTORY_MSG_98;Demosaicing method +!HISTORY_MSG_99;Hot pixel filter +!HISTORY_MSG_100;RGB Saturation +!HISTORY_MSG_101;HSV - Hue +!HISTORY_MSG_102;HSV - Saturation +!HISTORY_MSG_103;HSV - Value +!HISTORY_MSG_104;HSV Equalizer +!HISTORY_MSG_105;Defringe +!HISTORY_MSG_106;Defringe - Radius +!HISTORY_MSG_107;Defringe - Threshold +!HISTORY_MSG_108;Highlight Compr. Threshold +!HISTORY_MSG_109;Resize - Bounding box +!HISTORY_MSG_110;Resize - Applies to +!HISTORY_MSG_111;L*a*b* - Avoid color shift +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;L*a*b* - Red/skin prot. +!HISTORY_MSG_114;DCB iterations +!HISTORY_MSG_115;False color suppression +!HISTORY_MSG_116;DCB enhancement +!HISTORY_MSG_117;Raw CA correction - Red +!HISTORY_MSG_118;Raw CA correction - Blue +!HISTORY_MSG_119;Line noise filter +!HISTORY_MSG_120;Green equilibration +!HISTORY_MSG_121;Raw CA Correction - Auto +!HISTORY_MSG_122;Dark-Frame - Auto-selection +!HISTORY_MSG_123;Dark-Frame - File +!HISTORY_MSG_124;White point correction +!HISTORY_MSG_125;Highlight preservation +!HISTORY_MSG_126;Flat-Field - File +!HISTORY_MSG_127;Flat-Field - Auto-selection +!HISTORY_MSG_128;Flat-Field - Blur radius +!HISTORY_MSG_129;Flat-Field - Blur type +!HISTORY_MSG_130;Auto distorion correction +!HISTORY_MSG_131;NR - Luma +!HISTORY_MSG_132;NR - Chroma +!HISTORY_MSG_133;Output gamma +!HISTORY_MSG_134;Free gamma +!HISTORY_MSG_135;Free gamma +!HISTORY_MSG_136;Free gamma slope +!HISTORY_MSG_137;Black level - Green 1 +!HISTORY_MSG_138;Black level - Red +!HISTORY_MSG_139;Black level - Blue +!HISTORY_MSG_140;Black level - Green 2 +!HISTORY_MSG_141;Black level - Link greens +!HISTORY_MSG_142;ES - Iterations +!HISTORY_MSG_143;ES - Quantity +!HISTORY_MSG_144;Microcontrast - Quantity +!HISTORY_MSG_145;Microcontrast - Uniformity +!HISTORY_MSG_146;Edge sharpening +!HISTORY_MSG_147;ES - Luminance only +!HISTORY_MSG_148;Microcontrast +!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_150;Post-demosaic artifact/noise red. +!HISTORY_MSG_151;Vibrance +!HISTORY_MSG_152;Vib - Pastel tones +!HISTORY_MSG_153;Vib - Saturated tones +!HISTORY_MSG_154;Vib - Protect skin-tones +!HISTORY_MSG_155;Vib - Avoid color shift +!HISTORY_MSG_156;Vib - Link pastel/saturated +!HISTORY_MSG_157;Vib - P/S threshold +!HISTORY_MSG_158;TM - Strength +!HISTORY_MSG_159;TM - Edge stopping +!HISTORY_MSG_160;TM - Scale +!HISTORY_MSG_161;TM - Reweighting iterates +!HISTORY_MSG_162;Tone Mapping +!HISTORY_MSG_163;RGB curves - Red +!HISTORY_MSG_164;RGB curves - Green +!HISTORY_MSG_165;RGB curves - Blue +!HISTORY_MSG_166;Neutral levels +!HISTORY_MSG_167;--unused-- +!HISTORY_MSG_168;L*a*b* - CC curve +!HISTORY_MSG_169;L*a*b* - CH curve +!HISTORY_MSG_170;Vibrance - HH curve +!HISTORY_MSG_171;L*a*b* - LC curve +!HISTORY_MSG_172;L*a*b* - Restrict LC +!HISTORY_MSG_173;NR - Luminance detail +!HISTORY_MSG_174;CIECAM02 +!HISTORY_MSG_175;CAM02 - CAT02 adaptation +!HISTORY_MSG_176;CAM02 - Viewing surround +!HISTORY_MSG_177;CAM02 - Scene luminosity +!HISTORY_MSG_178;CAM02 - Viewing luminosity +!HISTORY_MSG_179;CAM02 - White-point model +!HISTORY_MSG_180;CAM02 - Lightness (J) +!HISTORY_MSG_181;CAM02 - Chroma (C) +!HISTORY_MSG_182;CAM02 - Automatic CAT02 +!HISTORY_MSG_183;CAM02 - Contrast (J) +!HISTORY_MSG_184;CAM02 - Scene surround +!HISTORY_MSG_185;CAM02 - Gamut control +!HISTORY_MSG_186;CAM02 - Algorithm +!HISTORY_MSG_187;CAM02 - Red/skin prot. +!HISTORY_MSG_188;CAM02 - Brightness (Q) +!HISTORY_MSG_189;CAM02 - Contrast (Q) +!HISTORY_MSG_190;CAM02 - Saturation (S) +!HISTORY_MSG_191;CAM02 - Colorfulness (M) +!HISTORY_MSG_192;CAM02 - Hue (h) +!HISTORY_MSG_193;CAM02 - Tone curve 1 +!HISTORY_MSG_194;CAM02 - Tone curve 2 +!HISTORY_MSG_195;CAM02 - Tone curve 1 +!HISTORY_MSG_196;CAM02 - Tone curve 2 +!HISTORY_MSG_197;CAM02 - Color curve +!HISTORY_MSG_198;CAM02 - Color curve +!HISTORY_MSG_199;CAM02 - Output histograms +!HISTORY_MSG_200;CAM02 - Tone mapping +!HISTORY_MSG_201;NR - Chrominance - R&G +!HISTORY_MSG_202;NR - Chrominance - B&Y +!HISTORY_MSG_203;NR - Method +!HISTORY_MSG_204;LMMSE enhancement steps +!HISTORY_MSG_205;CAM02 - Hot/bad pixel filter +!HISTORY_MSG_206;CAT02 - Auto scene luminosity +!HISTORY_MSG_207;Defringe - Hue curve +!HISTORY_MSG_208;WB - B/R equalizer +!HISTORY_MSG_210;GF - Angle +!HISTORY_MSG_211;Graduated Filter +!HISTORY_MSG_212;VF - Strength +!HISTORY_MSG_213;Vignette Filter +!HISTORY_MSG_214;Black-and-White +!HISTORY_MSG_215;B&W - CM - Red +!HISTORY_MSG_216;B&W - CM - Green +!HISTORY_MSG_217;B&W - CM - Blue +!HISTORY_MSG_218;B&W - Gamma - Red +!HISTORY_MSG_219;B&W - Gamma - Green +!HISTORY_MSG_220;B&W - Gamma - Blue +!HISTORY_MSG_221;B&W - Color filter +!HISTORY_MSG_222;B&W - Presets +!HISTORY_MSG_223;B&W - CM - Orange +!HISTORY_MSG_224;B&W - CM - Yellow +!HISTORY_MSG_225;B&W - CM - Cyan +!HISTORY_MSG_226;B&W - CM - Magenta +!HISTORY_MSG_227;B&W - CM - Purple +!HISTORY_MSG_228;B&W - Luminance equalizer +!HISTORY_MSG_229;B&W - Luminance equalizer +!HISTORY_MSG_230;B&W - Mode +!HISTORY_MSG_231;B&W - 'Before' curve +!HISTORY_MSG_232;B&W - 'Before' curve type +!HISTORY_MSG_233;B&W - 'After' curve +!HISTORY_MSG_234;B&W - 'After' curve type +!HISTORY_MSG_235;B&W - Auto channel mixer +!HISTORY_MSG_236;--unused-- +!HISTORY_MSG_237;B&W - Mixer +!HISTORY_MSG_238;GF - Feather +!HISTORY_MSG_239;GF - Strength +!HISTORY_MSG_240;GF - Center +!HISTORY_MSG_241;VF - Feather +!HISTORY_MSG_242;VF - Roundness +!HISTORY_MSG_243;VC - Radius +!HISTORY_MSG_244;VC - Strength +!HISTORY_MSG_245;VC - Center +!HISTORY_MSG_246;L*a*b* - CL curve +!HISTORY_MSG_247;L*a*b* - LH curve +!HISTORY_MSG_248;L*a*b* - HH curve +!HISTORY_MSG_249;CbDL - Threshold +!HISTORY_MSG_250;NR - Enhanced +!HISTORY_MSG_251;B&W - Algorithm +!HISTORY_MSG_252;CbDL - Skin tar/prot +!HISTORY_MSG_253;CbDL - Reduce artifacts +!HISTORY_MSG_254;CbDL - Skin hue +!HISTORY_MSG_255;NR - Median filter +!HISTORY_MSG_256;NR - Median type +!HISTORY_MSG_257;Color Toning +!HISTORY_MSG_258;CT - Color curve +!HISTORY_MSG_259;CT - Opacity curve +!HISTORY_MSG_260;CT - a*[b*] opacity +!HISTORY_MSG_261;CT - Method +!HISTORY_MSG_262;CT - b* opacity +!HISTORY_MSG_263;CT - Shadows - Red +!HISTORY_MSG_264;CT - Shadows - Green +!HISTORY_MSG_265;CT - Shadows - Blue +!HISTORY_MSG_266;CT - Mid - Red +!HISTORY_MSG_267;CT - Mid - Green +!HISTORY_MSG_268;CT - Mid - Blue +!HISTORY_MSG_269;CT - High - Red +!HISTORY_MSG_270;CT - High - Green +!HISTORY_MSG_271;CT - High - Blue +!HISTORY_MSG_272;CT - Balance +!HISTORY_MSG_273;CT - Reset +!HISTORY_MSG_274;CT - Sat. Shadows +!HISTORY_MSG_275;CT - Sat. Highlights +!HISTORY_MSG_276;CT - Opacity +!HISTORY_MSG_277;--unused-- +!HISTORY_MSG_278;CT - Preserve luminance +!HISTORY_MSG_279;CT - Shadows +!HISTORY_MSG_280;CT - Highlights +!HISTORY_MSG_281;CT - Sat. strength +!HISTORY_MSG_282;CT - Sat. threshold +!HISTORY_MSG_283;CT - Strength +!HISTORY_MSG_284;CT - Auto sat. protection +!HISTORY_MSG_285;NR - Median - Method +!HISTORY_MSG_286;NR - Median - Type +!HISTORY_MSG_287;NR - Median - Iterations +!HISTORY_MSG_288;Flat Field - Clip control +!HISTORY_MSG_289;Flat Field - Clip control - Auto +!HISTORY_MSG_290;Black Level - Red +!HISTORY_MSG_291;Black Level - Green +!HISTORY_MSG_292;Black Level - Blue +!HISTORY_MSG_293;Film Simulation +!HISTORY_MSG_294;Film Simulation - Strength +!HISTORY_MSG_295;Film Simulation - Film +!HISTORY_MSG_296;NR - Luminance curve +!HISTORY_MSG_297;NR - Quality +!HISTORY_MSG_298;Dead pixel filter +!HISTORY_MSG_299;NR - Chrominance curve +!HISTORY_MSG_300;- +!HISTORY_MSG_301;NR - Luma control +!HISTORY_MSG_302;NR - Chroma method +!HISTORY_MSG_303;NR - Chroma method +!HISTORY_MSG_304;W - Contrast levels +!HISTORY_MSG_305;Wavelet Levels +!HISTORY_MSG_306;W - Preview +!HISTORY_MSG_307;W - Preview +!HISTORY_MSG_308;W - Preview direction +!HISTORY_MSG_309;W - ES - Detail +!HISTORY_MSG_310;W - Residual - Sky tar/prot +!HISTORY_MSG_311;W - Wavelet levels +!HISTORY_MSG_312;W - Residual - Shadows threshold +!HISTORY_MSG_313;W - Chroma - Sat/past +!HISTORY_MSG_314;W - Gamut - Reduce artifacts +!HISTORY_MSG_315;W - Residual - Contrast +!HISTORY_MSG_316;W - Gamut - Skin tar/prot +!HISTORY_MSG_317;W - Gamut - Skin hue +!HISTORY_MSG_318;W - Contrast - Highlight levels +!HISTORY_MSG_319;W - Contrast - Highlight range +!HISTORY_MSG_320;W - Contrast - Shadow range +!HISTORY_MSG_321;W - Contrast - Shadow levels +!HISTORY_MSG_322;W - Gamut - Avoid color shift +!HISTORY_MSG_323;W - ES - Local contrast +!HISTORY_MSG_324;W - Chroma - Pastel +!HISTORY_MSG_325;W - Chroma - Saturated +!HISTORY_MSG_326;W - Chroma - Method +!HISTORY_MSG_327;W - Contrast - Apply to +!HISTORY_MSG_328;W - Chroma - Link strength +!HISTORY_MSG_329;W - Toning - Opacity RG +!HISTORY_MSG_330;W - Toning - Opacity BY +!HISTORY_MSG_331;W - Contrast levels - Extra +!HISTORY_MSG_332;W - Tiling method +!HISTORY_MSG_333;W - Residual - Shadows +!HISTORY_MSG_334;W - Residual - Chroma +!HISTORY_MSG_335;W - Residual - Highlights +!HISTORY_MSG_336;W - Residual - Highlights threshold +!HISTORY_MSG_337;W - Residual - Sky hue +!HISTORY_MSG_338;W - ES - Radius +!HISTORY_MSG_339;W - ES - Strength +!HISTORY_MSG_340;W - Strength +!HISTORY_MSG_341;W - Edge performance +!HISTORY_MSG_342;W - ES - First level +!HISTORY_MSG_343;W - Chroma levels +!HISTORY_MSG_344;W - Meth chroma sl/cur +!HISTORY_MSG_345;W - ES - Local contrast +!HISTORY_MSG_346;W - ES - Local contrast method +!HISTORY_MSG_347;W - Denoise - Level 0 +!HISTORY_MSG_348;W - Denoise - Level 1 +!HISTORY_MSG_349;W - Denoise - Level 2 +!HISTORY_MSG_350;W - ES - Edge detection +!HISTORY_MSG_351;W - Residual - HH curve +!HISTORY_MSG_352;W - Background +!HISTORY_MSG_353;W - ES - Gradient sensitivity +!HISTORY_MSG_354;W - ES - Enhance +!HISTORY_MSG_355;W - ES - Threshold low +!HISTORY_MSG_356;W - ES - Threshold high +!HISTORY_MSG_357;W - Denoise - Link with ES +!HISTORY_MSG_358;W - Gamut - CH +!HISTORY_MSG_359;Hot/Dead - Threshold +!HISTORY_MSG_360;TM Gamma +!HISTORY_MSG_361;W - Final - Chroma balance +!HISTORY_MSG_362;W - Residual - Compression method +!HISTORY_MSG_363;W - Residual - Compression strength +!HISTORY_MSG_364;W - Final - Contrast balance +!HISTORY_MSG_365;W - Final - Delta balance +!HISTORY_MSG_366;W - Residual - Compression gamma +!HISTORY_MSG_367;W - ES - Local contrast curve +!HISTORY_MSG_368;W - Final - Contrast balance +!HISTORY_MSG_369;W - Final - Balance method +!HISTORY_MSG_370;W - Final - Local contrast curve +!HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s +!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 +!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). +!MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Put current image to processing queue.\nShortcut: Ctrl+b +!MAIN_BUTTON_SAVE_TOOLTIP;Save current image.\nShortcut: Ctrl+s +!MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Edit current image in external editor.\nShortcut: Ctrl+e +!MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Show/hide all side panels.\nShortcut: m +!MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen +!MAIN_FRAME_BATCHQUEUE_TOOLTIP;Processing queue.\nShortcut: Ctrl-F3 +!MAIN_FRAME_EDITOR;Editor +!MAIN_FRAME_EDITOR_TOOLTIP;Editor.\nShortcut: Ctrl-F4 +!MAIN_FRAME_FILEBROWSER_TOOLTIP;File browser.\nShortcut: Ctrl-F2 +!MAIN_MSG_EMPTYFILENAME;Filename unspecified! +!MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue-processed first. +!MAIN_MSG_NAVIGATOR;Navigator +!MAIN_MSG_OPERATIONCANCELLED;Operation cancelled +!MAIN_MSG_PATHDOESNTEXIST;The path\n\n%1\n\ndoes not exist. Please set a correct path in Preferences. +!MAIN_MSG_SETPATHFIRST;You first have to set a target path in Preferences in order to use this function! +!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_EXPORT; Fast Export +!MAIN_TAB_EXPOSURE_TOOLTIP;Shortcut: Alt-e +!MAIN_TAB_INSPECT; Inspect +!MAIN_TAB_METADATA_TOOLTIP;Shortcut: Alt-m +!MAIN_TAB_RAW;Raw +!MAIN_TAB_RAW_TOOLTIP;Shortcut: Alt-r +!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_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%. +!MAIN_TOOLTIP_PREVIEWG;Preview the Green channel.\nShortcut: g +!MAIN_TOOLTIP_PREVIEWL;Preview the Luminosity.\nShortcut: v\n\n0.299*R + 0.587*G + 0.114*B +!MAIN_TOOLTIP_PREVIEWR;Preview the Red channel.\nShortcut: r +!MAIN_TOOLTIP_SHOWHIDELP1;Show/Hide the left panel.\nShortcut: l +!MAIN_TOOLTIP_SHOWHIDERP1;Show/Hide the right panel.\nShortcut: Alt-l +!MAIN_TOOLTIP_SHOWHIDETP1;Show/Hide the top panel.\nShortcut: Shift-l +!MAIN_TOOLTIP_THRESHOLD;Threshold +!MAIN_TOOLTIP_TOGGLE;Toggle the Before/After view.\nShortcut: Shift-b +!NAVIGATOR_B;B: +!NAVIGATOR_G;G: +!NAVIGATOR_H;H: +!NAVIGATOR_LAB_A;a*: +!NAVIGATOR_LAB_B;b*: +!NAVIGATOR_LAB_L;L*: +!NAVIGATOR_NA; -- +!NAVIGATOR_R;R: +!NAVIGATOR_S;S: +!NAVIGATOR_V;V: +!NAVIGATOR_XY_FULL;Width: %1, Height: %2 +!NAVIGATOR_XY_NA;x: --, y: -- +!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_CHANNELMIXERBW;Black-and-White +!PARTIALPASTE_CHANNELMIXER;Channel mixer +!PARTIALPASTE_COLORAPP;CIECAM02 +!PARTIALPASTE_COLORTONING;Color Toning +!PARTIALPASTE_COMMONTRANSFORMPARAMS;Auto-fill +!PARTIALPASTE_DARKFRAMEAUTOSELECT;Dark-frame auto-selection +!PARTIALPASTE_DARKFRAMEFILE;Dark-frame file +!PARTIALPASTE_DEFRINGE;Defringe +!PARTIALPASTE_DETAILGROUP;Detail Settings +!PARTIALPASTE_DIRPYRDENOISE;Noise reduction +!PARTIALPASTE_DIRPYREQUALIZER;Contrast by detail levels +!PARTIALPASTE_EPD;Tone mapping +!PARTIALPASTE_EQUALIZER;Wavelet Equalizer +!PARTIALPASTE_EVERYTHING;Everything +!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_GRADIENT;Graduated filter +!PARTIALPASTE_HSVEQUALIZER;HSV equalizer +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction +!PARTIALPASTE_LABCURVE;L*a*b* adjustments +!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_PCVIGNETTE;Vignette filter +!PARTIALPASTE_PERSPECTIVE;Perspective +!PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter +!PARTIALPASTE_PREPROCESS_GREENEQUIL;Green equilibration +!PARTIALPASTE_PREPROCESS_HOTPIXFILT;Hot pixel filter +!PARTIALPASTE_PREPROCESS_LINEDENOISE;Line noise filter +!PARTIALPASTE_RAWCACORR_AUTO;CA auto-correction +!PARTIALPASTE_RAWCACORR_CABLUE;CA blue +!PARTIALPASTE_RAWCACORR_CARED;CA red +!PARTIALPASTE_RAWEXPOS_BLACK;Black levels +!PARTIALPASTE_RAWEXPOS_LINEAR;White point correction +!PARTIALPASTE_RAWEXPOS_PRESER;Highlight preservation +!PARTIALPASTE_RAWGROUP;Raw Settings +!PARTIALPASTE_RAW_DCBENHANCE;DCB enhancement +!PARTIALPASTE_RAW_DCBITERATIONS;Number of DCB iterations +!PARTIALPASTE_RAW_DMETHOD;Demosaic method +!PARTIALPASTE_RAW_FALSECOLOR;Demosaic false color suppression steps +!PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!PARTIALPASTE_RGBCURVES;RGB curves +!PARTIALPASTE_SHARPENEDGE;Edges +!PARTIALPASTE_SHARPENMICRO;Microcontrast +!PARTIALPASTE_VIBRANCE;Vibrance +!PARTIALPASTE_WAVELETGROUP;Wavelet processing +!PREFERENCES_ADD;Add +!PREFERENCES_AUTLISLOW;Low +!PREFERENCES_AUTLISMAX;Max - Average of all tiles +!PREFERENCES_AUTLISSTD;High +!PREFERENCES_AUTLISVLOW;None +!PREFERENCES_AUTLOW;Low +!PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +!PREFERENCES_AUTSTD;Standard +!PREFERENCES_BATCH_PROCESSING;Batch Processing +!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_BEHADDALL;All to 'Add' +!PREFERENCES_BEHAVIOR;Behavior +!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_BEHSETALL;All to 'Set' +!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_CURVEBBOXPOS;Position of curve copypasta buttons +!PREFERENCES_CURVEBBOXPOS_ABOVE;Above +!PREFERENCES_CURVEBBOXPOS_BELOW;Below +!PREFERENCES_CURVEBBOXPOS_LEFT;Left +!PREFERENCES_CURVEBBOXPOS_RIGHT;Right +!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_CUSTPROFBUILD;Custom Processing Profile Builder +!PREFERENCES_CUTOVERLAYBRUSH;Crop mask color/transparency +!PREFERENCES_D50;5000K +!PREFERENCES_D55;5500K +!PREFERENCES_D60;6000K +!PREFERENCES_D65;6500K +!PREFERENCES_DARKFRAMEFOUND;Found +!PREFERENCES_DARKFRAMESHOTS;shots +!PREFERENCES_DARKFRAMETEMPLATES;templates +!PREFERENCES_DARKFRAME;Dark-Frame +!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 (de-select for low resolution display) +!PREFERENCES_FILMSIMULATION;Film Simulation +!PREFERENCES_FLATFIELDFOUND;Found +!PREFERENCES_FLATFIELDSDIR;Flat-fields directory +!PREFERENCES_FLATFIELDSHOTS;shots +!PREFERENCES_FLATFIELDTEMPLATES;templates +!PREFERENCES_FLATFIELD;Flat-Field +!PREFERENCES_FLUOF2;Fluorescent F2 +!PREFERENCES_FLUOF7;Fluorescent F7 +!PREFERENCES_FLUOF11;Fluorescent F11 +!PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT;Same thumbnail height between the Editor's panel 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_GREY05;Yb=05 CIE L#30 +!PREFERENCES_GREY10;Yb=10 CIE L#40 +!PREFERENCES_GREY15;Yb=15 CIE L#45 +!PREFERENCES_GREY18;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_GREYSC18;Yb=18 CIE L#50 +!PREFERENCES_GREYSCA;Automatic +!PREFERENCES_GREYSC;Scene Yb luminance (%) +!PREFERENCES_GREY;Output device's Yb luminance (%) +!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_LANGAUTODETECT;Use system language +!PREFERENCES_LEVAUTDN;Denoising level +!PREFERENCES_LEVDN;Cell size +!PREFERENCES_LISS;Auto multi-zone smoothing +!PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders +!PREFERENCES_MAX;Maxi (Tile) +!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_MENUGROUPRANK;Group "Rank" +!PREFERENCES_MENUOPTIONS;Context Menu Options +!PREFERENCES_METADATA;Metadata +!PREFERENCES_MIN;Mini (100x115) +!PREFERENCES_MULTITABDUALMON;Multiple Editor Tabs In Own Window Mode +!PREFERENCES_MULTITAB;Multiple Editor Tabs 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_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_PROPERTY;Property +!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 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_SINGLETABVERTAB;Single Editor Tab Mode, Vertical Tabs +!PREFERENCES_SINGLETAB;Single Editor Tab Mode +!PREFERENCES_SLIMUI;Slim interface +!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_PERFORMANCE;Performance & Quality +!PREFERENCES_TAB_SOUND;Sounds +!PREFERENCES_TIMAX;High +!PREFERENCES_TINB;Number of tiles +!PREFERENCES_TISTD;Standard +!PREFERENCES_TP_LABEL;Tool panel: +!PREFERENCES_TP_USEICONORTEXT;Use tab icons instead of text +!PREFERENCES_TP_VSCROLLBAR;Hide vertical scrollbar +!PREFERENCES_TUNNELMETADATA;Copy IPTC/XMP unchanged to output file (when tagging with other program) +!PREFERENCES_USEBUNDLEDPROFILES;Use bundled profiles +!PREFERENCES_USESYSTEMTHEME;Use system theme +!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_WORKFLOW;Layout +!PROFILEPANEL_COPYPPASTE;Parameters to copy +!PROFILEPANEL_GLOBALPROFILES;Bundled profiles +!PROFILEPANEL_LOADPPASTE;Parameters to load +!PROFILEPANEL_MODE_TIP;Processing profile fill mode.\n\nButton pressed: partial profiles will be converted to full profiles; the missing values will be replaced with hard-coded defaults.\n\nButton released: profiles will be applied as they are, altering only those values which they contain. +!PROFILEPANEL_MYPROFILES;My profiles +!PROFILEPANEL_PASTEPPASTE;Parameters to paste +!PROFILEPANEL_PINTERNAL;Neutral +!PROFILEPANEL_SAVEPPASTE;Parameters to save +!PROGRESSBAR_LOADINGTHUMBS;Loading thumbnails... +!PROGRESSBAR_NOIMAGES;No images found +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing profile saved +!PROGRESSBAR_SNAPSHOT_ADDED;Snapshot added +!PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists +!SAVEDLG_FORCEFORMATOPTS;Force saving options +!SAVEDLG_SUBSAMP;Subsampling +!SAVEDLG_SUBSAMP_1;Best compression +!SAVEDLG_SUBSAMP_2;Balanced +!SAVEDLG_SUBSAMP_3;Best quality +!SAVEDLG_SUBSAMP_TOOLTIP;Best compression: 4:1:1\nBalanced: 4:2:2\nBest quality: 4:4:4 +!SAVEDLG_TIFFUNCOMPRESSED;Uncompressed TIFF +!SAVEDLG_WARNFILENAME;File will be named +!SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. +!THRESHOLDSELECTOR_BL;Bottom-left +!THRESHOLDSELECTOR_BR;Bottom-right +!THRESHOLDSELECTOR_B;Bottom +!THRESHOLDSELECTOR_HINT;Hold the Shift key to move individual control points. +!THRESHOLDSELECTOR_TL;Top-left +!THRESHOLDSELECTOR_TR;Top-right +!THRESHOLDSELECTOR_T;Top +!TP_BWMIX_ALGO;Algorithm OYCPM +!TP_BWMIX_ALGO_LI;Linear +!TP_BWMIX_ALGO_SP;Special effects +!TP_BWMIX_ALGO_TOOLTIP;Linear: will produce a normal linear response.\nSpecial effects: will produce special effects by mixing channels non-linearly. +!TP_BWMIX_AUTOCH;Auto +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing Channel Mixer. +!TP_BWMIX_CC_ENABLED;Adjust complementary color +!TP_BWMIX_CC_TOOLTIP;Enable to allow automatic adjustment of complementary colors in ROYGCBPM mode. +!TP_BWMIX_CHANNEL;Luminance equalizer +!TP_BWMIX_CURVEEDITOR1;'Before' curve +!TP_BWMIX_CURVEEDITOR2;'After' curve +!TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Tone curve, after B&W conversion, at the end of treatment. +!TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Tone curve, just before B&W conversion.\nMay take into account the color components. +!TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H).\nPay attention to extreme values as they may cause artifacts. +!TP_BWMIX_FILTER;Color Filter +!TP_BWMIX_FILTER_BLUEGREEN;Blue-Green +!TP_BWMIX_FILTER_BLUE;Blue +!TP_BWMIX_FILTER_GREENYELLOW;Green-Yellow +!TP_BWMIX_FILTER_GREEN;Green +!TP_BWMIX_FILTER_NONE;None +!TP_BWMIX_FILTER_PURPLE;Purple +!TP_BWMIX_FILTER_REDYELLOW;Red-Yellow +!TP_BWMIX_FILTER_RED;Red +!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. +!TP_BWMIX_FILTER_YELLOW;Yellow +!TP_BWMIX_GAMMA;Gamma Correction +!TP_BWMIX_GAM_TOOLTIP;Correct gamma for each RGB channel. +!TP_BWMIX_LABEL;Black-and-White +!TP_BWMIX_MET;Method +!TP_BWMIX_MET_CHANMIX;Channel Mixer +!TP_BWMIX_MET_DESAT;Desaturation +!TP_BWMIX_MET_LUMEQUAL;Luminance Equalizer +!TP_BWMIX_MIXC;Mixer +!TP_BWMIX_NEUTRAL;Reset mixer +!TP_BWMIX_NEUTRAL_TIP;Reset all values (Color Filter, Channel Mixer) to default. +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all the mixer options.\n"Total" displays the sum of the RGB values:\n- always 100% in relative mode\n- higher (lighter) or lower (darker) than 100% in absolute mode. +!TP_BWMIX_RGB_TOOLTIP;Mix the RGB channels. Use presets for guidance.\nPay attention to negative values that may cause artifacts or erratic behavior. +!TP_BWMIX_SETTING;Presets +!TP_BWMIX_SETTING_TOOLTIP;Different presets (film, landscape, etc.) or manual Channel Mixer settings. +!TP_BWMIX_SET_HIGHCONTAST;High contrast +!TP_BWMIX_SET_HIGHSENSIT;High Sensitivity +!TP_BWMIX_SET_HYPERPANCHRO;Hyper Panchromatic +!TP_BWMIX_SET_INFRARED;Infrared +!TP_BWMIX_SET_LANDSCAPE;Landscape +!TP_BWMIX_SET_LOWSENSIT;Low Sensitivity +!TP_BWMIX_SET_LUMINANCE;Luminance +!TP_BWMIX_SET_NORMCONTAST;Normal Contrast +!TP_BWMIX_SET_ORTHOCHRO;Orthochromatic +!TP_BWMIX_SET_PANCHRO;Panchromatic +!TP_BWMIX_SET_PORTRAIT;Portrait +!TP_BWMIX_SET_RGBABS;Absolute RGB +!TP_BWMIX_SET_RGBREL;Relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Relative ROYGCBPM +!TP_BWMIX_TCMODE_FILMLIKE;B&W Film-like +!TP_BWMIX_TCMODE_SATANDVALBLENDING;B&W Saturation and Value Blending +!TP_BWMIX_TCMODE_STANDARD;B&W Standard +!TP_BWMIX_TCMODE_WEIGHTEDSTD;B&W Weighted Standard +!TP_BWMIX_VAL;L +!TP_CHROMATABERR_LABEL;Chromatic Aberration +!TP_COLORAPP_ADAPTSCENE;Scene luminosity +!TP_COLORAPP_ADAPTSCENE_TOOLTIP;Absolute luminance of the scene environement (cd/m²).\n1) Calculated from the Exif data:\nShutter speed - ISO speed - F number - camera exposure correction.\n2) Calculated from the raw white point and RT's Exposure Compensation slider. +!TP_COLORAPP_ADAPTVIEWING;Viewing luminosity (cd/m²) +!TP_COLORAPP_ADAPTVIEWING_TOOLTIP;Absolute luminance of the viewing environnement\n(usually 16cd/m²). +!TP_COLORAPP_ADAP_AUTO_TOOLTIP;If the checkbox is checked (recommended) RawTherapee calculates an optimum value from Exif data.\nTo set the value manually, uncheck the checkbox first. +!TP_COLORAPP_ALGO;Algorithm +!TP_COLORAPP_ALGO_ALL;All +!TP_COLORAPP_ALGO_JC;Lightness + Chroma (JC) +!TP_COLORAPP_ALGO_JS;Lightness + Saturation (JS) +!TP_COLORAPP_ALGO_QM;Brightness + Colorfulness (QM) +!TP_COLORAPP_ALGO_TOOLTIP;Lets you choose between parameter subsets or all parameters. +!TP_COLORAPP_BADPIXSL;Hot/bad pixel filter +!TP_COLORAPP_BADPIXSL_TOOLTIP;Suppression of hot/bad (brightly colored) pixels.\n0 = No effect\n1 = Median\n2 = Gaussian.\nAlternatively, adjust the image to avoid very dark shadows.\n\nThese artifacts are due to limitations of CIECAM02. +!TP_COLORAPP_BRIGHT;Brightness (Q) +!TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from L*a*b* and RGB brightness. +!TP_COLORAPP_CHROMA;Chroma (C) +!TP_COLORAPP_CHROMA_M;Colorfulnes (M) +!TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM02 differs from L*a*b* and RGB colorfulness. +!TP_COLORAPP_CHROMA_S;Saturation (S) +!TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from L*a*b* and RGB saturation. +!TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from L*a*b* and RGB chroma. +!TP_COLORAPP_CIECAT_DEGREE;CAT02 adaptation +!TP_COLORAPP_CONTRAST;Contrast (J) +!TP_COLORAPP_CONTRAST_Q;Contrast (Q) +!TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrast in CIECAM02 for the Q slider; it differs from L*a*b* and RGB contrast. +!TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from L*a*b* and RGB contrast. +!TP_COLORAPP_CURVEEDITOR1;Tone curve 1 +!TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L* (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of J or Q after CIECAM02.\n\nJ and Q are not shown in the main histogram panel.\n\nFor final output refer to the main histogram panel. +!TP_COLORAPP_CURVEEDITOR2;Tone curve 2 +!TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Same usage as with the second exposure tone curve. +!TP_COLORAPP_CURVEEDITOR3;Color curve +!TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Adjust either chroma, saturation or colorfulness.\n\nShows the histogram of chromaticity (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of C, s or M after CIECAM02.\n\nC, s and M are not shown in the main histogram panel.\nFor final output refer to the main histogram panel. +!TP_COLORAPP_DATACIE;CIECAM02 output histograms in curves +!TP_COLORAPP_DATACIE_TOOLTIP;When enabled, histograms in CIECAM02 curves show approximate values/ranges for J or Q, and C, s or M after the CIECAM02 adjustments.\nThis selection does not impact the main histogram panel.\n\nWhen disabled, histograms in CIECAM02 curves show L*a*b* values before CIECAM02 adjustments. +!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RawTherapee calculates an optimum value, which is then used by CAT02, and also for the entire CIECAM02.\nTo set the value manually, uncheck the check-box first (values above 65 are recommended). +!TP_COLORAPP_DEGREE_TOOLTIP;Amount of CIE Chromatic Adaptation Transform 2002. +!TP_COLORAPP_GAMUT;Gamut control (L*a*b*) +!TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in L*a*b* mode. +!TP_COLORAPP_HUE;Hue (h) +!TP_COLORAPP_HUE_TOOLTIP;Hue (h) - angle between 0° and 360°. +!TP_COLORAPP_LABEL;CIE Color Appearance Model 2002 +!TP_COLORAPP_LABEL_CAM02;Image Adjustments +!TP_COLORAPP_LABEL_SCENE;Scene Conditions +!TP_COLORAPP_LABEL_VIEWING;Viewing Conditions +!TP_COLORAPP_LIGHT;Lightness (J) +!TP_COLORAPP_LIGHT_TOOLTIP;Lightness in CIECAM02 differs from L*a*b* and RGB lightness. +!TP_COLORAPP_MODEL;WP Model +!TP_COLORAPP_MODEL_TOOLTIP;White-Point Model.\n\nWB [RT] + [output]: RT's white balance is used for the scene, CIECAM02 is set to D50, and the output device's white balance is set in Preferences > Color Management.\n\nWB [RT+CAT02] + [output]: RT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences - Color Management. +!TP_COLORAPP_RSTPRO;Red & skin-tones protection +!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin-tones protection affects both sliders and curves. +!TP_COLORAPP_SHARPCIE;--unused-- +!TP_COLORAPP_SHARPCIE_TOOLTIP;--unused-- +!TP_COLORAPP_SURROUND;Surround +!TP_COLORAPP_SURROUND_AVER;Average +!TP_COLORAPP_SURROUND_DARK;Dark +!TP_COLORAPP_SURROUND_DIM;Dim +!TP_COLORAPP_SURROUND_EXDARK;Extremly Dark (Cutsheet) +!TP_COLORAPP_SURROUND_TOOLTIP;Changes tones and colors to take into account the viewing conditions of the output device.\n\nAverage: Average light environment (standard). The image will not change.\n\nDim: Dim environment (TV). The image will become slighty dark.\n\nDark: Dark environment (projector). The image will become more dark.\n\nExtremly Dark: Extremly dark environment (cutsheet). The image will become very dark. +!TP_COLORAPP_SURSOURCE;Dark surround +!TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if image has a dark border. +!TP_COLORAPP_TCMODE_BRIGHTNESS;Brightness +!TP_COLORAPP_TCMODE_CHROMA;Chroma +!TP_COLORAPP_TCMODE_COLORF;Colorfulness +!TP_COLORAPP_TCMODE_LABEL1;Curve mode 1 +!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_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] +!TP_COLORAPP_WBRT;WB [RT] + [output] +!TP_COLORTONING_AB;o C/L +!TP_COLORTONING_AUTOSAT;Automatic +!TP_COLORTONING_BALANCE;Balance +!TP_COLORTONING_BY;o C/L +!TP_COLORTONING_CHROMAC;Opacity +!TP_COLORTONING_COLOR;Color +!TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;Chroma opacity as a function of luminance oC=f(L) +!TP_COLORTONING_HIGHLIGHT;Highlights +!TP_COLORTONING_HUE;Hue +!TP_COLORTONING_LABEL;Color Toning +!TP_COLORTONING_LAB;L*a*b* blending +!TP_COLORTONING_LUMAMODE;Preserve luminance +!TP_COLORTONING_LUMAMODE_TOOLTIP;If enabled, when you change color (red, green, cyan, blue, etc.) the luminance of each pixel is preserved. +!TP_COLORTONING_LUMA;Luminance +!TP_COLORTONING_METHOD;Method +!TP_COLORTONING_METHOD_TOOLTIP;"L*a*b* blending", "RGB sliders" and "RGB curves" use interpolated color blending.\n"Color balance (Shadows/Midtones/Highlights)" and "Saturation 2 colors" use direct colors.\n\nThe Black-and-White tool can be enabled when using any color toning method, which allows for color toning. +!TP_COLORTONING_MIDTONES;Midtones +!TP_COLORTONING_NEUTRAL;Reset sliders +!TP_COLORTONING_NEUTRAL_TIP;Reset all values (Shadows, Midtones, Highlights) to default. +!TP_COLORTONING_OPACITY;Opacity +!TP_COLORTONING_RGBCURVES;RGB - Curves +!TP_COLORTONING_RGBSLIDERS;RGB - Sliders +!TP_COLORTONING_SATURATEDOPACITY;Strength +!TP_COLORTONING_SATURATIONTHRESHOLD;Threshold +!TP_COLORTONING_SA;Saturation Protection +!TP_COLORTONING_SHADOWS;Shadows +!TP_COLORTONING_SPLITCOCO;Color Balance Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITCO;Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITLR;Saturation 2 colors +!TP_COLORTONING_STRENGTH;Strength +!TP_COLORTONING_STR;Strength +!TP_COLORTONING_TWO2;Special chroma '2 colors' +!TP_COLORTONING_TWOALL;Special chroma +!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_GTFRAME;Frame +!TP_CROP_GTGRID;Grid +!TP_CROP_GTHARMMEANS;Harmonic Means +!TP_CROP_GTTRIANGLE1;Golden Triangles 1 +!TP_CROP_GTTRIANGLE2;Golden Triangles 2 +!TP_CROP_PPI;PPI= +!TP_DARKFRAME_AUTOSELECT;Auto-selection +!TP_DARKFRAME_LABEL;Dark-Frame +!TP_DEFRINGE_LABEL;Defringe +!TP_DEFRINGE_RADIUS;Radius +!TP_DEFRINGE_THRESHOLD;Threshold +!TP_DIRPYRDENOISE_33;3×3 strong +!TP_DIRPYRDENOISE_55SOFT;5×5 +!TP_DIRPYRDENOISE_55;5×5 strong +!TP_DIRPYRDENOISE_77;7×7 (slow) +!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_ABM;Chroma only +!TP_DIRPYRDENOISE_AUTO;Automatic global +!TP_DIRPYRDENOISE_AUTO_TOOLTIP;Try to evaluate chroma noise\nBe careful, this calculation is average, and is quite subjective ! +!TP_DIRPYRDENOISE_AUT;Automatic global +!TP_DIRPYRDENOISE_BLUE;Chrominance - Blue-Yellow +!TP_DIRPYRDENOISE_C2TYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CCCURVE;Chrominance curve +!TP_DIRPYRDENOISE_CHROMAFR;Chrominance +!TP_DIRPYRDENOISE_CHROMA;Chrominance - Master +!TP_DIRPYRDENOISE_CTYPE;Auto method +!TP_DIRPYRDENOISE_CTYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nAutomatic multi-zones\nNo preview - works only during saving, but using the "Preview" method by matching the tile size and center to the preview size and center you can get an idea of the expected results.\nThe image is divided into tiles (about 10 to 70 depending on image size) and each tile receives its own chrominance noise reduction settings.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CURVEEDITOR_CC;Chroma +!TP_DIRPYRDENOISE_CURVEEDITOR_CC_TOOLTIP;Increase (multiply) the value of all chrominance sliders.\nThis curve lets you adjust the strength of chromatic noise reduction as a function of chromaticity, for instance to increase the action in areas of low saturation and to decrease it in those of high saturation. +!TP_DIRPYRDENOISE_CURVEEDITOR_L_TOOLTIP;Modulates action of 'Luminance' denoise +!TP_DIRPYRDENOISE_CUR;Curve +!TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on the gamma of the input color profile. An sRGB gamma is assumed, thus if the image uses an input color profile of a different gamma, the effects of luminance noise reduction will differ. +!TP_DIRPYRDENOISE_ENH;Enhanced mode +!TP_DIRPYRDENOISE_ENH_TOOLTIP;Increases noise reduction quality at the expense of a 20% processing time increase. +!TP_DIRPYRDENOISE_GAMMA;Gamma +!TP_DIRPYRDENOISE_GAMMA_TOOLTIP;Gamma varies noise reduction strength across the range of tones. Smaller values will target shadows, while larger values will stretch the effect to the brighter tones. +!TP_DIRPYRDENOISE_LABEL;Noise Reduction +!TP_DIRPYRDENOISE_LABM;L*a*b* +!TP_DIRPYRDENOISE_LAB;L*a*b* +!TP_DIRPYRDENOISE_LCURVE;Luminance curve +!TP_DIRPYRDENOISE_LDETAIL;Luminance - Detail +!TP_DIRPYRDENOISE_LM;Luminance only +!TP_DIRPYRDENOISE_LPLABM;Weighted L* (little) + a*b* (normal) +!TP_DIRPYRDENOISE_LTYPE;Luminance control +!TP_DIRPYRDENOISE_LUMAFR;Luminance +!TP_DIRPYRDENOISE_LUMAFR_TOOLTIP;Wavelet on luminance and Fourier transform for luminance detail +!TP_DIRPYRDENOISE_LUMA;Luminance +!TP_DIRPYRDENOISE_MANU;Manual +!TP_DIRPYRDENOISE_MAN;Manual +!TP_DIRPYRDENOISE_MEDMETHOD;Median method +!TP_DIRPYRDENOISE_MEDTYPE;Median type +!TP_DIRPYRDENOISE_MED;Median Filter +!TP_DIRPYRDENOISE_MED_TOOLTIP;Enabled median denoising +!TP_DIRPYRDENOISE_METHOD11;Quality +!TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. +!TP_DIRPYRDENOISE_METHOD;Method +!TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or L*a*b* methods can be used.\n\nFor non-raw images the L*a*b* method will be used, regardless of the selection. +!TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - +!TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 +!TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. +!TP_DIRPYRDENOISE_PASSES;Median iterations +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PON;Auto multi-zones +!TP_DIRPYRDENOISE_PREVLABEL;Preview size=%1, Center: Px=%2 Py=%3 +!TP_DIRPYRDENOISE_PREV;Preview +!TP_DIRPYRDENOISE_PRE;Preview multi-zones +!TP_DIRPYRDENOISE_RED;Chrominance - Red-Green +!TP_DIRPYRDENOISE_RGBM;RGB +!TP_DIRPYRDENOISE_RGB;RGB +!TP_DIRPYRDENOISE_SHALBI;High +!TP_DIRPYRDENOISE_SHAL;Standard +!TP_DIRPYRDENOISE_SLI;Slider +!TP_DIRPYRDENOISE_SOFT;3x3 +!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_LUMAFINEST;Finest +!TP_DIRPYREQUALIZER_LUMANEUTRAL;Neutral +!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_THRESHOLD;Threshold +!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;Auto Distortion Correction +!TP_DISTORTION_AUTO_TIP;Correct lens distortion automatically for some cameras (Micro 4/3, some compact digital cameras, etc.). +!TP_EPD_EDGESTOPPING;Edge stopping +!TP_EPD_GAMMA;Gamma +!TP_EPD_LABEL;Tone Mapping +!TP_EPD_REWEIGHTINGITERATES;Reweighting iterates +!TP_EPD_SCALE;Scale +!TP_EPD_STRENGTH;Strength +!TP_EPD_TOOLTIP;Tone mapping is possible in L*a*b* mode (standard) and CIECAM02 mode.\n\nWhen in L*a*b* mode, tone mapping can also be used on the residual image of the Wavelet Levels tool.\n\nTo engage CIECAM02 tone mapping mode enable the following settings:\n1. CIECAM02\n2. Algorithm="Brightness + Colorfulness (QM)"\n3. "Tone mapping using CIECAM02 brightness (Q)" +!TP_EXPOSURE_AUTOLEVELS_TIP;Toggles execution of Auto Levels to automatically set Exposure slider values based on an image analysis.\nEnables Highlight Reconstruction if necessary. +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in Auto Levels operation. +!TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Highlight compression threshold +!TP_EXPOSURE_CURVEEDITOR1;Tone curve 1 +!TP_EXPOSURE_CURVEEDITOR2;Tone curve 2 +!TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Please refer to the "Exposure > Tone Curves" RawPedia article to learn how to achieve the best results by using two tone curves. +!TP_EXPOSURE_SATURATION;Saturation +!TP_EXPOSURE_TCMODE_FILMLIKE;Film-like +!TP_EXPOSURE_TCMODE_LABEL1;Curve mode 1 +!TP_EXPOSURE_TCMODE_LABEL2;Curve mode 2 +!TP_EXPOSURE_TCMODE_LUMINANCE;Luminance +!TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Saturation and Value Blending +!TP_EXPOSURE_TCMODE_STANDARD;Standard +!TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard +!TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points +!TP_EXPOS_WHITEPOINT_LABEL;Raw White Points +!TP_FILMSIMULATION_LABEL;Film Simulation +!TP_FILMSIMULATION_STRENGTH;Strength +!TP_FILMSIMULATION_ZEROCLUTSFOUND;Set HaldCLUT directory in Preferences +!TP_FLATFIELD_AUTOSELECT;Auto-selection +!TP_FLATFIELD_BLURRADIUS;Blur radius +!TP_FLATFIELD_BLURTYPE;Blur type +!TP_FLATFIELD_BT_AREA;Area +!TP_FLATFIELD_BT_HORIZONTAL;Horizontal +!TP_FLATFIELD_BT_VERTHORIZ;Vertical + Horizontal +!TP_FLATFIELD_BT_VERTICAL;Vertical +!TP_FLATFIELD_CLIPCONTROL;Clip control +!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. +!TP_FLATFIELD_LABEL;Flat-Field +!TP_GAMMA_CURV;Gamma +!TP_GAMMA_FREE;Free gamma +!TP_GAMMA_OUTPUT;Output gamma +!TP_GAMMA_SLOP;Slope (linear) +!TP_GENERAL_11SCALE_TOOLTIP;The effects of this tool are only visible or only accurate at a preview scale of 1:1. +!TP_GRADIENT_CENTER;Center +!TP_GRADIENT_CENTER_X;Center X +!TP_GRADIENT_CENTER_X_TOOLTIP;Shift gradient to the left (negative values) or right (positive values). +!TP_GRADIENT_CENTER_Y;Center Y +!TP_GRADIENT_CENTER_Y_TOOLTIP;Shift gradient up (negative values) or down (positive values). +!TP_GRADIENT_DEGREE;Angle +!TP_GRADIENT_DEGREE_TOOLTIP;Rotation angle in degrees. +!TP_GRADIENT_FEATHER;Feather +!TP_GRADIENT_FEATHER_TOOLTIP;Gradient width in percent of the image diagonal. +!TP_GRADIENT_LABEL;Graduated Filter +!TP_GRADIENT_STRENGTH;Strength +!TP_GRADIENT_STRENGTH_TOOLTIP;Filter strength in stops. +!TP_HLREC_BLEND;Blend +!TP_HLREC_ENA_TOOLTIP;Could be activated by Auto Levels. +!TP_HSVEQUALIZER_CHANNEL;Channel +!TP_HSVEQUALIZER_HUE;H +!TP_HSVEQUALIZER_LABEL;HSV Equalizer +!TP_HSVEQUALIZER_SAT;S +!TP_HSVEQUALIZER_VAL;V +!TP_ICM_BLENDCMSMATRIX;Blend ICC highlights with matrix +!TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover clipped highlights when using LUT-based ICC profiles. +!TP_ICM_DCPILLUMINANT;Illuminant +!TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolated +!TP_ICM_DCPILLUMINANT_TOOLTIP;Select which embedded DCP illuminant to employ. Default is "interpolated" which is a mix between the two based on white balance. The setting is only enabled if a Dual-Illuminant DCP with interpolation support is selected. +!TP_ICM_INPUTCAMERAICC;Auto-matched camera profile +!TP_ICM_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input color profiles. These profiles are more precise than simpler matrix ones. They are not available for all cameras. These profiles are stored in the /iccprofiles/input and /dcpprofiles folders and are automatically retrieved based on a file name matching to the exact model name of the camera. +!TP_ICM_INPUTCAMERA_TOOLTIP;Use a simple color matrix from dcraw, an enhanced RawTherapee version (whichever is available based on camera model) or one embedded in the DNG. +!TP_ICM_INPUTCUSTOM_TOOLTIP;Select your own DCP/ICC color profile file for the camera. +!TP_ICM_INPUTEMBEDDED_TOOLTIP;Use color profile embedded in non-raw files. +!TP_ICM_INPUTNONE;No profile +!TP_ICM_INPUTNONE_TOOLTIP;Use no input color profile at all.\nUse only in special cases. +!TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance +!TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. The result can be used for calibration purposes and generation of a camera profile. +!TP_ICM_TONECURVE;Use DCP's tone curve +!TP_ICM_TONECURVE_TOOLTIP;Employ the embedded DCP tone curve. The setting is only enabled if the selected DCP has a tone curve. +!TP_IMPULSEDENOISE_LABEL;Impulse Noise Reduction +!TP_IMPULSEDENOISE_THRESH;Threshold +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid color shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction. +!TP_LABCURVE_BRIGHTNESS;Lightness +!TP_LABCURVE_CHROMATICITY;Chromaticity +!TP_LABCURVE_CHROMA_TOOLTIP;To apply B&W toning, set Chromaticity to -100. +!TP_LABCURVE_CONTRAST;Contrast +!TP_LABCURVE_CURVEEDITOR;Luminance Curve +!TP_LABCURVE_CURVEEDITOR_A_RANGE1;Green Saturated +!TP_LABCURVE_CURVEEDITOR_A_RANGE2;Green Pastel +!TP_LABCURVE_CURVEEDITOR_A_RANGE3;Red Pastel +!TP_LABCURVE_CURVEEDITOR_A_RANGE4;Red Saturated +!TP_LABCURVE_CURVEEDITOR_B_RANGE1;Blue Saturated +!TP_LABCURVE_CURVEEDITOR_B_RANGE2;Blue Pastel +!TP_LABCURVE_CURVEEDITOR_B_RANGE3;Yellow Pastel +!TP_LABCURVE_CURVEEDITOR_B_RANGE4;Yellow Saturated +!TP_LABCURVE_CURVEEDITOR_CC;CC +!TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutral +!TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Dull +!TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastel +!TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Saturated +!TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Chromaticity according to chromaticity C=f(C) +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to hue C=f(H) +!TP_LABCURVE_CURVEEDITOR_CL;CL +!TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Chromaticity according to luminance C=f(L) +!TP_LABCURVE_CURVEEDITOR_HH;HH +!TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Hue according to hue H=f(H) +!TP_LABCURVE_CURVEEDITOR_LC;LC +!TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminance according to chromaticity L=f(C) +!TP_LABCURVE_CURVEEDITOR_LH;LH +!TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H) +!TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminance according to luminance L=f(L) +!TP_LABCURVE_LABEL;L*a*b* Adjustments +!TP_LABCURVE_LCREDSK;Restrict LC to red and skin-tones +!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_LENSGEOM_AUTOCROP;Auto-Crop +!TP_LENSGEOM_FILL;Auto-fill +!TP_LENSGEOM_LABEL;Lens / Geometry +!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_USECA;Chromatic aberration correction +!TP_LENSPROFILE_USEDIST;Distortion correction +!TP_LENSPROFILE_USEVIGN;Vignetting correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Resets exposure sliders to neutral values.\nApplies to the same controls that Auto Levels applies to, regardless of whether you used Auto Levels or not. +!TP_PCVIGNETTE_FEATHER;Feather +!TP_PCVIGNETTE_FEATHER_TOOLTIP;Feathering:\n0 = corners only,\n50 = halfway to center,\n100 = to center. +!TP_PCVIGNETTE_LABEL;Vignette Filter +!TP_PCVIGNETTE_ROUNDNESS;Roundness +!TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness:\n0 = rectangle,\n50 = fitted ellipse,\n100 = circle. +!TP_PCVIGNETTE_STRENGTH;Strength +!TP_PCVIGNETTE_STRENGTH_TOOLTIP;Filter strength in stops (reached in corners). +!TP_PERSPECTIVE_HORIZONTAL;Horizontal +!TP_PERSPECTIVE_LABEL;Perspective +!TP_PERSPECTIVE_VERTICAL;Vertical +!TP_PFCURVE_CURVEEDITOR_CH;Hue +!TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Controls defringe strength by color.\nHigher = more,\nLower = less. +!TP_PREPROCESS_DEADPIXFILT;Dead pixel filter +!TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Tries to suppress dead pixels. +!TP_PREPROCESS_GREENEQUIL;Green equilibration +!TP_PREPROCESS_HOTPIXFILT;Hot pixel filter +!TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Tries to suppress hot pixels. +!TP_PREPROCESS_LABEL;Preprocessing +!TP_PREPROCESS_LINEDENOISE;Line noise filter +!TP_PREPROCESS_NO_FOUND;None found +!TP_RAWCACORR_AUTO;Auto-correction +!TP_RAWCACORR_CABLUE;Blue +!TP_RAWCACORR_CARED;Red +!TP_RAWEXPOS_BLACKS;Black Levels +!TP_RAWEXPOS_BLACK_0;Green 1 (lead) +!TP_RAWEXPOS_BLACK_1;Red +!TP_RAWEXPOS_BLACK_2;Blue +!TP_RAWEXPOS_BLACK_3;Green 2 +!TP_RAWEXPOS_BLACK_BLUE;Blue +!TP_RAWEXPOS_BLACK_GREEN;Green +!TP_RAWEXPOS_BLACK_RED;Red +!TP_RAWEXPOS_LINEAR;White-point correction +!TP_RAWEXPOS_PRESER;Highlight preservation +!TP_RAWEXPOS_RGB;Red, Green, Blue +!TP_RAWEXPOS_TWOGREEN;Link greens +!TP_RAW_DCBENHANCE;DCB enhancement +!TP_RAW_DCBITERATIONS;Number of DCB iterations +!TP_RAW_DMETHOD_PROGRESSBAR;%1 demosaicing... +!TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Demosaicing refinement... +!TP_RAW_DMETHOD_TOOLTIP;Note: IGV and LMMSE are dedicated to high ISO images to aid in noise reduction without leading to maze patterns, posterization or a washed-out look. +!TP_RAW_HD;Threshold +!TP_RAW_HD_TOOLTIP;Lower values make hot/dead pixel detection more aggressive, but false positives may lead to artifacts. If you notice any artifacts appearing when enabling the Hot/Dead Pixel Filters, gradually increase the threshold value until they disappear. +!TP_RAW_LABEL;Demosaicing +!TP_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!TP_RAW_LMMSE_TOOLTIP;Adds gamma (step 1), median (steps 2-4) and refinement (steps 5-6) to reduce artifacts and improve the signal-to-noise ratio. +!TP_RAW_SENSOR_BAYER_LABEL;Sensor with Bayer Matrix +!TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;3-pass gives best results (recommended for low ISO images).\n1-pass is almost undistinguishable from 3-pass for high ISO images and is faster. +!TP_RAW_SENSOR_XTRANS_LABEL;Sensor with X-Trans Matrix +!TP_RESIZE_APPLIESTO;Applies to: +!TP_RESIZE_CROPPEDAREA;Cropped Area +!TP_RESIZE_FITBOX;Bounding Box +!TP_RESIZE_FULLIMAGE;Full Image +!TP_RESIZE_HEIGHT;Height +!TP_RESIZE_LANCZOS;Lanczos +!TP_RESIZE_SPECIFY;Specify: +!TP_RESIZE_WIDTH;Width +!TP_RGBCURVES_BLUE;B +!TP_RGBCURVES_CHANNEL;Channel +!TP_RGBCURVES_GREEN;G +!TP_RGBCURVES_LABEL;RGB Curves +!TP_RGBCURVES_LUMAMODE;Luminosity mode +!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_RGBCURVES_RED;R +!TP_SAVEDIALOG_OK_TIP;Shortcut: Ctrl-Enter +!TP_SHADOWSHLIGHTS_SHARPMASK;Sharp mask +!TP_SHARPENEDGE_AMOUNT;Quantity +!TP_SHARPENEDGE_LABEL;Edges +!TP_SHARPENEDGE_PASSES;Iterations +!TP_SHARPENEDGE_THREE;Luminance only +!TP_SHARPENING_TOOLTIP;Expect a slightly different effect when using with CIECAM02. If difference is observed, adjust to taste. +!TP_SHARPENMICRO_AMOUNT;Quantity +!TP_SHARPENMICRO_LABEL;Microcontrast +!TP_SHARPENMICRO_MATRIX;3×3 matrix instead of 5×5 +!TP_SHARPENMICRO_UNIFORMITY;Uniformity +!TP_VIBRANCE_AVOIDCOLORSHIFT;Avoid color shift +!TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Red/Purple +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Red +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Red/Yellow +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Yellow +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Hue according to hue H=f(H) +!TP_VIBRANCE_LABEL;Vibrance +!TP_VIBRANCE_PASTELS;Pastel Tones +!TP_VIBRANCE_PASTSATTOG;Link pastel and saturated tones +!TP_VIBRANCE_PROTECTSKINS;Protect skin-tones +!TP_VIBRANCE_PSTHRESHOLD;Pastel/saturated tones threshold +!TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Saturation threshold +!TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;The vertical axis represents pastel tones at the bottom and saturated tones at the top.\nThe horizontal axis represents the saturation range. +!TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Pastel/saturated transition's weighting +!TP_VIBRANCE_SATURATED;Saturated Tones +!TP_VIGNETTING_CENTER;Center +!TP_VIGNETTING_CENTER_X;Center X +!TP_VIGNETTING_CENTER_Y;Center Y +!TP_VIGNETTING_STRENGTH;Strength +!TP_WAVELET_1;Level 1 +!TP_WAVELET_2;Level 2 +!TP_WAVELET_3;Level 3 +!TP_WAVELET_4;Level 4 +!TP_WAVELET_5;Level 5 +!TP_WAVELET_6;Level 6 +!TP_WAVELET_7;Level 7 +!TP_WAVELET_8;Level 8 +!TP_WAVELET_9;Level 9 +!TP_WAVELET_ALL;All levels in all directions +!TP_WAVELET_APPLYTO;Apply To +!TP_WAVELET_AVOID;Avoid color shift +!TP_WAVELET_B0;Black +!TP_WAVELET_B1;Grey +!TP_WAVELET_B2;Residual +!TP_WAVELET_BACUR;Curve +!TP_WAVELET_BALANCE;Contrast balance d/v-h +!TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chromaticity or residual tone mapping are activated, the effect due to balance is amplified. +!TP_WAVELET_BALCHRO;Chroma balance +!TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chromaticity balance. +!TP_WAVELET_BANONE;None +!TP_WAVELET_BASLI;Slider +!TP_WAVELET_BATYPE;Contrast balance method +!TP_WAVELET_CCURVE;Local contrast +!TP_WAVELET_CH1;Whole chromaticity range +!TP_WAVELET_CH2;Saturated/pastel +!TP_WAVELET_CH3;Link contrast levels +!TP_WAVELET_CHCU;Curve +!TP_WAVELET_CHRO;Saturated/pastel threshold +!TP_WAVELET_CHRO_TOOLTIP;Sets the wavelet level which will be the threshold between saturated and pastel colors.\n1-x: saturated\nx-9: pastel\n\nIf the value exceeds the amount of wavelet levels you are using then it will be ignored. +!TP_WAVELET_CHR;Chroma-contrast link strength +!TP_WAVELET_CHR_TOOLTIP;Adjusts chromaticity as a function of "contrast levels" and "chroma-contrast link strength" +!TP_WAVELET_CHSL;Sliders +!TP_WAVELET_CHTYPE;Chrominance method +!TP_WAVELET_COLORT;Opacity Red-Green +!TP_WAVELET_COMBOTH;Both +!TP_WAVELET_COMPCONT;Contrast +!TP_WAVELET_COMPGAMMA;Compression gamma +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjusting the gamma of the residual image allow you to equilibrate the data and histogram. +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjust gamma for residual image and compression.\nAllow to equilibrate data and histogram +!TP_WAVELET_COMPTM;Tone mapping +!TP_WAVELET_CONTEDIT;'After' Contrast curve +!TP_WAVELET_CONTEDIT;'After' contrast curve +!TP_WAVELET_CONTRAST_MINUS;Contrast - +!TP_WAVELET_CONTRAST_PLUS;Contrast + +!TP_WAVELET_CONTRA;Contrast +!TP_WAVELET_CONTRA_TOOLTIP;Changes contrast of the residual image. +!TP_WAVELET_CONTR;Gamut +!TP_WAVELET_CTYPE;Chrominance control +!TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modifies local contrast as a function of the original local contrast (absciss)\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 100..300)\n66% absciss represents standard deviation of local contrast (real value about 300..800)\n100% represents maximum (real value about 3000..8000) +!TP_WAVELET_CURVEEDITOR_CH;Contrast levels=f(Hue) +!TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modifies each level's contrast as a function oh hue.\nTake care not to overwrite changes made with the Gamut Hue controls.\nThe curve will only have an effect when wavelet contrast level sliders are non-zero. +!TP_WAVELET_CURVEEDITOR_CL;L +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Applies a final contrast luminance curve at the end of the wavelet treatment. +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Apply a contrast luminance curve at the end of wavelet level threatment +!TP_WAVELET_CURVEEDITOR_HH;HH +!TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modifies the residual image's hue as a function of hue. +!TP_WAVELET_DALL;All directions +!TP_WAVELET_DAUB;Edge performance +!TP_WAVELET_DAUB_TOOLTIP;Changes Daubechies coefficients:\nD4 = Standard,\nD14 = Often best performance, 10% more time-intensive.\n\nAffects edge detection as well as the general quality of the firsts levels. However the quality is not strictly related to this coefficient and can vary with images and uses. +!TP_WAVELET_DISP;Preview Settings +!TP_WAVELET_DONE;Vertical +!TP_WAVELET_DTHR;Diagonal +!TP_WAVELET_DTWO;Horizontal +!TP_WAVELET_EDCU;Curve +!TP_WAVELET_EDGCONT;Local contrast +!TP_WAVELET_EDGCONT_TOOLTIP;Adjusting the points to the left decreases contrast, and to the right increases it.\nBottom-left, Top-Left, Top-Right, Bottom-right represent respectively local contast for low values, mean, mean+stdev, maxima +!TP_WAVELET_EDGEDETECTTHR2;Threshold high (detection) +!TP_WAVELET_EDGEDETECTTHR;Threshold low (noise) +!TP_WAVELET_EDGEDETECTTHR_TOOLTIP;This adjuster lets you target edge detection for example to avoid applying edge sharpness to fine details, such as noise in the sky. +!TP_WAVELET_EDGEDETECT;Gradient sensitivity +!TP_WAVELET_EDGEDETECT_TOOLTIP;Moving the slider to the right increases edge sensitivity. This affects local contrast, edge settings and noise. +!TP_WAVELET_EDGE;Edge Sharpness +!TP_WAVELET_EDGREINF_TOOLTIP;Reinforce or reduce the action of the first level, do the opposite to the second level, and leave the rest unchanged. +!TP_WAVELET_EDGTHRESH;Detail +!TP_WAVELET_EDGTHRESH_TOOLTIP;Change the repartition between the first levels and the others. The higher the threshold the more the action is centred on the first levels. Be careful with negative values, they increase the action of high levels and can introduce artifacts. +!TP_WAVELET_EDRAD;Radius +!TP_WAVELET_EDRAD_TOOLTIP;This radius adjustment is very different from those in other sharpening tools. Its value is compared to each level through a complex function. In this sense, a value of zero still has an effect. +!TP_WAVELET_EDSL;Threshold Sliders +!TP_WAVELET_EDTYPE;Local contrast method +!TP_WAVELET_EDVAL;Strength +!TP_WAVELET_FINAL;Final Touchup +!TP_WAVELET_FINEST;Finest +!TP_WAVELET_HIGHLIGHT;Highlight luminance range +!TP_WAVELET_HS1;Whole luminance range +!TP_WAVELET_HS2;Shadows/Highlights +!TP_WAVELET_HUESKIN;Skin hue +!TP_WAVELET_HUESKIN_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_HUESKY;Sky hue +!TP_WAVELET_HUESKY_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_INF;Below or equal the level +!TP_WAVELET_ITER;Delta balance levels +!TP_WAVELET_ITER_TOOLTIP;Left: increase low levels and reduce high levels,\nRight: reduce low levels and increase high levels. +!TP_WAVELET_LABEL;Wavelet levels +!TP_WAVELET_LARGEST;Coarsest +!TP_WAVELET_LEVCH;Chromaticity +!TP_WAVELET_LEVELS;Wavelet levels +!TP_WAVELET_LEVELS_TOOLTIP;Choose the number of detail levels the image is to be decomposed into. More levels require more RAM and require a longer processing time. +!TP_WAVELET_LEVF;Contrast +!TP_WAVELET_LEVLABEL;Preview maximum possible levels = %1 +!TP_WAVELET_LEVONE;Level 2 +!TP_WAVELET_LEVTWO;Level 3 +!TP_WAVELET_LEVZERO;Level 1 +!TP_WAVELET_LINKEDG;Link with Edge Sharpness' Strength +!TP_WAVELET_LIPST;Enhanced algorithm +!TP_WAVELET_LIPST_TOOLTIP;This algorithm uses Lipschitz regularity to increase edge detection quality at a cost of increased processing time and memory requirements. +!TP_WAVELET_LOWLIGHT;Shadow luminance range +!TP_WAVELET_MEDGREINF;First level +!TP_WAVELET_MEDILEV;Edge detection +!TP_WAVELET_MEDI;Reduce artifacts in blue sky +!TP_WAVELET_NEUTRAL;Neutral +!TP_WAVELET_NOISE;Denoise and Refine +!TP_WAVELET_NOIS;Denoise +!TP_WAVELET_ONE;One level +!TP_WAVELET_OPACITYWL;Final local contrast +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify final local contrast in function of last local contrast (absciss) for all levels decomposition\nTake into account: \na)contrast levels \nb)edge sharpness \nc)contrast balance\nd)decomposition-recomposition\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 200..1000)\n66% absciss represents standard deviation of local contrast (real value about 1000..2000)\n100% represents maximum (real value about 5000..13000) +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify the final local contrast at the end of the wavelet treatment.\n\nThe left side represents the smallest local contrast, progressing to the largest local contrast on the right. +!TP_WAVELET_OPACITYW;Contrast balance d/v-h curve +!TP_WAVELET_OPACITY;Opacity Blue-Yellow +!TP_WAVELET_PASTEL;Pastel chromaticity +!TP_WAVELET_PREVIEWBACK;Background +!TP_WAVELET_PREVIEWLEVELS;Preview +!TP_WAVELET_RE1;Reinforced +!TP_WAVELET_RE2;Unchanged +!TP_WAVELET_RE3;Reduced +!TP_WAVELET_RESCHRO;Chromaticity +!TP_WAVELET_RESCONH;Highlights +!TP_WAVELET_RESCON;Shadows +!TP_WAVELET_RESID;Residual image +!TP_WAVELET_SAT;Saturated chromaticity +!TP_WAVELET_SETTINGS;Wavelet Settings +!TP_WAVELET_SKIN;Skin targetting/protection +!TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected. +!TP_WAVELET_SKY;Sky targetting/protection +!TP_WAVELET_SKY_TOOLTIP;At -100 sky-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 sky-tones are protected while all other tones are affected. +!TP_WAVELET_STRENGTH;Strength +!TP_WAVELET_STREN;Strength +!TP_WAVELET_SUPE;Extra +!TP_WAVELET_SUP;Above the level +!TP_WAVELET_THRESHOLD2;Shadow levels +!TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels between 9 and 9 minus the value will be affected by the shadow luminance range. Other levels will be fully treated. The highest level possible is limited by the highlight level value (9 minus highlight level value). +!TP_WAVELET_THRESHOLD;Highlight levels +!TP_WAVELET_THRESHOLD_TOOLTIP;Only levels beyond the chosen value will be affected by the highlight luminance range. Other levels will be fully treated. The chosen value here limits the highest possible value of the shadow levels. +!TP_WAVELET_THRH;Highlights threshold +!TP_WAVELET_THR;Shadows threshold +!TP_WAVELET_TILESBIG;Big tiles +!TP_WAVELET_TILESFULL;Full image +!TP_WAVELET_TILESIZE;Tiling method +!TP_WAVELET_TILESLIT;Little tiles +!TP_WAVELET_TILES_TOOLTIP;Processing the full image leads to better quality and is the recommended option, while using tiles is a fall-back solution for users with little RAM. Refer to RawPedia for memory requirements. +!TP_WAVELET_TMHIGH;High +!TP_WAVELET_TMLOWHIGH;Low+High +!TP_WAVELET_TMNONE;None +!TP_WAVELET_TMSTD;Standard +!TP_WAVELET_TMSTRENGTH;Compression strength +!TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image. When the value is different from 0, the Strength and Gamma sliders of the Tone Mapping tool in the Exposure tab will become grayed out. +!TP_WAVELET_TMTYPE;Compression method +!TP_WAVELET_TON;Toning +!TP_WAVELET_daub2;D2 - low +!TP_WAVELET_daub4;D4 - standard +!TP_WAVELET_daub6;D6 - standard plus +!TP_WAVELET_daub10;D10 - medium +!TP_WAVELET_daub14;D14 - high +!TP_WBALANCE_CLOUDY;Cloudy +!TP_WBALANCE_DAYLIGHT;Daylight (sunny) +!TP_WBALANCE_EQBLUERED;Blue/Red equalizer +!TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behavior of "white balance" by modulating the blue/red balance.\nThis can be useful when shooting conditions:\na) are far from the standard illuminant (e.g. underwater),\nb) are far from conditions where calibrations were performed,\nc) where the matrices or ICC profiles are unsuitable. +!TP_WBALANCE_FLASH55;Leica +!TP_WBALANCE_FLASH60;Standard, Canon, Pentax, Olympus +!TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta +!TP_WBALANCE_FLASH_HEADER;Flash +!TP_WBALANCE_FLUO1;F1 - Daylight +!TP_WBALANCE_FLUO2;F2 - Cool White +!TP_WBALANCE_FLUO3;F3 - White +!TP_WBALANCE_FLUO4;F4 - Warm White +!TP_WBALANCE_FLUO5;F5 - Daylight +!TP_WBALANCE_FLUO6;F6 - Lite White +!TP_WBALANCE_FLUO7;F7 - D65 Daylight Simulator +!TP_WBALANCE_FLUO8;F8 - D50 / Sylvania F40 Design +!TP_WBALANCE_FLUO9;F9 - Cool White Deluxe +!TP_WBALANCE_FLUO10;F10 - Philips TL85 +!TP_WBALANCE_FLUO11;F11 - Philips TL84 +!TP_WBALANCE_FLUO12;F12 - Philips TL83 +!TP_WBALANCE_FLUO_HEADER;Fluorescent +!TP_WBALANCE_GTI;GTI +!TP_WBALANCE_HMI;HMI +!TP_WBALANCE_JUDGEIII;JudgeIII +!TP_WBALANCE_LAMP_HEADER;Lamp +!TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 +!TP_WBALANCE_LED_HEADER;LED +!TP_WBALANCE_LED_LSI;LSI Lumelex 2040 +!TP_WBALANCE_SHADE;Shade +!TP_WBALANCE_SOLUX35;Solux 3500K +!TP_WBALANCE_SOLUX41;Solux 4100K +!TP_WBALANCE_SOLUX47;Solux 4700K (vendor) +!TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) +!TP_WBALANCE_TUNGSTEN;Tungsten +!TP_WBALANCE_WATER1;UnderWater 1 +!TP_WBALANCE_WATER2;UnderWater 2 +!TP_WBALANCE_WATER_HEADER;UnderWater +!ZOOMPANEL_100;(100%) +!ZOOMPANEL_NEWCROPWINDOW;Open (new) detail window +!ZOOMPANEL_ZOOM100;Zoom to 100%\nShortcut: z +!ZOOMPANEL_ZOOMFITCROPSCREEN;Fit crop to screen\nShortcut: Alt-f +!ZOOMPANEL_ZOOMFITSCREEN;Fit whole image to screen\nShortcut: f +!ZOOMPANEL_ZOOMIN;Zoom In\nShortcut: + +!ZOOMPANEL_ZOOMOUT;Zoom Out\nShortcut: - diff --git a/rtdata/languages/Deutsch b/rtdata/languages/Deutsch new file mode 100644 index 000000000..f19900bd9 --- /dev/null +++ b/rtdata/languages/Deutsch @@ -0,0 +1,1872 @@ +#01 keenonkites; Aktualisierte Version für 2.3 beta2 +#02 phberlin; basiert auf keenonkites' Erstübersetzung +#03 2007-12-20 +#04 2007-12-22 +#05 2008-01-08 +#06 2008-01-15 +#07 2008-02-20 +#08 2008-12-19 keenonkites, Anpassungen für 2.4beta4 +#09 2008-09-20 keenonkites, Anpassungen für 2.4m2 +#10 2008-04-04 Anpassungen für 2.4 +#11 Leichte Anpassungen (keenonkites/klonk) +#12 Erweiterung (oduis) +#13 Erweiterung (oduis) +#14 Erweiterung (oduis) +#15 Erweiterung (oduis) +#16 2012-12-05 3.0 alpha: Erweiterung und Korrekturen (Metex) +#17 2012-04-29 Erweiterungen und Korrekturen (MaWe) +#18 Erweiterung (oduis) +#19 Erweiterung (oduis) +#20 2013-02-27 Erweiterung (cytrinox) +#21 2013-12-31 Erweiterung (Ingo) + +ABOUT_TAB_BUILD;Version +ABOUT_TAB_CREDITS;Danksagungen +ABOUT_TAB_LICENSE;Lizenz +ABOUT_TAB_RELEASENOTES;Versionshinweise +ABOUT_TAB_SPLASH;Startbild +ADJUSTER_RESET_TO_DEFAULT;Standard wiederherstellen +BATCHQUEUE_AUTOSTART;Automatisch starten +BATCH_PROCESSING;Stapelverarbeitung +CURVEEDITOR_CURVES;Kurven +CURVEEDITOR_CURVE;Kurve +CURVEEDITOR_CUSTOM;Angepasst +CURVEEDITOR_DARKS;Tiefen +CURVEEDITOR_HIGHLIGHTS;Spitzlichter +CURVEEDITOR_LIGHTS;Lichter +CURVEEDITOR_LINEAR;Linear +CURVEEDITOR_LOADDLGLABEL;Kurve laden... +CURVEEDITOR_MINMAXCPOINTS;Min/Max Kontrollpunkte +CURVEEDITOR_NURBS;NURBS-Kurve +CURVEEDITOR_PARAMETRIC;Parametrisch +CURVEEDITOR_SAVEDLGLABEL;Kurve speichern... +CURVEEDITOR_SHADOWS;Schatten +CURVEEDITOR_TOOLTIPCOPY;Kurve in Zwischenablage kopieren +CURVEEDITOR_TOOLTIPLINEAR;Kurve zurücksetzen (Linear) +CURVEEDITOR_TOOLTIPLOAD;Kurve aus Datei laden +CURVEEDITOR_TOOLTIPPASTE;Kurve aus Zwischenablage einfügen +CURVEEDITOR_TOOLTIPSAVE;Kurve speichern +CURVEEDITOR_TYPE;Typ +DIRBROWSER_FOLDERS;Verzeichnisse +EDITWINDOW_TITLE;Bildbearbeitung +EXIFFILTER_APERTURE;Blende +EXIFFILTER_CAMERA;Kamera +EXIFFILTER_EXPOSURECOMPENSATION;Belichtungskorrektur (EV) +EXIFFILTER_FILETYPE;Dateityp +EXIFFILTER_FOCALLEN;Brennweite +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Objektiv +EXIFFILTER_METADATAFILTER;Metadatenfilter einschalten +EXIFFILTER_SHUTTER;Verschlusszeit +EXIFPANEL_ADDEDITHINT;Neues Attribut hinzufügen oder bestehendes ändern +EXIFPANEL_ADDEDIT;Neu/Ändern +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Wert eingeben +EXIFPANEL_ADDTAGDLG_SELECTTAG;Attribut wählen +EXIFPANEL_ADDTAGDLG_TITLE;Attribut hinzufügen/ändern +EXIFPANEL_KEEPHINT;Gewählte Attribute beim Erzeugen des Bildes behalten +EXIFPANEL_KEEP;Behalten +EXIFPANEL_REMOVEHINT;Gewählte Attribute beim Erzeugen des Bildes entfernen +EXIFPANEL_REMOVE;Entfernen +EXIFPANEL_RESETALLHINT;Alle Attribute auf die ursprünglichen Werte zurücksetzen +EXIFPANEL_RESETALL;Alle zurücksetzen +EXIFPANEL_RESETHINT;Gewählte Attribute auf die ursprünglichen Werte zurücksetzen +EXIFPANEL_RESET;Zurücksetzen +EXIFPANEL_SUBDIRECTORY;Unterverzeichnis +EXPORT_BYPASS_ALL;Alle/Keine der Umgehungen auswählen +EXPORT_BYPASS_DEFRINGE;Defringe umgehen +EXPORT_BYPASS_DIRPYRDENOISE;Rauschminderung umgehen +EXPORT_BYPASS_DIRPYREQUALIZER;Kontrast nach Detailstufen umgehen +EXPORT_BYPASS_RAW_CA;Korrektur der Chromatischen\nAberration umgehen [RAW] +EXPORT_BYPASS_RAW_CCSTEPS;Falschfarbenunterdrückung umgehen\n[RAW] +EXPORT_BYPASS_RAW_DCB_ENHANCE;DCB-Verfeinerungsschritt umgehen\n[RAW] +EXPORT_BYPASS_RAW_DCB_ITERATIONS;DCB-Interationen umgehen [RAW] +EXPORT_BYPASS_RAW_DF;Dunkelbild umgehen [RAW] +EXPORT_BYPASS_RAW_FF;Weißbild umgehen [RAW] +EXPORT_BYPASS_RAW_GREENTHRESH;Grün-Ausgleich umgehen [RAW] +EXPORT_BYPASS_RAW_LINENOISE;Zeilenrauschfilter umgehen [RAW] +EXPORT_BYPASS_SHARPENEDGE;Kantenschärfung umgehen +EXPORT_BYPASS_SHARPENING;Schärfung umgehen +EXPORT_BYPASS_SHARPENMICRO;Mikrokontrast umgehen +EXPORT_BYPASS_SH_HQ;Schatten/Lichter umgehen\n(Hohe Qualität) +EXPORT_FASTEXPORTOPTIONS;Schneller Export - Einstellungen +EXPORT_INSTRUCTIONS;Die Einstellungen zum schnellen Export\nerlauben es, zeit- und ressourcenintensive\nEntwicklungsschritte zu umgehen und dafür\ndie Warteschlangenverarbeitung mit\nschnellen Export-Einstellungen auszuführen.\nDieses Vorgehen wird zur schnelleren\nGenerierung von gering aufgelösten Bildern\nempfohlen, falls es auf die Geschwindigkeit\nankommt oder für ein oder mehrere Bilder\nandere Ausgabegrößen gewünscht werden,\nohne Änderungen an deren gespeicherten\nParameter vornehmen zu müssen. +EXPORT_MAXHEIGHT;Maximale Höhe: +EXPORT_MAXWIDTH;Maximale Breite: +EXPORT_PUTTOQUEUEFAST;In Warteschlange zum schnellen Export +EXPORT_RAW_DMETHOD;Farbinterpolation\nMethode +EXTPROGTARGET_1;Raw +EXTPROGTARGET_2;stapelverarbeitet +FILEBROWSER_ADDDELTEMPLATE;Vorlagen hinzu/entfernen... +FILEBROWSER_APPLYPROFILE;Profil anwenden +FILEBROWSER_APPLYPROFILE_PARTIAL;Profil selektiv anwenden +FILEBROWSER_AUTODARKFRAME;Automatisches Dunkelbild +FILEBROWSER_AUTOFLATFIELD;Automatisches Weißbild +FILEBROWSER_BROWSEPATHBUTTONHINT;Nebenstehenden Pfad öffnen +FILEBROWSER_BROWSEPATHHINT;Pfad zum Öffnen eingeben\nStrg+O zum Setzen des Fokus\nEingabe (bzw. Strg+Eingabe im Dateimanager) zum Öffnen\n\nSonderzeichen im Pfad:\n~ für Benutzerverzeichnis, ! für Bildverzeichnis des Benutzers +FILEBROWSER_CACHECLEARFROMFULL;Aus dem Cache entfernen (vollständig) +FILEBROWSER_CACHECLEARFROMPARTIAL;Aus dem Cache entfernen (teilweise) +FILEBROWSER_CACHE;Cache +FILEBROWSER_CLEARPROFILE;Profil löschen +FILEBROWSER_COLORLABEL_TOOLTIP;Farbmarkierung\n\nBenutze Dropdown oder Tastatur:\nShift-Strg-0 Keine\nShift-Strg-1 Rot\nShift-Strg-2 Gelb\nShift-Strg-3 Grün\nShift-Strg-4 Blau\nShift-Strg-5 Violett +FILEBROWSER_COPYPROFILE;Profil kopieren +FILEBROWSER_CURRENT_NAME;Aktueller Name: +FILEBROWSER_DARKFRAME;Dunkelbild +FILEBROWSER_DELETEDLGLABEL;Dateien löschen +FILEBROWSER_DELETEDLGMSGINCLPROC;Möchten Sie wirklich %1 Datei(en) unwiderruflich löschen, SAMT evtl. zugehörigen, aus der Stapelverarbeitung resultierenden Ausgabedateien? +FILEBROWSER_DELETEDLGMSG;Möchten Sie wirklich %1 Datei(en) unwiderruflich löschen? +FILEBROWSER_EMPTYTRASHHINT;Dateien endgültig aus Papierkorb löschen +FILEBROWSER_EMPTYTRASH;Papierkorb leeren +FILEBROWSER_EXEC_CPB;Benutzerdef. Bildprofilgenerator ausführen +FILEBROWSER_EXTPROGMENU;Öffnen mit +FILEBROWSER_FLATFIELD;Weißbild +FILEBROWSER_MOVETODARKFDIR;In Dunkelbild-Verzeichnis verschieben +FILEBROWSER_MOVETOFLATFIELDDIR;In Weißbild-Verzeichnis verschieben +FILEBROWSER_NEW_NAME;Neuer Name: +FILEBROWSER_OPENDEFAULTVIEWER;Windows Standard-Betracher (stapelverarbeitet) +FILEBROWSER_PARTIALPASTEPROFILE;Profil selektiv einfügen +FILEBROWSER_PASTEPROFILE;Profil einfügen +FILEBROWSER_POPUPCANCELJOB;Job abbrechen +FILEBROWSER_POPUPCOLORLABEL;Farbmarkierung +FILEBROWSER_POPUPCOPYTO;Kopieren nach... +FILEBROWSER_POPUPFILEOPERATIONS;Dateioperationen +FILEBROWSER_POPUPMOVEEND;An das Ende der Warteschlange verschieben +FILEBROWSER_POPUPMOVEHEAD;An den Anfang der Warteschlange verschieben +FILEBROWSER_POPUPMOVETO;Verschieben nach... +FILEBROWSER_POPUPOPENINEDITOR;Im Editor öffnen +FILEBROWSER_POPUPOPEN;Öffnen +FILEBROWSER_POPUPPROCESSFAST;In Warteschlange legen (Schnelles Exportieren) +FILEBROWSER_POPUPPROCESS;In Warteschlange legen +FILEBROWSER_POPUPPROFILEOPERATIONS;Profiloperationen +FILEBROWSER_POPUPRANK;Bewertung +FILEBROWSER_POPUPREMOVEINCLPROC;Löschen (auch Resultate der Stapelverarbeitung) +FILEBROWSER_POPUPREMOVE;Löschen +FILEBROWSER_POPUPRENAME;Umbenennen +FILEBROWSER_POPUPSELECTALL;Alle auswählen +FILEBROWSER_POPUPTRASH;In den Papierkorb verschieben +FILEBROWSER_POPUPUNRANK;Bewertung entfernen +FILEBROWSER_POPUPUNTRASH;Aus dem Papierkorb wiederherstellen +FILEBROWSER_QUERYBUTTONHINT;Nebenstehenden Suchfilter zurücksetzen +FILEBROWSER_QUERYHINT;Nur Dateien anzeigen, deren Namen die angegebene\nZeichenkette beinhalten\nStrg+F (im Dateimanager) zum Setzen des Fokus\nEingabe zum Suchen +FILEBROWSER_QUERYLABEL; Suche: +FILEBROWSER_RANK1_TOOLTIP;Bewertung 1 *\nShift-1 +FILEBROWSER_RANK2_TOOLTIP;Bewertung 2 *\nShift-2 +FILEBROWSER_RANK3_TOOLTIP;Bewertung 3 *\nShift-3 +FILEBROWSER_RANK4_TOOLTIP;Bewertung 4 *\nShift-4 +FILEBROWSER_RANK5_TOOLTIP;Bewertung 5 *\nShift-5 +FILEBROWSER_RENAMEDLGLABEL;Datei umbenennen +FILEBROWSER_RENAMEDLGMSG;Umbenennen der Datei "%1" nach: +FILEBROWSER_SELECTDARKFRAME;Dunkelbild wählen... +FILEBROWSER_SELECTFLATFIELD;Weißbild wählen... +FILEBROWSER_SHOWCOLORLABEL1HINT;Nur rot markierte Bilder anzeigen Alt+1 +FILEBROWSER_SHOWCOLORLABEL2HINT;Nur gelb markierte Bilder anzeigen Alt+2 +FILEBROWSER_SHOWCOLORLABEL3HINT;Nur grün markierte Bilder anzeigen Alt+3 +FILEBROWSER_SHOWCOLORLABEL4HINT;Nur blau markierte Bilder anzeigen Alt+4 +FILEBROWSER_SHOWCOLORLABEL5HINT;Nur violett markierte Bilder anzeigen Alt+5 +FILEBROWSER_SHOWDIRHINT;Nebenstehende Filter zurücksetzen D +FILEBROWSER_SHOWEDITEDHINT;Nur bearbeitete Bilder anzeigen 7 +FILEBROWSER_SHOWEDITEDNOTHINT;Nur unbearbeitete Bilder anzeigen 6 +FILEBROWSER_SHOWEXIFINFO;Bildinformationen ein-/ausblenden I +FILEBROWSER_SHOWRANK1HINT;Nur mit 1 Stern bewertete Bilder anzeigen 1 +FILEBROWSER_SHOWRANK2HINT;Nur mit 2 Sternen bewertete Bilder anzeigen 2 +FILEBROWSER_SHOWRANK3HINT;Nur mit 3 Sternen bewertete Bilder anzeigen 3 +FILEBROWSER_SHOWRANK4HINT;Nur mit 4 Sternen bewertete Bilder anzeigen 4 +FILEBROWSER_SHOWRANK5HINT;Nur mit 5 Sternen bewertete Bilder anzeigen 5 +FILEBROWSER_SHOWRECENTLYSAVEDHINT;Nur kürzlich gespeicherte Bilder anzeigen Alt+7 +FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Nur nicht kürzlich gespeicherte Bilder anzeigen Alt+6 +FILEBROWSER_SHOWTRASHHINT;Inhalt des Papierkorbs anzeigen Strg-t +FILEBROWSER_SHOWUNCOLORHINT;Nur unmarkierte Bilder anzeigen Alt+0 +FILEBROWSER_SHOWUNRANKHINT;Nur unbewertete Bilder anzeigen 0 +FILEBROWSER_STARTPROCESSINGHINT;Verarbeitung/Speichern der Bilder in der Warteschlange starten +FILEBROWSER_STARTPROCESSING;Verarbeitung starten +FILEBROWSER_STOPPROCESSINGHINT;Verarbeitung der Bilder stoppen +FILEBROWSER_STOPPROCESSING;Verarbeitung stoppen +FILEBROWSER_THUMBSIZE;Größe der Vorschau +FILEBROWSER_TOOLTIP_STOPPROCESSING;Bei neuem Job die Verarbeitung automatisch starten +FILEBROWSER_UNRANK_TOOLTIP;Bewertung entfernen\nShift-0 +FILEBROWSER_ZOOMINHINT;Voransichten vergrößern + +FILEBROWSER_ZOOMOUTHINT;Voransichten verkleinern - +GENERAL_ABOUT;Über +GENERAL_AFTER;Nachher +GENERAL_AUTO;Automatisch +GENERAL_BEFORE;Vorher +GENERAL_CANCEL;Abbruch +GENERAL_CLOSE;Schließen +GENERAL_DISABLED;Deaktiviert +GENERAL_DISABLE;Deaktivieren +GENERAL_ENABLED;Aktiv +GENERAL_ENABLE;Aktivieren +GENERAL_FILE;Datei +GENERAL_LANDSCAPE;Quer +GENERAL_NA;n/a +GENERAL_NONE;Keins +GENERAL_NO;Nein +GENERAL_OK;OK +GENERAL_PORTRAIT;Hoch +GENERAL_SAVE;Speichern +GENERAL_UNCHANGED;(Unverändert) +GENERAL_WARNING;Warnung +HISTOGRAM_TOOLTIP_BAR;RGB-Anzeigeleiste ein-/ausblenden\n\nZum Fixieren/Lösen der Anzeige muss mit der rechten Maustaste ins Bildfenster geklickt werden +HISTOGRAM_TOOLTIP_B;Blau-Histogramm ein-/ausblenden +HISTOGRAM_TOOLTIP_CHRO;Chromatizität-Histogramm ein/ausblenden +HISTOGRAM_TOOLTIP_FULL;Skaliertes Histogramm ein/ausschalten +HISTOGRAM_TOOLTIP_G;Grün-Histogramm ein-/ausblenden +HISTOGRAM_TOOLTIP_L;CIELab-Luminanz-Histogramm ein-/ausblenden +HISTOGRAM_TOOLTIP_RAW;Zwischen normalen Histogrammen und\nRAW-Histogrammen umschalten +HISTOGRAM_TOOLTIP_R;Rot-Histogramm ein-/ausblenden +HISTORY_CHANGED;Verändert +HISTORY_CUSTOMCURVE;Benutzerdefinierte Kurve +HISTORY_DELSNAPSHOT;Entf. +HISTORY_FROMCLIPBOARD;Aus der Zwischenablage +HISTORY_LABEL;Historie +HISTORY_MSG_1;Bild geladen +HISTORY_MSG_2;Profil geladen +HISTORY_MSG_3;Profil geändert +HISTORY_MSG_4;Historie durchsehen +HISTORY_MSG_5;Helligkeit +HISTORY_MSG_6;Kontrast +HISTORY_MSG_7;Schwarz +HISTORY_MSG_8;Belichtungskorrektur +HISTORY_MSG_9;Lichter-Kompression +HISTORY_MSG_10;Schatten-Kompression +HISTORY_MSG_11;Tonwertkurve 1 +HISTORY_MSG_12;Automatische Belichtung +HISTORY_MSG_13;Belichtungsbeschneidung +HISTORY_MSG_14;Luminanz Helligkeit +HISTORY_MSG_15;Luminanz Kontrast +HISTORY_MSG_16;Luminanz Schwarz +HISTORY_MSG_17;Luminanz Lichter-Kompression +HISTORY_MSG_18;Luminanz Schatten-Kompression +HISTORY_MSG_19;'L'-Kurve +HISTORY_MSG_20;Schärfung +HISTORY_MSG_21;Unscharfmaskierung\nRadius +HISTORY_MSG_22;Unscharfmaskierung\nStärke +HISTORY_MSG_23;Unscharfmaskierung\nSchwellenwert +HISTORY_MSG_24;Unscharfmaskierung\nNur Kanten +HISTORY_MSG_25;Unscharfmaskierung\nKanten Radius +HISTORY_MSG_26;Unscharfmaskierung\nKanten Toleranz +HISTORY_MSG_27;Unscharfmaskierung\nHalo-Kontrolle +HISTORY_MSG_28;Unscharfmaskierung\nHalo-Kontrolle Stärke +HISTORY_MSG_29;Schärfung Methode +HISTORY_MSG_30;Dekonvolution Radius +HISTORY_MSG_31;Dekonvolution Stärke +HISTORY_MSG_32;Dekonvolution\nDämpfung +HISTORY_MSG_33;Dekonvolution\nIterationen +HISTORY_MSG_34;LCP Verzerrung +HISTORY_MSG_35;LCP Vignettierung +HISTORY_MSG_36;LCP CA +HISTORY_MSG_37;Farbverstärkung +HISTORY_MSG_38;Weißabgleich Methode +HISTORY_MSG_39;Weißabgleich Farbtemp. +HISTORY_MSG_40;Weißabgleich Farbton +HISTORY_MSG_41;Tonewertkurve Modus 1 +HISTORY_MSG_42;Tonwertkurve 2 +HISTORY_MSG_43;Tonewertkurve Modus 2 +HISTORY_MSG_44;Luminanz-Rauschfilter Radius +HISTORY_MSG_45;Luminanz-Rauschfilter Kantentoleranz +HISTORY_MSG_46;Farb-Rauschfilter +HISTORY_MSG_47;ICC Lichter aus Matrix einmischen +HISTORY_MSG_48;DCP Tonwertkurve verwenden +HISTORY_MSG_49;Farb-Rauschfilter Kantensuche +HISTORY_MSG_50;Schatten/Lichter +HISTORY_MSG_51;Lichter abschwächen +HISTORY_MSG_52;Schatten verstärken +HISTORY_MSG_53;Tonweite Lichter +HISTORY_MSG_54;Tonweite Schatten +HISTORY_MSG_55;Lokaler Kontrast +HISTORY_MSG_56;Schatten/Lichter Radius +HISTORY_MSG_57;Grobe Drehung +HISTORY_MSG_58;Horizontal spiegeln +HISTORY_MSG_59;Vertikal spiegeln +HISTORY_MSG_60;Drehung - Grad +HISTORY_MSG_61;Auto-Füllen +HISTORY_MSG_62;Verzeichnungskorrektur +HISTORY_MSG_63;Variante gewählt +HISTORY_MSG_64;Bild beschneiden +HISTORY_MSG_65;Farbsaum entfernen +HISTORY_MSG_66;Lichter wiederherstellen +HISTORY_MSG_67;Lichter wiederherstellen\nStärke +HISTORY_MSG_68;Lichter wiederherstellen\nMethode +HISTORY_MSG_69;Aktueller Farbraum +HISTORY_MSG_70;Farbraum für Ausgabe +HISTORY_MSG_71;Farbraum für Eingabe +HISTORY_MSG_72;Vignettierungskorrektur +HISTORY_MSG_73;Kanal-Mixer +HISTORY_MSG_74;Größe ändern - Maßstab +HISTORY_MSG_75;Größe ändern - Methode +HISTORY_MSG_76;Exif Metadaten +HISTORY_MSG_77;IPTC Metadaten +HISTORY_MSG_78;Angaben für Größenänderung +HISTORY_MSG_79;Größe ändern - Breite +HISTORY_MSG_80;Größe ändern - Höhe +HISTORY_MSG_81;Größe ändern +HISTORY_MSG_82;Profil geändert +HISTORY_MSG_83;Schatten/Lichter\nHohe Qualität +HISTORY_MSG_84;Perspektive - Korrektur +HISTORY_MSG_85;Linsenkorrektur-Profil +HISTORY_MSG_86;Wavelet-Mixer +HISTORY_MSG_87;Impulsrauschminderung +HISTORY_MSG_88;Impulsrauschminderung\nSchwellenwert +HISTORY_MSG_89;Rauschminderung +HISTORY_MSG_90;Rauschminderung\nLuminanz +HISTORY_MSG_91;Rauschminderung\nChrominanz +HISTORY_MSG_92;Rauschminderung\nGamma +HISTORY_MSG_93;Kontrast - Detailstufen\nParameter +HISTORY_MSG_94;Kontrast - Detailstufen +HISTORY_MSG_95;Sättigung +HISTORY_MSG_96;'a'-Kurve +HISTORY_MSG_97;'b'-Kurve +HISTORY_MSG_98;Entrasterung Methode +HISTORY_MSG_99;Hot/Dead-Pixel-Filter +HISTORY_MSG_100;RGB Sättigung +HISTORY_MSG_101;HSV-Equalizer Farbton +HISTORY_MSG_102;HSV-Equalizer Sättigung +HISTORY_MSG_103;HSV-Equalizer Hellwert +HISTORY_MSG_104;HSV-Equalizer +HISTORY_MSG_105;Defringe +HISTORY_MSG_106;Defringe Radius +HISTORY_MSG_107;Defringe Schwellenwert +HISTORY_MSG_108;Lichter-Kompression\nSchwellenwert +HISTORY_MSG_109;Größe ändern\nBegrenzungsrahmen +HISTORY_MSG_110;Größenänderung gilt für +HISTORY_MSG_111;Farbbeschneidungen\nverhindern +HISTORY_MSG_112;Sättigungsbegrenzung +HISTORY_MSG_113;Sättigungsgrenze +HISTORY_MSG_114;DCB-Iterationen +HISTORY_MSG_115;Falschfarben-Iterationen +HISTORY_MSG_116;DCB-Verfeinerung +HISTORY_MSG_117;CA-Korrektur Rot +HISTORY_MSG_118;CA-Korrektur Blau +HISTORY_MSG_119;Zeilenrauschfilter +HISTORY_MSG_120;Grün-Ausgleich +HISTORY_MSG_121;Autom. CA +HISTORY_MSG_122;Autom. Dunkelbild +HISTORY_MSG_123;Dunkelbild - Datei +HISTORY_MSG_124;Belichtungskorrektur\nLinear +HISTORY_MSG_125;Belichtungskorrektur\nLichter bewahren +HISTORY_MSG_126;Weißbild - Datei +HISTORY_MSG_127;Autom. Weißbild +HISTORY_MSG_128;Weißbild Unschärferadius +HISTORY_MSG_129;Weißbild Unschärfetyp +HISTORY_MSG_130;Autom. Verzeichnung +HISTORY_MSG_131;Rauschminderung\nLuminanz +HISTORY_MSG_132;Rauschminderung\nChrominanz +HISTORY_MSG_133;Gamma +HISTORY_MSG_134;Gamma Position +HISTORY_MSG_135;Freies Gamma +HISTORY_MSG_136;Gamma Gradient +HISTORY_MSG_137;Schwarzpegel Grün 1 +HISTORY_MSG_138;Schwarzpegel Rot +HISTORY_MSG_139;Schwarzpegel Blau +HISTORY_MSG_140;Schwarzpegel Grün 2 +HISTORY_MSG_141;Schwarzpegel\nGrün-Werte angleichen +HISTORY_MSG_142;Kantenschärfung\nIterationen +HISTORY_MSG_143;Kantenschärfung\nStärke +HISTORY_MSG_144;Mikrokontrast\nStärke +HISTORY_MSG_145;Mikrokontrast\nGleichmäßigkeit +HISTORY_MSG_146;Kantenschärfung +HISTORY_MSG_147;Kantenschärfung\nNur Luminanz +HISTORY_MSG_148;Mikrokontrast +HISTORY_MSG_149;Mikrokontrast\n3×3-Matrix +HISTORY_MSG_150;Artifakt-/Rauschmind.\nnach Farbinterpolation +HISTORY_MSG_151;Dynamik +HISTORY_MSG_152;Dynamik - Pastelltöne +HISTORY_MSG_153;Dynamik\nGesättigte Töne +HISTORY_MSG_154;Dynamik\nHauttöne schützen +HISTORY_MSG_155;Dynamik - Farbver-\nschiebungen verhindern +HISTORY_MSG_156;Dynamik - Pastellene und\ngesättigte Töne koppeln +HISTORY_MSG_157;Dynamik - Schwellenwert\nPastell / gesättigte Töne +HISTORY_MSG_158;Tone Mapping\nStärke +HISTORY_MSG_159;Tone Mapping\nKantenschutz +HISTORY_MSG_160;Tone Mapping\nFaktor +HISTORY_MSG_161;Tone Mapping\nNeugewichtung +HISTORY_MSG_162;Tone Mapping +HISTORY_MSG_163;RGB-Kurven - R +HISTORY_MSG_164;RGB-Kurven - G +HISTORY_MSG_165;RGB-Kurven - B +HISTORY_MSG_166;Neutrale Belichtung +HISTORY_MSG_167;S&W Tonung +HISTORY_MSG_168;'CC' Kurve +HISTORY_MSG_169;'CH' Kurve +HISTORY_MSG_170;Vibrance - Kurve +HISTORY_MSG_171;'LC' Kurve +HISTORY_MSG_172;LC beschränken auf Rot- und Hauttöne +HISTORY_MSG_173;NR - Leuchtdichte Detail +HISTORY_MSG_174;CIECAM02 +HISTORY_MSG_175;CAM02 - Umfang der chrom. Anpassung +HISTORY_MSG_176;CAM02 - Dunkle Umgebung des Betrachters +HISTORY_MSG_177;CAM02 - Adaptation der Szenen-Luminanz +HISTORY_MSG_178;CAM02 - Adaption der Luminanz des Betrachters +HISTORY_MSG_179;CAM02 - Modell +HISTORY_MSG_180;CAM02 - Rel. Helligkeit (J) +HISTORY_MSG_181;CAM02 - Buntheit (C) +HISTORY_MSG_182;CAM02 - Automatisch CAT02 +HISTORY_MSG_183;CAM02 - Kontrast (J) +HISTORY_MSG_184;CAM02 - Szene in dunkler Umgebung +HISTORY_MSG_185;CAM02 - Gamut Kontrolle +HISTORY_MSG_186;CAM02 - Algorithmus +HISTORY_MSG_187;CAM02 - Rot & Hauttöne schützen +HISTORY_MSG_188;CAM02 - Absolute Helligkeit (Q) +HISTORY_MSG_189;CAM02 - Kontrast (Q) +HISTORY_MSG_190;CAM02 - Sättigung (S) +HISTORY_MSG_191;CAM02 - Farbigkeit (M) +HISTORY_MSG_192;CAM02 - Buntton (Winkel) +HISTORY_MSG_193;CAM02 - Tonwertkurve 1 +HISTORY_MSG_194;CAM02 - Tonwertkurve 2 +HISTORY_MSG_195;CAM02 - Tonwertkurve 1 +HISTORY_MSG_196;CAM02 - Tonwertkurve 2 +HISTORY_MSG_197;CAM02 - Farbkurve +HISTORY_MSG_198;CAM02 - Farbkurve +HISTORY_MSG_199;CAM02 - CIECAM02 Ausgabe-Histogramm als Kurve anzeigen +HISTORY_MSG_200;CAMO2 - Tone mapping mit CIECAM02 Q +HISTORY_MSG_201;NR - Delta Chrominanz Rot +HISTORY_MSG_202;NR - Delta Chrominanz Blau +HISTORY_MSG_203;NR - Methode +HISTORY_MSG_208;Blau/Rot Equalizer +HISTORY_MSG_210;Grauverlauff. - Winkel +HISTORY_MSG_211;Grauverlauffilter +HISTORY_MSG_212;Vignettierungsf. - Stärke +HISTORY_MSG_213;Vignettierungsfilter +HISTORY_MSG_214;SW +HISTORY_MSG_215;SW Kanal-Mixer Rot +HISTORY_MSG_216;SW Kanal-Mixer Grün +HISTORY_MSG_217;SW Kanal-Mixer Blau +HISTORY_MSG_218;SW Rot Gamma +HISTORY_MSG_219;SW Grün Gamma +HISTORY_MSG_220;SW Blau Gamma +HISTORY_MSG_221;SW Farb-Filter +HISTORY_MSG_222;SW Voreinstellung +HISTORY_MSG_230;SW Methode +HISTORY_MSG_235;SW Autom. Kanal-Mixer +HISTORY_MSG_237;SW Kanal-Mixer +HISTORY_MSG_238;Grauverlauff. - Verlauf +HISTORY_MSG_239;Grauverlauff. - Stärke +HISTORY_MSG_240;Grauverlauff. - Rotationsachse +HISTORY_MSG_241;Vignettierungsf. - Verlauf +HISTORY_MSG_242;Vignettierungsf. - Rundheit +HISTORY_MSG_243;Vignett.Korrektur - Radius +HISTORY_MSG_244;Vignett.Korrektur - Faktor +HISTORY_MSG_245;Vignett.Korrektur - Zentrum +HISTORY_MSG_246;'CL' Kurve +HISTORY_MSG_247;'LH' Kurve +HISTORY_MSG_248;'HH' Kurve +HISTORY_MSG_249;Kontrast - Detailstufen Schwellenwert +HISTORY_NEWSNAPSHOT;Hinzuf. +HISTORY_NEWSNAPSHOT_TOOLTIP;Kürzel: Alt-s +HISTORY_SNAPSHOTS;Varianten +HISTORY_SNAPSHOT;Variante +IPTCPANEL_AUTHORSPOSITIONHINT;Titel des Autors oder der Autoren (By-line Title) +IPTCPANEL_AUTHORSPOSITION;Position des\nAutors +IPTCPANEL_AUTHOR;Autor +IPTCPANEL_CAPTIONHINT;Beschreibung des Bildinhaltes (Caption - Abstract) +IPTCPANEL_CAPTIONWRITERHINT;Name der beim Schreiben, Editieren oder Korrigieren des Bildes oder der Bildbeschreibung beteiligten Person (Writer - Editor) +IPTCPANEL_CAPTIONWRITER;Autor der\nBildbeschreibung +IPTCPANEL_CAPTION;Bildbeschreibung +IPTCPANEL_CATEGORYHINT;3-stelliger Code, der die Kategorie des Bildes beschreibt (Category) +IPTCPANEL_CATEGORY;Kategorie +IPTCPANEL_CITYHINT;Aufnahmeort: Stadt (City) +IPTCPANEL_CITY;Stadt +IPTCPANEL_COPYHINT;IPTC-Werte in die Zwischenablage kopieren +IPTCPANEL_COPYRIGHTHINT;Alle nötigen Hinweise zu Urheberrechten (Copyright Notice) +IPTCPANEL_COPYRIGHT;Copyright +IPTCPANEL_COUNTRYHINT;Aufnahmeort: Land (Country - Primary Location Name) +IPTCPANEL_COUNTRY;Land +IPTCPANEL_CREDITHINT;Identifiziert den Anbieter des Bildes, es muss nicht der Eigentümer sein (Credit) +IPTCPANEL_CREDIT;Bildrechte +IPTCPANEL_DATECREATEDHINT;Erstellungsdatum des Bildes; Format: JJJJMMTT (Date Created) +IPTCPANEL_DATECREATED;Erstellt am +IPTCPANEL_EMBEDDEDHINT;Zu den im Bild eingebetteten Werten zurücksetzen +IPTCPANEL_EMBEDDED;Eingebettete +IPTCPANEL_HEADLINEHINT;Kurzform der Bildbeschreibung, könnte als Überschrift an das Bild geklebt werden (Headline) +IPTCPANEL_HEADLINE;Bildtitel +IPTCPANEL_INSTRUCTIONSHINT;Besondere Hinweise bezüglich der Verwendung des Bildes (Special Instructions) +IPTCPANEL_INSTRUCTIONS;Hinweise +IPTCPANEL_KEYWORDSHINT;Stichwörter für das spätere Wiederfinden der Bilder (Keywords) +IPTCPANEL_KEYWORDS;Schlagwörter +IPTCPANEL_PASTEHINT;IPTC-Werte aus der Zwischenablage einfügen +IPTCPANEL_PROVINCEHINT;Aufnahmeort: Provinz (Province-State) +IPTCPANEL_PROVINCE;Provinz +IPTCPANEL_RESETHINT;Zu den im Profil gesetzten Werten zurücksetzen +IPTCPANEL_RESET;Zurücksetzen +IPTCPANEL_SOURCEHINT;Der ursprüngliche Eigentümer des Werkes auf dem Bild (Source) +IPTCPANEL_SOURCE;Quelle +IPTCPANEL_SUPPCATEGORIESHINT;Frei wählbare zusätzliche Kategorien (Supplemental Categories) +IPTCPANEL_SUPPCATEGORIES;Zusätzliche\nKategorien +IPTCPANEL_TITLEHINT;Kurztitel des Bildes (Object Name) +IPTCPANEL_TITLE;Titel +IPTCPANEL_TRANSREFERENCEHINT;Ein Code, der den ursprünglichen Ort der Übertragung definiert (Original Transmission Reference) +IPTCPANEL_TRANSREFERENCE;Übertragungs\nReferenz +MAIN_BUTTON_FULLSCREEN;Vollbild F11 +MAIN_BUTTON_PREFERENCES;Einstellungen +MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Bild in Warteschlange einreihen Strg+Q +MAIN_BUTTON_SAVE_TOOLTIP;Bild speichern Strg+S +MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Bild im externen Editor bearbeiten Strg+E +MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Alle seitlichen Bedienfelder ein-/ausblenden M +MAIN_BUTTON_UNFULLSCREEN;Vollbild beenden F11 +MAIN_FRAME_BATCHQUEUE;Warteschlange +MAIN_FRAME_BATCHQUEUE_TOOLTIP;Warteschlange Strg+F3 +MAIN_FRAME_EDITOR;Editor +MAIN_FRAME_EDITOR_TOOLTIP;Editor Strg+F4 +MAIN_FRAME_FILEBROWSER;Dateiverwaltung +MAIN_FRAME_FILEBROWSER_TOOLTIP;Dateiverwaltung Strg+F2 +MAIN_FRAME_PLACES;Favoriten +MAIN_FRAME_PLACES_ADD;Hinzuf. +MAIN_FRAME_PLACES_DEL;Entf. +MAIN_FRAME_RECENT;Verzeichnishistorie +MAIN_MSG_ALREADYEXISTS;Diese Datei existiert bereits. +MAIN_MSG_CANNOTLOAD;Bild kann nicht geladen werden +MAIN_MSG_CANNOTSAVE;Fehler beim Speichern +MAIN_MSG_CANNOTSTARTEDITOR;Der Editor kann nicht gestartet werden. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Setzen Sie bitte den richtigen Pfad in den Einstellungen. +MAIN_MSG_EMPTYFILENAME;Dateiname fehlt! +MAIN_MSG_IMAGEUNPROCESSED;Für diese Funktion müssen erst alle Bilder stapelverarbeitet sein. +MAIN_MSG_NAVIGATOR;Navigator +MAIN_MSG_QOVERWRITE;Möchten Sie die Datei überschreiben? +MAIN_MSG_WRITEFAILED;Fehler beim Schreiben von\n\n"%1"\n\nStellen Sie sicher, dass das Verzeichnis existiert und dass Sie Schreibrechte besitzen. +MAIN_TAB_COLOR;Farbe +MAIN_TAB_COLOR_TOOLTIP;Alt+C +MAIN_TAB_DETAIL;Detail +MAIN_TAB_DETAIL_TOOLTIP;Alt+D +MAIN_TAB_DEVELOP;Entwickeln +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPORT;Exportieren +MAIN_TAB_EXPOSURE;Belichtung +MAIN_TAB_EXPOSURE_TOOLTIP;Alt+E +MAIN_TAB_FILTER;Metadatenfilter +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadaten +MAIN_TAB_METADATA_TOOLTIP;Alt+M +MAIN_TAB_RAW;RAW +MAIN_TAB_RAW_TOOLTIP;Alt+R +MAIN_TAB_TRANSFORM;Verändern +MAIN_TAB_TRANSFORM_TOOLTIP;Alt+T +MAIN_TOOLTIP_BACKCOLOR0;Hintergrundfarbe der Vorschau: Theme-basierend\nKürzel: 8 +MAIN_TOOLTIP_BACKCOLOR1;Hintergrundfarbe der Vorschau: Schwarz\nKürzel: 9 +MAIN_TOOLTIP_BACKCOLOR2;Hintergrundfarbe der Vorschau: Weiß\nKürzel: 0 +MAIN_TOOLTIP_BEFOREAFTERLOCK;Vorher-Ansicht sperren/entsperren\n\nSperren: Friert die Vorher-Ansicht ein, so dass sich die Gesamtwirkung mehrerer Werkzeuge beurteilen lässt; zudem können Vergleiche zu jedem Stand der Historie angestellt werden\n\nEntsperren: Die Vorher-Ansicht bleibt stets einen Änderungsschritt hinter der Nachher-Ansicht zurück, so dass die Auswirkung des zuletzt angewendeten Werkzeugs ersichtlich wird +MAIN_TOOLTIP_HIDEHP;Linkes Bedienfeld ein-/ausblenden (einschließlich der Historie) L / Strg+L +MAIN_TOOLTIP_INDCLIPPEDH;Anzeige zu heller Bereiche ein-/ausschalten <\n\nNur Windows: Alternativ kann während Betätigung eines\nSchiebereglers die Alt-Taste gedrückt gehalten werden +MAIN_TOOLTIP_INDCLIPPEDS;Anzeige zu dunkler Bereiche ein-/ausschalten >\n\nNur Windows: Alternativ kann während Betätigung eines\nSchiebereglers die Alt-Taste gedrückt gehalten werden +MAIN_TOOLTIP_PREVIEWB;Vorschau Blau-Kanal B +MAIN_TOOLTIP_PREVIEWFOCUSMASK;Vorschau Fokussiermaske Umschalt+F\n\nPräziser bei Bildern mit geringer Tiefenschärfe, niedrigem Rauschen und bei hoher Vergrößerung; zur Verbesserung der Erkennungsgenauigkeit bei verrauschten Bildern sollte ein kleiner Zoom (10-30 %) gewählt werden\n\nBei eingeschalteter Fokussiermaske dauert der Aufbau der Vorschau länger +MAIN_TOOLTIP_PREVIEWG;Vorschau Grün-Kanal G +MAIN_TOOLTIP_PREVIEWL;Vorschau Helligkeit V\n\n0.299·R + 0.587·G + 0.114·B +MAIN_TOOLTIP_PREVIEWR;Vorschau Rot-Kanal R +MAIN_TOOLTIP_QINFO;Bildinformationen ein-/ausblenden I +MAIN_TOOLTIP_SHOWHIDELP1;Linkes Bedienfeld ein-/ausblenden L / Strg+L +MAIN_TOOLTIP_SHOWHIDERP1;Rechtes Bedienfeld ein-/ausblenden Alt+L +MAIN_TOOLTIP_SHOWHIDETP1;Oberes Bedienfeld ein-/ausblenden Umschalt+L +MAIN_TOOLTIP_THRESHOLD;Schwellenwert +MAIN_TOOLTIP_TOGGLE;Vorher/Nachher-Ansicht ein-/ausschalten Umschalt+B +NAVIGATOR_XY_FULL;Breite = %1, Höhe = %2 +NAVIGATOR_XY_NA;x = k.a., y = k.a. +OPTIONS_DEFIMG_MISSING;Die Standard-Profile für nicht-Raw Photos wurden nicht gefunden oder nicht gesetzt.\n\nBitte prüfen Sie das Profil-Verzeichnis, es fehlt möglicherweise oder ist beschädigt.\n\nEs werden stattdessen interne Standardwerte verwendet. +OPTIONS_DEFRAW_MISSING;Die Standard-Profile für Raw Photos wurden nicht gefunden oder nicht gesetzt.\n\nBitte prüfen Sie das Profil-Verzeichnis, es fehlt möglicherweise oder ist beschädigt.\n\nEs werden stattdessen interne Standardwerte verwendet. +PARTIALPASTE_BASICGROUP;Gruppe Basiseinstellungen +PARTIALPASTE_CACORRECTION;Farbsaum entfernen +PARTIALPASTE_CHANNELMIXER;Kanal-Mixer +PARTIALPASTE_COARSETRANS;Drehen / Spiegeln +PARTIALPASTE_COLORAPP;CIE Color Appearance Model 2002 +PARTIALPASTE_COLORGROUP;Gruppe Farbeinstellungen +PARTIALPASTE_COMMONTRANSFORMPARAMS;Auto-Füllen +PARTIALPASTE_COMPOSITIONGROUP;Gruppe Gestaltungseinstellungen +PARTIALPASTE_CROP;Ausschnitt +PARTIALPASTE_DARKFRAMEAUTOSELECT;Dunkelbild: Automatische Auswahl +PARTIALPASTE_DARKFRAMEFILE;Dunkelbild: Datei +PARTIALPASTE_DEFRINGE;Defringe +PARTIALPASTE_DETAILGROUP;Gruppe Detaileinstellungen +PARTIALPASTE_DIALOGLABEL;Selektives Einfügen des Bearbeitungsprofils +PARTIALPASTE_DIRPYRDENOISE;Rauschminderung +PARTIALPASTE_DIRPYREQUALIZER;Kontrast nach Detailstufen +PARTIALPASTE_DISTORTION;Verzeichnungskorrektur +PARTIALPASTE_EPD;Tone Mapping +PARTIALPASTE_EVERYTHING;Alles +PARTIALPASTE_EXIFCHANGES;Änderungen an Exif-Daten +PARTIALPASTE_EXPOSURE;Belichtung +PARTIALPASTE_FLATFIELDAUTOSELECT;Weißbild: Automatische Auswahl +PARTIALPASTE_FLATFIELDBLURRADIUS;Weißbild: Unschärferadius +PARTIALPASTE_FLATFIELDBLURTYPE;Weißbild: Unschärfetyp +PARTIALPASTE_FLATFIELDFILE;Weißbild: Datei +PARTIALPASTE_GRADIENT;Grauverlauffilter +PARTIALPASTE_HSVEQUALIZER;HSV-Equalizer +PARTIALPASTE_ICMGAMMA;Ausgabe-Gamma +PARTIALPASTE_ICMSETTINGS;ICM-Einstellungen +PARTIALPASTE_IMPULSEDENOISE;Impulsrauschminderung +PARTIALPASTE_IPTCINFO;IPTC-Informationen +PARTIALPASTE_LABCURVE;Lab-Anpassungen +PARTIALPASTE_LENSGROUP;Gruppe Objektivkorrekturen +PARTIALPASTE_LENSPROFILE;Linsen-Korrekturprofil +PARTIALPASTE_METAGROUP;Gruppe Metadaten +PARTIALPASTE_PCVIGNETTE;Vignettierungsfilter +PARTIALPASTE_PERSPECTIVE;Perspektive +PARTIALPASTE_PREPROCESS_DEADPIXFILT;Vorverarbeitung: Dead-Pixel-Filter +PARTIALPASTE_PREPROCESS_GREENEQUIL;Vorverarbeitung: Grün-Ausgleich +PARTIALPASTE_PREPROCESS_HOTPIXFILT;Vorverarbeitung: Hot-Pixel-Filter +PARTIALPASTE_PREPROCESS_LINEDENOISE;Vorverarbeitung: Zeilenrauschfilter +PARTIALPASTE_RAWCACORR_AUTO;Chromatische Aberration: Automatische Korrektur +PARTIALPASTE_RAWCACORR_CABLUE;Chromatische Aberration: Blau +PARTIALPASTE_RAWCACORR_CARED;Chromatische Aberration: Rot +PARTIALPASTE_RAWEXPOS_BLACK;RAW-Weiß/Schwarz-Punkt: Schwarzpegel +PARTIALPASTE_RAWEXPOS_LINEAR;RAW-Weiß/Schwarz-Punkt: Linearer Korrekturfaktor +PARTIALPASTE_RAWEXPOS_PRESER;RAW-Weiß/Schwarz-Punkt: Lichter bewahren (EV) +PARTIALPASTE_RAWGROUP;Gruppe RAW +PARTIALPASTE_RAW_DCBENHANCE;Farbinterpolation: DCB-Verfeinerungsschritt +PARTIALPASTE_RAW_DCBITERATIONS;Farbinterpolation: Anzahl der DCB-Iterationen +PARTIALPASTE_RAW_DMETHOD;Farbinterpolation: Methode +PARTIALPASTE_RAW_FALSECOLOR;Farbinterpolation: Falschfarbenunterdrückung Stufen +PARTIALPASTE_RESIZE;Größe ändern +PARTIALPASTE_RGBCURVES;RGB-Kurven +PARTIALPASTE_ROTATION;Fein-Rotation +PARTIALPASTE_SHADOWSHIGHLIGHTS;Schatten/Lichter +PARTIALPASTE_SHARPENEDGE;Kantenschärfung +PARTIALPASTE_SHARPENING;Schärfung +PARTIALPASTE_SHARPENMICRO;Mikrokontrast +PARTIALPASTE_VIBRANCE;Dynamik +PARTIALPASTE_VIGNETTING;Vignettierungskorrektur +PARTIALPASTE_WHITEBALANCE;Weißabgleich +PREFERENCES_ADD;HINZU +PREFERENCES_APPLNEXTSTARTUP;erfordert Neustart +PREFERENCES_AUTOMONPROFILE;Autom. das für den aktuellen Monitor festgelegte Profil verwenden +PREFERENCES_BATCH_PROCESSING;Stapelverarbeitung +PREFERENCES_BEHAVIOR;Verhalten +PREFERENCES_BLACKBODY;Wolfram +PREFERENCES_CACHECLEARALL;Alles löschen +PREFERENCES_CACHECLEARPROFILES;Profile löschen +PREFERENCES_CACHECLEARTHUMBS;Voransichten löschen +PREFERENCES_CACHEMAXENTRIES;Höchstzahl der Einträge im Zwischenspeicher +PREFERENCES_CACHEOPTS;Einstellungen des Zwischenspeichers für Voransichten (Cache) +PREFERENCES_CACHETHUMBHEIGHT;Maximale Höhe der Voransichten +PREFERENCES_CIEART;CIECAM02 Optimierung +PREFERENCES_CIEART_LABEL;Einfache statt doppelte Genauigkeit +PREFERENCES_CIEART_TOOLTIP;Wenn aktiviert, werden CIECAM02-Berechnungen mit einfacher Genauigkeit statt doppelter durchgeführt. Dadurch wird der Vorgang etwas beschleunigt, die Qualität nimmt jedoch geringfügig ab. +PREFERENCES_CLIPPINGIND;Anzeige zu heller/dunkler Bereiche +PREFERENCES_CMETRICINTENT;Farbraumtransformation +PREFERENCES_CUSTPROFBUILDHINT;Anwendung (oder Skript) zur Erzeugung eines neuen Profils für ein Bild. Folgende Kommandozeilenparameter zur regelbasierten *.PP3-Erzeugung werden übergeben:\n[Pfad RAW/JPEG] [Pfad vorgegebenes Profil] [Blende] [Belichtungszeit in s] [Brennweite in mm] [ISO] [Objektiv] [Kamera] +PREFERENCES_CUSTPROFBUILDPATH;Anwendungspfad +PREFERENCES_CUSTPROFBUILD;Benutzerdefinierter Bildprofilgenerator +PREFERENCES_CUTOVERLAYBRUSH;Farbe/Transparenz für Schnittmaske +PREFERENCES_D50;5000K +PREFERENCES_D55;5500K +PREFERENCES_D60;6000K +PREFERENCES_D65;6500K +PREFERENCES_DARKFRAMEFOUND;Gefunden +PREFERENCES_DARKFRAMESHOTS;Aufnahmen +PREFERENCES_DARKFRAMETEMPLATES;Vorlagen +PREFERENCES_DARKFRAME;Dunkelbild +PREFERENCES_DATEFORMATHINT;Die folgenden Variablen können verwendet werden:\n%y : Jahr\n%m : Monat\n%d : Tag\n\nBeispiele:\n%d.%m.%y (übliche deutsche Datumsschreibweise)\n%y-%m-%d (Datumsformat nach ISO 8601 und EN 28601) +PREFERENCES_DATEFORMAT;Format +PREFERENCES_DEFAULTLANG;Sprache für Menüs und Dialoge +PREFERENCES_DEFAULTTHEME;Standard-Oberflächendesign +PREFERENCES_DIRDARKFRAMES;Dunkelbild-Verzeichnis +PREFERENCES_DIRHOME;Benutzer-Verzeichnis +PREFERENCES_DIRLAST;Zuletzt geöffnetes Verzeichnis +PREFERENCES_DIROTHER;Anderes +PREFERENCES_DIRSELECTDLG;Wähle das Bild-Verzeichnis beim Programmstart... +PREFERENCES_DIRSOFTWARE;Installationsverzeichnis +PREFERENCES_EDITORCMDLINE;Befehlszeile +PREFERENCES_EDITORLAYOUT;Editor-Layout +PREFERENCES_EXTERNALEDITOR;Externer Editor +PREFERENCES_FBROWSEROPTS;Bildinformationen und Voransichten +PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Einzeilige Werkzeugleiste in Dateiverwaltung (Bei geringer Bildschirmauflösung deaktivieren) +PREFERENCES_FILEFORMAT;Dateiformat +PREFERENCES_FLATFIELDFOUND;Gefunden +PREFERENCES_FLATFIELDSDIR;Weißbild-Verzeichnis +PREFERENCES_FLATFIELDSHOTS;Aufnahmen +PREFERENCES_FLATFIELDTEMPLATES;Vorlagen +PREFERENCES_FLATFIELD;Weißbild +PREFERENCES_FLUOF2;Fluoreszenz F2 +PREFERENCES_FLUOF7;Fluoreszenz F7 +PREFERENCES_FLUOF11;Fluoreszenz F11 +PREFERENCES_FORIMAGE;Für Bilddateien +PREFERENCES_FORRAW;Für RAW-Dateien +PREFERENCES_GIMPPATH;GIMP Installationsverzeichnis +PREFERENCES_GREY05;Yb=05 CIE L#30 +PREFERENCES_GREY10;Yb=10 CIE L#40 +PREFERENCES_GREY15;Yb=15 CIE L#45 +PREFERENCES_GREY18;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_GREY;Yb Helligkeit (%) des Ausgabegerätes +PREFERENCES_HISTOGRAMPOSITIONLEFT;Histogramm linksseitig +PREFERENCES_HLTHRESHOLD;Schwellenwert - zu hell +PREFERENCES_ICCDIR;ICC-Profile-Verzeichnis +PREFERENCES_IMPROCPARAMS;Standard-Bildbearbeitungsparameter +PREFERENCES_INTENT_ABSOLUTE;Absolut farbmetrisch +PREFERENCES_INTENT_PERCEPTUAL;Wahrnehmungsabhängig +PREFERENCES_INTENT_RELATIVE;Relativ farbmetrisch +PREFERENCES_INTENT_SATURATION;Sättigung +PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Voransicht aus RAW, wenn noch nicht editiert +PREFERENCES_LANGAUTODETECT;Betriebssystem-Einstellung verwenden +PREFERENCES_MENUGROUPEXTPROGS;Untermenü "Öffnen mit" +PREFERENCES_MENUGROUPFILEOPERATIONS;Untermenü Dateioperationen +PREFERENCES_MENUGROUPLABEL;Untermenü Farbmarkierung +PREFERENCES_MENUGROUPPROFILEOPERATIONS;Untermenü Profiloperationen +PREFERENCES_MENUGROUPRANK;Untermenü Bewertung +PREFERENCES_MENUOPTIONS;Menüoptionen +PREFERENCES_METADATA;Metadaten +PREFERENCES_MONITORICC;Monitor-Profil +PREFERENCES_MULTITABDUALMON;Multi-Reiter Modus (auf zweitem Monitor, wenn verfügbar) +PREFERENCES_MULTITAB;Multi-Reiter Modus +PREFERENCES_OUTDIRFOLDERHINT;Alle erzeugten Dateien in dem angegebenen Verzeichnis ablegen +PREFERENCES_OUTDIRFOLDER;Im Verzeichnis speichern +PREFERENCES_OUTDIRTEMPLATEHINT;Erzeugte Dateien gemäß Vorlage benennen und ablegen.\n\nDie folgenden Variablen können verwendet werden:\n%d1, %d2, ..., %f, %p1, %p2, ..., %r\n\nDiese Variablen beinhalten bestimmte Teile des Verzeichnispfades, in welchem sich ein Bild befindet, oder Attribute des Bildes.\n\nWenn zum Beispiel /home/tom/photos/2010-10-31/dsc0042.nef geöffnet wurde, dann haben die Variablen den folgenden Inhalt:\n%d4 = home\n%d3 = tom\n%d2 = photos\n%d1 = 2010-10-31\n%f = dsc0042\n%p1 = /home/tom/photos/2010-10-31\n%p2 = /home/tom/photos\n%p3 = /home/tom\n%p4 = /home\n\nWenn Sie die Ausgabedatei in dasselbe Verzeichnis wie das Originalbild speichern wollen, dann wählen Sie:\n%p1/%f\n\nWenn Sie die Ausgabedatei in ein Unterverzeichnis mit dem Namen "converted" schreiben wollen, dann wählen Sie:\n%p1/converted/%f\n\nWenn Sie die Ausgabedatei im Verzeichnispfad "/home/tom/photos/converted" speichern wollen, dort jedoch in einem mit dem Namen des Ursprungsverzeichnisses betitelten Unterverzeichnis, dann wählen Sie:\n%p2/converted/%d1/%f\n\nDie Variable %r enthält die Bewertung des Bildes; ihr Inhalt ist für unbewertete Bilder "0", für in den Papierkorb verschobene Bilder "x" und ansonsten - entsprechend der Anzahl der Sterne - eine Ziffer zwischen "1" und "5". +PREFERENCES_OUTDIRTEMPLATE;Vorlage verwenden +PREFERENCES_OUTDIR;Ausgabeverzeichnis +PREFERENCES_OVERLAY_FILENAMES;Dateiname und Informationen überlagert über Bild +PREFERENCES_OVERWRITEOUTPUTFILE;Bestehende Ausgabedateien überschreiben +PREFERENCES_PANFACTORLABEL;Schrittweite +PREFERENCES_PARSEDEXTADDHINT;Nebenstehenden Dateityp (Extension) der obigen Liste hinzufügen +PREFERENCES_PARSEDEXTADD;Dateityp\nhinzufügen +PREFERENCES_PARSEDEXTDELHINT;Markierten Dateityp aus Liste entfernen +PREFERENCES_PARSEDEXT;Angezeigte Dateitypen +PREFERENCES_PROFILEHANDLING;Behandlung der Bearbeitungsprofile +PREFERENCES_PROFILELOADPR;Priorität der Profile beim Laden +PREFERENCES_PROFILEPRCACHE;Bearbeitungsprofil im Zwischenspeicher (Cache) +PREFERENCES_PROFILEPRFILE;Bearbeitungsprofil, welches geladener Datei beiliegt (Sidecar) +PREFERENCES_PROFILESAVECACHE;Verarbeitungsparameter im Zwischenspeicher speichern (Cache) +PREFERENCES_PROFILESAVEINPUT;Verarbeitungsparameter zusammen mit Datei speichern (Sidecar) +PREFERENCES_PROPERTY;Eigenschaft +PREFERENCES_PSPATH;Adobe Photoshop Installationsverzeichnis +PREFERENCES_RGBDTL_LABEL;Max. Anzahl Threads für Rauschminderung +PREFERENCES_RGBDTL_TOOLTIP;Die Rauschminderung benötigt mindestens 128MB RAM für ein 10 Megapixel-Bild oder 512MB für ein 40 Megapixel-Bild, und zusätzlich 128MB RAM pro Thread. Je mehr Threads parallel ablaufen, desto schneller ist die Berechnung. Bei Einstellung "0" werden so viele Threads wie möglich benutzt. +PREFERENCES_SELECTFONT;Schriftart +PREFERENCES_SELECTLANG;Sprache +PREFERENCES_SELECTTHEME;Oberflächendesign +PREFERENCES_SET;SETZEN +PREFERENCES_SHOWBASICEXIF;Exif-Daten anzeigen +PREFERENCES_SHOWDATETIME;Datum und Uhrzeit anzeigen +PREFERENCES_SHOWEXPOSURECOMPENSATION;Belichtungskorrektur anfügen +PREFERENCES_SHTHRESHOLD;Schwellenwert - zu dunkel +PREFERENCES_SINGLETABVERTAB;Ein-Reiter Modus (vertikale Reiter) +PREFERENCES_SINGLETAB;Ein-Reiter Modus +PREFERENCES_SLIMUI;Kompakte Oberfläche +PREFERENCES_SND_BATCHQUEUEDONE;Warteschlange abgearbeitet +PREFERENCES_SND_HELP;Entweder Dateipfad eingeben oder nichts (falls kein Systemklang gewünscht).\nUnter Windows "SystemDefault", "SystemAsterisk" usw. für Systemklänge verwenden. +PREFERENCES_SND_LNGEDITPROCDONE;Bearbeitung abgeschlossen +PREFERENCES_SND_TRESHOLDSECS;nach (s) +PREFERENCES_STARTUPIMDIR;Bildverzeichnis beim Programmstart +PREFERENCES_TAB_BROWSER;Dateiverwaltung +PREFERENCES_TAB_COLORMGR;Farbmanagement +PREFERENCES_TAB_GENERAL;Allgemein +PREFERENCES_TAB_IMPROC;Bildbearbeitung +PREFERENCES_TAB_PERFORMANCE;Performance +PREFERENCES_TAB_SOUND;Systemklänge +PREFERENCES_TP_LABEL;Werkzeugbereich: +PREFERENCES_TP_USEICONORTEXT;Symbole statt Text in Karteireitern +PREFERENCES_TP_VSCROLLBAR;Keine vertikale Laufleiste +PREFERENCES_TUNNELMETADATA;IPTC/XMP unverändert in Ausgabedatei kopieren (falls Tagging mittels anderer Software) +PREFERENCES_USESYSTEMTHEME;Systemoberfläche +PREFERENCES_VIEW;Weißabgleich-Einstellung des Ausgabegerätes (Monitor, TV, Projektor, usw.) +PREFERENCES_WORKFLOW;Layout +PROFILEPANEL_COPYPPASTE;Zu kopierende Parameter +PROFILEPANEL_LABEL;Bearbeitungsprofile +PROFILEPANEL_LOADDLGLABEL;Bearbeitungsprofil laden... +PROFILEPANEL_LOADPPASTE;Zu ladende Parameter +PROFILEPANEL_PASTEPPASTE;Einzufügende Parameter +PROFILEPANEL_PCUSTOM;Benutzerdefiniert +PROFILEPANEL_PFILE;Aus Datei +PROFILEPANEL_PLASTSAVED;Zuletzt gespeichert +PROFILEPANEL_SAVEDLGLABEL;Bearbeitungsprofil speichern... +PROFILEPANEL_SAVEPPASTE;Zu speichernde Parameter +PROFILEPANEL_TOOLTIPCOPY;Profil in Zwischenablage kopieren\n\nStrg-Taste beim Anklicken gedrückt halten,\num zu kopierende Parameter auszuwählen +PROFILEPANEL_TOOLTIPLOAD;Profil aus Datei laden\n\nStrg-Taste beim Anklicken gedrückt halten,\num zu ladende Parameter auszuwählen +PROFILEPANEL_TOOLTIPPASTE;Profil aus Zwischenablage einfügen\n\nStrg-Taste beim Anklicken gedrückt halten,\num einzufügende Parameter auszuwählen +PROFILEPANEL_TOOLTIPSAVE;Profil speichern\n\nStrg-Taste beim Anklicken gedrückt halten,\num zu speichernde Parameter auszuwählen +PROGRESSBAR_LOADINGTHUMBS;Lade Voransichten... +PROGRESSBAR_LOADING;Lade Bild... +PROGRESSBAR_LOADJPEG;Lade JPEG... +PROGRESSBAR_LOADPNG;Lade PNG... +PROGRESSBAR_LOADTIFF;Lade TIFF... +PROGRESSBAR_PROCESSING;Berechne Bild... +PROGRESSBAR_PROCESSING_PROFILESAVED;Verarbeitungsprofil gespeichert +PROGRESSBAR_READY;Bereit +PROGRESSBAR_SAVEJPEG;Speichere JPEG... +PROGRESSBAR_SAVEPNG;Speichere PNG... +PROGRESSBAR_SAVETIFF;Speichere TIFF... +PROGRESSBAR_SNAPSHOT_ADDED;Schnappschuss hinzugefügt +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profil wurde im Browser geändert +QINFO_ISO;ISO +QINFO_NOEXIF;Keine Exif-Daten vorhanden. +SAVEDLG_AUTOSUFFIX;Suffix anfügen, falls unter dem Namen bereits eine Datei existiert +SAVEDLG_FILEFORMAT;Dateiformat +SAVEDLG_JPEGQUAL;JPEG-Qualität +SAVEDLG_PNGCOMPR;PNG-Kompression +SAVEDLG_PUTTOQUEUEHEAD;An den Anfang der Warteschlange für Verarbeitung legen +SAVEDLG_PUTTOQUEUETAIL;An das Ende der Warteschlange für Verarbeitung legen +SAVEDLG_PUTTOQUEUE;In Warteschlange für Verarbeitung legen +SAVEDLG_SAVEIMMEDIATELY;Sofort speichern +SAVEDLG_SAVESPP;Prozessparameter mit dem Bild speichern +SAVEDLG_SUBSAMP;Subsampling +SAVEDLG_SUBSAMP_1;Beste Kompression +SAVEDLG_SUBSAMP_2;Ausbalanciert +SAVEDLG_SUBSAMP_3;Beste Qualität +SAVEDLG_SUBSAMP_TOOLTIP;Beste Kompression: 4:1:1\nAusbalanciert: 4:2:2\nBeste Qualität: 4:4:4 +SAVEDLG_TIFFUNCOMPRESSED;Uncompressed TIFF +SAVEDLG_WARNFILENAME;Die Datei wird gespeichert als +SHCSELECTOR_TOOLTIP;Um die 3 Regler zurückzusetzen, rechte Maustaste klicken +THRESHOLDSELECTOR_BL;unten-links +THRESHOLDSELECTOR_BR;unten-rechts +THRESHOLDSELECTOR_B;unten +THRESHOLDSELECTOR_HINT;Shift-Taste halten, um individuelle Kontrollpunkte zu verschieben. +THRESHOLDSELECTOR_TL;oben-links +THRESHOLDSELECTOR_TR;oben-rechts +THRESHOLDSELECTOR_T;oben +TOOLBAR_TOOLTIP_CROP;Ausschnitt wählen C\n\nZum Verschieben des Ausschnitts muss die Umschalttaste gedrückt gehalten werden +TOOLBAR_TOOLTIP_HAND;Hand-Werkzeug H +TOOLBAR_TOOLTIP_STRAIGHTEN;Ausrichten / Fein-Rotation S\n\nRichtet das Bild entlang einer Leitlinie aus; der Drehwinkel wird neben der Leitlinie angezeigt, die Drehung erfolgt um die Bildmitte +TOOLBAR_TOOLTIP_WB;Weißabgleich manuell setzen W +TP_BWMIX_CC_ENABLED;Komplemantärfarbe anpassen +TP_BWMIX_CC_TOOLTIP;Aktiviert die automatische Anpassung der Komplementärfarbe im ROYGCBPM-Modus +TP_BWMIX_CHANNEL;Luminanz Equalizer +TP_BWMIX_FILTER;FarbFilter +TP_BWMIX_FILTER_BLUEGREEN;Blau-Grün +TP_BWMIX_FILTER_BLUE;Blau +TP_BWMIX_FILTER_GREENYELLOW;Grün-Gelb +TP_BWMIX_FILTER_GREEN;Grün +TP_BWMIX_FILTER_NONE;Keiner +TP_BWMIX_FILTER_PURPLE;Violett +TP_BWMIX_FILTER_REDYELLOW;Rot-Gelb +TP_BWMIX_FILTER_RED;Rot +TP_BWMIX_FILTER_TOOLTIP;Farbfilter simulieren Aufnahmen mit einem auf dem Objektiv montierten farbigen Filter. Farbfilter reduzieren die Durchlässigkeit für einen speziellen Farbbereich und verändern dementsprechend die Helligkeit in diesem Bereich. z.B. verdunkelt ein Rotfilter bauen Himmel. +TP_BWMIX_FILTER_YELLOW;Gelb +TP_BWMIX_GAMMA;Gamma-Korrektur +TP_BWMIX_GAM_TOOLTIP;Korrigiere Gamma für einzelne RGB-Kanäle +TP_BWMIX_LABEL;Schwarzweiß +TP_BWMIX_MET;Methode +TP_BWMIX_MET_CHANMIX;Kanal-Mixer +TP_BWMIX_MET_DESAT;Entsättigung +TP_BWMIX_MET_LUMEQUAL;Luminanz Equalizer +TP_BWMIX_MIXC;Mixer +TP_BWMIX_NEUTRAL;Mixer zurücksetzen +TP_BWMIX_SETTING;Voreinstellung +TP_BWMIX_SETTING_TOOLTIP;Verschiedene Voreinstellungen (Filmtypen, Landschaft, ...) oder benutzerdefinierte Einstellungen des Kanal-Mixers +TP_BWMIX_SET_HIGHCONTAST;Hoher Kontrast +TP_BWMIX_SET_HIGHSENSIT;Hohe Empfindlichkeit +TP_BWMIX_SET_HYPERPANCHRO;Hyper Panchromatisch +TP_BWMIX_SET_INFRARED;Infrarot +TP_BWMIX_SET_LANDSCAPE;Landschaft +TP_BWMIX_SET_LOWSENSIT;Niedrige Empfindlichkeit +TP_BWMIX_SET_LUMINANCE;Luminanz +TP_BWMIX_SET_NORMCONTAST;Normaler Kontrast +TP_BWMIX_SET_ORTHOCHRO;Orthochromatisch +TP_BWMIX_SET_PANCHRO;Panchromatisch +TP_BWMIX_SET_PORTRAIT;Portrait +TP_BWMIX_TCMODE_FILMLIKE;SW Film-ähnlich +TP_BWMIX_TCMODE_STANDARD;SW Standard +TP_BWMIX_TCMODE_WEIGHTEDSTD;SW Standard gewichtet +TP_CACORRECTION_BLUE;Blau +TP_CACORRECTION_LABEL;Farbsaum entfernen +TP_CACORRECTION_RED;Rot +TP_CHMIXER_BLUE;Blau-Kanal +TP_CHMIXER_GREEN;Grün-Kanal +TP_CHMIXER_LABEL;Kanal-Mixer +TP_CHMIXER_RED;Rot-Kanal +TP_CHROMATABERR_LABEL;Chromatische Aberration +TP_COARSETRAF_TOOLTIP_HFLIP;Horizontal spiegeln +TP_COARSETRAF_TOOLTIP_ROTLEFT;Nach links drehen [ +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Nach rechts drehen ] +TP_COARSETRAF_TOOLTIP_VFLIP;Vertikal spiegeln +TP_COLORAPP_ADAPTSCENE;Adaptation Szenen-Leuchtstärke (cd/m²) +TP_COLORAPP_ADAPTSCENE_TOOLTIP;Absolute Luminanz der Szenen-Umgebung\n(normalerweise 2000cd/m²) +TP_COLORAPP_ADAPTVIEWING;Adaptation Betrachungs-Leuchtstärke (cd/m²) +TP_COLORAPP_ADAPTVIEWING_TOOLTIP;Absolute Luminanz der Betrachtungs-Umgebung\n(normalerweise 16cd/m²) +TP_COLORAPP_ALGO;Algorithmus +TP_COLORAPP_ALGO_ALL;Alle +TP_COLORAPP_ALGO_JC;Helligkeit + Chroma (JC) +TP_COLORAPP_ALGO_JS;Helligkeit+ Sättigung (JS) +TP_COLORAPP_ALGO_QM;Helligkeit + Buntheit (QM) +TP_COLORAPP_ALGO_TOOLTIP;Auswahl zwischen Parameter-Teilmengen und allen Parametern +TP_COLORAPP_BRIGHT;Helligkeit (Q) +TP_COLORAPP_BRIGHT_TOOLTIP;Helligkeit in CIECAM02 berücksichtigt die Weiß-Intensität und unterscheidet sich von Lab und RGB-Helligkeit +TP_COLORAPP_CHROMA;Chroma (C) +TP_COLORAPP_CHROMA_M;Buntheit (M) +TP_COLORAPP_CHROMA_M_TOOLTIP;Buntheit in CIECAM02 unterscheidet sich von Lab und RGB Buntheit +TP_COLORAPP_CHROMA_S;Sättigung (S) +TP_COLORAPP_CHROMA_S_TOOLTIP;Sättigung in CIECAM02 unterscheidet sich von Lab und RGB Sättigung +TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 unterscheidet sich von Lab und RGB Chroma +TP_COLORAPP_CIECAT_DEGREE;CAT02 Adaptation +TP_COLORAPP_CONTRAST;Kontrast (J) +TP_COLORAPP_CONTRAST_Q;Kontrast (Q) +TP_COLORAPP_CONTRAST_Q_TOOLTIP;Kontrast in CIECAM02 des Q Reglers; unterscheidet sich von Lab und RGB Kontrast +TP_COLORAPP_CONTRAST_TOOLTIP;Kontrast in CIECAM02 des J Reglers; unterscheidet sich von Lab und RGB Kontrast +TP_COLORAPP_CURVEEDITOR1;Tonwertkurve 1 +TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Zeigt das Histogramm von L (Lab) vor CIECAM02.\nWenn "CIECAM02 Ausgabe-Histogramm als Kurve anzeigen" aktiviert ist, wird das Histogramm von J oder Q (nach CIECAM02) angezeigt.\n\nJ und Q werden nicht im Haupt-Histogramm angezeigt.\nFür die endgültige Ausgabe verwenden Sie das Haupt-Histogramm. +TP_COLORAPP_CURVEEDITOR2;Tonwertkurve 2 +TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Gleiche Verwendung wie bei dir zweiten Belichtungs-Tonwertkurve. +TP_COLORAPP_CURVEEDITOR3;Farbkurve +TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Korrigiert entweder Chroma, Sättigung oder Farbigkeit.\n\nZeigt das Histogramm der Chromatizität (Lab) vor CIECAM02.\nWenn "CIECAM02 Ausgabe-Histogramm als Kurve anzeigen" aktiviert ist, wird das Histogramm von C, S oder M (nach CIECAM02) angezeigt.\n\nC, S und M werden nicht im Haupt-Histogramm angezeigt.\nFür die endgültige Ausgabe verwenden Sie das Haupt-Histogramm. +TP_COLORAPP_DATACIE;CIECAM02 Ausgabe-Histogramm als Kurve anzeigen +TP_COLORAPP_DATACIE_TOOLTIP;Wenn aktiviert, zeigen die Histogramme für CIECAM02 Kurven die angenäherten Werte/Bereiche für J oder Q, und C, S oder M nach den CIECAM02 Anpassungen.\nDiese Auswahl betrifft nicht das Haupt-Histogramm.\n\nWenn deaktiviert, zeigen die Histogramme für CIECAM02 Kurven die Lab Werte vor CIECAM02 Anpassungen. +TP_COLORAPP_DEGREE_AUTO_TOOLTIP;Wenn aktiviert (emfohlen), berechnet RT einen optimalen Wert der von CAT02 verwendet wird sowie für CIECAM02.\nUm den Wert manuell zu setzen, muss die Option deaktiviert sein (Werte über 64 sind empfohlen). +TP_COLORAPP_DEGREE_TOOLTIP;Umfang der CIE Chromatic Adaptation Transform 2002 +TP_COLORAPP_GAMUT;Gamut Kontrolle (Lab) +TP_COLORAPP_GAMUT_TOOLTIP;Zulassen der Gamut Kontrolle im Lab Modus +TP_COLORAPP_HUE;Buntton (h) +TP_COLORAPP_HUE_TOOLTIP;Buntton (h) - Winkel zwischen 0° und 360° +TP_COLORAPP_LABEL;CIE Color Appearance Model 2002 +TP_COLORAPP_LABEL_CAM02;Bildanpassungen +TP_COLORAPP_LABEL_SCENE;Umgebungsbedingungen (Szene) +TP_COLORAPP_LABEL_VIEWING;Betrachtungsbedingungen +TP_COLORAPP_LIGHT;Helligkeit (J) +TP_COLORAPP_LIGHT_TOOLTIP;Helligkeit in CIECAM02 unterscheidet sich von Lab und RGB Helligkiet +TP_COLORAPP_MODEL;Weißpunkt Modell +TP_COLORAPP_MODEL_TOOLTIP;WB [RT] + [Ausgabe]:\nRT's Weißabgleich wird für die Szene verwendet, CIECAM02 auf D50 gesetzt und der Weißabgleich des Ausgabegerätes kann unter Einstellungen > Farb-Management eingestellt werden.\n\nWB [RT+CAT02] + [Ausgabe]:\nRT's Weißabgleich wird für CAT02 verwendet und der Weißabgleich des Ausgabegerätes kann unter Einstellungen > Farb-Management eingestellt werden. +TP_COLORAPP_RSTPRO;Rot- und Hauttöne schützen +TP_COLORAPP_RSTPRO_TOOLTIP;Rot- und Hauttöne schützen (Regler und Kurven) +TP_COLORAPP_SHARPCIE;Schärfung, Kontrast anhand Detailstufen, Mikrokontrast & Defringe mit Q/C +TP_COLORAPP_SHARPCIE_TOOLTIP;Schärfung, Kontrast anhand Detailstufen, Mikrokontrast & Defringe benutzen CIECAM02, wenn aktiviert. +TP_COLORAPP_SURROUND;Umgebung +TP_COLORAPP_SURROUND_AVER;Durchschnitt +TP_COLORAPP_SURROUND_DARK;Dunkel +TP_COLORAPP_SURROUND_DIM;Gedimmt +TP_COLORAPP_SURROUND_EXDARK;Extrem Dunkel (Cutsheet) +TP_COLORAPP_SURROUND_TOOLTIP;Verändert Töne und Farben unter Berücksichtigung der Betrachtungsbedingungen des Ausgabegerätes.\n\nDurchschnitt:\nDurchschnittliche Lichtumgebung (standard)\nDas Bild wird nicht angepasst\n\nGedimmt:\nGedimmte Umgebung (TV)\ndas Bild wird leicht dunkel\n\nDunkel:\nDunkle Umgebung (Projektor)\nDas Bild wird dunkler\n\nExtrem Dunkel:\n\nExtrem Dunkle Umgebung\nDas Bild wird sehr dunkel +TP_COLORAPP_SURSOURCE;Dunkle Umbgebung +TP_COLORAPP_SURSOURCE_TOOLTIP;Kann verwendet werden, wenn das Quellbild einen schwarzen Rahmen hat +TP_COLORAPP_TCMODE_BRIGHTNESS;Helligkeit +TP_COLORAPP_TCMODE_CHROMA;Chroma +TP_COLORAPP_TCMODE_COLORF;Buntheit +TP_COLORAPP_TCMODE_LABEL1;Kurve Modus 1 +TP_COLORAPP_TCMODE_LABEL2;Kurve Modus 2 +TP_COLORAPP_TCMODE_LABEL3;Kurve Chroma Modus +TP_COLORAPP_TCMODE_LIGHTNESS;Leuchtkraft +TP_COLORAPP_TCMODE_SATUR;Sättigung +TP_COLORAPP_TONECIE;Tone Mapping mittels CIECAM02 Helligkeit (Q) +TP_COLORAPP_TONECIE_TOOLTIP;Wenn diese Option ausgeschaltet ist, wird Tone Mapping im Lab Farbraum durchgeführt.\nWenn die Option eingeschaltet ist, wird CIECAM02 für Tone Mapping verwendet. Das Tone Mapping (Lab/CIECAM02) Werkzeug muss aktiviert sein, damit diese Option berücksichtigt wird. +TP_COLORAPP_WBCAM;WB [RT+CAT02] + [Ausgabe] +TP_COLORAPP_WBRT;WB [RT] + [Ausgabe] +TP_CROP_FIXRATIO;Festes\nVerhältnis: +TP_CROP_GTDIAGONALS;Diagonalregel +TP_CROP_GTEPASSPORT;Passfoto (biometrisch) +TP_CROP_GTFRAME;Frame +TP_CROP_GTGRID;Gitternetz +TP_CROP_GTNONE;Keine +TP_CROP_GTRULETHIRDS;Drittelregel +TP_CROP_GUIDETYPE;Hilfslinien: +TP_CROP_H;H +TP_CROP_LABEL;Ausschnitt +TP_CROP_PPI;PPI= +TP_CROP_SELECTCROP;Ausschnitt wählen +TP_CROP_W;B +TP_CROP_X;x +TP_CROP_Y;y +TP_DARKFRAME_AUTOSELECT;Automatische Auswahl +TP_DARKFRAME_LABEL;Dunkelbild +TP_DEFRINGE_LABEL;Defringe +TP_DEFRINGE_RADIUS;Radius +TP_DEFRINGE_THRESHOLD;Schwellenwert +TP_DIRPYRDENOISE_BLUE;Delta Chrominanz Blau +TP_DIRPYRDENOISE_CHROMA;Chrominanz +TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Kann für Raw und Nicht-Raw Bilder verwendet werden.\n\nBei Nicht-Raw Bildern hängt die Rauschreduzierung der Luminanz vom Gamma des Eingabe-Farbprofils ab. Es wird ein sRGB-Gamma angenommen, daher wird die Luminanz-Rauschreduzierung variieren, wenn das Eingabe-Bild ein Farbprofil mit anderem Gamma verwendet. +TP_DIRPYRDENOISE_GAMMA;Gamma +TP_DIRPYRDENOISE_GAMMA_TOOLTIP;Mit Gamma kann die Stärke der Rauschreduzierung über den Farbbereich variiert werden. Bei kleinen Werten sind nur dunkle Farbtöne betroffen, bei größeren Werten wird hingegen der Effekt auf hellere Töne ausgeweitet. +TP_DIRPYRDENOISE_LABEL;Rauschminderung +TP_DIRPYRDENOISE_LDETAIL;Luminanz Detail +TP_DIRPYRDENOISE_LUMA;Luminanz +TP_DIRPYRDENOISE_METHOD;Methode +TP_DIRPYRDENOISE_METHOD_TOOLTIP;Für Raw-Bilder kann entweder die RGB- oder Lab-Methode verwendet werden.\n\nFür andere Bilder wird unabhängig von der Auswahl immer die Lab-Methode verwendet. +TP_DIRPYRDENOISE_RED;Delta Chrominanz Rot +TP_DIRPYRDENOISE_RGB;RGB +TP_DIRPYREQUALIZER_LABEL;Kontrast nach Detailstufen +TP_DIRPYREQUALIZER_LUMACOARSEST;Gröbstes +TP_DIRPYREQUALIZER_LUMACONTRAST_MINUS;Kontrast- +TP_DIRPYREQUALIZER_LUMACONTRAST_PLUS;Kontrast+ +TP_DIRPYREQUALIZER_LUMAFINEST;Feinstes +TP_DIRPYREQUALIZER_LUMANEUTRAL;Neutral +TP_DIRPYREQUALIZER_THRESHOLD;Schwellenwert +TP_DISTORTION_AMOUNT;Stärke +TP_DISTORTION_AUTO;Autom. Verzeichnungskorrektur +TP_DISTORTION_AUTO_TIP;Linsenverzeichnungen automatisch korrigieren (nur für bestimmte Kameras, z.B. Micro 4/3, einige Kompaktkameras, usw.)\n\n(Diese Funktion befindet sich noch im Experimentierstadium) +TP_DISTORTION_LABEL;Verzeichnungskorrektur +TP_EPD_EDGESTOPPING;Kantenschutz +TP_EPD_LABEL;Tone Mapping +TP_EPD_REWEIGHTINGITERATES;Neugewichtung Iterationen +TP_EPD_SCALE;Faktor +TP_EPD_STRENGTH;Stärke +TP_EPD_TOOLTIP;Tone Mapping ist mit dem Lab Modus (Standard) und CIECAM02 Modus möglich.\n\nFür CIECAM02 Tone Mapping müssen folgende Optionen aktiviert werden:\n1. CIECAM02\n2. Algorithmus="Helligkeit + Buntheit (QM)"\n3. "Tone Mapping mittels CIECAM02 Helligkeit (Q)" +TP_EXPOSURE_AUTOLEVELS;Auto +TP_EXPOSURE_AUTOLEVELS_TIP;Automatische Belichtungseinstellungen basierend auf Bildanalyse +TP_EXPOSURE_BLACKLEVEL;Schwarzpegel +TP_EXPOSURE_BRIGHTNESS;Helligkeit +TP_EXPOSURE_CLIP;Grenzwert +TP_EXPOSURE_CLIP_TIP;Anteil der Pixel, die sich bei automatischer Belichtungseinstellung im Bereich der Spitzlichter und Schatten befinden müssen +TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Lichter wiederherstellen\nSchwellenwert +TP_EXPOSURE_COMPRHIGHLIGHTS;Lichter wiederherstellen\nStärke +TP_EXPOSURE_COMPRSHADOWS;Schatten wiederherstellen +TP_EXPOSURE_CONTRAST;Kontrast +TP_EXPOSURE_CURVEEDITOR1;Tonwertkurve 1 +TP_EXPOSURE_CURVEEDITOR2;Tonwertkurve 2 +TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Um mit den doppelten Tonwert-Kurven die besten Ergenisse zu erzielen, lesen Sie bitte den Abschnitt im Handbuch unter:\nDer Werkzeugkasten > Reiter Belichtung > Belichtungsbereich > Tonwertkurvee +TP_EXPOSURE_EXPCOMP;Belichtungskorrektur +TP_EXPOSURE_LABEL;Belichtung +TP_EXPOSURE_SATURATION;Sättigung +TP_EXPOSURE_TCMODE_FILMLIKE;Film-ähnliche +TP_EXPOSURE_TCMODE_LABEL1;Tonewertkurve Modus 1 +TP_EXPOSURE_TCMODE_LABEL2;Tonewertkurve Modus 2 +TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Saturation and Value Blending +TP_EXPOSURE_TCMODE_STANDARD;Standard +TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard +TP_FLATFIELD_AUTOSELECT;Automatische Auswahl +TP_FLATFIELD_BLURRADIUS;Unschärferadius +TP_FLATFIELD_BLURTYPE;Unschärfetyp +TP_FLATFIELD_BT_AREA;Bereich +TP_FLATFIELD_BT_HORIZONTAL;Horizontal +TP_FLATFIELD_BT_VERTHORIZ;Vertikal + Horizontal +TP_FLATFIELD_BT_VERTICAL;Vertikal +TP_FLATFIELD_LABEL;Weißbild +TP_GAMMA_CURV;Gamma +TP_GAMMA_FREE;Freies Gamma +TP_GAMMA_OUTPUT;Ausgabe-Gamma +TP_GAMMA_SLOP;Gradient (linear) +TP_GRADIENT_CENTER;Rotationsachse +TP_GRADIENT_CENTER_X;Rotationsachse X +TP_GRADIENT_CENTER_X_TOOLTIP;Ankerpunkt der Rotationsachse X: -100=linker Bildrand, 0=Bildmitte, +100=rechter Bildrand +TP_GRADIENT_CENTER_Y;Rotationsachse Y +TP_GRADIENT_CENTER_Y_TOOLTIP;Ankerpunkt der Rotationsachse Y: -100=oberer Bildrand, 0=Bildmitte, +100=unterer Bildrand +TP_GRADIENT_DEGREE;Winkel +TP_GRADIENT_DEGREE_TOOLTIP;Rotationswinkel in Grad +TP_GRADIENT_FEATHER;Verlauf +TP_GRADIENT_FEATHER_TOOLTIP;Breite des Verlaufs in Prozent der Bilddiagonalen +TP_GRADIENT_LABEL;Grauverlauffilter +TP_GRADIENT_STRENGTH;Stärke +TP_GRADIENT_STRENGTH_TOOLTIP;Filterstärke in Blendenstufen +TP_HLREC_BLEND;Blending +TP_HLREC_CIELAB;CIELab Blending +TP_HLREC_COLOR;Color Propagation +TP_HLREC_ENA_TOOLTIP;Wird bei Verwendung der automatischen Belichtungskorrektur möglicherweise automatsch aktiviert +TP_HLREC_LABEL;Lichter wiederherstellen +TP_HLREC_LUMINANCE;Luminanz wiederherstellen +TP_HLREC_METHOD;Methode: +TP_HSVEQUALIZER_CHANNEL;Kanal +TP_HSVEQUALIZER_HUE;H +TP_HSVEQUALIZER_LABEL;HSV-Equalizer +TP_HSVEQUALIZER_SAT;S +TP_HSVEQUALIZER_VAL;V +TP_ICM_BLENDCMSMATRIX;ICC Lichter aus Matrix einmischen +TP_ICM_BLENDCMSMATRIX_TOOLTIP;Stellt bei Verwendung von LUT-basierten\nICC-Profilen die Lichter wieder her. +TP_ICM_INPUTCAMERAICC;Kameraspezifisches Profil +TP_ICM_INPUTCAMERAICC_TOOLTIP;RawTherapees kameraspezifisches DCP/ICC-Eingabeprofil verwenden, welches präziser als eine einfache Matrix ist; diese im Verzeichnis /dcpprofiles/ (alternativ /iccprofiles/input) abgelegten Profile sind für einige Kameras verfügbar und werden automatisch herangezogen, wenn der Dateiname zum Namen des Kameramodells passt +TP_ICM_INPUTCAMERA;Kamera-Standard +TP_ICM_INPUTCAMERA_TOOLTIP;Einfache Farbmatrix von DCRAW, die (vom Namen des Kameramodells abhängige) erweiterte RawTherapee-Version oder die im DNG eingebettete verwenden +TP_ICM_INPUTCUSTOM;Benutzerdefiniert +TP_ICM_INPUTCUSTOM_TOOLTIP;Eigene DCP/ICC-Farbprofildatei für die Kamera verwenden +TP_ICM_INPUTDLGLABEL;Eingabe-DCP/ICC-Profil wählen... +TP_ICM_INPUTEMBEDDED;Eingebettetes verwenden, falls möglich +TP_ICM_INPUTEMBEDDED_TOOLTIP;Farbprofil verwenden, das ggf. in nicht-RAW Dateien eingebettet ist +TP_ICM_INPUTNONE;Kein Profil +TP_ICM_INPUTNONE_TOOLTIP;Kein Eingabe-Farbprofil verwenden; nur in speziellen Fällen sinnvoll +TP_ICM_INPUTPROFILE;Eingabeprofil +TP_ICM_LABEL;Farbmanagement +TP_ICM_NOICM;Kein ICM: sRGB-Ausgabe +TP_ICM_OUTPUTPROFILE;Ausgabeprofil +TP_ICM_SAVEREFERENCE;Referenzbild für Profil speichern +TP_ICM_TONECURVE;DCP Tonwertkurve verwenden +TP_ICM_TONECURVE_TOOLTIP;Verwendet die Tonwertkurve, die in DCP profilen eingebetten sein kann. +TP_ICM_WORKINGPROFILE;Arbeitsfarbraum +TP_IMPULSEDENOISE_LABEL;Impulsrauschminderung +TP_IMPULSEDENOISE_THRESH;Schwellenwert +TP_LABCURVE_AVOIDCOLORSHIFT;Vermeide Farbverschiebungen +TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Anpassung der Farben am Gamut des Arbeitsfarbraums und Munsell Korrektur anwenden +TP_LABCURVE_BRIGHTNESS;Helligkeit +TP_LABCURVE_CHROMATICITY;Chromatizität +TP_LABCURVE_CONTRAST;Kontrast +TP_LABCURVE_CURVEEDITOR;Luminanzkurve +TP_LABCURVE_CURVEEDITOR_A_RANGE1;Grün gesättigt +TP_LABCURVE_CURVEEDITOR_A_RANGE2;Grün pastell +TP_LABCURVE_CURVEEDITOR_A_RANGE3;Rot pastell +TP_LABCURVE_CURVEEDITOR_A_RANGE4;Rot gesättigt +TP_LABCURVE_CURVEEDITOR_B_RANGE1;Blau gesättigt +TP_LABCURVE_CURVEEDITOR_B_RANGE2;Blau pastell +TP_LABCURVE_CURVEEDITOR_B_RANGE3;Gelb pastell +TP_LABCURVE_CURVEEDITOR_B_RANGE4;Gelb gesättigt +TP_LABCURVE_CURVEEDITOR_CC;CC +TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutral +TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Matt +TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastell +TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Gesättigt +TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Chromatizität C=f(C).\n\nZeigt das Histogramm von C vor der Kurvenkorrektur.\nFür die endgültige Ausgabe verwenden Sie das Haupt-Histogramm. +TP_LABCURVE_CURVEEDITOR_CH;CH +TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromatizität gemäß Buntton +TP_LABCURVE_CURVEEDITOR_LC;LC +TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminanz gemäß Chromatizität +TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminanz Lab L=f(L).\n\nZeigt das Histogramm von L vor der Kurvenkorrektur.\nFür die endgültige Ausgabe verwenden Sie das Haupt-Histogramm. +TP_LABCURVE_LABEL;Lab-Anpassungen +TP_LABCURVE_LCREDSK;LC auf Rot- und Hauttöne beschränken +TP_LABCURVE_LCREDSK_TIP;Wenn aktiviert, wird die LC Kurve (Luminanz gemäß Chromatizität) beschränkt auf Rot- und Hauttöne.\nWenn deaktiviert, wird die LC Kurve auf alle Töne angewendet. +TP_LABCURVE_RSTPROTECTION;Rot- und Hauttöne schützen +TP_LABCURVE_RSTPRO_TOOLTIP;Kann mit dem Chromatizität-Regler und der CC Kurve verwendet werden. +TP_LENSGEOM_AUTOCROP;Auto-Schneiden +TP_LENSGEOM_FILL;Auto-Füllen +TP_LENSGEOM_LABEL;Objektivkorrekturen +TP_LENSPROFILE_LABEL;Linsen-Korrekturprofil +TP_LENSPROFILE_USECA;CA korrigieren +TP_LENSPROFILE_USEDIST;Verzerrung korrigieren +TP_LENSPROFILE_USEVIGN;Vignettierung korrigieren +TP_NEUTRAL;Neutral +TP_NEUTRAL_TIP;Belichtungseinstellungen auf neutrale Werte zurücksetzen +TP_PCVIGNETTE_FEATHER;Verlauf +TP_PCVIGNETTE_FEATHER_TOOLTIP;Verlauf: 0=nur Bildecken, 50=halbe Strecke zum Mittelpunkt, 100=bis zum Mittelpunkt +TP_PCVIGNETTE_LABEL;Vignettierungsfilter +TP_PCVIGNETTE_ROUNDNESS;Rundheit +TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Rundheit: 0=Rechteck, 50=eingepasste Ellipse, 100=Kreis +TP_PCVIGNETTE_STRENGTH;Stärke +TP_PCVIGNETTE_STRENGTH_TOOLTIP;Filterstärke in Blendenstufen (bezogen auf die Bildecken) +TP_PERSPECTIVE_HORIZONTAL;Horizontal +TP_PERSPECTIVE_LABEL;Perspektive +TP_PERSPECTIVE_VERTICAL;Vertikal +TP_PREPROCESS_DEADPIXFILT;Dead-Pixel-Filter +TP_PREPROCESS_GREENEQUIL;Grün-Ausgleich +TP_PREPROCESS_HOTPIXFILT;Hot-Pixel-Filter +TP_PREPROCESS_LABEL;Vorverarbeitung +TP_PREPROCESS_LINEDENOISE;Zeilenrauschfilter +TP_PREPROCESS_NO_FOUND;Keins gefunden +TP_RAWCACORR_AUTO;Automatische Korrektur +TP_RAWCACORR_CABLUE;Blau +TP_RAWCACORR_CARED;Rot +TP_RAWEXPOS_BLACKS;Schwarzpegel +TP_RAWEXPOS_LINEAR;Weißpunkt: Linearer\nKorrekturfaktor +TP_RAWEXPOS_PRESER;Weißpunkt: Lichter\nbewahrende Korrektur (EV) +TP_RAWEXPOS_TWOGREEN;Grün-Werte automatisch angleichen +TP_RAW_DCBENHANCE;DCB-Verfeinerungsschritt +TP_RAW_DCBITERATIONS;Anzahl der DCB-Iterationen +TP_RAW_DMETHOD;Methode +TP_RAW_FALSECOLOR;Falschfarbenunterdrückung\nStufen +TP_RAW_LABEL;Farbinterpolation +TP_RESIZE_APPLIESTO;Gilt für: +TP_RESIZE_CROPPEDAREA;Ausschnitt +TP_RESIZE_FITBOX;Begrenzungsrahmen +TP_RESIZE_FULLIMAGE;Ganzes Bild +TP_RESIZE_HEIGHT;Höhe +TP_RESIZE_H;H: +TP_RESIZE_LABEL;Größe ändern +TP_RESIZE_LANCZOS;Lanczos +TP_RESIZE_METHOD;Methode: +TP_RESIZE_NEAREST;Nächster Nachbar +TP_RESIZE_SCALE;Maßstab +TP_RESIZE_SPECIFY;Vorgabe: +TP_RESIZE_WIDTH;Breite +TP_RESIZE_W;B: +TP_RGBCURVES_BLUE;B +TP_RGBCURVES_CHANNEL;Kanal +TP_RGBCURVES_GREEN;G +TP_RGBCURVES_LABEL;RGB-Kurven +TP_RGBCURVES_LUMAMODE;Leuchtkraft Modus +TP_RGBCURVES_LUMAMODE_TOOLTIP;Der Leuchtkraft Modus ermöglicht die Verteilung der R, G und B Kanäle zur Leuchtkraft des Bildes, ohne die Farben des Bildes zu verändern. +TP_RGBCURVES_RED;R +TP_ROTATE_DEGREE;Grad +TP_ROTATE_LABEL;Fein-Rotation +TP_ROTATE_SELECTLINE;Leitlinie wählen +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Lichter +TP_SHADOWSHLIGHTS_HLTONALW;Farbtonbereich für Lichter +TP_SHADOWSHLIGHTS_LABEL;Schatten/Lichter +TP_SHADOWSHLIGHTS_LOCALCONTR;Lokaler Kontrast +TP_SHADOWSHLIGHTS_RADIUS;Radius +TP_SHADOWSHLIGHTS_SHADOWS;Schatten +TP_SHADOWSHLIGHTS_SHTONALW;Farbtonbereich für Schatten +TP_SHARPENEDGE_AMOUNT;Stärke +TP_SHARPENEDGE_LABEL;Kantenschärfung +TP_SHARPENEDGE_PASSES;Iterationen +TP_SHARPENEDGE_THREE;Nur Luminanz +TP_SHARPENING_AMOUNT;Stärke +TP_SHARPENING_EDRADIUS;Radius +TP_SHARPENING_EDTOLERANCE;Kantentoleranz +TP_SHARPENING_HALOCONTROL;Halo-Kontrolle +TP_SHARPENING_HCAMOUNT;Stärke +TP_SHARPENING_LABEL;Schärfung +TP_SHARPENING_METHOD;Methode +TP_SHARPENING_ONLYEDGES;Nur Kanten schärfen +TP_SHARPENING_RADIUS;Radius +TP_SHARPENING_RLD;RL-Dekonvolution +TP_SHARPENING_RLD_AMOUNT;Stärke +TP_SHARPENING_RLD_DAMPING;Dämpfung +TP_SHARPENING_RLD_ITERATIONS;Iterationen +TP_SHARPENING_THRESHOLD;Schwellenwert +TP_SHARPENING_TOOLTIP;Ergibt einen leicht geänderten Effekt, wenn CIECAM02 verwendet wird. Wenn ein Unterschied festzustellen ist, nach belieben abändern. +TP_SHARPENING_USM;Unscharfmaskierung +TP_SHARPENMICRO_AMOUNT;Stärke +TP_SHARPENMICRO_LABEL;Mikrokontrast +TP_SHARPENMICRO_MATRIX;3×3-Matrix statt 5×5-Matrix +TP_SHARPENMICRO_UNIFORMITY;Gleichmäßigkeit +TP_VIBRANCE_AVOIDCOLORSHIFT;Farbverschiebungen verhindern +TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH +TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Hauttöne +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Rot/Violett +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Rot +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Rot/Gelb +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Gelb +TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Färbung entsprechend des Farbtons +TP_VIBRANCE_LABEL;Dynamik +TP_VIBRANCE_PASTELS;Pastelltöne +TP_VIBRANCE_PASTSATTOG;Pastellene und gesättigte Töne koppeln +TP_VIBRANCE_PROTECTSKINS;Hauttöne schützen +TP_VIBRANCE_PSTHRESHOLD;Pastellene/gesättigte Töne\nSchwellenwert +TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Sättigung Schwellenwert +TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;Die vertikale Achse steht für die Pastell-Töne (unten) und gesättigte Töne (oben).\nDie horizontale Achse entspricht dem Sättigungsbereich. +TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Gewichtung des Übergangs pastell/gesättigt +TP_VIBRANCE_SATURATED;Gesättigte Töne +TP_VIGNETTING_AMOUNT;Stärke +TP_VIGNETTING_CENTER;Zentrum +TP_VIGNETTING_CENTER_X;Zentrum X +TP_VIGNETTING_CENTER_Y;Zentrum Y +TP_VIGNETTING_LABEL;Vignettierungskorrektur +TP_VIGNETTING_RADIUS;Radius +TP_VIGNETTING_STRENGTH;Faktor +TP_WBALANCE_AUTO;Automatisch +TP_WBALANCE_CAMERA;Kamera +TP_WBALANCE_CLOUDY;Bewölkt +TP_WBALANCE_CUSTOM;Benutzerdefiniert +TP_WBALANCE_DAYLIGHT;Tageslicht (sonnig) +TP_WBALANCE_FLASH55;Leica +TP_WBALANCE_FLASH60;Standard, Canon, Pentax, Olympus +TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta +TP_WBALANCE_FLASH_HEADER;Blitz +TP_WBALANCE_FLUO1;F1 - Daylight +TP_WBALANCE_FLUO2;F2 - Cool White +TP_WBALANCE_FLUO3;F3 - White +TP_WBALANCE_FLUO4;F4 - Warm White +TP_WBALANCE_FLUO5;F5 - Daylight +TP_WBALANCE_FLUO6;F6 - Lite White +TP_WBALANCE_FLUO7;F7 - D65 Daylight Simulator +TP_WBALANCE_FLUO8;F8 - D50 / Sylvania F40 Design +TP_WBALANCE_FLUO9;F9 - Cool White Deluxe +TP_WBALANCE_FLUO10;F10 - Philips TL85 +TP_WBALANCE_FLUO11;F11 - Philips TL84 +TP_WBALANCE_FLUO12;F12 - Philips TL83 +TP_WBALANCE_FLUO_HEADER;Leuchtstofflampe +TP_WBALANCE_GREEN;Farbton +TP_WBALANCE_GTI;GTI +TP_WBALANCE_HMI;HMI +TP_WBALANCE_JUDGEIII;JudgeIII +TP_WBALANCE_LABEL;Weißabgleich +TP_WBALANCE_LAMP_HEADER;Lampe +TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 +TP_WBALANCE_LED_HEADER;LED +TP_WBALANCE_LED_LSI;LSI Lumelex 2040 +TP_WBALANCE_METHOD;Methode +TP_WBALANCE_SHADE;Schatten +TP_WBALANCE_SIZE;Größe: +TP_WBALANCE_SOLUX35;Solux 3500K +TP_WBALANCE_SOLUX41;Solux 4100K +TP_WBALANCE_SOLUX47;Solux 4700K (Vendor) +TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) +TP_WBALANCE_SPOTWB;Manuell setzen +TP_WBALANCE_TEMPERATURE;Farbtemperatur +TP_WBALANCE_TUNGSTEN;Glühlampe +TP_WBALANCE_WATER1;Unterwasser 1 +TP_WBALANCE_WATER2;Unterwasser 2 +TP_WBALANCE_WATER_HEADER;Unterwasser +ZOOMPANEL_100;(100%) +ZOOMPANEL_NEWCROPWINDOW;(Weiteres) Detailfenster öffnen +ZOOMPANEL_ZOOM100;Zoom 100% z +ZOOMPANEL_ZOOMFITSCREEN;An Bildschirm anpassen f +ZOOMPANEL_ZOOMIN;Hineinzoomen + +ZOOMPANEL_ZOOMOUT;Herauszoomen - + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!BATCHQUEUE_DESTFILENAME;Path and file name +!CURVEEDITOR_AXIS_IN;I: +!CURVEEDITOR_AXIS_LEFT_TAN;LT: +!CURVEEDITOR_AXIS_OUT;O: +!CURVEEDITOR_AXIS_RIGHT_TAN;RT: +!CURVEEDITOR_EDITPOINT_HINT;Enable edition of node in/out values.\n\nRight-click on a node to select it.\nRight-click on empty space to de-select the node. +!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. +!EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels +!EXPORT_BYPASS_RAW_LMMSE_ITERATIONS;Bypass [raw] LMMSE Enhancement Steps +!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_POPUPRANK0;Unrank +!FILEBROWSER_POPUPRANK1;Rank 1 * +!FILEBROWSER_POPUPRANK2;Rank 2 ** +!FILEBROWSER_POPUPRANK3;Rank 3 *** +!FILEBROWSER_POPUPRANK4;Rank 4 **** +!FILEBROWSER_POPUPRANK5;Rank 5 ***** +!FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!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_ASIMAGE;As Image +!HISTORY_MSG_204;LMMSE enhancement steps +!HISTORY_MSG_205;CAM02 - Hot/bad pixel filter +!HISTORY_MSG_206;CAT02 - Auto scene luminosity +!HISTORY_MSG_207;Defringe - Hue curve +!HISTORY_MSG_223;B&W - CM - Orange +!HISTORY_MSG_224;B&W - CM - Yellow +!HISTORY_MSG_225;B&W - CM - Cyan +!HISTORY_MSG_226;B&W - CM - Magenta +!HISTORY_MSG_227;B&W - CM - Purple +!HISTORY_MSG_228;B&W - Luminance equalizer +!HISTORY_MSG_229;B&W - Luminance equalizer +!HISTORY_MSG_231;B&W - 'Before' curve +!HISTORY_MSG_232;B&W - 'Before' curve type +!HISTORY_MSG_233;B&W - 'After' curve +!HISTORY_MSG_234;B&W - 'After' curve type +!HISTORY_MSG_236;--unused-- +!HISTORY_MSG_250;NR - Enhanced +!HISTORY_MSG_251;B&W - Algorithm +!HISTORY_MSG_252;CbDL - Skin tar/prot +!HISTORY_MSG_253;CbDL - Reduce artifacts +!HISTORY_MSG_254;CbDL - Skin hue +!HISTORY_MSG_255;NR - Median filter +!HISTORY_MSG_256;NR - Median type +!HISTORY_MSG_257;Color Toning +!HISTORY_MSG_258;CT - Color curve +!HISTORY_MSG_259;CT - Opacity curve +!HISTORY_MSG_260;CT - a*[b*] opacity +!HISTORY_MSG_261;CT - Method +!HISTORY_MSG_262;CT - b* opacity +!HISTORY_MSG_263;CT - Shadows - Red +!HISTORY_MSG_264;CT - Shadows - Green +!HISTORY_MSG_265;CT - Shadows - Blue +!HISTORY_MSG_266;CT - Mid - Red +!HISTORY_MSG_267;CT - Mid - Green +!HISTORY_MSG_268;CT - Mid - Blue +!HISTORY_MSG_269;CT - High - Red +!HISTORY_MSG_270;CT - High - Green +!HISTORY_MSG_271;CT - High - Blue +!HISTORY_MSG_272;CT - Balance +!HISTORY_MSG_273;CT - Reset +!HISTORY_MSG_274;CT - Sat. Shadows +!HISTORY_MSG_275;CT - Sat. Highlights +!HISTORY_MSG_276;CT - Opacity +!HISTORY_MSG_277;--unused-- +!HISTORY_MSG_278;CT - Preserve luminance +!HISTORY_MSG_279;CT - Shadows +!HISTORY_MSG_280;CT - Highlights +!HISTORY_MSG_281;CT - Sat. strength +!HISTORY_MSG_282;CT - Sat. threshold +!HISTORY_MSG_283;CT - Strength +!HISTORY_MSG_284;CT - Auto sat. protection +!HISTORY_MSG_285;NR - Median - Method +!HISTORY_MSG_286;NR - Median - Type +!HISTORY_MSG_287;NR - Median - Iterations +!HISTORY_MSG_288;Flat Field - Clip control +!HISTORY_MSG_289;Flat Field - Clip control - Auto +!HISTORY_MSG_290;Black Level - Red +!HISTORY_MSG_291;Black Level - Green +!HISTORY_MSG_292;Black Level - Blue +!HISTORY_MSG_293;Film Simulation +!HISTORY_MSG_294;Film Simulation - Strength +!HISTORY_MSG_295;Film Simulation - Film +!HISTORY_MSG_296;NR - Luminance curve +!HISTORY_MSG_297;NR - Quality +!HISTORY_MSG_298;Dead pixel filter +!HISTORY_MSG_299;NR - Chrominance curve +!HISTORY_MSG_300;- +!HISTORY_MSG_301;NR - Luma control +!HISTORY_MSG_302;NR - Chroma method +!HISTORY_MSG_303;NR - Chroma method +!HISTORY_MSG_304;W - Contrast levels +!HISTORY_MSG_305;Wavelet Levels +!HISTORY_MSG_306;W - Preview +!HISTORY_MSG_307;W - Preview +!HISTORY_MSG_308;W - Preview direction +!HISTORY_MSG_309;W - ES - Detail +!HISTORY_MSG_310;W - Residual - Sky tar/prot +!HISTORY_MSG_311;W - Wavelet levels +!HISTORY_MSG_312;W - Residual - Shadows threshold +!HISTORY_MSG_313;W - Chroma - Sat/past +!HISTORY_MSG_314;W - Gamut - Reduce artifacts +!HISTORY_MSG_315;W - Residual - Contrast +!HISTORY_MSG_316;W - Gamut - Skin tar/prot +!HISTORY_MSG_317;W - Gamut - Skin hue +!HISTORY_MSG_318;W - Contrast - Highlight levels +!HISTORY_MSG_319;W - Contrast - Highlight range +!HISTORY_MSG_320;W - Contrast - Shadow range +!HISTORY_MSG_321;W - Contrast - Shadow levels +!HISTORY_MSG_322;W - Gamut - Avoid color shift +!HISTORY_MSG_323;W - ES - Local contrast +!HISTORY_MSG_324;W - Chroma - Pastel +!HISTORY_MSG_325;W - Chroma - Saturated +!HISTORY_MSG_326;W - Chroma - Method +!HISTORY_MSG_327;W - Contrast - Apply to +!HISTORY_MSG_328;W - Chroma - Link strength +!HISTORY_MSG_329;W - Toning - Opacity RG +!HISTORY_MSG_330;W - Toning - Opacity BY +!HISTORY_MSG_331;W - Contrast levels - Extra +!HISTORY_MSG_332;W - Tiling method +!HISTORY_MSG_333;W - Residual - Shadows +!HISTORY_MSG_334;W - Residual - Chroma +!HISTORY_MSG_335;W - Residual - Highlights +!HISTORY_MSG_336;W - Residual - Highlights threshold +!HISTORY_MSG_337;W - Residual - Sky hue +!HISTORY_MSG_338;W - ES - Radius +!HISTORY_MSG_339;W - ES - Strength +!HISTORY_MSG_340;W - Strength +!HISTORY_MSG_341;W - Edge performance +!HISTORY_MSG_342;W - ES - First level +!HISTORY_MSG_343;W - Chroma levels +!HISTORY_MSG_344;W - Meth chroma sl/cur +!HISTORY_MSG_345;W - ES - Local contrast +!HISTORY_MSG_346;W - ES - Local contrast method +!HISTORY_MSG_347;W - Denoise - Level 0 +!HISTORY_MSG_348;W - Denoise - Level 1 +!HISTORY_MSG_349;W - Denoise - Level 2 +!HISTORY_MSG_350;W - ES - Edge detection +!HISTORY_MSG_351;W - Residual - HH curve +!HISTORY_MSG_352;W - Background +!HISTORY_MSG_353;W - ES - Gradient sensitivity +!HISTORY_MSG_354;W - ES - Enhance +!HISTORY_MSG_355;W - ES - Threshold low +!HISTORY_MSG_356;W - ES - Threshold high +!HISTORY_MSG_357;W - Denoise - Link with ES +!HISTORY_MSG_358;W - Gamut - CH +!HISTORY_MSG_359;Hot/Dead - Threshold +!HISTORY_MSG_360;TM Gamma +!HISTORY_MSG_361;W - Final - Chroma balance +!HISTORY_MSG_362;W - Residual - Compression method +!HISTORY_MSG_363;W - Residual - Compression strength +!HISTORY_MSG_364;W - Final - Contrast balance +!HISTORY_MSG_365;W - Final - Delta balance +!HISTORY_MSG_366;W - Residual - Compression gamma +!HISTORY_MSG_367;W - ES - Local contrast curve +!HISTORY_MSG_368;W - Final - Contrast balance +!HISTORY_MSG_369;W - Final - Balance method +!HISTORY_MSG_370;W - Final - Local contrast curve +!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). +!MAIN_MSG_OPERATIONCANCELLED;Operation cancelled +!MAIN_MSG_PATHDOESNTEXIST;The path\n\n%1\n\ndoes not exist. Please set a correct path in Preferences. +!MAIN_MSG_SETPATHFIRST;You first have to set a target path in Preferences in order to use this function! +!MAIN_TAB_INSPECT; Inspect +!MAIN_TAB_WAVELET;Wavelet +!MAIN_TAB_WAVELET_TOOLTIP;Shortcut: Alt-w +!NAVIGATOR_B;B: +!NAVIGATOR_G;G: +!NAVIGATOR_H;H: +!NAVIGATOR_LAB_A;a*: +!NAVIGATOR_LAB_B;b*: +!NAVIGATOR_LAB_L;L*: +!NAVIGATOR_NA; -- +!NAVIGATOR_R;R: +!NAVIGATOR_S;S: +!NAVIGATOR_V;V: +!PARTIALPASTE_CHANNELMIXERBW;Black-and-White +!PARTIALPASTE_COLORTONING;Color Toning +!PARTIALPASTE_EQUALIZER;Wavelet Equalizer +!PARTIALPASTE_FILMSIMULATION;Film Simulation +!PARTIALPASTE_FLATFIELDCLIPCONTROL;Flat-field clip control +!PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!PARTIALPASTE_WAVELETGROUP;Wavelet processing +!PREFERENCES_AUTLISLOW;Low +!PREFERENCES_AUTLISMAX;Max - Average of all tiles +!PREFERENCES_AUTLISSTD;High +!PREFERENCES_AUTLISVLOW;None +!PREFERENCES_AUTLOW;Low +!PREFERENCES_AUTSTD;Standard +!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_BEHADDALL;All to 'Add' +!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_BEHSETALL;All to 'Set' +!PREFERENCES_CIEART_FRAME;CIECAM02-Specific Settings +!PREFERENCES_CLUTSCACHE;HaldCLUT Cache +!PREFERENCES_CLUTSCACHE_LABEL;Maximum number of cached CLUTs +!PREFERENCES_CLUTSDIR;HaldCLUT directory +!PREFERENCES_CURVEBBOXPOS;Position of curve copypasta buttons +!PREFERENCES_CURVEBBOXPOS_ABOVE;Above +!PREFERENCES_CURVEBBOXPOS_BELOW;Below +!PREFERENCES_CURVEBBOXPOS_LEFT;Left +!PREFERENCES_CURVEBBOXPOS_RIGHT;Right +!PREFERENCES_CUSTPROFBUILDKEYFORMAT;Keys format +!PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME;Name +!PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;TagID +!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_EXPAUT;Expert +!PREFERENCES_FILMSIMULATION;Film Simulation +!PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT;Same thumbnail height between the Editor's panel 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_GREYSC18;Yb=18 CIE L#50 +!PREFERENCES_GREYSCA;Automatic +!PREFERENCES_GREYSC;Scene Yb luminance (%) +!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_LEVAUTDN;Denoising level +!PREFERENCES_LEVDN;Cell size +!PREFERENCES_LISS;Auto multi-zone smoothing +!PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders +!PREFERENCES_MAX;Maxi (Tile) +!PREFERENCES_MED;Medium (Tile/2) +!PREFERENCES_MIN;Mini (100x115) +!PREFERENCES_NAVGUIDEBRUSH;Navigator guide color +!PREFERENCES_NAVIGATIONFRAME;Navigation +!PREFERENCES_NOISE;Noise Reduction +!PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Overlay filenames on thumbnails in the editor pannel +!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_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_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_SHOWFILMSTRIPTOOLBAR;Show filmstrip toolbar +!PREFERENCES_SIMPLAUT;Tool mode +!PREFERENCES_SMA;Small (250x287) +!PREFERENCES_STDAUT;Standard +!PREFERENCES_TIMAX;High +!PREFERENCES_TINB;Number of tiles +!PREFERENCES_TISTD;Standard +!PREFERENCES_USEBUNDLEDPROFILES;Use bundled profiles +!PREFERENCES_WAVLEV;Increase wavelet level in quality 'high' +!PREFERENCES_WLONE;One level +!PREFERENCES_WLTWO;Two levels +!PREFERENCES_WLZER;No +!PROFILEPANEL_GLOBALPROFILES;Bundled profiles +!PROFILEPANEL_MODE_TIP;Processing profile fill mode.\n\nButton pressed: partial profiles will be converted to full profiles; the missing values will be replaced with hard-coded defaults.\n\nButton released: profiles will be applied as they are, altering only those values which they contain. +!PROFILEPANEL_MYPROFILES;My profiles +!PROFILEPANEL_PINTERNAL;Neutral +!PROGRESSBAR_NOIMAGES;No images found +!SAVEDLG_FORCEFORMATOPTS;Force saving options +!TP_BWMIX_ALGO;Algorithm OYCPM +!TP_BWMIX_ALGO_LI;Linear +!TP_BWMIX_ALGO_SP;Special effects +!TP_BWMIX_ALGO_TOOLTIP;Linear: will produce a normal linear response.\nSpecial effects: will produce special effects by mixing channels non-linearly. +!TP_BWMIX_AUTOCH;Auto +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing Channel Mixer. +!TP_BWMIX_CURVEEDITOR1;'Before' curve +!TP_BWMIX_CURVEEDITOR2;'After' curve +!TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Tone curve, after B&W conversion, at the end of treatment. +!TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Tone curve, just before B&W conversion.\nMay take into account the color components. +!TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H).\nPay attention to extreme values as they may cause artifacts. +!TP_BWMIX_NEUTRAL_TIP;Reset all values (Color Filter, Channel Mixer) to default. +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all the mixer options.\n"Total" displays the sum of the RGB values:\n- always 100% in relative mode\n- higher (lighter) or lower (darker) than 100% in absolute mode. +!TP_BWMIX_RGB_TOOLTIP;Mix the RGB channels. Use presets for guidance.\nPay attention to negative values that may cause artifacts or erratic behavior. +!TP_BWMIX_SET_RGBABS;Absolute RGB +!TP_BWMIX_SET_RGBREL;Relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Relative ROYGCBPM +!TP_BWMIX_TCMODE_SATANDVALBLENDING;B&W Saturation and Value Blending +!TP_BWMIX_VAL;L +!TP_COLORAPP_ADAP_AUTO_TOOLTIP;If the checkbox is checked (recommended) RawTherapee calculates an optimum value from Exif data.\nTo set the value manually, uncheck the checkbox first. +!TP_COLORAPP_BADPIXSL;Hot/bad pixel filter +!TP_COLORAPP_BADPIXSL_TOOLTIP;Suppression of hot/bad (brightly colored) pixels.\n0 = No effect\n1 = Median\n2 = Gaussian.\nAlternatively, adjust the image to avoid very dark shadows.\n\nThese artifacts are due to limitations of CIECAM02. +!TP_COLORTONING_AB;o C/L +!TP_COLORTONING_AUTOSAT;Automatic +!TP_COLORTONING_BALANCE;Balance +!TP_COLORTONING_BY;o C/L +!TP_COLORTONING_CHROMAC;Opacity +!TP_COLORTONING_COLOR;Color +!TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;Chroma opacity as a function of luminance oC=f(L) +!TP_COLORTONING_HIGHLIGHT;Highlights +!TP_COLORTONING_HUE;Hue +!TP_COLORTONING_LABEL;Color Toning +!TP_COLORTONING_LAB;L*a*b* blending +!TP_COLORTONING_LUMAMODE;Preserve luminance +!TP_COLORTONING_LUMAMODE_TOOLTIP;If enabled, when you change color (red, green, cyan, blue, etc.) the luminance of each pixel is preserved. +!TP_COLORTONING_LUMA;Luminance +!TP_COLORTONING_METHOD;Method +!TP_COLORTONING_METHOD_TOOLTIP;"L*a*b* blending", "RGB sliders" and "RGB curves" use interpolated color blending.\n"Color balance (Shadows/Midtones/Highlights)" and "Saturation 2 colors" use direct colors.\n\nThe Black-and-White tool can be enabled when using any color toning method, which allows for color toning. +!TP_COLORTONING_MIDTONES;Midtones +!TP_COLORTONING_NEUTRAL;Reset sliders +!TP_COLORTONING_NEUTRAL_TIP;Reset all values (Shadows, Midtones, Highlights) to default. +!TP_COLORTONING_OPACITY;Opacity +!TP_COLORTONING_RGBCURVES;RGB - Curves +!TP_COLORTONING_RGBSLIDERS;RGB - Sliders +!TP_COLORTONING_SATURATEDOPACITY;Strength +!TP_COLORTONING_SATURATIONTHRESHOLD;Threshold +!TP_COLORTONING_SA;Saturation Protection +!TP_COLORTONING_SHADOWS;Shadows +!TP_COLORTONING_SPLITCOCO;Color Balance Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITCO;Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITLR;Saturation 2 colors +!TP_COLORTONING_STRENGTH;Strength +!TP_COLORTONING_STR;Strength +!TP_COLORTONING_TWO2;Special chroma '2 colors' +!TP_COLORTONING_TWOALL;Special chroma +!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_GTHARMMEANS;Harmonic Means +!TP_CROP_GTTRIANGLE1;Golden Triangles 1 +!TP_CROP_GTTRIANGLE2;Golden Triangles 2 +!TP_DIRPYRDENOISE_33;3×3 strong +!TP_DIRPYRDENOISE_55SOFT;5×5 +!TP_DIRPYRDENOISE_55;5×5 strong +!TP_DIRPYRDENOISE_77;7×7 (slow) +!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_ABM;Chroma only +!TP_DIRPYRDENOISE_AUTO;Automatic global +!TP_DIRPYRDENOISE_AUTO_TOOLTIP;Try to evaluate chroma noise\nBe careful, this calculation is average, and is quite subjective ! +!TP_DIRPYRDENOISE_AUT;Automatic global +!TP_DIRPYRDENOISE_C2TYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CCCURVE;Chrominance curve +!TP_DIRPYRDENOISE_CHROMAFR;Chrominance +!TP_DIRPYRDENOISE_CTYPE;Auto method +!TP_DIRPYRDENOISE_CTYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nAutomatic multi-zones\nNo preview - works only during saving, but using the "Preview" method by matching the tile size and center to the preview size and center you can get an idea of the expected results.\nThe image is divided into tiles (about 10 to 70 depending on image size) and each tile receives its own chrominance noise reduction settings.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CURVEEDITOR_CC;Chroma +!TP_DIRPYRDENOISE_CURVEEDITOR_CC_TOOLTIP;Increase (multiply) the value of all chrominance sliders.\nThis curve lets you adjust the strength of chromatic noise reduction as a function of chromaticity, for instance to increase the action in areas of low saturation and to decrease it in those of high saturation. +!TP_DIRPYRDENOISE_CURVEEDITOR_L_TOOLTIP;Modulates action of 'Luminance' denoise +!TP_DIRPYRDENOISE_CUR;Curve +!TP_DIRPYRDENOISE_ENH;Enhanced mode +!TP_DIRPYRDENOISE_ENH_TOOLTIP;Increases noise reduction quality at the expense of a 20% processing time increase. +!TP_DIRPYRDENOISE_LABM;L*a*b* +!TP_DIRPYRDENOISE_LCURVE;Luminance curve +!TP_DIRPYRDENOISE_LM;Luminance only +!TP_DIRPYRDENOISE_LPLABM;Weighted L* (little) + a*b* (normal) +!TP_DIRPYRDENOISE_LTYPE;Luminance control +!TP_DIRPYRDENOISE_LUMAFR;Luminance +!TP_DIRPYRDENOISE_LUMAFR_TOOLTIP;Wavelet on luminance and Fourier transform for luminance detail +!TP_DIRPYRDENOISE_MANU;Manual +!TP_DIRPYRDENOISE_MAN;Manual +!TP_DIRPYRDENOISE_MEDMETHOD;Median method +!TP_DIRPYRDENOISE_MEDTYPE;Median type +!TP_DIRPYRDENOISE_MED;Median Filter +!TP_DIRPYRDENOISE_MED_TOOLTIP;Enabled median denoising +!TP_DIRPYRDENOISE_METHOD11;Quality +!TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. +!TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - +!TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 +!TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. +!TP_DIRPYRDENOISE_PASSES;Median iterations +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PON;Auto multi-zones +!TP_DIRPYRDENOISE_PREVLABEL;Preview size=%1, Center: Px=%2 Py=%3 +!TP_DIRPYRDENOISE_PREV;Preview +!TP_DIRPYRDENOISE_PRE;Preview multi-zones +!TP_DIRPYRDENOISE_RGBM;RGB +!TP_DIRPYRDENOISE_SHALBI;High +!TP_DIRPYRDENOISE_SHAL;Standard +!TP_DIRPYRDENOISE_SLI;Slider +!TP_DIRPYRDENOISE_SOFT;3x3 +!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_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_EPD_GAMMA;Gamma +!TP_EXPOSURE_TCMODE_LUMINANCE;Luminance +!TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points +!TP_EXPOS_WHITEPOINT_LABEL;Raw White Points +!TP_FILMSIMULATION_LABEL;Film Simulation +!TP_FILMSIMULATION_STRENGTH;Strength +!TP_FILMSIMULATION_ZEROCLUTSFOUND;Set HaldCLUT directory in Preferences +!TP_FLATFIELD_CLIPCONTROL;Clip control +!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. +!TP_GENERAL_11SCALE_TOOLTIP;The effects of this tool are only visible or only accurate at a preview scale of 1:1. +!TP_ICM_DCPILLUMINANT;Illuminant +!TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolated +!TP_ICM_DCPILLUMINANT_TOOLTIP;Select which embedded DCP illuminant to employ. Default is "interpolated" which is a mix between the two based on white balance. The setting is only enabled if a Dual-Illuminant DCP with interpolation support is selected. +!TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance +!TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. The result can be used for calibration purposes and generation of a camera profile. +!TP_LABCURVE_CHROMA_TOOLTIP;To apply B&W toning, set Chromaticity to -100. +!TP_LABCURVE_CURVEEDITOR_CL;CL +!TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Chromaticity according to luminance C=f(L) +!TP_LABCURVE_CURVEEDITOR_HH;HH +!TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Hue according to hue H=f(H) +!TP_LABCURVE_CURVEEDITOR_LH;LH +!TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H) +!TP_PFCURVE_CURVEEDITOR_CH;Hue +!TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Controls defringe strength by color.\nHigher = more,\nLower = less. +!TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Tries to suppress dead pixels. +!TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Tries to suppress hot pixels. +!TP_RAWEXPOS_BLACK_0;Green 1 (lead) +!TP_RAWEXPOS_BLACK_1;Red +!TP_RAWEXPOS_BLACK_2;Blue +!TP_RAWEXPOS_BLACK_3;Green 2 +!TP_RAWEXPOS_BLACK_BLUE;Blue +!TP_RAWEXPOS_BLACK_GREEN;Green +!TP_RAWEXPOS_BLACK_RED;Red +!TP_RAWEXPOS_RGB;Red, Green, Blue +!TP_RAW_DMETHOD_PROGRESSBAR;%1 demosaicing... +!TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Demosaicing refinement... +!TP_RAW_DMETHOD_TOOLTIP;Note: IGV and LMMSE are dedicated to high ISO images to aid in noise reduction without leading to maze patterns, posterization or a washed-out look. +!TP_RAW_HD;Threshold +!TP_RAW_HD_TOOLTIP;Lower values make hot/dead pixel detection more aggressive, but false positives may lead to artifacts. If you notice any artifacts appearing when enabling the Hot/Dead Pixel Filters, gradually increase the threshold value until they disappear. +!TP_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!TP_RAW_LMMSE_TOOLTIP;Adds gamma (step 1), median (steps 2-4) and refinement (steps 5-6) to reduce artifacts and improve the signal-to-noise ratio. +!TP_RAW_SENSOR_BAYER_LABEL;Sensor with Bayer Matrix +!TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;3-pass gives best results (recommended for low ISO images).\n1-pass is almost undistinguishable from 3-pass for high ISO images and is faster. +!TP_RAW_SENSOR_XTRANS_LABEL;Sensor with X-Trans Matrix +!TP_SAVEDIALOG_OK_TIP;Shortcut: Ctrl-Enter +!TP_SHADOWSHLIGHTS_SHARPMASK;Sharp mask +!TP_WAVELET_1;Level 1 +!TP_WAVELET_2;Level 2 +!TP_WAVELET_3;Level 3 +!TP_WAVELET_4;Level 4 +!TP_WAVELET_5;Level 5 +!TP_WAVELET_6;Level 6 +!TP_WAVELET_7;Level 7 +!TP_WAVELET_8;Level 8 +!TP_WAVELET_9;Level 9 +!TP_WAVELET_ALL;All levels in all directions +!TP_WAVELET_APPLYTO;Apply To +!TP_WAVELET_AVOID;Avoid color shift +!TP_WAVELET_B0;Black +!TP_WAVELET_B1;Grey +!TP_WAVELET_B2;Residual +!TP_WAVELET_BACUR;Curve +!TP_WAVELET_BALANCE;Contrast balance d/v-h +!TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chromaticity or residual tone mapping are activated, the effect due to balance is amplified. +!TP_WAVELET_BALCHRO;Chroma balance +!TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chromaticity balance. +!TP_WAVELET_BANONE;None +!TP_WAVELET_BASLI;Slider +!TP_WAVELET_BATYPE;Contrast balance method +!TP_WAVELET_CCURVE;Local contrast +!TP_WAVELET_CH1;Whole chromaticity range +!TP_WAVELET_CH2;Saturated/pastel +!TP_WAVELET_CH3;Link contrast levels +!TP_WAVELET_CHCU;Curve +!TP_WAVELET_CHRO;Saturated/pastel threshold +!TP_WAVELET_CHRO_TOOLTIP;Sets the wavelet level which will be the threshold between saturated and pastel colors.\n1-x: saturated\nx-9: pastel\n\nIf the value exceeds the amount of wavelet levels you are using then it will be ignored. +!TP_WAVELET_CHR;Chroma-contrast link strength +!TP_WAVELET_CHR_TOOLTIP;Adjusts chromaticity as a function of "contrast levels" and "chroma-contrast link strength" +!TP_WAVELET_CHSL;Sliders +!TP_WAVELET_CHTYPE;Chrominance method +!TP_WAVELET_COLORT;Opacity Red-Green +!TP_WAVELET_COMBOTH;Both +!TP_WAVELET_COMPCONT;Contrast +!TP_WAVELET_COMPGAMMA;Compression gamma +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjusting the gamma of the residual image allow you to equilibrate the data and histogram. +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjust gamma for residual image and compression.\nAllow to equilibrate data and histogram +!TP_WAVELET_COMPTM;Tone mapping +!TP_WAVELET_CONTEDIT;'After' Contrast curve +!TP_WAVELET_CONTEDIT;'After' contrast curve +!TP_WAVELET_CONTRAST_MINUS;Contrast - +!TP_WAVELET_CONTRAST_PLUS;Contrast + +!TP_WAVELET_CONTRA;Contrast +!TP_WAVELET_CONTRA_TOOLTIP;Changes contrast of the residual image. +!TP_WAVELET_CONTR;Gamut +!TP_WAVELET_CTYPE;Chrominance control +!TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modifies local contrast as a function of the original local contrast (absciss)\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 100..300)\n66% absciss represents standard deviation of local contrast (real value about 300..800)\n100% represents maximum (real value about 3000..8000) +!TP_WAVELET_CURVEEDITOR_CH;Contrast levels=f(Hue) +!TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modifies each level's contrast as a function oh hue.\nTake care not to overwrite changes made with the Gamut Hue controls.\nThe curve will only have an effect when wavelet contrast level sliders are non-zero. +!TP_WAVELET_CURVEEDITOR_CL;L +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Applies a final contrast luminance curve at the end of the wavelet treatment. +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Apply a contrast luminance curve at the end of wavelet level threatment +!TP_WAVELET_CURVEEDITOR_HH;HH +!TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modifies the residual image's hue as a function of hue. +!TP_WAVELET_DALL;All directions +!TP_WAVELET_DAUB;Edge performance +!TP_WAVELET_DAUB_TOOLTIP;Changes Daubechies coefficients:\nD4 = Standard,\nD14 = Often best performance, 10% more time-intensive.\n\nAffects edge detection as well as the general quality of the firsts levels. However the quality is not strictly related to this coefficient and can vary with images and uses. +!TP_WAVELET_DISP;Preview Settings +!TP_WAVELET_DONE;Vertical +!TP_WAVELET_DTHR;Diagonal +!TP_WAVELET_DTWO;Horizontal +!TP_WAVELET_EDCU;Curve +!TP_WAVELET_EDGCONT;Local contrast +!TP_WAVELET_EDGCONT_TOOLTIP;Adjusting the points to the left decreases contrast, and to the right increases it.\nBottom-left, Top-Left, Top-Right, Bottom-right represent respectively local contast for low values, mean, mean+stdev, maxima +!TP_WAVELET_EDGEDETECTTHR2;Threshold high (detection) +!TP_WAVELET_EDGEDETECTTHR;Threshold low (noise) +!TP_WAVELET_EDGEDETECTTHR_TOOLTIP;This adjuster lets you target edge detection for example to avoid applying edge sharpness to fine details, such as noise in the sky. +!TP_WAVELET_EDGEDETECT;Gradient sensitivity +!TP_WAVELET_EDGEDETECT_TOOLTIP;Moving the slider to the right increases edge sensitivity. This affects local contrast, edge settings and noise. +!TP_WAVELET_EDGE;Edge Sharpness +!TP_WAVELET_EDGREINF_TOOLTIP;Reinforce or reduce the action of the first level, do the opposite to the second level, and leave the rest unchanged. +!TP_WAVELET_EDGTHRESH;Detail +!TP_WAVELET_EDGTHRESH_TOOLTIP;Change the repartition between the first levels and the others. The higher the threshold the more the action is centred on the first levels. Be careful with negative values, they increase the action of high levels and can introduce artifacts. +!TP_WAVELET_EDRAD;Radius +!TP_WAVELET_EDRAD_TOOLTIP;This radius adjustment is very different from those in other sharpening tools. Its value is compared to each level through a complex function. In this sense, a value of zero still has an effect. +!TP_WAVELET_EDSL;Threshold Sliders +!TP_WAVELET_EDTYPE;Local contrast method +!TP_WAVELET_EDVAL;Strength +!TP_WAVELET_FINAL;Final Touchup +!TP_WAVELET_FINEST;Finest +!TP_WAVELET_HIGHLIGHT;Highlight luminance range +!TP_WAVELET_HS1;Whole luminance range +!TP_WAVELET_HS2;Shadows/Highlights +!TP_WAVELET_HUESKIN;Skin hue +!TP_WAVELET_HUESKIN_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_HUESKY;Sky hue +!TP_WAVELET_HUESKY_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_INF;Below or equal the level +!TP_WAVELET_ITER;Delta balance levels +!TP_WAVELET_ITER_TOOLTIP;Left: increase low levels and reduce high levels,\nRight: reduce low levels and increase high levels. +!TP_WAVELET_LABEL;Wavelet levels +!TP_WAVELET_LARGEST;Coarsest +!TP_WAVELET_LEVCH;Chromaticity +!TP_WAVELET_LEVELS;Wavelet levels +!TP_WAVELET_LEVELS_TOOLTIP;Choose the number of detail levels the image is to be decomposed into. More levels require more RAM and require a longer processing time. +!TP_WAVELET_LEVF;Contrast +!TP_WAVELET_LEVLABEL;Preview maximum possible levels = %1 +!TP_WAVELET_LEVONE;Level 2 +!TP_WAVELET_LEVTWO;Level 3 +!TP_WAVELET_LEVZERO;Level 1 +!TP_WAVELET_LINKEDG;Link with Edge Sharpness' Strength +!TP_WAVELET_LIPST;Enhanced algorithm +!TP_WAVELET_LIPST_TOOLTIP;This algorithm uses Lipschitz regularity to increase edge detection quality at a cost of increased processing time and memory requirements. +!TP_WAVELET_LOWLIGHT;Shadow luminance range +!TP_WAVELET_MEDGREINF;First level +!TP_WAVELET_MEDILEV;Edge detection +!TP_WAVELET_MEDI;Reduce artifacts in blue sky +!TP_WAVELET_NEUTRAL;Neutral +!TP_WAVELET_NOISE;Denoise and Refine +!TP_WAVELET_NOIS;Denoise +!TP_WAVELET_ONE;One level +!TP_WAVELET_OPACITYWL;Final local contrast +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify final local contrast in function of last local contrast (absciss) for all levels decomposition\nTake into account: \na)contrast levels \nb)edge sharpness \nc)contrast balance\nd)decomposition-recomposition\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 200..1000)\n66% absciss represents standard deviation of local contrast (real value about 1000..2000)\n100% represents maximum (real value about 5000..13000) +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify the final local contrast at the end of the wavelet treatment.\n\nThe left side represents the smallest local contrast, progressing to the largest local contrast on the right. +!TP_WAVELET_OPACITYW;Contrast balance d/v-h curve +!TP_WAVELET_OPACITY;Opacity Blue-Yellow +!TP_WAVELET_PASTEL;Pastel chromaticity +!TP_WAVELET_PREVIEWBACK;Background +!TP_WAVELET_PREVIEWLEVELS;Preview +!TP_WAVELET_RE1;Reinforced +!TP_WAVELET_RE2;Unchanged +!TP_WAVELET_RE3;Reduced +!TP_WAVELET_RESCHRO;Chromaticity +!TP_WAVELET_RESCONH;Highlights +!TP_WAVELET_RESCON;Shadows +!TP_WAVELET_RESID;Residual image +!TP_WAVELET_SAT;Saturated chromaticity +!TP_WAVELET_SETTINGS;Wavelet Settings +!TP_WAVELET_SKIN;Skin targetting/protection +!TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected. +!TP_WAVELET_SKY;Sky targetting/protection +!TP_WAVELET_SKY_TOOLTIP;At -100 sky-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 sky-tones are protected while all other tones are affected. +!TP_WAVELET_STRENGTH;Strength +!TP_WAVELET_STREN;Strength +!TP_WAVELET_SUPE;Extra +!TP_WAVELET_SUP;Above the level +!TP_WAVELET_THRESHOLD2;Shadow levels +!TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels between 9 and 9 minus the value will be affected by the shadow luminance range. Other levels will be fully treated. The highest level possible is limited by the highlight level value (9 minus highlight level value). +!TP_WAVELET_THRESHOLD;Highlight levels +!TP_WAVELET_THRESHOLD_TOOLTIP;Only levels beyond the chosen value will be affected by the highlight luminance range. Other levels will be fully treated. The chosen value here limits the highest possible value of the shadow levels. +!TP_WAVELET_THRH;Highlights threshold +!TP_WAVELET_THR;Shadows threshold +!TP_WAVELET_TILESBIG;Big tiles +!TP_WAVELET_TILESFULL;Full image +!TP_WAVELET_TILESIZE;Tiling method +!TP_WAVELET_TILESLIT;Little tiles +!TP_WAVELET_TILES_TOOLTIP;Processing the full image leads to better quality and is the recommended option, while using tiles is a fall-back solution for users with little RAM. Refer to RawPedia for memory requirements. +!TP_WAVELET_TMHIGH;High +!TP_WAVELET_TMLOWHIGH;Low+High +!TP_WAVELET_TMNONE;None +!TP_WAVELET_TMSTD;Standard +!TP_WAVELET_TMSTRENGTH;Compression strength +!TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image. When the value is different from 0, the Strength and Gamma sliders of the Tone Mapping tool in the Exposure tab will become grayed out. +!TP_WAVELET_TMTYPE;Compression method +!TP_WAVELET_TON;Toning +!TP_WAVELET_daub2;D2 - low +!TP_WAVELET_daub4;D4 - standard +!TP_WAVELET_daub6;D6 - standard plus +!TP_WAVELET_daub10;D10 - medium +!TP_WAVELET_daub14;D14 - high +!TP_WBALANCE_EQBLUERED;Blue/Red equalizer +!TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behavior of "white balance" by modulating the blue/red balance.\nThis can be useful when shooting conditions:\na) are far from the standard illuminant (e.g. underwater),\nb) are far from conditions where calibrations were performed,\nc) where the matrices or ICC profiles are unsuitable. +!ZOOMPANEL_ZOOMFITCROPSCREEN;Fit crop to screen\nShortcut: Alt-f diff --git a/rtdata/languages/English (UK) b/rtdata/languages/English (UK) new file mode 100644 index 000000000..064d56081 --- /dev/null +++ b/rtdata/languages/English (UK) @@ -0,0 +1,1850 @@ +EXPORT_BYPASS_RAW_CCSTEPS;Bypass [raw] False Colour Suppression +FILEBROWSER_COLORLABEL_TOOLTIP;Colour label.\n\nUse dropdown menu or shortcuts:\nShift-Ctrl-0 No Colour\nShift-Ctrl-1 Red\nShift-Ctrl-2 Yellow\nShift-Ctrl-3 Green\nShift-Ctrl-4 Blue\nShift-Ctrl-5 Purple +FILEBROWSER_POPUPCOLORLABEL;Colour label +FILEBROWSER_SHOWUNCOLORHINT;Show images without a colour label.\nShortcut: Alt-0 +FILECHOOSER_FILTER_COLPROF;Colour profiles +HISTORY_MSG_46;Colour denoising +HISTORY_MSG_69;Working colour space +HISTORY_MSG_70;Output colour space +HISTORY_MSG_71;Input colour space +HISTORY_MSG_111;L*a*b* - Avoid colour shift +HISTORY_MSG_115;False colour suppression +HISTORY_MSG_155;Vib - Avoid colour shift +HISTORY_MSG_191;CAM02 - Colourfulness (M) +HISTORY_MSG_197;CAM02 - Colour curve +HISTORY_MSG_198;CAM02 - Colour curve +HISTORY_MSG_221;B&W - Colour filter +HISTORY_MSG_240;GF - Centre +HISTORY_MSG_245;VC - Centre +HISTORY_MSG_257;Colour Toning +HISTORY_MSG_258;CT - Colour curve +HISTORY_MSG_322;W - Gamut - Avoid colour shift +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 +PARTIALPASTE_COLORGROUP;Colour Related Settings +PARTIALPASTE_COLORTONING;Colour Toning +PARTIALPASTE_ICMSETTINGS;Colour management settings +PARTIALPASTE_RAW_FALSECOLOR;Demosaic false colour suppression steps +PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor colour profile +PREFERENCES_BEHAVIOR;Behaviour +PREFERENCES_CMETRICINTENT;Colourimetric intent +PREFERENCES_CUTOVERLAYBRUSH;Crop mask colour/transparency +PREFERENCES_ICCDIR;Directory containing colour profiles +PREFERENCES_INTENT_ABSOLUTE;Absolute Colourimetric +PREFERENCES_INTENT_RELATIVE;Relative Colourimetric +PREFERENCES_MENUGROUPLABEL;Group "Colour label" +PREFERENCES_MONITORICC;Monitor colour profile +PREFERENCES_NAVGUIDEBRUSH;Navigator guide colour +PREFERENCES_TAB_COLORMGR;Colour Management +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 +TP_BWMIX_CC_TOOLTIP;Enable to allow automatic adjustment of complementary colours in ROYGCBPM mode. +TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Tone curve, just before B&W conversion.\nMay take into account the colour components. +TP_BWMIX_FILTER;Colour Filter +TP_BWMIX_FILTER_TOOLTIP;The colour filter simulates shots taken with a coloured filter placed in front of the lens. Coloured filters reduce the transmission of specific colour ranges and therefore affect their lightness. E.g. a red filter darkens blue skies. +TP_BWMIX_NEUTRAL_TIP;Reset all values (Colour Filter, Channel Mixer) to default. +TP_BWMIX_RGB_TOOLTIP;Mix the RGB channels. Use presets for guidance.\nPay attention to negative values that may cause artifacts or erratic behaviour. +TP_COLORAPP_ALGO_QM;Brightness + Colourfulness (QM) +TP_COLORAPP_BADPIXSL_TOOLTIP;Suppression of hot/bad (brightly coloured) pixels.\n0 = No effect\n1 = Median\n2 = Gaussian.\nAlternatively, adjust the image to avoid very dark shadows.\n\nThese artifacts are due to limitations of CIECAM02. +TP_COLORAPP_CHROMA_M;Colourfulnes (M) +TP_COLORAPP_CHROMA_M_TOOLTIP;Colourfulness in CIECAM02 differs from L*a*b* and RGB colourfulness. +TP_COLORAPP_CURVEEDITOR3;Colour curve +TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Adjust either chroma, saturation or colourfulness.\n\nShows the histogram of chromaticity (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of C, s or M after CIECAM02.\n\nC, s and M are not shown in the main histogram panel.\nFor final output refer to the main histogram panel. +TP_COLORAPP_LABEL;CIE Colour Appearance Model 2002 +TP_COLORAPP_MODEL_TOOLTIP;White-Point Model.\n\nWB [RT] + [output]: RT's white balance is used for the scene, CIECAM02 is set to D50, and the output device's white balance is set in Preferences > Colour Management.\n\nWB [RT+CAT02] + [output]: RT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences - Colour Management. +TP_COLORAPP_SURROUND_TOOLTIP;Changes tones and colours to take into account the viewing conditions of the output device.\n\nAverage: Average light environment (standard). The image will not change.\n\nDim: Dim environment (TV). The image will become slighty dark.\n\nDark: Dark environment (projector). The image will become more dark.\n\nExtremly Dark: Extremly dark environment (cutsheet). The image will become very dark. +TP_COLORAPP_TCMODE_COLORF;Colourfulness +TP_COLORTONING_COLOR;Colour +TP_COLORTONING_LABEL;Colour Toning +TP_COLORTONING_LUMAMODE_TOOLTIP;If enabled, when you change colour (red, green, cyan, blue, etc.) the luminance of each pixel is preserved. +TP_COLORTONING_METHOD_TOOLTIP;"L*a*b* blending", "RGB sliders" and "RGB curves" use interpolated colour blending.\n"Colour balance (Shadows/Midtones/Highlights)" and "Saturation 2 colours" use direct colours.\n\nThe Black-and-White tool can be enabled when using any colour toning method, which allows for colour toning. +TP_COLORTONING_SPLITCOCO;Colour Balance Shadows/Midtones/Highlights +TP_COLORTONING_SPLITLR;Saturation 2 colours +TP_COLORTONING_TWO2;Special chroma '2 colours' +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 colours:\nMore predictable. +TP_DIRPYRDENOISE_CTYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nAutomatic multi-zones\nNo preview - works only during saving, but using the "Preview" method by matching the tile size and centre to the preview size and centre you can get an idea of the expected results.\nThe image is divided into tiles (about 10 to 70 depending on image size) and each tile receives its own chrominance noise reduction settings.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on the gamma of the input colour profile. An sRGB gamma is assumed, thus if the image uses an input colour profile of a different gamma, the effects of luminance noise reduction will differ. +TP_DIRPYRDENOISE_PREVLABEL;Preview size=%1, Centre: Px=%2 Py=%3 +TP_DIRPYRDENOISE_TILELABEL;Tile size=%1, Centre: Tx=%2 Ty=%3 +TP_DIRPYREQUALIZER_ALGO;Skin Colour Range +TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fine: closer to the colours of the skin, minimizing the action on other colours\nLarge: avoid more artifacts. +TP_DIRPYREQUALIZER_TOOLTIP;Attempts to reduce artifacts in the transitions between skin colours (hue, chroma, luma) and the rest of the image. +TP_EPD_TOOLTIP;Tone mapping is possible in L*a*b* mode (standard) and CIECAM02 mode.\n\nWhen in L*a*b* mode, tone mapping can also be used on the residual image of the Wavelet Levels tool.\n\nTo engage CIECAM02 tone mapping mode enable the following settings:\n1. CIECAM02\n2. Algorithm="Brightness + Colourfulness (QM)"\n3. "Tone mapping using CIECAM02 brightness (Q)" +TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to colour cast. +TP_GRADIENT_CENTER;Centre +TP_GRADIENT_CENTER_X;Centre X +TP_GRADIENT_CENTER_Y;Centre Y +TP_HLREC_COLOR;Colour Propagation +TP_ICM_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input colour profiles. These profiles are more precise than simpler matrix ones. They are not available for all cameras. These profiles are stored in the /iccprofiles/input and /dcpprofiles folders and are automatically retrieved based on a file name matching to the exact model name of the camera. +TP_ICM_INPUTCAMERA_TOOLTIP;Use a simple colour matrix from dcraw, an enhanced RawTherapee version (whichever is available based on camera model) or one embedded in the DNG. +TP_ICM_INPUTCUSTOM_TOOLTIP;Select your own DCP/ICC colour profile file for the camera. +TP_ICM_INPUTEMBEDDED_TOOLTIP;Use colour profile embedded in non-raw files. +TP_ICM_INPUTNONE_TOOLTIP;Use no input colour profile at all.\nUse only in special cases. +TP_ICM_LABEL;Colour Management +TP_LABCURVE_AVOIDCOLORSHIFT;Avoid colour shift +TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colours into gamut of the working colour space and apply Munsell correction. +TP_PCVIGNETTE_FEATHER_TOOLTIP;Feathering:\n0 = corners only,\n50 = halfway to centre,\n100 = to centre. +TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Controls defringe strength by colour.\nHigher = more,\nLower = less. +TP_RAW_FALSECOLOR;False colour suppression steps +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 colour. +TP_VIBRANCE_AVOIDCOLORSHIFT;Avoid colour shift +TP_VIGNETTING_CENTER;Centre +TP_VIGNETTING_CENTER_X;Centre X +TP_VIGNETTING_CENTER_Y;Centre Y +TP_WAVELET_AVOID;Avoid colour shift +TP_WAVELET_CHRO_TOOLTIP;Sets the wavelet level which will be the threshold between saturated and pastel colours.\n1-x: saturated\nx-9: pastel\n\nIf the value exceeds the amount of wavelet levels you are using then it will be ignored. +TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behaviour of "white balance" by modulating the blue/red balance.\nThis can be useful when shooting conditions:\na) are far from the standard illuminant (e.g. underwater),\nb) are far from conditions where calibrations were performed,\nc) where the matrices or ICC profiles are unsuitable. +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!ABOUT_TAB_BUILD;Version +!ABOUT_TAB_CREDITS;Credits +!ABOUT_TAB_LICENSE;License +!ABOUT_TAB_RELEASENOTES;Release Notes +!ABOUT_TAB_SPLASH;Splash +!ADJUSTER_RESET_TO_DEFAULT;Reset to default +!BATCHQUEUE_AUTOSTART;Auto-start +!BATCHQUEUE_DESTFILENAME;Path and file name +!BATCH_PROCESSING;Batch Processing +!CURVEEDITOR_AXIS_IN;I: +!CURVEEDITOR_AXIS_LEFT_TAN;LT: +!CURVEEDITOR_AXIS_OUT;O: +!CURVEEDITOR_AXIS_RIGHT_TAN;RT: +!CURVEEDITOR_CURVES;Curves +!CURVEEDITOR_CURVE;Curve +!CURVEEDITOR_CUSTOM;Custom +!CURVEEDITOR_DARKS;Darks +!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_HIGHLIGHTS;Highlights +!CURVEEDITOR_LIGHTS;Lights +!CURVEEDITOR_LINEAR;Linear +!CURVEEDITOR_LOADDLGLABEL;Load curve... +!CURVEEDITOR_MINMAXCPOINTS;Equalizer +!CURVEEDITOR_NURBS;Control cage +!CURVEEDITOR_PARAMETRIC;Parametric +!CURVEEDITOR_SAVEDLGLABEL;Save curve... +!CURVEEDITOR_SHADOWS;Shadows +!CURVEEDITOR_TOOLTIPCOPY;Copy current curve to clipboard. +!CURVEEDITOR_TOOLTIPLINEAR;Reset curve to linear. +!CURVEEDITOR_TOOLTIPLOAD;Load a curve from file. +!CURVEEDITOR_TOOLTIPPASTE;Paste curve from clipboard. +!CURVEEDITOR_TOOLTIPSAVE;Save current curve. +!CURVEEDITOR_TYPE;Type: +!DIRBROWSER_FOLDERS;Folders +!EDITWINDOW_TITLE;Image Edit +!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_APERTURE;Aperture +!EXIFFILTER_CAMERA;Camera +!EXIFFILTER_EXPOSURECOMPENSATION;Exposure compensation (EV) +!EXIFFILTER_FILETYPE;File type +!EXIFFILTER_FOCALLEN;Focal length +!EXIFFILTER_ISO;ISO +!EXIFFILTER_LENS;Lens +!EXIFFILTER_METADATAFILTER;Enable metadata filters +!EXIFFILTER_SHUTTER;Shutter +!EXIFPANEL_ADDEDITHINT;Add new tag or edit tag. +!EXIFPANEL_ADDEDIT;Add/Edit +!EXIFPANEL_ADDTAGDLG_ENTERVALUE;Enter value +!EXIFPANEL_ADDTAGDLG_SELECTTAG;Select tag +!EXIFPANEL_ADDTAGDLG_TITLE;Add/Edit Tag +!EXIFPANEL_KEEPHINT;Keep the selected tags when writing output file. +!EXIFPANEL_KEEP;Keep +!EXIFPANEL_REMOVEHINT;Remove the selected tags when writing output file. +!EXIFPANEL_REMOVE;Remove +!EXIFPANEL_RESETALLHINT;Reset all tags to their original values. +!EXIFPANEL_RESETALL;Reset All +!EXIFPANEL_RESETHINT;Reset the selected tags to their original values. +!EXIFPANEL_RESET;Reset +!EXIFPANEL_SUBDIRECTORY;Subdirectory +!EXPORT_BYPASS_ALL;Select / Unselect All +!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_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_FF;Bypass [raw] Flat-Field +!EXPORT_BYPASS_RAW_GREENTHRESH;Bypass [raw] Green Equilibration +!EXPORT_BYPASS_RAW_LINENOISE;Bypass [raw] Line Noise Filter +!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_FASTEXPORTOPTIONS;Fast Export Options +!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_MAXHEIGHT;Maximum height: +!EXPORT_MAXWIDTH;Maximum width: +!EXPORT_PUTTOQUEUEFAST; Put to queue for fast export +!EXPORT_RAW_DMETHOD;Demosaic method +!EXTPROGTARGET_1;raw +!EXTPROGTARGET_2;queue-processed +!FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +!FILEBROWSER_APPLYPROFILE;Apply +!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_CACHECLEARFROMFULL;Clear from cache - full +!FILEBROWSER_CACHECLEARFROMPARTIAL;Clear from cache - partial +!FILEBROWSER_CACHE;Cache +!FILEBROWSER_CLEARPROFILE;Clear +!FILEBROWSER_COPYPROFILE;Copy +!FILEBROWSER_CURRENT_NAME;Current name: +!FILEBROWSER_DARKFRAME;Dark-frame +!FILEBROWSER_DELETEDLGLABEL;File delete confirmation +!FILEBROWSER_DELETEDLGMSGINCLPROC;Are you sure you want to delete the selected %1 files including a queue-processed version? +!FILEBROWSER_DELETEDLGMSG;Are you sure you want to delete the selected %1 files? +!FILEBROWSER_EMPTYTRASHHINT;Permanently delete the files from trash. +!FILEBROWSER_EMPTYTRASH;Empty trash +!FILEBROWSER_EXEC_CPB;Custom Profile Builder +!FILEBROWSER_EXTPROGMENU;Open with +!FILEBROWSER_FLATFIELD;Flat-Field +!FILEBROWSER_MOVETODARKFDIR;Move to dark-frames directory +!FILEBROWSER_MOVETOFLATFIELDDIR;Move to flat-fields directory +!FILEBROWSER_NEW_NAME;New name: +!FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) +!FILEBROWSER_PARTIALPASTEPROFILE;Paste - partial +!FILEBROWSER_PASTEPROFILE;Paste +!FILEBROWSER_POPUPCANCELJOB;Cancel job +!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_POPUPCOPYTO;Copy to... +!FILEBROWSER_POPUPFILEOPERATIONS;File operations +!FILEBROWSER_POPUPMOVEEND;Move to end of queue +!FILEBROWSER_POPUPMOVEHEAD;Move to head of queue +!FILEBROWSER_POPUPMOVETO;Move to... +!FILEBROWSER_POPUPOPENINEDITOR;Open in Editor +!FILEBROWSER_POPUPOPEN;Open +!FILEBROWSER_POPUPPROCESSFAST;Put to queue (Fast export) +!FILEBROWSER_POPUPPROCESS;Put to queue +!FILEBROWSER_POPUPPROFILEOPERATIONS;Processing profile operations +!FILEBROWSER_POPUPRANK0;Unrank +!FILEBROWSER_POPUPRANK1;Rank 1 * +!FILEBROWSER_POPUPRANK2;Rank 2 ** +!FILEBROWSER_POPUPRANK3;Rank 3 *** +!FILEBROWSER_POPUPRANK4;Rank 4 **** +!FILEBROWSER_POPUPRANK5;Rank 5 ***** +!FILEBROWSER_POPUPRANK;Rank +!FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +!FILEBROWSER_POPUPREMOVE;Delete +!FILEBROWSER_POPUPRENAME;Rename +!FILEBROWSER_POPUPSELECTALL;Select all +!FILEBROWSER_POPUPTRASH;Move to trash +!FILEBROWSER_POPUPUNRANK;Unrank +!FILEBROWSER_POPUPUNTRASH;Remove from trash +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!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_QUERYLABEL; Find: +!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_RENAMEDLGLABEL;Rename file +!FILEBROWSER_RENAMEDLGMSG;Rename file "%1" to: +!FILEBROWSER_SELECTDARKFRAME;Select dark-frame... +!FILEBROWSER_SELECTFLATFIELD;Select flat-field... +!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 +!FILEBROWSER_SHOWCOLORLABEL4HINT;Show images labeled Blue.\nShortcut: Alt-4 +!FILEBROWSER_SHOWCOLORLABEL5HINT;Show images labeled Purple.\nShortcut: Alt-5 +!FILEBROWSER_SHOWDIRHINT;Clear all filters.\nShortcut: d +!FILEBROWSER_SHOWEDITEDHINT;Show edited images.\nShortcut: 7 +!FILEBROWSER_SHOWEDITEDNOTHINT;Show not edited images.\nShortcut: 6 +!FILEBROWSER_SHOWEXIFINFO;Show Exif info.\n\nShortcuts:\ni - Multiple Editor Tabs Mode,\nAlt-i - Single Editor Tab Mode. +!FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!FILEBROWSER_SHOWRANK1HINT;Show images ranked as 1-star.\nShortcut: 1 +!FILEBROWSER_SHOWRANK2HINT;Show images ranked as 2-star.\nShortcut: 2 +!FILEBROWSER_SHOWRANK3HINT;Show images ranked as 3-star.\nShortcut: 3 +!FILEBROWSER_SHOWRANK4HINT;Show images ranked as 4-star.\nShortcut: 4 +!FILEBROWSER_SHOWRANK5HINT;Show images ranked as 5-star.\nShortcut: 5 +!FILEBROWSER_SHOWRECENTLYSAVEDHINT;Show saved images.\nShortcut: Alt-7 +!FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show unsaved images.\nShortcut: Alt-6 +!FILEBROWSER_SHOWTRASHHINT;Show contents of trash.\nShortcut: Ctrl-t +!FILEBROWSER_SHOWUNRANKHINT;Show unranked images.\nShortcut: 0 +!FILEBROWSER_STARTPROCESSINGHINT;Start processing the images in the queue. +!FILEBROWSER_STARTPROCESSING;Start processing +!FILEBROWSER_STOPPROCESSINGHINT;Stop processing the images in the queue. +!FILEBROWSER_STOPPROCESSING;Stop processing +!FILEBROWSER_THUMBSIZE;Thumbnail size +!FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives. +!FILEBROWSER_UNRANK_TOOLTIP;Unrank.\nShortcut: Shift-0 +!FILEBROWSER_ZOOMINHINT;Increase thumbnail size.\n\nShortcuts:\n+ - Multiple Editor Tabs Mode,\nAlt-+ - Single Editor Tab Mode. +!FILEBROWSER_ZOOMOUTHINT;Decrease thumbnail size.\n\nShortcuts:\n- - Multiple Editor Tabs Mode,\nAlt-- - Single Editor Tab Mode. +!FILECHOOSER_FILTER_ANY;All files +!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_ABOUT;About +!GENERAL_AFTER;After +!GENERAL_ASIMAGE;As Image +!GENERAL_AUTO;Automatic +!GENERAL_BEFORE;Before +!GENERAL_CANCEL;Cancel +!GENERAL_CLOSE;Close +!GENERAL_DISABLED;Disabled +!GENERAL_DISABLE;Disable +!GENERAL_ENABLED;Enabled +!GENERAL_ENABLE;Enable +!GENERAL_FILE;File +!GENERAL_LANDSCAPE;Landscape +!GENERAL_NA;n/a +!GENERAL_NONE;None +!GENERAL_NO;No +!GENERAL_OK;OK +!GENERAL_PORTRAIT;Portrait +!GENERAL_SAVE;Save +!GENERAL_UNCHANGED;(Unchanged) +!GENERAL_WARNING;Warning +!HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar.\nRight-click on image preview to freeze/unfreeze. +!HISTOGRAM_TOOLTIP_B;Show/Hide blue histogram. +!HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram. +!HISTOGRAM_TOOLTIP_FULL;Toggle full (off) or scaled (on) histogram. +!HISTOGRAM_TOOLTIP_G;Show/Hide green histogram. +!HISTOGRAM_TOOLTIP_L;Show/Hide CIELab luminance histogram. +!HISTOGRAM_TOOLTIP_RAW;Show/Hide raw histogram. +!HISTOGRAM_TOOLTIP_R;Show/Hide red histogram. +!HISTORY_CHANGED;Changed +!HISTORY_CUSTOMCURVE;Custom curve +!HISTORY_DELSNAPSHOT;Del +!HISTORY_FROMCLIPBOARD;From clipboard +!HISTORY_LABEL;History +!HISTORY_MSG_1;Photo loaded +!HISTORY_MSG_2;PP3 loaded +!HISTORY_MSG_3;PP3 changed +!HISTORY_MSG_4;History browsing +!HISTORY_MSG_5;Lightness +!HISTORY_MSG_6;Contrast +!HISTORY_MSG_7;Black +!HISTORY_MSG_8;Exposure compensation +!HISTORY_MSG_9;Highlight compression +!HISTORY_MSG_10;Shadow compression +!HISTORY_MSG_11;Tone curve 1 +!HISTORY_MSG_12;Auto levels +!HISTORY_MSG_13;Exposure clipping +!HISTORY_MSG_14;L*a*b* - Lightness +!HISTORY_MSG_15;L*a*b* - Contrast +!HISTORY_MSG_16;- +!HISTORY_MSG_17;- +!HISTORY_MSG_18;- +!HISTORY_MSG_19;L*a*b* - L* curve +!HISTORY_MSG_20;Sharpening +!HISTORY_MSG_21;USM - Radius +!HISTORY_MSG_22;USM - Amount +!HISTORY_MSG_23;USM - Threshold +!HISTORY_MSG_24;USM - Sharpen only edges +!HISTORY_MSG_25;USM - Edge detection radius +!HISTORY_MSG_26;USM - Edge tolerance +!HISTORY_MSG_27;USM - Halo control +!HISTORY_MSG_28;USM - Halo control amount +!HISTORY_MSG_29;Sharpening method +!HISTORY_MSG_30;RLD - Radius +!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_37;Auto levels +!HISTORY_MSG_38;White balance method +!HISTORY_MSG_39;WB - Temperature +!HISTORY_MSG_40;WB - Tint +!HISTORY_MSG_41;Tone curve 1 mode +!HISTORY_MSG_42;Tone curve 2 +!HISTORY_MSG_43;Tone curve 2 mode +!HISTORY_MSG_44;Lum. denoising radius +!HISTORY_MSG_45;Lum. denoising edge tolerance +!HISTORY_MSG_47;Blend ICC highlights with matrix +!HISTORY_MSG_48;Use DCP's tone curve +!HISTORY_MSG_49;DCP illuminant +!HISTORY_MSG_50;Shadows/Highlights +!HISTORY_MSG_51;S/H - Highlights +!HISTORY_MSG_52;S/H - Shadows +!HISTORY_MSG_53;S/H - Highlight tonal width +!HISTORY_MSG_54;S/H - Shadow tonal width +!HISTORY_MSG_55;S/H - Local contrast +!HISTORY_MSG_56;S/H - Radius +!HISTORY_MSG_57;Coarse rotation +!HISTORY_MSG_58;Horizontal flipping +!HISTORY_MSG_59;Vertical flipping +!HISTORY_MSG_60;Rotation +!HISTORY_MSG_61;Auto-fill +!HISTORY_MSG_62;Distortion correction +!HISTORY_MSG_63;Snapshot selected +!HISTORY_MSG_64;Crop +!HISTORY_MSG_65;CA correction +!HISTORY_MSG_66;Highlight reconstruction +!HISTORY_MSG_67;HR reconstruction amount +!HISTORY_MSG_68;HL reconstruction method +!HISTORY_MSG_72;VC - Amount +!HISTORY_MSG_73;Channel Mixer +!HISTORY_MSG_74;Resize - Scale +!HISTORY_MSG_75;Resize - Method +!HISTORY_MSG_76;Exif metadata +!HISTORY_MSG_77;IPTC metadata +!HISTORY_MSG_78;- +!HISTORY_MSG_79;Resize - Width +!HISTORY_MSG_80;Resize - Height +!HISTORY_MSG_81;Resize +!HISTORY_MSG_82;Profile changed +!HISTORY_MSG_83;S/H - Sharp mask +!HISTORY_MSG_84;Perspective correction +!HISTORY_MSG_85;LCP +!HISTORY_MSG_86;RGB curves - Luminosity mode +!HISTORY_MSG_87;Impulse noise reduction +!HISTORY_MSG_88;Impulse NR threshold +!HISTORY_MSG_89;Noise Reduction +!HISTORY_MSG_90;NR - Luminance +!HISTORY_MSG_91;NR - Chrominance master +!HISTORY_MSG_92;NR - Gamma +!HISTORY_MSG_93;CbDL - Value +!HISTORY_MSG_94;Contrast by Detail Levels +!HISTORY_MSG_95;L*a*b* - Chromaticity +!HISTORY_MSG_96;L*a*b* - a* curve +!HISTORY_MSG_97;L*a*b* - b* curve +!HISTORY_MSG_98;Demosaicing method +!HISTORY_MSG_99;Hot pixel filter +!HISTORY_MSG_100;RGB Saturation +!HISTORY_MSG_101;HSV - Hue +!HISTORY_MSG_102;HSV - Saturation +!HISTORY_MSG_103;HSV - Value +!HISTORY_MSG_104;HSV Equalizer +!HISTORY_MSG_105;Defringe +!HISTORY_MSG_106;Defringe - Radius +!HISTORY_MSG_107;Defringe - Threshold +!HISTORY_MSG_108;Highlight Compr. Threshold +!HISTORY_MSG_109;Resize - Bounding box +!HISTORY_MSG_110;Resize - Applies to +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;L*a*b* - Red/skin prot. +!HISTORY_MSG_114;DCB iterations +!HISTORY_MSG_116;DCB enhancement +!HISTORY_MSG_117;Raw CA correction - Red +!HISTORY_MSG_118;Raw CA correction - Blue +!HISTORY_MSG_119;Line noise filter +!HISTORY_MSG_120;Green equilibration +!HISTORY_MSG_121;Raw CA Correction - Auto +!HISTORY_MSG_122;Dark-Frame - Auto-selection +!HISTORY_MSG_123;Dark-Frame - File +!HISTORY_MSG_124;White point correction +!HISTORY_MSG_125;Highlight preservation +!HISTORY_MSG_126;Flat-Field - File +!HISTORY_MSG_127;Flat-Field - Auto-selection +!HISTORY_MSG_128;Flat-Field - Blur radius +!HISTORY_MSG_129;Flat-Field - Blur type +!HISTORY_MSG_130;Auto distorion correction +!HISTORY_MSG_131;NR - Luma +!HISTORY_MSG_132;NR - Chroma +!HISTORY_MSG_133;Output gamma +!HISTORY_MSG_134;Free gamma +!HISTORY_MSG_135;Free gamma +!HISTORY_MSG_136;Free gamma slope +!HISTORY_MSG_137;Black level - Green 1 +!HISTORY_MSG_138;Black level - Red +!HISTORY_MSG_139;Black level - Blue +!HISTORY_MSG_140;Black level - Green 2 +!HISTORY_MSG_141;Black level - Link greens +!HISTORY_MSG_142;ES - Iterations +!HISTORY_MSG_143;ES - Quantity +!HISTORY_MSG_144;Microcontrast - Quantity +!HISTORY_MSG_145;Microcontrast - Uniformity +!HISTORY_MSG_146;Edge sharpening +!HISTORY_MSG_147;ES - Luminance only +!HISTORY_MSG_148;Microcontrast +!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_150;Post-demosaic artifact/noise red. +!HISTORY_MSG_151;Vibrance +!HISTORY_MSG_152;Vib - Pastel tones +!HISTORY_MSG_153;Vib - Saturated tones +!HISTORY_MSG_154;Vib - Protect skin-tones +!HISTORY_MSG_156;Vib - Link pastel/saturated +!HISTORY_MSG_157;Vib - P/S threshold +!HISTORY_MSG_158;TM - Strength +!HISTORY_MSG_159;TM - Edge stopping +!HISTORY_MSG_160;TM - Scale +!HISTORY_MSG_161;TM - Reweighting iterates +!HISTORY_MSG_162;Tone Mapping +!HISTORY_MSG_163;RGB curves - Red +!HISTORY_MSG_164;RGB curves - Green +!HISTORY_MSG_165;RGB curves - Blue +!HISTORY_MSG_166;Neutral levels +!HISTORY_MSG_167;--unused-- +!HISTORY_MSG_168;L*a*b* - CC curve +!HISTORY_MSG_169;L*a*b* - CH curve +!HISTORY_MSG_170;Vibrance - HH curve +!HISTORY_MSG_171;L*a*b* - LC curve +!HISTORY_MSG_172;L*a*b* - Restrict LC +!HISTORY_MSG_173;NR - Luminance detail +!HISTORY_MSG_174;CIECAM02 +!HISTORY_MSG_175;CAM02 - CAT02 adaptation +!HISTORY_MSG_176;CAM02 - Viewing surround +!HISTORY_MSG_177;CAM02 - Scene luminosity +!HISTORY_MSG_178;CAM02 - Viewing luminosity +!HISTORY_MSG_179;CAM02 - White-point model +!HISTORY_MSG_180;CAM02 - Lightness (J) +!HISTORY_MSG_181;CAM02 - Chroma (C) +!HISTORY_MSG_182;CAM02 - Automatic CAT02 +!HISTORY_MSG_183;CAM02 - Contrast (J) +!HISTORY_MSG_184;CAM02 - Scene surround +!HISTORY_MSG_185;CAM02 - Gamut control +!HISTORY_MSG_186;CAM02 - Algorithm +!HISTORY_MSG_187;CAM02 - Red/skin prot. +!HISTORY_MSG_188;CAM02 - Brightness (Q) +!HISTORY_MSG_189;CAM02 - Contrast (Q) +!HISTORY_MSG_190;CAM02 - Saturation (S) +!HISTORY_MSG_192;CAM02 - Hue (h) +!HISTORY_MSG_193;CAM02 - Tone curve 1 +!HISTORY_MSG_194;CAM02 - Tone curve 2 +!HISTORY_MSG_195;CAM02 - Tone curve 1 +!HISTORY_MSG_196;CAM02 - Tone curve 2 +!HISTORY_MSG_199;CAM02 - Output histograms +!HISTORY_MSG_200;CAM02 - Tone mapping +!HISTORY_MSG_201;NR - Chrominance - R&G +!HISTORY_MSG_202;NR - Chrominance - B&Y +!HISTORY_MSG_203;NR - Method +!HISTORY_MSG_204;LMMSE enhancement steps +!HISTORY_MSG_205;CAM02 - Hot/bad pixel filter +!HISTORY_MSG_206;CAT02 - Auto scene luminosity +!HISTORY_MSG_207;Defringe - Hue curve +!HISTORY_MSG_208;WB - B/R equalizer +!HISTORY_MSG_210;GF - Angle +!HISTORY_MSG_211;Graduated Filter +!HISTORY_MSG_212;VF - Strength +!HISTORY_MSG_213;Vignette Filter +!HISTORY_MSG_214;Black-and-White +!HISTORY_MSG_215;B&W - CM - Red +!HISTORY_MSG_216;B&W - CM - Green +!HISTORY_MSG_217;B&W - CM - Blue +!HISTORY_MSG_218;B&W - Gamma - Red +!HISTORY_MSG_219;B&W - Gamma - Green +!HISTORY_MSG_220;B&W - Gamma - Blue +!HISTORY_MSG_222;B&W - Presets +!HISTORY_MSG_223;B&W - CM - Orange +!HISTORY_MSG_224;B&W - CM - Yellow +!HISTORY_MSG_225;B&W - CM - Cyan +!HISTORY_MSG_226;B&W - CM - Magenta +!HISTORY_MSG_227;B&W - CM - Purple +!HISTORY_MSG_228;B&W - Luminance equalizer +!HISTORY_MSG_229;B&W - Luminance equalizer +!HISTORY_MSG_230;B&W - Mode +!HISTORY_MSG_231;B&W - 'Before' curve +!HISTORY_MSG_232;B&W - 'Before' curve type +!HISTORY_MSG_233;B&W - 'After' curve +!HISTORY_MSG_234;B&W - 'After' curve type +!HISTORY_MSG_235;B&W - Auto channel mixer +!HISTORY_MSG_236;--unused-- +!HISTORY_MSG_237;B&W - Mixer +!HISTORY_MSG_238;GF - Feather +!HISTORY_MSG_239;GF - Strength +!HISTORY_MSG_241;VF - Feather +!HISTORY_MSG_242;VF - Roundness +!HISTORY_MSG_243;VC - Radius +!HISTORY_MSG_244;VC - Strength +!HISTORY_MSG_246;L*a*b* - CL curve +!HISTORY_MSG_247;L*a*b* - LH curve +!HISTORY_MSG_248;L*a*b* - HH curve +!HISTORY_MSG_249;CbDL - Threshold +!HISTORY_MSG_250;NR - Enhanced +!HISTORY_MSG_251;B&W - Algorithm +!HISTORY_MSG_252;CbDL - Skin tar/prot +!HISTORY_MSG_253;CbDL - Reduce artifacts +!HISTORY_MSG_254;CbDL - Skin hue +!HISTORY_MSG_255;NR - Median filter +!HISTORY_MSG_256;NR - Median type +!HISTORY_MSG_259;CT - Opacity curve +!HISTORY_MSG_260;CT - a*[b*] opacity +!HISTORY_MSG_261;CT - Method +!HISTORY_MSG_262;CT - b* opacity +!HISTORY_MSG_263;CT - Shadows - Red +!HISTORY_MSG_264;CT - Shadows - Green +!HISTORY_MSG_265;CT - Shadows - Blue +!HISTORY_MSG_266;CT - Mid - Red +!HISTORY_MSG_267;CT - Mid - Green +!HISTORY_MSG_268;CT - Mid - Blue +!HISTORY_MSG_269;CT - High - Red +!HISTORY_MSG_270;CT - High - Green +!HISTORY_MSG_271;CT - High - Blue +!HISTORY_MSG_272;CT - Balance +!HISTORY_MSG_273;CT - Reset +!HISTORY_MSG_274;CT - Sat. Shadows +!HISTORY_MSG_275;CT - Sat. Highlights +!HISTORY_MSG_276;CT - Opacity +!HISTORY_MSG_277;--unused-- +!HISTORY_MSG_278;CT - Preserve luminance +!HISTORY_MSG_279;CT - Shadows +!HISTORY_MSG_280;CT - Highlights +!HISTORY_MSG_281;CT - Sat. strength +!HISTORY_MSG_282;CT - Sat. threshold +!HISTORY_MSG_283;CT - Strength +!HISTORY_MSG_284;CT - Auto sat. protection +!HISTORY_MSG_285;NR - Median - Method +!HISTORY_MSG_286;NR - Median - Type +!HISTORY_MSG_287;NR - Median - Iterations +!HISTORY_MSG_288;Flat Field - Clip control +!HISTORY_MSG_289;Flat Field - Clip control - Auto +!HISTORY_MSG_290;Black Level - Red +!HISTORY_MSG_291;Black Level - Green +!HISTORY_MSG_292;Black Level - Blue +!HISTORY_MSG_293;Film Simulation +!HISTORY_MSG_294;Film Simulation - Strength +!HISTORY_MSG_295;Film Simulation - Film +!HISTORY_MSG_296;NR - Luminance curve +!HISTORY_MSG_297;NR - Quality +!HISTORY_MSG_298;Dead pixel filter +!HISTORY_MSG_299;NR - Chrominance curve +!HISTORY_MSG_300;- +!HISTORY_MSG_301;NR - Luma control +!HISTORY_MSG_302;NR - Chroma method +!HISTORY_MSG_303;NR - Chroma method +!HISTORY_MSG_304;W - Contrast levels +!HISTORY_MSG_305;Wavelet Levels +!HISTORY_MSG_306;W - Preview +!HISTORY_MSG_307;W - Preview +!HISTORY_MSG_308;W - Preview direction +!HISTORY_MSG_309;W - ES - Detail +!HISTORY_MSG_310;W - Residual - Sky tar/prot +!HISTORY_MSG_311;W - Wavelet levels +!HISTORY_MSG_312;W - Residual - Shadows threshold +!HISTORY_MSG_313;W - Chroma - Sat/past +!HISTORY_MSG_314;W - Gamut - Reduce artifacts +!HISTORY_MSG_315;W - Residual - Contrast +!HISTORY_MSG_316;W - Gamut - Skin tar/prot +!HISTORY_MSG_317;W - Gamut - Skin hue +!HISTORY_MSG_318;W - Contrast - Highlight levels +!HISTORY_MSG_319;W - Contrast - Highlight range +!HISTORY_MSG_320;W - Contrast - Shadow range +!HISTORY_MSG_321;W - Contrast - Shadow levels +!HISTORY_MSG_323;W - ES - Local contrast +!HISTORY_MSG_324;W - Chroma - Pastel +!HISTORY_MSG_325;W - Chroma - Saturated +!HISTORY_MSG_326;W - Chroma - Method +!HISTORY_MSG_327;W - Contrast - Apply to +!HISTORY_MSG_328;W - Chroma - Link strength +!HISTORY_MSG_329;W - Toning - Opacity RG +!HISTORY_MSG_330;W - Toning - Opacity BY +!HISTORY_MSG_331;W - Contrast levels - Extra +!HISTORY_MSG_332;W - Tiling method +!HISTORY_MSG_333;W - Residual - Shadows +!HISTORY_MSG_334;W - Residual - Chroma +!HISTORY_MSG_335;W - Residual - Highlights +!HISTORY_MSG_336;W - Residual - Highlights threshold +!HISTORY_MSG_337;W - Residual - Sky hue +!HISTORY_MSG_338;W - ES - Radius +!HISTORY_MSG_339;W - ES - Strength +!HISTORY_MSG_340;W - Strength +!HISTORY_MSG_341;W - Edge performance +!HISTORY_MSG_342;W - ES - First level +!HISTORY_MSG_343;W - Chroma levels +!HISTORY_MSG_344;W - Meth chroma sl/cur +!HISTORY_MSG_345;W - ES - Local contrast +!HISTORY_MSG_346;W - ES - Local contrast method +!HISTORY_MSG_347;W - Denoise - Level 0 +!HISTORY_MSG_348;W - Denoise - Level 1 +!HISTORY_MSG_349;W - Denoise - Level 2 +!HISTORY_MSG_350;W - ES - Edge detection +!HISTORY_MSG_351;W - Residual - HH curve +!HISTORY_MSG_352;W - Background +!HISTORY_MSG_353;W - ES - Gradient sensitivity +!HISTORY_MSG_354;W - ES - Enhance +!HISTORY_MSG_355;W - ES - Threshold low +!HISTORY_MSG_356;W - ES - Threshold high +!HISTORY_MSG_357;W - Denoise - Link with ES +!HISTORY_MSG_358;W - Gamut - CH +!HISTORY_MSG_359;Hot/Dead - Threshold +!HISTORY_MSG_360;TM Gamma +!HISTORY_MSG_361;W - Final - Chroma balance +!HISTORY_MSG_362;W - Residual - Compression method +!HISTORY_MSG_363;W - Residual - Compression strength +!HISTORY_MSG_364;W - Final - Contrast balance +!HISTORY_MSG_365;W - Final - Delta balance +!HISTORY_MSG_366;W - Residual - Compression gamma +!HISTORY_MSG_367;W - ES - Local contrast curve +!HISTORY_MSG_368;W - Final - Contrast balance +!HISTORY_MSG_369;W - Final - Balance method +!HISTORY_MSG_370;W - Final - Local contrast curve +!HISTORY_NEWSNAPSHOT;Add +!HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s +!HISTORY_SNAPSHOTS;Snapshots +!HISTORY_SNAPSHOT;Snapshot +!IPTCPANEL_AUTHORSPOSITIONHINT;Title of the creator or creators of the object (By-line Title). +!IPTCPANEL_AUTHORSPOSITION;Author's position +!IPTCPANEL_AUTHOR;Author +!IPTCPANEL_CAPTIONHINT;A textual description of the data (Caption - Abstract). +!IPTCPANEL_CAPTIONWRITERHINT;The name of the person involved in the writing, editing or correcting the image or caption/abstract (Writer - Editor). +!IPTCPANEL_CAPTIONWRITER;Caption writer +!IPTCPANEL_CAPTION;Caption +!IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider (Category). +!IPTCPANEL_CATEGORY;Category +!IPTCPANEL_CITYHINT;City of image origin (City). +!IPTCPANEL_CITY;City +!IPTCPANEL_COPYHINT;Copy IPTC settings to clipboard. +!IPTCPANEL_COPYRIGHTHINT;Any necessary copyright notice (Copyright Notice). +!IPTCPANEL_COPYRIGHT;Copyright +!IPTCPANEL_COUNTRYHINT;The name of the country/primary location where the image was created (Country - Primary Location Name). +!IPTCPANEL_COUNTRY;Country +!IPTCPANEL_CREDITHINT;Identifies the provider of the image, not necessarily the owner/creator (Credit). +!IPTCPANEL_CREDIT;Credit +!IPTCPANEL_DATECREATEDHINT;The date the intellectual content of the image was created; Format: YYYYMMDD (Date Created). +!IPTCPANEL_DATECREATED;Date created +!IPTCPANEL_EMBEDDEDHINT;Reset to IPTC data embedded in the image file. +!IPTCPANEL_EMBEDDED;Embedded +!IPTCPANEL_HEADLINEHINT;A publishable entry providing a synopsis of the contents of the image (Headline). +!IPTCPANEL_HEADLINE;Headline +!IPTCPANEL_INSTRUCTIONSHINT;Other editorial instructions concerning the use of the image (Special Instructions). +!IPTCPANEL_INSTRUCTIONS;Instructions +!IPTCPANEL_KEYWORDSHINT;Used to indicate specific information retrieval words (Keywords). +!IPTCPANEL_KEYWORDS;Keywords +!IPTCPANEL_PASTEHINT;Paste IPTC settings from clipboard. +!IPTCPANEL_PROVINCEHINT;The Province/State where the image originates (Province-State). +!IPTCPANEL_PROVINCE;Province +!IPTCPANEL_RESETHINT;Reset to profile default. +!IPTCPANEL_RESET;Reset +!IPTCPANEL_SOURCEHINT;The original owner of the intellectual content of the image (Source). +!IPTCPANEL_SOURCE;Source +!IPTCPANEL_SUPPCATEGORIESHINT;Further refines the subject of the image (Supplemental Categories). +!IPTCPANEL_SUPPCATEGORIES;Suppl. categories +!IPTCPANEL_TITLEHINT;A shorthand reference for the image (Object Name). +!IPTCPANEL_TITLE;Title +!IPTCPANEL_TRANSREFERENCEHINT;A code representing the location of the original transmission (Original Transmission Reference). +!IPTCPANEL_TRANSREFERENCE;Trans. reference +!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 +!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). +!MAIN_BUTTON_PREFERENCES;Preferences +!MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Put current image to processing queue.\nShortcut: Ctrl+b +!MAIN_BUTTON_SAVE_TOOLTIP;Save current image.\nShortcut: Ctrl+s +!MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Edit current image in external editor.\nShortcut: Ctrl+e +!MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Show/hide all side panels.\nShortcut: m +!MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen +!MAIN_FRAME_BATCHQUEUE;Queue +!MAIN_FRAME_BATCHQUEUE_TOOLTIP;Processing queue.\nShortcut: Ctrl-F3 +!MAIN_FRAME_EDITOR;Editor +!MAIN_FRAME_EDITOR_TOOLTIP;Editor.\nShortcut: Ctrl-F4 +!MAIN_FRAME_FILEBROWSER;File Browser +!MAIN_FRAME_FILEBROWSER_TOOLTIP;File browser.\nShortcut: Ctrl-F2 +!MAIN_FRAME_PLACES;Places +!MAIN_FRAME_PLACES_ADD;Add +!MAIN_FRAME_PLACES_DEL;Del +!MAIN_FRAME_RECENT;Recent Folders +!MAIN_MSG_ALREADYEXISTS;File already exists. +!MAIN_MSG_CANNOTLOAD;Cannot load image +!MAIN_MSG_CANNOTSAVE;File saving error +!MAIN_MSG_CANNOTSTARTEDITOR;Cannot start editor. +!MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Please set the correct path in Preferences. +!MAIN_MSG_EMPTYFILENAME;Filename unspecified! +!MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue-processed first. +!MAIN_MSG_NAVIGATOR;Navigator +!MAIN_MSG_OPERATIONCANCELLED;Operation cancelled +!MAIN_MSG_PATHDOESNTEXIST;The path\n\n%1\n\ndoes not exist. Please set a correct path in Preferences. +!MAIN_MSG_QOVERWRITE;Do you want to overwrite it? +!MAIN_MSG_SETPATHFIRST;You first have to set a target path in Preferences in order to use this function! +!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;Detail +!MAIN_TAB_DETAIL_TOOLTIP;Shortcut: Alt-d +!MAIN_TAB_DEVELOP; Develop +!MAIN_TAB_EXIF;Exif +!MAIN_TAB_EXPORT; Fast Export +!MAIN_TAB_EXPOSURE;Exposure +!MAIN_TAB_EXPOSURE_TOOLTIP;Shortcut: Alt-e +!MAIN_TAB_FILTER; Filter +!MAIN_TAB_INSPECT; Inspect +!MAIN_TAB_IPTC;IPTC +!MAIN_TAB_METADATA;Metadata +!MAIN_TAB_METADATA_TOOLTIP;Shortcut: Alt-m +!MAIN_TAB_RAW;Raw +!MAIN_TAB_RAW_TOOLTIP;Shortcut: Alt-r +!MAIN_TAB_TRANSFORM;Transform +!MAIN_TAB_TRANSFORM_TOOLTIP;Shortcut: Alt-t +!MAIN_TAB_WAVELET;Wavelet +!MAIN_TAB_WAVELET_TOOLTIP;Shortcut: Alt-w +!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: < +!MAIN_TOOLTIP_INDCLIPPEDS;Clipped shadow indication.\nShortcut: > +!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%. +!MAIN_TOOLTIP_PREVIEWG;Preview the Green channel.\nShortcut: g +!MAIN_TOOLTIP_PREVIEWL;Preview the Luminosity.\nShortcut: v\n\n0.299*R + 0.587*G + 0.114*B +!MAIN_TOOLTIP_PREVIEWR;Preview the Red channel.\nShortcut: r +!MAIN_TOOLTIP_QINFO;Quick info on the image.\nShortcut: i +!MAIN_TOOLTIP_SHOWHIDELP1;Show/Hide the left panel.\nShortcut: l +!MAIN_TOOLTIP_SHOWHIDERP1;Show/Hide the right panel.\nShortcut: Alt-l +!MAIN_TOOLTIP_SHOWHIDETP1;Show/Hide the top panel.\nShortcut: Shift-l +!MAIN_TOOLTIP_THRESHOLD;Threshold +!MAIN_TOOLTIP_TOGGLE;Toggle the Before/After view.\nShortcut: Shift-b +!NAVIGATOR_B;B: +!NAVIGATOR_G;G: +!NAVIGATOR_H;H: +!NAVIGATOR_LAB_A;a*: +!NAVIGATOR_LAB_B;b*: +!NAVIGATOR_LAB_L;L*: +!NAVIGATOR_NA; -- +!NAVIGATOR_R;R: +!NAVIGATOR_S;S: +!NAVIGATOR_V;V: +!NAVIGATOR_XY_FULL;Width: %1, Height: %2 +!NAVIGATOR_XY_NA;x: --, y: -- +!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_BASICGROUP;Basic Settings +!PARTIALPASTE_CACORRECTION;Chromatic aberration correction +!PARTIALPASTE_CHANNELMIXERBW;Black-and-White +!PARTIALPASTE_CHANNELMIXER;Channel mixer +!PARTIALPASTE_COARSETRANS;Coarse rotation / flipping +!PARTIALPASTE_COLORAPP;CIECAM02 +!PARTIALPASTE_COMMONTRANSFORMPARAMS;Auto-fill +!PARTIALPASTE_COMPOSITIONGROUP;Composition Settings +!PARTIALPASTE_CROP;Crop +!PARTIALPASTE_DARKFRAMEAUTOSELECT;Dark-frame auto-selection +!PARTIALPASTE_DARKFRAMEFILE;Dark-frame file +!PARTIALPASTE_DEFRINGE;Defringe +!PARTIALPASTE_DETAILGROUP;Detail Settings +!PARTIALPASTE_DIALOGLABEL;Partial paste processing profile +!PARTIALPASTE_DIRPYRDENOISE;Noise reduction +!PARTIALPASTE_DIRPYREQUALIZER;Contrast by detail levels +!PARTIALPASTE_DISTORTION;Distortion correction +!PARTIALPASTE_EPD;Tone mapping +!PARTIALPASTE_EQUALIZER;Wavelet Equalizer +!PARTIALPASTE_EVERYTHING;Everything +!PARTIALPASTE_EXIFCHANGES;Exif +!PARTIALPASTE_EXPOSURE;Exposure +!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_GRADIENT;Graduated filter +!PARTIALPASTE_HSVEQUALIZER;HSV equalizer +!PARTIALPASTE_ICMGAMMA;Output gamma +!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_METAGROUP;Metadata +!PARTIALPASTE_PCVIGNETTE;Vignette filter +!PARTIALPASTE_PERSPECTIVE;Perspective +!PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter +!PARTIALPASTE_PREPROCESS_GREENEQUIL;Green equilibration +!PARTIALPASTE_PREPROCESS_HOTPIXFILT;Hot pixel filter +!PARTIALPASTE_PREPROCESS_LINEDENOISE;Line noise filter +!PARTIALPASTE_RAWCACORR_AUTO;CA auto-correction +!PARTIALPASTE_RAWCACORR_CABLUE;CA blue +!PARTIALPASTE_RAWCACORR_CARED;CA red +!PARTIALPASTE_RAWEXPOS_BLACK;Black levels +!PARTIALPASTE_RAWEXPOS_LINEAR;White point correction +!PARTIALPASTE_RAWEXPOS_PRESER;Highlight preservation +!PARTIALPASTE_RAWGROUP;Raw Settings +!PARTIALPASTE_RAW_DCBENHANCE;DCB enhancement +!PARTIALPASTE_RAW_DCBITERATIONS;Number of DCB iterations +!PARTIALPASTE_RAW_DMETHOD;Demosaic method +!PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!PARTIALPASTE_RESIZE;Resize +!PARTIALPASTE_RGBCURVES;RGB curves +!PARTIALPASTE_ROTATION;Rotation +!PARTIALPASTE_SHADOWSHIGHLIGHTS;Shadows/highlights +!PARTIALPASTE_SHARPENEDGE;Edges +!PARTIALPASTE_SHARPENING;Sharpening (USM/RL) +!PARTIALPASTE_SHARPENMICRO;Microcontrast +!PARTIALPASTE_VIBRANCE;Vibrance +!PARTIALPASTE_VIGNETTING;Vignetting correction +!PARTIALPASTE_WAVELETGROUP;Wavelet processing +!PARTIALPASTE_WHITEBALANCE;White balance +!PREFERENCES_ADD;Add +!PREFERENCES_APPLNEXTSTARTUP;restart required +!PREFERENCES_AUTLISLOW;Low +!PREFERENCES_AUTLISMAX;Max - Average of all tiles +!PREFERENCES_AUTLISSTD;High +!PREFERENCES_AUTLISVLOW;None +!PREFERENCES_AUTLOW;Low +!PREFERENCES_AUTSTD;Standard +!PREFERENCES_BATCH_PROCESSING;Batch Processing +!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_BEHADDALL;All to 'Add' +!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_BEHSETALL;All to 'Set' +!PREFERENCES_BLACKBODY;Tungsten +!PREFERENCES_CACHECLEARALL;Clear All +!PREFERENCES_CACHECLEARPROFILES;Clear Processing Profiles +!PREFERENCES_CACHECLEARTHUMBS;Clear Thumbnails +!PREFERENCES_CACHEMAXENTRIES;Maximum number of cache entries +!PREFERENCES_CACHEOPTS;Cache Options +!PREFERENCES_CACHETHUMBHEIGHT;Maximum thumbnail height +!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_CLIPPINGIND;Clipping Indication +!PREFERENCES_CLUTSCACHE;HaldCLUT Cache +!PREFERENCES_CLUTSCACHE_LABEL;Maximum number of cached CLUTs +!PREFERENCES_CLUTSDIR;HaldCLUT directory +!PREFERENCES_CURVEBBOXPOS;Position of curve copypasta buttons +!PREFERENCES_CURVEBBOXPOS_ABOVE;Above +!PREFERENCES_CURVEBBOXPOS_BELOW;Below +!PREFERENCES_CURVEBBOXPOS_LEFT;Left +!PREFERENCES_CURVEBBOXPOS_RIGHT;Right +!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_CUSTPROFBUILD;Custom Processing Profile Builder +!PREFERENCES_D50;5000K +!PREFERENCES_D55;5500K +!PREFERENCES_D60;6000K +!PREFERENCES_D65;6500K +!PREFERENCES_DARKFRAMEFOUND;Found +!PREFERENCES_DARKFRAMESHOTS;shots +!PREFERENCES_DARKFRAMETEMPLATES;templates +!PREFERENCES_DARKFRAME;Dark-Frame +!PREFERENCES_DATEFORMATHINT;You can use the following formatting strings:\n%y - year\n%m - month\n%d - day\n\nFor example, the ISO 8601 standard dictates the date format as follows:\n%y-%m-%d +!PREFERENCES_DATEFORMAT;Date format +!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_DEFAULTLANG;Default Language +!PREFERENCES_DEFAULTTHEME;Default Theme +!PREFERENCES_DIRDARKFRAMES;Dark-frames directory +!PREFERENCES_DIRHOME;Home directory +!PREFERENCES_DIRLAST;Last visited directory +!PREFERENCES_DIROTHER;Other +!PREFERENCES_DIRSELECTDLG;Select Image Directory at Startup... +!PREFERENCES_DIRSOFTWARE;Installation directory +!PREFERENCES_EDITORCMDLINE;Other command line +!PREFERENCES_EDITORLAYOUT;Editor Layout +!PREFERENCES_EXPAUT;Expert +!PREFERENCES_EXTERNALEDITOR;External Editor +!PREFERENCES_FBROWSEROPTS;File Browser / Thumbnail Options +!PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar (de-select for low resolution display) +!PREFERENCES_FILEFORMAT;File format +!PREFERENCES_FILMSIMULATION;Film Simulation +!PREFERENCES_FLATFIELDFOUND;Found +!PREFERENCES_FLATFIELDSDIR;Flat-fields directory +!PREFERENCES_FLATFIELDSHOTS;shots +!PREFERENCES_FLATFIELDTEMPLATES;templates +!PREFERENCES_FLATFIELD;Flat-Field +!PREFERENCES_FLUOF2;Fluorescent F2 +!PREFERENCES_FLUOF7;Fluorescent F7 +!PREFERENCES_FLUOF11;Fluorescent F11 +!PREFERENCES_FORIMAGE;For non-raw photos +!PREFERENCES_FORRAW;For raw photos +!PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT;Same thumbnail height between the Editor's panel 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 installation directory +!PREFERENCES_GREY05;Yb=05 CIE L#30 +!PREFERENCES_GREY10;Yb=10 CIE L#40 +!PREFERENCES_GREY15;Yb=15 CIE L#45 +!PREFERENCES_GREY18;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_GREYSC18;Yb=18 CIE L#50 +!PREFERENCES_GREYSCA;Automatic +!PREFERENCES_GREYSC;Scene Yb luminance (%) +!PREFERENCES_GREY;Output device's Yb luminance (%) +!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_HLTHRESHOLD;Threshold for clipped highlights +!PREFERENCES_IMG_RELOAD_NEEDED;These changes require the image to be reloaded (or a new image to be opened) to take effect. +!PREFERENCES_IMPROCPARAMS;Default Processing Profile +!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_INTENT_PERCEPTUAL;Perceptual +!PREFERENCES_INTENT_SATURATION;Saturation +!PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Show embedded JPEG thumbnail if raw is unedited +!PREFERENCES_LANGAUTODETECT;Use system language +!PREFERENCES_LEVAUTDN;Denoising level +!PREFERENCES_LEVDN;Cell size +!PREFERENCES_LISS;Auto multi-zone smoothing +!PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders +!PREFERENCES_MAX;Maxi (Tile) +!PREFERENCES_MED;Medium (Tile/2) +!PREFERENCES_MENUGROUPEXTPROGS;Group "Open with" +!PREFERENCES_MENUGROUPFILEOPERATIONS;Group "File operations" +!PREFERENCES_MENUGROUPPROFILEOPERATIONS;Group "Processing profile operations" +!PREFERENCES_MENUGROUPRANK;Group "Rank" +!PREFERENCES_MENUOPTIONS;Context Menu Options +!PREFERENCES_METADATA;Metadata +!PREFERENCES_MIN;Mini (100x115) +!PREFERENCES_MULTITABDUALMON;Multiple Editor Tabs In Own Window Mode +!PREFERENCES_MULTITAB;Multiple Editor Tabs Mode +!PREFERENCES_NAVIGATIONFRAME;Navigation +!PREFERENCES_NOISE;Noise Reduction +!PREFERENCES_OUTDIRFOLDERHINT;Save images to the selected folder. +!PREFERENCES_OUTDIRFOLDER;Save to folder +!PREFERENCES_OUTDIRTEMPLATEHINT;You can use the following formatting strings:\n%f, %d1, %d2, ..., %p1, %p2, ..., %r, %s1, %s2, ...\n\nThese formatting strings refer to the different parts of the photo's pathname, some attributes of the photo or an arbitrary sequence index in the batch job.\n\nFor example, if the photo being processed has the following pathname:\n/home/tom/photos/2010-10-31/dsc0042.nef\nthe meaning of the formatting strings are:\n%d4 = home\n%d3 = tom\n%d2 = photos\n%d1 = 2010-10-31\n%f = dsc0042\n%p1 = /home/tom/photos/2010-10-31/\n%p2 = /home/tom/photos/\n%p3 = /home/tom/\n%p4 = /home/\n\n%r will be replaced by the rank of the photo. If the photo is unranked, %r will be replaced by '0'. If the photo is in the trash bin, %r will be replaced by 'x'.\n\n%s1, %s2, etc. will be replaced by a sequence index which is padded to between 1 and 9 digits. The sequence index will start at one each time the queue processing is started and is incremented by one for each image processed.\n\nIf you want to save the output image where the original is, write:\n%p1/%f\n\nIf you want to save the output image in a directory named "converted" located in the directory of the opened image, write:\n%p1/converted/%f\n\nIf you want to save the output image in a directory named "/home/tom/photos/converted/2010-10-31", write:\n%p2/converted/%d1/%f +!PREFERENCES_OUTDIRTEMPLATE;Use template +!PREFERENCES_OUTDIR;Output Directory +!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_PARSEDEXTADDHINT;Add entered extension to the list. +!PREFERENCES_PARSEDEXTADD;Add extension +!PREFERENCES_PARSEDEXTDELHINT;Delete selected extension from the list. +!PREFERENCES_PARSEDEXT;Parsed Extensions +!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_PROFILEHANDLING;Processing Profile Handling +!PREFERENCES_PROFILELOADPR;Processing profile loading priority +!PREFERENCES_PROFILEPRCACHE;Profile in cache +!PREFERENCES_PROFILEPRFILE;Profile next to the input file +!PREFERENCES_PROFILESAVECACHE;Save processing profile to the cache +!PREFERENCES_PROFILESAVEINPUT;Save processing profile next to the input file +!PREFERENCES_PROPERTY;Property +!PREFERENCES_PSPATH;Adobe Photoshop installation directory +!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 font +!PREFERENCES_SELECTLANG;Select language +!PREFERENCES_SELECTTHEME;Select theme +!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_SHOWBASICEXIF;Show basic Exif info +!PREFERENCES_SHOWDATETIME;Show date and time +!PREFERENCES_SHOWEXPOSURECOMPENSATION;Append exposure compensation +!PREFERENCES_SHOWFILMSTRIPTOOLBAR;Show filmstrip toolbar +!PREFERENCES_SHTHRESHOLD;Threshold for clipped shadows +!PREFERENCES_SIMPLAUT;Tool mode +!PREFERENCES_SINGLETABVERTAB;Single Editor Tab Mode, Vertical Tabs +!PREFERENCES_SINGLETAB;Single Editor Tab Mode +!PREFERENCES_SLIMUI;Slim interface +!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_STARTUPIMDIR;Image Directory at Startup +!PREFERENCES_STDAUT;Standard +!PREFERENCES_TAB_BROWSER;File Browser +!PREFERENCES_TAB_GENERAL;General +!PREFERENCES_TAB_IMPROC;Image Processing +!PREFERENCES_TAB_PERFORMANCE;Performance & Quality +!PREFERENCES_TAB_SOUND;Sounds +!PREFERENCES_TIMAX;High +!PREFERENCES_TINB;Number of tiles +!PREFERENCES_TISTD;Standard +!PREFERENCES_TP_LABEL;Tool panel: +!PREFERENCES_TP_USEICONORTEXT;Use tab icons instead of text +!PREFERENCES_TP_VSCROLLBAR;Hide vertical scrollbar +!PREFERENCES_TUNNELMETADATA;Copy IPTC/XMP unchanged to output file (when tagging with other program) +!PREFERENCES_USEBUNDLEDPROFILES;Use bundled profiles +!PREFERENCES_USESYSTEMTHEME;Use system theme +!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_WORKFLOW;Layout +!PROFILEPANEL_COPYPPASTE;Parameters to copy +!PROFILEPANEL_GLOBALPROFILES;Bundled profiles +!PROFILEPANEL_LABEL;Processing Profiles +!PROFILEPANEL_LOADDLGLABEL;Load Processing Parameters... +!PROFILEPANEL_LOADPPASTE;Parameters to load +!PROFILEPANEL_MODE_TIP;Processing profile fill mode.\n\nButton pressed: partial profiles will be converted to full profiles; the missing values will be replaced with hard-coded defaults.\n\nButton released: profiles will be applied as they are, altering only those values which they contain. +!PROFILEPANEL_MYPROFILES;My profiles +!PROFILEPANEL_PASTEPPASTE;Parameters to paste +!PROFILEPANEL_PCUSTOM;Custom +!PROFILEPANEL_PFILE;From file +!PROFILEPANEL_PINTERNAL;Neutral +!PROFILEPANEL_PLASTSAVED;Last Saved +!PROFILEPANEL_SAVEDLGLABEL;Save Processing Parameters... +!PROFILEPANEL_SAVEPPASTE;Parameters to save +!PROFILEPANEL_TOOLTIPCOPY;Copy current processing profile to clipboard.\nCtrl-click to select the parameters to copy. +!PROFILEPANEL_TOOLTIPLOAD;Load a profile from file.\nCtrl-click to select the parameters to load. +!PROFILEPANEL_TOOLTIPPASTE;Paste profile from clipboard.\nCtrl-click to select the parameters to paste. +!PROFILEPANEL_TOOLTIPSAVE;Save current profile.\nCtrl-click to select the parameters to save. +!PROGRESSBAR_LOADINGTHUMBS;Loading thumbnails... +!PROGRESSBAR_LOADING;Loading image... +!PROGRESSBAR_LOADJPEG;Loading JPEG file... +!PROGRESSBAR_LOADPNG;Loading PNG file... +!PROGRESSBAR_LOADTIFF;Loading TIFF file... +!PROGRESSBAR_NOIMAGES;No images found +!PROGRESSBAR_PROCESSING;Processing image... +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing profile saved +!PROGRESSBAR_READY;Ready +!PROGRESSBAR_SAVEJPEG;Saving JPEG file... +!PROGRESSBAR_SAVEPNG;Saving PNG file... +!PROGRESSBAR_SAVETIFF;Saving TIFF file... +!PROGRESSBAR_SNAPSHOT_ADDED;Snapshot added +!PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!QINFO_ISO;ISO +!QINFO_NOEXIF;Exif data not available. +!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_PUTTOQUEUEHEAD;Put to the head of the processing queue +!SAVEDLG_PUTTOQUEUETAIL;Put to the end of the processing queue +!SAVEDLG_PUTTOQUEUE;Put into processing queue +!SAVEDLG_SAVEIMMEDIATELY;Save immediately +!SAVEDLG_SAVESPP;Save processing parameters with image +!SAVEDLG_SUBSAMP;Subsampling +!SAVEDLG_SUBSAMP_1;Best compression +!SAVEDLG_SUBSAMP_2;Balanced +!SAVEDLG_SUBSAMP_3;Best quality +!SAVEDLG_SUBSAMP_TOOLTIP;Best compression: 4:1:1\nBalanced: 4:2:2\nBest quality: 4:4:4 +!SAVEDLG_TIFFUNCOMPRESSED;Uncompressed TIFF +!SAVEDLG_WARNFILENAME;File will be named +!SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. +!THRESHOLDSELECTOR_BL;Bottom-left +!THRESHOLDSELECTOR_BR;Bottom-right +!THRESHOLDSELECTOR_B;Bottom +!THRESHOLDSELECTOR_HINT;Hold the Shift key to move individual control points. +!THRESHOLDSELECTOR_TL;Top-left +!THRESHOLDSELECTOR_TR;Top-right +!THRESHOLDSELECTOR_T;Top +!TOOLBAR_TOOLTIP_CROP;Crop selection.\nShortcut: c\nMove the crop area using Shift-mouse drag +!TOOLBAR_TOOLTIP_HAND;Hand tool.\nShortcut: h +!TOOLBAR_TOOLTIP_WB;Spot white balance.\nShortcut: w +!TP_BWMIX_ALGO;Algorithm OYCPM +!TP_BWMIX_ALGO_LI;Linear +!TP_BWMIX_ALGO_SP;Special effects +!TP_BWMIX_ALGO_TOOLTIP;Linear: will produce a normal linear response.\nSpecial effects: will produce special effects by mixing channels non-linearly. +!TP_BWMIX_AUTOCH;Auto +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing Channel Mixer. +!TP_BWMIX_CHANNEL;Luminance equalizer +!TP_BWMIX_CURVEEDITOR1;'Before' curve +!TP_BWMIX_CURVEEDITOR2;'After' curve +!TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Tone curve, after B&W conversion, at the end of treatment. +!TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H).\nPay attention to extreme values as they may cause artifacts. +!TP_BWMIX_FILTER_BLUEGREEN;Blue-Green +!TP_BWMIX_FILTER_BLUE;Blue +!TP_BWMIX_FILTER_GREENYELLOW;Green-Yellow +!TP_BWMIX_FILTER_GREEN;Green +!TP_BWMIX_FILTER_NONE;None +!TP_BWMIX_FILTER_PURPLE;Purple +!TP_BWMIX_FILTER_REDYELLOW;Red-Yellow +!TP_BWMIX_FILTER_RED;Red +!TP_BWMIX_FILTER_YELLOW;Yellow +!TP_BWMIX_GAMMA;Gamma Correction +!TP_BWMIX_GAM_TOOLTIP;Correct gamma for each RGB channel. +!TP_BWMIX_LABEL;Black-and-White +!TP_BWMIX_MET;Method +!TP_BWMIX_MET_CHANMIX;Channel Mixer +!TP_BWMIX_MET_DESAT;Desaturation +!TP_BWMIX_MET_LUMEQUAL;Luminance Equalizer +!TP_BWMIX_MIXC;Mixer +!TP_BWMIX_NEUTRAL;Reset mixer +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all the mixer options.\n"Total" displays the sum of the RGB values:\n- always 100% in relative mode\n- higher (lighter) or lower (darker) than 100% in absolute mode. +!TP_BWMIX_SETTING;Presets +!TP_BWMIX_SETTING_TOOLTIP;Different presets (film, landscape, etc.) or manual Channel Mixer settings. +!TP_BWMIX_SET_HIGHCONTAST;High contrast +!TP_BWMIX_SET_HIGHSENSIT;High Sensitivity +!TP_BWMIX_SET_HYPERPANCHRO;Hyper Panchromatic +!TP_BWMIX_SET_INFRARED;Infrared +!TP_BWMIX_SET_LANDSCAPE;Landscape +!TP_BWMIX_SET_LOWSENSIT;Low Sensitivity +!TP_BWMIX_SET_LUMINANCE;Luminance +!TP_BWMIX_SET_NORMCONTAST;Normal Contrast +!TP_BWMIX_SET_ORTHOCHRO;Orthochromatic +!TP_BWMIX_SET_PANCHRO;Panchromatic +!TP_BWMIX_SET_PORTRAIT;Portrait +!TP_BWMIX_SET_RGBABS;Absolute RGB +!TP_BWMIX_SET_RGBREL;Relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Relative ROYGCBPM +!TP_BWMIX_TCMODE_FILMLIKE;B&W Film-like +!TP_BWMIX_TCMODE_SATANDVALBLENDING;B&W Saturation and Value Blending +!TP_BWMIX_TCMODE_STANDARD;B&W Standard +!TP_BWMIX_TCMODE_WEIGHTEDSTD;B&W Weighted Standard +!TP_BWMIX_VAL;L +!TP_CACORRECTION_BLUE;Blue +!TP_CACORRECTION_LABEL;Chromatic Aberration Correction +!TP_CACORRECTION_RED;Red +!TP_CHMIXER_BLUE;Blue channel +!TP_CHMIXER_GREEN;Green channel +!TP_CHMIXER_LABEL;Channel Mixer +!TP_CHMIXER_RED;Red channel +!TP_CHROMATABERR_LABEL;Chromatic Aberration +!TP_COARSETRAF_TOOLTIP_HFLIP;Flip horizontally. +!TP_COARSETRAF_TOOLTIP_ROTLEFT;Rotate left.\n\nShortcuts:\n[ - Multiple Editor Tabs Mode,\nAlt-[ - Single Editor Tab Mode. +!TP_COARSETRAF_TOOLTIP_ROTRIGHT;Rotate right.\n\nShortcuts:\n] - Multiple Editor Tabs Mode,\nAlt-] - Single Editor Tab Mode. +!TP_COARSETRAF_TOOLTIP_VFLIP;Flip vertically. +!TP_COLORAPP_ADAPTSCENE;Scene luminosity +!TP_COLORAPP_ADAPTSCENE_TOOLTIP;Absolute luminance of the scene environement (cd/m²).\n1) Calculated from the Exif data:\nShutter speed - ISO speed - F number - camera exposure correction.\n2) Calculated from the raw white point and RT's Exposure Compensation slider. +!TP_COLORAPP_ADAPTVIEWING;Viewing luminosity (cd/m²) +!TP_COLORAPP_ADAPTVIEWING_TOOLTIP;Absolute luminance of the viewing environnement\n(usually 16cd/m²). +!TP_COLORAPP_ADAP_AUTO_TOOLTIP;If the checkbox is checked (recommended) RawTherapee calculates an optimum value from Exif data.\nTo set the value manually, uncheck the checkbox first. +!TP_COLORAPP_ALGO;Algorithm +!TP_COLORAPP_ALGO_ALL;All +!TP_COLORAPP_ALGO_JC;Lightness + Chroma (JC) +!TP_COLORAPP_ALGO_JS;Lightness + Saturation (JS) +!TP_COLORAPP_ALGO_TOOLTIP;Lets you choose between parameter subsets or all parameters. +!TP_COLORAPP_BADPIXSL;Hot/bad pixel filter +!TP_COLORAPP_BRIGHT;Brightness (Q) +!TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from L*a*b* and RGB brightness. +!TP_COLORAPP_CHROMA;Chroma (C) +!TP_COLORAPP_CHROMA_S;Saturation (S) +!TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from L*a*b* and RGB saturation. +!TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from L*a*b* and RGB chroma. +!TP_COLORAPP_CIECAT_DEGREE;CAT02 adaptation +!TP_COLORAPP_CONTRAST;Contrast (J) +!TP_COLORAPP_CONTRAST_Q;Contrast (Q) +!TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrast in CIECAM02 for the Q slider; it differs from L*a*b* and RGB contrast. +!TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from L*a*b* and RGB contrast. +!TP_COLORAPP_CURVEEDITOR1;Tone curve 1 +!TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L* (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of J or Q after CIECAM02.\n\nJ and Q are not shown in the main histogram panel.\n\nFor final output refer to the main histogram panel. +!TP_COLORAPP_CURVEEDITOR2;Tone curve 2 +!TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Same usage as with the second exposure tone curve. +!TP_COLORAPP_DATACIE;CIECAM02 output histograms in curves +!TP_COLORAPP_DATACIE_TOOLTIP;When enabled, histograms in CIECAM02 curves show approximate values/ranges for J or Q, and C, s or M after the CIECAM02 adjustments.\nThis selection does not impact the main histogram panel.\n\nWhen disabled, histograms in CIECAM02 curves show L*a*b* values before CIECAM02 adjustments. +!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RawTherapee calculates an optimum value, which is then used by CAT02, and also for the entire CIECAM02.\nTo set the value manually, uncheck the check-box first (values above 65 are recommended). +!TP_COLORAPP_DEGREE_TOOLTIP;Amount of CIE Chromatic Adaptation Transform 2002. +!TP_COLORAPP_GAMUT;Gamut control (L*a*b*) +!TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in L*a*b* mode. +!TP_COLORAPP_HUE;Hue (h) +!TP_COLORAPP_HUE_TOOLTIP;Hue (h) - angle between 0° and 360°. +!TP_COLORAPP_LABEL_CAM02;Image Adjustments +!TP_COLORAPP_LABEL_SCENE;Scene Conditions +!TP_COLORAPP_LABEL_VIEWING;Viewing Conditions +!TP_COLORAPP_LIGHT;Lightness (J) +!TP_COLORAPP_LIGHT_TOOLTIP;Lightness in CIECAM02 differs from L*a*b* and RGB lightness. +!TP_COLORAPP_MODEL;WP Model +!TP_COLORAPP_RSTPRO;Red & skin-tones protection +!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin-tones protection affects both sliders and curves. +!TP_COLORAPP_SHARPCIE;--unused-- +!TP_COLORAPP_SHARPCIE_TOOLTIP;--unused-- +!TP_COLORAPP_SURROUND;Surround +!TP_COLORAPP_SURROUND_AVER;Average +!TP_COLORAPP_SURROUND_DARK;Dark +!TP_COLORAPP_SURROUND_DIM;Dim +!TP_COLORAPP_SURROUND_EXDARK;Extremly Dark (Cutsheet) +!TP_COLORAPP_SURSOURCE;Dark surround +!TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if image has a dark border. +!TP_COLORAPP_TCMODE_BRIGHTNESS;Brightness +!TP_COLORAPP_TCMODE_CHROMA;Chroma +!TP_COLORAPP_TCMODE_LABEL1;Curve mode 1 +!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_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] +!TP_COLORAPP_WBRT;WB [RT] + [output] +!TP_COLORTONING_AB;o C/L +!TP_COLORTONING_AUTOSAT;Automatic +!TP_COLORTONING_BALANCE;Balance +!TP_COLORTONING_BY;o C/L +!TP_COLORTONING_CHROMAC;Opacity +!TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;Chroma opacity as a function of luminance oC=f(L) +!TP_COLORTONING_HIGHLIGHT;Highlights +!TP_COLORTONING_HUE;Hue +!TP_COLORTONING_LAB;L*a*b* blending +!TP_COLORTONING_LUMAMODE;Preserve luminance +!TP_COLORTONING_LUMA;Luminance +!TP_COLORTONING_METHOD;Method +!TP_COLORTONING_MIDTONES;Midtones +!TP_COLORTONING_NEUTRAL;Reset sliders +!TP_COLORTONING_NEUTRAL_TIP;Reset all values (Shadows, Midtones, Highlights) to default. +!TP_COLORTONING_OPACITY;Opacity +!TP_COLORTONING_RGBCURVES;RGB - Curves +!TP_COLORTONING_RGBSLIDERS;RGB - Sliders +!TP_COLORTONING_SATURATEDOPACITY;Strength +!TP_COLORTONING_SATURATIONTHRESHOLD;Threshold +!TP_COLORTONING_SA;Saturation Protection +!TP_COLORTONING_SHADOWS;Shadows +!TP_COLORTONING_SPLITCO;Shadows/Midtones/Highlights +!TP_COLORTONING_STRENGTH;Strength +!TP_COLORTONING_STR;Strength +!TP_COLORTONING_TWOALL;Special chroma +!TP_COLORTONING_TWOBY;Special a* and b* +!TP_COLORTONING_TWOSTD;Standard chroma +!TP_CROP_FIXRATIO;Lock ratio +!TP_CROP_GTDIAGONALS;Rule of Diagonals +!TP_CROP_GTEPASSPORT;Biometric Passport +!TP_CROP_GTFRAME;Frame +!TP_CROP_GTGRID;Grid +!TP_CROP_GTHARMMEANS;Harmonic Means +!TP_CROP_GTNONE;None +!TP_CROP_GTRULETHIRDS;Rule of Thirds +!TP_CROP_GTTRIANGLE1;Golden Triangles 1 +!TP_CROP_GTTRIANGLE2;Golden Triangles 2 +!TP_CROP_GUIDETYPE;Guide type: +!TP_CROP_H;Height +!TP_CROP_LABEL;Crop +!TP_CROP_PPI;PPI= +!TP_CROP_SELECTCROP;Select Crop +!TP_CROP_W;Width +!TP_CROP_X;X +!TP_CROP_Y;Y +!TP_DARKFRAME_AUTOSELECT;Auto-selection +!TP_DARKFRAME_LABEL;Dark-Frame +!TP_DEFRINGE_LABEL;Defringe +!TP_DEFRINGE_RADIUS;Radius +!TP_DEFRINGE_THRESHOLD;Threshold +!TP_DIRPYRDENOISE_33;3×3 strong +!TP_DIRPYRDENOISE_55SOFT;5×5 +!TP_DIRPYRDENOISE_55;5×5 strong +!TP_DIRPYRDENOISE_77;7×7 (slow) +!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_ABM;Chroma only +!TP_DIRPYRDENOISE_AUTO;Automatic global +!TP_DIRPYRDENOISE_AUTO_TOOLTIP;Try to evaluate chroma noise\nBe careful, this calculation is average, and is quite subjective ! +!TP_DIRPYRDENOISE_AUT;Automatic global +!TP_DIRPYRDENOISE_BLUE;Chrominance - Blue-Yellow +!TP_DIRPYRDENOISE_C2TYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CCCURVE;Chrominance curve +!TP_DIRPYRDENOISE_CHROMAFR;Chrominance +!TP_DIRPYRDENOISE_CHROMA;Chrominance - Master +!TP_DIRPYRDENOISE_CTYPE;Auto method +!TP_DIRPYRDENOISE_CURVEEDITOR_CC;Chroma +!TP_DIRPYRDENOISE_CURVEEDITOR_CC_TOOLTIP;Increase (multiply) the value of all chrominance sliders.\nThis curve lets you adjust the strength of chromatic noise reduction as a function of chromaticity, for instance to increase the action in areas of low saturation and to decrease it in those of high saturation. +!TP_DIRPYRDENOISE_CURVEEDITOR_L_TOOLTIP;Modulates action of 'Luminance' denoise +!TP_DIRPYRDENOISE_CUR;Curve +!TP_DIRPYRDENOISE_ENH;Enhanced mode +!TP_DIRPYRDENOISE_ENH_TOOLTIP;Increases noise reduction quality at the expense of a 20% processing time increase. +!TP_DIRPYRDENOISE_GAMMA;Gamma +!TP_DIRPYRDENOISE_GAMMA_TOOLTIP;Gamma varies noise reduction strength across the range of tones. Smaller values will target shadows, while larger values will stretch the effect to the brighter tones. +!TP_DIRPYRDENOISE_LABEL;Noise Reduction +!TP_DIRPYRDENOISE_LABM;L*a*b* +!TP_DIRPYRDENOISE_LAB;L*a*b* +!TP_DIRPYRDENOISE_LCURVE;Luminance curve +!TP_DIRPYRDENOISE_LDETAIL;Luminance - Detail +!TP_DIRPYRDENOISE_LM;Luminance only +!TP_DIRPYRDENOISE_LPLABM;Weighted L* (little) + a*b* (normal) +!TP_DIRPYRDENOISE_LTYPE;Luminance control +!TP_DIRPYRDENOISE_LUMAFR;Luminance +!TP_DIRPYRDENOISE_LUMAFR_TOOLTIP;Wavelet on luminance and Fourier transform for luminance detail +!TP_DIRPYRDENOISE_LUMA;Luminance +!TP_DIRPYRDENOISE_MANU;Manual +!TP_DIRPYRDENOISE_MAN;Manual +!TP_DIRPYRDENOISE_MEDMETHOD;Median method +!TP_DIRPYRDENOISE_MEDTYPE;Median type +!TP_DIRPYRDENOISE_MED;Median Filter +!TP_DIRPYRDENOISE_MED_TOOLTIP;Enabled median denoising +!TP_DIRPYRDENOISE_METHOD11;Quality +!TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. +!TP_DIRPYRDENOISE_METHOD;Method +!TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or L*a*b* methods can be used.\n\nFor non-raw images the L*a*b* method will be used, regardless of the selection. +!TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - +!TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 +!TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. +!TP_DIRPYRDENOISE_PASSES;Median iterations +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PON;Auto multi-zones +!TP_DIRPYRDENOISE_PREV;Preview +!TP_DIRPYRDENOISE_PRE;Preview multi-zones +!TP_DIRPYRDENOISE_RED;Chrominance - Red-Green +!TP_DIRPYRDENOISE_RGBM;RGB +!TP_DIRPYRDENOISE_RGB;RGB +!TP_DIRPYRDENOISE_SHALBI;High +!TP_DIRPYRDENOISE_SHAL;Standard +!TP_DIRPYRDENOISE_SLI;Slider +!TP_DIRPYRDENOISE_SOFT;3x3 +!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_LUMAFINEST;Finest +!TP_DIRPYREQUALIZER_LUMANEUTRAL;Neutral +!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_THRESHOLD;Threshold +!TP_DISTORTION_AMOUNT;Amount +!TP_DISTORTION_AUTO;Auto Distortion Correction +!TP_DISTORTION_AUTO_TIP;Correct lens distortion automatically for some cameras (Micro 4/3, some compact digital cameras, etc.). +!TP_DISTORTION_LABEL;Distortion Correction +!TP_EPD_EDGESTOPPING;Edge stopping +!TP_EPD_GAMMA;Gamma +!TP_EPD_LABEL;Tone Mapping +!TP_EPD_REWEIGHTINGITERATES;Reweighting iterates +!TP_EPD_SCALE;Scale +!TP_EPD_STRENGTH;Strength +!TP_EXPOSURE_AUTOLEVELS;Auto Levels +!TP_EXPOSURE_AUTOLEVELS_TIP;Toggles execution of Auto Levels to automatically set Exposure slider values based on an image analysis.\nEnables Highlight Reconstruction if necessary. +!TP_EXPOSURE_BLACKLEVEL;Black +!TP_EXPOSURE_BRIGHTNESS;Lightness +!TP_EXPOSURE_CLIP;Clip % +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in Auto Levels operation. +!TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Highlight compression threshold +!TP_EXPOSURE_COMPRHIGHLIGHTS;Highlight compression +!TP_EXPOSURE_COMPRSHADOWS;Shadow compression +!TP_EXPOSURE_CONTRAST;Contrast +!TP_EXPOSURE_CURVEEDITOR1;Tone curve 1 +!TP_EXPOSURE_CURVEEDITOR2;Tone curve 2 +!TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Please refer to the "Exposure > Tone Curves" RawPedia article to learn how to achieve the best results by using two tone curves. +!TP_EXPOSURE_EXPCOMP;Exposure compensation +!TP_EXPOSURE_LABEL;Exposure +!TP_EXPOSURE_SATURATION;Saturation +!TP_EXPOSURE_TCMODE_FILMLIKE;Film-like +!TP_EXPOSURE_TCMODE_LABEL1;Curve mode 1 +!TP_EXPOSURE_TCMODE_LABEL2;Curve mode 2 +!TP_EXPOSURE_TCMODE_LUMINANCE;Luminance +!TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Saturation and Value Blending +!TP_EXPOSURE_TCMODE_STANDARD;Standard +!TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard +!TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points +!TP_EXPOS_WHITEPOINT_LABEL;Raw White Points +!TP_FILMSIMULATION_LABEL;Film Simulation +!TP_FILMSIMULATION_STRENGTH;Strength +!TP_FILMSIMULATION_ZEROCLUTSFOUND;Set HaldCLUT directory in Preferences +!TP_FLATFIELD_AUTOSELECT;Auto-selection +!TP_FLATFIELD_BLURRADIUS;Blur radius +!TP_FLATFIELD_BLURTYPE;Blur type +!TP_FLATFIELD_BT_AREA;Area +!TP_FLATFIELD_BT_HORIZONTAL;Horizontal +!TP_FLATFIELD_BT_VERTHORIZ;Vertical + Horizontal +!TP_FLATFIELD_BT_VERTICAL;Vertical +!TP_FLATFIELD_CLIPCONTROL;Clip control +!TP_FLATFIELD_LABEL;Flat-Field +!TP_GAMMA_CURV;Gamma +!TP_GAMMA_FREE;Free gamma +!TP_GAMMA_OUTPUT;Output gamma +!TP_GAMMA_SLOP;Slope (linear) +!TP_GENERAL_11SCALE_TOOLTIP;The effects of this tool are only visible or only accurate at a preview scale of 1:1. +!TP_GRADIENT_CENTER_X_TOOLTIP;Shift gradient to the left (negative values) or right (positive values). +!TP_GRADIENT_CENTER_Y_TOOLTIP;Shift gradient up (negative values) or down (positive values). +!TP_GRADIENT_DEGREE;Angle +!TP_GRADIENT_DEGREE_TOOLTIP;Rotation angle in degrees. +!TP_GRADIENT_FEATHER;Feather +!TP_GRADIENT_FEATHER_TOOLTIP;Gradient width in percent of the image diagonal. +!TP_GRADIENT_LABEL;Graduated Filter +!TP_GRADIENT_STRENGTH;Strength +!TP_GRADIENT_STRENGTH_TOOLTIP;Filter strength in stops. +!TP_HLREC_BLEND;Blend +!TP_HLREC_CIELAB;CIELab Blending +!TP_HLREC_ENA_TOOLTIP;Could be activated by Auto Levels. +!TP_HLREC_LABEL;Highlight reconstruction +!TP_HLREC_LUMINANCE;Luminance Recovery +!TP_HLREC_METHOD;Method: +!TP_HSVEQUALIZER_CHANNEL;Channel +!TP_HSVEQUALIZER_HUE;H +!TP_HSVEQUALIZER_LABEL;HSV Equalizer +!TP_HSVEQUALIZER_SAT;S +!TP_HSVEQUALIZER_VAL;V +!TP_ICM_BLENDCMSMATRIX;Blend ICC highlights with matrix +!TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover clipped highlights when using LUT-based ICC profiles. +!TP_ICM_DCPILLUMINANT;Illuminant +!TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolated +!TP_ICM_DCPILLUMINANT_TOOLTIP;Select which embedded DCP illuminant to employ. Default is "interpolated" which is a mix between the two based on white balance. The setting is only enabled if a Dual-Illuminant DCP with interpolation support is selected. +!TP_ICM_INPUTCAMERAICC;Auto-matched camera profile +!TP_ICM_INPUTCAMERA;Camera standard +!TP_ICM_INPUTCUSTOM;Custom +!TP_ICM_INPUTDLGLABEL;Select Input DCP/ICC Profile... +!TP_ICM_INPUTEMBEDDED;Use embedded, if possible +!TP_ICM_INPUTNONE;No profile +!TP_ICM_INPUTPROFILE;Input Profile +!TP_ICM_NOICM;No ICM: sRGB Output +!TP_ICM_OUTPUTPROFILE;Output Profile +!TP_ICM_SAVEREFERENCE;Save Reference Image for Profiling +!TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance +!TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. The result can be used for calibration purposes and generation of a camera profile. +!TP_ICM_TONECURVE;Use DCP's tone curve +!TP_ICM_TONECURVE_TOOLTIP;Employ the embedded DCP tone curve. The setting is only enabled if the selected DCP has a tone curve. +!TP_ICM_WORKINGPROFILE;Working Profile +!TP_IMPULSEDENOISE_LABEL;Impulse Noise Reduction +!TP_IMPULSEDENOISE_THRESH;Threshold +!TP_LABCURVE_BRIGHTNESS;Lightness +!TP_LABCURVE_CHROMATICITY;Chromaticity +!TP_LABCURVE_CHROMA_TOOLTIP;To apply B&W toning, set Chromaticity to -100. +!TP_LABCURVE_CONTRAST;Contrast +!TP_LABCURVE_CURVEEDITOR;Luminance Curve +!TP_LABCURVE_CURVEEDITOR_A_RANGE1;Green Saturated +!TP_LABCURVE_CURVEEDITOR_A_RANGE2;Green Pastel +!TP_LABCURVE_CURVEEDITOR_A_RANGE3;Red Pastel +!TP_LABCURVE_CURVEEDITOR_A_RANGE4;Red Saturated +!TP_LABCURVE_CURVEEDITOR_B_RANGE1;Blue Saturated +!TP_LABCURVE_CURVEEDITOR_B_RANGE2;Blue Pastel +!TP_LABCURVE_CURVEEDITOR_B_RANGE3;Yellow Pastel +!TP_LABCURVE_CURVEEDITOR_B_RANGE4;Yellow Saturated +!TP_LABCURVE_CURVEEDITOR_CC;CC +!TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutral +!TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Dull +!TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastel +!TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Saturated +!TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Chromaticity according to chromaticity C=f(C) +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to hue C=f(H) +!TP_LABCURVE_CURVEEDITOR_CL;CL +!TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Chromaticity according to luminance C=f(L) +!TP_LABCURVE_CURVEEDITOR_HH;HH +!TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Hue according to hue H=f(H) +!TP_LABCURVE_CURVEEDITOR_LC;LC +!TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminance according to chromaticity L=f(C) +!TP_LABCURVE_CURVEEDITOR_LH;LH +!TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H) +!TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminance according to luminance L=f(L) +!TP_LABCURVE_LABEL;L*a*b* Adjustments +!TP_LABCURVE_LCREDSK;Restrict LC to red and skin-tones +!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_LENSGEOM_AUTOCROP;Auto-Crop +!TP_LENSGEOM_FILL;Auto-fill +!TP_LENSGEOM_LABEL;Lens / Geometry +!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_USECA;Chromatic aberration correction +!TP_LENSPROFILE_USEDIST;Distortion correction +!TP_LENSPROFILE_USEVIGN;Vignetting correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Resets exposure sliders to neutral values.\nApplies to the same controls that Auto Levels applies to, regardless of whether you used Auto Levels or not. +!TP_PCVIGNETTE_FEATHER;Feather +!TP_PCVIGNETTE_LABEL;Vignette Filter +!TP_PCVIGNETTE_ROUNDNESS;Roundness +!TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness:\n0 = rectangle,\n50 = fitted ellipse,\n100 = circle. +!TP_PCVIGNETTE_STRENGTH;Strength +!TP_PCVIGNETTE_STRENGTH_TOOLTIP;Filter strength in stops (reached in corners). +!TP_PERSPECTIVE_HORIZONTAL;Horizontal +!TP_PERSPECTIVE_LABEL;Perspective +!TP_PERSPECTIVE_VERTICAL;Vertical +!TP_PFCURVE_CURVEEDITOR_CH;Hue +!TP_PREPROCESS_DEADPIXFILT;Dead pixel filter +!TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Tries to suppress dead pixels. +!TP_PREPROCESS_GREENEQUIL;Green equilibration +!TP_PREPROCESS_HOTPIXFILT;Hot pixel filter +!TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Tries to suppress hot pixels. +!TP_PREPROCESS_LABEL;Preprocessing +!TP_PREPROCESS_LINEDENOISE;Line noise filter +!TP_PREPROCESS_NO_FOUND;None found +!TP_RAWCACORR_AUTO;Auto-correction +!TP_RAWCACORR_CABLUE;Blue +!TP_RAWCACORR_CARED;Red +!TP_RAWEXPOS_BLACKS;Black Levels +!TP_RAWEXPOS_BLACK_0;Green 1 (lead) +!TP_RAWEXPOS_BLACK_1;Red +!TP_RAWEXPOS_BLACK_2;Blue +!TP_RAWEXPOS_BLACK_3;Green 2 +!TP_RAWEXPOS_BLACK_BLUE;Blue +!TP_RAWEXPOS_BLACK_GREEN;Green +!TP_RAWEXPOS_BLACK_RED;Red +!TP_RAWEXPOS_LINEAR;White-point correction +!TP_RAWEXPOS_PRESER;Highlight preservation +!TP_RAWEXPOS_RGB;Red, Green, Blue +!TP_RAWEXPOS_TWOGREEN;Link greens +!TP_RAW_DCBENHANCE;DCB enhancement +!TP_RAW_DCBITERATIONS;Number of DCB iterations +!TP_RAW_DMETHOD;Method +!TP_RAW_DMETHOD_PROGRESSBAR;%1 demosaicing... +!TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Demosaicing refinement... +!TP_RAW_DMETHOD_TOOLTIP;Note: IGV and LMMSE are dedicated to high ISO images to aid in noise reduction without leading to maze patterns, posterization or a washed-out look. +!TP_RAW_HD;Threshold +!TP_RAW_HD_TOOLTIP;Lower values make hot/dead pixel detection more aggressive, but false positives may lead to artifacts. If you notice any artifacts appearing when enabling the Hot/Dead Pixel Filters, gradually increase the threshold value until they disappear. +!TP_RAW_LABEL;Demosaicing +!TP_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!TP_RAW_LMMSE_TOOLTIP;Adds gamma (step 1), median (steps 2-4) and refinement (steps 5-6) to reduce artifacts and improve the signal-to-noise ratio. +!TP_RAW_SENSOR_BAYER_LABEL;Sensor with Bayer Matrix +!TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;3-pass gives best results (recommended for low ISO images).\n1-pass is almost undistinguishable from 3-pass for high ISO images and is faster. +!TP_RAW_SENSOR_XTRANS_LABEL;Sensor with X-Trans Matrix +!TP_RESIZE_APPLIESTO;Applies to: +!TP_RESIZE_CROPPEDAREA;Cropped Area +!TP_RESIZE_FITBOX;Bounding Box +!TP_RESIZE_FULLIMAGE;Full Image +!TP_RESIZE_HEIGHT;Height +!TP_RESIZE_H;Height: +!TP_RESIZE_LABEL;Resize +!TP_RESIZE_LANCZOS;Lanczos +!TP_RESIZE_METHOD;Method: +!TP_RESIZE_NEAREST;Nearest +!TP_RESIZE_SCALE;Scale +!TP_RESIZE_SPECIFY;Specify: +!TP_RESIZE_WIDTH;Width +!TP_RESIZE_W;Width: +!TP_RGBCURVES_BLUE;B +!TP_RGBCURVES_CHANNEL;Channel +!TP_RGBCURVES_GREEN;G +!TP_RGBCURVES_LABEL;RGB Curves +!TP_RGBCURVES_LUMAMODE;Luminosity mode +!TP_RGBCURVES_RED;R +!TP_ROTATE_DEGREE;Degree +!TP_ROTATE_LABEL;Rotate +!TP_ROTATE_SELECTLINE;Select Straight Line +!TP_SAVEDIALOG_OK_TIP;Shortcut: Ctrl-Enter +!TP_SHADOWSHLIGHTS_HIGHLIGHTS;Highlights +!TP_SHADOWSHLIGHTS_HLTONALW;Highlights tonal width +!TP_SHADOWSHLIGHTS_LABEL;Shadows/highlights +!TP_SHADOWSHLIGHTS_LOCALCONTR;Local contrast +!TP_SHADOWSHLIGHTS_RADIUS;Radius +!TP_SHADOWSHLIGHTS_SHADOWS;Shadows +!TP_SHADOWSHLIGHTS_SHARPMASK;Sharp mask +!TP_SHADOWSHLIGHTS_SHTONALW;Shadows tonal width +!TP_SHARPENEDGE_AMOUNT;Quantity +!TP_SHARPENEDGE_LABEL;Edges +!TP_SHARPENEDGE_PASSES;Iterations +!TP_SHARPENEDGE_THREE;Luminance only +!TP_SHARPENING_AMOUNT;Amount +!TP_SHARPENING_EDRADIUS;Radius +!TP_SHARPENING_EDTOLERANCE;Edge tolerance +!TP_SHARPENING_HALOCONTROL;Halo control +!TP_SHARPENING_HCAMOUNT;Amount +!TP_SHARPENING_LABEL;Sharpening +!TP_SHARPENING_METHOD;Method +!TP_SHARPENING_ONLYEDGES;Sharpen only edges +!TP_SHARPENING_RADIUS;Radius +!TP_SHARPENING_RLD;RL Deconvolution +!TP_SHARPENING_RLD_AMOUNT;Amount +!TP_SHARPENING_RLD_DAMPING;Damping +!TP_SHARPENING_RLD_ITERATIONS;Iterations +!TP_SHARPENING_THRESHOLD;Threshold +!TP_SHARPENING_TOOLTIP;Expect a slightly different effect when using with CIECAM02. If difference is observed, adjust to taste. +!TP_SHARPENING_USM;Unsharp Mask +!TP_SHARPENMICRO_AMOUNT;Quantity +!TP_SHARPENMICRO_LABEL;Microcontrast +!TP_SHARPENMICRO_MATRIX;3×3 matrix instead of 5×5 +!TP_SHARPENMICRO_UNIFORMITY;Uniformity +!TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Red/Purple +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Red +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Red/Yellow +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Yellow +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Hue according to hue H=f(H) +!TP_VIBRANCE_LABEL;Vibrance +!TP_VIBRANCE_PASTELS;Pastel Tones +!TP_VIBRANCE_PASTSATTOG;Link pastel and saturated tones +!TP_VIBRANCE_PROTECTSKINS;Protect skin-tones +!TP_VIBRANCE_PSTHRESHOLD;Pastel/saturated tones threshold +!TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Saturation threshold +!TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;The vertical axis represents pastel tones at the bottom and saturated tones at the top.\nThe horizontal axis represents the saturation range. +!TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Pastel/saturated transition's weighting +!TP_VIBRANCE_SATURATED;Saturated Tones +!TP_VIGNETTING_AMOUNT;Amount +!TP_VIGNETTING_LABEL;Vignetting Correction +!TP_VIGNETTING_RADIUS;Radius +!TP_VIGNETTING_STRENGTH;Strength +!TP_WAVELET_1;Level 1 +!TP_WAVELET_2;Level 2 +!TP_WAVELET_3;Level 3 +!TP_WAVELET_4;Level 4 +!TP_WAVELET_5;Level 5 +!TP_WAVELET_6;Level 6 +!TP_WAVELET_7;Level 7 +!TP_WAVELET_8;Level 8 +!TP_WAVELET_9;Level 9 +!TP_WAVELET_ALL;All levels in all directions +!TP_WAVELET_APPLYTO;Apply To +!TP_WAVELET_B0;Black +!TP_WAVELET_B1;Grey +!TP_WAVELET_B2;Residual +!TP_WAVELET_BACUR;Curve +!TP_WAVELET_BALANCE;Contrast balance d/v-h +!TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chromaticity or residual tone mapping are activated, the effect due to balance is amplified. +!TP_WAVELET_BALCHRO;Chroma balance +!TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chromaticity balance. +!TP_WAVELET_BANONE;None +!TP_WAVELET_BASLI;Slider +!TP_WAVELET_BATYPE;Contrast balance method +!TP_WAVELET_CCURVE;Local contrast +!TP_WAVELET_CH1;Whole chromaticity range +!TP_WAVELET_CH2;Saturated/pastel +!TP_WAVELET_CH3;Link contrast levels +!TP_WAVELET_CHCU;Curve +!TP_WAVELET_CHRO;Saturated/pastel threshold +!TP_WAVELET_CHR;Chroma-contrast link strength +!TP_WAVELET_CHR_TOOLTIP;Adjusts chromaticity as a function of "contrast levels" and "chroma-contrast link strength" +!TP_WAVELET_CHSL;Sliders +!TP_WAVELET_CHTYPE;Chrominance method +!TP_WAVELET_COLORT;Opacity Red-Green +!TP_WAVELET_COMBOTH;Both +!TP_WAVELET_COMPCONT;Contrast +!TP_WAVELET_COMPGAMMA;Compression gamma +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjusting the gamma of the residual image allow you to equilibrate the data and histogram. +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjust gamma for residual image and compression.\nAllow to equilibrate data and histogram +!TP_WAVELET_COMPTM;Tone mapping +!TP_WAVELET_CONTEDIT;'After' Contrast curve +!TP_WAVELET_CONTEDIT;'After' contrast curve +!TP_WAVELET_CONTRAST_MINUS;Contrast - +!TP_WAVELET_CONTRAST_PLUS;Contrast + +!TP_WAVELET_CONTRA;Contrast +!TP_WAVELET_CONTRA_TOOLTIP;Changes contrast of the residual image. +!TP_WAVELET_CONTR;Gamut +!TP_WAVELET_CTYPE;Chrominance control +!TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modifies local contrast as a function of the original local contrast (absciss)\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 100..300)\n66% absciss represents standard deviation of local contrast (real value about 300..800)\n100% represents maximum (real value about 3000..8000) +!TP_WAVELET_CURVEEDITOR_CH;Contrast levels=f(Hue) +!TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modifies each level's contrast as a function oh hue.\nTake care not to overwrite changes made with the Gamut Hue controls.\nThe curve will only have an effect when wavelet contrast level sliders are non-zero. +!TP_WAVELET_CURVEEDITOR_CL;L +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Applies a final contrast luminance curve at the end of the wavelet treatment. +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Apply a contrast luminance curve at the end of wavelet level threatment +!TP_WAVELET_CURVEEDITOR_HH;HH +!TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modifies the residual image's hue as a function of hue. +!TP_WAVELET_DALL;All directions +!TP_WAVELET_DAUB;Edge performance +!TP_WAVELET_DAUB_TOOLTIP;Changes Daubechies coefficients:\nD4 = Standard,\nD14 = Often best performance, 10% more time-intensive.\n\nAffects edge detection as well as the general quality of the firsts levels. However the quality is not strictly related to this coefficient and can vary with images and uses. +!TP_WAVELET_DISP;Preview Settings +!TP_WAVELET_DONE;Vertical +!TP_WAVELET_DTHR;Diagonal +!TP_WAVELET_DTWO;Horizontal +!TP_WAVELET_EDCU;Curve +!TP_WAVELET_EDGCONT;Local contrast +!TP_WAVELET_EDGCONT_TOOLTIP;Adjusting the points to the left decreases contrast, and to the right increases it.\nBottom-left, Top-Left, Top-Right, Bottom-right represent respectively local contast for low values, mean, mean+stdev, maxima +!TP_WAVELET_EDGEDETECTTHR2;Threshold high (detection) +!TP_WAVELET_EDGEDETECTTHR;Threshold low (noise) +!TP_WAVELET_EDGEDETECTTHR_TOOLTIP;This adjuster lets you target edge detection for example to avoid applying edge sharpness to fine details, such as noise in the sky. +!TP_WAVELET_EDGEDETECT;Gradient sensitivity +!TP_WAVELET_EDGEDETECT_TOOLTIP;Moving the slider to the right increases edge sensitivity. This affects local contrast, edge settings and noise. +!TP_WAVELET_EDGE;Edge Sharpness +!TP_WAVELET_EDGREINF_TOOLTIP;Reinforce or reduce the action of the first level, do the opposite to the second level, and leave the rest unchanged. +!TP_WAVELET_EDGTHRESH;Detail +!TP_WAVELET_EDGTHRESH_TOOLTIP;Change the repartition between the first levels and the others. The higher the threshold the more the action is centred on the first levels. Be careful with negative values, they increase the action of high levels and can introduce artifacts. +!TP_WAVELET_EDRAD;Radius +!TP_WAVELET_EDRAD_TOOLTIP;This radius adjustment is very different from those in other sharpening tools. Its value is compared to each level through a complex function. In this sense, a value of zero still has an effect. +!TP_WAVELET_EDSL;Threshold Sliders +!TP_WAVELET_EDTYPE;Local contrast method +!TP_WAVELET_EDVAL;Strength +!TP_WAVELET_FINAL;Final Touchup +!TP_WAVELET_FINEST;Finest +!TP_WAVELET_HIGHLIGHT;Highlight luminance range +!TP_WAVELET_HS1;Whole luminance range +!TP_WAVELET_HS2;Shadows/Highlights +!TP_WAVELET_HUESKIN;Skin hue +!TP_WAVELET_HUESKIN_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_HUESKY;Sky hue +!TP_WAVELET_HUESKY_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_INF;Below or equal the level +!TP_WAVELET_ITER;Delta balance levels +!TP_WAVELET_ITER_TOOLTIP;Left: increase low levels and reduce high levels,\nRight: reduce low levels and increase high levels. +!TP_WAVELET_LABEL;Wavelet levels +!TP_WAVELET_LARGEST;Coarsest +!TP_WAVELET_LEVCH;Chromaticity +!TP_WAVELET_LEVELS;Wavelet levels +!TP_WAVELET_LEVELS_TOOLTIP;Choose the number of detail levels the image is to be decomposed into. More levels require more RAM and require a longer processing time. +!TP_WAVELET_LEVF;Contrast +!TP_WAVELET_LEVLABEL;Preview maximum possible levels = %1 +!TP_WAVELET_LEVONE;Level 2 +!TP_WAVELET_LEVTWO;Level 3 +!TP_WAVELET_LEVZERO;Level 1 +!TP_WAVELET_LINKEDG;Link with Edge Sharpness' Strength +!TP_WAVELET_LIPST;Enhanced algorithm +!TP_WAVELET_LIPST_TOOLTIP;This algorithm uses Lipschitz regularity to increase edge detection quality at a cost of increased processing time and memory requirements. +!TP_WAVELET_LOWLIGHT;Shadow luminance range +!TP_WAVELET_MEDGREINF;First level +!TP_WAVELET_MEDILEV;Edge detection +!TP_WAVELET_MEDI;Reduce artifacts in blue sky +!TP_WAVELET_NEUTRAL;Neutral +!TP_WAVELET_NOISE;Denoise and Refine +!TP_WAVELET_NOIS;Denoise +!TP_WAVELET_ONE;One level +!TP_WAVELET_OPACITYWL;Final local contrast +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify final local contrast in function of last local contrast (absciss) for all levels decomposition\nTake into account: \na)contrast levels \nb)edge sharpness \nc)contrast balance\nd)decomposition-recomposition\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 200..1000)\n66% absciss represents standard deviation of local contrast (real value about 1000..2000)\n100% represents maximum (real value about 5000..13000) +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify the final local contrast at the end of the wavelet treatment.\n\nThe left side represents the smallest local contrast, progressing to the largest local contrast on the right. +!TP_WAVELET_OPACITYW;Contrast balance d/v-h curve +!TP_WAVELET_OPACITY;Opacity Blue-Yellow +!TP_WAVELET_PASTEL;Pastel chromaticity +!TP_WAVELET_PREVIEWBACK;Background +!TP_WAVELET_PREVIEWLEVELS;Preview +!TP_WAVELET_RE1;Reinforced +!TP_WAVELET_RE2;Unchanged +!TP_WAVELET_RE3;Reduced +!TP_WAVELET_RESCHRO;Chromaticity +!TP_WAVELET_RESCONH;Highlights +!TP_WAVELET_RESCON;Shadows +!TP_WAVELET_RESID;Residual image +!TP_WAVELET_SAT;Saturated chromaticity +!TP_WAVELET_SETTINGS;Wavelet Settings +!TP_WAVELET_SKIN;Skin targetting/protection +!TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected. +!TP_WAVELET_SKY;Sky targetting/protection +!TP_WAVELET_SKY_TOOLTIP;At -100 sky-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 sky-tones are protected while all other tones are affected. +!TP_WAVELET_STRENGTH;Strength +!TP_WAVELET_STREN;Strength +!TP_WAVELET_SUPE;Extra +!TP_WAVELET_SUP;Above the level +!TP_WAVELET_THRESHOLD2;Shadow levels +!TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels between 9 and 9 minus the value will be affected by the shadow luminance range. Other levels will be fully treated. The highest level possible is limited by the highlight level value (9 minus highlight level value). +!TP_WAVELET_THRESHOLD;Highlight levels +!TP_WAVELET_THRESHOLD_TOOLTIP;Only levels beyond the chosen value will be affected by the highlight luminance range. Other levels will be fully treated. The chosen value here limits the highest possible value of the shadow levels. +!TP_WAVELET_THRH;Highlights threshold +!TP_WAVELET_THR;Shadows threshold +!TP_WAVELET_TILESBIG;Big tiles +!TP_WAVELET_TILESFULL;Full image +!TP_WAVELET_TILESIZE;Tiling method +!TP_WAVELET_TILESLIT;Little tiles +!TP_WAVELET_TILES_TOOLTIP;Processing the full image leads to better quality and is the recommended option, while using tiles is a fall-back solution for users with little RAM. Refer to RawPedia for memory requirements. +!TP_WAVELET_TMHIGH;High +!TP_WAVELET_TMLOWHIGH;Low+High +!TP_WAVELET_TMNONE;None +!TP_WAVELET_TMSTD;Standard +!TP_WAVELET_TMSTRENGTH;Compression strength +!TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image. When the value is different from 0, the Strength and Gamma sliders of the Tone Mapping tool in the Exposure tab will become grayed out. +!TP_WAVELET_TMTYPE;Compression method +!TP_WAVELET_TON;Toning +!TP_WAVELET_daub2;D2 - low +!TP_WAVELET_daub4;D4 - standard +!TP_WAVELET_daub6;D6 - standard plus +!TP_WAVELET_daub10;D10 - medium +!TP_WAVELET_daub14;D14 - high +!TP_WBALANCE_AUTO;Auto +!TP_WBALANCE_CAMERA;Camera +!TP_WBALANCE_CLOUDY;Cloudy +!TP_WBALANCE_CUSTOM;Custom +!TP_WBALANCE_DAYLIGHT;Daylight (sunny) +!TP_WBALANCE_EQBLUERED;Blue/Red equalizer +!TP_WBALANCE_FLASH55;Leica +!TP_WBALANCE_FLASH60;Standard, Canon, Pentax, Olympus +!TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta +!TP_WBALANCE_FLASH_HEADER;Flash +!TP_WBALANCE_FLUO1;F1 - Daylight +!TP_WBALANCE_FLUO2;F2 - Cool White +!TP_WBALANCE_FLUO3;F3 - White +!TP_WBALANCE_FLUO4;F4 - Warm White +!TP_WBALANCE_FLUO5;F5 - Daylight +!TP_WBALANCE_FLUO6;F6 - Lite White +!TP_WBALANCE_FLUO7;F7 - D65 Daylight Simulator +!TP_WBALANCE_FLUO8;F8 - D50 / Sylvania F40 Design +!TP_WBALANCE_FLUO9;F9 - Cool White Deluxe +!TP_WBALANCE_FLUO10;F10 - Philips TL85 +!TP_WBALANCE_FLUO11;F11 - Philips TL84 +!TP_WBALANCE_FLUO12;F12 - Philips TL83 +!TP_WBALANCE_FLUO_HEADER;Fluorescent +!TP_WBALANCE_GREEN;Tint +!TP_WBALANCE_GTI;GTI +!TP_WBALANCE_HMI;HMI +!TP_WBALANCE_JUDGEIII;JudgeIII +!TP_WBALANCE_LABEL;White Balance +!TP_WBALANCE_LAMP_HEADER;Lamp +!TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 +!TP_WBALANCE_LED_HEADER;LED +!TP_WBALANCE_LED_LSI;LSI Lumelex 2040 +!TP_WBALANCE_METHOD;Method +!TP_WBALANCE_SHADE;Shade +!TP_WBALANCE_SIZE;Size: +!TP_WBALANCE_SOLUX35;Solux 3500K +!TP_WBALANCE_SOLUX41;Solux 4100K +!TP_WBALANCE_SOLUX47;Solux 4700K (vendor) +!TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) +!TP_WBALANCE_SPOTWB;Spot WB +!TP_WBALANCE_TEMPERATURE;Temperature +!TP_WBALANCE_TUNGSTEN;Tungsten +!TP_WBALANCE_WATER1;UnderWater 1 +!TP_WBALANCE_WATER2;UnderWater 2 +!TP_WBALANCE_WATER_HEADER;UnderWater +!ZOOMPANEL_100;(100%) +!ZOOMPANEL_NEWCROPWINDOW;Open (new) detail window +!ZOOMPANEL_ZOOM100;Zoom to 100%\nShortcut: z +!ZOOMPANEL_ZOOMFITCROPSCREEN;Fit crop to screen\nShortcut: Alt-f +!ZOOMPANEL_ZOOMFITSCREEN;Fit whole image to screen\nShortcut: f +!ZOOMPANEL_ZOOMIN;Zoom In\nShortcut: + +!ZOOMPANEL_ZOOMOUT;Zoom Out\nShortcut: - diff --git a/rtdata/languages/English (US) b/rtdata/languages/English (US) new file mode 100644 index 000000000..df20859b4 --- /dev/null +++ b/rtdata/languages/English (US) @@ -0,0 +1,1850 @@ +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!ABOUT_TAB_BUILD;Version +!ABOUT_TAB_CREDITS;Credits +!ABOUT_TAB_LICENSE;License +!ABOUT_TAB_RELEASENOTES;Release Notes +!ABOUT_TAB_SPLASH;Splash +!ADJUSTER_RESET_TO_DEFAULT;Reset to default +!BATCHQUEUE_AUTOSTART;Auto-start +!BATCHQUEUE_DESTFILENAME;Path and file name +!BATCH_PROCESSING;Batch Processing +!CURVEEDITOR_AXIS_IN;I: +!CURVEEDITOR_AXIS_LEFT_TAN;LT: +!CURVEEDITOR_AXIS_OUT;O: +!CURVEEDITOR_AXIS_RIGHT_TAN;RT: +!CURVEEDITOR_CURVES;Curves +!CURVEEDITOR_CURVE;Curve +!CURVEEDITOR_CUSTOM;Custom +!CURVEEDITOR_DARKS;Darks +!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_HIGHLIGHTS;Highlights +!CURVEEDITOR_LIGHTS;Lights +!CURVEEDITOR_LINEAR;Linear +!CURVEEDITOR_LOADDLGLABEL;Load curve... +!CURVEEDITOR_MINMAXCPOINTS;Equalizer +!CURVEEDITOR_NURBS;Control cage +!CURVEEDITOR_PARAMETRIC;Parametric +!CURVEEDITOR_SAVEDLGLABEL;Save curve... +!CURVEEDITOR_SHADOWS;Shadows +!CURVEEDITOR_TOOLTIPCOPY;Copy current curve to clipboard. +!CURVEEDITOR_TOOLTIPLINEAR;Reset curve to linear. +!CURVEEDITOR_TOOLTIPLOAD;Load a curve from file. +!CURVEEDITOR_TOOLTIPPASTE;Paste curve from clipboard. +!CURVEEDITOR_TOOLTIPSAVE;Save current curve. +!CURVEEDITOR_TYPE;Type: +!DIRBROWSER_FOLDERS;Folders +!EDITWINDOW_TITLE;Image Edit +!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_APERTURE;Aperture +!EXIFFILTER_CAMERA;Camera +!EXIFFILTER_EXPOSURECOMPENSATION;Exposure compensation (EV) +!EXIFFILTER_FILETYPE;File type +!EXIFFILTER_FOCALLEN;Focal length +!EXIFFILTER_ISO;ISO +!EXIFFILTER_LENS;Lens +!EXIFFILTER_METADATAFILTER;Enable metadata filters +!EXIFFILTER_SHUTTER;Shutter +!EXIFPANEL_ADDEDITHINT;Add new tag or edit tag. +!EXIFPANEL_ADDEDIT;Add/Edit +!EXIFPANEL_ADDTAGDLG_ENTERVALUE;Enter value +!EXIFPANEL_ADDTAGDLG_SELECTTAG;Select tag +!EXIFPANEL_ADDTAGDLG_TITLE;Add/Edit Tag +!EXIFPANEL_KEEPHINT;Keep the selected tags when writing output file. +!EXIFPANEL_KEEP;Keep +!EXIFPANEL_REMOVEHINT;Remove the selected tags when writing output file. +!EXIFPANEL_REMOVE;Remove +!EXIFPANEL_RESETALLHINT;Reset all tags to their original values. +!EXIFPANEL_RESETALL;Reset All +!EXIFPANEL_RESETHINT;Reset the selected tags to their original values. +!EXIFPANEL_RESET;Reset +!EXIFPANEL_SUBDIRECTORY;Subdirectory +!EXPORT_BYPASS_ALL;Select / Unselect All +!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_FF;Bypass [raw] Flat-Field +!EXPORT_BYPASS_RAW_GREENTHRESH;Bypass [raw] Green Equilibration +!EXPORT_BYPASS_RAW_LINENOISE;Bypass [raw] Line Noise Filter +!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_FASTEXPORTOPTIONS;Fast Export Options +!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_MAXHEIGHT;Maximum height: +!EXPORT_MAXWIDTH;Maximum width: +!EXPORT_PUTTOQUEUEFAST; Put to queue for fast export +!EXPORT_RAW_DMETHOD;Demosaic method +!EXTPROGTARGET_1;raw +!EXTPROGTARGET_2;queue-processed +!FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +!FILEBROWSER_APPLYPROFILE;Apply +!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_CACHECLEARFROMFULL;Clear from cache - full +!FILEBROWSER_CACHECLEARFROMPARTIAL;Clear from cache - partial +!FILEBROWSER_CACHE;Cache +!FILEBROWSER_CLEARPROFILE;Clear +!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_COPYPROFILE;Copy +!FILEBROWSER_CURRENT_NAME;Current name: +!FILEBROWSER_DARKFRAME;Dark-frame +!FILEBROWSER_DELETEDLGLABEL;File delete confirmation +!FILEBROWSER_DELETEDLGMSGINCLPROC;Are you sure you want to delete the selected %1 files including a queue-processed version? +!FILEBROWSER_DELETEDLGMSG;Are you sure you want to delete the selected %1 files? +!FILEBROWSER_EMPTYTRASHHINT;Permanently delete the files from trash. +!FILEBROWSER_EMPTYTRASH;Empty trash +!FILEBROWSER_EXEC_CPB;Custom Profile Builder +!FILEBROWSER_EXTPROGMENU;Open with +!FILEBROWSER_FLATFIELD;Flat-Field +!FILEBROWSER_MOVETODARKFDIR;Move to dark-frames directory +!FILEBROWSER_MOVETOFLATFIELDDIR;Move to flat-fields directory +!FILEBROWSER_NEW_NAME;New name: +!FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) +!FILEBROWSER_PARTIALPASTEPROFILE;Paste - partial +!FILEBROWSER_PASTEPROFILE;Paste +!FILEBROWSER_POPUPCANCELJOB;Cancel job +!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_POPUPCOLORLABEL;Color label +!FILEBROWSER_POPUPCOPYTO;Copy to... +!FILEBROWSER_POPUPFILEOPERATIONS;File operations +!FILEBROWSER_POPUPMOVEEND;Move to end of queue +!FILEBROWSER_POPUPMOVEHEAD;Move to head of queue +!FILEBROWSER_POPUPMOVETO;Move to... +!FILEBROWSER_POPUPOPENINEDITOR;Open in Editor +!FILEBROWSER_POPUPOPEN;Open +!FILEBROWSER_POPUPPROCESSFAST;Put to queue (Fast export) +!FILEBROWSER_POPUPPROCESS;Put to queue +!FILEBROWSER_POPUPPROFILEOPERATIONS;Processing profile operations +!FILEBROWSER_POPUPRANK0;Unrank +!FILEBROWSER_POPUPRANK1;Rank 1 * +!FILEBROWSER_POPUPRANK2;Rank 2 ** +!FILEBROWSER_POPUPRANK3;Rank 3 *** +!FILEBROWSER_POPUPRANK4;Rank 4 **** +!FILEBROWSER_POPUPRANK5;Rank 5 ***** +!FILEBROWSER_POPUPRANK;Rank +!FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +!FILEBROWSER_POPUPREMOVE;Delete +!FILEBROWSER_POPUPRENAME;Rename +!FILEBROWSER_POPUPSELECTALL;Select all +!FILEBROWSER_POPUPTRASH;Move to trash +!FILEBROWSER_POPUPUNRANK;Unrank +!FILEBROWSER_POPUPUNTRASH;Remove from trash +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!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_QUERYLABEL; Find: +!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_RENAMEDLGLABEL;Rename file +!FILEBROWSER_RENAMEDLGMSG;Rename file "%1" to: +!FILEBROWSER_SELECTDARKFRAME;Select dark-frame... +!FILEBROWSER_SELECTFLATFIELD;Select flat-field... +!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 +!FILEBROWSER_SHOWCOLORLABEL4HINT;Show images labeled Blue.\nShortcut: Alt-4 +!FILEBROWSER_SHOWCOLORLABEL5HINT;Show images labeled Purple.\nShortcut: Alt-5 +!FILEBROWSER_SHOWDIRHINT;Clear all filters.\nShortcut: d +!FILEBROWSER_SHOWEDITEDHINT;Show edited images.\nShortcut: 7 +!FILEBROWSER_SHOWEDITEDNOTHINT;Show not edited images.\nShortcut: 6 +!FILEBROWSER_SHOWEXIFINFO;Show Exif info.\n\nShortcuts:\ni - Multiple Editor Tabs Mode,\nAlt-i - Single Editor Tab Mode. +!FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!FILEBROWSER_SHOWRANK1HINT;Show images ranked as 1-star.\nShortcut: 1 +!FILEBROWSER_SHOWRANK2HINT;Show images ranked as 2-star.\nShortcut: 2 +!FILEBROWSER_SHOWRANK3HINT;Show images ranked as 3-star.\nShortcut: 3 +!FILEBROWSER_SHOWRANK4HINT;Show images ranked as 4-star.\nShortcut: 4 +!FILEBROWSER_SHOWRANK5HINT;Show images ranked as 5-star.\nShortcut: 5 +!FILEBROWSER_SHOWRECENTLYSAVEDHINT;Show saved images.\nShortcut: Alt-7 +!FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show unsaved images.\nShortcut: Alt-6 +!FILEBROWSER_SHOWTRASHHINT;Show contents of trash.\nShortcut: Ctrl-t +!FILEBROWSER_SHOWUNCOLORHINT;Show images without a color label.\nShortcut: Alt-0 +!FILEBROWSER_SHOWUNRANKHINT;Show unranked images.\nShortcut: 0 +!FILEBROWSER_STARTPROCESSINGHINT;Start processing the images in the queue. +!FILEBROWSER_STARTPROCESSING;Start processing +!FILEBROWSER_STOPPROCESSINGHINT;Stop processing the images in the queue. +!FILEBROWSER_STOPPROCESSING;Stop processing +!FILEBROWSER_THUMBSIZE;Thumbnail size +!FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives. +!FILEBROWSER_UNRANK_TOOLTIP;Unrank.\nShortcut: Shift-0 +!FILEBROWSER_ZOOMINHINT;Increase thumbnail size.\n\nShortcuts:\n+ - Multiple Editor Tabs Mode,\nAlt-+ - Single Editor Tab Mode. +!FILEBROWSER_ZOOMOUTHINT;Decrease thumbnail size.\n\nShortcuts:\n- - Multiple Editor Tabs Mode,\nAlt-- - Single Editor Tab Mode. +!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_ABOUT;About +!GENERAL_AFTER;After +!GENERAL_ASIMAGE;As Image +!GENERAL_AUTO;Automatic +!GENERAL_BEFORE;Before +!GENERAL_CANCEL;Cancel +!GENERAL_CLOSE;Close +!GENERAL_DISABLED;Disabled +!GENERAL_DISABLE;Disable +!GENERAL_ENABLED;Enabled +!GENERAL_ENABLE;Enable +!GENERAL_FILE;File +!GENERAL_LANDSCAPE;Landscape +!GENERAL_NA;n/a +!GENERAL_NONE;None +!GENERAL_NO;No +!GENERAL_OK;OK +!GENERAL_PORTRAIT;Portrait +!GENERAL_SAVE;Save +!GENERAL_UNCHANGED;(Unchanged) +!GENERAL_WARNING;Warning +!HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar.\nRight-click on image preview to freeze/unfreeze. +!HISTOGRAM_TOOLTIP_B;Show/Hide blue histogram. +!HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram. +!HISTOGRAM_TOOLTIP_FULL;Toggle full (off) or scaled (on) histogram. +!HISTOGRAM_TOOLTIP_G;Show/Hide green histogram. +!HISTOGRAM_TOOLTIP_L;Show/Hide CIELab luminance histogram. +!HISTOGRAM_TOOLTIP_RAW;Show/Hide raw histogram. +!HISTOGRAM_TOOLTIP_R;Show/Hide red histogram. +!HISTORY_CHANGED;Changed +!HISTORY_CUSTOMCURVE;Custom curve +!HISTORY_DELSNAPSHOT;Del +!HISTORY_FROMCLIPBOARD;From clipboard +!HISTORY_LABEL;History +!HISTORY_MSG_1;Photo loaded +!HISTORY_MSG_2;PP3 loaded +!HISTORY_MSG_3;PP3 changed +!HISTORY_MSG_4;History browsing +!HISTORY_MSG_5;Lightness +!HISTORY_MSG_6;Contrast +!HISTORY_MSG_7;Black +!HISTORY_MSG_8;Exposure compensation +!HISTORY_MSG_9;Highlight compression +!HISTORY_MSG_10;Shadow compression +!HISTORY_MSG_11;Tone curve 1 +!HISTORY_MSG_12;Auto levels +!HISTORY_MSG_13;Exposure clipping +!HISTORY_MSG_14;L*a*b* - Lightness +!HISTORY_MSG_15;L*a*b* - Contrast +!HISTORY_MSG_16;- +!HISTORY_MSG_17;- +!HISTORY_MSG_18;- +!HISTORY_MSG_19;L*a*b* - L* curve +!HISTORY_MSG_20;Sharpening +!HISTORY_MSG_21;USM - Radius +!HISTORY_MSG_22;USM - Amount +!HISTORY_MSG_23;USM - Threshold +!HISTORY_MSG_24;USM - Sharpen only edges +!HISTORY_MSG_25;USM - Edge detection radius +!HISTORY_MSG_26;USM - Edge tolerance +!HISTORY_MSG_27;USM - Halo control +!HISTORY_MSG_28;USM - Halo control amount +!HISTORY_MSG_29;Sharpening method +!HISTORY_MSG_30;RLD - Radius +!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_37;Auto levels +!HISTORY_MSG_38;White balance method +!HISTORY_MSG_39;WB - Temperature +!HISTORY_MSG_40;WB - Tint +!HISTORY_MSG_41;Tone curve 1 mode +!HISTORY_MSG_42;Tone curve 2 +!HISTORY_MSG_43;Tone curve 2 mode +!HISTORY_MSG_44;Lum. denoising radius +!HISTORY_MSG_45;Lum. denoising edge tolerance +!HISTORY_MSG_46;Color denoising +!HISTORY_MSG_47;Blend ICC highlights with matrix +!HISTORY_MSG_48;Use DCP's tone curve +!HISTORY_MSG_49;DCP illuminant +!HISTORY_MSG_50;Shadows/Highlights +!HISTORY_MSG_51;S/H - Highlights +!HISTORY_MSG_52;S/H - Shadows +!HISTORY_MSG_53;S/H - Highlight tonal width +!HISTORY_MSG_54;S/H - Shadow tonal width +!HISTORY_MSG_55;S/H - Local contrast +!HISTORY_MSG_56;S/H - Radius +!HISTORY_MSG_57;Coarse rotation +!HISTORY_MSG_58;Horizontal flipping +!HISTORY_MSG_59;Vertical flipping +!HISTORY_MSG_60;Rotation +!HISTORY_MSG_61;Auto-fill +!HISTORY_MSG_62;Distortion correction +!HISTORY_MSG_63;Snapshot selected +!HISTORY_MSG_64;Crop +!HISTORY_MSG_65;CA correction +!HISTORY_MSG_66;Highlight reconstruction +!HISTORY_MSG_67;HR reconstruction amount +!HISTORY_MSG_68;HL reconstruction method +!HISTORY_MSG_69;Working color space +!HISTORY_MSG_70;Output color space +!HISTORY_MSG_71;Input color space +!HISTORY_MSG_72;VC - Amount +!HISTORY_MSG_73;Channel Mixer +!HISTORY_MSG_74;Resize - Scale +!HISTORY_MSG_75;Resize - Method +!HISTORY_MSG_76;Exif metadata +!HISTORY_MSG_77;IPTC metadata +!HISTORY_MSG_78;- +!HISTORY_MSG_79;Resize - Width +!HISTORY_MSG_80;Resize - Height +!HISTORY_MSG_81;Resize +!HISTORY_MSG_82;Profile changed +!HISTORY_MSG_83;S/H - Sharp mask +!HISTORY_MSG_84;Perspective correction +!HISTORY_MSG_85;LCP +!HISTORY_MSG_86;RGB curves - Luminosity mode +!HISTORY_MSG_87;Impulse noise reduction +!HISTORY_MSG_88;Impulse NR threshold +!HISTORY_MSG_89;Noise Reduction +!HISTORY_MSG_90;NR - Luminance +!HISTORY_MSG_91;NR - Chrominance master +!HISTORY_MSG_92;NR - Gamma +!HISTORY_MSG_93;CbDL - Value +!HISTORY_MSG_94;Contrast by Detail Levels +!HISTORY_MSG_95;L*a*b* - Chromaticity +!HISTORY_MSG_96;L*a*b* - a* curve +!HISTORY_MSG_97;L*a*b* - b* curve +!HISTORY_MSG_98;Demosaicing method +!HISTORY_MSG_99;Hot pixel filter +!HISTORY_MSG_100;RGB Saturation +!HISTORY_MSG_101;HSV - Hue +!HISTORY_MSG_102;HSV - Saturation +!HISTORY_MSG_103;HSV - Value +!HISTORY_MSG_104;HSV Equalizer +!HISTORY_MSG_105;Defringe +!HISTORY_MSG_106;Defringe - Radius +!HISTORY_MSG_107;Defringe - Threshold +!HISTORY_MSG_108;Highlight Compr. Threshold +!HISTORY_MSG_109;Resize - Bounding box +!HISTORY_MSG_110;Resize - Applies to +!HISTORY_MSG_111;L*a*b* - Avoid color shift +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;L*a*b* - Red/skin prot. +!HISTORY_MSG_114;DCB iterations +!HISTORY_MSG_115;False color suppression +!HISTORY_MSG_116;DCB enhancement +!HISTORY_MSG_117;Raw CA correction - Red +!HISTORY_MSG_118;Raw CA correction - Blue +!HISTORY_MSG_119;Line noise filter +!HISTORY_MSG_120;Green equilibration +!HISTORY_MSG_121;Raw CA Correction - Auto +!HISTORY_MSG_122;Dark-Frame - Auto-selection +!HISTORY_MSG_123;Dark-Frame - File +!HISTORY_MSG_124;White point correction +!HISTORY_MSG_125;Highlight preservation +!HISTORY_MSG_126;Flat-Field - File +!HISTORY_MSG_127;Flat-Field - Auto-selection +!HISTORY_MSG_128;Flat-Field - Blur radius +!HISTORY_MSG_129;Flat-Field - Blur type +!HISTORY_MSG_130;Auto distorion correction +!HISTORY_MSG_131;NR - Luma +!HISTORY_MSG_132;NR - Chroma +!HISTORY_MSG_133;Output gamma +!HISTORY_MSG_134;Free gamma +!HISTORY_MSG_135;Free gamma +!HISTORY_MSG_136;Free gamma slope +!HISTORY_MSG_137;Black level - Green 1 +!HISTORY_MSG_138;Black level - Red +!HISTORY_MSG_139;Black level - Blue +!HISTORY_MSG_140;Black level - Green 2 +!HISTORY_MSG_141;Black level - Link greens +!HISTORY_MSG_142;ES - Iterations +!HISTORY_MSG_143;ES - Quantity +!HISTORY_MSG_144;Microcontrast - Quantity +!HISTORY_MSG_145;Microcontrast - Uniformity +!HISTORY_MSG_146;Edge sharpening +!HISTORY_MSG_147;ES - Luminance only +!HISTORY_MSG_148;Microcontrast +!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_150;Post-demosaic artifact/noise red. +!HISTORY_MSG_151;Vibrance +!HISTORY_MSG_152;Vib - Pastel tones +!HISTORY_MSG_153;Vib - Saturated tones +!HISTORY_MSG_154;Vib - Protect skin-tones +!HISTORY_MSG_155;Vib - Avoid color shift +!HISTORY_MSG_156;Vib - Link pastel/saturated +!HISTORY_MSG_157;Vib - P/S threshold +!HISTORY_MSG_158;TM - Strength +!HISTORY_MSG_159;TM - Edge stopping +!HISTORY_MSG_160;TM - Scale +!HISTORY_MSG_161;TM - Reweighting iterates +!HISTORY_MSG_162;Tone Mapping +!HISTORY_MSG_163;RGB curves - Red +!HISTORY_MSG_164;RGB curves - Green +!HISTORY_MSG_165;RGB curves - Blue +!HISTORY_MSG_166;Neutral levels +!HISTORY_MSG_167;--unused-- +!HISTORY_MSG_168;L*a*b* - CC curve +!HISTORY_MSG_169;L*a*b* - CH curve +!HISTORY_MSG_170;Vibrance - HH curve +!HISTORY_MSG_171;L*a*b* - LC curve +!HISTORY_MSG_172;L*a*b* - Restrict LC +!HISTORY_MSG_173;NR - Luminance detail +!HISTORY_MSG_174;CIECAM02 +!HISTORY_MSG_175;CAM02 - CAT02 adaptation +!HISTORY_MSG_176;CAM02 - Viewing surround +!HISTORY_MSG_177;CAM02 - Scene luminosity +!HISTORY_MSG_178;CAM02 - Viewing luminosity +!HISTORY_MSG_179;CAM02 - White-point model +!HISTORY_MSG_180;CAM02 - Lightness (J) +!HISTORY_MSG_181;CAM02 - Chroma (C) +!HISTORY_MSG_182;CAM02 - Automatic CAT02 +!HISTORY_MSG_183;CAM02 - Contrast (J) +!HISTORY_MSG_184;CAM02 - Scene surround +!HISTORY_MSG_185;CAM02 - Gamut control +!HISTORY_MSG_186;CAM02 - Algorithm +!HISTORY_MSG_187;CAM02 - Red/skin prot. +!HISTORY_MSG_188;CAM02 - Brightness (Q) +!HISTORY_MSG_189;CAM02 - Contrast (Q) +!HISTORY_MSG_190;CAM02 - Saturation (S) +!HISTORY_MSG_191;CAM02 - Colorfulness (M) +!HISTORY_MSG_192;CAM02 - Hue (h) +!HISTORY_MSG_193;CAM02 - Tone curve 1 +!HISTORY_MSG_194;CAM02 - Tone curve 2 +!HISTORY_MSG_195;CAM02 - Tone curve 1 +!HISTORY_MSG_196;CAM02 - Tone curve 2 +!HISTORY_MSG_197;CAM02 - Color curve +!HISTORY_MSG_198;CAM02 - Color curve +!HISTORY_MSG_199;CAM02 - Output histograms +!HISTORY_MSG_200;CAM02 - Tone mapping +!HISTORY_MSG_201;NR - Chrominance - R&G +!HISTORY_MSG_202;NR - Chrominance - B&Y +!HISTORY_MSG_203;NR - Method +!HISTORY_MSG_204;LMMSE enhancement steps +!HISTORY_MSG_205;CAM02 - Hot/bad pixel filter +!HISTORY_MSG_206;CAT02 - Auto scene luminosity +!HISTORY_MSG_207;Defringe - Hue curve +!HISTORY_MSG_208;WB - B/R equalizer +!HISTORY_MSG_210;GF - Angle +!HISTORY_MSG_211;Graduated Filter +!HISTORY_MSG_212;VF - Strength +!HISTORY_MSG_213;Vignette Filter +!HISTORY_MSG_214;Black-and-White +!HISTORY_MSG_215;B&W - CM - Red +!HISTORY_MSG_216;B&W - CM - Green +!HISTORY_MSG_217;B&W - CM - Blue +!HISTORY_MSG_218;B&W - Gamma - Red +!HISTORY_MSG_219;B&W - Gamma - Green +!HISTORY_MSG_220;B&W - Gamma - Blue +!HISTORY_MSG_221;B&W - Color filter +!HISTORY_MSG_222;B&W - Presets +!HISTORY_MSG_223;B&W - CM - Orange +!HISTORY_MSG_224;B&W - CM - Yellow +!HISTORY_MSG_225;B&W - CM - Cyan +!HISTORY_MSG_226;B&W - CM - Magenta +!HISTORY_MSG_227;B&W - CM - Purple +!HISTORY_MSG_228;B&W - Luminance equalizer +!HISTORY_MSG_229;B&W - Luminance equalizer +!HISTORY_MSG_230;B&W - Mode +!HISTORY_MSG_231;B&W - 'Before' curve +!HISTORY_MSG_232;B&W - 'Before' curve type +!HISTORY_MSG_233;B&W - 'After' curve +!HISTORY_MSG_234;B&W - 'After' curve type +!HISTORY_MSG_235;B&W - Auto channel mixer +!HISTORY_MSG_236;--unused-- +!HISTORY_MSG_237;B&W - Mixer +!HISTORY_MSG_238;GF - Feather +!HISTORY_MSG_239;GF - Strength +!HISTORY_MSG_240;GF - Center +!HISTORY_MSG_241;VF - Feather +!HISTORY_MSG_242;VF - Roundness +!HISTORY_MSG_243;VC - Radius +!HISTORY_MSG_244;VC - Strength +!HISTORY_MSG_245;VC - Center +!HISTORY_MSG_246;L*a*b* - CL curve +!HISTORY_MSG_247;L*a*b* - LH curve +!HISTORY_MSG_248;L*a*b* - HH curve +!HISTORY_MSG_249;CbDL - Threshold +!HISTORY_MSG_250;NR - Enhanced +!HISTORY_MSG_251;B&W - Algorithm +!HISTORY_MSG_252;CbDL - Skin tar/prot +!HISTORY_MSG_253;CbDL - Reduce artifacts +!HISTORY_MSG_254;CbDL - Skin hue +!HISTORY_MSG_255;NR - Median filter +!HISTORY_MSG_256;NR - Median type +!HISTORY_MSG_257;Color Toning +!HISTORY_MSG_258;CT - Color curve +!HISTORY_MSG_259;CT - Opacity curve +!HISTORY_MSG_260;CT - a*[b*] opacity +!HISTORY_MSG_261;CT - Method +!HISTORY_MSG_262;CT - b* opacity +!HISTORY_MSG_263;CT - Shadows - Red +!HISTORY_MSG_264;CT - Shadows - Green +!HISTORY_MSG_265;CT - Shadows - Blue +!HISTORY_MSG_266;CT - Mid - Red +!HISTORY_MSG_267;CT - Mid - Green +!HISTORY_MSG_268;CT - Mid - Blue +!HISTORY_MSG_269;CT - High - Red +!HISTORY_MSG_270;CT - High - Green +!HISTORY_MSG_271;CT - High - Blue +!HISTORY_MSG_272;CT - Balance +!HISTORY_MSG_273;CT - Reset +!HISTORY_MSG_274;CT - Sat. Shadows +!HISTORY_MSG_275;CT - Sat. Highlights +!HISTORY_MSG_276;CT - Opacity +!HISTORY_MSG_277;--unused-- +!HISTORY_MSG_278;CT - Preserve luminance +!HISTORY_MSG_279;CT - Shadows +!HISTORY_MSG_280;CT - Highlights +!HISTORY_MSG_281;CT - Sat. strength +!HISTORY_MSG_282;CT - Sat. threshold +!HISTORY_MSG_283;CT - Strength +!HISTORY_MSG_284;CT - Auto sat. protection +!HISTORY_MSG_285;NR - Median - Method +!HISTORY_MSG_286;NR - Median - Type +!HISTORY_MSG_287;NR - Median - Iterations +!HISTORY_MSG_288;Flat Field - Clip control +!HISTORY_MSG_289;Flat Field - Clip control - Auto +!HISTORY_MSG_290;Black Level - Red +!HISTORY_MSG_291;Black Level - Green +!HISTORY_MSG_292;Black Level - Blue +!HISTORY_MSG_293;Film Simulation +!HISTORY_MSG_294;Film Simulation - Strength +!HISTORY_MSG_295;Film Simulation - Film +!HISTORY_MSG_296;NR - Luminance curve +!HISTORY_MSG_297;NR - Quality +!HISTORY_MSG_298;Dead pixel filter +!HISTORY_MSG_299;NR - Chrominance curve +!HISTORY_MSG_300;- +!HISTORY_MSG_301;NR - Luma control +!HISTORY_MSG_302;NR - Chroma method +!HISTORY_MSG_303;NR - Chroma method +!HISTORY_MSG_304;W - Contrast levels +!HISTORY_MSG_305;Wavelet Levels +!HISTORY_MSG_306;W - Preview +!HISTORY_MSG_307;W - Preview +!HISTORY_MSG_308;W - Preview direction +!HISTORY_MSG_309;W - ES - Detail +!HISTORY_MSG_310;W - Residual - Sky tar/prot +!HISTORY_MSG_311;W - Wavelet levels +!HISTORY_MSG_312;W - Residual - Shadows threshold +!HISTORY_MSG_313;W - Chroma - Sat/past +!HISTORY_MSG_314;W - Gamut - Reduce artifacts +!HISTORY_MSG_315;W - Residual - Contrast +!HISTORY_MSG_316;W - Gamut - Skin tar/prot +!HISTORY_MSG_317;W - Gamut - Skin hue +!HISTORY_MSG_318;W - Contrast - Highlight levels +!HISTORY_MSG_319;W - Contrast - Highlight range +!HISTORY_MSG_320;W - Contrast - Shadow range +!HISTORY_MSG_321;W - Contrast - Shadow levels +!HISTORY_MSG_322;W - Gamut - Avoid color shift +!HISTORY_MSG_323;W - ES - Local contrast +!HISTORY_MSG_324;W - Chroma - Pastel +!HISTORY_MSG_325;W - Chroma - Saturated +!HISTORY_MSG_326;W - Chroma - Method +!HISTORY_MSG_327;W - Contrast - Apply to +!HISTORY_MSG_328;W - Chroma - Link strength +!HISTORY_MSG_329;W - Toning - Opacity RG +!HISTORY_MSG_330;W - Toning - Opacity BY +!HISTORY_MSG_331;W - Contrast levels - Extra +!HISTORY_MSG_332;W - Tiling method +!HISTORY_MSG_333;W - Residual - Shadows +!HISTORY_MSG_334;W - Residual - Chroma +!HISTORY_MSG_335;W - Residual - Highlights +!HISTORY_MSG_336;W - Residual - Highlights threshold +!HISTORY_MSG_337;W - Residual - Sky hue +!HISTORY_MSG_338;W - ES - Radius +!HISTORY_MSG_339;W - ES - Strength +!HISTORY_MSG_340;W - Strength +!HISTORY_MSG_341;W - Edge performance +!HISTORY_MSG_342;W - ES - First level +!HISTORY_MSG_343;W - Chroma levels +!HISTORY_MSG_344;W - Meth chroma sl/cur +!HISTORY_MSG_345;W - ES - Local contrast +!HISTORY_MSG_346;W - ES - Local contrast method +!HISTORY_MSG_347;W - Denoise - Level 0 +!HISTORY_MSG_348;W - Denoise - Level 1 +!HISTORY_MSG_349;W - Denoise - Level 2 +!HISTORY_MSG_350;W - ES - Edge detection +!HISTORY_MSG_351;W - Residual - HH curve +!HISTORY_MSG_352;W - Background +!HISTORY_MSG_353;W - ES - Gradient sensitivity +!HISTORY_MSG_354;W - ES - Enhance +!HISTORY_MSG_355;W - ES - Threshold low +!HISTORY_MSG_356;W - ES - Threshold high +!HISTORY_MSG_357;W - Denoise - Link with ES +!HISTORY_MSG_358;W - Gamut - CH +!HISTORY_MSG_359;Hot/Dead - Threshold +!HISTORY_MSG_360;TM Gamma +!HISTORY_MSG_361;W - Final - Chroma balance +!HISTORY_MSG_362;W - Residual - Compression method +!HISTORY_MSG_363;W - Residual - Compression strength +!HISTORY_MSG_364;W - Final - Contrast balance +!HISTORY_MSG_365;W - Final - Delta balance +!HISTORY_MSG_366;W - Residual - Compression gamma +!HISTORY_MSG_367;W - ES - Local contrast curve +!HISTORY_MSG_368;W - Final - Contrast balance +!HISTORY_MSG_369;W - Final - Balance method +!HISTORY_MSG_370;W - Final - Local contrast curve +!HISTORY_NEWSNAPSHOT;Add +!HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s +!HISTORY_SNAPSHOTS;Snapshots +!HISTORY_SNAPSHOT;Snapshot +!IPTCPANEL_AUTHORSPOSITIONHINT;Title of the creator or creators of the object (By-line Title). +!IPTCPANEL_AUTHORSPOSITION;Author's position +!IPTCPANEL_AUTHOR;Author +!IPTCPANEL_CAPTIONHINT;A textual description of the data (Caption - Abstract). +!IPTCPANEL_CAPTIONWRITERHINT;The name of the person involved in the writing, editing or correcting the image or caption/abstract (Writer - Editor). +!IPTCPANEL_CAPTIONWRITER;Caption writer +!IPTCPANEL_CAPTION;Caption +!IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider (Category). +!IPTCPANEL_CATEGORY;Category +!IPTCPANEL_CITYHINT;City of image origin (City). +!IPTCPANEL_CITY;City +!IPTCPANEL_COPYHINT;Copy IPTC settings to clipboard. +!IPTCPANEL_COPYRIGHTHINT;Any necessary copyright notice (Copyright Notice). +!IPTCPANEL_COPYRIGHT;Copyright +!IPTCPANEL_COUNTRYHINT;The name of the country/primary location where the image was created (Country - Primary Location Name). +!IPTCPANEL_COUNTRY;Country +!IPTCPANEL_CREDITHINT;Identifies the provider of the image, not necessarily the owner/creator (Credit). +!IPTCPANEL_CREDIT;Credit +!IPTCPANEL_DATECREATEDHINT;The date the intellectual content of the image was created; Format: YYYYMMDD (Date Created). +!IPTCPANEL_DATECREATED;Date created +!IPTCPANEL_EMBEDDEDHINT;Reset to IPTC data embedded in the image file. +!IPTCPANEL_EMBEDDED;Embedded +!IPTCPANEL_HEADLINEHINT;A publishable entry providing a synopsis of the contents of the image (Headline). +!IPTCPANEL_HEADLINE;Headline +!IPTCPANEL_INSTRUCTIONSHINT;Other editorial instructions concerning the use of the image (Special Instructions). +!IPTCPANEL_INSTRUCTIONS;Instructions +!IPTCPANEL_KEYWORDSHINT;Used to indicate specific information retrieval words (Keywords). +!IPTCPANEL_KEYWORDS;Keywords +!IPTCPANEL_PASTEHINT;Paste IPTC settings from clipboard. +!IPTCPANEL_PROVINCEHINT;The Province/State where the image originates (Province-State). +!IPTCPANEL_PROVINCE;Province +!IPTCPANEL_RESETHINT;Reset to profile default. +!IPTCPANEL_RESET;Reset +!IPTCPANEL_SOURCEHINT;The original owner of the intellectual content of the image (Source). +!IPTCPANEL_SOURCE;Source +!IPTCPANEL_SUPPCATEGORIESHINT;Further refines the subject of the image (Supplemental Categories). +!IPTCPANEL_SUPPCATEGORIES;Suppl. categories +!IPTCPANEL_TITLEHINT;A shorthand reference for the image (Object Name). +!IPTCPANEL_TITLE;Title +!IPTCPANEL_TRANSREFERENCEHINT;A code representing the location of the original transmission (Original Transmission Reference). +!IPTCPANEL_TRANSREFERENCE;Trans. reference +!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 +!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). +!MAIN_BUTTON_PREFERENCES;Preferences +!MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Put current image to processing queue.\nShortcut: Ctrl+b +!MAIN_BUTTON_SAVE_TOOLTIP;Save current image.\nShortcut: Ctrl+s +!MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Edit current image in external editor.\nShortcut: Ctrl+e +!MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Show/hide all side panels.\nShortcut: m +!MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen +!MAIN_FRAME_BATCHQUEUE;Queue +!MAIN_FRAME_BATCHQUEUE_TOOLTIP;Processing queue.\nShortcut: Ctrl-F3 +!MAIN_FRAME_EDITOR;Editor +!MAIN_FRAME_EDITOR_TOOLTIP;Editor.\nShortcut: Ctrl-F4 +!MAIN_FRAME_FILEBROWSER;File Browser +!MAIN_FRAME_FILEBROWSER_TOOLTIP;File browser.\nShortcut: Ctrl-F2 +!MAIN_FRAME_PLACES;Places +!MAIN_FRAME_PLACES_ADD;Add +!MAIN_FRAME_PLACES_DEL;Del +!MAIN_FRAME_RECENT;Recent Folders +!MAIN_MSG_ALREADYEXISTS;File already exists. +!MAIN_MSG_CANNOTLOAD;Cannot load image +!MAIN_MSG_CANNOTSAVE;File saving error +!MAIN_MSG_CANNOTSTARTEDITOR;Cannot start editor. +!MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Please set the correct path in Preferences. +!MAIN_MSG_EMPTYFILENAME;Filename unspecified! +!MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue-processed first. +!MAIN_MSG_NAVIGATOR;Navigator +!MAIN_MSG_OPERATIONCANCELLED;Operation cancelled +!MAIN_MSG_PATHDOESNTEXIST;The path\n\n%1\n\ndoes not exist. Please set a correct path in Preferences. +!MAIN_MSG_QOVERWRITE;Do you want to overwrite it? +!MAIN_MSG_SETPATHFIRST;You first have to set a target path in Preferences in order to use this function! +!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;Color +!MAIN_TAB_COLOR_TOOLTIP;Shortcut: Alt-c +!MAIN_TAB_DETAIL;Detail +!MAIN_TAB_DETAIL_TOOLTIP;Shortcut: Alt-d +!MAIN_TAB_DEVELOP; Develop +!MAIN_TAB_EXIF;Exif +!MAIN_TAB_EXPORT; Fast Export +!MAIN_TAB_EXPOSURE;Exposure +!MAIN_TAB_EXPOSURE_TOOLTIP;Shortcut: Alt-e +!MAIN_TAB_FILTER; Filter +!MAIN_TAB_INSPECT; Inspect +!MAIN_TAB_IPTC;IPTC +!MAIN_TAB_METADATA;Metadata +!MAIN_TAB_METADATA_TOOLTIP;Shortcut: Alt-m +!MAIN_TAB_RAW;Raw +!MAIN_TAB_RAW_TOOLTIP;Shortcut: Alt-r +!MAIN_TAB_TRANSFORM;Transform +!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_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: < +!MAIN_TOOLTIP_INDCLIPPEDS;Clipped shadow indication.\nShortcut: > +!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%. +!MAIN_TOOLTIP_PREVIEWG;Preview the Green channel.\nShortcut: g +!MAIN_TOOLTIP_PREVIEWL;Preview the Luminosity.\nShortcut: v\n\n0.299*R + 0.587*G + 0.114*B +!MAIN_TOOLTIP_PREVIEWR;Preview the Red channel.\nShortcut: r +!MAIN_TOOLTIP_QINFO;Quick info on the image.\nShortcut: i +!MAIN_TOOLTIP_SHOWHIDELP1;Show/Hide the left panel.\nShortcut: l +!MAIN_TOOLTIP_SHOWHIDERP1;Show/Hide the right panel.\nShortcut: Alt-l +!MAIN_TOOLTIP_SHOWHIDETP1;Show/Hide the top panel.\nShortcut: Shift-l +!MAIN_TOOLTIP_THRESHOLD;Threshold +!MAIN_TOOLTIP_TOGGLE;Toggle the Before/After view.\nShortcut: Shift-b +!NAVIGATOR_B;B: +!NAVIGATOR_G;G: +!NAVIGATOR_H;H: +!NAVIGATOR_LAB_A;a*: +!NAVIGATOR_LAB_B;b*: +!NAVIGATOR_LAB_L;L*: +!NAVIGATOR_NA; -- +!NAVIGATOR_R;R: +!NAVIGATOR_S;S: +!NAVIGATOR_V;V: +!NAVIGATOR_XY_FULL;Width: %1, Height: %2 +!NAVIGATOR_XY_NA;x: --, y: -- +!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_BASICGROUP;Basic Settings +!PARTIALPASTE_CACORRECTION;Chromatic aberration correction +!PARTIALPASTE_CHANNELMIXERBW;Black-and-White +!PARTIALPASTE_CHANNELMIXER;Channel mixer +!PARTIALPASTE_COARSETRANS;Coarse rotation / flipping +!PARTIALPASTE_COLORAPP;CIECAM02 +!PARTIALPASTE_COLORGROUP;Color Related Settings +!PARTIALPASTE_COLORTONING;Color Toning +!PARTIALPASTE_COMMONTRANSFORMPARAMS;Auto-fill +!PARTIALPASTE_COMPOSITIONGROUP;Composition Settings +!PARTIALPASTE_CROP;Crop +!PARTIALPASTE_DARKFRAMEAUTOSELECT;Dark-frame auto-selection +!PARTIALPASTE_DARKFRAMEFILE;Dark-frame file +!PARTIALPASTE_DEFRINGE;Defringe +!PARTIALPASTE_DETAILGROUP;Detail Settings +!PARTIALPASTE_DIALOGLABEL;Partial paste processing profile +!PARTIALPASTE_DIRPYRDENOISE;Noise reduction +!PARTIALPASTE_DIRPYREQUALIZER;Contrast by detail levels +!PARTIALPASTE_DISTORTION;Distortion correction +!PARTIALPASTE_EPD;Tone mapping +!PARTIALPASTE_EQUALIZER;Wavelet Equalizer +!PARTIALPASTE_EVERYTHING;Everything +!PARTIALPASTE_EXIFCHANGES;Exif +!PARTIALPASTE_EXPOSURE;Exposure +!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_GRADIENT;Graduated filter +!PARTIALPASTE_HSVEQUALIZER;HSV equalizer +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_ICMSETTINGS;Color management settings +!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_METAGROUP;Metadata +!PARTIALPASTE_PCVIGNETTE;Vignette filter +!PARTIALPASTE_PERSPECTIVE;Perspective +!PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter +!PARTIALPASTE_PREPROCESS_GREENEQUIL;Green equilibration +!PARTIALPASTE_PREPROCESS_HOTPIXFILT;Hot pixel filter +!PARTIALPASTE_PREPROCESS_LINEDENOISE;Line noise filter +!PARTIALPASTE_RAWCACORR_AUTO;CA auto-correction +!PARTIALPASTE_RAWCACORR_CABLUE;CA blue +!PARTIALPASTE_RAWCACORR_CARED;CA red +!PARTIALPASTE_RAWEXPOS_BLACK;Black levels +!PARTIALPASTE_RAWEXPOS_LINEAR;White point correction +!PARTIALPASTE_RAWEXPOS_PRESER;Highlight preservation +!PARTIALPASTE_RAWGROUP;Raw Settings +!PARTIALPASTE_RAW_DCBENHANCE;DCB enhancement +!PARTIALPASTE_RAW_DCBITERATIONS;Number of DCB iterations +!PARTIALPASTE_RAW_DMETHOD;Demosaic method +!PARTIALPASTE_RAW_FALSECOLOR;Demosaic false color suppression steps +!PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!PARTIALPASTE_RESIZE;Resize +!PARTIALPASTE_RGBCURVES;RGB curves +!PARTIALPASTE_ROTATION;Rotation +!PARTIALPASTE_SHADOWSHIGHLIGHTS;Shadows/highlights +!PARTIALPASTE_SHARPENEDGE;Edges +!PARTIALPASTE_SHARPENING;Sharpening (USM/RL) +!PARTIALPASTE_SHARPENMICRO;Microcontrast +!PARTIALPASTE_VIBRANCE;Vibrance +!PARTIALPASTE_VIGNETTING;Vignetting correction +!PARTIALPASTE_WAVELETGROUP;Wavelet processing +!PARTIALPASTE_WHITEBALANCE;White balance +!PREFERENCES_ADD;Add +!PREFERENCES_APPLNEXTSTARTUP;restart required +!PREFERENCES_AUTLISLOW;Low +!PREFERENCES_AUTLISMAX;Max - Average of all tiles +!PREFERENCES_AUTLISSTD;High +!PREFERENCES_AUTLISVLOW;None +!PREFERENCES_AUTLOW;Low +!PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +!PREFERENCES_AUTSTD;Standard +!PREFERENCES_BATCH_PROCESSING;Batch Processing +!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_BEHADDALL;All to 'Add' +!PREFERENCES_BEHAVIOR;Behavior +!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_BEHSETALL;All to 'Set' +!PREFERENCES_BLACKBODY;Tungsten +!PREFERENCES_CACHECLEARALL;Clear All +!PREFERENCES_CACHECLEARPROFILES;Clear Processing Profiles +!PREFERENCES_CACHECLEARTHUMBS;Clear Thumbnails +!PREFERENCES_CACHEMAXENTRIES;Maximum number of cache entries +!PREFERENCES_CACHEOPTS;Cache Options +!PREFERENCES_CACHETHUMBHEIGHT;Maximum thumbnail height +!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_CLIPPINGIND;Clipping Indication +!PREFERENCES_CLUTSCACHE;HaldCLUT Cache +!PREFERENCES_CLUTSCACHE_LABEL;Maximum number of cached CLUTs +!PREFERENCES_CLUTSDIR;HaldCLUT directory +!PREFERENCES_CMETRICINTENT;Colorimetric intent +!PREFERENCES_CURVEBBOXPOS;Position of curve copypasta buttons +!PREFERENCES_CURVEBBOXPOS_ABOVE;Above +!PREFERENCES_CURVEBBOXPOS_BELOW;Below +!PREFERENCES_CURVEBBOXPOS_LEFT;Left +!PREFERENCES_CURVEBBOXPOS_RIGHT;Right +!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_CUSTPROFBUILD;Custom Processing Profile Builder +!PREFERENCES_CUTOVERLAYBRUSH;Crop mask color/transparency +!PREFERENCES_D50;5000K +!PREFERENCES_D55;5500K +!PREFERENCES_D60;6000K +!PREFERENCES_D65;6500K +!PREFERENCES_DARKFRAMEFOUND;Found +!PREFERENCES_DARKFRAMESHOTS;shots +!PREFERENCES_DARKFRAMETEMPLATES;templates +!PREFERENCES_DARKFRAME;Dark-Frame +!PREFERENCES_DATEFORMATHINT;You can use the following formatting strings:\n%y - year\n%m - month\n%d - day\n\nFor example, the ISO 8601 standard dictates the date format as follows:\n%y-%m-%d +!PREFERENCES_DATEFORMAT;Date format +!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_DEFAULTLANG;Default Language +!PREFERENCES_DEFAULTTHEME;Default Theme +!PREFERENCES_DIRDARKFRAMES;Dark-frames directory +!PREFERENCES_DIRHOME;Home directory +!PREFERENCES_DIRLAST;Last visited directory +!PREFERENCES_DIROTHER;Other +!PREFERENCES_DIRSELECTDLG;Select Image Directory at Startup... +!PREFERENCES_DIRSOFTWARE;Installation directory +!PREFERENCES_EDITORCMDLINE;Other command line +!PREFERENCES_EDITORLAYOUT;Editor Layout +!PREFERENCES_EXPAUT;Expert +!PREFERENCES_EXTERNALEDITOR;External Editor +!PREFERENCES_FBROWSEROPTS;File Browser / Thumbnail Options +!PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar (de-select for low resolution display) +!PREFERENCES_FILEFORMAT;File format +!PREFERENCES_FILMSIMULATION;Film Simulation +!PREFERENCES_FLATFIELDFOUND;Found +!PREFERENCES_FLATFIELDSDIR;Flat-fields directory +!PREFERENCES_FLATFIELDSHOTS;shots +!PREFERENCES_FLATFIELDTEMPLATES;templates +!PREFERENCES_FLATFIELD;Flat-Field +!PREFERENCES_FLUOF2;Fluorescent F2 +!PREFERENCES_FLUOF7;Fluorescent F7 +!PREFERENCES_FLUOF11;Fluorescent F11 +!PREFERENCES_FORIMAGE;For non-raw photos +!PREFERENCES_FORRAW;For raw photos +!PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT;Same thumbnail height between the Editor's panel 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 installation directory +!PREFERENCES_GREY05;Yb=05 CIE L#30 +!PREFERENCES_GREY10;Yb=10 CIE L#40 +!PREFERENCES_GREY15;Yb=15 CIE L#45 +!PREFERENCES_GREY18;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_GREYSC18;Yb=18 CIE L#50 +!PREFERENCES_GREYSCA;Automatic +!PREFERENCES_GREYSC;Scene Yb luminance (%) +!PREFERENCES_GREY;Output device's Yb luminance (%) +!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_HLTHRESHOLD;Threshold for clipped highlights +!PREFERENCES_ICCDIR;Directory containing color profiles +!PREFERENCES_IMG_RELOAD_NEEDED;These changes require the image to be reloaded (or a new image to be opened) to take effect. +!PREFERENCES_IMPROCPARAMS;Default Processing Profile +!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_INTENT_ABSOLUTE;Absolute Colorimetric +!PREFERENCES_INTENT_PERCEPTUAL;Perceptual +!PREFERENCES_INTENT_RELATIVE;Relative Colorimetric +!PREFERENCES_INTENT_SATURATION;Saturation +!PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Show embedded JPEG thumbnail if raw is unedited +!PREFERENCES_LANGAUTODETECT;Use system language +!PREFERENCES_LEVAUTDN;Denoising level +!PREFERENCES_LEVDN;Cell size +!PREFERENCES_LISS;Auto multi-zone smoothing +!PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders +!PREFERENCES_MAX;Maxi (Tile) +!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_MENUGROUPRANK;Group "Rank" +!PREFERENCES_MENUOPTIONS;Context Menu Options +!PREFERENCES_METADATA;Metadata +!PREFERENCES_MIN;Mini (100x115) +!PREFERENCES_MONITORICC;Monitor color profile +!PREFERENCES_MULTITABDUALMON;Multiple Editor Tabs In Own Window Mode +!PREFERENCES_MULTITAB;Multiple Editor Tabs Mode +!PREFERENCES_NAVGUIDEBRUSH;Navigator guide color +!PREFERENCES_NAVIGATIONFRAME;Navigation +!PREFERENCES_NOISE;Noise Reduction +!PREFERENCES_OUTDIRFOLDERHINT;Save images to the selected folder. +!PREFERENCES_OUTDIRFOLDER;Save to folder +!PREFERENCES_OUTDIRTEMPLATEHINT;You can use the following formatting strings:\n%f, %d1, %d2, ..., %p1, %p2, ..., %r, %s1, %s2, ...\n\nThese formatting strings refer to the different parts of the photo's pathname, some attributes of the photo or an arbitrary sequence index in the batch job.\n\nFor example, if the photo being processed has the following pathname:\n/home/tom/photos/2010-10-31/dsc0042.nef\nthe meaning of the formatting strings are:\n%d4 = home\n%d3 = tom\n%d2 = photos\n%d1 = 2010-10-31\n%f = dsc0042\n%p1 = /home/tom/photos/2010-10-31/\n%p2 = /home/tom/photos/\n%p3 = /home/tom/\n%p4 = /home/\n\n%r will be replaced by the rank of the photo. If the photo is unranked, %r will be replaced by '0'. If the photo is in the trash bin, %r will be replaced by 'x'.\n\n%s1, %s2, etc. will be replaced by a sequence index which is padded to between 1 and 9 digits. The sequence index will start at one each time the queue processing is started and is incremented by one for each image processed.\n\nIf you want to save the output image where the original is, write:\n%p1/%f\n\nIf you want to save the output image in a directory named "converted" located in the directory of the opened image, write:\n%p1/converted/%f\n\nIf you want to save the output image in a directory named "/home/tom/photos/converted/2010-10-31", write:\n%p2/converted/%d1/%f +!PREFERENCES_OUTDIRTEMPLATE;Use template +!PREFERENCES_OUTDIR;Output Directory +!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_PARSEDEXTADDHINT;Add entered extension to the list. +!PREFERENCES_PARSEDEXTADD;Add extension +!PREFERENCES_PARSEDEXTDELHINT;Delete selected extension from the list. +!PREFERENCES_PARSEDEXT;Parsed Extensions +!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_PROFILEHANDLING;Processing Profile Handling +!PREFERENCES_PROFILELOADPR;Processing profile loading priority +!PREFERENCES_PROFILEPRCACHE;Profile in cache +!PREFERENCES_PROFILEPRFILE;Profile next to the input file +!PREFERENCES_PROFILESAVECACHE;Save processing profile to the cache +!PREFERENCES_PROFILESAVEINPUT;Save processing profile next to the input file +!PREFERENCES_PROPERTY;Property +!PREFERENCES_PSPATH;Adobe Photoshop installation directory +!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 font +!PREFERENCES_SELECTLANG;Select language +!PREFERENCES_SELECTTHEME;Select theme +!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_SHOWBASICEXIF;Show basic Exif info +!PREFERENCES_SHOWDATETIME;Show date and time +!PREFERENCES_SHOWEXPOSURECOMPENSATION;Append exposure compensation +!PREFERENCES_SHOWFILMSTRIPTOOLBAR;Show filmstrip toolbar +!PREFERENCES_SHTHRESHOLD;Threshold for clipped shadows +!PREFERENCES_SIMPLAUT;Tool mode +!PREFERENCES_SINGLETABVERTAB;Single Editor Tab Mode, Vertical Tabs +!PREFERENCES_SINGLETAB;Single Editor Tab Mode +!PREFERENCES_SLIMUI;Slim interface +!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_STARTUPIMDIR;Image Directory at Startup +!PREFERENCES_STDAUT;Standard +!PREFERENCES_TAB_BROWSER;File Browser +!PREFERENCES_TAB_COLORMGR;Color Management +!PREFERENCES_TAB_GENERAL;General +!PREFERENCES_TAB_IMPROC;Image Processing +!PREFERENCES_TAB_PERFORMANCE;Performance & Quality +!PREFERENCES_TAB_SOUND;Sounds +!PREFERENCES_TIMAX;High +!PREFERENCES_TINB;Number of tiles +!PREFERENCES_TISTD;Standard +!PREFERENCES_TP_LABEL;Tool panel: +!PREFERENCES_TP_USEICONORTEXT;Use tab icons instead of text +!PREFERENCES_TP_VSCROLLBAR;Hide vertical scrollbar +!PREFERENCES_TUNNELMETADATA;Copy IPTC/XMP unchanged to output file (when tagging with other program) +!PREFERENCES_USEBUNDLEDPROFILES;Use bundled profiles +!PREFERENCES_USESYSTEMTHEME;Use system theme +!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_WORKFLOW;Layout +!PROFILEPANEL_COPYPPASTE;Parameters to copy +!PROFILEPANEL_GLOBALPROFILES;Bundled profiles +!PROFILEPANEL_LABEL;Processing Profiles +!PROFILEPANEL_LOADDLGLABEL;Load Processing Parameters... +!PROFILEPANEL_LOADPPASTE;Parameters to load +!PROFILEPANEL_MODE_TIP;Processing profile fill mode.\n\nButton pressed: partial profiles will be converted to full profiles; the missing values will be replaced with hard-coded defaults.\n\nButton released: profiles will be applied as they are, altering only those values which they contain. +!PROFILEPANEL_MYPROFILES;My profiles +!PROFILEPANEL_PASTEPPASTE;Parameters to paste +!PROFILEPANEL_PCUSTOM;Custom +!PROFILEPANEL_PFILE;From file +!PROFILEPANEL_PINTERNAL;Neutral +!PROFILEPANEL_PLASTSAVED;Last Saved +!PROFILEPANEL_SAVEDLGLABEL;Save Processing Parameters... +!PROFILEPANEL_SAVEPPASTE;Parameters to save +!PROFILEPANEL_TOOLTIPCOPY;Copy current processing profile to clipboard.\nCtrl-click to select the parameters to copy. +!PROFILEPANEL_TOOLTIPLOAD;Load a profile from file.\nCtrl-click to select the parameters to load. +!PROFILEPANEL_TOOLTIPPASTE;Paste profile from clipboard.\nCtrl-click to select the parameters to paste. +!PROFILEPANEL_TOOLTIPSAVE;Save current profile.\nCtrl-click to select the parameters to save. +!PROGRESSBAR_LOADINGTHUMBS;Loading thumbnails... +!PROGRESSBAR_LOADING;Loading image... +!PROGRESSBAR_LOADJPEG;Loading JPEG file... +!PROGRESSBAR_LOADPNG;Loading PNG file... +!PROGRESSBAR_LOADTIFF;Loading TIFF file... +!PROGRESSBAR_NOIMAGES;No images found +!PROGRESSBAR_PROCESSING;Processing image... +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing profile saved +!PROGRESSBAR_READY;Ready +!PROGRESSBAR_SAVEJPEG;Saving JPEG file... +!PROGRESSBAR_SAVEPNG;Saving PNG file... +!PROGRESSBAR_SAVETIFF;Saving TIFF file... +!PROGRESSBAR_SNAPSHOT_ADDED;Snapshot added +!PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!QINFO_ISO;ISO +!QINFO_NOEXIF;Exif data not available. +!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_PUTTOQUEUEHEAD;Put to the head of the processing queue +!SAVEDLG_PUTTOQUEUETAIL;Put to the end of the processing queue +!SAVEDLG_PUTTOQUEUE;Put into processing queue +!SAVEDLG_SAVEIMMEDIATELY;Save immediately +!SAVEDLG_SAVESPP;Save processing parameters with image +!SAVEDLG_SUBSAMP;Subsampling +!SAVEDLG_SUBSAMP_1;Best compression +!SAVEDLG_SUBSAMP_2;Balanced +!SAVEDLG_SUBSAMP_3;Best quality +!SAVEDLG_SUBSAMP_TOOLTIP;Best compression: 4:1:1\nBalanced: 4:2:2\nBest quality: 4:4:4 +!SAVEDLG_TIFFUNCOMPRESSED;Uncompressed TIFF +!SAVEDLG_WARNFILENAME;File will be named +!SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. +!THRESHOLDSELECTOR_BL;Bottom-left +!THRESHOLDSELECTOR_BR;Bottom-right +!THRESHOLDSELECTOR_B;Bottom +!THRESHOLDSELECTOR_HINT;Hold the Shift key to move individual control points. +!THRESHOLDSELECTOR_TL;Top-left +!THRESHOLDSELECTOR_TR;Top-right +!THRESHOLDSELECTOR_T;Top +!TOOLBAR_TOOLTIP_CROP;Crop selection.\nShortcut: c\nMove the crop area using Shift-mouse drag +!TOOLBAR_TOOLTIP_HAND;Hand tool.\nShortcut: h +!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. Center of rotation is the geometrical center of the image. +!TOOLBAR_TOOLTIP_WB;Spot white balance.\nShortcut: w +!TP_BWMIX_ALGO;Algorithm OYCPM +!TP_BWMIX_ALGO_LI;Linear +!TP_BWMIX_ALGO_SP;Special effects +!TP_BWMIX_ALGO_TOOLTIP;Linear: will produce a normal linear response.\nSpecial effects: will produce special effects by mixing channels non-linearly. +!TP_BWMIX_AUTOCH;Auto +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing Channel Mixer. +!TP_BWMIX_CC_ENABLED;Adjust complementary color +!TP_BWMIX_CC_TOOLTIP;Enable to allow automatic adjustment of complementary colors in ROYGCBPM mode. +!TP_BWMIX_CHANNEL;Luminance equalizer +!TP_BWMIX_CURVEEDITOR1;'Before' curve +!TP_BWMIX_CURVEEDITOR2;'After' curve +!TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Tone curve, after B&W conversion, at the end of treatment. +!TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Tone curve, just before B&W conversion.\nMay take into account the color components. +!TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H).\nPay attention to extreme values as they may cause artifacts. +!TP_BWMIX_FILTER;Color Filter +!TP_BWMIX_FILTER_BLUEGREEN;Blue-Green +!TP_BWMIX_FILTER_BLUE;Blue +!TP_BWMIX_FILTER_GREENYELLOW;Green-Yellow +!TP_BWMIX_FILTER_GREEN;Green +!TP_BWMIX_FILTER_NONE;None +!TP_BWMIX_FILTER_PURPLE;Purple +!TP_BWMIX_FILTER_REDYELLOW;Red-Yellow +!TP_BWMIX_FILTER_RED;Red +!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. +!TP_BWMIX_FILTER_YELLOW;Yellow +!TP_BWMIX_GAMMA;Gamma Correction +!TP_BWMIX_GAM_TOOLTIP;Correct gamma for each RGB channel. +!TP_BWMIX_LABEL;Black-and-White +!TP_BWMIX_MET;Method +!TP_BWMIX_MET_CHANMIX;Channel Mixer +!TP_BWMIX_MET_DESAT;Desaturation +!TP_BWMIX_MET_LUMEQUAL;Luminance Equalizer +!TP_BWMIX_MIXC;Mixer +!TP_BWMIX_NEUTRAL;Reset mixer +!TP_BWMIX_NEUTRAL_TIP;Reset all values (Color Filter, Channel Mixer) to default. +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all the mixer options.\n"Total" displays the sum of the RGB values:\n- always 100% in relative mode\n- higher (lighter) or lower (darker) than 100% in absolute mode. +!TP_BWMIX_RGB_TOOLTIP;Mix the RGB channels. Use presets for guidance.\nPay attention to negative values that may cause artifacts or erratic behavior. +!TP_BWMIX_SETTING;Presets +!TP_BWMIX_SETTING_TOOLTIP;Different presets (film, landscape, etc.) or manual Channel Mixer settings. +!TP_BWMIX_SET_HIGHCONTAST;High contrast +!TP_BWMIX_SET_HIGHSENSIT;High Sensitivity +!TP_BWMIX_SET_HYPERPANCHRO;Hyper Panchromatic +!TP_BWMIX_SET_INFRARED;Infrared +!TP_BWMIX_SET_LANDSCAPE;Landscape +!TP_BWMIX_SET_LOWSENSIT;Low Sensitivity +!TP_BWMIX_SET_LUMINANCE;Luminance +!TP_BWMIX_SET_NORMCONTAST;Normal Contrast +!TP_BWMIX_SET_ORTHOCHRO;Orthochromatic +!TP_BWMIX_SET_PANCHRO;Panchromatic +!TP_BWMIX_SET_PORTRAIT;Portrait +!TP_BWMIX_SET_RGBABS;Absolute RGB +!TP_BWMIX_SET_RGBREL;Relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Relative ROYGCBPM +!TP_BWMIX_TCMODE_FILMLIKE;B&W Film-like +!TP_BWMIX_TCMODE_SATANDVALBLENDING;B&W Saturation and Value Blending +!TP_BWMIX_TCMODE_STANDARD;B&W Standard +!TP_BWMIX_TCMODE_WEIGHTEDSTD;B&W Weighted Standard +!TP_BWMIX_VAL;L +!TP_CACORRECTION_BLUE;Blue +!TP_CACORRECTION_LABEL;Chromatic Aberration Correction +!TP_CACORRECTION_RED;Red +!TP_CHMIXER_BLUE;Blue channel +!TP_CHMIXER_GREEN;Green channel +!TP_CHMIXER_LABEL;Channel Mixer +!TP_CHMIXER_RED;Red channel +!TP_CHROMATABERR_LABEL;Chromatic Aberration +!TP_COARSETRAF_TOOLTIP_HFLIP;Flip horizontally. +!TP_COARSETRAF_TOOLTIP_ROTLEFT;Rotate left.\n\nShortcuts:\n[ - Multiple Editor Tabs Mode,\nAlt-[ - Single Editor Tab Mode. +!TP_COARSETRAF_TOOLTIP_ROTRIGHT;Rotate right.\n\nShortcuts:\n] - Multiple Editor Tabs Mode,\nAlt-] - Single Editor Tab Mode. +!TP_COARSETRAF_TOOLTIP_VFLIP;Flip vertically. +!TP_COLORAPP_ADAPTSCENE;Scene luminosity +!TP_COLORAPP_ADAPTSCENE_TOOLTIP;Absolute luminance of the scene environement (cd/m²).\n1) Calculated from the Exif data:\nShutter speed - ISO speed - F number - camera exposure correction.\n2) Calculated from the raw white point and RT's Exposure Compensation slider. +!TP_COLORAPP_ADAPTVIEWING;Viewing luminosity (cd/m²) +!TP_COLORAPP_ADAPTVIEWING_TOOLTIP;Absolute luminance of the viewing environnement\n(usually 16cd/m²). +!TP_COLORAPP_ADAP_AUTO_TOOLTIP;If the checkbox is checked (recommended) RawTherapee calculates an optimum value from Exif data.\nTo set the value manually, uncheck the checkbox first. +!TP_COLORAPP_ALGO;Algorithm +!TP_COLORAPP_ALGO_ALL;All +!TP_COLORAPP_ALGO_JC;Lightness + Chroma (JC) +!TP_COLORAPP_ALGO_JS;Lightness + Saturation (JS) +!TP_COLORAPP_ALGO_QM;Brightness + Colorfulness (QM) +!TP_COLORAPP_ALGO_TOOLTIP;Lets you choose between parameter subsets or all parameters. +!TP_COLORAPP_BADPIXSL;Hot/bad pixel filter +!TP_COLORAPP_BADPIXSL_TOOLTIP;Suppression of hot/bad (brightly colored) pixels.\n0 = No effect\n1 = Median\n2 = Gaussian.\nAlternatively, adjust the image to avoid very dark shadows.\n\nThese artifacts are due to limitations of CIECAM02. +!TP_COLORAPP_BRIGHT;Brightness (Q) +!TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from L*a*b* and RGB brightness. +!TP_COLORAPP_CHROMA;Chroma (C) +!TP_COLORAPP_CHROMA_M;Colorfulnes (M) +!TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM02 differs from L*a*b* and RGB colorfulness. +!TP_COLORAPP_CHROMA_S;Saturation (S) +!TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from L*a*b* and RGB saturation. +!TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from L*a*b* and RGB chroma. +!TP_COLORAPP_CIECAT_DEGREE;CAT02 adaptation +!TP_COLORAPP_CONTRAST;Contrast (J) +!TP_COLORAPP_CONTRAST_Q;Contrast (Q) +!TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrast in CIECAM02 for the Q slider; it differs from L*a*b* and RGB contrast. +!TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from L*a*b* and RGB contrast. +!TP_COLORAPP_CURVEEDITOR1;Tone curve 1 +!TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L* (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of J or Q after CIECAM02.\n\nJ and Q are not shown in the main histogram panel.\n\nFor final output refer to the main histogram panel. +!TP_COLORAPP_CURVEEDITOR2;Tone curve 2 +!TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Same usage as with the second exposure tone curve. +!TP_COLORAPP_CURVEEDITOR3;Color curve +!TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Adjust either chroma, saturation or colorfulness.\n\nShows the histogram of chromaticity (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of C, s or M after CIECAM02.\n\nC, s and M are not shown in the main histogram panel.\nFor final output refer to the main histogram panel. +!TP_COLORAPP_DATACIE;CIECAM02 output histograms in curves +!TP_COLORAPP_DATACIE_TOOLTIP;When enabled, histograms in CIECAM02 curves show approximate values/ranges for J or Q, and C, s or M after the CIECAM02 adjustments.\nThis selection does not impact the main histogram panel.\n\nWhen disabled, histograms in CIECAM02 curves show L*a*b* values before CIECAM02 adjustments. +!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RawTherapee calculates an optimum value, which is then used by CAT02, and also for the entire CIECAM02.\nTo set the value manually, uncheck the check-box first (values above 65 are recommended). +!TP_COLORAPP_DEGREE_TOOLTIP;Amount of CIE Chromatic Adaptation Transform 2002. +!TP_COLORAPP_GAMUT;Gamut control (L*a*b*) +!TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in L*a*b* mode. +!TP_COLORAPP_HUE;Hue (h) +!TP_COLORAPP_HUE_TOOLTIP;Hue (h) - angle between 0° and 360°. +!TP_COLORAPP_LABEL;CIE Color Appearance Model 2002 +!TP_COLORAPP_LABEL_CAM02;Image Adjustments +!TP_COLORAPP_LABEL_SCENE;Scene Conditions +!TP_COLORAPP_LABEL_VIEWING;Viewing Conditions +!TP_COLORAPP_LIGHT;Lightness (J) +!TP_COLORAPP_LIGHT_TOOLTIP;Lightness in CIECAM02 differs from L*a*b* and RGB lightness. +!TP_COLORAPP_MODEL;WP Model +!TP_COLORAPP_MODEL_TOOLTIP;White-Point Model.\n\nWB [RT] + [output]: RT's white balance is used for the scene, CIECAM02 is set to D50, and the output device's white balance is set in Preferences > Color Management.\n\nWB [RT+CAT02] + [output]: RT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences - Color Management. +!TP_COLORAPP_RSTPRO;Red & skin-tones protection +!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin-tones protection affects both sliders and curves. +!TP_COLORAPP_SHARPCIE;--unused-- +!TP_COLORAPP_SHARPCIE_TOOLTIP;--unused-- +!TP_COLORAPP_SURROUND;Surround +!TP_COLORAPP_SURROUND_AVER;Average +!TP_COLORAPP_SURROUND_DARK;Dark +!TP_COLORAPP_SURROUND_DIM;Dim +!TP_COLORAPP_SURROUND_EXDARK;Extremly Dark (Cutsheet) +!TP_COLORAPP_SURROUND_TOOLTIP;Changes tones and colors to take into account the viewing conditions of the output device.\n\nAverage: Average light environment (standard). The image will not change.\n\nDim: Dim environment (TV). The image will become slighty dark.\n\nDark: Dark environment (projector). The image will become more dark.\n\nExtremly Dark: Extremly dark environment (cutsheet). The image will become very dark. +!TP_COLORAPP_SURSOURCE;Dark surround +!TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if image has a dark border. +!TP_COLORAPP_TCMODE_BRIGHTNESS;Brightness +!TP_COLORAPP_TCMODE_CHROMA;Chroma +!TP_COLORAPP_TCMODE_COLORF;Colorfulness +!TP_COLORAPP_TCMODE_LABEL1;Curve mode 1 +!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_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] +!TP_COLORAPP_WBRT;WB [RT] + [output] +!TP_COLORTONING_AB;o C/L +!TP_COLORTONING_AUTOSAT;Automatic +!TP_COLORTONING_BALANCE;Balance +!TP_COLORTONING_BY;o C/L +!TP_COLORTONING_CHROMAC;Opacity +!TP_COLORTONING_COLOR;Color +!TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;Chroma opacity as a function of luminance oC=f(L) +!TP_COLORTONING_HIGHLIGHT;Highlights +!TP_COLORTONING_HUE;Hue +!TP_COLORTONING_LABEL;Color Toning +!TP_COLORTONING_LAB;L*a*b* blending +!TP_COLORTONING_LUMAMODE;Preserve luminance +!TP_COLORTONING_LUMAMODE_TOOLTIP;If enabled, when you change color (red, green, cyan, blue, etc.) the luminance of each pixel is preserved. +!TP_COLORTONING_LUMA;Luminance +!TP_COLORTONING_METHOD;Method +!TP_COLORTONING_METHOD_TOOLTIP;"L*a*b* blending", "RGB sliders" and "RGB curves" use interpolated color blending.\n"Color balance (Shadows/Midtones/Highlights)" and "Saturation 2 colors" use direct colors.\n\nThe Black-and-White tool can be enabled when using any color toning method, which allows for color toning. +!TP_COLORTONING_MIDTONES;Midtones +!TP_COLORTONING_NEUTRAL;Reset sliders +!TP_COLORTONING_NEUTRAL_TIP;Reset all values (Shadows, Midtones, Highlights) to default. +!TP_COLORTONING_OPACITY;Opacity +!TP_COLORTONING_RGBCURVES;RGB - Curves +!TP_COLORTONING_RGBSLIDERS;RGB - Sliders +!TP_COLORTONING_SATURATEDOPACITY;Strength +!TP_COLORTONING_SATURATIONTHRESHOLD;Threshold +!TP_COLORTONING_SA;Saturation Protection +!TP_COLORTONING_SHADOWS;Shadows +!TP_COLORTONING_SPLITCOCO;Color Balance Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITCO;Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITLR;Saturation 2 colors +!TP_COLORTONING_STRENGTH;Strength +!TP_COLORTONING_STR;Strength +!TP_COLORTONING_TWO2;Special chroma '2 colors' +!TP_COLORTONING_TWOALL;Special chroma +!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_FIXRATIO;Lock ratio +!TP_CROP_GTDIAGONALS;Rule of Diagonals +!TP_CROP_GTEPASSPORT;Biometric Passport +!TP_CROP_GTFRAME;Frame +!TP_CROP_GTGRID;Grid +!TP_CROP_GTHARMMEANS;Harmonic Means +!TP_CROP_GTNONE;None +!TP_CROP_GTRULETHIRDS;Rule of Thirds +!TP_CROP_GTTRIANGLE1;Golden Triangles 1 +!TP_CROP_GTTRIANGLE2;Golden Triangles 2 +!TP_CROP_GUIDETYPE;Guide type: +!TP_CROP_H;Height +!TP_CROP_LABEL;Crop +!TP_CROP_PPI;PPI= +!TP_CROP_SELECTCROP;Select Crop +!TP_CROP_W;Width +!TP_CROP_X;X +!TP_CROP_Y;Y +!TP_DARKFRAME_AUTOSELECT;Auto-selection +!TP_DARKFRAME_LABEL;Dark-Frame +!TP_DEFRINGE_LABEL;Defringe +!TP_DEFRINGE_RADIUS;Radius +!TP_DEFRINGE_THRESHOLD;Threshold +!TP_DIRPYRDENOISE_33;3×3 strong +!TP_DIRPYRDENOISE_55SOFT;5×5 +!TP_DIRPYRDENOISE_55;5×5 strong +!TP_DIRPYRDENOISE_77;7×7 (slow) +!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_ABM;Chroma only +!TP_DIRPYRDENOISE_AUTO;Automatic global +!TP_DIRPYRDENOISE_AUTO_TOOLTIP;Try to evaluate chroma noise\nBe careful, this calculation is average, and is quite subjective ! +!TP_DIRPYRDENOISE_AUT;Automatic global +!TP_DIRPYRDENOISE_BLUE;Chrominance - Blue-Yellow +!TP_DIRPYRDENOISE_C2TYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CCCURVE;Chrominance curve +!TP_DIRPYRDENOISE_CHROMAFR;Chrominance +!TP_DIRPYRDENOISE_CHROMA;Chrominance - Master +!TP_DIRPYRDENOISE_CTYPE;Auto method +!TP_DIRPYRDENOISE_CTYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nAutomatic multi-zones\nNo preview - works only during saving, but using the "Preview" method by matching the tile size and center to the preview size and center you can get an idea of the expected results.\nThe image is divided into tiles (about 10 to 70 depending on image size) and each tile receives its own chrominance noise reduction settings.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CURVEEDITOR_CC;Chroma +!TP_DIRPYRDENOISE_CURVEEDITOR_CC_TOOLTIP;Increase (multiply) the value of all chrominance sliders.\nThis curve lets you adjust the strength of chromatic noise reduction as a function of chromaticity, for instance to increase the action in areas of low saturation and to decrease it in those of high saturation. +!TP_DIRPYRDENOISE_CURVEEDITOR_L_TOOLTIP;Modulates action of 'Luminance' denoise +!TP_DIRPYRDENOISE_CUR;Curve +!TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on the gamma of the input color profile. An sRGB gamma is assumed, thus if the image uses an input color profile of a different gamma, the effects of luminance noise reduction will differ. +!TP_DIRPYRDENOISE_ENH;Enhanced mode +!TP_DIRPYRDENOISE_ENH_TOOLTIP;Increases noise reduction quality at the expense of a 20% processing time increase. +!TP_DIRPYRDENOISE_GAMMA;Gamma +!TP_DIRPYRDENOISE_GAMMA_TOOLTIP;Gamma varies noise reduction strength across the range of tones. Smaller values will target shadows, while larger values will stretch the effect to the brighter tones. +!TP_DIRPYRDENOISE_LABEL;Noise Reduction +!TP_DIRPYRDENOISE_LABM;L*a*b* +!TP_DIRPYRDENOISE_LAB;L*a*b* +!TP_DIRPYRDENOISE_LCURVE;Luminance curve +!TP_DIRPYRDENOISE_LDETAIL;Luminance - Detail +!TP_DIRPYRDENOISE_LM;Luminance only +!TP_DIRPYRDENOISE_LPLABM;Weighted L* (little) + a*b* (normal) +!TP_DIRPYRDENOISE_LTYPE;Luminance control +!TP_DIRPYRDENOISE_LUMAFR;Luminance +!TP_DIRPYRDENOISE_LUMAFR_TOOLTIP;Wavelet on luminance and Fourier transform for luminance detail +!TP_DIRPYRDENOISE_LUMA;Luminance +!TP_DIRPYRDENOISE_MANU;Manual +!TP_DIRPYRDENOISE_MAN;Manual +!TP_DIRPYRDENOISE_MEDMETHOD;Median method +!TP_DIRPYRDENOISE_MEDTYPE;Median type +!TP_DIRPYRDENOISE_MED;Median Filter +!TP_DIRPYRDENOISE_MED_TOOLTIP;Enabled median denoising +!TP_DIRPYRDENOISE_METHOD11;Quality +!TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. +!TP_DIRPYRDENOISE_METHOD;Method +!TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or L*a*b* methods can be used.\n\nFor non-raw images the L*a*b* method will be used, regardless of the selection. +!TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - +!TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 +!TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. +!TP_DIRPYRDENOISE_PASSES;Median iterations +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PON;Auto multi-zones +!TP_DIRPYRDENOISE_PREVLABEL;Preview size=%1, Center: Px=%2 Py=%3 +!TP_DIRPYRDENOISE_PREV;Preview +!TP_DIRPYRDENOISE_PRE;Preview multi-zones +!TP_DIRPYRDENOISE_RED;Chrominance - Red-Green +!TP_DIRPYRDENOISE_RGBM;RGB +!TP_DIRPYRDENOISE_RGB;RGB +!TP_DIRPYRDENOISE_SHALBI;High +!TP_DIRPYRDENOISE_SHAL;Standard +!TP_DIRPYRDENOISE_SLI;Slider +!TP_DIRPYRDENOISE_SOFT;3x3 +!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_LUMAFINEST;Finest +!TP_DIRPYREQUALIZER_LUMANEUTRAL;Neutral +!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_THRESHOLD;Threshold +!TP_DIRPYREQUALIZER_TOOLTIP;Attempts to reduce artifacts in the transitions between skin colors (hue, chroma, luma) and the rest of the image. +!TP_DISTORTION_AMOUNT;Amount +!TP_DISTORTION_AUTO;Auto Distortion Correction +!TP_DISTORTION_AUTO_TIP;Correct lens distortion automatically for some cameras (Micro 4/3, some compact digital cameras, etc.). +!TP_DISTORTION_LABEL;Distortion Correction +!TP_EPD_EDGESTOPPING;Edge stopping +!TP_EPD_GAMMA;Gamma +!TP_EPD_LABEL;Tone Mapping +!TP_EPD_REWEIGHTINGITERATES;Reweighting iterates +!TP_EPD_SCALE;Scale +!TP_EPD_STRENGTH;Strength +!TP_EPD_TOOLTIP;Tone mapping is possible in L*a*b* mode (standard) and CIECAM02 mode.\n\nWhen in L*a*b* mode, tone mapping can also be used on the residual image of the Wavelet Levels tool.\n\nTo engage CIECAM02 tone mapping mode enable the following settings:\n1. CIECAM02\n2. Algorithm="Brightness + Colorfulness (QM)"\n3. "Tone mapping using CIECAM02 brightness (Q)" +!TP_EXPOSURE_AUTOLEVELS;Auto Levels +!TP_EXPOSURE_AUTOLEVELS_TIP;Toggles execution of Auto Levels to automatically set Exposure slider values based on an image analysis.\nEnables Highlight Reconstruction if necessary. +!TP_EXPOSURE_BLACKLEVEL;Black +!TP_EXPOSURE_BRIGHTNESS;Lightness +!TP_EXPOSURE_CLIP;Clip % +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in Auto Levels operation. +!TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Highlight compression threshold +!TP_EXPOSURE_COMPRHIGHLIGHTS;Highlight compression +!TP_EXPOSURE_COMPRSHADOWS;Shadow compression +!TP_EXPOSURE_CONTRAST;Contrast +!TP_EXPOSURE_CURVEEDITOR1;Tone curve 1 +!TP_EXPOSURE_CURVEEDITOR2;Tone curve 2 +!TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Please refer to the "Exposure > Tone Curves" RawPedia article to learn how to achieve the best results by using two tone curves. +!TP_EXPOSURE_EXPCOMP;Exposure compensation +!TP_EXPOSURE_LABEL;Exposure +!TP_EXPOSURE_SATURATION;Saturation +!TP_EXPOSURE_TCMODE_FILMLIKE;Film-like +!TP_EXPOSURE_TCMODE_LABEL1;Curve mode 1 +!TP_EXPOSURE_TCMODE_LABEL2;Curve mode 2 +!TP_EXPOSURE_TCMODE_LUMINANCE;Luminance +!TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Saturation and Value Blending +!TP_EXPOSURE_TCMODE_STANDARD;Standard +!TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard +!TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points +!TP_EXPOS_WHITEPOINT_LABEL;Raw White Points +!TP_FILMSIMULATION_LABEL;Film Simulation +!TP_FILMSIMULATION_STRENGTH;Strength +!TP_FILMSIMULATION_ZEROCLUTSFOUND;Set HaldCLUT directory in Preferences +!TP_FLATFIELD_AUTOSELECT;Auto-selection +!TP_FLATFIELD_BLURRADIUS;Blur radius +!TP_FLATFIELD_BLURTYPE;Blur type +!TP_FLATFIELD_BT_AREA;Area +!TP_FLATFIELD_BT_HORIZONTAL;Horizontal +!TP_FLATFIELD_BT_VERTHORIZ;Vertical + Horizontal +!TP_FLATFIELD_BT_VERTICAL;Vertical +!TP_FLATFIELD_CLIPCONTROL;Clip control +!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. +!TP_FLATFIELD_LABEL;Flat-Field +!TP_GAMMA_CURV;Gamma +!TP_GAMMA_FREE;Free gamma +!TP_GAMMA_OUTPUT;Output gamma +!TP_GAMMA_SLOP;Slope (linear) +!TP_GENERAL_11SCALE_TOOLTIP;The effects of this tool are only visible or only accurate at a preview scale of 1:1. +!TP_GRADIENT_CENTER;Center +!TP_GRADIENT_CENTER_X;Center X +!TP_GRADIENT_CENTER_X_TOOLTIP;Shift gradient to the left (negative values) or right (positive values). +!TP_GRADIENT_CENTER_Y;Center Y +!TP_GRADIENT_CENTER_Y_TOOLTIP;Shift gradient up (negative values) or down (positive values). +!TP_GRADIENT_DEGREE;Angle +!TP_GRADIENT_DEGREE_TOOLTIP;Rotation angle in degrees. +!TP_GRADIENT_FEATHER;Feather +!TP_GRADIENT_FEATHER_TOOLTIP;Gradient width in percent of the image diagonal. +!TP_GRADIENT_LABEL;Graduated Filter +!TP_GRADIENT_STRENGTH;Strength +!TP_GRADIENT_STRENGTH_TOOLTIP;Filter strength in stops. +!TP_HLREC_BLEND;Blend +!TP_HLREC_CIELAB;CIELab Blending +!TP_HLREC_COLOR;Color Propagation +!TP_HLREC_ENA_TOOLTIP;Could be activated by Auto Levels. +!TP_HLREC_LABEL;Highlight reconstruction +!TP_HLREC_LUMINANCE;Luminance Recovery +!TP_HLREC_METHOD;Method: +!TP_HSVEQUALIZER_CHANNEL;Channel +!TP_HSVEQUALIZER_HUE;H +!TP_HSVEQUALIZER_LABEL;HSV Equalizer +!TP_HSVEQUALIZER_SAT;S +!TP_HSVEQUALIZER_VAL;V +!TP_ICM_BLENDCMSMATRIX;Blend ICC highlights with matrix +!TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover clipped highlights when using LUT-based ICC profiles. +!TP_ICM_DCPILLUMINANT;Illuminant +!TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolated +!TP_ICM_DCPILLUMINANT_TOOLTIP;Select which embedded DCP illuminant to employ. Default is "interpolated" which is a mix between the two based on white balance. The setting is only enabled if a Dual-Illuminant DCP with interpolation support is selected. +!TP_ICM_INPUTCAMERAICC;Auto-matched camera profile +!TP_ICM_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input color profiles. These profiles are more precise than simpler matrix ones. They are not available for all cameras. These profiles are stored in the /iccprofiles/input and /dcpprofiles folders and are automatically retrieved based on a file name matching to the exact model name of the camera. +!TP_ICM_INPUTCAMERA;Camera standard +!TP_ICM_INPUTCAMERA_TOOLTIP;Use a simple color matrix from dcraw, an enhanced RawTherapee version (whichever is available based on camera model) or one embedded in the DNG. +!TP_ICM_INPUTCUSTOM;Custom +!TP_ICM_INPUTCUSTOM_TOOLTIP;Select your own DCP/ICC color profile file for the camera. +!TP_ICM_INPUTDLGLABEL;Select Input DCP/ICC Profile... +!TP_ICM_INPUTEMBEDDED;Use embedded, if possible +!TP_ICM_INPUTEMBEDDED_TOOLTIP;Use color profile embedded in non-raw files. +!TP_ICM_INPUTNONE;No profile +!TP_ICM_INPUTNONE_TOOLTIP;Use no input color profile at all.\nUse only in special cases. +!TP_ICM_INPUTPROFILE;Input Profile +!TP_ICM_LABEL;Color Management +!TP_ICM_NOICM;No ICM: sRGB Output +!TP_ICM_OUTPUTPROFILE;Output Profile +!TP_ICM_SAVEREFERENCE;Save Reference Image for Profiling +!TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance +!TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. The result can be used for calibration purposes and generation of a camera profile. +!TP_ICM_TONECURVE;Use DCP's tone curve +!TP_ICM_TONECURVE_TOOLTIP;Employ the embedded DCP tone curve. The setting is only enabled if the selected DCP has a tone curve. +!TP_ICM_WORKINGPROFILE;Working Profile +!TP_IMPULSEDENOISE_LABEL;Impulse Noise Reduction +!TP_IMPULSEDENOISE_THRESH;Threshold +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid color shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction. +!TP_LABCURVE_BRIGHTNESS;Lightness +!TP_LABCURVE_CHROMATICITY;Chromaticity +!TP_LABCURVE_CHROMA_TOOLTIP;To apply B&W toning, set Chromaticity to -100. +!TP_LABCURVE_CONTRAST;Contrast +!TP_LABCURVE_CURVEEDITOR;Luminance Curve +!TP_LABCURVE_CURVEEDITOR_A_RANGE1;Green Saturated +!TP_LABCURVE_CURVEEDITOR_A_RANGE2;Green Pastel +!TP_LABCURVE_CURVEEDITOR_A_RANGE3;Red Pastel +!TP_LABCURVE_CURVEEDITOR_A_RANGE4;Red Saturated +!TP_LABCURVE_CURVEEDITOR_B_RANGE1;Blue Saturated +!TP_LABCURVE_CURVEEDITOR_B_RANGE2;Blue Pastel +!TP_LABCURVE_CURVEEDITOR_B_RANGE3;Yellow Pastel +!TP_LABCURVE_CURVEEDITOR_B_RANGE4;Yellow Saturated +!TP_LABCURVE_CURVEEDITOR_CC;CC +!TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutral +!TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Dull +!TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastel +!TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Saturated +!TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Chromaticity according to chromaticity C=f(C) +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to hue C=f(H) +!TP_LABCURVE_CURVEEDITOR_CL;CL +!TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Chromaticity according to luminance C=f(L) +!TP_LABCURVE_CURVEEDITOR_HH;HH +!TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Hue according to hue H=f(H) +!TP_LABCURVE_CURVEEDITOR_LC;LC +!TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminance according to chromaticity L=f(C) +!TP_LABCURVE_CURVEEDITOR_LH;LH +!TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H) +!TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminance according to luminance L=f(L) +!TP_LABCURVE_LABEL;L*a*b* Adjustments +!TP_LABCURVE_LCREDSK;Restrict LC to red and skin-tones +!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_LENSGEOM_AUTOCROP;Auto-Crop +!TP_LENSGEOM_FILL;Auto-fill +!TP_LENSGEOM_LABEL;Lens / Geometry +!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_USECA;Chromatic aberration correction +!TP_LENSPROFILE_USEDIST;Distortion correction +!TP_LENSPROFILE_USEVIGN;Vignetting correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Resets exposure sliders to neutral values.\nApplies to the same controls that Auto Levels applies to, regardless of whether you used Auto Levels or not. +!TP_PCVIGNETTE_FEATHER;Feather +!TP_PCVIGNETTE_FEATHER_TOOLTIP;Feathering:\n0 = corners only,\n50 = halfway to center,\n100 = to center. +!TP_PCVIGNETTE_LABEL;Vignette Filter +!TP_PCVIGNETTE_ROUNDNESS;Roundness +!TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness:\n0 = rectangle,\n50 = fitted ellipse,\n100 = circle. +!TP_PCVIGNETTE_STRENGTH;Strength +!TP_PCVIGNETTE_STRENGTH_TOOLTIP;Filter strength in stops (reached in corners). +!TP_PERSPECTIVE_HORIZONTAL;Horizontal +!TP_PERSPECTIVE_LABEL;Perspective +!TP_PERSPECTIVE_VERTICAL;Vertical +!TP_PFCURVE_CURVEEDITOR_CH;Hue +!TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Controls defringe strength by color.\nHigher = more,\nLower = less. +!TP_PREPROCESS_DEADPIXFILT;Dead pixel filter +!TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Tries to suppress dead pixels. +!TP_PREPROCESS_GREENEQUIL;Green equilibration +!TP_PREPROCESS_HOTPIXFILT;Hot pixel filter +!TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Tries to suppress hot pixels. +!TP_PREPROCESS_LABEL;Preprocessing +!TP_PREPROCESS_LINEDENOISE;Line noise filter +!TP_PREPROCESS_NO_FOUND;None found +!TP_RAWCACORR_AUTO;Auto-correction +!TP_RAWCACORR_CABLUE;Blue +!TP_RAWCACORR_CARED;Red +!TP_RAWEXPOS_BLACKS;Black Levels +!TP_RAWEXPOS_BLACK_0;Green 1 (lead) +!TP_RAWEXPOS_BLACK_1;Red +!TP_RAWEXPOS_BLACK_2;Blue +!TP_RAWEXPOS_BLACK_3;Green 2 +!TP_RAWEXPOS_BLACK_BLUE;Blue +!TP_RAWEXPOS_BLACK_GREEN;Green +!TP_RAWEXPOS_BLACK_RED;Red +!TP_RAWEXPOS_LINEAR;White-point correction +!TP_RAWEXPOS_PRESER;Highlight preservation +!TP_RAWEXPOS_RGB;Red, Green, Blue +!TP_RAWEXPOS_TWOGREEN;Link greens +!TP_RAW_DCBENHANCE;DCB enhancement +!TP_RAW_DCBITERATIONS;Number of DCB iterations +!TP_RAW_DMETHOD;Method +!TP_RAW_DMETHOD_PROGRESSBAR;%1 demosaicing... +!TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Demosaicing refinement... +!TP_RAW_DMETHOD_TOOLTIP;Note: IGV and LMMSE are dedicated to high ISO images to aid in noise reduction without leading to maze patterns, posterization or a washed-out look. +!TP_RAW_FALSECOLOR;False color suppression steps +!TP_RAW_HD;Threshold +!TP_RAW_HD_TOOLTIP;Lower values make hot/dead pixel detection more aggressive, but false positives may lead to artifacts. If you notice any artifacts appearing when enabling the Hot/Dead Pixel Filters, gradually increase the threshold value until they disappear. +!TP_RAW_LABEL;Demosaicing +!TP_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!TP_RAW_LMMSE_TOOLTIP;Adds gamma (step 1), median (steps 2-4) and refinement (steps 5-6) to reduce artifacts and improve the signal-to-noise ratio. +!TP_RAW_SENSOR_BAYER_LABEL;Sensor with Bayer Matrix +!TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;3-pass gives best results (recommended for low ISO images).\n1-pass is almost undistinguishable from 3-pass for high ISO images and is faster. +!TP_RAW_SENSOR_XTRANS_LABEL;Sensor with X-Trans Matrix +!TP_RESIZE_APPLIESTO;Applies to: +!TP_RESIZE_CROPPEDAREA;Cropped Area +!TP_RESIZE_FITBOX;Bounding Box +!TP_RESIZE_FULLIMAGE;Full Image +!TP_RESIZE_HEIGHT;Height +!TP_RESIZE_H;Height: +!TP_RESIZE_LABEL;Resize +!TP_RESIZE_LANCZOS;Lanczos +!TP_RESIZE_METHOD;Method: +!TP_RESIZE_NEAREST;Nearest +!TP_RESIZE_SCALE;Scale +!TP_RESIZE_SPECIFY;Specify: +!TP_RESIZE_WIDTH;Width +!TP_RESIZE_W;Width: +!TP_RGBCURVES_BLUE;B +!TP_RGBCURVES_CHANNEL;Channel +!TP_RGBCURVES_GREEN;G +!TP_RGBCURVES_LABEL;RGB Curves +!TP_RGBCURVES_LUMAMODE;Luminosity mode +!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_RGBCURVES_RED;R +!TP_ROTATE_DEGREE;Degree +!TP_ROTATE_LABEL;Rotate +!TP_ROTATE_SELECTLINE;Select Straight Line +!TP_SAVEDIALOG_OK_TIP;Shortcut: Ctrl-Enter +!TP_SHADOWSHLIGHTS_HIGHLIGHTS;Highlights +!TP_SHADOWSHLIGHTS_HLTONALW;Highlights tonal width +!TP_SHADOWSHLIGHTS_LABEL;Shadows/highlights +!TP_SHADOWSHLIGHTS_LOCALCONTR;Local contrast +!TP_SHADOWSHLIGHTS_RADIUS;Radius +!TP_SHADOWSHLIGHTS_SHADOWS;Shadows +!TP_SHADOWSHLIGHTS_SHARPMASK;Sharp mask +!TP_SHADOWSHLIGHTS_SHTONALW;Shadows tonal width +!TP_SHARPENEDGE_AMOUNT;Quantity +!TP_SHARPENEDGE_LABEL;Edges +!TP_SHARPENEDGE_PASSES;Iterations +!TP_SHARPENEDGE_THREE;Luminance only +!TP_SHARPENING_AMOUNT;Amount +!TP_SHARPENING_EDRADIUS;Radius +!TP_SHARPENING_EDTOLERANCE;Edge tolerance +!TP_SHARPENING_HALOCONTROL;Halo control +!TP_SHARPENING_HCAMOUNT;Amount +!TP_SHARPENING_LABEL;Sharpening +!TP_SHARPENING_METHOD;Method +!TP_SHARPENING_ONLYEDGES;Sharpen only edges +!TP_SHARPENING_RADIUS;Radius +!TP_SHARPENING_RLD;RL Deconvolution +!TP_SHARPENING_RLD_AMOUNT;Amount +!TP_SHARPENING_RLD_DAMPING;Damping +!TP_SHARPENING_RLD_ITERATIONS;Iterations +!TP_SHARPENING_THRESHOLD;Threshold +!TP_SHARPENING_TOOLTIP;Expect a slightly different effect when using with CIECAM02. If difference is observed, adjust to taste. +!TP_SHARPENING_USM;Unsharp Mask +!TP_SHARPENMICRO_AMOUNT;Quantity +!TP_SHARPENMICRO_LABEL;Microcontrast +!TP_SHARPENMICRO_MATRIX;3×3 matrix instead of 5×5 +!TP_SHARPENMICRO_UNIFORMITY;Uniformity +!TP_VIBRANCE_AVOIDCOLORSHIFT;Avoid color shift +!TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Red/Purple +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Red +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Red/Yellow +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Yellow +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Hue according to hue H=f(H) +!TP_VIBRANCE_LABEL;Vibrance +!TP_VIBRANCE_PASTELS;Pastel Tones +!TP_VIBRANCE_PASTSATTOG;Link pastel and saturated tones +!TP_VIBRANCE_PROTECTSKINS;Protect skin-tones +!TP_VIBRANCE_PSTHRESHOLD;Pastel/saturated tones threshold +!TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Saturation threshold +!TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;The vertical axis represents pastel tones at the bottom and saturated tones at the top.\nThe horizontal axis represents the saturation range. +!TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Pastel/saturated transition's weighting +!TP_VIBRANCE_SATURATED;Saturated Tones +!TP_VIGNETTING_AMOUNT;Amount +!TP_VIGNETTING_CENTER;Center +!TP_VIGNETTING_CENTER_X;Center X +!TP_VIGNETTING_CENTER_Y;Center Y +!TP_VIGNETTING_LABEL;Vignetting Correction +!TP_VIGNETTING_RADIUS;Radius +!TP_VIGNETTING_STRENGTH;Strength +!TP_WAVELET_1;Level 1 +!TP_WAVELET_2;Level 2 +!TP_WAVELET_3;Level 3 +!TP_WAVELET_4;Level 4 +!TP_WAVELET_5;Level 5 +!TP_WAVELET_6;Level 6 +!TP_WAVELET_7;Level 7 +!TP_WAVELET_8;Level 8 +!TP_WAVELET_9;Level 9 +!TP_WAVELET_ALL;All levels in all directions +!TP_WAVELET_APPLYTO;Apply To +!TP_WAVELET_AVOID;Avoid color shift +!TP_WAVELET_B0;Black +!TP_WAVELET_B1;Grey +!TP_WAVELET_B2;Residual +!TP_WAVELET_BACUR;Curve +!TP_WAVELET_BALANCE;Contrast balance d/v-h +!TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chromaticity or residual tone mapping are activated, the effect due to balance is amplified. +!TP_WAVELET_BALCHRO;Chroma balance +!TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chromaticity balance. +!TP_WAVELET_BANONE;None +!TP_WAVELET_BASLI;Slider +!TP_WAVELET_BATYPE;Contrast balance method +!TP_WAVELET_CCURVE;Local contrast +!TP_WAVELET_CH1;Whole chromaticity range +!TP_WAVELET_CH2;Saturated/pastel +!TP_WAVELET_CH3;Link contrast levels +!TP_WAVELET_CHCU;Curve +!TP_WAVELET_CHRO;Saturated/pastel threshold +!TP_WAVELET_CHRO_TOOLTIP;Sets the wavelet level which will be the threshold between saturated and pastel colors.\n1-x: saturated\nx-9: pastel\n\nIf the value exceeds the amount of wavelet levels you are using then it will be ignored. +!TP_WAVELET_CHR;Chroma-contrast link strength +!TP_WAVELET_CHR_TOOLTIP;Adjusts chromaticity as a function of "contrast levels" and "chroma-contrast link strength" +!TP_WAVELET_CHSL;Sliders +!TP_WAVELET_CHTYPE;Chrominance method +!TP_WAVELET_COLORT;Opacity Red-Green +!TP_WAVELET_COMBOTH;Both +!TP_WAVELET_COMPCONT;Contrast +!TP_WAVELET_COMPGAMMA;Compression gamma +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjusting the gamma of the residual image allow you to equilibrate the data and histogram. +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjust gamma for residual image and compression.\nAllow to equilibrate data and histogram +!TP_WAVELET_COMPTM;Tone mapping +!TP_WAVELET_CONTEDIT;'After' Contrast curve +!TP_WAVELET_CONTEDIT;'After' contrast curve +!TP_WAVELET_CONTRAST_MINUS;Contrast - +!TP_WAVELET_CONTRAST_PLUS;Contrast + +!TP_WAVELET_CONTRA;Contrast +!TP_WAVELET_CONTRA_TOOLTIP;Changes contrast of the residual image. +!TP_WAVELET_CONTR;Gamut +!TP_WAVELET_CTYPE;Chrominance control +!TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modifies local contrast as a function of the original local contrast (absciss)\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 100..300)\n66% absciss represents standard deviation of local contrast (real value about 300..800)\n100% represents maximum (real value about 3000..8000) +!TP_WAVELET_CURVEEDITOR_CH;Contrast levels=f(Hue) +!TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modifies each level's contrast as a function oh hue.\nTake care not to overwrite changes made with the Gamut Hue controls.\nThe curve will only have an effect when wavelet contrast level sliders are non-zero. +!TP_WAVELET_CURVEEDITOR_CL;L +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Applies a final contrast luminance curve at the end of the wavelet treatment. +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Apply a contrast luminance curve at the end of wavelet level threatment +!TP_WAVELET_CURVEEDITOR_HH;HH +!TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modifies the residual image's hue as a function of hue. +!TP_WAVELET_DALL;All directions +!TP_WAVELET_DAUB;Edge performance +!TP_WAVELET_DAUB_TOOLTIP;Changes Daubechies coefficients:\nD4 = Standard,\nD14 = Often best performance, 10% more time-intensive.\n\nAffects edge detection as well as the general quality of the firsts levels. However the quality is not strictly related to this coefficient and can vary with images and uses. +!TP_WAVELET_DISP;Preview Settings +!TP_WAVELET_DONE;Vertical +!TP_WAVELET_DTHR;Diagonal +!TP_WAVELET_DTWO;Horizontal +!TP_WAVELET_EDCU;Curve +!TP_WAVELET_EDGCONT;Local contrast +!TP_WAVELET_EDGCONT_TOOLTIP;Adjusting the points to the left decreases contrast, and to the right increases it.\nBottom-left, Top-Left, Top-Right, Bottom-right represent respectively local contast for low values, mean, mean+stdev, maxima +!TP_WAVELET_EDGEDETECTTHR2;Threshold high (detection) +!TP_WAVELET_EDGEDETECTTHR;Threshold low (noise) +!TP_WAVELET_EDGEDETECTTHR_TOOLTIP;This adjuster lets you target edge detection for example to avoid applying edge sharpness to fine details, such as noise in the sky. +!TP_WAVELET_EDGEDETECT;Gradient sensitivity +!TP_WAVELET_EDGEDETECT_TOOLTIP;Moving the slider to the right increases edge sensitivity. This affects local contrast, edge settings and noise. +!TP_WAVELET_EDGE;Edge Sharpness +!TP_WAVELET_EDGREINF_TOOLTIP;Reinforce or reduce the action of the first level, do the opposite to the second level, and leave the rest unchanged. +!TP_WAVELET_EDGTHRESH;Detail +!TP_WAVELET_EDGTHRESH_TOOLTIP;Change the repartition between the first levels and the others. The higher the threshold the more the action is centred on the first levels. Be careful with negative values, they increase the action of high levels and can introduce artifacts. +!TP_WAVELET_EDRAD;Radius +!TP_WAVELET_EDRAD_TOOLTIP;This radius adjustment is very different from those in other sharpening tools. Its value is compared to each level through a complex function. In this sense, a value of zero still has an effect. +!TP_WAVELET_EDSL;Threshold Sliders +!TP_WAVELET_EDTYPE;Local contrast method +!TP_WAVELET_EDVAL;Strength +!TP_WAVELET_FINAL;Final Touchup +!TP_WAVELET_FINEST;Finest +!TP_WAVELET_HIGHLIGHT;Highlight luminance range +!TP_WAVELET_HS1;Whole luminance range +!TP_WAVELET_HS2;Shadows/Highlights +!TP_WAVELET_HUESKIN;Skin hue +!TP_WAVELET_HUESKIN_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_HUESKY;Sky hue +!TP_WAVELET_HUESKY_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_INF;Below or equal the level +!TP_WAVELET_ITER;Delta balance levels +!TP_WAVELET_ITER_TOOLTIP;Left: increase low levels and reduce high levels,\nRight: reduce low levels and increase high levels. +!TP_WAVELET_LABEL;Wavelet levels +!TP_WAVELET_LARGEST;Coarsest +!TP_WAVELET_LEVCH;Chromaticity +!TP_WAVELET_LEVELS;Wavelet levels +!TP_WAVELET_LEVELS_TOOLTIP;Choose the number of detail levels the image is to be decomposed into. More levels require more RAM and require a longer processing time. +!TP_WAVELET_LEVF;Contrast +!TP_WAVELET_LEVLABEL;Preview maximum possible levels = %1 +!TP_WAVELET_LEVONE;Level 2 +!TP_WAVELET_LEVTWO;Level 3 +!TP_WAVELET_LEVZERO;Level 1 +!TP_WAVELET_LINKEDG;Link with Edge Sharpness' Strength +!TP_WAVELET_LIPST;Enhanced algorithm +!TP_WAVELET_LIPST_TOOLTIP;This algorithm uses Lipschitz regularity to increase edge detection quality at a cost of increased processing time and memory requirements. +!TP_WAVELET_LOWLIGHT;Shadow luminance range +!TP_WAVELET_MEDGREINF;First level +!TP_WAVELET_MEDILEV;Edge detection +!TP_WAVELET_MEDI;Reduce artifacts in blue sky +!TP_WAVELET_NEUTRAL;Neutral +!TP_WAVELET_NOISE;Denoise and Refine +!TP_WAVELET_NOIS;Denoise +!TP_WAVELET_ONE;One level +!TP_WAVELET_OPACITYWL;Final local contrast +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify final local contrast in function of last local contrast (absciss) for all levels decomposition\nTake into account: \na)contrast levels \nb)edge sharpness \nc)contrast balance\nd)decomposition-recomposition\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 200..1000)\n66% absciss represents standard deviation of local contrast (real value about 1000..2000)\n100% represents maximum (real value about 5000..13000) +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify the final local contrast at the end of the wavelet treatment.\n\nThe left side represents the smallest local contrast, progressing to the largest local contrast on the right. +!TP_WAVELET_OPACITYW;Contrast balance d/v-h curve +!TP_WAVELET_OPACITY;Opacity Blue-Yellow +!TP_WAVELET_PASTEL;Pastel chromaticity +!TP_WAVELET_PREVIEWBACK;Background +!TP_WAVELET_PREVIEWLEVELS;Preview +!TP_WAVELET_RE1;Reinforced +!TP_WAVELET_RE2;Unchanged +!TP_WAVELET_RE3;Reduced +!TP_WAVELET_RESCHRO;Chromaticity +!TP_WAVELET_RESCONH;Highlights +!TP_WAVELET_RESCON;Shadows +!TP_WAVELET_RESID;Residual image +!TP_WAVELET_SAT;Saturated chromaticity +!TP_WAVELET_SETTINGS;Wavelet Settings +!TP_WAVELET_SKIN;Skin targetting/protection +!TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected. +!TP_WAVELET_SKY;Sky targetting/protection +!TP_WAVELET_SKY_TOOLTIP;At -100 sky-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 sky-tones are protected while all other tones are affected. +!TP_WAVELET_STRENGTH;Strength +!TP_WAVELET_STREN;Strength +!TP_WAVELET_SUPE;Extra +!TP_WAVELET_SUP;Above the level +!TP_WAVELET_THRESHOLD2;Shadow levels +!TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels between 9 and 9 minus the value will be affected by the shadow luminance range. Other levels will be fully treated. The highest level possible is limited by the highlight level value (9 minus highlight level value). +!TP_WAVELET_THRESHOLD;Highlight levels +!TP_WAVELET_THRESHOLD_TOOLTIP;Only levels beyond the chosen value will be affected by the highlight luminance range. Other levels will be fully treated. The chosen value here limits the highest possible value of the shadow levels. +!TP_WAVELET_THRH;Highlights threshold +!TP_WAVELET_THR;Shadows threshold +!TP_WAVELET_TILESBIG;Big tiles +!TP_WAVELET_TILESFULL;Full image +!TP_WAVELET_TILESIZE;Tiling method +!TP_WAVELET_TILESLIT;Little tiles +!TP_WAVELET_TILES_TOOLTIP;Processing the full image leads to better quality and is the recommended option, while using tiles is a fall-back solution for users with little RAM. Refer to RawPedia for memory requirements. +!TP_WAVELET_TMHIGH;High +!TP_WAVELET_TMLOWHIGH;Low+High +!TP_WAVELET_TMNONE;None +!TP_WAVELET_TMSTD;Standard +!TP_WAVELET_TMSTRENGTH;Compression strength +!TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image. When the value is different from 0, the Strength and Gamma sliders of the Tone Mapping tool in the Exposure tab will become grayed out. +!TP_WAVELET_TMTYPE;Compression method +!TP_WAVELET_TON;Toning +!TP_WAVELET_daub2;D2 - low +!TP_WAVELET_daub4;D4 - standard +!TP_WAVELET_daub6;D6 - standard plus +!TP_WAVELET_daub10;D10 - medium +!TP_WAVELET_daub14;D14 - high +!TP_WBALANCE_AUTO;Auto +!TP_WBALANCE_CAMERA;Camera +!TP_WBALANCE_CLOUDY;Cloudy +!TP_WBALANCE_CUSTOM;Custom +!TP_WBALANCE_DAYLIGHT;Daylight (sunny) +!TP_WBALANCE_EQBLUERED;Blue/Red equalizer +!TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behavior of "white balance" by modulating the blue/red balance.\nThis can be useful when shooting conditions:\na) are far from the standard illuminant (e.g. underwater),\nb) are far from conditions where calibrations were performed,\nc) where the matrices or ICC profiles are unsuitable. +!TP_WBALANCE_FLASH55;Leica +!TP_WBALANCE_FLASH60;Standard, Canon, Pentax, Olympus +!TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta +!TP_WBALANCE_FLASH_HEADER;Flash +!TP_WBALANCE_FLUO1;F1 - Daylight +!TP_WBALANCE_FLUO2;F2 - Cool White +!TP_WBALANCE_FLUO3;F3 - White +!TP_WBALANCE_FLUO4;F4 - Warm White +!TP_WBALANCE_FLUO5;F5 - Daylight +!TP_WBALANCE_FLUO6;F6 - Lite White +!TP_WBALANCE_FLUO7;F7 - D65 Daylight Simulator +!TP_WBALANCE_FLUO8;F8 - D50 / Sylvania F40 Design +!TP_WBALANCE_FLUO9;F9 - Cool White Deluxe +!TP_WBALANCE_FLUO10;F10 - Philips TL85 +!TP_WBALANCE_FLUO11;F11 - Philips TL84 +!TP_WBALANCE_FLUO12;F12 - Philips TL83 +!TP_WBALANCE_FLUO_HEADER;Fluorescent +!TP_WBALANCE_GREEN;Tint +!TP_WBALANCE_GTI;GTI +!TP_WBALANCE_HMI;HMI +!TP_WBALANCE_JUDGEIII;JudgeIII +!TP_WBALANCE_LABEL;White Balance +!TP_WBALANCE_LAMP_HEADER;Lamp +!TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 +!TP_WBALANCE_LED_HEADER;LED +!TP_WBALANCE_LED_LSI;LSI Lumelex 2040 +!TP_WBALANCE_METHOD;Method +!TP_WBALANCE_SHADE;Shade +!TP_WBALANCE_SIZE;Size: +!TP_WBALANCE_SOLUX35;Solux 3500K +!TP_WBALANCE_SOLUX41;Solux 4100K +!TP_WBALANCE_SOLUX47;Solux 4700K (vendor) +!TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) +!TP_WBALANCE_SPOTWB;Spot WB +!TP_WBALANCE_TEMPERATURE;Temperature +!TP_WBALANCE_TUNGSTEN;Tungsten +!TP_WBALANCE_WATER1;UnderWater 1 +!TP_WBALANCE_WATER2;UnderWater 2 +!TP_WBALANCE_WATER_HEADER;UnderWater +!ZOOMPANEL_100;(100%) +!ZOOMPANEL_NEWCROPWINDOW;Open (new) detail window +!ZOOMPANEL_ZOOM100;Zoom to 100%\nShortcut: z +!ZOOMPANEL_ZOOMFITCROPSCREEN;Fit crop to screen\nShortcut: Alt-f +!ZOOMPANEL_ZOOMFITSCREEN;Fit whole image to screen\nShortcut: f +!ZOOMPANEL_ZOOMIN;Zoom In\nShortcut: + +!ZOOMPANEL_ZOOMOUT;Zoom Out\nShortcut: - diff --git a/rtdata/languages/Espanol b/rtdata/languages/Espanol new file mode 100644 index 000000000..fdbb9fea0 --- /dev/null +++ b/rtdata/languages/Espanol @@ -0,0 +1,1915 @@ +#01 Latin America - Spanish +#02 Conventions used to keep the same writing style along new texts and versions +#03 +#04 Abreviaturas (Abbreviations) +#05 ----------------------------- +#06 AC: Aberración cromática (fringe) +#07 B&N: Blanco y Negro (Black & White) +#08 CV: Corrección de Viñeteado (Vignette Filter: in Transform tab) +#09 FG: Filtro Graduado (Gradient Filter) +#10 FV: Filtrar Viñeteado (Vignette Filter: in Exposure tab) +#11 MC: Mezclador de canales (Channel Mixer) +#12 RGB: Modelo de color Rojo Verde Azul (Red Green Blue) +#13 WB: Balance de blancos (White Balance) +#14 +#15 Convención de traducción de términos importantes, +#16 sin equivalente estándar o poco conocidos en español: +#17 --------------------------------------------- +#18 Artifacts: Elementos extraños +#19 Brightness: Brillo +#20 Checkbox: Casilla (seleccionada/desmarcada) +#21 Chroma: Crominancia (**, definida en es.wikipedia) +#22 Chromatic: Cromática (*) +#23 Chromaticity: Cromaticidad (**) +#24 Colorfulness: Colorido +#25 Cyan: Cian (*) +#26 Dark Frame: Toma Negra +#27 Dim: Luz tenue +#28 Feather: Difuminado +#29 Illuminant: Iluminante +#30 Lightness: Claridad +#31 Luminance: Luminancia (*) +#32 Luminosity: Luminosidad +#33 Mapping: Mapeo (*) +#34 Sharpening: Enfoque +#35 Slider: Control deslizante +#36 Tone Curve: Curva tonal +#37 Vibrance: Vibranza +#38 +#39 (*) Término incluido en diccionario RAE +#40 (**) Término no incluido en diccionario RAE +#41 +#42 Términos conservados en Inglés por no tener traducción breve +#43 al español en el sentido usado por RT/fotografía digital +#44 ----------------------------------------------------- +#45 ICM (Image Color Management) +#46 Gamut +#47 Gamma +#48 Raw +#49 +#50 2008-01-15 keenonkites, first translation +#51 2008-03-03 Ioritz Ibarguren, corrections +#52 2008-04-05 keenonkites, completed for 2.4m1 +#53 2008-04-09 Ramon, partly corrected (part of 2.3) +#54 2008-04-29 Ramon, small correction +#55 2008-06-09 Ramon, Adaptions regarding 2.4m1 and others +#56 2008-09-20 keenonkites, first version for 2.4m2 +#57 2008-12-19 keenonkites, first version for 2.4beta4 +#58 2010-12-07 rickydh, some translations of untranslated keys for 3.0 alpha1 +#59 2011-12-25 plores, translation improvement, translation of untranslated strings +#60 2013-01-03 OdeLama, translation for v4.0.12 of untranslated/changed strings +#61 2014-01-14 mapelo, bug correction and small enhancements. +#62 2014-10-10 fotger + +ABOUT_TAB_BUILD;Versión +ABOUT_TAB_CREDITS;Créditos +ABOUT_TAB_LICENSE;Licencia +ABOUT_TAB_RELEASENOTES;Notas de la versión +ABOUT_TAB_SPLASH;Splash +ADJUSTER_RESET_TO_DEFAULT;Restablece los valores predeterminados +BATCHQUEUE_AUTOSTART;Inicio automático +BATCHQUEUE_DESTFILENAME;Ruta y nombre del archivo +BATCH_PROCESSING;Proceso por lotes +CURVEEDITOR_CURVES;Curvas +CURVEEDITOR_CURVE;Curva +CURVEEDITOR_CUSTOM;Personalizado +CURVEEDITOR_DARKS;Oscuros +CURVEEDITOR_HIGHLIGHTS;Luces altas +CURVEEDITOR_LIGHTS;Luces +CURVEEDITOR_LINEAR;Lineal +CURVEEDITOR_LOADDLGLABEL;Cargar curva... +CURVEEDITOR_MINMAXCPOINTS;Puntos de control de mínimo/máximo +CURVEEDITOR_NURBS;Jaula de control +CURVEEDITOR_PARAMETRIC;Paramétrica +CURVEEDITOR_SAVEDLGLABEL;Guardar curva... +CURVEEDITOR_SHADOWS;Sombras +CURVEEDITOR_TOOLTIPCOPY;Copiar curva actual al portapapeles +CURVEEDITOR_TOOLTIPLINEAR;Restablecer la curva a linea recta +CURVEEDITOR_TOOLTIPLOAD;Abrir una curva desde un archivo +CURVEEDITOR_TOOLTIPPASTE;Pegar curva desde el portapapeles +CURVEEDITOR_TOOLTIPSAVE;Guardar curva actual +CURVEEDITOR_TYPE;Tipo: +DIRBROWSER_FOLDERS;Carpetas +EDITWINDOW_TITLE;Edición de imagen +EDIT_OBJECT_TOOLTIP;Muestra un instrumento en la ventana de previo, el cual le permitirá ajustar esta herramienta. +EDIT_PIPETTE_TOOLTIP;Para agregar un punto de ajuste en la curva , mantenga presionada la tecla Ctrl mientras oprime el botón izquierdo del ratón sobre el punto deseado en el previo de la imagen.\nPara ajustar el punto, mantenga presionada la tecla Ctrl mientras oprime el botón izquierdo del ratón sobre la correspondiente area en el previo y muevase hacia arriba y/o hacia abajo, logrando un ajuste fino del punto en la curva. Si desea un ajuste mayor, libere la tecla Ctrl. +EXIFFILTER_APERTURE;Diafragma +EXIFFILTER_CAMERA;Cámara +EXIFFILTER_EXPOSURECOMPENSATION;Compensación de exposición (EV) +EXIFFILTER_FILETYPE;Tipo de archivo +EXIFFILTER_FOCALLEN;Distancia focal +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Lente +EXIFFILTER_METADATAFILTER;Activar filtros de metadatos +EXIFFILTER_SHUTTER;Tiempo de exposición +EXIFPANEL_ADDEDITHINT;Agregar atributo nuevo o cambiar atributo +EXIFPANEL_ADDEDIT;Agregar/Cambiar +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Introducir valor +EXIFPANEL_ADDTAGDLG_SELECTTAG;Seleccionar atributo +EXIFPANEL_ADDTAGDLG_TITLE;Agregar/Cambiar atributo +EXIFPANEL_KEEPHINT;Conserva las etiquetas seleccionadas al escribir el archivo de salida +EXIFPANEL_KEEP;Conservar +EXIFPANEL_REMOVEHINT;Quita las etiquetas seleccionadas al escribir el archivo de salida +EXIFPANEL_REMOVE;Borrar +EXIFPANEL_RESETALLHINT;Restablecer todos los atributos a los valores predeterminados +EXIFPANEL_RESETALL;Restablecer todo +EXIFPANEL_RESETHINT;Restablecer atributos seleccionados a los valores predeterminados +EXIFPANEL_RESET;Restablecer +EXIFPANEL_SUBDIRECTORY;Subcarpeta +EXPORT_BYPASS_ALL;Seleccionar / Deseleccionar todo +EXPORT_BYPASS_DEFRINGE;Saltar Quitar borde púrpura +EXPORT_BYPASS_DIRPYRDENOISE;Saltar Reducción de ruido +EXPORT_BYPASS_DIRPYREQUALIZER;Saltar Contraste por niveles de detalle +EXPORT_BYPASS_RAW_CA;Saltar [raw] Corrección de aberración cromática +EXPORT_BYPASS_RAW_CCSTEPS;Saltar [raw] Supresión de falso color +EXPORT_BYPASS_RAW_DCB_ENHANCE;Saltar [raw] Aplicar pasos de mejora DCB +EXPORT_BYPASS_RAW_DCB_ITERATIONS;Saltar [raw] Iteraciones DCB +EXPORT_BYPASS_RAW_DF;Saltar [raw] Toma Negra +EXPORT_BYPASS_RAW_FF;Saltar [raw] Campo plano +EXPORT_BYPASS_RAW_GREENTHRESH;Saltar [raw] Equilibrado de verdes +EXPORT_BYPASS_RAW_LINENOISE;Saltar [raw] Filtro de ruido de línea +EXPORT_BYPASS_RAW_LMMSE_ITERATIONS;Saltar [raw] Aplicar pasos de mejora LMMSE +EXPORT_BYPASS_SHARPENEDGE;Saltar Enfoque de bordes +EXPORT_BYPASS_SHARPENING;Saltar Enfoque +EXPORT_BYPASS_SHARPENMICRO;Saltar Microcontraste +EXPORT_BYPASS_SH_HQ;Saltar Máscara de Enfoque Sombras/Luces +EXPORT_FASTEXPORTOPTIONS;Opciones de Exportación Rápida +EXPORT_INSTRUCTIONS;Las opciones de Exportación Rápida proporcionan la posibilidad de saltarse pasos de revelado que consumen mucho tiempo y recursos, ejecutando en su lugar el procesamiento de la cola utilizando los ajustes de Exportación Rápida. Se recomienda este método para generar más rápidamente imágenes de menor resolución: cuando la velocidad es prioritaria, o cuando se desea cambiar el tamaño de una o muchas imágenes de salida sin modificar sus parámetros de revelado. +EXPORT_MAXHEIGHT;Altura máxima: +EXPORT_MAXWIDTH;Anchura máxima: +EXPORT_PUTTOQUEUEFAST; Poner en la cola de Exportación Rápida +EXPORT_RAW_DMETHOD;Método de interpolado +EXTPROGTARGET_1;Raw +EXTPROGTARGET_2;procesado en cola +FILEBROWSER_ADDDELTEMPLATE;Añadir/Borrar plantillas... +FILEBROWSER_APPLYPROFILE;Aplicar perfil +FILEBROWSER_APPLYPROFILE_PARTIAL;Aplicar perfil (parcial) +FILEBROWSER_AUTODARKFRAME;Toma Negra automática +FILEBROWSER_AUTOFLATFIELD;Campo plano automático +FILEBROWSER_BROWSEPATHBUTTONHINT;Pulsar para examinar la carpeta seleccionada +FILEBROWSER_BROWSEPATHHINT;Ingrese la ruta a examinar \nCtrl-O poner el foco en campo con la ruta\nEnter / Ctrl-Enter para examinar allí;\nEscPara quitar los cambios.\nShift-Esc Para quitar el foco.\n\n\nAbreviaturas de ruta:\n ~ - Carpeta hogar del usuario\n ! - Carpeta de imágenes del usuario +FILEBROWSER_CACHECLEARFROMFULL;Limpiar del caché - Total +FILEBROWSER_CACHECLEARFROMPARTIAL;Limpiar del caché - Parcial +FILEBROWSER_CACHE;Caché +FILEBROWSER_CLEARPROFILE;Borrar perfil +FILEBROWSER_COLORLABEL_TOOLTIP;Etiquetar con color\n\nUse menú desplegable o atajos de teclado:\nShift-Ctrl-0 No Color\nShift-Ctrl-1 Rojo\nShift-Ctrl-2 Amarillo\nShift-Ctrl-3 Verde\nShift-Ctrl-4 Azul\nShift-Ctrl-5 Púrpura +FILEBROWSER_COPYPROFILE;Copiar perfil +FILEBROWSER_CURRENT_NAME;Nombre actual: +FILEBROWSER_DARKFRAME;Toma Negra +FILEBROWSER_DELETEDLGLABEL;Confirmación de borrar archivos +FILEBROWSER_DELETEDLGMSGINCLPROC;¿Seguro que quiere borrar los %1 archivos seleccionados incluyendo la versión procesada en la cola? +FILEBROWSER_DELETEDLGMSG;¿Seguro que quiere borrar los %1 archivos seleccionados? +FILEBROWSER_EMPTYTRASHHINT;Borrar definitivamente los archivos en la papelera +FILEBROWSER_EMPTYTRASH;Vaciar papelera +FILEBROWSER_EXEC_CPB;Ejecutar generador de perfiles de imagen del usuario +FILEBROWSER_EXTPROGMENU;Abrir con +FILEBROWSER_FLATFIELD;Campo plano +FILEBROWSER_MOVETODARKFDIR;Mover a carpeta de Tomas Negras +FILEBROWSER_MOVETOFLATFIELDDIR;Mover a carpeta de Campo Plano +FILEBROWSER_NEW_NAME;Nuevo nombre: +FILEBROWSER_OPENDEFAULTVIEWER;Ventana predeterminada de visualización (procesada en cola) +FILEBROWSER_PARTIALPASTEPROFILE;Pegar perfil parcialmente +FILEBROWSER_PASTEPROFILE;Pegar perfil +FILEBROWSER_POPUPCANCELJOB;Cancelar trabajo +FILEBROWSER_POPUPCOLORLABEL1;Etiqueta: Rojo +FILEBROWSER_POPUPCOLORLABEL2;Etiqueta: Amarillo +FILEBROWSER_POPUPCOLORLABEL3;Etiqueta: Verde +FILEBROWSER_POPUPCOLORLABEL4;Etiqueta: Azul +FILEBROWSER_POPUPCOLORLABEL5;Etiqueta: Púrpura +FILEBROWSER_POPUPCOLORLABEL;Etiquetar con un color +FILEBROWSER_POPUPCOPYTO;Copiar a... +FILEBROWSER_POPUPFILEOPERATIONS;Operaciones con archivos +FILEBROWSER_POPUPMOVEEND;Mover hacia el final de la cola +FILEBROWSER_POPUPMOVEHEAD;Mover hacia el inicio de la cola +FILEBROWSER_POPUPMOVETO;Mover a... +FILEBROWSER_POPUPOPENINEDITOR;Abrir en Editor +FILEBROWSER_POPUPOPEN;Abrir +FILEBROWSER_POPUPPROCESSFAST;Poner en la cola (exportación rápida) +FILEBROWSER_POPUPPROCESS;Poner en la cola +FILEBROWSER_POPUPPROFILEOPERATIONS;Operaciones con perfiles +FILEBROWSER_POPUPRANK0;Sin Rango +FILEBROWSER_POPUPRANK1;Rango 1 * +FILEBROWSER_POPUPRANK2;Rango 2 ** +FILEBROWSER_POPUPRANK3;Rango 3 *** +FILEBROWSER_POPUPRANK4;Rango 4 **** +FILEBROWSER_POPUPRANK5;Rango 5 ***** +FILEBROWSER_POPUPRANK;Asignar rango +FILEBROWSER_POPUPREMOVEINCLPROC;Borrar con salida de la cola +FILEBROWSER_POPUPREMOVE;Borrar +FILEBROWSER_POPUPRENAME;Renombrar +FILEBROWSER_POPUPSELECTALL;Seleccionar todo +FILEBROWSER_POPUPTRASH;Mover a la papelera +FILEBROWSER_POPUPUNRANK;Quitar valoración +FILEBROWSER_POPUPUNTRASH;Sacar de la papelera +FILEBROWSER_QUERYBUTTONHINT;Borrar la búsqueda +FILEBROWSER_QUERYHINT;Escriba parte del nombre del archivo a buscar, o una lista separada con comas.\nP.ej. 1001,1004,1199\n\nCtrl-F Para poner el foco en el campo Buscar.\nEnter Para iniciar la búsqueda.\nEsc Para limpiar.\nShift-Esc Para quitar el foco. +FILEBROWSER_QUERYLABEL; Buscar: +FILEBROWSER_RANK1_TOOLTIP;Rango 1 *\nAtajoShift-1 +FILEBROWSER_RANK2_TOOLTIP;Rango 2 **\nAtajoShift-2 +FILEBROWSER_RANK3_TOOLTIP;Rango 3 ***\nAtajoShift-3 +FILEBROWSER_RANK4_TOOLTIP;Rango 4 ****\nAtajoShift-4 +FILEBROWSER_RANK5_TOOLTIP;Rango 5 *****\nAtajoShift-5 +FILEBROWSER_RENAMEDLGLABEL;Renombrar archivo +FILEBROWSER_RENAMEDLGMSG;Renombrar archivo "%1"a: +FILEBROWSER_SELECTDARKFRAME;Seleccionar Toma Negra… +FILEBROWSER_SELECTFLATFIELD;Seleccionar Campo Plano… +FILEBROWSER_SHOWCOLORLABEL1HINT;Mostrar imágenes etiquetadas con Rojo Alt-1 +FILEBROWSER_SHOWCOLORLABEL2HINT;Mostrar imágenes etiquetadas con Amarillo Alt-2 +FILEBROWSER_SHOWCOLORLABEL3HINT;Mostrar imágenes etiquetadas con Verde Alt-3 +FILEBROWSER_SHOWCOLORLABEL4HINT;Mostrar imágenes etiquetadas con Azul Alt-4 +FILEBROWSER_SHOWCOLORLABEL5HINT;Mostrar imágenes etiquetadas con Púrpura Alt-5 +FILEBROWSER_SHOWDIRHINT;Quitar todos los filtros.\nAtajo: d +FILEBROWSER_SHOWEDITEDHINT;Mostrar imágenes editadas.\nAtajo: 7 +FILEBROWSER_SHOWEDITEDNOTHINT;Mostrar imágenes no editadas.\nAtajo: 6 +FILEBROWSER_SHOWEXIFINFO;Mostrar datos Exif.\nAtajo: i\n\nAtajo en modo editor simple: Alt-I +FILEBROWSER_SHOWRANK1HINT;Mostrar imágenes con 1 estrella.\nAtajo: 1 +FILEBROWSER_SHOWRANK2HINT;Mostrar imágenes con 2 estrellas.\nAtajo: 2 +FILEBROWSER_SHOWRANK3HINT;Mostrar imágenes con 3 estrellas.\nAtajo: 3 +FILEBROWSER_SHOWRANK4HINT;Mostrar imágenes con 4 estrellas.\nAtajo: 4 +FILEBROWSER_SHOWRANK5HINT;Mostrar imágenes con 5 estrellas.\nAtajo: 5 +FILEBROWSER_SHOWRECENTLYSAVEDHINT;Mostrar imágenes guardadas recientemente.\nAtajo: Alt-7 +FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Mostrar imágenes no guardadas recientemente.\nAtajo: Alt-6 +FILEBROWSER_SHOWTRASHHINT;Mostrar el contenido de la papelera.\nAtajo: Ctrl-t +FILEBROWSER_SHOWUNCOLORHINT;Mostrar imágenes sin etiqueta de color.\nAtajo: Alt-0 +FILEBROWSER_SHOWUNRANKHINT;Mostrar imágenes sin rango.\nAtajo: 0 +FILEBROWSER_STARTPROCESSINGHINT;Iniciar el procesamiento de imágenes en la cola +FILEBROWSER_STARTPROCESSING;Iniciar procesamiento +FILEBROWSER_STOPPROCESSINGHINT;Parar el procesamiento de imágenes en la cola +FILEBROWSER_STOPPROCESSING;Parar procesamiento +FILEBROWSER_THUMBSIZE;Tamaño miniatura +FILEBROWSER_TOOLTIP_STOPPROCESSING;Iniciar automáticamente el procesamiento en cuanto llega un nuevo trabajo +FILEBROWSER_UNRANK_TOOLTIP;Sin Rango\nAtajoShift - 0 +FILEBROWSER_ZOOMINHINT;Agrandar miniatura.\nAtajo: +\n\nAtajo en modo editor simple: Alt-+ +FILEBROWSER_ZOOMOUTHINT;Reducir miniatura.\nAtajo: -\n\nAtajo en modo editor simple: Alt-- +GENERAL_ABOUT;Acerca de +GENERAL_AFTER;Después +GENERAL_AUTO;Automático +GENERAL_BEFORE;Antes +GENERAL_CANCEL;Cancelar +GENERAL_CLOSE;Cerrar +GENERAL_DISABLED;Desactivado +GENERAL_DISABLE;Desactivar +GENERAL_ENABLED;Activado +GENERAL_ENABLE;Activar +GENERAL_FILE;Archivo +GENERAL_LANDSCAPE;Paisaje +GENERAL_NA;n/a +GENERAL_NONE;Ninguno +GENERAL_NO;No +GENERAL_OK;Aceptar +GENERAL_PORTRAIT;Retrato +GENERAL_SAVE;Guardar +GENERAL_UNCHANGED;(Sin cambios) +GENERAL_WARNING;Advertencia +HISTOGRAM_TOOLTIP_BAR;Mostrar/Ocultar barra indicadora RGB\nHacer clic con el botón derecho del ratón en la previsualización para congelar/descongelar +HISTOGRAM_TOOLTIP_B;Mostrar/Ocultar Histograma Azul +HISTOGRAM_TOOLTIP_CHRO;Mostrar/Ocultar Histograma de cromaticidad +HISTOGRAM_TOOLTIP_FULL;Cambiar entre Histograma completo o escalado +HISTOGRAM_TOOLTIP_G;Mostrar/Ocultar Histograma Verde +HISTOGRAM_TOOLTIP_L;Mostrar/Ocultar Histograma de Luminancia CIELAB +HISTOGRAM_TOOLTIP_RAW;Mostrar/ocultar Histograma Raw +HISTOGRAM_TOOLTIP_R;Mostrar/Ocultar Histograma Rojo +HISTORY_CHANGED;Cambiado +HISTORY_CUSTOMCURVE;Curva a medida +HISTORY_DELSNAPSHOT;Quitar instantánea +HISTORY_FROMCLIPBOARD;Desde el portapapeles +HISTORY_LABEL;Historial +HISTORY_MSG_1;Foto abierta +HISTORY_MSG_2;Perfil Abierto +HISTORY_MSG_3;Perfil cambiado +HISTORY_MSG_4;Búsqueda de historial +HISTORY_MSG_5;Brillo +HISTORY_MSG_6;Contraste +HISTORY_MSG_7;Negro +HISTORY_MSG_8;Compensación de exposición +HISTORY_MSG_9;Compresión de luces altas +HISTORY_MSG_10;Compresión de sombras +HISTORY_MSG_11;Curva tonal 1 +HISTORY_MSG_12;Exposición automática +HISTORY_MSG_13;Recorte de exposición +HISTORY_MSG_14;Lab - Claridad +HISTORY_MSG_15;Lab - Contraste +HISTORY_MSG_16;Luminancia - Negro +HISTORY_MSG_17;Luminancia - Compr. de luces altas +HISTORY_MSG_18;Luminancia - Compr. de sombras +HISTORY_MSG_19;Curva 'L' +HISTORY_MSG_20;Enfoque +HISTORY_MSG_21;Enfoque - Radio +HISTORY_MSG_22;Enfoque - Cantidad +HISTORY_MSG_23;Enfoque - Umbral +HISTORY_MSG_24;Enfoque - Sólo bordes +HISTORY_MSG_25;Enfoque - Radio de detección de bordes +HISTORY_MSG_26;Enfoque - Tolerancia de bordes +HISTORY_MSG_27;Enfoque - Control de halo +HISTORY_MSG_28;Enfoque - Cantidad de Control de Halo +HISTORY_MSG_29;Método de Enfoque +HISTORY_MSG_30;Deconvolución - Radio +HISTORY_MSG_31;Deconvolución - Cantidad +HISTORY_MSG_32;Deconvolución - Amortiguación +HISTORY_MSG_33;Deconvolución - Iteraciones +HISTORY_MSG_34;LCP - Corrección de distorsión +HISTORY_MSG_35;LCP - Corrección de Viñeta +HISTORY_MSG_36;LCP - Corrección Aberr.Crom. +HISTORY_MSG_37;Niveles automáticos +HISTORY_MSG_38;Método de Balance de Blancos +HISTORY_MSG_39;Temperatura de color +HISTORY_MSG_40;Equilibrio de Blancos - Tinte +HISTORY_MSG_41;Curva tonal modo 1 +HISTORY_MSG_42;Curva tonal 2 +HISTORY_MSG_43;Curva tonal modo 2 +HISTORY_MSG_44;Red. ruido de lum. - Radio +HISTORY_MSG_45;Red. ruido de lum. - Tolerancia de Bordes +HISTORY_MSG_46;Red. ruido de color +HISTORY_MSG_47;Mezcla luces altas ICC con matriz +HISTORY_MSG_48;Usar curva de tono DCP +HISTORY_MSG_49;Iluminante DCP +HISTORY_MSG_50;Sombras/Luces altas (S/LA) +HISTORY_MSG_51;S/LA - Luces altas +HISTORY_MSG_52;S/LA - Sombras +HISTORY_MSG_53;S/LA - Ancho tonal Luces Altas +HISTORY_MSG_54;S/LA - Ancho tonal Sombras +HISTORY_MSG_55;S/LA - Contraste local +HISTORY_MSG_56;S/LA - Radio +HISTORY_MSG_57;Rotación basta +HISTORY_MSG_58;Volteo horizontal +HISTORY_MSG_59;Volteo vertical +HISTORY_MSG_60;Rotación +HISTORY_MSG_61;Rellenado automático +HISTORY_MSG_62;Corrección de distorsión +HISTORY_MSG_63;Marcador seleccionado +HISTORY_MSG_64;Recortar foto +HISTORY_MSG_65;Corrección aberraciones cromáticas +HISTORY_MSG_66;Recuperación de luces altas +HISTORY_MSG_67;Recuperación de luces altas - Cantidad +HISTORY_MSG_68;Recuperación de luces altas - Método +HISTORY_MSG_69;Espacio de color de trabajo +HISTORY_MSG_70;Espacio de color de salida +HISTORY_MSG_71;Espacio de color de entrada +HISTORY_MSG_72;Corrección de viñeteo +HISTORY_MSG_73;Mezclador de canal +HISTORY_MSG_74;Cambiar tamaño - Escala +HISTORY_MSG_75;Cambiar tamaño - Método +HISTORY_MSG_76;Metadatos de Exif +HISTORY_MSG_77;Metadatos de IPTC +HISTORY_MSG_78;Datos especificados para cambio tamaño +HISTORY_MSG_79;Cambiar tamaño - Anchura +HISTORY_MSG_80;Cambiar tamaño - Altura +HISTORY_MSG_81;Cambio tamaño activado +HISTORY_MSG_82;Perfil cambiado +HISTORY_MSG_83;Sombras/Luces Altas - Enfoque +HISTORY_MSG_84;Corrección de perspectiva +HISTORY_MSG_85;Perfil Corrector de Lente +HISTORY_MSG_86;Curvas RGB - Modo luminosidad +HISTORY_MSG_87;Impulsar Reducción de Ruido +HISTORY_MSG_88;Impulsar RR - Umbral +HISTORY_MSG_89;Reducción de ruido (RR) +HISTORY_MSG_90;RR - Luminancia +HISTORY_MSG_91;RR - Crominancia Maestra +HISTORY_MSG_92;RR - Gamma +HISTORY_MSG_93;Contraste/niveles de detalle - Valor +HISTORY_MSG_94;Contraste por niveles de detalle +HISTORY_MSG_95;Lab - Cromaticidad +HISTORY_MSG_96;Curva 'a' +HISTORY_MSG_97;Curva 'b' +HISTORY_MSG_98;Método de Interpolación +HISTORY_MSG_99;Filtra píxel muerto/caliente +HISTORY_MSG_100;Saturación +HISTORY_MSG_101;Ecualizador HSV - Matiz +HISTORY_MSG_102;Ecualizador HSV - Saturación +HISTORY_MSG_103;Ecualizador HSV - Valor +HISTORY_MSG_104;Ecualizador HSV +HISTORY_MSG_105;Quitar borde púrpura +HISTORY_MSG_106;Quitar borde púrpura - Radio +HISTORY_MSG_107;Quitar borde púrpura - Umbral +HISTORY_MSG_108;Umbral de compres. de luces altas +HISTORY_MSG_109;Tamaño del rectángulo limitador +HISTORY_MSG_110;Cambio de tamaño aplica a +HISTORY_MSG_111;Lab - Evita deriva de color +HISTORY_MSG_112;--Sin Uso-- +HISTORY_MSG_113;Lab - Protección +HISTORY_MSG_114;Iteraciones DCB +HISTORY_MSG_115;Supresión de color falso +HISTORY_MSG_116;DCB mejorado +HISTORY_MSG_117;Corrección AC - Rojo +HISTORY_MSG_118;Corrección AC - Azul +HISTORY_MSG_119;Filtro de ruido de línea +HISTORY_MSG_120;Equilibrado de verde +HISTORY_MSG_121;Corrección automática AC +HISTORY_MSG_122;Auto selección de arch. de Toma Negra +HISTORY_MSG_123;Archivo de Toma Negra +HISTORY_MSG_124;Corrección de punto blanco +HISTORY_MSG_125;Preservar Luces Altas +HISTORY_MSG_126;Archivo de campo plano +HISTORY_MSG_127;Auto selección archivo de campo plano +HISTORY_MSG_128;Radio de difuminado de campo plano +HISTORY_MSG_129;Tipo de difuminado de campo plano +HISTORY_MSG_130;Corrección automática de distorsión +HISTORY_MSG_131;Reducción de ruido de luminancia +HISTORY_MSG_132;Reducción de ruido de crominancia +HISTORY_MSG_133;Gamma de salida +HISTORY_MSG_134;Gamma libre +HISTORY_MSG_135;Gamma libre +HISTORY_MSG_136;Pendiente de gamma +HISTORY_MSG_137;Nivel de negro - Verde 1 +HISTORY_MSG_138;Nivel de negro - Rojo +HISTORY_MSG_139;Nivel de negro - Azul +HISTORY_MSG_140;Nivel de negro - Verde 2 +HISTORY_MSG_141;Nivel de negro - Vincular verdes +HISTORY_MSG_142;Claridad - Pasos +HISTORY_MSG_143;Claridad - Intensidad de gradiente +HISTORY_MSG_144;Micro-contraste - Cantidad +HISTORY_MSG_145;Micro-contraste - Uniformidad +HISTORY_MSG_146;Enfoque de bordes (EB) +HISTORY_MSG_147;EB - Sólo luminancia +HISTORY_MSG_148;Micro-contraste +HISTORY_MSG_149;Micro-contraste - matriz 3x3 +HISTORY_MSG_150;Reducción artefactos/ruido post interpolado +HISTORY_MSG_151;Vibranza (Vib) +HISTORY_MSG_152;Vib - Tonos pastel +HISTORY_MSG_153;Vib - Tonos saturados +HISTORY_MSG_154;Vib - Proteger tonos piel +HISTORY_MSG_155;Vib - Evitar deriva de color +HISTORY_MSG_156;Vib - Enlazar tonos pastel y saturados +HISTORY_MSG_157;Vib - Umbral pastel/saturado +HISTORY_MSG_158;MT - Intensidad +HISTORY_MSG_159;MT - Parada en los bordes +HISTORY_MSG_160;MT - Escala +HISTORY_MSG_161;MT - Iteraciones de reponderación +HISTORY_MSG_162;Mapeo tonal (MT) +HISTORY_MSG_163;Curvas RGB - Rojo +HISTORY_MSG_164;Curvas RGB - Verde +HISTORY_MSG_165;Curvas RGB - Azul +HISTORY_MSG_166;Niveles neutros +HISTORY_MSG_167;-No se usa-- +HISTORY_MSG_168;Curva 'CC' +HISTORY_MSG_169;Curva 'CM' +HISTORY_MSG_170;Vib - Curva +HISTORY_MSG_171;Curva 'LC' +HISTORY_MSG_172;Lab - Restringe 'LC' +HISTORY_MSG_173;RR - Detalle en luminancia +HISTORY_MSG_174;CIECAM02 +HISTORY_MSG_175;CAM02 - Adaptación CAT02 +HISTORY_MSG_176;CAM02 - Entorno de visualización +HISTORY_MSG_177;CAM02 - Luminosidad de escena +HISTORY_MSG_178;CAM02 - Luz de visualización +HISTORY_MSG_179;CAM02 - Modelo de punto blanco +HISTORY_MSG_180;CAM02 - Claridad (J) +HISTORY_MSG_181;CAM02 - Crominancia (C) +HISTORY_MSG_182;CAM02 - CAT02 Automático +HISTORY_MSG_183;CAM02 - Contraste (J) +HISTORY_MSG_184;CAM02 - Alrededor de escena +HISTORY_MSG_185;CAM02 - Control de Gamut +HISTORY_MSG_186;CAM02 - Algoritmo +HISTORY_MSG_187;CAM02 - Proteje tonos rojos & piel +HISTORY_MSG_188;CAM02 - Brillo(Q) +HISTORY_MSG_189;CAM02 - Contraste (Q) +HISTORY_MSG_190;CAM02 - Saturación (S) +HISTORY_MSG_191;CAM02 - Colorido (M) +HISTORY_MSG_192;CAM02 - Matiz (ángulo) +HISTORY_MSG_193;CAM02 - Curva tonal 1 +HISTORY_MSG_194;CAM02 - Curva tonal 2 +HISTORY_MSG_195;CAM02 - Curva tonal 1 +HISTORY_MSG_196;CAM02 - Curva tonal 2 +HISTORY_MSG_197;CAM02 - Curva de Color +HISTORY_MSG_198;CAM02 - Curva de Color +HISTORY_MSG_199;CAM02 - Histogramas de salida +HISTORY_MSG_200;CAMO2 - Mapeo tonal +HISTORY_MSG_201;RR - Crominancia Ro,Ve +HISTORY_MSG_202;RR - Crominancia Az,Am +HISTORY_MSG_203;RR - Método +HISTORY_MSG_204;Pasos de mejora LMMSE +HISTORY_MSG_205;CAM02 - Píxel caliente/muerto +HISTORY_MSG_206;CAT02 - Luz de escena auto. +HISTORY_MSG_207;Elimina AC - Matices +HISTORY_MSG_208;WB - Ecualizador Az-Ro +HISTORY_MSG_210;FG - Ángulo +HISTORY_MSG_211;Filtro de Gradiente (FG) +HISTORY_MSG_212;FV - Intensidad +HISTORY_MSG_213;Filtro quitar Viñeteado +HISTORY_MSG_214;Blanco y Negro +HISTORY_MSG_215;B&N - MC - Rojo +HISTORY_MSG_216;B&N - MC - Verde +HISTORY_MSG_217;B&N - MC - Azul +HISTORY_MSG_218;B&N - Gamma - Rojo +HISTORY_MSG_219;B&N - Gamma - Verde +HISTORY_MSG_220;B&N - Gamma - Azul +HISTORY_MSG_221;B&N - Filtro de color +HISTORY_MSG_222;B&N - Preestablecidos +HISTORY_MSG_223;B&N - MC - Naranja +HISTORY_MSG_224;B&N - MC - Amarillo +HISTORY_MSG_225;B&N - MC - Cian +HISTORY_MSG_226;B&N - MC - Magenta +HISTORY_MSG_227;B&N - MC - Púrpura +HISTORY_MSG_228;B&N - Ecualiza Luminancia +HISTORY_MSG_229;B&N - Ecualiza Luminancia +HISTORY_MSG_230;B&N - Modo +HISTORY_MSG_231;B&N - Curva 'Antes' +HISTORY_MSG_232;B&N - Tipo de curva 'Antes' +HISTORY_MSG_233;B&N - Curva 'Después' +HISTORY_MSG_234;B&N - Tipo de curva 'Después' +HISTORY_MSG_235;B&N - Mezcla canales Auto. +HISTORY_MSG_236;--Sin uso-- +HISTORY_MSG_237;B&N - Mezclador +HISTORY_MSG_238;FG - Difuminado +HISTORY_MSG_239;FG - Intensidad +HISTORY_MSG_240;FG - Centro +HISTORY_MSG_241;FV - Difuminado +HISTORY_MSG_242;FV - Redondez +HISTORY_MSG_243;CV - Radio +HISTORY_MSG_244;CV - Intensidad +HISTORY_MSG_245;CV - Centro +HISTORY_MSG_246;Curva 'CL' +HISTORY_MSG_247;Curva 'LM' +HISTORY_MSG_248;Curva 'MM' +HISTORY_MSG_249;CpND - Umbral +HISTORY_MSG_250;RR - Mejorado +HISTORY_MSG_251;B&N - Algoritmo +HISTORY_MSG_252;CbDL - Tono de piel +HISTORY_MSG_253;CbDL - Reducir elementos extraños +HISTORY_MSG_254;CbDL - Matiz de piel +HISTORY_MSG_255;RR - Filtro Median +HISTORY_MSG_256;RR - Tipo Median +HISTORY_MSG_257;Tonificación de Color +HISTORY_MSG_258;TC - Color +HISTORY_MSG_259;TC - Opacidad +HISTORY_MSG_260;TC - Opacidad'a[b]' +HISTORY_MSG_261;TC - Método +HISTORY_MSG_262;TC - Opacidad 'b' +HISTORY_MSG_263;TC - Sombras - Rojo +HISTORY_MSG_264;TC - Sombras - Verde +HISTORY_MSG_265;TC - Sombras - Azul +HISTORY_MSG_266;TC - Tonos Medios - Rojo +HISTORY_MSG_267;TC - Tonos Medios - Verde +HISTORY_MSG_268;TC - Tonos Medios - Azul +HISTORY_MSG_269;TC - Altas Luces - Rojo +HISTORY_MSG_270;TC - Altas Luces - Verde +HISTORY_MSG_271;TC - Altas Luces - Azul +HISTORY_MSG_272;TC - Balance +HISTORY_MSG_273;TC - Restablecer +HISTORY_MSG_274;TC - Sat. de Sombras +HISTORY_MSG_275;TC - Sat. de Altas Luces +HISTORY_MSG_276;TC - Opacidad +HISTORY_MSG_277;--no utilizado-- +HISTORY_MSG_278;TC - Preservar luminancia +HISTORY_MSG_279;TC - Sombras +HISTORY_MSG_280;TC - Altas Luces +HISTORY_MSG_281;TC - Intensidad de Saturación +HISTORY_MSG_282;TC - Umbral de Saturación +HISTORY_MSG_283;TC - Intensidad +HISTORY_MSG_284;TC - Autoprotección de Saturación +HISTORY_MSG_285;RR - Median - Método +HISTORY_MSG_286;RR - Median - Tipo +HISTORY_MSG_287;RR - Median - Iteracciones +HISTORY_MSG_288;Campo Plano - Control de recorte +HISTORY_MSG_289;Campo Plano - Control de recorte - Automático +HISTORY_MSG_290;Nivel de Negro - Rojo +HISTORY_MSG_291;Nivel de Negro - Verde +HISTORY_MSG_292;Nivel de Negro - Azul +HISTORY_MSG_293;Simulación de Fílmico +HISTORY_MSG_294;Simulación de Fílmico - Intensidad +HISTORY_MSG_295;Simulación de Fílmico - Filme +HISTORY_MSG_296;RR - Modular luminancia +HISTORY_MSG_297;RR - Calidad +HISTORY_MSG_298;Filtro Pixel Muerto +HISTORY_NEWSNAPSHOT;Agregar +HISTORY_NEWSNAPSHOT_TOOLTIP;Atajo: Alt-s +HISTORY_SNAPSHOTS;Instantáneas +HISTORY_SNAPSHOT;Instantánea +IPTCPANEL_AUTHORSPOSITIONHINT;Título o cargo del creador o de los creadores del objeto. +IPTCPANEL_AUTHORSPOSITION;Tratamiento o título del autor +IPTCPANEL_AUTHOR;Autor +IPTCPANEL_CAPTIONHINT;Descripción textual de la información (Leyenda). +IPTCPANEL_CAPTIONWRITERHINT;Nombre de la persona que escribió, modificó o corrigió la imagen o leyenda/resumen. +IPTCPANEL_CAPTIONWRITER;Autor de la leyenda +IPTCPANEL_CAPTION;Leyenda +IPTCPANEL_CATEGORYHINT;Identificador del tema de la imagen según el proveedor (Categoría). +IPTCPANEL_CATEGORY;Categoría +IPTCPANEL_CITYHINT;Ciudad Origen de la imagen. +IPTCPANEL_CITY;Ciudad +IPTCPANEL_COPYHINT;Copiar ajustes IPTC al portapapeles +IPTCPANEL_COPYRIGHTHINT;Cualquier aviso/nota necesario sobre los derechos de autor. +IPTCPANEL_COPYRIGHT;Derechos de autor +IPTCPANEL_COUNTRYHINT;Nombre de la Ciudad/Locación principal donde la imagen fue creada. +IPTCPANEL_COUNTRY;País +IPTCPANEL_CREDITHINT;Identifica el proveedor de la imagen, que no necesariamente el dueño o creador. +IPTCPANEL_CREDIT;Créditos +IPTCPANEL_DATECREATEDHINT;Fecha de creación del contenido intelectual de la imagen; Formato: AAAAMMDD. +IPTCPANEL_DATECREATED;Fecha de creación +IPTCPANEL_EMBEDDEDHINT;Restablecer a los datos IPTC incrustados en el archivo de la imagen +IPTCPANEL_EMBEDDED;Incrustado +IPTCPANEL_HEADLINEHINT;Una anotación publicable que provee una sinopsis de los contenidos de la imagen. +IPTCPANEL_HEADLINE;Encabezado +IPTCPANEL_INSTRUCTIONSHINT;Otras instrucciones editoriales sobre el uso de la imagen (Términos de uso). +IPTCPANEL_INSTRUCTIONS;Instrucciones +IPTCPANEL_KEYWORDSHINT;Palabras clave que facilitan la búsqueda de la imagen. +IPTCPANEL_KEYWORDS;Palabras clave +IPTCPANEL_PASTEHINT;Pegar ajustes IPTC desde el portapapeles +IPTCPANEL_PROVINCEHINT;Origen de la imagen: Estado/Provincia (Province-State). +IPTCPANEL_PROVINCE;Estado/Provincia +IPTCPANEL_RESETHINT;Restablecer a los ajustes predeterminados del perfil. +IPTCPANEL_RESET;Restablecer +IPTCPANEL_SOURCEHINT;Propietario original del contenido intelectual de la imagen (Source). +IPTCPANEL_SOURCE;Fuente +IPTCPANEL_SUPPCATEGORIESHINT;Datos adicionales del tema de la imagen. +IPTCPANEL_SUPPCATEGORIES;Categorías suplementarias +IPTCPANEL_TITLEHINT;Descripción breve de la imagen. +IPTCPANEL_TITLE;Título +IPTCPANEL_TRANSREFERENCEHINT;Código representando el lugar de la transmisión original. +IPTCPANEL_TRANSREFERENCE;Ref. Transm. original +MAIN_BUTTON_FULLSCREEN;Pantalla completa +MAIN_BUTTON_NAVNEXT_TOOLTIP;Navegar hasta la imagen Siguiente a la que está abierta en el editor:\nShift-F4\n\nPara navegar hasta la imagen Siguiente a aquella cuya miniatura está seleccionada en el Explorador de Archivos:\nF4 +MAIN_BUTTON_NAVPREV_TOOLTIP;Navegar hasta la imagen Anterior a la que está abierta en el editor:\nShift-F3\n\nPara navegar hasta la imagen Anterior a aquella cuya miniatura está seleccionada en el Explorador de Archivos:\nF3 +MAIN_BUTTON_NAVSYNC_TOOLTIP;Sincronizar el Navegador de Archivos con el Editor para mostrar la miniatura de la imagen actualmente abierta y quitar los filtros en el Navegador de Archivos:\nx\n\nPara hacer lo dicho anteriormente, pero sin quitar los filtros en el Navegador de Archivos:\ny\n(Note que la miniatura del archivo abierto no será mostrada si los filtros la excluyen). +MAIN_BUTTON_PREFERENCES;Preferencias +MAIN_BUTTON_PUTTOQUEUE;Poner en la cola +MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Añadir imagen actual a la cola de procesamiento.\nAtajo: Ctrl+B +MAIN_BUTTON_SAVE;Guardar imagen +MAIN_BUTTON_SAVE_TOOLTIP;Guardar imagen actual.\nAtajo: Ctrl+S +MAIN_BUTTON_SENDTOEDITOR;Abrir con editor +MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Editar imagen actual en editor externo.\nAtajo: Ctrl+E +MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Mostrar/ocultar todos los paneles laterales.\nAtajo: m +MAIN_BUTTON_UNFULLSCREEN;Salir de Pantalla completa +MAIN_FRAME_BATCHQUEUE;Cola de lotes +MAIN_FRAME_BATCHQUEUE_TOOLTIP; Cola de lotes.\nAtajo: Ctrl-F3 +MAIN_FRAME_EDITOR;Editor +MAIN_FRAME_EDITOR_TOOLTIP; Editor.\nAtajo: Ctrl-F4 +MAIN_FRAME_FILEBROWSER;Explorador de archivos +MAIN_FRAME_FILEBROWSER_TOOLTIP; Explorador de archivos.\nAtajo: Ctrl-F2 +MAIN_FRAME_PLACES;Ubicaciones +MAIN_FRAME_PLACES_ADD;Añadir +MAIN_FRAME_PLACES_DEL;Borrar +MAIN_FRAME_RECENT;Carpetas recientes +MAIN_MSG_ALREADYEXISTS;Este archivo ya existe. +MAIN_MSG_CANNOTLOAD;No se puede abrir imagen +MAIN_MSG_CANNOTSAVE;Error al guardar archivo +MAIN_MSG_CANNOTSTARTEDITOR;Problema abriendo editor. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Por favor ajuste la ruta correcta en las "Preferencias". +MAIN_MSG_EMPTYFILENAME;Nombre de archivo no especificado +MAIN_MSG_IMAGEUNPROCESSED;Este comando requiere primero que todas las imágenes seleccionadas sean procesadas en cola. +MAIN_MSG_NAVIGATOR;Navegador +MAIN_MSG_OPERATIONCANCELLED;Operación cancelada +MAIN_MSG_PATHDOESNTEXIST;La ruta\n\n%1\n\nno existe. Por favor, establezca una ruta correcta en la ventana de Preferencias. +MAIN_MSG_QOVERWRITE;¿Quiere sobre-escribirlo? +MAIN_MSG_SETPATHFIRST;Para poder usar esta función, primero tiene que establecer una \nruta objetivo en la ventana de Preferencias! +MAIN_MSG_WRITEFAILED;Falla al escribir\n\n"%1"\n\nAsegurese de que el folder exista y que usted tenga permiso de escritura sobre él. +MAIN_TAB_COLOR;Color +MAIN_TAB_COLOR_TOOLTIP;Atajo: Alt-C +MAIN_TAB_DETAIL;Detalle +MAIN_TAB_DETAIL_TOOLTIP;Atajo: Alt-D +MAIN_TAB_DEVELOP;Revelar +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPORT; Exportación Rápida +MAIN_TAB_EXPOSURE;Exposición +MAIN_TAB_EXPOSURE_TOOLTIP;Atajo: Alt-E +MAIN_TAB_FILTER;Filtro +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadatos +MAIN_TAB_METADATA_TOOLTIP;Atajo: Alt-M +MAIN_TAB_RAW;Raw +MAIN_TAB_RAW_TOOLTIP;Atajo: Alt-R +MAIN_TAB_TRANSFORM;Transformar +MAIN_TAB_TRANSFORM_TOOLTIP;Atajo: Alt-T +MAIN_TOOLTIP_BACKCOLOR0;Color de fondo de la previsualización: Color del tema\nAtajo: 8 +MAIN_TOOLTIP_BACKCOLOR1;Color de fondo de la previsualización: Negro\nAtajo: 9 +MAIN_TOOLTIP_BACKCOLOR2;Color de fondo de la previsualización: Blanco\nAtajo: 0 +MAIN_TOOLTIP_BEFOREAFTERLOCK;Bloquear / Desbloquear la vista Antes\n\nBloquear: la vista Antes permanece inalterada - \nútil para evaluar el efecto acumulativo de varias herramientas.\nAdemás, se puede hacer una comparación con cualquier estado en el Historial\n\nDesbloquear: la vista Antes seguirá a la vista Después un paso por detrás, mostrando la imagen antes del efecto de la herramienta que se está usando +MAIN_TOOLTIP_HIDEHP;Mostrar/Ocultar panel izquierdo (incluyendo historial).\nAtajo: i +MAIN_TOOLTIP_INDCLIPPEDH;Indicación de luces altas recortadas.\nAtajo: < +MAIN_TOOLTIP_INDCLIPPEDS;Indicación de sombras recortadas.\nAtajo: > +MAIN_TOOLTIP_PREVIEWB;Previsualización Canal azul.\nAtajo: b +MAIN_TOOLTIP_PREVIEWFOCUSMASK;Previsualización Máscara de Foco.\nAtajo: Shift-F\n\nMás preciso en imágenes con poca profundidad de campo, bajo ruido y a mayores niveles de aumento\n\nPara mejorar la precisión en imágenes con ruido evalúe usando menor aumento (10%-30%)\n\nPreview es realizada más lentamente cuando la Máscara de Foco esta activa. +MAIN_TOOLTIP_PREVIEWG;Previsualización Canal verde.\nAtajo: g +MAIN_TOOLTIP_PREVIEWL;Previsualización Luminosidad.\nAtajo: v\n\n0.299*R + 0.587*G + 0.114*B +MAIN_TOOLTIP_PREVIEWR;Previsualización Canal rojo.\nAtajo: r +MAIN_TOOLTIP_QINFO; Información breve de la imagen.\nAtajo: i +MAIN_TOOLTIP_SHOWHIDELP1;Mostrar/ocultar el panel izquierdo.\nAtajo: l +MAIN_TOOLTIP_SHOWHIDERP1;Mostrar/ocultar el panel derecho.\nAtajo: Alt-L +MAIN_TOOLTIP_SHOWHIDETP1;Mostrar/ocultar el panel superior.\nAtajo: Shift-L +MAIN_TOOLTIP_THRESHOLD;Umbral +MAIN_TOOLTIP_TOGGLE;Cambiar vista antes/después.\nAtajo: Shift-B +NAVIGATOR_NA; -- +NAVIGATOR_XY_FULL;Ancho = %1, Alto = %2 +NAVIGATOR_XY_NA;x = n/a, y = n/a +OPTIONS_DEFIMG_MISSING;El perfil predeterminado para fotos no raw no se pudo encontrar o no está establecido.\n\nPor favor verifique su folder de perfiles, puede estar dañado o no existir.\n\nSe usarán valores predeterminados internos. +OPTIONS_DEFRAW_MISSING;El perfil predeterminado para fotos raw no se pudo encontrar o no está establecido.\n\nPor favor verifique su folder de perfiles, puede estar dañado o no existir.\n\nSe usarán valores predeterminados internos. +PARTIALPASTE_BASICGROUP;Ajustes básicos +PARTIALPASTE_CACORRECTION;Corrección de aberraciones cromáticas +PARTIALPASTE_CHANNELMIXERBW;Blanco y Negro +PARTIALPASTE_CHANNELMIXER;Mezclador de canales +PARTIALPASTE_COARSETRANS;Rotar 90º/ voltear +PARTIALPASTE_COLORAPP;Modelo CIE 2002 de apariencia de color +PARTIALPASTE_COLORGROUP;Ajustes de color +PARTIALPASTE_COLORTONING;Tonificación de Color +PARTIALPASTE_COMMONTRANSFORMPARAMS;Auto relleno +PARTIALPASTE_COMPOSITIONGROUP;Ajustes de composición +PARTIALPASTE_CROP;Recortar +PARTIALPASTE_DARKFRAMEAUTOSELECT;Auto Selección de la Toma Negra +PARTIALPASTE_DARKFRAMEFILE;Archivo con Toma negra +PARTIALPASTE_DEFRINGE;Eliminar borde púrpura +PARTIALPASTE_DETAILGROUP;Ajustes de detalle +PARTIALPASTE_DIALOGLABEL;Pegar parcialmente perfil de procesamiento +PARTIALPASTE_DIRPYRDENOISE;Reducción de ruido +PARTIALPASTE_DIRPYREQUALIZER;Contraste por niveles de detalle +PARTIALPASTE_DISTORTION;Corrección de Distorsión +PARTIALPASTE_EPD;Mapeo tonal +PARTIALPASTE_EVERYTHING;Todo +PARTIALPASTE_EXIFCHANGES;Cambio en datos Exif +PARTIALPASTE_EXPOSURE;Exposición +PARTIALPASTE_FILMSIMULATION;Simulación de Fílmico +PARTIALPASTE_FLATFIELDAUTOSELECT;Auto Selección de campo plano +PARTIALPASTE_FLATFIELDBLURRADIUS;Radio de difuminado de campo plano +PARTIALPASTE_FLATFIELDBLURTYPE;Tipo de difuminado de campo plano +PARTIALPASTE_FLATFIELDCLIPCONTROL;Control de recorte de Campo Plano +PARTIALPASTE_FLATFIELDFILE;Archivo de campo plano +PARTIALPASTE_HSVEQUALIZER;Ecualizador HSV +PARTIALPASTE_ICMGAMMA;Gamma de salida +PARTIALPASTE_ICMSETTINGS;Ajustes de Gestión de Color +PARTIALPASTE_IMPULSEDENOISE;Impulsar Reducción de ruido +PARTIALPASTE_IPTCINFO;Información IPTC +PARTIALPASTE_LABCURVE;Ajustes Lab +PARTIALPASTE_LENSGROUP;Ajustes relativos al lente +PARTIALPASTE_LENSPROFILE;Perfil de corrección de lente +PARTIALPASTE_METAGROUP;Ajustes de metadatos +PARTIALPASTE_PCVIGNETTE;Filtro quitar viñeteado +PARTIALPASTE_PERSPECTIVE;Perspectiva +PARTIALPASTE_PREPROCESS_DEADPIXFILT;Aplicar filtro Pixel Muerto +PARTIALPASTE_PREPROCESS_GREENEQUIL;Equilibrio del verde +PARTIALPASTE_PREPROCESS_HOTPIXFILT;Aplicar filtro Pixel Caliente +PARTIALPASTE_PREPROCESS_LINEDENOISE;Filtro de ruido de línea +PARTIALPASTE_RAWCACORR_AUTO;Auto corrección de Aberración Cromática +PARTIALPASTE_RAWCACORR_CABLUE;AC Azul +PARTIALPASTE_RAWCACORR_CARED;AC Rojo +PARTIALPASTE_RAWEXPOS_BLACK;Nivel de negro +PARTIALPASTE_RAWEXPOS_LINEAR;Corrección de punto blanco +PARTIALPASTE_RAWEXPOS_PRESER;Preservar Luces Altas +PARTIALPASTE_RAWGROUP;Ajustes Raw +PARTIALPASTE_RAW_DCBENHANCE;Aplicar paso de mejora DCB +PARTIALPASTE_RAW_DCBITERATIONS;Número de iteraciones DCB +PARTIALPASTE_RAW_DMETHOD;Método de interpolado +PARTIALPASTE_RAW_FALSECOLOR;Pasos de supresión de falso color de interpolado +PARTIALPASTE_RAW_LMMSEITERATIONS;Pasos de mejora LMMSE +PARTIALPASTE_RESIZE;Cambiar tamaño +PARTIALPASTE_RGBCURVES;Curvas RGB +PARTIALPASTE_ROTATION;Rotar +PARTIALPASTE_SHADOWSHIGHLIGHTS;Sombras/Luces altas +PARTIALPASTE_SHARPENEDGE;Bordes +PARTIALPASTE_SHARPENING;Enfoque +PARTIALPASTE_SHARPENMICRO;Micro-contraste +PARTIALPASTE_VIBRANCE;Vibranza +PARTIALPASTE_VIGNETTING;Corrección de viñeteo +PARTIALPASTE_WHITEBALANCE;Equilibrio de blancos +PREFERENCES_ADD;Añadir +PREFERENCES_APPLNEXTSTARTUP;requiere reinicio +PREFERENCES_AUTOMONPROFILE;Usar perfil de color del monitor principal en el sistema operativo +PREFERENCES_BATCH_PROCESSING;Procesamiento por lotes +PREFERENCES_BEHADDALLHINT;Establezca todos los parámetros del modo Agregar.\nLos ajustes de parámetros en el panel de la herramienta de lotes serán deltas de los valores guardados +PREFERENCES_BEHADDALL;Todo para 'Agregar' +PREFERENCES_BEHAVIOR;Comportamiento +PREFERENCES_BEHSETALLHINT;Todos los parámetros para el modo Establecer.\nLos ajustes de parámetros en el panel de la herramienta de lotes serán serán absolutos, se mostrarán los valores vigentes +PREFERENCES_BEHSETALL;Todo para 'Establecer' +PREFERENCES_BLACKBODY;Tungsteno +PREFERENCES_CACHECLEARALL;Borrar todo +PREFERENCES_CACHECLEARPROFILES;Borrar perfiles +PREFERENCES_CACHECLEARTHUMBS;Borrar miniaturas +PREFERENCES_CACHEMAXENTRIES;Cantidad máxima de entradas en la memoria intermedia +PREFERENCES_CACHEOPTS;Opciones de memoria intermedia +PREFERENCES_CACHETHUMBHEIGHT;Altura máxima de las miniaturas +PREFERENCES_CIEART;Optimización CIECAM02 +PREFERENCES_CIEART_LABEL;Usar precisión flotante simple en lugar de doble. +PREFERENCES_CIEART_TOOLTIP;Si se habilita, los cálculos CIECAM02 se realizan con precisión flotante simple en lugar de doble. Esto provee un pequeño aumento en la velocidad de cálculo a expensas de una casi imperceptible pérdida de calidad +PREFERENCES_CLIPPINGIND;Indicación de recortes +PREFERENCES_CLUTSDIR;Directorio HaldCLUT +PREFERENCES_CMETRICINTENT;Intento colorimétrico +PREFERENCES_CUSTPROFBUILDHINT;Archivo ejecutable (o script) invocado un nuevo perfil de procesamiento inicial debe ser generado para una imagen.\n\nLa ruta del archivo de comunicación (estilo .ini) es agregado como parámetro de comando en línea. Éste contiene diversos parámetros requeridos y metadatos Exif de la imagen para permitir la generación de perfiles de procesamientos basados en reglas.\n\nADVERTENCIA:Usted es responsable de colocar comillas donde se requieren cuando se usan rutas conteniendo espacios en blanco. +PREFERENCES_CUSTPROFBUILDKEYFORMAT;Clave de formato +PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME;Nombre +PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;ID Etiqueta +PREFERENCES_CUSTPROFBUILDPATH;Ruta al programa ejecutable +PREFERENCES_CUSTPROFBUILD;Programa generador de perfiles de procesamiento de imagen del usuario +PREFERENCES_CUTOVERLAYBRUSH;Recortar máscara de color/transparencia +PREFERENCES_D50;5000ºK +PREFERENCES_D55;5500ºK +PREFERENCES_D60;6000ºK +PREFERENCES_D65;6500ºK +PREFERENCES_DARKFRAMEFOUND;Encontrado +PREFERENCES_DARKFRAMESHOTS;disparos +PREFERENCES_DARKFRAMETEMPLATES;plantillas +PREFERENCES_DARKFRAME;Toma Negra +PREFERENCES_DATEFORMATHINT;Puede usar las siguientes variables :\n%y : año\n%m : mes\n%d : dia\n\nPor ejemplo, la fecha en formato Húngaro es: \n%y/%m/%d +PREFERENCES_DATEFORMAT;Formato de fecha +PREFERENCES_DEFAULTLANG;Idioma predeterminado +PREFERENCES_DEFAULTTHEME;Tema predeterminado +PREFERENCES_DIRDARKFRAMES;Carpeta con las Tomas Negras +PREFERENCES_DIRHOME;Carpeta de usuario +PREFERENCES_DIRLAST;Última carpeta visitada +PREFERENCES_DIROTHER;Otro +PREFERENCES_DIRSELECTDLG;Seleccionar carpeta de imágenes en el arranque... +PREFERENCES_DIRSOFTWARE;Carpeta de instalación +PREFERENCES_EDITORCMDLINE;Otra línea de comando +PREFERENCES_EDITORLAYOUT;Disposición del editor +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_FLATFIELDFOUND;Encontrado +PREFERENCES_FLATFIELDSDIR;Carpeta de archivos de campo plano +PREFERENCES_FLATFIELDSHOTS;disparos +PREFERENCES_FLATFIELDTEMPLATES;plantillas +PREFERENCES_FLATFIELD;Campo plano +PREFERENCES_FLUOF2;Fluorescente F2 +PREFERENCES_FLUOF7;Fluorescente F7 +PREFERENCES_FLUOF11;Fluorescente F11 +PREFERENCES_FORIMAGE;Para fotos de tipo diferente a raw +PREFERENCES_FORRAW;Para fotos Raw +PREFERENCES_GIMPPATH;Carpeta de instalación de GIMP +PREFERENCES_GREY05;Yb=05 CIE L#30 +PREFERENCES_GREY10;Yb=10 CIE L#40 +PREFERENCES_GREY15;Yb=15 CIE L#45 +PREFERENCES_GREY18;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_GREY;Luminancia (%) Yb del dispositivo de salida +PREFERENCES_HISTOGRAMPOSITIONLEFT;Histograma en panel izquierdo +PREFERENCES_HISTOGRAMWORKING;Usar perfil de trabajo para el histograma principal y el navegador +PREFERENCES_HISTOGRAM_TOOLTIP;Si está activado, el perfil de trabajo se utiliza para renderizar el histograma principal y el panel navegador, de lo contrario se utiliza el perfil de Gamma Corregida de salida. +PREFERENCES_HLTHRESHOLD;Umbral de luces altas cortadas +PREFERENCES_ICCDIR;Carpeta con perfiles de color ICC +PREFERENCES_IMPROCPARAMS;Parámetros de procesamiento de imágenes predeterminados +PREFERENCES_INTENT_ABSOLUTE;Colorimétrico absoluto +PREFERENCES_INTENT_PERCEPTUAL;Perceptual +PREFERENCES_INTENT_RELATIVE;Colorimétrico relativo +PREFERENCES_INTENT_SATURATION;Saturación +PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Mostrar miniatura JPEG incrustada si foto Raw no se ha editado +PREFERENCES_LANGAUTODETECT;Usar idioma del sistema +PREFERENCES_MENUGROUPEXTPROGS;Grupo "Abrir con" +PREFERENCES_MENUGROUPFILEOPERATIONS;Grupo "Operaciones de archivo" +PREFERENCES_MENUGROUPLABEL;Grupo "Etiquetado con color" +PREFERENCES_MENUGROUPPROFILEOPERATIONS;Grupo "Operaciones de Perfil de Procesamiento" +PREFERENCES_MENUGROUPRANK;Grupo "Asignar Rango" +PREFERENCES_MENUOPTIONS;Opciones de menú de contexto +PREFERENCES_METADATA;Metadatos +PREFERENCES_MONITORICC;Perfil de pantalla +PREFERENCES_MULTITABDUALMON;Modo Editor de varias pestañas, si está disponible en segundo monitor +PREFERENCES_MULTITAB;Modo Editor de varias pestañas +PREFERENCES_NAVGUIDEBRUSH;Color de la guía del navegador +PREFERENCES_OUTDIRFOLDERHINT;Guardar las imágenes creadas en una carpeta elegida +PREFERENCES_OUTDIRFOLDER;Guardar en carpeta +PREFERENCES_OUTDIRTEMPLATEHINT;Se pueden usar las variables siguientes:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nEstas variables son referencias a las carpetas y subrutas de las rutas del lugar donde se encuentra la imagen raw.\n\nPor ejemplo, si abres /home/tom/image/02-09-2006/dsc0012.nef, los valores de las variables son:\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\nSi quieres guardar la imagen de salida en el lugar original, usa:\n%p1/%f\n\nSi quieres guardar la imagen de salida en una carpeta 'convertida' dentro de la carpeta original, usa:\n%p1/convertida/%f\n\nSi quieres guardar la imagen de salida en la carpeta '/home/tom/convertida' conservando la misma subcarpeta de fechas, usa:\n%p2/convertida/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Usar plantilla +PREFERENCES_OUTDIR;Carpeta de salida +PREFERENCES_OVERLAY_FILENAMES;Superponer nombres de archivo en miniaturas +PREFERENCES_OVERWRITEOUTPUTFILE;Sobreescribir archivos de salida existentes +PREFERENCES_PANFACTORLABEL;Factor +PREFERENCES_PARSEDEXTADDHINT;Ingrese una extensión y pulse este botón para agregarla a la lista +PREFERENCES_PARSEDEXTADD;Agregar extensión +PREFERENCES_PARSEDEXTDELHINT;Borrar de la lista las extensiones seleccionadas +PREFERENCES_PARSEDEXT;Extensiones analizadas +PREFERENCES_PROFILEHANDLING;Tratamiento de perfiles de procesamiento +PREFERENCES_PROFILELOADPR;Prioridad de perfiles cuando se abre imagen +PREFERENCES_PROFILEPRCACHE;Perfil en memoria intermedia +PREFERENCES_PROFILEPRFILE;Perfil junto a imagen de entrada +PREFERENCES_PROFILESAVECACHE;Guardar perfiles de procesamiento en memoria intermedia +PREFERENCES_PROFILESAVEINPUT;Guardar perfiles de procesamiento junto con imagen de entrada +PREFERENCES_PROPERTY;Propiedad +PREFERENCES_PSPATH;Carpeta de instalación de Adobe Photoshop +PREFERENCES_RGBDTL_LABEL;Número máximo de hilos para reducción de ruido +PREFERENCES_RGBDTL_TOOLTIP;La Reducción de Ruido requiere como base 128MB de RAM para una imagen de 10MPix o 512MB para una imagen de 40MPix; más 128MB RAM por hilo de proceso.\nMientras más hilos corren en paralelo, más rápido es el procesamiento. Coloque “0” para que automáticamente se use tantos hilos como sea posible según la capacidad de su equipo. +PREFERENCES_SELECTFONT;Seleccionar fuente +PREFERENCES_SELECTLANG;Seleccionar idioma +PREFERENCES_SELECTTHEME;Seleccionar tema +PREFERENCES_SET;Establecer +PREFERENCES_SHOWBASICEXIF;Mostrar datos Exif básicos +PREFERENCES_SHOWDATETIME;Mostrar fecha y hora +PREFERENCES_SHOWEXPOSURECOMPENSATION;Mostrar compensación de exposición +PREFERENCES_SHTHRESHOLD;Umbral de sombras cortadas +PREFERENCES_SINGLETABVERTAB;Modo Editor de pestaña única, pestañas verticales +PREFERENCES_SINGLETAB;Modo Editor de pestaña única +PREFERENCES_SLIMUI;Interfase gráfica adelgazada +PREFERENCES_SND_BATCHQUEUEDONE;Trabajos en cola finalizados +PREFERENCES_SND_HELP;Introducir el path o dejar en blanco (sin sonido). En Windows, usar "SystemDefault", "SystemAsterisk" etc. para los sonidos del sistema\nEn Linux use "complete", "window-attention" etc. para los sonidos del sistema. +PREFERENCES_SND_LNGEDITPROCDONE;Procesado del editor terminado +PREFERENCES_SND_TRESHOLDSECS;después de seg. +PREFERENCES_STARTUPIMDIR;Carpeta de imágenes en el arranque +PREFERENCES_TAB_BROWSER;Explorador de archivos +PREFERENCES_TAB_COLORMGR;Gestión del color +PREFERENCES_TAB_GENERAL;General +PREFERENCES_TAB_IMPROC;Procesamiento de imágenes +PREFERENCES_TAB_PERFORMANCE;Rendimiento +PREFERENCES_TAB_SOUND;Sonidos +PREFERENCES_TP_LABEL;Panel de herramientas: +PREFERENCES_TP_USEICONORTEXT;Usar iconos de pestaña en lugar de texto +PREFERENCES_TP_VSCROLLBAR;Ocultar barra de desplazamiento vertical del panel de herramientas +PREFERENCES_TUNNELMETADATA;Copiar IPTC/XMP sin cambios al fichero de salida (cuando etiquete con otro programa) +PREFERENCES_USEBUNDLEDPROFILES;Usar perfiles empaquetados +PREFERENCES_USESYSTEMTHEME;Usar tema del sistema +PREFERENCES_VIEW;Balance de blancos en el dispositivo de salida (monitor, TV, proyector...) +PREFERENCES_WORKFLOW;Disposición +PROFILEPANEL_COPYPPASTE;Parámetros a copiar +PROFILEPANEL_GLOBALPROFILES;Perfiles empaquetados +PROFILEPANEL_LABEL;Perfiles de procesamiento +PROFILEPANEL_LOADDLGLABEL;Cargar parámetros de procesamiento... +PROFILEPANEL_LOADPPASTE;Parámetros a cargar +PROFILEPANEL_MODE_TIP;Modo de procesamiento de perfiles.\n\nBotón Presionado: los perfiles parciales son completados; Los valores faltantes son llenados usando valores predeterminados de fábrica.\n\nBotón Liberado: Los perfiles son aplicados tal como están, alterando solo los valores que contienen; los parámetros sin valores en el perfil se dejan en la imagen tal como están. +PROFILEPANEL_MYPROFILES;Mis perfiles +PROFILEPANEL_PASTEPPASTE;Parámetros +PROFILEPANEL_PCUSTOM;A medida +PROFILEPANEL_PFILE;Desde archivo +PROFILEPANEL_PINTERNAL;Neutro +PROFILEPANEL_PLASTSAVED;Último guardado +PROFILEPANEL_SAVEDLGLABEL;Guardar parámetros de procesamiento... +PROFILEPANEL_SAVEPPASTE;Parámetros a guardar +PROFILEPANEL_TOOLTIPCOPY;Copiar parámetros de procesamiento al portapapeles.\nCtrl-click para seleccionar los parámetros a copiar +PROFILEPANEL_TOOLTIPLOAD;Cargar perfil de un archivo.\nCtrl-click para seleccionar los parámetros a cargar +PROFILEPANEL_TOOLTIPPASTE; Pegar perfil del portapapeles.\nCtrl-click para seleccionar los parámetros a pegar +PROFILEPANEL_TOOLTIPSAVE;Guardar perfil actual.\nCtrl-click para seleccionar los parámetros a guardar +PROGRESSBAR_LOADINGTHUMBS;Cargando miniaturas... +PROGRESSBAR_LOADING;Abriendo imagen... +PROGRESSBAR_LOADJPEG;Abriendo archivo JPEG... +PROGRESSBAR_LOADPNG;Abriendo archivo PNG... +PROGRESSBAR_LOADTIFF;Abriendo archivo TIFF... +PROGRESSBAR_NOIMAGES;No se han encontrado imágenes +PROGRESSBAR_PROCESSING;Procesando la imagen... +PROGRESSBAR_PROCESSING_PROFILESAVED;Se guardó el perfil de procesamiento +PROGRESSBAR_READY;Listo +PROGRESSBAR_SAVEJPEG;Guardando archivo JPEG... +PROGRESSBAR_SAVEPNG;Guardando archivo PNG... +PROGRESSBAR_SAVETIFF;Guardando archivo TIFF... +PROGRESSBAR_SNAPSHOT_ADDED;Se añadió instantánea +PROGRESSDLG_PROFILECHANGEDINBROWSER;Perfil de procesamiento cambiado en explorador +QINFO_ISO;ISO +QINFO_NOEXIF;No hay datos EXIF. +SAVEDLG_AUTOSUFFIX;Automáticamente añade un sufijo cuando el archivo ya existe +SAVEDLG_FILEFORMAT;Formato de archivo +SAVEDLG_FORCEFORMATOPTS;Opciones de guardar forzado +SAVEDLG_JPEGQUAL;Calidad JPEG +SAVEDLG_PNGCOMPR;Compresión PNG +SAVEDLG_PUTTOQUEUEHEAD;Poner al principio de la cola de procesamiento +SAVEDLG_PUTTOQUEUETAIL;Poner al final de la cola de procesamiento +SAVEDLG_PUTTOQUEUE;Poner en la cola de procesamiento +SAVEDLG_SAVEIMMEDIATELY;Guardar inmediatamente +SAVEDLG_SAVESPP;Guardar parámetros de procesamiento con la imagen +SAVEDLG_SUBSAMP;Submuestreo +SAVEDLG_SUBSAMP_1;Máxima compresión +SAVEDLG_SUBSAMP_2;Balanceado +SAVEDLG_SUBSAMP_3;Máxima calidad +SAVEDLG_SUBSAMP_TOOLTIP;Máxima compresión: 4:1:1\nBalanceado: 4:2:2\nMáxima calidad: 4:4:4 +SAVEDLG_TIFFUNCOMPRESSED;TIFF sin compresión +SAVEDLG_WARNFILENAME;Se asignará nombre al archivo +SHCSELECTOR_TOOLTIP;Pulsar el botón derecho del ratón para restablecer la posición de los tres controles deslizantes +THRESHOLDSELECTOR_BL;Inferior izquierdo +THRESHOLDSELECTOR_BR;Inferior derecho +THRESHOLDSELECTOR_B;Inferior +THRESHOLDSELECTOR_HINT;Mantenga la tecla Mayús presionada para mover puntos de control individuales. +THRESHOLDSELECTOR_TL;Superior izquierdo +THRESHOLDSELECTOR_TR;Superior derecho +THRESHOLDSELECTOR_T;Superior +TOOLBAR_TOOLTIP_CROP;Selección de recorte.\nAtajo: c +TOOLBAR_TOOLTIP_HAND;Herramienta mano.\nAtajo: h +TOOLBAR_TOOLTIP_STRAIGHTEN;Enderezado / Rotación Fina.\nAtajo: s\n\nIndique la vertical u horizontal trazando una línea guía sobre la vista previa de la imagen. El ángulo de rotación será mostrado al continuación de la línea guía. El centro de la imagen es el centro de rotación. +TOOLBAR_TOOLTIP_WB;Muestrea equilibrio de blancos.\nAtajo: w +TP_BWMIX_ALGO;Algoritmo OYCPM +TP_BWMIX_ALGO_LI;Lineal +TP_BWMIX_ALGO_SP;Efectos especiales +TP_BWMIX_ALGO_TOOLTIP;Lineal: producirá una respuesta lineal normal.\nEfectos especiales: producirá efectos especiales por mezclar no linealmente los canales. +TP_BWMIX_AUTOCH;Auto +TP_BWMIX_AUTOCH_TIP;Calcular valores óptimos para el Mezclador de Canales +TP_BWMIX_CC_ENABLED;Ajustar color complementario +TP_BWMIX_CC_TOOLTIP;Permite el ajuste automático de colores complementarios en modo RNAmVCAzPM +TP_BWMIX_CHANNEL;Ecualizador de luminancia +TP_BWMIX_CURVEEDITOR1;Curva 'Antes' +TP_BWMIX_CURVEEDITOR2;Curva 'Después' +TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Curva tonal, luego de conversión a B&N, aplicada al final del tratamiento +TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Curva tonal, aplicada antes de conversión a B&N\nPuede ser afectada por los colores de los componentes +TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Modifica luminancia en función del matiz (hue)\nTenga en cuenta que valores extremos pueden introducir elementos artificiales. +TP_BWMIX_FILTER;Filtro de color +TP_BWMIX_FILTER_BLUEGREEN;Azul-Verde +TP_BWMIX_FILTER_BLUE;Azul +TP_BWMIX_FILTER_GREENYELLOW;Verde-Amarillo +TP_BWMIX_FILTER_GREEN;Verde +TP_BWMIX_FILTER_NONE;Ninguno +TP_BWMIX_FILTER_PURPLE;Púrpura +TP_BWMIX_FILTER_REDYELLOW;Rojo-Amarillo +TP_BWMIX_FILTER_RED;Rojo +TP_BWMIX_FILTER_TOOLTIP;El filtro de color simula fotos tomadas con un filtro de color colocado frente a la lente de la cámara. Los filtros de colores reducen el paso de un rango específico de colores, afectando correspondientemente su claridad. Por ejemplo, un filtro rojo oscurece cielos azules. +TP_BWMIX_FILTER_YELLOW;Amarillo +TP_BWMIX_GAMMA;Corrección de Gamma +TP_BWMIX_GAM_TOOLTIP;Corrige la Gamma de cada canal RGB +TP_BWMIX_LABEL;Blanco y Negro +TP_BWMIX_MET;Método +TP_BWMIX_MET_CHANMIX;Mezclador de canales +TP_BWMIX_MET_DESAT;Des-saturación +TP_BWMIX_MET_LUMEQUAL;Ecualizador de Luminancia +TP_BWMIX_MIXC;Mezclador +TP_BWMIX_NEUTRAL;Restablece el mezclador +TP_BWMIX_NEUTRAL_TIP;Restablece todos los parámetros (filtro, mezclador de canales) a sus valores predeterminados. +TP_BWMIX_RGBLABEL;R: %1%% V: %2%% A: %3%% Total: %4%% +TP_BWMIX_RGBLABEL_HINT;Factores finales RGB tomando en cuenta todas las opciones del mezclador\nTotal muestra la suma de los valores RGB actualmente aplicados:\n- En modo relativo Siempre 100% \n- En modo absoluto mayor (más claro) o menor (más oscuro) que 100% +TP_BWMIX_RGB_TOOLTIP;Mezcla de canales RGB. Use como guía valores pre-establecidos.\nTenga en cuenta que valores negativos pueden introducir elementos extraños (artifacts) o resultados erráticos. +TP_BWMIX_SETTING;Predeterminados +TP_BWMIX_SETTING_TOOLTIP;Diversos pre-establecidos (película, paisaje, ...) o ajustes manuales del mezclador de canales +TP_BWMIX_SET_HIGHCONTAST;Alto Contraste +TP_BWMIX_SET_HIGHSENSIT;Alta sensibilidad +TP_BWMIX_SET_HYPERPANCHRO;Hiper Pancromático +TP_BWMIX_SET_INFRARED;Infrarrojo +TP_BWMIX_SET_LANDSCAPE;Paisaje +TP_BWMIX_SET_LOWSENSIT;Baja Sensibilidad +TP_BWMIX_SET_LUMINANCE;Luminancia +TP_BWMIX_SET_NORMCONTAST;Contraste Normal +TP_BWMIX_SET_ORTHOCHRO;Orto-cromático +TP_BWMIX_SET_PANCHRO;Pancromático +TP_BWMIX_SET_PORTRAIT;Retrato +TP_BWMIX_SET_RGBABS;RGB Absoluto +TP_BWMIX_SET_RGBREL;RGB Relativo +TP_BWMIX_SET_ROYGCBPMABS;RNAmVCAzPM Absoluto +TP_BWMIX_SET_ROYGCBPMREL;RNAmVCAzPM Relativo +TP_BWMIX_TCMODE_FILMLIKE;B&N simulando película +TP_BWMIX_TCMODE_SATANDVALBLENDING;Saturación y combinación de Valores B&N +TP_BWMIX_TCMODE_STANDARD;B&N Estándar +TP_BWMIX_TCMODE_WEIGHTEDSTD;B&N Estándar Ponderado +TP_BWMIX_VAL;L +TP_CACORRECTION_BLUE;Azul +TP_CACORRECTION_LABEL;Corrección de aberraciones cromáticas +TP_CACORRECTION_RED;Rojo +TP_CHMIXER_BLUE;Canal Azul +TP_CHMIXER_GREEN;Canal Verde +TP_CHMIXER_LABEL;Mezclador de canales +TP_CHMIXER_RED;Canal Rojo +TP_CHROMATABERR_LABEL;Aberración cromática (AC) +TP_COARSETRAF_TOOLTIP_HFLIP;Voltear horizontalmente.\nAtajo: '[' +TP_COARSETRAF_TOOLTIP_ROTLEFT;Rotar a la izquierda.\nAtajo: ']' +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Rotar a la derecha +TP_COARSETRAF_TOOLTIP_VFLIP;Voltear verticalmente +TP_COLORAPP_ADAPTSCENE;Adaptación a la luminosidad de la escena +TP_COLORAPP_ADAPTSCENE_TOOLTIP;Luminancia absoluta del entorno de la escena (cd/m²).\n1) Calculado en base a datos Exif: \nTiempo de Exposición - Velocidad ISO - Número F de apertura - Corrección de exposición\n2) Calculado a partir del Punto Blanco raw y Compensación de Exposición RT. +TP_COLORAPP_ADAPTVIEWING;Luminosidad de visualización (cd/m²) +TP_COLORAPP_ADAPTVIEWING_TOOLTIP;Luminancia absoluta del entorno de visualización\n(usualmente 16cd/m²) +TP_COLORAPP_ADAP_AUTO_TOOLTIP;Si la casilla está seleccionada (como se recomienda) RT calcula el valor óptimo a partir de los datos Exif.\nPara establecer el valor manualmente, primero desmarque la casilla +TP_COLORAPP_ALGO;Algoritmo +TP_COLORAPP_ALGO_ALL;Todo +TP_COLORAPP_ALGO_JC;Claridad + Crominancia (JC) +TP_COLORAPP_ALGO_JS;Claridad + Saturación (JS) +TP_COLORAPP_ALGO_QM;Brillo + Colorido (QM) +TP_COLORAPP_ALGO_TOOLTIP;Le permite elegir entre subconjuntos de parámetros o todos los parámetros +TP_COLORAPP_BADPIXSL;Filtro de píxeles calientes/muertos +TP_COLORAPP_BADPIXSL_TOOLTIP;Supresión de píxeles calientes/muertos (con coloreado brillante).\n 0 = Sin efecto \n 1 = Mediana \n 2 = Gaussiano.\n\nEstos elementos extraños son causados por limitaciones de CIECAM02. Como alternativa, ajuste la imagen para evitar sombras muy oscuras. +TP_COLORAPP_BRIGHT;Brillo (Q) +TP_COLORAPP_BRIGHT_TOOLTIP;En CIECAM02 el Brillo tiene en cuenta la luminosidad de los blancos y es diferente al de Lab y al de RGB +TP_COLORAPP_CHROMA;Crominancia (C) +TP_COLORAPP_CHROMA_M;Colorido (M) +TP_COLORAPP_CHROMA_M_TOOLTIP;El Colorido CIECAM02 es diferente al de Lab y al de RGB +TP_COLORAPP_CHROMA_S;Saturación (S) +TP_COLORAPP_CHROMA_S_TOOLTIP;La Saturación CIECAM02 es diferente a la de Lab y a la de RGB +TP_COLORAPP_CHROMA_TOOLTIP;Crominancia en CIECAM02 es diferente a la de Lab y a la de RGB +TP_COLORAPP_CIECAT_DEGREE;CAT02 adaptación +TP_COLORAPP_CONTRAST;Contraste (J) +TP_COLORAPP_CONTRAST_Q;Contraste (Q) +TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contraste en CIECAM02 para el control deslizante Q; es diferente al contraste en Lab y en RGB +TP_COLORAPP_CONTRAST_TOOLTIP;Contraste en CIECAM02 para el control deslizante J; es diferente al contraste en Lab y en RGB +TP_COLORAPP_CURVEEDITOR1;Curva tonal 1 +TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Muestra el histograma L (de Lab) antes de CIECAM02.\nSi la casilla "Muestra en las curvas histogramas de salida CIECAM02" está seleccionada, muestra los histogramas de J o Q después de CIECAM02.\n\nJ y Q no se muestran en el histograma del panel principal.\n\nVea el histograma de salida final en el panel principal +TP_COLORAPP_CURVEEDITOR2;Curva tonal 2 +TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Por favor, consulte RawPedia para aprender cómo obtener mejores resultados usando dos curvas tonales +TP_COLORAPP_CURVEEDITOR3;Curva de color +TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Ajusta Crominancia, Saturación o Colorido.\n\nMuestra el histograma de Cromaticidad (Lab) antes de los ajustes CIECAM02.\nSi la casilla "Muestra en las curvas histogramas de salida CIECAM02" está seleccionada, muestra el histograma de C, s o M después de CIECAM02.\n\nC, s y M no se muestran en el histograma del panel principal.\n\nVea el histograma de salida final en el panel principal +TP_COLORAPP_DATACIE;Curvas con histogramas de salida CIECAM02 +TP_COLORAPP_DATACIE_TOOLTIP;Si está seleccionada, los histogramas en las curvas CIECAM02 muestran aproximadamente valores/rangos de J o Q, y C, s o M después de los ajustes CIECAM02.\nEsta selección no influye en el histograma del panel principal.\n\nCuando no está seleccionada, los histogramas en las curvas CIECAM02 muestran valores Lab antes de los ajustes CIECAM02 +TP_COLORAPP_DEGREE_AUTO_TOOLTIP;Si la casilla está seleccionada (como se recomienda), RT calcula el valor óptimo, que es usado por CAT02, y también por todo CIECAM02.\nPara establecer manualmente el valor, primero desmarque la casilla (se recomienda usar valores mayores a 65) +TP_COLORAPP_DEGREE_TOOLTIP;Cantidad de transformación de adaptación cromática CIE 2002 +TP_COLORAPP_GAMUT;Control de Gamut (Lab) +TP_COLORAPP_GAMUT_TOOLTIP;Permite control de gamut en modo Lab +TP_COLORAPP_HUE;Matiz (h) +TP_COLORAPP_HUE_TOOLTIP;Matiz (h) - ángulo entre 0° y 360° +TP_COLORAPP_LABEL;CIE Modelo de Apariencia de Color 2002 +TP_COLORAPP_LABEL_CAM02;Ajustes de imagen +TP_COLORAPP_LABEL_SCENE;Condiciones de la escena +TP_COLORAPP_LABEL_VIEWING;Condiciones de visualización +TP_COLORAPP_LIGHT;Claridad (J) +TP_COLORAPP_LIGHT_TOOLTIP;Claridad en CIECAM02 es diferente a la de Lab y a la de RGB +TP_COLORAPP_MODEL;Modelo de Punto Blanco +TP_COLORAPP_MODEL_TOOLTIP;Modelo de Punto Blanco\n\nWB [RT] + [salida]:\nEl Balance de Blancos de RT es usado para la escena, CIECAM02 es establecido a D50, y el Balance de Blancos del dispositivo de salida es el establecido en Preferencias > Gestión de Color\n\nWB [RT+CAT02] + [salida]:\nEl Balance de Blancos de RT es usado por CAT02 y el del dispositivo de salida es el establecido en preferencias +TP_COLORAPP_RSTPRO; Protección de tonos rojos y color piel +TP_COLORAPP_RSTPRO_TOOLTIP;Intensidad de protección de tonos rojos y color piel (en curvas y en controles deslizantes) +TP_COLORAPP_SHARPCIE;Enfoque, Contraste por niveles de detalle, Micro-contraste & Eliminación de AC con Q/C +TP_COLORAPP_SHARPCIE_TOOLTIP;Si se selecciona, Enfoque, Contraste por niveles de detalle, Micro-contraste & Eliminación de AC usarán CIECAM02 +TP_COLORAPP_SURROUND;Entorno +TP_COLORAPP_SURROUND_AVER;Promedio +TP_COLORAPP_SURROUND_DARK;Oscuro +TP_COLORAPP_SURROUND_DIM;Luz Tenue +TP_COLORAPP_SURROUND_EXDARK;Muy oscuro +TP_COLORAPP_SURROUND_TOOLTIP;Cambia la tonalidad y color de la imagen teniendo en cuenta las condiciones de visualización en el dispositivo de salida\n\nPromedio:\nEntorno con iluminación media(estándar)\nLa imagen no cambiará\n\n\n\nLuz Tenue:\nAmbiente a media luz (TV)\nLa imagen se pondrá ligeramente oscura\n\nOscuro:\nEntorno oscuro (proyector)\nLa imagen se pondrá más oscura\n\nMuy Oscuro:\nEntorno extremadamente oscuro\nLa imagen se podrá bien oscura +TP_COLORAPP_SURSOURCE;Entorno oscuro +TP_COLORAPP_SURSOURCE_TOOLTIP;Puede usarse si la imagen original tiene borde oscuro. +TP_COLORAPP_TCMODE_BRIGHTNESS;Brillo +TP_COLORAPP_TCMODE_CHROMA;Crominancia +TP_COLORAPP_TCMODE_COLORF;Colorido +TP_COLORAPP_TCMODE_LABEL1;Curva modo 1 +TP_COLORAPP_TCMODE_LABEL2;Curve modo 2 +TP_COLORAPP_TCMODE_LABEL3;Curva en modo crominancia +TP_COLORAPP_TCMODE_LIGHTNESS;Claridad +TP_COLORAPP_TCMODE_SATUR;Saturación +TP_COLORAPP_TONECIE;Mapeo tonal usando Brillo (Q) CIECAM02. +TP_COLORAPP_TONECIE_TOOLTIP;Si esta opción no está seleccionada, el mapeo tonal se hace usando el espacio de color Lab.\nSi esta opción está seleccionada, el mapeo tonal se hace usando CIECAM02.\nLa herramienta de mapeo tonal debe de estar habilitada para que esta selección tenga efecto +TP_COLORAPP_WBCAM;BalBlanco [RT+CAT02] + [salida] +TP_COLORAPP_WBRT;BalBlanco [RT] + [salida] +TP_COLORTONING_AB;o C/L +TP_COLORTONING_AUTOSAT;Automático +TP_COLORTONING_BALANCE;Balance +TP_COLORTONING_BY;o C/L +TP_COLORTONING_CHROMAC;Opacidad +TP_COLORTONING_COLOR;Color +TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;Opacidad de la Crominancia en función de la Luminancia: C=f(L) +TP_COLORTONING_HIGHLIGHT;Luces Altas +TP_COLORTONING_HUE;Matiz +TP_COLORTONING_LABEL;Tonificación de Color +TP_COLORTONING_LAB;Mezcla Lab +TP_COLORTONING_LUMAMODE;Preservar luminancia +TP_COLORTONING_LUMAMODE_TOOLTIP;Si está activado, cuando se cambia el color(rojo, verde, cian, azul, etc.) la luminancia de cada pixel es preservada. +TP_COLORTONING_LUMA;Luminancia +TP_COLORTONING_METHOD;Método +TP_COLORTONING_METHOD_TOOLTIP;"Mezcla Lab", "Controles deslizantes RGB" y "Curvas RGB" utilizan mezcla de color interpolada.\n"Balance de Color (Sombras/Tonos Medios/Luces Altas)" y "Saturación 2 colores" utilizan colores directos.\n\nCualquier método de tonificación de color puede ser aplicado aún estando la herramienta Blanco y Negro activada. +TP_COLORTONING_MIDTONES;Tonos Medios +TP_COLORTONING_NEUTRAL;Restablecer controles deslizantes +TP_COLORTONING_NEUTRAL_TIP;Restablecer todos los valores predeterminados(Sombras, Tonos Medios, Luces Altas). +TP_COLORTONING_OPACITY;Opacidad +TP_COLORTONING_RGBCURVES;RGB - Curvas +TP_COLORTONING_RGBSLIDERS;RGB - Controles deslizantes +TP_COLORTONING_SATURATEDOPACITY;Intensidad +TP_COLORTONING_SATURATIONTHRESHOLD;Umbral +TP_COLORTONING_SA;Protección de saturación +TP_COLORTONING_SHADOWS;Sombras +TP_COLORTONING_SPLITCOCO;Balance de Color Sombras/Tonos Medios/Luces Altas +TP_COLORTONING_SPLITCO;Sombras/Tonos Medios/Luces Altas +TP_COLORTONING_SPLITLR;Saturación 2 colores +TP_COLORTONING_STRENGTH;Intensidad +TP_COLORTONING_STR;Intensidad +TP_COLORTONING_TWO2;Crominancia especial '2 colores' +TP_COLORTONING_TWOALL;Crominancia especial +TP_COLORTONING_TWOBY;Especial 'a' y 'b' +TP_COLORTONING_TWOCOLOR_TOOLTIP;Crominancia estándar:\nRespuesta lineal, a* = b*.\n\nCrominancia especial:\nRespuesta lineal, a* = b*, pero no unidas - intentar debajo de la diagonal.\n\nEspecial a* and b*:\nRespuesta lineal no unida con curvas separadas para a* y b*. Previsto para efectos especiales.\n\nCrominancia especial 2 colores:\nMás predecible. +TP_COLORTONING_TWOSTD;Crominancia estándar +TP_CROP_FIXRATIO;Fijar proporciones: +TP_CROP_GTDIAGONALS;Regla de las diagonales +TP_CROP_GTEPASSPORT;Pasaporte biométrico +TP_CROP_GTFRAME;Marco +TP_CROP_GTGRID;Rejilla +TP_CROP_GTNONE;Ninguna +TP_CROP_GTRULETHIRDS;Regla de los tercios +TP_CROP_GUIDETYPE;Clase de guía: +TP_CROP_H;Al +TP_CROP_LABEL;Recortar +TP_CROP_PPI;Ptos/Pulgada= +TP_CROP_SELECTCROP;Seleccionar recorte +TP_CROP_W;Ancho +TP_CROP_X;x +TP_CROP_Y;y +TP_DARKFRAME_AUTOSELECT;Auto selección +TP_DARKFRAME_LABEL;Toma Negra +TP_DEFRINGE_LABEL;Quitar borde púrpura +TP_DEFRINGE_RADIUS;Radio +TP_DEFRINGE_THRESHOLD;Umbral +TP_DIRPYRDENOISE_33;3×3 fuerte +TP_DIRPYRDENOISE_55SOFT;5×5 +TP_DIRPYRDENOISE_55;5×5 fuerte +TP_DIRPYRDENOISE_77;7×7 (lento) +TP_DIRPYRDENOISE_BLUE;Crominancia: Azul-Amarillo +TP_DIRPYRDENOISE_CHROMA;Crominancia: Maestra +TP_DIRPYRDENOISE_CURVEEDITOR_L_TOOLTIP;Modula la acción de eliminación de ruido 'de luminancia' +TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Puede usarse en imágenes Raw y no Raw.\n\nPara imágenes no Raw la reducción del ruido en la luminancia depende de la gamma en el perfil de color de entrada. Se asume la gamma de sRGB, de manera que si la imagen tiene un perfil de color con otra gamma, la reducción del ruido en la luminancia va a variar. +TP_DIRPYRDENOISE_ENH;Modo mejorado +TP_DIRPYRDENOISE_ENH_TOOLTIP;Incrementa la calidad de la Reducción de Ruido a costa de un incremento de 20% en el tiempo de procesamiento +TP_DIRPYRDENOISE_GAMMA;Gamma +TP_DIRPYRDENOISE_GAMMA_TOOLTIP;Gamma hace variar la fuerza de reducción del ruido a lo largo del rango tonal.\n\n Valores pequeños dirigen la reducción hacia las sombras, mientras que valores grandes extienden el efecto hasta los tonos brillantes +TP_DIRPYRDENOISE_GAMMA_TOOLTIP;Mediante Gamma se varía la intensidad de la Reducción de Ruido a lo largo del rango tonal. Valores pequeños están dirigidos a las sombras, mientras que valores grandes estiran el efecto hacia los tonos brillantes +TP_DIRPYRDENOISE_LABEL;Reducción de ruido +TP_DIRPYRDENOISE_LABM;Lab +TP_DIRPYRDENOISE_LCURVE;Curva de Luminancia +TP_DIRPYRDENOISE_LDETAIL;Detalle en luminancia +TP_DIRPYRDENOISE_LM;Sólo luminancia +TP_DIRPYRDENOISE_LUMA;Luminancia +TP_DIRPYRDENOISE_MEDMETHOD;Método Median +TP_DIRPYRDENOISE_MEDTYPE;Tipo Median +TP_DIRPYRDENOISE_MED;Median +TP_DIRPYRDENOISE_MED_TOOLTIP;Eliminador de ruido Median activado +TP_DIRPYRDENOISE_METHOD11;Calidad +TP_DIRPYRDENOISE_METHOD11_TOOLTIP;La Calidad puede ser adaptada a un patrón de ruido. Al seleccionar "Alto" se incrementa el efecto de reducción de ruido a costa de prolongar el tiempo de procesamiento. +TP_DIRPYRDENOISE_METHOD;Método +TP_DIRPYRDENOISE_METHOD_TOOLTIP;Para imágenes raw puede usar tanto el método RGB como el Lab.\n\nPara imágenes no raw el método Lab será usado de todas maneras, ignorando el método seleccionado. +TP_DIRPYRDENOISE_METM_TOOLTIP;Cuando se utiliza "Sólo Luminancia" y los métodos "Lab", el filtro Median será aplicado inmediatamente después de cada proceso de toda la cadena de reducción de ruido.\nCuando se utiliza el modo "RGB", el filtro Median se aplicará al final de toda la cadena de procesos de reducción de ruido. +TP_DIRPYRDENOISE_MET_TOOLTIP;Aplicar el filtro Median al tamaño deseado. Cuanto mayor sea el tamaño, demandará más tiempo.\n\n3x3 suave: procesar 5 píxeles en un rango de 1 píxel.\n3x3: procesar 9 píxeles en un rango de 1 píxel.\n5x5 suave: procesar 13 píxeles en un rango de 2 píxeles.\n5x5: procesar 25 píxeles en un rango de 2 píxeles.\n7x7: procesar 49 píxeles en un rango 3 píxeles.\n\nAlgunas veces es posible lograr una mayor calidad ejecutando varias iteraciones con un rango pequeño, que con una sóla iteración con un rango amplio. +TP_DIRPYRDENOISE_PASSES;Iteracciones Median +TP_DIRPYRDENOISE_PASSES_TOOLTIP;Aplicar el filtro Median 3x3 con 3 iteraciones, a menudo produce mejores resultados que aplicar una sola vez 7x7. +TP_DIRPYRDENOISE_RED;Crominancia: Rojo-Verde +TP_DIRPYRDENOISE_RGBM;RGB +TP_DIRPYRDENOISE_RGB;RGB +TP_DIRPYRDENOISE_SHALBI;Alto +TP_DIRPYRDENOISE_SHAL;Estándar +TP_DIRPYRDENOISE_SOFT;3x3 +TP_DIRPYREQUALIZER_ALGO;Rango de Color de Piel +TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fino: cercano a los colores de la piel, minimizando la acción en otros colores\nAmplio: evita más elementos extraños. +TP_DIRPYREQUALIZER_HUESKIN;Matiz de la piel +TP_DIRPYREQUALIZER_HUESKIN_TOOLTIP;En la parte superior se selecciona la zona con los valores máximos.\nEn la parte inferior se ajusta la transición.\nSi necesita para mover el área de manera significativa a la izquierda o a la derecha - o si hay elementos extraños:.. El balance de blancos es incorrecto \nPuedes reducir ligeramente la zona para evitar que el resto de la imagen se vea afectada. +TP_DIRPYREQUALIZER_LABEL;Contraste por niveles de detalle +TP_DIRPYREQUALIZER_LUMACOARSEST;Más grueso +TP_DIRPYREQUALIZER_LUMACONTRAST_MINUS;-Contraste +TP_DIRPYREQUALIZER_LUMACONTRAST_PLUS;+Contraste +TP_DIRPYREQUALIZER_LUMAFINEST;Más fino +TP_DIRPYREQUALIZER_LUMANEUTRAL;Neutro +TP_DIRPYREQUALIZER_SKIN;Tonos de Piel focalización/protección +TP_DIRPYREQUALIZER_SKIN_TOOLTIP;A -100 se focalizan los tonos de piel.\nA 0 todos los tonos son afectados de la misma manera.\nA 100 los tonos de piel son protegidos mientras otros tonos son afectados. +TP_DIRPYREQUALIZER_THRESHOLD;Umbral +TP_DIRPYREQUALIZER_TOOLTIP;Reduce los elementos extraños producidos en la transición entre los colores de piel (matiz, crominancia, luminancia) y el resto de la imagen. +TP_DISTORTION_AMOUNT;Cantidad +TP_DISTORTION_AUTO;Auto corrección de distorsión +TP_DISTORTION_AUTO_TIP;(Experimental) Corrige automáticamente la distorsión de la lente para algunas cámaras (Micro 4/3, algunas compactas DC, etc.) +TP_DISTORTION_LABEL;Corrección de Distorsión +TP_EPD_EDGESTOPPING;Parada en los bordes +TP_EPD_LABEL;Mapeo tonal +TP_EPD_REWEIGHTINGITERATES;Iteraciones de reponderación +TP_EPD_SCALE;Escala +TP_EPD_STRENGTH;Intensidad +TP_EPD_TOOLTIP;El mapeo tonal puede hacerse en modo Lab (estándar) y en modo CIECAM02.\n\nPara activar mapeo tonal modo CIECAM02 haga los siguientes ajustes:\n1. CIECAM02\n2. Algoritmo="Brillo + Colorido (QM)"\n3. "Mapeo tonal usando Brillo CIECAM02 (Q)" +TP_EXPOSURE_AUTOLEVELS;Niveles automáticos +TP_EXPOSURE_AUTOLEVELS_TIP;Ejecuta Niveles Automáticos. Establece automáticamente los valores de los parámetros basándose en el análisis de la imagen.\nHabilita la reconstrucción de luces altas si es necesario +TP_EXPOSURE_BLACKLEVEL;Nivel de Negro +TP_EXPOSURE_BRIGHTNESS;Brillo +TP_EXPOSURE_CLIP;Recorte % +TP_EXPOSURE_CLIP_TIP;Fracción de los píxeles que se recortará en una operación de Niveles Automáticos +TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Umbral de recuperación de luces altas +TP_EXPOSURE_COMPRHIGHLIGHTS;Compresión de luces altas +TP_EXPOSURE_COMPRSHADOWS;Compresión de sombras +TP_EXPOSURE_CONTRAST;Contraste +TP_EXPOSURE_CURVEEDITOR1;Curva tonal 1 +TP_EXPOSURE_CURVEEDITOR2;Curva tonal 2 +TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Por favor, consulte RawPedia para aprender cómo obtener mejores resultados usando dos curvas tonales +TP_EXPOSURE_EXPCOMP;Compensación de exposición +TP_EXPOSURE_LABEL;Exposición +TP_EXPOSURE_SATURATION;Saturación +TP_EXPOSURE_TCMODE_FILMLIKE;Similar a película +TP_EXPOSURE_TCMODE_LABEL1;Curva modo 1 +TP_EXPOSURE_TCMODE_LABEL2;Curva modo 2 +TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Mezcla de saturación y valor +TP_EXPOSURE_TCMODE_STANDARD;Estándar +TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Estándar ponderado +TP_EXPOS_BLACKPOINT_LABEL;Raw - Puntos Negros +TP_EXPOS_WHITEPOINT_LABEL;Raw - Puntos Blancos +TP_FILMSIMULATION_LABEL;Simulación de Fílmico +TP_FILMSIMULATION_STRENGTH;Intensidad +TP_FILMSIMULATION_ZEROCLUTSFOUND;Seleccionar el directorio HaldCLUT en Preferencias +TP_FLATFIELD_AUTOSELECT;Auto selección +TP_FLATFIELD_BLURRADIUS;Radio de difuminado +TP_FLATFIELD_BLURTYPE;Tipo de difuminado +TP_FLATFIELD_BT_AREA;Área +TP_FLATFIELD_BT_HORIZONTAL;Horizontal +TP_FLATFIELD_BT_VERTHORIZ;Vert. + Horiz. +TP_FLATFIELD_BT_VERTICAL;Vertical +TP_FLATFIELD_CLIPCONTROL;Control de Recorte +TP_FLATFIELD_CLIPCONTROL_TOOLTIP;El Control de Recorte evita la perdida de detalle en las luces altas causadas por la aplicación del Campo Plano. Si ya hubiera perdida de detalle en las altas luces antes de aplicar el Campo Plano, el Control de Recorte puede conducir a una dominante de color. +TP_FLATFIELD_LABEL;Campo plano +TP_GAMMA_CURV;Gamma +TP_GAMMA_FREE;Gamma libre +TP_GAMMA_OUTPUT;Gamma de salida +TP_GAMMA_SLOP;Pendiente (lineal) +TP_GENERAL_11SCALE_TOOLTIP;El efecto de esta herramienta o el de alguno de sus componentes solo es apreciable en escala de vista previa 1:1 +TP_GRADIENT_CENTER;Centro +TP_GRADIENT_CENTER_X;Centro X +TP_GRADIENT_CENTER_X_TOOLTIP;Ancla X del punto de rotación:\n-100 = borde izquierdo\n 0 = centro\n+100 = borde derecho +TP_GRADIENT_CENTER_Y;Centro Y +TP_GRADIENT_CENTER_Y_TOOLTIP;Ancla Y del punto de rotación:\n-100=borde superior\n0=centro\n+100=borde inferior +TP_GRADIENT_DEGREE;Ángulo +TP_GRADIENT_DEGREE_TOOLTIP;Ángulo de rotación en grados +TP_GRADIENT_FEATHER;Difuminado +TP_GRADIENT_FEATHER_TOOLTIP;Ancho del gradiente expresado como porcentaje de la diagonal de la imagen +TP_GRADIENT_LABEL;Filtro gradiente +TP_GRADIENT_STRENGTH;Intensidad +TP_GRADIENT_STRENGTH_TOOLTIP;Fuerza del filtro en pasos de exposición +TP_HLREC_BLEND;Mezcla +TP_HLREC_CIELAB;Mezclado CIELab +TP_HLREC_COLOR;Propagación de color +TP_HLREC_ENA_TOOLTIP;Puede activarse mediante exposición automática +TP_HLREC_LABEL;Recuperación de luces altas +TP_HLREC_LUMINANCE;Recuperación de luminancia +TP_HLREC_METHOD;Método: +TP_HSVEQUALIZER_CHANNEL;Canal +TP_HSVEQUALIZER_HUE;H +TP_HSVEQUALIZER_LABEL;Ecualizador HSV +TP_HSVEQUALIZER_SAT;S +TP_HSVEQUALIZER_VAL;V +TP_ICM_BLENDCMSMATRIX;Mezclar las luces altas ICC con matriz +TP_ICM_BLENDCMSMATRIX_TOOLTIP;Permite recuperar luces altas quemadas cuando se usan perfiles ICC basados en LUT +TP_ICM_DCPILLUMINANT;Iluminante +TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolado +TP_ICM_DCPILLUMINANT_TOOLTIP;Seleccione el Iluminante a emplear. El valor predeterminado es "interpolado", que es una mezcla entre dos basados en el Balance de Blancos. Este ajuste es posible solo si un Iluminante dual DCP con soporte de interpolación es seleccionado. +TP_ICM_INPUTCAMERAICC;Perfil de la cámara (auto elegida) +TP_ICM_INPUTCAMERAICC_TOOLTIP;Usa perfil de color de entrada específico de la cámara en RawTherapee. Estos perfiles son más precisos que los de matriz de color simple. No están disponibles para todas las cámaras. Estos perfiles son guardados en las carpetas /iccprofiles/input y /dcpprofiles instaladas con RT. Son automáticamente elegidas buscando coincidencia entre el nombre del archivo con la marca y el modelo exacto de la cámara. +TP_ICM_INPUTCAMERA;Cámara estándar +TP_ICM_INPUTCAMERA_TOOLTIP;Usa una versión de la matriz de color simple de dcraw mejorada por RT (cualquiera que esté disponible basándose en el modelo de la cámara) o incrustada en DNG +TP_ICM_INPUTCUSTOM;A medida +TP_ICM_INPUTCUSTOM_TOOLTIP;Seleccione su propio perfil de color DCP/ICC para la cámara +TP_ICM_INPUTDLGLABEL;Seleccionar perfil DCP/ICC de entrada... +TP_ICM_INPUTEMBEDDED;Usar incrustado, si es posible +TP_ICM_INPUTEMBEDDED_TOOLTIP;Usar el perfil de color incrustado en archivos no raw +TP_ICM_INPUTNONE;Sin perfil de color +TP_ICM_INPUTNONE_TOOLTIP;No usar ningún perfil de color. Utilizar sólo en casos especiales. +TP_ICM_INPUTPROFILE;Perfil de entrada +TP_ICM_LABEL;Gestión de color +TP_ICM_NOICM;Sin ICM: Salida sRGB +TP_ICM_OUTPUTPROFILE;Perfil de salida +TP_ICM_SAVEREFERENCE;Guardar como referencia para el perfilado +TP_ICM_SAVEREFERENCE_TOOLTIP;Guardar la imagen TIFF lineal antes de aplicar el perfil de entrada. El resultado puede ser utilizado para fines de calibración y la generación de un perfil de cámara. +TP_ICM_TONECURVE;Usar la curva tonal en DCP +TP_ICM_TONECURVE_TOOLTIP;Activa el uso de las curvas de tono que pueden contener los perfiles DCP. Este ajuste es posible solo si el DCP seleccionado contiene una curva tonal. +TP_ICM_WORKINGPROFILE;Perfil de trabajo +TP_IMPULSEDENOISE_LABEL;Impulsar Reducc. ruido +TP_IMPULSEDENOISE_THRESH;Umbral +TP_LABCURVE_AVOIDCOLORSHIFT;Evitar desplazamiento de colores +TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Encaja los colores dentro de la gama del espacio de color de trabajo y aplica la corrección de Munsell +TP_LABCURVE_BRIGHTNESS;Brillo +TP_LABCURVE_CHROMATICITY;Cromaticidad +TP_LABCURVE_CHROMA_TOOLTIP;Para aplicar mapeo tonal en blanco y negro, establezca la Cromaticidad a -100 +TP_LABCURVE_CONTRAST;Contraste +TP_LABCURVE_CURVEEDITOR;Curva de luminancia +TP_LABCURVE_CURVEEDITOR_A_RANGE1;Verde saturado +TP_LABCURVE_CURVEEDITOR_A_RANGE2;Verde pastel +TP_LABCURVE_CURVEEDITOR_A_RANGE3;Rojo pastel +TP_LABCURVE_CURVEEDITOR_A_RANGE4;Rojo saturado +TP_LABCURVE_CURVEEDITOR_B_RANGE1;Azul saturado +TP_LABCURVE_CURVEEDITOR_B_RANGE2;Azul pastel +TP_LABCURVE_CURVEEDITOR_B_RANGE3;Amarillo pastel +TP_LABCURVE_CURVEEDITOR_B_RANGE4;Amarillo saturado +TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutros +TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Mates +TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastel +TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Saturados +TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Cromaticidad en función de la Cromaticidad C=f(C) +TP_LABCURVE_CURVEEDITOR_CH;CM +TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Cromaticidad en función del Matiz C=f(M) +TP_LABCURVE_CURVEEDITOR_CL;CL +TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Cromaticidad en función de la Luminancia C=f(L) +TP_LABCURVE_CURVEEDITOR_HH;MM +TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Matiz en función del Matiz M=f(M) +TP_LABCURVE_CURVEEDITOR_LC;LC +TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminancia en función de la Cromaticidad L=f(C) +TP_LABCURVE_CURVEEDITOR_LH;LM +TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Luminancia en función del Matiz L=f(M) +TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminancia en función de la Luminancia L=f(L) +TP_LABCURVE_LABEL;Ajustes Lab +TP_LABCURVE_LCREDSK;Restringe LC a tonos rojos y piel +TP_LABCURVE_LCREDSK_TIP;Si se activa, la 'Curva LC' afecta solo a los tonos rojos y piel\nSi se desactiva, se aplica a todos los colores +TP_LABCURVE_RSTPROTECTION;Protección de rojos y tonos piel +TP_LABCURVE_RSTPRO_TOOLTIP;Puede usarse con el deslizador Cromaticidad y con la curva CC. +TP_LENSGEOM_AUTOCROP;Auto recorte +TP_LENSGEOM_FILL;Auto relleno +TP_LENSGEOM_LABEL;Lente / Geometría +TP_LENSPROFILE_LABEL;Perfil de corrección de lente +TP_LENSPROFILE_USECA;Corrección de AC +TP_LENSPROFILE_USEDIST;Corrección de distorsión +TP_LENSPROFILE_USEVIGN;Corrección de viñeteo +TP_NEUTRAL;Neutro +TP_NEUTRAL_TIP;Restablecer controles de exposición a valores neutros\nAplica a los mismos controles que son afectados por Niveles Automáticos, sin importar si usa o no Niveles Automáticos +TP_PCVIGNETTE_FEATHER;Difuminado +TP_PCVIGNETTE_FEATHER_TOOLTIP;Difuminación: \n0=Solo Esquinas\n50=Hasta medio camino al centro\n100=Hasta el Centro +TP_PCVIGNETTE_LABEL;Filtro quitar Viñeteado +TP_PCVIGNETTE_ROUNDNESS;Redondez +TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Redondez:\n0=Rectangular\n50=Elíptica\n100=Circular +TP_PCVIGNETTE_STRENGTH;Intensidad +TP_PCVIGNETTE_STRENGTH_TOOLTIP;Intensidad del filtro en pasos de exposición (alcanzada en las esquinas) +TP_PERSPECTIVE_HORIZONTAL;Horizontal +TP_PERSPECTIVE_LABEL;Perspectiva +TP_PERSPECTIVE_VERTICAL;Vertical +TP_PFCURVE_CURVEEDITOR_CH;Matiz +TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Controla la fuerza de reducción de bordes coloridos (AC):\n\n Alto = más\nbajo = menos. +TP_PREPROCESS_DEADPIXFILT;Filtro Pixel Muerto +TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Trata de eliminar los píxeles muertos. +TP_PREPROCESS_GREENEQUIL;Equilibrado de verdes +TP_PREPROCESS_HOTPIXFILT;Filtro Pixel Caliente +TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Trata de eliminar los píxeles calientes. +TP_PREPROCESS_LABEL;Preprocesado +TP_PREPROCESS_LINEDENOISE;Filtro de ruido de línea +TP_PREPROCESS_NO_FOUND;No encontrado +TP_RAWCACORR_AUTO;Auto corrección +TP_RAWCACORR_CABLUE;Azul +TP_RAWCACORR_CARED;Rojo +TP_RAWEXPOS_BLACKS;Niveles de negro +TP_RAWEXPOS_BLACK_0;Verde 1 (principal) +TP_RAWEXPOS_BLACK_1;Rojo +TP_RAWEXPOS_BLACK_2;Azul +TP_RAWEXPOS_BLACK_3;Verde 2 +TP_RAWEXPOS_BLACK_BLUE;Azul +TP_RAWEXPOS_BLACK_GREEN;Verde +TP_RAWEXPOS_BLACK_RED;Rojo +TP_RAWEXPOS_LINEAR;Corrección de punto blanco +TP_RAWEXPOS_PRESER;Preservación de Luces Altas +TP_RAWEXPOS_RGB;Rojo, Verde, Azul +TP_RAWEXPOS_TWOGREEN;Vincular verdes +TP_RAW_DCBENHANCE;Aplicar paso de mejora DCB +TP_RAW_DCBITERATIONS;Número de iteraciones DCB +TP_RAW_DMETHOD;Método +TP_RAW_DMETHOD_PROGRESSBAR;%1 interpolando mosaico... +TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Refinando la interpolación del mosaico... +TP_RAW_DMETHOD_TOOLTIP;Nota: IGV y LMMSE están dedicados a imágenes tomadas con grandes velocidades ISO +TP_RAW_FALSECOLOR;Pasos de supresión de color falso +TP_RAW_LABEL;Desmosaicado +TP_RAW_LMMSEITERATIONS;Pasos de mejora LMMSE +TP_RAW_LMMSE_TOOLTIP;Agregar gamma (paso 1)\n Agregar mediana (pasos 2,3,4)\nAgregar refinamientos (pasos 5,6) para reducir objetos espurios y mejorar la relación señal a ruido +TP_RAW_SENSOR_BAYER_LABEL;Sensor con matriz Bayer +TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;3-pases da mejores resultados (recomendado para imágenes de ISO bajo).\n1-pase es más rápido y es casi indistinguible del modo 3-pases para imágenes de ISO altas. +TP_RAW_SENSOR_XTRANS_LABEL;Sensor con matriz X-Trans +TP_RESIZE_APPLIESTO;Aplica a: +TP_RESIZE_CROPPEDAREA;Área recortada +TP_RESIZE_FITBOX;Rectángulo límite +TP_RESIZE_FULLIMAGE;Imagen completa +TP_RESIZE_HEIGHT;Altura +TP_RESIZE_H;Al: +TP_RESIZE_LABEL;Cambiar tamaño +TP_RESIZE_LANCZOS;Lanczos +TP_RESIZE_METHOD;Método: +TP_RESIZE_NEAREST;Más cercano +TP_RESIZE_SCALE;Escala +TP_RESIZE_SPECIFY;Especificar: +TP_RESIZE_WIDTH;Anchura +TP_RESIZE_W;An: +TP_RGBCURVES_BLUE;B +TP_RGBCURVES_CHANNEL;Canal +TP_RGBCURVES_GREEN;G +TP_RGBCURVES_LABEL;Curvas RGB +TP_RGBCURVES_LUMAMODE;Modo Luminosidad +TP_RGBCURVES_LUMAMODE_TOOLTIP;Modo Luminosidad permite variar el aporte de los canales Rojo, Verde y Azul a la luminosidad de la imagen, sin modificar el color de la misma. +TP_RGBCURVES_RED;R +TP_ROTATE_DEGREE;Grados +TP_ROTATE_LABEL;Rotar +TP_ROTATE_SELECTLINE;Seleccionar línea recta +TP_SAVEDIALOG_OK_TIP;Atajo Ctrl-Enter +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Luces altas +TP_SHADOWSHLIGHTS_HLTONALW;Ancho tonal de Luces Altas +TP_SHADOWSHLIGHTS_LABEL;Sombras/Luces altas +TP_SHADOWSHLIGHTS_LOCALCONTR;Contraste local +TP_SHADOWSHLIGHTS_RADIUS;Radio +TP_SHADOWSHLIGHTS_SHADOWS;Sombras +TP_SHADOWSHLIGHTS_SHARPMASK;Máscara de enfoque +TP_SHADOWSHLIGHTS_SHTONALW;Ancho tonal de Sombras +TP_SHARPENEDGE_AMOUNT;Cantidad +TP_SHARPENEDGE_LABEL;Bordes +TP_SHARPENEDGE_PASSES;Iteraciones +TP_SHARPENEDGE_THREE;Sólo luminancia +TP_SHARPENING_AMOUNT;Cantidad +TP_SHARPENING_EDRADIUS;Radio +TP_SHARPENING_EDTOLERANCE;Tolerancia de bordes +TP_SHARPENING_HALOCONTROL;Control de halo +TP_SHARPENING_HCAMOUNT;Cantidad +TP_SHARPENING_LABEL;Enfoque +TP_SHARPENING_METHOD;Método +TP_SHARPENING_ONLYEDGES;Enfocar solo bordes +TP_SHARPENING_RADIUS;Radio +TP_SHARPENING_RLD;Deconvolución RL +TP_SHARPENING_RLD_AMOUNT;Cantidad +TP_SHARPENING_RLD_DAMPING;Amortiguación +TP_SHARPENING_RLD_ITERATIONS;Iteraciones +TP_SHARPENING_THRESHOLD;Umbral +TP_SHARPENING_TOOLTIP;Espere un efecto ligeramente diferente cuando es usado en combinación con CIECAM02. Si la diferencia es notable ajuste a su gusto. +TP_SHARPENING_USM;Máscara de enfoque +TP_SHARPENMICRO_AMOUNT;Cantidad +TP_SHARPENMICRO_LABEL;Microcontraste +TP_SHARPENMICRO_MATRIX;Matriz 3×3 en lugar de 5×5 +TP_SHARPENMICRO_UNIFORMITY;Uniformidad +TP_VIBRANCE_AVOIDCOLORSHIFT;Evitar desplazamiento de color +TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH +TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Tonos de piel +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Rojo/Púrpura +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Rojo +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Rojo/Amarillo +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Amarillo +TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Matiz en función de Matiz M=f(M) +TP_VIBRANCE_LABEL;Vibranza +TP_VIBRANCE_PASTELS;Tonos pastel +TP_VIBRANCE_PASTSATTOG;Enlazar tonos pastel y saturados +TP_VIBRANCE_PROTECTSKINS;Proteger tonos de piel +TP_VIBRANCE_PSTHRESHOLD;Umbral de tono pastel/saturado +TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Umbral de saturación +TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;El eje vertical representa los tonos pastel en la parte inferior y los tonos saturados en la parte superior.\nEl eje horizontal representa el rango de saturación. +TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Ponderación de la transición pastel/saturado +TP_VIBRANCE_SATURATED;Tonos saturados +TP_VIGNETTING_AMOUNT;Cantidad +TP_VIGNETTING_CENTER;Centro +TP_VIGNETTING_CENTER_X;Centro X +TP_VIGNETTING_CENTER_Y;Centro Y +TP_VIGNETTING_LABEL;Corrección de viñeteo +TP_VIGNETTING_RADIUS;Radio +TP_VIGNETTING_STRENGTH;Intensidad +TP_WBALANCE_AUTO;Auto +TP_WBALANCE_CAMERA;Cámara +TP_WBALANCE_CLOUDY;Nublado +TP_WBALANCE_CUSTOM;A medida +TP_WBALANCE_DAYLIGHT;Luz de día (soleado) +TP_WBALANCE_EQBLUERED;Ecualizador Azul/Rojo +TP_WBALANCE_EQBLUERED_TOOLTIP;Permite desviarse del comportamiento normal del Balance de Blancos regulando el balance azul/rojo.\nEsto puede ser útil para fotografía en condiciones que:\na) Están lejos de tener una iluminación estándar (p. ej. Subacuático)\nb) Están lejos de las condiciones para las que se hizo la calibración de la cámara\nc) Donde las matrices o perfiles ICC disponibles son inadecuados +TP_WBALANCE_FLASH55;Leica +TP_WBALANCE_FLASH60;Estándar, Canon, Pentax, Olympus +TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta +TP_WBALANCE_FLASH_HEADER;Flash +TP_WBALANCE_FLUO1;F1 - Luz de día +TP_WBALANCE_FLUO2;F2 - Blanco frío +TP_WBALANCE_FLUO3;F3 - Blanco +TP_WBALANCE_FLUO4;F4 - Blanco cálido +TP_WBALANCE_FLUO5;F5 - Luz de día +TP_WBALANCE_FLUO6;F6 - Blanco ligero +TP_WBALANCE_FLUO7;F7 - D65 Simulador luz de día +TP_WBALANCE_FLUO8;F8 - D50 / Sylvania F40 Design +TP_WBALANCE_FLUO9;F9 - Blanco frío deluxe +TP_WBALANCE_FLUO10;F10 - Philips TL85 +TP_WBALANCE_FLUO11;F11 - Philips TL84 +TP_WBALANCE_FLUO12;F12 - Philips TL83 +TP_WBALANCE_FLUO_HEADER;Fluorescente +TP_WBALANCE_GREEN;Tinte +TP_WBALANCE_GTI;GTI +TP_WBALANCE_HMI;HMI +TP_WBALANCE_JUDGEIII;JudgeIII +TP_WBALANCE_LABEL;Balance de blancos +TP_WBALANCE_LAMP_HEADER;Lámpara +TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 +TP_WBALANCE_LED_HEADER;LED +TP_WBALANCE_LED_LSI;LSI Lumelex 2040 +TP_WBALANCE_METHOD;Método +TP_WBALANCE_SHADE;Sombra +TP_WBALANCE_SIZE;Tamaño: +TP_WBALANCE_SOLUX35;Solux 3500K +TP_WBALANCE_SOLUX41;Solux 4100K +TP_WBALANCE_SOLUX47;Solux 4700K (proveedor) +TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) +TP_WBALANCE_SPOTWB;Muestra bal. blancos +TP_WBALANCE_TEMPERATURE;Temperatura +TP_WBALANCE_TUNGSTEN;Tungsteno +TP_WBALANCE_WATER1;Subacuático 1 +TP_WBALANCE_WATER2;Subacuático 2 +TP_WBALANCE_WATER_HEADER;Subacuático +ZOOMPANEL_100;(100%) +ZOOMPANEL_NEWCROPWINDOW;Abrir (nueva) ventana de detalle +ZOOMPANEL_ZOOM100;Zoom al 100%\nAtajo: z +ZOOMPANEL_ZOOMFITSCREEN;Ajustar a pantalla\nAtajo: f +ZOOMPANEL_ZOOMIN;Aumentar Zoom\nAtajo: + +ZOOMPANEL_ZOOMOUT;Reducir Zoom\nAtajo: - + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!CURVEEDITOR_AXIS_IN;I: +!CURVEEDITOR_AXIS_LEFT_TAN;LT: +!CURVEEDITOR_AXIS_OUT;O: +!CURVEEDITOR_AXIS_RIGHT_TAN;RT: +!CURVEEDITOR_EDITPOINT_HINT;Enable edition of node in/out values.\n\nRight-click on a node to select it.\nRight-click on empty space to de-select the node. +!EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels +!FILEBROWSER_POPUPCOLORLABEL0;Label: None +!FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!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_ASIMAGE;As Image +!HISTORY_MSG_299;NR - Chrominance curve +!HISTORY_MSG_300;- +!HISTORY_MSG_301;NR - Luma control +!HISTORY_MSG_302;NR - Chroma method +!HISTORY_MSG_303;NR - Chroma method +!HISTORY_MSG_304;W - Contrast levels +!HISTORY_MSG_305;Wavelet Levels +!HISTORY_MSG_306;W - Preview +!HISTORY_MSG_307;W - Preview +!HISTORY_MSG_308;W - Preview direction +!HISTORY_MSG_309;W - ES - Detail +!HISTORY_MSG_310;W - Residual - Sky tar/prot +!HISTORY_MSG_311;W - Wavelet levels +!HISTORY_MSG_312;W - Residual - Shadows threshold +!HISTORY_MSG_313;W - Chroma - Sat/past +!HISTORY_MSG_314;W - Gamut - Reduce artifacts +!HISTORY_MSG_315;W - Residual - Contrast +!HISTORY_MSG_316;W - Gamut - Skin tar/prot +!HISTORY_MSG_317;W - Gamut - Skin hue +!HISTORY_MSG_318;W - Contrast - Highlight levels +!HISTORY_MSG_319;W - Contrast - Highlight range +!HISTORY_MSG_320;W - Contrast - Shadow range +!HISTORY_MSG_321;W - Contrast - Shadow levels +!HISTORY_MSG_322;W - Gamut - Avoid color shift +!HISTORY_MSG_323;W - ES - Local contrast +!HISTORY_MSG_324;W - Chroma - Pastel +!HISTORY_MSG_325;W - Chroma - Saturated +!HISTORY_MSG_326;W - Chroma - Method +!HISTORY_MSG_327;W - Contrast - Apply to +!HISTORY_MSG_328;W - Chroma - Link strength +!HISTORY_MSG_329;W - Toning - Opacity RG +!HISTORY_MSG_330;W - Toning - Opacity BY +!HISTORY_MSG_331;W - Contrast levels - Extra +!HISTORY_MSG_332;W - Tiling method +!HISTORY_MSG_333;W - Residual - Shadows +!HISTORY_MSG_334;W - Residual - Chroma +!HISTORY_MSG_335;W - Residual - Highlights +!HISTORY_MSG_336;W - Residual - Highlights threshold +!HISTORY_MSG_337;W - Residual - Sky hue +!HISTORY_MSG_338;W - ES - Radius +!HISTORY_MSG_339;W - ES - Strength +!HISTORY_MSG_340;W - Strength +!HISTORY_MSG_341;W - Edge performance +!HISTORY_MSG_342;W - ES - First level +!HISTORY_MSG_343;W - Chroma levels +!HISTORY_MSG_344;W - Meth chroma sl/cur +!HISTORY_MSG_345;W - ES - Local contrast +!HISTORY_MSG_346;W - ES - Local contrast method +!HISTORY_MSG_347;W - Denoise - Level 0 +!HISTORY_MSG_348;W - Denoise - Level 1 +!HISTORY_MSG_349;W - Denoise - Level 2 +!HISTORY_MSG_350;W - ES - Edge detection +!HISTORY_MSG_351;W - Residual - HH curve +!HISTORY_MSG_352;W - Background +!HISTORY_MSG_353;W - ES - Gradient sensitivity +!HISTORY_MSG_354;W - ES - Enhance +!HISTORY_MSG_355;W - ES - Threshold low +!HISTORY_MSG_356;W - ES - Threshold high +!HISTORY_MSG_357;W - Denoise - Link with ES +!HISTORY_MSG_358;W - Gamut - CH +!HISTORY_MSG_359;Hot/Dead - Threshold +!HISTORY_MSG_360;TM Gamma +!HISTORY_MSG_361;W - Final - Chroma balance +!HISTORY_MSG_362;W - Residual - Compression method +!HISTORY_MSG_363;W - Residual - Compression strength +!HISTORY_MSG_364;W - Final - Contrast balance +!HISTORY_MSG_365;W - Final - Delta balance +!HISTORY_MSG_366;W - Residual - Compression gamma +!HISTORY_MSG_367;W - ES - Local contrast curve +!HISTORY_MSG_368;W - Final - Contrast balance +!HISTORY_MSG_369;W - Final - Balance method +!HISTORY_MSG_370;W - Final - Local contrast curve +!MAIN_TAB_INSPECT; Inspect +!MAIN_TAB_WAVELET;Wavelet +!MAIN_TAB_WAVELET_TOOLTIP;Shortcut: Alt-w +!NAVIGATOR_B;B: +!NAVIGATOR_G;G: +!NAVIGATOR_H;H: +!NAVIGATOR_LAB_A;a*: +!NAVIGATOR_LAB_B;b*: +!NAVIGATOR_LAB_L;L*: +!NAVIGATOR_R;R: +!NAVIGATOR_S;S: +!NAVIGATOR_V;V: +!PARTIALPASTE_EQUALIZER;Wavelet Equalizer +!PARTIALPASTE_GRADIENT;Graduated filter +!PARTIALPASTE_WAVELETGROUP;Wavelet processing +!PREFERENCES_AUTLISLOW;Low +!PREFERENCES_AUTLISMAX;Max - Average of all tiles +!PREFERENCES_AUTLISSTD;High +!PREFERENCES_AUTLISVLOW;None +!PREFERENCES_AUTLOW;Low +!PREFERENCES_AUTSTD;Standard +!PREFERENCES_CIEART_FRAME;CIECAM02-Specific Settings +!PREFERENCES_CLUTSCACHE;HaldCLUT Cache +!PREFERENCES_CLUTSCACHE_LABEL;Maximum number of cached CLUTs +!PREFERENCES_CURVEBBOXPOS;Position of curve copypasta buttons +!PREFERENCES_CURVEBBOXPOS_ABOVE;Above +!PREFERENCES_CURVEBBOXPOS_BELOW;Below +!PREFERENCES_CURVEBBOXPOS_LEFT;Left +!PREFERENCES_CURVEBBOXPOS_RIGHT;Right +!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_EXPAUT;Expert +!PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT;Same thumbnail height between the Editor's panel 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_GREYSC18;Yb=18 CIE L#50 +!PREFERENCES_GREYSCA;Automatic +!PREFERENCES_GREYSC;Scene Yb luminance (%) +!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_LEVAUTDN;Denoising level +!PREFERENCES_LEVDN;Cell size +!PREFERENCES_LISS;Auto multi-zone smoothing +!PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders +!PREFERENCES_MAX;Maxi (Tile) +!PREFERENCES_MED;Medium (Tile/2) +!PREFERENCES_MIN;Mini (100x115) +!PREFERENCES_NAVIGATIONFRAME;Navigation +!PREFERENCES_NOISE;Noise Reduction +!PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Overlay filenames on thumbnails in the editor pannel +!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_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_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_SHOWFILMSTRIPTOOLBAR;Show filmstrip toolbar +!PREFERENCES_SIMPLAUT;Tool mode +!PREFERENCES_SMA;Small (250x287) +!PREFERENCES_STDAUT;Standard +!PREFERENCES_TIMAX;High +!PREFERENCES_TINB;Number of tiles +!PREFERENCES_TISTD;Standard +!PREFERENCES_WAVLEV;Increase wavelet level in quality 'high' +!PREFERENCES_WLONE;One level +!PREFERENCES_WLTWO;Two levels +!PREFERENCES_WLZER;No +!TP_CROP_GTHARMMEANS;Harmonic Means +!TP_CROP_GTTRIANGLE1;Golden Triangles 1 +!TP_CROP_GTTRIANGLE2;Golden Triangles 2 +!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_ABM;Chroma only +!TP_DIRPYRDENOISE_AUTO;Automatic global +!TP_DIRPYRDENOISE_AUTO_TOOLTIP;Try to evaluate chroma noise\nBe careful, this calculation is average, and is quite subjective ! +!TP_DIRPYRDENOISE_AUT;Automatic global +!TP_DIRPYRDENOISE_C2TYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CCCURVE;Chrominance curve +!TP_DIRPYRDENOISE_CHROMAFR;Chrominance +!TP_DIRPYRDENOISE_CTYPE;Auto method +!TP_DIRPYRDENOISE_CTYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nAutomatic multi-zones\nNo preview - works only during saving, but using the "Preview" method by matching the tile size and center to the preview size and center you can get an idea of the expected results.\nThe image is divided into tiles (about 10 to 70 depending on image size) and each tile receives its own chrominance noise reduction settings.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CURVEEDITOR_CC;Chroma +!TP_DIRPYRDENOISE_CURVEEDITOR_CC_TOOLTIP;Increase (multiply) the value of all chrominance sliders.\nThis curve lets you adjust the strength of chromatic noise reduction as a function of chromaticity, for instance to increase the action in areas of low saturation and to decrease it in those of high saturation. +!TP_DIRPYRDENOISE_LPLABM;Weighted L* (little) + a*b* (normal) +!TP_DIRPYRDENOISE_LTYPE;Luminance control +!TP_DIRPYRDENOISE_LUMAFR;Luminance +!TP_DIRPYRDENOISE_LUMAFR_TOOLTIP;Wavelet on luminance and Fourier transform for luminance detail +!TP_DIRPYRDENOISE_MANU;Manual +!TP_DIRPYRDENOISE_MAN;Manual +!TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - +!TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 +!TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. +!TP_DIRPYRDENOISE_PON;Auto multi-zones +!TP_DIRPYRDENOISE_PREVLABEL;Preview size=%1, Center: Px=%2 Py=%3 +!TP_DIRPYRDENOISE_PREV;Preview +!TP_DIRPYRDENOISE_PRE;Preview multi-zones +!TP_DIRPYRDENOISE_SLI;Slider +!TP_DIRPYRDENOISE_TILELABEL;Tile size=%1, Center: Tx=%2 Ty=%3 +!TP_DIRPYREQUALIZER_ARTIF;Reduce artifacts +!TP_EPD_GAMMA;Gamma +!TP_EXPOSURE_TCMODE_LUMINANCE;Luminance +!TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance +!TP_RAW_HD;Threshold +!TP_RAW_HD_TOOLTIP;Lower values make hot/dead pixel detection more aggressive, but false positives may lead to artifacts. If you notice any artifacts appearing when enabling the Hot/Dead Pixel Filters, gradually increase the threshold value until they disappear. +!TP_WAVELET_1;Level 1 +!TP_WAVELET_2;Level 2 +!TP_WAVELET_3;Level 3 +!TP_WAVELET_4;Level 4 +!TP_WAVELET_5;Level 5 +!TP_WAVELET_6;Level 6 +!TP_WAVELET_7;Level 7 +!TP_WAVELET_8;Level 8 +!TP_WAVELET_9;Level 9 +!TP_WAVELET_ALL;All levels in all directions +!TP_WAVELET_APPLYTO;Apply To +!TP_WAVELET_AVOID;Avoid color shift +!TP_WAVELET_B0;Black +!TP_WAVELET_B1;Grey +!TP_WAVELET_B2;Residual +!TP_WAVELET_BACUR;Curve +!TP_WAVELET_BALANCE;Contrast balance d/v-h +!TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chromaticity or residual tone mapping are activated, the effect due to balance is amplified. +!TP_WAVELET_BALCHRO;Chroma balance +!TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chromaticity balance. +!TP_WAVELET_BANONE;None +!TP_WAVELET_BASLI;Slider +!TP_WAVELET_BATYPE;Contrast balance method +!TP_WAVELET_CCURVE;Local contrast +!TP_WAVELET_CH1;Whole chromaticity range +!TP_WAVELET_CH2;Saturated/pastel +!TP_WAVELET_CH3;Link contrast levels +!TP_WAVELET_CHCU;Curve +!TP_WAVELET_CHRO;Saturated/pastel threshold +!TP_WAVELET_CHRO_TOOLTIP;Sets the wavelet level which will be the threshold between saturated and pastel colors.\n1-x: saturated\nx-9: pastel\n\nIf the value exceeds the amount of wavelet levels you are using then it will be ignored. +!TP_WAVELET_CHR;Chroma-contrast link strength +!TP_WAVELET_CHR_TOOLTIP;Adjusts chromaticity as a function of "contrast levels" and "chroma-contrast link strength" +!TP_WAVELET_CHSL;Sliders +!TP_WAVELET_CHTYPE;Chrominance method +!TP_WAVELET_COLORT;Opacity Red-Green +!TP_WAVELET_COMBOTH;Both +!TP_WAVELET_COMPCONT;Contrast +!TP_WAVELET_COMPGAMMA;Compression gamma +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjusting the gamma of the residual image allow you to equilibrate the data and histogram. +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjust gamma for residual image and compression.\nAllow to equilibrate data and histogram +!TP_WAVELET_COMPTM;Tone mapping +!TP_WAVELET_CONTEDIT;'After' Contrast curve +!TP_WAVELET_CONTEDIT;'After' contrast curve +!TP_WAVELET_CONTRAST_MINUS;Contrast - +!TP_WAVELET_CONTRAST_PLUS;Contrast + +!TP_WAVELET_CONTRA;Contrast +!TP_WAVELET_CONTRA_TOOLTIP;Changes contrast of the residual image. +!TP_WAVELET_CONTR;Gamut +!TP_WAVELET_CTYPE;Chrominance control +!TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modifies local contrast as a function of the original local contrast (absciss)\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 100..300)\n66% absciss represents standard deviation of local contrast (real value about 300..800)\n100% represents maximum (real value about 3000..8000) +!TP_WAVELET_CURVEEDITOR_CH;Contrast levels=f(Hue) +!TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modifies each level's contrast as a function oh hue.\nTake care not to overwrite changes made with the Gamut Hue controls.\nThe curve will only have an effect when wavelet contrast level sliders are non-zero. +!TP_WAVELET_CURVEEDITOR_CL;L +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Applies a final contrast luminance curve at the end of the wavelet treatment. +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Apply a contrast luminance curve at the end of wavelet level threatment +!TP_WAVELET_CURVEEDITOR_HH;HH +!TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modifies the residual image's hue as a function of hue. +!TP_WAVELET_DALL;All directions +!TP_WAVELET_DAUB;Edge performance +!TP_WAVELET_DAUB_TOOLTIP;Changes Daubechies coefficients:\nD4 = Standard,\nD14 = Often best performance, 10% more time-intensive.\n\nAffects edge detection as well as the general quality of the firsts levels. However the quality is not strictly related to this coefficient and can vary with images and uses. +!TP_WAVELET_DISP;Preview Settings +!TP_WAVELET_DONE;Vertical +!TP_WAVELET_DTHR;Diagonal +!TP_WAVELET_DTWO;Horizontal +!TP_WAVELET_EDCU;Curve +!TP_WAVELET_EDGCONT;Local contrast +!TP_WAVELET_EDGCONT_TOOLTIP;Adjusting the points to the left decreases contrast, and to the right increases it.\nBottom-left, Top-Left, Top-Right, Bottom-right represent respectively local contast for low values, mean, mean+stdev, maxima +!TP_WAVELET_EDGEDETECTTHR2;Threshold high (detection) +!TP_WAVELET_EDGEDETECTTHR;Threshold low (noise) +!TP_WAVELET_EDGEDETECTTHR_TOOLTIP;This adjuster lets you target edge detection for example to avoid applying edge sharpness to fine details, such as noise in the sky. +!TP_WAVELET_EDGEDETECT;Gradient sensitivity +!TP_WAVELET_EDGEDETECT_TOOLTIP;Moving the slider to the right increases edge sensitivity. This affects local contrast, edge settings and noise. +!TP_WAVELET_EDGE;Edge Sharpness +!TP_WAVELET_EDGREINF_TOOLTIP;Reinforce or reduce the action of the first level, do the opposite to the second level, and leave the rest unchanged. +!TP_WAVELET_EDGTHRESH;Detail +!TP_WAVELET_EDGTHRESH_TOOLTIP;Change the repartition between the first levels and the others. The higher the threshold the more the action is centred on the first levels. Be careful with negative values, they increase the action of high levels and can introduce artifacts. +!TP_WAVELET_EDRAD;Radius +!TP_WAVELET_EDRAD_TOOLTIP;This radius adjustment is very different from those in other sharpening tools. Its value is compared to each level through a complex function. In this sense, a value of zero still has an effect. +!TP_WAVELET_EDSL;Threshold Sliders +!TP_WAVELET_EDTYPE;Local contrast method +!TP_WAVELET_EDVAL;Strength +!TP_WAVELET_FINAL;Final Touchup +!TP_WAVELET_FINEST;Finest +!TP_WAVELET_HIGHLIGHT;Highlight luminance range +!TP_WAVELET_HS1;Whole luminance range +!TP_WAVELET_HS2;Shadows/Highlights +!TP_WAVELET_HUESKIN;Skin hue +!TP_WAVELET_HUESKIN_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_HUESKY;Sky hue +!TP_WAVELET_HUESKY_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_INF;Below or equal the level +!TP_WAVELET_ITER;Delta balance levels +!TP_WAVELET_ITER_TOOLTIP;Left: increase low levels and reduce high levels,\nRight: reduce low levels and increase high levels. +!TP_WAVELET_LABEL;Wavelet levels +!TP_WAVELET_LARGEST;Coarsest +!TP_WAVELET_LEVCH;Chromaticity +!TP_WAVELET_LEVELS;Wavelet levels +!TP_WAVELET_LEVELS_TOOLTIP;Choose the number of detail levels the image is to be decomposed into. More levels require more RAM and require a longer processing time. +!TP_WAVELET_LEVF;Contrast +!TP_WAVELET_LEVLABEL;Preview maximum possible levels = %1 +!TP_WAVELET_LEVONE;Level 2 +!TP_WAVELET_LEVTWO;Level 3 +!TP_WAVELET_LEVZERO;Level 1 +!TP_WAVELET_LINKEDG;Link with Edge Sharpness' Strength +!TP_WAVELET_LIPST;Enhanced algorithm +!TP_WAVELET_LIPST_TOOLTIP;This algorithm uses Lipschitz regularity to increase edge detection quality at a cost of increased processing time and memory requirements. +!TP_WAVELET_LOWLIGHT;Shadow luminance range +!TP_WAVELET_MEDGREINF;First level +!TP_WAVELET_MEDILEV;Edge detection +!TP_WAVELET_MEDI;Reduce artifacts in blue sky +!TP_WAVELET_NEUTRAL;Neutral +!TP_WAVELET_NOISE;Denoise and Refine +!TP_WAVELET_NOIS;Denoise +!TP_WAVELET_ONE;One level +!TP_WAVELET_OPACITYWL;Final local contrast +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify final local contrast in function of last local contrast (absciss) for all levels decomposition\nTake into account: \na)contrast levels \nb)edge sharpness \nc)contrast balance\nd)decomposition-recomposition\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 200..1000)\n66% absciss represents standard deviation of local contrast (real value about 1000..2000)\n100% represents maximum (real value about 5000..13000) +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify the final local contrast at the end of the wavelet treatment.\n\nThe left side represents the smallest local contrast, progressing to the largest local contrast on the right. +!TP_WAVELET_OPACITYW;Contrast balance d/v-h curve +!TP_WAVELET_OPACITY;Opacity Blue-Yellow +!TP_WAVELET_PASTEL;Pastel chromaticity +!TP_WAVELET_PREVIEWBACK;Background +!TP_WAVELET_PREVIEWLEVELS;Preview +!TP_WAVELET_RE1;Reinforced +!TP_WAVELET_RE2;Unchanged +!TP_WAVELET_RE3;Reduced +!TP_WAVELET_RESCHRO;Chromaticity +!TP_WAVELET_RESCONH;Highlights +!TP_WAVELET_RESCON;Shadows +!TP_WAVELET_RESID;Residual image +!TP_WAVELET_SAT;Saturated chromaticity +!TP_WAVELET_SETTINGS;Wavelet Settings +!TP_WAVELET_SKIN;Skin targetting/protection +!TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected. +!TP_WAVELET_SKY;Sky targetting/protection +!TP_WAVELET_SKY_TOOLTIP;At -100 sky-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 sky-tones are protected while all other tones are affected. +!TP_WAVELET_STRENGTH;Strength +!TP_WAVELET_STREN;Strength +!TP_WAVELET_SUPE;Extra +!TP_WAVELET_SUP;Above the level +!TP_WAVELET_THRESHOLD2;Shadow levels +!TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels between 9 and 9 minus the value will be affected by the shadow luminance range. Other levels will be fully treated. The highest level possible is limited by the highlight level value (9 minus highlight level value). +!TP_WAVELET_THRESHOLD;Highlight levels +!TP_WAVELET_THRESHOLD_TOOLTIP;Only levels beyond the chosen value will be affected by the highlight luminance range. Other levels will be fully treated. The chosen value here limits the highest possible value of the shadow levels. +!TP_WAVELET_THRH;Highlights threshold +!TP_WAVELET_THR;Shadows threshold +!TP_WAVELET_TILESBIG;Big tiles +!TP_WAVELET_TILESFULL;Full image +!TP_WAVELET_TILESIZE;Tiling method +!TP_WAVELET_TILESLIT;Little tiles +!TP_WAVELET_TILES_TOOLTIP;Processing the full image leads to better quality and is the recommended option, while using tiles is a fall-back solution for users with little RAM. Refer to RawPedia for memory requirements. +!TP_WAVELET_TMHIGH;High +!TP_WAVELET_TMLOWHIGH;Low+High +!TP_WAVELET_TMNONE;None +!TP_WAVELET_TMSTD;Standard +!TP_WAVELET_TMSTRENGTH;Compression strength +!TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image. When the value is different from 0, the Strength and Gamma sliders of the Tone Mapping tool in the Exposure tab will become grayed out. +!TP_WAVELET_TMTYPE;Compression method +!TP_WAVELET_TON;Toning +!TP_WAVELET_daub2;D2 - low +!TP_WAVELET_daub4;D4 - standard +!TP_WAVELET_daub6;D6 - standard plus +!TP_WAVELET_daub10;D10 - medium +!TP_WAVELET_daub14;D14 - high +!ZOOMPANEL_ZOOMFITCROPSCREEN;Fit crop to screen\nShortcut: Alt-f diff --git a/rtdata/languages/Euskara b/rtdata/languages/Euskara new file mode 100644 index 000000000..ae7a1a4c0 --- /dev/null +++ b/rtdata/languages/Euskara @@ -0,0 +1,1857 @@ +#01 2008-03-03 Ioritz Ibarguren + +ADJUSTER_RESET_TO_DEFAULT;Hasierako balioetara itzuli +CURVEEDITOR_LINEAR;Lineala +CURVEEDITOR_LOADDLGLABEL;Kurba ireki... +CURVEEDITOR_SAVEDLGLABEL;Kurba gorde... +CURVEEDITOR_TOOLTIPLINEAR;Kurba lineala berrabiarazi +CURVEEDITOR_TOOLTIPLOAD;Artxibo batetik kurba ireki +CURVEEDITOR_TOOLTIPSAVE;Uneko kurba gorde +DIRBROWSER_FOLDERS;Karpetak +EXIFFILTER_APERTURE;Aperture +EXIFFILTER_CAMERA;Camera +EXIFFILTER_FOCALLEN;Focal Length +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Lens +EXIFFILTER_SHUTTER;Shutter +EXIFPANEL_ADDEDITHINT;Add new tag or edit tag +EXIFPANEL_ADDEDIT;Add/Edit +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Enter value +EXIFPANEL_ADDTAGDLG_SELECTTAG;Select tag +EXIFPANEL_ADDTAGDLG_TITLE;Add/Edit Tag +EXIFPANEL_KEEPHINT;Keep the selected tags when writing output file +EXIFPANEL_KEEP;Keep +EXIFPANEL_REMOVEHINT;Remove the selected tags when writing output file +EXIFPANEL_REMOVE;Remove +EXIFPANEL_RESETALLHINT;Reset all tags to their original values +EXIFPANEL_RESETALL;Reset All +EXIFPANEL_RESETHINT;Reset the selected tags to their original values +EXIFPANEL_RESET;Reset +EXIFPANEL_SUBDIRECTORY;Subdirectory +FILEBROWSER_APPLYPROFILE;Apply profile +FILEBROWSER_CLEARPROFILE;Clear profile +FILEBROWSER_COPYPROFILE;Copy profile +FILEBROWSER_DELETEDLGLABEL;File delete confirmation +FILEBROWSER_DELETEDLGMSG;Are you sure you want to delete the selected %1 files? +FILEBROWSER_EMPTYTRASHHINT;Permanently delete the files of the trash +FILEBROWSER_EMPTYTRASH;Empty Trash +FILEBROWSER_PARTIALPASTEPROFILE;Partial paste +FILEBROWSER_PASTEPROFILE;Paste profile +FILEBROWSER_POPUPCANCELJOB;Cancel job +FILEBROWSER_POPUPMOVEEND;Move to end of queue +FILEBROWSER_POPUPMOVEHEAD;Move to head of queue +FILEBROWSER_POPUPOPENINEDITOR;Open in Editor +FILEBROWSER_POPUPOPEN;Open +FILEBROWSER_POPUPPROCESS;Put to processing queue +FILEBROWSER_POPUPREMOVE;Remove from filesystem +FILEBROWSER_POPUPRENAME;Rename +FILEBROWSER_POPUPSELECTALL;Select all +FILEBROWSER_POPUPTRASH;Move to trash +FILEBROWSER_POPUPUNRANK;Unrank +FILEBROWSER_POPUPUNTRASH;Remove from trash +FILEBROWSER_RENAMEDLGLABEL;Rename file +FILEBROWSER_RENAMEDLGMSG;Rename file "%1" to: +FILEBROWSER_SHOWDIRHINT;Show all images of the directory +FILEBROWSER_SHOWRANK1HINT;Show images ranked as 1 star +FILEBROWSER_SHOWRANK2HINT;Show images ranked as 2 star +FILEBROWSER_SHOWRANK3HINT;Show images ranked as 3 star +FILEBROWSER_SHOWRANK4HINT;Show images ranked as 4 star +FILEBROWSER_SHOWRANK5HINT;Show images ranked as 5 star +FILEBROWSER_SHOWTRASHHINT;Show content of the trash +FILEBROWSER_SHOWUNRANKHINT;Show unranked images +FILEBROWSER_STARTPROCESSINGHINT;Start processing/saving of images in the queue +FILEBROWSER_STARTPROCESSING;Start Processing +FILEBROWSER_STOPPROCESSINGHINT;Stop processing of images +FILEBROWSER_STOPPROCESSING;Stop processing +FILEBROWSER_THUMBSIZE;Thumb. size +FILEBROWSER_ZOOMINHINT;Increase thumbnail size +FILEBROWSER_ZOOMOUTHINT;Decrease thumbnail size +GENERAL_ABOUT;Honi buruz +GENERAL_CANCEL;Baztertu +GENERAL_DISABLED;Ezeztatua +GENERAL_DISABLE;Ezestatu +GENERAL_ENABLED;Gaitua +GENERAL_ENABLE;Gaitu +GENERAL_LANDSCAPE;Paisaia +GENERAL_NA;n/a +GENERAL_NO;Ez +GENERAL_OK;Onartu +GENERAL_PORTRAIT;Erretratua +GENERAL_SAVE;Gorde +HISTOGRAM_TOOLTIP_B;Erakutsi/Ezkutatu urdin histograma +HISTOGRAM_TOOLTIP_G;Erakutsi/Ezkutatu berde histograma +HISTOGRAM_TOOLTIP_L;Erakutsi/Ezkutatu CIELAB argitasun histograma +HISTOGRAM_TOOLTIP_R;Erakutsi/Ezkutatu gorri histograma +HISTORY_CHANGED;Changed +HISTORY_CUSTOMCURVE;Neurriko kurba +HISTORY_DELSNAPSHOT;Argazkia kendu +HISTORY_FROMCLIPBOARD;From clipboard +HISTORY_LABEL;Historia +HISTORY_MSG_1;Argazki irekia +HISTORY_MSG_2;Profila irekia +HISTORY_MSG_3;Profila aldatua +HISTORY_MSG_4;Historia arakatu +HISTORY_MSG_5;Argitasuna +HISTORY_MSG_6;Kontrastea +HISTORY_MSG_7;Beltza +HISTORY_MSG_8;Esposizio konpentsazioa +HISTORY_MSG_9;Argi konpresioa +HISTORY_MSG_10;Itzal konpresioa +HISTORY_MSG_11;Tonu kurba +HISTORY_MSG_12;Auto-esposizioa +HISTORY_MSG_13;Esposizio mozketa +HISTORY_MSG_14;Liminantzia argitasuna +HISTORY_MSG_15;Luminantzia kontrastea +HISTORY_MSG_16;Luminantzia beltza +HISTORY_MSG_17;Liminantzia argi konpresioa +HISTORY_MSG_18;Luminantzia itzal konpresioa +HISTORY_MSG_19;Luminantzia kurba +HISTORY_MSG_20;Fokatzea +HISTORY_MSG_21;Fokatze erradioa +HISTORY_MSG_22;Fokatze kopurua +HISTORY_MSG_23;Fokatze muga +HISTORY_MSG_24;Ertzak bakarrik fokatu +HISTORY_MSG_25;Ertz detekzio erradio fokatzea +HISTORY_MSG_26;Ertz tolerantzia fokatzea +HISTORY_MSG_27;Halo kontrol fokatzea +HISTORY_MSG_28;Halo kopuru kontrola +HISTORY_MSG_29;Fokatze metodoa +HISTORY_MSG_30;Dekonboluzio erradioa +HISTORY_MSG_31;Dekonboluzio kopurua +HISTORY_MSG_32;Dekonboluzio indargetzea +HISTORY_MSG_33;Dekonboluzio iterazioak +HISTORY_MSG_34;Kolore mozketa ekidin +HISTORY_MSG_35;Saturazio mugatzailea +HISTORY_MSG_36;Saturazio muga +HISTORY_MSG_37;Koloreak jaso +HISTORY_MSG_38;Zuri balantze metodoa +HISTORY_MSG_39;Kolore tenperatura +HISTORY_MSG_40;Zuri balantze tonua +HISTORY_MSG_41;"A" kolore aldaketa +HISTORY_MSG_42;"B" kolore aldaketa +HISTORY_MSG_43;Luminantzia zarata murrizketa +HISTORY_MSG_44;Lum. zar. murr. erradioa +HISTORY_MSG_45;Lum. zar. murr. ertz tolerantzia +HISTORY_MSG_46;Kolore zarata murrizketa +HISTORY_MSG_47;Kol. zar. murr. erradioa +HISTORY_MSG_48;Kol. zar. murr. ertz tolerantzia +HISTORY_MSG_49;Kol. zar. murr. ertzekiko sentikorra +HISTORY_MSG_50;Itzal/Argi tresna +HISTORY_MSG_51;Argiak jaso +HISTORY_MSG_52;Itzalak jaso +HISTORY_MSG_53;Argi tonu zabalera +HISTORY_MSG_54;Itzal tonu zabalera +HISTORY_MSG_55;Tokiko kontrastea +HISTORY_MSG_56;Itzal/Argi erradioa +HISTORY_MSG_57;Biraketa arrunta +HISTORY_MSG_58;Horizontalki irauli +HISTORY_MSG_59;Bertikalki irauli +HISTORY_MSG_60;Biraketa +HISTORY_MSG_61;Biraketa +HISTORY_MSG_62;Objetibo deformazio zuzenketa +HISTORY_MSG_63;Lastermarka hautatua +HISTORY_MSG_64;Argazkia moztu +HISTORY_MSG_65;C/A zuzenketa +HISTORY_MSG_66;Distira berreskurapena +HISTORY_MSG_67;Distira berreskurapen kopurua +HISTORY_MSG_68;Distira berreskurapen metodoa +HISTORY_MSG_69;Lan kolore esparrua +HISTORY_MSG_70;Irteera kolore esparrua +HISTORY_MSG_71;Sarrera kolore esparrua +HISTORY_MSG_72;Iluntze zuzenketa +HISTORY_MSG_73;Kanal nahastainlea +HISTORY_MSG_74;Eskala tamaina aldaketa +HISTORY_MSG_75;Tamaina aldaketa metodoa +HISTORY_MSG_76;Exif Metadata +HISTORY_MSG_77;IPTC Metadata +HISTORY_MSG_78;Data specified for resize +HISTORY_MSG_79;Resize width +HISTORY_MSG_80;Resize height +HISTORY_MSG_81;Resize enabled +HISTORY_NEWSNAPSHOT;Argazki berria +HISTORY_SNAPSHOTS;Argazkiak +HISTORY_SNAPSHOT;Argazkia +IPTCPANEL_AUTHORSPOSITIONHINT;Title of the creator or creators of the object (By-line Title). +IPTCPANEL_AUTHORSPOSITION;Author's position +IPTCPANEL_AUTHOR;Author +IPTCPANEL_CAPTIONHINT;A textual description of the data (Caption - Abstract) +IPTCPANEL_CAPTIONWRITERHINT;The name of the person involved in the writing, editing or correcting the image or caption/abstract (Writer - Editor) +IPTCPANEL_CAPTIONWRITER;Caption Writer +IPTCPANEL_CAPTION;Caption +IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider (Category). +IPTCPANEL_CATEGORY;Category +IPTCPANEL_CITYHINT;City of image origin (City). +IPTCPANEL_CITY;City +IPTCPANEL_COPYHINT;Copy IPTC settings to clipboard +IPTCPANEL_COPYRIGHTHINT;Any necessary copyright notice (Copyright Notice). +IPTCPANEL_COPYRIGHT;Copyright +IPTCPANEL_COUNTRYHINT;The name of the country/primary location where the image was created (Country - Primary Location Name). +IPTCPANEL_COUNTRY;Country +IPTCPANEL_CREDITHINT;Identifies the provider of the image, not necessarily the owner/creator (Credit). +IPTCPANEL_CREDIT;Credit +IPTCPANEL_DATECREATEDHINT;The date the intellectual content of the image was created; Format: JJJJMMTT (Date Created). +IPTCPANEL_DATECREATED;Date Created +IPTCPANEL_EMBEDDEDHINT;Reset to IPTC data embedded in the image file +IPTCPANEL_EMBEDDED;Embedded +IPTCPANEL_HEADLINEHINT;A publishable entry providing a synopsis of the contents of the image (Headline). +IPTCPANEL_HEADLINE;Headline +IPTCPANEL_INSTRUCTIONSHINT;Other editorial instructions concerning the use of the image (Special Instructions). +IPTCPANEL_INSTRUCTIONS;Instructions +IPTCPANEL_KEYWORDSHINT;Used to indicate specific information retrieval words (Keywords). +IPTCPANEL_KEYWORDS;Keywords +IPTCPANEL_PASTEHINT;Paste IPTC settings from clipboard +IPTCPANEL_PROVINCEHINT;The Province/State where the image originates (Province-State). +IPTCPANEL_PROVINCE;Province +IPTCPANEL_RESETHINT;Reset to profile default +IPTCPANEL_RESET;Reset +IPTCPANEL_SOURCEHINT;The original owner of the intellectual content of the image (Source). +IPTCPANEL_SOURCE;Source +IPTCPANEL_SUPPCATEGORIESHINT;Further refines the subject of the image (Supplemental Categories). +IPTCPANEL_SUPPCATEGORIES;Suppl. Categories +IPTCPANEL_TITLEHINT;A shorthand reference for the image (Object Name). +IPTCPANEL_TITLE;Title +IPTCPANEL_TRANSREFERENCEHINT;A code representing the location of original transmission (Original Transmission Reference). +IPTCPANEL_TRANSREFERENCE;Trans. Reference +MAIN_BUTTON_PREFERENCES;Ezarpenak +MAIN_BUTTON_SAVE;Irudia gorde +MAIN_BUTTON_SENDTOEDITOR;Send to editor +MAIN_FRAME_BATCHQUEUE;Batch Queue +MAIN_FRAME_FILEBROWSER;File Browser +MAIN_FRAME_PLACES;Places +MAIN_FRAME_PLACES_ADD;Add +MAIN_FRAME_PLACES_DEL;Del +MAIN_FRAME_RECENT;Recent Folders +MAIN_MSG_ALREADYEXISTS;Artxiboa jadanik badago. +MAIN_MSG_CANNOTLOAD;Ezin dut irudia ireki +MAIN_MSG_CANNOTSAVE;Errorea irudia gordetzen +MAIN_MSG_CANNOTSTARTEDITOR;Can not start editor. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Please set the correct path in the "Preferences" dialog. +MAIN_MSG_QOVERWRITE;Gainidatzi? +MAIN_TAB_COLOR;Color +MAIN_TAB_DETAIL;Detail +MAIN_TAB_DEVELOP;Develop +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;Exposure +MAIN_TAB_FILTER;Filter +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadata +MAIN_TAB_TRANSFORM;Bihurtu +MAIN_TOOLTIP_HIDEHP;Erakutsi/Ezkutatu ezker panela (historia, shortcut key: H) +MAIN_TOOLTIP_INDCLIPPEDH;Mozturiko argi adierazlea +MAIN_TOOLTIP_INDCLIPPEDS;Mozturiko itzal adierazlea +MAIN_TOOLTIP_QINFO; Irudiaren informazio laburra +PARTIALPASTE_BASICGROUP;Basic settings +PARTIALPASTE_CACORRECTION;C/A correction +PARTIALPASTE_COARSETRANS;90 deg rotation / flipping +PARTIALPASTE_COLORGROUP;Color related settings +PARTIALPASTE_COMPOSITIONGROUP;Composition settings +PARTIALPASTE_CROP;Crop +PARTIALPASTE_DIALOGLABEL;Partial paste processing profile +PARTIALPASTE_DISTORTION;Distortion correction +PARTIALPASTE_EXIFCHANGES;Changes to exif data +PARTIALPASTE_EXPOSURE;Exposure +PARTIALPASTE_ICMSETTINGS;ICM settings +PARTIALPASTE_IPTCINFO;IPTC info +PARTIALPASTE_LENSGROUP;Lens related settings +PARTIALPASTE_METAGROUP;Metadata +PARTIALPASTE_RESIZE;Resize +PARTIALPASTE_ROTATION;Rotation +PARTIALPASTE_SHADOWSHIGHLIGHTS;Shadows/Highlights +PARTIALPASTE_SHARPENING;Sharpening +PARTIALPASTE_VIGNETTING;Vignetting correction +PARTIALPASTE_WHITEBALANCE;White balance +PREFERENCES_APPLNEXTSTARTUP;hurrengo abioan aplikatua +PREFERENCES_CACHECLEARALL;Clear All +PREFERENCES_CACHECLEARPROFILES;Clear Profiles +PREFERENCES_CACHECLEARTHUMBS;Clear Thumbnails +PREFERENCES_CACHEMAXENTRIES;Maximal Number of Cache Entries +PREFERENCES_CACHEOPTS;Cache Options +PREFERENCES_CACHETHUMBHEIGHT;Maximal Thumbnail Height +PREFERENCES_CLIPPINGIND;Itzal/argi moztuen adierazlea +PREFERENCES_CMETRICINTENT;Saiakera kolorimetrikoa +PREFERENCES_DATEFORMATHINT;You can use the following formatting strings:\n%y : year\n%m : month\n%d : day\n\nFor example, the hungarian date format is:\n%y/%m/%d +PREFERENCES_DATEFORMAT;Data formatua +PREFERENCES_DEFAULTLANG;Hizkuntza +PREFERENCES_DEFAULTTHEME;Default theme +PREFERENCES_DIRHOME;Etxe karpeta +PREFERENCES_DIRLAST;Azkena ikusitako karpeta +PREFERENCES_DIROTHER;Besterik +PREFERENCES_DIRSELECTDLG;Abioko irudien karpeta hautatu... +PREFERENCES_DIRSOFTWARE;Inatalazio karpeta +PREFERENCES_EDITORCMDLINE;Other command line +PREFERENCES_EXTERNALEDITOR;External editor +PREFERENCES_FBROWSEROPTS;Arakatzailearen aukerak +PREFERENCES_FILEFORMAT;Artxiboen formatua +PREFERENCES_FORIMAGE;Irudi artxiboetarako +PREFERENCES_FORRAW;RAW artxiboetarako +PREFERENCES_GIMPPATH;GIMP installation directory +PREFERENCES_HLTHRESHOLD;Moztutako argien muga +PREFERENCES_ICCDIR;ICC profilen karpeta +PREFERENCES_IMPROCPARAMS;Irudi prozesurako aukera lehenetsiak +PREFERENCES_INTENT_ABSOLUTE;Kolorimetriko absolutua +PREFERENCES_INTENT_PERCEPTUAL;Petzeptuala +PREFERENCES_INTENT_RELATIVE;Kolorimetriko erlatiboa +PREFERENCES_INTENT_SATURATION;Saturazioa +PREFERENCES_MONITORICC;Pantaila profilak +PREFERENCES_OUTDIRFOLDERHINT;Put the saved images to the seledted folder +PREFERENCES_OUTDIRFOLDER;Save to folder +PREFERENCES_OUTDIRTEMPLATEHINT;You can use the following formatting strings:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nThese formatting strings refer to the directories and sub-paths of the path of the raw file.\n\nFor example, if /home/tom/image/02-09-2006/dsc0012.nefhas been opened, the meaning of the formatting strings are:\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\nIf you want to save the output image where the original is, write:\n%p1/%f\n\nIf you want to save the output image in a directory 'converted' located the directory of the original, write:\n%p1/converted/%f\n\nIf you want to save the output image in directory '/home/tom/converted' with keeping the same subdirectory of dates, write:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Use Template +PREFERENCES_OUTDIR;Irteera karpeta +PREFERENCES_PARSEDEXTADDHINT;Type an extension and press this button to append list +PREFERENCES_PARSEDEXTADD;Add Extension +PREFERENCES_PARSEDEXTDELHINT;Delete selected extension from the list +PREFERENCES_PARSEDEXT;Parsed Extensions +PREFERENCES_PROFILEHANDLING;Processing Profile Handling +PREFERENCES_PROFILELOADPR;Profile Loading Priority +PREFERENCES_PROFILEPRCACHE;Profile in Cache +PREFERENCES_PROFILEPRFILE;Profile Next to the Input File +PREFERENCES_PROFILESAVECACHE;Save Processing Parameters to the Cache +PREFERENCES_PROFILESAVEINPUT;Save Processing Parameters Next to the Input File +PREFERENCES_PSPATH;Adobe Photoshop installation directory +PREFERENCES_SELECTLANG;Hizkuntza hautatu +PREFERENCES_SELECTTHEME;Select theme +PREFERENCES_SHOWBASICEXIF;Oinarrizko EXIF datuak bistaratu +PREFERENCES_SHOWDATETIME;Data eta ordua bistratu +PREFERENCES_SHTHRESHOLD;Moztutako itzalen muga +PREFERENCES_STARTUPIMDIR;Abioako irudien karpeta +PREFERENCES_TAB_BROWSER;Artxibo arakatzailea +PREFERENCES_TAB_COLORMGR;Kolore kudeaketa +PREFERENCES_TAB_GENERAL;Orokorra +PREFERENCES_TAB_IMPROC;Irudien prozesua +PROFILEPANEL_LABEL;Prozesu profilak +PROFILEPANEL_LOADDLGLABEL;Profilaren aldagaiak ireki... +PROFILEPANEL_PCUSTOM;Neurrira +PROFILEPANEL_PFILE;Artxibotik +PROFILEPANEL_PLASTSAVED;Gordtako azkena +PROFILEPANEL_SAVEDLGLABEL;Profilaren aldagaiak gorde... +PROFILEPANEL_TOOLTIPCOPY;Copy current profile to clipboard +PROFILEPANEL_TOOLTIPLOAD;Profila artxibotik ireki +PROFILEPANEL_TOOLTIPPASTE; Paste profile from clipboard +PROFILEPANEL_TOOLTIPSAVE;Uneko profila gorde +PROGRESSBAR_LOADING;Irudia ireki... +PROGRESSBAR_LOADJPEG;JPG artxiboa irekitzen... +PROGRESSBAR_LOADPNG;PNG artxiboa irekitzen... +PROGRESSBAR_LOADTIFF;TIFF artxiboa irekitzen... +PROGRESSBAR_PROCESSING;Irudiaren prozesua... +PROGRESSBAR_READY;Prest +PROGRESSBAR_SAVEJPEG;JPG artxiboa gordetzen... +PROGRESSBAR_SAVEPNG;PNG artxiboa gordetzen... +PROGRESSBAR_SAVETIFF;TIFF artxiboa gordetzen... +QINFO_ISO;ISO +QINFO_NOEXIF;Ez dago EXIF daturik. +SAVEDLG_FILEFORMAT;Artxiboaren formatua +SAVEDLG_JPEGQUAL;JPEG kalitatea +SAVEDLG_PNGCOMPR;PNG konpresioa +SAVEDLG_PUTTOQUEUEHEAD;Put to the head of the processing queue +SAVEDLG_PUTTOQUEUETAIL;Put to the end of the processing queue +SAVEDLG_PUTTOQUEUE;Put into processing queue +SAVEDLG_SAVEIMMEDIATELY;Save immediately +SAVEDLG_SAVESPP;Prozesu aldagaiak irudiarekin batera gorde +TOOLBAR_TOOLTIP_CROP;Hautapena moztu (shortcut key: C) +TOOLBAR_TOOLTIP_HAND;Esku tresna (shortcut key: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;Lerro zuzena hautatu (shortcut key: S) +TOOLBAR_TOOLTIP_WB;Zuri balantze puntuala (shortcut key: W) +TP_CACORRECTION_BLUE;Urdina +TP_CACORRECTION_LABEL;C/A zuzenketa +TP_CACORRECTION_RED;Gorria +TP_CHMIXER_BLUE;Urdina +TP_CHMIXER_GREEN;Berdea +TP_CHMIXER_LABEL;Kanal nahastailea +TP_CHMIXER_RED;Gorria +TP_COARSETRAF_TOOLTIP_HFLIP;Horizontalki irauli +TP_COARSETRAF_TOOLTIP_ROTLEFT;Errotazioa ezkerraldera +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Errotazioa eskunialdera +TP_COARSETRAF_TOOLTIP_VFLIP;Bertikalki irauli +TP_CROP_FIXRATIO;Erlazio finkoa: +TP_CROP_GTDIAGONALS;Diagonalen erregela +TP_CROP_GTNONE;Bat ere ez +TP_CROP_GTRULETHIRDS;Herenen erregela +TP_CROP_GUIDETYPE;Gida mota: +TP_CROP_H;H +TP_CROP_LABEL;Moztu +TP_CROP_SELECTCROP; Mozketa hautatu +TP_CROP_W;W +TP_CROP_X;x +TP_CROP_Y;y +TP_DISTORTION_AMOUNT;Kopurua +TP_DISTORTION_LABEL;Distortsioa +TP_EXPOSURE_AUTOLEVELS;Maila auto. +TP_EXPOSURE_BLACKLEVEL;Beltza +TP_EXPOSURE_BRIGHTNESS;Distira +TP_EXPOSURE_CLIP;Moztu +TP_EXPOSURE_COMPRHIGHLIGHTS;Argi konpresioa +TP_EXPOSURE_COMPRSHADOWS;Itzal konpresioa +TP_EXPOSURE_CONTRAST;Kontrastea +TP_EXPOSURE_CURVEEDITOR;Tonu kurba +TP_EXPOSURE_EXPCOMP;Esp. Konp. +TP_EXPOSURE_LABEL;Esposizioa +TP_HLREC_CIELAB;CIELab Blending +TP_HLREC_COLOR;Kolorearen hedapena +TP_HLREC_LABEL;Distiren berreskurapena +TP_HLREC_LUMINANCE;Argitasun berreskurapena +TP_HLREC_METHOD;Metodoa: +TP_ICM_INPUTCAMERA;Kameraren jatorrizko balioak +TP_ICM_INPUTCUSTOM;Neurrira +TP_ICM_INPUTDLGLABEL;Sarrerako ICC profila hautatu... +TP_ICM_INPUTEMBEDDED;Txertatutakoa erabili, egonez gero +TP_ICM_INPUTPROFILE;Sarrerako profila +TP_ICM_LABEL;ICM +TP_ICM_NOICM;ICM-rik ez: sRGB irteera +TP_ICM_OUTPUTPROFILE;Irteera profila +TP_ICM_SAVEREFERENCE;Save reference image for profiling +TP_ICM_WORKINGPROFILE;Lan profila +TP_RAW_DMETHOD;Metodoa +TP_RAW_FALSECOLOR;Okerreko kolore ezabaketa atalak +TP_RESIZE_H;H: +TP_RESIZE_LABEL;Tamaina aldatu +TP_RESIZE_METHOD;Metodoa: +TP_RESIZE_NEAREST;Gertuena +TP_RESIZE_SCALE;Eskala +TP_RESIZE_W;W: +TP_ROTATE_DEGREE;Angelua +TP_ROTATE_LABEL;Errotazioa +TP_ROTATE_SELECTLINE; Lerro zuzena hautatu +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Argiak +TP_SHADOWSHLIGHTS_HLTONALW;Tonu zabalera +TP_SHADOWSHLIGHTS_LABEL;Itzalak/Argiak +TP_SHADOWSHLIGHTS_LOCALCONTR;Tokiko kontrastea +TP_SHADOWSHLIGHTS_RADIUS;Erradioa +TP_SHADOWSHLIGHTS_SHADOWS;Itzalak +TP_SHADOWSHLIGHTS_SHTONALW;Tonu zabalera +TP_SHARPENING_AMOUNT;Kopurua +TP_SHARPENING_EDRADIUS;Erradioa +TP_SHARPENING_EDTOLERANCE;Ertz tolerantzia +TP_SHARPENING_HALOCONTROL;Halo kontrola +TP_SHARPENING_HCAMOUNT;Kopurua +TP_SHARPENING_LABEL;Fokatu +TP_SHARPENING_METHOD;Metodoa +TP_SHARPENING_ONLYEDGES;Ertzak bakarrik fokatu +TP_SHARPENING_RADIUS;Erradioa +TP_SHARPENING_RLD;RL Dekonboluzioa +TP_SHARPENING_RLD_AMOUNT;Kopurua +TP_SHARPENING_RLD_DAMPING;Indargetzea +TP_SHARPENING_RLD_ITERATIONS;Iterazioak +TP_SHARPENING_THRESHOLD;Muga +TP_SHARPENING_USM;Defokatze maskara +TP_VIGNETTING_AMOUNT;Kopurua +TP_VIGNETTING_LABEL;Iluntze zuzenketa +TP_VIGNETTING_RADIUS;Erradioa +TP_WBALANCE_AUTO;Auto +TP_WBALANCE_CAMERA;Camera +TP_WBALANCE_CUSTOM;Pertsonalizatua +TP_WBALANCE_GREEN;Tindua +TP_WBALANCE_LABEL;Zuri balantzea +TP_WBALANCE_METHOD;Metodoa +TP_WBALANCE_SIZE;Tamaina: +TP_WBALANCE_SPOTWB;Z/B Puntuala +TP_WBALANCE_TEMPERATURE;Tenperatura +# + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!ABOUT_TAB_BUILD;Version +!ABOUT_TAB_CREDITS;Credits +!ABOUT_TAB_LICENSE;License +!ABOUT_TAB_RELEASENOTES;Release Notes +!ABOUT_TAB_SPLASH;Splash +!BATCHQUEUE_AUTOSTART;Auto-start +!BATCHQUEUE_DESTFILENAME;Path and file name +!BATCH_PROCESSING;Batch Processing +!CURVEEDITOR_AXIS_IN;I: +!CURVEEDITOR_AXIS_LEFT_TAN;LT: +!CURVEEDITOR_AXIS_OUT;O: +!CURVEEDITOR_AXIS_RIGHT_TAN;RT: +!CURVEEDITOR_CURVES;Curves +!CURVEEDITOR_CURVE;Curve +!CURVEEDITOR_CUSTOM;Custom +!CURVEEDITOR_DARKS;Darks +!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_HIGHLIGHTS;Highlights +!CURVEEDITOR_LIGHTS;Lights +!CURVEEDITOR_MINMAXCPOINTS;Equalizer +!CURVEEDITOR_NURBS;Control cage +!CURVEEDITOR_PARAMETRIC;Parametric +!CURVEEDITOR_SHADOWS;Shadows +!CURVEEDITOR_TOOLTIPCOPY;Copy current curve to clipboard. +!CURVEEDITOR_TOOLTIPPASTE;Paste curve from clipboard. +!CURVEEDITOR_TYPE;Type: +!EDITWINDOW_TITLE;Image Edit +!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_FILETYPE;File type +!EXIFFILTER_METADATAFILTER;Enable metadata filters +!EXPORT_BYPASS_ALL;Select / Unselect All +!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_FF;Bypass [raw] Flat-Field +!EXPORT_BYPASS_RAW_GREENTHRESH;Bypass [raw] Green Equilibration +!EXPORT_BYPASS_RAW_LINENOISE;Bypass [raw] Line Noise Filter +!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_FASTEXPORTOPTIONS;Fast Export Options +!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_MAXHEIGHT;Maximum height: +!EXPORT_MAXWIDTH;Maximum width: +!EXPORT_PUTTOQUEUEFAST; Put to queue for fast export +!EXPORT_RAW_DMETHOD;Demosaic method +!EXTPROGTARGET_1;raw +!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_CACHECLEARFROMFULL;Clear from cache - full +!FILEBROWSER_CACHECLEARFROMPARTIAL;Clear from cache - partial +!FILEBROWSER_CACHE;Cache +!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_CURRENT_NAME;Current name: +!FILEBROWSER_DARKFRAME;Dark-frame +!FILEBROWSER_DELETEDLGMSGINCLPROC;Are you sure you want to delete the selected %1 files including a queue-processed version? +!FILEBROWSER_EXEC_CPB;Custom Profile Builder +!FILEBROWSER_EXTPROGMENU;Open with +!FILEBROWSER_FLATFIELD;Flat-Field +!FILEBROWSER_MOVETODARKFDIR;Move to dark-frames directory +!FILEBROWSER_MOVETOFLATFIELDDIR;Move to flat-fields directory +!FILEBROWSER_NEW_NAME;New name: +!FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) +!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_POPUPCOLORLABEL;Color label +!FILEBROWSER_POPUPCOPYTO;Copy to... +!FILEBROWSER_POPUPFILEOPERATIONS;File operations +!FILEBROWSER_POPUPMOVETO;Move to... +!FILEBROWSER_POPUPPROCESSFAST;Put to queue (Fast export) +!FILEBROWSER_POPUPPROFILEOPERATIONS;Processing profile operations +!FILEBROWSER_POPUPRANK0;Unrank +!FILEBROWSER_POPUPRANK1;Rank 1 * +!FILEBROWSER_POPUPRANK2;Rank 2 ** +!FILEBROWSER_POPUPRANK3;Rank 3 *** +!FILEBROWSER_POPUPRANK4;Rank 4 **** +!FILEBROWSER_POPUPRANK5;Rank 5 ***** +!FILEBROWSER_POPUPRANK;Rank +!FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!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_QUERYLABEL; Find: +!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_SELECTDARKFRAME;Select dark-frame... +!FILEBROWSER_SELECTFLATFIELD;Select flat-field... +!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 +!FILEBROWSER_SHOWCOLORLABEL4HINT;Show images labeled Blue.\nShortcut: Alt-4 +!FILEBROWSER_SHOWCOLORLABEL5HINT;Show images labeled Purple.\nShortcut: Alt-5 +!FILEBROWSER_SHOWEDITEDHINT;Show edited images.\nShortcut: 7 +!FILEBROWSER_SHOWEDITEDNOTHINT;Show not edited images.\nShortcut: 6 +!FILEBROWSER_SHOWEXIFINFO;Show Exif info.\n\nShortcuts:\ni - Multiple Editor Tabs Mode,\nAlt-i - Single Editor Tab Mode. +!FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!FILEBROWSER_SHOWRECENTLYSAVEDHINT;Show saved images.\nShortcut: Alt-7 +!FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show unsaved images.\nShortcut: Alt-6 +!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_AFTER;After +!GENERAL_ASIMAGE;As Image +!GENERAL_AUTO;Automatic +!GENERAL_BEFORE;Before +!GENERAL_CLOSE;Close +!GENERAL_FILE;File +!GENERAL_NONE;None +!GENERAL_UNCHANGED;(Unchanged) +!GENERAL_WARNING;Warning +!HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar.\nRight-click on image preview to freeze/unfreeze. +!HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram. +!HISTOGRAM_TOOLTIP_FULL;Toggle full (off) or scaled (on) histogram. +!HISTOGRAM_TOOLTIP_RAW;Show/Hide raw histogram. +!HISTORY_MSG_82;Profile changed +!HISTORY_MSG_83;S/H - Sharp mask +!HISTORY_MSG_84;Perspective correction +!HISTORY_MSG_85;LCP +!HISTORY_MSG_86;RGB curves - Luminosity mode +!HISTORY_MSG_87;Impulse noise reduction +!HISTORY_MSG_88;Impulse NR threshold +!HISTORY_MSG_89;Noise Reduction +!HISTORY_MSG_90;NR - Luminance +!HISTORY_MSG_91;NR - Chrominance master +!HISTORY_MSG_92;NR - Gamma +!HISTORY_MSG_93;CbDL - Value +!HISTORY_MSG_94;Contrast by Detail Levels +!HISTORY_MSG_95;L*a*b* - Chromaticity +!HISTORY_MSG_96;L*a*b* - a* curve +!HISTORY_MSG_97;L*a*b* - b* curve +!HISTORY_MSG_98;Demosaicing method +!HISTORY_MSG_99;Hot pixel filter +!HISTORY_MSG_100;RGB Saturation +!HISTORY_MSG_101;HSV - Hue +!HISTORY_MSG_102;HSV - Saturation +!HISTORY_MSG_103;HSV - Value +!HISTORY_MSG_104;HSV Equalizer +!HISTORY_MSG_105;Defringe +!HISTORY_MSG_106;Defringe - Radius +!HISTORY_MSG_107;Defringe - Threshold +!HISTORY_MSG_108;Highlight Compr. Threshold +!HISTORY_MSG_109;Resize - Bounding box +!HISTORY_MSG_110;Resize - Applies to +!HISTORY_MSG_111;L*a*b* - Avoid color shift +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;L*a*b* - Red/skin prot. +!HISTORY_MSG_114;DCB iterations +!HISTORY_MSG_115;False color suppression +!HISTORY_MSG_116;DCB enhancement +!HISTORY_MSG_117;Raw CA correction - Red +!HISTORY_MSG_118;Raw CA correction - Blue +!HISTORY_MSG_119;Line noise filter +!HISTORY_MSG_120;Green equilibration +!HISTORY_MSG_121;Raw CA Correction - Auto +!HISTORY_MSG_122;Dark-Frame - Auto-selection +!HISTORY_MSG_123;Dark-Frame - File +!HISTORY_MSG_124;White point correction +!HISTORY_MSG_125;Highlight preservation +!HISTORY_MSG_126;Flat-Field - File +!HISTORY_MSG_127;Flat-Field - Auto-selection +!HISTORY_MSG_128;Flat-Field - Blur radius +!HISTORY_MSG_129;Flat-Field - Blur type +!HISTORY_MSG_130;Auto distorion correction +!HISTORY_MSG_131;NR - Luma +!HISTORY_MSG_132;NR - Chroma +!HISTORY_MSG_133;Output gamma +!HISTORY_MSG_134;Free gamma +!HISTORY_MSG_135;Free gamma +!HISTORY_MSG_136;Free gamma slope +!HISTORY_MSG_137;Black level - Green 1 +!HISTORY_MSG_138;Black level - Red +!HISTORY_MSG_139;Black level - Blue +!HISTORY_MSG_140;Black level - Green 2 +!HISTORY_MSG_141;Black level - Link greens +!HISTORY_MSG_142;ES - Iterations +!HISTORY_MSG_143;ES - Quantity +!HISTORY_MSG_144;Microcontrast - Quantity +!HISTORY_MSG_145;Microcontrast - Uniformity +!HISTORY_MSG_146;Edge sharpening +!HISTORY_MSG_147;ES - Luminance only +!HISTORY_MSG_148;Microcontrast +!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_150;Post-demosaic artifact/noise red. +!HISTORY_MSG_151;Vibrance +!HISTORY_MSG_152;Vib - Pastel tones +!HISTORY_MSG_153;Vib - Saturated tones +!HISTORY_MSG_154;Vib - Protect skin-tones +!HISTORY_MSG_155;Vib - Avoid color shift +!HISTORY_MSG_156;Vib - Link pastel/saturated +!HISTORY_MSG_157;Vib - P/S threshold +!HISTORY_MSG_158;TM - Strength +!HISTORY_MSG_159;TM - Edge stopping +!HISTORY_MSG_160;TM - Scale +!HISTORY_MSG_161;TM - Reweighting iterates +!HISTORY_MSG_162;Tone Mapping +!HISTORY_MSG_163;RGB curves - Red +!HISTORY_MSG_164;RGB curves - Green +!HISTORY_MSG_165;RGB curves - Blue +!HISTORY_MSG_166;Neutral levels +!HISTORY_MSG_167;--unused-- +!HISTORY_MSG_168;L*a*b* - CC curve +!HISTORY_MSG_169;L*a*b* - CH curve +!HISTORY_MSG_170;Vibrance - HH curve +!HISTORY_MSG_171;L*a*b* - LC curve +!HISTORY_MSG_172;L*a*b* - Restrict LC +!HISTORY_MSG_173;NR - Luminance detail +!HISTORY_MSG_174;CIECAM02 +!HISTORY_MSG_175;CAM02 - CAT02 adaptation +!HISTORY_MSG_176;CAM02 - Viewing surround +!HISTORY_MSG_177;CAM02 - Scene luminosity +!HISTORY_MSG_178;CAM02 - Viewing luminosity +!HISTORY_MSG_179;CAM02 - White-point model +!HISTORY_MSG_180;CAM02 - Lightness (J) +!HISTORY_MSG_181;CAM02 - Chroma (C) +!HISTORY_MSG_182;CAM02 - Automatic CAT02 +!HISTORY_MSG_183;CAM02 - Contrast (J) +!HISTORY_MSG_184;CAM02 - Scene surround +!HISTORY_MSG_185;CAM02 - Gamut control +!HISTORY_MSG_186;CAM02 - Algorithm +!HISTORY_MSG_187;CAM02 - Red/skin prot. +!HISTORY_MSG_188;CAM02 - Brightness (Q) +!HISTORY_MSG_189;CAM02 - Contrast (Q) +!HISTORY_MSG_190;CAM02 - Saturation (S) +!HISTORY_MSG_191;CAM02 - Colorfulness (M) +!HISTORY_MSG_192;CAM02 - Hue (h) +!HISTORY_MSG_193;CAM02 - Tone curve 1 +!HISTORY_MSG_194;CAM02 - Tone curve 2 +!HISTORY_MSG_195;CAM02 - Tone curve 1 +!HISTORY_MSG_196;CAM02 - Tone curve 2 +!HISTORY_MSG_197;CAM02 - Color curve +!HISTORY_MSG_198;CAM02 - Color curve +!HISTORY_MSG_199;CAM02 - Output histograms +!HISTORY_MSG_200;CAM02 - Tone mapping +!HISTORY_MSG_201;NR - Chrominance - R&G +!HISTORY_MSG_202;NR - Chrominance - B&Y +!HISTORY_MSG_203;NR - Method +!HISTORY_MSG_204;LMMSE enhancement steps +!HISTORY_MSG_205;CAM02 - Hot/bad pixel filter +!HISTORY_MSG_206;CAT02 - Auto scene luminosity +!HISTORY_MSG_207;Defringe - Hue curve +!HISTORY_MSG_208;WB - B/R equalizer +!HISTORY_MSG_210;GF - Angle +!HISTORY_MSG_211;Graduated Filter +!HISTORY_MSG_212;VF - Strength +!HISTORY_MSG_213;Vignette Filter +!HISTORY_MSG_214;Black-and-White +!HISTORY_MSG_215;B&W - CM - Red +!HISTORY_MSG_216;B&W - CM - Green +!HISTORY_MSG_217;B&W - CM - Blue +!HISTORY_MSG_218;B&W - Gamma - Red +!HISTORY_MSG_219;B&W - Gamma - Green +!HISTORY_MSG_220;B&W - Gamma - Blue +!HISTORY_MSG_221;B&W - Color filter +!HISTORY_MSG_222;B&W - Presets +!HISTORY_MSG_223;B&W - CM - Orange +!HISTORY_MSG_224;B&W - CM - Yellow +!HISTORY_MSG_225;B&W - CM - Cyan +!HISTORY_MSG_226;B&W - CM - Magenta +!HISTORY_MSG_227;B&W - CM - Purple +!HISTORY_MSG_228;B&W - Luminance equalizer +!HISTORY_MSG_229;B&W - Luminance equalizer +!HISTORY_MSG_230;B&W - Mode +!HISTORY_MSG_231;B&W - 'Before' curve +!HISTORY_MSG_232;B&W - 'Before' curve type +!HISTORY_MSG_233;B&W - 'After' curve +!HISTORY_MSG_234;B&W - 'After' curve type +!HISTORY_MSG_235;B&W - Auto channel mixer +!HISTORY_MSG_236;--unused-- +!HISTORY_MSG_237;B&W - Mixer +!HISTORY_MSG_238;GF - Feather +!HISTORY_MSG_239;GF - Strength +!HISTORY_MSG_240;GF - Center +!HISTORY_MSG_241;VF - Feather +!HISTORY_MSG_242;VF - Roundness +!HISTORY_MSG_243;VC - Radius +!HISTORY_MSG_244;VC - Strength +!HISTORY_MSG_245;VC - Center +!HISTORY_MSG_246;L*a*b* - CL curve +!HISTORY_MSG_247;L*a*b* - LH curve +!HISTORY_MSG_248;L*a*b* - HH curve +!HISTORY_MSG_249;CbDL - Threshold +!HISTORY_MSG_250;NR - Enhanced +!HISTORY_MSG_251;B&W - Algorithm +!HISTORY_MSG_252;CbDL - Skin tar/prot +!HISTORY_MSG_253;CbDL - Reduce artifacts +!HISTORY_MSG_254;CbDL - Skin hue +!HISTORY_MSG_255;NR - Median filter +!HISTORY_MSG_256;NR - Median type +!HISTORY_MSG_257;Color Toning +!HISTORY_MSG_258;CT - Color curve +!HISTORY_MSG_259;CT - Opacity curve +!HISTORY_MSG_260;CT - a*[b*] opacity +!HISTORY_MSG_261;CT - Method +!HISTORY_MSG_262;CT - b* opacity +!HISTORY_MSG_263;CT - Shadows - Red +!HISTORY_MSG_264;CT - Shadows - Green +!HISTORY_MSG_265;CT - Shadows - Blue +!HISTORY_MSG_266;CT - Mid - Red +!HISTORY_MSG_267;CT - Mid - Green +!HISTORY_MSG_268;CT - Mid - Blue +!HISTORY_MSG_269;CT - High - Red +!HISTORY_MSG_270;CT - High - Green +!HISTORY_MSG_271;CT - High - Blue +!HISTORY_MSG_272;CT - Balance +!HISTORY_MSG_273;CT - Reset +!HISTORY_MSG_274;CT - Sat. Shadows +!HISTORY_MSG_275;CT - Sat. Highlights +!HISTORY_MSG_276;CT - Opacity +!HISTORY_MSG_277;--unused-- +!HISTORY_MSG_278;CT - Preserve luminance +!HISTORY_MSG_279;CT - Shadows +!HISTORY_MSG_280;CT - Highlights +!HISTORY_MSG_281;CT - Sat. strength +!HISTORY_MSG_282;CT - Sat. threshold +!HISTORY_MSG_283;CT - Strength +!HISTORY_MSG_284;CT - Auto sat. protection +!HISTORY_MSG_285;NR - Median - Method +!HISTORY_MSG_286;NR - Median - Type +!HISTORY_MSG_287;NR - Median - Iterations +!HISTORY_MSG_288;Flat Field - Clip control +!HISTORY_MSG_289;Flat Field - Clip control - Auto +!HISTORY_MSG_290;Black Level - Red +!HISTORY_MSG_291;Black Level - Green +!HISTORY_MSG_292;Black Level - Blue +!HISTORY_MSG_293;Film Simulation +!HISTORY_MSG_294;Film Simulation - Strength +!HISTORY_MSG_295;Film Simulation - Film +!HISTORY_MSG_296;NR - Luminance curve +!HISTORY_MSG_297;NR - Quality +!HISTORY_MSG_298;Dead pixel filter +!HISTORY_MSG_299;NR - Chrominance curve +!HISTORY_MSG_300;- +!HISTORY_MSG_301;NR - Luma control +!HISTORY_MSG_302;NR - Chroma method +!HISTORY_MSG_303;NR - Chroma method +!HISTORY_MSG_304;W - Contrast levels +!HISTORY_MSG_305;Wavelet Levels +!HISTORY_MSG_306;W - Preview +!HISTORY_MSG_307;W - Preview +!HISTORY_MSG_308;W - Preview direction +!HISTORY_MSG_309;W - ES - Detail +!HISTORY_MSG_310;W - Residual - Sky tar/prot +!HISTORY_MSG_311;W - Wavelet levels +!HISTORY_MSG_312;W - Residual - Shadows threshold +!HISTORY_MSG_313;W - Chroma - Sat/past +!HISTORY_MSG_314;W - Gamut - Reduce artifacts +!HISTORY_MSG_315;W - Residual - Contrast +!HISTORY_MSG_316;W - Gamut - Skin tar/prot +!HISTORY_MSG_317;W - Gamut - Skin hue +!HISTORY_MSG_318;W - Contrast - Highlight levels +!HISTORY_MSG_319;W - Contrast - Highlight range +!HISTORY_MSG_320;W - Contrast - Shadow range +!HISTORY_MSG_321;W - Contrast - Shadow levels +!HISTORY_MSG_322;W - Gamut - Avoid color shift +!HISTORY_MSG_323;W - ES - Local contrast +!HISTORY_MSG_324;W - Chroma - Pastel +!HISTORY_MSG_325;W - Chroma - Saturated +!HISTORY_MSG_326;W - Chroma - Method +!HISTORY_MSG_327;W - Contrast - Apply to +!HISTORY_MSG_328;W - Chroma - Link strength +!HISTORY_MSG_329;W - Toning - Opacity RG +!HISTORY_MSG_330;W - Toning - Opacity BY +!HISTORY_MSG_331;W - Contrast levels - Extra +!HISTORY_MSG_332;W - Tiling method +!HISTORY_MSG_333;W - Residual - Shadows +!HISTORY_MSG_334;W - Residual - Chroma +!HISTORY_MSG_335;W - Residual - Highlights +!HISTORY_MSG_336;W - Residual - Highlights threshold +!HISTORY_MSG_337;W - Residual - Sky hue +!HISTORY_MSG_338;W - ES - Radius +!HISTORY_MSG_339;W - ES - Strength +!HISTORY_MSG_340;W - Strength +!HISTORY_MSG_341;W - Edge performance +!HISTORY_MSG_342;W - ES - First level +!HISTORY_MSG_343;W - Chroma levels +!HISTORY_MSG_344;W - Meth chroma sl/cur +!HISTORY_MSG_345;W - ES - Local contrast +!HISTORY_MSG_346;W - ES - Local contrast method +!HISTORY_MSG_347;W - Denoise - Level 0 +!HISTORY_MSG_348;W - Denoise - Level 1 +!HISTORY_MSG_349;W - Denoise - Level 2 +!HISTORY_MSG_350;W - ES - Edge detection +!HISTORY_MSG_351;W - Residual - HH curve +!HISTORY_MSG_352;W - Background +!HISTORY_MSG_353;W - ES - Gradient sensitivity +!HISTORY_MSG_354;W - ES - Enhance +!HISTORY_MSG_355;W - ES - Threshold low +!HISTORY_MSG_356;W - ES - Threshold high +!HISTORY_MSG_357;W - Denoise - Link with ES +!HISTORY_MSG_358;W - Gamut - CH +!HISTORY_MSG_359;Hot/Dead - Threshold +!HISTORY_MSG_360;TM Gamma +!HISTORY_MSG_361;W - Final - Chroma balance +!HISTORY_MSG_362;W - Residual - Compression method +!HISTORY_MSG_363;W - Residual - Compression strength +!HISTORY_MSG_364;W - Final - Contrast balance +!HISTORY_MSG_365;W - Final - Delta balance +!HISTORY_MSG_366;W - Residual - Compression gamma +!HISTORY_MSG_367;W - ES - Local contrast curve +!HISTORY_MSG_368;W - Final - Contrast balance +!HISTORY_MSG_369;W - Final - Balance method +!HISTORY_MSG_370;W - Final - Local contrast curve +!HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s +!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 +!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). +!MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Put current image to processing queue.\nShortcut: Ctrl+b +!MAIN_BUTTON_SAVE_TOOLTIP;Save current image.\nShortcut: Ctrl+s +!MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Edit current image in external editor.\nShortcut: Ctrl+e +!MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Show/hide all side panels.\nShortcut: m +!MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen +!MAIN_FRAME_BATCHQUEUE_TOOLTIP;Processing queue.\nShortcut: Ctrl-F3 +!MAIN_FRAME_EDITOR;Editor +!MAIN_FRAME_EDITOR_TOOLTIP;Editor.\nShortcut: Ctrl-F4 +!MAIN_FRAME_FILEBROWSER_TOOLTIP;File browser.\nShortcut: Ctrl-F2 +!MAIN_MSG_EMPTYFILENAME;Filename unspecified! +!MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue-processed first. +!MAIN_MSG_NAVIGATOR;Navigator +!MAIN_MSG_OPERATIONCANCELLED;Operation cancelled +!MAIN_MSG_PATHDOESNTEXIST;The path\n\n%1\n\ndoes not exist. Please set a correct path in Preferences. +!MAIN_MSG_SETPATHFIRST;You first have to set a target path in Preferences in order to use this function! +!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_EXPORT; Fast Export +!MAIN_TAB_EXPOSURE_TOOLTIP;Shortcut: Alt-e +!MAIN_TAB_INSPECT; Inspect +!MAIN_TAB_METADATA_TOOLTIP;Shortcut: Alt-m +!MAIN_TAB_RAW;Raw +!MAIN_TAB_RAW_TOOLTIP;Shortcut: Alt-r +!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_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%. +!MAIN_TOOLTIP_PREVIEWG;Preview the Green channel.\nShortcut: g +!MAIN_TOOLTIP_PREVIEWL;Preview the Luminosity.\nShortcut: v\n\n0.299*R + 0.587*G + 0.114*B +!MAIN_TOOLTIP_PREVIEWR;Preview the Red channel.\nShortcut: r +!MAIN_TOOLTIP_SHOWHIDELP1;Show/Hide the left panel.\nShortcut: l +!MAIN_TOOLTIP_SHOWHIDERP1;Show/Hide the right panel.\nShortcut: Alt-l +!MAIN_TOOLTIP_SHOWHIDETP1;Show/Hide the top panel.\nShortcut: Shift-l +!MAIN_TOOLTIP_THRESHOLD;Threshold +!MAIN_TOOLTIP_TOGGLE;Toggle the Before/After view.\nShortcut: Shift-b +!NAVIGATOR_B;B: +!NAVIGATOR_G;G: +!NAVIGATOR_H;H: +!NAVIGATOR_LAB_A;a*: +!NAVIGATOR_LAB_B;b*: +!NAVIGATOR_LAB_L;L*: +!NAVIGATOR_NA; -- +!NAVIGATOR_R;R: +!NAVIGATOR_S;S: +!NAVIGATOR_V;V: +!NAVIGATOR_XY_FULL;Width: %1, Height: %2 +!NAVIGATOR_XY_NA;x: --, y: -- +!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_CHANNELMIXERBW;Black-and-White +!PARTIALPASTE_CHANNELMIXER;Channel mixer +!PARTIALPASTE_COLORAPP;CIECAM02 +!PARTIALPASTE_COLORTONING;Color Toning +!PARTIALPASTE_COMMONTRANSFORMPARAMS;Auto-fill +!PARTIALPASTE_DARKFRAMEAUTOSELECT;Dark-frame auto-selection +!PARTIALPASTE_DARKFRAMEFILE;Dark-frame file +!PARTIALPASTE_DEFRINGE;Defringe +!PARTIALPASTE_DETAILGROUP;Detail Settings +!PARTIALPASTE_DIRPYRDENOISE;Noise reduction +!PARTIALPASTE_DIRPYREQUALIZER;Contrast by detail levels +!PARTIALPASTE_EPD;Tone mapping +!PARTIALPASTE_EQUALIZER;Wavelet Equalizer +!PARTIALPASTE_EVERYTHING;Everything +!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_GRADIENT;Graduated filter +!PARTIALPASTE_HSVEQUALIZER;HSV equalizer +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction +!PARTIALPASTE_LABCURVE;L*a*b* adjustments +!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_PCVIGNETTE;Vignette filter +!PARTIALPASTE_PERSPECTIVE;Perspective +!PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter +!PARTIALPASTE_PREPROCESS_GREENEQUIL;Green equilibration +!PARTIALPASTE_PREPROCESS_HOTPIXFILT;Hot pixel filter +!PARTIALPASTE_PREPROCESS_LINEDENOISE;Line noise filter +!PARTIALPASTE_RAWCACORR_AUTO;CA auto-correction +!PARTIALPASTE_RAWCACORR_CABLUE;CA blue +!PARTIALPASTE_RAWCACORR_CARED;CA red +!PARTIALPASTE_RAWEXPOS_BLACK;Black levels +!PARTIALPASTE_RAWEXPOS_LINEAR;White point correction +!PARTIALPASTE_RAWEXPOS_PRESER;Highlight preservation +!PARTIALPASTE_RAWGROUP;Raw Settings +!PARTIALPASTE_RAW_DCBENHANCE;DCB enhancement +!PARTIALPASTE_RAW_DCBITERATIONS;Number of DCB iterations +!PARTIALPASTE_RAW_DMETHOD;Demosaic method +!PARTIALPASTE_RAW_FALSECOLOR;Demosaic false color suppression steps +!PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!PARTIALPASTE_RGBCURVES;RGB curves +!PARTIALPASTE_SHARPENEDGE;Edges +!PARTIALPASTE_SHARPENMICRO;Microcontrast +!PARTIALPASTE_VIBRANCE;Vibrance +!PARTIALPASTE_WAVELETGROUP;Wavelet processing +!PREFERENCES_ADD;Add +!PREFERENCES_AUTLISLOW;Low +!PREFERENCES_AUTLISMAX;Max - Average of all tiles +!PREFERENCES_AUTLISSTD;High +!PREFERENCES_AUTLISVLOW;None +!PREFERENCES_AUTLOW;Low +!PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +!PREFERENCES_AUTSTD;Standard +!PREFERENCES_BATCH_PROCESSING;Batch Processing +!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_BEHADDALL;All to 'Add' +!PREFERENCES_BEHAVIOR;Behavior +!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_BEHSETALL;All to 'Set' +!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_CURVEBBOXPOS;Position of curve copypasta buttons +!PREFERENCES_CURVEBBOXPOS_ABOVE;Above +!PREFERENCES_CURVEBBOXPOS_BELOW;Below +!PREFERENCES_CURVEBBOXPOS_LEFT;Left +!PREFERENCES_CURVEBBOXPOS_RIGHT;Right +!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_CUSTPROFBUILD;Custom Processing Profile Builder +!PREFERENCES_CUTOVERLAYBRUSH;Crop mask color/transparency +!PREFERENCES_D50;5000K +!PREFERENCES_D55;5500K +!PREFERENCES_D60;6000K +!PREFERENCES_D65;6500K +!PREFERENCES_DARKFRAMEFOUND;Found +!PREFERENCES_DARKFRAMESHOTS;shots +!PREFERENCES_DARKFRAMETEMPLATES;templates +!PREFERENCES_DARKFRAME;Dark-Frame +!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 (de-select for low resolution display) +!PREFERENCES_FILMSIMULATION;Film Simulation +!PREFERENCES_FLATFIELDFOUND;Found +!PREFERENCES_FLATFIELDSDIR;Flat-fields directory +!PREFERENCES_FLATFIELDSHOTS;shots +!PREFERENCES_FLATFIELDTEMPLATES;templates +!PREFERENCES_FLATFIELD;Flat-Field +!PREFERENCES_FLUOF2;Fluorescent F2 +!PREFERENCES_FLUOF7;Fluorescent F7 +!PREFERENCES_FLUOF11;Fluorescent F11 +!PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT;Same thumbnail height between the Editor's panel 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_GREY05;Yb=05 CIE L#30 +!PREFERENCES_GREY10;Yb=10 CIE L#40 +!PREFERENCES_GREY15;Yb=15 CIE L#45 +!PREFERENCES_GREY18;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_GREYSC18;Yb=18 CIE L#50 +!PREFERENCES_GREYSCA;Automatic +!PREFERENCES_GREYSC;Scene Yb luminance (%) +!PREFERENCES_GREY;Output device's Yb luminance (%) +!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_LANGAUTODETECT;Use system language +!PREFERENCES_LEVAUTDN;Denoising level +!PREFERENCES_LEVDN;Cell size +!PREFERENCES_LISS;Auto multi-zone smoothing +!PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders +!PREFERENCES_MAX;Maxi (Tile) +!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_MENUGROUPRANK;Group "Rank" +!PREFERENCES_MENUOPTIONS;Context Menu Options +!PREFERENCES_METADATA;Metadata +!PREFERENCES_MIN;Mini (100x115) +!PREFERENCES_MULTITABDUALMON;Multiple Editor Tabs In Own Window Mode +!PREFERENCES_MULTITAB;Multiple Editor Tabs 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_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_PROPERTY;Property +!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 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_SINGLETABVERTAB;Single Editor Tab Mode, Vertical Tabs +!PREFERENCES_SINGLETAB;Single Editor Tab Mode +!PREFERENCES_SLIMUI;Slim interface +!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_PERFORMANCE;Performance & Quality +!PREFERENCES_TAB_SOUND;Sounds +!PREFERENCES_TIMAX;High +!PREFERENCES_TINB;Number of tiles +!PREFERENCES_TISTD;Standard +!PREFERENCES_TP_LABEL;Tool panel: +!PREFERENCES_TP_USEICONORTEXT;Use tab icons instead of text +!PREFERENCES_TP_VSCROLLBAR;Hide vertical scrollbar +!PREFERENCES_TUNNELMETADATA;Copy IPTC/XMP unchanged to output file (when tagging with other program) +!PREFERENCES_USEBUNDLEDPROFILES;Use bundled profiles +!PREFERENCES_USESYSTEMTHEME;Use system theme +!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_WORKFLOW;Layout +!PROFILEPANEL_COPYPPASTE;Parameters to copy +!PROFILEPANEL_GLOBALPROFILES;Bundled profiles +!PROFILEPANEL_LOADPPASTE;Parameters to load +!PROFILEPANEL_MODE_TIP;Processing profile fill mode.\n\nButton pressed: partial profiles will be converted to full profiles; the missing values will be replaced with hard-coded defaults.\n\nButton released: profiles will be applied as they are, altering only those values which they contain. +!PROFILEPANEL_MYPROFILES;My profiles +!PROFILEPANEL_PASTEPPASTE;Parameters to paste +!PROFILEPANEL_PINTERNAL;Neutral +!PROFILEPANEL_SAVEPPASTE;Parameters to save +!PROGRESSBAR_LOADINGTHUMBS;Loading thumbnails... +!PROGRESSBAR_NOIMAGES;No images found +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing profile saved +!PROGRESSBAR_SNAPSHOT_ADDED;Snapshot added +!PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists +!SAVEDLG_FORCEFORMATOPTS;Force saving options +!SAVEDLG_SUBSAMP;Subsampling +!SAVEDLG_SUBSAMP_1;Best compression +!SAVEDLG_SUBSAMP_2;Balanced +!SAVEDLG_SUBSAMP_3;Best quality +!SAVEDLG_SUBSAMP_TOOLTIP;Best compression: 4:1:1\nBalanced: 4:2:2\nBest quality: 4:4:4 +!SAVEDLG_TIFFUNCOMPRESSED;Uncompressed TIFF +!SAVEDLG_WARNFILENAME;File will be named +!SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. +!THRESHOLDSELECTOR_BL;Bottom-left +!THRESHOLDSELECTOR_BR;Bottom-right +!THRESHOLDSELECTOR_B;Bottom +!THRESHOLDSELECTOR_HINT;Hold the Shift key to move individual control points. +!THRESHOLDSELECTOR_TL;Top-left +!THRESHOLDSELECTOR_TR;Top-right +!THRESHOLDSELECTOR_T;Top +!TP_BWMIX_ALGO;Algorithm OYCPM +!TP_BWMIX_ALGO_LI;Linear +!TP_BWMIX_ALGO_SP;Special effects +!TP_BWMIX_ALGO_TOOLTIP;Linear: will produce a normal linear response.\nSpecial effects: will produce special effects by mixing channels non-linearly. +!TP_BWMIX_AUTOCH;Auto +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing Channel Mixer. +!TP_BWMIX_CC_ENABLED;Adjust complementary color +!TP_BWMIX_CC_TOOLTIP;Enable to allow automatic adjustment of complementary colors in ROYGCBPM mode. +!TP_BWMIX_CHANNEL;Luminance equalizer +!TP_BWMIX_CURVEEDITOR1;'Before' curve +!TP_BWMIX_CURVEEDITOR2;'After' curve +!TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Tone curve, after B&W conversion, at the end of treatment. +!TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Tone curve, just before B&W conversion.\nMay take into account the color components. +!TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H).\nPay attention to extreme values as they may cause artifacts. +!TP_BWMIX_FILTER;Color Filter +!TP_BWMIX_FILTER_BLUEGREEN;Blue-Green +!TP_BWMIX_FILTER_BLUE;Blue +!TP_BWMIX_FILTER_GREENYELLOW;Green-Yellow +!TP_BWMIX_FILTER_GREEN;Green +!TP_BWMIX_FILTER_NONE;None +!TP_BWMIX_FILTER_PURPLE;Purple +!TP_BWMIX_FILTER_REDYELLOW;Red-Yellow +!TP_BWMIX_FILTER_RED;Red +!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. +!TP_BWMIX_FILTER_YELLOW;Yellow +!TP_BWMIX_GAMMA;Gamma Correction +!TP_BWMIX_GAM_TOOLTIP;Correct gamma for each RGB channel. +!TP_BWMIX_LABEL;Black-and-White +!TP_BWMIX_MET;Method +!TP_BWMIX_MET_CHANMIX;Channel Mixer +!TP_BWMIX_MET_DESAT;Desaturation +!TP_BWMIX_MET_LUMEQUAL;Luminance Equalizer +!TP_BWMIX_MIXC;Mixer +!TP_BWMIX_NEUTRAL;Reset mixer +!TP_BWMIX_NEUTRAL_TIP;Reset all values (Color Filter, Channel Mixer) to default. +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all the mixer options.\n"Total" displays the sum of the RGB values:\n- always 100% in relative mode\n- higher (lighter) or lower (darker) than 100% in absolute mode. +!TP_BWMIX_RGB_TOOLTIP;Mix the RGB channels. Use presets for guidance.\nPay attention to negative values that may cause artifacts or erratic behavior. +!TP_BWMIX_SETTING;Presets +!TP_BWMIX_SETTING_TOOLTIP;Different presets (film, landscape, etc.) or manual Channel Mixer settings. +!TP_BWMIX_SET_HIGHCONTAST;High contrast +!TP_BWMIX_SET_HIGHSENSIT;High Sensitivity +!TP_BWMIX_SET_HYPERPANCHRO;Hyper Panchromatic +!TP_BWMIX_SET_INFRARED;Infrared +!TP_BWMIX_SET_LANDSCAPE;Landscape +!TP_BWMIX_SET_LOWSENSIT;Low Sensitivity +!TP_BWMIX_SET_LUMINANCE;Luminance +!TP_BWMIX_SET_NORMCONTAST;Normal Contrast +!TP_BWMIX_SET_ORTHOCHRO;Orthochromatic +!TP_BWMIX_SET_PANCHRO;Panchromatic +!TP_BWMIX_SET_PORTRAIT;Portrait +!TP_BWMIX_SET_RGBABS;Absolute RGB +!TP_BWMIX_SET_RGBREL;Relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Relative ROYGCBPM +!TP_BWMIX_TCMODE_FILMLIKE;B&W Film-like +!TP_BWMIX_TCMODE_SATANDVALBLENDING;B&W Saturation and Value Blending +!TP_BWMIX_TCMODE_STANDARD;B&W Standard +!TP_BWMIX_TCMODE_WEIGHTEDSTD;B&W Weighted Standard +!TP_BWMIX_VAL;L +!TP_CHROMATABERR_LABEL;Chromatic Aberration +!TP_COLORAPP_ADAPTSCENE;Scene luminosity +!TP_COLORAPP_ADAPTSCENE_TOOLTIP;Absolute luminance of the scene environement (cd/m²).\n1) Calculated from the Exif data:\nShutter speed - ISO speed - F number - camera exposure correction.\n2) Calculated from the raw white point and RT's Exposure Compensation slider. +!TP_COLORAPP_ADAPTVIEWING;Viewing luminosity (cd/m²) +!TP_COLORAPP_ADAPTVIEWING_TOOLTIP;Absolute luminance of the viewing environnement\n(usually 16cd/m²). +!TP_COLORAPP_ADAP_AUTO_TOOLTIP;If the checkbox is checked (recommended) RawTherapee calculates an optimum value from Exif data.\nTo set the value manually, uncheck the checkbox first. +!TP_COLORAPP_ALGO;Algorithm +!TP_COLORAPP_ALGO_ALL;All +!TP_COLORAPP_ALGO_JC;Lightness + Chroma (JC) +!TP_COLORAPP_ALGO_JS;Lightness + Saturation (JS) +!TP_COLORAPP_ALGO_QM;Brightness + Colorfulness (QM) +!TP_COLORAPP_ALGO_TOOLTIP;Lets you choose between parameter subsets or all parameters. +!TP_COLORAPP_BADPIXSL;Hot/bad pixel filter +!TP_COLORAPP_BADPIXSL_TOOLTIP;Suppression of hot/bad (brightly colored) pixels.\n0 = No effect\n1 = Median\n2 = Gaussian.\nAlternatively, adjust the image to avoid very dark shadows.\n\nThese artifacts are due to limitations of CIECAM02. +!TP_COLORAPP_BRIGHT;Brightness (Q) +!TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from L*a*b* and RGB brightness. +!TP_COLORAPP_CHROMA;Chroma (C) +!TP_COLORAPP_CHROMA_M;Colorfulnes (M) +!TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM02 differs from L*a*b* and RGB colorfulness. +!TP_COLORAPP_CHROMA_S;Saturation (S) +!TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from L*a*b* and RGB saturation. +!TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from L*a*b* and RGB chroma. +!TP_COLORAPP_CIECAT_DEGREE;CAT02 adaptation +!TP_COLORAPP_CONTRAST;Contrast (J) +!TP_COLORAPP_CONTRAST_Q;Contrast (Q) +!TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrast in CIECAM02 for the Q slider; it differs from L*a*b* and RGB contrast. +!TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from L*a*b* and RGB contrast. +!TP_COLORAPP_CURVEEDITOR1;Tone curve 1 +!TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L* (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of J or Q after CIECAM02.\n\nJ and Q are not shown in the main histogram panel.\n\nFor final output refer to the main histogram panel. +!TP_COLORAPP_CURVEEDITOR2;Tone curve 2 +!TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Same usage as with the second exposure tone curve. +!TP_COLORAPP_CURVEEDITOR3;Color curve +!TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Adjust either chroma, saturation or colorfulness.\n\nShows the histogram of chromaticity (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of C, s or M after CIECAM02.\n\nC, s and M are not shown in the main histogram panel.\nFor final output refer to the main histogram panel. +!TP_COLORAPP_DATACIE;CIECAM02 output histograms in curves +!TP_COLORAPP_DATACIE_TOOLTIP;When enabled, histograms in CIECAM02 curves show approximate values/ranges for J or Q, and C, s or M after the CIECAM02 adjustments.\nThis selection does not impact the main histogram panel.\n\nWhen disabled, histograms in CIECAM02 curves show L*a*b* values before CIECAM02 adjustments. +!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RawTherapee calculates an optimum value, which is then used by CAT02, and also for the entire CIECAM02.\nTo set the value manually, uncheck the check-box first (values above 65 are recommended). +!TP_COLORAPP_DEGREE_TOOLTIP;Amount of CIE Chromatic Adaptation Transform 2002. +!TP_COLORAPP_GAMUT;Gamut control (L*a*b*) +!TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in L*a*b* mode. +!TP_COLORAPP_HUE;Hue (h) +!TP_COLORAPP_HUE_TOOLTIP;Hue (h) - angle between 0° and 360°. +!TP_COLORAPP_LABEL;CIE Color Appearance Model 2002 +!TP_COLORAPP_LABEL_CAM02;Image Adjustments +!TP_COLORAPP_LABEL_SCENE;Scene Conditions +!TP_COLORAPP_LABEL_VIEWING;Viewing Conditions +!TP_COLORAPP_LIGHT;Lightness (J) +!TP_COLORAPP_LIGHT_TOOLTIP;Lightness in CIECAM02 differs from L*a*b* and RGB lightness. +!TP_COLORAPP_MODEL;WP Model +!TP_COLORAPP_MODEL_TOOLTIP;White-Point Model.\n\nWB [RT] + [output]: RT's white balance is used for the scene, CIECAM02 is set to D50, and the output device's white balance is set in Preferences > Color Management.\n\nWB [RT+CAT02] + [output]: RT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences - Color Management. +!TP_COLORAPP_RSTPRO;Red & skin-tones protection +!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin-tones protection affects both sliders and curves. +!TP_COLORAPP_SHARPCIE;--unused-- +!TP_COLORAPP_SHARPCIE_TOOLTIP;--unused-- +!TP_COLORAPP_SURROUND;Surround +!TP_COLORAPP_SURROUND_AVER;Average +!TP_COLORAPP_SURROUND_DARK;Dark +!TP_COLORAPP_SURROUND_DIM;Dim +!TP_COLORAPP_SURROUND_EXDARK;Extremly Dark (Cutsheet) +!TP_COLORAPP_SURROUND_TOOLTIP;Changes tones and colors to take into account the viewing conditions of the output device.\n\nAverage: Average light environment (standard). The image will not change.\n\nDim: Dim environment (TV). The image will become slighty dark.\n\nDark: Dark environment (projector). The image will become more dark.\n\nExtremly Dark: Extremly dark environment (cutsheet). The image will become very dark. +!TP_COLORAPP_SURSOURCE;Dark surround +!TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if image has a dark border. +!TP_COLORAPP_TCMODE_BRIGHTNESS;Brightness +!TP_COLORAPP_TCMODE_CHROMA;Chroma +!TP_COLORAPP_TCMODE_COLORF;Colorfulness +!TP_COLORAPP_TCMODE_LABEL1;Curve mode 1 +!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_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] +!TP_COLORAPP_WBRT;WB [RT] + [output] +!TP_COLORTONING_AB;o C/L +!TP_COLORTONING_AUTOSAT;Automatic +!TP_COLORTONING_BALANCE;Balance +!TP_COLORTONING_BY;o C/L +!TP_COLORTONING_CHROMAC;Opacity +!TP_COLORTONING_COLOR;Color +!TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;Chroma opacity as a function of luminance oC=f(L) +!TP_COLORTONING_HIGHLIGHT;Highlights +!TP_COLORTONING_HUE;Hue +!TP_COLORTONING_LABEL;Color Toning +!TP_COLORTONING_LAB;L*a*b* blending +!TP_COLORTONING_LUMAMODE;Preserve luminance +!TP_COLORTONING_LUMAMODE_TOOLTIP;If enabled, when you change color (red, green, cyan, blue, etc.) the luminance of each pixel is preserved. +!TP_COLORTONING_LUMA;Luminance +!TP_COLORTONING_METHOD;Method +!TP_COLORTONING_METHOD_TOOLTIP;"L*a*b* blending", "RGB sliders" and "RGB curves" use interpolated color blending.\n"Color balance (Shadows/Midtones/Highlights)" and "Saturation 2 colors" use direct colors.\n\nThe Black-and-White tool can be enabled when using any color toning method, which allows for color toning. +!TP_COLORTONING_MIDTONES;Midtones +!TP_COLORTONING_NEUTRAL;Reset sliders +!TP_COLORTONING_NEUTRAL_TIP;Reset all values (Shadows, Midtones, Highlights) to default. +!TP_COLORTONING_OPACITY;Opacity +!TP_COLORTONING_RGBCURVES;RGB - Curves +!TP_COLORTONING_RGBSLIDERS;RGB - Sliders +!TP_COLORTONING_SATURATEDOPACITY;Strength +!TP_COLORTONING_SATURATIONTHRESHOLD;Threshold +!TP_COLORTONING_SA;Saturation Protection +!TP_COLORTONING_SHADOWS;Shadows +!TP_COLORTONING_SPLITCOCO;Color Balance Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITCO;Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITLR;Saturation 2 colors +!TP_COLORTONING_STRENGTH;Strength +!TP_COLORTONING_STR;Strength +!TP_COLORTONING_TWO2;Special chroma '2 colors' +!TP_COLORTONING_TWOALL;Special chroma +!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_GTFRAME;Frame +!TP_CROP_GTGRID;Grid +!TP_CROP_GTHARMMEANS;Harmonic Means +!TP_CROP_GTTRIANGLE1;Golden Triangles 1 +!TP_CROP_GTTRIANGLE2;Golden Triangles 2 +!TP_CROP_PPI;PPI= +!TP_DARKFRAME_AUTOSELECT;Auto-selection +!TP_DARKFRAME_LABEL;Dark-Frame +!TP_DEFRINGE_LABEL;Defringe +!TP_DEFRINGE_RADIUS;Radius +!TP_DEFRINGE_THRESHOLD;Threshold +!TP_DIRPYRDENOISE_33;3×3 strong +!TP_DIRPYRDENOISE_55SOFT;5×5 +!TP_DIRPYRDENOISE_55;5×5 strong +!TP_DIRPYRDENOISE_77;7×7 (slow) +!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_ABM;Chroma only +!TP_DIRPYRDENOISE_AUTO;Automatic global +!TP_DIRPYRDENOISE_AUTO_TOOLTIP;Try to evaluate chroma noise\nBe careful, this calculation is average, and is quite subjective ! +!TP_DIRPYRDENOISE_AUT;Automatic global +!TP_DIRPYRDENOISE_BLUE;Chrominance - Blue-Yellow +!TP_DIRPYRDENOISE_C2TYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CCCURVE;Chrominance curve +!TP_DIRPYRDENOISE_CHROMAFR;Chrominance +!TP_DIRPYRDENOISE_CHROMA;Chrominance - Master +!TP_DIRPYRDENOISE_CTYPE;Auto method +!TP_DIRPYRDENOISE_CTYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nAutomatic multi-zones\nNo preview - works only during saving, but using the "Preview" method by matching the tile size and center to the preview size and center you can get an idea of the expected results.\nThe image is divided into tiles (about 10 to 70 depending on image size) and each tile receives its own chrominance noise reduction settings.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CURVEEDITOR_CC;Chroma +!TP_DIRPYRDENOISE_CURVEEDITOR_CC_TOOLTIP;Increase (multiply) the value of all chrominance sliders.\nThis curve lets you adjust the strength of chromatic noise reduction as a function of chromaticity, for instance to increase the action in areas of low saturation and to decrease it in those of high saturation. +!TP_DIRPYRDENOISE_CURVEEDITOR_L_TOOLTIP;Modulates action of 'Luminance' denoise +!TP_DIRPYRDENOISE_CUR;Curve +!TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on the gamma of the input color profile. An sRGB gamma is assumed, thus if the image uses an input color profile of a different gamma, the effects of luminance noise reduction will differ. +!TP_DIRPYRDENOISE_ENH;Enhanced mode +!TP_DIRPYRDENOISE_ENH_TOOLTIP;Increases noise reduction quality at the expense of a 20% processing time increase. +!TP_DIRPYRDENOISE_GAMMA;Gamma +!TP_DIRPYRDENOISE_GAMMA_TOOLTIP;Gamma varies noise reduction strength across the range of tones. Smaller values will target shadows, while larger values will stretch the effect to the brighter tones. +!TP_DIRPYRDENOISE_LABEL;Noise Reduction +!TP_DIRPYRDENOISE_LABM;L*a*b* +!TP_DIRPYRDENOISE_LAB;L*a*b* +!TP_DIRPYRDENOISE_LCURVE;Luminance curve +!TP_DIRPYRDENOISE_LDETAIL;Luminance - Detail +!TP_DIRPYRDENOISE_LM;Luminance only +!TP_DIRPYRDENOISE_LPLABM;Weighted L* (little) + a*b* (normal) +!TP_DIRPYRDENOISE_LTYPE;Luminance control +!TP_DIRPYRDENOISE_LUMAFR;Luminance +!TP_DIRPYRDENOISE_LUMAFR_TOOLTIP;Wavelet on luminance and Fourier transform for luminance detail +!TP_DIRPYRDENOISE_LUMA;Luminance +!TP_DIRPYRDENOISE_MANU;Manual +!TP_DIRPYRDENOISE_MAN;Manual +!TP_DIRPYRDENOISE_MEDMETHOD;Median method +!TP_DIRPYRDENOISE_MEDTYPE;Median type +!TP_DIRPYRDENOISE_MED;Median Filter +!TP_DIRPYRDENOISE_MED_TOOLTIP;Enabled median denoising +!TP_DIRPYRDENOISE_METHOD11;Quality +!TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. +!TP_DIRPYRDENOISE_METHOD;Method +!TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or L*a*b* methods can be used.\n\nFor non-raw images the L*a*b* method will be used, regardless of the selection. +!TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - +!TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 +!TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. +!TP_DIRPYRDENOISE_PASSES;Median iterations +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PON;Auto multi-zones +!TP_DIRPYRDENOISE_PREVLABEL;Preview size=%1, Center: Px=%2 Py=%3 +!TP_DIRPYRDENOISE_PREV;Preview +!TP_DIRPYRDENOISE_PRE;Preview multi-zones +!TP_DIRPYRDENOISE_RED;Chrominance - Red-Green +!TP_DIRPYRDENOISE_RGBM;RGB +!TP_DIRPYRDENOISE_RGB;RGB +!TP_DIRPYRDENOISE_SHALBI;High +!TP_DIRPYRDENOISE_SHAL;Standard +!TP_DIRPYRDENOISE_SLI;Slider +!TP_DIRPYRDENOISE_SOFT;3x3 +!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_LUMAFINEST;Finest +!TP_DIRPYREQUALIZER_LUMANEUTRAL;Neutral +!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_THRESHOLD;Threshold +!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;Auto Distortion Correction +!TP_DISTORTION_AUTO_TIP;Correct lens distortion automatically for some cameras (Micro 4/3, some compact digital cameras, etc.). +!TP_EPD_EDGESTOPPING;Edge stopping +!TP_EPD_GAMMA;Gamma +!TP_EPD_LABEL;Tone Mapping +!TP_EPD_REWEIGHTINGITERATES;Reweighting iterates +!TP_EPD_SCALE;Scale +!TP_EPD_STRENGTH;Strength +!TP_EPD_TOOLTIP;Tone mapping is possible in L*a*b* mode (standard) and CIECAM02 mode.\n\nWhen in L*a*b* mode, tone mapping can also be used on the residual image of the Wavelet Levels tool.\n\nTo engage CIECAM02 tone mapping mode enable the following settings:\n1. CIECAM02\n2. Algorithm="Brightness + Colorfulness (QM)"\n3. "Tone mapping using CIECAM02 brightness (Q)" +!TP_EXPOSURE_AUTOLEVELS_TIP;Toggles execution of Auto Levels to automatically set Exposure slider values based on an image analysis.\nEnables Highlight Reconstruction if necessary. +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in Auto Levels operation. +!TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Highlight compression threshold +!TP_EXPOSURE_CURVEEDITOR1;Tone curve 1 +!TP_EXPOSURE_CURVEEDITOR2;Tone curve 2 +!TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Please refer to the "Exposure > Tone Curves" RawPedia article to learn how to achieve the best results by using two tone curves. +!TP_EXPOSURE_SATURATION;Saturation +!TP_EXPOSURE_TCMODE_FILMLIKE;Film-like +!TP_EXPOSURE_TCMODE_LABEL1;Curve mode 1 +!TP_EXPOSURE_TCMODE_LABEL2;Curve mode 2 +!TP_EXPOSURE_TCMODE_LUMINANCE;Luminance +!TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Saturation and Value Blending +!TP_EXPOSURE_TCMODE_STANDARD;Standard +!TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard +!TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points +!TP_EXPOS_WHITEPOINT_LABEL;Raw White Points +!TP_FILMSIMULATION_LABEL;Film Simulation +!TP_FILMSIMULATION_STRENGTH;Strength +!TP_FILMSIMULATION_ZEROCLUTSFOUND;Set HaldCLUT directory in Preferences +!TP_FLATFIELD_AUTOSELECT;Auto-selection +!TP_FLATFIELD_BLURRADIUS;Blur radius +!TP_FLATFIELD_BLURTYPE;Blur type +!TP_FLATFIELD_BT_AREA;Area +!TP_FLATFIELD_BT_HORIZONTAL;Horizontal +!TP_FLATFIELD_BT_VERTHORIZ;Vertical + Horizontal +!TP_FLATFIELD_BT_VERTICAL;Vertical +!TP_FLATFIELD_CLIPCONTROL;Clip control +!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. +!TP_FLATFIELD_LABEL;Flat-Field +!TP_GAMMA_CURV;Gamma +!TP_GAMMA_FREE;Free gamma +!TP_GAMMA_OUTPUT;Output gamma +!TP_GAMMA_SLOP;Slope (linear) +!TP_GENERAL_11SCALE_TOOLTIP;The effects of this tool are only visible or only accurate at a preview scale of 1:1. +!TP_GRADIENT_CENTER;Center +!TP_GRADIENT_CENTER_X;Center X +!TP_GRADIENT_CENTER_X_TOOLTIP;Shift gradient to the left (negative values) or right (positive values). +!TP_GRADIENT_CENTER_Y;Center Y +!TP_GRADIENT_CENTER_Y_TOOLTIP;Shift gradient up (negative values) or down (positive values). +!TP_GRADIENT_DEGREE;Angle +!TP_GRADIENT_DEGREE_TOOLTIP;Rotation angle in degrees. +!TP_GRADIENT_FEATHER;Feather +!TP_GRADIENT_FEATHER_TOOLTIP;Gradient width in percent of the image diagonal. +!TP_GRADIENT_LABEL;Graduated Filter +!TP_GRADIENT_STRENGTH;Strength +!TP_GRADIENT_STRENGTH_TOOLTIP;Filter strength in stops. +!TP_HLREC_BLEND;Blend +!TP_HLREC_ENA_TOOLTIP;Could be activated by Auto Levels. +!TP_HSVEQUALIZER_CHANNEL;Channel +!TP_HSVEQUALIZER_HUE;H +!TP_HSVEQUALIZER_LABEL;HSV Equalizer +!TP_HSVEQUALIZER_SAT;S +!TP_HSVEQUALIZER_VAL;V +!TP_ICM_BLENDCMSMATRIX;Blend ICC highlights with matrix +!TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover clipped highlights when using LUT-based ICC profiles. +!TP_ICM_DCPILLUMINANT;Illuminant +!TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolated +!TP_ICM_DCPILLUMINANT_TOOLTIP;Select which embedded DCP illuminant to employ. Default is "interpolated" which is a mix between the two based on white balance. The setting is only enabled if a Dual-Illuminant DCP with interpolation support is selected. +!TP_ICM_INPUTCAMERAICC;Auto-matched camera profile +!TP_ICM_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input color profiles. These profiles are more precise than simpler matrix ones. They are not available for all cameras. These profiles are stored in the /iccprofiles/input and /dcpprofiles folders and are automatically retrieved based on a file name matching to the exact model name of the camera. +!TP_ICM_INPUTCAMERA_TOOLTIP;Use a simple color matrix from dcraw, an enhanced RawTherapee version (whichever is available based on camera model) or one embedded in the DNG. +!TP_ICM_INPUTCUSTOM_TOOLTIP;Select your own DCP/ICC color profile file for the camera. +!TP_ICM_INPUTEMBEDDED_TOOLTIP;Use color profile embedded in non-raw files. +!TP_ICM_INPUTNONE;No profile +!TP_ICM_INPUTNONE_TOOLTIP;Use no input color profile at all.\nUse only in special cases. +!TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance +!TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. The result can be used for calibration purposes and generation of a camera profile. +!TP_ICM_TONECURVE;Use DCP's tone curve +!TP_ICM_TONECURVE_TOOLTIP;Employ the embedded DCP tone curve. The setting is only enabled if the selected DCP has a tone curve. +!TP_IMPULSEDENOISE_LABEL;Impulse Noise Reduction +!TP_IMPULSEDENOISE_THRESH;Threshold +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid color shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction. +!TP_LABCURVE_BRIGHTNESS;Lightness +!TP_LABCURVE_CHROMATICITY;Chromaticity +!TP_LABCURVE_CHROMA_TOOLTIP;To apply B&W toning, set Chromaticity to -100. +!TP_LABCURVE_CONTRAST;Contrast +!TP_LABCURVE_CURVEEDITOR;Luminance Curve +!TP_LABCURVE_CURVEEDITOR_A_RANGE1;Green Saturated +!TP_LABCURVE_CURVEEDITOR_A_RANGE2;Green Pastel +!TP_LABCURVE_CURVEEDITOR_A_RANGE3;Red Pastel +!TP_LABCURVE_CURVEEDITOR_A_RANGE4;Red Saturated +!TP_LABCURVE_CURVEEDITOR_B_RANGE1;Blue Saturated +!TP_LABCURVE_CURVEEDITOR_B_RANGE2;Blue Pastel +!TP_LABCURVE_CURVEEDITOR_B_RANGE3;Yellow Pastel +!TP_LABCURVE_CURVEEDITOR_B_RANGE4;Yellow Saturated +!TP_LABCURVE_CURVEEDITOR_CC;CC +!TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutral +!TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Dull +!TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastel +!TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Saturated +!TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Chromaticity according to chromaticity C=f(C) +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to hue C=f(H) +!TP_LABCURVE_CURVEEDITOR_CL;CL +!TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Chromaticity according to luminance C=f(L) +!TP_LABCURVE_CURVEEDITOR_HH;HH +!TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Hue according to hue H=f(H) +!TP_LABCURVE_CURVEEDITOR_LC;LC +!TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminance according to chromaticity L=f(C) +!TP_LABCURVE_CURVEEDITOR_LH;LH +!TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H) +!TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminance according to luminance L=f(L) +!TP_LABCURVE_LABEL;L*a*b* Adjustments +!TP_LABCURVE_LCREDSK;Restrict LC to red and skin-tones +!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_LENSGEOM_AUTOCROP;Auto-Crop +!TP_LENSGEOM_FILL;Auto-fill +!TP_LENSGEOM_LABEL;Lens / Geometry +!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_USECA;Chromatic aberration correction +!TP_LENSPROFILE_USEDIST;Distortion correction +!TP_LENSPROFILE_USEVIGN;Vignetting correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Resets exposure sliders to neutral values.\nApplies to the same controls that Auto Levels applies to, regardless of whether you used Auto Levels or not. +!TP_PCVIGNETTE_FEATHER;Feather +!TP_PCVIGNETTE_FEATHER_TOOLTIP;Feathering:\n0 = corners only,\n50 = halfway to center,\n100 = to center. +!TP_PCVIGNETTE_LABEL;Vignette Filter +!TP_PCVIGNETTE_ROUNDNESS;Roundness +!TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness:\n0 = rectangle,\n50 = fitted ellipse,\n100 = circle. +!TP_PCVIGNETTE_STRENGTH;Strength +!TP_PCVIGNETTE_STRENGTH_TOOLTIP;Filter strength in stops (reached in corners). +!TP_PERSPECTIVE_HORIZONTAL;Horizontal +!TP_PERSPECTIVE_LABEL;Perspective +!TP_PERSPECTIVE_VERTICAL;Vertical +!TP_PFCURVE_CURVEEDITOR_CH;Hue +!TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Controls defringe strength by color.\nHigher = more,\nLower = less. +!TP_PREPROCESS_DEADPIXFILT;Dead pixel filter +!TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Tries to suppress dead pixels. +!TP_PREPROCESS_GREENEQUIL;Green equilibration +!TP_PREPROCESS_HOTPIXFILT;Hot pixel filter +!TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Tries to suppress hot pixels. +!TP_PREPROCESS_LABEL;Preprocessing +!TP_PREPROCESS_LINEDENOISE;Line noise filter +!TP_PREPROCESS_NO_FOUND;None found +!TP_RAWCACORR_AUTO;Auto-correction +!TP_RAWCACORR_CABLUE;Blue +!TP_RAWCACORR_CARED;Red +!TP_RAWEXPOS_BLACKS;Black Levels +!TP_RAWEXPOS_BLACK_0;Green 1 (lead) +!TP_RAWEXPOS_BLACK_1;Red +!TP_RAWEXPOS_BLACK_2;Blue +!TP_RAWEXPOS_BLACK_3;Green 2 +!TP_RAWEXPOS_BLACK_BLUE;Blue +!TP_RAWEXPOS_BLACK_GREEN;Green +!TP_RAWEXPOS_BLACK_RED;Red +!TP_RAWEXPOS_LINEAR;White-point correction +!TP_RAWEXPOS_PRESER;Highlight preservation +!TP_RAWEXPOS_RGB;Red, Green, Blue +!TP_RAWEXPOS_TWOGREEN;Link greens +!TP_RAW_DCBENHANCE;DCB enhancement +!TP_RAW_DCBITERATIONS;Number of DCB iterations +!TP_RAW_DMETHOD_PROGRESSBAR;%1 demosaicing... +!TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Demosaicing refinement... +!TP_RAW_DMETHOD_TOOLTIP;Note: IGV and LMMSE are dedicated to high ISO images to aid in noise reduction without leading to maze patterns, posterization or a washed-out look. +!TP_RAW_HD;Threshold +!TP_RAW_HD_TOOLTIP;Lower values make hot/dead pixel detection more aggressive, but false positives may lead to artifacts. If you notice any artifacts appearing when enabling the Hot/Dead Pixel Filters, gradually increase the threshold value until they disappear. +!TP_RAW_LABEL;Demosaicing +!TP_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!TP_RAW_LMMSE_TOOLTIP;Adds gamma (step 1), median (steps 2-4) and refinement (steps 5-6) to reduce artifacts and improve the signal-to-noise ratio. +!TP_RAW_SENSOR_BAYER_LABEL;Sensor with Bayer Matrix +!TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;3-pass gives best results (recommended for low ISO images).\n1-pass is almost undistinguishable from 3-pass for high ISO images and is faster. +!TP_RAW_SENSOR_XTRANS_LABEL;Sensor with X-Trans Matrix +!TP_RESIZE_APPLIESTO;Applies to: +!TP_RESIZE_CROPPEDAREA;Cropped Area +!TP_RESIZE_FITBOX;Bounding Box +!TP_RESIZE_FULLIMAGE;Full Image +!TP_RESIZE_HEIGHT;Height +!TP_RESIZE_LANCZOS;Lanczos +!TP_RESIZE_SPECIFY;Specify: +!TP_RESIZE_WIDTH;Width +!TP_RGBCURVES_BLUE;B +!TP_RGBCURVES_CHANNEL;Channel +!TP_RGBCURVES_GREEN;G +!TP_RGBCURVES_LABEL;RGB Curves +!TP_RGBCURVES_LUMAMODE;Luminosity mode +!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_RGBCURVES_RED;R +!TP_SAVEDIALOG_OK_TIP;Shortcut: Ctrl-Enter +!TP_SHADOWSHLIGHTS_SHARPMASK;Sharp mask +!TP_SHARPENEDGE_AMOUNT;Quantity +!TP_SHARPENEDGE_LABEL;Edges +!TP_SHARPENEDGE_PASSES;Iterations +!TP_SHARPENEDGE_THREE;Luminance only +!TP_SHARPENING_TOOLTIP;Expect a slightly different effect when using with CIECAM02. If difference is observed, adjust to taste. +!TP_SHARPENMICRO_AMOUNT;Quantity +!TP_SHARPENMICRO_LABEL;Microcontrast +!TP_SHARPENMICRO_MATRIX;3×3 matrix instead of 5×5 +!TP_SHARPENMICRO_UNIFORMITY;Uniformity +!TP_VIBRANCE_AVOIDCOLORSHIFT;Avoid color shift +!TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Red/Purple +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Red +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Red/Yellow +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Yellow +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Hue according to hue H=f(H) +!TP_VIBRANCE_LABEL;Vibrance +!TP_VIBRANCE_PASTELS;Pastel Tones +!TP_VIBRANCE_PASTSATTOG;Link pastel and saturated tones +!TP_VIBRANCE_PROTECTSKINS;Protect skin-tones +!TP_VIBRANCE_PSTHRESHOLD;Pastel/saturated tones threshold +!TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Saturation threshold +!TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;The vertical axis represents pastel tones at the bottom and saturated tones at the top.\nThe horizontal axis represents the saturation range. +!TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Pastel/saturated transition's weighting +!TP_VIBRANCE_SATURATED;Saturated Tones +!TP_VIGNETTING_CENTER;Center +!TP_VIGNETTING_CENTER_X;Center X +!TP_VIGNETTING_CENTER_Y;Center Y +!TP_VIGNETTING_STRENGTH;Strength +!TP_WAVELET_1;Level 1 +!TP_WAVELET_2;Level 2 +!TP_WAVELET_3;Level 3 +!TP_WAVELET_4;Level 4 +!TP_WAVELET_5;Level 5 +!TP_WAVELET_6;Level 6 +!TP_WAVELET_7;Level 7 +!TP_WAVELET_8;Level 8 +!TP_WAVELET_9;Level 9 +!TP_WAVELET_ALL;All levels in all directions +!TP_WAVELET_APPLYTO;Apply To +!TP_WAVELET_AVOID;Avoid color shift +!TP_WAVELET_B0;Black +!TP_WAVELET_B1;Grey +!TP_WAVELET_B2;Residual +!TP_WAVELET_BACUR;Curve +!TP_WAVELET_BALANCE;Contrast balance d/v-h +!TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chromaticity or residual tone mapping are activated, the effect due to balance is amplified. +!TP_WAVELET_BALCHRO;Chroma balance +!TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chromaticity balance. +!TP_WAVELET_BANONE;None +!TP_WAVELET_BASLI;Slider +!TP_WAVELET_BATYPE;Contrast balance method +!TP_WAVELET_CCURVE;Local contrast +!TP_WAVELET_CH1;Whole chromaticity range +!TP_WAVELET_CH2;Saturated/pastel +!TP_WAVELET_CH3;Link contrast levels +!TP_WAVELET_CHCU;Curve +!TP_WAVELET_CHRO;Saturated/pastel threshold +!TP_WAVELET_CHRO_TOOLTIP;Sets the wavelet level which will be the threshold between saturated and pastel colors.\n1-x: saturated\nx-9: pastel\n\nIf the value exceeds the amount of wavelet levels you are using then it will be ignored. +!TP_WAVELET_CHR;Chroma-contrast link strength +!TP_WAVELET_CHR_TOOLTIP;Adjusts chromaticity as a function of "contrast levels" and "chroma-contrast link strength" +!TP_WAVELET_CHSL;Sliders +!TP_WAVELET_CHTYPE;Chrominance method +!TP_WAVELET_COLORT;Opacity Red-Green +!TP_WAVELET_COMBOTH;Both +!TP_WAVELET_COMPCONT;Contrast +!TP_WAVELET_COMPGAMMA;Compression gamma +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjusting the gamma of the residual image allow you to equilibrate the data and histogram. +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjust gamma for residual image and compression.\nAllow to equilibrate data and histogram +!TP_WAVELET_COMPTM;Tone mapping +!TP_WAVELET_CONTEDIT;'After' Contrast curve +!TP_WAVELET_CONTEDIT;'After' contrast curve +!TP_WAVELET_CONTRAST_MINUS;Contrast - +!TP_WAVELET_CONTRAST_PLUS;Contrast + +!TP_WAVELET_CONTRA;Contrast +!TP_WAVELET_CONTRA_TOOLTIP;Changes contrast of the residual image. +!TP_WAVELET_CONTR;Gamut +!TP_WAVELET_CTYPE;Chrominance control +!TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modifies local contrast as a function of the original local contrast (absciss)\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 100..300)\n66% absciss represents standard deviation of local contrast (real value about 300..800)\n100% represents maximum (real value about 3000..8000) +!TP_WAVELET_CURVEEDITOR_CH;Contrast levels=f(Hue) +!TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modifies each level's contrast as a function oh hue.\nTake care not to overwrite changes made with the Gamut Hue controls.\nThe curve will only have an effect when wavelet contrast level sliders are non-zero. +!TP_WAVELET_CURVEEDITOR_CL;L +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Applies a final contrast luminance curve at the end of the wavelet treatment. +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Apply a contrast luminance curve at the end of wavelet level threatment +!TP_WAVELET_CURVEEDITOR_HH;HH +!TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modifies the residual image's hue as a function of hue. +!TP_WAVELET_DALL;All directions +!TP_WAVELET_DAUB;Edge performance +!TP_WAVELET_DAUB_TOOLTIP;Changes Daubechies coefficients:\nD4 = Standard,\nD14 = Often best performance, 10% more time-intensive.\n\nAffects edge detection as well as the general quality of the firsts levels. However the quality is not strictly related to this coefficient and can vary with images and uses. +!TP_WAVELET_DISP;Preview Settings +!TP_WAVELET_DONE;Vertical +!TP_WAVELET_DTHR;Diagonal +!TP_WAVELET_DTWO;Horizontal +!TP_WAVELET_EDCU;Curve +!TP_WAVELET_EDGCONT;Local contrast +!TP_WAVELET_EDGCONT_TOOLTIP;Adjusting the points to the left decreases contrast, and to the right increases it.\nBottom-left, Top-Left, Top-Right, Bottom-right represent respectively local contast for low values, mean, mean+stdev, maxima +!TP_WAVELET_EDGEDETECTTHR2;Threshold high (detection) +!TP_WAVELET_EDGEDETECTTHR;Threshold low (noise) +!TP_WAVELET_EDGEDETECTTHR_TOOLTIP;This adjuster lets you target edge detection for example to avoid applying edge sharpness to fine details, such as noise in the sky. +!TP_WAVELET_EDGEDETECT;Gradient sensitivity +!TP_WAVELET_EDGEDETECT_TOOLTIP;Moving the slider to the right increases edge sensitivity. This affects local contrast, edge settings and noise. +!TP_WAVELET_EDGE;Edge Sharpness +!TP_WAVELET_EDGREINF_TOOLTIP;Reinforce or reduce the action of the first level, do the opposite to the second level, and leave the rest unchanged. +!TP_WAVELET_EDGTHRESH;Detail +!TP_WAVELET_EDGTHRESH_TOOLTIP;Change the repartition between the first levels and the others. The higher the threshold the more the action is centred on the first levels. Be careful with negative values, they increase the action of high levels and can introduce artifacts. +!TP_WAVELET_EDRAD;Radius +!TP_WAVELET_EDRAD_TOOLTIP;This radius adjustment is very different from those in other sharpening tools. Its value is compared to each level through a complex function. In this sense, a value of zero still has an effect. +!TP_WAVELET_EDSL;Threshold Sliders +!TP_WAVELET_EDTYPE;Local contrast method +!TP_WAVELET_EDVAL;Strength +!TP_WAVELET_FINAL;Final Touchup +!TP_WAVELET_FINEST;Finest +!TP_WAVELET_HIGHLIGHT;Highlight luminance range +!TP_WAVELET_HS1;Whole luminance range +!TP_WAVELET_HS2;Shadows/Highlights +!TP_WAVELET_HUESKIN;Skin hue +!TP_WAVELET_HUESKIN_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_HUESKY;Sky hue +!TP_WAVELET_HUESKY_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_INF;Below or equal the level +!TP_WAVELET_ITER;Delta balance levels +!TP_WAVELET_ITER_TOOLTIP;Left: increase low levels and reduce high levels,\nRight: reduce low levels and increase high levels. +!TP_WAVELET_LABEL;Wavelet levels +!TP_WAVELET_LARGEST;Coarsest +!TP_WAVELET_LEVCH;Chromaticity +!TP_WAVELET_LEVELS;Wavelet levels +!TP_WAVELET_LEVELS_TOOLTIP;Choose the number of detail levels the image is to be decomposed into. More levels require more RAM and require a longer processing time. +!TP_WAVELET_LEVF;Contrast +!TP_WAVELET_LEVLABEL;Preview maximum possible levels = %1 +!TP_WAVELET_LEVONE;Level 2 +!TP_WAVELET_LEVTWO;Level 3 +!TP_WAVELET_LEVZERO;Level 1 +!TP_WAVELET_LINKEDG;Link with Edge Sharpness' Strength +!TP_WAVELET_LIPST;Enhanced algorithm +!TP_WAVELET_LIPST_TOOLTIP;This algorithm uses Lipschitz regularity to increase edge detection quality at a cost of increased processing time and memory requirements. +!TP_WAVELET_LOWLIGHT;Shadow luminance range +!TP_WAVELET_MEDGREINF;First level +!TP_WAVELET_MEDILEV;Edge detection +!TP_WAVELET_MEDI;Reduce artifacts in blue sky +!TP_WAVELET_NEUTRAL;Neutral +!TP_WAVELET_NOISE;Denoise and Refine +!TP_WAVELET_NOIS;Denoise +!TP_WAVELET_ONE;One level +!TP_WAVELET_OPACITYWL;Final local contrast +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify final local contrast in function of last local contrast (absciss) for all levels decomposition\nTake into account: \na)contrast levels \nb)edge sharpness \nc)contrast balance\nd)decomposition-recomposition\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 200..1000)\n66% absciss represents standard deviation of local contrast (real value about 1000..2000)\n100% represents maximum (real value about 5000..13000) +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify the final local contrast at the end of the wavelet treatment.\n\nThe left side represents the smallest local contrast, progressing to the largest local contrast on the right. +!TP_WAVELET_OPACITYW;Contrast balance d/v-h curve +!TP_WAVELET_OPACITY;Opacity Blue-Yellow +!TP_WAVELET_PASTEL;Pastel chromaticity +!TP_WAVELET_PREVIEWBACK;Background +!TP_WAVELET_PREVIEWLEVELS;Preview +!TP_WAVELET_RE1;Reinforced +!TP_WAVELET_RE2;Unchanged +!TP_WAVELET_RE3;Reduced +!TP_WAVELET_RESCHRO;Chromaticity +!TP_WAVELET_RESCONH;Highlights +!TP_WAVELET_RESCON;Shadows +!TP_WAVELET_RESID;Residual image +!TP_WAVELET_SAT;Saturated chromaticity +!TP_WAVELET_SETTINGS;Wavelet Settings +!TP_WAVELET_SKIN;Skin targetting/protection +!TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected. +!TP_WAVELET_SKY;Sky targetting/protection +!TP_WAVELET_SKY_TOOLTIP;At -100 sky-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 sky-tones are protected while all other tones are affected. +!TP_WAVELET_STRENGTH;Strength +!TP_WAVELET_STREN;Strength +!TP_WAVELET_SUPE;Extra +!TP_WAVELET_SUP;Above the level +!TP_WAVELET_THRESHOLD2;Shadow levels +!TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels between 9 and 9 minus the value will be affected by the shadow luminance range. Other levels will be fully treated. The highest level possible is limited by the highlight level value (9 minus highlight level value). +!TP_WAVELET_THRESHOLD;Highlight levels +!TP_WAVELET_THRESHOLD_TOOLTIP;Only levels beyond the chosen value will be affected by the highlight luminance range. Other levels will be fully treated. The chosen value here limits the highest possible value of the shadow levels. +!TP_WAVELET_THRH;Highlights threshold +!TP_WAVELET_THR;Shadows threshold +!TP_WAVELET_TILESBIG;Big tiles +!TP_WAVELET_TILESFULL;Full image +!TP_WAVELET_TILESIZE;Tiling method +!TP_WAVELET_TILESLIT;Little tiles +!TP_WAVELET_TILES_TOOLTIP;Processing the full image leads to better quality and is the recommended option, while using tiles is a fall-back solution for users with little RAM. Refer to RawPedia for memory requirements. +!TP_WAVELET_TMHIGH;High +!TP_WAVELET_TMLOWHIGH;Low+High +!TP_WAVELET_TMNONE;None +!TP_WAVELET_TMSTD;Standard +!TP_WAVELET_TMSTRENGTH;Compression strength +!TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image. When the value is different from 0, the Strength and Gamma sliders of the Tone Mapping tool in the Exposure tab will become grayed out. +!TP_WAVELET_TMTYPE;Compression method +!TP_WAVELET_TON;Toning +!TP_WAVELET_daub2;D2 - low +!TP_WAVELET_daub4;D4 - standard +!TP_WAVELET_daub6;D6 - standard plus +!TP_WAVELET_daub10;D10 - medium +!TP_WAVELET_daub14;D14 - high +!TP_WBALANCE_CLOUDY;Cloudy +!TP_WBALANCE_DAYLIGHT;Daylight (sunny) +!TP_WBALANCE_EQBLUERED;Blue/Red equalizer +!TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behavior of "white balance" by modulating the blue/red balance.\nThis can be useful when shooting conditions:\na) are far from the standard illuminant (e.g. underwater),\nb) are far from conditions where calibrations were performed,\nc) where the matrices or ICC profiles are unsuitable. +!TP_WBALANCE_FLASH55;Leica +!TP_WBALANCE_FLASH60;Standard, Canon, Pentax, Olympus +!TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta +!TP_WBALANCE_FLASH_HEADER;Flash +!TP_WBALANCE_FLUO1;F1 - Daylight +!TP_WBALANCE_FLUO2;F2 - Cool White +!TP_WBALANCE_FLUO3;F3 - White +!TP_WBALANCE_FLUO4;F4 - Warm White +!TP_WBALANCE_FLUO5;F5 - Daylight +!TP_WBALANCE_FLUO6;F6 - Lite White +!TP_WBALANCE_FLUO7;F7 - D65 Daylight Simulator +!TP_WBALANCE_FLUO8;F8 - D50 / Sylvania F40 Design +!TP_WBALANCE_FLUO9;F9 - Cool White Deluxe +!TP_WBALANCE_FLUO10;F10 - Philips TL85 +!TP_WBALANCE_FLUO11;F11 - Philips TL84 +!TP_WBALANCE_FLUO12;F12 - Philips TL83 +!TP_WBALANCE_FLUO_HEADER;Fluorescent +!TP_WBALANCE_GTI;GTI +!TP_WBALANCE_HMI;HMI +!TP_WBALANCE_JUDGEIII;JudgeIII +!TP_WBALANCE_LAMP_HEADER;Lamp +!TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 +!TP_WBALANCE_LED_HEADER;LED +!TP_WBALANCE_LED_LSI;LSI Lumelex 2040 +!TP_WBALANCE_SHADE;Shade +!TP_WBALANCE_SOLUX35;Solux 3500K +!TP_WBALANCE_SOLUX41;Solux 4100K +!TP_WBALANCE_SOLUX47;Solux 4700K (vendor) +!TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) +!TP_WBALANCE_TUNGSTEN;Tungsten +!TP_WBALANCE_WATER1;UnderWater 1 +!TP_WBALANCE_WATER2;UnderWater 2 +!TP_WBALANCE_WATER_HEADER;UnderWater +!ZOOMPANEL_100;(100%) +!ZOOMPANEL_NEWCROPWINDOW;Open (new) detail window +!ZOOMPANEL_ZOOM100;Zoom to 100%\nShortcut: z +!ZOOMPANEL_ZOOMFITCROPSCREEN;Fit crop to screen\nShortcut: Alt-f +!ZOOMPANEL_ZOOMFITSCREEN;Fit whole image to screen\nShortcut: f +!ZOOMPANEL_ZOOMIN;Zoom In\nShortcut: + +!ZOOMPANEL_ZOOMOUT;Zoom Out\nShortcut: - diff --git a/rtdata/languages/Francais b/rtdata/languages/Francais new file mode 100644 index 000000000..ead415a47 --- /dev/null +++ b/rtdata/languages/Francais @@ -0,0 +1,1854 @@ +#01 2008-03-01 Initial translation by Hombre + +ABOUT_TAB_BUILD;Version +ABOUT_TAB_CREDITS;Crédits +ABOUT_TAB_LICENSE;Licence +ABOUT_TAB_RELEASENOTES;Notes de version +ABOUT_TAB_SPLASH;Splash +ADJUSTER_RESET_TO_DEFAULT;Réglages par défaut +BATCHQUEUE_AUTOSTART;Démarrage auto +BATCHQUEUE_DESTFILENAME;Chemin et nom de fichier +BATCH_PROCESSING;Traitement par lot +CURVEEDITOR_AXIS_IN;E: +CURVEEDITOR_AXIS_LEFT_TAN;TG: +CURVEEDITOR_AXIS_OUT;S: +CURVEEDITOR_AXIS_RIGHT_TAN;TD: +CURVEEDITOR_CURVES;Courbes +CURVEEDITOR_CURVE;Courbe +CURVEEDITOR_CUSTOM;Personnalisé +CURVEEDITOR_DARKS;Zones sombres +CURVEEDITOR_EDITPOINT_HINT;Active l'édition des valeurs d'entrée/sortie.\n\nUn clic droit sur un point le sélectionne.\nUn clic droit dans un espace vide desélectionne le point. +CURVEEDITOR_HIGHLIGHTS;Hautes lumières +CURVEEDITOR_LIGHTS;Zones claires +CURVEEDITOR_LINEAR;Linéaire +CURVEEDITOR_LOADDLGLABEL;Charger la courbe... +CURVEEDITOR_MINMAXCPOINTS;Points de contrôle minima/maxima +CURVEEDITOR_NURBS;Cage de contrôle +CURVEEDITOR_PARAMETRIC;Paramétrique +CURVEEDITOR_SAVEDLGLABEL;Enregistrer la courbe... +CURVEEDITOR_SHADOWS;Ombres bouchées +CURVEEDITOR_TOOLTIPCOPY;Copie la courbe courante dans le presse-papier +CURVEEDITOR_TOOLTIPLINEAR;Réinitialise la courbe en linéaire +CURVEEDITOR_TOOLTIPLOAD;Charger une courbe depuis un fichier +CURVEEDITOR_TOOLTIPPASTE;Colle la courbe du presse-papier +CURVEEDITOR_TOOLTIPSAVE;Enregistrer la courbe actuelle +CURVEEDITOR_TYPE;Type: +DIRBROWSER_FOLDERS;Répertoires +EDITWINDOW_TITLE;Édition d'image +EDIT_OBJECT_TOOLTIP;Affiche des éléments dans la fenêtre de prévisualisation qui vous permettront d'ajuster cet outil. +EDIT_PIPETTE_TOOLTIP;Pour ajouter un point d'ajustement de la courbe, maintenez la touche Ctrl préssée et cliquez dans l'image avec le bouton gauche.\nPour ajuster le point, pressez la touche Ctrl lors du clic-gauche sur la zone correspondande dans l'apperçu, puis relachez Ctrl (sauf si vous désirez un control plus fin) et tout en gardant le bouton gauche appuyé, déplacez le curseur vers le haut ou le bas pour ajuster la position du point. +EXIFFILTER_APERTURE;Ouverture +EXIFFILTER_CAMERA;Appareil photo +EXIFFILTER_EXPOSURECOMPENSATION;Compensation d'exposition (EV) +EXIFFILTER_FILETYPE;Type de fichier +EXIFFILTER_FOCALLEN;Longueur focale +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Objectif +EXIFFILTER_METADATAFILTER;Activer les filtres sur les Métadonnées +EXIFFILTER_SHUTTER;Obturateur +EXIFPANEL_ADDEDITHINT;Ajoute ou édite une donnée +EXIFPANEL_ADDEDIT;Ajouter/Éditer +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Saisissez une valeur +EXIFPANEL_ADDTAGDLG_SELECTTAG;Choisissez une donnée +EXIFPANEL_ADDTAGDLG_TITLE;Ajouter/Éditer une donnée +EXIFPANEL_KEEPHINT;Conserve les données sélectionnées lors de l'écriture du fichier de sortie +EXIFPANEL_KEEP;Conserver +EXIFPANEL_REMOVEHINT;Retire les données sélectionnées lors de l'écriture du fichier de sortie +EXIFPANEL_REMOVE;Retirer +EXIFPANEL_RESETALLHINT;Réinitialise tous les tags à leur valeur initiale +EXIFPANEL_RESETALL;Réinitialiser tout +EXIFPANEL_RESETHINT;Réinitialise les données sélectionnées à la valeur initiale +EXIFPANEL_RESET;Réinitialiser +EXIFPANEL_SUBDIRECTORY;Sous-répertoire +EXPORT_BYPASS_ALL;Sélectionner / Désélectionner tout +EXPORT_BYPASS_DEFRINGE;Ignorer la corr. d'aberration chromatique +EXPORT_BYPASS_DIRPYRDENOISE;Ignorer la réduction du bruit +EXPORT_BYPASS_DIRPYREQUALIZER;Ignorer le contraste par niveaux de détail +EXPORT_BYPASS_RAW_CA;Ignorer la corr. d'aberration chromatique [raw] +EXPORT_BYPASS_RAW_CCSTEPS;Ignorer la suppr. des fausses couleurs [raw] +EXPORT_BYPASS_RAW_DCB_ENHANCE;Ignorer la phase d'amélioration de DCB [raw] +EXPORT_BYPASS_RAW_DCB_ITERATIONS;Ignorer le nombre d'itération de DCB [raw] +EXPORT_BYPASS_RAW_DF;Ignorer la Trame Noire [raw] +EXPORT_BYPASS_RAW_FF;Ignorer le Champ Uniforme [raw] +EXPORT_BYPASS_RAW_GREENTHRESH;Ignorer l'équilibrage du vert [raw] +EXPORT_BYPASS_RAW_LINENOISE;Ignorer le filtre de bruit de ligne [raw] +EXPORT_BYPASS_RAW_LMMSE_ITERATIONS;Ignorer le niveau d'amélioration LMMSE [raw] +EXPORT_BYPASS_SHARPENEDGE;Ignorer netteté des bords +EXPORT_BYPASS_SHARPENING;Ignorer la netteté +EXPORT_BYPASS_SHARPENMICRO;Ignorer netteté des microcontrastes +EXPORT_BYPASS_SH_HQ;Ignorer Ombres/Hautes lumières (HQ) +EXPORT_FASTEXPORTOPTIONS;Options d'Export Rapide +EXPORT_INSTRUCTIONS;Les options d'Export Rapide permettent de forcer des paramètres afin d'éviter d'utiliser des outils très consommateur de temps et de ressources, et d'utiliser ces options dans la file de traitement. Cette méthode est recommandée pour la génération rapide d'images de basse résolution quand la vitesse est une priorité ou lorsqu'on désir une version redimensionnée d'une ou plusieurs images de sortie sans avoir à modifier leurs paramètres de développement. +EXPORT_MAXHEIGHT;Hauteur maximum: +EXPORT_MAXWIDTH;Largeur maximum: +EXPORT_PUTTOQUEUEFAST;Mettre dans la file de traitement\npour Export Rapide +EXPORT_RAW_DMETHOD;Méthode de dématriçage +EXTPROGTARGET_1;raw +EXTPROGTARGET_2;file de traitement +FILEBROWSER_ADDDELTEMPLATE;Ajouter/Supprimer le modèle... +FILEBROWSER_APPLYPROFILE;Appliquer le profil +FILEBROWSER_APPLYPROFILE_PARTIAL;Appliquer le profil (partiel) +FILEBROWSER_AUTODARKFRAME;Soustraction automatique de Trame Noire +FILEBROWSER_AUTOFLATFIELD;Champ Uniforme auto +FILEBROWSER_BROWSEPATHBUTTONHINT;Cliquez pour parcourir le chemin saisi +FILEBROWSER_BROWSEPATHHINT;Saisissez le chemin à parcourir\nCtrl-O pour placer le focus sur le champ de saisie.\nEntrée / Ctrl-Entrée pour y naviguer;\nEsc pour effacer les modifications.\nShift-Esc pour enlever le focus.\n\n\nRaccourcis pour les chemins:\n ~ - le dossier utilisateur\n ! - le dossier Images de l'utilisateur +FILEBROWSER_CACHECLEARFROMFULL;Supprimer du cache (complet) +FILEBROWSER_CACHECLEARFROMPARTIAL;Supprimer du cache (partiel) +FILEBROWSER_CACHE;Cache +FILEBROWSER_CLEARPROFILE;Remettre le profil à zéro +FILEBROWSER_COLORLABEL_TOOLTIP;Label couleur\n\nUtilisez le menu déroulant ou le raccourci clavier:\nShift-Ctrl-0 Pas de couleur\nShift-Ctrl-1 Rouge\nShift-Ctrl-2 Jaune\nShift-Ctrl-3 Vert\nShift-Ctrl-4 Bleu\nShift-Ctrl-5 Pourpre +FILEBROWSER_COPYPROFILE;Copier le profil +FILEBROWSER_CURRENT_NAME;Nom courant: +FILEBROWSER_DARKFRAME;Trame Noire +FILEBROWSER_DELETEDLGLABEL;Confirmation de la suppression de fichier +FILEBROWSER_DELETEDLGMSGINCLPROC;Êtes-vous sûr de vouloir supprimer les %1 fichiers sélectionnés, INCLUANT une version déjà traitée? +FILEBROWSER_DELETEDLGMSG;Êtes-vous sûr de vouloir supprimer les %1 fichiers selectionnés? +FILEBROWSER_EMPTYTRASHHINT;Supprime définitivement les fichiers de la corbeille +FILEBROWSER_EMPTYTRASH;Vider la corbeille +FILEBROWSER_EXEC_CPB;Lancer un constructeur de profil personnalisé +FILEBROWSER_EXTPROGMENU;Ouvrir avec +FILEBROWSER_FLATFIELD;Champ Uniforme +FILEBROWSER_MOVETODARKFDIR;Déplacer dans le dossier d'images de Trame Noire +FILEBROWSER_MOVETOFLATFIELDDIR;Déplacer vers le dossier de Champ Uniforme +FILEBROWSER_NEW_NAME;Nouveau nom: +FILEBROWSER_OPENDEFAULTVIEWER;Visualiseur par défaut de Windows (image déjà traitée) +FILEBROWSER_PARTIALPASTEPROFILE;Coller partiellement +FILEBROWSER_PASTEPROFILE;Coller le profil +FILEBROWSER_POPUPCANCELJOB;Retirer de la file de traitement +FILEBROWSER_POPUPCOLORLABEL0;Label: Aucun +FILEBROWSER_POPUPCOLORLABEL1;Label: Rouge +FILEBROWSER_POPUPCOLORLABEL2;Label: Jaune +FILEBROWSER_POPUPCOLORLABEL3;Label: Vert +FILEBROWSER_POPUPCOLORLABEL4;Label: Bleu +FILEBROWSER_POPUPCOLORLABEL5;Label: Pourpre +FILEBROWSER_POPUPCOLORLABEL;Label couleur +FILEBROWSER_POPUPCOPYTO;Copier vers... +FILEBROWSER_POPUPFILEOPERATIONS;Opérations sur les fichiers +FILEBROWSER_POPUPMOVEEND;Déplacer à la fin de la file +FILEBROWSER_POPUPMOVEHEAD;Déplacer en tête de file +FILEBROWSER_POPUPMOVETO;Déplacer vers... +FILEBROWSER_POPUPOPENINEDITOR;Ouvrir dans l'éditeur +FILEBROWSER_POPUPOPEN;Ouvrir +FILEBROWSER_POPUPPROCESSFAST;Mettre dans la file de traitement (Export Rapide) +FILEBROWSER_POPUPPROCESS;Mettre dans la file de traitement +FILEBROWSER_POPUPPROFILEOPERATIONS;Opérations sur les profils +FILEBROWSER_POPUPRANK0;Aucun +FILEBROWSER_POPUPRANK1;Rang 1 * +FILEBROWSER_POPUPRANK2;Rang 2 ** +FILEBROWSER_POPUPRANK3;Rang 3 *** +FILEBROWSER_POPUPRANK4;Rang 4 **** +FILEBROWSER_POPUPRANK5;Rang 5 ***** +FILEBROWSER_POPUPRANK;Rang +FILEBROWSER_POPUPREMOVEINCLPROC;Supprimer (y compris les sorties de la file de traitement) +FILEBROWSER_POPUPREMOVE;Retirer du système de fichier +FILEBROWSER_POPUPRENAME;Renommer +FILEBROWSER_POPUPSELECTALL;Sélectionner tout +FILEBROWSER_POPUPTRASH;Déplacer dans la corbeille +FILEBROWSER_POPUPUNRANK;Effacer le rang +FILEBROWSER_POPUPUNTRASH;Retirer de la corbeille +FILEBROWSER_QUERYBUTTONHINT;Effacer la recherche +FILEBROWSER_QUERYHINT;Taper la partie du nom du fichier à chercher ou une liste spéarée par des virgules.\nEx: 1001.1004.1199\n\nCtrl-F pour placer le curseur dans le champ de saisie.\nEntrée pour lancer la recherche\nEsc pour effacer.\nShift-Esc pour enlever le focus. +FILEBROWSER_QUERYLABEL;Chercher: +FILEBROWSER_RANK1_TOOLTIP;Rang 1 *\nRaccourci: Shift-1 +FILEBROWSER_RANK2_TOOLTIP;Rang 2 *\nRaccourci: Shift-2 +FILEBROWSER_RANK3_TOOLTIP;Rang 3 *\nRaccourci: Shift-3 +FILEBROWSER_RANK4_TOOLTIP;Rang 4 *\nRaccourci: Shift-4 +FILEBROWSER_RANK5_TOOLTIP;Rang 5 *\nRaccourci: Shift-5 +FILEBROWSER_RENAMEDLGLABEL;Renommage du fichier +FILEBROWSER_RENAMEDLGMSG;Renommer le fichier "%1" en: +FILEBROWSER_SELECTDARKFRAME;Choisir une image de Trame Noire... +FILEBROWSER_SELECTFLATFIELD;Sélectionner un Champ Uniforme... +FILEBROWSER_SHOWCOLORLABEL1HINT;Afficher les images avec un label Rouge\nRaccourci: Alt-1 +FILEBROWSER_SHOWCOLORLABEL2HINT;Afficher les images avec un label Jaune\nRaccourci: Alt-2 +FILEBROWSER_SHOWCOLORLABEL3HINT;Afficher les images avec un label Vert\nRaccourci: Alt-3 +FILEBROWSER_SHOWCOLORLABEL4HINT;Afficher les images avec un label Bleu\nRaccourci: Alt-4 +FILEBROWSER_SHOWCOLORLABEL5HINT;Afficher les images avec un label Pourpre\nRaccourci: Alt-5 +FILEBROWSER_SHOWDIRHINT;Voir toutes les images du dossier\nRaccourci: d +FILEBROWSER_SHOWEDITEDHINT;Afficher les images éditées\nRaccourci: 7 +FILEBROWSER_SHOWEDITEDNOTHINT;Afficher les images non éditées\nRaccourci: 6 +FILEBROWSER_SHOWEXIFINFO;Montrer les infos EXIF.\nRaccourci: i\n\nRaccourcis dans le mode Éditeur Unique: Alt-i +FILEBROWSER_SHOWRANK1HINT;Voir les images 1 étoile\nRaccourci: 1 +FILEBROWSER_SHOWRANK2HINT;Voir les images 2 étoiles\nRaccourci: 2 +FILEBROWSER_SHOWRANK3HINT;Voir les images 3 étoiles\nRaccourci: 3 +FILEBROWSER_SHOWRANK4HINT;Voir les images 4 étoiles\nRaccourci: 4 +FILEBROWSER_SHOWRANK5HINT;Voir les images 5 étoiles\nRaccourci: 5 +FILEBROWSER_SHOWRECENTLYSAVEDHINT;Afficher les images sauvegardées récemment\nRaccourci: Alt-7 +FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT; Afficher les images non sauvegardées récemment\nRaccourci: Alt-6 +FILEBROWSER_SHOWTRASHHINT;Voir le contenu de la corbeille\nRaccourci: Ctrl-t +FILEBROWSER_SHOWUNCOLORHINT;Afficher les images sans label de couleur\nRaccourci: Alt-0 +FILEBROWSER_SHOWUNRANKHINT;Voir les images sans étoile\nRaccourci: 0 +FILEBROWSER_STARTPROCESSINGHINT;Démarre le traitement/sauvegarde des images dans la file +FILEBROWSER_STARTPROCESSING;Démarrer le traitement +FILEBROWSER_STOPPROCESSINGHINT;Arrête le traitement des images +FILEBROWSER_STOPPROCESSING;Arrêter le traitement +FILEBROWSER_THUMBSIZE;Taille vign. +FILEBROWSER_TOOLTIP_STOPPROCESSING;Démarrer automatiquement le traitement à l'arrivée d'une nouvelle tâche +FILEBROWSER_UNRANK_TOOLTIP;Effacer le rang\nRaccourci: Shift-0 +FILEBROWSER_ZOOMINHINT;Augmenter la taille des vignettes.\nRaccourci: +\n\nRaccourcis dans le mode Éditeur Unique: Alt-+ +FILEBROWSER_ZOOMOUTHINT;Diminuer la taille des vignettes.\nRaccourci: -\n\nRaccourcis dans le mode Éditeur Unique: Alt-- +GENERAL_ABOUT;À propos +GENERAL_AFTER;Après +GENERAL_AUTO;Automatique +GENERAL_BEFORE;Avant +GENERAL_CANCEL;Annuler +GENERAL_CLOSE;Fermer +GENERAL_DISABLED;Désactivé +GENERAL_DISABLE;Désactiver +GENERAL_ENABLED;Activé +GENERAL_ENABLE;Activer +GENERAL_FILE;Fichier +GENERAL_LANDSCAPE;Paysage +GENERAL_NA;indisponible +GENERAL_NONE;Aucun +GENERAL_NO;Non +GENERAL_OK;OK +GENERAL_PORTRAIT;Portrait +GENERAL_SAVE;Enregistrer +GENERAL_UNCHANGED;(Inchangé) +GENERAL_WARNING;Attention +HISTOGRAM_TOOLTIP_BAR;Montrer/Cacher l'indicateur RVB du pixel pointé\nCliquer le bouton droit de la souris sur l'image de prévisualisation pour geler/dégeler +HISTOGRAM_TOOLTIP_B;Montrer/cacher l'histogramme BLEU +HISTOGRAM_TOOLTIP_CHRO;Montrer/Cacher l'histogramme de Chromaticité +HISTOGRAM_TOOLTIP_FULL;Basculer la vue de l'histogramme : complet (activé) / zoomé (désactivé) +HISTOGRAM_TOOLTIP_G;Montrer/cacher l'histogramme VERT +HISTOGRAM_TOOLTIP_L;Montrer/cacher l'histogramme Luminance CIELAB +HISTOGRAM_TOOLTIP_RAW;Montrer/Cacher l'histogramme des données RAW +HISTOGRAM_TOOLTIP_R;Montrer/cacher l'histogramme ROUGE +HISTORY_CHANGED;Changé +HISTORY_CUSTOMCURVE;Courbe personnelle +HISTORY_DELSNAPSHOT;Supprimer +HISTORY_FROMCLIPBOARD;Du presse-papier +HISTORY_LABEL;Historique +HISTORY_MSG_1;Photo chargée +HISTORY_MSG_2;Profil chargé +HISTORY_MSG_3;Profil changé +HISTORY_MSG_4;Navigation dans l'historique +HISTORY_MSG_5;Luminosité +HISTORY_MSG_6;Contraste +HISTORY_MSG_7;Noir +HISTORY_MSG_8;Compensation d'exposition +HISTORY_MSG_9;Compression des hautes lumières +HISTORY_MSG_10;Compression des ombres +HISTORY_MSG_11;Courbe tonale 1 +HISTORY_MSG_12;Niveaux Auto +HISTORY_MSG_13;Rognage de l'exposition +HISTORY_MSG_14;Lab - Luminosité +HISTORY_MSG_15;Lab - Contraste +HISTORY_MSG_16;Luminance - Noir +HISTORY_MSG_17;Luminance - Compression Hautes lumières +HISTORY_MSG_18;Luminance - Compression des Ombres +HISTORY_MSG_19;Courbe 'L' +HISTORY_MSG_20;Netteté +HISTORY_MSG_21;Netteté (USM) - Rayon +HISTORY_MSG_22;Netteté (USM) - Quantité +HISTORY_MSG_23;Netteté (USM) - Seuil +HISTORY_MSG_24;Netteté (USM) - Améliorer seulement les bords +HISTORY_MSG_25;Netteté (USM) - Amélio. bords - Rayon +HISTORY_MSG_26;Netteté (USM) - Amélio. bords - Tolérance +HISTORY_MSG_27;Netteté (USM) - Contrôle du halo +HISTORY_MSG_28;Netteté (USM) - Contrôle du halo - Quantité +HISTORY_MSG_29;Méthode d'amélioration de la netteté +HISTORY_MSG_30;Déconvolution - Rayon +HISTORY_MSG_31;Déconvolution - Quantité +HISTORY_MSG_32;Déconvolution - Amortissement +HISTORY_MSG_33;Déconvolution - Itérations +HISTORY_MSG_34;Éviter l'écrêtage couleur +HISTORY_MSG_35;Limiteur de saturation +HISTORY_MSG_36;Limite de saturation +HISTORY_MSG_37;Exposition auto +HISTORY_MSG_38;Méthode de balance des blancs +HISTORY_MSG_39;BdB - Température +HISTORY_MSG_40;BdB - Teinte +HISTORY_MSG_41;Mode courbe tonale 1 +HISTORY_MSG_42;Courbe tonale2 +HISTORY_MSG_43;Mode courbe tonale 2 +HISTORY_MSG_44;Débruitage Lum. - Rayon +HISTORY_MSG_45;Débruitage Lum. - Tolérance des bords +HISTORY_MSG_46;Débruitage Chromatique +HISTORY_MSG_47;Mélange HL du profil ICC et la matrice +HISTORY_MSG_48;Courbe tonale du profil DCP +HISTORY_MSG_49;Illuminant DCP +HISTORY_MSG_50;Ombres/Hautes lumières +HISTORY_MSG_51;O/HL - Hautes lumières +HISTORY_MSG_52;O/HL - Ombres +HISTORY_MSG_53;O/HL - Amplitude tonale des HL +HISTORY_MSG_54;O/HL - Amplitude tonale des ombres +HISTORY_MSG_55;O/HL - Contraste Local +HISTORY_MSG_56;O/HL - Rayon +HISTORY_MSG_57;Rotation grossière +HISTORY_MSG_58;Symétrisation / axe vertical +HISTORY_MSG_59;Symétrisation / axe horizontal +HISTORY_MSG_60;Rotation +HISTORY_MSG_61;Rotation +HISTORY_MSG_62;Correction de la distorsion +HISTORY_MSG_63;Signet sélectionné +HISTORY_MSG_64;Recadrage +HISTORY_MSG_65;Aberration chromatique +HISTORY_MSG_66;Reconst. Hautes Lumières +HISTORY_MSG_67;Reconst. HL - Quantité +HISTORY_MSG_68;Reconst. HL - Méthode +HISTORY_MSG_69;Espace de couleur de travail +HISTORY_MSG_70;Espace de couleur de sortie +HISTORY_MSG_71;Espace de couleur d'entrée +HISTORY_MSG_72;Vignettage - Quantité +HISTORY_MSG_73;Mixage des canaux +HISTORY_MSG_74;Redim. - Échelle +HISTORY_MSG_75;Méthode de redimensionnement +HISTORY_MSG_76;Métadonnées EXIF +HISTORY_MSG_77;Métadonnées IPTC +HISTORY_MSG_78;Type de redimensionnement +HISTORY_MSG_79;Redim. - Largeur +HISTORY_MSG_80;Redim. - Hauteur +HISTORY_MSG_81;Redimensionnement +HISTORY_MSG_82;Changement de profil +HISTORY_MSG_83;O/HL - Masque haute précision +HISTORY_MSG_84;Correction de la perspective +HISTORY_MSG_85;LCP +HISTORY_MSG_86;Courbes RVB - Mode Luminosité +HISTORY_MSG_87;Réduction du bruit d'impulsion +HISTORY_MSG_88;Seuil de réduction de bruit +HISTORY_MSG_89;Réd. de bruit +HISTORY_MSG_90;Réd. de bruit - Luminance +HISTORY_MSG_91;Réd. de bruit - Chrominance Maître +HISTORY_MSG_92;Réd. de bruit - Gamma +HISTORY_MSG_93;Param. Contraste par niv. de détail +HISTORY_MSG_94;Contraste par niveau de détail +HISTORY_MSG_95;Lab - Chromaticité +HISTORY_MSG_96;Courbe 'a' +HISTORY_MSG_97;Courbe 'b' +HISTORY_MSG_98;Algorithme de dématriçage +HISTORY_MSG_99;Filtrage des pixels chauds/morts +HISTORY_MSG_100;Saturation RVB +HISTORY_MSG_101;Ég. TSV - Teinte +HISTORY_MSG_102;Ég. TSV - Saturation +HISTORY_MSG_103;Ég. TSV - Valeur +HISTORY_MSG_104;Égaliseur TSV +HISTORY_MSG_105;Défrangeage +HISTORY_MSG_106;Défrangeage - Rayon +HISTORY_MSG_107;Défrangeage - Seuil +HISTORY_MSG_108;Seuil de compr. des hautes lumières +HISTORY_MSG_109;Redim. - boîte englobante +HISTORY_MSG_110;Redim. s'applique à +HISTORY_MSG_111;Lab - Éviter les dérives de teinte +HISTORY_MSG_112;--inutilisé-- +HISTORY_MSG_113;Lab - Protection +HISTORY_MSG_114;Nbr d'itération DCB +HISTORY_MSG_115;Suppression des fausses couleurs +HISTORY_MSG_116;Amélioration de DCB +HISTORY_MSG_117;A.C. Raw - Rouge +HISTORY_MSG_118;A.C. Raw - Bleu +HISTORY_MSG_119;Filtre de bruit de ligne +HISTORY_MSG_120;Équilibrage du vert +HISTORY_MSG_121;A.C. Raw - Auto +HISTORY_MSG_122;Sélection auto de Trame Noire +HISTORY_MSG_123;Fichier de Trame Noire +HISTORY_MSG_124;Correct. du Point Blanc +HISTORY_MSG_125;Préservation des HL +HISTORY_MSG_126;Champ Uniforme - Fichier +HISTORY_MSG_127;Champ Uniforme - Sélection Auto +HISTORY_MSG_128;Champ Uniforme - Rayon +HISTORY_MSG_129;Champ Uniforme - Type de Floutage +HISTORY_MSG_130;Distorsion Auto +HISTORY_MSG_131;Réd. de bruit - Luminance +HISTORY_MSG_132;Réd. de bruit - Chrominance +HISTORY_MSG_133;Gamma de Sortie +HISTORY_MSG_134;Gamma - Manuel +HISTORY_MSG_135;Gamma - Manuel +HISTORY_MSG_136;Gamma - Pente +HISTORY_MSG_137;Niveau de noir - Vert 1 +HISTORY_MSG_138;Niveau de noir - Rouge +HISTORY_MSG_139;Niveau de noir - Bleu +HISTORY_MSG_140;Niveau de noir - Vert 2 +HISTORY_MSG_141;Niveau de noir - Lier les niveaux des verts +HISTORY_MSG_142;Bords - Itérations +HISTORY_MSG_143;Bords - Quantité +HISTORY_MSG_144;Microcontraste - Quantité +HISTORY_MSG_145;Microcontraste - Uniformité +HISTORY_MSG_146;Netteté des bords +HISTORY_MSG_147;Bords - Luminance uniquement +HISTORY_MSG_148;Microcontraste +HISTORY_MSG_149;Microcontraste - Matrice 3x3 +HISTORY_MSG_150;Réduction du bruit/artefact post-dématriçage +HISTORY_MSG_151;Vibrance +HISTORY_MSG_152;Vib. - Tons pastels +HISTORY_MSG_153;Vib. - Tons saturés +HISTORY_MSG_154;Vib. - Protéger les tons chairs +HISTORY_MSG_155;Vib. - Éviter dérives de teinte +HISTORY_MSG_156;Vib. - Lier Pastels/Saturés +HISTORY_MSG_157;Vib. - Seuil Pastels/Saturés +HISTORY_MSG_158;CT - Force +HISTORY_MSG_159;CT - Arrêt des bords +HISTORY_MSG_160;CT - Échelle +HISTORY_MSG_161;CT - Itérations de la pondération +HISTORY_MSG_162;Compression Tonale +HISTORY_MSG_163;Courbes RVB - Rouge +HISTORY_MSG_164;Courbes RVB - Vert +HISTORY_MSG_165;Courbes RVB - Bleu +HISTORY_MSG_166;Niveaux Neutre +HISTORY_MSG_167;--inutilisé-- +HISTORY_MSG_168;Courbe 'CC' +HISTORY_MSG_169;Courbe 'CT' +HISTORY_MSG_170;Vib. - Courbe +HISTORY_MSG_171;Courbe 'LC' +HISTORY_MSG_172;Lab - Restreindre 'LC' +HISTORY_MSG_173;Réd. Bruit - Détail Luminance +HISTORY_MSG_174;Modèle d'Apparence de la Couleur 2002 +HISTORY_MSG_175;CAM02 - Adaptation CAT02 +HISTORY_MSG_176;CAM02 - Environ. de visionnage +HISTORY_MSG_177;CAM02 - Luminosité de la scène +HISTORY_MSG_178;CAM02 - Luminosité du visionnage +HISTORY_MSG_179;CAM02 - Modèle de Point Blanc +HISTORY_MSG_180;CAM02 - Lumière (J) +HISTORY_MSG_181;CAM02 - Couleur (C) +HISTORY_MSG_182;CAM02 - CAT02 Automatique +HISTORY_MSG_183;CAM02 - Contraste (J) +HISTORY_MSG_184;CAM02 - Entourage de la scène +HISTORY_MSG_185;CAM02 - Controle du gamut +HISTORY_MSG_186;CAM02 - Algorithme +HISTORY_MSG_187;CAM02 - Prot. tons rouges & chair +HISTORY_MSG_188;CAM02 - Brillance (Q) +HISTORY_MSG_189;CAM02 - Contraste (Q) +HISTORY_MSG_190;CAM02 - Saturation (S) +HISTORY_MSG_191;CAM02 - Niveau de couleur (M) +HISTORY_MSG_192;CAM02 - Teinte (h) +HISTORY_MSG_193;CAM02 - Courbe tonale 1 +HISTORY_MSG_194;CAM02 - Courbe tonale 2 +HISTORY_MSG_195;CAM02 - Courbe tonale 1 +HISTORY_MSG_196;CAM02 - Courbe tonale 2 +HISTORY_MSG_197;CAM02 - Courbe couleur +HISTORY_MSG_198;CAM02 - Courbe couleur +HISTORY_MSG_199;CAM02 - Histogrammes de sortie +HISTORY_MSG_200;CAM02 - Compression Tonale +HISTORY_MSG_201;Réd. de bruit - Chrom. R,V +HISTORY_MSG_202;Réd. de bruit - Chrom. B,J +HISTORY_MSG_203;Réd. de bruit - Méthode +HISTORY_MSG_204;Niveau d'amélioration LMMSE +HISTORY_MSG_205;CAM02 Pixels chauds/morts +HISTORY_MSG_206;CAT02 - Luminosité de la scène auto +HISTORY_MSG_207;Défrangeage - Teintes +HISTORY_MSG_208;BdB - Égaliseur B/R +HISTORY_MSG_210;FD - Angle +HISTORY_MSG_211;Filtre Dégradé +HISTORY_MSG_212;FV - Force +HISTORY_MSG_213;Filtre Vignettage +HISTORY_MSG_214;Noir & Blanc +HISTORY_MSG_215;N&B - Mix. - Rouge +HISTORY_MSG_216;N&B - Mix. - Vert +HISTORY_MSG_217;N&B - Mix. - Bleu +HISTORY_MSG_218;N&B - Gamma - Rouge +HISTORY_MSG_219;N&B - Gamma - Vert +HISTORY_MSG_220;N&B - Gamma - Bleu +HISTORY_MSG_221;N&B - Filtre de couleur +HISTORY_MSG_222;N&B - Préréglages +HISTORY_MSG_223;N&B - Mix. - Orange +HISTORY_MSG_224;N&B - Mix. - Jaune +HISTORY_MSG_225;N&B - Mix. - Cyan +HISTORY_MSG_226;N&B - Mix. - Magenta +HISTORY_MSG_227;N&B - Mix. - Pourpre +HISTORY_MSG_228;N&B - Égaliseur de Luminance +HISTORY_MSG_229;N&B - Égaliseur de Luminance +HISTORY_MSG_230;N&B - Mode +HISTORY_MSG_231;N&B - Courbe 'Avant' +HISTORY_MSG_232;N&B - Type de courbe 'Avant' +HISTORY_MSG_233;N&B - Courbe 'Après' +HISTORY_MSG_234;N&B - Type de courbe 'Après' +HISTORY_MSG_235;N&B - Mixeur - Mode Auto +HISTORY_MSG_236;--inutilisé-- +HISTORY_MSG_237;N&B - Mixeur +HISTORY_MSG_238;FD - Étendu +HISTORY_MSG_239;FD - Force +HISTORY_MSG_240;FD - Centre +HISTORY_MSG_241;FV - Adoucissement +HISTORY_MSG_242;FV - Circularité +HISTORY_MSG_243;Vignet. - Rayon +HISTORY_MSG_244;Vignet. - Force +HISTORY_MSG_245;Vignet. - Centre +HISTORY_MSG_246;Courbe 'CL' +HISTORY_MSG_247;Courbe 'LT' +HISTORY_MSG_248;Courbe 'TT' +HISTORY_MSG_249;Seuil Contraste par niv. de détail +HISTORY_MSG_250;Réd. de bruit - Amélioré +HISTORY_MSG_251;N&B - Algorithme +HISTORY_MSG_252;CpND - Tons chair +HISTORY_MSG_253;CpND - Réduction des artéfactes +HISTORY_MSG_254;CpND - Teinte chair +HISTORY_MSG_255;Réd. de bruit - Filtre Médian +HISTORY_MSG_256;Réd. de bruit - Type de Médiane +HISTORY_MSG_257;Virage Partiel +HISTORY_MSG_258;Virage Partiel - Couleur +HISTORY_MSG_259;Virage Partiel - Opacité +HISTORY_MSG_260;Virage Partiel - Opacité 'a[b]' +HISTORY_MSG_261;Virage Partiel - Méthode +HISTORY_MSG_262;Virage Partiel - Opacité 'b' +HISTORY_MSG_263;Virage Partiel - Ombres - Rouge +HISTORY_MSG_264;Virage Partiel - Ombres - Vert +HISTORY_MSG_265;Virage Partiel - Ombres - Bleu +HISTORY_MSG_266;Virage Partiel - Moyen - Rouge +HISTORY_MSG_267;Virage Partiel - Moyen - Vert +HISTORY_MSG_268;Virage Partiel - Moyen - Bleu +HISTORY_MSG_269;Virage Partiel - HL - Rouge +HISTORY_MSG_270;Virage Partiel - HL - Vert +HISTORY_MSG_271;Virage Partiel - HL - Bleu +HISTORY_MSG_272;Virage Partiel - Balance +HISTORY_MSG_273;Virage Partiel - Réinit. +HISTORY_MSG_274;Virage Partiel - Saturation Shadows +HISTORY_MSG_275;Virage Partiel - Saturation Highlights +HISTORY_MSG_276;Virage Partiel - Opacité +HISTORY_MSG_277;--inutilisé-- +HISTORY_MSG_278;Virage Partiel - Préserver Luminance +HISTORY_MSG_279;Virage partiel - Ombres +HISTORY_MSG_280;Virage partiel - Hautes Lumières +HISTORY_MSG_281;Virage partiel - Protect. Saturé +HISTORY_MSG_282;Virage partiel - Seuil de Protection +HISTORY_MSG_283;Virage partiel - Force +HISTORY_MSG_284;Virage partiel - Protect. Saturé Auto +HISTORY_MSG_285;Réd. de bruit - Médiane - Méthode +HISTORY_MSG_286;Réd. de bruit - Médiane - Type +HISTORY_MSG_287;Réd. de bruit - Médiane - Itérations +HISTORY_MSG_288;Champ Uniforme - Ctrl de l'Écrêtage +HISTORY_MSG_289;Champ Uniforme - Ctrl Auto de l'Écrêtage +HISTORY_MSG_290;Niveau de noir - Rouge +HISTORY_MSG_291;Niveau de noir - Vert +HISTORY_MSG_292;Niveau de noir - Bleu +HISTORY_MSG_293;Simulation de Film +HISTORY_MSG_294;Simulation de Film - Force +HISTORY_MSG_295;Simulation de Film - Film +HISTORY_NEWSNAPSHOT;Ajouter +HISTORY_NEWSNAPSHOT_TOOLTIP;Raccourci: Alt-s +HISTORY_SNAPSHOTS;Captures +HISTORY_SNAPSHOT;Capture +IPTCPANEL_AUTHORSPOSITIONHINT;Statut du ou des créateurs de l'objet (By-line Title). +IPTCPANEL_AUTHORSPOSITION;Statut de l'auteur +IPTCPANEL_AUTHOR;Auteur +IPTCPANEL_CAPTIONHINT;Une description explicite de la donnée (Légende - Résumé) +IPTCPANEL_CAPTIONWRITERHINT;Le nom de la personne ayant rédigé, édité ou corrigé l'image ou la légende/résumé (Auteur - Editeur). +IPTCPANEL_CAPTIONWRITER;Auteur de la légende +IPTCPANEL_CAPTION;Légende +IPTCPANEL_CATEGORYHINT;Identifie le sujet de l'image selon l'avis du fournisseur (Catégorie). +IPTCPANEL_CATEGORY;Catégorie +IPTCPANEL_CITYHINT;Ville d'origine de l'image (Ville). +IPTCPANEL_CITY;Ville +IPTCPANEL_COPYHINT;Copie les réglages IPTC dans le presse-papier +IPTCPANEL_COPYRIGHTHINT;Toute remarque nécessaire de droit de copie (Remarque droit de copie). +IPTCPANEL_COPYRIGHT;Droit de copie +IPTCPANEL_COUNTRYHINT;Le nom du pays de la ville principale où l'image a été créée (Pays - Nom de la ville principale). +IPTCPANEL_COUNTRY;Pays +IPTCPANEL_CREDITHINT;Identifie le fournisseur de l'image, pas nécessairement le propriétaire/créateur (Crédit). +IPTCPANEL_CREDIT;Crédit +IPTCPANEL_DATECREATEDHINT;La date de création du contenu intellectuel de l'image; Format: AAAAMMJJ (Date de création). +IPTCPANEL_DATECREATED;Date de création +IPTCPANEL_EMBEDDEDHINT;Réinitialise selon les données IPTC incorporées dans le fichier image +IPTCPANEL_EMBEDDED;Incorporés +IPTCPANEL_HEADLINEHINT;Une entrée publiable fournissant un synopsis du contenu de l'image (Titre). +IPTCPANEL_HEADLINE;Titre +IPTCPANEL_INSTRUCTIONSHINT;Autres instructions éditoriales concernant l'utilisation de l'image (Instructions spéciales). +IPTCPANEL_INSTRUCTIONS;Instructions +IPTCPANEL_KEYWORDSHINT;Utilisé pour spécifier des mots clés de recherches (Mots clés). +IPTCPANEL_KEYWORDS;Mots clés +IPTCPANEL_PASTEHINT;Colle les réglages IPTC du presse-papier +IPTCPANEL_PROVINCEHINT;La province/état d'où est issue l'image (Province-Etat). +IPTCPANEL_PROVINCE;Province +IPTCPANEL_RESETHINT;Réinitialise selon le profil par défaut +IPTCPANEL_RESET;Réinitialisation +IPTCPANEL_SOURCEHINT;Le propriétaire intellectuel du contenu de l'image (Source). +IPTCPANEL_SOURCE;Source +IPTCPANEL_SUPPCATEGORIESHINT;Précise un peu plus le sujet de l'image (Catégories supplémentaires). +IPTCPANEL_SUPPCATEGORIES;Catégories suppl. +IPTCPANEL_TITLEHINT;Raccourcis de référence de l'image (Nom de l'objet). +IPTCPANEL_TITLE;Titre +IPTCPANEL_TRANSREFERENCEHINT;Un code représentant le lieux de la transmission initiale (Référence de transmission initiale). +IPTCPANEL_TRANSREFERENCE;Réf. transmission +MAIN_BUTTON_FULLSCREEN;Plein écran +MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigue à l'image Suivante relativement à l'image ouverte dans l'Éditeur\nRaccourci: Shift-F4\n\nPour naviguer à l'image Suivante relativement à la vignette sélectionnée dans le Navigateur de fichiers\nRaccourci: F4 +MAIN_BUTTON_NAVPREV_TOOLTIP;Navigue à l'image Précédente relativement à l'image ouverte dans l'Éditeur\nRaccourci: Shift-F3\n\nPour naviguer à l'image Précédente relativement à la vignette sélectionnée dans le Navigateur de fichiers\nRaccourci: F3 +MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchronise le Navigateur de fichiers avec l'Éditeur pour révéler la vignette de l'image actuellement ouverte, et efface les filtres dans le Navigateur de fichiers\nRaccourci: x\n\nComme ci-dessus, mais sans effacer les filtres dans le Navigateur de fichiers\nRaccourci: y\n(Notez que la vignette ne sera pas visible si elle a été filtrée). +MAIN_BUTTON_PREFERENCES;Préférences +MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Ajouter l'image courante à la file de traitement\nRaccourci: Ctrl+b +MAIN_BUTTON_SAVE_TOOLTIP;Enregistrer l'image courante\nRaccourci: Ctrl+s +MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Éditer l'image courante dans l'éditeur externe\nRaccourci: Ctrl+e +MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Afficher/Cacher les 2 panneaux latéraux\nRaccourci: m +MAIN_BUTTON_UNFULLSCREEN;Quitter le plein écran +MAIN_FRAME_BATCHQUEUE;File d'attente +MAIN_FRAME_BATCHQUEUE_TOOLTIP; File de traitement\nRaccourci: Ctrl-F3 +MAIN_FRAME_EDITOR;Éditeur +MAIN_FRAME_EDITOR_TOOLTIP; Éditeur\nRaccourci: Ctrl-F4 +MAIN_FRAME_FILEBROWSER;Navigateur de fichiers +MAIN_FRAME_FILEBROWSER_TOOLTIP; Navigateur de fichiers\nRaccourci: Ctrl-F2 +MAIN_FRAME_PLACES;Emplacements +MAIN_FRAME_PLACES_ADD;Ajouter +MAIN_FRAME_PLACES_DEL;Supprimer +MAIN_FRAME_RECENT;Fichiers récents +MAIN_MSG_ALREADYEXISTS;Le fichier existe déjà. +MAIN_MSG_CANNOTLOAD;Impossible de charger l'image +MAIN_MSG_CANNOTSAVE;Erreur d'enregistrement du fichier +MAIN_MSG_CANNOTSTARTEDITOR;Impossible de lancer l'éditeur. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Veuillez saisir son chemin d'accès dans les "Préférences". +MAIN_MSG_EMPTYFILENAME;Nom de fichier non spécifié! +MAIN_MSG_IMAGEUNPROCESSED;Cette commande nécessite que toutes les images sélectionnées aient été préalablement traité. +MAIN_MSG_NAVIGATOR;Navigateur +MAIN_MSG_OPERATIONCANCELLED;Opération annulée +MAIN_MSG_PATHDOESNTEXIST;Le chemin \n\n%1\n\nn'existe pas. S.V.P indiquez un chemin correct dans la fenêtre Préférences. +MAIN_MSG_QOVERWRITE;Voulez-vous l'écraser? +MAIN_MSG_SETPATHFIRST;Vous devez d'abord choisir un dossier cible dans Préférences\npour pouvoir utiliser cette fonction! +MAIN_MSG_WRITEFAILED;Échec de l'enregistrement du fichier\n\n"%1"\n\nAssurez-vous que le dossier existe et qu'il est permis d'y écrire. +MAIN_TAB_COLOR;Couleur +MAIN_TAB_COLOR_TOOLTIP;Raccourci:Alt-c +MAIN_TAB_DETAIL;Détail +MAIN_TAB_DETAIL_TOOLTIP;Raccourci:Alt-d +MAIN_TAB_DEVELOP; Développer +MAIN_TAB_EXIF;EXIF +MAIN_TAB_EXPORT;Export Rapide +MAIN_TAB_EXPOSURE;Exposition +MAIN_TAB_EXPOSURE_TOOLTIP;Raccourci:Alt-e +MAIN_TAB_FILTER; Filtrer +MAIN_TAB_INSPECT; Inspecter +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Métadonnées +MAIN_TAB_METADATA_TOOLTIP;Raccourci:Alt-m +MAIN_TAB_RAW;RAW +MAIN_TAB_RAW_TOOLTIP;Raccourci:Alt-r +MAIN_TAB_TRANSFORM;Transformation +MAIN_TAB_TRANSFORM_TOOLTIP;Raccourci:Alt-t +MAIN_TOOLTIP_BACKCOLOR0;Couleur de fond de l'aperçu: Selon le thème\nRaccourci : 9 +MAIN_TOOLTIP_BACKCOLOR1;Couleur de fond de l'aperçu: Noir\nRaccourci : 9 +MAIN_TOOLTIP_BACKCOLOR2;Couleur de fond de l'aperçu: Blanc\nRaccourci: 9 +MAIN_TOOLTIP_BEFOREAFTERLOCK;Vérouille / déverouille la vue Avant\n\nVérouille: garde la vue Avant inchangée - \nutile pour évaluer l'effet cumulatif de plusieurs outils.\nDe plus, une comparaison peut être faite à partir de n'importe quelle étape de l'historique\n\nDéverouille: la vue Avant représentera l'étape précédant la vue Après, montrant l'effet qui vient d'être modifié +MAIN_TOOLTIP_HIDEHP;Montrer/cacher le panneau gauche (incluant l'historique)\nRaccourci: l +MAIN_TOOLTIP_INDCLIPPEDH;Indication hautes lumières hors domaine\nRaccourci: < +MAIN_TOOLTIP_INDCLIPPEDS;Indication ombres hors domaine\nRaccourci: > +MAIN_TOOLTIP_PREVIEWB;Affichage du canal Bleu\nRaccourci: b +MAIN_TOOLTIP_PREVIEWFOCUSMASK;Affichage du Masque du focus\nRaccourci: Shift-f\n\nPlus précis sur les images avec une faible profondeur de champ, à faible bruit et à des niveaux de zoom élevé\n\nPour améliorer la précision de détection des images bruitées, évaluez les à un facteur de zoom de 10-30%\n\nLa prévisualisation met plus de temps à se calculer lorsque cet outil est actif. +MAIN_TOOLTIP_PREVIEWG;Affichage du canal Vert\nRaccourci: g +MAIN_TOOLTIP_PREVIEWL;Affichage de la Luminosité\nRaccourci: v\n\n0.299*R + 0.587*V + 0.114*B +MAIN_TOOLTIP_PREVIEWR;Affichage du canal Rouge\nRaccourci: r +MAIN_TOOLTIP_QINFO;Informations rapide sur l'image\nRaccourci: i +MAIN_TOOLTIP_SHOWHIDELP1;Montrer/Cacher le panneau gauche\nRaccourci: l +MAIN_TOOLTIP_SHOWHIDERP1;Afficher/Cacher le panneau droit\nRaccourci: Alt-l +MAIN_TOOLTIP_SHOWHIDETP1;Afficher/Cacher le panneau supérieur\nRaccourci: Shift-L +MAIN_TOOLTIP_THRESHOLD;Seuil +MAIN_TOOLTIP_TOGGLE;Comparaison avant/après\nRaccourci: Shift-b +NAVIGATOR_XY_FULL;Largeur = %1, Hauteur = %2 +NAVIGATOR_XY_NA;x = n/d, y = n/d +OPTIONS_DEFIMG_MISSING;Le profil par défaut pour les images standards n'a pas été trouvé ou n'a pas été réglé.\n\nVérifiez également le dossier de vos profils, il peut être manquant ou endommagé\n\nLes valeurs internes pas défaut seront utilisées. +OPTIONS_DEFRAW_MISSING;Le profil par défaut pour les images Raw n'a pas été trouvé ou n'a pas été réglé.\n\nVérifiez également le dossier de vos profils, il peut être manquant ou endommagé\n\nLes valeurs internes pas défaut seront utilisées. +PARTIALPASTE_BASICGROUP;Réglages de base +PARTIALPASTE_CACORRECTION;Aberration chromatique +PARTIALPASTE_CHANNELMIXERBW;Noir et Blanc +PARTIALPASTE_CHANNELMIXER;Mixage des canaux +PARTIALPASTE_COARSETRANS;Rotation de 90° / symétrisation +PARTIALPASTE_COLORAPP;CIE Modèle apparence de la couleur 2002 +PARTIALPASTE_COLORGROUP;Réglages couleurs +PARTIALPASTE_COLORTONING;Virage Partiel +PARTIALPASTE_COMMONTRANSFORMPARAMS;Remplir +PARTIALPASTE_COMPOSITIONGROUP;Réglages de la composition +PARTIALPASTE_CROP;Recadrage +PARTIALPASTE_DARKFRAMEAUTOSELECT;Sélection auto de la Trame Noire +PARTIALPASTE_DARKFRAMEFILE;Fichier de Trame Noire +PARTIALPASTE_DEFRINGE;Aberration chromatique +PARTIALPASTE_DETAILGROUP;Détail +PARTIALPASTE_DIALOGLABEL;Collage partiel de profil de traitement +PARTIALPASTE_DIRPYRDENOISE;Réduction du bruit +PARTIALPASTE_DIRPYREQUALIZER;Contraste par niveaux de détail +PARTIALPASTE_DISTORTION;Correction de distorsion +PARTIALPASTE_EPD;Compression tonale +PARTIALPASTE_EVERYTHING;Tout +PARTIALPASTE_EXIFCHANGES;Modification des données EXIF +PARTIALPASTE_EXPOSURE;Exposition +PARTIALPASTE_FLATFIELDAUTOSELECT;Sélection auto du Champ Uniforme +PARTIALPASTE_FLATFIELDBLURRADIUS;Rayon de floutage du Champ Uniforme +PARTIALPASTE_FLATFIELDBLURTYPE;Type de floutage du Champ Uniforme +PARTIALPASTE_FLATFIELDCLIPCONTROL;Contrôle de l'écrêtage du Champs Uniforme +PARTIALPASTE_FLATFIELDFILE;Fichier de Champ Uniforme +PARTIALPASTE_GRADIENT;Filtre Dégradé +PARTIALPASTE_HSVEQUALIZER;Égaliseur TSV +PARTIALPASTE_ICMGAMMA;Gamma de sortie +PARTIALPASTE_ICMSETTINGS;Réglages ICM +PARTIALPASTE_IMPULSEDENOISE;Réduction du bruit d'impulsion +PARTIALPASTE_IPTCINFO;Infos IPTC +PARTIALPASTE_LABCURVE;Courbes Lab +PARTIALPASTE_LENSGROUP;Réglages de l'objectif +PARTIALPASTE_LENSPROFILE;Profil de correction d'Objectif +PARTIALPASTE_METAGROUP;Réglages des Métadonnées +PARTIALPASTE_PCVIGNETTE;Filtre Vignettage +PARTIALPASTE_PERSPECTIVE;Perspective +PARTIALPASTE_PREPROCESS_DEADPIXFILT;Filtrage des pixels morts +PARTIALPASTE_PREPROCESS_GREENEQUIL;Équilibrage du vert +PARTIALPASTE_PREPROCESS_HOTPIXFILT;Filtrage des pixels chauds +PARTIALPASTE_PREPROCESS_LINEDENOISE;Filtre de bruit de ligne +PARTIALPASTE_RAWCACORR_AUTO;Corr. auto. de l'aberr. chromatique +PARTIALPASTE_RAWCACORR_CABLUE;Aberr. chromatique bleu +PARTIALPASTE_RAWCACORR_CARED;Aberr. chromatique rouge +PARTIALPASTE_RAWEXPOS_BLACK;Niveaux de noir +PARTIALPASTE_RAWEXPOS_LINEAR;Correction du point blanc +PARTIALPASTE_RAWEXPOS_PRESER;Préservation des Hautes Lumières +PARTIALPASTE_RAWGROUP;Réglages RAW +PARTIALPASTE_RAW_DCBENHANCE;Amélioration de DCB +PARTIALPASTE_RAW_DCBITERATIONS;Nombre d'itération de DCB +PARTIALPASTE_RAW_DMETHOD;Algorithme de dématriçage +PARTIALPASTE_RAW_FALSECOLOR;Nbr d'itération des fausses couleurs +PARTIALPASTE_RAW_LMMSEITERATIONS;Niveau d'amélioration LMMSE +PARTIALPASTE_RESIZE;Redimentionnement +PARTIALPASTE_RGBCURVES;Courbes RVB +PARTIALPASTE_ROTATION;Rotation +PARTIALPASTE_SHADOWSHIGHLIGHTS;Ombres/Hautes lumières +PARTIALPASTE_SHARPENEDGE;Bords +PARTIALPASTE_SHARPENING;Netteté +PARTIALPASTE_SHARPENMICRO;Microcontraste +PARTIALPASTE_VIBRANCE;Vibrance +PARTIALPASTE_VIGNETTING;Correction du vignettage +PARTIALPASTE_WHITEBALANCE;Balance des blancs +PREFERENCES_ADD;Ajoute +PREFERENCES_APPLNEXTSTARTUP;appliqué au prochain lancement +PREFERENCES_AUTOMONPROFILE;Utiliser automatiquement le profil de l'écran principal +PREFERENCES_BATCH_PROCESSING;Traitement par lot +PREFERENCES_BEHADDALLHINT;Règle tous les paramètres sur le mode Ajoute.\nLa modification des paramètres dans le panneau d'édition en par lot sera des deltas par-rapport aux valeurs existantes +PREFERENCES_BEHADDALL;Tout à 'Ajoute' +PREFERENCES_BEHAVIOR;Comportement +PREFERENCES_BEHSETALLHINT;Règle tous les paramètres sur le mode Remplace.\nLa modification des paramètres dans le panneau d'édition en par lot sera absolue, les valeurs réelles seront affichées +PREFERENCES_BEHSETALL;Tout à 'Remplace' +PREFERENCES_BLACKBODY;Tungstène +PREFERENCES_CACHECLEARALL;Tout nettoyer +PREFERENCES_CACHECLEARPROFILES;Nettoyer les profils +PREFERENCES_CACHECLEARTHUMBS;Nettoyer les vignettes +PREFERENCES_CACHEMAXENTRIES;Nombre maximal d'éléments dans le Cache +PREFERENCES_CACHEOPTS;Options du Cache +PREFERENCES_CACHETHUMBHEIGHT;Hauteur maximale des vignettes +PREFERENCES_CIEART;CIECAM02 optimisation +PREFERENCES_CIEART_LABEL;Utilise la précision float au lieu de double pour CIECAM02 +PREFERENCES_CIEART_TOOLTIP;Si activé, les calculs CIECAM sont réalisés en précision float au lieu de précision double. Cela amène un léger accroissement de vitesse, et une légère réduction de qualité +PREFERENCES_CLIPPINGIND;Indication du dépassement de plage dynamique +PREFERENCES_CLUTSDIR;Dossier HaldCLUT +PREFERENCES_CMETRICINTENT;Intention Colorimétrique +PREFERENCES_CUSTPROFBUILDHINT;Fichier éxecutable (ou script) appelé lorsqu'un nouveau profil initial doit être généré pour une image.\n\nLe chemin du fichier de communication (style *.ini, aussi appelé "KeyFile") est ajouté en paramètre de la ligne de commande. Il contient divers paramètres nécessaire au script et les métadonnées Exif de l'image pour permettre la génération d'un .pp3 basé sur des règles.\n\nATTENTION: Il vous appartient d'utiliser ou non des guillemets double pour spécifier des chemins si ceux-ci contiennent des espaces. +PREFERENCES_CUSTPROFBUILDKEYFORMAT;Format des clés +PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME;Nom +PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;TagID +PREFERENCES_CUSTPROFBUILDPATH;Chemin de l'exécutable +PREFERENCES_CUSTPROFBUILD;Constructeur de profil d'image personnalisé +PREFERENCES_CUTOVERLAYBRUSH;Masque de recadrage +PREFERENCES_D50;5000K +PREFERENCES_D55;5500K +PREFERENCES_D60;6000K +PREFERENCES_D65;6500K +PREFERENCES_DARKFRAMEFOUND;Trouvé +PREFERENCES_DARKFRAMESHOTS;image(s) +PREFERENCES_DARKFRAMETEMPLATES;modèle(s) +PREFERENCES_DARKFRAME;Soustraction de Trame Noire +PREFERENCES_DATEFORMATHINT;Vous pouvez utiliser les paramètres de chaînes formatées suivants:\n%y : année\n%m : mois\n%d : jour\n\nPar exemple, le format de date française est:\n%d/%m/%y +PREFERENCES_DATEFORMAT;Format +PREFERENCES_DEFAULTLANG;Langue par défaut +PREFERENCES_DEFAULTTHEME;Thème par défaut +PREFERENCES_DIRDARKFRAMES;Dossier des images de Trame Noire +PREFERENCES_DIRHOME;Racine de mes documents personnels +PREFERENCES_DIRLAST;Dernier dossier visité +PREFERENCES_DIROTHER;Autre +PREFERENCES_DIRSELECTDLG;Choix du dossier Image au lancement... +PREFERENCES_DIRSOFTWARE;Dossier d'installation +PREFERENCES_EDITORCMDLINE;Autre ligne de commande +PREFERENCES_EDITORLAYOUT;Disposition de l'éditeur +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 (à désactiver pour les écrans de faible résolution) +PREFERENCES_FILEFORMAT;Format du fichier +PREFERENCES_FILMSIMULATION;Simulation de Film +PREFERENCES_FLATFIELDFOUND;Trouvé +PREFERENCES_FLATFIELDSDIR;Dossier des images de Champ Uniforme +PREFERENCES_FLATFIELDSHOTS;image(s) +PREFERENCES_FLATFIELDTEMPLATES;modèle(s) +PREFERENCES_FLATFIELD;Champ Uniforme +PREFERENCES_FLUOF2;Fluorescent F2 +PREFERENCES_FLUOF7;Fluorescent F7 +PREFERENCES_FLUOF11;Fluorescent F11 +PREFERENCES_FORIMAGE;Pour les fichiers images +PREFERENCES_FORRAW;Pour les fichiers RAW +PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT;Taille de vignette identique entre l'Éditeur et le Navigateur de Fichier +PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT_HINT;Avoir une hauteur différente demandera plus de temp de traitement à chaque fois que vous baculerez entre l'Éditeur unique et le Navigateur de Fichier. +PREFERENCES_GIMPPATH;Dossier d'intallation de GIMP +PREFERENCES_GREY05;Yb=05 CIE L#30 +PREFERENCES_GREY10;Yb=10 CIE L#40 +PREFERENCES_GREY15;Yb=15 CIE L#45 +PREFERENCES_GREY18;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_GREY;Luminance Yb du périphérique de sortie (%) +PREFERENCES_HISTOGRAMPOSITIONLEFT;Histogramme dans le panneau de gauche +PREFERENCES_HLTHRESHOLD;Seuil pour le dépassement de domaine supérieur +PREFERENCES_ICCDIR;Dossier des profils ICC +PREFERENCES_IMPROCPARAMS;Paramètres de traitement d'image par défaut +PREFERENCES_INSPECT_LABEL;Inspecter +PREFERENCES_INSPECT_MAXBUFFERS_LABEL;Nombre maxi de mémoire tampon +PREFERENCES_INSPECT_MAXBUFFERS_TOOLTIP;Règle le nombre maximum d'images mis en cache lors de leur survol dans le Navigateur de Fichier ; les systèmes avec peu de mémoire RAM (2 Go) devraient garder cette valeur à 1 ou 2. +PREFERENCES_INTENT_ABSOLUTE;Colorimétrie absolue +PREFERENCES_INTENT_PERCEPTUAL;Perceptuel +PREFERENCES_INTENT_RELATIVE;Colorimétrie relative +PREFERENCES_INTENT_SATURATION;Saturation +PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Afficher vignette incluse dans fichier RAW si non édité +PREFERENCES_LANGAUTODETECT;Utiliser les paramètres linguistiques de l'OS +PREFERENCES_MENUGROUPEXTPROGS;Groupe "Ouvrir avec" +PREFERENCES_MENUGROUPFILEOPERATIONS;Opérations sur les fichiers +PREFERENCES_MENUGROUPLABEL;Label +PREFERENCES_MENUGROUPPROFILEOPERATIONS;Opérations sur les profils +PREFERENCES_MENUGROUPRANK;Classement +PREFERENCES_MENUOPTIONS;Options du menu +PREFERENCES_METADATA;Metadonnées +PREFERENCES_MONITORICC;Profil du moniteur +PREFERENCES_MULTITABDUALMON;Éditeurs multiple, si possible sur un second moniteur +PREFERENCES_MULTITAB;Éditeurs multiple +PREFERENCES_OUTDIRFOLDERHINT;Place les images traitées dans le dossier selectionné +PREFERENCES_OUTDIRFOLDER;Dossier de sauvegarde +PREFERENCES_OUTDIRTEMPLATEHINT;Vous pouvez utiliser les paramètres de chaîne formatées suivants:\n%f, %d1, %d2, ..., %p1, %p2, ..., %r, %s1, %s2, ...\n\nCes chaînes de formattage se réfèrent aux différentes parties du chemin de la photo, certains de ses attributs ou un numéro de séquence arbitraire dans le traitement par lot.\n\nPar exemple, si la photo en cours de traitement a le chemin suivant:\n/home/tom/image/02-09-2006/dsc0012.nef\nla signification des chaînes de formattage est:\n%d4 = home\n%d3 = tom\n%d2 = photos\n%d1 = 2010-10-31\n%f = dsc0042\n%p1 = /home/tom/photos/2010-10-31/\n%p2 = /home/tom/photos/\n%p3 = /home/tom/\n%p4 = /home/\n\n%r sera remplacé par le rang de la photo. Si la photo n'a pas de rang, %r sera remplacé par '0'. Si la photo est dans la corbeille de RawTherapee, %r sera remplacé par 'x'.\n\n%s1, %s2, etc. sera remplacé par un index de séquence constitué de 1 à 9 chiffre. L'index de la séquence commencera à 1 à chaque fois que le file de traitement est démarrée, et est incrémenté de 1 pour chaque image traitée.\n\nSi vous voulez enregistrer l'image de sortie là où se trouve l'originale, écrivez:\n%p1/%f\n\nSi vous voulez enregistrer l'image de sortie dans un dossier nommé "convertis" situé dans le dossier de l'originale, écrivez:\n%p1/convertis/%f\n\nSi vous voulez enregistrer l'image de sortie dans un dossier nommé "/home/tom/photos/convertis/2010-10-31", écrivez:\n%p2/convertis/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Utiliser le modèle +PREFERENCES_OUTDIR;Dossier de sortie +PREFERENCES_OVERLAY_FILENAMES;Superposer les noms de fichier sur les vignettes dans le navigateur de fichier +PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Superposer les noms de fichier sur les vignettes dans le panneau d'édition +PREFERENCES_OVERWRITEOUTPUTFILE;Écraser le fichier s'il existe déjà +PREFERENCES_PANFACTORLABEL;Facteur +PREFERENCES_PARSEDEXTADDHINT;Tapez une extension et cliquez ce bouton pour l'ajouter à la liste +PREFERENCES_PARSEDEXTADD;Ajout de l'extension +PREFERENCES_PARSEDEXTDELHINT;Supprime de la liste les extensions sélectionnées +PREFERENCES_PARSEDEXT;Extensions considérées +PREFERENCES_PROFILEHANDLING;Gestionnaire des profils de traitement +PREFERENCES_PROFILELOADPR;Priorité de chargement des profils +PREFERENCES_PROFILEPRCACHE;Profil dans le Cache +PREFERENCES_PROFILEPRFILE;Profil accolé au fichier d'entrée +PREFERENCES_PROFILESAVECACHE;Enregistrer la paramètres de traitement dans le Cache +PREFERENCES_PROFILESAVEINPUT;Enregistrer la paramètres de traitement accolé au fichier d'entrée +PREFERENCES_PROPERTY;Propriété +PREFERENCES_PSPATH;Dossier d'installation d'Adobe Photoshop +PREFERENCES_RGBDTL_LABEL;Nombre maximum d'unités de calcul pour la Réduction du bruit +PREFERENCES_RGBDTL_TOOLTIP;La réduction du bruit nécessite un minimum d'à peu près 128Mo de RAM pour une image de 10MPix ou 512Mo pour une image de 40MPix, ainsi que 128Mo de RAM supplémentaire par unité de calcul. Plus il y aura d'unités de calcul travaillant en parallèle, plus ce sera rapide. Laissez la valeur à "0" pour utiliser automatiquement autant d'unités de calcul que possible. +PREFERENCES_SELECTFONT;Police de caractère +PREFERENCES_SELECTLANG;Choix de la langue +PREFERENCES_SELECTTHEME;Choisissez un thème +PREFERENCES_SET;Remplace +PREFERENCES_SHOWBASICEXIF;Voir les infos EXIF basiques +PREFERENCES_SHOWDATETIME;Voir la date et l'heure +PREFERENCES_SHOWEXPOSURECOMPENSATION;Ajoute la compensation d'exposition +PREFERENCES_SHTHRESHOLD;Seuil pour le dépassement de domaine inférieur +PREFERENCES_SINGLETABVERTAB;Éditeur unique, onglets verticaux +PREFERENCES_SINGLETAB;Éditeur unique +PREFERENCES_SLIMUI;Interface compacte +PREFERENCES_SND_BATCHQUEUEDONE;File de traitement terminée +PREFERENCES_SND_HELP;Saisissez un chemin de fichier ou rien du tout (pour ne pas avoir de son). Pour Windows,\nsaisissez "SystemDefault", "SystemAsterisk" etc. pour utiliser les sons systèmes. +PREFERENCES_SND_LNGEDITPROCDONE;Traitement de la zone de prévisualisation terminé +PREFERENCES_SND_TRESHOLDSECS;après (s) +PREFERENCES_STARTUPIMDIR;Répertoire Image au démarrage +PREFERENCES_TAB_BROWSER;Navigateur de fichiers +PREFERENCES_TAB_COLORMGR;Gestion des couleurs +PREFERENCES_TAB_GENERAL;Général +PREFERENCES_TAB_IMPROC;Traitement de l'image +PREFERENCES_TAB_PERFORMANCE;Performance +PREFERENCES_TAB_SOUND;Sons +PREFERENCES_TP_LABEL;Panneau des outils: +PREFERENCES_TP_USEICONORTEXT;Utiliser des icônes au lieu de textes +PREFERENCES_TP_VSCROLLBAR;Cacher la barre de défilement verticale +PREFERENCES_TUNNELMETADATA;Copier les données IPTC/XMP sans les\nchanger dans fichier de sortie +PREFERENCES_USEBUNDLEDPROFILES;Utiliser les profils fournis +PREFERENCES_USESYSTEMTHEME;Utiliser le thème système +PREFERENCES_VIEW;Point blanc du périphérique sortie (moniteur, TV, projecteur,...) +PREFERENCES_WORKFLOW;Habitudes de travail +PROFILEPANEL_COPYPPASTE;Paramètres à copier +PROFILEPANEL_GLOBALPROFILES;Profils fournis +PROFILEPANEL_LABEL;Profils de post-traitement +PROFILEPANEL_LOADDLGLABEL;Charger les paramètres de post-traitement... +PROFILEPANEL_LOADPPASTE;Paramètres à charger +PROFILEPANEL_MODE_TIP;Mode de complètement des profils de traitement.\n\nBouton pressé: les profils partiels seront convertis en profils complets; les valeurs manquantes seront remplacées par les valeurs internes par défaut\n\nBouton relevé: les profils seront appliqués tel quel, altérant seulement les paramètres qu'ils contiennent. +PROFILEPANEL_MYPROFILES;Mes profils +PROFILEPANEL_PASTEPPASTE;Paramètres à coller +PROFILEPANEL_PCUSTOM;Personnel +PROFILEPANEL_PFILE;Depuis le fichier +PROFILEPANEL_PINTERNAL;Neutre +PROFILEPANEL_PLASTSAVED;Dernière sauvegarde +PROFILEPANEL_SAVEDLGLABEL;Enregistrer les paramètres de post-traitement... +PROFILEPANEL_SAVEPPASTE;Paramètres à enregistrer +PROFILEPANEL_TOOLTIPCOPY;Copie le profil courant dans le presse-papier\nCTRL-clic pour sélectionner les paramètres à copier +PROFILEPANEL_TOOLTIPLOAD;Charger un profil depuis un fichier\nCTRL-clic pour sélectionner les paramètres à charger +PROFILEPANEL_TOOLTIPPASTE;Colle le profil depuis le presse-papier\nCTRL-clic pour sélectionner les paramètres à coller +PROFILEPANEL_TOOLTIPSAVE;Enregistrer le profil actuel\nCTRL-clic pour sélectionner les paramètres à enregistrer +PROGRESSBAR_LOADINGTHUMBS;Chargement des vignettes... +PROGRESSBAR_LOADING;Chargement de l'Image... +PROGRESSBAR_LOADJPEG;Chargement du fichier JPEG... +PROGRESSBAR_LOADPNG;Chargement du fichier PNG... +PROGRESSBAR_LOADTIFF;Chargement du fichier TIFF... +PROGRESSBAR_NOIMAGES;Pas d'image trouvée +PROGRESSBAR_PROCESSING;Traitement de l'Image... +PROGRESSBAR_PROCESSING_PROFILESAVED;Profil de traitement sauvegardé +PROGRESSBAR_READY;Prêt +PROGRESSBAR_SAVEJPEG;Enregistrement du fichier JPEG... +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_ISO;ISO +QINFO_NOEXIF;Données EXIF non disponibles. +SAVEDLG_AUTOSUFFIX;Ajouter automatiquement un suffixe si le fichier existe déjà +SAVEDLG_FILEFORMAT;Format de fichier +SAVEDLG_FORCEFORMATOPTS;Forcer les options d'enregistrement +SAVEDLG_JPEGQUAL;Qualité JPEG +SAVEDLG_PNGCOMPR;Compression PNG +SAVEDLG_PUTTOQUEUEHEAD;Placer au début de la file de traitement +SAVEDLG_PUTTOQUEUETAIL;Placer au fin de la file de traitement +SAVEDLG_PUTTOQUEUE;Placer dans la file de traitement +SAVEDLG_SAVEIMMEDIATELY;Enregistrer immédiatement +SAVEDLG_SAVESPP;Enregistrer les paramètres de développement avec l'image +SAVEDLG_SUBSAMP;Sous-échantillonnage +SAVEDLG_SUBSAMP_1;Meilleure compression +SAVEDLG_SUBSAMP_2;Équilibré +SAVEDLG_SUBSAMP_3;Meilleure qualité +SAVEDLG_SUBSAMP_TOOLTIP;Compression: 4:1:1\nÉquilibré: 4:2:2\nQualité: 4:4:4 +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 +THRESHOLDSELECTOR_BL;Bas-gauche +THRESHOLDSELECTOR_BR;Bas-droite +THRESHOLDSELECTOR_B;Bas +THRESHOLDSELECTOR_HINT;Maintenez la touche Shift appuyée pour déplacer les curseurs individuellement. +THRESHOLDSELECTOR_TL;Haut-Gauche +THRESHOLDSELECTOR_TR;Haut-droite +THRESHOLDSELECTOR_T;Haut +TOOLBAR_TOOLTIP_CROP;Sélection du recadrage\nRaccourci: c\nDéplacez le recadrage en utilisant Shift + Glisser +TOOLBAR_TOOLTIP_HAND;Outil de navigation\nRaccourci: h +TOOLBAR_TOOLTIP_STRAIGHTEN;Sélection de la ligne d'horizon\nRaccourci: s\n\nIndiquez la verticale ou l'horizontale en dessinant une ligne à travers l'image de prévisualisation. L'angle de rotation sera affiché près de la ligne guide. Le centre de rotation est le centre géométrique de l'image. +TOOLBAR_TOOLTIP_WB;Choix du point déterminant la balance des blancs\nRaccourci: w +TP_BWMIX_AUTOCH;Auto +TP_BWMIX_AUTOCH_TIP;Calcul les valeurs optimales du mixeur de canaux +TP_BWMIX_CC_ENABLED;Ajuster les couleurs complémentaires +TP_BWMIX_CC_TOOLTIP;Activer pour permettre l'ajustage automatique des couleur complémentaire dans le mode ROJVCBPM +TP_BWMIX_CHANNEL;Égaliseur de Luminance +TP_BWMIX_CURVEEDITOR1;Courbe 'avant' +TP_BWMIX_CURVEEDITOR2;Courbe 'après' +TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Courbe tonale, après la conversion en N&B, à la fin du traitement +TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Courbe tonale, juste avant la conversion en N&B\nPeut prendre en compte les composantes couleur +TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Modifie la luminance en fonction de la teinte\nFaites attention aux valeurs extrêmes qui peuvent causer des artefacts +TP_BWMIX_FILTER;Filtre de couleur +TP_BWMIX_FILTER_BLUEGREEN;Bleu-Vert +TP_BWMIX_FILTER_BLUE;Bleu +TP_BWMIX_FILTER_GREENYELLOW;Vert-Jaune +TP_BWMIX_FILTER_GREEN;Vert +TP_BWMIX_FILTER_NONE;Aucun +TP_BWMIX_FILTER_PURPLE;Pourpre +TP_BWMIX_FILTER_REDYELLOW;Rouge-Jaune +TP_BWMIX_FILTER_RED;Rouge +TP_BWMIX_FILTER_TOOLTIP;Le filtre de couleur simule les prises de vue avec un filtre coloré placé devant l'objectif. Les filtres colorés réduisent la transmission d'une plage de couleur spécifique et en affectent donc leur luminosité. Ex: un filtre rouge assombri les ciels bleus. +TP_BWMIX_FILTER_YELLOW;Jaune +TP_BWMIX_GAMMA;Correction Gamma +TP_BWMIX_GAM_TOOLTIP;Corrige le gamma pour chaque canaux RVB +TP_BWMIX_LABEL;Noir & Blanc +TP_BWMIX_MET;Méthode +TP_BWMIX_MET_CHANMIX;Mixeur de Canaux +TP_BWMIX_MET_DESAT;Désaturation +TP_BWMIX_MET_LUMEQUAL;Égaliseur de Luminance +TP_BWMIX_MIXC;Mixeur +TP_BWMIX_NEUTRAL;Réinit. Mixeur +TP_BWMIX_NEUTRAL_TIP;Réinitialise tous les paramètres (filtre, mixeur de canaux) à zéro +TP_BWMIX_RGBLABEL;R: %1%% V: %2%% B: %3%% Total: %4%% +TP_BWMIX_RGBLABEL_HINT;Coefficients RVB finaux qui tiennent compte de toutes les options du mixeur\nTotal affiche la somme des valeurs RVB actuellement appliqué:\n- toujours 100% en mode relatif\n- supérieur (plus clair) ou inférieur (plus sombre) à 100% en mode absolu. +TP_BWMIX_RGB_TOOLTIP;Mixe les canaux RVB. Utilisez les Préréglages pour vous guider.\nAttention aux valeurs négatives qui peuvent causer des artefacts ou un comportement erratique. +TP_BWMIX_SETTING;Préréglages +TP_BWMIX_SETTING_TOOLTIP;Différents préréglages (films, paysage, ...) ou réglages manuel du mixeur de canaux +TP_BWMIX_SET_HIGHCONTAST;Contraste Élevé +TP_BWMIX_SET_HIGHSENSIT;Haute Sensibilité +TP_BWMIX_SET_HYPERPANCHRO;Hyper Panchromatique +TP_BWMIX_SET_INFRARED;Infrarouge +TP_BWMIX_SET_LANDSCAPE;Paysage +TP_BWMIX_SET_LOWSENSIT;Basse Sensibilité +TP_BWMIX_SET_LUMINANCE;Luminance +TP_BWMIX_SET_NORMCONTAST;Contraste Normal +TP_BWMIX_SET_ORTHOCHRO;Orthochromatique +TP_BWMIX_SET_PANCHRO;Panchromatique +TP_BWMIX_SET_PORTRAIT;Portrait +TP_BWMIX_SET_RGBABS;RVB Absolu +TP_BWMIX_SET_RGBREL;RVB Relatif +TP_BWMIX_SET_ROYGCBPMABS;ROJVCBPM Absolu +TP_BWMIX_SET_ROYGCBPMREL;ROJVCBPM Relatif +TP_BWMIX_TCMODE_FILMLIKE;N&B Similaire Film +TP_BWMIX_TCMODE_SATANDVALBLENDING;N&B Mixage Saturation et Valeur +TP_BWMIX_TCMODE_STANDARD;N&B Standard +TP_BWMIX_TCMODE_WEIGHTEDSTD;N&B Standard Pondéré +TP_BWMIX_VAL;L +TP_CACORRECTION_BLUE;Bleu +TP_CACORRECTION_LABEL;Aberration chromatique +TP_CACORRECTION_RED;Rouge +TP_CHMIXER_BLUE;Bleu +TP_CHMIXER_GREEN;Vert +TP_CHMIXER_LABEL;Mixage des canaux +TP_CHMIXER_RED;Rouge +TP_CHROMATABERR_LABEL;Aberration Chromatique +TP_COARSETRAF_TOOLTIP_HFLIP;Symétriser / axe vertical +TP_COARSETRAF_TOOLTIP_ROTLEFT;Rotation vers la gauche\nRaccourci: [\n\nRaccourci en mode Éditeur unique: Alt-[ +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Rotation vers la droite\nRaccourci: ]\n\nRaccourci en mode Éditeur unique: Alt-] +TP_COARSETRAF_TOOLTIP_VFLIP;Symétriser / axe horizontal +TP_COLORAPP_ADAPTSCENE;Luminosité de la scène +TP_COLORAPP_ADAPTSCENE_TOOLTIP;Luminance absolue de l'environnement de la scène (cd/m²).\n1) Calculé à partir des données Exif:\nVitesse d'obturation - val. ISO - ouverture F - correction d'expos. du boitier.\n2) Calculé à partir du Point Blanc Raw et de la Compensation d'Exposition de RawTherapee +TP_COLORAPP_ADAPTVIEWING;Luminosité du visionnage (cd/m²) +TP_COLORAPP_ADAPTVIEWING_TOOLTIP;Luminance absolue de l'environnement de visionnage\n(souvent 16cd/m²) +TP_COLORAPP_ADAP_AUTO_TOOLTIP;Si la case est cochée (recommandé), une valeur optimum est calculée à partir des données Exif.\nPour régler la valeur manuellement, décochez d'abord la case +TP_COLORAPP_ALGO;Algorithme +TP_COLORAPP_ALGO_ALL;Tout +TP_COLORAPP_ALGO_JC;Luminosité + Chroma (JC) +TP_COLORAPP_ALGO_JS;Luminosité + Saturation (JS) +TP_COLORAPP_ALGO_QM;Brillance + Niveau de couleur (QM) +TP_COLORAPP_ALGO_TOOLTIP;Permet de choisir entre des jeux réduits de paramètres ou tous les paramètres +TP_COLORAPP_BADPIXSL;Filtrer les pixels chauds/morts +TP_COLORAPP_BADPIXSL_TOOLTIP;Suppression des pixels chauds/morts (colorés de manière intense).\n0=Aucun effet 1=Médian 2=Gaussien.\n\nCes artefacts sont dus aux limitations de CIECAM02. Vous pouvez également adjuster l'image afin d'éviter les ombres très sombres. +TP_COLORAPP_BRIGHT;Brillance (Q) +TP_COLORAPP_BRIGHT_TOOLTIP;Brillance dans CIECAM02 est différent de Lab et RVB, prend en compte la luminosité du blanc +TP_COLORAPP_CHROMA;Chroma (C) +TP_COLORAPP_CHROMA_M;Niveau de couleurs (M) +TP_COLORAPP_CHROMA_M_TOOLTIP;Niveau de couleurs dans CIECAM02 est différent de Lab et RVB +TP_COLORAPP_CHROMA_S;Saturation (S) +TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation dans CIECAM02 est différent de Lab et RVB +TP_COLORAPP_CHROMA_TOOLTIP;Chroma dans CIECAM02 est différent de Lab et RVB +TP_COLORAPP_CIECAT_DEGREE;Adaptation CAT02 +TP_COLORAPP_CONTRAST;Contraste (J) +TP_COLORAPP_CONTRAST_Q;Contraste (Q) +TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contraste dans CIECAM02 pour le curseur (Q); est différent du contraste Lab et RVB +TP_COLORAPP_CONTRAST_TOOLTIP;Contraste dans CIECAM02 pour le curseur (J); est différent du contraste Lab et RVB +TP_COLORAPP_CURVEEDITOR1;Courbe tonale 1 +TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Histogramme affiche L (lab) avant CIECAM02.\nOn peut voir le résultat dans la fenêtre histogramme.\n Histogramme de J/Q avant/après si la case à cocher "Données CIECAM" est activée.\n (J,Q) ne sont pas affichés dans le panneau histogramme +TP_COLORAPP_CURVEEDITOR2;Courbe tonale 2 +TP_COLORAPP_CURVEEDITOR2_TOOLTIP;usage similaire aux courbes tonales exposition +TP_COLORAPP_CURVEEDITOR3;Courbes chroma +TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Vous pouvez choisir entre chroma -saturation- niveau couleurs.\n Histogramme affiche la chromaticité Lab avant CIECAM.\n On peut voir le résultat final dans la fenêtre histogramme.\n Histogramme de C,s,M avant/après si la cas à cocher "Données CIECAM" est activée.\n (C,s,M) ne sont pas affichés dans le panneau histogramme +TP_COLORAPP_DATACIE;Histogrammes post CIECAM dans les courbes +TP_COLORAPP_DATACIE_TOOLTIP;Quand activé, les histogrammes de fond des courbes CIECAM02 montrent des valeurs/amplitudes approximatives de J/Q, ou de C:s/M après les ajustements CIECAM.\nCette sélection n'a pas d'incidence sur l'histogramme général.\n\nQuand désactivé, les histogrammes de fond des courbes CIECAM affichent les valeurs Lab avant les ajustements CIECAM +TP_COLORAPP_DEGREE_AUTO_TOOLTIP;Si la case est cochée (recommandé), RT calcule une valeur optimale, qui est utilisée par CAT02, mais aussi pour l'ensemble de CIECAM02.\nVous pouvez décocher la case et changer la valeur du curseur; (les valeurs supérieures à 65 sont recommandées) +TP_COLORAPP_DEGREE_TOOLTIP;Niveau d'adaptation chromatique CIE CAT 2002 +TP_COLORAPP_GAMUT;Contrôle du gamut (Lab) +TP_COLORAPP_GAMUT_TOOLTIP;Permet le controle du gamut en mode Lab +TP_COLORAPP_HUE;Teinte (h) +TP_COLORAPP_HUE_TOOLTIP;Teinte (h) - angle entre 0° et 360° +TP_COLORAPP_LABEL;Apparence de la Couleur (CIECAM02) +TP_COLORAPP_LABEL_CAM02;Édition de l'image avec CIE-CAM 2002 +TP_COLORAPP_LABEL_SCENE;Conditions de la scène +TP_COLORAPP_LABEL_VIEWING;Conditions de visionnage +TP_COLORAPP_LIGHT;Luminosité (J) +TP_COLORAPP_LIGHT_TOOLTIP;Luminosité dans CIECAM02 est différent de celui de Lab et RVB +TP_COLORAPP_MODEL;Modèle de Point Blanc +TP_COLORAPP_MODEL_TOOLTIP;Modèle de Point Blanc\n\nBB [RT] + [sortie]:\nLa BB de RT est utilisée pour la scène, CIECAM est réglé sur D50, le blanc du périphérique de sortie utilise la valeur réglée dans Préférences\n\nBB [RT+CAT02] + [sortie]:\nLes réglages de BB de RT sont utilisés par CAT02 et le blanc du périphérique de sortie utilise la valeur réglée dans Préférences +TP_COLORAPP_RSTPRO;Protection des tons chairs et rouges +TP_COLORAPP_RSTPRO_TOOLTIP;Protection des tons chairs et rouges (curseurs et courbes) +TP_COLORAPP_SHARPCIE;Netteté, Contraste par niveau de détails, Microcontraste & Aberration chromatique avec Q/C +TP_COLORAPP_SHARPCIE_TOOLTIP;Netteté, Contraste par niveau de détails, Microcontraste & Aberration chromatique utiliseront CIECAM02 si activé. +TP_COLORAPP_SURROUND;Entourage +TP_COLORAPP_SURROUND_AVER;Moyen +TP_COLORAPP_SURROUND_DARK;Sombre +TP_COLORAPP_SURROUND_DIM;Tamisé +TP_COLORAPP_SURROUND_EXDARK;Extrêmement Sombre (Transparent) +TP_COLORAPP_SURROUND_TOOLTIP;Change les tons et couleurs pour prendre en compte les conditions de visionnage du périphérique de sortie\n\nMoyen:\nLuminance de l'entourage moyen (standard)\nL'image ne va pas changer\n\nTamisé:\nEntourage légèrement sombre (TV)\nL'image va devenir un peu plus sombre\n\nSombre:\nEntourage sombre (projecteur)\nL'image va devenir plus sombre\n\nExtrêmement sombre:\nEntourage noir (transparents)\nL'image va devenir encore plus sombre +TP_COLORAPP_SURSOURCE;Entourage sombre +TP_COLORAPP_SURSOURCE_TOOLTIP;Peut être utilisé si l'image source a un bord noir. +TP_COLORAPP_TCMODE_BRIGHTNESS;Brillance +TP_COLORAPP_TCMODE_CHROMA;Chroma +TP_COLORAPP_TCMODE_COLORF;Niveau de couleurs +TP_COLORAPP_TCMODE_LABEL1;Courbe mode 1 +TP_COLORAPP_TCMODE_LABEL2;Courbe mode 2 +TP_COLORAPP_TCMODE_LABEL3;Courbe chroma mode +TP_COLORAPP_TCMODE_LIGHTNESS;Luminosité +TP_COLORAPP_TCMODE_SATUR;Saturation +TP_COLORAPP_TONECIE;Compression Tonale utilisant CIECAM02 +TP_COLORAPP_TONECIE_TOOLTIP;Si cette option est désactivée, la compression tonale est faite dans l'espace Lab.\nSi cette options est activée, la compression tonale est faite en utilisant CIECAM02.\nL'outil Compression Tonale doit être activé pour que ce réglage prenne effet +TP_COLORAPP_WBCAM;BB [RT+CAT02] + [sortie] +TP_COLORAPP_WBRT;BB [RT] + [sortie] +TP_COLORTONING_AB;o C/L +TP_COLORTONING_BALANCE;Balance +TP_COLORTONING_BY;o C/L +TP_COLORTONING_CHROMAC;Opacité +TP_COLORTONING_COLOR;Couleur +TP_COLORTONING_HIGHLIGHT;Hautes lumières +TP_COLORTONING_HUE;Teinte +TP_COLORTONING_LABEL;Virage Partiel +TP_COLORTONING_LAB;Mixage Lab +TP_COLORTONING_LUMAMODE;Préserver la luminance +TP_COLORTONING_LUMAMODE_TOOLTIP;Si activé, lorsque vous changez la couleur (rouge, vert, cyan, bleu, etc.), la luminance de chaque pixel est préservé +TP_COLORTONING_LUMA;Luminance +TP_COLORTONING_METHOD;Méthode +TP_COLORTONING_METHOD_TOOLTIP;Mixage Lab - RVB courbes - RVB curseurs utilise une interpolation\nBalance couleur(ombres / tons moyens / hautes lumières)\nSaturation 2 couleurs utilise couleurs directes\nDans tous les méthodes vous pouvez activer Noir et Blanc +TP_COLORTONING_MIDTONES;Tons Moyens +TP_COLORTONING_NEUTRAL_TIP;Réinitialise toutes les valeurs (Ombres, Tons moyens, Hautes lumières) à leur valeur par défaut. +TP_COLORTONING_OPACITY;Opacité +TP_COLORTONING_RGBCURVES;RVB - Courbes +TP_COLORTONING_RGBSLIDERS;RVB - Curseurs +TP_COLORTONING_SATURATEDOPACITY;Force +TP_COLORTONING_SATURATIONTHRESHOLD;Seuil +TP_COLORTONING_SA;Saturation protection +TP_COLORTONING_SHADOWS;Ombres +TP_COLORTONING_SPLITCOCO;Balance Couleur Ombres / Tons moyens / Hautes lumières +TP_COLORTONING_SPLITCO;Ombres / Tons moyens / Hautes lumières +TP_COLORTONING_SPLITLR;Saturation 2 couleurs +TP_COLORTONING_STRENGTH;Force +TP_COLORTONING_STR;Force +TP_COLORTONING_TWO2;Chroma spécial '2 couleurs' +TP_COLORTONING_TWOALL;Chroma spécial +TP_COLORTONING_TWOBY;Chroma spécial 'a' and 'b' +TP_COLORTONING_TWOCOLOR_TOOLTIP;Standard: réponse linéaire identique pour 'a' et 'b'\nSpécial 'ab': même réponse pour 'a' et 'b', mais sans limites - essayez en dessous de la diagonale\nSpécial 'a' et 'b': comme Spécial mais avec des courbes séparées pour 'a' et 'b': dédié aux effets spéciaux\nSpécial 2 couleurs - plus prévisible +TP_COLORTONING_TWOSTD;Chroma standard +TP_CROP_FIXRATIO;Ratio fixe: +TP_CROP_GTDIAGONALS;Règle des diagonales +TP_CROP_GTEPASSPORT;Passeport biométrique +TP_CROP_GTFRAME;Cadre +TP_CROP_GTGRID;Grille +TP_CROP_GTNONE;Aucun +TP_CROP_GTRULETHIRDS;Règle des tiers +TP_CROP_GUIDETYPE;Type de guide: +TP_CROP_H;H +TP_CROP_LABEL;Recadrage +TP_CROP_PPI;PPI= +TP_CROP_SELECTCROP; Sélection du recadrage +TP_CROP_W;L +TP_CROP_X;X +TP_CROP_Y;Y +TP_DARKFRAME_AUTOSELECT;Sélection automatique +TP_DARKFRAME_LABEL;Trame Noire +TP_DEFRINGE_LABEL;Aberration chromatique +TP_DEFRINGE_RADIUS;Rayon +TP_DEFRINGE_THRESHOLD;Seuil +TP_DIRPYRDENOISE_33;3×3 fort +TP_DIRPYRDENOISE_55SOFT;5×5 +TP_DIRPYRDENOISE_55;5×5 fort +TP_DIRPYRDENOISE_77;7×7 (lent) +TP_DIRPYRDENOISE_BLUE;Chrominance - Bleu-Jaune +TP_DIRPYRDENOISE_CHROMA;Chrominance - Maître +TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Peut être utilisé sur les images raw et non-raw.\n\nPour les images non-raw, la réduction de bruit de luminance dépend du gamma du profil couleur d'entée. Un gamma sRGB est supposé, c'est pourquoi si l'image a un profil couleur d'un gamma différent, la réduction de bruit de luminance variera. +TP_DIRPYRDENOISE_ENH;Mode amélioré +TP_DIRPYRDENOISE_ENH_TOOLTIP;Augmente la qualité du débruitage, mais augmente le temps de traitement d'environ 20% +TP_DIRPYRDENOISE_GAMMA;Gamma +TP_DIRPYRDENOISE_GAMMA_TOOLTIP;Gamma fait varier la quantité de réduction de bruit sur l'échelle des tons. Les plus petites valeurs cibleront les ombres, les plus hautes valeurs cibleront les tons les plus clairs. +TP_DIRPYRDENOISE_LABEL;Réduction du bruit +TP_DIRPYRDENOISE_LAB;Lab +TP_DIRPYRDENOISE_LDETAIL;Niveau de détails de Luminance +TP_DIRPYRDENOISE_LM;Luminance seulement +TP_DIRPYRDENOISE_LUMA;Luminance +TP_DIRPYRDENOISE_MEDMETHOD;Méthode +TP_DIRPYRDENOISE_MEDTYPE;Type de médiane +TP_DIRPYRDENOISE_MED;Filtre Médian +TP_DIRPYRDENOISE_MED_TOOLTIP;Active le débruitage médian +TP_DIRPYRDENOISE_METHOD;Méthode +TP_DIRPYRDENOISE_METHOD_TOOLTIP;Pour les images raw, les méthodes RVB ou Lab peuvent être utilisées.\n\nPour les images non-raw la méthode Lab sera utilisée, indépendamment de ce qu'indique ce bouton. +TP_DIRPYRDENOISE_METM_TOOLTIP;Lorsque vous utilisez les méthodes "Luminance seulement" et "Lab", un filtrage médian sera effectué juste après l'étape des ondelettes dans le pipeline de la réduction de bruit.\nEm mode "RVB", il sera effectué à la toute fin du pipeline de la réduction de bruit. +TP_DIRPYRDENOISE_MET_TOOLTIP;Applique un filtre médian de la taille souhaité. Plus il est large, plus cela prendra de temps.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +TP_DIRPYRDENOISE_MET_TOOLTIP;Type de filtrage médian:\n3x3, 3x3 fort et 5x5 (RVB) ou 3x3, 3x3 fort, 5x5, 5x5 fort ou 7x7 (L seulement + Lab)\n\nSupprime encore plus de bruit. +TP_DIRPYRDENOISE_PASSES_TOOLTIP;Appliquer 3 itération du filtre médian 3x3 donne de meilleurs résultats qu'appliquer une seule fois le filtre 7x7. +TP_DIRPYRDENOISE_PASSE;Itérations +TP_DIRPYRDENOISE_RED;Chrominance - Rouge-Vert +TP_DIRPYRDENOISE_RGB;RVB +TP_DIRPYREQUALIZER_ALGO;Domaine des tons chairs +TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fin: plus proche des tons chairs, minimisant l'actions sur les autres couleurs\nLarge: évite plus d'artéfacts +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;Contraste par niveaux de détail +TP_DIRPYREQUALIZER_LUMACOARSEST;les plus gros +TP_DIRPYREQUALIZER_LUMACONTRAST_MINUS;Contraste- +TP_DIRPYREQUALIZER_LUMACONTRAST_PLUS;Contraste+ +TP_DIRPYREQUALIZER_LUMAFINEST;les plus petits +TP_DIRPYREQUALIZER_LUMANEUTRAL;Neutre +TP_DIRPYREQUALIZER_SKIN;Protection/Ciblage des Tons Chairs +TP_DIRPYREQUALIZER_SKIN_TOOLTIP;A -100, les tons chairs sont ciblés.\nA 0 tous les tons sont traités de maière équivalentes.\nA +100, les tons chairs sont protégés et tous les autres tons sont traités. +TP_DIRPYREQUALIZER_THRESHOLD;Seuil +TP_DIRPYREQUALIZER_TOOLTIP;Attempts to reduce artifacts due to the transitions between the color (hue, chroma, luma) of the skin and the rest of the image. +TP_DISTORTION_AMOUNT;Quantité +TP_DISTORTION_AUTO;Correction auto de la distorsion +TP_DISTORTION_AUTO_TIP;(Experimental) Corrige la distorsion de l'objectif automatiquement pour certains APN (M4/3, quelques compacts, etc.) +TP_DISTORTION_LABEL;Distorsion +TP_EPD_EDGESTOPPING;Arrêt des bords +TP_EPD_LABEL;Compression tonale +TP_EPD_REWEIGHTINGITERATES;Itérations de la pondération +TP_EPD_SCALE;Échelle +TP_EPD_STRENGTH;Force +TP_EPD_TOOLTIP;Vous pouvez choisir entre le mode Lab (standard) ou le mode CIECAM02.\n En activant "Compression tonale avec brillance Q CIECAM" dans le menu "Brillance + Niveau de couleur CIECAM" +TP_EXPOSURE_AUTOLEVELS;Niveaux Auto +TP_EXPOSURE_AUTOLEVELS_TIP;Bascule l'usage de Niveaux automatiques afin de régler automatiquement les valeurs basé sur l'analyse de l'image\nActive la Reconstruction des Hautes Lumières si nécessaire. +TP_EXPOSURE_BLACKLEVEL;Noir +TP_EXPOSURE_BRIGHTNESS;Luminosité +TP_EXPOSURE_CLIP;Rognage % +TP_EXPOSURE_CLIP_TIP;La fraction de pixels que l'outil Niveaux Auto passera en dehors du domaine +TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Seuil de compression\ndes hautes lumières +TP_EXPOSURE_COMPRHIGHLIGHTS;Compression hautes lumières +TP_EXPOSURE_COMPRSHADOWS;Compression des ombres +TP_EXPOSURE_CONTRAST;Contraste +TP_EXPOSURE_CURVEEDITOR1;Courbe Tonale 1 +TP_EXPOSURE_CURVEEDITOR2;Courbe Tonale 2 +TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Référez-vous à la section suivante du manuel pour en savoir plus sur les manières d'obtenir les meilleurs résultats avec l'option de double courbe:\nThe Toolbox > Exposure Tab > Exposure Panel > Tone Curve +TP_EXPOSURE_EXPCOMP;Compensation d'exposition +TP_EXPOSURE_LABEL;Exposition +TP_EXPOSURE_SATURATION;Saturation +TP_EXPOSURE_TCMODE_FILMLIKE;Similaire Film +TP_EXPOSURE_TCMODE_LABEL1;Mode courbe 1 +TP_EXPOSURE_TCMODE_LABEL2;Mode courbe 2 +TP_EXPOSURE_TCMODE_LUMINANCE;Luminance +TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Mixage Saturation et Valeur +TP_EXPOSURE_TCMODE_STANDARD;Standard +TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Standard Pondéré +TP_EXPOS_BLACKPOINT_LABEL;Points Noir Raw +TP_EXPOS_WHITEPOINT_LABEL;Points Blanc Raw +TP_FILMSIMULATION_LABEL;Simulation de Film +TP_FILMSIMULATION_STRENGTH;Force +TP_FILMSIMULATION_ZEROCLUTSFOUND;Veuillez préciser le dossier contenant les fichiers HaldCLUT dans les Préférences +TP_FLATFIELD_AUTOSELECT;Sélection automatique +TP_FLATFIELD_BLURRADIUS;Rayon de floutage +TP_FLATFIELD_BLURTYPE;Type de floutage +TP_FLATFIELD_BT_AREA;Zone +TP_FLATFIELD_BT_HORIZONTAL;Horizontal +TP_FLATFIELD_BT_VERTHORIZ;Vert. + Horiz. +TP_FLATFIELD_BT_VERTICAL;Vertical +TP_FLATFIELD_CLIPCONTROL;Control de l'écrêtage +TP_FLATFIELD_LABEL;Champ Uniforme +TP_GAMMA_CURV;Gamma +TP_GAMMA_FREE;Manuel +TP_GAMMA_OUTPUT;Gamma de sortie +TP_GAMMA_SLOP;Pente (linéaire) +TP_GENERAL_11SCALE_TOOLTIP;Les effets de cet outil ne sont visible ou fiable qu'avec un aperçu à l'échelle 1:1. +TP_GRADIENT_CENTER;Centre +TP_GRADIENT_CENTER_X;Centre X +TP_GRADIENT_CENTER_X_TOOLTIP;Coord. X du point d'ancrage de la rotation: -100=bord gauche, 0=centre, +100=bord droit +TP_GRADIENT_CENTER_Y;Centre Y +TP_GRADIENT_CENTER_Y_TOOLTIP;Coord. Y du point d'ancrage de la rotation: -100=bord supérieur, 0=centre, +100=bord inférieur +TP_GRADIENT_DEGREE;Angle +TP_GRADIENT_DEGREE_TOOLTIP;Angle de rotation (degré) +TP_GRADIENT_FEATHER;Adoucissement +TP_GRADIENT_FEATHER_TOOLTIP;Largeur du dégradé (pourcentage de la diagonal de l'image) +TP_GRADIENT_LABEL;Filtre Dégradé +TP_GRADIENT_STRENGTH;Force +TP_GRADIENT_STRENGTH_TOOLTIP;Force de l'effet (EV) +TP_HLREC_BLEND;Blend (mélange) +TP_HLREC_CIELAB;Mélange CIELab +TP_HLREC_COLOR;Propagation de la couleur +TP_HLREC_ENA_TOOLTIP;Peut être activé par le bouton Niveau Auto +TP_HLREC_LABEL;Reconstruction des hautes lumières +TP_HLREC_LUMINANCE;Récupération de la luminance +TP_HLREC_METHOD;Méthode: +TP_HSVEQUALIZER_CHANNEL;Canal +TP_HSVEQUALIZER_HUE;T +TP_HSVEQUALIZER_LABEL;Égaliseur TSV +TP_HSVEQUALIZER_SAT;S +TP_HSVEQUALIZER_VAL;V +TP_ICM_BLENDCMSMATRIX;Mélange des hautes lumières\ndu profil ICC avec la matrice +TP_ICM_BLENDCMSMATRIX_TOOLTIP;Activer la récupération des zones brûlées lorsque les profils ICC basés sur la LUT sont utilisés +TP_ICM_DCPILLUMINANT;Illuminant +TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolé +TP_ICM_DCPILLUMINANT_TOOLTIP;Sélectionne quel illuminant DCP inclus utiliser. La valeur par défaut est "Interpolé", qui est un mix entre les 2 profils inclus basé sur la Balance des Blancs choisie. Ce paramètre n'est actif que si un fichier DCP Bi-Illuminant avec support de l'interpolation est choisi. +TP_ICM_INPUTCAMERAICC;Sél. auto du profile de l'APN +TP_ICM_INPUTCAMERAICC_TOOLTIP;Utilise les profils d'entrée DCP ou ICC spécifiques à RawTherapee, qui sont plus précis qu'une simple matrice.\nDisponible pour certains appareils photo, ces profils sont stoqués dans le dossier /iccprofiles/input.\nCelui dont le nom de fichier correspond au champ EXIF "Modèle" (de l'appareil) est automatiquement sélectionné. +TP_ICM_INPUTCAMERA;Celui de l'appareil photo +TP_ICM_INPUTCAMERA_TOOLTIP;Par ordre de préférence, utilise les matrices de couleur incluses dans le fichier RAW, les matrices de couleur simple fournies par RawTherapee ou celles de DCRaw +TP_ICM_INPUTCUSTOM;Personnel +TP_ICM_INPUTCUSTOM_TOOLTIP;Sélectionez votre propre profil DCP/ICC pour votre appareil photo +TP_ICM_INPUTDLGLABEL;Choix du profil DCP/ICC d'entrée... +TP_ICM_INPUTEMBEDDED;Utiliser celui inclus, si possible +TP_ICM_INPUTEMBEDDED_TOOLTIP;Utilise le profil inclus dans les fichiers non-Raw +TP_ICM_INPUTNONE;Sans profil +TP_ICM_INPUTNONE_TOOLTIP;N'utilise aucun profil couleur d'entrée du tout. À n'utiliser que dans des cas très spéciaux. +TP_ICM_INPUTPROFILE;Profil d'entrée +TP_ICM_LABEL;ICM +TP_ICM_NOICM;Pas d'ICM: sortie sRGB +TP_ICM_OUTPUTPROFILE;Profil de sortie +TP_ICM_SAVEREFERENCE;Utiliser l'image comme profil de référence +TP_ICM_SAVEREFERENCE_TOOLTIP;Sauvegarde une image TIFF linéaire avant que le profil d'entrée ne soit appliqué. Le résultat peut être utilisé à des fins de calibrage, pour générer un profil APN. +TP_ICM_TONECURVE;Utiliser la courbe tonale du profil DCP +TP_ICM_TONECURVE_TOOLTIP;Utilise la courbe tonale DCP incluse. Ce paramètre ne sera actif que si le profil DCP contient une courbe tonale +TP_ICM_WORKINGPROFILE;Profil de Travail +TP_IMPULSEDENOISE_LABEL;Réduction du bruit d'impulsion +TP_IMPULSEDENOISE_THRESH;Seuil +TP_LABCURVE_AVOIDCOLORSHIFT;Éviter les dérives de teinte +TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Ramènes les données dans le gamut de l'espace couleur de travail\npuis applique la correction de Munsell +TP_LABCURVE_BRIGHTNESS;Luminosité +TP_LABCURVE_CHROMATICITY;Chromaticité +TP_LABCURVE_CHROMA_TOOLTIP;Pour activer la colorisation du N&B par les courbes 'a' et 'b', réglez la Chromaticité à -100 +TP_LABCURVE_CONTRAST;Contraste +TP_LABCURVE_CURVEEDITOR;Courbe de luminance +TP_LABCURVE_CURVEEDITOR_A_RANGE1;Vert saturé +TP_LABCURVE_CURVEEDITOR_A_RANGE2;Vert pastel +TP_LABCURVE_CURVEEDITOR_A_RANGE3;Rouge pastel +TP_LABCURVE_CURVEEDITOR_A_RANGE4;Rouge saturé +TP_LABCURVE_CURVEEDITOR_B_RANGE1;Bleu saturé +TP_LABCURVE_CURVEEDITOR_B_RANGE2;Bleu pastel +TP_LABCURVE_CURVEEDITOR_B_RANGE3;Jaune pastel +TP_LABCURVE_CURVEEDITOR_B_RANGE4;Jaune saturé +TP_LABCURVE_CURVEEDITOR_CC;CC +TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutre +TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Terne +TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastel +TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Saturé +TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Chromaticité en fonction de la Chromaticité C=f(C) +TP_LABCURVE_CURVEEDITOR_CH;CT +TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticité en fonction de la Teinte C=f(T) +TP_LABCURVE_CURVEEDITOR_CL;CL +TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Chromaticité en fonction de la Luminance C=f(L) +TP_LABCURVE_CURVEEDITOR_HH;TT +TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Teinte en fonction de la Teinte T=f(T) +TP_LABCURVE_CURVEEDITOR_LC;LC +TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminance en fonction de la Chromaticité L=f(C) +TP_LABCURVE_CURVEEDITOR_LH;LT +TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Luminance en fonction de la Teinte L=f(T) +TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminance en fonction de la Luminance L=f(L) +TP_LABCURVE_LABEL;Ajustements Lab +TP_LABCURVE_LCREDSK;Restreindre LC aux tons rouge et peau +TP_LABCURVE_LCREDSK_TIP;Si activé, la courbe 'LC' est limitée au tons rouge et peau.\nSi désactivé, elle s'applique à toutes les teintes. +TP_LABCURVE_RSTPROTECTION;Protection des tons rouges et chair +TP_LABCURVE_RSTPRO_TOOLTIP;Peut être utilisé avec le curseur Chromaticité et la courbe CC. +TP_LENSGEOM_AUTOCROP;Recadrage auto +TP_LENSGEOM_FILL;Remplir +TP_LENSGEOM_LABEL;Objectif / Géométrie +TP_LENSPROFILE_LABEL;Profil de correction d'objectif +TP_LENSPROFILE_USECA;Corr. de l'aber. chromatique +TP_LENSPROFILE_USEDIST;Corr. de la distortion +TP_LENSPROFILE_USEVIGN;Corr. du vignettage +TP_NEUTRAL;Neutre +TP_NEUTRAL_TIP;Réinitialise les valeurs de l'exposition à des valeurs neutres +TP_PCVIGNETTE_FEATHER;Étendue +TP_PCVIGNETTE_FEATHER_TOOLTIP;Étendue: 0=bords uniquement, 50=mi-chemin du centre, 100=jusqu'au centre +TP_PCVIGNETTE_LABEL;Filtre Vignettage +TP_PCVIGNETTE_ROUNDNESS;Circularité +TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Circularité: 0=rectangulaire, 50=elliptique, 100=circulaire +TP_PCVIGNETTE_STRENGTH;Force +TP_PCVIGNETTE_STRENGTH_TOOLTIP;Force du filtre en EV (maximum dans les coins) +TP_PERSPECTIVE_HORIZONTAL;Horizontale +TP_PERSPECTIVE_LABEL;Perspective +TP_PERSPECTIVE_VERTICAL;Verticale +TP_PFCURVE_CURVEEDITOR_CH;Teinte +TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Contrôle la force du défrangeage en fonction de la couleur. En haut = action maxi, en bas = pas d'action sur la couleur. +TP_PREPROCESS_DEADPIXFILT;Filtrer les pixels morts +TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Essaie de supprimer les pixels morts +TP_PREPROCESS_GREENEQUIL;Équilibrage du vert +TP_PREPROCESS_HOTPIXFILT;Filtrer les pixels chauds +TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Essaie de supprimer les pixels chauds +TP_PREPROCESS_LABEL;Traitement pre-dématriçage +TP_PREPROCESS_LINEDENOISE;Filtre de bruit de ligne +TP_PREPROCESS_NO_FOUND;Aucun trouvé +TP_RAWCACORR_AUTO;Correction automatique +TP_RAWCACORR_CABLUE;Bleu +TP_RAWCACORR_CARED;Rouge +TP_RAWEXPOS_BLACKS;Niveaux de noir +TP_RAWEXPOS_BLACK_0;Vert 1 (maître) +TP_RAWEXPOS_BLACK_1;Rouge +TP_RAWEXPOS_BLACK_2;Bleu +TP_RAWEXPOS_BLACK_3;Vert 2 +TP_RAWEXPOS_BLACK_BLUE;Bleu +TP_RAWEXPOS_BLACK_GREEN;Vert +TP_RAWEXPOS_BLACK_RED;Rouge +TP_RAWEXPOS_LINEAR;Corr. du Point Blanc +TP_RAWEXPOS_PRESER;Préservation des HL +TP_RAWEXPOS_RGB;Rouge, Vert, Bleu +TP_RAWEXPOS_TWOGREEN;Lier les verts +TP_RAW_DCBENHANCE;Amélioration de DCB +TP_RAW_DCBITERATIONS;Nombre d'itération de DCB +TP_RAW_DMETHOD;Méthode +TP_RAW_DMETHOD_PROGRESSBAR;Dématriçage %1... +TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Affinage du dématriçage... +TP_RAW_DMETHOD_TOOLTIP;Note: IGV et LMMSE sont dédiés aux images à haut ISO +TP_RAW_FALSECOLOR;Itérations pour la suppression\ndes fausses couleurs +TP_RAW_LABEL;Dématriçage +TP_RAW_LMMSEITERATIONS;Niveau d'amélioration LMMSE +TP_RAW_LMMSE_TOOLTIP;Ajoute gamma (niveau 1) + médian (niveau 2-4) + affinage (niveau 5-6) pour réduire les artéfacts et améliorer le rapport signal/bruit +TP_RAW_SENSOR_BAYER_LABEL;Capteur à matrice de Bayer +TP_RAW_SENSOR_XTRANS_LABEL;Capteur à matrice X-Trans +TP_RESIZE_APPLIESTO;S'applique à: +TP_RESIZE_CROPPEDAREA;La zone recadrée +TP_RESIZE_FITBOX;Boîte englobante +TP_RESIZE_FULLIMAGE;L'image entière +TP_RESIZE_HEIGHT;Hauteur +TP_RESIZE_H;H: +TP_RESIZE_LABEL;Redimensionnement +TP_RESIZE_LANCZOS;Lanczos +TP_RESIZE_METHOD;Méthode: +TP_RESIZE_NEAREST;Au plus proche +TP_RESIZE_SCALE;Échelle +TP_RESIZE_SPECIFY;Préciser: +TP_RESIZE_WIDTH;Largeur +TP_RESIZE_W;L: +TP_RGBCURVES_BLUE;B +TP_RGBCURVES_CHANNEL;Canal +TP_RGBCURVES_GREEN;V +TP_RGBCURVES_LABEL;Courbes RVB +TP_RGBCURVES_LUMAMODE;Mode Lominosité +TP_RGBCURVES_LUMAMODE_TOOLTIP;Mode Lominosité permet de faire varier la contribution des canaux R, V et B à la luminosité de l'image, sans altérer les couleurs de l'image. +TP_RGBCURVES_RED;R +TP_ROTATE_DEGREE;Degré +TP_ROTATE_LABEL;Rotation +TP_ROTATE_SELECTLINE;Choisir la ligne d'horizon +TP_SAVEDIALOG_OK_TIP;Raccourci: Ctrl-Entrée +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Hautes lumières +TP_SHADOWSHLIGHTS_HLTONALW;Amplitude tonale des\nhautes lumières +TP_SHADOWSHLIGHTS_LABEL;Ombres/Hautes lumières +TP_SHADOWSHLIGHTS_LOCALCONTR;Contraste local +TP_SHADOWSHLIGHTS_RADIUS;Rayon +TP_SHADOWSHLIGHTS_SHADOWS;Ombres +TP_SHADOWSHLIGHTS_SHARPMASK;Masque haute précision +TP_SHADOWSHLIGHTS_SHTONALW;Amplitude tonale des ombres +TP_SHARPENEDGE_AMOUNT;Quantité +TP_SHARPENEDGE_LABEL;Bords +TP_SHARPENEDGE_PASSES;Itérations +TP_SHARPENEDGE_THREE;Luminance uniquement +TP_SHARPENING_AMOUNT;Quantité +TP_SHARPENING_EDRADIUS;Rayon +TP_SHARPENING_EDTOLERANCE;Tolérance des bords +TP_SHARPENING_HALOCONTROL;Contrôle du halo +TP_SHARPENING_HCAMOUNT;Quantité +TP_SHARPENING_LABEL;Netteté +TP_SHARPENING_METHOD;Méthode +TP_SHARPENING_ONLYEDGES;Améliorer seulement les bords +TP_SHARPENING_RADIUS;Rayon +TP_SHARPENING_RLD;Déconvolution de Richardson–Lucy +TP_SHARPENING_RLD_AMOUNT;Quantité +TP_SHARPENING_RLD_DAMPING;Amortissement +TP_SHARPENING_RLD_ITERATIONS;Itérations +TP_SHARPENING_THRESHOLD;Seuil +TP_SHARPENING_TOOLTIP;Un effet légèrement différent peut être obtenu avec CIECAM02. Si différence observée, ajuster les réglages +TP_SHARPENING_USM;Masque flou (USM) +TP_SHARPENMICRO_AMOUNT;Quantité +TP_SHARPENMICRO_LABEL;Microcontraste +TP_SHARPENMICRO_MATRIX;Matrice 3×3 au lieu de 5×5 +TP_SHARPENMICRO_UNIFORMITY;Uniformité +TP_VIBRANCE_AVOIDCOLORSHIFT;Éviter les dérives de teinte +TP_VIBRANCE_CURVEEDITOR_SKINTONES;TT +TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Tons chair +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Rouge/Pourpre +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Rouge +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Rouge/Jaune +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Jaune +TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Teinte en fonction de la teinte +TP_VIBRANCE_LABEL;Vibrance +TP_VIBRANCE_PASTELS;Tons pastels +TP_VIBRANCE_PASTSATTOG;Lier Pastels et Saturés +TP_VIBRANCE_PROTECTSKINS;Protéger les tons chairs +TP_VIBRANCE_PSTHRESHOLD;Seuil entre tons pastels/saturés +TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Seuil de saturation +TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;L'axe vertical représente les tons pastels en bas et les tons saturés en haut.\nL'axe horizontal représente l'échelle de la saturation. +TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Pondération de la transition pastels/saturés +TP_VIBRANCE_SATURATED;Tons saturés +TP_VIGNETTING_AMOUNT;Quantité +TP_VIGNETTING_CENTER;Centre +TP_VIGNETTING_CENTER_X;Centre X +TP_VIGNETTING_CENTER_Y;Centre Y +TP_VIGNETTING_LABEL;Correction vignettage +TP_VIGNETTING_RADIUS;Rayon +TP_VIGNETTING_STRENGTH;Force +TP_WBALANCE_AUTO;Auto +TP_WBALANCE_CAMERA;Appareil photo +TP_WBALANCE_CLOUDY;Nuageux +TP_WBALANCE_CUSTOM;Personnalisé +TP_WBALANCE_DAYLIGHT;Lumière du jour (ensoleillé) +TP_WBALANCE_EQBLUERED;Égaliseur Bleu/Rouge +TP_WBALANCE_EQBLUERED_TOOLTIP;Permet de dévier du comportement normal de la "balance des blancs" en modulant la balance bleu/rouge.\nCeci peut être utile lorsque les conditions de prise de vue:\na) sont loins de l'illuminant strandard (ex: sous-marin)\nb) sont loins des conditions où a été réalisé le calibrage\nc) où les matrices ou les profils ICC sont incorrect +TP_WBALANCE_FLASH55;Leica +TP_WBALANCE_FLASH60;Standard, Canon, Pentax, Olympus +TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta +TP_WBALANCE_FLASH_HEADER;Flash +TP_WBALANCE_FLUO1;F1 - Lumière du jour +TP_WBALANCE_FLUO2;F2 - Blanc froid +TP_WBALANCE_FLUO3;F3 - Blanc +TP_WBALANCE_FLUO4;F4 - Blanc chaud +TP_WBALANCE_FLUO5;F5 - Lumière du jour +TP_WBALANCE_FLUO6;F6 - Blanc lumineux +TP_WBALANCE_FLUO7;F7 - D65 Lumière du jour +TP_WBALANCE_FLUO8;F8 - D50 / Sylvania F40 Design +TP_WBALANCE_FLUO9;F9 - Blanc froid deluxe +TP_WBALANCE_FLUO10;F10 - Philips TL85 +TP_WBALANCE_FLUO11;F11 - Philips TL84 +TP_WBALANCE_FLUO12;F12 - Philips TL83 +TP_WBALANCE_FLUO_HEADER;Fluorescent +TP_WBALANCE_GREEN;Teinte +TP_WBALANCE_GTI;GTI +TP_WBALANCE_HMI;HMI +TP_WBALANCE_JUDGEIII;JudgeIII +TP_WBALANCE_LABEL;Balance des blancs +TP_WBALANCE_LAMP_HEADER;Lampe +TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 +TP_WBALANCE_LED_HEADER;LED +TP_WBALANCE_LED_LSI;LSI Lumelex 2040 +TP_WBALANCE_METHOD;Méthode +TP_WBALANCE_SHADE;Ombre +TP_WBALANCE_SIZE;Taille: +TP_WBALANCE_SOLUX35;Solux 3500K +TP_WBALANCE_SOLUX41;Solux 4100K +TP_WBALANCE_SOLUX47;Solux 4700K (fabricant) +TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) +TP_WBALANCE_SPOTWB;Point de mesure +TP_WBALANCE_TEMPERATURE;Température +TP_WBALANCE_TUNGSTEN;Tungstène +TP_WBALANCE_WATER1;Sous-marin 1 +TP_WBALANCE_WATER2;Sous-marin 2 +TP_WBALANCE_WATER_HEADER;Sous-marin +Toggle execution of auto levels to automatically set parameter values based on image analysis\nEnable Highlight Reconstruction if necessary +ZOOMPANEL_100;(100%) +ZOOMPANEL_NEWCROPWINDOW;Ouvrir une (nouvelle) vue détaillée +ZOOMPANEL_ZOOM100;Zoom à 100%\nRaccourci: z +ZOOMPANEL_ZOOMFITSCREEN;Ajuster à la fenêtre\nRaccourci: f +ZOOMPANEL_ZOOMIN;Zoom Avant\nRaccourci: + +ZOOMPANEL_ZOOMOUT;Zoom Arrière\nRaccourci: - + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels +!FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!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_ASIMAGE;As Image +!HISTORY_MSG_296;NR - Luminance curve +!HISTORY_MSG_297;NR - Quality +!HISTORY_MSG_298;Dead pixel filter +!HISTORY_MSG_299;NR - Chrominance curve +!HISTORY_MSG_300;- +!HISTORY_MSG_301;NR - Luma control +!HISTORY_MSG_302;NR - Chroma method +!HISTORY_MSG_303;NR - Chroma method +!HISTORY_MSG_304;W - Contrast levels +!HISTORY_MSG_305;Wavelet Levels +!HISTORY_MSG_306;W - Preview +!HISTORY_MSG_307;W - Preview +!HISTORY_MSG_308;W - Preview direction +!HISTORY_MSG_309;W - ES - Detail +!HISTORY_MSG_310;W - Residual - Sky tar/prot +!HISTORY_MSG_311;W - Wavelet levels +!HISTORY_MSG_312;W - Residual - Shadows threshold +!HISTORY_MSG_313;W - Chroma - Sat/past +!HISTORY_MSG_314;W - Gamut - Reduce artifacts +!HISTORY_MSG_315;W - Residual - Contrast +!HISTORY_MSG_316;W - Gamut - Skin tar/prot +!HISTORY_MSG_317;W - Gamut - Skin hue +!HISTORY_MSG_318;W - Contrast - Highlight levels +!HISTORY_MSG_319;W - Contrast - Highlight range +!HISTORY_MSG_320;W - Contrast - Shadow range +!HISTORY_MSG_321;W - Contrast - Shadow levels +!HISTORY_MSG_322;W - Gamut - Avoid color shift +!HISTORY_MSG_323;W - ES - Local contrast +!HISTORY_MSG_324;W - Chroma - Pastel +!HISTORY_MSG_325;W - Chroma - Saturated +!HISTORY_MSG_326;W - Chroma - Method +!HISTORY_MSG_327;W - Contrast - Apply to +!HISTORY_MSG_328;W - Chroma - Link strength +!HISTORY_MSG_329;W - Toning - Opacity RG +!HISTORY_MSG_330;W - Toning - Opacity BY +!HISTORY_MSG_331;W - Contrast levels - Extra +!HISTORY_MSG_332;W - Tiling method +!HISTORY_MSG_333;W - Residual - Shadows +!HISTORY_MSG_334;W - Residual - Chroma +!HISTORY_MSG_335;W - Residual - Highlights +!HISTORY_MSG_336;W - Residual - Highlights threshold +!HISTORY_MSG_337;W - Residual - Sky hue +!HISTORY_MSG_338;W - ES - Radius +!HISTORY_MSG_339;W - ES - Strength +!HISTORY_MSG_340;W - Strength +!HISTORY_MSG_341;W - Edge performance +!HISTORY_MSG_342;W - ES - First level +!HISTORY_MSG_343;W - Chroma levels +!HISTORY_MSG_344;W - Meth chroma sl/cur +!HISTORY_MSG_345;W - ES - Local contrast +!HISTORY_MSG_346;W - ES - Local contrast method +!HISTORY_MSG_347;W - Denoise - Level 0 +!HISTORY_MSG_348;W - Denoise - Level 1 +!HISTORY_MSG_349;W - Denoise - Level 2 +!HISTORY_MSG_350;W - ES - Edge detection +!HISTORY_MSG_351;W - Residual - HH curve +!HISTORY_MSG_352;W - Background +!HISTORY_MSG_353;W - ES - Gradient sensitivity +!HISTORY_MSG_354;W - ES - Enhance +!HISTORY_MSG_355;W - ES - Threshold low +!HISTORY_MSG_356;W - ES - Threshold high +!HISTORY_MSG_357;W - Denoise - Link with ES +!HISTORY_MSG_358;W - Gamut - CH +!HISTORY_MSG_359;Hot/Dead - Threshold +!HISTORY_MSG_360;TM Gamma +!HISTORY_MSG_361;W - Final - Chroma balance +!HISTORY_MSG_362;W - Residual - Compression method +!HISTORY_MSG_363;W - Residual - Compression strength +!HISTORY_MSG_364;W - Final - Contrast balance +!HISTORY_MSG_365;W - Final - Delta balance +!HISTORY_MSG_366;W - Residual - Compression gamma +!HISTORY_MSG_367;W - ES - Local contrast curve +!HISTORY_MSG_368;W - Final - Contrast balance +!HISTORY_MSG_369;W - Final - Balance method +!HISTORY_MSG_370;W - Final - Local contrast curve +!MAIN_TAB_WAVELET;Wavelet +!MAIN_TAB_WAVELET_TOOLTIP;Shortcut: Alt-w +!NAVIGATOR_B;B: +!NAVIGATOR_G;G: +!NAVIGATOR_H;H: +!NAVIGATOR_LAB_A;a*: +!NAVIGATOR_LAB_B;b*: +!NAVIGATOR_LAB_L;L*: +!NAVIGATOR_NA; -- +!NAVIGATOR_R;R: +!NAVIGATOR_S;S: +!NAVIGATOR_V;V: +!PARTIALPASTE_EQUALIZER;Wavelet Equalizer +!PARTIALPASTE_FILMSIMULATION;Film Simulation +!PARTIALPASTE_WAVELETGROUP;Wavelet processing +!PREFERENCES_AUTLISLOW;Low +!PREFERENCES_AUTLISMAX;Max - Average of all tiles +!PREFERENCES_AUTLISSTD;High +!PREFERENCES_AUTLISVLOW;None +!PREFERENCES_AUTLOW;Low +!PREFERENCES_AUTSTD;Standard +!PREFERENCES_CIEART_FRAME;CIECAM02-Specific Settings +!PREFERENCES_CLUTSCACHE;HaldCLUT Cache +!PREFERENCES_CLUTSCACHE_LABEL;Maximum number of cached CLUTs +!PREFERENCES_CURVEBBOXPOS;Position of curve copypasta buttons +!PREFERENCES_CURVEBBOXPOS_ABOVE;Above +!PREFERENCES_CURVEBBOXPOS_BELOW;Below +!PREFERENCES_CURVEBBOXPOS_LEFT;Left +!PREFERENCES_CURVEBBOXPOS_RIGHT;Right +!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_EXPAUT;Expert +!PREFERENCES_GREYSC18;Yb=18 CIE L#50 +!PREFERENCES_GREYSCA;Automatic +!PREFERENCES_GREYSC;Scene Yb luminance (%) +!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_LEVAUTDN;Denoising level +!PREFERENCES_LEVDN;Cell size +!PREFERENCES_LISS;Auto multi-zone smoothing +!PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders +!PREFERENCES_MAX;Maxi (Tile) +!PREFERENCES_MED;Medium (Tile/2) +!PREFERENCES_MIN;Mini (100x115) +!PREFERENCES_NAVGUIDEBRUSH;Navigator guide color +!PREFERENCES_NAVIGATIONFRAME;Navigation +!PREFERENCES_NOISE;Noise Reduction +!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_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_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_SHOWFILMSTRIPTOOLBAR;Show filmstrip toolbar +!PREFERENCES_SIMPLAUT;Tool mode +!PREFERENCES_SMA;Small (250x287) +!PREFERENCES_STDAUT;Standard +!PREFERENCES_TIMAX;High +!PREFERENCES_TINB;Number of tiles +!PREFERENCES_TISTD;Standard +!PREFERENCES_WAVLEV;Increase wavelet level in quality 'high' +!PREFERENCES_WLONE;One level +!PREFERENCES_WLTWO;Two levels +!PREFERENCES_WLZER;No +!TP_BWMIX_ALGO;Algorithm OYCPM +!TP_BWMIX_ALGO_LI;Linear +!TP_BWMIX_ALGO_SP;Special effects +!TP_BWMIX_ALGO_TOOLTIP;Linear: will produce a normal linear response.\nSpecial effects: will produce special effects by mixing channels non-linearly. +!TP_COLORTONING_AUTOSAT;Automatic +!TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;Chroma opacity as a function of luminance oC=f(L) +!TP_CROP_GTHARMMEANS;Harmonic Means +!TP_CROP_GTTRIANGLE1;Golden Triangles 1 +!TP_CROP_GTTRIANGLE2;Golden Triangles 2 +!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_ABM;Chroma only +!TP_DIRPYRDENOISE_AUTO;Automatic global +!TP_DIRPYRDENOISE_AUTO_TOOLTIP;Try to evaluate chroma noise\nBe careful, this calculation is average, and is quite subjective ! +!TP_DIRPYRDENOISE_AUT;Automatic global +!TP_DIRPYRDENOISE_C2TYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CCCURVE;Chrominance curve +!TP_DIRPYRDENOISE_CHROMAFR;Chrominance +!TP_DIRPYRDENOISE_CTYPE;Auto method +!TP_DIRPYRDENOISE_CTYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nAutomatic multi-zones\nNo preview - works only during saving, but using the "Preview" method by matching the tile size and center to the preview size and center you can get an idea of the expected results.\nThe image is divided into tiles (about 10 to 70 depending on image size) and each tile receives its own chrominance noise reduction settings.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CURVEEDITOR_CC;Chroma +!TP_DIRPYRDENOISE_CURVEEDITOR_CC_TOOLTIP;Increase (multiply) the value of all chrominance sliders.\nThis curve lets you adjust the strength of chromatic noise reduction as a function of chromaticity, for instance to increase the action in areas of low saturation and to decrease it in those of high saturation. +!TP_DIRPYRDENOISE_CURVEEDITOR_L_TOOLTIP;Modulates action of 'Luminance' denoise +!TP_DIRPYRDENOISE_CUR;Curve +!TP_DIRPYRDENOISE_LABM;L*a*b* +!TP_DIRPYRDENOISE_LCURVE;Luminance curve +!TP_DIRPYRDENOISE_LPLABM;Weighted L* (little) + a*b* (normal) +!TP_DIRPYRDENOISE_LTYPE;Luminance control +!TP_DIRPYRDENOISE_LUMAFR;Luminance +!TP_DIRPYRDENOISE_LUMAFR_TOOLTIP;Wavelet on luminance and Fourier transform for luminance detail +!TP_DIRPYRDENOISE_MANU;Manual +!TP_DIRPYRDENOISE_MAN;Manual +!TP_DIRPYRDENOISE_METHOD11;Quality +!TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. +!TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - +!TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 +!TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. +!TP_DIRPYRDENOISE_PON;Auto multi-zones +!TP_DIRPYRDENOISE_PREVLABEL;Preview size=%1, Center: Px=%2 Py=%3 +!TP_DIRPYRDENOISE_PREV;Preview +!TP_DIRPYRDENOISE_PRE;Preview multi-zones +!TP_DIRPYRDENOISE_RGBM;RGB +!TP_DIRPYRDENOISE_SHALBI;High +!TP_DIRPYRDENOISE_SHAL;Standard +!TP_DIRPYRDENOISE_SLI;Slider +!TP_DIRPYRDENOISE_SOFT;3x3 +!TP_DIRPYRDENOISE_TILELABEL;Tile size=%1, Center: Tx=%2 Ty=%3 +!TP_DIRPYREQUALIZER_ARTIF;Reduce artifacts +!TP_EPD_GAMMA;Gamma +!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. +!TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance +!TP_RAW_HD;Threshold +!TP_RAW_HD_TOOLTIP;Lower values make hot/dead pixel detection more aggressive, but false positives may lead to artifacts. If you notice any artifacts appearing when enabling the Hot/Dead Pixel Filters, gradually increase the threshold value until they disappear. +!TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;3-pass gives best results (recommended for low ISO images).\n1-pass is almost undistinguishable from 3-pass for high ISO images and is faster. +!TP_WAVELET_1;Level 1 +!TP_WAVELET_2;Level 2 +!TP_WAVELET_3;Level 3 +!TP_WAVELET_4;Level 4 +!TP_WAVELET_5;Level 5 +!TP_WAVELET_6;Level 6 +!TP_WAVELET_7;Level 7 +!TP_WAVELET_8;Level 8 +!TP_WAVELET_9;Level 9 +!TP_WAVELET_ALL;All levels in all directions +!TP_WAVELET_APPLYTO;Apply To +!TP_WAVELET_AVOID;Avoid color shift +!TP_WAVELET_B0;Black +!TP_WAVELET_B1;Grey +!TP_WAVELET_B2;Residual +!TP_WAVELET_BACUR;Curve +!TP_WAVELET_BALANCE;Contrast balance d/v-h +!TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chromaticity or residual tone mapping are activated, the effect due to balance is amplified. +!TP_WAVELET_BALCHRO;Chroma balance +!TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chromaticity balance. +!TP_WAVELET_BANONE;None +!TP_WAVELET_BASLI;Slider +!TP_WAVELET_BATYPE;Contrast balance method +!TP_WAVELET_CCURVE;Local contrast +!TP_WAVELET_CH1;Whole chromaticity range +!TP_WAVELET_CH2;Saturated/pastel +!TP_WAVELET_CH3;Link contrast levels +!TP_WAVELET_CHCU;Curve +!TP_WAVELET_CHRO;Saturated/pastel threshold +!TP_WAVELET_CHRO_TOOLTIP;Sets the wavelet level which will be the threshold between saturated and pastel colors.\n1-x: saturated\nx-9: pastel\n\nIf the value exceeds the amount of wavelet levels you are using then it will be ignored. +!TP_WAVELET_CHR;Chroma-contrast link strength +!TP_WAVELET_CHR_TOOLTIP;Adjusts chromaticity as a function of "contrast levels" and "chroma-contrast link strength" +!TP_WAVELET_CHSL;Sliders +!TP_WAVELET_CHTYPE;Chrominance method +!TP_WAVELET_COLORT;Opacity Red-Green +!TP_WAVELET_COMBOTH;Both +!TP_WAVELET_COMPCONT;Contrast +!TP_WAVELET_COMPGAMMA;Compression gamma +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjusting the gamma of the residual image allow you to equilibrate the data and histogram. +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjust gamma for residual image and compression.\nAllow to equilibrate data and histogram +!TP_WAVELET_COMPTM;Tone mapping +!TP_WAVELET_CONTEDIT;'After' Contrast curve +!TP_WAVELET_CONTEDIT;'After' contrast curve +!TP_WAVELET_CONTRAST_MINUS;Contrast - +!TP_WAVELET_CONTRAST_PLUS;Contrast + +!TP_WAVELET_CONTRA;Contrast +!TP_WAVELET_CONTRA_TOOLTIP;Changes contrast of the residual image. +!TP_WAVELET_CONTR;Gamut +!TP_WAVELET_CTYPE;Chrominance control +!TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modifies local contrast as a function of the original local contrast (absciss)\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 100..300)\n66% absciss represents standard deviation of local contrast (real value about 300..800)\n100% represents maximum (real value about 3000..8000) +!TP_WAVELET_CURVEEDITOR_CH;Contrast levels=f(Hue) +!TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modifies each level's contrast as a function oh hue.\nTake care not to overwrite changes made with the Gamut Hue controls.\nThe curve will only have an effect when wavelet contrast level sliders are non-zero. +!TP_WAVELET_CURVEEDITOR_CL;L +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Applies a final contrast luminance curve at the end of the wavelet treatment. +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Apply a contrast luminance curve at the end of wavelet level threatment +!TP_WAVELET_CURVEEDITOR_HH;HH +!TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modifies the residual image's hue as a function of hue. +!TP_WAVELET_DALL;All directions +!TP_WAVELET_DAUB;Edge performance +!TP_WAVELET_DAUB_TOOLTIP;Changes Daubechies coefficients:\nD4 = Standard,\nD14 = Often best performance, 10% more time-intensive.\n\nAffects edge detection as well as the general quality of the firsts levels. However the quality is not strictly related to this coefficient and can vary with images and uses. +!TP_WAVELET_DISP;Preview Settings +!TP_WAVELET_DONE;Vertical +!TP_WAVELET_DTHR;Diagonal +!TP_WAVELET_DTWO;Horizontal +!TP_WAVELET_EDCU;Curve +!TP_WAVELET_EDGCONT;Local contrast +!TP_WAVELET_EDGCONT_TOOLTIP;Adjusting the points to the left decreases contrast, and to the right increases it.\nBottom-left, Top-Left, Top-Right, Bottom-right represent respectively local contast for low values, mean, mean+stdev, maxima +!TP_WAVELET_EDGEDETECTTHR2;Threshold high (detection) +!TP_WAVELET_EDGEDETECTTHR;Threshold low (noise) +!TP_WAVELET_EDGEDETECTTHR_TOOLTIP;This adjuster lets you target edge detection for example to avoid applying edge sharpness to fine details, such as noise in the sky. +!TP_WAVELET_EDGEDETECT;Gradient sensitivity +!TP_WAVELET_EDGEDETECT_TOOLTIP;Moving the slider to the right increases edge sensitivity. This affects local contrast, edge settings and noise. +!TP_WAVELET_EDGE;Edge Sharpness +!TP_WAVELET_EDGREINF_TOOLTIP;Reinforce or reduce the action of the first level, do the opposite to the second level, and leave the rest unchanged. +!TP_WAVELET_EDGTHRESH;Detail +!TP_WAVELET_EDGTHRESH_TOOLTIP;Change the repartition between the first levels and the others. The higher the threshold the more the action is centred on the first levels. Be careful with negative values, they increase the action of high levels and can introduce artifacts. +!TP_WAVELET_EDRAD;Radius +!TP_WAVELET_EDRAD_TOOLTIP;This radius adjustment is very different from those in other sharpening tools. Its value is compared to each level through a complex function. In this sense, a value of zero still has an effect. +!TP_WAVELET_EDSL;Threshold Sliders +!TP_WAVELET_EDTYPE;Local contrast method +!TP_WAVELET_EDVAL;Strength +!TP_WAVELET_FINAL;Final Touchup +!TP_WAVELET_FINEST;Finest +!TP_WAVELET_HIGHLIGHT;Highlight luminance range +!TP_WAVELET_HS1;Whole luminance range +!TP_WAVELET_HS2;Shadows/Highlights +!TP_WAVELET_HUESKIN;Skin hue +!TP_WAVELET_HUESKIN_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_HUESKY;Sky hue +!TP_WAVELET_HUESKY_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_INF;Below or equal the level +!TP_WAVELET_ITER;Delta balance levels +!TP_WAVELET_ITER_TOOLTIP;Left: increase low levels and reduce high levels,\nRight: reduce low levels and increase high levels. +!TP_WAVELET_LABEL;Wavelet levels +!TP_WAVELET_LARGEST;Coarsest +!TP_WAVELET_LEVCH;Chromaticity +!TP_WAVELET_LEVELS;Wavelet levels +!TP_WAVELET_LEVELS_TOOLTIP;Choose the number of detail levels the image is to be decomposed into. More levels require more RAM and require a longer processing time. +!TP_WAVELET_LEVF;Contrast +!TP_WAVELET_LEVLABEL;Preview maximum possible levels = %1 +!TP_WAVELET_LEVONE;Level 2 +!TP_WAVELET_LEVTWO;Level 3 +!TP_WAVELET_LEVZERO;Level 1 +!TP_WAVELET_LINKEDG;Link with Edge Sharpness' Strength +!TP_WAVELET_LIPST;Enhanced algorithm +!TP_WAVELET_LIPST_TOOLTIP;This algorithm uses Lipschitz regularity to increase edge detection quality at a cost of increased processing time and memory requirements. +!TP_WAVELET_LOWLIGHT;Shadow luminance range +!TP_WAVELET_MEDGREINF;First level +!TP_WAVELET_MEDILEV;Edge detection +!TP_WAVELET_MEDI;Reduce artifacts in blue sky +!TP_WAVELET_NEUTRAL;Neutral +!TP_WAVELET_NOISE;Denoise and Refine +!TP_WAVELET_NOIS;Denoise +!TP_WAVELET_ONE;One level +!TP_WAVELET_OPACITYWL;Final local contrast +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify final local contrast in function of last local contrast (absciss) for all levels decomposition\nTake into account: \na)contrast levels \nb)edge sharpness \nc)contrast balance\nd)decomposition-recomposition\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 200..1000)\n66% absciss represents standard deviation of local contrast (real value about 1000..2000)\n100% represents maximum (real value about 5000..13000) +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify the final local contrast at the end of the wavelet treatment.\n\nThe left side represents the smallest local contrast, progressing to the largest local contrast on the right. +!TP_WAVELET_OPACITYW;Contrast balance d/v-h curve +!TP_WAVELET_OPACITY;Opacity Blue-Yellow +!TP_WAVELET_PASTEL;Pastel chromaticity +!TP_WAVELET_PREVIEWBACK;Background +!TP_WAVELET_PREVIEWLEVELS;Preview +!TP_WAVELET_RE1;Reinforced +!TP_WAVELET_RE2;Unchanged +!TP_WAVELET_RE3;Reduced +!TP_WAVELET_RESCHRO;Chromaticity +!TP_WAVELET_RESCONH;Highlights +!TP_WAVELET_RESCON;Shadows +!TP_WAVELET_RESID;Residual image +!TP_WAVELET_SAT;Saturated chromaticity +!TP_WAVELET_SETTINGS;Wavelet Settings +!TP_WAVELET_SKIN;Skin targetting/protection +!TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected. +!TP_WAVELET_SKY;Sky targetting/protection +!TP_WAVELET_SKY_TOOLTIP;At -100 sky-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 sky-tones are protected while all other tones are affected. +!TP_WAVELET_STRENGTH;Strength +!TP_WAVELET_STREN;Strength +!TP_WAVELET_SUPE;Extra +!TP_WAVELET_SUP;Above the level +!TP_WAVELET_THRESHOLD2;Shadow levels +!TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels between 9 and 9 minus the value will be affected by the shadow luminance range. Other levels will be fully treated. The highest level possible is limited by the highlight level value (9 minus highlight level value). +!TP_WAVELET_THRESHOLD;Highlight levels +!TP_WAVELET_THRESHOLD_TOOLTIP;Only levels beyond the chosen value will be affected by the highlight luminance range. Other levels will be fully treated. The chosen value here limits the highest possible value of the shadow levels. +!TP_WAVELET_THRH;Highlights threshold +!TP_WAVELET_THR;Shadows threshold +!TP_WAVELET_TILESBIG;Big tiles +!TP_WAVELET_TILESFULL;Full image +!TP_WAVELET_TILESIZE;Tiling method +!TP_WAVELET_TILESLIT;Little tiles +!TP_WAVELET_TILES_TOOLTIP;Processing the full image leads to better quality and is the recommended option, while using tiles is a fall-back solution for users with little RAM. Refer to RawPedia for memory requirements. +!TP_WAVELET_TMHIGH;High +!TP_WAVELET_TMLOWHIGH;Low+High +!TP_WAVELET_TMNONE;None +!TP_WAVELET_TMSTD;Standard +!TP_WAVELET_TMSTRENGTH;Compression strength +!TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image. When the value is different from 0, the Strength and Gamma sliders of the Tone Mapping tool in the Exposure tab will become grayed out. +!TP_WAVELET_TMTYPE;Compression method +!TP_WAVELET_TON;Toning +!TP_WAVELET_daub2;D2 - low +!TP_WAVELET_daub4;D4 - standard +!TP_WAVELET_daub6;D6 - standard plus +!TP_WAVELET_daub10;D10 - medium +!TP_WAVELET_daub14;D14 - high +!ZOOMPANEL_ZOOMFITCROPSCREEN;Fit crop to screen\nShortcut: Alt-f diff --git a/rtdata/languages/Greek b/rtdata/languages/Greek new file mode 100644 index 000000000..c66df6987 --- /dev/null +++ b/rtdata/languages/Greek @@ -0,0 +1,1856 @@ +#01 2008-05-14 zeusalmighty + +ADJUSTER_RESET_TO_DEFAULT;Επαναφορά προεπιλογών +CURVEEDITOR_LINEAR;Γραμμικό +CURVEEDITOR_LOADDLGLABEL;Φόρτωση καμπύλης... +CURVEEDITOR_SAVEDLGLABEL;Αποθήκευση καμπλης... +CURVEEDITOR_TOOLTIPLINEAR;Επαναφορά καμπύλης σε γραμμική +CURVEEDITOR_TOOLTIPLOAD;Φόρτωση καμπύλης απο αρχείο +CURVEEDITOR_TOOLTIPSAVE;Αποθήκευση παρούσας καμπύλης +DIRBROWSER_FOLDERS;Φάκελοι +EXIFFILTER_APERTURE;Aperture +EXIFFILTER_CAMERA;Camera +EXIFFILTER_FOCALLEN;Focal Length +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Lens +EXIFFILTER_SHUTTER;Shutter +EXIFPANEL_ADDEDITHINT;Προσθήκη καινούριας ετικέττας ή επεξεργασία +EXIFPANEL_ADDEDIT;Προσθήκη/Επεξεργασία +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Εισαγωγή τιμής +EXIFPANEL_ADDTAGDLG_SELECTTAG;Επιλογή ετικέττας +EXIFPANEL_ADDTAGDLG_TITLE;Προσθήκη/Επεξεργασία ετικέττας +EXIFPANEL_KEEPHINT;Συγκράτηση των επιλεγμένων ετικεττών κατά την εγγραφή του παραγώμενου αρχείου +EXIFPANEL_KEEP;Συγκράτηση +EXIFPANEL_REMOVEHINT;Αφαίρεση των επιλεγμένων ετικεττών κατά την εγγραφή του παραγώμενου αρχείου +EXIFPANEL_REMOVE;Αφαίρεση +EXIFPANEL_RESETALLHINT;Επαναφορά όλων των ετικεττών στην αρχική τους τιμή +EXIFPANEL_RESETALL;Επαναφορά όλων +EXIFPANEL_RESETHINT;Επαναφορά των επιλεγμένων ετικεττών στις πρωτότυπες τους τιμές +EXIFPANEL_RESET;Επαναφορά +EXIFPANEL_SUBDIRECTORY;Subdirectory +FILEBROWSER_APPLYPROFILE;Apply profile +FILEBROWSER_CLEARPROFILE;Clear profile +FILEBROWSER_COPYPROFILE;Copy profile +FILEBROWSER_DELETEDLGLABEL;File delete confirmation +FILEBROWSER_DELETEDLGMSG;Are you sure you want to delete the selected %1 files? +FILEBROWSER_EMPTYTRASHHINT;Permanently delete the files of the trash +FILEBROWSER_EMPTYTRASH;Empty Trash +FILEBROWSER_PARTIALPASTEPROFILE;Partial paste +FILEBROWSER_PASTEPROFILE;Paste profile +FILEBROWSER_POPUPCANCELJOB;Cancel job +FILEBROWSER_POPUPMOVEEND;Move to end of queue +FILEBROWSER_POPUPMOVEHEAD;Move to head of queue +FILEBROWSER_POPUPOPENINEDITOR;Open in Editor +FILEBROWSER_POPUPOPEN;Open +FILEBROWSER_POPUPPROCESS;Put to processing queue +FILEBROWSER_POPUPREMOVE;Remove from filesystem +FILEBROWSER_POPUPRENAME;Rename +FILEBROWSER_POPUPSELECTALL;Select all +FILEBROWSER_POPUPTRASH;Move to trash +FILEBROWSER_POPUPUNRANK;Unrank +FILEBROWSER_POPUPUNTRASH;Remove from trash +FILEBROWSER_RENAMEDLGLABEL;Rename file +FILEBROWSER_RENAMEDLGMSG;Rename file "%1" to: +FILEBROWSER_SHOWDIRHINT;Show all images of the directory +FILEBROWSER_SHOWRANK1HINT;Show images ranked as 1 star +FILEBROWSER_SHOWRANK2HINT;Show images ranked as 2 star +FILEBROWSER_SHOWRANK3HINT;Show images ranked as 3 star +FILEBROWSER_SHOWRANK4HINT;Show images ranked as 4 star +FILEBROWSER_SHOWRANK5HINT;Show images ranked as 5 star +FILEBROWSER_SHOWTRASHHINT;Show content of the trash +FILEBROWSER_SHOWUNRANKHINT;Show unranked images +FILEBROWSER_STARTPROCESSINGHINT;Start processing/saving of images in the queue +FILEBROWSER_STARTPROCESSING;Start Processing +FILEBROWSER_STOPPROCESSINGHINT;Stop processing of images +FILEBROWSER_STOPPROCESSING;Stop processing +FILEBROWSER_THUMBSIZE;Thumb. size +FILEBROWSER_ZOOMINHINT;Increase thumbnail size +FILEBROWSER_ZOOMOUTHINT;Decrease thumbnail size +GENERAL_ABOUT;About +GENERAL_CANCEL;Ακύρωση +GENERAL_DISABLED;Απενεργοποιημένο +GENERAL_DISABLE;Απενεργοποίηση +GENERAL_ENABLED;Ενεργοποιημένο +GENERAL_ENABLE;Ενεργοποίηση +GENERAL_LANDSCAPE;Τοπίο +GENERAL_NA;μη διαθέσιμο +GENERAL_NO;Όχι +GENERAL_OK;Εντάξει +GENERAL_PORTRAIT;Πορτραίτο +GENERAL_SAVE;Αποθήκευση +HISTOGRAM_TOOLTIP_B;Προβολή/απόκρυψη ΜΠΛΕ ιστογράμματος +HISTOGRAM_TOOLTIP_G;Προβολή/απόκρυψη ΠΡΑΣΙΝΟΥ ιστογράμματος +HISTOGRAM_TOOLTIP_L;Προβολή/απόκρυψη CIELAB ιστογράμματος φωτεινότητας +HISTOGRAM_TOOLTIP_R;Προβολή/απόκρυψη KOKKINOY ιστογράμματος +HISTORY_CHANGED;Αλλαγή +HISTORY_CUSTOMCURVE;Προσαρμοσμένη καμπύλη +HISTORY_DELSNAPSHOT;Αφαίρεση στιγμιοτύπου +HISTORY_FROMCLIPBOARD;From clipboard +HISTORY_LABEL;Ιστορικό +HISTORY_MSG_1;Φορτώθηκε εικόνα +HISTORY_MSG_2;Φορτώθηκε προφίλ +HISTORY_MSG_3;Αλλαγή προφίλ +HISTORY_MSG_4;Αναζήτηση ιστορικού +HISTORY_MSG_5;Φωτεινότητα +HISTORY_MSG_6;Αντίθεση +HISTORY_MSG_7;Μαύρα +HISTORY_MSG_8;Επανόρθωση Έκθεσης +HISTORY_MSG_9;Συμπίεση φωτεινών σημείων +HISTORY_MSG_10;Συμπίεση σκιών +HISTORY_MSG_11;Καμπύλη τονικότητας +HISTORY_MSG_12;Αυτόματη έκθεση +HISTORY_MSG_13;Ψαλιδισμός έκθεσης +HISTORY_MSG_14;Φωτεινότητα Φωτεινότητας +HISTORY_MSG_15;Φωτεινότητα αντίθεσης +HISTORY_MSG_16;Φωτεινότητα μαύρων +HISTORY_MSG_17;Φωτεινότητα συμπίεσησ φωτεινών σημείων. +HISTORY_MSG_18;Φωτεινότητα συμπίεσης σκιών. +HISTORY_MSG_19;Καμπύλη φωτεινότητας +HISTORY_MSG_20;Όξυνση +HISTORY_MSG_21;Ακτίνα όξυνσης +HISTORY_MSG_22;Ένταση όξυνσης +HISTORY_MSG_23;Κατώφλι όξυνσης +HISTORY_MSG_24;Όξυνση μόνο ορίων +HISTORY_MSG_25;Ακτίνα ανίχνευσης ορίων όξυνσης +HISTORY_MSG_26;Όξυνση, Ανοχή ορίων +HISTORY_MSG_27;Όξυνση, Έλεγχος άλως +HISTORY_MSG_28;Ένταση ελέγχου άλως +HISTORY_MSG_29;Μέθοδοςν όξυνσης +HISTORY_MSG_30;Ακτίνα Deconvolution +HISTORY_MSG_31;Ένταση Deconvolution +HISTORY_MSG_32;Καταστολή Deconvolution +HISTORY_MSG_33;Επαναλήψεις Deconvolution +HISTORY_MSG_34;Αποφυγή ψαλιδίσματος χρώματος +HISTORY_MSG_35;Περιοσμός κορεσμού +HISTORY_MSG_36;Ένταση περιοσμού κορεσμού +HISTORY_MSG_37;Ενίσχυση χρώματος +HISTORY_MSG_38;Μέθοδος εξισορρόπησης λευκού +HISTORY_MSG_39;Θερμοκρασία χρώματος +HISTORY_MSG_40;Απόχρωση εξισορρόπησης λευκού +HISTORY_MSG_41;Χρωματική μετατόπιση "A" +HISTORY_MSG_42;Χρωματική μετατόπιση "B" +HISTORY_MSG_43;Αποθορύβηση φωτεινότητας +HISTORY_MSG_44;Ακτίνα αποθορύβησης φωτεινότητας +HISTORY_MSG_45;Ανοχή ορίων αποθορύβησης φωτεινότητας +HISTORY_MSG_46;Αποθορύβηση χρώματος +HISTORY_MSG_47;Ακτίνα αποθορύβησης χρώματος +HISTORY_MSG_48;Ανοχή ορίων αποθορύβησης χρώματος +HISTORY_MSG_49;Αποθορύβηση χρώματος (ευαισθησία ορίων) +HISTORY_MSG_50;Εργαλείο σκιών/φωτεινών σημείων +HISTORY_MSG_51;Μείωση φωτεινών σημείων +HISTORY_MSG_52;Ενίσχυση σκιών +HISTORY_MSG_53;Τονικό εύρος φωτεινών σημείων +HISTORY_MSG_54;Τονικό εύρος σκιών +HISTORY_MSG_55;Τοπική αντίθεση +HISTORY_MSG_56;Ακτίνα σκιών/φωτεινών σημείων +HISTORY_MSG_57;Coarse Rotation +HISTORY_MSG_58;Οριζόντια ανατροπή +HISTORY_MSG_59;Κατακόρυφη ανατροπή +HISTORY_MSG_60;Περιστροφή +HISTORY_MSG_61;Περιστροφή +HISTORY_MSG_62;Διόρθωση παραμόρφωσης φακού +HISTORY_MSG_63;Επιλέχθηκε στιγμιότυπο +HISTORY_MSG_64;Αποκοπή εικόνας +HISTORY_MSG_65;C/A Διόρθωση +HISTORY_MSG_66;Ανάκτηση Φωτεινών σημείων +HISTORY_MSG_67;Ένταση ανάκτησης φωτεινών σημείων +HISTORY_MSG_68;Μέθοδος ανάκτηση φωτεινών σημείων +HISTORY_MSG_69;Παρόν χρωματικό προφίλ +HISTORY_MSG_70;Χρωματικό προφίλ εξόδου +HISTORY_MSG_71;Χρωματικό προφίλ εισόδου +HISTORY_MSG_72;Διόρθωση Vignetting +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_79;Resize width +HISTORY_MSG_80;Resize height +HISTORY_MSG_81;Resize enabled +HISTORY_NEWSNAPSHOT;Νέο στιγμιότυπο +HISTORY_SNAPSHOTS;Στιγμιότυπα +HISTORY_SNAPSHOT;Στιγμιότυπο +IPTCPANEL_AUTHORSPOSITIONHINT;Τίτλος που αποδίδεται από τον/τους δημιουργό/γους (Ανα γραμμή τίτλος). +IPTCPANEL_AUTHORSPOSITION;Θέση δημιουργού +IPTCPANEL_AUTHOR;Συγγραφέας +IPTCPANEL_CAPTIONHINT;Μια λεκτική περιγραφή των στοιχείων (Λεζάντα - Περίληψη). +IPTCPANEL_CAPTIONWRITERHINT;Το όνομα του προσώπου που ασχολήθηκε με την συγγραφή, επεξεργασία ή διόρθωση της εικόνας ή λεζάντας/περίληψης (Συγγραφέας - Επιμελητής). +IPTCPANEL_CAPTIONWRITER;Συγγραφέας λεζάντας +IPTCPANEL_CAPTION;Λεζάντα +IPTCPANEL_CATEGORYHINT;Ταυτοποιεί το θέμα της εικόνας βάση της άποψης του παροχέα (Κατηγορία). +IPTCPANEL_CATEGORY;Κατηγορία +IPTCPANEL_CITYHINT;Πόλη προέλευσης εικόνας (Πόλη). +IPTCPANEL_CITY;Πόλη +IPTCPANEL_COPYHINT;Αντιγραφή ρυθμίσεων IPTC στην περιοχή αποκομμάτων +IPTCPANEL_COPYRIGHTHINT;Όποιο απαραίτητο σχόλιο περι πνευματικής ιδιοκτησίας (Σχόλια περι πνευματική ιδιοκτησία). +IPTCPANEL_COPYRIGHT;Πνευματική ιδιοκτησία +IPTCPANEL_COUNTRYHINT;Χώρα/αρχική τοποθεσία δημιουργίας εικόνας (Χώρα/αρχική τοποθεσία). +IPTCPANEL_COUNTRY;Χώρα +IPTCPANEL_CREDITHINT;Ταυτοποιεί τον παροχέα της εικόνας, όχι απραίτητα δημιουργό/ιδιοκτήτη (Εύσημα). +IPTCPANEL_CREDIT;Εύσημα +IPTCPANEL_DATECREATEDHINT;Η ημερομηνία δημιουργίας του πνευματικού περιεχομένου; Τύπος: JJJJMMTT (Ημερομηνία δημιουργίας). +IPTCPANEL_DATECREATED;Ημερομηνία δημιουργίας +IPTCPANEL_EMBEDDEDHINT;Επαναφορά στοιχείων IPTC αρχείου εικόνας +IPTCPANEL_EMBEDDED;Ενσωματωμένο +IPTCPANEL_HEADLINEHINT;Ένας δημοσιεύσιμος τίτλος που παρέχει μια σύνοψη των περιεχομένων της εικόνας (Επικεφαλίδα). +IPTCPANEL_HEADLINE;Επικεφαλίδα +IPTCPANEL_INSTRUCTIONSHINT;Άλλες οδηγίες επιμέλειας που αφορούν την χρήση της εικόνας (Ειδικίες οδηγίες). +IPTCPANEL_INSTRUCTIONS;Οδηγίες +IPTCPANEL_KEYWORDSHINT;Χρησιμοποιούνται ενδεικτικά ως λέξεις ανάκτησης(Λέξεις-κλειδιά). +IPTCPANEL_KEYWORDS;Λέξεις-κλειδιά +IPTCPANEL_PASTEHINT;Επικόλληση ρυθμίσεων IPTC από την περιοχή αποκομμάτων +IPTCPANEL_PROVINCEHINT;Επαρχία/Πολιτεία/Νομός προέλευσης της εικόνας (Επαρχία/Πολιτεία/Νομός). +IPTCPANEL_PROVINCE;Επαρχία +IPTCPANEL_RESETHINT;Επαναφορά προεπιλεγμένου προφίλ +IPTCPANEL_RESET;Επαναφορά +IPTCPANEL_SOURCEHINT;Αυθεντικός ιδιοκτήτης πνευματικού περιεχομένου της εικόνας (Πηγή). +IPTCPANEL_SOURCE;Πηγή +IPTCPANEL_SUPPCATEGORIESHINT;Προσδιορίζουν επιπλέον το θέμα της εικόνας (Συμπληρωματικές κατηγορίες). +IPTCPANEL_SUPPCATEGORIES;Συμπληρ. Κατηγορίες +IPTCPANEL_TITLEHINT;Μια σύντομη αναφορά για την εικόνα (Όνομα αντικειμένου). +IPTCPANEL_TITLE;Τίτλος +IPTCPANEL_TRANSREFERENCEHINT;Ένας κωδικός που αντιπροσωπέυει την τοποθεσία αυθεντικής μετάδοσης (Κωδικός Αυθεντικής Μετάδοσης). +IPTCPANEL_TRANSREFERENCE;Κωδικός αυθεντικής μετάδοσης +MAIN_BUTTON_PREFERENCES;Ρυθμίσεις +MAIN_BUTTON_SAVE;Αποθήκευση εικόνας +MAIN_BUTTON_SENDTOEDITOR;Send to editor +MAIN_FRAME_BATCHQUEUE;Batch Queue +MAIN_FRAME_FILEBROWSER;File Browser +MAIN_FRAME_PLACES;Places +MAIN_FRAME_PLACES_ADD;Add +MAIN_FRAME_PLACES_DEL;Del +MAIN_FRAME_RECENT;Recent Folders +MAIN_MSG_ALREADYEXISTS;Το αρχείο ήδη υπάρχει. +MAIN_MSG_CANNOTLOAD;Αδύνατη η φόρτωση εικόνας +MAIN_MSG_CANNOTSAVE;Αδύνατη η αποθήκευση αρχείου +MAIN_MSG_CANNOTSTARTEDITOR;Can not start editor. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Please set the correct path in the "Preferences" dialog. +MAIN_MSG_QOVERWRITE;Θέλετε να το αντικαταστήσετε; +MAIN_TAB_COLOR;Color +MAIN_TAB_DETAIL;Detail +MAIN_TAB_DEVELOP;Develop +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;Exposure +MAIN_TAB_FILTER;Filter +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadata +MAIN_TAB_TRANSFORM;Μετατροπή +MAIN_TOOLTIP_HIDEHP;Προβολή/απόκρυψη αριστερού πλαισίου (περιλαμβανομένου του ιστορικού, shortcut key: H) +MAIN_TOOLTIP_INDCLIPPEDH;Ένδειξη ψαλισμού φωτεινών σημείων +MAIN_TOOLTIP_INDCLIPPEDS;Ένδειξη ψαλισμού σκιών +MAIN_TOOLTIP_QINFO;Γρήγορες πληροφορίες στην εικόνα +PARTIALPASTE_BASICGROUP;Basic settings +PARTIALPASTE_CACORRECTION;C/A correction +PARTIALPASTE_COARSETRANS;90 deg rotation / flipping +PARTIALPASTE_COLORGROUP;Color related settings +PARTIALPASTE_COMPOSITIONGROUP;Composition settings +PARTIALPASTE_CROP;Crop +PARTIALPASTE_DIALOGLABEL;Partial paste processing profile +PARTIALPASTE_DISTORTION;Distortion correction +PARTIALPASTE_EXIFCHANGES;Changes to exif data +PARTIALPASTE_EXPOSURE;Exposure +PARTIALPASTE_ICMSETTINGS;ICM settings +PARTIALPASTE_IPTCINFO;IPTC info +PARTIALPASTE_LENSGROUP;Lens related settings +PARTIALPASTE_METAGROUP;Metadata +PARTIALPASTE_RESIZE;Resize +PARTIALPASTE_ROTATION;Rotation +PARTIALPASTE_SHADOWSHIGHLIGHTS;Shadows/Highlights +PARTIALPASTE_SHARPENING;Sharpening +PARTIALPASTE_VIGNETTING;Vignetting correction +PARTIALPASTE_WHITEBALANCE;White balance +PREFERENCES_APPLNEXTSTARTUP;εφαρμόζεται στην επόμενη εκκίνηση +PREFERENCES_CACHECLEARALL;Clear All +PREFERENCES_CACHECLEARPROFILES;Clear Profiles +PREFERENCES_CACHECLEARTHUMBS;Clear Thumbnails +PREFERENCES_CACHEMAXENTRIES;Maximal Number of Cache Entries +PREFERENCES_CACHEOPTS;Cache Options +PREFERENCES_CACHETHUMBHEIGHT;Maximal Thumbnail Height +PREFERENCES_CLIPPINGIND;Ένδειξη ψαλιδίσματος +PREFERENCES_CMETRICINTENT;Colorimetric Intent +PREFERENCES_DATEFORMATHINT;YΜπορείτε να χρησιμοποιήσετε τις εξής εντολές μορφοποίησης:\n%y : χρονολογία\n%m : μήνας\n%d : ημέρα\n\nΓια παράδειγμα, η μορφοποίηση ημερομηνίας στην Ελλάδα είναι:\n%y/%m/%d +PREFERENCES_DATEFORMAT;Διάταξη ημερομηνίας +PREFERENCES_DEFAULTLANG;Προεπιλεγμένη γλώσσα +PREFERENCES_DEFAULTTHEME;Προεπιλεγμένο θέμα +PREFERENCES_DIRHOME;Τοποθεσία "Home" +PREFERENCES_DIRLAST;Τελευταία τοποθεσία που χρησιμοποιήθηκε +PREFERENCES_DIROTHER;Άλλο +PREFERENCES_DIRSELECTDLG;Επιλέξτε τοποθεσία εικόνων κατά την έναρξη... +PREFERENCES_DIRSOFTWARE;Τοποθεσία εγκατάστασης +PREFERENCES_EDITORCMDLINE;Other command line +PREFERENCES_EXTERNALEDITOR;External editor +PREFERENCES_FBROWSEROPTS;Επιλογές περιήγησης αρχείων +PREFERENCES_FILEFORMAT;Είδος αρχείου +PREFERENCES_FORIMAGE;Για αρχεία εικόνων +PREFERENCES_FORRAW;Για αρχεία RAW +PREFERENCES_GIMPPATH;GIMP installation directory +PREFERENCES_HLTHRESHOLD;Κατώφλι ψαλιδίσματος φωτεινών σημείων +PREFERENCES_ICCDIR;Τοποθεσία των προφίλ ICC +PREFERENCES_IMPROCPARAMS;Προεπιλεγμένες παραμέτροι επεξεργασίας εικόνας +PREFERENCES_INTENT_ABSOLUTE;Absolute Colorimetric +PREFERENCES_INTENT_PERCEPTUAL;Perceptual +PREFERENCES_INTENT_RELATIVE;Relative Colorimetric +PREFERENCES_INTENT_SATURATION;Saturation +PREFERENCES_MONITORICC;Προφίλ οθόνης +PREFERENCES_OUTDIRFOLDERHINT;Put the saved images to the seledted folder +PREFERENCES_OUTDIRFOLDER;Save to folder +PREFERENCES_OUTDIRTEMPLATEHINT;You can use the following formatting strings:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nThese formatting strings refer to the directories and sub-paths of the path of the raw file.\n\nFor example, if /home/tom/image/02-09-2006/dsc0012.nefhas been opened, the meaning of the formatting strings are:\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\nIf you want to save the output image where the original is, write:\n%p1/%f\n\nIf you want to save the output image in a directory 'converted' located the directory of the original, write:\n%p1/converted/%f\n\nIf you want to save the output image in directory '/home/tom/converted' with keeping the same subdirectory of dates, write:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Use Template +PREFERENCES_OUTDIR;Τοποθεσία εξόδου +PREFERENCES_PARSEDEXTADDHINT;Type an extension and press this button to append list +PREFERENCES_PARSEDEXTADD;Add Extension +PREFERENCES_PARSEDEXTDELHINT;Delete selected extension from the list +PREFERENCES_PARSEDEXT;Parsed Extensions +PREFERENCES_PROFILEHANDLING;Processing Profile Handling +PREFERENCES_PROFILELOADPR;Profile Loading Priority +PREFERENCES_PROFILEPRCACHE;Profile in Cache +PREFERENCES_PROFILEPRFILE;Profile Next to the Input File +PREFERENCES_PROFILESAVECACHE;Save Processing Parameters to the Cache +PREFERENCES_PROFILESAVEINPUT;Save Processing Parameters Next to the Input File +PREFERENCES_PSPATH;Adobe Photoshop installation directory +PREFERENCES_SELECTLANG;Επιλογή γλώσσας +PREFERENCES_SELECTTHEME;Επιλογή θέματος +PREFERENCES_SHOWBASICEXIF;Προβολή βασικών στοιχείων Exif +PREFERENCES_SHOWDATETIME;Προβολή ημερομηνίας και ώρας +PREFERENCES_SHTHRESHOLD;Κατώφλι ψαλιδίσματος σκιών +PREFERENCES_STARTUPIMDIR;Τοποθεσία εικόνων κατά την έναρξη +PREFERENCES_TAB_BROWSER;Περιήγηση αρχείου +PREFERENCES_TAB_COLORMGR;Διαχείριση χρώματος +PREFERENCES_TAB_GENERAL;Γενικά +PREFERENCES_TAB_IMPROC;Επεξεργασίας εικόνας +PROFILEPANEL_LABEL;Προφίλ επεξεργασίας +PROFILEPANEL_LOADDLGLABEL;Φόρτωση παραμέτρων επεξεργασίας... +PROFILEPANEL_PCUSTOM;Προσαρμοσμένο +PROFILEPANEL_PFILE;Απο αρχείο +PROFILEPANEL_PLASTSAVED;Τελευταία αποθηκευμένη +PROFILEPANEL_SAVEDLGLABEL;Αποθήκευση παραμέτρων επεξεργασίας... +PROFILEPANEL_TOOLTIPCOPY;Copy current profile to clipboard +PROFILEPANEL_TOOLTIPLOAD;Φόρτωση προφίλ απο αρχείο +PROFILEPANEL_TOOLTIPPASTE; Paste profile from clipboard +PROFILEPANEL_TOOLTIPSAVE;Αποθήκευση παρόντος προφίλ +PROGRESSBAR_LOADING;Φόρτωση εικόνας... +PROGRESSBAR_LOADJPEG;Φόρτωση αρχείου JPEG... +PROGRESSBAR_LOADPNG;Φόρτωση αρχείου PNG... +PROGRESSBAR_LOADTIFF;Φόρτωση αρχείου TIFF... +PROGRESSBAR_PROCESSING;Επεξεργάζεται εικόνα... +PROGRESSBAR_READY;Έτοιμο +PROGRESSBAR_SAVEJPEG;Αποθήκευση αρχείου JPEG... +PROGRESSBAR_SAVEPNG;Αποθήκευση αρχείου PNG... +PROGRESSBAR_SAVETIFF;Αποθήκευση αρχείου TIFF... +QINFO_ISO;ISO +QINFO_NOEXIF;Στοιχεία Exif μη διαθέσιμα. +SAVEDLG_FILEFORMAT;Είδος αρχείου +SAVEDLG_JPEGQUAL;Ποιότητα JPEG +SAVEDLG_PNGCOMPR;Συμπίεση PNG +SAVEDLG_PUTTOQUEUEHEAD;Put to the head of the processing queue +SAVEDLG_PUTTOQUEUETAIL;Put to the end of the processing queue +SAVEDLG_PUTTOQUEUE;Put into processing queue +SAVEDLG_SAVEIMMEDIATELY;Save immediately +SAVEDLG_SAVESPP;Αποθήκευση παραμέτρων επεξεργασίας μαζί με την εικόνα +TOOLBAR_TOOLTIP_CROP;Αποκοπή επιλογής (shortcut key: C) +TOOLBAR_TOOLTIP_HAND;Εργαλείο μετακίνησης (shortcut key: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;Επιλογή ευθείας γραμμής (shortcut key: S) +TOOLBAR_TOOLTIP_WB;Εξισορροπία λευκού από σημείο (shortcut key: W) +TP_CACORRECTION_BLUE;Μπλέ +TP_CACORRECTION_LABEL;C/A Διόρθωση +TP_CACORRECTION_RED;Κόκκινο +TP_CHMIXER_BLUE;Μπλέ +TP_CHMIXER_GREEN;Πράσινο +TP_CHMIXER_LABEL;Μίξη καναλιών +TP_CHMIXER_RED;Κόκκινο +TP_COARSETRAF_TOOLTIP_HFLIP;Αναστροφή οριζόντια +TP_COARSETRAF_TOOLTIP_ROTLEFT;Περιστροφή αριστερά +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Περιστροφή δεξιά +TP_COARSETRAF_TOOLTIP_VFLIP;Αναστροφή κατακόρυφα +TP_CROP_FIXRATIO;Κλείδωμα αναλογίας: +TP_CROP_GTDIAGONALS;Κανόνας διαγωνίων +TP_CROP_GTNONE;Κανένα +TP_CROP_GTRULETHIRDS;Κανόνας τρίτων +TP_CROP_GUIDETYPE;Είδος βοηθών: +TP_CROP_H;H +TP_CROP_LABEL;Αποκοπή +TP_CROP_SELECTCROP; Επιλογή αποκοπής +TP_CROP_W;W +TP_CROP_X;x +TP_CROP_Y;y +TP_DISTORTION_AMOUNT;Ένταση +TP_DISTORTION_LABEL;Παραμόρφωση +TP_EXPOSURE_AUTOLEVELS;Αυτόματα επίπεδα +TP_EXPOSURE_BLACKLEVEL;Μαύρα +TP_EXPOSURE_BRIGHTNESS;Φωτεινότητα +TP_EXPOSURE_CLIP;Αποκοπή +TP_EXPOSURE_COMPRHIGHLIGHTS;Συμπίεση φωτεινών σημείων +TP_EXPOSURE_COMPRSHADOWS;Συμπίεση σκιών +TP_EXPOSURE_CONTRAST;Αντίθεση +TP_EXPOSURE_CURVEEDITOR;Καμπύλη τονικότητας +TP_EXPOSURE_EXPCOMP;Επανόρθωση Έκθεσης +TP_EXPOSURE_LABEL;Έκθεση +TP_HLREC_CIELAB;Ανάμιξη CIELab +TP_HLREC_COLOR;Διάδοση χρώματος +TP_HLREC_LABEL;Ανάκτηση φωτεινών σημείων +TP_HLREC_LUMINANCE;Ανάκτηση Φωτεινότητας +TP_HLREC_METHOD;Μέθοδος: +TP_ICM_INPUTCAMERA;Προεπιλογή φωτογραφικής μηχανής +TP_ICM_INPUTCUSTOM;Προσαρμοσμένο +TP_ICM_INPUTDLGLABEL;Επιλέξτε προφιλ ICC εισόδου... +TP_ICM_INPUTEMBEDDED;Χρήση ενσωματωμένου, αν αυτό είναι δυνατό +TP_ICM_INPUTPROFILE;Προφίλ εισαγωγής +TP_ICM_LABEL;ICM +TP_ICM_NOICM;No ICM: sRGB output +TP_ICM_OUTPUTPROFILE;Προφίλ εξόδου +TP_ICM_SAVEREFERENCE;Αποθήκευση εικόνας ως αναφορά για δημιουργία προφίλ. +TP_ICM_WORKINGPROFILE;Παρόν προφίλ +TP_RAW_DMETHOD;Μέθοδος +TP_RAW_FALSECOLOR;Βήματα καταστολής σφαλμένων χρωμάτων +TP_RESIZE_H;H: +TP_RESIZE_LABEL;Αλλαγή μεγέθους +TP_RESIZE_METHOD;Μέθοδος: +TP_RESIZE_NEAREST;Nearest +TP_RESIZE_SCALE;Κλίμακα +TP_RESIZE_W;W: +TP_ROTATE_DEGREE;Γωνία +TP_ROTATE_LABEL;Περιστροφή +TP_ROTATE_SELECTLINE; Επιλογή ευθείας +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Φωτεινά σημεία +TP_SHADOWSHLIGHTS_HLTONALW;Τονικό εύρος +TP_SHADOWSHLIGHTS_LABEL;Σκιές/Φωτεινά σημεία +TP_SHADOWSHLIGHTS_LOCALCONTR;Τοπική αντίθεση +TP_SHADOWSHLIGHTS_RADIUS;Ακτίνα +TP_SHADOWSHLIGHTS_SHADOWS;Σκιές +TP_SHADOWSHLIGHTS_SHTONALW;Τονικό εύρος +TP_SHARPENING_AMOUNT;Ένταση +TP_SHARPENING_EDRADIUS;Ακτίνα +TP_SHARPENING_EDTOLERANCE;Ανοχή ορίων +TP_SHARPENING_HALOCONTROL;Έλεγχος άλως +TP_SHARPENING_HCAMOUNT;Ένταση +TP_SHARPENING_LABEL;Όξυνση +TP_SHARPENING_METHOD;Μέθοδος +TP_SHARPENING_ONLYEDGES;Όξυνση μόνο ορίων +TP_SHARPENING_RADIUS;Ακτίνα +TP_SHARPENING_RLD;RL Deconvolution +TP_SHARPENING_RLD_AMOUNT;Ένταση +TP_SHARPENING_RLD_DAMPING;Απόσβεση +TP_SHARPENING_RLD_ITERATIONS;Επαναλήψεις +TP_SHARPENING_THRESHOLD;Κατώφλι +TP_SHARPENING_USM;Unsharp Mask +TP_VIGNETTING_AMOUNT;Ένταση +TP_VIGNETTING_LABEL;Διόρθωση vignetting +TP_VIGNETTING_RADIUS;Ακτίνα +TP_WBALANCE_AUTO;Αυτόματο +TP_WBALANCE_CAMERA;Φωτογραφικής μηχανής +TP_WBALANCE_CUSTOM;Προσαρμοσμένο +TP_WBALANCE_GREEN;Απόχρωση +TP_WBALANCE_LABEL;Εξισορρόπηση λευκού +TP_WBALANCE_METHOD;Μέθοδος +TP_WBALANCE_SIZE;Μέγεθος: +TP_WBALANCE_SPOTWB;Εξ.Λ. σημείου +TP_WBALANCE_TEMPERATURE;Θερμοκρασία + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!ABOUT_TAB_BUILD;Version +!ABOUT_TAB_CREDITS;Credits +!ABOUT_TAB_LICENSE;License +!ABOUT_TAB_RELEASENOTES;Release Notes +!ABOUT_TAB_SPLASH;Splash +!BATCHQUEUE_AUTOSTART;Auto-start +!BATCHQUEUE_DESTFILENAME;Path and file name +!BATCH_PROCESSING;Batch Processing +!CURVEEDITOR_AXIS_IN;I: +!CURVEEDITOR_AXIS_LEFT_TAN;LT: +!CURVEEDITOR_AXIS_OUT;O: +!CURVEEDITOR_AXIS_RIGHT_TAN;RT: +!CURVEEDITOR_CURVES;Curves +!CURVEEDITOR_CURVE;Curve +!CURVEEDITOR_CUSTOM;Custom +!CURVEEDITOR_DARKS;Darks +!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_HIGHLIGHTS;Highlights +!CURVEEDITOR_LIGHTS;Lights +!CURVEEDITOR_MINMAXCPOINTS;Equalizer +!CURVEEDITOR_NURBS;Control cage +!CURVEEDITOR_PARAMETRIC;Parametric +!CURVEEDITOR_SHADOWS;Shadows +!CURVEEDITOR_TOOLTIPCOPY;Copy current curve to clipboard. +!CURVEEDITOR_TOOLTIPPASTE;Paste curve from clipboard. +!CURVEEDITOR_TYPE;Type: +!EDITWINDOW_TITLE;Image Edit +!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_FILETYPE;File type +!EXIFFILTER_METADATAFILTER;Enable metadata filters +!EXPORT_BYPASS_ALL;Select / Unselect All +!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_FF;Bypass [raw] Flat-Field +!EXPORT_BYPASS_RAW_GREENTHRESH;Bypass [raw] Green Equilibration +!EXPORT_BYPASS_RAW_LINENOISE;Bypass [raw] Line Noise Filter +!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_FASTEXPORTOPTIONS;Fast Export Options +!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_MAXHEIGHT;Maximum height: +!EXPORT_MAXWIDTH;Maximum width: +!EXPORT_PUTTOQUEUEFAST; Put to queue for fast export +!EXPORT_RAW_DMETHOD;Demosaic method +!EXTPROGTARGET_1;raw +!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_CACHECLEARFROMFULL;Clear from cache - full +!FILEBROWSER_CACHECLEARFROMPARTIAL;Clear from cache - partial +!FILEBROWSER_CACHE;Cache +!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_CURRENT_NAME;Current name: +!FILEBROWSER_DARKFRAME;Dark-frame +!FILEBROWSER_DELETEDLGMSGINCLPROC;Are you sure you want to delete the selected %1 files including a queue-processed version? +!FILEBROWSER_EXEC_CPB;Custom Profile Builder +!FILEBROWSER_EXTPROGMENU;Open with +!FILEBROWSER_FLATFIELD;Flat-Field +!FILEBROWSER_MOVETODARKFDIR;Move to dark-frames directory +!FILEBROWSER_MOVETOFLATFIELDDIR;Move to flat-fields directory +!FILEBROWSER_NEW_NAME;New name: +!FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) +!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_POPUPCOLORLABEL;Color label +!FILEBROWSER_POPUPCOPYTO;Copy to... +!FILEBROWSER_POPUPFILEOPERATIONS;File operations +!FILEBROWSER_POPUPMOVETO;Move to... +!FILEBROWSER_POPUPPROCESSFAST;Put to queue (Fast export) +!FILEBROWSER_POPUPPROFILEOPERATIONS;Processing profile operations +!FILEBROWSER_POPUPRANK0;Unrank +!FILEBROWSER_POPUPRANK1;Rank 1 * +!FILEBROWSER_POPUPRANK2;Rank 2 ** +!FILEBROWSER_POPUPRANK3;Rank 3 *** +!FILEBROWSER_POPUPRANK4;Rank 4 **** +!FILEBROWSER_POPUPRANK5;Rank 5 ***** +!FILEBROWSER_POPUPRANK;Rank +!FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!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_QUERYLABEL; Find: +!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_SELECTDARKFRAME;Select dark-frame... +!FILEBROWSER_SELECTFLATFIELD;Select flat-field... +!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 +!FILEBROWSER_SHOWCOLORLABEL4HINT;Show images labeled Blue.\nShortcut: Alt-4 +!FILEBROWSER_SHOWCOLORLABEL5HINT;Show images labeled Purple.\nShortcut: Alt-5 +!FILEBROWSER_SHOWEDITEDHINT;Show edited images.\nShortcut: 7 +!FILEBROWSER_SHOWEDITEDNOTHINT;Show not edited images.\nShortcut: 6 +!FILEBROWSER_SHOWEXIFINFO;Show Exif info.\n\nShortcuts:\ni - Multiple Editor Tabs Mode,\nAlt-i - Single Editor Tab Mode. +!FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!FILEBROWSER_SHOWRECENTLYSAVEDHINT;Show saved images.\nShortcut: Alt-7 +!FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show unsaved images.\nShortcut: Alt-6 +!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_AFTER;After +!GENERAL_ASIMAGE;As Image +!GENERAL_AUTO;Automatic +!GENERAL_BEFORE;Before +!GENERAL_CLOSE;Close +!GENERAL_FILE;File +!GENERAL_NONE;None +!GENERAL_UNCHANGED;(Unchanged) +!GENERAL_WARNING;Warning +!HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar.\nRight-click on image preview to freeze/unfreeze. +!HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram. +!HISTOGRAM_TOOLTIP_FULL;Toggle full (off) or scaled (on) histogram. +!HISTOGRAM_TOOLTIP_RAW;Show/Hide raw histogram. +!HISTORY_MSG_82;Profile changed +!HISTORY_MSG_83;S/H - Sharp mask +!HISTORY_MSG_84;Perspective correction +!HISTORY_MSG_85;LCP +!HISTORY_MSG_86;RGB curves - Luminosity mode +!HISTORY_MSG_87;Impulse noise reduction +!HISTORY_MSG_88;Impulse NR threshold +!HISTORY_MSG_89;Noise Reduction +!HISTORY_MSG_90;NR - Luminance +!HISTORY_MSG_91;NR - Chrominance master +!HISTORY_MSG_92;NR - Gamma +!HISTORY_MSG_93;CbDL - Value +!HISTORY_MSG_94;Contrast by Detail Levels +!HISTORY_MSG_95;L*a*b* - Chromaticity +!HISTORY_MSG_96;L*a*b* - a* curve +!HISTORY_MSG_97;L*a*b* - b* curve +!HISTORY_MSG_98;Demosaicing method +!HISTORY_MSG_99;Hot pixel filter +!HISTORY_MSG_100;RGB Saturation +!HISTORY_MSG_101;HSV - Hue +!HISTORY_MSG_102;HSV - Saturation +!HISTORY_MSG_103;HSV - Value +!HISTORY_MSG_104;HSV Equalizer +!HISTORY_MSG_105;Defringe +!HISTORY_MSG_106;Defringe - Radius +!HISTORY_MSG_107;Defringe - Threshold +!HISTORY_MSG_108;Highlight Compr. Threshold +!HISTORY_MSG_109;Resize - Bounding box +!HISTORY_MSG_110;Resize - Applies to +!HISTORY_MSG_111;L*a*b* - Avoid color shift +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;L*a*b* - Red/skin prot. +!HISTORY_MSG_114;DCB iterations +!HISTORY_MSG_115;False color suppression +!HISTORY_MSG_116;DCB enhancement +!HISTORY_MSG_117;Raw CA correction - Red +!HISTORY_MSG_118;Raw CA correction - Blue +!HISTORY_MSG_119;Line noise filter +!HISTORY_MSG_120;Green equilibration +!HISTORY_MSG_121;Raw CA Correction - Auto +!HISTORY_MSG_122;Dark-Frame - Auto-selection +!HISTORY_MSG_123;Dark-Frame - File +!HISTORY_MSG_124;White point correction +!HISTORY_MSG_125;Highlight preservation +!HISTORY_MSG_126;Flat-Field - File +!HISTORY_MSG_127;Flat-Field - Auto-selection +!HISTORY_MSG_128;Flat-Field - Blur radius +!HISTORY_MSG_129;Flat-Field - Blur type +!HISTORY_MSG_130;Auto distorion correction +!HISTORY_MSG_131;NR - Luma +!HISTORY_MSG_132;NR - Chroma +!HISTORY_MSG_133;Output gamma +!HISTORY_MSG_134;Free gamma +!HISTORY_MSG_135;Free gamma +!HISTORY_MSG_136;Free gamma slope +!HISTORY_MSG_137;Black level - Green 1 +!HISTORY_MSG_138;Black level - Red +!HISTORY_MSG_139;Black level - Blue +!HISTORY_MSG_140;Black level - Green 2 +!HISTORY_MSG_141;Black level - Link greens +!HISTORY_MSG_142;ES - Iterations +!HISTORY_MSG_143;ES - Quantity +!HISTORY_MSG_144;Microcontrast - Quantity +!HISTORY_MSG_145;Microcontrast - Uniformity +!HISTORY_MSG_146;Edge sharpening +!HISTORY_MSG_147;ES - Luminance only +!HISTORY_MSG_148;Microcontrast +!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_150;Post-demosaic artifact/noise red. +!HISTORY_MSG_151;Vibrance +!HISTORY_MSG_152;Vib - Pastel tones +!HISTORY_MSG_153;Vib - Saturated tones +!HISTORY_MSG_154;Vib - Protect skin-tones +!HISTORY_MSG_155;Vib - Avoid color shift +!HISTORY_MSG_156;Vib - Link pastel/saturated +!HISTORY_MSG_157;Vib - P/S threshold +!HISTORY_MSG_158;TM - Strength +!HISTORY_MSG_159;TM - Edge stopping +!HISTORY_MSG_160;TM - Scale +!HISTORY_MSG_161;TM - Reweighting iterates +!HISTORY_MSG_162;Tone Mapping +!HISTORY_MSG_163;RGB curves - Red +!HISTORY_MSG_164;RGB curves - Green +!HISTORY_MSG_165;RGB curves - Blue +!HISTORY_MSG_166;Neutral levels +!HISTORY_MSG_167;--unused-- +!HISTORY_MSG_168;L*a*b* - CC curve +!HISTORY_MSG_169;L*a*b* - CH curve +!HISTORY_MSG_170;Vibrance - HH curve +!HISTORY_MSG_171;L*a*b* - LC curve +!HISTORY_MSG_172;L*a*b* - Restrict LC +!HISTORY_MSG_173;NR - Luminance detail +!HISTORY_MSG_174;CIECAM02 +!HISTORY_MSG_175;CAM02 - CAT02 adaptation +!HISTORY_MSG_176;CAM02 - Viewing surround +!HISTORY_MSG_177;CAM02 - Scene luminosity +!HISTORY_MSG_178;CAM02 - Viewing luminosity +!HISTORY_MSG_179;CAM02 - White-point model +!HISTORY_MSG_180;CAM02 - Lightness (J) +!HISTORY_MSG_181;CAM02 - Chroma (C) +!HISTORY_MSG_182;CAM02 - Automatic CAT02 +!HISTORY_MSG_183;CAM02 - Contrast (J) +!HISTORY_MSG_184;CAM02 - Scene surround +!HISTORY_MSG_185;CAM02 - Gamut control +!HISTORY_MSG_186;CAM02 - Algorithm +!HISTORY_MSG_187;CAM02 - Red/skin prot. +!HISTORY_MSG_188;CAM02 - Brightness (Q) +!HISTORY_MSG_189;CAM02 - Contrast (Q) +!HISTORY_MSG_190;CAM02 - Saturation (S) +!HISTORY_MSG_191;CAM02 - Colorfulness (M) +!HISTORY_MSG_192;CAM02 - Hue (h) +!HISTORY_MSG_193;CAM02 - Tone curve 1 +!HISTORY_MSG_194;CAM02 - Tone curve 2 +!HISTORY_MSG_195;CAM02 - Tone curve 1 +!HISTORY_MSG_196;CAM02 - Tone curve 2 +!HISTORY_MSG_197;CAM02 - Color curve +!HISTORY_MSG_198;CAM02 - Color curve +!HISTORY_MSG_199;CAM02 - Output histograms +!HISTORY_MSG_200;CAM02 - Tone mapping +!HISTORY_MSG_201;NR - Chrominance - R&G +!HISTORY_MSG_202;NR - Chrominance - B&Y +!HISTORY_MSG_203;NR - Method +!HISTORY_MSG_204;LMMSE enhancement steps +!HISTORY_MSG_205;CAM02 - Hot/bad pixel filter +!HISTORY_MSG_206;CAT02 - Auto scene luminosity +!HISTORY_MSG_207;Defringe - Hue curve +!HISTORY_MSG_208;WB - B/R equalizer +!HISTORY_MSG_210;GF - Angle +!HISTORY_MSG_211;Graduated Filter +!HISTORY_MSG_212;VF - Strength +!HISTORY_MSG_213;Vignette Filter +!HISTORY_MSG_214;Black-and-White +!HISTORY_MSG_215;B&W - CM - Red +!HISTORY_MSG_216;B&W - CM - Green +!HISTORY_MSG_217;B&W - CM - Blue +!HISTORY_MSG_218;B&W - Gamma - Red +!HISTORY_MSG_219;B&W - Gamma - Green +!HISTORY_MSG_220;B&W - Gamma - Blue +!HISTORY_MSG_221;B&W - Color filter +!HISTORY_MSG_222;B&W - Presets +!HISTORY_MSG_223;B&W - CM - Orange +!HISTORY_MSG_224;B&W - CM - Yellow +!HISTORY_MSG_225;B&W - CM - Cyan +!HISTORY_MSG_226;B&W - CM - Magenta +!HISTORY_MSG_227;B&W - CM - Purple +!HISTORY_MSG_228;B&W - Luminance equalizer +!HISTORY_MSG_229;B&W - Luminance equalizer +!HISTORY_MSG_230;B&W - Mode +!HISTORY_MSG_231;B&W - 'Before' curve +!HISTORY_MSG_232;B&W - 'Before' curve type +!HISTORY_MSG_233;B&W - 'After' curve +!HISTORY_MSG_234;B&W - 'After' curve type +!HISTORY_MSG_235;B&W - Auto channel mixer +!HISTORY_MSG_236;--unused-- +!HISTORY_MSG_237;B&W - Mixer +!HISTORY_MSG_238;GF - Feather +!HISTORY_MSG_239;GF - Strength +!HISTORY_MSG_240;GF - Center +!HISTORY_MSG_241;VF - Feather +!HISTORY_MSG_242;VF - Roundness +!HISTORY_MSG_243;VC - Radius +!HISTORY_MSG_244;VC - Strength +!HISTORY_MSG_245;VC - Center +!HISTORY_MSG_246;L*a*b* - CL curve +!HISTORY_MSG_247;L*a*b* - LH curve +!HISTORY_MSG_248;L*a*b* - HH curve +!HISTORY_MSG_249;CbDL - Threshold +!HISTORY_MSG_250;NR - Enhanced +!HISTORY_MSG_251;B&W - Algorithm +!HISTORY_MSG_252;CbDL - Skin tar/prot +!HISTORY_MSG_253;CbDL - Reduce artifacts +!HISTORY_MSG_254;CbDL - Skin hue +!HISTORY_MSG_255;NR - Median filter +!HISTORY_MSG_256;NR - Median type +!HISTORY_MSG_257;Color Toning +!HISTORY_MSG_258;CT - Color curve +!HISTORY_MSG_259;CT - Opacity curve +!HISTORY_MSG_260;CT - a*[b*] opacity +!HISTORY_MSG_261;CT - Method +!HISTORY_MSG_262;CT - b* opacity +!HISTORY_MSG_263;CT - Shadows - Red +!HISTORY_MSG_264;CT - Shadows - Green +!HISTORY_MSG_265;CT - Shadows - Blue +!HISTORY_MSG_266;CT - Mid - Red +!HISTORY_MSG_267;CT - Mid - Green +!HISTORY_MSG_268;CT - Mid - Blue +!HISTORY_MSG_269;CT - High - Red +!HISTORY_MSG_270;CT - High - Green +!HISTORY_MSG_271;CT - High - Blue +!HISTORY_MSG_272;CT - Balance +!HISTORY_MSG_273;CT - Reset +!HISTORY_MSG_274;CT - Sat. Shadows +!HISTORY_MSG_275;CT - Sat. Highlights +!HISTORY_MSG_276;CT - Opacity +!HISTORY_MSG_277;--unused-- +!HISTORY_MSG_278;CT - Preserve luminance +!HISTORY_MSG_279;CT - Shadows +!HISTORY_MSG_280;CT - Highlights +!HISTORY_MSG_281;CT - Sat. strength +!HISTORY_MSG_282;CT - Sat. threshold +!HISTORY_MSG_283;CT - Strength +!HISTORY_MSG_284;CT - Auto sat. protection +!HISTORY_MSG_285;NR - Median - Method +!HISTORY_MSG_286;NR - Median - Type +!HISTORY_MSG_287;NR - Median - Iterations +!HISTORY_MSG_288;Flat Field - Clip control +!HISTORY_MSG_289;Flat Field - Clip control - Auto +!HISTORY_MSG_290;Black Level - Red +!HISTORY_MSG_291;Black Level - Green +!HISTORY_MSG_292;Black Level - Blue +!HISTORY_MSG_293;Film Simulation +!HISTORY_MSG_294;Film Simulation - Strength +!HISTORY_MSG_295;Film Simulation - Film +!HISTORY_MSG_296;NR - Luminance curve +!HISTORY_MSG_297;NR - Quality +!HISTORY_MSG_298;Dead pixel filter +!HISTORY_MSG_299;NR - Chrominance curve +!HISTORY_MSG_300;- +!HISTORY_MSG_301;NR - Luma control +!HISTORY_MSG_302;NR - Chroma method +!HISTORY_MSG_303;NR - Chroma method +!HISTORY_MSG_304;W - Contrast levels +!HISTORY_MSG_305;Wavelet Levels +!HISTORY_MSG_306;W - Preview +!HISTORY_MSG_307;W - Preview +!HISTORY_MSG_308;W - Preview direction +!HISTORY_MSG_309;W - ES - Detail +!HISTORY_MSG_310;W - Residual - Sky tar/prot +!HISTORY_MSG_311;W - Wavelet levels +!HISTORY_MSG_312;W - Residual - Shadows threshold +!HISTORY_MSG_313;W - Chroma - Sat/past +!HISTORY_MSG_314;W - Gamut - Reduce artifacts +!HISTORY_MSG_315;W - Residual - Contrast +!HISTORY_MSG_316;W - Gamut - Skin tar/prot +!HISTORY_MSG_317;W - Gamut - Skin hue +!HISTORY_MSG_318;W - Contrast - Highlight levels +!HISTORY_MSG_319;W - Contrast - Highlight range +!HISTORY_MSG_320;W - Contrast - Shadow range +!HISTORY_MSG_321;W - Contrast - Shadow levels +!HISTORY_MSG_322;W - Gamut - Avoid color shift +!HISTORY_MSG_323;W - ES - Local contrast +!HISTORY_MSG_324;W - Chroma - Pastel +!HISTORY_MSG_325;W - Chroma - Saturated +!HISTORY_MSG_326;W - Chroma - Method +!HISTORY_MSG_327;W - Contrast - Apply to +!HISTORY_MSG_328;W - Chroma - Link strength +!HISTORY_MSG_329;W - Toning - Opacity RG +!HISTORY_MSG_330;W - Toning - Opacity BY +!HISTORY_MSG_331;W - Contrast levels - Extra +!HISTORY_MSG_332;W - Tiling method +!HISTORY_MSG_333;W - Residual - Shadows +!HISTORY_MSG_334;W - Residual - Chroma +!HISTORY_MSG_335;W - Residual - Highlights +!HISTORY_MSG_336;W - Residual - Highlights threshold +!HISTORY_MSG_337;W - Residual - Sky hue +!HISTORY_MSG_338;W - ES - Radius +!HISTORY_MSG_339;W - ES - Strength +!HISTORY_MSG_340;W - Strength +!HISTORY_MSG_341;W - Edge performance +!HISTORY_MSG_342;W - ES - First level +!HISTORY_MSG_343;W - Chroma levels +!HISTORY_MSG_344;W - Meth chroma sl/cur +!HISTORY_MSG_345;W - ES - Local contrast +!HISTORY_MSG_346;W - ES - Local contrast method +!HISTORY_MSG_347;W - Denoise - Level 0 +!HISTORY_MSG_348;W - Denoise - Level 1 +!HISTORY_MSG_349;W - Denoise - Level 2 +!HISTORY_MSG_350;W - ES - Edge detection +!HISTORY_MSG_351;W - Residual - HH curve +!HISTORY_MSG_352;W - Background +!HISTORY_MSG_353;W - ES - Gradient sensitivity +!HISTORY_MSG_354;W - ES - Enhance +!HISTORY_MSG_355;W - ES - Threshold low +!HISTORY_MSG_356;W - ES - Threshold high +!HISTORY_MSG_357;W - Denoise - Link with ES +!HISTORY_MSG_358;W - Gamut - CH +!HISTORY_MSG_359;Hot/Dead - Threshold +!HISTORY_MSG_360;TM Gamma +!HISTORY_MSG_361;W - Final - Chroma balance +!HISTORY_MSG_362;W - Residual - Compression method +!HISTORY_MSG_363;W - Residual - Compression strength +!HISTORY_MSG_364;W - Final - Contrast balance +!HISTORY_MSG_365;W - Final - Delta balance +!HISTORY_MSG_366;W - Residual - Compression gamma +!HISTORY_MSG_367;W - ES - Local contrast curve +!HISTORY_MSG_368;W - Final - Contrast balance +!HISTORY_MSG_369;W - Final - Balance method +!HISTORY_MSG_370;W - Final - Local contrast curve +!HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s +!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 +!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). +!MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Put current image to processing queue.\nShortcut: Ctrl+b +!MAIN_BUTTON_SAVE_TOOLTIP;Save current image.\nShortcut: Ctrl+s +!MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Edit current image in external editor.\nShortcut: Ctrl+e +!MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Show/hide all side panels.\nShortcut: m +!MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen +!MAIN_FRAME_BATCHQUEUE_TOOLTIP;Processing queue.\nShortcut: Ctrl-F3 +!MAIN_FRAME_EDITOR;Editor +!MAIN_FRAME_EDITOR_TOOLTIP;Editor.\nShortcut: Ctrl-F4 +!MAIN_FRAME_FILEBROWSER_TOOLTIP;File browser.\nShortcut: Ctrl-F2 +!MAIN_MSG_EMPTYFILENAME;Filename unspecified! +!MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue-processed first. +!MAIN_MSG_NAVIGATOR;Navigator +!MAIN_MSG_OPERATIONCANCELLED;Operation cancelled +!MAIN_MSG_PATHDOESNTEXIST;The path\n\n%1\n\ndoes not exist. Please set a correct path in Preferences. +!MAIN_MSG_SETPATHFIRST;You first have to set a target path in Preferences in order to use this function! +!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_EXPORT; Fast Export +!MAIN_TAB_EXPOSURE_TOOLTIP;Shortcut: Alt-e +!MAIN_TAB_INSPECT; Inspect +!MAIN_TAB_METADATA_TOOLTIP;Shortcut: Alt-m +!MAIN_TAB_RAW;Raw +!MAIN_TAB_RAW_TOOLTIP;Shortcut: Alt-r +!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_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%. +!MAIN_TOOLTIP_PREVIEWG;Preview the Green channel.\nShortcut: g +!MAIN_TOOLTIP_PREVIEWL;Preview the Luminosity.\nShortcut: v\n\n0.299*R + 0.587*G + 0.114*B +!MAIN_TOOLTIP_PREVIEWR;Preview the Red channel.\nShortcut: r +!MAIN_TOOLTIP_SHOWHIDELP1;Show/Hide the left panel.\nShortcut: l +!MAIN_TOOLTIP_SHOWHIDERP1;Show/Hide the right panel.\nShortcut: Alt-l +!MAIN_TOOLTIP_SHOWHIDETP1;Show/Hide the top panel.\nShortcut: Shift-l +!MAIN_TOOLTIP_THRESHOLD;Threshold +!MAIN_TOOLTIP_TOGGLE;Toggle the Before/After view.\nShortcut: Shift-b +!NAVIGATOR_B;B: +!NAVIGATOR_G;G: +!NAVIGATOR_H;H: +!NAVIGATOR_LAB_A;a*: +!NAVIGATOR_LAB_B;b*: +!NAVIGATOR_LAB_L;L*: +!NAVIGATOR_NA; -- +!NAVIGATOR_R;R: +!NAVIGATOR_S;S: +!NAVIGATOR_V;V: +!NAVIGATOR_XY_FULL;Width: %1, Height: %2 +!NAVIGATOR_XY_NA;x: --, y: -- +!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_CHANNELMIXERBW;Black-and-White +!PARTIALPASTE_CHANNELMIXER;Channel mixer +!PARTIALPASTE_COLORAPP;CIECAM02 +!PARTIALPASTE_COLORTONING;Color Toning +!PARTIALPASTE_COMMONTRANSFORMPARAMS;Auto-fill +!PARTIALPASTE_DARKFRAMEAUTOSELECT;Dark-frame auto-selection +!PARTIALPASTE_DARKFRAMEFILE;Dark-frame file +!PARTIALPASTE_DEFRINGE;Defringe +!PARTIALPASTE_DETAILGROUP;Detail Settings +!PARTIALPASTE_DIRPYRDENOISE;Noise reduction +!PARTIALPASTE_DIRPYREQUALIZER;Contrast by detail levels +!PARTIALPASTE_EPD;Tone mapping +!PARTIALPASTE_EQUALIZER;Wavelet Equalizer +!PARTIALPASTE_EVERYTHING;Everything +!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_GRADIENT;Graduated filter +!PARTIALPASTE_HSVEQUALIZER;HSV equalizer +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction +!PARTIALPASTE_LABCURVE;L*a*b* adjustments +!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_PCVIGNETTE;Vignette filter +!PARTIALPASTE_PERSPECTIVE;Perspective +!PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter +!PARTIALPASTE_PREPROCESS_GREENEQUIL;Green equilibration +!PARTIALPASTE_PREPROCESS_HOTPIXFILT;Hot pixel filter +!PARTIALPASTE_PREPROCESS_LINEDENOISE;Line noise filter +!PARTIALPASTE_RAWCACORR_AUTO;CA auto-correction +!PARTIALPASTE_RAWCACORR_CABLUE;CA blue +!PARTIALPASTE_RAWCACORR_CARED;CA red +!PARTIALPASTE_RAWEXPOS_BLACK;Black levels +!PARTIALPASTE_RAWEXPOS_LINEAR;White point correction +!PARTIALPASTE_RAWEXPOS_PRESER;Highlight preservation +!PARTIALPASTE_RAWGROUP;Raw Settings +!PARTIALPASTE_RAW_DCBENHANCE;DCB enhancement +!PARTIALPASTE_RAW_DCBITERATIONS;Number of DCB iterations +!PARTIALPASTE_RAW_DMETHOD;Demosaic method +!PARTIALPASTE_RAW_FALSECOLOR;Demosaic false color suppression steps +!PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!PARTIALPASTE_RGBCURVES;RGB curves +!PARTIALPASTE_SHARPENEDGE;Edges +!PARTIALPASTE_SHARPENMICRO;Microcontrast +!PARTIALPASTE_VIBRANCE;Vibrance +!PARTIALPASTE_WAVELETGROUP;Wavelet processing +!PREFERENCES_ADD;Add +!PREFERENCES_AUTLISLOW;Low +!PREFERENCES_AUTLISMAX;Max - Average of all tiles +!PREFERENCES_AUTLISSTD;High +!PREFERENCES_AUTLISVLOW;None +!PREFERENCES_AUTLOW;Low +!PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +!PREFERENCES_AUTSTD;Standard +!PREFERENCES_BATCH_PROCESSING;Batch Processing +!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_BEHADDALL;All to 'Add' +!PREFERENCES_BEHAVIOR;Behavior +!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_BEHSETALL;All to 'Set' +!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_CURVEBBOXPOS;Position of curve copypasta buttons +!PREFERENCES_CURVEBBOXPOS_ABOVE;Above +!PREFERENCES_CURVEBBOXPOS_BELOW;Below +!PREFERENCES_CURVEBBOXPOS_LEFT;Left +!PREFERENCES_CURVEBBOXPOS_RIGHT;Right +!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_CUSTPROFBUILD;Custom Processing Profile Builder +!PREFERENCES_CUTOVERLAYBRUSH;Crop mask color/transparency +!PREFERENCES_D50;5000K +!PREFERENCES_D55;5500K +!PREFERENCES_D60;6000K +!PREFERENCES_D65;6500K +!PREFERENCES_DARKFRAMEFOUND;Found +!PREFERENCES_DARKFRAMESHOTS;shots +!PREFERENCES_DARKFRAMETEMPLATES;templates +!PREFERENCES_DARKFRAME;Dark-Frame +!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 (de-select for low resolution display) +!PREFERENCES_FILMSIMULATION;Film Simulation +!PREFERENCES_FLATFIELDFOUND;Found +!PREFERENCES_FLATFIELDSDIR;Flat-fields directory +!PREFERENCES_FLATFIELDSHOTS;shots +!PREFERENCES_FLATFIELDTEMPLATES;templates +!PREFERENCES_FLATFIELD;Flat-Field +!PREFERENCES_FLUOF2;Fluorescent F2 +!PREFERENCES_FLUOF7;Fluorescent F7 +!PREFERENCES_FLUOF11;Fluorescent F11 +!PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT;Same thumbnail height between the Editor's panel 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_GREY05;Yb=05 CIE L#30 +!PREFERENCES_GREY10;Yb=10 CIE L#40 +!PREFERENCES_GREY15;Yb=15 CIE L#45 +!PREFERENCES_GREY18;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_GREYSC18;Yb=18 CIE L#50 +!PREFERENCES_GREYSCA;Automatic +!PREFERENCES_GREYSC;Scene Yb luminance (%) +!PREFERENCES_GREY;Output device's Yb luminance (%) +!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_LANGAUTODETECT;Use system language +!PREFERENCES_LEVAUTDN;Denoising level +!PREFERENCES_LEVDN;Cell size +!PREFERENCES_LISS;Auto multi-zone smoothing +!PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders +!PREFERENCES_MAX;Maxi (Tile) +!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_MENUGROUPRANK;Group "Rank" +!PREFERENCES_MENUOPTIONS;Context Menu Options +!PREFERENCES_METADATA;Metadata +!PREFERENCES_MIN;Mini (100x115) +!PREFERENCES_MULTITABDUALMON;Multiple Editor Tabs In Own Window Mode +!PREFERENCES_MULTITAB;Multiple Editor Tabs 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_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_PROPERTY;Property +!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 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_SINGLETABVERTAB;Single Editor Tab Mode, Vertical Tabs +!PREFERENCES_SINGLETAB;Single Editor Tab Mode +!PREFERENCES_SLIMUI;Slim interface +!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_PERFORMANCE;Performance & Quality +!PREFERENCES_TAB_SOUND;Sounds +!PREFERENCES_TIMAX;High +!PREFERENCES_TINB;Number of tiles +!PREFERENCES_TISTD;Standard +!PREFERENCES_TP_LABEL;Tool panel: +!PREFERENCES_TP_USEICONORTEXT;Use tab icons instead of text +!PREFERENCES_TP_VSCROLLBAR;Hide vertical scrollbar +!PREFERENCES_TUNNELMETADATA;Copy IPTC/XMP unchanged to output file (when tagging with other program) +!PREFERENCES_USEBUNDLEDPROFILES;Use bundled profiles +!PREFERENCES_USESYSTEMTHEME;Use system theme +!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_WORKFLOW;Layout +!PROFILEPANEL_COPYPPASTE;Parameters to copy +!PROFILEPANEL_GLOBALPROFILES;Bundled profiles +!PROFILEPANEL_LOADPPASTE;Parameters to load +!PROFILEPANEL_MODE_TIP;Processing profile fill mode.\n\nButton pressed: partial profiles will be converted to full profiles; the missing values will be replaced with hard-coded defaults.\n\nButton released: profiles will be applied as they are, altering only those values which they contain. +!PROFILEPANEL_MYPROFILES;My profiles +!PROFILEPANEL_PASTEPPASTE;Parameters to paste +!PROFILEPANEL_PINTERNAL;Neutral +!PROFILEPANEL_SAVEPPASTE;Parameters to save +!PROGRESSBAR_LOADINGTHUMBS;Loading thumbnails... +!PROGRESSBAR_NOIMAGES;No images found +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing profile saved +!PROGRESSBAR_SNAPSHOT_ADDED;Snapshot added +!PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists +!SAVEDLG_FORCEFORMATOPTS;Force saving options +!SAVEDLG_SUBSAMP;Subsampling +!SAVEDLG_SUBSAMP_1;Best compression +!SAVEDLG_SUBSAMP_2;Balanced +!SAVEDLG_SUBSAMP_3;Best quality +!SAVEDLG_SUBSAMP_TOOLTIP;Best compression: 4:1:1\nBalanced: 4:2:2\nBest quality: 4:4:4 +!SAVEDLG_TIFFUNCOMPRESSED;Uncompressed TIFF +!SAVEDLG_WARNFILENAME;File will be named +!SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. +!THRESHOLDSELECTOR_BL;Bottom-left +!THRESHOLDSELECTOR_BR;Bottom-right +!THRESHOLDSELECTOR_B;Bottom +!THRESHOLDSELECTOR_HINT;Hold the Shift key to move individual control points. +!THRESHOLDSELECTOR_TL;Top-left +!THRESHOLDSELECTOR_TR;Top-right +!THRESHOLDSELECTOR_T;Top +!TP_BWMIX_ALGO;Algorithm OYCPM +!TP_BWMIX_ALGO_LI;Linear +!TP_BWMIX_ALGO_SP;Special effects +!TP_BWMIX_ALGO_TOOLTIP;Linear: will produce a normal linear response.\nSpecial effects: will produce special effects by mixing channels non-linearly. +!TP_BWMIX_AUTOCH;Auto +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing Channel Mixer. +!TP_BWMIX_CC_ENABLED;Adjust complementary color +!TP_BWMIX_CC_TOOLTIP;Enable to allow automatic adjustment of complementary colors in ROYGCBPM mode. +!TP_BWMIX_CHANNEL;Luminance equalizer +!TP_BWMIX_CURVEEDITOR1;'Before' curve +!TP_BWMIX_CURVEEDITOR2;'After' curve +!TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Tone curve, after B&W conversion, at the end of treatment. +!TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Tone curve, just before B&W conversion.\nMay take into account the color components. +!TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H).\nPay attention to extreme values as they may cause artifacts. +!TP_BWMIX_FILTER;Color Filter +!TP_BWMIX_FILTER_BLUEGREEN;Blue-Green +!TP_BWMIX_FILTER_BLUE;Blue +!TP_BWMIX_FILTER_GREENYELLOW;Green-Yellow +!TP_BWMIX_FILTER_GREEN;Green +!TP_BWMIX_FILTER_NONE;None +!TP_BWMIX_FILTER_PURPLE;Purple +!TP_BWMIX_FILTER_REDYELLOW;Red-Yellow +!TP_BWMIX_FILTER_RED;Red +!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. +!TP_BWMIX_FILTER_YELLOW;Yellow +!TP_BWMIX_GAMMA;Gamma Correction +!TP_BWMIX_GAM_TOOLTIP;Correct gamma for each RGB channel. +!TP_BWMIX_LABEL;Black-and-White +!TP_BWMIX_MET;Method +!TP_BWMIX_MET_CHANMIX;Channel Mixer +!TP_BWMIX_MET_DESAT;Desaturation +!TP_BWMIX_MET_LUMEQUAL;Luminance Equalizer +!TP_BWMIX_MIXC;Mixer +!TP_BWMIX_NEUTRAL;Reset mixer +!TP_BWMIX_NEUTRAL_TIP;Reset all values (Color Filter, Channel Mixer) to default. +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all the mixer options.\n"Total" displays the sum of the RGB values:\n- always 100% in relative mode\n- higher (lighter) or lower (darker) than 100% in absolute mode. +!TP_BWMIX_RGB_TOOLTIP;Mix the RGB channels. Use presets for guidance.\nPay attention to negative values that may cause artifacts or erratic behavior. +!TP_BWMIX_SETTING;Presets +!TP_BWMIX_SETTING_TOOLTIP;Different presets (film, landscape, etc.) or manual Channel Mixer settings. +!TP_BWMIX_SET_HIGHCONTAST;High contrast +!TP_BWMIX_SET_HIGHSENSIT;High Sensitivity +!TP_BWMIX_SET_HYPERPANCHRO;Hyper Panchromatic +!TP_BWMIX_SET_INFRARED;Infrared +!TP_BWMIX_SET_LANDSCAPE;Landscape +!TP_BWMIX_SET_LOWSENSIT;Low Sensitivity +!TP_BWMIX_SET_LUMINANCE;Luminance +!TP_BWMIX_SET_NORMCONTAST;Normal Contrast +!TP_BWMIX_SET_ORTHOCHRO;Orthochromatic +!TP_BWMIX_SET_PANCHRO;Panchromatic +!TP_BWMIX_SET_PORTRAIT;Portrait +!TP_BWMIX_SET_RGBABS;Absolute RGB +!TP_BWMIX_SET_RGBREL;Relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Relative ROYGCBPM +!TP_BWMIX_TCMODE_FILMLIKE;B&W Film-like +!TP_BWMIX_TCMODE_SATANDVALBLENDING;B&W Saturation and Value Blending +!TP_BWMIX_TCMODE_STANDARD;B&W Standard +!TP_BWMIX_TCMODE_WEIGHTEDSTD;B&W Weighted Standard +!TP_BWMIX_VAL;L +!TP_CHROMATABERR_LABEL;Chromatic Aberration +!TP_COLORAPP_ADAPTSCENE;Scene luminosity +!TP_COLORAPP_ADAPTSCENE_TOOLTIP;Absolute luminance of the scene environement (cd/m²).\n1) Calculated from the Exif data:\nShutter speed - ISO speed - F number - camera exposure correction.\n2) Calculated from the raw white point and RT's Exposure Compensation slider. +!TP_COLORAPP_ADAPTVIEWING;Viewing luminosity (cd/m²) +!TP_COLORAPP_ADAPTVIEWING_TOOLTIP;Absolute luminance of the viewing environnement\n(usually 16cd/m²). +!TP_COLORAPP_ADAP_AUTO_TOOLTIP;If the checkbox is checked (recommended) RawTherapee calculates an optimum value from Exif data.\nTo set the value manually, uncheck the checkbox first. +!TP_COLORAPP_ALGO;Algorithm +!TP_COLORAPP_ALGO_ALL;All +!TP_COLORAPP_ALGO_JC;Lightness + Chroma (JC) +!TP_COLORAPP_ALGO_JS;Lightness + Saturation (JS) +!TP_COLORAPP_ALGO_QM;Brightness + Colorfulness (QM) +!TP_COLORAPP_ALGO_TOOLTIP;Lets you choose between parameter subsets or all parameters. +!TP_COLORAPP_BADPIXSL;Hot/bad pixel filter +!TP_COLORAPP_BADPIXSL_TOOLTIP;Suppression of hot/bad (brightly colored) pixels.\n0 = No effect\n1 = Median\n2 = Gaussian.\nAlternatively, adjust the image to avoid very dark shadows.\n\nThese artifacts are due to limitations of CIECAM02. +!TP_COLORAPP_BRIGHT;Brightness (Q) +!TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from L*a*b* and RGB brightness. +!TP_COLORAPP_CHROMA;Chroma (C) +!TP_COLORAPP_CHROMA_M;Colorfulnes (M) +!TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM02 differs from L*a*b* and RGB colorfulness. +!TP_COLORAPP_CHROMA_S;Saturation (S) +!TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from L*a*b* and RGB saturation. +!TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from L*a*b* and RGB chroma. +!TP_COLORAPP_CIECAT_DEGREE;CAT02 adaptation +!TP_COLORAPP_CONTRAST;Contrast (J) +!TP_COLORAPP_CONTRAST_Q;Contrast (Q) +!TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrast in CIECAM02 for the Q slider; it differs from L*a*b* and RGB contrast. +!TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from L*a*b* and RGB contrast. +!TP_COLORAPP_CURVEEDITOR1;Tone curve 1 +!TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L* (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of J or Q after CIECAM02.\n\nJ and Q are not shown in the main histogram panel.\n\nFor final output refer to the main histogram panel. +!TP_COLORAPP_CURVEEDITOR2;Tone curve 2 +!TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Same usage as with the second exposure tone curve. +!TP_COLORAPP_CURVEEDITOR3;Color curve +!TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Adjust either chroma, saturation or colorfulness.\n\nShows the histogram of chromaticity (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of C, s or M after CIECAM02.\n\nC, s and M are not shown in the main histogram panel.\nFor final output refer to the main histogram panel. +!TP_COLORAPP_DATACIE;CIECAM02 output histograms in curves +!TP_COLORAPP_DATACIE_TOOLTIP;When enabled, histograms in CIECAM02 curves show approximate values/ranges for J or Q, and C, s or M after the CIECAM02 adjustments.\nThis selection does not impact the main histogram panel.\n\nWhen disabled, histograms in CIECAM02 curves show L*a*b* values before CIECAM02 adjustments. +!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RawTherapee calculates an optimum value, which is then used by CAT02, and also for the entire CIECAM02.\nTo set the value manually, uncheck the check-box first (values above 65 are recommended). +!TP_COLORAPP_DEGREE_TOOLTIP;Amount of CIE Chromatic Adaptation Transform 2002. +!TP_COLORAPP_GAMUT;Gamut control (L*a*b*) +!TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in L*a*b* mode. +!TP_COLORAPP_HUE;Hue (h) +!TP_COLORAPP_HUE_TOOLTIP;Hue (h) - angle between 0° and 360°. +!TP_COLORAPP_LABEL;CIE Color Appearance Model 2002 +!TP_COLORAPP_LABEL_CAM02;Image Adjustments +!TP_COLORAPP_LABEL_SCENE;Scene Conditions +!TP_COLORAPP_LABEL_VIEWING;Viewing Conditions +!TP_COLORAPP_LIGHT;Lightness (J) +!TP_COLORAPP_LIGHT_TOOLTIP;Lightness in CIECAM02 differs from L*a*b* and RGB lightness. +!TP_COLORAPP_MODEL;WP Model +!TP_COLORAPP_MODEL_TOOLTIP;White-Point Model.\n\nWB [RT] + [output]: RT's white balance is used for the scene, CIECAM02 is set to D50, and the output device's white balance is set in Preferences > Color Management.\n\nWB [RT+CAT02] + [output]: RT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences - Color Management. +!TP_COLORAPP_RSTPRO;Red & skin-tones protection +!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin-tones protection affects both sliders and curves. +!TP_COLORAPP_SHARPCIE;--unused-- +!TP_COLORAPP_SHARPCIE_TOOLTIP;--unused-- +!TP_COLORAPP_SURROUND;Surround +!TP_COLORAPP_SURROUND_AVER;Average +!TP_COLORAPP_SURROUND_DARK;Dark +!TP_COLORAPP_SURROUND_DIM;Dim +!TP_COLORAPP_SURROUND_EXDARK;Extremly Dark (Cutsheet) +!TP_COLORAPP_SURROUND_TOOLTIP;Changes tones and colors to take into account the viewing conditions of the output device.\n\nAverage: Average light environment (standard). The image will not change.\n\nDim: Dim environment (TV). The image will become slighty dark.\n\nDark: Dark environment (projector). The image will become more dark.\n\nExtremly Dark: Extremly dark environment (cutsheet). The image will become very dark. +!TP_COLORAPP_SURSOURCE;Dark surround +!TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if image has a dark border. +!TP_COLORAPP_TCMODE_BRIGHTNESS;Brightness +!TP_COLORAPP_TCMODE_CHROMA;Chroma +!TP_COLORAPP_TCMODE_COLORF;Colorfulness +!TP_COLORAPP_TCMODE_LABEL1;Curve mode 1 +!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_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] +!TP_COLORAPP_WBRT;WB [RT] + [output] +!TP_COLORTONING_AB;o C/L +!TP_COLORTONING_AUTOSAT;Automatic +!TP_COLORTONING_BALANCE;Balance +!TP_COLORTONING_BY;o C/L +!TP_COLORTONING_CHROMAC;Opacity +!TP_COLORTONING_COLOR;Color +!TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;Chroma opacity as a function of luminance oC=f(L) +!TP_COLORTONING_HIGHLIGHT;Highlights +!TP_COLORTONING_HUE;Hue +!TP_COLORTONING_LABEL;Color Toning +!TP_COLORTONING_LAB;L*a*b* blending +!TP_COLORTONING_LUMAMODE;Preserve luminance +!TP_COLORTONING_LUMAMODE_TOOLTIP;If enabled, when you change color (red, green, cyan, blue, etc.) the luminance of each pixel is preserved. +!TP_COLORTONING_LUMA;Luminance +!TP_COLORTONING_METHOD;Method +!TP_COLORTONING_METHOD_TOOLTIP;"L*a*b* blending", "RGB sliders" and "RGB curves" use interpolated color blending.\n"Color balance (Shadows/Midtones/Highlights)" and "Saturation 2 colors" use direct colors.\n\nThe Black-and-White tool can be enabled when using any color toning method, which allows for color toning. +!TP_COLORTONING_MIDTONES;Midtones +!TP_COLORTONING_NEUTRAL;Reset sliders +!TP_COLORTONING_NEUTRAL_TIP;Reset all values (Shadows, Midtones, Highlights) to default. +!TP_COLORTONING_OPACITY;Opacity +!TP_COLORTONING_RGBCURVES;RGB - Curves +!TP_COLORTONING_RGBSLIDERS;RGB - Sliders +!TP_COLORTONING_SATURATEDOPACITY;Strength +!TP_COLORTONING_SATURATIONTHRESHOLD;Threshold +!TP_COLORTONING_SA;Saturation Protection +!TP_COLORTONING_SHADOWS;Shadows +!TP_COLORTONING_SPLITCOCO;Color Balance Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITCO;Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITLR;Saturation 2 colors +!TP_COLORTONING_STRENGTH;Strength +!TP_COLORTONING_STR;Strength +!TP_COLORTONING_TWO2;Special chroma '2 colors' +!TP_COLORTONING_TWOALL;Special chroma +!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_GTFRAME;Frame +!TP_CROP_GTGRID;Grid +!TP_CROP_GTHARMMEANS;Harmonic Means +!TP_CROP_GTTRIANGLE1;Golden Triangles 1 +!TP_CROP_GTTRIANGLE2;Golden Triangles 2 +!TP_CROP_PPI;PPI= +!TP_DARKFRAME_AUTOSELECT;Auto-selection +!TP_DARKFRAME_LABEL;Dark-Frame +!TP_DEFRINGE_LABEL;Defringe +!TP_DEFRINGE_RADIUS;Radius +!TP_DEFRINGE_THRESHOLD;Threshold +!TP_DIRPYRDENOISE_33;3×3 strong +!TP_DIRPYRDENOISE_55SOFT;5×5 +!TP_DIRPYRDENOISE_55;5×5 strong +!TP_DIRPYRDENOISE_77;7×7 (slow) +!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_ABM;Chroma only +!TP_DIRPYRDENOISE_AUTO;Automatic global +!TP_DIRPYRDENOISE_AUTO_TOOLTIP;Try to evaluate chroma noise\nBe careful, this calculation is average, and is quite subjective ! +!TP_DIRPYRDENOISE_AUT;Automatic global +!TP_DIRPYRDENOISE_BLUE;Chrominance - Blue-Yellow +!TP_DIRPYRDENOISE_C2TYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CCCURVE;Chrominance curve +!TP_DIRPYRDENOISE_CHROMAFR;Chrominance +!TP_DIRPYRDENOISE_CHROMA;Chrominance - Master +!TP_DIRPYRDENOISE_CTYPE;Auto method +!TP_DIRPYRDENOISE_CTYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nAutomatic multi-zones\nNo preview - works only during saving, but using the "Preview" method by matching the tile size and center to the preview size and center you can get an idea of the expected results.\nThe image is divided into tiles (about 10 to 70 depending on image size) and each tile receives its own chrominance noise reduction settings.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CURVEEDITOR_CC;Chroma +!TP_DIRPYRDENOISE_CURVEEDITOR_CC_TOOLTIP;Increase (multiply) the value of all chrominance sliders.\nThis curve lets you adjust the strength of chromatic noise reduction as a function of chromaticity, for instance to increase the action in areas of low saturation and to decrease it in those of high saturation. +!TP_DIRPYRDENOISE_CURVEEDITOR_L_TOOLTIP;Modulates action of 'Luminance' denoise +!TP_DIRPYRDENOISE_CUR;Curve +!TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on the gamma of the input color profile. An sRGB gamma is assumed, thus if the image uses an input color profile of a different gamma, the effects of luminance noise reduction will differ. +!TP_DIRPYRDENOISE_ENH;Enhanced mode +!TP_DIRPYRDENOISE_ENH_TOOLTIP;Increases noise reduction quality at the expense of a 20% processing time increase. +!TP_DIRPYRDENOISE_GAMMA;Gamma +!TP_DIRPYRDENOISE_GAMMA_TOOLTIP;Gamma varies noise reduction strength across the range of tones. Smaller values will target shadows, while larger values will stretch the effect to the brighter tones. +!TP_DIRPYRDENOISE_LABEL;Noise Reduction +!TP_DIRPYRDENOISE_LABM;L*a*b* +!TP_DIRPYRDENOISE_LAB;L*a*b* +!TP_DIRPYRDENOISE_LCURVE;Luminance curve +!TP_DIRPYRDENOISE_LDETAIL;Luminance - Detail +!TP_DIRPYRDENOISE_LM;Luminance only +!TP_DIRPYRDENOISE_LPLABM;Weighted L* (little) + a*b* (normal) +!TP_DIRPYRDENOISE_LTYPE;Luminance control +!TP_DIRPYRDENOISE_LUMAFR;Luminance +!TP_DIRPYRDENOISE_LUMAFR_TOOLTIP;Wavelet on luminance and Fourier transform for luminance detail +!TP_DIRPYRDENOISE_LUMA;Luminance +!TP_DIRPYRDENOISE_MANU;Manual +!TP_DIRPYRDENOISE_MAN;Manual +!TP_DIRPYRDENOISE_MEDMETHOD;Median method +!TP_DIRPYRDENOISE_MEDTYPE;Median type +!TP_DIRPYRDENOISE_MED;Median Filter +!TP_DIRPYRDENOISE_MED_TOOLTIP;Enabled median denoising +!TP_DIRPYRDENOISE_METHOD11;Quality +!TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. +!TP_DIRPYRDENOISE_METHOD;Method +!TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or L*a*b* methods can be used.\n\nFor non-raw images the L*a*b* method will be used, regardless of the selection. +!TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - +!TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 +!TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. +!TP_DIRPYRDENOISE_PASSES;Median iterations +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PON;Auto multi-zones +!TP_DIRPYRDENOISE_PREVLABEL;Preview size=%1, Center: Px=%2 Py=%3 +!TP_DIRPYRDENOISE_PREV;Preview +!TP_DIRPYRDENOISE_PRE;Preview multi-zones +!TP_DIRPYRDENOISE_RED;Chrominance - Red-Green +!TP_DIRPYRDENOISE_RGBM;RGB +!TP_DIRPYRDENOISE_RGB;RGB +!TP_DIRPYRDENOISE_SHALBI;High +!TP_DIRPYRDENOISE_SHAL;Standard +!TP_DIRPYRDENOISE_SLI;Slider +!TP_DIRPYRDENOISE_SOFT;3x3 +!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_LUMAFINEST;Finest +!TP_DIRPYREQUALIZER_LUMANEUTRAL;Neutral +!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_THRESHOLD;Threshold +!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;Auto Distortion Correction +!TP_DISTORTION_AUTO_TIP;Correct lens distortion automatically for some cameras (Micro 4/3, some compact digital cameras, etc.). +!TP_EPD_EDGESTOPPING;Edge stopping +!TP_EPD_GAMMA;Gamma +!TP_EPD_LABEL;Tone Mapping +!TP_EPD_REWEIGHTINGITERATES;Reweighting iterates +!TP_EPD_SCALE;Scale +!TP_EPD_STRENGTH;Strength +!TP_EPD_TOOLTIP;Tone mapping is possible in L*a*b* mode (standard) and CIECAM02 mode.\n\nWhen in L*a*b* mode, tone mapping can also be used on the residual image of the Wavelet Levels tool.\n\nTo engage CIECAM02 tone mapping mode enable the following settings:\n1. CIECAM02\n2. Algorithm="Brightness + Colorfulness (QM)"\n3. "Tone mapping using CIECAM02 brightness (Q)" +!TP_EXPOSURE_AUTOLEVELS_TIP;Toggles execution of Auto Levels to automatically set Exposure slider values based on an image analysis.\nEnables Highlight Reconstruction if necessary. +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in Auto Levels operation. +!TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Highlight compression threshold +!TP_EXPOSURE_CURVEEDITOR1;Tone curve 1 +!TP_EXPOSURE_CURVEEDITOR2;Tone curve 2 +!TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Please refer to the "Exposure > Tone Curves" RawPedia article to learn how to achieve the best results by using two tone curves. +!TP_EXPOSURE_SATURATION;Saturation +!TP_EXPOSURE_TCMODE_FILMLIKE;Film-like +!TP_EXPOSURE_TCMODE_LABEL1;Curve mode 1 +!TP_EXPOSURE_TCMODE_LABEL2;Curve mode 2 +!TP_EXPOSURE_TCMODE_LUMINANCE;Luminance +!TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Saturation and Value Blending +!TP_EXPOSURE_TCMODE_STANDARD;Standard +!TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard +!TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points +!TP_EXPOS_WHITEPOINT_LABEL;Raw White Points +!TP_FILMSIMULATION_LABEL;Film Simulation +!TP_FILMSIMULATION_STRENGTH;Strength +!TP_FILMSIMULATION_ZEROCLUTSFOUND;Set HaldCLUT directory in Preferences +!TP_FLATFIELD_AUTOSELECT;Auto-selection +!TP_FLATFIELD_BLURRADIUS;Blur radius +!TP_FLATFIELD_BLURTYPE;Blur type +!TP_FLATFIELD_BT_AREA;Area +!TP_FLATFIELD_BT_HORIZONTAL;Horizontal +!TP_FLATFIELD_BT_VERTHORIZ;Vertical + Horizontal +!TP_FLATFIELD_BT_VERTICAL;Vertical +!TP_FLATFIELD_CLIPCONTROL;Clip control +!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. +!TP_FLATFIELD_LABEL;Flat-Field +!TP_GAMMA_CURV;Gamma +!TP_GAMMA_FREE;Free gamma +!TP_GAMMA_OUTPUT;Output gamma +!TP_GAMMA_SLOP;Slope (linear) +!TP_GENERAL_11SCALE_TOOLTIP;The effects of this tool are only visible or only accurate at a preview scale of 1:1. +!TP_GRADIENT_CENTER;Center +!TP_GRADIENT_CENTER_X;Center X +!TP_GRADIENT_CENTER_X_TOOLTIP;Shift gradient to the left (negative values) or right (positive values). +!TP_GRADIENT_CENTER_Y;Center Y +!TP_GRADIENT_CENTER_Y_TOOLTIP;Shift gradient up (negative values) or down (positive values). +!TP_GRADIENT_DEGREE;Angle +!TP_GRADIENT_DEGREE_TOOLTIP;Rotation angle in degrees. +!TP_GRADIENT_FEATHER;Feather +!TP_GRADIENT_FEATHER_TOOLTIP;Gradient width in percent of the image diagonal. +!TP_GRADIENT_LABEL;Graduated Filter +!TP_GRADIENT_STRENGTH;Strength +!TP_GRADIENT_STRENGTH_TOOLTIP;Filter strength in stops. +!TP_HLREC_BLEND;Blend +!TP_HLREC_ENA_TOOLTIP;Could be activated by Auto Levels. +!TP_HSVEQUALIZER_CHANNEL;Channel +!TP_HSVEQUALIZER_HUE;H +!TP_HSVEQUALIZER_LABEL;HSV Equalizer +!TP_HSVEQUALIZER_SAT;S +!TP_HSVEQUALIZER_VAL;V +!TP_ICM_BLENDCMSMATRIX;Blend ICC highlights with matrix +!TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover clipped highlights when using LUT-based ICC profiles. +!TP_ICM_DCPILLUMINANT;Illuminant +!TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolated +!TP_ICM_DCPILLUMINANT_TOOLTIP;Select which embedded DCP illuminant to employ. Default is "interpolated" which is a mix between the two based on white balance. The setting is only enabled if a Dual-Illuminant DCP with interpolation support is selected. +!TP_ICM_INPUTCAMERAICC;Auto-matched camera profile +!TP_ICM_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input color profiles. These profiles are more precise than simpler matrix ones. They are not available for all cameras. These profiles are stored in the /iccprofiles/input and /dcpprofiles folders and are automatically retrieved based on a file name matching to the exact model name of the camera. +!TP_ICM_INPUTCAMERA_TOOLTIP;Use a simple color matrix from dcraw, an enhanced RawTherapee version (whichever is available based on camera model) or one embedded in the DNG. +!TP_ICM_INPUTCUSTOM_TOOLTIP;Select your own DCP/ICC color profile file for the camera. +!TP_ICM_INPUTEMBEDDED_TOOLTIP;Use color profile embedded in non-raw files. +!TP_ICM_INPUTNONE;No profile +!TP_ICM_INPUTNONE_TOOLTIP;Use no input color profile at all.\nUse only in special cases. +!TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance +!TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. The result can be used for calibration purposes and generation of a camera profile. +!TP_ICM_TONECURVE;Use DCP's tone curve +!TP_ICM_TONECURVE_TOOLTIP;Employ the embedded DCP tone curve. The setting is only enabled if the selected DCP has a tone curve. +!TP_IMPULSEDENOISE_LABEL;Impulse Noise Reduction +!TP_IMPULSEDENOISE_THRESH;Threshold +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid color shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction. +!TP_LABCURVE_BRIGHTNESS;Lightness +!TP_LABCURVE_CHROMATICITY;Chromaticity +!TP_LABCURVE_CHROMA_TOOLTIP;To apply B&W toning, set Chromaticity to -100. +!TP_LABCURVE_CONTRAST;Contrast +!TP_LABCURVE_CURVEEDITOR;Luminance Curve +!TP_LABCURVE_CURVEEDITOR_A_RANGE1;Green Saturated +!TP_LABCURVE_CURVEEDITOR_A_RANGE2;Green Pastel +!TP_LABCURVE_CURVEEDITOR_A_RANGE3;Red Pastel +!TP_LABCURVE_CURVEEDITOR_A_RANGE4;Red Saturated +!TP_LABCURVE_CURVEEDITOR_B_RANGE1;Blue Saturated +!TP_LABCURVE_CURVEEDITOR_B_RANGE2;Blue Pastel +!TP_LABCURVE_CURVEEDITOR_B_RANGE3;Yellow Pastel +!TP_LABCURVE_CURVEEDITOR_B_RANGE4;Yellow Saturated +!TP_LABCURVE_CURVEEDITOR_CC;CC +!TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutral +!TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Dull +!TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastel +!TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Saturated +!TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Chromaticity according to chromaticity C=f(C) +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to hue C=f(H) +!TP_LABCURVE_CURVEEDITOR_CL;CL +!TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Chromaticity according to luminance C=f(L) +!TP_LABCURVE_CURVEEDITOR_HH;HH +!TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Hue according to hue H=f(H) +!TP_LABCURVE_CURVEEDITOR_LC;LC +!TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminance according to chromaticity L=f(C) +!TP_LABCURVE_CURVEEDITOR_LH;LH +!TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H) +!TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminance according to luminance L=f(L) +!TP_LABCURVE_LABEL;L*a*b* Adjustments +!TP_LABCURVE_LCREDSK;Restrict LC to red and skin-tones +!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_LENSGEOM_AUTOCROP;Auto-Crop +!TP_LENSGEOM_FILL;Auto-fill +!TP_LENSGEOM_LABEL;Lens / Geometry +!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_USECA;Chromatic aberration correction +!TP_LENSPROFILE_USEDIST;Distortion correction +!TP_LENSPROFILE_USEVIGN;Vignetting correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Resets exposure sliders to neutral values.\nApplies to the same controls that Auto Levels applies to, regardless of whether you used Auto Levels or not. +!TP_PCVIGNETTE_FEATHER;Feather +!TP_PCVIGNETTE_FEATHER_TOOLTIP;Feathering:\n0 = corners only,\n50 = halfway to center,\n100 = to center. +!TP_PCVIGNETTE_LABEL;Vignette Filter +!TP_PCVIGNETTE_ROUNDNESS;Roundness +!TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness:\n0 = rectangle,\n50 = fitted ellipse,\n100 = circle. +!TP_PCVIGNETTE_STRENGTH;Strength +!TP_PCVIGNETTE_STRENGTH_TOOLTIP;Filter strength in stops (reached in corners). +!TP_PERSPECTIVE_HORIZONTAL;Horizontal +!TP_PERSPECTIVE_LABEL;Perspective +!TP_PERSPECTIVE_VERTICAL;Vertical +!TP_PFCURVE_CURVEEDITOR_CH;Hue +!TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Controls defringe strength by color.\nHigher = more,\nLower = less. +!TP_PREPROCESS_DEADPIXFILT;Dead pixel filter +!TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Tries to suppress dead pixels. +!TP_PREPROCESS_GREENEQUIL;Green equilibration +!TP_PREPROCESS_HOTPIXFILT;Hot pixel filter +!TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Tries to suppress hot pixels. +!TP_PREPROCESS_LABEL;Preprocessing +!TP_PREPROCESS_LINEDENOISE;Line noise filter +!TP_PREPROCESS_NO_FOUND;None found +!TP_RAWCACORR_AUTO;Auto-correction +!TP_RAWCACORR_CABLUE;Blue +!TP_RAWCACORR_CARED;Red +!TP_RAWEXPOS_BLACKS;Black Levels +!TP_RAWEXPOS_BLACK_0;Green 1 (lead) +!TP_RAWEXPOS_BLACK_1;Red +!TP_RAWEXPOS_BLACK_2;Blue +!TP_RAWEXPOS_BLACK_3;Green 2 +!TP_RAWEXPOS_BLACK_BLUE;Blue +!TP_RAWEXPOS_BLACK_GREEN;Green +!TP_RAWEXPOS_BLACK_RED;Red +!TP_RAWEXPOS_LINEAR;White-point correction +!TP_RAWEXPOS_PRESER;Highlight preservation +!TP_RAWEXPOS_RGB;Red, Green, Blue +!TP_RAWEXPOS_TWOGREEN;Link greens +!TP_RAW_DCBENHANCE;DCB enhancement +!TP_RAW_DCBITERATIONS;Number of DCB iterations +!TP_RAW_DMETHOD_PROGRESSBAR;%1 demosaicing... +!TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Demosaicing refinement... +!TP_RAW_DMETHOD_TOOLTIP;Note: IGV and LMMSE are dedicated to high ISO images to aid in noise reduction without leading to maze patterns, posterization or a washed-out look. +!TP_RAW_HD;Threshold +!TP_RAW_HD_TOOLTIP;Lower values make hot/dead pixel detection more aggressive, but false positives may lead to artifacts. If you notice any artifacts appearing when enabling the Hot/Dead Pixel Filters, gradually increase the threshold value until they disappear. +!TP_RAW_LABEL;Demosaicing +!TP_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!TP_RAW_LMMSE_TOOLTIP;Adds gamma (step 1), median (steps 2-4) and refinement (steps 5-6) to reduce artifacts and improve the signal-to-noise ratio. +!TP_RAW_SENSOR_BAYER_LABEL;Sensor with Bayer Matrix +!TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;3-pass gives best results (recommended for low ISO images).\n1-pass is almost undistinguishable from 3-pass for high ISO images and is faster. +!TP_RAW_SENSOR_XTRANS_LABEL;Sensor with X-Trans Matrix +!TP_RESIZE_APPLIESTO;Applies to: +!TP_RESIZE_CROPPEDAREA;Cropped Area +!TP_RESIZE_FITBOX;Bounding Box +!TP_RESIZE_FULLIMAGE;Full Image +!TP_RESIZE_HEIGHT;Height +!TP_RESIZE_LANCZOS;Lanczos +!TP_RESIZE_SPECIFY;Specify: +!TP_RESIZE_WIDTH;Width +!TP_RGBCURVES_BLUE;B +!TP_RGBCURVES_CHANNEL;Channel +!TP_RGBCURVES_GREEN;G +!TP_RGBCURVES_LABEL;RGB Curves +!TP_RGBCURVES_LUMAMODE;Luminosity mode +!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_RGBCURVES_RED;R +!TP_SAVEDIALOG_OK_TIP;Shortcut: Ctrl-Enter +!TP_SHADOWSHLIGHTS_SHARPMASK;Sharp mask +!TP_SHARPENEDGE_AMOUNT;Quantity +!TP_SHARPENEDGE_LABEL;Edges +!TP_SHARPENEDGE_PASSES;Iterations +!TP_SHARPENEDGE_THREE;Luminance only +!TP_SHARPENING_TOOLTIP;Expect a slightly different effect when using with CIECAM02. If difference is observed, adjust to taste. +!TP_SHARPENMICRO_AMOUNT;Quantity +!TP_SHARPENMICRO_LABEL;Microcontrast +!TP_SHARPENMICRO_MATRIX;3×3 matrix instead of 5×5 +!TP_SHARPENMICRO_UNIFORMITY;Uniformity +!TP_VIBRANCE_AVOIDCOLORSHIFT;Avoid color shift +!TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Red/Purple +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Red +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Red/Yellow +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Yellow +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Hue according to hue H=f(H) +!TP_VIBRANCE_LABEL;Vibrance +!TP_VIBRANCE_PASTELS;Pastel Tones +!TP_VIBRANCE_PASTSATTOG;Link pastel and saturated tones +!TP_VIBRANCE_PROTECTSKINS;Protect skin-tones +!TP_VIBRANCE_PSTHRESHOLD;Pastel/saturated tones threshold +!TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Saturation threshold +!TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;The vertical axis represents pastel tones at the bottom and saturated tones at the top.\nThe horizontal axis represents the saturation range. +!TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Pastel/saturated transition's weighting +!TP_VIBRANCE_SATURATED;Saturated Tones +!TP_VIGNETTING_CENTER;Center +!TP_VIGNETTING_CENTER_X;Center X +!TP_VIGNETTING_CENTER_Y;Center Y +!TP_VIGNETTING_STRENGTH;Strength +!TP_WAVELET_1;Level 1 +!TP_WAVELET_2;Level 2 +!TP_WAVELET_3;Level 3 +!TP_WAVELET_4;Level 4 +!TP_WAVELET_5;Level 5 +!TP_WAVELET_6;Level 6 +!TP_WAVELET_7;Level 7 +!TP_WAVELET_8;Level 8 +!TP_WAVELET_9;Level 9 +!TP_WAVELET_ALL;All levels in all directions +!TP_WAVELET_APPLYTO;Apply To +!TP_WAVELET_AVOID;Avoid color shift +!TP_WAVELET_B0;Black +!TP_WAVELET_B1;Grey +!TP_WAVELET_B2;Residual +!TP_WAVELET_BACUR;Curve +!TP_WAVELET_BALANCE;Contrast balance d/v-h +!TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chromaticity or residual tone mapping are activated, the effect due to balance is amplified. +!TP_WAVELET_BALCHRO;Chroma balance +!TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chromaticity balance. +!TP_WAVELET_BANONE;None +!TP_WAVELET_BASLI;Slider +!TP_WAVELET_BATYPE;Contrast balance method +!TP_WAVELET_CCURVE;Local contrast +!TP_WAVELET_CH1;Whole chromaticity range +!TP_WAVELET_CH2;Saturated/pastel +!TP_WAVELET_CH3;Link contrast levels +!TP_WAVELET_CHCU;Curve +!TP_WAVELET_CHRO;Saturated/pastel threshold +!TP_WAVELET_CHRO_TOOLTIP;Sets the wavelet level which will be the threshold between saturated and pastel colors.\n1-x: saturated\nx-9: pastel\n\nIf the value exceeds the amount of wavelet levels you are using then it will be ignored. +!TP_WAVELET_CHR;Chroma-contrast link strength +!TP_WAVELET_CHR_TOOLTIP;Adjusts chromaticity as a function of "contrast levels" and "chroma-contrast link strength" +!TP_WAVELET_CHSL;Sliders +!TP_WAVELET_CHTYPE;Chrominance method +!TP_WAVELET_COLORT;Opacity Red-Green +!TP_WAVELET_COMBOTH;Both +!TP_WAVELET_COMPCONT;Contrast +!TP_WAVELET_COMPGAMMA;Compression gamma +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjusting the gamma of the residual image allow you to equilibrate the data and histogram. +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjust gamma for residual image and compression.\nAllow to equilibrate data and histogram +!TP_WAVELET_COMPTM;Tone mapping +!TP_WAVELET_CONTEDIT;'After' Contrast curve +!TP_WAVELET_CONTEDIT;'After' contrast curve +!TP_WAVELET_CONTRAST_MINUS;Contrast - +!TP_WAVELET_CONTRAST_PLUS;Contrast + +!TP_WAVELET_CONTRA;Contrast +!TP_WAVELET_CONTRA_TOOLTIP;Changes contrast of the residual image. +!TP_WAVELET_CONTR;Gamut +!TP_WAVELET_CTYPE;Chrominance control +!TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modifies local contrast as a function of the original local contrast (absciss)\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 100..300)\n66% absciss represents standard deviation of local contrast (real value about 300..800)\n100% represents maximum (real value about 3000..8000) +!TP_WAVELET_CURVEEDITOR_CH;Contrast levels=f(Hue) +!TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modifies each level's contrast as a function oh hue.\nTake care not to overwrite changes made with the Gamut Hue controls.\nThe curve will only have an effect when wavelet contrast level sliders are non-zero. +!TP_WAVELET_CURVEEDITOR_CL;L +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Applies a final contrast luminance curve at the end of the wavelet treatment. +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Apply a contrast luminance curve at the end of wavelet level threatment +!TP_WAVELET_CURVEEDITOR_HH;HH +!TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modifies the residual image's hue as a function of hue. +!TP_WAVELET_DALL;All directions +!TP_WAVELET_DAUB;Edge performance +!TP_WAVELET_DAUB_TOOLTIP;Changes Daubechies coefficients:\nD4 = Standard,\nD14 = Often best performance, 10% more time-intensive.\n\nAffects edge detection as well as the general quality of the firsts levels. However the quality is not strictly related to this coefficient and can vary with images and uses. +!TP_WAVELET_DISP;Preview Settings +!TP_WAVELET_DONE;Vertical +!TP_WAVELET_DTHR;Diagonal +!TP_WAVELET_DTWO;Horizontal +!TP_WAVELET_EDCU;Curve +!TP_WAVELET_EDGCONT;Local contrast +!TP_WAVELET_EDGCONT_TOOLTIP;Adjusting the points to the left decreases contrast, and to the right increases it.\nBottom-left, Top-Left, Top-Right, Bottom-right represent respectively local contast for low values, mean, mean+stdev, maxima +!TP_WAVELET_EDGEDETECTTHR2;Threshold high (detection) +!TP_WAVELET_EDGEDETECTTHR;Threshold low (noise) +!TP_WAVELET_EDGEDETECTTHR_TOOLTIP;This adjuster lets you target edge detection for example to avoid applying edge sharpness to fine details, such as noise in the sky. +!TP_WAVELET_EDGEDETECT;Gradient sensitivity +!TP_WAVELET_EDGEDETECT_TOOLTIP;Moving the slider to the right increases edge sensitivity. This affects local contrast, edge settings and noise. +!TP_WAVELET_EDGE;Edge Sharpness +!TP_WAVELET_EDGREINF_TOOLTIP;Reinforce or reduce the action of the first level, do the opposite to the second level, and leave the rest unchanged. +!TP_WAVELET_EDGTHRESH;Detail +!TP_WAVELET_EDGTHRESH_TOOLTIP;Change the repartition between the first levels and the others. The higher the threshold the more the action is centred on the first levels. Be careful with negative values, they increase the action of high levels and can introduce artifacts. +!TP_WAVELET_EDRAD;Radius +!TP_WAVELET_EDRAD_TOOLTIP;This radius adjustment is very different from those in other sharpening tools. Its value is compared to each level through a complex function. In this sense, a value of zero still has an effect. +!TP_WAVELET_EDSL;Threshold Sliders +!TP_WAVELET_EDTYPE;Local contrast method +!TP_WAVELET_EDVAL;Strength +!TP_WAVELET_FINAL;Final Touchup +!TP_WAVELET_FINEST;Finest +!TP_WAVELET_HIGHLIGHT;Highlight luminance range +!TP_WAVELET_HS1;Whole luminance range +!TP_WAVELET_HS2;Shadows/Highlights +!TP_WAVELET_HUESKIN;Skin hue +!TP_WAVELET_HUESKIN_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_HUESKY;Sky hue +!TP_WAVELET_HUESKY_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_INF;Below or equal the level +!TP_WAVELET_ITER;Delta balance levels +!TP_WAVELET_ITER_TOOLTIP;Left: increase low levels and reduce high levels,\nRight: reduce low levels and increase high levels. +!TP_WAVELET_LABEL;Wavelet levels +!TP_WAVELET_LARGEST;Coarsest +!TP_WAVELET_LEVCH;Chromaticity +!TP_WAVELET_LEVELS;Wavelet levels +!TP_WAVELET_LEVELS_TOOLTIP;Choose the number of detail levels the image is to be decomposed into. More levels require more RAM and require a longer processing time. +!TP_WAVELET_LEVF;Contrast +!TP_WAVELET_LEVLABEL;Preview maximum possible levels = %1 +!TP_WAVELET_LEVONE;Level 2 +!TP_WAVELET_LEVTWO;Level 3 +!TP_WAVELET_LEVZERO;Level 1 +!TP_WAVELET_LINKEDG;Link with Edge Sharpness' Strength +!TP_WAVELET_LIPST;Enhanced algorithm +!TP_WAVELET_LIPST_TOOLTIP;This algorithm uses Lipschitz regularity to increase edge detection quality at a cost of increased processing time and memory requirements. +!TP_WAVELET_LOWLIGHT;Shadow luminance range +!TP_WAVELET_MEDGREINF;First level +!TP_WAVELET_MEDILEV;Edge detection +!TP_WAVELET_MEDI;Reduce artifacts in blue sky +!TP_WAVELET_NEUTRAL;Neutral +!TP_WAVELET_NOISE;Denoise and Refine +!TP_WAVELET_NOIS;Denoise +!TP_WAVELET_ONE;One level +!TP_WAVELET_OPACITYWL;Final local contrast +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify final local contrast in function of last local contrast (absciss) for all levels decomposition\nTake into account: \na)contrast levels \nb)edge sharpness \nc)contrast balance\nd)decomposition-recomposition\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 200..1000)\n66% absciss represents standard deviation of local contrast (real value about 1000..2000)\n100% represents maximum (real value about 5000..13000) +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify the final local contrast at the end of the wavelet treatment.\n\nThe left side represents the smallest local contrast, progressing to the largest local contrast on the right. +!TP_WAVELET_OPACITYW;Contrast balance d/v-h curve +!TP_WAVELET_OPACITY;Opacity Blue-Yellow +!TP_WAVELET_PASTEL;Pastel chromaticity +!TP_WAVELET_PREVIEWBACK;Background +!TP_WAVELET_PREVIEWLEVELS;Preview +!TP_WAVELET_RE1;Reinforced +!TP_WAVELET_RE2;Unchanged +!TP_WAVELET_RE3;Reduced +!TP_WAVELET_RESCHRO;Chromaticity +!TP_WAVELET_RESCONH;Highlights +!TP_WAVELET_RESCON;Shadows +!TP_WAVELET_RESID;Residual image +!TP_WAVELET_SAT;Saturated chromaticity +!TP_WAVELET_SETTINGS;Wavelet Settings +!TP_WAVELET_SKIN;Skin targetting/protection +!TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected. +!TP_WAVELET_SKY;Sky targetting/protection +!TP_WAVELET_SKY_TOOLTIP;At -100 sky-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 sky-tones are protected while all other tones are affected. +!TP_WAVELET_STRENGTH;Strength +!TP_WAVELET_STREN;Strength +!TP_WAVELET_SUPE;Extra +!TP_WAVELET_SUP;Above the level +!TP_WAVELET_THRESHOLD2;Shadow levels +!TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels between 9 and 9 minus the value will be affected by the shadow luminance range. Other levels will be fully treated. The highest level possible is limited by the highlight level value (9 minus highlight level value). +!TP_WAVELET_THRESHOLD;Highlight levels +!TP_WAVELET_THRESHOLD_TOOLTIP;Only levels beyond the chosen value will be affected by the highlight luminance range. Other levels will be fully treated. The chosen value here limits the highest possible value of the shadow levels. +!TP_WAVELET_THRH;Highlights threshold +!TP_WAVELET_THR;Shadows threshold +!TP_WAVELET_TILESBIG;Big tiles +!TP_WAVELET_TILESFULL;Full image +!TP_WAVELET_TILESIZE;Tiling method +!TP_WAVELET_TILESLIT;Little tiles +!TP_WAVELET_TILES_TOOLTIP;Processing the full image leads to better quality and is the recommended option, while using tiles is a fall-back solution for users with little RAM. Refer to RawPedia for memory requirements. +!TP_WAVELET_TMHIGH;High +!TP_WAVELET_TMLOWHIGH;Low+High +!TP_WAVELET_TMNONE;None +!TP_WAVELET_TMSTD;Standard +!TP_WAVELET_TMSTRENGTH;Compression strength +!TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image. When the value is different from 0, the Strength and Gamma sliders of the Tone Mapping tool in the Exposure tab will become grayed out. +!TP_WAVELET_TMTYPE;Compression method +!TP_WAVELET_TON;Toning +!TP_WAVELET_daub2;D2 - low +!TP_WAVELET_daub4;D4 - standard +!TP_WAVELET_daub6;D6 - standard plus +!TP_WAVELET_daub10;D10 - medium +!TP_WAVELET_daub14;D14 - high +!TP_WBALANCE_CLOUDY;Cloudy +!TP_WBALANCE_DAYLIGHT;Daylight (sunny) +!TP_WBALANCE_EQBLUERED;Blue/Red equalizer +!TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behavior of "white balance" by modulating the blue/red balance.\nThis can be useful when shooting conditions:\na) are far from the standard illuminant (e.g. underwater),\nb) are far from conditions where calibrations were performed,\nc) where the matrices or ICC profiles are unsuitable. +!TP_WBALANCE_FLASH55;Leica +!TP_WBALANCE_FLASH60;Standard, Canon, Pentax, Olympus +!TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta +!TP_WBALANCE_FLASH_HEADER;Flash +!TP_WBALANCE_FLUO1;F1 - Daylight +!TP_WBALANCE_FLUO2;F2 - Cool White +!TP_WBALANCE_FLUO3;F3 - White +!TP_WBALANCE_FLUO4;F4 - Warm White +!TP_WBALANCE_FLUO5;F5 - Daylight +!TP_WBALANCE_FLUO6;F6 - Lite White +!TP_WBALANCE_FLUO7;F7 - D65 Daylight Simulator +!TP_WBALANCE_FLUO8;F8 - D50 / Sylvania F40 Design +!TP_WBALANCE_FLUO9;F9 - Cool White Deluxe +!TP_WBALANCE_FLUO10;F10 - Philips TL85 +!TP_WBALANCE_FLUO11;F11 - Philips TL84 +!TP_WBALANCE_FLUO12;F12 - Philips TL83 +!TP_WBALANCE_FLUO_HEADER;Fluorescent +!TP_WBALANCE_GTI;GTI +!TP_WBALANCE_HMI;HMI +!TP_WBALANCE_JUDGEIII;JudgeIII +!TP_WBALANCE_LAMP_HEADER;Lamp +!TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 +!TP_WBALANCE_LED_HEADER;LED +!TP_WBALANCE_LED_LSI;LSI Lumelex 2040 +!TP_WBALANCE_SHADE;Shade +!TP_WBALANCE_SOLUX35;Solux 3500K +!TP_WBALANCE_SOLUX41;Solux 4100K +!TP_WBALANCE_SOLUX47;Solux 4700K (vendor) +!TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) +!TP_WBALANCE_TUNGSTEN;Tungsten +!TP_WBALANCE_WATER1;UnderWater 1 +!TP_WBALANCE_WATER2;UnderWater 2 +!TP_WBALANCE_WATER_HEADER;UnderWater +!ZOOMPANEL_100;(100%) +!ZOOMPANEL_NEWCROPWINDOW;Open (new) detail window +!ZOOMPANEL_ZOOM100;Zoom to 100%\nShortcut: z +!ZOOMPANEL_ZOOMFITCROPSCREEN;Fit crop to screen\nShortcut: Alt-f +!ZOOMPANEL_ZOOMFITSCREEN;Fit whole image to screen\nShortcut: f +!ZOOMPANEL_ZOOMIN;Zoom In\nShortcut: + +!ZOOMPANEL_ZOOMOUT;Zoom Out\nShortcut: - diff --git a/rtdata/languages/Hebrew b/rtdata/languages/Hebrew new file mode 100644 index 000000000..19319818d --- /dev/null +++ b/rtdata/languages/Hebrew @@ -0,0 +1,1857 @@ +#01 2008-02-21 + +ADJUSTER_RESET_TO_DEFAULT;ברירת מחדל +CURVEEDITOR_LINEAR;ישיר +CURVEEDITOR_LOADDLGLABEL;הטען עקמה +CURVEEDITOR_SAVEDLGLABEL;שמור עקמה +CURVEEDITOR_TOOLTIPLINEAR;החזר עקמה לישירה +CURVEEDITOR_TOOLTIPLOAD;הטען עקמה +CURVEEDITOR_TOOLTIPSAVE;שמור עקמה נוכחית +DIRBROWSER_FOLDERS;תיקיות +EXIFFILTER_APERTURE;Aperture +EXIFFILTER_CAMERA;Camera +EXIFFILTER_FOCALLEN;Focal Length +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Lens +EXIFFILTER_SHUTTER;Shutter +EXIFPANEL_ADDEDITHINT;Add new tag or edit tag +EXIFPANEL_ADDEDIT;Add/Edit +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Enter value +EXIFPANEL_ADDTAGDLG_SELECTTAG;Select tag +EXIFPANEL_ADDTAGDLG_TITLE;Add/Edit Tag +EXIFPANEL_KEEPHINT;Keep the selected tags when writing output file +EXIFPANEL_KEEP;Keep +EXIFPANEL_REMOVEHINT;Remove the selected tags when writing output file +EXIFPANEL_REMOVE;Remove +EXIFPANEL_RESETALLHINT;Reset all tags to their original values +EXIFPANEL_RESETALL;Reset All +EXIFPANEL_RESETHINT;Reset the selected tags to their original values +EXIFPANEL_RESET;Reset +EXIFPANEL_SUBDIRECTORY;Subdirectory +FILEBROWSER_APPLYPROFILE;Apply profile +FILEBROWSER_CLEARPROFILE;Clear profile +FILEBROWSER_COPYPROFILE;Copy profile +FILEBROWSER_DELETEDLGLABEL;File delete confirmation +FILEBROWSER_DELETEDLGMSG;Are you sure you want to delete the selected %1 files? +FILEBROWSER_EMPTYTRASHHINT;Permanently delete the files of the trash +FILEBROWSER_EMPTYTRASH;Empty Trash +FILEBROWSER_PARTIALPASTEPROFILE;Partial paste +FILEBROWSER_PASTEPROFILE;Paste profile +FILEBROWSER_POPUPCANCELJOB;Cancel job +FILEBROWSER_POPUPMOVEEND;Move to end of queue +FILEBROWSER_POPUPMOVEHEAD;Move to head of queue +FILEBROWSER_POPUPOPENINEDITOR;Open in Editor +FILEBROWSER_POPUPOPEN;Open +FILEBROWSER_POPUPPROCESS;Put to processing queue +FILEBROWSER_POPUPREMOVE;Remove from filesystem +FILEBROWSER_POPUPRENAME;Rename +FILEBROWSER_POPUPSELECTALL;Select all +FILEBROWSER_POPUPTRASH;Move to trash +FILEBROWSER_POPUPUNRANK;Unrank +FILEBROWSER_POPUPUNTRASH;Remove from trash +FILEBROWSER_RENAMEDLGLABEL;Rename file +FILEBROWSER_RENAMEDLGMSG;Rename file "%1" to: +FILEBROWSER_SHOWDIRHINT;Show all images of the directory +FILEBROWSER_SHOWRANK1HINT;Show images ranked as 1 star +FILEBROWSER_SHOWRANK2HINT;Show images ranked as 2 star +FILEBROWSER_SHOWRANK3HINT;Show images ranked as 3 star +FILEBROWSER_SHOWRANK4HINT;Show images ranked as 4 star +FILEBROWSER_SHOWRANK5HINT;Show images ranked as 5 star +FILEBROWSER_SHOWTRASHHINT;Show content of the trash +FILEBROWSER_SHOWUNRANKHINT;Show unranked images +FILEBROWSER_STARTPROCESSINGHINT;Start processing/saving of images in the queue +FILEBROWSER_STARTPROCESSING;Start Processing +FILEBROWSER_STOPPROCESSINGHINT;Stop processing of images +FILEBROWSER_STOPPROCESSING;Stop processing +FILEBROWSER_THUMBSIZE;Thumb. size +FILEBROWSER_ZOOMINHINT;Increase thumbnail size +FILEBROWSER_ZOOMOUTHINT;Decrease thumbnail size +GENERAL_ABOUT;אודות +GENERAL_CANCEL;בטל +GENERAL_DISABLED;מבוטל +GENERAL_DISABLE;בטל +GENERAL_ENABLED;מופעל +GENERAL_ENABLE;הפעל +GENERAL_LANDSCAPE;נוף +GENERAL_NA;אין +GENERAL_NO;לא +GENERAL_OK;שמור +GENERAL_PORTRAIT;דיוקן +GENERAL_SAVE;שמור +HISTOGRAM_TOOLTIP_B;Show/הסתר היסטוגרם כחול +HISTOGRAM_TOOLTIP_G;Show/הסתר היסטוגרם ירוק +HISTOGRAM_TOOLTIP_L;Show/CIELAB הסתר היסטוגרם +HISTOGRAM_TOOLTIP_R;Show/הסתר היסטוגרם אדום +HISTORY_CHANGED;Changed +HISTORY_CUSTOMCURVE;עקמה מותאמת +HISTORY_DELSNAPSHOT;הסר תצלום +HISTORY_FROMCLIPBOARD;From clipboard +HISTORY_LABEL;היסטוריה +HISTORY_MSG_1;צילום טעון +HISTORY_MSG_2;פרופיל טעון +HISTORY_MSG_3;פרופיל הוחלף +HISTORY_MSG_4;דיפדוף בהיסטוריה +HISTORY_MSG_5;בהירות +HISTORY_MSG_6;ניגודיות +HISTORY_MSG_7;שחור +HISTORY_MSG_8;פיצוי חשיפה +HISTORY_MSG_9;דחיסת גוונים בהירים +HISTORY_MSG_10;דחיסת גוונים כהים +HISTORY_MSG_11;עקמת גוונים +HISTORY_MSG_12;חשיפה אוטומטית +HISTORY_MSG_13;קיצוץ החסיפה +HISTORY_MSG_14;הארה - בהירות +HISTORY_MSG_15;הארה - ניגודיות +HISTORY_MSG_16;הארה - שחור +HISTORY_MSG_17;הארה - דחיסת גוונים בהירים +HISTORY_MSG_18;הארה - דחיסת גוונים כהים +HISTORY_MSG_19;הארה - עקמה +HISTORY_MSG_20;חידוד +HISTORY_MSG_21;חידוד - רדיוס +HISTORY_MSG_22;חידוד - כמות +HISTORY_MSG_23;חידוד - סף +HISTORY_MSG_24;חידוד - רק קצוות +HISTORY_MSG_25;חידוד - רדיוס גילוי קצוות +HISTORY_MSG_26;חידוד - סבילות קצוות +HISTORY_MSG_27;חידוד - בקרת הילה +HISTORY_MSG_28;בקרת הילה, כמות +HISTORY_MSG_29;שיטת החידוד +HISTORY_MSG_30;דיקונבולוציה - רדיוס +HISTORY_MSG_31;גיקונבולוציה - כמות +HISTORY_MSG_32;גיקונבולוציה - ריסון +HISTORY_MSG_33;גיקונבולוציה - חזרות +HISTORY_MSG_34;המנע מקיצוץ צבע +HISTORY_MSG_35;הגבלת רויה +HISTORY_MSG_36;גבול רויה +HISTORY_MSG_37;הגברת צבע +HISTORY_MSG_38;שיטת איזון לבן +HISTORY_MSG_39;מידת חום +HISTORY_MSG_40;גיוון איזון צבע +HISTORY_MSG_41;העברת צבע א +HISTORY_MSG_42;העברת צבע ב +HISTORY_MSG_43;הסרת רעש בהירות +HISTORY_MSG_44;הסרת רעש בהירות רדיוס +HISTORY_MSG_45;הסרת רעש בהירות סבילות קצוות +HISTORY_MSG_46;הסרת רעש צבעוני +HISTORY_MSG_47;הסרת רעש צבעוני רדיוס +HISTORY_MSG_48;הסרת רעש צבעוני סבילות קצוות +HISTORY_MSG_49;הסרת רעש צבעוני רגישות לקצוות +HISTORY_MSG_50;כלי בהירים\כהים +HISTORY_MSG_51;הגברת גוונים בהירים +HISTORY_MSG_52;ההגברת גוונים כהים +HISTORY_MSG_53;בהירים, רוחב גוונים +HISTORY_MSG_54;כהים, רוחב גוונים +HISTORY_MSG_55;ניגודיות מקומית +HISTORY_MSG_56;בהירים\כהים רדיוס +HISTORY_MSG_57;סיבוב גס +HISTORY_MSG_58;היפוך אופקי +HISTORY_MSG_59;היפוך אנכי +HISTORY_MSG_60;סיבוב +HISTORY_MSG_61;סיבוב +HISTORY_MSG_62;תיקון עיוות בעדשה +HISTORY_MSG_63;סימניה נבחרה +HISTORY_MSG_64;גזירת תצלום +HISTORY_MSG_65;C/A תיקון עיוות +HISTORY_MSG_66;שחזור גוונים בהירים +HISTORY_MSG_67;שחזור גוונים בהירים, כמות +HISTORY_MSG_68;שחזור גוונים בהירים, שיטה +HISTORY_MSG_69;מרחב צבע עבודה +HISTORY_MSG_70;מרחב צבע ייצוא +HISTORY_MSG_71;מרחב צבע ייבוא +HISTORY_MSG_72;תיקון פינות כהות +HISTORY_MSG_73;מערבב ערוצים +HISTORY_MSG_74;מידת שינוי גודל +HISTORY_MSG_75;שיטת שינוי גודל +HISTORY_MSG_76;Exif Metadata +HISTORY_MSG_77;IPTC Metadata +HISTORY_MSG_78;Data specified for resize +HISTORY_MSG_79;Resize width +HISTORY_MSG_80;Resize height +HISTORY_MSG_81;Resize enabled +HISTORY_NEWSNAPSHOT;תצלום חדש +HISTORY_SNAPSHOTS;תצלומים +HISTORY_SNAPSHOT;תצלום +IPTCPANEL_AUTHORSPOSITIONHINT;Title of the creator or creators of the object (By-line Title). +IPTCPANEL_AUTHORSPOSITION;Author's position +IPTCPANEL_AUTHOR;Author +IPTCPANEL_CAPTIONHINT;A textual description of the data (Caption - Abstract) +IPTCPANEL_CAPTIONWRITERHINT;The name of the person involved in the writing, editing or correcting the image or caption/abstract (Writer - Editor). +IPTCPANEL_CAPTIONWRITER;Caption Writer +IPTCPANEL_CAPTION;Caption +IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider (Category). +IPTCPANEL_CATEGORY;Category +IPTCPANEL_CITYHINT;City of image origin (City). +IPTCPANEL_CITY;City +IPTCPANEL_COPYHINT;Copy IPTC settings to clipboard +IPTCPANEL_COPYRIGHTHINT;Any necessary copyright notice (Copyright Notice). +IPTCPANEL_COPYRIGHT;Copyright +IPTCPANEL_COUNTRYHINT;The name of the country/primary location where the image was created (Country - Primary Location Name). +IPTCPANEL_COUNTRY;Country +IPTCPANEL_CREDITHINT;Identifies the provider of the image, not necessarily the owner/creator (Credit). +IPTCPANEL_CREDIT;Credit +IPTCPANEL_DATECREATEDHINT;The date the intellectual content of the image was created; Format: JJJJMMTT (Date Created). +IPTCPANEL_DATECREATED;Date Created +IPTCPANEL_EMBEDDEDHINT;Reset to IPTC data embedded in the image file +IPTCPANEL_EMBEDDED;Embedded +IPTCPANEL_HEADLINEHINT;A publishable entry providing a synopsis of the contents of the image (Headline). +IPTCPANEL_HEADLINE;Headline +IPTCPANEL_INSTRUCTIONSHINT;Other editorial instructions concerning the use of the image (Special Instructions). +IPTCPANEL_INSTRUCTIONS;Instructions +IPTCPANEL_KEYWORDSHINT;Used to indicate specific information retrieval words (Keywords). +IPTCPANEL_KEYWORDS;Keywords +IPTCPANEL_PASTEHINT;Paste IPTC settings from clipboard +IPTCPANEL_PROVINCEHINT;The Province/State where the image originates (Province-State). +IPTCPANEL_PROVINCE;Province +IPTCPANEL_RESETHINT;Reset to profile default +IPTCPANEL_RESET;Reset +IPTCPANEL_SOURCEHINT;The original owner of the intellectual content of the image (Source). +IPTCPANEL_SOURCE;Source +IPTCPANEL_SUPPCATEGORIESHINT;Further refines the subject of the image (Supplemental Categories). +IPTCPANEL_SUPPCATEGORIES;Suppl. Categories +IPTCPANEL_TITLEHINT;A shorthand reference for the image (Object Name). +IPTCPANEL_TITLE;Title +IPTCPANEL_TRANSREFERENCEHINT;A code representing the location of original transmission (Original Transmission Reference). +IPTCPANEL_TRANSREFERENCE;Trans. Reference +MAIN_BUTTON_PREFERENCES;העדפויות +MAIN_BUTTON_SAVE;שמור צילום +MAIN_BUTTON_SENDTOEDITOR;Send to editor +MAIN_FRAME_BATCHQUEUE;Batch Queue +MAIN_FRAME_FILEBROWSER;File Browser +MAIN_FRAME_PLACES;Places +MAIN_FRAME_PLACES_ADD;Add +MAIN_FRAME_PLACES_DEL;Del +MAIN_FRAME_RECENT;Recent Folders +MAIN_MSG_ALREADYEXISTS;הקובץ כבר קיים +MAIN_MSG_CANNOTLOAD;לא יכול להעלות את הקובץ +MAIN_MSG_CANNOTSAVE;טעות בשמירת הקובץ +MAIN_MSG_CANNOTSTARTEDITOR;Can not start editor. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Please set the correct path in the "Preferences" dialog. +MAIN_MSG_QOVERWRITE;?רצונך לכתוב אותו מחדש? +MAIN_TAB_COLOR;Color +MAIN_TAB_DETAIL;Detail +MAIN_TAB_DEVELOP;Develop +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;Exposure +MAIN_TAB_FILTER;Filter +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadata +MAIN_TAB_TRANSFORM;התמרות +MAIN_TOOLTIP_HIDEHP;גלה\הסתר לוח שמאלי - היסטוריה (shortcut key: F) +MAIN_TOOLTIP_INDCLIPPEDH;סימן לגוונים בהירים מקוצצים +MAIN_TOOLTIP_INDCLIPPEDS;סימן לגוונים כהים מקוצצים +MAIN_TOOLTIP_QINFO;מידע מהיר אודות הצילום +PARTIALPASTE_BASICGROUP;Basic settings +PARTIALPASTE_CACORRECTION;C/A correction +PARTIALPASTE_COARSETRANS;90 deg rotation / flipping +PARTIALPASTE_COLORGROUP;Color related settings +PARTIALPASTE_COMPOSITIONGROUP;Composition settings +PARTIALPASTE_CROP;Crop +PARTIALPASTE_DIALOGLABEL;Partial paste processing profile +PARTIALPASTE_DISTORTION;Distortion correction +PARTIALPASTE_EXIFCHANGES;Changes to exif data +PARTIALPASTE_EXPOSURE;Exposure +PARTIALPASTE_ICMSETTINGS;ICM settings +PARTIALPASTE_IPTCINFO;IPTC info +PARTIALPASTE_LENSGROUP;Lens related settings +PARTIALPASTE_METAGROUP;Metadata +PARTIALPASTE_RESIZE;Resize +PARTIALPASTE_ROTATION;Rotation +PARTIALPASTE_SHADOWSHIGHLIGHTS;Shadows/Highlights +PARTIALPASTE_SHARPENING;Sharpening +PARTIALPASTE_VIGNETTING;Vignetting correction +PARTIALPASTE_WHITEBALANCE;White balance +PREFERENCES_APPLNEXTSTARTUP;ייושם באתחול הבא +PREFERENCES_CACHECLEARALL;Clear All +PREFERENCES_CACHECLEARPROFILES;Clear Profiles +PREFERENCES_CACHECLEARTHUMBS;Clear Thumbnails +PREFERENCES_CACHEMAXENTRIES;Maximal Number of Cache Entries +PREFERENCES_CACHEOPTS;Cache Options +PREFERENCES_CACHETHUMBHEIGHT;Maximal Thumbnail Height +PREFERENCES_CLIPPINGIND;סימון קיצוץ +PREFERENCES_CMETRICINTENT;כוונה קולורמטרית +PREFERENCES_DATEFORMATHINT;You can use the following formatting strings:\n%y : year\n%m : month\n%d : day\n\nFor example, the hungarian date format is:\n%y/%m/%d +PREFERENCES_DATEFORMAT;צורת תאריך +PREFERENCES_DEFAULTLANG;שפה ברירת המחדל +PREFERENCES_DEFAULTTHEME;Default theme +PREFERENCES_DIRHOME;תיקיית הבית +PREFERENCES_DIRLAST;תיקיה האחרונה שביקרתי בה +PREFERENCES_DIROTHER;אחר +PREFERENCES_DIRSELECTDLG;בחר תיקיית צילומים לאתחול +PREFERENCES_DIRSOFTWARE;תיקיית התקנה +PREFERENCES_EDITORCMDLINE;Other command line +PREFERENCES_EXTERNALEDITOR;External editor +PREFERENCES_FBROWSEROPTS;ברירות דפדפן +PREFERENCES_FILEFORMAT;תצורת קובץ +PREFERENCES_FORIMAGE;עבור קבצי צילום +PREFERENCES_FORRAW;RAW עבור קבצי +PREFERENCES_GIMPPATH;GIMP installation directory +PREFERENCES_HLTHRESHOLD;סף קיצוץ עליון +PREFERENCES_ICCDIR;ICC תיקיית פרופילי צבע +PREFERENCES_IMPROCPARAMS;נתוני עיבוד ברירת המחדל +PREFERENCES_INTENT_ABSOLUTE;קולורמטרית מוחלטת +PREFERENCES_INTENT_PERCEPTUAL;תפיסתית +PREFERENCES_INTENT_RELATIVE;קולורמטרית יחסית +PREFERENCES_INTENT_SATURATION;רויה +PREFERENCES_MONITORICC;פרופיל מסך +PREFERENCES_OUTDIRFOLDERHINT;Put the saved images to the seledted folder +PREFERENCES_OUTDIRFOLDER;Save to folder +PREFERENCES_OUTDIRTEMPLATEHINT;You can use the following formatting strings:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nThese formatting strings refer to the directories and sub-paths of the path of the raw file.\n\nFor example, if /home/tom/image/02-09-2006/dsc0012.nefhas been opened, the meaning of the formatting strings are:\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\nIf you want to save the output image where the original is, write:\n%p1/%f\n\nIf you want to save the output image in a directory 'converted' located the directory of the original, write:\n%p1/converted/%f\n\nIf you want to save the output image in directory '/home/tom/converted' with keeping the same subdirectory of dates, write:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Use Template +PREFERENCES_OUTDIR;תיקיית ייצוא +PREFERENCES_PARSEDEXTADDHINT;Type an extension and press this button to append list +PREFERENCES_PARSEDEXTADD;Add Extension +PREFERENCES_PARSEDEXTDELHINT;Delete selected extension from the list +PREFERENCES_PARSEDEXT;Parsed Extensions +PREFERENCES_PROFILEHANDLING;Processing Profile Handling +PREFERENCES_PROFILELOADPR;Profile Loading Priority +PREFERENCES_PROFILEPRCACHE;Profile in Cache +PREFERENCES_PROFILEPRFILE;Profile Next to the Input File +PREFERENCES_PROFILESAVECACHE;Save Processing Parameters to the Cache +PREFERENCES_PROFILESAVEINPUT;Save Processing Parameters Next to the Input File +PREFERENCES_PSPATH;Adobe Photoshop installation directory +PREFERENCES_SELECTLANG;בחר שפה +PREFERENCES_SELECTTHEME;Select theme +PREFERENCES_SHOWBASICEXIF;Exif הראה מידע +PREFERENCES_SHOWDATETIME;הראה תאריך ושעה +PREFERENCES_SHTHRESHOLD;סף קיצוץ תחתון +PREFERENCES_STARTUPIMDIR;תיקיית צילומים באתחול +PREFERENCES_TAB_BROWSER;דפדפן קבצים +PREFERENCES_TAB_COLORMGR;ניהול צבעים +PREFERENCES_TAB_GENERAL;כללי +PREFERENCES_TAB_IMPROC;עיבוד צילום +PROFILEPANEL_LABEL;פרופילי עיבוד +PROFILEPANEL_LOADDLGLABEL;הטען נתוני עיבוד +PROFILEPANEL_PCUSTOM;מותאם +PROFILEPANEL_PFILE;מקובץ +PROFILEPANEL_PLASTSAVED;נשמר אחרון +PROFILEPANEL_SAVEDLGLABEL;שמור נתוני עיבוד +PROFILEPANEL_TOOLTIPCOPY;Copy current profile to clipboard +PROFILEPANEL_TOOLTIPLOAD;הטען פרופיל מקובץ +PROFILEPANEL_TOOLTIPPASTE; Paste profile from clipboard +PROFILEPANEL_TOOLTIPSAVE;שמור פרופיל נוכחי +PROGRESSBAR_LOADING;מטעין צילום +PROGRESSBAR_LOADJPEG;JPG מטעין קובץ +PROGRESSBAR_LOADPNG;PNG מטעין קובץ +PROGRESSBAR_LOADTIFF;TIFF מטעין קובץ +PROGRESSBAR_PROCESSING;מעבד צילום +PROGRESSBAR_READY;מוכן +PROGRESSBAR_SAVEJPEG;JPG שומר קובץ +PROGRESSBAR_SAVEPNG;PNG שומר קובץ +PROGRESSBAR_SAVETIFF;TIFF שומר קובץ +QINFO_ISO;ISO +QINFO_NOEXIF;המידע לא זמין +SAVEDLG_FILEFORMAT;תצורת קובץ +SAVEDLG_JPEGQUAL;JPEG איכות +SAVEDLG_PNGCOMPR;PNG דחיסת +SAVEDLG_PUTTOQUEUEHEAD;Put to the head of the processing queue +SAVEDLG_PUTTOQUEUETAIL;Put to the end of the processing queue +SAVEDLG_PUTTOQUEUE;Put into processing queue +SAVEDLG_SAVEIMMEDIATELY;Save immediately +SAVEDLG_SAVESPP;שמור נתוני עיבוד עם הצילום +TOOLBAR_TOOLTIP_CROP;בחירת גזירה (shortcut key: C) +TOOLBAR_TOOLTIP_HAND;כלי יד (shortcut key: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;בחירת קו ישר (shortcut key: S) +TOOLBAR_TOOLTIP_WB;איזון לבן נקודתי (shortcut key: W) +TP_CACORRECTION_BLUE;כחול +TP_CACORRECTION_LABEL;C/A תיקון +TP_CACORRECTION_RED;אדום +TP_CHMIXER_BLUE;כחול +TP_CHMIXER_GREEN;ירוק +TP_CHMIXER_LABEL;מערבב ערוצים +TP_CHMIXER_RED;אדום +TP_COARSETRAF_TOOLTIP_HFLIP;הפוך אופקי +TP_COARSETRAF_TOOLTIP_ROTLEFT;סובב שמאלה +TP_COARSETRAF_TOOLTIP_ROTRIGHT;סובב ימינה +TP_COARSETRAF_TOOLTIP_VFLIP;הפוך אנכי +TP_CROP_FIXRATIO;קבע יחס +TP_CROP_GTDIAGONALS;כלל האלכסון +TP_CROP_GTNONE;ללא +TP_CROP_GTRULETHIRDS;כלל השליש +TP_CROP_GUIDETYPE;סוג מדריך +TP_CROP_H;גובה +TP_CROP_LABEL;גזור +TP_CROP_SELECTCROP;בחור גזירה +TP_CROP_W;רוחב +TP_CROP_X;x +TP_CROP_Y;y +TP_DISTORTION_AMOUNT;כמות +TP_DISTORTION_LABEL;עיוות +TP_EXPOSURE_AUTOLEVELS;מפלסים אוטומטים +TP_EXPOSURE_BLACKLEVEL;שחור +TP_EXPOSURE_BRIGHTNESS;בהירות +TP_EXPOSURE_CLIP;קצץ +TP_EXPOSURE_COMPRHIGHLIGHTS;דחיסת גוונים בהירים +TP_EXPOSURE_COMPRSHADOWS;דחיסת גוונים כהים +TP_EXPOSURE_CONTRAST;ניגודיות +TP_EXPOSURE_CURVEEDITOR;עקמת גוונים +TP_EXPOSURE_EXPCOMP;פיצוי חשיפה +TP_EXPOSURE_LABEL;חשיפה +TP_HLREC_CIELAB;CIELab Blending +TP_HLREC_COLOR;הפצת צבע +TP_HLREC_LABEL;שחזור גוונים בהירים +TP_HLREC_LUMINANCE;שחזור בהירות +TP_HLREC_METHOD;שיטה +TP_ICM_INPUTCAMERA;ברירת מחדל המצלמה +TP_ICM_INPUTCUSTOM;מותאם +TP_ICM_INPUTDLGLABEL;בחר בפרופיל צבע ייבוא +TP_ICM_INPUTEMBEDDED;השתמש בפרופיל משובץ,אם אפשר +TP_ICM_INPUTPROFILE;פרופיל ייבוא +TP_ICM_LABEL;ניהול צבע +TP_ICM_NOICM;sRGBללא ניהול צבע - ייצוא ב +TP_ICM_OUTPUTPROFILE;פרופיל ייצוא +TP_ICM_SAVEREFERENCE;Save reference image for profiling +TP_ICM_WORKINGPROFILE;פרופיל עבודה +TP_RAW_DMETHOD;שיטה +TP_RAW_FALSECOLOR;דחיית צבע מסולף +TP_RESIZE_H;גובה +TP_RESIZE_LABEL;החלף גודל +TP_RESIZE_METHOD;שיטה +TP_RESIZE_NEAREST;הקרוב +TP_RESIZE_SCALE;מידה +TP_RESIZE_W;רוחב +TP_ROTATE_DEGREE;מעלות +TP_ROTATE_LABEL;סובב +TP_ROTATE_SELECTLINE;בחור קו ישר +TP_SHADOWSHLIGHTS_HIGHLIGHTS;גוונים בהירים +TP_SHADOWSHLIGHTS_HLTONALW;רוחב גוונים +TP_SHADOWSHLIGHTS_LABEL;בהירים\כהים +TP_SHADOWSHLIGHTS_LOCALCONTR;ניגודיות מקומית +TP_SHADOWSHLIGHTS_RADIUS;רדיוס +TP_SHADOWSHLIGHTS_SHADOWS;גוונים כהים +TP_SHADOWSHLIGHTS_SHTONALW;רוחב גוונים +TP_SHARPENING_AMOUNT;כמות +TP_SHARPENING_EDRADIUS;רדיוס +TP_SHARPENING_EDTOLERANCE;סבילות לקצוות +TP_SHARPENING_HALOCONTROL;בקרת הילה +TP_SHARPENING_HCAMOUNT;כמות +TP_SHARPENING_LABEL;חידוד +TP_SHARPENING_METHOD;שיטה +TP_SHARPENING_ONLYEDGES;חידוד רק בקצוות +TP_SHARPENING_RADIUS;רדיוס +TP_SHARPENING_RLD;RL דיקונבולוציה +TP_SHARPENING_RLD_AMOUNT;כמות +TP_SHARPENING_RLD_DAMPING;ריסון +TP_SHARPENING_RLD_ITERATIONS;חזרות +TP_SHARPENING_THRESHOLD;םף +TP_SHARPENING_USM;מיסוך אי-חדות +TP_VIGNETTING_AMOUNT;כמות +TP_VIGNETTING_LABEL;תיקון פינות כהות +TP_VIGNETTING_RADIUS;רדיוס +TP_WBALANCE_AUTO;אוטומטי +TP_WBALANCE_CAMERA;מצלמה +TP_WBALANCE_CUSTOM;מותאם +TP_WBALANCE_GREEN;גיוון +TP_WBALANCE_LABEL;איזון לבן +TP_WBALANCE_METHOD;שיטה +TP_WBALANCE_SIZE;גודל +TP_WBALANCE_SPOTWB;לפי נקודה +TP_WBALANCE_TEMPERATURE;מידת חום +# Hebrew + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!ABOUT_TAB_BUILD;Version +!ABOUT_TAB_CREDITS;Credits +!ABOUT_TAB_LICENSE;License +!ABOUT_TAB_RELEASENOTES;Release Notes +!ABOUT_TAB_SPLASH;Splash +!BATCHQUEUE_AUTOSTART;Auto-start +!BATCHQUEUE_DESTFILENAME;Path and file name +!BATCH_PROCESSING;Batch Processing +!CURVEEDITOR_AXIS_IN;I: +!CURVEEDITOR_AXIS_LEFT_TAN;LT: +!CURVEEDITOR_AXIS_OUT;O: +!CURVEEDITOR_AXIS_RIGHT_TAN;RT: +!CURVEEDITOR_CURVES;Curves +!CURVEEDITOR_CURVE;Curve +!CURVEEDITOR_CUSTOM;Custom +!CURVEEDITOR_DARKS;Darks +!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_HIGHLIGHTS;Highlights +!CURVEEDITOR_LIGHTS;Lights +!CURVEEDITOR_MINMAXCPOINTS;Equalizer +!CURVEEDITOR_NURBS;Control cage +!CURVEEDITOR_PARAMETRIC;Parametric +!CURVEEDITOR_SHADOWS;Shadows +!CURVEEDITOR_TOOLTIPCOPY;Copy current curve to clipboard. +!CURVEEDITOR_TOOLTIPPASTE;Paste curve from clipboard. +!CURVEEDITOR_TYPE;Type: +!EDITWINDOW_TITLE;Image Edit +!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_FILETYPE;File type +!EXIFFILTER_METADATAFILTER;Enable metadata filters +!EXPORT_BYPASS_ALL;Select / Unselect All +!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_FF;Bypass [raw] Flat-Field +!EXPORT_BYPASS_RAW_GREENTHRESH;Bypass [raw] Green Equilibration +!EXPORT_BYPASS_RAW_LINENOISE;Bypass [raw] Line Noise Filter +!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_FASTEXPORTOPTIONS;Fast Export Options +!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_MAXHEIGHT;Maximum height: +!EXPORT_MAXWIDTH;Maximum width: +!EXPORT_PUTTOQUEUEFAST; Put to queue for fast export +!EXPORT_RAW_DMETHOD;Demosaic method +!EXTPROGTARGET_1;raw +!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_CACHECLEARFROMFULL;Clear from cache - full +!FILEBROWSER_CACHECLEARFROMPARTIAL;Clear from cache - partial +!FILEBROWSER_CACHE;Cache +!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_CURRENT_NAME;Current name: +!FILEBROWSER_DARKFRAME;Dark-frame +!FILEBROWSER_DELETEDLGMSGINCLPROC;Are you sure you want to delete the selected %1 files including a queue-processed version? +!FILEBROWSER_EXEC_CPB;Custom Profile Builder +!FILEBROWSER_EXTPROGMENU;Open with +!FILEBROWSER_FLATFIELD;Flat-Field +!FILEBROWSER_MOVETODARKFDIR;Move to dark-frames directory +!FILEBROWSER_MOVETOFLATFIELDDIR;Move to flat-fields directory +!FILEBROWSER_NEW_NAME;New name: +!FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) +!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_POPUPCOLORLABEL;Color label +!FILEBROWSER_POPUPCOPYTO;Copy to... +!FILEBROWSER_POPUPFILEOPERATIONS;File operations +!FILEBROWSER_POPUPMOVETO;Move to... +!FILEBROWSER_POPUPPROCESSFAST;Put to queue (Fast export) +!FILEBROWSER_POPUPPROFILEOPERATIONS;Processing profile operations +!FILEBROWSER_POPUPRANK0;Unrank +!FILEBROWSER_POPUPRANK1;Rank 1 * +!FILEBROWSER_POPUPRANK2;Rank 2 ** +!FILEBROWSER_POPUPRANK3;Rank 3 *** +!FILEBROWSER_POPUPRANK4;Rank 4 **** +!FILEBROWSER_POPUPRANK5;Rank 5 ***** +!FILEBROWSER_POPUPRANK;Rank +!FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!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_QUERYLABEL; Find: +!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_SELECTDARKFRAME;Select dark-frame... +!FILEBROWSER_SELECTFLATFIELD;Select flat-field... +!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 +!FILEBROWSER_SHOWCOLORLABEL4HINT;Show images labeled Blue.\nShortcut: Alt-4 +!FILEBROWSER_SHOWCOLORLABEL5HINT;Show images labeled Purple.\nShortcut: Alt-5 +!FILEBROWSER_SHOWEDITEDHINT;Show edited images.\nShortcut: 7 +!FILEBROWSER_SHOWEDITEDNOTHINT;Show not edited images.\nShortcut: 6 +!FILEBROWSER_SHOWEXIFINFO;Show Exif info.\n\nShortcuts:\ni - Multiple Editor Tabs Mode,\nAlt-i - Single Editor Tab Mode. +!FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!FILEBROWSER_SHOWRECENTLYSAVEDHINT;Show saved images.\nShortcut: Alt-7 +!FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show unsaved images.\nShortcut: Alt-6 +!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_AFTER;After +!GENERAL_ASIMAGE;As Image +!GENERAL_AUTO;Automatic +!GENERAL_BEFORE;Before +!GENERAL_CLOSE;Close +!GENERAL_FILE;File +!GENERAL_NONE;None +!GENERAL_UNCHANGED;(Unchanged) +!GENERAL_WARNING;Warning +!HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar.\nRight-click on image preview to freeze/unfreeze. +!HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram. +!HISTOGRAM_TOOLTIP_FULL;Toggle full (off) or scaled (on) histogram. +!HISTOGRAM_TOOLTIP_RAW;Show/Hide raw histogram. +!HISTORY_MSG_82;Profile changed +!HISTORY_MSG_83;S/H - Sharp mask +!HISTORY_MSG_84;Perspective correction +!HISTORY_MSG_85;LCP +!HISTORY_MSG_86;RGB curves - Luminosity mode +!HISTORY_MSG_87;Impulse noise reduction +!HISTORY_MSG_88;Impulse NR threshold +!HISTORY_MSG_89;Noise Reduction +!HISTORY_MSG_90;NR - Luminance +!HISTORY_MSG_91;NR - Chrominance master +!HISTORY_MSG_92;NR - Gamma +!HISTORY_MSG_93;CbDL - Value +!HISTORY_MSG_94;Contrast by Detail Levels +!HISTORY_MSG_95;L*a*b* - Chromaticity +!HISTORY_MSG_96;L*a*b* - a* curve +!HISTORY_MSG_97;L*a*b* - b* curve +!HISTORY_MSG_98;Demosaicing method +!HISTORY_MSG_99;Hot pixel filter +!HISTORY_MSG_100;RGB Saturation +!HISTORY_MSG_101;HSV - Hue +!HISTORY_MSG_102;HSV - Saturation +!HISTORY_MSG_103;HSV - Value +!HISTORY_MSG_104;HSV Equalizer +!HISTORY_MSG_105;Defringe +!HISTORY_MSG_106;Defringe - Radius +!HISTORY_MSG_107;Defringe - Threshold +!HISTORY_MSG_108;Highlight Compr. Threshold +!HISTORY_MSG_109;Resize - Bounding box +!HISTORY_MSG_110;Resize - Applies to +!HISTORY_MSG_111;L*a*b* - Avoid color shift +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;L*a*b* - Red/skin prot. +!HISTORY_MSG_114;DCB iterations +!HISTORY_MSG_115;False color suppression +!HISTORY_MSG_116;DCB enhancement +!HISTORY_MSG_117;Raw CA correction - Red +!HISTORY_MSG_118;Raw CA correction - Blue +!HISTORY_MSG_119;Line noise filter +!HISTORY_MSG_120;Green equilibration +!HISTORY_MSG_121;Raw CA Correction - Auto +!HISTORY_MSG_122;Dark-Frame - Auto-selection +!HISTORY_MSG_123;Dark-Frame - File +!HISTORY_MSG_124;White point correction +!HISTORY_MSG_125;Highlight preservation +!HISTORY_MSG_126;Flat-Field - File +!HISTORY_MSG_127;Flat-Field - Auto-selection +!HISTORY_MSG_128;Flat-Field - Blur radius +!HISTORY_MSG_129;Flat-Field - Blur type +!HISTORY_MSG_130;Auto distorion correction +!HISTORY_MSG_131;NR - Luma +!HISTORY_MSG_132;NR - Chroma +!HISTORY_MSG_133;Output gamma +!HISTORY_MSG_134;Free gamma +!HISTORY_MSG_135;Free gamma +!HISTORY_MSG_136;Free gamma slope +!HISTORY_MSG_137;Black level - Green 1 +!HISTORY_MSG_138;Black level - Red +!HISTORY_MSG_139;Black level - Blue +!HISTORY_MSG_140;Black level - Green 2 +!HISTORY_MSG_141;Black level - Link greens +!HISTORY_MSG_142;ES - Iterations +!HISTORY_MSG_143;ES - Quantity +!HISTORY_MSG_144;Microcontrast - Quantity +!HISTORY_MSG_145;Microcontrast - Uniformity +!HISTORY_MSG_146;Edge sharpening +!HISTORY_MSG_147;ES - Luminance only +!HISTORY_MSG_148;Microcontrast +!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_150;Post-demosaic artifact/noise red. +!HISTORY_MSG_151;Vibrance +!HISTORY_MSG_152;Vib - Pastel tones +!HISTORY_MSG_153;Vib - Saturated tones +!HISTORY_MSG_154;Vib - Protect skin-tones +!HISTORY_MSG_155;Vib - Avoid color shift +!HISTORY_MSG_156;Vib - Link pastel/saturated +!HISTORY_MSG_157;Vib - P/S threshold +!HISTORY_MSG_158;TM - Strength +!HISTORY_MSG_159;TM - Edge stopping +!HISTORY_MSG_160;TM - Scale +!HISTORY_MSG_161;TM - Reweighting iterates +!HISTORY_MSG_162;Tone Mapping +!HISTORY_MSG_163;RGB curves - Red +!HISTORY_MSG_164;RGB curves - Green +!HISTORY_MSG_165;RGB curves - Blue +!HISTORY_MSG_166;Neutral levels +!HISTORY_MSG_167;--unused-- +!HISTORY_MSG_168;L*a*b* - CC curve +!HISTORY_MSG_169;L*a*b* - CH curve +!HISTORY_MSG_170;Vibrance - HH curve +!HISTORY_MSG_171;L*a*b* - LC curve +!HISTORY_MSG_172;L*a*b* - Restrict LC +!HISTORY_MSG_173;NR - Luminance detail +!HISTORY_MSG_174;CIECAM02 +!HISTORY_MSG_175;CAM02 - CAT02 adaptation +!HISTORY_MSG_176;CAM02 - Viewing surround +!HISTORY_MSG_177;CAM02 - Scene luminosity +!HISTORY_MSG_178;CAM02 - Viewing luminosity +!HISTORY_MSG_179;CAM02 - White-point model +!HISTORY_MSG_180;CAM02 - Lightness (J) +!HISTORY_MSG_181;CAM02 - Chroma (C) +!HISTORY_MSG_182;CAM02 - Automatic CAT02 +!HISTORY_MSG_183;CAM02 - Contrast (J) +!HISTORY_MSG_184;CAM02 - Scene surround +!HISTORY_MSG_185;CAM02 - Gamut control +!HISTORY_MSG_186;CAM02 - Algorithm +!HISTORY_MSG_187;CAM02 - Red/skin prot. +!HISTORY_MSG_188;CAM02 - Brightness (Q) +!HISTORY_MSG_189;CAM02 - Contrast (Q) +!HISTORY_MSG_190;CAM02 - Saturation (S) +!HISTORY_MSG_191;CAM02 - Colorfulness (M) +!HISTORY_MSG_192;CAM02 - Hue (h) +!HISTORY_MSG_193;CAM02 - Tone curve 1 +!HISTORY_MSG_194;CAM02 - Tone curve 2 +!HISTORY_MSG_195;CAM02 - Tone curve 1 +!HISTORY_MSG_196;CAM02 - Tone curve 2 +!HISTORY_MSG_197;CAM02 - Color curve +!HISTORY_MSG_198;CAM02 - Color curve +!HISTORY_MSG_199;CAM02 - Output histograms +!HISTORY_MSG_200;CAM02 - Tone mapping +!HISTORY_MSG_201;NR - Chrominance - R&G +!HISTORY_MSG_202;NR - Chrominance - B&Y +!HISTORY_MSG_203;NR - Method +!HISTORY_MSG_204;LMMSE enhancement steps +!HISTORY_MSG_205;CAM02 - Hot/bad pixel filter +!HISTORY_MSG_206;CAT02 - Auto scene luminosity +!HISTORY_MSG_207;Defringe - Hue curve +!HISTORY_MSG_208;WB - B/R equalizer +!HISTORY_MSG_210;GF - Angle +!HISTORY_MSG_211;Graduated Filter +!HISTORY_MSG_212;VF - Strength +!HISTORY_MSG_213;Vignette Filter +!HISTORY_MSG_214;Black-and-White +!HISTORY_MSG_215;B&W - CM - Red +!HISTORY_MSG_216;B&W - CM - Green +!HISTORY_MSG_217;B&W - CM - Blue +!HISTORY_MSG_218;B&W - Gamma - Red +!HISTORY_MSG_219;B&W - Gamma - Green +!HISTORY_MSG_220;B&W - Gamma - Blue +!HISTORY_MSG_221;B&W - Color filter +!HISTORY_MSG_222;B&W - Presets +!HISTORY_MSG_223;B&W - CM - Orange +!HISTORY_MSG_224;B&W - CM - Yellow +!HISTORY_MSG_225;B&W - CM - Cyan +!HISTORY_MSG_226;B&W - CM - Magenta +!HISTORY_MSG_227;B&W - CM - Purple +!HISTORY_MSG_228;B&W - Luminance equalizer +!HISTORY_MSG_229;B&W - Luminance equalizer +!HISTORY_MSG_230;B&W - Mode +!HISTORY_MSG_231;B&W - 'Before' curve +!HISTORY_MSG_232;B&W - 'Before' curve type +!HISTORY_MSG_233;B&W - 'After' curve +!HISTORY_MSG_234;B&W - 'After' curve type +!HISTORY_MSG_235;B&W - Auto channel mixer +!HISTORY_MSG_236;--unused-- +!HISTORY_MSG_237;B&W - Mixer +!HISTORY_MSG_238;GF - Feather +!HISTORY_MSG_239;GF - Strength +!HISTORY_MSG_240;GF - Center +!HISTORY_MSG_241;VF - Feather +!HISTORY_MSG_242;VF - Roundness +!HISTORY_MSG_243;VC - Radius +!HISTORY_MSG_244;VC - Strength +!HISTORY_MSG_245;VC - Center +!HISTORY_MSG_246;L*a*b* - CL curve +!HISTORY_MSG_247;L*a*b* - LH curve +!HISTORY_MSG_248;L*a*b* - HH curve +!HISTORY_MSG_249;CbDL - Threshold +!HISTORY_MSG_250;NR - Enhanced +!HISTORY_MSG_251;B&W - Algorithm +!HISTORY_MSG_252;CbDL - Skin tar/prot +!HISTORY_MSG_253;CbDL - Reduce artifacts +!HISTORY_MSG_254;CbDL - Skin hue +!HISTORY_MSG_255;NR - Median filter +!HISTORY_MSG_256;NR - Median type +!HISTORY_MSG_257;Color Toning +!HISTORY_MSG_258;CT - Color curve +!HISTORY_MSG_259;CT - Opacity curve +!HISTORY_MSG_260;CT - a*[b*] opacity +!HISTORY_MSG_261;CT - Method +!HISTORY_MSG_262;CT - b* opacity +!HISTORY_MSG_263;CT - Shadows - Red +!HISTORY_MSG_264;CT - Shadows - Green +!HISTORY_MSG_265;CT - Shadows - Blue +!HISTORY_MSG_266;CT - Mid - Red +!HISTORY_MSG_267;CT - Mid - Green +!HISTORY_MSG_268;CT - Mid - Blue +!HISTORY_MSG_269;CT - High - Red +!HISTORY_MSG_270;CT - High - Green +!HISTORY_MSG_271;CT - High - Blue +!HISTORY_MSG_272;CT - Balance +!HISTORY_MSG_273;CT - Reset +!HISTORY_MSG_274;CT - Sat. Shadows +!HISTORY_MSG_275;CT - Sat. Highlights +!HISTORY_MSG_276;CT - Opacity +!HISTORY_MSG_277;--unused-- +!HISTORY_MSG_278;CT - Preserve luminance +!HISTORY_MSG_279;CT - Shadows +!HISTORY_MSG_280;CT - Highlights +!HISTORY_MSG_281;CT - Sat. strength +!HISTORY_MSG_282;CT - Sat. threshold +!HISTORY_MSG_283;CT - Strength +!HISTORY_MSG_284;CT - Auto sat. protection +!HISTORY_MSG_285;NR - Median - Method +!HISTORY_MSG_286;NR - Median - Type +!HISTORY_MSG_287;NR - Median - Iterations +!HISTORY_MSG_288;Flat Field - Clip control +!HISTORY_MSG_289;Flat Field - Clip control - Auto +!HISTORY_MSG_290;Black Level - Red +!HISTORY_MSG_291;Black Level - Green +!HISTORY_MSG_292;Black Level - Blue +!HISTORY_MSG_293;Film Simulation +!HISTORY_MSG_294;Film Simulation - Strength +!HISTORY_MSG_295;Film Simulation - Film +!HISTORY_MSG_296;NR - Luminance curve +!HISTORY_MSG_297;NR - Quality +!HISTORY_MSG_298;Dead pixel filter +!HISTORY_MSG_299;NR - Chrominance curve +!HISTORY_MSG_300;- +!HISTORY_MSG_301;NR - Luma control +!HISTORY_MSG_302;NR - Chroma method +!HISTORY_MSG_303;NR - Chroma method +!HISTORY_MSG_304;W - Contrast levels +!HISTORY_MSG_305;Wavelet Levels +!HISTORY_MSG_306;W - Preview +!HISTORY_MSG_307;W - Preview +!HISTORY_MSG_308;W - Preview direction +!HISTORY_MSG_309;W - ES - Detail +!HISTORY_MSG_310;W - Residual - Sky tar/prot +!HISTORY_MSG_311;W - Wavelet levels +!HISTORY_MSG_312;W - Residual - Shadows threshold +!HISTORY_MSG_313;W - Chroma - Sat/past +!HISTORY_MSG_314;W - Gamut - Reduce artifacts +!HISTORY_MSG_315;W - Residual - Contrast +!HISTORY_MSG_316;W - Gamut - Skin tar/prot +!HISTORY_MSG_317;W - Gamut - Skin hue +!HISTORY_MSG_318;W - Contrast - Highlight levels +!HISTORY_MSG_319;W - Contrast - Highlight range +!HISTORY_MSG_320;W - Contrast - Shadow range +!HISTORY_MSG_321;W - Contrast - Shadow levels +!HISTORY_MSG_322;W - Gamut - Avoid color shift +!HISTORY_MSG_323;W - ES - Local contrast +!HISTORY_MSG_324;W - Chroma - Pastel +!HISTORY_MSG_325;W - Chroma - Saturated +!HISTORY_MSG_326;W - Chroma - Method +!HISTORY_MSG_327;W - Contrast - Apply to +!HISTORY_MSG_328;W - Chroma - Link strength +!HISTORY_MSG_329;W - Toning - Opacity RG +!HISTORY_MSG_330;W - Toning - Opacity BY +!HISTORY_MSG_331;W - Contrast levels - Extra +!HISTORY_MSG_332;W - Tiling method +!HISTORY_MSG_333;W - Residual - Shadows +!HISTORY_MSG_334;W - Residual - Chroma +!HISTORY_MSG_335;W - Residual - Highlights +!HISTORY_MSG_336;W - Residual - Highlights threshold +!HISTORY_MSG_337;W - Residual - Sky hue +!HISTORY_MSG_338;W - ES - Radius +!HISTORY_MSG_339;W - ES - Strength +!HISTORY_MSG_340;W - Strength +!HISTORY_MSG_341;W - Edge performance +!HISTORY_MSG_342;W - ES - First level +!HISTORY_MSG_343;W - Chroma levels +!HISTORY_MSG_344;W - Meth chroma sl/cur +!HISTORY_MSG_345;W - ES - Local contrast +!HISTORY_MSG_346;W - ES - Local contrast method +!HISTORY_MSG_347;W - Denoise - Level 0 +!HISTORY_MSG_348;W - Denoise - Level 1 +!HISTORY_MSG_349;W - Denoise - Level 2 +!HISTORY_MSG_350;W - ES - Edge detection +!HISTORY_MSG_351;W - Residual - HH curve +!HISTORY_MSG_352;W - Background +!HISTORY_MSG_353;W - ES - Gradient sensitivity +!HISTORY_MSG_354;W - ES - Enhance +!HISTORY_MSG_355;W - ES - Threshold low +!HISTORY_MSG_356;W - ES - Threshold high +!HISTORY_MSG_357;W - Denoise - Link with ES +!HISTORY_MSG_358;W - Gamut - CH +!HISTORY_MSG_359;Hot/Dead - Threshold +!HISTORY_MSG_360;TM Gamma +!HISTORY_MSG_361;W - Final - Chroma balance +!HISTORY_MSG_362;W - Residual - Compression method +!HISTORY_MSG_363;W - Residual - Compression strength +!HISTORY_MSG_364;W - Final - Contrast balance +!HISTORY_MSG_365;W - Final - Delta balance +!HISTORY_MSG_366;W - Residual - Compression gamma +!HISTORY_MSG_367;W - ES - Local contrast curve +!HISTORY_MSG_368;W - Final - Contrast balance +!HISTORY_MSG_369;W - Final - Balance method +!HISTORY_MSG_370;W - Final - Local contrast curve +!HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s +!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 +!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). +!MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Put current image to processing queue.\nShortcut: Ctrl+b +!MAIN_BUTTON_SAVE_TOOLTIP;Save current image.\nShortcut: Ctrl+s +!MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Edit current image in external editor.\nShortcut: Ctrl+e +!MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Show/hide all side panels.\nShortcut: m +!MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen +!MAIN_FRAME_BATCHQUEUE_TOOLTIP;Processing queue.\nShortcut: Ctrl-F3 +!MAIN_FRAME_EDITOR;Editor +!MAIN_FRAME_EDITOR_TOOLTIP;Editor.\nShortcut: Ctrl-F4 +!MAIN_FRAME_FILEBROWSER_TOOLTIP;File browser.\nShortcut: Ctrl-F2 +!MAIN_MSG_EMPTYFILENAME;Filename unspecified! +!MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue-processed first. +!MAIN_MSG_NAVIGATOR;Navigator +!MAIN_MSG_OPERATIONCANCELLED;Operation cancelled +!MAIN_MSG_PATHDOESNTEXIST;The path\n\n%1\n\ndoes not exist. Please set a correct path in Preferences. +!MAIN_MSG_SETPATHFIRST;You first have to set a target path in Preferences in order to use this function! +!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_EXPORT; Fast Export +!MAIN_TAB_EXPOSURE_TOOLTIP;Shortcut: Alt-e +!MAIN_TAB_INSPECT; Inspect +!MAIN_TAB_METADATA_TOOLTIP;Shortcut: Alt-m +!MAIN_TAB_RAW;Raw +!MAIN_TAB_RAW_TOOLTIP;Shortcut: Alt-r +!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_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%. +!MAIN_TOOLTIP_PREVIEWG;Preview the Green channel.\nShortcut: g +!MAIN_TOOLTIP_PREVIEWL;Preview the Luminosity.\nShortcut: v\n\n0.299*R + 0.587*G + 0.114*B +!MAIN_TOOLTIP_PREVIEWR;Preview the Red channel.\nShortcut: r +!MAIN_TOOLTIP_SHOWHIDELP1;Show/Hide the left panel.\nShortcut: l +!MAIN_TOOLTIP_SHOWHIDERP1;Show/Hide the right panel.\nShortcut: Alt-l +!MAIN_TOOLTIP_SHOWHIDETP1;Show/Hide the top panel.\nShortcut: Shift-l +!MAIN_TOOLTIP_THRESHOLD;Threshold +!MAIN_TOOLTIP_TOGGLE;Toggle the Before/After view.\nShortcut: Shift-b +!NAVIGATOR_B;B: +!NAVIGATOR_G;G: +!NAVIGATOR_H;H: +!NAVIGATOR_LAB_A;a*: +!NAVIGATOR_LAB_B;b*: +!NAVIGATOR_LAB_L;L*: +!NAVIGATOR_NA; -- +!NAVIGATOR_R;R: +!NAVIGATOR_S;S: +!NAVIGATOR_V;V: +!NAVIGATOR_XY_FULL;Width: %1, Height: %2 +!NAVIGATOR_XY_NA;x: --, y: -- +!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_CHANNELMIXERBW;Black-and-White +!PARTIALPASTE_CHANNELMIXER;Channel mixer +!PARTIALPASTE_COLORAPP;CIECAM02 +!PARTIALPASTE_COLORTONING;Color Toning +!PARTIALPASTE_COMMONTRANSFORMPARAMS;Auto-fill +!PARTIALPASTE_DARKFRAMEAUTOSELECT;Dark-frame auto-selection +!PARTIALPASTE_DARKFRAMEFILE;Dark-frame file +!PARTIALPASTE_DEFRINGE;Defringe +!PARTIALPASTE_DETAILGROUP;Detail Settings +!PARTIALPASTE_DIRPYRDENOISE;Noise reduction +!PARTIALPASTE_DIRPYREQUALIZER;Contrast by detail levels +!PARTIALPASTE_EPD;Tone mapping +!PARTIALPASTE_EQUALIZER;Wavelet Equalizer +!PARTIALPASTE_EVERYTHING;Everything +!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_GRADIENT;Graduated filter +!PARTIALPASTE_HSVEQUALIZER;HSV equalizer +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction +!PARTIALPASTE_LABCURVE;L*a*b* adjustments +!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_PCVIGNETTE;Vignette filter +!PARTIALPASTE_PERSPECTIVE;Perspective +!PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter +!PARTIALPASTE_PREPROCESS_GREENEQUIL;Green equilibration +!PARTIALPASTE_PREPROCESS_HOTPIXFILT;Hot pixel filter +!PARTIALPASTE_PREPROCESS_LINEDENOISE;Line noise filter +!PARTIALPASTE_RAWCACORR_AUTO;CA auto-correction +!PARTIALPASTE_RAWCACORR_CABLUE;CA blue +!PARTIALPASTE_RAWCACORR_CARED;CA red +!PARTIALPASTE_RAWEXPOS_BLACK;Black levels +!PARTIALPASTE_RAWEXPOS_LINEAR;White point correction +!PARTIALPASTE_RAWEXPOS_PRESER;Highlight preservation +!PARTIALPASTE_RAWGROUP;Raw Settings +!PARTIALPASTE_RAW_DCBENHANCE;DCB enhancement +!PARTIALPASTE_RAW_DCBITERATIONS;Number of DCB iterations +!PARTIALPASTE_RAW_DMETHOD;Demosaic method +!PARTIALPASTE_RAW_FALSECOLOR;Demosaic false color suppression steps +!PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!PARTIALPASTE_RGBCURVES;RGB curves +!PARTIALPASTE_SHARPENEDGE;Edges +!PARTIALPASTE_SHARPENMICRO;Microcontrast +!PARTIALPASTE_VIBRANCE;Vibrance +!PARTIALPASTE_WAVELETGROUP;Wavelet processing +!PREFERENCES_ADD;Add +!PREFERENCES_AUTLISLOW;Low +!PREFERENCES_AUTLISMAX;Max - Average of all tiles +!PREFERENCES_AUTLISSTD;High +!PREFERENCES_AUTLISVLOW;None +!PREFERENCES_AUTLOW;Low +!PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +!PREFERENCES_AUTSTD;Standard +!PREFERENCES_BATCH_PROCESSING;Batch Processing +!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_BEHADDALL;All to 'Add' +!PREFERENCES_BEHAVIOR;Behavior +!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_BEHSETALL;All to 'Set' +!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_CURVEBBOXPOS;Position of curve copypasta buttons +!PREFERENCES_CURVEBBOXPOS_ABOVE;Above +!PREFERENCES_CURVEBBOXPOS_BELOW;Below +!PREFERENCES_CURVEBBOXPOS_LEFT;Left +!PREFERENCES_CURVEBBOXPOS_RIGHT;Right +!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_CUSTPROFBUILD;Custom Processing Profile Builder +!PREFERENCES_CUTOVERLAYBRUSH;Crop mask color/transparency +!PREFERENCES_D50;5000K +!PREFERENCES_D55;5500K +!PREFERENCES_D60;6000K +!PREFERENCES_D65;6500K +!PREFERENCES_DARKFRAMEFOUND;Found +!PREFERENCES_DARKFRAMESHOTS;shots +!PREFERENCES_DARKFRAMETEMPLATES;templates +!PREFERENCES_DARKFRAME;Dark-Frame +!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 (de-select for low resolution display) +!PREFERENCES_FILMSIMULATION;Film Simulation +!PREFERENCES_FLATFIELDFOUND;Found +!PREFERENCES_FLATFIELDSDIR;Flat-fields directory +!PREFERENCES_FLATFIELDSHOTS;shots +!PREFERENCES_FLATFIELDTEMPLATES;templates +!PREFERENCES_FLATFIELD;Flat-Field +!PREFERENCES_FLUOF2;Fluorescent F2 +!PREFERENCES_FLUOF7;Fluorescent F7 +!PREFERENCES_FLUOF11;Fluorescent F11 +!PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT;Same thumbnail height between the Editor's panel 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_GREY05;Yb=05 CIE L#30 +!PREFERENCES_GREY10;Yb=10 CIE L#40 +!PREFERENCES_GREY15;Yb=15 CIE L#45 +!PREFERENCES_GREY18;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_GREYSC18;Yb=18 CIE L#50 +!PREFERENCES_GREYSCA;Automatic +!PREFERENCES_GREYSC;Scene Yb luminance (%) +!PREFERENCES_GREY;Output device's Yb luminance (%) +!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_LANGAUTODETECT;Use system language +!PREFERENCES_LEVAUTDN;Denoising level +!PREFERENCES_LEVDN;Cell size +!PREFERENCES_LISS;Auto multi-zone smoothing +!PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders +!PREFERENCES_MAX;Maxi (Tile) +!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_MENUGROUPRANK;Group "Rank" +!PREFERENCES_MENUOPTIONS;Context Menu Options +!PREFERENCES_METADATA;Metadata +!PREFERENCES_MIN;Mini (100x115) +!PREFERENCES_MULTITABDUALMON;Multiple Editor Tabs In Own Window Mode +!PREFERENCES_MULTITAB;Multiple Editor Tabs 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_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_PROPERTY;Property +!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 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_SINGLETABVERTAB;Single Editor Tab Mode, Vertical Tabs +!PREFERENCES_SINGLETAB;Single Editor Tab Mode +!PREFERENCES_SLIMUI;Slim interface +!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_PERFORMANCE;Performance & Quality +!PREFERENCES_TAB_SOUND;Sounds +!PREFERENCES_TIMAX;High +!PREFERENCES_TINB;Number of tiles +!PREFERENCES_TISTD;Standard +!PREFERENCES_TP_LABEL;Tool panel: +!PREFERENCES_TP_USEICONORTEXT;Use tab icons instead of text +!PREFERENCES_TP_VSCROLLBAR;Hide vertical scrollbar +!PREFERENCES_TUNNELMETADATA;Copy IPTC/XMP unchanged to output file (when tagging with other program) +!PREFERENCES_USEBUNDLEDPROFILES;Use bundled profiles +!PREFERENCES_USESYSTEMTHEME;Use system theme +!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_WORKFLOW;Layout +!PROFILEPANEL_COPYPPASTE;Parameters to copy +!PROFILEPANEL_GLOBALPROFILES;Bundled profiles +!PROFILEPANEL_LOADPPASTE;Parameters to load +!PROFILEPANEL_MODE_TIP;Processing profile fill mode.\n\nButton pressed: partial profiles will be converted to full profiles; the missing values will be replaced with hard-coded defaults.\n\nButton released: profiles will be applied as they are, altering only those values which they contain. +!PROFILEPANEL_MYPROFILES;My profiles +!PROFILEPANEL_PASTEPPASTE;Parameters to paste +!PROFILEPANEL_PINTERNAL;Neutral +!PROFILEPANEL_SAVEPPASTE;Parameters to save +!PROGRESSBAR_LOADINGTHUMBS;Loading thumbnails... +!PROGRESSBAR_NOIMAGES;No images found +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing profile saved +!PROGRESSBAR_SNAPSHOT_ADDED;Snapshot added +!PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists +!SAVEDLG_FORCEFORMATOPTS;Force saving options +!SAVEDLG_SUBSAMP;Subsampling +!SAVEDLG_SUBSAMP_1;Best compression +!SAVEDLG_SUBSAMP_2;Balanced +!SAVEDLG_SUBSAMP_3;Best quality +!SAVEDLG_SUBSAMP_TOOLTIP;Best compression: 4:1:1\nBalanced: 4:2:2\nBest quality: 4:4:4 +!SAVEDLG_TIFFUNCOMPRESSED;Uncompressed TIFF +!SAVEDLG_WARNFILENAME;File will be named +!SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. +!THRESHOLDSELECTOR_BL;Bottom-left +!THRESHOLDSELECTOR_BR;Bottom-right +!THRESHOLDSELECTOR_B;Bottom +!THRESHOLDSELECTOR_HINT;Hold the Shift key to move individual control points. +!THRESHOLDSELECTOR_TL;Top-left +!THRESHOLDSELECTOR_TR;Top-right +!THRESHOLDSELECTOR_T;Top +!TP_BWMIX_ALGO;Algorithm OYCPM +!TP_BWMIX_ALGO_LI;Linear +!TP_BWMIX_ALGO_SP;Special effects +!TP_BWMIX_ALGO_TOOLTIP;Linear: will produce a normal linear response.\nSpecial effects: will produce special effects by mixing channels non-linearly. +!TP_BWMIX_AUTOCH;Auto +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing Channel Mixer. +!TP_BWMIX_CC_ENABLED;Adjust complementary color +!TP_BWMIX_CC_TOOLTIP;Enable to allow automatic adjustment of complementary colors in ROYGCBPM mode. +!TP_BWMIX_CHANNEL;Luminance equalizer +!TP_BWMIX_CURVEEDITOR1;'Before' curve +!TP_BWMIX_CURVEEDITOR2;'After' curve +!TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Tone curve, after B&W conversion, at the end of treatment. +!TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Tone curve, just before B&W conversion.\nMay take into account the color components. +!TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H).\nPay attention to extreme values as they may cause artifacts. +!TP_BWMIX_FILTER;Color Filter +!TP_BWMIX_FILTER_BLUEGREEN;Blue-Green +!TP_BWMIX_FILTER_BLUE;Blue +!TP_BWMIX_FILTER_GREENYELLOW;Green-Yellow +!TP_BWMIX_FILTER_GREEN;Green +!TP_BWMIX_FILTER_NONE;None +!TP_BWMIX_FILTER_PURPLE;Purple +!TP_BWMIX_FILTER_REDYELLOW;Red-Yellow +!TP_BWMIX_FILTER_RED;Red +!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. +!TP_BWMIX_FILTER_YELLOW;Yellow +!TP_BWMIX_GAMMA;Gamma Correction +!TP_BWMIX_GAM_TOOLTIP;Correct gamma for each RGB channel. +!TP_BWMIX_LABEL;Black-and-White +!TP_BWMIX_MET;Method +!TP_BWMIX_MET_CHANMIX;Channel Mixer +!TP_BWMIX_MET_DESAT;Desaturation +!TP_BWMIX_MET_LUMEQUAL;Luminance Equalizer +!TP_BWMIX_MIXC;Mixer +!TP_BWMIX_NEUTRAL;Reset mixer +!TP_BWMIX_NEUTRAL_TIP;Reset all values (Color Filter, Channel Mixer) to default. +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all the mixer options.\n"Total" displays the sum of the RGB values:\n- always 100% in relative mode\n- higher (lighter) or lower (darker) than 100% in absolute mode. +!TP_BWMIX_RGB_TOOLTIP;Mix the RGB channels. Use presets for guidance.\nPay attention to negative values that may cause artifacts or erratic behavior. +!TP_BWMIX_SETTING;Presets +!TP_BWMIX_SETTING_TOOLTIP;Different presets (film, landscape, etc.) or manual Channel Mixer settings. +!TP_BWMIX_SET_HIGHCONTAST;High contrast +!TP_BWMIX_SET_HIGHSENSIT;High Sensitivity +!TP_BWMIX_SET_HYPERPANCHRO;Hyper Panchromatic +!TP_BWMIX_SET_INFRARED;Infrared +!TP_BWMIX_SET_LANDSCAPE;Landscape +!TP_BWMIX_SET_LOWSENSIT;Low Sensitivity +!TP_BWMIX_SET_LUMINANCE;Luminance +!TP_BWMIX_SET_NORMCONTAST;Normal Contrast +!TP_BWMIX_SET_ORTHOCHRO;Orthochromatic +!TP_BWMIX_SET_PANCHRO;Panchromatic +!TP_BWMIX_SET_PORTRAIT;Portrait +!TP_BWMIX_SET_RGBABS;Absolute RGB +!TP_BWMIX_SET_RGBREL;Relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Relative ROYGCBPM +!TP_BWMIX_TCMODE_FILMLIKE;B&W Film-like +!TP_BWMIX_TCMODE_SATANDVALBLENDING;B&W Saturation and Value Blending +!TP_BWMIX_TCMODE_STANDARD;B&W Standard +!TP_BWMIX_TCMODE_WEIGHTEDSTD;B&W Weighted Standard +!TP_BWMIX_VAL;L +!TP_CHROMATABERR_LABEL;Chromatic Aberration +!TP_COLORAPP_ADAPTSCENE;Scene luminosity +!TP_COLORAPP_ADAPTSCENE_TOOLTIP;Absolute luminance of the scene environement (cd/m²).\n1) Calculated from the Exif data:\nShutter speed - ISO speed - F number - camera exposure correction.\n2) Calculated from the raw white point and RT's Exposure Compensation slider. +!TP_COLORAPP_ADAPTVIEWING;Viewing luminosity (cd/m²) +!TP_COLORAPP_ADAPTVIEWING_TOOLTIP;Absolute luminance of the viewing environnement\n(usually 16cd/m²). +!TP_COLORAPP_ADAP_AUTO_TOOLTIP;If the checkbox is checked (recommended) RawTherapee calculates an optimum value from Exif data.\nTo set the value manually, uncheck the checkbox first. +!TP_COLORAPP_ALGO;Algorithm +!TP_COLORAPP_ALGO_ALL;All +!TP_COLORAPP_ALGO_JC;Lightness + Chroma (JC) +!TP_COLORAPP_ALGO_JS;Lightness + Saturation (JS) +!TP_COLORAPP_ALGO_QM;Brightness + Colorfulness (QM) +!TP_COLORAPP_ALGO_TOOLTIP;Lets you choose between parameter subsets or all parameters. +!TP_COLORAPP_BADPIXSL;Hot/bad pixel filter +!TP_COLORAPP_BADPIXSL_TOOLTIP;Suppression of hot/bad (brightly colored) pixels.\n0 = No effect\n1 = Median\n2 = Gaussian.\nAlternatively, adjust the image to avoid very dark shadows.\n\nThese artifacts are due to limitations of CIECAM02. +!TP_COLORAPP_BRIGHT;Brightness (Q) +!TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from L*a*b* and RGB brightness. +!TP_COLORAPP_CHROMA;Chroma (C) +!TP_COLORAPP_CHROMA_M;Colorfulnes (M) +!TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM02 differs from L*a*b* and RGB colorfulness. +!TP_COLORAPP_CHROMA_S;Saturation (S) +!TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from L*a*b* and RGB saturation. +!TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from L*a*b* and RGB chroma. +!TP_COLORAPP_CIECAT_DEGREE;CAT02 adaptation +!TP_COLORAPP_CONTRAST;Contrast (J) +!TP_COLORAPP_CONTRAST_Q;Contrast (Q) +!TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrast in CIECAM02 for the Q slider; it differs from L*a*b* and RGB contrast. +!TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from L*a*b* and RGB contrast. +!TP_COLORAPP_CURVEEDITOR1;Tone curve 1 +!TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L* (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of J or Q after CIECAM02.\n\nJ and Q are not shown in the main histogram panel.\n\nFor final output refer to the main histogram panel. +!TP_COLORAPP_CURVEEDITOR2;Tone curve 2 +!TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Same usage as with the second exposure tone curve. +!TP_COLORAPP_CURVEEDITOR3;Color curve +!TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Adjust either chroma, saturation or colorfulness.\n\nShows the histogram of chromaticity (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of C, s or M after CIECAM02.\n\nC, s and M are not shown in the main histogram panel.\nFor final output refer to the main histogram panel. +!TP_COLORAPP_DATACIE;CIECAM02 output histograms in curves +!TP_COLORAPP_DATACIE_TOOLTIP;When enabled, histograms in CIECAM02 curves show approximate values/ranges for J or Q, and C, s or M after the CIECAM02 adjustments.\nThis selection does not impact the main histogram panel.\n\nWhen disabled, histograms in CIECAM02 curves show L*a*b* values before CIECAM02 adjustments. +!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RawTherapee calculates an optimum value, which is then used by CAT02, and also for the entire CIECAM02.\nTo set the value manually, uncheck the check-box first (values above 65 are recommended). +!TP_COLORAPP_DEGREE_TOOLTIP;Amount of CIE Chromatic Adaptation Transform 2002. +!TP_COLORAPP_GAMUT;Gamut control (L*a*b*) +!TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in L*a*b* mode. +!TP_COLORAPP_HUE;Hue (h) +!TP_COLORAPP_HUE_TOOLTIP;Hue (h) - angle between 0° and 360°. +!TP_COLORAPP_LABEL;CIE Color Appearance Model 2002 +!TP_COLORAPP_LABEL_CAM02;Image Adjustments +!TP_COLORAPP_LABEL_SCENE;Scene Conditions +!TP_COLORAPP_LABEL_VIEWING;Viewing Conditions +!TP_COLORAPP_LIGHT;Lightness (J) +!TP_COLORAPP_LIGHT_TOOLTIP;Lightness in CIECAM02 differs from L*a*b* and RGB lightness. +!TP_COLORAPP_MODEL;WP Model +!TP_COLORAPP_MODEL_TOOLTIP;White-Point Model.\n\nWB [RT] + [output]: RT's white balance is used for the scene, CIECAM02 is set to D50, and the output device's white balance is set in Preferences > Color Management.\n\nWB [RT+CAT02] + [output]: RT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences - Color Management. +!TP_COLORAPP_RSTPRO;Red & skin-tones protection +!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin-tones protection affects both sliders and curves. +!TP_COLORAPP_SHARPCIE;--unused-- +!TP_COLORAPP_SHARPCIE_TOOLTIP;--unused-- +!TP_COLORAPP_SURROUND;Surround +!TP_COLORAPP_SURROUND_AVER;Average +!TP_COLORAPP_SURROUND_DARK;Dark +!TP_COLORAPP_SURROUND_DIM;Dim +!TP_COLORAPP_SURROUND_EXDARK;Extremly Dark (Cutsheet) +!TP_COLORAPP_SURROUND_TOOLTIP;Changes tones and colors to take into account the viewing conditions of the output device.\n\nAverage: Average light environment (standard). The image will not change.\n\nDim: Dim environment (TV). The image will become slighty dark.\n\nDark: Dark environment (projector). The image will become more dark.\n\nExtremly Dark: Extremly dark environment (cutsheet). The image will become very dark. +!TP_COLORAPP_SURSOURCE;Dark surround +!TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if image has a dark border. +!TP_COLORAPP_TCMODE_BRIGHTNESS;Brightness +!TP_COLORAPP_TCMODE_CHROMA;Chroma +!TP_COLORAPP_TCMODE_COLORF;Colorfulness +!TP_COLORAPP_TCMODE_LABEL1;Curve mode 1 +!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_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] +!TP_COLORAPP_WBRT;WB [RT] + [output] +!TP_COLORTONING_AB;o C/L +!TP_COLORTONING_AUTOSAT;Automatic +!TP_COLORTONING_BALANCE;Balance +!TP_COLORTONING_BY;o C/L +!TP_COLORTONING_CHROMAC;Opacity +!TP_COLORTONING_COLOR;Color +!TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;Chroma opacity as a function of luminance oC=f(L) +!TP_COLORTONING_HIGHLIGHT;Highlights +!TP_COLORTONING_HUE;Hue +!TP_COLORTONING_LABEL;Color Toning +!TP_COLORTONING_LAB;L*a*b* blending +!TP_COLORTONING_LUMAMODE;Preserve luminance +!TP_COLORTONING_LUMAMODE_TOOLTIP;If enabled, when you change color (red, green, cyan, blue, etc.) the luminance of each pixel is preserved. +!TP_COLORTONING_LUMA;Luminance +!TP_COLORTONING_METHOD;Method +!TP_COLORTONING_METHOD_TOOLTIP;"L*a*b* blending", "RGB sliders" and "RGB curves" use interpolated color blending.\n"Color balance (Shadows/Midtones/Highlights)" and "Saturation 2 colors" use direct colors.\n\nThe Black-and-White tool can be enabled when using any color toning method, which allows for color toning. +!TP_COLORTONING_MIDTONES;Midtones +!TP_COLORTONING_NEUTRAL;Reset sliders +!TP_COLORTONING_NEUTRAL_TIP;Reset all values (Shadows, Midtones, Highlights) to default. +!TP_COLORTONING_OPACITY;Opacity +!TP_COLORTONING_RGBCURVES;RGB - Curves +!TP_COLORTONING_RGBSLIDERS;RGB - Sliders +!TP_COLORTONING_SATURATEDOPACITY;Strength +!TP_COLORTONING_SATURATIONTHRESHOLD;Threshold +!TP_COLORTONING_SA;Saturation Protection +!TP_COLORTONING_SHADOWS;Shadows +!TP_COLORTONING_SPLITCOCO;Color Balance Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITCO;Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITLR;Saturation 2 colors +!TP_COLORTONING_STRENGTH;Strength +!TP_COLORTONING_STR;Strength +!TP_COLORTONING_TWO2;Special chroma '2 colors' +!TP_COLORTONING_TWOALL;Special chroma +!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_GTFRAME;Frame +!TP_CROP_GTGRID;Grid +!TP_CROP_GTHARMMEANS;Harmonic Means +!TP_CROP_GTTRIANGLE1;Golden Triangles 1 +!TP_CROP_GTTRIANGLE2;Golden Triangles 2 +!TP_CROP_PPI;PPI= +!TP_DARKFRAME_AUTOSELECT;Auto-selection +!TP_DARKFRAME_LABEL;Dark-Frame +!TP_DEFRINGE_LABEL;Defringe +!TP_DEFRINGE_RADIUS;Radius +!TP_DEFRINGE_THRESHOLD;Threshold +!TP_DIRPYRDENOISE_33;3×3 strong +!TP_DIRPYRDENOISE_55SOFT;5×5 +!TP_DIRPYRDENOISE_55;5×5 strong +!TP_DIRPYRDENOISE_77;7×7 (slow) +!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_ABM;Chroma only +!TP_DIRPYRDENOISE_AUTO;Automatic global +!TP_DIRPYRDENOISE_AUTO_TOOLTIP;Try to evaluate chroma noise\nBe careful, this calculation is average, and is quite subjective ! +!TP_DIRPYRDENOISE_AUT;Automatic global +!TP_DIRPYRDENOISE_BLUE;Chrominance - Blue-Yellow +!TP_DIRPYRDENOISE_C2TYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CCCURVE;Chrominance curve +!TP_DIRPYRDENOISE_CHROMAFR;Chrominance +!TP_DIRPYRDENOISE_CHROMA;Chrominance - Master +!TP_DIRPYRDENOISE_CTYPE;Auto method +!TP_DIRPYRDENOISE_CTYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nAutomatic multi-zones\nNo preview - works only during saving, but using the "Preview" method by matching the tile size and center to the preview size and center you can get an idea of the expected results.\nThe image is divided into tiles (about 10 to 70 depending on image size) and each tile receives its own chrominance noise reduction settings.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CURVEEDITOR_CC;Chroma +!TP_DIRPYRDENOISE_CURVEEDITOR_CC_TOOLTIP;Increase (multiply) the value of all chrominance sliders.\nThis curve lets you adjust the strength of chromatic noise reduction as a function of chromaticity, for instance to increase the action in areas of low saturation and to decrease it in those of high saturation. +!TP_DIRPYRDENOISE_CURVEEDITOR_L_TOOLTIP;Modulates action of 'Luminance' denoise +!TP_DIRPYRDENOISE_CUR;Curve +!TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on the gamma of the input color profile. An sRGB gamma is assumed, thus if the image uses an input color profile of a different gamma, the effects of luminance noise reduction will differ. +!TP_DIRPYRDENOISE_ENH;Enhanced mode +!TP_DIRPYRDENOISE_ENH_TOOLTIP;Increases noise reduction quality at the expense of a 20% processing time increase. +!TP_DIRPYRDENOISE_GAMMA;Gamma +!TP_DIRPYRDENOISE_GAMMA_TOOLTIP;Gamma varies noise reduction strength across the range of tones. Smaller values will target shadows, while larger values will stretch the effect to the brighter tones. +!TP_DIRPYRDENOISE_LABEL;Noise Reduction +!TP_DIRPYRDENOISE_LABM;L*a*b* +!TP_DIRPYRDENOISE_LAB;L*a*b* +!TP_DIRPYRDENOISE_LCURVE;Luminance curve +!TP_DIRPYRDENOISE_LDETAIL;Luminance - Detail +!TP_DIRPYRDENOISE_LM;Luminance only +!TP_DIRPYRDENOISE_LPLABM;Weighted L* (little) + a*b* (normal) +!TP_DIRPYRDENOISE_LTYPE;Luminance control +!TP_DIRPYRDENOISE_LUMAFR;Luminance +!TP_DIRPYRDENOISE_LUMAFR_TOOLTIP;Wavelet on luminance and Fourier transform for luminance detail +!TP_DIRPYRDENOISE_LUMA;Luminance +!TP_DIRPYRDENOISE_MANU;Manual +!TP_DIRPYRDENOISE_MAN;Manual +!TP_DIRPYRDENOISE_MEDMETHOD;Median method +!TP_DIRPYRDENOISE_MEDTYPE;Median type +!TP_DIRPYRDENOISE_MED;Median Filter +!TP_DIRPYRDENOISE_MED_TOOLTIP;Enabled median denoising +!TP_DIRPYRDENOISE_METHOD11;Quality +!TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. +!TP_DIRPYRDENOISE_METHOD;Method +!TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or L*a*b* methods can be used.\n\nFor non-raw images the L*a*b* method will be used, regardless of the selection. +!TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - +!TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 +!TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. +!TP_DIRPYRDENOISE_PASSES;Median iterations +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PON;Auto multi-zones +!TP_DIRPYRDENOISE_PREVLABEL;Preview size=%1, Center: Px=%2 Py=%3 +!TP_DIRPYRDENOISE_PREV;Preview +!TP_DIRPYRDENOISE_PRE;Preview multi-zones +!TP_DIRPYRDENOISE_RED;Chrominance - Red-Green +!TP_DIRPYRDENOISE_RGBM;RGB +!TP_DIRPYRDENOISE_RGB;RGB +!TP_DIRPYRDENOISE_SHALBI;High +!TP_DIRPYRDENOISE_SHAL;Standard +!TP_DIRPYRDENOISE_SLI;Slider +!TP_DIRPYRDENOISE_SOFT;3x3 +!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_LUMAFINEST;Finest +!TP_DIRPYREQUALIZER_LUMANEUTRAL;Neutral +!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_THRESHOLD;Threshold +!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;Auto Distortion Correction +!TP_DISTORTION_AUTO_TIP;Correct lens distortion automatically for some cameras (Micro 4/3, some compact digital cameras, etc.). +!TP_EPD_EDGESTOPPING;Edge stopping +!TP_EPD_GAMMA;Gamma +!TP_EPD_LABEL;Tone Mapping +!TP_EPD_REWEIGHTINGITERATES;Reweighting iterates +!TP_EPD_SCALE;Scale +!TP_EPD_STRENGTH;Strength +!TP_EPD_TOOLTIP;Tone mapping is possible in L*a*b* mode (standard) and CIECAM02 mode.\n\nWhen in L*a*b* mode, tone mapping can also be used on the residual image of the Wavelet Levels tool.\n\nTo engage CIECAM02 tone mapping mode enable the following settings:\n1. CIECAM02\n2. Algorithm="Brightness + Colorfulness (QM)"\n3. "Tone mapping using CIECAM02 brightness (Q)" +!TP_EXPOSURE_AUTOLEVELS_TIP;Toggles execution of Auto Levels to automatically set Exposure slider values based on an image analysis.\nEnables Highlight Reconstruction if necessary. +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in Auto Levels operation. +!TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Highlight compression threshold +!TP_EXPOSURE_CURVEEDITOR1;Tone curve 1 +!TP_EXPOSURE_CURVEEDITOR2;Tone curve 2 +!TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Please refer to the "Exposure > Tone Curves" RawPedia article to learn how to achieve the best results by using two tone curves. +!TP_EXPOSURE_SATURATION;Saturation +!TP_EXPOSURE_TCMODE_FILMLIKE;Film-like +!TP_EXPOSURE_TCMODE_LABEL1;Curve mode 1 +!TP_EXPOSURE_TCMODE_LABEL2;Curve mode 2 +!TP_EXPOSURE_TCMODE_LUMINANCE;Luminance +!TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Saturation and Value Blending +!TP_EXPOSURE_TCMODE_STANDARD;Standard +!TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard +!TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points +!TP_EXPOS_WHITEPOINT_LABEL;Raw White Points +!TP_FILMSIMULATION_LABEL;Film Simulation +!TP_FILMSIMULATION_STRENGTH;Strength +!TP_FILMSIMULATION_ZEROCLUTSFOUND;Set HaldCLUT directory in Preferences +!TP_FLATFIELD_AUTOSELECT;Auto-selection +!TP_FLATFIELD_BLURRADIUS;Blur radius +!TP_FLATFIELD_BLURTYPE;Blur type +!TP_FLATFIELD_BT_AREA;Area +!TP_FLATFIELD_BT_HORIZONTAL;Horizontal +!TP_FLATFIELD_BT_VERTHORIZ;Vertical + Horizontal +!TP_FLATFIELD_BT_VERTICAL;Vertical +!TP_FLATFIELD_CLIPCONTROL;Clip control +!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. +!TP_FLATFIELD_LABEL;Flat-Field +!TP_GAMMA_CURV;Gamma +!TP_GAMMA_FREE;Free gamma +!TP_GAMMA_OUTPUT;Output gamma +!TP_GAMMA_SLOP;Slope (linear) +!TP_GENERAL_11SCALE_TOOLTIP;The effects of this tool are only visible or only accurate at a preview scale of 1:1. +!TP_GRADIENT_CENTER;Center +!TP_GRADIENT_CENTER_X;Center X +!TP_GRADIENT_CENTER_X_TOOLTIP;Shift gradient to the left (negative values) or right (positive values). +!TP_GRADIENT_CENTER_Y;Center Y +!TP_GRADIENT_CENTER_Y_TOOLTIP;Shift gradient up (negative values) or down (positive values). +!TP_GRADIENT_DEGREE;Angle +!TP_GRADIENT_DEGREE_TOOLTIP;Rotation angle in degrees. +!TP_GRADIENT_FEATHER;Feather +!TP_GRADIENT_FEATHER_TOOLTIP;Gradient width in percent of the image diagonal. +!TP_GRADIENT_LABEL;Graduated Filter +!TP_GRADIENT_STRENGTH;Strength +!TP_GRADIENT_STRENGTH_TOOLTIP;Filter strength in stops. +!TP_HLREC_BLEND;Blend +!TP_HLREC_ENA_TOOLTIP;Could be activated by Auto Levels. +!TP_HSVEQUALIZER_CHANNEL;Channel +!TP_HSVEQUALIZER_HUE;H +!TP_HSVEQUALIZER_LABEL;HSV Equalizer +!TP_HSVEQUALIZER_SAT;S +!TP_HSVEQUALIZER_VAL;V +!TP_ICM_BLENDCMSMATRIX;Blend ICC highlights with matrix +!TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover clipped highlights when using LUT-based ICC profiles. +!TP_ICM_DCPILLUMINANT;Illuminant +!TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolated +!TP_ICM_DCPILLUMINANT_TOOLTIP;Select which embedded DCP illuminant to employ. Default is "interpolated" which is a mix between the two based on white balance. The setting is only enabled if a Dual-Illuminant DCP with interpolation support is selected. +!TP_ICM_INPUTCAMERAICC;Auto-matched camera profile +!TP_ICM_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input color profiles. These profiles are more precise than simpler matrix ones. They are not available for all cameras. These profiles are stored in the /iccprofiles/input and /dcpprofiles folders and are automatically retrieved based on a file name matching to the exact model name of the camera. +!TP_ICM_INPUTCAMERA_TOOLTIP;Use a simple color matrix from dcraw, an enhanced RawTherapee version (whichever is available based on camera model) or one embedded in the DNG. +!TP_ICM_INPUTCUSTOM_TOOLTIP;Select your own DCP/ICC color profile file for the camera. +!TP_ICM_INPUTEMBEDDED_TOOLTIP;Use color profile embedded in non-raw files. +!TP_ICM_INPUTNONE;No profile +!TP_ICM_INPUTNONE_TOOLTIP;Use no input color profile at all.\nUse only in special cases. +!TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance +!TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. The result can be used for calibration purposes and generation of a camera profile. +!TP_ICM_TONECURVE;Use DCP's tone curve +!TP_ICM_TONECURVE_TOOLTIP;Employ the embedded DCP tone curve. The setting is only enabled if the selected DCP has a tone curve. +!TP_IMPULSEDENOISE_LABEL;Impulse Noise Reduction +!TP_IMPULSEDENOISE_THRESH;Threshold +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid color shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction. +!TP_LABCURVE_BRIGHTNESS;Lightness +!TP_LABCURVE_CHROMATICITY;Chromaticity +!TP_LABCURVE_CHROMA_TOOLTIP;To apply B&W toning, set Chromaticity to -100. +!TP_LABCURVE_CONTRAST;Contrast +!TP_LABCURVE_CURVEEDITOR;Luminance Curve +!TP_LABCURVE_CURVEEDITOR_A_RANGE1;Green Saturated +!TP_LABCURVE_CURVEEDITOR_A_RANGE2;Green Pastel +!TP_LABCURVE_CURVEEDITOR_A_RANGE3;Red Pastel +!TP_LABCURVE_CURVEEDITOR_A_RANGE4;Red Saturated +!TP_LABCURVE_CURVEEDITOR_B_RANGE1;Blue Saturated +!TP_LABCURVE_CURVEEDITOR_B_RANGE2;Blue Pastel +!TP_LABCURVE_CURVEEDITOR_B_RANGE3;Yellow Pastel +!TP_LABCURVE_CURVEEDITOR_B_RANGE4;Yellow Saturated +!TP_LABCURVE_CURVEEDITOR_CC;CC +!TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutral +!TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Dull +!TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastel +!TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Saturated +!TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Chromaticity according to chromaticity C=f(C) +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to hue C=f(H) +!TP_LABCURVE_CURVEEDITOR_CL;CL +!TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Chromaticity according to luminance C=f(L) +!TP_LABCURVE_CURVEEDITOR_HH;HH +!TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Hue according to hue H=f(H) +!TP_LABCURVE_CURVEEDITOR_LC;LC +!TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminance according to chromaticity L=f(C) +!TP_LABCURVE_CURVEEDITOR_LH;LH +!TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H) +!TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminance according to luminance L=f(L) +!TP_LABCURVE_LABEL;L*a*b* Adjustments +!TP_LABCURVE_LCREDSK;Restrict LC to red and skin-tones +!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_LENSGEOM_AUTOCROP;Auto-Crop +!TP_LENSGEOM_FILL;Auto-fill +!TP_LENSGEOM_LABEL;Lens / Geometry +!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_USECA;Chromatic aberration correction +!TP_LENSPROFILE_USEDIST;Distortion correction +!TP_LENSPROFILE_USEVIGN;Vignetting correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Resets exposure sliders to neutral values.\nApplies to the same controls that Auto Levels applies to, regardless of whether you used Auto Levels or not. +!TP_PCVIGNETTE_FEATHER;Feather +!TP_PCVIGNETTE_FEATHER_TOOLTIP;Feathering:\n0 = corners only,\n50 = halfway to center,\n100 = to center. +!TP_PCVIGNETTE_LABEL;Vignette Filter +!TP_PCVIGNETTE_ROUNDNESS;Roundness +!TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness:\n0 = rectangle,\n50 = fitted ellipse,\n100 = circle. +!TP_PCVIGNETTE_STRENGTH;Strength +!TP_PCVIGNETTE_STRENGTH_TOOLTIP;Filter strength in stops (reached in corners). +!TP_PERSPECTIVE_HORIZONTAL;Horizontal +!TP_PERSPECTIVE_LABEL;Perspective +!TP_PERSPECTIVE_VERTICAL;Vertical +!TP_PFCURVE_CURVEEDITOR_CH;Hue +!TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Controls defringe strength by color.\nHigher = more,\nLower = less. +!TP_PREPROCESS_DEADPIXFILT;Dead pixel filter +!TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Tries to suppress dead pixels. +!TP_PREPROCESS_GREENEQUIL;Green equilibration +!TP_PREPROCESS_HOTPIXFILT;Hot pixel filter +!TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Tries to suppress hot pixels. +!TP_PREPROCESS_LABEL;Preprocessing +!TP_PREPROCESS_LINEDENOISE;Line noise filter +!TP_PREPROCESS_NO_FOUND;None found +!TP_RAWCACORR_AUTO;Auto-correction +!TP_RAWCACORR_CABLUE;Blue +!TP_RAWCACORR_CARED;Red +!TP_RAWEXPOS_BLACKS;Black Levels +!TP_RAWEXPOS_BLACK_0;Green 1 (lead) +!TP_RAWEXPOS_BLACK_1;Red +!TP_RAWEXPOS_BLACK_2;Blue +!TP_RAWEXPOS_BLACK_3;Green 2 +!TP_RAWEXPOS_BLACK_BLUE;Blue +!TP_RAWEXPOS_BLACK_GREEN;Green +!TP_RAWEXPOS_BLACK_RED;Red +!TP_RAWEXPOS_LINEAR;White-point correction +!TP_RAWEXPOS_PRESER;Highlight preservation +!TP_RAWEXPOS_RGB;Red, Green, Blue +!TP_RAWEXPOS_TWOGREEN;Link greens +!TP_RAW_DCBENHANCE;DCB enhancement +!TP_RAW_DCBITERATIONS;Number of DCB iterations +!TP_RAW_DMETHOD_PROGRESSBAR;%1 demosaicing... +!TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Demosaicing refinement... +!TP_RAW_DMETHOD_TOOLTIP;Note: IGV and LMMSE are dedicated to high ISO images to aid in noise reduction without leading to maze patterns, posterization or a washed-out look. +!TP_RAW_HD;Threshold +!TP_RAW_HD_TOOLTIP;Lower values make hot/dead pixel detection more aggressive, but false positives may lead to artifacts. If you notice any artifacts appearing when enabling the Hot/Dead Pixel Filters, gradually increase the threshold value until they disappear. +!TP_RAW_LABEL;Demosaicing +!TP_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!TP_RAW_LMMSE_TOOLTIP;Adds gamma (step 1), median (steps 2-4) and refinement (steps 5-6) to reduce artifacts and improve the signal-to-noise ratio. +!TP_RAW_SENSOR_BAYER_LABEL;Sensor with Bayer Matrix +!TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;3-pass gives best results (recommended for low ISO images).\n1-pass is almost undistinguishable from 3-pass for high ISO images and is faster. +!TP_RAW_SENSOR_XTRANS_LABEL;Sensor with X-Trans Matrix +!TP_RESIZE_APPLIESTO;Applies to: +!TP_RESIZE_CROPPEDAREA;Cropped Area +!TP_RESIZE_FITBOX;Bounding Box +!TP_RESIZE_FULLIMAGE;Full Image +!TP_RESIZE_HEIGHT;Height +!TP_RESIZE_LANCZOS;Lanczos +!TP_RESIZE_SPECIFY;Specify: +!TP_RESIZE_WIDTH;Width +!TP_RGBCURVES_BLUE;B +!TP_RGBCURVES_CHANNEL;Channel +!TP_RGBCURVES_GREEN;G +!TP_RGBCURVES_LABEL;RGB Curves +!TP_RGBCURVES_LUMAMODE;Luminosity mode +!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_RGBCURVES_RED;R +!TP_SAVEDIALOG_OK_TIP;Shortcut: Ctrl-Enter +!TP_SHADOWSHLIGHTS_SHARPMASK;Sharp mask +!TP_SHARPENEDGE_AMOUNT;Quantity +!TP_SHARPENEDGE_LABEL;Edges +!TP_SHARPENEDGE_PASSES;Iterations +!TP_SHARPENEDGE_THREE;Luminance only +!TP_SHARPENING_TOOLTIP;Expect a slightly different effect when using with CIECAM02. If difference is observed, adjust to taste. +!TP_SHARPENMICRO_AMOUNT;Quantity +!TP_SHARPENMICRO_LABEL;Microcontrast +!TP_SHARPENMICRO_MATRIX;3×3 matrix instead of 5×5 +!TP_SHARPENMICRO_UNIFORMITY;Uniformity +!TP_VIBRANCE_AVOIDCOLORSHIFT;Avoid color shift +!TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Red/Purple +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Red +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Red/Yellow +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Yellow +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Hue according to hue H=f(H) +!TP_VIBRANCE_LABEL;Vibrance +!TP_VIBRANCE_PASTELS;Pastel Tones +!TP_VIBRANCE_PASTSATTOG;Link pastel and saturated tones +!TP_VIBRANCE_PROTECTSKINS;Protect skin-tones +!TP_VIBRANCE_PSTHRESHOLD;Pastel/saturated tones threshold +!TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Saturation threshold +!TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;The vertical axis represents pastel tones at the bottom and saturated tones at the top.\nThe horizontal axis represents the saturation range. +!TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Pastel/saturated transition's weighting +!TP_VIBRANCE_SATURATED;Saturated Tones +!TP_VIGNETTING_CENTER;Center +!TP_VIGNETTING_CENTER_X;Center X +!TP_VIGNETTING_CENTER_Y;Center Y +!TP_VIGNETTING_STRENGTH;Strength +!TP_WAVELET_1;Level 1 +!TP_WAVELET_2;Level 2 +!TP_WAVELET_3;Level 3 +!TP_WAVELET_4;Level 4 +!TP_WAVELET_5;Level 5 +!TP_WAVELET_6;Level 6 +!TP_WAVELET_7;Level 7 +!TP_WAVELET_8;Level 8 +!TP_WAVELET_9;Level 9 +!TP_WAVELET_ALL;All levels in all directions +!TP_WAVELET_APPLYTO;Apply To +!TP_WAVELET_AVOID;Avoid color shift +!TP_WAVELET_B0;Black +!TP_WAVELET_B1;Grey +!TP_WAVELET_B2;Residual +!TP_WAVELET_BACUR;Curve +!TP_WAVELET_BALANCE;Contrast balance d/v-h +!TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chromaticity or residual tone mapping are activated, the effect due to balance is amplified. +!TP_WAVELET_BALCHRO;Chroma balance +!TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chromaticity balance. +!TP_WAVELET_BANONE;None +!TP_WAVELET_BASLI;Slider +!TP_WAVELET_BATYPE;Contrast balance method +!TP_WAVELET_CCURVE;Local contrast +!TP_WAVELET_CH1;Whole chromaticity range +!TP_WAVELET_CH2;Saturated/pastel +!TP_WAVELET_CH3;Link contrast levels +!TP_WAVELET_CHCU;Curve +!TP_WAVELET_CHRO;Saturated/pastel threshold +!TP_WAVELET_CHRO_TOOLTIP;Sets the wavelet level which will be the threshold between saturated and pastel colors.\n1-x: saturated\nx-9: pastel\n\nIf the value exceeds the amount of wavelet levels you are using then it will be ignored. +!TP_WAVELET_CHR;Chroma-contrast link strength +!TP_WAVELET_CHR_TOOLTIP;Adjusts chromaticity as a function of "contrast levels" and "chroma-contrast link strength" +!TP_WAVELET_CHSL;Sliders +!TP_WAVELET_CHTYPE;Chrominance method +!TP_WAVELET_COLORT;Opacity Red-Green +!TP_WAVELET_COMBOTH;Both +!TP_WAVELET_COMPCONT;Contrast +!TP_WAVELET_COMPGAMMA;Compression gamma +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjusting the gamma of the residual image allow you to equilibrate the data and histogram. +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjust gamma for residual image and compression.\nAllow to equilibrate data and histogram +!TP_WAVELET_COMPTM;Tone mapping +!TP_WAVELET_CONTEDIT;'After' Contrast curve +!TP_WAVELET_CONTEDIT;'After' contrast curve +!TP_WAVELET_CONTRAST_MINUS;Contrast - +!TP_WAVELET_CONTRAST_PLUS;Contrast + +!TP_WAVELET_CONTRA;Contrast +!TP_WAVELET_CONTRA_TOOLTIP;Changes contrast of the residual image. +!TP_WAVELET_CONTR;Gamut +!TP_WAVELET_CTYPE;Chrominance control +!TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modifies local contrast as a function of the original local contrast (absciss)\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 100..300)\n66% absciss represents standard deviation of local contrast (real value about 300..800)\n100% represents maximum (real value about 3000..8000) +!TP_WAVELET_CURVEEDITOR_CH;Contrast levels=f(Hue) +!TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modifies each level's contrast as a function oh hue.\nTake care not to overwrite changes made with the Gamut Hue controls.\nThe curve will only have an effect when wavelet contrast level sliders are non-zero. +!TP_WAVELET_CURVEEDITOR_CL;L +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Applies a final contrast luminance curve at the end of the wavelet treatment. +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Apply a contrast luminance curve at the end of wavelet level threatment +!TP_WAVELET_CURVEEDITOR_HH;HH +!TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modifies the residual image's hue as a function of hue. +!TP_WAVELET_DALL;All directions +!TP_WAVELET_DAUB;Edge performance +!TP_WAVELET_DAUB_TOOLTIP;Changes Daubechies coefficients:\nD4 = Standard,\nD14 = Often best performance, 10% more time-intensive.\n\nAffects edge detection as well as the general quality of the firsts levels. However the quality is not strictly related to this coefficient and can vary with images and uses. +!TP_WAVELET_DISP;Preview Settings +!TP_WAVELET_DONE;Vertical +!TP_WAVELET_DTHR;Diagonal +!TP_WAVELET_DTWO;Horizontal +!TP_WAVELET_EDCU;Curve +!TP_WAVELET_EDGCONT;Local contrast +!TP_WAVELET_EDGCONT_TOOLTIP;Adjusting the points to the left decreases contrast, and to the right increases it.\nBottom-left, Top-Left, Top-Right, Bottom-right represent respectively local contast for low values, mean, mean+stdev, maxima +!TP_WAVELET_EDGEDETECTTHR2;Threshold high (detection) +!TP_WAVELET_EDGEDETECTTHR;Threshold low (noise) +!TP_WAVELET_EDGEDETECTTHR_TOOLTIP;This adjuster lets you target edge detection for example to avoid applying edge sharpness to fine details, such as noise in the sky. +!TP_WAVELET_EDGEDETECT;Gradient sensitivity +!TP_WAVELET_EDGEDETECT_TOOLTIP;Moving the slider to the right increases edge sensitivity. This affects local contrast, edge settings and noise. +!TP_WAVELET_EDGE;Edge Sharpness +!TP_WAVELET_EDGREINF_TOOLTIP;Reinforce or reduce the action of the first level, do the opposite to the second level, and leave the rest unchanged. +!TP_WAVELET_EDGTHRESH;Detail +!TP_WAVELET_EDGTHRESH_TOOLTIP;Change the repartition between the first levels and the others. The higher the threshold the more the action is centred on the first levels. Be careful with negative values, they increase the action of high levels and can introduce artifacts. +!TP_WAVELET_EDRAD;Radius +!TP_WAVELET_EDRAD_TOOLTIP;This radius adjustment is very different from those in other sharpening tools. Its value is compared to each level through a complex function. In this sense, a value of zero still has an effect. +!TP_WAVELET_EDSL;Threshold Sliders +!TP_WAVELET_EDTYPE;Local contrast method +!TP_WAVELET_EDVAL;Strength +!TP_WAVELET_FINAL;Final Touchup +!TP_WAVELET_FINEST;Finest +!TP_WAVELET_HIGHLIGHT;Highlight luminance range +!TP_WAVELET_HS1;Whole luminance range +!TP_WAVELET_HS2;Shadows/Highlights +!TP_WAVELET_HUESKIN;Skin hue +!TP_WAVELET_HUESKIN_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_HUESKY;Sky hue +!TP_WAVELET_HUESKY_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_INF;Below or equal the level +!TP_WAVELET_ITER;Delta balance levels +!TP_WAVELET_ITER_TOOLTIP;Left: increase low levels and reduce high levels,\nRight: reduce low levels and increase high levels. +!TP_WAVELET_LABEL;Wavelet levels +!TP_WAVELET_LARGEST;Coarsest +!TP_WAVELET_LEVCH;Chromaticity +!TP_WAVELET_LEVELS;Wavelet levels +!TP_WAVELET_LEVELS_TOOLTIP;Choose the number of detail levels the image is to be decomposed into. More levels require more RAM and require a longer processing time. +!TP_WAVELET_LEVF;Contrast +!TP_WAVELET_LEVLABEL;Preview maximum possible levels = %1 +!TP_WAVELET_LEVONE;Level 2 +!TP_WAVELET_LEVTWO;Level 3 +!TP_WAVELET_LEVZERO;Level 1 +!TP_WAVELET_LINKEDG;Link with Edge Sharpness' Strength +!TP_WAVELET_LIPST;Enhanced algorithm +!TP_WAVELET_LIPST_TOOLTIP;This algorithm uses Lipschitz regularity to increase edge detection quality at a cost of increased processing time and memory requirements. +!TP_WAVELET_LOWLIGHT;Shadow luminance range +!TP_WAVELET_MEDGREINF;First level +!TP_WAVELET_MEDILEV;Edge detection +!TP_WAVELET_MEDI;Reduce artifacts in blue sky +!TP_WAVELET_NEUTRAL;Neutral +!TP_WAVELET_NOISE;Denoise and Refine +!TP_WAVELET_NOIS;Denoise +!TP_WAVELET_ONE;One level +!TP_WAVELET_OPACITYWL;Final local contrast +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify final local contrast in function of last local contrast (absciss) for all levels decomposition\nTake into account: \na)contrast levels \nb)edge sharpness \nc)contrast balance\nd)decomposition-recomposition\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 200..1000)\n66% absciss represents standard deviation of local contrast (real value about 1000..2000)\n100% represents maximum (real value about 5000..13000) +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify the final local contrast at the end of the wavelet treatment.\n\nThe left side represents the smallest local contrast, progressing to the largest local contrast on the right. +!TP_WAVELET_OPACITYW;Contrast balance d/v-h curve +!TP_WAVELET_OPACITY;Opacity Blue-Yellow +!TP_WAVELET_PASTEL;Pastel chromaticity +!TP_WAVELET_PREVIEWBACK;Background +!TP_WAVELET_PREVIEWLEVELS;Preview +!TP_WAVELET_RE1;Reinforced +!TP_WAVELET_RE2;Unchanged +!TP_WAVELET_RE3;Reduced +!TP_WAVELET_RESCHRO;Chromaticity +!TP_WAVELET_RESCONH;Highlights +!TP_WAVELET_RESCON;Shadows +!TP_WAVELET_RESID;Residual image +!TP_WAVELET_SAT;Saturated chromaticity +!TP_WAVELET_SETTINGS;Wavelet Settings +!TP_WAVELET_SKIN;Skin targetting/protection +!TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected. +!TP_WAVELET_SKY;Sky targetting/protection +!TP_WAVELET_SKY_TOOLTIP;At -100 sky-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 sky-tones are protected while all other tones are affected. +!TP_WAVELET_STRENGTH;Strength +!TP_WAVELET_STREN;Strength +!TP_WAVELET_SUPE;Extra +!TP_WAVELET_SUP;Above the level +!TP_WAVELET_THRESHOLD2;Shadow levels +!TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels between 9 and 9 minus the value will be affected by the shadow luminance range. Other levels will be fully treated. The highest level possible is limited by the highlight level value (9 minus highlight level value). +!TP_WAVELET_THRESHOLD;Highlight levels +!TP_WAVELET_THRESHOLD_TOOLTIP;Only levels beyond the chosen value will be affected by the highlight luminance range. Other levels will be fully treated. The chosen value here limits the highest possible value of the shadow levels. +!TP_WAVELET_THRH;Highlights threshold +!TP_WAVELET_THR;Shadows threshold +!TP_WAVELET_TILESBIG;Big tiles +!TP_WAVELET_TILESFULL;Full image +!TP_WAVELET_TILESIZE;Tiling method +!TP_WAVELET_TILESLIT;Little tiles +!TP_WAVELET_TILES_TOOLTIP;Processing the full image leads to better quality and is the recommended option, while using tiles is a fall-back solution for users with little RAM. Refer to RawPedia for memory requirements. +!TP_WAVELET_TMHIGH;High +!TP_WAVELET_TMLOWHIGH;Low+High +!TP_WAVELET_TMNONE;None +!TP_WAVELET_TMSTD;Standard +!TP_WAVELET_TMSTRENGTH;Compression strength +!TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image. When the value is different from 0, the Strength and Gamma sliders of the Tone Mapping tool in the Exposure tab will become grayed out. +!TP_WAVELET_TMTYPE;Compression method +!TP_WAVELET_TON;Toning +!TP_WAVELET_daub2;D2 - low +!TP_WAVELET_daub4;D4 - standard +!TP_WAVELET_daub6;D6 - standard plus +!TP_WAVELET_daub10;D10 - medium +!TP_WAVELET_daub14;D14 - high +!TP_WBALANCE_CLOUDY;Cloudy +!TP_WBALANCE_DAYLIGHT;Daylight (sunny) +!TP_WBALANCE_EQBLUERED;Blue/Red equalizer +!TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behavior of "white balance" by modulating the blue/red balance.\nThis can be useful when shooting conditions:\na) are far from the standard illuminant (e.g. underwater),\nb) are far from conditions where calibrations were performed,\nc) where the matrices or ICC profiles are unsuitable. +!TP_WBALANCE_FLASH55;Leica +!TP_WBALANCE_FLASH60;Standard, Canon, Pentax, Olympus +!TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta +!TP_WBALANCE_FLASH_HEADER;Flash +!TP_WBALANCE_FLUO1;F1 - Daylight +!TP_WBALANCE_FLUO2;F2 - Cool White +!TP_WBALANCE_FLUO3;F3 - White +!TP_WBALANCE_FLUO4;F4 - Warm White +!TP_WBALANCE_FLUO5;F5 - Daylight +!TP_WBALANCE_FLUO6;F6 - Lite White +!TP_WBALANCE_FLUO7;F7 - D65 Daylight Simulator +!TP_WBALANCE_FLUO8;F8 - D50 / Sylvania F40 Design +!TP_WBALANCE_FLUO9;F9 - Cool White Deluxe +!TP_WBALANCE_FLUO10;F10 - Philips TL85 +!TP_WBALANCE_FLUO11;F11 - Philips TL84 +!TP_WBALANCE_FLUO12;F12 - Philips TL83 +!TP_WBALANCE_FLUO_HEADER;Fluorescent +!TP_WBALANCE_GTI;GTI +!TP_WBALANCE_HMI;HMI +!TP_WBALANCE_JUDGEIII;JudgeIII +!TP_WBALANCE_LAMP_HEADER;Lamp +!TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 +!TP_WBALANCE_LED_HEADER;LED +!TP_WBALANCE_LED_LSI;LSI Lumelex 2040 +!TP_WBALANCE_SHADE;Shade +!TP_WBALANCE_SOLUX35;Solux 3500K +!TP_WBALANCE_SOLUX41;Solux 4100K +!TP_WBALANCE_SOLUX47;Solux 4700K (vendor) +!TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) +!TP_WBALANCE_TUNGSTEN;Tungsten +!TP_WBALANCE_WATER1;UnderWater 1 +!TP_WBALANCE_WATER2;UnderWater 2 +!TP_WBALANCE_WATER_HEADER;UnderWater +!ZOOMPANEL_100;(100%) +!ZOOMPANEL_NEWCROPWINDOW;Open (new) detail window +!ZOOMPANEL_ZOOM100;Zoom to 100%\nShortcut: z +!ZOOMPANEL_ZOOMFITCROPSCREEN;Fit crop to screen\nShortcut: Alt-f +!ZOOMPANEL_ZOOMFITSCREEN;Fit whole image to screen\nShortcut: f +!ZOOMPANEL_ZOOMIN;Zoom In\nShortcut: + +!ZOOMPANEL_ZOOMOUT;Zoom Out\nShortcut: - diff --git a/rtdata/languages/Italiano b/rtdata/languages/Italiano new file mode 100644 index 000000000..591bab712 --- /dev/null +++ b/rtdata/languages/Italiano @@ -0,0 +1,1857 @@ +#01 2008-01-19 v2.3 breek +#02 2008-11-01 v2.4 pantaraf, chelidon, roberto +#03 2011-08-26 v3.0 joker, chelidon, ffsup2 +#04 2011-08-31 v4.0 chelidon, ffsup2 +#05 2014-04-21 crx + +ABOUT_TAB_BUILD;Versione +ABOUT_TAB_CREDITS;Riconoscimenti +ABOUT_TAB_LICENSE;Licenza +ABOUT_TAB_RELEASENOTES;Note di rilascio +ABOUT_TAB_SPLASH;Emblema +ADJUSTER_RESET_TO_DEFAULT;Ripristina +BATCHQUEUE_AUTOSTART;Autoavvia +BATCHQUEUE_DESTFILENAME;Percorso e nome file +BATCH_PROCESSING;Sviluppo in serie +CURVEEDITOR_CURVES;Curve +CURVEEDITOR_CURVE;Curva +CURVEEDITOR_CUSTOM;Personalizzata +CURVEEDITOR_DARKS;Toni Scuri +CURVEEDITOR_HIGHLIGHTS;Alteluci +CURVEEDITOR_LIGHTS;Toni chiari +CURVEEDITOR_LINEAR;Lineare +CURVEEDITOR_LOADDLGLABEL;Carica curva... +CURVEEDITOR_MINMAXCPOINTS;Punti di controllo minimo/massimo +CURVEEDITOR_NURBS;Gabbia di controllo +CURVEEDITOR_PARAMETRIC;Parametrica +CURVEEDITOR_SAVEDLGLABEL;Salva curva... +CURVEEDITOR_SHADOWS;Ombre +CURVEEDITOR_TOOLTIPCOPY;Copia la curva corrente negli appunti +CURVEEDITOR_TOOLTIPLINEAR;Ripristina curva lineare +CURVEEDITOR_TOOLTIPLOAD;Carica una curva da file +CURVEEDITOR_TOOLTIPPASTE;Incolla la curva dagli appunti +CURVEEDITOR_TOOLTIPSAVE;Salva la curva corrente +CURVEEDITOR_TYPE;Tipologia: +DIRBROWSER_FOLDERS;Cartelle +EDITWINDOW_TITLE;Modifica immagine +EDIT_OBJECT_TOOLTIP;Mostra un widget nella finestra anteprima che ti permette di configurare questo strumento. +EDIT_PIPETTE_TOOLTIP;Per aggiungere un punto di regolazione alla curva, tieni premuto il tasto Ctrl e fai click sul punto desiderato nell'anteprima dell'immagine.\nPer sistemare il punto, tieni premuto il tasto Ctrl mentre fai click sulla corrispondente area nell'anteprima, poi lascia il tasto Ctrl (a meno che non desideri un controllo fine) e mentre tieni premuto il tasto sinistro del mouse, muovilo in su e in giù per muovere il punto su e giù sulla curva. +EXIFFILTER_APERTURE;Diaframma +EXIFFILTER_CAMERA;Fotocamera +EXIFFILTER_EXPOSURECOMPENSATION;Compensazione dell'Esposizione (EV) +EXIFFILTER_FILETYPE;Tipo file +EXIFFILTER_FOCALLEN;Lunghezza focale +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Obiettivo +EXIFFILTER_METADATAFILTER;Abilita filtri metadati +EXIFFILTER_SHUTTER;Tempo d'esposizione +EXIFPANEL_ADDEDITHINT;Aggiungi un nuovo campo o modificane uno esistente +EXIFPANEL_ADDEDIT;Aggiungi/Modifica +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Inserisci il valore +EXIFPANEL_ADDTAGDLG_SELECTTAG;Seleziona un campo +EXIFPANEL_ADDTAGDLG_TITLE;Aggiungi/Modifica un campo +EXIFPANEL_KEEPHINT;Mantieni i campi selezionati nel file di uscita +EXIFPANEL_KEEP;Mantieni +EXIFPANEL_REMOVEHINT;Rimuovi i campi selezionati dal file di uscita +EXIFPANEL_REMOVE;Rimuovi +EXIFPANEL_RESETALLHINT;Ripristina tutti i campi al loro valore originario +EXIFPANEL_RESETALL;Ripristina tutto +EXIFPANEL_RESETHINT;Ripristina i campi selezionati ai loro valori originari +EXIFPANEL_RESET;Ripristina +EXIFPANEL_SUBDIRECTORY;Sottocartella +EXPORT_BYPASS_ALL;Seleziona/Deseleziona Tutto +EXPORT_BYPASS_DEFRINGE;Ignora Defringe +EXPORT_BYPASS_DIRPYRDENOISE;Ignora Riduzione Rumore +EXPORT_BYPASS_DIRPYREQUALIZER;Ignora Contrasto per livelli di dettaglio +EXPORT_BYPASS_RAW_CA;Ignora Correzione Aberrazione Cromatica [raw] +EXPORT_BYPASS_RAW_CCSTEPS;Ignora Soppressione Falsi Colori [raw] +EXPORT_BYPASS_RAW_DCB_ENHANCE;Ignora Passaggi di Miglioramento DCB [raw] +EXPORT_BYPASS_RAW_DCB_ITERATIONS;Ignora Iterazioni DCB [raw] +EXPORT_BYPASS_RAW_DF;Ignora Dark Frame [raw] +EXPORT_BYPASS_RAW_FF;Ignora Flat Field [raw] +EXPORT_BYPASS_RAW_GREENTHRESH;Ignora Bilanciamento del Verde [raw] +EXPORT_BYPASS_RAW_LINENOISE;Ignora Filtro Rumore a Bande [raw] +EXPORT_BYPASS_RAW_LMMSE_ITERATIONS;Ignora i Passaggi di Miglioramento LMMSE +EXPORT_BYPASS_SHARPENEDGE;Ignora Nitidezza dei bordi +EXPORT_BYPASS_SHARPENING;Ignora Nitidezza +EXPORT_BYPASS_SHARPENMICRO;Ignora Microcontrasto +EXPORT_BYPASS_SH_HQ;Ignora Ombre/Alteluci (Alta Qualità) +EXPORT_FASTEXPORTOPTIONS;Opzioni di Esportazione Rapida +EXPORT_INSTRUCTIONS;Le opzioni di Esportazione Rapida forniscono opzioni per ignorare le impostazioni di sviluppo ad elevato consumo di tempo e risorse ed avviare quindi la coda di sviluppo usando solo le impostazioni veloci. Questo metodo è consigliato per la lavorazione veloce di immagini a bassa risoluzione quando è importante la rapidità, oppure quando si desidera ridimensionare una o più immagini senza apportare modifiche ai parametri di sviluppo salvati. +EXPORT_MAXHEIGHT;Altezza Massima: +EXPORT_MAXWIDTH;Larghezza Massima: +EXPORT_PUTTOQUEUEFAST; Aggiungi alla Coda di sviluppo per l'Esportazione Rapida +EXPORT_RAW_DMETHOD;Metodo di Demosaicizzazione +EXTPROGTARGET_1;raw +EXTPROGTARGET_2;Lavorato dalla Coda +FILEBROWSER_ADDDELTEMPLATE;Aggiungi/Rimuovi schemi... +FILEBROWSER_APPLYPROFILE;Applica +FILEBROWSER_APPLYPROFILE_PARTIAL;Applica (parziale) +FILEBROWSER_AUTODARKFRAME;Dark Frame automatico +FILEBROWSER_AUTOFLATFIELD;Flat Field automatico +FILEBROWSER_BROWSEPATHBUTTONHINT;Premi per aprire il percorso inserito +FILEBROWSER_BROWSEPATHHINT;Inserisci il percorso da aprire\nCtrl-o seleziona il percorso\nEnter, Ctrl-Enter (solo nel Navigatore) porta alla destinazione ;\nScorciatoie:\n ~ - Cartella home\n ! - Cartella Immagini +FILEBROWSER_CACHECLEARFROMFULL;Rimuovi dalla memoria - totale +FILEBROWSER_CACHECLEARFROMPARTIAL;Rimuovi dalla memoria - parziale +FILEBROWSER_CACHE;Memoria +FILEBROWSER_CLEARPROFILE;Cancella +FILEBROWSER_COLORLABEL_TOOLTIP;Etichetta colore.\n\nUsa il menù o le scorciatoie:\nShift-Ctrl-0 Nessun Colore\nShift-Ctrl-1 Rosso\nShift-Ctrl-2 Giallo\nShift-Ctrl-3 Verde\nShift-Ctrl-4 Blu\nShift-Ctrl-5 Viola +FILEBROWSER_COPYPROFILE;Copia +FILEBROWSER_CURRENT_NAME;Nome corrente: +FILEBROWSER_DARKFRAME;Dark Frame +FILEBROWSER_DELETEDLGLABEL;Conferma eliminazione del file +FILEBROWSER_DELETEDLGMSGINCLPROC;Vuoi eliminare i %1 file inclusa la versione sviluppata nella coda? +FILEBROWSER_DELETEDLGMSG;Vuoi eliminare i %1 file selezionati? +FILEBROWSER_EMPTYTRASHHINT;Elimina definitivamente i file dal cestino. +FILEBROWSER_EMPTYTRASH;Svuota cestino +FILEBROWSER_EXEC_CPB;Generatore profili personalizzati +FILEBROWSER_EXTPROGMENU;Apri con +FILEBROWSER_FLATFIELD;Flat Field +FILEBROWSER_MOVETODARKFDIR;Sposta nella cartella dei Dark Frame +FILEBROWSER_MOVETOFLATFIELDDIR;Sposta nella cartella dei Flat Field +FILEBROWSER_NEW_NAME;Nuovo nome: +FILEBROWSER_OPENDEFAULTVIEWER;Visualiatore predefinito di Windows (lavorato dalla Coda) +FILEBROWSER_PARTIALPASTEPROFILE;Incolla - parziale +FILEBROWSER_PASTEPROFILE;Incolla +FILEBROWSER_POPUPCANCELJOB;Annulla lavoro +FILEBROWSER_POPUPCOLORLABEL0;Etichetta: Nessuna +FILEBROWSER_POPUPCOLORLABEL1;Etichetta: Rosso +FILEBROWSER_POPUPCOLORLABEL2;Etichetta: Giallo +FILEBROWSER_POPUPCOLORLABEL3;Etichetta: Verde +FILEBROWSER_POPUPCOLORLABEL4;Etichetta: Blu +FILEBROWSER_POPUPCOLORLABEL5;Etichetta: Viola +FILEBROWSER_POPUPCOLORLABEL;Etichetta colorata +FILEBROWSER_POPUPCOPYTO;Copia in... +FILEBROWSER_POPUPFILEOPERATIONS;Operazioni sul file +FILEBROWSER_POPUPMOVEEND;Sposta in fondo alla coda +FILEBROWSER_POPUPMOVEHEAD;Sposta in cima alla coda +FILEBROWSER_POPUPMOVETO;Sposta in... +FILEBROWSER_POPUPOPENINEDITOR;Apri in Editor +FILEBROWSER_POPUPOPEN;Apri +FILEBROWSER_POPUPPROCESSFAST;Aggiungi alla Coda (Esportazione Rapida) +FILEBROWSER_POPUPPROCESS;Aggiungi alla Coda +FILEBROWSER_POPUPPROFILEOPERATIONS;Operazioni sui Profili di Sviluppo +FILEBROWSER_POPUPRANK0;Nessun Punteggio +FILEBROWSER_POPUPRANK1;Punteggio 1 * +FILEBROWSER_POPUPRANK2;Punteggio 2 ** +FILEBROWSER_POPUPRANK3;Punteggio 3 *** +FILEBROWSER_POPUPRANK4;Punteggio 4 **** +FILEBROWSER_POPUPRANK5;Punteggio 5 ***** +FILEBROWSER_POPUPRANK;Classificazione +FILEBROWSER_POPUPREMOVEINCLPROC;Elimina insieme a quanto sviluppato nella coda +FILEBROWSER_POPUPREMOVE;Elimina +FILEBROWSER_POPUPRENAME;Rinomina +FILEBROWSER_POPUPSELECTALL;Seleziona tutto +FILEBROWSER_POPUPTRASH;Sposta nel cestino +FILEBROWSER_POPUPUNRANK;Rimuovi il punteggio +FILEBROWSER_POPUPUNTRASH;Rimuovi dal cestino +FILEBROWSER_QUERYBUTTONHINT;Azzera la ricerca +FILEBROWSER_QUERYHINT;Scrivi il nome del file da cercare. Supporta nomi parziali. Separa i termini di ricerca con una virgola, ad esempio:\n1001,1004,1199\n\nScorciatoie:\nCtrl-f - Posiziona sulla Casella di Ricerca,\nInvio - ricerca,\nEsc<\b> - cancellare la Casella di Ricerca,\nShift-Esc - Toglie il fuoco dalla Casella di Ricerca. +FILEBROWSER_QUERYLABEL; Cerca: +FILEBROWSER_RANK1_TOOLTIP;Punteggio 1 *\nScorciatoia: Shift-1 +FILEBROWSER_RANK2_TOOLTIP;Punteggio 2 *\nScorciatoia: Shift-2 +FILEBROWSER_RANK3_TOOLTIP;Punteggio 3 *\nScorciatoia: Shift-3 +FILEBROWSER_RANK4_TOOLTIP;Punteggio 4 *\nScorciatoia: Shift-4 +FILEBROWSER_RANK5_TOOLTIP;Punteggio 5 *\nScorciatoia: Shift-5 +FILEBROWSER_RENAMEDLGLABEL;Rinomina il file +FILEBROWSER_RENAMEDLGMSG;Rinomina il file "%1" in: +FILEBROWSER_SELECTDARKFRAME;Seleziona un Dark Frame... +FILEBROWSER_SELECTFLATFIELD;Seleziona un Flat Field... +FILEBROWSER_SHOWCOLORLABEL1HINT;Mostra le immagini con etichetta Rossa.\nScorciatoia: Alt-1 +FILEBROWSER_SHOWCOLORLABEL2HINT;Mostra le immagini con etichetta Gialla.\nScorciatoia: Alt-2 +FILEBROWSER_SHOWCOLORLABEL3HINT;Mostra le immagini con etichetta Verde.\nScorciatoia: Alt-3 +FILEBROWSER_SHOWCOLORLABEL4HINT;Mostra le immagini con etichetta Blu.\nScorciatoia: Alt-4 +FILEBROWSER_SHOWCOLORLABEL5HINT;Mostra le immagini con etichetta Viola.\nScorciatoia: Alt-5 +FILEBROWSER_SHOWDIRHINT;Rimuovi tutti i filtri.\nScorciatoia: d +FILEBROWSER_SHOWEDITEDHINT;Mostra immagini modificate.\nScorciatoia: 7 +FILEBROWSER_SHOWEDITEDNOTHINT;Mostra immagini non modificate.\nScorciatoia: 6 +FILEBROWSER_SHOWEXIFINFO;Mostra informazioni Exif.\nScorciatoie:\ni - Modalità a Schede Multiple,\nAlt-i - Modalità a Schede Singole. +FILEBROWSER_SHOWRANK1HINT;Mostra le immagini classificate con 1 stella.\nScorciatoia: 1 +FILEBROWSER_SHOWRANK2HINT;Mostra le immagini classificate con 2 stelle.\nScorciatoia: 2 +FILEBROWSER_SHOWRANK3HINT;Mostra le immagini classificate con 3 stelle.\nScorciatoia: 3 +FILEBROWSER_SHOWRANK4HINT;Mostra le immagini classificate con 4 stelle.\nScorciatoia: 4 +FILEBROWSER_SHOWRANK5HINT;Mostra le immagini classificate con 5 stelle.\nScorciatoia: 5 +FILEBROWSER_SHOWRECENTLYSAVEDHINT;Mostra le immagini salvate.\nScorciatoia: Alt-7 +FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Mostra le immagini non salvate.\nScorciatoia: Alt-6 +FILEBROWSER_SHOWTRASHHINT;Mostra il contenuto del cestino.\nScorciatoia: Ctrl-t +FILEBROWSER_SHOWUNCOLORHINT;Mostra le immagini senza etichetta colorata.\nScorciatoia: Alt-0 +FILEBROWSER_SHOWUNRANKHINT;Mostra le immagini non classificate.\nScorciatoia: 0 +FILEBROWSER_STARTPROCESSINGHINT;Inizia a sviluppare le immagini nella Coda. +FILEBROWSER_STARTPROCESSING;Comincia a sviluppare +FILEBROWSER_STOPPROCESSINGHINT;Ferma lo sviluppo delle immagini nella Coda. +FILEBROWSER_STOPPROCESSING;Ferma lo sviluppo +FILEBROWSER_THUMBSIZE;Dimensione miniature +FILEBROWSER_TOOLTIP_STOPPROCESSING;Inizia a sviluppare automaticamente quando un nuovo lavoro viene accodato +FILEBROWSER_UNRANK_TOOLTIP;Nessun Punteggio.\nScorciatoia: Shift-0 +FILEBROWSER_ZOOMINHINT;Aumenta la dimensione delle miniature.\n\nScorciatoie:\n+ - Modalità a Schede Multiple,\nAlt-+ - Modalità a Schede Singole. +FILEBROWSER_ZOOMOUTHINT;Diminuisci la dimensione delle miniature.\n\nScorciatoie:\n- - Modalità a Schede Multiple,\nAlt-- - Modalità a Schede Singole. +GENERAL_ABOUT;Informazioni +GENERAL_AFTER;Dopo +GENERAL_AUTO;Automatico +GENERAL_BEFORE;Prima +GENERAL_CANCEL;Annulla +GENERAL_CLOSE;Chiudi +GENERAL_DISABLED;Disabilitato +GENERAL_DISABLE;Disabilita +GENERAL_ENABLED;Abilitato +GENERAL_ENABLE;Abilita +GENERAL_FILE;File +GENERAL_LANDSCAPE;Panorama +GENERAL_NA;n/a +GENERAL_NONE;Nessuno +GENERAL_NO;No +GENERAL_OK;OK +GENERAL_PORTRAIT;Ritratto +GENERAL_SAVE;Salva +GENERAL_UNCHANGED;(Invariato) +GENERAL_WARNING;Attenzione +HISTOGRAM_TOOLTIP_BAR;Mostra/Nascondi la barra RBG.\nPremi il tasto destro del mouse sull'anteprima dell'immagine per bloccarla/sbloccarla. +HISTOGRAM_TOOLTIP_B;Mostra/Nascondi l'istogramma del Blu. +HISTOGRAM_TOOLTIP_CHRO;Mostra/Nascondi l'istogramma di cromaticità. +HISTOGRAM_TOOLTIP_FULL;Commuta tra istogramma pieno (premuto) o scalato (rilasciato). +HISTOGRAM_TOOLTIP_G;Mostra/Nascondi l'istogramma del Verde. +HISTOGRAM_TOOLTIP_L;Mostra/Nascondi l'istogramma di Luminanza CIELAB. +HISTOGRAM_TOOLTIP_RAW;Mostra/Nascondi l'istogramma del raw. +HISTOGRAM_TOOLTIP_R;Mostra/Nascondi l'istogramma del Rosso. +HISTORY_CHANGED;Modificato +HISTORY_CUSTOMCURVE;Curva personalizzata +HISTORY_DELSNAPSHOT;Rimuovi +HISTORY_FROMCLIPBOARD;Dagli appunti +HISTORY_LABEL;Cronologia +HISTORY_MSG_1;Foto caricata +HISTORY_MSG_2;PP3 caricato +HISTORY_MSG_3;PP3 modificato +HISTORY_MSG_4;Visualizzazione cronologia +HISTORY_MSG_5;Luminosità +HISTORY_MSG_6;Contrasto +HISTORY_MSG_7;Livello del nero +HISTORY_MSG_8;Compensazione dell'esposizione +HISTORY_MSG_9;Compressione alteluci +HISTORY_MSG_10;Compressione ombre +HISTORY_MSG_11;Curva Tono 1 +HISTORY_MSG_12;Livelli Automatici +HISTORY_MSG_13;Tosaggio Esposizione +HISTORY_MSG_14;Lab - Luminosità +HISTORY_MSG_15;Lab - Contrasto +HISTORY_MSG_16;Luminanza: Livello del nero +HISTORY_MSG_17;Luminanza: Compr. alteluci +HISTORY_MSG_18;Luminanza: Compr. ombre +HISTORY_MSG_19;Curva per 'L' +HISTORY_MSG_20;Nitidezza +HISTORY_MSG_21;USM - Raggio +HISTORY_MSG_22;USM - Quantità +HISTORY_MSG_23;USM - Soglia +HISTORY_MSG_24;USM - Definisci solo i bordi +HISTORY_MSG_25;USM - Raggio di Rilevamento Bordi +HISTORY_MSG_26;USM - Tolleranza bordi +HISTORY_MSG_27;USM - Controllo alone +HISTORY_MSG_28;USM - Quantità Controllo Alone +HISTORY_MSG_29;Nitidezza - Metodo +HISTORY_MSG_30;RLD - Raggio +HISTORY_MSG_31;RLD - Quantità +HISTORY_MSG_32;RLD - Smorzamento +HISTORY_MSG_33;RLD - Iterazioni +HISTORY_MSG_34;LCP - Correzione Distorsione +HISTORY_MSG_35;LCP - Correzione Vignettatura +HISTORY_MSG_36;LCP - Correzione AC +HISTORY_MSG_37;Livelli Automatici +HISTORY_MSG_38;WB - Metodo +HISTORY_MSG_39;WB - Temperatura +HISTORY_MSG_40;WB - Tinta +HISTORY_MSG_41;Curva Tono Modo 1 +HISTORY_MSG_42;Curva Tono 2 +HISTORY_MSG_43;Curva Tono Modo 2 +HISTORY_MSG_44;Rid. rumore lum. - Raggio +HISTORY_MSG_45;Rid. rumore lum. - Tolleranza bordi +HISTORY_MSG_46;Riduzione Rumore Crominanza +HISTORY_MSG_47;Fondi alteluci ICC con matrix +HISTORY_MSG_48;Usa curva tono del DCP +HISTORY_MSG_49;DCP - Illuminazione +HISTORY_MSG_50;Ombre/Alteluci +HISTORY_MSG_51;S/H - Alteluci +HISTORY_MSG_52;S/H - Ombre +HISTORY_MSG_53;S/H - Ampiezza tonale - Alteluci +HISTORY_MSG_54;S/H - Ampiezza tonale - Ombre +HISTORY_MSG_55;S/H - Contrasto locale +HISTORY_MSG_56;S/H - Ombre/Alteluci - Raggio +HISTORY_MSG_57;Rotazione semplice +HISTORY_MSG_58;Ribaltamento orizzontale +HISTORY_MSG_59;Ribaltamento verticale +HISTORY_MSG_60;Ruota +HISTORY_MSG_61;Riadatta +HISTORY_MSG_62;Correzione Distorsione +HISTORY_MSG_63;Istantanea Selezionata +HISTORY_MSG_64;Ritaglia +HISTORY_MSG_65;Correzione AC +HISTORY_MSG_66;Ricostruzione Alteluci +HISTORY_MSG_67;Ricostruzione Alteluci - Quantità +HISTORY_MSG_68;Ricostruzione Alteluci - Metodo +HISTORY_MSG_69;Spazio Colore di Lavoro +HISTORY_MSG_70;Spazio Colore di Uscita +HISTORY_MSG_71;Spazio Colore di Ingresso +HISTORY_MSG_72;Correzione vignettatura - Quantità +HISTORY_MSG_73;Miscelatore Canali +HISTORY_MSG_74;Ridimensiona - Scala +HISTORY_MSG_75;Ridimensiona - Metodo +HISTORY_MSG_76;Metadati Exif +HISTORY_MSG_77;Metadati IPTC +HISTORY_MSG_78;Misure specificate per Ridimensiona +HISTORY_MSG_79;Ridimensiona - Larghezza +HISTORY_MSG_80;Ridimensiona - Altezza +HISTORY_MSG_81;Ridimensiona - Abilitato +HISTORY_MSG_82;Profilo modificato +HISTORY_MSG_83;S/H - Maschera di Nitidezza +HISTORY_MSG_84;Correzione prospettiva +HISTORY_MSG_85;Profilo di Correzione Obiettivo +HISTORY_MSG_86;Curve RGB - Modalità Luminosità +HISTORY_MSG_87;Riduzione Rumore Puntuale +HISTORY_MSG_88;Riduzione Rumore Puntuale - Soglia +HISTORY_MSG_89;Riduzione Rumore (NR) +HISTORY_MSG_90;NR - Luminanza +HISTORY_MSG_91;NR - Crominanza +HISTORY_MSG_92;NR - Gamma +HISTORY_MSG_93;CbLD - Valore +HISTORY_MSG_94;CbLD +HISTORY_MSG_95;Lab - Cromaticità +HISTORY_MSG_96;Curva 'a' +HISTORY_MSG_97;Curva 'b' +HISTORY_MSG_98;Demosaicizzazione - Metodo +HISTORY_MSG_99;Filtro pixel surriscaldati/guasti +HISTORY_MSG_100;Saturazione RGB +HISTORY_MSG_101;HSV - Tonalità +HISTORY_MSG_102;HSV - Saturazione +HISTORY_MSG_103;HSV - Valore +HISTORY_MSG_104;HSV - Equalizzatore +HISTORY_MSG_105;Defringe +HISTORY_MSG_106;Defringe - Raggio +HISTORY_MSG_107;Defringe - Soglia +HISTORY_MSG_108;Soglia di compr. alteluci +HISTORY_MSG_109;Ridimensiona - Riquadro +HISTORY_MSG_110;Ridimensiona applicato a +HISTORY_MSG_111;Lab - Previeni color shift +HISTORY_MSG_112;--inutilizzato-- +HISTORY_MSG_113;Lab - Protezione +HISTORY_MSG_114;Iterazioni DCB +HISTORY_MSG_115;Soppressione Falsi Colori +HISTORY_MSG_116;Miglioramento DCB +HISTORY_MSG_117;Correzione AC Rosso (Raw) +HISTORY_MSG_118;Correzione AC Blu (Raw) +HISTORY_MSG_119;Filtro rumore a bande +HISTORY_MSG_120;Bilancam. verde +HISTORY_MSG_121;AC automatica (Raw) +HISTORY_MSG_122;Dark Frame - Automatico +HISTORY_MSG_123;Dark Frame - File +HISTORY_MSG_124;Correzione Punto di Bianco +HISTORY_MSG_125;Protezione AlteLuci +HISTORY_MSG_126;Flat Field - File +HISTORY_MSG_127;Flat Field - Automatico +HISTORY_MSG_128;Flat Field - Raggio di Sfocamento +HISTORY_MSG_129;Flat Field - Modalità di Sfocamento +HISTORY_MSG_130;Autocorr. Distorsione +HISTORY_MSG_131;Riduzione rum. luminanza +HISTORY_MSG_132;Riduzione rum. crominanza +HISTORY_MSG_133;Gamma - Uscita +HISTORY_MSG_134;Gamma - Posizione +HISTORY_MSG_135;Gamma - Libero +HISTORY_MSG_136;Gamma - Pendenza +HISTORY_MSG_137;Punto del Nero - Verde 1 +HISTORY_MSG_138;Punto del Nero - Rosso +HISTORY_MSG_139;Punto del Nero - Blu +HISTORY_MSG_140;Punto del Nero - Verde 2 +HISTORY_MSG_141;Punto del Nero - Verdi uniti +HISTORY_MSG_142;ES - Iterazioni +HISTORY_MSG_143;ES - Quantità +HISTORY_MSG_144;Microcontrasto - Quantità +HISTORY_MSG_145;Microcontrasto - Uniformità +HISTORY_MSG_146;Nitidezza ai Bordi (ES) +HISTORY_MSG_147;ES - Solo luminanza +HISTORY_MSG_148;Microcontrasto +HISTORY_MSG_149;Microcontrasto - Matrice 3x3 +HISTORY_MSG_150;Rid. rumore/artefatti di demosaic. +HISTORY_MSG_151;Vividezza +HISTORY_MSG_152;Vividezza - Toni Pastello +HISTORY_MSG_153;Vividezza - Toni Saturi +HISTORY_MSG_154;Vividezza - Proteggi Incarnato +HISTORY_MSG_155;Vividezza - Evita il color shift +HISTORY_MSG_156;Vividezza - Lega toni Pastello/Saturi +HISTORY_MSG_157;Vividezza - Soglia Pastello/Saturi +HISTORY_MSG_158;TM - Forza +HISTORY_MSG_159;TM - Blocco ai Bordi +HISTORY_MSG_160;TM - Scala +HISTORY_MSG_161;TM - Iterazioni di Ribilanciamento +HISTORY_MSG_162;Tone Mapping (TM) +HISTORY_MSG_163;Curve RGB - R (Rosso) +HISTORY_MSG_164;Curve RGB - G (Verde) +HISTORY_MSG_165;Curve RGB - B (Blu) +HISTORY_MSG_166;Livelli Neutrali +HISTORY_MSG_167;--inutilizzato-- +HISTORY_MSG_168;Curva 'CC' +HISTORY_MSG_169;Curva 'CH' +HISTORY_MSG_170;Vividezza - Curva +HISTORY_MSG_171;Curva 'LC' +HISTORY_MSG_172;Lab - Limita LC +HISTORY_MSG_173;NR - Dettaglio di Luminanza +HISTORY_MSG_174;CIECAM02 +HISTORY_MSG_175;CAM02 - Adattamento CAT02 +HISTORY_MSG_176;CAM02 - Ambiente di Visualizzazione +HISTORY_MSG_177;CAM02 - Lum. della scena +HISTORY_MSG_178;CAM02 - Lum. della visualizzazione +HISTORY_MSG_179;CAM02 - Modello Punto di Bianco +HISTORY_MSG_180;CAM02 - Chiarezza (J) +HISTORY_MSG_181;CAM02 - Croma (C) +HISTORY_MSG_182;CAM02 - CAT02 Automatico +HISTORY_MSG_183;CAM02 - Contrasto (J) +HISTORY_MSG_184;CAM02 - Ambiente +HISTORY_MSG_185;CAM02 - Controllo del Gamut +HISTORY_MSG_186;CAM02 - Algoritmo +HISTORY_MSG_187;CAM02 - Protezione Rosso & incarnato +HISTORY_MSG_188;CAM02 - Brillanza (Q) +HISTORY_MSG_189;CAM02 - Contrasto (Q) +HISTORY_MSG_190;CAM02 - Saturazione (S) +HISTORY_MSG_191;CAM02 - Pienezza (M) +HISTORY_MSG_192;CAM02 - Tinta (h) +HISTORY_MSG_193;CAM02 - Curva Tono 1 +HISTORY_MSG_194;CAM02 - Curva Tono 2 +HISTORY_MSG_195;CAM02 - Curva Tono 1 +HISTORY_MSG_196;CAM02 - Curva Tono 2 +HISTORY_MSG_197;CAM02 - Curva Colore +HISTORY_MSG_198;CAM02 - Curva Colore +HISTORY_MSG_199;CAM02 - Mostra negli istogrammi +HISTORY_MSG_200;CAM02 - Tone mapping +HISTORY_MSG_201;NR - Crominanza R,G +HISTORY_MSG_202;NR - Crominanza B,Y +HISTORY_MSG_203;NR - Metodo +HISTORY_MSG_204;Passaggi di miglioramento LMMSE +HISTORY_MSG_205;CAM02 - Pixel Surriscaldati/Guasti +HISTORY_MSG_206;CAT02 - Lum. automatica della scena +HISTORY_MSG_207;Defringe - Curva Tonalità +HISTORY_MSG_208;WB - B-R Equalizzatore +HISTORY_MSG_210;GF - Angolo +HISTORY_MSG_211;Filtro Graduato (GF) +HISTORY_MSG_212;VF - Forza +HISTORY_MSG_213;Filtro Vignettatura (VF) +HISTORY_MSG_214;Bianco-Nero (BN) +HISTORY_MSG_215;BN - CM - Rosso +HISTORY_MSG_216;BN - CM - Verde +HISTORY_MSG_217;BN - CM - Blu +HISTORY_MSG_218;BN - Gamma - Rosso +HISTORY_MSG_219;BN - Gamma - Verde +HISTORY_MSG_220;BN - Gamma - Blu +HISTORY_MSG_221;BN - Filtro Colore +HISTORY_MSG_222;BN - Preimpostazioni +HISTORY_MSG_223;BN - CM - Arancio +HISTORY_MSG_224;BN - CM - Giallo +HISTORY_MSG_225;BN - CM - Ciano +HISTORY_MSG_226;BN - CM - Magenta +HISTORY_MSG_227;BN - CM - Viola +HISTORY_MSG_228;BN - Equalizzatore di Luminanza +HISTORY_MSG_229;BN - Equalizzatore di Luminanza +HISTORY_MSG_230;BN - Modalità +HISTORY_MSG_231;BN - Curva 'Prima' +HISTORY_MSG_232;BN - Tipo Curva 'Prima' +HISTORY_MSG_233;BN - Curva 'Dopo' +HISTORY_MSG_234;BN - Tipo Curva 'Dopo' +HISTORY_MSG_235;BN - Misc. Canali Automatico +HISTORY_MSG_236;--unused-- +HISTORY_MSG_237;BN - Miscelatore +HISTORY_MSG_238;GF - Scia +HISTORY_MSG_239;GF - Forza +HISTORY_MSG_240;GF - Centro +HISTORY_MSG_241;VF - Scia +HISTORY_MSG_242;VF - Rotondità +HISTORY_MSG_243;VC - Raggio +HISTORY_MSG_244;VC - Forza +HISTORY_MSG_245;VC - Centro +HISTORY_MSG_246;Curva 'CL' +HISTORY_MSG_247;Curva 'LH' +HISTORY_MSG_248;Curva 'HH' +HISTORY_MSG_249;CbDL - Soglia +HISTORY_MSG_250;NR - Miglioramento +HISTORY_MSG_251;B&W - Algoritmo +HISTORY_MSG_252;CbDL Toni della Pelle +HISTORY_MSG_253;CbDL Riduzione Artefatti +HISTORY_MSG_254;CbDL - Tonalità Incarnato +HISTORY_MSG_255;CbDL - Algoritmo +HISTORY_NEWSNAPSHOT;Aggiungi +HISTORY_NEWSNAPSHOT_TOOLTIP;Scorciatoia: Alt-s +HISTORY_SNAPSHOTS;Istantanee +HISTORY_SNAPSHOT;Istantanea +IPTCPANEL_AUTHORSPOSITIONHINT;Titolo del creatore o creatori dell'opera (By-line Title). +IPTCPANEL_AUTHORSPOSITION;Qualifica dell'Autore +IPTCPANEL_AUTHOR;Autore +IPTCPANEL_CAPTIONHINT;Una descrizione testuale dei dati (Caption - Abstract). +IPTCPANEL_CAPTIONWRITERHINT;Il nome della persona impegnata nella scrittura, modifica o correzione dell'immagine o della descrizione riassuntiva (Writer - Editor). +IPTCPANEL_CAPTIONWRITER;Autore della didascalia +IPTCPANEL_CAPTION;Didascalia +IPTCPANEL_CATEGORYHINT;Identifica il soggetto dell'immagine secondo l'opinione del fornitore (Category). +IPTCPANEL_CATEGORY;Categoria +IPTCPANEL_CITYHINT;Città di origine dell'immagine (City). +IPTCPANEL_CITY;Città +IPTCPANEL_COPYHINT;Copia le impostazioni IPTC negli appunti +IPTCPANEL_COPYRIGHTHINT;Qualsiasi annotazione necessaria riguardante il diritto d'autore (Copyright Notice). +IPTCPANEL_COPYRIGHT;Diritto d'autore +IPTCPANEL_COUNTRYHINT;Il nome dello stato/confederazione in cui l'immagine è stata creata (Country - Primary Location Name). +IPTCPANEL_COUNTRY;Stato +IPTCPANEL_CREDITHINT;Identifica il fornitore dell'immagine, non necessariamente il possessore/creatore (Credit). +IPTCPANEL_CREDIT;Riconoscimento +IPTCPANEL_DATECREATEDHINT;La data in cui è stato creato il contenuto intellettuale dell'immagine; Formato: AAAAMMGG (Date Created). +IPTCPANEL_DATECREATED;Data di creazione +IPTCPANEL_EMBEDDEDHINT;Ripristina i dati IPTC incorporati nel file d'immagine +IPTCPANEL_EMBEDDED;Incorporato +IPTCPANEL_HEADLINEHINT;Una didascalia pubblicabile che esprime una sinossi del contenuto dell'immagine (Headline). +IPTCPANEL_HEADLINE;Intestazione +IPTCPANEL_INSTRUCTIONSHINT;Altre istruzioni editoriali riguardanti l'uso dell'immagine (Special Instructions). +IPTCPANEL_INSTRUCTIONS;Istruzioni +IPTCPANEL_KEYWORDSHINT;Usate per indicare parole emblematiche al fine di recuperare informazioni specifiche (Keywords). +IPTCPANEL_KEYWORDS;Parole Chiave +IPTCPANEL_PASTEHINT;Incolla le impostazioni IPTC dagli appunti +IPTCPANEL_PROVINCEHINT;La provincia/regione da cui l'immagine proviene (Province-State). +IPTCPANEL_PROVINCE;Provincia +IPTCPANEL_RESETHINT;Ripristina il profilo predefinito +IPTCPANEL_RESET;Ripristina +IPTCPANEL_SOURCEHINT;Il possessore originario del contenuto intellettuale rappresentato nell'immagine (Source). +IPTCPANEL_SOURCE;Origine +IPTCPANEL_SUPPCATEGORIESHINT;Ulteriore miglioramento del soggetto dell'immagine (Supplemental Categories). +IPTCPANEL_SUPPCATEGORIES;Categorie agg. +IPTCPANEL_TITLEHINT;Un'abbreviazione che alluda all'immagine (Object Name). +IPTCPANEL_TITLE;Titolo +IPTCPANEL_TRANSREFERENCEHINT;Un codice che rappresenta l'ubicazione da cui è avvenuta la trasmissione originaria (Original Transmission Reference). +IPTCPANEL_TRANSREFERENCE;Riferimento Trasm. +MAIN_BUTTON_FULLSCREEN;Schermo intero +MAIN_BUTTON_NAVNEXT_TOOLTIP;Passa all'immagine successiva rispetto all'immagine aperta per la Modifica\nScorciatoia: Shift-F4\n\nPer passare all'immagine successiva rispetto alla miniatura selezionata nel Navigatore o nel Rullino:\nScorciatoia: F4 +MAIN_BUTTON_NAVPREV_TOOLTIP;Passa all'immagine precedente rispetto all'immagine aperta per la Modifica\nScorciatoia: Shift-F3\n\nPer passare all'immagine precedente rispetto alla miniatura selezionata nel Navigatore o nel Rullino:\nScorciatoia: F3 +MAIN_BUTTON_NAVSYNC_TOOLTIP;Sincronizza il Navigatore o il Rullino con la scheda di Modifica per trovare la miniatura dell'immagine attualmente aperta e rimuovere tutti i filtri di ricerca\nScorciatoia: x\n\nCome sopra, ma senza cancellare i filtri di ricerca\nScorciatoia: y\n(Nota che la miniatura del file aperto, se filtrato, non verrà mostrata). +MAIN_BUTTON_PREFERENCES;Preferenze +MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Aggiungi l'immagine corrente alla coda di sviluppo.\nScorciatoia: Ctrl+B +MAIN_BUTTON_SAVE_TOOLTIP;Salva l'immagine corrente.\nSscorciatoia: Ctrl+S +MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Modifica l'immagine corrente con un programma di fotoritocco.\nScorciatoia: Ctrl+E +MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Mostra/Nascondi tutti i pannelli laterali.\nScorciatoia: m +MAIN_BUTTON_UNFULLSCREEN;Esci da schermo intero +MAIN_FRAME_BATCHQUEUE;Coda di sviluppo +MAIN_FRAME_BATCHQUEUE_TOOLTIP;Coda di sviluppo.\nScorciatoia: Ctrl-F3 +MAIN_FRAME_EDITOR;Modifica +MAIN_FRAME_EDITOR_TOOLTIP;Modifica.\nScorciatoia: Ctrl-F4 +MAIN_FRAME_FILEBROWSER;Navigatore +MAIN_FRAME_FILEBROWSER_TOOLTIP;Navigatore.\nScorciatoia: Ctrl-F2 +MAIN_FRAME_PLACES;Risorse +MAIN_FRAME_PLACES_ADD;Aggiungi +MAIN_FRAME_PLACES_DEL;Rimuovi +MAIN_FRAME_RECENT;Cartelle recenti +MAIN_MSG_ALREADYEXISTS;File già esistente +MAIN_MSG_CANNOTLOAD;Impossibile caricare l'immagine +MAIN_MSG_CANNOTSAVE;Errore nel salvataggio del file +MAIN_MSG_CANNOTSTARTEDITOR;Non riesco ad avviare il programma di fotoritocco. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Inserisci il percorso corretto nelle "Preferenze". +MAIN_MSG_EMPTYFILENAME;Nome del file non specificato! +MAIN_MSG_IMAGEUNPROCESSED;Questo comando richiede che tutte le immagini selezionate vengano prima elaborate nella coda. +MAIN_MSG_NAVIGATOR;Navigatore +MAIN_MSG_OPERATIONCANCELLED;Operatione annullata +MAIN_MSG_PATHDOESNTEXIST;Il percorso\n\n%1\n\nnon esiste. Imposta un percorso corretto nella finestra Preferenze. +MAIN_MSG_QOVERWRITE;Vuoi sovrascriverlo? +MAIN_MSG_SETPATHFIRST;Per utilizzare questa funzione\ndevi impostare un percorso nelle Preferenze. +MAIN_MSG_WRITEFAILED;Impossibile scrivere\n\n"%1"\n\nAssicurati che la cartella esista e di averne i permessi di scrittura. +MAIN_TAB_COLOR;Colore +MAIN_TAB_COLOR_TOOLTIP;Scorciatoia: Alt-c +MAIN_TAB_DETAIL;Dettaglio +MAIN_TAB_DETAIL_TOOLTIP;Scorciatoia: Alt-d +MAIN_TAB_DEVELOP;Sviluppo +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPORT; Esportazione Rapida +MAIN_TAB_EXPOSURE;Esposizione +MAIN_TAB_EXPOSURE_TOOLTIP;Scorciatoia: Alt-e +MAIN_TAB_FILTER;Filtro +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadati +MAIN_TAB_METADATA_TOOLTIP;Scorciatoia: Alt-m +MAIN_TAB_RAW;Raw +MAIN_TAB_RAW_TOOLTIP;Scorciatoia: Alt-r +MAIN_TAB_TRANSFORM;Trasformazione +MAIN_TAB_TRANSFORM_TOOLTIP;Scorciatoia: Alt-t +MAIN_TOOLTIP_BACKCOLOR0;Colore di sfondo dell'anteprima: Basato sul tema\nScorciatoia: 9 +MAIN_TOOLTIP_BACKCOLOR1;Colore di sfondo dell'anteprima: Nero\nScorciatoia: 9 +MAIN_TOOLTIP_BACKCOLOR2;Colore di sfondo dell'anteprima: Bianco\nScorciatoia: 9 +MAIN_TOOLTIP_BEFOREAFTERLOCK;Blocca/Sblocca la vista Prima\n\nBlocca: Conserva la vista Prima.\nUtile per valutare l'effetto cumulativo di diversi strumenti.\nIn più, possono essere confrontati diversi passi della cronologia.\n\nSblocca: la vista Prima segue di un passo la vista Dopo, mostrando l'immagine prima dell'effetto dello strumento corrente. +MAIN_TOOLTIP_HIDEHP;Mostra/Nascondi il pannello sinistro (inclusa la cronologia)\nScorciatoia: l +MAIN_TOOLTIP_INDCLIPPEDH;Indicazione delle alteluci tosate.\nScorciatoia: < +MAIN_TOOLTIP_INDCLIPPEDS;Indicazione delle ombre tosate.\nScorciatoia: > +MAIN_TOOLTIP_PREVIEWB;Anteprima del Canale Blu.\nScorciatoia: b +MAIN_TOOLTIP_PREVIEWFOCUSMASK;Anteprima della Focus Mask.\nScorciatoia: Maiuscolo-F\n\nPiù accurato su immagini con bassa profondità di campo, poco rumore e ad elevati livelli di zoom.\n\nPer aumentare l'accuratezza della rilevazione su immagini con molto rumore, riduci le dimensioni del 10-30%. +MAIN_TOOLTIP_PREVIEWG;Anteprima del Canale Verde.\nScorciatoia: g +MAIN_TOOLTIP_PREVIEWL;Anteprima della Luminosità.\nScorciatoia: v\n\n0.299*R + 0.587*G + 0.114*B +MAIN_TOOLTIP_PREVIEWR;Anteprima del Canale Rosso.\nScorciatoia: r +MAIN_TOOLTIP_QINFO;Informazioni generali sullo scatto.\nScorciatoia: i +MAIN_TOOLTIP_SHOWHIDELP1;Mostra/Nascondi il pannello sinistro.\nScorciatoia: l +MAIN_TOOLTIP_SHOWHIDERP1;Mostra/Nascondi il pannello destro.\nScorciatoia: Alt-l +MAIN_TOOLTIP_SHOWHIDETP1;Mostra/Nascondi il pannello superiore.\nScorciatoia: Maiuscolo-l +MAIN_TOOLTIP_THRESHOLD;Soglia +MAIN_TOOLTIP_TOGGLE;Vista Prima/Dopo.\nScorciatoia: Maiuscolo-b +NAVIGATOR_B;B: +NAVIGATOR_G;G: +NAVIGATOR_H;H: +NAVIGATOR_LAB_A;a: +NAVIGATOR_LAB_B;b: +NAVIGATOR_LAB_L;L: +NAVIGATOR_NA; -- +NAVIGATOR_R;R: +NAVIGATOR_S;S: +NAVIGATOR_V;V: +NAVIGATOR_XY_FULL;Larghezza: %1, Altezza: %2 +NAVIGATOR_XY_NA;x: --, y: -- +OPTIONS_DEFIMG_MISSING;Il profilo predefinito per le foto non-raw non può essere trovato o non è stato impostato.\n\nControlla la tua cartella dei profili, potrebbe essere assente o danneggiata.\n\nSaranno utilizzati i valori di default. +OPTIONS_DEFRAW_MISSING;Il profilo predefinito per le foto raw non può essere trovato o non è stato impostato.\n\nControlla la tua cartella dei profili, potrebbe essere assente o danneggiata.\n\nSaranno utilizzati i valori di default. +PARTIALPASTE_BASICGROUP;Parametri principali +PARTIALPASTE_CACORRECTION;Correzione AC +PARTIALPASTE_CHANNELMIXERBW;Bianco-Nero +PARTIALPASTE_CHANNELMIXER;Miscelatore Canali +PARTIALPASTE_COARSETRANS;Rotazione di 90°/Riflessione +PARTIALPASTE_COLORAPP;Modello di Aspetto Colore CIE 2002 +PARTIALPASTE_COLORGROUP;Parametri relativi al colore +PARTIALPASTE_COMMONTRANSFORMPARAMS;Riadatta +PARTIALPASTE_COMPOSITIONGROUP;Parametri di composizione +PARTIALPASTE_CROP;Ritaglio +PARTIALPASTE_DARKFRAMEAUTOSELECT;Dark Frame - Autoselezione +PARTIALPASTE_DARKFRAMEFILE;File Dark Frame +PARTIALPASTE_DEFRINGE;Defringe +PARTIALPASTE_DETAILGROUP;Parametri di dettaglio +PARTIALPASTE_DIALOGLABEL;Incolla una parte del profilo di sviluppo +PARTIALPASTE_DIRPYRDENOISE;Riduzione Rumore +PARTIALPASTE_DIRPYREQUALIZER;Contrasto per livelli di dettaglio +PARTIALPASTE_DISTORTION;Correzione Distorsione +PARTIALPASTE_EPD;Tone mapping +PARTIALPASTE_EVERYTHING;Tutto +PARTIALPASTE_EXIFCHANGES;Modifiche ai dati Exif +PARTIALPASTE_EXPOSURE;Esposizione +PARTIALPASTE_FLATFIELDAUTOSELECT;Flat Field - Autoselezione +PARTIALPASTE_FLATFIELDBLURRADIUS;Flat Field - Raggio di sfocamento +PARTIALPASTE_FLATFIELDBLURTYPE;Flat Field - Modalità di sfocamento +PARTIALPASTE_FLATFIELDFILE;File Flat Field +PARTIALPASTE_GRADIENT;Filtro Graduato +PARTIALPASTE_HSVEQUALIZER;Equalizzatore HSV +PARTIALPASTE_ICMGAMMA;Gamma di uscita +PARTIALPASTE_ICMSETTINGS;Impostazioni Gestione Colore +PARTIALPASTE_IMPULSEDENOISE;Riduzione Rumore Puntuale +PARTIALPASTE_IPTCINFO;Informazioni IPTC +PARTIALPASTE_LABCURVE;Regolazioni Lab +PARTIALPASTE_LENSGROUP;Impostazioni dell'Obiettivo +PARTIALPASTE_LENSPROFILE;Profilo di Correzione dell'Obiettivo +PARTIALPASTE_METAGROUP;Impostazioni di metadati +PARTIALPASTE_PCVIGNETTE;Filtro Vignettatura +PARTIALPASTE_PERSPECTIVE;Prospettiva +PARTIALPASTE_PREPROCESS_GREENEQUIL;Bilanciamento del verde +PARTIALPASTE_PREPROCESS_LINEDENOISE;Filtro per rumore a bande +PARTIALPASTE_RAWCACORR_AUTO;Autocorrezione AC +PARTIALPASTE_RAWCACORR_CABLUE;Correzione AC blu +PARTIALPASTE_RAWCACORR_CARED;Correzione AC rosso +PARTIALPASTE_RAWEXPOS_BLACK;Punto del Nero +PARTIALPASTE_RAWEXPOS_LINEAR;Correzione Punto del Bianco +PARTIALPASTE_RAWEXPOS_PRESER;Conservazione Alteluci +PARTIALPASTE_RAWGROUP;Impostazioni del Raw +PARTIALPASTE_RAW_DCBENHANCE;Miglioramento DCB +PARTIALPASTE_RAW_DCBITERATIONS;Numero di iterazioni DCB +PARTIALPASTE_RAW_DMETHOD;Metodo di demosaicizzazione +PARTIALPASTE_RAW_FALSECOLOR;Soppressione di falsi colori demosaicizzati +PARTIALPASTE_RAW_LMMSEITERATIONS;Passaggi di miglioramento LMMSE +PARTIALPASTE_RESIZE;Ridimensionamento +PARTIALPASTE_RGBCURVES;Curve RGB +PARTIALPASTE_ROTATION;Rotazione +PARTIALPASTE_SHADOWSHIGHLIGHTS;Ombre/Alteluci +PARTIALPASTE_SHARPENEDGE;Bordi +PARTIALPASTE_SHARPENING;Nitidezza (USM/RL) +PARTIALPASTE_SHARPENMICRO;Microcontrasto +PARTIALPASTE_VIBRANCE;Vividezza +PARTIALPASTE_VIGNETTING;Correzione Vignettatura +PARTIALPASTE_WHITEBALANCE;Bilanciamento del bianco +PREFERENCES_ADD;Somma +PREFERENCES_APPLNEXTSTARTUP;applicato al prossimo avvio +PREFERENCES_AUTOMONPROFILE;Usa il profilo colore dello schermo principale del sistema operativo +PREFERENCES_BATCH_PROCESSING;Sviluppo in serie +PREFERENCES_BEHADDALLHINT;Imposta tutti i parametri nella modalità Somma.\nLe regolazioni dei parametri nel pannello strumenti batch saranno differenze dei valori memorizzati. +PREFERENCES_BEHADDALL;Tutti a 'Somma' +PREFERENCES_BEHAVIOR;Comportamento +PREFERENCES_BEHSETALLHINT;Imposta tutti i parametri nella modalità Imposta.\nLe regolazioni dei parametri nel pannello strumenti batch saranno assoluti, verranno mostrati i valori reali. +PREFERENCES_BEHSETALL;Tutti a 'Imposta' +PREFERENCES_BLACKBODY;Tungsteno +PREFERENCES_CACHECLEARALL;Rimuovi tutto +PREFERENCES_CACHECLEARPROFILES;Rimuovi i profili di sviluppo +PREFERENCES_CACHECLEARTHUMBS;Rimuovi le miniature +PREFERENCES_CACHEMAXENTRIES;Numero massimo di voci in memoria +PREFERENCES_CACHEOPTS;Opzioni della memoria +PREFERENCES_CACHETHUMBHEIGHT;Massima altezza delle miniature +PREFERENCES_CIEART;Ottimizzazione CIECAM02 +PREFERENCES_CIEART_LABEL;Utilizza precisione singola anziché doppia +PREFERENCES_CIEART_TOOLTIP;Se abilitata, i calcoli CIECAM02 sono effettuati in formato a virgola mobile a precisione singola anziché doppia. Questo permette un piccolo incremento di velocità al costo di una trascurabile perdita di qualità. +PREFERENCES_CLIPPINGIND;Indicazione di tosaggio +PREFERENCES_CMETRICINTENT;Intento colorimetrico +PREFERENCES_CUSTPROFBUILDHINT;File eseguibile (o script) richiamato quando è necessario generare un nuovo profilo per un'immagine.\nIl percorso del file di comunicazione (del tipo *.ini, detto "Keyfile") è aggiunto come parametro da linea di comando. Contiene diversi paramentri necessari agli script e ai dati Exif per generare un profilo di elaborazione.\n\nATTENZIONE:: Devi utilizzare le virgolette doppie quando necessario se utilizzi percorsi contenenti spazi. +PREFERENCES_CUSTPROFBUILDKEYFORMAT;Formato tasti +PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME;Nome +PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;TagID +PREFERENCES_CUSTPROFBUILDPATH;Percorso dell'eseguibile +PREFERENCES_CUSTPROFBUILD;Generatore profili personalizzati +PREFERENCES_CUTOVERLAYBRUSH;Colore/Trasparenza della maschera di ritaglio +PREFERENCES_D50;5000K +PREFERENCES_D55;5500K +PREFERENCES_D60;6000K +PREFERENCES_D65;6500K +PREFERENCES_DARKFRAMEFOUND;Trovati +PREFERENCES_DARKFRAMESHOTS;fotogrammi +PREFERENCES_DARKFRAMETEMPLATES;modelli +PREFERENCES_DARKFRAME;Dark Frame +PREFERENCES_DATEFORMATHINT;Puoi usare le seguenti stringhe di formattazione:\n%y : anno\n%m : mese\n%d : giorno\n\nPer esempio, il formato italiano per la data è:\n%d/%m/%y +PREFERENCES_DATEFORMAT;Formato della data +PREFERENCES_DEFAULTLANG;Lingua predefinita +PREFERENCES_DEFAULTTHEME;Tema predefinito +PREFERENCES_DIRDARKFRAMES;Cartella dei fotogrammi di fondo (Dark Frame) +PREFERENCES_DIRHOME;Cartella personale dell'utente (home directory) +PREFERENCES_DIRLAST;Ultima cartella visitata +PREFERENCES_DIROTHER;Altra +PREFERENCES_DIRSELECTDLG;Seleziona la cartella delle immagini all'avvio... +PREFERENCES_DIRSOFTWARE;Cartella d'installazione +PREFERENCES_EDITORCMDLINE;Altra linea di comando +PREFERENCES_EDITORLAYOUT;Disposizione +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_FLATFIELDFOUND;Trovati +PREFERENCES_FLATFIELDSDIR;Cartella dei fotogrammi di campo (Flat Field) +PREFERENCES_FLATFIELDSHOTS;fotogrammi +PREFERENCES_FLATFIELDTEMPLATES;modelli +PREFERENCES_FLATFIELD;Flat Field +PREFERENCES_FLUOF2;Fluorescente F2 +PREFERENCES_FLUOF7;Fluorescente F7 +PREFERENCES_FLUOF11;Fluorescente F11 +PREFERENCES_FORIMAGE;Per foto non raw +PREFERENCES_FORRAW;Per foto raw +PREFERENCES_GIMPPATH;Cartella d'installazione di GIMP +PREFERENCES_GREY05;Yb=05 CIE L#30 +PREFERENCES_GREY10;Yb=10 CIE L#40 +PREFERENCES_GREY15;Yb=15 CIE L#45 +PREFERENCES_GREY18;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_GREY;Luminosità Yb del dispositivo di uscita (%) +PREFERENCES_HISTOGRAMPOSITIONLEFT;Istogramma nel pannello sinistro +PREFERENCES_HISTOGRAMWORKING;Profilo di Lavoro per Istogramma e Navigatore +PREFERENCES_HISTOGRAM_TOOLTIP;Se abilitato, Navigatore e Istogramma usano il Profilo di Lavoro anziché il Profilo di Uscita (con gamma) +PREFERENCES_HLTHRESHOLD;Soglia per le alteluci tosate +PREFERENCES_ICCDIR;Cartella profili colore +PREFERENCES_IMPROCPARAMS;Parametri predefiniti di elaborazione dell'immagine +PREFERENCES_INTENT_ABSOLUTE;Colorimetrico Assoluto +PREFERENCES_INTENT_PERCEPTUAL;Percettivo +PREFERENCES_INTENT_RELATIVE;Colorimetrico Relativo +PREFERENCES_INTENT_SATURATION;Saturazione +PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Mostra miniatura JPEG incorporata, se il raw non è stato lavorato +PREFERENCES_LANGAUTODETECT;Usa l'impostazione di lingua del sistema +PREFERENCES_MENUGROUPEXTPROGS;Raggruppa "Apri con" +PREFERENCES_MENUGROUPFILEOPERATIONS;Raggruppa "Operazioni sui file" +PREFERENCES_MENUGROUPLABEL;Raggruppa "Etichette Colore" +PREFERENCES_MENUGROUPPROFILEOPERATIONS;Raggruppa "Operazioni sui profili" +PREFERENCES_MENUGROUPRANK;Raggruppa "Classificazioni" +PREFERENCES_MENUOPTIONS;Opzioni del menù a discesa +PREFERENCES_METADATA;Metadati +PREFERENCES_MONITORICC;Profilo colore del monitor +PREFERENCES_MULTITABDUALMON;Modalità a Schede Multiple (se disponibile sul secondo schermo) +PREFERENCES_MULTITAB;Modalità a Schede Multiple +PREFERENCES_NAVGUIDEBRUSH;Colore delle guide del Navigatore +PREFERENCES_OUTDIRFOLDERHINT;Salva le immagini nella cartella scelta +PREFERENCES_OUTDIRFOLDER;Salva nella cartella +PREFERENCES_OUTDIRTEMPLATEHINT;Puoi usare le seguenti stringhe di formattazione:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nQueste stringhe di formattazione si riferiscono ai vari livelli del percorso in cui si trova la foto.\n\nPer esempio, se la foto sviluppata si trovasse nel seguente percorso:\n/home/mario/foto/31-10-2010/dsc0042.nef\nil significato delle stringhe di formattazione sarebbe:\n%d4 = home\n%d3 = mario\n%d2 = foto\n%d1 = 31-10-2010\n%f = dsc0042\n%p1 = /home/mario/foto/31-10-2010/\n%p2 = /home/mario/foto/\n%p3 = /home/mario/\n%p4 = /home/\n\nPer salvare l'immagine finale nella stessa posizione dove si trova l'originale, scrivi:\n%p1/%f\n\nPer salvare l'immagine finale in una cartella chiamata "sviluppate" situata nella cartella degli originali, scrivi:\n%p1/sviluppate/%f\n\nPer salvare l'immagine finale in una cartella chiamata "/home/mario/foto/sviluppate/31-10-2010", scrivi:\n%p2/sviluppate/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Usa lo schema +PREFERENCES_OUTDIR;Cartella di destinazione +PREFERENCES_OVERLAY_FILENAMES;Mostra i nomi dei file sovrapposti alle miniature +PREFERENCES_OVERWRITEOUTPUTFILE;Sovrascrivi file esistenti +PREFERENCES_PANFACTORLABEL;Fattore +PREFERENCES_PARSEDEXTADDHINT;Aggiungi l'estensione alla lista. +PREFERENCES_PARSEDEXTADD;Aggiungi un'estensione +PREFERENCES_PARSEDEXTDELHINT;Rimuovi l'estensione selezionata dalla lista. +PREFERENCES_PARSEDEXT;Estensioni riconosciute +PREFERENCES_PROFILEHANDLING;Gestione dei profilo di sviluppo +PREFERENCES_PROFILELOADPR;Priorità nel caricamento del profilo +PREFERENCES_PROFILEPRCACHE;Profilo nella memoria +PREFERENCES_PROFILEPRFILE;Profilo a fianco del file originario +PREFERENCES_PROFILESAVECACHE;Salva il profilo di sviluppo nella memoria +PREFERENCES_PROFILESAVEINPUT;Salva il profilo di sviluppo a fianco del file originario +PREFERENCES_PROPERTY;Proprietà +PREFERENCES_PSPATH;Cartella d'installazione di Adobe Photoshop +PREFERENCES_RGBDTL_LABEL;Numero massimo di thread per la Riduzione Rumore +PREFERENCES_RGBDTL_TOOLTIP;La Riduzione Rumore richiede un minimo di circa 128MB di RAM per un'immagine di 10MPixel o 512MB per una di 40MPixel più 128MB di RAM per ogni thread. Più thread vengono eseguiti in parallelo, più rapida sarà l'elaborazione. Lascia l'impostazione a "0" per usare automaticamente quanti più thread possibili. +PREFERENCES_SELECTFONT;Seleziona il carattere +PREFERENCES_SELECTLANG;Seleziona la lingua +PREFERENCES_SELECTTHEME;Seleziona il tema +PREFERENCES_SET;Imposta +PREFERENCES_SHOWBASICEXIF;Mostra dati Exif di base +PREFERENCES_SHOWDATETIME;Mostra data e ora +PREFERENCES_SHOWEXPOSURECOMPENSATION;Accoda compensazione dell'esposizione +PREFERENCES_SHTHRESHOLD;Soglia per le ombre tosate +PREFERENCES_SINGLETABVERTAB;Modalità a Scheda Singola, schede verticali +PREFERENCES_SINGLETAB;Modalità a Scheda Singola +PREFERENCES_SLIMUI;Interfaccia compatta +PREFERENCES_SND_BATCHQUEUEDONE;Al termine dell'elaborazione della coda +PREFERENCES_SND_HELP;Inserire un percorso oppure nulla (per non avere suoni).\nSu Windows usa "SystemDefault", "SystemAsterisk" ecc. per i suoni di sistema.\nSu Linux usa "complete", "window-attention" ecc. per i suoni di sistema. +PREFERENCES_SND_LNGEDITPROCDONE;Al termine delle operazioni di modifica +PREFERENCES_SND_TRESHOLDSECS;dopo un tempo in secondi +PREFERENCES_STARTUPIMDIR;Cartella delle immagini all'avvio +PREFERENCES_TAB_BROWSER;Navigatore +PREFERENCES_TAB_COLORMGR;Gestione Colore +PREFERENCES_TAB_GENERAL;Generale +PREFERENCES_TAB_IMPROC;Elaborazione immagine +PREFERENCES_TAB_PERFORMANCE;Prestazioni +PREFERENCES_TAB_SOUND;Suoni +PREFERENCES_TP_LABEL;Pannello Strumenti: +PREFERENCES_TP_USEICONORTEXT;Utilizza le icone delle schede anziché il testo +PREFERENCES_TP_VSCROLLBAR;Nascondi la barra di scorrimento verticale +PREFERENCES_TUNNELMETADATA;Copia i dati IPTC/XMP non modificati nel file sviluppato (qualora si etichetti con un altro programma) +PREFERENCES_USEBUNDLEDPROFILES;Usa profili inclusi +PREFERENCES_USESYSTEMTHEME;Usa tema di sistema +PREFERENCES_VIEW;Bilanciamento del bianco del dispositivo di uscita (monitor, TV, proiettore...) +PREFERENCES_WORKFLOW;Disposizione +PROFILEPANEL_COPYPPASTE;Parametri da copiare +PROFILEPANEL_GLOBALPROFILES;Profili inclusi +PROFILEPANEL_LABEL;Profili di sviluppo +PROFILEPANEL_LOADDLGLABEL;Carico i parametri di sviluppo... +PROFILEPANEL_LOADPPASTE;Parametri da caricare +PROFILEPANEL_MODE_TIP;Modalità di riempimento del Profilo di Sviluppo.\n\nPulsante premuto: i profili parziali verranno convertiti in profili completi; i valori mancanti verranno sostituiti con i valori predefiniti.\n\nPulsante rilasciato: i Profili saranno applicati così come sono, modificando solo i valori che contengono. +PROFILEPANEL_MYPROFILES;Miei profili +PROFILEPANEL_PASTEPPASTE;Parametri da incollare +PROFILEPANEL_PCUSTOM;Personalizzato +PROFILEPANEL_PFILE;Da file +PROFILEPANEL_PINTERNAL;Neutral +PROFILEPANEL_PLASTSAVED;Ultimo salvato +PROFILEPANEL_SAVEDLGLABEL;Salvo i parametri di sviluppo... +PROFILEPANEL_SAVEPPASTE;Parametri da salvare +PROFILEPANEL_TOOLTIPCOPY;Copia il profilo corrente negli appunti.\nCtrl-click per selezionare i parametri da copiare. +PROFILEPANEL_TOOLTIPLOAD;Carica profilo da file.\nCtrl-click per selezionare i parametri da caricare. +PROFILEPANEL_TOOLTIPPASTE;Incolla il profilo dagli appunti.\nCtrl-click per selezionare i parametri da incollare. +PROFILEPANEL_TOOLTIPSAVE;Salva il profilo corrente.\nCtrl-click per selezionare i parametri da salvare. +PROGRESSBAR_LOADINGTHUMBS;Caricamento miniature... +PROGRESSBAR_LOADING;Caricamento immagine... +PROGRESSBAR_LOADJPEG;Caricamento JPEG... +PROGRESSBAR_LOADPNG;Caricamento PNG... +PROGRESSBAR_LOADTIFF;Caricamento TIFF... +PROGRESSBAR_NOIMAGES;Nessuna immagine trovata +PROGRESSBAR_PROCESSING;Elaborazione dell'immagine... +PROGRESSBAR_PROCESSING_PROFILESAVED;Profilo di sviluppo salvato +PROGRESSBAR_READY;Pronto +PROGRESSBAR_SAVEJPEG;Salvataggio del file JPEG... +PROGRESSBAR_SAVEPNG;Salvataggio del file PNG... +PROGRESSBAR_SAVETIFF;Salvataggio del file TIFF... +PROGRESSBAR_SNAPSHOT_ADDED;Istantanea aggiunta +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profilo di sviluppo modificato nel navigatore +QINFO_ISO;ISO +QINFO_NOEXIF;Dati Exif non disponibili. +SAVEDLG_AUTOSUFFIX;Aggiungi automaticamente un suffisso se il file esiste già +SAVEDLG_FILEFORMAT;Formato file +SAVEDLG_FORCEFORMATOPTS;Opzioni di salvataggio forzato +SAVEDLG_JPEGQUAL;Qualità JPEG +SAVEDLG_PNGCOMPR;Compressione PNG +SAVEDLG_PUTTOQUEUEHEAD;Metti in cima alla coda di sviluppo +SAVEDLG_PUTTOQUEUETAIL;Metti in fondo alla coda di sviluppo +SAVEDLG_PUTTOQUEUE;Inserisci nella coda di sviluppo +SAVEDLG_SAVEIMMEDIATELY;Salva subito +SAVEDLG_SAVESPP;Salva i parametri di elaborazione con l'immagine +SAVEDLG_SUBSAMP;Sottocampionamento +SAVEDLG_SUBSAMP_1;Migliore Compressione +SAVEDLG_SUBSAMP_2;Bilanciato +SAVEDLG_SUBSAMP_3;Migliore Qualità +SAVEDLG_SUBSAMP_TOOLTIP;Migliore Compressione: 4:1:1\nBilanciato: 4:2:2\nMigliore Qualità: 4:4:4 +SAVEDLG_TIFFUNCOMPRESSED;TIFF non compresso +SAVEDLG_WARNFILENAME;Il file verrà chiamato +SHCSELECTOR_TOOLTIP;Click destro per ripristinare la posizione di questi tre cursori. +THRESHOLDSELECTOR_BL;Basso-Sinistra +THRESHOLDSELECTOR_BR;Basso-Destra +THRESHOLDSELECTOR_B;Basso +THRESHOLDSELECTOR_HINT;Tieni premuto Maiuscolo per muovere un singolo punto di controllo. +THRESHOLDSELECTOR_TL;Alto-Sinistra +THRESHOLDSELECTOR_TR;Alto-Destra +THRESHOLDSELECTOR_T;Alto +TOOLBAR_TOOLTIP_CROP;Ritaglia la selezione.\nScorciatoia: c\nSposta l'area di ritaglio tenendo premuto Maiuscolo mentre muovi il mouse +TOOLBAR_TOOLTIP_HAND;Strumento mano.\nScorciatoia: h +TOOLBAR_TOOLTIP_STRAIGHTEN;Linea Dritta/Rotazione Precisa.\nScorciatoia: s\n\nTraccia il verticale o l'orizzontale disegnando una linea sull'anteprima dell'immagine. L'angolo di rotazione verrà mostrato accanto alla linea guida. Il centro della rotazione è il centro geometrico dell'immagine. +TOOLBAR_TOOLTIP_WB;Bilanciamento del bianco puntuale.\nScorciatoia: w +TP_BWMIX_ALGO;Algoritmo OYCPM +TP_BWMIX_ALGO_LI;Lineare +TP_BWMIX_ALGO_SP;Effetti speciali +TP_BWMIX_ALGO_TOOLTIP;Lineare: produrrà una risposta normale lineare.\nEffetti speciali: produrrà effetti speciali miscelando i canali non-linearmente. +TP_BWMIX_AUTOCH;Auto +TP_BWMIX_AUTOCH_TIP;Calcola i valori ottimali del Miscelatore Canali. +TP_BWMIX_CC_ENABLED;Regola il colore complementare +TP_BWMIX_CC_TOOLTIP;Abilita per consentire le regolazioni automatiche dei colori complementari nella modalità ROYGCBPM. +TP_BWMIX_CHANNEL;Equalizzatore di Luminanza +TP_BWMIX_CURVEEDITOR1;Curva 'Prima' +TP_BWMIX_CURVEEDITOR2;Curva 'Dopo' +TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Curva Tono, dopo la conversione B&W, alla fine del trattamento. +TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Curva Tono, appena prima della conversione B&W.\nPuò prendere in considerazione le componenti colore. +TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Luminosità secondo Tonalità L=f(H).\nFai attenzione ai valori estermi: possono generare artefatti. +TP_BWMIX_FILTER;Filtro Colore +TP_BWMIX_FILTER_BLUEGREEN;Blu-Verde +TP_BWMIX_FILTER_BLUE;Blu +TP_BWMIX_FILTER_GREENYELLOW;Verde-Giallo +TP_BWMIX_FILTER_GREEN;Verde +TP_BWMIX_FILTER_NONE;Nessuno +TP_BWMIX_FILTER_PURPLE;Viola +TP_BWMIX_FILTER_REDYELLOW;Rosso-Giallo +TP_BWMIX_FILTER_RED;Rosso +TP_BWMIX_FILTER_TOOLTIP;Il filtro colore simula uno scatto con un filtro colorato posto davanti all'obiettivo. I filtri colorati riducono la trasmissione di uno specifico intervallo di colori modificando la loro luminosità. Ad esempio, un filtro rosso scurisce i cieli blu. +TP_BWMIX_FILTER_YELLOW;Giallo +TP_BWMIX_GAMMA;Correzione Gamma +TP_BWMIX_GAM_TOOLTIP;Corregge il gamma per ogni canale RGB. +TP_BWMIX_LABEL;Bianco-Nero +TP_BWMIX_MET;Metodo +TP_BWMIX_MET_CHANMIX;Miscelatore Canali +TP_BWMIX_MET_DESAT;Desaturazione +TP_BWMIX_MET_LUMEQUAL;Equalizzatore di Luminanza +TP_BWMIX_MIXC;Miscelatore +TP_BWMIX_NEUTRAL;Ripristina il miscelatore +TP_BWMIX_NEUTRAL_TIP;Ripristina tutti i valori (Filtro Colore, Miscelatore Canali). +TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Totale: %4%% +TP_BWMIX_RGBLABEL_HINT;Fattori RGB finali che si occupano di tutte le opzioni del miscelatore.\n"Totale" mostra la somma dei valori RGB:\n- sempre 100% nella modalità relativa\n- Più alto (luminoso) or più basso (scuro) del 100% nella modalità assoluta. +TP_BWMIX_RGB_TOOLTIP;Miscela i canali RGB. Usa i valori preimpostati per orientarti.\nFai attenzione ai valori negativi: possono causare artefatti o comportamenti imprevisti. +TP_BWMIX_SETTING;Preimpostazioni +TP_BWMIX_SETTING_TOOLTIP;Impostazioni delle Preimpostazioni (pellicola, panorama, etc.) o del Miscelatore Canali manuale. +TP_BWMIX_SET_HIGHCONTAST;Contrasto Elevato +TP_BWMIX_SET_HIGHSENSIT;Sensibilità Elevata +TP_BWMIX_SET_HYPERPANCHRO;Iper-Pancromatica +TP_BWMIX_SET_INFRARED;Infrarosso +TP_BWMIX_SET_LANDSCAPE;Panorama +TP_BWMIX_SET_LOWSENSIT;Bassa Sensibilità +TP_BWMIX_SET_LUMINANCE;Luminanza +TP_BWMIX_SET_NORMCONTAST;Contrasto Normale +TP_BWMIX_SET_ORTHOCHRO;Ortocromatica +TP_BWMIX_SET_PANCHRO;Pancromatica +TP_BWMIX_SET_PORTRAIT;Ritratto +TP_BWMIX_SET_RGBABS;RGB assoluto +TP_BWMIX_SET_RGBREL;RGB relativo +TP_BWMIX_SET_ROYGCBPMABS;ROYGCBPM assoluto +TP_BWMIX_SET_ROYGCBPMREL;ROYGCBPM relativo +TP_BWMIX_TCMODE_FILMLIKE;BN tipo pellicola +TP_BWMIX_TCMODE_SATANDVALBLENDING;BN Fusione Saturazione e Valore +TP_BWMIX_TCMODE_STANDARD;BN Standard +TP_BWMIX_TCMODE_WEIGHTEDSTD;BN Standard Pesata +TP_BWMIX_VAL;L +TP_CACORRECTION_BLUE;Blu +TP_CACORRECTION_LABEL;Correzione AC +TP_CACORRECTION_RED;Rosso +TP_CHMIXER_BLUE;Canale Blu +TP_CHMIXER_GREEN;Canale Verde +TP_CHMIXER_LABEL;Miscelatore Canali +TP_CHMIXER_RED;Canale Rosso +TP_CHROMATABERR_LABEL;Aberrazione Cromatica +TP_COARSETRAF_TOOLTIP_HFLIP;Rifletti orizzontalmente. +TP_COARSETRAF_TOOLTIP_ROTLEFT;Ruota a sinistra.\nScorciatoie:\n[ - Modalità a Scheda Multipla,\nAlt-[ - Modalità a Scheda Singola. +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Ruota a destra.\nScorciatoie:\n] - Modalità a Scheda Multipla,\nAlt-] - Modalità a Scheda Singola. +TP_COARSETRAF_TOOLTIP_VFLIP;Rifletti verticalmente +TP_COLORAPP_ADAPTSCENE;Luminanza della scena +TP_COLORAPP_ADAPTSCENE_TOOLTIP;Luminanza assoluta dell'ambiente della scena (cd/m²)\n1) Calcolata dai dati Exif:\nTempo - ISO - Diaframma - Compensazione dell'Esposizione.\n2) Calcolata dal punto di bianco del raw e dal cursore di Compensazione dell'Esposizione. +TP_COLORAPP_ADAPTVIEWING;Luminanza di visualizzazione (cd/m²) +TP_COLORAPP_ADAPTVIEWING_TOOLTIP;Luminanza assoluta dell'ambiente di visualizzazione\n(normalmente 16cd/m²). +TP_COLORAPP_ADAP_AUTO_TOOLTIP;Se questa casella è selezionata (raccomandato) RT calcola un valore ottimale dai dati Exif.\nPer impostare un valore manualmente, deseleziona la casella. +TP_COLORAPP_ALGO;Algoritmo +TP_COLORAPP_ALGO_ALL;Tutto +TP_COLORAPP_ALGO_JC;Chiarezza + Croma (JC) +TP_COLORAPP_ALGO_JS;Chiarezza + Saturazione (JS) +TP_COLORAPP_ALGO_QM;Brillanza + Pienezza (QM) +TP_COLORAPP_ALGO_TOOLTIP;Scegli un sottoinsieme di parametri o tutti +TP_COLORAPP_BADPIXSL;Filtro pixel surriscaldati/guasti +TP_COLORAPP_BADPIXSL_TOOLTIP;Soppressione dei pixel surriscaldati/guasti (eccessivamente colorati).\n0 = nessun effetto\n1 = mediana\n2 = gaussiana.\n\nQuesti artefatti derivano dalle limitazioni di CIECAM02. Alternativamente, regola l'immagine per evitare ombre eccessivamente scure. +TP_COLORAPP_BRIGHT;Brillanza (Q) +TP_COLORAPP_BRIGHT_TOOLTIP;La Brillanza in CIECAM02 prende in considerazione la luminosità del bianco ed è diversa da quella in Lab e RGB. +TP_COLORAPP_CHROMA;Croma (C) +TP_COLORAPP_CHROMA_M;Pienezza (M) +TP_COLORAPP_CHROMA_M_TOOLTIP;La Pienezza in CIECAM02 è diversa da quella in Lab e RGB. +TP_COLORAPP_CHROMA_S;Saturazione (S) +TP_COLORAPP_CHROMA_S_TOOLTIP;La Saturazione in CIECAM02 è diversa da quella in Lab e RGB. +TP_COLORAPP_CHROMA_TOOLTIP;Il Croma in CIECAM02 è diverso da quello in Lab e RGB. +TP_COLORAPP_CIECAT_DEGREE;Adattamento CAT02 +TP_COLORAPP_CONTRAST;Contrasto (J) +TP_COLORAPP_CONTRAST_Q;Contrasto (Q) +TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrasto per il cursore Q in CIECAM02; è diverso da quello in Lab e RGB. +TP_COLORAPP_CONTRAST_TOOLTIP;Contrasto per il cursore J in CIECAM02; è diverso da quello in Lab e RGB. +TP_COLORAPP_CURVEEDITOR1;Curva Tono 1 +TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Mostra l'istogramma di L (Lab) prima di CIECAM02.\nSe "Mostra gli istogrammi di uscita CIECAM02 nelle curve" è abilitato, mostra gli istogrammi di J o Q dopo CIECAM02.\n\nJ e Q non sono mostrati nel pannello Istogramma.\n\nPer l'output finale fare riferimento al pannello Istogramma +TP_COLORAPP_CURVEEDITOR2;Curva Tono 2 +TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Stesso utilizzo della Curva Tono 2 di Esposizione +TP_COLORAPP_CURVEEDITOR3;Curva Colore +TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Regola Croma, Saturazione o Pienezza.\nL'Istogramma mostra la Cromaticità (Lab) prima di CIECAM02.\nSe "Mostra gli istogrammi di uscita CIECAM02 nelle curve" è abilitato, l'Istogramma mostra C, s e M dopo CIECAM02.\nC, s e M non sono mostrati direttamente nel pannello Istogramma.\nPer l'output finale fare riferimento al pannello Istogramma +TP_COLORAPP_DATACIE;Mostra gli istogrammi di uscita CIECAM02 nelle curve +TP_COLORAPP_DATACIE_TOOLTIP;Quando abilitato, gli istogrammi nelle curve CIECAM02 mostrano valori e intervalli approssimati di J o Q, e C, s o M dopo le regolazioni CIECAM02.\nQuesta selezione non ha effetto nel pannello Istogramma principale.\n\nQuando disabilitato, gli istogrammi nelle curve CIECAM02 mostrano i valori Lab, come sono prima delle regolazioni CIECAM02. +TP_COLORAPP_DEGREE_AUTO_TOOLTIP;Se abilitato (raccomandato), RT calcola un valore ottimale, che sarà utilizzato da CAT02, e anche per l'intero CIECAM02.\nDisabilitare per impostare il valore manualmente (sono raccomandati valori superiori a 65). +TP_COLORAPP_DEGREE_TOOLTIP;Quantità di Trasformazione di Adattamento Cromatico CIE 2002 +TP_COLORAPP_GAMUT;Controllo Gamut (Lab) +TP_COLORAPP_GAMUT_TOOLTIP;Consenti il controllo gamut nella modalità Lab +TP_COLORAPP_HUE;Tinta (h) +TP_COLORAPP_HUE_TOOLTIP;Tinta (h) - angolo tra 0° e 360° +TP_COLORAPP_LABEL;Modello di Aspetto Colore CIE 2002 +TP_COLORAPP_LABEL_CAM02;Regolazioni Immagine +TP_COLORAPP_LABEL_SCENE;Caratteristiche della scena +TP_COLORAPP_LABEL_VIEWING;Caratteristiche della visualizzazione +TP_COLORAPP_LIGHT;Chiarezza (J) +TP_COLORAPP_LIGHT_TOOLTIP;La Chiarezza in CIECAM02 è diversa da quella in Lab e RGB. +TP_COLORAPP_MODEL;Modello del Punto di Bianco +TP_COLORAPP_MODEL_TOOLTIP;Modello del Punto di bianco.\n\nWB [RT] + [output]: Per la scena viene usato il Bilanciamento del Bianco di RT, CIECAM02 è impostato a D50, il bianco del dispositivo di uscita utilizza il valore impostato in Preferenze > Gestione Colore.\n\nWB [RT+CAT02] + [output]: Le impostazioni di Bilanciamento del Bianco di RT sono utilizzate da CAT02 e il bianco del dispositivo di uscita utilizza il valore impostato in Preferenze > Gestione Colore. +TP_COLORAPP_RSTPRO;Protezione rossi e incarnato +TP_COLORAPP_RSTPRO_TOOLTIP;Protezione dei toni rossi e dell'incarnato (cursori e curve) +TP_COLORAPP_SHARPCIE;--inutilizzato-- +TP_COLORAPP_SHARPCIE_TOOLTIP;--inutilizzato-- +TP_COLORAPP_SURROUND;Ambiente +TP_COLORAPP_SURROUND_AVER;Medio +TP_COLORAPP_SURROUND_DARK;Scuro +TP_COLORAPP_SURROUND_DIM;Fioco +TP_COLORAPP_SURROUND_EXDARK;Estremamente Scuro (Pieghevole) +TP_COLORAPP_SURROUND_TOOLTIP;Cambia toni e colori per tenere conto delle condizioni di visualizzazione del dispositivo di uscita\n\nMedio: Ambiente mediamente illuminato (standard)\nL'immagine non verrà modificata.\n\nFioco: Ambiente fioco (TV)\nL'immagine diverrà leggermente più scura\n\nScuro: Ambiente scuro (proiettore)\nL'immagine diventerà più scura\n\nEstremamente Scuro: Ambiente buio (Pieghevole)\nL'immagine diventerà molto più scura. +TP_COLORAPP_SURSOURCE;Ambiente scuro +TP_COLORAPP_SURSOURCE_TOOLTIP;Si può utilizzare nel caso in cui l'immagine abbia bordi scuri. +TP_COLORAPP_TCMODE_BRIGHTNESS;Brillanza +TP_COLORAPP_TCMODE_CHROMA;Croma +TP_COLORAPP_TCMODE_COLORF;Pienezza +TP_COLORAPP_TCMODE_LABEL1;Modo Curva 1 +TP_COLORAPP_TCMODE_LABEL2;Modo Curva 2 +TP_COLORAPP_TCMODE_LABEL3;Modo Curva Croma +TP_COLORAPP_TCMODE_LIGHTNESS;Chiarezza +TP_COLORAPP_TCMODE_SATUR;Saturazione +TP_COLORAPP_TONECIE;Tone mapping con CIECAM02 +TP_COLORAPP_TONECIE_TOOLTIP;Se questa opzione è disabilitata, il Tone Mapping è eseguito nello spazio Lab.\nSe l'opzione è abilitata, il Tone Mapping è fatto usando CIECAM02.\nLo strumento Tone Mapping (Lab/CIECAM02) deve essere abilitato affinché questa impostazione abbia effetto. +TP_COLORAPP_WBCAM;WB [RT+CAT02] + [output] +TP_COLORAPP_WBRT;WB [RT] + [output] +TP_CROP_FIXRATIO;Rapporto fisso: +TP_CROP_GTDIAGONALS;Regola delle diagonali +TP_CROP_GTEPASSPORT;Passaporto Biometrico +TP_CROP_GTFRAME;Fotogramma +TP_CROP_GTGRID;Griglia +TP_CROP_GTNONE;Nessuna +TP_CROP_GTRULETHIRDS;Regola dei terzi +TP_CROP_GUIDETYPE;Tipo di guida: +TP_CROP_H;A +TP_CROP_LABEL;Ritaglio +TP_CROP_PPI;PPI= +TP_CROP_SELECTCROP; Seleziona Area +TP_CROP_W;L +TP_CROP_X;X +TP_CROP_Y;Y +TP_DARKFRAME_AUTOSELECT;Autoselezione +TP_DARKFRAME_LABEL;Dark Frame +TP_DEFRINGE_LABEL;Defringe +TP_DEFRINGE_RADIUS;Raggio +TP_DEFRINGE_THRESHOLD;Soglia +TP_DIRPYRDENOISE_BLUE;Crominanza - Blu-Giallo +TP_DIRPYRDENOISE_CHROMA;Crominanza (Principale) +TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Utilizzabile su immagini raw e non raw.\n\nPer immagini non raw, la riduzione rumore di luminanza dipende dal gamma del profilo colore di ingresso. Si presume un gamma sRGB, quindi se l'immagine di ingresso ha un profilo colore di un gamma diverso, la riduzione rumore di luminanza cambierà. +TP_DIRPYRDENOISE_ENH;Modalità Migliorata +TP_DIRPYRDENOISE_ENH_TOOLTIP;Aumenta la qualità della riduzione rumore al costo di un incremento del 20% del tempo di elaborazione. +TP_DIRPYRDENOISE_GAMMA;Gamma +TP_DIRPYRDENOISE_GAMMA_TOOLTIP;Il gamma varia la forza della riduzione rumore su tutto l'intervallo di toni. Valori più piccoli incideranno sulle ombre, mentre valori maggiori estenderanno l'effetto ai toni più luminosi. +TP_DIRPYRDENOISE_LABEL;Riduzione Rumore +TP_DIRPYRDENOISE_LAB;Lab +TP_DIRPYRDENOISE_LDETAIL;Dettaglio di Luminanza +TP_DIRPYRDENOISE_LUMA;Luminanza +TP_DIRPYRDENOISE_METHOD;Metodo +TP_DIRPYRDENOISE_METHOD_TOOLTIP;Per immagini raw può essere usato il metodo RGB o Lab.\n\nPer immagini non raw verrà utilizzato il metodo Lab, indipendentemente dalla selezione. +TP_DIRPYRDENOISE_RED;Crominanza - Rosso-Verde +TP_DIRPYRDENOISE_RGB;RGB +TP_DIRPYREQUALIZER_ALGO;Algoritmo Pelle +TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fine: più simile ai colori dell'incarnato, minimizzando l'azione di altri colori\nAmpio: evita ulteriori artefatti +TP_DIRPYREQUALIZER_HUESKIN;Tonalità della Pelle +TP_DIRPYREQUALIZER_HUESKIN_TOOLTIP;Questa piramide è per la parte superiore, con l'algoritmo alla sua massima efficienza.\nNella parte inferiore, le zone di transizione.\nSe devi muovere in modo significativo la zona verso destra o verso sinistra (o se ci sono artefatti): il bilanciamento del bianco è sbagliato\nPuoi ridurre leggermente la zona per evitare che la parte rimante dell'immagine ne sia influenzata +TP_DIRPYREQUALIZER_LABEL;Contrasto per livelli di dettaglio (CbDL) +TP_DIRPYREQUALIZER_LUMACOARSEST;Estesissimo +TP_DIRPYREQUALIZER_LUMACONTRAST_MINUS;Contrasto- +TP_DIRPYREQUALIZER_LUMACONTRAST_PLUS;Contrasto+ +TP_DIRPYREQUALIZER_LUMAFINEST;Finissimo +TP_DIRPYREQUALIZER_LUMANEUTRAL;Neutro +TP_DIRPYREQUALIZER_SKIN;Toni della Pelle - Elaborazione/Protezione +TP_DIRPYREQUALIZER_SKIN_TOOLTIP;A -100 i toni della pelle sono elaborati.\nA 0 tutti i toni sono trattati allo stesso modo.\nA +100 i toni della pelle sono protetti mentre gli altri toni sono elaborati. +TP_DIRPYREQUALIZER_THRESHOLD;Soglia +TP_DIRPYREQUALIZER_TOOLTIP;Tenta di ridurre gli artefatti dovuti alle transizioni tra colori (tonalità, croma, luma) dell'incarnato e del resto dell'immagine +TP_DISTORTION_AMOUNT;Quantità +TP_DISTORTION_AUTO; Autocorrezione Distorsione +TP_DISTORTION_AUTO_TIP;Corregge la distorsione delle ottiche automaticamente per alcune fotocamere (Micro 4/3, alcune compatte, ecc.) +TP_DISTORTION_LABEL;Distorsione +TP_EPD_EDGESTOPPING;Blocco ai Bordi +TP_EPD_LABEL;Tone Mapping +TP_EPD_REWEIGHTINGITERATES;Iterazioni di Ribilanciamento +TP_EPD_SCALE;Scala +TP_EPD_STRENGTH;Forza +TP_EPD_TOOLTIP;Il Tone Mapping è possibile in modalità Lab (standard) o CIECAM02.\n\nPer utilizare il Tone Mapping CIECAM02 abilita quste impostazioni: \n 1. CIECAM02\n 2. Algoritmo="Brillanza + Pienezza (QM)"\n 3. "Tone mapping con CIECAM02" +TP_EXPOSURE_AUTOLEVELS;Livelli automatici +TP_EXPOSURE_AUTOLEVELS_TIP;Abilita l'esecuzione dei livelli automatici per impostare automaticamente il cursore Esposizione in base all'analisi dell'immagine.\nSe necessario, abilita Ricostruzione Alteluci. +TP_EXPOSURE_BLACKLEVEL;Livello del nero +TP_EXPOSURE_BRIGHTNESS;Luminosità +TP_EXPOSURE_CLIP;Tosaggio % +TP_EXPOSURE_CLIP_TIP;La frazione di pixel da tosare nell'operazione di livelli automatici. +TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Soglia di Compressione Alteluci +TP_EXPOSURE_COMPRHIGHLIGHTS;Compressione Alteluci +TP_EXPOSURE_COMPRSHADOWS;Compressione Ombre +TP_EXPOSURE_CONTRAST;Contrasto +TP_EXPOSURE_CURVEEDITOR1;Curva Tono 1 +TP_EXPOSURE_CURVEEDITOR2;Curva Tono 2 +TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Fare riferimento alla pagina "Exposure > Tone Curves" di RawPedia per capire come ottenere i risultati migliori con le doppie curve. +TP_EXPOSURE_EXPCOMP;Compensazione Esposizione +TP_EXPOSURE_LABEL;Esposizione +TP_EXPOSURE_SATURATION;Saturazione +TP_EXPOSURE_TCMODE_FILMLIKE;Pellicola +TP_EXPOSURE_TCMODE_LABEL1;Tipo Curva 1 +TP_EXPOSURE_TCMODE_LABEL2;Tipo Curva 2 +TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Fusione Saturazione/Valore +TP_EXPOSURE_TCMODE_STANDARD;Standard +TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Standard Pesata +TP_FLATFIELD_AUTOSELECT;Autoselezione +TP_FLATFIELD_BLURRADIUS;Raggio di sfocamento +TP_FLATFIELD_BLURTYPE;Modalità di sfocamento +TP_FLATFIELD_BT_AREA;Area +TP_FLATFIELD_BT_HORIZONTAL;Orizzontale +TP_FLATFIELD_BT_VERTHORIZ;Vert. + Oriz. +TP_FLATFIELD_BT_VERTICAL;Verticale +TP_FLATFIELD_LABEL;Flat Field +TP_GAMMA_CURV;Gamma +TP_GAMMA_FREE;Gamma libero +TP_GAMMA_OUTPUT;Gamma di uscita +TP_GAMMA_SLOP;Pendenza (lineare) +TP_GENERAL_11SCALE_TOOLTIP;L'effetto di questo strumento è visibile solo (o è accurato solo) con l'anteprima in scala 1:1. +TP_GRADIENT_CENTER;Centro +TP_GRADIENT_CENTER_X;Centro X +TP_GRADIENT_CENTER_X_TOOLTIP;Sposta il gradiente a sinistra (valori negativi) o a destra (valori positivi). +TP_GRADIENT_CENTER_Y;Centro Y +TP_GRADIENT_CENTER_Y_TOOLTIP;Sposta il gradiente su (valori negativi) o giù (valori positivi). +TP_GRADIENT_DEGREE;Angolo +TP_GRADIENT_DEGREE_TOOLTIP;Angolo di rotazione in gradi. +TP_GRADIENT_FEATHER;Scia +TP_GRADIENT_FEATHER_TOOLTIP;Ampiezza del gradiente in percento della diagonale dell'immagine. +TP_GRADIENT_LABEL;Filtro Graduato +TP_GRADIENT_STRENGTH;Forza +TP_GRADIENT_STRENGTH_TOOLTIP;Forza del filtro in stop. +TP_HLREC_BLEND;Fusione +TP_HLREC_CIELAB;Fusione in CIELab +TP_HLREC_COLOR;Propagazione di crominanza +TP_HLREC_ENA_TOOLTIP;Può essere attivato dai Livelli Automatici. +TP_HLREC_LABEL;Ricostruzione Alteluci +TP_HLREC_LUMINANCE;Recupero di Luminanza +TP_HLREC_METHOD;Metodo: +TP_HSVEQUALIZER_CHANNEL;Canale +TP_HSVEQUALIZER_HUE;H +TP_HSVEQUALIZER_LABEL;Equalizzatore HSV +TP_HSVEQUALIZER_SAT;S +TP_HSVEQUALIZER_VAL;V +TP_ICM_BLENDCMSMATRIX;Fonde le alteluci ICC con matrix +TP_ICM_BLENDCMSMATRIX_TOOLTIP;Abilita per recuperare le alteluci bruciate quando usi profili ICC basati su LUT. +TP_ICM_DCPILLUMINANT;Illuminazione +TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolato +TP_ICM_DCPILLUMINANT_TOOLTIP;Seleziona il DCP del tipo di illuminazione da utilizzare. Il predefinito è "interpolato", un mix tra i due basato sul bilanciamento del bianco. Questa impostazione è abilitata solo se è selezionato Doppia Illuminazione con supporto interpolato. +TP_ICM_INPUTCAMERAICC;Specifico della fotocamera +TP_ICM_INPUTCAMERAICC_TOOLTIP;Utilizza i profili colore di ingresso DCP o ICC di RawTherapee specifici per la fotocamera. Questi profili sono più precisi dei semplici matrix. Non sono però disponibili per tutte le fotocamere. Questi profili sono archiviati nelle cartelle /iccprofiles/input e /dcpprofiles e sono recuperati automaticamente in base all'esatta corrispondenza tra nome del file e modello di fotocamera. +TP_ICM_INPUTCAMERA;Predefinito della fotocamera +TP_ICM_INPUTCAMERA_TOOLTIP;Utilizza i semplici color matrix di dcraw, migliorati nella versione di RawTherapee (qualunque sia disponibile in base al modello di fotocamera) o inclusi nel DNG. +TP_ICM_INPUTCUSTOM;Personalizzato +TP_ICM_INPUTCUSTOM_TOOLTIP;Seleziona il tuo profilo colore DCP/ICC per la fotocamera. +TP_ICM_INPUTDLGLABEL;Seleziona il profilo DCP/ICC di ingresso... +TP_ICM_INPUTEMBEDDED;Incorporato, se disponibile +TP_ICM_INPUTEMBEDDED_TOOLTIP;Utilizza il profilo colore incluso nei file non-raw. +TP_ICM_INPUTNONE;Nessun profilo +TP_ICM_INPUTNONE_TOOLTIP;Non applicare un profilo colore.\nDa utilizzare solo in casi particolari. +TP_ICM_INPUTPROFILE;Profilo di ingresso +TP_ICM_LABEL;Gestione Colore +TP_ICM_NOICM;Nessun ICM: uscita in sRGB +TP_ICM_OUTPUTPROFILE;Profilo di Uscita +TP_ICM_SAVEREFERENCE;Salva riferimento per la profilazione +TP_ICM_SAVEREFERENCE_TOOLTIP;Salva l'immagine TIFF lineare prima che sia applicato il profilo colore. Il risultato può essere utilizzato per la calibrazione e generazione del profilo della fotocamera. +TP_ICM_TONECURVE;Usa la curva tono del DCP +TP_ICM_TONECURVE_TOOLTIP;Utilizza le curve tono incluse nel DCP. Questa opzione è abilitata solo se il DCP selezionato possiede una curva tono. +TP_ICM_WORKINGPROFILE;Profilo di lavoro +TP_IMPULSEDENOISE_LABEL;Riduzione Rumore Puntuale +TP_IMPULSEDENOISE_THRESH;Soglia +TP_LABCURVE_AVOIDCOLORSHIFT;Evita il color shift +TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Adatta i colori all'interno del gamut dello spazio colore di lavoro e applica la correzione Munsell. +TP_LABCURVE_BRIGHTNESS;Luminosità +TP_LABCURVE_CHROMATICITY;Cromaticità +TP_LABCURVE_CHROMA_TOOLTIP;Per applicare il toning BN impostare la Cromaticità a -100. +TP_LABCURVE_CONTRAST;Contrasto +TP_LABCURVE_CURVEEDITOR;Curva di luminanza +TP_LABCURVE_CURVEEDITOR_A_RANGE1;Verde Saturo +TP_LABCURVE_CURVEEDITOR_A_RANGE2;Verde Pastello +TP_LABCURVE_CURVEEDITOR_A_RANGE3;Rosso Pastello +TP_LABCURVE_CURVEEDITOR_A_RANGE4;Rosso Saturo +TP_LABCURVE_CURVEEDITOR_B_RANGE1;Blu Saturo +TP_LABCURVE_CURVEEDITOR_B_RANGE2;Blu Pastello +TP_LABCURVE_CURVEEDITOR_B_RANGE3;Giallo Pastello +TP_LABCURVE_CURVEEDITOR_B_RANGE4;Giallo Saturo +TP_LABCURVE_CURVEEDITOR_CC;CC +TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutri +TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Opachi +TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastello +TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Saturi +TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Cromaticità secondo Cromaticità C=f(C) +TP_LABCURVE_CURVEEDITOR_CH;CH +TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Cromaticità secondo Tonalità C=f(H) +TP_LABCURVE_CURVEEDITOR_CL;CL +TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Cromaticità secondo Luminanza C=f(L) +TP_LABCURVE_CURVEEDITOR_HH;HH +TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Tonalità secondo Tonalità H=f(H) +TP_LABCURVE_CURVEEDITOR_LC;LC +TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminanza secondo Cromaticità L=f(C) +TP_LABCURVE_CURVEEDITOR_LH;LH +TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Luminanza secondo Tonalità L=f(H) +TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminanza secondo Luminanza L=f(L) +TP_LABCURVE_LABEL;Regolazioni Lab +TP_LABCURVE_LCREDSK;Limita LC ai toni rossi e all'incarnato +TP_LABCURVE_LCREDSK_TIP;Se abilitato, la Curva LC è applicata solo ai toni rossi e dell'incarnato.\nSe disabilitato, ha effetto su tutti i toni. +TP_LABCURVE_RSTPROTECTION;Protezione Toni rossi e dell'incarnato +TP_LABCURVE_RSTPRO_TOOLTIP;Può essere utilizzato con il cursore Cromaticità e la curva CC. +TP_LENSGEOM_AUTOCROP; Ritaglio automatico +TP_LENSGEOM_FILL;Adattamento automatico +TP_LENSGEOM_LABEL;Obiettivo/Geometria +TP_LENSPROFILE_LABEL;Profilo di Correzione dell'Obiettivo +TP_LENSPROFILE_USECA;Correzione dell'Aberrazione Cromatica (AC) +TP_LENSPROFILE_USEDIST;Correzione della Distorsione +TP_LENSPROFILE_USEVIGN;Correzione della Vignettatura +TP_NEUTRAL;Neutrale +TP_NEUTRAL_TIP;Riporta i controlli dell'esposizione ai valori neutrali.\nVale per gli stessi controlli cui è applicato Livelli Automatici, indipendentemente dal fatto che Livelli Automatici sia abilitato. +TP_PCVIGNETTE_FEATHER;Scia +TP_PCVIGNETTE_FEATHER_TOOLTIP;Scia:\n0 = solo i bordi,\n50 = a metà strada con il centro,\n100 = al centro. +TP_PCVIGNETTE_LABEL;Filtro Vignettatura +TP_PCVIGNETTE_ROUNDNESS;Rotondità +TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Rotondità:\n0 = rettangolo,\n50 = ellisse riempito,\n100 = cerchio. +TP_PCVIGNETTE_STRENGTH;Forza +TP_PCVIGNETTE_STRENGTH_TOOLTIP;Forza del filtro in stop (raggiunta agli angoli). +TP_PERSPECTIVE_HORIZONTAL;Orizzontale +TP_PERSPECTIVE_LABEL;Prospettiva +TP_PERSPECTIVE_VERTICAL;Verticale +TP_PFCURVE_CURVEEDITOR_CH;Tonalità +TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Controlla la forza di defringe dal colore.\nPiù alto = di più,\nPiù basso = di meno. +TP_PREPROCESS_GREENEQUIL;Bilanciamento del verde +TP_PREPROCESS_LABEL;Pre-elaborazione +TP_PREPROCESS_LINEDENOISE;Filtro per rumore a bande +TP_PREPROCESS_NO_FOUND;Nessuno presente +TP_RAWCACORR_AUTO;Autocorrezione +TP_RAWCACORR_CABLUE;Blu +TP_RAWCACORR_CARED;Rosso +TP_RAWEXPOS_BLACKS;Livelli del nero +TP_RAWEXPOS_LINEAR;Punto del Bianco - Correzione +TP_RAWEXPOS_PRESER;Punto del Bianco - Protezione Alteluci +TP_RAWEXPOS_TWOGREEN;Valori del verde uniti +TP_RAW_DCBENHANCE;Miglioramento DCB +TP_RAW_DCBITERATIONS;Numero di iterazioni DCB +TP_RAW_DMETHOD;Metodo +TP_RAW_DMETHOD_PROGRESSBAR;Demosaicizzazione %1... +TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Perfezionamento della demosaicizzazione... +TP_RAW_DMETHOD_TOOLTIP;Nota: IGV e LMMSE sono dedicati alle immagini ad alti ISO per aiutare nella riduzione rumore senza comportare posterizzazione o colori lavati. +TP_RAW_FALSECOLOR;Stadi per soppressione di falsi colori +TP_RAW_LABEL;Demosaicizzazione +TP_RAW_LMMSEITERATIONS;Passaggi di miglioramento LMMSE +TP_RAW_LMMSE_TOOLTIP;Aggiunge gamma (passo 1) - Aggiunge mediana (passi 2-4), poi perfeziona (passi 5-6) per ridurre gli artefatti e migliorare il rapporto segnale/rumore. +TP_RESIZE_APPLIESTO;Applica a: +TP_RESIZE_CROPPEDAREA;Zona ritagliata +TP_RESIZE_FITBOX;Riquadro delimitato +TP_RESIZE_FULLIMAGE;Tutta l'immagine +TP_RESIZE_HEIGHT;Altezza +TP_RESIZE_H;A: +TP_RESIZE_LABEL;Ridimensiona +TP_RESIZE_LANCZOS;Lanczos +TP_RESIZE_METHOD;Metodo: +TP_RESIZE_NEAREST;Più prossimo (Nearest) +TP_RESIZE_SCALE;Scala +TP_RESIZE_SPECIFY;Specifica: +TP_RESIZE_WIDTH;Larghezza +TP_RESIZE_W;L: +TP_RGBCURVES_BLUE;B +TP_RGBCURVES_CHANNEL;Canale +TP_RGBCURVES_GREEN;G +TP_RGBCURVES_LABEL;Curve RGB +TP_RGBCURVES_LUMAMODE;Modalità Luminosità +TP_RGBCURVES_LUMAMODE_TOOLTIP;La Modalità Luminosità consente di variare il contributo dei canali R, G e B alla luminosità dell'immagine, senza alterarne il colore. +TP_RGBCURVES_RED;R +TP_ROTATE_DEGREE;Angolo +TP_ROTATE_LABEL;Ruota +TP_ROTATE_SELECTLINE; Seleziona una linea dritta +TP_SAVEDIALOG_OK_TIP;Scorciatoia: Ctrl-Enter +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Alteluci +TP_SHADOWSHLIGHTS_HLTONALW;Ampiezza Tonale delle Alteluci +TP_SHADOWSHLIGHTS_LABEL;Ombre/Alteluci +TP_SHADOWSHLIGHTS_LOCALCONTR;Contrasto Locale +TP_SHADOWSHLIGHTS_RADIUS;Raggio +TP_SHADOWSHLIGHTS_SHADOWS;Ombre +TP_SHADOWSHLIGHTS_SHARPMASK;Maschera di Nitidezza +TP_SHADOWSHLIGHTS_SHTONALW;Ampiezza Tonale delle Ombre +TP_SHARPENEDGE_AMOUNT;Quantità +TP_SHARPENEDGE_LABEL;Bordi +TP_SHARPENEDGE_PASSES;Iterazioni +TP_SHARPENEDGE_THREE;Solo per luminanza +TP_SHARPENING_AMOUNT;Quantità +TP_SHARPENING_EDRADIUS;Raggio +TP_SHARPENING_EDTOLERANCE;Tolleranza bordi +TP_SHARPENING_HALOCONTROL;Controllo dell'alone +TP_SHARPENING_HCAMOUNT;Quantità +TP_SHARPENING_LABEL;Nitidezza +TP_SHARPENING_METHOD;Metodo +TP_SHARPENING_ONLYEDGES;Definisci solo i bordi +TP_SHARPENING_RADIUS;Raggio +TP_SHARPENING_RLD;Deconvoluzione RL +TP_SHARPENING_RLD_AMOUNT;Quantità +TP_SHARPENING_RLD_DAMPING;Smorzamento +TP_SHARPENING_RLD_ITERATIONS;Iterazioni +TP_SHARPENING_THRESHOLD;Soglia +TP_SHARPENING_TOOLTIP;Aspettati un risultato leggermente diverso quando usato con CIECAM02. Se noti differenze, regola a tuo piacimento. +TP_SHARPENING_USM;Maschera di contrasto +TP_SHARPENMICRO_AMOUNT;Quantità +TP_SHARPENMICRO_LABEL;Microcontrasto +TP_SHARPENMICRO_MATRIX;Matrice 3×3 invece di 5×5 +TP_SHARPENMICRO_UNIFORMITY;Uniformità +TP_VIBRANCE_AVOIDCOLORSHIFT;Evita il color shift +TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH +TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Incarnato +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Rosso/Viola +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Rosso +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Rosso/Giallo +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Giallo +TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Tonalità a seconda della Tinta H=f(H) +TP_VIBRANCE_LABEL;Vividezza +TP_VIBRANCE_PASTELS;Toni Pastello +TP_VIBRANCE_PASTSATTOG;Lega i toni pastello e saturi +TP_VIBRANCE_PROTECTSKINS;Proteggi l'incarnato +TP_VIBRANCE_PSTHRESHOLD;Soglia toni pastello/saturi +TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Soglia Saturazione +TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;L'asse verticale rappresenta i toni pastello alla base e i toni saturi in cima.\nL'asse orizzontale rappresenta l'intervallo di saturazione. +TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Peso della transizione pastello/saturi +TP_VIBRANCE_SATURATED;Toni Saturi +TP_VIGNETTING_AMOUNT;Quantità +TP_VIGNETTING_CENTER;Centro +TP_VIGNETTING_CENTER_X;Centra X +TP_VIGNETTING_CENTER_Y;Centra Y +TP_VIGNETTING_LABEL;Correzione Vignettatura +TP_VIGNETTING_RADIUS;Raggio +TP_VIGNETTING_STRENGTH;Forza +TP_WBALANCE_AUTO;Automatico +TP_WBALANCE_CAMERA;Fotocamera +TP_WBALANCE_CLOUDY;Nuvoloso +TP_WBALANCE_CUSTOM;Personalizzato +TP_WBALANCE_DAYLIGHT;Luce Diurna (soleggiato) +TP_WBALANCE_EQBLUERED;Equalizzatore Blu/Rosso +TP_WBALANCE_EQBLUERED_TOOLTIP;Consente di deviare dal comportamento normale del "bilanciamento del bianco" modulando il bilanciamento blu/rosso.\nPuò essere utile quando le condizioni di ripresa:\na) sono molto diverse dalle illuminazioni normali (ad esempio, sott'acqua),\nb) sono molto diverse dalle condizioni alle quali sono state effettuate le calibrazioni,\nc) quando le matrici o i profili ICC non sono disponibili. +TP_WBALANCE_FLASH55;Leica +TP_WBALANCE_FLASH60;Standard, Canon, Pentax, Olympus +TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta +TP_WBALANCE_FLASH_HEADER;Flash +TP_WBALANCE_FLUO1;F1 - Luce Diurna +TP_WBALANCE_FLUO2;F2 - Bianco Freddo +TP_WBALANCE_FLUO3;F3 - Bianco +TP_WBALANCE_FLUO4;F4 - Bianco Caldo +TP_WBALANCE_FLUO5;F5 - Luce Diurna +TP_WBALANCE_FLUO6;F6 - Bianco Chiaro +TP_WBALANCE_FLUO7;F7 - D65 Simulatore di Luce Diurna +TP_WBALANCE_FLUO8;F8 - D50 / Sylvania F40 Design +TP_WBALANCE_FLUO9;F9 - Bianco Freddo Deluxe +TP_WBALANCE_FLUO10;F10 - Philips TL85 +TP_WBALANCE_FLUO11;F11 - Philips TL84 +TP_WBALANCE_FLUO12;F12 - Philips TL83 +TP_WBALANCE_FLUO_HEADER;Fluorescente +TP_WBALANCE_GREEN;Tinta +TP_WBALANCE_GTI;GTI +TP_WBALANCE_HMI;HMI +TP_WBALANCE_JUDGEIII;JudgeIII +TP_WBALANCE_LABEL;Bilanciamento del bianco +TP_WBALANCE_LAMP_HEADER;Lamp +TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 +TP_WBALANCE_LED_HEADER;LED +TP_WBALANCE_LED_LSI;LSI Lumelex 2040 +TP_WBALANCE_METHOD;Metodo +TP_WBALANCE_SHADE;Ombra +TP_WBALANCE_SIZE;Dimensione: +TP_WBALANCE_SOLUX35;Solux 3500K +TP_WBALANCE_SOLUX41;Solux 4100K +TP_WBALANCE_SOLUX47;Solux 4700K (vendor) +TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) +TP_WBALANCE_SPOTWB;Punto BB +TP_WBALANCE_TEMPERATURE;Temperatura +TP_WBALANCE_TUNGSTEN;Tungsteno +TP_WBALANCE_WATER1;Subacqueo 1 +TP_WBALANCE_WATER2;Subacqueo 2 +TP_WBALANCE_WATER_HEADER;Subacqueo +ZOOMPANEL_100;(100%) +ZOOMPANEL_NEWCROPWINDOW;Apri (nuova) finestra di dettaglio +ZOOMPANEL_ZOOM100;Ingrandimento al 100%.\nScorciatoia: z +ZOOMPANEL_ZOOMFITSCREEN;Adatta allo schermo.\nScorciatoia: f +ZOOMPANEL_ZOOMIN;Ingrandisci.\nScorciatoia: + +ZOOMPANEL_ZOOMOUT;Rimpicciolisci.\nScorciatoia: - + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!CURVEEDITOR_AXIS_IN;I: +!CURVEEDITOR_AXIS_LEFT_TAN;LT: +!CURVEEDITOR_AXIS_OUT;O: +!CURVEEDITOR_AXIS_RIGHT_TAN;RT: +!CURVEEDITOR_EDITPOINT_HINT;Enable edition of node in/out values.\n\nRight-click on a node to select it.\nRight-click on empty space to de-select the node. +!EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels +!FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!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_ASIMAGE;As Image +!HISTORY_MSG_256;NR - Median type +!HISTORY_MSG_257;Color Toning +!HISTORY_MSG_258;CT - Color curve +!HISTORY_MSG_259;CT - Opacity curve +!HISTORY_MSG_260;CT - a*[b*] opacity +!HISTORY_MSG_261;CT - Method +!HISTORY_MSG_262;CT - b* opacity +!HISTORY_MSG_263;CT - Shadows - Red +!HISTORY_MSG_264;CT - Shadows - Green +!HISTORY_MSG_265;CT - Shadows - Blue +!HISTORY_MSG_266;CT - Mid - Red +!HISTORY_MSG_267;CT - Mid - Green +!HISTORY_MSG_268;CT - Mid - Blue +!HISTORY_MSG_269;CT - High - Red +!HISTORY_MSG_270;CT - High - Green +!HISTORY_MSG_271;CT - High - Blue +!HISTORY_MSG_272;CT - Balance +!HISTORY_MSG_273;CT - Reset +!HISTORY_MSG_274;CT - Sat. Shadows +!HISTORY_MSG_275;CT - Sat. Highlights +!HISTORY_MSG_276;CT - Opacity +!HISTORY_MSG_277;--unused-- +!HISTORY_MSG_278;CT - Preserve luminance +!HISTORY_MSG_279;CT - Shadows +!HISTORY_MSG_280;CT - Highlights +!HISTORY_MSG_281;CT - Sat. strength +!HISTORY_MSG_282;CT - Sat. threshold +!HISTORY_MSG_283;CT - Strength +!HISTORY_MSG_284;CT - Auto sat. protection +!HISTORY_MSG_285;NR - Median - Method +!HISTORY_MSG_286;NR - Median - Type +!HISTORY_MSG_287;NR - Median - Iterations +!HISTORY_MSG_288;Flat Field - Clip control +!HISTORY_MSG_289;Flat Field - Clip control - Auto +!HISTORY_MSG_290;Black Level - Red +!HISTORY_MSG_291;Black Level - Green +!HISTORY_MSG_292;Black Level - Blue +!HISTORY_MSG_293;Film Simulation +!HISTORY_MSG_294;Film Simulation - Strength +!HISTORY_MSG_295;Film Simulation - Film +!HISTORY_MSG_296;NR - Luminance curve +!HISTORY_MSG_297;NR - Quality +!HISTORY_MSG_298;Dead pixel filter +!HISTORY_MSG_299;NR - Chrominance curve +!HISTORY_MSG_300;- +!HISTORY_MSG_301;NR - Luma control +!HISTORY_MSG_302;NR - Chroma method +!HISTORY_MSG_303;NR - Chroma method +!HISTORY_MSG_304;W - Contrast levels +!HISTORY_MSG_305;Wavelet Levels +!HISTORY_MSG_306;W - Preview +!HISTORY_MSG_307;W - Preview +!HISTORY_MSG_308;W - Preview direction +!HISTORY_MSG_309;W - ES - Detail +!HISTORY_MSG_310;W - Residual - Sky tar/prot +!HISTORY_MSG_311;W - Wavelet levels +!HISTORY_MSG_312;W - Residual - Shadows threshold +!HISTORY_MSG_313;W - Chroma - Sat/past +!HISTORY_MSG_314;W - Gamut - Reduce artifacts +!HISTORY_MSG_315;W - Residual - Contrast +!HISTORY_MSG_316;W - Gamut - Skin tar/prot +!HISTORY_MSG_317;W - Gamut - Skin hue +!HISTORY_MSG_318;W - Contrast - Highlight levels +!HISTORY_MSG_319;W - Contrast - Highlight range +!HISTORY_MSG_320;W - Contrast - Shadow range +!HISTORY_MSG_321;W - Contrast - Shadow levels +!HISTORY_MSG_322;W - Gamut - Avoid color shift +!HISTORY_MSG_323;W - ES - Local contrast +!HISTORY_MSG_324;W - Chroma - Pastel +!HISTORY_MSG_325;W - Chroma - Saturated +!HISTORY_MSG_326;W - Chroma - Method +!HISTORY_MSG_327;W - Contrast - Apply to +!HISTORY_MSG_328;W - Chroma - Link strength +!HISTORY_MSG_329;W - Toning - Opacity RG +!HISTORY_MSG_330;W - Toning - Opacity BY +!HISTORY_MSG_331;W - Contrast levels - Extra +!HISTORY_MSG_332;W - Tiling method +!HISTORY_MSG_333;W - Residual - Shadows +!HISTORY_MSG_334;W - Residual - Chroma +!HISTORY_MSG_335;W - Residual - Highlights +!HISTORY_MSG_336;W - Residual - Highlights threshold +!HISTORY_MSG_337;W - Residual - Sky hue +!HISTORY_MSG_338;W - ES - Radius +!HISTORY_MSG_339;W - ES - Strength +!HISTORY_MSG_340;W - Strength +!HISTORY_MSG_341;W - Edge performance +!HISTORY_MSG_342;W - ES - First level +!HISTORY_MSG_343;W - Chroma levels +!HISTORY_MSG_344;W - Meth chroma sl/cur +!HISTORY_MSG_345;W - ES - Local contrast +!HISTORY_MSG_346;W - ES - Local contrast method +!HISTORY_MSG_347;W - Denoise - Level 0 +!HISTORY_MSG_348;W - Denoise - Level 1 +!HISTORY_MSG_349;W - Denoise - Level 2 +!HISTORY_MSG_350;W - ES - Edge detection +!HISTORY_MSG_351;W - Residual - HH curve +!HISTORY_MSG_352;W - Background +!HISTORY_MSG_353;W - ES - Gradient sensitivity +!HISTORY_MSG_354;W - ES - Enhance +!HISTORY_MSG_355;W - ES - Threshold low +!HISTORY_MSG_356;W - ES - Threshold high +!HISTORY_MSG_357;W - Denoise - Link with ES +!HISTORY_MSG_358;W - Gamut - CH +!HISTORY_MSG_359;Hot/Dead - Threshold +!HISTORY_MSG_360;TM Gamma +!HISTORY_MSG_361;W - Final - Chroma balance +!HISTORY_MSG_362;W - Residual - Compression method +!HISTORY_MSG_363;W - Residual - Compression strength +!HISTORY_MSG_364;W - Final - Contrast balance +!HISTORY_MSG_365;W - Final - Delta balance +!HISTORY_MSG_366;W - Residual - Compression gamma +!HISTORY_MSG_367;W - ES - Local contrast curve +!HISTORY_MSG_368;W - Final - Contrast balance +!HISTORY_MSG_369;W - Final - Balance method +!HISTORY_MSG_370;W - Final - Local contrast curve +!MAIN_TAB_INSPECT; Inspect +!MAIN_TAB_WAVELET;Wavelet +!MAIN_TAB_WAVELET_TOOLTIP;Shortcut: Alt-w +!PARTIALPASTE_COLORTONING;Color Toning +!PARTIALPASTE_EQUALIZER;Wavelet Equalizer +!PARTIALPASTE_FILMSIMULATION;Film Simulation +!PARTIALPASTE_FLATFIELDCLIPCONTROL;Flat-field clip control +!PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter +!PARTIALPASTE_PREPROCESS_HOTPIXFILT;Hot pixel filter +!PARTIALPASTE_WAVELETGROUP;Wavelet processing +!PREFERENCES_AUTLISLOW;Low +!PREFERENCES_AUTLISMAX;Max - Average of all tiles +!PREFERENCES_AUTLISSTD;High +!PREFERENCES_AUTLISVLOW;None +!PREFERENCES_AUTLOW;Low +!PREFERENCES_AUTSTD;Standard +!PREFERENCES_CIEART_FRAME;CIECAM02-Specific Settings +!PREFERENCES_CLUTSCACHE;HaldCLUT Cache +!PREFERENCES_CLUTSCACHE_LABEL;Maximum number of cached CLUTs +!PREFERENCES_CLUTSDIR;HaldCLUT directory +!PREFERENCES_CURVEBBOXPOS;Position of curve copypasta buttons +!PREFERENCES_CURVEBBOXPOS_ABOVE;Above +!PREFERENCES_CURVEBBOXPOS_BELOW;Below +!PREFERENCES_CURVEBBOXPOS_LEFT;Left +!PREFERENCES_CURVEBBOXPOS_RIGHT;Right +!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_EXPAUT;Expert +!PREFERENCES_FILMSIMULATION;Film Simulation +!PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT;Same thumbnail height between the Editor's panel 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_GREYSC18;Yb=18 CIE L#50 +!PREFERENCES_GREYSCA;Automatic +!PREFERENCES_GREYSC;Scene Yb luminance (%) +!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_LEVAUTDN;Denoising level +!PREFERENCES_LEVDN;Cell size +!PREFERENCES_LISS;Auto multi-zone smoothing +!PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders +!PREFERENCES_MAX;Maxi (Tile) +!PREFERENCES_MED;Medium (Tile/2) +!PREFERENCES_MIN;Mini (100x115) +!PREFERENCES_NAVIGATIONFRAME;Navigation +!PREFERENCES_NOISE;Noise Reduction +!PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Overlay filenames on thumbnails in the editor pannel +!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_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_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_SHOWFILMSTRIPTOOLBAR;Show filmstrip toolbar +!PREFERENCES_SIMPLAUT;Tool mode +!PREFERENCES_SMA;Small (250x287) +!PREFERENCES_STDAUT;Standard +!PREFERENCES_TIMAX;High +!PREFERENCES_TINB;Number of tiles +!PREFERENCES_TISTD;Standard +!PREFERENCES_WAVLEV;Increase wavelet level in quality 'high' +!PREFERENCES_WLONE;One level +!PREFERENCES_WLTWO;Two levels +!PREFERENCES_WLZER;No +!TP_COLORTONING_AB;o C/L +!TP_COLORTONING_AUTOSAT;Automatic +!TP_COLORTONING_BALANCE;Balance +!TP_COLORTONING_BY;o C/L +!TP_COLORTONING_CHROMAC;Opacity +!TP_COLORTONING_COLOR;Color +!TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;Chroma opacity as a function of luminance oC=f(L) +!TP_COLORTONING_HIGHLIGHT;Highlights +!TP_COLORTONING_HUE;Hue +!TP_COLORTONING_LABEL;Color Toning +!TP_COLORTONING_LAB;L*a*b* blending +!TP_COLORTONING_LUMAMODE;Preserve luminance +!TP_COLORTONING_LUMAMODE_TOOLTIP;If enabled, when you change color (red, green, cyan, blue, etc.) the luminance of each pixel is preserved. +!TP_COLORTONING_LUMA;Luminance +!TP_COLORTONING_METHOD;Method +!TP_COLORTONING_METHOD_TOOLTIP;"L*a*b* blending", "RGB sliders" and "RGB curves" use interpolated color blending.\n"Color balance (Shadows/Midtones/Highlights)" and "Saturation 2 colors" use direct colors.\n\nThe Black-and-White tool can be enabled when using any color toning method, which allows for color toning. +!TP_COLORTONING_MIDTONES;Midtones +!TP_COLORTONING_NEUTRAL;Reset sliders +!TP_COLORTONING_NEUTRAL_TIP;Reset all values (Shadows, Midtones, Highlights) to default. +!TP_COLORTONING_OPACITY;Opacity +!TP_COLORTONING_RGBCURVES;RGB - Curves +!TP_COLORTONING_RGBSLIDERS;RGB - Sliders +!TP_COLORTONING_SATURATEDOPACITY;Strength +!TP_COLORTONING_SATURATIONTHRESHOLD;Threshold +!TP_COLORTONING_SA;Saturation Protection +!TP_COLORTONING_SHADOWS;Shadows +!TP_COLORTONING_SPLITCOCO;Color Balance Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITCO;Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITLR;Saturation 2 colors +!TP_COLORTONING_STRENGTH;Strength +!TP_COLORTONING_STR;Strength +!TP_COLORTONING_TWO2;Special chroma '2 colors' +!TP_COLORTONING_TWOALL;Special chroma +!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_GTHARMMEANS;Harmonic Means +!TP_CROP_GTTRIANGLE1;Golden Triangles 1 +!TP_CROP_GTTRIANGLE2;Golden Triangles 2 +!TP_DIRPYRDENOISE_33;3×3 strong +!TP_DIRPYRDENOISE_55SOFT;5×5 +!TP_DIRPYRDENOISE_55;5×5 strong +!TP_DIRPYRDENOISE_77;7×7 (slow) +!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_ABM;Chroma only +!TP_DIRPYRDENOISE_AUTO;Automatic global +!TP_DIRPYRDENOISE_AUTO_TOOLTIP;Try to evaluate chroma noise\nBe careful, this calculation is average, and is quite subjective ! +!TP_DIRPYRDENOISE_AUT;Automatic global +!TP_DIRPYRDENOISE_C2TYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CCCURVE;Chrominance curve +!TP_DIRPYRDENOISE_CHROMAFR;Chrominance +!TP_DIRPYRDENOISE_CTYPE;Auto method +!TP_DIRPYRDENOISE_CTYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nAutomatic multi-zones\nNo preview - works only during saving, but using the "Preview" method by matching the tile size and center to the preview size and center you can get an idea of the expected results.\nThe image is divided into tiles (about 10 to 70 depending on image size) and each tile receives its own chrominance noise reduction settings.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CURVEEDITOR_CC;Chroma +!TP_DIRPYRDENOISE_CURVEEDITOR_CC_TOOLTIP;Increase (multiply) the value of all chrominance sliders.\nThis curve lets you adjust the strength of chromatic noise reduction as a function of chromaticity, for instance to increase the action in areas of low saturation and to decrease it in those of high saturation. +!TP_DIRPYRDENOISE_CURVEEDITOR_L_TOOLTIP;Modulates action of 'Luminance' denoise +!TP_DIRPYRDENOISE_CUR;Curve +!TP_DIRPYRDENOISE_LABM;L*a*b* +!TP_DIRPYRDENOISE_LCURVE;Luminance curve +!TP_DIRPYRDENOISE_LM;Luminance only +!TP_DIRPYRDENOISE_LPLABM;Weighted L* (little) + a*b* (normal) +!TP_DIRPYRDENOISE_LTYPE;Luminance control +!TP_DIRPYRDENOISE_LUMAFR;Luminance +!TP_DIRPYRDENOISE_LUMAFR_TOOLTIP;Wavelet on luminance and Fourier transform for luminance detail +!TP_DIRPYRDENOISE_MANU;Manual +!TP_DIRPYRDENOISE_MAN;Manual +!TP_DIRPYRDENOISE_MEDMETHOD;Median method +!TP_DIRPYRDENOISE_MEDTYPE;Median type +!TP_DIRPYRDENOISE_MED;Median Filter +!TP_DIRPYRDENOISE_MED_TOOLTIP;Enabled median denoising +!TP_DIRPYRDENOISE_METHOD11;Quality +!TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. +!TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - +!TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 +!TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. +!TP_DIRPYRDENOISE_PASSES;Median iterations +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PON;Auto multi-zones +!TP_DIRPYRDENOISE_PREVLABEL;Preview size=%1, Center: Px=%2 Py=%3 +!TP_DIRPYRDENOISE_PREV;Preview +!TP_DIRPYRDENOISE_PRE;Preview multi-zones +!TP_DIRPYRDENOISE_RGBM;RGB +!TP_DIRPYRDENOISE_SHALBI;High +!TP_DIRPYRDENOISE_SHAL;Standard +!TP_DIRPYRDENOISE_SLI;Slider +!TP_DIRPYRDENOISE_SOFT;3x3 +!TP_DIRPYRDENOISE_TILELABEL;Tile size=%1, Center: Tx=%2 Ty=%3 +!TP_DIRPYREQUALIZER_ARTIF;Reduce artifacts +!TP_EPD_GAMMA;Gamma +!TP_EXPOSURE_TCMODE_LUMINANCE;Luminance +!TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points +!TP_EXPOS_WHITEPOINT_LABEL;Raw White Points +!TP_FILMSIMULATION_LABEL;Film Simulation +!TP_FILMSIMULATION_STRENGTH;Strength +!TP_FILMSIMULATION_ZEROCLUTSFOUND;Set HaldCLUT directory in Preferences +!TP_FLATFIELD_CLIPCONTROL;Clip control +!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. +!TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance +!TP_PREPROCESS_DEADPIXFILT;Dead pixel filter +!TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Tries to suppress dead pixels. +!TP_PREPROCESS_HOTPIXFILT;Hot pixel filter +!TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Tries to suppress hot pixels. +!TP_RAWEXPOS_BLACK_0;Green 1 (lead) +!TP_RAWEXPOS_BLACK_1;Red +!TP_RAWEXPOS_BLACK_2;Blue +!TP_RAWEXPOS_BLACK_3;Green 2 +!TP_RAWEXPOS_BLACK_BLUE;Blue +!TP_RAWEXPOS_BLACK_GREEN;Green +!TP_RAWEXPOS_BLACK_RED;Red +!TP_RAWEXPOS_RGB;Red, Green, Blue +!TP_RAW_HD;Threshold +!TP_RAW_HD_TOOLTIP;Lower values make hot/dead pixel detection more aggressive, but false positives may lead to artifacts. If you notice any artifacts appearing when enabling the Hot/Dead Pixel Filters, gradually increase the threshold value until they disappear. +!TP_RAW_SENSOR_BAYER_LABEL;Sensor with Bayer Matrix +!TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;3-pass gives best results (recommended for low ISO images).\n1-pass is almost undistinguishable from 3-pass for high ISO images and is faster. +!TP_RAW_SENSOR_XTRANS_LABEL;Sensor with X-Trans Matrix +!TP_WAVELET_1;Level 1 +!TP_WAVELET_2;Level 2 +!TP_WAVELET_3;Level 3 +!TP_WAVELET_4;Level 4 +!TP_WAVELET_5;Level 5 +!TP_WAVELET_6;Level 6 +!TP_WAVELET_7;Level 7 +!TP_WAVELET_8;Level 8 +!TP_WAVELET_9;Level 9 +!TP_WAVELET_ALL;All levels in all directions +!TP_WAVELET_APPLYTO;Apply To +!TP_WAVELET_AVOID;Avoid color shift +!TP_WAVELET_B0;Black +!TP_WAVELET_B1;Grey +!TP_WAVELET_B2;Residual +!TP_WAVELET_BACUR;Curve +!TP_WAVELET_BALANCE;Contrast balance d/v-h +!TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chromaticity or residual tone mapping are activated, the effect due to balance is amplified. +!TP_WAVELET_BALCHRO;Chroma balance +!TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chromaticity balance. +!TP_WAVELET_BANONE;None +!TP_WAVELET_BASLI;Slider +!TP_WAVELET_BATYPE;Contrast balance method +!TP_WAVELET_CCURVE;Local contrast +!TP_WAVELET_CH1;Whole chromaticity range +!TP_WAVELET_CH2;Saturated/pastel +!TP_WAVELET_CH3;Link contrast levels +!TP_WAVELET_CHCU;Curve +!TP_WAVELET_CHRO;Saturated/pastel threshold +!TP_WAVELET_CHRO_TOOLTIP;Sets the wavelet level which will be the threshold between saturated and pastel colors.\n1-x: saturated\nx-9: pastel\n\nIf the value exceeds the amount of wavelet levels you are using then it will be ignored. +!TP_WAVELET_CHR;Chroma-contrast link strength +!TP_WAVELET_CHR_TOOLTIP;Adjusts chromaticity as a function of "contrast levels" and "chroma-contrast link strength" +!TP_WAVELET_CHSL;Sliders +!TP_WAVELET_CHTYPE;Chrominance method +!TP_WAVELET_COLORT;Opacity Red-Green +!TP_WAVELET_COMBOTH;Both +!TP_WAVELET_COMPCONT;Contrast +!TP_WAVELET_COMPGAMMA;Compression gamma +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjusting the gamma of the residual image allow you to equilibrate the data and histogram. +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjust gamma for residual image and compression.\nAllow to equilibrate data and histogram +!TP_WAVELET_COMPTM;Tone mapping +!TP_WAVELET_CONTEDIT;'After' Contrast curve +!TP_WAVELET_CONTEDIT;'After' contrast curve +!TP_WAVELET_CONTRAST_MINUS;Contrast - +!TP_WAVELET_CONTRAST_PLUS;Contrast + +!TP_WAVELET_CONTRA;Contrast +!TP_WAVELET_CONTRA_TOOLTIP;Changes contrast of the residual image. +!TP_WAVELET_CONTR;Gamut +!TP_WAVELET_CTYPE;Chrominance control +!TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modifies local contrast as a function of the original local contrast (absciss)\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 100..300)\n66% absciss represents standard deviation of local contrast (real value about 300..800)\n100% represents maximum (real value about 3000..8000) +!TP_WAVELET_CURVEEDITOR_CH;Contrast levels=f(Hue) +!TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modifies each level's contrast as a function oh hue.\nTake care not to overwrite changes made with the Gamut Hue controls.\nThe curve will only have an effect when wavelet contrast level sliders are non-zero. +!TP_WAVELET_CURVEEDITOR_CL;L +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Applies a final contrast luminance curve at the end of the wavelet treatment. +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Apply a contrast luminance curve at the end of wavelet level threatment +!TP_WAVELET_CURVEEDITOR_HH;HH +!TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modifies the residual image's hue as a function of hue. +!TP_WAVELET_DALL;All directions +!TP_WAVELET_DAUB;Edge performance +!TP_WAVELET_DAUB_TOOLTIP;Changes Daubechies coefficients:\nD4 = Standard,\nD14 = Often best performance, 10% more time-intensive.\n\nAffects edge detection as well as the general quality of the firsts levels. However the quality is not strictly related to this coefficient and can vary with images and uses. +!TP_WAVELET_DISP;Preview Settings +!TP_WAVELET_DONE;Vertical +!TP_WAVELET_DTHR;Diagonal +!TP_WAVELET_DTWO;Horizontal +!TP_WAVELET_EDCU;Curve +!TP_WAVELET_EDGCONT;Local contrast +!TP_WAVELET_EDGCONT_TOOLTIP;Adjusting the points to the left decreases contrast, and to the right increases it.\nBottom-left, Top-Left, Top-Right, Bottom-right represent respectively local contast for low values, mean, mean+stdev, maxima +!TP_WAVELET_EDGEDETECTTHR2;Threshold high (detection) +!TP_WAVELET_EDGEDETECTTHR;Threshold low (noise) +!TP_WAVELET_EDGEDETECTTHR_TOOLTIP;This adjuster lets you target edge detection for example to avoid applying edge sharpness to fine details, such as noise in the sky. +!TP_WAVELET_EDGEDETECT;Gradient sensitivity +!TP_WAVELET_EDGEDETECT_TOOLTIP;Moving the slider to the right increases edge sensitivity. This affects local contrast, edge settings and noise. +!TP_WAVELET_EDGE;Edge Sharpness +!TP_WAVELET_EDGREINF_TOOLTIP;Reinforce or reduce the action of the first level, do the opposite to the second level, and leave the rest unchanged. +!TP_WAVELET_EDGTHRESH;Detail +!TP_WAVELET_EDGTHRESH_TOOLTIP;Change the repartition between the first levels and the others. The higher the threshold the more the action is centred on the first levels. Be careful with negative values, they increase the action of high levels and can introduce artifacts. +!TP_WAVELET_EDRAD;Radius +!TP_WAVELET_EDRAD_TOOLTIP;This radius adjustment is very different from those in other sharpening tools. Its value is compared to each level through a complex function. In this sense, a value of zero still has an effect. +!TP_WAVELET_EDSL;Threshold Sliders +!TP_WAVELET_EDTYPE;Local contrast method +!TP_WAVELET_EDVAL;Strength +!TP_WAVELET_FINAL;Final Touchup +!TP_WAVELET_FINEST;Finest +!TP_WAVELET_HIGHLIGHT;Highlight luminance range +!TP_WAVELET_HS1;Whole luminance range +!TP_WAVELET_HS2;Shadows/Highlights +!TP_WAVELET_HUESKIN;Skin hue +!TP_WAVELET_HUESKIN_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_HUESKY;Sky hue +!TP_WAVELET_HUESKY_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_INF;Below or equal the level +!TP_WAVELET_ITER;Delta balance levels +!TP_WAVELET_ITER_TOOLTIP;Left: increase low levels and reduce high levels,\nRight: reduce low levels and increase high levels. +!TP_WAVELET_LABEL;Wavelet levels +!TP_WAVELET_LARGEST;Coarsest +!TP_WAVELET_LEVCH;Chromaticity +!TP_WAVELET_LEVELS;Wavelet levels +!TP_WAVELET_LEVELS_TOOLTIP;Choose the number of detail levels the image is to be decomposed into. More levels require more RAM and require a longer processing time. +!TP_WAVELET_LEVF;Contrast +!TP_WAVELET_LEVLABEL;Preview maximum possible levels = %1 +!TP_WAVELET_LEVONE;Level 2 +!TP_WAVELET_LEVTWO;Level 3 +!TP_WAVELET_LEVZERO;Level 1 +!TP_WAVELET_LINKEDG;Link with Edge Sharpness' Strength +!TP_WAVELET_LIPST;Enhanced algorithm +!TP_WAVELET_LIPST_TOOLTIP;This algorithm uses Lipschitz regularity to increase edge detection quality at a cost of increased processing time and memory requirements. +!TP_WAVELET_LOWLIGHT;Shadow luminance range +!TP_WAVELET_MEDGREINF;First level +!TP_WAVELET_MEDILEV;Edge detection +!TP_WAVELET_MEDI;Reduce artifacts in blue sky +!TP_WAVELET_NEUTRAL;Neutral +!TP_WAVELET_NOISE;Denoise and Refine +!TP_WAVELET_NOIS;Denoise +!TP_WAVELET_ONE;One level +!TP_WAVELET_OPACITYWL;Final local contrast +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify final local contrast in function of last local contrast (absciss) for all levels decomposition\nTake into account: \na)contrast levels \nb)edge sharpness \nc)contrast balance\nd)decomposition-recomposition\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 200..1000)\n66% absciss represents standard deviation of local contrast (real value about 1000..2000)\n100% represents maximum (real value about 5000..13000) +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify the final local contrast at the end of the wavelet treatment.\n\nThe left side represents the smallest local contrast, progressing to the largest local contrast on the right. +!TP_WAVELET_OPACITYW;Contrast balance d/v-h curve +!TP_WAVELET_OPACITY;Opacity Blue-Yellow +!TP_WAVELET_PASTEL;Pastel chromaticity +!TP_WAVELET_PREVIEWBACK;Background +!TP_WAVELET_PREVIEWLEVELS;Preview +!TP_WAVELET_RE1;Reinforced +!TP_WAVELET_RE2;Unchanged +!TP_WAVELET_RE3;Reduced +!TP_WAVELET_RESCHRO;Chromaticity +!TP_WAVELET_RESCONH;Highlights +!TP_WAVELET_RESCON;Shadows +!TP_WAVELET_RESID;Residual image +!TP_WAVELET_SAT;Saturated chromaticity +!TP_WAVELET_SETTINGS;Wavelet Settings +!TP_WAVELET_SKIN;Skin targetting/protection +!TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected. +!TP_WAVELET_SKY;Sky targetting/protection +!TP_WAVELET_SKY_TOOLTIP;At -100 sky-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 sky-tones are protected while all other tones are affected. +!TP_WAVELET_STRENGTH;Strength +!TP_WAVELET_STREN;Strength +!TP_WAVELET_SUPE;Extra +!TP_WAVELET_SUP;Above the level +!TP_WAVELET_THRESHOLD2;Shadow levels +!TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels between 9 and 9 minus the value will be affected by the shadow luminance range. Other levels will be fully treated. The highest level possible is limited by the highlight level value (9 minus highlight level value). +!TP_WAVELET_THRESHOLD;Highlight levels +!TP_WAVELET_THRESHOLD_TOOLTIP;Only levels beyond the chosen value will be affected by the highlight luminance range. Other levels will be fully treated. The chosen value here limits the highest possible value of the shadow levels. +!TP_WAVELET_THRH;Highlights threshold +!TP_WAVELET_THR;Shadows threshold +!TP_WAVELET_TILESBIG;Big tiles +!TP_WAVELET_TILESFULL;Full image +!TP_WAVELET_TILESIZE;Tiling method +!TP_WAVELET_TILESLIT;Little tiles +!TP_WAVELET_TILES_TOOLTIP;Processing the full image leads to better quality and is the recommended option, while using tiles is a fall-back solution for users with little RAM. Refer to RawPedia for memory requirements. +!TP_WAVELET_TMHIGH;High +!TP_WAVELET_TMLOWHIGH;Low+High +!TP_WAVELET_TMNONE;None +!TP_WAVELET_TMSTD;Standard +!TP_WAVELET_TMSTRENGTH;Compression strength +!TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image. When the value is different from 0, the Strength and Gamma sliders of the Tone Mapping tool in the Exposure tab will become grayed out. +!TP_WAVELET_TMTYPE;Compression method +!TP_WAVELET_TON;Toning +!TP_WAVELET_daub2;D2 - low +!TP_WAVELET_daub4;D4 - standard +!TP_WAVELET_daub6;D6 - standard plus +!TP_WAVELET_daub10;D10 - medium +!TP_WAVELET_daub14;D14 - high +!ZOOMPANEL_ZOOMFITCROPSCREEN;Fit crop to screen\nShortcut: Alt-f diff --git a/rtdata/languages/Japanese b/rtdata/languages/Japanese new file mode 100644 index 000000000..ede65a402 --- /dev/null +++ b/rtdata/languages/Japanese @@ -0,0 +1,1877 @@ +#01 2011-05-15 a3novy +#02 2011-11-13 a3novy +#03 2011-11-20 a3novy +#04 2011-12-03 a3novy +#05 2012-02-11 a3novy +#06 2012-04-04 a3novy +#07 2012-07-12 a3novy +#08 2012-12-22 a3novy +#09 2013-04-01 a3novy +#10 2013-04-19 a3novy +#11 2013-09-10 firefly +#12 2013-10-28 firefly +#13 2014-01-07 firefly +#14 2014-01-15 firefly +#15 2014-02-25 firefly +#16 2014-04-07 firefly +#17 2014-04-08 firefly +#18 2014-05-16 firefly +#19 2014-07-13 firefly +#20 2014-07-24 firefly +#21 2014-09-11 firefly +#22 2014-10-21 firefly +#23 2014-11-07 firefly +#24 2014-11-18 firefly +#25 2015-01-05 firefly +#26 2015-02-17 firefly +#27 2015-02-21 firefly +#28 2015-03-03 firefly +#29 2015-04-20 firefly +#30 2015-05-01 firefly +#31 2015-05-31 firefly +#32 2015-06-13 firefly + +ABOUT_TAB_BUILD;バージョン +ABOUT_TAB_CREDITS;クレジット +ABOUT_TAB_LICENSE;ライセンス +ABOUT_TAB_RELEASENOTES;リリースノート +ABOUT_TAB_SPLASH;スプラッシュ +ADJUSTER_RESET_TO_DEFAULT;デフォルト値に戻す +BATCHQUEUE_AUTOSTART;オートスタート +BATCHQUEUE_DESTFILENAME;パスとファイル名 +BATCH_PROCESSING;バッチ処理 +CURVEEDITOR_AXIS_IN;I: +CURVEEDITOR_AXIS_LEFT_TAN;LT: +CURVEEDITOR_AXIS_OUT;O: +CURVEEDITOR_AXIS_RIGHT_TAN;RT: +CURVEEDITOR_CURVES;カーブ +CURVEEDITOR_CURVE;カーブ +CURVEEDITOR_CUSTOM;カスタム +CURVEEDITOR_DARKS;ダーク +CURVEEDITOR_EDITPOINT_HINT;ボタンを押すと数値で入出力を編集出来ます\n\n編集したいカーブ上のポイントを右クリックします\n編集を無効にする場合はポイント以外の部分んで右クリックします +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;フォルダ +EDITWINDOW_TITLE;画像編集 +EDIT_OBJECT_TOOLTIP;この機能を使うための目安に、プレビュー画面にガイドを表示する +EDIT_PIPETTE_TOOLTIP;カーブ上に調整ポイントを追加するには、Ctrlキーを押しながら、プレビューの画像上の目標ポイントを左クリックします。\n追加されたそのポイントを調整するには、Ctrlキーを押しながら、プレビュー画像のそのポイントに当たる部分を左クリックします。それからCtrlキーを離し(微妙な調整をする場合はそのまま)、左クリックしたままマウスを画面上で上下に動かすと、それに合わせてトーンカーブが調整されます。 +EXIFFILTER_APERTURE;絞り +EXIFFILTER_CAMERA;カメラ +EXIFFILTER_EXPOSURECOMPENSATION;露光量補正 (EV) +EXIFFILTER_FILETYPE;ファイル タイプ +EXIFFILTER_FOCALLEN;焦点距離 +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;レンズ +EXIFFILTER_METADATAFILTER;メタデータ絞り込みの適用 +EXIFFILTER_SHUTTER;シャッター +EXIFPANEL_ADDEDITHINT;新しいタグを追加、またはタグの編集 +EXIFPANEL_ADDEDIT;追加/編集 +EXIFPANEL_ADDTAGDLG_ENTERVALUE;値の入力 +EXIFPANEL_ADDTAGDLG_SELECTTAG;タグ選択 +EXIFPANEL_ADDTAGDLG_TITLE;タグの追加/編集 +EXIFPANEL_KEEPHINT;出力ファイルに書き込む際、選択タグをそのままにする +EXIFPANEL_KEEP;そのまま +EXIFPANEL_REMOVEHINT;出力ファイルに書き込む際、選択タグは外す +EXIFPANEL_REMOVE;削除 +EXIFPANEL_RESETALLHINT;すべて元の値にリセット +EXIFPANEL_RESETALL;すべてリセット +EXIFPANEL_RESETHINT;選択タグを元の値にリセット +EXIFPANEL_RESET;リセット +EXIFPANEL_SUBDIRECTORY;サブディレクトリ +EXPORT_BYPASS_ALL;全て選択 / 全て解除 +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_DCB_ENHANCE;[raw] DCB 拡張処理を迂回 +EXPORT_BYPASS_RAW_DCB_ITERATIONS;[raw] DCB 反復を迂回 +EXPORT_BYPASS_RAW_DF;[raw] ダークフレームを迂回 +EXPORT_BYPASS_RAW_FF;[raw] フラットフィールドを迂回 +EXPORT_BYPASS_RAW_GREENTHRESH;[raw] グリーン平衡化を迂回 +EXPORT_BYPASS_RAW_LINENOISE;[raw] ラインノイズ フィルタを迂回 +EXPORT_BYPASS_RAW_LMMSE_ITERATIONS;[raw] LMMSE 拡張処理を迂回 +EXPORT_BYPASS_SHARPENEDGE;エッジ・シャープ化を迂回 +EXPORT_BYPASS_SHARPENING;シャープ化を迂回 +EXPORT_BYPASS_SHARPENMICRO;マイクロコントラストを迂回 +EXPORT_BYPASS_SH_HQ;シャドウ/ハイライト(高画質)を迂回 +EXPORT_FASTEXPORTOPTIONS;高速書き出しオプション +EXPORT_INSTRUCTIONS;現像の設定に要する時間と手間を省くために、高速書き出しを優先させるオプションです。処理速度が優先される場合や、既定の現像パラメータを変えずに何枚ものリサイズ画像が要求される場合に奨められる方法で、低解像度画像を迅速に生成します。 +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_BROWSEPATHHINT;参照するパスを入力します\nCtrl-O パスのテキストボックスにフォーカス\nEnter / Ctrl-Enterその場所をブラウズします\nEsc 変更をクリア\nShift-Escフォーカスを削除\nパスのショートカット:\n ~ - ユーザーのホームディレクトリ\n ! - ユーザーの画像ディレクトリ +FILEBROWSER_CACHECLEARFROMFULL;cacheをクリア - すべて +FILEBROWSER_CACHECLEARFROMPARTIAL;cacheをクリア - 一部 +FILEBROWSER_CACHE;cache +FILEBROWSER_CLEARPROFILE;プロファイルのクリア +FILEBROWSER_COLORLABEL_TOOLTIP;カラー・ラベル\n\nドロップダウン・メニューからか、ショートカット:\nShift-Ctrl-1 レッド\nShift-Ctrl-2 イエロー\nShift-Ctrl-3 グリーン\nShift-Ctrl-4 ブルー\nShift-Ctrl-5 パープル +FILEBROWSER_COPYPROFILE;プロファイルをコピー +FILEBROWSER_CURRENT_NAME;現在の名前: +FILEBROWSER_DARKFRAME;ダークフレーム +FILEBROWSER_DELETEDLGLABEL;ファイル削除確認 +FILEBROWSER_DELETEDLGMSGINCLPROC;バッチ処理に組み込まれている選択済みのファイル %1 を削除してもいいですか? +FILEBROWSER_DELETEDLGMSG;選択済みのファイル %1 を削除してもいいですか? +FILEBROWSER_EMPTYTRASHHINT;ゴミ箱のファイルを完全に削除する +FILEBROWSER_EMPTYTRASH;ゴミ箱を空にする +FILEBROWSER_EXEC_CPB;カスタム・プロファイルビルダーを実行 +FILEBROWSER_EXTPROGMENU;..で開く +FILEBROWSER_FLATFIELD;フラットフィールド +FILEBROWSER_MOVETODARKFDIR;ダークフレーム・ディレクトリに移動 +FILEBROWSER_MOVETOFLATFIELDDIR;フラットフィールド・ディレクトリに移動 +FILEBROWSER_NEW_NAME;新しい名前: +FILEBROWSER_OPENDEFAULTVIEWER;Windowsのデフォルト・ビューア(キュー処理) +FILEBROWSER_PARTIALPASTEPROFILE;プロファイルの貼り付け - 一部 +FILEBROWSER_PASTEPROFILE;プロファイルの貼り付け +FILEBROWSER_POPUPCANCELJOB;ジョブ キャンセル +FILEBROWSER_POPUPCOLORLABEL0;ラベル: なし +FILEBROWSER_POPUPCOLORLABEL1;ラベル: レッド +FILEBROWSER_POPUPCOLORLABEL2;ラベル: イエロー +FILEBROWSER_POPUPCOLORLABEL3;ラベル: グリーン +FILEBROWSER_POPUPCOLORLABEL4;ラベル: ブルー +FILEBROWSER_POPUPCOLORLABEL5;ラベル: パープル +FILEBROWSER_POPUPCOLORLABEL;カラー・ラベル +FILEBROWSER_POPUPCOPYTO;コピーします... +FILEBROWSER_POPUPFILEOPERATIONS;ファイルの操作 +FILEBROWSER_POPUPMOVEEND;キュー処理の最後に移動 +FILEBROWSER_POPUPMOVEHEAD;キュー処理の最初に移動 +FILEBROWSER_POPUPMOVETO;移動します... +FILEBROWSER_POPUPOPENINEDITOR;編集画面を開く +FILEBROWSER_POPUPOPEN;開く +FILEBROWSER_POPUPPROCESSFAST;キューに追加 (高速書き出し) +FILEBROWSER_POPUPPROCESS;キューに追加 +FILEBROWSER_POPUPPROFILEOPERATIONS;プロファイルの操作 +FILEBROWSER_POPUPRANK0;ランクなし +FILEBROWSER_POPUPRANK1;ランク 1 * +FILEBROWSER_POPUPRANK2;ランク 2 ** +FILEBROWSER_POPUPRANK3;ランク 3 *** +FILEBROWSER_POPUPRANK4;ランク 4 **** +FILEBROWSER_POPUPRANK5;ランク 5 ***** +FILEBROWSER_POPUPRANK;ランク +FILEBROWSER_POPUPREMOVEINCLPROC;ファイルシステムとバッチの結果から削除 +FILEBROWSER_POPUPREMOVE;ファイルシステムから削除 +FILEBROWSER_POPUPRENAME;名前変更 +FILEBROWSER_POPUPSELECTALL;全選択 +FILEBROWSER_POPUPTRASH;ゴミ箱へ移動 +FILEBROWSER_POPUPUNRANK;ランクなし +FILEBROWSER_POPUPUNTRASH;ゴミ箱から移動 +FILEBROWSER_QUERYBUTTONHINT;検索ボックス内のヒントをクリア +FILEBROWSER_QUERYHINT;ファイルを検索する。ファイル名の一部でも可。複数の場合は、ファイル名をカンマで区切る\n例 1001,1004,1199\n\n入力した名前以外のファイルを検索する場合は、先頭に!=を入れる\n例 !=1001,1004,1199\n\nショートカット:\nCtrl-F 検索ボックスをフォーカスにする\nEnter 検索を開始\nEsc クリア\nShift-Escフォーカスを解除 +FILEBROWSER_QUERYLABEL; 検索: +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_RENAMEDLGMSG;"%1" にファイル名変更: +FILEBROWSER_SELECTDARKFRAME;ダークフレームの選択... +FILEBROWSER_SELECTFLATFIELD;フラットフィールドの選択... +FILEBROWSER_SHOWCOLORLABEL1HINT;レッド・ラベルの画像を表示\nショートカット: Alt-1 +FILEBROWSER_SHOWCOLORLABEL2HINT;イエロー・ラベルの画像を表示\nショートカット: Alt-2 +FILEBROWSER_SHOWCOLORLABEL3HINT;グリーン・ラベルの画像を表示\nショートカット: Alt-3 +FILEBROWSER_SHOWCOLORLABEL4HINT;ブルー・ラベルの画像を表示\nショートカット: Alt-4 +FILEBROWSER_SHOWCOLORLABEL5HINT;パープル・ラベルの画像を表示\nショートカット: Alt-5 +FILEBROWSER_SHOWDIRHINT;全ての絞り込みをクリア\nショートカット: d +FILEBROWSER_SHOWEDITEDHINT;編集済み画像を表示\nショートカット: 7 +FILEBROWSER_SHOWEDITEDNOTHINT;未編集画像を表示\nショートカット: 6 +FILEBROWSER_SHOWEXIFINFO;EXIF情報を表示\nショートカット: i\n\nシングル・エディタ・タブのショートカット: Alt-i +FILEBROWSER_SHOWNOTTRASHHINT;削除されていない画像だけ表示 +FILEBROWSER_SHOWRANK1HINT;1つ星ランクを表示\nショートカット: 1 +FILEBROWSER_SHOWRANK2HINT;2つ星ランクを表示\nショートカット: 2 +FILEBROWSER_SHOWRANK3HINT;3つ星ランクを表示\nショートカット: 3 +FILEBROWSER_SHOWRANK4HINT;4つ星ランクを表示\nショートカット: 4 +FILEBROWSER_SHOWRANK5HINT;5つ星ランクを表示\nショートカット: 5 +FILEBROWSER_SHOWRECENTLYSAVEDHINT;最近保存された画像を表示\nショートカット: Alt-7 +FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;最近保存されていない画像を表示\nショートカット: Alt-6 +FILEBROWSER_SHOWTRASHHINT;ゴミ箱の内容を表示\nショートカット: Ctrl-t +FILEBROWSER_SHOWUNCOLORHINT;カラー・ラベルのない画像を表示\nショートカット: Alt-0 +FILEBROWSER_SHOWUNRANKHINT;ランクなし画像を表示\nショートカット: 0 +FILEBROWSER_STARTPROCESSINGHINT;処理開始/キュー画像の保存 +FILEBROWSER_STARTPROCESSING;処理開始 +FILEBROWSER_STOPPROCESSINGHINT;画像処理の中止 +FILEBROWSER_STOPPROCESSING;処理中止 +FILEBROWSER_THUMBSIZE;サムネイルのサイズ +FILEBROWSER_TOOLTIP_STOPPROCESSING;新しいrawファイルが送られて来たら自動的に現像処理を開始します +FILEBROWSER_UNRANK_TOOLTIP;ランクなし\nショートカット: Shift-0 +FILEBROWSER_ZOOMINHINT;サムネイルサイズの拡大\nショートカット: +\n\nシングル・エディタ・タブのショートカット: Alt-+ +FILEBROWSER_ZOOMOUTHINT;サムネイルサイズの縮小\nショートカット: -\n\nシングル・エディタ・タブのショートカット: Alt-- +FILECHOOSER_FILTER_ANY;全てのファイル +FILECHOOSER_FILTER_COLPROF;カラープロファイル +FILECHOOSER_FILTER_CURVE;カーブファイル +FILECHOOSER_FILTER_LCP;レンズ補正プロファイル +FILECHOOSER_FILTER_PP;処理プロファイル +FILECHOOSER_FILTER_SAME;現在の画像と同じフォーマット +FILECHOOSER_FILTER_TIFF;TIFFファイル +GENERAL_ABOUT;RawTherapeeについて.. +GENERAL_AFTER;補正後 +GENERAL_ASIMAGE;画像通り +GENERAL_AUTO;自動 +GENERAL_BEFORE;補正前 +GENERAL_CANCEL;キャンセル +GENERAL_CLOSE;閉じる +GENERAL_DISABLED;無効 +GENERAL_DISABLE;無効 +GENERAL_ENABLED;有効 +GENERAL_ENABLE;有効 +GENERAL_FILE;ファイル +GENERAL_LANDSCAPE;横 +GENERAL_NA;n/a +GENERAL_NONE;なし +GENERAL_NO;No +GENERAL_OK;OK +GENERAL_PORTRAIT;縦 +GENERAL_SAVE;保存 +GENERAL_UNCHANGED;(変更なし) +GENERAL_WARNING;警告 +HISTOGRAM_TOOLTIP_BAR;RGBインジケーター・バーの表示/非表示\nプレビュー画像上でマウスの右ボタンクリックで 固定/開放 +HISTOGRAM_TOOLTIP_B;ブルー・ヒストグラム 表示/非表示 +HISTOGRAM_TOOLTIP_CHRO;色度・ヒストグラム 表示/非表示 +HISTOGRAM_TOOLTIP_FULL;完全/縮尺調整の表示切り替え +HISTOGRAM_TOOLTIP_G;グリーン・ヒストグラム 表示/非表示 +HISTOGRAM_TOOLTIP_L;CIEL*a*b* 輝度・ヒストグラム 表示/非表示 +HISTOGRAM_TOOLTIP_RAW;rawヒストグラム 表示/非表示 +HISTOGRAM_TOOLTIP_R;レッド・ヒストグラム 表示/非表示 +HISTORY_CHANGED;変更されました +HISTORY_CUSTOMCURVE;カスタムカーブ +HISTORY_DELSNAPSHOT;削除 +HISTORY_FROMCLIPBOARD;クリップボードから +HISTORY_LABEL;履歴 +HISTORY_MSG_1;写真を読み込みました +HISTORY_MSG_2;PP3を読み込みました +HISTORY_MSG_3;PP3を変更しました +HISTORY_MSG_4;履歴ブラウジング +HISTORY_MSG_5;明度 +HISTORY_MSG_6;コントラスト +HISTORY_MSG_7;黒 +HISTORY_MSG_8;露光量補正 +HISTORY_MSG_9;ハイライト圧縮 +HISTORY_MSG_10;シャドウ圧縮 +HISTORY_MSG_11;トーンカーブ 1 +HISTORY_MSG_12;自動露光補正 +HISTORY_MSG_13;露光 クリッピング +HISTORY_MSG_14;L*a*b* - 明度 +HISTORY_MSG_15;L*a*b* - コントラスト +HISTORY_MSG_16;輝度 黒レベル +HISTORY_MSG_17;輝度 ハイライト圧縮 +HISTORY_MSG_18;輝度 シャドウ圧縮 +HISTORY_MSG_19;L*a*b* - L*カーブ +HISTORY_MSG_20;シャープ化 +HISTORY_MSG_21;シャープ化 半径 +HISTORY_MSG_22;シャープ化 適用量 +HISTORY_MSG_23;シャープ化 しきい値 +HISTORY_MSG_24;シャープ化 エッジのみ +HISTORY_MSG_25;シャープ化 エッジ検出 半径 +HISTORY_MSG_26;シャープ化 エッジ許容 +HISTORY_MSG_27;シャープ化 ハロ抑制 +HISTORY_MSG_28;ハロ抑制 適用量 +HISTORY_MSG_29;シャープ化 方式 +HISTORY_MSG_30;デコンボリューション 半径 +HISTORY_MSG_31;デコンボリューション 適用量 +HISTORY_MSG_32;デコンボリューション 減衰 +HISTORY_MSG_33;デコンボリューション 繰返し +HISTORY_MSG_34;LCP 歪曲収差補正 +HISTORY_MSG_35;LCP 周辺光量補正 +HISTORY_MSG_36;LCP 色収差補正 +HISTORY_MSG_37;オートレベル +HISTORY_MSG_38;ホワイトバランス モード +HISTORY_MSG_39;色温度 +HISTORY_MSG_40;色偏差 +HISTORY_MSG_41;トーンカーブ1のモード +HISTORY_MSG_42;トーンカーブ 2 +HISTORY_MSG_43;トーンカーブ2のモード +HISTORY_MSG_44;輝度ノイズ低減 半径 +HISTORY_MSG_45;輝度ノイズ低減 エッジの許容度 +HISTORY_MSG_46;色ノイズ低減 +HISTORY_MSG_47;マトリクスでICCハイライト・ブレンド +HISTORY_MSG_48;DCPトーンカーブ使用 +HISTORY_MSG_49;色ノイズ低減 エッジの感度 +HISTORY_MSG_50;シャドウ/ハイライト +HISTORY_MSG_51;ハイライト +HISTORY_MSG_52;シャドウ +HISTORY_MSG_53;ハイライト トーンの幅 +HISTORY_MSG_54;シャドウ トーンの幅 +HISTORY_MSG_55;ローカルコントラスト +HISTORY_MSG_56;シャドウ/ハイライト 半径 +HISTORY_MSG_57;90度 回転 +HISTORY_MSG_58;左右反転 +HISTORY_MSG_59;上下反転 +HISTORY_MSG_60;回転 +HISTORY_MSG_61;オートフィル +HISTORY_MSG_62;レンズ歪曲収差補正 +HISTORY_MSG_63;スナップショット選択 +HISTORY_MSG_64;写真切り抜き +HISTORY_MSG_65;色収差補正 +HISTORY_MSG_66;ハイライト復元 +HISTORY_MSG_67;ハイライト復元 量 +HISTORY_MSG_68;ハイライト復元 方式 +HISTORY_MSG_69;作業カラースペース +HISTORY_MSG_70;出力カラースペース +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;リサイズ指定のデータ +HISTORY_MSG_79;リサイズ幅 +HISTORY_MSG_80;リサイズ 高さ +HISTORY_MSG_81;リサイズの有効・無効 +HISTORY_MSG_82;プロファイル変更 +HISTORY_MSG_83;高画質 シャドウ/ハイライト +HISTORY_MSG_84;パースペクティブの補正 +HISTORY_MSG_85;レンズ補正 プロファイル +HISTORY_MSG_86;RGB カーブ - 輝度モード +HISTORY_MSG_87;インパルスノイズ低減 +HISTORY_MSG_88;インパルスノイズ低減 しきい値 +HISTORY_MSG_89;ノイズ低減 +HISTORY_MSG_90;輝度ノイズの低減 +HISTORY_MSG_91;色ノイズの低減 +HISTORY_MSG_92;ノイズ低減のガンマ +HISTORY_MSG_93;ディテールのコントラスト係数 +HISTORY_MSG_94;ディテールのコントラスト +HISTORY_MSG_95;L*a*b*の色度 +HISTORY_MSG_96;L*a*b* - a*カーブ +HISTORY_MSG_97;L*a*b* - b*カーブ +HISTORY_MSG_98;デモザイク 方式 +HISTORY_MSG_99;ホットピクセルフィルター +HISTORY_MSG_100;RGB 彩度 +HISTORY_MSG_101;HSV イコライザ - 色相 +HISTORY_MSG_102;HSV イコライザ - 彩度 +HISTORY_MSG_103;HSV イコライザ - 明度 +HISTORY_MSG_104;HSV イコライザ +HISTORY_MSG_105;フリンジ低減 +HISTORY_MSG_106;フリンジ低減 半径 +HISTORY_MSG_107;フリンジ低減 しきい値 +HISTORY_MSG_108;ハイライト圧縮 しきい値 +HISTORY_MSG_109;リサイズ バウンディングボックス +HISTORY_MSG_110;リサイズの適用領域 +HISTORY_MSG_111;L*a*b* - 色ずれ回避 +HISTORY_MSG_112;--未使用-- +HISTORY_MSG_113;L*a*b* - レッドと肌色トーンを保護 +HISTORY_MSG_114;DCB 反復 +HISTORY_MSG_115;偽色抑制 +HISTORY_MSG_116;DCB 拡張 +HISTORY_MSG_117;raw 色収差 レッド +HISTORY_MSG_118;raw 色収差 ブルー +HISTORY_MSG_119;ラインノイズ フィルタ +HISTORY_MSG_120;グリーン 平衡化 +HISTORY_MSG_121;raw 色収差 自動 +HISTORY_MSG_122;ダークフレーム 自動 +HISTORY_MSG_123;ダークフレーム ファイル +HISTORY_MSG_124;リニア露光補正 +HISTORY_MSG_125;露光補正 HLを保持 +HISTORY_MSG_126;フラットフィールド ファイル +HISTORY_MSG_127;フラットフィールド 自動選択 +HISTORY_MSG_128;フラットフィールド・ぼかし半径 +HISTORY_MSG_129;フラットフィールド・ぼかしタイプ +HISTORY_MSG_130;自動歪曲収差補正 +HISTORY_MSG_131;ノイズ低減 輝度 +HISTORY_MSG_132;ノイズ低減 カラー +HISTORY_MSG_133;ガンマ +HISTORY_MSG_134;ガンマポジション +HISTORY_MSG_135;フリー・ガンマ +HISTORY_MSG_136;ガンマ 勾配 +HISTORY_MSG_137;黒レベル グリーン 1 +HISTORY_MSG_138;黒レベル レッド +HISTORY_MSG_139;黒レベル ブルー +HISTORY_MSG_140;黒レベル グリーン 2 +HISTORY_MSG_141;黒レベル グリーン 連動 +HISTORY_MSG_142;エッジ シャープ化 - 反復 +HISTORY_MSG_143;エッジ シャープ化 - 適用量 +HISTORY_MSG_144;マイクロコントラスト - 適用量 +HISTORY_MSG_145;マイクロコントラスト - 均等 +HISTORY_MSG_146;エッジ シャープ化 +HISTORY_MSG_147;エッジ シャープ化 - 輝度のみ +HISTORY_MSG_148;マイクロコントラスト +HISTORY_MSG_149;マイクロコントラスト - 3x3 マトリクス +HISTORY_MSG_150;デモザイク後にアーティファクトとノイズを軽減 +HISTORY_MSG_151;自然な彩度 +HISTORY_MSG_152;自然な彩度 - 明清色トーン +HISTORY_MSG_153;自然な彩度 - 純色トーン +HISTORY_MSG_154;自然な彩度 - 肌色トーンを保護 +HISTORY_MSG_155;自然な彩度 - 色ずれを回避 +HISTORY_MSG_156;自然な彩度 - 明清色と純色トーンをリンク +HISTORY_MSG_157;自然な彩度 - 明清色/純色トーン しきい値 +HISTORY_MSG_158;強さ +HISTORY_MSG_159;エッジ停止 +HISTORY_MSG_160;スケール +HISTORY_MSG_161;再加重反復 +HISTORY_MSG_162;トーンマッピング +HISTORY_MSG_163;RGB カーブ - レッド +HISTORY_MSG_164;RGB カーブ - グリーン +HISTORY_MSG_165;RGB カーブ - ブルー +HISTORY_MSG_166;ニュートラル・レベル +HISTORY_MSG_167;--未使用-- +HISTORY_MSG_168;L*a*b* CC カーブ +HISTORY_MSG_169;L*a*b* CH カーブ +HISTORY_MSG_170;自然な彩度 - カーブ +HISTORY_MSG_171;L*a*b* LC カーブ +HISTORY_MSG_172;LCの適用をレッドと肌色トーンだけに制限 +HISTORY_MSG_173;輝度ノイズ 細部の復元 +HISTORY_MSG_174;CIE色の見えモデル2002 +HISTORY_MSG_175;CAM02 - 色順応量 +HISTORY_MSG_176;CAM02 - 観視の暗い周囲環境 +HISTORY_MSG_177;CAM02 - 撮影環境の順応輝度 +HISTORY_MSG_178;CAM02 - 観視の順応輝度 +HISTORY_MSG_179;CAM02 - モデル +HISTORY_MSG_180;CAM02 - 明度 (J) +HISTORY_MSG_181;CAM02 - 色度 (C) +HISTORY_MSG_182;CAM02 - 自動 CAT02 +HISTORY_MSG_183;CAM02 - コントラスト (J) +HISTORY_MSG_184;CAM02 - 暗い周囲環境を伴う撮影環境 +HISTORY_MSG_185;CAM02 - 色域制御 +HISTORY_MSG_186;CAM02 - アルゴリズム +HISTORY_MSG_187;CAM02 - レッドと肌色トーンを保護 +HISTORY_MSG_188;CAM02 - 明るさ (Q) +HISTORY_MSG_189;CAM02 - コントラスト (Q) +HISTORY_MSG_190;CAM02 - 彩度 (S) +HISTORY_MSG_191;CAM02 - 彩度 (M) +HISTORY_MSG_192;CAM02 - 色相角 +HISTORY_MSG_193;CAM02 - トーンカーブ 1 +HISTORY_MSG_194;CAM02 - トーンカーブ 2 +HISTORY_MSG_195;CAM02 - トーンカーブ 1 +HISTORY_MSG_196;CAM02 - トーンカーブ 2 +HISTORY_MSG_197;CAM02 - カラー・カーブ +HISTORY_MSG_198;CAM02 - カラー・カーブ +HISTORY_MSG_199;CAM02 - カーブでCIECAM02出力のヒストグラムを表示 +HISTORY_MSG_200;CAM02 - CIECAM02 Q でトーンマッピング +HISTORY_MSG_201;色差 レッド/グリーン +HISTORY_MSG_202;色差 ブルー/イエロー +HISTORY_MSG_203;ノイズ低減 - 方式 +HISTORY_MSG_204;LMMSE 拡張処理 +HISTORY_MSG_205;CAM02 ホット/バッドピクセル +HISTORY_MSG_206;CAT02 - 自動で順応 +HISTORY_MSG_207;フリンジ低減 - 色相カーブ +HISTORY_MSG_208;ブルー/レッド イコライザ +HISTORY_MSG_210;グラデーションフィルター - 角度 +HISTORY_MSG_211;グラデーションフィルター +HISTORY_MSG_212;ビネットフィルター - 強さ +HISTORY_MSG_213;ビネットフィルター +HISTORY_MSG_214;白黒 +HISTORY_MSG_215;白黒 チャンネルミキサー レッド +HISTORY_MSG_216;白黒 チャンネルミキサー グリーン +HISTORY_MSG_217;白黒 チャンネルミキサー ブルー +HISTORY_MSG_218;白黒 レッドのガンマ +HISTORY_MSG_219;白黒 グリーンのガンマ +HISTORY_MSG_220;白黒 ブルーのガンマ +HISTORY_MSG_221;白黒 カラーフィルター +HISTORY_MSG_222;白黒 プリセット +HISTORY_MSG_223;白黒 チャンネルミキサー オレンジ +HISTORY_MSG_224;白黒 チャンネルミキサー イエロー +HISTORY_MSG_225;白黒 チャンネルミキサー シアン +HISTORY_MSG_226;白黒 チャンネルミキサー マゼンタ +HISTORY_MSG_227;白黒 チャンネルミキサー パープル +HISTORY_MSG_228;白黒 輝度イコライザ +HISTORY_MSG_229;白黒 輝度イコライザ +HISTORY_MSG_230;白黒 モード +HISTORY_MSG_231;白黒 ‘前の‘カーブ +HISTORY_MSG_232;白黒 ‘前の‘カーブのタイプ +HISTORY_MSG_233;白黒 ‘後の‘カーブ +HISTORY_MSG_234;白黒 ‘後の‘カーブのタイプ +HISTORY_MSG_235;白黒 オートチャンネルミキサー +HISTORY_MSG_236;--未使用-- +HISTORY_MSG_237;白黒 ミキサー +HISTORY_MSG_238;グラデーションフィルター フェザー処理 +HISTORY_MSG_239;グラデーションフィルター 強さ +HISTORY_MSG_240;グラデーションフィルター 中央 +HISTORY_MSG_241;ビネットフィルター フェザー処理 +HISTORY_MSG_242;ビネットフィルター 形状 +HISTORY_MSG_243;半径 +HISTORY_MSG_244;ビネットフィルター 強さ +HISTORY_MSG_245;ビネットフィルター 中央 +HISTORY_MSG_246;L*a*b* CL カーブ +HISTORY_MSG_247;L*a*b* LH カーブ +HISTORY_MSG_248;L*a*b* HH カーブ +HISTORY_MSG_249;ディテールレベルのコントラスト - しきい値 +HISTORY_MSG_250;ノイズ低減 - 強化 +HISTORY_MSG_251;白黒 - アルゴリズム +HISTORY_MSG_252;CbDL 肌色の目標/保護 +HISTORY_MSG_253;CbDL アーティファクトを軽減 +HISTORY_MSG_254;CbDL 肌色の色相 +HISTORY_MSG_255;ノイズ低減 - メディアン +HISTORY_MSG_256;ノイズ低減 - フィルターの種類 +HISTORY_MSG_257;カラートーン調整 +HISTORY_MSG_258;カラートーン調整 - カラーのカーブ +HISTORY_MSG_259;カラートーン調整 - 不透明度のカーブ +HISTORY_MSG_260;カラートーン調整 - a*(b*)の不透明度 +HISTORY_MSG_261;カラートーン調整 - 方法 +HISTORY_MSG_262;カラートーン調整 - b*の不透明度 +HISTORY_MSG_263;カラートーン調整 - シャドウのレッド +HISTORY_MSG_264;カラートーン調整 - シャドウのグリーン +HISTORY_MSG_265;カラートーン調整 - シャドウのブルー +HISTORY_MSG_266;カラートーン調整 - 中間トーンのレッド +HISTORY_MSG_267;カラートーン調整 - 中間トーンのグリーン +HISTORY_MSG_268;カラートーン調整 - 中間トーンのブルー +HISTORY_MSG_269;カラートーン調整 - ハイライトのレッド +HISTORY_MSG_270;カラートーン調整 - ハイライトのグリーン +HISTORY_MSG_271;カラートーン調整 - ハイライトのブルー +HISTORY_MSG_272;カラートーン調整 - バランス +HISTORY_MSG_273;カラートーン調整 - リセット +HISTORY_MSG_274;カラートーン調整 - シャドウの彩度 +HISTORY_MSG_275;カラートーン調整 - ハイライトの彩度 +HISTORY_MSG_276;カラートーン調整 - 不透明度 +HISTORY_MSG_277;カラートーン調整 - カーブをリセット +HISTORY_MSG_278;カラートーン調整 - 明度を維持 +HISTORY_MSG_279;カラートーン調整 - シャドウ +HISTORY_MSG_280;カラートーン調整 - ハイライト +HISTORY_MSG_281;カラートーン調整 - 彩度の保護 +HISTORY_MSG_282;カラートーン調整 - 彩度のしきい値 +HISTORY_MSG_283;カラートーン調整 - 強さを維持 +HISTORY_MSG_284;カラートーン調整 - 自動彩度 +HISTORY_MSG_285;メディアンの方式 +HISTORY_MSG_286;メディアンフィルターの種類 +HISTORY_MSG_287;フィルタリングの回数 +HISTORY_MSG_288;フラットフィールド クリッピングコントロール +HISTORY_MSG_289;フラットフィールド クリッピングコントロール 自動 +HISTORY_MSG_290;黒レベル - レッド +HISTORY_MSG_291;黒レベル - グリーン +HISTORY_MSG_292;黒レベル - ブルー +HISTORY_MSG_293;フィルムシミュレーション +HISTORY_MSG_294;フィルムシミュレーション - 強さ +HISTORY_MSG_295;フィルムシミュレーション - フィルム +HISTORY_MSG_296;輝度ノイズ低減のカーブ +HISTORY_MSG_297;ノイズ低減 - 質 +HISTORY_MSG_298;デッドピクセルフィルター +HISTORY_MSG_299;色ノイズ低減のカーブ +HISTORY_MSG_300;- +HISTORY_MSG_301;輝度ノイズの調整方法 +HISTORY_MSG_302;色ノイズの調整方法 +HISTORY_MSG_303;色ノイズの調整方法 +HISTORY_MSG_304;W- コントラストレベル +HISTORY_MSG_305;ウェーブレットのレベル +HISTORY_MSG_306;W- プレビュー +HISTORY_MSG_307;W- プレビュー +HISTORY_MSG_308;W- プレビューの方向 +HISTORY_MSG_309;W- ES ディテール +HISTORY_MSG_310;W- 残差 青空の目標/保護 +HISTORY_MSG_311;W- ウェーブレットのレベル +HISTORY_MSG_312;W- 残差 シャドウのしきい値 +HISTORY_MSG_313;W- 色度 明星色/純色 +HISTORY_MSG_314;W- 色域 アーティファクトの軽減 +HISTORY_MSG_315;W- 残差 コントラスト +HISTORY_MSG_316;W- 色域 肌色の目標/保護 +HISTORY_MSG_317;W- 色域 肌色の色相 +HISTORY_MSG_318;W- コントラスト ハイライトレベル +HISTORY_MSG_319;W- コントラスト ハイライト範囲 +HISTORY_MSG_320;W- コントラスト シャドウ範囲 +HISTORY_MSG_321;W- コントラスト シャドウレベル +HISTORY_MSG_322;W- 色域 色ずれの回避 +HISTORY_MSG_323;W- ES ローカルコントラスト +HISTORY_MSG_324;W- 色度 明星色 +HISTORY_MSG_325;W- 色度 純色 +HISTORY_MSG_326;W- 色度 方法 +HISTORY_MSG_327;W- コントラスト 適用先 +HISTORY_MSG_328;W- 色度 リンクを強化 +HISTORY_MSG_329;W- 色調 R/Gの不透明度 +HISTORY_MSG_330;W- 色調 B/Yの不透明度 +HISTORY_MSG_331;W- コントラストレベル エキストラ +HISTORY_MSG_332;W- タイルの種類 +HISTORY_MSG_333;W- 残差 シャドウ +HISTORY_MSG_334;W- 残差 色度 +HISTORY_MSG_335;W- 残差 ハイライト +HISTORY_MSG_336;W- 残差 ハイライトのしきい値 +HISTORY_MSG_337;W- 残差 青空の色相 +HISTORY_MSG_338;W- ES 半径 +HISTORY_MSG_339;W- ES 強さ +HISTORY_MSG_340;W- 強さ +HISTORY_MSG_341;W- エッジパフォーマンス +HISTORY_MSG_342;W- ES 最初のレベル +HISTORY_MSG_343;W- 色度のレベル +HISTORY_MSG_344;W- 色度 方式 スライダー/カーブ +HISTORY_MSG_345;W- ES ローカルコントラスト +HISTORY_MSG_346;W- ES ローカルコントラスト 方式 +HISTORY_MSG_347;W- ノイズ低減とリファイン レベル0 +HISTORY_MSG_348;W- ノイズ低減とリファイン レベル1 +HISTORY_MSG_349;W- ノイズ低減とリファイン レベル2 +HISTORY_MSG_350;W- ES エッジ検出 +HISTORY_MSG_351;W- 残差 HHカーブ +HISTORY_MSG_352;W- 背景色 +HISTORY_MSG_353;W- ES グラデーション感度 +HISTORY_MSG_354;W- ES 強化 +HISTORY_MSG_355;W- ES しきい値(低) +HISTORY_MSG_356;W- ES しきい値(高) +HISTORY_MSG_357;W- ノイズ低減 ESとリンク +HISTORY_MSG_358;W- 色域 CHカーブ +HISTORY_MSG_359;ホット/デッド しきい値 +HISTORY_MSG_360;トーンマッピング ガンマ +HISTORY_MSG_361;W- 最終 色度バランス +HISTORY_MSG_362;W- 残差 圧縮の方法 +HISTORY_MSG_363;W- 残差 圧縮の強さ +HISTORY_MSG_364;W- 最終 コントラストバランス +HISTORY_MSG_365;W- 最終 デルタバランス +HISTORY_MSG_366;W- 残差 圧縮のガンマ +HISTORY_MSG_367;W- ES ローカルコントラストカーブ +HISTORY_MSG_368;W- 最終 コントラストバランス +HISTORY_MSG_369;W- 最終 バランスの方法 +HISTORY_MSG_370;W- 最終 ローカルコントラストカーブ +HISTORY_NEWSNAPSHOT;追加 +HISTORY_NEWSNAPSHOT_TOOLTIP;ショートカット: Alt-s +HISTORY_SNAPSHOTS;スナップショット +HISTORY_SNAPSHOT;スナップショット +IPTCPANEL_AUTHORSPOSITIONHINT;作成者の肩書または作品の作成者(署名 タイトル). +IPTCPANEL_AUTHORSPOSITION;作成者の肩書 +IPTCPANEL_AUTHOR;作成者 +IPTCPANEL_CAPTIONHINT;データのテキストによる説明 (説明--要約) +IPTCPANEL_CAPTIONWRITERHINT;画像を編集修正する人、または説明/要約の執筆に係わる人の名前 (作家--編集者). +IPTCPANEL_CAPTIONWRITER;説明記入者 +IPTCPANEL_CAPTION;キャプション、説明文 +IPTCPANEL_CATEGORYHINT;提供者の見解で画像の主題を決めます (カテゴリ). +IPTCPANEL_CATEGORY;カテゴリ +IPTCPANEL_CITYHINT;撮影された都市 (市町村). +IPTCPANEL_CITY;都市 +IPTCPANEL_COPYHINT;IPTC設定をクリップボードにコピー +IPTCPANEL_COPYRIGHTHINT;著作権表示 (著作権情報). +IPTCPANEL_COPYRIGHT;著作権 +IPTCPANEL_COUNTRYHINT;国名、/画像が撮影・作成された国 (国--撮影国). +IPTCPANEL_COUNTRY;撮影国 +IPTCPANEL_CREDITHINT;所有者/作成者に限らず、画像の提供元の識別 (クレジット). +IPTCPANEL_CREDIT;クレジット +IPTCPANEL_DATECREATEDHINT;画像の知的内容が作成された日付; フォーマット: JJJJMMTT (作成日). +IPTCPANEL_DATECREATED;作成日 +IPTCPANEL_EMBEDDEDHINT;画像に埋め込まれたIPTCデータにリセット +IPTCPANEL_EMBEDDED;埋め込み +IPTCPANEL_HEADLINEHINT;画像の内容の概要を示す記入項目 (タイトル). +IPTCPANEL_HEADLINE;見出し +IPTCPANEL_INSTRUCTIONSHINT;画像の使用に関するその他の特記事項 (編集注記). +IPTCPANEL_INSTRUCTIONS;編集注記 +IPTCPANEL_KEYWORDSHINT;情報検索に使用する単語 (キーワード). +IPTCPANEL_KEYWORDS;キーワード +IPTCPANEL_PASTEHINT;IPTC設定をクリップボードから貼り付け +IPTCPANEL_PROVINCEHINT;撮影された地域/州・都道府県(地域--州・都道府県). +IPTCPANEL_PROVINCE;州・都道府県 +IPTCPANEL_RESETHINT;デフォルトのプロファイルにリセット +IPTCPANEL_RESET;リセット +IPTCPANEL_SOURCEHINT;画像の著作権保有者 (ソース). +IPTCPANEL_SOURCE;ソース +IPTCPANEL_SUPPCATEGORIESHINT;さらに細かく画像の主題 (カテゴリ補助). +IPTCPANEL_SUPPCATEGORIES;カテゴリ補助 +IPTCPANEL_TITLEHINT;画像のタイトルを簡略に (タイトル). +IPTCPANEL_TITLE;タイトル +IPTCPANEL_TRANSREFERENCEHINT;オリジナルの送信証明の位置を表すコード (オリジナル 送信証明). +IPTCPANEL_TRANSREFERENCE;送信証明 +MAIN_BUTTON_FULLSCREEN;フルスクリーン +MAIN_BUTTON_NAVNEXT_TOOLTIP;エディタで開いている画像に対応する次の画像に移動します\nショートカット: Shift-F4\n\nファイルブラウザで選択したサムネイルに対応する次の画像に移動するには\nショートカット: F4 +MAIN_BUTTON_NAVPREV_TOOLTIP;エディタで開いている画像に対応する前の画像に移動します\nショートカット: Shift-F3\n\nファイルブラウザで選択したサムネイルに対応する前の画像に移動するには\nショートカット: F3 +MAIN_BUTTON_NAVSYNC_TOOLTIP;現在開いている画像のサムネイルを明示しエディタとファイルブラウザを同期させ、ファイルブラウザでのフィルタをクリアします \nショートカット: x\n\n上記と同じですが、ファイルブラウザでのフィルタをクリアしません\nショートカット: y\n(除外する場合、開いているファイルのサムネイルが表示されませんので注意してください). +MAIN_BUTTON_PREFERENCES;環境設定 +MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;現在の画像をキュー処理に追加\nショートカット: Ctrl+b +MAIN_BUTTON_SAVE_TOOLTIP;現在の画像を保存\nショートカット: Ctrl+S +MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;現在の画像を外部エディタで編集\nショートカット: Ctrl+e +MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;表示/非表示 すべてのパネル\nショートカット: m +MAIN_BUTTON_UNFULLSCREEN;フルスクリーン解除 +MAIN_FRAME_BATCHQUEUE;キュー +MAIN_FRAME_BATCHQUEUE_TOOLTIP;キューで処理します\nショートカット: Ctrl-F3 +MAIN_FRAME_EDITOR;編集 +MAIN_FRAME_EDITOR_TOOLTIP; 編集\nショートカット: Ctrl-F4 +MAIN_FRAME_FILEBROWSER;ファイルブラウザ +MAIN_FRAME_FILEBROWSER_TOOLTIP; ファイル・ブラウザ\nショートカット: Ctrl-F2 +MAIN_FRAME_PLACES;場所 +MAIN_FRAME_PLACES_ADD;追加 +MAIN_FRAME_PLACES_DEL;削除 +MAIN_FRAME_RECENT;最近開いたフォルダ +MAIN_MSG_ALREADYEXISTS;ファイルはすでに存在します +MAIN_MSG_CANNOTLOAD;画像読み込みできません +MAIN_MSG_CANNOTSAVE;ファイル保存エラー +MAIN_MSG_CANNOTSTARTEDITOR;エディタを開始することができません +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;"環境設定"で正しいパスを設定してください +MAIN_MSG_EMPTYFILENAME;未定義のファイル名 +MAIN_MSG_IMAGEUNPROCESSED;このコマンドは、先に選択されたすべての画像をキュー処理する必要があります +MAIN_MSG_NAVIGATOR;ナビゲータ +MAIN_MSG_OPERATIONCANCELLED;操作キャンセル +MAIN_MSG_PATHDOESNTEXIST;パス\n\n%1\n\がありません。設定ウィンドウで正しいパスを設定してください +MAIN_MSG_QOVERWRITE;上書きしますか? +MAIN_MSG_SETPATHFIRST;この関数を使用するには、最初に環境設定でターゲット・パスを設定する必要があります! +MAIN_MSG_WRITEFAILED;書き込みに失敗しました\n\n"%1"\n\nフォルダが在るか書き込み権限を持っているか確認してください +MAIN_TAB_COLOR;カラー +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_EXPOSURE_TOOLTIP;ショートカット: Alt-e +MAIN_TAB_FILTER;絞り込み +MAIN_TAB_INSPECT;カメラ出しJPEG +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_TOOLTIP;ショートカット: Alt-t +MAIN_TAB_WAVELET;ウェーブレット +MAIN_TAB_WAVELET_TOOLTIP;ショートカット: Alt-w +MAIN_TOOLTIP_BACKCOLOR0;プレビューの背景色を指定します: テーマに基づく\nショートカット: 9 +MAIN_TOOLTIP_BACKCOLOR1;プレビューの背景色を指定します: \nショートカットt: 9 +MAIN_TOOLTIP_BACKCOLOR2;プレビューの背景色を指定します: \nショートカット: 9 +MAIN_TOOLTIP_BEFOREAFTERLOCK;固定 / 固定解除 - 補正前 の表示設定\n\n固定: 補正前をそのまま表示し変更されません\n複数のツールの累積効果を評価するのに役立ちます\nさらに、比較は履歴上のどこからでも行うことができます\n\n固定解除: 現在使用のツールの効果が 補正後 に表示され、その1段階前が 補正前 に表示されます +MAIN_TOOLTIP_HIDEHP;左パネル 表示/非表示 (履歴含む)\nショートカット: l +MAIN_TOOLTIP_INDCLIPPEDH;ハイライト・クリッピング領域の表示\nショートカット: < +MAIN_TOOLTIP_INDCLIPPEDS;シャドウ・クリッピング領域の表示\nショートカット: > +MAIN_TOOLTIP_PREVIEWB;ブルー チャンネル表示\nショートカット: b +MAIN_TOOLTIP_PREVIEWFOCUSMASK;フォーカス・マスク表示\nショートカット: Shift-f\n\n浅い被写界深度、低ノイズ、高ズームの画像の場合は、より正確に\n\nノイズの多い画像に対しては、検出精度を向上させるため10から30%縮小して評価します\n\nフォーカス・マスクをオンにすると表示に時間が掛かります +MAIN_TOOLTIP_PREVIEWG;グリーン チャンネル表示\nショートカット: g +MAIN_TOOLTIP_PREVIEWL;輝度表示\nショートカット: v\n\n0.299*R + 0.587*G + 0.114*B +MAIN_TOOLTIP_PREVIEWR;レッド チャンネル表示\nショートカット: r +MAIN_TOOLTIP_QINFO;画像の情報\nショートカット: i +MAIN_TOOLTIP_SHOWHIDELP1;表示/非表示 左パネル\nショートカット: l +MAIN_TOOLTIP_SHOWHIDERP1;表示/非表示 右パネル\nショートカット: Alt-l +MAIN_TOOLTIP_SHOWHIDETP1;表示/非表示 上パネル\nショートカット: Shift-L +MAIN_TOOLTIP_THRESHOLD;しきい値 +MAIN_TOOLTIP_TOGGLE;補正前/補正後 切り替え\nショートカット: Shift-b +NAVIGATOR_B;B: +NAVIGATOR_G;G: +NAVIGATOR_H;H: +NAVIGATOR_LAB_A;a*: +NAVIGATOR_LAB_B;b*: +NAVIGATOR_LAB_L;L*: +NAVIGATOR_NA; -- +NAVIGATOR_R;R: +NAVIGATOR_S;S: +NAVIGATOR_V;V: +NAVIGATOR_XY_FULL;幅 = %1, 高さ = %2 +NAVIGATOR_XY_NA;x = n/a, y = n/a +OPTIONS_DEFIMG_MISSING;rawではない画像のデフォルプロファイルが見つからないか、設定されていません\n\nプロファイル・ディレクトリを確認してください、存在しないか破損しているかもしれません\n\nデフォルト設定値が使用されます +OPTIONS_DEFRAW_MISSING;raw画像のデフォル・プロファイルが見つからないか、設定されていません\n\nプロファイル・ディレクトリを確認してください、存在しないか破損しているかもしれません\n\nデフォルト設定値が使用されます +PARTIALPASTE_BASICGROUP;基本設定 +PARTIALPASTE_CACORRECTION;色収差補正 +PARTIALPASTE_CHANNELMIXERBW;白黒 +PARTIALPASTE_CHANNELMIXER;チャンネル・ミキサー +PARTIALPASTE_COARSETRANS;90° 回転 / 反転 +PARTIALPASTE_COLORAPP;CIE色の見えモデル2002 +PARTIALPASTE_COLORGROUP;カラー 設定 +PARTIALPASTE_COLORTONING;カラートーン調整 +PARTIALPASTE_COMMONTRANSFORMPARAMS;オート・フィル +PARTIALPASTE_COMPOSITIONGROUP;変形 設定 +PARTIALPASTE_CROP;切り抜き +PARTIALPASTE_DARKFRAMEAUTOSELECT;ダークフレーム自動選択 +PARTIALPASTE_DARKFRAMEFILE;ダークフレーム・ファイル +PARTIALPASTE_DEFRINGE;フリンジ低減 +PARTIALPASTE_DETAILGROUP;ディテールの設定 +PARTIALPASTE_DIALOGLABEL;処理プロファイルの部分ペースト +PARTIALPASTE_DIRPYRDENOISE;ノイズ低減 +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_ICMGAMMA;出力ガンマ +PARTIALPASTE_ICMSETTINGS;ICM 設定 +PARTIALPASTE_IMPULSEDENOISE;インパルス・ノイズ低減 +PARTIALPASTE_IPTCINFO;IPTC 情報 +PARTIALPASTE_LABCURVE;L*a*b* 調整 +PARTIALPASTE_LENSGROUP;レンズ設定 +PARTIALPASTE_LENSPROFILE;レンズ補正プロファイル +PARTIALPASTE_METAGROUP;メタデータ +PARTIALPASTE_PCVIGNETTE;ビネットフィルター +PARTIALPASTE_PERSPECTIVE;パースペクティブの補正 +PARTIALPASTE_PREPROCESS_DEADPIXFILT;デッドピクセルフィルターを適用 +PARTIALPASTE_PREPROCESS_GREENEQUIL;グリーン 平衡化 +PARTIALPASTE_PREPROCESS_HOTPIXFILT;ホットピクセルフィルターを適用 +PARTIALPASTE_PREPROCESS_LINEDENOISE;ラインノイズ フィルタ +PARTIALPASTE_RAWCACORR_AUTO;自動色収差補正 +PARTIALPASTE_RAWCACORR_CABLUE;色収差 ブルー +PARTIALPASTE_RAWCACORR_CARED;色収差 レッド +PARTIALPASTE_RAWEXPOS_BLACK;黒レベル +PARTIALPASTE_RAWEXPOS_LINEAR;raw ホワイトポイント リニア補正係数 +PARTIALPASTE_RAWEXPOS_PRESER;raw ホワイトポイント ハイライトを保持したまま補正 (EV) +PARTIALPASTE_RAWGROUP;raw 設定 +PARTIALPASTE_RAW_DCBENHANCE;DCB 拡張処理適用 +PARTIALPASTE_RAW_DCBITERATIONS;DCB反復の数 +PARTIALPASTE_RAW_DMETHOD;デモザイクの方法 +PARTIALPASTE_RAW_FALSECOLOR;デモザイク 偽色抑制の処理段階 +PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE 拡張処理 +PARTIALPASTE_RESIZE;リサイズ +PARTIALPASTE_RGBCURVES;RGB カーブ +PARTIALPASTE_ROTATION;回転 +PARTIALPASTE_SHADOWSHIGHLIGHTS;シャドウ/ハイライト +PARTIALPASTE_SHARPENEDGE;エッジ +PARTIALPASTE_SHARPENING;シャープ化 (USM/RL) +PARTIALPASTE_SHARPENMICRO;マイクロコントラスト +PARTIALPASTE_VIBRANCE;自然な彩度 +PARTIALPASTE_VIGNETTING;周辺光量補正 +PARTIALPASTE_WAVELETGROUP;ウェーブレット処理 +PARTIALPASTE_WHITEBALANCE;ホワイトバランス +PREFERENCES_ADD;追加 +PREFERENCES_APPLNEXTSTARTUP;要再起動 +PREFERENCES_AUTLISLOW;低 +PREFERENCES_AUTLISMAX;最大 - 全タイルの平均 +PREFERENCES_AUTLISSTD;高 +PREFERENCES_AUTLISVLOW;なし +PREFERENCES_AUTLOW;低 +PREFERENCES_AUTOMONPROFILE;OSのメインモニター・プロファイルを使用 +PREFERENCES_AUTSTD;標準 +PREFERENCES_BATCH_PROCESSING;バッチ処理 +PREFERENCES_BEHADDALLHINT;すべてのパラメータを 追加モードにします\nバッチツールパネルで設定される調整値が、各画像の既定値に加算されます +PREFERENCES_BEHADDALL;すべて '追加' +PREFERENCES_BEHAVIOR;ビヘイビア +PREFERENCES_BEHSETALLHINT;すべてのパラメータを 設定モードにします\nバッチツールパネルで設定される調整値が、各画像の既定値に取って代わり同一になります +PREFERENCES_BEHSETALL;すべて '設定' +PREFERENCES_BLACKBODY;タングステン +PREFERENCES_CACHECLEARALL;すべてクリア +PREFERENCES_CACHECLEARPROFILES;プロファイルのクリア +PREFERENCES_CACHECLEARTHUMBS;サムネイルのクリア +PREFERENCES_CACHEMAXENTRIES;キャッシュエントリーの最大数 +PREFERENCES_CACHEOPTS;cache オプション +PREFERENCES_CACHETHUMBHEIGHT;サムネイル縦の最大値 +PREFERENCES_CIEART;CIECAM02 最適化 +PREFERENCES_CIEART_FRAME;CIECAM02-特定の設定 +PREFERENCES_CIEART_LABEL;倍精度の代わりに単精度浮動小数点を使用 +PREFERENCES_CIEART_TOOLTIP;有効にした場合、 CIECAM02は倍精度浮動小数点形式の代わりに単精度で実行されます。これは品質を少し犠牲にし、速度を少し増加させます +PREFERENCES_CLIPPINGIND;クリッピング領域の表示 +PREFERENCES_CLUTSCACHE;HaldCLUT cache +PREFERENCES_CLUTSCACHE_LABEL;cacheに置けるHaldCLUTの最大数 +PREFERENCES_CLUTSDIR;HaldCLUTのディレクトリー +PREFERENCES_CMETRICINTENT;レンダリング・インテント +PREFERENCES_CURVEBBOXPOS;カーブのコピーペイストボタンの位置 +PREFERENCES_CURVEBBOXPOS_ABOVE;上 +PREFERENCES_CURVEBBOXPOS_BELOW;下 +PREFERENCES_CURVEBBOXPOS_LEFT;左 +PREFERENCES_CURVEBBOXPOS_RIGHT;右 +PREFERENCES_CUSTPROFBUILDHINT;画像から新規のプロファイルを作成する際に呼び出される実行ファイル (またはスクリプト)\n.PP3生成のルールに基づいたコマンドライン・パラメータを受け取ります\n[raw/JPG・パス] [デフォルトのプロファイルのパス] [f-数値] [露出時間 秒] [焦点距離 mm] [ISO] [レンズ] [カメラ] +PREFERENCES_CUSTPROFBUILDKEYFORMAT;キーフォーマット +PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME;名前 +PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;タグID +PREFERENCES_CUSTPROFBUILDPATH;実行ファイルのパス +PREFERENCES_CUSTPROFBUILD;カスタム・イメージ・プロファイル・ビルダー +PREFERENCES_CUTOVERLAYBRUSH;切り抜きマスクカラー 不透明度 +PREFERENCES_D50;5000K +PREFERENCES_D55;5500K +PREFERENCES_D60;6000K +PREFERENCES_D65;6500K +PREFERENCES_DARKFRAMEFOUND;検出 +PREFERENCES_DARKFRAMESHOTS;ショット +PREFERENCES_DARKFRAMETEMPLATES;テンプレート +PREFERENCES_DARKFRAME;ダークフレーム +PREFERENCES_DATEFORMATHINT;次の書式を使用することができます:\n%y : 年\n%m : 月\n%d : 日\n\n例として, ハンガリアン記法の日付:\n%y/%m/%d +PREFERENCES_DATEFORMAT;日付の形式 +PREFERENCES_DAUB_LABEL;ドビッシー関数のタイプ D4の代わりにD6を使う +PREFERENCES_DAUB_TOOLTIP;ノイズ低減とウェーブレットのレベルツールはマザーウェーブレットにドビッシーを使っています。このタイプでD4の代わりにD6を選択すると、直交系であるドビッシーの係数が増えるので、恐らくスケールの小さいレベルは質が向上するでしょう。タイプを変えても処理時間やメモリー使用量に影響はありません。 +PREFERENCES_DEFAULTLANG;デフォルトの言語 +PREFERENCES_DEFAULTTHEME;デフォルトテーマ +PREFERENCES_DIRDARKFRAMES;ダークフレーム・ディレクトリ +PREFERENCES_DIRHOME;ホーム・ディレクトリ +PREFERENCES_DIRLAST;最近参照したディレクトリ +PREFERENCES_DIROTHER;他 +PREFERENCES_DIRSELECTDLG;起動時の画像ディレクトリ選択... +PREFERENCES_DIRSOFTWARE;インストール・ディレクトリ +PREFERENCES_EDITORCMDLINE;その他・コマンド入力 +PREFERENCES_EDITORLAYOUT;編集 レイアウト +PREFERENCES_EXPAUT;高度 +PREFERENCES_EXTERNALEDITOR;外部エディタ +PREFERENCES_FBROWSEROPTS;ファイルブラウザ/サムネイルのオプション +PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;ファイルブラウザでの一行のツールバー (低解像度表示用に選択解除) +PREFERENCES_FILEFORMAT;ファイル形式 +PREFERENCES_FILMSIMULATION;フィルムシミュレーション +PREFERENCES_FLATFIELDFOUND;検出 +PREFERENCES_FLATFIELDSDIR;フラットフィールド・ディレクトリ +PREFERENCES_FLATFIELDSHOTS;ショット +PREFERENCES_FLATFIELDTEMPLATES;テンプレート +PREFERENCES_FLATFIELD;フラットフィールド +PREFERENCES_FLUOF2;蛍光灯 F2 +PREFERENCES_FLUOF7;蛍光灯 F7 +PREFERENCES_FLUOF11;蛍光灯 F11 +PREFERENCES_FORIMAGE;rawではない画像 +PREFERENCES_FORRAW;raw画像 +PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT;ファイルブラウザと編集パネルのサムネイルのサイズを同じにする +PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT_HINT;サムネイルのサイズが異なると、編集パネルとファイルブラウザ間の切り替えで、余分な処理時間がかかります +PREFERENCES_GIMPPATH;GIMP インストール ディレクトリ +PREFERENCES_GREY05;Yb=05 CIE L#30 +PREFERENCES_GREY10;Yb=10 CIE L#40 +PREFERENCES_GREY15;Yb=15 CIE L#45 +PREFERENCES_GREY18;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_GREYSC18;Yb=18 CIE L#50 +PREFERENCES_GREYSCA;Ybを自動で計算 +PREFERENCES_GREYSC;撮影時のYb輝度 (%) +PREFERENCES_GREY;出力デバイスのYb輝度 (%) +PREFERENCES_HISTOGRAMPOSITIONLEFT;左パネルにヒストグラム +PREFERENCES_HISTOGRAMWORKING;ヒストグラムとナビゲーターの表示に作業プロファイルを使う +PREFERENCES_HISTOGRAM_TOOLTIP;これを有効にすると、ヒストグラムとナビゲーターの表示に、出力プロファイル(ガンマ適用)の代わりに作業プロファイルを使います +PREFERENCES_HLTHRESHOLD;ハイライト・クリッピング領域のしきい値 +PREFERENCES_ICCDIR;カラープロファイルを含むディレクトリ +PREFERENCES_IMG_RELOAD_NEEDED;これらの変更を有効にするには画像の再読み込みが必要です(或いは、新しい画像の読み込み) +PREFERENCES_IMPROCPARAMS;画像処理のデフォルト値 +PREFERENCES_INSPECT_LABEL;カメラ出しJPEG +PREFERENCES_INSPECT_MAXBUFFERS_LABEL;cacheに入れる画像の最大数 +PREFERENCES_INSPECT_MAXBUFFERS_TOOLTIP;ファイルブラウザの操作中にcacheに入れられる画像の最大数。RAM容量が小さい場合(2G以下)の場合は、設定値を1或いは2にするべき +PREFERENCES_INTENT_ABSOLUTE;絶対的な色域を維持 +PREFERENCES_INTENT_PERCEPTUAL;知覚的 +PREFERENCES_INTENT_RELATIVE;相対的な色域を維持 +PREFERENCES_INTENT_SATURATION;彩度 +PREFERENCES_INTERNALTHUMBIFUNTOUCHED;rawファイルが未編集の場合 JPEGのサムネイルを表示 +PREFERENCES_LANGAUTODETECT;OSの言語設定を使用 +PREFERENCES_LEVAUTDN;ノイズ低減のレベル +PREFERENCES_LEVDN;セルのサイズ +PREFERENCES_LISS;自動(多分割スムージング) +PREFERENCES_MAXRECENTFOLDERS;直近のフォルダーの最大数 +PREFERENCES_MAX;最大(タイル) +PREFERENCES_MED;中 (タイルの半分) +PREFERENCES_MENUGROUPEXTPROGS;"..で開く"のグループ +PREFERENCES_MENUGROUPFILEOPERATIONS;"ファイル操作"のグループ +PREFERENCES_MENUGROUPLABEL;"カラーラベル"のグループ +PREFERENCES_MENUGROUPPROFILEOPERATIONS;"処理プロファイル操作"のグループ +PREFERENCES_MENUGROUPRANK;"ランキング"のグループ +PREFERENCES_MENUOPTIONS;メニューオプションの状況 +PREFERENCES_METADATA;メタデータ +PREFERENCES_MIN;最小 (100x115) +PREFERENCES_MONITORICC;モニター・カラープロファイル +PREFERENCES_MULTITABDUALMON;独自のウィンドウモードによるマルチ編集タブ +PREFERENCES_MULTITAB;マルチ編集タブモード +PREFERENCES_NAVGUIDEBRUSH;ナビゲーターのガイドカラー +PREFERENCES_NAVIGATIONFRAME;ナビゲーション +PREFERENCES_NOISE;ノイズ低減 +PREFERENCES_OUTDIRFOLDERHINT;選択したフォルダに画像を保存します +PREFERENCES_OUTDIRFOLDER;フォルダに保存 +PREFERENCES_OUTDIRTEMPLATEHINT;次の書式文字を使用することができます:\n%f, %d1, %d2, ..., %p1, %p2, ...%r\n\nこれらの書式文字は画像パス名のそれぞれ別々の部分、画像の属性を参照します\n\n例えば、次の画像を処理中の場合は:\n\n/home/tom/photos/2010-10-31/dsc0042.nef\n書式文字の意味するものは:\n%d4 = home\n%d3 = tom\n%d2 = photos\n%d1 = 2010-10-31\n%f = dsc0042\n%p1 = /home/tom/photos/2010-10-31/\n%p2 = /home/tom/photos/\n%p3 = /home/tom/\n%p4 = /home/\n\n%rは写真のランクに置き換えられます。評価なしは%rは'0 'に置換されます。画像がごみ箱にある場合、%rは'X'に置換されます\n\n元画像と同じ場所に出力したい場合はこのように書きます:\n%p1/%f\n\n処理画像のディレクトリ下 "converted" という名前のディレクトリに出力画像を保存したい場合このように書きます:\n%p1/converted/%f\n\n"/home/tom/photos/converted/2010-10-31" という名前のディレクトリに出力画像を保存したい場合はこのように書きます:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;テンプレートを使う +PREFERENCES_OUTDIR;出力ディレクトリ +PREFERENCES_OVERLAY_FILENAMES;ファイル名をサムネイル上に透過表示する +PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;ファイル名を編集パネルのサムネイル上に透過表示する +PREFERENCES_OVERWRITEOUTPUTFILE;既存ファイルを上書き +PREFERENCES_PANFACTORLABEL;パン速度の増幅 +PREFERENCES_PARSEDEXTADDHINT;拡張子を記入し このボタンでリストに追加します +PREFERENCES_PARSEDEXTADD;拡張子の追加 +PREFERENCES_PARSEDEXTDELHINT;選択した拡張子をリストから削除します +PREFERENCES_PARSEDEXT;拡張子 +PREFERENCES_PREVDEMO;プレビューのデモザイク方式 +PREFERENCES_PREVDEMO_FAST;Fast +PREFERENCES_PREVDEMO_LABEL;プレビューのズームレベルが100%以下の場合に使うデモザイクアルゴリズム: +PREFERENCES_PREVDEMO_SIDECAR;PP3の記述通り +PREFERENCES_PROFILEHANDLING;処理プロファイルの取扱い +PREFERENCES_PROFILELOADPR;処理プロファイル読み込みの優先 +PREFERENCES_PROFILEPRCACHE;cacheの中のプロファイル +PREFERENCES_PROFILEPRFILE;入力ファイルに隣接するプロファイル +PREFERENCES_PROFILESAVECACHE;処理プロファイルのパラメータをcacheに保存 +PREFERENCES_PROFILESAVEINPUT;処理プロファイルのパラメータを入力ファイルと同じディレクトリに保存 +PREFERENCES_PROPERTY;プロパティ +PREFERENCES_PSPATH;Adobe Photoshop のインストール・ディレクトリ +PREFERENCES_REMEMBERZOOMPAN;ズームレベルとパン速度を記憶する +PREFERENCES_REMEMBERZOOMPAN_TOOLTIP;現在の画像のズームレベルとパン速度を記憶し、新しく開く画像に適用\n\nこのオプションが使えるのは、編集画面のモードが“シングル編集”で、“プレビューのズームレベルが100%以下の場合に使うデモザイク”が“pp3に従う”と設定されている場合だけです。 +PREFERENCES_RGBDTL_LABEL;スレッドの最大数 +PREFERENCES_RGBDTL_TOOLTIP;ノイズ低減は、10メガピクセル画像では128MB程度、40メガピクセル画像では512MBを必要とします、そして更にスレッドごとに128MBが必要です。複数のスレッドを同時に実行すると演算が速くなります。自動的にできる限り多くのスレッドを使用するには"0"の設定のままにします +PREFERENCES_SELECTFONT;フォント選択 +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_SINGLETABVERTAB;シングル編集タブモード, 垂直タブ +PREFERENCES_SINGLETAB;シングルタブモードモード +PREFERENCES_SLIMUI;スリムインタフェース +PREFERENCES_SMA;小 (250x287) +PREFERENCES_SND_BATCHQUEUEDONE;キュー処理 終了 +PREFERENCES_SND_HELP;ファイルパスを入力 または空欄(無音).\nWindowsはシステムサウンドの "SystemDefault", "SystemAsterisk"など..\nLinuxはシステムサウンドの "complete", "window-attention"などを使用します +PREFERENCES_SND_LNGEDITPROCDONE;編集処理 終了 +PREFERENCES_SND_TRESHOLDSECS;秒後 +PREFERENCES_STARTUPIMDIR;起動時の画像・ディレクトリ +PREFERENCES_STDAUT;標準 +PREFERENCES_TAB_BROWSER;ファイルブラウザ +PREFERENCES_TAB_COLORMGR;カラーマネジメント +PREFERENCES_TAB_GENERAL;一般 +PREFERENCES_TAB_IMPROC;画像処理 +PREFERENCES_TAB_PERFORMANCE;パフォーマンスとクォリティ +PREFERENCES_TAB_SOUND;サウンド +PREFERENCES_TIMAX;多数 +PREFERENCES_TINB;タイル数 +PREFERENCES_TISTD;標準 +PREFERENCES_TP_LABEL;ツール パネル: +PREFERENCES_TP_USEICONORTEXT;テキストの代わりにタブアイコンを使用 +PREFERENCES_TP_VSCROLLBAR;ツールパネルの垂直スクロールバーを隠す +PREFERENCES_TUNNELMETADATA;変更のないIPTC/XMPを出力ファイルにコピー(他のプログラムにタグ付する場合) +PREFERENCES_USEBUNDLEDPROFILES;付属のプロファイルを使用 +PREFERENCES_USESYSTEMTHEME;システムのテーマを使う +PREFERENCES_VIEW;出力デバイスのホワイトバランス設定 (モニター, TV, プロジェクター,観視...) +PREFERENCES_WAVLEV;’高い’質の場合、ウェーブレット変換のレベルを上げる +PREFERENCES_WLONE;レベル1 +PREFERENCES_WLTWO;レベル2 +PREFERENCES_WLZER;上げない +PREFERENCES_WORKFLOW;レイアウト +PROFILEPANEL_COPYPPASTE;コピーするパラメータ +PROFILEPANEL_GLOBALPROFILES;付属のプロファイル +PROFILEPANEL_LABEL;処理プロファイル +PROFILEPANEL_LOADDLGLABEL;処理プロファイルを読み込む... +PROFILEPANEL_LOADPPASTE;読み込むパラメータ +PROFILEPANEL_MODE_TIP;処理プロファイルの適用モードボタン\n\nボタンが押された状態:処理プロファイルで設定されている値が適用され、且つ、他の値はプログラムにハードコーディングされているデフォルト値に置き換えられます\n\nボタンが離された状態:その処理プロファイルで設定されている値だけが適用されます +PROFILEPANEL_MYPROFILES;自分のプロファイル +PROFILEPANEL_PASTEPPASTE;貼り付けるパラメータ +PROFILEPANEL_PCUSTOM;カスタム +PROFILEPANEL_PFILE;ファイルから +PROFILEPANEL_PINTERNAL;ニュートラル +PROFILEPANEL_PLASTSAVED;更新済 +PROFILEPANEL_SAVEDLGLABEL;処理プロファイルを保存... +PROFILEPANEL_SAVEPPASTE;保存するパラメータ +PROFILEPANEL_TOOLTIPCOPY;クリップボードに現在のプロファイルをコピーします\nCtrl-クリックでコピーするパラメータを選択します +PROFILEPANEL_TOOLTIPLOAD;ファイルからプロファイルを読み込みます\nCtrl-クリックで読み込むパラメータを選択します +PROFILEPANEL_TOOLTIPPASTE; クリップボードからプロファイルを貼り付けます\nCtrl-クリックで貼り付けるパラメータを選択します +PROFILEPANEL_TOOLTIPSAVE;現在のプロファイルを保存\nCtrl-クリックで保存するパラメータを選択します +PROGRESSBAR_LOADINGTHUMBS;サムネイルの読み込み... +PROGRESSBAR_LOADING;画像読み込み中... +PROGRESSBAR_LOADJPEG;JPEGファイル読み込み中... +PROGRESSBAR_LOADPNG;;PNGファイル読み込み中... +PROGRESSBAR_LOADTIFF;TIFFファイル読み込み中... +PROGRESSBAR_NOIMAGES;画像が見つかりません +PROGRESSBAR_PROCESSING;画像処理中... +PROGRESSBAR_PROCESSING_PROFILESAVED;処理プロファイルを保存しました +PROGRESSBAR_READY;準備完了 +PROGRESSBAR_SAVEJPEG;JPEGファイル保存中... +PROGRESSBAR_SAVEPNG;PNGファイル保存中... +PROGRESSBAR_SAVETIFF;TIFFファイル保存中... +PROGRESSBAR_SNAPSHOT_ADDED;スナップショット追加 +PROGRESSDLG_PROFILECHANGEDINBROWSER;ブラウザでプロファイルの変更 +QINFO_ISO;ISO +QINFO_NOEXIF;Exifデータがありません +SAVEDLG_AUTOSUFFIX;ファイルが存在する場合、自動的に末尾に文字を加える +SAVEDLG_FILEFORMAT;ファイル形式 +SAVEDLG_FORCEFORMATOPTS;強制保存オプション +SAVEDLG_JPEGQUAL;JPEG 品質 +SAVEDLG_PNGCOMPR;PNG 圧縮 +SAVEDLG_PUTTOQUEUEHEAD;キュー処理の最初に追加 +SAVEDLG_PUTTOQUEUETAIL;キュー処理の最後に追加 +SAVEDLG_PUTTOQUEUE;キュー処理に追加 +SAVEDLG_SAVEIMMEDIATELY;すぐに保存 +SAVEDLG_SAVESPP;設定値も保存する +SAVEDLG_SUBSAMP;サブ・サンプリング +SAVEDLG_SUBSAMP_1;高圧縮 +SAVEDLG_SUBSAMP_2;バランス +SAVEDLG_SUBSAMP_3;高画質 +SAVEDLG_SUBSAMP_TOOLTIP;高圧縮: 4:1:1\nバランス: 4:2:2\n高画質: 4:4:4 +SAVEDLG_TIFFUNCOMPRESSED;非圧縮 TIFF +SAVEDLG_WARNFILENAME;ファイルに名前が付けられます +SHCSELECTOR_TOOLTIP;この3つのスライダーの位置をリセットするには\nマウスの右ボタンをクリック +THRESHOLDSELECTOR_BL;下-左 +THRESHOLDSELECTOR_BR;下-右 +THRESHOLDSELECTOR_B;下 +THRESHOLDSELECTOR_HINT;個々のコントロールポイントを移動するには、Shiftキーを押し続けます +THRESHOLDSELECTOR_TL;上-左 +THRESHOLDSELECTOR_TR;上-右 +THRESHOLDSELECTOR_T;上 +TOOLBAR_TOOLTIP_CROP;切り抜き範囲選択\nショートカット: c +TOOLBAR_TOOLTIP_HAND;手の平ツール\nショートカット: h +TOOLBAR_TOOLTIP_STRAIGHTEN;直線選択 / 角度補正\nショートカット: s\nプレビュー画像上にガイド線を描画し、垂直または水平方向を指示します。回転角度は、ガイド線の隣に表示されます。回転の中心は、プレビュー画像の中心です +TOOLBAR_TOOLTIP_WB;スポット・ホワイトバランス\nショートカット: w +TP_BWMIX_ALGO;アルゴリズム OYCPM +TP_BWMIX_ALGO_LI;リニア +TP_BWMIX_ALGO_SP;特殊効果 +TP_BWMIX_ALGO_TOOLTIP;リニア: 通常の 線形的 な効果です\n特殊効果: チャンネルミキサーによる 非線形的な特殊効果です +TP_BWMIX_AUTOCH;オート +TP_BWMIX_AUTOCH_TIP;チャンネルミキサーの最適値を計算します +TP_BWMIX_CC_ENABLED;補色の調整 +TP_BWMIX_CC_TOOLTIP;ROYGCBPMモードの中で補色の調整を自動で行います +TP_BWMIX_CHANNEL;輝度イコライザー +TP_BWMIX_CURVEEDITOR1;‘前の‘カーブ +TP_BWMIX_CURVEEDITOR2;‘後の‘カーブ +TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;処理最終段階で白黒変換を施した後のトーンカーブ +TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;色の構成を変えるかもしれない\n白黒変換を施す前のトーンカーブ +TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;色相における明度を補正\n極端な補正はアーティファクトの発生に注意します +TP_BWMIX_FILTER;カラーフィルター +TP_BWMIX_FILTER_BLUEGREEN;ブルー/グリーン +TP_BWMIX_FILTER_BLUE;ブルー +TP_BWMIX_FILTER_GREENYELLOW;グリーン/イエロー +TP_BWMIX_FILTER_GREEN;グリーン +TP_BWMIX_FILTER_NONE;なし +TP_BWMIX_FILTER_PURPLE;パープル +TP_BWMIX_FILTER_REDYELLOW;レッド/イエロー +TP_BWMIX_FILTER_RED;レッド +TP_BWMIX_FILTER_TOOLTIP;カラーフィルターはレンズにカラーフィルターを装着して撮影したような効果をもたらします。カラーフィルターは特定の入光色を減らし、特定の明るさを変えます。例、レッドフィルターは青空の色を暗くします。 +TP_BWMIX_FILTER_YELLOW;イエロー +TP_BWMIX_GAMMA;ガンマ補正 +TP_BWMIX_GAM_TOOLTIP;RGB各チャンネルのガンマを修正 +TP_BWMIX_LABEL;白黒 +TP_BWMIX_MET;方法 +TP_BWMIX_MET_CHANMIX;チャンネルミキサー +TP_BWMIX_MET_DESAT;彩度低減 +TP_BWMIX_MET_LUMEQUAL;輝度イコライザー +TP_BWMIX_MIXC;ミキサー +TP_BWMIX_NEUTRAL;ミキサーのリセット +TP_BWMIX_NEUTRAL_TIP;全ての値(フィルター、チャンネルミキサー)をデフォルトに戻します +TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% トータル: %4%% +TP_BWMIX_RGBLABEL_HINT;ミキサーオプションの全てを考慮した最終のRGBファクター\nトータルは実際に適用されたRGBの合計を表示:\n- 常に100%相対モード\n- 絶対モード100%より高い(明るい)、或いは低い(暗い) +TP_BWMIX_RGB_TOOLTIP;RGBチャンネルをミックス。ガイダンスとしてプリセットを使います。\nマイナス値はアーティファクトの発生や誤った作用を起こすかもしれないことに注意します +TP_BWMIX_SETTING;プリセット +TP_BWMIX_SETTING_TOOLTIP;異なるプリセット(フィルム調、風景。。。)、或いはチャンネルミキサーのマニュアル設定 +TP_BWMIX_SET_HIGHCONTAST;ハイコントラスト +TP_BWMIX_SET_HIGHSENSIT;高感度 +TP_BWMIX_SET_HYPERPANCHRO;ハイパーパンクロマティック +TP_BWMIX_SET_INFRARED;赤外線 +TP_BWMIX_SET_LANDSCAPE;風景 +TP_BWMIX_SET_LOWSENSIT;低感度 +TP_BWMIX_SET_LUMINANCE;輝度 +TP_BWMIX_SET_NORMCONTAST;普通のコントラスト +TP_BWMIX_SET_ORTHOCHRO;オルソクロマティック +TP_BWMIX_SET_PANCHRO;パンクロマティック +TP_BWMIX_SET_PORTRAIT;ポートレート +TP_BWMIX_SET_RGBABS;絶対RGB +TP_BWMIX_SET_RGBREL;相対RGB +TP_BWMIX_SET_ROYGCBPMABS;絶対ROYGCPBM +TP_BWMIX_SET_ROYGCBPMREL;相対ROYGCPBM +TP_BWMIX_TCMODE_FILMLIKE;白黒 フィルム調 +TP_BWMIX_TCMODE_SATANDVALBLENDING;白黒 彩度と明度のブレンド +TP_BWMIX_TCMODE_STANDARD;白黒 標準 +TP_BWMIX_TCMODE_WEIGHTEDSTD;白黒 加重平均 +TP_BWMIX_VAL;L +TP_CACORRECTION_BLUE;ブルー +TP_CACORRECTION_LABEL;色収差補正 +TP_CACORRECTION_RED;レッド +TP_CHMIXER_BLUE;ブルー +TP_CHMIXER_GREEN;グリーン +TP_CHMIXER_LABEL;チャンネルミキサー +TP_CHMIXER_RED;レッドチャンネル +TP_CHROMATABERR_LABEL;色収差 +TP_COARSETRAF_TOOLTIP_HFLIP;左右反転 +TP_COARSETRAF_TOOLTIP_ROTLEFT;90度左回転\nショートカット: [\n\nシングル・エディタ・タブのショートカット: Alt-[ +TP_COARSETRAF_TOOLTIP_ROTRIGHT;90度右回転\nショートカット: ]\n\nシングル・エディタ・タブのショートカット: Alt-] +TP_COARSETRAF_TOOLTIP_VFLIP;上下反転 +TP_COLORAPP_ADAPTSCENE;撮影輝度への適応 +TP_COLORAPP_ADAPTSCENE_TOOLTIP;撮影環境の絶対輝度(cd/m2)\n1)Exif情報から算出:\nシャッター速度、ISO、絞り、カメラの露出補正\n2)rawのホワイトポイントとRTの露光補正スライダー値から算出 +TP_COLORAPP_ADAPTVIEWING;観視輝度への適応 (cd/m2) +TP_COLORAPP_ADAPTVIEWING_TOOLTIP;観視環境の絶対輝度\n(通常 16cd/m2) +TP_COLORAPP_ADAP_AUTO_TOOLTIP;チェックボックッスが有効の場合(推奨)はRTがExif情報に基づいて最適値を計算します\n手動で行う場合はチェックボックスを無効にします +TP_COLORAPP_ALGO;アルゴリズム +TP_COLORAPP_ALGO_ALL;すべて +TP_COLORAPP_ALGO_JC;明度 + 色度 (JC) +TP_COLORAPP_ALGO_JS;明度 + 彩度 (JS) +TP_COLORAPP_ALGO_QM;明るさ + 鮮やかさ (QM) +TP_COLORAPP_ALGO_TOOLTIP;サブセット、或いは全てのパラメータの中から選択 +TP_COLORAPP_BADPIXSL;ホット/バッドピクセルフィルター +TP_COLORAPP_BADPIXSL_TOOLTIP;明るい部分のホット/バッドピクセルを圧縮します\n 0は効果なし 1は中間 2はガウスほかし\n\nこれらアーティファクトはCIECAM02の限界に起因するものです。色域を抑制する代わりに、イメージに暗い影が現れるのを防ぎます +TP_COLORAPP_BRIGHT;明るさ (Q) +TP_COLORAPP_BRIGHT_TOOLTIP;CIECAM02の明るさは L*a*b*やRGBとは異なり、白の輝度を計算に入れます +TP_COLORAPP_CHROMA;色度 (C) +TP_COLORAPP_CHROMA_M;鮮やかさ (M) +TP_COLORAPP_CHROMA_M_TOOLTIP;CIECAM02の鮮やかさは L*a*b*やRGBの鮮やかさとは異なります +TP_COLORAPP_CHROMA_S;彩度 (S) +TP_COLORAPP_CHROMA_S_TOOLTIP;CIECAM02の彩度は L*a*b*やRGBの彩度とは異なります +TP_COLORAPP_CHROMA_TOOLTIP;CIECAM02の色度は L*a*b*やRGBの色度とは異なります +TP_COLORAPP_CIECAT_DEGREE;CAT02に適応 +TP_COLORAPP_CONTRAST;コントラスト (J) +TP_COLORAPP_CONTRAST_Q;コントラスト (Q) +TP_COLORAPP_CONTRAST_Q_TOOLTIP;CIECAM02のコントラスト(明るさQ)スライダーは L*a*b*やRGBとは異なります +TP_COLORAPP_CONTRAST_TOOLTIP;CIECAM02のコントラスト(明度J)スライダーは L*a*b*やRGBとは異なります +TP_COLORAPP_CURVEEDITOR1;トーンカーブ1 +TP_COLORAPP_CURVEEDITOR1_TOOLTIP;CIECAM02調整前のL(L*a*b*)のヒストグラムを表示\n CIECAM出力のヒストグラム表示チェックボックスが有効になっている場合は、CIECAM調整後の JまたはQのヒストグラムを表示します\n\n(J、Q)はメイン・ヒストグラムパネルには表示されません\n\n最終出力はメインのヒストグラムパネルを参照してください +TP_COLORAPP_CURVEEDITOR2;トーンカーブ2 +TP_COLORAPP_CURVEEDITOR2_TOOLTIP;2番目の露光トーンカーブも同じ使い方です +TP_COLORAPP_CURVEEDITOR3;カラーカーブ +TP_COLORAPP_CURVEEDITOR3_TOOLTIP;色度、彩度、鮮やかさのいずれかを調整します\n\nCIECAM02調整前の色度(L*a*b*)のヒストグラムを表示します\nチェックボックスの"カーブにCIECAM02出力のヒストグラムを表示" が有効の場合、CIECAM02調整後のC,sまたはMのヒストグラムを表示します\n\nC, sとMは、メインのヒストグラム・パネルには表示されません\n最終出力は、メインのヒストグラム・パネルを参照してください +TP_COLORAPP_DATACIE;カーブにCIECAM02出力のヒストグラムを表示 +TP_COLORAPP_DATACIE_TOOLTIP;有効の場合、CIECAM02カーブのヒストグラムは、JかQ、CIECAM02調整後のCかs、またはMの値/範囲の近似値を表示します\nこの選択はメイン・ヒストグラムパネルには影響を与えません\n\n無効の場合、CIECAM02カーブのヒストグラムは、CIECAM調整前のL*a*b*値を表示します +TP_COLORAPP_DEGREE_AUTO_TOOLTIP;チェックボックスが有効の場合 (推奨)\nRTは、CAT02で使用され、更にCIECAM02全体で使用する最適値を算出します\n手動で値を設定するには、チェックボックスを無効にします (65以上の値を推奨) +TP_COLORAPP_DEGREE_TOOLTIP;CIE色順応変換2002(CAT02)の量 +TP_COLORAPP_GAMUT;色域制御 (L*a*b*) +TP_COLORAPP_GAMUT_TOOLTIP;L*a*b*モードの色域制御を許可 +TP_COLORAPP_HUE;色相 (h) +TP_COLORAPP_HUE_TOOLTIP;色相 (h) - 0° から 360°の角度 +TP_COLORAPP_LABEL;CIE色の見えモデル2002 +TP_COLORAPP_LABEL_CAM02;画像の調整 +TP_COLORAPP_LABEL_SCENE;撮影環境条件 +TP_COLORAPP_LABEL_VIEWING;観視条件 +TP_COLORAPP_LIGHT;明度 (J) +TP_COLORAPP_LIGHT_TOOLTIP;CIECAM02の明度は L*a*b*やRGBの明度とは異なります +TP_COLORAPP_MODEL;ホワイトポイント・モデル +TP_COLORAPP_MODEL_TOOLTIP;WB [RT] + [出力]:\nRTのホワイトバランスは、撮影環境に使用されます。CIECAM02はD50の設定, 出力デバイスのホワイトバランスは「環境設定」の「カラーマネジメント」の設定\n\nWB [RT+CAT02] + [出力]:\nRTのホワイトバランス設定は、CAT02で使用され、出力デバイスのホワイトバランスは環境設定の値を使用します +TP_COLORAPP_RSTPRO;レッドと肌色トーンを保護 +TP_COLORAPP_RSTPRO_TOOLTIP;レッドと肌色トーンを保護はスライダーとカーブの両方に影響します +TP_COLORAPP_SHARPCIE;Q/C で、シャープ化、ディテールレベルのコントラストとフリンジ低減 +TP_COLORAPP_SHARPCIE_TOOLTIP;有効にした場合、シャープ化、ディテールレベルのコントラストとフリンジ低減は、CIECAM02を使用します +TP_COLORAPP_SURROUND;周囲環境 +TP_COLORAPP_SURROUND_AVER;普通 +TP_COLORAPP_SURROUND_DARK;暗い +TP_COLORAPP_SURROUND_DIM;薄暗い +TP_COLORAPP_SURROUND_EXDARK;非常に暗い (Cutsheet) +TP_COLORAPP_SURROUND_TOOLTIP;トーンとカラーの変更は、出力デバイスの観視条件を計算に入れます\n\n普通:\n平均的な明るい環境 (標準)\n画像は変更されません\n\n薄暗い:\n薄暗い環境 (TV)\n画像は若干暗くなります\n\n暗い:\n暗い環境 (プロジェクター)\n画像はかなり暗くなります\n\n非常に暗い:\n非常に暗い環境 (Cutsheet)\n画像はとても暗くなります +TP_COLORAPP_SURSOURCE;暗い周囲環境 +TP_COLORAPP_SURSOURCE_TOOLTIP;ソース画像が暗い周囲環境にある場合使用できます +TP_COLORAPP_TCMODE_BRIGHTNESS;明るさ +TP_COLORAPP_TCMODE_CHROMA;色度 +TP_COLORAPP_TCMODE_COLORF;鮮やかさ +TP_COLORAPP_TCMODE_LABEL1;カーブ・モード1 +TP_COLORAPP_TCMODE_LABEL2;カーブ・モード2 +TP_COLORAPP_TCMODE_LABEL3;カーブ・色度モード +TP_COLORAPP_TCMODE_LIGHTNESS;明度 +TP_COLORAPP_TCMODE_SATUR;彩度 +TP_COLORAPP_TONECIE;CIECAM02 明るさ(Q)を使用してトーンマッピング +TP_COLORAPP_TONECIE_TOOLTIP;このオプションが無効になっている場合、トーンマッピングはL*a*b*空間を使用します\nこのオプションが有効になっている場合、トーンマッピングは、CIECAM02を使用します\nトーンマッピング(L*a*b*/CIECAM02)ツールを有効にするには、この設定を有効にする必要があります +TP_COLORAPP_WBCAM;WB [RT+CAT02] + [出力] +TP_COLORAPP_WBRT;WB [RT] + [出力] +TP_COLORTONING_AB;o C/L +TP_COLORTONING_AUTOSAT;自動彩度 +TP_COLORTONING_BALANCE;バランス +TP_COLORTONING_BY;o C/L +TP_COLORTONING_CHROMAC;不透明度 +TP_COLORTONING_COLOR;カラー +TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;C=f(L)の明度に応じたクロマの不透明度 +TP_COLORTONING_HIGHLIGHT;ハイライト +TP_COLORTONING_HUE;色相 +TP_COLORTONING_LABEL;カラートーン調整 +TP_COLORTONING_LAB;L*a*b*モデルでブレンド +TP_COLORTONING_LUMAMODE;明度を維持 +TP_COLORTONING_LUMAMODE_TOOLTIP;カラー(レッド、グリーン、シアン、ブルーなど)を変える際に、これを有効にすると、各ピクセルの明度は維持されます。 +TP_COLORTONING_LUMA;明度 +TP_COLORTONING_METHOD;方法 +TP_COLORTONING_METHOD_TOOLTIP;L*a*b*モデルのブレンドはカラー補間を使います\nカラーバランスは、シャドウ、ミッドトーン、ハイライトでバランスをとります\nSH+バランスは、ダイレクトカラーを使ってシャドウとハイライトでカラートン調整とバランスを調整します\n全ての方法で白黒変換を有効に出来ます +TP_COLORTONING_MIDTONES;中間トーン +TP_COLORTONING_NEUTRAL;スライダーをリセット +TP_COLORTONING_NEUTRAL_TIP;スライダーの全ての値(SMH:シャドウ、ミッドトーン、ハイライト)をデフォルトに戻す +TP_COLORTONING_OPACITY;不透明度 +TP_COLORTONING_RGBCURVES;RGB - カーブ +TP_COLORTONING_RGBSLIDERS;RGB - スライダー +TP_COLORTONING_SATURATEDOPACITY;強さ +TP_COLORTONING_SATURATIONTHRESHOLD;しきい値 +TP_COLORTONING_SA;彩度の保護 +TP_COLORTONING_SHADOWS;シャドウ +TP_COLORTONING_SPLITCOCO;S/M/Hでカラーバランス +TP_COLORTONING_SPLITCO;S/M/Hでカラートーン調整 +TP_COLORTONING_SPLITLR;2色の彩度でカラートーン調整 +TP_COLORTONING_STRENGTH;強さ +TP_COLORTONING_STR;強さ +TP_COLORTONING_TWO2;特定のクロマ‘2色’ +TP_COLORTONING_TWOALL;特定のクロマ +TP_COLORTONING_TWOBY;特定の'a*'と'b*' +TP_COLORTONING_TWOCOLOR_TOOLTIP;標準的クロマ:\n線形的作用 a*=b*\n特定のクロマ:\n線形的作用 a*=b*、同じ増減率、カーブを対角線より下に下げると不透明度の値はマイナスになる、色相全体が影響を受ける\n特定のa*とb*:\n線形的作用 a*、b*別々に調整、特殊効果が目的\n特定のクロマ2色:\nカラーカーブで特定された2つの色相だけが影響を受ける +TP_COLORTONING_TWOSTD;標準的クロマ +TP_CROP_FIXRATIO;縦横比固定 +TP_CROP_GTDIAGONALS;対角線 +TP_CROP_GTEPASSPORT;バイオメトリック・パスポート +TP_CROP_GTFRAME;フレーム +TP_CROP_GTGRID;グリッド +TP_CROP_GTHARMMEANS;調和平均 +TP_CROP_GTNONE;なし +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_W;W 幅 +TP_CROP_X;X +TP_CROP_Y;Y +TP_DARKFRAME_AUTOSELECT;自動選択 +TP_DARKFRAME_LABEL;ダークフレーム +TP_DEFRINGE_LABEL;フリンジ低減 +TP_DEFRINGE_RADIUS;半径 +TP_DEFRINGE_THRESHOLD;しきい値 +TP_DIRPYRDENOISE_33;強い3x3 +TP_DIRPYRDENOISE_55SOFT;5x5 +TP_DIRPYRDENOISE_55;強い5x5 +TP_DIRPYRDENOISE_77;7x7(遅い) +TP_DIRPYRDENOISE_99;9x9 (非常に遅い) +TP_DIRPYRDENOISE_ABM;色ノイズだけ +TP_DIRPYRDENOISE_AUTO;自動(分割方式) +TP_DIRPYRDENOISE_AUTO_TOOLTIP;色ノイズ低減の効果を確認して下さい\n注意:設定値の計算はあくまで平均的なもので、かなり主観的でです +TP_DIRPYRDENOISE_AUT;自動(分割方式) +TP_DIRPYRDENOISE_BLUE;色差 ブルー/イエロー +TP_DIRPYRDENOISE_C2TYPE_TOOLTIP;手動\n画像全体に作用します\nノイズ低減の設定を手動で行います\n\n自動(分割方式)\n画像全体に作用します\n画像を9つに分割して、そこから全体の色ノイズ低減に適した設定を自動的に行います\n\n自動(プレビュー方式)\n画像全体に作用します\nプレビューで見えている画像の一部を使って全体の色ノイズ低減に適した設定を自動で行います +TP_DIRPYRDENOISE_CCCURVE;色ノイズ低減のカーブ +TP_DIRPYRDENOISE_CHROMAFR;色ノイズ +TP_DIRPYRDENOISE_CHROMA;色(マスター) +TP_DIRPYRDENOISE_CTYPE;色ノイズの調整法 +TP_DIRPYRDENOISE_CTYPE_TOOLTIP;手動\n画像全体に作用します\nノイズ低減の設定を手動で行います\n\n自動(分割方式)\n画像全体に作用します\n画像を9つに分割して、そこから全体の色ノイズ低減に適した設定を自動的に行います\n\n自動(多分割方式)\nプレビュー画像には反映されません-保存画像だけに反映されます。但し、タイルサイズとその中心をプレビューサイズとその中心にマッチさせる〝プレビュー”方式を使えば、効果がどれ位か予測がつきます。\n画像をタイル状に分割し(タイル数は画像サイズ次第で、10~70枚になります)、各タイルにあった色ノイズ低減の設定を自動で行います\n\n自動(プレビュー方式)\n画像全体に作用します\nプレビューで見えている画像の一部を使って全体の色ノイズ低減に適した設定を自動で行います +TP_DIRPYRDENOISE_CURVEEDITOR_CC;色度 +TP_DIRPYRDENOISE_CURVEEDITOR_CC_TOOLTIP;色度のスライダーの値を全て増やします(乗数)\nこれは色度に応じて色ノイズの低減効果の強弱を調節するカーブです。例えば、色度の低い部分で低減効果を高めるとか、色度の高い部分で低減効果を緩める、という具合です。 +TP_DIRPYRDENOISE_CURVEEDITOR_L_TOOLTIP;‘輝度’の位置でノイズ低減の強さを加減します +TP_DIRPYRDENOISE_CUR;カーブ +TP_DIRPYRDENOISE_ENABLED_TOOLTIP;rawと非raw画像に使用することができます\n\n非raw画像の場合、輝度ノイズ低減は、入力カラープロファイルのガンマを使って行います。その際sRGBのガンマが想定されていますので、入力画像が異なるガンマのカラープロファイルであれば、輝度ノイズ低減の結果も異なります。 +TP_DIRPYRDENOISE_ENH;強化モード +TP_DIRPYRDENOISE_ENH_TOOLTIP;ノイズ低減の効果を髙めますが、代わりに演算時間が約20%増えます。 +TP_DIRPYRDENOISE_GAMMA;ガンマ +TP_DIRPYRDENOISE_GAMMA_TOOLTIP;ガンマは、トーンの範囲全体でノイズ低減の量を変化させます。値が大きいほど明るいトーンに効果を及ぼし、値が小さいほどシャドウをターゲットにします +TP_DIRPYRDENOISE_LABEL;ノイズ低減 +TP_DIRPYRDENOISE_LABM;L*a*b* +TP_DIRPYRDENOISE_LAB;L*a*b* +TP_DIRPYRDENOISE_LCURVE;輝度カーブ +TP_DIRPYRDENOISE_LDETAIL;輝度 細部の復元 +TP_DIRPYRDENOISE_LM;輝度のみ +TP_DIRPYRDENOISE_LPLABM;加重平均 L* (少なめ) + a*b* (普通) +TP_DIRPYRDENOISE_LTYPE;輝度ノイズの調整法 +TP_DIRPYRDENOISE_LUMAFR;輝度ノイズ +TP_DIRPYRDENOISE_LUMAFR_TOOLTIP;輝度の低減で、全体的にはウェーブレット変換、ディテールにはフーリエ変換を使います +TP_DIRPYRDENOISE_LUMA;輝度 +TP_DIRPYRDENOISE_MANU;手動 +TP_DIRPYRDENOISE_MAN;手動 +TP_DIRPYRDENOISE_MEDMETHOD;方式 +TP_DIRPYRDENOISE_MEDTYPE;フィルターの種類 +TP_DIRPYRDENOISE_MED;メディアンフィルター +TP_DIRPYRDENOISE_MED_TOOLTIP;メディアンフィルターによるノイズ低減を有効にします +TP_DIRPYRDENOISE_METHOD11;ノイズ低減の質 +TP_DIRPYRDENOISE_METHOD11_TOOLTIP;ノイズの状態に応じて低減効果の質を選べます:1-標準 2-高い\n2の方がノイズ低減効果は高くなりますが、その分処理時間が増えます。 +TP_DIRPYRDENOISE_METHOD;方式 +TP_DIRPYRDENOISE_METHOD_TOOLTIP;raw画像は、RGBまたはL*a*b*方式のいずれかを使用することができます。\n\nraw以外の画像は、選択にかかわらずL*a*b*方式が採用されます +TP_DIRPYRDENOISE_METM_TOOLTIP;フィルタリングの方式で、"輝度のみ"と"L*a*b*"を選択した場合、メディアンフィルタリングはノイズ低減行程でウェーブレット変換が行われた直後に適用されます\n"RGB"モードの場合は、ノイズ低減行程の最後で適用されます +TP_DIRPYRDENOISE_MET_TOOLTIP;適用するメディアンフィルターのサイズを決めます。大きくするとその分処理時間が増えます。\n\nソフトな3x3:1ピクセル範囲で5ピクセルの処理を行います\n強い3x3:1ピクセル範囲で9ピクセルの処理を行います\nソフトな5x5:2ピクセル範囲で13ピクセルの処理を行います\n強い5x5:2ピクセル範囲で25ピクセルの処理を行います\n7x7:3ピクセル範囲で49ピクセルの処理を行います\n9x9:4ピクセル範囲で81ピクセルの処理を行います\n\n小さいフィルターを使って、繰り返し処理をした方が、大きいフィルターを1回使うより結果が良いこともあります。 +TP_DIRPYRDENOISE_NOISELABELEMPTY;プレビューのノイズ: 中間色度= - 高色度= - +TP_DIRPYRDENOISE_NOISELABEL;プレビューのノイズ: 中間色度=%1 高色度=%2 +TP_DIRPYRDENOISE_NRESID_TOOLTIP;ウェーブレット変換後、プレビューで見える部分画像で残ったノイズのレベルを表示します\n\n>300以上 非常にノイズが多い\n100~300 ノイズが多い\n50~100 ノイズが少ない\n50以下 ノイズが非常に少ない\n\n算出値はRGBとL*a*b*モードでは異なります。RGBモードは輝度と色を完全に切り離すことが出来ないので、算出値の精度は劣ります。 +TP_DIRPYRDENOISE_PASSES;フィルタリングの繰り返し回数 +TP_DIRPYRDENOISE_PASSES_TOOLTIP;3x3のメディアンフィルターを3回繰り返して適用する方が、7x7のフィルターを1回適用するより、良い結果を生むことが多いです +TP_DIRPYRDENOISE_PON;自動(多分割方式) +TP_DIRPYRDENOISE_PREVLABEL;プレビューのサイズ=%1, 中心: Px=%2 Py=%3 +TP_DIRPYRDENOISE_PREV;プレビュー方式 +TP_DIRPYRDENOISE_PRE;自動(プレビュー方式) +TP_DIRPYRDENOISE_RED;色差 レッド/グリーン +TP_DIRPYRDENOISE_RGBM;RGB +TP_DIRPYRDENOISE_RGB;RGB +TP_DIRPYRDENOISE_SHALBI;高い +TP_DIRPYRDENOISE_SHAL;標準 +TP_DIRPYRDENOISE_SLI;スライダー +TP_DIRPYRDENOISE_SOFT;3x3 +TP_DIRPYRDENOISE_TILELABEL;タイルのサイズ=%1, 中心位置: X座標=%2 Y座標=%3 +TP_DIRPYREQUALIZER_ALGO;肌色の範囲 +TP_DIRPYREQUALIZER_ALGO_TOOLTIP;ファイン:撮影の肌色に近い部分に働くアルゴリズム、他の色への影響を最小限に抑えます\n広範: アーティファクトの増加を避けるアルゴリズムです +TP_DIRPYREQUALIZER_ARTIF;アーティファクトを軽減 +TP_DIRPYREQUALIZER_HUESKIN;肌色の色相 +TP_DIRPYREQUALIZER_HUESKIN_TOOLTIP;このカーブは上部ほど、アルゴリズムが効率良く働くことを示しています。\n下部ほど、色相の遷移が見られる部分です。\nコントロールポイントを左右に大きく動かす必要が生じたり、アーティファクトが生じたりする場合は、ホワイトバランスが妥当ではない時です。\n他の色への影響を避けるには、調整範囲を少し減らします +TP_DIRPYREQUALIZER_LABEL;ディテールレベルのコントラスト +TP_DIRPYREQUALIZER_LUMACOARSEST;粗い +TP_DIRPYREQUALIZER_LUMACONTRAST_MINUS;コントラスト- +TP_DIRPYREQUALIZER_LUMACONTRAST_PLUS;コントラスト+ +TP_DIRPYREQUALIZER_LUMAFINEST;細かい +TP_DIRPYREQUALIZER_LUMANEUTRAL;ニュートラル +TP_DIRPYREQUALIZER_SKIN;肌色の目標/保護 +TP_DIRPYREQUALIZER_SKIN_TOOLTIP;-100 肌色トーンの調整が目的になります\n0 全ての色調が調整の対象です\n+100 肌色が保護され、他の色調が調整されます +TP_DIRPYREQUALIZER_THRESHOLD;しきい値 +TP_DIRPYREQUALIZER_TOOLTIP;肌色(色相、色度、明度)と他の色の間の遷移でアーティファクトが発生するのを軽減します +TP_DISTORTION_AMOUNT;適用量 +TP_DISTORTION_AUTO;自動歪曲収差補正 +TP_DISTORTION_AUTO_TIP;(試用) 自動レンズ収差補正 (M4/3, 一部のコンデジ, etc.) +TP_DISTORTION_LABEL;歪曲収差補正 +TP_EPD_EDGESTOPPING;エッジ停止 +TP_EPD_GAMMA;ガンマ +TP_EPD_LABEL;トーンマッピング +TP_EPD_REWEIGHTINGITERATES;再加重反復 +TP_EPD_SCALE;スケール +TP_EPD_STRENGTH;強さ +TP_EPD_TOOLTIP;トーンマッピングは、L*a*b*モード(標準)またはCIECAM02モードを介して可能です\n\nL*a*b*モードの場合、トーンマッピングはウェーブレット機能の残差画像にも使えます\n\n CIECAM02トーンマッピングモードは以下の設定を有効にします:\n 1. CIECAM02\n 2. アルゴリズム="明るさ + 鮮やかさ (QM)"\n 3. "CIECAM02 明るさ(Q)でトーンマッピング" +TP_EXPOSURE_AUTOLEVELS;自動露光補正 +TP_EXPOSURE_AUTOLEVELS_TIP;画像を解析し露光補正を自動で設定します +TP_EXPOSURE_BLACKLEVEL;黒レベル +TP_EXPOSURE_BRIGHTNESS;明度 +TP_EXPOSURE_CLIP;クリップ % +TP_EXPOSURE_CLIP_TIP;自動露光補正によるハイライトとシャドウ部分での飽和ピクセルの割合制限 +TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;ハイライト圧縮 しきい値 +TP_EXPOSURE_COMPRHIGHLIGHTS;ハイライト圧縮 +TP_EXPOSURE_COMPRSHADOWS;シャドウ圧縮 +TP_EXPOSURE_CONTRAST;コントラスト +TP_EXPOSURE_CURVEEDITOR1;トーンカーブ1 +TP_EXPOSURE_CURVEEDITOR2;トーンカーブ2 +TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;2つのトーンカーブで最良の結果を得るためには、RawPediaの“露光>トーンカーブ”を参照して下さい。 +TP_EXPOSURE_EXPCOMP;露光量補正 +TP_EXPOSURE_LABEL;露光補正 +TP_EXPOSURE_SATURATION;彩度 +TP_EXPOSURE_TCMODE_FILMLIKE;フィルム調 +TP_EXPOSURE_TCMODE_LABEL1;カーブ・モード1 +TP_EXPOSURE_TCMODE_LABEL2;カーブ・モード2 +TP_EXPOSURE_TCMODE_LUMINANCE;輝度 +TP_EXPOSURE_TCMODE_SATANDVALBLENDING;彩度と明度のブレンド +TP_EXPOSURE_TCMODE_STANDARD;標準 +TP_EXPOSURE_TCMODE_WEIGHTEDSTD;加重平均 +TP_EXPOS_BLACKPOINT_LABEL;raw ブラック・ポイント +TP_EXPOS_WHITEPOINT_LABEL;raw ホワイト・ポイント +TP_FILMSIMULATION_LABEL;フィルムシミュレーション +TP_FILMSIMULATION_STRENGTH;強さ +TP_FILMSIMULATION_ZEROCLUTSFOUND;HaldCLUTのディレクトリーを指定して下さい +TP_FLATFIELD_AUTOSELECT;自動選択 +TP_FLATFIELD_BLURRADIUS;ぼかし半径 +TP_FLATFIELD_BLURTYPE;ぼかしタイプ +TP_FLATFIELD_BT_AREA;面 +TP_FLATFIELD_BT_HORIZONTAL;水平 +TP_FLATFIELD_BT_VERTHORIZ;垂直 + 水平 +TP_FLATFIELD_BT_VERTICAL;垂直 +TP_FLATFIELD_CLIPCONTROL;クリップコントロール +TP_FLATFIELD_CLIPCONTROL_TOOLTIP;クリップコントロールは、フラットフィールドを使った時に白飛びが発生するのを避けるために使います。適用する元画像に既に白飛びがある場合は、クリップコントロールの適用で色被りが起こる可能性があります。 +TP_FLATFIELD_LABEL;フラットフィールド +TP_GAMMA_CURV;ガンマ +TP_GAMMA_FREE;フリーなガンマ +TP_GAMMA_OUTPUT;出力 ガンマ +TP_GAMMA_SLOP;勾配(リニア) +TP_GENERAL_11SCALE_TOOLTIP;この機能の効果や、そのサブコンポーネントの確認には、プレビューで1:1以上のスケールが必要です。 +TP_GRADIENT_CENTER;中央位置 +TP_GRADIENT_CENTER_X;中央 X軸 +TP_GRADIENT_CENTER_X_TOOLTIP;アンカーポイントの位置 X軸: -100=左端, 0=中央, +100=右端 +TP_GRADIENT_CENTER_Y;中央 Y軸 +TP_GRADIENT_CENTER_Y_TOOLTIP;アンカーポイントの位置 y軸: -100=上端, 0=中央, +100=下端 +TP_GRADIENT_DEGREE;角度 +TP_GRADIENT_DEGREE_TOOLTIP;回転角度の度数 +TP_GRADIENT_FEATHER;フェザー処理 +TP_GRADIENT_FEATHER_TOOLTIP;対角線に対するグラデーションの幅の割合 +TP_GRADIENT_LABEL;グラデーションフィルター +TP_GRADIENT_STRENGTH;強さ +TP_GRADIENT_STRENGTH_TOOLTIP;終点位置でのフィルターの強さ +TP_HLREC_BLEND;ブレンド +TP_HLREC_CIELAB;CIEL*a*b* ブレンディング +TP_HLREC_COLOR;色の波及 +TP_HLREC_ENA_TOOLTIP;自動露光でも動作可 +TP_HLREC_LABEL;ハイライト復元 +TP_HLREC_LUMINANCE;輝度復元 +TP_HLREC_METHOD;方式: +TP_HSVEQUALIZER_CHANNEL;HSV チャンネル +TP_HSVEQUALIZER_HUE;H +TP_HSVEQUALIZER_LABEL;HSV イコライザ +TP_HSVEQUALIZER_SAT;S +TP_HSVEQUALIZER_VAL;V +TP_ICM_BLENDCMSMATRIX;マトリクスとハイライト・ブレンド +TP_ICM_BLENDCMSMATRIX_TOOLTIP;LUTベースのICCプロファイルを使用するときに白トビを修復 +TP_ICM_DCPILLUMINANT;光源 +TP_ICM_DCPILLUMINANT_INTERPOLATED;補間 +TP_ICM_DCPILLUMINANT_TOOLTIP;埋め込まれているDCPの光源のどちらを使うか選択。デフォルトではホワイトバランスに基づいて二つの光源の中間に補間する。この設定は二つのDCPの光源が補間サポートされる、を選択している場合に有効。 +TP_ICM_INPUTCAMERAICC;カメラ固有のプロファイル +TP_ICM_INPUTCAMERAICC_TOOLTIP;RawTherapeeが持っているカメラ固有のDCP或いはICCプロファイルを使用 シンプルなマトリクスより正確だが一部のカメラだけに利用可能 +TP_ICM_INPUTCAMERA;カメラの標準的プロファイル +TP_ICM_INPUTCAMERA_TOOLTIP;dcrawのシンプルなカラー・マトリクス、RawTherapeeの拡張バージョン(カメラの機種によりどちらでも可能)またはDNGの埋め込みを使用 +TP_ICM_INPUTCUSTOM;カスタム +TP_ICM_INPUTCUSTOM_TOOLTIP;独自の DCP/ICCプロファイルファイルを選択 +TP_ICM_INPUTDLGLABEL;DCP/ICC 入力プロファイルを選択... +TP_ICM_INPUTEMBEDDED;埋め込み使用, 可能なら +TP_ICM_INPUTEMBEDDED_TOOLTIP;raw以外のファイルに埋め込まれたカラープロファイルを使用 +TP_ICM_INPUTNONE;プロファイルなし +TP_ICM_INPUTNONE_TOOLTIP;すべてにカラープロファイルを使用しない 特殊な場合にのみ使用 +TP_ICM_INPUTPROFILE;入力プロファイル +TP_ICM_LABEL;カラー・マネジメント +TP_ICM_NOICM;No ICM: sRGB 出力 +TP_ICM_OUTPUTPROFILE;出力プロファイル +TP_ICM_SAVEREFERENCE;プロファイリングを参照する画像を保存 +TP_ICM_SAVEREFERENCE_APPLYWB;ホワイトバランスを適用 +TP_ICM_SAVEREFERENCE_TOOLTIP;入力プロファイルが適用される前のリニアなTIFF画像を保存します。キャリブレーション目的やカメラプロファイルの作成などに使います。 +TP_ICM_TONECURVE;DCPトーンカーブ使用 +TP_ICM_TONECURVE_TOOLTIP;DCPのプロファイルに含まれているトーンカーブを使用することができます +TP_ICM_WORKINGPROFILE;作業プロファイル +TP_IMPULSEDENOISE_LABEL;インパルスノイズ低減 +TP_IMPULSEDENOISE_THRESH;しきい値 +TP_LABCURVE_AVOIDCOLORSHIFT;色ずれを回避 +TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;作業色空間の色域に色を合わせ、マンセル補正を適用します +TP_LABCURVE_BRIGHTNESS;明度 +TP_LABCURVE_CHROMATICITY;色度 +TP_LABCURVE_CHROMA_TOOLTIP;白黒トーンを適用するには、彩度を-100に設定します +TP_LABCURVE_CONTRAST;コントラスト +TP_LABCURVE_CURVEEDITOR;L*a*b* 明度カーブ +TP_LABCURVE_CURVEEDITOR_A_RANGE1;グリーン・純色 +TP_LABCURVE_CURVEEDITOR_A_RANGE2;グリーン・明清色 +TP_LABCURVE_CURVEEDITOR_A_RANGE3;レッド・明清色 +TP_LABCURVE_CURVEEDITOR_A_RANGE4;レッド・純色 +TP_LABCURVE_CURVEEDITOR_B_RANGE1;ブルー・純色 +TP_LABCURVE_CURVEEDITOR_B_RANGE2;ブルー・明清色 +TP_LABCURVE_CURVEEDITOR_B_RANGE3;イエロー・明清色 +TP_LABCURVE_CURVEEDITOR_B_RANGE4;イエロー・純色 +TP_LABCURVE_CURVEEDITOR_CC;CC +TP_LABCURVE_CURVEEDITOR_CC_RANGE1;中間色 +TP_LABCURVE_CURVEEDITOR_CC_RANGE2;暗清色 +TP_LABCURVE_CURVEEDITOR_CC_RANGE3;明清色 +TP_LABCURVE_CURVEEDITOR_CC_RANGE4;純色 +TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;色度に応じた色度 C=f(C) +TP_LABCURVE_CURVEEDITOR_CH;CH +TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;色相に応じた色度 C=f(H) +TP_LABCURVE_CURVEEDITOR_CL;CL +TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;輝度に応じた色度 C=f(L) +TP_LABCURVE_CURVEEDITOR_HH;HH +TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;色相に応じた色相 H=f(H) +TP_LABCURVE_CURVEEDITOR_LC;LC +TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;色度に応じた輝度 L=f(C) +TP_LABCURVE_CURVEEDITOR_LH;LH +TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;色相に応じた輝度 L=f(H) +TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;輝度に応じた輝度 L*a*b* L=f(L) +TP_LABCURVE_LABEL;L*a*b* 調整 +TP_LABCURVE_LCREDSK;LCの適用をレッドと肌色トーンだけに制限 +TP_LABCURVE_LCREDSK_TIP;有効の場合 LC カーブ(色度に応じた輝度)の適用は、レッドと肌色トーンだけ制限されます\n無効の場合は、すべてのトーンに適用されます +TP_LABCURVE_RSTPROTECTION;レッドと肌色トーンを保護 +TP_LABCURVE_RSTPRO_TOOLTIP;色度スライダーとCCカーブを使用することができます +TP_LENSGEOM_AUTOCROP;自動的に切り抜き選択 +TP_LENSGEOM_FILL;オートフィル +TP_LENSGEOM_LABEL;レンズ / ジオメトリ +TP_LENSPROFILE_LABEL;レンズ補正 プロファイル +TP_LENSPROFILE_USECA;色収差補正 +TP_LENSPROFILE_USEDIST;歪曲収差補正 +TP_LENSPROFILE_USEVIGN;周辺光量補正 +TP_NEUTRAL;ニュートラル +TP_NEUTRAL_TIP;露光量補正のスライダー値をニュートラルにリセットします。\n自動露光補正の調整値ついても同様にリセットされます +TP_PCVIGNETTE_FEATHER;フェザー処理 +TP_PCVIGNETTE_FEATHER_TOOLTIP;フェザー処理: 0=四隅だけ、50=中央までの半分、100=中央まで +TP_PCVIGNETTE_LABEL;ビネットフィルター +TP_PCVIGNETTE_ROUNDNESS;フィルター形状 +TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;形状: 0=長方形、50=楕円形、100=円形 +TP_PCVIGNETTE_STRENGTH;強さ +TP_PCVIGNETTE_STRENGTH_TOOLTIP;終点位置でのフィルターの強さ(四隅) +TP_PERSPECTIVE_HORIZONTAL;水平 +TP_PERSPECTIVE_LABEL;パースペクティブ +TP_PERSPECTIVE_VERTICAL;垂直 +TP_PFCURVE_CURVEEDITOR_CH;色相 +TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;デフリンジの強さをコントロールします。値が高いと効果が強まり、低いと弱まります +TP_PREPROCESS_DEADPIXFILT;デッドピクセルフィルター +TP_PREPROCESS_DEADPIXFILT_TOOLTIP;デッドピクセルの圧縮を試みます +TP_PREPROCESS_GREENEQUIL;グリーン 平衡化 +TP_PREPROCESS_HOTPIXFILT;ホットピクセル・フィルター +TP_PREPROCESS_HOTPIXFILT_TOOLTIP;ホットピクセルの圧縮を試みます +TP_PREPROCESS_LABEL;前処理 +TP_PREPROCESS_LINEDENOISE;ラインノイズ フィルタ +TP_PREPROCESS_NO_FOUND;未検出 +TP_RAWCACORR_AUTO;自動補正 +TP_RAWCACORR_CABLUE;ブルー +TP_RAWCACORR_CARED;レッド +TP_RAWEXPOS_BLACKS;黒レベル +TP_RAWEXPOS_BLACK_0;グリーン1(先頭) +TP_RAWEXPOS_BLACK_1;レッド +TP_RAWEXPOS_BLACK_2;ブルー +TP_RAWEXPOS_BLACK_3;グリーン2 +TP_RAWEXPOS_BLACK_BLUE;ブルー +TP_RAWEXPOS_BLACK_GREEN;グリーン +TP_RAWEXPOS_BLACK_RED;レッド +TP_RAWEXPOS_LINEAR;ホワイトポイント補正 +TP_RAWEXPOS_PRESER;ハイライトを保持 +TP_RAWEXPOS_RGB;レッド、グリーン、ブルー +TP_RAWEXPOS_TWOGREEN;2つのグリーンを連動 +TP_RAW_DCBENHANCE;DCB 拡張処理 +TP_RAW_DCBITERATIONS;DCB 反復の数 +TP_RAW_DMETHOD;方式 +TP_RAW_DMETHOD_PROGRESSBAR;%1 デモザイク中... +TP_RAW_DMETHOD_PROGRESSBAR_REFINE;デモザイク・リファイン中... +TP_RAW_DMETHOD_TOOLTIP;注: IGVとLMMSEは高ISO画像に適しています +TP_RAW_FALSECOLOR;偽色抑制処理の回数 +TP_RAW_HD;しきい値 +TP_RAW_HD_TOOLTIP;設定値を低くすると、ホット/デッドピクセルの検出が強くなりますが、偽陽性によりアーティファクトが増えるかもしれません。ホット/デッドピクセルフィルターの使用で、アーティファクトの発生が認められた場合は、しきい値を少しずつアーティファクトが消えるまで増やします。 +TP_RAW_LABEL;デモザイク +TP_RAW_LMMSEITERATIONS;LMMSE 拡張処理 +TP_RAW_LMMSE_TOOLTIP;ガンマ追加 (step 1) - メディアン追加 (step 2,3,4), リファイン追加 (step 5,6) アーティファクトを低減しノイズ比を向上させます +TP_RAW_SENSOR_BAYER_LABEL;ベイヤー配列を使ったセンサー +TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;3-passが最適です(低ISO画像には奨められます)\n高ISO画像の場合、1-passと3-passの違いは殆どありません、処理速度は前者の方が速いです。 +TP_RAW_SENSOR_XTRANS_LABEL;X-Transマトリクスを使ったセンサー +TP_RESIZE_APPLIESTO;適用領域: +TP_RESIZE_CROPPEDAREA;切り抜き画像 +TP_RESIZE_FITBOX;バウンディング・ボックス +TP_RESIZE_FULLIMAGE;全画像 +TP_RESIZE_HEIGHT;高さ +TP_RESIZE_H;H: +TP_RESIZE_LABEL;リサイズ +TP_RESIZE_LANCZOS;ランチョス +TP_RESIZE_METHOD;方式: +TP_RESIZE_NEAREST;ニアリスト +TP_RESIZE_SCALE;スケール +TP_RESIZE_SPECIFY;条件指定: +TP_RESIZE_WIDTH;幅 +TP_RESIZE_W;W: +TP_RGBCURVES_BLUE;B +TP_RGBCURVES_CHANNEL;チャンネル +TP_RGBCURVES_GREEN;G +TP_RGBCURVES_LABEL;RGB カーブ +TP_RGBCURVES_LUMAMODE;輝度モード +TP_RGBCURVES_LUMAMODE_TOOLTIP;輝度モードは画像の色を変更させることなく、R、G、Bチャネルごとに画像の輝度を変化させることができます +TP_RGBCURVES_RED;R +TP_ROTATE_DEGREE;角度 +TP_ROTATE_LABEL;回転 +TP_ROTATE_SELECTLINE;直線選択・角度補正ツール +TP_SAVEDIALOG_OK_TIP;ショートカット Ctrl-Enter +TP_SHADOWSHLIGHTS_HIGHLIGHTS;ハイライトを暗く +TP_SHADOWSHLIGHTS_HLTONALW;ハイライトトーンの幅 +TP_SHADOWSHLIGHTS_LABEL;シャドウ/ハイライト +TP_SHADOWSHLIGHTS_LOCALCONTR;ローカルコントラスト +TP_SHADOWSHLIGHTS_RADIUS;半径 +TP_SHADOWSHLIGHTS_SHADOWS;シャドウを明るく +TP_SHADOWSHLIGHTS_SHARPMASK;シャープマスク +TP_SHADOWSHLIGHTS_SHTONALW;シャドウトーンの幅 +TP_SHARPENEDGE_AMOUNT;適用量 +TP_SHARPENEDGE_LABEL;エッジ +TP_SHARPENEDGE_PASSES;反復 +TP_SHARPENEDGE_THREE;輝度のみ +TP_SHARPENING_AMOUNT;適用量 +TP_SHARPENING_EDRADIUS;半径 +TP_SHARPENING_EDTOLERANCE;エッジ許容 +TP_SHARPENING_HALOCONTROL;ハロ抑制 +TP_SHARPENING_HCAMOUNT;適用量 +TP_SHARPENING_LABEL;シャープ化 +TP_SHARPENING_METHOD;方式 +TP_SHARPENING_ONLYEDGES;エッジのみシャープ化 +TP_SHARPENING_RADIUS;半径 +TP_SHARPENING_RLD;RL デコンボリューション +TP_SHARPENING_RLD_AMOUNT;適用量 +TP_SHARPENING_RLD_DAMPING;減衰 +TP_SHARPENING_RLD_ITERATIONS;繰返し +TP_SHARPENING_THRESHOLD;しきい値 +TP_SHARPENING_TOOLTIP;CIECAM02で使用する場合、わずかに異なる結果が予想されます。違いが認められた場合、好みに合わせて調整します +TP_SHARPENING_USM;アンシャープマスク +TP_SHARPENMICRO_AMOUNT;適用量 +TP_SHARPENMICRO_LABEL;マイクロコントラスト +TP_SHARPENMICRO_MATRIX;3×3マトリクスの代わりに 5×5 +TP_SHARPENMICRO_UNIFORMITY;均等 +TP_VIBRANCE_AVOIDCOLORSHIFT;色ずれを回避 +TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH +TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;肌色トーン +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;レッド/パープル +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;レッド +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;レッド/イエロー +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;イエロー +TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;色相に応じた色相 H=f(H) +TP_VIBRANCE_LABEL;自然な彩度 +TP_VIBRANCE_PASTELS;明清色トーン +TP_VIBRANCE_PASTSATTOG;明清色と純色トーンをリンク +TP_VIBRANCE_PROTECTSKINS;肌色トーンを保護 +TP_VIBRANCE_PSTHRESHOLD;明清色/純色トーン しきい値 +TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;純色トーン しきい値 +TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;縦軸は下が明清色トーン,上が純色を表し\n\n横軸は彩度の範囲を表しています +TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;明清色/純色トーン 移行の加重 +TP_VIBRANCE_SATURATED;純色トーン +TP_VIGNETTING_AMOUNT;適用量 +TP_VIGNETTING_CENTER;中心位置 +TP_VIGNETTING_CENTER_X;中心 X軸 +TP_VIGNETTING_CENTER_Y;中心 Y軸 +TP_VIGNETTING_LABEL;周辺光量補正 +TP_VIGNETTING_RADIUS;半径 +TP_VIGNETTING_STRENGTH;濃度 +TP_WAVELET_1;レベル 1 +TP_WAVELET_2;レベル 2 +TP_WAVELET_3;レベル 3 +TP_WAVELET_4;レベル 4 +TP_WAVELET_5;レベル 5 +TP_WAVELET_6;レベル 6 +TP_WAVELET_7;レベル 7 +TP_WAVELET_8;レベル 8 +TP_WAVELET_9;レベル 9 +TP_WAVELET_ALL;全てのレベルと方向を合わせた画像 +TP_WAVELET_APPLYTO;適用 +TP_WAVELET_AVOID;色ずれの回避 +TP_WAVELET_B0;黒 +TP_WAVELET_B1;グレー +TP_WAVELET_B2;残差 +TP_WAVELET_BACUR;カーブ +TP_WAVELET_BALANCE;コントラストバランス 斜め/垂直-水平 +TP_WAVELET_BALANCE_TOOLTIP;ウェーブレットの方向で垂直-水平と斜めのバランスを変えます\nコントラスト、色度、或いは残差画像のトーンマッピングが有効の場合、バランスにより効果が増幅されます +TP_WAVELET_BALCHRO;色度のバランス +TP_WAVELET_BALCHRO_TOOLTIP;有効にすると、’コントラストバランス’のカーブやスライダーも色度のバランスに影響します +TP_WAVELET_BANONE;なし +TP_WAVELET_BASLI;スライダー +TP_WAVELET_BATYPE;バランス方式 +TP_WAVELET_CCURVE;ローカルコントラスト +TP_WAVELET_CH1;全ての色 +TP_WAVELET_CH2;明清色 - 純色 +TP_WAVELET_CH3;コントラストのレベルとリンク +TP_WAVELET_CHCU;カーブ +TP_WAVELET_CHRO;純色 - 明清色のしきい値 +TP_WAVELET_CHRO_TOOLTIP;どのレベルで明清色と純色を調整するか決めます\n1-x:純色を調整するレベルの範囲\nx-9:明清色を調整するレベルの範囲\n\n但し、値がレベルの総数より多い場合は機能が無効となります +TP_WAVELET_CHR;色度とコントラストのリンクの強さ +TP_WAVELET_CHR_TOOLTIP;色度を”コントラストレベル”と”色度とコントラストのリンクの強さ”の相関関係で調整します +TP_WAVELET_CHSL;スライダー +TP_WAVELET_CHTYPE;調整の方法 +TP_WAVELET_COLORT;レッド/グリーンの不透明度 +TP_WAVELET_COMBOTH;両方 +TP_WAVELET_COMPCONT;コントラスト +TP_WAVELET_COMPGAMMA;ガンマの圧縮 +TP_WAVELET_COMPGAMMA_TOOLTIP;残差画像のガンマを調整することで、画像データとヒストグラムの均衡を図ります。 +TP_WAVELET_COMPTM;トーンマッピング +TP_WAVELET_CONTEDIT;'後の' コントラストカーブ +TP_WAVELET_CONTRAST_MINUS;コントラスト - +TP_WAVELET_CONTRAST_PLUS;コントラスト + +TP_WAVELET_CONTRA;コントラスト +TP_WAVELET_CONTRA_TOOLTIP;残差画像のコントラストを変えます +TP_WAVELET_CONTR;色域 +TP_WAVELET_CTYPE;色の制御 +TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;元画像のローカルコントラストに応じてローカルコントラストを調節します\n横軸の低い部分は細かいローカルコントラストを表しています(実質値10~20)\n50%はローカルコントラストの平均(実質値100~300)を表しています\n66%はローカルコントラストの標準偏差(実質値300~800)を表しています\n100%はローカルコントラストの最大値を表しています(実質値3000~8000) +TP_WAVELET_CURVEEDITOR_CH;コントラストレベル=f(色相) +TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;色相に応じて各レベルのコントラストを調節します\n色域抑制のカーブ調整と重複しないように注意します\nウェーブレットのコントラストレベルスライダー値が0の場合は効果はありません +TP_WAVELET_CURVEEDITOR_CL;L +TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;ウェーブレットの処理工程の最後で最終的な輝度のコントラストカーブを適用します +TP_WAVELET_CURVEEDITOR_HH;HH +TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;色相に応じて、残差画像の色相を調整します +TP_WAVELET_DALL;全ての方向 +TP_WAVELET_DAUB;エッジ検出の効果 +TP_WAVELET_DAUB_TOOLTIP;ドブシー関数の係数を変更します\nD4=標準的なエッジ検出の効果\nD14=通常はエッジ検出の効果が高いが、処理時間が約10%増加\n\n初めのレベルの質だけでなくエッジ検出にも影響します。但し、レベル質は厳格に係数の種類に比例している訳ではありません。画像や使い方にも影響されます。 +TP_WAVELET_DISP;プレビューでの表示形式 +TP_WAVELET_DONE;垂直 +TP_WAVELET_DTHR;対角線 +TP_WAVELET_DTWO;水平 +TP_WAVELET_EDCU;カーブ +TP_WAVELET_EDGCONT;ローカルコントラスト +TP_WAVELET_EDGCONT_TOOLTIP;スライダーを左に動かすとコントラストが減り、右に動かすと増えます\n底部の左、天井部の左、底部の右、天井部の右は、それぞれ低いコントラスト、平均的コントラスト、平均+1標準偏差のコントラスト、最も高いコントラストを示しています +TP_WAVELET_EDGEDETECTTHR2;しきい値 高(エッジ検出) +TP_WAVELET_EDGEDETECTTHR;しきい値 低(ノイズ) +TP_WAVELET_EDGEDETECTTHR_TOOLTIP;しきい値を変えることで、エッジ検出の目標を調整します。例えば、青空の中のノイズが先鋭化しないようにします。 +TP_WAVELET_EDGEDETECT;グラデーション感度 +TP_WAVELET_EDGEDETECT_TOOLTIP;スライダーを右に動かすと、エッジ検出の感度が上がります。これはローカルコントラスト、しきい値 高、しきい値 低にも影響します +TP_WAVELET_EDGE;エッジのシャープネス +TP_WAVELET_EDGREINF_TOOLTIP;最初のレベルに対する作用を強めたり、弱めたりし、次のレベルに対してはその逆を行います、他のレベルは変わりません +TP_WAVELET_EDGTHRESH;ディテール +TP_WAVELET_EDGTHRESH_TOOLTIP;低いレベルと他のレベルの区分を変更します。しきい値を高くするほど、低いレベルに作用の重点が置かれます。注意:マイナス値の設定は高いレベルに重点が置かれ、アーティファクトが発生することがあります。 +TP_WAVELET_EDRAD;半径 +TP_WAVELET_EDRAD_TOOLTIP;この機能の半径は、他のシャープ化機能の半径とは大きく異なります。複雑な関数を使って各レベルの値を比較します。そのため、半径がゼロでも何らかの効果があります +TP_WAVELET_EDSL;しきい値スライダー +TP_WAVELET_EDTYPE;ローカルコントラストの方式 +TP_WAVELET_EDVAL;強さ +TP_WAVELET_FINAL;最終調整 +TP_WAVELET_FINEST;最も細かい +TP_WAVELET_HIGHLIGHT;ハイライトの輝度範囲 +TP_WAVELET_HS1;全輝度範囲 +TP_WAVELET_HS2;シャドウ-ハイライト +TP_WAVELET_HUESKIN;肌色の色相 +TP_WAVELET_HUESKIN_TOOLTIP;底部の2つのポイントは、色相変化が始まる部分に設定されています、天井部の2つのポイントは変化が終わる所で、色相調整の効果が最も高い部分です\n\n設定ポイントを著しく動かす必要がある場合、或いはアーティファクトが発生するようであれば、ホワイトバランスが不適切と考えられます +TP_WAVELET_HUESKY;色相の範囲(デフォルト:青空) +TP_WAVELET_HUESKY_TOOLTIP;底部の2つのポイントは、色相変化が始まる部分に設定されています、天井部の2つのポイントは変化が終わる所で、色相調整の効果が最も高い部分です\n\n設定ポイントを著しく動かす必要がある場合、或いはアーティファクトが発生するようであれば、ホワイトバランスが不適切と考えられます +TP_WAVELET_INF;選択したレベル以下の画像 +TP_WAVELET_ITER;デルタバランスのレベル +TP_WAVELET_ITER_TOOLTIP;スライダーを左に動かすと、低いレベルのデルタが増え、高いレベルのデルタが減ります\n右に動かすとその逆です +TP_WAVELET_LABEL;ウェーブレット +TP_WAVELET_LARGEST;最も粗い +TP_WAVELET_LEVCH;色度 +TP_WAVELET_LEVELS;ウェーブレット レベルの数 +TP_WAVELET_LEVELS_TOOLTIP;画像を幾つの詳細レベルに分割するか選択します。分割数が増えればメモリー使用量が増え、処理時間も長くなります。 +TP_WAVELET_LEVF;コントラスト +TP_WAVELET_LEVLABEL;プレビューで表示可能な最大レベル=%1 +TP_WAVELET_LEVONE;レベル2 +TP_WAVELET_LEVTWO;レベル3 +TP_WAVELET_LEVZERO;レベル1 +TP_WAVELET_LINKEDG;エッジのシャープネスの強さとリンク +TP_WAVELET_LIPST;高度なアルゴリズム +TP_WAVELET_LIPST_TOOLTIP;リプシッツ連続というアルゴリズムを使います。処理時間とメモリー消費量は増えますが、エッジ検出の精度は上がります +TP_WAVELET_LOWLIGHT;シャドウの輝度範囲 +TP_WAVELET_MEDGREINF;最初のレベル +TP_WAVELET_MEDILEV;エッジ検出 +TP_WAVELET_MEDI;青空のアーティファクトを軽減 +TP_WAVELET_NEUTRAL;ニュートラル +TP_WAVELET_NOISE;ノイズ低減とリファイン +TP_WAVELET_NOIS;ノイズ低減 +TP_WAVELET_ONE;選択したレベルだけ +TP_WAVELET_OPACITYWL;最終的なローカルコントラスト +TP_WAVELET_OPACITYWL_TOOLTIP;ウェーブレット処理の最後で最終的なローカルコントラストを調整します\n\nイコライザは左から右に向かって、最も細かいローカルコントラストから大きいローカルコントラストを表しています +TP_WAVELET_OPACITYWL_TOOLTIP;分解された全てのレベルの画像に対し、最後に施されたローカルコントラスト(横座標)に応じて、最終的なローカルコントラストを調整します\n調整にあたっては以下の点を考慮します: \na)コントラストレベル\nb)エッジのシャープネス\nc)コントラストのバランス\nd)分解‐再合成の影響\n横座標の低い部分は細かいローカルコントラストを意味します(実数値をしては10~20)\n横座標の50%は平均的なローカルコントラストを代表しています(実数値をしては200~1000)\n横座標の66%は1標準偏差に収まるローカルコントラストを代表しています(実数値としては1000~2000)\n横座標の100%部分はローカルコントラストの最大値です(実数値として約5000~13000) +TP_WAVELET_OPACITYW;コントラストバランス d/v-hカーブ +TP_WAVELET_OPACITY;ブルー/イエローの不透明度 +TP_WAVELET_PASTEL;明清色の色度 +TP_WAVELET_PREVIEWBACK;背景 +TP_WAVELET_PREVIEWLEVELS;プレビュー +TP_WAVELET_RE1;強める +TP_WAVELET_RE2;変えない +TP_WAVELET_RE3;弱める +TP_WAVELET_RESCHRO;色度 +TP_WAVELET_RESCONH;ハイライト +TP_WAVELET_RESCON;シャドウ +TP_WAVELET_RESID;残差画像 +TP_WAVELET_SAT;純色の色度 +TP_WAVELET_SETTINGS;ウェーブレットの設定 +TP_WAVELET_SKIN;色相-トーン (肌色) の目標/保護 +TP_WAVELET_SKIN_TOOLTIP;-100にすると肌色のトーンだけが調整の対象になります\n0にすると全てのカラートーンが調整されます\n+100にすると肌色のトーンは保護され、他のカラートーンが調整されます +TP_WAVELET_SKY;色相-トーン(青空)の目標/保護 +TP_WAVELET_SKY_TOOLTIP;-100にすると青空のトーンだけが調整の対象になります\n0にすると全てのカラートーンが調整されます\n+100にすると青空のトーンは保護され、他のカラートーンが調整されます +TP_WAVELET_STRENGTH;強さ +TP_WAVELET_STREN;強さ +TP_WAVELET_SUPE;エキストラ +TP_WAVELET_SUP;選択したレベルより上の画像 +TP_WAVELET_THRESHOLD2;シャドウを調整するレベル +TP_WAVELET_THRESHOLD2_TOOLTIP;レベル9と(9-設定値)のレベルの間でシャドウの輝度が調整されます。他のレベルは輝度範囲全体で調整されます。 +TP_WAVELET_THRESHOLD;ハイライトを調整するレベル +TP_WAVELET_THRESHOLD_TOOLTIP;設定値以上のレベルだけが、ハイライトの輝度で調整されます。他のレベルは輝度範囲全体で調整されます。選べる設定値の最大数はシャドウレベルの設定に左右されます。 +TP_WAVELET_THRH;ハイライトのしきい値 +TP_WAVELET_THR;シャドウのしきい値 +TP_WAVELET_TILESBIG;大きいタイル +TP_WAVELET_TILESFULL;画像全体 +TP_WAVELET_TILESIZE;タイルのサイズ +TP_WAVELET_TILESLIT;小さいタイル +TP_WAVELET_TILES_TOOLTIP;画像全体を処理する方が良い結果をもたらすので、推奨される選択です。タイルによる処理はRAMの容量が小さいユーザー向けです。必要なメモリー容量に関してはRawPediaを参照して下さい。 +TP_WAVELET_TMHIGH;高 +TP_WAVELET_TMLOWHIGH;低と高に偏重 +TP_WAVELET_TMNONE;なし +TP_WAVELET_TMSTD;標準 +TP_WAVELET_TMSTRENGTH;残差の効力を圧縮 +TP_WAVELET_TMSTRENGTH_TOOLTIP;トーンマッピングの強さや残差画像のコントラストの圧縮を加減します。値が0以外の場合、露光補正パネルのトーンマッピングでは、強さとガンマのスライダー無効となります +TP_WAVELET_TMTYPE;圧縮の方法 +TP_WAVELET_TON;カラートーン +TP_WAVELET_daub2;D2 - 低い +TP_WAVELET_daub4;D4 - 標準 +TP_WAVELET_daub6;D6 - 標準プラス +TP_WAVELET_daub10;D10 - やや高い +TP_WAVELET_daub14;D14 - 高い +TP_WBALANCE_AUTO;自動補正 +TP_WBALANCE_CAMERA;カメラ +TP_WBALANCE_CLOUDY;曇天 +TP_WBALANCE_CUSTOM;カスタム +TP_WBALANCE_DAYLIGHT;昼光 (晴天) +TP_WBALANCE_EQBLUERED;ブルー/レッド イコライザ +TP_WBALANCE_EQBLUERED_TOOLTIP;ブルーとレッドを調整することで、ホワイトバランスの作用を通常とは異なるものにします。\nこれは次のような撮影条件の場合に役立つでしょう:\na)光源が標準的なものと大きく異なる場合(例、水中)\nb)キャリブレーションの範囲から大きく外れている場合\nc)カラーマトリクスやICCプロファイルが不適当な場合 +TP_WBALANCE_FLASH55;Leica +TP_WBALANCE_FLASH60;標準, Canon, Pentax, Olympus +TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta +TP_WBALANCE_FLASH_HEADER;フラッシュ +TP_WBALANCE_FLUO1;F1 - 昼光色 +TP_WBALANCE_FLUO2;F2 - クールホワイト +TP_WBALANCE_FLUO3;F3 - ホワイト +TP_WBALANCE_FLUO4;F4 - ウォームホワイト +TP_WBALANCE_FLUO5;F5 - 昼白色 +TP_WBALANCE_FLUO6;F6 - Lite ホワイト +TP_WBALANCE_FLUO7;F7 - D65 常用光源 +TP_WBALANCE_FLUO8;F8 - D50 / Sylvania F40 Design +TP_WBALANCE_FLUO9;F9 - デラックスクールホワイト +TP_WBALANCE_FLUO10;F10 - Philips TL85 +TP_WBALANCE_FLUO11;F11 - Philips TL84 +TP_WBALANCE_FLUO12;F12 - Philips TL83 +TP_WBALANCE_FLUO_HEADER;蛍光灯 +TP_WBALANCE_GREEN;色偏差 +TP_WBALANCE_GTI;GTI +TP_WBALANCE_HMI;HMI +TP_WBALANCE_JUDGEIII;JudgeIII +TP_WBALANCE_LABEL;ホワイトバランス +TP_WBALANCE_LAMP_HEADER;ランプ +TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 +TP_WBALANCE_LED_HEADER;LED +TP_WBALANCE_LED_LSI;LSI Lumelex 2040 +TP_WBALANCE_METHOD;モード +TP_WBALANCE_SHADE;日陰 +TP_WBALANCE_SIZE;サイズ: +TP_WBALANCE_SOLUX35;Solux 3500K +TP_WBALANCE_SOLUX41;Solux 4100K +TP_WBALANCE_SOLUX47;Solux 4700K (vendor) +TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) +TP_WBALANCE_SPOTWB;スポットWB +TP_WBALANCE_TEMPERATURE;色温度 +TP_WBALANCE_TUNGSTEN;タングステン +TP_WBALANCE_WATER1;水中 1 +TP_WBALANCE_WATER2;水中 2 +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ショートカット: - + diff --git a/rtdata/languages/LICENSE b/rtdata/languages/LICENSE new file mode 100755 index 000000000..fbc14b67e --- /dev/null +++ b/rtdata/languages/LICENSE @@ -0,0 +1,18 @@ +# All files in this directory are part of RawTherapee. +# +# Copyright (c) 2004-2010 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 . +# + diff --git a/rtdata/languages/Latvian b/rtdata/languages/Latvian new file mode 100644 index 000000000..bc0fef6ab --- /dev/null +++ b/rtdata/languages/Latvian @@ -0,0 +1,1857 @@ +#01 YYYY-MM-DD by nickname + +ADJUSTER_RESET_TO_DEFAULT;Atmest uz noklusēto +CURVEEDITOR_LINEAR;Lineāri +CURVEEDITOR_LOADDLGLABEL;Ielādēt līkni... +CURVEEDITOR_SAVEDLGLABEL;Saglabāt līkni... +CURVEEDITOR_TOOLTIPLINEAR;Iztaisnot līkni +CURVEEDITOR_TOOLTIPLOAD;Ielādēt līkni no faila +CURVEEDITOR_TOOLTIPSAVE;Saglabāt esošo līkni +DIRBROWSER_FOLDERS;Mapes +EXIFFILTER_APERTURE;Atvērums +EXIFFILTER_CAMERA;Kamera +EXIFFILTER_FOCALLEN;Fokusa garums +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Lēca +EXIFFILTER_SHUTTER;Slēdzis +EXIFPANEL_ADDEDITHINT;Pielikt jaunu birku vai labot birku +EXIFPANEL_ADDEDIT;Pielikt/Labot +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Ievadiet vērtību +EXIFPANEL_ADDTAGDLG_SELECTTAG;Izvēlēt birku +EXIFPANEL_ADDTAGDLG_TITLE;Pielikt/Labot birku +EXIFPANEL_KEEPHINT;Atstāt izvēlētās birkas kad raksta izvades failu +EXIFPANEL_KEEP;Atstāt +EXIFPANEL_REMOVEHINT;Noņemt izvēlētās birkas kad raksta izvades failu +EXIFPANEL_REMOVE;Noņemt +EXIFPANEL_RESETALLHINT;Atmest visas birkas uz to noklusētajām vērtībām +EXIFPANEL_RESETALL;Atmest visu +EXIFPANEL_RESETHINT;Atmest izvēlētās birkas uz to noklusētajām vērtībām +EXIFPANEL_RESET;Atmest +EXIFPANEL_SUBDIRECTORY;Subdirektorijs +FILEBROWSER_APPLYPROFILE;Lietot profilu +FILEBROWSER_CLEARPROFILE;Notīrīt profilu +FILEBROWSER_COPYPROFILE;Kopēt profilu +FILEBROWSER_DELETEDLGLABEL;Faila dzēšanas apstiprinājums +FILEBROWSER_DELETEDLGMSG;Vai tiešām dzēst %1 atzīmētos filus? +FILEBROWSER_EMPTYTRASHHINT;Galīgi izdzēst atkritnes failus +FILEBROWSER_EMPTYTRASH;Izmest atkritumus +FILEBROWSER_PARTIALPASTEPROFILE;Daļēja ielīmēšana +FILEBROWSER_PASTEPROFILE;Ielīmēt profilu +FILEBROWSER_POPUPCANCELJOB;Atcelt darbu +FILEBROWSER_POPUPMOVEEND;Pārvietot uz rindas beigām +FILEBROWSER_POPUPMOVEHEAD;Pārvietot uz rindas sākumu +FILEBROWSER_POPUPOPENINEDITOR;Atvērt redaktorā +FILEBROWSER_POPUPOPEN;Atvērt +FILEBROWSER_POPUPPROCESS;Ielikt apstrādes rindā +FILEBROWSER_POPUPREMOVE;Dzēst no failu sistēmas +FILEBROWSER_POPUPRENAME;Pārsaukt +FILEBROWSER_POPUPSELECTALL;Atzīmēt visu +FILEBROWSER_POPUPTRASH;Izmest atkritnē +FILEBROWSER_POPUPUNRANK;Nevērtēt +FILEBROWSER_POPUPUNTRASH;Izņemt no atkritnes +FILEBROWSER_RENAMEDLGLABEL;Pārsaukt failu +FILEBROWSER_RENAMEDLGMSG;Pārsaukt failu "%1" uz: +FILEBROWSER_SHOWDIRHINT;Rādīt visus direktorija attēlus +FILEBROWSER_SHOWRANK1HINT;Rādīt attēlus ar 1 zvaigzni +FILEBROWSER_SHOWRANK2HINT;Rādīt attēlus ar 2 zvaigznēm +FILEBROWSER_SHOWRANK3HINT;Rādīt attēlus ar 3 zvaigznēm +FILEBROWSER_SHOWRANK4HINT;Rādīt attēlus ar 4 zvaigznēm +FILEBROWSER_SHOWRANK5HINT;Rādīt attēlus ar 5 zvaigznēm +FILEBROWSER_SHOWTRASHHINT;Rādīt atkritni +FILEBROWSER_SHOWUNRANKHINT;Rādīt nevērtētus attēlus +FILEBROWSER_STARTPROCESSINGHINT;Sākt attēlu rindas apstrādi/saglabāšanu +FILEBROWSER_STARTPROCESSING;Sākt apstrādi +FILEBROWSER_STOPPROCESSINGHINT;Apturēt attēlu apstrādi +FILEBROWSER_STOPPROCESSING;Apturēt apstrādi +FILEBROWSER_THUMBSIZE;Sīktēlu izmērs +FILEBROWSER_ZOOMINHINT;Palielināt sīktēlus +FILEBROWSER_ZOOMOUTHINT;Samazināt sīktēlus +GENERAL_ABOUT;Par +GENERAL_CANCEL;Atcelt +GENERAL_DISABLED;Atslēgts +GENERAL_DISABLE;Atslēgt +GENERAL_ENABLED;Ieslēgts +GENERAL_ENABLE;Ieslēgt +GENERAL_LANDSCAPE;Ainava +GENERAL_NA;n/a +GENERAL_NO;Nē +GENERAL_OK;Labi +GENERAL_PORTRAIT;Portrets +GENERAL_SAVE;Saglabāt +HISTOGRAM_TOOLTIP_B;Rādīt/Slēpt Zilā histogrammu +HISTOGRAM_TOOLTIP_G;Rādīt/Slēpt Zaļā histogrammu +HISTOGRAM_TOOLTIP_L;Rādīt/Slēpt CIELAB Spīduma histogrammu +HISTOGRAM_TOOLTIP_R;Rādīt/Slēpt Sarkanā histogrammu +HISTORY_CHANGED;Mainīts +HISTORY_CUSTOMCURVE;Pielāgota līkne +HISTORY_DELSNAPSHOT;Noņemt grāmtzīmi +HISTORY_FROMCLIPBOARD;No starplikas +HISTORY_LABEL;Vēsture +HISTORY_MSG_1;Attēls ielādēts +HISTORY_MSG_2;Profils ielādēts +HISTORY_MSG_3;Profils izmainīts +HISTORY_MSG_4;Vēstures pārlūkošana +HISTORY_MSG_5;Gaišums +HISTORY_MSG_6;Kontrasts +HISTORY_MSG_7;Melnais +HISTORY_MSG_8;Ekspozīcijas labošana +HISTORY_MSG_9;Izgaismojumu spiešana +HISTORY_MSG_10;Ēnu spiešana +HISTORY_MSG_11;Toņa līkne +HISTORY_MSG_12;Auto Ekspozīcija +HISTORY_MSG_13;Ekspozīcijas cirpšana +HISTORY_MSG_14;Spīduma Gaišums +HISTORY_MSG_15;Spīduma Kontrasts +HISTORY_MSG_16;Spīduma Melnais +HISTORY_MSG_17;Spīduma Izgaismojumu spiešana +HISTORY_MSG_18;Spīduma Ēnu spiešana +HISTORY_MSG_19;Spīduma Līkne +HISTORY_MSG_20;Asināšana +HISTORY_MSG_21;Asināšanas radiuss +HISTORY_MSG_22;Asināšanas apjoms +HISTORY_MSG_23;Asināšanas slieksnis +HISTORY_MSG_24;Asināt tikai malas +HISTORY_MSG_25;Asināšanas malu meklēšanas radiuss +HISTORY_MSG_26;Asināšanas malu iecietība +HISTORY_MSG_27;Asināšanas caurumu kontrole +HISTORY_MSG_28;Caurumu kontroles apjoms +HISTORY_MSG_29;Asināšanas metode +HISTORY_MSG_30;Atritināšanas radiuss +HISTORY_MSG_31;Atritināšanas apjoms +HISTORY_MSG_32;Atritināšanas slāpēšana +HISTORY_MSG_33;Atritināšanas soļi +HISTORY_MSG_34;Izvairīties no krāsu cirpšanas +HISTORY_MSG_35;Piesātinājuma ierobežojums +HISTORY_MSG_36;Piesātinājuma robeža +HISTORY_MSG_37;Krāsu pastiprināšana +HISTORY_MSG_38;Baltā līdzsvara metode +HISTORY_MSG_39;Krāsu temperatūra +HISTORY_MSG_40;Baltā līdzsvara nokrāsa +HISTORY_MSG_41;Krāsu nobīde "A" +HISTORY_MSG_42;Krāsu nobīde "B" +HISTORY_MSG_43;Spīduma trokšņu slāpēšana +HISTORY_MSG_44;Spož. trokšņu slāpēšanas radiuss +HISTORY_MSG_45;Spož. trokšņu slāpēšanas malu iecietība +HISTORY_MSG_46;Krāsu trokšņu slāpēšana +HISTORY_MSG_47;Krāsu trokšņu slāpēšanas radiuss +HISTORY_MSG_48;Krāsu trokšņu slāpēšanas malu iecietība +HISTORY_MSG_49;Krāsu trokšņu slāpēšanas malu jutīgums +HISTORY_MSG_50;Ēnu/Izgaismojumu rīks +HISTORY_MSG_51;Izgaismojumu pastiprināšana +HISTORY_MSG_52;Ēnu pastiprināšana +HISTORY_MSG_53;Izgaismojumu toņa platums +HISTORY_MSG_54;Ēnu toņa platums +HISTORY_MSG_55;Vietējais kontrasts +HISTORY_MSG_56;Ēnu/Izgaismojumu radiuss +HISTORY_MSG_57;Raupja pagriešana +HISTORY_MSG_58;Horizontāla apmešana +HISTORY_MSG_59;Vertikāla apmešana +HISTORY_MSG_60;Pagriešana +HISTORY_MSG_61;Pagriešana +HISTORY_MSG_62;Lēcu kropļojumu labošana +HISTORY_MSG_63;Grāmatzīme izvēlēta +HISTORY_MSG_64;Kadrējums +HISTORY_MSG_65;Krāsu nobīdes labošana +HISTORY_MSG_66;Izgaismojumu atgūšana +HISTORY_MSG_67;Izgaismojumu atgūšanas apjoms +HISTORY_MSG_68;Izgaismojumu atgūšanas metode +HISTORY_MSG_69;Krāsu telpa darbam +HISTORY_MSG_70;Krāsu telpa izvadei +HISTORY_MSG_71;Ievades krāsu telpa +HISTORY_MSG_72;Vinjetes labošana +HISTORY_MSG_73;Kanālu jaucējs +HISTORY_MSG_74;Izmēra mērogs +HISTORY_MSG_75;Izmērmaiņas metode +HISTORY_MSG_76;Exif metadati +HISTORY_MSG_77;IPTC metadati +HISTORY_MSG_78;Norādīti izmērmaiņas dati +HISTORY_MSG_79;Izmērmaiņas platums +HISTORY_MSG_80;Izmērmaiņas augstums +HISTORY_MSG_81;Izmērmaiņa ieslēgta +HISTORY_NEWSNAPSHOT;Jauna grāmtzīme +HISTORY_SNAPSHOTS;Grāmtzīmes +HISTORY_SNAPSHOT;Grāmtzīme +IPTCPANEL_AUTHORSPOSITIONHINT;Objekta radītāja amapts (By-line Title). +IPTCPANEL_AUTHORSPOSITION;Autora amats +IPTCPANEL_AUTHOR;Autors +IPTCPANEL_CAPTIONHINT;Datu tekstveida apraksts (Caption - Abstract) +IPTCPANEL_CAPTIONWRITERHINT;Personas vārfds, kura ir iesaistīta attēla, virsraksta vai kopsavilkuma rakstīšanā, rediģēšanā vai labošānā (Writer - Editor) +IPTCPANEL_CAPTIONWRITER;Virsraksta autors +IPTCPANEL_CAPTION;Virsraksts +IPTCPANEL_CATEGORYHINT;Attēla radītājs identificē attēla subjektu (Category). +IPTCPANEL_CATEGORY;Kategorija +IPTCPANEL_CITYHINT;Attēla izcelsmes pilsēta (City). +IPTCPANEL_CITY;Pilsēta +IPTCPANEL_COPYHINT;Kopēt IPTC iestatījumus uz starpliku +IPTCPANEL_COPYRIGHTHINT;Jebkāds nepieciešamais brīdinājums par autortiesībām (Copyright Notice). +IPTCPANEL_COPYRIGHT;Autortiesības +IPTCPANEL_COUNTRYHINT;Attēla sākotnējās izveidošanas valsts (Country - Primary Location Name). +IPTCPANEL_COUNTRY;Valsts +IPTCPANEL_CREDITHINT;Identificē attēla sniedzēju, nav obligāti radītājs vai īpašnieks (Credit). +IPTCPANEL_CREDIT;Pateicība +IPTCPANEL_DATECREATEDHINT;Attēla intelektuālā satura radīšanas datums; Formāts: ggggmmdd (Date Created). +IPTCPANEL_DATECREATED;Izveidošanas datums +IPTCPANEL_EMBEDDEDHINT;Attiestatīt uz attēla iegultajiem IPTC datiem +IPTCPANEL_EMBEDDED;Iegultais +IPTCPANEL_HEADLINEHINT;Publicējams raksts, kas satur attēla konspektu (Headline). +IPTCPANEL_HEADLINE;Konspekts +IPTCPANEL_INSTRUCTIONSHINT;Citi redaktora norādījumi par attēla lietošanu (Special Instructions). +IPTCPANEL_INSTRUCTIONS;Norādījumi +IPTCPANEL_KEYWORDSHINT;Norāda vārdus specifiskas informācijas iegūšanai (Keywords). +IPTCPANEL_KEYWORDS;Atslēgvārdi +IPTCPANEL_PASTEHINT;Ielīmēt IPTC iestatījumus no starplikas +IPTCPANEL_PROVINCEHINT;Attēla izcelsmes valsts vai province (Province-State). +IPTCPANEL_PROVINCE;Province +IPTCPANEL_RESETHINT;Atiestatīt uz profila noklusējumu +IPTCPANEL_RESET;Atiestate +IPTCPANEL_SOURCEHINT;Attēla intelektuālā īpašuma īpašnieks (Source). +IPTCPANEL_SOURCE;Avots +IPTCPANEL_SUPPCATEGORIESHINT;Precizē attēla subjektu (Supplemental Categories). +IPTCPANEL_SUPPCATEGORIES;Apakškategorija +IPTCPANEL_TITLEHINT;Attēla saīsināts nosaukums (Object Name). +IPTCPANEL_TITLE;Nosaukums +IPTCPANEL_TRANSREFERENCEHINT;Kods, kas norāda uz attēla sākotnējas pārneses vietu (Original Transmission Reference). +IPTCPANEL_TRANSREFERENCE;Pārneses atsauce +MAIN_BUTTON_PREFERENCES;Iestatījumi +MAIN_BUTTON_SAVE;Saglabāt attēlu +MAIN_BUTTON_SENDTOEDITOR;Sūtīt uz redaktoru +MAIN_FRAME_BATCHQUEUE;Batch Queue +MAIN_FRAME_FILEBROWSER;File Browser +MAIN_FRAME_PLACES;Places +MAIN_FRAME_PLACES_ADD;Add +MAIN_FRAME_PLACES_DEL;Del +MAIN_FRAME_RECENT;Recent Folders +MAIN_MSG_ALREADYEXISTS;Fails jau ir. +MAIN_MSG_CANNOTLOAD;Nevaru ielādēt attēlu +MAIN_MSG_CANNOTSAVE;Faila saglabāšanas kļūda +MAIN_MSG_CANNOTSTARTEDITOR;Nevar uzsākt redaktoru. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Lūdzu ievadiet pareizu ceļu dialogā "Uzstādījumi". +MAIN_MSG_QOVERWRITE;Vai pārrakstīt to? +MAIN_TAB_COLOR;Krāsa +MAIN_TAB_DETAIL;Detaļas +MAIN_TAB_DEVELOP;Develop +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;Ekspozīcija +MAIN_TAB_FILTER;Filter +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadati +MAIN_TAB_TRANSFORM;Pārveidot +MAIN_TOOLTIP_HIDEHP;Rādīt/slēpt kreiso ielaidumu (ieskaitot vēsturi, saīsne: H) +MAIN_TOOLTIP_INDCLIPPEDH;Izgaismojumu cirpšanas pazīme +MAIN_TOOLTIP_INDCLIPPEDS;Ēnu cirpšanas pazīme +MAIN_TOOLTIP_QINFO;Ātrā info uz attēla +PARTIALPASTE_BASICGROUP;Pamata uzstādījumi +PARTIALPASTE_CACORRECTION;Krāsu novirzes labošana +PARTIALPASTE_COARSETRANS;90 grādu rotēšana / apmešana +PARTIALPASTE_COLORGROUP;Krāsu uzstādījumi +PARTIALPASTE_COMPOSITIONGROUP;Kompozīcijas uzstādījumi +PARTIALPASTE_CROP;Apcirpt +PARTIALPASTE_DIALOGLABEL;Daļēji ielīmēt apstrādes profilu +PARTIALPASTE_DISTORTION;Kropļojumu labošana +PARTIALPASTE_EXIFCHANGES;exif datu izmaiņas +PARTIALPASTE_EXPOSURE;Ekspozīcija +PARTIALPASTE_ICMSETTINGS;ICM uzstādījumi +PARTIALPASTE_IPTCINFO;IPTC info +PARTIALPASTE_LENSGROUP;Lēcas uzstādījumi +PARTIALPASTE_METAGROUP;Metadati +PARTIALPASTE_RESIZE;Izmērmaiņa +PARTIALPASTE_ROTATION;Rotācija +PARTIALPASTE_SHADOWSHIGHLIGHTS;Ēnas/izgaismojumi +PARTIALPASTE_SHARPENING;Asināšana +PARTIALPASTE_VIGNETTING;Vinjetes labošana +PARTIALPASTE_WHITEBALANCE;Baltā līdzsvarss +PREFERENCES_APPLNEXTSTARTUP;lietos nākamā reizē +PREFERENCES_CACHECLEARALL;Attīrīt visu +PREFERENCES_CACHECLEARPROFILES;Attīrīt Profilus +PREFERENCES_CACHECLEARTHUMBS;Attīrīt sīktēlus +PREFERENCES_CACHEMAXENTRIES;Maksimālais keša ierakstu skaits +PREFERENCES_CACHEOPTS;Keša opcijas +PREFERENCES_CACHETHUMBHEIGHT;Keša maksimālais sīktēla augstums +PREFERENCES_CLIPPINGIND;Cirpšanas pazīme +PREFERENCES_CMETRICINTENT;Kolorimetrijas nolūks +PREFERENCES_DATEFORMATHINT;Jūs varat lietot šāduas formatēšanas parametrus:\n%y : gads\n%m : mēnesis\n%d : diena\n\nPiemēram, ungāru datuma formāts ir:\n%y/%m/%d +PREFERENCES_DATEFORMAT;Datuma formāts +PREFERENCES_DEFAULTLANG;Noklusētā valoda +PREFERENCES_DEFAULTTHEME;Noklusētā tēma +PREFERENCES_DIRHOME;Mājas mape +PREFERENCES_DIRLAST;Pēdējā lietotā mape +PREFERENCES_DIROTHER;Cita +PREFERENCES_DIRSELECTDLG;Izvēlies attēlu mapi sākumam... +PREFERENCES_DIRSOFTWARE;Uzstādīšanas mape +PREFERENCES_EDITORCMDLINE;Cita komandrinda +PREFERENCES_EXTERNALEDITOR;Ārējais redaktors +PREFERENCES_FBROWSEROPTS;Failu pārlūka iespējas +PREFERENCES_FILEFORMAT;Faila formāts +PREFERENCES_FORIMAGE;Attēlu failiem +PREFERENCES_FORRAW;RAW failiem +PREFERENCES_GIMPPATH;GIMP instalācijas direktorijs +PREFERENCES_HLTHRESHOLD;Cirpto izgaismojumu slieksnis +PREFERENCES_ICCDIR;ICC profilu mape +PREFERENCES_IMPROCPARAMS;Noklusētie attēla apstrādes parametri +PREFERENCES_INTENT_ABSOLUTE;Absolūtā kolorimetrija +PREFERENCES_INTENT_PERCEPTUAL;Uztverams +PREFERENCES_INTENT_RELATIVE;Relatīvā kolorimetrija +PREFERENCES_INTENT_SATURATION;Piesātinājums +PREFERENCES_MONITORICC;Monitora Profils +PREFERENCES_OUTDIRFOLDERHINT;Likt saglabātos attēlus norādītajā mapē +PREFERENCES_OUTDIRFOLDER;Saglabāt mapē +PREFERENCES_OUTDIRTEMPLATEHINT;Jūs varat lietot šādas formatēšanas virknes:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nŠīs formatēšanas virknes attiecas uz direktorijiem un RAW faila apakšceļiem.\n\nPiemēram, ja ir atvērts /home/tom/image/02-09-2006/dsc0012.nef, formatējuma virkņu nozīme ir:\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\nJa vēlaties rezultātu saglabāt turpat pie oriģināla, rakstiet:\n%p1/%f\n\nJa vēlaties rezultātu saglabāt direktorijā 'converted' pie oriģināla, rakstiet:\n%p1/converted/%f\n\nJa vēlaties rezultātu saglabāt direktorijā '/home/tom/converted' paturot to pašu datumu apakšdirektoriju, rakstiet:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Lietot veidni +PREFERENCES_OUTDIR;Izvades mape +PREFERENCES_PARSEDEXTADDHINT;Ierakstiet paplašinājumu un nospiediet šo pogu lai pievienotu sarakstam +PREFERENCES_PARSEDEXTADD;Pielikt paplašinājumu +PREFERENCES_PARSEDEXTDELHINT;Dzēst atzīmēto paplašinājumu no saraksta +PREFERENCES_PARSEDEXT;Parsētie paplašīnājumi +PREFERENCES_PROFILEHANDLING;Apstrādes profilu politika +PREFERENCES_PROFILELOADPR;Profilu ielādes prioritāte +PREFERENCES_PROFILEPRCACHE;Profils kešā +PREFERENCES_PROFILEPRFILE;Profils pie ievades faila +PREFERENCES_PROFILESAVECACHE;Saglabāt apstrādes profilu kešā +PREFERENCES_PROFILESAVEINPUT;Saglabāt apstrādes profilu pie ievades faila +PREFERENCES_PSPATH;Adobe Photoshop instalācijas direktorijs +PREFERENCES_SELECTLANG;Izvēlies valodu +PREFERENCES_SELECTTHEME;Izvēlieties tēmu +PREFERENCES_SHOWBASICEXIF;Rādīt Exif pamatdatus +PREFERENCES_SHOWDATETIME;Rādīt datumu un laiku +PREFERENCES_SHTHRESHOLD;Cirpto ēnu slieksnis +PREFERENCES_STARTUPIMDIR;Attēlu mape sākumā +PREFERENCES_TAB_BROWSER;Failu pārlūks +PREFERENCES_TAB_COLORMGR;Krāsu pārvaldība +PREFERENCES_TAB_GENERAL;Vispārīgi +PREFERENCES_TAB_IMPROC;Attēlu apstrāde +PROFILEPANEL_LABEL;Apstrādes profili +PROFILEPANEL_LOADDLGLABEL;Ielādēt apstrādes profilu... +PROFILEPANEL_PCUSTOM;Pielāgots +PROFILEPANEL_PFILE;No faila +PROFILEPANEL_PLASTSAVED;Pēdējais saglabātais +PROFILEPANEL_SAVEDLGLABEL;Saglabāt apstrādes profilu... +PROFILEPANEL_TOOLTIPCOPY;Kopēt esošo profilu uz starpliku +PROFILEPANEL_TOOLTIPLOAD;Ielādēt profilu no faila +PROFILEPANEL_TOOLTIPPASTE;Ielīmēt profilu no starplikas +PROFILEPANEL_TOOLTIPSAVE;Saglabāt šībrīža profilu +PROGRESSBAR_LOADING;Attēla ielāde... +PROGRESSBAR_LOADJPEG;Ielādēju JPEG failu... +PROGRESSBAR_LOADPNG;Ielādēju PNG failu... +PROGRESSBAR_LOADTIFF;Ielādēju TIFF failu... +PROGRESSBAR_PROCESSING;Attēla apstrāde... +PROGRESSBAR_READY;Gatavs +PROGRESSBAR_SAVEJPEG;Saglabāju JPEG failu... +PROGRESSBAR_SAVEPNG;Saglabāju PNG failu... +PROGRESSBAR_SAVETIFF;Saglabāju TIFF failu... +QINFO_ISO;ISO +QINFO_NOEXIF;Exif dati nav pieejami. +SAVEDLG_FILEFORMAT;Faila formāts +SAVEDLG_JPEGQUAL;JPEG Kvalitāte +SAVEDLG_PNGCOMPR;PNG Spiešana +SAVEDLG_PUTTOQUEUEHEAD;Likt apstrādes rindas sākumā +SAVEDLG_PUTTOQUEUETAIL;Likt apstrādes rindas beigās +SAVEDLG_PUTTOQUEUE;Likt apstrādes rindā +SAVEDLG_SAVEIMMEDIATELY;Saglabāt tūlīt +SAVEDLG_SAVESPP;Saglabāt apstrādes profilu ar attēlu +TOOLBAR_TOOLTIP_CROP;Kadrēšanas rīks (saīsne: C) +TOOLBAR_TOOLTIP_HAND;Plaukstas rīks (saīsne: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;Līmeņošanas rīks (saīsne: S) +TOOLBAR_TOOLTIP_WB;Punkta baltā līdzsvara rīks (saīsne: W) +TP_CACORRECTION_BLUE;Zils +TP_CACORRECTION_LABEL;Lēcas krāsu nobīdes +TP_CACORRECTION_RED;Sarkans +TP_CHMIXER_BLUE;Zils +TP_CHMIXER_GREEN;Zaļš +TP_CHMIXER_LABEL;Kanālu jaucējs +TP_CHMIXER_RED;Sarkans +TP_COARSETRAF_TOOLTIP_HFLIP;Apmest horizontāli +TP_COARSETRAF_TOOLTIP_ROTLEFT;Pagriezt pa kreisi +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Pagriezt pa labi +TP_COARSETRAF_TOOLTIP_VFLIP;Apmest vertikāli +TP_CROP_FIXRATIO;Attiecība: +TP_CROP_GTDIAGONALS;Diagonāles +TP_CROP_GTNONE;Nekādas +TP_CROP_GTRULETHIRDS;Trešdaļas +TP_CROP_GUIDETYPE;Vadlīnijas: +TP_CROP_H;A +TP_CROP_LABEL;Kadrējums +TP_CROP_SELECTCROP; Norādīt kadrējumu +TP_CROP_W;P +TP_CROP_X;x +TP_CROP_Y;y +TP_DISTORTION_AMOUNT;Apjoms +TP_DISTORTION_LABEL;Lēcas kropļojums +TP_EXPOSURE_AUTOLEVELS;Auto Līmeņi +TP_EXPOSURE_BLACKLEVEL;Melnais +TP_EXPOSURE_BRIGHTNESS;Gaišums +TP_EXPOSURE_CLIP;Cirpt +TP_EXPOSURE_COMPRHIGHLIGHTS;Izgaismojumu spiešana +TP_EXPOSURE_COMPRSHADOWS;Ēnu spiešana +TP_EXPOSURE_CONTRAST;Kontrasts +TP_EXPOSURE_CURVEEDITOR;Toņa līkne +TP_EXPOSURE_EXPCOMP;Eksp. nobīde +TP_EXPOSURE_LABEL;Ekspozīcija +TP_HLREC_CIELAB;CIELab maisījums +TP_HLREC_COLOR;Krāsu pavairošana +TP_HLREC_LABEL;Izgaismojumu atgūšana +TP_HLREC_LUMINANCE;Spīduma atgūšana +TP_HLREC_METHOD;Metode: +TP_ICM_INPUTCAMERA;Kameras noklusētais +TP_ICM_INPUTCUSTOM;Pielāgots +TP_ICM_INPUTDLGLABEL;Izvēlies Ievades ICC Profilu... +TP_ICM_INPUTEMBEDDED;Lietot iegulto, ja var +TP_ICM_INPUTPROFILE;Ievades profils +TP_ICM_LABEL;ICM +TP_ICM_NOICM;Bez ICM: sRGB izvade +TP_ICM_OUTPUTPROFILE;Izvades profils +TP_ICM_SAVEREFERENCE;Saglabāt atsauces attēlu profila izveidei +TP_ICM_WORKINGPROFILE;Darba profils +TP_RAW_DMETHOD;Metode +TP_RAW_FALSECOLOR;Neīsto krāsu slāpēšanas soļi +TP_RESIZE_H;A: +TP_RESIZE_LABEL;Izmērmaiņa +TP_RESIZE_METHOD;Metode: +TP_RESIZE_NEAREST;Tuvākais +TP_RESIZE_SCALE;Mērogs +TP_RESIZE_W;P: +TP_ROTATE_DEGREE;Grādi +TP_ROTATE_LABEL;Pagriezt +TP_ROTATE_SELECTLINE; Norādīt līmeni +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Izgaismojumi +TP_SHADOWSHLIGHTS_HLTONALW;Toņa platums +TP_SHADOWSHLIGHTS_LABEL;Ēnas/Izgaismojumi +TP_SHADOWSHLIGHTS_LOCALCONTR;Vietējais kontrasts +TP_SHADOWSHLIGHTS_RADIUS;Radiuss +TP_SHADOWSHLIGHTS_SHADOWS;Ēnas +TP_SHADOWSHLIGHTS_SHTONALW;Toņa platums +TP_SHARPENING_AMOUNT;Apjoms +TP_SHARPENING_EDRADIUS;Radiuss +TP_SHARPENING_EDTOLERANCE;Iecietība pret malām +TP_SHARPENING_HALOCONTROL;Caurumu kontole +TP_SHARPENING_HCAMOUNT;Apjoms +TP_SHARPENING_LABEL;Asināšana +TP_SHARPENING_METHOD;Metode +TP_SHARPENING_ONLYEDGES;Asināt tikai malas +TP_SHARPENING_RADIUS;Radiuss +TP_SHARPENING_RLD;RL atritināšana +TP_SHARPENING_RLD_AMOUNT;Apjoms +TP_SHARPENING_RLD_DAMPING;Slāpēšana +TP_SHARPENING_RLD_ITERATIONS;Soļi +TP_SHARPENING_THRESHOLD;Slieksnis +TP_SHARPENING_USM;Neasā maska +TP_VIGNETTING_AMOUNT;Apjoms +TP_VIGNETTING_LABEL;Vinjetes Labošana +TP_VIGNETTING_RADIUS;Radiuss +TP_WBALANCE_AUTO;Auto +TP_WBALANCE_CAMERA;Kamera +TP_WBALANCE_CUSTOM;Pielāgots +TP_WBALANCE_GREEN;Nokrāsa +TP_WBALANCE_LABEL;Baltā līdzsvars +TP_WBALANCE_METHOD;Metode +TP_WBALANCE_SIZE;izmērs: +TP_WBALANCE_SPOTWB;Punkta BL +TP_WBALANCE_TEMPERATURE;Temperatūra +# + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!ABOUT_TAB_BUILD;Version +!ABOUT_TAB_CREDITS;Credits +!ABOUT_TAB_LICENSE;License +!ABOUT_TAB_RELEASENOTES;Release Notes +!ABOUT_TAB_SPLASH;Splash +!BATCHQUEUE_AUTOSTART;Auto-start +!BATCHQUEUE_DESTFILENAME;Path and file name +!BATCH_PROCESSING;Batch Processing +!CURVEEDITOR_AXIS_IN;I: +!CURVEEDITOR_AXIS_LEFT_TAN;LT: +!CURVEEDITOR_AXIS_OUT;O: +!CURVEEDITOR_AXIS_RIGHT_TAN;RT: +!CURVEEDITOR_CURVES;Curves +!CURVEEDITOR_CURVE;Curve +!CURVEEDITOR_CUSTOM;Custom +!CURVEEDITOR_DARKS;Darks +!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_HIGHLIGHTS;Highlights +!CURVEEDITOR_LIGHTS;Lights +!CURVEEDITOR_MINMAXCPOINTS;Equalizer +!CURVEEDITOR_NURBS;Control cage +!CURVEEDITOR_PARAMETRIC;Parametric +!CURVEEDITOR_SHADOWS;Shadows +!CURVEEDITOR_TOOLTIPCOPY;Copy current curve to clipboard. +!CURVEEDITOR_TOOLTIPPASTE;Paste curve from clipboard. +!CURVEEDITOR_TYPE;Type: +!EDITWINDOW_TITLE;Image Edit +!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_FILETYPE;File type +!EXIFFILTER_METADATAFILTER;Enable metadata filters +!EXPORT_BYPASS_ALL;Select / Unselect All +!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_FF;Bypass [raw] Flat-Field +!EXPORT_BYPASS_RAW_GREENTHRESH;Bypass [raw] Green Equilibration +!EXPORT_BYPASS_RAW_LINENOISE;Bypass [raw] Line Noise Filter +!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_FASTEXPORTOPTIONS;Fast Export Options +!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_MAXHEIGHT;Maximum height: +!EXPORT_MAXWIDTH;Maximum width: +!EXPORT_PUTTOQUEUEFAST; Put to queue for fast export +!EXPORT_RAW_DMETHOD;Demosaic method +!EXTPROGTARGET_1;raw +!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_CACHECLEARFROMFULL;Clear from cache - full +!FILEBROWSER_CACHECLEARFROMPARTIAL;Clear from cache - partial +!FILEBROWSER_CACHE;Cache +!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_CURRENT_NAME;Current name: +!FILEBROWSER_DARKFRAME;Dark-frame +!FILEBROWSER_DELETEDLGMSGINCLPROC;Are you sure you want to delete the selected %1 files including a queue-processed version? +!FILEBROWSER_EXEC_CPB;Custom Profile Builder +!FILEBROWSER_EXTPROGMENU;Open with +!FILEBROWSER_FLATFIELD;Flat-Field +!FILEBROWSER_MOVETODARKFDIR;Move to dark-frames directory +!FILEBROWSER_MOVETOFLATFIELDDIR;Move to flat-fields directory +!FILEBROWSER_NEW_NAME;New name: +!FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) +!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_POPUPCOLORLABEL;Color label +!FILEBROWSER_POPUPCOPYTO;Copy to... +!FILEBROWSER_POPUPFILEOPERATIONS;File operations +!FILEBROWSER_POPUPMOVETO;Move to... +!FILEBROWSER_POPUPPROCESSFAST;Put to queue (Fast export) +!FILEBROWSER_POPUPPROFILEOPERATIONS;Processing profile operations +!FILEBROWSER_POPUPRANK0;Unrank +!FILEBROWSER_POPUPRANK1;Rank 1 * +!FILEBROWSER_POPUPRANK2;Rank 2 ** +!FILEBROWSER_POPUPRANK3;Rank 3 *** +!FILEBROWSER_POPUPRANK4;Rank 4 **** +!FILEBROWSER_POPUPRANK5;Rank 5 ***** +!FILEBROWSER_POPUPRANK;Rank +!FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!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_QUERYLABEL; Find: +!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_SELECTDARKFRAME;Select dark-frame... +!FILEBROWSER_SELECTFLATFIELD;Select flat-field... +!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 +!FILEBROWSER_SHOWCOLORLABEL4HINT;Show images labeled Blue.\nShortcut: Alt-4 +!FILEBROWSER_SHOWCOLORLABEL5HINT;Show images labeled Purple.\nShortcut: Alt-5 +!FILEBROWSER_SHOWEDITEDHINT;Show edited images.\nShortcut: 7 +!FILEBROWSER_SHOWEDITEDNOTHINT;Show not edited images.\nShortcut: 6 +!FILEBROWSER_SHOWEXIFINFO;Show Exif info.\n\nShortcuts:\ni - Multiple Editor Tabs Mode,\nAlt-i - Single Editor Tab Mode. +!FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!FILEBROWSER_SHOWRECENTLYSAVEDHINT;Show saved images.\nShortcut: Alt-7 +!FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show unsaved images.\nShortcut: Alt-6 +!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_AFTER;After +!GENERAL_ASIMAGE;As Image +!GENERAL_AUTO;Automatic +!GENERAL_BEFORE;Before +!GENERAL_CLOSE;Close +!GENERAL_FILE;File +!GENERAL_NONE;None +!GENERAL_UNCHANGED;(Unchanged) +!GENERAL_WARNING;Warning +!HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar.\nRight-click on image preview to freeze/unfreeze. +!HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram. +!HISTOGRAM_TOOLTIP_FULL;Toggle full (off) or scaled (on) histogram. +!HISTOGRAM_TOOLTIP_RAW;Show/Hide raw histogram. +!HISTORY_MSG_82;Profile changed +!HISTORY_MSG_83;S/H - Sharp mask +!HISTORY_MSG_84;Perspective correction +!HISTORY_MSG_85;LCP +!HISTORY_MSG_86;RGB curves - Luminosity mode +!HISTORY_MSG_87;Impulse noise reduction +!HISTORY_MSG_88;Impulse NR threshold +!HISTORY_MSG_89;Noise Reduction +!HISTORY_MSG_90;NR - Luminance +!HISTORY_MSG_91;NR - Chrominance master +!HISTORY_MSG_92;NR - Gamma +!HISTORY_MSG_93;CbDL - Value +!HISTORY_MSG_94;Contrast by Detail Levels +!HISTORY_MSG_95;L*a*b* - Chromaticity +!HISTORY_MSG_96;L*a*b* - a* curve +!HISTORY_MSG_97;L*a*b* - b* curve +!HISTORY_MSG_98;Demosaicing method +!HISTORY_MSG_99;Hot pixel filter +!HISTORY_MSG_100;RGB Saturation +!HISTORY_MSG_101;HSV - Hue +!HISTORY_MSG_102;HSV - Saturation +!HISTORY_MSG_103;HSV - Value +!HISTORY_MSG_104;HSV Equalizer +!HISTORY_MSG_105;Defringe +!HISTORY_MSG_106;Defringe - Radius +!HISTORY_MSG_107;Defringe - Threshold +!HISTORY_MSG_108;Highlight Compr. Threshold +!HISTORY_MSG_109;Resize - Bounding box +!HISTORY_MSG_110;Resize - Applies to +!HISTORY_MSG_111;L*a*b* - Avoid color shift +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;L*a*b* - Red/skin prot. +!HISTORY_MSG_114;DCB iterations +!HISTORY_MSG_115;False color suppression +!HISTORY_MSG_116;DCB enhancement +!HISTORY_MSG_117;Raw CA correction - Red +!HISTORY_MSG_118;Raw CA correction - Blue +!HISTORY_MSG_119;Line noise filter +!HISTORY_MSG_120;Green equilibration +!HISTORY_MSG_121;Raw CA Correction - Auto +!HISTORY_MSG_122;Dark-Frame - Auto-selection +!HISTORY_MSG_123;Dark-Frame - File +!HISTORY_MSG_124;White point correction +!HISTORY_MSG_125;Highlight preservation +!HISTORY_MSG_126;Flat-Field - File +!HISTORY_MSG_127;Flat-Field - Auto-selection +!HISTORY_MSG_128;Flat-Field - Blur radius +!HISTORY_MSG_129;Flat-Field - Blur type +!HISTORY_MSG_130;Auto distorion correction +!HISTORY_MSG_131;NR - Luma +!HISTORY_MSG_132;NR - Chroma +!HISTORY_MSG_133;Output gamma +!HISTORY_MSG_134;Free gamma +!HISTORY_MSG_135;Free gamma +!HISTORY_MSG_136;Free gamma slope +!HISTORY_MSG_137;Black level - Green 1 +!HISTORY_MSG_138;Black level - Red +!HISTORY_MSG_139;Black level - Blue +!HISTORY_MSG_140;Black level - Green 2 +!HISTORY_MSG_141;Black level - Link greens +!HISTORY_MSG_142;ES - Iterations +!HISTORY_MSG_143;ES - Quantity +!HISTORY_MSG_144;Microcontrast - Quantity +!HISTORY_MSG_145;Microcontrast - Uniformity +!HISTORY_MSG_146;Edge sharpening +!HISTORY_MSG_147;ES - Luminance only +!HISTORY_MSG_148;Microcontrast +!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_150;Post-demosaic artifact/noise red. +!HISTORY_MSG_151;Vibrance +!HISTORY_MSG_152;Vib - Pastel tones +!HISTORY_MSG_153;Vib - Saturated tones +!HISTORY_MSG_154;Vib - Protect skin-tones +!HISTORY_MSG_155;Vib - Avoid color shift +!HISTORY_MSG_156;Vib - Link pastel/saturated +!HISTORY_MSG_157;Vib - P/S threshold +!HISTORY_MSG_158;TM - Strength +!HISTORY_MSG_159;TM - Edge stopping +!HISTORY_MSG_160;TM - Scale +!HISTORY_MSG_161;TM - Reweighting iterates +!HISTORY_MSG_162;Tone Mapping +!HISTORY_MSG_163;RGB curves - Red +!HISTORY_MSG_164;RGB curves - Green +!HISTORY_MSG_165;RGB curves - Blue +!HISTORY_MSG_166;Neutral levels +!HISTORY_MSG_167;--unused-- +!HISTORY_MSG_168;L*a*b* - CC curve +!HISTORY_MSG_169;L*a*b* - CH curve +!HISTORY_MSG_170;Vibrance - HH curve +!HISTORY_MSG_171;L*a*b* - LC curve +!HISTORY_MSG_172;L*a*b* - Restrict LC +!HISTORY_MSG_173;NR - Luminance detail +!HISTORY_MSG_174;CIECAM02 +!HISTORY_MSG_175;CAM02 - CAT02 adaptation +!HISTORY_MSG_176;CAM02 - Viewing surround +!HISTORY_MSG_177;CAM02 - Scene luminosity +!HISTORY_MSG_178;CAM02 - Viewing luminosity +!HISTORY_MSG_179;CAM02 - White-point model +!HISTORY_MSG_180;CAM02 - Lightness (J) +!HISTORY_MSG_181;CAM02 - Chroma (C) +!HISTORY_MSG_182;CAM02 - Automatic CAT02 +!HISTORY_MSG_183;CAM02 - Contrast (J) +!HISTORY_MSG_184;CAM02 - Scene surround +!HISTORY_MSG_185;CAM02 - Gamut control +!HISTORY_MSG_186;CAM02 - Algorithm +!HISTORY_MSG_187;CAM02 - Red/skin prot. +!HISTORY_MSG_188;CAM02 - Brightness (Q) +!HISTORY_MSG_189;CAM02 - Contrast (Q) +!HISTORY_MSG_190;CAM02 - Saturation (S) +!HISTORY_MSG_191;CAM02 - Colorfulness (M) +!HISTORY_MSG_192;CAM02 - Hue (h) +!HISTORY_MSG_193;CAM02 - Tone curve 1 +!HISTORY_MSG_194;CAM02 - Tone curve 2 +!HISTORY_MSG_195;CAM02 - Tone curve 1 +!HISTORY_MSG_196;CAM02 - Tone curve 2 +!HISTORY_MSG_197;CAM02 - Color curve +!HISTORY_MSG_198;CAM02 - Color curve +!HISTORY_MSG_199;CAM02 - Output histograms +!HISTORY_MSG_200;CAM02 - Tone mapping +!HISTORY_MSG_201;NR - Chrominance - R&G +!HISTORY_MSG_202;NR - Chrominance - B&Y +!HISTORY_MSG_203;NR - Method +!HISTORY_MSG_204;LMMSE enhancement steps +!HISTORY_MSG_205;CAM02 - Hot/bad pixel filter +!HISTORY_MSG_206;CAT02 - Auto scene luminosity +!HISTORY_MSG_207;Defringe - Hue curve +!HISTORY_MSG_208;WB - B/R equalizer +!HISTORY_MSG_210;GF - Angle +!HISTORY_MSG_211;Graduated Filter +!HISTORY_MSG_212;VF - Strength +!HISTORY_MSG_213;Vignette Filter +!HISTORY_MSG_214;Black-and-White +!HISTORY_MSG_215;B&W - CM - Red +!HISTORY_MSG_216;B&W - CM - Green +!HISTORY_MSG_217;B&W - CM - Blue +!HISTORY_MSG_218;B&W - Gamma - Red +!HISTORY_MSG_219;B&W - Gamma - Green +!HISTORY_MSG_220;B&W - Gamma - Blue +!HISTORY_MSG_221;B&W - Color filter +!HISTORY_MSG_222;B&W - Presets +!HISTORY_MSG_223;B&W - CM - Orange +!HISTORY_MSG_224;B&W - CM - Yellow +!HISTORY_MSG_225;B&W - CM - Cyan +!HISTORY_MSG_226;B&W - CM - Magenta +!HISTORY_MSG_227;B&W - CM - Purple +!HISTORY_MSG_228;B&W - Luminance equalizer +!HISTORY_MSG_229;B&W - Luminance equalizer +!HISTORY_MSG_230;B&W - Mode +!HISTORY_MSG_231;B&W - 'Before' curve +!HISTORY_MSG_232;B&W - 'Before' curve type +!HISTORY_MSG_233;B&W - 'After' curve +!HISTORY_MSG_234;B&W - 'After' curve type +!HISTORY_MSG_235;B&W - Auto channel mixer +!HISTORY_MSG_236;--unused-- +!HISTORY_MSG_237;B&W - Mixer +!HISTORY_MSG_238;GF - Feather +!HISTORY_MSG_239;GF - Strength +!HISTORY_MSG_240;GF - Center +!HISTORY_MSG_241;VF - Feather +!HISTORY_MSG_242;VF - Roundness +!HISTORY_MSG_243;VC - Radius +!HISTORY_MSG_244;VC - Strength +!HISTORY_MSG_245;VC - Center +!HISTORY_MSG_246;L*a*b* - CL curve +!HISTORY_MSG_247;L*a*b* - LH curve +!HISTORY_MSG_248;L*a*b* - HH curve +!HISTORY_MSG_249;CbDL - Threshold +!HISTORY_MSG_250;NR - Enhanced +!HISTORY_MSG_251;B&W - Algorithm +!HISTORY_MSG_252;CbDL - Skin tar/prot +!HISTORY_MSG_253;CbDL - Reduce artifacts +!HISTORY_MSG_254;CbDL - Skin hue +!HISTORY_MSG_255;NR - Median filter +!HISTORY_MSG_256;NR - Median type +!HISTORY_MSG_257;Color Toning +!HISTORY_MSG_258;CT - Color curve +!HISTORY_MSG_259;CT - Opacity curve +!HISTORY_MSG_260;CT - a*[b*] opacity +!HISTORY_MSG_261;CT - Method +!HISTORY_MSG_262;CT - b* opacity +!HISTORY_MSG_263;CT - Shadows - Red +!HISTORY_MSG_264;CT - Shadows - Green +!HISTORY_MSG_265;CT - Shadows - Blue +!HISTORY_MSG_266;CT - Mid - Red +!HISTORY_MSG_267;CT - Mid - Green +!HISTORY_MSG_268;CT - Mid - Blue +!HISTORY_MSG_269;CT - High - Red +!HISTORY_MSG_270;CT - High - Green +!HISTORY_MSG_271;CT - High - Blue +!HISTORY_MSG_272;CT - Balance +!HISTORY_MSG_273;CT - Reset +!HISTORY_MSG_274;CT - Sat. Shadows +!HISTORY_MSG_275;CT - Sat. Highlights +!HISTORY_MSG_276;CT - Opacity +!HISTORY_MSG_277;--unused-- +!HISTORY_MSG_278;CT - Preserve luminance +!HISTORY_MSG_279;CT - Shadows +!HISTORY_MSG_280;CT - Highlights +!HISTORY_MSG_281;CT - Sat. strength +!HISTORY_MSG_282;CT - Sat. threshold +!HISTORY_MSG_283;CT - Strength +!HISTORY_MSG_284;CT - Auto sat. protection +!HISTORY_MSG_285;NR - Median - Method +!HISTORY_MSG_286;NR - Median - Type +!HISTORY_MSG_287;NR - Median - Iterations +!HISTORY_MSG_288;Flat Field - Clip control +!HISTORY_MSG_289;Flat Field - Clip control - Auto +!HISTORY_MSG_290;Black Level - Red +!HISTORY_MSG_291;Black Level - Green +!HISTORY_MSG_292;Black Level - Blue +!HISTORY_MSG_293;Film Simulation +!HISTORY_MSG_294;Film Simulation - Strength +!HISTORY_MSG_295;Film Simulation - Film +!HISTORY_MSG_296;NR - Luminance curve +!HISTORY_MSG_297;NR - Quality +!HISTORY_MSG_298;Dead pixel filter +!HISTORY_MSG_299;NR - Chrominance curve +!HISTORY_MSG_300;- +!HISTORY_MSG_301;NR - Luma control +!HISTORY_MSG_302;NR - Chroma method +!HISTORY_MSG_303;NR - Chroma method +!HISTORY_MSG_304;W - Contrast levels +!HISTORY_MSG_305;Wavelet Levels +!HISTORY_MSG_306;W - Preview +!HISTORY_MSG_307;W - Preview +!HISTORY_MSG_308;W - Preview direction +!HISTORY_MSG_309;W - ES - Detail +!HISTORY_MSG_310;W - Residual - Sky tar/prot +!HISTORY_MSG_311;W - Wavelet levels +!HISTORY_MSG_312;W - Residual - Shadows threshold +!HISTORY_MSG_313;W - Chroma - Sat/past +!HISTORY_MSG_314;W - Gamut - Reduce artifacts +!HISTORY_MSG_315;W - Residual - Contrast +!HISTORY_MSG_316;W - Gamut - Skin tar/prot +!HISTORY_MSG_317;W - Gamut - Skin hue +!HISTORY_MSG_318;W - Contrast - Highlight levels +!HISTORY_MSG_319;W - Contrast - Highlight range +!HISTORY_MSG_320;W - Contrast - Shadow range +!HISTORY_MSG_321;W - Contrast - Shadow levels +!HISTORY_MSG_322;W - Gamut - Avoid color shift +!HISTORY_MSG_323;W - ES - Local contrast +!HISTORY_MSG_324;W - Chroma - Pastel +!HISTORY_MSG_325;W - Chroma - Saturated +!HISTORY_MSG_326;W - Chroma - Method +!HISTORY_MSG_327;W - Contrast - Apply to +!HISTORY_MSG_328;W - Chroma - Link strength +!HISTORY_MSG_329;W - Toning - Opacity RG +!HISTORY_MSG_330;W - Toning - Opacity BY +!HISTORY_MSG_331;W - Contrast levels - Extra +!HISTORY_MSG_332;W - Tiling method +!HISTORY_MSG_333;W - Residual - Shadows +!HISTORY_MSG_334;W - Residual - Chroma +!HISTORY_MSG_335;W - Residual - Highlights +!HISTORY_MSG_336;W - Residual - Highlights threshold +!HISTORY_MSG_337;W - Residual - Sky hue +!HISTORY_MSG_338;W - ES - Radius +!HISTORY_MSG_339;W - ES - Strength +!HISTORY_MSG_340;W - Strength +!HISTORY_MSG_341;W - Edge performance +!HISTORY_MSG_342;W - ES - First level +!HISTORY_MSG_343;W - Chroma levels +!HISTORY_MSG_344;W - Meth chroma sl/cur +!HISTORY_MSG_345;W - ES - Local contrast +!HISTORY_MSG_346;W - ES - Local contrast method +!HISTORY_MSG_347;W - Denoise - Level 0 +!HISTORY_MSG_348;W - Denoise - Level 1 +!HISTORY_MSG_349;W - Denoise - Level 2 +!HISTORY_MSG_350;W - ES - Edge detection +!HISTORY_MSG_351;W - Residual - HH curve +!HISTORY_MSG_352;W - Background +!HISTORY_MSG_353;W - ES - Gradient sensitivity +!HISTORY_MSG_354;W - ES - Enhance +!HISTORY_MSG_355;W - ES - Threshold low +!HISTORY_MSG_356;W - ES - Threshold high +!HISTORY_MSG_357;W - Denoise - Link with ES +!HISTORY_MSG_358;W - Gamut - CH +!HISTORY_MSG_359;Hot/Dead - Threshold +!HISTORY_MSG_360;TM Gamma +!HISTORY_MSG_361;W - Final - Chroma balance +!HISTORY_MSG_362;W - Residual - Compression method +!HISTORY_MSG_363;W - Residual - Compression strength +!HISTORY_MSG_364;W - Final - Contrast balance +!HISTORY_MSG_365;W - Final - Delta balance +!HISTORY_MSG_366;W - Residual - Compression gamma +!HISTORY_MSG_367;W - ES - Local contrast curve +!HISTORY_MSG_368;W - Final - Contrast balance +!HISTORY_MSG_369;W - Final - Balance method +!HISTORY_MSG_370;W - Final - Local contrast curve +!HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s +!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 +!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). +!MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Put current image to processing queue.\nShortcut: Ctrl+b +!MAIN_BUTTON_SAVE_TOOLTIP;Save current image.\nShortcut: Ctrl+s +!MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Edit current image in external editor.\nShortcut: Ctrl+e +!MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Show/hide all side panels.\nShortcut: m +!MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen +!MAIN_FRAME_BATCHQUEUE_TOOLTIP;Processing queue.\nShortcut: Ctrl-F3 +!MAIN_FRAME_EDITOR;Editor +!MAIN_FRAME_EDITOR_TOOLTIP;Editor.\nShortcut: Ctrl-F4 +!MAIN_FRAME_FILEBROWSER_TOOLTIP;File browser.\nShortcut: Ctrl-F2 +!MAIN_MSG_EMPTYFILENAME;Filename unspecified! +!MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue-processed first. +!MAIN_MSG_NAVIGATOR;Navigator +!MAIN_MSG_OPERATIONCANCELLED;Operation cancelled +!MAIN_MSG_PATHDOESNTEXIST;The path\n\n%1\n\ndoes not exist. Please set a correct path in Preferences. +!MAIN_MSG_SETPATHFIRST;You first have to set a target path in Preferences in order to use this function! +!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_EXPORT; Fast Export +!MAIN_TAB_EXPOSURE_TOOLTIP;Shortcut: Alt-e +!MAIN_TAB_INSPECT; Inspect +!MAIN_TAB_METADATA_TOOLTIP;Shortcut: Alt-m +!MAIN_TAB_RAW;Raw +!MAIN_TAB_RAW_TOOLTIP;Shortcut: Alt-r +!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_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%. +!MAIN_TOOLTIP_PREVIEWG;Preview the Green channel.\nShortcut: g +!MAIN_TOOLTIP_PREVIEWL;Preview the Luminosity.\nShortcut: v\n\n0.299*R + 0.587*G + 0.114*B +!MAIN_TOOLTIP_PREVIEWR;Preview the Red channel.\nShortcut: r +!MAIN_TOOLTIP_SHOWHIDELP1;Show/Hide the left panel.\nShortcut: l +!MAIN_TOOLTIP_SHOWHIDERP1;Show/Hide the right panel.\nShortcut: Alt-l +!MAIN_TOOLTIP_SHOWHIDETP1;Show/Hide the top panel.\nShortcut: Shift-l +!MAIN_TOOLTIP_THRESHOLD;Threshold +!MAIN_TOOLTIP_TOGGLE;Toggle the Before/After view.\nShortcut: Shift-b +!NAVIGATOR_B;B: +!NAVIGATOR_G;G: +!NAVIGATOR_H;H: +!NAVIGATOR_LAB_A;a*: +!NAVIGATOR_LAB_B;b*: +!NAVIGATOR_LAB_L;L*: +!NAVIGATOR_NA; -- +!NAVIGATOR_R;R: +!NAVIGATOR_S;S: +!NAVIGATOR_V;V: +!NAVIGATOR_XY_FULL;Width: %1, Height: %2 +!NAVIGATOR_XY_NA;x: --, y: -- +!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_CHANNELMIXERBW;Black-and-White +!PARTIALPASTE_CHANNELMIXER;Channel mixer +!PARTIALPASTE_COLORAPP;CIECAM02 +!PARTIALPASTE_COLORTONING;Color Toning +!PARTIALPASTE_COMMONTRANSFORMPARAMS;Auto-fill +!PARTIALPASTE_DARKFRAMEAUTOSELECT;Dark-frame auto-selection +!PARTIALPASTE_DARKFRAMEFILE;Dark-frame file +!PARTIALPASTE_DEFRINGE;Defringe +!PARTIALPASTE_DETAILGROUP;Detail Settings +!PARTIALPASTE_DIRPYRDENOISE;Noise reduction +!PARTIALPASTE_DIRPYREQUALIZER;Contrast by detail levels +!PARTIALPASTE_EPD;Tone mapping +!PARTIALPASTE_EQUALIZER;Wavelet Equalizer +!PARTIALPASTE_EVERYTHING;Everything +!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_GRADIENT;Graduated filter +!PARTIALPASTE_HSVEQUALIZER;HSV equalizer +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction +!PARTIALPASTE_LABCURVE;L*a*b* adjustments +!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_PCVIGNETTE;Vignette filter +!PARTIALPASTE_PERSPECTIVE;Perspective +!PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter +!PARTIALPASTE_PREPROCESS_GREENEQUIL;Green equilibration +!PARTIALPASTE_PREPROCESS_HOTPIXFILT;Hot pixel filter +!PARTIALPASTE_PREPROCESS_LINEDENOISE;Line noise filter +!PARTIALPASTE_RAWCACORR_AUTO;CA auto-correction +!PARTIALPASTE_RAWCACORR_CABLUE;CA blue +!PARTIALPASTE_RAWCACORR_CARED;CA red +!PARTIALPASTE_RAWEXPOS_BLACK;Black levels +!PARTIALPASTE_RAWEXPOS_LINEAR;White point correction +!PARTIALPASTE_RAWEXPOS_PRESER;Highlight preservation +!PARTIALPASTE_RAWGROUP;Raw Settings +!PARTIALPASTE_RAW_DCBENHANCE;DCB enhancement +!PARTIALPASTE_RAW_DCBITERATIONS;Number of DCB iterations +!PARTIALPASTE_RAW_DMETHOD;Demosaic method +!PARTIALPASTE_RAW_FALSECOLOR;Demosaic false color suppression steps +!PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!PARTIALPASTE_RGBCURVES;RGB curves +!PARTIALPASTE_SHARPENEDGE;Edges +!PARTIALPASTE_SHARPENMICRO;Microcontrast +!PARTIALPASTE_VIBRANCE;Vibrance +!PARTIALPASTE_WAVELETGROUP;Wavelet processing +!PREFERENCES_ADD;Add +!PREFERENCES_AUTLISLOW;Low +!PREFERENCES_AUTLISMAX;Max - Average of all tiles +!PREFERENCES_AUTLISSTD;High +!PREFERENCES_AUTLISVLOW;None +!PREFERENCES_AUTLOW;Low +!PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +!PREFERENCES_AUTSTD;Standard +!PREFERENCES_BATCH_PROCESSING;Batch Processing +!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_BEHADDALL;All to 'Add' +!PREFERENCES_BEHAVIOR;Behavior +!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_BEHSETALL;All to 'Set' +!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_CURVEBBOXPOS;Position of curve copypasta buttons +!PREFERENCES_CURVEBBOXPOS_ABOVE;Above +!PREFERENCES_CURVEBBOXPOS_BELOW;Below +!PREFERENCES_CURVEBBOXPOS_LEFT;Left +!PREFERENCES_CURVEBBOXPOS_RIGHT;Right +!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_CUSTPROFBUILD;Custom Processing Profile Builder +!PREFERENCES_CUTOVERLAYBRUSH;Crop mask color/transparency +!PREFERENCES_D50;5000K +!PREFERENCES_D55;5500K +!PREFERENCES_D60;6000K +!PREFERENCES_D65;6500K +!PREFERENCES_DARKFRAMEFOUND;Found +!PREFERENCES_DARKFRAMESHOTS;shots +!PREFERENCES_DARKFRAMETEMPLATES;templates +!PREFERENCES_DARKFRAME;Dark-Frame +!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 (de-select for low resolution display) +!PREFERENCES_FILMSIMULATION;Film Simulation +!PREFERENCES_FLATFIELDFOUND;Found +!PREFERENCES_FLATFIELDSDIR;Flat-fields directory +!PREFERENCES_FLATFIELDSHOTS;shots +!PREFERENCES_FLATFIELDTEMPLATES;templates +!PREFERENCES_FLATFIELD;Flat-Field +!PREFERENCES_FLUOF2;Fluorescent F2 +!PREFERENCES_FLUOF7;Fluorescent F7 +!PREFERENCES_FLUOF11;Fluorescent F11 +!PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT;Same thumbnail height between the Editor's panel 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_GREY05;Yb=05 CIE L#30 +!PREFERENCES_GREY10;Yb=10 CIE L#40 +!PREFERENCES_GREY15;Yb=15 CIE L#45 +!PREFERENCES_GREY18;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_GREYSC18;Yb=18 CIE L#50 +!PREFERENCES_GREYSCA;Automatic +!PREFERENCES_GREYSC;Scene Yb luminance (%) +!PREFERENCES_GREY;Output device's Yb luminance (%) +!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_LANGAUTODETECT;Use system language +!PREFERENCES_LEVAUTDN;Denoising level +!PREFERENCES_LEVDN;Cell size +!PREFERENCES_LISS;Auto multi-zone smoothing +!PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders +!PREFERENCES_MAX;Maxi (Tile) +!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_MENUGROUPRANK;Group "Rank" +!PREFERENCES_MENUOPTIONS;Context Menu Options +!PREFERENCES_METADATA;Metadata +!PREFERENCES_MIN;Mini (100x115) +!PREFERENCES_MULTITABDUALMON;Multiple Editor Tabs In Own Window Mode +!PREFERENCES_MULTITAB;Multiple Editor Tabs 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_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_PROPERTY;Property +!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 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_SINGLETABVERTAB;Single Editor Tab Mode, Vertical Tabs +!PREFERENCES_SINGLETAB;Single Editor Tab Mode +!PREFERENCES_SLIMUI;Slim interface +!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_PERFORMANCE;Performance & Quality +!PREFERENCES_TAB_SOUND;Sounds +!PREFERENCES_TIMAX;High +!PREFERENCES_TINB;Number of tiles +!PREFERENCES_TISTD;Standard +!PREFERENCES_TP_LABEL;Tool panel: +!PREFERENCES_TP_USEICONORTEXT;Use tab icons instead of text +!PREFERENCES_TP_VSCROLLBAR;Hide vertical scrollbar +!PREFERENCES_TUNNELMETADATA;Copy IPTC/XMP unchanged to output file (when tagging with other program) +!PREFERENCES_USEBUNDLEDPROFILES;Use bundled profiles +!PREFERENCES_USESYSTEMTHEME;Use system theme +!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_WORKFLOW;Layout +!PROFILEPANEL_COPYPPASTE;Parameters to copy +!PROFILEPANEL_GLOBALPROFILES;Bundled profiles +!PROFILEPANEL_LOADPPASTE;Parameters to load +!PROFILEPANEL_MODE_TIP;Processing profile fill mode.\n\nButton pressed: partial profiles will be converted to full profiles; the missing values will be replaced with hard-coded defaults.\n\nButton released: profiles will be applied as they are, altering only those values which they contain. +!PROFILEPANEL_MYPROFILES;My profiles +!PROFILEPANEL_PASTEPPASTE;Parameters to paste +!PROFILEPANEL_PINTERNAL;Neutral +!PROFILEPANEL_SAVEPPASTE;Parameters to save +!PROGRESSBAR_LOADINGTHUMBS;Loading thumbnails... +!PROGRESSBAR_NOIMAGES;No images found +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing profile saved +!PROGRESSBAR_SNAPSHOT_ADDED;Snapshot added +!PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists +!SAVEDLG_FORCEFORMATOPTS;Force saving options +!SAVEDLG_SUBSAMP;Subsampling +!SAVEDLG_SUBSAMP_1;Best compression +!SAVEDLG_SUBSAMP_2;Balanced +!SAVEDLG_SUBSAMP_3;Best quality +!SAVEDLG_SUBSAMP_TOOLTIP;Best compression: 4:1:1\nBalanced: 4:2:2\nBest quality: 4:4:4 +!SAVEDLG_TIFFUNCOMPRESSED;Uncompressed TIFF +!SAVEDLG_WARNFILENAME;File will be named +!SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. +!THRESHOLDSELECTOR_BL;Bottom-left +!THRESHOLDSELECTOR_BR;Bottom-right +!THRESHOLDSELECTOR_B;Bottom +!THRESHOLDSELECTOR_HINT;Hold the Shift key to move individual control points. +!THRESHOLDSELECTOR_TL;Top-left +!THRESHOLDSELECTOR_TR;Top-right +!THRESHOLDSELECTOR_T;Top +!TP_BWMIX_ALGO;Algorithm OYCPM +!TP_BWMIX_ALGO_LI;Linear +!TP_BWMIX_ALGO_SP;Special effects +!TP_BWMIX_ALGO_TOOLTIP;Linear: will produce a normal linear response.\nSpecial effects: will produce special effects by mixing channels non-linearly. +!TP_BWMIX_AUTOCH;Auto +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing Channel Mixer. +!TP_BWMIX_CC_ENABLED;Adjust complementary color +!TP_BWMIX_CC_TOOLTIP;Enable to allow automatic adjustment of complementary colors in ROYGCBPM mode. +!TP_BWMIX_CHANNEL;Luminance equalizer +!TP_BWMIX_CURVEEDITOR1;'Before' curve +!TP_BWMIX_CURVEEDITOR2;'After' curve +!TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Tone curve, after B&W conversion, at the end of treatment. +!TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Tone curve, just before B&W conversion.\nMay take into account the color components. +!TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H).\nPay attention to extreme values as they may cause artifacts. +!TP_BWMIX_FILTER;Color Filter +!TP_BWMIX_FILTER_BLUEGREEN;Blue-Green +!TP_BWMIX_FILTER_BLUE;Blue +!TP_BWMIX_FILTER_GREENYELLOW;Green-Yellow +!TP_BWMIX_FILTER_GREEN;Green +!TP_BWMIX_FILTER_NONE;None +!TP_BWMIX_FILTER_PURPLE;Purple +!TP_BWMIX_FILTER_REDYELLOW;Red-Yellow +!TP_BWMIX_FILTER_RED;Red +!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. +!TP_BWMIX_FILTER_YELLOW;Yellow +!TP_BWMIX_GAMMA;Gamma Correction +!TP_BWMIX_GAM_TOOLTIP;Correct gamma for each RGB channel. +!TP_BWMIX_LABEL;Black-and-White +!TP_BWMIX_MET;Method +!TP_BWMIX_MET_CHANMIX;Channel Mixer +!TP_BWMIX_MET_DESAT;Desaturation +!TP_BWMIX_MET_LUMEQUAL;Luminance Equalizer +!TP_BWMIX_MIXC;Mixer +!TP_BWMIX_NEUTRAL;Reset mixer +!TP_BWMIX_NEUTRAL_TIP;Reset all values (Color Filter, Channel Mixer) to default. +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all the mixer options.\n"Total" displays the sum of the RGB values:\n- always 100% in relative mode\n- higher (lighter) or lower (darker) than 100% in absolute mode. +!TP_BWMIX_RGB_TOOLTIP;Mix the RGB channels. Use presets for guidance.\nPay attention to negative values that may cause artifacts or erratic behavior. +!TP_BWMIX_SETTING;Presets +!TP_BWMIX_SETTING_TOOLTIP;Different presets (film, landscape, etc.) or manual Channel Mixer settings. +!TP_BWMIX_SET_HIGHCONTAST;High contrast +!TP_BWMIX_SET_HIGHSENSIT;High Sensitivity +!TP_BWMIX_SET_HYPERPANCHRO;Hyper Panchromatic +!TP_BWMIX_SET_INFRARED;Infrared +!TP_BWMIX_SET_LANDSCAPE;Landscape +!TP_BWMIX_SET_LOWSENSIT;Low Sensitivity +!TP_BWMIX_SET_LUMINANCE;Luminance +!TP_BWMIX_SET_NORMCONTAST;Normal Contrast +!TP_BWMIX_SET_ORTHOCHRO;Orthochromatic +!TP_BWMIX_SET_PANCHRO;Panchromatic +!TP_BWMIX_SET_PORTRAIT;Portrait +!TP_BWMIX_SET_RGBABS;Absolute RGB +!TP_BWMIX_SET_RGBREL;Relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Relative ROYGCBPM +!TP_BWMIX_TCMODE_FILMLIKE;B&W Film-like +!TP_BWMIX_TCMODE_SATANDVALBLENDING;B&W Saturation and Value Blending +!TP_BWMIX_TCMODE_STANDARD;B&W Standard +!TP_BWMIX_TCMODE_WEIGHTEDSTD;B&W Weighted Standard +!TP_BWMIX_VAL;L +!TP_CHROMATABERR_LABEL;Chromatic Aberration +!TP_COLORAPP_ADAPTSCENE;Scene luminosity +!TP_COLORAPP_ADAPTSCENE_TOOLTIP;Absolute luminance of the scene environement (cd/m²).\n1) Calculated from the Exif data:\nShutter speed - ISO speed - F number - camera exposure correction.\n2) Calculated from the raw white point and RT's Exposure Compensation slider. +!TP_COLORAPP_ADAPTVIEWING;Viewing luminosity (cd/m²) +!TP_COLORAPP_ADAPTVIEWING_TOOLTIP;Absolute luminance of the viewing environnement\n(usually 16cd/m²). +!TP_COLORAPP_ADAP_AUTO_TOOLTIP;If the checkbox is checked (recommended) RawTherapee calculates an optimum value from Exif data.\nTo set the value manually, uncheck the checkbox first. +!TP_COLORAPP_ALGO;Algorithm +!TP_COLORAPP_ALGO_ALL;All +!TP_COLORAPP_ALGO_JC;Lightness + Chroma (JC) +!TP_COLORAPP_ALGO_JS;Lightness + Saturation (JS) +!TP_COLORAPP_ALGO_QM;Brightness + Colorfulness (QM) +!TP_COLORAPP_ALGO_TOOLTIP;Lets you choose between parameter subsets or all parameters. +!TP_COLORAPP_BADPIXSL;Hot/bad pixel filter +!TP_COLORAPP_BADPIXSL_TOOLTIP;Suppression of hot/bad (brightly colored) pixels.\n0 = No effect\n1 = Median\n2 = Gaussian.\nAlternatively, adjust the image to avoid very dark shadows.\n\nThese artifacts are due to limitations of CIECAM02. +!TP_COLORAPP_BRIGHT;Brightness (Q) +!TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from L*a*b* and RGB brightness. +!TP_COLORAPP_CHROMA;Chroma (C) +!TP_COLORAPP_CHROMA_M;Colorfulnes (M) +!TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM02 differs from L*a*b* and RGB colorfulness. +!TP_COLORAPP_CHROMA_S;Saturation (S) +!TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from L*a*b* and RGB saturation. +!TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from L*a*b* and RGB chroma. +!TP_COLORAPP_CIECAT_DEGREE;CAT02 adaptation +!TP_COLORAPP_CONTRAST;Contrast (J) +!TP_COLORAPP_CONTRAST_Q;Contrast (Q) +!TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrast in CIECAM02 for the Q slider; it differs from L*a*b* and RGB contrast. +!TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from L*a*b* and RGB contrast. +!TP_COLORAPP_CURVEEDITOR1;Tone curve 1 +!TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L* (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of J or Q after CIECAM02.\n\nJ and Q are not shown in the main histogram panel.\n\nFor final output refer to the main histogram panel. +!TP_COLORAPP_CURVEEDITOR2;Tone curve 2 +!TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Same usage as with the second exposure tone curve. +!TP_COLORAPP_CURVEEDITOR3;Color curve +!TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Adjust either chroma, saturation or colorfulness.\n\nShows the histogram of chromaticity (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of C, s or M after CIECAM02.\n\nC, s and M are not shown in the main histogram panel.\nFor final output refer to the main histogram panel. +!TP_COLORAPP_DATACIE;CIECAM02 output histograms in curves +!TP_COLORAPP_DATACIE_TOOLTIP;When enabled, histograms in CIECAM02 curves show approximate values/ranges for J or Q, and C, s or M after the CIECAM02 adjustments.\nThis selection does not impact the main histogram panel.\n\nWhen disabled, histograms in CIECAM02 curves show L*a*b* values before CIECAM02 adjustments. +!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RawTherapee calculates an optimum value, which is then used by CAT02, and also for the entire CIECAM02.\nTo set the value manually, uncheck the check-box first (values above 65 are recommended). +!TP_COLORAPP_DEGREE_TOOLTIP;Amount of CIE Chromatic Adaptation Transform 2002. +!TP_COLORAPP_GAMUT;Gamut control (L*a*b*) +!TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in L*a*b* mode. +!TP_COLORAPP_HUE;Hue (h) +!TP_COLORAPP_HUE_TOOLTIP;Hue (h) - angle between 0° and 360°. +!TP_COLORAPP_LABEL;CIE Color Appearance Model 2002 +!TP_COLORAPP_LABEL_CAM02;Image Adjustments +!TP_COLORAPP_LABEL_SCENE;Scene Conditions +!TP_COLORAPP_LABEL_VIEWING;Viewing Conditions +!TP_COLORAPP_LIGHT;Lightness (J) +!TP_COLORAPP_LIGHT_TOOLTIP;Lightness in CIECAM02 differs from L*a*b* and RGB lightness. +!TP_COLORAPP_MODEL;WP Model +!TP_COLORAPP_MODEL_TOOLTIP;White-Point Model.\n\nWB [RT] + [output]: RT's white balance is used for the scene, CIECAM02 is set to D50, and the output device's white balance is set in Preferences > Color Management.\n\nWB [RT+CAT02] + [output]: RT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences - Color Management. +!TP_COLORAPP_RSTPRO;Red & skin-tones protection +!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin-tones protection affects both sliders and curves. +!TP_COLORAPP_SHARPCIE;--unused-- +!TP_COLORAPP_SHARPCIE_TOOLTIP;--unused-- +!TP_COLORAPP_SURROUND;Surround +!TP_COLORAPP_SURROUND_AVER;Average +!TP_COLORAPP_SURROUND_DARK;Dark +!TP_COLORAPP_SURROUND_DIM;Dim +!TP_COLORAPP_SURROUND_EXDARK;Extremly Dark (Cutsheet) +!TP_COLORAPP_SURROUND_TOOLTIP;Changes tones and colors to take into account the viewing conditions of the output device.\n\nAverage: Average light environment (standard). The image will not change.\n\nDim: Dim environment (TV). The image will become slighty dark.\n\nDark: Dark environment (projector). The image will become more dark.\n\nExtremly Dark: Extremly dark environment (cutsheet). The image will become very dark. +!TP_COLORAPP_SURSOURCE;Dark surround +!TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if image has a dark border. +!TP_COLORAPP_TCMODE_BRIGHTNESS;Brightness +!TP_COLORAPP_TCMODE_CHROMA;Chroma +!TP_COLORAPP_TCMODE_COLORF;Colorfulness +!TP_COLORAPP_TCMODE_LABEL1;Curve mode 1 +!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_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] +!TP_COLORAPP_WBRT;WB [RT] + [output] +!TP_COLORTONING_AB;o C/L +!TP_COLORTONING_AUTOSAT;Automatic +!TP_COLORTONING_BALANCE;Balance +!TP_COLORTONING_BY;o C/L +!TP_COLORTONING_CHROMAC;Opacity +!TP_COLORTONING_COLOR;Color +!TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;Chroma opacity as a function of luminance oC=f(L) +!TP_COLORTONING_HIGHLIGHT;Highlights +!TP_COLORTONING_HUE;Hue +!TP_COLORTONING_LABEL;Color Toning +!TP_COLORTONING_LAB;L*a*b* blending +!TP_COLORTONING_LUMAMODE;Preserve luminance +!TP_COLORTONING_LUMAMODE_TOOLTIP;If enabled, when you change color (red, green, cyan, blue, etc.) the luminance of each pixel is preserved. +!TP_COLORTONING_LUMA;Luminance +!TP_COLORTONING_METHOD;Method +!TP_COLORTONING_METHOD_TOOLTIP;"L*a*b* blending", "RGB sliders" and "RGB curves" use interpolated color blending.\n"Color balance (Shadows/Midtones/Highlights)" and "Saturation 2 colors" use direct colors.\n\nThe Black-and-White tool can be enabled when using any color toning method, which allows for color toning. +!TP_COLORTONING_MIDTONES;Midtones +!TP_COLORTONING_NEUTRAL;Reset sliders +!TP_COLORTONING_NEUTRAL_TIP;Reset all values (Shadows, Midtones, Highlights) to default. +!TP_COLORTONING_OPACITY;Opacity +!TP_COLORTONING_RGBCURVES;RGB - Curves +!TP_COLORTONING_RGBSLIDERS;RGB - Sliders +!TP_COLORTONING_SATURATEDOPACITY;Strength +!TP_COLORTONING_SATURATIONTHRESHOLD;Threshold +!TP_COLORTONING_SA;Saturation Protection +!TP_COLORTONING_SHADOWS;Shadows +!TP_COLORTONING_SPLITCOCO;Color Balance Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITCO;Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITLR;Saturation 2 colors +!TP_COLORTONING_STRENGTH;Strength +!TP_COLORTONING_STR;Strength +!TP_COLORTONING_TWO2;Special chroma '2 colors' +!TP_COLORTONING_TWOALL;Special chroma +!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_GTFRAME;Frame +!TP_CROP_GTGRID;Grid +!TP_CROP_GTHARMMEANS;Harmonic Means +!TP_CROP_GTTRIANGLE1;Golden Triangles 1 +!TP_CROP_GTTRIANGLE2;Golden Triangles 2 +!TP_CROP_PPI;PPI= +!TP_DARKFRAME_AUTOSELECT;Auto-selection +!TP_DARKFRAME_LABEL;Dark-Frame +!TP_DEFRINGE_LABEL;Defringe +!TP_DEFRINGE_RADIUS;Radius +!TP_DEFRINGE_THRESHOLD;Threshold +!TP_DIRPYRDENOISE_33;3×3 strong +!TP_DIRPYRDENOISE_55SOFT;5×5 +!TP_DIRPYRDENOISE_55;5×5 strong +!TP_DIRPYRDENOISE_77;7×7 (slow) +!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_ABM;Chroma only +!TP_DIRPYRDENOISE_AUTO;Automatic global +!TP_DIRPYRDENOISE_AUTO_TOOLTIP;Try to evaluate chroma noise\nBe careful, this calculation is average, and is quite subjective ! +!TP_DIRPYRDENOISE_AUT;Automatic global +!TP_DIRPYRDENOISE_BLUE;Chrominance - Blue-Yellow +!TP_DIRPYRDENOISE_C2TYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CCCURVE;Chrominance curve +!TP_DIRPYRDENOISE_CHROMAFR;Chrominance +!TP_DIRPYRDENOISE_CHROMA;Chrominance - Master +!TP_DIRPYRDENOISE_CTYPE;Auto method +!TP_DIRPYRDENOISE_CTYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nAutomatic multi-zones\nNo preview - works only during saving, but using the "Preview" method by matching the tile size and center to the preview size and center you can get an idea of the expected results.\nThe image is divided into tiles (about 10 to 70 depending on image size) and each tile receives its own chrominance noise reduction settings.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CURVEEDITOR_CC;Chroma +!TP_DIRPYRDENOISE_CURVEEDITOR_CC_TOOLTIP;Increase (multiply) the value of all chrominance sliders.\nThis curve lets you adjust the strength of chromatic noise reduction as a function of chromaticity, for instance to increase the action in areas of low saturation and to decrease it in those of high saturation. +!TP_DIRPYRDENOISE_CURVEEDITOR_L_TOOLTIP;Modulates action of 'Luminance' denoise +!TP_DIRPYRDENOISE_CUR;Curve +!TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on the gamma of the input color profile. An sRGB gamma is assumed, thus if the image uses an input color profile of a different gamma, the effects of luminance noise reduction will differ. +!TP_DIRPYRDENOISE_ENH;Enhanced mode +!TP_DIRPYRDENOISE_ENH_TOOLTIP;Increases noise reduction quality at the expense of a 20% processing time increase. +!TP_DIRPYRDENOISE_GAMMA;Gamma +!TP_DIRPYRDENOISE_GAMMA_TOOLTIP;Gamma varies noise reduction strength across the range of tones. Smaller values will target shadows, while larger values will stretch the effect to the brighter tones. +!TP_DIRPYRDENOISE_LABEL;Noise Reduction +!TP_DIRPYRDENOISE_LABM;L*a*b* +!TP_DIRPYRDENOISE_LAB;L*a*b* +!TP_DIRPYRDENOISE_LCURVE;Luminance curve +!TP_DIRPYRDENOISE_LDETAIL;Luminance - Detail +!TP_DIRPYRDENOISE_LM;Luminance only +!TP_DIRPYRDENOISE_LPLABM;Weighted L* (little) + a*b* (normal) +!TP_DIRPYRDENOISE_LTYPE;Luminance control +!TP_DIRPYRDENOISE_LUMAFR;Luminance +!TP_DIRPYRDENOISE_LUMAFR_TOOLTIP;Wavelet on luminance and Fourier transform for luminance detail +!TP_DIRPYRDENOISE_LUMA;Luminance +!TP_DIRPYRDENOISE_MANU;Manual +!TP_DIRPYRDENOISE_MAN;Manual +!TP_DIRPYRDENOISE_MEDMETHOD;Median method +!TP_DIRPYRDENOISE_MEDTYPE;Median type +!TP_DIRPYRDENOISE_MED;Median Filter +!TP_DIRPYRDENOISE_MED_TOOLTIP;Enabled median denoising +!TP_DIRPYRDENOISE_METHOD11;Quality +!TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. +!TP_DIRPYRDENOISE_METHOD;Method +!TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or L*a*b* methods can be used.\n\nFor non-raw images the L*a*b* method will be used, regardless of the selection. +!TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - +!TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 +!TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. +!TP_DIRPYRDENOISE_PASSES;Median iterations +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PON;Auto multi-zones +!TP_DIRPYRDENOISE_PREVLABEL;Preview size=%1, Center: Px=%2 Py=%3 +!TP_DIRPYRDENOISE_PREV;Preview +!TP_DIRPYRDENOISE_PRE;Preview multi-zones +!TP_DIRPYRDENOISE_RED;Chrominance - Red-Green +!TP_DIRPYRDENOISE_RGBM;RGB +!TP_DIRPYRDENOISE_RGB;RGB +!TP_DIRPYRDENOISE_SHALBI;High +!TP_DIRPYRDENOISE_SHAL;Standard +!TP_DIRPYRDENOISE_SLI;Slider +!TP_DIRPYRDENOISE_SOFT;3x3 +!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_LUMAFINEST;Finest +!TP_DIRPYREQUALIZER_LUMANEUTRAL;Neutral +!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_THRESHOLD;Threshold +!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;Auto Distortion Correction +!TP_DISTORTION_AUTO_TIP;Correct lens distortion automatically for some cameras (Micro 4/3, some compact digital cameras, etc.). +!TP_EPD_EDGESTOPPING;Edge stopping +!TP_EPD_GAMMA;Gamma +!TP_EPD_LABEL;Tone Mapping +!TP_EPD_REWEIGHTINGITERATES;Reweighting iterates +!TP_EPD_SCALE;Scale +!TP_EPD_STRENGTH;Strength +!TP_EPD_TOOLTIP;Tone mapping is possible in L*a*b* mode (standard) and CIECAM02 mode.\n\nWhen in L*a*b* mode, tone mapping can also be used on the residual image of the Wavelet Levels tool.\n\nTo engage CIECAM02 tone mapping mode enable the following settings:\n1. CIECAM02\n2. Algorithm="Brightness + Colorfulness (QM)"\n3. "Tone mapping using CIECAM02 brightness (Q)" +!TP_EXPOSURE_AUTOLEVELS_TIP;Toggles execution of Auto Levels to automatically set Exposure slider values based on an image analysis.\nEnables Highlight Reconstruction if necessary. +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in Auto Levels operation. +!TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Highlight compression threshold +!TP_EXPOSURE_CURVEEDITOR1;Tone curve 1 +!TP_EXPOSURE_CURVEEDITOR2;Tone curve 2 +!TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Please refer to the "Exposure > Tone Curves" RawPedia article to learn how to achieve the best results by using two tone curves. +!TP_EXPOSURE_SATURATION;Saturation +!TP_EXPOSURE_TCMODE_FILMLIKE;Film-like +!TP_EXPOSURE_TCMODE_LABEL1;Curve mode 1 +!TP_EXPOSURE_TCMODE_LABEL2;Curve mode 2 +!TP_EXPOSURE_TCMODE_LUMINANCE;Luminance +!TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Saturation and Value Blending +!TP_EXPOSURE_TCMODE_STANDARD;Standard +!TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard +!TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points +!TP_EXPOS_WHITEPOINT_LABEL;Raw White Points +!TP_FILMSIMULATION_LABEL;Film Simulation +!TP_FILMSIMULATION_STRENGTH;Strength +!TP_FILMSIMULATION_ZEROCLUTSFOUND;Set HaldCLUT directory in Preferences +!TP_FLATFIELD_AUTOSELECT;Auto-selection +!TP_FLATFIELD_BLURRADIUS;Blur radius +!TP_FLATFIELD_BLURTYPE;Blur type +!TP_FLATFIELD_BT_AREA;Area +!TP_FLATFIELD_BT_HORIZONTAL;Horizontal +!TP_FLATFIELD_BT_VERTHORIZ;Vertical + Horizontal +!TP_FLATFIELD_BT_VERTICAL;Vertical +!TP_FLATFIELD_CLIPCONTROL;Clip control +!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. +!TP_FLATFIELD_LABEL;Flat-Field +!TP_GAMMA_CURV;Gamma +!TP_GAMMA_FREE;Free gamma +!TP_GAMMA_OUTPUT;Output gamma +!TP_GAMMA_SLOP;Slope (linear) +!TP_GENERAL_11SCALE_TOOLTIP;The effects of this tool are only visible or only accurate at a preview scale of 1:1. +!TP_GRADIENT_CENTER;Center +!TP_GRADIENT_CENTER_X;Center X +!TP_GRADIENT_CENTER_X_TOOLTIP;Shift gradient to the left (negative values) or right (positive values). +!TP_GRADIENT_CENTER_Y;Center Y +!TP_GRADIENT_CENTER_Y_TOOLTIP;Shift gradient up (negative values) or down (positive values). +!TP_GRADIENT_DEGREE;Angle +!TP_GRADIENT_DEGREE_TOOLTIP;Rotation angle in degrees. +!TP_GRADIENT_FEATHER;Feather +!TP_GRADIENT_FEATHER_TOOLTIP;Gradient width in percent of the image diagonal. +!TP_GRADIENT_LABEL;Graduated Filter +!TP_GRADIENT_STRENGTH;Strength +!TP_GRADIENT_STRENGTH_TOOLTIP;Filter strength in stops. +!TP_HLREC_BLEND;Blend +!TP_HLREC_ENA_TOOLTIP;Could be activated by Auto Levels. +!TP_HSVEQUALIZER_CHANNEL;Channel +!TP_HSVEQUALIZER_HUE;H +!TP_HSVEQUALIZER_LABEL;HSV Equalizer +!TP_HSVEQUALIZER_SAT;S +!TP_HSVEQUALIZER_VAL;V +!TP_ICM_BLENDCMSMATRIX;Blend ICC highlights with matrix +!TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover clipped highlights when using LUT-based ICC profiles. +!TP_ICM_DCPILLUMINANT;Illuminant +!TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolated +!TP_ICM_DCPILLUMINANT_TOOLTIP;Select which embedded DCP illuminant to employ. Default is "interpolated" which is a mix between the two based on white balance. The setting is only enabled if a Dual-Illuminant DCP with interpolation support is selected. +!TP_ICM_INPUTCAMERAICC;Auto-matched camera profile +!TP_ICM_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input color profiles. These profiles are more precise than simpler matrix ones. They are not available for all cameras. These profiles are stored in the /iccprofiles/input and /dcpprofiles folders and are automatically retrieved based on a file name matching to the exact model name of the camera. +!TP_ICM_INPUTCAMERA_TOOLTIP;Use a simple color matrix from dcraw, an enhanced RawTherapee version (whichever is available based on camera model) or one embedded in the DNG. +!TP_ICM_INPUTCUSTOM_TOOLTIP;Select your own DCP/ICC color profile file for the camera. +!TP_ICM_INPUTEMBEDDED_TOOLTIP;Use color profile embedded in non-raw files. +!TP_ICM_INPUTNONE;No profile +!TP_ICM_INPUTNONE_TOOLTIP;Use no input color profile at all.\nUse only in special cases. +!TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance +!TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. The result can be used for calibration purposes and generation of a camera profile. +!TP_ICM_TONECURVE;Use DCP's tone curve +!TP_ICM_TONECURVE_TOOLTIP;Employ the embedded DCP tone curve. The setting is only enabled if the selected DCP has a tone curve. +!TP_IMPULSEDENOISE_LABEL;Impulse Noise Reduction +!TP_IMPULSEDENOISE_THRESH;Threshold +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid color shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction. +!TP_LABCURVE_BRIGHTNESS;Lightness +!TP_LABCURVE_CHROMATICITY;Chromaticity +!TP_LABCURVE_CHROMA_TOOLTIP;To apply B&W toning, set Chromaticity to -100. +!TP_LABCURVE_CONTRAST;Contrast +!TP_LABCURVE_CURVEEDITOR;Luminance Curve +!TP_LABCURVE_CURVEEDITOR_A_RANGE1;Green Saturated +!TP_LABCURVE_CURVEEDITOR_A_RANGE2;Green Pastel +!TP_LABCURVE_CURVEEDITOR_A_RANGE3;Red Pastel +!TP_LABCURVE_CURVEEDITOR_A_RANGE4;Red Saturated +!TP_LABCURVE_CURVEEDITOR_B_RANGE1;Blue Saturated +!TP_LABCURVE_CURVEEDITOR_B_RANGE2;Blue Pastel +!TP_LABCURVE_CURVEEDITOR_B_RANGE3;Yellow Pastel +!TP_LABCURVE_CURVEEDITOR_B_RANGE4;Yellow Saturated +!TP_LABCURVE_CURVEEDITOR_CC;CC +!TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutral +!TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Dull +!TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastel +!TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Saturated +!TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Chromaticity according to chromaticity C=f(C) +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to hue C=f(H) +!TP_LABCURVE_CURVEEDITOR_CL;CL +!TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Chromaticity according to luminance C=f(L) +!TP_LABCURVE_CURVEEDITOR_HH;HH +!TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Hue according to hue H=f(H) +!TP_LABCURVE_CURVEEDITOR_LC;LC +!TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminance according to chromaticity L=f(C) +!TP_LABCURVE_CURVEEDITOR_LH;LH +!TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H) +!TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminance according to luminance L=f(L) +!TP_LABCURVE_LABEL;L*a*b* Adjustments +!TP_LABCURVE_LCREDSK;Restrict LC to red and skin-tones +!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_LENSGEOM_AUTOCROP;Auto-Crop +!TP_LENSGEOM_FILL;Auto-fill +!TP_LENSGEOM_LABEL;Lens / Geometry +!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_USECA;Chromatic aberration correction +!TP_LENSPROFILE_USEDIST;Distortion correction +!TP_LENSPROFILE_USEVIGN;Vignetting correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Resets exposure sliders to neutral values.\nApplies to the same controls that Auto Levels applies to, regardless of whether you used Auto Levels or not. +!TP_PCVIGNETTE_FEATHER;Feather +!TP_PCVIGNETTE_FEATHER_TOOLTIP;Feathering:\n0 = corners only,\n50 = halfway to center,\n100 = to center. +!TP_PCVIGNETTE_LABEL;Vignette Filter +!TP_PCVIGNETTE_ROUNDNESS;Roundness +!TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness:\n0 = rectangle,\n50 = fitted ellipse,\n100 = circle. +!TP_PCVIGNETTE_STRENGTH;Strength +!TP_PCVIGNETTE_STRENGTH_TOOLTIP;Filter strength in stops (reached in corners). +!TP_PERSPECTIVE_HORIZONTAL;Horizontal +!TP_PERSPECTIVE_LABEL;Perspective +!TP_PERSPECTIVE_VERTICAL;Vertical +!TP_PFCURVE_CURVEEDITOR_CH;Hue +!TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Controls defringe strength by color.\nHigher = more,\nLower = less. +!TP_PREPROCESS_DEADPIXFILT;Dead pixel filter +!TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Tries to suppress dead pixels. +!TP_PREPROCESS_GREENEQUIL;Green equilibration +!TP_PREPROCESS_HOTPIXFILT;Hot pixel filter +!TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Tries to suppress hot pixels. +!TP_PREPROCESS_LABEL;Preprocessing +!TP_PREPROCESS_LINEDENOISE;Line noise filter +!TP_PREPROCESS_NO_FOUND;None found +!TP_RAWCACORR_AUTO;Auto-correction +!TP_RAWCACORR_CABLUE;Blue +!TP_RAWCACORR_CARED;Red +!TP_RAWEXPOS_BLACKS;Black Levels +!TP_RAWEXPOS_BLACK_0;Green 1 (lead) +!TP_RAWEXPOS_BLACK_1;Red +!TP_RAWEXPOS_BLACK_2;Blue +!TP_RAWEXPOS_BLACK_3;Green 2 +!TP_RAWEXPOS_BLACK_BLUE;Blue +!TP_RAWEXPOS_BLACK_GREEN;Green +!TP_RAWEXPOS_BLACK_RED;Red +!TP_RAWEXPOS_LINEAR;White-point correction +!TP_RAWEXPOS_PRESER;Highlight preservation +!TP_RAWEXPOS_RGB;Red, Green, Blue +!TP_RAWEXPOS_TWOGREEN;Link greens +!TP_RAW_DCBENHANCE;DCB enhancement +!TP_RAW_DCBITERATIONS;Number of DCB iterations +!TP_RAW_DMETHOD_PROGRESSBAR;%1 demosaicing... +!TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Demosaicing refinement... +!TP_RAW_DMETHOD_TOOLTIP;Note: IGV and LMMSE are dedicated to high ISO images to aid in noise reduction without leading to maze patterns, posterization or a washed-out look. +!TP_RAW_HD;Threshold +!TP_RAW_HD_TOOLTIP;Lower values make hot/dead pixel detection more aggressive, but false positives may lead to artifacts. If you notice any artifacts appearing when enabling the Hot/Dead Pixel Filters, gradually increase the threshold value until they disappear. +!TP_RAW_LABEL;Demosaicing +!TP_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!TP_RAW_LMMSE_TOOLTIP;Adds gamma (step 1), median (steps 2-4) and refinement (steps 5-6) to reduce artifacts and improve the signal-to-noise ratio. +!TP_RAW_SENSOR_BAYER_LABEL;Sensor with Bayer Matrix +!TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;3-pass gives best results (recommended for low ISO images).\n1-pass is almost undistinguishable from 3-pass for high ISO images and is faster. +!TP_RAW_SENSOR_XTRANS_LABEL;Sensor with X-Trans Matrix +!TP_RESIZE_APPLIESTO;Applies to: +!TP_RESIZE_CROPPEDAREA;Cropped Area +!TP_RESIZE_FITBOX;Bounding Box +!TP_RESIZE_FULLIMAGE;Full Image +!TP_RESIZE_HEIGHT;Height +!TP_RESIZE_LANCZOS;Lanczos +!TP_RESIZE_SPECIFY;Specify: +!TP_RESIZE_WIDTH;Width +!TP_RGBCURVES_BLUE;B +!TP_RGBCURVES_CHANNEL;Channel +!TP_RGBCURVES_GREEN;G +!TP_RGBCURVES_LABEL;RGB Curves +!TP_RGBCURVES_LUMAMODE;Luminosity mode +!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_RGBCURVES_RED;R +!TP_SAVEDIALOG_OK_TIP;Shortcut: Ctrl-Enter +!TP_SHADOWSHLIGHTS_SHARPMASK;Sharp mask +!TP_SHARPENEDGE_AMOUNT;Quantity +!TP_SHARPENEDGE_LABEL;Edges +!TP_SHARPENEDGE_PASSES;Iterations +!TP_SHARPENEDGE_THREE;Luminance only +!TP_SHARPENING_TOOLTIP;Expect a slightly different effect when using with CIECAM02. If difference is observed, adjust to taste. +!TP_SHARPENMICRO_AMOUNT;Quantity +!TP_SHARPENMICRO_LABEL;Microcontrast +!TP_SHARPENMICRO_MATRIX;3×3 matrix instead of 5×5 +!TP_SHARPENMICRO_UNIFORMITY;Uniformity +!TP_VIBRANCE_AVOIDCOLORSHIFT;Avoid color shift +!TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Red/Purple +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Red +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Red/Yellow +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Yellow +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Hue according to hue H=f(H) +!TP_VIBRANCE_LABEL;Vibrance +!TP_VIBRANCE_PASTELS;Pastel Tones +!TP_VIBRANCE_PASTSATTOG;Link pastel and saturated tones +!TP_VIBRANCE_PROTECTSKINS;Protect skin-tones +!TP_VIBRANCE_PSTHRESHOLD;Pastel/saturated tones threshold +!TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Saturation threshold +!TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;The vertical axis represents pastel tones at the bottom and saturated tones at the top.\nThe horizontal axis represents the saturation range. +!TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Pastel/saturated transition's weighting +!TP_VIBRANCE_SATURATED;Saturated Tones +!TP_VIGNETTING_CENTER;Center +!TP_VIGNETTING_CENTER_X;Center X +!TP_VIGNETTING_CENTER_Y;Center Y +!TP_VIGNETTING_STRENGTH;Strength +!TP_WAVELET_1;Level 1 +!TP_WAVELET_2;Level 2 +!TP_WAVELET_3;Level 3 +!TP_WAVELET_4;Level 4 +!TP_WAVELET_5;Level 5 +!TP_WAVELET_6;Level 6 +!TP_WAVELET_7;Level 7 +!TP_WAVELET_8;Level 8 +!TP_WAVELET_9;Level 9 +!TP_WAVELET_ALL;All levels in all directions +!TP_WAVELET_APPLYTO;Apply To +!TP_WAVELET_AVOID;Avoid color shift +!TP_WAVELET_B0;Black +!TP_WAVELET_B1;Grey +!TP_WAVELET_B2;Residual +!TP_WAVELET_BACUR;Curve +!TP_WAVELET_BALANCE;Contrast balance d/v-h +!TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chromaticity or residual tone mapping are activated, the effect due to balance is amplified. +!TP_WAVELET_BALCHRO;Chroma balance +!TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chromaticity balance. +!TP_WAVELET_BANONE;None +!TP_WAVELET_BASLI;Slider +!TP_WAVELET_BATYPE;Contrast balance method +!TP_WAVELET_CCURVE;Local contrast +!TP_WAVELET_CH1;Whole chromaticity range +!TP_WAVELET_CH2;Saturated/pastel +!TP_WAVELET_CH3;Link contrast levels +!TP_WAVELET_CHCU;Curve +!TP_WAVELET_CHRO;Saturated/pastel threshold +!TP_WAVELET_CHRO_TOOLTIP;Sets the wavelet level which will be the threshold between saturated and pastel colors.\n1-x: saturated\nx-9: pastel\n\nIf the value exceeds the amount of wavelet levels you are using then it will be ignored. +!TP_WAVELET_CHR;Chroma-contrast link strength +!TP_WAVELET_CHR_TOOLTIP;Adjusts chromaticity as a function of "contrast levels" and "chroma-contrast link strength" +!TP_WAVELET_CHSL;Sliders +!TP_WAVELET_CHTYPE;Chrominance method +!TP_WAVELET_COLORT;Opacity Red-Green +!TP_WAVELET_COMBOTH;Both +!TP_WAVELET_COMPCONT;Contrast +!TP_WAVELET_COMPGAMMA;Compression gamma +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjusting the gamma of the residual image allow you to equilibrate the data and histogram. +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjust gamma for residual image and compression.\nAllow to equilibrate data and histogram +!TP_WAVELET_COMPTM;Tone mapping +!TP_WAVELET_CONTEDIT;'After' Contrast curve +!TP_WAVELET_CONTEDIT;'After' contrast curve +!TP_WAVELET_CONTRAST_MINUS;Contrast - +!TP_WAVELET_CONTRAST_PLUS;Contrast + +!TP_WAVELET_CONTRA;Contrast +!TP_WAVELET_CONTRA_TOOLTIP;Changes contrast of the residual image. +!TP_WAVELET_CONTR;Gamut +!TP_WAVELET_CTYPE;Chrominance control +!TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modifies local contrast as a function of the original local contrast (absciss)\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 100..300)\n66% absciss represents standard deviation of local contrast (real value about 300..800)\n100% represents maximum (real value about 3000..8000) +!TP_WAVELET_CURVEEDITOR_CH;Contrast levels=f(Hue) +!TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modifies each level's contrast as a function oh hue.\nTake care not to overwrite changes made with the Gamut Hue controls.\nThe curve will only have an effect when wavelet contrast level sliders are non-zero. +!TP_WAVELET_CURVEEDITOR_CL;L +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Applies a final contrast luminance curve at the end of the wavelet treatment. +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Apply a contrast luminance curve at the end of wavelet level threatment +!TP_WAVELET_CURVEEDITOR_HH;HH +!TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modifies the residual image's hue as a function of hue. +!TP_WAVELET_DALL;All directions +!TP_WAVELET_DAUB;Edge performance +!TP_WAVELET_DAUB_TOOLTIP;Changes Daubechies coefficients:\nD4 = Standard,\nD14 = Often best performance, 10% more time-intensive.\n\nAffects edge detection as well as the general quality of the firsts levels. However the quality is not strictly related to this coefficient and can vary with images and uses. +!TP_WAVELET_DISP;Preview Settings +!TP_WAVELET_DONE;Vertical +!TP_WAVELET_DTHR;Diagonal +!TP_WAVELET_DTWO;Horizontal +!TP_WAVELET_EDCU;Curve +!TP_WAVELET_EDGCONT;Local contrast +!TP_WAVELET_EDGCONT_TOOLTIP;Adjusting the points to the left decreases contrast, and to the right increases it.\nBottom-left, Top-Left, Top-Right, Bottom-right represent respectively local contast for low values, mean, mean+stdev, maxima +!TP_WAVELET_EDGEDETECTTHR2;Threshold high (detection) +!TP_WAVELET_EDGEDETECTTHR;Threshold low (noise) +!TP_WAVELET_EDGEDETECTTHR_TOOLTIP;This adjuster lets you target edge detection for example to avoid applying edge sharpness to fine details, such as noise in the sky. +!TP_WAVELET_EDGEDETECT;Gradient sensitivity +!TP_WAVELET_EDGEDETECT_TOOLTIP;Moving the slider to the right increases edge sensitivity. This affects local contrast, edge settings and noise. +!TP_WAVELET_EDGE;Edge Sharpness +!TP_WAVELET_EDGREINF_TOOLTIP;Reinforce or reduce the action of the first level, do the opposite to the second level, and leave the rest unchanged. +!TP_WAVELET_EDGTHRESH;Detail +!TP_WAVELET_EDGTHRESH_TOOLTIP;Change the repartition between the first levels and the others. The higher the threshold the more the action is centred on the first levels. Be careful with negative values, they increase the action of high levels and can introduce artifacts. +!TP_WAVELET_EDRAD;Radius +!TP_WAVELET_EDRAD_TOOLTIP;This radius adjustment is very different from those in other sharpening tools. Its value is compared to each level through a complex function. In this sense, a value of zero still has an effect. +!TP_WAVELET_EDSL;Threshold Sliders +!TP_WAVELET_EDTYPE;Local contrast method +!TP_WAVELET_EDVAL;Strength +!TP_WAVELET_FINAL;Final Touchup +!TP_WAVELET_FINEST;Finest +!TP_WAVELET_HIGHLIGHT;Highlight luminance range +!TP_WAVELET_HS1;Whole luminance range +!TP_WAVELET_HS2;Shadows/Highlights +!TP_WAVELET_HUESKIN;Skin hue +!TP_WAVELET_HUESKIN_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_HUESKY;Sky hue +!TP_WAVELET_HUESKY_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_INF;Below or equal the level +!TP_WAVELET_ITER;Delta balance levels +!TP_WAVELET_ITER_TOOLTIP;Left: increase low levels and reduce high levels,\nRight: reduce low levels and increase high levels. +!TP_WAVELET_LABEL;Wavelet levels +!TP_WAVELET_LARGEST;Coarsest +!TP_WAVELET_LEVCH;Chromaticity +!TP_WAVELET_LEVELS;Wavelet levels +!TP_WAVELET_LEVELS_TOOLTIP;Choose the number of detail levels the image is to be decomposed into. More levels require more RAM and require a longer processing time. +!TP_WAVELET_LEVF;Contrast +!TP_WAVELET_LEVLABEL;Preview maximum possible levels = %1 +!TP_WAVELET_LEVONE;Level 2 +!TP_WAVELET_LEVTWO;Level 3 +!TP_WAVELET_LEVZERO;Level 1 +!TP_WAVELET_LINKEDG;Link with Edge Sharpness' Strength +!TP_WAVELET_LIPST;Enhanced algorithm +!TP_WAVELET_LIPST_TOOLTIP;This algorithm uses Lipschitz regularity to increase edge detection quality at a cost of increased processing time and memory requirements. +!TP_WAVELET_LOWLIGHT;Shadow luminance range +!TP_WAVELET_MEDGREINF;First level +!TP_WAVELET_MEDILEV;Edge detection +!TP_WAVELET_MEDI;Reduce artifacts in blue sky +!TP_WAVELET_NEUTRAL;Neutral +!TP_WAVELET_NOISE;Denoise and Refine +!TP_WAVELET_NOIS;Denoise +!TP_WAVELET_ONE;One level +!TP_WAVELET_OPACITYWL;Final local contrast +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify final local contrast in function of last local contrast (absciss) for all levels decomposition\nTake into account: \na)contrast levels \nb)edge sharpness \nc)contrast balance\nd)decomposition-recomposition\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 200..1000)\n66% absciss represents standard deviation of local contrast (real value about 1000..2000)\n100% represents maximum (real value about 5000..13000) +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify the final local contrast at the end of the wavelet treatment.\n\nThe left side represents the smallest local contrast, progressing to the largest local contrast on the right. +!TP_WAVELET_OPACITYW;Contrast balance d/v-h curve +!TP_WAVELET_OPACITY;Opacity Blue-Yellow +!TP_WAVELET_PASTEL;Pastel chromaticity +!TP_WAVELET_PREVIEWBACK;Background +!TP_WAVELET_PREVIEWLEVELS;Preview +!TP_WAVELET_RE1;Reinforced +!TP_WAVELET_RE2;Unchanged +!TP_WAVELET_RE3;Reduced +!TP_WAVELET_RESCHRO;Chromaticity +!TP_WAVELET_RESCONH;Highlights +!TP_WAVELET_RESCON;Shadows +!TP_WAVELET_RESID;Residual image +!TP_WAVELET_SAT;Saturated chromaticity +!TP_WAVELET_SETTINGS;Wavelet Settings +!TP_WAVELET_SKIN;Skin targetting/protection +!TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected. +!TP_WAVELET_SKY;Sky targetting/protection +!TP_WAVELET_SKY_TOOLTIP;At -100 sky-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 sky-tones are protected while all other tones are affected. +!TP_WAVELET_STRENGTH;Strength +!TP_WAVELET_STREN;Strength +!TP_WAVELET_SUPE;Extra +!TP_WAVELET_SUP;Above the level +!TP_WAVELET_THRESHOLD2;Shadow levels +!TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels between 9 and 9 minus the value will be affected by the shadow luminance range. Other levels will be fully treated. The highest level possible is limited by the highlight level value (9 minus highlight level value). +!TP_WAVELET_THRESHOLD;Highlight levels +!TP_WAVELET_THRESHOLD_TOOLTIP;Only levels beyond the chosen value will be affected by the highlight luminance range. Other levels will be fully treated. The chosen value here limits the highest possible value of the shadow levels. +!TP_WAVELET_THRH;Highlights threshold +!TP_WAVELET_THR;Shadows threshold +!TP_WAVELET_TILESBIG;Big tiles +!TP_WAVELET_TILESFULL;Full image +!TP_WAVELET_TILESIZE;Tiling method +!TP_WAVELET_TILESLIT;Little tiles +!TP_WAVELET_TILES_TOOLTIP;Processing the full image leads to better quality and is the recommended option, while using tiles is a fall-back solution for users with little RAM. Refer to RawPedia for memory requirements. +!TP_WAVELET_TMHIGH;High +!TP_WAVELET_TMLOWHIGH;Low+High +!TP_WAVELET_TMNONE;None +!TP_WAVELET_TMSTD;Standard +!TP_WAVELET_TMSTRENGTH;Compression strength +!TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image. When the value is different from 0, the Strength and Gamma sliders of the Tone Mapping tool in the Exposure tab will become grayed out. +!TP_WAVELET_TMTYPE;Compression method +!TP_WAVELET_TON;Toning +!TP_WAVELET_daub2;D2 - low +!TP_WAVELET_daub4;D4 - standard +!TP_WAVELET_daub6;D6 - standard plus +!TP_WAVELET_daub10;D10 - medium +!TP_WAVELET_daub14;D14 - high +!TP_WBALANCE_CLOUDY;Cloudy +!TP_WBALANCE_DAYLIGHT;Daylight (sunny) +!TP_WBALANCE_EQBLUERED;Blue/Red equalizer +!TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behavior of "white balance" by modulating the blue/red balance.\nThis can be useful when shooting conditions:\na) are far from the standard illuminant (e.g. underwater),\nb) are far from conditions where calibrations were performed,\nc) where the matrices or ICC profiles are unsuitable. +!TP_WBALANCE_FLASH55;Leica +!TP_WBALANCE_FLASH60;Standard, Canon, Pentax, Olympus +!TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta +!TP_WBALANCE_FLASH_HEADER;Flash +!TP_WBALANCE_FLUO1;F1 - Daylight +!TP_WBALANCE_FLUO2;F2 - Cool White +!TP_WBALANCE_FLUO3;F3 - White +!TP_WBALANCE_FLUO4;F4 - Warm White +!TP_WBALANCE_FLUO5;F5 - Daylight +!TP_WBALANCE_FLUO6;F6 - Lite White +!TP_WBALANCE_FLUO7;F7 - D65 Daylight Simulator +!TP_WBALANCE_FLUO8;F8 - D50 / Sylvania F40 Design +!TP_WBALANCE_FLUO9;F9 - Cool White Deluxe +!TP_WBALANCE_FLUO10;F10 - Philips TL85 +!TP_WBALANCE_FLUO11;F11 - Philips TL84 +!TP_WBALANCE_FLUO12;F12 - Philips TL83 +!TP_WBALANCE_FLUO_HEADER;Fluorescent +!TP_WBALANCE_GTI;GTI +!TP_WBALANCE_HMI;HMI +!TP_WBALANCE_JUDGEIII;JudgeIII +!TP_WBALANCE_LAMP_HEADER;Lamp +!TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 +!TP_WBALANCE_LED_HEADER;LED +!TP_WBALANCE_LED_LSI;LSI Lumelex 2040 +!TP_WBALANCE_SHADE;Shade +!TP_WBALANCE_SOLUX35;Solux 3500K +!TP_WBALANCE_SOLUX41;Solux 4100K +!TP_WBALANCE_SOLUX47;Solux 4700K (vendor) +!TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) +!TP_WBALANCE_TUNGSTEN;Tungsten +!TP_WBALANCE_WATER1;UnderWater 1 +!TP_WBALANCE_WATER2;UnderWater 2 +!TP_WBALANCE_WATER_HEADER;UnderWater +!ZOOMPANEL_100;(100%) +!ZOOMPANEL_NEWCROPWINDOW;Open (new) detail window +!ZOOMPANEL_ZOOM100;Zoom to 100%\nShortcut: z +!ZOOMPANEL_ZOOMFITCROPSCREEN;Fit crop to screen\nShortcut: Alt-f +!ZOOMPANEL_ZOOMFITSCREEN;Fit whole image to screen\nShortcut: f +!ZOOMPANEL_ZOOMIN;Zoom In\nShortcut: + +!ZOOMPANEL_ZOOMOUT;Zoom Out\nShortcut: - diff --git a/rtdata/languages/Magyar b/rtdata/languages/Magyar new file mode 100644 index 000000000..f089de0d2 --- /dev/null +++ b/rtdata/languages/Magyar @@ -0,0 +1,1856 @@ +#01 2010-11-20 RT 3.0 alpha 1 rev. 597:fb291bf74c by Dr. Gyurkó M. 'dualon' Dávid + +ABOUT_TAB_BUILD;Verzió +ABOUT_TAB_CREDITS;Szerzők +ABOUT_TAB_LICENSE;Licensz +ABOUT_TAB_RELEASENOTES;Kiadási megjegyzések +ABOUT_TAB_SPLASH;Splash +ADJUSTER_RESET_TO_DEFAULT;Alaphelyzetbe állítás +BATCHQUEUE_AUTOSTART;Auto start +BATCH_PROCESSING;Kötegelt feldolgozás +CURVEEDITOR_CURVES;Görbék +CURVEEDITOR_CURVE;Görbe +CURVEEDITOR_CUSTOM;Egyedi +CURVEEDITOR_DARKS;Sötétek +CURVEEDITOR_HIGHLIGHTS;Csúcsfények +CURVEEDITOR_LIGHTS;Középfények +CURVEEDITOR_LINEAR;Lineáris +CURVEEDITOR_LOADDLGLABEL;Görbe betöltése... +CURVEEDITOR_MINMAXCPOINTS;Minimum/maximum kontrollpontok +CURVEEDITOR_NURBS;Húrkontroll +CURVEEDITOR_PARAMETRIC;Parametrikus +CURVEEDITOR_SAVEDLGLABEL;Görbe mentése... +CURVEEDITOR_SHADOWS;Árnyékok +CURVEEDITOR_TOOLTIPCOPY;Aktuális görbe másolása a vágólapra +CURVEEDITOR_TOOLTIPLINEAR;Lineáris görbe visszaállítása +CURVEEDITOR_TOOLTIPLOAD;Görbe betöltése +CURVEEDITOR_TOOLTIPPASTE;Görbe beillesztése a vágólapról +CURVEEDITOR_TOOLTIPSAVE;Görbe mentése +CURVEEDITOR_TYPE;Típus: +DIRBROWSER_FOLDERS;Mappák +EDITWINDOW_TITLE;Kép szerkesztése +EXIFFILTER_APERTURE;Rekesz +EXIFFILTER_CAMERA;Fényképezőgép +EXIFFILTER_EXPOSURECOMPENSATION;Expozíciókompenzáció (FÉ) +EXIFFILTER_FILETYPE;Állománytípus +EXIFFILTER_FOCALLEN;Fókusztávolság +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Objektív +EXIFFILTER_METADATAFILTER;Metaadat-szűrő engedélyezése +EXIFFILTER_SHUTTER;Záridő +EXIFPANEL_ADDEDITHINT;Új tagok hozzáadása, szerkesztése +EXIFPANEL_ADDEDIT;Hozzáad/Szerkeszt +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Érték megadása +EXIFPANEL_ADDTAGDLG_SELECTTAG;Tag kijelölése +EXIFPANEL_ADDTAGDLG_TITLE;Új tagok hozzáadása / Tagok szerkesztése +EXIFPANEL_KEEPHINT;A kijelölt adatok megtartása a végső fájl mentésekor +EXIFPANEL_KEEP;Megtart +EXIFPANEL_REMOVEHINT;A kijelölt adatok eldobása a végső fájl mentésekor +EXIFPANEL_REMOVE;Eltávolít +EXIFPANEL_RESETALLHINT;Az összes metaadat visszaállítása az eredeti állapotba +EXIFPANEL_RESETALL;Mindent visszaállít +EXIFPANEL_RESETHINT;A kijelölt adatok visszaállítása az eredeti állapotba +EXIFPANEL_RESET;Visszaállít +EXIFPANEL_SUBDIRECTORY;Alkönyvtár +EXPORT_BYPASS_ALL;Mindent kijelöl/Kijelölés megszüntetése +EXPORT_BYPASS_DEFRINGE;Színihiba-korrekció kihagyása +EXPORT_BYPASS_DIRPYRDENOISE;Zajszűrés kihagyása +EXPORT_BYPASS_DIRPYREQUALIZER;Kontraszt részletek szerint kihagyása +EXPORT_BYPASS_RAW_CA;[Raw]Színihiba-korrekció kihagyása +EXPORT_BYPASS_RAW_CCSTEPS;[Raw] Hamis színek javításának kihagyása +EXPORT_BYPASS_RAW_DCB_ENHANCE;[Raw] DCB javító lépések kihagyása +EXPORT_BYPASS_RAW_DCB_ITERATIONS;[Raw] DCB ismétlések kihagyása +EXPORT_BYPASS_RAW_DF;[Raw] fekete referenciakép (dark frame) kihagyása +EXPORT_BYPASS_RAW_FF;[Raw] Flat Field kihagyása +EXPORT_BYPASS_RAW_GREENTHRESH;[Raw] zöldegyensúly kihagyása +EXPORT_BYPASS_RAW_LINENOISE;[Raw] soronkénti zajszűrés kihagyása +EXPORT_BYPASS_SHARPENEDGE;Élek élesítésének kihagyása +EXPORT_BYPASS_SHARPENING;Élesítés kihagyása +EXPORT_BYPASS_SHARPENMICRO;Mikrokontraszt kihagyása +EXPORT_BYPASS_SH_HQ;(Kiváló minőségű) árnyékok/csúcsfények kihagyása +EXPORT_FASTEXPORTOPTIONS;Expressz exportálás beállításai +EXPORT_INSTRUCTIONS;Az expressz exportálás lehetővé teszi, hogy az idő- és erőforrás-igényes előhívási lépéseket kihagyd, és helyettük az expressz exportálás beállításait használd a feldolgozási sor lefuttatására. E megoldás kisebb felbontású képek gyors létrehozásához javasolt, ahol a sebesség az elsődleges, vagy ahol átméretezett képekre van szükség egyéb feldolgozási paramétereik módosítása nélkül. +EXPORT_MAXHEIGHT;Maximum magasság: +EXPORT_MAXWIDTH;Maximum szélesség: +EXPORT_PUTTOQUEUEFAST; Feldolgozási sorba helyezés expressz exportáláshoz +EXPORT_RAW_DMETHOD;Interpoláció algoritmusa +FILEBROWSER_ADDDELTEMPLATE;Sablon hozzáadása/törlése... +FILEBROWSER_APPLYPROFILE;Feldolgozási paraméter hozzárendelése +FILEBROWSER_APPLYPROFILE_PARTIAL;Profil alkalmazása (részleges) +FILEBROWSER_AUTODARKFRAME;Auto referencia feketekép (dark frame) +FILEBROWSER_AUTOFLATFIELD;Auto Flat Field +FILEBROWSER_BROWSEPATHBUTTONHINT;Kattints a kiválasztott útvonal böngészéséhez +FILEBROWSER_BROWSEPATHHINT;Gépeld be az elérni kívánt útvonalat.\nCtrl-O-val tudod a fókuszt a beviteli mezőre vinni.\nEnter / Ctrl-Enter (az állományböngészőben) az ottani böngészéshez;\n\nÚtvonalrövidítések:\n ~ - felhasználói fiók (home) könyvtára\n - a felhasználó képkönyvtára +FILEBROWSER_CACHECLEARFROMFULL;Gyorsítótár ürítése - teljes +FILEBROWSER_CACHECLEARFROMPARTIAL;Gyorsítótár ürítése - részleges +FILEBROWSER_CACHE;Gyorsítótár +FILEBROWSER_CLEARPROFILE;Feldolgozási paraméter törlése +FILEBROWSER_COPYPROFILE;Feldolgozási paraméterek másolása +FILEBROWSER_CURRENT_NAME;Aktuális név: +FILEBROWSER_DARKFRAME;Referencia feketekép (dark frame) +FILEBROWSER_DELETEDLGLABEL;Állománytörlés megerősítése +FILEBROWSER_DELETEDLGMSGINCLPROC;Biztos vagy benne, hogy törölni szeredné a kiválasztott %1 állományt, beleértve a feldolgozási sorba helyezett változatát IS? +FILEBROWSER_DELETEDLGMSG;Biztosan törölni kívánja a kijelölt %1 képet? +FILEBROWSER_EMPTYTRASHHINT;A kukában lévő képek végleges, állományrendszerből történő eltávolítása. +FILEBROWSER_EMPTYTRASH;Kuka ürítése +FILEBROWSER_EXEC_CPB;Egyedi profil készítő futtatása +FILEBROWSER_FLATFIELD;Flat Field +FILEBROWSER_MOVETODARKFDIR;Mozgatás a 'dark frame' könyvtárba +FILEBROWSER_MOVETOFLATFIELDDIR;Flat Fields könyvtárba mozgatás +FILEBROWSER_NEW_NAME;Új név: +FILEBROWSER_PARTIALPASTEPROFILE;Részleges beillesztés +FILEBROWSER_PASTEPROFILE;Feldolgozási paraméterek beillesztése +FILEBROWSER_POPUPCANCELJOB;Eltávolítás a sorból +FILEBROWSER_POPUPCOLORLABEL;Színcímke +FILEBROWSER_POPUPCOPYTO;Másolás máshová... +FILEBROWSER_POPUPFILEOPERATIONS;Állományműveletek +FILEBROWSER_POPUPMOVEEND;Végére mozgatás +FILEBROWSER_POPUPMOVEHEAD;Elejére mozgatás +FILEBROWSER_POPUPMOVETO;Mozgatás máshová... +FILEBROWSER_POPUPOPENINEDITOR;Open in Szerkesztő +FILEBROWSER_POPUPOPEN;Megnyitás szerkesztésre +FILEBROWSER_POPUPPROCESSFAST;Feldolgozási sorba helyez (expressz export) +FILEBROWSER_POPUPPROCESS;Feldolgozási sorba helyezés +FILEBROWSER_POPUPPROFILEOPERATIONS;Profilműveletek +FILEBROWSER_POPUPREMOVEINCLPROC;Törlés (feldolgozási sorból is) +FILEBROWSER_POPUPREMOVE;Törlés (végleges) +FILEBROWSER_POPUPRENAME;Átnevezés +FILEBROWSER_POPUPSELECTALL;Mindent kijelöl +FILEBROWSER_POPUPTRASH;Kukába dobás +FILEBROWSER_POPUPUNRANK;Jelölés megszüntetése +FILEBROWSER_POPUPUNTRASH;Visszaállítás a kukából +FILEBROWSER_QUERYBUTTONHINT;Találati lista ürítése +FILEBROWSER_QUERYHINT;Írd be a keresett állomány nevét vagy abból egy töredéket.\nCtrl-F megnyomásával (az állományböngészőben) a fókuszt a keresőmezőre helyezheted.\nEnter indítja a keresést. +FILEBROWSER_QUERYLABEL; Keresés: +FILEBROWSER_RENAMEDLGLABEL;Fájl átnevezése +FILEBROWSER_RENAMEDLGMSG;%1 új neve: +FILEBROWSER_SELECTDARKFRAME;Referencia feketekép kiválasztása... +FILEBROWSER_SELECTFLATFIELD;Flat field kép kiválasztása +FILEBROWSER_SHOWCOLORLABEL1HINT;Piros címkéjű képek megjelenítése.\nGyorsbillentyű: Alt-1 +FILEBROWSER_SHOWCOLORLABEL2HINT;Sárga címkéjű képek megjelenítése.\nGyorsbillentyű: Alt-2 +FILEBROWSER_SHOWCOLORLABEL3HINT;Zöld címkéjű képek megjelenítése.\nGyorsbillentyű: Alt-3 +FILEBROWSER_SHOWCOLORLABEL4HINT;Kék címkéjű képek megjelenítése.\nGyorsbillentyű: Alt-4 +FILEBROWSER_SHOWCOLORLABEL5HINT;Lila címkéjű képek megjelenítése.\nGyorsbillentyű: Alt-5 +FILEBROWSER_SHOWDIRHINT;A könyvtárban lévő összes kép mutatása +FILEBROWSER_SHOWEDITEDHINT;Szerkesztett képek megjelenítése.\nGyorsbillentyű: 7 +FILEBROWSER_SHOWEDITEDNOTHINT;Még nem szerkesztett képek megjelenítése.\nGyorsbillentyű: 6 +FILEBROWSER_SHOWEXIFINFO;EXIF info megjelenítése: i +FILEBROWSER_SHOWRANK1HINT;1 csillaggal jelölt képek mutatása +FILEBROWSER_SHOWRANK2HINT;2 csillaggal jelölt képek mutatása +FILEBROWSER_SHOWRANK3HINT;3 csillaggal jelölt képek mutatása +FILEBROWSER_SHOWRANK4HINT;4 csillaggal jelölt képek mutatása +FILEBROWSER_SHOWRANK5HINT;5 csillaggal jelölt képek mutatása +FILEBROWSER_SHOWRECENTLYSAVEDHINT;Mostanában mentett képek megjelenítése.\nGyorsbillentyű: Alt-7 +FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Korábban mentett képek megjelenítése.\nGyorsbillentyű: Alt-6 +FILEBROWSER_SHOWTRASHHINT;A kuka tartalmának mutatása +FILEBROWSER_SHOWUNCOLORHINT;Színcímke nélküli képek megjelenítése.\nGyorsbillentyű: Alt-0 +FILEBROWSER_SHOWUNRANKHINT;Meg nem jelölt képek mutatása +FILEBROWSER_STARTPROCESSINGHINT;A sorban álló képek feldolgozásának elindítása +FILEBROWSER_STARTPROCESSING;Feldolgozás indítása +FILEBROWSER_STOPPROCESSINGHINT;A sorban álló képek feldolgozásának leállítása +FILEBROWSER_STOPPROCESSING;Feldolgozás leállítása +FILEBROWSER_THUMBSIZE;Bélyegméret +FILEBROWSER_TOOLTIP_STOPPROCESSING;Új kép érkezése esetén a feldolgozás automatikus indítása. +FILEBROWSER_ZOOMINHINT;Növelés +FILEBROWSER_ZOOMOUTHINT;Csökkentés +GENERAL_ABOUT;Névjegy +GENERAL_AFTER;Utána +GENERAL_BEFORE;Előtte +GENERAL_CANCEL;Mégsem +GENERAL_DISABLED;Kikapcsolva +GENERAL_DISABLE;Kikapcsol +GENERAL_ENABLED;Engedélyezve +GENERAL_ENABLE;Engedélyez +GENERAL_FILE;Állomány +GENERAL_LANDSCAPE;Fekvő +GENERAL_NA;n/a +GENERAL_NONE;Nincs +GENERAL_NO;Nem +GENERAL_OK;OK +GENERAL_PORTRAIT;Álló +GENERAL_SAVE;Mentés +GENERAL_UNCHANGED;(Változatlan) +HISTOGRAM_TOOLTIP_BAR;RGB jelzősáv megjelenítése/elrejtése.\nKattints jobb gombbal a kép előnézetére a fagyasztáshoz / feloldáshoz. +HISTOGRAM_TOOLTIP_B;Kék csatorna hisztogrammja (mutat/elrejt) +HISTOGRAM_TOOLTIP_G;Zöld csatorna hisztogrammja (mutat/elrejt) +HISTOGRAM_TOOLTIP_L;CIELAB Luminancia hisztogramm (mutat/elrejt) +HISTOGRAM_TOOLTIP_RAW;Raw hisztogram megjelenítése/elrejtése +HISTOGRAM_TOOLTIP_R;Piros csatorna hisztogrammja (mutat/elrejt) +HISTORY_CHANGED;Változott +HISTORY_CUSTOMCURVE;Saját görbe +HISTORY_DELSNAPSHOT;Töröl +HISTORY_FROMCLIPBOARD;Vágólapról +HISTORY_LABEL;Előzmények +HISTORY_MSG_1;Kép betöltve +HISTORY_MSG_2;Beállítások betöltése +HISTORY_MSG_3;Beállítások változtatása +HISTORY_MSG_4;Előzményböngészés +HISTORY_MSG_5;Fényerő +HISTORY_MSG_6;Kontraszt +HISTORY_MSG_7;Fekete szint +HISTORY_MSG_8;Expozíció kompenzáció +HISTORY_MSG_9;Világos tónusok tömörítése +HISTORY_MSG_10;Sötét tónusok tömörítése +HISTORY_MSG_11;Tónusgörbe +HISTORY_MSG_12;Auto szint +HISTORY_MSG_13;Vágás +HISTORY_MSG_14;Luminancia, fényerő +HISTORY_MSG_15;Luminancia, kontraszt +HISTORY_MSG_16;Luminancia, fekete szint +HISTORY_MSG_17;Luminancia, világos tónusok tömörítése +HISTORY_MSG_18;Luminancia, sötét tónusok tömörítése +HISTORY_MSG_19;Luminancia görbe +HISTORY_MSG_20;Élesítés +HISTORY_MSG_21;Élesítés sugara +HISTORY_MSG_22;Élesítés mértéke +HISTORY_MSG_23;Élesítési küszöb +HISTORY_MSG_24;Csak az élek élesítése +HISTORY_MSG_25;Élesítés élferismerési sugara +HISTORY_MSG_26;Élesítés élferismerési toleranciája +HISTORY_MSG_27;Élesítési mellékhatás csökkentése +HISTORY_MSG_28;Élesítési mellékhatás-csökkentés mértéke +HISTORY_MSG_29;Élesítés algoritmusa +HISTORY_MSG_30;Dekonvolúciós sugár +HISTORY_MSG_31;Deconvolúció mértéke +HISTORY_MSG_32;Deconvolúció zajelnyomása +HISTORY_MSG_33;Deconvolúció iterációszáma +HISTORY_MSG_34;Színtelítődés megelőzése +HISTORY_MSG_35;Telítettség-korlátozó +HISTORY_MSG_36;Telítettségi korlát +HISTORY_MSG_37;Színtelítettség +HISTORY_MSG_38;Fehéregyensúly beállítása +HISTORY_MSG_39;Színhőmérséklet +HISTORY_MSG_40;Fehér árnyalat +HISTORY_MSG_41;Színeltolás "A" +HISTORY_MSG_42;Színeltolás "B" +HISTORY_MSG_43;Luminanciazaj-csökkentés +HISTORY_MSG_44;Lum. zajcsökkentés sugara +HISTORY_MSG_45;Lum. zajcsökkentés éltoleranciája +HISTORY_MSG_46;Színzaj-csökkentés +HISTORY_MSG_47;Színzaj-csökkentés sugara +HISTORY_MSG_48;Színzaj-csökkentés éltoleranciája +HISTORY_MSG_49;Élérzékeny színzaj-csökkentés +HISTORY_MSG_50;Árnyékok/Fények korrekció +HISTORY_MSG_51;Fényes részek +HISTORY_MSG_52;Sötét részek +HISTORY_MSG_53;Világos tónustartomány +HISTORY_MSG_54;Sötét tónustartomány +HISTORY_MSG_55;Lokális kontraszt +HISTORY_MSG_56;Árnyékok/Fények sugár +HISTORY_MSG_57;Durva forgatás +HISTORY_MSG_58;Vízszintes tükrözés +HISTORY_MSG_59;Függőleges tükrözés +HISTORY_MSG_60;Forgatás +HISTORY_MSG_61;Forgatás +HISTORY_MSG_62;Torzításkorrekció +HISTORY_MSG_63;Pillanatkép kiválasztása +HISTORY_MSG_64;Képkivágás +HISTORY_MSG_65;Kromatikus aberráció korrekciója +HISTORY_MSG_66;Kiégett részek megmentése +HISTORY_MSG_67;Kiégett részek visszaállítása +HISTORY_MSG_68;Kiégett részek algoritmus +HISTORY_MSG_69;Feldolgozási (munka-) színprofil +HISTORY_MSG_70;Kimeneti színprofil +HISTORY_MSG_71;Bemeneti színprofil +HISTORY_MSG_72;Peremsötétedés +HISTORY_MSG_73;Színkeverő +HISTORY_MSG_74;Átméretezés szorzója +HISTORY_MSG_75;Átméretezés algoritmusa +HISTORY_MSG_76;EXIF Metaadatok +HISTORY_MSG_77;IPTC Metaadatok +HISTORY_MSG_78;Data specified for resize +HISTORY_MSG_79;Átméretezés szélesség szerint +HISTORY_MSG_80;Átméretezés magasság szerint +HISTORY_MSG_81;Átméretezés engedélyezve +HISTORY_MSG_82;Megváltozott profil +HISTORY_MSG_83;Árnyékok/csúcsfények - kiváló minőség +HISTORY_MSG_84;Perspektívakorrekció +HISTORY_MSG_85;Wavelet együtthatók +HISTORY_MSG_86;Wavelet equalizer +HISTORY_MSG_87;Salt&pepper zajcsökkentés +HISTORY_MSG_88;Salt&pepper NR küszöb +HISTORY_MSG_89;Zajcsökkentés (NR) +HISTORY_MSG_90;NR - luminanciazaj +HISTORY_MSG_91;NR - színzaj +HISTORY_MSG_92;NR - gamma +HISTORY_MSG_93;Kontraszt részletek szerint értéke +HISTORY_MSG_94;Kontraszt részletek szerint +HISTORY_MSG_95;Színtelítettség +HISTORY_MSG_96;'a' görbe +HISTORY_MSG_97;'b' görbe +HISTORY_MSG_98;Bayer-deinterpoláció +HISTORY_MSG_99;Előfeldolgozás +HISTORY_MSG_100;RGB színtelítettség +HISTORY_MSG_101;HSV EQ -- Árnyalat +HISTORY_MSG_102;HSV EQ -- Telítettség +HISTORY_MSG_103;HSV EQ -- Színérték +HISTORY_MSG_104;HSV Equalizer +HISTORY_MSG_105;Színihiba-javítás (defringing) +HISTORY_MSG_106;Színihiba-javítás sugara +HISTORY_MSG_107;Színihiba-javítás küszöbe +HISTORY_MSG_108;Csúcsfény-tömörítés küszöbe +HISTORY_MSG_109;Átméretezés határolókerete +HISTORY_MSG_110;Átméretezés +HISTORY_MSG_111;Színkiégés elkerülése +HISTORY_MSG_112;Telítettségkorlátozó +HISTORY_MSG_113;Telítettségkorlátozás +HISTORY_MSG_114;DCB ismétlések +HISTORY_MSG_115;Hamis szín ismétlések +HISTORY_MSG_116;Fejlesztett DCB +HISTORY_MSG_117;Vörös CA korrekció +HISTORY_MSG_118;Kék CA korrekció +HISTORY_MSG_119;Soronkénti zajszűrés +HISTORY_MSG_120;Zöldegyensúly-küszöb +HISTORY_MSG_121;Auto CA +HISTORY_MSG_122;Auto ref. feketekép (dark frame) +HISTORY_MSG_123;Ref. feketekép állománya +HISTORY_MSG_124;Lineáris exp. korrekció +HISTORY_MSG_125;Exp. korrekció csúcsfények megőrzésével +HISTORY_MSG_126;Flat Field állomány +HISTORY_MSG_127;Flat Field automatikus kivál. +HISTORY_MSG_128;Flat Field elmosás sugara +HISTORY_MSG_129;Flat Field elmosás típusa +HISTORY_MSG_130;Auto torzítás +HISTORY_MSG_131;Zajszűrés - luminencia +HISTORY_MSG_132;Zajszűrés - szín +HISTORY_MSG_133;Gamma +HISTORY_MSG_134;Gamma - Position +HISTORY_MSG_135;Gamma - szabad +HISTORY_MSG_136;Gamma - meredekség +HISTORY_MSG_137;Feketeszint - zöld 1 +HISTORY_MSG_138;Feketeszint - vörös +HISTORY_MSG_139;Feketeszint - kék +HISTORY_MSG_140;Feketeszint - zöld 2 +HISTORY_MSG_141;Feketeszint - zöldek együtt +HISTORY_MSG_142;Élek élesítése - smétlések +HISTORY_MSG_143;Élek élesítése - mérték +HISTORY_MSG_144;Mikrokontraszt - mérték +HISTORY_MSG_145;Mikrokontraszt - egységesség +HISTORY_MSG_146;Élek élesítése +HISTORY_MSG_147;Élek élesítése - csak luminencia +HISTORY_MSG_148;Mikrokontraszt +HISTORY_MSG_149;Mikrokontraszt - 3x3 mátrix +HISTORY_MSG_150;Interpoláció utáni műtermék-/zajcsökkentés +HISTORY_MSG_151;Vibrancia +HISTORY_MSG_152;Vibrancia - Pastel tones +HISTORY_MSG_153;Vibrancia - Telített árnyalatok +HISTORY_MSG_154;Vibrancia - Bőrtónusok védelme +HISTORY_MSG_155;Vibrancia - színeltolódás kivédése +HISTORY_MSG_156;Vibrancia - pasztell és telített árnyalatok kapcsolása +HISTORY_MSG_157;Vibrancia - pasztell/telített küszöb +HISTORY_MSG_158;Erősség +HISTORY_MSG_159;Megállás az éleknél +HISTORY_MSG_160;Skála +HISTORY_MSG_161;Újrasúlyozási ismétlések +HISTORY_MSG_162;Tónustérképezés +HISTORY_MSG_163;RGB görbék - R +HISTORY_MSG_164;RGB görbék - G +HISTORY_MSG_165;RGB görbék - B +HISTORY_MSG_166;Semleges szintek +HISTORY_NEWSNAPSHOT;Új +HISTORY_SNAPSHOTS;Pillanatképek +HISTORY_SNAPSHOT;Pillanatkép +IPTCPANEL_AUTHORSPOSITIONHINT;A kép létrehozójának munkaköre illetve titulusa (By-line Title) +IPTCPANEL_AUTHORSPOSITION;Szerző titulusa +IPTCPANEL_AUTHOR;Szerző +IPTCPANEL_CAPTIONHINT;A kép szöveges leírása (Caption - Abstract) +IPTCPANEL_CAPTIONWRITERHINT;A leírást és az adatok rögzítését/szerkesztését/javítását végző személy neve (Writer - Editor) +IPTCPANEL_CAPTIONWRITER;Író +IPTCPANEL_CAPTION;Leírás +IPTCPANEL_CATEGORYHINT;A kép témáját azonosítja (Category) +IPTCPANEL_CATEGORY;Kategória +IPTCPANEL_CITYHINT;A város, ahonnan a kép származik (City) +IPTCPANEL_CITY;Város +IPTCPANEL_COPYHINT;IPTC beállítások másolása a vágólapra +IPTCPANEL_COPYRIGHTHINT;Szerzői joggal kapcsolatos megjegyzések (Copyright Notice) +IPTCPANEL_COPYRIGHT;Szerzői jog +IPTCPANEL_COUNTRYHINT;Az ország, ahonnan a kép származik (Country - Primary Location Name) +IPTCPANEL_COUNTRY;Ország +IPTCPANEL_CREDITHINT;A kép kibocsájtójának neve (nem feltétlenül a szerző) (Credit) +IPTCPANEL_CREDIT;Rendelkező +IPTCPANEL_DATECREATEDHINT;A kép rögzítésének dátuma; formátum: ééééhhnn (Date Created) +IPTCPANEL_DATECREATED;Dátum +IPTCPANEL_EMBEDDEDHINT;A betöltött képbe ágyazott információk kiolvasása +IPTCPANEL_EMBEDDED;Beágyazott +IPTCPANEL_HEADLINEHINT;A kép témájának összegzése (Headline) +IPTCPANEL_HEADLINE;Főcím +IPTCPANEL_INSTRUCTIONSHINT;Egyéb, a képre vonatkozó szerkesztési útmutatás (Special Instructions) +IPTCPANEL_INSTRUCTIONS;Útmutatás +IPTCPANEL_KEYWORDSHINT;Kategorizáláshoz/szűréshez használatos, a képre vonatkozó kulcsszavak (Keywords) +IPTCPANEL_KEYWORDS;Kulcsszavak +IPTCPANEL_PASTEHINT;IPTC beállítások beillesztése a vágólapról +IPTCPANEL_PROVINCEHINT;A megye/állam/régió, ahonnan a kép származik (Province-State) +IPTCPANEL_PROVINCE;Régió +IPTCPANEL_RESETHINT;Visszatérés az aktuális profil alapértékéhez +IPTCPANEL_RESET;Visszaállítás +IPTCPANEL_SOURCEHINT;A kép szellemi tartalmának eredeti tulajdonosa (Source) +IPTCPANEL_SOURCE;Forrás +IPTCPANEL_SUPPCATEGORIESHINT;A kép finomabb, részletesebb kategorizálását teszi lehetővé (Supplemental Categories) +IPTCPANEL_SUPPCATEGORIES;További kategóriák +IPTCPANEL_TITLEHINT;A kép rövid azonosítója (Object Name) +IPTCPANEL_TITLE;Címke +IPTCPANEL_TRANSREFERENCEHINT;A továbbítás helyének megjelölése (Original Transmission Reference) +IPTCPANEL_TRANSREFERENCE;Továbbítás helye +MAIN_BUTTON_FULLSCREEN;Teljes képernyő +MAIN_BUTTON_PREFERENCES;Beállítások +MAIN_BUTTON_PUTTOQUEUE;Feldolgozási sorba helyez +MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Add hozzá a kiválasztott képet a feldolgozási sorhoz Ctrl+B +MAIN_BUTTON_SAVE;Kép mentése +MAIN_BUTTON_SAVE_TOOLTIP;Kiválasztott kép mentése Ctrl+S +MAIN_BUTTON_SENDTOEDITOR;Megnyitás külső programmal +MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Kiválasztott kép szerkesztése külső programmal Ctrl+E +MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Minden panel megjelenítése/elrejtése.\nGyorsbillentyű: m +MAIN_BUTTON_UNFULLSCREEN;Teljes képernyő elhagyása +MAIN_FRAME_BATCHQUEUE;Kötegelt feldolgozási sor +MAIN_FRAME_BATCHQUEUE_TOOLTIP; Feldolgozási sor.\nGyorsbillentyű: Ctrl-F3 +MAIN_FRAME_EDITOR;Szerkesztő +MAIN_FRAME_EDITOR_TOOLTIP; Szerkesztő.\nGyorsbillentyű: Ctrl-F4 +MAIN_FRAME_FILEBROWSER;Állományböngésző +MAIN_FRAME_FILEBROWSER_TOOLTIP; Állományböngésző.\nGyorsbillentyű: Ctrl-F2 +MAIN_FRAME_PLACES;Helyek +MAIN_FRAME_PLACES_ADD;Hozzáadás +MAIN_FRAME_PLACES_DEL;Törlés +MAIN_FRAME_RECENT;Legutóbbi könyvtárak +MAIN_MSG_ALREADYEXISTS;Ilyen nevű állomány már létezik! +MAIN_MSG_CANNOTLOAD;A képet nem sikerült betölteni. +MAIN_MSG_CANNOTSAVE;Hiba történt az állomány mentése közben! +MAIN_MSG_CANNOTSTARTEDITOR;A megadott külső program nem indítható. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Állítsa be a helyes elérési utat a "Beállítások" ablakban. +MAIN_MSG_EMPTYFILENAME;Üres állománynév +MAIN_MSG_NAVIGATOR;Navigátor +MAIN_MSG_QOVERWRITE;Felülírjam? +MAIN_TAB_COLOR;Színek +MAIN_TAB_COLOR_TOOLTIP;Gyorsbillentyű: Alt-C +MAIN_TAB_DETAIL;Részletek +MAIN_TAB_DETAIL_TOOLTIP;Gyorsbillentyű: Alt-D +MAIN_TAB_DEVELOP;Kidolgozás +MAIN_TAB_EXIF;EXIF +MAIN_TAB_EXPORT; Exportálás +MAIN_TAB_EXPOSURE;Expozíció +MAIN_TAB_EXPOSURE_TOOLTIP;Gyorsbillentyű: Alt-E +MAIN_TAB_FILTER;Szűrők +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metaadatok +MAIN_TAB_METADATA_TOOLTIP;Gyorsbillentyű: Alt-M +MAIN_TAB_RAW;Raw +MAIN_TAB_RAW_TOOLTIP;Gyorsbillentyű: Alt-R +MAIN_TAB_TRANSFORM;Transzformáció +MAIN_TAB_TRANSFORM_TOOLTIP;Gyorsbillentyű: Alt-T +MAIN_TOOLTIP_BEFOREAFTERLOCK;Zárolás / Feloldás az Előtte nézetben\n\nZárolás: az Előtte nézet változatlanul tartása.\nHasznos több eszköz összeadódó hatásának megítélésére.\nSegítségével az előzményekben szereplő bármely állapot összehasonlítható a zárolttal.\n\nFeloldás: az Előtte nézet egy lépéssel követi az Utánanézetet, vagyis a legutoljára használt eszköz előtti állapotot mutatja. +MAIN_TOOLTIP_HIDEHP;Az előzményeket is tartalmazó bal panel elrejtése/megjelenítése (Gyorsbillentyű: H) +MAIN_TOOLTIP_INDCLIPPEDH;Túlexponált területek jelzése +MAIN_TOOLTIP_INDCLIPPEDS;Alulexponált területek jelzése +MAIN_TOOLTIP_PREVIEWB;A kék csatorna előnézete.\nGyorsbillentyű: b +MAIN_TOOLTIP_PREVIEWFOCUSMASK;A fókuszmaszk előnézete.\nGyorsbillentyű: Shift-F\n\nPontosabb a kis mélységélességű, alacsony zajú és erősebben zoomolt képeken.\n\nA felismerés pontosságának növeléséhez használd az eszközt 10-30%-os nagyítás mellett.\n\nAz előnézet frissítése bekapcsolt fókuszmaszk mellett lassabb. +MAIN_TOOLTIP_PREVIEWG;A Green csatorna előnézete.\nGyorsbillentyű: g +MAIN_TOOLTIP_PREVIEWL;A luminencia (luminosity) előnézete.\nGyorsbillentyű: v\n\n0.299*R + 0.587*G + 0.114*B +MAIN_TOOLTIP_PREVIEWR;A vörös csatorna előnézete.\nGyorsbillentyű: r +MAIN_TOOLTIP_QINFO;Néhány fontos információ megjelenítése a képről +MAIN_TOOLTIP_SHOWHIDELP1;Bal oldali panel megjelenítése/elrejtése.\nGyorsbillentyű: l +MAIN_TOOLTIP_SHOWHIDERP1;Jobb oldali panel megjelenítése/elrejtése.\nGyorsbillentyű: Alt-L +MAIN_TOOLTIP_SHOWHIDETP1;Felső panel megjelenítése/elrejtése.\nGyorsbillentyű: Shift-L +MAIN_TOOLTIP_THRESHOLD;Küszöb +MAIN_TOOLTIP_TOGGLE;Előtte/utána nézet be- és kikapcsolása B +NAVIGATOR_XY_NA;x = n/a, y = n/a +PARTIALPASTE_BASICGROUP;Alapbeállítások +PARTIALPASTE_CACORRECTION;Kromatikus aberráció +PARTIALPASTE_CHANNELMIXER;Színkeverő +PARTIALPASTE_COARSETRANS;90 fokonkénti forgatás/tükrözés +PARTIALPASTE_COLORGROUP;Színeket érintő beállítások +PARTIALPASTE_COMMONTRANSFORMPARAMS;Automatikus bejelölés +PARTIALPASTE_COMPOSITIONGROUP;Kompozíciós beállítások +PARTIALPASTE_CROP;Vágás +PARTIALPASTE_DARKFRAMEAUTOSELECT;Referencia feketekép (dark frame) automatikus kiválasztása +PARTIALPASTE_DARKFRAMEFILE;Referencia feketekép (dark frame) állomány +PARTIALPASTE_DEFRINGE;Színihiba-javítás (defringe) +PARTIALPASTE_DETAILGROUP;Képrészlet-beállítások +PARTIALPASTE_DIALOGLABEL;Feldolgozási beállítások részleges alkalmazása +PARTIALPASTE_DIRPYRDENOISE;Zajszűrés +PARTIALPASTE_DIRPYREQUALIZER;Kontraszt részletek szerint +PARTIALPASTE_DISTORTION;Torzítás +PARTIALPASTE_EPD;Tónustérképezés +PARTIALPASTE_EVERYTHING;Minden +PARTIALPASTE_EXIFCHANGES;EXIF változtatások +PARTIALPASTE_EXPOSURE;Expozíció +PARTIALPASTE_FLATFIELDAUTOSELECT;FF automatikus kiválasztása +PARTIALPASTE_FLATFIELDBLURRADIUS;FF elmosás sugara +PARTIALPASTE_FLATFIELDBLURTYPE;FF elmosás típusa +PARTIALPASTE_FLATFIELDFILE;Flat field (FF) állomány +PARTIALPASTE_HSVEQUALIZER;HSV Equalizer +PARTIALPASTE_ICMGAMMA;Kimeneti gamma +PARTIALPASTE_ICMSETTINGS;ICM beállítások +PARTIALPASTE_IMPULSEDENOISE;Impulse zajszűrés +PARTIALPASTE_IPTCINFO;IPTC információk +PARTIALPASTE_LABCURVE;Lab görbe +PARTIALPASTE_LENSGROUP;Objektív optikai hibáinak javítása +PARTIALPASTE_METAGROUP;Metaadat +PARTIALPASTE_PERSPECTIVE;Perspektíva +PARTIALPASTE_PREPROCESS_GREENEQUIL;Zöldegyensúly +PARTIALPASTE_PREPROCESS_LINEDENOISE;Soronkénti zajszűrés +PARTIALPASTE_RAWCACORR_AUTO;CA autokorrekció +PARTIALPASTE_RAWCACORR_CABLUE;CA kék +PARTIALPASTE_RAWCACORR_CARED;CA vörös +PARTIALPASTE_RAWEXPOS_BLACK;Feketeszint +PARTIALPASTE_RAWEXPOS_LINEAR;Raw fehérszint lineáris korrekciós faktor (FÉ) +PARTIALPASTE_RAWEXPOS_PRESER;Raw fehérszint csúcsfény-megőrző faktor (FÉ) +PARTIALPASTE_RAWGROUP;Raw beállítások +PARTIALPASTE_RAW_DCBENHANCE;DCB javítási lépés alkalmazása +PARTIALPASTE_RAW_DCBITERATIONS;DCB iterációk száma +PARTIALPASTE_RAW_DMETHOD;Interpoláció algoritmusa +PARTIALPASTE_RAW_FALSECOLOR;Interpolációs hamis szín javítási lépések +PARTIALPASTE_RESIZE;Átméretezés +PARTIALPASTE_RGBCURVES;RGB görbék +PARTIALPASTE_ROTATION;Forgatás +PARTIALPASTE_SHADOWSHIGHLIGHTS;Árnyékos/Világos részek +PARTIALPASTE_SHARPENEDGE;Élek +PARTIALPASTE_SHARPENING;Élesítés +PARTIALPASTE_SHARPENMICRO;Mikrokontraszt +PARTIALPASTE_VIBRANCE;Vibrancia +PARTIALPASTE_VIGNETTING;Peremsötétedés +PARTIALPASTE_WHITEBALANCE;Fehéregyensúly +PREFERENCES_ADD;Hozzáadás +PREFERENCES_APPLNEXTSTARTUP;újraindítás után érvényes +PREFERENCES_AUTOMONPROFILE;Oprendszerben beállított monitor-színprofil automatikus használata +PREFERENCES_BATCH_PROCESSING;Kötegelt feldolgozás +PREFERENCES_BEHAVIOR;Viselkedés +PREFERENCES_CACHECLEARALL;Teljes gyorsítótár törlése +PREFERENCES_CACHECLEARPROFILES;Feldolg. param. törlése +PREFERENCES_CACHECLEARTHUMBS;Előnézeti képek törlése +PREFERENCES_CACHEMAXENTRIES;Gyorsítótárban tárolt képek max. száma +PREFERENCES_CACHEOPTS;Gyorsítótár beállítások +PREFERENCES_CACHETHUMBHEIGHT;Előnézeti kép maximális magassága +PREFERENCES_CLIPPINGIND;Kiégett és bebukott részek jelzése +PREFERENCES_CMETRICINTENT;Intent +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_CUSTPROFBUILD;Egyedi profil készítő +PREFERENCES_CUTOVERLAYBRUSH;Vágás maszkjának színe/áttetszősége +PREFERENCES_DARKFRAMEFOUND;Találat +PREFERENCES_DARKFRAMESHOTS;kép +PREFERENCES_DARKFRAMETEMPLATES;sablonok +PREFERENCES_DARKFRAME;Fekete referenciakép (dark frame) +PREFERENCES_DATEFORMATHINT;A következő jeleket lehet használni:\n%y : év\n%m : hónap\n%d : nap\n\nPéldául a magyar dátumformátum:\n%y/%m/%d +PREFERENCES_DATEFORMAT;Dátumformátum +PREFERENCES_DEFAULTLANG;Alapértelmezett nyelv +PREFERENCES_DEFAULTTHEME;Alapértelmezett kinézet +PREFERENCES_DIRDARKFRAMES;Dark frame könyvtára +PREFERENCES_DIRHOME;Saját könyvtár +PREFERENCES_DIRLAST;Utoljára látogatott könyvtár +PREFERENCES_DIROTHER;Más +PREFERENCES_DIRSELECTDLG;Képek könyvtára induláskor... +PREFERENCES_DIRSOFTWARE;Telepítés helye +PREFERENCES_EDITORCMDLINE;Egyéb parancssor +PREFERENCES_EDITORLAYOUT;Szerkesztési mód +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_FLATFIELDFOUND;Találat +PREFERENCES_FLATFIELDSDIR;Flat Fields könyvtár +PREFERENCES_FLATFIELDSHOTS;kép +PREFERENCES_FLATFIELDTEMPLATES;sablonok +PREFERENCES_FLATFIELD;Flat Field +PREFERENCES_FORIMAGE;Egyéb képekhez +PREFERENCES_FORRAW;RAW állományokhoz +PREFERENCES_GIMPPATH;GIMP telepítési könyvtára +PREFERENCES_HISTOGRAMPOSITIONLEFT;Hisztogram a bal oldali panelen +PREFERENCES_HLTHRESHOLD;Küszöbérték kiégett területekhez +PREFERENCES_ICCDIR;ICC profilok könyvtára +PREFERENCES_IMPROCPARAMS;Alapértelmezett feldolgozási paraméterek +PREFERENCES_INTENT_ABSOLUTE;Abszolút kolorimetrikus +PREFERENCES_INTENT_PERCEPTUAL;Perceptuális +PREFERENCES_INTENT_RELATIVE;Relatív kolorimetrikus +PREFERENCES_INTENT_SATURATION;Színtelítettség +PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Nyers beágyazott előnézeti kép megjelenése, amíg szerkesztetlen a kép +PREFERENCES_LANGAUTODETECT;Oprendszer nyelvének használata +PREFERENCES_MENUGROUPFILEOPERATIONS;Állományműveletek csoportosítása +PREFERENCES_MENUGROUPLABEL;Címkézés csoportosítása +PREFERENCES_MENUGROUPPROFILEOPERATIONS;Profilműveletek csoportosítása +PREFERENCES_MENUGROUPRANK;Értékelés csoportosítása +PREFERENCES_MENUOPTIONS;Menübeállítások +PREFERENCES_METADATA;Metaadatok +PREFERENCES_MONITORICC;Monitor ICC profilja +PREFERENCES_MULTITABDUALMON;Több fül mód második kijelzővel (ha elérhető) +PREFERENCES_MULTITAB;Több szerkesztőfül +PREFERENCES_OUTDIRFOLDERHINT;Ha ezt a lehetőséget választja, az összes feldolgozott kép ebbe a könyvtárba kerül +PREFERENCES_OUTDIRFOLDER;Mentés ebbe a könyvtárba: +PREFERENCES_OUTDIRTEMPLATEHINT;A következő jeleket lehet használni:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nEzek a jelek a megnyitott kép elérési útvonalának részeire vonatkoznak.\n\nPéldául, ha a /home/tom/image/02-09-2006/dsc0012.nef képet nyitjuk meg, ezek a jelek a következőket jelentik:\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\nHa oda kívánja menteni a kész képet, ahol az eredeti volt, az alábbiakat kell beírni:\n%p1/%f\n\nHa a kész képet az eredeti könyvtárán belül egy "converted" alkönyvtárba kívánja menteni, az alábbiakat kell beírni:\n%p1/converted/%f\n\nHa a kész képeket a '/home/tom/converted' könyvtárba kívánja menteni az eredeti, dátumot tartalmazó alkönyvtár megtartásával, írja ezt:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Sablon használata +PREFERENCES_OUTDIR;Kimeneti alapértelmezett könyvtár +PREFERENCES_OVERLAY_FILENAMES;Állománynevek megjelenítése az előnézeti képeken +PREFERENCES_OVERWRITEOUTPUTFILE;A már létező kimeneti állományok felülírása +PREFERENCES_PANFACTORLABEL;Faktor +PREFERENCES_PARSEDEXTADDHINT;A kiterjesztés beírása után ez a gomb felveszi a listára +PREFERENCES_PARSEDEXTADD;Kiterjesztés hozzáadása +PREFERENCES_PARSEDEXTDELHINT;A kiválasztott sor törlése a listából +PREFERENCES_PARSEDEXT;Felismert kiterjesztések +PREFERENCES_PROFILEHANDLING;Feldolgozási paraméterek kezelése +PREFERENCES_PROFILELOADPR;Ha mindkét helyen van feldolgozási paraméter +PREFERENCES_PROFILEPRCACHE;A gyorsítótárban lévőt használja +PREFERENCES_PROFILEPRFILE;A kép mellettit használja +PREFERENCES_PROFILESAVECACHE;Feldolgozási paraméterek mentése a gyorsítótárba +PREFERENCES_PROFILESAVEINPUT;Feldolgozási paraméterek mentése a kép mellé +PREFERENCES_PROPERTY;Property +PREFERENCES_PSPATH;Adobe Photoshop telepítési könyvtára +PREFERENCES_SELECTFONT;Betűtípus kiválasztása +PREFERENCES_SELECTLANG;Nyelv kiválasztása +PREFERENCES_SELECTTHEME;Kinézet kiválasztása +PREFERENCES_SET;Beállítás +PREFERENCES_SHOWBASICEXIF;Fontosabb EXIF információk megjelenítése +PREFERENCES_SHOWDATETIME;Felvétel dátumának és idejének megjelenítése +PREFERENCES_SHOWEXPOSURECOMPENSATION;Expozíciókompenzáció megjelenítése +PREFERENCES_SHTHRESHOLD;Küszöbérték bebukott árnyékokhoz +PREFERENCES_SINGLETABVERTAB;Egyetlen fül mód, függőleges előnézeti képek +PREFERENCES_SINGLETAB;Egyetlen szerkesztőfül +PREFERENCES_SLIMUI;Karcsú felület +PREFERENCES_SND_BATCHQUEUEDONE;Feldolgozási sor végén +PREFERENCES_SND_HELP;Állomány elérése, vagy hagyd üresen (ekkor nincs hang). Windows-on használd a "SystemDefault", "SystemAsterisk", stb. stringeket a rendszerhangokhoz. +PREFERENCES_SND_LNGEDITPROCDONE;Amikor a képszerkesztés végződik +PREFERENCES_SND_TRESHOLDSECS;másodperc után +PREFERENCES_STARTUPIMDIR;Képek könyvtára induláskor +PREFERENCES_TAB_BROWSER;Fájl böngésző +PREFERENCES_TAB_COLORMGR;Színkezelés +PREFERENCES_TAB_GENERAL;Általános +PREFERENCES_TAB_IMPROC;Képfeldolgozás +PREFERENCES_TAB_SOUND;Hangok +PREFERENCES_TP_LABEL;Eszközök panel: +PREFERENCES_TP_USEICONORTEXT;Ikonok használata szöveg helyett a füleken +PREFERENCES_TP_VSCROLLBAR;Függőleges görgetősáv elrejtése +PREFERENCES_TUNNELMETADATA;IPTC/XMP adatok változatlan átmentése a kimeneti állományba (pl. más programmal való címkézéskor) +PREFERENCES_USESYSTEMTHEME;Rendszer megjelenésének használata +PREFERENCES_WORKFLOW;Munkamenet +PROFILEPANEL_COPYPPASTE;Másolandó paraméterek +PROFILEPANEL_LABEL;Feldolgozási beállítások +PROFILEPANEL_LOADDLGLABEL;Feldolgozási beállítások betöltése... +PROFILEPANEL_LOADPPASTE;Betöltendő paraméterek +PROFILEPANEL_PASTEPPASTE;Beillesztendő paraméterek +PROFILEPANEL_PCUSTOM;Egyedi +PROFILEPANEL_PFILE;Fáljból +PROFILEPANEL_PLASTSAVED;Legutóbb használt +PROFILEPANEL_SAVEDLGLABEL;Feldolgozási beállítások mentése... +PROFILEPANEL_SAVEPPASTE;Mentendő paraméterek +PROFILEPANEL_TOOLTIPCOPY;Feldolgozási beállítások vágólapra mentése +PROFILEPANEL_TOOLTIPLOAD;Feldolgozási beállítások betöltése +PROFILEPANEL_TOOLTIPPASTE;Feldolgozási beállítások beillesztése a vágólapról +PROFILEPANEL_TOOLTIPSAVE;Feldolgozási beállítások mentése +PROGRESSBAR_LOADINGTHUMBS;Előnézeti képek betöltése... +PROGRESSBAR_LOADING;Kép betöltése... +PROGRESSBAR_LOADJPEG;JPEG fájl betöltése... +PROGRESSBAR_LOADPNG;PNG fájl betöltése... +PROGRESSBAR_LOADTIFF;TIFF fájl betöltése... +PROGRESSBAR_PROCESSING;Kép feldolgozása... +PROGRESSBAR_READY;Kész +PROGRESSBAR_SAVEJPEG;JPEG fájl mentése... +PROGRESSBAR_SAVEPNG;PNG fájl mentése... +PROGRESSBAR_SAVETIFF;TIFF fájl mentése... +PROGRESSDLG_PROFILECHANGEDINBROWSER;A profil az állományböngészőben megváltozott +QINFO_ISO;ISO +QINFO_NOEXIF;EXIF adat nem áll rendelkezésre. +SAVEDLG_AUTOSUFFIX;Utótag hozzáadása automatikusan, ha az állomány már létezik +SAVEDLG_FILEFORMAT;Állományformátum +SAVEDLG_JPEGQUAL;JPEG Minőség +SAVEDLG_PNGCOMPR;PNG Tömörítés +SAVEDLG_PUTTOQUEUEHEAD;Feldolgozási sorba helyezés az első helyre +SAVEDLG_PUTTOQUEUETAIL;Feldolgozási sorba helyezés az utolsó helyre +SAVEDLG_PUTTOQUEUE;Feldolgozási sorba helyezés +SAVEDLG_SAVEIMMEDIATELY;Mentés azonnal +SAVEDLG_SAVESPP;Feldolgozási paraméterek mentése a kép mellé +SAVEDLG_TIFFUNCOMPRESSED;Tömörítetlen TIFF +TOOLBAR_TOOLTIP_CROP;Vágás (Gyorsbillentyű: C) +TOOLBAR_TOOLTIP_HAND;"Kéz" eszköz (Gyorsbillentyű: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;Vízszintes/függőleges vonal kijelölése (Gyorsbillentyű: S) +TOOLBAR_TOOLTIP_WB;Fehéregyensúly kijelölés (Gyorsbillentyű: W) +TP_CACORRECTION_BLUE;Kék +TP_CACORRECTION_LABEL;Kromatikus aberráció +TP_CACORRECTION_RED;Vörös +TP_CHMIXER_BLUE;Kék +TP_CHMIXER_GREEN;Zöld +TP_CHMIXER_LABEL;Színkeverő +TP_CHMIXER_RED;Piros +TP_CHROMATABERR_LABEL;Színihiba (kromatikus aberráció) +TP_COARSETRAF_TOOLTIP_HFLIP;Vizszintes tükrözés +TP_COARSETRAF_TOOLTIP_ROTLEFT;Forgatás balra +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Forgatás jobbra +TP_COARSETRAF_TOOLTIP_VFLIP;Függőleges tükrözés +TP_CROP_FIXRATIO;Rögzített oldalarány +TP_CROP_GTDIAGONALS;Diagonál módszer +TP_CROP_GTEPASSPORT;Biometric Passport +TP_CROP_GTGRID;Rács +TP_CROP_GTNONE;Nincs +TP_CROP_GTRULETHIRDS;Harmadolás +TP_CROP_GUIDETYPE;Segédvonal típusa: +TP_CROP_H;M +TP_CROP_LABEL;Kivágás +TP_CROP_PPI;PPI= +TP_CROP_SELECTCROP; Kijelölés egérrel +TP_CROP_W;Sz +TP_CROP_X;x +TP_CROP_Y;y +TP_DARKFRAME_AUTOSELECT;Auto selection +TP_DARKFRAME_LABEL;Fekete referenciakép (dark frame) +TP_DEFRINGE_LABEL;Színihiba-javítás (defringe) +TP_DEFRINGE_RADIUS;Sugár +TP_DEFRINGE_THRESHOLD;Küszöb +TP_DIRPYRDENOISE_CHROMA;Színzaj +TP_DIRPYRDENOISE_GAMMA;Gamma +TP_DIRPYRDENOISE_LABEL;Zajcsökkentés +TP_DIRPYRDENOISE_LUMA;Luminancia +TP_DIRPYREQUALIZER_LABEL;Kontraszt részletek szerint +TP_DIRPYREQUALIZER_LUMACOARSEST;Durva részletek +TP_DIRPYREQUALIZER_LUMACONTRAST_MINUS;Kontraszt- +TP_DIRPYREQUALIZER_LUMACONTRAST_PLUS;Kontraszt+ +TP_DIRPYREQUALIZER_LUMAFINEST;Finom részletek +TP_DIRPYREQUALIZER_LUMANEUTRAL;Semleges +TP_DIRPYREQUALIZER_THRESHOLD;Küszöb +TP_DISTORTION_AMOUNT;Erősség +TP_DISTORTION_AUTO; Automatikus torzításhelyreállítás +TP_DISTORTION_AUTO_TIP;(Kísérleti) Objektív torzításának automatikus helyreállítása egyes fényképezőgépeknél (pl. M4/3, néhány digitális kompakt, stb...) +TP_DISTORTION_LABEL;Torzítás +TP_EPD_EDGESTOPPING;Éleknél megállás +TP_EPD_LABEL;Tónustérképezés +TP_EPD_REWEIGHTINGITERATES;Újrasúlyozási ismétlések +TP_EPD_SCALE;Skála +TP_EPD_STRENGTH;Erősség +TP_EXPOSURE_AUTOLEVELS;Auto szint +TP_EXPOSURE_AUTOLEVELS_TIP;Az automatikus szintek ki/bekapcsolása, mely a kép elemzése alapján állítja be a paramétereket +TP_EXPOSURE_BLACKLEVEL;Feketeszint +TP_EXPOSURE_BRIGHTNESS;Fényerő +TP_EXPOSURE_CLIP;Vágás +TP_EXPOSURE_CLIP_TIP;Automatikus szintek meghatározásához a kiégett pixelek aránya +TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Csúcsfények helyreállításának küszöbe +TP_EXPOSURE_COMPRHIGHLIGHTS;Világos tónusok tömörítése +TP_EXPOSURE_COMPRSHADOWS;Sötét tónusok tömörítése +TP_EXPOSURE_CONTRAST;Kontraszt +TP_EXPOSURE_CURVEEDITOR;Tónusgörbe +TP_EXPOSURE_EXPCOMP;Exp. Kompenzáció +TP_EXPOSURE_LABEL;Expozíció +TP_EXPOSURE_SATURATION;Színtelítettség +TP_FLATFIELD_AUTOSELECT;Automatikus választás +TP_FLATFIELD_BLURRADIUS;Elmosás sugara +TP_FLATFIELD_BLURTYPE;Elmosás típusa +TP_FLATFIELD_BT_AREA;Terület +TP_FLATFIELD_BT_HORIZONTAL;Vízszintes +TP_FLATFIELD_BT_VERTHORIZ;Függ. + vízsz. +TP_FLATFIELD_BT_VERTICAL;Függőleges +TP_FLATFIELD_LABEL;Flat Field +TP_GAMMA_CURV;gamma +TP_GAMMA_FREE;Szabad gamma +TP_GAMMA_OUTPUT;Kimeneti gamma +TP_GAMMA_SLOP;meredekség (lineáris) +TP_HLREC_BLEND;Egybemosás +TP_HLREC_CIELAB;CIELab visszaállítás +TP_HLREC_COLOR;Színterjesztés +TP_HLREC_LABEL;Kiégett részletek megmentése +TP_HLREC_LUMINANCE;Luminancia +TP_HLREC_METHOD;Preferencia: +TP_HSVEQUALIZER_CHANNEL;HSV Csatorna +TP_HSVEQUALIZER_HUE;Színárnyalat +TP_HSVEQUALIZER_LABEL;HSV Equalizer +TP_HSVEQUALIZER_SAT;Színtelítettség +TP_HSVEQUALIZER_VAL;Színérték +TP_ICM_BLENDCMSMATRIX;Csúcsfények és mátrix egybemosása +TP_ICM_BLENDCMSMATRIX_TOOLTIP;Kiégett csúcsfények helyrehozásának engedélyezése LUT-alapú ICC profilok használatánál +TP_ICM_INPUTCAMERAICC;Fényképezőgép-specifikus színprofil +TP_ICM_INPUTCAMERAICC_TOOLTIP;A RawTherapee saját, fényképezőgép-specifikus színprofiljainak használata bemeneti profilként. Ez a profil pontosabb az egyszerű mátrixnál, és ha a fényképezőgéphez van elérhető színprofil az iccprofiles/input könyvtárban, akkor azt a RawTherapee a fényképezőgép típus és az állománynév pontos egyezése esetén automatikusan be fogja tölteni. +TP_ICM_INPUTCAMERA;Fényképezőgép alapértelmezése +TP_ICM_INPUTCAMERA_TOOLTIP;A dcraw-ból származó, továbfejlesztett, egyszerű, a fényképezőgép típusa alapján meghatározott, vagy a DNG állományokba beágyazott színmátrix használata bemeneti színprofilként. +TP_ICM_INPUTCUSTOM;Saját +TP_ICM_INPUTCUSTOM_TOOLTIP;A kamerához tartozó saját bemeneti DCP/ICC profil kiválasztása +TP_ICM_INPUTDLGLABEL;Bemeneti színprofil kiválasztása... +TP_ICM_INPUTEMBEDDED;Beágyazott profil, ha van +TP_ICM_INPUTEMBEDDED_TOOLTIP;A raw állományokba ágyazott színprofil használata bemeneti színprofilként. +TP_ICM_INPUTNONE;Profil mellőzése +TP_ICM_INPUTNONE_TOOLTIP;Bemeneti színprofil teljes mellőzése. Csak különleges esetekben használandó. +TP_ICM_INPUTPROFILE;Bemeneti színprofil +TP_ICM_LABEL;ICM +TP_ICM_NOICM;Nincs színkezelés: sRGB kimenet +TP_ICM_OUTPUTPROFILE;Kimeneti színprofil +TP_ICM_SAVEREFERENCE;Referenciakép mentése profilkalibráláshoz +TP_ICM_WORKINGPROFILE;Feldolgozási színprofil +TP_IMPULSEDENOISE_LABEL;Pontzaj-csökkentés +TP_IMPULSEDENOISE_THRESH;Küszöb +TP_LABCURVE_BRIGHTNESS;Világosság +TP_LABCURVE_CONTRAST;Kontraszt +TP_LABCURVE_CURVEEDITOR;Luminanciagörbe +TP_LABCURVE_LABEL;Lab görbék +TP_LENSGEOM_AUTOCROP;Automatikus vágás +TP_LENSGEOM_FILL;Automatikus kitöltés +TP_LENSGEOM_LABEL;Objektív / Geometria +TP_NEUTRAL;Semleges +TP_NEUTRAL_TIP;Expozíciós paraméterek visszaállítása a semleges értékre +TP_PERSPECTIVE_HORIZONTAL;Vízszintes +TP_PERSPECTIVE_LABEL;Perspektíva +TP_PERSPECTIVE_VERTICAL;Függőleges +TP_PREPROCESS_GREENEQUIL;Zöldegyensúly +TP_PREPROCESS_LABEL;Előfeldolgozás +TP_PREPROCESS_LINEDENOISE;Sorzaj-szűrő +TP_PREPROCESS_NO_FOUND;Nincs elérhető +TP_RAWCACORR_AUTO;Színihiba (kromatikus aberráció) automatikus helyesbítése +TP_RAWCACORR_CABLUE;Kék +TP_RAWCACORR_CARED;Vörös +TP_RAWEXPOS_BLACKS;Feketeszintek +TP_RAWEXPOS_LINEAR;Fehérszint: lineáris korrelációs faktor +TP_RAWEXPOS_PRESER;Fehérszint: csúcsfény-megőrző korrekció (FÉ) +TP_RAWEXPOS_TWOGREEN;Zöldek együtt +TP_RAW_DCBENHANCE;DCB helyesbítő lépés alkalmazása +TP_RAW_DCBITERATIONS;DCB iterációk száma +TP_RAW_DMETHOD;Algoritmus +TP_RAW_FALSECOLOR;Színhiba-elnyomási lépések +TP_RAW_LABEL;Deinterpoláció +TP_RESIZE_APPLIESTO;Érvényesség: +TP_RESIZE_CROPPEDAREA;Vágott terület +TP_RESIZE_FITBOX;Határolókeret +TP_RESIZE_FULLIMAGE;Teljes kép +TP_RESIZE_HEIGHT;Magasság +TP_RESIZE_H;M: +TP_RESIZE_LABEL;Átméretezés +TP_RESIZE_LANCZOS;Lanczos +TP_RESIZE_METHOD;Algoritmus: +TP_RESIZE_NEAREST;Legközelebbi szomszéd +TP_RESIZE_SCALE;Szorzó +TP_RESIZE_SPECIFY;Egyedi: +TP_RESIZE_WIDTH;Szélesség +TP_RESIZE_W;Sz: +TP_RGBCURVES_BLUE;B +TP_RGBCURVES_CHANNEL;Csatorna +TP_RGBCURVES_GREEN;G +TP_RGBCURVES_LABEL;RGB görbék +TP_RGBCURVES_RED;R +TP_ROTATE_DEGREE;Fok +TP_ROTATE_LABEL;Forgatás +TP_ROTATE_SELECTLINE; Vízszintes vonal kijelölése +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Csúcsfények +TP_SHADOWSHLIGHTS_HLTONALW;Csúcsfények tónustartománya +TP_SHADOWSHLIGHTS_LABEL;Árnyékok/Csúcsfények +TP_SHADOWSHLIGHTS_LOCALCONTR;Lokális kontraszt +TP_SHADOWSHLIGHTS_RADIUS;Sugár +TP_SHADOWSHLIGHTS_SHADOWS;Árnyékok +TP_SHADOWSHLIGHTS_SHTONALW;Árnyékok tónustartománya +TP_SHARPENEDGE_AMOUNT;Élek élesítésének mértéke +TP_SHARPENEDGE_LABEL;Élek +TP_SHARPENEDGE_PASSES;Ismétlések száma +TP_SHARPENEDGE_THREE;Csak luminencia +TP_SHARPENING_AMOUNT;Erősség +TP_SHARPENING_EDRADIUS;Sugár +TP_SHARPENING_EDTOLERANCE;Éltolerancia +TP_SHARPENING_HALOCONTROL;Mellékhatás-csökkentés +TP_SHARPENING_HCAMOUNT;Mértéke +TP_SHARPENING_LABEL;Élesítés +TP_SHARPENING_METHOD;Algoritmus +TP_SHARPENING_ONLYEDGES;Csak az élek élesítése +TP_SHARPENING_RADIUS;Sugár +TP_SHARPENING_RLD;RL Dekonvolúció +TP_SHARPENING_RLD_AMOUNT;Erősség +TP_SHARPENING_RLD_DAMPING;Zajelnyomás +TP_SHARPENING_RLD_ITERATIONS;Iterációszám +TP_SHARPENING_THRESHOLD;Küszöb +TP_SHARPENING_USM;Unsharp Mask +TP_SHARPENMICRO_AMOUNT;Mikrokontraszt mértéke +TP_SHARPENMICRO_LABEL;Mikrokontraszt +TP_SHARPENMICRO_MATRIX;3×3 mátrix az 5×5-ös helyett +TP_SHARPENMICRO_UNIFORMITY;Egységesség +TP_VIBRANCE_AVOIDCOLORSHIFT;Színeltolódás kiküszöbölése +TP_VIBRANCE_LABEL;Vibrancia +TP_VIBRANCE_PASTELS;Pasztell árnyalatok +TP_VIBRANCE_PASTSATTOG;Pasztell és telített árnyalatok kapcsolása +TP_VIBRANCE_PROTECTSKINS;Bőrtónusok védelme +TP_VIBRANCE_PSTHRESHOLD;Pasztell/Telített árnyalatok küszöbe +TP_VIBRANCE_SATURATED;Telített árnyalatok +TP_VIGNETTING_AMOUNT;Mérték +TP_VIGNETTING_CENTER;Középpont +TP_VIGNETTING_CENTER_X;Középpont X +TP_VIGNETTING_CENTER_Y;Középpont Y +TP_VIGNETTING_LABEL;Peremsötétedés +TP_VIGNETTING_RADIUS;Sugár +TP_VIGNETTING_STRENGTH;Erősség +TP_WBALANCE_AUTO;Automatikus +TP_WBALANCE_CAMERA;Tárolt +TP_WBALANCE_CLOUDY;Felhős +TP_WBALANCE_CUSTOM;Egyedi +TP_WBALANCE_DAYLIGHT;Nappali (napfény) +TP_WBALANCE_FLASH55;Leica +TP_WBALANCE_FLASH60;Standard, Canon, Pentax, Olympus +TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta +TP_WBALANCE_FLASH_HEADER;Flash +TP_WBALANCE_FLUO1;F1 - Nappali fény +TP_WBALANCE_FLUO2;F2 - Hideg fehér +TP_WBALANCE_FLUO3;F3 - Fehér +TP_WBALANCE_FLUO4;F4 - Meleg fehér +TP_WBALANCE_FLUO5;F5 - Nappali fény +TP_WBALANCE_FLUO6;F6 - Lite fehér +TP_WBALANCE_FLUO7;F7 - D65 Daylight utánzat +TP_WBALANCE_FLUO8;F8 - D50 / Sylvania F40 Design +TP_WBALANCE_FLUO9;F9 - Cool white deluxe +TP_WBALANCE_FLUO10;F10 - Philips TL85 +TP_WBALANCE_FLUO11;F11 - Philips TL84 +TP_WBALANCE_FLUO12;F12 - Philips TL83 +TP_WBALANCE_FLUO_HEADER;Fluorescent +TP_WBALANCE_GREEN;Árnyalat +TP_WBALANCE_GTI;GTI +TP_WBALANCE_HMI;HMI +TP_WBALANCE_JUDGEIII;JudgeIII +TP_WBALANCE_LABEL;Fehéregyensúly +TP_WBALANCE_LAMP_HEADER;Lamp +TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 +TP_WBALANCE_LED_HEADER;LED +TP_WBALANCE_LED_LSI;LSI Lumelex 2040 +TP_WBALANCE_METHOD;Beállítás +TP_WBALANCE_SHADE;Shade +TP_WBALANCE_SIZE;Méret: +TP_WBALANCE_SOLUX35;Solux 3500K +TP_WBALANCE_SOLUX41;Solux 4100K +TP_WBALANCE_SOLUX47;Solux 4700K (vendor) +TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) +TP_WBALANCE_SPOTWB;Mintavétel +TP_WBALANCE_TEMPERATURE;Színhőmérséklet +TP_WBALANCE_TUNGSTEN;Tungsten +ZOOMPANEL_100;(100%) +ZOOMPANEL_NEWCROPWINDOW;(Új) lupe megnyitása +ZOOMPANEL_ZOOM100;Nagyítás 100%-ra z +ZOOMPANEL_ZOOMFITSCREEN;Képernyő méretéhez igazítás f +ZOOMPANEL_ZOOMIN;Nagyítás + +ZOOMPANEL_ZOOMOUT;Kicsinyítés - + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!BATCHQUEUE_DESTFILENAME;Path and file name +!CURVEEDITOR_AXIS_IN;I: +!CURVEEDITOR_AXIS_LEFT_TAN;LT: +!CURVEEDITOR_AXIS_OUT;O: +!CURVEEDITOR_AXIS_RIGHT_TAN;RT: +!CURVEEDITOR_EDITPOINT_HINT;Enable edition of node in/out values.\n\nRight-click on a node to select it.\nRight-click on empty space to de-select the node. +!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. +!EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels +!EXPORT_BYPASS_RAW_LMMSE_ITERATIONS;Bypass [raw] LMMSE Enhancement Steps +!EXTPROGTARGET_1;raw +!EXTPROGTARGET_2;queue-processed +!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_EXTPROGMENU;Open with +!FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) +!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_POPUPRANK0;Unrank +!FILEBROWSER_POPUPRANK1;Rank 1 * +!FILEBROWSER_POPUPRANK2;Rank 2 ** +!FILEBROWSER_POPUPRANK3;Rank 3 *** +!FILEBROWSER_POPUPRANK4;Rank 4 **** +!FILEBROWSER_POPUPRANK5;Rank 5 ***** +!FILEBROWSER_POPUPRANK;Rank +!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_SHOWNOTTRASHHINT;Show only non-deleted images. +!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_ASIMAGE;As Image +!GENERAL_AUTO;Automatic +!GENERAL_CLOSE;Close +!GENERAL_WARNING;Warning +!HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram. +!HISTOGRAM_TOOLTIP_FULL;Toggle full (off) or scaled (on) histogram. +!HISTORY_MSG_167;--unused-- +!HISTORY_MSG_168;L*a*b* - CC curve +!HISTORY_MSG_169;L*a*b* - CH curve +!HISTORY_MSG_170;Vibrance - HH curve +!HISTORY_MSG_171;L*a*b* - LC curve +!HISTORY_MSG_172;L*a*b* - Restrict LC +!HISTORY_MSG_173;NR - Luminance detail +!HISTORY_MSG_174;CIECAM02 +!HISTORY_MSG_175;CAM02 - CAT02 adaptation +!HISTORY_MSG_176;CAM02 - Viewing surround +!HISTORY_MSG_177;CAM02 - Scene luminosity +!HISTORY_MSG_178;CAM02 - Viewing luminosity +!HISTORY_MSG_179;CAM02 - White-point model +!HISTORY_MSG_180;CAM02 - Lightness (J) +!HISTORY_MSG_181;CAM02 - Chroma (C) +!HISTORY_MSG_182;CAM02 - Automatic CAT02 +!HISTORY_MSG_183;CAM02 - Contrast (J) +!HISTORY_MSG_184;CAM02 - Scene surround +!HISTORY_MSG_185;CAM02 - Gamut control +!HISTORY_MSG_186;CAM02 - Algorithm +!HISTORY_MSG_187;CAM02 - Red/skin prot. +!HISTORY_MSG_188;CAM02 - Brightness (Q) +!HISTORY_MSG_189;CAM02 - Contrast (Q) +!HISTORY_MSG_190;CAM02 - Saturation (S) +!HISTORY_MSG_191;CAM02 - Colorfulness (M) +!HISTORY_MSG_192;CAM02 - Hue (h) +!HISTORY_MSG_193;CAM02 - Tone curve 1 +!HISTORY_MSG_194;CAM02 - Tone curve 2 +!HISTORY_MSG_195;CAM02 - Tone curve 1 +!HISTORY_MSG_196;CAM02 - Tone curve 2 +!HISTORY_MSG_197;CAM02 - Color curve +!HISTORY_MSG_198;CAM02 - Color curve +!HISTORY_MSG_199;CAM02 - Output histograms +!HISTORY_MSG_200;CAM02 - Tone mapping +!HISTORY_MSG_201;NR - Chrominance - R&G +!HISTORY_MSG_202;NR - Chrominance - B&Y +!HISTORY_MSG_203;NR - Method +!HISTORY_MSG_204;LMMSE enhancement steps +!HISTORY_MSG_205;CAM02 - Hot/bad pixel filter +!HISTORY_MSG_206;CAT02 - Auto scene luminosity +!HISTORY_MSG_207;Defringe - Hue curve +!HISTORY_MSG_208;WB - B/R equalizer +!HISTORY_MSG_210;GF - Angle +!HISTORY_MSG_211;Graduated Filter +!HISTORY_MSG_212;VF - Strength +!HISTORY_MSG_213;Vignette Filter +!HISTORY_MSG_214;Black-and-White +!HISTORY_MSG_215;B&W - CM - Red +!HISTORY_MSG_216;B&W - CM - Green +!HISTORY_MSG_217;B&W - CM - Blue +!HISTORY_MSG_218;B&W - Gamma - Red +!HISTORY_MSG_219;B&W - Gamma - Green +!HISTORY_MSG_220;B&W - Gamma - Blue +!HISTORY_MSG_221;B&W - Color filter +!HISTORY_MSG_222;B&W - Presets +!HISTORY_MSG_223;B&W - CM - Orange +!HISTORY_MSG_224;B&W - CM - Yellow +!HISTORY_MSG_225;B&W - CM - Cyan +!HISTORY_MSG_226;B&W - CM - Magenta +!HISTORY_MSG_227;B&W - CM - Purple +!HISTORY_MSG_228;B&W - Luminance equalizer +!HISTORY_MSG_229;B&W - Luminance equalizer +!HISTORY_MSG_230;B&W - Mode +!HISTORY_MSG_231;B&W - 'Before' curve +!HISTORY_MSG_232;B&W - 'Before' curve type +!HISTORY_MSG_233;B&W - 'After' curve +!HISTORY_MSG_234;B&W - 'After' curve type +!HISTORY_MSG_235;B&W - Auto channel mixer +!HISTORY_MSG_236;--unused-- +!HISTORY_MSG_237;B&W - Mixer +!HISTORY_MSG_238;GF - Feather +!HISTORY_MSG_239;GF - Strength +!HISTORY_MSG_240;GF - Center +!HISTORY_MSG_241;VF - Feather +!HISTORY_MSG_242;VF - Roundness +!HISTORY_MSG_243;VC - Radius +!HISTORY_MSG_244;VC - Strength +!HISTORY_MSG_245;VC - Center +!HISTORY_MSG_246;L*a*b* - CL curve +!HISTORY_MSG_247;L*a*b* - LH curve +!HISTORY_MSG_248;L*a*b* - HH curve +!HISTORY_MSG_249;CbDL - Threshold +!HISTORY_MSG_250;NR - Enhanced +!HISTORY_MSG_251;B&W - Algorithm +!HISTORY_MSG_252;CbDL - Skin tar/prot +!HISTORY_MSG_253;CbDL - Reduce artifacts +!HISTORY_MSG_254;CbDL - Skin hue +!HISTORY_MSG_255;NR - Median filter +!HISTORY_MSG_256;NR - Median type +!HISTORY_MSG_257;Color Toning +!HISTORY_MSG_258;CT - Color curve +!HISTORY_MSG_259;CT - Opacity curve +!HISTORY_MSG_260;CT - a*[b*] opacity +!HISTORY_MSG_261;CT - Method +!HISTORY_MSG_262;CT - b* opacity +!HISTORY_MSG_263;CT - Shadows - Red +!HISTORY_MSG_264;CT - Shadows - Green +!HISTORY_MSG_265;CT - Shadows - Blue +!HISTORY_MSG_266;CT - Mid - Red +!HISTORY_MSG_267;CT - Mid - Green +!HISTORY_MSG_268;CT - Mid - Blue +!HISTORY_MSG_269;CT - High - Red +!HISTORY_MSG_270;CT - High - Green +!HISTORY_MSG_271;CT - High - Blue +!HISTORY_MSG_272;CT - Balance +!HISTORY_MSG_273;CT - Reset +!HISTORY_MSG_274;CT - Sat. Shadows +!HISTORY_MSG_275;CT - Sat. Highlights +!HISTORY_MSG_276;CT - Opacity +!HISTORY_MSG_277;--unused-- +!HISTORY_MSG_278;CT - Preserve luminance +!HISTORY_MSG_279;CT - Shadows +!HISTORY_MSG_280;CT - Highlights +!HISTORY_MSG_281;CT - Sat. strength +!HISTORY_MSG_282;CT - Sat. threshold +!HISTORY_MSG_283;CT - Strength +!HISTORY_MSG_284;CT - Auto sat. protection +!HISTORY_MSG_285;NR - Median - Method +!HISTORY_MSG_286;NR - Median - Type +!HISTORY_MSG_287;NR - Median - Iterations +!HISTORY_MSG_288;Flat Field - Clip control +!HISTORY_MSG_289;Flat Field - Clip control - Auto +!HISTORY_MSG_290;Black Level - Red +!HISTORY_MSG_291;Black Level - Green +!HISTORY_MSG_292;Black Level - Blue +!HISTORY_MSG_293;Film Simulation +!HISTORY_MSG_294;Film Simulation - Strength +!HISTORY_MSG_295;Film Simulation - Film +!HISTORY_MSG_296;NR - Luminance curve +!HISTORY_MSG_297;NR - Quality +!HISTORY_MSG_298;Dead pixel filter +!HISTORY_MSG_299;NR - Chrominance curve +!HISTORY_MSG_300;- +!HISTORY_MSG_301;NR - Luma control +!HISTORY_MSG_302;NR - Chroma method +!HISTORY_MSG_303;NR - Chroma method +!HISTORY_MSG_304;W - Contrast levels +!HISTORY_MSG_305;Wavelet Levels +!HISTORY_MSG_306;W - Preview +!HISTORY_MSG_307;W - Preview +!HISTORY_MSG_308;W - Preview direction +!HISTORY_MSG_309;W - ES - Detail +!HISTORY_MSG_310;W - Residual - Sky tar/prot +!HISTORY_MSG_311;W - Wavelet levels +!HISTORY_MSG_312;W - Residual - Shadows threshold +!HISTORY_MSG_313;W - Chroma - Sat/past +!HISTORY_MSG_314;W - Gamut - Reduce artifacts +!HISTORY_MSG_315;W - Residual - Contrast +!HISTORY_MSG_316;W - Gamut - Skin tar/prot +!HISTORY_MSG_317;W - Gamut - Skin hue +!HISTORY_MSG_318;W - Contrast - Highlight levels +!HISTORY_MSG_319;W - Contrast - Highlight range +!HISTORY_MSG_320;W - Contrast - Shadow range +!HISTORY_MSG_321;W - Contrast - Shadow levels +!HISTORY_MSG_322;W - Gamut - Avoid color shift +!HISTORY_MSG_323;W - ES - Local contrast +!HISTORY_MSG_324;W - Chroma - Pastel +!HISTORY_MSG_325;W - Chroma - Saturated +!HISTORY_MSG_326;W - Chroma - Method +!HISTORY_MSG_327;W - Contrast - Apply to +!HISTORY_MSG_328;W - Chroma - Link strength +!HISTORY_MSG_329;W - Toning - Opacity RG +!HISTORY_MSG_330;W - Toning - Opacity BY +!HISTORY_MSG_331;W - Contrast levels - Extra +!HISTORY_MSG_332;W - Tiling method +!HISTORY_MSG_333;W - Residual - Shadows +!HISTORY_MSG_334;W - Residual - Chroma +!HISTORY_MSG_335;W - Residual - Highlights +!HISTORY_MSG_336;W - Residual - Highlights threshold +!HISTORY_MSG_337;W - Residual - Sky hue +!HISTORY_MSG_338;W - ES - Radius +!HISTORY_MSG_339;W - ES - Strength +!HISTORY_MSG_340;W - Strength +!HISTORY_MSG_341;W - Edge performance +!HISTORY_MSG_342;W - ES - First level +!HISTORY_MSG_343;W - Chroma levels +!HISTORY_MSG_344;W - Meth chroma sl/cur +!HISTORY_MSG_345;W - ES - Local contrast +!HISTORY_MSG_346;W - ES - Local contrast method +!HISTORY_MSG_347;W - Denoise - Level 0 +!HISTORY_MSG_348;W - Denoise - Level 1 +!HISTORY_MSG_349;W - Denoise - Level 2 +!HISTORY_MSG_350;W - ES - Edge detection +!HISTORY_MSG_351;W - Residual - HH curve +!HISTORY_MSG_352;W - Background +!HISTORY_MSG_353;W - ES - Gradient sensitivity +!HISTORY_MSG_354;W - ES - Enhance +!HISTORY_MSG_355;W - ES - Threshold low +!HISTORY_MSG_356;W - ES - Threshold high +!HISTORY_MSG_357;W - Denoise - Link with ES +!HISTORY_MSG_358;W - Gamut - CH +!HISTORY_MSG_359;Hot/Dead - Threshold +!HISTORY_MSG_360;TM Gamma +!HISTORY_MSG_361;W - Final - Chroma balance +!HISTORY_MSG_362;W - Residual - Compression method +!HISTORY_MSG_363;W - Residual - Compression strength +!HISTORY_MSG_364;W - Final - Contrast balance +!HISTORY_MSG_365;W - Final - Delta balance +!HISTORY_MSG_366;W - Residual - Compression gamma +!HISTORY_MSG_367;W - ES - Local contrast curve +!HISTORY_MSG_368;W - Final - Contrast balance +!HISTORY_MSG_369;W - Final - Balance method +!HISTORY_MSG_370;W - Final - Local contrast curve +!HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s +!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). +!MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue-processed first. +!MAIN_MSG_OPERATIONCANCELLED;Operation cancelled +!MAIN_MSG_PATHDOESNTEXIST;The path\n\n%1\n\ndoes not exist. Please set a correct path in Preferences. +!MAIN_MSG_SETPATHFIRST;You first have to set a target path in Preferences in order to use this function! +!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_INSPECT; Inspect +!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 +!NAVIGATOR_B;B: +!NAVIGATOR_G;G: +!NAVIGATOR_H;H: +!NAVIGATOR_LAB_A;a*: +!NAVIGATOR_LAB_B;b*: +!NAVIGATOR_LAB_L;L*: +!NAVIGATOR_NA; -- +!NAVIGATOR_R;R: +!NAVIGATOR_S;S: +!NAVIGATOR_V;V: +!NAVIGATOR_XY_FULL;Width: %1, Height: %2 +!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_CHANNELMIXERBW;Black-and-White +!PARTIALPASTE_COLORAPP;CIECAM02 +!PARTIALPASTE_COLORTONING;Color Toning +!PARTIALPASTE_EQUALIZER;Wavelet Equalizer +!PARTIALPASTE_FILMSIMULATION;Film Simulation +!PARTIALPASTE_FLATFIELDCLIPCONTROL;Flat-field clip control +!PARTIALPASTE_GRADIENT;Graduated filter +!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_PCVIGNETTE;Vignette filter +!PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter +!PARTIALPASTE_PREPROCESS_HOTPIXFILT;Hot pixel filter +!PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!PARTIALPASTE_WAVELETGROUP;Wavelet processing +!PREFERENCES_AUTLISLOW;Low +!PREFERENCES_AUTLISMAX;Max - Average of all tiles +!PREFERENCES_AUTLISSTD;High +!PREFERENCES_AUTLISVLOW;None +!PREFERENCES_AUTLOW;Low +!PREFERENCES_AUTSTD;Standard +!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_BEHADDALL;All to 'Add' +!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_BEHSETALL;All to 'Set' +!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_CURVEBBOXPOS;Position of curve copypasta buttons +!PREFERENCES_CURVEBBOXPOS_ABOVE;Above +!PREFERENCES_CURVEBBOXPOS_BELOW;Below +!PREFERENCES_CURVEBBOXPOS_LEFT;Left +!PREFERENCES_CURVEBBOXPOS_RIGHT;Right +!PREFERENCES_CUSTPROFBUILDKEYFORMAT;Keys format +!PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME;Name +!PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;TagID +!PREFERENCES_D50;5000K +!PREFERENCES_D55;5500K +!PREFERENCES_D60;6000K +!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_EXPAUT;Expert +!PREFERENCES_FILMSIMULATION;Film Simulation +!PREFERENCES_FLUOF2;Fluorescent F2 +!PREFERENCES_FLUOF7;Fluorescent F7 +!PREFERENCES_FLUOF11;Fluorescent F11 +!PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT;Same thumbnail height between the Editor's panel 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_GREY05;Yb=05 CIE L#30 +!PREFERENCES_GREY10;Yb=10 CIE L#40 +!PREFERENCES_GREY15;Yb=15 CIE L#45 +!PREFERENCES_GREY18;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_GREYSC18;Yb=18 CIE L#50 +!PREFERENCES_GREYSCA;Automatic +!PREFERENCES_GREYSC;Scene Yb luminance (%) +!PREFERENCES_GREY;Output device's Yb luminance (%) +!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_LEVAUTDN;Denoising level +!PREFERENCES_LEVDN;Cell size +!PREFERENCES_LISS;Auto multi-zone smoothing +!PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders +!PREFERENCES_MAX;Maxi (Tile) +!PREFERENCES_MED;Medium (Tile/2) +!PREFERENCES_MENUGROUPEXTPROGS;Group "Open with" +!PREFERENCES_MIN;Mini (100x115) +!PREFERENCES_NAVGUIDEBRUSH;Navigator guide color +!PREFERENCES_NAVIGATIONFRAME;Navigation +!PREFERENCES_NOISE;Noise Reduction +!PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Overlay filenames on thumbnails in the editor pannel +!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_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_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_SHOWFILMSTRIPTOOLBAR;Show filmstrip toolbar +!PREFERENCES_SIMPLAUT;Tool mode +!PREFERENCES_SMA;Small (250x287) +!PREFERENCES_STDAUT;Standard +!PREFERENCES_TAB_PERFORMANCE;Performance & Quality +!PREFERENCES_TIMAX;High +!PREFERENCES_TINB;Number of tiles +!PREFERENCES_TISTD;Standard +!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 +!PROFILEPANEL_GLOBALPROFILES;Bundled profiles +!PROFILEPANEL_MODE_TIP;Processing profile fill mode.\n\nButton pressed: partial profiles will be converted to full profiles; the missing values will be replaced with hard-coded defaults.\n\nButton released: profiles will be applied as they are, altering only those values which they contain. +!PROFILEPANEL_MYPROFILES;My profiles +!PROFILEPANEL_PINTERNAL;Neutral +!PROGRESSBAR_NOIMAGES;No images found +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing profile saved +!PROGRESSBAR_SNAPSHOT_ADDED;Snapshot added +!SAVEDLG_FORCEFORMATOPTS;Force saving options +!SAVEDLG_SUBSAMP;Subsampling +!SAVEDLG_SUBSAMP_1;Best compression +!SAVEDLG_SUBSAMP_2;Balanced +!SAVEDLG_SUBSAMP_3;Best quality +!SAVEDLG_SUBSAMP_TOOLTIP;Best compression: 4:1:1\nBalanced: 4:2:2\nBest quality: 4:4:4 +!SAVEDLG_WARNFILENAME;File will be named +!SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. +!THRESHOLDSELECTOR_BL;Bottom-left +!THRESHOLDSELECTOR_BR;Bottom-right +!THRESHOLDSELECTOR_B;Bottom +!THRESHOLDSELECTOR_HINT;Hold the Shift key to move individual control points. +!THRESHOLDSELECTOR_TL;Top-left +!THRESHOLDSELECTOR_TR;Top-right +!THRESHOLDSELECTOR_T;Top +!TP_BWMIX_ALGO;Algorithm OYCPM +!TP_BWMIX_ALGO_LI;Linear +!TP_BWMIX_ALGO_SP;Special effects +!TP_BWMIX_ALGO_TOOLTIP;Linear: will produce a normal linear response.\nSpecial effects: will produce special effects by mixing channels non-linearly. +!TP_BWMIX_AUTOCH;Auto +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing Channel Mixer. +!TP_BWMIX_CC_ENABLED;Adjust complementary color +!TP_BWMIX_CC_TOOLTIP;Enable to allow automatic adjustment of complementary colors in ROYGCBPM mode. +!TP_BWMIX_CHANNEL;Luminance equalizer +!TP_BWMIX_CURVEEDITOR1;'Before' curve +!TP_BWMIX_CURVEEDITOR2;'After' curve +!TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Tone curve, after B&W conversion, at the end of treatment. +!TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Tone curve, just before B&W conversion.\nMay take into account the color components. +!TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H).\nPay attention to extreme values as they may cause artifacts. +!TP_BWMIX_FILTER;Color Filter +!TP_BWMIX_FILTER_BLUEGREEN;Blue-Green +!TP_BWMIX_FILTER_BLUE;Blue +!TP_BWMIX_FILTER_GREENYELLOW;Green-Yellow +!TP_BWMIX_FILTER_GREEN;Green +!TP_BWMIX_FILTER_NONE;None +!TP_BWMIX_FILTER_PURPLE;Purple +!TP_BWMIX_FILTER_REDYELLOW;Red-Yellow +!TP_BWMIX_FILTER_RED;Red +!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. +!TP_BWMIX_FILTER_YELLOW;Yellow +!TP_BWMIX_GAMMA;Gamma Correction +!TP_BWMIX_GAM_TOOLTIP;Correct gamma for each RGB channel. +!TP_BWMIX_LABEL;Black-and-White +!TP_BWMIX_MET;Method +!TP_BWMIX_MET_CHANMIX;Channel Mixer +!TP_BWMIX_MET_DESAT;Desaturation +!TP_BWMIX_MET_LUMEQUAL;Luminance Equalizer +!TP_BWMIX_MIXC;Mixer +!TP_BWMIX_NEUTRAL;Reset mixer +!TP_BWMIX_NEUTRAL_TIP;Reset all values (Color Filter, Channel Mixer) to default. +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all the mixer options.\n"Total" displays the sum of the RGB values:\n- always 100% in relative mode\n- higher (lighter) or lower (darker) than 100% in absolute mode. +!TP_BWMIX_RGB_TOOLTIP;Mix the RGB channels. Use presets for guidance.\nPay attention to negative values that may cause artifacts or erratic behavior. +!TP_BWMIX_SETTING;Presets +!TP_BWMIX_SETTING_TOOLTIP;Different presets (film, landscape, etc.) or manual Channel Mixer settings. +!TP_BWMIX_SET_HIGHCONTAST;High contrast +!TP_BWMIX_SET_HIGHSENSIT;High Sensitivity +!TP_BWMIX_SET_HYPERPANCHRO;Hyper Panchromatic +!TP_BWMIX_SET_INFRARED;Infrared +!TP_BWMIX_SET_LANDSCAPE;Landscape +!TP_BWMIX_SET_LOWSENSIT;Low Sensitivity +!TP_BWMIX_SET_LUMINANCE;Luminance +!TP_BWMIX_SET_NORMCONTAST;Normal Contrast +!TP_BWMIX_SET_ORTHOCHRO;Orthochromatic +!TP_BWMIX_SET_PANCHRO;Panchromatic +!TP_BWMIX_SET_PORTRAIT;Portrait +!TP_BWMIX_SET_RGBABS;Absolute RGB +!TP_BWMIX_SET_RGBREL;Relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Relative ROYGCBPM +!TP_BWMIX_TCMODE_FILMLIKE;B&W Film-like +!TP_BWMIX_TCMODE_SATANDVALBLENDING;B&W Saturation and Value Blending +!TP_BWMIX_TCMODE_STANDARD;B&W Standard +!TP_BWMIX_TCMODE_WEIGHTEDSTD;B&W Weighted Standard +!TP_BWMIX_VAL;L +!TP_COLORAPP_ADAPTSCENE;Scene luminosity +!TP_COLORAPP_ADAPTSCENE_TOOLTIP;Absolute luminance of the scene environement (cd/m²).\n1) Calculated from the Exif data:\nShutter speed - ISO speed - F number - camera exposure correction.\n2) Calculated from the raw white point and RT's Exposure Compensation slider. +!TP_COLORAPP_ADAPTVIEWING;Viewing luminosity (cd/m²) +!TP_COLORAPP_ADAPTVIEWING_TOOLTIP;Absolute luminance of the viewing environnement\n(usually 16cd/m²). +!TP_COLORAPP_ADAP_AUTO_TOOLTIP;If the checkbox is checked (recommended) RawTherapee calculates an optimum value from Exif data.\nTo set the value manually, uncheck the checkbox first. +!TP_COLORAPP_ALGO;Algorithm +!TP_COLORAPP_ALGO_ALL;All +!TP_COLORAPP_ALGO_JC;Lightness + Chroma (JC) +!TP_COLORAPP_ALGO_JS;Lightness + Saturation (JS) +!TP_COLORAPP_ALGO_QM;Brightness + Colorfulness (QM) +!TP_COLORAPP_ALGO_TOOLTIP;Lets you choose between parameter subsets or all parameters. +!TP_COLORAPP_BADPIXSL;Hot/bad pixel filter +!TP_COLORAPP_BADPIXSL_TOOLTIP;Suppression of hot/bad (brightly colored) pixels.\n0 = No effect\n1 = Median\n2 = Gaussian.\nAlternatively, adjust the image to avoid very dark shadows.\n\nThese artifacts are due to limitations of CIECAM02. +!TP_COLORAPP_BRIGHT;Brightness (Q) +!TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from L*a*b* and RGB brightness. +!TP_COLORAPP_CHROMA;Chroma (C) +!TP_COLORAPP_CHROMA_M;Colorfulnes (M) +!TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM02 differs from L*a*b* and RGB colorfulness. +!TP_COLORAPP_CHROMA_S;Saturation (S) +!TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from L*a*b* and RGB saturation. +!TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from L*a*b* and RGB chroma. +!TP_COLORAPP_CIECAT_DEGREE;CAT02 adaptation +!TP_COLORAPP_CONTRAST;Contrast (J) +!TP_COLORAPP_CONTRAST_Q;Contrast (Q) +!TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrast in CIECAM02 for the Q slider; it differs from L*a*b* and RGB contrast. +!TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from L*a*b* and RGB contrast. +!TP_COLORAPP_CURVEEDITOR1;Tone curve 1 +!TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L* (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of J or Q after CIECAM02.\n\nJ and Q are not shown in the main histogram panel.\n\nFor final output refer to the main histogram panel. +!TP_COLORAPP_CURVEEDITOR2;Tone curve 2 +!TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Same usage as with the second exposure tone curve. +!TP_COLORAPP_CURVEEDITOR3;Color curve +!TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Adjust either chroma, saturation or colorfulness.\n\nShows the histogram of chromaticity (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of C, s or M after CIECAM02.\n\nC, s and M are not shown in the main histogram panel.\nFor final output refer to the main histogram panel. +!TP_COLORAPP_DATACIE;CIECAM02 output histograms in curves +!TP_COLORAPP_DATACIE_TOOLTIP;When enabled, histograms in CIECAM02 curves show approximate values/ranges for J or Q, and C, s or M after the CIECAM02 adjustments.\nThis selection does not impact the main histogram panel.\n\nWhen disabled, histograms in CIECAM02 curves show L*a*b* values before CIECAM02 adjustments. +!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RawTherapee calculates an optimum value, which is then used by CAT02, and also for the entire CIECAM02.\nTo set the value manually, uncheck the check-box first (values above 65 are recommended). +!TP_COLORAPP_DEGREE_TOOLTIP;Amount of CIE Chromatic Adaptation Transform 2002. +!TP_COLORAPP_GAMUT;Gamut control (L*a*b*) +!TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in L*a*b* mode. +!TP_COLORAPP_HUE;Hue (h) +!TP_COLORAPP_HUE_TOOLTIP;Hue (h) - angle between 0° and 360°. +!TP_COLORAPP_LABEL;CIE Color Appearance Model 2002 +!TP_COLORAPP_LABEL_CAM02;Image Adjustments +!TP_COLORAPP_LABEL_SCENE;Scene Conditions +!TP_COLORAPP_LABEL_VIEWING;Viewing Conditions +!TP_COLORAPP_LIGHT;Lightness (J) +!TP_COLORAPP_LIGHT_TOOLTIP;Lightness in CIECAM02 differs from L*a*b* and RGB lightness. +!TP_COLORAPP_MODEL;WP Model +!TP_COLORAPP_MODEL_TOOLTIP;White-Point Model.\n\nWB [RT] + [output]: RT's white balance is used for the scene, CIECAM02 is set to D50, and the output device's white balance is set in Preferences > Color Management.\n\nWB [RT+CAT02] + [output]: RT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences - Color Management. +!TP_COLORAPP_RSTPRO;Red & skin-tones protection +!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin-tones protection affects both sliders and curves. +!TP_COLORAPP_SHARPCIE;--unused-- +!TP_COLORAPP_SHARPCIE_TOOLTIP;--unused-- +!TP_COLORAPP_SURROUND;Surround +!TP_COLORAPP_SURROUND_AVER;Average +!TP_COLORAPP_SURROUND_DARK;Dark +!TP_COLORAPP_SURROUND_DIM;Dim +!TP_COLORAPP_SURROUND_EXDARK;Extremly Dark (Cutsheet) +!TP_COLORAPP_SURROUND_TOOLTIP;Changes tones and colors to take into account the viewing conditions of the output device.\n\nAverage: Average light environment (standard). The image will not change.\n\nDim: Dim environment (TV). The image will become slighty dark.\n\nDark: Dark environment (projector). The image will become more dark.\n\nExtremly Dark: Extremly dark environment (cutsheet). The image will become very dark. +!TP_COLORAPP_SURSOURCE;Dark surround +!TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if image has a dark border. +!TP_COLORAPP_TCMODE_BRIGHTNESS;Brightness +!TP_COLORAPP_TCMODE_CHROMA;Chroma +!TP_COLORAPP_TCMODE_COLORF;Colorfulness +!TP_COLORAPP_TCMODE_LABEL1;Curve mode 1 +!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_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] +!TP_COLORAPP_WBRT;WB [RT] + [output] +!TP_COLORTONING_AB;o C/L +!TP_COLORTONING_AUTOSAT;Automatic +!TP_COLORTONING_BALANCE;Balance +!TP_COLORTONING_BY;o C/L +!TP_COLORTONING_CHROMAC;Opacity +!TP_COLORTONING_COLOR;Color +!TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;Chroma opacity as a function of luminance oC=f(L) +!TP_COLORTONING_HIGHLIGHT;Highlights +!TP_COLORTONING_HUE;Hue +!TP_COLORTONING_LABEL;Color Toning +!TP_COLORTONING_LAB;L*a*b* blending +!TP_COLORTONING_LUMAMODE;Preserve luminance +!TP_COLORTONING_LUMAMODE_TOOLTIP;If enabled, when you change color (red, green, cyan, blue, etc.) the luminance of each pixel is preserved. +!TP_COLORTONING_LUMA;Luminance +!TP_COLORTONING_METHOD;Method +!TP_COLORTONING_METHOD_TOOLTIP;"L*a*b* blending", "RGB sliders" and "RGB curves" use interpolated color blending.\n"Color balance (Shadows/Midtones/Highlights)" and "Saturation 2 colors" use direct colors.\n\nThe Black-and-White tool can be enabled when using any color toning method, which allows for color toning. +!TP_COLORTONING_MIDTONES;Midtones +!TP_COLORTONING_NEUTRAL;Reset sliders +!TP_COLORTONING_NEUTRAL_TIP;Reset all values (Shadows, Midtones, Highlights) to default. +!TP_COLORTONING_OPACITY;Opacity +!TP_COLORTONING_RGBCURVES;RGB - Curves +!TP_COLORTONING_RGBSLIDERS;RGB - Sliders +!TP_COLORTONING_SATURATEDOPACITY;Strength +!TP_COLORTONING_SATURATIONTHRESHOLD;Threshold +!TP_COLORTONING_SA;Saturation Protection +!TP_COLORTONING_SHADOWS;Shadows +!TP_COLORTONING_SPLITCOCO;Color Balance Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITCO;Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITLR;Saturation 2 colors +!TP_COLORTONING_STRENGTH;Strength +!TP_COLORTONING_STR;Strength +!TP_COLORTONING_TWO2;Special chroma '2 colors' +!TP_COLORTONING_TWOALL;Special chroma +!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_GTFRAME;Frame +!TP_CROP_GTHARMMEANS;Harmonic Means +!TP_CROP_GTTRIANGLE1;Golden Triangles 1 +!TP_CROP_GTTRIANGLE2;Golden Triangles 2 +!TP_DIRPYRDENOISE_33;3×3 strong +!TP_DIRPYRDENOISE_55SOFT;5×5 +!TP_DIRPYRDENOISE_55;5×5 strong +!TP_DIRPYRDENOISE_77;7×7 (slow) +!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_ABM;Chroma only +!TP_DIRPYRDENOISE_AUTO;Automatic global +!TP_DIRPYRDENOISE_AUTO_TOOLTIP;Try to evaluate chroma noise\nBe careful, this calculation is average, and is quite subjective ! +!TP_DIRPYRDENOISE_AUT;Automatic global +!TP_DIRPYRDENOISE_BLUE;Chrominance - Blue-Yellow +!TP_DIRPYRDENOISE_C2TYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CCCURVE;Chrominance curve +!TP_DIRPYRDENOISE_CHROMAFR;Chrominance +!TP_DIRPYRDENOISE_CTYPE;Auto method +!TP_DIRPYRDENOISE_CTYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nAutomatic multi-zones\nNo preview - works only during saving, but using the "Preview" method by matching the tile size and center to the preview size and center you can get an idea of the expected results.\nThe image is divided into tiles (about 10 to 70 depending on image size) and each tile receives its own chrominance noise reduction settings.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CURVEEDITOR_CC;Chroma +!TP_DIRPYRDENOISE_CURVEEDITOR_CC_TOOLTIP;Increase (multiply) the value of all chrominance sliders.\nThis curve lets you adjust the strength of chromatic noise reduction as a function of chromaticity, for instance to increase the action in areas of low saturation and to decrease it in those of high saturation. +!TP_DIRPYRDENOISE_CURVEEDITOR_L_TOOLTIP;Modulates action of 'Luminance' denoise +!TP_DIRPYRDENOISE_CUR;Curve +!TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on the gamma of the input color profile. An sRGB gamma is assumed, thus if the image uses an input color profile of a different gamma, the effects of luminance noise reduction will differ. +!TP_DIRPYRDENOISE_ENH;Enhanced mode +!TP_DIRPYRDENOISE_ENH_TOOLTIP;Increases noise reduction quality at the expense of a 20% processing time increase. +!TP_DIRPYRDENOISE_GAMMA_TOOLTIP;Gamma varies noise reduction strength across the range of tones. Smaller values will target shadows, while larger values will stretch the effect to the brighter tones. +!TP_DIRPYRDENOISE_LABM;L*a*b* +!TP_DIRPYRDENOISE_LCURVE;Luminance curve +!TP_DIRPYRDENOISE_LDETAIL;Luminance - Detail +!TP_DIRPYRDENOISE_LM;Luminance only +!TP_DIRPYRDENOISE_LPLABM;Weighted L* (little) + a*b* (normal) +!TP_DIRPYRDENOISE_LTYPE;Luminance control +!TP_DIRPYRDENOISE_LUMAFR;Luminance +!TP_DIRPYRDENOISE_LUMAFR_TOOLTIP;Wavelet on luminance and Fourier transform for luminance detail +!TP_DIRPYRDENOISE_MANU;Manual +!TP_DIRPYRDENOISE_MAN;Manual +!TP_DIRPYRDENOISE_MEDMETHOD;Median method +!TP_DIRPYRDENOISE_MEDTYPE;Median type +!TP_DIRPYRDENOISE_MED;Median Filter +!TP_DIRPYRDENOISE_MED_TOOLTIP;Enabled median denoising +!TP_DIRPYRDENOISE_METHOD11;Quality +!TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. +!TP_DIRPYRDENOISE_METHOD;Method +!TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or L*a*b* methods can be used.\n\nFor non-raw images the L*a*b* method will be used, regardless of the selection. +!TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - +!TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 +!TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. +!TP_DIRPYRDENOISE_PASSES;Median iterations +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PON;Auto multi-zones +!TP_DIRPYRDENOISE_PREVLABEL;Preview size=%1, Center: Px=%2 Py=%3 +!TP_DIRPYRDENOISE_PREV;Preview +!TP_DIRPYRDENOISE_PRE;Preview multi-zones +!TP_DIRPYRDENOISE_RED;Chrominance - Red-Green +!TP_DIRPYRDENOISE_RGBM;RGB +!TP_DIRPYRDENOISE_RGB;RGB +!TP_DIRPYRDENOISE_SHALBI;High +!TP_DIRPYRDENOISE_SHAL;Standard +!TP_DIRPYRDENOISE_SLI;Slider +!TP_DIRPYRDENOISE_SOFT;3x3 +!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_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_EPD_GAMMA;Gamma +!TP_EPD_TOOLTIP;Tone mapping is possible in L*a*b* mode (standard) and CIECAM02 mode.\n\nWhen in L*a*b* mode, tone mapping can also be used on the residual image of the Wavelet Levels tool.\n\nTo engage CIECAM02 tone mapping mode enable the following settings:\n1. CIECAM02\n2. Algorithm="Brightness + Colorfulness (QM)"\n3. "Tone mapping using CIECAM02 brightness (Q)" +!TP_EXPOSURE_CURVEEDITOR1;Tone curve 1 +!TP_EXPOSURE_CURVEEDITOR2;Tone curve 2 +!TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Please refer to the "Exposure > Tone Curves" RawPedia article to learn how to achieve the best results by using two tone curves. +!TP_EXPOSURE_TCMODE_FILMLIKE;Film-like +!TP_EXPOSURE_TCMODE_LABEL1;Curve mode 1 +!TP_EXPOSURE_TCMODE_LABEL2;Curve mode 2 +!TP_EXPOSURE_TCMODE_LUMINANCE;Luminance +!TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Saturation and Value Blending +!TP_EXPOSURE_TCMODE_STANDARD;Standard +!TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard +!TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points +!TP_EXPOS_WHITEPOINT_LABEL;Raw White Points +!TP_FILMSIMULATION_LABEL;Film Simulation +!TP_FILMSIMULATION_STRENGTH;Strength +!TP_FILMSIMULATION_ZEROCLUTSFOUND;Set HaldCLUT directory in Preferences +!TP_FLATFIELD_CLIPCONTROL;Clip control +!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. +!TP_GENERAL_11SCALE_TOOLTIP;The effects of this tool are only visible or only accurate at a preview scale of 1:1. +!TP_GRADIENT_CENTER;Center +!TP_GRADIENT_CENTER_X;Center X +!TP_GRADIENT_CENTER_X_TOOLTIP;Shift gradient to the left (negative values) or right (positive values). +!TP_GRADIENT_CENTER_Y;Center Y +!TP_GRADIENT_CENTER_Y_TOOLTIP;Shift gradient up (negative values) or down (positive values). +!TP_GRADIENT_DEGREE;Angle +!TP_GRADIENT_DEGREE_TOOLTIP;Rotation angle in degrees. +!TP_GRADIENT_FEATHER;Feather +!TP_GRADIENT_FEATHER_TOOLTIP;Gradient width in percent of the image diagonal. +!TP_GRADIENT_LABEL;Graduated Filter +!TP_GRADIENT_STRENGTH;Strength +!TP_GRADIENT_STRENGTH_TOOLTIP;Filter strength in stops. +!TP_HLREC_ENA_TOOLTIP;Could be activated by Auto Levels. +!TP_ICM_DCPILLUMINANT;Illuminant +!TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolated +!TP_ICM_DCPILLUMINANT_TOOLTIP;Select which embedded DCP illuminant to employ. Default is "interpolated" which is a mix between the two based on white balance. The setting is only enabled if a Dual-Illuminant DCP with interpolation support is selected. +!TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance +!TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. The result can be used for calibration purposes and generation of a camera profile. +!TP_ICM_TONECURVE;Use DCP's tone curve +!TP_ICM_TONECURVE_TOOLTIP;Employ the embedded DCP tone curve. The setting is only enabled if the selected DCP has a tone curve. +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid color shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction. +!TP_LABCURVE_CHROMATICITY;Chromaticity +!TP_LABCURVE_CHROMA_TOOLTIP;To apply B&W toning, set Chromaticity to -100. +!TP_LABCURVE_CURVEEDITOR_A_RANGE1;Green Saturated +!TP_LABCURVE_CURVEEDITOR_A_RANGE2;Green Pastel +!TP_LABCURVE_CURVEEDITOR_A_RANGE3;Red Pastel +!TP_LABCURVE_CURVEEDITOR_A_RANGE4;Red Saturated +!TP_LABCURVE_CURVEEDITOR_B_RANGE1;Blue Saturated +!TP_LABCURVE_CURVEEDITOR_B_RANGE2;Blue Pastel +!TP_LABCURVE_CURVEEDITOR_B_RANGE3;Yellow Pastel +!TP_LABCURVE_CURVEEDITOR_B_RANGE4;Yellow Saturated +!TP_LABCURVE_CURVEEDITOR_CC;CC +!TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutral +!TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Dull +!TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastel +!TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Saturated +!TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Chromaticity according to chromaticity C=f(C) +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to hue C=f(H) +!TP_LABCURVE_CURVEEDITOR_CL;CL +!TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Chromaticity according to luminance C=f(L) +!TP_LABCURVE_CURVEEDITOR_HH;HH +!TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Hue according to hue H=f(H) +!TP_LABCURVE_CURVEEDITOR_LC;LC +!TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminance according to chromaticity L=f(C) +!TP_LABCURVE_CURVEEDITOR_LH;LH +!TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H) +!TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminance according to luminance L=f(L) +!TP_LABCURVE_LCREDSK;Restrict LC to red and skin-tones +!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_USECA;Chromatic aberration correction +!TP_LENSPROFILE_USEDIST;Distortion correction +!TP_LENSPROFILE_USEVIGN;Vignetting correction +!TP_PCVIGNETTE_FEATHER;Feather +!TP_PCVIGNETTE_FEATHER_TOOLTIP;Feathering:\n0 = corners only,\n50 = halfway to center,\n100 = to center. +!TP_PCVIGNETTE_LABEL;Vignette Filter +!TP_PCVIGNETTE_ROUNDNESS;Roundness +!TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness:\n0 = rectangle,\n50 = fitted ellipse,\n100 = circle. +!TP_PCVIGNETTE_STRENGTH;Strength +!TP_PCVIGNETTE_STRENGTH_TOOLTIP;Filter strength in stops (reached in corners). +!TP_PFCURVE_CURVEEDITOR_CH;Hue +!TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Controls defringe strength by color.\nHigher = more,\nLower = less. +!TP_PREPROCESS_DEADPIXFILT;Dead pixel filter +!TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Tries to suppress dead pixels. +!TP_PREPROCESS_HOTPIXFILT;Hot pixel filter +!TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Tries to suppress hot pixels. +!TP_RAWEXPOS_BLACK_0;Green 1 (lead) +!TP_RAWEXPOS_BLACK_1;Red +!TP_RAWEXPOS_BLACK_2;Blue +!TP_RAWEXPOS_BLACK_3;Green 2 +!TP_RAWEXPOS_BLACK_BLUE;Blue +!TP_RAWEXPOS_BLACK_GREEN;Green +!TP_RAWEXPOS_BLACK_RED;Red +!TP_RAWEXPOS_RGB;Red, Green, Blue +!TP_RAW_DMETHOD_PROGRESSBAR;%1 demosaicing... +!TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Demosaicing refinement... +!TP_RAW_DMETHOD_TOOLTIP;Note: IGV and LMMSE are dedicated to high ISO images to aid in noise reduction without leading to maze patterns, posterization or a washed-out look. +!TP_RAW_HD;Threshold +!TP_RAW_HD_TOOLTIP;Lower values make hot/dead pixel detection more aggressive, but false positives may lead to artifacts. If you notice any artifacts appearing when enabling the Hot/Dead Pixel Filters, gradually increase the threshold value until they disappear. +!TP_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!TP_RAW_LMMSE_TOOLTIP;Adds gamma (step 1), median (steps 2-4) and refinement (steps 5-6) to reduce artifacts and improve the signal-to-noise ratio. +!TP_RAW_SENSOR_BAYER_LABEL;Sensor with Bayer Matrix +!TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;3-pass gives best results (recommended for low ISO images).\n1-pass is almost undistinguishable from 3-pass for high ISO images and is faster. +!TP_RAW_SENSOR_XTRANS_LABEL;Sensor with X-Trans Matrix +!TP_RGBCURVES_LUMAMODE;Luminosity mode +!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_SHARPENING_TOOLTIP;Expect a slightly different effect when using with CIECAM02. If difference is observed, adjust to taste. +!TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Red/Purple +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Red +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Red/Yellow +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Yellow +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Hue according to hue H=f(H) +!TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Saturation threshold +!TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;The vertical axis represents pastel tones at the bottom and saturated tones at the top.\nThe horizontal axis represents the saturation range. +!TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Pastel/saturated transition's weighting +!TP_WAVELET_1;Level 1 +!TP_WAVELET_2;Level 2 +!TP_WAVELET_3;Level 3 +!TP_WAVELET_4;Level 4 +!TP_WAVELET_5;Level 5 +!TP_WAVELET_6;Level 6 +!TP_WAVELET_7;Level 7 +!TP_WAVELET_8;Level 8 +!TP_WAVELET_9;Level 9 +!TP_WAVELET_ALL;All levels in all directions +!TP_WAVELET_APPLYTO;Apply To +!TP_WAVELET_AVOID;Avoid color shift +!TP_WAVELET_B0;Black +!TP_WAVELET_B1;Grey +!TP_WAVELET_B2;Residual +!TP_WAVELET_BACUR;Curve +!TP_WAVELET_BALANCE;Contrast balance d/v-h +!TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chromaticity or residual tone mapping are activated, the effect due to balance is amplified. +!TP_WAVELET_BALCHRO;Chroma balance +!TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chromaticity balance. +!TP_WAVELET_BANONE;None +!TP_WAVELET_BASLI;Slider +!TP_WAVELET_BATYPE;Contrast balance method +!TP_WAVELET_CCURVE;Local contrast +!TP_WAVELET_CH1;Whole chromaticity range +!TP_WAVELET_CH2;Saturated/pastel +!TP_WAVELET_CH3;Link contrast levels +!TP_WAVELET_CHCU;Curve +!TP_WAVELET_CHRO;Saturated/pastel threshold +!TP_WAVELET_CHRO_TOOLTIP;Sets the wavelet level which will be the threshold between saturated and pastel colors.\n1-x: saturated\nx-9: pastel\n\nIf the value exceeds the amount of wavelet levels you are using then it will be ignored. +!TP_WAVELET_CHR;Chroma-contrast link strength +!TP_WAVELET_CHR_TOOLTIP;Adjusts chromaticity as a function of "contrast levels" and "chroma-contrast link strength" +!TP_WAVELET_CHSL;Sliders +!TP_WAVELET_CHTYPE;Chrominance method +!TP_WAVELET_COLORT;Opacity Red-Green +!TP_WAVELET_COMBOTH;Both +!TP_WAVELET_COMPCONT;Contrast +!TP_WAVELET_COMPGAMMA;Compression gamma +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjusting the gamma of the residual image allow you to equilibrate the data and histogram. +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjust gamma for residual image and compression.\nAllow to equilibrate data and histogram +!TP_WAVELET_COMPTM;Tone mapping +!TP_WAVELET_CONTEDIT;'After' Contrast curve +!TP_WAVELET_CONTEDIT;'After' contrast curve +!TP_WAVELET_CONTRAST_MINUS;Contrast - +!TP_WAVELET_CONTRAST_PLUS;Contrast + +!TP_WAVELET_CONTRA;Contrast +!TP_WAVELET_CONTRA_TOOLTIP;Changes contrast of the residual image. +!TP_WAVELET_CONTR;Gamut +!TP_WAVELET_CTYPE;Chrominance control +!TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modifies local contrast as a function of the original local contrast (absciss)\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 100..300)\n66% absciss represents standard deviation of local contrast (real value about 300..800)\n100% represents maximum (real value about 3000..8000) +!TP_WAVELET_CURVEEDITOR_CH;Contrast levels=f(Hue) +!TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modifies each level's contrast as a function oh hue.\nTake care not to overwrite changes made with the Gamut Hue controls.\nThe curve will only have an effect when wavelet contrast level sliders are non-zero. +!TP_WAVELET_CURVEEDITOR_CL;L +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Applies a final contrast luminance curve at the end of the wavelet treatment. +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Apply a contrast luminance curve at the end of wavelet level threatment +!TP_WAVELET_CURVEEDITOR_HH;HH +!TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modifies the residual image's hue as a function of hue. +!TP_WAVELET_DALL;All directions +!TP_WAVELET_DAUB;Edge performance +!TP_WAVELET_DAUB_TOOLTIP;Changes Daubechies coefficients:\nD4 = Standard,\nD14 = Often best performance, 10% more time-intensive.\n\nAffects edge detection as well as the general quality of the firsts levels. However the quality is not strictly related to this coefficient and can vary with images and uses. +!TP_WAVELET_DISP;Preview Settings +!TP_WAVELET_DONE;Vertical +!TP_WAVELET_DTHR;Diagonal +!TP_WAVELET_DTWO;Horizontal +!TP_WAVELET_EDCU;Curve +!TP_WAVELET_EDGCONT;Local contrast +!TP_WAVELET_EDGCONT_TOOLTIP;Adjusting the points to the left decreases contrast, and to the right increases it.\nBottom-left, Top-Left, Top-Right, Bottom-right represent respectively local contast for low values, mean, mean+stdev, maxima +!TP_WAVELET_EDGEDETECTTHR2;Threshold high (detection) +!TP_WAVELET_EDGEDETECTTHR;Threshold low (noise) +!TP_WAVELET_EDGEDETECTTHR_TOOLTIP;This adjuster lets you target edge detection for example to avoid applying edge sharpness to fine details, such as noise in the sky. +!TP_WAVELET_EDGEDETECT;Gradient sensitivity +!TP_WAVELET_EDGEDETECT_TOOLTIP;Moving the slider to the right increases edge sensitivity. This affects local contrast, edge settings and noise. +!TP_WAVELET_EDGE;Edge Sharpness +!TP_WAVELET_EDGREINF_TOOLTIP;Reinforce or reduce the action of the first level, do the opposite to the second level, and leave the rest unchanged. +!TP_WAVELET_EDGTHRESH;Detail +!TP_WAVELET_EDGTHRESH_TOOLTIP;Change the repartition between the first levels and the others. The higher the threshold the more the action is centred on the first levels. Be careful with negative values, they increase the action of high levels and can introduce artifacts. +!TP_WAVELET_EDRAD;Radius +!TP_WAVELET_EDRAD_TOOLTIP;This radius adjustment is very different from those in other sharpening tools. Its value is compared to each level through a complex function. In this sense, a value of zero still has an effect. +!TP_WAVELET_EDSL;Threshold Sliders +!TP_WAVELET_EDTYPE;Local contrast method +!TP_WAVELET_EDVAL;Strength +!TP_WAVELET_FINAL;Final Touchup +!TP_WAVELET_FINEST;Finest +!TP_WAVELET_HIGHLIGHT;Highlight luminance range +!TP_WAVELET_HS1;Whole luminance range +!TP_WAVELET_HS2;Shadows/Highlights +!TP_WAVELET_HUESKIN;Skin hue +!TP_WAVELET_HUESKIN_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_HUESKY;Sky hue +!TP_WAVELET_HUESKY_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_INF;Below or equal the level +!TP_WAVELET_ITER;Delta balance levels +!TP_WAVELET_ITER_TOOLTIP;Left: increase low levels and reduce high levels,\nRight: reduce low levels and increase high levels. +!TP_WAVELET_LABEL;Wavelet levels +!TP_WAVELET_LARGEST;Coarsest +!TP_WAVELET_LEVCH;Chromaticity +!TP_WAVELET_LEVELS;Wavelet levels +!TP_WAVELET_LEVELS_TOOLTIP;Choose the number of detail levels the image is to be decomposed into. More levels require more RAM and require a longer processing time. +!TP_WAVELET_LEVF;Contrast +!TP_WAVELET_LEVLABEL;Preview maximum possible levels = %1 +!TP_WAVELET_LEVONE;Level 2 +!TP_WAVELET_LEVTWO;Level 3 +!TP_WAVELET_LEVZERO;Level 1 +!TP_WAVELET_LINKEDG;Link with Edge Sharpness' Strength +!TP_WAVELET_LIPST;Enhanced algorithm +!TP_WAVELET_LIPST_TOOLTIP;This algorithm uses Lipschitz regularity to increase edge detection quality at a cost of increased processing time and memory requirements. +!TP_WAVELET_LOWLIGHT;Shadow luminance range +!TP_WAVELET_MEDGREINF;First level +!TP_WAVELET_MEDILEV;Edge detection +!TP_WAVELET_MEDI;Reduce artifacts in blue sky +!TP_WAVELET_NEUTRAL;Neutral +!TP_WAVELET_NOISE;Denoise and Refine +!TP_WAVELET_NOIS;Denoise +!TP_WAVELET_ONE;One level +!TP_WAVELET_OPACITYWL;Final local contrast +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify final local contrast in function of last local contrast (absciss) for all levels decomposition\nTake into account: \na)contrast levels \nb)edge sharpness \nc)contrast balance\nd)decomposition-recomposition\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 200..1000)\n66% absciss represents standard deviation of local contrast (real value about 1000..2000)\n100% represents maximum (real value about 5000..13000) +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify the final local contrast at the end of the wavelet treatment.\n\nThe left side represents the smallest local contrast, progressing to the largest local contrast on the right. +!TP_WAVELET_OPACITYW;Contrast balance d/v-h curve +!TP_WAVELET_OPACITY;Opacity Blue-Yellow +!TP_WAVELET_PASTEL;Pastel chromaticity +!TP_WAVELET_PREVIEWBACK;Background +!TP_WAVELET_PREVIEWLEVELS;Preview +!TP_WAVELET_RE1;Reinforced +!TP_WAVELET_RE2;Unchanged +!TP_WAVELET_RE3;Reduced +!TP_WAVELET_RESCHRO;Chromaticity +!TP_WAVELET_RESCONH;Highlights +!TP_WAVELET_RESCON;Shadows +!TP_WAVELET_RESID;Residual image +!TP_WAVELET_SAT;Saturated chromaticity +!TP_WAVELET_SETTINGS;Wavelet Settings +!TP_WAVELET_SKIN;Skin targetting/protection +!TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected. +!TP_WAVELET_SKY;Sky targetting/protection +!TP_WAVELET_SKY_TOOLTIP;At -100 sky-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 sky-tones are protected while all other tones are affected. +!TP_WAVELET_STRENGTH;Strength +!TP_WAVELET_STREN;Strength +!TP_WAVELET_SUPE;Extra +!TP_WAVELET_SUP;Above the level +!TP_WAVELET_THRESHOLD2;Shadow levels +!TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels between 9 and 9 minus the value will be affected by the shadow luminance range. Other levels will be fully treated. The highest level possible is limited by the highlight level value (9 minus highlight level value). +!TP_WAVELET_THRESHOLD;Highlight levels +!TP_WAVELET_THRESHOLD_TOOLTIP;Only levels beyond the chosen value will be affected by the highlight luminance range. Other levels will be fully treated. The chosen value here limits the highest possible value of the shadow levels. +!TP_WAVELET_THRH;Highlights threshold +!TP_WAVELET_THR;Shadows threshold +!TP_WAVELET_TILESBIG;Big tiles +!TP_WAVELET_TILESFULL;Full image +!TP_WAVELET_TILESIZE;Tiling method +!TP_WAVELET_TILESLIT;Little tiles +!TP_WAVELET_TILES_TOOLTIP;Processing the full image leads to better quality and is the recommended option, while using tiles is a fall-back solution for users with little RAM. Refer to RawPedia for memory requirements. +!TP_WAVELET_TMHIGH;High +!TP_WAVELET_TMLOWHIGH;Low+High +!TP_WAVELET_TMNONE;None +!TP_WAVELET_TMSTD;Standard +!TP_WAVELET_TMSTRENGTH;Compression strength +!TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image. When the value is different from 0, the Strength and Gamma sliders of the Tone Mapping tool in the Exposure tab will become grayed out. +!TP_WAVELET_TMTYPE;Compression method +!TP_WAVELET_TON;Toning +!TP_WAVELET_daub2;D2 - low +!TP_WAVELET_daub4;D4 - standard +!TP_WAVELET_daub6;D6 - standard plus +!TP_WAVELET_daub10;D10 - medium +!TP_WAVELET_daub14;D14 - high +!TP_WBALANCE_EQBLUERED;Blue/Red equalizer +!TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behavior of "white balance" by modulating the blue/red balance.\nThis can be useful when shooting conditions:\na) are far from the standard illuminant (e.g. underwater),\nb) are far from conditions where calibrations were performed,\nc) where the matrices or ICC profiles are unsuitable. +!TP_WBALANCE_WATER1;UnderWater 1 +!TP_WBALANCE_WATER2;UnderWater 2 +!TP_WBALANCE_WATER_HEADER;UnderWater +!ZOOMPANEL_ZOOMFITCROPSCREEN;Fit crop to screen\nShortcut: Alt-f diff --git a/rtdata/languages/Nederlands b/rtdata/languages/Nederlands new file mode 100644 index 000000000..cc64602ed --- /dev/null +++ b/rtdata/languages/Nederlands @@ -0,0 +1,1867 @@ +#01 2007-12-26 Rens Duijsens en Brent Huisman +#02 2008-03-14 updated by reggybe +#03 2009-02-01 updated to RT2.4-RC by paul.matthijsse +#04 2010-05-02 updated to rt3a1 by paul.matthijsse +#05 2011-03-03 updated to rt3a2 by paul.matthijsse +#06 2011-10-10 updated to rt4.0 by wim ter meer +#07 2011-11-28 updated by pm +#08 2012-05-17 updated to rt4.0.8 by wim ter meer +#09 2013-03-27 updated to rt4.0.10 by wim ter meer +#10 2013-11-27 updated to rt4.0.11 by wim ter meer +#11 2014-03-24 updated to rt4.1 by wim ter meer +#12 2014-10-19 updated to rt4.1.92 by wim ter meer +#13 2015-03-03 updated to rt4.2.102 by wim ter meer + +ABOUT_TAB_BUILD;Versie +ABOUT_TAB_CREDITS;Credits +ABOUT_TAB_LICENSE;Licentie +ABOUT_TAB_RELEASENOTES;Uitgave-opmerkingen +ABOUT_TAB_SPLASH;Splash +ADJUSTER_RESET_TO_DEFAULT;Terug naar beginwaarde +BATCHQUEUE_AUTOSTART;Autostart +BATCHQUEUE_DESTFILENAME;Pad en bestandsnaam +BATCH_PROCESSING;Batch-verwerking +CURVEEDITOR_CURVES;Curven +CURVEEDITOR_CURVE;Curve +CURVEEDITOR_CUSTOM;Handmatig +CURVEEDITOR_DARKS;Schaduwen +CURVEEDITOR_HIGHLIGHTS;Hoge lichten +CURVEEDITOR_LIGHTS;Lichten +CURVEEDITOR_LINEAR;Lineair +CURVEEDITOR_LOADDLGLABEL;Laad curve... +CURVEEDITOR_MINMAXCPOINTS;Min/Max controlepunten +CURVEEDITOR_NURBS;Kooicurve +CURVEEDITOR_PARAMETRIC;Parametrisch +CURVEEDITOR_SAVEDLGLABEL;Bewaar curve... +CURVEEDITOR_SHADOWS;Diepe schaduwen +CURVEEDITOR_TOOLTIPCOPY;Kopieer huidige curve naar klembord +CURVEEDITOR_TOOLTIPLINEAR;Maak curve lineair +CURVEEDITOR_TOOLTIPLOAD;Laad curve uit bestand +CURVEEDITOR_TOOLTIPPASTE;Plak curve van klembord +CURVEEDITOR_TOOLTIPSAVE;Bewaar huidige curve +CURVEEDITOR_TYPE;Type: +DIRBROWSER_FOLDERS;Mappen +EDITWINDOW_TITLE;Bewerk afbeelding +EDIT_OBJECT_TOOLTIP;Toont een widget in het voorbeeld scherm waarmee de werking van het gereedschap kan worden aangepast. +EDIT_PIPETTE_TOOLTIP;Voeg een punt toe aan de curve door de Ctrl toets ingedrukt te houden en tegelijkertijd te links-klikken op de gewenste plek op het voorbeeld.\nOm een punt te wijzigen, hou de Ctrl toets ingedrukt en links-klik tegelijkertijd op het gewenste gebied in het voorbeeld, en laat daarna de Ctrl toets los (behalve wanneer fijne controle is gewenst), blijf de linker muis knop ingedrukt houden en beweeg de muis naar boven of beneden om dit punt te verschuiven op de curve. +EXIFFILTER_APERTURE;Diafragma +EXIFFILTER_CAMERA;Camera +EXIFFILTER_EXPOSURECOMPENSATION;Belichtingscompensatie (EV) +EXIFFILTER_FILETYPE;Bestandstype +EXIFFILTER_FOCALLEN;Brandpuntsafstand +EXIFFILTER_ISO;ISO-waarde +EXIFFILTER_LENS;Objectief +EXIFFILTER_METADATAFILTER;Activeer metadatafilters +EXIFFILTER_SHUTTER;Sluitertijd +EXIFPANEL_ADDEDITHINT;Voeg nieuwe tag toe of bewerk tag +EXIFPANEL_ADDEDIT;Voeg toe/bewerk +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Geef waarde +EXIFPANEL_ADDTAGDLG_SELECTTAG;Selecteer tag +EXIFPANEL_ADDTAGDLG_TITLE;Voeg tag toe of bewerk +EXIFPANEL_KEEPHINT;Bewaar geselecteerde tags in doelbestand +EXIFPANEL_KEEP;Bewaar +EXIFPANEL_REMOVEHINT;Verwijder geselecteerde tags in doelbestand +EXIFPANEL_REMOVE;Verwijder +EXIFPANEL_RESETALLHINT;Zet alle tags terug naar oorspronkelijke waarden +EXIFPANEL_RESETALL;Herstel alles +EXIFPANEL_RESETHINT;Zet geselecteerde tags terug naar oorspronkelijke waarden +EXIFPANEL_RESET;Herstel +EXIFPANEL_SUBDIRECTORY;Submap +EXPORT_BYPASS_ALL;Alles selecteren/deselecteren +EXPORT_BYPASS_DEFRINGE;Verzachten niet toepassen +EXPORT_BYPASS_DIRPYRDENOISE;Ruisonderdrukking niet toepassen +EXPORT_BYPASS_DIRPYREQUALIZER;Detailcontrast niet toepassen +EXPORT_BYPASS_EQUALIZER;Wavelet Niveau niet toepassen +EXPORT_BYPASS_RAW_CA;Correctie Chromatische Aberratie niet toepassen [raw] +EXPORT_BYPASS_RAW_CCSTEPS;Kleurfoutonderdrukking niet toepassen [raw] +EXPORT_BYPASS_RAW_DCB_ENHANCE;DCB-verbetering niet toepassen [raw] +EXPORT_BYPASS_RAW_DCB_ITERATIONS;DCB-herhalingen niet toepassen [raw] +EXPORT_BYPASS_RAW_DF;Donkerframe niet toepassen [raw] +EXPORT_BYPASS_RAW_FF;Vlakveld niet toepassen [raw] +EXPORT_BYPASS_RAW_GREENTHRESH;Groenbalans niet toepassen [raw] +EXPORT_BYPASS_RAW_LINENOISE;Lijnruisfilter niet toepassen [raw] +EXPORT_BYPASS_RAW_LMMSE_ITERATIONS;LMMSE Verbetering niet toeppassen [raw] +EXPORT_BYPASS_SHARPENEDGE;Randen verscherpen niet toepassen +EXPORT_BYPASS_SHARPENING;Verscherpen niet toepassen +EXPORT_BYPASS_SHARPENMICRO;Microcontrast niet toepassen +EXPORT_BYPASS_SH_HQ;Schaduwen/hoge lichten (Hoge kwaliteit) niet toepassen +EXPORT_FASTEXPORTOPTIONS;Opties Snelle Export +EXPORT_INSTRUCTIONS;Snel Exporteren biedt de mogelijkheid om gereedschappen uit te schakelen die veel tijd en rekenkracht vergen tijdens het converteren. Deze methode wordt aanbevolen om snel foto's in lagere resoluties aan te maken of wanneer de grootte moet worden aangepast voor één of meerdere afbeeldingen zonder de reeds opgeslagen ontwikkelinstellingen te wijzigen. +EXPORT_MAXHEIGHT;Max. hoogte: +EXPORT_MAXWIDTH;Max. breedte: +EXPORT_PUTTOQUEUEFAST;Plaats in verwerkingsrij voor Snelle Export +EXPORT_RAW_DMETHOD;Demozaïekmethode +EXTPROGTARGET_1;raw +EXTPROGTARGET_2;verwerkingsrij +FILEBROWSER_ADDDELTEMPLATE;Voeg sjablonen toe of verwijder... +FILEBROWSER_APPLYPROFILE;Pas profiel toe +FILEBROWSER_APPLYPROFILE_PARTIAL;Pas profiel toe (gedeeltelijk) +FILEBROWSER_AUTODARKFRAME;Automatisch donkerframe +FILEBROWSER_AUTOFLATFIELD;Selecteer automatisch vlakveldopname +FILEBROWSER_BROWSEPATHBUTTONHINT;Klik om te navigeren naar het gekozen pad +FILEBROWSER_BROWSEPATHHINT;Typ het pad naar de doelmap.\nCtrl-O markeer het pad in het tekstveld.\nEnter / Ctrl-Enter open de map.\nEsc maak het tekstveld leeg.\nShift-Esc verwijder markering.\n\n\nSneltoetsen:\n ~ - gebruikers home directory\n ! - gebruikers afbeeldingen map +FILEBROWSER_CACHECLEARFROMFULL;Verwijder uit cache - volledig +FILEBROWSER_CACHECLEARFROMPARTIAL;Verwijder uit cache - gedeeltelijk +FILEBROWSER_CACHE;Cache +FILEBROWSER_CLEARPROFILE;Verwijder profiel +FILEBROWSER_COLORLABEL_TOOLTIP;Kleur label\n\nGebruik keuzemenu of nSneltoets:\nShift-Ctrl-0 Geen kleur\nShift-Ctrl-1 Rood\nShift-Ctrl-2 Geel\nShift-Ctrl-3 Groen\nShift-Ctrl-4 Blauw\nShift-Ctrl-5 Paars +FILEBROWSER_COPYPROFILE;Kopieer profiel +FILEBROWSER_CURRENT_NAME;Huidige naam: +FILEBROWSER_DARKFRAME;Donkerframe +FILEBROWSER_DELETEDLGLABEL;Bevestiging bestand verwijderen +FILEBROWSER_DELETEDLGMSGINCLPROC;Weet u zeker dat u de %1 geselecteerde bestanden wilt verwijderen *inclusief* de versies van de verwerkingsrij? +FILEBROWSER_DELETEDLGMSG;Weet u zeker dat u de geselecteerde %1 bestanden wilt verwijderen? +FILEBROWSER_EMPTYTRASHHINT;Verwijder bestanden in prullenbak voorgoed +FILEBROWSER_EMPTYTRASH;Leeg prullenbak +FILEBROWSER_EXEC_CPB;Start externe/eigen profielgenerator +FILEBROWSER_EXTPROGMENU;Open met +FILEBROWSER_FLATFIELD;Vlakveld +FILEBROWSER_MOVETODARKFDIR;Verplaats naar map met donkerframes +FILEBROWSER_MOVETOFLATFIELDDIR;Verplaats naar vlakveldmap +FILEBROWSER_NEW_NAME;Nieuwe naam: +FILEBROWSER_OPENDEFAULTVIEWER;Windows standaard viewer (verwerkingsrij) +FILEBROWSER_PARTIALPASTEPROFILE;Gedeeltelijk plakken +FILEBROWSER_PASTEPROFILE;Plak profiel +FILEBROWSER_POPUPCANCELJOB;Verwijder uit verwerkingsrij +FILEBROWSER_POPUPCOLORLABEL0;Label: Geen +FILEBROWSER_POPUPCOLORLABEL1;Label: Rood +FILEBROWSER_POPUPCOLORLABEL2;Label: Geel +FILEBROWSER_POPUPCOLORLABEL3;Label: Groen +FILEBROWSER_POPUPCOLORLABEL4;Label: Blauw +FILEBROWSER_POPUPCOLORLABEL5;Label: Paars +FILEBROWSER_POPUPCOLORLABEL;Kleur label +FILEBROWSER_POPUPCOPYTO;Kopieer naar... +FILEBROWSER_POPUPFILEOPERATIONS;Bestandsbewerkingen +FILEBROWSER_POPUPMOVEEND;Naar eind van verwerkingsrij +FILEBROWSER_POPUPMOVEHEAD;Naar begin verwerkingsrij +FILEBROWSER_POPUPMOVETO;Verplaats naar... +FILEBROWSER_POPUPOPENINEDITOR;Open in Bewerkingsvenster +FILEBROWSER_POPUPOPEN;Open +FILEBROWSER_POPUPPROCESSFAST;Plaats in verwerkingsrij voor Snelle Export +FILEBROWSER_POPUPPROCESS;Plaats in verwerkingsrij +FILEBROWSER_POPUPPROFILEOPERATIONS;Profielbewerkingen +FILEBROWSER_POPUPRANK0;Geen +FILEBROWSER_POPUPRANK1;Waardering 1 * +FILEBROWSER_POPUPRANK2;Waardering 2 ** +FILEBROWSER_POPUPRANK3;Waardering 3 *** +FILEBROWSER_POPUPRANK4;Waardering 4 **** +FILEBROWSER_POPUPRANK5;Waardering 5 ***** +FILEBROWSER_POPUPRANK;Waardering +FILEBROWSER_POPUPREMOVEINCLPROC;Verwijder (met bestand in verwerkingsrij) +FILEBROWSER_POPUPREMOVE;Verwijder van bestandssysteem +FILEBROWSER_POPUPRENAME;Hernoem +FILEBROWSER_POPUPSELECTALL;Alles selecteren +FILEBROWSER_POPUPTRASH;Verplaats naar prullenbak +FILEBROWSER_POPUPUNRANK;Verwijder sterwaardering +FILEBROWSER_POPUPUNTRASH;Haal terug uit prullenbak +FILEBROWSER_QUERYBUTTONHINT;Wis zoekopdracht +FILEBROWSER_QUERYHINT;Zoeken op bestandsnamen. Ondersteund gedeeltelijke bestandsnamen. Scheidt de zoektermen door komma's, bv.\n1001,1004,1199\n\nSluit zoektermen uit door ze te prefixen met != bv.\n!=1001,1004,1199 \n\nSneltoets:\nCtrl-f - focus het zoekveld,\nEnter - zoek,\nEsc - verwijder zoekresultaat, \nShift-Esc - verwijder focus van het zoekveld. +FILEBROWSER_QUERYLABEL; Zoeken: +FILEBROWSER_RANK1_TOOLTIP;Waardering 1 *\nSneltoets: Shift-1 +FILEBROWSER_RANK2_TOOLTIP;Waardering 2 *\nSneltoets: Shift-2 +FILEBROWSER_RANK3_TOOLTIP;Waardering 3 *\nSneltoets: Shift-3 +FILEBROWSER_RANK4_TOOLTIP;Waardering 4 *\nSneltoets: Shift-4 +FILEBROWSER_RANK5_TOOLTIP;Waardering 5 *\nSneltoets: Shift-5 +FILEBROWSER_RENAMEDLGLABEL;Hernoem bestand +FILEBROWSER_RENAMEDLGMSG;Hernoem bestand "%1" naar: +FILEBROWSER_SELECTDARKFRAME;Selecteer donkerframe... +FILEBROWSER_SELECTFLATFIELD;Kies vlakveldopname... +FILEBROWSER_SHOWCOLORLABEL1HINT;Toon foto's met label Rood\nSneltoets: Alt-1 +FILEBROWSER_SHOWCOLORLABEL2HINT;Toon foto's met label Geel\nSneltoets: Alt-2 +FILEBROWSER_SHOWCOLORLABEL3HINT;Toon foto's met label Groen\nSneltoets: Alt-3 +FILEBROWSER_SHOWCOLORLABEL4HINT;Toon foto's met label Blauw\nSneltoets: Alt-4 +FILEBROWSER_SHOWCOLORLABEL5HINT;Toon foto's met label Paars\nSneltoets: Alt-5 +FILEBROWSER_SHOWDIRHINT;Verwijder alle filters.\nSneltoets: d +FILEBROWSER_SHOWEDITEDHINT;Toon bewerkte foto's\nSneltoets: 7 +FILEBROWSER_SHOWEDITEDNOTHINT;Toon niet-bewerkte foto's\nSneltoets: 6 +FILEBROWSER_SHOWEXIFINFO;Toon EXIF-info +FILEBROWSER_SHOWRANK1HINT;Toon foto's met 1 ster.\nSneltoets: 1 +FILEBROWSER_SHOWRANK2HINT;Toon foto's met 2 sterren.\nSneltoets: 2 +FILEBROWSER_SHOWRANK3HINT;Toon foto's met 3 sterren.\nSneltoets: 3 +FILEBROWSER_SHOWRANK4HINT;Toon foto's met 4 sterren.\nSneltoets: 4 +FILEBROWSER_SHOWRANK5HINT;Toon foto's met 5 sterren.\nSneltoets: 5 +FILEBROWSER_SHOWRECENTLYSAVEDHINT;Toon recent opgeslagen/verwerkte foto's.\nSneltoets: Alt-7 +FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Toon niet-opgeslagen/verwerkte foto's.\nSneltoets: Alt-6 +FILEBROWSER_SHOWTRASHHINT;Toon inhoud prullenbak\nSneltoets: Ctrl-t +FILEBROWSER_SHOWUNCOLORHINT;Toon foto's zonder kleurlabel.\nSneltoets: Alt-0 +FILEBROWSER_SHOWUNRANKHINT;Toon foto's zonder sterwaardering.\nSneltoets: 0 +FILEBROWSER_STARTPROCESSINGHINT;Start verwerking van bestanden in verwerkingsrij +FILEBROWSER_STARTPROCESSING;Start verwerking +FILEBROWSER_STOPPROCESSINGHINT;Stop verwerking van bestanden in verwerkingsrij +FILEBROWSER_STOPPROCESSING;Stop verwerking +FILEBROWSER_THUMBSIZE;Miniaturen +FILEBROWSER_TOOLTIP_STOPPROCESSING;Start verwerking automatisch wanneer nieuwe foto arriveert +FILEBROWSER_UNRANK_TOOLTIP;Verwijder sterwaardering\nSneltoets: Shift-0 +FILEBROWSER_ZOOMINHINT;Groter +FILEBROWSER_ZOOMOUTHINT;Kleiner +GENERAL_ABOUT;Over RawTherapee +GENERAL_AFTER;Na +GENERAL_AUTO;Automatisch +GENERAL_BEFORE;Voor +GENERAL_CANCEL;Annuleren +GENERAL_CLOSE;Sluiten +GENERAL_DISABLED;Gedeactiveerd +GENERAL_DISABLE;Deactiveren +GENERAL_ENABLED;Geactiveerd +GENERAL_ENABLE;Activeer +GENERAL_FILE;Bestand +GENERAL_LANDSCAPE;Landschap +GENERAL_NA;nvt. +GENERAL_NONE;Geen +GENERAL_NO;Nee +GENERAL_OK;OK +GENERAL_PORTRAIT;Portret +GENERAL_SAVE;Opslaan +GENERAL_UNCHANGED;(Onveranderd) +GENERAL_WARNING;Waarschuwing +HISTOGRAM_TOOLTIP_BAR;Toon/verberg RGB-indicatie\nRechtermuisklik op foto om te starten/stoppen +HISTOGRAM_TOOLTIP_B;Toon/verberg blauw histogram +HISTOGRAM_TOOLTIP_CHRO;Toon/Verberg Chromaticiteit histogram +HISTOGRAM_TOOLTIP_FULL;Wissel tussen volledig of aangepast histogram +HISTOGRAM_TOOLTIP_G;Toon/verberg groen histogram +HISTOGRAM_TOOLTIP_L;Toon/verberg CIELAB-luminantiehistogram +HISTOGRAM_TOOLTIP_RAW;Toon/verberg RAW-histogram +HISTOGRAM_TOOLTIP_R;Toon/verberg rood histogram +HISTORY_CHANGED;Veranderd +HISTORY_CUSTOMCURVE;Handmatig +HISTORY_DELSNAPSHOT;Wis +HISTORY_FROMCLIPBOARD;Van klembord +HISTORY_LABEL;Geschiedenis +HISTORY_MSG_1;Foto geladen +HISTORY_MSG_2;Profiel geladen +HISTORY_MSG_3;Profiel aangepast +HISTORY_MSG_4;Door geschiedenis bladeren +HISTORY_MSG_5;Helderheid +HISTORY_MSG_6;Contrast +HISTORY_MSG_7;Schaduwen +HISTORY_MSG_8;Belichtingscompensatie +HISTORY_MSG_9;Hoge lichten Comprimeren +HISTORY_MSG_10;Schaduwcompressie +HISTORY_MSG_11;Tooncurve 1 +HISTORY_MSG_12;Automatische belichting +HISTORY_MSG_13;Drempel +HISTORY_MSG_14;L*a*b* - Helderheid +HISTORY_MSG_15;L*a*b* - Contrast +HISTORY_MSG_16;- +HISTORY_MSG_17;- +HISTORY_MSG_18;- +HISTORY_MSG_19;L*a*b* - L* curve +HISTORY_MSG_20;Verscherpen +HISTORY_MSG_21;OSM - Straal +HISTORY_MSG_22;OSM - Hoeveelheid +HISTORY_MSG_23;OSM - Drempel +HISTORY_MSG_24;OSM - Randen +HISTORY_MSG_25;OSM - Randen Straal +HISTORY_MSG_26;OSM - Randtolerantie +HISTORY_MSG_27;OSM - Halocontrole +HISTORY_MSG_28;OSM - Halo hoeveelheid +HISTORY_MSG_29;Verscherpingsmethode +HISTORY_MSG_30;RL-verscherping - Straal +HISTORY_MSG_31;RL-verscherping - Hoeveelheid +HISTORY_MSG_32;RL-verscherping - Demping +HISTORY_MSG_33;RL-verscherping - Herhaling +HISTORY_MSG_34;LCP Lensvervorming correctie +HISTORY_MSG_35;LCP Vignettering correctie +HISTORY_MSG_36;LCP CA correctie +HISTORY_MSG_37;Automatische Niveaus +HISTORY_MSG_38;Witbalans Methode +HISTORY_MSG_39;Kleurtemperatuur +HISTORY_MSG_40;Witbalans Groentint +HISTORY_MSG_41;Tooncurve Mode 1 +HISTORY_MSG_42;Tooncurve 2 +HISTORY_MSG_43;Tooncurve Mode 2 +HISTORY_MSG_44;Lum. Straal ruisond. +HISTORY_MSG_45;Lum. Randtolerantie ruisond. +HISTORY_MSG_46;Ruisonderdrukking kleur +HISTORY_MSG_47;Meng hoge lichten met matrix +HISTORY_MSG_48;Gebruik DCP's toon curve +HISTORY_MSG_49;DCP Illuminant +HISTORY_MSG_50;Schaduwen/hoge lichten +HISTORY_MSG_51;S/HL - Hoge lichten +HISTORY_MSG_52;S/HL - Schaduwen +HISTORY_MSG_53;S/HL - Toonomvang HL. +HISTORY_MSG_54;S/HL - Toonomvang S. +HISTORY_MSG_55;S/HL - Lokaal contrast +HISTORY_MSG_56;S/HL - Straal +HISTORY_MSG_57;Grof roteren +HISTORY_MSG_58;Horizontaal spiegelen +HISTORY_MSG_59;Verticaal spiegelen +HISTORY_MSG_60;Roteren +HISTORY_MSG_61;Automatisch uitvullen +HISTORY_MSG_62;Corrigeer lensvervorming +HISTORY_MSG_63;Snapshot +HISTORY_MSG_64;Bijsnijden +HISTORY_MSG_65;CA-correctie +HISTORY_MSG_66;Hoge lichten herstellen +HISTORY_MSG_67;HL herstellen hoeveelheid +HISTORY_MSG_68;HL herstellen methode +HISTORY_MSG_69;Kleurwerkruimte +HISTORY_MSG_70;Uitvoerkleurruimte +HISTORY_MSG_71;Invoerkleurruimte +HISTORY_MSG_72;VC - Hoeveelheid +HISTORY_MSG_73;Kleurkanaal Mixer +HISTORY_MSG_74;Schalingsinstelling +HISTORY_MSG_75;Schalingsmethode +HISTORY_MSG_76;Exif-metadata +HISTORY_MSG_77;IPTC-metadata +HISTORY_MSG_78;Schalen +HISTORY_MSG_79;Schalen - Breedte +HISTORY_MSG_80;Schalen - Hoogte +HISTORY_MSG_81;Schalen geactiveerd +HISTORY_MSG_82;Profiel veranderd +HISTORY_MSG_83;S/HL - Verscherpingsmasker +HISTORY_MSG_84;Perspectiefcorrectie +HISTORY_MSG_85;Lenscorrectie Profiel +HISTORY_MSG_86;RGB Curven - Luminos. Mode +HISTORY_MSG_87;Spot-ruisonderdrukking +HISTORY_MSG_88;Spot-ruis drempel +HISTORY_MSG_89;Ruisonderdrukking +HISTORY_MSG_90;RO -Luminantie +HISTORY_MSG_91;RO -Chrominantie leidend +HISTORY_MSG_92;RO -Gamma +HISTORY_MSG_93;DC waarde +HISTORY_MSG_94;Detailcontrast +HISTORY_MSG_95;L*a*b* -Chromaticiteit +HISTORY_MSG_96;L*a*b* -'a*'-curve +HISTORY_MSG_97;L*a*b* -'b*'-curve +HISTORY_MSG_98;Demozaïekmethode +HISTORY_MSG_99;Hete pixels filter +HISTORY_MSG_100;RGB Verzadiging +HISTORY_MSG_101;HSV - Tint +HISTORY_MSG_102;HSV - Verzadiging +HISTORY_MSG_103;HSV - Waarde +HISTORY_MSG_104;HSV Balans +HISTORY_MSG_105;Randverzachting +HISTORY_MSG_106;RV - Straal +HISTORY_MSG_107;RV - Drempel +HISTORY_MSG_108;Drempel Hoge lichten compr. +HISTORY_MSG_109;Hoogte en breedte +HISTORY_MSG_110;Herschalen van: +HISTORY_MSG_111;L*a*b* - Vermijd kleurversch. +HISTORY_MSG_112;--unused-- +HISTORY_MSG_113;L*a*b* - Beschermen +HISTORY_MSG_114;DCB Herhalingen +HISTORY_MSG_115;Valse kleuren onderdrukken +HISTORY_MSG_116;Verbeterd DCB +HISTORY_MSG_117;RAW CA-correctie - Rood +HISTORY_MSG_118;RAW CA-correctie - Blauw +HISTORY_MSG_119;Lijnruis +HISTORY_MSG_120;Groenbalans drempel +HISTORY_MSG_121;RAW CA-correctie - Auto +HISTORY_MSG_122;Donkerframe - Autom. selectie +HISTORY_MSG_123;Donkerframe - Bestand +HISTORY_MSG_124;Witpunt correctie +HISTORY_MSG_125;Hoge lichten behouden +HISTORY_MSG_126;Vlakveld - Bestand +HISTORY_MSG_127;Vlakveld - Autom. selectie +HISTORY_MSG_128;Vlakveld - Verzachten straal +HISTORY_MSG_129;Vlakveld - Verzachten type +HISTORY_MSG_130;Auto correctie lensvervorming +HISTORY_MSG_131;RO - Luma +HISTORY_MSG_132;RO - Chroma +HISTORY_MSG_133;Gamma +HISTORY_MSG_134;Gamma - Positie +HISTORY_MSG_135;Gamma - Vrij +HISTORY_MSG_136;Gamma - Helling +HISTORY_MSG_137;Zwartniveau - Groen 1 +HISTORY_MSG_138;Zwartniveau - Rood +HISTORY_MSG_139;Zwartniveau - Blauw +HISTORY_MSG_140;Zwartniveau - Groen 2 +HISTORY_MSG_141;Zwartniveau - Comb. groenen +HISTORY_MSG_142;RV - Herhalingen +HISTORY_MSG_143;RV - Hoeveelheid +HISTORY_MSG_144;Microcontrast - Hoeveelheid +HISTORY_MSG_145;Microcontrast - Uniformiteit +HISTORY_MSG_146;Randen verscherpen +HISTORY_MSG_147;RV - Luminantie +HISTORY_MSG_148;Microcontrast +HISTORY_MSG_149;Microcontrast - 3x3 matrix +HISTORY_MSG_150;Nabewerking demozaïek +HISTORY_MSG_151;Levendigheid +HISTORY_MSG_152;LV - Pasteltinten +HISTORY_MSG_153;LV - Verzadigde tinten +HISTORY_MSG_154;LV - Bescherm huidtinten +HISTORY_MSG_155;LV - Vermijd verschuiving +HISTORY_MSG_156;LV - Koppel pastel/verzadig +HISTORY_MSG_157;LV - P/S Drempel +HISTORY_MSG_158;TK - Sterkte +HISTORY_MSG_159;TK - Randen +HISTORY_MSG_160;TK - Schaal +HISTORY_MSG_161;TK - Herhaling +HISTORY_MSG_162;Tonen koppelen +HISTORY_MSG_163;RGB-curve - R +HISTORY_MSG_164;RGB-curve - G +HISTORY_MSG_165;RGB-curve - B +HISTORY_MSG_166;Neutrale niveaus +HISTORY_MSG_167;- +HISTORY_MSG_168;L*a*b* - CC curve +HISTORY_MSG_169;L*a*b* - CH curve +HISTORY_MSG_170;Levendigheid curve +HISTORY_MSG_171;L*a*b* - LC curve +HISTORY_MSG_172;L*a*b* - Beperk LC +HISTORY_MSG_173;RO - Luminantie Detail +HISTORY_MSG_174;CIECAM02 +HISTORY_MSG_175;CAM02 - CAT02 toepassing +HISTORY_MSG_176;CAM02 - Weergave omgeving +HISTORY_MSG_177;CAM02 - Opname Luminositeit +HISTORY_MSG_178;CAM02 - Weergave Luminositeit +HISTORY_MSG_179;CAM02 - Witpunt model +HISTORY_MSG_180;CAM02 - Lichtheid (J) +HISTORY_MSG_181;CAM02 - Chroma (C) +HISTORY_MSG_182;CAM02 - Automatisch CAT02 +HISTORY_MSG_183;CAM02 - Contrast (J) +HISTORY_MSG_184;CAM02 - Opname omgeving +HISTORY_MSG_185;CAM02 - Gamut controle +HISTORY_MSG_186;CAM02 - Algoritme +HISTORY_MSG_187;CAM02 - Rode/Huidtint bescher. +HISTORY_MSG_188;CAM02 - Helderheid (Q) +HISTORY_MSG_189;CAM02 - Contrast (Q) +HISTORY_MSG_190;CAM02 - Verzadiging (S) +HISTORY_MSG_191;CAM02 - Kleurrijkheid (M) +HISTORY_MSG_192;CAM02 - Tint (h) +HISTORY_MSG_193;CAM02 - Toon curve 1 +HISTORY_MSG_194;CAM02 - Toon curve 2 +HISTORY_MSG_195;CAM02 - Toon curve 1 +HISTORY_MSG_196;CAM02 - Toon curve 2 +HISTORY_MSG_197;CAM02 - Kleur curve +HISTORY_MSG_198;CAM02 - Kleur curve +HISTORY_MSG_199;CAM02 - Toont in histogram +HISTORY_MSG_200;CAM02 - Tonemapping +HISTORY_MSG_201;RO - Chromin. rood-groen +HISTORY_MSG_202;RO - Chromin. blauw-geel +HISTORY_MSG_203;RO - Methode +HISTORY_MSG_204;LMMSE Verbetering +HISTORY_MSG_205;CAM02 hete/dode pixels +HISTORY_MSG_206;CAT02 - Opname Lum. Auto +HISTORY_MSG_207;Verzachten Tint curve +HISTORY_MSG_208;WB - Blauw/Rood balans +HISTORY_MSG_210;GF - Hoek +HISTORY_MSG_211;Grijsverloop Filter +HISTORY_MSG_212;VF - Sterkte +HISTORY_MSG_213;Vignettering Filter +HISTORY_MSG_214;Zwart-Wit +HISTORY_MSG_215;ZW - KM - Rood +HISTORY_MSG_216;ZW - KM - Groen +HISTORY_MSG_217;ZW - KM - Blauw +HISTORY_MSG_218;ZW - Gamma - Rood +HISTORY_MSG_219;ZW - Gamma - Groen +HISTORY_MSG_220;ZW - Gamma - Blauw +HISTORY_MSG_221;ZW - Kleur Filter +HISTORY_MSG_222;ZW - Voorinstelling +HISTORY_MSG_223;ZW - KM - Oranje +HISTORY_MSG_224;ZW - KM - Geel +HISTORY_MSG_225;ZW - KM - Cyaan +HISTORY_MSG_226;ZW - KM - Magenta +HISTORY_MSG_227;ZW - KM - Paars +HISTORY_MSG_228;ZW - Luminantie Mixer +HISTORY_MSG_229;ZW - Luminantie Mixer +HISTORY_MSG_230;ZW - Mode +HISTORY_MSG_231;ZW - 'Voor' curve +HISTORY_MSG_232;ZW - 'Voor' curve type +HISTORY_MSG_233;ZW - 'Na' curve +HISTORY_MSG_234;ZW - 'Na' curve type +HISTORY_MSG_235;ZW - Auto Kanaalmixer +HISTORY_MSG_236;- +HISTORY_MSG_237;ZW Mixer +HISTORY_MSG_238;GF - Straal +HISTORY_MSG_239;GF - Sterkte +HISTORY_MSG_240;GF - Centrum +HISTORY_MSG_241;VF - Straal +HISTORY_MSG_242;VF - Vorm +HISTORY_MSG_243;VC - Straal +HISTORY_MSG_244;VC - Sterkte +HISTORY_MSG_245;VC - Centrum +HISTORY_MSG_246;L*a*b* - CL curve +HISTORY_MSG_247;L*a*b* - LH curve +HISTORY_MSG_248;L*a*b* - HH curve +HISTORY_MSG_249;DC - Drempel +HISTORY_MSG_250;RO - Verbeteren +HISTORY_MSG_251;ZW - Algoritme +HISTORY_MSG_252;DC - Huidtonen +HISTORY_MSG_253;DC - Verminder artefacten +HISTORY_MSG_254;DC - Huidtint +HISTORY_MSG_255;DC - Algoritme +HISTORY_MSG_255;RO - Mediaan Filter +HISTORY_MSG_256;RO - Mediaan Type +HISTORY_MSG_257;Kleurtint +HISTORY_MSG_258;KT - Kleur curve +HISTORY_MSG_259;KT - Dekking +HISTORY_MSG_260;KT - a*[b*] Dekking +HISTORY_MSG_261;KT - Methode +HISTORY_MSG_262;KT - b* Dekking +HISTORY_MSG_263;KT - Schaduwen - Rood +HISTORY_MSG_264;KT - Schaduwen - Groen +HISTORY_MSG_265;KT - Schaduwen - Blauw +HISTORY_MSG_266;KT - Midden - Rood +HISTORY_MSG_267;KT - Midden - Groen +HISTORY_MSG_268;KT - Midden - Blauw +HISTORY_MSG_269;KT - Hoog - Rood +HISTORY_MSG_270;KT - Hoog - Groen +HISTORY_MSG_271;KT - Hoog - Blauw +HISTORY_MSG_272;KT - Balans +HISTORY_MSG_273;KT - Beginwaarde +HISTORY_MSG_274;KT - Verz. Schaduwen +HISTORY_MSG_275;KT - Verz. Hoge lichten +HISTORY_MSG_276;KT - Dekking +HISTORY_MSG_277;--unused-- +HISTORY_MSG_278;KT - Behoud luminantie +HISTORY_MSG_279;KT - Schaduwen +HISTORY_MSG_280;KT - Hoge lichten +HISTORY_MSG_281;KT - Verz. sterkte +HISTORY_MSG_282;KT - Verz. drempel +HISTORY_MSG_283;KT - Sterkte +HISTORY_MSG_284;KT - Auto verz. bescherming +HISTORY_MSG_285;RO - Mediaan - Methode +HISTORY_MSG_286;RO - Mediaan - Type +HISTORY_MSG_287;RO - Mediaan - Herhalingen +HISTORY_MSG_288;Vlakveld - Clip Controle +HISTORY_MSG_289;Vlakveld - Clip Controle - Auto +HISTORY_MSG_290;Zwartniveau - Rood +HISTORY_MSG_291;Zwartniveau - Groen +HISTORY_MSG_292;Zwartniveau - Blauw +HISTORY_MSG_293;Film Simuleren +HISTORY_MSG_294;Film - Sterkte +HISTORY_MSG_295;Film - Film +HISTORY_MSG_296;RO - Luminantie curve +HISTORY_MSG_297;RO - Kwaliteit +HISTORY_MSG_298;Dode pixels filter +HISTORY_MSG_299;RO - Chrominantie curve +HISTORY_MSG_300;- +HISTORY_MSG_301;RO - Luma controle +HISTORY_MSG_302;RO - Chroma methode +HISTORY_MSG_303;RO - Chroma methode +HISTORY_MSG_304;Wavelet niveau +HISTORY_MSG_305;Wavelet niveau +HISTORY_MSG_306;Wavelet N° niveau +HISTORY_MSG_307;Wavelet Ch niveau +HISTORY_MSG_308;Wavelet richting +HISTORY_MSG_309;Wavelet tegels +HISTORY_MSG_310;Wavelet Tinten lucht +HISTORY_MSG_311;Wavelet Max niveau's +HISTORY_MSG_312;Wavelet Schaduwen drempel +HISTORY_MSG_313;Wavelet Pastel Verzadigd +HISTORY_MSG_314;Wavelet Artefacten blauwe lucht +HISTORY_MSG_315;Wavelet Contrast Rest afbeelding +HISTORY_MSG_316;Wavelet Tinten huid +HISTORY_MSG_317;Wavelet Tinten reeks Huid +HISTORY_MSG_318;Wavelet Hoge lichten niveau +HISTORY_MSG_319;Wavelet Hoge lichten reeks +HISTORY_MSG_320;Wavelet Schaduwen reeks +HISTORY_MSG_321;Wavelet Schaduwen niveau +HISTORY_MSG_322;Wavelet kleurverschuiving +HISTORY_MSG_323;Wavelet Chroma niveau +HISTORY_MSG_324;Wavelet Chroma pastel +HISTORY_MSG_325;Wavelet Chroma verzadigd +HISTORY_MSG_326;Wavelet Chroma methode +HISTORY_MSG_327;Wavelet Contrast methode +HISTORY_MSG_328;Wavelet Chroma koppelen +HISTORY_MSG_329;Wavelet Dekking Rood-Groen +HISTORY_MSG_330;Wavelet Dekking Blauw-Geel +HISTORY_MSG_331;Wavelet Extra +HISTORY_MSG_332;Wavelet Tegels Methode +HISTORY_MSG_333;Wavelet Schaduwen Rest afbeelding +HISTORY_MSG_334;Wavelet Chroma +HISTORY_MSG_335;Wavelet Hoge lichten Rest afbeelding +HISTORY_MSG_336;Wavelet Hoge lichten drempel +HISTORY_MSG_337;Wavelet Tinten reeks Lucht +HISTORY_MSG_338;Wavelet Randen Straal +HISTORY_MSG_339;Wavelet Randen Waarde +HISTORY_MSG_340;Wavelet Sterkte +HISTORY_NEWSNAPSHOT;Nieuw +HISTORY_NEWSNAPSHOT_TOOLTIP;Sneltoets: Alt-s +HISTORY_SNAPSHOTS;Snapshots +HISTORY_SNAPSHOT;Nieuw +IPTCPANEL_AUTHORSPOSITIONHINT;Titel van de maker(s) van het object (By-line Title) +IPTCPANEL_AUTHORSPOSITION;Positie van de maker +IPTCPANEL_AUTHOR;Auteur +IPTCPANEL_CAPTIONHINT;Tekstuele omschrijving van de data (Omschrijving - abstract) +IPTCPANEL_CAPTIONWRITERHINT;De naam van de persoon betrokken bij het schrijven, bewerken of corrigeren van de foto of omschrijving (Schrijver - Editor) +IPTCPANEL_CAPTIONWRITER;Maker van de omschrijving +IPTCPANEL_CAPTION;Omschrijving +IPTCPANEL_CATEGORYHINT;Beschrijft het onderwerp van de foto volgens de mening van de maker (Categorie) +IPTCPANEL_CATEGORY;Categorie +IPTCPANEL_CITYHINT;Plaats van de opname (Plaats) +IPTCPANEL_CITY;Plaats +IPTCPANEL_COPYHINT;Kopieer IPTC-instellingen naar klembord +IPTCPANEL_COPYRIGHTHINT;Eventuele vereiste copyright-meldingen (Copyright-melding) +IPTCPANEL_COPYRIGHT;Copyright +IPTCPANEL_COUNTRYHINT;De naam van het land/primaire locatie waar de foto werd genomen (Land - Primaire locatienaam) +IPTCPANEL_COUNTRY;Land +IPTCPANEL_CREDITHINT;Naam van de leverancier van de foto, niet noodzakelijkerwijs de eigenaar/maker (Credit) +IPTCPANEL_CREDIT;Credit +IPTCPANEL_DATECREATEDHINT;Datum waarop de foto werd genomen; formaat: JJJJMMDD (Opnamedatum) +IPTCPANEL_DATECREATED;Opnamedatum +IPTCPANEL_EMBEDDEDHINT;Keer terug naar IPTC-data die in de foto zijn opgeslagen +IPTCPANEL_EMBEDDED;Ingebed +IPTCPANEL_HEADLINEHINT;Samenvatting van de inhoud van de foto (Titel) +IPTCPANEL_HEADLINE;Titel +IPTCPANEL_INSTRUCTIONSHINT;Andere instructies mbt. beeldgebruik (Speciale Instructies) +IPTCPANEL_INSTRUCTIONS;Instructies +IPTCPANEL_KEYWORDSHINT;Gebruikt om sleutelwoorden mee te geven tbv. zoekdoeleinden (Sleutelwoorden) +IPTCPANEL_KEYWORDS;Sleutelwoorden +IPTCPANEL_PASTEHINT;Plak IPTC-instellingen van klembord +IPTCPANEL_PROVINCEHINT;De provincie/staat/departement waar de foto werd genomen (Provincie-Staat) +IPTCPANEL_PROVINCE;Provincie +IPTCPANEL_RESETHINT;Terug naar standaardwaarden +IPTCPANEL_RESET;Standaardwaarden +IPTCPANEL_SOURCEHINT;De oorspronkelijke eigenaar van de foto (Bron) +IPTCPANEL_SOURCE;Bron +IPTCPANEL_SUPPCATEGORIESHINT;Verdere verfijning van het onderwerp van de foto (Extra categorieën) +IPTCPANEL_SUPPCATEGORIES;Extra categorieën +IPTCPANEL_TITLEHINT;Een korte referentienaam voor de foto (Objectnaam) +IPTCPANEL_TITLE;Titel +IPTCPANEL_TRANSREFERENCEHINT;Een code die de locatie van de oorspronkelijke transmissie representeert (Original Transmission Reference) +IPTCPANEL_TRANSREFERENCE;Trans. Reference +MAIN_BUTTON_FULLSCREEN;Volledig scherm +MAIN_BUTTON_NAVNEXT_TOOLTIP;Navigeer naar de volgende afbeelding relatief ten opzichte van de geopende afbeelding in de Editor\nSneltoets: Shift-F4\n\nNavigeer naar de volgende afbeelding relatief ten opzichte van de miniatuur geselecteerd in de Bestandsnavigator\nSneltoets: F4 +MAIN_BUTTON_NAVPREV_TOOLTIP;Navigeer naar de vorige afbeelding relatief ten opzichte van de geopende afbeelding in de Editor\nShortcut: Shift-F3 \n\nNavigeer naar de vorige afbeelding relatief ten opzichte van de miniatuur geselecteerd in de Bestandsnavigator\nSneltoets: F3 +MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchroniseer de Bestandsnavigator met de Editor om de miniatuur te tonen van de huidig geopende afbeelding, en verwijder de filters in de Bestandsnavigator \nSneltoets: x\n\nAls voorgaand, maar zonder het verwijderen van de filters in de Bestandsnavigator \nSneltoets: y\n(NB de miniatuur van de geopende afbeelding zal niet worden getoond indien gefilterd) +MAIN_BUTTON_PREFERENCES;Voorkeuren +MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Plaats huidige foto in verwerkingsrij.\nSneltoets: Ctrl+B +MAIN_BUTTON_SAVE_TOOLTIP;Bewaar huidige foto.\nSneltoets: Ctrl+S +MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Stuur huidige foto naar extern fotobewerkingsprogramma.\nSneltoets: Ctrl+E +MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Toon/verberg alle zijpanelen.\nSneltoets: m +MAIN_BUTTON_UNFULLSCREEN;Verlaat volledig scherm +MAIN_FRAME_BATCHQUEUE;Verwerkingsrij +MAIN_FRAME_BATCHQUEUE_TOOLTIP; Verwerkingsrij.\nSneltoets: Ctrl-F3 +MAIN_FRAME_EDITOR;Fotobewerker +MAIN_FRAME_EDITOR_TOOLTIP; Bewerking.\nSneltoets: Ctrl-F4 +MAIN_FRAME_FILEBROWSER;Bestandsnavigator +MAIN_FRAME_FILEBROWSER_TOOLTIP; Bestandsnavigator.\nSneltoets: Ctrl-F2 +MAIN_FRAME_PLACES;Locaties +MAIN_FRAME_PLACES_ADD;Nieuw +MAIN_FRAME_PLACES_DEL;Wis +MAIN_FRAME_RECENT;Recente mappen +MAIN_MSG_ALREADYEXISTS;Bestand bestaat reeds. +MAIN_MSG_CANNOTLOAD;Fout bij laden +MAIN_MSG_CANNOTSAVE;Fout bij opslaan van de afbeelding +MAIN_MSG_CANNOTSTARTEDITOR;Kan fotoprogramma niet starten. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Geef juiste pad op in 'Voorkeuren'. +MAIN_MSG_EMPTYFILENAME;Geen bestandsnaam opgegeven! +MAIN_MSG_IMAGEUNPROCESSED;Deze opdracht vereist dat alle geselecteerde foto's eerst moeten zijn verwerkt. +MAIN_MSG_NAVIGATOR;Navigator +MAIN_MSG_OPERATIONCANCELLED;Opdracht afgebroken +MAIN_MSG_PATHDOESNTEXIST;Het pad\n\n%1\n\nbestaat niet. Zet een correct pad bij Voorkeuren. +MAIN_MSG_QOVERWRITE;Wilt u het bestand overschrijven? +MAIN_MSG_SETPATHFIRST;Specificeer eerst een doelmap in Voorkeuren \nom deze functionaliteit te kunnen gebruiken! +MAIN_MSG_WRITEFAILED;Niet opgeslagen\n\n"%1"\n\nControleer of de map bestaat en dat u schrijfrechten heeft. +MAIN_TAB_COLOR;Kleur +MAIN_TAB_COLOR_TOOLTIP;Sneltoets: Alt-c +MAIN_TAB_DETAIL;Detail +MAIN_TAB_DETAIL_TOOLTIP;Sneltoets: Alt-d +MAIN_TAB_DEVELOP;Ontwikkel +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPORT; Exporteren +MAIN_TAB_EXPOSURE;Belichting +MAIN_TAB_EXPOSURE_TOOLTIP;Sneltoets: Alt-e +MAIN_TAB_FILTER;Filter +MAIN_TAB_INSPECT; Inspecteren +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadata +MAIN_TAB_METADATA_TOOLTIP;Sneltoets: Alt-m +MAIN_TAB_RAW;RAW +MAIN_TAB_RAW_TOOLTIP;Sneltoets: Alt-r +MAIN_TAB_TRANSFORM;Transformeer +MAIN_TAB_TRANSFORM_TOOLTIP;Sneltoets: Alt-t +MAIN_TOOLTIP_BACKCOLOR0;Achtergrond kleur van het voorbeeld: Thema-based\nSneltoets: 8 +MAIN_TOOLTIP_BACKCOLOR1;Achtergrond kleur van het voorbeeld: Zwart\nSneltoets: 9 +MAIN_TOOLTIP_BACKCOLOR2;Achtergrond kleur van het voorbeeld: Wit\nSneltoets: 0 +MAIN_TOOLTIP_BEFOREAFTERLOCK;Vergrendel / Ontgrendel de Voorafbeelding.\n\nVergrendel: hou de Voorafbeelding ongewijzigd.\nDit is handig om het cumulatieve effect van meerdere gereedschappen te beoordelen.\nBovendien kan er worden vergeleken met elke stap in de geschiedenislijst.\n\nOntgrendel: de Voorafbeelding volgt een stap achter de Naafbeelding en laat de afbeelding zien zonder het effect van het huidige gereedschap. +MAIN_TOOLTIP_HIDEHP;Toon/verberg linkerpaneel (geschiedenis).\nSneltoets: H +MAIN_TOOLTIP_INDCLIPPEDH;Overbelichtingsindicatie.\nSneltoets: < +MAIN_TOOLTIP_INDCLIPPEDS;Onderbelichtingsindicatie.\nSneltoets: > +MAIN_TOOLTIP_PREVIEWB;Bekijk het Blauwe kanaal.\nSneltoets: b +MAIN_TOOLTIP_PREVIEWFOCUSMASK;Bekijk het Focus Masker.\nSneltoets: Shift-F\n\nAccurater bij afbeeldingen met geringe scherptediepte, weinig ruis en hogere zoomniveaus.\n\nBekijk de afbeelding op lagere zoomniveaus (10-30%) om de accuratesse te vergroten bij afbeeldingen met veel ruis.\n\nHet voorbeeld wordt langzamer aangemaakt als Focus Masker aanstaat. +MAIN_TOOLTIP_PREVIEWG;Bekijk het Groene kanaal.\nSneltoets: g +MAIN_TOOLTIP_PREVIEWL;Bekijk de Luminositeit.\nSneltoets: v\n\n0.299*R + 0.587*G + 0.114*B +MAIN_TOOLTIP_PREVIEWR;Bekijk het Rode kanaal.\nSneltoets: r +MAIN_TOOLTIP_QINFO;Beknopte fotogegevens +MAIN_TOOLTIP_SHOWHIDELP1;Toon/verberg linkerpaneel.\nSneltoets: l +MAIN_TOOLTIP_SHOWHIDERP1;Toon/verberg rechterpaneel.\nSneltoets: Alt-l +MAIN_TOOLTIP_SHOWHIDETP1;Toon/verberg bovenste paneel.\nSneltoets: Shift-L +MAIN_TOOLTIP_THRESHOLD;Drempel +MAIN_TOOLTIP_TOGGLE;Vergelijk origineel en bewerking +NAVIGATOR_B;B: +NAVIGATOR_G;G: +NAVIGATOR_H;H: +NAVIGATOR_LAB_A;a*: +NAVIGATOR_LAB_B;b*: +NAVIGATOR_LAB_L;L*: +NAVIGATOR_NA; -- +NAVIGATOR_R;R: +NAVIGATOR_S;S: +NAVIGATOR_V;V: +NAVIGATOR_XY_FULL;Breedte: %1, Hoogte: %2 +NAVIGATOR_XY_NA;x: --, y: -- +OPTIONS_DEFIMG_MISSING;Het standaard profiel voor non-raw foto's kan niet worden gevonden of is niet ingesteld.\n\nControleer de map met de profielen, deze kan missen of beschadigd zijn.\n\nDe standaard waarden zullen worden gebruikt. +OPTIONS_DEFRAW_MISSING;Het standaard profiel voor raw foto's kan niet worden gevonden of is niet ingesteld.\n\nControleer de map met de profielen, deze kan missen of beschadigd zijn.\n\nDe standaard waarden zullen worden gebruikt. +PARTIALPASTE_BASICGROUP;Basisinstellingen +PARTIALPASTE_CACORRECTION;C/A-correctie +PARTIALPASTE_CHANNELMIXERBW;Zwart-Wit +PARTIALPASTE_CHANNELMIXER;Kleurkanaal mixer +PARTIALPASTE_COARSETRANS;90 graden roteren/spiegelen +PARTIALPASTE_COLORAPP;CIE Color Appearance Model 2002 +PARTIALPASTE_COLORGROUP;Kleurgerelateerde instellingen +PARTIALPASTE_COLORTONING;Kleurtinten +PARTIALPASTE_COMMONTRANSFORMPARAMS;Automatisch uitvullen +PARTIALPASTE_COMPOSITIONGROUP;Compositie-instellingen +PARTIALPASTE_CROP;Bijsnijden +PARTIALPASTE_DARKFRAMEAUTOSELECT;Donkerframe autom. selectie +PARTIALPASTE_DARKFRAMEFILE;Donkerframe-opname +PARTIALPASTE_DEFRINGE;Verzachten +PARTIALPASTE_DETAILGROUP;Detailinstellingen +PARTIALPASTE_DIALOGLABEL;Profiel gedeeltelijk plakken... +PARTIALPASTE_DIRPYRDENOISE;Ruisonderdrukking +PARTIALPASTE_DIRPYREQUALIZER;Detailcontrast +PARTIALPASTE_DISTORTION;Corrigeer lensvervorming +PARTIALPASTE_EPD;Tonemapping +PARTIALPASTE_EQUALIZER;Wavelet Balans +PARTIALPASTE_EVERYTHING;Alles +PARTIALPASTE_EXIFCHANGES;Wijzig Exif-gegevens +PARTIALPASTE_EXPOSURE;Belichting +PARTIALPASTE_FILMSIMULATION;Film Simuleren +PARTIALPASTE_FLATFIELDAUTOSELECT;Vlakveld autoselectie +PARTIALPASTE_FLATFIELDBLURRADIUS;Vlakveld verzachting straal +PARTIALPASTE_FLATFIELDBLURTYPE;Vlakveld verzachting type +PARTIALPASTE_FLATFIELDCLIPCONTROL;Vlakveld clip controle +PARTIALPASTE_FLATFIELDFILE;Vlakveldopname +PARTIALPASTE_GRADIENT;Grijsverloop Filter +PARTIALPASTE_HSVEQUALIZER;HSV-balans +PARTIALPASTE_ICMGAMMA;Uitvoer gamma +PARTIALPASTE_ICMSETTINGS;ICM-instellingen +PARTIALPASTE_IMPULSEDENOISE;Spot ruisonderdrukking +PARTIALPASTE_IPTCINFO;IPTC-informatie +PARTIALPASTE_LABCURVE;LAB-curve +PARTIALPASTE_LENSGROUP;Lensgerelateerde instellingen +PARTIALPASTE_LENSPROFILE;Lens correctie profiel +PARTIALPASTE_METAGROUP;Metadata +PARTIALPASTE_PCVIGNETTE;Vignettering Filter +PARTIALPASTE_PERSPECTIVE;Perspectief +PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dode pixels filter +PARTIALPASTE_PREPROCESS_GREENEQUIL;Groenbalans +PARTIALPASTE_PREPROCESS_HOTPIXFILT;Hete pixels filter +PARTIALPASTE_PREPROCESS_LINEDENOISE;Lijnruisfilter +PARTIALPASTE_RAWCACORR_AUTO;Autom. C/A-correctie +PARTIALPASTE_RAWCACORR_CABLUE;C/A Blauw +PARTIALPASTE_RAWCACORR_CARED;C/A Rood +PARTIALPASTE_RAWEXPOS_BLACK;Zwartniveau +PARTIALPASTE_RAWEXPOS_LINEAR;Raw witpunt- lineaire corr. factor +PARTIALPASTE_RAWEXPOS_PRESER;Raw witpunt- herstel hoge lichten (EV) +PARTIALPASTE_RAWGROUP;Raw-instellingen +PARTIALPASTE_RAW_DCBENHANCE;Pas DCB-verbetering toe +PARTIALPASTE_RAW_DCBITERATIONS;aantal DCB-herhalingen +PARTIALPASTE_RAW_DMETHOD;Demozaïekmethode +PARTIALPASTE_RAW_FALSECOLOR;Demozaïek stapgrootte kleurfoutonderdrukking +PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE verbetering +PARTIALPASTE_RESIZE;Wijzig grootte +PARTIALPASTE_RGBCURVES;RGB-curven +PARTIALPASTE_ROTATION;Roteren +PARTIALPASTE_SHADOWSHIGHLIGHTS;Schaduwen/hoge lichten +PARTIALPASTE_SHARPENEDGE;Randen +PARTIALPASTE_SHARPENING;Verscherping +PARTIALPASTE_SHARPENMICRO;Microcontrast +PARTIALPASTE_VIBRANCE;Levendigheid +PARTIALPASTE_VIGNETTING;Vignetteringscorrectie +PARTIALPASTE_WHITEBALANCE;Witbalans +PREFERENCES_ADD;Toevoegen +PREFERENCES_APPLNEXTSTARTUP;herstart vereist +PREFERENCES_AUTLISLOW;Laag +PREFERENCES_AUTLISMAX;Max - Gemiddelde van alle tegels +PREFERENCES_AUTLISVLOW;Geen +PREFERENCES_AUTLOW;Laag +PREFERENCES_AUTOMONPROFILE;Gebruik automatisch het standaard monitorprofiel \nvan het besturingsysteem +PREFERENCES_AUTSTD;Standaard +PREFERENCES_BATCH_PROCESSING;Batch-verwerking +PREFERENCES_BEHADDALLHINT;Zet alle parameters in de Toevoegen mode.\nWijzigingen van parameters in de batch tool zijn deltas op de opgeslagen waarden. +PREFERENCES_BEHADDALL;Alles op 'Toevoegen' +PREFERENCES_BEHAVIOR;Gedrag +PREFERENCES_BEHSETALLHINT;Zet alle parameters in de Activeer mode.\nWijzigingen van parameters in de batch tool zijn absoluut. De actuele waarden worden gebruikt. +PREFERENCES_BEHSETALL;Alles op 'Activeer' +PREFERENCES_BLACKBODY;Tungsten(wolfraam) +PREFERENCES_CACHECLEARALL;Wis alles +PREFERENCES_CACHECLEARPROFILES;Wis profielen +PREFERENCES_CACHECLEARTHUMBS;Wis miniaturen +PREFERENCES_CACHEMAXENTRIES;Maximaal aantal elementen in cache +PREFERENCES_CACHEOPTS;Cache-opties +PREFERENCES_CACHETHUMBHEIGHT;Maximale hoogte miniaturen +PREFERENCES_CIEART;CIECAM02 optimalisatie +PREFERENCES_CIEART_FRAME;CIECAM02-Specifieke instellingen +PREFERENCES_CIEART_LABEL;Gebruik float precisie in plaats van double +PREFERENCES_CIEART_TOOLTIP;Indien aangezet worden CIECAM02 berekening uitgevoerd in het single-precision floating-point formaat in plaats van double-precision. Dit levert een iets hogere verwerkingssnelheid ten koste van een verwaarloosbaar verlies aan kwaliteit +PREFERENCES_CLIPPINGIND;Indicatie over-/onderbelichting +PREFERENCES_CLUTSCACHE;HaldCLUT cache +PREFERENCES_CLUTSCACHE_LABEL;Maximum aantal cached Cluts +PREFERENCES_CLUTSDIR;HaldCLUT map +PREFERENCES_CMETRICINTENT;Bedoelde colorimetrie +PREFERENCES_CUSTPROFBUILDHINT;Programma (of script) dat wordt aangeroepen om een initieel profiel voor foto te maken.\nOntvangt terminalparameters voor het genereren van pp3's gebaseerd op regels:\n[Pad RAW/JPG] [Pad default profiel] [f-getal] [belichting in sec] [brandpuntsafstand in mm] [ISO] [lens] [Camera make] [camera model]\n\n WAARSCHUWING: Indien een pad spaties bevat moeten er dubbele quotes worden gezet om het pad. +PREFERENCES_CUSTPROFBUILDKEYFORMAT;Keys formaat +PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME;Naam +PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;TagID +PREFERENCES_CUSTPROFBUILDPATH;Pad naar programma of script +PREFERENCES_CUSTPROFBUILD;Eigen/externe profielgenerator +PREFERENCES_CUTOVERLAYBRUSH;Kleur uitsnedemasker +PREFERENCES_D50;5000K +PREFERENCES_D55;5500K +PREFERENCES_D60;6000K +PREFERENCES_D65;6500K +PREFERENCES_DARKFRAMEFOUND;Gevonden +PREFERENCES_DARKFRAMESHOTS;foto's +PREFERENCES_DARKFRAMETEMPLATES;sjablonen +PREFERENCES_DARKFRAME;Donkerframe +PREFERENCES_DATEFORMATHINT;U kunt de volgende formaten gebruiken:\n%y : jaar\n%m : maand\n%d : dag\n\nHet Nederlandse datumformaat is bijvoorbeeld:\n%d/%m/%y +PREFERENCES_DATEFORMAT;Datumformaat +PREFERENCES_DAUB_LABEL;Gebruik Daubechies D6 wavelets in plaats van D4 +PREFERENCES_DEFAULTLANG;Standaardtaal +PREFERENCES_DEFAULTTHEME;Standaardthema +PREFERENCES_DIRDARKFRAMES;Map met donkerframes +PREFERENCES_DIRHOME;Standaardmap +PREFERENCES_DIRLAST;Laatst bezochte map +PREFERENCES_DIROTHER;Anders +PREFERENCES_DIRSELECTDLG;Selecteer standaardmap bij opstarten... +PREFERENCES_DIRSOFTWARE;Installatiemap +PREFERENCES_EDITORCMDLINE;Andere editor, geef pad +PREFERENCES_EDITORLAYOUT;Bewerkingsvenster +PREFERENCES_EXPAUT;Expert +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_FLATFIELDFOUND;Gevonden +PREFERENCES_FLATFIELDSDIR;Vlakveldmap +PREFERENCES_FLATFIELDSHOTS;foto's +PREFERENCES_FLATFIELDTEMPLATES;sjablonen +PREFERENCES_FLATFIELD;Vlakveldopname (tbv. vignetteringscorrectie) +PREFERENCES_FLUOF2;Fluorescent F2 +PREFERENCES_FLUOF7;Fluorescent F7 +PREFERENCES_FLUOF11;Fluorescent F11 +PREFERENCES_FORIMAGE;Voor niet-RAW-bestanden +PREFERENCES_FORRAW;Voor RAW-bestanden +PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT;Zelfde hoogte miniaturen in Bewerkingsvenster en Bestandsnavigator +PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT_HINT;Verschillende hoogtes voor miniaturen vereist meer verwerkingstijd wanneer je wisselt tussen Bewerkingsvenster en Bestandsnavigator +PREFERENCES_GIMPPATH;Installatiemap GIMP +PREFERENCES_GREY05;Yb=05 CIE L#30 +PREFERENCES_GREY10;Yb=10 CIE L#40 +PREFERENCES_GREY15;Yb=15 CIE L#45 +PREFERENCES_GREY18;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_GREYSC18;Yb=18 CIE L#50 +PREFERENCES_GREYSCA;Automatisch +PREFERENCES_GREYSC;Omgeving Yb luminantie (%) +PREFERENCES_GREY;Uitvoerapparaat's Yb luminantie (%) +PREFERENCES_HISTOGRAMPOSITIONLEFT;Histogram in linkerpaneel +PREFERENCES_HISTOGRAMWORKING;Gebruik het werkprofiel voor het Hoofdhistogram en de Navigator +PREFERENCES_HISTOGRAM_TOOLTIP;Het werkprofiel wordt gebruikt voor het Hoofdhistogram en de Navigator. In alle andere gevallen wordt het gamma-gecorrigeerde uitvoerprofiel gebruikt. +PREFERENCES_HLTHRESHOLD;Grenswaarde overbelichting +PREFERENCES_ICCDIR;Map met ICC-profielen +PREFERENCES_IMG_RELOAD_NEEDED;Deze wijzigingen vereisen dat de afbeelding wordt herladen (of dat een nieuwe afbeelding wordt geopend). +PREFERENCES_IMPROCPARAMS;Standaardprofiel +PREFERENCES_INSPECT_LABEL;Inspecteren +PREFERENCES_INSPECT_MAXBUFFERS_LABEL;Maximum aantal afbeeldingen in cache +PREFERENCES_INSPECT_MAXBUFFERS_TOOLTIP;Het maximum aantal afbeeldingen in de cache wanneer je in de Bestandsnavigator met de cursor over de miniaturen beweegt. Op computers met weinig RAM geheugen (2 Gb) moet deze waarde op 1 of 2 worden gezet. +PREFERENCES_INTENT_ABSOLUTE;Absolute colorimetrie +PREFERENCES_INTENT_PERCEPTUAL;Waargenomen colorimetrie +PREFERENCES_INTENT_RELATIVE;Relatieve colorimetrie +PREFERENCES_INTENT_SATURATION;Verzadiging +PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Toon interne JPEG-miniatuur indien onbewerkt +PREFERENCES_LANGAUTODETECT;Gebruik taalinstellingen pc +PREFERENCES_LEVAUTDN;Ruisonderdrukking niveau +PREFERENCES_LEVDN;Cell grootte +PREFERENCES_LISS;Auto multi-zone verzachten +PREFERENCES_MAX;Maxi (Tegel) +PREFERENCES_MED;Gemiddeld (Tegel/2) +PREFERENCES_MENUGROUPEXTPROGS;Groepeer open met +PREFERENCES_MENUGROUPFILEOPERATIONS;Groepeer bestandsbewerkingen +PREFERENCES_MENUGROUPLABEL;Groepeer labelen +PREFERENCES_MENUGROUPPROFILEOPERATIONS;Groepeer profielbewerkingen +PREFERENCES_MENUGROUPRANK;Groepeer markering +PREFERENCES_MENUOPTIONS;Menu-opties +PREFERENCES_METADATA;Metadata +PREFERENCES_MIN;Mini (100x115) +PREFERENCES_MONITORICC;Monitorprofiel +PREFERENCES_MULTITABDUALMON;Multi-tab, indien beschikbaar op tweede monitor +PREFERENCES_MULTITAB;Multi-tab: elke foto opent in nieuw tabvenster +PREFERENCES_NAVGUIDEBRUSH;Navigator randkleur +PREFERENCES_NOISE;Ruisonderdrukking +PREFERENCES_OUTDIRFOLDERHINT;Sla foto's op in andere map +PREFERENCES_OUTDIRFOLDER;Sla op in map +PREFERENCES_OUTDIRTEMPLATEHINT;U kunt de volgende formaten gebruiken:\n%f, %d1, %d2, ..., %p1, %p2, ..., %r\n\nDeze formaten hebben betrekking op de mappen, submappen en atributen van het RAW-bestand.\n\nAls bijvoorbeeld /home/tom/image/02-09-2006/dsc0012.nef is geopend, hebben deze formaten de volgende betekenis:\n%f=dsc0012, %d1=02-09-2006, %d2=foto, ...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\n%r wordt vervangen door de rank van de foto. Als de foto geen rank heeft, wordt %r vervangen door '0'. Als de foto in de prullenbak zit zal %r worden vervangen door 'x'.\n\nWanneer de geconverteerde RAW-foto in dezelfde map moet komen als het origineel, schrijf dan:\n%p1/%f\n\nIndien u de geconverteerde RAW-foto in een map genaamd 'geconverteerd' wilt plaatsen die een submap is van de oorspronkelijke locatie, schrijft u:\n%p1/geconverteerd/%f\n\nWilt u het geconverteerde RAW-bestand bewaren in map '/home/tom/geconverteerd' met behoud van dezelfde submap met datums, schrijf dan:\n%p2/geconverteerd/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Gebruik sjabloon +PREFERENCES_OUTDIR;Uitvoermap +PREFERENCES_OVERLAY_FILENAMES;Toon bestandsnamen over miniaturen +PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Toon bestandsnaam over miniaturen in het Bewerkingsvenster +PREFERENCES_OVERWRITEOUTPUTFILE;Overschrijf bestaande output-bestanden +PREFERENCES_PANFACTORLABEL;Factor +PREFERENCES_PARSEDEXTADDHINT;Typ nieuwe extensie en druk op knop om aan lijst toe te voegen +PREFERENCES_PARSEDEXTADD;Voeg extensie toe +PREFERENCES_PARSEDEXTDELHINT;Verwijder geselecteerde extensie(s) uit lijst +PREFERENCES_PARSEDEXT;Toon extensies +PREFERENCES_PREVDEMO;Voorbeeld Demozaïekmethode +PREFERENCES_PREVDEMO_FAST;Snel +PREFERENCES_PREVDEMO_LABEL;Demozaïekmethode van het voorbeeld bij <100% zoom: +PREFERENCES_PREVDEMO_SIDECAR;Gelijk aan PP3 +PREFERENCES_PROFILEHANDLING;Verwerking profielen +PREFERENCES_PROFILELOADPR;Laadprioriteit profielen +PREFERENCES_PROFILEPRCACHE;Profiel in cache +PREFERENCES_PROFILEPRFILE;Profiel bij RAW-bestand +PREFERENCES_PROFILESAVECACHE;Bewaar profiel in cache +PREFERENCES_PROFILESAVEINPUT;Bewaar profiel bij RAW-bestand +PREFERENCES_PROPERTY;Eigenschap +PREFERENCES_PSPATH;Installatiemap Adobe Photoshop +PREFERENCES_RGBDTL_LABEL;Maximum aantal 'threads' voor Ruisonderdrukking en Wavelet (gedeeld door 2) +PREFERENCES_RGBDTL_TOOLTIP;Ruisonderdrukking en Wavelet gebruiken ongeveer 128MB RAM voor een 10MPix afbeelding, of 512MB voor een 40MPix afbeelding en additioneel 128MB RAM per thread. Hoe meer threads parallel worden gebruikt, hoe sneller de bewerking. Laat de instelling op "0" staan om automatisch het maximale aantal threads te gebruiken dat mogelijk is. +PREFERENCES_SELECTFONT;Kies lettertype +PREFERENCES_SELECTLANG;Selecteer taal +PREFERENCES_SELECTTHEME;Kies thema +PREFERENCES_SET;Activeer +PREFERENCES_SHOWBASICEXIF;Toon standaard Exif-info +PREFERENCES_SHOWDATETIME;Toon datum en tijd +PREFERENCES_SHOWEXPOSURECOMPENSATION;Toon belichtingscompensatie +PREFERENCES_SHOWFILMSTRIPTOOLBAR;Toon filmstrip werkbalk +PREFERENCES_SHTHRESHOLD;Grenswaarde onderbelichting +PREFERENCES_SIMPLAUT;Gereedschap +PREFERENCES_SINGLETABVERTAB;Enkel-tab ('filmstrip') modus met verticale tabs +PREFERENCES_SINGLETAB;Enkel-tab: foto's openen in zelfde tabvenster +PREFERENCES_SLIMUI;Slanke interface +PREFERENCES_SMA;Klein (250x287) +PREFERENCES_SND_BATCHQUEUEDONE;Verwerkingsrij klaar +PREFERENCES_SND_HELP;Typ bestandsnaam (of niets: geen geluid).\nWindows: gebruik 'SystemDefault', 'SystemAsterisk', etc. voor systeemgeluiden.\nLinux: gebruik "complete", "window-attention" etc. voor systeemgeluiden +PREFERENCES_SND_LNGEDITPROCDONE;Bewerking klaar +PREFERENCES_SND_TRESHOLDSECS;na seconden +PREFERENCES_STARTUPIMDIR;Standaardmap bij opstarten +PREFERENCES_STDAUT;Standaard +PREFERENCES_TAB_BROWSER;Bestandsnavigator +PREFERENCES_TAB_COLORMGR;Kleurbeheer +PREFERENCES_TAB_GENERAL;Algemeen +PREFERENCES_TAB_IMPROC;Beeldverwerking +PREFERENCES_TAB_PERFORMANCE;Prestaties en Kwaliteit +PREFERENCES_TAB_SOUND;Geluiden +PREFERENCES_TIMAX;Hoog +PREFERENCES_TINB;Aantal tegles +PREFERENCES_TISTD;Standaard +PREFERENCES_TP_LABEL;Gereedschapspaneel: +PREFERENCES_TP_USEICONORTEXT;Gebruik iconen ipv. tekst voor de tabbladen +PREFERENCES_TP_VSCROLLBAR;Verberg de schuifbalk van het gereedschapspaneel +PREFERENCES_TUNNELMETADATA;Kopieer IPTC/XMP-data onveranderd naar uitvoerbestand \n(praktisch indien extern programma voor tagging wordt gebruikt) +PREFERENCES_USEBUNDLEDPROFILES;Gebruik gebundelde profielen +PREFERENCES_USESYSTEMTHEME; Gebruik systeemthema +PREFERENCES_VIEW;Witbalans instelling van het uitvoerapparaat (monitor, TV, projector...) +PREFERENCES_WAVLEV;Vergroot wavelet ninveau voor kwaliteit 'hoog' +PREFERENCES_WLONE;Eén niveau +PREFERENCES_WLTWO;Twee niveau's +PREFERENCES_WLZER;Nee +PREFERENCES_WORKFLOW;Layout +PROFILEPANEL_COPYPPASTE;Te kopiëren parameters +PROFILEPANEL_GLOBALPROFILES;Gebundelde profielen +PROFILEPANEL_LABEL;Profielen +PROFILEPANEL_LOADDLGLABEL;Kies profiel... +PROFILEPANEL_LOADPPASTE;Te laden parameters +PROFILEPANEL_MODE_TIP;Profiel aanvullen.\n\nKnop ingedrukt: gedeeltelijke profielen worden omgezet naar volledige profielen. De ontbrekende waarden worden vervangen door hard-coded defaults.\n\nKnop neutraal: profielen worden toegepast zo als ze zijn, alleen de aanwezige waarden worden gewijzigd. +PROFILEPANEL_MYPROFILES;Mijn profielen +PROFILEPANEL_PASTEPPASTE;Te plakken parameters +PROFILEPANEL_PCUSTOM;Handmatig +PROFILEPANEL_PFILE;Uit bestand +PROFILEPANEL_PINTERNAL;Neutraal +PROFILEPANEL_PLASTSAVED;Laatst opgeslagen +PROFILEPANEL_SAVEDLGLABEL;Bewaar profiel... +PROFILEPANEL_SAVEPPASTE;Te bewaren parameters +PROFILEPANEL_TOOLTIPCOPY;Kopieer huidig profiel naar klembord +PROFILEPANEL_TOOLTIPLOAD;Laad profiel uit bestand +PROFILEPANEL_TOOLTIPPASTE; Plak profiel van klembord +PROFILEPANEL_TOOLTIPSAVE;Bewaar huidig profiel.\nCtrl-click voor het selecteren van de instellingen voor opslaan. +PROGRESSBAR_LOADINGTHUMBS;Miniaturen laden... +PROGRESSBAR_LOADING;Afbeelding laden... +PROGRESSBAR_LOADJPEG;Laden JPEG-bestand... +PROGRESSBAR_LOADPNG;Laden PNG-bestand... +PROGRESSBAR_LOADTIFF;Laden TIFF-bestand... +PROGRESSBAR_NOIMAGES;Geen afbeeldingen +PROGRESSBAR_PROCESSING;Foto verwerken... +PROGRESSBAR_PROCESSING_PROFILESAVED;Uitvoeren 'Profiel opslaan' +PROGRESSBAR_READY;Gereed +PROGRESSBAR_SAVEJPEG;Opslaan JPEG-bestand... +PROGRESSBAR_SAVEPNG;Opslaan PNG-bestand... +PROGRESSBAR_SAVETIFF;Opslaan TIFF-bestand... +PROGRESSBAR_SNAPSHOT_ADDED;Snapshot toegevoegd +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profiel veranderd in bestandsnavigator +QINFO_ISO;ISO +QINFO_NOEXIF;Exif-gegevens niet beschikbaar. +REFERENCES_AUTLISSTD;Hoog +SAVEDLG_AUTOSUFFIX;Voeg automatisch ophogend nummer (-1, -2..) toe als bestand al bestaat +SAVEDLG_FILEFORMAT;Bestandstype +SAVEDLG_FORCEFORMATOPTS;Forceer opties voor opslaan +SAVEDLG_JPEGQUAL;JPEG-kwaliteit +SAVEDLG_PNGCOMPR;PNG-compressie +SAVEDLG_PUTTOQUEUEHEAD;Plaats vooraan in verwerkingsrij +SAVEDLG_PUTTOQUEUETAIL;Plaats achteraan in verwerkingsrij +SAVEDLG_PUTTOQUEUE;Plaats in verwerkingsrij +SAVEDLG_SAVEIMMEDIATELY;Bewaar meteen +SAVEDLG_SAVESPP;Bewaar afbeelding met profiel +SAVEDLG_SUBSAMP;Subsampling +SAVEDLG_SUBSAMP_1;Beste compressie +SAVEDLG_SUBSAMP_2;Gebalanceerd +SAVEDLG_SUBSAMP_3;Beste kwaliteit +SAVEDLG_SUBSAMP_TOOLTIP;Beste Compressie: 4:1:1\nGebalanceerd: 4:2:2\nBeste kwaliteit: 4:4:4 +SAVEDLG_TIFFUNCOMPRESSED;Geen compressie +SAVEDLG_WARNFILENAME;Bestandsnaam wordt +SHCSELECTOR_TOOLTIP;Klik op de rechtermuisknop om\nde 3 knoppen te verschuiven +THRESHOLDSELECTOR_BL;Onderkant-links +THRESHOLDSELECTOR_BR;Onderkant-rechts +THRESHOLDSELECTOR_B;Onderkant +THRESHOLDSELECTOR_HINT;Houdt de Shift-toets ingedrukt om individuele controle punten te verschuiven. +THRESHOLDSELECTOR_TL;Bovenkant-links +THRESHOLDSELECTOR_TR;Bovenkant-rechts +THRESHOLDSELECTOR_T;Bovenkant +TOOLBAR_TOOLTIP_CROP;Bijsnijden.\nSneltoets: c +TOOLBAR_TOOLTIP_HAND;Sleepgereedschap.\nSneltoets: h +TOOLBAR_TOOLTIP_STRAIGHTEN;Rechtmaken / Kleine rotaties.\nSneltoets: s\n\nBepaal de vertikale of horizontale as door het trekken van een hulplijn over de afbeelding. De rotatiehoek wordt naast de hulplijn getoond. Het centrum van de roatatie is het geometrische midden van de afbeelding. +TOOLBAR_TOOLTIP_WB;Witbalans.\nSneltoets: w +TP_BWMIX_ALGO;Algoritme OYCPM +TP_BWMIX_ALGO_LI;Linear +TP_BWMIX_ALGO_SP;Speciale effecten +TP_BWMIX_ALGO_TOOLTIP;Linear: creëert een normale lineare response.\nSpeciale effecten: creëert speciale effecten door kanalen non-linearl te mixen. +TP_BWMIX_AUTOCH;Auto +TP_BWMIX_AUTOCH_TIP;Bereken optimale waardes voor de kanaalmixer. +TP_BWMIX_CC_ENABLED;Wijzig complementaire kleur +TP_BWMIX_CC_TOOLTIP;Automatische aanpassing van complementaire kleuren in ROYGCBPM mode. +TP_BWMIX_CHANNEL;Luminantie Balans +TP_BWMIX_CURVEEDITOR1;'Voor' curve +TP_BWMIX_CURVEEDITOR2;'Na' curve +TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Toon curve wordt toegepast na de Zwart-Wit conversie. +TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Toon curve wordt toegepast voor de Zwart-Wit conversie\nHoudt rekening met de kleur componenten. +TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Wijzig luminantie in de functie van hue\nNegatieve waarden kunnen artefacten of onregelmatigheden veroorzaken. +TP_BWMIX_FILTER;Kleur Filter +TP_BWMIX_FILTER_BLUEGREEN;Blauw-Groen +TP_BWMIX_FILTER_BLUE;Blauw +TP_BWMIX_FILTER_GREENYELLOW;Groen-Geel +TP_BWMIX_FILTER_GREEN;Groen +TP_BWMIX_FILTER_NONE;Geen +TP_BWMIX_FILTER_PURPLE;Paars +TP_BWMIX_FILTER_REDYELLOW;Rood-Geel +TP_BWMIX_FILTER_RED;Rood +TP_BWMIX_FILTER_TOOLTIP;Het kleurfilter heeft hetzelfde effect als een voor de lens geplaatst filter. Kleurfilters reduceren specifieke reeksen van kleuren en beninvloeden de helderheid. Bv. een rood filter maak een blauwe lucht donkerder. +TP_BWMIX_FILTER_YELLOW;Geel +TP_BWMIX_GAMMA;Gamma Correctie +TP_BWMIX_GAM_TOOLTIP;Corrigeer gamma voor elk RGB kanaal +TP_BWMIX_LABEL;Zwart-Wit +TP_BWMIX_MET;Methode +TP_BWMIX_MET_CHANMIX;Kanaalmixer +TP_BWMIX_MET_DESAT;Desatureren +TP_BWMIX_MET_LUMEQUAL;Luminantie Balans +TP_BWMIX_MIXC;Mixer +TP_BWMIX_NEUTRAL;Terug naar beginwaarde +TP_BWMIX_NEUTRAL_TIP;Zet alle waardes - schuifbalken - filters - kanaalmixers terug naar de standaard waarde. +TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Totaal: %4%% +TP_BWMIX_RGBLABEL_HINT;RGB omrekeningsfactoren. Hierin zijn alle gekozen opties vewerkt.\nTotaal toont de som van de uit te voeren RGB factoren:\n- dit is altijd 100% in relatieve mode\n- hoger (lichter) of lager (donkerder) dan 100% in absolute mode. +TP_BWMIX_RGB_TOOLTIP;Mix de RGB kanalen. Gebruik Voorinstellingen voor aanwijzingen.\nNegatieve waarden kunnen artefacten of onregelmatigheden veroorzaken. +TP_BWMIX_SETTING;Voorinstellingen +TP_BWMIX_SETTING_TOOLTIP;Verschillende voorinstellingen (film, landschap, etc.) of handmatige instellingen van de kanaalmixer. +TP_BWMIX_SET_HIGHCONTAST;Hoog Contrast +TP_BWMIX_SET_HIGHSENSIT;Hoge Gevoeligheid +TP_BWMIX_SET_HYPERPANCHRO;Hyper Panchromatisch +TP_BWMIX_SET_INFRARED;Infrarood +TP_BWMIX_SET_LANDSCAPE;Landschap +TP_BWMIX_SET_LOWSENSIT;Lage Gevoeligheid +TP_BWMIX_SET_LUMINANCE;Luminantie +TP_BWMIX_SET_NORMCONTAST;Normaal Contrast +TP_BWMIX_SET_ORTHOCHRO;Orthochromatisch +TP_BWMIX_SET_PANCHRO;Panchromatisch +TP_BWMIX_SET_PORTRAIT;Portret +TP_BWMIX_SET_RGBABS;Absolute RGB +TP_BWMIX_SET_RGBREL;Relatieve RGB +TP_BWMIX_SET_ROYGCBPMABS;Absolute ROYGCBPM +TP_BWMIX_SET_ROYGCBPMREL;Relatieve ROYGCBPM +TP_BWMIX_TCMODE_FILMLIKE;Z&W Film-achtig +TP_BWMIX_TCMODE_SATANDVALBLENDING;Z-W Verzadinging en Waarde menging +TP_BWMIX_TCMODE_STANDARD;Z-W Standaard +TP_BWMIX_TCMODE_WEIGHTEDSTD;Z-W Gewogen Standard +TP_BWMIX_VAL;L +TP_CACORRECTION_BLUE;Blauw +TP_CACORRECTION_LABEL;Corrigeer chromatische aberratie +TP_CACORRECTION_RED;Rood +TP_CHMIXER_BLUE;Blauw +TP_CHMIXER_GREEN;Groen +TP_CHMIXER_LABEL;Kleurkanaal mixer +TP_CHMIXER_RED;Rood +TP_CHROMATABERR_LABEL;Chromatische aberratie +TP_COARSETRAF_TOOLTIP_HFLIP;Horizontaal spiegelen +TP_COARSETRAF_TOOLTIP_ROTLEFT;Rotate left.\n\nSneltoets:\n[ - Multi-tab Mode,\nAlt-[ - Enkel-tab Mode. +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Rotate right.\n\nSneltoets:\n] - Multi-tab Mode,\nAlt-] - Enkel-tab Mode. +TP_COARSETRAF_TOOLTIP_VFLIP;Verticaal spiegelen +TP_COLORAPP_ADAPTSCENE;Opnameomgeving luminositeit +TP_COLORAPP_ADAPTSCENE_TOOLTIP;Absolute luminantie van de opnameomgeving (cd/m²).\n1) Berekend op basis van de Exif data:\nSluitertijd - ISO-waarde - Diafragma - Camera belichtingscompensatie.\n2) Berekend op basis van het raw witpunt en RT's Belichtingscompensatie +TP_COLORAPP_ADAPTVIEWING;Weergaveomgeving luminositeit (cd/m2) +TP_COLORAPP_ADAPTVIEWING_TOOLTIP;Absolute luminantie van de weergaveomgeving \n(gebruikelijk 16cd/m²) +TP_COLORAPP_ADAP_AUTO_TOOLTIP;Als het keuzevakje is aangezet (aanbevolen), dan berekent RT de optimale waarde op basis van de Exif data.\nOm de waarde handmatig in te stellen moet het keuzevakje worden uitgezet +TP_COLORAPP_ALGO;Algoritme +TP_COLORAPP_ALGO_ALL;Alle +TP_COLORAPP_ALGO_JC;Lichtheid + Chroma (JC) +TP_COLORAPP_ALGO_JS;Lichtheid + Verzadiging (JS) +TP_COLORAPP_ALGO_QM;Helderheid + Kleurrijkheid (QM) +TP_COLORAPP_ALGO_TOOLTIP;Keuze uit parameters +TP_COLORAPP_BADPIXSL;Hete/dode pixel filter +TP_COLORAPP_BADPIXSL_TOOLTIP;Onderdruk hete/dode (sterk gekleurde) pixels.\n 0=geen effect 1=mediaan 2=gaussian.\n\nDeze artefacten zijn het gevolg van de beperkingen van CIECAM02. Het alternatief is het aanpassen van de afbeelding om zeer donkere schaduwen te voorkomen. +TP_COLORAPP_BRIGHT;Helderheid (Q) +TP_COLORAPP_BRIGHT_TOOLTIP;Helderheid in CIECAM02 is verschillend van Lab en RGB, hou rekening met de luminositeit van wit +TP_COLORAPP_CHROMA;Chroma (C) +TP_COLORAPP_CHROMA_M;Kleurrijkheid (M) +TP_COLORAPP_CHROMA_M_TOOLTIP;Kleurrijkheid in CIECAM02 is verschillend van Lab en RGB +TP_COLORAPP_CHROMA_S;Verzadiging (S) +TP_COLORAPP_CHROMA_S_TOOLTIP;Verzadiging in CIECAM02 is verschillend van Lab en RGB +TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 is verschillend van Lab en RGB +TP_COLORAPP_CIECAT_DEGREE;CAT02 toepassen +TP_COLORAPP_CONTRAST;Contrast (J) +TP_COLORAPP_CONTRAST_Q;Contrast (Q) +TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrast (Q)in CIECAM02 is verschillend van Lab en RGB +TP_COLORAPP_CONTRAST_TOOLTIP;Contrast (J) in CIECAM02 is verschillend van Lab en RGB +TP_COLORAPP_CURVEEDITOR1;Toon curve 1 +TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Toont het histogram van L (Lab) voor CIECAM wijzigingen.\n\nHet histogram toont J,Q na toepassing van CIECAM, indien het selectievakje 'Toon CIECAM uitvoer' is aangezet.\n(J,Q) worden niet getoond in het hoofd histogram. \n\nRaadpleeg voor de definitieve uitvoer het Histogram paneel. +TP_COLORAPP_CURVEEDITOR2;Toon curve 2 +TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Heeft dezelfde werking als belichtings 'Toon Curve 2'. +TP_COLORAPP_CURVEEDITOR3;Chroma curve +TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Wijzigt ofwel chroma, verzadiging of kleurrijkheid.\n Het Histogram toont chromaticiteit (Lab) voor CIECAM wijzigingen.\nHet Histogram toont C,s,M na toepassing van CIECAM indien het selectievakje 'Toon CIECAM uitvoer' is aangezet.\n(C,s,M) worden niet getoond in het Hoofd histogram paneel. \nRaadpleeg het Histogram paneel voor de definitieve uitvoer +TP_COLORAPP_DATACIE;CIECAM02 uitvoer histogram in de curven +TP_COLORAPP_DATACIE_TOOLTIP;Indien aangezet, tonen de histogrammen van de CIECAM02 curven bij benadering de waarden/reeksen voor J of Q, en C, s of M na de CIECAM02 aanpassingen.\nDit beïnvloed niet het hoofd histogram paneel.\n\nIndien uitgezet tonen de histogrammen van de CIECAM02 curven de Lab waarden zoals deze waren voor de CIECAM02 aanpassingen +TP_COLORAPP_DEGREE_AUTO_TOOLTIP;Als het keuzevakje is aangezet (aanbevolen), dan berekent RT een optimale waarde. Deze wordt gebruikt door CAT02 en door CIECAM02.\nOm de waarden handmatig in te stellen moet het keuzevakje worden uitgezet (waarden groter dan 65 worden aanbevolen) +TP_COLORAPP_DEGREE_TOOLTIP;Hoeveelheid van CIE Chromatic Adaptation Transform 2002 +TP_COLORAPP_GAMUT;Gamut controle (Lab) +TP_COLORAPP_GAMUT_TOOLTIP;Sta gamut controle toe in Lab mode +TP_COLORAPP_HUE;Tint (h) +TP_COLORAPP_HUE_TOOLTIP;Tint (h) - hoek tussen 0° en 360° +TP_COLORAPP_LABEL;CIE Color Appearance Model 2002 +TP_COLORAPP_LABEL_CAM02;Afbeelding wijzigen +TP_COLORAPP_LABEL_SCENE;Opnameomstandigheden +TP_COLORAPP_LABEL_VIEWING;Weergaveomstandigheden +TP_COLORAPP_LIGHT;Lichtheid (J) +TP_COLORAPP_LIGHT_TOOLTIP;Lichtheid in CIECAM02 verschilt van Lab en RGB lichtheid +TP_COLORAPP_MODEL;Witpunt Model +TP_COLORAPP_MODEL_TOOLTIP;WB [RT] + [uitvoer]:\nRT's WB wordt gebruikt voor de opname, CIECAM02 wordt gezet op D50. Het uitvoerapparaat's wit gebruikt de instelling van Voorkeuren > Kleurbeheer\n\nWB [RT+CAT02] + [output]:\nRT's WB instellingen worden gebruikt door CAT02 en het uitvoerapparaat's wit gebruikt de waarde van de Voorkeuren. +TP_COLORAPP_RSTPRO;Rode en Huidtinten bescherming +TP_COLORAPP_RSTPRO_TOOLTIP;Rode en Huidtinten bescherming (schuifbalk en curven) +TP_COLORAPP_SHARPCIE;Verscherpen, Detailcontrast, Microcontrast & Randen met Q/C +TP_COLORAPP_SHARPCIE_TOOLTIP;Verscherpen, Detailcontrast, Microcontrast & Randen zullen CIECAM02 gebruiken wanneer dit is aangezet. +TP_COLORAPP_SURROUND;Omgeving +TP_COLORAPP_SURROUND_AVER;Gemmideld +TP_COLORAPP_SURROUND_DARK;Donker +TP_COLORAPP_SURROUND_DIM;Gedimd +TP_COLORAPP_SURROUND_EXDARK;Duister +TP_COLORAPP_SURROUND_TOOLTIP;Verander tonen en kleuren rekening houdend met de weergaveomstandigheden van het uitvoerapparaat\n\nGemiddeld:\nGemiddeld verlichte omgeving (standaard)\nDe afbeelding zal niet veranderen \n\nGedimd:\nGedimde omgeving (TV)\nDe afbeelding zal enigszins donkerder worden\n\nDonker:\nDonkere omgeving (projector)\nDe afbeelding zal veel donkerder worden\n\nDuister:\nDuistere omgeving\nDe afbeelding zal zeer donker worden +TP_COLORAPP_SURSOURCE;Donkere omgeving +TP_COLORAPP_SURSOURCE_TOOLTIP;Kan worden gebruikt als de fotos is gemaakt in een donkere omgeving +TP_COLORAPP_TCMODE_BRIGHTNESS;Helderheid +TP_COLORAPP_TCMODE_CHROMA;Chroma +TP_COLORAPP_TCMODE_COLORF;Kleurrijkheid +TP_COLORAPP_TCMODE_LABEL1;Curve modus 1 +TP_COLORAPP_TCMODE_LABEL2;Curve modus 2 +TP_COLORAPP_TCMODE_LABEL3;Curve chroma modus +TP_COLORAPP_TCMODE_LIGHTNESS;lichtheid +TP_COLORAPP_TCMODE_SATUR;Verzadiging +TP_COLORAPP_TONECIE;Tonemapping gebruik makend van CIECAM +TP_COLORAPP_TONECIE_TOOLTIP;Indien uitgezet zal tonemapping plaats vinden in Lab.\nIndien aangezet zal tonemapping gebruik maken van CIECAM02.\nVoorwaarde is dat Tonemapping (Lab/CIECAM02) actief is. +TP_COLORAPP_WBCAM;WB [RT+CAT02] + [uitvoer] +TP_COLORAPP_WBRT;WB [RT] + [uitvoer] +TP_COLORTONING_AB;o C/L +TP_COLORTONING_AUTOSAT;Automatisch +TP_COLORTONING_BALANCE;Balans +TP_COLORTONING_BY;o C/L +TP_COLORTONING_CHROMAC;Dekking +TP_COLORTONING_COLOR;Kleur +TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;Chroma dekking als een functie van Luminantie oC=f(L) +TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;Dekking Chroma op basis van Luminantie (C=f(L)) +TP_COLORTONING_HIGHLIGHT;Hoge lichten +TP_COLORTONING_HUE;Kleurtint +TP_COLORTONING_LABEL;Kleurtinten +TP_COLORTONING_LAB;L*a*b* menging +TP_COLORTONING_LUMAMODE;Behoud luminantie +TP_COLORTONING_LUMAMODE_TOOLTIP;Wanneer de kleur wijzigt (rood, groen, cyaan, blauw, etc.) blijft de luminatie van elke pixel behouden. +TP_COLORTONING_LUMA;Luminantie +TP_COLORTONING_METHOD;Methode +TP_COLORTONING_METHOD_TOOLTIP;"L*a*b* menging", "RGB schuifbalk" en "RGB curven" gebruiken interpolatie kleurmenging.\n"Kleurbalans" (Schaduwen/Midden tonen/Hoge lichten) en "Verzadigen 2 kleuren" gebruiken directe kleuren.\nAlle methodes werken ook op Zwart-Wit. +TP_COLORTONING_MIDTONES;Midden tonen +TP_COLORTONING_NEUTRAL;Terug naar beginstand +TP_COLORTONING_NEUTRAL_TIP;Zet alle waarden (Schaduwen, Midden tonen, Hoge lichten) terug naar default. +TP_COLORTONING_OPACITY;Dekking +TP_COLORTONING_RGBCURVES;RGB - Curven +TP_COLORTONING_RGBSLIDERS;RGB - Schuifbalken +TP_COLORTONING_SATURATEDOPACITY;Sterkte +TP_COLORTONING_SATURATIONTHRESHOLD;Drempel +TP_COLORTONING_SA;Verzadiging bescherming +TP_COLORTONING_SHADOWS;Schaduwen +TP_COLORTONING_SPLITCOCO;Kleurbalans SMH +TP_COLORTONING_SPLITCO;Schaduwen/Midden tonen/Hoge lichten +TP_COLORTONING_SPLITLR;Verzadiging 2 kleuren +TP_COLORTONING_STRENGTH;Sterkte +TP_COLORTONING_TWO2;Speciaal chroma '2 kleuren' +TP_COLORTONING_TWOALL;Speciaal chroma +TP_COLORTONING_TWOBY;Speciaal a* en b* +TP_COLORTONING_TWOCOLOR_TOOLTIP;Standaard chroma:\nLineaire response, a* = b*.\n\nSpeciaal chroma:\nLineaire response, a* = b*, maar zonder begrenzing - probeer beneden de diagonaal.\n\nSpeciaal a* en b*:\nLineaire response zonder begrenzing met aparte curves voor a* en b*. Bedoeld voor speciale effecten.\n\nSpeciaal chroma 2 kleuren: meest voorspelbare uitkomst. +TP_COLORTONING_TWOSTD;Standaard chroma +TP_CROP_FIXRATIO;Verhouding: +TP_CROP_GTDIAGONALS;Diagonaalmethode +TP_CROP_GTEPASSPORT;Biometrisch paspoort +TP_CROP_GTFRAME;Frame +TP_CROP_GTGRID;Raster +TP_CROP_GTNONE;Geen +TP_CROP_GTRULETHIRDS;Regel van derden +TP_CROP_GUIDETYPE;Hulplijnen: +TP_CROP_H;Hoogte +TP_CROP_LABEL;Bijsnijden +TP_CROP_PPI;PPI= +TP_CROP_SELECTCROP;Selecteer gebied +TP_CROP_W;Breedte +TP_CROP_X;X +TP_CROP_Y;Y +TP_DARKFRAME_AUTOSELECT;Automatische selectie +TP_DARKFRAME_LABEL;Donkerframe +TP_DEFRINGE_LABEL;Verzachten (Lab/CIECAM02) +TP_DEFRINGE_RADIUS;Straal +TP_DEFRINGE_THRESHOLD;Drempel +TP_DIRPYRDENOISE_33;3x3 sterk +TP_DIRPYRDENOISE_55SOFT;5x5 +TP_DIRPYRDENOISE_55;5x5 sterk +TP_DIRPYRDENOISE_77;7x7 (langzaaam) +TP_DIRPYRDENOISE_99;9x9 (erg langzaam) +TP_DIRPYRDENOISE_ABM;Alleen chroma +TP_DIRPYRDENOISE_AUTO;Automatisch algemeen +TP_DIRPYRDENOISE_AUTO_TOOLTIP;Probeert chroma ruis te bepalen\nWees voorzichtig, deze berekening is een gemiddelde en kan subjectief zijn! +TP_DIRPYRDENOISE_AUT;Automatisch algemeen +TP_DIRPYRDENOISE_BLUE;Chrominantie Blauw & Geel +TP_DIRPYRDENOISE_C2TYPE_TOOLTIP;Handmatig\nWerkt op de hele afbeelding.\nDe instellingen voor ruisonderdrukking moeten zelf worden bepaald.\n\nAutomatisch algemeen\nWerkt op de hele afbeelding.\n9 gebieden worden gebruikt om de chroma ruisonderdrukking te bepalen.\n\nVoorbeeld\nWerkt op de hele afbeelding.\nHet deel van de afbeelding dat zichtbaar is in het voorbeeld wordt gebruikt om de chroma ruisonderdrukking te bepalen. +TP_DIRPYRDENOISE_CCCURVE;Chrominantie curve +TP_DIRPYRDENOISE_CHROMAFR;Chrominantie +TP_DIRPYRDENOISE_CHROMA;Chrominantie (master) +TP_DIRPYRDENOISE_CTYPE;Auto methode +TP_DIRPYRDENOISE_CTYPE_TOOLTIP;Handmatig\nWerkt op de hele afbeelding.\nDe instellingen voor ruisonderdrukking moeten zelf worden bepaald.\n\nAutomatisch algemeen\nWerkt op de hele afbeelding.\n9 gebieden worden gebruikt om de chroma ruisonderdrukking te bepalen.\n\nAutomatisch multi-zones\nGeen voorbeeld - werkt alleen bij opslaan. Gebruik de "Voorbeeld" methode om een idee te krijgen van het verwachte resultaat door de tegelgrootte en het centrum van het voorbeeld te matchen.\nDe afbeelding is verdeeld in tegels (10 tot 70 afhankelijk van de afbeeldingsgrootte) en van elke tegel wordt de eigen chroma ruisonderdrukking bepaald.\n\Voorbeeld\nWerkt op de hele afbeelding.\nHet deel van de afbeelding dat zichtbaar is in het voorbeeld wordt gebruikt om de chroma ruisonderdrukking te bepalen. +TP_DIRPYRDENOISE_CURVEEDITOR_CC;Chroma +TP_DIRPYRDENOISE_CURVEEDITOR_CC_TOOLTIP;Vergroot (vermenigvuldigt) de waarde van alle chrominantie schuifbalken.\nMet deze curve kun je de sterkte aanpassen van de chromatische ruisonderdrukking. Bijvoorbeeld door de werking te vergroten in gebieden met lage verzadiging en te verminderen in gebieden met hoge verzadiging. +TP_DIRPYRDENOISE_CURVEEDITOR_L_TOOLTIP;Luminantie ruisonderdrukking. Werkt niet lineair maar modulerend +TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Kan worden gebruikt op raw en niet-raw afbeeldingen.\n\nVoor niet-raw afbeeldingen geldt dat ruisonderdrukking van de luminantie afhangt van het gamma van het invoerprofiel. Standaard wordt uitgegaan van het gamma van sRGB. Als de afbeelding dus een kleurprofiel heeft met een afwijkend gamma, zal de luminantie ruisonderdrukking verschillen. +TP_DIRPYRDENOISE_ENH;Verbeteren +TP_DIRPYRDENOISE_ENH_TOOLTIP;Verbetert de ruisonderdrukking, maar vergroot de verwerkingstijd met ongeveer 20% +TP_DIRPYRDENOISE_GAMMA;Gamma +TP_DIRPYRDENOISE_GAMMA_TOOLTIP;Gamma varieert de mate van ruisonderdrukking over het bereik van tinten. Kleinere waarden beperken zich tot schaduwen, terwijl grotere waarden het bereik oprekken tot heldere tinten +TP_DIRPYRDENOISE_LABEL;Ruisonderdrukking +TP_DIRPYRDENOISE_LABM;L*a*b* +TP_DIRPYRDENOISE_LCURVE;Luminantie curve +TP_DIRPYRDENOISE_LDETAIL;Luminantie Detail +TP_DIRPYRDENOISE_LM;Alleen Luminantie +TP_DIRPYRDENOISE_LPLABM;Gewogen L* (weinig) + a*b* (normaal) +TP_DIRPYRDENOISE_LTYPE;Type gereedschap +TP_DIRPYRDENOISE_LUMAFR;Luminantie +TP_DIRPYRDENOISE_LUMAFR_TOOLTIP;Wavelet voor Luminantie- en Fourier transformatie voor betere details bij luminantie +TP_DIRPYRDENOISE_LUMA;Luminantie +TP_DIRPYRDENOISE_MANU;Handmatig +TP_DIRPYRDENOISE_MAN;Handmatig +TP_DIRPYRDENOISE_MEDMETHOD;Methode +TP_DIRPYRDENOISE_MEDTYPE;Type +TP_DIRPYRDENOISE_MED;Mediaan filter +TP_DIRPYRDENOISE_MED_TOOLTIP;Mediaan ruisonderdrukking +TP_DIRPYRDENOISE_METHOD11;Kwaliteit +TP_DIRPYRDENOISE_METHOD11_TOOLTIP;De kwaliteit kan worden aangepast aan de hoeveelheid ruis. \nHoog verbetert de ruisonderdrukking, maar verlengt de verwerkingstijd +TP_DIRPYRDENOISE_METHOD;Methode +TP_DIRPYRDENOISE_METHOD_TOOLTIP;Voor raw afbeeldingen kan RGB of Lab methode worden gebruikt.\n\nVoor niet-raw afbeeldingen zal altijd de Lab methode worden gebruikt, ongeacht de geselecteerde methode. +TP_DIRPYRDENOISE_METM_TOOLTIP;De "Alleen Luminantie" en "L*a*b*" methodes worden meteen na de wavelet stap uitgevoerd bij het onderdrukken van ruis.\nDe "RGB" methode, wordt echter als laatste stap uitgevoerd bij ruisonderdrukking. +TP_DIRPYRDENOISE_MET_TOOLTIP;Mediaan filters. Hoe groter de omvang, hoe langer de verwerking.\n\n3x3: bewerkt 5 pixels in een 1-pixel reeks.\n3x3 sterk: bewerkt 9 pixels in een 1-pixel reeks.\n5x5 soft: bewerkt 13 pixels in een 2-pixel reeks.\n5x5: bewerkt 25 pixels in een 2-pixel reeks.\n7x7: bewerkt 49 pixels in een 3-pixel reeks.\n9x9: bewerkt 81 pixels in een 4-pixel reeks.\n\nSoms is het mogelijk om een beter resultaat te behalen door meerdere iteraties met een kleinere reeks uit te voeren dan 1 iteratie met een grotere reeks. +TP_DIRPYRDENOISE_NOISELABELEMPTY;Voorbeeld ruis: Gemiddeld= - Hoog= - +TP_DIRPYRDENOISE_NOISELABEL;Voorbeeld ruis: Gemiddeld=%1 Hoog=%2 +TP_DIRPYRDENOISE_NRESID_TOOLTIP;Toont de overgebleven ruisniveau's van het zichtbare deel van de afbeelding in het voorbeeld na wavelet.\n\n>300 Veel ruis\n100-300 Gemiddeld ruis\n50-100 Weinig ruis\n<50 Zeer weinig ruis\n\nVoorzichtig, de waarden zullen verschillen tussen RGB en L*a*b* mode. De RGB waarden zijn minder accuraat omdat de RGB mode luminantie en chrominantie niet volledig scheidt. +TP_DIRPYRDENOISE_PASSES_TOOLTIP;Een 3x3 filter met drie iteraties geeft meestal een beter resultaat dan eenmaal het 7x7 filter. +TP_DIRPYRDENOISE_PASSE;Iteraties +TP_DIRPYRDENOISE_PON;Auto multi-zone +TP_DIRPYRDENOISE_PREVLABEL;Voorbeeld grootte=%1, Centrum: Px=%2 Py=%3 +TP_DIRPYRDENOISE_PREV;Voorbeeld +TP_DIRPYRDENOISE_PRE;Voorbeeld multi-zone +TP_DIRPYRDENOISE_RED;Chrominantie Rood & Groen +TP_DIRPYRDENOISE_RGBM;RGB +TP_DIRPYRDENOISE_RGB;RGB +TP_DIRPYRDENOISE_SHALBI;Hoog +TP_DIRPYRDENOISE_SHAL;Standaard +TP_DIRPYRDENOISE_SLI;Schuifbalk +TP_DIRPYRDENOISE_SOFT;3x3 +TP_DIRPYRDENOISE_TILELABEL;Tegel grootte=%1, Centrum: Tx=%2 Ty=%3 +TP_DIRPYREQUALIZER_ALGO;Algoritme Huid +TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fijn: behoud de kleuren van de huid, minimaliseert de actie op andere kleuren\nGroot: vermijd artefacten +TP_DIRPYREQUALIZER_HUESKIN;Huidtint +TP_DIRPYREQUALIZER_LABEL;Detailcontrast (Lab/CIECAM02) +TP_DIRPYREQUALIZER_LUMACOARSEST;grofste +TP_DIRPYREQUALIZER_LUMACONTRAST_MINUS;Contrast- +TP_DIRPYREQUALIZER_LUMACONTRAST_PLUS;Contrast+ +TP_DIRPYREQUALIZER_LUMAFINEST;fijnste +TP_DIRPYREQUALIZER_LUMANEUTRAL;Neutraal +TP_DIRPYREQUALIZER_SKIN;Huidtinten Wijzigen/Beschermen +TP_DIRPYREQUALIZER_SKIN_TOOLTIP;Bij -100 huidtinten worden gewijzigd.\nBij 0 alle tinten worden gelijk behandeld.\nBij +100 huidtinten worden beschermd en alle andere tinten worden gewijzigd +TP_DIRPYREQUALIZER_THRESHOLD;Drempel +TP_DIRPYREQUALIZER_TOOLTIP;Probeert artefacten te verminderen die het gevolg zijn van kleurverschuiving van de huidtinten(hue, chroma, luma) en de rest van de afbeelding +TP_DISTORTION_AMOUNT;Hoeveelheid +TP_DISTORTION_AUTO; Automatische correctie lensvervorming +TP_DISTORTION_AUTO_TIP;(Experimenteel) Automatische correctie lensvervorming voor sommige camera's (M4/3, enkele compacts, etc.) +TP_DISTORTION_LABEL;Corrigeer lensvervorming +TP_EPD_EDGESTOPPING;Randen +TP_EPD_LABEL;Tonemapping (Lab/CIECAM02) +TP_EPD_REWEIGHTINGITERATES;Herhaling +TP_EPD_SCALE;Schaal +TP_EPD_STRENGTH;Sterkte +TP_EPD_TOOLTIP;Tonemapping is mogelijk via Lab mode (standaard) of CIECAM02 mode.\n\nOm CIECAM02 Tonemapping mode te gebruiken moeten de volgende instellingen worden gekozen: \n1. CIECAM\n2. Algoritme="Helderheid + Kleurrijkheid (QM)"\n3. "Tonemapping gebruik makend van CIECAM02 helderheid (Q)" +TP_EXPOSURE_AUTOLEVELS;Autom. niveaus +TP_EXPOSURE_AUTOLEVELS_TIP;Activeer automatische niveaus\nActiveer Herstel Hoge lichten indien nodig. +TP_EXPOSURE_BLACKLEVEL;Schaduwen +TP_EXPOSURE_BRIGHTNESS;Helderheid +TP_EXPOSURE_CLIP;Clip % +TP_EXPOSURE_CLIP_TIP;Het deel van de pixels dat moet worden hersteld bij gebruik van automatische niveaus. +TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Drempel Hoge lichten Comprimeren +TP_EXPOSURE_COMPRHIGHLIGHTS;Hoge lichten Comprimeren +TP_EXPOSURE_COMPRSHADOWS;Schaduwcompressie +TP_EXPOSURE_CONTRAST;Contrast +TP_EXPOSURE_CURVEEDITOR1;Toon curve 1 +TP_EXPOSURE_CURVEEDITOR2;Toon curve 2 +TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Raadpleeg de volgende paragraaf van de handleiding om te leren hoe U het beste resultaat kunt boeken bij het werken met dubbele curven:\n The Toolbox > Exposure Tab > Exposure Panel > Tone Curve +TP_EXPOSURE_CURVEEDITOR;Tooncurve +TP_EXPOSURE_EXPCOMP;Belichtingscompensatie +TP_EXPOSURE_LABEL;Belichting +TP_EXPOSURE_SATURATION;Verzadiging +TP_EXPOSURE_TCMODE_FILMLIKE;Film-achtig +TP_EXPOSURE_TCMODE_LABEL1;Curve modus 1 +TP_EXPOSURE_TCMODE_LABEL2;Curve modus 2 +TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Verzadiging en Waarde mengen +TP_EXPOSURE_TCMODE_STANDARD;Standaard +TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Gewogen Standaard +TP_EXPOS_BLACKPOINT_LABEL;Raw Zwartpunten +TP_EXPOS_WHITEPOINT_LABEL;Raw Witpunten +TP_FILMSIMULATION_LABEL;Film Simuleren +TP_FILMSIMULATION_STRENGTH;Sterkte +TP_FILMSIMULATION_ZEROCLUTSFOUND;Specificeer HaldCLUT map in Voorkeuren +TP_FLATFIELD_AUTOSELECT;Automatische selectie +TP_FLATFIELD_BLURRADIUS;Verzachten: straal +TP_FLATFIELD_BLURTYPE;Verzachten: type +TP_FLATFIELD_BT_AREA;Gebied +TP_FLATFIELD_BT_HORIZONTAL;Horizontaal +TP_FLATFIELD_BT_VERTHORIZ;Vert. + Horiz. +TP_FLATFIELD_BT_VERTICAL;Verticaal +TP_FLATFIELD_CLIPCONTROL;Clip controle +TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip controle vermijd geclipte hoge lichten veroorzaakt door het toepassen van vlakveld. Als er al geclipte hoge lichten waren voor het toepassen van vlakveld dan kan clip controle kleurzweem veroorzaken. +TP_FLATFIELD_LABEL;Vlakveld +TP_GAMMA_CURV;Gamma +TP_GAMMA_FREE;Vrij gamma +TP_GAMMA_OUTPUT;Uitvoer gamma +TP_GAMMA_SLOP;Helling (lineair) +TP_GENERAL_11SCALE_TOOLTIP;De werking is alleen zichtbaar op schaal 1:1 van het voorbeeld +TP_GRADIENT_CENTER;Centrum +TP_GRADIENT_CENTER_X;Centrum X +TP_GRADIENT_CENTER_X_TOOLTIP;Rotatiepunt X-as: \n-100=linkerkant \n0=centrum \n+100=rechterkant +TP_GRADIENT_CENTER_Y;Centrum Y +TP_GRADIENT_CENTER_Y_TOOLTIP;Rotatiepunt Y-as: \n-100=bovenkant \n0=centrum \n+100=onderkant +TP_GRADIENT_DEGREE;Hoek +TP_GRADIENT_DEGREE_TOOLTIP;Rotatie hoek in graden +TP_GRADIENT_FEATHER;Verloop +TP_GRADIENT_FEATHER_TOOLTIP;Verloop als percentage van de afbeeldingsdiagonaal +TP_GRADIENT_LABEL;Grijsverloop Filter +TP_GRADIENT_STRENGTH;Sterkte +TP_GRADIENT_STRENGTH_TOOLTIP;Filtersterkte in stops +TP_HLREC_BLEND;Mengen +TP_HLREC_CIELAB;CIELab-blending +TP_HLREC_COLOR;Kleurherstel +TP_HLREC_ENA_TOOLTIP;Kan worden geactiveerd door automatische niveaus +TP_HLREC_LABEL;Hoge lichten Herstellen +TP_HLREC_LUMINANCE;Lichtherstel +TP_HLREC_METHOD;Methode: +TP_HSVEQUALIZER_CHANNEL;HSV-balans +TP_HSVEQUALIZER_HUE;Tint +TP_HSVEQUALIZER_LABEL;HSV-balans +TP_HSVEQUALIZER_SAT;Verzadiging +TP_HSVEQUALIZER_VAL;Waarde +TP_ICM_BLENDCMSMATRIX;Meng hoge lichten met matrix +TP_ICM_BLENDCMSMATRIX_TOOLTIP;Activeer om uitgebeten hoge lichten te herstellen wanneer op LUT gebaseerde ICC-profielen worden gebruikt. +TP_ICM_DCPILLUMINANT;Illuminant +TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpoleren +TP_ICM_DCPILLUMINANT_TOOLTIP;Kies welk ingebed DCP illuminant moet worden gebruikt. Standaard is dit "interpoleren". Dit is een mix van de twee gebaseerd op de witbalans. De instelling is alleen actief als een Dual-Illuminant DCP met interpolatie is geselecteerd. +TP_ICM_INPUTCAMERAICC;Camera-specifiek kleurprofiel +TP_ICM_INPUTCAMERAICC_TOOLTIP;Gebruik RawTherapee's camera-specifieke DCP- of ICC-kleurprofiel dat preciezer is dan een eenvoudige matrix. Beschikbaar voor sommige camera's. Deze profielen zijn opgeslagen in de map /iccprofiles/input en worden automatisch opgehaald gebaseerd op de exacte overeenkomst van bestandsnaam met de modelnaam van de camera. +TP_ICM_INPUTCAMERA;Camera standaard +TP_ICM_INPUTCAMERA_TOOLTIP;Gebruik de eenvoudige kleurenmatrix van dcraw, of de uitgebreidere RawTherapee-versie (indien aanwezig voor het cameramodel) of gebruik het ingebedde profiel in de DNG. +TP_ICM_INPUTCUSTOM;Handmatig +TP_ICM_INPUTCUSTOM_TOOLTIP;Selecteer eigen DCP/ICC-kleurenprofiel voor uw camera. +TP_ICM_INPUTDLGLABEL;Selecteer invoer-ICC-profiel... +TP_ICM_INPUTEMBEDDED;Gebruik ingebed profiel, indien mogelijk +TP_ICM_INPUTEMBEDDED_TOOLTIP;Gebruik ingebed profiel, indien mogelijk. +TP_ICM_INPUTNONE;Geen profiel +TP_ICM_INPUTNONE_TOOLTIP;Gebruik geen invoerprofiel. Alleen toepassen in speciale gevallen. +TP_ICM_INPUTPROFILE;Invoerprofiel +TP_ICM_LABEL;Kleurbeheer +TP_ICM_NOICM;Geen ICM: sRGB-uitvoer +TP_ICM_OUTPUTPROFILE;Uitvoerprofiel +TP_ICM_SAVEREFERENCE;Bewaar referentiefoto tbv. profiling +TP_ICM_SAVEREFERENCE_TOOLTIP;Sla de lineare TIFF afbeelding op voordat het invoer profiel is toegepast. Het resultaat kan worden gebruikt voor calibratie en het genereren van een camera profiel. +TP_ICM_TONECURVE;Gebruik DCP's toon curve +TP_ICM_TONECURVE_TOOLTIP;Gebruik de ingebedde DCP toon curve. De instelling is alleen actief als de geselecteerd DCP een toon curve heeft. +TP_ICM_WORKINGPROFILE;Werkprofiel +TP_IMPULSEDENOISE_LABEL;Spot-ruisonderdrukking +TP_IMPULSEDENOISE_THRESH;Drempel +TP_LABCURVE_AVOIDCOLORSHIFT;Vermijd kleurverschuiving +TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Plaats de kleuren in het gamut van de kleurruimte van het werkprofiel\nen pas Munsell correctie toe +TP_LABCURVE_BRIGHTNESS;Helderheid +TP_LABCURVE_CHROMATICITY;Chromaticiteit +TP_LABCURVE_CHROMA_TOOLTIP;Voor Z-W tonen, zet Chromaticiteit op -100 +TP_LABCURVE_CONTRAST;Contrast +TP_LABCURVE_CURVEEDITOR;Luminantiecurve +TP_LABCURVE_CURVEEDITOR_A_RANGE1;Groen verzadigd +TP_LABCURVE_CURVEEDITOR_A_RANGE2;Groen pastel +TP_LABCURVE_CURVEEDITOR_A_RANGE3;Rood pastel +TP_LABCURVE_CURVEEDITOR_A_RANGE4;Rood verzadigd +TP_LABCURVE_CURVEEDITOR_B_RANGE1;Blauw verzadigd +TP_LABCURVE_CURVEEDITOR_B_RANGE2;Blauw pastel +TP_LABCURVE_CURVEEDITOR_B_RANGE3;Geel pastel +TP_LABCURVE_CURVEEDITOR_B_RANGE4;Geel verzadigd +TP_LABCURVE_CURVEEDITOR_CC;CC +TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutraal +TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Saai +TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastel +TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Verzadigd +TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Chromaticiteit volgens chromaticeit C=f(C) +TP_LABCURVE_CURVEEDITOR_CH;CH +TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticiteit volgens Tint C=f(H) +TP_LABCURVE_CURVEEDITOR_CL;CL +TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Chromaticiteit volgens Luminantie C=f(L) +TP_LABCURVE_CURVEEDITOR_HH;HH +TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Hue volgens hue H=f(H) +TP_LABCURVE_CURVEEDITOR_LC;LC +TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminantie volgens chromaticiteit L=f(C) +TP_LABCURVE_CURVEEDITOR_LH;LH +TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Luminantie volgens hue L=f(H) +TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminantie volgens luminantie L=f(L) +TP_LABCURVE_LABEL;Lab +TP_LABCURVE_LCREDSK;Beperkt LC tot Rode en Huidtinten +TP_LABCURVE_LCREDSK_TIP;Indien ingeschakeld, beinvloed de LC Curve alleen rode en huidtinten\nIndien uitgeschakeld, is het van toepassing op all tinten +TP_LABCURVE_RSTPROTECTION;Rode en huidtinten Bescherming +TP_LABCURVE_RSTPRO_TOOLTIP;Kan worden gebruikt met de chromaticiteits schuifbalk en de CC curve. +TP_LENSGEOM_AUTOCROP;Automatisch bijsnijden +TP_LENSGEOM_FILL;Automatisch uitvullen +TP_LENSGEOM_LABEL;Objectief / Geometrie +TP_LENSPROFILE_LABEL;Lenscorrectie Profielen +TP_LENSPROFILE_USECA;CA correctie +TP_LENSPROFILE_USEDIST;Lensvervorming correctie +TP_LENSPROFILE_USEVIGN;Vignettering correctie +TP_NEUTRAL;Neutraal +TP_NEUTRAL_TIP;Alle belichtingsinstellingen naar 0 +TP_PCVIGNETTE_FEATHER;Straal +TP_PCVIGNETTE_FEATHER_TOOLTIP;Straal: \n0=alleen hoeken \n50=halverwege tot het centrum \n100=tot aan het centrum +TP_PCVIGNETTE_LABEL;Vignettering Filter +TP_PCVIGNETTE_ROUNDNESS;Vorm +TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Vorm: \n0=rechthoek \n50=ellips \n100=circel +TP_PCVIGNETTE_STRENGTH;Sterkte +TP_PCVIGNETTE_STRENGTH_TOOLTIP;Filtersterkte in stops (volledig in de hoeken). +TP_PERSPECTIVE_HORIZONTAL;Horizontaal +TP_PERSPECTIVE_LABEL;Perspectief +TP_PERSPECTIVE_VERTICAL;Verticaal +TP_PFCURVE_CURVEEDITOR_CH;Tint +TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Bepaalt de mate van verzachten per kleur. Hoger = meer, lager = minder. +TP_PREPROCESS_DEADPIXFILT;Dode pixels filter +TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Onderdrukt dode pixels. +TP_PREPROCESS_GREENEQUIL;Groenbalans +TP_PREPROCESS_HOTPIXFILT;Hete pixels filter +TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Onderdrukt hete pixels. +TP_PREPROCESS_LABEL;Voorbewerking +TP_PREPROCESS_LINEDENOISE;Lijnruisfilter +TP_PREPROCESS_NO_FOUND;Niet gevonden +TP_RAWCACORR_AUTO;Automatische CA-correctie +TP_RAWCACORR_CABLUE;Blauw +TP_RAWCACORR_CARED;Rood +TP_RAWEXPOS_BLACKS;Zwartniveaus +TP_RAWEXPOS_BLACK_0;Groen 1 (leidend) +TP_RAWEXPOS_BLACK_1;Rood +TP_RAWEXPOS_BLACK_2;Blauw +TP_RAWEXPOS_BLACK_3;Groen 2 +TP_RAWEXPOS_BLACK_BLUE;Blauw +TP_RAWEXPOS_BLACK_GREEN;Groen +TP_RAWEXPOS_BLACK_RED;Rood +TP_RAWEXPOS_LINEAR;Witpunt Correctie +TP_RAWEXPOS_PRESER;Herstel hoge lichten +TP_RAWEXPOS_RGB;Rood, Groen, Blauw +TP_RAWEXPOS_TWOGREEN;Koppel Groen 1 en 2 +TP_RAW_DCBENHANCE;DCB Verbetering +TP_RAW_DCBITERATIONS;Aantal DCB-herhalingen +TP_RAW_DMETHOD;Methode +TP_RAW_DMETHOD_PROGRESSBAR;%1 Demozaïeken... +TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Demozaïek verfijning... +TP_RAW_DMETHOD_TOOLTIP;IGV en LMMSE zijn speciaal bedoeld voor hoge ISO afbeeldingen +TP_RAW_FALSECOLOR;Stapgrootte kleurfoutonderdrukking +TP_RAW_LABEL;Demozaïekproces +TP_RAW_LMMSEITERATIONS;LMMSE Verbetering Stappen +TP_RAW_LMMSE_TOOLTIP;Toevoegen gamma (stap 1), mediaan (stappen 2-4), en verfijnen (stappen 5-6) om artefacten te verwijderen en de signaal/ruis ratio te verbeteren. +TP_RAW_SENSOR_BAYER_LABEL;Sensor met Bayer matrix +TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;3-pass geeft het beste resultaat (aanbevolen voor lage ISO afbeeldingen)\n1-pass geeft hetzelfde resultaat als 3-pass voor hoge ISO afbeeldingen en is sneller. +TP_RAW_SENSOR_XTRANS_LABEL;Sensor met X-Trans matrix +TP_RESIZE_APPLIESTO;Toepassen op: +TP_RESIZE_CROPPEDAREA;Uitsnede +TP_RESIZE_FITBOX;Breedte en hoogte +TP_RESIZE_FULLIMAGE;Hele foto +TP_RESIZE_HEIGHT;Hoogte +TP_RESIZE_H;H: +TP_RESIZE_LABEL;Grootte aanpassen +TP_RESIZE_LANCZOS;Lanczos +TP_RESIZE_METHOD;Methode: +TP_RESIZE_NEAREST;Dichtstbij +TP_RESIZE_SCALE;Schaal +TP_RESIZE_SPECIFY;Specificeer: +TP_RESIZE_WIDTH;Breedte +TP_RESIZE_W;B: +TP_RGBCURVES_BLUE;B +TP_RGBCURVES_CHANNEL;Kanaal +TP_RGBCURVES_GREEN;G +TP_RGBCURVES_LABEL;RGB-curven +TP_RGBCURVES_LUMAMODE;Luminositeit Mode +TP_RGBCURVES_LUMAMODE_TOOLTIP;Luminositeit ModeVarieert de toewijzing van de R, G en B kanalen aan de Luminositeit van de afbeelding, zonder dat de kleur van de afbeelding wijzigt. +TP_RGBCURVES_RED;R +TP_ROTATE_DEGREE;Graden +TP_ROTATE_LABEL;Roteren +TP_ROTATE_SELECTLINE;Bepaal rechte lijn +TP_SAVEDIALOG_OK_TIP;Sneltoets: Ctrl-Enter +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Hoge lichten +TP_SHADOWSHLIGHTS_HLTONALW;Toonomvang +TP_SHADOWSHLIGHTS_LABEL;Schaduwen/hoge lichten +TP_SHADOWSHLIGHTS_LOCALCONTR;Lokaal contrast +TP_SHADOWSHLIGHTS_RADIUS;Straal +TP_SHADOWSHLIGHTS_SHADOWS;Schaduwen +TP_SHADOWSHLIGHTS_SHARPMASK;Verscherpingsmasker +TP_SHADOWSHLIGHTS_SHTONALW;Toonomvang +TP_SHARPENEDGE_AMOUNT;Hoeveelheid +TP_SHARPENEDGE_LABEL;Randen +TP_SHARPENEDGE_PASSES;Herhaling +TP_SHARPENEDGE_THREE;Alleen luminantie +TP_SHARPENING_AMOUNT;Hoeveelheid +TP_SHARPENING_EDRADIUS;Straal +TP_SHARPENING_EDTOLERANCE;Randtolerantie +TP_SHARPENING_HALOCONTROL;Halocontrole +TP_SHARPENING_HCAMOUNT;Hoeveelheid +TP_SHARPENING_LABEL;Verscherpen (Lab/CIECAM02) +TP_SHARPENING_METHOD;Methode +TP_SHARPENING_ONLYEDGES;Alleen randen verscherpen +TP_SHARPENING_RADIUS;Straal +TP_SHARPENING_RLD;RL-verscherping +TP_SHARPENING_RLD_AMOUNT;Hoeveelheid +TP_SHARPENING_RLD_DAMPING;Demping +TP_SHARPENING_RLD_ITERATIONS;Herhaling +TP_SHARPENING_THRESHOLD;Drempel +TP_SHARPENING_TOOLTIP;Hou rekening met een enigszins ander effect in combinatie met CIECAM02. Aanpassen naar eigen smaak. +TP_SHARPENING_USM;Onscherpmasker +TP_SHARPENMICRO_AMOUNT;Hoeveelheid +TP_SHARPENMICRO_LABEL;Microcontrast (Lab/CIECAM02) +TP_SHARPENMICRO_MATRIX;3×3-matrix ipv. 5×5 +TP_SHARPENMICRO_UNIFORMITY;Uniformiteit +TP_VIBRANCE_AVOIDCOLORSHIFT;Vermijd kleurverschuiving +TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH +TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Huidtinten +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Rood/Paars +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Rood +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Rood/Geel +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Geel +TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Tint volgens Tint +TP_VIBRANCE_LABEL;Levendigheid +TP_VIBRANCE_PASTELS;Pasteltinten +TP_VIBRANCE_PASTSATTOG;Koppel pastel- en verzadigde tinten +TP_VIBRANCE_PROTECTSKINS;Bescherm huidtinten +TP_VIBRANCE_PSTHRESHOLD;Drempel pastel/verzadiging +TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Drempel Verzadiging +TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;De verticale as vertegenwoordigt aan de onderkant de pastel tinten en aan de bovenkanten de verzadigde tinten.\nDe horizontale as vertegenwoordigt de verzadigde reeks. +TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Pastel/verzadigings transitie weging +TP_VIBRANCE_SATURATED;Verzadigde tinten +TP_VIGNETTING_AMOUNT;Hoeveelheid +TP_VIGNETTING_CENTER;Centrum +TP_VIGNETTING_CENTER_X;Centrum X +TP_VIGNETTING_CENTER_Y;Centrum Y +TP_VIGNETTING_LABEL;Vignettering Correctie +TP_VIGNETTING_RADIUS;Straal +TP_VIGNETTING_STRENGTH;Sterkte +TP_WAVELET_1;Niveau 1 +TP_WAVELET_2;Niveau 2 +TP_WAVELET_3;Niveau 3 +TP_WAVELET_4;Niveau 4 +TP_WAVELET_5;Niveau 5 +TP_WAVELET_6;Niveau 6 +TP_WAVELET_7;Niveau 7 +TP_WAVELET_8;Niveau 8 +TP_WAVELET_ALL;Alle niveau-richtingen +TP_WAVELET_APPLYTO;Toepassen +TP_WAVELET_AVOID;Vermijd kleurverschuiving +TP_WAVELET_CH1;Alle chroma's +TP_WAVELET_CH2;Pastel - Verzadigd +TP_WAVELET_CH3;Koppel contrast niveau's +TP_WAVELET_CHRO;Verzadigd - Pastel +TP_WAVELET_CHRO_TOOLTIP;Begrens tussen pastel en verzadigd\n 1-x niveau verzadigd\n x-9 niveau pastel +TP_WAVELET_CHR;Koppel Chroma aan contrast +TP_WAVELET_CHR_TOOLTIP;Wijzig chroma in combinatie met Contrast niveau's +TP_WAVELET_COLORT;Dekking Rood-Groen Niveau +TP_WAVELET_CONTRAST_MINUS;Contrast - +TP_WAVELET_CONTRAST_PLUS;Contrast + +TP_WAVELET_CONTRA;Contrast +TP_WAVELET_CONTRA_TOOLTIP;Wijzig contrast in de rest van de afbeelding +TP_WAVELET_CONTR;Gamut - controle +TP_WAVELET_DALL;Alle richtingen +TP_WAVELET_DISP;Wavelet niveau's +TP_WAVELET_DONE;Richting: Vertikaal +TP_WAVELET_DTHR;Richting: Diagonaal +TP_WAVELET_DTWO;Richting: Horizontaal +TP_WAVELET_EDGE;Randen verscherpen (Luminantie) +TP_WAVELET_EDGTHRESH;Drempel +TP_WAVELET_EDRAD;Straal +TP_WAVELET_EDVAL;Waarde +TP_WAVELET_FINEST;fijn +TP_WAVELET_HIGHLIGHT;Hoge lichten: Luminantie Reeks (0..100) +TP_WAVELET_HS1;Alle luminanties +TP_WAVELET_HS2;Hoge lichten/Schaduwen +TP_WAVELET_HUESKIN;Tint reeks (huid) +TP_WAVELET_HUESKY;Tint Reeks (lucht) +TP_WAVELET_INF;Onder of gelijk aan het niveau +TP_WAVELET_LABEL;Wavelet niveau's +TP_WAVELET_LARGEST;grof +TP_WAVELET_LEVCH;Chromaticiteit +TP_WAVELET_LEVELS;Wavelet niveau's +TP_WAVELET_LEVELS_TOOLTIP;Kies het aantal detail niveau's. Meer niveau's vereisen meer RAM en de verwerking duurt langer. +TP_WAVELET_LEVF;Contrast +TP_WAVELET_LEVLABEL;Voorbeeld maximum mogelijke niveau's=%1 +TP_WAVELET_LOWLIGHT;Schaduwen: Luminantie Reeks (0..100) +TP_WAVELET_MEDI;Verminder artefacten in blauwe lucht +TP_WAVELET_NEUTRAL;Neutraal +TP_WAVELET_ONE;Eén niveau +TP_WAVELET_OPACITY;Dekking Blauw-Geel Niveau +TP_WAVELET_PASTEL;Pastel chromaciteit +TP_WAVELET_PREVIEWLEVELS;Voorbeeld +TP_WAVELET_RESCHRO;Chromaticiteit +TP_WAVELET_RESCONH;Hoge lichten +TP_WAVELET_RESCON;Schaduwen +TP_WAVELET_RESID;Rest van de afbeelding +TP_WAVELET_SAT;Verzadigd chromaciteit +TP_WAVELET_SETTINGS;Wavelet Instellingen +TP_WAVELET_SKIN;Huidtinten Wijzigen/Beschermen +TP_WAVELET_SKIN_TOOLTIP;Bij -100 worden alleen huidtinten gewijzigd.\nBij 0 worden alle tinten gelijk behandeld.\nBij +100 worden huidtinten beschermd. Alle andere tinten worden gewijzigd. +TP_WAVELET_SKY;Tint-tonen (lucht) Wijzigen/Beschermen +TP_WAVELET_SKY_TOOLTIP;Vergroot/verminder chrominantie in de tint reeks\nVermijd artefacten in blauwe lucht als gevolg van micro-contrast, micro-chroma,... +TP_WAVELET_STRENGTH;Sterkte +TP_WAVELET_SUPE;Extra +TP_WAVELET_SUP;Boven het niveau + overblijvend +TP_WAVELET_THRESHOLD2;Schaduwen: Aantal te gebruiken niveau's (grof naar fijn) +TP_WAVELET_THRESHOLD2_TOOLTIP;Alleen niveau's tussen '9' en '9 minus gekozen waarde' worden behandeld als schaduwen\nDe andere niveau's worden volledig behandeld\nHet maximum niveau voor schaduwen wordt beperkt door het aantal Hoge lichten niveau's (9- hoge lichten niveau) +TP_WAVELET_THRESHOLD;Hoge lichten: Aantal te gebruiken niveau's (fijn naar grof - leidend) +TP_WAVELET_THRESHOLD_TOOLTIP;Alleen niveau's boven de gekozen waarde worden behandeld als hoge lichten\nDe andere niveau's worden volledig behandeld +TP_WAVELET_THRES;Max niveau +TP_WAVELET_THRH;Drempel Hoge lichten +TP_WAVELET_THR;Drempel Schaduwen +TP_WAVELET_TILESBIG;Grote Tegels +TP_WAVELET_TILESFULL;Volldige afbeelding +TP_WAVELET_TILESIZE;Tegel grootte +TP_WAVELET_TILESLIT;Kleine Tegels +TP_WAVELET_TILES;Tegel grootte (* 128) +TP_WAVELET_TILES_TOOLTIP;De optie 'Volledige afbeelding' geeft een betere kwaliteit en is de aanbevolen keuze. Selecteer Tegels als er onvoldoende geheugen beschikbaar is. Raadpleeg RawPedia voor geheugen aanbevelingen. +TP_WAVELET_TON;Kleurtinten +TP_WBALANCE_AUTO;Automatisch +TP_WBALANCE_CAMERA;Camera +TP_WBALANCE_CLOUDY;Bewolkt +TP_WBALANCE_CUSTOM;Handmatig +TP_WBALANCE_DAYLIGHT;Daglicht (zonnig) +TP_WBALANCE_EQBLUERED;Blauw/Rood Balans +TP_WBALANCE_EQBLUERED_TOOLTIP;Wijzigt het normale gedrag van "witbalans" door de blauw/rood balans te verschuiven.\nToepassen wanneer de opname-omstandigheden sterk afwijken van: \na) standaard belichting (bv. onderwater)\nb) de condities waar de calibraties zijn uitgevoerd\nc) de matrices of ICC profielen. +TP_WBALANCE_FLASH55;Leica +TP_WBALANCE_FLASH60;Standaard, Canon, Pentax, Olympus +TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta +TP_WBALANCE_FLASH_HEADER;Flits +TP_WBALANCE_FLUO1;F1 - Daglicht +TP_WBALANCE_FLUO2;F2 - Koel wit +TP_WBALANCE_FLUO3;F3 - Wit +TP_WBALANCE_FLUO4;F4 - Warm wit +TP_WBALANCE_FLUO5;F5 - Daglicht +TP_WBALANCE_FLUO6;F6 - Licht wit +TP_WBALANCE_FLUO7;F7 - D65 Daglicht simuleren +TP_WBALANCE_FLUO8;F8 - D50 / Sylvania F40 Design +TP_WBALANCE_FLUO9;F9 - Koel wit deluxe +TP_WBALANCE_FLUO10;F10 - Philips TL85 +TP_WBALANCE_FLUO11;F11 - Philips TL84 +TP_WBALANCE_FLUO12;F12 - Philips TL83 +TP_WBALANCE_FLUO_HEADER;Fluorescent(TL) +TP_WBALANCE_GREEN;Groentint +TP_WBALANCE_GTI;GTI +TP_WBALANCE_HMI;HMI +TP_WBALANCE_JUDGEIII;JudgeIII +TP_WBALANCE_LABEL;Witbalans +TP_WBALANCE_LAMP_HEADER;Lamp +TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 +TP_WBALANCE_LED_HEADER;LED +TP_WBALANCE_LED_LSI;LSI Lumelex 2040 +TP_WBALANCE_METHOD;Methode +TP_WBALANCE_SHADE;Schaduw +TP_WBALANCE_SIZE;Grootte: +TP_WBALANCE_SOLUX35;Solux 3500K +TP_WBALANCE_SOLUX41;Solux 4100K +TP_WBALANCE_SOLUX47;Solux 4700K (leverancier) +TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) +TP_WBALANCE_SPOTWB;Wijs WB aan +TP_WBALANCE_TEMPERATURE;Kleurtemperatuur +TP_WBALANCE_TUNGSTEN;Tungsten (wolfraam) +TP_WBALANCE_WATER1;Onderwater 1 +TP_WBALANCE_WATER2;Onderwater 2 +TP_WBALANCE_WATER_HEADER;Onderwater +ZOOMPANEL_100;(100%) +ZOOMPANEL_NEWCROPWINDOW;Open (nieuw) detailvenster +ZOOMPANEL_ZOOM100;Zoom naar 100%\nSneltoets: z +ZOOMPANEL_ZOOMFITSCREEN;Passend in venster\nSneltoets: f +ZOOMPANEL_ZOOMIN;Zoom in\nSneltoets: + +ZOOMPANEL_ZOOMOUT;Zoom uit\nSneltoets: - ++TP_WAVELET_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_WAVELET_HUESKY_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. + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!CURVEEDITOR_AXIS_IN;I: +!CURVEEDITOR_AXIS_LEFT_TAN;LT: +!CURVEEDITOR_AXIS_OUT;O: +!CURVEEDITOR_AXIS_RIGHT_TAN;RT: +!CURVEEDITOR_EDITPOINT_HINT;Enable edition of node in/out values.\n\nRight-click on a node to select it.\nRight-click on empty space to de-select the node. +!FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!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_ASIMAGE;As Image +!HISTORY_MSG_341;W - Edge performance +!HISTORY_MSG_342;W - ES - First level +!HISTORY_MSG_343;W - Chroma levels +!HISTORY_MSG_344;W - Meth chroma sl/cur +!HISTORY_MSG_345;W - ES - Local contrast +!HISTORY_MSG_346;W - ES - Local contrast method +!HISTORY_MSG_347;W - Denoise - Level 0 +!HISTORY_MSG_348;W - Denoise - Level 1 +!HISTORY_MSG_349;W - Denoise - Level 2 +!HISTORY_MSG_350;W - ES - Edge detection +!HISTORY_MSG_351;W - Residual - HH curve +!HISTORY_MSG_352;W - Background +!HISTORY_MSG_353;W - ES - Gradient sensitivity +!HISTORY_MSG_354;W - ES - Enhance +!HISTORY_MSG_355;W - ES - Threshold low +!HISTORY_MSG_356;W - ES - Threshold high +!HISTORY_MSG_357;W - Denoise - Link with ES +!HISTORY_MSG_358;W - Gamut - CH +!HISTORY_MSG_359;Hot/Dead - Threshold +!HISTORY_MSG_360;TM Gamma +!HISTORY_MSG_361;W - Final - Chroma balance +!HISTORY_MSG_362;W - Residual - Compression method +!HISTORY_MSG_363;W - Residual - Compression strength +!HISTORY_MSG_364;W - Final - Contrast balance +!HISTORY_MSG_365;W - Final - Delta balance +!HISTORY_MSG_366;W - Residual - Compression gamma +!HISTORY_MSG_367;W - ES - Local contrast curve +!HISTORY_MSG_368;W - Final - Contrast balance +!HISTORY_MSG_369;W - Final - Balance method +!HISTORY_MSG_370;W - Final - Local contrast curve +!MAIN_TAB_WAVELET;Wavelet +!MAIN_TAB_WAVELET_TOOLTIP;Shortcut: Alt-w +!PARTIALPASTE_WAVELETGROUP;Wavelet processing +!PREFERENCES_AUTLISSTD;High +!PREFERENCES_CURVEBBOXPOS;Position of curve copypasta buttons +!PREFERENCES_CURVEBBOXPOS_ABOVE;Above +!PREFERENCES_CURVEBBOXPOS_BELOW;Below +!PREFERENCES_CURVEBBOXPOS_LEFT;Left +!PREFERENCES_CURVEBBOXPOS_RIGHT;Right +!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_MAXRECENTFOLDERS;Maximum number of recent folders +!PREFERENCES_NAVIGATIONFRAME;Navigation +!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_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. +!TP_CROP_GTHARMMEANS;Harmonic Means +!TP_CROP_GTTRIANGLE1;Golden Triangles 1 +!TP_CROP_GTTRIANGLE2;Golden Triangles 2 +!TP_DIRPYREQUALIZER_ARTIF;Reduce artifacts +!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_EPD_GAMMA;Gamma +!TP_EXPOSURE_TCMODE_LUMINANCE;Luminance +!TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance +!TP_RAW_HD;Threshold +!TP_RAW_HD_TOOLTIP;Lower values make hot/dead pixel detection more aggressive, but false positives may lead to artifacts. If you notice any artifacts appearing when enabling the Hot/Dead Pixel Filters, gradually increase the threshold value until they disappear. +!TP_WAVELET_9;Level 9 +!TP_WAVELET_B0;Black +!TP_WAVELET_B1;Grey +!TP_WAVELET_B2;Residual +!TP_WAVELET_BACUR;Curve +!TP_WAVELET_BALANCE;Contrast balance d/v-h +!TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chromaticity or residual tone mapping are activated, the effect due to balance is amplified. +!TP_WAVELET_BALCHRO;Chroma balance +!TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chromaticity balance. +!TP_WAVELET_BANONE;None +!TP_WAVELET_BASLI;Slider +!TP_WAVELET_BATYPE;Contrast balance method +!TP_WAVELET_CCURVE;Local contrast +!TP_WAVELET_CHCU;Curve +!TP_WAVELET_CHSL;Sliders +!TP_WAVELET_CHTYPE;Chrominance method +!TP_WAVELET_COMBOTH;Both +!TP_WAVELET_COMPCONT;Contrast +!TP_WAVELET_COMPGAMMA;Compression gamma +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjusting the gamma of the residual image allow you to equilibrate the data and histogram. +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjust gamma for residual image and compression.\nAllow to equilibrate data and histogram +!TP_WAVELET_COMPTM;Tone mapping +!TP_WAVELET_CONTEDIT;'After' Contrast curve +!TP_WAVELET_CONTEDIT;'After' contrast curve +!TP_WAVELET_CTYPE;Chrominance control +!TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modifies local contrast as a function of the original local contrast (absciss)\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 100..300)\n66% absciss represents standard deviation of local contrast (real value about 300..800)\n100% represents maximum (real value about 3000..8000) +!TP_WAVELET_CURVEEDITOR_CH;Contrast levels=f(Hue) +!TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modifies each level's contrast as a function oh hue.\nTake care not to overwrite changes made with the Gamut Hue controls.\nThe curve will only have an effect when wavelet contrast level sliders are non-zero. +!TP_WAVELET_CURVEEDITOR_CL;L +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Applies a final contrast luminance curve at the end of the wavelet treatment. +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Apply a contrast luminance curve at the end of wavelet level threatment +!TP_WAVELET_CURVEEDITOR_HH;HH +!TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modifies the residual image's hue as a function of hue. +!TP_WAVELET_DAUB;Edge performance +!TP_WAVELET_DAUB_TOOLTIP;Changes Daubechies coefficients:\nD4 = Standard,\nD14 = Often best performance, 10% more time-intensive.\n\nAffects edge detection as well as the general quality of the firsts levels. However the quality is not strictly related to this coefficient and can vary with images and uses. +!TP_WAVELET_EDCU;Curve +!TP_WAVELET_EDGCONT;Local contrast +!TP_WAVELET_EDGCONT_TOOLTIP;Adjusting the points to the left decreases contrast, and to the right increases it.\nBottom-left, Top-Left, Top-Right, Bottom-right represent respectively local contast for low values, mean, mean+stdev, maxima +!TP_WAVELET_EDGEDETECTTHR2;Threshold high (detection) +!TP_WAVELET_EDGEDETECTTHR;Threshold low (noise) +!TP_WAVELET_EDGEDETECTTHR_TOOLTIP;This adjuster lets you target edge detection for example to avoid applying edge sharpness to fine details, such as noise in the sky. +!TP_WAVELET_EDGEDETECT;Gradient sensitivity +!TP_WAVELET_EDGEDETECT_TOOLTIP;Moving the slider to the right increases edge sensitivity. This affects local contrast, edge settings and noise. +!TP_WAVELET_EDGREINF_TOOLTIP;Reinforce or reduce the action of the first level, do the opposite to the second level, and leave the rest unchanged. +!TP_WAVELET_EDGTHRESH_TOOLTIP;Change the repartition between the first levels and the others. The higher the threshold the more the action is centred on the first levels. Be careful with negative values, they increase the action of high levels and can introduce artifacts. +!TP_WAVELET_EDRAD_TOOLTIP;This radius adjustment is very different from those in other sharpening tools. Its value is compared to each level through a complex function. In this sense, a value of zero still has an effect. +!TP_WAVELET_EDSL;Threshold Sliders +!TP_WAVELET_EDTYPE;Local contrast method +!TP_WAVELET_FINAL;Final Touchup +!TP_WAVELET_ITER;Delta balance levels +!TP_WAVELET_ITER_TOOLTIP;Left: increase low levels and reduce high levels,\nRight: reduce low levels and increase high levels. +!TP_WAVELET_LEVONE;Level 2 +!TP_WAVELET_LEVTWO;Level 3 +!TP_WAVELET_LEVZERO;Level 1 +!TP_WAVELET_LINKEDG;Link with Edge Sharpness' Strength +!TP_WAVELET_LIPST;Enhanced algorithm +!TP_WAVELET_LIPST_TOOLTIP;This algorithm uses Lipschitz regularity to increase edge detection quality at a cost of increased processing time and memory requirements. +!TP_WAVELET_MEDGREINF;First level +!TP_WAVELET_MEDILEV;Edge detection +!TP_WAVELET_NOISE;Denoise and Refine +!TP_WAVELET_NOIS;Denoise +!TP_WAVELET_OPACITYWL;Final local contrast +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify final local contrast in function of last local contrast (absciss) for all levels decomposition\nTake into account: \na)contrast levels \nb)edge sharpness \nc)contrast balance\nd)decomposition-recomposition\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 200..1000)\n66% absciss represents standard deviation of local contrast (real value about 1000..2000)\n100% represents maximum (real value about 5000..13000) +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify the final local contrast at the end of the wavelet treatment.\n\nThe left side represents the smallest local contrast, progressing to the largest local contrast on the right. +!TP_WAVELET_OPACITYW;Contrast balance d/v-h curve +!TP_WAVELET_PREVIEWBACK;Background +!TP_WAVELET_RE1;Reinforced +!TP_WAVELET_RE2;Unchanged +!TP_WAVELET_RE3;Reduced +!TP_WAVELET_TMHIGH;High +!TP_WAVELET_TMLOWHIGH;Low+High +!TP_WAVELET_TMNONE;None +!TP_WAVELET_TMSTD;Standard +!TP_WAVELET_TMSTRENGTH;Compression strength +!TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image. When the value is different from 0, the Strength and Gamma sliders of the Tone Mapping tool in the Exposure tab will become grayed out. +!TP_WAVELET_TMTYPE;Compression method +!TP_WAVELET_daub2;D2 - low +!TP_WAVELET_daub4;D4 - standard +!TP_WAVELET_daub6;D6 - standard plus +!TP_WAVELET_daub10;D10 - medium +!TP_WAVELET_daub14;D14 - high +!ZOOMPANEL_ZOOMFITCROPSCREEN;Fit crop to screen\nShortcut: Alt-f diff --git a/rtdata/languages/Norsk BM b/rtdata/languages/Norsk BM new file mode 100644 index 000000000..376f3c025 --- /dev/null +++ b/rtdata/languages/Norsk BM @@ -0,0 +1,1856 @@ +#01 2009-02-12 Esben L. Kristensen + +ADJUSTER_RESET_TO_DEFAULT;Tilbake til standard +CURVEEDITOR_LINEAR;Linjær +CURVEEDITOR_LOADDLGLABEL;Åpne kurve... +CURVEEDITOR_SAVEDLGLABEL;Lagre kurve... +CURVEEDITOR_TOOLTIPLINEAR;Nullstil kurve til linjær +CURVEEDITOR_TOOLTIPLOAD;Lagre kurve fra fil +CURVEEDITOR_TOOLTIPSAVE;Lagre nåværende kurve +DIRBROWSER_FOLDERS;Mapper +EXIFFILTER_APERTURE;Blender +EXIFFILTER_CAMERA;Kamera +EXIFFILTER_FOCALLEN;Fokallengde +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Objektiv +EXIFFILTER_SHUTTER;Lukker +EXIFPANEL_ADDEDITHINT;Tilføy ny tag eller rediger tag +EXIFPANEL_ADDEDIT;Tilføy/Rediger +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Skriv verdi +EXIFPANEL_ADDTAGDLG_SELECTTAG;Velg tag +EXIFPANEL_ADDTAGDLG_TITLE;Tilføy/Rediger Tag +EXIFPANEL_KEEPHINT;Behold de utvalgte tags når det skrives output fil +EXIFPANEL_KEEP;Behold +EXIFPANEL_REMOVEHINT;Fjern de utvalgte tags når det skrives output fil +EXIFPANEL_REMOVE;Fjern +EXIFPANEL_RESETALLHINT;Nullstil alle tags til de opprinnelige verdier +EXIFPANEL_RESETALL;Nullstil alle +EXIFPANEL_RESETHINT;Nullstil de utvalgte tags til de opprinnelige verdier +EXIFPANEL_RESET;Nullstil +EXIFPANEL_SUBDIRECTORY;Undermappe +FILEBROWSER_APPLYPROFILE;Legg til profil +FILEBROWSER_CLEARPROFILE;Slett profil +FILEBROWSER_COPYPROFILE;Kopier profil +FILEBROWSER_DELETEDLGLABEL;Bekreft slett fil +FILEBROWSER_DELETEDLGMSG;Vil du slette valgte %1 filer? +FILEBROWSER_EMPTYTRASHHINT;Tøm søpla permanent +FILEBROWSER_EMPTYTRASH;Tøm søpla +FILEBROWSER_PARTIALPASTEPROFILE;Delvis lim inn +FILEBROWSER_PASTEPROFILE;Lim inn profil +FILEBROWSER_POPUPCANCELJOB;Avbryt jobben +FILEBROWSER_POPUPMOVEEND;Flytt til enden av køen +FILEBROWSER_POPUPMOVEHEAD;Flytt til begynnelsen av køen +FILEBROWSER_POPUPOPENINEDITOR;Åpne i Editor +FILEBROWSER_POPUPOPEN;Åpne +FILEBROWSER_POPUPPROCESS;Legg til i prosesseringskøen +FILEBROWSER_POPUPREMOVE;Fjern fra filsystem +FILEBROWSER_POPUPRENAME;Skift navn +FILEBROWSER_POPUPSELECTALL;Velg alt +FILEBROWSER_POPUPTRASH;Flytt til søpla +FILEBROWSER_POPUPUNRANK;Fjern rangering +FILEBROWSER_POPUPUNTRASH;Fjern fra søpla +FILEBROWSER_RENAMEDLGLABEL;Bytt filnavn +FILEBROWSER_RENAMEDLGMSG;Bytt filnavn "%1" til: +FILEBROWSER_SHOWDIRHINT;Vis alle bildene i folderen +FILEBROWSER_SHOWRANK1HINT;Vis bilder rangert med 1 stjerne +FILEBROWSER_SHOWRANK2HINT;Vis bilder rangert med 2 stjerne +FILEBROWSER_SHOWRANK3HINT;Vis bilder rangert med 3 stjerne +FILEBROWSER_SHOWRANK4HINT;Vis bilder rangert med 4 stjerne +FILEBROWSER_SHOWRANK5HINT;Vis bilder rangert med 5 stjerne +FILEBROWSER_SHOWTRASHHINT;Vis innholdet i søpla +FILEBROWSER_SHOWUNRANKHINT;Vis unrangerte bilder +FILEBROWSER_STARTPROCESSINGHINT;Begynn prosessering/lagring av bilder i køen +FILEBROWSER_STARTPROCESSING;Start Processing +FILEBROWSER_STOPPROCESSINGHINT;Stopp prosesseringen av bilder +FILEBROWSER_STOPPROCESSING;Stopp prosesseringen +FILEBROWSER_THUMBSIZE;Thumbnail størrelse +FILEBROWSER_ZOOMINHINT;Øk thumbnail størrelse +FILEBROWSER_ZOOMOUTHINT;Reduser thumbnail størrelse +GENERAL_ABOUT;Om +GENERAL_CANCEL;Annuller +GENERAL_DISABLED;Deaktivert +GENERAL_DISABLE;Deaktiver +GENERAL_ENABLED;Aktivert +GENERAL_ENABLE;Aktiver +GENERAL_LANDSCAPE;Landskap +GENERAL_NA;n/a +GENERAL_NO;Nei +GENERAL_OK;Ok +GENERAL_PORTRAIT;Portrett +GENERAL_SAVE;Lagre +HISTOGRAM_TOOLTIP_B;Vis/skjul blått histogram +HISTOGRAM_TOOLTIP_G;Vis/skjul grønt histogram +HISTOGRAM_TOOLTIP_L;Vis/skjul CIELAB Luminans histogram +HISTOGRAM_TOOLTIP_R;Vis/skjul rødt histogram +HISTORY_CHANGED;Forandret +HISTORY_CUSTOMCURVE;Egen kurve +HISTORY_DELSNAPSHOT;Fjern b.m +HISTORY_FROMCLIPBOARD;Fra utklippstavlen +HISTORY_LABEL;Historikk +HISTORY_MSG_1;Foto åpnet +HISTORY_MSG_2;Profil åpnet +HISTORY_MSG_3;Profil endret +HISTORY_MSG_4;Historikk-gjennomsyn +HISTORY_MSG_5;Lysstyrke +HISTORY_MSG_6;Kontrast +HISTORY_MSG_7;Sort +HISTORY_MSG_8;Eksponerings-komprimering +HISTORY_MSG_9;Høylys-komprimering +HISTORY_MSG_10;Skyggekomprimering +HISTORY_MSG_11;Tonekurve +HISTORY_MSG_12;Autoeksponering +HISTORY_MSG_13;Eksponeringsmarkering +HISTORY_MSG_14;Luminanslysstyrke +HISTORY_MSG_15;Luminanskontrast +HISTORY_MSG_16;Sort luminans +HISTORY_MSG_17;Luminans høylys kompr. +HISTORY_MSG_18;Luminans skygge kompr. +HISTORY_MSG_19;Luminanskurve +HISTORY_MSG_20;Skarphet +HISTORY_MSG_21;Skarphetsradius +HISTORY_MSG_22;Skarphetsmengde +HISTORY_MSG_23;Skarphetsterskelverdi +HISTORY_MSG_24;Skarphet kun i kanter +HISTORY_MSG_25;Kanttegningsradie-skarphet +HISTORY_MSG_26;Kantskarphetstoleranse +HISTORY_MSG_27;Halo-skarphetsskontroll +HISTORY_MSG_28;Halo-kontrollstørrelse +HISTORY_MSG_29;Skarphetsmetode +HISTORY_MSG_30;Deconvolution-radius +HISTORY_MSG_31;Deconvolution-størrelse +HISTORY_MSG_32;Deconvolution-dempning +HISTORY_MSG_33;Deconvolution-gjentakelse +HISTORY_MSG_34;Unngå fargemarkeringer +HISTORY_MSG_35;Metthetsbegrensning +HISTORY_MSG_36;Methetsgrense +HISTORY_MSG_37;Fargeforsterkning +HISTORY_MSG_38;Hvitbalansemetode +HISTORY_MSG_39;Fargetemperatur +HISTORY_MSG_40;Hvitbalansenyanse +HISTORY_MSG_41;Fargeskift "A" +HISTORY_MSG_42;Fargeskift "B" +HISTORY_MSG_43;Luminans støyreduksjon +HISTORY_MSG_44;Lum. støyreduksjon-radius +HISTORY_MSG_45;Lum. støyreduksjon kanttoleranse +HISTORY_MSG_46;Fargestøyreduksjon +HISTORY_MSG_47;Fargestøyreduksjon-radius +HISTORY_MSG_48;Fargestøjreduktion-kanttoleranse +HISTORY_MSG_49;Kantfølsom fargestøyreduksjon +HISTORY_MSG_50;Skygge/høylys verktøy +HISTORY_MSG_51;Høylys-forsterkning +HISTORY_MSG_52;Skyggeforsterkning +HISTORY_MSG_53;Høylys-tonvidde +HISTORY_MSG_54;Skygge-tonevidde +HISTORY_MSG_55;Lokal kontrast +HISTORY_MSG_56;Skygge/høylys -radius +HISTORY_MSG_57;Enkel rotasjon +HISTORY_MSG_58;Vend horisontalt +HISTORY_MSG_59;Vend vertikalt +HISTORY_MSG_60;Rotasjon +HISTORY_MSG_61;Rotasjon +HISTORY_MSG_62;Objektivforvrengning-korrigering +HISTORY_MSG_63;Valgt bokmerke +HISTORY_MSG_64;Beskjær foto +HISTORY_MSG_65;C/A korrigering +HISTORY_MSG_66;Høylys-forbedring +HISTORY_MSG_67;Høylys-forbedringsstyrke +HISTORY_MSG_68;Høylys-forbedringsmetode +HISTORY_MSG_69;Arbeidsfargerom +HISTORY_MSG_70;Utgangssfargerom +HISTORY_MSG_71;Inngangsfargerom +HISTORY_MSG_72;Vignettering-korrigering +HISTORY_MSG_73;Kanalmikser +HISTORY_MSG_74;Endre størrelsesskala +HISTORY_MSG_75;Endre størrelses metode +HISTORY_MSG_76;Exif Metadata +HISTORY_MSG_77;IPTC Metadata +HISTORY_MSG_78;Data specified for resize +HISTORY_MSG_79;Resize width +HISTORY_MSG_80;Resize height +HISTORY_MSG_81;Resize enabled +HISTORY_NEWSNAPSHOT;Nytt b.m +HISTORY_SNAPSHOTS;Bokmerker +HISTORY_SNAPSHOT;Bokmerke +IPTCPANEL_AUTHORSPOSITIONHINT;Beskrivelse av oppretterens tittel (By-line Title). +IPTCPANEL_AUTHORSPOSITION;Oppretterens tittel +IPTCPANEL_AUTHOR;Oppretter +IPTCPANEL_CAPTIONHINT;Tekstbeskrivelse av bildets innhold (Caption - Abstract). +IPTCPANEL_CAPTIONWRITERHINT;Navnet på personen som har opprettet, redigert eller korrigeret bildeteksten (Writer - Editor). +IPTCPANEL_CAPTIONWRITER;Bildetekst forfatter +IPTCPANEL_CAPTION;Billdetekst +IPTCPANEL_CATEGORYHINT;Brukes til å beskrive innholdet i bildet ifølge kategorien (Category). +IPTCPANEL_CATEGORY;Kategori +IPTCPANEL_CITYHINT;Bildets opprinnelsesby (City). +IPTCPANEL_CITY;By +IPTCPANEL_COPYHINT;Kopier IPTC innstillinger til utklippstavlen +IPTCPANEL_COPYRIGHTHINT;Eventuelle copyright tilføyelser (Copyright Notice). +IPTCPANEL_COPYRIGHT;Copyright +IPTCPANEL_COUNTRYHINT;Navnet på landet/primære område hvor bildet er tatt (Country - Primary Location Name). +IPTCPANEL_COUNTRY;Land +IPTCPANEL_CREDITHINT;Identifisere oppretteren av bildet, ikke nødvendivis den samme som eieren (Credit). +IPTCPANEL_CREDIT;Kreditering +IPTCPANEL_DATECREATEDHINT;Datoen bildet ble tatt; Format: JJJJMMTT (Date Created). +IPTCPANEL_DATECREATED;Opptakelsesdato +IPTCPANEL_EMBEDDEDHINT;Nullstil til de IPTC data som finnes internt i bildefilen +IPTCPANEL_EMBEDDED;Intern IPTC data +IPTCPANEL_HEADLINEHINT;En kort beskrivelse av innholdet av bildet (Headline). +IPTCPANEL_HEADLINE;Overskrift +IPTCPANEL_INSTRUCTIONSHINT;Andre instuksjoner som omhandler bruken av bildet (Special Instructions). +IPTCPANEL_INSTRUCTIONS;Instruksjoner +IPTCPANEL_KEYWORDSHINT;Brukes til å beskrive spesifikke nøkkelord (Keywords). +IPTCPANEL_KEYWORDS;Nøkkelord +IPTCPANEL_PASTEHINT;Innsett IPTC innstillinger fra utklipstavlen +IPTCPANEL_PROVINCEHINT;Billedets opprinnelsesprovins/-stat (Province-State). +IPTCPANEL_PROVINCE;Provins +IPTCPANEL_RESETHINT;Nullstil til standard profil +IPTCPANEL_RESET;Nullstil +IPTCPANEL_SOURCEHINT;Den originale eier af bildets innhold (Source). +IPTCPANEL_SOURCE;Kilde +IPTCPANEL_SUPPCATEGORIESHINT;Ytterlige beskrivelser av innholdet i bildet (Supplemental Categories). +IPTCPANEL_SUPPCATEGORIES;Suppl. kategorier +IPTCPANEL_TITLEHINT;En kort beskrivelse av bildet (Object Name). +IPTCPANEL_TITLE;Bildetittel +IPTCPANEL_TRANSREFERENCEHINT;En kode som representerer stedet for original transmisjon (Original Transmission Reference). +IPTCPANEL_TRANSREFERENCE;Trans. Reference +MAIN_BUTTON_PREFERENCES;Innstillinger +MAIN_BUTTON_SAVE;Lagre bilde +MAIN_BUTTON_SENDTOEDITOR;Send til editor +MAIN_FRAME_BATCHQUEUE;Batch Queue +MAIN_FRAME_FILEBROWSER;File Browser +MAIN_FRAME_PLACES;Places +MAIN_FRAME_PLACES_ADD;Add +MAIN_FRAME_PLACES_DEL;Del +MAIN_FRAME_RECENT;Recent Folders +MAIN_MSG_ALREADYEXISTS;Filen eksisterer allerede. +MAIN_MSG_CANNOTLOAD;Kan ikke åpne bildet +MAIN_MSG_CANNOTSAVE;Kan ikke lagre +MAIN_MSG_CANNOTSTARTEDITOR;Kan ikke starte editor. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Vennligst sett korrekt bane i "Innstillinger" dialogen. +MAIN_MSG_QOVERWRITE;Vil du overskrive? +MAIN_TAB_COLOR;Farge +MAIN_TAB_DETAIL;Detailj +MAIN_TAB_DEVELOP;Develop +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;Eksponering +MAIN_TAB_FILTER;Filter +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadata +MAIN_TAB_TRANSFORM;Endre +MAIN_TOOLTIP_HIDEHP;Vis/skjul venstre panel (Inneholder historikken shortcut key: H) +MAIN_TOOLTIP_INDCLIPPEDH;Marker høylys-indikering +MAIN_TOOLTIP_INDCLIPPEDS;Marker skygge-indikering +MAIN_TOOLTIP_QINFO;Hurtig informasjon om bildet +PARTIALPASTE_BASICGROUP;Basisinnstillinger +PARTIALPASTE_CACORRECTION;C/A korreksjon +PARTIALPASTE_COARSETRANS;90° rotasjon/flipping +PARTIALPASTE_COLORGROUP;Fargerelaterte innstillinger +PARTIALPASTE_COMPOSITIONGROUP;Komposisjonsinnstillinger +PARTIALPASTE_CROP;Utsnitt +PARTIALPASTE_DIALOGLABEL;Delvis innliming av prosesseringsprofil +PARTIALPASTE_DISTORTION;Forvrengningskorreksjon +PARTIALPASTE_EXIFCHANGES;Forandringer i exif data +PARTIALPASTE_EXPOSURE;Exponering +PARTIALPASTE_ICMSETTINGS;ICM settings +PARTIALPASTE_IPTCINFO;IPTC info +PARTIALPASTE_LENSGROUP;Objektivrelaterte innstillinger +PARTIALPASTE_METAGROUP;Metadata +PARTIALPASTE_RESIZE;Forandre størrelse +PARTIALPASTE_ROTATION;Rotasjon +PARTIALPASTE_SHADOWSHIGHLIGHTS;Skygger/Høylys +PARTIALPASTE_SHARPENING;Oppskarping +PARTIALPASTE_VIGNETTING;Vignetteringskorreksjon +PARTIALPASTE_WHITEBALANCE;Hvitbalanse +PREFERENCES_APPLNEXTSTARTUP;Endres ved neste oppstart +PREFERENCES_CACHECLEARALL;Slett alle +PREFERENCES_CACHECLEARPROFILES;Slett profiler +PREFERENCES_CACHECLEARTHUMBS;Slett thumbnails +PREFERENCES_CACHEMAXENTRIES;Maksimalt antall cache oppføringer +PREFERENCES_CACHEOPTS;Cache innstillinger +PREFERENCES_CACHETHUMBHEIGHT;Maksimal Thumbnail Høyde +PREFERENCES_CLIPPINGIND;Markerings-indikasjon +PREFERENCES_CMETRICINTENT;Kolorimetrisk Inntrykk +PREFERENCES_DATEFORMATHINT;Du kan bruke følgende formattering:\n%y : år\n%m : måned\n%d : dag\n\nF. eks. er ungarsk datoformat:\n%y/%m/%d +PREFERENCES_DATEFORMAT;Datoformat +PREFERENCES_DEFAULTLANG;Programspråk +PREFERENCES_DEFAULTTHEME;Standard tema +PREFERENCES_DIRHOME;Hjemmemappe +PREFERENCES_DIRLAST;Sidste besøkte mappe +PREFERENCES_DIROTHER;Annen +PREFERENCES_DIRSELECTDLG;Velg bildemappe ved oppstart... +PREFERENCES_DIRSOFTWARE;Installasjons-mappe +PREFERENCES_EDITORCMDLINE;Annen kommandolinje +PREFERENCES_EXTERNALEDITOR;Ekstern editor +PREFERENCES_FBROWSEROPTS;Filfremviser-innstillinger +PREFERENCES_FILEFORMAT;Filformat +PREFERENCES_FORIMAGE;For bildefiler +PREFERENCES_FORRAW;For RAW-filer +PREFERENCES_GIMPPATH;GIMP installasjonsmappe +PREFERENCES_HLTHRESHOLD;Terskelverdi for markerte høylys +PREFERENCES_ICCDIR;Mappe til ICC-profiler +PREFERENCES_IMPROCPARAMS;Standard-bildebehandlingsparametre +PREFERENCES_INTENT_ABSOLUTE;Total kolorimetri +PREFERENCES_INTENT_PERCEPTUAL;Oppfattet kolorimetri +PREFERENCES_INTENT_RELATIVE;Relativ kolorimetri +PREFERENCES_INTENT_SATURATION;Metning +PREFERENCES_MONITORICC;Skjermprofil +PREFERENCES_OUTDIRFOLDERHINT;Send lagrede bilder til valgt folder +PREFERENCES_OUTDIRFOLDER;Lagre til folder +PREFERENCES_OUTDIRTEMPLATEHINT;Du kan bruke følgende formattering:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nFormateringsstrengene refererer til folderne og understier av stien til RAW-filen.\n\nF. eks., hvis /home/tom/image/02-09-2006/dsc0012.nefhar vært åpnet, vil det bety at formateringsstrengen er:\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\nvis du vil lagre det prosesserte bildet der originalen er, skriv:\n%p1/%f\n\nHvis du vil lagre det prosesserte bildet i folderen 'converted' under inni originalfolderen, skriv:\n%p1/converted/%f\n\nHvis du vil lagre det prosesserte bildet i '/home/tom/converted' men beholde underfolderens datomerking, skriv:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Bruk mal +PREFERENCES_OUTDIR;Utmappe +PREFERENCES_PARSEDEXTADDHINT;Skriv inn en utvidelse og trykk på kanppen for å legge til listen +PREFERENCES_PARSEDEXTADD;Legg til utvidelse +PREFERENCES_PARSEDEXTDELHINT;Fjern valgte utvidelse fra listen +PREFERENCES_PARSEDEXT;Analyserte utvidelser +PREFERENCES_PROFILEHANDLING;Prosesserer filbehandling +PREFERENCES_PROFILELOADPR;Profillastingsprioritet +PREFERENCES_PROFILEPRCACHE;Profil i Cache +PREFERENCES_PROFILEPRFILE;Profil i innfilen +PREFERENCES_PROFILESAVECACHE;Lagre prosesseringsparametre til cachen +PREFERENCES_PROFILESAVEINPUT;Lagre prosesseringsparametre i innfilen +PREFERENCES_PSPATH;Adobe Photoshop installasjonsfolder +PREFERENCES_SELECTLANG;Velg språk +PREFERENCES_SELECTTHEME;Velg tema +PREFERENCES_SHOWBASICEXIF;Vis utvidet Exif-informasjon +PREFERENCES_SHOWDATETIME;Vis dato og tid +PREFERENCES_SHTHRESHOLD;Terskelverdi for markerte skygger +PREFERENCES_STARTUPIMDIR;Bildemappe som vises ved oppstart +PREFERENCES_TAB_BROWSER;Filfremviser +PREFERENCES_TAB_COLORMGR;Fargehåndtering +PREFERENCES_TAB_GENERAL;Generelt +PREFERENCES_TAB_IMPROC;Bildebehandling +PROFILEPANEL_LABEL;Bildebehandlingsprofiler +PROFILEPANEL_LOADDLGLABEL;Åpne bildebehandlingsparametre... +PROFILEPANEL_PCUSTOM;Egen +PROFILEPANEL_PFILE;Fra fil +PROFILEPANEL_PLASTSAVED;Seneste lagret +PROFILEPANEL_SAVEDLGLABEL;Lagre bildebehandlingsparametre... +PROFILEPANEL_TOOLTIPCOPY;Kopier gjeldende profil til utklippstavlen +PROFILEPANEL_TOOLTIPLOAD;Åpne profil fra fil +PROFILEPANEL_TOOLTIPPASTE; Lim inn profil fra utklippstavlen +PROFILEPANEL_TOOLTIPSAVE;Lagre nåværende profil +PROGRESSBAR_LOADING;Åpner bilde... +PROGRESSBAR_LOADJPEG;Åpner JPEG-fil... +PROGRESSBAR_LOADPNG;Åpner PNG-fil... +PROGRESSBAR_LOADTIFF;Åpner TIFF-fil... +PROGRESSBAR_PROCESSING;Bearbeider Bilde... +PROGRESSBAR_READY;Klar +PROGRESSBAR_SAVEJPEG;Lagre JPEG-fil... +PROGRESSBAR_SAVEPNG;Lagre PNG-fil... +PROGRESSBAR_SAVETIFF;Lagre TIFF-fil... +QINFO_ISO;ISO +QINFO_NOEXIF;Exifdata utilgjengelig. +SAVEDLG_FILEFORMAT;Filformat +SAVEDLG_JPEGQUAL;JPEG-kvalitet +SAVEDLG_PNGCOMPR;PNG-komprimering +SAVEDLG_PUTTOQUEUEHEAD;Sett øverst i prosesseringskøen +SAVEDLG_PUTTOQUEUETAIL;Sett nederst i prosesseringskøen +SAVEDLG_PUTTOQUEUE;Sett i prosesseringskø +SAVEDLG_SAVEIMMEDIATELY;Lagre med en gang +SAVEDLG_SAVESPP;Lagre bildebehandlingsparametre med bildene +TOOLBAR_TOOLTIP_CROP;Velg beskjæringsområde (shortcut key: C) +TOOLBAR_TOOLTIP_HAND;Håndverktøy (shortcut key: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;Rett opp (shortcut key: S) +TOOLBAR_TOOLTIP_WB;Punkt-hvitbalanse (shortcut key: W) +TP_CACORRECTION_BLUE;Blå +TP_CACORRECTION_LABEL;C/A justering +TP_CACORRECTION_RED;Rød +TP_CHMIXER_BLUE;Blå +TP_CHMIXER_GREEN;Grønn +TP_CHMIXER_LABEL;Kanalmikser +TP_CHMIXER_RED;Rød +TP_COARSETRAF_TOOLTIP_HFLIP;Vend horisontalt +TP_COARSETRAF_TOOLTIP_ROTLEFT;Roter mot venstre +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Roter mot høyre +TP_COARSETRAF_TOOLTIP_VFLIP;Vend vertikalt +TP_CROP_FIXRATIO;Fast proporsjon +TP_CROP_GTDIAGONALS;Diagonalreglen +TP_CROP_GTNONE;Ingen +TP_CROP_GTRULETHIRDS;Tredjedelsreglen +TP_CROP_GUIDETYPE;Guidetype: +TP_CROP_H;H +TP_CROP_LABEL;Beskjæring +TP_CROP_SELECTCROP;Velg beskjæringsområde +TP_CROP_W;B +TP_CROP_X;x +TP_CROP_Y;y +TP_DISTORTION_AMOUNT;Mengde +TP_DISTORTION_LABEL;Forvrengning +TP_EXPOSURE_AUTOLEVELS;Auto nivå +TP_EXPOSURE_BLACKLEVEL;Sort +TP_EXPOSURE_BRIGHTNESS;Lysstyrke +TP_EXPOSURE_CLIP;Klipp +TP_EXPOSURE_COMPRHIGHLIGHTS;Høylyskomprimering +TP_EXPOSURE_COMPRSHADOWS;Skyggekomprimering +TP_EXPOSURE_CONTRAST;Kontrast +TP_EXPOSURE_CURVEEDITOR;Tonekurve +TP_EXPOSURE_EXPCOMP;Eks. Komp. +TP_EXPOSURE_LABEL;Eksponering +TP_HLREC_CIELAB;CIELab Blending +TP_HLREC_COLOR;Fargespedning +TP_HLREC_LABEL;Høylys-forbedring +TP_HLREC_LUMINANCE;Forbedring av luminans +TP_HLREC_METHOD;Metode: +TP_ICM_INPUTCAMERA;Kameravalg +TP_ICM_INPUTCUSTOM;Egen +TP_ICM_INPUTDLGLABEL;Velg indgangs ICC-profil... +TP_ICM_INPUTEMBEDDED;Anvend intern, hvis mulig +TP_ICM_INPUTPROFILE;Inngangprofil +TP_ICM_LABEL;ICM +TP_ICM_NOICM;Ingen ICM: sRGB-profil +TP_ICM_OUTPUTPROFILE;Utgangsprofil +TP_ICM_SAVEREFERENCE;Lagre referansebilde til profil +TP_ICM_WORKINGPROFILE;Arbeidsprofil +TP_RAW_DMETHOD;Metode +TP_RAW_FALSECOLOR;Falsk fargefortrengningsverdi +TP_RESIZE_H;H: +TP_RESIZE_LABEL;Endre størrelse +TP_RESIZE_METHOD;Metode: +TP_RESIZE_NEAREST;Nærmeste +TP_RESIZE_SCALE;Skala +TP_RESIZE_W;B: +TP_ROTATE_DEGREE;Antall grader +TP_ROTATE_LABEL;Rett opp +TP_ROTATE_SELECTLINE;Velg rett linje +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Høylys +TP_SHADOWSHLIGHTS_HLTONALW;Toneomfang +TP_SHADOWSHLIGHTS_LABEL;Skygger/høylys +TP_SHADOWSHLIGHTS_LOCALCONTR;Lokal kontrast +TP_SHADOWSHLIGHTS_RADIUS;Radius +TP_SHADOWSHLIGHTS_SHADOWS;Skygger +TP_SHADOWSHLIGHTS_SHTONALW;Toneomfang +TP_SHARPENING_AMOUNT;Mengde +TP_SHARPENING_EDRADIUS;Radius +TP_SHARPENING_EDTOLERANCE;Kanttoleranse +TP_SHARPENING_HALOCONTROL;Halo-kontroll +TP_SHARPENING_HCAMOUNT;Mengde +TP_SHARPENING_LABEL;Skarphet +TP_SHARPENING_METHOD;Metode +TP_SHARPENING_ONLYEDGES;Skarphet kun i kanter +TP_SHARPENING_RADIUS;Radius +TP_SHARPENING_RLD;RL Dekonvolusjon +TP_SHARPENING_RLD_AMOUNT;Mengde +TP_SHARPENING_RLD_DAMPING;Demping +TP_SHARPENING_RLD_ITERATIONS;Gjentakelse +TP_SHARPENING_THRESHOLD;Terskelverdi +TP_SHARPENING_USM;Uskarp maske +TP_VIGNETTING_AMOUNT;Mengde +TP_VIGNETTING_LABEL;Vignetterings-korrigering +TP_VIGNETTING_RADIUS;Radius +TP_WBALANCE_AUTO;Auto +TP_WBALANCE_CAMERA;Kamera +TP_WBALANCE_CUSTOM;Egen +TP_WBALANCE_GREEN;Nyanse +TP_WBALANCE_LABEL;Hvitbalanse +TP_WBALANCE_METHOD;Metode +TP_WBALANCE_SIZE;Størrelse: +TP_WBALANCE_SPOTWB;Punkt HB +TP_WBALANCE_TEMPERATURE;Temperatur + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!ABOUT_TAB_BUILD;Version +!ABOUT_TAB_CREDITS;Credits +!ABOUT_TAB_LICENSE;License +!ABOUT_TAB_RELEASENOTES;Release Notes +!ABOUT_TAB_SPLASH;Splash +!BATCHQUEUE_AUTOSTART;Auto-start +!BATCHQUEUE_DESTFILENAME;Path and file name +!BATCH_PROCESSING;Batch Processing +!CURVEEDITOR_AXIS_IN;I: +!CURVEEDITOR_AXIS_LEFT_TAN;LT: +!CURVEEDITOR_AXIS_OUT;O: +!CURVEEDITOR_AXIS_RIGHT_TAN;RT: +!CURVEEDITOR_CURVES;Curves +!CURVEEDITOR_CURVE;Curve +!CURVEEDITOR_CUSTOM;Custom +!CURVEEDITOR_DARKS;Darks +!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_HIGHLIGHTS;Highlights +!CURVEEDITOR_LIGHTS;Lights +!CURVEEDITOR_MINMAXCPOINTS;Equalizer +!CURVEEDITOR_NURBS;Control cage +!CURVEEDITOR_PARAMETRIC;Parametric +!CURVEEDITOR_SHADOWS;Shadows +!CURVEEDITOR_TOOLTIPCOPY;Copy current curve to clipboard. +!CURVEEDITOR_TOOLTIPPASTE;Paste curve from clipboard. +!CURVEEDITOR_TYPE;Type: +!EDITWINDOW_TITLE;Image Edit +!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_FILETYPE;File type +!EXIFFILTER_METADATAFILTER;Enable metadata filters +!EXPORT_BYPASS_ALL;Select / Unselect All +!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_FF;Bypass [raw] Flat-Field +!EXPORT_BYPASS_RAW_GREENTHRESH;Bypass [raw] Green Equilibration +!EXPORT_BYPASS_RAW_LINENOISE;Bypass [raw] Line Noise Filter +!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_FASTEXPORTOPTIONS;Fast Export Options +!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_MAXHEIGHT;Maximum height: +!EXPORT_MAXWIDTH;Maximum width: +!EXPORT_PUTTOQUEUEFAST; Put to queue for fast export +!EXPORT_RAW_DMETHOD;Demosaic method +!EXTPROGTARGET_1;raw +!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_CACHECLEARFROMFULL;Clear from cache - full +!FILEBROWSER_CACHECLEARFROMPARTIAL;Clear from cache - partial +!FILEBROWSER_CACHE;Cache +!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_CURRENT_NAME;Current name: +!FILEBROWSER_DARKFRAME;Dark-frame +!FILEBROWSER_DELETEDLGMSGINCLPROC;Are you sure you want to delete the selected %1 files including a queue-processed version? +!FILEBROWSER_EXEC_CPB;Custom Profile Builder +!FILEBROWSER_EXTPROGMENU;Open with +!FILEBROWSER_FLATFIELD;Flat-Field +!FILEBROWSER_MOVETODARKFDIR;Move to dark-frames directory +!FILEBROWSER_MOVETOFLATFIELDDIR;Move to flat-fields directory +!FILEBROWSER_NEW_NAME;New name: +!FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) +!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_POPUPCOLORLABEL;Color label +!FILEBROWSER_POPUPCOPYTO;Copy to... +!FILEBROWSER_POPUPFILEOPERATIONS;File operations +!FILEBROWSER_POPUPMOVETO;Move to... +!FILEBROWSER_POPUPPROCESSFAST;Put to queue (Fast export) +!FILEBROWSER_POPUPPROFILEOPERATIONS;Processing profile operations +!FILEBROWSER_POPUPRANK0;Unrank +!FILEBROWSER_POPUPRANK1;Rank 1 * +!FILEBROWSER_POPUPRANK2;Rank 2 ** +!FILEBROWSER_POPUPRANK3;Rank 3 *** +!FILEBROWSER_POPUPRANK4;Rank 4 **** +!FILEBROWSER_POPUPRANK5;Rank 5 ***** +!FILEBROWSER_POPUPRANK;Rank +!FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!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_QUERYLABEL; Find: +!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_SELECTDARKFRAME;Select dark-frame... +!FILEBROWSER_SELECTFLATFIELD;Select flat-field... +!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 +!FILEBROWSER_SHOWCOLORLABEL4HINT;Show images labeled Blue.\nShortcut: Alt-4 +!FILEBROWSER_SHOWCOLORLABEL5HINT;Show images labeled Purple.\nShortcut: Alt-5 +!FILEBROWSER_SHOWEDITEDHINT;Show edited images.\nShortcut: 7 +!FILEBROWSER_SHOWEDITEDNOTHINT;Show not edited images.\nShortcut: 6 +!FILEBROWSER_SHOWEXIFINFO;Show Exif info.\n\nShortcuts:\ni - Multiple Editor Tabs Mode,\nAlt-i - Single Editor Tab Mode. +!FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!FILEBROWSER_SHOWRECENTLYSAVEDHINT;Show saved images.\nShortcut: Alt-7 +!FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show unsaved images.\nShortcut: Alt-6 +!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_AFTER;After +!GENERAL_ASIMAGE;As Image +!GENERAL_AUTO;Automatic +!GENERAL_BEFORE;Before +!GENERAL_CLOSE;Close +!GENERAL_FILE;File +!GENERAL_NONE;None +!GENERAL_UNCHANGED;(Unchanged) +!GENERAL_WARNING;Warning +!HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar.\nRight-click on image preview to freeze/unfreeze. +!HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram. +!HISTOGRAM_TOOLTIP_FULL;Toggle full (off) or scaled (on) histogram. +!HISTOGRAM_TOOLTIP_RAW;Show/Hide raw histogram. +!HISTORY_MSG_82;Profile changed +!HISTORY_MSG_83;S/H - Sharp mask +!HISTORY_MSG_84;Perspective correction +!HISTORY_MSG_85;LCP +!HISTORY_MSG_86;RGB curves - Luminosity mode +!HISTORY_MSG_87;Impulse noise reduction +!HISTORY_MSG_88;Impulse NR threshold +!HISTORY_MSG_89;Noise Reduction +!HISTORY_MSG_90;NR - Luminance +!HISTORY_MSG_91;NR - Chrominance master +!HISTORY_MSG_92;NR - Gamma +!HISTORY_MSG_93;CbDL - Value +!HISTORY_MSG_94;Contrast by Detail Levels +!HISTORY_MSG_95;L*a*b* - Chromaticity +!HISTORY_MSG_96;L*a*b* - a* curve +!HISTORY_MSG_97;L*a*b* - b* curve +!HISTORY_MSG_98;Demosaicing method +!HISTORY_MSG_99;Hot pixel filter +!HISTORY_MSG_100;RGB Saturation +!HISTORY_MSG_101;HSV - Hue +!HISTORY_MSG_102;HSV - Saturation +!HISTORY_MSG_103;HSV - Value +!HISTORY_MSG_104;HSV Equalizer +!HISTORY_MSG_105;Defringe +!HISTORY_MSG_106;Defringe - Radius +!HISTORY_MSG_107;Defringe - Threshold +!HISTORY_MSG_108;Highlight Compr. Threshold +!HISTORY_MSG_109;Resize - Bounding box +!HISTORY_MSG_110;Resize - Applies to +!HISTORY_MSG_111;L*a*b* - Avoid color shift +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;L*a*b* - Red/skin prot. +!HISTORY_MSG_114;DCB iterations +!HISTORY_MSG_115;False color suppression +!HISTORY_MSG_116;DCB enhancement +!HISTORY_MSG_117;Raw CA correction - Red +!HISTORY_MSG_118;Raw CA correction - Blue +!HISTORY_MSG_119;Line noise filter +!HISTORY_MSG_120;Green equilibration +!HISTORY_MSG_121;Raw CA Correction - Auto +!HISTORY_MSG_122;Dark-Frame - Auto-selection +!HISTORY_MSG_123;Dark-Frame - File +!HISTORY_MSG_124;White point correction +!HISTORY_MSG_125;Highlight preservation +!HISTORY_MSG_126;Flat-Field - File +!HISTORY_MSG_127;Flat-Field - Auto-selection +!HISTORY_MSG_128;Flat-Field - Blur radius +!HISTORY_MSG_129;Flat-Field - Blur type +!HISTORY_MSG_130;Auto distorion correction +!HISTORY_MSG_131;NR - Luma +!HISTORY_MSG_132;NR - Chroma +!HISTORY_MSG_133;Output gamma +!HISTORY_MSG_134;Free gamma +!HISTORY_MSG_135;Free gamma +!HISTORY_MSG_136;Free gamma slope +!HISTORY_MSG_137;Black level - Green 1 +!HISTORY_MSG_138;Black level - Red +!HISTORY_MSG_139;Black level - Blue +!HISTORY_MSG_140;Black level - Green 2 +!HISTORY_MSG_141;Black level - Link greens +!HISTORY_MSG_142;ES - Iterations +!HISTORY_MSG_143;ES - Quantity +!HISTORY_MSG_144;Microcontrast - Quantity +!HISTORY_MSG_145;Microcontrast - Uniformity +!HISTORY_MSG_146;Edge sharpening +!HISTORY_MSG_147;ES - Luminance only +!HISTORY_MSG_148;Microcontrast +!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_150;Post-demosaic artifact/noise red. +!HISTORY_MSG_151;Vibrance +!HISTORY_MSG_152;Vib - Pastel tones +!HISTORY_MSG_153;Vib - Saturated tones +!HISTORY_MSG_154;Vib - Protect skin-tones +!HISTORY_MSG_155;Vib - Avoid color shift +!HISTORY_MSG_156;Vib - Link pastel/saturated +!HISTORY_MSG_157;Vib - P/S threshold +!HISTORY_MSG_158;TM - Strength +!HISTORY_MSG_159;TM - Edge stopping +!HISTORY_MSG_160;TM - Scale +!HISTORY_MSG_161;TM - Reweighting iterates +!HISTORY_MSG_162;Tone Mapping +!HISTORY_MSG_163;RGB curves - Red +!HISTORY_MSG_164;RGB curves - Green +!HISTORY_MSG_165;RGB curves - Blue +!HISTORY_MSG_166;Neutral levels +!HISTORY_MSG_167;--unused-- +!HISTORY_MSG_168;L*a*b* - CC curve +!HISTORY_MSG_169;L*a*b* - CH curve +!HISTORY_MSG_170;Vibrance - HH curve +!HISTORY_MSG_171;L*a*b* - LC curve +!HISTORY_MSG_172;L*a*b* - Restrict LC +!HISTORY_MSG_173;NR - Luminance detail +!HISTORY_MSG_174;CIECAM02 +!HISTORY_MSG_175;CAM02 - CAT02 adaptation +!HISTORY_MSG_176;CAM02 - Viewing surround +!HISTORY_MSG_177;CAM02 - Scene luminosity +!HISTORY_MSG_178;CAM02 - Viewing luminosity +!HISTORY_MSG_179;CAM02 - White-point model +!HISTORY_MSG_180;CAM02 - Lightness (J) +!HISTORY_MSG_181;CAM02 - Chroma (C) +!HISTORY_MSG_182;CAM02 - Automatic CAT02 +!HISTORY_MSG_183;CAM02 - Contrast (J) +!HISTORY_MSG_184;CAM02 - Scene surround +!HISTORY_MSG_185;CAM02 - Gamut control +!HISTORY_MSG_186;CAM02 - Algorithm +!HISTORY_MSG_187;CAM02 - Red/skin prot. +!HISTORY_MSG_188;CAM02 - Brightness (Q) +!HISTORY_MSG_189;CAM02 - Contrast (Q) +!HISTORY_MSG_190;CAM02 - Saturation (S) +!HISTORY_MSG_191;CAM02 - Colorfulness (M) +!HISTORY_MSG_192;CAM02 - Hue (h) +!HISTORY_MSG_193;CAM02 - Tone curve 1 +!HISTORY_MSG_194;CAM02 - Tone curve 2 +!HISTORY_MSG_195;CAM02 - Tone curve 1 +!HISTORY_MSG_196;CAM02 - Tone curve 2 +!HISTORY_MSG_197;CAM02 - Color curve +!HISTORY_MSG_198;CAM02 - Color curve +!HISTORY_MSG_199;CAM02 - Output histograms +!HISTORY_MSG_200;CAM02 - Tone mapping +!HISTORY_MSG_201;NR - Chrominance - R&G +!HISTORY_MSG_202;NR - Chrominance - B&Y +!HISTORY_MSG_203;NR - Method +!HISTORY_MSG_204;LMMSE enhancement steps +!HISTORY_MSG_205;CAM02 - Hot/bad pixel filter +!HISTORY_MSG_206;CAT02 - Auto scene luminosity +!HISTORY_MSG_207;Defringe - Hue curve +!HISTORY_MSG_208;WB - B/R equalizer +!HISTORY_MSG_210;GF - Angle +!HISTORY_MSG_211;Graduated Filter +!HISTORY_MSG_212;VF - Strength +!HISTORY_MSG_213;Vignette Filter +!HISTORY_MSG_214;Black-and-White +!HISTORY_MSG_215;B&W - CM - Red +!HISTORY_MSG_216;B&W - CM - Green +!HISTORY_MSG_217;B&W - CM - Blue +!HISTORY_MSG_218;B&W - Gamma - Red +!HISTORY_MSG_219;B&W - Gamma - Green +!HISTORY_MSG_220;B&W - Gamma - Blue +!HISTORY_MSG_221;B&W - Color filter +!HISTORY_MSG_222;B&W - Presets +!HISTORY_MSG_223;B&W - CM - Orange +!HISTORY_MSG_224;B&W - CM - Yellow +!HISTORY_MSG_225;B&W - CM - Cyan +!HISTORY_MSG_226;B&W - CM - Magenta +!HISTORY_MSG_227;B&W - CM - Purple +!HISTORY_MSG_228;B&W - Luminance equalizer +!HISTORY_MSG_229;B&W - Luminance equalizer +!HISTORY_MSG_230;B&W - Mode +!HISTORY_MSG_231;B&W - 'Before' curve +!HISTORY_MSG_232;B&W - 'Before' curve type +!HISTORY_MSG_233;B&W - 'After' curve +!HISTORY_MSG_234;B&W - 'After' curve type +!HISTORY_MSG_235;B&W - Auto channel mixer +!HISTORY_MSG_236;--unused-- +!HISTORY_MSG_237;B&W - Mixer +!HISTORY_MSG_238;GF - Feather +!HISTORY_MSG_239;GF - Strength +!HISTORY_MSG_240;GF - Center +!HISTORY_MSG_241;VF - Feather +!HISTORY_MSG_242;VF - Roundness +!HISTORY_MSG_243;VC - Radius +!HISTORY_MSG_244;VC - Strength +!HISTORY_MSG_245;VC - Center +!HISTORY_MSG_246;L*a*b* - CL curve +!HISTORY_MSG_247;L*a*b* - LH curve +!HISTORY_MSG_248;L*a*b* - HH curve +!HISTORY_MSG_249;CbDL - Threshold +!HISTORY_MSG_250;NR - Enhanced +!HISTORY_MSG_251;B&W - Algorithm +!HISTORY_MSG_252;CbDL - Skin tar/prot +!HISTORY_MSG_253;CbDL - Reduce artifacts +!HISTORY_MSG_254;CbDL - Skin hue +!HISTORY_MSG_255;NR - Median filter +!HISTORY_MSG_256;NR - Median type +!HISTORY_MSG_257;Color Toning +!HISTORY_MSG_258;CT - Color curve +!HISTORY_MSG_259;CT - Opacity curve +!HISTORY_MSG_260;CT - a*[b*] opacity +!HISTORY_MSG_261;CT - Method +!HISTORY_MSG_262;CT - b* opacity +!HISTORY_MSG_263;CT - Shadows - Red +!HISTORY_MSG_264;CT - Shadows - Green +!HISTORY_MSG_265;CT - Shadows - Blue +!HISTORY_MSG_266;CT - Mid - Red +!HISTORY_MSG_267;CT - Mid - Green +!HISTORY_MSG_268;CT - Mid - Blue +!HISTORY_MSG_269;CT - High - Red +!HISTORY_MSG_270;CT - High - Green +!HISTORY_MSG_271;CT - High - Blue +!HISTORY_MSG_272;CT - Balance +!HISTORY_MSG_273;CT - Reset +!HISTORY_MSG_274;CT - Sat. Shadows +!HISTORY_MSG_275;CT - Sat. Highlights +!HISTORY_MSG_276;CT - Opacity +!HISTORY_MSG_277;--unused-- +!HISTORY_MSG_278;CT - Preserve luminance +!HISTORY_MSG_279;CT - Shadows +!HISTORY_MSG_280;CT - Highlights +!HISTORY_MSG_281;CT - Sat. strength +!HISTORY_MSG_282;CT - Sat. threshold +!HISTORY_MSG_283;CT - Strength +!HISTORY_MSG_284;CT - Auto sat. protection +!HISTORY_MSG_285;NR - Median - Method +!HISTORY_MSG_286;NR - Median - Type +!HISTORY_MSG_287;NR - Median - Iterations +!HISTORY_MSG_288;Flat Field - Clip control +!HISTORY_MSG_289;Flat Field - Clip control - Auto +!HISTORY_MSG_290;Black Level - Red +!HISTORY_MSG_291;Black Level - Green +!HISTORY_MSG_292;Black Level - Blue +!HISTORY_MSG_293;Film Simulation +!HISTORY_MSG_294;Film Simulation - Strength +!HISTORY_MSG_295;Film Simulation - Film +!HISTORY_MSG_296;NR - Luminance curve +!HISTORY_MSG_297;NR - Quality +!HISTORY_MSG_298;Dead pixel filter +!HISTORY_MSG_299;NR - Chrominance curve +!HISTORY_MSG_300;- +!HISTORY_MSG_301;NR - Luma control +!HISTORY_MSG_302;NR - Chroma method +!HISTORY_MSG_303;NR - Chroma method +!HISTORY_MSG_304;W - Contrast levels +!HISTORY_MSG_305;Wavelet Levels +!HISTORY_MSG_306;W - Preview +!HISTORY_MSG_307;W - Preview +!HISTORY_MSG_308;W - Preview direction +!HISTORY_MSG_309;W - ES - Detail +!HISTORY_MSG_310;W - Residual - Sky tar/prot +!HISTORY_MSG_311;W - Wavelet levels +!HISTORY_MSG_312;W - Residual - Shadows threshold +!HISTORY_MSG_313;W - Chroma - Sat/past +!HISTORY_MSG_314;W - Gamut - Reduce artifacts +!HISTORY_MSG_315;W - Residual - Contrast +!HISTORY_MSG_316;W - Gamut - Skin tar/prot +!HISTORY_MSG_317;W - Gamut - Skin hue +!HISTORY_MSG_318;W - Contrast - Highlight levels +!HISTORY_MSG_319;W - Contrast - Highlight range +!HISTORY_MSG_320;W - Contrast - Shadow range +!HISTORY_MSG_321;W - Contrast - Shadow levels +!HISTORY_MSG_322;W - Gamut - Avoid color shift +!HISTORY_MSG_323;W - ES - Local contrast +!HISTORY_MSG_324;W - Chroma - Pastel +!HISTORY_MSG_325;W - Chroma - Saturated +!HISTORY_MSG_326;W - Chroma - Method +!HISTORY_MSG_327;W - Contrast - Apply to +!HISTORY_MSG_328;W - Chroma - Link strength +!HISTORY_MSG_329;W - Toning - Opacity RG +!HISTORY_MSG_330;W - Toning - Opacity BY +!HISTORY_MSG_331;W - Contrast levels - Extra +!HISTORY_MSG_332;W - Tiling method +!HISTORY_MSG_333;W - Residual - Shadows +!HISTORY_MSG_334;W - Residual - Chroma +!HISTORY_MSG_335;W - Residual - Highlights +!HISTORY_MSG_336;W - Residual - Highlights threshold +!HISTORY_MSG_337;W - Residual - Sky hue +!HISTORY_MSG_338;W - ES - Radius +!HISTORY_MSG_339;W - ES - Strength +!HISTORY_MSG_340;W - Strength +!HISTORY_MSG_341;W - Edge performance +!HISTORY_MSG_342;W - ES - First level +!HISTORY_MSG_343;W - Chroma levels +!HISTORY_MSG_344;W - Meth chroma sl/cur +!HISTORY_MSG_345;W - ES - Local contrast +!HISTORY_MSG_346;W - ES - Local contrast method +!HISTORY_MSG_347;W - Denoise - Level 0 +!HISTORY_MSG_348;W - Denoise - Level 1 +!HISTORY_MSG_349;W - Denoise - Level 2 +!HISTORY_MSG_350;W - ES - Edge detection +!HISTORY_MSG_351;W - Residual - HH curve +!HISTORY_MSG_352;W - Background +!HISTORY_MSG_353;W - ES - Gradient sensitivity +!HISTORY_MSG_354;W - ES - Enhance +!HISTORY_MSG_355;W - ES - Threshold low +!HISTORY_MSG_356;W - ES - Threshold high +!HISTORY_MSG_357;W - Denoise - Link with ES +!HISTORY_MSG_358;W - Gamut - CH +!HISTORY_MSG_359;Hot/Dead - Threshold +!HISTORY_MSG_360;TM Gamma +!HISTORY_MSG_361;W - Final - Chroma balance +!HISTORY_MSG_362;W - Residual - Compression method +!HISTORY_MSG_363;W - Residual - Compression strength +!HISTORY_MSG_364;W - Final - Contrast balance +!HISTORY_MSG_365;W - Final - Delta balance +!HISTORY_MSG_366;W - Residual - Compression gamma +!HISTORY_MSG_367;W - ES - Local contrast curve +!HISTORY_MSG_368;W - Final - Contrast balance +!HISTORY_MSG_369;W - Final - Balance method +!HISTORY_MSG_370;W - Final - Local contrast curve +!HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s +!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 +!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). +!MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Put current image to processing queue.\nShortcut: Ctrl+b +!MAIN_BUTTON_SAVE_TOOLTIP;Save current image.\nShortcut: Ctrl+s +!MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Edit current image in external editor.\nShortcut: Ctrl+e +!MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Show/hide all side panels.\nShortcut: m +!MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen +!MAIN_FRAME_BATCHQUEUE_TOOLTIP;Processing queue.\nShortcut: Ctrl-F3 +!MAIN_FRAME_EDITOR;Editor +!MAIN_FRAME_EDITOR_TOOLTIP;Editor.\nShortcut: Ctrl-F4 +!MAIN_FRAME_FILEBROWSER_TOOLTIP;File browser.\nShortcut: Ctrl-F2 +!MAIN_MSG_EMPTYFILENAME;Filename unspecified! +!MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue-processed first. +!MAIN_MSG_NAVIGATOR;Navigator +!MAIN_MSG_OPERATIONCANCELLED;Operation cancelled +!MAIN_MSG_PATHDOESNTEXIST;The path\n\n%1\n\ndoes not exist. Please set a correct path in Preferences. +!MAIN_MSG_SETPATHFIRST;You first have to set a target path in Preferences in order to use this function! +!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_EXPORT; Fast Export +!MAIN_TAB_EXPOSURE_TOOLTIP;Shortcut: Alt-e +!MAIN_TAB_INSPECT; Inspect +!MAIN_TAB_METADATA_TOOLTIP;Shortcut: Alt-m +!MAIN_TAB_RAW;Raw +!MAIN_TAB_RAW_TOOLTIP;Shortcut: Alt-r +!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_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%. +!MAIN_TOOLTIP_PREVIEWG;Preview the Green channel.\nShortcut: g +!MAIN_TOOLTIP_PREVIEWL;Preview the Luminosity.\nShortcut: v\n\n0.299*R + 0.587*G + 0.114*B +!MAIN_TOOLTIP_PREVIEWR;Preview the Red channel.\nShortcut: r +!MAIN_TOOLTIP_SHOWHIDELP1;Show/Hide the left panel.\nShortcut: l +!MAIN_TOOLTIP_SHOWHIDERP1;Show/Hide the right panel.\nShortcut: Alt-l +!MAIN_TOOLTIP_SHOWHIDETP1;Show/Hide the top panel.\nShortcut: Shift-l +!MAIN_TOOLTIP_THRESHOLD;Threshold +!MAIN_TOOLTIP_TOGGLE;Toggle the Before/After view.\nShortcut: Shift-b +!NAVIGATOR_B;B: +!NAVIGATOR_G;G: +!NAVIGATOR_H;H: +!NAVIGATOR_LAB_A;a*: +!NAVIGATOR_LAB_B;b*: +!NAVIGATOR_LAB_L;L*: +!NAVIGATOR_NA; -- +!NAVIGATOR_R;R: +!NAVIGATOR_S;S: +!NAVIGATOR_V;V: +!NAVIGATOR_XY_FULL;Width: %1, Height: %2 +!NAVIGATOR_XY_NA;x: --, y: -- +!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_CHANNELMIXERBW;Black-and-White +!PARTIALPASTE_CHANNELMIXER;Channel mixer +!PARTIALPASTE_COLORAPP;CIECAM02 +!PARTIALPASTE_COLORTONING;Color Toning +!PARTIALPASTE_COMMONTRANSFORMPARAMS;Auto-fill +!PARTIALPASTE_DARKFRAMEAUTOSELECT;Dark-frame auto-selection +!PARTIALPASTE_DARKFRAMEFILE;Dark-frame file +!PARTIALPASTE_DEFRINGE;Defringe +!PARTIALPASTE_DETAILGROUP;Detail Settings +!PARTIALPASTE_DIRPYRDENOISE;Noise reduction +!PARTIALPASTE_DIRPYREQUALIZER;Contrast by detail levels +!PARTIALPASTE_EPD;Tone mapping +!PARTIALPASTE_EQUALIZER;Wavelet Equalizer +!PARTIALPASTE_EVERYTHING;Everything +!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_GRADIENT;Graduated filter +!PARTIALPASTE_HSVEQUALIZER;HSV equalizer +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction +!PARTIALPASTE_LABCURVE;L*a*b* adjustments +!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_PCVIGNETTE;Vignette filter +!PARTIALPASTE_PERSPECTIVE;Perspective +!PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter +!PARTIALPASTE_PREPROCESS_GREENEQUIL;Green equilibration +!PARTIALPASTE_PREPROCESS_HOTPIXFILT;Hot pixel filter +!PARTIALPASTE_PREPROCESS_LINEDENOISE;Line noise filter +!PARTIALPASTE_RAWCACORR_AUTO;CA auto-correction +!PARTIALPASTE_RAWCACORR_CABLUE;CA blue +!PARTIALPASTE_RAWCACORR_CARED;CA red +!PARTIALPASTE_RAWEXPOS_BLACK;Black levels +!PARTIALPASTE_RAWEXPOS_LINEAR;White point correction +!PARTIALPASTE_RAWEXPOS_PRESER;Highlight preservation +!PARTIALPASTE_RAWGROUP;Raw Settings +!PARTIALPASTE_RAW_DCBENHANCE;DCB enhancement +!PARTIALPASTE_RAW_DCBITERATIONS;Number of DCB iterations +!PARTIALPASTE_RAW_DMETHOD;Demosaic method +!PARTIALPASTE_RAW_FALSECOLOR;Demosaic false color suppression steps +!PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!PARTIALPASTE_RGBCURVES;RGB curves +!PARTIALPASTE_SHARPENEDGE;Edges +!PARTIALPASTE_SHARPENMICRO;Microcontrast +!PARTIALPASTE_VIBRANCE;Vibrance +!PARTIALPASTE_WAVELETGROUP;Wavelet processing +!PREFERENCES_ADD;Add +!PREFERENCES_AUTLISLOW;Low +!PREFERENCES_AUTLISMAX;Max - Average of all tiles +!PREFERENCES_AUTLISSTD;High +!PREFERENCES_AUTLISVLOW;None +!PREFERENCES_AUTLOW;Low +!PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +!PREFERENCES_AUTSTD;Standard +!PREFERENCES_BATCH_PROCESSING;Batch Processing +!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_BEHADDALL;All to 'Add' +!PREFERENCES_BEHAVIOR;Behavior +!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_BEHSETALL;All to 'Set' +!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_CURVEBBOXPOS;Position of curve copypasta buttons +!PREFERENCES_CURVEBBOXPOS_ABOVE;Above +!PREFERENCES_CURVEBBOXPOS_BELOW;Below +!PREFERENCES_CURVEBBOXPOS_LEFT;Left +!PREFERENCES_CURVEBBOXPOS_RIGHT;Right +!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_CUSTPROFBUILD;Custom Processing Profile Builder +!PREFERENCES_CUTOVERLAYBRUSH;Crop mask color/transparency +!PREFERENCES_D50;5000K +!PREFERENCES_D55;5500K +!PREFERENCES_D60;6000K +!PREFERENCES_D65;6500K +!PREFERENCES_DARKFRAMEFOUND;Found +!PREFERENCES_DARKFRAMESHOTS;shots +!PREFERENCES_DARKFRAMETEMPLATES;templates +!PREFERENCES_DARKFRAME;Dark-Frame +!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 (de-select for low resolution display) +!PREFERENCES_FILMSIMULATION;Film Simulation +!PREFERENCES_FLATFIELDFOUND;Found +!PREFERENCES_FLATFIELDSDIR;Flat-fields directory +!PREFERENCES_FLATFIELDSHOTS;shots +!PREFERENCES_FLATFIELDTEMPLATES;templates +!PREFERENCES_FLATFIELD;Flat-Field +!PREFERENCES_FLUOF2;Fluorescent F2 +!PREFERENCES_FLUOF7;Fluorescent F7 +!PREFERENCES_FLUOF11;Fluorescent F11 +!PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT;Same thumbnail height between the Editor's panel 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_GREY05;Yb=05 CIE L#30 +!PREFERENCES_GREY10;Yb=10 CIE L#40 +!PREFERENCES_GREY15;Yb=15 CIE L#45 +!PREFERENCES_GREY18;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_GREYSC18;Yb=18 CIE L#50 +!PREFERENCES_GREYSCA;Automatic +!PREFERENCES_GREYSC;Scene Yb luminance (%) +!PREFERENCES_GREY;Output device's Yb luminance (%) +!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_LANGAUTODETECT;Use system language +!PREFERENCES_LEVAUTDN;Denoising level +!PREFERENCES_LEVDN;Cell size +!PREFERENCES_LISS;Auto multi-zone smoothing +!PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders +!PREFERENCES_MAX;Maxi (Tile) +!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_MENUGROUPRANK;Group "Rank" +!PREFERENCES_MENUOPTIONS;Context Menu Options +!PREFERENCES_METADATA;Metadata +!PREFERENCES_MIN;Mini (100x115) +!PREFERENCES_MULTITABDUALMON;Multiple Editor Tabs In Own Window Mode +!PREFERENCES_MULTITAB;Multiple Editor Tabs 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_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_PROPERTY;Property +!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 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_SINGLETABVERTAB;Single Editor Tab Mode, Vertical Tabs +!PREFERENCES_SINGLETAB;Single Editor Tab Mode +!PREFERENCES_SLIMUI;Slim interface +!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_PERFORMANCE;Performance & Quality +!PREFERENCES_TAB_SOUND;Sounds +!PREFERENCES_TIMAX;High +!PREFERENCES_TINB;Number of tiles +!PREFERENCES_TISTD;Standard +!PREFERENCES_TP_LABEL;Tool panel: +!PREFERENCES_TP_USEICONORTEXT;Use tab icons instead of text +!PREFERENCES_TP_VSCROLLBAR;Hide vertical scrollbar +!PREFERENCES_TUNNELMETADATA;Copy IPTC/XMP unchanged to output file (when tagging with other program) +!PREFERENCES_USEBUNDLEDPROFILES;Use bundled profiles +!PREFERENCES_USESYSTEMTHEME;Use system theme +!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_WORKFLOW;Layout +!PROFILEPANEL_COPYPPASTE;Parameters to copy +!PROFILEPANEL_GLOBALPROFILES;Bundled profiles +!PROFILEPANEL_LOADPPASTE;Parameters to load +!PROFILEPANEL_MODE_TIP;Processing profile fill mode.\n\nButton pressed: partial profiles will be converted to full profiles; the missing values will be replaced with hard-coded defaults.\n\nButton released: profiles will be applied as they are, altering only those values which they contain. +!PROFILEPANEL_MYPROFILES;My profiles +!PROFILEPANEL_PASTEPPASTE;Parameters to paste +!PROFILEPANEL_PINTERNAL;Neutral +!PROFILEPANEL_SAVEPPASTE;Parameters to save +!PROGRESSBAR_LOADINGTHUMBS;Loading thumbnails... +!PROGRESSBAR_NOIMAGES;No images found +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing profile saved +!PROGRESSBAR_SNAPSHOT_ADDED;Snapshot added +!PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists +!SAVEDLG_FORCEFORMATOPTS;Force saving options +!SAVEDLG_SUBSAMP;Subsampling +!SAVEDLG_SUBSAMP_1;Best compression +!SAVEDLG_SUBSAMP_2;Balanced +!SAVEDLG_SUBSAMP_3;Best quality +!SAVEDLG_SUBSAMP_TOOLTIP;Best compression: 4:1:1\nBalanced: 4:2:2\nBest quality: 4:4:4 +!SAVEDLG_TIFFUNCOMPRESSED;Uncompressed TIFF +!SAVEDLG_WARNFILENAME;File will be named +!SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. +!THRESHOLDSELECTOR_BL;Bottom-left +!THRESHOLDSELECTOR_BR;Bottom-right +!THRESHOLDSELECTOR_B;Bottom +!THRESHOLDSELECTOR_HINT;Hold the Shift key to move individual control points. +!THRESHOLDSELECTOR_TL;Top-left +!THRESHOLDSELECTOR_TR;Top-right +!THRESHOLDSELECTOR_T;Top +!TP_BWMIX_ALGO;Algorithm OYCPM +!TP_BWMIX_ALGO_LI;Linear +!TP_BWMIX_ALGO_SP;Special effects +!TP_BWMIX_ALGO_TOOLTIP;Linear: will produce a normal linear response.\nSpecial effects: will produce special effects by mixing channels non-linearly. +!TP_BWMIX_AUTOCH;Auto +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing Channel Mixer. +!TP_BWMIX_CC_ENABLED;Adjust complementary color +!TP_BWMIX_CC_TOOLTIP;Enable to allow automatic adjustment of complementary colors in ROYGCBPM mode. +!TP_BWMIX_CHANNEL;Luminance equalizer +!TP_BWMIX_CURVEEDITOR1;'Before' curve +!TP_BWMIX_CURVEEDITOR2;'After' curve +!TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Tone curve, after B&W conversion, at the end of treatment. +!TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Tone curve, just before B&W conversion.\nMay take into account the color components. +!TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H).\nPay attention to extreme values as they may cause artifacts. +!TP_BWMIX_FILTER;Color Filter +!TP_BWMIX_FILTER_BLUEGREEN;Blue-Green +!TP_BWMIX_FILTER_BLUE;Blue +!TP_BWMIX_FILTER_GREENYELLOW;Green-Yellow +!TP_BWMIX_FILTER_GREEN;Green +!TP_BWMIX_FILTER_NONE;None +!TP_BWMIX_FILTER_PURPLE;Purple +!TP_BWMIX_FILTER_REDYELLOW;Red-Yellow +!TP_BWMIX_FILTER_RED;Red +!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. +!TP_BWMIX_FILTER_YELLOW;Yellow +!TP_BWMIX_GAMMA;Gamma Correction +!TP_BWMIX_GAM_TOOLTIP;Correct gamma for each RGB channel. +!TP_BWMIX_LABEL;Black-and-White +!TP_BWMIX_MET;Method +!TP_BWMIX_MET_CHANMIX;Channel Mixer +!TP_BWMIX_MET_DESAT;Desaturation +!TP_BWMIX_MET_LUMEQUAL;Luminance Equalizer +!TP_BWMIX_MIXC;Mixer +!TP_BWMIX_NEUTRAL;Reset mixer +!TP_BWMIX_NEUTRAL_TIP;Reset all values (Color Filter, Channel Mixer) to default. +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all the mixer options.\n"Total" displays the sum of the RGB values:\n- always 100% in relative mode\n- higher (lighter) or lower (darker) than 100% in absolute mode. +!TP_BWMIX_RGB_TOOLTIP;Mix the RGB channels. Use presets for guidance.\nPay attention to negative values that may cause artifacts or erratic behavior. +!TP_BWMIX_SETTING;Presets +!TP_BWMIX_SETTING_TOOLTIP;Different presets (film, landscape, etc.) or manual Channel Mixer settings. +!TP_BWMIX_SET_HIGHCONTAST;High contrast +!TP_BWMIX_SET_HIGHSENSIT;High Sensitivity +!TP_BWMIX_SET_HYPERPANCHRO;Hyper Panchromatic +!TP_BWMIX_SET_INFRARED;Infrared +!TP_BWMIX_SET_LANDSCAPE;Landscape +!TP_BWMIX_SET_LOWSENSIT;Low Sensitivity +!TP_BWMIX_SET_LUMINANCE;Luminance +!TP_BWMIX_SET_NORMCONTAST;Normal Contrast +!TP_BWMIX_SET_ORTHOCHRO;Orthochromatic +!TP_BWMIX_SET_PANCHRO;Panchromatic +!TP_BWMIX_SET_PORTRAIT;Portrait +!TP_BWMIX_SET_RGBABS;Absolute RGB +!TP_BWMIX_SET_RGBREL;Relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Relative ROYGCBPM +!TP_BWMIX_TCMODE_FILMLIKE;B&W Film-like +!TP_BWMIX_TCMODE_SATANDVALBLENDING;B&W Saturation and Value Blending +!TP_BWMIX_TCMODE_STANDARD;B&W Standard +!TP_BWMIX_TCMODE_WEIGHTEDSTD;B&W Weighted Standard +!TP_BWMIX_VAL;L +!TP_CHROMATABERR_LABEL;Chromatic Aberration +!TP_COLORAPP_ADAPTSCENE;Scene luminosity +!TP_COLORAPP_ADAPTSCENE_TOOLTIP;Absolute luminance of the scene environement (cd/m²).\n1) Calculated from the Exif data:\nShutter speed - ISO speed - F number - camera exposure correction.\n2) Calculated from the raw white point and RT's Exposure Compensation slider. +!TP_COLORAPP_ADAPTVIEWING;Viewing luminosity (cd/m²) +!TP_COLORAPP_ADAPTVIEWING_TOOLTIP;Absolute luminance of the viewing environnement\n(usually 16cd/m²). +!TP_COLORAPP_ADAP_AUTO_TOOLTIP;If the checkbox is checked (recommended) RawTherapee calculates an optimum value from Exif data.\nTo set the value manually, uncheck the checkbox first. +!TP_COLORAPP_ALGO;Algorithm +!TP_COLORAPP_ALGO_ALL;All +!TP_COLORAPP_ALGO_JC;Lightness + Chroma (JC) +!TP_COLORAPP_ALGO_JS;Lightness + Saturation (JS) +!TP_COLORAPP_ALGO_QM;Brightness + Colorfulness (QM) +!TP_COLORAPP_ALGO_TOOLTIP;Lets you choose between parameter subsets or all parameters. +!TP_COLORAPP_BADPIXSL;Hot/bad pixel filter +!TP_COLORAPP_BADPIXSL_TOOLTIP;Suppression of hot/bad (brightly colored) pixels.\n0 = No effect\n1 = Median\n2 = Gaussian.\nAlternatively, adjust the image to avoid very dark shadows.\n\nThese artifacts are due to limitations of CIECAM02. +!TP_COLORAPP_BRIGHT;Brightness (Q) +!TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from L*a*b* and RGB brightness. +!TP_COLORAPP_CHROMA;Chroma (C) +!TP_COLORAPP_CHROMA_M;Colorfulnes (M) +!TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM02 differs from L*a*b* and RGB colorfulness. +!TP_COLORAPP_CHROMA_S;Saturation (S) +!TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from L*a*b* and RGB saturation. +!TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from L*a*b* and RGB chroma. +!TP_COLORAPP_CIECAT_DEGREE;CAT02 adaptation +!TP_COLORAPP_CONTRAST;Contrast (J) +!TP_COLORAPP_CONTRAST_Q;Contrast (Q) +!TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrast in CIECAM02 for the Q slider; it differs from L*a*b* and RGB contrast. +!TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from L*a*b* and RGB contrast. +!TP_COLORAPP_CURVEEDITOR1;Tone curve 1 +!TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L* (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of J or Q after CIECAM02.\n\nJ and Q are not shown in the main histogram panel.\n\nFor final output refer to the main histogram panel. +!TP_COLORAPP_CURVEEDITOR2;Tone curve 2 +!TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Same usage as with the second exposure tone curve. +!TP_COLORAPP_CURVEEDITOR3;Color curve +!TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Adjust either chroma, saturation or colorfulness.\n\nShows the histogram of chromaticity (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of C, s or M after CIECAM02.\n\nC, s and M are not shown in the main histogram panel.\nFor final output refer to the main histogram panel. +!TP_COLORAPP_DATACIE;CIECAM02 output histograms in curves +!TP_COLORAPP_DATACIE_TOOLTIP;When enabled, histograms in CIECAM02 curves show approximate values/ranges for J or Q, and C, s or M after the CIECAM02 adjustments.\nThis selection does not impact the main histogram panel.\n\nWhen disabled, histograms in CIECAM02 curves show L*a*b* values before CIECAM02 adjustments. +!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RawTherapee calculates an optimum value, which is then used by CAT02, and also for the entire CIECAM02.\nTo set the value manually, uncheck the check-box first (values above 65 are recommended). +!TP_COLORAPP_DEGREE_TOOLTIP;Amount of CIE Chromatic Adaptation Transform 2002. +!TP_COLORAPP_GAMUT;Gamut control (L*a*b*) +!TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in L*a*b* mode. +!TP_COLORAPP_HUE;Hue (h) +!TP_COLORAPP_HUE_TOOLTIP;Hue (h) - angle between 0° and 360°. +!TP_COLORAPP_LABEL;CIE Color Appearance Model 2002 +!TP_COLORAPP_LABEL_CAM02;Image Adjustments +!TP_COLORAPP_LABEL_SCENE;Scene Conditions +!TP_COLORAPP_LABEL_VIEWING;Viewing Conditions +!TP_COLORAPP_LIGHT;Lightness (J) +!TP_COLORAPP_LIGHT_TOOLTIP;Lightness in CIECAM02 differs from L*a*b* and RGB lightness. +!TP_COLORAPP_MODEL;WP Model +!TP_COLORAPP_MODEL_TOOLTIP;White-Point Model.\n\nWB [RT] + [output]: RT's white balance is used for the scene, CIECAM02 is set to D50, and the output device's white balance is set in Preferences > Color Management.\n\nWB [RT+CAT02] + [output]: RT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences - Color Management. +!TP_COLORAPP_RSTPRO;Red & skin-tones protection +!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin-tones protection affects both sliders and curves. +!TP_COLORAPP_SHARPCIE;--unused-- +!TP_COLORAPP_SHARPCIE_TOOLTIP;--unused-- +!TP_COLORAPP_SURROUND;Surround +!TP_COLORAPP_SURROUND_AVER;Average +!TP_COLORAPP_SURROUND_DARK;Dark +!TP_COLORAPP_SURROUND_DIM;Dim +!TP_COLORAPP_SURROUND_EXDARK;Extremly Dark (Cutsheet) +!TP_COLORAPP_SURROUND_TOOLTIP;Changes tones and colors to take into account the viewing conditions of the output device.\n\nAverage: Average light environment (standard). The image will not change.\n\nDim: Dim environment (TV). The image will become slighty dark.\n\nDark: Dark environment (projector). The image will become more dark.\n\nExtremly Dark: Extremly dark environment (cutsheet). The image will become very dark. +!TP_COLORAPP_SURSOURCE;Dark surround +!TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if image has a dark border. +!TP_COLORAPP_TCMODE_BRIGHTNESS;Brightness +!TP_COLORAPP_TCMODE_CHROMA;Chroma +!TP_COLORAPP_TCMODE_COLORF;Colorfulness +!TP_COLORAPP_TCMODE_LABEL1;Curve mode 1 +!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_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] +!TP_COLORAPP_WBRT;WB [RT] + [output] +!TP_COLORTONING_AB;o C/L +!TP_COLORTONING_AUTOSAT;Automatic +!TP_COLORTONING_BALANCE;Balance +!TP_COLORTONING_BY;o C/L +!TP_COLORTONING_CHROMAC;Opacity +!TP_COLORTONING_COLOR;Color +!TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;Chroma opacity as a function of luminance oC=f(L) +!TP_COLORTONING_HIGHLIGHT;Highlights +!TP_COLORTONING_HUE;Hue +!TP_COLORTONING_LABEL;Color Toning +!TP_COLORTONING_LAB;L*a*b* blending +!TP_COLORTONING_LUMAMODE;Preserve luminance +!TP_COLORTONING_LUMAMODE_TOOLTIP;If enabled, when you change color (red, green, cyan, blue, etc.) the luminance of each pixel is preserved. +!TP_COLORTONING_LUMA;Luminance +!TP_COLORTONING_METHOD;Method +!TP_COLORTONING_METHOD_TOOLTIP;"L*a*b* blending", "RGB sliders" and "RGB curves" use interpolated color blending.\n"Color balance (Shadows/Midtones/Highlights)" and "Saturation 2 colors" use direct colors.\n\nThe Black-and-White tool can be enabled when using any color toning method, which allows for color toning. +!TP_COLORTONING_MIDTONES;Midtones +!TP_COLORTONING_NEUTRAL;Reset sliders +!TP_COLORTONING_NEUTRAL_TIP;Reset all values (Shadows, Midtones, Highlights) to default. +!TP_COLORTONING_OPACITY;Opacity +!TP_COLORTONING_RGBCURVES;RGB - Curves +!TP_COLORTONING_RGBSLIDERS;RGB - Sliders +!TP_COLORTONING_SATURATEDOPACITY;Strength +!TP_COLORTONING_SATURATIONTHRESHOLD;Threshold +!TP_COLORTONING_SA;Saturation Protection +!TP_COLORTONING_SHADOWS;Shadows +!TP_COLORTONING_SPLITCOCO;Color Balance Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITCO;Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITLR;Saturation 2 colors +!TP_COLORTONING_STRENGTH;Strength +!TP_COLORTONING_STR;Strength +!TP_COLORTONING_TWO2;Special chroma '2 colors' +!TP_COLORTONING_TWOALL;Special chroma +!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_GTFRAME;Frame +!TP_CROP_GTGRID;Grid +!TP_CROP_GTHARMMEANS;Harmonic Means +!TP_CROP_GTTRIANGLE1;Golden Triangles 1 +!TP_CROP_GTTRIANGLE2;Golden Triangles 2 +!TP_CROP_PPI;PPI= +!TP_DARKFRAME_AUTOSELECT;Auto-selection +!TP_DARKFRAME_LABEL;Dark-Frame +!TP_DEFRINGE_LABEL;Defringe +!TP_DEFRINGE_RADIUS;Radius +!TP_DEFRINGE_THRESHOLD;Threshold +!TP_DIRPYRDENOISE_33;3×3 strong +!TP_DIRPYRDENOISE_55SOFT;5×5 +!TP_DIRPYRDENOISE_55;5×5 strong +!TP_DIRPYRDENOISE_77;7×7 (slow) +!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_ABM;Chroma only +!TP_DIRPYRDENOISE_AUTO;Automatic global +!TP_DIRPYRDENOISE_AUTO_TOOLTIP;Try to evaluate chroma noise\nBe careful, this calculation is average, and is quite subjective ! +!TP_DIRPYRDENOISE_AUT;Automatic global +!TP_DIRPYRDENOISE_BLUE;Chrominance - Blue-Yellow +!TP_DIRPYRDENOISE_C2TYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CCCURVE;Chrominance curve +!TP_DIRPYRDENOISE_CHROMAFR;Chrominance +!TP_DIRPYRDENOISE_CHROMA;Chrominance - Master +!TP_DIRPYRDENOISE_CTYPE;Auto method +!TP_DIRPYRDENOISE_CTYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nAutomatic multi-zones\nNo preview - works only during saving, but using the "Preview" method by matching the tile size and center to the preview size and center you can get an idea of the expected results.\nThe image is divided into tiles (about 10 to 70 depending on image size) and each tile receives its own chrominance noise reduction settings.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CURVEEDITOR_CC;Chroma +!TP_DIRPYRDENOISE_CURVEEDITOR_CC_TOOLTIP;Increase (multiply) the value of all chrominance sliders.\nThis curve lets you adjust the strength of chromatic noise reduction as a function of chromaticity, for instance to increase the action in areas of low saturation and to decrease it in those of high saturation. +!TP_DIRPYRDENOISE_CURVEEDITOR_L_TOOLTIP;Modulates action of 'Luminance' denoise +!TP_DIRPYRDENOISE_CUR;Curve +!TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on the gamma of the input color profile. An sRGB gamma is assumed, thus if the image uses an input color profile of a different gamma, the effects of luminance noise reduction will differ. +!TP_DIRPYRDENOISE_ENH;Enhanced mode +!TP_DIRPYRDENOISE_ENH_TOOLTIP;Increases noise reduction quality at the expense of a 20% processing time increase. +!TP_DIRPYRDENOISE_GAMMA;Gamma +!TP_DIRPYRDENOISE_GAMMA_TOOLTIP;Gamma varies noise reduction strength across the range of tones. Smaller values will target shadows, while larger values will stretch the effect to the brighter tones. +!TP_DIRPYRDENOISE_LABEL;Noise Reduction +!TP_DIRPYRDENOISE_LABM;L*a*b* +!TP_DIRPYRDENOISE_LAB;L*a*b* +!TP_DIRPYRDENOISE_LCURVE;Luminance curve +!TP_DIRPYRDENOISE_LDETAIL;Luminance - Detail +!TP_DIRPYRDENOISE_LM;Luminance only +!TP_DIRPYRDENOISE_LPLABM;Weighted L* (little) + a*b* (normal) +!TP_DIRPYRDENOISE_LTYPE;Luminance control +!TP_DIRPYRDENOISE_LUMAFR;Luminance +!TP_DIRPYRDENOISE_LUMAFR_TOOLTIP;Wavelet on luminance and Fourier transform for luminance detail +!TP_DIRPYRDENOISE_LUMA;Luminance +!TP_DIRPYRDENOISE_MANU;Manual +!TP_DIRPYRDENOISE_MAN;Manual +!TP_DIRPYRDENOISE_MEDMETHOD;Median method +!TP_DIRPYRDENOISE_MEDTYPE;Median type +!TP_DIRPYRDENOISE_MED;Median Filter +!TP_DIRPYRDENOISE_MED_TOOLTIP;Enabled median denoising +!TP_DIRPYRDENOISE_METHOD11;Quality +!TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. +!TP_DIRPYRDENOISE_METHOD;Method +!TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or L*a*b* methods can be used.\n\nFor non-raw images the L*a*b* method will be used, regardless of the selection. +!TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - +!TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 +!TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. +!TP_DIRPYRDENOISE_PASSES;Median iterations +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PON;Auto multi-zones +!TP_DIRPYRDENOISE_PREVLABEL;Preview size=%1, Center: Px=%2 Py=%3 +!TP_DIRPYRDENOISE_PREV;Preview +!TP_DIRPYRDENOISE_PRE;Preview multi-zones +!TP_DIRPYRDENOISE_RED;Chrominance - Red-Green +!TP_DIRPYRDENOISE_RGBM;RGB +!TP_DIRPYRDENOISE_RGB;RGB +!TP_DIRPYRDENOISE_SHALBI;High +!TP_DIRPYRDENOISE_SHAL;Standard +!TP_DIRPYRDENOISE_SLI;Slider +!TP_DIRPYRDENOISE_SOFT;3x3 +!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_LUMAFINEST;Finest +!TP_DIRPYREQUALIZER_LUMANEUTRAL;Neutral +!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_THRESHOLD;Threshold +!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;Auto Distortion Correction +!TP_DISTORTION_AUTO_TIP;Correct lens distortion automatically for some cameras (Micro 4/3, some compact digital cameras, etc.). +!TP_EPD_EDGESTOPPING;Edge stopping +!TP_EPD_GAMMA;Gamma +!TP_EPD_LABEL;Tone Mapping +!TP_EPD_REWEIGHTINGITERATES;Reweighting iterates +!TP_EPD_SCALE;Scale +!TP_EPD_STRENGTH;Strength +!TP_EPD_TOOLTIP;Tone mapping is possible in L*a*b* mode (standard) and CIECAM02 mode.\n\nWhen in L*a*b* mode, tone mapping can also be used on the residual image of the Wavelet Levels tool.\n\nTo engage CIECAM02 tone mapping mode enable the following settings:\n1. CIECAM02\n2. Algorithm="Brightness + Colorfulness (QM)"\n3. "Tone mapping using CIECAM02 brightness (Q)" +!TP_EXPOSURE_AUTOLEVELS_TIP;Toggles execution of Auto Levels to automatically set Exposure slider values based on an image analysis.\nEnables Highlight Reconstruction if necessary. +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in Auto Levels operation. +!TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Highlight compression threshold +!TP_EXPOSURE_CURVEEDITOR1;Tone curve 1 +!TP_EXPOSURE_CURVEEDITOR2;Tone curve 2 +!TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Please refer to the "Exposure > Tone Curves" RawPedia article to learn how to achieve the best results by using two tone curves. +!TP_EXPOSURE_SATURATION;Saturation +!TP_EXPOSURE_TCMODE_FILMLIKE;Film-like +!TP_EXPOSURE_TCMODE_LABEL1;Curve mode 1 +!TP_EXPOSURE_TCMODE_LABEL2;Curve mode 2 +!TP_EXPOSURE_TCMODE_LUMINANCE;Luminance +!TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Saturation and Value Blending +!TP_EXPOSURE_TCMODE_STANDARD;Standard +!TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard +!TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points +!TP_EXPOS_WHITEPOINT_LABEL;Raw White Points +!TP_FILMSIMULATION_LABEL;Film Simulation +!TP_FILMSIMULATION_STRENGTH;Strength +!TP_FILMSIMULATION_ZEROCLUTSFOUND;Set HaldCLUT directory in Preferences +!TP_FLATFIELD_AUTOSELECT;Auto-selection +!TP_FLATFIELD_BLURRADIUS;Blur radius +!TP_FLATFIELD_BLURTYPE;Blur type +!TP_FLATFIELD_BT_AREA;Area +!TP_FLATFIELD_BT_HORIZONTAL;Horizontal +!TP_FLATFIELD_BT_VERTHORIZ;Vertical + Horizontal +!TP_FLATFIELD_BT_VERTICAL;Vertical +!TP_FLATFIELD_CLIPCONTROL;Clip control +!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. +!TP_FLATFIELD_LABEL;Flat-Field +!TP_GAMMA_CURV;Gamma +!TP_GAMMA_FREE;Free gamma +!TP_GAMMA_OUTPUT;Output gamma +!TP_GAMMA_SLOP;Slope (linear) +!TP_GENERAL_11SCALE_TOOLTIP;The effects of this tool are only visible or only accurate at a preview scale of 1:1. +!TP_GRADIENT_CENTER;Center +!TP_GRADIENT_CENTER_X;Center X +!TP_GRADIENT_CENTER_X_TOOLTIP;Shift gradient to the left (negative values) or right (positive values). +!TP_GRADIENT_CENTER_Y;Center Y +!TP_GRADIENT_CENTER_Y_TOOLTIP;Shift gradient up (negative values) or down (positive values). +!TP_GRADIENT_DEGREE;Angle +!TP_GRADIENT_DEGREE_TOOLTIP;Rotation angle in degrees. +!TP_GRADIENT_FEATHER;Feather +!TP_GRADIENT_FEATHER_TOOLTIP;Gradient width in percent of the image diagonal. +!TP_GRADIENT_LABEL;Graduated Filter +!TP_GRADIENT_STRENGTH;Strength +!TP_GRADIENT_STRENGTH_TOOLTIP;Filter strength in stops. +!TP_HLREC_BLEND;Blend +!TP_HLREC_ENA_TOOLTIP;Could be activated by Auto Levels. +!TP_HSVEQUALIZER_CHANNEL;Channel +!TP_HSVEQUALIZER_HUE;H +!TP_HSVEQUALIZER_LABEL;HSV Equalizer +!TP_HSVEQUALIZER_SAT;S +!TP_HSVEQUALIZER_VAL;V +!TP_ICM_BLENDCMSMATRIX;Blend ICC highlights with matrix +!TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover clipped highlights when using LUT-based ICC profiles. +!TP_ICM_DCPILLUMINANT;Illuminant +!TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolated +!TP_ICM_DCPILLUMINANT_TOOLTIP;Select which embedded DCP illuminant to employ. Default is "interpolated" which is a mix between the two based on white balance. The setting is only enabled if a Dual-Illuminant DCP with interpolation support is selected. +!TP_ICM_INPUTCAMERAICC;Auto-matched camera profile +!TP_ICM_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input color profiles. These profiles are more precise than simpler matrix ones. They are not available for all cameras. These profiles are stored in the /iccprofiles/input and /dcpprofiles folders and are automatically retrieved based on a file name matching to the exact model name of the camera. +!TP_ICM_INPUTCAMERA_TOOLTIP;Use a simple color matrix from dcraw, an enhanced RawTherapee version (whichever is available based on camera model) or one embedded in the DNG. +!TP_ICM_INPUTCUSTOM_TOOLTIP;Select your own DCP/ICC color profile file for the camera. +!TP_ICM_INPUTEMBEDDED_TOOLTIP;Use color profile embedded in non-raw files. +!TP_ICM_INPUTNONE;No profile +!TP_ICM_INPUTNONE_TOOLTIP;Use no input color profile at all.\nUse only in special cases. +!TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance +!TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. The result can be used for calibration purposes and generation of a camera profile. +!TP_ICM_TONECURVE;Use DCP's tone curve +!TP_ICM_TONECURVE_TOOLTIP;Employ the embedded DCP tone curve. The setting is only enabled if the selected DCP has a tone curve. +!TP_IMPULSEDENOISE_LABEL;Impulse Noise Reduction +!TP_IMPULSEDENOISE_THRESH;Threshold +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid color shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction. +!TP_LABCURVE_BRIGHTNESS;Lightness +!TP_LABCURVE_CHROMATICITY;Chromaticity +!TP_LABCURVE_CHROMA_TOOLTIP;To apply B&W toning, set Chromaticity to -100. +!TP_LABCURVE_CONTRAST;Contrast +!TP_LABCURVE_CURVEEDITOR;Luminance Curve +!TP_LABCURVE_CURVEEDITOR_A_RANGE1;Green Saturated +!TP_LABCURVE_CURVEEDITOR_A_RANGE2;Green Pastel +!TP_LABCURVE_CURVEEDITOR_A_RANGE3;Red Pastel +!TP_LABCURVE_CURVEEDITOR_A_RANGE4;Red Saturated +!TP_LABCURVE_CURVEEDITOR_B_RANGE1;Blue Saturated +!TP_LABCURVE_CURVEEDITOR_B_RANGE2;Blue Pastel +!TP_LABCURVE_CURVEEDITOR_B_RANGE3;Yellow Pastel +!TP_LABCURVE_CURVEEDITOR_B_RANGE4;Yellow Saturated +!TP_LABCURVE_CURVEEDITOR_CC;CC +!TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutral +!TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Dull +!TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastel +!TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Saturated +!TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Chromaticity according to chromaticity C=f(C) +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to hue C=f(H) +!TP_LABCURVE_CURVEEDITOR_CL;CL +!TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Chromaticity according to luminance C=f(L) +!TP_LABCURVE_CURVEEDITOR_HH;HH +!TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Hue according to hue H=f(H) +!TP_LABCURVE_CURVEEDITOR_LC;LC +!TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminance according to chromaticity L=f(C) +!TP_LABCURVE_CURVEEDITOR_LH;LH +!TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H) +!TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminance according to luminance L=f(L) +!TP_LABCURVE_LABEL;L*a*b* Adjustments +!TP_LABCURVE_LCREDSK;Restrict LC to red and skin-tones +!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_LENSGEOM_AUTOCROP;Auto-Crop +!TP_LENSGEOM_FILL;Auto-fill +!TP_LENSGEOM_LABEL;Lens / Geometry +!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_USECA;Chromatic aberration correction +!TP_LENSPROFILE_USEDIST;Distortion correction +!TP_LENSPROFILE_USEVIGN;Vignetting correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Resets exposure sliders to neutral values.\nApplies to the same controls that Auto Levels applies to, regardless of whether you used Auto Levels or not. +!TP_PCVIGNETTE_FEATHER;Feather +!TP_PCVIGNETTE_FEATHER_TOOLTIP;Feathering:\n0 = corners only,\n50 = halfway to center,\n100 = to center. +!TP_PCVIGNETTE_LABEL;Vignette Filter +!TP_PCVIGNETTE_ROUNDNESS;Roundness +!TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness:\n0 = rectangle,\n50 = fitted ellipse,\n100 = circle. +!TP_PCVIGNETTE_STRENGTH;Strength +!TP_PCVIGNETTE_STRENGTH_TOOLTIP;Filter strength in stops (reached in corners). +!TP_PERSPECTIVE_HORIZONTAL;Horizontal +!TP_PERSPECTIVE_LABEL;Perspective +!TP_PERSPECTIVE_VERTICAL;Vertical +!TP_PFCURVE_CURVEEDITOR_CH;Hue +!TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Controls defringe strength by color.\nHigher = more,\nLower = less. +!TP_PREPROCESS_DEADPIXFILT;Dead pixel filter +!TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Tries to suppress dead pixels. +!TP_PREPROCESS_GREENEQUIL;Green equilibration +!TP_PREPROCESS_HOTPIXFILT;Hot pixel filter +!TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Tries to suppress hot pixels. +!TP_PREPROCESS_LABEL;Preprocessing +!TP_PREPROCESS_LINEDENOISE;Line noise filter +!TP_PREPROCESS_NO_FOUND;None found +!TP_RAWCACORR_AUTO;Auto-correction +!TP_RAWCACORR_CABLUE;Blue +!TP_RAWCACORR_CARED;Red +!TP_RAWEXPOS_BLACKS;Black Levels +!TP_RAWEXPOS_BLACK_0;Green 1 (lead) +!TP_RAWEXPOS_BLACK_1;Red +!TP_RAWEXPOS_BLACK_2;Blue +!TP_RAWEXPOS_BLACK_3;Green 2 +!TP_RAWEXPOS_BLACK_BLUE;Blue +!TP_RAWEXPOS_BLACK_GREEN;Green +!TP_RAWEXPOS_BLACK_RED;Red +!TP_RAWEXPOS_LINEAR;White-point correction +!TP_RAWEXPOS_PRESER;Highlight preservation +!TP_RAWEXPOS_RGB;Red, Green, Blue +!TP_RAWEXPOS_TWOGREEN;Link greens +!TP_RAW_DCBENHANCE;DCB enhancement +!TP_RAW_DCBITERATIONS;Number of DCB iterations +!TP_RAW_DMETHOD_PROGRESSBAR;%1 demosaicing... +!TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Demosaicing refinement... +!TP_RAW_DMETHOD_TOOLTIP;Note: IGV and LMMSE are dedicated to high ISO images to aid in noise reduction without leading to maze patterns, posterization or a washed-out look. +!TP_RAW_HD;Threshold +!TP_RAW_HD_TOOLTIP;Lower values make hot/dead pixel detection more aggressive, but false positives may lead to artifacts. If you notice any artifacts appearing when enabling the Hot/Dead Pixel Filters, gradually increase the threshold value until they disappear. +!TP_RAW_LABEL;Demosaicing +!TP_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!TP_RAW_LMMSE_TOOLTIP;Adds gamma (step 1), median (steps 2-4) and refinement (steps 5-6) to reduce artifacts and improve the signal-to-noise ratio. +!TP_RAW_SENSOR_BAYER_LABEL;Sensor with Bayer Matrix +!TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;3-pass gives best results (recommended for low ISO images).\n1-pass is almost undistinguishable from 3-pass for high ISO images and is faster. +!TP_RAW_SENSOR_XTRANS_LABEL;Sensor with X-Trans Matrix +!TP_RESIZE_APPLIESTO;Applies to: +!TP_RESIZE_CROPPEDAREA;Cropped Area +!TP_RESIZE_FITBOX;Bounding Box +!TP_RESIZE_FULLIMAGE;Full Image +!TP_RESIZE_HEIGHT;Height +!TP_RESIZE_LANCZOS;Lanczos +!TP_RESIZE_SPECIFY;Specify: +!TP_RESIZE_WIDTH;Width +!TP_RGBCURVES_BLUE;B +!TP_RGBCURVES_CHANNEL;Channel +!TP_RGBCURVES_GREEN;G +!TP_RGBCURVES_LABEL;RGB Curves +!TP_RGBCURVES_LUMAMODE;Luminosity mode +!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_RGBCURVES_RED;R +!TP_SAVEDIALOG_OK_TIP;Shortcut: Ctrl-Enter +!TP_SHADOWSHLIGHTS_SHARPMASK;Sharp mask +!TP_SHARPENEDGE_AMOUNT;Quantity +!TP_SHARPENEDGE_LABEL;Edges +!TP_SHARPENEDGE_PASSES;Iterations +!TP_SHARPENEDGE_THREE;Luminance only +!TP_SHARPENING_TOOLTIP;Expect a slightly different effect when using with CIECAM02. If difference is observed, adjust to taste. +!TP_SHARPENMICRO_AMOUNT;Quantity +!TP_SHARPENMICRO_LABEL;Microcontrast +!TP_SHARPENMICRO_MATRIX;3×3 matrix instead of 5×5 +!TP_SHARPENMICRO_UNIFORMITY;Uniformity +!TP_VIBRANCE_AVOIDCOLORSHIFT;Avoid color shift +!TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Red/Purple +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Red +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Red/Yellow +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Yellow +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Hue according to hue H=f(H) +!TP_VIBRANCE_LABEL;Vibrance +!TP_VIBRANCE_PASTELS;Pastel Tones +!TP_VIBRANCE_PASTSATTOG;Link pastel and saturated tones +!TP_VIBRANCE_PROTECTSKINS;Protect skin-tones +!TP_VIBRANCE_PSTHRESHOLD;Pastel/saturated tones threshold +!TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Saturation threshold +!TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;The vertical axis represents pastel tones at the bottom and saturated tones at the top.\nThe horizontal axis represents the saturation range. +!TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Pastel/saturated transition's weighting +!TP_VIBRANCE_SATURATED;Saturated Tones +!TP_VIGNETTING_CENTER;Center +!TP_VIGNETTING_CENTER_X;Center X +!TP_VIGNETTING_CENTER_Y;Center Y +!TP_VIGNETTING_STRENGTH;Strength +!TP_WAVELET_1;Level 1 +!TP_WAVELET_2;Level 2 +!TP_WAVELET_3;Level 3 +!TP_WAVELET_4;Level 4 +!TP_WAVELET_5;Level 5 +!TP_WAVELET_6;Level 6 +!TP_WAVELET_7;Level 7 +!TP_WAVELET_8;Level 8 +!TP_WAVELET_9;Level 9 +!TP_WAVELET_ALL;All levels in all directions +!TP_WAVELET_APPLYTO;Apply To +!TP_WAVELET_AVOID;Avoid color shift +!TP_WAVELET_B0;Black +!TP_WAVELET_B1;Grey +!TP_WAVELET_B2;Residual +!TP_WAVELET_BACUR;Curve +!TP_WAVELET_BALANCE;Contrast balance d/v-h +!TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chromaticity or residual tone mapping are activated, the effect due to balance is amplified. +!TP_WAVELET_BALCHRO;Chroma balance +!TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chromaticity balance. +!TP_WAVELET_BANONE;None +!TP_WAVELET_BASLI;Slider +!TP_WAVELET_BATYPE;Contrast balance method +!TP_WAVELET_CCURVE;Local contrast +!TP_WAVELET_CH1;Whole chromaticity range +!TP_WAVELET_CH2;Saturated/pastel +!TP_WAVELET_CH3;Link contrast levels +!TP_WAVELET_CHCU;Curve +!TP_WAVELET_CHRO;Saturated/pastel threshold +!TP_WAVELET_CHRO_TOOLTIP;Sets the wavelet level which will be the threshold between saturated and pastel colors.\n1-x: saturated\nx-9: pastel\n\nIf the value exceeds the amount of wavelet levels you are using then it will be ignored. +!TP_WAVELET_CHR;Chroma-contrast link strength +!TP_WAVELET_CHR_TOOLTIP;Adjusts chromaticity as a function of "contrast levels" and "chroma-contrast link strength" +!TP_WAVELET_CHSL;Sliders +!TP_WAVELET_CHTYPE;Chrominance method +!TP_WAVELET_COLORT;Opacity Red-Green +!TP_WAVELET_COMBOTH;Both +!TP_WAVELET_COMPCONT;Contrast +!TP_WAVELET_COMPGAMMA;Compression gamma +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjusting the gamma of the residual image allow you to equilibrate the data and histogram. +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjust gamma for residual image and compression.\nAllow to equilibrate data and histogram +!TP_WAVELET_COMPTM;Tone mapping +!TP_WAVELET_CONTEDIT;'After' Contrast curve +!TP_WAVELET_CONTEDIT;'After' contrast curve +!TP_WAVELET_CONTRAST_MINUS;Contrast - +!TP_WAVELET_CONTRAST_PLUS;Contrast + +!TP_WAVELET_CONTRA;Contrast +!TP_WAVELET_CONTRA_TOOLTIP;Changes contrast of the residual image. +!TP_WAVELET_CONTR;Gamut +!TP_WAVELET_CTYPE;Chrominance control +!TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modifies local contrast as a function of the original local contrast (absciss)\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 100..300)\n66% absciss represents standard deviation of local contrast (real value about 300..800)\n100% represents maximum (real value about 3000..8000) +!TP_WAVELET_CURVEEDITOR_CH;Contrast levels=f(Hue) +!TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modifies each level's contrast as a function oh hue.\nTake care not to overwrite changes made with the Gamut Hue controls.\nThe curve will only have an effect when wavelet contrast level sliders are non-zero. +!TP_WAVELET_CURVEEDITOR_CL;L +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Applies a final contrast luminance curve at the end of the wavelet treatment. +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Apply a contrast luminance curve at the end of wavelet level threatment +!TP_WAVELET_CURVEEDITOR_HH;HH +!TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modifies the residual image's hue as a function of hue. +!TP_WAVELET_DALL;All directions +!TP_WAVELET_DAUB;Edge performance +!TP_WAVELET_DAUB_TOOLTIP;Changes Daubechies coefficients:\nD4 = Standard,\nD14 = Often best performance, 10% more time-intensive.\n\nAffects edge detection as well as the general quality of the firsts levels. However the quality is not strictly related to this coefficient and can vary with images and uses. +!TP_WAVELET_DISP;Preview Settings +!TP_WAVELET_DONE;Vertical +!TP_WAVELET_DTHR;Diagonal +!TP_WAVELET_DTWO;Horizontal +!TP_WAVELET_EDCU;Curve +!TP_WAVELET_EDGCONT;Local contrast +!TP_WAVELET_EDGCONT_TOOLTIP;Adjusting the points to the left decreases contrast, and to the right increases it.\nBottom-left, Top-Left, Top-Right, Bottom-right represent respectively local contast for low values, mean, mean+stdev, maxima +!TP_WAVELET_EDGEDETECTTHR2;Threshold high (detection) +!TP_WAVELET_EDGEDETECTTHR;Threshold low (noise) +!TP_WAVELET_EDGEDETECTTHR_TOOLTIP;This adjuster lets you target edge detection for example to avoid applying edge sharpness to fine details, such as noise in the sky. +!TP_WAVELET_EDGEDETECT;Gradient sensitivity +!TP_WAVELET_EDGEDETECT_TOOLTIP;Moving the slider to the right increases edge sensitivity. This affects local contrast, edge settings and noise. +!TP_WAVELET_EDGE;Edge Sharpness +!TP_WAVELET_EDGREINF_TOOLTIP;Reinforce or reduce the action of the first level, do the opposite to the second level, and leave the rest unchanged. +!TP_WAVELET_EDGTHRESH;Detail +!TP_WAVELET_EDGTHRESH_TOOLTIP;Change the repartition between the first levels and the others. The higher the threshold the more the action is centred on the first levels. Be careful with negative values, they increase the action of high levels and can introduce artifacts. +!TP_WAVELET_EDRAD;Radius +!TP_WAVELET_EDRAD_TOOLTIP;This radius adjustment is very different from those in other sharpening tools. Its value is compared to each level through a complex function. In this sense, a value of zero still has an effect. +!TP_WAVELET_EDSL;Threshold Sliders +!TP_WAVELET_EDTYPE;Local contrast method +!TP_WAVELET_EDVAL;Strength +!TP_WAVELET_FINAL;Final Touchup +!TP_WAVELET_FINEST;Finest +!TP_WAVELET_HIGHLIGHT;Highlight luminance range +!TP_WAVELET_HS1;Whole luminance range +!TP_WAVELET_HS2;Shadows/Highlights +!TP_WAVELET_HUESKIN;Skin hue +!TP_WAVELET_HUESKIN_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_HUESKY;Sky hue +!TP_WAVELET_HUESKY_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_INF;Below or equal the level +!TP_WAVELET_ITER;Delta balance levels +!TP_WAVELET_ITER_TOOLTIP;Left: increase low levels and reduce high levels,\nRight: reduce low levels and increase high levels. +!TP_WAVELET_LABEL;Wavelet levels +!TP_WAVELET_LARGEST;Coarsest +!TP_WAVELET_LEVCH;Chromaticity +!TP_WAVELET_LEVELS;Wavelet levels +!TP_WAVELET_LEVELS_TOOLTIP;Choose the number of detail levels the image is to be decomposed into. More levels require more RAM and require a longer processing time. +!TP_WAVELET_LEVF;Contrast +!TP_WAVELET_LEVLABEL;Preview maximum possible levels = %1 +!TP_WAVELET_LEVONE;Level 2 +!TP_WAVELET_LEVTWO;Level 3 +!TP_WAVELET_LEVZERO;Level 1 +!TP_WAVELET_LINKEDG;Link with Edge Sharpness' Strength +!TP_WAVELET_LIPST;Enhanced algorithm +!TP_WAVELET_LIPST_TOOLTIP;This algorithm uses Lipschitz regularity to increase edge detection quality at a cost of increased processing time and memory requirements. +!TP_WAVELET_LOWLIGHT;Shadow luminance range +!TP_WAVELET_MEDGREINF;First level +!TP_WAVELET_MEDILEV;Edge detection +!TP_WAVELET_MEDI;Reduce artifacts in blue sky +!TP_WAVELET_NEUTRAL;Neutral +!TP_WAVELET_NOISE;Denoise and Refine +!TP_WAVELET_NOIS;Denoise +!TP_WAVELET_ONE;One level +!TP_WAVELET_OPACITYWL;Final local contrast +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify final local contrast in function of last local contrast (absciss) for all levels decomposition\nTake into account: \na)contrast levels \nb)edge sharpness \nc)contrast balance\nd)decomposition-recomposition\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 200..1000)\n66% absciss represents standard deviation of local contrast (real value about 1000..2000)\n100% represents maximum (real value about 5000..13000) +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify the final local contrast at the end of the wavelet treatment.\n\nThe left side represents the smallest local contrast, progressing to the largest local contrast on the right. +!TP_WAVELET_OPACITYW;Contrast balance d/v-h curve +!TP_WAVELET_OPACITY;Opacity Blue-Yellow +!TP_WAVELET_PASTEL;Pastel chromaticity +!TP_WAVELET_PREVIEWBACK;Background +!TP_WAVELET_PREVIEWLEVELS;Preview +!TP_WAVELET_RE1;Reinforced +!TP_WAVELET_RE2;Unchanged +!TP_WAVELET_RE3;Reduced +!TP_WAVELET_RESCHRO;Chromaticity +!TP_WAVELET_RESCONH;Highlights +!TP_WAVELET_RESCON;Shadows +!TP_WAVELET_RESID;Residual image +!TP_WAVELET_SAT;Saturated chromaticity +!TP_WAVELET_SETTINGS;Wavelet Settings +!TP_WAVELET_SKIN;Skin targetting/protection +!TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected. +!TP_WAVELET_SKY;Sky targetting/protection +!TP_WAVELET_SKY_TOOLTIP;At -100 sky-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 sky-tones are protected while all other tones are affected. +!TP_WAVELET_STRENGTH;Strength +!TP_WAVELET_STREN;Strength +!TP_WAVELET_SUPE;Extra +!TP_WAVELET_SUP;Above the level +!TP_WAVELET_THRESHOLD2;Shadow levels +!TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels between 9 and 9 minus the value will be affected by the shadow luminance range. Other levels will be fully treated. The highest level possible is limited by the highlight level value (9 minus highlight level value). +!TP_WAVELET_THRESHOLD;Highlight levels +!TP_WAVELET_THRESHOLD_TOOLTIP;Only levels beyond the chosen value will be affected by the highlight luminance range. Other levels will be fully treated. The chosen value here limits the highest possible value of the shadow levels. +!TP_WAVELET_THRH;Highlights threshold +!TP_WAVELET_THR;Shadows threshold +!TP_WAVELET_TILESBIG;Big tiles +!TP_WAVELET_TILESFULL;Full image +!TP_WAVELET_TILESIZE;Tiling method +!TP_WAVELET_TILESLIT;Little tiles +!TP_WAVELET_TILES_TOOLTIP;Processing the full image leads to better quality and is the recommended option, while using tiles is a fall-back solution for users with little RAM. Refer to RawPedia for memory requirements. +!TP_WAVELET_TMHIGH;High +!TP_WAVELET_TMLOWHIGH;Low+High +!TP_WAVELET_TMNONE;None +!TP_WAVELET_TMSTD;Standard +!TP_WAVELET_TMSTRENGTH;Compression strength +!TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image. When the value is different from 0, the Strength and Gamma sliders of the Tone Mapping tool in the Exposure tab will become grayed out. +!TP_WAVELET_TMTYPE;Compression method +!TP_WAVELET_TON;Toning +!TP_WAVELET_daub2;D2 - low +!TP_WAVELET_daub4;D4 - standard +!TP_WAVELET_daub6;D6 - standard plus +!TP_WAVELET_daub10;D10 - medium +!TP_WAVELET_daub14;D14 - high +!TP_WBALANCE_CLOUDY;Cloudy +!TP_WBALANCE_DAYLIGHT;Daylight (sunny) +!TP_WBALANCE_EQBLUERED;Blue/Red equalizer +!TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behavior of "white balance" by modulating the blue/red balance.\nThis can be useful when shooting conditions:\na) are far from the standard illuminant (e.g. underwater),\nb) are far from conditions where calibrations were performed,\nc) where the matrices or ICC profiles are unsuitable. +!TP_WBALANCE_FLASH55;Leica +!TP_WBALANCE_FLASH60;Standard, Canon, Pentax, Olympus +!TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta +!TP_WBALANCE_FLASH_HEADER;Flash +!TP_WBALANCE_FLUO1;F1 - Daylight +!TP_WBALANCE_FLUO2;F2 - Cool White +!TP_WBALANCE_FLUO3;F3 - White +!TP_WBALANCE_FLUO4;F4 - Warm White +!TP_WBALANCE_FLUO5;F5 - Daylight +!TP_WBALANCE_FLUO6;F6 - Lite White +!TP_WBALANCE_FLUO7;F7 - D65 Daylight Simulator +!TP_WBALANCE_FLUO8;F8 - D50 / Sylvania F40 Design +!TP_WBALANCE_FLUO9;F9 - Cool White Deluxe +!TP_WBALANCE_FLUO10;F10 - Philips TL85 +!TP_WBALANCE_FLUO11;F11 - Philips TL84 +!TP_WBALANCE_FLUO12;F12 - Philips TL83 +!TP_WBALANCE_FLUO_HEADER;Fluorescent +!TP_WBALANCE_GTI;GTI +!TP_WBALANCE_HMI;HMI +!TP_WBALANCE_JUDGEIII;JudgeIII +!TP_WBALANCE_LAMP_HEADER;Lamp +!TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 +!TP_WBALANCE_LED_HEADER;LED +!TP_WBALANCE_LED_LSI;LSI Lumelex 2040 +!TP_WBALANCE_SHADE;Shade +!TP_WBALANCE_SOLUX35;Solux 3500K +!TP_WBALANCE_SOLUX41;Solux 4100K +!TP_WBALANCE_SOLUX47;Solux 4700K (vendor) +!TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) +!TP_WBALANCE_TUNGSTEN;Tungsten +!TP_WBALANCE_WATER1;UnderWater 1 +!TP_WBALANCE_WATER2;UnderWater 2 +!TP_WBALANCE_WATER_HEADER;UnderWater +!ZOOMPANEL_100;(100%) +!ZOOMPANEL_NEWCROPWINDOW;Open (new) detail window +!ZOOMPANEL_ZOOM100;Zoom to 100%\nShortcut: z +!ZOOMPANEL_ZOOMFITCROPSCREEN;Fit crop to screen\nShortcut: Alt-f +!ZOOMPANEL_ZOOMFITSCREEN;Fit whole image to screen\nShortcut: f +!ZOOMPANEL_ZOOMIN;Zoom In\nShortcut: + +!ZOOMPANEL_ZOOMOUT;Zoom Out\nShortcut: - diff --git a/rtdata/languages/Polish b/rtdata/languages/Polish new file mode 100644 index 000000000..1393c2aa7 --- /dev/null +++ b/rtdata/languages/Polish @@ -0,0 +1,1876 @@ +#01 2007-12-24 Mateusz Ludwin +#02 2010-01-08 Bartosz "Simek" Kaszubowski +#03 2011-09-06 Dariusz 'Salvadhor' Duma +#04 2011-11-30 DrSlony +#05 2012-01-14 DrSlony +#06 2012-01-30 DrSlony +#07 2012-04-02 DrSlony +#08 2013-05-21 DrSlony +#09 2014-10-16 DrSlony + +ABOUT_TAB_BUILD;Wersja +ABOUT_TAB_CREDITS;Zasługi +ABOUT_TAB_LICENSE;Licencja +ABOUT_TAB_RELEASENOTES;Notatki eksploatacyjne +ABOUT_TAB_SPLASH;Ekran powitalny +ADJUSTER_RESET_TO_DEFAULT;Przywróć domyślne +BATCHQUEUE_AUTOSTART;Autostart +BATCHQUEUE_DESTFILENAME;Ścieżka i nazwa pliku +BATCH_PROCESSING;Przetwarzanie wsadowe +CURVEEDITOR_CURVES;Krzywe +CURVEEDITOR_CURVE;Krzywa +CURVEEDITOR_CUSTOM;Własna +CURVEEDITOR_DARKS;Ciemne +CURVEEDITOR_HIGHLIGHTS;Najjaśniejsze +CURVEEDITOR_LIGHTS;Jasne +CURVEEDITOR_LINEAR;Liniowa +CURVEEDITOR_LOADDLGLABEL;Wczytaj krzywą... +CURVEEDITOR_MINMAXCPOINTS;Ekwalizator +CURVEEDITOR_NURBS;NURBS +CURVEEDITOR_PARAMETRIC;Parametryczna +CURVEEDITOR_SAVEDLGLABEL;Zapisz krzywą... +CURVEEDITOR_SHADOWS;Najciemniejsze +CURVEEDITOR_TOOLTIPCOPY;Skopiuj krzywą do schowka +CURVEEDITOR_TOOLTIPLINEAR;Zresetuj krzywą do liniowej +CURVEEDITOR_TOOLTIPLOAD;Wczytaj krzywą z pliku +CURVEEDITOR_TOOLTIPPASTE;Wstaw krzywą ze schowka +CURVEEDITOR_TOOLTIPSAVE;Zapisz krzywą +CURVEEDITOR_TYPE;Typ: +DIRBROWSER_FOLDERS;Katalogi +EDITWINDOW_TITLE;Edytor obrazu +EDIT_OBJECT_TOOLTIP;Wyświetla widżet na podglądzie który ułatwia ustawienie narzędzia. +EDIT_PIPETTE_TOOLTIP;Aby dodać punkt do krzywej należy trzymac wciśnięty klawisz Ctrl podczas kliknięcia lewym guzikiem myszki na danym obszarze głównego podglądu.\nAby zmienic ustawienie już istniejącego punktu, należy trzymać wduszony klawisz Ctrl podczas kliknięcia lewym guzikiem myszki na danym obszarze głównego podglądu, następnie należy puścić klawisz Ctrl (chyba że chodzi nam o bardzo precyzyjne ustawienie dzieki spowolnieniu jakie trzymanie klawisza Ctrl nam daje) i podczas trzymania lewego guzika myszki należy myszką ruszać w pionie aby odpowiednio manipulować punktem w pionie. +EXIFFILTER_APERTURE;Przysłona +EXIFFILTER_CAMERA;Aparat +EXIFFILTER_EXPOSURECOMPENSATION;Korekcja ekspozycji (EV) +EXIFFILTER_FILETYPE;Typ pliku +EXIFFILTER_FOCALLEN;Wartość ogniskowej +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Obiektyw +EXIFFILTER_METADATAFILTER;Włącz filtry metadanych +EXIFFILTER_SHUTTER;Migawka +EXIFPANEL_ADDEDITHINT;Dodaje nową etykietę lub edytuje etykietę +EXIFPANEL_ADDEDIT;Dodaj/Edytuj +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Wpisz wartość +EXIFPANEL_ADDTAGDLG_SELECTTAG;Wybierz etykietę +EXIFPANEL_ADDTAGDLG_TITLE;Dodaj/Edytuj etykietę +EXIFPANEL_KEEPHINT;Zapamiętuje wybrane etykiety podczas zapisywania pliku wyjściowego +EXIFPANEL_KEEP;Zapamiętaj +EXIFPANEL_REMOVEHINT;Usuwa wybrane etykiety podczas zapisywania pliku wyjściowego +EXIFPANEL_REMOVE;Usuń +EXIFPANEL_RESETALLHINT;Przywraca orginalne wartości etykiet +EXIFPANEL_RESETALL;Przywróć wszystkie +EXIFPANEL_RESETHINT;Przywraca orginalne wartości wybranych etykiet +EXIFPANEL_RESET;Przywróć +EXIFPANEL_SUBDIRECTORY;Podkatalog +EXPORT_BYPASS_ALL;Zaznacz / Odznacz wszystkie +EXPORT_BYPASS_DEFRINGE;Pomiń usuwanie widma +EXPORT_BYPASS_DIRPYRDENOISE;Pomiń redukcję szumów +EXPORT_BYPASS_DIRPYREQUALIZER;Pomiń kontrast wg. poziomu detali +EXPORT_BYPASS_RAW_CA;Pomiń redukcję aberracji chromatycznej (raw) +EXPORT_BYPASS_RAW_CCSTEPS;Pomiń tłumienie fałszowania koloru (raw) +EXPORT_BYPASS_RAW_DCB_ENHANCE;Pomiń poprawę DCB (raw) +EXPORT_BYPASS_RAW_DCB_ITERATIONS;Pomiń liczbę powtórzeń DCB (raw) +EXPORT_BYPASS_RAW_DF;Pomiń czarną klatkę (raw) +EXPORT_BYPASS_RAW_FF;Pomiń puste polę (raw) +EXPORT_BYPASS_RAW_GREENTHRESH;Pomiń wyrównanie zieleni (raw) +EXPORT_BYPASS_RAW_LINENOISE;Pomiń redukcję szumów liniowych (raw) +EXPORT_BYPASS_RAW_LMMSE_ITERATIONS;Pomiń poprawę LMMSE [raw] +EXPORT_BYPASS_SHARPENEDGE;Pomiń wyostrzanie krawędzi +EXPORT_BYPASS_SHARPENING;Pomiń wyostrzanie +EXPORT_BYPASS_SHARPENMICRO;Pomiń mikrokontrast +EXPORT_BYPASS_SH_HQ;Pomiń wysokiej jakości korekte cieni/podświetleń +EXPORT_FASTEXPORTOPTIONS;Opcje szybkiego eksportu +EXPORT_INSTRUCTIONS;Opcje szybkiego eksportu umożliwiają pominięcie pewnych narzędzi które mogą być dość wymagające na procesor oraz mogą znacznie przedłużyc czas przetwarzania podczas eksportowania zdjęć. Ta metoda jest zalecana w razie potrzeby szybkiego uzyskania zdjęć o niższej rozdzielczości oraz jakości kiedy zależy nam na czasie a nie chcemy modyfikować plików PP3. +EXPORT_MAXHEIGHT;Maksymalna wysokość: +EXPORT_MAXWIDTH;Maksymalna szerokość: +EXPORT_PUTTOQUEUEFAST; Dodaj do kolejki szybkiego eksportu +EXPORT_RAW_DMETHOD;Algorytm demozaikowania +EXTPROGTARGET_1;raw +EXTPROGTARGET_2;wywołane w kolejce +FILEBROWSER_ADDDELTEMPLATE;Dodaj/Usuń szablon... +FILEBROWSER_APPLYPROFILE;Zastosuj profil +FILEBROWSER_APPLYPROFILE_PARTIAL;Zastosuj częściowy profil +FILEBROWSER_AUTODARKFRAME;Automatyczne użycie czarnej klatki +FILEBROWSER_AUTOFLATFIELD;Automatyczne użycie klatki typu puste pole +FILEBROWSER_BROWSEPATHBUTTONHINT;Należy kliknąć, aby przeglądać wybraną ścieżkę +FILEBROWSER_BROWSEPATHHINT;Umożliwia przeglądanie wprowadzonej ścieżki\nCtrl-o zaznaczenie\nEnter, Ctrl-Enter (w menedżerze plików) przeglądanie\nSkróty:\n ~ - katalog domowy użytkownika\n ! - katalog z obrazami użytkownia +FILEBROWSER_CACHECLEARFROMFULL;Czyszczenie pamięci podręcznej - pełne +FILEBROWSER_CACHECLEARFROMPARTIAL;Czyszczenie pamięci podręcznej - częściowe +FILEBROWSER_CACHE;Pamięć podręczna +FILEBROWSER_CLEARPROFILE;Wyczyść profil +FILEBROWSER_COLORLABEL_TOOLTIP;Kolorowe etykiety\n\nUżyj za pomocą rozwijanej listy lub skrótów:\nShift-Ctrl-0 No Color\nShift-Ctrl-1 Czerwona\nShift-Ctrl-2 Żółta\nShift-Ctrl-3 Zielona\nShift-Ctrl-4 Niebieska\nShift-Ctrl-5 Purpurowa +FILEBROWSER_COPYPROFILE;Kopiuj profil +FILEBROWSER_CURRENT_NAME;Obecna nazwa: +FILEBROWSER_DARKFRAME;Czarna klatka +FILEBROWSER_DELETEDLGLABEL;Potwierdzenie usunięcia pliku +FILEBROWSER_DELETEDLGMSGINCLPROC;Na pewno usunąć wybrany plik %1 WŁĄCZNIE z wersją utworzoną przez kolejkę przetwarzania? +FILEBROWSER_DELETEDLGMSG;Na pewno usunąć zaznaczone %1 plików? +FILEBROWSER_EMPTYTRASHHINT;Definitywnie usuwa pliki z kosza +FILEBROWSER_EMPTYTRASH;Wyczyść kosz +FILEBROWSER_EXEC_CPB;Uruchom zewnętrzny kreator profilów +FILEBROWSER_EXTPROGMENU;Otwórz za pomocą +FILEBROWSER_FLATFIELD;Puste pole +FILEBROWSER_MOVETODARKFDIR;Przenieś do katalogu zawierającego czarne klatki +FILEBROWSER_MOVETOFLATFIELDDIR;Przenieś do katalogu zawierającego puste pola +FILEBROWSER_NEW_NAME;Nowa nazwa: +FILEBROWSER_OPENDEFAULTVIEWER;Domyślna przeglądarka zdjęć (z kolejki) +FILEBROWSER_PARTIALPASTEPROFILE;Wklej częściowo +FILEBROWSER_PASTEPROFILE;Wklej profil +FILEBROWSER_POPUPCANCELJOB;Anuluj zadanie +FILEBROWSER_POPUPCOLORLABEL0;Etykieta: Brak +FILEBROWSER_POPUPCOLORLABEL1;Etykieta: Czerwona +FILEBROWSER_POPUPCOLORLABEL2;Etykieta: Żółta +FILEBROWSER_POPUPCOLORLABEL3;Etykieta: Zielona +FILEBROWSER_POPUPCOLORLABEL4;Etykieta: Niebieska +FILEBROWSER_POPUPCOLORLABEL5;Etykieta: Purpurowa +FILEBROWSER_POPUPCOLORLABEL;Kolorowa etykieta +FILEBROWSER_POPUPCOPYTO;Skopiuj do... +FILEBROWSER_POPUPFILEOPERATIONS;Operacje na plikach +FILEBROWSER_POPUPMOVEEND;Przenieś na koniec kolejki +FILEBROWSER_POPUPMOVEHEAD;Przenieś na początek kolejki +FILEBROWSER_POPUPMOVETO;Przenieś do... +FILEBROWSER_POPUPOPENINEDITOR;Otwórz w edytorze +FILEBROWSER_POPUPOPEN;Otwórz +FILEBROWSER_POPUPPROCESSFAST;Dodaj do kolejki szybkiego eksportu +FILEBROWSER_POPUPPROCESS;Umieść w kolejce do przetwarzania +FILEBROWSER_POPUPPROFILEOPERATIONS;Profile przetwarzania +FILEBROWSER_POPUPRANK0;Usuń ocenę +FILEBROWSER_POPUPRANK1;Ocena 1 * +FILEBROWSER_POPUPRANK2;Ocena 2 ** +FILEBROWSER_POPUPRANK3;Ocena 3 *** +FILEBROWSER_POPUPRANK4;Ocena 4 **** +FILEBROWSER_POPUPRANK5;Ocena 5 ***** +FILEBROWSER_POPUPRANK;Ocena +FILEBROWSER_POPUPREMOVEINCLPROC;Usuń z dysku wraz z wynikiem przetwarzania +FILEBROWSER_POPUPREMOVE;Usuń z dysku +FILEBROWSER_POPUPRENAME;Zmień nazwę +FILEBROWSER_POPUPSELECTALL;Zaznacz wszystkie +FILEBROWSER_POPUPTRASH;Przenieś do kosza +FILEBROWSER_POPUPUNRANK;Usuń ocenę +FILEBROWSER_POPUPUNTRASH;Usuń z kosza +FILEBROWSER_QUERYBUTTONHINT;Wyczyść hasło szukania +FILEBROWSER_QUERYHINT;Wprowadź część nazwy, by zlokalizować plik. Oddziel hasła przecinkami, np.\n1001,1004,1199\n\nWyklucz hasła poprzedzając je znakiem !=\nnp.\n!=1001,1004,1199\n\nSkróty:\nCtrl-f - przejdź do pola "Znajdź",\nEnter - szukaj,\nEsc - wyczyść pole "Znajdź",\nShift-Esc - wyjdź z pola "Znajdź". +FILEBROWSER_QUERYLABEL; Znajdź: +FILEBROWSER_RANK1_TOOLTIP;Oceń 1 *\nSkrót: Shift-1 +FILEBROWSER_RANK2_TOOLTIP;Oceń 2 *\nSkrót: Shift-2 +FILEBROWSER_RANK3_TOOLTIP;Oceń 3 *\nSkrót: Shift-3 +FILEBROWSER_RANK4_TOOLTIP;Oceń 4 *\nSkrót: Shift-4 +FILEBROWSER_RANK5_TOOLTIP;Oceń 5 *\nSkrót: Shift-5 +FILEBROWSER_RENAMEDLGLABEL;Zmień nazwę pliku +FILEBROWSER_RENAMEDLGMSG;Zmień nazwę pliku "%1" na: +FILEBROWSER_SELECTDARKFRAME;Wybierz czarną klatkę... +FILEBROWSER_SELECTFLATFIELD;Wybierz puste pole... +FILEBROWSER_SHOWCOLORLABEL1HINT;Pokazuje zdjęcia z czerwoną etykietą.\nSkrót: Alt-1 +FILEBROWSER_SHOWCOLORLABEL2HINT;Pokazuje zdjęcia z żółtą etykietą.\nSkrót: Alt-2 +FILEBROWSER_SHOWCOLORLABEL3HINT;Pokazuje zdjęcia z zieloną etykietą.\nSkrót: Alt-3 +FILEBROWSER_SHOWCOLORLABEL4HINT;Pokazuje zdjęcia z niebieską etykietą.\nSkrót: Alt-4 +FILEBROWSER_SHOWCOLORLABEL5HINT;Pokazuje zdjęcia z purpurową etykietą.\nSkrót: Alt-5 +FILEBROWSER_SHOWDIRHINT;Wyłącza wyszstkie filtry.\nSkrót: d +FILEBROWSER_SHOWEDITEDHINT;Pokazuje edytowane zdjęcia.\nSkrót: 7 +FILEBROWSER_SHOWEDITEDNOTHINT;Pokazuje nieedytowane zdjęcia.\nSkrót: 6 +FILEBROWSER_SHOWEXIFINFO;Pokaż dane Exif.\n\nSkróty:\ni - Tryb wielu zakładek,\nAlt-i - Tryb jednej zakładki. +FILEBROWSER_SHOWRANK1HINT;Pokazuje zdjęcia ocenione na 1 gwiazdkę.\nSkrót: 1 +FILEBROWSER_SHOWRANK2HINT;Pokazuje zdjęcia ocenione na 2 gwiazdki.\nSkrót: 2 +FILEBROWSER_SHOWRANK3HINT;Pokazuje zdjęcia ocenione na 3 gwiazdki.\nSkrót: 3 +FILEBROWSER_SHOWRANK4HINT;Pokazuje zdjęcia ocenione na 4 gwiazdki.\nSkrót: 4 +FILEBROWSER_SHOWRANK5HINT;Pokazuje zdjęcia ocenione na 5 gwiazdek.\nSkrót: 5 +FILEBROWSER_SHOWRECENTLYSAVEDHINT;Pokazuje zapisane zdjęcia.\nSkrót: Alt-7 +FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Pokazuje niezapisane zdjęcia.\nSkrót: Alt-6 +FILEBROWSER_SHOWTRASHHINT;Pokazuje zawartość kosza.\nSkrót: Ctrl-t +FILEBROWSER_SHOWUNCOLORHINT;Pokazuje zdjęcia bez kolorowej etykiety.\nSkrót: Alt-0 +FILEBROWSER_SHOWUNRANKHINT;Pokazuje nieocenione zdjęcia.\nSkrót: 0 +FILEBROWSER_STARTPROCESSINGHINT;Rozpoczyna przetwarzanie/zapisywanie plików z kolejki. +FILEBROWSER_STARTPROCESSING;Rozpocznij przetwarzanie +FILEBROWSER_STOPPROCESSINGHINT;Zatrzymuje przetwarzanie zdjęć. +FILEBROWSER_STOPPROCESSING;Zatrzymaj przetwarzanie +FILEBROWSER_THUMBSIZE;Rozmiar minaturek +FILEBROWSER_TOOLTIP_STOPPROCESSING;Rozpocznij przetwarzanie automatycznie gdy pojawi się nowe zadanie. +FILEBROWSER_UNRANK_TOOLTIP;Usuń ocenę.\nSkrót: Shift-0 +FILEBROWSER_ZOOMINHINT;Zwiększa rozmiar miniaturek.\n\nSkróty:\n+ - Tryb wielu zakładek,\nAlt-+ - Tryb pojedyńczej zakładki. +FILEBROWSER_ZOOMOUTHINT;Zmniejsza rozmiar miniaturek.\n\nSkróty:\n- - Tryb wielu zakładek,\nAlt-- - Tryb pojedyńczej zakładki. +GENERAL_ABOUT;O programie +GENERAL_AFTER;Po +GENERAL_AUTO;Automatyczne +GENERAL_BEFORE;Przed +GENERAL_CANCEL;Anuluj +GENERAL_CLOSE;Zamknij +GENERAL_DISABLED;Wyłączone +GENERAL_DISABLE;Wyłącz +GENERAL_ENABLED;Włączone +GENERAL_ENABLE;Włącz +GENERAL_FILE;Plik +GENERAL_LANDSCAPE;Poziomo +GENERAL_NA;nd. +GENERAL_NONE;Żaden +GENERAL_NO;Nie +GENERAL_OK;OK +GENERAL_PORTRAIT;Pionowo +GENERAL_SAVE;Zapisz +GENERAL_UNCHANGED;(Niezmienione) +GENERAL_WARNING;Uwaga +HISTOGRAM_TOOLTIP_BAR;Pokazuje/Ukrywa wskaźnik RGB.\nKliknięcie prawym przyciskiem myszy na podglądzie zdjęcia blokuje/odblokowuje. +HISTOGRAM_TOOLTIP_B;Pokaż/Ukryj histogram błękitów. +HISTOGRAM_TOOLTIP_CHRO;Pokaż/Ukryj histogram chromatyczności. +HISTOGRAM_TOOLTIP_FULL;Przełącz histogram pełny (wyłączone)/skalowany (włączone). +HISTOGRAM_TOOLTIP_G;Pokaż/Ukryj histogram zieleni. +HISTOGRAM_TOOLTIP_L;Pokaż/Ukryj histogram luminancji CIELab. +HISTOGRAM_TOOLTIP_RAW;Pokaż/Ukryj histogram raw. +HISTOGRAM_TOOLTIP_R;Pokaż/Ukryj histogram czerwieni. +HISTORY_CHANGED;Zmieniono +HISTORY_CUSTOMCURVE;Krzywa własna +HISTORY_DELSNAPSHOT;Usuń migawkę +HISTORY_FROMCLIPBOARD;Ze schowka +HISTORY_LABEL;Historia +HISTORY_MSG_1;Zdjęcie załadowane +HISTORY_MSG_2;Profil załadowany +HISTORY_MSG_3;Profil zmieniony +HISTORY_MSG_4;Przeglądanie historii +HISTORY_MSG_5;Światłość +HISTORY_MSG_6;Kontrast +HISTORY_MSG_7;Czerń +HISTORY_MSG_8;Kompensacja ekspozycji +HISTORY_MSG_9;Kompresja podświetleń +HISTORY_MSG_10;Kompresja cieni +HISTORY_MSG_11;Krzywa tonalna +HISTORY_MSG_12;Automatyczna ekspozycja +HISTORY_MSG_13;Przycinanie ekspozycji +HISTORY_MSG_14;L*a*b* - Światłość +HISTORY_MSG_15;L*a*b* - Kontrast +HISTORY_MSG_16;- +HISTORY_MSG_17;- +HISTORY_MSG_18;- +HISTORY_MSG_19;Krzywa L* +HISTORY_MSG_20;Wyostrzanie +HISTORY_MSG_21;USM - Promień +HISTORY_MSG_22;USM - Siła +HISTORY_MSG_23;USM - Próg wyostrzania +HISTORY_MSG_24;USM - Wyostrz tylko krawędzie +HISTORY_MSG_25;USM - Promień detekcji krawędzi +HISTORY_MSG_26;USM - Tolerancja krawędzi +HISTORY_MSG_27;USM - Kontrola poświaty +HISTORY_MSG_28;USM - Stopień kontroli poświaty +HISTORY_MSG_29;Metoda wyostrzania +HISTORY_MSG_30;RLD - Promień +HISTORY_MSG_31;RLD - Siła +HISTORY_MSG_32;RLD - Tłumienie +HISTORY_MSG_33;RLD - Powtórzenia +HISTORY_MSG_34;LCP - Korekcja dystorsji +HISTORY_MSG_35;LCP - Korekcja winietowania +HISTORY_MSG_36;LCP - Korekcja aberacji +HISTORY_MSG_37;Automatyczna ekspozycja +HISTORY_MSG_38;Metoda balansu bieli +HISTORY_MSG_39;BB - Temperatura +HISTORY_MSG_40;BB - Odcień +HISTORY_MSG_41;Tryb krzywej 1 +HISTORY_MSG_42;Krzywa 1 +HISTORY_MSG_43;Tryb krzywej 2 +HISTORY_MSG_44;Odszumianie lum. - Promień +HISTORY_MSG_45;Odszumianie lum. - Tolerancja krawędzi +HISTORY_MSG_46;Odszumianie koloru +HISTORY_MSG_47;Mieszanie podświetleń ICC z matrycą +HISTORY_MSG_48;Użycie krzywej tonalnej z DCP +HISTORY_MSG_49;Illuminant DCP +HISTORY_MSG_50;Cienie/Podświetlenia +HISTORY_MSG_51;C/P - Podświetlenia +HISTORY_MSG_52;C/P - Cienie +HISTORY_MSG_53;C/P - Szerokość tonalna podśw. +HISTORY_MSG_54;C/P - Szerokość tonalna cieni +HISTORY_MSG_55;C/P - Kontrast lokalny +HISTORY_MSG_56;C/P - Promień +HISTORY_MSG_57;Obrót dyskretny +HISTORY_MSG_58;Odbicie w poziomie +HISTORY_MSG_59;Odbicie w pionie +HISTORY_MSG_60;Obrót +HISTORY_MSG_61;Auto-wypełnianie +HISTORY_MSG_62;Korekcja dystorsji obiektywu +HISTORY_MSG_63;Migawka wybrana +HISTORY_MSG_64;Kadrowanie +HISTORY_MSG_65;Korekcja aberracji chromatycznej +HISTORY_MSG_66;Rekonstrukcja prześwietleń +HISTORY_MSG_67;Rekonstrukcja prześwietleń - Siła +HISTORY_MSG_68;Rekonstrukcja prześwietleń - Metoda +HISTORY_MSG_69;Robocza przestrzeń kolorów +HISTORY_MSG_70;Wyjściowa przestrzeń kolorów +HISTORY_MSG_71;Wejściowa przestrzeń kolorów +HISTORY_MSG_72;KW - Siła +HISTORY_MSG_73;Mieszacz kanałów +HISTORY_MSG_74;Zmiany rozmiaru - Skala +HISTORY_MSG_75;Zmiany rozmiaru - Metoda +HISTORY_MSG_76;Metadane Exif +HISTORY_MSG_77;Metadane IPTC +HISTORY_MSG_78;- +HISTORY_MSG_79;Zmiany rozmiaru - Szerokość +HISTORY_MSG_80;Zmiany rozmiaru - Wysokość +HISTORY_MSG_81;Zmiany rozmiaru +HISTORY_MSG_82;Profil zmieniony +HISTORY_MSG_83;C/P - Ostra maska +HISTORY_MSG_84;Korekcja perspektywy +HISTORY_MSG_85;LCP +HISTORY_MSG_86;Krzywe RGB - Tryb luminancji +HISTORY_MSG_87;Redukcja szumów impulsowych +HISTORY_MSG_88;RSI - Próg +HISTORY_MSG_89;Redukcja szumów +HISTORY_MSG_90;RS - Luminancja +HISTORY_MSG_91;RS - Chrominancja +HISTORY_MSG_92;RS - Gamma +HISTORY_MSG_93;Kontrast wg. poziomu detali +HISTORY_MSG_94;Kontrast wg. poziomu detali +HISTORY_MSG_95;L*a*b* - Chromatyczność +HISTORY_MSG_96;Krzywa a* +HISTORY_MSG_97;Krzywa b* +HISTORY_MSG_98;Algorytm demozaikowania +HISTORY_MSG_99;Filtrowanie gorących pikseli +HISTORY_MSG_100;Nasycenie RGB +HISTORY_MSG_101;HSV - Odcień +HISTORY_MSG_102;HSV - Nasycenie +HISTORY_MSG_103;HSV - Mocy światła białego +HISTORY_MSG_104;Ekwalizator HSV +HISTORY_MSG_105;Usuwanie widma +HISTORY_MSG_106;Usuwanie widma - Promień +HISTORY_MSG_107;Usuwanie widma - Próg +HISTORY_MSG_108;Próg kompresji prześwietleń +HISTORY_MSG_109;Zmiana rozmiaru - Wymiary obwodu +HISTORY_MSG_110;Zmiana rozmiaru dotyczy +HISTORY_MSG_111;L*a*b* - Unikaj przycinania koloru +HISTORY_MSG_112;- +HISTORY_MSG_113;L*a*b* - Ograniczenie nasyczenia +HISTORY_MSG_114;DCB - Liczba powtórzeń +HISTORY_MSG_115;DCB - Zapobieganie fałszowaniu koloru +HISTORY_MSG_116;DCB - Ulepszone +HISTORY_MSG_117;Korekcja aberracji raw - Czerwona +HISTORY_MSG_118;Korekcja aberracji raw - Niebieska +HISTORY_MSG_119;Redukcja szumów liniowych +HISTORY_MSG_120;Wyrównanie zieleni +HISTORY_MSG_121;Autokorekcja aberracji chromatycznej +HISTORY_MSG_122;Czarna klatka - Auto-wybór +HISTORY_MSG_123;Czarna klatka - Wybór +HISTORY_MSG_124;Korekcja punktu bieli +HISTORY_MSG_125;Zachowanie prześwietleń +HISTORY_MSG_126;Puste pole - Wybór +HISTORY_MSG_127;Puste pole - Auto-wybór +HISTORY_MSG_128;Puste pole - Promień rozmycia +HISTORY_MSG_129;Puste pole - Typ rozmycia +HISTORY_MSG_130;Automatyczna korekcja dystorsji +HISTORY_MSG_131;RS - Luma +HISTORY_MSG_132;RS - Chroma +HISTORY_MSG_133;Gamma wyjściowa +HISTORY_MSG_134;Wolna gamma +HISTORY_MSG_135;Wolna gamma +HISTORY_MSG_136;Nachylenie gamma +HISTORY_MSG_137;Poziom czerni - Zielony 1 +HISTORY_MSG_138;Poziom czerni - Czerwony +HISTORY_MSG_139;Poziom czerni - Niebieski +HISTORY_MSG_140;Poziom czerni - Zielony 2 +HISTORY_MSG_141;Poziom czerni - Połącz zielone +HISTORY_MSG_142;WK - Powtórzenia +HISTORY_MSG_143;WK - Siła +HISTORY_MSG_144;Mikrokontrast - Siła +HISTORY_MSG_145;Mikrokontrast - Jednolitość +HISTORY_MSG_146;Wyostrzanie krawędzi +HISTORY_MSG_147;Wyostrzanie krawędzi - tylko luminacja +HISTORY_MSG_148;Mikrokontrast +HISTORY_MSG_149;Mikrokontrast - matryca 3x3 +HISTORY_MSG_150;Redukcja szumu i artefaktów po demozaikowaniu +HISTORY_MSG_151;Jaskrawość +HISTORY_MSG_152;Jaskrawość - Ppastelowe +HISTORY_MSG_153;Jaskrawość - Nasycone +HISTORY_MSG_154;Jaskrawość - Chroń odcienie skóry +HISTORY_MSG_155;Jaskrawość - Zapobiegaj zmianom kolorów +HISTORY_MSG_156;Jaskrawość - Połącz pastelowe i nasycone +HISTORY_MSG_157;Jaskrawość - Próg pastelowych/nasyconych +HISTORY_MSG_158;TM - Siła +HISTORY_MSG_159;TM - Wyszukanie krawędzi +HISTORY_MSG_160;TM - Skala +HISTORY_MSG_161;TM - Powtarzanie rozważania +HISTORY_MSG_162;Tone Mapping +HISTORY_MSG_163;Krzywe RGB - Czerwona +HISTORY_MSG_164;Krzywe RGB - Zielona +HISTORY_MSG_165;Krzywe RGB - Niebieska +HISTORY_MSG_166;Neutralna ekspozycja +HISTORY_MSG_167;- +HISTORY_MSG_168;L*a*b* - Krzywa CC +HISTORY_MSG_169;L*a*b* - Krzywa CH +HISTORY_MSG_170;Jaskrawość - Krzywa HH +HISTORY_MSG_171;L*a*b* - Krzywa LC +HISTORY_MSG_172;L*a*b* - Ogranicz LC +HISTORY_MSG_173;RS - Szczegóły luminancji +HISTORY_MSG_174;CIECAM02 +HISTORY_MSG_175;CAM02 - Adaptacja CAT02 +HISTORY_MSG_176;CAM02 - Otoczenie +HISTORY_MSG_177;CAM02 - Luminancja sceny +HISTORY_MSG_178;CAM02 - Luminancja widowni +HISTORY_MSG_179;CAM02 - Model punktu bieli +HISTORY_MSG_180;CAM02 - Światłość (J) +HISTORY_MSG_181;CAM02 - Chroma (C) +HISTORY_MSG_182;CAM02 - Automatyczne CAT02 +HISTORY_MSG_183;CAM02 - Kontrast (J) +HISTORY_MSG_184;CAM02 - Otoczenie sceny +HISTORY_MSG_185;CAM02 - Kontrola gamma +HISTORY_MSG_186;CAM02 - Algorytm +HISTORY_MSG_187;CAM02 - Ochrona czerwieni/skóry +HISTORY_MSG_188;CAM02 - Jasność (Q) +HISTORY_MSG_189;CAM02 - Kontrast (Q) +HISTORY_MSG_190;CAM02 - Nasycenie (S) +HISTORY_MSG_191;CAM02 - Barwistość (M) +HISTORY_MSG_192;CAM02 - Odcień (hue, h) +HISTORY_MSG_193;CAM02 - Krzywa tonalna 1 +HISTORY_MSG_194;CAM02 - Krzywa tonalna 2 +HISTORY_MSG_195;CAM02 - Krzywa tonalna 1 +HISTORY_MSG_196;CAM02 - Krzywa tonalna 2 +HISTORY_MSG_197;CAM02 - Krzywa koloru +HISTORY_MSG_198;CAM02 - Krzywa koloru +HISTORY_MSG_199;CAM02 - Histogramy wyjściowe +HISTORY_MSG_200;CAMO2 - Tone mapping +HISTORY_MSG_201;RS - Chrominancja - R&G +HISTORY_MSG_202;RS - Chrominancja - B&Y +HISTORY_MSG_203;RS - Metoda +HISTORY_MSG_204;Kroki poprawy LMMSE +HISTORY_MSG_205;CAM02 - Gorące/uszkodzone px +HISTORY_MSG_206;CAT02 - Auto luminancja sceny +HISTORY_MSG_207;Usuwanie widma - Krzywa odcieni +HISTORY_MSG_208;BB - Ekwalizator N/C +HISTORY_MSG_210;FP - Kąt +HISTORY_MSG_211;Filtr Połówkowy +HISTORY_MSG_212;Winietowanie - Siła +HISTORY_MSG_213;Winietowanie +HISTORY_MSG_214;Czarno-białe (B&W) +HISTORY_MSG_215;B&W - MK - Czerwony +HISTORY_MSG_216;B&W - MK - Zielony +HISTORY_MSG_217;B&W - MK - Niebieski +HISTORY_MSG_218;B&W - Gamma - Czerwony +HISTORY_MSG_219;B&W - Gamma - Zielony +HISTORY_MSG_220;B&W - Gamma - Niebieski +HISTORY_MSG_221;B&W - Filtr barwny +HISTORY_MSG_222;B&W - Ustawienia +HISTORY_MSG_223;B&W - MK - Pomarańczowy +HISTORY_MSG_224;B&W - MK - Żółty +HISTORY_MSG_225;B&W - MK - Cyjanowy +HISTORY_MSG_226;B&W - MK - Magenta +HISTORY_MSG_227;B&W - MK - Purpurowy +HISTORY_MSG_228;B&W - Ekwalizator luminancji +HISTORY_MSG_229;B&W - Ekwalizator luminancji +HISTORY_MSG_230;B&W - Tryb +HISTORY_MSG_231;B&W - Krzywa 'Przed' +HISTORY_MSG_232;B&W - Rodzaj krzywej 'Przed' +HISTORY_MSG_233;B&W - Krzywa 'Po' +HISTORY_MSG_234;B&W - Rodzaj krzywej 'Po' +HISTORY_MSG_235;B&W - Auto-mieszanie kolorów +HISTORY_MSG_236;- +HISTORY_MSG_237;B&W - Mieszacz +HISTORY_MSG_238;FP - Wtapianie +HISTORY_MSG_239;FP - Siła +HISTORY_MSG_240;FP - Środek +HISTORY_MSG_241;Winietowanie - Wtapianie +HISTORY_MSG_242;Winietowanie - Okrągłość +HISTORY_MSG_243;Winietowanie - Promień +HISTORY_MSG_244;Winietowanie - Siła +HISTORY_MSG_245;Winietowanie - Środek +HISTORY_MSG_246;Krzywa CL +HISTORY_MSG_247;Krzywa LH +HISTORY_MSG_248;Krzywa HH +HISTORY_MSG_249;KwgPS - Próg +HISTORY_MSG_250;RS - Ulepszona +HISTORY_MSG_251;B&W - Algorytm +HISTORY_MSG_252;KwgPS - Odcienie skóry +HISTORY_MSG_253;KwgPS - Redukcja błędów +HISTORY_MSG_254;KwgPS - Odcienie skóry +HISTORY_MSG_255;RS - Filtr mediana +HISTORY_MSG_256;RS - Wielkość okna mediana +HISTORY_MSG_257;Koloryzacja +HISTORY_MSG_258;Koloryzacja - Kolor +HISTORY_MSG_259;Koloryzacja - Przezroczystość +HISTORY_MSG_260;Koloryzacja - Przezroczystość a*[b*] +HISTORY_MSG_261;Koloryzacja - Metoda +HISTORY_MSG_262;Koloryzacja - Przezroczystość b* +HISTORY_MSG_263;Koloryzacja - Cienie - Czerwony +HISTORY_MSG_264;Koloryzacja - Cienie - Zielony +HISTORY_MSG_265;Koloryzacja - Cienie - Niebiski +HISTORY_MSG_266;Koloryzacja - Þółcienie - Czerwone +HISTORY_MSG_267;Koloryzacja - Þółcienie - Zielone +HISTORY_MSG_268;Koloryzacja - Þółcienie - Niebieskie +HISTORY_MSG_269;Koloryzacja - Podświetlenia - Czerwone +HISTORY_MSG_270;Koloryzacja - Podświetlenia - Zielona +HISTORY_MSG_271;Koloryzacja - Podświetlenia - Niebieskie +HISTORY_MSG_272;Koloryzacja - Balans +HISTORY_MSG_273;Koloryzacja - Reset +HISTORY_MSG_274;Koloryzacja - Nasycenie cieni +HISTORY_MSG_275;Koloryzacja - Nasycenie jasnych +HISTORY_MSG_276;Koloryzacja - Przezroczystość +HISTORY_MSG_277;--unused-- +HISTORY_MSG_278;Koloryzacja - Zachowaj luminancję +HISTORY_MSG_279;Koloryzacja - Cienie +HISTORY_MSG_280;Koloryzacja - Tony jasne +HISTORY_MSG_281;Koloryzacja - Siła nasycenia +HISTORY_MSG_282;Koloryzacja - Próg nasycenia +HISTORY_MSG_283;Koloryzacja - Siła +HISTORY_MSG_284;Koloryzacja - Auto ochrona przesycenia +HISTORY_MSG_285;RS - Mediana - Metoda +HISTORY_MSG_286;RS - Mediana - Typ +HISTORY_MSG_287;RS - Mediana - Powtarzanie +HISTORY_MSG_288;Puste pole - Zabezp. przed obcinaniem +HISTORY_MSG_289;Puste pole - Auto-zabezp. przed obcinaniem +HISTORY_MSG_290;Próg czerni - Czerwony +HISTORY_MSG_291;Próg czerni - Zielony +HISTORY_MSG_292;Próg czerni - Niebieski +HISTORY_MSG_293;Symulacja Kliszy +HISTORY_MSG_294;Symulacja Kliszy - Siła +HISTORY_MSG_295;Symulacja Kliszy - Klisza +HISTORY_MSG_296;RS - Modulacja luminancji +HISTORY_MSG_297;RS - Jakość +HISTORY_MSG_298;Filtrowanie martwych pikseli +HISTORY_NEWSNAPSHOT;Nowa migawka +HISTORY_NEWSNAPSHOT_TOOLTIP;Skrót: Alt-s +HISTORY_SNAPSHOTS;Migawki +HISTORY_SNAPSHOT;Migawka +IPTCPANEL_AUTHORSPOSITIONHINT;Stanowisko lub funkcja autora lub autorów dzieła (By-line Title). +IPTCPANEL_AUTHORSPOSITION;Stanowisko +IPTCPANEL_AUTHOR;Autor +IPTCPANEL_CAPTIONHINT;Tekstowy opis treści (Caption - Abstract). +IPTCPANEL_CAPTIONWRITERHINT;Imię i nazwisko osoby biorące udział w opracowywaniu, edytowanie lub korygowania obrazu lub opisu (Writer - Editor). +IPTCPANEL_CAPTIONWRITER;Autor opisu +IPTCPANEL_CAPTION;Tytuł +IPTCPANEL_CATEGORYHINT;Identyfikuje temat zdjęcia w opinii jego dostawcy (Category). +IPTCPANEL_CATEGORY;Kategoria +IPTCPANEL_CITYHINT;Miasto w którym wykonano zdjęcie (City). +IPTCPANEL_CITY;Miasto +IPTCPANEL_COPYHINT;Kopiuje ustawienia IPTC do schowka +IPTCPANEL_COPYRIGHTHINT;Ważne uwagi o prawach autorskich (Copyright Notice). +IPTCPANEL_COPYRIGHT;Prawa autorskie +IPTCPANEL_COUNTRYHINT;Nazwa kraju lub lokalizacji, gdzie zostało wykonane zdjęcie (Country - Primary Location Name). +IPTCPANEL_COUNTRY;Kraj +IPTCPANEL_CREDITHINT;Identyfikuje dostawcę zdjęcia, niekoniecznie właściciela lub autora (Credit). +IPTCPANEL_CREDIT;Zasługa +IPTCPANEL_DATECREATEDHINT;Data powstania intelektualnej treści zdjęcia. Format: JJJJMMTT (Date Created). +IPTCPANEL_DATECREATED;Data utworzenia +IPTCPANEL_EMBEDDEDHINT;Resetuje dane IPTC do domyślnych ustawień osadzonych w orginalnym zdjęciu +IPTCPANEL_EMBEDDED;Osadzony +IPTCPANEL_HEADLINEHINT;Gotowy do opublikowania wpis streszczający zawratość zdjęcia (Headline). +IPTCPANEL_HEADLINE;Nagłówek +IPTCPANEL_INSTRUCTIONSHINT;Inne wskazówki redakcyjne dotyczące korzystania z obrazu (Special Instructions). +IPTCPANEL_INSTRUCTIONS;Instrukcje +IPTCPANEL_KEYWORDSHINT;Wskazuje konkretne treści możliwe do odszukania (Keywords). +IPTCPANEL_KEYWORDS;Słowa kluczowe +IPTCPANEL_PASTEHINT;Wstawia ustawienia IPTC ze schowka +IPTCPANEL_PROVINCEHINT;Województwo, gmina, stan gdzie zostało wykonane zdjęcie (Province-State). +IPTCPANEL_PROVINCE;Stan, województwo, dystrykt itd. +IPTCPANEL_RESETHINT;Resetuje do domyślnych ustawień profilu +IPTCPANEL_RESET;Reset +IPTCPANEL_SOURCEHINT;Pierwotny właściciel treści intelektualnych zdjęcia (Source). +IPTCPANEL_SOURCE;Źródło +IPTCPANEL_SUPPCATEGORIESHINT;Doprecyzowuje kategorie tematyczne zdjęcia (Supplemental Categories). +IPTCPANEL_SUPPCATEGORIES;Dodatkowe kategorie tematyczne +IPTCPANEL_TITLEHINT;Skrócony temat odniesienia zdjęcia (Object Name). +IPTCPANEL_TITLE;Tytuł +IPTCPANEL_TRANSREFERENCEHINT;Numer badź kod identyfikujący zlecenie utworzony zazwyczaj przez fotografa przy transmisji umożliwiający śledzenie obrazu w obiegu. +IPTCPANEL_TRANSREFERENCE;Kod ident. zlecenie +MAIN_BUTTON_FULLSCREEN;Pełen ekran +MAIN_BUTTON_NAVNEXT_TOOLTIP;Przejdź do następnego zdjęcia względem zdjęcia otwartego w Edytorze.\nSkrót: Shift-F4\n\nAby przejść do następnego zdjęcia względem miniaturki wybranej w Nawigatorze Zdjęć:\nSkrót: F4 +MAIN_BUTTON_NAVPREV_TOOLTIP;Przejdź do poprzedniego zdjęcia wzgledem zdjęcia otwartego w Edytorze.\nSkrót: Shift-F3 \n\nAby przejść do poprzedniego zdjęcia względem miniaturki wybranej w Nawigatorze Zdjęć:\nSkrót: F3 +MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchronizuj Nawigator Zdjęć z Edytorem aby ukazać miniaturkę obecnie otwartego zdjęcia, oraz usuń filtry w Nawigatorze Zdjęć.\nSkrót: x\n\nJak wyżej, ale bez usuwania filtrów:\nSkrót: y\n(Miniaturka otwartego zdjęcia nie zostanie wyświetlona jesli filtr ją ukrywa). +MAIN_BUTTON_PREFERENCES;Ustawienia +MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Dodaj bieżące zdjęcie do kolejki przetwarzania Ctrl+B +MAIN_BUTTON_SAVE_TOOLTIP;Zapisz bieżące zdjęcieCtrl+S +MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Otwórz bieżące zdjęcie w zewnętrznym edytorze.\nSkrót: Ctrl+e +MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Pokaż/Ukryj wszystkie panele boczne.\nSkrót: m +MAIN_BUTTON_UNFULLSCREEN;Zwolnij ekran +MAIN_FRAME_BATCHQUEUE;Kolejka +MAIN_FRAME_BATCHQUEUE_TOOLTIP;Przetwarzanie wsadowe\nSkrót: Ctrl-F3 +MAIN_FRAME_EDITOR;Edytor +MAIN_FRAME_EDITOR_TOOLTIP;Edytor.\nSkrót: Ctrl-F4 +MAIN_FRAME_FILEBROWSER;Przeglądarka plików +MAIN_FRAME_FILEBROWSER_TOOLTIP; Przeglądarka plików.\nSkrót: Ctrl-F2 +MAIN_FRAME_PLACES;Miejsca +MAIN_FRAME_PLACES_ADD;Dodaj +MAIN_FRAME_PLACES_DEL;Usuń +MAIN_FRAME_RECENT;Ostatnio używane foldery +MAIN_MSG_ALREADYEXISTS;Plik już istnieje. +MAIN_MSG_CANNOTLOAD;Nie można wczytać obrazu +MAIN_MSG_CANNOTSAVE;Błąd zapisu pliku +MAIN_MSG_CANNOTSTARTEDITOR;Nie mozna uruchomic edytora. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Proszę wprowadzić prawidłową ścieżkę w Ustawieniach. +MAIN_MSG_EMPTYFILENAME;Nie podano nazwy pliku! +MAIN_MSG_IMAGEUNPROCESSED;Ta komenda wymaga aby wszystkie wybrane zdjęcia były wpierw wywołane poprzez kolejkę. +MAIN_MSG_NAVIGATOR;Nawigator +MAIN_MSG_OPERATIONCANCELLED;Operację anulowano +MAIN_MSG_PATHDOESNTEXIST;Ścieżka\n\n%1\n\nnie istnieje. Wybierz przawidłową ścieżkę w Ustawieniach. +MAIN_MSG_QOVERWRITE;Zastąpić? +MAIN_MSG_SETPATHFIRST;Aby użyć tej funkcji należy wpierw wybrać odpowiednią ścieżkę docelową w Ustawieniach! +MAIN_MSG_WRITEFAILED;Zapis nie powiódł się:\n\n"%1"\n\nUpewnij się, że folder istnieje oraz że można do niego zapisywać. +MAIN_TAB_COLOR;Kolor +MAIN_TAB_COLOR_TOOLTIP;Skrót: Alt-c +MAIN_TAB_DETAIL;Szczegóły +MAIN_TAB_DETAIL_TOOLTIP;Skrót: Alt-d +MAIN_TAB_DEVELOP; Przetwarzanie +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPORT; Szybki eksport +MAIN_TAB_EXPOSURE;Ekspozycja +MAIN_TAB_EXPOSURE_TOOLTIP;Skrót: Alt-e +MAIN_TAB_FILTER; Filtr +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadane +MAIN_TAB_METADATA_TOOLTIP;Skrót: Alt-m +MAIN_TAB_RAW;Raw +MAIN_TAB_RAW_TOOLTIP;Skrót: Alt-r +MAIN_TAB_TRANSFORM;Transformacje +MAIN_TAB_TRANSFORM_TOOLTIP;Skrót: Alt-t +MAIN_TOOLTIP_BACKCOLOR0;Kolor tła podglądu: Tematyczny\nSkrót: 9 +MAIN_TOOLTIP_BACKCOLOR1;Kolor tła podglądu: Czarny\nSkrót: 9 +MAIN_TOOLTIP_BACKCOLOR2;Kolor tła podglądu: Biały\nSkrót: 9 +MAIN_TOOLTIP_BEFOREAFTERLOCK;Zablokuj / Odblokuj widok Przed\n\nZablokuj: nie zmieniaj widoku Przed - \nPrzydatne w porównywaniu zablokowanego obrazu z obrazem na ktorym wykonano wiele zmian.\n\nOdblokuj: widok Przed będzie śledził widok Po o jeden krok do tyłu, pokazując obraz przed efektem aktualnie użytego narzędzia. +MAIN_TOOLTIP_HIDEHP;Pokaż/ukryj lewy panel (razem z historią).\nSkrót: l +MAIN_TOOLTIP_INDCLIPPEDH;Pokaż obcięte prześwietlenia.\nSkrót: < +MAIN_TOOLTIP_INDCLIPPEDS;Pokaż obcięte niedoświetlenia.\nSkrót: > +MAIN_TOOLTIP_PREVIEWB;Podgląd kanału niebieskiego.\nSkrót: b +MAIN_TOOLTIP_PREVIEWFOCUSMASK;Podgląd maski ostrości.\nSkrót: Shift-f\n\nDokładniejsze w przypadku zdjęc o płytkiej głębi ostrości, niskim pozimie szumów i o większym przybliżeniu. W przypadku zdjęć o wyższym poziomie szumów maska ostrości będzie dokładniejsza przy mniejszym zoomie (10-30%). +MAIN_TOOLTIP_PREVIEWG;Podgląd kanału zielonego.\nSkrót: g +MAIN_TOOLTIP_PREVIEWL;Podgląd kanału jasności.\nSkrót: v\n\n0.299*R + 0.587*G + 0.114*B +MAIN_TOOLTIP_PREVIEWR;Podgląd kanału czerwonego.\nSkrót: r +MAIN_TOOLTIP_QINFO;Informacje o zdjęciu.\nSkrót: i +MAIN_TOOLTIP_SHOWHIDELP1;Pokaż/Ukryj lewy panel.\nSkrót: l +MAIN_TOOLTIP_SHOWHIDERP1;Pokaż/Ukryj prawy panel.\nSkrót: Alt-l +MAIN_TOOLTIP_SHOWHIDETP1;Pokaż/Ukryj górny panel.\nSkrót: Shift-l +MAIN_TOOLTIP_THRESHOLD;Próg +MAIN_TOOLTIP_TOGGLE;Przełącz widok Przed/Po.\nSkrót: Shift-b +NAVIGATOR_B;B: +NAVIGATOR_G;G: +NAVIGATOR_H;H: +NAVIGATOR_LAB_A;a*: +NAVIGATOR_LAB_B;b*: +NAVIGATOR_LAB_L;L*: +NAVIGATOR_NA; -- +NAVIGATOR_R;R: +NAVIGATOR_S;S: +NAVIGATOR_V;V: +NAVIGATOR_XY_FULL;Szerokość: %1, Wysokość: %2 +NAVIGATOR_XY_NA;x: --, y: -- +OPTIONS_DEFIMG_MISSING;Nie znaleziono domyślnego profilu dla plików innych niż raw, lub profil nie jest ustawiony.\n\nProszę sprawdz folder z profilami - możliwe że został skasowany bądź uszkodzony.\n\nDomyślne wewnętrzne ustawienia zostaną użyte. +OPTIONS_DEFRAW_MISSING;Nie znaleziono domyślnego profilu dla plików raw, lub profil nie jest ustawiony.\n\nProszę sprawdz folder z profilami - możliwe że został skasowany bądź uszkodzony.\n\nDomyślne wewnętrzne ustawienia zostaną użyte. +PARTIALPASTE_BASICGROUP;Podstawowe ustawienia +PARTIALPASTE_CACORRECTION;Korekcja aberacji chr. +PARTIALPASTE_CHANNELMIXERBW;Czarno-białe +PARTIALPASTE_CHANNELMIXER;Mieszacz kanałów +PARTIALPASTE_COARSETRANS;Obrót dyskretny / odbicie +PARTIALPASTE_COLORAPP;CIECAM02 +PARTIALPASTE_COLORGROUP;Ustawienia związane z kolorem +PARTIALPASTE_COLORTONING;Koloryzacja +PARTIALPASTE_COMMONTRANSFORMPARAMS;Auto-wypełnianie +PARTIALPASTE_COMPOSITIONGROUP;Ustawienia kompozycji +PARTIALPASTE_CROP;Kadrowanie +PARTIALPASTE_DARKFRAMEAUTOSELECT;Auto-wybór czarnej klatki +PARTIALPASTE_DARKFRAMEFILE;Wybór czarnej klatki +PARTIALPASTE_DEFRINGE;Usuwanie widma +PARTIALPASTE_DETAILGROUP;Ustawienia szczegółowe +PARTIALPASTE_DIALOGLABEL;Częściowe wklejenie profilu przetwarzania +PARTIALPASTE_DIRPYRDENOISE;Redukcja szumu +PARTIALPASTE_DIRPYREQUALIZER;Kontrast wg. poziomu detali +PARTIALPASTE_DISTORTION;Korekcja zniekształcenia +PARTIALPASTE_EPD;Tone Mapping +PARTIALPASTE_EVERYTHING;Wszystko +PARTIALPASTE_EXIFCHANGES;Exif +PARTIALPASTE_EXPOSURE;Ekspozycja +PARTIALPASTE_FILMSIMULATION;Symulacja kliszy +PARTIALPASTE_FLATFIELDAUTOSELECT;Puste pole - Auto-wybór +PARTIALPASTE_FLATFIELDBLURRADIUS;Puste pole - Promień +PARTIALPASTE_FLATFIELDBLURTYPE;Puste pole - Typ +PARTIALPASTE_FLATFIELDCLIPCONTROL;Puste pole - Zabezp. przed obcinaniem +PARTIALPASTE_FLATFIELDFILE;Puste pole - Wybór +PARTIALPASTE_GRADIENT;Filtr połówkowy +PARTIALPASTE_HSVEQUALIZER;Ekwalizator HSV +PARTIALPASTE_ICMGAMMA;Gamma wyjściowa +PARTIALPASTE_ICMSETTINGS;Ustawienia ICM +PARTIALPASTE_IMPULSEDENOISE;Redukcja szumów impulsowych +PARTIALPASTE_IPTCINFO;IPTC +PARTIALPASTE_LABCURVE;Regulacje L*a*b* +PARTIALPASTE_LENSGROUP;Ustawienia związane z obiektywem +PARTIALPASTE_LENSPROFILE;Profil korekcji obiektywu LCP +PARTIALPASTE_METAGROUP;Metadane +PARTIALPASTE_PCVIGNETTE;Winietowanie +PARTIALPASTE_PERSPECTIVE;Perspektywa +PARTIALPASTE_PREPROCESS_DEADPIXFILT;Filtr martwych pikseli +PARTIALPASTE_PREPROCESS_GREENEQUIL;Wyrównanie zieleni +PARTIALPASTE_PREPROCESS_HOTPIXFILT;Filtr gorących pikseli +PARTIALPASTE_PREPROCESS_LINEDENOISE;Redukcja szumów liniowych +PARTIALPASTE_RAWCACORR_AUTO;Autokorekcja aberracji chr. +PARTIALPASTE_RAWCACORR_CABLUE;AbChr niebieski +PARTIALPASTE_RAWCACORR_CARED;AbChr czerwony +PARTIALPASTE_RAWEXPOS_BLACK;Poziomy czerni +PARTIALPASTE_RAWEXPOS_LINEAR;Korekcja punktu bieli +PARTIALPASTE_RAWEXPOS_PRESER;Zachowanie prześwietleń +PARTIALPASTE_RAWGROUP;Ustawienia raw +PARTIALPASTE_RAW_DCBENHANCE;Zastosuj poprawę DCB +PARTIALPASTE_RAW_DCBITERATIONS;Liczba powtórzeń DCB +PARTIALPASTE_RAW_DMETHOD;Algorytm demozaikowania +PARTIALPASTE_RAW_FALSECOLOR;Tłumienie fałszowania koloru +PARTIALPASTE_RAW_LMMSEITERATIONS;Kroki poprawy LMMSE +PARTIALPASTE_RESIZE;Zmiana rozmiaru +PARTIALPASTE_RGBCURVES;Krzywe RGB +PARTIALPASTE_ROTATION;Obrót +PARTIALPASTE_SHADOWSHIGHLIGHTS;Cienie/Podświetlenia +PARTIALPASTE_SHARPENEDGE;Krawędzie +PARTIALPASTE_SHARPENING;Wyostrzanie +PARTIALPASTE_SHARPENMICRO;Mikrokontrast +PARTIALPASTE_VIBRANCE;Jaskrawość +PARTIALPASTE_VIGNETTING;Korekcja winietowania +PARTIALPASTE_WHITEBALANCE;Balans bieli +PREFERENCES_ADD;Dodaj +PREFERENCES_APPLNEXTSTARTUP;wymaga ponownego uruchomienia +PREFERENCES_AUTOMONPROFILE;Automatycznie użyj systemowego profilu monitora +PREFERENCES_BATCH_PROCESSING;Przetwarzanie wsadowe +PREFERENCES_BEHADDALLHINT;Ustaw wszystkie narzędzia w tryb Dodaj.\nZmiany parametrów w panelu edycji zbiorczej zostaną traktowane jako różnicę do poprzednich wartości. +PREFERENCES_BEHADDALL;'Dodaj' wszystkie +PREFERENCES_BEHAVIOR;Zachowanie +PREFERENCES_BEHSETALLHINT;Ustaw wszystkie narzędzia w tryb Ustaw.\nZmiany parametrów w panelu edycji zbiorczej zostaną traktowane jako absolutne, nie biorąc pod uwagę poprzednich wartości. +PREFERENCES_BEHSETALL;'Ustaw' wszystkie +PREFERENCES_BLACKBODY;Wolfram +PREFERENCES_CACHECLEARALL;Wyczyść wszystko +PREFERENCES_CACHECLEARPROFILES;Wyczyść profile +PREFERENCES_CACHECLEARTHUMBS;Wyczyść miniaturki +PREFERENCES_CACHEMAXENTRIES;Maksymalna liczba wpisów w pamięci podręcznej +PREFERENCES_CACHEOPTS;Opcje pamięci podręcznej +PREFERENCES_CACHETHUMBHEIGHT;Maksymalna wysokość miniatury +PREFERENCES_CIEART;CIECAM02 optymalizacja +PREFERENCES_CIEART_LABEL;Użyj precyzję zmiennoprzecinkową zamiast podwójną. +PREFERENCES_CIEART_TOOLTIP;Gdy umożliwione, kalkulacje CIECAM02 są wykonywane w notacji zmiennoprzecinkowej o pojedyńczej precyzji zamiast podwójnej. Skraca to czas egzekucji kosztem nieistotnej zmiany w jakości. +PREFERENCES_CLIPPINGIND;Pokazywanie obciętych prześwietleń/cieni +PREFERENCES_CLUTSDIR;Folder obrazów HaldCLUT +PREFERENCES_CMETRICINTENT;Sposób odwzorowania barw +PREFERENCES_CUSTPROFBUILDHINT;Plik wykonywalny (lub skrypt) uruchamiany kiedy trzeba wygenerować profil przetwarzania dla zdjęcia.\n\nScieżka pliku nośnego (w stylu *.ini czyli sekcje i klucze/parametry) występuje jako parametr wiersza poleceń. Plik ten zawiera przeróżne parametry oraz dane Exif dzięki którym odpowiedni program bądź skrypt może wygenerować plik PP3 według reguł.\n\nUWAGA: Twoją odpowiedzialnością jest prawidłowe użycie cudzysłowiów w przypadku ścieżek zawierających spacje i znaki specjalne. +PREFERENCES_CUSTPROFBUILDKEYFORMAT;Rodzaj kluczy +PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME;Nazwa +PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;TagID +PREFERENCES_CUSTPROFBUILDPATH;Ścieżka pliku wykonywalnego +PREFERENCES_CUSTPROFBUILD;Zewnętrzny kreator profilów przetwarzania +PREFERENCES_CUTOVERLAYBRUSH;Kolor/przezroczystość maski kadrowania +PREFERENCES_D50;5000K +PREFERENCES_D55;5500K +PREFERENCES_D60;6000K +PREFERENCES_D65;6500K +PREFERENCES_DARKFRAMEFOUND;Znaleziono +PREFERENCES_DARKFRAMESHOTS;zdjęć(ia) +PREFERENCES_DARKFRAMETEMPLATES;szablonów(ny) +PREFERENCES_DARKFRAME;Czarna klatka +PREFERENCES_DATEFORMATHINT;Dozwolone są następujące kody formatujące:\n%y - rok\n%m - miesiąc\n%d - dzień\n\nNa przykład według standardu ISO 8601 format daty wygląda następująco:\n%y-%m-%d +PREFERENCES_DATEFORMAT;Format daty +PREFERENCES_DEFAULTLANG;Domyślny język +PREFERENCES_DEFAULTTHEME;Domyślny temat +PREFERENCES_DIRDARKFRAMES;Katalog z czarnymi klatkami +PREFERENCES_DIRHOME;Katalog domowy +PREFERENCES_DIRLAST;Ostatnio odwiedzony katalog +PREFERENCES_DIROTHER;Inny +PREFERENCES_DIRSELECTDLG;Wybierz katalog z obrazami po uruchomieniu... +PREFERENCES_DIRSOFTWARE;Katalog instalacyjny +PREFERENCES_EDITORCMDLINE;Inna linia poleceń +PREFERENCES_EDITORLAYOUT;Układ edytora +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_FLATFIELDFOUND;Znaleziono +PREFERENCES_FLATFIELDSDIR;Katalog z pustymi polami +PREFERENCES_FLATFIELDSHOTS;kadry +PREFERENCES_FLATFIELDTEMPLATES;szablony +PREFERENCES_FLATFIELD;Puste pole +PREFERENCES_FLUOF2;Fluorescent F2 +PREFERENCES_FLUOF7;Fluorescent F7 +PREFERENCES_FLUOF11;Fluorescent F11 +PREFERENCES_FORIMAGE;Dla zdjęć innych niż raw +PREFERENCES_FORRAW;Dla zdjęć raw +PREFERENCES_GIMPPATH;Katalog, w którym zainstalowany jest GIMP +PREFERENCES_GREY05;Yb=05 CIE L#30 +PREFERENCES_GREY10;Yb=10 CIE L#40 +PREFERENCES_GREY15;Yb=15 CIE L#45 +PREFERENCES_GREY18;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_GREY;Luminancja Yb urządzenia wyjściowego (%) +PREFERENCES_HISTOGRAMPOSITIONLEFT;Histogram w lewym panelu +PREFERENCES_HISTOGRAMWORKING;Zastosuj profil roboczy do obliczenia głównego histogramu i Nawigatora +PREFERENCES_HISTOGRAM_TOOLTIP;Jeśli opcja jest włączona profil roboczy jest użyty do obliczenia głównego histogramu oraz panelu Nawigatora, inaczej profil wyjściowy z korektą gamma zostanie użyty. +PREFERENCES_HLTHRESHOLD;Próg dla prześwietleń +PREFERENCES_ICCDIR;Katalog z profilami koloru ICC +PREFERENCES_IMPROCPARAMS;Domyślne parametry przetwarzania obrazu +PREFERENCES_INTENT_ABSOLUTE;Absolutnie kolorymetryczny +PREFERENCES_INTENT_PERCEPTUAL;Percepcyjny +PREFERENCES_INTENT_RELATIVE;Względnie kolorymetryczny +PREFERENCES_INTENT_SATURATION;Nasyceniowy +PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Pokaż osadzoną miniaturę JPEG jeśli plik raw jest nieedytowany +PREFERENCES_LANGAUTODETECT;Użyj języka systemowego +PREFERENCES_MENUGROUPEXTPROGS;Grupuj "Otwórz za pomocą" +PREFERENCES_MENUGROUPFILEOPERATIONS;Grupuj operacje plików +PREFERENCES_MENUGROUPLABEL;Grupuj operacje etykiet +PREFERENCES_MENUGROUPPROFILEOPERATIONS;Grupuj operacje profili przetwarzania +PREFERENCES_MENUGROUPRANK;Grupuj operacje oceny +PREFERENCES_MENUOPTIONS;Opcje menu +PREFERENCES_METADATA;Metadane +PREFERENCES_MONITORICC;Profil monitora +PREFERENCES_MULTITABDUALMON;Tryb wielu zakładek (na drugim monitorze jeśli dostępny) +PREFERENCES_MULTITAB;Tryb wielu zakładek +PREFERENCES_NAVGUIDEBRUSH;Kolor ramki Nawigatora +PREFERENCES_OUTDIRFOLDERHINT;Umieszcza zapisywane zdjęcia w wybranym katalogu +PREFERENCES_OUTDIRFOLDER;Zapisz do katalogu +PREFERENCES_OUTDIRTEMPLATEHINT;Dozwolone są następujące kody formatujące:\n%f, %d1, %d2, ..., %p1, %p2, ..., %r, %s1, %s2, ...\n\nKody formatujące odnoszą się do różnych elementów ścieżki zdjęcia, atrybutów zdjęcia oraz do arbitralnego ciągu numerycznego operacji wsadowej.\n\nPrzykładowo, jeśli zdjęcie obrabiane ma następującą ścieżkę:\n/home/andrzej/zdjecia/2010-10-31/dsc0042.nef\nznaczenie kodów formatujących jest następujące:\n%d4 = home\n%d3 = andrzej\n%d2 = zdjecia\n%d1 = 2010-10-31\n%f = dsc0042\n%p1 = /home/tom/photos/2010-10-31/\n%p2 = /home/andrzej/zdjecia/\n%p3 = /home/andrzej/\n%p4 = /home/\n\n%r zostanie zastąpione oceną zdjęcia. Jeśli zdjęcie nie posiada oceny, %r zostanie zastąpione liczbą '0'. Jeśli zdjęcie leży w śmietniku, %r zostanie zastąpione znakiem 'x'.\n\n%s1, %s2, etc. zostanie zastąpione ciągniem numerycznym dopełnionym od jednej do dziewięciu cyfr. Ciąg ten zostanie rozpocznięty od "1" za każdym razem gdy kolejka przetwarzania zostanie uruchomiona, i liczba jest zwiększona o "1" dla każdego zapisanego obrazu.\n\nJeśli chcesz zapisać obraz wyjściowy obok obrazu wejściowego, napisz:\n%p1/%f\n\nJeśli chcesz zapisać obraz wyjściowy w folderze o nazwie "wywolane" znajdującego się w katalogu zawierającym otwarty obraz, napisz:\n%p1/wywolane/%f\n\nJeśli chcesz zapisać obraz wyjściowy w folderze o nazwie "/home/andrzej/zdjecia/wywolane/2010-10-31", napisz:\n%p2/wywolane/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Użyj schemat +PREFERENCES_OUTDIR;Katalog wyjściowy +PREFERENCES_OVERLAY_FILENAMES;Nakładaj nazwy pliku na miniatury +PREFERENCES_OVERWRITEOUTPUTFILE;Nadpisuj istniejące pliki +PREFERENCES_PANFACTORLABEL;Współczynnik +PREFERENCES_PARSEDEXTADDHINT;Proszę wprowadzić rozszerzenie i zatwierdzić przyciskiem, by dodać do listy +PREFERENCES_PARSEDEXTADD;Dodaj rozszerzenie +PREFERENCES_PARSEDEXTDELHINT;Skasuje wybrane rozszerzenie z listy +PREFERENCES_PARSEDEXT;Przetwarzane rozszerzenia +PREFERENCES_PROFILEHANDLING;Obsługa profili +PREFERENCES_PROFILELOADPR;Priorytet wczytywania profilu +PREFERENCES_PROFILEPRCACHE;Profil w pamięci podręcznej +PREFERENCES_PROFILEPRFILE;Profil przy pliku wejściowym +PREFERENCES_PROFILESAVECACHE;Zapisz parametry przetwarzania w pamięci podręcznej +PREFERENCES_PROFILESAVEINPUT;Zapisz parametry przetwarzania obok pliku wejściowego +PREFERENCES_PROPERTY;Własność +PREFERENCES_PSPATH;Katalog w którym zainstalowany jest Adobe Photoshop +PREFERENCES_RGBDTL_LABEL;Maksymalna ilość wątków redukcji szumów +PREFERENCES_RGBDTL_TOOLTIP;Redukcja szumów potrzebuje około 128MB RAMu dla zdjęcia 10Mpix oraz 512MB dla zdjęcia 40Mpix, i dodatkowo 128MB dla każdego wątku. Im większa liczba równoległych wątków, tym krótszy czas egzekucji. Zostawienie ustawienia na "0" automatycznie użyje tyle wątków, ile możliwe. +PREFERENCES_SELECTFONT;Wybierz czcionkę +PREFERENCES_SELECTLANG;Wybierz język +PREFERENCES_SELECTTHEME;Wybierz temat +PREFERENCES_SET;Ustaw +PREFERENCES_SHOWBASICEXIF;Pokaż podstawowe dane Exif +PREFERENCES_SHOWDATETIME;Pokaż datę i czas +PREFERENCES_SHOWEXPOSURECOMPENSATION;Pokaż korektę ekspozycji +PREFERENCES_SHTHRESHOLD;Próg dla niedoświetleń +PREFERENCES_SINGLETABVERTAB;Tryb pojedynczej zakładki, pionowy układ +PREFERENCES_SINGLETAB;Tryb pojedynczej zakładki +PREFERENCES_SLIMUI;Wąskie suwaki +PREFERENCES_SND_BATCHQUEUEDONE;Zakończono przetwarzanie wsadowe +PREFERENCES_SND_HELP;Należy wprowadzić ścieżkę do pliku, bądź pozostawić niewypełnione (brak dźwięków).\nW systemie Windows można stosować "SystemDefault", "SystemAsterisk" itp. dla dźwięków systemowych.\nW systemie Linux można stosować "complete", "window-attention" etc. dla dzwięków systemowych. +PREFERENCES_SND_LNGEDITPROCDONE;Praca edytora wykonana +PREFERENCES_SND_TRESHOLDSECS;po sekundach +PREFERENCES_STARTUPIMDIR;Katalog startowy +PREFERENCES_TAB_BROWSER;Przeglądarka plików +PREFERENCES_TAB_COLORMGR;Zarządzanie kolorami +PREFERENCES_TAB_GENERAL;Ogólne +PREFERENCES_TAB_IMPROC;Przetwarzanie obrazu +PREFERENCES_TAB_PERFORMANCE;Wydajność +PREFERENCES_TAB_SOUND;Dźwięki +PREFERENCES_TP_LABEL;Panel narzędzi: +PREFERENCES_TP_USEICONORTEXT;Uzyj ikon w zakładkach zamiast tekstowych etykiet +PREFERENCES_TP_VSCROLLBAR;Ukry pionowy pasek przesuwania +PREFERENCES_TUNNELMETADATA;Skopiuj niezmienione IPTC/XMP do pliku wynikowego (gdy tagowane za pomocą innego programu) +PREFERENCES_USEBUNDLEDPROFILES;Użyj załączone profile przetwarzania +PREFERENCES_USESYSTEMTHEME; Użyj tematu systemowego +PREFERENCES_VIEW;Balans bieli urządzenia wyjściowego (monitora, TV, projektora, widowni, etc.) +PREFERENCES_WORKFLOW;Tok pracy +PROFILEPANEL_COPYPPASTE;Parametry do skopiowania +PROFILEPANEL_GLOBALPROFILES;Załączone profile przetwarzania +PROFILEPANEL_LABEL;Profil przetwarzania +PROFILEPANEL_LOADDLGLABEL;Wczytaj profil przetwarzania końcowego... +PROFILEPANEL_LOADPPASTE;Parametry do załadowania +PROFILEPANEL_MODE_TIP;Tryb wypełnienia parametrów przetwarzania.\n\nWduszone: częściowe profile zostaną przetworzone w profile pełne; brakujące wartości zostana wypełnione domyślnymi, zakodowanymi w silniku RawTherapee.\n\nWyłączone: profile zostaną zastosowane takie, jakie są, zmieniając tylko te wartości, które zawierają. +PROFILEPANEL_MYPROFILES;Moje profile przetwarzania +PROFILEPANEL_PASTEPPASTE;Parametry do wklejenia +PROFILEPANEL_PCUSTOM;Własny +PROFILEPANEL_PFILE;Z pliku +PROFILEPANEL_PINTERNAL;Neutralny +PROFILEPANEL_PLASTSAVED;Ostatnio zapisany +PROFILEPANEL_SAVEDLGLABEL;Zapisz profil przetwarzania... +PROFILEPANEL_SAVEPPASTE;Parametry do zapisania +PROFILEPANEL_TOOLTIPCOPY;Skopiuj aktualny profil do schowka +PROFILEPANEL_TOOLTIPLOAD;Ładuj profil z pliku.\nCtrl+klik aby wybrać parametry do ładowania. +PROFILEPANEL_TOOLTIPPASTE;Wklej profil ze schowka.\nCtrl+klik aby wybrać parametry do wklejenia. +PROFILEPANEL_TOOLTIPSAVE;Zapisz aktualny profil.\nCtrl+klik aby wybrać parametry do zapisania. +PROGRESSBAR_LOADINGTHUMBS;Wczytywanie miniatur... +PROGRESSBAR_LOADING;Wczytywanie obrazu... +PROGRESSBAR_LOADJPEG;Ładowanie pliku JPEG... +PROGRESSBAR_LOADPNG;Ładowanie pliku PNG... +PROGRESSBAR_LOADTIFF;Ładowanie pliku TIFF... +PROGRESSBAR_NOIMAGES;Nie znaleziono żadnych obrazów +PROGRESSBAR_PROCESSING;Przetwarzanie obrazu... +PROGRESSBAR_PROCESSING_PROFILESAVED;Zapisano profil przetwarzania +PROGRESSBAR_READY;Gotowe +PROGRESSBAR_SAVEJPEG;Zapisywanie pliku JPEG... +PROGRESSBAR_SAVEPNG;Zapisywanie pliku PNG... +PROGRESSBAR_SAVETIFF;Zapisywanie pliku TIFF... +PROGRESSBAR_SNAPSHOT_ADDED;Dodano migawkę +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profil zmieniony w przeglądarce +QINFO_ISO;ISO +QINFO_NOEXIF;Dane Exif niedostępne. +SAVEDLG_AUTOSUFFIX;Automatycznie dodaj przyrostek, jeżeli plik już istnieje +SAVEDLG_FILEFORMAT;Format pliku +SAVEDLG_FORCEFORMATOPTS;Wymuś opcje zapisu +SAVEDLG_JPEGQUAL;Jakość JPEG +SAVEDLG_PNGCOMPR;Kompresja PNG +SAVEDLG_PUTTOQUEUEHEAD;Umieść na początku kolejki przetwarzania +SAVEDLG_PUTTOQUEUETAIL;Umieść na końcu kolejki przetwarzania +SAVEDLG_PUTTOQUEUE;Umieść w kolejce przetwarzania +SAVEDLG_SAVEIMMEDIATELY;Zapisz natychmiast +SAVEDLG_SAVESPP;Zapisz parametry przetwarzania wraz z obrazem +SAVEDLG_SUBSAMP;Subsampling +SAVEDLG_SUBSAMP_1;Najlepsza kompresja +SAVEDLG_SUBSAMP_2;Pomiędzy +SAVEDLG_SUBSAMP_3;Najlepsza jakość +SAVEDLG_SUBSAMP_TOOLTIP;Najlepsza kompresja: 4:1:1\nPomiędzy: 4:2:2\nNajlepsza jakość: 4:4:4 +SAVEDLG_TIFFUNCOMPRESSED;Nieskompresowany TIFF +SAVEDLG_WARNFILENAME;Plik zostanie nazwany +SHCSELECTOR_TOOLTIP;Kliknij prawym przyciskiem myszki aby zresetować poycję trzech suwaków. +THRESHOLDSELECTOR_BL;Dolny lewy +THRESHOLDSELECTOR_BR;Dolny prawy +THRESHOLDSELECTOR_B;Dolny +THRESHOLDSELECTOR_HINT;Użyj Shift aby przesuwać poszczególne punkty kontrolne. +THRESHOLDSELECTOR_TL;Górny lewy +THRESHOLDSELECTOR_TR;Górny prawy +THRESHOLDSELECTOR_T;Top +TOOLBAR_TOOLTIP_CROP;Kadruj.\nSkrót: c\nMożna przesuwać obszar kadrowania za pomocą Shift-przeciągnięcia myszki +TOOLBAR_TOOLTIP_HAND;Przesuń.\nSkrót: h +TOOLBAR_TOOLTIP_STRAIGHTEN;Wyprostuj / obróć.\nSkrót: s\n\nWyznacz pionową lub poziomą poprzez narysowanie linii prowadnicy na podglądzie. Kąt obrotu zostanie pokazany obok linii prowadnicy. Punktem obrotu jest geometryczny środek obrazu. +TOOLBAR_TOOLTIP_WB;Wskaż balans bieli.\nSkrót: w +TP_BWMIX_ALGO;Algorytm PZCRM +TP_BWMIX_ALGO_LI;Liniowy +TP_BWMIX_ALGO_SP;Efekty specjalne +TP_BWMIX_ALGO_TOOLTIP;Liniowy: mieszanie kanałów liniowo.\nEfekty specjalne: kanały zostaną mieszane nieliniowo. +TP_BWMIX_AUTOCH;Auto +TP_BWMIX_AUTOCH_TIP;Oblicza wartości optymalizacji mieszacza kanałów. +TP_BWMIX_CC_ENABLED;Dopasuj barwy dopełniające +TP_BWMIX_CC_TOOLTIP;Włącz aby umożliwić automatyczne dopasowanie barw dopełniających w trybie CPŻZCNPM. +TP_BWMIX_CHANNEL;Ekwalizator luminancji +TP_BWMIX_CURVEEDITOR1;Krzywa 'Przed' +TP_BWMIX_CURVEEDITOR2;Krzywa 'Po' +TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Krzywa po konwersji obrazu na czarnobiały. +TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Krzywa przed konwersją obrazu na czarnobiały.\nWspółczynniki koloru mogą mieć wpływ. +TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Luminancja według odcieni (hue) L=f(H).\nNależy zwrócić uwagę na ekstremalne ustawienia ponieważ mogą pojawić się zniekształcenia sygnału w obrazie. +TP_BWMIX_FILTER;Filtr barwny +TP_BWMIX_FILTER_BLUEGREEN;Niebieski-Zielony +TP_BWMIX_FILTER_BLUE;Niebieski +TP_BWMIX_FILTER_GREENYELLOW;Zielony-Żółty +TP_BWMIX_FILTER_GREEN;Zielony +TP_BWMIX_FILTER_NONE;Brak +TP_BWMIX_FILTER_PURPLE;Purpurowy +TP_BWMIX_FILTER_REDYELLOW;Czerwony-Żółty +TP_BWMIX_FILTER_RED;Czerwony +TP_BWMIX_FILTER_TOOLTIP;Filtr barwny symuluje działanie prawdziwego filtru barwnego usytuowanego przed obiektywem. Filtry barwne obniżają transmitancję specyficznych kolorów a zatem mają wpływ na ich jasność, np. filtr czerwony przyciemnia niebieskie niebo. +TP_BWMIX_FILTER_YELLOW;Żółty +TP_BWMIX_GAMMA;Korekcja gamma +TP_BWMIX_GAM_TOOLTIP;Korekcja gamma dla każdego kanału RGB. +TP_BWMIX_LABEL;Czarno-Biały +TP_BWMIX_MET;Metoda +TP_BWMIX_MET_CHANMIX;Mieszacz kanałów +TP_BWMIX_MET_DESAT;Desaturacja +TP_BWMIX_MET_LUMEQUAL;Ekwalizator luminancji +TP_BWMIX_MIXC;Mieszacz +TP_BWMIX_NEUTRAL;Zresetuj mieszacz +TP_BWMIX_NEUTRAL_TIP;Zresetuj wszystkie wartości (filtru barwnego, mieszacza kanałów) na domyślne. +TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +TP_BWMIX_RGBLABEL_HINT;Ostateczne wartości RGB które uwzględniają wszystkie opcje mieszacza.\n"Total" wyświetla sumę wartości RGB:\n- zawsze 100% w trybie relatywnym,\n- ponad (jaśniej) lub poniżej (ciemniej) 100% w trybie absolutnym. +TP_BWMIX_RGB_TOOLTIP;Miesza kanały RGB. Kieruj się gotowymi ustawieniami.\nNależy zwrócić uwagę na ujemne wartości ponieważ mogą pojawić się zniekształcenia sygnału w obrazie lub działać w sposób nieprzewidywalny. +TP_BWMIX_SETTING;Gotowe ustawienia +TP_BWMIX_SETTING_TOOLTIP;Różne gotowe ustawienia (klisza, krajobraz, etc.) oraz ręcznie ustawienia mieszacza kanałów. +TP_BWMIX_SET_HIGHCONTAST;Wysoki kontrast +TP_BWMIX_SET_HIGHSENSIT;Wysoka czułość +TP_BWMIX_SET_HYPERPANCHRO;Hyper Panchromatic +TP_BWMIX_SET_INFRARED;Podczerwień +TP_BWMIX_SET_LANDSCAPE;Krajobraz +TP_BWMIX_SET_LOWSENSIT;Niska czułość +TP_BWMIX_SET_LUMINANCE;Luminancja +TP_BWMIX_SET_NORMCONTAST;Normalny kontrast +TP_BWMIX_SET_ORTHOCHRO;Orthochromatic +TP_BWMIX_SET_PANCHRO;Panchromatic +TP_BWMIX_SET_PORTRAIT;Portret +TP_BWMIX_SET_RGBABS;Absolutny RGB +TP_BWMIX_SET_RGBREL;Relatywny RGB +TP_BWMIX_SET_ROYGCBPMABS;Absolutny CPŻZCNPM +TP_BWMIX_SET_ROYGCBPMREL;Relatywny CPŻZCNPM +TP_BWMIX_TCMODE_FILMLIKE;B&W Klisza +TP_BWMIX_TCMODE_SATANDVALBLENDING;B&W Mieszanie Nasycenia i Mocy Światła Białego +TP_BWMIX_TCMODE_STANDARD;B&W Standardowa +TP_BWMIX_TCMODE_WEIGHTEDSTD;B&W Ważona Standardowa +TP_BWMIX_VAL;L +TP_CACORRECTION_BLUE;Niebieski +TP_CACORRECTION_LABEL;Korekcja aberracji chromatycznej +TP_CACORRECTION_RED;Czerwony +TP_CHMIXER_BLUE;Niebieski +TP_CHMIXER_GREEN;Zielony +TP_CHMIXER_LABEL;Mieszacz kanałów +TP_CHMIXER_RED;Czerwony +TP_CHROMATABERR_LABEL;Aberracja chromatyczna +TP_COARSETRAF_TOOLTIP_HFLIP;Odbij w poziomie +TP_COARSETRAF_TOOLTIP_ROTLEFT;Obróć w lewo.\n\nSkróty:\n[ - Tryb wielu zakładek,\nAlt-[ - Tryb jednej zakładki. +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Obróć w prawo.\n\nSkróty:\n] - Tryb wielu zakładek,\nAlt-] - Tryb jednej zakładki. +TP_COARSETRAF_TOOLTIP_VFLIP;Odbij w pionie +TP_COLORAPP_ADAPTSCENE;Luminancji sceny +TP_COLORAPP_ADAPTSCENE_TOOLTIP;Bezwzględna luminancja sceny (cd/m²).\n1)Obliczona za pomocą Exif:\nCzas naświetlania - ISO - Przysłona - Korekcja ekspozycji EV w aparacie.\n2)Obliczona również na podstawie punktu bieli raw oraz korekty ekspozycji w RawTherapee +TP_COLORAPP_ADAPTVIEWING;Luminancji widowni (cd/m²) +TP_COLORAPP_ADAPTVIEWING_TOOLTIP;Bezwzględna luminancja widowni\n(zazwyczaj 16cd/m²). +TP_COLORAPP_ADAP_AUTO_TOOLTIP;Jesli zaznaczone (polecamy), RawTherapee obliczy optymalną wartość na podstawie Exif.\nAby ustawic wartość ręcznie, należy wpierw odznaczyc pudło. +TP_COLORAPP_ALGO;Algorytm +TP_COLORAPP_ALGO_ALL;Wszystkie +TP_COLORAPP_ALGO_JC;Światłość + Chroma (JC) +TP_COLORAPP_ALGO_JS;Światłość + Nasycenie (JS) +TP_COLORAPP_ALGO_QM;Jasność + Barwistość (QM) +TP_COLORAPP_ALGO_TOOLTIP;Umożliwia wybór wszystkich parametrów lub ich podzespół. +TP_COLORAPP_BADPIXSL;Filtr pikseli gorących/uszkodzonych +TP_COLORAPP_BADPIXSL_TOOLTIP;Usuwanie gorących/uszkodzonych (świecących) pikseli.\n0 = Wyłączone\n1 = Metodą Mediana\n2 = Metodą Gaussa.\nMożna również dostroić zdjęcie tak, aby unikać bardzo ciemnych miejsc.\n\nTe anomalie wynikają z limitacji CIECAM02. +TP_COLORAPP_BRIGHT;Jasność (Q) +TP_COLORAPP_BRIGHT_TOOLTIP;Jasność w CIECAM02 bierze pod uwagę luminancję bieli i różni się od jasności L*a*b* oraz RGB. +TP_COLORAPP_CHROMA;Chroma (C) +TP_COLORAPP_CHROMA_M;Barwistość (M) +TP_COLORAPP_CHROMA_M_TOOLTIP;Barwistość w CIECAM02 różni się od barwistości L*a*b* oraz RGB. +TP_COLORAPP_CHROMA_S;Nasycenie (S) +TP_COLORAPP_CHROMA_S_TOOLTIP;Nasycenie w CIECAM02 różni się od nasycenia L*a*b* oraz RGB. +TP_COLORAPP_CHROMA_TOOLTIP;Chroma w CIECAM02 różni się od chromy L*a*b* oraz RGB. +TP_COLORAPP_CIECAT_DEGREE;Adaptacja CAT02 +TP_COLORAPP_CONTRAST;Kontrast (J) +TP_COLORAPP_CONTRAST_Q;Kontrast (Q) +TP_COLORAPP_CONTRAST_Q_TOOLTIP;Kontrast w CIECAM02 dla suwaka Q różni się od kontrastu L*a*b* oraz RGB. +TP_COLORAPP_CONTRAST_TOOLTIP;Kontrast w CIECAM02 dla suwaka J różni się od kontrastu L*a*b* oraz RGB. +TP_COLORAPP_CURVEEDITOR1;Krzywa tonalna 1 +TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Pokazuje histogram L* (L*a*b*) przed CIECAM02.\nJeśli opcja "Pokaż histogramy wyjściowe CIECAM02 za krzywymi" jest włączona, pokazuje histogram J i Q po CIECAM02.\n\nJ i Q nie są pokazywane w głównym histogramie.\n\nEfekt końcowy jest przedstawiony w głównym histogramie. +TP_COLORAPP_CURVEEDITOR2;Krzywa tonalna 2 +TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Tak samo działa jak krzywa tonalna 1. +TP_COLORAPP_CURVEEDITOR3;Krzywa koloru +TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Ustawienie chromy, nasycenia bądź barwistości.\n\nPokazuje histogram chromatyczności (L*a*b*) przed CIECAM02.\nJeśli opcja "Pokaż histogramy wyjściowe CIECAM02 za krzywymi" jest włączona, pokazuje histogram C, s bądź M po CIECAM02.\n\nC, s oraz M nie są pokazywane w głównym histogramie.\nEfekt końcowy jest przedstawiony w głównym histogramie. +TP_COLORAPP_DATACIE;Pokaż histogramy wyjściowe CIECAM02 za krzywymi +TP_COLORAPP_DATACIE_TOOLTIP;Kiedy opcja jest włączona, histogramy za krzywymi CIECAM02 pokazują przybliżone wartości/zakresy J lub Q, oraz C, s lub M po korekcjach CIECAM02.\nTen wybór nie ma wpływu na główny histogram.\n\nKiedy opcja jest wyłączona, histogramy za krzywymi CIECAM02 pokazują wartości L*a*b* przed korekcjami CIECAM02. +TP_COLORAPP_DEGREE_AUTO_TOOLTIP;Jeśli opcja jest zaznaczona (zalecane), RawTherapee kalkuluje wartość optymalną, która jest potem użyta przez CAT02 oraz przez całość CIECAM02.\nAby ustawić wartość ręcznie, odznacz wpierw opcję (wartości powyżej 65 zalecane). +TP_COLORAPP_DEGREE_TOOLTIP;Siła CIE Chromatic Adaptation Transform 2002 +TP_COLORAPP_GAMUT;Kontrola gamma (L*a*b*). +TP_COLORAPP_GAMUT_TOOLTIP;Włącz kontrolę gamma w trybie L*a*b*. +TP_COLORAPP_HUE;Odcień (hue, h) +TP_COLORAPP_HUE_TOOLTIP;Odcień (hue, h) - kąt pomiędzy 0° a 360°. +TP_COLORAPP_LABEL;CIE Color Appearance Model 2002 +TP_COLORAPP_LABEL_CAM02;Ustawienia Obrazu +TP_COLORAPP_LABEL_SCENE;Ustawienia Sceny +TP_COLORAPP_LABEL_VIEWING;Własności Widowni +TP_COLORAPP_LIGHT;Światłość (J) +TP_COLORAPP_LIGHT_TOOLTIP;Światłość w CIECAM02 różni się od światłości CIELab oraz RGB +TP_COLORAPP_MODEL;Model PB +TP_COLORAPP_MODEL_TOOLTIP;Model punktu bieli.\n\nBB [RT] + [wyjściowy]:\nBalans bieli RawTherapee jest użyty dla sceny, CIECAM02 jest ustawione na D50, i balans bieli urządzenia wyjściowego ustawiony jest w Ustawieniach > Zarządzanie Kolorami\n\nBB [RT+CAT02] + [wyjściowe]:\nUstawienia balansu bieli RawTherapee są używane przez CAT02, i balans bieli urządzenia wyjściowego jest ustawione w Ustawieniach > Zarządzanie Kolorami. +TP_COLORAPP_RSTPRO;Ochrona odcieni skóry i czerwieni +TP_COLORAPP_RSTPRO_TOOLTIP;Ochrona odcieni skóry i czerwieni (suwaki i krzywe) +TP_COLORAPP_SHARPCIE;- +TP_COLORAPP_SHARPCIE_TOOLTIP;- +TP_COLORAPP_SURROUND;Otoczenie +TP_COLORAPP_SURROUND_AVER;Średnie +TP_COLORAPP_SURROUND_DARK;Ciemne +TP_COLORAPP_SURROUND_DIM;Przyćmione +TP_COLORAPP_SURROUND_EXDARK;Bardzo Ciemne (Cut-sheet) +TP_COLORAPP_SURROUND_TOOLTIP;Zmienia barwy i kolory aby wziąć pod uwagę własności widowni urządzenia wyjściowego.\n\nŚrednie:\nŚrednie światło otoczenia (standardowe). Obraz się nie zmieni.\n\nPrzyćmione:\nPrzyćmione otoczenie (TV). Obraz stanie się troszkę ciemniejszy.\n\nCiemne:\nCiemne otoczenie (projektor). Obraz stanie się jeszczę ciemniejszy.\n\nBardzo Ciemne:\nBardzo ciemne otoczenie (cut-sheet). Obraz stanie się bardzo ciemny. +TP_COLORAPP_SURSOURCE;Ciemne otoczenie +TP_COLORAPP_SURSOURCE_TOOLTIP;Można użyć kiedy np. obraz wejściowy ma ciemne krawędzie. +TP_COLORAPP_TCMODE_BRIGHTNESS;Jasność +TP_COLORAPP_TCMODE_CHROMA;Chroma +TP_COLORAPP_TCMODE_COLORF;Barwistość +TP_COLORAPP_TCMODE_LABEL1;Tryb krzywej 1 +TP_COLORAPP_TCMODE_LABEL2;Tryb krzywej 2 +TP_COLORAPP_TCMODE_LABEL3;Tryb krzywej chromy +TP_COLORAPP_TCMODE_LIGHTNESS;Światłość +TP_COLORAPP_TCMODE_SATUR;Nasycenie +TP_COLORAPP_TONECIE;Tone mapping za pomocą jasności CIECAM02 (Q) +TP_COLORAPP_TONECIE_TOOLTIP;Jeśli ta opcja jest wyłączona, tone mapping odbywa się w przestrzeni kolorów L*a*b*, zaś jeśli jest włączona, w przestrzeni kolorów CIECAM02.\nNarzędzie Tone Mapping musi być włączone aby to utawienie działało. +TP_COLORAPP_WBCAM;BB [RT+CAT02] + [wyjściowy] +TP_COLORAPP_WBRT;BB [RT] + [wyjściowy] +TP_COLORTONING_AB;o C/L +TP_COLORTONING_AUTOSAT;Automatyczna +TP_COLORTONING_BALANCE;Balans +TP_COLORTONING_BY;o C/L +TP_COLORTONING_CHROMAC;Przezroczystość +TP_COLORTONING_COLOR;Kolor +TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;Przezroczystość chromy według luminancji oC=f(L) +TP_COLORTONING_HIGHLIGHT;Podświetlenia +TP_COLORTONING_HUE;Odcień (hue) +TP_COLORTONING_LABEL;Koloryzacja +TP_COLORTONING_LAB;Mieszanie L*a*b* +TP_COLORTONING_LUMAMODE;Zachowaj luminancję +TP_COLORTONING_LUMAMODE_TOOLTIP;Luminancja zostanie zachowana przy zmianie kolorów. +TP_COLORTONING_LUMA;Luminancja +TP_COLORTONING_METHOD;Metoda +TP_COLORTONING_METHOD_TOOLTIP;"Mieszanie L*a*b*", "Suwaki RGB" oraz "Krzywe RGB" stosują interpolację do mieszania kolorów.\n"Balansowanie kolorów (cienie, półcienie, podświetlenia)" oraz "Nasycenie - Dwa Kolory" stosują kolory bezpośrednio.\n\nNarzędzie "Czarno-białe" można używac jednocześnie z narzędziem "Koloryzacji", co umożliwi tonowanie zdjęcia. +TP_COLORTONING_MIDTONES;Półcienie +TP_COLORTONING_NEUTRAL;Zresetuj suwaki +TP_COLORTONING_NEUTRAL_TIP;Zresetuj wszystkie wartości (cienie, półcienie, podświetlenia) na domyślne. +TP_COLORTONING_OPACITY;Przezroczystość +TP_COLORTONING_RGBCURVES;RGB - Krzywe +TP_COLORTONING_RGBSLIDERS;RGB - Suwaki +TP_COLORTONING_SATURATEDOPACITY;Śiła +TP_COLORTONING_SATURATIONTHRESHOLD;Próg +TP_COLORTONING_SA;Ochrona przed przesyceniem +TP_COLORTONING_SHADOWS;Cienie +TP_COLORTONING_SPLITCOCO;Balans kolorów - cienie/półcienie/podświetlenia +TP_COLORTONING_SPLITCO;Cienie/półcienie/podświetlenia +TP_COLORTONING_SPLITLR;Nasycenie - dwa kolory +TP_COLORTONING_STRENGTH;Siła +TP_COLORTONING_STR;Siła +TP_COLORTONING_TWO2;Specjalna chroma 'dwa kolory' +TP_COLORTONING_TWOALL;Specjalna chroma +TP_COLORTONING_TWOBY;Specjalne a* i b* +TP_COLORTONING_TWOCOLOR_TOOLTIP;Standardowa chroma:\nLiniowe mieszanie kanałów, a* = b*.\n\nSpecjalna chroma:\nLiniowe mieszanie kanałów, a* = b*, ale nieograniczone - spróbuj krzywą zagiąc pod przekątną.\n\nSpecialne a* i b*:\nLiniowe nieograniczone mieszanie kanałów z osobnymi krzywymi dla a* i b*. Przeznaczone dla efektów specjalnych.\n\nSpecjalna chroma - dwa kolory:\nBardziej nieprzewidywalne. +TP_COLORTONING_TWOSTD;Standardowa chroma +TP_CROP_FIXRATIO;Zablokuj proporcje +TP_CROP_GTDIAGONALS;Przekątna +TP_CROP_GTEPASSPORT;Paszport biometryczny +TP_CROP_GTFRAME;Ramka +TP_CROP_GTGRID;Siatka +TP_CROP_GTNONE;Nic +TP_CROP_GTRULETHIRDS;Trójpodział +TP_CROP_GUIDETYPE;Typ pomocy: +TP_CROP_H;Wysokość +TP_CROP_LABEL;Kadrowanie +TP_CROP_PPI;PPI= +TP_CROP_SELECTCROP;Wybierz kadr +TP_CROP_W;Szerokość +TP_CROP_X;X +TP_CROP_Y;Y +TP_DARKFRAME_AUTOSELECT;Autowybór +TP_DARKFRAME_LABEL;Czarna klatka +TP_DEFRINGE_LABEL;Usuwanie widma +TP_DEFRINGE_RADIUS;Promień +TP_DEFRINGE_THRESHOLD;Próg +TP_DIRPYRDENOISE_33;3×3 silne +TP_DIRPYRDENOISE_55SOFT;5×5 +TP_DIRPYRDENOISE_55;5×5 silne +TP_DIRPYRDENOISE_77;7×7 (wolne) +TP_DIRPYRDENOISE_BLUE;Chrominancja - Błękit-żółć +TP_DIRPYRDENOISE_CHROMA;Chrominancja - Główna +TP_DIRPYRDENOISE_CURVEEDITOR_L_TOOLTIP;Moduluje działanie usuwania szumów luminancji +TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Działa z obrazami typu raw i nie-raw.\n\nDla obrazów typu raw, działanie redukcji szumów luminancji zależy od gammy wejściowego profilu ICC. Z góry założona jest gamma sRGB, zatem jeśli obraz wejściowy ma profil o innej gammie można się spodziewać zmian w działaniu rekucji szumów luminancji. +TP_DIRPYRDENOISE_ENH;Tryb ulepszony +TP_DIRPYRDENOISE_ENH_TOOLTIP;Ulepsza jakość usuwania szumów kosztem około 20% wzrostu czasu przetwarzania. +TP_DIRPYRDENOISE_GAMMA;Gamma +TP_DIRPYRDENOISE_GAMMA_TOOLTIP;Gamma skupia siłę redukcji szumów na danym predziale zakresu tonalnego. Mniejsze wartości gamma powodują skupienie na ciemniejszych barwach, natomiast większe wartości rozciągną zakres działania również na barwy jasne. +TP_DIRPYRDENOISE_LABEL;Redukcja szumu +TP_DIRPYRDENOISE_LABM;L*a*b* +TP_DIRPYRDENOISE_LCURVE;Krzywa luminancji +TP_DIRPYRDENOISE_LDETAIL;Szczegółowość luminancji +TP_DIRPYRDENOISE_LM;Tylko luminancja +TP_DIRPYRDENOISE_LUMA;Luminacja +TP_DIRPYRDENOISE_MEDMETHOD;Metoda mediana +TP_DIRPYRDENOISE_MEDTYPE;Rodzaj mediana +TP_DIRPYRDENOISE_MED;Filtr Mediana +TP_DIRPYRDENOISE_MED_TOOLTIP;Włącz odszumianie metodą mediana. +TP_DIRPYRDENOISE_METHOD11;Jakość +TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Jakość może zostać dopasowana do wzoru szumów. Ustawienie "wysoka" ulepsza odszumianie około 20% wzrostu czasu przetwarzania. +TP_DIRPYRDENOISE_METHOD;Metoda +TP_DIRPYRDENOISE_METHOD_TOOLTIP;Dla obrazów raw można używać metody RGB oraz L*a*b*.\n\nDla obrazów nie-raw metoda L*a*b* zostanie użyta niezależnie od wyboru. +TP_DIRPYRDENOISE_METM_TOOLTIP;Przy użyciu metod "tylko luminancja" oraz "L*a*b*", filtrowanie mediana zostanie wykonane prosto po funkcji falki w procesie odszumiania.\nW trybie "RGB" filtrowanie to zostanie wykonana pod koniec calego procesu. +TP_DIRPYRDENOISE_MET_TOOLTIP;Zasrosuj filtrowanie mediana o oknie pożądanego rozmiaru. Im większy rozmiar okna, tym dłużej przetwarzanie zajmie.\n\n3x3 miękki: użyje 5 pikseli w zasięgu 1 pikseli.\n3x3: użyje 9 pikseli w zasięgu 1 pikseli.\n5x5 miękki: użyje 13 pikseli w zasięgu 2 pikseli.\n5x5: użyje 25 pikseli w zasięgu 2 pikseli.\n7x7: użyje 49 pikseli w zasięgu 3 pikseli.\n\nCzasem można uzyskać wyższą jakość wielokrotnym powtórzeniem filtru przy użyciu małego okna niz przy jednokrotnym przetworzeniu przy użyciu dużego okna. +TP_DIRPYRDENOISE_PASSES;Liczba powtórzeń mediana +TP_DIRPYRDENOISE_PASSES_TOOLTIP;Trzykrotne powtórzenie filtru mediana przy użyciu okna o rozmiarze 3x3 często skutkuje wyższą jakością niż jednokrotne z oknem o rozmiarze 7x7. +TP_DIRPYRDENOISE_RED;Chrominancja - Czerwień-zieleń +TP_DIRPYRDENOISE_RGBM;RGB +TP_DIRPYRDENOISE_RGB;RGB +TP_DIRPYRDENOISE_SHALBI;Wysoka +TP_DIRPYRDENOISE_SHAL;Standardowa +TP_DIRPYRDENOISE_SOFT;3x3 +TP_DIRPYREQUALIZER_ALGO;Zakres odcieni skóry +TP_DIRPYREQUALIZER_ALGO_TOOLTIP;- +TP_DIRPYREQUALIZER_HUESKIN;Odcień skóry +TP_DIRPYREQUALIZER_HUESKIN_TOOLTIP;Piramida wyznacza zakres kolorów uważany jako zakres odcieni skóry. Większość odcieni skóry - białej, czarnej, i pomiędzy - ma tę samą odcień. Małe poprawki są dopuszczalne, jednak jeśli potrzebna jest większa zmiana w lewo lub prawo, lub jeśli są widoczne artefakty, to najprawdopobniej balans bieli jest niepoprawny. +TP_DIRPYREQUALIZER_LABEL;Kontrast wg. precyzji detali +TP_DIRPYREQUALIZER_LUMACOARSEST;Zgrubne +TP_DIRPYREQUALIZER_LUMACONTRAST_MINUS;Kontrast- +TP_DIRPYREQUALIZER_LUMACONTRAST_PLUS;Kontrast+ +TP_DIRPYREQUALIZER_LUMAFINEST;Delikatne +TP_DIRPYREQUALIZER_LUMANEUTRAL;Neutralne +TP_DIRPYREQUALIZER_SKIN;Ochrona/celowanie odcieni skóry +TP_DIRPYREQUALIZER_SKIN_TOOLTIP;Przy -100 oddziaływanie efektu odbywa się wyłącznie na odcieniach skóry.\nPrzy 0 oddziaływanie efektu odbywa się jednakowo na wszystkich odcieniach.\nPrzy +100 odcienie skóry są pomijane podczas gdy oddziaływanie odbywa się na wszystkich pozostałych odcieniach. +TP_DIRPYREQUALIZER_THRESHOLD;Próg +TP_DIRPYREQUALIZER_TOOLTIP;Zapobiega artefaktom w strefach przejścia pomiędzy odcieniom skóry (hue, chrominancja, luminancja) a pozostałym odcieniom. +TP_DISTORTION_AMOUNT;Siła +TP_DISTORTION_AUTO;Automatyczna korekcja dystorsji +TP_DISTORTION_AUTO_TIP;(Eksperymentalne) Automatyczna korekcja dystorsji obiektywu dla niektórych aparatów (M4/3, kompakty DC, itp.) +TP_DISTORTION_LABEL;Dystorsja +TP_EPD_EDGESTOPPING;Wyszukiwanie krawędzi +TP_EPD_LABEL;Tone Mapping +TP_EPD_REWEIGHTINGITERATES;Powtarzanie rozważania +TP_EPD_SCALE;Skala +TP_EPD_STRENGTH;Siła +TP_EPD_TOOLTIP;Tone mapping może się odbyć w przestrzeni kolorów L*a*b* (domyślnie) oraz CIECAM02.\n\nAby wykonać tone mapping w przestrzeni CIECAM02 należy włączyć następujące ustawienia:\n1. CIECAM02\n2. Algorytm="Jasność + Barwistość (QM)"\n3. "Tone mapping za pomocą jasności CIECAM02 (Q)" +TP_EXPOSURE_AUTOLEVELS;Wyrównaj poziomy +TP_EXPOSURE_AUTOLEVELS_TIP;Dokonaj automatycznego ustawienia parametrów ekspozycji na podstawie analizy obrazu +TP_EXPOSURE_BLACKLEVEL;Czerń +TP_EXPOSURE_BRIGHTNESS;Jasność +TP_EXPOSURE_CLIP;Przytnij % +TP_EXPOSURE_CLIP_TIP;Ułamek pikseli ktore mają zostać rozjaśnione do punktu prześwietlenia podczas automatycznego wyrównania poziomów. +TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Próg kompresji podświetleń +TP_EXPOSURE_COMPRHIGHLIGHTS;Kompresja podświetleń +TP_EXPOSURE_COMPRSHADOWS;Kompresja cieni +TP_EXPOSURE_CONTRAST;Kontrast +TP_EXPOSURE_CURVEEDITOR1;Krzywa Tonalna 1 +TP_EXPOSURE_CURVEEDITOR2;Krzywa Tonalna 2 +TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Więcej informacji na temat optymalnego wykorzystania obu krzywych jest dostępne w podręczniku (RawTherapee Manual) w dziale:\nThe Toolbox > Exposure Tab > Exposure Panel > Tone Curve\n(Narzędzie > Zakładka Ekspozycji > Krzywe Tonalne) +TP_EXPOSURE_CURVEEDITOR;Krzywa tonalna +TP_EXPOSURE_EXPCOMP;Korekcja ekspozycji (EV) +TP_EXPOSURE_LABEL;Ekspozycja +TP_EXPOSURE_SATURATION;Nasycenie +TP_EXPOSURE_TCMODE_FILMLIKE;Klisza +TP_EXPOSURE_TCMODE_LABEL1;Tryb krzywej 1 +TP_EXPOSURE_TCMODE_LABEL2;Tryb krzywej 2 +TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Mieszanie nasycenia i mocy światła białego +TP_EXPOSURE_TCMODE_STANDARD;Standardowa +TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Ważona standardowa +TP_EXPOS_BLACKPOINT_LABEL;Punkt czerni raw +TP_EXPOS_WHITEPOINT_LABEL;Punkt bieli raw +TP_FILMSIMULATION_LABEL;Symulacja Kliszy +TP_FILMSIMULATION_STRENGTH;Siła +TP_FILMSIMULATION_ZEROCLUTSFOUND;Ustaw folder HaldCLUT w Ustawieniach +TP_FLATFIELD_AUTOSELECT;Autowybór +TP_FLATFIELD_BLURRADIUS;Promień rozmycia +TP_FLATFIELD_BLURTYPE;Typ rozmycia +TP_FLATFIELD_BT_AREA;Obszar +TP_FLATFIELD_BT_HORIZONTAL;Poziomy +TP_FLATFIELD_BT_VERTHORIZ;Poziomy + pionowy +TP_FLATFIELD_BT_VERTICAL;Pionowy +TP_FLATFIELD_CLIPCONTROL;Zabezpieczenie przed obcinaniem +TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Funkcja ta chroni przed obcinaniem podświetleń które może zaistnieć przy stosowaniu obrazów type "puste pole". Należy zachować ostrożność, ponieważ jeśli obcięte rejony istnieją przed zastosowaniem pustego pola, funkcja ta może spowodować zabarwienie tych rejonów które powinny być białe. +TP_FLATFIELD_LABEL;Puste pole +TP_GAMMA_CURV;Gamma +TP_GAMMA_FREE;Dowolna gamma +TP_GAMMA_OUTPUT;Wyjściowa gamma +TP_GAMMA_SLOP;Nachylenie (liniowy) +TP_GENERAL_11SCALE_TOOLTIP;Efekty tego narzędzia są widoczne bądź poprawne przy przybliżeniu 100% lub więcej. +TP_GRADIENT_CENTER;Środek +TP_GRADIENT_CENTER_X;Środek X +TP_GRADIENT_CENTER_X_TOOLTIP;Przesuń filtr do lewej (ujemne wartości) lub prawej (dodatne wartości). +TP_GRADIENT_CENTER_Y;Środek Y +TP_GRADIENT_CENTER_Y_TOOLTIP;Przesuń filtr do góry (ujemne wartości) lub do dołu (dodatne wartości). +TP_GRADIENT_DEGREE;Kąt +TP_GRADIENT_DEGREE_TOOLTIP;Kąt obrotu filtra w stopniach. +TP_GRADIENT_FEATHER;Wtapianie +TP_GRADIENT_FEATHER_TOOLTIP;Szerokośc nachylenia zbocza w procentach przekątnej. +TP_GRADIENT_LABEL;Filtr Połówkowy +TP_GRADIENT_STRENGTH;Siła +TP_GRADIENT_STRENGTH_TOOLTIP;Śiła filtru w jednostkach EV. +TP_HLREC_BLEND;Mieszanie +TP_HLREC_CIELAB;Mieszanie koloru CIELab +TP_HLREC_COLOR;Propagacja koloru +TP_HLREC_ENA_TOOLTIP;Może zostać automatycznie włączone w skutek działania automatycznej ekspozycji +TP_HLREC_LABEL;Odzyskiwanie prześwietleń +TP_HLREC_LUMINANCE;Odzyskiwanie luminancji +TP_HLREC_METHOD;Metoda: +TP_HSVEQUALIZER_CHANNEL;Kanał +TP_HSVEQUALIZER_HUE;H +TP_HSVEQUALIZER_LABEL;Ekwalizator HSV +TP_HSVEQUALIZER_SAT;S +TP_HSVEQUALIZER_VAL;V +TP_ICM_BLENDCMSMATRIX;Tłumienie prześwietleń danymi z matrycy +TP_ICM_BLENDCMSMATRIX_TOOLTIP;Włącz odzyskiwanie prześwietlonych regionow jesli profil ICC wykorzystuje LUT (tablicowanie). +TP_ICM_DCPILLUMINANT;Iluminant +TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolowany +TP_ICM_DCPILLUMINANT_TOOLTIP;Wybierz który osadzony iluminant DCP należy użyć. Domyślną opcją jest "interpolowany", czyli wartość jest mieszaniną pomiędzy dwoma osadzonymi wartościami iluminantu zależnie od balansu bieli. Ten wybór jest możliwy jedynie kiedy DCP zawiera dwa iluminanty z możliwościa interpolacji. +TP_ICM_INPUTCAMERAICC;Domyślny aparatu lub ICC +TP_ICM_INPUTCAMERAICC_TOOLTIP;Uzyj profil ICC stworzony specjalnie na potrzeby RawTherapee. Jest bardziej dokładny niż domyślny matrycowy profil ICC, lecz dostępny tylko dla niektórych aparatów. +TP_ICM_INPUTCAMERA;Domyślny aparatu +TP_ICM_INPUTCAMERA_TOOLTIP;Użyj prostej domyślnej matrycy kolorów z DCRAW bądź zapisanej w DNG. +TP_ICM_INPUTCUSTOM;Własny +TP_ICM_INPUTCUSTOM_TOOLTIP;Wczytaj własny profil ICC z pliku. +TP_ICM_INPUTDLGLABEL;Wybierz wejściowy profil ICC... +TP_ICM_INPUTEMBEDDED;Jeśli to możliwe, użyj osadzonego +TP_ICM_INPUTEMBEDDED_TOOLTIP;Użyj profil ICC zapisany w plikach innych niż raw. +TP_ICM_INPUTNONE;Bez profilu +TP_ICM_INPUTNONE_TOOLTIP;Nie używaj żadnego profilu kolorów. Pożyteczne jedynie w wyjątkowych przypadkach. +TP_ICM_INPUTPROFILE;Profil wejściowy +TP_ICM_LABEL;ICM +TP_ICM_NOICM;Brak ICM: Wyjście sRGB +TP_ICM_OUTPUTPROFILE;Profil wyjściowy +TP_ICM_SAVEREFERENCE;Zapisz obraz wzorcowy dla profilowania +TP_ICM_SAVEREFERENCE_TOOLTIP;Zapisz liniowy obraz TIFF zanim profil wejściowy zostanie zastosowany. Obraz ten można użyć do kalibracji oraz do wytworzenia profilu aparatu. +TP_ICM_TONECURVE;Użyj krzywą tonalną z DCP +TP_ICM_TONECURVE_TOOLTIP;Włącz aby użyć krzywą tonalną znajdującą się w profilu DCP. Opcja ta jest tylko aktywna jeśli profil DCP zawiera krzywą tonalną. +TP_ICM_WORKINGPROFILE;Profil roboczy +TP_IMPULSEDENOISE_LABEL;Redukcja Szumów Impulsowych +TP_IMPULSEDENOISE_THRESH;Próg +TP_LABCURVE_AVOIDCOLORSHIFT;Zapobiegaj zmianom koloru +TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Umieszcza kolory w gamie roboczej przestrzeni kolorów i stosuje korektę Munsell'a +TP_LABCURVE_BRIGHTNESS;Światłość +TP_LABCURVE_CHROMATICITY;Chromatyczność +TP_LABCURVE_CHROMA_TOOLTIP;Aby zastosować tonowanie zdjęcia B&W, ustaw chromatyczność na -100. +TP_LABCURVE_CONTRAST;Kontrast +TP_LABCURVE_CURVEEDITOR;Krzywa luminacji +TP_LABCURVE_CURVEEDITOR_A_RANGE1;Zielone Nasycone +TP_LABCURVE_CURVEEDITOR_A_RANGE2;Zielone Pastelowe +TP_LABCURVE_CURVEEDITOR_A_RANGE3;Czerwone Pastelowe +TP_LABCURVE_CURVEEDITOR_A_RANGE4;Czerwone Nasycone +TP_LABCURVE_CURVEEDITOR_B_RANGE1;Niebieskie Nasycone +TP_LABCURVE_CURVEEDITOR_B_RANGE2;Niebieskie Pastelowe +TP_LABCURVE_CURVEEDITOR_B_RANGE3;Żółte Pastelowe +TP_LABCURVE_CURVEEDITOR_B_RANGE4;Żółte Nasycone +TP_LABCURVE_CURVEEDITOR_CC;CC +TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutralne +TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Mętne +TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastelowe +TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Nasycone +TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Chromatyczność według chromatyczności C=f(C). +TP_LABCURVE_CURVEEDITOR_CH;CH +TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromatyczność według odcieni (hue) C=f(H) +TP_LABCURVE_CURVEEDITOR_CL;CL +TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Chromatyczność według luminancji C=f(L) +TP_LABCURVE_CURVEEDITOR_HH;HH +TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Odcień (hue) według odcieni H=f(H) +TP_LABCURVE_CURVEEDITOR_LC;LC +TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminancja według chromatyczności L=f(C) +TP_LABCURVE_CURVEEDITOR_LH;LH +TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Luminance według odcieni (hue) L=f(H) +TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminancja według luminancji L=f(L) +TP_LABCURVE_LABEL;Regulacja L*a*b* +TP_LABCURVE_LCREDSK;Ogranicz LC do odcieni skóry oraz czerwieni +TP_LABCURVE_LCREDSK_TIP;Kiedy opcja jest włączona, wpływ krzywej LC (Luminancja według chromatyczności) jest ograniczony do odcieni skóry oraz czerwieni.\nKiedy opcja jest wyłączona, krzywa LC wpływa na wszystkie barwy. +TP_LABCURVE_RSTPROTECTION;Ochrona skóry oraz czerwieni +TP_LABCURVE_RSTPRO_TOOLTIP;Ma wpływ na suwak Chromatyczności oraz na krzywą CC. +TP_LENSGEOM_AUTOCROP;Auto-kadrowanie +TP_LENSGEOM_FILL;Auto-wypełnienie +TP_LENSGEOM_LABEL;Obiektyw / Geometria +TP_LENSPROFILE_LABEL;Profil korekcji obiektywu LCP +TP_LENSPROFILE_USECA;Korekja aberacji chromatycznej +TP_LENSPROFILE_USEDIST;Korekcja dystorsji +TP_LENSPROFILE_USEVIGN;Korekcja winietowania +TP_NEUTRAL;Neutralne +TP_NEUTRAL_TIP;Zresetuj ustawienia do wartości neutralnych.\nDziała na tych samych suwakach na których funkcja "Wyrównaj poziomy" działa, niezależnie od tego czy funkcja ta była użyta czy nie. +TP_PCVIGNETTE_FEATHER;Wtapianie +TP_PCVIGNETTE_FEATHER_TOOLTIP;Wtapianie:\n0 = tylko brzegi,\n50 = w pół drogi do środka,\n100 = aż do środka. +TP_PCVIGNETTE_LABEL;Winietowanie +TP_PCVIGNETTE_ROUNDNESS;Okrągłość +TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Okrągłość:\n0 = prostokąt,\n50 = dopasowana elipsa,\n100 = okrąg. +TP_PCVIGNETTE_STRENGTH;Śiła +TP_PCVIGNETTE_STRENGTH_TOOLTIP;Siła filtru w kątach w jednostkach EV. +TP_PERSPECTIVE_HORIZONTAL;Pozioma +TP_PERSPECTIVE_LABEL;Perspektywa +TP_PERSPECTIVE_VERTICAL;Pionowa +TP_PFCURVE_CURVEEDITOR_CH;Odcień +TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Ogranicza natężenie usuwania widma według kolorów.\nWyżej = bardziej,\nNiżej = mniej. +TP_PREPROCESS_DEADPIXFILT;Filtr martwych pikseli +TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Łata martwe piksele (pojedyńcze czarne piksele). +TP_PREPROCESS_GREENEQUIL;Wyrównanie zieleni +TP_PREPROCESS_HOTPIXFILT;Filtr gorących pikseli +TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Łata gorące piksele (pojedyńcze świecące, przesycone piksele). +TP_PREPROCESS_LABEL;Przetwarzanie początkowe +TP_PREPROCESS_LINEDENOISE;Filtr zakłóceń liniowych +TP_PREPROCESS_NO_FOUND;Nic nie znaleziono +TP_RAWCACORR_AUTO;Autokorekcja +TP_RAWCACORR_CABLUE;Niebieski +TP_RAWCACORR_CARED;Czerwony +TP_RAWEXPOS_BLACKS;Poziomy czerni +TP_RAWEXPOS_BLACK_0;Zielony 1 (główny) +TP_RAWEXPOS_BLACK_1;Czerwony +TP_RAWEXPOS_BLACK_2;Niebieski +TP_RAWEXPOS_BLACK_3;Zielony 2 +TP_RAWEXPOS_BLACK_BLUE;Niebieski +TP_RAWEXPOS_BLACK_GREEN;Zielony +TP_RAWEXPOS_BLACK_RED;Czerwony +TP_RAWEXPOS_LINEAR;Liniowy współczynnik korekcji +TP_RAWEXPOS_PRESER;Zachowanie prześwietleń +TP_RAWEXPOS_RGB;Czerwony, Zielony, Niebieski +TP_RAWEXPOS_TWOGREEN;Połącz obie zielenie +TP_RAW_DCBENHANCE;Zastosuj poprawę DCB +TP_RAW_DCBITERATIONS;Liczba powtórzeń DCB +TP_RAW_DMETHOD;Metoda +TP_RAW_DMETHOD_PROGRESSBAR;Demozaikowanie %1... +TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Udoskonalanie demozaikowania... +TP_RAW_DMETHOD_TOOLTIP;IGV oraz LMMSE są przeznaczone dla zdjęć raw o wysokim poziomie szumów (wysokie ISO) aby zapobiec utworzeniu się wzorków w kształcie małych labiryntów, posteryzacji oraz mydlanego wyglądu. +TP_RAW_FALSECOLOR;Kroki zapobiegające fałszowaniu kolorów +TP_RAW_LABEL;Demozaikowanie +TP_RAW_LMMSEITERATIONS;Ilość kroków udoskonalenia LMMSE +TP_RAW_LMMSE_TOOLTIP;Aby zmniejszyć ilość artefaktów i poprawić stosunek sygnału do szumów, można wykorzystać następujące ustawienia:\n1: Gamma\n2-4: Średnia mediana\n5-6: Rafinowanie +TP_RAW_SENSOR_BAYER_LABEL;Matryca z filtrem Bayera +TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;Trzy powtórzenia prowadzą do najlepszych rezultatów (zalecane dla zdjęć o niskim ISO).\nJedno powtórzenie jest prawie nie do odróżnienia od trzech dla zdjęć o wysokim ISO a jest znacznie szybsze. +TP_RAW_SENSOR_XTRANS_LABEL;Matryca z filtrem X-Trans +TP_RESIZE_APPLIESTO;Dotyczy: +TP_RESIZE_CROPPEDAREA;Obszaru kadrowanego +TP_RESIZE_FITBOX;Wymiary obwodu +TP_RESIZE_FULLIMAGE;Całego zdjęcia +TP_RESIZE_HEIGHT;Wysokość +TP_RESIZE_H;Wysokość: +TP_RESIZE_LABEL;Zmiana rozmiaru +TP_RESIZE_LANCZOS;Lanczos +TP_RESIZE_METHOD;Metoda: +TP_RESIZE_NEAREST;Najbliższa +TP_RESIZE_SCALE;Skalę +TP_RESIZE_SPECIFY;Określ: +TP_RESIZE_WIDTH;Szerokość +TP_RESIZE_W;Szerokość +TP_RGBCURVES_BLUE;B +TP_RGBCURVES_CHANNEL;Kanał +TP_RGBCURVES_GREEN;G +TP_RGBCURVES_LABEL;Krzywe RGB +TP_RGBCURVES_LUMAMODE;Tryb Luminancji +TP_RGBCURVES_LUMAMODE_TOOLTIP;Tryb Luminancji pozwala na zmianę wpływu kanałów R, G i B na luminancję obrazu bez zmian kolorów. +TP_RGBCURVES_RED;R +TP_ROTATE_DEGREE;Stopnie +TP_ROTATE_LABEL;Obrót +TP_ROTATE_SELECTLINE;Wyprostuj obraz +TP_SAVEDIALOG_OK_TIP;Skrót: Ctrl-Enter +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Podświetlenia +TP_SHADOWSHLIGHTS_HLTONALW;Szerokość tonalna +TP_SHADOWSHLIGHTS_LABEL;Cienie/Podświetlenia +TP_SHADOWSHLIGHTS_LOCALCONTR;Kontrast lokalny +TP_SHADOWSHLIGHTS_RADIUS;Promień +TP_SHADOWSHLIGHTS_SHADOWS;Cienie +TP_SHADOWSHLIGHTS_SHARPMASK;Ostra maska +TP_SHADOWSHLIGHTS_SHTONALW;Szerokość tonalna +TP_SHARPENEDGE_AMOUNT;Siła +TP_SHARPENEDGE_LABEL;Krawędzie +TP_SHARPENEDGE_PASSES;Powtórzenia +TP_SHARPENEDGE_THREE;Tylko luminancja +TP_SHARPENING_AMOUNT;Siła +TP_SHARPENING_EDRADIUS;Promień +TP_SHARPENING_EDTOLERANCE;Tolerancja krawędzi +TP_SHARPENING_HALOCONTROL;Kontrola poświaty +TP_SHARPENING_HCAMOUNT;Siła +TP_SHARPENING_LABEL;Wyostrzanie +TP_SHARPENING_METHOD;Metoda +TP_SHARPENING_ONLYEDGES;Wyostrz tylko krawędzie +TP_SHARPENING_RADIUS;Promień +TP_SHARPENING_RLD;Dekonwolucja RL +TP_SHARPENING_RLD_AMOUNT;Siła +TP_SHARPENING_RLD_DAMPING;Tłumienie +TP_SHARPENING_RLD_ITERATIONS;Powtórzenia +TP_SHARPENING_THRESHOLD;Próg +TP_SHARPENING_TOOLTIP;Kiedy CIECAM02 jest aktywne efekt wyostrzania może ulec drobnym zmianom. W mało prawdopodobnym przypadku zuważenia zmiany wystarczy prystosować suwaki według gustu. +TP_SHARPENING_USM;Maska wyostrzająca +TP_SHARPENMICRO_AMOUNT;Siła +TP_SHARPENMICRO_LABEL;Mikrokontrast +TP_SHARPENMICRO_MATRIX;Matryca 3×3 zamiast 5×5 +TP_SHARPENMICRO_UNIFORMITY;Jednolitość +TP_VIBRANCE_AVOIDCOLORSHIFT;Zapobiegaj przesunięcia kolorów +TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH +TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Odcienie skóry +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Czerwone/Purpurowe +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Czerwone +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Czerwone/Żółte +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Żółte +TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Odcień (hue) według odcieni H=f(H) +TP_VIBRANCE_LABEL;Jaskrawość +TP_VIBRANCE_PASTELS;Odcienie pastelowe +TP_VIBRANCE_PASTSATTOG;Połącz odcienie pastelowe i nasycone +TP_VIBRANCE_PROTECTSKINS;Zachowaj odcienie skóry +TP_VIBRANCE_PSTHRESHOLD;Próg odcieni pastelowych/nasyconych +TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Próg nasycenia +TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;Oś pionowa odpowiada barwą pastelowym na dole oraz nasyconym na górze.\nOś pozioma przedstawia zakres nasycenia. +TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Ważenie przejścia barw pastelowych/nasyconych +TP_VIBRANCE_SATURATED;Odcienie nasycone +TP_VIGNETTING_AMOUNT;Ilość +TP_VIGNETTING_CENTER;Środek +TP_VIGNETTING_CENTER_X;Środek X +TP_VIGNETTING_CENTER_Y;Środek Y +TP_VIGNETTING_LABEL;Korekcja winietowania +TP_VIGNETTING_RADIUS;Promień +TP_VIGNETTING_STRENGTH;Siła +TP_WBALANCE_AUTO;Auto +TP_WBALANCE_CAMERA;Z aparatu +TP_WBALANCE_CLOUDY;Pochmurnie +TP_WBALANCE_CUSTOM;Własny +TP_WBALANCE_DAYLIGHT;Światło dzienne (słonecznie) +TP_WBALANCE_EQBLUERED;Ekwalizator niebieskości/czerwieni +TP_WBALANCE_EQBLUERED_TOOLTIP;Pozwala na odchyłkę od typowego użytku balansu bieli poprzez modulację balansu niebieskości/czerwieni.\nJest to przydatne kiedy:\na) warunki miejsca fotografii są oddalone od standardowego iluminantu (światła o określonych parametrach za pomocą którego kalibruje się profil wejściowy aparatu), np. zdjęcia robione pod wodą,\nb) warunki fotografii są oddalone od warunków pod którymi kalibracje zostały wykonane,\nc) macierze oraz profile ICC/DCP są z jakiegos powodu nieodpowiednie. +TP_WBALANCE_FLASH55;Leica +TP_WBALANCE_FLASH60;Standardowe, Canon, Pentax, Olympus +TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta +TP_WBALANCE_FLASH_HEADER;Flash +TP_WBALANCE_FLUO1;F1 - Światło dzienne +TP_WBALANCE_FLUO2;F2 - Chłodne białe +TP_WBALANCE_FLUO3;F3 - Białe +TP_WBALANCE_FLUO4;F4 - Ciepłe białe +TP_WBALANCE_FLUO5;F5 - Światło dzienne +TP_WBALANCE_FLUO6;F6 - Białe Lite +TP_WBALANCE_FLUO7;F7 - D65 Symulator światła dziennego +TP_WBALANCE_FLUO8;F8 - D50 / Sylvania F40 Design +TP_WBALANCE_FLUO9;F9 - Chłodne białe deluxe +TP_WBALANCE_FLUO10;F10 - Philips TL85 +TP_WBALANCE_FLUO11;F11 - Philips TL84 +TP_WBALANCE_FLUO12;F12 - Philips TL83 +TP_WBALANCE_FLUO_HEADER;Jarzeniowe +TP_WBALANCE_GREEN;Odcień +TP_WBALANCE_GTI;GTI +TP_WBALANCE_HMI;HMI +TP_WBALANCE_JUDGEIII;JudgeIII +TP_WBALANCE_LABEL;Balans bieli +TP_WBALANCE_LAMP_HEADER;Lamp +TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 +TP_WBALANCE_LED_HEADER;LED +TP_WBALANCE_LED_LSI;LSI Lumelex 2040 +TP_WBALANCE_METHOD;Metoda +TP_WBALANCE_SHADE;Ćień +TP_WBALANCE_SIZE;Wielkość: +TP_WBALANCE_SOLUX35;Solux 3500K +TP_WBALANCE_SOLUX41;Solux 4100K +TP_WBALANCE_SOLUX47;Solux 4700K (vendor) +TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) +TP_WBALANCE_SPOTWB;Punktowy +TP_WBALANCE_TEMPERATURE;Temperatura +TP_WBALANCE_TUNGSTEN;Wolfram +TP_WBALANCE_WATER1;Pod wodą 1 +TP_WBALANCE_WATER2;Pod wodą 2 +TP_WBALANCE_WATER_HEADER;Pod wodą +ZOOMPANEL_100;(100%) +ZOOMPANEL_NEWCROPWINDOW;Otwórz (nową) lupę +ZOOMPANEL_ZOOM100;Powiększ do 100%\nSkrót: z +ZOOMPANEL_ZOOMFITCROPSCREEN;Dopasuj kadr do ekranu\nSkrót: Alt-f +ZOOMPANEL_ZOOMFITSCREEN;Dopasuj cały obraz do ekranu\nSkrót: f +ZOOMPANEL_ZOOMIN;Przybliż\nSkrót: + +ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: - + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!CURVEEDITOR_AXIS_IN;I: +!CURVEEDITOR_AXIS_LEFT_TAN;LT: +!CURVEEDITOR_AXIS_OUT;O: +!CURVEEDITOR_AXIS_RIGHT_TAN;RT: +!CURVEEDITOR_EDITPOINT_HINT;Enable edition of node in/out values.\n\nRight-click on a node to select it.\nRight-click on empty space to de-select the node. +!EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels +!FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!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_ASIMAGE;As Image +!HISTORY_MSG_299;NR - Chrominance curve +!HISTORY_MSG_300;- +!HISTORY_MSG_301;NR - Luma control +!HISTORY_MSG_302;NR - Chroma method +!HISTORY_MSG_303;NR - Chroma method +!HISTORY_MSG_304;W - Contrast levels +!HISTORY_MSG_305;Wavelet Levels +!HISTORY_MSG_306;W - Preview +!HISTORY_MSG_307;W - Preview +!HISTORY_MSG_308;W - Preview direction +!HISTORY_MSG_309;W - ES - Detail +!HISTORY_MSG_310;W - Residual - Sky tar/prot +!HISTORY_MSG_311;W - Wavelet levels +!HISTORY_MSG_312;W - Residual - Shadows threshold +!HISTORY_MSG_313;W - Chroma - Sat/past +!HISTORY_MSG_314;W - Gamut - Reduce artifacts +!HISTORY_MSG_315;W - Residual - Contrast +!HISTORY_MSG_316;W - Gamut - Skin tar/prot +!HISTORY_MSG_317;W - Gamut - Skin hue +!HISTORY_MSG_318;W - Contrast - Highlight levels +!HISTORY_MSG_319;W - Contrast - Highlight range +!HISTORY_MSG_320;W - Contrast - Shadow range +!HISTORY_MSG_321;W - Contrast - Shadow levels +!HISTORY_MSG_322;W - Gamut - Avoid color shift +!HISTORY_MSG_323;W - ES - Local contrast +!HISTORY_MSG_324;W - Chroma - Pastel +!HISTORY_MSG_325;W - Chroma - Saturated +!HISTORY_MSG_326;W - Chroma - Method +!HISTORY_MSG_327;W - Contrast - Apply to +!HISTORY_MSG_328;W - Chroma - Link strength +!HISTORY_MSG_329;W - Toning - Opacity RG +!HISTORY_MSG_330;W - Toning - Opacity BY +!HISTORY_MSG_331;W - Contrast levels - Extra +!HISTORY_MSG_332;W - Tiling method +!HISTORY_MSG_333;W - Residual - Shadows +!HISTORY_MSG_334;W - Residual - Chroma +!HISTORY_MSG_335;W - Residual - Highlights +!HISTORY_MSG_336;W - Residual - Highlights threshold +!HISTORY_MSG_337;W - Residual - Sky hue +!HISTORY_MSG_338;W - ES - Radius +!HISTORY_MSG_339;W - ES - Strength +!HISTORY_MSG_340;W - Strength +!HISTORY_MSG_341;W - Edge performance +!HISTORY_MSG_342;W - ES - First level +!HISTORY_MSG_343;W - Chroma levels +!HISTORY_MSG_344;W - Meth chroma sl/cur +!HISTORY_MSG_345;W - ES - Local contrast +!HISTORY_MSG_346;W - ES - Local contrast method +!HISTORY_MSG_347;W - Denoise - Level 0 +!HISTORY_MSG_348;W - Denoise - Level 1 +!HISTORY_MSG_349;W - Denoise - Level 2 +!HISTORY_MSG_350;W - ES - Edge detection +!HISTORY_MSG_351;W - Residual - HH curve +!HISTORY_MSG_352;W - Background +!HISTORY_MSG_353;W - ES - Gradient sensitivity +!HISTORY_MSG_354;W - ES - Enhance +!HISTORY_MSG_355;W - ES - Threshold low +!HISTORY_MSG_356;W - ES - Threshold high +!HISTORY_MSG_357;W - Denoise - Link with ES +!HISTORY_MSG_358;W - Gamut - CH +!HISTORY_MSG_359;Hot/Dead - Threshold +!HISTORY_MSG_360;TM Gamma +!HISTORY_MSG_361;W - Final - Chroma balance +!HISTORY_MSG_362;W - Residual - Compression method +!HISTORY_MSG_363;W - Residual - Compression strength +!HISTORY_MSG_364;W - Final - Contrast balance +!HISTORY_MSG_365;W - Final - Delta balance +!HISTORY_MSG_366;W - Residual - Compression gamma +!HISTORY_MSG_367;W - ES - Local contrast curve +!HISTORY_MSG_368;W - Final - Contrast balance +!HISTORY_MSG_369;W - Final - Balance method +!HISTORY_MSG_370;W - Final - Local contrast curve +!HISTORY_MSG_371;Post-Resize Sharpening +!HISTORY_MSG_372;PRS USM - Radius +!HISTORY_MSG_373;PRS USM - Amount +!HISTORY_MSG_374;PRS USM - Threshold +!HISTORY_MSG_375;PRS USM - Sharpen only edges +!HISTORY_MSG_376;PRS USM - Edge detection radius +!HISTORY_MSG_377;PRS USM - Edge tolerance +!HISTORY_MSG_378;PRS USM - Halo control +!HISTORY_MSG_379;PRS USM - Halo control amount +!HISTORY_MSG_380;PRS - Method +!HISTORY_MSG_381;PRS RLD - Radius +!HISTORY_MSG_382;PRS RLD - Amount +!HISTORY_MSG_383;PRS RLD - Damping +!HISTORY_MSG_384;PRS RLD - Iterations +!MAIN_TAB_INSPECT; Inspect +!MAIN_TAB_WAVELET;Wavelet +!MAIN_TAB_WAVELET_TOOLTIP;Shortcut: Alt-w +!PARTIALPASTE_EQUALIZER;Wavelet levels +!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 +!PREFERENCES_CIEART_FRAME;CIECAM02-Specific Settings +!PREFERENCES_CLUTSCACHE;HaldCLUT Cache +!PREFERENCES_CLUTSCACHE_LABEL;Maximum number of cached CLUTs +!PREFERENCES_CURVEBBOXPOS;Position of curve copypasta buttons +!PREFERENCES_CURVEBBOXPOS_ABOVE;Above +!PREFERENCES_CURVEBBOXPOS_BELOW;Below +!PREFERENCES_CURVEBBOXPOS_LEFT;Left +!PREFERENCES_CURVEBBOXPOS_RIGHT;Right +!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_EXPAUT;Expert +!PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT;Same thumbnail height between the Editor's panel 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_GREYSC18;Yb=18 CIE L#50 +!PREFERENCES_GREYSCA;Automatic +!PREFERENCES_GREYSC;Scene Yb luminance (%) +!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_LEVAUTDN;Denoising level +!PREFERENCES_LEVDN;Cell size +!PREFERENCES_LISS;Auto multi-zone smoothing +!PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders +!PREFERENCES_MAX;Maxi (Tile) +!PREFERENCES_MED;Medium (Tile/2) +!PREFERENCES_MIN;Mini (100x115) +!PREFERENCES_NAVIGATIONFRAME;Navigation +!PREFERENCES_NOISE;Noise Reduction +!PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Overlay filenames on thumbnails in the editor pannel +!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_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_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_SHOWFILMSTRIPTOOLBAR;Show filmstrip toolbar +!PREFERENCES_SIMPLAUT;Tool mode +!PREFERENCES_SMA;Small (250x287) +!PREFERENCES_STDAUT;Standard +!PREFERENCES_TIMAX;High +!PREFERENCES_TINB;Number of tiles +!PREFERENCES_TISTD;Standard +!PREFERENCES_WAVLEV;Increase wavelet level in quality 'high' +!PREFERENCES_WLONE;One level +!PREFERENCES_WLTWO;Two levels +!PREFERENCES_WLZER;No +!TP_CROP_GTHARMMEANS;Harmonic Means +!TP_CROP_GTTRIANGLE1;Golden Triangles 1 +!TP_CROP_GTTRIANGLE2;Golden Triangles 2 +!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_ABM;Chroma only +!TP_DIRPYRDENOISE_AUTO;Automatic global +!TP_DIRPYRDENOISE_AUTO_TOOLTIP;Try to evaluate chroma noise\nBe careful, this calculation is average, and is quite subjective ! +!TP_DIRPYRDENOISE_AUT;Automatic global +!TP_DIRPYRDENOISE_C2TYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CCCURVE;Chrominance curve +!TP_DIRPYRDENOISE_CHROMAFR;Chrominance +!TP_DIRPYRDENOISE_CTYPE;Auto method +!TP_DIRPYRDENOISE_CTYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nAutomatic multi-zones\nNo preview - works only during saving, but using the "Preview" method by matching the tile size and center to the preview size and center you can get an idea of the expected results.\nThe image is divided into tiles (about 10 to 70 depending on image size) and each tile receives its own chrominance noise reduction settings.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CURVEEDITOR_CC;Chroma +!TP_DIRPYRDENOISE_CURVEEDITOR_CC_TOOLTIP;Increase (multiply) the value of all chrominance sliders.\nThis curve lets you adjust the strength of chromatic noise reduction as a function of chromaticity, for instance to increase the action in areas of low saturation and to decrease it in those of high saturation. +!TP_DIRPYRDENOISE_LPLABM;Weighted L* (little) + a*b* (normal) +!TP_DIRPYRDENOISE_LTYPE;Luminance control +!TP_DIRPYRDENOISE_LUMAFR;Luminance +!TP_DIRPYRDENOISE_LUMAFR_TOOLTIP;Wavelet on luminance and Fourier transform for luminance detail +!TP_DIRPYRDENOISE_MANU;Manual +!TP_DIRPYRDENOISE_MAN;Manual +!TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - +!TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 +!TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. +!TP_DIRPYRDENOISE_PON;Auto multi-zones +!TP_DIRPYRDENOISE_PREVLABEL;Preview size=%1, Center: Px=%2 Py=%3 +!TP_DIRPYRDENOISE_PREV;Preview +!TP_DIRPYRDENOISE_PRE;Preview multi-zones +!TP_DIRPYRDENOISE_SLI;Slider +!TP_DIRPYRDENOISE_TILELABEL;Tile size=%1, Center: Tx=%2 Ty=%3 +!TP_DIRPYREQUALIZER_ARTIF;Reduce artifacts +!TP_EPD_GAMMA;Gamma +!TP_EXPOSURE_TCMODE_LUMINANCE;Luminance +!TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance +!TP_PRSHARPENING_LABEL;Post-Resize Sharpening +!TP_PRSHARPENING_TOOLTIP;Sharpens the image after resizing. Only works when the "Lanczos" resizing method is used. It is impossible to preview the effects of this tool. See RawPedia for usage instructions. +!TP_RAW_HD;Threshold +!TP_RAW_HD_TOOLTIP;Lower values make hot/dead pixel detection more aggressive, but false positives may lead to artifacts. If you notice any artifacts appearing when enabling the Hot/Dead Pixel Filters, gradually increase the threshold value until they disappear. +!TP_WAVELET_1;Level 1 +!TP_WAVELET_2;Level 2 +!TP_WAVELET_3;Level 3 +!TP_WAVELET_4;Level 4 +!TP_WAVELET_5;Level 5 +!TP_WAVELET_6;Level 6 +!TP_WAVELET_7;Level 7 +!TP_WAVELET_8;Level 8 +!TP_WAVELET_9;Level 9 +!TP_WAVELET_ALL;All levels in all directions +!TP_WAVELET_APPLYTO;Apply To +!TP_WAVELET_AVOID;Avoid color shift +!TP_WAVELET_B0;Black +!TP_WAVELET_B1;Grey +!TP_WAVELET_B2;Residual +!TP_WAVELET_BACUR;Curve +!TP_WAVELET_BALANCE;Contrast balance d/v-h +!TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chromaticity or residual tone mapping are activated, the effect due to balance is amplified. +!TP_WAVELET_BALCHRO;Chroma balance +!TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chromaticity balance. +!TP_WAVELET_BANONE;None +!TP_WAVELET_BASLI;Slider +!TP_WAVELET_BATYPE;Contrast balance method +!TP_WAVELET_CCURVE;Local contrast +!TP_WAVELET_CH1;Whole chromaticity range +!TP_WAVELET_CH2;Saturated/pastel +!TP_WAVELET_CH3;Link contrast levels +!TP_WAVELET_CHCU;Curve +!TP_WAVELET_CHRO;Saturated/pastel threshold +!TP_WAVELET_CHRO_TOOLTIP;Sets the wavelet level which will be the threshold between saturated and pastel colors.\n1-x: saturated\nx-9: pastel\n\nIf the value exceeds the amount of wavelet levels you are using then it will be ignored. +!TP_WAVELET_CHR;Chroma-contrast link strength +!TP_WAVELET_CHR_TOOLTIP;Adjusts chromaticity as a function of "contrast levels" and "chroma-contrast link strength" +!TP_WAVELET_CHSL;Sliders +!TP_WAVELET_CHTYPE;Chrominance method +!TP_WAVELET_COLORT;Opacity Red-Green +!TP_WAVELET_COMBOTH;Both +!TP_WAVELET_COMPCONT;Contrast +!TP_WAVELET_COMPGAMMA;Compression gamma +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjusting the gamma of the residual image allow you to equilibrate the data and histogram. +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjust gamma for residual image and compression.\nAllow to equilibrate data and histogram +!TP_WAVELET_COMPTM;Tone mapping +!TP_WAVELET_CONTEDIT;'After' Contrast curve +!TP_WAVELET_CONTEDIT;'After' contrast curve +!TP_WAVELET_CONTRAST_MINUS;Contrast - +!TP_WAVELET_CONTRAST_PLUS;Contrast + +!TP_WAVELET_CONTRA;Contrast +!TP_WAVELET_CONTRA_TOOLTIP;Changes contrast of the residual image. +!TP_WAVELET_CONTR;Gamut +!TP_WAVELET_CTYPE;Chrominance control +!TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modifies local contrast as a function of the original local contrast (absciss)\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 100..300)\n66% absciss represents standard deviation of local contrast (real value about 300..800)\n100% represents maximum (real value about 3000..8000) +!TP_WAVELET_CURVEEDITOR_CH;Contrast levels=f(Hue) +!TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modifies each level's contrast as a function oh hue.\nTake care not to overwrite changes made with the Gamut Hue controls.\nThe curve will only have an effect when wavelet contrast level sliders are non-zero. +!TP_WAVELET_CURVEEDITOR_CL;L +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Applies a final contrast luminance curve at the end of the wavelet treatment. +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Apply a contrast luminance curve at the end of wavelet level threatment +!TP_WAVELET_CURVEEDITOR_HH;HH +!TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modifies the residual image's hue as a function of hue. +!TP_WAVELET_DALL;All directions +!TP_WAVELET_DAUB;Edge performance +!TP_WAVELET_DAUB_TOOLTIP;Changes Daubechies coefficients:\nD4 = Standard,\nD14 = Often best performance, 10% more time-intensive.\n\nAffects edge detection as well as the general quality of the firsts levels. However the quality is not strictly related to this coefficient and can vary with images and uses. +!TP_WAVELET_DISP;Preview Settings +!TP_WAVELET_DONE;Vertical +!TP_WAVELET_DTHR;Diagonal +!TP_WAVELET_DTWO;Horizontal +!TP_WAVELET_EDCU;Curve +!TP_WAVELET_EDGCONT;Local contrast +!TP_WAVELET_EDGCONT_TOOLTIP;Adjusting the points to the left decreases contrast, and to the right increases it.\nBottom-left, Top-Left, Top-Right, Bottom-right represent respectively local contast for low values, mean, mean+stdev, maxima +!TP_WAVELET_EDGEDETECTTHR2;Threshold high (detection) +!TP_WAVELET_EDGEDETECTTHR;Threshold low (noise) +!TP_WAVELET_EDGEDETECTTHR_TOOLTIP;This adjuster lets you target edge detection for example to avoid applying edge sharpness to fine details, such as noise in the sky. +!TP_WAVELET_EDGEDETECT;Gradient sensitivity +!TP_WAVELET_EDGEDETECT_TOOLTIP;Moving the slider to the right increases edge sensitivity. This affects local contrast, edge settings and noise. +!TP_WAVELET_EDGE;Edge Sharpness +!TP_WAVELET_EDGREINF_TOOLTIP;Reinforce or reduce the action of the first level, do the opposite to the second level, and leave the rest unchanged. +!TP_WAVELET_EDGTHRESH;Detail +!TP_WAVELET_EDGTHRESH_TOOLTIP;Change the repartition between the first levels and the others. The higher the threshold the more the action is centred on the first levels. Be careful with negative values, they increase the action of high levels and can introduce artifacts. +!TP_WAVELET_EDRAD;Radius +!TP_WAVELET_EDRAD_TOOLTIP;This radius adjustment is very different from those in other sharpening tools. Its value is compared to each level through a complex function. In this sense, a value of zero still has an effect. +!TP_WAVELET_EDSL;Threshold Sliders +!TP_WAVELET_EDTYPE;Local contrast method +!TP_WAVELET_EDVAL;Strength +!TP_WAVELET_FINAL;Final Touchup +!TP_WAVELET_FINEST;Finest +!TP_WAVELET_HIGHLIGHT;Highlight luminance range +!TP_WAVELET_HS1;Whole luminance range +!TP_WAVELET_HS2;Shadows/Highlights +!TP_WAVELET_HUESKIN;Skin hue +!TP_WAVELET_HUESKIN_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_HUESKY;Sky hue +!TP_WAVELET_HUESKY_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_INF;Below or equal the level +!TP_WAVELET_ITER;Delta balance levels +!TP_WAVELET_ITER_TOOLTIP;Left: increase low levels and reduce high levels,\nRight: reduce low levels and increase high levels. +!TP_WAVELET_LABEL;Wavelet Levels +!TP_WAVELET_LARGEST;Coarsest +!TP_WAVELET_LEVCH;Chromaticity +!TP_WAVELET_LEVELS;Wavelet Levels +!TP_WAVELET_LEVELS_TOOLTIP;Choose the number of detail levels the image is to be decomposed into. More levels require more RAM and require a longer processing time. +!TP_WAVELET_LEVF;Contrast +!TP_WAVELET_LEVLABEL;Preview maximum possible levels = %1 +!TP_WAVELET_LEVONE;Level 2 +!TP_WAVELET_LEVTWO;Level 3 +!TP_WAVELET_LEVZERO;Level 1 +!TP_WAVELET_LINKEDG;Link with Edge Sharpness' Strength +!TP_WAVELET_LIPST;Enhanced algorithm +!TP_WAVELET_LIPST_TOOLTIP;This algorithm uses Lipschitz regularity to increase edge detection quality at a cost of increased processing time and memory requirements. +!TP_WAVELET_LOWLIGHT;Shadow luminance range +!TP_WAVELET_MEDGREINF;First level +!TP_WAVELET_MEDILEV;Edge detection +!TP_WAVELET_MEDI;Reduce artifacts in blue sky +!TP_WAVELET_NEUTRAL;Neutral +!TP_WAVELET_NOISE;Denoise and Refine +!TP_WAVELET_NOIS;Denoise +!TP_WAVELET_ONE;One level +!TP_WAVELET_OPACITYWL;Final local contrast +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify final local contrast in function of last local contrast (absciss) for all levels decomposition\nTake into account: \na)contrast levels \nb)edge sharpness \nc)contrast balance\nd)decomposition-recomposition\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 200..1000)\n66% absciss represents standard deviation of local contrast (real value about 1000..2000)\n100% represents maximum (real value about 5000..13000) +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify the final local contrast at the end of the wavelet treatment.\n\nThe left side represents the smallest local contrast, progressing to the largest local contrast on the right. +!TP_WAVELET_OPACITYW;Contrast balance d/v-h curve +!TP_WAVELET_OPACITY;Opacity Blue-Yellow +!TP_WAVELET_PASTEL;Pastel chromaticity +!TP_WAVELET_PREVIEWBACK;Background +!TP_WAVELET_PREVIEWLEVELS;Preview +!TP_WAVELET_RE1;Reinforced +!TP_WAVELET_RE2;Unchanged +!TP_WAVELET_RE3;Reduced +!TP_WAVELET_RESCHRO;Chromaticity +!TP_WAVELET_RESCONH;Highlights +!TP_WAVELET_RESCON;Shadows +!TP_WAVELET_RESID;Residual image +!TP_WAVELET_SAT;Saturated chromaticity +!TP_WAVELET_SETTINGS;Wavelet Settings +!TP_WAVELET_SKIN;Skin targetting/protection +!TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected. +!TP_WAVELET_SKY;Sky targetting/protection +!TP_WAVELET_SKY_TOOLTIP;At -100 sky-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 sky-tones are protected while all other tones are affected. +!TP_WAVELET_STRENGTH;Strength +!TP_WAVELET_STREN;Strength +!TP_WAVELET_SUPE;Extra +!TP_WAVELET_SUP;Above the level +!TP_WAVELET_THRESHOLD2;Shadow levels +!TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels between 9 and 9 minus the value will be affected by the shadow luminance range. Other levels will be fully treated. The highest level possible is limited by the highlight level value (9 minus highlight level value). +!TP_WAVELET_THRESHOLD;Highlight levels +!TP_WAVELET_THRESHOLD_TOOLTIP;Only levels beyond the chosen value will be affected by the highlight luminance range. Other levels will be fully treated. The chosen value here limits the highest possible value of the shadow levels. +!TP_WAVELET_THRH;Highlights threshold +!TP_WAVELET_THR;Shadows threshold +!TP_WAVELET_TILESBIG;Big tiles +!TP_WAVELET_TILESFULL;Full image +!TP_WAVELET_TILESIZE;Tiling method +!TP_WAVELET_TILESLIT;Little tiles +!TP_WAVELET_TILES_TOOLTIP;Processing the full image leads to better quality and is the recommended option, while using tiles is a fall-back solution for users with little RAM. Refer to RawPedia for memory requirements. +!TP_WAVELET_TMHIGH;High +!TP_WAVELET_TMLOWHIGH;Low+High +!TP_WAVELET_TMNONE;None +!TP_WAVELET_TMSTD;Standard +!TP_WAVELET_TMSTRENGTH;Compression strength +!TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image. When the value is different from 0, the Strength and Gamma sliders of the Tone Mapping tool in the Exposure tab will become grayed out. +!TP_WAVELET_TMTYPE;Compression method +!TP_WAVELET_TON;Toning +!TP_WAVELET_daub2;D2 - low +!TP_WAVELET_daub4;D4 - standard +!TP_WAVELET_daub6;D6 - standard plus +!TP_WAVELET_daub10;D10 - medium +!TP_WAVELET_daub14;D14 - high diff --git a/rtdata/languages/Polish (Latin Characters) b/rtdata/languages/Polish (Latin Characters) new file mode 100644 index 000000000..ff2a64c6b --- /dev/null +++ b/rtdata/languages/Polish (Latin Characters) @@ -0,0 +1,1860 @@ +#01 2007-12-24 Mateusz Ludwin +#02 2010-01-08 Bartosz "Simek" Kaszubowski +#03 2011-09-06 Dariusz 'Salvadhor' Duma +#04 2011-11-30 DrSlony +#05 2012-01-14 DrSlony +#06 2012-01-30 DrSlony +#07 2012-04-02 DrSlony +#08 2013-05-21 DrSlony +#09 2014-10-16 DrSlony + +ABOUT_TAB_BUILD;Wersja +ABOUT_TAB_CREDITS;Zaslugi +ABOUT_TAB_LICENSE;Licencja +ABOUT_TAB_RELEASENOTES;Notatki eksploatacyjne +ABOUT_TAB_SPLASH;Ekran powitalny +ADJUSTER_RESET_TO_DEFAULT;Przywroc domyslne +BATCHQUEUE_AUTOSTART;Autostart +BATCHQUEUE_DESTFILENAME;Sciezka i nazwa pliku +BATCH_PROCESSING;Przetwarzanie wsadowe +CURVEEDITOR_CURVES;Krzywe +CURVEEDITOR_CURVE;Krzywa +CURVEEDITOR_CUSTOM;Wlasna +CURVEEDITOR_DARKS;Ciemne +CURVEEDITOR_HIGHLIGHTS;Najjasniejsze +CURVEEDITOR_LIGHTS;Jasne +CURVEEDITOR_LINEAR;Liniowa +CURVEEDITOR_LOADDLGLABEL;Wczytaj krzywa... +CURVEEDITOR_MINMAXCPOINTS;Ekwalizator +CURVEEDITOR_NURBS;NURBS +CURVEEDITOR_PARAMETRIC;Parametryczna +CURVEEDITOR_SAVEDLGLABEL;Zapisz krzywa... +CURVEEDITOR_SHADOWS;Najciemniejsze +CURVEEDITOR_TOOLTIPCOPY;Skopiuj krzywa do schowka +CURVEEDITOR_TOOLTIPLINEAR;Zresetuj krzywa do liniowej +CURVEEDITOR_TOOLTIPLOAD;Wczytaj krzywa z pliku +CURVEEDITOR_TOOLTIPPASTE;Wstaw krzywa ze schowka +CURVEEDITOR_TOOLTIPSAVE;Zapisz krzywa +CURVEEDITOR_TYPE;Typ: +DIRBROWSER_FOLDERS;Katalogi +EDITWINDOW_TITLE;Edytor obrazu +EDIT_OBJECT_TOOLTIP;Wyswietla widzet na podgladzie ktory ulatwia ustawienie narzedzia. +EDIT_PIPETTE_TOOLTIP;Aby dodac punkt do krzywej nalezy trzymac wcisniety klawisz Ctrl podczas klikniecia lewym guzikiem myszki na danym obszarze glownego podgladu.\nAby zmienic ustawienie juz istniejacego punktu, nalezy trzymac wduszony klawisz Ctrl podczas klikniecia lewym guzikiem myszki na danym obszarze glownego podgladu, nastepnie nalezy puscic klawisz Ctrl (chyba ze chodzi nam o bardzo precyzyjne ustawienie dzieki spowolnieniu jakie trzymanie klawisza Ctrl nam daje) i podczas trzymania lewego guzika myszki nalezy myszka ruszac w pionie aby odpowiednio manipulowac punktem w pionie. +EXIFFILTER_APERTURE;Przyslona +EXIFFILTER_CAMERA;Aparat +EXIFFILTER_EXPOSURECOMPENSATION;Korekcja ekspozycji (EV) +EXIFFILTER_FILETYPE;Typ pliku +EXIFFILTER_FOCALLEN;Wartosc ogniskowej +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Obiektyw +EXIFFILTER_METADATAFILTER;Wlacz filtry metadanych +EXIFFILTER_SHUTTER;Migawka +EXIFPANEL_ADDEDITHINT;Dodaje nowa etykiete lub edytuje etykiete +EXIFPANEL_ADDEDIT;Dodaj/Edytuj +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Wpisz wartosc +EXIFPANEL_ADDTAGDLG_SELECTTAG;Wybierz etykiete +EXIFPANEL_ADDTAGDLG_TITLE;Dodaj/Edytuj etykiete +EXIFPANEL_KEEPHINT;Zapamietuje wybrane etykiety podczas zapisywania pliku wyjsciowego +EXIFPANEL_KEEP;Zapamietaj +EXIFPANEL_REMOVEHINT;Usuwa wybrane etykiety podczas zapisywania pliku wyjsciowego +EXIFPANEL_REMOVE;Usun +EXIFPANEL_RESETALLHINT;Przywraca orginalne wartosci etykiet +EXIFPANEL_RESETALL;Przywroc wszystkie +EXIFPANEL_RESETHINT;Przywraca orginalne wartosci wybranych etykiet +EXIFPANEL_RESET;Przywroc +EXIFPANEL_SUBDIRECTORY;Podkatalog +EXPORT_BYPASS_ALL;Zaznacz / Odznacz wszystkie +EXPORT_BYPASS_DEFRINGE;Pomin usuwanie widma +EXPORT_BYPASS_DIRPYRDENOISE;Pomin redukcje szumow +EXPORT_BYPASS_DIRPYREQUALIZER;Pomin kontrast wg. poziomu detali +EXPORT_BYPASS_RAW_CA;Pomin redukcje aberracji chromatycznej (raw) +EXPORT_BYPASS_RAW_CCSTEPS;Pomin tlumienie falszowania koloru (raw) +EXPORT_BYPASS_RAW_DCB_ENHANCE;Pomin poprawe DCB (raw) +EXPORT_BYPASS_RAW_DCB_ITERATIONS;Pomin liczbe powtorzen DCB (raw) +EXPORT_BYPASS_RAW_DF;Pomin czarna klatke (raw) +EXPORT_BYPASS_RAW_FF;Pomin puste pole (raw) +EXPORT_BYPASS_RAW_GREENTHRESH;Pomin wyrownanie zieleni (raw) +EXPORT_BYPASS_RAW_LINENOISE;Pomin redukcje szumow liniowych (raw) +EXPORT_BYPASS_RAW_LMMSE_ITERATIONS;Pomin poprawe LMMSE [raw] +EXPORT_BYPASS_SHARPENEDGE;Pomin wyostrzanie krawedzi +EXPORT_BYPASS_SHARPENING;Pomin wyostrzanie +EXPORT_BYPASS_SHARPENMICRO;Pomin mikrokontrast +EXPORT_BYPASS_SH_HQ;Pomin wysokiej jakosci korekte cieni/podswietlen +EXPORT_FASTEXPORTOPTIONS;Opcje szybkiego eksportu +EXPORT_INSTRUCTIONS;Opcje szybkiego eksportu umozliwiaja pominiecie pewnych narzedzi ktore moga byc dosc wymagajace na procesor oraz moga znacznie przedluzyc czas przetwarzania podczas eksportowania zdjec. Ta metoda jest zalecana w razie potrzeby szybkiego uzyskania zdjec o nizszej rozdzielczosci oraz jakosci kiedy zalezy nam na czasie a nie chcemy modyfikowac plikow PP3. +EXPORT_MAXHEIGHT;Maksymalna wysokosc: +EXPORT_MAXWIDTH;Maksymalna szerokosc: +EXPORT_PUTTOQUEUEFAST; Dodaj do kolejki szybkiego eksportu +EXPORT_RAW_DMETHOD;Algorytm demozaikowania +EXTPROGTARGET_1;raw +EXTPROGTARGET_2;wywolane w kolejce +FILEBROWSER_ADDDELTEMPLATE;Dodaj/Usun szablon... +FILEBROWSER_APPLYPROFILE;Zastosuj profil +FILEBROWSER_APPLYPROFILE_PARTIAL;Zastosuj czesciowy profil +FILEBROWSER_AUTODARKFRAME;Automatyczne uzycie czarnej klatki +FILEBROWSER_AUTOFLATFIELD;Automatyczne uzycie klatki typu puste pole +FILEBROWSER_BROWSEPATHBUTTONHINT;Nalezy kliknac, aby przegladac wybrana sciezke +FILEBROWSER_BROWSEPATHHINT;Umozliwia przegladanie wprowadzonej sciezki\nCtrl-o zaznaczenie\nEnter, Ctrl-Enter (w menedzerze plikow) przegladanie\nSkroty:\n ~ - katalog domowy uzytkownika\n ! - katalog z obrazami uzytkownia +FILEBROWSER_CACHECLEARFROMFULL;Czyszczenie pamieci podrecznej - pelne +FILEBROWSER_CACHECLEARFROMPARTIAL;Czyszczenie pamieci podrecznej - czesciowe +FILEBROWSER_CACHE;Pamiec podreczna +FILEBROWSER_CLEARPROFILE;Wyczysc profil +FILEBROWSER_COLORLABEL_TOOLTIP;Kolorowe etykiety\n\nUzyj za pomoca rozwijanej listy lub skrotow:\nShift-Ctrl-0 No Color\nShift-Ctrl-1 Czerwona\nShift-Ctrl-2 Zolta\nShift-Ctrl-3 Zielona\nShift-Ctrl-4 Niebieska\nShift-Ctrl-5 Purpurowa +FILEBROWSER_COPYPROFILE;Kopiuj profil +FILEBROWSER_CURRENT_NAME;Obecna nazwa: +FILEBROWSER_DARKFRAME;Czarna klatka +FILEBROWSER_DELETEDLGLABEL;Potwierdzenie usuniecia pliku +FILEBROWSER_DELETEDLGMSGINCLPROC;Na pewno usunac wybrany plik %1 WLACZNIE z wersja utworzona przez kolejke przetwarzania? +FILEBROWSER_DELETEDLGMSG;Na pewno usunac zaznaczone %1 plikow? +FILEBROWSER_EMPTYTRASHHINT;Definitywnie usuwa pliki z kosza +FILEBROWSER_EMPTYTRASH;Wyczysc kosz +FILEBROWSER_EXEC_CPB;Uruchom zewnetrzny kreator profilow +FILEBROWSER_EXTPROGMENU;Otworz za pomoca +FILEBROWSER_FLATFIELD;Puste pole +FILEBROWSER_MOVETODARKFDIR;Przenies do katalogu zawierajacego czarne klatki +FILEBROWSER_MOVETOFLATFIELDDIR;Przenies do katalogu zawierajacego puste pola +FILEBROWSER_NEW_NAME;Nowa nazwa: +FILEBROWSER_OPENDEFAULTVIEWER;Domyslna przegladarka zdjec (z kolejki) +FILEBROWSER_PARTIALPASTEPROFILE;Wklej czesciowo +FILEBROWSER_PASTEPROFILE;Wklej profil +FILEBROWSER_POPUPCANCELJOB;Anuluj zadanie +FILEBROWSER_POPUPCOLORLABEL0;Etykieta: Brak +FILEBROWSER_POPUPCOLORLABEL1;Etykieta: Czerwona +FILEBROWSER_POPUPCOLORLABEL2;Etykieta: Zolta +FILEBROWSER_POPUPCOLORLABEL3;Etykieta: Zielona +FILEBROWSER_POPUPCOLORLABEL4;Etykieta: Niebieska +FILEBROWSER_POPUPCOLORLABEL5;Etykieta: Purpurowa +FILEBROWSER_POPUPCOLORLABEL;Kolorowa etykieta +FILEBROWSER_POPUPCOPYTO;Skopiuj do... +FILEBROWSER_POPUPFILEOPERATIONS;Operacje na plikach +FILEBROWSER_POPUPMOVEEND;Przenies na koniec kolejki +FILEBROWSER_POPUPMOVEHEAD;Przenies na poczatek kolejki +FILEBROWSER_POPUPMOVETO;Przenies do... +FILEBROWSER_POPUPOPENINEDITOR;Otworz w edytorze +FILEBROWSER_POPUPOPEN;Otworz +FILEBROWSER_POPUPPROCESSFAST;Dodaj do kolejki szybkiego eksportu +FILEBROWSER_POPUPPROCESS;Umiesc w kolejce do przetwarzania +FILEBROWSER_POPUPPROFILEOPERATIONS;Profile przetwarzania +FILEBROWSER_POPUPRANK0;Usun ocene +FILEBROWSER_POPUPRANK1;Ocena 1 * +FILEBROWSER_POPUPRANK2;Ocena 2 ** +FILEBROWSER_POPUPRANK3;Ocena 3 *** +FILEBROWSER_POPUPRANK4;Ocena 4 **** +FILEBROWSER_POPUPRANK5;Ocena 5 ***** +FILEBROWSER_POPUPRANK;Ocena +FILEBROWSER_POPUPREMOVEINCLPROC;Usun z dysku wraz z wynikiem przetwarzania +FILEBROWSER_POPUPREMOVE;Usun z dysku +FILEBROWSER_POPUPRENAME;Zmien nazwe +FILEBROWSER_POPUPSELECTALL;Zaznacz wszystkie +FILEBROWSER_POPUPTRASH;Przenies do kosza +FILEBROWSER_POPUPUNRANK;Usun ocene +FILEBROWSER_POPUPUNTRASH;Usun z kosza +FILEBROWSER_QUERYBUTTONHINT;Wyczysc haslo szukania +FILEBROWSER_QUERYHINT;Wprowadz czesc nazwy, by zlokalizowac plik. Oddziel hasla przecinkami, np.\n1001,1004,1199\n\nWyklucz hasla poprzedzajac je znakiem !=\nnp.\n!=1001,1004,1199\n\nSkroty:\nCtrl-f - przejdz do pola "Znajdz",\nEnter - szukaj,\nEsc - wyczysc pole "Znajdz",\nShift-Esc - wyjdz z pola "Znajdz". +FILEBROWSER_QUERYLABEL; Znajdz: +FILEBROWSER_RANK1_TOOLTIP;Ocen 1 *\nSkrot: Shift-1 +FILEBROWSER_RANK2_TOOLTIP;Ocen 2 *\nSkrot: Shift-2 +FILEBROWSER_RANK3_TOOLTIP;Ocen 3 *\nSkrot: Shift-3 +FILEBROWSER_RANK4_TOOLTIP;Ocen 4 *\nSkrot: Shift-4 +FILEBROWSER_RANK5_TOOLTIP;Ocen 5 *\nSkrot: Shift-5 +FILEBROWSER_RENAMEDLGLABEL;Zmien nazwe pliku +FILEBROWSER_RENAMEDLGMSG;Zmien nazwe pliku "%1" na: +FILEBROWSER_SELECTDARKFRAME;Wybierz czarna klatke... +FILEBROWSER_SELECTFLATFIELD;Wybierz puste pole... +FILEBROWSER_SHOWCOLORLABEL1HINT;Pokazuje zdjecia z czerwona etykieta.\nSkrot: Alt-1 +FILEBROWSER_SHOWCOLORLABEL2HINT;Pokazuje zdjecia z zolta etykieta.\nSkrot: Alt-2 +FILEBROWSER_SHOWCOLORLABEL3HINT;Pokazuje zdjecia z zielona etykieta.\nSkrot: Alt-3 +FILEBROWSER_SHOWCOLORLABEL4HINT;Pokazuje zdjecia z niebieska etykieta.\nSkrot: Alt-4 +FILEBROWSER_SHOWCOLORLABEL5HINT;Pokazuje zdjecia z purpurowa etykieta.\nSkrot: Alt-5 +FILEBROWSER_SHOWDIRHINT;Wylacza wyszstkie filtry.\nSkrot: d +FILEBROWSER_SHOWEDITEDHINT;Pokazuje edytowane zdjecia.\nSkrot: 7 +FILEBROWSER_SHOWEDITEDNOTHINT;Pokazuje nieedytowane zdjecia.\nSkrot: 6 +FILEBROWSER_SHOWEXIFINFO;Pokaz dane Exif.\n\nSkroty:\ni - Tryb wielu zakladek,\nAlt-i - Tryb jednej zakladki. +FILEBROWSER_SHOWRANK1HINT;Pokazuje zdjecia ocenione na 1 gwiazdke.\nSkrot: 1 +FILEBROWSER_SHOWRANK2HINT;Pokazuje zdjecia ocenione na 2 gwiazdki.\nSkrot: 2 +FILEBROWSER_SHOWRANK3HINT;Pokazuje zdjecia ocenione na 3 gwiazdki.\nSkrot: 3 +FILEBROWSER_SHOWRANK4HINT;Pokazuje zdjecia ocenione na 4 gwiazdki.\nSkrot: 4 +FILEBROWSER_SHOWRANK5HINT;Pokazuje zdjecia ocenione na 5 gwiazdek.\nSkrot: 5 +FILEBROWSER_SHOWRECENTLYSAVEDHINT;Pokazuje zapisane zdjecia.\nSkrot: Alt-7 +FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Pokazuje niezapisane zdjecia.\nSkrot: Alt-6 +FILEBROWSER_SHOWTRASHHINT;Pokazuje zawartosc kosza.\nSkrot: Ctrl-t +FILEBROWSER_SHOWUNCOLORHINT;Pokazuje zdjecia bez kolorowej etykiety.\nSkrot: Alt-0 +FILEBROWSER_SHOWUNRANKHINT;Pokazuje nieocenione zdjecia.\nSkrot: 0 +FILEBROWSER_STARTPROCESSINGHINT;Rozpoczyna przetwarzanie/zapisywanie plikow z kolejki. +FILEBROWSER_STARTPROCESSING;Rozpocznij przetwarzanie +FILEBROWSER_STOPPROCESSINGHINT;Zatrzymuje przetwarzanie zdjec. +FILEBROWSER_STOPPROCESSING;Zatrzymaj przetwarzanie +FILEBROWSER_THUMBSIZE;Rozmiar minaturek +FILEBROWSER_TOOLTIP_STOPPROCESSING;Rozpocznij przetwarzanie automatycznie gdy pojawi sie nowe zadanie. +FILEBROWSER_UNRANK_TOOLTIP;Usun ocene.\nSkrot: Shift-0 +FILEBROWSER_ZOOMINHINT;Zwieksza rozmiar miniaturek.\n\nSkroty:\n+ - Tryb wielu zakladek,\nAlt-+ - Tryb pojedynczej zakladki. +FILEBROWSER_ZOOMOUTHINT;Zmniejsza rozmiar miniaturek.\n\nSkroty:\n- - Tryb wielu zakladek,\nAlt-- - Tryb pojedynczej zakladki. +GENERAL_ABOUT;O programie +GENERAL_AFTER;Po +GENERAL_AUTO;Automatyczne +GENERAL_BEFORE;Przed +GENERAL_CANCEL;Anuluj +GENERAL_CLOSE;Zamknij +GENERAL_DISABLED;Wylaczone +GENERAL_DISABLE;Wylacz +GENERAL_ENABLED;Wlaczone +GENERAL_ENABLE;Wlacz +GENERAL_FILE;Plik +GENERAL_LANDSCAPE;Poziomo +GENERAL_NA;nd. +GENERAL_NONE;Zaden +GENERAL_NO;Nie +GENERAL_OK;OK +GENERAL_PORTRAIT;Pionowo +GENERAL_SAVE;Zapisz +GENERAL_UNCHANGED;(Niezmienione) +GENERAL_WARNING;Uwaga +HISTOGRAM_TOOLTIP_BAR;Pokazuje/Ukrywa wskaznik RGB.\nKlikniecie prawym przyciskiem myszy na podgladzie zdjecia blokuje/odblokowuje. +HISTOGRAM_TOOLTIP_B;Pokaz/Ukryj histogram blekitow. +HISTOGRAM_TOOLTIP_CHRO;Pokaz/Ukryj histogram chromatycznosci. +HISTOGRAM_TOOLTIP_FULL;Przelacz histogram pelny (wylaczone)/skalowany (wlaczone). +HISTOGRAM_TOOLTIP_G;Pokaz/Ukryj histogram zieleni. +HISTOGRAM_TOOLTIP_L;Pokaz/Ukryj histogram luminancji CIELab. +HISTOGRAM_TOOLTIP_RAW;Pokaz/Ukryj histogram raw. +HISTOGRAM_TOOLTIP_R;Pokaz/Ukryj histogram czerwieni. +HISTORY_CHANGED;Zmieniono +HISTORY_CUSTOMCURVE;Krzywa wlasna +HISTORY_DELSNAPSHOT;Usun migawke +HISTORY_FROMCLIPBOARD;Ze schowka +HISTORY_LABEL;Historia +HISTORY_MSG_1;Zdjecie zaladowane +HISTORY_MSG_2;Profil zaladowany +HISTORY_MSG_3;Profil zmieniony +HISTORY_MSG_4;Przegladanie historii +HISTORY_MSG_5;Swiatlosc +HISTORY_MSG_6;Kontrast +HISTORY_MSG_7;Czern +HISTORY_MSG_8;Kompensacja ekspozycji +HISTORY_MSG_9;Kompresja podswietlen +HISTORY_MSG_10;Kompresja cieni +HISTORY_MSG_11;Krzywa tonalna +HISTORY_MSG_12;Automatyczna ekspozycja +HISTORY_MSG_13;Przycinanie ekspozycji +HISTORY_MSG_14;L*a*b* - Swiatlosc +HISTORY_MSG_15;L*a*b* - Kontrast +HISTORY_MSG_16;- +HISTORY_MSG_17;- +HISTORY_MSG_18;- +HISTORY_MSG_19;Krzywa L* +HISTORY_MSG_20;Wyostrzanie +HISTORY_MSG_21;USM - Promien +HISTORY_MSG_22;USM - Sila +HISTORY_MSG_23;USM - Prog wyostrzania +HISTORY_MSG_24;USM - Wyostrz tylko krawedzie +HISTORY_MSG_25;USM - Promien detekcji krawedzi +HISTORY_MSG_26;USM - Tolerancja krawedzi +HISTORY_MSG_27;USM - Kontrola poswiaty +HISTORY_MSG_28;USM - Stopien kontroli poswiaty +HISTORY_MSG_29;Metoda wyostrzania +HISTORY_MSG_30;RLD - Promien +HISTORY_MSG_31;RLD - Sila +HISTORY_MSG_32;RLD - Tlumienie +HISTORY_MSG_33;RLD - Powtorzenia +HISTORY_MSG_34;LCP - Korekcja dystorsji +HISTORY_MSG_35;LCP - Korekcja winietowania +HISTORY_MSG_36;LCP - Korekcja aberacji +HISTORY_MSG_37;Automatyczna ekspozycja +HISTORY_MSG_38;Metoda balansu bieli +HISTORY_MSG_39;BB - Temperatura +HISTORY_MSG_40;BB - Odcien +HISTORY_MSG_41;Tryb krzywej 1 +HISTORY_MSG_42;Krzywa 1 +HISTORY_MSG_43;Tryb krzywej 2 +HISTORY_MSG_44;Odszumianie lum. - Promien +HISTORY_MSG_45;Odszumianie lum. - Tolerancja krawedzi +HISTORY_MSG_46;Odszumianie koloru +HISTORY_MSG_47;Mieszanie podswietlen ICC z matryca +HISTORY_MSG_48;Uzycie krzywej tonalnej z DCP +HISTORY_MSG_49;Illuminant DCP +HISTORY_MSG_50;Cienie/Podswietlenia +HISTORY_MSG_51;C/P - Podswietlenia +HISTORY_MSG_52;C/P - Cienie +HISTORY_MSG_53;C/P - Szerokosc tonalna podsw. +HISTORY_MSG_54;C/P - Szerokosc tonalna cieni +HISTORY_MSG_55;C/P - Kontrast lokalny +HISTORY_MSG_56;C/P - Promien +HISTORY_MSG_57;Obrot dyskretny +HISTORY_MSG_58;Odbicie w poziomie +HISTORY_MSG_59;Odbicie w pionie +HISTORY_MSG_60;Obrot +HISTORY_MSG_61;Auto-wypelnianie +HISTORY_MSG_62;Korekcja dystorsji obiektywu +HISTORY_MSG_63;Migawka wybrana +HISTORY_MSG_64;Kadrowanie +HISTORY_MSG_65;Korekcja aberracji chromatycznej +HISTORY_MSG_66;Rekonstrukcja przeswietlen +HISTORY_MSG_67;Rekonstrukcja przeswietlen - Sila +HISTORY_MSG_68;Rekonstrukcja przeswietlen - Metoda +HISTORY_MSG_69;Robocza przestrzen kolorow +HISTORY_MSG_70;Wyjsciowa przestrzen kolorow +HISTORY_MSG_71;Wejsciowa przestrzen kolorow +HISTORY_MSG_72;KW - Sila +HISTORY_MSG_73;Mieszacz kanalow +HISTORY_MSG_74;Zmiany rozmiaru - Skala +HISTORY_MSG_75;Zmiany rozmiaru - Metoda +HISTORY_MSG_76;Metadane Exif +HISTORY_MSG_77;Metadane IPTC +HISTORY_MSG_78;- +HISTORY_MSG_79;Zmiany rozmiaru - Szerokosc +HISTORY_MSG_80;Zmiany rozmiaru - Wysokosc +HISTORY_MSG_81;Zmiany rozmiaru +HISTORY_MSG_82;Profil zmieniony +HISTORY_MSG_83;C/P - Ostra maska +HISTORY_MSG_84;Korekcja perspektywy +HISTORY_MSG_85;LCP +HISTORY_MSG_86;Krzywe RGB - Tryb luminancji +HISTORY_MSG_87;Redukcja szumow impulsowych +HISTORY_MSG_88;RSI - Prog +HISTORY_MSG_89;Redukcja szumow +HISTORY_MSG_90;RS - Luminancja +HISTORY_MSG_91;RS - Chrominancja +HISTORY_MSG_92;RS - Gamma +HISTORY_MSG_93;Kontrast wg. poziomu detali +HISTORY_MSG_94;Kontrast wg. poziomu detali +HISTORY_MSG_95;L*a*b* - Chromatycznosc +HISTORY_MSG_96;Krzywa a* +HISTORY_MSG_97;Krzywa b* +HISTORY_MSG_98;Algorytm demozaikowania +HISTORY_MSG_99;Filtrowanie goracych pikseli +HISTORY_MSG_100;Nasycenie RGB +HISTORY_MSG_101;HSV - Odcien +HISTORY_MSG_102;HSV - Nasycenie +HISTORY_MSG_103;HSV - Mocy swiatla bialego +HISTORY_MSG_104;Ekwalizator HSV +HISTORY_MSG_105;Usuwanie widma +HISTORY_MSG_106;Usuwanie widma - Promien +HISTORY_MSG_107;Usuwanie widma - Prog +HISTORY_MSG_108;Prog kompresji przeswietlen +HISTORY_MSG_109;Zmiana rozmiaru - Wymiary obwodu +HISTORY_MSG_110;Zmiana rozmiaru dotyczy +HISTORY_MSG_111;L*a*b* - Unikaj przycinania koloru +HISTORY_MSG_112;- +HISTORY_MSG_113;L*a*b* - Ograniczenie nasyczenia +HISTORY_MSG_114;DCB - Liczba powtorzen +HISTORY_MSG_115;DCB - Zapobieganie falszowaniu koloru +HISTORY_MSG_116;DCB - Ulepszone +HISTORY_MSG_117;Korekcja aberracji raw - Czerwona +HISTORY_MSG_118;Korekcja aberracji raw - Niebieska +HISTORY_MSG_119;Redukcja szumow liniowych +HISTORY_MSG_120;Wyrownanie zieleni +HISTORY_MSG_121;Autokorekcja aberracji chromatycznej +HISTORY_MSG_122;Czarna klatka - Auto-wybor +HISTORY_MSG_123;Czarna klatka - Wybor +HISTORY_MSG_124;Korekcja punktu bieli +HISTORY_MSG_125;Zachowanie przeswietlen +HISTORY_MSG_126;Puste pole - Wybor +HISTORY_MSG_127;Puste pole - Auto-wybor +HISTORY_MSG_128;Puste pole - Promien rozmycia +HISTORY_MSG_129;Puste pole - Typ rozmycia +HISTORY_MSG_130;Automatyczna korekcja dystorsji +HISTORY_MSG_131;RS - Luma +HISTORY_MSG_132;RS - Chroma +HISTORY_MSG_133;Gamma wyjsciowa +HISTORY_MSG_134;Wolna gamma +HISTORY_MSG_135;Wolna gamma +HISTORY_MSG_136;Nachylenie gamma +HISTORY_MSG_137;Poziom czerni - Zielony 1 +HISTORY_MSG_138;Poziom czerni - Czerwony +HISTORY_MSG_139;Poziom czerni - Niebieski +HISTORY_MSG_140;Poziom czerni - Zielony 2 +HISTORY_MSG_141;Poziom czerni - Polacz zielone +HISTORY_MSG_142;WK - Powtorzenia +HISTORY_MSG_143;WK - Sila +HISTORY_MSG_144;Mikrokontrast - Sila +HISTORY_MSG_145;Mikrokontrast - Jednolitosc +HISTORY_MSG_146;Wyostrzanie krawedzi +HISTORY_MSG_147;Wyostrzanie krawedzi - tylko luminacja +HISTORY_MSG_148;Mikrokontrast +HISTORY_MSG_149;Mikrokontrast - matryca 3x3 +HISTORY_MSG_150;Redukcja szumu i artefaktow po demozaikowaniu +HISTORY_MSG_151;Jaskrawosc +HISTORY_MSG_152;Jaskrawosc - Ppastelowe +HISTORY_MSG_153;Jaskrawosc - Nasycone +HISTORY_MSG_154;Jaskrawosc - Chron odcienie skory +HISTORY_MSG_155;Jaskrawosc - Zapobiegaj zmianom kolorow +HISTORY_MSG_156;Jaskrawosc - Polacz pastelowe i nasycone +HISTORY_MSG_157;Jaskrawosc - Prog pastelowych/nasyconych +HISTORY_MSG_158;TM - Sila +HISTORY_MSG_159;TM - Wyszukanie krawedzi +HISTORY_MSG_160;TM - Skala +HISTORY_MSG_161;TM - Powtarzanie rozwazania +HISTORY_MSG_162;Tone Mapping +HISTORY_MSG_163;Krzywe RGB - Czerwona +HISTORY_MSG_164;Krzywe RGB - Zielona +HISTORY_MSG_165;Krzywe RGB - Niebieska +HISTORY_MSG_166;Neutralna ekspozycja +HISTORY_MSG_167;- +HISTORY_MSG_168;L*a*b* - Krzywa CC +HISTORY_MSG_169;L*a*b* - Krzywa CH +HISTORY_MSG_170;Jaskrawosc - Krzywa HH +HISTORY_MSG_171;L*a*b* - Krzywa LC +HISTORY_MSG_172;L*a*b* - Ogranicz LC +HISTORY_MSG_173;RS - Szczegoly luminancji +HISTORY_MSG_174;CIECAM02 +HISTORY_MSG_175;CAM02 - Adaptacja CAT02 +HISTORY_MSG_176;CAM02 - Otoczenie +HISTORY_MSG_177;CAM02 - Luminancja sceny +HISTORY_MSG_178;CAM02 - Luminancja widowni +HISTORY_MSG_179;CAM02 - Model punktu bieli +HISTORY_MSG_180;CAM02 - Swiatlosc (J) +HISTORY_MSG_181;CAM02 - Chroma (C) +HISTORY_MSG_182;CAM02 - Automatyczne CAT02 +HISTORY_MSG_183;CAM02 - Kontrast (J) +HISTORY_MSG_184;CAM02 - Otoczenie sceny +HISTORY_MSG_185;CAM02 - Kontrola gamma +HISTORY_MSG_186;CAM02 - Algorytm +HISTORY_MSG_187;CAM02 - Ochrona czerwieni/skory +HISTORY_MSG_188;CAM02 - Jasnosc (Q) +HISTORY_MSG_189;CAM02 - Kontrast (Q) +HISTORY_MSG_190;CAM02 - Nasycenie (S) +HISTORY_MSG_191;CAM02 - Barwistosc (M) +HISTORY_MSG_192;CAM02 - Odcien (hue, h) +HISTORY_MSG_193;CAM02 - Krzywa tonalna 1 +HISTORY_MSG_194;CAM02 - Krzywa tonalna 2 +HISTORY_MSG_195;CAM02 - Krzywa tonalna 1 +HISTORY_MSG_196;CAM02 - Krzywa tonalna 2 +HISTORY_MSG_197;CAM02 - Krzywa koloru +HISTORY_MSG_198;CAM02 - Krzywa koloru +HISTORY_MSG_199;CAM02 - Histogramy wyjsciowe +HISTORY_MSG_200;CAMO2 - Tone mapping +HISTORY_MSG_201;RS - Chrominancja - R&G +HISTORY_MSG_202;RS - Chrominancja - B&Y +HISTORY_MSG_203;RS - Metoda +HISTORY_MSG_204;Kroki poprawy LMMSE +HISTORY_MSG_205;CAM02 - Gorace/uszkodzone px +HISTORY_MSG_206;CAT02 - Auto luminancja sceny +HISTORY_MSG_207;Usuwanie widma - Krzywa odcieni +HISTORY_MSG_208;BB - Ekwalizator N/C +HISTORY_MSG_210;FP - Kat +HISTORY_MSG_211;Filtr Polowkowy +HISTORY_MSG_212;Winietowanie - Sila +HISTORY_MSG_213;Winietowanie +HISTORY_MSG_214;Czarno-biale (B&W) +HISTORY_MSG_215;B&W - MK - Czerwony +HISTORY_MSG_216;B&W - MK - Zielony +HISTORY_MSG_217;B&W - MK - Niebieski +HISTORY_MSG_218;B&W - Gamma - Czerwony +HISTORY_MSG_219;B&W - Gamma - Zielony +HISTORY_MSG_220;B&W - Gamma - Niebieski +HISTORY_MSG_221;B&W - Filtr barwny +HISTORY_MSG_222;B&W - Ustawienia +HISTORY_MSG_223;B&W - MK - Pomaranczowy +HISTORY_MSG_224;B&W - MK - Zolty +HISTORY_MSG_225;B&W - MK - Cyjanowy +HISTORY_MSG_226;B&W - MK - Magenta +HISTORY_MSG_227;B&W - MK - Purpurowy +HISTORY_MSG_228;B&W - Ekwalizator luminancji +HISTORY_MSG_229;B&W - Ekwalizator luminancji +HISTORY_MSG_230;B&W - Tryb +HISTORY_MSG_231;B&W - Krzywa 'Przed' +HISTORY_MSG_232;B&W - Rodzaj krzywej 'Przed' +HISTORY_MSG_233;B&W - Krzywa 'Po' +HISTORY_MSG_234;B&W - Rodzaj krzywej 'Po' +HISTORY_MSG_235;B&W - Auto-mieszanie kolorow +HISTORY_MSG_236;- +HISTORY_MSG_237;B&W - Mieszacz +HISTORY_MSG_238;FP - Wtapianie +HISTORY_MSG_239;FP - Sila +HISTORY_MSG_240;FP - Srodek +HISTORY_MSG_241;Winietowanie - Wtapianie +HISTORY_MSG_242;Winietowanie - Okraglosc +HISTORY_MSG_243;Winietowanie - Promien +HISTORY_MSG_244;Winietowanie - Sila +HISTORY_MSG_245;Winietowanie - Srodek +HISTORY_MSG_246;Krzywa CL +HISTORY_MSG_247;Krzywa LH +HISTORY_MSG_248;Krzywa HH +HISTORY_MSG_249;KwgPS - Prog +HISTORY_MSG_250;RS - Ulepszona +HISTORY_MSG_251;B&W - Algorytm +HISTORY_MSG_252;KwgPS - Odcienie skory +HISTORY_MSG_253;KwgPS - Redukcja bledow +HISTORY_MSG_254;KwgPS - Odcienie skory +HISTORY_MSG_255;RS - Filtr mediana +HISTORY_MSG_256;RS - Wielkosc okna mediana +HISTORY_MSG_257;Koloryzacja +HISTORY_MSG_258;Koloryzacja - Kolor +HISTORY_MSG_259;Koloryzacja - Przezroczystosc +HISTORY_MSG_260;Koloryzacja - Przezroczystosc a*[b*] +HISTORY_MSG_261;Koloryzacja - Metoda +HISTORY_MSG_262;Koloryzacja - Przezroczystosc b* +HISTORY_MSG_263;Koloryzacja - Cienie - Czerwony +HISTORY_MSG_264;Koloryzacja - Cienie - Zielony +HISTORY_MSG_265;Koloryzacja - Cienie - Niebiski +HISTORY_MSG_266;Koloryzacja - Þolcienie - Czerwone +HISTORY_MSG_267;Koloryzacja - Þolcienie - Zielone +HISTORY_MSG_268;Koloryzacja - Þolcienie - Niebieskie +HISTORY_MSG_269;Koloryzacja - Podswietlenia - Czerwone +HISTORY_MSG_270;Koloryzacja - Podswietlenia - Zielona +HISTORY_MSG_271;Koloryzacja - Podswietlenia - Niebieskie +HISTORY_MSG_272;Koloryzacja - Balans +HISTORY_MSG_273;Koloryzacja - Reset +HISTORY_MSG_274;Koloryzacja - Nasycenie cieni +HISTORY_MSG_275;Koloryzacja - Nasycenie jasnych +HISTORY_MSG_276;Koloryzacja - Przezroczystosc +HISTORY_MSG_277;--unused-- +HISTORY_MSG_278;Koloryzacja - Zachowaj luminancje +HISTORY_MSG_279;Koloryzacja - Cienie +HISTORY_MSG_280;Koloryzacja - Tony jasne +HISTORY_MSG_281;Koloryzacja - Sila nasycenia +HISTORY_MSG_282;Koloryzacja - Prog nasycenia +HISTORY_MSG_283;Koloryzacja - Sila +HISTORY_MSG_284;Koloryzacja - Auto ochrona przesycenia +HISTORY_MSG_285;RS - Mediana - Metoda +HISTORY_MSG_286;RS - Mediana - Typ +HISTORY_MSG_287;RS - Mediana - Powtarzanie +HISTORY_MSG_288;Puste pole - Zabezp. przed obcinaniem +HISTORY_MSG_289;Puste pole - Auto-zabezp. przed obcinaniem +HISTORY_MSG_290;Prog czerni - Czerwony +HISTORY_MSG_291;Prog czerni - Zielony +HISTORY_MSG_292;Prog czerni - Niebieski +HISTORY_MSG_293;Symulacja Kliszy +HISTORY_MSG_294;Symulacja Kliszy - Sila +HISTORY_MSG_295;Symulacja Kliszy - Klisza +HISTORY_MSG_296;RS - Modulacja luminancji +HISTORY_MSG_297;RS - Jakosc +HISTORY_MSG_298;Filtrowanie martwych pikseli +HISTORY_NEWSNAPSHOT;Nowa migawka +HISTORY_NEWSNAPSHOT_TOOLTIP;Skrot: Alt-s +HISTORY_SNAPSHOTS;Migawki +HISTORY_SNAPSHOT;Migawka +IPTCPANEL_AUTHORSPOSITIONHINT;Stanowisko lub funkcja autora lub autorow dziela (By-line Title). +IPTCPANEL_AUTHORSPOSITION;Stanowisko +IPTCPANEL_AUTHOR;Autor +IPTCPANEL_CAPTIONHINT;Tekstowy opis tresci (Caption - Abstract). +IPTCPANEL_CAPTIONWRITERHINT;Imie i nazwisko osoby biorace udzial w opracowywaniu, edytowanie lub korygowania obrazu lub opisu (Writer - Editor). +IPTCPANEL_CAPTIONWRITER;Autor opisu +IPTCPANEL_CAPTION;Tytul +IPTCPANEL_CATEGORYHINT;Identyfikuje temat zdjecia w opinii jego dostawcy (Category). +IPTCPANEL_CATEGORY;Kategoria +IPTCPANEL_CITYHINT;Miasto w ktorym wykonano zdjecie (City). +IPTCPANEL_CITY;Miasto +IPTCPANEL_COPYHINT;Kopiuje ustawienia IPTC do schowka +IPTCPANEL_COPYRIGHTHINT;Wazne uwagi o prawach autorskich (Copyright Notice). +IPTCPANEL_COPYRIGHT;Prawa autorskie +IPTCPANEL_COUNTRYHINT;Nazwa kraju lub lokalizacji, gdzie zostalo wykonane zdjecie (Country - Primary Location Name). +IPTCPANEL_COUNTRY;Kraj +IPTCPANEL_CREDITHINT;Identyfikuje dostawce zdjecia, niekoniecznie wlasciciela lub autora (Credit). +IPTCPANEL_CREDIT;Zasluga +IPTCPANEL_DATECREATEDHINT;Data powstania intelektualnej tresci zdjecia. Format: JJJJMMTT (Date Created). +IPTCPANEL_DATECREATED;Data utworzenia +IPTCPANEL_EMBEDDEDHINT;Resetuje dane IPTC do domyslnych ustawien osadzonych w orginalnym zdjeciu +IPTCPANEL_EMBEDDED;Osadzony +IPTCPANEL_HEADLINEHINT;Gotowy do opublikowania wpis streszczajacy zawratosc zdjecia (Headline). +IPTCPANEL_HEADLINE;Naglowek +IPTCPANEL_INSTRUCTIONSHINT;Inne wskazowki redakcyjne dotyczace korzystania z obrazu (Special Instructions). +IPTCPANEL_INSTRUCTIONS;Instrukcje +IPTCPANEL_KEYWORDSHINT;Wskazuje konkretne tresci mozliwe do odszukania (Keywords). +IPTCPANEL_KEYWORDS;Slowa kluczowe +IPTCPANEL_PASTEHINT;Wstawia ustawienia IPTC ze schowka +IPTCPANEL_PROVINCEHINT;Wojewodztwo, gmina, stan gdzie zostalo wykonane zdjecie (Province-State). +IPTCPANEL_PROVINCE;Stan, wojewodztwo, dystrykt itd. +IPTCPANEL_RESETHINT;Resetuje do domyslnych ustawien profilu +IPTCPANEL_RESET;Reset +IPTCPANEL_SOURCEHINT;Pierwotny wlasciciel tresci intelektualnych zdjecia (Source). +IPTCPANEL_SOURCE;Zrodlo +IPTCPANEL_SUPPCATEGORIESHINT;Doprecyzowuje kategorie tematyczne zdjecia (Supplemental Categories). +IPTCPANEL_SUPPCATEGORIES;Dodatkowe kategorie tematyczne +IPTCPANEL_TITLEHINT;Skrocony temat odniesienia zdjecia (Object Name). +IPTCPANEL_TITLE;Tytul +IPTCPANEL_TRANSREFERENCEHINT;Numer badz kod identyfikujacy zlecenie utworzony zazwyczaj przez fotografa przy transmisji umozliwiajacy sledzenie obrazu w obiegu. +IPTCPANEL_TRANSREFERENCE;Kod ident. zlecenie +MAIN_BUTTON_FULLSCREEN;Pelen ekran +MAIN_BUTTON_NAVNEXT_TOOLTIP;Przejdz do nastepnego zdjecia wzgledem zdjecia otwartego w Edytorze.\nSkrot: Shift-F4\n\nAby przejsc do nastepnego zdjecia wzgledem miniaturki wybranej w Nawigatorze Zdjec:\nSkrot: F4 +MAIN_BUTTON_NAVPREV_TOOLTIP;Przejdz do poprzedniego zdjecia wzgledem zdjecia otwartego w Edytorze.\nSkrot: Shift-F3 \n\nAby przejsc do poprzedniego zdjecia wzgledem miniaturki wybranej w Nawigatorze Zdjec:\nSkrot: F3 +MAIN_BUTTON_NAVSYNC_TOOLTIP;Synchronizuj Nawigator Zdjec z Edytorem aby ukazac miniaturke obecnie otwartego zdjecia, oraz usun filtry w Nawigatorze Zdjec.\nSkrot: x\n\nJak wyzej, ale bez usuwania filtrow:\nSkrot: y\n(Miniaturka otwartego zdjecia nie zostanie wyswietlona jesli filtr ja ukrywa). +MAIN_BUTTON_PREFERENCES;Ustawienia +MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Dodaj biezace zdjecie do kolejki przetwarzania Ctrl+B +MAIN_BUTTON_SAVE_TOOLTIP;Zapisz biezace zdjecieCtrl+S +MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Otworz biezace zdjecie w zewnetrznym edytorze.\nSkrot: Ctrl+e +MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Pokaz/Ukryj wszystkie panele boczne.\nSkrot: m +MAIN_BUTTON_UNFULLSCREEN;Zwolnij ekran +MAIN_FRAME_BATCHQUEUE;Kolejka +MAIN_FRAME_BATCHQUEUE_TOOLTIP;Przetwarzanie wsadowe\nSkrot: Ctrl-F3 +MAIN_FRAME_EDITOR;Edytor +MAIN_FRAME_EDITOR_TOOLTIP;Edytor.\nSkrot: Ctrl-F4 +MAIN_FRAME_FILEBROWSER;Przegladarka plikow +MAIN_FRAME_FILEBROWSER_TOOLTIP; Przegladarka plikow.\nSkrot: Ctrl-F2 +MAIN_FRAME_PLACES;Miejsca +MAIN_FRAME_PLACES_ADD;Dodaj +MAIN_FRAME_PLACES_DEL;Usun +MAIN_FRAME_RECENT;Ostatnio uzywane foldery +MAIN_MSG_ALREADYEXISTS;Plik juz istnieje. +MAIN_MSG_CANNOTLOAD;Nie mozna wczytac obrazu +MAIN_MSG_CANNOTSAVE;Blad zapisu pliku +MAIN_MSG_CANNOTSTARTEDITOR;Nie mozna uruchomic edytora. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Prosze wprowadzic prawidlowa sciezke w Ustawieniach. +MAIN_MSG_EMPTYFILENAME;Nie podano nazwy pliku! +MAIN_MSG_IMAGEUNPROCESSED;Ta komenda wymaga aby wszystkie wybrane zdjecia byly wpierw wywolane poprzez kolejke. +MAIN_MSG_NAVIGATOR;Nawigator +MAIN_MSG_OPERATIONCANCELLED;Operacje anulowano +MAIN_MSG_PATHDOESNTEXIST;Sciezka\n\n%1\n\nnie istnieje. Wybierz przawidlowa sciezke w Ustawieniach. +MAIN_MSG_QOVERWRITE;Zastapic? +MAIN_MSG_SETPATHFIRST;Aby uzyc tej funkcji nalezy wpierw wybrac odpowiednia sciezke docelowa w Ustawieniach! +MAIN_MSG_WRITEFAILED;Zapis nie powiodl sie:\n\n"%1"\n\nUpewnij sie, ze folder istnieje oraz ze mozna do niego zapisywac. +MAIN_TAB_COLOR;Kolor +MAIN_TAB_COLOR_TOOLTIP;Skrot: Alt-c +MAIN_TAB_DETAIL;Szczegoly +MAIN_TAB_DETAIL_TOOLTIP;Skrot: Alt-d +MAIN_TAB_DEVELOP; Przetwarzanie +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPORT; Szybki eksport +MAIN_TAB_EXPOSURE;Ekspozycja +MAIN_TAB_EXPOSURE_TOOLTIP;Skrot: Alt-e +MAIN_TAB_FILTER; Filtr +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadane +MAIN_TAB_METADATA_TOOLTIP;Skrot: Alt-m +MAIN_TAB_RAW;Raw +MAIN_TAB_RAW_TOOLTIP;Skrot: Alt-r +MAIN_TAB_TRANSFORM;Transformacje +MAIN_TAB_TRANSFORM_TOOLTIP;Skrot: Alt-t +MAIN_TOOLTIP_BACKCOLOR0;Kolor tla podgladu: Tematyczny\nSkrot: 9 +MAIN_TOOLTIP_BACKCOLOR1;Kolor tla podgladu: Czarny\nSkrot: 9 +MAIN_TOOLTIP_BACKCOLOR2;Kolor tla podgladu: Bialy\nSkrot: 9 +MAIN_TOOLTIP_BEFOREAFTERLOCK;Zablokuj / Odblokuj widok Przed\n\nZablokuj: nie zmieniaj widoku Przed - \nPrzydatne w porownywaniu zablokowanego obrazu z obrazem na ktorym wykonano wiele zmian.\n\nOdblokuj: widok Przed bedzie sledzil widok Po o jeden krok do tylu, pokazujac obraz przed efektem aktualnie uzytego narzedzia. +MAIN_TOOLTIP_HIDEHP;Pokaz/ukryj lewy panel (razem z historia).\nSkrot: l +MAIN_TOOLTIP_INDCLIPPEDH;Pokaz obciete przeswietlenia.\nSkrot: < +MAIN_TOOLTIP_INDCLIPPEDS;Pokaz obciete niedoswietlenia.\nSkrot: > +MAIN_TOOLTIP_PREVIEWB;Podglad kanalu niebieskiego.\nSkrot: b +MAIN_TOOLTIP_PREVIEWFOCUSMASK;Podglad maski ostrosci.\nSkrot: Shift-f\n\nDokladniejsze w przypadku zdjec o plytkiej glebi ostrosci, niskim pozimie szumow i o wiekszym przyblizeniu. W przypadku zdjec o wyzszym poziomie szumow maska ostrosci bedzie dokladniejsza przy mniejszym zoomie (10-30%). +MAIN_TOOLTIP_PREVIEWG;Podglad kanalu zielonego.\nSkrot: g +MAIN_TOOLTIP_PREVIEWL;Podglad kanalu jasnosci.\nSkrot: v\n\n0.299*R + 0.587*G + 0.114*B +MAIN_TOOLTIP_PREVIEWR;Podglad kanalu czerwonego.\nSkrot: r +MAIN_TOOLTIP_QINFO;Informacje o zdjeciu.\nSkrot: i +MAIN_TOOLTIP_SHOWHIDELP1;Pokaz/Ukryj lewy panel.\nSkrot: l +MAIN_TOOLTIP_SHOWHIDERP1;Pokaz/Ukryj prawy panel.\nSkrot: Alt-l +MAIN_TOOLTIP_SHOWHIDETP1;Pokaz/Ukryj gorny panel.\nSkrot: Shift-l +MAIN_TOOLTIP_THRESHOLD;Prog +MAIN_TOOLTIP_TOGGLE;Przelacz widok Przed/Po.\nSkrot: Shift-b +NAVIGATOR_B;B: +NAVIGATOR_G;G: +NAVIGATOR_H;H: +NAVIGATOR_LAB_A;a*: +NAVIGATOR_LAB_B;b*: +NAVIGATOR_LAB_L;L*: +NAVIGATOR_NA; -- +NAVIGATOR_R;R: +NAVIGATOR_S;S: +NAVIGATOR_V;V: +NAVIGATOR_XY_FULL;Szerokosc: %1, Wysokosc: %2 +NAVIGATOR_XY_NA;x: --, y: -- +OPTIONS_DEFIMG_MISSING;Nie znaleziono domyslnego profilu dla plikow innych niz raw, lub profil nie jest ustawiony.\n\nProsze sprawdz folder z profilami - mozliwe ze zostal skasowany badz uszkodzony.\n\nDomyslne wewnetrzne ustawienia zostana uzyte. +OPTIONS_DEFRAW_MISSING;Nie znaleziono domyslnego profilu dla plikow raw, lub profil nie jest ustawiony.\n\nProsze sprawdz folder z profilami - mozliwe ze zostal skasowany badz uszkodzony.\n\nDomyslne wewnetrzne ustawienia zostana uzyte. +PARTIALPASTE_BASICGROUP;Podstawowe ustawienia +PARTIALPASTE_CACORRECTION;Korekcja aberacji chr. +PARTIALPASTE_CHANNELMIXERBW;Czarno-biale +PARTIALPASTE_CHANNELMIXER;Mieszacz kanalow +PARTIALPASTE_COARSETRANS;Obrot dyskretny / odbicie +PARTIALPASTE_COLORAPP;CIECAM02 +PARTIALPASTE_COLORGROUP;Ustawienia zwiazane z kolorem +PARTIALPASTE_COLORTONING;Koloryzacja +PARTIALPASTE_COMMONTRANSFORMPARAMS;Auto-wypelnianie +PARTIALPASTE_COMPOSITIONGROUP;Ustawienia kompozycji +PARTIALPASTE_CROP;Kadrowanie +PARTIALPASTE_DARKFRAMEAUTOSELECT;Auto-wybor czarnej klatki +PARTIALPASTE_DARKFRAMEFILE;Wybor czarnej klatki +PARTIALPASTE_DEFRINGE;Usuwanie widma +PARTIALPASTE_DETAILGROUP;Ustawienia szczegolowe +PARTIALPASTE_DIALOGLABEL;Czesciowe wklejenie profilu przetwarzania +PARTIALPASTE_DIRPYRDENOISE;Redukcja szumu +PARTIALPASTE_DIRPYREQUALIZER;Kontrast wg. poziomu detali +PARTIALPASTE_DISTORTION;Korekcja znieksztalcenia +PARTIALPASTE_EPD;Tone Mapping +PARTIALPASTE_EVERYTHING;Wszystko +PARTIALPASTE_EXIFCHANGES;Exif +PARTIALPASTE_EXPOSURE;Ekspozycja +PARTIALPASTE_FILMSIMULATION;Symulacja kliszy +PARTIALPASTE_FLATFIELDAUTOSELECT;Puste pole - Auto-wybor +PARTIALPASTE_FLATFIELDBLURRADIUS;Puste pole - Promien +PARTIALPASTE_FLATFIELDBLURTYPE;Puste pole - Typ +PARTIALPASTE_FLATFIELDCLIPCONTROL;Puste pole - Zabezp. przed obcinaniem +PARTIALPASTE_FLATFIELDFILE;Puste pole - Wybor +PARTIALPASTE_GRADIENT;Filtr polowkowy +PARTIALPASTE_HSVEQUALIZER;Ekwalizator HSV +PARTIALPASTE_ICMGAMMA;Gamma wyjsciowa +PARTIALPASTE_ICMSETTINGS;Ustawienia ICM +PARTIALPASTE_IMPULSEDENOISE;Redukcja szumow impulsowych +PARTIALPASTE_IPTCINFO;IPTC +PARTIALPASTE_LABCURVE;Regulacje L*a*b* +PARTIALPASTE_LENSGROUP;Ustawienia zwiazane z obiektywem +PARTIALPASTE_LENSPROFILE;Profil korekcji obiektywu LCP +PARTIALPASTE_METAGROUP;Metadane +PARTIALPASTE_PCVIGNETTE;Winietowanie +PARTIALPASTE_PERSPECTIVE;Perspektywa +PARTIALPASTE_PREPROCESS_DEADPIXFILT;Filtr martwych pikseli +PARTIALPASTE_PREPROCESS_GREENEQUIL;Wyrownanie zieleni +PARTIALPASTE_PREPROCESS_HOTPIXFILT;Filtr goracych pikseli +PARTIALPASTE_PREPROCESS_LINEDENOISE;Redukcja szumow liniowych +PARTIALPASTE_RAWCACORR_AUTO;Autokorekcja aberracji chr. +PARTIALPASTE_RAWCACORR_CABLUE;AbChr niebieski +PARTIALPASTE_RAWCACORR_CARED;AbChr czerwony +PARTIALPASTE_RAWEXPOS_BLACK;Poziomy czerni +PARTIALPASTE_RAWEXPOS_LINEAR;Korekcja punktu bieli +PARTIALPASTE_RAWEXPOS_PRESER;Zachowanie przeswietlen +PARTIALPASTE_RAWGROUP;Ustawienia raw +PARTIALPASTE_RAW_DCBENHANCE;Zastosuj poprawe DCB +PARTIALPASTE_RAW_DCBITERATIONS;Liczba powtorzen DCB +PARTIALPASTE_RAW_DMETHOD;Algorytm demozaikowania +PARTIALPASTE_RAW_FALSECOLOR;Tlumienie falszowania koloru +PARTIALPASTE_RAW_LMMSEITERATIONS;Kroki poprawy LMMSE +PARTIALPASTE_RESIZE;Zmiana rozmiaru +PARTIALPASTE_RGBCURVES;Krzywe RGB +PARTIALPASTE_ROTATION;Obrot +PARTIALPASTE_SHADOWSHIGHLIGHTS;Cienie/Podswietlenia +PARTIALPASTE_SHARPENEDGE;Krawedzie +PARTIALPASTE_SHARPENING;Wyostrzanie +PARTIALPASTE_SHARPENMICRO;Mikrokontrast +PARTIALPASTE_VIBRANCE;Jaskrawosc +PARTIALPASTE_VIGNETTING;Korekcja winietowania +PARTIALPASTE_WHITEBALANCE;Balans bieli +PREFERENCES_ADD;Dodaj +PREFERENCES_APPLNEXTSTARTUP;wymaga ponownego uruchomienia +PREFERENCES_AUTOMONPROFILE;Automatycznie uzyj systemowego profilu monitora +PREFERENCES_BATCH_PROCESSING;Przetwarzanie wsadowe +PREFERENCES_BEHADDALLHINT;Ustaw wszystkie narzedzia w tryb Dodaj.\nZmiany parametrow w panelu edycji zbiorczej zostana traktowane jako roznice do poprzednich wartosci. +PREFERENCES_BEHADDALL;'Dodaj' wszystkie +PREFERENCES_BEHAVIOR;Zachowanie +PREFERENCES_BEHSETALLHINT;Ustaw wszystkie narzedzia w tryb Ustaw.\nZmiany parametrow w panelu edycji zbiorczej zostana traktowane jako absolutne, nie biorac pod uwage poprzednich wartosci. +PREFERENCES_BEHSETALL;'Ustaw' wszystkie +PREFERENCES_BLACKBODY;Wolfram +PREFERENCES_CACHECLEARALL;Wyczysc wszystko +PREFERENCES_CACHECLEARPROFILES;Wyczysc profile +PREFERENCES_CACHECLEARTHUMBS;Wyczysc miniaturki +PREFERENCES_CACHEMAXENTRIES;Maksymalna liczba wpisow w pamieci podrecznej +PREFERENCES_CACHEOPTS;Opcje pamieci podrecznej +PREFERENCES_CACHETHUMBHEIGHT;Maksymalna wysokosc miniatury +PREFERENCES_CIEART;CIECAM02 optymalizacja +PREFERENCES_CIEART_LABEL;Uzyj precyzje zmiennoprzecinkowa zamiast podwojna. +PREFERENCES_CIEART_TOOLTIP;Gdy umozliwione, kalkulacje CIECAM02 sa wykonywane w notacji zmiennoprzecinkowej o pojedynczej precyzji zamiast podwojnej. Skraca to czas egzekucji kosztem nieistotnej zmiany w jakosci. +PREFERENCES_CLIPPINGIND;Pokazywanie obcietych przeswietlen/cieni +PREFERENCES_CLUTSDIR;Folder obrazow HaldCLUT +PREFERENCES_CMETRICINTENT;Sposob odwzorowania barw +PREFERENCES_CUSTPROFBUILDHINT;Plik wykonywalny (lub skrypt) uruchamiany kiedy trzeba wygenerowac profil przetwarzania dla zdjecia.\n\nSciezka pliku nosnego (w stylu *.ini czyli sekcje i klucze/parametry) wystepuje jako parametr wiersza polecen. Plik ten zawiera przerozne parametry oraz dane Exif dzieki ktorym odpowiedni program badz skrypt moze wygenerowac plik PP3 wedlug regul.\n\nUWAGA: Twoja odpowiedzialnoscia jest prawidlowe uzycie cudzyslowiow w przypadku sciezek zawierajacych spacje i znaki specjalne. +PREFERENCES_CUSTPROFBUILDKEYFORMAT;Rodzaj kluczy +PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME;Nazwa +PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;TagID +PREFERENCES_CUSTPROFBUILDPATH;Sciezka pliku wykonywalnego +PREFERENCES_CUSTPROFBUILD;Zewnetrzny kreator profilow przetwarzania +PREFERENCES_CUTOVERLAYBRUSH;Kolor/przezroczystosc maski kadrowania +PREFERENCES_D50;5000K +PREFERENCES_D55;5500K +PREFERENCES_D60;6000K +PREFERENCES_D65;6500K +PREFERENCES_DARKFRAMEFOUND;Znaleziono +PREFERENCES_DARKFRAMESHOTS;zdjec(ia) +PREFERENCES_DARKFRAMETEMPLATES;szablonow(ny) +PREFERENCES_DARKFRAME;Czarna klatka +PREFERENCES_DATEFORMATHINT;Dozwolone sa nastepujace kody formatujace:\n%y - rok\n%m - miesiac\n%d - dzien\n\nNa przyklad wedlug standardu ISO 8601 format daty wyglada nastepujaco:\n%y-%m-%d +PREFERENCES_DATEFORMAT;Format daty +PREFERENCES_DEFAULTLANG;Domyslny jezyk +PREFERENCES_DEFAULTTHEME;Domyslny temat +PREFERENCES_DIRDARKFRAMES;Katalog z czarnymi klatkami +PREFERENCES_DIRHOME;Katalog domowy +PREFERENCES_DIRLAST;Ostatnio odwiedzony katalog +PREFERENCES_DIROTHER;Inny +PREFERENCES_DIRSELECTDLG;Wybierz katalog z obrazami po uruchomieniu... +PREFERENCES_DIRSOFTWARE;Katalog instalacyjny +PREFERENCES_EDITORCMDLINE;Inna linia polecen +PREFERENCES_EDITORLAYOUT;Uklad edytora +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_FLATFIELDFOUND;Znaleziono +PREFERENCES_FLATFIELDSDIR;Katalog z pustymi polami +PREFERENCES_FLATFIELDSHOTS;kadry +PREFERENCES_FLATFIELDTEMPLATES;szablony +PREFERENCES_FLATFIELD;Puste pole +PREFERENCES_FLUOF2;Fluorescent F2 +PREFERENCES_FLUOF7;Fluorescent F7 +PREFERENCES_FLUOF11;Fluorescent F11 +PREFERENCES_FORIMAGE;Dla zdjec innych niz raw +PREFERENCES_FORRAW;Dla zdjec raw +PREFERENCES_GIMPPATH;Katalog, w ktorym zainstalowany jest GIMP +PREFERENCES_GREY05;Yb=05 CIE L#30 +PREFERENCES_GREY10;Yb=10 CIE L#40 +PREFERENCES_GREY15;Yb=15 CIE L#45 +PREFERENCES_GREY18;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_GREY;Luminancja Yb urzadzenia wyjsciowego (%) +PREFERENCES_HISTOGRAMPOSITIONLEFT;Histogram w lewym panelu +PREFERENCES_HISTOGRAMWORKING;Zastosuj profil roboczy do obliczenia glownego histogramu i Nawigatora +PREFERENCES_HISTOGRAM_TOOLTIP;Jesli opcja jest wlaczona profil roboczy jest uzyty do obliczenia glownego histogramu oraz panelu Nawigatora, inaczej profil wyjsciowy z korekta gamma zostanie uzyty. +PREFERENCES_HLTHRESHOLD;Prog dla przeswietlen +PREFERENCES_ICCDIR;Katalog z profilami koloru ICC +PREFERENCES_IMPROCPARAMS;Domyslne parametry przetwarzania obrazu +PREFERENCES_INTENT_ABSOLUTE;Absolutnie kolorymetryczny +PREFERENCES_INTENT_PERCEPTUAL;Percepcyjny +PREFERENCES_INTENT_RELATIVE;Wzglednie kolorymetryczny +PREFERENCES_INTENT_SATURATION;Nasyceniowy +PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Pokaz osadzona miniature JPEG jesli plik raw jest nieedytowany +PREFERENCES_LANGAUTODETECT;Uzyj jezyka systemowego +PREFERENCES_MENUGROUPEXTPROGS;Grupuj "Otworz za pomoca" +PREFERENCES_MENUGROUPFILEOPERATIONS;Grupuj operacje plikow +PREFERENCES_MENUGROUPLABEL;Grupuj operacje etykiet +PREFERENCES_MENUGROUPPROFILEOPERATIONS;Grupuj operacje profili przetwarzania +PREFERENCES_MENUGROUPRANK;Grupuj operacje oceny +PREFERENCES_MENUOPTIONS;Opcje menu +PREFERENCES_METADATA;Metadane +PREFERENCES_MONITORICC;Profil monitora +PREFERENCES_MULTITABDUALMON;Tryb wielu zakladek (na drugim monitorze jesli dostepny) +PREFERENCES_MULTITAB;Tryb wielu zakladek +PREFERENCES_NAVGUIDEBRUSH;Kolor ramki Nawigatora +PREFERENCES_OUTDIRFOLDERHINT;Umieszcza zapisywane zdjecia w wybranym katalogu +PREFERENCES_OUTDIRFOLDER;Zapisz do katalogu +PREFERENCES_OUTDIRTEMPLATEHINT;Dozwolone sa nastepujace kody formatujace:\n%f, %d1, %d2, ..., %p1, %p2, ..., %r, %s1, %s2, ...\n\nKody formatujace odnosza sie do roznych elementow sciezki zdjecia, atrybutow zdjecia oraz do arbitralnego ciagu numerycznego operacji wsadowej.\n\nPrzykladowo, jesli zdjecie obrabiane ma nastepujaca sciezke:\n/home/andrzej/zdjecia/2010-10-31/dsc0042.nef\nznaczenie kodow formatujacych jest nastepujace:\n%d4 = home\n%d3 = andrzej\n%d2 = zdjecia\n%d1 = 2010-10-31\n%f = dsc0042\n%p1 = /home/tom/photos/2010-10-31/\n%p2 = /home/andrzej/zdjecia/\n%p3 = /home/andrzej/\n%p4 = /home/\n\n%r zostanie zastapione ocena zdjecia. Jesli zdjecie nie posiada oceny, %r zostanie zastapione liczba '0'. Jesli zdjecie lezy w smietniku, %r zostanie zastapione znakiem 'x'.\n\n%s1, %s2, etc. zostanie zastapione ciagniem numerycznym dopelnionym od jednej do dziewieciu cyfr. Ciag ten zostanie rozpoczniety od "1" za kazdym razem gdy kolejka przetwarzania zostanie uruchomiona, i liczba jest zwiekszona o "1" dla kazdego zapisanego obrazu.\n\nJesli chcesz zapisac obraz wyjsciowy obok obrazu wejsciowego, napisz:\n%p1/%f\n\nJesli chcesz zapisac obraz wyjsciowy w folderze o nazwie "wywolane" znajdujacego sie w katalogu zawierajacym otwarty obraz, napisz:\n%p1/wywolane/%f\n\nJesli chcesz zapisac obraz wyjsciowy w folderze o nazwie "/home/andrzej/zdjecia/wywolane/2010-10-31", napisz:\n%p2/wywolane/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Uzyj schemat +PREFERENCES_OUTDIR;Katalog wyjsciowy +PREFERENCES_OVERLAY_FILENAMES;Nakladaj nazwy pliku na miniatury +PREFERENCES_OVERWRITEOUTPUTFILE;Nadpisuj istniejace pliki +PREFERENCES_PANFACTORLABEL;Wspolczynnik +PREFERENCES_PARSEDEXTADDHINT;Prosze wprowadzic rozszerzenie i zatwierdzic przyciskiem, by dodac do listy +PREFERENCES_PARSEDEXTADD;Dodaj rozszerzenie +PREFERENCES_PARSEDEXTDELHINT;Skasuje wybrane rozszerzenie z listy +PREFERENCES_PARSEDEXT;Przetwarzane rozszerzenia +PREFERENCES_PROFILEHANDLING;Obsluga profili +PREFERENCES_PROFILELOADPR;Priorytet wczytywania profilu +PREFERENCES_PROFILEPRCACHE;Profil w pamieci podrecznej +PREFERENCES_PROFILEPRFILE;Profil przy pliku wejsciowym +PREFERENCES_PROFILESAVECACHE;Zapisz parametry przetwarzania w pamieci podrecznej +PREFERENCES_PROFILESAVEINPUT;Zapisz parametry przetwarzania obok pliku wejsciowego +PREFERENCES_PROPERTY;Wlasnosc +PREFERENCES_PSPATH;Katalog w ktorym zainstalowany jest Adobe Photoshop +PREFERENCES_RGBDTL_LABEL;Maksymalna ilosc watkow redukcji szumow +PREFERENCES_RGBDTL_TOOLTIP;Redukcja szumow potrzebuje okolo 128MB RAMu dla zdjecia 10Mpix oraz 512MB dla zdjecia 40Mpix, i dodatkowo 128MB dla kazdego watku. Im wieksza liczba rownoleglych watkow, tym krotszy czas egzekucji. Zostawienie ustawienia na "0" automatycznie uzyje tyle watkow, ile mozliwe. +PREFERENCES_SELECTFONT;Wybierz czcionke +PREFERENCES_SELECTLANG;Wybierz jezyk +PREFERENCES_SELECTTHEME;Wybierz temat +PREFERENCES_SET;Ustaw +PREFERENCES_SHOWBASICEXIF;Pokaz podstawowe dane Exif +PREFERENCES_SHOWDATETIME;Pokaz date i czas +PREFERENCES_SHOWEXPOSURECOMPENSATION;Pokaz korekte ekspozycji +PREFERENCES_SHTHRESHOLD;Prog dla niedoswietlen +PREFERENCES_SINGLETABVERTAB;Tryb pojedynczej zakladki, pionowy uklad +PREFERENCES_SINGLETAB;Tryb pojedynczej zakladki +PREFERENCES_SLIMUI;Waskie suwaki +PREFERENCES_SND_BATCHQUEUEDONE;Zakonczono przetwarzanie wsadowe +PREFERENCES_SND_HELP;Nalezy wprowadzic sciezke do pliku, badz pozostawic niewypelnione (brak dzwiekow).\nW systemie Windows mozna stosowac "SystemDefault", "SystemAsterisk" itp. dla dzwiekow systemowych.\nW systemie Linux mozna stosowac "complete", "window-attention" etc. dla dzwiekow systemowych. +PREFERENCES_SND_LNGEDITPROCDONE;Praca edytora wykonana +PREFERENCES_SND_TRESHOLDSECS;po sekundach +PREFERENCES_STARTUPIMDIR;Katalog startowy +PREFERENCES_TAB_BROWSER;Przegladarka plikow +PREFERENCES_TAB_COLORMGR;Zarzadzanie kolorami +PREFERENCES_TAB_GENERAL;Ogolne +PREFERENCES_TAB_IMPROC;Przetwarzanie obrazu +PREFERENCES_TAB_PERFORMANCE;Wydajnosc +PREFERENCES_TAB_SOUND;Dzwieki +PREFERENCES_TP_LABEL;Panel narzedzi: +PREFERENCES_TP_USEICONORTEXT;Uzyj ikon w zakladkach zamiast tekstowych etykiet +PREFERENCES_TP_VSCROLLBAR;Ukry pionowy pasek przesuwania +PREFERENCES_TUNNELMETADATA;Skopiuj niezmienione IPTC/XMP do pliku wynikowego (gdy tagowane za pomoca innego programu) +PREFERENCES_USEBUNDLEDPROFILES;Uzyj zalaczone profile przetwarzania +PREFERENCES_USESYSTEMTHEME; Uzyj tematu systemowego +PREFERENCES_VIEW;Balans bieli urzadzenia wyjsciowego (monitora, TV, projektora, widowni, etc.) +PREFERENCES_WORKFLOW;Tok pracy +PROFILEPANEL_COPYPPASTE;Parametry do skopiowania +PROFILEPANEL_GLOBALPROFILES;Zalaczone profile przetwarzania +PROFILEPANEL_LABEL;Profil przetwarzania +PROFILEPANEL_LOADDLGLABEL;Wczytaj profil przetwarzania koncowego... +PROFILEPANEL_LOADPPASTE;Parametry do zaladowania +PROFILEPANEL_MODE_TIP;Tryb wypelnienia parametrow przetwarzania.\n\nWduszone: czesciowe profile zostana przetworzone w profile pelne; brakujace wartosci zostana wypelnione domyslnymi, zakodowanymi w silniku RawTherapee.\n\nWylaczone: profile zostana zastosowane takie, jakie sa, zmieniajac tylko te wartosci, ktore zawieraja. +PROFILEPANEL_MYPROFILES;Moje profile przetwarzania +PROFILEPANEL_PASTEPPASTE;Parametry do wklejenia +PROFILEPANEL_PCUSTOM;Wlasny +PROFILEPANEL_PFILE;Z pliku +PROFILEPANEL_PINTERNAL;Neutralny +PROFILEPANEL_PLASTSAVED;Ostatnio zapisany +PROFILEPANEL_SAVEDLGLABEL;Zapisz profil przetwarzania... +PROFILEPANEL_SAVEPPASTE;Parametry do zapisania +PROFILEPANEL_TOOLTIPCOPY;Skopiuj aktualny profil do schowka +PROFILEPANEL_TOOLTIPLOAD;Laduj profil z pliku.\nCtrl+klik aby wybrac parametry do ladowania. +PROFILEPANEL_TOOLTIPPASTE;Wklej profil ze schowka.\nCtrl+klik aby wybrac parametry do wklejenia. +PROFILEPANEL_TOOLTIPSAVE;Zapisz aktualny profil.\nCtrl+klik aby wybrac parametry do zapisania. +PROGRESSBAR_LOADINGTHUMBS;Wczytywanie miniatur... +PROGRESSBAR_LOADING;Wczytywanie obrazu... +PROGRESSBAR_LOADJPEG;Ladowanie pliku JPEG... +PROGRESSBAR_LOADPNG;Ladowanie pliku PNG... +PROGRESSBAR_LOADTIFF;Ladowanie pliku TIFF... +PROGRESSBAR_NOIMAGES;Nie znaleziono zadnych obrazow +PROGRESSBAR_PROCESSING;Przetwarzanie obrazu... +PROGRESSBAR_PROCESSING_PROFILESAVED;Zapisano profil przetwarzania +PROGRESSBAR_READY;Gotowe +PROGRESSBAR_SAVEJPEG;Zapisywanie pliku JPEG... +PROGRESSBAR_SAVEPNG;Zapisywanie pliku PNG... +PROGRESSBAR_SAVETIFF;Zapisywanie pliku TIFF... +PROGRESSBAR_SNAPSHOT_ADDED;Dodano migawke +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profil zmieniony w przegladarce +QINFO_ISO;ISO +QINFO_NOEXIF;Dane Exif niedostepne. +SAVEDLG_AUTOSUFFIX;Automatycznie dodaj przyrostek, jezeli plik juz istnieje +SAVEDLG_FILEFORMAT;Format pliku +SAVEDLG_FORCEFORMATOPTS;Wymus opcje zapisu +SAVEDLG_JPEGQUAL;Jakosc JPEG +SAVEDLG_PNGCOMPR;Kompresja PNG +SAVEDLG_PUTTOQUEUEHEAD;Umiesc na poczatku kolejki przetwarzania +SAVEDLG_PUTTOQUEUETAIL;Umiesc na koncu kolejki przetwarzania +SAVEDLG_PUTTOQUEUE;Umiesc w kolejce przetwarzania +SAVEDLG_SAVEIMMEDIATELY;Zapisz natychmiast +SAVEDLG_SAVESPP;Zapisz parametry przetwarzania wraz z obrazem +SAVEDLG_SUBSAMP;Subsampling +SAVEDLG_SUBSAMP_1;Najlepsza kompresja +SAVEDLG_SUBSAMP_2;Pomiedzy +SAVEDLG_SUBSAMP_3;Najlepsza jakosc +SAVEDLG_SUBSAMP_TOOLTIP;Najlepsza kompresja: 4:1:1\nPomiedzy: 4:2:2\nNajlepsza jakosc: 4:4:4 +SAVEDLG_TIFFUNCOMPRESSED;Nieskompresowany TIFF +SAVEDLG_WARNFILENAME;Plik zostanie nazwany +SHCSELECTOR_TOOLTIP;Kliknij prawym przyciskiem myszki aby zresetowac poycje trzech suwakow. +THRESHOLDSELECTOR_BL;Dolny lewy +THRESHOLDSELECTOR_BR;Dolny prawy +THRESHOLDSELECTOR_B;Dolny +THRESHOLDSELECTOR_HINT;Uzyj Shift aby przesuwac poszczegolne punkty kontrolne. +THRESHOLDSELECTOR_TL;Gorny lewy +THRESHOLDSELECTOR_TR;Gorny prawy +THRESHOLDSELECTOR_T;Top +TOOLBAR_TOOLTIP_CROP;Kadruj.\nSkrot: c\nMozna przesuwac obszar kadrowania za pomoca Shift-przeciagniecia myszki +TOOLBAR_TOOLTIP_HAND;Przesun.\nSkrot: h +TOOLBAR_TOOLTIP_STRAIGHTEN;Wyprostuj / obroc.\nSkrot: s\n\nWyznacz pionowa lub pozioma poprzez narysowanie linii prowadnicy na podgladzie. Kat obrotu zostanie pokazany obok linii prowadnicy. Punktem obrotu jest geometryczny srodek obrazu. +TOOLBAR_TOOLTIP_WB;Wskaz balans bieli.\nSkrot: w +TP_BWMIX_ALGO;Algorytm PZCRM +TP_BWMIX_ALGO_LI;Liniowy +TP_BWMIX_ALGO_SP;Efekty specjalne +TP_BWMIX_ALGO_TOOLTIP;Liniowy: mieszanie kanalow liniowo.\nEfekty specjalne: kanaly zostana mieszane nieliniowo. +TP_BWMIX_AUTOCH;Auto +TP_BWMIX_AUTOCH_TIP;Oblicza wartosci optymalizacji mieszacza kanalow. +TP_BWMIX_CC_ENABLED;Dopasuj barwy dopelniajace +TP_BWMIX_CC_TOOLTIP;Wlacz aby umozliwic automatyczne dopasowanie barw dopelniajacych w trybie CPZZCNPM. +TP_BWMIX_CHANNEL;Ekwalizator luminancji +TP_BWMIX_CURVEEDITOR1;Krzywa 'Przed' +TP_BWMIX_CURVEEDITOR2;Krzywa 'Po' +TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Krzywa po konwersji obrazu na czarnobialy. +TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Krzywa przed konwersja obrazu na czarnobialy.\nWspolczynniki koloru moga miec wplyw. +TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Luminancja wedlug odcieni (hue) L=f(H).\nNalezy zwrocic uwage na ekstremalne ustawienia poniewaz moga pojawic sie znieksztalcenia sygnalu w obrazie. +TP_BWMIX_FILTER;Filtr barwny +TP_BWMIX_FILTER_BLUEGREEN;Niebieski-Zielony +TP_BWMIX_FILTER_BLUE;Niebieski +TP_BWMIX_FILTER_GREENYELLOW;Zielony-Zolty +TP_BWMIX_FILTER_GREEN;Zielony +TP_BWMIX_FILTER_NONE;Brak +TP_BWMIX_FILTER_PURPLE;Purpurowy +TP_BWMIX_FILTER_REDYELLOW;Czerwony-Zolty +TP_BWMIX_FILTER_RED;Czerwony +TP_BWMIX_FILTER_TOOLTIP;Filtr barwny symuluje dzialanie prawdziwego filtru barwnego usytuowanego przed obiektywem. Filtry barwne obnizaja transmitancje specyficznych kolorow a zatem maja wplyw na ich jasnosc, np. filtr czerwony przyciemnia niebieskie niebo. +TP_BWMIX_FILTER_YELLOW;Zolty +TP_BWMIX_GAMMA;Korekcja gamma +TP_BWMIX_GAM_TOOLTIP;Korekcja gamma dla kazdego kanalu RGB. +TP_BWMIX_LABEL;Czarno-Bialy +TP_BWMIX_MET;Metoda +TP_BWMIX_MET_CHANMIX;Mieszacz kanalow +TP_BWMIX_MET_DESAT;Desaturacja +TP_BWMIX_MET_LUMEQUAL;Ekwalizator luminancji +TP_BWMIX_MIXC;Mieszacz +TP_BWMIX_NEUTRAL;Zresetuj mieszacz +TP_BWMIX_NEUTRAL_TIP;Zresetuj wszystkie wartosci (filtru barwnego, mieszacza kanalow) na domyslne. +TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +TP_BWMIX_RGBLABEL_HINT;Ostateczne wartosci RGB ktore uwzgledniaja wszystkie opcje mieszacza.\n"Total" wyswietla sume wartosci RGB:\n- zawsze 100% w trybie relatywnym,\n- ponad (jasniej) lub ponizej (ciemniej) 100% w trybie absolutnym. +TP_BWMIX_RGB_TOOLTIP;Miesza kanaly RGB. Kieruj sie gotowymi ustawieniami.\nNalezy zwrocic uwage na ujemne wartosci poniewaz moga pojawic sie znieksztalcenia sygnalu w obrazie lub dzialac w sposob nieprzewidywalny. +TP_BWMIX_SETTING;Gotowe ustawienia +TP_BWMIX_SETTING_TOOLTIP;Rozne gotowe ustawienia (klisza, krajobraz, etc.) oraz recznie ustawienia mieszacza kanalow. +TP_BWMIX_SET_HIGHCONTAST;Wysoki kontrast +TP_BWMIX_SET_HIGHSENSIT;Wysoka czulosc +TP_BWMIX_SET_HYPERPANCHRO;Hyper Panchromatic +TP_BWMIX_SET_INFRARED;Podczerwien +TP_BWMIX_SET_LANDSCAPE;Krajobraz +TP_BWMIX_SET_LOWSENSIT;Niska czulosc +TP_BWMIX_SET_LUMINANCE;Luminancja +TP_BWMIX_SET_NORMCONTAST;Normalny kontrast +TP_BWMIX_SET_ORTHOCHRO;Orthochromatic +TP_BWMIX_SET_PANCHRO;Panchromatic +TP_BWMIX_SET_PORTRAIT;Portret +TP_BWMIX_SET_RGBABS;Absolutny RGB +TP_BWMIX_SET_RGBREL;Relatywny RGB +TP_BWMIX_SET_ROYGCBPMABS;Absolutny CPZZCNPM +TP_BWMIX_SET_ROYGCBPMREL;Relatywny CPZZCNPM +TP_BWMIX_TCMODE_FILMLIKE;B&W Klisza +TP_BWMIX_TCMODE_SATANDVALBLENDING;B&W Mieszanie Nasycenia i Mocy Swiatla Bialego +TP_BWMIX_TCMODE_STANDARD;B&W Standardowa +TP_BWMIX_TCMODE_WEIGHTEDSTD;B&W Wazona Standardowa +TP_BWMIX_VAL;L +TP_CACORRECTION_BLUE;Niebieski +TP_CACORRECTION_LABEL;Korekcja aberracji chromatycznej +TP_CACORRECTION_RED;Czerwony +TP_CHMIXER_BLUE;Niebieski +TP_CHMIXER_GREEN;Zielony +TP_CHMIXER_LABEL;Mieszacz kanalow +TP_CHMIXER_RED;Czerwony +TP_CHROMATABERR_LABEL;Aberracja chromatyczna +TP_COARSETRAF_TOOLTIP_HFLIP;Odbij w poziomie +TP_COARSETRAF_TOOLTIP_ROTLEFT;Obroc w lewo.\n\nSkroty:\n[ - Tryb wielu zakladek,\nAlt-[ - Tryb jednej zakladki. +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Obroc w prawo.\n\nSkroty:\n] - Tryb wielu zakladek,\nAlt-] - Tryb jednej zakladki. +TP_COARSETRAF_TOOLTIP_VFLIP;Odbij w pionie +TP_COLORAPP_ADAPTSCENE;Luminancji sceny +TP_COLORAPP_ADAPTSCENE_TOOLTIP;Bezwzgledna luminancja sceny (cd/m²).\n1)Obliczona za pomoca Exif:\nCzas naswietlania - ISO - Przyslona - Korekcja ekspozycji EV w aparacie.\n2)Obliczona rowniez na podstawie punktu bieli raw oraz korekty ekspozycji w RawTherapee +TP_COLORAPP_ADAPTVIEWING;Luminancji widowni (cd/m²) +TP_COLORAPP_ADAPTVIEWING_TOOLTIP;Bezwzgledna luminancja widowni\n(zazwyczaj 16cd/m²). +TP_COLORAPP_ADAP_AUTO_TOOLTIP;Jesli zaznaczone (polecamy), RawTherapee obliczy optymalna wartosc na podstawie Exif.\nAby ustawic wartosc recznie, nalezy wpierw odznaczyc pudlo. +TP_COLORAPP_ALGO;Algorytm +TP_COLORAPP_ALGO_ALL;Wszystkie +TP_COLORAPP_ALGO_JC;Swiatlosc + Chroma (JC) +TP_COLORAPP_ALGO_JS;Swiatlosc + Nasycenie (JS) +TP_COLORAPP_ALGO_QM;Jasnosc + Barwistosc (QM) +TP_COLORAPP_ALGO_TOOLTIP;Umozliwia wybor wszystkich parametrow lub ich podzespol. +TP_COLORAPP_BADPIXSL;Filtr pikseli goracych/uszkodzonych +TP_COLORAPP_BADPIXSL_TOOLTIP;Usuwanie goracych/uszkodzonych (swiecacych) pikseli.\n0 = Wylaczone\n1 = Metoda Mediana\n2 = Metoda Gaussa.\nMozna rowniez dostroic zdjecie tak, aby unikac bardzo ciemnych miejsc.\n\nTe anomalie wynikaja z limitacji CIECAM02. +TP_COLORAPP_BRIGHT;Jasnosc (Q) +TP_COLORAPP_BRIGHT_TOOLTIP;Jasnosc w CIECAM02 bierze pod uwage luminancje bieli i rozni sie od jasnosci L*a*b* oraz RGB. +TP_COLORAPP_CHROMA;Chroma (C) +TP_COLORAPP_CHROMA_M;Barwistosc (M) +TP_COLORAPP_CHROMA_M_TOOLTIP;Barwistosc w CIECAM02 rozni sie od barwistosci L*a*b* oraz RGB. +TP_COLORAPP_CHROMA_S;Nasycenie (S) +TP_COLORAPP_CHROMA_S_TOOLTIP;Nasycenie w CIECAM02 rozni sie od nasycenia L*a*b* oraz RGB. +TP_COLORAPP_CHROMA_TOOLTIP;Chroma w CIECAM02 rozni sie od chromy L*a*b* oraz RGB. +TP_COLORAPP_CIECAT_DEGREE;Adaptacja CAT02 +TP_COLORAPP_CONTRAST;Kontrast (J) +TP_COLORAPP_CONTRAST_Q;Kontrast (Q) +TP_COLORAPP_CONTRAST_Q_TOOLTIP;Kontrast w CIECAM02 dla suwaka Q rozni sie od kontrastu L*a*b* oraz RGB. +TP_COLORAPP_CONTRAST_TOOLTIP;Kontrast w CIECAM02 dla suwaka J rozni sie od kontrastu L*a*b* oraz RGB. +TP_COLORAPP_CURVEEDITOR1;Krzywa tonalna 1 +TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Pokazuje histogram L* (L*a*b*) przed CIECAM02.\nJesli opcja "Pokaz histogramy wyjsciowe CIECAM02 za krzywymi" jest wlaczona, pokazuje histogram J i Q po CIECAM02.\n\nJ i Q nie sa pokazywane w glownym histogramie.\n\nEfekt koncowy jest przedstawiony w glownym histogramie. +TP_COLORAPP_CURVEEDITOR2;Krzywa tonalna 2 +TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Tak samo dziala jak krzywa tonalna 1. +TP_COLORAPP_CURVEEDITOR3;Krzywa koloru +TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Ustawienie chromy, nasycenia badz barwistosci.\n\nPokazuje histogram chromatycznosci (L*a*b*) przed CIECAM02.\nJesli opcja "Pokaz histogramy wyjsciowe CIECAM02 za krzywymi" jest wlaczona, pokazuje histogram C, s badz M po CIECAM02.\n\nC, s oraz M nie sa pokazywane w glownym histogramie.\nEfekt koncowy jest przedstawiony w glownym histogramie. +TP_COLORAPP_DATACIE;Pokaz histogramy wyjsciowe CIECAM02 za krzywymi +TP_COLORAPP_DATACIE_TOOLTIP;Kiedy opcja jest wlaczona, histogramy za krzywymi CIECAM02 pokazuja przyblizone wartosci/zakresy J lub Q, oraz C, s lub M po korekcjach CIECAM02.\nTen wybor nie ma wplywu na glowny histogram.\n\nKiedy opcja jest wylaczona, histogramy za krzywymi CIECAM02 pokazuja wartosci L*a*b* przed korekcjami CIECAM02. +TP_COLORAPP_DEGREE_AUTO_TOOLTIP;Jesli opcja jest zaznaczona (zalecane), RawTherapee kalkuluje wartosc optymalna, ktora jest potem uzyta przez CAT02 oraz przez calosc CIECAM02.\nAby ustawic wartosc recznie, odznacz wpierw opcje (wartosci powyzej 65 zalecane). +TP_COLORAPP_DEGREE_TOOLTIP;Sila CIE Chromatic Adaptation Transform 2002 +TP_COLORAPP_GAMUT;Kontrola gamma (L*a*b*). +TP_COLORAPP_GAMUT_TOOLTIP;Wlacz kontrole gamma w trybie L*a*b*. +TP_COLORAPP_HUE;Odcien (hue, h) +TP_COLORAPP_HUE_TOOLTIP;Odcien (hue, h) - kat pomiedzy 0° a 360°. +TP_COLORAPP_LABEL;CIE Color Appearance Model 2002 +TP_COLORAPP_LABEL_CAM02;Ustawienia Obrazu +TP_COLORAPP_LABEL_SCENE;Ustawienia Sceny +TP_COLORAPP_LABEL_VIEWING;Wlasnosci Widowni +TP_COLORAPP_LIGHT;Swiatlosc (J) +TP_COLORAPP_LIGHT_TOOLTIP;Swiatlosc w CIECAM02 rozni sie od swiatlosci CIELab oraz RGB +TP_COLORAPP_MODEL;Model PB +TP_COLORAPP_MODEL_TOOLTIP;Model punktu bieli.\n\nBB [RT] + [wyjsciowy]:\nBalans bieli RawTherapee jest uzyty dla sceny, CIECAM02 jest ustawione na D50, i balans bieli urzadzenia wyjsciowego ustawiony jest w Ustawieniach > Zarzadzanie Kolorami\n\nBB [RT+CAT02] + [wyjsciowe]:\nUstawienia balansu bieli RawTherapee sa uzywane przez CAT02, i balans bieli urzadzenia wyjsciowego jest ustawione w Ustawieniach > Zarzadzanie Kolorami. +TP_COLORAPP_RSTPRO;Ochrona odcieni skory i czerwieni +TP_COLORAPP_RSTPRO_TOOLTIP;Ochrona odcieni skory i czerwieni (suwaki i krzywe) +TP_COLORAPP_SHARPCIE;- +TP_COLORAPP_SHARPCIE_TOOLTIP;- +TP_COLORAPP_SURROUND;Otoczenie +TP_COLORAPP_SURROUND_AVER;Srednie +TP_COLORAPP_SURROUND_DARK;Ciemne +TP_COLORAPP_SURROUND_DIM;Przycmione +TP_COLORAPP_SURROUND_EXDARK;Bardzo Ciemne (Cut-sheet) +TP_COLORAPP_SURROUND_TOOLTIP;Zmienia barwy i kolory aby wziac pod uwage wlasnosci widowni urzadzenia wyjsciowego.\n\nSrednie:\nSrednie swiatlo otoczenia (standardowe). Obraz sie nie zmieni.\n\nPrzycmione:\nPrzycmione otoczenie (TV). Obraz stanie sie troszke ciemniejszy.\n\nCiemne:\nCiemne otoczenie (projektor). Obraz stanie sie jeszcze ciemniejszy.\n\nBardzo Ciemne:\nBardzo ciemne otoczenie (cut-sheet). Obraz stanie sie bardzo ciemny. +TP_COLORAPP_SURSOURCE;Ciemne otoczenie +TP_COLORAPP_SURSOURCE_TOOLTIP;Mozna uzyc kiedy np. obraz wejsciowy ma ciemne krawedzie. +TP_COLORAPP_TCMODE_BRIGHTNESS;Jasnosc +TP_COLORAPP_TCMODE_CHROMA;Chroma +TP_COLORAPP_TCMODE_COLORF;Barwistosc +TP_COLORAPP_TCMODE_LABEL1;Tryb krzywej 1 +TP_COLORAPP_TCMODE_LABEL2;Tryb krzywej 2 +TP_COLORAPP_TCMODE_LABEL3;Tryb krzywej chromy +TP_COLORAPP_TCMODE_LIGHTNESS;Swiatlosc +TP_COLORAPP_TCMODE_SATUR;Nasycenie +TP_COLORAPP_TONECIE;Tone mapping za pomoca jasnosci CIECAM02 (Q) +TP_COLORAPP_TONECIE_TOOLTIP;Jesli ta opcja jest wylaczona, tone mapping odbywa sie w przestrzeni kolorow L*a*b*, zas jesli jest wlaczona, w przestrzeni kolorow CIECAM02.\nNarzedzie Tone Mapping musi byc wlaczone aby to utawienie dzialalo. +TP_COLORAPP_WBCAM;BB [RT+CAT02] + [wyjsciowy] +TP_COLORAPP_WBRT;BB [RT] + [wyjsciowy] +TP_COLORTONING_AB;o C/L +TP_COLORTONING_AUTOSAT;Automatyczna +TP_COLORTONING_BALANCE;Balans +TP_COLORTONING_BY;o C/L +TP_COLORTONING_CHROMAC;Przezroczystosc +TP_COLORTONING_COLOR;Kolor +TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;Przezroczystosc chromy wedlug luminancji oC=f(L) +TP_COLORTONING_HIGHLIGHT;Podswietlenia +TP_COLORTONING_HUE;Odcien (hue) +TP_COLORTONING_LABEL;Koloryzacja +TP_COLORTONING_LAB;Mieszanie L*a*b* +TP_COLORTONING_LUMAMODE;Zachowaj luminancje +TP_COLORTONING_LUMAMODE_TOOLTIP;Luminancja zostanie zachowana przy zmianie kolorow. +TP_COLORTONING_LUMA;Luminancja +TP_COLORTONING_METHOD;Metoda +TP_COLORTONING_METHOD_TOOLTIP;"Mieszanie L*a*b*", "Suwaki RGB" oraz "Krzywe RGB" stosuja interpolacje do mieszania kolorow.\n"Balansowanie kolorow (cienie, polcienie, podswietlenia)" oraz "Nasycenie - Dwa Kolory" stosuja kolory bezposrednio.\n\nNarzedzie "Czarno-biale" mozna uzywac jednoczesnie z narzedziem "Koloryzacji", co umozliwi tonowanie zdjecia. +TP_COLORTONING_MIDTONES;Polcienie +TP_COLORTONING_NEUTRAL;Zresetuj suwaki +TP_COLORTONING_NEUTRAL_TIP;Zresetuj wszystkie wartosci (cienie, polcienie, podswietlenia) na domyslne. +TP_COLORTONING_OPACITY;Przezroczystosc +TP_COLORTONING_RGBCURVES;RGB - Krzywe +TP_COLORTONING_RGBSLIDERS;RGB - Suwaki +TP_COLORTONING_SATURATEDOPACITY;Sila +TP_COLORTONING_SATURATIONTHRESHOLD;Prog +TP_COLORTONING_SA;Ochrona przed przesyceniem +TP_COLORTONING_SHADOWS;Cienie +TP_COLORTONING_SPLITCOCO;Balans kolorow - cienie/polcienie/podswietlenia +TP_COLORTONING_SPLITCO;Cienie/polcienie/podswietlenia +TP_COLORTONING_SPLITLR;Nasycenie - dwa kolory +TP_COLORTONING_STRENGTH;Sila +TP_COLORTONING_STR;Sila +TP_COLORTONING_TWO2;Specjalna chroma 'dwa kolory' +TP_COLORTONING_TWOALL;Specjalna chroma +TP_COLORTONING_TWOBY;Specjalne a* i b* +TP_COLORTONING_TWOCOLOR_TOOLTIP;Standardowa chroma:\nLiniowe mieszanie kanalow, a* = b*.\n\nSpecjalna chroma:\nLiniowe mieszanie kanalow, a* = b*, ale nieograniczone - sprobuj krzywa zagiac pod przekatna.\n\nSpecialne a* i b*:\nLiniowe nieograniczone mieszanie kanalow z osobnymi krzywymi dla a* i b*. Przeznaczone dla efektow specjalnych.\n\nSpecjalna chroma - dwa kolory:\nBardziej nieprzewidywalne. +TP_COLORTONING_TWOSTD;Standardowa chroma +TP_CROP_FIXRATIO;Zablokuj proporcje +TP_CROP_GTDIAGONALS;Przekatna +TP_CROP_GTEPASSPORT;Paszport biometryczny +TP_CROP_GTFRAME;Ramka +TP_CROP_GTGRID;Siatka +TP_CROP_GTNONE;Nic +TP_CROP_GTRULETHIRDS;Trojpodzial +TP_CROP_GUIDETYPE;Typ pomocy: +TP_CROP_H;Wysokosc +TP_CROP_LABEL;Kadrowanie +TP_CROP_PPI;PPI= +TP_CROP_SELECTCROP;Wybierz kadr +TP_CROP_W;Szerokosc +TP_CROP_X;X +TP_CROP_Y;Y +TP_DARKFRAME_AUTOSELECT;Autowybor +TP_DARKFRAME_LABEL;Czarna klatka +TP_DEFRINGE_LABEL;Usuwanie widma +TP_DEFRINGE_RADIUS;Promien +TP_DEFRINGE_THRESHOLD;Prog +TP_DIRPYRDENOISE_33;3×3 silne +TP_DIRPYRDENOISE_55SOFT;5×5 +TP_DIRPYRDENOISE_55;5×5 silne +TP_DIRPYRDENOISE_77;7×7 (wolne) +TP_DIRPYRDENOISE_BLUE;Chrominancja - Blekit-zolc +TP_DIRPYRDENOISE_CHROMA;Chrominancja - Glowna +TP_DIRPYRDENOISE_CURVEEDITOR_L_TOOLTIP;Moduluje dzialanie usuwania szumow luminancji +TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Dziala z obrazami typu raw i nie-raw.\n\nDla obrazow typu raw, dzialanie redukcji szumow luminancji zalezy od gammy wejsciowego profilu ICC. Z gory zalozona jest gamma sRGB, zatem jesli obraz wejsciowy ma profil o innej gammie mozna sie spodziewac zmian w dzialaniu rekucji szumow luminancji. +TP_DIRPYRDENOISE_ENH;Tryb ulepszony +TP_DIRPYRDENOISE_ENH_TOOLTIP;Ulepsza jakosc usuwania szumow kosztem okolo 20% wzrostu czasu przetwarzania. +TP_DIRPYRDENOISE_GAMMA;Gamma +TP_DIRPYRDENOISE_GAMMA_TOOLTIP;Gamma skupia sile redukcji szumow na danym predziale zakresu tonalnego. Mniejsze wartosci gamma powoduja skupienie na ciemniejszych barwach, natomiast wieksze wartosci rozciagna zakres dzialania rowniez na barwy jasne. +TP_DIRPYRDENOISE_LABEL;Redukcja szumu +TP_DIRPYRDENOISE_LABM;L*a*b* +TP_DIRPYRDENOISE_LCURVE;Krzywa luminancji +TP_DIRPYRDENOISE_LDETAIL;Szczegolowosc luminancji +TP_DIRPYRDENOISE_LM;Tylko luminancja +TP_DIRPYRDENOISE_LUMA;Luminacja +TP_DIRPYRDENOISE_MEDMETHOD;Metoda mediana +TP_DIRPYRDENOISE_MEDTYPE;Rodzaj mediana +TP_DIRPYRDENOISE_MED;Filtr Mediana +TP_DIRPYRDENOISE_MED_TOOLTIP;Wlacz odszumianie metoda mediana. +TP_DIRPYRDENOISE_METHOD11;Jakosc +TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Jakosc moze zostac dopasowana do wzoru szumow. Ustawienie "wysoka" ulepsza odszumianie okolo 20% wzrostu czasu przetwarzania. +TP_DIRPYRDENOISE_METHOD;Metoda +TP_DIRPYRDENOISE_METHOD_TOOLTIP;Dla obrazow raw mozna uzywac metody RGB oraz L*a*b*.\n\nDla obrazow nie-raw metoda L*a*b* zostanie uzyta niezaleznie od wyboru. +TP_DIRPYRDENOISE_METM_TOOLTIP;Przy uzyciu metod "tylko luminancja" oraz "L*a*b*", filtrowanie mediana zostanie wykonane prosto po funkcji falki w procesie odszumiania.\nW trybie "RGB" filtrowanie to zostanie wykonana pod koniec calego procesu. +TP_DIRPYRDENOISE_MET_TOOLTIP;Zasrosuj filtrowanie mediana o oknie pozadanego rozmiaru. Im wiekszy rozmiar okna, tym dluzej przetwarzanie zajmie.\n\n3x3 miekki: uzyje 5 pikseli w zasiegu 1 pikseli.\n3x3: uzyje 9 pikseli w zasiegu 1 pikseli.\n5x5 miekki: uzyje 13 pikseli w zasiegu 2 pikseli.\n5x5: uzyje 25 pikseli w zasiegu 2 pikseli.\n7x7: uzyje 49 pikseli w zasiegu 3 pikseli.\n\nCzasem mozna uzyskac wyzsza jakosc wielokrotnym powtorzeniem filtru przy uzyciu malego okna niz przy jednokrotnym przetworzeniu przy uzyciu duzego okna. +TP_DIRPYRDENOISE_PASSES;Liczba powtorzen mediana +TP_DIRPYRDENOISE_PASSES_TOOLTIP;Trzykrotne powtorzenie filtru mediana przy uzyciu okna o rozmiarze 3x3 czesto skutkuje wyzsza jakoscia niz jednokrotne z oknem o rozmiarze 7x7. +TP_DIRPYRDENOISE_RED;Chrominancja - Czerwien-zielen +TP_DIRPYRDENOISE_RGBM;RGB +TP_DIRPYRDENOISE_RGB;RGB +TP_DIRPYRDENOISE_SHALBI;Wysoka +TP_DIRPYRDENOISE_SHAL;Standardowa +TP_DIRPYRDENOISE_SOFT;3x3 +TP_DIRPYREQUALIZER_ALGO;Zakres odcieni skory +TP_DIRPYREQUALIZER_ALGO_TOOLTIP;- +TP_DIRPYREQUALIZER_HUESKIN;Odcien skory +TP_DIRPYREQUALIZER_HUESKIN_TOOLTIP;Piramida wyznacza zakres kolorow uwazany jako zakres odcieni skory. Wiekszosc odcieni skory - bialej, czarnej, i pomiedzy - ma te sama odcien. Male poprawki sa dopuszczalne, jednak jesli potrzebna jest wieksza zmiana w lewo lub prawo, lub jesli sa widoczne artefakty, to najprawdopobniej balans bieli jest niepoprawny. +TP_DIRPYREQUALIZER_LABEL;Kontrast wg. precyzji detali +TP_DIRPYREQUALIZER_LUMACOARSEST;Zgrubne +TP_DIRPYREQUALIZER_LUMACONTRAST_MINUS;Kontrast- +TP_DIRPYREQUALIZER_LUMACONTRAST_PLUS;Kontrast+ +TP_DIRPYREQUALIZER_LUMAFINEST;Delikatne +TP_DIRPYREQUALIZER_LUMANEUTRAL;Neutralne +TP_DIRPYREQUALIZER_SKIN;Ochrona/celowanie odcieni skory +TP_DIRPYREQUALIZER_SKIN_TOOLTIP;Przy -100 oddzialywanie efektu odbywa sie wylacznie na odcieniach skory.\nPrzy 0 oddzialywanie efektu odbywa sie jednakowo na wszystkich odcieniach.\nPrzy +100 odcienie skory sa pomijane podczas gdy oddzialywanie odbywa sie na wszystkich pozostalych odcieniach. +TP_DIRPYREQUALIZER_THRESHOLD;Prog +TP_DIRPYREQUALIZER_TOOLTIP;Zapobiega artefaktom w strefach przejscia pomiedzy odcieniom skory (hue, chrominancja, luminancja) a pozostalym odcieniom. +TP_DISTORTION_AMOUNT;Sila +TP_DISTORTION_AUTO;Automatyczna korekcja dystorsji +TP_DISTORTION_AUTO_TIP;(Eksperymentalne) Automatyczna korekcja dystorsji obiektywu dla niektorych aparatow (M4/3, kompakty DC, itp.) +TP_DISTORTION_LABEL;Dystorsja +TP_EPD_EDGESTOPPING;Wyszukiwanie krawedzi +TP_EPD_LABEL;Tone Mapping +TP_EPD_REWEIGHTINGITERATES;Powtarzanie rozwazania +TP_EPD_SCALE;Skala +TP_EPD_STRENGTH;Sila +TP_EPD_TOOLTIP;Tone mapping moze sie odbyc w przestrzeni kolorow L*a*b* (domyslnie) oraz CIECAM02.\n\nAby wykonac tone mapping w przestrzeni CIECAM02 nalezy wlaczyc nastepujace ustawienia:\n1. CIECAM02\n2. Algorytm="Jasnosc + Barwistosc (QM)"\n3. "Tone mapping za pomoca jasnosci CIECAM02 (Q)" +TP_EXPOSURE_AUTOLEVELS;Wyrownaj poziomy +TP_EXPOSURE_AUTOLEVELS_TIP;Dokonaj automatycznego ustawienia parametrow ekspozycji na podstawie analizy obrazu +TP_EXPOSURE_BLACKLEVEL;Czern +TP_EXPOSURE_BRIGHTNESS;Jasnosc +TP_EXPOSURE_CLIP;Przytnij % +TP_EXPOSURE_CLIP_TIP;Ulamek pikseli ktore maja zostac rozjasnione do punktu przeswietlenia podczas automatycznego wyrownania poziomow. +TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Prog kompresji podswietlen +TP_EXPOSURE_COMPRHIGHLIGHTS;Kompresja podswietlen +TP_EXPOSURE_COMPRSHADOWS;Kompresja cieni +TP_EXPOSURE_CONTRAST;Kontrast +TP_EXPOSURE_CURVEEDITOR1;Krzywa Tonalna 1 +TP_EXPOSURE_CURVEEDITOR2;Krzywa Tonalna 2 +TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Wiecej informacji na temat optymalnego wykorzystania obu krzywych jest dostepne w podreczniku (RawTherapee Manual) w dziale:\nThe Toolbox > Exposure Tab > Exposure Panel > Tone Curve\n(Narzedzie > Zakladka Ekspozycji > Krzywe Tonalne) +TP_EXPOSURE_CURVEEDITOR;Krzywa tonalna +TP_EXPOSURE_EXPCOMP;Korekcja ekspozycji (EV) +TP_EXPOSURE_LABEL;Ekspozycja +TP_EXPOSURE_SATURATION;Nasycenie +TP_EXPOSURE_TCMODE_FILMLIKE;Klisza +TP_EXPOSURE_TCMODE_LABEL1;Tryb krzywej 1 +TP_EXPOSURE_TCMODE_LABEL2;Tryb krzywej 2 +TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Mieszanie nasycenia i mocy swiatla bialego +TP_EXPOSURE_TCMODE_STANDARD;Standardowa +TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Wazona standardowa +TP_EXPOS_BLACKPOINT_LABEL;Punkt czerni raw +TP_EXPOS_WHITEPOINT_LABEL;Punkt bieli raw +TP_FILMSIMULATION_LABEL;Symulacja Kliszy +TP_FILMSIMULATION_STRENGTH;Sila +TP_FILMSIMULATION_ZEROCLUTSFOUND;Ustaw folder HaldCLUT w Ustawieniach +TP_FLATFIELD_AUTOSELECT;Autowybor +TP_FLATFIELD_BLURRADIUS;Promien rozmycia +TP_FLATFIELD_BLURTYPE;Typ rozmycia +TP_FLATFIELD_BT_AREA;Obszar +TP_FLATFIELD_BT_HORIZONTAL;Poziomy +TP_FLATFIELD_BT_VERTHORIZ;Poziomy + pionowy +TP_FLATFIELD_BT_VERTICAL;Pionowy +TP_FLATFIELD_CLIPCONTROL;Zabezpieczenie przed obcinaniem +TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Funkcja ta chroni przed obcinaniem podswietlen ktore moze zaistniec przy stosowaniu obrazow type "puste pole". Nalezy zachowac ostroznosc, poniewaz jesli obciete rejony istnieja przed zastosowaniem pustego pola, funkcja ta moze spowodowac zabarwienie tych rejonow ktore powinny byc biale. +TP_FLATFIELD_LABEL;Puste pole +TP_GAMMA_CURV;Gamma +TP_GAMMA_FREE;Dowolna gamma +TP_GAMMA_OUTPUT;Wyjsciowa gamma +TP_GAMMA_SLOP;Nachylenie (liniowy) +TP_GENERAL_11SCALE_TOOLTIP;Efekty tego narzedzia sa widoczne badz poprawne przy przyblizeniu 100% lub wiecej. +TP_GRADIENT_CENTER;Srodek +TP_GRADIENT_CENTER_X;Srodek X +TP_GRADIENT_CENTER_X_TOOLTIP;Przesun filtr do lewej (ujemne wartosci) lub prawej (dodatne wartosci). +TP_GRADIENT_CENTER_Y;Srodek Y +TP_GRADIENT_CENTER_Y_TOOLTIP;Przesun filtr do gory (ujemne wartosci) lub do dolu (dodatne wartosci). +TP_GRADIENT_DEGREE;Kat +TP_GRADIENT_DEGREE_TOOLTIP;Kat obrotu filtra w stopniach. +TP_GRADIENT_FEATHER;Wtapianie +TP_GRADIENT_FEATHER_TOOLTIP;Szerokosc nachylenia zbocza w procentach przekatnej. +TP_GRADIENT_LABEL;Filtr Polowkowy +TP_GRADIENT_STRENGTH;Sila +TP_GRADIENT_STRENGTH_TOOLTIP;Sila filtru w jednostkach EV. +TP_HLREC_BLEND;Mieszanie +TP_HLREC_CIELAB;Mieszanie koloru CIELab +TP_HLREC_COLOR;Propagacja koloru +TP_HLREC_ENA_TOOLTIP;Moze zostac automatycznie wlaczone w skutek dzialania automatycznej ekspozycji +TP_HLREC_LABEL;Odzyskiwanie przeswietlen +TP_HLREC_LUMINANCE;Odzyskiwanie luminancji +TP_HLREC_METHOD;Metoda: +TP_HSVEQUALIZER_CHANNEL;Kanal +TP_HSVEQUALIZER_HUE;H +TP_HSVEQUALIZER_LABEL;Ekwalizator HSV +TP_HSVEQUALIZER_SAT;S +TP_HSVEQUALIZER_VAL;V +TP_ICM_BLENDCMSMATRIX;Tlumienie przeswietlen danymi z matrycy +TP_ICM_BLENDCMSMATRIX_TOOLTIP;Wlacz odzyskiwanie przeswietlonych regionow jesli profil ICC wykorzystuje LUT (tablicowanie). +TP_ICM_DCPILLUMINANT;Iluminant +TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolowany +TP_ICM_DCPILLUMINANT_TOOLTIP;Wybierz ktory osadzony iluminant DCP nalezy uzyc. Domyslna opcja jest "interpolowany", czyli wartosc jest mieszanina pomiedzy dwoma osadzonymi wartosciami iluminantu zaleznie od balansu bieli. Ten wybor jest mozliwy jedynie kiedy DCP zawiera dwa iluminanty z mozliwoscia interpolacji. +TP_ICM_INPUTCAMERAICC;Domyslny aparatu lub ICC +TP_ICM_INPUTCAMERAICC_TOOLTIP;Uzyj profil ICC stworzony specjalnie na potrzeby RawTherapee. Jest bardziej dokladny niz domyslny matrycowy profil ICC, lecz dostepny tylko dla niektorych aparatow. +TP_ICM_INPUTCAMERA;Domyslny aparatu +TP_ICM_INPUTCAMERA_TOOLTIP;Uzyj prostej domyslnej matrycy kolorow z DCRAW badz zapisanej w DNG. +TP_ICM_INPUTCUSTOM;Wlasny +TP_ICM_INPUTCUSTOM_TOOLTIP;Wczytaj wlasny profil ICC z pliku. +TP_ICM_INPUTDLGLABEL;Wybierz wejsciowy profil ICC... +TP_ICM_INPUTEMBEDDED;Jesli to mozliwe, uzyj osadzonego +TP_ICM_INPUTEMBEDDED_TOOLTIP;Uzyj profil ICC zapisany w plikach innych niz raw. +TP_ICM_INPUTNONE;Bez profilu +TP_ICM_INPUTNONE_TOOLTIP;Nie uzywaj zadnego profilu kolorow. Pozyteczne jedynie w wyjatkowych przypadkach. +TP_ICM_INPUTPROFILE;Profil wejsciowy +TP_ICM_LABEL;ICM +TP_ICM_NOICM;Brak ICM: Wyjscie sRGB +TP_ICM_OUTPUTPROFILE;Profil wyjsciowy +TP_ICM_SAVEREFERENCE;Zapisz obraz wzorcowy dla profilowania +TP_ICM_SAVEREFERENCE_TOOLTIP;Zapisz liniowy obraz TIFF zanim profil wejsciowy zostanie zastosowany. Obraz ten mozna uzyc do kalibracji oraz do wytworzenia profilu aparatu. +TP_ICM_TONECURVE;Uzyj krzywa tonalna z DCP +TP_ICM_TONECURVE_TOOLTIP;Wlacz aby uzyc krzywa tonalna znajdujaca sie w profilu DCP. Opcja ta jest tylko aktywna jesli profil DCP zawiera krzywa tonalna. +TP_ICM_WORKINGPROFILE;Profil roboczy +TP_IMPULSEDENOISE_LABEL;Redukcja Szumow Impulsowych +TP_IMPULSEDENOISE_THRESH;Prog +TP_LABCURVE_AVOIDCOLORSHIFT;Zapobiegaj zmianom koloru +TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Umieszcza kolory w gamie roboczej przestrzeni kolorow i stosuje korekte Munsell'a +TP_LABCURVE_BRIGHTNESS;Swiatlosc +TP_LABCURVE_CHROMATICITY;Chromatycznosc +TP_LABCURVE_CHROMA_TOOLTIP;Aby zastosowac tonowanie zdjecia B&W, ustaw chromatycznosc na -100. +TP_LABCURVE_CONTRAST;Kontrast +TP_LABCURVE_CURVEEDITOR;Krzywa luminacji +TP_LABCURVE_CURVEEDITOR_A_RANGE1;Zielone Nasycone +TP_LABCURVE_CURVEEDITOR_A_RANGE2;Zielone Pastelowe +TP_LABCURVE_CURVEEDITOR_A_RANGE3;Czerwone Pastelowe +TP_LABCURVE_CURVEEDITOR_A_RANGE4;Czerwone Nasycone +TP_LABCURVE_CURVEEDITOR_B_RANGE1;Niebieskie Nasycone +TP_LABCURVE_CURVEEDITOR_B_RANGE2;Niebieskie Pastelowe +TP_LABCURVE_CURVEEDITOR_B_RANGE3;Zolte Pastelowe +TP_LABCURVE_CURVEEDITOR_B_RANGE4;Zolte Nasycone +TP_LABCURVE_CURVEEDITOR_CC;CC +TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutralne +TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Metne +TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastelowe +TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Nasycone +TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Chromatycznosc wedlug chromatycznosci C=f(C). +TP_LABCURVE_CURVEEDITOR_CH;CH +TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromatycznosc wedlug odcieni (hue) C=f(H) +TP_LABCURVE_CURVEEDITOR_CL;CL +TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Chromatycznosc wedlug luminancji C=f(L) +TP_LABCURVE_CURVEEDITOR_HH;HH +TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Odcien (hue) wedlug odcieni H=f(H) +TP_LABCURVE_CURVEEDITOR_LC;LC +TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminancja wedlug chromatycznosci L=f(C) +TP_LABCURVE_CURVEEDITOR_LH;LH +TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Luminance wedlug odcieni (hue) L=f(H) +TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminancja wedlug luminancji L=f(L) +TP_LABCURVE_LABEL;Regulacja L*a*b* +TP_LABCURVE_LCREDSK;Ogranicz LC do odcieni skory oraz czerwieni +TP_LABCURVE_LCREDSK_TIP;Kiedy opcja jest wlaczona, wplyw krzywej LC (Luminancja wedlug chromatycznosci) jest ograniczony do odcieni skory oraz czerwieni.\nKiedy opcja jest wylaczona, krzywa LC wplywa na wszystkie barwy. +TP_LABCURVE_RSTPROTECTION;Ochrona skory oraz czerwieni +TP_LABCURVE_RSTPRO_TOOLTIP;Ma wplyw na suwak Chromatycznosci oraz na krzywa CC. +TP_LENSGEOM_AUTOCROP;Auto-kadrowanie +TP_LENSGEOM_FILL;Auto-wypelnienie +TP_LENSGEOM_LABEL;Obiektyw / Geometria +TP_LENSPROFILE_LABEL;Profil korekcji obiektywu LCP +TP_LENSPROFILE_USECA;Korekja aberacji chromatycznej +TP_LENSPROFILE_USEDIST;Korekcja dystorsji +TP_LENSPROFILE_USEVIGN;Korekcja winietowania +TP_NEUTRAL;Neutralne +TP_NEUTRAL_TIP;Zresetuj ustawienia do wartosci neutralnych.\nDziala na tych samych suwakach na ktorych funkcja "Wyrownaj poziomy" dziala, niezaleznie od tego czy funkcja ta byla uzyta czy nie. +TP_PCVIGNETTE_FEATHER;Wtapianie +TP_PCVIGNETTE_FEATHER_TOOLTIP;Wtapianie:\n0 = tylko brzegi,\n50 = w pol drogi do srodka,\n100 = az do srodka. +TP_PCVIGNETTE_LABEL;Winietowanie +TP_PCVIGNETTE_ROUNDNESS;Okraglosc +TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Okraglosc:\n0 = prostokat,\n50 = dopasowana elipsa,\n100 = okrag. +TP_PCVIGNETTE_STRENGTH;Sila +TP_PCVIGNETTE_STRENGTH_TOOLTIP;Sila filtru w katach w jednostkach EV. +TP_PERSPECTIVE_HORIZONTAL;Pozioma +TP_PERSPECTIVE_LABEL;Perspektywa +TP_PERSPECTIVE_VERTICAL;Pionowa +TP_PFCURVE_CURVEEDITOR_CH;Odcien +TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Ogranicza natezenie usuwania widma wedlug kolorow.\nWyzej = bardziej,\nNizej = mniej. +TP_PREPROCESS_DEADPIXFILT;Filtr martwych pikseli +TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Lata martwe piksele (pojedyncze czarne piksele). +TP_PREPROCESS_GREENEQUIL;Wyrownanie zieleni +TP_PREPROCESS_HOTPIXFILT;Filtr goracych pikseli +TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Lata gorace piksele (pojedyncze swiecace, przesycone piksele). +TP_PREPROCESS_LABEL;Przetwarzanie poczatkowe +TP_PREPROCESS_LINEDENOISE;Filtr zaklocen liniowych +TP_PREPROCESS_NO_FOUND;Nic nie znaleziono +TP_RAWCACORR_AUTO;Autokorekcja +TP_RAWCACORR_CABLUE;Niebieski +TP_RAWCACORR_CARED;Czerwony +TP_RAWEXPOS_BLACKS;Poziomy czerni +TP_RAWEXPOS_BLACK_0;Zielony 1 (glowny) +TP_RAWEXPOS_BLACK_1;Czerwony +TP_RAWEXPOS_BLACK_2;Niebieski +TP_RAWEXPOS_BLACK_3;Zielony 2 +TP_RAWEXPOS_BLACK_BLUE;Niebieski +TP_RAWEXPOS_BLACK_GREEN;Zielony +TP_RAWEXPOS_BLACK_RED;Czerwony +TP_RAWEXPOS_LINEAR;Liniowy wspolczynnik korekcji +TP_RAWEXPOS_PRESER;Zachowanie przeswietlen +TP_RAWEXPOS_RGB;Czerwony, Zielony, Niebieski +TP_RAWEXPOS_TWOGREEN;Polacz obie zielenie +TP_RAW_DCBENHANCE;Zastosuj poprawe DCB +TP_RAW_DCBITERATIONS;Liczba powtorzen DCB +TP_RAW_DMETHOD;Metoda +TP_RAW_DMETHOD_PROGRESSBAR;Demozaikowanie %1... +TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Udoskonalanie demozaikowania... +TP_RAW_DMETHOD_TOOLTIP;IGV oraz LMMSE sa przeznaczone dla zdjec raw o wysokim poziomie szumow (wysokie ISO) aby zapobiec utworzeniu sie wzorkow w ksztalcie malych labiryntow, posteryzacji oraz mydlanego wygladu. +TP_RAW_FALSECOLOR;Kroki zapobiegajace falszowaniu kolorow +TP_RAW_LABEL;Demozaikowanie +TP_RAW_LMMSEITERATIONS;Ilosc krokow udoskonalenia LMMSE +TP_RAW_LMMSE_TOOLTIP;Aby zmniejszyc ilosc artefaktow i poprawic stosunek sygnalu do szumow, mozna wykorzystac nastepujace ustawienia:\n1: Gamma\n2-4: Srednia mediana\n5-6: Rafinowanie +TP_RAW_SENSOR_BAYER_LABEL;Matryca z filtrem Bayera +TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;Trzy powtorzenia prowadza do najlepszych rezultatow (zalecane dla zdjec o niskim ISO).\nJedno powtorzenie jest prawie nie do odroznienia od trzech dla zdjec o wysokim ISO a jest znacznie szybsze. +TP_RAW_SENSOR_XTRANS_LABEL;Matryca z filtrem X-Trans +TP_RESIZE_APPLIESTO;Dotyczy: +TP_RESIZE_CROPPEDAREA;Obszaru kadrowanego +TP_RESIZE_FITBOX;Wymiary obwodu +TP_RESIZE_FULLIMAGE;Calego zdjecia +TP_RESIZE_HEIGHT;Wysokosc +TP_RESIZE_H;Wysokosc: +TP_RESIZE_LABEL;Zmiana rozmiaru +TP_RESIZE_LANCZOS;Lanczos +TP_RESIZE_METHOD;Metoda: +TP_RESIZE_NEAREST;Najblizsza +TP_RESIZE_SCALE;Skale +TP_RESIZE_SPECIFY;Okresl: +TP_RESIZE_WIDTH;Szerokosc +TP_RESIZE_W;Szerokosc +TP_RGBCURVES_BLUE;B +TP_RGBCURVES_CHANNEL;Kanal +TP_RGBCURVES_GREEN;G +TP_RGBCURVES_LABEL;Krzywe RGB +TP_RGBCURVES_LUMAMODE;Tryb Luminancji +TP_RGBCURVES_LUMAMODE_TOOLTIP;Tryb Luminancji pozwala na zmiane wplywu kanalow R, G i B na luminancje obrazu bez zmian kolorow. +TP_RGBCURVES_RED;R +TP_ROTATE_DEGREE;Stopnie +TP_ROTATE_LABEL;Obrot +TP_ROTATE_SELECTLINE;Wyprostuj obraz +TP_SAVEDIALOG_OK_TIP;Skrot: Ctrl-Enter +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Podswietlenia +TP_SHADOWSHLIGHTS_HLTONALW;Szerokosc tonalna +TP_SHADOWSHLIGHTS_LABEL;Cienie/Podswietlenia +TP_SHADOWSHLIGHTS_LOCALCONTR;Kontrast lokalny +TP_SHADOWSHLIGHTS_RADIUS;Promien +TP_SHADOWSHLIGHTS_SHADOWS;Cienie +TP_SHADOWSHLIGHTS_SHARPMASK;Ostra maska +TP_SHADOWSHLIGHTS_SHTONALW;Szerokosc tonalna +TP_SHARPENEDGE_AMOUNT;Sila +TP_SHARPENEDGE_LABEL;Krawedzie +TP_SHARPENEDGE_PASSES;Powtorzenia +TP_SHARPENEDGE_THREE;Tylko luminancja +TP_SHARPENING_AMOUNT;Sila +TP_SHARPENING_EDRADIUS;Promien +TP_SHARPENING_EDTOLERANCE;Tolerancja krawedzi +TP_SHARPENING_HALOCONTROL;Kontrola poswiaty +TP_SHARPENING_HCAMOUNT;Sila +TP_SHARPENING_LABEL;Wyostrzanie +TP_SHARPENING_METHOD;Metoda +TP_SHARPENING_ONLYEDGES;Wyostrz tylko krawedzie +TP_SHARPENING_RADIUS;Promien +TP_SHARPENING_RLD;Dekonwolucja RL +TP_SHARPENING_RLD_AMOUNT;Sila +TP_SHARPENING_RLD_DAMPING;Tlumienie +TP_SHARPENING_RLD_ITERATIONS;Powtorzenia +TP_SHARPENING_THRESHOLD;Prog +TP_SHARPENING_TOOLTIP;Kiedy CIECAM02 jest aktywne efekt wyostrzania moze ulec drobnym zmianom. W malo prawdopodobnym przypadku zuwazenia zmiany wystarczy prystosowac suwaki wedlug gustu. +TP_SHARPENING_USM;Maska wyostrzajaca +TP_SHARPENMICRO_AMOUNT;Sila +TP_SHARPENMICRO_LABEL;Mikrokontrast +TP_SHARPENMICRO_MATRIX;Matryca 3×3 zamiast 5×5 +TP_SHARPENMICRO_UNIFORMITY;Jednolitosc +TP_VIBRANCE_AVOIDCOLORSHIFT;Zapobiegaj przesuniecia kolorow +TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH +TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Odcienie skory +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Czerwone/Purpurowe +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Czerwone +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Czerwone/Zolte +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Zolte +TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Odcien (hue) wedlug odcieni H=f(H) +TP_VIBRANCE_LABEL;Jaskrawosc +TP_VIBRANCE_PASTELS;Odcienie pastelowe +TP_VIBRANCE_PASTSATTOG;Polacz odcienie pastelowe i nasycone +TP_VIBRANCE_PROTECTSKINS;Zachowaj odcienie skory +TP_VIBRANCE_PSTHRESHOLD;Prog odcieni pastelowych/nasyconych +TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Prog nasycenia +TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;Os pionowa odpowiada barwa pastelowym na dole oraz nasyconym na gorze.\nOs pozioma przedstawia zakres nasycenia. +TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Wazenie przejscia barw pastelowych/nasyconych +TP_VIBRANCE_SATURATED;Odcienie nasycone +TP_VIGNETTING_AMOUNT;Ilosc +TP_VIGNETTING_CENTER;Srodek +TP_VIGNETTING_CENTER_X;Srodek X +TP_VIGNETTING_CENTER_Y;Srodek Y +TP_VIGNETTING_LABEL;Korekcja winietowania +TP_VIGNETTING_RADIUS;Promien +TP_VIGNETTING_STRENGTH;Sila +TP_WBALANCE_AUTO;Auto +TP_WBALANCE_CAMERA;Z aparatu +TP_WBALANCE_CLOUDY;Pochmurnie +TP_WBALANCE_CUSTOM;Wlasny +TP_WBALANCE_DAYLIGHT;Swiatlo dzienne (slonecznie) +TP_WBALANCE_EQBLUERED;Ekwalizator niebieskosci/czerwieni +TP_WBALANCE_EQBLUERED_TOOLTIP;Pozwala na odchylke od typowego uzytku balansu bieli poprzez modulacje balansu niebieskosci/czerwieni.\nJest to przydatne kiedy:\na) warunki miejsca fotografii sa oddalone od standardowego iluminantu (swiatla o okreslonych parametrach za pomoca ktorego kalibruje sie profil wejsciowy aparatu), np. zdjecia robione pod woda,\nb) warunki fotografii sa oddalone od warunkow pod ktorymi kalibracje zostaly wykonane,\nc) macierze oraz profile ICC/DCP sa z jakiegos powodu nieodpowiednie. +TP_WBALANCE_FLASH55;Leica +TP_WBALANCE_FLASH60;Standardowe, Canon, Pentax, Olympus +TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta +TP_WBALANCE_FLASH_HEADER;Flash +TP_WBALANCE_FLUO1;F1 - Swiatlo dzienne +TP_WBALANCE_FLUO2;F2 - Chlodne biale +TP_WBALANCE_FLUO3;F3 - Biale +TP_WBALANCE_FLUO4;F4 - Cieple biale +TP_WBALANCE_FLUO5;F5 - Swiatlo dzienne +TP_WBALANCE_FLUO6;F6 - Biale Lite +TP_WBALANCE_FLUO7;F7 - D65 Symulator swiatla dziennego +TP_WBALANCE_FLUO8;F8 - D50 / Sylvania F40 Design +TP_WBALANCE_FLUO9;F9 - Chlodne biale deluxe +TP_WBALANCE_FLUO10;F10 - Philips TL85 +TP_WBALANCE_FLUO11;F11 - Philips TL84 +TP_WBALANCE_FLUO12;F12 - Philips TL83 +TP_WBALANCE_FLUO_HEADER;Jarzeniowe +TP_WBALANCE_GREEN;Odcien +TP_WBALANCE_GTI;GTI +TP_WBALANCE_HMI;HMI +TP_WBALANCE_JUDGEIII;JudgeIII +TP_WBALANCE_LABEL;Balans bieli +TP_WBALANCE_LAMP_HEADER;Lamp +TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 +TP_WBALANCE_LED_HEADER;LED +TP_WBALANCE_LED_LSI;LSI Lumelex 2040 +TP_WBALANCE_METHOD;Metoda +TP_WBALANCE_SHADE;Cien +TP_WBALANCE_SIZE;Wielkosc: +TP_WBALANCE_SOLUX35;Solux 3500K +TP_WBALANCE_SOLUX41;Solux 4100K +TP_WBALANCE_SOLUX47;Solux 4700K (vendor) +TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) +TP_WBALANCE_SPOTWB;Punktowy +TP_WBALANCE_TEMPERATURE;Temperatura +TP_WBALANCE_TUNGSTEN;Wolfram +TP_WBALANCE_WATER1;Pod woda 1 +TP_WBALANCE_WATER2;Pod woda 2 +TP_WBALANCE_WATER_HEADER;Pod woda +ZOOMPANEL_100;(100%) +ZOOMPANEL_NEWCROPWINDOW;Otworz (nowa) lupe +ZOOMPANEL_ZOOM100;Powieksz do 100%\nSkrot: z +ZOOMPANEL_ZOOMFITCROPSCREEN;Dopasuj kadr do ekranu\nSkrot: Alt-f +ZOOMPANEL_ZOOMFITSCREEN;Dopasuj caly obraz do ekranu\nSkrot: f +ZOOMPANEL_ZOOMIN;Przybliz\nSkrot: + +ZOOMPANEL_ZOOMOUT;Oddal\nSkrot: - + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!CURVEEDITOR_AXIS_IN;I: +!CURVEEDITOR_AXIS_LEFT_TAN;LT: +!CURVEEDITOR_AXIS_OUT;O: +!CURVEEDITOR_AXIS_RIGHT_TAN;RT: +!CURVEEDITOR_EDITPOINT_HINT;Enable edition of node in/out values.\n\nRight-click on a node to select it.\nRight-click on empty space to de-select the node. +!EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels +!FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!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_ASIMAGE;As Image +!HISTORY_MSG_299;NR - Chrominance curve +!HISTORY_MSG_300;- +!HISTORY_MSG_301;NR - Luma control +!HISTORY_MSG_302;NR - Chroma method +!HISTORY_MSG_303;NR - Chroma method +!HISTORY_MSG_304;W - Contrast levels +!HISTORY_MSG_305;Wavelet Levels +!HISTORY_MSG_306;W - Preview +!HISTORY_MSG_307;W - Preview +!HISTORY_MSG_308;W - Preview direction +!HISTORY_MSG_309;W - ES - Detail +!HISTORY_MSG_310;W - Residual - Sky tar/prot +!HISTORY_MSG_311;W - Wavelet levels +!HISTORY_MSG_312;W - Residual - Shadows threshold +!HISTORY_MSG_313;W - Chroma - Sat/past +!HISTORY_MSG_314;W - Gamut - Reduce artifacts +!HISTORY_MSG_315;W - Residual - Contrast +!HISTORY_MSG_316;W - Gamut - Skin tar/prot +!HISTORY_MSG_317;W - Gamut - Skin hue +!HISTORY_MSG_318;W - Contrast - Highlight levels +!HISTORY_MSG_319;W - Contrast - Highlight range +!HISTORY_MSG_320;W - Contrast - Shadow range +!HISTORY_MSG_321;W - Contrast - Shadow levels +!HISTORY_MSG_322;W - Gamut - Avoid color shift +!HISTORY_MSG_323;W - ES - Local contrast +!HISTORY_MSG_324;W - Chroma - Pastel +!HISTORY_MSG_325;W - Chroma - Saturated +!HISTORY_MSG_326;W - Chroma - Method +!HISTORY_MSG_327;W - Contrast - Apply to +!HISTORY_MSG_328;W - Chroma - Link strength +!HISTORY_MSG_329;W - Toning - Opacity RG +!HISTORY_MSG_330;W - Toning - Opacity BY +!HISTORY_MSG_331;W - Contrast levels - Extra +!HISTORY_MSG_332;W - Tiling method +!HISTORY_MSG_333;W - Residual - Shadows +!HISTORY_MSG_334;W - Residual - Chroma +!HISTORY_MSG_335;W - Residual - Highlights +!HISTORY_MSG_336;W - Residual - Highlights threshold +!HISTORY_MSG_337;W - Residual - Sky hue +!HISTORY_MSG_338;W - ES - Radius +!HISTORY_MSG_339;W - ES - Strength +!HISTORY_MSG_340;W - Strength +!HISTORY_MSG_341;W - Edge performance +!HISTORY_MSG_342;W - ES - First level +!HISTORY_MSG_343;W - Chroma levels +!HISTORY_MSG_344;W - Meth chroma sl/cur +!HISTORY_MSG_345;W - ES - Local contrast +!HISTORY_MSG_346;W - ES - Local contrast method +!HISTORY_MSG_347;W - Denoise - Level 0 +!HISTORY_MSG_348;W - Denoise - Level 1 +!HISTORY_MSG_349;W - Denoise - Level 2 +!HISTORY_MSG_350;W - ES - Edge detection +!HISTORY_MSG_351;W - Residual - HH curve +!HISTORY_MSG_352;W - Background +!HISTORY_MSG_353;W - ES - Gradient sensitivity +!HISTORY_MSG_354;W - ES - Enhance +!HISTORY_MSG_355;W - ES - Threshold low +!HISTORY_MSG_356;W - ES - Threshold high +!HISTORY_MSG_357;W - Denoise - Link with ES +!HISTORY_MSG_358;W - Gamut - CH +!HISTORY_MSG_359;Hot/Dead - Threshold +!HISTORY_MSG_360;TM Gamma +!HISTORY_MSG_361;W - Final - Chroma balance +!HISTORY_MSG_362;W - Residual - Compression method +!HISTORY_MSG_363;W - Residual - Compression strength +!HISTORY_MSG_364;W - Final - Contrast balance +!HISTORY_MSG_365;W - Final - Delta balance +!HISTORY_MSG_366;W - Residual - Compression gamma +!HISTORY_MSG_367;W - ES - Local contrast curve +!HISTORY_MSG_368;W - Final - Contrast balance +!HISTORY_MSG_369;W - Final - Balance method +!HISTORY_MSG_370;W - Final - Local contrast curve +!MAIN_TAB_INSPECT; Inspect +!MAIN_TAB_WAVELET;Wavelet +!MAIN_TAB_WAVELET_TOOLTIP;Shortcut: Alt-w +!PARTIALPASTE_EQUALIZER;Wavelet Equalizer +!PARTIALPASTE_WAVELETGROUP;Wavelet processing +!PREFERENCES_AUTLISLOW;Low +!PREFERENCES_AUTLISMAX;Max - Average of all tiles +!PREFERENCES_AUTLISSTD;High +!PREFERENCES_AUTLISVLOW;None +!PREFERENCES_AUTLOW;Low +!PREFERENCES_AUTSTD;Standard +!PREFERENCES_CIEART_FRAME;CIECAM02-Specific Settings +!PREFERENCES_CLUTSCACHE;HaldCLUT Cache +!PREFERENCES_CLUTSCACHE_LABEL;Maximum number of cached CLUTs +!PREFERENCES_CURVEBBOXPOS;Position of curve copypasta buttons +!PREFERENCES_CURVEBBOXPOS_ABOVE;Above +!PREFERENCES_CURVEBBOXPOS_BELOW;Below +!PREFERENCES_CURVEBBOXPOS_LEFT;Left +!PREFERENCES_CURVEBBOXPOS_RIGHT;Right +!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_EXPAUT;Expert +!PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT;Same thumbnail height between the Editor's panel 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_GREYSC18;Yb=18 CIE L#50 +!PREFERENCES_GREYSCA;Automatic +!PREFERENCES_GREYSC;Scene Yb luminance (%) +!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_LEVAUTDN;Denoising level +!PREFERENCES_LEVDN;Cell size +!PREFERENCES_LISS;Auto multi-zone smoothing +!PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders +!PREFERENCES_MAX;Maxi (Tile) +!PREFERENCES_MED;Medium (Tile/2) +!PREFERENCES_MIN;Mini (100x115) +!PREFERENCES_NAVIGATIONFRAME;Navigation +!PREFERENCES_NOISE;Noise Reduction +!PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Overlay filenames on thumbnails in the editor pannel +!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_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_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_SHOWFILMSTRIPTOOLBAR;Show filmstrip toolbar +!PREFERENCES_SIMPLAUT;Tool mode +!PREFERENCES_SMA;Small (250x287) +!PREFERENCES_STDAUT;Standard +!PREFERENCES_TIMAX;High +!PREFERENCES_TINB;Number of tiles +!PREFERENCES_TISTD;Standard +!PREFERENCES_WAVLEV;Increase wavelet level in quality 'high' +!PREFERENCES_WLONE;One level +!PREFERENCES_WLTWO;Two levels +!PREFERENCES_WLZER;No +!TP_CROP_GTHARMMEANS;Harmonic Means +!TP_CROP_GTTRIANGLE1;Golden Triangles 1 +!TP_CROP_GTTRIANGLE2;Golden Triangles 2 +!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_ABM;Chroma only +!TP_DIRPYRDENOISE_AUTO;Automatic global +!TP_DIRPYRDENOISE_AUTO_TOOLTIP;Try to evaluate chroma noise\nBe careful, this calculation is average, and is quite subjective ! +!TP_DIRPYRDENOISE_AUT;Automatic global +!TP_DIRPYRDENOISE_C2TYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CCCURVE;Chrominance curve +!TP_DIRPYRDENOISE_CHROMAFR;Chrominance +!TP_DIRPYRDENOISE_CTYPE;Auto method +!TP_DIRPYRDENOISE_CTYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nAutomatic multi-zones\nNo preview - works only during saving, but using the "Preview" method by matching the tile size and center to the preview size and center you can get an idea of the expected results.\nThe image is divided into tiles (about 10 to 70 depending on image size) and each tile receives its own chrominance noise reduction settings.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CURVEEDITOR_CC;Chroma +!TP_DIRPYRDENOISE_CURVEEDITOR_CC_TOOLTIP;Increase (multiply) the value of all chrominance sliders.\nThis curve lets you adjust the strength of chromatic noise reduction as a function of chromaticity, for instance to increase the action in areas of low saturation and to decrease it in those of high saturation. +!TP_DIRPYRDENOISE_LPLABM;Weighted L* (little) + a*b* (normal) +!TP_DIRPYRDENOISE_LTYPE;Luminance control +!TP_DIRPYRDENOISE_LUMAFR;Luminance +!TP_DIRPYRDENOISE_LUMAFR_TOOLTIP;Wavelet on luminance and Fourier transform for luminance detail +!TP_DIRPYRDENOISE_MANU;Manual +!TP_DIRPYRDENOISE_MAN;Manual +!TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - +!TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 +!TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. +!TP_DIRPYRDENOISE_PON;Auto multi-zones +!TP_DIRPYRDENOISE_PREVLABEL;Preview size=%1, Center: Px=%2 Py=%3 +!TP_DIRPYRDENOISE_PREV;Preview +!TP_DIRPYRDENOISE_PRE;Preview multi-zones +!TP_DIRPYRDENOISE_SLI;Slider +!TP_DIRPYRDENOISE_TILELABEL;Tile size=%1, Center: Tx=%2 Ty=%3 +!TP_DIRPYREQUALIZER_ARTIF;Reduce artifacts +!TP_EPD_GAMMA;Gamma +!TP_EXPOSURE_TCMODE_LUMINANCE;Luminance +!TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance +!TP_RAW_HD;Threshold +!TP_RAW_HD_TOOLTIP;Lower values make hot/dead pixel detection more aggressive, but false positives may lead to artifacts. If you notice any artifacts appearing when enabling the Hot/Dead Pixel Filters, gradually increase the threshold value until they disappear. +!TP_WAVELET_1;Level 1 +!TP_WAVELET_2;Level 2 +!TP_WAVELET_3;Level 3 +!TP_WAVELET_4;Level 4 +!TP_WAVELET_5;Level 5 +!TP_WAVELET_6;Level 6 +!TP_WAVELET_7;Level 7 +!TP_WAVELET_8;Level 8 +!TP_WAVELET_9;Level 9 +!TP_WAVELET_ALL;All levels in all directions +!TP_WAVELET_APPLYTO;Apply To +!TP_WAVELET_AVOID;Avoid color shift +!TP_WAVELET_B0;Black +!TP_WAVELET_B1;Grey +!TP_WAVELET_B2;Residual +!TP_WAVELET_BACUR;Curve +!TP_WAVELET_BALANCE;Contrast balance d/v-h +!TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chromaticity or residual tone mapping are activated, the effect due to balance is amplified. +!TP_WAVELET_BALCHRO;Chroma balance +!TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chromaticity balance. +!TP_WAVELET_BANONE;None +!TP_WAVELET_BASLI;Slider +!TP_WAVELET_BATYPE;Contrast balance method +!TP_WAVELET_CCURVE;Local contrast +!TP_WAVELET_CH1;Whole chromaticity range +!TP_WAVELET_CH2;Saturated/pastel +!TP_WAVELET_CH3;Link contrast levels +!TP_WAVELET_CHCU;Curve +!TP_WAVELET_CHRO;Saturated/pastel threshold +!TP_WAVELET_CHRO_TOOLTIP;Sets the wavelet level which will be the threshold between saturated and pastel colors.\n1-x: saturated\nx-9: pastel\n\nIf the value exceeds the amount of wavelet levels you are using then it will be ignored. +!TP_WAVELET_CHR;Chroma-contrast link strength +!TP_WAVELET_CHR_TOOLTIP;Adjusts chromaticity as a function of "contrast levels" and "chroma-contrast link strength" +!TP_WAVELET_CHSL;Sliders +!TP_WAVELET_CHTYPE;Chrominance method +!TP_WAVELET_COLORT;Opacity Red-Green +!TP_WAVELET_COMBOTH;Both +!TP_WAVELET_COMPCONT;Contrast +!TP_WAVELET_COMPGAMMA;Compression gamma +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjusting the gamma of the residual image allow you to equilibrate the data and histogram. +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjust gamma for residual image and compression.\nAllow to equilibrate data and histogram +!TP_WAVELET_COMPTM;Tone mapping +!TP_WAVELET_CONTEDIT;'After' Contrast curve +!TP_WAVELET_CONTEDIT;'After' contrast curve +!TP_WAVELET_CONTRAST_MINUS;Contrast - +!TP_WAVELET_CONTRAST_PLUS;Contrast + +!TP_WAVELET_CONTRA;Contrast +!TP_WAVELET_CONTRA_TOOLTIP;Changes contrast of the residual image. +!TP_WAVELET_CONTR;Gamut +!TP_WAVELET_CTYPE;Chrominance control +!TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modifies local contrast as a function of the original local contrast (absciss)\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 100..300)\n66% absciss represents standard deviation of local contrast (real value about 300..800)\n100% represents maximum (real value about 3000..8000) +!TP_WAVELET_CURVEEDITOR_CH;Contrast levels=f(Hue) +!TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modifies each level's contrast as a function oh hue.\nTake care not to overwrite changes made with the Gamut Hue controls.\nThe curve will only have an effect when wavelet contrast level sliders are non-zero. +!TP_WAVELET_CURVEEDITOR_CL;L +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Applies a final contrast luminance curve at the end of the wavelet treatment. +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Apply a contrast luminance curve at the end of wavelet level threatment +!TP_WAVELET_CURVEEDITOR_HH;HH +!TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modifies the residual image's hue as a function of hue. +!TP_WAVELET_DALL;All directions +!TP_WAVELET_DAUB;Edge performance +!TP_WAVELET_DAUB_TOOLTIP;Changes Daubechies coefficients:\nD4 = Standard,\nD14 = Often best performance, 10% more time-intensive.\n\nAffects edge detection as well as the general quality of the firsts levels. However the quality is not strictly related to this coefficient and can vary with images and uses. +!TP_WAVELET_DISP;Preview Settings +!TP_WAVELET_DONE;Vertical +!TP_WAVELET_DTHR;Diagonal +!TP_WAVELET_DTWO;Horizontal +!TP_WAVELET_EDCU;Curve +!TP_WAVELET_EDGCONT;Local contrast +!TP_WAVELET_EDGCONT_TOOLTIP;Adjusting the points to the left decreases contrast, and to the right increases it.\nBottom-left, Top-Left, Top-Right, Bottom-right represent respectively local contast for low values, mean, mean+stdev, maxima +!TP_WAVELET_EDGEDETECTTHR2;Threshold high (detection) +!TP_WAVELET_EDGEDETECTTHR;Threshold low (noise) +!TP_WAVELET_EDGEDETECTTHR_TOOLTIP;This adjuster lets you target edge detection for example to avoid applying edge sharpness to fine details, such as noise in the sky. +!TP_WAVELET_EDGEDETECT;Gradient sensitivity +!TP_WAVELET_EDGEDETECT_TOOLTIP;Moving the slider to the right increases edge sensitivity. This affects local contrast, edge settings and noise. +!TP_WAVELET_EDGE;Edge Sharpness +!TP_WAVELET_EDGREINF_TOOLTIP;Reinforce or reduce the action of the first level, do the opposite to the second level, and leave the rest unchanged. +!TP_WAVELET_EDGTHRESH;Detail +!TP_WAVELET_EDGTHRESH_TOOLTIP;Change the repartition between the first levels and the others. The higher the threshold the more the action is centred on the first levels. Be careful with negative values, they increase the action of high levels and can introduce artifacts. +!TP_WAVELET_EDRAD;Radius +!TP_WAVELET_EDRAD_TOOLTIP;This radius adjustment is very different from those in other sharpening tools. Its value is compared to each level through a complex function. In this sense, a value of zero still has an effect. +!TP_WAVELET_EDSL;Threshold Sliders +!TP_WAVELET_EDTYPE;Local contrast method +!TP_WAVELET_EDVAL;Strength +!TP_WAVELET_FINAL;Final Touchup +!TP_WAVELET_FINEST;Finest +!TP_WAVELET_HIGHLIGHT;Highlight luminance range +!TP_WAVELET_HS1;Whole luminance range +!TP_WAVELET_HS2;Shadows/Highlights +!TP_WAVELET_HUESKIN;Skin hue +!TP_WAVELET_HUESKIN_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_HUESKY;Sky hue +!TP_WAVELET_HUESKY_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_INF;Below or equal the level +!TP_WAVELET_ITER;Delta balance levels +!TP_WAVELET_ITER_TOOLTIP;Left: increase low levels and reduce high levels,\nRight: reduce low levels and increase high levels. +!TP_WAVELET_LABEL;Wavelet levels +!TP_WAVELET_LARGEST;Coarsest +!TP_WAVELET_LEVCH;Chromaticity +!TP_WAVELET_LEVELS;Wavelet levels +!TP_WAVELET_LEVELS_TOOLTIP;Choose the number of detail levels the image is to be decomposed into. More levels require more RAM and require a longer processing time. +!TP_WAVELET_LEVF;Contrast +!TP_WAVELET_LEVLABEL;Preview maximum possible levels = %1 +!TP_WAVELET_LEVONE;Level 2 +!TP_WAVELET_LEVTWO;Level 3 +!TP_WAVELET_LEVZERO;Level 1 +!TP_WAVELET_LINKEDG;Link with Edge Sharpness' Strength +!TP_WAVELET_LIPST;Enhanced algorithm +!TP_WAVELET_LIPST_TOOLTIP;This algorithm uses Lipschitz regularity to increase edge detection quality at a cost of increased processing time and memory requirements. +!TP_WAVELET_LOWLIGHT;Shadow luminance range +!TP_WAVELET_MEDGREINF;First level +!TP_WAVELET_MEDILEV;Edge detection +!TP_WAVELET_MEDI;Reduce artifacts in blue sky +!TP_WAVELET_NEUTRAL;Neutral +!TP_WAVELET_NOISE;Denoise and Refine +!TP_WAVELET_NOIS;Denoise +!TP_WAVELET_ONE;One level +!TP_WAVELET_OPACITYWL;Final local contrast +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify final local contrast in function of last local contrast (absciss) for all levels decomposition\nTake into account: \na)contrast levels \nb)edge sharpness \nc)contrast balance\nd)decomposition-recomposition\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 200..1000)\n66% absciss represents standard deviation of local contrast (real value about 1000..2000)\n100% represents maximum (real value about 5000..13000) +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify the final local contrast at the end of the wavelet treatment.\n\nThe left side represents the smallest local contrast, progressing to the largest local contrast on the right. +!TP_WAVELET_OPACITYW;Contrast balance d/v-h curve +!TP_WAVELET_OPACITY;Opacity Blue-Yellow +!TP_WAVELET_PASTEL;Pastel chromaticity +!TP_WAVELET_PREVIEWBACK;Background +!TP_WAVELET_PREVIEWLEVELS;Preview +!TP_WAVELET_RE1;Reinforced +!TP_WAVELET_RE2;Unchanged +!TP_WAVELET_RE3;Reduced +!TP_WAVELET_RESCHRO;Chromaticity +!TP_WAVELET_RESCONH;Highlights +!TP_WAVELET_RESCON;Shadows +!TP_WAVELET_RESID;Residual image +!TP_WAVELET_SAT;Saturated chromaticity +!TP_WAVELET_SETTINGS;Wavelet Settings +!TP_WAVELET_SKIN;Skin targetting/protection +!TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected. +!TP_WAVELET_SKY;Sky targetting/protection +!TP_WAVELET_SKY_TOOLTIP;At -100 sky-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 sky-tones are protected while all other tones are affected. +!TP_WAVELET_STRENGTH;Strength +!TP_WAVELET_STREN;Strength +!TP_WAVELET_SUPE;Extra +!TP_WAVELET_SUP;Above the level +!TP_WAVELET_THRESHOLD2;Shadow levels +!TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels between 9 and 9 minus the value will be affected by the shadow luminance range. Other levels will be fully treated. The highest level possible is limited by the highlight level value (9 minus highlight level value). +!TP_WAVELET_THRESHOLD;Highlight levels +!TP_WAVELET_THRESHOLD_TOOLTIP;Only levels beyond the chosen value will be affected by the highlight luminance range. Other levels will be fully treated. The chosen value here limits the highest possible value of the shadow levels. +!TP_WAVELET_THRH;Highlights threshold +!TP_WAVELET_THR;Shadows threshold +!TP_WAVELET_TILESBIG;Big tiles +!TP_WAVELET_TILESFULL;Full image +!TP_WAVELET_TILESIZE;Tiling method +!TP_WAVELET_TILESLIT;Little tiles +!TP_WAVELET_TILES_TOOLTIP;Processing the full image leads to better quality and is the recommended option, while using tiles is a fall-back solution for users with little RAM. Refer to RawPedia for memory requirements. +!TP_WAVELET_TMHIGH;High +!TP_WAVELET_TMLOWHIGH;Low+High +!TP_WAVELET_TMNONE;None +!TP_WAVELET_TMSTD;Standard +!TP_WAVELET_TMSTRENGTH;Compression strength +!TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image. When the value is different from 0, the Strength and Gamma sliders of the Tone Mapping tool in the Exposure tab will become grayed out. +!TP_WAVELET_TMTYPE;Compression method +!TP_WAVELET_TON;Toning +!TP_WAVELET_daub2;D2 - low +!TP_WAVELET_daub4;D4 - standard +!TP_WAVELET_daub6;D6 - standard plus +!TP_WAVELET_daub10;D10 - medium +!TP_WAVELET_daub14;D14 - high diff --git a/rtdata/languages/Portugues (Brasil) b/rtdata/languages/Portugues (Brasil) new file mode 100644 index 000000000..e978933ad --- /dev/null +++ b/rtdata/languages/Portugues (Brasil) @@ -0,0 +1,1857 @@ +#01 2010-02-01 Vitor da Silva Gonçalves + +ADJUSTER_RESET_TO_DEFAULT;Restaurar para o padrão +CURVEEDITOR_LINEAR;Linear +CURVEEDITOR_LOADDLGLABEL;Carregar Curva... +CURVEEDITOR_SAVEDLGLABEL;Salvar Curva... +CURVEEDITOR_TOOLTIPLINEAR;Restaurar curva para linha +CURVEEDITOR_TOOLTIPLOAD;Carregar uma Curva a Partir de Arquivo +CURVEEDITOR_TOOLTIPSAVE;Salvar Arquivo Atual +DIRBROWSER_FOLDERS;Folders +EXIFFILTER_APERTURE;Abertura +EXIFFILTER_CAMERA;Câmera +EXIFFILTER_FOCALLEN;Distância Focal +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Lente +EXIFFILTER_SHUTTER;Obturador +EXIFPANEL_ADDEDITHINT;Adicionar nova etiqueta ou editá-la +EXIFPANEL_ADDEDIT;Adicionar/Editar +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Entre um valor +EXIFPANEL_ADDTAGDLG_SELECTTAG;Selecione uma etiqueta +EXIFPANEL_ADDTAGDLG_TITLE;Adicionar/Editar etiqueta +EXIFPANEL_KEEPHINT;Manter as etiquetas selecionadas ao escrever arquivo de saída +EXIFPANEL_KEEP;Manter +EXIFPANEL_REMOVEHINT;Remover as etiquetas selecionadas ao escrever arquivo de saída +EXIFPANEL_REMOVE;Remover +EXIFPANEL_RESETALLHINT;Restaurar todas as etiquetas a seus valores originais +EXIFPANEL_RESETALL;Restaurar Tudo +EXIFPANEL_RESETHINT;Restaurar todas as etiquetas selecionadas a seus valores originais +EXIFPANEL_RESET;Restaurar +EXIFPANEL_SUBDIRECTORY;Subdiretório +FILEBROWSER_APPLYPROFILE;Aplicar Perfil +FILEBROWSER_CLEARPROFILE;Limpar Perfil +FILEBROWSER_COPYPROFILE;Copiar Perfil +FILEBROWSER_DELETEDLGLABEL;Confirmação para Apagar Arquivo +FILEBROWSER_DELETEDLGMSG;Tem certeza de que deseja apagar os %1 arquivos selecionados? +FILEBROWSER_EMPTYTRASHHINT;Remove permanentemente os arquivos da lixeira +FILEBROWSER_EMPTYTRASH;Esvaziar Lixeira +FILEBROWSER_PARTIALPASTEPROFILE;Colar parcialmente +FILEBROWSER_PASTEPROFILE;Colar Perfil +FILEBROWSER_POPUPCANCELJOB;Cancelar trabalho +FILEBROWSER_POPUPMOVEEND;Mover para o fim da fila +FILEBROWSER_POPUPMOVEHEAD;Mover para o início da fila +FILEBROWSER_POPUPOPENINEDITOR;Abrir em Editor de +FILEBROWSER_POPUPOPEN;Abrir +FILEBROWSER_POPUPPROCESS;Colocar na fila de processamento +FILEBROWSER_POPUPREMOVE;Remover do sistema de arquivos +FILEBROWSER_POPUPRENAME;Renomear +FILEBROWSER_POPUPSELECTALL;Selecionar tudo +FILEBROWSER_POPUPTRASH;Mover para a lixeira +FILEBROWSER_POPUPUNRANK;Desclassificar +FILEBROWSER_POPUPUNTRASH;Remover da lixeira +FILEBROWSER_RENAMEDLGLABEL;Renomear arquivo +FILEBROWSER_RENAMEDLGMSG;Renomear arquivo "%1" como: +FILEBROWSER_SHOWDIRHINT;Exibir todas as imagens do diretório +FILEBROWSER_SHOWRANK1HINT;Exibir imagens classificadas como 1 estrela +FILEBROWSER_SHOWRANK2HINT;Exibir imagens classificadas como 2 estrelas +FILEBROWSER_SHOWRANK3HINT;Exibir imagens classificadas como 3 estrelas +FILEBROWSER_SHOWRANK4HINT;Exibir imagens classificadas como 4 estrelas +FILEBROWSER_SHOWRANK5HINT;Exibir imagens classificadas como 5 estrelas +FILEBROWSER_SHOWTRASHHINT;Exibir conteúdo da lixeira +FILEBROWSER_SHOWUNRANKHINT;Exibir imagens não classificadas +FILEBROWSER_STARTPROCESSINGHINT;Iniciar processamento/salvar imagens da lista +FILEBROWSER_STARTPROCESSING;Iniciar Processamento +FILEBROWSER_STOPPROCESSINGHINT;Para o processamento das imagens +FILEBROWSER_STOPPROCESSING;Parar processamento +FILEBROWSER_THUMBSIZE;Tamanho das Miniaturas +FILEBROWSER_ZOOMINHINT;Aumentar Tamanho das Miniaturas +FILEBROWSER_ZOOMOUTHINT;Diminuir Tamanho das Miniaturas +GENERAL_ABOUT;Sobre +GENERAL_CANCEL;Cancelar +GENERAL_DISABLED;Desabilitado +GENERAL_DISABLE;Desabilitar +GENERAL_ENABLED;Habilitado +GENERAL_ENABLE;Habilitar +GENERAL_LANDSCAPE;Paisagem +GENERAL_NA;n/a +GENERAL_NO;Não +GENERAL_OK;OK +GENERAL_PORTRAIT;Retrato +GENERAL_SAVE;Salvar +HISTOGRAM_TOOLTIP_B;Mostrar/Esconder histograma AZUL +HISTOGRAM_TOOLTIP_G;Mostrar/Esconder histograma VERDE +HISTOGRAM_TOOLTIP_L;Mostrar/Esconder histograma CIELAB +HISTOGRAM_TOOLTIP_R;Mostrar/Esconder histograma VERMELHO +HISTORY_CHANGED;Alterado +HISTORY_CUSTOMCURVE;Curva personalizada +HISTORY_DELSNAPSHOT;Apagar +HISTORY_FROMCLIPBOARD;Da área de transferência +HISTORY_LABEL;Histórico +HISTORY_MSG_1;Foto carregada +HISTORY_MSG_2;Perfil Carregado +HISTORY_MSG_3;Perfil Alterado +HISTORY_MSG_4;Navegador do histórico +HISTORY_MSG_5;Brilho +HISTORY_MSG_6;Contraste +HISTORY_MSG_7;Preto +HISTORY_MSG_8;Compensação de Exposição +HISTORY_MSG_9;Compressão da Luz +HISTORY_MSG_10;Compressão de Sombras +HISTORY_MSG_11;Curva de Tons +HISTORY_MSG_12;Exposição Automática +HISTORY_MSG_13;Clipping de Exposição +HISTORY_MSG_14;Brilho de Luminância +HISTORY_MSG_15;Contraste de Luminância +HISTORY_MSG_16;Luminância do Preto +HISTORY_MSG_17;Compressão do Foco de Luminância +HISTORY_MSG_18;Compressão das sombras de Luminância +HISTORY_MSG_19;Curva de Luminância +HISTORY_MSG_20;Tornar Nítido +HISTORY_MSG_21;Raio de Nitidez +HISTORY_MSG_22;Quantidade de Nitidez +HISTORY_MSG_23;Limiar de Nitidez +HISTORY_MSG_24;Tornar nítido apenas as bordas +HISTORY_MSG_25;Raio de Detecção de Bordas de Nitidez +HISTORY_MSG_26;Tolerância da nitidez das bordas +HISTORY_MSG_27;Controle de luz na nitidez +HISTORY_MSG_28;Quantidade do Controle de Luz +HISTORY_MSG_29;Método de Nitidez +HISTORY_MSG_30;Raio de Desconvolução +HISTORY_MSG_31;Quantidade de Desconvolução +HISTORY_MSG_32;Umedecimento de Desconvolução +HISTORY_MSG_33;Interações de Desconvolução +HISTORY_MSG_34;Evitar Clipping de Cor +HISTORY_MSG_35;Limitador de Saturação +HISTORY_MSG_36;limite de Saturação +HISTORY_MSG_37;Melhoria de Cor +HISTORY_MSG_38;Método do Balanço do Branco +HISTORY_MSG_39;Temperatura de Cor +HISTORY_MSG_40;Tonalidade do Balanço de Branco +HISTORY_MSG_41;Deslocamento da Cor "A" +HISTORY_MSG_42;Deslocamento da Cor "B" +HISTORY_MSG_43;Remoção de ruídos da luminância +HISTORY_MSG_44;Raio da remoção de ruídos da lum. +HISTORY_MSG_45;Tolerância de bordas da remoção de ruídos da lum. +HISTORY_MSG_46;Remoção de ruídos da cor +HISTORY_MSG_47;Raio da remoção de ruídos da cor +HISTORY_MSG_48;Tolerância de bordas da remoção de ruídos da cor +HISTORY_MSG_49;Remoção de ruidos da cor sensível a bordas +HISTORY_MSG_50;Ferramenta Sombra/Luz +HISTORY_MSG_51;Melhora de luz +HISTORY_MSG_52;Melhora de Sombras +HISTORY_MSG_53;Largura de Tons da Luz +HISTORY_MSG_54;Largura de Tons das Sombras +HISTORY_MSG_55;Contraste Local +HISTORY_MSG_56;Raio de Luz/Sombra +HISTORY_MSG_57;Coarse Rotation +HISTORY_MSG_58;Inversão Horizontal +HISTORY_MSG_59;Inversão Vertical +HISTORY_MSG_60;Rotação +HISTORY_MSG_61;Rotação +HISTORY_MSG_62;Correção de Distorção de Lente +HISTORY_MSG_63;Snapshot Selecionado +HISTORY_MSG_64;Cortar Foto +HISTORY_MSG_65;Correção de C/A +HISTORY_MSG_66;Recuperação de Luz +HISTORY_MSG_67;Quantidade de Recuperação +HISTORY_MSG_68;Método de Recuperação +HISTORY_MSG_69;Espaço de atuação da cor +HISTORY_MSG_70;Espaço de Cor de Saída +HISTORY_MSG_71;Espaço de Cor de Entrada +HISTORY_MSG_72;Correção de Vinheta +HISTORY_MSG_73;Misturador de Canais +HISTORY_MSG_74;Escala de Redimensionamento +HISTORY_MSG_75;Método de Redimensionamento +HISTORY_MSG_76;Metadados Exif +HISTORY_MSG_77;Metadados IPTC +HISTORY_MSG_78;Dados especificados para redimensionamento +HISTORY_MSG_79;Largura do redimensionamento +HISTORY_MSG_80;Altura do redimensionamento +HISTORY_MSG_81;Redimensionamento habilitado +HISTORY_NEWSNAPSHOT;Adicionar +HISTORY_SNAPSHOTS;Snapshots +HISTORY_SNAPSHOT;Snapshot +IPTCPANEL_AUTHORSPOSITIONHINT;Título do criador ou criadores do objeto. +IPTCPANEL_AUTHORSPOSITION;Posição do autor +IPTCPANEL_AUTHOR;Autor +IPTCPANEL_CAPTIONHINT;Uma descrição dos dados em forma de texto. +IPTCPANEL_CAPTIONWRITERHINT;o nome da pessoa envolvida na escrita, edição ou correção da imagem ou legenda/resumo. +IPTCPANEL_CAPTIONWRITER;Autor da Legenda +IPTCPANEL_CAPTION;Legenda +IPTCPANEL_CATEGORYHINT;Identifica o assunto da imagem (Categoria). +IPTCPANEL_CATEGORY;Categoria +IPTCPANEL_CITYHINT;Cidade de origem da imagem. +IPTCPANEL_CITY;Cidade +IPTCPANEL_COPYHINT;Copiar configurações IPTC da área de transferência +IPTCPANEL_COPYRIGHTHINT;qualquer informação necessário sobre os direitos autorais. +IPTCPANEL_COPYRIGHT;Direios autorais (Copyright). +IPTCPANEL_COUNTRYHINT;O nome do país onde a imagem foi criada. +IPTCPANEL_COUNTRY;País +IPTCPANEL_CREDITHINT;Identifica o provedor da imagem, nçao necessariamente o proprietário/criador. +IPTCPANEL_CREDIT;Créditos +IPTCPANEL_DATECREATEDHINT;A data em que o conteúdo intelectual da imagem foi criado; Formato: AAAAMMDD. +IPTCPANEL_DATECREATED;Data de criação +IPTCPANEL_EMBEDDEDHINT;Restaura para IPTC os dados encaixados na imagem +IPTCPANEL_EMBEDDED;Embedded +IPTCPANEL_HEADLINEHINT;Uma entrada publicável que com uma sinopse dos conteúdos da imagem. +IPTCPANEL_HEADLINE;Título +IPTCPANEL_INSTRUCTIONSHINT;Outras instruções editorias sobre o uso da imagem. +IPTCPANEL_INSTRUCTIONS;Instruções +IPTCPANEL_KEYWORDSHINT;Utilizado para indicar informações especificas. +IPTCPANEL_KEYWORDS;Palavras-chave +IPTCPANEL_PASTEHINT;colar configurações IPTC da área de transferência +IPTCPANEL_PROVINCEHINT;o Estado/província de origem da imagem. +IPTCPANEL_PROVINCE;Província +IPTCPANEL_RESETHINT;Restaurar paara o padrão do perfil +IPTCPANEL_RESET;Restaurar +IPTCPANEL_SOURCEHINT;o proprietário original do contepudo intelectual da imagem. +IPTCPANEL_SOURCE;Fonte +IPTCPANEL_SUPPCATEGORIESHINT;Mais informações sobre o assunto da imagem. +IPTCPANEL_SUPPCATEGORIES; Categorias Adicionais +IPTCPANEL_TITLEHINT;Uma referência rápida da imagem. +IPTCPANEL_TITLE;Título +IPTCPANEL_TRANSREFERENCEHINT;Um código representando a localização da transmissão original. +IPTCPANEL_TRANSREFERENCE;Trans. Referência +MAIN_BUTTON_PREFERENCES;Preferências +MAIN_BUTTON_SAVE;Salvar Imagem +MAIN_BUTTON_SENDTOEDITOR;Enviar ao Editor +MAIN_FRAME_BATCHQUEUE;Batch Queue +MAIN_FRAME_FILEBROWSER;File Browser +MAIN_FRAME_PLACES;Places +MAIN_FRAME_PLACES_ADD;Add +MAIN_FRAME_PLACES_DEL;Del +MAIN_FRAME_RECENT;Recent Folders +MAIN_MSG_ALREADYEXISTS;Arquivo Já Existe. +MAIN_MSG_CANNOTLOAD;Não foi possível carregar a imagem +MAIN_MSG_CANNOTSAVE;Erro ao salvar arquivo +MAIN_MSG_CANNOTSTARTEDITOR;Não foi possível iniciar o editor. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;por favor ajuste corretamente o caminho no diálogo "Preferências". +MAIN_MSG_QOVERWRITE;Deseja sobreescrever? +MAIN_TAB_COLOR;Cor +MAIN_TAB_DETAIL;Detalhes +MAIN_TAB_DEVELOP;Develop +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;Exposição +MAIN_TAB_FILTER;Filter +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadados +MAIN_TAB_TRANSFORM;Transformar +MAIN_TOOLTIP_HIDEHP;Mostrar/esconder o painel à esquerda (incluindo o histórico, tecla de atallho: H) +MAIN_TOOLTIP_INDCLIPPEDH;Indicação de luz recortada +MAIN_TOOLTIP_INDCLIPPEDS;Indicação de sombra recortada +MAIN_TOOLTIP_QINFO;Informações rápidas da imagem +PARTIALPASTE_BASICGROUP;Configurações básicas +PARTIALPASTE_CACORRECTION;Correção C/A +PARTIALPASTE_COARSETRANS;Rotação de 90 graus +PARTIALPASTE_COLORGROUP;Configurações relacionadas à cor +PARTIALPASTE_COMPOSITIONGROUP;Configurações de composição +PARTIALPASTE_CROP;Cortar +PARTIALPASTE_DIALOGLABEL;Perfil de processamento de colagem parcial +PARTIALPASTE_DISTORTION;Correção de Distorção +PARTIALPASTE_EXIFCHANGES;alterações dos dados exif +PARTIALPASTE_EXPOSURE;Exposição +PARTIALPASTE_ICMSETTINGS;Configurações ICM +PARTIALPASTE_IPTCINFO;informações IPTC +PARTIALPASTE_LENSGROUP;Configurações relacionadas à Lente +PARTIALPASTE_METAGROUP;Metadados +PARTIALPASTE_RESIZE;Redimensionar +PARTIALPASTE_ROTATION;Rotação +PARTIALPASTE_SHADOWSHIGHLIGHTS;Sombra/Luz +PARTIALPASTE_SHARPENING;Nitidez +PARTIALPASTE_VIGNETTING;Correção de vinheta +PARTIALPASTE_WHITEBALANCE;Balanço do branco +PREFERENCES_APPLNEXTSTARTUP;Aplicadas na próxima inicialização +PREFERENCES_CACHECLEARALL;Limpar Tudo +PREFERENCES_CACHECLEARPROFILES;Limpar perfis +PREFERENCES_CACHECLEARTHUMBS;Limpar Miniaturas +PREFERENCES_CACHEMAXENTRIES;Número máximo de entradas no cache +PREFERENCES_CACHEOPTS;Opções de Cache +PREFERENCES_CACHETHUMBHEIGHT;Tamanho máximo das miniaturas +PREFERENCES_CLIPPINGIND;Recortando indicação +PREFERENCES_CMETRICINTENT;Intenção colorimétrica +PREFERENCES_DATEFORMATHINT;Você pode usar as seguintes formatações:\n%a : ano\n%m : mês\n%d : dia\n\nPor exemplo, o formato de data húngaro é:\n%a/%m/%d +PREFERENCES_DATEFORMAT;Formato de data +PREFERENCES_DEFAULTLANG;Idioma padrão +PREFERENCES_DEFAULTTHEME;Tema padrão +PREFERENCES_DIRHOME;Directory inicial +PREFERENCES_DIRLAST;Último directory visitado +PREFERENCES_DIROTHER;Outro +PREFERENCES_DIRSELECTDLG;selecionar diretório de imagem na inicialização... +PREFERENCES_DIRSOFTWARE;Diretório de instalação +PREFERENCES_EDITORCMDLINE;Outra Linha de Comando +PREFERENCES_EXTERNALEDITOR;Editor externo +PREFERENCES_FBROWSEROPTS;Opções do navegador de arquivos +PREFERENCES_FILEFORMAT;Formato de arquivo +PREFERENCES_FORIMAGE;Para arquivos de imagem +PREFERENCES_FORRAW;Para arquivos RAW +PREFERENCES_GIMPPATH;Diretório de Instalação do GIMP +PREFERENCES_HLTHRESHOLD;ponto inicial para luzes recortadas +PREFERENCES_ICCDIR;Diretório de perfis ICC +PREFERENCES_IMPROCPARAMS;Parâmetros padrões de processamento de imagem +PREFERENCES_INTENT_ABSOLUTE;Colorimétrico Absoluto +PREFERENCES_INTENT_PERCEPTUAL;Perceptual +PREFERENCES_INTENT_RELATIVE;Colorimétrico Relativo +PREFERENCES_INTENT_SATURATION;Saturação +PREFERENCES_MONITORICC;Monitorar perfil +PREFERENCES_OUTDIRFOLDERHINT;Colocar as imagens salvas na pasta selecionada +PREFERENCES_OUTDIRFOLDER;Salvar em folder +PREFERENCES_OUTDIRTEMPLATEHINT;Você pode utilizar a seguinte formatação:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nEsta formatação se refere aos diretórios e subdiretórios do caminho do arquivo raw.\n\npor exemplo, se /home/tom/image/02-09-2006/dsc0012.neffoi aberto, significa que a formatação é:\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\nSe você deseja salvar a imagem de saída onde está a original, escreva:\n%p1/%f\n\nSe você deseja salvar a imagem de saída em um diretório 'convertido' localizado no mesmo diretório que a original, escreva:\n%p1/converted/%f\n\nSe você deseja salvar a imagem de saída no diretório '/home/tom/converted' mantendo o mesmo subdiretório de datas, escreva:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Usar Template +PREFERENCES_OUTDIR;Diretório de Saída +PREFERENCES_PARSEDEXTADDHINT;escreva uma extensão e pressione este botão para adicionar à lista +PREFERENCES_PARSEDEXTADD;Adicionar Extensão +PREFERENCES_PARSEDEXTDELHINT;Apagar extensão selecionada da lista +PREFERENCES_PARSEDEXT;Extensões analisadas gramaticalmente +PREFERENCES_PROFILEHANDLING;Manipulação de processamento de perfil +PREFERENCES_PROFILELOADPR;Prioridade de carregamento de perfil +PREFERENCES_PROFILEPRCACHE;Perfil no Cache +PREFERENCES_PROFILEPRFILE;Perfil próximo ao arquivo de entrada +PREFERENCES_PROFILESAVECACHE;Salvar parâmetros de processamento no cache +PREFERENCES_PROFILESAVEINPUT;Salvar parâmetros de processamento próximo ao arquivo de entrada +PREFERENCES_PSPATH;Diretório de instalação do Adobe Photoshop +PREFERENCES_SELECTLANG;Selecionar idioma +PREFERENCES_SELECTTHEME;Selecionar tema +PREFERENCES_SHOWBASICEXIF;Mostrar informações Exif básicas +PREFERENCES_SHOWDATETIME;Mostrar data e hora +PREFERENCES_SHTHRESHOLD;Limiar para sombras recortadas +PREFERENCES_STARTUPIMDIR;Diretório de Imagens ao Iniciar +PREFERENCES_TAB_BROWSER;Navegador de Arquivos +PREFERENCES_TAB_COLORMGR;Gerenciamento de Cores +PREFERENCES_TAB_GENERAL;Geral +PREFERENCES_TAB_IMPROC;Processamento de Imagem +PROFILEPANEL_LABEL;Perfis de pós-processamento +PROFILEPANEL_LOADDLGLABEL;Carregar parâmetros de pós-processamento... +PROFILEPANEL_PCUSTOM;Personalizado +PROFILEPANEL_PFILE;do Arquivo +PROFILEPANEL_PLASTSAVED;Último Salvo +PROFILEPANEL_SAVEDLGLABEL;Save parâmetros de pós-processamento... +PROFILEPANEL_TOOLTIPCOPY;Copiar perfil atual para a área de transferência +PROFILEPANEL_TOOLTIPLOAD;carregar perfil a partir de um arquivo +PROFILEPANEL_TOOLTIPPASTE; Colar perfil da área de transferência +PROFILEPANEL_TOOLTIPSAVE;Salvar perfil atual +PROGRESSBAR_LOADING;Carregando Imagem... +PROGRESSBAR_LOADJPEG;Carregando arquivo JPEG... +PROGRESSBAR_LOADPNG;Carregando arquivo PNG... +PROGRESSBAR_LOADTIFF;Carregando arquivo TIFF... +PROGRESSBAR_PROCESSING;Processando imagem... +PROGRESSBAR_READY;Pronto +PROGRESSBAR_SAVEJPEG;Salvando Arquivo JPEG... +PROGRESSBAR_SAVEPNG;Salvando Arquivo PNG... +PROGRESSBAR_SAVETIFF;Salvando Arquivo TIFF... +QINFO_ISO;ISO +QINFO_NOEXIF;Dados Exif não disponíveis. +SAVEDLG_FILEFORMAT;Formato do Arquivo +SAVEDLG_JPEGQUAL;Qualidade do JPEG +SAVEDLG_PNGCOMPR;Compressão PNG +SAVEDLG_PUTTOQUEUEHEAD;Colocar no topo da fila de processamento +SAVEDLG_PUTTOQUEUETAIL;Colocar no final da fila de processamento +SAVEDLG_PUTTOQUEUE;Colocar na fila de processamento +SAVEDLG_SAVEIMMEDIATELY;Salvar Imediatamente +SAVEDLG_SAVESPP;Salvar parâmetros de processamento com a imagem +TOOLBAR_TOOLTIP_CROP;Seleção de Corte (Tecla de Atalho: C) +TOOLBAR_TOOLTIP_HAND;Ferramenta Mão (Tecla de Atalho: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;Seleção de linha reta (Tecla de atalho: S) +TOOLBAR_TOOLTIP_WB;Balanço de branco em área (Tecla de atalho: W) +TP_CACORRECTION_BLUE;Azul +TP_CACORRECTION_LABEL;Correção C/A +TP_CACORRECTION_RED;Vermelho +TP_CHMIXER_BLUE;Azul +TP_CHMIXER_GREEN;Verde +TP_CHMIXER_LABEL;Misturador de Canais +TP_CHMIXER_RED;Vermelho +TP_COARSETRAF_TOOLTIP_HFLIP;Inverter horizontalmente +TP_COARSETRAF_TOOLTIP_ROTLEFT;Rotacionar à esquerda +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Rotacionar à direita +TP_COARSETRAF_TOOLTIP_VFLIP;Inverter verticalmente +TP_CROP_FIXRATIO;Relação Fixa: +TP_CROP_GTDIAGONALS;Regra das diagonais +TP_CROP_GTNONE;Nenhum +TP_CROP_GTRULETHIRDS;Regra de Terceiros +TP_CROP_GUIDETYPE;Tipo de guia: +TP_CROP_H;H +TP_CROP_LABEL;Cortar +TP_CROP_SELECTCROP; Selecione o Corte +TP_CROP_W;W +TP_CROP_X;x +TP_CROP_Y;y +TP_DISTORTION_AMOUNT;Quantidade +TP_DISTORTION_LABEL;Distorção +TP_EXPOSURE_AUTOLEVELS;Níveis Automáticos +TP_EXPOSURE_BLACKLEVEL;Preto +TP_EXPOSURE_BRIGHTNESS;Brilho +TP_EXPOSURE_CLIP;Clip +TP_EXPOSURE_COMPRHIGHLIGHTS;Compressão de Luz +TP_EXPOSURE_COMPRSHADOWS;Compressão de Sombras +TP_EXPOSURE_CONTRAST;Contraste +TP_EXPOSURE_CURVEEDITOR;Curva de Tons +TP_EXPOSURE_EXPCOMP;Exp. Comp. +TP_EXPOSURE_LABEL;Exposição +TP_HLREC_CIELAB;Mistura CIELab +TP_HLREC_COLOR;Propagação de Cores +TP_HLREC_LABEL;Recuperação de Luz +TP_HLREC_LUMINANCE;Recuperação de Luminância +TP_HLREC_METHOD;Método: +TP_ICM_INPUTCAMERA;Padrão de Câmera +TP_ICM_INPUTCUSTOM;Personalizado +TP_ICM_INPUTDLGLABEL;Selecione perfil de entrada ICC... +TP_ICM_INPUTEMBEDDED;Use Embedded, se possível +TP_ICM_INPUTPROFILE;Perfil de entrada +TP_ICM_LABEL;ICM +TP_ICM_NOICM;Sem ICM: Saída sRGB +TP_ICM_OUTPUTPROFILE;Perfil de Saída +TP_ICM_SAVEREFERENCE;Salvar imagem de referência para perfis +TP_ICM_WORKINGPROFILE;Perfil Utilizado +TP_RAW_DMETHOD;Método +TP_RAW_FALSECOLOR;Supressão de cor falsa +TP_RESIZE_H;H: +TP_RESIZE_LABEL;Redimensionar +TP_RESIZE_METHOD;Método: +TP_RESIZE_NEAREST;Mais Próximo +TP_RESIZE_SCALE;Escala +TP_RESIZE_W;W: +TP_ROTATE_DEGREE;Graus +TP_ROTATE_LABEL;Rotacionar +TP_ROTATE_SELECTLINE; Selecionar Linha Reta +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Luzes +TP_SHADOWSHLIGHTS_HLTONALW;Largura de Tons +TP_SHADOWSHLIGHTS_LABEL;Sombras/Luzes +TP_SHADOWSHLIGHTS_LOCALCONTR;Contraste Local +TP_SHADOWSHLIGHTS_RADIUS;Raio +TP_SHADOWSHLIGHTS_SHADOWS;Sombras +TP_SHADOWSHLIGHTS_SHTONALW;largura de tons +TP_SHARPENING_AMOUNT;Quantidade +TP_SHARPENING_EDRADIUS;Raio +TP_SHARPENING_EDTOLERANCE;Tolerância de bordas +TP_SHARPENING_HALOCONTROL;Controle de luz +TP_SHARPENING_HCAMOUNT;Quantidade +TP_SHARPENING_LABEL;Nitidez +TP_SHARPENING_METHOD;Método +TP_SHARPENING_ONLYEDGES;tornar nítido somente as bordas +TP_SHARPENING_RADIUS;Raio +TP_SHARPENING_RLD;RL Desconvolução +TP_SHARPENING_RLD_AMOUNT;Quantidade +TP_SHARPENING_RLD_DAMPING;Umedecimento +TP_SHARPENING_RLD_ITERATIONS;Iterações +TP_SHARPENING_THRESHOLD;Limiar +TP_SHARPENING_USM;Máscara de Nitidez +TP_VIGNETTING_AMOUNT;Quantidade +TP_VIGNETTING_LABEL;Correção de vinheta +TP_VIGNETTING_RADIUS;Raio +TP_WBALANCE_AUTO;Auto +TP_WBALANCE_CAMERA;Câmera +TP_WBALANCE_CUSTOM;Personalizado +TP_WBALANCE_GREEN;Tonalidade +TP_WBALANCE_LABEL;Balanço do Branco +TP_WBALANCE_METHOD;Método +TP_WBALANCE_SIZE;Tamanho: +TP_WBALANCE_SPOTWB;Balanço de Branco de área +TP_WBALANCE_TEMPERATURE;Temperatura +# + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!ABOUT_TAB_BUILD;Version +!ABOUT_TAB_CREDITS;Credits +!ABOUT_TAB_LICENSE;License +!ABOUT_TAB_RELEASENOTES;Release Notes +!ABOUT_TAB_SPLASH;Splash +!BATCHQUEUE_AUTOSTART;Auto-start +!BATCHQUEUE_DESTFILENAME;Path and file name +!BATCH_PROCESSING;Batch Processing +!CURVEEDITOR_AXIS_IN;I: +!CURVEEDITOR_AXIS_LEFT_TAN;LT: +!CURVEEDITOR_AXIS_OUT;O: +!CURVEEDITOR_AXIS_RIGHT_TAN;RT: +!CURVEEDITOR_CURVES;Curves +!CURVEEDITOR_CURVE;Curve +!CURVEEDITOR_CUSTOM;Custom +!CURVEEDITOR_DARKS;Darks +!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_HIGHLIGHTS;Highlights +!CURVEEDITOR_LIGHTS;Lights +!CURVEEDITOR_MINMAXCPOINTS;Equalizer +!CURVEEDITOR_NURBS;Control cage +!CURVEEDITOR_PARAMETRIC;Parametric +!CURVEEDITOR_SHADOWS;Shadows +!CURVEEDITOR_TOOLTIPCOPY;Copy current curve to clipboard. +!CURVEEDITOR_TOOLTIPPASTE;Paste curve from clipboard. +!CURVEEDITOR_TYPE;Type: +!EDITWINDOW_TITLE;Image Edit +!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_FILETYPE;File type +!EXIFFILTER_METADATAFILTER;Enable metadata filters +!EXPORT_BYPASS_ALL;Select / Unselect All +!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_FF;Bypass [raw] Flat-Field +!EXPORT_BYPASS_RAW_GREENTHRESH;Bypass [raw] Green Equilibration +!EXPORT_BYPASS_RAW_LINENOISE;Bypass [raw] Line Noise Filter +!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_FASTEXPORTOPTIONS;Fast Export Options +!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_MAXHEIGHT;Maximum height: +!EXPORT_MAXWIDTH;Maximum width: +!EXPORT_PUTTOQUEUEFAST; Put to queue for fast export +!EXPORT_RAW_DMETHOD;Demosaic method +!EXTPROGTARGET_1;raw +!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_CACHECLEARFROMFULL;Clear from cache - full +!FILEBROWSER_CACHECLEARFROMPARTIAL;Clear from cache - partial +!FILEBROWSER_CACHE;Cache +!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_CURRENT_NAME;Current name: +!FILEBROWSER_DARKFRAME;Dark-frame +!FILEBROWSER_DELETEDLGMSGINCLPROC;Are you sure you want to delete the selected %1 files including a queue-processed version? +!FILEBROWSER_EXEC_CPB;Custom Profile Builder +!FILEBROWSER_EXTPROGMENU;Open with +!FILEBROWSER_FLATFIELD;Flat-Field +!FILEBROWSER_MOVETODARKFDIR;Move to dark-frames directory +!FILEBROWSER_MOVETOFLATFIELDDIR;Move to flat-fields directory +!FILEBROWSER_NEW_NAME;New name: +!FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) +!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_POPUPCOLORLABEL;Color label +!FILEBROWSER_POPUPCOPYTO;Copy to... +!FILEBROWSER_POPUPFILEOPERATIONS;File operations +!FILEBROWSER_POPUPMOVETO;Move to... +!FILEBROWSER_POPUPPROCESSFAST;Put to queue (Fast export) +!FILEBROWSER_POPUPPROFILEOPERATIONS;Processing profile operations +!FILEBROWSER_POPUPRANK0;Unrank +!FILEBROWSER_POPUPRANK1;Rank 1 * +!FILEBROWSER_POPUPRANK2;Rank 2 ** +!FILEBROWSER_POPUPRANK3;Rank 3 *** +!FILEBROWSER_POPUPRANK4;Rank 4 **** +!FILEBROWSER_POPUPRANK5;Rank 5 ***** +!FILEBROWSER_POPUPRANK;Rank +!FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!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_QUERYLABEL; Find: +!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_SELECTDARKFRAME;Select dark-frame... +!FILEBROWSER_SELECTFLATFIELD;Select flat-field... +!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 +!FILEBROWSER_SHOWCOLORLABEL4HINT;Show images labeled Blue.\nShortcut: Alt-4 +!FILEBROWSER_SHOWCOLORLABEL5HINT;Show images labeled Purple.\nShortcut: Alt-5 +!FILEBROWSER_SHOWEDITEDHINT;Show edited images.\nShortcut: 7 +!FILEBROWSER_SHOWEDITEDNOTHINT;Show not edited images.\nShortcut: 6 +!FILEBROWSER_SHOWEXIFINFO;Show Exif info.\n\nShortcuts:\ni - Multiple Editor Tabs Mode,\nAlt-i - Single Editor Tab Mode. +!FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!FILEBROWSER_SHOWRECENTLYSAVEDHINT;Show saved images.\nShortcut: Alt-7 +!FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show unsaved images.\nShortcut: Alt-6 +!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_AFTER;After +!GENERAL_ASIMAGE;As Image +!GENERAL_AUTO;Automatic +!GENERAL_BEFORE;Before +!GENERAL_CLOSE;Close +!GENERAL_FILE;File +!GENERAL_NONE;None +!GENERAL_UNCHANGED;(Unchanged) +!GENERAL_WARNING;Warning +!HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar.\nRight-click on image preview to freeze/unfreeze. +!HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram. +!HISTOGRAM_TOOLTIP_FULL;Toggle full (off) or scaled (on) histogram. +!HISTOGRAM_TOOLTIP_RAW;Show/Hide raw histogram. +!HISTORY_MSG_82;Profile changed +!HISTORY_MSG_83;S/H - Sharp mask +!HISTORY_MSG_84;Perspective correction +!HISTORY_MSG_85;LCP +!HISTORY_MSG_86;RGB curves - Luminosity mode +!HISTORY_MSG_87;Impulse noise reduction +!HISTORY_MSG_88;Impulse NR threshold +!HISTORY_MSG_89;Noise Reduction +!HISTORY_MSG_90;NR - Luminance +!HISTORY_MSG_91;NR - Chrominance master +!HISTORY_MSG_92;NR - Gamma +!HISTORY_MSG_93;CbDL - Value +!HISTORY_MSG_94;Contrast by Detail Levels +!HISTORY_MSG_95;L*a*b* - Chromaticity +!HISTORY_MSG_96;L*a*b* - a* curve +!HISTORY_MSG_97;L*a*b* - b* curve +!HISTORY_MSG_98;Demosaicing method +!HISTORY_MSG_99;Hot pixel filter +!HISTORY_MSG_100;RGB Saturation +!HISTORY_MSG_101;HSV - Hue +!HISTORY_MSG_102;HSV - Saturation +!HISTORY_MSG_103;HSV - Value +!HISTORY_MSG_104;HSV Equalizer +!HISTORY_MSG_105;Defringe +!HISTORY_MSG_106;Defringe - Radius +!HISTORY_MSG_107;Defringe - Threshold +!HISTORY_MSG_108;Highlight Compr. Threshold +!HISTORY_MSG_109;Resize - Bounding box +!HISTORY_MSG_110;Resize - Applies to +!HISTORY_MSG_111;L*a*b* - Avoid color shift +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;L*a*b* - Red/skin prot. +!HISTORY_MSG_114;DCB iterations +!HISTORY_MSG_115;False color suppression +!HISTORY_MSG_116;DCB enhancement +!HISTORY_MSG_117;Raw CA correction - Red +!HISTORY_MSG_118;Raw CA correction - Blue +!HISTORY_MSG_119;Line noise filter +!HISTORY_MSG_120;Green equilibration +!HISTORY_MSG_121;Raw CA Correction - Auto +!HISTORY_MSG_122;Dark-Frame - Auto-selection +!HISTORY_MSG_123;Dark-Frame - File +!HISTORY_MSG_124;White point correction +!HISTORY_MSG_125;Highlight preservation +!HISTORY_MSG_126;Flat-Field - File +!HISTORY_MSG_127;Flat-Field - Auto-selection +!HISTORY_MSG_128;Flat-Field - Blur radius +!HISTORY_MSG_129;Flat-Field - Blur type +!HISTORY_MSG_130;Auto distorion correction +!HISTORY_MSG_131;NR - Luma +!HISTORY_MSG_132;NR - Chroma +!HISTORY_MSG_133;Output gamma +!HISTORY_MSG_134;Free gamma +!HISTORY_MSG_135;Free gamma +!HISTORY_MSG_136;Free gamma slope +!HISTORY_MSG_137;Black level - Green 1 +!HISTORY_MSG_138;Black level - Red +!HISTORY_MSG_139;Black level - Blue +!HISTORY_MSG_140;Black level - Green 2 +!HISTORY_MSG_141;Black level - Link greens +!HISTORY_MSG_142;ES - Iterations +!HISTORY_MSG_143;ES - Quantity +!HISTORY_MSG_144;Microcontrast - Quantity +!HISTORY_MSG_145;Microcontrast - Uniformity +!HISTORY_MSG_146;Edge sharpening +!HISTORY_MSG_147;ES - Luminance only +!HISTORY_MSG_148;Microcontrast +!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_150;Post-demosaic artifact/noise red. +!HISTORY_MSG_151;Vibrance +!HISTORY_MSG_152;Vib - Pastel tones +!HISTORY_MSG_153;Vib - Saturated tones +!HISTORY_MSG_154;Vib - Protect skin-tones +!HISTORY_MSG_155;Vib - Avoid color shift +!HISTORY_MSG_156;Vib - Link pastel/saturated +!HISTORY_MSG_157;Vib - P/S threshold +!HISTORY_MSG_158;TM - Strength +!HISTORY_MSG_159;TM - Edge stopping +!HISTORY_MSG_160;TM - Scale +!HISTORY_MSG_161;TM - Reweighting iterates +!HISTORY_MSG_162;Tone Mapping +!HISTORY_MSG_163;RGB curves - Red +!HISTORY_MSG_164;RGB curves - Green +!HISTORY_MSG_165;RGB curves - Blue +!HISTORY_MSG_166;Neutral levels +!HISTORY_MSG_167;--unused-- +!HISTORY_MSG_168;L*a*b* - CC curve +!HISTORY_MSG_169;L*a*b* - CH curve +!HISTORY_MSG_170;Vibrance - HH curve +!HISTORY_MSG_171;L*a*b* - LC curve +!HISTORY_MSG_172;L*a*b* - Restrict LC +!HISTORY_MSG_173;NR - Luminance detail +!HISTORY_MSG_174;CIECAM02 +!HISTORY_MSG_175;CAM02 - CAT02 adaptation +!HISTORY_MSG_176;CAM02 - Viewing surround +!HISTORY_MSG_177;CAM02 - Scene luminosity +!HISTORY_MSG_178;CAM02 - Viewing luminosity +!HISTORY_MSG_179;CAM02 - White-point model +!HISTORY_MSG_180;CAM02 - Lightness (J) +!HISTORY_MSG_181;CAM02 - Chroma (C) +!HISTORY_MSG_182;CAM02 - Automatic CAT02 +!HISTORY_MSG_183;CAM02 - Contrast (J) +!HISTORY_MSG_184;CAM02 - Scene surround +!HISTORY_MSG_185;CAM02 - Gamut control +!HISTORY_MSG_186;CAM02 - Algorithm +!HISTORY_MSG_187;CAM02 - Red/skin prot. +!HISTORY_MSG_188;CAM02 - Brightness (Q) +!HISTORY_MSG_189;CAM02 - Contrast (Q) +!HISTORY_MSG_190;CAM02 - Saturation (S) +!HISTORY_MSG_191;CAM02 - Colorfulness (M) +!HISTORY_MSG_192;CAM02 - Hue (h) +!HISTORY_MSG_193;CAM02 - Tone curve 1 +!HISTORY_MSG_194;CAM02 - Tone curve 2 +!HISTORY_MSG_195;CAM02 - Tone curve 1 +!HISTORY_MSG_196;CAM02 - Tone curve 2 +!HISTORY_MSG_197;CAM02 - Color curve +!HISTORY_MSG_198;CAM02 - Color curve +!HISTORY_MSG_199;CAM02 - Output histograms +!HISTORY_MSG_200;CAM02 - Tone mapping +!HISTORY_MSG_201;NR - Chrominance - R&G +!HISTORY_MSG_202;NR - Chrominance - B&Y +!HISTORY_MSG_203;NR - Method +!HISTORY_MSG_204;LMMSE enhancement steps +!HISTORY_MSG_205;CAM02 - Hot/bad pixel filter +!HISTORY_MSG_206;CAT02 - Auto scene luminosity +!HISTORY_MSG_207;Defringe - Hue curve +!HISTORY_MSG_208;WB - B/R equalizer +!HISTORY_MSG_210;GF - Angle +!HISTORY_MSG_211;Graduated Filter +!HISTORY_MSG_212;VF - Strength +!HISTORY_MSG_213;Vignette Filter +!HISTORY_MSG_214;Black-and-White +!HISTORY_MSG_215;B&W - CM - Red +!HISTORY_MSG_216;B&W - CM - Green +!HISTORY_MSG_217;B&W - CM - Blue +!HISTORY_MSG_218;B&W - Gamma - Red +!HISTORY_MSG_219;B&W - Gamma - Green +!HISTORY_MSG_220;B&W - Gamma - Blue +!HISTORY_MSG_221;B&W - Color filter +!HISTORY_MSG_222;B&W - Presets +!HISTORY_MSG_223;B&W - CM - Orange +!HISTORY_MSG_224;B&W - CM - Yellow +!HISTORY_MSG_225;B&W - CM - Cyan +!HISTORY_MSG_226;B&W - CM - Magenta +!HISTORY_MSG_227;B&W - CM - Purple +!HISTORY_MSG_228;B&W - Luminance equalizer +!HISTORY_MSG_229;B&W - Luminance equalizer +!HISTORY_MSG_230;B&W - Mode +!HISTORY_MSG_231;B&W - 'Before' curve +!HISTORY_MSG_232;B&W - 'Before' curve type +!HISTORY_MSG_233;B&W - 'After' curve +!HISTORY_MSG_234;B&W - 'After' curve type +!HISTORY_MSG_235;B&W - Auto channel mixer +!HISTORY_MSG_236;--unused-- +!HISTORY_MSG_237;B&W - Mixer +!HISTORY_MSG_238;GF - Feather +!HISTORY_MSG_239;GF - Strength +!HISTORY_MSG_240;GF - Center +!HISTORY_MSG_241;VF - Feather +!HISTORY_MSG_242;VF - Roundness +!HISTORY_MSG_243;VC - Radius +!HISTORY_MSG_244;VC - Strength +!HISTORY_MSG_245;VC - Center +!HISTORY_MSG_246;L*a*b* - CL curve +!HISTORY_MSG_247;L*a*b* - LH curve +!HISTORY_MSG_248;L*a*b* - HH curve +!HISTORY_MSG_249;CbDL - Threshold +!HISTORY_MSG_250;NR - Enhanced +!HISTORY_MSG_251;B&W - Algorithm +!HISTORY_MSG_252;CbDL - Skin tar/prot +!HISTORY_MSG_253;CbDL - Reduce artifacts +!HISTORY_MSG_254;CbDL - Skin hue +!HISTORY_MSG_255;NR - Median filter +!HISTORY_MSG_256;NR - Median type +!HISTORY_MSG_257;Color Toning +!HISTORY_MSG_258;CT - Color curve +!HISTORY_MSG_259;CT - Opacity curve +!HISTORY_MSG_260;CT - a*[b*] opacity +!HISTORY_MSG_261;CT - Method +!HISTORY_MSG_262;CT - b* opacity +!HISTORY_MSG_263;CT - Shadows - Red +!HISTORY_MSG_264;CT - Shadows - Green +!HISTORY_MSG_265;CT - Shadows - Blue +!HISTORY_MSG_266;CT - Mid - Red +!HISTORY_MSG_267;CT - Mid - Green +!HISTORY_MSG_268;CT - Mid - Blue +!HISTORY_MSG_269;CT - High - Red +!HISTORY_MSG_270;CT - High - Green +!HISTORY_MSG_271;CT - High - Blue +!HISTORY_MSG_272;CT - Balance +!HISTORY_MSG_273;CT - Reset +!HISTORY_MSG_274;CT - Sat. Shadows +!HISTORY_MSG_275;CT - Sat. Highlights +!HISTORY_MSG_276;CT - Opacity +!HISTORY_MSG_277;--unused-- +!HISTORY_MSG_278;CT - Preserve luminance +!HISTORY_MSG_279;CT - Shadows +!HISTORY_MSG_280;CT - Highlights +!HISTORY_MSG_281;CT - Sat. strength +!HISTORY_MSG_282;CT - Sat. threshold +!HISTORY_MSG_283;CT - Strength +!HISTORY_MSG_284;CT - Auto sat. protection +!HISTORY_MSG_285;NR - Median - Method +!HISTORY_MSG_286;NR - Median - Type +!HISTORY_MSG_287;NR - Median - Iterations +!HISTORY_MSG_288;Flat Field - Clip control +!HISTORY_MSG_289;Flat Field - Clip control - Auto +!HISTORY_MSG_290;Black Level - Red +!HISTORY_MSG_291;Black Level - Green +!HISTORY_MSG_292;Black Level - Blue +!HISTORY_MSG_293;Film Simulation +!HISTORY_MSG_294;Film Simulation - Strength +!HISTORY_MSG_295;Film Simulation - Film +!HISTORY_MSG_296;NR - Luminance curve +!HISTORY_MSG_297;NR - Quality +!HISTORY_MSG_298;Dead pixel filter +!HISTORY_MSG_299;NR - Chrominance curve +!HISTORY_MSG_300;- +!HISTORY_MSG_301;NR - Luma control +!HISTORY_MSG_302;NR - Chroma method +!HISTORY_MSG_303;NR - Chroma method +!HISTORY_MSG_304;W - Contrast levels +!HISTORY_MSG_305;Wavelet Levels +!HISTORY_MSG_306;W - Preview +!HISTORY_MSG_307;W - Preview +!HISTORY_MSG_308;W - Preview direction +!HISTORY_MSG_309;W - ES - Detail +!HISTORY_MSG_310;W - Residual - Sky tar/prot +!HISTORY_MSG_311;W - Wavelet levels +!HISTORY_MSG_312;W - Residual - Shadows threshold +!HISTORY_MSG_313;W - Chroma - Sat/past +!HISTORY_MSG_314;W - Gamut - Reduce artifacts +!HISTORY_MSG_315;W - Residual - Contrast +!HISTORY_MSG_316;W - Gamut - Skin tar/prot +!HISTORY_MSG_317;W - Gamut - Skin hue +!HISTORY_MSG_318;W - Contrast - Highlight levels +!HISTORY_MSG_319;W - Contrast - Highlight range +!HISTORY_MSG_320;W - Contrast - Shadow range +!HISTORY_MSG_321;W - Contrast - Shadow levels +!HISTORY_MSG_322;W - Gamut - Avoid color shift +!HISTORY_MSG_323;W - ES - Local contrast +!HISTORY_MSG_324;W - Chroma - Pastel +!HISTORY_MSG_325;W - Chroma - Saturated +!HISTORY_MSG_326;W - Chroma - Method +!HISTORY_MSG_327;W - Contrast - Apply to +!HISTORY_MSG_328;W - Chroma - Link strength +!HISTORY_MSG_329;W - Toning - Opacity RG +!HISTORY_MSG_330;W - Toning - Opacity BY +!HISTORY_MSG_331;W - Contrast levels - Extra +!HISTORY_MSG_332;W - Tiling method +!HISTORY_MSG_333;W - Residual - Shadows +!HISTORY_MSG_334;W - Residual - Chroma +!HISTORY_MSG_335;W - Residual - Highlights +!HISTORY_MSG_336;W - Residual - Highlights threshold +!HISTORY_MSG_337;W - Residual - Sky hue +!HISTORY_MSG_338;W - ES - Radius +!HISTORY_MSG_339;W - ES - Strength +!HISTORY_MSG_340;W - Strength +!HISTORY_MSG_341;W - Edge performance +!HISTORY_MSG_342;W - ES - First level +!HISTORY_MSG_343;W - Chroma levels +!HISTORY_MSG_344;W - Meth chroma sl/cur +!HISTORY_MSG_345;W - ES - Local contrast +!HISTORY_MSG_346;W - ES - Local contrast method +!HISTORY_MSG_347;W - Denoise - Level 0 +!HISTORY_MSG_348;W - Denoise - Level 1 +!HISTORY_MSG_349;W - Denoise - Level 2 +!HISTORY_MSG_350;W - ES - Edge detection +!HISTORY_MSG_351;W - Residual - HH curve +!HISTORY_MSG_352;W - Background +!HISTORY_MSG_353;W - ES - Gradient sensitivity +!HISTORY_MSG_354;W - ES - Enhance +!HISTORY_MSG_355;W - ES - Threshold low +!HISTORY_MSG_356;W - ES - Threshold high +!HISTORY_MSG_357;W - Denoise - Link with ES +!HISTORY_MSG_358;W - Gamut - CH +!HISTORY_MSG_359;Hot/Dead - Threshold +!HISTORY_MSG_360;TM Gamma +!HISTORY_MSG_361;W - Final - Chroma balance +!HISTORY_MSG_362;W - Residual - Compression method +!HISTORY_MSG_363;W - Residual - Compression strength +!HISTORY_MSG_364;W - Final - Contrast balance +!HISTORY_MSG_365;W - Final - Delta balance +!HISTORY_MSG_366;W - Residual - Compression gamma +!HISTORY_MSG_367;W - ES - Local contrast curve +!HISTORY_MSG_368;W - Final - Contrast balance +!HISTORY_MSG_369;W - Final - Balance method +!HISTORY_MSG_370;W - Final - Local contrast curve +!HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s +!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 +!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). +!MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Put current image to processing queue.\nShortcut: Ctrl+b +!MAIN_BUTTON_SAVE_TOOLTIP;Save current image.\nShortcut: Ctrl+s +!MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Edit current image in external editor.\nShortcut: Ctrl+e +!MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Show/hide all side panels.\nShortcut: m +!MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen +!MAIN_FRAME_BATCHQUEUE_TOOLTIP;Processing queue.\nShortcut: Ctrl-F3 +!MAIN_FRAME_EDITOR;Editor +!MAIN_FRAME_EDITOR_TOOLTIP;Editor.\nShortcut: Ctrl-F4 +!MAIN_FRAME_FILEBROWSER_TOOLTIP;File browser.\nShortcut: Ctrl-F2 +!MAIN_MSG_EMPTYFILENAME;Filename unspecified! +!MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue-processed first. +!MAIN_MSG_NAVIGATOR;Navigator +!MAIN_MSG_OPERATIONCANCELLED;Operation cancelled +!MAIN_MSG_PATHDOESNTEXIST;The path\n\n%1\n\ndoes not exist. Please set a correct path in Preferences. +!MAIN_MSG_SETPATHFIRST;You first have to set a target path in Preferences in order to use this function! +!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_EXPORT; Fast Export +!MAIN_TAB_EXPOSURE_TOOLTIP;Shortcut: Alt-e +!MAIN_TAB_INSPECT; Inspect +!MAIN_TAB_METADATA_TOOLTIP;Shortcut: Alt-m +!MAIN_TAB_RAW;Raw +!MAIN_TAB_RAW_TOOLTIP;Shortcut: Alt-r +!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_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%. +!MAIN_TOOLTIP_PREVIEWG;Preview the Green channel.\nShortcut: g +!MAIN_TOOLTIP_PREVIEWL;Preview the Luminosity.\nShortcut: v\n\n0.299*R + 0.587*G + 0.114*B +!MAIN_TOOLTIP_PREVIEWR;Preview the Red channel.\nShortcut: r +!MAIN_TOOLTIP_SHOWHIDELP1;Show/Hide the left panel.\nShortcut: l +!MAIN_TOOLTIP_SHOWHIDERP1;Show/Hide the right panel.\nShortcut: Alt-l +!MAIN_TOOLTIP_SHOWHIDETP1;Show/Hide the top panel.\nShortcut: Shift-l +!MAIN_TOOLTIP_THRESHOLD;Threshold +!MAIN_TOOLTIP_TOGGLE;Toggle the Before/After view.\nShortcut: Shift-b +!NAVIGATOR_B;B: +!NAVIGATOR_G;G: +!NAVIGATOR_H;H: +!NAVIGATOR_LAB_A;a*: +!NAVIGATOR_LAB_B;b*: +!NAVIGATOR_LAB_L;L*: +!NAVIGATOR_NA; -- +!NAVIGATOR_R;R: +!NAVIGATOR_S;S: +!NAVIGATOR_V;V: +!NAVIGATOR_XY_FULL;Width: %1, Height: %2 +!NAVIGATOR_XY_NA;x: --, y: -- +!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_CHANNELMIXERBW;Black-and-White +!PARTIALPASTE_CHANNELMIXER;Channel mixer +!PARTIALPASTE_COLORAPP;CIECAM02 +!PARTIALPASTE_COLORTONING;Color Toning +!PARTIALPASTE_COMMONTRANSFORMPARAMS;Auto-fill +!PARTIALPASTE_DARKFRAMEAUTOSELECT;Dark-frame auto-selection +!PARTIALPASTE_DARKFRAMEFILE;Dark-frame file +!PARTIALPASTE_DEFRINGE;Defringe +!PARTIALPASTE_DETAILGROUP;Detail Settings +!PARTIALPASTE_DIRPYRDENOISE;Noise reduction +!PARTIALPASTE_DIRPYREQUALIZER;Contrast by detail levels +!PARTIALPASTE_EPD;Tone mapping +!PARTIALPASTE_EQUALIZER;Wavelet Equalizer +!PARTIALPASTE_EVERYTHING;Everything +!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_GRADIENT;Graduated filter +!PARTIALPASTE_HSVEQUALIZER;HSV equalizer +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction +!PARTIALPASTE_LABCURVE;L*a*b* adjustments +!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_PCVIGNETTE;Vignette filter +!PARTIALPASTE_PERSPECTIVE;Perspective +!PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter +!PARTIALPASTE_PREPROCESS_GREENEQUIL;Green equilibration +!PARTIALPASTE_PREPROCESS_HOTPIXFILT;Hot pixel filter +!PARTIALPASTE_PREPROCESS_LINEDENOISE;Line noise filter +!PARTIALPASTE_RAWCACORR_AUTO;CA auto-correction +!PARTIALPASTE_RAWCACORR_CABLUE;CA blue +!PARTIALPASTE_RAWCACORR_CARED;CA red +!PARTIALPASTE_RAWEXPOS_BLACK;Black levels +!PARTIALPASTE_RAWEXPOS_LINEAR;White point correction +!PARTIALPASTE_RAWEXPOS_PRESER;Highlight preservation +!PARTIALPASTE_RAWGROUP;Raw Settings +!PARTIALPASTE_RAW_DCBENHANCE;DCB enhancement +!PARTIALPASTE_RAW_DCBITERATIONS;Number of DCB iterations +!PARTIALPASTE_RAW_DMETHOD;Demosaic method +!PARTIALPASTE_RAW_FALSECOLOR;Demosaic false color suppression steps +!PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!PARTIALPASTE_RGBCURVES;RGB curves +!PARTIALPASTE_SHARPENEDGE;Edges +!PARTIALPASTE_SHARPENMICRO;Microcontrast +!PARTIALPASTE_VIBRANCE;Vibrance +!PARTIALPASTE_WAVELETGROUP;Wavelet processing +!PREFERENCES_ADD;Add +!PREFERENCES_AUTLISLOW;Low +!PREFERENCES_AUTLISMAX;Max - Average of all tiles +!PREFERENCES_AUTLISSTD;High +!PREFERENCES_AUTLISVLOW;None +!PREFERENCES_AUTLOW;Low +!PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +!PREFERENCES_AUTSTD;Standard +!PREFERENCES_BATCH_PROCESSING;Batch Processing +!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_BEHADDALL;All to 'Add' +!PREFERENCES_BEHAVIOR;Behavior +!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_BEHSETALL;All to 'Set' +!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_CURVEBBOXPOS;Position of curve copypasta buttons +!PREFERENCES_CURVEBBOXPOS_ABOVE;Above +!PREFERENCES_CURVEBBOXPOS_BELOW;Below +!PREFERENCES_CURVEBBOXPOS_LEFT;Left +!PREFERENCES_CURVEBBOXPOS_RIGHT;Right +!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_CUSTPROFBUILD;Custom Processing Profile Builder +!PREFERENCES_CUTOVERLAYBRUSH;Crop mask color/transparency +!PREFERENCES_D50;5000K +!PREFERENCES_D55;5500K +!PREFERENCES_D60;6000K +!PREFERENCES_D65;6500K +!PREFERENCES_DARKFRAMEFOUND;Found +!PREFERENCES_DARKFRAMESHOTS;shots +!PREFERENCES_DARKFRAMETEMPLATES;templates +!PREFERENCES_DARKFRAME;Dark-Frame +!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 (de-select for low resolution display) +!PREFERENCES_FILMSIMULATION;Film Simulation +!PREFERENCES_FLATFIELDFOUND;Found +!PREFERENCES_FLATFIELDSDIR;Flat-fields directory +!PREFERENCES_FLATFIELDSHOTS;shots +!PREFERENCES_FLATFIELDTEMPLATES;templates +!PREFERENCES_FLATFIELD;Flat-Field +!PREFERENCES_FLUOF2;Fluorescent F2 +!PREFERENCES_FLUOF7;Fluorescent F7 +!PREFERENCES_FLUOF11;Fluorescent F11 +!PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT;Same thumbnail height between the Editor's panel 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_GREY05;Yb=05 CIE L#30 +!PREFERENCES_GREY10;Yb=10 CIE L#40 +!PREFERENCES_GREY15;Yb=15 CIE L#45 +!PREFERENCES_GREY18;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_GREYSC18;Yb=18 CIE L#50 +!PREFERENCES_GREYSCA;Automatic +!PREFERENCES_GREYSC;Scene Yb luminance (%) +!PREFERENCES_GREY;Output device's Yb luminance (%) +!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_LANGAUTODETECT;Use system language +!PREFERENCES_LEVAUTDN;Denoising level +!PREFERENCES_LEVDN;Cell size +!PREFERENCES_LISS;Auto multi-zone smoothing +!PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders +!PREFERENCES_MAX;Maxi (Tile) +!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_MENUGROUPRANK;Group "Rank" +!PREFERENCES_MENUOPTIONS;Context Menu Options +!PREFERENCES_METADATA;Metadata +!PREFERENCES_MIN;Mini (100x115) +!PREFERENCES_MULTITABDUALMON;Multiple Editor Tabs In Own Window Mode +!PREFERENCES_MULTITAB;Multiple Editor Tabs 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_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_PROPERTY;Property +!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 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_SINGLETABVERTAB;Single Editor Tab Mode, Vertical Tabs +!PREFERENCES_SINGLETAB;Single Editor Tab Mode +!PREFERENCES_SLIMUI;Slim interface +!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_PERFORMANCE;Performance & Quality +!PREFERENCES_TAB_SOUND;Sounds +!PREFERENCES_TIMAX;High +!PREFERENCES_TINB;Number of tiles +!PREFERENCES_TISTD;Standard +!PREFERENCES_TP_LABEL;Tool panel: +!PREFERENCES_TP_USEICONORTEXT;Use tab icons instead of text +!PREFERENCES_TP_VSCROLLBAR;Hide vertical scrollbar +!PREFERENCES_TUNNELMETADATA;Copy IPTC/XMP unchanged to output file (when tagging with other program) +!PREFERENCES_USEBUNDLEDPROFILES;Use bundled profiles +!PREFERENCES_USESYSTEMTHEME;Use system theme +!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_WORKFLOW;Layout +!PROFILEPANEL_COPYPPASTE;Parameters to copy +!PROFILEPANEL_GLOBALPROFILES;Bundled profiles +!PROFILEPANEL_LOADPPASTE;Parameters to load +!PROFILEPANEL_MODE_TIP;Processing profile fill mode.\n\nButton pressed: partial profiles will be converted to full profiles; the missing values will be replaced with hard-coded defaults.\n\nButton released: profiles will be applied as they are, altering only those values which they contain. +!PROFILEPANEL_MYPROFILES;My profiles +!PROFILEPANEL_PASTEPPASTE;Parameters to paste +!PROFILEPANEL_PINTERNAL;Neutral +!PROFILEPANEL_SAVEPPASTE;Parameters to save +!PROGRESSBAR_LOADINGTHUMBS;Loading thumbnails... +!PROGRESSBAR_NOIMAGES;No images found +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing profile saved +!PROGRESSBAR_SNAPSHOT_ADDED;Snapshot added +!PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists +!SAVEDLG_FORCEFORMATOPTS;Force saving options +!SAVEDLG_SUBSAMP;Subsampling +!SAVEDLG_SUBSAMP_1;Best compression +!SAVEDLG_SUBSAMP_2;Balanced +!SAVEDLG_SUBSAMP_3;Best quality +!SAVEDLG_SUBSAMP_TOOLTIP;Best compression: 4:1:1\nBalanced: 4:2:2\nBest quality: 4:4:4 +!SAVEDLG_TIFFUNCOMPRESSED;Uncompressed TIFF +!SAVEDLG_WARNFILENAME;File will be named +!SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. +!THRESHOLDSELECTOR_BL;Bottom-left +!THRESHOLDSELECTOR_BR;Bottom-right +!THRESHOLDSELECTOR_B;Bottom +!THRESHOLDSELECTOR_HINT;Hold the Shift key to move individual control points. +!THRESHOLDSELECTOR_TL;Top-left +!THRESHOLDSELECTOR_TR;Top-right +!THRESHOLDSELECTOR_T;Top +!TP_BWMIX_ALGO;Algorithm OYCPM +!TP_BWMIX_ALGO_LI;Linear +!TP_BWMIX_ALGO_SP;Special effects +!TP_BWMIX_ALGO_TOOLTIP;Linear: will produce a normal linear response.\nSpecial effects: will produce special effects by mixing channels non-linearly. +!TP_BWMIX_AUTOCH;Auto +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing Channel Mixer. +!TP_BWMIX_CC_ENABLED;Adjust complementary color +!TP_BWMIX_CC_TOOLTIP;Enable to allow automatic adjustment of complementary colors in ROYGCBPM mode. +!TP_BWMIX_CHANNEL;Luminance equalizer +!TP_BWMIX_CURVEEDITOR1;'Before' curve +!TP_BWMIX_CURVEEDITOR2;'After' curve +!TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Tone curve, after B&W conversion, at the end of treatment. +!TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Tone curve, just before B&W conversion.\nMay take into account the color components. +!TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H).\nPay attention to extreme values as they may cause artifacts. +!TP_BWMIX_FILTER;Color Filter +!TP_BWMIX_FILTER_BLUEGREEN;Blue-Green +!TP_BWMIX_FILTER_BLUE;Blue +!TP_BWMIX_FILTER_GREENYELLOW;Green-Yellow +!TP_BWMIX_FILTER_GREEN;Green +!TP_BWMIX_FILTER_NONE;None +!TP_BWMIX_FILTER_PURPLE;Purple +!TP_BWMIX_FILTER_REDYELLOW;Red-Yellow +!TP_BWMIX_FILTER_RED;Red +!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. +!TP_BWMIX_FILTER_YELLOW;Yellow +!TP_BWMIX_GAMMA;Gamma Correction +!TP_BWMIX_GAM_TOOLTIP;Correct gamma for each RGB channel. +!TP_BWMIX_LABEL;Black-and-White +!TP_BWMIX_MET;Method +!TP_BWMIX_MET_CHANMIX;Channel Mixer +!TP_BWMIX_MET_DESAT;Desaturation +!TP_BWMIX_MET_LUMEQUAL;Luminance Equalizer +!TP_BWMIX_MIXC;Mixer +!TP_BWMIX_NEUTRAL;Reset mixer +!TP_BWMIX_NEUTRAL_TIP;Reset all values (Color Filter, Channel Mixer) to default. +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all the mixer options.\n"Total" displays the sum of the RGB values:\n- always 100% in relative mode\n- higher (lighter) or lower (darker) than 100% in absolute mode. +!TP_BWMIX_RGB_TOOLTIP;Mix the RGB channels. Use presets for guidance.\nPay attention to negative values that may cause artifacts or erratic behavior. +!TP_BWMIX_SETTING;Presets +!TP_BWMIX_SETTING_TOOLTIP;Different presets (film, landscape, etc.) or manual Channel Mixer settings. +!TP_BWMIX_SET_HIGHCONTAST;High contrast +!TP_BWMIX_SET_HIGHSENSIT;High Sensitivity +!TP_BWMIX_SET_HYPERPANCHRO;Hyper Panchromatic +!TP_BWMIX_SET_INFRARED;Infrared +!TP_BWMIX_SET_LANDSCAPE;Landscape +!TP_BWMIX_SET_LOWSENSIT;Low Sensitivity +!TP_BWMIX_SET_LUMINANCE;Luminance +!TP_BWMIX_SET_NORMCONTAST;Normal Contrast +!TP_BWMIX_SET_ORTHOCHRO;Orthochromatic +!TP_BWMIX_SET_PANCHRO;Panchromatic +!TP_BWMIX_SET_PORTRAIT;Portrait +!TP_BWMIX_SET_RGBABS;Absolute RGB +!TP_BWMIX_SET_RGBREL;Relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Relative ROYGCBPM +!TP_BWMIX_TCMODE_FILMLIKE;B&W Film-like +!TP_BWMIX_TCMODE_SATANDVALBLENDING;B&W Saturation and Value Blending +!TP_BWMIX_TCMODE_STANDARD;B&W Standard +!TP_BWMIX_TCMODE_WEIGHTEDSTD;B&W Weighted Standard +!TP_BWMIX_VAL;L +!TP_CHROMATABERR_LABEL;Chromatic Aberration +!TP_COLORAPP_ADAPTSCENE;Scene luminosity +!TP_COLORAPP_ADAPTSCENE_TOOLTIP;Absolute luminance of the scene environement (cd/m²).\n1) Calculated from the Exif data:\nShutter speed - ISO speed - F number - camera exposure correction.\n2) Calculated from the raw white point and RT's Exposure Compensation slider. +!TP_COLORAPP_ADAPTVIEWING;Viewing luminosity (cd/m²) +!TP_COLORAPP_ADAPTVIEWING_TOOLTIP;Absolute luminance of the viewing environnement\n(usually 16cd/m²). +!TP_COLORAPP_ADAP_AUTO_TOOLTIP;If the checkbox is checked (recommended) RawTherapee calculates an optimum value from Exif data.\nTo set the value manually, uncheck the checkbox first. +!TP_COLORAPP_ALGO;Algorithm +!TP_COLORAPP_ALGO_ALL;All +!TP_COLORAPP_ALGO_JC;Lightness + Chroma (JC) +!TP_COLORAPP_ALGO_JS;Lightness + Saturation (JS) +!TP_COLORAPP_ALGO_QM;Brightness + Colorfulness (QM) +!TP_COLORAPP_ALGO_TOOLTIP;Lets you choose between parameter subsets or all parameters. +!TP_COLORAPP_BADPIXSL;Hot/bad pixel filter +!TP_COLORAPP_BADPIXSL_TOOLTIP;Suppression of hot/bad (brightly colored) pixels.\n0 = No effect\n1 = Median\n2 = Gaussian.\nAlternatively, adjust the image to avoid very dark shadows.\n\nThese artifacts are due to limitations of CIECAM02. +!TP_COLORAPP_BRIGHT;Brightness (Q) +!TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from L*a*b* and RGB brightness. +!TP_COLORAPP_CHROMA;Chroma (C) +!TP_COLORAPP_CHROMA_M;Colorfulnes (M) +!TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM02 differs from L*a*b* and RGB colorfulness. +!TP_COLORAPP_CHROMA_S;Saturation (S) +!TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from L*a*b* and RGB saturation. +!TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from L*a*b* and RGB chroma. +!TP_COLORAPP_CIECAT_DEGREE;CAT02 adaptation +!TP_COLORAPP_CONTRAST;Contrast (J) +!TP_COLORAPP_CONTRAST_Q;Contrast (Q) +!TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrast in CIECAM02 for the Q slider; it differs from L*a*b* and RGB contrast. +!TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from L*a*b* and RGB contrast. +!TP_COLORAPP_CURVEEDITOR1;Tone curve 1 +!TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L* (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of J or Q after CIECAM02.\n\nJ and Q are not shown in the main histogram panel.\n\nFor final output refer to the main histogram panel. +!TP_COLORAPP_CURVEEDITOR2;Tone curve 2 +!TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Same usage as with the second exposure tone curve. +!TP_COLORAPP_CURVEEDITOR3;Color curve +!TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Adjust either chroma, saturation or colorfulness.\n\nShows the histogram of chromaticity (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of C, s or M after CIECAM02.\n\nC, s and M are not shown in the main histogram panel.\nFor final output refer to the main histogram panel. +!TP_COLORAPP_DATACIE;CIECAM02 output histograms in curves +!TP_COLORAPP_DATACIE_TOOLTIP;When enabled, histograms in CIECAM02 curves show approximate values/ranges for J or Q, and C, s or M after the CIECAM02 adjustments.\nThis selection does not impact the main histogram panel.\n\nWhen disabled, histograms in CIECAM02 curves show L*a*b* values before CIECAM02 adjustments. +!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RawTherapee calculates an optimum value, which is then used by CAT02, and also for the entire CIECAM02.\nTo set the value manually, uncheck the check-box first (values above 65 are recommended). +!TP_COLORAPP_DEGREE_TOOLTIP;Amount of CIE Chromatic Adaptation Transform 2002. +!TP_COLORAPP_GAMUT;Gamut control (L*a*b*) +!TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in L*a*b* mode. +!TP_COLORAPP_HUE;Hue (h) +!TP_COLORAPP_HUE_TOOLTIP;Hue (h) - angle between 0° and 360°. +!TP_COLORAPP_LABEL;CIE Color Appearance Model 2002 +!TP_COLORAPP_LABEL_CAM02;Image Adjustments +!TP_COLORAPP_LABEL_SCENE;Scene Conditions +!TP_COLORAPP_LABEL_VIEWING;Viewing Conditions +!TP_COLORAPP_LIGHT;Lightness (J) +!TP_COLORAPP_LIGHT_TOOLTIP;Lightness in CIECAM02 differs from L*a*b* and RGB lightness. +!TP_COLORAPP_MODEL;WP Model +!TP_COLORAPP_MODEL_TOOLTIP;White-Point Model.\n\nWB [RT] + [output]: RT's white balance is used for the scene, CIECAM02 is set to D50, and the output device's white balance is set in Preferences > Color Management.\n\nWB [RT+CAT02] + [output]: RT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences - Color Management. +!TP_COLORAPP_RSTPRO;Red & skin-tones protection +!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin-tones protection affects both sliders and curves. +!TP_COLORAPP_SHARPCIE;--unused-- +!TP_COLORAPP_SHARPCIE_TOOLTIP;--unused-- +!TP_COLORAPP_SURROUND;Surround +!TP_COLORAPP_SURROUND_AVER;Average +!TP_COLORAPP_SURROUND_DARK;Dark +!TP_COLORAPP_SURROUND_DIM;Dim +!TP_COLORAPP_SURROUND_EXDARK;Extremly Dark (Cutsheet) +!TP_COLORAPP_SURROUND_TOOLTIP;Changes tones and colors to take into account the viewing conditions of the output device.\n\nAverage: Average light environment (standard). The image will not change.\n\nDim: Dim environment (TV). The image will become slighty dark.\n\nDark: Dark environment (projector). The image will become more dark.\n\nExtremly Dark: Extremly dark environment (cutsheet). The image will become very dark. +!TP_COLORAPP_SURSOURCE;Dark surround +!TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if image has a dark border. +!TP_COLORAPP_TCMODE_BRIGHTNESS;Brightness +!TP_COLORAPP_TCMODE_CHROMA;Chroma +!TP_COLORAPP_TCMODE_COLORF;Colorfulness +!TP_COLORAPP_TCMODE_LABEL1;Curve mode 1 +!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_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] +!TP_COLORAPP_WBRT;WB [RT] + [output] +!TP_COLORTONING_AB;o C/L +!TP_COLORTONING_AUTOSAT;Automatic +!TP_COLORTONING_BALANCE;Balance +!TP_COLORTONING_BY;o C/L +!TP_COLORTONING_CHROMAC;Opacity +!TP_COLORTONING_COLOR;Color +!TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;Chroma opacity as a function of luminance oC=f(L) +!TP_COLORTONING_HIGHLIGHT;Highlights +!TP_COLORTONING_HUE;Hue +!TP_COLORTONING_LABEL;Color Toning +!TP_COLORTONING_LAB;L*a*b* blending +!TP_COLORTONING_LUMAMODE;Preserve luminance +!TP_COLORTONING_LUMAMODE_TOOLTIP;If enabled, when you change color (red, green, cyan, blue, etc.) the luminance of each pixel is preserved. +!TP_COLORTONING_LUMA;Luminance +!TP_COLORTONING_METHOD;Method +!TP_COLORTONING_METHOD_TOOLTIP;"L*a*b* blending", "RGB sliders" and "RGB curves" use interpolated color blending.\n"Color balance (Shadows/Midtones/Highlights)" and "Saturation 2 colors" use direct colors.\n\nThe Black-and-White tool can be enabled when using any color toning method, which allows for color toning. +!TP_COLORTONING_MIDTONES;Midtones +!TP_COLORTONING_NEUTRAL;Reset sliders +!TP_COLORTONING_NEUTRAL_TIP;Reset all values (Shadows, Midtones, Highlights) to default. +!TP_COLORTONING_OPACITY;Opacity +!TP_COLORTONING_RGBCURVES;RGB - Curves +!TP_COLORTONING_RGBSLIDERS;RGB - Sliders +!TP_COLORTONING_SATURATEDOPACITY;Strength +!TP_COLORTONING_SATURATIONTHRESHOLD;Threshold +!TP_COLORTONING_SA;Saturation Protection +!TP_COLORTONING_SHADOWS;Shadows +!TP_COLORTONING_SPLITCOCO;Color Balance Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITCO;Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITLR;Saturation 2 colors +!TP_COLORTONING_STRENGTH;Strength +!TP_COLORTONING_STR;Strength +!TP_COLORTONING_TWO2;Special chroma '2 colors' +!TP_COLORTONING_TWOALL;Special chroma +!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_GTFRAME;Frame +!TP_CROP_GTGRID;Grid +!TP_CROP_GTHARMMEANS;Harmonic Means +!TP_CROP_GTTRIANGLE1;Golden Triangles 1 +!TP_CROP_GTTRIANGLE2;Golden Triangles 2 +!TP_CROP_PPI;PPI= +!TP_DARKFRAME_AUTOSELECT;Auto-selection +!TP_DARKFRAME_LABEL;Dark-Frame +!TP_DEFRINGE_LABEL;Defringe +!TP_DEFRINGE_RADIUS;Radius +!TP_DEFRINGE_THRESHOLD;Threshold +!TP_DIRPYRDENOISE_33;3×3 strong +!TP_DIRPYRDENOISE_55SOFT;5×5 +!TP_DIRPYRDENOISE_55;5×5 strong +!TP_DIRPYRDENOISE_77;7×7 (slow) +!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_ABM;Chroma only +!TP_DIRPYRDENOISE_AUTO;Automatic global +!TP_DIRPYRDENOISE_AUTO_TOOLTIP;Try to evaluate chroma noise\nBe careful, this calculation is average, and is quite subjective ! +!TP_DIRPYRDENOISE_AUT;Automatic global +!TP_DIRPYRDENOISE_BLUE;Chrominance - Blue-Yellow +!TP_DIRPYRDENOISE_C2TYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CCCURVE;Chrominance curve +!TP_DIRPYRDENOISE_CHROMAFR;Chrominance +!TP_DIRPYRDENOISE_CHROMA;Chrominance - Master +!TP_DIRPYRDENOISE_CTYPE;Auto method +!TP_DIRPYRDENOISE_CTYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nAutomatic multi-zones\nNo preview - works only during saving, but using the "Preview" method by matching the tile size and center to the preview size and center you can get an idea of the expected results.\nThe image is divided into tiles (about 10 to 70 depending on image size) and each tile receives its own chrominance noise reduction settings.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CURVEEDITOR_CC;Chroma +!TP_DIRPYRDENOISE_CURVEEDITOR_CC_TOOLTIP;Increase (multiply) the value of all chrominance sliders.\nThis curve lets you adjust the strength of chromatic noise reduction as a function of chromaticity, for instance to increase the action in areas of low saturation and to decrease it in those of high saturation. +!TP_DIRPYRDENOISE_CURVEEDITOR_L_TOOLTIP;Modulates action of 'Luminance' denoise +!TP_DIRPYRDENOISE_CUR;Curve +!TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on the gamma of the input color profile. An sRGB gamma is assumed, thus if the image uses an input color profile of a different gamma, the effects of luminance noise reduction will differ. +!TP_DIRPYRDENOISE_ENH;Enhanced mode +!TP_DIRPYRDENOISE_ENH_TOOLTIP;Increases noise reduction quality at the expense of a 20% processing time increase. +!TP_DIRPYRDENOISE_GAMMA;Gamma +!TP_DIRPYRDENOISE_GAMMA_TOOLTIP;Gamma varies noise reduction strength across the range of tones. Smaller values will target shadows, while larger values will stretch the effect to the brighter tones. +!TP_DIRPYRDENOISE_LABEL;Noise Reduction +!TP_DIRPYRDENOISE_LABM;L*a*b* +!TP_DIRPYRDENOISE_LAB;L*a*b* +!TP_DIRPYRDENOISE_LCURVE;Luminance curve +!TP_DIRPYRDENOISE_LDETAIL;Luminance - Detail +!TP_DIRPYRDENOISE_LM;Luminance only +!TP_DIRPYRDENOISE_LPLABM;Weighted L* (little) + a*b* (normal) +!TP_DIRPYRDENOISE_LTYPE;Luminance control +!TP_DIRPYRDENOISE_LUMAFR;Luminance +!TP_DIRPYRDENOISE_LUMAFR_TOOLTIP;Wavelet on luminance and Fourier transform for luminance detail +!TP_DIRPYRDENOISE_LUMA;Luminance +!TP_DIRPYRDENOISE_MANU;Manual +!TP_DIRPYRDENOISE_MAN;Manual +!TP_DIRPYRDENOISE_MEDMETHOD;Median method +!TP_DIRPYRDENOISE_MEDTYPE;Median type +!TP_DIRPYRDENOISE_MED;Median Filter +!TP_DIRPYRDENOISE_MED_TOOLTIP;Enabled median denoising +!TP_DIRPYRDENOISE_METHOD11;Quality +!TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. +!TP_DIRPYRDENOISE_METHOD;Method +!TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or L*a*b* methods can be used.\n\nFor non-raw images the L*a*b* method will be used, regardless of the selection. +!TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - +!TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 +!TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. +!TP_DIRPYRDENOISE_PASSES;Median iterations +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PON;Auto multi-zones +!TP_DIRPYRDENOISE_PREVLABEL;Preview size=%1, Center: Px=%2 Py=%3 +!TP_DIRPYRDENOISE_PREV;Preview +!TP_DIRPYRDENOISE_PRE;Preview multi-zones +!TP_DIRPYRDENOISE_RED;Chrominance - Red-Green +!TP_DIRPYRDENOISE_RGBM;RGB +!TP_DIRPYRDENOISE_RGB;RGB +!TP_DIRPYRDENOISE_SHALBI;High +!TP_DIRPYRDENOISE_SHAL;Standard +!TP_DIRPYRDENOISE_SLI;Slider +!TP_DIRPYRDENOISE_SOFT;3x3 +!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_LUMAFINEST;Finest +!TP_DIRPYREQUALIZER_LUMANEUTRAL;Neutral +!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_THRESHOLD;Threshold +!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;Auto Distortion Correction +!TP_DISTORTION_AUTO_TIP;Correct lens distortion automatically for some cameras (Micro 4/3, some compact digital cameras, etc.). +!TP_EPD_EDGESTOPPING;Edge stopping +!TP_EPD_GAMMA;Gamma +!TP_EPD_LABEL;Tone Mapping +!TP_EPD_REWEIGHTINGITERATES;Reweighting iterates +!TP_EPD_SCALE;Scale +!TP_EPD_STRENGTH;Strength +!TP_EPD_TOOLTIP;Tone mapping is possible in L*a*b* mode (standard) and CIECAM02 mode.\n\nWhen in L*a*b* mode, tone mapping can also be used on the residual image of the Wavelet Levels tool.\n\nTo engage CIECAM02 tone mapping mode enable the following settings:\n1. CIECAM02\n2. Algorithm="Brightness + Colorfulness (QM)"\n3. "Tone mapping using CIECAM02 brightness (Q)" +!TP_EXPOSURE_AUTOLEVELS_TIP;Toggles execution of Auto Levels to automatically set Exposure slider values based on an image analysis.\nEnables Highlight Reconstruction if necessary. +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in Auto Levels operation. +!TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Highlight compression threshold +!TP_EXPOSURE_CURVEEDITOR1;Tone curve 1 +!TP_EXPOSURE_CURVEEDITOR2;Tone curve 2 +!TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Please refer to the "Exposure > Tone Curves" RawPedia article to learn how to achieve the best results by using two tone curves. +!TP_EXPOSURE_SATURATION;Saturation +!TP_EXPOSURE_TCMODE_FILMLIKE;Film-like +!TP_EXPOSURE_TCMODE_LABEL1;Curve mode 1 +!TP_EXPOSURE_TCMODE_LABEL2;Curve mode 2 +!TP_EXPOSURE_TCMODE_LUMINANCE;Luminance +!TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Saturation and Value Blending +!TP_EXPOSURE_TCMODE_STANDARD;Standard +!TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard +!TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points +!TP_EXPOS_WHITEPOINT_LABEL;Raw White Points +!TP_FILMSIMULATION_LABEL;Film Simulation +!TP_FILMSIMULATION_STRENGTH;Strength +!TP_FILMSIMULATION_ZEROCLUTSFOUND;Set HaldCLUT directory in Preferences +!TP_FLATFIELD_AUTOSELECT;Auto-selection +!TP_FLATFIELD_BLURRADIUS;Blur radius +!TP_FLATFIELD_BLURTYPE;Blur type +!TP_FLATFIELD_BT_AREA;Area +!TP_FLATFIELD_BT_HORIZONTAL;Horizontal +!TP_FLATFIELD_BT_VERTHORIZ;Vertical + Horizontal +!TP_FLATFIELD_BT_VERTICAL;Vertical +!TP_FLATFIELD_CLIPCONTROL;Clip control +!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. +!TP_FLATFIELD_LABEL;Flat-Field +!TP_GAMMA_CURV;Gamma +!TP_GAMMA_FREE;Free gamma +!TP_GAMMA_OUTPUT;Output gamma +!TP_GAMMA_SLOP;Slope (linear) +!TP_GENERAL_11SCALE_TOOLTIP;The effects of this tool are only visible or only accurate at a preview scale of 1:1. +!TP_GRADIENT_CENTER;Center +!TP_GRADIENT_CENTER_X;Center X +!TP_GRADIENT_CENTER_X_TOOLTIP;Shift gradient to the left (negative values) or right (positive values). +!TP_GRADIENT_CENTER_Y;Center Y +!TP_GRADIENT_CENTER_Y_TOOLTIP;Shift gradient up (negative values) or down (positive values). +!TP_GRADIENT_DEGREE;Angle +!TP_GRADIENT_DEGREE_TOOLTIP;Rotation angle in degrees. +!TP_GRADIENT_FEATHER;Feather +!TP_GRADIENT_FEATHER_TOOLTIP;Gradient width in percent of the image diagonal. +!TP_GRADIENT_LABEL;Graduated Filter +!TP_GRADIENT_STRENGTH;Strength +!TP_GRADIENT_STRENGTH_TOOLTIP;Filter strength in stops. +!TP_HLREC_BLEND;Blend +!TP_HLREC_ENA_TOOLTIP;Could be activated by Auto Levels. +!TP_HSVEQUALIZER_CHANNEL;Channel +!TP_HSVEQUALIZER_HUE;H +!TP_HSVEQUALIZER_LABEL;HSV Equalizer +!TP_HSVEQUALIZER_SAT;S +!TP_HSVEQUALIZER_VAL;V +!TP_ICM_BLENDCMSMATRIX;Blend ICC highlights with matrix +!TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover clipped highlights when using LUT-based ICC profiles. +!TP_ICM_DCPILLUMINANT;Illuminant +!TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolated +!TP_ICM_DCPILLUMINANT_TOOLTIP;Select which embedded DCP illuminant to employ. Default is "interpolated" which is a mix between the two based on white balance. The setting is only enabled if a Dual-Illuminant DCP with interpolation support is selected. +!TP_ICM_INPUTCAMERAICC;Auto-matched camera profile +!TP_ICM_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input color profiles. These profiles are more precise than simpler matrix ones. They are not available for all cameras. These profiles are stored in the /iccprofiles/input and /dcpprofiles folders and are automatically retrieved based on a file name matching to the exact model name of the camera. +!TP_ICM_INPUTCAMERA_TOOLTIP;Use a simple color matrix from dcraw, an enhanced RawTherapee version (whichever is available based on camera model) or one embedded in the DNG. +!TP_ICM_INPUTCUSTOM_TOOLTIP;Select your own DCP/ICC color profile file for the camera. +!TP_ICM_INPUTEMBEDDED_TOOLTIP;Use color profile embedded in non-raw files. +!TP_ICM_INPUTNONE;No profile +!TP_ICM_INPUTNONE_TOOLTIP;Use no input color profile at all.\nUse only in special cases. +!TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance +!TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. The result can be used for calibration purposes and generation of a camera profile. +!TP_ICM_TONECURVE;Use DCP's tone curve +!TP_ICM_TONECURVE_TOOLTIP;Employ the embedded DCP tone curve. The setting is only enabled if the selected DCP has a tone curve. +!TP_IMPULSEDENOISE_LABEL;Impulse Noise Reduction +!TP_IMPULSEDENOISE_THRESH;Threshold +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid color shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction. +!TP_LABCURVE_BRIGHTNESS;Lightness +!TP_LABCURVE_CHROMATICITY;Chromaticity +!TP_LABCURVE_CHROMA_TOOLTIP;To apply B&W toning, set Chromaticity to -100. +!TP_LABCURVE_CONTRAST;Contrast +!TP_LABCURVE_CURVEEDITOR;Luminance Curve +!TP_LABCURVE_CURVEEDITOR_A_RANGE1;Green Saturated +!TP_LABCURVE_CURVEEDITOR_A_RANGE2;Green Pastel +!TP_LABCURVE_CURVEEDITOR_A_RANGE3;Red Pastel +!TP_LABCURVE_CURVEEDITOR_A_RANGE4;Red Saturated +!TP_LABCURVE_CURVEEDITOR_B_RANGE1;Blue Saturated +!TP_LABCURVE_CURVEEDITOR_B_RANGE2;Blue Pastel +!TP_LABCURVE_CURVEEDITOR_B_RANGE3;Yellow Pastel +!TP_LABCURVE_CURVEEDITOR_B_RANGE4;Yellow Saturated +!TP_LABCURVE_CURVEEDITOR_CC;CC +!TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutral +!TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Dull +!TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastel +!TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Saturated +!TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Chromaticity according to chromaticity C=f(C) +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to hue C=f(H) +!TP_LABCURVE_CURVEEDITOR_CL;CL +!TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Chromaticity according to luminance C=f(L) +!TP_LABCURVE_CURVEEDITOR_HH;HH +!TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Hue according to hue H=f(H) +!TP_LABCURVE_CURVEEDITOR_LC;LC +!TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminance according to chromaticity L=f(C) +!TP_LABCURVE_CURVEEDITOR_LH;LH +!TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H) +!TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminance according to luminance L=f(L) +!TP_LABCURVE_LABEL;L*a*b* Adjustments +!TP_LABCURVE_LCREDSK;Restrict LC to red and skin-tones +!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_LENSGEOM_AUTOCROP;Auto-Crop +!TP_LENSGEOM_FILL;Auto-fill +!TP_LENSGEOM_LABEL;Lens / Geometry +!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_USECA;Chromatic aberration correction +!TP_LENSPROFILE_USEDIST;Distortion correction +!TP_LENSPROFILE_USEVIGN;Vignetting correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Resets exposure sliders to neutral values.\nApplies to the same controls that Auto Levels applies to, regardless of whether you used Auto Levels or not. +!TP_PCVIGNETTE_FEATHER;Feather +!TP_PCVIGNETTE_FEATHER_TOOLTIP;Feathering:\n0 = corners only,\n50 = halfway to center,\n100 = to center. +!TP_PCVIGNETTE_LABEL;Vignette Filter +!TP_PCVIGNETTE_ROUNDNESS;Roundness +!TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness:\n0 = rectangle,\n50 = fitted ellipse,\n100 = circle. +!TP_PCVIGNETTE_STRENGTH;Strength +!TP_PCVIGNETTE_STRENGTH_TOOLTIP;Filter strength in stops (reached in corners). +!TP_PERSPECTIVE_HORIZONTAL;Horizontal +!TP_PERSPECTIVE_LABEL;Perspective +!TP_PERSPECTIVE_VERTICAL;Vertical +!TP_PFCURVE_CURVEEDITOR_CH;Hue +!TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Controls defringe strength by color.\nHigher = more,\nLower = less. +!TP_PREPROCESS_DEADPIXFILT;Dead pixel filter +!TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Tries to suppress dead pixels. +!TP_PREPROCESS_GREENEQUIL;Green equilibration +!TP_PREPROCESS_HOTPIXFILT;Hot pixel filter +!TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Tries to suppress hot pixels. +!TP_PREPROCESS_LABEL;Preprocessing +!TP_PREPROCESS_LINEDENOISE;Line noise filter +!TP_PREPROCESS_NO_FOUND;None found +!TP_RAWCACORR_AUTO;Auto-correction +!TP_RAWCACORR_CABLUE;Blue +!TP_RAWCACORR_CARED;Red +!TP_RAWEXPOS_BLACKS;Black Levels +!TP_RAWEXPOS_BLACK_0;Green 1 (lead) +!TP_RAWEXPOS_BLACK_1;Red +!TP_RAWEXPOS_BLACK_2;Blue +!TP_RAWEXPOS_BLACK_3;Green 2 +!TP_RAWEXPOS_BLACK_BLUE;Blue +!TP_RAWEXPOS_BLACK_GREEN;Green +!TP_RAWEXPOS_BLACK_RED;Red +!TP_RAWEXPOS_LINEAR;White-point correction +!TP_RAWEXPOS_PRESER;Highlight preservation +!TP_RAWEXPOS_RGB;Red, Green, Blue +!TP_RAWEXPOS_TWOGREEN;Link greens +!TP_RAW_DCBENHANCE;DCB enhancement +!TP_RAW_DCBITERATIONS;Number of DCB iterations +!TP_RAW_DMETHOD_PROGRESSBAR;%1 demosaicing... +!TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Demosaicing refinement... +!TP_RAW_DMETHOD_TOOLTIP;Note: IGV and LMMSE are dedicated to high ISO images to aid in noise reduction without leading to maze patterns, posterization or a washed-out look. +!TP_RAW_HD;Threshold +!TP_RAW_HD_TOOLTIP;Lower values make hot/dead pixel detection more aggressive, but false positives may lead to artifacts. If you notice any artifacts appearing when enabling the Hot/Dead Pixel Filters, gradually increase the threshold value until they disappear. +!TP_RAW_LABEL;Demosaicing +!TP_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!TP_RAW_LMMSE_TOOLTIP;Adds gamma (step 1), median (steps 2-4) and refinement (steps 5-6) to reduce artifacts and improve the signal-to-noise ratio. +!TP_RAW_SENSOR_BAYER_LABEL;Sensor with Bayer Matrix +!TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;3-pass gives best results (recommended for low ISO images).\n1-pass is almost undistinguishable from 3-pass for high ISO images and is faster. +!TP_RAW_SENSOR_XTRANS_LABEL;Sensor with X-Trans Matrix +!TP_RESIZE_APPLIESTO;Applies to: +!TP_RESIZE_CROPPEDAREA;Cropped Area +!TP_RESIZE_FITBOX;Bounding Box +!TP_RESIZE_FULLIMAGE;Full Image +!TP_RESIZE_HEIGHT;Height +!TP_RESIZE_LANCZOS;Lanczos +!TP_RESIZE_SPECIFY;Specify: +!TP_RESIZE_WIDTH;Width +!TP_RGBCURVES_BLUE;B +!TP_RGBCURVES_CHANNEL;Channel +!TP_RGBCURVES_GREEN;G +!TP_RGBCURVES_LABEL;RGB Curves +!TP_RGBCURVES_LUMAMODE;Luminosity mode +!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_RGBCURVES_RED;R +!TP_SAVEDIALOG_OK_TIP;Shortcut: Ctrl-Enter +!TP_SHADOWSHLIGHTS_SHARPMASK;Sharp mask +!TP_SHARPENEDGE_AMOUNT;Quantity +!TP_SHARPENEDGE_LABEL;Edges +!TP_SHARPENEDGE_PASSES;Iterations +!TP_SHARPENEDGE_THREE;Luminance only +!TP_SHARPENING_TOOLTIP;Expect a slightly different effect when using with CIECAM02. If difference is observed, adjust to taste. +!TP_SHARPENMICRO_AMOUNT;Quantity +!TP_SHARPENMICRO_LABEL;Microcontrast +!TP_SHARPENMICRO_MATRIX;3×3 matrix instead of 5×5 +!TP_SHARPENMICRO_UNIFORMITY;Uniformity +!TP_VIBRANCE_AVOIDCOLORSHIFT;Avoid color shift +!TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Red/Purple +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Red +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Red/Yellow +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Yellow +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Hue according to hue H=f(H) +!TP_VIBRANCE_LABEL;Vibrance +!TP_VIBRANCE_PASTELS;Pastel Tones +!TP_VIBRANCE_PASTSATTOG;Link pastel and saturated tones +!TP_VIBRANCE_PROTECTSKINS;Protect skin-tones +!TP_VIBRANCE_PSTHRESHOLD;Pastel/saturated tones threshold +!TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Saturation threshold +!TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;The vertical axis represents pastel tones at the bottom and saturated tones at the top.\nThe horizontal axis represents the saturation range. +!TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Pastel/saturated transition's weighting +!TP_VIBRANCE_SATURATED;Saturated Tones +!TP_VIGNETTING_CENTER;Center +!TP_VIGNETTING_CENTER_X;Center X +!TP_VIGNETTING_CENTER_Y;Center Y +!TP_VIGNETTING_STRENGTH;Strength +!TP_WAVELET_1;Level 1 +!TP_WAVELET_2;Level 2 +!TP_WAVELET_3;Level 3 +!TP_WAVELET_4;Level 4 +!TP_WAVELET_5;Level 5 +!TP_WAVELET_6;Level 6 +!TP_WAVELET_7;Level 7 +!TP_WAVELET_8;Level 8 +!TP_WAVELET_9;Level 9 +!TP_WAVELET_ALL;All levels in all directions +!TP_WAVELET_APPLYTO;Apply To +!TP_WAVELET_AVOID;Avoid color shift +!TP_WAVELET_B0;Black +!TP_WAVELET_B1;Grey +!TP_WAVELET_B2;Residual +!TP_WAVELET_BACUR;Curve +!TP_WAVELET_BALANCE;Contrast balance d/v-h +!TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chromaticity or residual tone mapping are activated, the effect due to balance is amplified. +!TP_WAVELET_BALCHRO;Chroma balance +!TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chromaticity balance. +!TP_WAVELET_BANONE;None +!TP_WAVELET_BASLI;Slider +!TP_WAVELET_BATYPE;Contrast balance method +!TP_WAVELET_CCURVE;Local contrast +!TP_WAVELET_CH1;Whole chromaticity range +!TP_WAVELET_CH2;Saturated/pastel +!TP_WAVELET_CH3;Link contrast levels +!TP_WAVELET_CHCU;Curve +!TP_WAVELET_CHRO;Saturated/pastel threshold +!TP_WAVELET_CHRO_TOOLTIP;Sets the wavelet level which will be the threshold between saturated and pastel colors.\n1-x: saturated\nx-9: pastel\n\nIf the value exceeds the amount of wavelet levels you are using then it will be ignored. +!TP_WAVELET_CHR;Chroma-contrast link strength +!TP_WAVELET_CHR_TOOLTIP;Adjusts chromaticity as a function of "contrast levels" and "chroma-contrast link strength" +!TP_WAVELET_CHSL;Sliders +!TP_WAVELET_CHTYPE;Chrominance method +!TP_WAVELET_COLORT;Opacity Red-Green +!TP_WAVELET_COMBOTH;Both +!TP_WAVELET_COMPCONT;Contrast +!TP_WAVELET_COMPGAMMA;Compression gamma +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjusting the gamma of the residual image allow you to equilibrate the data and histogram. +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjust gamma for residual image and compression.\nAllow to equilibrate data and histogram +!TP_WAVELET_COMPTM;Tone mapping +!TP_WAVELET_CONTEDIT;'After' Contrast curve +!TP_WAVELET_CONTEDIT;'After' contrast curve +!TP_WAVELET_CONTRAST_MINUS;Contrast - +!TP_WAVELET_CONTRAST_PLUS;Contrast + +!TP_WAVELET_CONTRA;Contrast +!TP_WAVELET_CONTRA_TOOLTIP;Changes contrast of the residual image. +!TP_WAVELET_CONTR;Gamut +!TP_WAVELET_CTYPE;Chrominance control +!TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modifies local contrast as a function of the original local contrast (absciss)\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 100..300)\n66% absciss represents standard deviation of local contrast (real value about 300..800)\n100% represents maximum (real value about 3000..8000) +!TP_WAVELET_CURVEEDITOR_CH;Contrast levels=f(Hue) +!TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modifies each level's contrast as a function oh hue.\nTake care not to overwrite changes made with the Gamut Hue controls.\nThe curve will only have an effect when wavelet contrast level sliders are non-zero. +!TP_WAVELET_CURVEEDITOR_CL;L +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Applies a final contrast luminance curve at the end of the wavelet treatment. +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Apply a contrast luminance curve at the end of wavelet level threatment +!TP_WAVELET_CURVEEDITOR_HH;HH +!TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modifies the residual image's hue as a function of hue. +!TP_WAVELET_DALL;All directions +!TP_WAVELET_DAUB;Edge performance +!TP_WAVELET_DAUB_TOOLTIP;Changes Daubechies coefficients:\nD4 = Standard,\nD14 = Often best performance, 10% more time-intensive.\n\nAffects edge detection as well as the general quality of the firsts levels. However the quality is not strictly related to this coefficient and can vary with images and uses. +!TP_WAVELET_DISP;Preview Settings +!TP_WAVELET_DONE;Vertical +!TP_WAVELET_DTHR;Diagonal +!TP_WAVELET_DTWO;Horizontal +!TP_WAVELET_EDCU;Curve +!TP_WAVELET_EDGCONT;Local contrast +!TP_WAVELET_EDGCONT_TOOLTIP;Adjusting the points to the left decreases contrast, and to the right increases it.\nBottom-left, Top-Left, Top-Right, Bottom-right represent respectively local contast for low values, mean, mean+stdev, maxima +!TP_WAVELET_EDGEDETECTTHR2;Threshold high (detection) +!TP_WAVELET_EDGEDETECTTHR;Threshold low (noise) +!TP_WAVELET_EDGEDETECTTHR_TOOLTIP;This adjuster lets you target edge detection for example to avoid applying edge sharpness to fine details, such as noise in the sky. +!TP_WAVELET_EDGEDETECT;Gradient sensitivity +!TP_WAVELET_EDGEDETECT_TOOLTIP;Moving the slider to the right increases edge sensitivity. This affects local contrast, edge settings and noise. +!TP_WAVELET_EDGE;Edge Sharpness +!TP_WAVELET_EDGREINF_TOOLTIP;Reinforce or reduce the action of the first level, do the opposite to the second level, and leave the rest unchanged. +!TP_WAVELET_EDGTHRESH;Detail +!TP_WAVELET_EDGTHRESH_TOOLTIP;Change the repartition between the first levels and the others. The higher the threshold the more the action is centred on the first levels. Be careful with negative values, they increase the action of high levels and can introduce artifacts. +!TP_WAVELET_EDRAD;Radius +!TP_WAVELET_EDRAD_TOOLTIP;This radius adjustment is very different from those in other sharpening tools. Its value is compared to each level through a complex function. In this sense, a value of zero still has an effect. +!TP_WAVELET_EDSL;Threshold Sliders +!TP_WAVELET_EDTYPE;Local contrast method +!TP_WAVELET_EDVAL;Strength +!TP_WAVELET_FINAL;Final Touchup +!TP_WAVELET_FINEST;Finest +!TP_WAVELET_HIGHLIGHT;Highlight luminance range +!TP_WAVELET_HS1;Whole luminance range +!TP_WAVELET_HS2;Shadows/Highlights +!TP_WAVELET_HUESKIN;Skin hue +!TP_WAVELET_HUESKIN_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_HUESKY;Sky hue +!TP_WAVELET_HUESKY_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_INF;Below or equal the level +!TP_WAVELET_ITER;Delta balance levels +!TP_WAVELET_ITER_TOOLTIP;Left: increase low levels and reduce high levels,\nRight: reduce low levels and increase high levels. +!TP_WAVELET_LABEL;Wavelet levels +!TP_WAVELET_LARGEST;Coarsest +!TP_WAVELET_LEVCH;Chromaticity +!TP_WAVELET_LEVELS;Wavelet levels +!TP_WAVELET_LEVELS_TOOLTIP;Choose the number of detail levels the image is to be decomposed into. More levels require more RAM and require a longer processing time. +!TP_WAVELET_LEVF;Contrast +!TP_WAVELET_LEVLABEL;Preview maximum possible levels = %1 +!TP_WAVELET_LEVONE;Level 2 +!TP_WAVELET_LEVTWO;Level 3 +!TP_WAVELET_LEVZERO;Level 1 +!TP_WAVELET_LINKEDG;Link with Edge Sharpness' Strength +!TP_WAVELET_LIPST;Enhanced algorithm +!TP_WAVELET_LIPST_TOOLTIP;This algorithm uses Lipschitz regularity to increase edge detection quality at a cost of increased processing time and memory requirements. +!TP_WAVELET_LOWLIGHT;Shadow luminance range +!TP_WAVELET_MEDGREINF;First level +!TP_WAVELET_MEDILEV;Edge detection +!TP_WAVELET_MEDI;Reduce artifacts in blue sky +!TP_WAVELET_NEUTRAL;Neutral +!TP_WAVELET_NOISE;Denoise and Refine +!TP_WAVELET_NOIS;Denoise +!TP_WAVELET_ONE;One level +!TP_WAVELET_OPACITYWL;Final local contrast +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify final local contrast in function of last local contrast (absciss) for all levels decomposition\nTake into account: \na)contrast levels \nb)edge sharpness \nc)contrast balance\nd)decomposition-recomposition\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 200..1000)\n66% absciss represents standard deviation of local contrast (real value about 1000..2000)\n100% represents maximum (real value about 5000..13000) +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify the final local contrast at the end of the wavelet treatment.\n\nThe left side represents the smallest local contrast, progressing to the largest local contrast on the right. +!TP_WAVELET_OPACITYW;Contrast balance d/v-h curve +!TP_WAVELET_OPACITY;Opacity Blue-Yellow +!TP_WAVELET_PASTEL;Pastel chromaticity +!TP_WAVELET_PREVIEWBACK;Background +!TP_WAVELET_PREVIEWLEVELS;Preview +!TP_WAVELET_RE1;Reinforced +!TP_WAVELET_RE2;Unchanged +!TP_WAVELET_RE3;Reduced +!TP_WAVELET_RESCHRO;Chromaticity +!TP_WAVELET_RESCONH;Highlights +!TP_WAVELET_RESCON;Shadows +!TP_WAVELET_RESID;Residual image +!TP_WAVELET_SAT;Saturated chromaticity +!TP_WAVELET_SETTINGS;Wavelet Settings +!TP_WAVELET_SKIN;Skin targetting/protection +!TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected. +!TP_WAVELET_SKY;Sky targetting/protection +!TP_WAVELET_SKY_TOOLTIP;At -100 sky-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 sky-tones are protected while all other tones are affected. +!TP_WAVELET_STRENGTH;Strength +!TP_WAVELET_STREN;Strength +!TP_WAVELET_SUPE;Extra +!TP_WAVELET_SUP;Above the level +!TP_WAVELET_THRESHOLD2;Shadow levels +!TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels between 9 and 9 minus the value will be affected by the shadow luminance range. Other levels will be fully treated. The highest level possible is limited by the highlight level value (9 minus highlight level value). +!TP_WAVELET_THRESHOLD;Highlight levels +!TP_WAVELET_THRESHOLD_TOOLTIP;Only levels beyond the chosen value will be affected by the highlight luminance range. Other levels will be fully treated. The chosen value here limits the highest possible value of the shadow levels. +!TP_WAVELET_THRH;Highlights threshold +!TP_WAVELET_THR;Shadows threshold +!TP_WAVELET_TILESBIG;Big tiles +!TP_WAVELET_TILESFULL;Full image +!TP_WAVELET_TILESIZE;Tiling method +!TP_WAVELET_TILESLIT;Little tiles +!TP_WAVELET_TILES_TOOLTIP;Processing the full image leads to better quality and is the recommended option, while using tiles is a fall-back solution for users with little RAM. Refer to RawPedia for memory requirements. +!TP_WAVELET_TMHIGH;High +!TP_WAVELET_TMLOWHIGH;Low+High +!TP_WAVELET_TMNONE;None +!TP_WAVELET_TMSTD;Standard +!TP_WAVELET_TMSTRENGTH;Compression strength +!TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image. When the value is different from 0, the Strength and Gamma sliders of the Tone Mapping tool in the Exposure tab will become grayed out. +!TP_WAVELET_TMTYPE;Compression method +!TP_WAVELET_TON;Toning +!TP_WAVELET_daub2;D2 - low +!TP_WAVELET_daub4;D4 - standard +!TP_WAVELET_daub6;D6 - standard plus +!TP_WAVELET_daub10;D10 - medium +!TP_WAVELET_daub14;D14 - high +!TP_WBALANCE_CLOUDY;Cloudy +!TP_WBALANCE_DAYLIGHT;Daylight (sunny) +!TP_WBALANCE_EQBLUERED;Blue/Red equalizer +!TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behavior of "white balance" by modulating the blue/red balance.\nThis can be useful when shooting conditions:\na) are far from the standard illuminant (e.g. underwater),\nb) are far from conditions where calibrations were performed,\nc) where the matrices or ICC profiles are unsuitable. +!TP_WBALANCE_FLASH55;Leica +!TP_WBALANCE_FLASH60;Standard, Canon, Pentax, Olympus +!TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta +!TP_WBALANCE_FLASH_HEADER;Flash +!TP_WBALANCE_FLUO1;F1 - Daylight +!TP_WBALANCE_FLUO2;F2 - Cool White +!TP_WBALANCE_FLUO3;F3 - White +!TP_WBALANCE_FLUO4;F4 - Warm White +!TP_WBALANCE_FLUO5;F5 - Daylight +!TP_WBALANCE_FLUO6;F6 - Lite White +!TP_WBALANCE_FLUO7;F7 - D65 Daylight Simulator +!TP_WBALANCE_FLUO8;F8 - D50 / Sylvania F40 Design +!TP_WBALANCE_FLUO9;F9 - Cool White Deluxe +!TP_WBALANCE_FLUO10;F10 - Philips TL85 +!TP_WBALANCE_FLUO11;F11 - Philips TL84 +!TP_WBALANCE_FLUO12;F12 - Philips TL83 +!TP_WBALANCE_FLUO_HEADER;Fluorescent +!TP_WBALANCE_GTI;GTI +!TP_WBALANCE_HMI;HMI +!TP_WBALANCE_JUDGEIII;JudgeIII +!TP_WBALANCE_LAMP_HEADER;Lamp +!TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 +!TP_WBALANCE_LED_HEADER;LED +!TP_WBALANCE_LED_LSI;LSI Lumelex 2040 +!TP_WBALANCE_SHADE;Shade +!TP_WBALANCE_SOLUX35;Solux 3500K +!TP_WBALANCE_SOLUX41;Solux 4100K +!TP_WBALANCE_SOLUX47;Solux 4700K (vendor) +!TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) +!TP_WBALANCE_TUNGSTEN;Tungsten +!TP_WBALANCE_WATER1;UnderWater 1 +!TP_WBALANCE_WATER2;UnderWater 2 +!TP_WBALANCE_WATER_HEADER;UnderWater +!ZOOMPANEL_100;(100%) +!ZOOMPANEL_NEWCROPWINDOW;Open (new) detail window +!ZOOMPANEL_ZOOM100;Zoom to 100%\nShortcut: z +!ZOOMPANEL_ZOOMFITCROPSCREEN;Fit crop to screen\nShortcut: Alt-f +!ZOOMPANEL_ZOOMFITSCREEN;Fit whole image to screen\nShortcut: f +!ZOOMPANEL_ZOOMIN;Zoom In\nShortcut: + +!ZOOMPANEL_ZOOMOUT;Zoom Out\nShortcut: - diff --git a/rtdata/languages/README b/rtdata/languages/README new file mode 100644 index 000000000..bffdb994b --- /dev/null +++ b/rtdata/languages/README @@ -0,0 +1,66 @@ +This is the directory where all translations should go. + +Translations are loaded for a given term at three levels: + + 1) default + 2) + 3) + +Developers who are adding a new feature should add new strings *only* to +default. This file should be comprised of basic English text. It will be used +in the event that there are no more specific languages specified. Once you +have modified default, you should run ./tools/generateTranslationDiffs (Bash +script) which will re-generate the localizations with commented out additions +which you have just added. + +Translators should in general implement the file. This is the +generic translation for a given language; for instance, 'French', 'German', +'Norsk', etc. If a string exists in this file (and the user has specified this +language), then RawTherapee will override the value in default with the value +in . Please note that the filename for this file must not contain +any spaces. + +In some situations, translations may differ based on region, locale, etc. A +good example of this is the difference in spelling between 'color' (American +English) and 'colour' (British English). In this case, the vast majority of +strings are identical between English and English (UK); however, to keep the +proper spelling in Britain, we have a locale file called 'English (UK)' which +contains the differences between the two. RawTherapee uses locale files when: + a) The user has selected a language which has a space in the file name + b) There is another file which is identical to the locale file up until the + space (i.e., 'English' to the locale file 'English (UK)'). + +If a locale file is used, it is applied in the same manner as is to +default. The locale will override any keys present from the ones in the +language file (and in turn, the default). + +After the generateTranslationDiffs has been run, all untranslated terms for +a given language/locale will exist at the end of the file, prefixed by a ! +comment marker. Translators should go through this section of the file and +translate all terms which they can. After you have translated a line, just +remove the ! comment marker. Comments may be included using the #xx comment +marker, where xx is a numeric prefix used to make sure automated sorting keeps +comments in the right order, e.g.: + #00 Comment line 1... + #01 Line 2... + #02 3, etc. + +To create a file with only Latin characters from a non-Latin one, you can use +sed with the "y" command. For example, to create a latin-only "Polish (Latin +Characters)" file from the non-latin "Polish" one: + sed 'y/ĄĆĘŁŃÓŚŹŻąćęłńóśźż/ACELNOSZZacelnoszz/' < Polish > "Polish (Latin Characters)" + +You can use this Wikipedia "Character sets" category page to help you find all +the characters in the language file you want to convert into Latin-only: + http://en.wikipedia.org/wiki/Category:Character_sets + +To convert all line terminators in all language files to CRLF (dos/mac/unix) +you can use vim: + a) cd rtdata/languages + vim + b) In vim, type: + :set ffs=dos + :args * + :argdo w + c) vim will process all language files. Once done, you can close it: + :q diff --git a/rtdata/languages/Russian b/rtdata/languages/Russian new file mode 100644 index 000000000..701fa912e --- /dev/null +++ b/rtdata/languages/Russian @@ -0,0 +1,1859 @@ +#01 2007-12-23 ArtDen +#02 2008-07-20 Denis Artemov +#03 2009-02-16 Kvark +#04 2010-02-26 Sergey Smirnov AKA smiserg +#05 2010-11-01 Ilia Popov +#06 2012-07-17 Roman Milanskij +#07 2014-02-12 Kostia (Kildor) Romanov + +ABOUT_TAB_BUILD;Версия +ABOUT_TAB_CREDITS;Авторы +ABOUT_TAB_LICENSE;Лицензия +ABOUT_TAB_RELEASENOTES;Примечания к выпуску +ABOUT_TAB_SPLASH;Заставка +ADJUSTER_RESET_TO_DEFAULT;Сбросить настройки +BATCHQUEUE_AUTOSTART;Автостарт +BATCHQUEUE_DESTFILENAME;Имя файла и путь к нему +BATCH_PROCESSING;Пакетная обработка +CURVEEDITOR_CURVES;Кривые +CURVEEDITOR_CURVE;Кривая +CURVEEDITOR_CUSTOM;Произвольный +CURVEEDITOR_DARKS;Темные тона +CURVEEDITOR_HIGHLIGHTS;Света +CURVEEDITOR_LIGHTS;Светлые тона +CURVEEDITOR_LINEAR;Линейная +CURVEEDITOR_LOADDLGLABEL;Загрузить кривую... +CURVEEDITOR_MINMAXCPOINTS;Мин/Макс контрольные точки +CURVEEDITOR_NURBS;Управляющая 3d-сетка +CURVEEDITOR_PARAMETRIC;Параметрический +CURVEEDITOR_SAVEDLGLABEL;Сохранить кривую... +CURVEEDITOR_SHADOWS;Тени +CURVEEDITOR_TOOLTIPCOPY;Скопировать текущую кривую в буфер обмена +CURVEEDITOR_TOOLTIPLINEAR;Выставить линейную тоновую кривую +CURVEEDITOR_TOOLTIPLOAD;Загрузить тоновую кривую +CURVEEDITOR_TOOLTIPPASTE;Вставить кривую из буфера обмена +CURVEEDITOR_TOOLTIPSAVE;Сохранить тоновую кривую +CURVEEDITOR_TYPE;Тип: +DIRBROWSER_FOLDERS;Папки +EDITWINDOW_TITLE;Редактор +EXIFFILTER_APERTURE;Диафрагма +EXIFFILTER_CAMERA;Камера +EXIFFILTER_EXPOSURECOMPENSATION;Компенсация экспозиции (EV) +EXIFFILTER_FILETYPE;Тип фильтра +EXIFFILTER_FOCALLEN;Фокусное расстояние +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Объектив +EXIFFILTER_METADATAFILTER;Включить фильтры метаданных +EXIFFILTER_SHUTTER;Выдержка +EXIFPANEL_ADDEDITHINT;Добавить новый тэг или редактировать существующий +EXIFPANEL_ADDEDIT;Добавить +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Ввести значение +EXIFPANEL_ADDTAGDLG_SELECTTAG;Выбрать тег +EXIFPANEL_ADDTAGDLG_TITLE;Добавить/редактировать тег +EXIFPANEL_KEEPHINT;Сохранять выбранные теги при записи файла +EXIFPANEL_KEEP;Записать +EXIFPANEL_REMOVEHINT;Удалять выбранные теги при записи файла +EXIFPANEL_REMOVE;Удалить +EXIFPANEL_RESETALLHINT;Сбросить все теги в первоначальные значения +EXIFPANEL_RESETALL;Сбросить все +EXIFPANEL_RESETHINT;Сбросить выбранные теги в первоначальные значения +EXIFPANEL_RESET;Сбросить +EXIFPANEL_SUBDIRECTORY;Подкаталог +EXPORT_BYPASS_ALL;Выделить все / Снять выделение +EXPORT_BYPASS_DEFRINGE;Пропустить подавление ореолов +EXPORT_BYPASS_DIRPYRDENOISE;Пропустить подавление шума +EXPORT_BYPASS_DIRPYREQUALIZER;Пропустить контраст в зависимости от детализации +EXPORT_BYPASS_RAW_CA;Пропустить [raw] коррекцию хроматических аберраций +EXPORT_BYPASS_RAW_CCSTEPS;Пропустить [raw] подавление ложных цветов +EXPORT_BYPASS_RAW_DCB_ENHANCE;Пропустить [raw] расширенный DCB +EXPORT_BYPASS_RAW_DCB_ITERATIONS;Пропустить [raw] DCB-проходы +EXPORT_BYPASS_RAW_DF;Пропустить [raw] Темновой кадр +EXPORT_BYPASS_RAW_FF;Пропустить [raw] Плоское поле +EXPORT_BYPASS_RAW_GREENTHRESH;Пропустить [raw] Уравновешивание зеленого +EXPORT_BYPASS_RAW_LINENOISE;Пропустить [raw] Фильтр линейного шума +EXPORT_BYPASS_RAW_LMMSE_ITERATIONS;Пропустить [raw] шаги LMMSE улучшения +EXPORT_BYPASS_SHARPENEDGE;Пропустить контурное повышение резкости +EXPORT_BYPASS_SHARPENING;Пропустить повышение резкости +EXPORT_BYPASS_SHARPENMICRO;Пропустить микроконтраст +EXPORT_BYPASS_SH_HQ;Пропустить настройки теней/пересветов +EXPORT_FASTEXPORTOPTIONS;Настройки быстрого экспорта +EXPORT_INSTRUCTIONS;Настройки быстрого экспорта помогают экономить время и ресурсы, затрачиваемые на установку настроек обработки и запускать очередь обработки, используя вместо этого настройки быстрого экспорта. Этот метод рекомендуется для быстрого создания изображений с низким разрешением, когда скорость обработки в приоритете или когда нужно отмасштабировать одно или несколько изображений без внесения изменений в их сохранённые параметры обработки. +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_BROWSEPATHHINT;Введите путь для перехода.\nCtrl-O для перехода на диалог ввода текста.\nEnter / Ctrl-Enter (в обозревателе файлов) для перехода;\n\nЯрлыки путей:\n ~ - домашняя папка пользователя\n ! - папка пользователя с изображениями +FILEBROWSER_CACHECLEARFROMFULL;Удалить из кэша - полностью +FILEBROWSER_CACHECLEARFROMPARTIAL;Удалить из кэша - частично +FILEBROWSER_CACHE;Кэш +FILEBROWSER_CLEARPROFILE;Удалить профиль +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_COPYPROFILE;Скопировать профиль +FILEBROWSER_CURRENT_NAME;Текущее имя: +FILEBROWSER_DARKFRAME;Темновой кадр +FILEBROWSER_DELETEDLGLABEL;Подтверждение удаления файла +FILEBROWSER_DELETEDLGMSGINCLPROC;Вы уверены, что хотите удалить %1 выделенных файлов, включая обработанные версии? +FILEBROWSER_DELETEDLGMSG;Вы уверены, что хотите удалить %1 выбранный(ых) файл(ов)? +FILEBROWSER_EMPTYTRASHHINT;Удалить файлы из корзины без возможности восстановления +FILEBROWSER_EMPTYTRASH;Очистить корзину +FILEBROWSER_EXEC_CPB;Создание собственного профиля +FILEBROWSER_EXTPROGMENU;Открыть с помощью +FILEBROWSER_FLATFIELD;Плоское поле +FILEBROWSER_MOVETODARKFDIR;Переместить в папку темновых кадров +FILEBROWSER_MOVETOFLATFIELDDIR;Переместить в папку с файлами плоских полей +FILEBROWSER_NEW_NAME;Новое имя: +FILEBROWSER_OPENDEFAULTVIEWER;Программа просмотра в Windows по умолчанию (после обработки) +FILEBROWSER_PARTIALPASTEPROFILE;Частичная вставка +FILEBROWSER_PASTEPROFILE;Вставить профиль +FILEBROWSER_POPUPCANCELJOB;Отменить задание +FILEBROWSER_POPUPCOLORLABEL0;Пометка: нет +FILEBROWSER_POPUPCOLORLABEL1;Пометка: Красным +FILEBROWSER_POPUPCOLORLABEL2;Пометка: Желтым +FILEBROWSER_POPUPCOLORLABEL3;Пометка: Зеленым +FILEBROWSER_POPUPCOLORLABEL4;Пометка: Синим +FILEBROWSER_POPUPCOLORLABEL5;Пометка: Фиолетовым +FILEBROWSER_POPUPCOLORLABEL;Цветовая пометка +FILEBROWSER_POPUPCOPYTO;Скопировать в... +FILEBROWSER_POPUPFILEOPERATIONS;Действия с файлами +FILEBROWSER_POPUPMOVEEND;Переместить в конец очереди +FILEBROWSER_POPUPMOVEHEAD;Переместить в начало очереди +FILEBROWSER_POPUPMOVETO;Переместить в... +FILEBROWSER_POPUPOPENINEDITOR;Открыть в редакторе +FILEBROWSER_POPUPOPEN;Открыть +FILEBROWSER_POPUPPROCESSFAST;Поставить в очередь (Быстрый экспорт) +FILEBROWSER_POPUPPROCESS;Поместить в очередь на обработку +FILEBROWSER_POPUPPROFILEOPERATIONS;Обработка операций профиля +FILEBROWSER_POPUPRANK1;Рейтинг 1 * +FILEBROWSER_POPUPRANK2;Рейтинг 2 ** +FILEBROWSER_POPUPRANK3;Рейтинг 3 *** +FILEBROWSER_POPUPRANK4;Рейтинг 4 **** +FILEBROWSER_POPUPRANK5;Рейтинг 5 ***** +FILEBROWSER_POPUPRANK;Рейтинг +FILEBROWSER_POPUPREMOVEINCLPROC;Удалить с диска и пакетной обработки +FILEBROWSER_POPUPREMOVE;Удалить с диска +FILEBROWSER_POPUPRENAME;Переименовать +FILEBROWSER_POPUPSELECTALL;Выбрать все +FILEBROWSER_POPUPTRASH;Удалить в корзину +FILEBROWSER_POPUPUNRANK;Снять рейтинг +FILEBROWSER_POPUPUNTRASH;Удалить из корзины +FILEBROWSER_QUERYBUTTONHINT;Очистить поисковой запрос +FILEBROWSER_QUERYHINT;Введите часть искомого имени файла или список разделённый запятыми (пробелы значимы).\nНапример 1001,1005,1042 \n\nCtrl-F для переключения на диалог поиска текста.\nEnter для начала поиска.\nShift-Esc для снятия фокуса +FILEBROWSER_QUERYLABEL; Найти: +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_RENAMEDLGMSG;Переименовать файл "%1" в: +FILEBROWSER_SELECTDARKFRAME;Выбрать темновой кадр... +FILEBROWSER_SELECTFLATFIELD;Выбрать плоское поле... +FILEBROWSER_SHOWCOLORLABEL1HINT;Показать изображения, отмеченные Красным.\nГорячая клавиша: Alt-1 +FILEBROWSER_SHOWCOLORLABEL2HINT;Показать изображения, отмеченные Желтым.\nГорячая клавиша: Alt-2 +FILEBROWSER_SHOWCOLORLABEL3HINT;Показать изображения, отмеченные Зеленым.\nГорячая клавиша: Alt-3 +FILEBROWSER_SHOWCOLORLABEL4HINT;Показать изображения, отмеченные Синим.\nГорячая клавиша: Alt-4 +FILEBROWSER_SHOWCOLORLABEL5HINT;Показать изображения, отмеченные Фиолетовым.\nГорячая клавиша: Alt-5 +FILEBROWSER_SHOWDIRHINT;Сбросить все фильтры.\nГорячая клавиша: d +FILEBROWSER_SHOWEDITEDHINT;Показать измененные изображения.\nГорячая клавиша: 7 +FILEBROWSER_SHOWEDITEDNOTHINT;Показать не измененные изображения.\nГорячая клавиша: 6 +FILEBROWSER_SHOWEXIFINFO;Показать информацию EXIF.\nГорячая клавиша: i\n\nГорячая клавиша в режиме Одиночного редактора: Alt-i +FILEBROWSER_SHOWRANK1HINT;Показать изображения с рейтингом 1.\nГорячая клавиша: 1 +FILEBROWSER_SHOWRANK2HINT;Показать изображения с рейтингом 2.\nГорячая клавиша: 2 +FILEBROWSER_SHOWRANK3HINT;Показать изображения с рейтингом 3.\nГорячая клавиша: 3 +FILEBROWSER_SHOWRANK4HINT;Показать изображения с рейтингом 4.\nГорячая клавиша: 4 +FILEBROWSER_SHOWRANK5HINT;Показать изображения с рейтингом 5.\nГорячая клавиша: 5 +FILEBROWSER_SHOWRECENTLYSAVEDHINT;Показать изображения, сохранённые недавно.\nГорячая клавиша: Alt-7 +FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Показать изображения, сохранённые давно.\nГорячая клавиша: Alt-6 +FILEBROWSER_SHOWTRASHHINT;Показать содержимое корзины.\nГорячая клавиша: Ctrl-t +FILEBROWSER_SHOWUNCOLORHINT;Показать изображения без цветовой метки.\nГорячая клавиша: Alt-0 +FILEBROWSER_SHOWUNRANKHINT;Показать изображения без рейтинга\nГорячая клавиша: 0 +FILEBROWSER_STARTPROCESSINGHINT;Запуск обработки помещенных в очередь изображений +FILEBROWSER_STARTPROCESSING;Начать обработку +FILEBROWSER_STOPPROCESSINGHINT;Отмена обработки изображений +FILEBROWSER_STOPPROCESSING;Остановить обработку +FILEBROWSER_THUMBSIZE;Размер эскиза +FILEBROWSER_TOOLTIP_STOPPROCESSING;Автоматически запускать обработку при добавлении файла в очередь +FILEBROWSER_UNRANK_TOOLTIP;Удалить рейтинг\nГорячая клавиша: Shift-~ +FILEBROWSER_ZOOMINHINT;Увеличить размер эскиза\nГорячая клавиша: +\n\nГорячая клавиша в режиме Одиночного редактора: Alt-+ +FILEBROWSER_ZOOMOUTHINT;Уменьшить размер эскиза\nГорячая клавиша: +\n\nГорячая клавиша в режиме Одиночного редактора: Alt-- +GENERAL_ABOUT;О программе +GENERAL_AFTER;После +GENERAL_AUTO;Автоматический +GENERAL_BEFORE;До +GENERAL_CANCEL;Отмена +GENERAL_CLOSE;Закрыть +GENERAL_DISABLED;Выключено +GENERAL_DISABLE;Выключить +GENERAL_ENABLED;Включено +GENERAL_ENABLE;Включить +GENERAL_FILE;Файл +GENERAL_LANDSCAPE;Альбомный +GENERAL_NA;Н/Д +GENERAL_NONE;Нет +GENERAL_NO;Нет +GENERAL_OK;OK +GENERAL_PORTRAIT;Портретный +GENERAL_SAVE;Сохранить +GENERAL_UNCHANGED;(не менялось) +GENERAL_WARNING;Внимание +HISTOGRAM_TOOLTIP_BAR;Показать/скрыть панель отображения RGB\nНажмите правую кнопку мыши на предпросмотре изображения, чтобы заблокировать/разблокировать его +HISTOGRAM_TOOLTIP_B;Показать/скрыть синий канал гистограммы +HISTOGRAM_TOOLTIP_CHRO;Показать/скрыть хроматическую гистограмму +HISTOGRAM_TOOLTIP_FULL;Переключить полную (вкл) или отмасштабированную (выкл) гистограмму +HISTOGRAM_TOOLTIP_G;Показать/скрыть зелёный канал гистограммы +HISTOGRAM_TOOLTIP_L;Показать/скрыть CIELAB канал гистограммы +HISTOGRAM_TOOLTIP_RAW;Показать/скрыть Raw гистограмму +HISTOGRAM_TOOLTIP_R;Показать/скрыть красный канал гистограммы +HISTORY_CHANGED;Изменено +HISTORY_CUSTOMCURVE;Пользовательская кривая +HISTORY_DELSNAPSHOT;Удалить +HISTORY_FROMCLIPBOARD;Из буфера обмена +HISTORY_LABEL;История +HISTORY_MSG_1;Фото загружено +HISTORY_MSG_2;Профиль загружен +HISTORY_MSG_3;Профиль изменён +HISTORY_MSG_4;Просмотр истории +HISTORY_MSG_5;Яркость +HISTORY_MSG_6;Контраст +HISTORY_MSG_7;Уровень чёрного +HISTORY_MSG_8;Компенсация экспозиции +HISTORY_MSG_9;Сжатие засветов +HISTORY_MSG_10;Сжатие теней +HISTORY_MSG_11;Тоновая кривая 1 +HISTORY_MSG_12;Автоматические уровни +HISTORY_MSG_13;Обрезка экспозиции +HISTORY_MSG_14;Lab: Яркость +HISTORY_MSG_15;Lab: Контраст +HISTORY_MSG_16;Освещенность: Уровень чёрного +HISTORY_MSG_17;Освещенность: Сжатие светов +HISTORY_MSG_18;Освещенность: Сжатие теней +HISTORY_MSG_19;Кривая 'L' +HISTORY_MSG_20;Резкость +HISTORY_MSG_21;Резкость: Радиус +HISTORY_MSG_22;Резкость: Величина +HISTORY_MSG_23;Резкость: Порог +HISTORY_MSG_24;Резкость: Только контуры +HISTORY_MSG_25;Резкость: Радиус определения контуров +HISTORY_MSG_26;Резкость: Допуск определения контуров +HISTORY_MSG_27;Резкость: Управление ореолом +HISTORY_MSG_28;Резкость: Величина ореола +HISTORY_MSG_29;Резкость: Метод +HISTORY_MSG_30;Деконволюция: Радиус +HISTORY_MSG_31;Деконволюция: Значение +HISTORY_MSG_32;Деконволюция: Ослабление +HISTORY_MSG_33;Деконволюция: Повторы +HISTORY_MSG_34;ПКО: коррекция искажения +HISTORY_MSG_35;ПКО: коррекция виньетирования +HISTORY_MSG_36;ПКО: коррекция ХА +HISTORY_MSG_37;Автоматические уровни +HISTORY_MSG_38;Метод определения баланса белого +HISTORY_MSG_39;Баланс белого: температура +HISTORY_MSG_40;Баланс белого: оттенок +HISTORY_MSG_41;Режим тоновой кривой 1 +HISTORY_MSG_42;Тоновая кривая 2 +HISTORY_MSG_43;Режим тоновой кривой 2 +HISTORY_MSG_44;Удаление шума: радиус +HISTORY_MSG_45;Удаление шума: чувств. к границам +HISTORY_MSG_46;Удаление цв. шума +HISTORY_MSG_47;Смешение ICC светов с матрицей +HISTORY_MSG_48;Использование тональной кривой ICC +HISTORY_MSG_49;Источник цвета DCP +HISTORY_MSG_50;Тени/Света +HISTORY_MSG_51;Т/С: Света +HISTORY_MSG_52;Т/С: Тени +HISTORY_MSG_53;Т/С: Уровень светов +HISTORY_MSG_54;Т/С: Уровень теней +HISTORY_MSG_55;Т/С: Локальный контраст +HISTORY_MSG_56;Т/С: Радиус +HISTORY_MSG_57;Грубый поворот +HISTORY_MSG_58;Горизонтальное отражение +HISTORY_MSG_59;Вертикальное отражение +HISTORY_MSG_60;Поворот +HISTORY_MSG_61;Автозаполнение +HISTORY_MSG_62;Коррекция искажений оптики +HISTORY_MSG_63;Снимок выбран +HISTORY_MSG_64;Кадрирование +HISTORY_MSG_65;Коррекция ХА +HISTORY_MSG_66;Восстановление пересветов +HISTORY_MSG_67;ВП: Величина восстановления +HISTORY_MSG_68;ВП: Способ восстановления +HISTORY_MSG_69;Рабочая цветовая модель +HISTORY_MSG_70;Выходная цветовая модель +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;Масштаб: Данные +HISTORY_MSG_79;Масштаб: Ширина +HISTORY_MSG_80;Масштаб: Высота +HISTORY_MSG_81;Масштабирование +HISTORY_MSG_82;Изменение профиля +HISTORY_MSG_83;Т/С: Маска резкости +HISTORY_MSG_84;Коррекция перспективы +HISTORY_MSG_85;Профиль коррекции объектива +HISTORY_MSG_86;Кривая RGB: Яркость +HISTORY_MSG_87;Импульсное подавление шума +HISTORY_MSG_88;Импульсное ПШ: порог +HISTORY_MSG_89;Подавление шума +HISTORY_MSG_90;ПШ - яркость +HISTORY_MSG_91;ПШ - цветность +HISTORY_MSG_92;ПШ - гамма +HISTORY_MSG_93;КпУД: значение +HISTORY_MSG_94;Контраст по уровням деталей +HISTORY_MSG_95;Lab: Насыщенность +HISTORY_MSG_96;Кривая 'a' +HISTORY_MSG_97;Кривая 'b' +HISTORY_MSG_98;Демозаик +HISTORY_MSG_99;Фильтр горячих/битых пикселей +HISTORY_MSG_100;Насыщенность +HISTORY_MSG_101;HSV: Цветовой тон +HISTORY_MSG_102;HSV: Насыщенность +HISTORY_MSG_103;HSV: Яркость +HISTORY_MSG_104;Эквалайзер HSV +HISTORY_MSG_105;Подавление ореолов +HISTORY_MSG_106;Подавление ореолов: радиус +HISTORY_MSG_107;Подавление ореолов: порог +HISTORY_MSG_108;Порог компрессии засветов +HISTORY_MSG_109;Изменение размера рамки +HISTORY_MSG_110;Масштабирование относится к +HISTORY_MSG_111;Lab: Избегать сдвига цвета +HISTORY_MSG_112;--неиспользуемый-- +HISTORY_MSG_113;Lab: Защита тонов +HISTORY_MSG_114;Проходы DCB +HISTORY_MSG_115;Проходы подавления ложного цвета +HISTORY_MSG_116;Расширенная DCB +HISTORY_MSG_117;(raw) Коррекция красных ХА +HISTORY_MSG_118;(raw) Коррекция синих ХА +HISTORY_MSG_119;Фильтр линейного шума +HISTORY_MSG_120;Равновесие зеленого +HISTORY_MSG_121;(raw) Авто ХА +HISTORY_MSG_122;Авто темновой кадр +HISTORY_MSG_123;Файл темнового кадра +HISTORY_MSG_124;Коррекция баланса белого +HISTORY_MSG_125;Сохранение пересветов +HISTORY_MSG_126;Файл плоского поля +HISTORY_MSG_127;Автовыбор плоского поля +HISTORY_MSG_128;Радиус размытия плоского поля +HISTORY_MSG_129;Тип размытия плоского поля +HISTORY_MSG_130;Автоискажения +HISTORY_MSG_131;Подавление яркостного шума +HISTORY_MSG_132;Подавление цветового шума +HISTORY_MSG_133;Гамма +HISTORY_MSG_134;Свободная гамма +HISTORY_MSG_135;Свободная гамма +HISTORY_MSG_136;Крутизна гаммы +HISTORY_MSG_137;Ур. черного: Зеленый 1 +HISTORY_MSG_138;Ур. черного: Красный +HISTORY_MSG_139;Ур. черного: Синий +HISTORY_MSG_140;Ур. черного: Зеленый 2 +HISTORY_MSG_141;Ур. черного: Зеленые вместе +HISTORY_MSG_142;РК: Проходы +HISTORY_MSG_143;РК: Количество +HISTORY_MSG_144;Микроконтраст: Количество +HISTORY_MSG_145;Микроконтраст: Равномерность +HISTORY_MSG_146;Резкость контуров +HISTORY_MSG_147;РК: Только освещенность +HISTORY_MSG_148;Микроконтраст +HISTORY_MSG_149;Микроконтраст: матрица 3x3 +HISTORY_MSG_150;Пост-демозаик шумоподавление +HISTORY_MSG_151;Резонанс +HISTORY_MSG_152;Рез: Пастельные тона +HISTORY_MSG_153;Рез: Насыщенные тона +HISTORY_MSG_154;Рез: Сохр. оттенки кожи +HISTORY_MSG_155;Рез: Избегать сдвига цветов +HISTORY_MSG_156;Рез: Связь пастельных/насыщенных +HISTORY_MSG_157;Рез: Уровень пастельных/насыщенных +HISTORY_MSG_158;ТК: Интенсивность +HISTORY_MSG_159;ТК: Учет контуров +HISTORY_MSG_160;ТК: Масштаб +HISTORY_MSG_161;ТК: Перевзвешивание проходов +HISTORY_MSG_162;Тональная компрессия +HISTORY_MSG_163;Кривая RGB: Красный +HISTORY_MSG_164;Кривая RGB: Зелёный +HISTORY_MSG_165;Кривая RGB: Синий +HISTORY_MSG_166;Нейтральные уровни +HISTORY_MSG_167;--неиспользуемый-- +HISTORY_MSG_168;Кривая 'ЦЦ' +HISTORY_MSG_169;Кривая 'ЦО' +HISTORY_MSG_170;Рез: кривая +HISTORY_MSG_171;Кривая 'ЯЦ' +HISTORY_MSG_172;LAB: Ограничение 'ЯЦ' +HISTORY_MSG_173;ПШ: Детализация яркости +HISTORY_MSG_174;CIECAM02 +HISTORY_MSG_175;CAM02: Адаптация CAT02 +HISTORY_MSG_176;CAM02: Условия просмотра +HISTORY_MSG_177;CAM02: Яркость обстановки +HISTORY_MSG_178;CAM02: Яркость при просмотре +HISTORY_MSG_179;CAM02: Модель белой точки +HISTORY_MSG_180;CAM02: Яркость (J) +HISTORY_MSG_181;CAM02: Цветность (C) +HISTORY_MSG_182;CAM02: Автоматич. CAT02 +HISTORY_MSG_183;CAM02: Контраст (J) +HISTORY_MSG_184;CAM02: Окружение снимка +HISTORY_MSG_185;CAM02: Контроль диапазона +HISTORY_MSG_186;CAM02: Алгоритм +HISTORY_MSG_187;CAM02: Сохр. тонов красного и кожи +HISTORY_MSG_188;CAM02: Яркость (Q) +HISTORY_MSG_189;CAM02: Контраст (Q) +HISTORY_MSG_190;CAM02: Насыщенность (S) +HISTORY_MSG_191;CAM02: Красочность (M) +HISTORY_MSG_192;CAM02: Цвет (h) +HISTORY_MSG_193;CAM02: Тональная кривая 1 +HISTORY_MSG_194;CAM02: Тональная кривая 2 +HISTORY_MSG_195;CAM02: Тональная кривая 1 +HISTORY_MSG_196;CAM02: Тональная кривая 2 +HISTORY_MSG_197;CAM02: Кривая цвета +HISTORY_MSG_198;CAM02: Кривая цвета +HISTORY_MSG_199;CAM02: Выходная гистограмма +HISTORY_MSG_200;CAM02: Тональное отображение +HISTORY_MSG_201;ПШ: Цветность К,З +HISTORY_MSG_202;ПШ: Цветность С,Ж +HISTORY_MSG_203;ПШ: Метод +HISTORY_MSG_204;Шагов улучшения LMMSE +HISTORY_MSG_205;CAM02: Горячие/битые пиксели +HISTORY_MSG_206;CAT02: Автояркость сцены +HISTORY_MSG_207;Ореолы: Кривая цвета +HISTORY_MSG_208;ББ: Эквалайзер С/К +HISTORY_MSG_210;ГФ: Угол +HISTORY_MSG_211;Градиентный фильтр +HISTORY_MSG_212;ФВ: Сила +HISTORY_MSG_213;Фильтр виньетирования +HISTORY_MSG_214;Чёрный-и-Белый +HISTORY_MSG_215;Ч&Б: МК - Красный +HISTORY_MSG_216;Ч&Б: МК - Зелёный +HISTORY_MSG_217;Ч&Б: МК - Синий +HISTORY_MSG_218;Ч&Б: Гамма - Красный +HISTORY_MSG_219;Ч&Б: Гамма - Зелёный +HISTORY_MSG_220;Ч&Б: Гамма - Синий +HISTORY_MSG_221;Ч&Б: Фильтр цветов +HISTORY_MSG_222;Ч&Б: Пресеты +HISTORY_MSG_223;Ч&Б: МК - Оранжевый +HISTORY_MSG_224;Ч&Б: МК - Жёлтый +HISTORY_MSG_225;Ч&Б: МК - Циан +HISTORY_MSG_226;Ч&Б: МК - Магента +HISTORY_MSG_227;Ч&Б: МК - Фиолетовый +HISTORY_MSG_228;Ч&Б: Яркостный эквалайзер +HISTORY_MSG_229;Ч&Б: Яркостный эквалайзер +HISTORY_MSG_230;Ч&Б: Режим +HISTORY_MSG_231;Ч&Б: Кривая 'До' +HISTORY_MSG_232;Ч&Б: Тип кривой 'До' +HISTORY_MSG_233;Ч&Б: Кривая 'После' +HISTORY_MSG_234;Ч&Б: Тип кривой 'После' +HISTORY_MSG_235;Ч&Б: Автомиксер каналов +HISTORY_MSG_236;--неиспользуемый-- +HISTORY_MSG_237;Ч&Б: Миксер +HISTORY_MSG_238;ГФ: Растушёвка +HISTORY_MSG_239;ГФ: Сила +HISTORY_MSG_240;ГФ: Центр +HISTORY_MSG_241;ФВ: Растушёвка +HISTORY_MSG_242;ФВ: Радиус +HISTORY_MSG_243;Виньетирование: Радиус +HISTORY_MSG_244;Виньетирование: Сила +HISTORY_MSG_245;Виньетирование: Центр +HISTORY_MSG_246;Кривая 'CL' +HISTORY_MSG_247;Кривая 'LH' +HISTORY_MSG_248;Кривая 'HH' +HISTORY_MSG_249;КпУД: Порог +HISTORY_MSG_250;ПШ: Улучшенный +HISTORY_MSG_251;Ч&Б: Алгоритм +HISTORY_NEWSNAPSHOT;Добавить +HISTORY_NEWSNAPSHOT_TOOLTIP;Горячая клавиша: Alt-s +HISTORY_SNAPSHOTS;Снимки +HISTORY_SNAPSHOT;Снимок +IPTCPANEL_AUTHORSPOSITIONHINT;Название автора или авторов объекта (By-line Title). +IPTCPANEL_AUTHORSPOSITION;Позиция автора +IPTCPANEL_AUTHOR;Автор +IPTCPANEL_CAPTIONHINT;Текстовое описание данных (Caption - Abstract) +IPTCPANEL_CAPTIONWRITERHINT;Имя человека, участвовавшего в создании, изменении или редактировании изображения либо подписи (Writer - Editor). +IPTCPANEL_CAPTIONWRITER;Автор подписи +IPTCPANEL_CAPTION;Подпись +IPTCPANEL_CATEGORYHINT;Устанавливает тему изображения (Category) +IPTCPANEL_CATEGORY;Категория +IPTCPANEL_CITYHINT;Город (City). +IPTCPANEL_CITY;Город +IPTCPANEL_COPYHINT;Копировать данные IPTC в буфер обмена +IPTCPANEL_COPYRIGHTHINT;Любые предупреждения об авторских правах (Copyright Notice). +IPTCPANEL_COPYRIGHT;Авторские права +IPTCPANEL_COUNTRYHINT;Название страны/начального местоположения (Country - Primary Location Name). +IPTCPANEL_COUNTRY;Страна +IPTCPANEL_CREDITHINT;Лица и организации, осуществляющие какую либо поддержку изображения (Credit). +IPTCPANEL_CREDIT;Поддержка +IPTCPANEL_DATECREATEDHINT;Дата создания интеллектуального содержания изображения; Формат: ГГГГММДД (Date Created). +IPTCPANEL_DATECREATED;Дата создания +IPTCPANEL_EMBEDDEDHINT;Сбросить данные IPTC, встроенные в файл изображения +IPTCPANEL_EMBEDDED;Встроенный +IPTCPANEL_HEADLINEHINT;Подходящий для публикации краткий обзор содержимого изображения (Headline). +IPTCPANEL_HEADLINE;Заголовок +IPTCPANEL_INSTRUCTIONSHINT;Прочие редакторские инструкции об использовании изображения (Special Instructions). +IPTCPANEL_INSTRUCTIONS;Инструкции +IPTCPANEL_KEYWORDSHINT;Ключевые слова, используемые для поиска (Keywords). +IPTCPANEL_KEYWORDS;Ключевые слова +IPTCPANEL_PASTEHINT;Вставить данные IPTC из буфера обмена +IPTCPANEL_PROVINCEHINT;Провинция/штат (Province-State). +IPTCPANEL_PROVINCE;Провинция +IPTCPANEL_RESETHINT;Сбросить профиль на значения по умолчанию +IPTCPANEL_RESET;Сбросить +IPTCPANEL_SOURCEHINT;Первоначальный владелец интеллектуального содержания изображения (Source). +IPTCPANEL_SOURCE;Источник +IPTCPANEL_SUPPCATEGORIESHINT;Дополнительные уточнения темы изображения (Supplemental Categories). +IPTCPANEL_SUPPCATEGORIES;Доп. категории +IPTCPANEL_TITLEHINT;Простое описание изображения (Object Name). +IPTCPANEL_TITLE;Название +IPTCPANEL_TRANSREFERENCEHINT;Код, облегчающий отслеживание изображения при передаче в обработку на сторону (Original Transmission Reference). +IPTCPANEL_TRANSREFERENCE;Код поддержки +MAIN_BUTTON_FULLSCREEN;Полный экран +MAIN_BUTTON_NAVNEXT_TOOLTIP;Перейти к следующему изображению относительно открытого в редакторе\nГорячая клавиша: Shift+F4\n\nПерейти к следущему изображению относительно выбранного в файловом браузере\nгорячая клавиша F4 +MAIN_BUTTON_NAVPREV_TOOLTIP;Перейти к предыдущему изображению относительно открытого в редакторе\nгорячая клавиша: Shift+F4\n\nПерейти к предыдущему изображению относительно выбранного в файловом браузере\nгорячая клавиша F4 +MAIN_BUTTON_NAVSYNC_TOOLTIP;Синхронизировать файловый браузер с редактором чтоб показать эскиз открытого изображения и очистить фильтры браузера файлов\nгорячая клавиша: x\n\nТо же, но без очистки фильтров\nгорячая клавиша: y\n(Обратите внимание что эскиз открытого в редакторе файла не будет показан если не подпадает под текущие фильтры). +MAIN_BUTTON_PREFERENCES;Настройки +MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Поместить текущее изображение в очередь на обработку.\nГорячая клавиша Ctrl+B +MAIN_BUTTON_SAVE_TOOLTIP;Сохранить текущее изображение.\nГорячая клавиша Ctrl+S +MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Редактировать изображение во внешнем редакторе.\nГорячая клавиша Ctrl+E +MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Показать/скрыть все боковые панели.\nГорячая клавиша m +MAIN_BUTTON_UNFULLSCREEN;Оконный режим +MAIN_FRAME_BATCHQUEUE;Очередь обработки +MAIN_FRAME_BATCHQUEUE_TOOLTIP;Очередь пакетной обработки.\nГорячая клавиша Ctrl-F3 +MAIN_FRAME_EDITOR;Редактор +MAIN_FRAME_EDITOR_TOOLTIP;Редактор.\nГорячая клавиша Ctrl-F4 +MAIN_FRAME_FILEBROWSER;Файловый браузер +MAIN_FRAME_FILEBROWSER_TOOLTIP;Проводник.\nГорячая клавиша Ctrl-F2 +MAIN_FRAME_PLACES;Закладки +MAIN_FRAME_PLACES_ADD;Добавить +MAIN_FRAME_PLACES_DEL;Удалить +MAIN_FRAME_RECENT;Недавние папки +MAIN_MSG_ALREADYEXISTS;Файл уже существует. +MAIN_MSG_CANNOTLOAD;Невозможно загрузить изображение +MAIN_MSG_CANNOTSAVE;Ошибка при сохранении файла +MAIN_MSG_CANNOTSTARTEDITOR;не удалось запустить редактор. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Пожалуйста, установите правильный каталог в диалоге "Настройки". +MAIN_MSG_EMPTYFILENAME;Имя файла не указано! +MAIN_MSG_IMAGEUNPROCESSED;Для выполнения этой команды нужно, чтобы все изображения в очереди сперва были обработаны. +MAIN_MSG_NAVIGATOR;Навигатор +MAIN_MSG_OPERATIONCANCELLED;Операция отменена +MAIN_MSG_PATHDOESNTEXIST;Путь\n\n%1\n\nне существует. Пожалуйста, установите корректный путь в окне настроек. +MAIN_MSG_QOVERWRITE;Вы хотите перезаписать его? +MAIN_MSG_SETPATHFIRST;Прежде необходимо установить целевой каталог в настройках\nчтоб использовать эту функцию! +MAIN_MSG_WRITEFAILED;Не удалось записать\n\n"%1".\n\nУбедитесь, что каталог существует и у вас есть права на запись в него. +MAIN_TAB_COLOR;Цвет +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_EXPOSURE_TOOLTIP;Горячая клавиша: Alt-E +MAIN_TAB_FILTER;Фильтр +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_TOOLTIP;Горячая клавиша: Alt-T +MAIN_TOOLTIP_BACKCOLOR0;Фоновый цвет предпросмотра: Как в теме\nГорячая клавиша: 9 +MAIN_TOOLTIP_BACKCOLOR1;Фоновый цвет предпросмотра: Черный\nГорячая клавиша: 9 +MAIN_TOOLTIP_BACKCOLOR2;Фоновый цвет предпросмотра: Белый\nГорячая клавиша: 9 +MAIN_TOOLTIP_BEFOREAFTERLOCK;Заблокировать / Разблокировать предыдущий вид\n\nЗаблокировать: сохраняет предыдущий вид неизменным.\nПолезно для оценки общего эффекта от применения нескольких инструментов.\nК тому же, сравнения могут быть произведены на любом состоянии истории\n\nРазблокировать: предыдущий вид будет следовать сразу за следующим, показывая состояние изображения до применения текущего инструмента. +MAIN_TOOLTIP_INDCLIPPEDH;Индикатор пересветов.\nГорячая клавиша: < +MAIN_TOOLTIP_INDCLIPPEDS;Индикатор затемнений.\nГорячая клавиша: > +MAIN_TOOLTIP_PREVIEWB;Просмотреть канал синего.\nГорячая клавиша: b +MAIN_TOOLTIP_PREVIEWFOCUSMASK;Просмотреть Маску резкости.\nГорячая клавиша: Shift-F\n\nБолее точна на изображениях с небольшой глубиной резкости, малым шумом и при большем приближении изображения\n\nДля улучшения определения на шумных изображениях используйте на маленьком зуме 10-30%\n\nПредпросмотр просчитывается медленнее со включенной маской резкости. +MAIN_TOOLTIP_PREVIEWG;Просмотреть канал зеленого.\nГорячая клавиша: g +MAIN_TOOLTIP_PREVIEWL;Просмотреть Световую составляющую.\nГорячая клавиша: v\n\n0.299*R + 0.587*G + 0.114*B +MAIN_TOOLTIP_PREVIEWR;Просмотреть канал красного.\nГорячая клавиша: r +MAIN_TOOLTIP_QINFO;Информация об изображении.\nГорячая клавиша i +MAIN_TOOLTIP_SHOWHIDELP1;Показать/скрыть левую панель l +MAIN_TOOLTIP_SHOWHIDERP1;Показать/скрыть правую панель Alt-l +MAIN_TOOLTIP_SHOWHIDETP1;Показать/скрыть верхнюю панель Shift-L +MAIN_TOOLTIP_THRESHOLD;Порог +MAIN_TOOLTIP_TOGGLE;Включить режим "до/после".\nГорячая клавиша b +NAVIGATOR_XY_FULL;Ширина = %1, Высота = %2 +NAVIGATOR_XY_NA;x = н/д, y = н/д +OPTIONS_DEFIMG_MISSING;Профиль по умолчанию для не-raw снимков не найден или не установлен.\n\nПожалуйста, проверьте папку с профилями, она может отсутствовать или быть повреждена.\n\nБудут использованы значения по умолчанию. +OPTIONS_DEFRAW_MISSING;Профиль по умолчанию для raw снимков не найден или не установлен.\n\nПожалуйста, проверьте папку с профилями, она может отсутствовать или быть повреждена.\n\nБудут использованы значения по умолчанию. +PARTIALPASTE_BASICGROUP;Базовые настройки +PARTIALPASTE_CACORRECTION;Коррекция C/A +PARTIALPASTE_CHANNELMIXERBW;Чёрный-и-Белый +PARTIALPASTE_CHANNELMIXER;Смешение каналов +PARTIALPASTE_COARSETRANS;поворот на 90 гр. / отражение +PARTIALPASTE_COLORAPP;Модель Представления Цветов CIE 2002 +PARTIALPASTE_COLORGROUP;Настройка цвета +PARTIALPASTE_COMMONTRANSFORMPARAMS;Автозаполнение +PARTIALPASTE_COMPOSITIONGROUP;Параметры компоновки +PARTIALPASTE_CROP;Кадрирование +PARTIALPASTE_DARKFRAMEAUTOSELECT;Авто выбор темнового кадра +PARTIALPASTE_DARKFRAMEFILE;Файл темнового кадра +PARTIALPASTE_DEFRINGE;Подавление ореолов +PARTIALPASTE_DETAILGROUP;Настройки детализации +PARTIALPASTE_DIALOGLABEL;Частичная вставка параметров обработки +PARTIALPASTE_DIRPYRDENOISE;Подавление шумов +PARTIALPASTE_DIRPYREQUALIZER;Контраст по уровню деталей +PARTIALPASTE_DISTORTION;Дисторсия +PARTIALPASTE_EPD;Тональная компрессия +PARTIALPASTE_EVERYTHING;Всё +PARTIALPASTE_EXIFCHANGES;Изменения данных Exif +PARTIALPASTE_EXPOSURE;Экспозиция +PARTIALPASTE_FLATFIELDAUTOSELECT;Авто выбор ПП +PARTIALPASTE_FLATFIELDBLURRADIUS;Радиус размытия ПП +PARTIALPASTE_FLATFIELDBLURTYPE;Тип размытия ПП +PARTIALPASTE_FLATFIELDFILE;Файл плоского поля (ПП) +PARTIALPASTE_GRADIENT;Градиентный фильтр +PARTIALPASTE_HSVEQUALIZER;HSV Эквалайзер +PARTIALPASTE_ICMGAMMA;Выходная гамма +PARTIALPASTE_ICMSETTINGS;Параметры ICM +PARTIALPASTE_IMPULSEDENOISE;Подавление импульсного шума +PARTIALPASTE_IPTCINFO;Данные IPTC +PARTIALPASTE_LABCURVE;Настройка Lab +PARTIALPASTE_LENSGROUP;Параметры связанные с объективом +PARTIALPASTE_LENSPROFILE;Профиль коррекции объектива +PARTIALPASTE_METAGROUP;Настройка метаданных +PARTIALPASTE_PCVIGNETTE;Фильтр виньетирования +PARTIALPASTE_PERSPECTIVE;Перспектива +PARTIALPASTE_PREPROCESS_GREENEQUIL;Выравнивание зелёного канала +PARTIALPASTE_PREPROCESS_LINEDENOISE;Фильтр полосообразного шума +PARTIALPASTE_RAWCACORR_AUTO;Автоматическая коррекция ХА +PARTIALPASTE_RAWCACORR_CABLUE;Синие ХА +PARTIALPASTE_RAWCACORR_CARED;Красные ХА +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_LMMSEITERATIONS;Шагов улучшения LMMSE +PARTIALPASTE_RESIZE;Изменение размера +PARTIALPASTE_RGBCURVES;Кривые RGB +PARTIALPASTE_ROTATION;Поворот +PARTIALPASTE_SHADOWSHIGHLIGHTS;Тени/света +PARTIALPASTE_SHARPENEDGE;Края +PARTIALPASTE_SHARPENING;Повышение резкости +PARTIALPASTE_SHARPENMICRO;Микроконтраст +PARTIALPASTE_VIBRANCE;Резонанс +PARTIALPASTE_VIGNETTING;Коррекция виньетирования +PARTIALPASTE_WHITEBALANCE;Баланс белого +PREFERENCES_ADD;Добавить +PREFERENCES_APPLNEXTSTARTUP;нужен перезапуск +PREFERENCES_AUTOMONPROFILE;Использовать профиль основного монитора ОС +PREFERENCES_BATCH_PROCESSING;Пакетная обработка +PREFERENCES_BEHADDALLHINT;Выставить все параметры в режим Добавить.\nНастройки параметров в панели пакетной обработки будут дельтой к сохранённым данным +PREFERENCES_BEHADDALL;Всё в "Добавить" +PREFERENCES_BEHAVIOR;Поведение +PREFERENCES_BEHSETALLHINT;Выставить все параметры в режим Установить.\nНастройки параметров в панели пакетной обработки будут абсолютными, будут показаны используемые значения +PREFERENCES_BEHSETALL;Всё в "Установить" +PREFERENCES_BLACKBODY;Лампа накаливания +PREFERENCES_CACHECLEARALL;Удалить все +PREFERENCES_CACHECLEARPROFILES;Удалить параметры обработки +PREFERENCES_CACHECLEARTHUMBS;Удалить эскизы +PREFERENCES_CACHEMAXENTRIES;Максимальное число элементов в кэше +PREFERENCES_CACHEOPTS;Параметры кэширования +PREFERENCES_CACHETHUMBHEIGHT;Максимальная высота эскиза +PREFERENCES_CIEART;Оптимизация CIECAM02 +PREFERENCES_CIEART_LABEL;Использовать числа с плавающей запятой вместо двойной точности +PREFERENCES_CIEART_TOOLTIP;Если включено, вычисления CIECAM02 будут выполняться в формате плавающей запятой с одинарной точностью вместо использования двойной точности. Это обеспечит небольшое увеличение скорости с несущественной потерей качества. +PREFERENCES_CLIPPINGIND;Индикация пересветов/затемнений +PREFERENCES_CMETRICINTENT;Колориметрическое преобразование +PREFERENCES_CUSTPROFBUILDHINT;Исполняемый (или скриптовой) файл, вызываемый, когда для изображения должен быть сгенерирован новый профиль обработки.\n\nПуть к коммуникационному файлу (стиля *.ini) будет добавлен как параметр. Он содержит различные параметры, требуемые для скрипта и значения Exif фотографии для возможности генерации профиля основанной на правилах.\n\nВнимание: Необходимо использовать двойные кавычки при необходимости, если вы используете пути, содержащие пробелы. +PREFERENCES_CUSTPROFBUILDKEYFORMAT;Формат ключей +PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME;Имя +PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;TagID +PREFERENCES_CUSTPROFBUILDPATH;Путь к исполняемому файлу +PREFERENCES_CUSTPROFBUILD;Создание собственного профиля обработки +PREFERENCES_CUTOVERLAYBRUSH; Цвет/прозрачность маски обрезки +PREFERENCES_D50;5000K +PREFERENCES_D55;5500K +PREFERENCES_D60;6000K +PREFERENCES_D65;6500K +PREFERENCES_DARKFRAMEFOUND;Найдено +PREFERENCES_DARKFRAMESHOTS;снимков +PREFERENCES_DARKFRAMETEMPLATES;шаблонов +PREFERENCES_DARKFRAME;Темновой кадр +PREFERENCES_DATEFORMATHINT;Вы можете использовать следующие элементы форматирования:\n%y: год\n%m: месяц\n%d: день\n\nНапример, венгерский формат даты такой:\n%y/%m/%d +PREFERENCES_DATEFORMAT;Формат даты +PREFERENCES_DEFAULTLANG;Язык по умолчанию +PREFERENCES_DEFAULTTHEME;Тема по умолчанию +PREFERENCES_DIRDARKFRAMES;Каталог размещения темновых кадров +PREFERENCES_DIRHOME;Домашний каталог +PREFERENCES_DIRLAST;Последний каталог +PREFERENCES_DIROTHER;Другой +PREFERENCES_DIRSELECTDLG;Каталог, открываемый при запуске программы +PREFERENCES_DIRSOFTWARE;Каталог установки +PREFERENCES_EDITORCMDLINE;Другой (путь к исполняемому файлу) +PREFERENCES_EDITORLAYOUT;Тип редактора +PREFERENCES_EXTERNALEDITOR;Внешний редактор +PREFERENCES_FBROWSEROPTS;Настройки +PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Однорядная панель обозревателя файлов (отключите для экранов с низким разрешением) +PREFERENCES_FILEFORMAT;Формат файлов +PREFERENCES_FLATFIELDFOUND;Найдено +PREFERENCES_FLATFIELDSDIR;Папка с файлами плоских полей +PREFERENCES_FLATFIELDSHOTS;снимков +PREFERENCES_FLATFIELDTEMPLATES;шаблонов +PREFERENCES_FLATFIELD;Плоское поле +PREFERENCES_FLUOF2;Лампа дневного света F2 +PREFERENCES_FLUOF7;Лампа дневного света F7 +PREFERENCES_FLUOF11;Лампа дневного света F11 +PREFERENCES_FORIMAGE;Для изображений +PREFERENCES_FORRAW;Для Raw файлов +PREFERENCES_GIMPPATH;Каталог установки GIMP +PREFERENCES_GREY05;Yb=05 CIE L#30 +PREFERENCES_GREY10;Yb=10 CIE L#40 +PREFERENCES_GREY15;Yb=15 CIE L#45 +PREFERENCES_GREY18;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_GREY;Яркость (Yb) устройства вывода (%) +PREFERENCES_HISTOGRAMPOSITIONLEFT;Гистограмма на левой панели +PREFERENCES_HLTHRESHOLD;Порог срабатывания пересветов +PREFERENCES_ICCDIR;Каталог ICC профилей +PREFERENCES_IMPROCPARAMS;Обработка по умолчанию +PREFERENCES_INTENT_ABSOLUTE;Абсолютное колориметрическое +PREFERENCES_INTENT_PERCEPTUAL;Перцепционное +PREFERENCES_INTENT_RELATIVE;Относительное колориметрическое +PREFERENCES_INTENT_SATURATION;По насыщенности +PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Показывать встроенную миниатюру если файл не отредактирован +PREFERENCES_LANGAUTODETECT;Использовать язык ОС +PREFERENCES_MENUGROUPEXTPROGS;Группа "Открыть с помощью" +PREFERENCES_MENUGROUPFILEOPERATIONS;Группа "Действия с файлами" +PREFERENCES_MENUGROUPLABEL;Группа "Цветовая пометка" +PREFERENCES_MENUGROUPPROFILEOPERATIONS;Группа "Действия с профилем обработки" +PREFERENCES_MENUGROUPRANK;Группа "Рейтинг" +PREFERENCES_MENUOPTIONS;Настройки контекстного меню +PREFERENCES_METADATA;Метаданные +PREFERENCES_MONITORICC;Профиль монитора +PREFERENCES_MULTITABDUALMON;Много вкладок, на втором мониторе (если возможно) +PREFERENCES_MULTITAB;Много вкладок +PREFERENCES_OUTDIRFOLDERHINT;Сохранение изображений в выбранный каталог +PREFERENCES_OUTDIRFOLDER;Сохранять в каталог +PREFERENCES_OUTDIRTEMPLATEHINT;Вы можете использовать следующие элементы форматирования:\n%f, %d1, %d2, …, %p1, %p2, …, %r, %s1, %s2, …\n\nЭлементы соответствуют различным элементам в пути к RAW-файлу, некоторым атрибутам файла или индексу в очереди обработки.\n\nНапример, если был открыт файл /home/tom/image/02-09-2006/dsc0012.nef, элементы форматирования будут выглядеть так:\n%d4 = home\n%d3 = tom\n%d2 = photos\n%d1 = 2010-10-31\n%f = dsc0042\n%p1 = /home/tom/photos/2010-10-31/\n%p2 = /home/tom/photos/\n%p3 = /home/tom/\n%p4 = /home/\n\n%r заменится на рейтинг фотографии, либо '0' при пустом, либо на 'x' если фотография находится в корзине.\n\n%s1, %s2 и т.д. заменятся на индекс фотографии в очереди обработки, дополненный нулями до 1-9 символов. Индекс сбрасывается при старте и увеличивается на единицу при обработке фотографии.\nЕсли вы хотите сохранять изображения в каталоге с оригиналом, введите:\n%p1/%f\n\nЕсли вы хотите сохранять изображения в каталоге "converted" в каталоге оригинального файла, введите строку:\n%p1/converted/%f\nДля сохранения изображений в папке "/home/tom/photos/converted/2010-10-31", напишите:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Использовать шаблон +PREFERENCES_OUTDIR;Каталог для сохранения изображений +PREFERENCES_OVERLAY_FILENAMES;Показывать информацию поверх миниатюр +PREFERENCES_OVERWRITEOUTPUTFILE;Перезаписывать существующие файлы +PREFERENCES_PANFACTORLABEL;Коэффициент +PREFERENCES_PARSEDEXTADDHINT;Введите расширение и нажмите на эту кнопку, чтобы добавить его в список +PREFERENCES_PARSEDEXTADD;Добавить +PREFERENCES_PARSEDEXTDELHINT;Удаление выбранных расширений из списка +PREFERENCES_PARSEDEXT;Расширения для предпросмотра +PREFERENCES_PROFILEHANDLING;Профиль обработки +PREFERENCES_PROFILELOADPR;Приоритет загрузки профиля обработки +PREFERENCES_PROFILEPRCACHE;загружать из кэша +PREFERENCES_PROFILEPRFILE;загружать из каталога с файлом +PREFERENCES_PROFILESAVECACHE;Сохранять профиль обработки в кэше +PREFERENCES_PROFILESAVEINPUT;Сохранять профиль обработки в одном каталоге с исходным файлом +PREFERENCES_PROPERTY;Свойство +PREFERENCES_PSPATH;Каталог установки Adobe Photoshop +PREFERENCES_RGBDTL_LABEL;Максимальное количество потоков для подавления шума +PREFERENCES_RGBDTL_TOOLTIP;Подавление шума требует в среднем 128М оперативной памяти для изображения в 10MPix или 512M для 40MPix и дополнительно 128MB на поток. Чем больше потоков будет запущено одновременно, тем быстрее будет расчёт. Оставьте 0 чтоб использовать максимально возможное количество потоков. +PREFERENCES_SELECTFONT;Выбрать шрифт +PREFERENCES_SELECTLANG;Выбрать язык +PREFERENCES_SELECTTHEME;Выбрать тему +PREFERENCES_SET;Установить +PREFERENCES_SHOWBASICEXIF;Показывать основные данные Exif +PREFERENCES_SHOWDATETIME;Показывать дату и время +PREFERENCES_SHOWEXPOSURECOMPENSATION;Показывать компенсацию выдержки +PREFERENCES_SHTHRESHOLD;Порог обрезки теней +PREFERENCES_SINGLETABVERTAB;Одна вкладка редактирования, вертикальная панель вкладок +PREFERENCES_SINGLETAB;Одна вкладка редактирования +PREFERENCES_SLIMUI;Тонкий интерфейс +PREFERENCES_SND_BATCHQUEUEDONE;Пакетная обработка завершена +PREFERENCES_SND_HELP;Введите имя файла, либо оставьте поле пустым (без звука). В Windows можно использовать "SystemDefault", "SystemAsterisk" и т.д. для системных звуков. +PREFERENCES_SND_LNGEDITPROCDONE;Обработка в редакторе завершена +PREFERENCES_SND_TRESHOLDSECS;после, секунд +PREFERENCES_STARTUPIMDIR;Каталог изображений при запуске +PREFERENCES_TAB_BROWSER;Файловый браузер +PREFERENCES_TAB_COLORMGR;Управление цветом +PREFERENCES_TAB_GENERAL;Основные настройки +PREFERENCES_TAB_IMPROC;Обработка изображения +PREFERENCES_TAB_PERFORMANCE;Производительность +PREFERENCES_TAB_SOUND;Звуки +PREFERENCES_TP_LABEL;Панель инструментов: +PREFERENCES_TP_USEICONORTEXT;Использовать иконки вместо текста +PREFERENCES_TP_VSCROLLBAR;Спрятать вертикальную полосу прокрутки +PREFERENCES_TUNNELMETADATA;Копировать IPTC/XMP в неизменном виде при сохранении (при каталогизации внешними программами) +PREFERENCES_USEBUNDLEDPROFILES;Использовать предустановленный профиль +PREFERENCES_USESYSTEMTHEME;Использовать системную тему оформления +PREFERENCES_VIEW;ББ устройства вывода (монитор, проектор и т.д.) +PREFERENCES_WORKFLOW;Стиль работы +PROFILEPANEL_COPYPPASTE;Параметры для копирования +PROFILEPANEL_GLOBALPROFILES;Предустановленные профили +PROFILEPANEL_LABEL;Профиль обработки +PROFILEPANEL_LOADDLGLABEL;Загрузить профиль обработки... +PROFILEPANEL_LOADPPASTE;Параметры для загрузки +PROFILEPANEL_MODE_TIP;Режим применения профиля\n\nКнопка зажата: Частичные профили будут сконвертированы в полные профили, отсутствующие значения заменятся на значения по умолчанию.\n\nКнопка отжата: Профили будут применяться как они есть, изменяя только те параметры, которые в них прописаны. +PROFILEPANEL_MYPROFILES;Мои профили +PROFILEPANEL_PASTEPPASTE;Параметры для вставки +PROFILEPANEL_PCUSTOM;Пользовательский +PROFILEPANEL_PFILE;Из файла +PROFILEPANEL_PINTERNAL;Нейтральный +PROFILEPANEL_PLASTSAVED;Последний сохранённый +PROFILEPANEL_SAVEDLGLABEL;Сохранить профиль обработки... +PROFILEPANEL_SAVEPPASTE;Параметры для сохранения +PROFILEPANEL_TOOLTIPCOPY;Скопировать текущий профиль в буфер обмена.\nCtrl+click для выбора параметров для копирования +PROFILEPANEL_TOOLTIPLOAD;Загрузить профиль из файла\nCtrl+click для выбора параметров для загрузки +PROFILEPANEL_TOOLTIPPASTE;Вставить профиль из буфера обмена\nCtrl+click для выбора параметров для вставки +PROFILEPANEL_TOOLTIPSAVE;Сохранить текущий профиль\nCtrl+click для выбора параметров для сохранения +PROGRESSBAR_LOADINGTHUMBS;Загрузка миниатюр... +PROGRESSBAR_LOADING;Загрузка изображения... +PROGRESSBAR_LOADJPEG;Чтение JPEG файла... +PROGRESSBAR_LOADPNG;Чтение PNG файла... +PROGRESSBAR_LOADTIFF;Чтение TIFF файла... +PROGRESSBAR_NOIMAGES;Изображения не найдены +PROGRESSBAR_PROCESSING;Обработка изображения... +PROGRESSBAR_PROCESSING_PROFILESAVED;Профиль обработки сохранен +PROGRESSBAR_READY;Готово +PROGRESSBAR_SAVEJPEG;Сохранение JPEG файла... +PROGRESSBAR_SAVEPNG;Сохранение PNG файла... +PROGRESSBAR_SAVETIFF;Сохранение TIFF файла... +PROGRESSBAR_SNAPSHOT_ADDED;Снимок добавлен +PROGRESSDLG_PROFILECHANGEDINBROWSER;Профиль изменён в браузере +QINFO_ISO;ISO +QINFO_NOEXIF;Данные Exif недоступны +SAVEDLG_AUTOSUFFIX;Автоматически добавлять суффикс если файл существует +SAVEDLG_FILEFORMAT;Формат файла +SAVEDLG_FORCEFORMATOPTS;Принудительно установить настройки сохранения +SAVEDLG_JPEGQUAL;Качество JPEG +SAVEDLG_PNGCOMPR;Сжатие PNG +SAVEDLG_PUTTOQUEUEHEAD;Поместить в начало очереди на обработку +SAVEDLG_PUTTOQUEUETAIL;Поместить в конец очереди на обработку +SAVEDLG_PUTTOQUEUE;Поместить в очередь на обработку +SAVEDLG_SAVEIMMEDIATELY;Сохранить сейчас +SAVEDLG_SAVESPP;Сохранять параметры обработки вместе с изображением +SAVEDLG_SUBSAMP;Субдискретизация +SAVEDLG_SUBSAMP_1;Лучшая компрессия +SAVEDLG_SUBSAMP_2;Сбалансированно +SAVEDLG_SUBSAMP_3;Лучшее качество +SAVEDLG_SUBSAMP_TOOLTIP;Лучшая компрессия: 4:1:1\nСбалансированно: 4:2:2\nЛучшее качество: 4:4:4 +SAVEDLG_TIFFUNCOMPRESSED;Несжатый TIFF +SAVEDLG_WARNFILENAME;Файл будет назван +SHCSELECTOR_TOOLTIP;Нажмите правую кнопку мыши для сброса позиции этих трех ползунков. +THRESHOLDSELECTOR_BL;Нижний левый +THRESHOLDSELECTOR_BR;Нижний правый +THRESHOLDSELECTOR_B;Низ +THRESHOLDSELECTOR_HINT;Зажмите клавишу Shift для перемещения отдельных контрольных точек. +THRESHOLDSELECTOR_TL;Верхний левый +THRESHOLDSELECTOR_TR;Верхний правый +THRESHOLDSELECTOR_T;Верх +TOOLBAR_TOOLTIP_CROP;Кадрирование\nгорячая клавиша: C\nДля перемещения области зажмите Shift и переносите мышью. +TOOLBAR_TOOLTIP_HAND;Инструмент "Рука"\nГорячая клавиша: H +TOOLBAR_TOOLTIP_STRAIGHTEN;Выравнивание / Точный поворот\nГорячая клавиша: S\n\nУкажите вертикаль или горизонталь проведя направляющую по рисунку. Угол поворота будет показан возле направляющей. Осью поворота является геометрический центр изображения. +TOOLBAR_TOOLTIP_WB;Указать белую точку\nГорячая клавиша: W +TP_BWMIX_ALGO;Алгоритм OYCPM +TP_BWMIX_ALGO_LI;Линейный +TP_BWMIX_ALGO_SP;Специальные эффекты +TP_BWMIX_ALGO_TOOLTIP;Линейный: выдаст нормальный линейный отклик.\nСпециальные эффекты: выдаст специальные эффекты путём смешивания каналов нелинейно. +TP_BWMIX_AUTOCH;Автоопределение +TP_BWMIX_AUTOCH_TIP;Автоматическое вычисление значений миксера каналов +TP_BWMIX_CC_ENABLED;Подстраивать дополнительные цвета +TP_BWMIX_CC_TOOLTIP;Включите для автоматической регулировки дополнительных цветов в модели ROYGCBPM +TP_BWMIX_CHANNEL;Эквалайзер яркости +TP_BWMIX_CURVEEDITOR1;Кривая "До" +TP_BWMIX_CURVEEDITOR2;Кривая "После" +TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Тональная кривая после конверсии в Ч/Б, в конце обработки. +TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Тональная кривая сразу перед конверсией в Ч/Б.\nМожет учитывать цветовые компоненты. +TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Модифицирует яркость как функцию от цвета.\nУчитывает предельные значения, способные вызывать искажения +TP_BWMIX_FILTER;Цветовой фильтр +TP_BWMIX_FILTER_BLUEGREEN;Синий-Зелёный +TP_BWMIX_FILTER_BLUE;Синий +TP_BWMIX_FILTER_GREENYELLOW;Зелёный-Жёлтый +TP_BWMIX_FILTER_GREEN;Зелёный +TP_BWMIX_FILTER_NONE;Нет +TP_BWMIX_FILTER_PURPLE;Фиолетовый +TP_BWMIX_FILTER_REDYELLOW;Красный-Жёлтый +TP_BWMIX_FILTER_RED;Красный +TP_BWMIX_FILTER_TOOLTIP;Цветовой фильтр воспроизводит снимки, снятые с использованием светофильтра, помещённого перед объективом. Светофильтры подавляют передачу определённой части спектра и соответствующим образом влияют на их яркость. К примеру красный фильтр затемняет синее небо. +TP_BWMIX_FILTER_YELLOW;Жёлтый +TP_BWMIX_GAMMA;Коррекция гаммы +TP_BWMIX_GAM_TOOLTIP;Корректирует гамму для каждого канала RGB. +TP_BWMIX_LABEL;Чёрный-и-белый +TP_BWMIX_MET;Метод +TP_BWMIX_MET_CHANMIX;Миксер каналов +TP_BWMIX_MET_DESAT;Обесцвечивание +TP_BWMIX_MET_LUMEQUAL;Яркостный Эквалайзер +TP_BWMIX_MIXC;Миксер +TP_BWMIX_NEUTRAL;Сбросить +TP_BWMIX_NEUTRAL_TIP;Сбросить все значения (фильтр, миксер каналов) на умолчательные +TP_BWMIX_RGBLABEL;К: %1%% З: %2%% С: %3%% Итог: %4%% +TP_BWMIX_RGBLABEL_HINT;Итоговые значения RGB, учитывающие все настройки миксера.\nИтог показывает сумму применённых значений RGB:\n- всегда 100% в относительных режимах\n- выше (светлее) или ниже (темнее) в абсолютных режимах. +TP_BWMIX_RGB_TOOLTIP;Смешивание каналов RGB. Используйте пресеты для руководства.\nУчтите что отрицательные значения могут вызвать искажения или неустойчивое поведение. +TP_BWMIX_SETTING;Пресеты +TP_BWMIX_SETTING_TOOLTIP;Различные пресеты (плёнка, пейзаж, ...) или ручные значения миксера каналов. +TP_BWMIX_SET_HIGHCONTAST;Высокий контраст +TP_BWMIX_SET_HIGHSENSIT;Высокая чувствительность +TP_BWMIX_SET_HYPERPANCHRO;Сверхпанхроматический +TP_BWMIX_SET_INFRARED;Инфракрасный +TP_BWMIX_SET_LANDSCAPE;Пейзаж +TP_BWMIX_SET_LOWSENSIT;Низкая чувствительность +TP_BWMIX_SET_LUMINANCE;Яркость +TP_BWMIX_SET_NORMCONTAST;Нормальный контраст +TP_BWMIX_SET_ORTHOCHRO;Ортохроматический +TP_BWMIX_SET_PANCHRO;Панхроматический +TP_BWMIX_SET_PORTRAIT;Портретный +TP_BWMIX_TCMODE_FILMLIKE;Ч&Б плёнка +TP_BWMIX_TCMODE_SATANDVALBLENDING;Ч&Б насыщенность+значение +TP_BWMIX_TCMODE_STANDARD;Ч&Б Стандарт +TP_BWMIX_TCMODE_WEIGHTEDSTD;Ч&Б Средневзвешенный стандарт +TP_BWMIX_VAL;L +TP_CACORRECTION_BLUE;Синий +TP_CACORRECTION_LABEL;Хроматические аберрации +TP_CACORRECTION_RED;Красный +TP_CHMIXER_BLUE;Синий +TP_CHMIXER_GREEN;Зелёный +TP_CHMIXER_LABEL;Цветовые каналы +TP_CHMIXER_RED;Красный +TP_CHROMATABERR_LABEL;Хроматические аберрации +TP_COARSETRAF_TOOLTIP_HFLIP;Горизонтальное зеркальное отражение +TP_COARSETRAF_TOOLTIP_ROTLEFT;Повернуть влево +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Повернуть вправо +TP_COARSETRAF_TOOLTIP_VFLIP;Вертикальное зеркальное отражение +TP_COLORAPP_ADAPTSCENE;Яркость обстановки +TP_COLORAPP_ADAPTSCENE_TOOLTIP;Абсолютная освещённость места и объекта съёмки (кд/м²).\n1) Высчитывается из данных Exif:\nВыдержка − Значение ISO − Значение F − Внутрикамерная коррекция выдержки.\n2) Высчитывается из точки белого в raw и значения компенсации экспозиции RT. +TP_COLORAPP_ADAPTVIEWING;Яркость при просмотре (кд/м²) +TP_COLORAPP_ADAPTVIEWING_TOOLTIP;Абсолютная яркость при просмотре.\n(Обычно 16 кд/м²) +TP_COLORAPP_ADAP_AUTO_TOOLTIP;Если галка отмечена (рекомендуется) RT расчитывает оптимальное значение из данных Exif.\nДля ручного редактирования необходимо предварительно снять галку. +TP_COLORAPP_ALGO;Алгоритм +TP_COLORAPP_ALGO_ALL;Все +TP_COLORAPP_ALGO_JC;Светимость + Цвет (JC) +TP_COLORAPP_ALGO_JS;Светимость + Насыщенность (JS) +TP_COLORAPP_ALGO_QM;Яркость + Красочность (QM) +TP_COLORAPP_ALGO_TOOLTIP;Позволяет выбирать между всеми парамерами или их подмножествами. +TP_COLORAPP_BADPIXSL;Фильтр горячих/битых пикселей +TP_COLORAPP_BADPIXSL_TOOLTIP;Подавляет горячие/битые (слишком яркие) пиксели.\n0: без эффекта\n1: средний (медианный)\n2: гауссиан.\n\nЭти искажения возникают в связи с ограничениями CIECAM02. Иначе настройте изображение для уменьшения очень тёмных теней. +TP_COLORAPP_BRIGHT;Яркость (Q) +TP_COLORAPP_BRIGHT_TOOLTIP;Яркость в модели CIECAM02 берёт в расчёт яркость белого и отличается от яркости в моделях Lab и RGB. +TP_COLORAPP_CHROMA;Цвет (C) +TP_COLORAPP_CHROMA_M;Красочность (M) +TP_COLORAPP_CHROMA_M_TOOLTIP;Красочность в модели CIECAM02 отличается от красочности в моделях Lab и RGB. +TP_COLORAPP_CHROMA_S;Насыщенность (S) +TP_COLORAPP_CHROMA_S_TOOLTIP;Насыщенность в модели CIECAM02 отличается от насыщенности в моделях Lab и RGB. +TP_COLORAPP_CHROMA_TOOLTIP;Цвет в модели CIECAM02 отличается от цвета в моделях Lab и RGB. +TP_COLORAPP_CIECAT_DEGREE;Адаптация CAT02 +TP_COLORAPP_CONTRAST;Контраст (J) +TP_COLORAPP_CONTRAST_Q;Контраст (Q) +TP_COLORAPP_CONTRAST_Q_TOOLTIP;Контраст в модели CIECAM02 для слайдера Q. Он отличается от контраста в моделях Lab и RGB. +TP_COLORAPP_CONTRAST_TOOLTIP;Контраст в модели CIECAM02 для слайдера J. Он отличается от контраста в моделях Lab и RGB. +TP_COLORAPP_CURVEEDITOR1;Тональная кривая 1 +TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Показывает яркостную гистограмму L (Lab) перед CIECAM02.\nЕсли стоит галка "Показывать кривые в CIECAM02", показывает гистограмму J или Q после CIECAM02.\n\nJ и Q не отображаются в главной гистограмме.\n\nИтоговый вывод смотрите на основной гистограмме. +TP_COLORAPP_CURVEEDITOR2;Тональная кривая 2 +TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Использование аналогично второй кривой в разделе экспозиции. +TP_COLORAPP_CURVEEDITOR3;Цветовая кривая +TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Позволяет настроить цвет (C), насыщенность (S) или красочность (M).\n\nПоказывает гистограмму насыщенности (Lab) перед CIECAM02.\nЕсли стоит галка "Показывать кривые в CIECAM02", показывает в гистограмме значения C, s или M. C, s и M не показываются в основной гистограмме.\nИтоговый вывод смотрите на основной гистограмме. +TP_COLORAPP_DATACIE;Показывать кривые в CIECAM02 +TP_COLORAPP_GAMUT;Контроль гаммы (Lab) +TP_COLORAPP_GAMUT_TOOLTIP;Позволяет контролировать гамму в режиме Lab. +TP_COLORAPP_HUE;Цвет (h) +TP_COLORAPP_MODEL;Модель точки белого +TP_COLORAPP_SHARPCIE;--неиспользуемый-- +TP_COLORAPP_SHARPCIE_TOOLTIP;--неиспользуемый-- +TP_CROP_FIXRATIO;Пропорция: +TP_CROP_GTDIAGONALS;Правило диагоналей +TP_CROP_GTEPASSPORT;Биометрический паспорт +TP_CROP_GTFRAME;Рамка +TP_CROP_GTGRID;Сетка +TP_CROP_GTNONE;Нет +TP_CROP_GTRULETHIRDS;Правило третей +TP_CROP_GUIDETYPE;Тип направляющей: +TP_CROP_H;Высота +TP_CROP_LABEL;Кадрирование +TP_CROP_PPI;PPI= +TP_CROP_SELECTCROP; Включить режим обрезки +TP_CROP_W;Ширина +TP_CROP_X;x +TP_CROP_Y;y +TP_DARKFRAME_AUTOSELECT;Автовыбор +TP_DARKFRAME_LABEL;Темновой кадр +TP_DEFRINGE_LABEL;Подавление ореолов +TP_DEFRINGE_RADIUS;Радиус +TP_DEFRINGE_THRESHOLD;Порог +TP_DIRPYRDENOISE_BLUE;Цветность: синий-жёлтый +TP_DIRPYRDENOISE_CHROMA;Цветность +TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Может использоваться как для raw, так и для обычных изображений.\n\nДля не-raw файлов подавление яркостного шума зависит от гаммы входящего цветового профиля, причём подразумевается гамма sRGB. Поэтому, если снимок имеет цветовой профиль с иной гаммой, результаты операции могут варьировать. +TP_DIRPYRDENOISE_ENH;Улучшенный режим +TP_DIRPYRDENOISE_ENH_TOOLTIP;Улучшает качество шумоподавления путём увеличения времени обработки на 20%. +TP_DIRPYRDENOISE_GAMMA;Гамма +TP_DIRPYRDENOISE_GAMMA_TOOLTIP;Значение гаммы изменяет диапазон тонов для подавления шума. Уменьшение значения влияет на тени, увеличение расширит эффект на более светлые тона. +TP_DIRPYRDENOISE_LABEL;Подавление шума +TP_DIRPYRDENOISE_LAB;Lab +TP_DIRPYRDENOISE_LDETAIL;Детализация яркости +TP_DIRPYRDENOISE_LUMA;Яркость +TP_DIRPYRDENOISE_METHOD;Метод +TP_DIRPYRDENOISE_METHOD_TOOLTIP;Для raw-изображений можно использовать как режим RGB так и Lab.\n\nДля не-raw будет использован Lab режим вне зависимости от выбора. +TP_DIRPYRDENOISE_RED;Цветность: красный-зелёный +TP_DIRPYRDENOISE_RGB;RGB +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_DISTORTION_AUTO;Автоматическая коррекция +TP_DISTORTION_AUTO_TIP;(Экспериментально) Автоматическая коррекция дисторсии на некоторых камерах (M4/3, некоторые компактные камеры и т.д.) +TP_DISTORTION_LABEL;Дисторсия +TP_EPD_EDGESTOPPING;Определение контуров +TP_EPD_LABEL;Тональная компрессия +TP_EPD_REWEIGHTINGITERATES;Перевзвешивание проходов +TP_EPD_SCALE;Масштаб +TP_EPD_STRENGTH;Интенсивность +TP_EPD_TOOLTIP;Тональная компрессия возможна в режиме Lab (по умолчанию) и CIECAM02.\n\n.Для использования модели тональной компрессии CIECAM02 включите следующие настройки:\n1. CIECAM02\n2. Алгоритм Яркость+Красочность (QM)\n3. Тональная компрессия, использующая яркость CIECAM02 (Q). +TP_EXPOSURE_AUTOLEVELS;Автоуровни +TP_EXPOSURE_AUTOLEVELS_TIP;Переключение выполнения автоуровней для автоматической установки параметров экспозиции на основе анализа изображения +TP_EXPOSURE_BLACKLEVEL;Уровень чёрного +TP_EXPOSURE_BRIGHTNESS;Яркость +TP_EXPOSURE_CLIP;Ограничить +TP_EXPOSURE_CLIP_TIP;Часть пикселей, обрезаемая операцией автоматических уровней +TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Порог восстановления светов +TP_EXPOSURE_COMPRHIGHLIGHTS;Сжатие светов +TP_EXPOSURE_COMPRSHADOWS;Сжатие теней +TP_EXPOSURE_CONTRAST;Контраст +TP_EXPOSURE_CURVEEDITOR1;Тональная кривая 1 +TP_EXPOSURE_CURVEEDITOR2;Тональная кривая 2 +TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Для понимания того, как достичь лучших результов, используя две кривые, прочтите следующий раздел Руководства:\nИнструменты → Вкладка "Экспозиция" → Экспозиция → Тональная кривая +TP_EXPOSURE_EXPCOMP;Компенсация экспозиции +TP_EXPOSURE_LABEL;Экспозиция +TP_EXPOSURE_SATURATION;Насыщенность +TP_EXPOSURE_TCMODE_FILMLIKE;Плёнка +TP_EXPOSURE_TCMODE_LABEL1;Режим кривой 1 +TP_EXPOSURE_TCMODE_LABEL2;Режим кривой 2 +TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Насыщенность+значение +TP_EXPOSURE_TCMODE_STANDARD;Стандарт +TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Средневзвешенный стандарт +TP_FLATFIELD_AUTOSELECT;Автоматический выбор +TP_FLATFIELD_BLURRADIUS;Радиус размытия +TP_FLATFIELD_BLURTYPE;Тип размытия +TP_FLATFIELD_BT_AREA;Область +TP_FLATFIELD_BT_HORIZONTAL;Горизонтальная +TP_FLATFIELD_BT_VERTHORIZ;Вертикальная + Горизонтальная +TP_FLATFIELD_BT_VERTICAL;Вертикальная +TP_FLATFIELD_LABEL;Плоское поле +TP_GAMMA_CURV;гамма +TP_GAMMA_FREE;Свободная гамма +TP_GAMMA_OUTPUT;Выходная гамма +TP_GAMMA_SLOP;наклонная (линейная) +TP_GENERAL_11SCALE_TOOLTIP;Эффект от применения этого инструмента или одного из его компонентов будет виден лишь при просмотре в масштабе 1:1. +TP_GRADIENT_CENTER;Центр +TP_GRADIENT_CENTER_X;X-координата +TP_GRADIENT_CENTER_X_TOOLTIP;X-координата точки вращения:\n-100=левый край, 0=центр, +100=правый край. +TP_GRADIENT_CENTER_Y;Y-координата +TP_GRADIENT_CENTER_Y_TOOLTIP;Y-координата точки вращения:\n-100=верхний край, 0=центр, +100=нижний край. +TP_GRADIENT_DEGREE;Угол +TP_GRADIENT_DEGREE_TOOLTIP;Угол поворота градиента в градусах. +TP_GRADIENT_FEATHER;Растушёвка +TP_GRADIENT_FEATHER_TOOLTIP;Ширина градиента в процентах от диагонали изображения. +TP_GRADIENT_LABEL;Градиентный фильтр +TP_GRADIENT_STRENGTH;Сила +TP_GRADIENT_STRENGTH_TOOLTIP;Сила градиента в стопах. +TP_HLREC_BLEND;Наложение +TP_HLREC_CIELAB;Смешивание CIELab +TP_HLREC_COLOR;Реконструкция цвета +TP_HLREC_ENA_TOOLTIP;Может быть активирован при выборе автоматических уровней. +TP_HLREC_LABEL;Восстановление ярких участков +TP_HLREC_LUMINANCE;Восстановление яркости +TP_HLREC_METHOD;Метод: +TP_HSVEQUALIZER_CHANNEL;Канал +TP_HSVEQUALIZER_HUE;H +TP_HSVEQUALIZER_LABEL;Эквалайзер HSV +TP_HSVEQUALIZER_SAT;S +TP_HSVEQUALIZER_VAL;V +TP_ICM_BLENDCMSMATRIX;Смешивать засветы с матрицей +TP_ICM_BLENDCMSMATRIX_TOOLTIP;Включить восстановление пересветов во время использования профилей ICC на основе LUT +TP_ICM_DCPILLUMINANT;Источник света +TP_ICM_DCPILLUMINANT_INTERPOLATED;Интерполированный +TP_ICM_INPUTCAMERAICC;Автоопределенный для камеры +TP_ICM_INPUTCAMERAICC_TOOLTIP;Использовать входящий цветовой профиль RawTherapee (DCP или ICC) для конкретной камеры. Эти профили более точные, чем простые матрицы. Доступны не для всех камер. Эти профили хранятся в папках /iccprofiles/input и /dcpprofiles и автоматически выбираются на основе сопоставления имени файла и названия модели камеры. +TP_ICM_INPUTCAMERA;По умолчанию для камеры +TP_ICM_INPUTCAMERA_TOOLTIP;Использовать простую цветовую матрицу из dcraw, улучшенную версию от RawTherapee (если она доступна для соотв. камеры) или встроенную в DNG. +TP_ICM_INPUTCUSTOM;Пользовательский +TP_ICM_INPUTCUSTOM_TOOLTIP;Выбор собственного файла профиля DCP/ICC для камеры +TP_ICM_INPUTDLGLABEL;Выберите входной ICC профиль... +TP_ICM_INPUTEMBEDDED;Использовать встроенный +TP_ICM_INPUTEMBEDDED_TOOLTIP;Использовать цветовой профиль, встроенный в не-raw файлы, если это возможно +TP_ICM_INPUTNONE;Без профиля +TP_ICM_INPUTNONE_TOOLTIP;Не применять входящий цветовой профиль. Использовать только в особых случаях. +TP_ICM_INPUTPROFILE;Входной профиль +TP_ICM_LABEL;ICM +TP_ICM_NOICM;Без ICM: sRGB на выходе +TP_ICM_OUTPUTPROFILE;Выходной профиль +TP_ICM_SAVEREFERENCE;Сохранить для профилирования +TP_ICM_SAVEREFERENCE_TOOLTIP;Сохранить линейный TIFF файл перед применением входного профиля. Результат может использоваться для калибровки и создания профиля камеры. +TP_ICM_TONECURVE;Использовать тональную кривую DCP +TP_ICM_TONECURVE_TOOLTIP;Использовать встроенную тональную кривую DCP. Настройка включается только в том случае, если выбранный DCP содержит тональную кривую. +TP_ICM_WORKINGPROFILE;Рабочий профиль +TP_IMPULSEDENOISE_LABEL;Подавление импульсного шума +TP_IMPULSEDENOISE_THRESH;Порог +TP_LABCURVE_AVOIDCOLORSHIFT;Избегать сдвига цветов +TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Умещать цвета в диапазон рабочего цветового пространства и применять коррекцию Манселла +TP_LABCURVE_BRIGHTNESS;Яркость +TP_LABCURVE_CHROMATICITY;Цветность +TP_LABCURVE_CHROMA_TOOLTIP;Для применения тонирования Ч&Б, выставьте Цветность в -100 +TP_LABCURVE_CONTRAST;Контраст +TP_LABCURVE_CURVEEDITOR;Кривая яркости +TP_LABCURVE_CURVEEDITOR_A_RANGE1;Зеленый насыщенный +TP_LABCURVE_CURVEEDITOR_A_RANGE2;Зеленый пастельный +TP_LABCURVE_CURVEEDITOR_A_RANGE3;Красный пастельный +TP_LABCURVE_CURVEEDITOR_A_RANGE4;Красный насыщенный +TP_LABCURVE_CURVEEDITOR_B_RANGE1;Синий насыщенный +TP_LABCURVE_CURVEEDITOR_B_RANGE2;Синий пастельный +TP_LABCURVE_CURVEEDITOR_B_RANGE3;Желтый пастельный +TP_LABCURVE_CURVEEDITOR_B_RANGE4;Желтый насыщенный +TP_LABCURVE_CURVEEDITOR_CC;ЦЦ +TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Нейтральный +TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Тусклый +TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Пастельный +TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Насыщенный +TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Цветность в соответствии с цветностью.\nC=f(C) +TP_LABCURVE_CURVEEDITOR_CH;ЦО +TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Цветность в соответствии с оттенком.\nC=f(H) +TP_LABCURVE_CURVEEDITOR_CL;ЦЯ +TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Цветность в соответствии с яркостью.\nC=f(L) +TP_LABCURVE_CURVEEDITOR_HH;ОО +TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Оттенок в соответствии с оттенком.\nH=f(H) +TP_LABCURVE_CURVEEDITOR_LC;ЯЦ +TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Яркость в соответствии с цветностью.\nL=f(C) +TP_LABCURVE_CURVEEDITOR_LH;ЯО +TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Яркость в соответствии с оттенком.\nL=f(H) +TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Яркость в соответствии с яркостью.\nL=f(L) +TP_LABCURVE_LABEL;Кривые Lab +TP_LABCURVE_LCREDSK;Ограничить применение кривой ЯЦ +TP_LABCURVE_LCREDSK_TIP;Если включено, то кривая яркости от цвета применится лишь для тонов кожи и красных оттенков.\nИначе применится для всех тонов +TP_LABCURVE_RSTPROTECTION;Защита красного и тонов кожи +TP_LABCURVE_RSTPRO_TOOLTIP;Защита красных тонов и оттенков кожи\nМожно использовать вместе со слайдером Цветность и кривой ЦЦ. +TP_LENSGEOM_AUTOCROP;Автокадрирование +TP_LENSGEOM_FILL;Автозаполнение +TP_LENSGEOM_LABEL;Геометрия +TP_LENSPROFILE_LABEL;Профиль коррекции объектива +TP_LENSPROFILE_USECA;Корректировать ХА +TP_LENSPROFILE_USEDIST;Корректировать дисторсию +TP_LENSPROFILE_USEVIGN;Корректировать виньетирование +TP_NEUTRAL;Нейтральный +TP_NEUTRAL_TIP;Сбросить настройки выдержки на средние значения +TP_PCVIGNETTE_FEATHER;Размытие +TP_PCVIGNETTE_FEATHER_TOOLTIP;Размытие:\n0=только углы, 50=наполовину к центру, 100=к центру. +TP_PCVIGNETTE_LABEL;Фильтр виньетирования +TP_PCVIGNETTE_ROUNDNESS;Скруглённость +TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Скруглённость:\n0=прямоугольник, 50=вписанный овал, 100=круг. +TP_PCVIGNETTE_STRENGTH;Сила +TP_PCVIGNETTE_STRENGTH_TOOLTIP;Сила фильтра в стопах (достигается в углах). +TP_PERSPECTIVE_HORIZONTAL;Горизонтальная +TP_PERSPECTIVE_LABEL;Перспектива +TP_PERSPECTIVE_VERTICAL;Вертикальная +TP_PFCURVE_CURVEEDITOR_CH;Цвет +TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Контроль силы подавления в зависимости от цвета.\nВыше - сильней, ниже - слабей. +TP_PREPROCESS_GREENEQUIL;Выравнивание зелёного +TP_PREPROCESS_LABEL;Предобработка +TP_PREPROCESS_LINEDENOISE;Фильтр линейного шума +TP_PREPROCESS_NO_FOUND;Ничего не найдено +TP_RAWCACORR_AUTO;Автоматическая коррекция +TP_RAWCACORR_CABLUE;Синий +TP_RAWCACORR_CARED;Красный +TP_RAWEXPOS_BLACKS;Уровни черного +TP_RAWEXPOS_LINEAR;Коррекция точки белого +TP_RAWEXPOS_PRESER;Сохранение пересветов +TP_RAWEXPOS_TWOGREEN;Два зеленых совместно +TP_RAW_DCBENHANCE;Расширенный DCB +TP_RAW_DCBITERATIONS;Количество итераций DCB +TP_RAW_DMETHOD;Метод +TP_RAW_DMETHOD_PROGRESSBAR;Демозаик %1... +TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Улучшение демозаика... +TP_RAW_DMETHOD_TOOLTIP;Внимание: Методы IGV и LMMSE предназначены для фотографий с высокими значениями ISO. +TP_RAW_FALSECOLOR;Шагов подавления ложных цветов: +TP_RAW_LABEL;Демозаик +TP_RAW_LMMSEITERATIONS;Шагов улучшения LMMSE +TP_RAW_LMMSE_TOOLTIP;Добавляет гамму (шаг 1), вычисляет среднее (шаги 2-4) и уточняет демозаик (шаги 5-6) для уменьшения искажений и улучшения соотношения сигнала к шуму. +TP_RESIZE_APPLIESTO;Применить к: +TP_RESIZE_CROPPEDAREA;Кадрированной области +TP_RESIZE_FITBOX;Ограничивающей рамке +TP_RESIZE_FULLIMAGE;Полному изображению +TP_RESIZE_HEIGHT;высоту +TP_RESIZE_H;В: +TP_RESIZE_LABEL;Изменение размера +TP_RESIZE_LANCZOS;Ланцош +TP_RESIZE_METHOD;Метод: +TP_RESIZE_NEAREST;Ближайшие точки +TP_RESIZE_SCALE;Масштаб +TP_RESIZE_SPECIFY;Задать: +TP_RESIZE_WIDTH;ширину +TP_RESIZE_W;Ш: +TP_RGBCURVES_BLUE;B +TP_RGBCURVES_CHANNEL;Канал +TP_RGBCURVES_GREEN;G +TP_RGBCURVES_LABEL;Кривые RGB +TP_RGBCURVES_LUMAMODE;Режим яркости +TP_RGBCURVES_LUMAMODE_TOOLTIP;Режим яркости Позволяет изменять вклад каналов R, G и B в яркость изображения, без изменения цвета рисунка. +TP_RGBCURVES_RED;R +TP_ROTATE_DEGREE;Угол +TP_ROTATE_LABEL;Поворот +TP_ROTATE_SELECTLINE;Выбрать прямую линию +TP_SAVEDIALOG_OK_TIP;Горячая клавиша Ctrl-Enter +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Света +TP_SHADOWSHLIGHTS_HLTONALW;Уровень +TP_SHADOWSHLIGHTS_LABEL;Тени/света +TP_SHADOWSHLIGHTS_LOCALCONTR;Локальный контраст +TP_SHADOWSHLIGHTS_RADIUS;Радиус +TP_SHADOWSHLIGHTS_SHADOWS;Тени +TP_SHADOWSHLIGHTS_SHARPMASK;Маска резкости +TP_SHADOWSHLIGHTS_SHTONALW;Уровень +TP_SHARPENEDGE_AMOUNT;Количество +TP_SHARPENEDGE_LABEL;Края +TP_SHARPENEDGE_PASSES;Подходы +TP_SHARPENEDGE_THREE;Только освещенность +TP_SHARPENING_AMOUNT;Величина +TP_SHARPENING_EDRADIUS;Радиус +TP_SHARPENING_EDTOLERANCE;Границы краёв +TP_SHARPENING_HALOCONTROL;Регулировка хром. аберраций +TP_SHARPENING_HCAMOUNT;Величина +TP_SHARPENING_LABEL;Резкость +TP_SHARPENING_METHOD;Метод +TP_SHARPENING_ONLYEDGES;Только контуры +TP_SHARPENING_RADIUS;Радиус +TP_SHARPENING_RLD;Обращённая свёртка RL +TP_SHARPENING_RLD_AMOUNT;Величина +TP_SHARPENING_RLD_DAMPING;Ослабление +TP_SHARPENING_RLD_ITERATIONS;Повторений +TP_SHARPENING_THRESHOLD;Порог +TP_SHARPENING_TOOLTIP;Ожидается небольшая разница при использовании совместно с CIECAM02. Настройте по вкусу если заметили разницу. +TP_SHARPENING_USM;Маска размытия +TP_SHARPENMICRO_AMOUNT;Количество +TP_SHARPENMICRO_LABEL;Микроконтраст +TP_SHARPENMICRO_MATRIX;Матрица 3×3 вместо 5×5 +TP_SHARPENMICRO_UNIFORMITY;Равномерность +TP_VIBRANCE_AVOIDCOLORSHIFT;Избегать сдвига цветов +TP_VIBRANCE_CURVEEDITOR_SKINTONES;ОО +TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Оттенки кожи +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Красный/Фиолетовый +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Красный +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Красный/Желтый +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Желтый +TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Оттенок в соответствии с оттенком +TP_VIBRANCE_LABEL;Резонанс +TP_VIBRANCE_PASTELS;Пастельные тона +TP_VIBRANCE_PASTSATTOG;Связать пастельные и насыщенные тона +TP_VIBRANCE_PROTECTSKINS;Сохранить оттенки кожи +TP_VIBRANCE_PSTHRESHOLD;Уровень пастельных/насыщенных тонов +TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Порог насыщенности +TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;Вертикальная ось обозначает пастельные тона внизу и насыщенные вверху.\nГоризонтальная ось представляет диапазон насыщенности. +TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Условие перехода пастельных/насыщенных +TP_VIBRANCE_SATURATED;Насыщенные тона +TP_VIGNETTING_AMOUNT;Величина +TP_VIGNETTING_CENTER;Центр +TP_VIGNETTING_CENTER_X;Центр X +TP_VIGNETTING_CENTER_Y;Центр Y +TP_VIGNETTING_LABEL;Виньетирование +TP_VIGNETTING_RADIUS;Радиус +TP_VIGNETTING_STRENGTH;Степень +TP_WBALANCE_AUTO;Автоматический +TP_WBALANCE_CAMERA;Камера +TP_WBALANCE_CLOUDY;Облачно +TP_WBALANCE_CUSTOM;Пользовательский +TP_WBALANCE_DAYLIGHT;Дневной (солнечно) +TP_WBALANCE_EQBLUERED;Эквалайзер красного/синего +TP_WBALANCE_EQBLUERED_TOOLTIP;Позволяет отойти от обычного поведения "баланса белого" путём регулирования баланса красного/синего.\nЭто может быть полезно когда условия сьёмки:\n* Далеки от стандартного освещения (например под водой)\n* Далеки от условий, когда была произведена калибровка\n* Когда используемые цветовые профили (ICC) неподходящи. +TP_WBALANCE_FLASH55;Leica +TP_WBALANCE_FLASH60;Стандарт, Canon, Pentax, Olympus +TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta +TP_WBALANCE_FLASH_HEADER;Вспышка +TP_WBALANCE_FLUO1;F1 - Дневной +TP_WBALANCE_FLUO2;F2 - Прохладный белый +TP_WBALANCE_FLUO3;F3 - Белый +TP_WBALANCE_FLUO4;F4 - Теплый белый +TP_WBALANCE_FLUO5;F5 - Дневной +TP_WBALANCE_FLUO6;F6 - Ярко-белый +TP_WBALANCE_FLUO7;F7 - D65 Имитация дневного +TP_WBALANCE_FLUO8;F8 - D50 / Лампа Sylvania F40 Design +TP_WBALANCE_FLUO9;F9 - Прохладный белый deluxe +TP_WBALANCE_FLUO10;F10 - Philips TL85 +TP_WBALANCE_FLUO11;F11 - Philips TL84 +TP_WBALANCE_FLUO12;F12 - Philips TL83 +TP_WBALANCE_FLUO_HEADER;Флюоресцентный +TP_WBALANCE_GREEN;Оттенок +TP_WBALANCE_GTI;GTI +TP_WBALANCE_HMI;HMI +TP_WBALANCE_JUDGEIII;JudgeIII +TP_WBALANCE_LABEL;Баланс белого +TP_WBALANCE_LAMP_HEADER;Лампа +TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 +TP_WBALANCE_LED_HEADER;Светодиодный +TP_WBALANCE_LED_LSI;LSI Lumelex 2040 +TP_WBALANCE_METHOD;Метод +TP_WBALANCE_SHADE;Тень +TP_WBALANCE_SIZE;Размер пипетки: +TP_WBALANCE_SOLUX35;Solux 3500K +TP_WBALANCE_SOLUX41;Solux 4100K +TP_WBALANCE_SOLUX47;Solux 4700K (производит.) +TP_WBALANCE_SOLUX47_NG;Solux 4700K (Нац. галерея) +TP_WBALANCE_SPOTWB;Указать точку белого +TP_WBALANCE_TEMPERATURE;Температура +TP_WBALANCE_TUNGSTEN;Лампа накаливания +TP_WBALANCE_WATER1;Подводный 1 +TP_WBALANCE_WATER2;Подводный 2 +TP_WBALANCE_WATER_HEADER;Подводный +ZOOMPANEL_100;(100%) +ZOOMPANEL_NEWCROPWINDOW;Новое окно детального просмотра +ZOOMPANEL_ZOOM100;Масштаб 100% z +ZOOMPANEL_ZOOMFITSCREEN;По размерам окна f +ZOOMPANEL_ZOOMIN;Приблизить + +ZOOMPANEL_ZOOMOUT;Удалить - + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!CURVEEDITOR_AXIS_IN;I: +!CURVEEDITOR_AXIS_LEFT_TAN;LT: +!CURVEEDITOR_AXIS_OUT;O: +!CURVEEDITOR_AXIS_RIGHT_TAN;RT: +!CURVEEDITOR_EDITPOINT_HINT;Enable edition of node in/out values.\n\nRight-click on a node to select it.\nRight-click on empty space to de-select the node. +!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. +!EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels +!FILEBROWSER_POPUPRANK0;Unrank +!FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!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_ASIMAGE;As Image +!HISTORY_MSG_252;CbDL - Skin tar/prot +!HISTORY_MSG_253;CbDL - Reduce artifacts +!HISTORY_MSG_254;CbDL - Skin hue +!HISTORY_MSG_255;NR - Median filter +!HISTORY_MSG_256;NR - Median type +!HISTORY_MSG_257;Color Toning +!HISTORY_MSG_258;CT - Color curve +!HISTORY_MSG_259;CT - Opacity curve +!HISTORY_MSG_260;CT - a*[b*] opacity +!HISTORY_MSG_261;CT - Method +!HISTORY_MSG_262;CT - b* opacity +!HISTORY_MSG_263;CT - Shadows - Red +!HISTORY_MSG_264;CT - Shadows - Green +!HISTORY_MSG_265;CT - Shadows - Blue +!HISTORY_MSG_266;CT - Mid - Red +!HISTORY_MSG_267;CT - Mid - Green +!HISTORY_MSG_268;CT - Mid - Blue +!HISTORY_MSG_269;CT - High - Red +!HISTORY_MSG_270;CT - High - Green +!HISTORY_MSG_271;CT - High - Blue +!HISTORY_MSG_272;CT - Balance +!HISTORY_MSG_273;CT - Reset +!HISTORY_MSG_274;CT - Sat. Shadows +!HISTORY_MSG_275;CT - Sat. Highlights +!HISTORY_MSG_276;CT - Opacity +!HISTORY_MSG_277;--unused-- +!HISTORY_MSG_278;CT - Preserve luminance +!HISTORY_MSG_279;CT - Shadows +!HISTORY_MSG_280;CT - Highlights +!HISTORY_MSG_281;CT - Sat. strength +!HISTORY_MSG_282;CT - Sat. threshold +!HISTORY_MSG_283;CT - Strength +!HISTORY_MSG_284;CT - Auto sat. protection +!HISTORY_MSG_285;NR - Median - Method +!HISTORY_MSG_286;NR - Median - Type +!HISTORY_MSG_287;NR - Median - Iterations +!HISTORY_MSG_288;Flat Field - Clip control +!HISTORY_MSG_289;Flat Field - Clip control - Auto +!HISTORY_MSG_290;Black Level - Red +!HISTORY_MSG_291;Black Level - Green +!HISTORY_MSG_292;Black Level - Blue +!HISTORY_MSG_293;Film Simulation +!HISTORY_MSG_294;Film Simulation - Strength +!HISTORY_MSG_295;Film Simulation - Film +!HISTORY_MSG_296;NR - Luminance curve +!HISTORY_MSG_297;NR - Quality +!HISTORY_MSG_298;Dead pixel filter +!HISTORY_MSG_299;NR - Chrominance curve +!HISTORY_MSG_300;- +!HISTORY_MSG_301;NR - Luma control +!HISTORY_MSG_302;NR - Chroma method +!HISTORY_MSG_303;NR - Chroma method +!HISTORY_MSG_304;W - Contrast levels +!HISTORY_MSG_305;Wavelet Levels +!HISTORY_MSG_306;W - Preview +!HISTORY_MSG_307;W - Preview +!HISTORY_MSG_308;W - Preview direction +!HISTORY_MSG_309;W - ES - Detail +!HISTORY_MSG_310;W - Residual - Sky tar/prot +!HISTORY_MSG_311;W - Wavelet levels +!HISTORY_MSG_312;W - Residual - Shadows threshold +!HISTORY_MSG_313;W - Chroma - Sat/past +!HISTORY_MSG_314;W - Gamut - Reduce artifacts +!HISTORY_MSG_315;W - Residual - Contrast +!HISTORY_MSG_316;W - Gamut - Skin tar/prot +!HISTORY_MSG_317;W - Gamut - Skin hue +!HISTORY_MSG_318;W - Contrast - Highlight levels +!HISTORY_MSG_319;W - Contrast - Highlight range +!HISTORY_MSG_320;W - Contrast - Shadow range +!HISTORY_MSG_321;W - Contrast - Shadow levels +!HISTORY_MSG_322;W - Gamut - Avoid color shift +!HISTORY_MSG_323;W - ES - Local contrast +!HISTORY_MSG_324;W - Chroma - Pastel +!HISTORY_MSG_325;W - Chroma - Saturated +!HISTORY_MSG_326;W - Chroma - Method +!HISTORY_MSG_327;W - Contrast - Apply to +!HISTORY_MSG_328;W - Chroma - Link strength +!HISTORY_MSG_329;W - Toning - Opacity RG +!HISTORY_MSG_330;W - Toning - Opacity BY +!HISTORY_MSG_331;W - Contrast levels - Extra +!HISTORY_MSG_332;W - Tiling method +!HISTORY_MSG_333;W - Residual - Shadows +!HISTORY_MSG_334;W - Residual - Chroma +!HISTORY_MSG_335;W - Residual - Highlights +!HISTORY_MSG_336;W - Residual - Highlights threshold +!HISTORY_MSG_337;W - Residual - Sky hue +!HISTORY_MSG_338;W - ES - Radius +!HISTORY_MSG_339;W - ES - Strength +!HISTORY_MSG_340;W - Strength +!HISTORY_MSG_341;W - Edge performance +!HISTORY_MSG_342;W - ES - First level +!HISTORY_MSG_343;W - Chroma levels +!HISTORY_MSG_344;W - Meth chroma sl/cur +!HISTORY_MSG_345;W - ES - Local contrast +!HISTORY_MSG_346;W - ES - Local contrast method +!HISTORY_MSG_347;W - Denoise - Level 0 +!HISTORY_MSG_348;W - Denoise - Level 1 +!HISTORY_MSG_349;W - Denoise - Level 2 +!HISTORY_MSG_350;W - ES - Edge detection +!HISTORY_MSG_351;W - Residual - HH curve +!HISTORY_MSG_352;W - Background +!HISTORY_MSG_353;W - ES - Gradient sensitivity +!HISTORY_MSG_354;W - ES - Enhance +!HISTORY_MSG_355;W - ES - Threshold low +!HISTORY_MSG_356;W - ES - Threshold high +!HISTORY_MSG_357;W - Denoise - Link with ES +!HISTORY_MSG_358;W - Gamut - CH +!HISTORY_MSG_359;Hot/Dead - Threshold +!HISTORY_MSG_360;TM Gamma +!HISTORY_MSG_361;W - Final - Chroma balance +!HISTORY_MSG_362;W - Residual - Compression method +!HISTORY_MSG_363;W - Residual - Compression strength +!HISTORY_MSG_364;W - Final - Contrast balance +!HISTORY_MSG_365;W - Final - Delta balance +!HISTORY_MSG_366;W - Residual - Compression gamma +!HISTORY_MSG_367;W - ES - Local contrast curve +!HISTORY_MSG_368;W - Final - Contrast balance +!HISTORY_MSG_369;W - Final - Balance method +!HISTORY_MSG_370;W - Final - Local contrast curve +!MAIN_TAB_INSPECT; Inspect +!MAIN_TAB_WAVELET;Wavelet +!MAIN_TAB_WAVELET_TOOLTIP;Shortcut: Alt-w +!MAIN_TOOLTIP_HIDEHP;Show/Hide the left panel (including the history).\nShortcut: l +!NAVIGATOR_B;B: +!NAVIGATOR_G;G: +!NAVIGATOR_H;H: +!NAVIGATOR_LAB_A;a*: +!NAVIGATOR_LAB_B;b*: +!NAVIGATOR_LAB_L;L*: +!NAVIGATOR_NA; -- +!NAVIGATOR_R;R: +!NAVIGATOR_S;S: +!NAVIGATOR_V;V: +!PARTIALPASTE_COLORTONING;Color Toning +!PARTIALPASTE_EQUALIZER;Wavelet Equalizer +!PARTIALPASTE_FILMSIMULATION;Film Simulation +!PARTIALPASTE_FLATFIELDCLIPCONTROL;Flat-field clip control +!PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter +!PARTIALPASTE_PREPROCESS_HOTPIXFILT;Hot pixel filter +!PARTIALPASTE_WAVELETGROUP;Wavelet processing +!PREFERENCES_AUTLISLOW;Low +!PREFERENCES_AUTLISMAX;Max - Average of all tiles +!PREFERENCES_AUTLISSTD;High +!PREFERENCES_AUTLISVLOW;None +!PREFERENCES_AUTLOW;Low +!PREFERENCES_AUTSTD;Standard +!PREFERENCES_CIEART_FRAME;CIECAM02-Specific Settings +!PREFERENCES_CLUTSCACHE;HaldCLUT Cache +!PREFERENCES_CLUTSCACHE_LABEL;Maximum number of cached CLUTs +!PREFERENCES_CLUTSDIR;HaldCLUT directory +!PREFERENCES_CURVEBBOXPOS;Position of curve copypasta buttons +!PREFERENCES_CURVEBBOXPOS_ABOVE;Above +!PREFERENCES_CURVEBBOXPOS_BELOW;Below +!PREFERENCES_CURVEBBOXPOS_LEFT;Left +!PREFERENCES_CURVEBBOXPOS_RIGHT;Right +!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_EXPAUT;Expert +!PREFERENCES_FILMSIMULATION;Film Simulation +!PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT;Same thumbnail height between the Editor's panel 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_GREYSC18;Yb=18 CIE L#50 +!PREFERENCES_GREYSCA;Automatic +!PREFERENCES_GREYSC;Scene Yb luminance (%) +!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_LEVAUTDN;Denoising level +!PREFERENCES_LEVDN;Cell size +!PREFERENCES_LISS;Auto multi-zone smoothing +!PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders +!PREFERENCES_MAX;Maxi (Tile) +!PREFERENCES_MED;Medium (Tile/2) +!PREFERENCES_MIN;Mini (100x115) +!PREFERENCES_NAVGUIDEBRUSH;Navigator guide color +!PREFERENCES_NAVIGATIONFRAME;Navigation +!PREFERENCES_NOISE;Noise Reduction +!PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Overlay filenames on thumbnails in the editor pannel +!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_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_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_SHOWFILMSTRIPTOOLBAR;Show filmstrip toolbar +!PREFERENCES_SIMPLAUT;Tool mode +!PREFERENCES_SMA;Small (250x287) +!PREFERENCES_STDAUT;Standard +!PREFERENCES_TIMAX;High +!PREFERENCES_TINB;Number of tiles +!PREFERENCES_TISTD;Standard +!PREFERENCES_WAVLEV;Increase wavelet level in quality 'high' +!PREFERENCES_WLONE;One level +!PREFERENCES_WLTWO;Two levels +!PREFERENCES_WLZER;No +!TP_BWMIX_SET_RGBABS;Absolute RGB +!TP_BWMIX_SET_RGBREL;Relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Relative ROYGCBPM +!TP_COLORAPP_DATACIE_TOOLTIP;When enabled, histograms in CIECAM02 curves show approximate values/ranges for J or Q, and C, s or M after the CIECAM02 adjustments.\nThis selection does not impact the main histogram panel.\n\nWhen disabled, histograms in CIECAM02 curves show L*a*b* values before CIECAM02 adjustments. +!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RawTherapee calculates an optimum value, which is then used by CAT02, and also for the entire CIECAM02.\nTo set the value manually, uncheck the check-box first (values above 65 are recommended). +!TP_COLORAPP_DEGREE_TOOLTIP;Amount of CIE Chromatic Adaptation Transform 2002. +!TP_COLORAPP_HUE_TOOLTIP;Hue (h) - angle between 0° and 360°. +!TP_COLORAPP_LABEL;CIE Color Appearance Model 2002 +!TP_COLORAPP_LABEL_CAM02;Image Adjustments +!TP_COLORAPP_LABEL_SCENE;Scene Conditions +!TP_COLORAPP_LABEL_VIEWING;Viewing Conditions +!TP_COLORAPP_LIGHT;Lightness (J) +!TP_COLORAPP_LIGHT_TOOLTIP;Lightness in CIECAM02 differs from L*a*b* and RGB lightness. +!TP_COLORAPP_MODEL_TOOLTIP;White-Point Model.\n\nWB [RT] + [output]: RT's white balance is used for the scene, CIECAM02 is set to D50, and the output device's white balance is set in Preferences > Color Management.\n\nWB [RT+CAT02] + [output]: RT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences - Color Management. +!TP_COLORAPP_RSTPRO;Red & skin-tones protection +!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin-tones protection affects both sliders and curves. +!TP_COLORAPP_SURROUND;Surround +!TP_COLORAPP_SURROUND_AVER;Average +!TP_COLORAPP_SURROUND_DARK;Dark +!TP_COLORAPP_SURROUND_DIM;Dim +!TP_COLORAPP_SURROUND_EXDARK;Extremly Dark (Cutsheet) +!TP_COLORAPP_SURROUND_TOOLTIP;Changes tones and colors to take into account the viewing conditions of the output device.\n\nAverage: Average light environment (standard). The image will not change.\n\nDim: Dim environment (TV). The image will become slighty dark.\n\nDark: Dark environment (projector). The image will become more dark.\n\nExtremly Dark: Extremly dark environment (cutsheet). The image will become very dark. +!TP_COLORAPP_SURSOURCE;Dark surround +!TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if image has a dark border. +!TP_COLORAPP_TCMODE_BRIGHTNESS;Brightness +!TP_COLORAPP_TCMODE_CHROMA;Chroma +!TP_COLORAPP_TCMODE_COLORF;Colorfulness +!TP_COLORAPP_TCMODE_LABEL1;Curve mode 1 +!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_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] +!TP_COLORAPP_WBRT;WB [RT] + [output] +!TP_COLORTONING_AB;o C/L +!TP_COLORTONING_AUTOSAT;Automatic +!TP_COLORTONING_BALANCE;Balance +!TP_COLORTONING_BY;o C/L +!TP_COLORTONING_CHROMAC;Opacity +!TP_COLORTONING_COLOR;Color +!TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;Chroma opacity as a function of luminance oC=f(L) +!TP_COLORTONING_HIGHLIGHT;Highlights +!TP_COLORTONING_HUE;Hue +!TP_COLORTONING_LABEL;Color Toning +!TP_COLORTONING_LAB;L*a*b* blending +!TP_COLORTONING_LUMAMODE;Preserve luminance +!TP_COLORTONING_LUMAMODE_TOOLTIP;If enabled, when you change color (red, green, cyan, blue, etc.) the luminance of each pixel is preserved. +!TP_COLORTONING_LUMA;Luminance +!TP_COLORTONING_METHOD;Method +!TP_COLORTONING_METHOD_TOOLTIP;"L*a*b* blending", "RGB sliders" and "RGB curves" use interpolated color blending.\n"Color balance (Shadows/Midtones/Highlights)" and "Saturation 2 colors" use direct colors.\n\nThe Black-and-White tool can be enabled when using any color toning method, which allows for color toning. +!TP_COLORTONING_MIDTONES;Midtones +!TP_COLORTONING_NEUTRAL;Reset sliders +!TP_COLORTONING_NEUTRAL_TIP;Reset all values (Shadows, Midtones, Highlights) to default. +!TP_COLORTONING_OPACITY;Opacity +!TP_COLORTONING_RGBCURVES;RGB - Curves +!TP_COLORTONING_RGBSLIDERS;RGB - Sliders +!TP_COLORTONING_SATURATEDOPACITY;Strength +!TP_COLORTONING_SATURATIONTHRESHOLD;Threshold +!TP_COLORTONING_SA;Saturation Protection +!TP_COLORTONING_SHADOWS;Shadows +!TP_COLORTONING_SPLITCOCO;Color Balance Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITCO;Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITLR;Saturation 2 colors +!TP_COLORTONING_STRENGTH;Strength +!TP_COLORTONING_STR;Strength +!TP_COLORTONING_TWO2;Special chroma '2 colors' +!TP_COLORTONING_TWOALL;Special chroma +!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_GTHARMMEANS;Harmonic Means +!TP_CROP_GTTRIANGLE1;Golden Triangles 1 +!TP_CROP_GTTRIANGLE2;Golden Triangles 2 +!TP_DIRPYRDENOISE_33;3×3 strong +!TP_DIRPYRDENOISE_55SOFT;5×5 +!TP_DIRPYRDENOISE_55;5×5 strong +!TP_DIRPYRDENOISE_77;7×7 (slow) +!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_ABM;Chroma only +!TP_DIRPYRDENOISE_AUTO;Automatic global +!TP_DIRPYRDENOISE_AUTO_TOOLTIP;Try to evaluate chroma noise\nBe careful, this calculation is average, and is quite subjective ! +!TP_DIRPYRDENOISE_AUT;Automatic global +!TP_DIRPYRDENOISE_C2TYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CCCURVE;Chrominance curve +!TP_DIRPYRDENOISE_CHROMAFR;Chrominance +!TP_DIRPYRDENOISE_CTYPE;Auto method +!TP_DIRPYRDENOISE_CTYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nAutomatic multi-zones\nNo preview - works only during saving, but using the "Preview" method by matching the tile size and center to the preview size and center you can get an idea of the expected results.\nThe image is divided into tiles (about 10 to 70 depending on image size) and each tile receives its own chrominance noise reduction settings.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CURVEEDITOR_CC;Chroma +!TP_DIRPYRDENOISE_CURVEEDITOR_CC_TOOLTIP;Increase (multiply) the value of all chrominance sliders.\nThis curve lets you adjust the strength of chromatic noise reduction as a function of chromaticity, for instance to increase the action in areas of low saturation and to decrease it in those of high saturation. +!TP_DIRPYRDENOISE_CURVEEDITOR_L_TOOLTIP;Modulates action of 'Luminance' denoise +!TP_DIRPYRDENOISE_CUR;Curve +!TP_DIRPYRDENOISE_LABM;L*a*b* +!TP_DIRPYRDENOISE_LCURVE;Luminance curve +!TP_DIRPYRDENOISE_LM;Luminance only +!TP_DIRPYRDENOISE_LPLABM;Weighted L* (little) + a*b* (normal) +!TP_DIRPYRDENOISE_LTYPE;Luminance control +!TP_DIRPYRDENOISE_LUMAFR;Luminance +!TP_DIRPYRDENOISE_LUMAFR_TOOLTIP;Wavelet on luminance and Fourier transform for luminance detail +!TP_DIRPYRDENOISE_MANU;Manual +!TP_DIRPYRDENOISE_MAN;Manual +!TP_DIRPYRDENOISE_MEDMETHOD;Median method +!TP_DIRPYRDENOISE_MEDTYPE;Median type +!TP_DIRPYRDENOISE_MED;Median Filter +!TP_DIRPYRDENOISE_MED_TOOLTIP;Enabled median denoising +!TP_DIRPYRDENOISE_METHOD11;Quality +!TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. +!TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - +!TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 +!TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. +!TP_DIRPYRDENOISE_PASSES;Median iterations +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PON;Auto multi-zones +!TP_DIRPYRDENOISE_PREVLABEL;Preview size=%1, Center: Px=%2 Py=%3 +!TP_DIRPYRDENOISE_PREV;Preview +!TP_DIRPYRDENOISE_PRE;Preview multi-zones +!TP_DIRPYRDENOISE_RGBM;RGB +!TP_DIRPYRDENOISE_SHALBI;High +!TP_DIRPYRDENOISE_SHAL;Standard +!TP_DIRPYRDENOISE_SLI;Slider +!TP_DIRPYRDENOISE_SOFT;3x3 +!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_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_EPD_GAMMA;Gamma +!TP_EXPOSURE_TCMODE_LUMINANCE;Luminance +!TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points +!TP_EXPOS_WHITEPOINT_LABEL;Raw White Points +!TP_FILMSIMULATION_LABEL;Film Simulation +!TP_FILMSIMULATION_STRENGTH;Strength +!TP_FILMSIMULATION_ZEROCLUTSFOUND;Set HaldCLUT directory in Preferences +!TP_FLATFIELD_CLIPCONTROL;Clip control +!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. +!TP_ICM_DCPILLUMINANT_TOOLTIP;Select which embedded DCP illuminant to employ. Default is "interpolated" which is a mix between the two based on white balance. The setting is only enabled if a Dual-Illuminant DCP with interpolation support is selected. +!TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance +!TP_PREPROCESS_DEADPIXFILT;Dead pixel filter +!TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Tries to suppress dead pixels. +!TP_PREPROCESS_HOTPIXFILT;Hot pixel filter +!TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Tries to suppress hot pixels. +!TP_RAWEXPOS_BLACK_0;Green 1 (lead) +!TP_RAWEXPOS_BLACK_1;Red +!TP_RAWEXPOS_BLACK_2;Blue +!TP_RAWEXPOS_BLACK_3;Green 2 +!TP_RAWEXPOS_BLACK_BLUE;Blue +!TP_RAWEXPOS_BLACK_GREEN;Green +!TP_RAWEXPOS_BLACK_RED;Red +!TP_RAWEXPOS_RGB;Red, Green, Blue +!TP_RAW_HD;Threshold +!TP_RAW_HD_TOOLTIP;Lower values make hot/dead pixel detection more aggressive, but false positives may lead to artifacts. If you notice any artifacts appearing when enabling the Hot/Dead Pixel Filters, gradually increase the threshold value until they disappear. +!TP_RAW_SENSOR_BAYER_LABEL;Sensor with Bayer Matrix +!TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;3-pass gives best results (recommended for low ISO images).\n1-pass is almost undistinguishable from 3-pass for high ISO images and is faster. +!TP_RAW_SENSOR_XTRANS_LABEL;Sensor with X-Trans Matrix +!TP_WAVELET_1;Level 1 +!TP_WAVELET_2;Level 2 +!TP_WAVELET_3;Level 3 +!TP_WAVELET_4;Level 4 +!TP_WAVELET_5;Level 5 +!TP_WAVELET_6;Level 6 +!TP_WAVELET_7;Level 7 +!TP_WAVELET_8;Level 8 +!TP_WAVELET_9;Level 9 +!TP_WAVELET_ALL;All levels in all directions +!TP_WAVELET_APPLYTO;Apply To +!TP_WAVELET_AVOID;Avoid color shift +!TP_WAVELET_B0;Black +!TP_WAVELET_B1;Grey +!TP_WAVELET_B2;Residual +!TP_WAVELET_BACUR;Curve +!TP_WAVELET_BALANCE;Contrast balance d/v-h +!TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chromaticity or residual tone mapping are activated, the effect due to balance is amplified. +!TP_WAVELET_BALCHRO;Chroma balance +!TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chromaticity balance. +!TP_WAVELET_BANONE;None +!TP_WAVELET_BASLI;Slider +!TP_WAVELET_BATYPE;Contrast balance method +!TP_WAVELET_CCURVE;Local contrast +!TP_WAVELET_CH1;Whole chromaticity range +!TP_WAVELET_CH2;Saturated/pastel +!TP_WAVELET_CH3;Link contrast levels +!TP_WAVELET_CHCU;Curve +!TP_WAVELET_CHRO;Saturated/pastel threshold +!TP_WAVELET_CHRO_TOOLTIP;Sets the wavelet level which will be the threshold between saturated and pastel colors.\n1-x: saturated\nx-9: pastel\n\nIf the value exceeds the amount of wavelet levels you are using then it will be ignored. +!TP_WAVELET_CHR;Chroma-contrast link strength +!TP_WAVELET_CHR_TOOLTIP;Adjusts chromaticity as a function of "contrast levels" and "chroma-contrast link strength" +!TP_WAVELET_CHSL;Sliders +!TP_WAVELET_CHTYPE;Chrominance method +!TP_WAVELET_COLORT;Opacity Red-Green +!TP_WAVELET_COMBOTH;Both +!TP_WAVELET_COMPCONT;Contrast +!TP_WAVELET_COMPGAMMA;Compression gamma +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjusting the gamma of the residual image allow you to equilibrate the data and histogram. +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjust gamma for residual image and compression.\nAllow to equilibrate data and histogram +!TP_WAVELET_COMPTM;Tone mapping +!TP_WAVELET_CONTEDIT;'After' Contrast curve +!TP_WAVELET_CONTEDIT;'After' contrast curve +!TP_WAVELET_CONTRAST_MINUS;Contrast - +!TP_WAVELET_CONTRAST_PLUS;Contrast + +!TP_WAVELET_CONTRA;Contrast +!TP_WAVELET_CONTRA_TOOLTIP;Changes contrast of the residual image. +!TP_WAVELET_CONTR;Gamut +!TP_WAVELET_CTYPE;Chrominance control +!TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modifies local contrast as a function of the original local contrast (absciss)\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 100..300)\n66% absciss represents standard deviation of local contrast (real value about 300..800)\n100% represents maximum (real value about 3000..8000) +!TP_WAVELET_CURVEEDITOR_CH;Contrast levels=f(Hue) +!TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modifies each level's contrast as a function oh hue.\nTake care not to overwrite changes made with the Gamut Hue controls.\nThe curve will only have an effect when wavelet contrast level sliders are non-zero. +!TP_WAVELET_CURVEEDITOR_CL;L +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Applies a final contrast luminance curve at the end of the wavelet treatment. +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Apply a contrast luminance curve at the end of wavelet level threatment +!TP_WAVELET_CURVEEDITOR_HH;HH +!TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modifies the residual image's hue as a function of hue. +!TP_WAVELET_DALL;All directions +!TP_WAVELET_DAUB;Edge performance +!TP_WAVELET_DAUB_TOOLTIP;Changes Daubechies coefficients:\nD4 = Standard,\nD14 = Often best performance, 10% more time-intensive.\n\nAffects edge detection as well as the general quality of the firsts levels. However the quality is not strictly related to this coefficient and can vary with images and uses. +!TP_WAVELET_DISP;Preview Settings +!TP_WAVELET_DONE;Vertical +!TP_WAVELET_DTHR;Diagonal +!TP_WAVELET_DTWO;Horizontal +!TP_WAVELET_EDCU;Curve +!TP_WAVELET_EDGCONT;Local contrast +!TP_WAVELET_EDGCONT_TOOLTIP;Adjusting the points to the left decreases contrast, and to the right increases it.\nBottom-left, Top-Left, Top-Right, Bottom-right represent respectively local contast for low values, mean, mean+stdev, maxima +!TP_WAVELET_EDGEDETECTTHR2;Threshold high (detection) +!TP_WAVELET_EDGEDETECTTHR;Threshold low (noise) +!TP_WAVELET_EDGEDETECTTHR_TOOLTIP;This adjuster lets you target edge detection for example to avoid applying edge sharpness to fine details, such as noise in the sky. +!TP_WAVELET_EDGEDETECT;Gradient sensitivity +!TP_WAVELET_EDGEDETECT_TOOLTIP;Moving the slider to the right increases edge sensitivity. This affects local contrast, edge settings and noise. +!TP_WAVELET_EDGE;Edge Sharpness +!TP_WAVELET_EDGREINF_TOOLTIP;Reinforce or reduce the action of the first level, do the opposite to the second level, and leave the rest unchanged. +!TP_WAVELET_EDGTHRESH;Detail +!TP_WAVELET_EDGTHRESH_TOOLTIP;Change the repartition between the first levels and the others. The higher the threshold the more the action is centred on the first levels. Be careful with negative values, they increase the action of high levels and can introduce artifacts. +!TP_WAVELET_EDRAD;Radius +!TP_WAVELET_EDRAD_TOOLTIP;This radius adjustment is very different from those in other sharpening tools. Its value is compared to each level through a complex function. In this sense, a value of zero still has an effect. +!TP_WAVELET_EDSL;Threshold Sliders +!TP_WAVELET_EDTYPE;Local contrast method +!TP_WAVELET_EDVAL;Strength +!TP_WAVELET_FINAL;Final Touchup +!TP_WAVELET_FINEST;Finest +!TP_WAVELET_HIGHLIGHT;Highlight luminance range +!TP_WAVELET_HS1;Whole luminance range +!TP_WAVELET_HS2;Shadows/Highlights +!TP_WAVELET_HUESKIN;Skin hue +!TP_WAVELET_HUESKIN_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_HUESKY;Sky hue +!TP_WAVELET_HUESKY_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_INF;Below or equal the level +!TP_WAVELET_ITER;Delta balance levels +!TP_WAVELET_ITER_TOOLTIP;Left: increase low levels and reduce high levels,\nRight: reduce low levels and increase high levels. +!TP_WAVELET_LABEL;Wavelet levels +!TP_WAVELET_LARGEST;Coarsest +!TP_WAVELET_LEVCH;Chromaticity +!TP_WAVELET_LEVELS;Wavelet levels +!TP_WAVELET_LEVELS_TOOLTIP;Choose the number of detail levels the image is to be decomposed into. More levels require more RAM and require a longer processing time. +!TP_WAVELET_LEVF;Contrast +!TP_WAVELET_LEVLABEL;Preview maximum possible levels = %1 +!TP_WAVELET_LEVONE;Level 2 +!TP_WAVELET_LEVTWO;Level 3 +!TP_WAVELET_LEVZERO;Level 1 +!TP_WAVELET_LINKEDG;Link with Edge Sharpness' Strength +!TP_WAVELET_LIPST;Enhanced algorithm +!TP_WAVELET_LIPST_TOOLTIP;This algorithm uses Lipschitz regularity to increase edge detection quality at a cost of increased processing time and memory requirements. +!TP_WAVELET_LOWLIGHT;Shadow luminance range +!TP_WAVELET_MEDGREINF;First level +!TP_WAVELET_MEDILEV;Edge detection +!TP_WAVELET_MEDI;Reduce artifacts in blue sky +!TP_WAVELET_NEUTRAL;Neutral +!TP_WAVELET_NOISE;Denoise and Refine +!TP_WAVELET_NOIS;Denoise +!TP_WAVELET_ONE;One level +!TP_WAVELET_OPACITYWL;Final local contrast +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify final local contrast in function of last local contrast (absciss) for all levels decomposition\nTake into account: \na)contrast levels \nb)edge sharpness \nc)contrast balance\nd)decomposition-recomposition\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 200..1000)\n66% absciss represents standard deviation of local contrast (real value about 1000..2000)\n100% represents maximum (real value about 5000..13000) +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify the final local contrast at the end of the wavelet treatment.\n\nThe left side represents the smallest local contrast, progressing to the largest local contrast on the right. +!TP_WAVELET_OPACITYW;Contrast balance d/v-h curve +!TP_WAVELET_OPACITY;Opacity Blue-Yellow +!TP_WAVELET_PASTEL;Pastel chromaticity +!TP_WAVELET_PREVIEWBACK;Background +!TP_WAVELET_PREVIEWLEVELS;Preview +!TP_WAVELET_RE1;Reinforced +!TP_WAVELET_RE2;Unchanged +!TP_WAVELET_RE3;Reduced +!TP_WAVELET_RESCHRO;Chromaticity +!TP_WAVELET_RESCONH;Highlights +!TP_WAVELET_RESCON;Shadows +!TP_WAVELET_RESID;Residual image +!TP_WAVELET_SAT;Saturated chromaticity +!TP_WAVELET_SETTINGS;Wavelet Settings +!TP_WAVELET_SKIN;Skin targetting/protection +!TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected. +!TP_WAVELET_SKY;Sky targetting/protection +!TP_WAVELET_SKY_TOOLTIP;At -100 sky-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 sky-tones are protected while all other tones are affected. +!TP_WAVELET_STRENGTH;Strength +!TP_WAVELET_STREN;Strength +!TP_WAVELET_SUPE;Extra +!TP_WAVELET_SUP;Above the level +!TP_WAVELET_THRESHOLD2;Shadow levels +!TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels between 9 and 9 minus the value will be affected by the shadow luminance range. Other levels will be fully treated. The highest level possible is limited by the highlight level value (9 minus highlight level value). +!TP_WAVELET_THRESHOLD;Highlight levels +!TP_WAVELET_THRESHOLD_TOOLTIP;Only levels beyond the chosen value will be affected by the highlight luminance range. Other levels will be fully treated. The chosen value here limits the highest possible value of the shadow levels. +!TP_WAVELET_THRH;Highlights threshold +!TP_WAVELET_THR;Shadows threshold +!TP_WAVELET_TILESBIG;Big tiles +!TP_WAVELET_TILESFULL;Full image +!TP_WAVELET_TILESIZE;Tiling method +!TP_WAVELET_TILESLIT;Little tiles +!TP_WAVELET_TILES_TOOLTIP;Processing the full image leads to better quality and is the recommended option, while using tiles is a fall-back solution for users with little RAM. Refer to RawPedia for memory requirements. +!TP_WAVELET_TMHIGH;High +!TP_WAVELET_TMLOWHIGH;Low+High +!TP_WAVELET_TMNONE;None +!TP_WAVELET_TMSTD;Standard +!TP_WAVELET_TMSTRENGTH;Compression strength +!TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image. When the value is different from 0, the Strength and Gamma sliders of the Tone Mapping tool in the Exposure tab will become grayed out. +!TP_WAVELET_TMTYPE;Compression method +!TP_WAVELET_TON;Toning +!TP_WAVELET_daub2;D2 - low +!TP_WAVELET_daub4;D4 - standard +!TP_WAVELET_daub6;D6 - standard plus +!TP_WAVELET_daub10;D10 - medium +!TP_WAVELET_daub14;D14 - high +!ZOOMPANEL_ZOOMFITCROPSCREEN;Fit crop to screen\nShortcut: Alt-f diff --git a/rtdata/languages/Serbian (Cyrilic Characters) b/rtdata/languages/Serbian (Cyrilic Characters) new file mode 100644 index 000000000..79e01fe4e --- /dev/null +++ b/rtdata/languages/Serbian (Cyrilic Characters) @@ -0,0 +1,1857 @@ +#01 2010-11-16 gpopac + +ABOUT_TAB_BUILD;Издање +ABOUT_TAB_CREDITS;Заслуге +ABOUT_TAB_LICENSE;Лиценца +ABOUT_TAB_SPLASH;Увод +ADJUSTER_RESET_TO_DEFAULT;Врати на подразумевано +BATCHQUEUE_AUTOSTART;Сам започни +BATCH_PROCESSING;обрада +CURVEEDITOR_CURVES;Кривуље +CURVEEDITOR_CURVE;Кривуља +CURVEEDITOR_CUSTOM;Произвољно +CURVEEDITOR_DARKS;Тамно +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;Фасцикле +EDITWINDOW_TITLE;Уређивање слике +EXIFFILTER_APERTURE;Отвор бленде +EXIFFILTER_CAMERA;Фото апарат +EXIFFILTER_FILETYPE;Врста датотеке +EXIFFILTER_FOCALLEN;Жижна даљина +EXIFFILTER_ISO;ИСО +EXIFFILTER_LENS;Објектив +EXIFFILTER_METADATAFILTER;Филтрирај метаподатке +EXIFFILTER_SHUTTER;Експозиција +EXIFPANEL_ADDEDITHINT;Додаје нову ознаку или уређује постојећу +EXIFPANEL_ADDEDIT;Додај/Измени +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Унесите вредност +EXIFPANEL_ADDTAGDLG_SELECTTAG;Изаберите ознаку +EXIFPANEL_ADDTAGDLG_TITLE;Додај/Измени ознаку +EXIFPANEL_KEEPHINT;Задржава изабране ознаке при упису излазне датотеке +EXIFPANEL_KEEP;Задржи +EXIFPANEL_REMOVEHINT;Уклања изабране ознаке при упису излазне датотеке +EXIFPANEL_REMOVE;Уклони +EXIFPANEL_RESETALLHINT;Враћа све ознаке на почетне вредности +EXIFPANEL_RESETALL;Врати све +EXIFPANEL_RESETHINT;Враћа изабрану ознаку на почетну вредности +EXIFPANEL_RESET;Врати +EXIFPANEL_SUBDIRECTORY;Поддиректоријум +FILEBROWSER_ADDDELTEMPLATE;Додај/уклони шаблоне... +FILEBROWSER_APPLYPROFILE;Примени профил +FILEBROWSER_APPLYPROFILE_PARTIAL;Примени профил (половично) +FILEBROWSER_AUTODARKFRAME;Сам одреди тамни кадар +FILEBROWSER_AUTOFLATFIELD;Аутоматски одреди равно поље +FILEBROWSER_BROWSEPATHBUTTONHINT;Кликните за одлазак на узабрану путању +FILEBROWSER_BROWSEPATHHINT;Укуцајте путању за разгледање (Ctrl-o поставља фокус, Ctrl-Enter приказује у разгледачу датотека);nПречице путања: ~ — лични директоријум, ! — директоријум са сликама +FILEBROWSER_CACHECLEARFROMFULL;Очисти из оставе — све +FILEBROWSER_CACHECLEARFROMPARTIAL;Очисти из оставе — половично +FILEBROWSER_CACHE;Остава +FILEBROWSER_CLEARPROFILE;Обриши профил +FILEBROWSER_COPYPROFILE;Умножи профил +FILEBROWSER_CURRENT_NAME;Тренутно име: +FILEBROWSER_DARKFRAME;Тамни кадар +FILEBROWSER_DELETEDLGLABEL;Брисање датотеке +FILEBROWSER_DELETEDLGMSGINCLPROC;Да ли желите да обришете %1 изабраних датотека, укључујући и оне које су заказане? +FILEBROWSER_DELETEDLGMSG;Да ли сигурно желите да обришете %1 датотека? +FILEBROWSER_EMPTYTRASHHINT;Трајно брише датотеке из смећа +FILEBROWSER_EMPTYTRASH;Избаци смеће +FILEBROWSER_EXEC_CPB;Изгради почетни профил +FILEBROWSER_FLATFIELD;Равно поље +FILEBROWSER_MOVETODARKFDIR;Пребаци у фасциклу са тамним кадровима +FILEBROWSER_MOVETOFLATFIELDDIR;Премести у фасцикли са равним пољима +FILEBROWSER_NEW_NAME;Ново име: +FILEBROWSER_PARTIALPASTEPROFILE;Делимично убаци +FILEBROWSER_PASTEPROFILE;Убаци профил +FILEBROWSER_POPUPCANCELJOB;Откажи задатак +FILEBROWSER_POPUPCOLORLABEL;Обојена ознака +FILEBROWSER_POPUPCOPYTO;Умножи у... +FILEBROWSER_POPUPFILEOPERATIONS;Датотека +FILEBROWSER_POPUPMOVEEND;Премести на крај заказаних +FILEBROWSER_POPUPMOVEHEAD;Премести на почетак заказаних +FILEBROWSER_POPUPMOVETO;Премести у... +FILEBROWSER_POPUPOPENINEDITOR;Отвори у уреднику +FILEBROWSER_POPUPOPEN;Отвори +FILEBROWSER_POPUPPROCESS;Закажи за обраду +FILEBROWSER_POPUPPROFILEOPERATIONS;Профил +FILEBROWSER_POPUPREMOVEINCLPROC;Уклони из система датотека и заказаног +FILEBROWSER_POPUPREMOVE;Уклони из система датотека +FILEBROWSER_POPUPRENAME;Преименуј +FILEBROWSER_POPUPSELECTALL;Изабери све +FILEBROWSER_POPUPTRASH;Премести у смеће +FILEBROWSER_POPUPUNRANK;Уклони оцену +FILEBROWSER_POPUPUNTRASH;Уклони из смећа +FILEBROWSER_QUERYBUTTONHINT;Очисти поље за претрагу +FILEBROWSER_QUERYHINT;Унесите део имена датотеке за претрагу nCtrl-f поставља фокус (у Разгледачу датотека);nEnter претражује +FILEBROWSER_QUERYLABEL; Тражи: +FILEBROWSER_RENAMEDLGLABEL;Преименуј датотеку +FILEBROWSER_RENAMEDLGMSG;Преименуј датотеку „%1“ у: +FILEBROWSER_SELECTDARKFRAME;Изабери тамни кадар... +FILEBROWSER_SELECTFLATFIELD;Изабери равно поље... +FILEBROWSER_SHOWCOLORLABEL1HINT;Приказује слике означене црвеном Alt-1 +FILEBROWSER_SHOWCOLORLABEL2HINT;Приказује слике означене жутом Alt-2 +FILEBROWSER_SHOWCOLORLABEL3HINT;Приказујеслике означене зеленом Alt-3 +FILEBROWSER_SHOWCOLORLABEL4HINT;Приказује слике означене плавом Alt-4 +FILEBROWSER_SHOWCOLORLABEL5HINT;Приказује слике означене љубичастом Alt-5 +FILEBROWSER_SHOWDIRHINT;Приказује све слике из директоријума +FILEBROWSER_SHOWEDITEDHINT;Приказује само измењене слике 7 +FILEBROWSER_SHOWEDITEDNOTHINT;Приказује само неисмењене слике 6 +FILEBROWSER_SHOWEXIFINFO;Приказује EXIF податке и +FILEBROWSER_SHOWRANK1HINT;Приказује слике оцењене са 1 звездицом +FILEBROWSER_SHOWRANK2HINT;Приказује слике оцењене са 2 звездице +FILEBROWSER_SHOWRANK3HINT;Приказује слике оцењене са 3 звездице +FILEBROWSER_SHOWRANK4HINT;Приказује слике оцењене са 4 звездице +FILEBROWSER_SHOWRANK5HINT;Приказује слике оцењене са 5 звездица +FILEBROWSER_SHOWRECENTLYSAVEDHINT;Приказује недавно сачуване слике Alt-7 +FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Приказује слике које нису скоро сачуване Alt-6 +FILEBROWSER_SHOWTRASHHINT;Приказује слике у смећу +FILEBROWSER_SHOWUNCOLORHINT;Приказује слике које нису означене бојом Alt-0 +FILEBROWSER_SHOWUNRANKHINT;Прикажи неоцењене слике +FILEBROWSER_STARTPROCESSINGHINT;Почиње обраду и чување заказаних слика +FILEBROWSER_STARTPROCESSING;Започни обраду +FILEBROWSER_STOPPROCESSINGHINT;Зауставља обраду слика +FILEBROWSER_STOPPROCESSING;Заустави обраду +FILEBROWSER_THUMBSIZE;Преглед +FILEBROWSER_TOOLTIP_STOPPROCESSING;Покреће обраду фотографија када их закажете +FILEBROWSER_ZOOMINHINT;Увећава преглед +FILEBROWSER_ZOOMOUTHINT;Умањује преглед +GENERAL_ABOUT;О програму +GENERAL_AFTER;После +GENERAL_BEFORE;Пре +GENERAL_CANCEL;Откажи +GENERAL_DISABLED;Искључено +GENERAL_DISABLE;Искључи +GENERAL_ENABLED;Укључи +GENERAL_ENABLE;Укључи +GENERAL_FILE;Датотека +GENERAL_LANDSCAPE;Положено +GENERAL_NA;нема +GENERAL_NONE;Ништа +GENERAL_NO;Не +GENERAL_OK;У реду +GENERAL_PORTRAIT;Усправно +GENERAL_SAVE;Сачувај +GENERAL_UNCHANGED;(неизмењено) +HISTOGRAM_TOOLTIP_BAR;Приказује/сакрива РГБ индикатор. Кликните десни тастер миша на умањени приказ да замрзнете +HISTOGRAM_TOOLTIP_B;Приказује плави хистограм +HISTOGRAM_TOOLTIP_G;Приказује зелени хистограм +HISTOGRAM_TOOLTIP_L;Приказује ЦиеЛаб хитограм +HISTOGRAM_TOOLTIP_RAW;Приказује/скрива RAW хистограм +HISTOGRAM_TOOLTIP_R;Приказује црвени хистограм +HISTORY_CHANGED;Измењено +HISTORY_CUSTOMCURVE;Произвољна крива +HISTORY_DELSNAPSHOT;Уклони +HISTORY_FROMCLIPBOARD;Из оставе +HISTORY_LABEL;Историјат +HISTORY_MSG_1;Слика је учитана +HISTORY_MSG_2;Профил је учитан +HISTORY_MSG_3;Измена профила +HISTORY_MSG_4;Разгледање историјата +HISTORY_MSG_5;Осветљеност +HISTORY_MSG_6;Контраст +HISTORY_MSG_7;Црна +HISTORY_MSG_8;Компензација експозиције +HISTORY_MSG_9;Сабијање светлог +HISTORY_MSG_10;Сабијање сенки +HISTORY_MSG_11;Крива нијанси +HISTORY_MSG_12;Ауто експозиција +HISTORY_MSG_13;Одсецање експозиције +HISTORY_MSG_14;Светлина луминансе +HISTORY_MSG_15;Контраст луминансе +HISTORY_MSG_16;Црна луминансе +HISTORY_MSG_17;Сабијање сенки л. +HISTORY_MSG_18;Сабијање светлог л. +HISTORY_MSG_19;Крива луминансе +HISTORY_MSG_20;Оштрење +HISTORY_MSG_21;Полупречник оштрења +HISTORY_MSG_22;Количина оштрења +HISTORY_MSG_23;Праг оштрења +HISTORY_MSG_24;Изоштри само ивице +HISTORY_MSG_25;Полупречник за налажење ивица +HISTORY_MSG_26;Толеранција за налажење ивица +HISTORY_MSG_27;Контрола ареола оштрења +HISTORY_MSG_28;Количина контроле ареала +HISTORY_MSG_29;Начин оштрења +HISTORY_MSG_30;Полупречник деконволуције +HISTORY_MSG_31;Количина деконволуције +HISTORY_MSG_32;Пригушивање деконволуције +HISTORY_MSG_33;Понављања деконволуције +HISTORY_MSG_34;Избегни одсецање боја +HISTORY_MSG_35;Граничник засићења +HISTORY_MSG_36;Ограничи засићење +HISTORY_MSG_37;Појачање боја +HISTORY_MSG_38;Начин балансирања беле +HISTORY_MSG_39;Температура боје +HISTORY_MSG_40;Заленило боје +HISTORY_MSG_41;Померај боје „А“ +HISTORY_MSG_42;Померај боје „Б“ +HISTORY_MSG_43;Уклањање светлосног шума +HISTORY_MSG_44;Радијус укл. светлосног шума +HISTORY_MSG_45;Толеранција ивице укл. с. шума +HISTORY_MSG_46;Уклањање колорног шума +HISTORY_MSG_47;Полупречник укл. колорног шума +HISTORY_MSG_48;Толеранција ивице укл. к. шума +HISTORY_MSG_49;Осетљивост ивице укл. к. шума +HISTORY_MSG_50;Алат за сенке/светло +HISTORY_MSG_51;Појачавање светлине +HISTORY_MSG_52;Појачавање сенки +HISTORY_MSG_53;Ширина тонова за светло +HISTORY_MSG_54;Ширина тонова за сенке +HISTORY_MSG_55;Ликални контраст +HISTORY_MSG_56;Полупречник сенки/светлог +HISTORY_MSG_57;Груба ротација +HISTORY_MSG_58;Хоризонтално извртање +HISTORY_MSG_59;Вертикално извртање +HISTORY_MSG_60;Ротација +HISTORY_MSG_61;Ротација +HISTORY_MSG_62;Исправљање изобличења сочива +HISTORY_MSG_63;Ибор снимка +HISTORY_MSG_64;Исеци фотографију +HISTORY_MSG_65;Исправљање хр. аберација +HISTORY_MSG_66;Чупање светла +HISTORY_MSG_67;Количина чупања светла +HISTORY_MSG_68;Начин чупања светла +HISTORY_MSG_69;Радни простор боја +HISTORY_MSG_70;Излазни простор боја +HISTORY_MSG_71;Улазни профил боја +HISTORY_MSG_72;Исправљање вињетарења +HISTORY_MSG_73;Мешање канала +HISTORY_MSG_74;Промена величине +HISTORY_MSG_75;Начин промене величине +HISTORY_MSG_76;Exif метаподаци +HISTORY_MSG_77;ИПТЦ метаподаци +HISTORY_MSG_78;Подаци за промени величине +HISTORY_MSG_79;Ширина при промени величине +HISTORY_MSG_80;Висина при промени величине +HISTORY_MSG_81;Укључена промена величина +HISTORY_MSG_82;Профил је измењен +HISTORY_MSG_83;Квалитетно светлост/сенке +HISTORY_MSG_84;Исправљање перспективе +HISTORY_MSG_85;Талоасни коефицијенти +HISTORY_MSG_86;Таласно уједначење +HISTORY_MSG_87;Уклањање шума „бибер и со“ +HISTORY_MSG_88;Праг уклањања шума за „бибер и со“ +HISTORY_MSG_89;Уклањање шума +HISTORY_MSG_90;Шум — осветљеност +HISTORY_MSG_91;Шум — боје +HISTORY_MSG_92;Шум — гама +HISTORY_MSG_93;Контраст детањном вредношћу нивоа +HISTORY_MSG_94;Детањни ниво контрастa +HISTORY_MSG_95;Засићеност +HISTORY_MSG_96;„а“ крива +HISTORY_MSG_97;„б“ крива +HISTORY_MSG_98;Растављам мозаик +HISTORY_MSG_99;Обрађујем +HISTORY_MSG_100;РГБ засићеност +HISTORY_MSG_101;ХСВ EQ — Нијанса +HISTORY_MSG_102;ХСВ EQ — Засићеност +HISTORY_MSG_103;ХСВ EQ — Вреднсот +HISTORY_MSG_104;Уједначење ХСВ +HISTORY_MSG_105;Уклањање ореола +HISTORY_MSG_106;Полупречник +HISTORY_MSG_107;Праг +HISTORY_MSG_108;Праг компенз. светлог +HISTORY_MSG_109;Оквир за промену величине +HISTORY_MSG_110;Промена величине примењена на +HISTORY_MSG_111;Избегни исецање боја +HISTORY_MSG_112;Ограничавање засићења +HISTORY_MSG_113;Граничник засићења +HISTORY_MSG_114;ДЦБ понављања +HISTORY_MSG_115;Понављање лажних боја +HISTORY_MSG_116;Унапређени ДЦБ +HISTORY_MSG_117;Поправка црвене хроминансе +HISTORY_MSG_118;Поправка плаве хроминансе +HISTORY_MSG_119;Линијско уклаљање шума +HISTORY_MSG_120;Праг уједначења зелене +HISTORY_MSG_121;Сам исправи аберације +HISTORY_MSG_122;Сам примени тамни кадар +HISTORY_MSG_123;Датотека за тамни кадар +HISTORY_MSG_124;Линеарна исправка експ. +HISTORY_MSG_125;Поправка експ. уз очување светлог +HISTORY_MSG_126;Датотека са равним пољем +HISTORY_MSG_127;Сам изабери равно поље +HISTORY_MSG_128;Полупречник равног поља +HISTORY_MSG_129;Начин замућења равног поља +HISTORY_MSG_130;Аутоматска дисторзија +HISTORY_MSG_131;Уклањање шума луминансе +HISTORY_MSG_132;Уклањање шума боје +HISTORY_MSG_133;Гама +HISTORY_MSG_134;Гама позиција +HISTORY_MSG_135;Гама слобода +HISTORY_MSG_136;Гама нагиб +HISTORY_MSG_137;Ниво црне зелена 1 +HISTORY_MSG_138;Ниво црне црвена +HISTORY_MSG_139;Ниво црне плава +HISTORY_MSG_140;Ниво црне зелена 2 +HISTORY_MSG_141;Ниво црне обе зелене +HISTORY_MSG_142;Оштрење ивица - бр. понављања +HISTORY_MSG_143;Оштрење ивица - количина +HISTORY_MSG_144;Микроконтраст - количина +HISTORY_MSG_145;Микроконтраст - уједначеност +HISTORY_MSG_146;Оштрење ивица +HISTORY_MSG_147;Оштрење ивица - само луминанса +HISTORY_MSG_148;Микроконтраст +HISTORY_MSG_149;Микроконтраст - 3x3 матрица +HISTORY_MSG_150;Уклањање артефакта/шума након расклапања мозаика +HISTORY_NEWSNAPSHOT;Додај +HISTORY_SNAPSHOTS;Снимак +HISTORY_SNAPSHOT;Снимак +IPTCPANEL_AUTHORSPOSITIONHINT;Звање једног или више аутора (једно по реди). +IPTCPANEL_AUTHORSPOSITION;Звање аутора +IPTCPANEL_AUTHOR;Аутор +IPTCPANEL_CAPTIONHINT;Кратак опис дела (наслов — абстракт). +IPTCPANEL_CAPTIONWRITERHINT;Име особе које је укључена у писање, уређивање или исправљање слике/назица/апстракта (писац — уредник). +IPTCPANEL_CAPTIONWRITER;Писац наслова +IPTCPANEL_CAPTION;Назив +IPTCPANEL_CATEGORYHINT;Одређује шта се налази на слици (категорија). +IPTCPANEL_CATEGORY;Категорија +IPTCPANEL_CITYHINT;Град у коме је слика настало (град). +IPTCPANEL_CITY;Град +IPTCPANEL_COPYHINT;Коппирај ИПТЦ пшодешавања у оставу +IPTCPANEL_COPYRIGHTHINT;Белешка о ауторским правима над делом (белешка о ауторским правима). +IPTCPANEL_COPYRIGHT;Ауторска права +IPTCPANEL_COUNTRYHINT;Име државе/основног места где је настала слика (држава — назив места). +IPTCPANEL_COUNTRY;Држава +IPTCPANEL_CREDITHINT;Указује да онај ко издаје слику не мора бити аутор/власник (Заслуге). +IPTCPANEL_CREDIT;Заслуге +IPTCPANEL_DATECREATEDHINT;Датум када је стављено власништво над интелектуални садржај слике; Формат: ГГГГММДД (датум настанка). +IPTCPANEL_DATECREATED;Датум настанка +IPTCPANEL_EMBEDDEDHINT;Врати поља на ИПТЦ податке угњежђене у слику +IPTCPANEL_EMBEDDED;Угњежђено +IPTCPANEL_HEADLINEHINT;Назив који указује на везу са садржајем слике и под којим се она издаје (наслов). +IPTCPANEL_HEADLINE;Наслов +IPTCPANEL_INSTRUCTIONSHINT;Остала упутства уредника везана за употребу слике (специјална упутства). +IPTCPANEL_INSTRUCTIONS;Упутства +IPTCPANEL_KEYWORDSHINT;Речи које указују на разне податке о слици (кључне речи). +IPTCPANEL_KEYWORDS;Кључне речи +IPTCPANEL_PASTEHINT;Убаци ИПТЦ подешавања из оставе +IPTCPANEL_PROVINCEHINT;Покрајина/држава где је настала слика (провинција — држава). +IPTCPANEL_PROVINCE;Покрајина +IPTCPANEL_RESETHINT;Поставља подразумеване вредности профила +IPTCPANEL_RESET;Врати +IPTCPANEL_SOURCEHINT;Првобитни власник иннтелектуалног садржаја на слици (извор). +IPTCPANEL_SOURCE;Извор +IPTCPANEL_SUPPCATEGORIESHINT;Додатно одређује мотив на слици (додатне категорије). +IPTCPANEL_SUPPCATEGORIES;Доп. категорије +IPTCPANEL_TITLEHINT;Кратни назив слике (име објекта). +IPTCPANEL_TITLE;Натпис +IPTCPANEL_TRANSREFERENCEHINT;Код којји представља место првобитног преноса (референца првог преноса). +IPTCPANEL_TRANSREFERENCE;Реф. преноса +MAIN_BUTTON_FULLSCREEN;Цео екран +MAIN_BUTTON_PREFERENCES;Поставке +MAIN_BUTTON_PUTTOQUEUE;Закажи +MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Додаје тренутну слику у заказане Ctrl+B +MAIN_BUTTON_SAVE;Сачувај +MAIN_BUTTON_SAVE_TOOLTIP;Чува тренутну слику Ctrl+С +MAIN_BUTTON_SENDTOEDITOR;Уреди +MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Уређује тренутну слику у спољном програму Ctrl+Е +MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Приказује/сакрива све бочне површине m +MAIN_BUTTON_UNFULLSCREEN;Напусти цео екран +MAIN_FRAME_BATCHQUEUE;Заказане датотеке +MAIN_FRAME_BATCHQUEUE_TOOLTIP; Заказано Ctrl-F3 +MAIN_FRAME_EDITOR;Уређивач +MAIN_FRAME_EDITOR_TOOLTIP; Уређивач Ctrl-F4 +MAIN_FRAME_FILEBROWSER;Разгледач датотека +MAIN_FRAME_FILEBROWSER_TOOLTIP; Разгледач датотека Ctrl-F2 +MAIN_FRAME_PLACES;Места +MAIN_FRAME_PLACES_ADD;Додај +MAIN_FRAME_PLACES_DEL;Уклони +MAIN_FRAME_RECENT;Recent Фасцикле +MAIN_MSG_ALREADYEXISTS;Датотека већ постоји. +MAIN_MSG_CANNOTLOAD;Не могу да учитам слику +MAIN_MSG_CANNOTSAVE;Грешка при чувању датотеке +MAIN_MSG_CANNOTSTARTEDITOR;Не могу да покренем програм за уређивање. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Изаберите исправну путању у „Поставкама“. +MAIN_MSG_EMPTYFILENAME;Није одређено име датотеке! +MAIN_MSG_NAVIGATOR;Навигатор +MAIN_MSG_QOVERWRITE;Да ли желите да препишете? +MAIN_TAB_COLOR;Боја +MAIN_TAB_COLOR_TOOLTIP;Alt-c +MAIN_TAB_DETAIL;Детаљи +MAIN_TAB_DETAIL_TOOLTIP;Alt-d +MAIN_TAB_DEVELOP;Развијање +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;Светлост +MAIN_TAB_EXPOSURE_TOOLTIP;Alt-e +MAIN_TAB_FILTER;Филтер +MAIN_TAB_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_TOOLTIP;Alt-t +MAIN_TOOLTIP_HIDEHP;Приказује/сакрива леву површ, заједно са историјатом (пречица: Х) +MAIN_TOOLTIP_INDCLIPPEDH;Приказује исечене светле делове +MAIN_TOOLTIP_INDCLIPPEDS;Приказује исечене тамне делове +MAIN_TOOLTIP_QINFO;Основни подаци о слици И +MAIN_TOOLTIP_SHOWHIDELP1;Приказује/сакрива леву површ l +MAIN_TOOLTIP_SHOWHIDERP1;Приказује/сакрива десну површ Alt-l +MAIN_TOOLTIP_SHOWHIDETP1;Приказује/сакрива горњу површ Shift-L +MAIN_TOOLTIP_TOGGLE;Приказује слику пре и после обраде Б +NAVIGATOR_XY_NA;x = ○, y = ○ +PARTIALPASTE_BASICGROUP;Основна подешавања +PARTIALPASTE_CACORRECTION;Исправљање аберација +PARTIALPASTE_CHANNELMIXER;Мешање канала +PARTIALPASTE_COARSETRANS;Ротација за 90˚ / извртање +PARTIALPASTE_COLORGROUP;Подешавање боја +PARTIALPASTE_COMMONTRANSFORMPARAMS;Сам попуни +PARTIALPASTE_COMPOSITIONGROUP;Подешавање композиције +PARTIALPASTE_CROP;Исеци +PARTIALPASTE_DARKFRAMEAUTOSELECT;Аутоматски избор тамног кадра +PARTIALPASTE_DARKFRAMEFILE;Датотека за тамни кадар +PARTIALPASTE_DEFRINGE;Уклањање ореола +PARTIALPASTE_DETAILGROUP;Подешавање детаља +PARTIALPASTE_DIALOGLABEL;Делимочно убацује профил за обраду +PARTIALPASTE_DIRPYRDENOISE;Уклањање шума +PARTIALPASTE_DIRPYREQUALIZER;Контраст нивоима детаља +PARTIALPASTE_DISTORTION;Исправљање изобличења +PARTIALPASTE_EVERYTHING;Све +PARTIALPASTE_EXIFCHANGES;Измене exif података +PARTIALPASTE_EXPOSURE;Експозиција +PARTIALPASTE_FLATFIELDAUTOSELECT;Аутоматски избор РК +PARTIALPASTE_FLATFIELDBLURRADIUS;Полупречник замућења РК +PARTIALPASTE_FLATFIELDBLURTYPE;Начин замућења РК +PARTIALPASTE_FLATFIELDFILE;Датотека за равни кадар +PARTIALPASTE_HSVEQUALIZER;Уједначење ХСВ +PARTIALPASTE_ICMSETTINGS;ИЦМ подешавања +PARTIALPASTE_IMPULSEDENOISE;Импулсно уклањање шума +PARTIALPASTE_IPTCINFO;ИПТЦ подави +PARTIALPASTE_LABCURVE;Лаб крива +PARTIALPASTE_LENSGROUP;Подешавања објектива +PARTIALPASTE_METAGROUP;Метаподаци +PARTIALPASTE_PERSPECTIVE;Перспектива +PARTIALPASTE_PREPROCESS_GREENEQUIL;Уједначавање зелене +PARTIALPASTE_PREPROCESS_LINEDENOISE;Линијски филтер шума +PARTIALPASTE_RAWCACORR_AUTO;Ауто хроматске аберације +PARTIALPASTE_RAWCACORR_CABLUE;Плава хроминанса +PARTIALPASTE_RAWCACORR_CARED;Црвена хроминанса +PARTIALPASTE_RAWEXPOS_BLACK;Ниво црне +PARTIALPASTE_RAWEXPOS_LINEAR;Линеарни фактор исправке RAW беле тачке +PARTIALPASTE_RAWEXPOS_PRESER;Raw тачка беле уз очување светлих делова +PARTIALPASTE_RAWGROUP;Raw подешавања +PARTIALPASTE_RAW_DCBENHANCE;Примени корак ДЦБ побољшања +PARTIALPASTE_RAW_DCBITERATIONS;Број ДЦБ понављања +PARTIALPASTE_RAW_DMETHOD;Начин расклапања мозаика +PARTIALPASTE_RAW_FALSECOLOR;Кораци пригушења лажне боје при расклапању мозаика +PARTIALPASTE_RESIZE;Промена величине +PARTIALPASTE_ROTATION;Ротација +PARTIALPASTE_SHADOWSHIGHLIGHTS;Сенке/Светлост +PARTIALPASTE_SHARPENEDGE;Ивице +PARTIALPASTE_SHARPENING;Оштрење +PARTIALPASTE_SHARPENMICRO;Микроконтраст +PARTIALPASTE_VIGNETTING;Исправљање вињетарења +PARTIALPASTE_WHITEBALANCE;Баланс беле +PREFERENCES_ADD;Додај +PREFERENCES_APPLNEXTSTARTUP;примењује се након поновног покретања +PREFERENCES_AUTOMONPROFILE;Сам примени профиле монитора из оперативног система +PREFERENCES_BATCH_PROCESSING;Обрада закзаног +PREFERENCES_BEHAVIOR;Понашање +PREFERENCES_CACHECLEARALL;Обриши све +PREFERENCES_CACHECLEARPROFILES;Обриши профиле +PREFERENCES_CACHECLEARTHUMBS;Обриши приказе +PREFERENCES_CACHEMAXENTRIES;Највећи број мест у остави +PREFERENCES_CACHEOPTS;Подешавање оставе +PREFERENCES_CACHETHUMBHEIGHT;Највећа висина приказа +PREFERENCES_CLIPPINGIND;Показивачи одсечених делова +PREFERENCES_CMETRICINTENT;Колориметријска намера +PREFERENCES_CUSTPROFBUILDHINT;Извршна датотека (или скрипта) која се позива када изграђујете нови почетни профил за слику.nПрихвата параметре из командне линије ради прављења .pp3 датотеке на основу неких правила:n[Путања до RAW/JPG] [Путања подразумеваног профила] [Бленда] [Експозиција у s] [Жижна дужина mm] [ИСО] [Објектив] [Фото-апарат] +PREFERENCES_CUSTPROFBUILDPATH;Извршна путања +PREFERENCES_CUSTPROFBUILD;Изградња произвољног почетног профила слике +PREFERENCES_CUTOVERLAYBRUSH;Маска исецања боје/провидног +PREFERENCES_DARKFRAMEFOUND;Нађен +PREFERENCES_DARKFRAMESHOTS;снимака +PREFERENCES_DARKFRAMETEMPLATES;шаблони +PREFERENCES_DARKFRAME;Тамни кадар +PREFERENCES_DATEFORMATHINT;Можете задати следеће формате:\n%y :година\n%m : месец\n%d : дан\n\nУ Србији се највише користи:\n%d.%m.%y +PREFERENCES_DATEFORMAT;Формат датума +PREFERENCES_DEFAULTLANG;Језик програма +PREFERENCES_DEFAULTTHEME;Тема програма +PREFERENCES_DIRDARKFRAMES;Директоријум тамног кадра +PREFERENCES_DIRHOME;Лични директоријум +PREFERENCES_DIRLAST;Последњи директоријум +PREFERENCES_DIROTHER;Неки други +PREFERENCES_DIRSELECTDLG;Бира одређени директоријум са сликама... +PREFERENCES_DIRSOFTWARE;Директоријум са инсталацијом +PREFERENCES_EDITORCMDLINE;Произвољна наредба +PREFERENCES_EDITORLAYOUT;Размештај програма +PREFERENCES_EXTERNALEDITOR;Спољни уређивач +PREFERENCES_FBROWSEROPTS;Опције разгледача датотеке +PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Прикажи алатке у једном реду +PREFERENCES_FILEFORMAT;Формат датотеке +PREFERENCES_FLATFIELDFOUND;Нађено +PREFERENCES_FLATFIELDSDIR;Директоријум за равна поља +PREFERENCES_FLATFIELDSHOTS;снимака +PREFERENCES_FLATFIELDTEMPLATES;шаблони +PREFERENCES_FLATFIELD;Равно поље +PREFERENCES_FORIMAGE;За датотеке са сликама +PREFERENCES_FORRAW;За RAW датотеке +PREFERENCES_GIMPPATH;Директоријум са инсталираним Гимпом +PREFERENCES_HISTOGRAMPOSITIONLEFT;Хистограм у левој површи +PREFERENCES_HLTHRESHOLD;Праг за одсечене светле делове +PREFERENCES_ICCDIR;ИЦЦ директоријум +PREFERENCES_IMPROCPARAMS;Подразумевани параметри за обраду слика +PREFERENCES_INTENT_ABSOLUTE;Апсолутно колориметријски +PREFERENCES_INTENT_PERCEPTUAL;Перцептуално +PREFERENCES_INTENT_RELATIVE;Релативно колориметријски +PREFERENCES_INTENT_SATURATION;Засићени приказ +PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Користи угњежђени RAW приказ до измене +PREFERENCES_LANGAUTODETECT;Сам откриј +PREFERENCES_MENUGROUPFILEOPERATIONS;Групиши радње над датотекама +PREFERENCES_MENUGROUPLABEL;Групиши обележавање +PREFERENCES_MENUGROUPPROFILEOPERATIONS;Групиши радње са профилима +PREFERENCES_MENUGROUPRANK;Групиши оцењивање +PREFERENCES_MENUOPTIONS;Опције менија +PREFERENCES_METADATA;Метаподаци +PREFERENCES_MONITORICC;Профил монитора +PREFERENCES_MULTITABDUALMON;Режим у више листова, на другом монитору +PREFERENCES_MULTITAB;Режим у више листова +PREFERENCES_OUTDIRFOLDERHINT;Ставља сачуване слике у +PREFERENCES_OUTDIRFOLDER;Сачувај у фасциклу +PREFERENCES_OUTDIRTEMPLATEHINT;Можете да задате следеће скраћенице за форматирање:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nОви знакови за форматирање се односе на директоријуме, подпутање путања до raw датотеке.\n\nНа пример, уколико је отворена слика /home/ivan/слике/02.09.2010/dsc0012.nef, скраћенице означавају:\n%f=dsc0012, %d1=02.09.2010, %d2=слике, ...\n%p1=/home/ivan/слике/02.09.2010, %p2=/home/ivan/слике, %p3=/home/ivan, ...\n\nУколико желите да сачувате развијену слику поред оригинала, унесите:\n%p1/%f\n\nУколико желите да сачувате излазну слику у директоријум „развијене“ који се налази где и оригинална слика, унесите:\n%p1/развијене/%f\n\nУколико желите да сачувате развијену слику у директоријум „/home/ivan/развијене“, а да структура поддиректоријума остане очувана, унесите:\n%p2/развијене/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Употреби шаблон +PREFERENCES_OUTDIR;Излазни директоријум +PREFERENCES_OVERLAY_FILENAMES;Постави преко умањеног приказа +PREFERENCES_OVERWRITEOUTPUTFILE;Препиши постојеће излазне датотеке +PREFERENCES_PANFACTORLABEL;Фактор +PREFERENCES_PARSEDEXTADDHINT;Додаје уписану екстензију на списак +PREFERENCES_PARSEDEXTADD;Додај екстензију +PREFERENCES_PARSEDEXTDELHINT;Брише изабрану екстензију из списка +PREFERENCES_PARSEDEXT;Екстензије за приказ +PREFERENCES_PROFILEHANDLING;Рад са профилима обраде +PREFERENCES_PROFILELOADPR;Приоритет учитавања профила +PREFERENCES_PROFILEPRCACHE;Профил у оставу +PREFERENCES_PROFILEPRFILE;Профил уз улазну датотеку +PREFERENCES_PROFILESAVECACHE;Сачувај параметре обраде у оставу +PREFERENCES_PROFILESAVEINPUT;Сачувај парамтре обраде поред улазне датотеке +PREFERENCES_PROPERTY;Особина +PREFERENCES_PSPATH;Директоријум са инсталираним Адобе Фотошопом +PREFERENCES_SELECTFONT;Изаберите фонт +PREFERENCES_SELECTLANG;Језик +PREFERENCES_SELECTTHEME;Тема +PREFERENCES_SET;Постави +PREFERENCES_SHOWBASICEXIF;Прикажи основне Exif податке +PREFERENCES_SHOWDATETIME;Прикажи датум и време +PREFERENCES_SHTHRESHOLD;Праг за одсечене тамне делове +PREFERENCES_SINGLETABVERTAB;Режим у једном листу, вертикални листови +PREFERENCES_SINGLETAB;Режим у једном листу +PREFERENCES_SLIMUI;Танки изглед +PREFERENCES_SND_BATCHQUEUEDONE;Обрађене су заказане датотеке +PREFERENCES_SND_HELP;Унесите путању до датотеке или оставите празно уколико не желите звук. На Windows-у можете да користите „SystemDefault“, „SystemAsterisk“ за системске звуке. +PREFERENCES_SND_LNGEDITPROCDONE;Уредник је завршио обраду +PREFERENCES_SND_TRESHOLDSECS;бр. секунди +PREFERENCES_STARTUPIMDIR;Директоријум по покретању +PREFERENCES_TAB_BROWSER;Преглед датотека +PREFERENCES_TAB_COLORMGR;Управљање бојама +PREFERENCES_TAB_GENERAL;Опште +PREFERENCES_TAB_IMPROC;Обрада сликe +PREFERENCES_TAB_SOUND;Звуци +PREFERENCES_TP_VSCROLLBAR;Сакриј клизаче у области са алаткама +PREFERENCES_TUNNELMETADATA;Копирај неизмењене IPTC/XMP (када је слика означена другим програмом) +PREFERENCES_USESYSTEMTHEME; Користи системску тему +PREFERENCES_WORKFLOW;Ток обраде +PROFILEPANEL_LABEL;Профили обраде +PROFILEPANEL_LOADDLGLABEL;Учитај профил за обраду... +PROFILEPANEL_PCUSTOM;Произвољно +PROFILEPANEL_PFILE;Из датотеке +PROFILEPANEL_PLASTSAVED;Од последњег чувања +PROFILEPANEL_SAVEDLGLABEL;Чува параметре за обраду... +PROFILEPANEL_TOOLTIPCOPY;Копира тренутни профил у оставу +PROFILEPANEL_TOOLTIPLOAD;Учитава профил из датотеке +PROFILEPANEL_TOOLTIPPASTE; Учитава профил из +PROFILEPANEL_TOOLTIPSAVE;Чува тренутни профил +PROGRESSBAR_LOADINGTHUMBS;Учитавам приказе... +PROGRESSBAR_LOADING;Учитавам слику... +PROGRESSBAR_LOADJPEG;Учитавам JPEG датотеку... +PROGRESSBAR_LOADPNG;Учитавам PNG датотеку... +PROGRESSBAR_LOADTIFF;Учитавам TIFF датотеку... +PROGRESSBAR_PROCESSING;Обрађујем слику... +PROGRESSBAR_READY;Чекам +PROGRESSBAR_SAVEJPEG;Чувам JPEG датотеку... +PROGRESSBAR_SAVEPNG;Чувам PNG датотеку... +PROGRESSBAR_SAVETIFF;Чувам TIFF датотеку... +PROGRESSDLG_PROFILECHANGEDINBROWSER;Профил измењен у разгледачу +P_GAMMA_CURV;гама +QINFO_ISO;ИСО +QINFO_NOEXIF;Нису доступни Exif подаци. +SAVEDLG_AUTOSUFFIX;Сам додај суфикс уколико датотека већ постоји +SAVEDLG_FILEFORMAT;Формат датотеке +SAVEDLG_JPEGQUAL;JPEG квалитет +SAVEDLG_PNGCOMPR;PNG паковање +SAVEDLG_PUTTOQUEUEHEAD;Премешта слику на почетак заказаних +SAVEDLG_PUTTOQUEUETAIL;Премешта слику на крај заказаних +SAVEDLG_PUTTOQUEUE;Заказује слику за обраду +SAVEDLG_SAVEIMMEDIATELY;Одмах сачувај +SAVEDLG_SAVESPP;Сачувај параметре обраде уз слику +SAVEDLG_TIFFUNCOMPRESSED;Незапаковани TIFF +TOOLBAR_TOOLTIP_CROP;Поставља оквир за исецање (пречица: Ц) +TOOLBAR_TOOLTIP_HAND;Алат за померање (пречица: Н) +TOOLBAR_TOOLTIP_STRAIGHTEN;Исправља линију хоризонта (пречица: С) +TOOLBAR_TOOLTIP_WB;Одређује баланс беле из тачке (пречица: W) +TP_CACORRECTION_BLUE;Плава +TP_CACORRECTION_LABEL;Хроматке аберације +TP_CACORRECTION_RED;Црвена +TP_CHMIXER_BLUE;Плава +TP_CHMIXER_GREEN;Зелена +TP_CHMIXER_LABEL;Мешање канала +TP_CHMIXER_RED;Црвена +TP_CHROMATABERR_LABEL;Хроматске аберације +TP_COARSETRAF_TOOLTIP_HFLIP;Изврће слику хоризонтално +TP_COARSETRAF_TOOLTIP_ROTLEFT;Окреће слику улево +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Окреће слику удесно +TP_COARSETRAF_TOOLTIP_VFLIP;Изврће слику вертикално +TP_CROP_FIXRATIO;Сразмерно: +TP_CROP_GTDIAGONALS;Правило дијагонала +TP_CROP_GTGRID;Мрежа +TP_CROP_GTNONE;Ништа +TP_CROP_GTRULETHIRDS;Правило трећина +TP_CROP_GUIDETYPE;Вођицe: +TP_CROP_H;В +TP_CROP_LABEL;Исецање +TP_CROP_PPI;ППИ= +TP_CROP_SELECTCROP; Изабери област +TP_CROP_W;Ш +TP_CROP_X;x +TP_CROP_Y;y +TP_DARKFRAME_AUTOSELECT;Сам изабери +TP_DARKFRAME_LABEL;Тамни кадар +TP_DEFRINGE_LABEL;Уклаљање ореола +TP_DEFRINGE_RADIUS;Полупречник +TP_DEFRINGE_THRESHOLD;Праг +TP_DIRPYRDENOISE_CHROMA;Боја +TP_DIRPYRDENOISE_GAMMA;Гама +TP_DIRPYRDENOISE_LABEL;Дирекционо пирамидно уклањање шума +TP_DIRPYRDENOISE_LUMA;Луминанса +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_DISTORTION_AUTO;Сам исправи изобличења +TP_DISTORTION_AUTO_TIP;(Експериментално) Аутоматски исправља изобличења неких апарата (М4/3, неки компакти, и др.) +TP_DISTORTION_LABEL;Изобличења +TP_EXPOSURE_AUTOLEVELS;Ауто-нивои +TP_EXPOSURE_BLACKLEVEL;Црна +TP_EXPOSURE_BRIGHTNESS;Осветљеност +TP_EXPOSURE_CLIP;Одсеци +TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Праг за чупање светлих делова +TP_EXPOSURE_COMPRHIGHLIGHTS;Сабијање светлог +TP_EXPOSURE_COMPRSHADOWS;Сабијање сенки +TP_EXPOSURE_CONTRAST;Контраст +TP_EXPOSURE_CURVEEDITOR;Крива нијанси +TP_EXPOSURE_EXPCOMP;Компензација +TP_EXPOSURE_LABEL;Експозиција +TP_EXPOSURE_SATURATION;Засићеност +TP_FLATFIELD_AUTOSELECT;Сам изабери +TP_FLATFIELD_BLURRADIUS;Полупречник замућења +TP_FLATFIELD_BLURTYPE;Замути +TP_FLATFIELD_BT_AREA;Област +TP_FLATFIELD_BT_HORIZONTAL;Хоризонтално +TP_FLATFIELD_BT_VERTHORIZ;Хориз. и вертик. +TP_FLATFIELD_BT_VERTICAL;Вертикално +TP_FLATFIELD_LABEL;Равно поље +TP_GAMMA_FREE;Гама слобода +TP_GAMMA_OUTPUT;Излазна гама +TP_GAMMA_SLOP;нагиб (линеарни) +TP_HLREC_BLEND;Утапање +TP_HLREC_CIELAB;ЦиеЛаб стапање +TP_HLREC_COLOR;Пропагинација боје +TP_HLREC_LABEL;Чупање светлих делова +TP_HLREC_LUMINANCE;Извлачење луминансе +TP_HLREC_METHOD;Начин: +TP_HSVEQUALIZER_CHANNEL;ХСВ канал +TP_HSVEQUALIZER_HUE;Нијанса +TP_HSVEQUALIZER_LABEL;Уједначење ХСВ канала +TP_HSVEQUALIZER_SAT;Засићеност +TP_HSVEQUALIZER_VAL;Вредност +TP_ICM_BLENDCMSMATRIX;Утопи светле делове у матрицу +TP_ICM_INPUTCAMERAICC;Фото-апарат или стандардни ИЦЦ +TP_ICM_INPUTCAMERA;Подразумевано из апарата +TP_ICM_INPUTCUSTOM;Произвољно +TP_ICM_INPUTDLGLABEL;Изаберите улазни ИЦЦ профил... +TP_ICM_INPUTEMBEDDED;Угњежђено, уколико је могуће +TP_ICM_INPUTNONE;Нема профила +TP_ICM_INPUTPROFILE;Улазни профил +TP_ICM_LABEL;ИЦМ +TP_ICM_NOICM;No ICM: sRGB излаз +TP_ICM_OUTPUTPROFILE;Излазни профил +TP_ICM_SAVEREFERENCE;Сачувај слику као референцу за профил +TP_ICM_WORKINGPROFILE;Радни профил +TP_IMPULSEDENOISE_LABEL;Импулсно уклањање шума +TP_IMPULSEDENOISE_THRESH;Праг +TP_LABCURVE_BRIGHTNESS;Осветљеност +TP_LABCURVE_CONTRAST;Контраст +TP_LABCURVE_CURVEEDITOR;Крива светлости +TP_LABCURVE_LABEL;Лаб крива +TP_LENSGEOM_AUTOCROP;Сам исеци +TP_LENSGEOM_FILL;Сам попуни +TP_LENSGEOM_LABEL;Објектив и геометрија +TP_PERSPECTIVE_HORIZONTAL;Хоризонтална +TP_PERSPECTIVE_LABEL;Перспектива +TP_PERSPECTIVE_VERTICAL;Вертикална +TP_PREPROCESS_GREENEQUIL;Калибрација зелене боје +TP_PREPROCESS_LABEL;Предобрада +TP_PREPROCESS_LINEDENOISE;Линијски филтер шума +TP_PREPROCESS_NO_FOUND;Није пронађено +TP_RAWCACORR_AUTO;Исправи хроматске аберације +TP_RAWCACORR_CABLUE;Плава +TP_RAWCACORR_CARED;Црвена +TP_RAWEXPOS_BLACKS;Ниво црне +TP_RAWEXPOS_LINEAR;Линеарни фактор корекције +TP_RAWEXPOS_PRESER;Очување светлих делова +TP_RAWEXPOS_TWOGREEN;Обе зелене +TP_RAW_DCBENHANCE;Примени ДЦБ побољшање +TP_RAW_DCBITERATIONS;Број ДЦБ пролаза +TP_RAW_DMETHOD;Начин +TP_RAW_FALSECOLOR;Кораци за пригушивање лажне боје +TP_RAW_LABEL;Расклапање мозаика +TP_RESIZE_APPLIESTO;Примени на: +TP_RESIZE_CROPPEDAREA;Исечену област +TP_RESIZE_FITBOX;Ширину и висину +TP_RESIZE_FULLIMAGE;Целу слику +TP_RESIZE_HEIGHT;Висину +TP_RESIZE_H;В: +TP_RESIZE_LABEL;Величина слике +TP_RESIZE_LANCZOS;Ланхоз +TP_RESIZE_METHOD;Начин: +TP_RESIZE_NEAREST;Најближе +TP_RESIZE_SCALE;Умањење +TP_RESIZE_SPECIFY;Изабери: +TP_RESIZE_WIDTH;Ширину +TP_RESIZE_W;Ш: +TP_ROTATE_DEGREE;Степени: +TP_ROTATE_LABEL;Ротација +TP_ROTATE_SELECTLINE; Постави праву линију +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Светло +TP_SHADOWSHLIGHTS_HLTONALW;Ширина тонова +TP_SHADOWSHLIGHTS_LABEL;Сенке/Светло +TP_SHADOWSHLIGHTS_LOCALCONTR;Локални контраст +TP_SHADOWSHLIGHTS_RADIUS;Полупречник +TP_SHADOWSHLIGHTS_SHADOWS;Сенке +TP_SHADOWSHLIGHTS_SHTONALW;Ширина тонова +TP_SHARPENEDGE_AMOUNT;Количина +TP_SHARPENEDGE_LABEL;Ивице +TP_SHARPENEDGE_PASSES;Понављања +TP_SHARPENEDGE_THREE;Само луминанса +TP_SHARPENING_AMOUNT;Количина +TP_SHARPENING_EDRADIUS;Полупречник +TP_SHARPENING_EDTOLERANCE;Толеранција ивице +TP_SHARPENING_HALOCONTROL;Уклони ореол +TP_SHARPENING_HCAMOUNT;Количина +TP_SHARPENING_LABEL;Оштрење +TP_SHARPENING_METHOD;Начин +TP_SHARPENING_ONLYEDGES;Изоштри само ивице +TP_SHARPENING_RADIUS;Полупречник +TP_SHARPENING_RLD;RL деконволуција +TP_SHARPENING_RLD_AMOUNT;Количина +TP_SHARPENING_RLD_DAMPING;Пригушивање +TP_SHARPENING_RLD_ITERATIONS;Понављања +TP_SHARPENING_THRESHOLD;Праг +TP_SHARPENING_USM;Оштрина маске +TP_SHARPENMICRO_AMOUNT;Количина +TP_SHARPENMICRO_LABEL;Микроконттраст +TP_SHARPENMICRO_MATRIX;3×3 матрица уместо 5×5 +TP_SHARPENMICRO_UNIFORMITY;Уједначеност +TP_VIGNETTING_AMOUNT;Количина +TP_VIGNETTING_CENTER;Центар +TP_VIGNETTING_CENTER_X;Центар X +TP_VIGNETTING_CENTER_Y;Центар Y +TP_VIGNETTING_LABEL;Вињетарење +TP_VIGNETTING_RADIUS;Полупречник +TP_VIGNETTING_STRENGTH;Јачина +TP_WBALANCE_AUTO;Сам одреди +TP_WBALANCE_CAMERA;Из апарата +TP_WBALANCE_CUSTOM;Произвољно +TP_WBALANCE_GREEN;Зеленило +TP_WBALANCE_LABEL;Баланс беле +TP_WBALANCE_METHOD;Начин: +TP_WBALANCE_SIZE;Величина: +TP_WBALANCE_SPOTWB;Из тачке +TP_WBALANCE_TEMPERATURE;Температура +ZOOMPANEL_100;(100%) +ZOOMPANEL_NEWCROPWINDOW;Отвара нови прозор са детаљима +ZOOMPANEL_ZOOM100;Повећава преглед на 100% z +ZOOMPANEL_ZOOMFITSCREEN;Уклапа слику у величину прозора Ф +ZOOMPANEL_ZOOMIN;Увећава приказ слике + +ZOOMPANEL_ZOOMOUT;Умањује приказ слике - + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!ABOUT_TAB_RELEASENOTES;Release Notes +!BATCHQUEUE_DESTFILENAME;Path and file name +!CURVEEDITOR_AXIS_IN;I: +!CURVEEDITOR_AXIS_LEFT_TAN;LT: +!CURVEEDITOR_AXIS_OUT;O: +!CURVEEDITOR_AXIS_RIGHT_TAN;RT: +!CURVEEDITOR_EDITPOINT_HINT;Enable edition of node in/out values.\n\nRight-click on a node to select it.\nRight-click on empty space to de-select the node. +!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) +!EXPORT_BYPASS_ALL;Select / Unselect All +!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_FF;Bypass [raw] Flat-Field +!EXPORT_BYPASS_RAW_GREENTHRESH;Bypass [raw] Green Equilibration +!EXPORT_BYPASS_RAW_LINENOISE;Bypass [raw] Line Noise Filter +!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_FASTEXPORTOPTIONS;Fast Export Options +!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_MAXHEIGHT;Maximum height: +!EXPORT_MAXWIDTH;Maximum width: +!EXPORT_PUTTOQUEUEFAST; Put to queue for fast export +!EXPORT_RAW_DMETHOD;Demosaic method +!EXTPROGTARGET_1;raw +!EXTPROGTARGET_2;queue-processed +!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_EXTPROGMENU;Open with +!FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) +!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_POPUPPROCESSFAST;Put to queue (Fast export) +!FILEBROWSER_POPUPRANK0;Unrank +!FILEBROWSER_POPUPRANK1;Rank 1 * +!FILEBROWSER_POPUPRANK2;Rank 2 ** +!FILEBROWSER_POPUPRANK3;Rank 3 *** +!FILEBROWSER_POPUPRANK4;Rank 4 **** +!FILEBROWSER_POPUPRANK5;Rank 5 ***** +!FILEBROWSER_POPUPRANK;Rank +!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_SHOWNOTTRASHHINT;Show only non-deleted images. +!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_ASIMAGE;As Image +!GENERAL_AUTO;Automatic +!GENERAL_CLOSE;Close +!GENERAL_WARNING;Warning +!HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram. +!HISTOGRAM_TOOLTIP_FULL;Toggle full (off) or scaled (on) histogram. +!HISTORY_MSG_151;Vibrance +!HISTORY_MSG_152;Vib - Pastel tones +!HISTORY_MSG_153;Vib - Saturated tones +!HISTORY_MSG_154;Vib - Protect skin-tones +!HISTORY_MSG_155;Vib - Avoid color shift +!HISTORY_MSG_156;Vib - Link pastel/saturated +!HISTORY_MSG_157;Vib - P/S threshold +!HISTORY_MSG_158;TM - Strength +!HISTORY_MSG_159;TM - Edge stopping +!HISTORY_MSG_160;TM - Scale +!HISTORY_MSG_161;TM - Reweighting iterates +!HISTORY_MSG_162;Tone Mapping +!HISTORY_MSG_163;RGB curves - Red +!HISTORY_MSG_164;RGB curves - Green +!HISTORY_MSG_165;RGB curves - Blue +!HISTORY_MSG_166;Neutral levels +!HISTORY_MSG_167;--unused-- +!HISTORY_MSG_168;L*a*b* - CC curve +!HISTORY_MSG_169;L*a*b* - CH curve +!HISTORY_MSG_170;Vibrance - HH curve +!HISTORY_MSG_171;L*a*b* - LC curve +!HISTORY_MSG_172;L*a*b* - Restrict LC +!HISTORY_MSG_173;NR - Luminance detail +!HISTORY_MSG_174;CIECAM02 +!HISTORY_MSG_175;CAM02 - CAT02 adaptation +!HISTORY_MSG_176;CAM02 - Viewing surround +!HISTORY_MSG_177;CAM02 - Scene luminosity +!HISTORY_MSG_178;CAM02 - Viewing luminosity +!HISTORY_MSG_179;CAM02 - White-point model +!HISTORY_MSG_180;CAM02 - Lightness (J) +!HISTORY_MSG_181;CAM02 - Chroma (C) +!HISTORY_MSG_182;CAM02 - Automatic CAT02 +!HISTORY_MSG_183;CAM02 - Contrast (J) +!HISTORY_MSG_184;CAM02 - Scene surround +!HISTORY_MSG_185;CAM02 - Gamut control +!HISTORY_MSG_186;CAM02 - Algorithm +!HISTORY_MSG_187;CAM02 - Red/skin prot. +!HISTORY_MSG_188;CAM02 - Brightness (Q) +!HISTORY_MSG_189;CAM02 - Contrast (Q) +!HISTORY_MSG_190;CAM02 - Saturation (S) +!HISTORY_MSG_191;CAM02 - Colorfulness (M) +!HISTORY_MSG_192;CAM02 - Hue (h) +!HISTORY_MSG_193;CAM02 - Tone curve 1 +!HISTORY_MSG_194;CAM02 - Tone curve 2 +!HISTORY_MSG_195;CAM02 - Tone curve 1 +!HISTORY_MSG_196;CAM02 - Tone curve 2 +!HISTORY_MSG_197;CAM02 - Color curve +!HISTORY_MSG_198;CAM02 - Color curve +!HISTORY_MSG_199;CAM02 - Output histograms +!HISTORY_MSG_200;CAM02 - Tone mapping +!HISTORY_MSG_201;NR - Chrominance - R&G +!HISTORY_MSG_202;NR - Chrominance - B&Y +!HISTORY_MSG_203;NR - Method +!HISTORY_MSG_204;LMMSE enhancement steps +!HISTORY_MSG_205;CAM02 - Hot/bad pixel filter +!HISTORY_MSG_206;CAT02 - Auto scene luminosity +!HISTORY_MSG_207;Defringe - Hue curve +!HISTORY_MSG_208;WB - B/R equalizer +!HISTORY_MSG_210;GF - Angle +!HISTORY_MSG_211;Graduated Filter +!HISTORY_MSG_212;VF - Strength +!HISTORY_MSG_213;Vignette Filter +!HISTORY_MSG_214;Black-and-White +!HISTORY_MSG_215;B&W - CM - Red +!HISTORY_MSG_216;B&W - CM - Green +!HISTORY_MSG_217;B&W - CM - Blue +!HISTORY_MSG_218;B&W - Gamma - Red +!HISTORY_MSG_219;B&W - Gamma - Green +!HISTORY_MSG_220;B&W - Gamma - Blue +!HISTORY_MSG_221;B&W - Color filter +!HISTORY_MSG_222;B&W - Presets +!HISTORY_MSG_223;B&W - CM - Orange +!HISTORY_MSG_224;B&W - CM - Yellow +!HISTORY_MSG_225;B&W - CM - Cyan +!HISTORY_MSG_226;B&W - CM - Magenta +!HISTORY_MSG_227;B&W - CM - Purple +!HISTORY_MSG_228;B&W - Luminance equalizer +!HISTORY_MSG_229;B&W - Luminance equalizer +!HISTORY_MSG_230;B&W - Mode +!HISTORY_MSG_231;B&W - 'Before' curve +!HISTORY_MSG_232;B&W - 'Before' curve type +!HISTORY_MSG_233;B&W - 'After' curve +!HISTORY_MSG_234;B&W - 'After' curve type +!HISTORY_MSG_235;B&W - Auto channel mixer +!HISTORY_MSG_236;--unused-- +!HISTORY_MSG_237;B&W - Mixer +!HISTORY_MSG_238;GF - Feather +!HISTORY_MSG_239;GF - Strength +!HISTORY_MSG_240;GF - Center +!HISTORY_MSG_241;VF - Feather +!HISTORY_MSG_242;VF - Roundness +!HISTORY_MSG_243;VC - Radius +!HISTORY_MSG_244;VC - Strength +!HISTORY_MSG_245;VC - Center +!HISTORY_MSG_246;L*a*b* - CL curve +!HISTORY_MSG_247;L*a*b* - LH curve +!HISTORY_MSG_248;L*a*b* - HH curve +!HISTORY_MSG_249;CbDL - Threshold +!HISTORY_MSG_250;NR - Enhanced +!HISTORY_MSG_251;B&W - Algorithm +!HISTORY_MSG_252;CbDL - Skin tar/prot +!HISTORY_MSG_253;CbDL - Reduce artifacts +!HISTORY_MSG_254;CbDL - Skin hue +!HISTORY_MSG_255;NR - Median filter +!HISTORY_MSG_256;NR - Median type +!HISTORY_MSG_257;Color Toning +!HISTORY_MSG_258;CT - Color curve +!HISTORY_MSG_259;CT - Opacity curve +!HISTORY_MSG_260;CT - a*[b*] opacity +!HISTORY_MSG_261;CT - Method +!HISTORY_MSG_262;CT - b* opacity +!HISTORY_MSG_263;CT - Shadows - Red +!HISTORY_MSG_264;CT - Shadows - Green +!HISTORY_MSG_265;CT - Shadows - Blue +!HISTORY_MSG_266;CT - Mid - Red +!HISTORY_MSG_267;CT - Mid - Green +!HISTORY_MSG_268;CT - Mid - Blue +!HISTORY_MSG_269;CT - High - Red +!HISTORY_MSG_270;CT - High - Green +!HISTORY_MSG_271;CT - High - Blue +!HISTORY_MSG_272;CT - Balance +!HISTORY_MSG_273;CT - Reset +!HISTORY_MSG_274;CT - Sat. Shadows +!HISTORY_MSG_275;CT - Sat. Highlights +!HISTORY_MSG_276;CT - Opacity +!HISTORY_MSG_277;--unused-- +!HISTORY_MSG_278;CT - Preserve luminance +!HISTORY_MSG_279;CT - Shadows +!HISTORY_MSG_280;CT - Highlights +!HISTORY_MSG_281;CT - Sat. strength +!HISTORY_MSG_282;CT - Sat. threshold +!HISTORY_MSG_283;CT - Strength +!HISTORY_MSG_284;CT - Auto sat. protection +!HISTORY_MSG_285;NR - Median - Method +!HISTORY_MSG_286;NR - Median - Type +!HISTORY_MSG_287;NR - Median - Iterations +!HISTORY_MSG_288;Flat Field - Clip control +!HISTORY_MSG_289;Flat Field - Clip control - Auto +!HISTORY_MSG_290;Black Level - Red +!HISTORY_MSG_291;Black Level - Green +!HISTORY_MSG_292;Black Level - Blue +!HISTORY_MSG_293;Film Simulation +!HISTORY_MSG_294;Film Simulation - Strength +!HISTORY_MSG_295;Film Simulation - Film +!HISTORY_MSG_296;NR - Luminance curve +!HISTORY_MSG_297;NR - Quality +!HISTORY_MSG_298;Dead pixel filter +!HISTORY_MSG_299;NR - Chrominance curve +!HISTORY_MSG_300;- +!HISTORY_MSG_301;NR - Luma control +!HISTORY_MSG_302;NR - Chroma method +!HISTORY_MSG_303;NR - Chroma method +!HISTORY_MSG_304;W - Contrast levels +!HISTORY_MSG_305;Wavelet Levels +!HISTORY_MSG_306;W - Preview +!HISTORY_MSG_307;W - Preview +!HISTORY_MSG_308;W - Preview direction +!HISTORY_MSG_309;W - ES - Detail +!HISTORY_MSG_310;W - Residual - Sky tar/prot +!HISTORY_MSG_311;W - Wavelet levels +!HISTORY_MSG_312;W - Residual - Shadows threshold +!HISTORY_MSG_313;W - Chroma - Sat/past +!HISTORY_MSG_314;W - Gamut - Reduce artifacts +!HISTORY_MSG_315;W - Residual - Contrast +!HISTORY_MSG_316;W - Gamut - Skin tar/prot +!HISTORY_MSG_317;W - Gamut - Skin hue +!HISTORY_MSG_318;W - Contrast - Highlight levels +!HISTORY_MSG_319;W - Contrast - Highlight range +!HISTORY_MSG_320;W - Contrast - Shadow range +!HISTORY_MSG_321;W - Contrast - Shadow levels +!HISTORY_MSG_322;W - Gamut - Avoid color shift +!HISTORY_MSG_323;W - ES - Local contrast +!HISTORY_MSG_324;W - Chroma - Pastel +!HISTORY_MSG_325;W - Chroma - Saturated +!HISTORY_MSG_326;W - Chroma - Method +!HISTORY_MSG_327;W - Contrast - Apply to +!HISTORY_MSG_328;W - Chroma - Link strength +!HISTORY_MSG_329;W - Toning - Opacity RG +!HISTORY_MSG_330;W - Toning - Opacity BY +!HISTORY_MSG_331;W - Contrast levels - Extra +!HISTORY_MSG_332;W - Tiling method +!HISTORY_MSG_333;W - Residual - Shadows +!HISTORY_MSG_334;W - Residual - Chroma +!HISTORY_MSG_335;W - Residual - Highlights +!HISTORY_MSG_336;W - Residual - Highlights threshold +!HISTORY_MSG_337;W - Residual - Sky hue +!HISTORY_MSG_338;W - ES - Radius +!HISTORY_MSG_339;W - ES - Strength +!HISTORY_MSG_340;W - Strength +!HISTORY_MSG_341;W - Edge performance +!HISTORY_MSG_342;W - ES - First level +!HISTORY_MSG_343;W - Chroma levels +!HISTORY_MSG_344;W - Meth chroma sl/cur +!HISTORY_MSG_345;W - ES - Local contrast +!HISTORY_MSG_346;W - ES - Local contrast method +!HISTORY_MSG_347;W - Denoise - Level 0 +!HISTORY_MSG_348;W - Denoise - Level 1 +!HISTORY_MSG_349;W - Denoise - Level 2 +!HISTORY_MSG_350;W - ES - Edge detection +!HISTORY_MSG_351;W - Residual - HH curve +!HISTORY_MSG_352;W - Background +!HISTORY_MSG_353;W - ES - Gradient sensitivity +!HISTORY_MSG_354;W - ES - Enhance +!HISTORY_MSG_355;W - ES - Threshold low +!HISTORY_MSG_356;W - ES - Threshold high +!HISTORY_MSG_357;W - Denoise - Link with ES +!HISTORY_MSG_358;W - Gamut - CH +!HISTORY_MSG_359;Hot/Dead - Threshold +!HISTORY_MSG_360;TM Gamma +!HISTORY_MSG_361;W - Final - Chroma balance +!HISTORY_MSG_362;W - Residual - Compression method +!HISTORY_MSG_363;W - Residual - Compression strength +!HISTORY_MSG_364;W - Final - Contrast balance +!HISTORY_MSG_365;W - Final - Delta balance +!HISTORY_MSG_366;W - Residual - Compression gamma +!HISTORY_MSG_367;W - ES - Local contrast curve +!HISTORY_MSG_368;W - Final - Contrast balance +!HISTORY_MSG_369;W - Final - Balance method +!HISTORY_MSG_370;W - Final - Local contrast curve +!HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s +!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). +!MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue-processed first. +!MAIN_MSG_OPERATIONCANCELLED;Operation cancelled +!MAIN_MSG_PATHDOESNTEXIST;The path\n\n%1\n\ndoes not exist. Please set a correct path in Preferences. +!MAIN_MSG_SETPATHFIRST;You first have to set a target path in Preferences in order to use this function! +!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_EXPORT; Fast Export +!MAIN_TAB_INSPECT; Inspect +!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_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%. +!MAIN_TOOLTIP_PREVIEWG;Preview the Green channel.\nShortcut: g +!MAIN_TOOLTIP_PREVIEWL;Preview the Luminosity.\nShortcut: v\n\n0.299*R + 0.587*G + 0.114*B +!MAIN_TOOLTIP_PREVIEWR;Preview the Red channel.\nShortcut: r +!MAIN_TOOLTIP_THRESHOLD;Threshold +!NAVIGATOR_B;B: +!NAVIGATOR_G;G: +!NAVIGATOR_H;H: +!NAVIGATOR_LAB_A;a*: +!NAVIGATOR_LAB_B;b*: +!NAVIGATOR_LAB_L;L*: +!NAVIGATOR_NA; -- +!NAVIGATOR_R;R: +!NAVIGATOR_S;S: +!NAVIGATOR_V;V: +!NAVIGATOR_XY_FULL;Width: %1, Height: %2 +!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_CHANNELMIXERBW;Black-and-White +!PARTIALPASTE_COLORAPP;CIECAM02 +!PARTIALPASTE_COLORTONING;Color Toning +!PARTIALPASTE_EPD;Tone mapping +!PARTIALPASTE_EQUALIZER;Wavelet Equalizer +!PARTIALPASTE_FILMSIMULATION;Film Simulation +!PARTIALPASTE_FLATFIELDCLIPCONTROL;Flat-field clip control +!PARTIALPASTE_GRADIENT;Graduated filter +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_PCVIGNETTE;Vignette filter +!PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter +!PARTIALPASTE_PREPROCESS_HOTPIXFILT;Hot pixel filter +!PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!PARTIALPASTE_RGBCURVES;RGB curves +!PARTIALPASTE_VIBRANCE;Vibrance +!PARTIALPASTE_WAVELETGROUP;Wavelet processing +!PREFERENCES_AUTLISLOW;Low +!PREFERENCES_AUTLISMAX;Max - Average of all tiles +!PREFERENCES_AUTLISSTD;High +!PREFERENCES_AUTLISVLOW;None +!PREFERENCES_AUTLOW;Low +!PREFERENCES_AUTSTD;Standard +!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_BEHADDALL;All to 'Add' +!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_BEHSETALL;All to 'Set' +!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_CURVEBBOXPOS;Position of curve copypasta buttons +!PREFERENCES_CURVEBBOXPOS_ABOVE;Above +!PREFERENCES_CURVEBBOXPOS_BELOW;Below +!PREFERENCES_CURVEBBOXPOS_LEFT;Left +!PREFERENCES_CURVEBBOXPOS_RIGHT;Right +!PREFERENCES_CUSTPROFBUILDKEYFORMAT;Keys format +!PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME;Name +!PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;TagID +!PREFERENCES_D50;5000K +!PREFERENCES_D55;5500K +!PREFERENCES_D60;6000K +!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_EXPAUT;Expert +!PREFERENCES_FILMSIMULATION;Film Simulation +!PREFERENCES_FLUOF2;Fluorescent F2 +!PREFERENCES_FLUOF7;Fluorescent F7 +!PREFERENCES_FLUOF11;Fluorescent F11 +!PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT;Same thumbnail height between the Editor's panel 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_GREY05;Yb=05 CIE L#30 +!PREFERENCES_GREY10;Yb=10 CIE L#40 +!PREFERENCES_GREY15;Yb=15 CIE L#45 +!PREFERENCES_GREY18;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_GREYSC18;Yb=18 CIE L#50 +!PREFERENCES_GREYSCA;Automatic +!PREFERENCES_GREYSC;Scene Yb luminance (%) +!PREFERENCES_GREY;Output device's Yb luminance (%) +!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_LEVAUTDN;Denoising level +!PREFERENCES_LEVDN;Cell size +!PREFERENCES_LISS;Auto multi-zone smoothing +!PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders +!PREFERENCES_MAX;Maxi (Tile) +!PREFERENCES_MED;Medium (Tile/2) +!PREFERENCES_MENUGROUPEXTPROGS;Group "Open with" +!PREFERENCES_MIN;Mini (100x115) +!PREFERENCES_NAVGUIDEBRUSH;Navigator guide color +!PREFERENCES_NAVIGATIONFRAME;Navigation +!PREFERENCES_NOISE;Noise Reduction +!PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Overlay filenames on thumbnails in the editor pannel +!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_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_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_SHOWEXPOSURECOMPENSATION;Append exposure compensation +!PREFERENCES_SHOWFILMSTRIPTOOLBAR;Show filmstrip toolbar +!PREFERENCES_SIMPLAUT;Tool mode +!PREFERENCES_SMA;Small (250x287) +!PREFERENCES_STDAUT;Standard +!PREFERENCES_TAB_PERFORMANCE;Performance & Quality +!PREFERENCES_TIMAX;High +!PREFERENCES_TINB;Number of tiles +!PREFERENCES_TISTD;Standard +!PREFERENCES_TP_LABEL;Tool panel: +!PREFERENCES_TP_USEICONORTEXT;Use tab icons instead of text +!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 +!PROFILEPANEL_COPYPPASTE;Parameters to copy +!PROFILEPANEL_GLOBALPROFILES;Bundled profiles +!PROFILEPANEL_LOADPPASTE;Parameters to load +!PROFILEPANEL_MODE_TIP;Processing profile fill mode.\n\nButton pressed: partial profiles will be converted to full profiles; the missing values will be replaced with hard-coded defaults.\n\nButton released: profiles will be applied as they are, altering only those values which they contain. +!PROFILEPANEL_MYPROFILES;My profiles +!PROFILEPANEL_PASTEPPASTE;Parameters to paste +!PROFILEPANEL_PINTERNAL;Neutral +!PROFILEPANEL_SAVEPPASTE;Parameters to save +!PROGRESSBAR_NOIMAGES;No images found +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing profile saved +!PROGRESSBAR_SNAPSHOT_ADDED;Snapshot added +!SAVEDLG_FORCEFORMATOPTS;Force saving options +!SAVEDLG_SUBSAMP;Subsampling +!SAVEDLG_SUBSAMP_1;Best compression +!SAVEDLG_SUBSAMP_2;Balanced +!SAVEDLG_SUBSAMP_3;Best quality +!SAVEDLG_SUBSAMP_TOOLTIP;Best compression: 4:1:1\nBalanced: 4:2:2\nBest quality: 4:4:4 +!SAVEDLG_WARNFILENAME;File will be named +!SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. +!THRESHOLDSELECTOR_BL;Bottom-left +!THRESHOLDSELECTOR_BR;Bottom-right +!THRESHOLDSELECTOR_B;Bottom +!THRESHOLDSELECTOR_HINT;Hold the Shift key to move individual control points. +!THRESHOLDSELECTOR_TL;Top-left +!THRESHOLDSELECTOR_TR;Top-right +!THRESHOLDSELECTOR_T;Top +!TP_BWMIX_ALGO;Algorithm OYCPM +!TP_BWMIX_ALGO_LI;Linear +!TP_BWMIX_ALGO_SP;Special effects +!TP_BWMIX_ALGO_TOOLTIP;Linear: will produce a normal linear response.\nSpecial effects: will produce special effects by mixing channels non-linearly. +!TP_BWMIX_AUTOCH;Auto +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing Channel Mixer. +!TP_BWMIX_CC_ENABLED;Adjust complementary color +!TP_BWMIX_CC_TOOLTIP;Enable to allow automatic adjustment of complementary colors in ROYGCBPM mode. +!TP_BWMIX_CHANNEL;Luminance equalizer +!TP_BWMIX_CURVEEDITOR1;'Before' curve +!TP_BWMIX_CURVEEDITOR2;'After' curve +!TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Tone curve, after B&W conversion, at the end of treatment. +!TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Tone curve, just before B&W conversion.\nMay take into account the color components. +!TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H).\nPay attention to extreme values as they may cause artifacts. +!TP_BWMIX_FILTER;Color Filter +!TP_BWMIX_FILTER_BLUEGREEN;Blue-Green +!TP_BWMIX_FILTER_BLUE;Blue +!TP_BWMIX_FILTER_GREENYELLOW;Green-Yellow +!TP_BWMIX_FILTER_GREEN;Green +!TP_BWMIX_FILTER_NONE;None +!TP_BWMIX_FILTER_PURPLE;Purple +!TP_BWMIX_FILTER_REDYELLOW;Red-Yellow +!TP_BWMIX_FILTER_RED;Red +!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. +!TP_BWMIX_FILTER_YELLOW;Yellow +!TP_BWMIX_GAMMA;Gamma Correction +!TP_BWMIX_GAM_TOOLTIP;Correct gamma for each RGB channel. +!TP_BWMIX_LABEL;Black-and-White +!TP_BWMIX_MET;Method +!TP_BWMIX_MET_CHANMIX;Channel Mixer +!TP_BWMIX_MET_DESAT;Desaturation +!TP_BWMIX_MET_LUMEQUAL;Luminance Equalizer +!TP_BWMIX_MIXC;Mixer +!TP_BWMIX_NEUTRAL;Reset mixer +!TP_BWMIX_NEUTRAL_TIP;Reset all values (Color Filter, Channel Mixer) to default. +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all the mixer options.\n"Total" displays the sum of the RGB values:\n- always 100% in relative mode\n- higher (lighter) or lower (darker) than 100% in absolute mode. +!TP_BWMIX_RGB_TOOLTIP;Mix the RGB channels. Use presets for guidance.\nPay attention to negative values that may cause artifacts or erratic behavior. +!TP_BWMIX_SETTING;Presets +!TP_BWMIX_SETTING_TOOLTIP;Different presets (film, landscape, etc.) or manual Channel Mixer settings. +!TP_BWMIX_SET_HIGHCONTAST;High contrast +!TP_BWMIX_SET_HIGHSENSIT;High Sensitivity +!TP_BWMIX_SET_HYPERPANCHRO;Hyper Panchromatic +!TP_BWMIX_SET_INFRARED;Infrared +!TP_BWMIX_SET_LANDSCAPE;Landscape +!TP_BWMIX_SET_LOWSENSIT;Low Sensitivity +!TP_BWMIX_SET_LUMINANCE;Luminance +!TP_BWMIX_SET_NORMCONTAST;Normal Contrast +!TP_BWMIX_SET_ORTHOCHRO;Orthochromatic +!TP_BWMIX_SET_PANCHRO;Panchromatic +!TP_BWMIX_SET_PORTRAIT;Portrait +!TP_BWMIX_SET_RGBABS;Absolute RGB +!TP_BWMIX_SET_RGBREL;Relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Relative ROYGCBPM +!TP_BWMIX_TCMODE_FILMLIKE;B&W Film-like +!TP_BWMIX_TCMODE_SATANDVALBLENDING;B&W Saturation and Value Blending +!TP_BWMIX_TCMODE_STANDARD;B&W Standard +!TP_BWMIX_TCMODE_WEIGHTEDSTD;B&W Weighted Standard +!TP_BWMIX_VAL;L +!TP_COLORAPP_ADAPTSCENE;Scene luminosity +!TP_COLORAPP_ADAPTSCENE_TOOLTIP;Absolute luminance of the scene environement (cd/m²).\n1) Calculated from the Exif data:\nShutter speed - ISO speed - F number - camera exposure correction.\n2) Calculated from the raw white point and RT's Exposure Compensation slider. +!TP_COLORAPP_ADAPTVIEWING;Viewing luminosity (cd/m²) +!TP_COLORAPP_ADAPTVIEWING_TOOLTIP;Absolute luminance of the viewing environnement\n(usually 16cd/m²). +!TP_COLORAPP_ADAP_AUTO_TOOLTIP;If the checkbox is checked (recommended) RawTherapee calculates an optimum value from Exif data.\nTo set the value manually, uncheck the checkbox first. +!TP_COLORAPP_ALGO;Algorithm +!TP_COLORAPP_ALGO_ALL;All +!TP_COLORAPP_ALGO_JC;Lightness + Chroma (JC) +!TP_COLORAPP_ALGO_JS;Lightness + Saturation (JS) +!TP_COLORAPP_ALGO_QM;Brightness + Colorfulness (QM) +!TP_COLORAPP_ALGO_TOOLTIP;Lets you choose between parameter subsets or all parameters. +!TP_COLORAPP_BADPIXSL;Hot/bad pixel filter +!TP_COLORAPP_BADPIXSL_TOOLTIP;Suppression of hot/bad (brightly colored) pixels.\n0 = No effect\n1 = Median\n2 = Gaussian.\nAlternatively, adjust the image to avoid very dark shadows.\n\nThese artifacts are due to limitations of CIECAM02. +!TP_COLORAPP_BRIGHT;Brightness (Q) +!TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from L*a*b* and RGB brightness. +!TP_COLORAPP_CHROMA;Chroma (C) +!TP_COLORAPP_CHROMA_M;Colorfulnes (M) +!TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM02 differs from L*a*b* and RGB colorfulness. +!TP_COLORAPP_CHROMA_S;Saturation (S) +!TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from L*a*b* and RGB saturation. +!TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from L*a*b* and RGB chroma. +!TP_COLORAPP_CIECAT_DEGREE;CAT02 adaptation +!TP_COLORAPP_CONTRAST;Contrast (J) +!TP_COLORAPP_CONTRAST_Q;Contrast (Q) +!TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrast in CIECAM02 for the Q slider; it differs from L*a*b* and RGB contrast. +!TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from L*a*b* and RGB contrast. +!TP_COLORAPP_CURVEEDITOR1;Tone curve 1 +!TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L* (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of J or Q after CIECAM02.\n\nJ and Q are not shown in the main histogram panel.\n\nFor final output refer to the main histogram panel. +!TP_COLORAPP_CURVEEDITOR2;Tone curve 2 +!TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Same usage as with the second exposure tone curve. +!TP_COLORAPP_CURVEEDITOR3;Color curve +!TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Adjust either chroma, saturation or colorfulness.\n\nShows the histogram of chromaticity (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of C, s or M after CIECAM02.\n\nC, s and M are not shown in the main histogram panel.\nFor final output refer to the main histogram panel. +!TP_COLORAPP_DATACIE;CIECAM02 output histograms in curves +!TP_COLORAPP_DATACIE_TOOLTIP;When enabled, histograms in CIECAM02 curves show approximate values/ranges for J or Q, and C, s or M after the CIECAM02 adjustments.\nThis selection does not impact the main histogram panel.\n\nWhen disabled, histograms in CIECAM02 curves show L*a*b* values before CIECAM02 adjustments. +!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RawTherapee calculates an optimum value, which is then used by CAT02, and also for the entire CIECAM02.\nTo set the value manually, uncheck the check-box first (values above 65 are recommended). +!TP_COLORAPP_DEGREE_TOOLTIP;Amount of CIE Chromatic Adaptation Transform 2002. +!TP_COLORAPP_GAMUT;Gamut control (L*a*b*) +!TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in L*a*b* mode. +!TP_COLORAPP_HUE;Hue (h) +!TP_COLORAPP_HUE_TOOLTIP;Hue (h) - angle between 0° and 360°. +!TP_COLORAPP_LABEL;CIE Color Appearance Model 2002 +!TP_COLORAPP_LABEL_CAM02;Image Adjustments +!TP_COLORAPP_LABEL_SCENE;Scene Conditions +!TP_COLORAPP_LABEL_VIEWING;Viewing Conditions +!TP_COLORAPP_LIGHT;Lightness (J) +!TP_COLORAPP_LIGHT_TOOLTIP;Lightness in CIECAM02 differs from L*a*b* and RGB lightness. +!TP_COLORAPP_MODEL;WP Model +!TP_COLORAPP_MODEL_TOOLTIP;White-Point Model.\n\nWB [RT] + [output]: RT's white balance is used for the scene, CIECAM02 is set to D50, and the output device's white balance is set in Preferences > Color Management.\n\nWB [RT+CAT02] + [output]: RT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences - Color Management. +!TP_COLORAPP_RSTPRO;Red & skin-tones protection +!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin-tones protection affects both sliders and curves. +!TP_COLORAPP_SHARPCIE;--unused-- +!TP_COLORAPP_SHARPCIE_TOOLTIP;--unused-- +!TP_COLORAPP_SURROUND;Surround +!TP_COLORAPP_SURROUND_AVER;Average +!TP_COLORAPP_SURROUND_DARK;Dark +!TP_COLORAPP_SURROUND_DIM;Dim +!TP_COLORAPP_SURROUND_EXDARK;Extremly Dark (Cutsheet) +!TP_COLORAPP_SURROUND_TOOLTIP;Changes tones and colors to take into account the viewing conditions of the output device.\n\nAverage: Average light environment (standard). The image will not change.\n\nDim: Dim environment (TV). The image will become slighty dark.\n\nDark: Dark environment (projector). The image will become more dark.\n\nExtremly Dark: Extremly dark environment (cutsheet). The image will become very dark. +!TP_COLORAPP_SURSOURCE;Dark surround +!TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if image has a dark border. +!TP_COLORAPP_TCMODE_BRIGHTNESS;Brightness +!TP_COLORAPP_TCMODE_CHROMA;Chroma +!TP_COLORAPP_TCMODE_COLORF;Colorfulness +!TP_COLORAPP_TCMODE_LABEL1;Curve mode 1 +!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_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] +!TP_COLORAPP_WBRT;WB [RT] + [output] +!TP_COLORTONING_AB;o C/L +!TP_COLORTONING_AUTOSAT;Automatic +!TP_COLORTONING_BALANCE;Balance +!TP_COLORTONING_BY;o C/L +!TP_COLORTONING_CHROMAC;Opacity +!TP_COLORTONING_COLOR;Color +!TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;Chroma opacity as a function of luminance oC=f(L) +!TP_COLORTONING_HIGHLIGHT;Highlights +!TP_COLORTONING_HUE;Hue +!TP_COLORTONING_LABEL;Color Toning +!TP_COLORTONING_LAB;L*a*b* blending +!TP_COLORTONING_LUMAMODE;Preserve luminance +!TP_COLORTONING_LUMAMODE_TOOLTIP;If enabled, when you change color (red, green, cyan, blue, etc.) the luminance of each pixel is preserved. +!TP_COLORTONING_LUMA;Luminance +!TP_COLORTONING_METHOD;Method +!TP_COLORTONING_METHOD_TOOLTIP;"L*a*b* blending", "RGB sliders" and "RGB curves" use interpolated color blending.\n"Color balance (Shadows/Midtones/Highlights)" and "Saturation 2 colors" use direct colors.\n\nThe Black-and-White tool can be enabled when using any color toning method, which allows for color toning. +!TP_COLORTONING_MIDTONES;Midtones +!TP_COLORTONING_NEUTRAL;Reset sliders +!TP_COLORTONING_NEUTRAL_TIP;Reset all values (Shadows, Midtones, Highlights) to default. +!TP_COLORTONING_OPACITY;Opacity +!TP_COLORTONING_RGBCURVES;RGB - Curves +!TP_COLORTONING_RGBSLIDERS;RGB - Sliders +!TP_COLORTONING_SATURATEDOPACITY;Strength +!TP_COLORTONING_SATURATIONTHRESHOLD;Threshold +!TP_COLORTONING_SA;Saturation Protection +!TP_COLORTONING_SHADOWS;Shadows +!TP_COLORTONING_SPLITCOCO;Color Balance Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITCO;Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITLR;Saturation 2 colors +!TP_COLORTONING_STRENGTH;Strength +!TP_COLORTONING_STR;Strength +!TP_COLORTONING_TWO2;Special chroma '2 colors' +!TP_COLORTONING_TWOALL;Special chroma +!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_GTFRAME;Frame +!TP_CROP_GTHARMMEANS;Harmonic Means +!TP_CROP_GTTRIANGLE1;Golden Triangles 1 +!TP_CROP_GTTRIANGLE2;Golden Triangles 2 +!TP_DIRPYRDENOISE_33;3×3 strong +!TP_DIRPYRDENOISE_55SOFT;5×5 +!TP_DIRPYRDENOISE_55;5×5 strong +!TP_DIRPYRDENOISE_77;7×7 (slow) +!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_ABM;Chroma only +!TP_DIRPYRDENOISE_AUTO;Automatic global +!TP_DIRPYRDENOISE_AUTO_TOOLTIP;Try to evaluate chroma noise\nBe careful, this calculation is average, and is quite subjective ! +!TP_DIRPYRDENOISE_AUT;Automatic global +!TP_DIRPYRDENOISE_BLUE;Chrominance - Blue-Yellow +!TP_DIRPYRDENOISE_C2TYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CCCURVE;Chrominance curve +!TP_DIRPYRDENOISE_CHROMAFR;Chrominance +!TP_DIRPYRDENOISE_CTYPE;Auto method +!TP_DIRPYRDENOISE_CTYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nAutomatic multi-zones\nNo preview - works only during saving, but using the "Preview" method by matching the tile size and center to the preview size and center you can get an idea of the expected results.\nThe image is divided into tiles (about 10 to 70 depending on image size) and each tile receives its own chrominance noise reduction settings.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CURVEEDITOR_CC;Chroma +!TP_DIRPYRDENOISE_CURVEEDITOR_CC_TOOLTIP;Increase (multiply) the value of all chrominance sliders.\nThis curve lets you adjust the strength of chromatic noise reduction as a function of chromaticity, for instance to increase the action in areas of low saturation and to decrease it in those of high saturation. +!TP_DIRPYRDENOISE_CURVEEDITOR_L_TOOLTIP;Modulates action of 'Luminance' denoise +!TP_DIRPYRDENOISE_CUR;Curve +!TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on the gamma of the input color profile. An sRGB gamma is assumed, thus if the image uses an input color profile of a different gamma, the effects of luminance noise reduction will differ. +!TP_DIRPYRDENOISE_ENH;Enhanced mode +!TP_DIRPYRDENOISE_ENH_TOOLTIP;Increases noise reduction quality at the expense of a 20% processing time increase. +!TP_DIRPYRDENOISE_GAMMA_TOOLTIP;Gamma varies noise reduction strength across the range of tones. Smaller values will target shadows, while larger values will stretch the effect to the brighter tones. +!TP_DIRPYRDENOISE_LABM;L*a*b* +!TP_DIRPYRDENOISE_LCURVE;Luminance curve +!TP_DIRPYRDENOISE_LDETAIL;Luminance - Detail +!TP_DIRPYRDENOISE_LM;Luminance only +!TP_DIRPYRDENOISE_LPLABM;Weighted L* (little) + a*b* (normal) +!TP_DIRPYRDENOISE_LTYPE;Luminance control +!TP_DIRPYRDENOISE_LUMAFR;Luminance +!TP_DIRPYRDENOISE_LUMAFR_TOOLTIP;Wavelet on luminance and Fourier transform for luminance detail +!TP_DIRPYRDENOISE_MANU;Manual +!TP_DIRPYRDENOISE_MAN;Manual +!TP_DIRPYRDENOISE_MEDMETHOD;Median method +!TP_DIRPYRDENOISE_MEDTYPE;Median type +!TP_DIRPYRDENOISE_MED;Median Filter +!TP_DIRPYRDENOISE_MED_TOOLTIP;Enabled median denoising +!TP_DIRPYRDENOISE_METHOD11;Quality +!TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. +!TP_DIRPYRDENOISE_METHOD;Method +!TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or L*a*b* methods can be used.\n\nFor non-raw images the L*a*b* method will be used, regardless of the selection. +!TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - +!TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 +!TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. +!TP_DIRPYRDENOISE_PASSES;Median iterations +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PON;Auto multi-zones +!TP_DIRPYRDENOISE_PREVLABEL;Preview size=%1, Center: Px=%2 Py=%3 +!TP_DIRPYRDENOISE_PREV;Preview +!TP_DIRPYRDENOISE_PRE;Preview multi-zones +!TP_DIRPYRDENOISE_RED;Chrominance - Red-Green +!TP_DIRPYRDENOISE_RGBM;RGB +!TP_DIRPYRDENOISE_RGB;RGB +!TP_DIRPYRDENOISE_SHALBI;High +!TP_DIRPYRDENOISE_SHAL;Standard +!TP_DIRPYRDENOISE_SLI;Slider +!TP_DIRPYRDENOISE_SOFT;3x3 +!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_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_EPD_EDGESTOPPING;Edge stopping +!TP_EPD_GAMMA;Gamma +!TP_EPD_LABEL;Tone Mapping +!TP_EPD_REWEIGHTINGITERATES;Reweighting iterates +!TP_EPD_SCALE;Scale +!TP_EPD_STRENGTH;Strength +!TP_EPD_TOOLTIP;Tone mapping is possible in L*a*b* mode (standard) and CIECAM02 mode.\n\nWhen in L*a*b* mode, tone mapping can also be used on the residual image of the Wavelet Levels tool.\n\nTo engage CIECAM02 tone mapping mode enable the following settings:\n1. CIECAM02\n2. Algorithm="Brightness + Colorfulness (QM)"\n3. "Tone mapping using CIECAM02 brightness (Q)" +!TP_EXPOSURE_AUTOLEVELS_TIP;Toggles execution of Auto Levels to automatically set Exposure slider values based on an image analysis.\nEnables Highlight Reconstruction if necessary. +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in Auto Levels operation. +!TP_EXPOSURE_CURVEEDITOR1;Tone curve 1 +!TP_EXPOSURE_CURVEEDITOR2;Tone curve 2 +!TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Please refer to the "Exposure > Tone Curves" RawPedia article to learn how to achieve the best results by using two tone curves. +!TP_EXPOSURE_TCMODE_FILMLIKE;Film-like +!TP_EXPOSURE_TCMODE_LABEL1;Curve mode 1 +!TP_EXPOSURE_TCMODE_LABEL2;Curve mode 2 +!TP_EXPOSURE_TCMODE_LUMINANCE;Luminance +!TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Saturation and Value Blending +!TP_EXPOSURE_TCMODE_STANDARD;Standard +!TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard +!TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points +!TP_EXPOS_WHITEPOINT_LABEL;Raw White Points +!TP_FILMSIMULATION_LABEL;Film Simulation +!TP_FILMSIMULATION_STRENGTH;Strength +!TP_FILMSIMULATION_ZEROCLUTSFOUND;Set HaldCLUT directory in Preferences +!TP_FLATFIELD_CLIPCONTROL;Clip control +!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. +!TP_GAMMA_CURV;Gamma +!TP_GENERAL_11SCALE_TOOLTIP;The effects of this tool are only visible or only accurate at a preview scale of 1:1. +!TP_GRADIENT_CENTER;Center +!TP_GRADIENT_CENTER_X;Center X +!TP_GRADIENT_CENTER_X_TOOLTIP;Shift gradient to the left (negative values) or right (positive values). +!TP_GRADIENT_CENTER_Y;Center Y +!TP_GRADIENT_CENTER_Y_TOOLTIP;Shift gradient up (negative values) or down (positive values). +!TP_GRADIENT_DEGREE;Angle +!TP_GRADIENT_DEGREE_TOOLTIP;Rotation angle in degrees. +!TP_GRADIENT_FEATHER;Feather +!TP_GRADIENT_FEATHER_TOOLTIP;Gradient width in percent of the image diagonal. +!TP_GRADIENT_LABEL;Graduated Filter +!TP_GRADIENT_STRENGTH;Strength +!TP_GRADIENT_STRENGTH_TOOLTIP;Filter strength in stops. +!TP_HLREC_ENA_TOOLTIP;Could be activated by Auto Levels. +!TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover clipped highlights when using LUT-based ICC profiles. +!TP_ICM_DCPILLUMINANT;Illuminant +!TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolated +!TP_ICM_DCPILLUMINANT_TOOLTIP;Select which embedded DCP illuminant to employ. Default is "interpolated" which is a mix between the two based on white balance. The setting is only enabled if a Dual-Illuminant DCP with interpolation support is selected. +!TP_ICM_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input color profiles. These profiles are more precise than simpler matrix ones. They are not available for all cameras. These profiles are stored in the /iccprofiles/input and /dcpprofiles folders and are automatically retrieved based on a file name matching to the exact model name of the camera. +!TP_ICM_INPUTCAMERA_TOOLTIP;Use a simple color matrix from dcraw, an enhanced RawTherapee version (whichever is available based on camera model) or one embedded in the DNG. +!TP_ICM_INPUTCUSTOM_TOOLTIP;Select your own DCP/ICC color profile file for the camera. +!TP_ICM_INPUTEMBEDDED_TOOLTIP;Use color profile embedded in non-raw files. +!TP_ICM_INPUTNONE_TOOLTIP;Use no input color profile at all.\nUse only in special cases. +!TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance +!TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. The result can be used for calibration purposes and generation of a camera profile. +!TP_ICM_TONECURVE;Use DCP's tone curve +!TP_ICM_TONECURVE_TOOLTIP;Employ the embedded DCP tone curve. The setting is only enabled if the selected DCP has a tone curve. +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid color shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction. +!TP_LABCURVE_CHROMATICITY;Chromaticity +!TP_LABCURVE_CHROMA_TOOLTIP;To apply B&W toning, set Chromaticity to -100. +!TP_LABCURVE_CURVEEDITOR_A_RANGE1;Green Saturated +!TP_LABCURVE_CURVEEDITOR_A_RANGE2;Green Pastel +!TP_LABCURVE_CURVEEDITOR_A_RANGE3;Red Pastel +!TP_LABCURVE_CURVEEDITOR_A_RANGE4;Red Saturated +!TP_LABCURVE_CURVEEDITOR_B_RANGE1;Blue Saturated +!TP_LABCURVE_CURVEEDITOR_B_RANGE2;Blue Pastel +!TP_LABCURVE_CURVEEDITOR_B_RANGE3;Yellow Pastel +!TP_LABCURVE_CURVEEDITOR_B_RANGE4;Yellow Saturated +!TP_LABCURVE_CURVEEDITOR_CC;CC +!TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutral +!TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Dull +!TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastel +!TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Saturated +!TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Chromaticity according to chromaticity C=f(C) +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to hue C=f(H) +!TP_LABCURVE_CURVEEDITOR_CL;CL +!TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Chromaticity according to luminance C=f(L) +!TP_LABCURVE_CURVEEDITOR_HH;HH +!TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Hue according to hue H=f(H) +!TP_LABCURVE_CURVEEDITOR_LC;LC +!TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminance according to chromaticity L=f(C) +!TP_LABCURVE_CURVEEDITOR_LH;LH +!TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H) +!TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminance according to luminance L=f(L) +!TP_LABCURVE_LCREDSK;Restrict LC to red and skin-tones +!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_USECA;Chromatic aberration correction +!TP_LENSPROFILE_USEDIST;Distortion correction +!TP_LENSPROFILE_USEVIGN;Vignetting correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Resets exposure sliders to neutral values.\nApplies to the same controls that Auto Levels applies to, regardless of whether you used Auto Levels or not. +!TP_PCVIGNETTE_FEATHER;Feather +!TP_PCVIGNETTE_FEATHER_TOOLTIP;Feathering:\n0 = corners only,\n50 = halfway to center,\n100 = to center. +!TP_PCVIGNETTE_LABEL;Vignette Filter +!TP_PCVIGNETTE_ROUNDNESS;Roundness +!TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness:\n0 = rectangle,\n50 = fitted ellipse,\n100 = circle. +!TP_PCVIGNETTE_STRENGTH;Strength +!TP_PCVIGNETTE_STRENGTH_TOOLTIP;Filter strength in stops (reached in corners). +!TP_PFCURVE_CURVEEDITOR_CH;Hue +!TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Controls defringe strength by color.\nHigher = more,\nLower = less. +!TP_PREPROCESS_DEADPIXFILT;Dead pixel filter +!TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Tries to suppress dead pixels. +!TP_PREPROCESS_HOTPIXFILT;Hot pixel filter +!TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Tries to suppress hot pixels. +!TP_RAWEXPOS_BLACK_0;Green 1 (lead) +!TP_RAWEXPOS_BLACK_1;Red +!TP_RAWEXPOS_BLACK_2;Blue +!TP_RAWEXPOS_BLACK_3;Green 2 +!TP_RAWEXPOS_BLACK_BLUE;Blue +!TP_RAWEXPOS_BLACK_GREEN;Green +!TP_RAWEXPOS_BLACK_RED;Red +!TP_RAWEXPOS_RGB;Red, Green, Blue +!TP_RAW_DMETHOD_PROGRESSBAR;%1 demosaicing... +!TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Demosaicing refinement... +!TP_RAW_DMETHOD_TOOLTIP;Note: IGV and LMMSE are dedicated to high ISO images to aid in noise reduction without leading to maze patterns, posterization or a washed-out look. +!TP_RAW_HD;Threshold +!TP_RAW_HD_TOOLTIP;Lower values make hot/dead pixel detection more aggressive, but false positives may lead to artifacts. If you notice any artifacts appearing when enabling the Hot/Dead Pixel Filters, gradually increase the threshold value until they disappear. +!TP_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!TP_RAW_LMMSE_TOOLTIP;Adds gamma (step 1), median (steps 2-4) and refinement (steps 5-6) to reduce artifacts and improve the signal-to-noise ratio. +!TP_RAW_SENSOR_BAYER_LABEL;Sensor with Bayer Matrix +!TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;3-pass gives best results (recommended for low ISO images).\n1-pass is almost undistinguishable from 3-pass for high ISO images and is faster. +!TP_RAW_SENSOR_XTRANS_LABEL;Sensor with X-Trans Matrix +!TP_RGBCURVES_BLUE;B +!TP_RGBCURVES_CHANNEL;Channel +!TP_RGBCURVES_GREEN;G +!TP_RGBCURVES_LABEL;RGB Curves +!TP_RGBCURVES_LUMAMODE;Luminosity mode +!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_RGBCURVES_RED;R +!TP_SAVEDIALOG_OK_TIP;Shortcut: Ctrl-Enter +!TP_SHADOWSHLIGHTS_SHARPMASK;Sharp mask +!TP_SHARPENING_TOOLTIP;Expect a slightly different effect when using with CIECAM02. If difference is observed, adjust to taste. +!TP_VIBRANCE_AVOIDCOLORSHIFT;Avoid color shift +!TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Red/Purple +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Red +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Red/Yellow +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Yellow +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Hue according to hue H=f(H) +!TP_VIBRANCE_LABEL;Vibrance +!TP_VIBRANCE_PASTELS;Pastel Tones +!TP_VIBRANCE_PASTSATTOG;Link pastel and saturated tones +!TP_VIBRANCE_PROTECTSKINS;Protect skin-tones +!TP_VIBRANCE_PSTHRESHOLD;Pastel/saturated tones threshold +!TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Saturation threshold +!TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;The vertical axis represents pastel tones at the bottom and saturated tones at the top.\nThe horizontal axis represents the saturation range. +!TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Pastel/saturated transition's weighting +!TP_VIBRANCE_SATURATED;Saturated Tones +!TP_WAVELET_1;Level 1 +!TP_WAVELET_2;Level 2 +!TP_WAVELET_3;Level 3 +!TP_WAVELET_4;Level 4 +!TP_WAVELET_5;Level 5 +!TP_WAVELET_6;Level 6 +!TP_WAVELET_7;Level 7 +!TP_WAVELET_8;Level 8 +!TP_WAVELET_9;Level 9 +!TP_WAVELET_ALL;All levels in all directions +!TP_WAVELET_APPLYTO;Apply To +!TP_WAVELET_AVOID;Avoid color shift +!TP_WAVELET_B0;Black +!TP_WAVELET_B1;Grey +!TP_WAVELET_B2;Residual +!TP_WAVELET_BACUR;Curve +!TP_WAVELET_BALANCE;Contrast balance d/v-h +!TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chromaticity or residual tone mapping are activated, the effect due to balance is amplified. +!TP_WAVELET_BALCHRO;Chroma balance +!TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chromaticity balance. +!TP_WAVELET_BANONE;None +!TP_WAVELET_BASLI;Slider +!TP_WAVELET_BATYPE;Contrast balance method +!TP_WAVELET_CCURVE;Local contrast +!TP_WAVELET_CH1;Whole chromaticity range +!TP_WAVELET_CH2;Saturated/pastel +!TP_WAVELET_CH3;Link contrast levels +!TP_WAVELET_CHCU;Curve +!TP_WAVELET_CHRO;Saturated/pastel threshold +!TP_WAVELET_CHRO_TOOLTIP;Sets the wavelet level which will be the threshold between saturated and pastel colors.\n1-x: saturated\nx-9: pastel\n\nIf the value exceeds the amount of wavelet levels you are using then it will be ignored. +!TP_WAVELET_CHR;Chroma-contrast link strength +!TP_WAVELET_CHR_TOOLTIP;Adjusts chromaticity as a function of "contrast levels" and "chroma-contrast link strength" +!TP_WAVELET_CHSL;Sliders +!TP_WAVELET_CHTYPE;Chrominance method +!TP_WAVELET_COLORT;Opacity Red-Green +!TP_WAVELET_COMBOTH;Both +!TP_WAVELET_COMPCONT;Contrast +!TP_WAVELET_COMPGAMMA;Compression gamma +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjusting the gamma of the residual image allow you to equilibrate the data and histogram. +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjust gamma for residual image and compression.\nAllow to equilibrate data and histogram +!TP_WAVELET_COMPTM;Tone mapping +!TP_WAVELET_CONTEDIT;'After' Contrast curve +!TP_WAVELET_CONTEDIT;'After' contrast curve +!TP_WAVELET_CONTRAST_MINUS;Contrast - +!TP_WAVELET_CONTRAST_PLUS;Contrast + +!TP_WAVELET_CONTRA;Contrast +!TP_WAVELET_CONTRA_TOOLTIP;Changes contrast of the residual image. +!TP_WAVELET_CONTR;Gamut +!TP_WAVELET_CTYPE;Chrominance control +!TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modifies local contrast as a function of the original local contrast (absciss)\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 100..300)\n66% absciss represents standard deviation of local contrast (real value about 300..800)\n100% represents maximum (real value about 3000..8000) +!TP_WAVELET_CURVEEDITOR_CH;Contrast levels=f(Hue) +!TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modifies each level's contrast as a function oh hue.\nTake care not to overwrite changes made with the Gamut Hue controls.\nThe curve will only have an effect when wavelet contrast level sliders are non-zero. +!TP_WAVELET_CURVEEDITOR_CL;L +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Applies a final contrast luminance curve at the end of the wavelet treatment. +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Apply a contrast luminance curve at the end of wavelet level threatment +!TP_WAVELET_CURVEEDITOR_HH;HH +!TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modifies the residual image's hue as a function of hue. +!TP_WAVELET_DALL;All directions +!TP_WAVELET_DAUB;Edge performance +!TP_WAVELET_DAUB_TOOLTIP;Changes Daubechies coefficients:\nD4 = Standard,\nD14 = Often best performance, 10% more time-intensive.\n\nAffects edge detection as well as the general quality of the firsts levels. However the quality is not strictly related to this coefficient and can vary with images and uses. +!TP_WAVELET_DISP;Preview Settings +!TP_WAVELET_DONE;Vertical +!TP_WAVELET_DTHR;Diagonal +!TP_WAVELET_DTWO;Horizontal +!TP_WAVELET_EDCU;Curve +!TP_WAVELET_EDGCONT;Local contrast +!TP_WAVELET_EDGCONT_TOOLTIP;Adjusting the points to the left decreases contrast, and to the right increases it.\nBottom-left, Top-Left, Top-Right, Bottom-right represent respectively local contast for low values, mean, mean+stdev, maxima +!TP_WAVELET_EDGEDETECTTHR2;Threshold high (detection) +!TP_WAVELET_EDGEDETECTTHR;Threshold low (noise) +!TP_WAVELET_EDGEDETECTTHR_TOOLTIP;This adjuster lets you target edge detection for example to avoid applying edge sharpness to fine details, such as noise in the sky. +!TP_WAVELET_EDGEDETECT;Gradient sensitivity +!TP_WAVELET_EDGEDETECT_TOOLTIP;Moving the slider to the right increases edge sensitivity. This affects local contrast, edge settings and noise. +!TP_WAVELET_EDGE;Edge Sharpness +!TP_WAVELET_EDGREINF_TOOLTIP;Reinforce or reduce the action of the first level, do the opposite to the second level, and leave the rest unchanged. +!TP_WAVELET_EDGTHRESH;Detail +!TP_WAVELET_EDGTHRESH_TOOLTIP;Change the repartition between the first levels and the others. The higher the threshold the more the action is centred on the first levels. Be careful with negative values, they increase the action of high levels and can introduce artifacts. +!TP_WAVELET_EDRAD;Radius +!TP_WAVELET_EDRAD_TOOLTIP;This radius adjustment is very different from those in other sharpening tools. Its value is compared to each level through a complex function. In this sense, a value of zero still has an effect. +!TP_WAVELET_EDSL;Threshold Sliders +!TP_WAVELET_EDTYPE;Local contrast method +!TP_WAVELET_EDVAL;Strength +!TP_WAVELET_FINAL;Final Touchup +!TP_WAVELET_FINEST;Finest +!TP_WAVELET_HIGHLIGHT;Highlight luminance range +!TP_WAVELET_HS1;Whole luminance range +!TP_WAVELET_HS2;Shadows/Highlights +!TP_WAVELET_HUESKIN;Skin hue +!TP_WAVELET_HUESKIN_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_HUESKY;Sky hue +!TP_WAVELET_HUESKY_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_INF;Below or equal the level +!TP_WAVELET_ITER;Delta balance levels +!TP_WAVELET_ITER_TOOLTIP;Left: increase low levels and reduce high levels,\nRight: reduce low levels and increase high levels. +!TP_WAVELET_LABEL;Wavelet levels +!TP_WAVELET_LARGEST;Coarsest +!TP_WAVELET_LEVCH;Chromaticity +!TP_WAVELET_LEVELS;Wavelet levels +!TP_WAVELET_LEVELS_TOOLTIP;Choose the number of detail levels the image is to be decomposed into. More levels require more RAM and require a longer processing time. +!TP_WAVELET_LEVF;Contrast +!TP_WAVELET_LEVLABEL;Preview maximum possible levels = %1 +!TP_WAVELET_LEVONE;Level 2 +!TP_WAVELET_LEVTWO;Level 3 +!TP_WAVELET_LEVZERO;Level 1 +!TP_WAVELET_LINKEDG;Link with Edge Sharpness' Strength +!TP_WAVELET_LIPST;Enhanced algorithm +!TP_WAVELET_LIPST_TOOLTIP;This algorithm uses Lipschitz regularity to increase edge detection quality at a cost of increased processing time and memory requirements. +!TP_WAVELET_LOWLIGHT;Shadow luminance range +!TP_WAVELET_MEDGREINF;First level +!TP_WAVELET_MEDILEV;Edge detection +!TP_WAVELET_MEDI;Reduce artifacts in blue sky +!TP_WAVELET_NEUTRAL;Neutral +!TP_WAVELET_NOISE;Denoise and Refine +!TP_WAVELET_NOIS;Denoise +!TP_WAVELET_ONE;One level +!TP_WAVELET_OPACITYWL;Final local contrast +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify final local contrast in function of last local contrast (absciss) for all levels decomposition\nTake into account: \na)contrast levels \nb)edge sharpness \nc)contrast balance\nd)decomposition-recomposition\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 200..1000)\n66% absciss represents standard deviation of local contrast (real value about 1000..2000)\n100% represents maximum (real value about 5000..13000) +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify the final local contrast at the end of the wavelet treatment.\n\nThe left side represents the smallest local contrast, progressing to the largest local contrast on the right. +!TP_WAVELET_OPACITYW;Contrast balance d/v-h curve +!TP_WAVELET_OPACITY;Opacity Blue-Yellow +!TP_WAVELET_PASTEL;Pastel chromaticity +!TP_WAVELET_PREVIEWBACK;Background +!TP_WAVELET_PREVIEWLEVELS;Preview +!TP_WAVELET_RE1;Reinforced +!TP_WAVELET_RE2;Unchanged +!TP_WAVELET_RE3;Reduced +!TP_WAVELET_RESCHRO;Chromaticity +!TP_WAVELET_RESCONH;Highlights +!TP_WAVELET_RESCON;Shadows +!TP_WAVELET_RESID;Residual image +!TP_WAVELET_SAT;Saturated chromaticity +!TP_WAVELET_SETTINGS;Wavelet Settings +!TP_WAVELET_SKIN;Skin targetting/protection +!TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected. +!TP_WAVELET_SKY;Sky targetting/protection +!TP_WAVELET_SKY_TOOLTIP;At -100 sky-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 sky-tones are protected while all other tones are affected. +!TP_WAVELET_STRENGTH;Strength +!TP_WAVELET_STREN;Strength +!TP_WAVELET_SUPE;Extra +!TP_WAVELET_SUP;Above the level +!TP_WAVELET_THRESHOLD2;Shadow levels +!TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels between 9 and 9 minus the value will be affected by the shadow luminance range. Other levels will be fully treated. The highest level possible is limited by the highlight level value (9 minus highlight level value). +!TP_WAVELET_THRESHOLD;Highlight levels +!TP_WAVELET_THRESHOLD_TOOLTIP;Only levels beyond the chosen value will be affected by the highlight luminance range. Other levels will be fully treated. The chosen value here limits the highest possible value of the shadow levels. +!TP_WAVELET_THRH;Highlights threshold +!TP_WAVELET_THR;Shadows threshold +!TP_WAVELET_TILESBIG;Big tiles +!TP_WAVELET_TILESFULL;Full image +!TP_WAVELET_TILESIZE;Tiling method +!TP_WAVELET_TILESLIT;Little tiles +!TP_WAVELET_TILES_TOOLTIP;Processing the full image leads to better quality and is the recommended option, while using tiles is a fall-back solution for users with little RAM. Refer to RawPedia for memory requirements. +!TP_WAVELET_TMHIGH;High +!TP_WAVELET_TMLOWHIGH;Low+High +!TP_WAVELET_TMNONE;None +!TP_WAVELET_TMSTD;Standard +!TP_WAVELET_TMSTRENGTH;Compression strength +!TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image. When the value is different from 0, the Strength and Gamma sliders of the Tone Mapping tool in the Exposure tab will become grayed out. +!TP_WAVELET_TMTYPE;Compression method +!TP_WAVELET_TON;Toning +!TP_WAVELET_daub2;D2 - low +!TP_WAVELET_daub4;D4 - standard +!TP_WAVELET_daub6;D6 - standard plus +!TP_WAVELET_daub10;D10 - medium +!TP_WAVELET_daub14;D14 - high +!TP_WBALANCE_CLOUDY;Cloudy +!TP_WBALANCE_DAYLIGHT;Daylight (sunny) +!TP_WBALANCE_EQBLUERED;Blue/Red equalizer +!TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behavior of "white balance" by modulating the blue/red balance.\nThis can be useful when shooting conditions:\na) are far from the standard illuminant (e.g. underwater),\nb) are far from conditions where calibrations were performed,\nc) where the matrices or ICC profiles are unsuitable. +!TP_WBALANCE_FLASH55;Leica +!TP_WBALANCE_FLASH60;Standard, Canon, Pentax, Olympus +!TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta +!TP_WBALANCE_FLASH_HEADER;Flash +!TP_WBALANCE_FLUO1;F1 - Daylight +!TP_WBALANCE_FLUO2;F2 - Cool White +!TP_WBALANCE_FLUO3;F3 - White +!TP_WBALANCE_FLUO4;F4 - Warm White +!TP_WBALANCE_FLUO5;F5 - Daylight +!TP_WBALANCE_FLUO6;F6 - Lite White +!TP_WBALANCE_FLUO7;F7 - D65 Daylight Simulator +!TP_WBALANCE_FLUO8;F8 - D50 / Sylvania F40 Design +!TP_WBALANCE_FLUO9;F9 - Cool White Deluxe +!TP_WBALANCE_FLUO10;F10 - Philips TL85 +!TP_WBALANCE_FLUO11;F11 - Philips TL84 +!TP_WBALANCE_FLUO12;F12 - Philips TL83 +!TP_WBALANCE_FLUO_HEADER;Fluorescent +!TP_WBALANCE_GTI;GTI +!TP_WBALANCE_HMI;HMI +!TP_WBALANCE_JUDGEIII;JudgeIII +!TP_WBALANCE_LAMP_HEADER;Lamp +!TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 +!TP_WBALANCE_LED_HEADER;LED +!TP_WBALANCE_LED_LSI;LSI Lumelex 2040 +!TP_WBALANCE_SHADE;Shade +!TP_WBALANCE_SOLUX35;Solux 3500K +!TP_WBALANCE_SOLUX41;Solux 4100K +!TP_WBALANCE_SOLUX47;Solux 4700K (vendor) +!TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) +!TP_WBALANCE_TUNGSTEN;Tungsten +!TP_WBALANCE_WATER1;UnderWater 1 +!TP_WBALANCE_WATER2;UnderWater 2 +!TP_WBALANCE_WATER_HEADER;UnderWater +!ZOOMPANEL_ZOOMFITCROPSCREEN;Fit crop to screen\nShortcut: Alt-f diff --git a/rtdata/languages/Serbian (Latin Characters) b/rtdata/languages/Serbian (Latin Characters) new file mode 100644 index 000000000..7db78df94 --- /dev/null +++ b/rtdata/languages/Serbian (Latin Characters) @@ -0,0 +1,1857 @@ +#01 2010-11-16 gpopac + +ABOUT_TAB_BUILD;Izdanje +ABOUT_TAB_CREDITS;Zasluge +ABOUT_TAB_LICENSE;Licenca +ABOUT_TAB_SPLASH;Uvod +ADJUSTER_RESET_TO_DEFAULT;Vrati na podrazumevano +BATCHQUEUE_AUTOSTART;Sam započni +BATCH_PROCESSING;obrada +CURVEEDITOR_CURVES;Krivulje +CURVEEDITOR_CURVE;Krivulja +CURVEEDITOR_CUSTOM;Proizvoljno +CURVEEDITOR_DARKS;Tamno +CURVEEDITOR_HIGHLIGHTS;Presvetlo +CURVEEDITOR_LIGHTS;Svetlo +CURVEEDITOR_LINEAR;Linearno +CURVEEDITOR_LOADDLGLABEL;Učitaj krivu... +CURVEEDITOR_MINMAXCPOINTS;Min/maks. kontrolne tačke +CURVEEDITOR_NURBS;Sa kavezom +CURVEEDITOR_PARAMETRIC;Parametarski +CURVEEDITOR_SAVEDLGLABEL;Sačuvaj krivu... +CURVEEDITOR_SHADOWS;Senke +CURVEEDITOR_TOOLTIPCOPY;Umnožava trenutnu krivulju u ostavu +CURVEEDITOR_TOOLTIPLINEAR;Vraća krivu na linearnu +CURVEEDITOR_TOOLTIPLOAD;Učitava krivulju iz datoteke +CURVEEDITOR_TOOLTIPPASTE;Ubacuje krivulju iz ostave +CURVEEDITOR_TOOLTIPSAVE;Čuva trenutnu krivulju +CURVEEDITOR_TYPE;Vrsta: +DIRBROWSER_FOLDERS;Fascikle +EDITWINDOW_TITLE;Uređivanje slike +EXIFFILTER_APERTURE;Otvor blende +EXIFFILTER_CAMERA;Foto aparat +EXIFFILTER_FILETYPE;Vrsta datoteke +EXIFFILTER_FOCALLEN;Žižna daljina +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Objektiv +EXIFFILTER_METADATAFILTER;Filtriraj metapodatke +EXIFFILTER_SHUTTER;Ekspozicija +EXIFPANEL_ADDEDITHINT;Dodaje novu oznaku ili uređuje postojeću +EXIFPANEL_ADDEDIT;Dodaj/Izmeni +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Unesite vrednost +EXIFPANEL_ADDTAGDLG_SELECTTAG;Izaberite oznaku +EXIFPANEL_ADDTAGDLG_TITLE;Dodaj/Izmeni oznaku +EXIFPANEL_KEEPHINT;Zadržava izabrane oznake pri upisu izlazne datoteke +EXIFPANEL_KEEP;Zadrži +EXIFPANEL_REMOVEHINT;Uklanja izabrane oznake pri upisu izlazne datoteke +EXIFPANEL_REMOVE;Ukloni +EXIFPANEL_RESETALLHINT;Vraća sve oznake na početne vrednosti +EXIFPANEL_RESETALL;Vrati sve +EXIFPANEL_RESETHINT;Vraća izabranu oznaku na početnu vrednosti +EXIFPANEL_RESET;Vrati +EXIFPANEL_SUBDIRECTORY;Poddirektorijum +FILEBROWSER_ADDDELTEMPLATE;Dodaj/ukloni šablone... +FILEBROWSER_APPLYPROFILE;Primeni profil +FILEBROWSER_APPLYPROFILE_PARTIAL;Primeni profil (polovično) +FILEBROWSER_AUTODARKFRAME;Sam odredi tamni kadar +FILEBROWSER_AUTOFLATFIELD;Automatski odredi ravno polje +FILEBROWSER_BROWSEPATHBUTTONHINT;Kliknite za odlazak na uzabranu putanju +FILEBROWSER_BROWSEPATHHINT;Ukucajte putanju za razgledanje (Ctrl-o postavlja fokus, Ctrl-Enter prikazuje u razgledaču datoteka);nPrečice putanja: ~ — lični direktorijum, ! — direktorijum sa slikama +FILEBROWSER_CACHECLEARFROMFULL;Očisti iz ostave — sve +FILEBROWSER_CACHECLEARFROMPARTIAL;Očisti iz ostave — polovično +FILEBROWSER_CACHE;Ostava +FILEBROWSER_CLEARPROFILE;Obriši profil +FILEBROWSER_COPYPROFILE;Umnoži profil +FILEBROWSER_CURRENT_NAME;Trenutno ime: +FILEBROWSER_DARKFRAME;Tamni kadar +FILEBROWSER_DELETEDLGLABEL;Brisanje datoteke +FILEBROWSER_DELETEDLGMSGINCLPROC;Da li želite da obrišete %1 izabranih datoteka, uključujući i one koje su zakazane? +FILEBROWSER_DELETEDLGMSG;Da li sigurno želite da obrišete %1 datoteka? +FILEBROWSER_EMPTYTRASHHINT;Trajno briše datoteke iz smeća +FILEBROWSER_EMPTYTRASH;Izbaci smeće +FILEBROWSER_EXEC_CPB;Izgradi početni profil +FILEBROWSER_FLATFIELD;Ravno polje +FILEBROWSER_MOVETODARKFDIR;Prebaci u fasciklu sa tamnim kadrovima +FILEBROWSER_MOVETOFLATFIELDDIR;Premesti u fascikli sa ravnim poljima +FILEBROWSER_NEW_NAME;Novo ime: +FILEBROWSER_PARTIALPASTEPROFILE;Delimično ubaci +FILEBROWSER_PASTEPROFILE;Ubaci profil +FILEBROWSER_POPUPCANCELJOB;Otkaži zadatak +FILEBROWSER_POPUPCOLORLABEL;Obojena oznaka +FILEBROWSER_POPUPCOPYTO;Umnoži u... +FILEBROWSER_POPUPFILEOPERATIONS;Datoteka +FILEBROWSER_POPUPMOVEEND;Premesti na kraj zakazanih +FILEBROWSER_POPUPMOVEHEAD;Premesti na početak zakazanih +FILEBROWSER_POPUPMOVETO;Premesti u... +FILEBROWSER_POPUPOPENINEDITOR;Otvori u Uredniku +FILEBROWSER_POPUPOPEN;Otvori +FILEBROWSER_POPUPPROCESS;Zakaži za obradu +FILEBROWSER_POPUPPROFILEOPERATIONS;Profil +FILEBROWSER_POPUPREMOVEINCLPROC;Ukloni iz sistema datoteka i zakazanog +FILEBROWSER_POPUPREMOVE;Ukloni iz sistema datoteka +FILEBROWSER_POPUPRENAME;Preimenuj +FILEBROWSER_POPUPSELECTALL;Izaberi sve +FILEBROWSER_POPUPTRASH;Premesti u smeće +FILEBROWSER_POPUPUNRANK;Ukloni ocenu +FILEBROWSER_POPUPUNTRASH;Ukloni iz smeća +FILEBROWSER_QUERYBUTTONHINT;Očisti polje za pretragu +FILEBROWSER_QUERYHINT;Unesite deo imena datoteke za pretragu nCtrl-f postavlja fokus (u Razgledaču datoteka);nEnter pretražuje +FILEBROWSER_QUERYLABEL; Traži: +FILEBROWSER_RENAMEDLGLABEL;Preimenuj datoteku +FILEBROWSER_RENAMEDLGMSG;Preimenuj datoteku „%1“ u: +FILEBROWSER_SELECTDARKFRAME;Izaberi tamni kadar... +FILEBROWSER_SELECTFLATFIELD;Izaberi ravno polje... +FILEBROWSER_SHOWCOLORLABEL1HINT;Prikazuje slike označene crvenom Alt-1 +FILEBROWSER_SHOWCOLORLABEL2HINT;Prikazuje slike označene žutom Alt-2 +FILEBROWSER_SHOWCOLORLABEL3HINT;Prikazujeslike označene zelenom Alt-3 +FILEBROWSER_SHOWCOLORLABEL4HINT;Prikazuje slike označene plavom Alt-4 +FILEBROWSER_SHOWCOLORLABEL5HINT;Prikazuje slike označene ljubičastom Alt-5 +FILEBROWSER_SHOWDIRHINT;Prikazuje sve slike iz direktorijuma +FILEBROWSER_SHOWEDITEDHINT;Prikazuje samo izmenjene slike 7 +FILEBROWSER_SHOWEDITEDNOTHINT;Prikazuje samo neismenjene slike 6 +FILEBROWSER_SHOWEXIFINFO;Prikazuje EXIF podatke i +FILEBROWSER_SHOWRANK1HINT;Prikazuje slike ocenjene sa 1 zvezdicom +FILEBROWSER_SHOWRANK2HINT;Prikazuje slike ocenjene sa 2 zvezdice +FILEBROWSER_SHOWRANK3HINT;Prikazuje slike ocenjene sa 3 zvezdice +FILEBROWSER_SHOWRANK4HINT;Prikazuje slike ocenjene sa 4 zvezdice +FILEBROWSER_SHOWRANK5HINT;Prikazuje slike ocenjene sa 5 zvezdica +FILEBROWSER_SHOWRECENTLYSAVEDHINT;Prikazuje nedavno sačuvane slike Alt-7 +FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Prikazuje slike koje nisu skoro sačuvane Alt-6 +FILEBROWSER_SHOWTRASHHINT;Prikazuje slike u smeću +FILEBROWSER_SHOWUNCOLORHINT;Prikazuje slike koje nisu označene bojom Alt-0 +FILEBROWSER_SHOWUNRANKHINT;Prikaži neocenjene slike +FILEBROWSER_STARTPROCESSINGHINT;Počinje obradu i čuvanje zakazanih slika +FILEBROWSER_STARTPROCESSING;Započni obradu +FILEBROWSER_STOPPROCESSINGHINT;Zaustavlja obradu slika +FILEBROWSER_STOPPROCESSING;Zaustavi obradu +FILEBROWSER_THUMBSIZE;Pregled +FILEBROWSER_TOOLTIP_STOPPROCESSING;Pokreće obradu fotografija kada ih zakažete +FILEBROWSER_ZOOMINHINT;Uvećava pregled +FILEBROWSER_ZOOMOUTHINT;Umanjuje pregled +GENERAL_ABOUT;O programu +GENERAL_AFTER;Posle +GENERAL_BEFORE;Pre +GENERAL_CANCEL;Otkaži +GENERAL_DISABLED;Isključeno +GENERAL_DISABLE;Isključi +GENERAL_ENABLED;Uključi +GENERAL_ENABLE;Uključi +GENERAL_FILE;Datoteka +GENERAL_LANDSCAPE;Položeno +GENERAL_NA;nema +GENERAL_NONE;Ništa +GENERAL_NO;Ne +GENERAL_OK;U redu +GENERAL_PORTRAIT;Uspravno +GENERAL_SAVE;Sačuvaj +GENERAL_UNCHANGED;(neizmenjeno) +HISTOGRAM_TOOLTIP_BAR;Prikazuje/sakriva RGB indikator. Kliknite desni taster miša na umanjeni prikaz da zamrznete +HISTOGRAM_TOOLTIP_B;Prikazuje plavi histogram +HISTOGRAM_TOOLTIP_G;Prikazuje zeleni histogram +HISTOGRAM_TOOLTIP_L;Prikazuje CieLab hitogram +HISTOGRAM_TOOLTIP_RAW;Prikazuje/skriva RAW histogram +HISTOGRAM_TOOLTIP_R;Prikazuje crveni histogram +HISTORY_CHANGED;Izmenjeno +HISTORY_CUSTOMCURVE;Proizvoljna kriva +HISTORY_DELSNAPSHOT;Ukloni +HISTORY_FROMCLIPBOARD;Iz ostave +HISTORY_LABEL;Istorijat +HISTORY_MSG_1;Slika je učitana +HISTORY_MSG_2;Profil je učitan +HISTORY_MSG_3;Izmena profila +HISTORY_MSG_4;Razgledanje istorijata +HISTORY_MSG_5;Osvetljenost +HISTORY_MSG_6;Kontrast +HISTORY_MSG_7;Crna +HISTORY_MSG_8;Kompenzacija ekspozicije +HISTORY_MSG_9;Sabijanje svetlog +HISTORY_MSG_10;Sabijanje senki +HISTORY_MSG_11;Kriva nijansi +HISTORY_MSG_12;Auto ekspozicija +HISTORY_MSG_13;Odsecanje ekspozicije +HISTORY_MSG_14;Svetlina luminanse +HISTORY_MSG_15;Kontrast luminanse +HISTORY_MSG_16;Crna luminanse +HISTORY_MSG_17;Sabijanje senki l. +HISTORY_MSG_18;Sabijanje svetlog l. +HISTORY_MSG_19;Kriva luminanse +HISTORY_MSG_20;Oštrenje +HISTORY_MSG_21;Poluprečnik oštrenja +HISTORY_MSG_22;Količina oštrenja +HISTORY_MSG_23;Prag oštrenja +HISTORY_MSG_24;Izoštri samo ivice +HISTORY_MSG_25;Poluprečnik za nalaženje ivica +HISTORY_MSG_26;Tolerancija za nalaženje ivica +HISTORY_MSG_27;Kontrola areola oštrenja +HISTORY_MSG_28;Količina kontrole areala +HISTORY_MSG_29;Način oštrenja +HISTORY_MSG_30;Poluprečnik dekonvolucije +HISTORY_MSG_31;Količina dekonvolucije +HISTORY_MSG_32;Prigušivanje dekonvolucije +HISTORY_MSG_33;Ponavljanja dekonvolucije +HISTORY_MSG_34;Izbegni odsecanje boja +HISTORY_MSG_35;Graničnik zasićenja +HISTORY_MSG_36;Ograniči zasićenje +HISTORY_MSG_37;Pojačanje boja +HISTORY_MSG_38;Način balansiranja bele +HISTORY_MSG_39;Temperatura boje +HISTORY_MSG_40;Zalenilo boje +HISTORY_MSG_41;Pomeraj boje „A“ +HISTORY_MSG_42;Pomeraj boje „B“ +HISTORY_MSG_43;Uklanjanje svetlosnog šuma +HISTORY_MSG_44;Radijus ukl. svetlosnog šuma +HISTORY_MSG_45;Tolerancija ivice ukl. s. šuma +HISTORY_MSG_46;Uklanjanje kolornog šuma +HISTORY_MSG_47;Poluprečnik ukl. kolornog šuma +HISTORY_MSG_48;Tolerancija ivice ukl. k. šuma +HISTORY_MSG_49;Osetljivost ivice ukl. k. šuma +HISTORY_MSG_50;Alat za senke/svetlo +HISTORY_MSG_51;Pojačavanje svetline +HISTORY_MSG_52;Pojačavanje senki +HISTORY_MSG_53;Širina tonova za svetlo +HISTORY_MSG_54;Širina tonova za senke +HISTORY_MSG_55;Likalni kontrast +HISTORY_MSG_56;Poluprečnik senki/svetlog +HISTORY_MSG_57;Gruba rotacija +HISTORY_MSG_58;Horizontalno izvrtanje +HISTORY_MSG_59;Vertikalno izvrtanje +HISTORY_MSG_60;Rotacija +HISTORY_MSG_61;Rotacija +HISTORY_MSG_62;Ispravljanje izobličenja sočiva +HISTORY_MSG_63;Ibor snimka +HISTORY_MSG_64;Iseci fotografiju +HISTORY_MSG_65;Ispravljanje hr. aberacija +HISTORY_MSG_66;Čupanje svetla +HISTORY_MSG_67;Količina čupanja svetla +HISTORY_MSG_68;Način čupanja svetla +HISTORY_MSG_69;Radni prostor boja +HISTORY_MSG_70;Izlazni prostor boja +HISTORY_MSG_71;Ulazni profil boja +HISTORY_MSG_72;Ispravljanje vinjetarenja +HISTORY_MSG_73;Mešanje kanala +HISTORY_MSG_74;Promena veličine +HISTORY_MSG_75;Način promene veličine +HISTORY_MSG_76;Exif metapodaci +HISTORY_MSG_77;IPTC metapodaci +HISTORY_MSG_78;Podaci za promeni veličine +HISTORY_MSG_79;Širina pri promeni veličine +HISTORY_MSG_80;Visina pri promeni veličine +HISTORY_MSG_81;Uključena promena veličina +HISTORY_MSG_82;Profil je izmenjen +HISTORY_MSG_83;Kvalitetno svetlost/senke +HISTORY_MSG_84;Ispravljanje perspektive +HISTORY_MSG_85;Taloasni koeficijenti +HISTORY_MSG_86;Talasno ujednačenje +HISTORY_MSG_87;Uklanjanje šuma „biber i so“ +HISTORY_MSG_88;Prag uklanjanja šuma za „biber i so“ +HISTORY_MSG_89;Uklanjanje šuma +HISTORY_MSG_90;Šum — osvetljenost +HISTORY_MSG_91;Šum — boje +HISTORY_MSG_92;Šum — gama +HISTORY_MSG_93;Kontrast detanjnom vrednošću nivoa +HISTORY_MSG_94;Detanjni nivo kontrasta +HISTORY_MSG_95;Zasićenost +HISTORY_MSG_96;„a“ kriva +HISTORY_MSG_97;„b“ kriva +HISTORY_MSG_98;Rastavljam mozaik +HISTORY_MSG_99;Obrađujem +HISTORY_MSG_100;RGB zasićenost +HISTORY_MSG_101;HSV EQ — Nijansa +HISTORY_MSG_102;HSV EQ — Zasićenost +HISTORY_MSG_103;HSV EQ — Vrednsot +HISTORY_MSG_104;Ujednačenje HSV +HISTORY_MSG_105;Uklanjanje oreola +HISTORY_MSG_106;Poluprečnik +HISTORY_MSG_107;Prag +HISTORY_MSG_108;Prag kompenz. svetlog +HISTORY_MSG_109;Okvir za promenu veličine +HISTORY_MSG_110;Promena veličine primenjena na +HISTORY_MSG_111;Izbegni isecanje boja +HISTORY_MSG_112;Ograničavanje zasićenja +HISTORY_MSG_113;Graničnik zasićenja +HISTORY_MSG_114;DCB ponavljanja +HISTORY_MSG_115;Ponavljanje lažnih boja +HISTORY_MSG_116;Unapređeni DCB +HISTORY_MSG_117;Popravka crvene hrominanse +HISTORY_MSG_118;Popravka plave hrominanse +HISTORY_MSG_119;Linijsko uklaljanje šuma +HISTORY_MSG_120;Prag ujednačenja zelene +HISTORY_MSG_121;Sam ispravi aberacije +HISTORY_MSG_122;Sam primeni tamni kadar +HISTORY_MSG_123;Datoteka za tamni kadar +HISTORY_MSG_124;Linearna ispravka eksp. +HISTORY_MSG_125;Popravka eksp. uz očuvanje svetlog +HISTORY_MSG_126;Datoteka sa ravnim poljem +HISTORY_MSG_127;Sam izaberi ravno polje +HISTORY_MSG_128;Poluprečnik ravnog polja +HISTORY_MSG_129;Način zamućenja ravnog polja +HISTORY_MSG_130;Automatska distorzija +HISTORY_MSG_131;Uklanjanje šuma luminanse +HISTORY_MSG_132;Uklanjanje šuma boje +HISTORY_MSG_133;Gama +HISTORY_MSG_134;Gama pozicija +HISTORY_MSG_135;Gama sloboda +HISTORY_MSG_136;Gama nagib +HISTORY_MSG_137;Nivo crne zelena 1 +HISTORY_MSG_138;Nivo crne crvena +HISTORY_MSG_139;Nivo crne plava +HISTORY_MSG_140;Nivo crne zelena 2 +HISTORY_MSG_141;Nivo crne obe zelene +HISTORY_MSG_142;Oštrenje ivica - br. ponavljanja +HISTORY_MSG_143;Oštrenje ivica - količina +HISTORY_MSG_144;Mikrokontrast - količina +HISTORY_MSG_145;Mikrokontrast - ujednačenost +HISTORY_MSG_146;Oštrenje ivica +HISTORY_MSG_147;Oštrenje ivica - samo luminansa +HISTORY_MSG_148;Mikrokontrast +HISTORY_MSG_149;Mikrokontrast - 3x3 matrica +HISTORY_MSG_150;Uklanjanje artefakta/šuma nakon rasklapanja mozaika +HISTORY_NEWSNAPSHOT;Dodaj +HISTORY_SNAPSHOTS;Snimak +HISTORY_SNAPSHOT;Snimak +IPTCPANEL_AUTHORSPOSITIONHINT;Zvanje jednog ili više autora (jedno po redi). +IPTCPANEL_AUTHORSPOSITION;Zvanje autora +IPTCPANEL_AUTHOR;Autor +IPTCPANEL_CAPTIONHINT;Kratak opis dela (naslov — abstrakt). +IPTCPANEL_CAPTIONWRITERHINT;Ime osobe koje je uključena u pisanje, uređivanje ili ispravljanje slike/nazica/apstrakta (pisac — urednik). +IPTCPANEL_CAPTIONWRITER;Pisac naslova +IPTCPANEL_CAPTION;Naziv +IPTCPANEL_CATEGORYHINT;Određuje šta se nalazi na slici (kategorija). +IPTCPANEL_CATEGORY;Kategorija +IPTCPANEL_CITYHINT;Grad u kome je slika nastalo (grad). +IPTCPANEL_CITY;Grad +IPTCPANEL_COPYHINT;Koppiraj IPTC pšodešavanja u ostavu +IPTCPANEL_COPYRIGHTHINT;Beleška o autorskim pravima nad delom (beleška o autorskim pravima). +IPTCPANEL_COPYRIGHT;Autorska prava +IPTCPANEL_COUNTRYHINT;Ime države/osnovnog mesta gde je nastala slika (država — naziv mesta). +IPTCPANEL_COUNTRY;Država +IPTCPANEL_CREDITHINT;Ukazuje da onaj ko izdaje sliku ne mora biti autor/vlasnik (Zasluge). +IPTCPANEL_CREDIT;Zasluge +IPTCPANEL_DATECREATEDHINT;Datum kada je stavljeno vlasništvo nad intelektualni sadržaj slike; Format: GGGGMMDD (datum nastanka). +IPTCPANEL_DATECREATED;Datum nastanka +IPTCPANEL_EMBEDDEDHINT;Vrati polja na IPTC podatke ugnježđene u sliku +IPTCPANEL_EMBEDDED;Ugnježđeno +IPTCPANEL_HEADLINEHINT;Naziv koji ukazuje na vezu sa sadržajem slike i pod kojim se ona izdaje (naslov). +IPTCPANEL_HEADLINE;Naslov +IPTCPANEL_INSTRUCTIONSHINT;Ostala uputstva urednika vezana za upotrebu slike (specijalna uputstva). +IPTCPANEL_INSTRUCTIONS;Uputstva +IPTCPANEL_KEYWORDSHINT;Reči koje ukazuju na razne podatke o slici (ključne reči). +IPTCPANEL_KEYWORDS;Ključne reči +IPTCPANEL_PASTEHINT;Ubaci IPTC podešavanja iz ostave +IPTCPANEL_PROVINCEHINT;Pokrajina/država gde je nastala slika (provincija — država). +IPTCPANEL_PROVINCE;Pokrajina +IPTCPANEL_RESETHINT;Postavlja podrazumevane vrednosti profila +IPTCPANEL_RESET;Vrati +IPTCPANEL_SOURCEHINT;Prvobitni vlasnik inntelektualnog sadržaja na slici (izvor). +IPTCPANEL_SOURCE;Izvor +IPTCPANEL_SUPPCATEGORIESHINT;Dodatno određuje motiv na slici (dodatne kategorije). +IPTCPANEL_SUPPCATEGORIES;Dop. kategorije +IPTCPANEL_TITLEHINT;Kratni naziv slike (ime objekta). +IPTCPANEL_TITLE;Natpis +IPTCPANEL_TRANSREFERENCEHINT;Kod kojji predstavlja mesto prvobitnog prenosa (referenca prvog prenosa). +IPTCPANEL_TRANSREFERENCE;Ref. prenosa +MAIN_BUTTON_FULLSCREEN;Ceo ekran +MAIN_BUTTON_PREFERENCES;Postavke +MAIN_BUTTON_PUTTOQUEUE;Zakaži +MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Dodaje trenutnu sliku u zakazane Ctrl+B +MAIN_BUTTON_SAVE;Sačuvaj +MAIN_BUTTON_SAVE_TOOLTIP;Čuva trenutnu sliku Ctrl+S +MAIN_BUTTON_SENDTOEDITOR;Uredi +MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Uređuje trenutnu sliku u spoljnom programu Ctrl+E +MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Prikazuje/sakriva sve bočne površine m +MAIN_BUTTON_UNFULLSCREEN;Napusti ceo ekran +MAIN_FRAME_BATCHQUEUE;Zakazane datoteke +MAIN_FRAME_BATCHQUEUE_TOOLTIP; Zakazano Ctrl-F3 +MAIN_FRAME_EDITOR;Uređivač +MAIN_FRAME_EDITOR_TOOLTIP; Uređivač Ctrl-F4 +MAIN_FRAME_FILEBROWSER;Razgledač datoteka +MAIN_FRAME_FILEBROWSER_TOOLTIP; Razgledač datoteka Ctrl-F2 +MAIN_FRAME_PLACES;Mesta +MAIN_FRAME_PLACES_ADD;Dodaj +MAIN_FRAME_PLACES_DEL;Ukloni +MAIN_FRAME_RECENT;Recent Fascikle +MAIN_MSG_ALREADYEXISTS;Datoteka već postoji. +MAIN_MSG_CANNOTLOAD;Ne mogu da učitam sliku +MAIN_MSG_CANNOTSAVE;Greška pri čuvanju datoteke +MAIN_MSG_CANNOTSTARTEDITOR;Ne mogu da pokrenem program za uređivanje. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Izaberite ispravnu putanju u „Postavkama“. +MAIN_MSG_EMPTYFILENAME;Nije određeno ime datoteke! +MAIN_MSG_NAVIGATOR;Navigator +MAIN_MSG_QOVERWRITE;Da li želite da prepišete? +MAIN_TAB_COLOR;Boja +MAIN_TAB_COLOR_TOOLTIP;Alt-c +MAIN_TAB_DETAIL;Detalji +MAIN_TAB_DETAIL_TOOLTIP;Alt-d +MAIN_TAB_DEVELOP;Razvijanje +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;Svetlost +MAIN_TAB_EXPOSURE_TOOLTIP;Alt-e +MAIN_TAB_FILTER;Filter +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metapodaci +MAIN_TAB_METADATA_TOOLTIP;Alt-m +MAIN_TAB_RAW;RAW +MAIN_TAB_RAW_TOOLTIP;Alt-r +MAIN_TAB_TRANSFORM;Ispravke +MAIN_TAB_TRANSFORM_TOOLTIP;Alt-t +MAIN_TOOLTIP_HIDEHP;Prikazuje/sakriva levu površ, zajedno sa istorijatom (prečica: H) +MAIN_TOOLTIP_INDCLIPPEDH;Prikazuje isečene svetle delove +MAIN_TOOLTIP_INDCLIPPEDS;Prikazuje isečene tamne delove +MAIN_TOOLTIP_QINFO;Osnovni podaci o slici I +MAIN_TOOLTIP_SHOWHIDELP1;Prikazuje/sakriva levu površ l +MAIN_TOOLTIP_SHOWHIDERP1;Prikazuje/sakriva desnu površ Alt-l +MAIN_TOOLTIP_SHOWHIDETP1;Prikazuje/sakriva gornju površ Shift-L +MAIN_TOOLTIP_TOGGLE;Prikazuje sliku pre i posle obrade B +NAVIGATOR_XY_NA;x = ○, y = ○ +PARTIALPASTE_BASICGROUP;Osnovna podešavanja +PARTIALPASTE_CACORRECTION;Ispravljanje aberacija +PARTIALPASTE_CHANNELMIXER;Mešanje kanala +PARTIALPASTE_COARSETRANS;Rotacija za 90˚ / izvrtanje +PARTIALPASTE_COLORGROUP;Podešavanje boja +PARTIALPASTE_COMMONTRANSFORMPARAMS;Sam popuni +PARTIALPASTE_COMPOSITIONGROUP;Podešavanje kompozicije +PARTIALPASTE_CROP;Iseci +PARTIALPASTE_DARKFRAMEAUTOSELECT;Automatski izbor tamnog kadra +PARTIALPASTE_DARKFRAMEFILE;Datoteka za tamni kadar +PARTIALPASTE_DEFRINGE;Uklanjanje oreola +PARTIALPASTE_DETAILGROUP;Podešavanje detalja +PARTIALPASTE_DIALOGLABEL;Delimočno ubacuje profil za obradu +PARTIALPASTE_DIRPYRDENOISE;Uklanjanje šuma +PARTIALPASTE_DIRPYREQUALIZER;Kontrast nivoima detalja +PARTIALPASTE_DISTORTION;Ispravljanje izobličenja +PARTIALPASTE_EVERYTHING;Sve +PARTIALPASTE_EXIFCHANGES;Izmene exif podataka +PARTIALPASTE_EXPOSURE;Ekspozicija +PARTIALPASTE_FLATFIELDAUTOSELECT;Automatski izbor RK +PARTIALPASTE_FLATFIELDBLURRADIUS;Poluprečnik zamućenja RK +PARTIALPASTE_FLATFIELDBLURTYPE;Način zamućenja RK +PARTIALPASTE_FLATFIELDFILE;Datoteka za ravni kadar +PARTIALPASTE_HSVEQUALIZER;Ujednačenje HSV +PARTIALPASTE_ICMSETTINGS;ICM podešavanja +PARTIALPASTE_IMPULSEDENOISE;Impulsno uklanjanje šuma +PARTIALPASTE_IPTCINFO;IPTC podavi +PARTIALPASTE_LABCURVE;Lab kriva +PARTIALPASTE_LENSGROUP;Podešavanja objektiva +PARTIALPASTE_METAGROUP;Metapodaci +PARTIALPASTE_PERSPECTIVE;Perspektiva +PARTIALPASTE_PREPROCESS_GREENEQUIL;Ujednačavanje zelene +PARTIALPASTE_PREPROCESS_LINEDENOISE;Linijski filter šuma +PARTIALPASTE_RAWCACORR_AUTO;Auto hromatske aberacije +PARTIALPASTE_RAWCACORR_CABLUE;Plava hrominansa +PARTIALPASTE_RAWCACORR_CARED;Crvena hrominansa +PARTIALPASTE_RAWEXPOS_BLACK;Nivo crne +PARTIALPASTE_RAWEXPOS_LINEAR;Linearni faktor ispravke RAW bele tačke +PARTIALPASTE_RAWEXPOS_PRESER;Raw tačka bele uz očuvanje svetlih delova +PARTIALPASTE_RAWGROUP;Raw podešavanja +PARTIALPASTE_RAW_DCBENHANCE;Primeni korak DCB poboljšanja +PARTIALPASTE_RAW_DCBITERATIONS;Broj DCB ponavljanja +PARTIALPASTE_RAW_DMETHOD;Način rasklapanja mozaika +PARTIALPASTE_RAW_FALSECOLOR;Koraci prigušenja lažne boje pri rasklapanju mozaika +PARTIALPASTE_RESIZE;Promena veličine +PARTIALPASTE_ROTATION;Rotacija +PARTIALPASTE_SHADOWSHIGHLIGHTS;Senke/Svetlost +PARTIALPASTE_SHARPENEDGE;Ivice +PARTIALPASTE_SHARPENING;Oštrenje +PARTIALPASTE_SHARPENMICRO;Mikrokontrast +PARTIALPASTE_VIGNETTING;Ispravljanje vinjetarenja +PARTIALPASTE_WHITEBALANCE;Balans bele +PREFERENCES_ADD;Dodaj +PREFERENCES_APPLNEXTSTARTUP;primenjuje se nakon ponovnog pokretanja +PREFERENCES_AUTOMONPROFILE;Sam primeni profile monitora iz operativnog sistema +PREFERENCES_BATCH_PROCESSING;Obrada zakzanog +PREFERENCES_BEHAVIOR;Ponašanje +PREFERENCES_CACHECLEARALL;Obriši sve +PREFERENCES_CACHECLEARPROFILES;Obriši profile +PREFERENCES_CACHECLEARTHUMBS;Obriši prikaze +PREFERENCES_CACHEMAXENTRIES;Najveći broj mest u ostavi +PREFERENCES_CACHEOPTS;Podešavanje ostave +PREFERENCES_CACHETHUMBHEIGHT;Najveća visina prikaza +PREFERENCES_CLIPPINGIND;Pokazivači odsečenih delova +PREFERENCES_CMETRICINTENT;Kolorimetrijska namera +PREFERENCES_CUSTPROFBUILDHINT;Izvršna datoteka (ili skripta) koja se poziva kada izgrađujete novi početni profil za sliku.nPrihvata parametre iz komandne linije radi pravljenja .pp3 datoteke na osnovu nekih pravila:n[Putanja do RAW/JPG] [Putanja podrazumevanog profila] [Blenda] [Ekspozicija u s] [Žižna dužina mm] [ISO] [Objektiv] [Foto-aparat] +PREFERENCES_CUSTPROFBUILDPATH;Izvršna putanja +PREFERENCES_CUSTPROFBUILD;Izgradnja proizvoljnog početnog profila slike +PREFERENCES_CUTOVERLAYBRUSH;Maska isecanja boje/providnog +PREFERENCES_DARKFRAMEFOUND;Nađen +PREFERENCES_DARKFRAMESHOTS;snimaka +PREFERENCES_DARKFRAMETEMPLATES;šabloni +PREFERENCES_DARKFRAME;Tamni kadar +PREFERENCES_DATEFORMATHINT;Možete zadati sledeće formate:\n%y :godina\n%m : mesec\n%d : dan\n\nU Srbiji se najviše koristi:\n%d.%m.%y +PREFERENCES_DATEFORMAT;Format datuma +PREFERENCES_DEFAULTLANG;Jezik programa +PREFERENCES_DEFAULTTHEME;Tema programa +PREFERENCES_DIRDARKFRAMES;Direktorijum tamnog kadra +PREFERENCES_DIRHOME;Lični direktorijum +PREFERENCES_DIRLAST;Poslednji direktorijum +PREFERENCES_DIROTHER;Neki drugi +PREFERENCES_DIRSELECTDLG;Bira određeni direktorijum sa slikama... +PREFERENCES_DIRSOFTWARE;Direktorijum sa instalacijom +PREFERENCES_EDITORCMDLINE;Proizvoljna naredba +PREFERENCES_EDITORLAYOUT;Razmeštaj programa +PREFERENCES_EXTERNALEDITOR;Spoljni uređivač +PREFERENCES_FBROWSEROPTS;Opcije razgledača datoteke +PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Prikaži alatke u jednom redu +PREFERENCES_FILEFORMAT;Format datoteke +PREFERENCES_FLATFIELDFOUND;Nađeno +PREFERENCES_FLATFIELDSDIR;Direktorijum za ravna polja +PREFERENCES_FLATFIELDSHOTS;snimaka +PREFERENCES_FLATFIELDTEMPLATES;šabloni +PREFERENCES_FLATFIELD;Ravno polje +PREFERENCES_FORIMAGE;Za datoteke sa slikama +PREFERENCES_FORRAW;Za RAW datoteke +PREFERENCES_GIMPPATH;Direktorijum sa instaliranim Gimpom +PREFERENCES_HISTOGRAMPOSITIONLEFT;Histogram u levoj površi +PREFERENCES_HLTHRESHOLD;Prag za odsečene svetle delove +PREFERENCES_ICCDIR;ICC direktorijum +PREFERENCES_IMPROCPARAMS;Podrazumevani parametri za obradu slika +PREFERENCES_INTENT_ABSOLUTE;Apsolutno kolorimetrijski +PREFERENCES_INTENT_PERCEPTUAL;Perceptualno +PREFERENCES_INTENT_RELATIVE;Relativno kolorimetrijski +PREFERENCES_INTENT_SATURATION;Zasićeni prikaz +PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Koristi ugnježđeni RAW prikaz do izmene +PREFERENCES_LANGAUTODETECT;Sam otkrij +PREFERENCES_MENUGROUPFILEOPERATIONS;Grupiši radnje nad datotekama +PREFERENCES_MENUGROUPLABEL;Grupiši obeležavanje +PREFERENCES_MENUGROUPPROFILEOPERATIONS;Grupiši radnje sa profilima +PREFERENCES_MENUGROUPRANK;Grupiši ocenjivanje +PREFERENCES_MENUOPTIONS;Opcije menija +PREFERENCES_METADATA;Metapodaci +PREFERENCES_MONITORICC;Profil monitora +PREFERENCES_MULTITABDUALMON;Režim u više listova, na drugom monitoru +PREFERENCES_MULTITAB;Režim u više listova +PREFERENCES_OUTDIRFOLDERHINT;Stavlja sačuvane slike u +PREFERENCES_OUTDIRFOLDER;Sačuvaj u fasciklu +PREFERENCES_OUTDIRTEMPLATEHINT;Možete da zadate sledeće skraćenice za formatiranje:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nOvi znakovi za formatiranje se odnose na direktorijume, podputanje putanja do raw datoteke.\n\nNa primer, ukoliko je otvorena slika /home/ivan/slike/02.09.2010/dsc0012.nef, skraćenice označavaju:\n%f=dsc0012, %d1=02.09.2010, %d2=slike, ...\n%p1=/home/ivan/slike/02.09.2010, %p2=/home/ivan/slike, %p3=/home/ivan, ...\n\nUkoliko želite da sačuvate razvijenu sliku pored originala, unesite:\n%p1/%f\n\nUkoliko želite da sačuvate izlaznu sliku u direktorijum „razvijene“ koji se nalazi gde i originalna slika, unesite:\n%p1/razvijene/%f\n\nUkoliko želite da sačuvate razvijenu sliku u direktorijum „/home/ivan/razvijene“, a da struktura poddirektorijuma ostane očuvana, unesite:\n%p2/razvijene/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Upotrebi šablon +PREFERENCES_OUTDIR;Izlazni direktorijum +PREFERENCES_OVERLAY_FILENAMES;Postavi preko umanjenog prikaza +PREFERENCES_OVERWRITEOUTPUTFILE;Prepiši postojeće izlazne datoteke +PREFERENCES_PANFACTORLABEL;Faktor +PREFERENCES_PARSEDEXTADDHINT;Dodaje upisanu ekstenziju na spisak +PREFERENCES_PARSEDEXTADD;Dodaj ekstenziju +PREFERENCES_PARSEDEXTDELHINT;Briše izabranu ekstenziju iz spiska +PREFERENCES_PARSEDEXT;Ekstenzije za prikaz +PREFERENCES_PROFILEHANDLING;Rad sa profilima obrade +PREFERENCES_PROFILELOADPR;Prioritet učitavanja profila +PREFERENCES_PROFILEPRCACHE;Profil u ostavu +PREFERENCES_PROFILEPRFILE;Profil uz ulaznu datoteku +PREFERENCES_PROFILESAVECACHE;Sačuvaj parametre obrade u ostavu +PREFERENCES_PROFILESAVEINPUT;Sačuvaj paramtre obrade pored ulazne datoteke +PREFERENCES_PROPERTY;Osobina +PREFERENCES_PSPATH;Direktorijum sa instaliranim Adobe Fotošopom +PREFERENCES_SELECTFONT;Izaberite font +PREFERENCES_SELECTLANG;Jezik +PREFERENCES_SELECTTHEME;Tema +PREFERENCES_SET;Postavi +PREFERENCES_SHOWBASICEXIF;Prikaži osnovne Exif podatke +PREFERENCES_SHOWDATETIME;Prikaži datum i vreme +PREFERENCES_SHTHRESHOLD;Prag za odsečene tamne delove +PREFERENCES_SINGLETABVERTAB;Režim u jednom listu, vertikalni listovi +PREFERENCES_SINGLETAB;Režim u jednom listu +PREFERENCES_SLIMUI;Tanki izgled +PREFERENCES_SND_BATCHQUEUEDONE;Obrađene su zakazane datoteke +PREFERENCES_SND_HELP;Unesite putanju do datoteke ili ostavite prazno ukoliko ne želite zvuk. Na Windows-u možete da koristite „SystemDefault“, „SystemAsterisk“ za sistemske zvuke. +PREFERENCES_SND_LNGEDITPROCDONE;Urednik je završio obradu +PREFERENCES_SND_TRESHOLDSECS;br. sekundi +PREFERENCES_STARTUPIMDIR;Direktorijum po pokretanju +PREFERENCES_TAB_BROWSER;Pregled datoteka +PREFERENCES_TAB_COLORMGR;Upravljanje bojama +PREFERENCES_TAB_GENERAL;Opšte +PREFERENCES_TAB_IMPROC;Obrada slike +PREFERENCES_TAB_SOUND;Zvuci +PREFERENCES_TP_VSCROLLBAR;Sakrij klizače u oblasti sa alatkama +PREFERENCES_TUNNELMETADATA;Kopiraj neizmenjene IPTC/XMP (kada je slika označena drugim programom) +PREFERENCES_USESYSTEMTHEME; Koristi sistemsku temu +PREFERENCES_WORKFLOW;Tok obrade +PROFILEPANEL_LABEL;Profili obrade +PROFILEPANEL_LOADDLGLABEL;Učitaj profil za obradu... +PROFILEPANEL_PCUSTOM;Proizvoljno +PROFILEPANEL_PFILE;Iz datoteke +PROFILEPANEL_PLASTSAVED;Od poslednjeg čuvanja +PROFILEPANEL_SAVEDLGLABEL;Čuva parametre za obradu... +PROFILEPANEL_TOOLTIPCOPY;Kopira trenutni profil u ostavu +PROFILEPANEL_TOOLTIPLOAD;Učitava profil iz datoteke +PROFILEPANEL_TOOLTIPPASTE; Učitava profil iz +PROFILEPANEL_TOOLTIPSAVE;Čuva trenutni profil +PROGRESSBAR_LOADINGTHUMBS;Učitavam prikaze... +PROGRESSBAR_LOADING;Učitavam sliku... +PROGRESSBAR_LOADJPEG;Učitavam JPEG datoteku... +PROGRESSBAR_LOADPNG;Učitavam PNG datoteku... +PROGRESSBAR_LOADTIFF;Učitavam TIFF datoteku... +PROGRESSBAR_PROCESSING;Obrađujem sliku... +PROGRESSBAR_READY;Čekam +PROGRESSBAR_SAVEJPEG;Čuvam JPEG datoteku... +PROGRESSBAR_SAVEPNG;Čuvam PNG datoteku... +PROGRESSBAR_SAVETIFF;Čuvam TIFF datoteku... +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profil izmenjen u razgledaču +P_GAMMA_CURV;gama +QINFO_ISO;ISO +QINFO_NOEXIF;Nisu dostupni Exif podaci. +SAVEDLG_AUTOSUFFIX;Sam dodaj sufiks ukoliko datoteka već postoji +SAVEDLG_FILEFORMAT;Format datoteke +SAVEDLG_JPEGQUAL;JPEG kvalitet +SAVEDLG_PNGCOMPR;PNG pakovanje +SAVEDLG_PUTTOQUEUEHEAD;Premešta sliku na početak zakazanih +SAVEDLG_PUTTOQUEUETAIL;Premešta sliku na kraj zakazanih +SAVEDLG_PUTTOQUEUE;Zakazuje sliku za obradu +SAVEDLG_SAVEIMMEDIATELY;Odmah sačuvaj +SAVEDLG_SAVESPP;Sačuvaj parametre obrade uz sliku +SAVEDLG_TIFFUNCOMPRESSED;Nezapakovani TIFF +TOOLBAR_TOOLTIP_CROP;Postavlja okvir za isecanje (prečica: C) +TOOLBAR_TOOLTIP_HAND;Alat za pomeranje (prečica: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;Ispravlja liniju horizonta (prečica: S) +TOOLBAR_TOOLTIP_WB;Određuje balans bele iz tačke (prečica: W) +TP_CACORRECTION_BLUE;Plava +TP_CACORRECTION_LABEL;Hromatke aberacije +TP_CACORRECTION_RED;Crvena +TP_CHMIXER_BLUE;Plava +TP_CHMIXER_GREEN;Zelena +TP_CHMIXER_LABEL;Mešanje kanala +TP_CHMIXER_RED;Crvena +TP_CHROMATABERR_LABEL;Hromatske aberacije +TP_COARSETRAF_TOOLTIP_HFLIP;Izvrće sliku horizontalno +TP_COARSETRAF_TOOLTIP_ROTLEFT;Okreće sliku ulevo +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Okreće sliku udesno +TP_COARSETRAF_TOOLTIP_VFLIP;Izvrće sliku vertikalno +TP_CROP_FIXRATIO;Srazmerno: +TP_CROP_GTDIAGONALS;Pravilo dijagonala +TP_CROP_GTGRID;Mreža +TP_CROP_GTNONE;Ništa +TP_CROP_GTRULETHIRDS;Pravilo trećina +TP_CROP_GUIDETYPE;Vođice: +TP_CROP_H;V +TP_CROP_LABEL;Isecanje +TP_CROP_PPI;PPI= +TP_CROP_SELECTCROP; Izaberi oblast +TP_CROP_W;Š +TP_CROP_X;x +TP_CROP_Y;y +TP_DARKFRAME_AUTOSELECT;Sam izaberi +TP_DARKFRAME_LABEL;Tamni kadar +TP_DEFRINGE_LABEL;Uklaljanje oreola +TP_DEFRINGE_RADIUS;Poluprečnik +TP_DEFRINGE_THRESHOLD;Prag +TP_DIRPYRDENOISE_CHROMA;Boja +TP_DIRPYRDENOISE_GAMMA;Gama +TP_DIRPYRDENOISE_LABEL;Direkciono piramidno uklanjanje šuma +TP_DIRPYRDENOISE_LUMA;Luminansa +TP_DIRPYREQUALIZER_LABEL;Detaljni nivo kontrasta +TP_DIRPYREQUALIZER_LUMACOARSEST;grubo +TP_DIRPYREQUALIZER_LUMACONTRAST_MINUS;Kontrast- +TP_DIRPYREQUALIZER_LUMACONTRAST_PLUS;Kontrast+ +TP_DIRPYREQUALIZER_LUMAFINEST;fino +TP_DIRPYREQUALIZER_LUMANEUTRAL;Neutralno +TP_DIRPYREQUALIZER_THRESHOLD;Prag +TP_DISTORTION_AMOUNT;Količina +TP_DISTORTION_AUTO;Sam ispravi izobličenja +TP_DISTORTION_AUTO_TIP;(Eksperimentalno) Automatski ispravlja izobličenja nekih aparata (M4/3, neki kompakti, i dr.) +TP_DISTORTION_LABEL;Izobličenja +TP_EXPOSURE_AUTOLEVELS;Auto-nivoi +TP_EXPOSURE_BLACKLEVEL;Crna +TP_EXPOSURE_BRIGHTNESS;Osvetljenost +TP_EXPOSURE_CLIP;Odseci +TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Prag za čupanje svetlih delova +TP_EXPOSURE_COMPRHIGHLIGHTS;Sabijanje svetlog +TP_EXPOSURE_COMPRSHADOWS;Sabijanje senki +TP_EXPOSURE_CONTRAST;Kontrast +TP_EXPOSURE_CURVEEDITOR;Kriva nijansi +TP_EXPOSURE_EXPCOMP;Kompenzacija +TP_EXPOSURE_LABEL;Ekspozicija +TP_EXPOSURE_SATURATION;Zasićenost +TP_FLATFIELD_AUTOSELECT;Sam izaberi +TP_FLATFIELD_BLURRADIUS;Poluprečnik zamućenja +TP_FLATFIELD_BLURTYPE;Zamuti +TP_FLATFIELD_BT_AREA;Oblast +TP_FLATFIELD_BT_HORIZONTAL;Horizontalno +TP_FLATFIELD_BT_VERTHORIZ;Horiz. i vertik. +TP_FLATFIELD_BT_VERTICAL;Vertikalno +TP_FLATFIELD_LABEL;Ravno polje +TP_GAMMA_FREE;Gama sloboda +TP_GAMMA_OUTPUT;Izlazna gama +TP_GAMMA_SLOP;nagib (linearni) +TP_HLREC_BLEND;Utapanje +TP_HLREC_CIELAB;CieLab stapanje +TP_HLREC_COLOR;Propaginacija boje +TP_HLREC_LABEL;Čupanje svetlih delova +TP_HLREC_LUMINANCE;Izvlačenje luminanse +TP_HLREC_METHOD;Način: +TP_HSVEQUALIZER_CHANNEL;HSV kanal +TP_HSVEQUALIZER_HUE;Nijansa +TP_HSVEQUALIZER_LABEL;Ujednačenje HSV kanala +TP_HSVEQUALIZER_SAT;Zasićenost +TP_HSVEQUALIZER_VAL;Vrednost +TP_ICM_BLENDCMSMATRIX;Utopi svetle delove u matricu +TP_ICM_INPUTCAMERAICC;Foto-aparat ili standardni ICC +TP_ICM_INPUTCAMERA;Podrazumevano iz aparata +TP_ICM_INPUTCUSTOM;Proizvoljno +TP_ICM_INPUTDLGLABEL;Izaberite ulazni ICC profil... +TP_ICM_INPUTEMBEDDED;Ugnježđeno, ukoliko je moguće +TP_ICM_INPUTNONE;Nema profila +TP_ICM_INPUTPROFILE;Ulazni profil +TP_ICM_LABEL;ICM +TP_ICM_NOICM;No ICM: sRGB izlaz +TP_ICM_OUTPUTPROFILE;Izlazni profil +TP_ICM_SAVEREFERENCE;Sačuvaj sliku kao referencu za profil +TP_ICM_WORKINGPROFILE;Radni profil +TP_IMPULSEDENOISE_LABEL;Impulsno uklanjanje šuma +TP_IMPULSEDENOISE_THRESH;Prag +TP_LABCURVE_BRIGHTNESS;Osvetljenost +TP_LABCURVE_CONTRAST;Kontrast +TP_LABCURVE_CURVEEDITOR;Kriva svetlosti +TP_LABCURVE_LABEL;Lab kriva +TP_LENSGEOM_AUTOCROP;Sam iseci +TP_LENSGEOM_FILL;Sam popuni +TP_LENSGEOM_LABEL;Objektiv i geometrija +TP_PERSPECTIVE_HORIZONTAL;Horizontalna +TP_PERSPECTIVE_LABEL;Perspektiva +TP_PERSPECTIVE_VERTICAL;Vertikalna +TP_PREPROCESS_GREENEQUIL;Kalibracija zelene boje +TP_PREPROCESS_LABEL;Predobrada +TP_PREPROCESS_LINEDENOISE;Linijski filter šuma +TP_PREPROCESS_NO_FOUND;Nije pronađeno +TP_RAWCACORR_AUTO;Ispravi hromatske aberacije +TP_RAWCACORR_CABLUE;Plava +TP_RAWCACORR_CARED;Crvena +TP_RAWEXPOS_BLACKS;Nivo crne +TP_RAWEXPOS_LINEAR;Linearni faktor korekcije +TP_RAWEXPOS_PRESER;Očuvanje svetlih delova +TP_RAWEXPOS_TWOGREEN;Obe zelene +TP_RAW_DCBENHANCE;Primeni DCB poboljšanje +TP_RAW_DCBITERATIONS;Broj DCB prolaza +TP_RAW_DMETHOD;Način +TP_RAW_FALSECOLOR;Koraci za prigušivanje lažne boje +TP_RAW_LABEL;Rasklapanje mozaika +TP_RESIZE_APPLIESTO;Primeni na: +TP_RESIZE_CROPPEDAREA;Isečenu oblast +TP_RESIZE_FITBOX;Širinu i visinu +TP_RESIZE_FULLIMAGE;Celu sliku +TP_RESIZE_HEIGHT;Visinu +TP_RESIZE_H;V: +TP_RESIZE_LABEL;Veličina slike +TP_RESIZE_LANCZOS;Lanhoz +TP_RESIZE_METHOD;Način: +TP_RESIZE_NEAREST;Najbliže +TP_RESIZE_SCALE;Umanjenje +TP_RESIZE_SPECIFY;Izaberi: +TP_RESIZE_WIDTH;Širinu +TP_RESIZE_W;Š: +TP_ROTATE_DEGREE;Stepeni: +TP_ROTATE_LABEL;Rotacija +TP_ROTATE_SELECTLINE; Postavi pravu liniju +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Svetlo +TP_SHADOWSHLIGHTS_HLTONALW;Širina tonova +TP_SHADOWSHLIGHTS_LABEL;Senke/Svetlo +TP_SHADOWSHLIGHTS_LOCALCONTR;Lokalni kontrast +TP_SHADOWSHLIGHTS_RADIUS;Poluprečnik +TP_SHADOWSHLIGHTS_SHADOWS;Senke +TP_SHADOWSHLIGHTS_SHTONALW;Širina tonova +TP_SHARPENEDGE_AMOUNT;Količina +TP_SHARPENEDGE_LABEL;Ivice +TP_SHARPENEDGE_PASSES;Ponavljanja +TP_SHARPENEDGE_THREE;Samo luminansa +TP_SHARPENING_AMOUNT;Količina +TP_SHARPENING_EDRADIUS;Poluprečnik +TP_SHARPENING_EDTOLERANCE;Tolerancija ivice +TP_SHARPENING_HALOCONTROL;Ukloni oreol +TP_SHARPENING_HCAMOUNT;Količina +TP_SHARPENING_LABEL;Oštrenje +TP_SHARPENING_METHOD;Način +TP_SHARPENING_ONLYEDGES;Izoštri samo ivice +TP_SHARPENING_RADIUS;Poluprečnik +TP_SHARPENING_RLD;RL dekonvolucija +TP_SHARPENING_RLD_AMOUNT;Količina +TP_SHARPENING_RLD_DAMPING;Prigušivanje +TP_SHARPENING_RLD_ITERATIONS;Ponavljanja +TP_SHARPENING_THRESHOLD;Prag +TP_SHARPENING_USM;Oštrina maske +TP_SHARPENMICRO_AMOUNT;Količina +TP_SHARPENMICRO_LABEL;Mikrokonttrast +TP_SHARPENMICRO_MATRIX;3×3 matrica umesto 5×5 +TP_SHARPENMICRO_UNIFORMITY;Ujednačenost +TP_VIGNETTING_AMOUNT;Količina +TP_VIGNETTING_CENTER;Centar +TP_VIGNETTING_CENTER_X;Centar X +TP_VIGNETTING_CENTER_Y;Centar Y +TP_VIGNETTING_LABEL;Vinjetarenje +TP_VIGNETTING_RADIUS;Poluprečnik +TP_VIGNETTING_STRENGTH;Jačina +TP_WBALANCE_AUTO;Sam odredi +TP_WBALANCE_CAMERA;Iz aparata +TP_WBALANCE_CUSTOM;Proizvoljno +TP_WBALANCE_GREEN;Zelenilo +TP_WBALANCE_LABEL;Balans bele +TP_WBALANCE_METHOD;Način: +TP_WBALANCE_SIZE;Veličina: +TP_WBALANCE_SPOTWB;Iz tačke +TP_WBALANCE_TEMPERATURE;Temperatura +ZOOMPANEL_100;(100%) +ZOOMPANEL_NEWCROPWINDOW;Otvara novi prozor sa detaljima +ZOOMPANEL_ZOOM100;Povećava pregled na 100% z +ZOOMPANEL_ZOOMFITSCREEN;Uklapa sliku u veličinu prozora f +ZOOMPANEL_ZOOMIN;Uvećava prikaz slike + +ZOOMPANEL_ZOOMOUT;Umanjuje prikaz slike - + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!ABOUT_TAB_RELEASENOTES;Release Notes +!BATCHQUEUE_DESTFILENAME;Path and file name +!CURVEEDITOR_AXIS_IN;I: +!CURVEEDITOR_AXIS_LEFT_TAN;LT: +!CURVEEDITOR_AXIS_OUT;O: +!CURVEEDITOR_AXIS_RIGHT_TAN;RT: +!CURVEEDITOR_EDITPOINT_HINT;Enable edition of node in/out values.\n\nRight-click on a node to select it.\nRight-click on empty space to de-select the node. +!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) +!EXPORT_BYPASS_ALL;Select / Unselect All +!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_FF;Bypass [raw] Flat-Field +!EXPORT_BYPASS_RAW_GREENTHRESH;Bypass [raw] Green Equilibration +!EXPORT_BYPASS_RAW_LINENOISE;Bypass [raw] Line Noise Filter +!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_FASTEXPORTOPTIONS;Fast Export Options +!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_MAXHEIGHT;Maximum height: +!EXPORT_MAXWIDTH;Maximum width: +!EXPORT_PUTTOQUEUEFAST; Put to queue for fast export +!EXPORT_RAW_DMETHOD;Demosaic method +!EXTPROGTARGET_1;raw +!EXTPROGTARGET_2;queue-processed +!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_EXTPROGMENU;Open with +!FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) +!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_POPUPPROCESSFAST;Put to queue (Fast export) +!FILEBROWSER_POPUPRANK0;Unrank +!FILEBROWSER_POPUPRANK1;Rank 1 * +!FILEBROWSER_POPUPRANK2;Rank 2 ** +!FILEBROWSER_POPUPRANK3;Rank 3 *** +!FILEBROWSER_POPUPRANK4;Rank 4 **** +!FILEBROWSER_POPUPRANK5;Rank 5 ***** +!FILEBROWSER_POPUPRANK;Rank +!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_SHOWNOTTRASHHINT;Show only non-deleted images. +!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_ASIMAGE;As Image +!GENERAL_AUTO;Automatic +!GENERAL_CLOSE;Close +!GENERAL_WARNING;Warning +!HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram. +!HISTOGRAM_TOOLTIP_FULL;Toggle full (off) or scaled (on) histogram. +!HISTORY_MSG_151;Vibrance +!HISTORY_MSG_152;Vib - Pastel tones +!HISTORY_MSG_153;Vib - Saturated tones +!HISTORY_MSG_154;Vib - Protect skin-tones +!HISTORY_MSG_155;Vib - Avoid color shift +!HISTORY_MSG_156;Vib - Link pastel/saturated +!HISTORY_MSG_157;Vib - P/S threshold +!HISTORY_MSG_158;TM - Strength +!HISTORY_MSG_159;TM - Edge stopping +!HISTORY_MSG_160;TM - Scale +!HISTORY_MSG_161;TM - Reweighting iterates +!HISTORY_MSG_162;Tone Mapping +!HISTORY_MSG_163;RGB curves - Red +!HISTORY_MSG_164;RGB curves - Green +!HISTORY_MSG_165;RGB curves - Blue +!HISTORY_MSG_166;Neutral levels +!HISTORY_MSG_167;--unused-- +!HISTORY_MSG_168;L*a*b* - CC curve +!HISTORY_MSG_169;L*a*b* - CH curve +!HISTORY_MSG_170;Vibrance - HH curve +!HISTORY_MSG_171;L*a*b* - LC curve +!HISTORY_MSG_172;L*a*b* - Restrict LC +!HISTORY_MSG_173;NR - Luminance detail +!HISTORY_MSG_174;CIECAM02 +!HISTORY_MSG_175;CAM02 - CAT02 adaptation +!HISTORY_MSG_176;CAM02 - Viewing surround +!HISTORY_MSG_177;CAM02 - Scene luminosity +!HISTORY_MSG_178;CAM02 - Viewing luminosity +!HISTORY_MSG_179;CAM02 - White-point model +!HISTORY_MSG_180;CAM02 - Lightness (J) +!HISTORY_MSG_181;CAM02 - Chroma (C) +!HISTORY_MSG_182;CAM02 - Automatic CAT02 +!HISTORY_MSG_183;CAM02 - Contrast (J) +!HISTORY_MSG_184;CAM02 - Scene surround +!HISTORY_MSG_185;CAM02 - Gamut control +!HISTORY_MSG_186;CAM02 - Algorithm +!HISTORY_MSG_187;CAM02 - Red/skin prot. +!HISTORY_MSG_188;CAM02 - Brightness (Q) +!HISTORY_MSG_189;CAM02 - Contrast (Q) +!HISTORY_MSG_190;CAM02 - Saturation (S) +!HISTORY_MSG_191;CAM02 - Colorfulness (M) +!HISTORY_MSG_192;CAM02 - Hue (h) +!HISTORY_MSG_193;CAM02 - Tone curve 1 +!HISTORY_MSG_194;CAM02 - Tone curve 2 +!HISTORY_MSG_195;CAM02 - Tone curve 1 +!HISTORY_MSG_196;CAM02 - Tone curve 2 +!HISTORY_MSG_197;CAM02 - Color curve +!HISTORY_MSG_198;CAM02 - Color curve +!HISTORY_MSG_199;CAM02 - Output histograms +!HISTORY_MSG_200;CAM02 - Tone mapping +!HISTORY_MSG_201;NR - Chrominance - R&G +!HISTORY_MSG_202;NR - Chrominance - B&Y +!HISTORY_MSG_203;NR - Method +!HISTORY_MSG_204;LMMSE enhancement steps +!HISTORY_MSG_205;CAM02 - Hot/bad pixel filter +!HISTORY_MSG_206;CAT02 - Auto scene luminosity +!HISTORY_MSG_207;Defringe - Hue curve +!HISTORY_MSG_208;WB - B/R equalizer +!HISTORY_MSG_210;GF - Angle +!HISTORY_MSG_211;Graduated Filter +!HISTORY_MSG_212;VF - Strength +!HISTORY_MSG_213;Vignette Filter +!HISTORY_MSG_214;Black-and-White +!HISTORY_MSG_215;B&W - CM - Red +!HISTORY_MSG_216;B&W - CM - Green +!HISTORY_MSG_217;B&W - CM - Blue +!HISTORY_MSG_218;B&W - Gamma - Red +!HISTORY_MSG_219;B&W - Gamma - Green +!HISTORY_MSG_220;B&W - Gamma - Blue +!HISTORY_MSG_221;B&W - Color filter +!HISTORY_MSG_222;B&W - Presets +!HISTORY_MSG_223;B&W - CM - Orange +!HISTORY_MSG_224;B&W - CM - Yellow +!HISTORY_MSG_225;B&W - CM - Cyan +!HISTORY_MSG_226;B&W - CM - Magenta +!HISTORY_MSG_227;B&W - CM - Purple +!HISTORY_MSG_228;B&W - Luminance equalizer +!HISTORY_MSG_229;B&W - Luminance equalizer +!HISTORY_MSG_230;B&W - Mode +!HISTORY_MSG_231;B&W - 'Before' curve +!HISTORY_MSG_232;B&W - 'Before' curve type +!HISTORY_MSG_233;B&W - 'After' curve +!HISTORY_MSG_234;B&W - 'After' curve type +!HISTORY_MSG_235;B&W - Auto channel mixer +!HISTORY_MSG_236;--unused-- +!HISTORY_MSG_237;B&W - Mixer +!HISTORY_MSG_238;GF - Feather +!HISTORY_MSG_239;GF - Strength +!HISTORY_MSG_240;GF - Center +!HISTORY_MSG_241;VF - Feather +!HISTORY_MSG_242;VF - Roundness +!HISTORY_MSG_243;VC - Radius +!HISTORY_MSG_244;VC - Strength +!HISTORY_MSG_245;VC - Center +!HISTORY_MSG_246;L*a*b* - CL curve +!HISTORY_MSG_247;L*a*b* - LH curve +!HISTORY_MSG_248;L*a*b* - HH curve +!HISTORY_MSG_249;CbDL - Threshold +!HISTORY_MSG_250;NR - Enhanced +!HISTORY_MSG_251;B&W - Algorithm +!HISTORY_MSG_252;CbDL - Skin tar/prot +!HISTORY_MSG_253;CbDL - Reduce artifacts +!HISTORY_MSG_254;CbDL - Skin hue +!HISTORY_MSG_255;NR - Median filter +!HISTORY_MSG_256;NR - Median type +!HISTORY_MSG_257;Color Toning +!HISTORY_MSG_258;CT - Color curve +!HISTORY_MSG_259;CT - Opacity curve +!HISTORY_MSG_260;CT - a*[b*] opacity +!HISTORY_MSG_261;CT - Method +!HISTORY_MSG_262;CT - b* opacity +!HISTORY_MSG_263;CT - Shadows - Red +!HISTORY_MSG_264;CT - Shadows - Green +!HISTORY_MSG_265;CT - Shadows - Blue +!HISTORY_MSG_266;CT - Mid - Red +!HISTORY_MSG_267;CT - Mid - Green +!HISTORY_MSG_268;CT - Mid - Blue +!HISTORY_MSG_269;CT - High - Red +!HISTORY_MSG_270;CT - High - Green +!HISTORY_MSG_271;CT - High - Blue +!HISTORY_MSG_272;CT - Balance +!HISTORY_MSG_273;CT - Reset +!HISTORY_MSG_274;CT - Sat. Shadows +!HISTORY_MSG_275;CT - Sat. Highlights +!HISTORY_MSG_276;CT - Opacity +!HISTORY_MSG_277;--unused-- +!HISTORY_MSG_278;CT - Preserve luminance +!HISTORY_MSG_279;CT - Shadows +!HISTORY_MSG_280;CT - Highlights +!HISTORY_MSG_281;CT - Sat. strength +!HISTORY_MSG_282;CT - Sat. threshold +!HISTORY_MSG_283;CT - Strength +!HISTORY_MSG_284;CT - Auto sat. protection +!HISTORY_MSG_285;NR - Median - Method +!HISTORY_MSG_286;NR - Median - Type +!HISTORY_MSG_287;NR - Median - Iterations +!HISTORY_MSG_288;Flat Field - Clip control +!HISTORY_MSG_289;Flat Field - Clip control - Auto +!HISTORY_MSG_290;Black Level - Red +!HISTORY_MSG_291;Black Level - Green +!HISTORY_MSG_292;Black Level - Blue +!HISTORY_MSG_293;Film Simulation +!HISTORY_MSG_294;Film Simulation - Strength +!HISTORY_MSG_295;Film Simulation - Film +!HISTORY_MSG_296;NR - Luminance curve +!HISTORY_MSG_297;NR - Quality +!HISTORY_MSG_298;Dead pixel filter +!HISTORY_MSG_299;NR - Chrominance curve +!HISTORY_MSG_300;- +!HISTORY_MSG_301;NR - Luma control +!HISTORY_MSG_302;NR - Chroma method +!HISTORY_MSG_303;NR - Chroma method +!HISTORY_MSG_304;W - Contrast levels +!HISTORY_MSG_305;Wavelet Levels +!HISTORY_MSG_306;W - Preview +!HISTORY_MSG_307;W - Preview +!HISTORY_MSG_308;W - Preview direction +!HISTORY_MSG_309;W - ES - Detail +!HISTORY_MSG_310;W - Residual - Sky tar/prot +!HISTORY_MSG_311;W - Wavelet levels +!HISTORY_MSG_312;W - Residual - Shadows threshold +!HISTORY_MSG_313;W - Chroma - Sat/past +!HISTORY_MSG_314;W - Gamut - Reduce artifacts +!HISTORY_MSG_315;W - Residual - Contrast +!HISTORY_MSG_316;W - Gamut - Skin tar/prot +!HISTORY_MSG_317;W - Gamut - Skin hue +!HISTORY_MSG_318;W - Contrast - Highlight levels +!HISTORY_MSG_319;W - Contrast - Highlight range +!HISTORY_MSG_320;W - Contrast - Shadow range +!HISTORY_MSG_321;W - Contrast - Shadow levels +!HISTORY_MSG_322;W - Gamut - Avoid color shift +!HISTORY_MSG_323;W - ES - Local contrast +!HISTORY_MSG_324;W - Chroma - Pastel +!HISTORY_MSG_325;W - Chroma - Saturated +!HISTORY_MSG_326;W - Chroma - Method +!HISTORY_MSG_327;W - Contrast - Apply to +!HISTORY_MSG_328;W - Chroma - Link strength +!HISTORY_MSG_329;W - Toning - Opacity RG +!HISTORY_MSG_330;W - Toning - Opacity BY +!HISTORY_MSG_331;W - Contrast levels - Extra +!HISTORY_MSG_332;W - Tiling method +!HISTORY_MSG_333;W - Residual - Shadows +!HISTORY_MSG_334;W - Residual - Chroma +!HISTORY_MSG_335;W - Residual - Highlights +!HISTORY_MSG_336;W - Residual - Highlights threshold +!HISTORY_MSG_337;W - Residual - Sky hue +!HISTORY_MSG_338;W - ES - Radius +!HISTORY_MSG_339;W - ES - Strength +!HISTORY_MSG_340;W - Strength +!HISTORY_MSG_341;W - Edge performance +!HISTORY_MSG_342;W - ES - First level +!HISTORY_MSG_343;W - Chroma levels +!HISTORY_MSG_344;W - Meth chroma sl/cur +!HISTORY_MSG_345;W - ES - Local contrast +!HISTORY_MSG_346;W - ES - Local contrast method +!HISTORY_MSG_347;W - Denoise - Level 0 +!HISTORY_MSG_348;W - Denoise - Level 1 +!HISTORY_MSG_349;W - Denoise - Level 2 +!HISTORY_MSG_350;W - ES - Edge detection +!HISTORY_MSG_351;W - Residual - HH curve +!HISTORY_MSG_352;W - Background +!HISTORY_MSG_353;W - ES - Gradient sensitivity +!HISTORY_MSG_354;W - ES - Enhance +!HISTORY_MSG_355;W - ES - Threshold low +!HISTORY_MSG_356;W - ES - Threshold high +!HISTORY_MSG_357;W - Denoise - Link with ES +!HISTORY_MSG_358;W - Gamut - CH +!HISTORY_MSG_359;Hot/Dead - Threshold +!HISTORY_MSG_360;TM Gamma +!HISTORY_MSG_361;W - Final - Chroma balance +!HISTORY_MSG_362;W - Residual - Compression method +!HISTORY_MSG_363;W - Residual - Compression strength +!HISTORY_MSG_364;W - Final - Contrast balance +!HISTORY_MSG_365;W - Final - Delta balance +!HISTORY_MSG_366;W - Residual - Compression gamma +!HISTORY_MSG_367;W - ES - Local contrast curve +!HISTORY_MSG_368;W - Final - Contrast balance +!HISTORY_MSG_369;W - Final - Balance method +!HISTORY_MSG_370;W - Final - Local contrast curve +!HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s +!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). +!MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue-processed first. +!MAIN_MSG_OPERATIONCANCELLED;Operation cancelled +!MAIN_MSG_PATHDOESNTEXIST;The path\n\n%1\n\ndoes not exist. Please set a correct path in Preferences. +!MAIN_MSG_SETPATHFIRST;You first have to set a target path in Preferences in order to use this function! +!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_EXPORT; Fast Export +!MAIN_TAB_INSPECT; Inspect +!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_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%. +!MAIN_TOOLTIP_PREVIEWG;Preview the Green channel.\nShortcut: g +!MAIN_TOOLTIP_PREVIEWL;Preview the Luminosity.\nShortcut: v\n\n0.299*R + 0.587*G + 0.114*B +!MAIN_TOOLTIP_PREVIEWR;Preview the Red channel.\nShortcut: r +!MAIN_TOOLTIP_THRESHOLD;Threshold +!NAVIGATOR_B;B: +!NAVIGATOR_G;G: +!NAVIGATOR_H;H: +!NAVIGATOR_LAB_A;a*: +!NAVIGATOR_LAB_B;b*: +!NAVIGATOR_LAB_L;L*: +!NAVIGATOR_NA; -- +!NAVIGATOR_R;R: +!NAVIGATOR_S;S: +!NAVIGATOR_V;V: +!NAVIGATOR_XY_FULL;Width: %1, Height: %2 +!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_CHANNELMIXERBW;Black-and-White +!PARTIALPASTE_COLORAPP;CIECAM02 +!PARTIALPASTE_COLORTONING;Color Toning +!PARTIALPASTE_EPD;Tone mapping +!PARTIALPASTE_EQUALIZER;Wavelet Equalizer +!PARTIALPASTE_FILMSIMULATION;Film Simulation +!PARTIALPASTE_FLATFIELDCLIPCONTROL;Flat-field clip control +!PARTIALPASTE_GRADIENT;Graduated filter +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_PCVIGNETTE;Vignette filter +!PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter +!PARTIALPASTE_PREPROCESS_HOTPIXFILT;Hot pixel filter +!PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!PARTIALPASTE_RGBCURVES;RGB curves +!PARTIALPASTE_VIBRANCE;Vibrance +!PARTIALPASTE_WAVELETGROUP;Wavelet processing +!PREFERENCES_AUTLISLOW;Low +!PREFERENCES_AUTLISMAX;Max - Average of all tiles +!PREFERENCES_AUTLISSTD;High +!PREFERENCES_AUTLISVLOW;None +!PREFERENCES_AUTLOW;Low +!PREFERENCES_AUTSTD;Standard +!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_BEHADDALL;All to 'Add' +!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_BEHSETALL;All to 'Set' +!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_CURVEBBOXPOS;Position of curve copypasta buttons +!PREFERENCES_CURVEBBOXPOS_ABOVE;Above +!PREFERENCES_CURVEBBOXPOS_BELOW;Below +!PREFERENCES_CURVEBBOXPOS_LEFT;Left +!PREFERENCES_CURVEBBOXPOS_RIGHT;Right +!PREFERENCES_CUSTPROFBUILDKEYFORMAT;Keys format +!PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME;Name +!PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;TagID +!PREFERENCES_D50;5000K +!PREFERENCES_D55;5500K +!PREFERENCES_D60;6000K +!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_EXPAUT;Expert +!PREFERENCES_FILMSIMULATION;Film Simulation +!PREFERENCES_FLUOF2;Fluorescent F2 +!PREFERENCES_FLUOF7;Fluorescent F7 +!PREFERENCES_FLUOF11;Fluorescent F11 +!PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT;Same thumbnail height between the Editor's panel 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_GREY05;Yb=05 CIE L#30 +!PREFERENCES_GREY10;Yb=10 CIE L#40 +!PREFERENCES_GREY15;Yb=15 CIE L#45 +!PREFERENCES_GREY18;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_GREYSC18;Yb=18 CIE L#50 +!PREFERENCES_GREYSCA;Automatic +!PREFERENCES_GREYSC;Scene Yb luminance (%) +!PREFERENCES_GREY;Output device's Yb luminance (%) +!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_LEVAUTDN;Denoising level +!PREFERENCES_LEVDN;Cell size +!PREFERENCES_LISS;Auto multi-zone smoothing +!PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders +!PREFERENCES_MAX;Maxi (Tile) +!PREFERENCES_MED;Medium (Tile/2) +!PREFERENCES_MENUGROUPEXTPROGS;Group "Open with" +!PREFERENCES_MIN;Mini (100x115) +!PREFERENCES_NAVGUIDEBRUSH;Navigator guide color +!PREFERENCES_NAVIGATIONFRAME;Navigation +!PREFERENCES_NOISE;Noise Reduction +!PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Overlay filenames on thumbnails in the editor pannel +!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_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_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_SHOWEXPOSURECOMPENSATION;Append exposure compensation +!PREFERENCES_SHOWFILMSTRIPTOOLBAR;Show filmstrip toolbar +!PREFERENCES_SIMPLAUT;Tool mode +!PREFERENCES_SMA;Small (250x287) +!PREFERENCES_STDAUT;Standard +!PREFERENCES_TAB_PERFORMANCE;Performance & Quality +!PREFERENCES_TIMAX;High +!PREFERENCES_TINB;Number of tiles +!PREFERENCES_TISTD;Standard +!PREFERENCES_TP_LABEL;Tool panel: +!PREFERENCES_TP_USEICONORTEXT;Use tab icons instead of text +!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 +!PROFILEPANEL_COPYPPASTE;Parameters to copy +!PROFILEPANEL_GLOBALPROFILES;Bundled profiles +!PROFILEPANEL_LOADPPASTE;Parameters to load +!PROFILEPANEL_MODE_TIP;Processing profile fill mode.\n\nButton pressed: partial profiles will be converted to full profiles; the missing values will be replaced with hard-coded defaults.\n\nButton released: profiles will be applied as they are, altering only those values which they contain. +!PROFILEPANEL_MYPROFILES;My profiles +!PROFILEPANEL_PASTEPPASTE;Parameters to paste +!PROFILEPANEL_PINTERNAL;Neutral +!PROFILEPANEL_SAVEPPASTE;Parameters to save +!PROGRESSBAR_NOIMAGES;No images found +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing profile saved +!PROGRESSBAR_SNAPSHOT_ADDED;Snapshot added +!SAVEDLG_FORCEFORMATOPTS;Force saving options +!SAVEDLG_SUBSAMP;Subsampling +!SAVEDLG_SUBSAMP_1;Best compression +!SAVEDLG_SUBSAMP_2;Balanced +!SAVEDLG_SUBSAMP_3;Best quality +!SAVEDLG_SUBSAMP_TOOLTIP;Best compression: 4:1:1\nBalanced: 4:2:2\nBest quality: 4:4:4 +!SAVEDLG_WARNFILENAME;File will be named +!SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. +!THRESHOLDSELECTOR_BL;Bottom-left +!THRESHOLDSELECTOR_BR;Bottom-right +!THRESHOLDSELECTOR_B;Bottom +!THRESHOLDSELECTOR_HINT;Hold the Shift key to move individual control points. +!THRESHOLDSELECTOR_TL;Top-left +!THRESHOLDSELECTOR_TR;Top-right +!THRESHOLDSELECTOR_T;Top +!TP_BWMIX_ALGO;Algorithm OYCPM +!TP_BWMIX_ALGO_LI;Linear +!TP_BWMIX_ALGO_SP;Special effects +!TP_BWMIX_ALGO_TOOLTIP;Linear: will produce a normal linear response.\nSpecial effects: will produce special effects by mixing channels non-linearly. +!TP_BWMIX_AUTOCH;Auto +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing Channel Mixer. +!TP_BWMIX_CC_ENABLED;Adjust complementary color +!TP_BWMIX_CC_TOOLTIP;Enable to allow automatic adjustment of complementary colors in ROYGCBPM mode. +!TP_BWMIX_CHANNEL;Luminance equalizer +!TP_BWMIX_CURVEEDITOR1;'Before' curve +!TP_BWMIX_CURVEEDITOR2;'After' curve +!TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Tone curve, after B&W conversion, at the end of treatment. +!TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Tone curve, just before B&W conversion.\nMay take into account the color components. +!TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H).\nPay attention to extreme values as they may cause artifacts. +!TP_BWMIX_FILTER;Color Filter +!TP_BWMIX_FILTER_BLUEGREEN;Blue-Green +!TP_BWMIX_FILTER_BLUE;Blue +!TP_BWMIX_FILTER_GREENYELLOW;Green-Yellow +!TP_BWMIX_FILTER_GREEN;Green +!TP_BWMIX_FILTER_NONE;None +!TP_BWMIX_FILTER_PURPLE;Purple +!TP_BWMIX_FILTER_REDYELLOW;Red-Yellow +!TP_BWMIX_FILTER_RED;Red +!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. +!TP_BWMIX_FILTER_YELLOW;Yellow +!TP_BWMIX_GAMMA;Gamma Correction +!TP_BWMIX_GAM_TOOLTIP;Correct gamma for each RGB channel. +!TP_BWMIX_LABEL;Black-and-White +!TP_BWMIX_MET;Method +!TP_BWMIX_MET_CHANMIX;Channel Mixer +!TP_BWMIX_MET_DESAT;Desaturation +!TP_BWMIX_MET_LUMEQUAL;Luminance Equalizer +!TP_BWMIX_MIXC;Mixer +!TP_BWMIX_NEUTRAL;Reset mixer +!TP_BWMIX_NEUTRAL_TIP;Reset all values (Color Filter, Channel Mixer) to default. +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all the mixer options.\n"Total" displays the sum of the RGB values:\n- always 100% in relative mode\n- higher (lighter) or lower (darker) than 100% in absolute mode. +!TP_BWMIX_RGB_TOOLTIP;Mix the RGB channels. Use presets for guidance.\nPay attention to negative values that may cause artifacts or erratic behavior. +!TP_BWMIX_SETTING;Presets +!TP_BWMIX_SETTING_TOOLTIP;Different presets (film, landscape, etc.) or manual Channel Mixer settings. +!TP_BWMIX_SET_HIGHCONTAST;High contrast +!TP_BWMIX_SET_HIGHSENSIT;High Sensitivity +!TP_BWMIX_SET_HYPERPANCHRO;Hyper Panchromatic +!TP_BWMIX_SET_INFRARED;Infrared +!TP_BWMIX_SET_LANDSCAPE;Landscape +!TP_BWMIX_SET_LOWSENSIT;Low Sensitivity +!TP_BWMIX_SET_LUMINANCE;Luminance +!TP_BWMIX_SET_NORMCONTAST;Normal Contrast +!TP_BWMIX_SET_ORTHOCHRO;Orthochromatic +!TP_BWMIX_SET_PANCHRO;Panchromatic +!TP_BWMIX_SET_PORTRAIT;Portrait +!TP_BWMIX_SET_RGBABS;Absolute RGB +!TP_BWMIX_SET_RGBREL;Relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Relative ROYGCBPM +!TP_BWMIX_TCMODE_FILMLIKE;B&W Film-like +!TP_BWMIX_TCMODE_SATANDVALBLENDING;B&W Saturation and Value Blending +!TP_BWMIX_TCMODE_STANDARD;B&W Standard +!TP_BWMIX_TCMODE_WEIGHTEDSTD;B&W Weighted Standard +!TP_BWMIX_VAL;L +!TP_COLORAPP_ADAPTSCENE;Scene luminosity +!TP_COLORAPP_ADAPTSCENE_TOOLTIP;Absolute luminance of the scene environement (cd/m²).\n1) Calculated from the Exif data:\nShutter speed - ISO speed - F number - camera exposure correction.\n2) Calculated from the raw white point and RT's Exposure Compensation slider. +!TP_COLORAPP_ADAPTVIEWING;Viewing luminosity (cd/m²) +!TP_COLORAPP_ADAPTVIEWING_TOOLTIP;Absolute luminance of the viewing environnement\n(usually 16cd/m²). +!TP_COLORAPP_ADAP_AUTO_TOOLTIP;If the checkbox is checked (recommended) RawTherapee calculates an optimum value from Exif data.\nTo set the value manually, uncheck the checkbox first. +!TP_COLORAPP_ALGO;Algorithm +!TP_COLORAPP_ALGO_ALL;All +!TP_COLORAPP_ALGO_JC;Lightness + Chroma (JC) +!TP_COLORAPP_ALGO_JS;Lightness + Saturation (JS) +!TP_COLORAPP_ALGO_QM;Brightness + Colorfulness (QM) +!TP_COLORAPP_ALGO_TOOLTIP;Lets you choose between parameter subsets or all parameters. +!TP_COLORAPP_BADPIXSL;Hot/bad pixel filter +!TP_COLORAPP_BADPIXSL_TOOLTIP;Suppression of hot/bad (brightly colored) pixels.\n0 = No effect\n1 = Median\n2 = Gaussian.\nAlternatively, adjust the image to avoid very dark shadows.\n\nThese artifacts are due to limitations of CIECAM02. +!TP_COLORAPP_BRIGHT;Brightness (Q) +!TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from L*a*b* and RGB brightness. +!TP_COLORAPP_CHROMA;Chroma (C) +!TP_COLORAPP_CHROMA_M;Colorfulnes (M) +!TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM02 differs from L*a*b* and RGB colorfulness. +!TP_COLORAPP_CHROMA_S;Saturation (S) +!TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from L*a*b* and RGB saturation. +!TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from L*a*b* and RGB chroma. +!TP_COLORAPP_CIECAT_DEGREE;CAT02 adaptation +!TP_COLORAPP_CONTRAST;Contrast (J) +!TP_COLORAPP_CONTRAST_Q;Contrast (Q) +!TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrast in CIECAM02 for the Q slider; it differs from L*a*b* and RGB contrast. +!TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from L*a*b* and RGB contrast. +!TP_COLORAPP_CURVEEDITOR1;Tone curve 1 +!TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L* (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of J or Q after CIECAM02.\n\nJ and Q are not shown in the main histogram panel.\n\nFor final output refer to the main histogram panel. +!TP_COLORAPP_CURVEEDITOR2;Tone curve 2 +!TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Same usage as with the second exposure tone curve. +!TP_COLORAPP_CURVEEDITOR3;Color curve +!TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Adjust either chroma, saturation or colorfulness.\n\nShows the histogram of chromaticity (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of C, s or M after CIECAM02.\n\nC, s and M are not shown in the main histogram panel.\nFor final output refer to the main histogram panel. +!TP_COLORAPP_DATACIE;CIECAM02 output histograms in curves +!TP_COLORAPP_DATACIE_TOOLTIP;When enabled, histograms in CIECAM02 curves show approximate values/ranges for J or Q, and C, s or M after the CIECAM02 adjustments.\nThis selection does not impact the main histogram panel.\n\nWhen disabled, histograms in CIECAM02 curves show L*a*b* values before CIECAM02 adjustments. +!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RawTherapee calculates an optimum value, which is then used by CAT02, and also for the entire CIECAM02.\nTo set the value manually, uncheck the check-box first (values above 65 are recommended). +!TP_COLORAPP_DEGREE_TOOLTIP;Amount of CIE Chromatic Adaptation Transform 2002. +!TP_COLORAPP_GAMUT;Gamut control (L*a*b*) +!TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in L*a*b* mode. +!TP_COLORAPP_HUE;Hue (h) +!TP_COLORAPP_HUE_TOOLTIP;Hue (h) - angle between 0° and 360°. +!TP_COLORAPP_LABEL;CIE Color Appearance Model 2002 +!TP_COLORAPP_LABEL_CAM02;Image Adjustments +!TP_COLORAPP_LABEL_SCENE;Scene Conditions +!TP_COLORAPP_LABEL_VIEWING;Viewing Conditions +!TP_COLORAPP_LIGHT;Lightness (J) +!TP_COLORAPP_LIGHT_TOOLTIP;Lightness in CIECAM02 differs from L*a*b* and RGB lightness. +!TP_COLORAPP_MODEL;WP Model +!TP_COLORAPP_MODEL_TOOLTIP;White-Point Model.\n\nWB [RT] + [output]: RT's white balance is used for the scene, CIECAM02 is set to D50, and the output device's white balance is set in Preferences > Color Management.\n\nWB [RT+CAT02] + [output]: RT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences - Color Management. +!TP_COLORAPP_RSTPRO;Red & skin-tones protection +!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin-tones protection affects both sliders and curves. +!TP_COLORAPP_SHARPCIE;--unused-- +!TP_COLORAPP_SHARPCIE_TOOLTIP;--unused-- +!TP_COLORAPP_SURROUND;Surround +!TP_COLORAPP_SURROUND_AVER;Average +!TP_COLORAPP_SURROUND_DARK;Dark +!TP_COLORAPP_SURROUND_DIM;Dim +!TP_COLORAPP_SURROUND_EXDARK;Extremly Dark (Cutsheet) +!TP_COLORAPP_SURROUND_TOOLTIP;Changes tones and colors to take into account the viewing conditions of the output device.\n\nAverage: Average light environment (standard). The image will not change.\n\nDim: Dim environment (TV). The image will become slighty dark.\n\nDark: Dark environment (projector). The image will become more dark.\n\nExtremly Dark: Extremly dark environment (cutsheet). The image will become very dark. +!TP_COLORAPP_SURSOURCE;Dark surround +!TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if image has a dark border. +!TP_COLORAPP_TCMODE_BRIGHTNESS;Brightness +!TP_COLORAPP_TCMODE_CHROMA;Chroma +!TP_COLORAPP_TCMODE_COLORF;Colorfulness +!TP_COLORAPP_TCMODE_LABEL1;Curve mode 1 +!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_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] +!TP_COLORAPP_WBRT;WB [RT] + [output] +!TP_COLORTONING_AB;o C/L +!TP_COLORTONING_AUTOSAT;Automatic +!TP_COLORTONING_BALANCE;Balance +!TP_COLORTONING_BY;o C/L +!TP_COLORTONING_CHROMAC;Opacity +!TP_COLORTONING_COLOR;Color +!TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;Chroma opacity as a function of luminance oC=f(L) +!TP_COLORTONING_HIGHLIGHT;Highlights +!TP_COLORTONING_HUE;Hue +!TP_COLORTONING_LABEL;Color Toning +!TP_COLORTONING_LAB;L*a*b* blending +!TP_COLORTONING_LUMAMODE;Preserve luminance +!TP_COLORTONING_LUMAMODE_TOOLTIP;If enabled, when you change color (red, green, cyan, blue, etc.) the luminance of each pixel is preserved. +!TP_COLORTONING_LUMA;Luminance +!TP_COLORTONING_METHOD;Method +!TP_COLORTONING_METHOD_TOOLTIP;"L*a*b* blending", "RGB sliders" and "RGB curves" use interpolated color blending.\n"Color balance (Shadows/Midtones/Highlights)" and "Saturation 2 colors" use direct colors.\n\nThe Black-and-White tool can be enabled when using any color toning method, which allows for color toning. +!TP_COLORTONING_MIDTONES;Midtones +!TP_COLORTONING_NEUTRAL;Reset sliders +!TP_COLORTONING_NEUTRAL_TIP;Reset all values (Shadows, Midtones, Highlights) to default. +!TP_COLORTONING_OPACITY;Opacity +!TP_COLORTONING_RGBCURVES;RGB - Curves +!TP_COLORTONING_RGBSLIDERS;RGB - Sliders +!TP_COLORTONING_SATURATEDOPACITY;Strength +!TP_COLORTONING_SATURATIONTHRESHOLD;Threshold +!TP_COLORTONING_SA;Saturation Protection +!TP_COLORTONING_SHADOWS;Shadows +!TP_COLORTONING_SPLITCOCO;Color Balance Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITCO;Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITLR;Saturation 2 colors +!TP_COLORTONING_STRENGTH;Strength +!TP_COLORTONING_STR;Strength +!TP_COLORTONING_TWO2;Special chroma '2 colors' +!TP_COLORTONING_TWOALL;Special chroma +!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_GTFRAME;Frame +!TP_CROP_GTHARMMEANS;Harmonic Means +!TP_CROP_GTTRIANGLE1;Golden Triangles 1 +!TP_CROP_GTTRIANGLE2;Golden Triangles 2 +!TP_DIRPYRDENOISE_33;3×3 strong +!TP_DIRPYRDENOISE_55SOFT;5×5 +!TP_DIRPYRDENOISE_55;5×5 strong +!TP_DIRPYRDENOISE_77;7×7 (slow) +!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_ABM;Chroma only +!TP_DIRPYRDENOISE_AUTO;Automatic global +!TP_DIRPYRDENOISE_AUTO_TOOLTIP;Try to evaluate chroma noise\nBe careful, this calculation is average, and is quite subjective ! +!TP_DIRPYRDENOISE_AUT;Automatic global +!TP_DIRPYRDENOISE_BLUE;Chrominance - Blue-Yellow +!TP_DIRPYRDENOISE_C2TYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CCCURVE;Chrominance curve +!TP_DIRPYRDENOISE_CHROMAFR;Chrominance +!TP_DIRPYRDENOISE_CTYPE;Auto method +!TP_DIRPYRDENOISE_CTYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nAutomatic multi-zones\nNo preview - works only during saving, but using the "Preview" method by matching the tile size and center to the preview size and center you can get an idea of the expected results.\nThe image is divided into tiles (about 10 to 70 depending on image size) and each tile receives its own chrominance noise reduction settings.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CURVEEDITOR_CC;Chroma +!TP_DIRPYRDENOISE_CURVEEDITOR_CC_TOOLTIP;Increase (multiply) the value of all chrominance sliders.\nThis curve lets you adjust the strength of chromatic noise reduction as a function of chromaticity, for instance to increase the action in areas of low saturation and to decrease it in those of high saturation. +!TP_DIRPYRDENOISE_CURVEEDITOR_L_TOOLTIP;Modulates action of 'Luminance' denoise +!TP_DIRPYRDENOISE_CUR;Curve +!TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on the gamma of the input color profile. An sRGB gamma is assumed, thus if the image uses an input color profile of a different gamma, the effects of luminance noise reduction will differ. +!TP_DIRPYRDENOISE_ENH;Enhanced mode +!TP_DIRPYRDENOISE_ENH_TOOLTIP;Increases noise reduction quality at the expense of a 20% processing time increase. +!TP_DIRPYRDENOISE_GAMMA_TOOLTIP;Gamma varies noise reduction strength across the range of tones. Smaller values will target shadows, while larger values will stretch the effect to the brighter tones. +!TP_DIRPYRDENOISE_LABM;L*a*b* +!TP_DIRPYRDENOISE_LCURVE;Luminance curve +!TP_DIRPYRDENOISE_LDETAIL;Luminance - Detail +!TP_DIRPYRDENOISE_LM;Luminance only +!TP_DIRPYRDENOISE_LPLABM;Weighted L* (little) + a*b* (normal) +!TP_DIRPYRDENOISE_LTYPE;Luminance control +!TP_DIRPYRDENOISE_LUMAFR;Luminance +!TP_DIRPYRDENOISE_LUMAFR_TOOLTIP;Wavelet on luminance and Fourier transform for luminance detail +!TP_DIRPYRDENOISE_MANU;Manual +!TP_DIRPYRDENOISE_MAN;Manual +!TP_DIRPYRDENOISE_MEDMETHOD;Median method +!TP_DIRPYRDENOISE_MEDTYPE;Median type +!TP_DIRPYRDENOISE_MED;Median Filter +!TP_DIRPYRDENOISE_MED_TOOLTIP;Enabled median denoising +!TP_DIRPYRDENOISE_METHOD11;Quality +!TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. +!TP_DIRPYRDENOISE_METHOD;Method +!TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or L*a*b* methods can be used.\n\nFor non-raw images the L*a*b* method will be used, regardless of the selection. +!TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - +!TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 +!TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. +!TP_DIRPYRDENOISE_PASSES;Median iterations +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PON;Auto multi-zones +!TP_DIRPYRDENOISE_PREVLABEL;Preview size=%1, Center: Px=%2 Py=%3 +!TP_DIRPYRDENOISE_PREV;Preview +!TP_DIRPYRDENOISE_PRE;Preview multi-zones +!TP_DIRPYRDENOISE_RED;Chrominance - Red-Green +!TP_DIRPYRDENOISE_RGBM;RGB +!TP_DIRPYRDENOISE_RGB;RGB +!TP_DIRPYRDENOISE_SHALBI;High +!TP_DIRPYRDENOISE_SHAL;Standard +!TP_DIRPYRDENOISE_SLI;Slider +!TP_DIRPYRDENOISE_SOFT;3x3 +!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_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_EPD_EDGESTOPPING;Edge stopping +!TP_EPD_GAMMA;Gamma +!TP_EPD_LABEL;Tone Mapping +!TP_EPD_REWEIGHTINGITERATES;Reweighting iterates +!TP_EPD_SCALE;Scale +!TP_EPD_STRENGTH;Strength +!TP_EPD_TOOLTIP;Tone mapping is possible in L*a*b* mode (standard) and CIECAM02 mode.\n\nWhen in L*a*b* mode, tone mapping can also be used on the residual image of the Wavelet Levels tool.\n\nTo engage CIECAM02 tone mapping mode enable the following settings:\n1. CIECAM02\n2. Algorithm="Brightness + Colorfulness (QM)"\n3. "Tone mapping using CIECAM02 brightness (Q)" +!TP_EXPOSURE_AUTOLEVELS_TIP;Toggles execution of Auto Levels to automatically set Exposure slider values based on an image analysis.\nEnables Highlight Reconstruction if necessary. +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in Auto Levels operation. +!TP_EXPOSURE_CURVEEDITOR1;Tone curve 1 +!TP_EXPOSURE_CURVEEDITOR2;Tone curve 2 +!TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Please refer to the "Exposure > Tone Curves" RawPedia article to learn how to achieve the best results by using two tone curves. +!TP_EXPOSURE_TCMODE_FILMLIKE;Film-like +!TP_EXPOSURE_TCMODE_LABEL1;Curve mode 1 +!TP_EXPOSURE_TCMODE_LABEL2;Curve mode 2 +!TP_EXPOSURE_TCMODE_LUMINANCE;Luminance +!TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Saturation and Value Blending +!TP_EXPOSURE_TCMODE_STANDARD;Standard +!TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard +!TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points +!TP_EXPOS_WHITEPOINT_LABEL;Raw White Points +!TP_FILMSIMULATION_LABEL;Film Simulation +!TP_FILMSIMULATION_STRENGTH;Strength +!TP_FILMSIMULATION_ZEROCLUTSFOUND;Set HaldCLUT directory in Preferences +!TP_FLATFIELD_CLIPCONTROL;Clip control +!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. +!TP_GAMMA_CURV;Gamma +!TP_GENERAL_11SCALE_TOOLTIP;The effects of this tool are only visible or only accurate at a preview scale of 1:1. +!TP_GRADIENT_CENTER;Center +!TP_GRADIENT_CENTER_X;Center X +!TP_GRADIENT_CENTER_X_TOOLTIP;Shift gradient to the left (negative values) or right (positive values). +!TP_GRADIENT_CENTER_Y;Center Y +!TP_GRADIENT_CENTER_Y_TOOLTIP;Shift gradient up (negative values) or down (positive values). +!TP_GRADIENT_DEGREE;Angle +!TP_GRADIENT_DEGREE_TOOLTIP;Rotation angle in degrees. +!TP_GRADIENT_FEATHER;Feather +!TP_GRADIENT_FEATHER_TOOLTIP;Gradient width in percent of the image diagonal. +!TP_GRADIENT_LABEL;Graduated Filter +!TP_GRADIENT_STRENGTH;Strength +!TP_GRADIENT_STRENGTH_TOOLTIP;Filter strength in stops. +!TP_HLREC_ENA_TOOLTIP;Could be activated by Auto Levels. +!TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover clipped highlights when using LUT-based ICC profiles. +!TP_ICM_DCPILLUMINANT;Illuminant +!TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolated +!TP_ICM_DCPILLUMINANT_TOOLTIP;Select which embedded DCP illuminant to employ. Default is "interpolated" which is a mix between the two based on white balance. The setting is only enabled if a Dual-Illuminant DCP with interpolation support is selected. +!TP_ICM_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input color profiles. These profiles are more precise than simpler matrix ones. They are not available for all cameras. These profiles are stored in the /iccprofiles/input and /dcpprofiles folders and are automatically retrieved based on a file name matching to the exact model name of the camera. +!TP_ICM_INPUTCAMERA_TOOLTIP;Use a simple color matrix from dcraw, an enhanced RawTherapee version (whichever is available based on camera model) or one embedded in the DNG. +!TP_ICM_INPUTCUSTOM_TOOLTIP;Select your own DCP/ICC color profile file for the camera. +!TP_ICM_INPUTEMBEDDED_TOOLTIP;Use color profile embedded in non-raw files. +!TP_ICM_INPUTNONE_TOOLTIP;Use no input color profile at all.\nUse only in special cases. +!TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance +!TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. The result can be used for calibration purposes and generation of a camera profile. +!TP_ICM_TONECURVE;Use DCP's tone curve +!TP_ICM_TONECURVE_TOOLTIP;Employ the embedded DCP tone curve. The setting is only enabled if the selected DCP has a tone curve. +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid color shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction. +!TP_LABCURVE_CHROMATICITY;Chromaticity +!TP_LABCURVE_CHROMA_TOOLTIP;To apply B&W toning, set Chromaticity to -100. +!TP_LABCURVE_CURVEEDITOR_A_RANGE1;Green Saturated +!TP_LABCURVE_CURVEEDITOR_A_RANGE2;Green Pastel +!TP_LABCURVE_CURVEEDITOR_A_RANGE3;Red Pastel +!TP_LABCURVE_CURVEEDITOR_A_RANGE4;Red Saturated +!TP_LABCURVE_CURVEEDITOR_B_RANGE1;Blue Saturated +!TP_LABCURVE_CURVEEDITOR_B_RANGE2;Blue Pastel +!TP_LABCURVE_CURVEEDITOR_B_RANGE3;Yellow Pastel +!TP_LABCURVE_CURVEEDITOR_B_RANGE4;Yellow Saturated +!TP_LABCURVE_CURVEEDITOR_CC;CC +!TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutral +!TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Dull +!TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastel +!TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Saturated +!TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Chromaticity according to chromaticity C=f(C) +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to hue C=f(H) +!TP_LABCURVE_CURVEEDITOR_CL;CL +!TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Chromaticity according to luminance C=f(L) +!TP_LABCURVE_CURVEEDITOR_HH;HH +!TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Hue according to hue H=f(H) +!TP_LABCURVE_CURVEEDITOR_LC;LC +!TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminance according to chromaticity L=f(C) +!TP_LABCURVE_CURVEEDITOR_LH;LH +!TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H) +!TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminance according to luminance L=f(L) +!TP_LABCURVE_LCREDSK;Restrict LC to red and skin-tones +!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_USECA;Chromatic aberration correction +!TP_LENSPROFILE_USEDIST;Distortion correction +!TP_LENSPROFILE_USEVIGN;Vignetting correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Resets exposure sliders to neutral values.\nApplies to the same controls that Auto Levels applies to, regardless of whether you used Auto Levels or not. +!TP_PCVIGNETTE_FEATHER;Feather +!TP_PCVIGNETTE_FEATHER_TOOLTIP;Feathering:\n0 = corners only,\n50 = halfway to center,\n100 = to center. +!TP_PCVIGNETTE_LABEL;Vignette Filter +!TP_PCVIGNETTE_ROUNDNESS;Roundness +!TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness:\n0 = rectangle,\n50 = fitted ellipse,\n100 = circle. +!TP_PCVIGNETTE_STRENGTH;Strength +!TP_PCVIGNETTE_STRENGTH_TOOLTIP;Filter strength in stops (reached in corners). +!TP_PFCURVE_CURVEEDITOR_CH;Hue +!TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Controls defringe strength by color.\nHigher = more,\nLower = less. +!TP_PREPROCESS_DEADPIXFILT;Dead pixel filter +!TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Tries to suppress dead pixels. +!TP_PREPROCESS_HOTPIXFILT;Hot pixel filter +!TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Tries to suppress hot pixels. +!TP_RAWEXPOS_BLACK_0;Green 1 (lead) +!TP_RAWEXPOS_BLACK_1;Red +!TP_RAWEXPOS_BLACK_2;Blue +!TP_RAWEXPOS_BLACK_3;Green 2 +!TP_RAWEXPOS_BLACK_BLUE;Blue +!TP_RAWEXPOS_BLACK_GREEN;Green +!TP_RAWEXPOS_BLACK_RED;Red +!TP_RAWEXPOS_RGB;Red, Green, Blue +!TP_RAW_DMETHOD_PROGRESSBAR;%1 demosaicing... +!TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Demosaicing refinement... +!TP_RAW_DMETHOD_TOOLTIP;Note: IGV and LMMSE are dedicated to high ISO images to aid in noise reduction without leading to maze patterns, posterization or a washed-out look. +!TP_RAW_HD;Threshold +!TP_RAW_HD_TOOLTIP;Lower values make hot/dead pixel detection more aggressive, but false positives may lead to artifacts. If you notice any artifacts appearing when enabling the Hot/Dead Pixel Filters, gradually increase the threshold value until they disappear. +!TP_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!TP_RAW_LMMSE_TOOLTIP;Adds gamma (step 1), median (steps 2-4) and refinement (steps 5-6) to reduce artifacts and improve the signal-to-noise ratio. +!TP_RAW_SENSOR_BAYER_LABEL;Sensor with Bayer Matrix +!TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;3-pass gives best results (recommended for low ISO images).\n1-pass is almost undistinguishable from 3-pass for high ISO images and is faster. +!TP_RAW_SENSOR_XTRANS_LABEL;Sensor with X-Trans Matrix +!TP_RGBCURVES_BLUE;B +!TP_RGBCURVES_CHANNEL;Channel +!TP_RGBCURVES_GREEN;G +!TP_RGBCURVES_LABEL;RGB Curves +!TP_RGBCURVES_LUMAMODE;Luminosity mode +!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_RGBCURVES_RED;R +!TP_SAVEDIALOG_OK_TIP;Shortcut: Ctrl-Enter +!TP_SHADOWSHLIGHTS_SHARPMASK;Sharp mask +!TP_SHARPENING_TOOLTIP;Expect a slightly different effect when using with CIECAM02. If difference is observed, adjust to taste. +!TP_VIBRANCE_AVOIDCOLORSHIFT;Avoid color shift +!TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Red/Purple +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Red +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Red/Yellow +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Yellow +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Hue according to hue H=f(H) +!TP_VIBRANCE_LABEL;Vibrance +!TP_VIBRANCE_PASTELS;Pastel Tones +!TP_VIBRANCE_PASTSATTOG;Link pastel and saturated tones +!TP_VIBRANCE_PROTECTSKINS;Protect skin-tones +!TP_VIBRANCE_PSTHRESHOLD;Pastel/saturated tones threshold +!TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Saturation threshold +!TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;The vertical axis represents pastel tones at the bottom and saturated tones at the top.\nThe horizontal axis represents the saturation range. +!TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Pastel/saturated transition's weighting +!TP_VIBRANCE_SATURATED;Saturated Tones +!TP_WAVELET_1;Level 1 +!TP_WAVELET_2;Level 2 +!TP_WAVELET_3;Level 3 +!TP_WAVELET_4;Level 4 +!TP_WAVELET_5;Level 5 +!TP_WAVELET_6;Level 6 +!TP_WAVELET_7;Level 7 +!TP_WAVELET_8;Level 8 +!TP_WAVELET_9;Level 9 +!TP_WAVELET_ALL;All levels in all directions +!TP_WAVELET_APPLYTO;Apply To +!TP_WAVELET_AVOID;Avoid color shift +!TP_WAVELET_B0;Black +!TP_WAVELET_B1;Grey +!TP_WAVELET_B2;Residual +!TP_WAVELET_BACUR;Curve +!TP_WAVELET_BALANCE;Contrast balance d/v-h +!TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chromaticity or residual tone mapping are activated, the effect due to balance is amplified. +!TP_WAVELET_BALCHRO;Chroma balance +!TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chromaticity balance. +!TP_WAVELET_BANONE;None +!TP_WAVELET_BASLI;Slider +!TP_WAVELET_BATYPE;Contrast balance method +!TP_WAVELET_CCURVE;Local contrast +!TP_WAVELET_CH1;Whole chromaticity range +!TP_WAVELET_CH2;Saturated/pastel +!TP_WAVELET_CH3;Link contrast levels +!TP_WAVELET_CHCU;Curve +!TP_WAVELET_CHRO;Saturated/pastel threshold +!TP_WAVELET_CHRO_TOOLTIP;Sets the wavelet level which will be the threshold between saturated and pastel colors.\n1-x: saturated\nx-9: pastel\n\nIf the value exceeds the amount of wavelet levels you are using then it will be ignored. +!TP_WAVELET_CHR;Chroma-contrast link strength +!TP_WAVELET_CHR_TOOLTIP;Adjusts chromaticity as a function of "contrast levels" and "chroma-contrast link strength" +!TP_WAVELET_CHSL;Sliders +!TP_WAVELET_CHTYPE;Chrominance method +!TP_WAVELET_COLORT;Opacity Red-Green +!TP_WAVELET_COMBOTH;Both +!TP_WAVELET_COMPCONT;Contrast +!TP_WAVELET_COMPGAMMA;Compression gamma +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjusting the gamma of the residual image allow you to equilibrate the data and histogram. +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjust gamma for residual image and compression.\nAllow to equilibrate data and histogram +!TP_WAVELET_COMPTM;Tone mapping +!TP_WAVELET_CONTEDIT;'After' Contrast curve +!TP_WAVELET_CONTEDIT;'After' contrast curve +!TP_WAVELET_CONTRAST_MINUS;Contrast - +!TP_WAVELET_CONTRAST_PLUS;Contrast + +!TP_WAVELET_CONTRA;Contrast +!TP_WAVELET_CONTRA_TOOLTIP;Changes contrast of the residual image. +!TP_WAVELET_CONTR;Gamut +!TP_WAVELET_CTYPE;Chrominance control +!TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modifies local contrast as a function of the original local contrast (absciss)\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 100..300)\n66% absciss represents standard deviation of local contrast (real value about 300..800)\n100% represents maximum (real value about 3000..8000) +!TP_WAVELET_CURVEEDITOR_CH;Contrast levels=f(Hue) +!TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modifies each level's contrast as a function oh hue.\nTake care not to overwrite changes made with the Gamut Hue controls.\nThe curve will only have an effect when wavelet contrast level sliders are non-zero. +!TP_WAVELET_CURVEEDITOR_CL;L +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Applies a final contrast luminance curve at the end of the wavelet treatment. +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Apply a contrast luminance curve at the end of wavelet level threatment +!TP_WAVELET_CURVEEDITOR_HH;HH +!TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modifies the residual image's hue as a function of hue. +!TP_WAVELET_DALL;All directions +!TP_WAVELET_DAUB;Edge performance +!TP_WAVELET_DAUB_TOOLTIP;Changes Daubechies coefficients:\nD4 = Standard,\nD14 = Often best performance, 10% more time-intensive.\n\nAffects edge detection as well as the general quality of the firsts levels. However the quality is not strictly related to this coefficient and can vary with images and uses. +!TP_WAVELET_DISP;Preview Settings +!TP_WAVELET_DONE;Vertical +!TP_WAVELET_DTHR;Diagonal +!TP_WAVELET_DTWO;Horizontal +!TP_WAVELET_EDCU;Curve +!TP_WAVELET_EDGCONT;Local contrast +!TP_WAVELET_EDGCONT_TOOLTIP;Adjusting the points to the left decreases contrast, and to the right increases it.\nBottom-left, Top-Left, Top-Right, Bottom-right represent respectively local contast for low values, mean, mean+stdev, maxima +!TP_WAVELET_EDGEDETECTTHR2;Threshold high (detection) +!TP_WAVELET_EDGEDETECTTHR;Threshold low (noise) +!TP_WAVELET_EDGEDETECTTHR_TOOLTIP;This adjuster lets you target edge detection for example to avoid applying edge sharpness to fine details, such as noise in the sky. +!TP_WAVELET_EDGEDETECT;Gradient sensitivity +!TP_WAVELET_EDGEDETECT_TOOLTIP;Moving the slider to the right increases edge sensitivity. This affects local contrast, edge settings and noise. +!TP_WAVELET_EDGE;Edge Sharpness +!TP_WAVELET_EDGREINF_TOOLTIP;Reinforce or reduce the action of the first level, do the opposite to the second level, and leave the rest unchanged. +!TP_WAVELET_EDGTHRESH;Detail +!TP_WAVELET_EDGTHRESH_TOOLTIP;Change the repartition between the first levels and the others. The higher the threshold the more the action is centred on the first levels. Be careful with negative values, they increase the action of high levels and can introduce artifacts. +!TP_WAVELET_EDRAD;Radius +!TP_WAVELET_EDRAD_TOOLTIP;This radius adjustment is very different from those in other sharpening tools. Its value is compared to each level through a complex function. In this sense, a value of zero still has an effect. +!TP_WAVELET_EDSL;Threshold Sliders +!TP_WAVELET_EDTYPE;Local contrast method +!TP_WAVELET_EDVAL;Strength +!TP_WAVELET_FINAL;Final Touchup +!TP_WAVELET_FINEST;Finest +!TP_WAVELET_HIGHLIGHT;Highlight luminance range +!TP_WAVELET_HS1;Whole luminance range +!TP_WAVELET_HS2;Shadows/Highlights +!TP_WAVELET_HUESKIN;Skin hue +!TP_WAVELET_HUESKIN_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_HUESKY;Sky hue +!TP_WAVELET_HUESKY_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_INF;Below or equal the level +!TP_WAVELET_ITER;Delta balance levels +!TP_WAVELET_ITER_TOOLTIP;Left: increase low levels and reduce high levels,\nRight: reduce low levels and increase high levels. +!TP_WAVELET_LABEL;Wavelet levels +!TP_WAVELET_LARGEST;Coarsest +!TP_WAVELET_LEVCH;Chromaticity +!TP_WAVELET_LEVELS;Wavelet levels +!TP_WAVELET_LEVELS_TOOLTIP;Choose the number of detail levels the image is to be decomposed into. More levels require more RAM and require a longer processing time. +!TP_WAVELET_LEVF;Contrast +!TP_WAVELET_LEVLABEL;Preview maximum possible levels = %1 +!TP_WAVELET_LEVONE;Level 2 +!TP_WAVELET_LEVTWO;Level 3 +!TP_WAVELET_LEVZERO;Level 1 +!TP_WAVELET_LINKEDG;Link with Edge Sharpness' Strength +!TP_WAVELET_LIPST;Enhanced algorithm +!TP_WAVELET_LIPST_TOOLTIP;This algorithm uses Lipschitz regularity to increase edge detection quality at a cost of increased processing time and memory requirements. +!TP_WAVELET_LOWLIGHT;Shadow luminance range +!TP_WAVELET_MEDGREINF;First level +!TP_WAVELET_MEDILEV;Edge detection +!TP_WAVELET_MEDI;Reduce artifacts in blue sky +!TP_WAVELET_NEUTRAL;Neutral +!TP_WAVELET_NOISE;Denoise and Refine +!TP_WAVELET_NOIS;Denoise +!TP_WAVELET_ONE;One level +!TP_WAVELET_OPACITYWL;Final local contrast +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify final local contrast in function of last local contrast (absciss) for all levels decomposition\nTake into account: \na)contrast levels \nb)edge sharpness \nc)contrast balance\nd)decomposition-recomposition\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 200..1000)\n66% absciss represents standard deviation of local contrast (real value about 1000..2000)\n100% represents maximum (real value about 5000..13000) +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify the final local contrast at the end of the wavelet treatment.\n\nThe left side represents the smallest local contrast, progressing to the largest local contrast on the right. +!TP_WAVELET_OPACITYW;Contrast balance d/v-h curve +!TP_WAVELET_OPACITY;Opacity Blue-Yellow +!TP_WAVELET_PASTEL;Pastel chromaticity +!TP_WAVELET_PREVIEWBACK;Background +!TP_WAVELET_PREVIEWLEVELS;Preview +!TP_WAVELET_RE1;Reinforced +!TP_WAVELET_RE2;Unchanged +!TP_WAVELET_RE3;Reduced +!TP_WAVELET_RESCHRO;Chromaticity +!TP_WAVELET_RESCONH;Highlights +!TP_WAVELET_RESCON;Shadows +!TP_WAVELET_RESID;Residual image +!TP_WAVELET_SAT;Saturated chromaticity +!TP_WAVELET_SETTINGS;Wavelet Settings +!TP_WAVELET_SKIN;Skin targetting/protection +!TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected. +!TP_WAVELET_SKY;Sky targetting/protection +!TP_WAVELET_SKY_TOOLTIP;At -100 sky-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 sky-tones are protected while all other tones are affected. +!TP_WAVELET_STRENGTH;Strength +!TP_WAVELET_STREN;Strength +!TP_WAVELET_SUPE;Extra +!TP_WAVELET_SUP;Above the level +!TP_WAVELET_THRESHOLD2;Shadow levels +!TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels between 9 and 9 minus the value will be affected by the shadow luminance range. Other levels will be fully treated. The highest level possible is limited by the highlight level value (9 minus highlight level value). +!TP_WAVELET_THRESHOLD;Highlight levels +!TP_WAVELET_THRESHOLD_TOOLTIP;Only levels beyond the chosen value will be affected by the highlight luminance range. Other levels will be fully treated. The chosen value here limits the highest possible value of the shadow levels. +!TP_WAVELET_THRH;Highlights threshold +!TP_WAVELET_THR;Shadows threshold +!TP_WAVELET_TILESBIG;Big tiles +!TP_WAVELET_TILESFULL;Full image +!TP_WAVELET_TILESIZE;Tiling method +!TP_WAVELET_TILESLIT;Little tiles +!TP_WAVELET_TILES_TOOLTIP;Processing the full image leads to better quality and is the recommended option, while using tiles is a fall-back solution for users with little RAM. Refer to RawPedia for memory requirements. +!TP_WAVELET_TMHIGH;High +!TP_WAVELET_TMLOWHIGH;Low+High +!TP_WAVELET_TMNONE;None +!TP_WAVELET_TMSTD;Standard +!TP_WAVELET_TMSTRENGTH;Compression strength +!TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image. When the value is different from 0, the Strength and Gamma sliders of the Tone Mapping tool in the Exposure tab will become grayed out. +!TP_WAVELET_TMTYPE;Compression method +!TP_WAVELET_TON;Toning +!TP_WAVELET_daub2;D2 - low +!TP_WAVELET_daub4;D4 - standard +!TP_WAVELET_daub6;D6 - standard plus +!TP_WAVELET_daub10;D10 - medium +!TP_WAVELET_daub14;D14 - high +!TP_WBALANCE_CLOUDY;Cloudy +!TP_WBALANCE_DAYLIGHT;Daylight (sunny) +!TP_WBALANCE_EQBLUERED;Blue/Red equalizer +!TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behavior of "white balance" by modulating the blue/red balance.\nThis can be useful when shooting conditions:\na) are far from the standard illuminant (e.g. underwater),\nb) are far from conditions where calibrations were performed,\nc) where the matrices or ICC profiles are unsuitable. +!TP_WBALANCE_FLASH55;Leica +!TP_WBALANCE_FLASH60;Standard, Canon, Pentax, Olympus +!TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta +!TP_WBALANCE_FLASH_HEADER;Flash +!TP_WBALANCE_FLUO1;F1 - Daylight +!TP_WBALANCE_FLUO2;F2 - Cool White +!TP_WBALANCE_FLUO3;F3 - White +!TP_WBALANCE_FLUO4;F4 - Warm White +!TP_WBALANCE_FLUO5;F5 - Daylight +!TP_WBALANCE_FLUO6;F6 - Lite White +!TP_WBALANCE_FLUO7;F7 - D65 Daylight Simulator +!TP_WBALANCE_FLUO8;F8 - D50 / Sylvania F40 Design +!TP_WBALANCE_FLUO9;F9 - Cool White Deluxe +!TP_WBALANCE_FLUO10;F10 - Philips TL85 +!TP_WBALANCE_FLUO11;F11 - Philips TL84 +!TP_WBALANCE_FLUO12;F12 - Philips TL83 +!TP_WBALANCE_FLUO_HEADER;Fluorescent +!TP_WBALANCE_GTI;GTI +!TP_WBALANCE_HMI;HMI +!TP_WBALANCE_JUDGEIII;JudgeIII +!TP_WBALANCE_LAMP_HEADER;Lamp +!TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 +!TP_WBALANCE_LED_HEADER;LED +!TP_WBALANCE_LED_LSI;LSI Lumelex 2040 +!TP_WBALANCE_SHADE;Shade +!TP_WBALANCE_SOLUX35;Solux 3500K +!TP_WBALANCE_SOLUX41;Solux 4100K +!TP_WBALANCE_SOLUX47;Solux 4700K (vendor) +!TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) +!TP_WBALANCE_TUNGSTEN;Tungsten +!TP_WBALANCE_WATER1;UnderWater 1 +!TP_WBALANCE_WATER2;UnderWater 2 +!TP_WBALANCE_WATER_HEADER;UnderWater +!ZOOMPANEL_ZOOMFITCROPSCREEN;Fit crop to screen\nShortcut: Alt-f diff --git a/rtdata/languages/Slovak b/rtdata/languages/Slovak new file mode 100644 index 000000000..e21d38bd1 --- /dev/null +++ b/rtdata/languages/Slovak @@ -0,0 +1,1858 @@ +#01 2008-05-08 +#02 2009-02-01 +#03 2010-10-23 slapo + +ADJUSTER_RESET_TO_DEFAULT;Resetovať na predvolené nastavenia +BATCHQUEUE_AUTOSTART;Auto štart +BATCH_PROCESSING;Dávkové spracovanie +CURVEEDITOR_CUSTOM;Vlastné +CURVEEDITOR_DARKS;Tiene +CURVEEDITOR_HIGHLIGHTS;Najvyššie svetlá +CURVEEDITOR_LIGHTS;Svetlá +CURVEEDITOR_LINEAR;Lineárna +CURVEEDITOR_LOADDLGLABEL;Načítať krivku... +CURVEEDITOR_NURBS;Kontrolná klietka +CURVEEDITOR_PARAMETRIC;Parametricky +CURVEEDITOR_SAVEDLGLABEL;Uložiť krivku... +CURVEEDITOR_SHADOWS;Hlboké tiene +CURVEEDITOR_TOOLTIPLINEAR;Resetovať krivku na lineárnu +CURVEEDITOR_TOOLTIPLOAD;Načítať krivku zo súboru +CURVEEDITOR_TOOLTIPSAVE;Uložiť súčasnú krivku +CURVEEDITOR_TYPE;Typ: +DIRBROWSER_FOLDERS;Priečinky +EXIFFILTER_APERTURE;Clona +EXIFFILTER_CAMERA;Fotoaparát +EXIFFILTER_FOCALLEN;Ohnisková vzdialenosť +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Objektív +EXIFFILTER_METADATAFILTER;Povoliť filtre meta údajov +EXIFFILTER_SHUTTER;Uzávierka +EXIFPANEL_ADDEDITHINT;Pridať novú značku alebo upraviť značku +EXIFPANEL_ADDEDIT;Pridať/Upraviť +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Vložiť hodnotu +EXIFPANEL_ADDTAGDLG_SELECTTAG;Vybrať značku +EXIFPANEL_ADDTAGDLG_TITLE;Pridať/Upraviť značku +EXIFPANEL_KEEPHINT;Ponechať vybrané značky pri písaní výstupného súboru +EXIFPANEL_KEEP;Ponechať +EXIFPANEL_REMOVEHINT;Odstrániť vybrané značky pri písaní výstupného súboru +EXIFPANEL_REMOVE;Odstrániť +EXIFPANEL_RESETALLHINT;Resetovať všetky značky na ich pôvodné hodnoty +EXIFPANEL_RESETALL;Resetovať všetky +EXIFPANEL_RESETHINT;Resetovať vybrané značky na ich pôvodné hodnoty +EXIFPANEL_RESET;Resetovať +EXIFPANEL_SUBDIRECTORY;Podadresár +FILEBROWSER_ADDDELTEMPLATE;Pridať/Odstrániť šablóny... +FILEBROWSER_APPLYPROFILE;Použiť profil +FILEBROWSER_CLEARPROFILE;Vyčistiť profil +FILEBROWSER_COPYPROFILE;Kopírovať profil +FILEBROWSER_CURRENT_NAME;Súčasný názov: +FILEBROWSER_DELETEDLGLABEL;Potvrdenie odstránenia súboru +FILEBROWSER_DELETEDLGMSG;Ste si istí, že chcete odstrániť vybrané %1 súbory? +FILEBROWSER_EMPTYTRASHHINT;Permanentne odstrániť súbory z koša +FILEBROWSER_EMPTYTRASH;Vyprázdniť kôš +FILEBROWSER_NEW_NAME;Nový názov: +FILEBROWSER_PARTIALPASTEPROFILE;Čiastočné vloženie +FILEBROWSER_PASTEPROFILE;Vložiť profil +FILEBROWSER_POPUPCANCELJOB;Zrušiť úlohu +FILEBROWSER_POPUPMOVEEND;Presunúť na koniec radu +FILEBROWSER_POPUPMOVEHEAD;Presunúť na začiatok radu +FILEBROWSER_POPUPOPENINEDITOR;Otvoriť v editore +FILEBROWSER_POPUPOPEN;Otvoriť +FILEBROWSER_POPUPPROCESS;Vložiť do radu na spracovanie +FILEBROWSER_POPUPREMOVE;Odstrániť zo systému súborov +FILEBROWSER_POPUPRENAME;Premenovať +FILEBROWSER_POPUPSELECTALL;Vybrať všetko +FILEBROWSER_POPUPTRASH;Presunúť do koša +FILEBROWSER_POPUPUNRANK;Zrušiť triedu +FILEBROWSER_POPUPUNTRASH;Odstrániť z koša +FILEBROWSER_RENAMEDLGLABEL;Premenovať súbor +FILEBROWSER_RENAMEDLGMSG;Premenovať súbor "%1" na: +FILEBROWSER_SHOWDIRHINT;Ukázať všetky obrázky v adresári +FILEBROWSER_SHOWEXIFINFO;Ukázať EXIF info i +FILEBROWSER_SHOWRANK1HINT;Ukázať obrázky triedy 1 hviezda +FILEBROWSER_SHOWRANK2HINT;Ukázať obrázky triedy 2 hviezda +FILEBROWSER_SHOWRANK3HINT;Ukázať obrázky triedy 3 hviezda +FILEBROWSER_SHOWRANK4HINT;Ukázať obrázky triedy 4 hviezda +FILEBROWSER_SHOWRANK5HINT;Ukázať obrázky triedy 5 hviezda +FILEBROWSER_SHOWTRASHHINT;Zobraziť obsah koša +FILEBROWSER_SHOWUNRANKHINT;Zobraziť obrázky bez triedy +FILEBROWSER_STARTPROCESSINGHINT;Začať spracovanie/ukladanie obrázkov v rade +FILEBROWSER_STARTPROCESSING;Začať spracovanie +FILEBROWSER_STOPPROCESSINGHINT;Zastaviť spracovanie obrázkov +FILEBROWSER_STOPPROCESSING;Zastaviť spracovanie +FILEBROWSER_THUMBSIZE;Veľkosť zmenšenín +FILEBROWSER_TOOLTIP_STOPPROCESSING;Začať spracovanie automaticky, keď príde nová úloha +FILEBROWSER_ZOOMINHINT;Zväčšiť veľkosť zmenšenín +FILEBROWSER_ZOOMOUTHINT;Zmenšiť veľkosť zmenšenín +GENERAL_ABOUT;O programe +GENERAL_AFTER;Potom +GENERAL_BEFORE;Predtým +GENERAL_CANCEL;Zrušiť +GENERAL_DISABLED;Zakázané +GENERAL_DISABLE;Zakázať +GENERAL_ENABLED;Povolené +GENERAL_ENABLE;Povoliť +GENERAL_LANDSCAPE;Krajina +GENERAL_NA;n/a +GENERAL_NO;Nie +GENERAL_OK;OK +GENERAL_PORTRAIT;Portrét +GENERAL_SAVE;Uložiť +GENERAL_UNCHANGED;(Nezmenené) +HISTOGRAM_TOOLTIP_B;Zobraziť/Schovať MODRÝ histogram +HISTOGRAM_TOOLTIP_G;Zobraziť/Schovať ZELENÝ histogram +HISTOGRAM_TOOLTIP_L;Zobraziť/Schovať histogram CIELAB svietivosti +HISTOGRAM_TOOLTIP_R;Zobraziť/Schovať ČERVENÝ histogram +HISTORY_CHANGED;Zmenené +HISTORY_CUSTOMCURVE;Vlastná krivka +HISTORY_DELSNAPSHOT;Odstrániť Snímok +HISTORY_FROMCLIPBOARD;Zo schránky +HISTORY_LABEL;História +HISTORY_MSG_1;Fotka načítaná +HISTORY_MSG_2;Profil načítaný +HISTORY_MSG_3;Profil zmenený +HISTORY_MSG_4;História prehliadania +HISTORY_MSG_5;Jas +HISTORY_MSG_6;Kontrast +HISTORY_MSG_7;Čierna +HISTORY_MSG_8;Kompenzácia expozície +HISTORY_MSG_9;Kompresia najvyšších svetiel +HISTORY_MSG_10;Kompresia tieňov +HISTORY_MSG_11;Krivka tónov +HISTORY_MSG_12;Auto expozícia +HISTORY_MSG_13;Orezávanie expozície +HISTORY_MSG_14;Jas svietivosti +HISTORY_MSG_15;Kontrast svietivosti +HISTORY_MSG_16;Čierna svietivosti +HISTORY_MSG_17;Kompresia najvyšších svetiel v oblasti svietivosti +HISTORY_MSG_18;Kompresia tieňov v oblasti svietivosti +HISTORY_MSG_19;Krivka svietivosti +HISTORY_MSG_20;Doostrenie +HISTORY_MSG_21;Polomer doostrenia +HISTORY_MSG_22;Množstvo doostrenia +HISTORY_MSG_23;Prah doostrenia +HISTORY_MSG_24;Doostriť len okraje +HISTORY_MSG_25;Polomer detekcie okrajov pri doostrení +HISTORY_MSG_26;Tolerancia okrajov pri doostrení +HISTORY_MSG_27;Kontrola svätožiary pri doostrení +HISTORY_MSG_28;Množstvo kontroly svätožiary +HISTORY_MSG_29;Doostrovacia metóda +HISTORY_MSG_30;Polomer dekonvolúcie +HISTORY_MSG_31;Množstvo dekonvolúcie +HISTORY_MSG_32;Tlmenie dekonvolúcie +HISTORY_MSG_33;Iterácie dekonvolúcie +HISTORY_MSG_34;Vyhnúť sa orezaniu farieb +HISTORY_MSG_35;Obmedzovač sýtosti +HISTORY_MSG_36;Hranica sýtosti +HISTORY_MSG_37;Zosilnenie farieb +HISTORY_MSG_38;Metóda vyváženia bielej +HISTORY_MSG_39;Farebná teplota +HISTORY_MSG_40;Nádych vyváženia bielej +HISTORY_MSG_41;Farebný posun "A" +HISTORY_MSG_42;Farebný posun "B" +HISTORY_MSG_43;Odšumenie svietivosti +HISTORY_MSG_44;Polomer odšumenia svietivosti +HISTORY_MSG_45;Tolerancia okrajov odšumenia svietivosti +HISTORY_MSG_46;Farebné odšumenie +HISTORY_MSG_47;Polomer farebného odšumenia +HISTORY_MSG_48;Tolerancia okrajov farebného odšumenia +HISTORY_MSG_49;Citlivosť na okraje pri farebnom odšumení +HISTORY_MSG_50;Nástroj Tiene/Najvyššie svetlá +HISTORY_MSG_51;Zosilnenie najvyšších svetiel +HISTORY_MSG_52;Zosilnenie tieňov +HISTORY_MSG_53;Tonálna šírka najvyšších svetiel +HISTORY_MSG_54;Tonálna šírka tieňov +HISTORY_MSG_55;Miestny kontrast +HISTORY_MSG_56;Polomer Tiene/Najvyššie svetlá +HISTORY_MSG_57;Hrubé otočenie +HISTORY_MSG_58;Horizontálne preklápanie +HISTORY_MSG_59;Vertikálne preklápanie +HISTORY_MSG_60;Otočenie +HISTORY_MSG_61;Otočenie +HISTORY_MSG_62;Korekcia zakrivenia objektívu +HISTORY_MSG_63;Záložka vybraná +HISTORY_MSG_64;Orezanie fotky +HISTORY_MSG_65;Korekcia chromatickej aberácie +HISTORY_MSG_66;Obnova najvyšších svetiel +HISTORY_MSG_67;Množstvo obnovy najvyšších svetiel +HISTORY_MSG_68;Metóda obnovy najvyšších svetiel +HISTORY_MSG_69;Pracovný farebný priestor +HISTORY_MSG_70;Výstupný farebný priestor +HISTORY_MSG_71;Vstupný farebný priestor +HISTORY_MSG_72;Korekcia vignetácie +HISTORY_MSG_73;Mixér kanálov +HISTORY_MSG_74;Zmeniť veľkosť - Rozmer +HISTORY_MSG_75;Zmeniť veľkosť - Metóda +HISTORY_MSG_76;Exif Metadáta +HISTORY_MSG_77;IPTC Metadáta +HISTORY_MSG_78;Zadané údaje pre zmenu veľkosti +HISTORY_MSG_79;Zmena veľkosti podľa šírky +HISTORY_MSG_80;Zmena veľkosti podľa výšky +HISTORY_MSG_81;Zmena veľkosti povolená +HISTORY_MSG_82;Profil zmenený +HISTORY_MSG_83;Tiene/najvyšie svetlá vyskokej kvality +HISTORY_MSG_84;Náprava perspektívy +HISTORY_MSG_85;Koeficienty vlnky +HISTORY_MSG_86;Vyrovnávač vlnky +HISTORY_MSG_87;Impulzná redukcia šumu +HISTORY_MSG_89;Smerová pyramída +HISTORY_MSG_90;Svietivosť smerovej pyramídy +HISTORY_MSG_91;Farebnosť smerovej pyramídy +HISTORY_MSG_92;Gamma smerovej pyramídy +HISTORY_NEWSNAPSHOT;Nový Snímok +HISTORY_SNAPSHOTS;Snímky +HISTORY_SNAPSHOT;Snímok +IPTCPANEL_AUTHORSPOSITIONHINT;Titul tvorcu alebo tvorcov objektu (Titul pri mene autora). +IPTCPANEL_AUTHORSPOSITION;Autorov titul +IPTCPANEL_AUTHOR;Autor +IPTCPANEL_CAPTIONHINT;Textový opis údajov (Titul - Abstrakt). +IPTCPANEL_CAPTIONWRITERHINT;Meno osoby, ktorá titul/abstrakt obrazu napísala, upravila alebo opravila (Pisateľ - Editor). +IPTCPANEL_CAPTIONWRITER;Pisateľ titulu +IPTCPANEL_CAPTION;Titul +IPTCPANEL_CATEGORYHINT;Identifikuje subjekt obrázka podľa názoru poskytovateľa (Kategória). +IPTCPANEL_CATEGORY;Kategória +IPTCPANEL_CITYHINT;Mesto pôvodu (Mesto). +IPTCPANEL_CITY;Mesto +IPTCPANEL_COPYHINT;Kopírovať IPTC nastavenia do schránky +IPTCPANEL_COPYRIGHTHINT;Akýkoľvek potrebný oznam o copyrighte (Oznam o copyrighte). +IPTCPANEL_COPYRIGHT;Copyright +IPTCPANEL_COUNTRYHINT;Názov krajiny/miesta pôvodu (Krajina - miesto pôvodu). +IPTCPANEL_COUNTRY;Krajina +IPTCPANEL_CREDITHINT;Identifikuje poskytovateľa obrázka, nemusí byť nevyhnutne vlastníkom/tvorcom (Kredit). +IPTCPANEL_CREDIT;Kredit +IPTCPANEL_DATECREATEDHINT;Dátum, kedy bol vytvorený intelektuálny obsah obrázka; Formát: RRRRMMDD (Deň vytvorenia). +IPTCPANEL_DATECREATED;Dátum vytvorenia +IPTCPANEL_EMBEDDEDHINT;Resetovať na IPTV údaje vložené do obrázka +IPTCPANEL_EMBEDDED;Vložené +IPTCPANEL_HEADLINEHINT;Publikovateľný vstup poskytujúci zhrnutie obsahu obrázka (Nadpis). +IPTCPANEL_HEADLINE;Nadpis +IPTCPANEL_INSTRUCTIONSHINT;Iné pokyny ohľadne použitia obrázka (Špeciálne pokyny). +IPTCPANEL_INSTRUCTIONS;Pokyny +IPTCPANEL_KEYWORDSHINT;Používa sa na indikáciu kľúčových slov. +IPTCPANEL_KEYWORDS;Kľúčové slová +IPTCPANEL_PASTEHINT;Prilepiť IPTC nastavenia zo schránky +IPTCPANEL_PROVINCEHINT;Provincia/štát pôvodu obrázka (Provincia-štát). +IPTCPANEL_PROVINCE;Provincia/štát +IPTCPANEL_RESETHINT;Resetovať na predvolené profilom +IPTCPANEL_RESET;Resetovať +IPTCPANEL_SOURCEHINT;Pôvodný vlastník intektuálneho obsahu obrázka (Zdroj). +IPTCPANEL_SOURCE;Zdroj +IPTCPANEL_SUPPCATEGORIESHINT;Ďalej upresňuje subjekt obrázka (Dodatočné kategórie). +IPTCPANEL_SUPPCATEGORIES;Dodatočné kategórie +IPTCPANEL_TITLEHINT;Krátka referencia pre obrázok (Meno objektu). +IPTCPANEL_TITLE;Názov +IPTCPANEL_TRANSREFERENCEHINT;Kód reprezentujúci miesto pôvodného prenosu (Pôvodná referencia prenosu). +IPTCPANEL_TRANSREFERENCE;Referencia prenosu +MAIN_BUTTON_FULLSCREEN;Celá obrazovka +MAIN_BUTTON_PREFERENCES;Predvoľby +MAIN_BUTTON_PUTTOQUEUE;Vložiť do radu +MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Pridať súčasný obrázok do radu na spracovanie Ctrl+B +MAIN_BUTTON_SAVE;Uložiť obrázok +MAIN_BUTTON_SAVE_TOOLTIP;Uložiť súčasný obrázok Ctrl+S +MAIN_BUTTON_SENDTOEDITOR;Odoslať do editora +MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Upraviť súčasný obrázok v externom editore Ctrl+E +MAIN_BUTTON_UNFULLSCREEN;Ukončiť zobrazenie na celú obrazovku +MAIN_FRAME_BATCHQUEUE;Dávkový rad +MAIN_FRAME_FILEBROWSER;Prehliadač súborov +MAIN_FRAME_PLACES;Miesta +MAIN_FRAME_PLACES_ADD;Pridať +MAIN_FRAME_PLACES_DEL;Odstrániť +MAIN_FRAME_RECENT;Nedávne priečinky +MAIN_MSG_ALREADYEXISTS;Súbor už existuje. +MAIN_MSG_CANNOTLOAD;Nemôžem načítať obrázok +MAIN_MSG_CANNOTSAVE;Chyba pri ukladaní súboru +MAIN_MSG_CANNOTSTARTEDITOR;Nebolo možné spustiť editor. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Prosím, nastavte správnu cestu v dialógu "Predvoľby". +MAIN_MSG_NAVIGATOR;Navigátor +MAIN_MSG_QOVERWRITE;Chcete ho prepísať? +MAIN_TAB_COLOR;Farba +MAIN_TAB_DETAIL;Detail +MAIN_TAB_DEVELOP;Vyvinúť +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;Expozícia +MAIN_TAB_FILTER;Filter +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadáta +MAIN_TAB_TRANSFORM;Transformácie +MAIN_TOOLTIP_HIDEHP;Zobraziť/ukázať ľavý panel (vrátane histórie, shortcut key: H) +MAIN_TOOLTIP_INDCLIPPEDH;Indikácia orezania najvyšších svetiel +MAIN_TOOLTIP_INDCLIPPEDS;Indikácia orezania tieňov +MAIN_TOOLTIP_QINFO;Rýchle informácie o obrázku +MAIN_TOOLTIP_TOGGLE;Prepnúť pohľad predtým/potom B +NAVIGATOR_XY_NA;x = n/a, y = n/a +PARTIALPASTE_BASICGROUP;Základné nastavenia +PARTIALPASTE_CACORRECTION;Korekcia C/A +PARTIALPASTE_COARSETRANS;90° otočenie/preklopenie +PARTIALPASTE_COLORGROUP;Nastavenia súvisiace s farbou +PARTIALPASTE_COMPOSITIONGROUP;Nastavenia kompozície +PARTIALPASTE_CROP;Orez +PARTIALPASTE_DIALOGLABEL;Profil spracovania čiastočného vloženia +PARTIALPASTE_DISTORTION;Korekcia skreslenia +PARTIALPASTE_EXIFCHANGES;Zmeny v EXIF údajochChanges to exif data +PARTIALPASTE_EXPOSURE;Expozícia +PARTIALPASTE_ICMSETTINGS;Nastavenia ICM +PARTIALPASTE_IPTCINFO;IPTC informácie +PARTIALPASTE_LABCURVE;Krivka svietivosti +PARTIALPASTE_LENSGROUP;Nastavenia súvisiace s objektívom +PARTIALPASTE_METAGROUP;Nastavenia metadát +PARTIALPASTE_RESIZE;Zmeniť veľkosť +PARTIALPASTE_ROTATION;Otočenie +PARTIALPASTE_SHADOWSHIGHLIGHTS;Tiene/Najvyššie svetlá +PARTIALPASTE_SHARPENING;Doostrenie +PARTIALPASTE_VIGNETTING;Korekcia vignetácie +PARTIALPASTE_WHITEBALANCE;Vyváženie bielej +PREFERENCES_ADD;Pridať +PREFERENCES_APPLNEXTSTARTUP;Aplikovaný pri ďalšom spustení +PREFERENCES_BATCH_PROCESSING;dávkové spracovanie +PREFERENCES_BEHAVIOR;Správanie sa +PREFERENCES_CACHECLEARALL;Vyčistiť všetko +PREFERENCES_CACHECLEARPROFILES;Vyčistiť profily +PREFERENCES_CACHECLEARTHUMBS;Vyčistiť zmenšeniny +PREFERENCES_CACHEMAXENTRIES;Maximálny počet vstupov v cache +PREFERENCES_CACHEOPTS;Možnosti cache +PREFERENCES_CACHETHUMBHEIGHT;Maximálna výška zmenšenín +PREFERENCES_CLIPPINGIND;Indikácia orezu +PREFERENCES_CMETRICINTENT;Kolorimetrický zámer +PREFERENCES_DATEFORMATHINT;Môžete použiť nasledujúce formátovacie reťazce:\n%y : rok\n%m : mesiac\n%d : deň\n\nNapríklad, slovenský formát je:\n%d.%m.%y +PREFERENCES_DATEFORMAT;Formát dátumu +PREFERENCES_DEFAULTLANG;Predvolený jazyk +PREFERENCES_DEFAULTTHEME;Predvolený vzhľad +PREFERENCES_DIRHOME;Domovský adresár +PREFERENCES_DIRLAST;Posledný navštívený adresár +PREFERENCES_DIROTHER;Iný +PREFERENCES_DIRSELECTDLG;Vybrať adresár s obrázkami pri spustení... +PREFERENCES_DIRSOFTWARE;Inštalačný adresár +PREFERENCES_EDITORCMDLINE;Iný príkazový riadok +PREFERENCES_EDITORLAYOUT;Rozloženie editora +PREFERENCES_EXTERNALEDITOR;Externý editor +PREFERENCES_FBROWSEROPTS;Voľby prehliadača súborov +PREFERENCES_FILEFORMAT;Formát súborov +PREFERENCES_FORIMAGE;Pre obrazové súbory +PREFERENCES_FORRAW;Pre RAW súbory +PREFERENCES_GIMPPATH;Inštalačný adresár GIMPu +PREFERENCES_HLTHRESHOLD;Prah pre orezanie najvyšších svetiel +PREFERENCES_ICCDIR;Adresár s ICC profilmy +PREFERENCES_IMPROCPARAMS;Predvolené parametre spracovania obrazu +PREFERENCES_INTENT_ABSOLUTE;Absolútny kolorimetrický +PREFERENCES_INTENT_PERCEPTUAL;Vnímaný +PREFERENCES_INTENT_RELATIVE;Relatívny kolorimetrický +PREFERENCES_INTENT_SATURATION;Sýtosť +PREFERENCES_MONITORICC;Profil monitora +PREFERENCES_MULTITAB;Režim viacerých kariet +PREFERENCES_OUTDIRFOLDERHINT;Uložiť obrázky do vybraného adresára +PREFERENCES_OUTDIRFOLDER;Uložiť do adresára +PREFERENCES_OUTDIRTEMPLATEHINT;Môžete použiť nasledujúce formátovacie reťazce:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nTieto formátovacie reťazce odkazujú na adresáre a časti cesty k raw súboru.\n\nNapríklad, ak bol /home/tom/image/02-09-2006/dsc0012.nefotvorený, význam formátovacích reťazcov je:\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\nIf you want to save the output image where the original is, write:\n%p1/%f\n\nIf you want to save the output image in a directory 'converted' located the directory of the original, write:\n%p1/converted/%f\n\nAk chcete uložiť výstupný obraz tam, kde je originál, napíšte:\n%p1/%f\n\nAk chcete uložiť výstupný obraz v adresári 'converted' nachádzajúcom sa v adresári s originálom, napíšte:\n%p1/converted/%f\n\nAk chcete uložiť výstupný obraz v adresári '/home/tom/converted' pri zachovaní toho istého podadresára s dátumami, napíšte:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Použiť šablónu +PREFERENCES_OUTDIR;Výstupný adresár +PREFERENCES_OVERLAY_FILENAMES;Prekryť mená súborov cez zmenšeniny +PREFERENCES_PARSEDEXTADDHINT;Napíšte príponu a stlačte tento gombík pre pripojenie k zoznamu +PREFERENCES_PARSEDEXTADD;Pridať príponu +PREFERENCES_PARSEDEXTDELHINT;Odstrániť vybranú príponu zo zoznamu +PREFERENCES_PARSEDEXT;Spracúvané prípony +PREFERENCES_PROFILEHANDLING;Zaobchádzanie s profilom spracovania +PREFERENCES_PROFILELOADPR;Priorita načítavania profilu +PREFERENCES_PROFILEPRCACHE;Profil v cache +PREFERENCES_PROFILEPRFILE;Profil pri vstupnom súbore +PREFERENCES_PROFILESAVECACHE;Uložiť parametre spracovania do cache +PREFERENCES_PROFILESAVEINPUT;Uložiť parametre spracovania k vstupnému súboru +PREFERENCES_PROPERTY;Vlastnosť +PREFERENCES_PSPATH;Inštalačný adresár Adobe Photoshop +PREFERENCES_SELECTFONT;Vybrať písmo +PREFERENCES_SELECTLANG;Vybrať si jazyk +PREFERENCES_SELECTTHEME;Vybrať vzhľad +PREFERENCES_SET;Nastaviť +PREFERENCES_SHOWBASICEXIF;Zobrazovať základné EXIF informácie +PREFERENCES_SHOWDATETIME;Ukázovať dátum a čas +PREFERENCES_SHTHRESHOLD;Prah pre orezané tiene +PREFERENCES_SINGLETAB;Režim jednej karty +PREFERENCES_STARTUPIMDIR;Adresár s obrázkami pri spustení +PREFERENCES_TAB_BROWSER;Prehliadač súborov +PREFERENCES_TAB_COLORMGR;Správa farieb +PREFERENCES_TAB_GENERAL;Všeobecné +PREFERENCES_TAB_IMPROC;Spracovanie obrazu +PREFERENCES_USESYSTEMTHEME; Použiť systémový vzhľad +PREFERENCES_WORKFLOW;Tok práce +PROFILEPANEL_LABEL;Profily spracovania +PROFILEPANEL_LOADDLGLABEL;Načítať parametre spracovania... +PROFILEPANEL_PCUSTOM;Vlastné +PROFILEPANEL_PFILE;Zo súboru +PROFILEPANEL_PLASTSAVED;Posledné uložené +PROFILEPANEL_SAVEDLGLABEL;Uložiť parametre spracovania... +PROFILEPANEL_TOOLTIPCOPY;Kopírovať súčasný profil do schránky +PROFILEPANEL_TOOLTIPLOAD;Načítať profil zo súboru +PROFILEPANEL_TOOLTIPPASTE;Vložiť profil zo schránky +PROFILEPANEL_TOOLTIPSAVE;Uložiť súčasný profil +PROGRESSBAR_LOADING;Načítavam obrázok... +PROGRESSBAR_LOADJPEG;Ukladám JPEG súbor... +PROGRESSBAR_LOADPNG;Ukladám PNG súbor... +PROGRESSBAR_LOADTIFF;Ukladám TIFF súbor... +PROGRESSBAR_PROCESSING;Spracúvam obrázok... +PROGRESSBAR_READY;Pripravený +PROGRESSBAR_SAVEJPEG;Ukladám JPEG súbor... +PROGRESSBAR_SAVEPNG;Ukladám PNG súbor... +PROGRESSBAR_SAVETIFF;Ukladám TIFF súbor... +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profil zmenený v prehliadači +QINFO_ISO;ISO +QINFO_NOEXIF;Exif údaje sú nedostupné. +SAVEDLG_AUTOSUFFIX;Automaticky pridať príponu, ak už súbor existuje +SAVEDLG_FILEFORMAT;Formát súboru +SAVEDLG_JPEGQUAL;JPEG Kvalita +SAVEDLG_PNGCOMPR;PNG Kompresia +SAVEDLG_PUTTOQUEUEHEAD;Presunúť na čelo radu na spracovanie +SAVEDLG_PUTTOQUEUETAIL;Presunúť na koniec radu na spracovanie +SAVEDLG_PUTTOQUEUE;Vložiť do radu na spracovanie +SAVEDLG_SAVEIMMEDIATELY;Uložiť okamžite +SAVEDLG_SAVESPP;Uložiť parametre spracovania s obrázkom +SAVEDLG_TIFFUNCOMPRESSED;Nekomprimovaný TIFF +TOOLBAR_TOOLTIP_CROP;Orezanie výberu (shortcut key: C) +TOOLBAR_TOOLTIP_HAND;Nástroj ruka (shortcut key: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;Výber rovnej čiary (shortcut key: S) +TOOLBAR_TOOLTIP_WB;Bodové vyváženie bielej (shortcut key: W) +TP_CACORRECTION_BLUE;Modrá +TP_CACORRECTION_LABEL;Korekcia chromatickej aberácie +TP_CACORRECTION_RED;Červená +TP_CHMIXER_BLUE;Modrá +TP_CHMIXER_GREEN;Zelená +TP_CHMIXER_LABEL;Mixér kanálov +TP_CHMIXER_RED;Červená +TP_COARSETRAF_TOOLTIP_HFLIP;Prevrátiť horizontálne +TP_COARSETRAF_TOOLTIP_ROTLEFT;Otočiť doľava +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Otočiť doprava +TP_COARSETRAF_TOOLTIP_VFLIP;Prevrátiť vertikálne +TP_CROP_FIXRATIO;Pevný pomer: +TP_CROP_GTDIAGONALS;Pravidlo diagonál +TP_CROP_GTNONE;Žiadne +TP_CROP_GTRULETHIRDS;Pravidlo tretín +TP_CROP_GUIDETYPE;Type vodidiel: +TP_CROP_H;V +TP_CROP_LABEL;Orezanie +TP_CROP_SELECTCROP; Vyberte Orez +TP_CROP_W;Š +TP_CROP_X;x +TP_CROP_Y;y +TP_DIRPYRDENOISE_CHROMA;Farebnosť +TP_DIRPYRDENOISE_GAMMA;Gamma +TP_DIRPYRDENOISE_LABEL;Redukcia šumu pomocou smerovej pyramídy +TP_DIRPYRDENOISE_LUMA;Svietivosť +TP_DIRPYREQUALIZER_LABEL;Vyrovnávač smerovej pyramídy +TP_DIRPYREQUALIZER_LUMACOARSEST;Najhrubšie +TP_DIRPYREQUALIZER_LUMACONTRAST_MINUS;Kontrast- +TP_DIRPYREQUALIZER_LUMACONTRAST_PLUS;Kontrast+ +TP_DIRPYREQUALIZER_LUMAFINEST;Najjemnejšie +TP_DIRPYREQUALIZER_LUMANEUTRAL;Neutrálne +TP_DIRPYREQUALIZER_THRESHOLD;Threshold +TP_DISTORTION_AMOUNT;Množstvo +TP_DISTORTION_LABEL;Zakrivenie +TP_EXPOSURE_AUTOLEVELS;Auto úrovne +TP_EXPOSURE_BLACKLEVEL;Čierna +TP_EXPOSURE_BRIGHTNESS;Jas +TP_EXPOSURE_CLIP;Orezať +TP_EXPOSURE_COMPRHIGHLIGHTS;Kompresia najvyšších svetiel +TP_EXPOSURE_COMPRSHADOWS;Kompresia tieňov +TP_EXPOSURE_CONTRAST;Kontrast +TP_EXPOSURE_CURVEEDITOR;Krivka tónov +TP_EXPOSURE_EXPCOMP;Kompenzácia expozície +TP_EXPOSURE_LABEL;Expozícia +TP_HLREC_CIELAB;CIELab Blending +TP_HLREC_COLOR;Šírenie farieb +TP_HLREC_LABEL;Obnova najvyšších svetiel +TP_HLREC_LUMINANCE;Obnova svietivosti +TP_HLREC_METHOD;Metóda: +TP_ICM_INPUTCAMERA;Predvolený aparátu +TP_ICM_INPUTCUSTOM;Vlastný +TP_ICM_INPUTDLGLABEL;Vybrať vstupný ICC profil... +TP_ICM_INPUTEMBEDDED;Použiť vstavaný, ak je to možné +TP_ICM_INPUTPROFILE;Vstupný profil +TP_ICM_LABEL;ICM +TP_ICM_NOICM;Bez správy farieb: sRGB výstup +TP_ICM_OUTPUTPROFILE;Výstupný profil +TP_ICM_SAVEREFERENCE;Uložiť referenčný obrázok pre tvorbu profilu +TP_ICM_WORKINGPROFILE;Pracovný profil +TP_IMPULSEDENOISE_LABEL;Impulzná redukcia šumu +TP_IMPULSEDENOISE_THRESH;Prah +TP_LABCURVE_BRIGHTNESS;Jas +TP_LABCURVE_CONTRAST;Kontrast +TP_LABCURVE_CURVEEDITOR;Krivka svietivosti +TP_LABCURVE_LABEL;Krivka svietivosti +TP_LENSGEOM_AUTOCROP;Automatické orezanie +TP_LENSGEOM_FILL;Automatické vyplnenie +TP_LENSGEOM_LABEL;Objektív/Geometria +TP_PERSPECTIVE_HORIZONTAL;Horizontálne +TP_PERSPECTIVE_LABEL;Perspektíva +TP_PERSPECTIVE_VERTICAL;Vertikálne +TP_PREPROCESS_GREENEQUIL;Vyvažovanie zelenej +TP_PREPROCESS_LINEDENOISE;Filter šumu vedenia +TP_RAWCACORR_AUTO;Použiť automatickú úpravu CA +TP_RAW_DCBENHANCE;Použiť vylepšovací krok DCB +TP_RAW_DCBITERATIONS;Počet iterácií DCB +TP_RAW_DMETHOD;Metóda +TP_RAW_FALSECOLOR;Kroky potlačenia chybných farieb +TP_RESIZE_HEIGHT;Výška +TP_RESIZE_H;V: +TP_RESIZE_LABEL;Zmeniť veľkosť +TP_RESIZE_METHOD;Metóda: +TP_RESIZE_NEAREST;Najbližšie +TP_RESIZE_SCALE;Pomer +TP_RESIZE_SPECIFY;Zadať: +TP_RESIZE_WIDTH;Šírka +TP_RESIZE_W;Š: +TP_ROTATE_DEGREE;Stupeň +TP_ROTATE_LABEL;Otočiť +TP_ROTATE_SELECTLINE;Vybrať rovnú čiaru +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Najvyššie svetlá +TP_SHADOWSHLIGHTS_HLTONALW;Tonálna šírka +TP_SHADOWSHLIGHTS_LABEL;Tiene/Najvyššie svetlá +TP_SHADOWSHLIGHTS_LOCALCONTR;Miestny kontrast +TP_SHADOWSHLIGHTS_RADIUS;Polomer +TP_SHADOWSHLIGHTS_SHADOWS;Tiene +TP_SHADOWSHLIGHTS_SHTONALW;Tonálna šírka +TP_SHARPENING_AMOUNT;Množstvo +TP_SHARPENING_EDRADIUS;Polomer +TP_SHARPENING_EDTOLERANCE;Tolerancia okrajov +TP_SHARPENING_HALOCONTROL;Kontrola svätožiary +TP_SHARPENING_HCAMOUNT;Množstvo +TP_SHARPENING_LABEL;Doostrenie +TP_SHARPENING_METHOD;Metóda +TP_SHARPENING_ONLYEDGES;Doostriť len okraje +TP_SHARPENING_RADIUS;Polomer +TP_SHARPENING_RLD;RL Dekonvolúcia +TP_SHARPENING_RLD_AMOUNT;Množstvo +TP_SHARPENING_RLD_DAMPING;Tlmenie +TP_SHARPENING_RLD_ITERATIONS;Iterácie +TP_SHARPENING_THRESHOLD;Prah +TP_SHARPENING_USM;Unsharp Mask +TP_VIGNETTING_AMOUNT;Množstvo +TP_VIGNETTING_LABEL;Korekcia vignetácie +TP_VIGNETTING_RADIUS;Polomer +TP_WBALANCE_AUTO;Automatické +TP_WBALANCE_CAMERA;Fotoaparát +TP_WBALANCE_CUSTOM;Vlastné +TP_WBALANCE_GREEN;Nádych +TP_WBALANCE_LABEL;Vyváženie bielej +TP_WBALANCE_METHOD;Metóda +TP_WBALANCE_SIZE;Veľkosť: +TP_WBALANCE_SPOTWB;Bodové VB +TP_WBALANCE_TEMPERATURE;Teplota +ZOOMPANEL_100;(100%) +ZOOMPANEL_NEWCROPWINDOW;Otvoriť (nové) okno s detailom +ZOOMPANEL_ZOOM100;Priblíženie na 100% z +ZOOMPANEL_ZOOMFITSCREEN;Prispôsobiť obrazovke f +ZOOMPANEL_ZOOMIN;Priblížiť + +ZOOMPANEL_ZOOMOUT;Oddialiť - + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!ABOUT_TAB_BUILD;Version +!ABOUT_TAB_CREDITS;Credits +!ABOUT_TAB_LICENSE;License +!ABOUT_TAB_RELEASENOTES;Release Notes +!ABOUT_TAB_SPLASH;Splash +!BATCHQUEUE_DESTFILENAME;Path and file name +!CURVEEDITOR_AXIS_IN;I: +!CURVEEDITOR_AXIS_LEFT_TAN;LT: +!CURVEEDITOR_AXIS_OUT;O: +!CURVEEDITOR_AXIS_RIGHT_TAN;RT: +!CURVEEDITOR_CURVES;Curves +!CURVEEDITOR_CURVE;Curve +!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_TOOLTIPCOPY;Copy current curve to clipboard. +!CURVEEDITOR_TOOLTIPPASTE;Paste curve from clipboard. +!EDITWINDOW_TITLE;Image Edit +!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_FILETYPE;File type +!EXPORT_BYPASS_ALL;Select / Unselect All +!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_FF;Bypass [raw] Flat-Field +!EXPORT_BYPASS_RAW_GREENTHRESH;Bypass [raw] Green Equilibration +!EXPORT_BYPASS_RAW_LINENOISE;Bypass [raw] Line Noise Filter +!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_FASTEXPORTOPTIONS;Fast Export Options +!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_MAXHEIGHT;Maximum height: +!EXPORT_MAXWIDTH;Maximum width: +!EXPORT_PUTTOQUEUEFAST; Put to queue for fast export +!EXPORT_RAW_DMETHOD;Demosaic method +!EXTPROGTARGET_1;raw +!EXTPROGTARGET_2;queue-processed +!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_CACHECLEARFROMFULL;Clear from cache - full +!FILEBROWSER_CACHECLEARFROMPARTIAL;Clear from cache - partial +!FILEBROWSER_CACHE;Cache +!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_EXEC_CPB;Custom Profile Builder +!FILEBROWSER_EXTPROGMENU;Open with +!FILEBROWSER_FLATFIELD;Flat-Field +!FILEBROWSER_MOVETODARKFDIR;Move to dark-frames directory +!FILEBROWSER_MOVETOFLATFIELDDIR;Move to flat-fields directory +!FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) +!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_POPUPCOLORLABEL;Color label +!FILEBROWSER_POPUPCOPYTO;Copy to... +!FILEBROWSER_POPUPFILEOPERATIONS;File operations +!FILEBROWSER_POPUPMOVETO;Move to... +!FILEBROWSER_POPUPPROCESSFAST;Put to queue (Fast export) +!FILEBROWSER_POPUPPROFILEOPERATIONS;Processing profile operations +!FILEBROWSER_POPUPRANK0;Unrank +!FILEBROWSER_POPUPRANK1;Rank 1 * +!FILEBROWSER_POPUPRANK2;Rank 2 ** +!FILEBROWSER_POPUPRANK3;Rank 3 *** +!FILEBROWSER_POPUPRANK4;Rank 4 **** +!FILEBROWSER_POPUPRANK5;Rank 5 ***** +!FILEBROWSER_POPUPRANK;Rank +!FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!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_QUERYLABEL; Find: +!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_SELECTDARKFRAME;Select dark-frame... +!FILEBROWSER_SELECTFLATFIELD;Select flat-field... +!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 +!FILEBROWSER_SHOWCOLORLABEL4HINT;Show images labeled Blue.\nShortcut: Alt-4 +!FILEBROWSER_SHOWCOLORLABEL5HINT;Show images labeled Purple.\nShortcut: Alt-5 +!FILEBROWSER_SHOWEDITEDHINT;Show edited images.\nShortcut: 7 +!FILEBROWSER_SHOWEDITEDNOTHINT;Show not edited images.\nShortcut: 6 +!FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!FILEBROWSER_SHOWRECENTLYSAVEDHINT;Show saved images.\nShortcut: Alt-7 +!FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show unsaved images.\nShortcut: Alt-6 +!FILEBROWSER_SHOWUNCOLORHINT;Show images without a color label.\nShortcut: Alt-0 +!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_ASIMAGE;As Image +!GENERAL_AUTO;Automatic +!GENERAL_CLOSE;Close +!GENERAL_FILE;File +!GENERAL_NONE;None +!GENERAL_WARNING;Warning +!HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar.\nRight-click on image preview to freeze/unfreeze. +!HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram. +!HISTOGRAM_TOOLTIP_FULL;Toggle full (off) or scaled (on) histogram. +!HISTOGRAM_TOOLTIP_RAW;Show/Hide raw histogram. +!HISTORY_MSG_88;Impulse NR threshold +!HISTORY_MSG_93;CbDL - Value +!HISTORY_MSG_94;Contrast by Detail Levels +!HISTORY_MSG_95;L*a*b* - Chromaticity +!HISTORY_MSG_96;L*a*b* - a* curve +!HISTORY_MSG_97;L*a*b* - b* curve +!HISTORY_MSG_98;Demosaicing method +!HISTORY_MSG_99;Hot pixel filter +!HISTORY_MSG_100;RGB Saturation +!HISTORY_MSG_101;HSV - Hue +!HISTORY_MSG_102;HSV - Saturation +!HISTORY_MSG_103;HSV - Value +!HISTORY_MSG_104;HSV Equalizer +!HISTORY_MSG_105;Defringe +!HISTORY_MSG_106;Defringe - Radius +!HISTORY_MSG_107;Defringe - Threshold +!HISTORY_MSG_108;Highlight Compr. Threshold +!HISTORY_MSG_109;Resize - Bounding box +!HISTORY_MSG_110;Resize - Applies to +!HISTORY_MSG_111;L*a*b* - Avoid color shift +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;L*a*b* - Red/skin prot. +!HISTORY_MSG_114;DCB iterations +!HISTORY_MSG_115;False color suppression +!HISTORY_MSG_116;DCB enhancement +!HISTORY_MSG_117;Raw CA correction - Red +!HISTORY_MSG_118;Raw CA correction - Blue +!HISTORY_MSG_119;Line noise filter +!HISTORY_MSG_120;Green equilibration +!HISTORY_MSG_121;Raw CA Correction - Auto +!HISTORY_MSG_122;Dark-Frame - Auto-selection +!HISTORY_MSG_123;Dark-Frame - File +!HISTORY_MSG_124;White point correction +!HISTORY_MSG_125;Highlight preservation +!HISTORY_MSG_126;Flat-Field - File +!HISTORY_MSG_127;Flat-Field - Auto-selection +!HISTORY_MSG_128;Flat-Field - Blur radius +!HISTORY_MSG_129;Flat-Field - Blur type +!HISTORY_MSG_130;Auto distorion correction +!HISTORY_MSG_131;NR - Luma +!HISTORY_MSG_132;NR - Chroma +!HISTORY_MSG_133;Output gamma +!HISTORY_MSG_134;Free gamma +!HISTORY_MSG_135;Free gamma +!HISTORY_MSG_136;Free gamma slope +!HISTORY_MSG_137;Black level - Green 1 +!HISTORY_MSG_138;Black level - Red +!HISTORY_MSG_139;Black level - Blue +!HISTORY_MSG_140;Black level - Green 2 +!HISTORY_MSG_141;Black level - Link greens +!HISTORY_MSG_142;ES - Iterations +!HISTORY_MSG_143;ES - Quantity +!HISTORY_MSG_144;Microcontrast - Quantity +!HISTORY_MSG_145;Microcontrast - Uniformity +!HISTORY_MSG_146;Edge sharpening +!HISTORY_MSG_147;ES - Luminance only +!HISTORY_MSG_148;Microcontrast +!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_150;Post-demosaic artifact/noise red. +!HISTORY_MSG_151;Vibrance +!HISTORY_MSG_152;Vib - Pastel tones +!HISTORY_MSG_153;Vib - Saturated tones +!HISTORY_MSG_154;Vib - Protect skin-tones +!HISTORY_MSG_155;Vib - Avoid color shift +!HISTORY_MSG_156;Vib - Link pastel/saturated +!HISTORY_MSG_157;Vib - P/S threshold +!HISTORY_MSG_158;TM - Strength +!HISTORY_MSG_159;TM - Edge stopping +!HISTORY_MSG_160;TM - Scale +!HISTORY_MSG_161;TM - Reweighting iterates +!HISTORY_MSG_162;Tone Mapping +!HISTORY_MSG_163;RGB curves - Red +!HISTORY_MSG_164;RGB curves - Green +!HISTORY_MSG_165;RGB curves - Blue +!HISTORY_MSG_166;Neutral levels +!HISTORY_MSG_167;--unused-- +!HISTORY_MSG_168;L*a*b* - CC curve +!HISTORY_MSG_169;L*a*b* - CH curve +!HISTORY_MSG_170;Vibrance - HH curve +!HISTORY_MSG_171;L*a*b* - LC curve +!HISTORY_MSG_172;L*a*b* - Restrict LC +!HISTORY_MSG_173;NR - Luminance detail +!HISTORY_MSG_174;CIECAM02 +!HISTORY_MSG_175;CAM02 - CAT02 adaptation +!HISTORY_MSG_176;CAM02 - Viewing surround +!HISTORY_MSG_177;CAM02 - Scene luminosity +!HISTORY_MSG_178;CAM02 - Viewing luminosity +!HISTORY_MSG_179;CAM02 - White-point model +!HISTORY_MSG_180;CAM02 - Lightness (J) +!HISTORY_MSG_181;CAM02 - Chroma (C) +!HISTORY_MSG_182;CAM02 - Automatic CAT02 +!HISTORY_MSG_183;CAM02 - Contrast (J) +!HISTORY_MSG_184;CAM02 - Scene surround +!HISTORY_MSG_185;CAM02 - Gamut control +!HISTORY_MSG_186;CAM02 - Algorithm +!HISTORY_MSG_187;CAM02 - Red/skin prot. +!HISTORY_MSG_188;CAM02 - Brightness (Q) +!HISTORY_MSG_189;CAM02 - Contrast (Q) +!HISTORY_MSG_190;CAM02 - Saturation (S) +!HISTORY_MSG_191;CAM02 - Colorfulness (M) +!HISTORY_MSG_192;CAM02 - Hue (h) +!HISTORY_MSG_193;CAM02 - Tone curve 1 +!HISTORY_MSG_194;CAM02 - Tone curve 2 +!HISTORY_MSG_195;CAM02 - Tone curve 1 +!HISTORY_MSG_196;CAM02 - Tone curve 2 +!HISTORY_MSG_197;CAM02 - Color curve +!HISTORY_MSG_198;CAM02 - Color curve +!HISTORY_MSG_199;CAM02 - Output histograms +!HISTORY_MSG_200;CAM02 - Tone mapping +!HISTORY_MSG_201;NR - Chrominance - R&G +!HISTORY_MSG_202;NR - Chrominance - B&Y +!HISTORY_MSG_203;NR - Method +!HISTORY_MSG_204;LMMSE enhancement steps +!HISTORY_MSG_205;CAM02 - Hot/bad pixel filter +!HISTORY_MSG_206;CAT02 - Auto scene luminosity +!HISTORY_MSG_207;Defringe - Hue curve +!HISTORY_MSG_208;WB - B/R equalizer +!HISTORY_MSG_210;GF - Angle +!HISTORY_MSG_211;Graduated Filter +!HISTORY_MSG_212;VF - Strength +!HISTORY_MSG_213;Vignette Filter +!HISTORY_MSG_214;Black-and-White +!HISTORY_MSG_215;B&W - CM - Red +!HISTORY_MSG_216;B&W - CM - Green +!HISTORY_MSG_217;B&W - CM - Blue +!HISTORY_MSG_218;B&W - Gamma - Red +!HISTORY_MSG_219;B&W - Gamma - Green +!HISTORY_MSG_220;B&W - Gamma - Blue +!HISTORY_MSG_221;B&W - Color filter +!HISTORY_MSG_222;B&W - Presets +!HISTORY_MSG_223;B&W - CM - Orange +!HISTORY_MSG_224;B&W - CM - Yellow +!HISTORY_MSG_225;B&W - CM - Cyan +!HISTORY_MSG_226;B&W - CM - Magenta +!HISTORY_MSG_227;B&W - CM - Purple +!HISTORY_MSG_228;B&W - Luminance equalizer +!HISTORY_MSG_229;B&W - Luminance equalizer +!HISTORY_MSG_230;B&W - Mode +!HISTORY_MSG_231;B&W - 'Before' curve +!HISTORY_MSG_232;B&W - 'Before' curve type +!HISTORY_MSG_233;B&W - 'After' curve +!HISTORY_MSG_234;B&W - 'After' curve type +!HISTORY_MSG_235;B&W - Auto channel mixer +!HISTORY_MSG_236;--unused-- +!HISTORY_MSG_237;B&W - Mixer +!HISTORY_MSG_238;GF - Feather +!HISTORY_MSG_239;GF - Strength +!HISTORY_MSG_240;GF - Center +!HISTORY_MSG_241;VF - Feather +!HISTORY_MSG_242;VF - Roundness +!HISTORY_MSG_243;VC - Radius +!HISTORY_MSG_244;VC - Strength +!HISTORY_MSG_245;VC - Center +!HISTORY_MSG_246;L*a*b* - CL curve +!HISTORY_MSG_247;L*a*b* - LH curve +!HISTORY_MSG_248;L*a*b* - HH curve +!HISTORY_MSG_249;CbDL - Threshold +!HISTORY_MSG_250;NR - Enhanced +!HISTORY_MSG_251;B&W - Algorithm +!HISTORY_MSG_252;CbDL - Skin tar/prot +!HISTORY_MSG_253;CbDL - Reduce artifacts +!HISTORY_MSG_254;CbDL - Skin hue +!HISTORY_MSG_255;NR - Median filter +!HISTORY_MSG_256;NR - Median type +!HISTORY_MSG_257;Color Toning +!HISTORY_MSG_258;CT - Color curve +!HISTORY_MSG_259;CT - Opacity curve +!HISTORY_MSG_260;CT - a*[b*] opacity +!HISTORY_MSG_261;CT - Method +!HISTORY_MSG_262;CT - b* opacity +!HISTORY_MSG_263;CT - Shadows - Red +!HISTORY_MSG_264;CT - Shadows - Green +!HISTORY_MSG_265;CT - Shadows - Blue +!HISTORY_MSG_266;CT - Mid - Red +!HISTORY_MSG_267;CT - Mid - Green +!HISTORY_MSG_268;CT - Mid - Blue +!HISTORY_MSG_269;CT - High - Red +!HISTORY_MSG_270;CT - High - Green +!HISTORY_MSG_271;CT - High - Blue +!HISTORY_MSG_272;CT - Balance +!HISTORY_MSG_273;CT - Reset +!HISTORY_MSG_274;CT - Sat. Shadows +!HISTORY_MSG_275;CT - Sat. Highlights +!HISTORY_MSG_276;CT - Opacity +!HISTORY_MSG_277;--unused-- +!HISTORY_MSG_278;CT - Preserve luminance +!HISTORY_MSG_279;CT - Shadows +!HISTORY_MSG_280;CT - Highlights +!HISTORY_MSG_281;CT - Sat. strength +!HISTORY_MSG_282;CT - Sat. threshold +!HISTORY_MSG_283;CT - Strength +!HISTORY_MSG_284;CT - Auto sat. protection +!HISTORY_MSG_285;NR - Median - Method +!HISTORY_MSG_286;NR - Median - Type +!HISTORY_MSG_287;NR - Median - Iterations +!HISTORY_MSG_288;Flat Field - Clip control +!HISTORY_MSG_289;Flat Field - Clip control - Auto +!HISTORY_MSG_290;Black Level - Red +!HISTORY_MSG_291;Black Level - Green +!HISTORY_MSG_292;Black Level - Blue +!HISTORY_MSG_293;Film Simulation +!HISTORY_MSG_294;Film Simulation - Strength +!HISTORY_MSG_295;Film Simulation - Film +!HISTORY_MSG_296;NR - Luminance curve +!HISTORY_MSG_297;NR - Quality +!HISTORY_MSG_298;Dead pixel filter +!HISTORY_MSG_299;NR - Chrominance curve +!HISTORY_MSG_300;- +!HISTORY_MSG_301;NR - Luma control +!HISTORY_MSG_302;NR - Chroma method +!HISTORY_MSG_303;NR - Chroma method +!HISTORY_MSG_304;W - Contrast levels +!HISTORY_MSG_305;Wavelet Levels +!HISTORY_MSG_306;W - Preview +!HISTORY_MSG_307;W - Preview +!HISTORY_MSG_308;W - Preview direction +!HISTORY_MSG_309;W - ES - Detail +!HISTORY_MSG_310;W - Residual - Sky tar/prot +!HISTORY_MSG_311;W - Wavelet levels +!HISTORY_MSG_312;W - Residual - Shadows threshold +!HISTORY_MSG_313;W - Chroma - Sat/past +!HISTORY_MSG_314;W - Gamut - Reduce artifacts +!HISTORY_MSG_315;W - Residual - Contrast +!HISTORY_MSG_316;W - Gamut - Skin tar/prot +!HISTORY_MSG_317;W - Gamut - Skin hue +!HISTORY_MSG_318;W - Contrast - Highlight levels +!HISTORY_MSG_319;W - Contrast - Highlight range +!HISTORY_MSG_320;W - Contrast - Shadow range +!HISTORY_MSG_321;W - Contrast - Shadow levels +!HISTORY_MSG_322;W - Gamut - Avoid color shift +!HISTORY_MSG_323;W - ES - Local contrast +!HISTORY_MSG_324;W - Chroma - Pastel +!HISTORY_MSG_325;W - Chroma - Saturated +!HISTORY_MSG_326;W - Chroma - Method +!HISTORY_MSG_327;W - Contrast - Apply to +!HISTORY_MSG_328;W - Chroma - Link strength +!HISTORY_MSG_329;W - Toning - Opacity RG +!HISTORY_MSG_330;W - Toning - Opacity BY +!HISTORY_MSG_331;W - Contrast levels - Extra +!HISTORY_MSG_332;W - Tiling method +!HISTORY_MSG_333;W - Residual - Shadows +!HISTORY_MSG_334;W - Residual - Chroma +!HISTORY_MSG_335;W - Residual - Highlights +!HISTORY_MSG_336;W - Residual - Highlights threshold +!HISTORY_MSG_337;W - Residual - Sky hue +!HISTORY_MSG_338;W - ES - Radius +!HISTORY_MSG_339;W - ES - Strength +!HISTORY_MSG_340;W - Strength +!HISTORY_MSG_341;W - Edge performance +!HISTORY_MSG_342;W - ES - First level +!HISTORY_MSG_343;W - Chroma levels +!HISTORY_MSG_344;W - Meth chroma sl/cur +!HISTORY_MSG_345;W - ES - Local contrast +!HISTORY_MSG_346;W - ES - Local contrast method +!HISTORY_MSG_347;W - Denoise - Level 0 +!HISTORY_MSG_348;W - Denoise - Level 1 +!HISTORY_MSG_349;W - Denoise - Level 2 +!HISTORY_MSG_350;W - ES - Edge detection +!HISTORY_MSG_351;W - Residual - HH curve +!HISTORY_MSG_352;W - Background +!HISTORY_MSG_353;W - ES - Gradient sensitivity +!HISTORY_MSG_354;W - ES - Enhance +!HISTORY_MSG_355;W - ES - Threshold low +!HISTORY_MSG_356;W - ES - Threshold high +!HISTORY_MSG_357;W - Denoise - Link with ES +!HISTORY_MSG_358;W - Gamut - CH +!HISTORY_MSG_359;Hot/Dead - Threshold +!HISTORY_MSG_360;TM Gamma +!HISTORY_MSG_361;W - Final - Chroma balance +!HISTORY_MSG_362;W - Residual - Compression method +!HISTORY_MSG_363;W - Residual - Compression strength +!HISTORY_MSG_364;W - Final - Contrast balance +!HISTORY_MSG_365;W - Final - Delta balance +!HISTORY_MSG_366;W - Residual - Compression gamma +!HISTORY_MSG_367;W - ES - Local contrast curve +!HISTORY_MSG_368;W - Final - Contrast balance +!HISTORY_MSG_369;W - Final - Balance method +!HISTORY_MSG_370;W - Final - Local contrast curve +!HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s +!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). +!MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Show/hide all side panels.\nShortcut: m +!MAIN_FRAME_BATCHQUEUE_TOOLTIP;Processing queue.\nShortcut: Ctrl-F3 +!MAIN_FRAME_EDITOR;Editor +!MAIN_FRAME_EDITOR_TOOLTIP;Editor.\nShortcut: Ctrl-F4 +!MAIN_FRAME_FILEBROWSER_TOOLTIP;File browser.\nShortcut: Ctrl-F2 +!MAIN_MSG_EMPTYFILENAME;Filename unspecified! +!MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue-processed first. +!MAIN_MSG_OPERATIONCANCELLED;Operation cancelled +!MAIN_MSG_PATHDOESNTEXIST;The path\n\n%1\n\ndoes not exist. Please set a correct path in Preferences. +!MAIN_MSG_SETPATHFIRST;You first have to set a target path in Preferences in order to use this function! +!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_EXPORT; Fast Export +!MAIN_TAB_EXPOSURE_TOOLTIP;Shortcut: Alt-e +!MAIN_TAB_INSPECT; Inspect +!MAIN_TAB_METADATA_TOOLTIP;Shortcut: Alt-m +!MAIN_TAB_RAW;Raw +!MAIN_TAB_RAW_TOOLTIP;Shortcut: Alt-r +!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_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%. +!MAIN_TOOLTIP_PREVIEWG;Preview the Green channel.\nShortcut: g +!MAIN_TOOLTIP_PREVIEWL;Preview the Luminosity.\nShortcut: v\n\n0.299*R + 0.587*G + 0.114*B +!MAIN_TOOLTIP_PREVIEWR;Preview the Red channel.\nShortcut: r +!MAIN_TOOLTIP_SHOWHIDELP1;Show/Hide the left panel.\nShortcut: l +!MAIN_TOOLTIP_SHOWHIDERP1;Show/Hide the right panel.\nShortcut: Alt-l +!MAIN_TOOLTIP_SHOWHIDETP1;Show/Hide the top panel.\nShortcut: Shift-l +!MAIN_TOOLTIP_THRESHOLD;Threshold +!NAVIGATOR_B;B: +!NAVIGATOR_G;G: +!NAVIGATOR_H;H: +!NAVIGATOR_LAB_A;a*: +!NAVIGATOR_LAB_B;b*: +!NAVIGATOR_LAB_L;L*: +!NAVIGATOR_NA; -- +!NAVIGATOR_R;R: +!NAVIGATOR_S;S: +!NAVIGATOR_V;V: +!NAVIGATOR_XY_FULL;Width: %1, Height: %2 +!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_CHANNELMIXERBW;Black-and-White +!PARTIALPASTE_CHANNELMIXER;Channel mixer +!PARTIALPASTE_COLORAPP;CIECAM02 +!PARTIALPASTE_COLORTONING;Color Toning +!PARTIALPASTE_COMMONTRANSFORMPARAMS;Auto-fill +!PARTIALPASTE_DARKFRAMEAUTOSELECT;Dark-frame auto-selection +!PARTIALPASTE_DARKFRAMEFILE;Dark-frame file +!PARTIALPASTE_DEFRINGE;Defringe +!PARTIALPASTE_DETAILGROUP;Detail Settings +!PARTIALPASTE_DIRPYRDENOISE;Noise reduction +!PARTIALPASTE_DIRPYREQUALIZER;Contrast by detail levels +!PARTIALPASTE_EPD;Tone mapping +!PARTIALPASTE_EQUALIZER;Wavelet Equalizer +!PARTIALPASTE_EVERYTHING;Everything +!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_GRADIENT;Graduated filter +!PARTIALPASTE_HSVEQUALIZER;HSV equalizer +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction +!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_PCVIGNETTE;Vignette filter +!PARTIALPASTE_PERSPECTIVE;Perspective +!PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter +!PARTIALPASTE_PREPROCESS_GREENEQUIL;Green equilibration +!PARTIALPASTE_PREPROCESS_HOTPIXFILT;Hot pixel filter +!PARTIALPASTE_PREPROCESS_LINEDENOISE;Line noise filter +!PARTIALPASTE_RAWCACORR_AUTO;CA auto-correction +!PARTIALPASTE_RAWCACORR_CABLUE;CA blue +!PARTIALPASTE_RAWCACORR_CARED;CA red +!PARTIALPASTE_RAWEXPOS_BLACK;Black levels +!PARTIALPASTE_RAWEXPOS_LINEAR;White point correction +!PARTIALPASTE_RAWEXPOS_PRESER;Highlight preservation +!PARTIALPASTE_RAWGROUP;Raw Settings +!PARTIALPASTE_RAW_DCBENHANCE;DCB enhancement +!PARTIALPASTE_RAW_DCBITERATIONS;Number of DCB iterations +!PARTIALPASTE_RAW_DMETHOD;Demosaic method +!PARTIALPASTE_RAW_FALSECOLOR;Demosaic false color suppression steps +!PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!PARTIALPASTE_RGBCURVES;RGB curves +!PARTIALPASTE_SHARPENEDGE;Edges +!PARTIALPASTE_SHARPENMICRO;Microcontrast +!PARTIALPASTE_VIBRANCE;Vibrance +!PARTIALPASTE_WAVELETGROUP;Wavelet processing +!PREFERENCES_AUTLISLOW;Low +!PREFERENCES_AUTLISMAX;Max - Average of all tiles +!PREFERENCES_AUTLISSTD;High +!PREFERENCES_AUTLISVLOW;None +!PREFERENCES_AUTLOW;Low +!PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +!PREFERENCES_AUTSTD;Standard +!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_BEHADDALL;All to 'Add' +!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_BEHSETALL;All to 'Set' +!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_CURVEBBOXPOS;Position of curve copypasta buttons +!PREFERENCES_CURVEBBOXPOS_ABOVE;Above +!PREFERENCES_CURVEBBOXPOS_BELOW;Below +!PREFERENCES_CURVEBBOXPOS_LEFT;Left +!PREFERENCES_CURVEBBOXPOS_RIGHT;Right +!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_CUSTPROFBUILD;Custom Processing Profile Builder +!PREFERENCES_CUTOVERLAYBRUSH;Crop mask color/transparency +!PREFERENCES_D50;5000K +!PREFERENCES_D55;5500K +!PREFERENCES_D60;6000K +!PREFERENCES_D65;6500K +!PREFERENCES_DARKFRAMEFOUND;Found +!PREFERENCES_DARKFRAMESHOTS;shots +!PREFERENCES_DARKFRAMETEMPLATES;templates +!PREFERENCES_DARKFRAME;Dark-Frame +!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_EXPAUT;Expert +!PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar (de-select for low resolution display) +!PREFERENCES_FILMSIMULATION;Film Simulation +!PREFERENCES_FLATFIELDFOUND;Found +!PREFERENCES_FLATFIELDSDIR;Flat-fields directory +!PREFERENCES_FLATFIELDSHOTS;shots +!PREFERENCES_FLATFIELDTEMPLATES;templates +!PREFERENCES_FLATFIELD;Flat-Field +!PREFERENCES_FLUOF2;Fluorescent F2 +!PREFERENCES_FLUOF7;Fluorescent F7 +!PREFERENCES_FLUOF11;Fluorescent F11 +!PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT;Same thumbnail height between the Editor's panel 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_GREY05;Yb=05 CIE L#30 +!PREFERENCES_GREY10;Yb=10 CIE L#40 +!PREFERENCES_GREY15;Yb=15 CIE L#45 +!PREFERENCES_GREY18;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_GREYSC18;Yb=18 CIE L#50 +!PREFERENCES_GREYSCA;Automatic +!PREFERENCES_GREYSC;Scene Yb luminance (%) +!PREFERENCES_GREY;Output device's Yb luminance (%) +!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_LANGAUTODETECT;Use system language +!PREFERENCES_LEVAUTDN;Denoising level +!PREFERENCES_LEVDN;Cell size +!PREFERENCES_LISS;Auto multi-zone smoothing +!PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders +!PREFERENCES_MAX;Maxi (Tile) +!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_MENUGROUPRANK;Group "Rank" +!PREFERENCES_MENUOPTIONS;Context Menu Options +!PREFERENCES_METADATA;Metadata +!PREFERENCES_MIN;Mini (100x115) +!PREFERENCES_MULTITABDUALMON;Multiple Editor Tabs In Own Window Mode +!PREFERENCES_NAVGUIDEBRUSH;Navigator guide color +!PREFERENCES_NAVIGATIONFRAME;Navigation +!PREFERENCES_NOISE;Noise Reduction +!PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Overlay filenames on thumbnails in the editor pannel +!PREFERENCES_OVERWRITEOUTPUTFILE;Overwrite existing output files +!PREFERENCES_PANFACTORLABEL;Pan rate amplification +!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_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_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_SHOWEXPOSURECOMPENSATION;Append exposure compensation +!PREFERENCES_SHOWFILMSTRIPTOOLBAR;Show filmstrip toolbar +!PREFERENCES_SIMPLAUT;Tool mode +!PREFERENCES_SINGLETABVERTAB;Single Editor Tab Mode, Vertical Tabs +!PREFERENCES_SLIMUI;Slim interface +!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_PERFORMANCE;Performance & Quality +!PREFERENCES_TAB_SOUND;Sounds +!PREFERENCES_TIMAX;High +!PREFERENCES_TINB;Number of tiles +!PREFERENCES_TISTD;Standard +!PREFERENCES_TP_LABEL;Tool panel: +!PREFERENCES_TP_USEICONORTEXT;Use tab icons instead of text +!PREFERENCES_TP_VSCROLLBAR;Hide vertical scrollbar +!PREFERENCES_TUNNELMETADATA;Copy IPTC/XMP unchanged to output file (when tagging with other program) +!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 +!PROFILEPANEL_COPYPPASTE;Parameters to copy +!PROFILEPANEL_GLOBALPROFILES;Bundled profiles +!PROFILEPANEL_LOADPPASTE;Parameters to load +!PROFILEPANEL_MODE_TIP;Processing profile fill mode.\n\nButton pressed: partial profiles will be converted to full profiles; the missing values will be replaced with hard-coded defaults.\n\nButton released: profiles will be applied as they are, altering only those values which they contain. +!PROFILEPANEL_MYPROFILES;My profiles +!PROFILEPANEL_PASTEPPASTE;Parameters to paste +!PROFILEPANEL_PINTERNAL;Neutral +!PROFILEPANEL_SAVEPPASTE;Parameters to save +!PROGRESSBAR_LOADINGTHUMBS;Loading thumbnails... +!PROGRESSBAR_NOIMAGES;No images found +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing profile saved +!PROGRESSBAR_SNAPSHOT_ADDED;Snapshot added +!SAVEDLG_FORCEFORMATOPTS;Force saving options +!SAVEDLG_SUBSAMP;Subsampling +!SAVEDLG_SUBSAMP_1;Best compression +!SAVEDLG_SUBSAMP_2;Balanced +!SAVEDLG_SUBSAMP_3;Best quality +!SAVEDLG_SUBSAMP_TOOLTIP;Best compression: 4:1:1\nBalanced: 4:2:2\nBest quality: 4:4:4 +!SAVEDLG_WARNFILENAME;File will be named +!SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. +!THRESHOLDSELECTOR_BL;Bottom-left +!THRESHOLDSELECTOR_BR;Bottom-right +!THRESHOLDSELECTOR_B;Bottom +!THRESHOLDSELECTOR_HINT;Hold the Shift key to move individual control points. +!THRESHOLDSELECTOR_TL;Top-left +!THRESHOLDSELECTOR_TR;Top-right +!THRESHOLDSELECTOR_T;Top +!TP_BWMIX_ALGO;Algorithm OYCPM +!TP_BWMIX_ALGO_LI;Linear +!TP_BWMIX_ALGO_SP;Special effects +!TP_BWMIX_ALGO_TOOLTIP;Linear: will produce a normal linear response.\nSpecial effects: will produce special effects by mixing channels non-linearly. +!TP_BWMIX_AUTOCH;Auto +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing Channel Mixer. +!TP_BWMIX_CC_ENABLED;Adjust complementary color +!TP_BWMIX_CC_TOOLTIP;Enable to allow automatic adjustment of complementary colors in ROYGCBPM mode. +!TP_BWMIX_CHANNEL;Luminance equalizer +!TP_BWMIX_CURVEEDITOR1;'Before' curve +!TP_BWMIX_CURVEEDITOR2;'After' curve +!TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Tone curve, after B&W conversion, at the end of treatment. +!TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Tone curve, just before B&W conversion.\nMay take into account the color components. +!TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H).\nPay attention to extreme values as they may cause artifacts. +!TP_BWMIX_FILTER;Color Filter +!TP_BWMIX_FILTER_BLUEGREEN;Blue-Green +!TP_BWMIX_FILTER_BLUE;Blue +!TP_BWMIX_FILTER_GREENYELLOW;Green-Yellow +!TP_BWMIX_FILTER_GREEN;Green +!TP_BWMIX_FILTER_NONE;None +!TP_BWMIX_FILTER_PURPLE;Purple +!TP_BWMIX_FILTER_REDYELLOW;Red-Yellow +!TP_BWMIX_FILTER_RED;Red +!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. +!TP_BWMIX_FILTER_YELLOW;Yellow +!TP_BWMIX_GAMMA;Gamma Correction +!TP_BWMIX_GAM_TOOLTIP;Correct gamma for each RGB channel. +!TP_BWMIX_LABEL;Black-and-White +!TP_BWMIX_MET;Method +!TP_BWMIX_MET_CHANMIX;Channel Mixer +!TP_BWMIX_MET_DESAT;Desaturation +!TP_BWMIX_MET_LUMEQUAL;Luminance Equalizer +!TP_BWMIX_MIXC;Mixer +!TP_BWMIX_NEUTRAL;Reset mixer +!TP_BWMIX_NEUTRAL_TIP;Reset all values (Color Filter, Channel Mixer) to default. +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all the mixer options.\n"Total" displays the sum of the RGB values:\n- always 100% in relative mode\n- higher (lighter) or lower (darker) than 100% in absolute mode. +!TP_BWMIX_RGB_TOOLTIP;Mix the RGB channels. Use presets for guidance.\nPay attention to negative values that may cause artifacts or erratic behavior. +!TP_BWMIX_SETTING;Presets +!TP_BWMIX_SETTING_TOOLTIP;Different presets (film, landscape, etc.) or manual Channel Mixer settings. +!TP_BWMIX_SET_HIGHCONTAST;High contrast +!TP_BWMIX_SET_HIGHSENSIT;High Sensitivity +!TP_BWMIX_SET_HYPERPANCHRO;Hyper Panchromatic +!TP_BWMIX_SET_INFRARED;Infrared +!TP_BWMIX_SET_LANDSCAPE;Landscape +!TP_BWMIX_SET_LOWSENSIT;Low Sensitivity +!TP_BWMIX_SET_LUMINANCE;Luminance +!TP_BWMIX_SET_NORMCONTAST;Normal Contrast +!TP_BWMIX_SET_ORTHOCHRO;Orthochromatic +!TP_BWMIX_SET_PANCHRO;Panchromatic +!TP_BWMIX_SET_PORTRAIT;Portrait +!TP_BWMIX_SET_RGBABS;Absolute RGB +!TP_BWMIX_SET_RGBREL;Relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Relative ROYGCBPM +!TP_BWMIX_TCMODE_FILMLIKE;B&W Film-like +!TP_BWMIX_TCMODE_SATANDVALBLENDING;B&W Saturation and Value Blending +!TP_BWMIX_TCMODE_STANDARD;B&W Standard +!TP_BWMIX_TCMODE_WEIGHTEDSTD;B&W Weighted Standard +!TP_BWMIX_VAL;L +!TP_CHROMATABERR_LABEL;Chromatic Aberration +!TP_COLORAPP_ADAPTSCENE;Scene luminosity +!TP_COLORAPP_ADAPTSCENE_TOOLTIP;Absolute luminance of the scene environement (cd/m²).\n1) Calculated from the Exif data:\nShutter speed - ISO speed - F number - camera exposure correction.\n2) Calculated from the raw white point and RT's Exposure Compensation slider. +!TP_COLORAPP_ADAPTVIEWING;Viewing luminosity (cd/m²) +!TP_COLORAPP_ADAPTVIEWING_TOOLTIP;Absolute luminance of the viewing environnement\n(usually 16cd/m²). +!TP_COLORAPP_ADAP_AUTO_TOOLTIP;If the checkbox is checked (recommended) RawTherapee calculates an optimum value from Exif data.\nTo set the value manually, uncheck the checkbox first. +!TP_COLORAPP_ALGO;Algorithm +!TP_COLORAPP_ALGO_ALL;All +!TP_COLORAPP_ALGO_JC;Lightness + Chroma (JC) +!TP_COLORAPP_ALGO_JS;Lightness + Saturation (JS) +!TP_COLORAPP_ALGO_QM;Brightness + Colorfulness (QM) +!TP_COLORAPP_ALGO_TOOLTIP;Lets you choose between parameter subsets or all parameters. +!TP_COLORAPP_BADPIXSL;Hot/bad pixel filter +!TP_COLORAPP_BADPIXSL_TOOLTIP;Suppression of hot/bad (brightly colored) pixels.\n0 = No effect\n1 = Median\n2 = Gaussian.\nAlternatively, adjust the image to avoid very dark shadows.\n\nThese artifacts are due to limitations of CIECAM02. +!TP_COLORAPP_BRIGHT;Brightness (Q) +!TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from L*a*b* and RGB brightness. +!TP_COLORAPP_CHROMA;Chroma (C) +!TP_COLORAPP_CHROMA_M;Colorfulnes (M) +!TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM02 differs from L*a*b* and RGB colorfulness. +!TP_COLORAPP_CHROMA_S;Saturation (S) +!TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from L*a*b* and RGB saturation. +!TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from L*a*b* and RGB chroma. +!TP_COLORAPP_CIECAT_DEGREE;CAT02 adaptation +!TP_COLORAPP_CONTRAST;Contrast (J) +!TP_COLORAPP_CONTRAST_Q;Contrast (Q) +!TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrast in CIECAM02 for the Q slider; it differs from L*a*b* and RGB contrast. +!TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from L*a*b* and RGB contrast. +!TP_COLORAPP_CURVEEDITOR1;Tone curve 1 +!TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L* (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of J or Q after CIECAM02.\n\nJ and Q are not shown in the main histogram panel.\n\nFor final output refer to the main histogram panel. +!TP_COLORAPP_CURVEEDITOR2;Tone curve 2 +!TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Same usage as with the second exposure tone curve. +!TP_COLORAPP_CURVEEDITOR3;Color curve +!TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Adjust either chroma, saturation or colorfulness.\n\nShows the histogram of chromaticity (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of C, s or M after CIECAM02.\n\nC, s and M are not shown in the main histogram panel.\nFor final output refer to the main histogram panel. +!TP_COLORAPP_DATACIE;CIECAM02 output histograms in curves +!TP_COLORAPP_DATACIE_TOOLTIP;When enabled, histograms in CIECAM02 curves show approximate values/ranges for J or Q, and C, s or M after the CIECAM02 adjustments.\nThis selection does not impact the main histogram panel.\n\nWhen disabled, histograms in CIECAM02 curves show L*a*b* values before CIECAM02 adjustments. +!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RawTherapee calculates an optimum value, which is then used by CAT02, and also for the entire CIECAM02.\nTo set the value manually, uncheck the check-box first (values above 65 are recommended). +!TP_COLORAPP_DEGREE_TOOLTIP;Amount of CIE Chromatic Adaptation Transform 2002. +!TP_COLORAPP_GAMUT;Gamut control (L*a*b*) +!TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in L*a*b* mode. +!TP_COLORAPP_HUE;Hue (h) +!TP_COLORAPP_HUE_TOOLTIP;Hue (h) - angle between 0° and 360°. +!TP_COLORAPP_LABEL;CIE Color Appearance Model 2002 +!TP_COLORAPP_LABEL_CAM02;Image Adjustments +!TP_COLORAPP_LABEL_SCENE;Scene Conditions +!TP_COLORAPP_LABEL_VIEWING;Viewing Conditions +!TP_COLORAPP_LIGHT;Lightness (J) +!TP_COLORAPP_LIGHT_TOOLTIP;Lightness in CIECAM02 differs from L*a*b* and RGB lightness. +!TP_COLORAPP_MODEL;WP Model +!TP_COLORAPP_MODEL_TOOLTIP;White-Point Model.\n\nWB [RT] + [output]: RT's white balance is used for the scene, CIECAM02 is set to D50, and the output device's white balance is set in Preferences > Color Management.\n\nWB [RT+CAT02] + [output]: RT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences - Color Management. +!TP_COLORAPP_RSTPRO;Red & skin-tones protection +!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin-tones protection affects both sliders and curves. +!TP_COLORAPP_SHARPCIE;--unused-- +!TP_COLORAPP_SHARPCIE_TOOLTIP;--unused-- +!TP_COLORAPP_SURROUND;Surround +!TP_COLORAPP_SURROUND_AVER;Average +!TP_COLORAPP_SURROUND_DARK;Dark +!TP_COLORAPP_SURROUND_DIM;Dim +!TP_COLORAPP_SURROUND_EXDARK;Extremly Dark (Cutsheet) +!TP_COLORAPP_SURROUND_TOOLTIP;Changes tones and colors to take into account the viewing conditions of the output device.\n\nAverage: Average light environment (standard). The image will not change.\n\nDim: Dim environment (TV). The image will become slighty dark.\n\nDark: Dark environment (projector). The image will become more dark.\n\nExtremly Dark: Extremly dark environment (cutsheet). The image will become very dark. +!TP_COLORAPP_SURSOURCE;Dark surround +!TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if image has a dark border. +!TP_COLORAPP_TCMODE_BRIGHTNESS;Brightness +!TP_COLORAPP_TCMODE_CHROMA;Chroma +!TP_COLORAPP_TCMODE_COLORF;Colorfulness +!TP_COLORAPP_TCMODE_LABEL1;Curve mode 1 +!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_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] +!TP_COLORAPP_WBRT;WB [RT] + [output] +!TP_COLORTONING_AB;o C/L +!TP_COLORTONING_AUTOSAT;Automatic +!TP_COLORTONING_BALANCE;Balance +!TP_COLORTONING_BY;o C/L +!TP_COLORTONING_CHROMAC;Opacity +!TP_COLORTONING_COLOR;Color +!TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;Chroma opacity as a function of luminance oC=f(L) +!TP_COLORTONING_HIGHLIGHT;Highlights +!TP_COLORTONING_HUE;Hue +!TP_COLORTONING_LABEL;Color Toning +!TP_COLORTONING_LAB;L*a*b* blending +!TP_COLORTONING_LUMAMODE;Preserve luminance +!TP_COLORTONING_LUMAMODE_TOOLTIP;If enabled, when you change color (red, green, cyan, blue, etc.) the luminance of each pixel is preserved. +!TP_COLORTONING_LUMA;Luminance +!TP_COLORTONING_METHOD;Method +!TP_COLORTONING_METHOD_TOOLTIP;"L*a*b* blending", "RGB sliders" and "RGB curves" use interpolated color blending.\n"Color balance (Shadows/Midtones/Highlights)" and "Saturation 2 colors" use direct colors.\n\nThe Black-and-White tool can be enabled when using any color toning method, which allows for color toning. +!TP_COLORTONING_MIDTONES;Midtones +!TP_COLORTONING_NEUTRAL;Reset sliders +!TP_COLORTONING_NEUTRAL_TIP;Reset all values (Shadows, Midtones, Highlights) to default. +!TP_COLORTONING_OPACITY;Opacity +!TP_COLORTONING_RGBCURVES;RGB - Curves +!TP_COLORTONING_RGBSLIDERS;RGB - Sliders +!TP_COLORTONING_SATURATEDOPACITY;Strength +!TP_COLORTONING_SATURATIONTHRESHOLD;Threshold +!TP_COLORTONING_SA;Saturation Protection +!TP_COLORTONING_SHADOWS;Shadows +!TP_COLORTONING_SPLITCOCO;Color Balance Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITCO;Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITLR;Saturation 2 colors +!TP_COLORTONING_STRENGTH;Strength +!TP_COLORTONING_STR;Strength +!TP_COLORTONING_TWO2;Special chroma '2 colors' +!TP_COLORTONING_TWOALL;Special chroma +!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_GTFRAME;Frame +!TP_CROP_GTGRID;Grid +!TP_CROP_GTHARMMEANS;Harmonic Means +!TP_CROP_GTTRIANGLE1;Golden Triangles 1 +!TP_CROP_GTTRIANGLE2;Golden Triangles 2 +!TP_CROP_PPI;PPI= +!TP_DARKFRAME_AUTOSELECT;Auto-selection +!TP_DARKFRAME_LABEL;Dark-Frame +!TP_DEFRINGE_LABEL;Defringe +!TP_DEFRINGE_RADIUS;Radius +!TP_DEFRINGE_THRESHOLD;Threshold +!TP_DIRPYRDENOISE_33;3×3 strong +!TP_DIRPYRDENOISE_55SOFT;5×5 +!TP_DIRPYRDENOISE_55;5×5 strong +!TP_DIRPYRDENOISE_77;7×7 (slow) +!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_ABM;Chroma only +!TP_DIRPYRDENOISE_AUTO;Automatic global +!TP_DIRPYRDENOISE_AUTO_TOOLTIP;Try to evaluate chroma noise\nBe careful, this calculation is average, and is quite subjective ! +!TP_DIRPYRDENOISE_AUT;Automatic global +!TP_DIRPYRDENOISE_BLUE;Chrominance - Blue-Yellow +!TP_DIRPYRDENOISE_C2TYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CCCURVE;Chrominance curve +!TP_DIRPYRDENOISE_CHROMAFR;Chrominance +!TP_DIRPYRDENOISE_CTYPE;Auto method +!TP_DIRPYRDENOISE_CTYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nAutomatic multi-zones\nNo preview - works only during saving, but using the "Preview" method by matching the tile size and center to the preview size and center you can get an idea of the expected results.\nThe image is divided into tiles (about 10 to 70 depending on image size) and each tile receives its own chrominance noise reduction settings.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CURVEEDITOR_CC;Chroma +!TP_DIRPYRDENOISE_CURVEEDITOR_CC_TOOLTIP;Increase (multiply) the value of all chrominance sliders.\nThis curve lets you adjust the strength of chromatic noise reduction as a function of chromaticity, for instance to increase the action in areas of low saturation and to decrease it in those of high saturation. +!TP_DIRPYRDENOISE_CURVEEDITOR_L_TOOLTIP;Modulates action of 'Luminance' denoise +!TP_DIRPYRDENOISE_CUR;Curve +!TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on the gamma of the input color profile. An sRGB gamma is assumed, thus if the image uses an input color profile of a different gamma, the effects of luminance noise reduction will differ. +!TP_DIRPYRDENOISE_ENH;Enhanced mode +!TP_DIRPYRDENOISE_ENH_TOOLTIP;Increases noise reduction quality at the expense of a 20% processing time increase. +!TP_DIRPYRDENOISE_GAMMA_TOOLTIP;Gamma varies noise reduction strength across the range of tones. Smaller values will target shadows, while larger values will stretch the effect to the brighter tones. +!TP_DIRPYRDENOISE_LABM;L*a*b* +!TP_DIRPYRDENOISE_LCURVE;Luminance curve +!TP_DIRPYRDENOISE_LDETAIL;Luminance - Detail +!TP_DIRPYRDENOISE_LM;Luminance only +!TP_DIRPYRDENOISE_LPLABM;Weighted L* (little) + a*b* (normal) +!TP_DIRPYRDENOISE_LTYPE;Luminance control +!TP_DIRPYRDENOISE_LUMAFR;Luminance +!TP_DIRPYRDENOISE_LUMAFR_TOOLTIP;Wavelet on luminance and Fourier transform for luminance detail +!TP_DIRPYRDENOISE_MANU;Manual +!TP_DIRPYRDENOISE_MAN;Manual +!TP_DIRPYRDENOISE_MEDMETHOD;Median method +!TP_DIRPYRDENOISE_MEDTYPE;Median type +!TP_DIRPYRDENOISE_MED;Median Filter +!TP_DIRPYRDENOISE_MED_TOOLTIP;Enabled median denoising +!TP_DIRPYRDENOISE_METHOD11;Quality +!TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. +!TP_DIRPYRDENOISE_METHOD;Method +!TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or L*a*b* methods can be used.\n\nFor non-raw images the L*a*b* method will be used, regardless of the selection. +!TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - +!TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 +!TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. +!TP_DIRPYRDENOISE_PASSES;Median iterations +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PON;Auto multi-zones +!TP_DIRPYRDENOISE_PREVLABEL;Preview size=%1, Center: Px=%2 Py=%3 +!TP_DIRPYRDENOISE_PREV;Preview +!TP_DIRPYRDENOISE_PRE;Preview multi-zones +!TP_DIRPYRDENOISE_RED;Chrominance - Red-Green +!TP_DIRPYRDENOISE_RGBM;RGB +!TP_DIRPYRDENOISE_RGB;RGB +!TP_DIRPYRDENOISE_SHALBI;High +!TP_DIRPYRDENOISE_SHAL;Standard +!TP_DIRPYRDENOISE_SLI;Slider +!TP_DIRPYRDENOISE_SOFT;3x3 +!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_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;Auto Distortion Correction +!TP_DISTORTION_AUTO_TIP;Correct lens distortion automatically for some cameras (Micro 4/3, some compact digital cameras, etc.). +!TP_EPD_EDGESTOPPING;Edge stopping +!TP_EPD_GAMMA;Gamma +!TP_EPD_LABEL;Tone Mapping +!TP_EPD_REWEIGHTINGITERATES;Reweighting iterates +!TP_EPD_SCALE;Scale +!TP_EPD_STRENGTH;Strength +!TP_EPD_TOOLTIP;Tone mapping is possible in L*a*b* mode (standard) and CIECAM02 mode.\n\nWhen in L*a*b* mode, tone mapping can also be used on the residual image of the Wavelet Levels tool.\n\nTo engage CIECAM02 tone mapping mode enable the following settings:\n1. CIECAM02\n2. Algorithm="Brightness + Colorfulness (QM)"\n3. "Tone mapping using CIECAM02 brightness (Q)" +!TP_EXPOSURE_AUTOLEVELS_TIP;Toggles execution of Auto Levels to automatically set Exposure slider values based on an image analysis.\nEnables Highlight Reconstruction if necessary. +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in Auto Levels operation. +!TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Highlight compression threshold +!TP_EXPOSURE_CURVEEDITOR1;Tone curve 1 +!TP_EXPOSURE_CURVEEDITOR2;Tone curve 2 +!TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Please refer to the "Exposure > Tone Curves" RawPedia article to learn how to achieve the best results by using two tone curves. +!TP_EXPOSURE_SATURATION;Saturation +!TP_EXPOSURE_TCMODE_FILMLIKE;Film-like +!TP_EXPOSURE_TCMODE_LABEL1;Curve mode 1 +!TP_EXPOSURE_TCMODE_LABEL2;Curve mode 2 +!TP_EXPOSURE_TCMODE_LUMINANCE;Luminance +!TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Saturation and Value Blending +!TP_EXPOSURE_TCMODE_STANDARD;Standard +!TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard +!TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points +!TP_EXPOS_WHITEPOINT_LABEL;Raw White Points +!TP_FILMSIMULATION_LABEL;Film Simulation +!TP_FILMSIMULATION_STRENGTH;Strength +!TP_FILMSIMULATION_ZEROCLUTSFOUND;Set HaldCLUT directory in Preferences +!TP_FLATFIELD_AUTOSELECT;Auto-selection +!TP_FLATFIELD_BLURRADIUS;Blur radius +!TP_FLATFIELD_BLURTYPE;Blur type +!TP_FLATFIELD_BT_AREA;Area +!TP_FLATFIELD_BT_HORIZONTAL;Horizontal +!TP_FLATFIELD_BT_VERTHORIZ;Vertical + Horizontal +!TP_FLATFIELD_BT_VERTICAL;Vertical +!TP_FLATFIELD_CLIPCONTROL;Clip control +!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. +!TP_FLATFIELD_LABEL;Flat-Field +!TP_GAMMA_CURV;Gamma +!TP_GAMMA_FREE;Free gamma +!TP_GAMMA_OUTPUT;Output gamma +!TP_GAMMA_SLOP;Slope (linear) +!TP_GENERAL_11SCALE_TOOLTIP;The effects of this tool are only visible or only accurate at a preview scale of 1:1. +!TP_GRADIENT_CENTER;Center +!TP_GRADIENT_CENTER_X;Center X +!TP_GRADIENT_CENTER_X_TOOLTIP;Shift gradient to the left (negative values) or right (positive values). +!TP_GRADIENT_CENTER_Y;Center Y +!TP_GRADIENT_CENTER_Y_TOOLTIP;Shift gradient up (negative values) or down (positive values). +!TP_GRADIENT_DEGREE;Angle +!TP_GRADIENT_DEGREE_TOOLTIP;Rotation angle in degrees. +!TP_GRADIENT_FEATHER;Feather +!TP_GRADIENT_FEATHER_TOOLTIP;Gradient width in percent of the image diagonal. +!TP_GRADIENT_LABEL;Graduated Filter +!TP_GRADIENT_STRENGTH;Strength +!TP_GRADIENT_STRENGTH_TOOLTIP;Filter strength in stops. +!TP_HLREC_BLEND;Blend +!TP_HLREC_ENA_TOOLTIP;Could be activated by Auto Levels. +!TP_HSVEQUALIZER_CHANNEL;Channel +!TP_HSVEQUALIZER_HUE;H +!TP_HSVEQUALIZER_LABEL;HSV Equalizer +!TP_HSVEQUALIZER_SAT;S +!TP_HSVEQUALIZER_VAL;V +!TP_ICM_BLENDCMSMATRIX;Blend ICC highlights with matrix +!TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover clipped highlights when using LUT-based ICC profiles. +!TP_ICM_DCPILLUMINANT;Illuminant +!TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolated +!TP_ICM_DCPILLUMINANT_TOOLTIP;Select which embedded DCP illuminant to employ. Default is "interpolated" which is a mix between the two based on white balance. The setting is only enabled if a Dual-Illuminant DCP with interpolation support is selected. +!TP_ICM_INPUTCAMERAICC;Auto-matched camera profile +!TP_ICM_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input color profiles. These profiles are more precise than simpler matrix ones. They are not available for all cameras. These profiles are stored in the /iccprofiles/input and /dcpprofiles folders and are automatically retrieved based on a file name matching to the exact model name of the camera. +!TP_ICM_INPUTCAMERA_TOOLTIP;Use a simple color matrix from dcraw, an enhanced RawTherapee version (whichever is available based on camera model) or one embedded in the DNG. +!TP_ICM_INPUTCUSTOM_TOOLTIP;Select your own DCP/ICC color profile file for the camera. +!TP_ICM_INPUTEMBEDDED_TOOLTIP;Use color profile embedded in non-raw files. +!TP_ICM_INPUTNONE;No profile +!TP_ICM_INPUTNONE_TOOLTIP;Use no input color profile at all.\nUse only in special cases. +!TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance +!TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. The result can be used for calibration purposes and generation of a camera profile. +!TP_ICM_TONECURVE;Use DCP's tone curve +!TP_ICM_TONECURVE_TOOLTIP;Employ the embedded DCP tone curve. The setting is only enabled if the selected DCP has a tone curve. +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid color shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction. +!TP_LABCURVE_CHROMATICITY;Chromaticity +!TP_LABCURVE_CHROMA_TOOLTIP;To apply B&W toning, set Chromaticity to -100. +!TP_LABCURVE_CURVEEDITOR_A_RANGE1;Green Saturated +!TP_LABCURVE_CURVEEDITOR_A_RANGE2;Green Pastel +!TP_LABCURVE_CURVEEDITOR_A_RANGE3;Red Pastel +!TP_LABCURVE_CURVEEDITOR_A_RANGE4;Red Saturated +!TP_LABCURVE_CURVEEDITOR_B_RANGE1;Blue Saturated +!TP_LABCURVE_CURVEEDITOR_B_RANGE2;Blue Pastel +!TP_LABCURVE_CURVEEDITOR_B_RANGE3;Yellow Pastel +!TP_LABCURVE_CURVEEDITOR_B_RANGE4;Yellow Saturated +!TP_LABCURVE_CURVEEDITOR_CC;CC +!TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutral +!TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Dull +!TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastel +!TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Saturated +!TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Chromaticity according to chromaticity C=f(C) +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to hue C=f(H) +!TP_LABCURVE_CURVEEDITOR_CL;CL +!TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Chromaticity according to luminance C=f(L) +!TP_LABCURVE_CURVEEDITOR_HH;HH +!TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Hue according to hue H=f(H) +!TP_LABCURVE_CURVEEDITOR_LC;LC +!TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminance according to chromaticity L=f(C) +!TP_LABCURVE_CURVEEDITOR_LH;LH +!TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H) +!TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminance according to luminance L=f(L) +!TP_LABCURVE_LCREDSK;Restrict LC to red and skin-tones +!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_USECA;Chromatic aberration correction +!TP_LENSPROFILE_USEDIST;Distortion correction +!TP_LENSPROFILE_USEVIGN;Vignetting correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Resets exposure sliders to neutral values.\nApplies to the same controls that Auto Levels applies to, regardless of whether you used Auto Levels or not. +!TP_PCVIGNETTE_FEATHER;Feather +!TP_PCVIGNETTE_FEATHER_TOOLTIP;Feathering:\n0 = corners only,\n50 = halfway to center,\n100 = to center. +!TP_PCVIGNETTE_LABEL;Vignette Filter +!TP_PCVIGNETTE_ROUNDNESS;Roundness +!TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness:\n0 = rectangle,\n50 = fitted ellipse,\n100 = circle. +!TP_PCVIGNETTE_STRENGTH;Strength +!TP_PCVIGNETTE_STRENGTH_TOOLTIP;Filter strength in stops (reached in corners). +!TP_PFCURVE_CURVEEDITOR_CH;Hue +!TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Controls defringe strength by color.\nHigher = more,\nLower = less. +!TP_PREPROCESS_DEADPIXFILT;Dead pixel filter +!TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Tries to suppress dead pixels. +!TP_PREPROCESS_HOTPIXFILT;Hot pixel filter +!TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Tries to suppress hot pixels. +!TP_PREPROCESS_LABEL;Preprocessing +!TP_PREPROCESS_NO_FOUND;None found +!TP_RAWCACORR_CABLUE;Blue +!TP_RAWCACORR_CARED;Red +!TP_RAWEXPOS_BLACKS;Black Levels +!TP_RAWEXPOS_BLACK_0;Green 1 (lead) +!TP_RAWEXPOS_BLACK_1;Red +!TP_RAWEXPOS_BLACK_2;Blue +!TP_RAWEXPOS_BLACK_3;Green 2 +!TP_RAWEXPOS_BLACK_BLUE;Blue +!TP_RAWEXPOS_BLACK_GREEN;Green +!TP_RAWEXPOS_BLACK_RED;Red +!TP_RAWEXPOS_LINEAR;White-point correction +!TP_RAWEXPOS_PRESER;Highlight preservation +!TP_RAWEXPOS_RGB;Red, Green, Blue +!TP_RAWEXPOS_TWOGREEN;Link greens +!TP_RAW_DMETHOD_PROGRESSBAR;%1 demosaicing... +!TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Demosaicing refinement... +!TP_RAW_DMETHOD_TOOLTIP;Note: IGV and LMMSE are dedicated to high ISO images to aid in noise reduction without leading to maze patterns, posterization or a washed-out look. +!TP_RAW_HD;Threshold +!TP_RAW_HD_TOOLTIP;Lower values make hot/dead pixel detection more aggressive, but false positives may lead to artifacts. If you notice any artifacts appearing when enabling the Hot/Dead Pixel Filters, gradually increase the threshold value until they disappear. +!TP_RAW_LABEL;Demosaicing +!TP_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!TP_RAW_LMMSE_TOOLTIP;Adds gamma (step 1), median (steps 2-4) and refinement (steps 5-6) to reduce artifacts and improve the signal-to-noise ratio. +!TP_RAW_SENSOR_BAYER_LABEL;Sensor with Bayer Matrix +!TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;3-pass gives best results (recommended for low ISO images).\n1-pass is almost undistinguishable from 3-pass for high ISO images and is faster. +!TP_RAW_SENSOR_XTRANS_LABEL;Sensor with X-Trans Matrix +!TP_RESIZE_APPLIESTO;Applies to: +!TP_RESIZE_CROPPEDAREA;Cropped Area +!TP_RESIZE_FITBOX;Bounding Box +!TP_RESIZE_FULLIMAGE;Full Image +!TP_RESIZE_LANCZOS;Lanczos +!TP_RGBCURVES_BLUE;B +!TP_RGBCURVES_CHANNEL;Channel +!TP_RGBCURVES_GREEN;G +!TP_RGBCURVES_LABEL;RGB Curves +!TP_RGBCURVES_LUMAMODE;Luminosity mode +!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_RGBCURVES_RED;R +!TP_SAVEDIALOG_OK_TIP;Shortcut: Ctrl-Enter +!TP_SHADOWSHLIGHTS_SHARPMASK;Sharp mask +!TP_SHARPENEDGE_AMOUNT;Quantity +!TP_SHARPENEDGE_LABEL;Edges +!TP_SHARPENEDGE_PASSES;Iterations +!TP_SHARPENEDGE_THREE;Luminance only +!TP_SHARPENING_TOOLTIP;Expect a slightly different effect when using with CIECAM02. If difference is observed, adjust to taste. +!TP_SHARPENMICRO_AMOUNT;Quantity +!TP_SHARPENMICRO_LABEL;Microcontrast +!TP_SHARPENMICRO_MATRIX;3×3 matrix instead of 5×5 +!TP_SHARPENMICRO_UNIFORMITY;Uniformity +!TP_VIBRANCE_AVOIDCOLORSHIFT;Avoid color shift +!TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Red/Purple +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Red +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Red/Yellow +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Yellow +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Hue according to hue H=f(H) +!TP_VIBRANCE_LABEL;Vibrance +!TP_VIBRANCE_PASTELS;Pastel Tones +!TP_VIBRANCE_PASTSATTOG;Link pastel and saturated tones +!TP_VIBRANCE_PROTECTSKINS;Protect skin-tones +!TP_VIBRANCE_PSTHRESHOLD;Pastel/saturated tones threshold +!TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Saturation threshold +!TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;The vertical axis represents pastel tones at the bottom and saturated tones at the top.\nThe horizontal axis represents the saturation range. +!TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Pastel/saturated transition's weighting +!TP_VIBRANCE_SATURATED;Saturated Tones +!TP_VIGNETTING_CENTER;Center +!TP_VIGNETTING_CENTER_X;Center X +!TP_VIGNETTING_CENTER_Y;Center Y +!TP_VIGNETTING_STRENGTH;Strength +!TP_WAVELET_1;Level 1 +!TP_WAVELET_2;Level 2 +!TP_WAVELET_3;Level 3 +!TP_WAVELET_4;Level 4 +!TP_WAVELET_5;Level 5 +!TP_WAVELET_6;Level 6 +!TP_WAVELET_7;Level 7 +!TP_WAVELET_8;Level 8 +!TP_WAVELET_9;Level 9 +!TP_WAVELET_ALL;All levels in all directions +!TP_WAVELET_APPLYTO;Apply To +!TP_WAVELET_AVOID;Avoid color shift +!TP_WAVELET_B0;Black +!TP_WAVELET_B1;Grey +!TP_WAVELET_B2;Residual +!TP_WAVELET_BACUR;Curve +!TP_WAVELET_BALANCE;Contrast balance d/v-h +!TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chromaticity or residual tone mapping are activated, the effect due to balance is amplified. +!TP_WAVELET_BALCHRO;Chroma balance +!TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chromaticity balance. +!TP_WAVELET_BANONE;None +!TP_WAVELET_BASLI;Slider +!TP_WAVELET_BATYPE;Contrast balance method +!TP_WAVELET_CCURVE;Local contrast +!TP_WAVELET_CH1;Whole chromaticity range +!TP_WAVELET_CH2;Saturated/pastel +!TP_WAVELET_CH3;Link contrast levels +!TP_WAVELET_CHCU;Curve +!TP_WAVELET_CHRO;Saturated/pastel threshold +!TP_WAVELET_CHRO_TOOLTIP;Sets the wavelet level which will be the threshold between saturated and pastel colors.\n1-x: saturated\nx-9: pastel\n\nIf the value exceeds the amount of wavelet levels you are using then it will be ignored. +!TP_WAVELET_CHR;Chroma-contrast link strength +!TP_WAVELET_CHR_TOOLTIP;Adjusts chromaticity as a function of "contrast levels" and "chroma-contrast link strength" +!TP_WAVELET_CHSL;Sliders +!TP_WAVELET_CHTYPE;Chrominance method +!TP_WAVELET_COLORT;Opacity Red-Green +!TP_WAVELET_COMBOTH;Both +!TP_WAVELET_COMPCONT;Contrast +!TP_WAVELET_COMPGAMMA;Compression gamma +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjusting the gamma of the residual image allow you to equilibrate the data and histogram. +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjust gamma for residual image and compression.\nAllow to equilibrate data and histogram +!TP_WAVELET_COMPTM;Tone mapping +!TP_WAVELET_CONTEDIT;'After' Contrast curve +!TP_WAVELET_CONTEDIT;'After' contrast curve +!TP_WAVELET_CONTRAST_MINUS;Contrast - +!TP_WAVELET_CONTRAST_PLUS;Contrast + +!TP_WAVELET_CONTRA;Contrast +!TP_WAVELET_CONTRA_TOOLTIP;Changes contrast of the residual image. +!TP_WAVELET_CONTR;Gamut +!TP_WAVELET_CTYPE;Chrominance control +!TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modifies local contrast as a function of the original local contrast (absciss)\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 100..300)\n66% absciss represents standard deviation of local contrast (real value about 300..800)\n100% represents maximum (real value about 3000..8000) +!TP_WAVELET_CURVEEDITOR_CH;Contrast levels=f(Hue) +!TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modifies each level's contrast as a function oh hue.\nTake care not to overwrite changes made with the Gamut Hue controls.\nThe curve will only have an effect when wavelet contrast level sliders are non-zero. +!TP_WAVELET_CURVEEDITOR_CL;L +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Applies a final contrast luminance curve at the end of the wavelet treatment. +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Apply a contrast luminance curve at the end of wavelet level threatment +!TP_WAVELET_CURVEEDITOR_HH;HH +!TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modifies the residual image's hue as a function of hue. +!TP_WAVELET_DALL;All directions +!TP_WAVELET_DAUB;Edge performance +!TP_WAVELET_DAUB_TOOLTIP;Changes Daubechies coefficients:\nD4 = Standard,\nD14 = Often best performance, 10% more time-intensive.\n\nAffects edge detection as well as the general quality of the firsts levels. However the quality is not strictly related to this coefficient and can vary with images and uses. +!TP_WAVELET_DISP;Preview Settings +!TP_WAVELET_DONE;Vertical +!TP_WAVELET_DTHR;Diagonal +!TP_WAVELET_DTWO;Horizontal +!TP_WAVELET_EDCU;Curve +!TP_WAVELET_EDGCONT;Local contrast +!TP_WAVELET_EDGCONT_TOOLTIP;Adjusting the points to the left decreases contrast, and to the right increases it.\nBottom-left, Top-Left, Top-Right, Bottom-right represent respectively local contast for low values, mean, mean+stdev, maxima +!TP_WAVELET_EDGEDETECTTHR2;Threshold high (detection) +!TP_WAVELET_EDGEDETECTTHR;Threshold low (noise) +!TP_WAVELET_EDGEDETECTTHR_TOOLTIP;This adjuster lets you target edge detection for example to avoid applying edge sharpness to fine details, such as noise in the sky. +!TP_WAVELET_EDGEDETECT;Gradient sensitivity +!TP_WAVELET_EDGEDETECT_TOOLTIP;Moving the slider to the right increases edge sensitivity. This affects local contrast, edge settings and noise. +!TP_WAVELET_EDGE;Edge Sharpness +!TP_WAVELET_EDGREINF_TOOLTIP;Reinforce or reduce the action of the first level, do the opposite to the second level, and leave the rest unchanged. +!TP_WAVELET_EDGTHRESH;Detail +!TP_WAVELET_EDGTHRESH_TOOLTIP;Change the repartition between the first levels and the others. The higher the threshold the more the action is centred on the first levels. Be careful with negative values, they increase the action of high levels and can introduce artifacts. +!TP_WAVELET_EDRAD;Radius +!TP_WAVELET_EDRAD_TOOLTIP;This radius adjustment is very different from those in other sharpening tools. Its value is compared to each level through a complex function. In this sense, a value of zero still has an effect. +!TP_WAVELET_EDSL;Threshold Sliders +!TP_WAVELET_EDTYPE;Local contrast method +!TP_WAVELET_EDVAL;Strength +!TP_WAVELET_FINAL;Final Touchup +!TP_WAVELET_FINEST;Finest +!TP_WAVELET_HIGHLIGHT;Highlight luminance range +!TP_WAVELET_HS1;Whole luminance range +!TP_WAVELET_HS2;Shadows/Highlights +!TP_WAVELET_HUESKIN;Skin hue +!TP_WAVELET_HUESKIN_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_HUESKY;Sky hue +!TP_WAVELET_HUESKY_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_INF;Below or equal the level +!TP_WAVELET_ITER;Delta balance levels +!TP_WAVELET_ITER_TOOLTIP;Left: increase low levels and reduce high levels,\nRight: reduce low levels and increase high levels. +!TP_WAVELET_LABEL;Wavelet levels +!TP_WAVELET_LARGEST;Coarsest +!TP_WAVELET_LEVCH;Chromaticity +!TP_WAVELET_LEVELS;Wavelet levels +!TP_WAVELET_LEVELS_TOOLTIP;Choose the number of detail levels the image is to be decomposed into. More levels require more RAM and require a longer processing time. +!TP_WAVELET_LEVF;Contrast +!TP_WAVELET_LEVLABEL;Preview maximum possible levels = %1 +!TP_WAVELET_LEVONE;Level 2 +!TP_WAVELET_LEVTWO;Level 3 +!TP_WAVELET_LEVZERO;Level 1 +!TP_WAVELET_LINKEDG;Link with Edge Sharpness' Strength +!TP_WAVELET_LIPST;Enhanced algorithm +!TP_WAVELET_LIPST_TOOLTIP;This algorithm uses Lipschitz regularity to increase edge detection quality at a cost of increased processing time and memory requirements. +!TP_WAVELET_LOWLIGHT;Shadow luminance range +!TP_WAVELET_MEDGREINF;First level +!TP_WAVELET_MEDILEV;Edge detection +!TP_WAVELET_MEDI;Reduce artifacts in blue sky +!TP_WAVELET_NEUTRAL;Neutral +!TP_WAVELET_NOISE;Denoise and Refine +!TP_WAVELET_NOIS;Denoise +!TP_WAVELET_ONE;One level +!TP_WAVELET_OPACITYWL;Final local contrast +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify final local contrast in function of last local contrast (absciss) for all levels decomposition\nTake into account: \na)contrast levels \nb)edge sharpness \nc)contrast balance\nd)decomposition-recomposition\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 200..1000)\n66% absciss represents standard deviation of local contrast (real value about 1000..2000)\n100% represents maximum (real value about 5000..13000) +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify the final local contrast at the end of the wavelet treatment.\n\nThe left side represents the smallest local contrast, progressing to the largest local contrast on the right. +!TP_WAVELET_OPACITYW;Contrast balance d/v-h curve +!TP_WAVELET_OPACITY;Opacity Blue-Yellow +!TP_WAVELET_PASTEL;Pastel chromaticity +!TP_WAVELET_PREVIEWBACK;Background +!TP_WAVELET_PREVIEWLEVELS;Preview +!TP_WAVELET_RE1;Reinforced +!TP_WAVELET_RE2;Unchanged +!TP_WAVELET_RE3;Reduced +!TP_WAVELET_RESCHRO;Chromaticity +!TP_WAVELET_RESCONH;Highlights +!TP_WAVELET_RESCON;Shadows +!TP_WAVELET_RESID;Residual image +!TP_WAVELET_SAT;Saturated chromaticity +!TP_WAVELET_SETTINGS;Wavelet Settings +!TP_WAVELET_SKIN;Skin targetting/protection +!TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected. +!TP_WAVELET_SKY;Sky targetting/protection +!TP_WAVELET_SKY_TOOLTIP;At -100 sky-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 sky-tones are protected while all other tones are affected. +!TP_WAVELET_STRENGTH;Strength +!TP_WAVELET_STREN;Strength +!TP_WAVELET_SUPE;Extra +!TP_WAVELET_SUP;Above the level +!TP_WAVELET_THRESHOLD2;Shadow levels +!TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels between 9 and 9 minus the value will be affected by the shadow luminance range. Other levels will be fully treated. The highest level possible is limited by the highlight level value (9 minus highlight level value). +!TP_WAVELET_THRESHOLD;Highlight levels +!TP_WAVELET_THRESHOLD_TOOLTIP;Only levels beyond the chosen value will be affected by the highlight luminance range. Other levels will be fully treated. The chosen value here limits the highest possible value of the shadow levels. +!TP_WAVELET_THRH;Highlights threshold +!TP_WAVELET_THR;Shadows threshold +!TP_WAVELET_TILESBIG;Big tiles +!TP_WAVELET_TILESFULL;Full image +!TP_WAVELET_TILESIZE;Tiling method +!TP_WAVELET_TILESLIT;Little tiles +!TP_WAVELET_TILES_TOOLTIP;Processing the full image leads to better quality and is the recommended option, while using tiles is a fall-back solution for users with little RAM. Refer to RawPedia for memory requirements. +!TP_WAVELET_TMHIGH;High +!TP_WAVELET_TMLOWHIGH;Low+High +!TP_WAVELET_TMNONE;None +!TP_WAVELET_TMSTD;Standard +!TP_WAVELET_TMSTRENGTH;Compression strength +!TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image. When the value is different from 0, the Strength and Gamma sliders of the Tone Mapping tool in the Exposure tab will become grayed out. +!TP_WAVELET_TMTYPE;Compression method +!TP_WAVELET_TON;Toning +!TP_WAVELET_daub2;D2 - low +!TP_WAVELET_daub4;D4 - standard +!TP_WAVELET_daub6;D6 - standard plus +!TP_WAVELET_daub10;D10 - medium +!TP_WAVELET_daub14;D14 - high +!TP_WBALANCE_CLOUDY;Cloudy +!TP_WBALANCE_DAYLIGHT;Daylight (sunny) +!TP_WBALANCE_EQBLUERED;Blue/Red equalizer +!TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behavior of "white balance" by modulating the blue/red balance.\nThis can be useful when shooting conditions:\na) are far from the standard illuminant (e.g. underwater),\nb) are far from conditions where calibrations were performed,\nc) where the matrices or ICC profiles are unsuitable. +!TP_WBALANCE_FLASH55;Leica +!TP_WBALANCE_FLASH60;Standard, Canon, Pentax, Olympus +!TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta +!TP_WBALANCE_FLASH_HEADER;Flash +!TP_WBALANCE_FLUO1;F1 - Daylight +!TP_WBALANCE_FLUO2;F2 - Cool White +!TP_WBALANCE_FLUO3;F3 - White +!TP_WBALANCE_FLUO4;F4 - Warm White +!TP_WBALANCE_FLUO5;F5 - Daylight +!TP_WBALANCE_FLUO6;F6 - Lite White +!TP_WBALANCE_FLUO7;F7 - D65 Daylight Simulator +!TP_WBALANCE_FLUO8;F8 - D50 / Sylvania F40 Design +!TP_WBALANCE_FLUO9;F9 - Cool White Deluxe +!TP_WBALANCE_FLUO10;F10 - Philips TL85 +!TP_WBALANCE_FLUO11;F11 - Philips TL84 +!TP_WBALANCE_FLUO12;F12 - Philips TL83 +!TP_WBALANCE_FLUO_HEADER;Fluorescent +!TP_WBALANCE_GTI;GTI +!TP_WBALANCE_HMI;HMI +!TP_WBALANCE_JUDGEIII;JudgeIII +!TP_WBALANCE_LAMP_HEADER;Lamp +!TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 +!TP_WBALANCE_LED_HEADER;LED +!TP_WBALANCE_LED_LSI;LSI Lumelex 2040 +!TP_WBALANCE_SHADE;Shade +!TP_WBALANCE_SOLUX35;Solux 3500K +!TP_WBALANCE_SOLUX41;Solux 4100K +!TP_WBALANCE_SOLUX47;Solux 4700K (vendor) +!TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) +!TP_WBALANCE_TUNGSTEN;Tungsten +!TP_WBALANCE_WATER1;UnderWater 1 +!TP_WBALANCE_WATER2;UnderWater 2 +!TP_WBALANCE_WATER_HEADER;UnderWater +!ZOOMPANEL_ZOOMFITCROPSCREEN;Fit crop to screen\nShortcut: Alt-f diff --git a/rtdata/languages/Suomi b/rtdata/languages/Suomi new file mode 100644 index 000000000..701acede6 --- /dev/null +++ b/rtdata/languages/Suomi @@ -0,0 +1,1857 @@ +#01 2009-05-03 T. Kauppinen + +ADJUSTER_RESET_TO_DEFAULT;Palauta oletusasetukset +CURVEEDITOR_LINEAR;Suora +CURVEEDITOR_LOADDLGLABEL;Lataa käyrä... +CURVEEDITOR_SAVEDLGLABEL;Tallenna käyrä... +CURVEEDITOR_TOOLTIPLINEAR;Palauta suoraksi +CURVEEDITOR_TOOLTIPLOAD;Lataa käyrä tiedostosta +CURVEEDITOR_TOOLTIPSAVE;Tallenna käyrä +DIRBROWSER_FOLDERS;Kansiot +EXIFFILTER_APERTURE;Aukko +EXIFFILTER_CAMERA;Kamera +EXIFFILTER_FOCALLEN;Polttoväli +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Objektiivi +EXIFFILTER_SHUTTER;Suljinaika +EXIFPANEL_ADDEDITHINT;Lisää uusi EXIF-tieto tai muokkaa olemassaolevaa +EXIFPANEL_ADDEDIT;Lisää/Muokkaa +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Uusi arvo +EXIFPANEL_ADDTAGDLG_SELECTTAG;Valitse +EXIFPANEL_ADDTAGDLG_TITLE;Lisää/Muokkaa +EXIFPANEL_KEEPHINT;Pidä valitut tallennettaessa +EXIFPANEL_KEEP;Pidä +EXIFPANEL_REMOVEHINT;Poista valitut tallennettaessa +EXIFPANEL_REMOVE;Poista +EXIFPANEL_RESETALLHINT;Palauta kaikki alkuperäisiksi +EXIFPANEL_RESETALL;Palauta kaikki +EXIFPANEL_RESETHINT;Palauta valitut alkuperäisiksi +EXIFPANEL_RESET;Palauta +EXIFPANEL_SUBDIRECTORY;Alihakemisto +FILEBROWSER_APPLYPROFILE;Käytä profiilia +FILEBROWSER_CLEARPROFILE;Tyhjennä profiili +FILEBROWSER_COPYPROFILE;Kopioi profiili +FILEBROWSER_DELETEDLGLABEL;Tiedostojen poisto +FILEBROWSER_DELETEDLGMSG;Haluatko varmasti poistaa valitut %1 tiedostoa? +FILEBROWSER_EMPTYTRASHHINT;Poistaa pysyvästi tiedostot roskakorista +FILEBROWSER_EMPTYTRASH;Tyhjennä roskakori +FILEBROWSER_PARTIALPASTEPROFILE;Liitä valiten.. +FILEBROWSER_PASTEPROFILE;Liitä profiili +FILEBROWSER_POPUPCANCELJOB;Peruuta työ +FILEBROWSER_POPUPMOVEEND;Siirrä jonon viimeiseksi +FILEBROWSER_POPUPMOVEHEAD;Siirrä jonon ensimmäiseksi +FILEBROWSER_POPUPOPENINEDITOR;Avaa Editor +FILEBROWSER_POPUPOPEN;Avaa +FILEBROWSER_POPUPPROCESS;Laita käsittelyjonoon +FILEBROWSER_POPUPREMOVE;Poista kokonaan +FILEBROWSER_POPUPRENAME;Nimeä uudelleen.. +FILEBROWSER_POPUPSELECTALL;Valitse kaikki +FILEBROWSER_POPUPTRASH;Siirrä roskakoriin +FILEBROWSER_POPUPUNRANK;Poista arvostelu +FILEBROWSER_POPUPUNTRASH;Pelasta roskakorista +FILEBROWSER_RENAMEDLGLABEL;Nimeä uudelleen +FILEBROWSER_RENAMEDLGMSG;Tiedoston "%1" uusi nimi: +FILEBROWSER_SHOWDIRHINT;Näytä hakemiston kaikki kuvat +FILEBROWSER_SHOWRANK1HINT;Näytä 1 tähden kuvat +FILEBROWSER_SHOWRANK2HINT;Näytä 2 tähden kuvat +FILEBROWSER_SHOWRANK3HINT;Näytä 3 tähden kuvat +FILEBROWSER_SHOWRANK4HINT;Näytä 4 tähden kuvat +FILEBROWSER_SHOWRANK5HINT;Näytä 5 tähden kuvat +FILEBROWSER_SHOWTRASHHINT;Näytä roskakorin sisältö +FILEBROWSER_SHOWUNRANKHINT;Näytä arvostelemattomat kuvat +FILEBROWSER_STARTPROCESSINGHINT;Aloita jonossa olevien kuvien käsittely +FILEBROWSER_STARTPROCESSING;Aloita käsittely +FILEBROWSER_STOPPROCESSINGHINT;Lopeta jonossa olevien kuvien käsittely +FILEBROWSER_STOPPROCESSING;Lopeta käsittely +FILEBROWSER_THUMBSIZE;Esikatselun koko +FILEBROWSER_ZOOMINHINT;Kasvata esikatselukuvien kokoa +FILEBROWSER_ZOOMOUTHINT;Pienennä esikatselukuvien kokoa +GENERAL_ABOUT;Tietoja +GENERAL_CANCEL;Peruuta +GENERAL_DISABLED;Pois +GENERAL_DISABLE;Pois +GENERAL_ENABLED;Päällä +GENERAL_ENABLE;Päälle +GENERAL_LANDSCAPE;Vaaka +GENERAL_NA;- +GENERAL_NO;Ei +GENERAL_OK;OK +GENERAL_PORTRAIT;Pysty +GENERAL_SAVE;Tallenna +HISTOGRAM_TOOLTIP_B;Näytä/piilota SININEN +HISTOGRAM_TOOLTIP_G;Näytä/piilota VIHREÄ +HISTOGRAM_TOOLTIP_L;Näytä/piilota CIELAB luminanssi +HISTOGRAM_TOOLTIP_R;Näytä/piilota PUNAINEN +HISTORY_CHANGED;Muutettu +HISTORY_CUSTOMCURVE;Oma käyrä +HISTORY_DELSNAPSHOT;Poista pikakuva +HISTORY_FROMCLIPBOARD;Leikepöydältä +HISTORY_LABEL;Historia +HISTORY_MSG_1;Kuva ladattu +HISTORY_MSG_2;Profiili ladattu +HISTORY_MSG_3;Profiili vaihdettu +HISTORY_MSG_4;Historian selaus +HISTORY_MSG_5;Valotus\nKirkkaus +HISTORY_MSG_6;Valotus\nKontrasti +HISTORY_MSG_7;Valotus\nTummuus +HISTORY_MSG_8;Valotus\nKompensointi +HISTORY_MSG_9;Valotus\nVaaleiden alueiden vaimennus +HISTORY_MSG_10;Valotuksen säätö\nTummien alueiden vaimennus +HISTORY_MSG_11;Valotuksen säätö\nSävykäyrä +HISTORY_MSG_12;Valotuksen säätö\nAutomaattinen +HISTORY_MSG_13;Valotuksen säätö\nAutomaattisen valotuksen raja +HISTORY_MSG_14;Luminanssi\nKirkkaus +HISTORY_MSG_15;Luminanssi\nKontrasti +HISTORY_MSG_16;Luminanssi\nTummuus +HISTORY_MSG_17;Luminanssi\nVaaleiden alueiden vaimennus +HISTORY_MSG_18;Luminanssi\nTummien alueiden vaimennus +HISTORY_MSG_19;Luminanssi\nKäyrä +HISTORY_MSG_20;Terävöinti +HISTORY_MSG_21;Terävöinti\nEpäterävä maski: Säde +HISTORY_MSG_22;Terävöinti\nEpäterävä maski: Määrä +HISTORY_MSG_23;Terävöinti\nEpäterävä maski: Kynnys +HISTORY_MSG_24;Terävöinti\nEpäterävä maski: Vain reunat +HISTORY_MSG_25;Terävöinti\nEpäterävä maski: Reunatunnistuksen säde +HISTORY_MSG_26;Terävöinti\nEpäterävä maski: Reunatunnistuksen herkkyys +HISTORY_MSG_27;Terävöinti\nEpäterävä maski: Halo-ilmiön esto +HISTORY_MSG_28;Terävöinti\nEpäterävä maski: Halo-ilmiön eston määrä +HISTORY_MSG_29;Terävöinti\nMenetelmä +HISTORY_MSG_30;Terävöinti\nDekonvoluutio: Säde +HISTORY_MSG_31;Terävöinti\nDekonvoluutio: Määrä +HISTORY_MSG_32;Terävöinti\nDekonvoluutio: Vaimennus +HISTORY_MSG_33;Terävöinti\nDekonvoluutio: Iteraatiot +HISTORY_MSG_34;Värikylläisyys\nVältä leikkautuminen +HISTORY_MSG_35;Värikylläisyys\nEstä kyllästyminen +HISTORY_MSG_36;Värikylläisyys\nKyllästymisraja +HISTORY_MSG_37;Värikylläisyys +HISTORY_MSG_38;Valkotasapaino\nMenetelmä +HISTORY_MSG_39;Valkotasapaino\nLämpötila [K] +HISTORY_MSG_40;Valkotasapaino\nValkoisen sävy +HISTORY_MSG_41;Värisävy\nvihreä-punainen +HISTORY_MSG_42;Värisävy\nsininen-keltainen +HISTORY_MSG_43;Luminanssin kohinanvaimennus +HISTORY_MSG_44;Luminanssin kohinanvaimennus\nSäde +HISTORY_MSG_45;Luminanssin kohinanvaimennus\nReunan tunnistusherkkyys +HISTORY_MSG_46;Värin kohinanvaimennus +HISTORY_MSG_47;Värin kohinanvaimennus\nSäde +HISTORY_MSG_48;Värin kohinanvaimennus\nReunan tunnistusherkkyys +HISTORY_MSG_49;Värin kohinanvaimennus\nReunaherkkä +HISTORY_MSG_50;Tummat/vaaleat alueet +HISTORY_MSG_51;Tummat/vaaleat alueet\nVaaleiden alueiden vaimennus +HISTORY_MSG_52;Tummat/vaaleat alueet\nTummien alueiden vaimennus +HISTORY_MSG_53;Tummat/vaaleat alueet\nVaalean sävyalueen laajuus +HISTORY_MSG_54;Tummat/vaaleat alueet\nTumman sävyalueen laajuus +HISTORY_MSG_55;Tummat/vaaleat alueet\nPaikallinen kontrasti +HISTORY_MSG_56;Tummat/vaaleat alueet\nSäde +HISTORY_MSG_57;Kääntö +HISTORY_MSG_58;Peilaa vaakasuunnassa +HISTORY_MSG_59;Peilaa pystysuunnassa +HISTORY_MSG_60;Oikaisu +HISTORY_MSG_61;Kääntö +HISTORY_MSG_62;Linssivääristymän korjaus +HISTORY_MSG_63;Pikakuva valittu +HISTORY_MSG_64;Rajaus +HISTORY_MSG_65;Värivääristymän korjaus +HISTORY_MSG_66;Huippuvaloalueiden palautus +HISTORY_MSG_67;Huippuvaloalueiden palautus\nMäärä +HISTORY_MSG_68;Huippuvaloalueiden palautus\nMenetelmä +HISTORY_MSG_69;Työväriprofiili +HISTORY_MSG_70;Tulosväriprofiili +HISTORY_MSG_71;Lähdeväriprofiili +HISTORY_MSG_72;Vinjetoinnin korjaus +HISTORY_MSG_73;Kanavat +HISTORY_MSG_74;Koko +HISTORY_MSG_75;Koko\nMenetelmä +HISTORY_MSG_76;EXIF-tiedot +HISTORY_MSG_77;IPTC-tiedot +HISTORY_MSG_78;Data specified for resize +HISTORY_MSG_79;Resize width +HISTORY_MSG_80;Resize height +HISTORY_MSG_81;Resize enabled +HISTORY_NEWSNAPSHOT;Uusi pikakuva +HISTORY_SNAPSHOTS;Pikakuvat +HISTORY_SNAPSHOT;Pikakuva +IPTCPANEL_AUTHORSPOSITIONHINT;(Author position) Kuvaajan titteli. +IPTCPANEL_AUTHORSPOSITION;Kuvaajan titteli +IPTCPANEL_AUTHOR;Kuvaaja +IPTCPANEL_CAPTIONHINT;(Caption) Kuvaus kohteesta. +IPTCPANEL_CAPTIONWRITERHINT;(Caption Writer) Kuvauksen kirjoittajan nimi. +IPTCPANEL_CAPTIONWRITER;Kuvauksen kirjoittaja +IPTCPANEL_CAPTION;Aihe +IPTCPANEL_CATEGORYHINT;(Category) Aiheryhmän 3-kirjaiminen koodi. +IPTCPANEL_CATEGORY;Aiheryhmä +IPTCPANEL_CITYHINT;(City) Kaupunki jossa kuva on otettu. +IPTCPANEL_CITY;Kaupunki +IPTCPANEL_COPYHINT;Kopioi IPTC tiedot leikepöydälle +IPTCPANEL_COPYRIGHTHINT;(Copyright) Tekijänoikeustiedot. +IPTCPANEL_COPYRIGHT;Tekijänoikeudet +IPTCPANEL_COUNTRYHINT;(Country) Maa jossa kuva on otettu. +IPTCPANEL_COUNTRY;Maa +IPTCPANEL_CREDITHINT;(Credit) Välittäjän tiedot. +IPTCPANEL_CREDIT;Välittäjä +IPTCPANEL_DATECREATEDHINT;(Date Created) Päivämäärä jolloin kuva on otettu. +IPTCPANEL_DATECREATED;Päivämäärä +IPTCPANEL_EMBEDDEDHINT;Palauta kuvan IPTC tiedot +IPTCPANEL_EMBEDDED;Kuvan oma +IPTCPANEL_HEADLINEHINT;(Headline) Julkaistava otsikko. +IPTCPANEL_HEADLINE;Julkaistava otsikko +IPTCPANEL_INSTRUCTIONSHINT;(Instructions) Ohjeet ja rajoitukset. +IPTCPANEL_INSTRUCTIONS;Ohjeet +IPTCPANEL_KEYWORDSHINT;(Keywords) Kohdetta kuvaavia avainsanoja. +IPTCPANEL_KEYWORDS;Avainsanat +IPTCPANEL_PASTEHINT;Liitä IPTC tiedot leikepöydältä +IPTCPANEL_PROVINCEHINT;(Province) Maakunta jossa kuva on otettu. +IPTCPANEL_PROVINCE;Maakunta +IPTCPANEL_RESETHINT;Palauta profiilin oletukseen +IPTCPANEL_RESET;Palauta +IPTCPANEL_SOURCEHINT;(Source) Kuvan lähde. +IPTCPANEL_SOURCE;Lähde +IPTCPANEL_SUPPCATEGORIESHINT;(Supplemental Categories) Tarkempi aiheryhmä. +IPTCPANEL_SUPPCATEGORIES;Tarkempi aiheryhmä +IPTCPANEL_TITLEHINT;(Title) Otsikko. +IPTCPANEL_TITLE;Otsikko +IPTCPANEL_TRANSREFERENCEHINT;(Original Transmission Reference) Alkuperäviite. +IPTCPANEL_TRANSREFERENCE;Alkuperäviite +MAIN_BUTTON_PREFERENCES;Asetukset +MAIN_BUTTON_SAVE;Tallenna kuva +MAIN_BUTTON_SENDTOEDITOR;Avaa ulkoisessa ohjelmassa +MAIN_FRAME_BATCHQUEUE;Batch Queue +MAIN_FRAME_FILEBROWSER;File Browser +MAIN_FRAME_PLACES;Places +MAIN_FRAME_PLACES_ADD;Add +MAIN_FRAME_PLACES_DEL;Del +MAIN_FRAME_RECENT;Recent Folders +MAIN_MSG_ALREADYEXISTS;Tiedosto on jo olemassa. +MAIN_MSG_CANNOTLOAD;Kuvaa ei voi avata +MAIN_MSG_CANNOTSAVE;Tiedoston tallennusongelma +MAIN_MSG_CANNOTSTARTEDITOR;Ulkoista ohjelmaa ei voi käynnistää +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Tarkista ohjelman polku asetuksissa! +MAIN_MSG_QOVERWRITE;Haluatko tallentaa päälle? +MAIN_TAB_COLOR;Väri +MAIN_TAB_DETAIL;Yksityiskohdat +MAIN_TAB_DEVELOP;Develop +MAIN_TAB_EXIF;EXIF +MAIN_TAB_EXPOSURE;Valotus +MAIN_TAB_FILTER;Filter +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metatiedot +MAIN_TAB_TRANSFORM;Muunnokset +MAIN_TOOLTIP_HIDEHP;Näytä/piilota vasen ikkuna (pikanäppäin: H) +MAIN_TOOLTIP_INDCLIPPEDH;Näytä leikkautuvat\nvaaleat alueet +MAIN_TOOLTIP_INDCLIPPEDS;Näytä leikkautuvat\ntummat alueet +MAIN_TOOLTIP_QINFO;Kuvan tiedot +PARTIALPASTE_BASICGROUP;Perusasetukset +PARTIALPASTE_CACORRECTION;Väripoikkeaman korjaus +PARTIALPASTE_COARSETRANS;Vasen/oikea kääntö ja peilaus +PARTIALPASTE_COLORGROUP;Väriasetukset +PARTIALPASTE_COMPOSITIONGROUP;Muunnokset +PARTIALPASTE_CROP;Rajaus +PARTIALPASTE_DIALOGLABEL;Liitä valiten.. +PARTIALPASTE_DISTORTION;Linssivääristymän korjaus +PARTIALPASTE_EXIFCHANGES;EXIF-tiedot +PARTIALPASTE_EXPOSURE;Valotus +PARTIALPASTE_ICMSETTINGS;ICM-profiili +PARTIALPASTE_IPTCINFO;IPTC-tiedot +PARTIALPASTE_LENSGROUP;Objektiiviin liittyvät asetukset +PARTIALPASTE_METAGROUP;Metatiedot +PARTIALPASTE_RESIZE;Koko +PARTIALPASTE_ROTATION;Oikaisu +PARTIALPASTE_SHADOWSHIGHLIGHTS;Tummat/vaaleat alueet +PARTIALPASTE_SHARPENING;Terävöinti +PARTIALPASTE_VIGNETTING;Vinjetoinnin korjaus +PARTIALPASTE_WHITEBALANCE;Valkotasapaino +PREFERENCES_APPLNEXTSTARTUP;käytössä käynnistyksen jälkeen +PREFERENCES_CACHECLEARALL;Tyhjennä kaikki +PREFERENCES_CACHECLEARPROFILES;Tyhjennä profiilit +PREFERENCES_CACHECLEARTHUMBS;Tyhjennä esikatselukuvat +PREFERENCES_CACHEMAXENTRIES;Välimuistin koko +PREFERENCES_CACHEOPTS;Välimuistin asetukset +PREFERENCES_CACHETHUMBHEIGHT;Suurin esikatselukuvan korkeus +PREFERENCES_CLIPPINGIND;Leikkautuminen +PREFERENCES_CMETRICINTENT;Näköistystapa +PREFERENCES_DATEFORMATHINT;Voit käyttää seuraavia komentoja:\n%y : vuosi\n%m : kuukausi\n%d : päivä\n\nEsimerkiksi, pp.kk.vvvv:\n%d.%m.%y +PREFERENCES_DATEFORMAT;Päivämäärän muoto +PREFERENCES_DEFAULTLANG;Oletuskieli +PREFERENCES_DEFAULTTHEME;Oletusteema +PREFERENCES_DIRHOME;Kotihakemisto +PREFERENCES_DIRLAST;Viimeksi käytetty hakemisto +PREFERENCES_DIROTHER;Muu +PREFERENCES_DIRSELECTDLG;Valitse kuvahakemisto käynnistettäessä... +PREFERENCES_DIRSOFTWARE;Asennushakemisto +PREFERENCES_EDITORCMDLINE;Muu komentorivi +PREFERENCES_EXTERNALEDITOR;Ulkoinen ohjelma +PREFERENCES_FBROWSEROPTS;Näytettävät tiedot +PREFERENCES_FILEFORMAT;Tallennuksen asetukset +PREFERENCES_FORIMAGE;Kuvatiedostoille +PREFERENCES_FORRAW;RAW-tiedostoille +PREFERENCES_GIMPPATH;GIMP:n asennushakemisto +PREFERENCES_HLTHRESHOLD;Kynnysarvo vaaleille alueille +PREFERENCES_ICCDIR;ICC-profiilien hakemisto +PREFERENCES_IMPROCPARAMS;Oletuskäsittelyprofiilit +PREFERENCES_INTENT_ABSOLUTE;Absoluuttinen kolorimetrinen +PREFERENCES_INTENT_PERCEPTUAL;Havainnollinen +PREFERENCES_INTENT_RELATIVE;Suhteellinen kolorimetrinen +PREFERENCES_INTENT_SATURATION;Kylläisyyden säilyttävä +PREFERENCES_MONITORICC;Näytön profiili +PREFERENCES_OUTDIRFOLDERHINT;Tallenna kuvat valittuun kansioon +PREFERENCES_OUTDIRFOLDER;Valitse hakemisto +PREFERENCES_OUTDIRTEMPLATEHINT;Voit käyttää seuraavia komentoja:\n%f tiedosto\n%p1, %p2, ... polku\n%d1, %d2, ..., hakemisto\nNämä komennot viittaavat RAW-tiedoston hakemistoihin ja polkuihin.\n\nEsimerkiksi: jos /home/tom/image/02-09-2006/dsc0012.nefon avattu, komennot tarkoittavat seuraavaa:\n%f=dsc0012\n%d1=02-09-2006, %d2=image,...\n%p1=/home/tom/image/02-09-2006, %p2=/home/tom/image, p3=/home/tom, ...\n\nJos haluat tallentaa alkuperäisen kuvan hakemistoon:\n%p1/%f\n\nJos haluat tallentaa hakemistoon nimeltä 'converted' joka sijaitsee alkuperäisen kuvan hakemistossa:\n%p1/converted/%f\n\nJos haluat tallentaa hakemistoon '/home/tom/image/converted' ja pitää päivämäärähakemistot:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Ohjelmoi hakemisto +PREFERENCES_OUTDIR;Tallennushakemisto +PREFERENCES_PARSEDEXTADDHINT;Lisää tunniste +PREFERENCES_PARSEDEXTADD;Lisää tunniste +PREFERENCES_PARSEDEXTDELHINT;Poista valitut tunnisteet listasta +PREFERENCES_PARSEDEXT;Käytössä olevat tunnisteet +PREFERENCES_PROFILEHANDLING;Käsittelyprofiilit +PREFERENCES_PROFILELOADPR;Ensisijainen profiili +PREFERENCES_PROFILEPRCACHE;välimuisti +PREFERENCES_PROFILEPRFILE;oheistiedosto +PREFERENCES_PROFILESAVECACHE;Tallenna käsittelyparametrit välimuistiin +PREFERENCES_PROFILESAVEINPUT;Tallenna käsittelyparametrit oheistiedostoon +PREFERENCES_PSPATH;Adobe Photoshop:n asennushakemisto +PREFERENCES_SELECTLANG;Valitse kieli +PREFERENCES_SELECTTHEME;Valitse teema +PREFERENCES_SHOWBASICEXIF;Perus EXIF-tiedot +PREFERENCES_SHOWDATETIME;Päivämäärä ja aika +PREFERENCES_SHTHRESHOLD;Kynnysarvo tummille alueille +PREFERENCES_STARTUPIMDIR;Kuvahakemisto käynnistettäessä +PREFERENCES_TAB_BROWSER;Tiedostot +PREFERENCES_TAB_COLORMGR;Värit +PREFERENCES_TAB_GENERAL;Yleiset +PREFERENCES_TAB_IMPROC;Kuvankäsittely +PROFILEPANEL_LABEL;Käsittelyprofiili +PROFILEPANEL_LOADDLGLABEL;Lataa käsittelyprofiili... +PROFILEPANEL_PCUSTOM;Oma +PROFILEPANEL_PFILE;Tiedostosta +PROFILEPANEL_PLASTSAVED;Viimeisin tallennettu +PROFILEPANEL_SAVEDLGLABEL;Tallenna käsittelyprofiili... +PROFILEPANEL_TOOLTIPCOPY;Kopioi nykyinen profiili leikepöydälle +PROFILEPANEL_TOOLTIPLOAD;Lataa profiili tiedostosta +PROFILEPANEL_TOOLTIPPASTE;Liitä profiili leikepöydältä +PROFILEPANEL_TOOLTIPSAVE;Tallenna profiili +PROGRESSBAR_LOADING;Kuvaa ladataan... +PROGRESSBAR_LOADJPEG;JPEG-tiedostoa ladataan... +PROGRESSBAR_LOADPNG;PNG-tiedostoa ladataan... +PROGRESSBAR_LOADTIFF;TIFF-tiedostoa ladataan... +PROGRESSBAR_PROCESSING;Kuvaa käsitellään... +PROGRESSBAR_READY;Valmis +PROGRESSBAR_SAVEJPEG;JPEG-tiedostoa tallennetaan... +PROGRESSBAR_SAVEPNG;PNG-tiedostoa tallennetaan... +PROGRESSBAR_SAVETIFF;TIFF-tiedostoa tallennetaan... +QINFO_ISO;ISO +QINFO_NOEXIF;EXIF-tietoja ei saatavilla. +SAVEDLG_FILEFORMAT;Tiedostomuoto +SAVEDLG_JPEGQUAL;JPEG laatu (suurempi luku, parempi laatu) +SAVEDLG_PNGCOMPR;PNG pakkaus (suurempi luku, enemmän pakkausta) +SAVEDLG_PUTTOQUEUEHEAD;Laita käsittelyjonon ensimmäiseksi +SAVEDLG_PUTTOQUEUETAIL;Laita käsittelyjonon viimeiseksi +SAVEDLG_PUTTOQUEUE;Laita käsittelyjonoon +SAVEDLG_SAVEIMMEDIATELY;Tallenna heti +SAVEDLG_SAVESPP;Tallenna kuvankäsittelytiedot kuvan mukana +SAVEDLG_TIFFUNCOMPRESSED;Uncompressed TIFF +TOOLBAR_TOOLTIP_CROP;Valitse rajattava alue (pikanäppäin: C) +TOOLBAR_TOOLTIP_HAND;Kuvan siirtotyökalu (pikanäppäin: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;Valitse suora linja (pikanäppäin: S) +TOOLBAR_TOOLTIP_WB;Valitse valkotasapainon\nvalkea piste kuvasta (pikanäppäin: W) +TP_CACORRECTION_BLUE;Sininen +TP_CACORRECTION_LABEL;Väripoikkeaman korjaus +TP_CACORRECTION_RED;Punainen +TP_CHMIXER_BLUE;Sininen +TP_CHMIXER_GREEN;Vihreä +TP_CHMIXER_LABEL;Kanavat +TP_CHMIXER_RED;Punainen +TP_COARSETRAF_TOOLTIP_HFLIP;Peilaa vaakasuunnassa +TP_COARSETRAF_TOOLTIP_ROTLEFT;Käännä vasemmalle +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Käännä oikealle +TP_COARSETRAF_TOOLTIP_VFLIP;Peilaa pystysuunnassa +TP_CROP_FIXRATIO;Pidä kuvasuhde: +TP_CROP_GTDIAGONALS;Kulmien puolittajat +TP_CROP_GTNONE;Ei mikään +TP_CROP_GTRULETHIRDS;Kolmijako +TP_CROP_GUIDETYPE;Sommittelumalli: +TP_CROP_H;Kork. +TP_CROP_LABEL;Rajaus +TP_CROP_SELECTCROP;Valitse alue +TP_CROP_W;Lev. +TP_CROP_X; x +TP_CROP_Y; y +TP_DISTORTION_AMOUNT;Määrä +TP_DISTORTION_LABEL;Linssivääristymän korjaus +TP_EXPOSURE_AUTOLEVELS;Automaattinen +TP_EXPOSURE_BLACKLEVEL;Tummuus +TP_EXPOSURE_BRIGHTNESS;Kirkkaus +TP_EXPOSURE_CLIP;Raja +TP_EXPOSURE_COMPRHIGHLIGHTS;Vaaleiden alueiden vaimennus +TP_EXPOSURE_COMPRSHADOWS;Tummien alueiden vaimennus +TP_EXPOSURE_CONTRAST;Kontrasti +TP_EXPOSURE_CURVEEDITOR;Sävykäyrä +TP_EXPOSURE_EXPCOMP;Kompensointi +TP_EXPOSURE_LABEL;Valotuksen säätö +TP_HLREC_CIELAB;CIELAB värisekoitus +TP_HLREC_COLOR;Värin palautus +TP_HLREC_LABEL;Huippuvaloalueiden palautus +TP_HLREC_LUMINANCE;Luminanssin palautus +TP_HLREC_METHOD;Menetelmä: +TP_ICM_INPUTCAMERA;Kameran oletus +TP_ICM_INPUTCUSTOM;Oma +TP_ICM_INPUTDLGLABEL;Valitse lähteen ICC-profiili... +TP_ICM_INPUTEMBEDDED;Käytä kuvan omaa, jos mahdollista +TP_ICM_INPUTPROFILE;Lähdeväriprofiili +TP_ICM_LABEL;ICM +TP_ICM_NOICM;Ei ICM-profiilia: sRGB +TP_ICM_OUTPUTPROFILE;Tulosväriprofiili +TP_ICM_SAVEREFERENCE;Tallenna mallikuva\nprofilointia varten +TP_ICM_WORKINGPROFILE;Työväriprofiili +TP_RAW_DMETHOD;Menetelmä +TP_RAW_FALSECOLOR;Värivääristymien eston määrä +TP_RESIZE_H;Kork.: +TP_RESIZE_LABEL;Koko +TP_RESIZE_METHOD;Menetelmä: +TP_RESIZE_NEAREST;Lähin +TP_RESIZE_SCALE;Mittakaava +TP_RESIZE_W;Lev.: +TP_ROTATE_DEGREE;Astetta +TP_ROTATE_LABEL;Oikaisu +TP_ROTATE_SELECTLINE;Valitse suora linja +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Vaaleiden alueiden vaimennus +TP_SHADOWSHLIGHTS_HLTONALW;Vaalean sävyalueen laajuus +TP_SHADOWSHLIGHTS_LABEL;Tummat/vaaleat alueet +TP_SHADOWSHLIGHTS_LOCALCONTR;Paikallinen kontrasti +TP_SHADOWSHLIGHTS_RADIUS;Säde +TP_SHADOWSHLIGHTS_SHADOWS;Tummien alueiden vaimennus +TP_SHADOWSHLIGHTS_SHTONALW;Tumman sävyalueen laajuus +TP_SHARPENING_AMOUNT;Määrä +TP_SHARPENING_EDRADIUS;Säde +TP_SHARPENING_EDTOLERANCE;Reunan tunnistusherkkyys +TP_SHARPENING_HALOCONTROL;Halo-ilmiön esto +TP_SHARPENING_HCAMOUNT;Määrä +TP_SHARPENING_LABEL;Terävöinti +TP_SHARPENING_METHOD;Menetelmä +TP_SHARPENING_ONLYEDGES;Terävöi vain reunat +TP_SHARPENING_RADIUS;Säde +TP_SHARPENING_RLD;RL dekonvoluutio +TP_SHARPENING_RLD_AMOUNT;Määrä +TP_SHARPENING_RLD_DAMPING;Vaimennus +TP_SHARPENING_RLD_ITERATIONS;Iteraatiot +TP_SHARPENING_THRESHOLD;Kynnys +TP_SHARPENING_USM;Epäterävä maski +TP_VIGNETTING_AMOUNT;Määrä +TP_VIGNETTING_LABEL;Vinjetoinnin korjaus +TP_VIGNETTING_RADIUS;Säde +TP_WBALANCE_AUTO;Automaattinen +TP_WBALANCE_CAMERA;Kamera +TP_WBALANCE_CUSTOM;Oma +TP_WBALANCE_GREEN;Valkoisen sävy +TP_WBALANCE_LABEL;Valkotasapaino +TP_WBALANCE_METHOD;Menetelmä +TP_WBALANCE_SIZE;Koko: +TP_WBALANCE_SPOTWB;Valitse valkoinen kuvasta +TP_WBALANCE_TEMPERATURE;Lämpötila [K] +# + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!ABOUT_TAB_BUILD;Version +!ABOUT_TAB_CREDITS;Credits +!ABOUT_TAB_LICENSE;License +!ABOUT_TAB_RELEASENOTES;Release Notes +!ABOUT_TAB_SPLASH;Splash +!BATCHQUEUE_AUTOSTART;Auto-start +!BATCHQUEUE_DESTFILENAME;Path and file name +!BATCH_PROCESSING;Batch Processing +!CURVEEDITOR_AXIS_IN;I: +!CURVEEDITOR_AXIS_LEFT_TAN;LT: +!CURVEEDITOR_AXIS_OUT;O: +!CURVEEDITOR_AXIS_RIGHT_TAN;RT: +!CURVEEDITOR_CURVES;Curves +!CURVEEDITOR_CURVE;Curve +!CURVEEDITOR_CUSTOM;Custom +!CURVEEDITOR_DARKS;Darks +!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_HIGHLIGHTS;Highlights +!CURVEEDITOR_LIGHTS;Lights +!CURVEEDITOR_MINMAXCPOINTS;Equalizer +!CURVEEDITOR_NURBS;Control cage +!CURVEEDITOR_PARAMETRIC;Parametric +!CURVEEDITOR_SHADOWS;Shadows +!CURVEEDITOR_TOOLTIPCOPY;Copy current curve to clipboard. +!CURVEEDITOR_TOOLTIPPASTE;Paste curve from clipboard. +!CURVEEDITOR_TYPE;Type: +!EDITWINDOW_TITLE;Image Edit +!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_FILETYPE;File type +!EXIFFILTER_METADATAFILTER;Enable metadata filters +!EXPORT_BYPASS_ALL;Select / Unselect All +!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_FF;Bypass [raw] Flat-Field +!EXPORT_BYPASS_RAW_GREENTHRESH;Bypass [raw] Green Equilibration +!EXPORT_BYPASS_RAW_LINENOISE;Bypass [raw] Line Noise Filter +!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_FASTEXPORTOPTIONS;Fast Export Options +!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_MAXHEIGHT;Maximum height: +!EXPORT_MAXWIDTH;Maximum width: +!EXPORT_PUTTOQUEUEFAST; Put to queue for fast export +!EXPORT_RAW_DMETHOD;Demosaic method +!EXTPROGTARGET_1;raw +!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_CACHECLEARFROMFULL;Clear from cache - full +!FILEBROWSER_CACHECLEARFROMPARTIAL;Clear from cache - partial +!FILEBROWSER_CACHE;Cache +!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_CURRENT_NAME;Current name: +!FILEBROWSER_DARKFRAME;Dark-frame +!FILEBROWSER_DELETEDLGMSGINCLPROC;Are you sure you want to delete the selected %1 files including a queue-processed version? +!FILEBROWSER_EXEC_CPB;Custom Profile Builder +!FILEBROWSER_EXTPROGMENU;Open with +!FILEBROWSER_FLATFIELD;Flat-Field +!FILEBROWSER_MOVETODARKFDIR;Move to dark-frames directory +!FILEBROWSER_MOVETOFLATFIELDDIR;Move to flat-fields directory +!FILEBROWSER_NEW_NAME;New name: +!FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) +!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_POPUPCOLORLABEL;Color label +!FILEBROWSER_POPUPCOPYTO;Copy to... +!FILEBROWSER_POPUPFILEOPERATIONS;File operations +!FILEBROWSER_POPUPMOVETO;Move to... +!FILEBROWSER_POPUPPROCESSFAST;Put to queue (Fast export) +!FILEBROWSER_POPUPPROFILEOPERATIONS;Processing profile operations +!FILEBROWSER_POPUPRANK0;Unrank +!FILEBROWSER_POPUPRANK1;Rank 1 * +!FILEBROWSER_POPUPRANK2;Rank 2 ** +!FILEBROWSER_POPUPRANK3;Rank 3 *** +!FILEBROWSER_POPUPRANK4;Rank 4 **** +!FILEBROWSER_POPUPRANK5;Rank 5 ***** +!FILEBROWSER_POPUPRANK;Rank +!FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!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_QUERYLABEL; Find: +!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_SELECTDARKFRAME;Select dark-frame... +!FILEBROWSER_SELECTFLATFIELD;Select flat-field... +!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 +!FILEBROWSER_SHOWCOLORLABEL4HINT;Show images labeled Blue.\nShortcut: Alt-4 +!FILEBROWSER_SHOWCOLORLABEL5HINT;Show images labeled Purple.\nShortcut: Alt-5 +!FILEBROWSER_SHOWEDITEDHINT;Show edited images.\nShortcut: 7 +!FILEBROWSER_SHOWEDITEDNOTHINT;Show not edited images.\nShortcut: 6 +!FILEBROWSER_SHOWEXIFINFO;Show Exif info.\n\nShortcuts:\ni - Multiple Editor Tabs Mode,\nAlt-i - Single Editor Tab Mode. +!FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!FILEBROWSER_SHOWRECENTLYSAVEDHINT;Show saved images.\nShortcut: Alt-7 +!FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show unsaved images.\nShortcut: Alt-6 +!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_AFTER;After +!GENERAL_ASIMAGE;As Image +!GENERAL_AUTO;Automatic +!GENERAL_BEFORE;Before +!GENERAL_CLOSE;Close +!GENERAL_FILE;File +!GENERAL_NONE;None +!GENERAL_UNCHANGED;(Unchanged) +!GENERAL_WARNING;Warning +!HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar.\nRight-click on image preview to freeze/unfreeze. +!HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram. +!HISTOGRAM_TOOLTIP_FULL;Toggle full (off) or scaled (on) histogram. +!HISTOGRAM_TOOLTIP_RAW;Show/Hide raw histogram. +!HISTORY_MSG_82;Profile changed +!HISTORY_MSG_83;S/H - Sharp mask +!HISTORY_MSG_84;Perspective correction +!HISTORY_MSG_85;LCP +!HISTORY_MSG_86;RGB curves - Luminosity mode +!HISTORY_MSG_87;Impulse noise reduction +!HISTORY_MSG_88;Impulse NR threshold +!HISTORY_MSG_89;Noise Reduction +!HISTORY_MSG_90;NR - Luminance +!HISTORY_MSG_91;NR - Chrominance master +!HISTORY_MSG_92;NR - Gamma +!HISTORY_MSG_93;CbDL - Value +!HISTORY_MSG_94;Contrast by Detail Levels +!HISTORY_MSG_95;L*a*b* - Chromaticity +!HISTORY_MSG_96;L*a*b* - a* curve +!HISTORY_MSG_97;L*a*b* - b* curve +!HISTORY_MSG_98;Demosaicing method +!HISTORY_MSG_99;Hot pixel filter +!HISTORY_MSG_100;RGB Saturation +!HISTORY_MSG_101;HSV - Hue +!HISTORY_MSG_102;HSV - Saturation +!HISTORY_MSG_103;HSV - Value +!HISTORY_MSG_104;HSV Equalizer +!HISTORY_MSG_105;Defringe +!HISTORY_MSG_106;Defringe - Radius +!HISTORY_MSG_107;Defringe - Threshold +!HISTORY_MSG_108;Highlight Compr. Threshold +!HISTORY_MSG_109;Resize - Bounding box +!HISTORY_MSG_110;Resize - Applies to +!HISTORY_MSG_111;L*a*b* - Avoid color shift +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;L*a*b* - Red/skin prot. +!HISTORY_MSG_114;DCB iterations +!HISTORY_MSG_115;False color suppression +!HISTORY_MSG_116;DCB enhancement +!HISTORY_MSG_117;Raw CA correction - Red +!HISTORY_MSG_118;Raw CA correction - Blue +!HISTORY_MSG_119;Line noise filter +!HISTORY_MSG_120;Green equilibration +!HISTORY_MSG_121;Raw CA Correction - Auto +!HISTORY_MSG_122;Dark-Frame - Auto-selection +!HISTORY_MSG_123;Dark-Frame - File +!HISTORY_MSG_124;White point correction +!HISTORY_MSG_125;Highlight preservation +!HISTORY_MSG_126;Flat-Field - File +!HISTORY_MSG_127;Flat-Field - Auto-selection +!HISTORY_MSG_128;Flat-Field - Blur radius +!HISTORY_MSG_129;Flat-Field - Blur type +!HISTORY_MSG_130;Auto distorion correction +!HISTORY_MSG_131;NR - Luma +!HISTORY_MSG_132;NR - Chroma +!HISTORY_MSG_133;Output gamma +!HISTORY_MSG_134;Free gamma +!HISTORY_MSG_135;Free gamma +!HISTORY_MSG_136;Free gamma slope +!HISTORY_MSG_137;Black level - Green 1 +!HISTORY_MSG_138;Black level - Red +!HISTORY_MSG_139;Black level - Blue +!HISTORY_MSG_140;Black level - Green 2 +!HISTORY_MSG_141;Black level - Link greens +!HISTORY_MSG_142;ES - Iterations +!HISTORY_MSG_143;ES - Quantity +!HISTORY_MSG_144;Microcontrast - Quantity +!HISTORY_MSG_145;Microcontrast - Uniformity +!HISTORY_MSG_146;Edge sharpening +!HISTORY_MSG_147;ES - Luminance only +!HISTORY_MSG_148;Microcontrast +!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_150;Post-demosaic artifact/noise red. +!HISTORY_MSG_151;Vibrance +!HISTORY_MSG_152;Vib - Pastel tones +!HISTORY_MSG_153;Vib - Saturated tones +!HISTORY_MSG_154;Vib - Protect skin-tones +!HISTORY_MSG_155;Vib - Avoid color shift +!HISTORY_MSG_156;Vib - Link pastel/saturated +!HISTORY_MSG_157;Vib - P/S threshold +!HISTORY_MSG_158;TM - Strength +!HISTORY_MSG_159;TM - Edge stopping +!HISTORY_MSG_160;TM - Scale +!HISTORY_MSG_161;TM - Reweighting iterates +!HISTORY_MSG_162;Tone Mapping +!HISTORY_MSG_163;RGB curves - Red +!HISTORY_MSG_164;RGB curves - Green +!HISTORY_MSG_165;RGB curves - Blue +!HISTORY_MSG_166;Neutral levels +!HISTORY_MSG_167;--unused-- +!HISTORY_MSG_168;L*a*b* - CC curve +!HISTORY_MSG_169;L*a*b* - CH curve +!HISTORY_MSG_170;Vibrance - HH curve +!HISTORY_MSG_171;L*a*b* - LC curve +!HISTORY_MSG_172;L*a*b* - Restrict LC +!HISTORY_MSG_173;NR - Luminance detail +!HISTORY_MSG_174;CIECAM02 +!HISTORY_MSG_175;CAM02 - CAT02 adaptation +!HISTORY_MSG_176;CAM02 - Viewing surround +!HISTORY_MSG_177;CAM02 - Scene luminosity +!HISTORY_MSG_178;CAM02 - Viewing luminosity +!HISTORY_MSG_179;CAM02 - White-point model +!HISTORY_MSG_180;CAM02 - Lightness (J) +!HISTORY_MSG_181;CAM02 - Chroma (C) +!HISTORY_MSG_182;CAM02 - Automatic CAT02 +!HISTORY_MSG_183;CAM02 - Contrast (J) +!HISTORY_MSG_184;CAM02 - Scene surround +!HISTORY_MSG_185;CAM02 - Gamut control +!HISTORY_MSG_186;CAM02 - Algorithm +!HISTORY_MSG_187;CAM02 - Red/skin prot. +!HISTORY_MSG_188;CAM02 - Brightness (Q) +!HISTORY_MSG_189;CAM02 - Contrast (Q) +!HISTORY_MSG_190;CAM02 - Saturation (S) +!HISTORY_MSG_191;CAM02 - Colorfulness (M) +!HISTORY_MSG_192;CAM02 - Hue (h) +!HISTORY_MSG_193;CAM02 - Tone curve 1 +!HISTORY_MSG_194;CAM02 - Tone curve 2 +!HISTORY_MSG_195;CAM02 - Tone curve 1 +!HISTORY_MSG_196;CAM02 - Tone curve 2 +!HISTORY_MSG_197;CAM02 - Color curve +!HISTORY_MSG_198;CAM02 - Color curve +!HISTORY_MSG_199;CAM02 - Output histograms +!HISTORY_MSG_200;CAM02 - Tone mapping +!HISTORY_MSG_201;NR - Chrominance - R&G +!HISTORY_MSG_202;NR - Chrominance - B&Y +!HISTORY_MSG_203;NR - Method +!HISTORY_MSG_204;LMMSE enhancement steps +!HISTORY_MSG_205;CAM02 - Hot/bad pixel filter +!HISTORY_MSG_206;CAT02 - Auto scene luminosity +!HISTORY_MSG_207;Defringe - Hue curve +!HISTORY_MSG_208;WB - B/R equalizer +!HISTORY_MSG_210;GF - Angle +!HISTORY_MSG_211;Graduated Filter +!HISTORY_MSG_212;VF - Strength +!HISTORY_MSG_213;Vignette Filter +!HISTORY_MSG_214;Black-and-White +!HISTORY_MSG_215;B&W - CM - Red +!HISTORY_MSG_216;B&W - CM - Green +!HISTORY_MSG_217;B&W - CM - Blue +!HISTORY_MSG_218;B&W - Gamma - Red +!HISTORY_MSG_219;B&W - Gamma - Green +!HISTORY_MSG_220;B&W - Gamma - Blue +!HISTORY_MSG_221;B&W - Color filter +!HISTORY_MSG_222;B&W - Presets +!HISTORY_MSG_223;B&W - CM - Orange +!HISTORY_MSG_224;B&W - CM - Yellow +!HISTORY_MSG_225;B&W - CM - Cyan +!HISTORY_MSG_226;B&W - CM - Magenta +!HISTORY_MSG_227;B&W - CM - Purple +!HISTORY_MSG_228;B&W - Luminance equalizer +!HISTORY_MSG_229;B&W - Luminance equalizer +!HISTORY_MSG_230;B&W - Mode +!HISTORY_MSG_231;B&W - 'Before' curve +!HISTORY_MSG_232;B&W - 'Before' curve type +!HISTORY_MSG_233;B&W - 'After' curve +!HISTORY_MSG_234;B&W - 'After' curve type +!HISTORY_MSG_235;B&W - Auto channel mixer +!HISTORY_MSG_236;--unused-- +!HISTORY_MSG_237;B&W - Mixer +!HISTORY_MSG_238;GF - Feather +!HISTORY_MSG_239;GF - Strength +!HISTORY_MSG_240;GF - Center +!HISTORY_MSG_241;VF - Feather +!HISTORY_MSG_242;VF - Roundness +!HISTORY_MSG_243;VC - Radius +!HISTORY_MSG_244;VC - Strength +!HISTORY_MSG_245;VC - Center +!HISTORY_MSG_246;L*a*b* - CL curve +!HISTORY_MSG_247;L*a*b* - LH curve +!HISTORY_MSG_248;L*a*b* - HH curve +!HISTORY_MSG_249;CbDL - Threshold +!HISTORY_MSG_250;NR - Enhanced +!HISTORY_MSG_251;B&W - Algorithm +!HISTORY_MSG_252;CbDL - Skin tar/prot +!HISTORY_MSG_253;CbDL - Reduce artifacts +!HISTORY_MSG_254;CbDL - Skin hue +!HISTORY_MSG_255;NR - Median filter +!HISTORY_MSG_256;NR - Median type +!HISTORY_MSG_257;Color Toning +!HISTORY_MSG_258;CT - Color curve +!HISTORY_MSG_259;CT - Opacity curve +!HISTORY_MSG_260;CT - a*[b*] opacity +!HISTORY_MSG_261;CT - Method +!HISTORY_MSG_262;CT - b* opacity +!HISTORY_MSG_263;CT - Shadows - Red +!HISTORY_MSG_264;CT - Shadows - Green +!HISTORY_MSG_265;CT - Shadows - Blue +!HISTORY_MSG_266;CT - Mid - Red +!HISTORY_MSG_267;CT - Mid - Green +!HISTORY_MSG_268;CT - Mid - Blue +!HISTORY_MSG_269;CT - High - Red +!HISTORY_MSG_270;CT - High - Green +!HISTORY_MSG_271;CT - High - Blue +!HISTORY_MSG_272;CT - Balance +!HISTORY_MSG_273;CT - Reset +!HISTORY_MSG_274;CT - Sat. Shadows +!HISTORY_MSG_275;CT - Sat. Highlights +!HISTORY_MSG_276;CT - Opacity +!HISTORY_MSG_277;--unused-- +!HISTORY_MSG_278;CT - Preserve luminance +!HISTORY_MSG_279;CT - Shadows +!HISTORY_MSG_280;CT - Highlights +!HISTORY_MSG_281;CT - Sat. strength +!HISTORY_MSG_282;CT - Sat. threshold +!HISTORY_MSG_283;CT - Strength +!HISTORY_MSG_284;CT - Auto sat. protection +!HISTORY_MSG_285;NR - Median - Method +!HISTORY_MSG_286;NR - Median - Type +!HISTORY_MSG_287;NR - Median - Iterations +!HISTORY_MSG_288;Flat Field - Clip control +!HISTORY_MSG_289;Flat Field - Clip control - Auto +!HISTORY_MSG_290;Black Level - Red +!HISTORY_MSG_291;Black Level - Green +!HISTORY_MSG_292;Black Level - Blue +!HISTORY_MSG_293;Film Simulation +!HISTORY_MSG_294;Film Simulation - Strength +!HISTORY_MSG_295;Film Simulation - Film +!HISTORY_MSG_296;NR - Luminance curve +!HISTORY_MSG_297;NR - Quality +!HISTORY_MSG_298;Dead pixel filter +!HISTORY_MSG_299;NR - Chrominance curve +!HISTORY_MSG_300;- +!HISTORY_MSG_301;NR - Luma control +!HISTORY_MSG_302;NR - Chroma method +!HISTORY_MSG_303;NR - Chroma method +!HISTORY_MSG_304;W - Contrast levels +!HISTORY_MSG_305;Wavelet Levels +!HISTORY_MSG_306;W - Preview +!HISTORY_MSG_307;W - Preview +!HISTORY_MSG_308;W - Preview direction +!HISTORY_MSG_309;W - ES - Detail +!HISTORY_MSG_310;W - Residual - Sky tar/prot +!HISTORY_MSG_311;W - Wavelet levels +!HISTORY_MSG_312;W - Residual - Shadows threshold +!HISTORY_MSG_313;W - Chroma - Sat/past +!HISTORY_MSG_314;W - Gamut - Reduce artifacts +!HISTORY_MSG_315;W - Residual - Contrast +!HISTORY_MSG_316;W - Gamut - Skin tar/prot +!HISTORY_MSG_317;W - Gamut - Skin hue +!HISTORY_MSG_318;W - Contrast - Highlight levels +!HISTORY_MSG_319;W - Contrast - Highlight range +!HISTORY_MSG_320;W - Contrast - Shadow range +!HISTORY_MSG_321;W - Contrast - Shadow levels +!HISTORY_MSG_322;W - Gamut - Avoid color shift +!HISTORY_MSG_323;W - ES - Local contrast +!HISTORY_MSG_324;W - Chroma - Pastel +!HISTORY_MSG_325;W - Chroma - Saturated +!HISTORY_MSG_326;W - Chroma - Method +!HISTORY_MSG_327;W - Contrast - Apply to +!HISTORY_MSG_328;W - Chroma - Link strength +!HISTORY_MSG_329;W - Toning - Opacity RG +!HISTORY_MSG_330;W - Toning - Opacity BY +!HISTORY_MSG_331;W - Contrast levels - Extra +!HISTORY_MSG_332;W - Tiling method +!HISTORY_MSG_333;W - Residual - Shadows +!HISTORY_MSG_334;W - Residual - Chroma +!HISTORY_MSG_335;W - Residual - Highlights +!HISTORY_MSG_336;W - Residual - Highlights threshold +!HISTORY_MSG_337;W - Residual - Sky hue +!HISTORY_MSG_338;W - ES - Radius +!HISTORY_MSG_339;W - ES - Strength +!HISTORY_MSG_340;W - Strength +!HISTORY_MSG_341;W - Edge performance +!HISTORY_MSG_342;W - ES - First level +!HISTORY_MSG_343;W - Chroma levels +!HISTORY_MSG_344;W - Meth chroma sl/cur +!HISTORY_MSG_345;W - ES - Local contrast +!HISTORY_MSG_346;W - ES - Local contrast method +!HISTORY_MSG_347;W - Denoise - Level 0 +!HISTORY_MSG_348;W - Denoise - Level 1 +!HISTORY_MSG_349;W - Denoise - Level 2 +!HISTORY_MSG_350;W - ES - Edge detection +!HISTORY_MSG_351;W - Residual - HH curve +!HISTORY_MSG_352;W - Background +!HISTORY_MSG_353;W - ES - Gradient sensitivity +!HISTORY_MSG_354;W - ES - Enhance +!HISTORY_MSG_355;W - ES - Threshold low +!HISTORY_MSG_356;W - ES - Threshold high +!HISTORY_MSG_357;W - Denoise - Link with ES +!HISTORY_MSG_358;W - Gamut - CH +!HISTORY_MSG_359;Hot/Dead - Threshold +!HISTORY_MSG_360;TM Gamma +!HISTORY_MSG_361;W - Final - Chroma balance +!HISTORY_MSG_362;W - Residual - Compression method +!HISTORY_MSG_363;W - Residual - Compression strength +!HISTORY_MSG_364;W - Final - Contrast balance +!HISTORY_MSG_365;W - Final - Delta balance +!HISTORY_MSG_366;W - Residual - Compression gamma +!HISTORY_MSG_367;W - ES - Local contrast curve +!HISTORY_MSG_368;W - Final - Contrast balance +!HISTORY_MSG_369;W - Final - Balance method +!HISTORY_MSG_370;W - Final - Local contrast curve +!HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s +!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 +!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). +!MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Put current image to processing queue.\nShortcut: Ctrl+b +!MAIN_BUTTON_SAVE_TOOLTIP;Save current image.\nShortcut: Ctrl+s +!MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Edit current image in external editor.\nShortcut: Ctrl+e +!MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Show/hide all side panels.\nShortcut: m +!MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen +!MAIN_FRAME_BATCHQUEUE_TOOLTIP;Processing queue.\nShortcut: Ctrl-F3 +!MAIN_FRAME_EDITOR;Editor +!MAIN_FRAME_EDITOR_TOOLTIP;Editor.\nShortcut: Ctrl-F4 +!MAIN_FRAME_FILEBROWSER_TOOLTIP;File browser.\nShortcut: Ctrl-F2 +!MAIN_MSG_EMPTYFILENAME;Filename unspecified! +!MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue-processed first. +!MAIN_MSG_NAVIGATOR;Navigator +!MAIN_MSG_OPERATIONCANCELLED;Operation cancelled +!MAIN_MSG_PATHDOESNTEXIST;The path\n\n%1\n\ndoes not exist. Please set a correct path in Preferences. +!MAIN_MSG_SETPATHFIRST;You first have to set a target path in Preferences in order to use this function! +!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_EXPORT; Fast Export +!MAIN_TAB_EXPOSURE_TOOLTIP;Shortcut: Alt-e +!MAIN_TAB_INSPECT; Inspect +!MAIN_TAB_METADATA_TOOLTIP;Shortcut: Alt-m +!MAIN_TAB_RAW;Raw +!MAIN_TAB_RAW_TOOLTIP;Shortcut: Alt-r +!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_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%. +!MAIN_TOOLTIP_PREVIEWG;Preview the Green channel.\nShortcut: g +!MAIN_TOOLTIP_PREVIEWL;Preview the Luminosity.\nShortcut: v\n\n0.299*R + 0.587*G + 0.114*B +!MAIN_TOOLTIP_PREVIEWR;Preview the Red channel.\nShortcut: r +!MAIN_TOOLTIP_SHOWHIDELP1;Show/Hide the left panel.\nShortcut: l +!MAIN_TOOLTIP_SHOWHIDERP1;Show/Hide the right panel.\nShortcut: Alt-l +!MAIN_TOOLTIP_SHOWHIDETP1;Show/Hide the top panel.\nShortcut: Shift-l +!MAIN_TOOLTIP_THRESHOLD;Threshold +!MAIN_TOOLTIP_TOGGLE;Toggle the Before/After view.\nShortcut: Shift-b +!NAVIGATOR_B;B: +!NAVIGATOR_G;G: +!NAVIGATOR_H;H: +!NAVIGATOR_LAB_A;a*: +!NAVIGATOR_LAB_B;b*: +!NAVIGATOR_LAB_L;L*: +!NAVIGATOR_NA; -- +!NAVIGATOR_R;R: +!NAVIGATOR_S;S: +!NAVIGATOR_V;V: +!NAVIGATOR_XY_FULL;Width: %1, Height: %2 +!NAVIGATOR_XY_NA;x: --, y: -- +!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_CHANNELMIXERBW;Black-and-White +!PARTIALPASTE_CHANNELMIXER;Channel mixer +!PARTIALPASTE_COLORAPP;CIECAM02 +!PARTIALPASTE_COLORTONING;Color Toning +!PARTIALPASTE_COMMONTRANSFORMPARAMS;Auto-fill +!PARTIALPASTE_DARKFRAMEAUTOSELECT;Dark-frame auto-selection +!PARTIALPASTE_DARKFRAMEFILE;Dark-frame file +!PARTIALPASTE_DEFRINGE;Defringe +!PARTIALPASTE_DETAILGROUP;Detail Settings +!PARTIALPASTE_DIRPYRDENOISE;Noise reduction +!PARTIALPASTE_DIRPYREQUALIZER;Contrast by detail levels +!PARTIALPASTE_EPD;Tone mapping +!PARTIALPASTE_EQUALIZER;Wavelet Equalizer +!PARTIALPASTE_EVERYTHING;Everything +!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_GRADIENT;Graduated filter +!PARTIALPASTE_HSVEQUALIZER;HSV equalizer +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction +!PARTIALPASTE_LABCURVE;L*a*b* adjustments +!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_PCVIGNETTE;Vignette filter +!PARTIALPASTE_PERSPECTIVE;Perspective +!PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter +!PARTIALPASTE_PREPROCESS_GREENEQUIL;Green equilibration +!PARTIALPASTE_PREPROCESS_HOTPIXFILT;Hot pixel filter +!PARTIALPASTE_PREPROCESS_LINEDENOISE;Line noise filter +!PARTIALPASTE_RAWCACORR_AUTO;CA auto-correction +!PARTIALPASTE_RAWCACORR_CABLUE;CA blue +!PARTIALPASTE_RAWCACORR_CARED;CA red +!PARTIALPASTE_RAWEXPOS_BLACK;Black levels +!PARTIALPASTE_RAWEXPOS_LINEAR;White point correction +!PARTIALPASTE_RAWEXPOS_PRESER;Highlight preservation +!PARTIALPASTE_RAWGROUP;Raw Settings +!PARTIALPASTE_RAW_DCBENHANCE;DCB enhancement +!PARTIALPASTE_RAW_DCBITERATIONS;Number of DCB iterations +!PARTIALPASTE_RAW_DMETHOD;Demosaic method +!PARTIALPASTE_RAW_FALSECOLOR;Demosaic false color suppression steps +!PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!PARTIALPASTE_RGBCURVES;RGB curves +!PARTIALPASTE_SHARPENEDGE;Edges +!PARTIALPASTE_SHARPENMICRO;Microcontrast +!PARTIALPASTE_VIBRANCE;Vibrance +!PARTIALPASTE_WAVELETGROUP;Wavelet processing +!PREFERENCES_ADD;Add +!PREFERENCES_AUTLISLOW;Low +!PREFERENCES_AUTLISMAX;Max - Average of all tiles +!PREFERENCES_AUTLISSTD;High +!PREFERENCES_AUTLISVLOW;None +!PREFERENCES_AUTLOW;Low +!PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +!PREFERENCES_AUTSTD;Standard +!PREFERENCES_BATCH_PROCESSING;Batch Processing +!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_BEHADDALL;All to 'Add' +!PREFERENCES_BEHAVIOR;Behavior +!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_BEHSETALL;All to 'Set' +!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_CURVEBBOXPOS;Position of curve copypasta buttons +!PREFERENCES_CURVEBBOXPOS_ABOVE;Above +!PREFERENCES_CURVEBBOXPOS_BELOW;Below +!PREFERENCES_CURVEBBOXPOS_LEFT;Left +!PREFERENCES_CURVEBBOXPOS_RIGHT;Right +!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_CUSTPROFBUILD;Custom Processing Profile Builder +!PREFERENCES_CUTOVERLAYBRUSH;Crop mask color/transparency +!PREFERENCES_D50;5000K +!PREFERENCES_D55;5500K +!PREFERENCES_D60;6000K +!PREFERENCES_D65;6500K +!PREFERENCES_DARKFRAMEFOUND;Found +!PREFERENCES_DARKFRAMESHOTS;shots +!PREFERENCES_DARKFRAMETEMPLATES;templates +!PREFERENCES_DARKFRAME;Dark-Frame +!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 (de-select for low resolution display) +!PREFERENCES_FILMSIMULATION;Film Simulation +!PREFERENCES_FLATFIELDFOUND;Found +!PREFERENCES_FLATFIELDSDIR;Flat-fields directory +!PREFERENCES_FLATFIELDSHOTS;shots +!PREFERENCES_FLATFIELDTEMPLATES;templates +!PREFERENCES_FLATFIELD;Flat-Field +!PREFERENCES_FLUOF2;Fluorescent F2 +!PREFERENCES_FLUOF7;Fluorescent F7 +!PREFERENCES_FLUOF11;Fluorescent F11 +!PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT;Same thumbnail height between the Editor's panel 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_GREY05;Yb=05 CIE L#30 +!PREFERENCES_GREY10;Yb=10 CIE L#40 +!PREFERENCES_GREY15;Yb=15 CIE L#45 +!PREFERENCES_GREY18;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_GREYSC18;Yb=18 CIE L#50 +!PREFERENCES_GREYSCA;Automatic +!PREFERENCES_GREYSC;Scene Yb luminance (%) +!PREFERENCES_GREY;Output device's Yb luminance (%) +!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_LANGAUTODETECT;Use system language +!PREFERENCES_LEVAUTDN;Denoising level +!PREFERENCES_LEVDN;Cell size +!PREFERENCES_LISS;Auto multi-zone smoothing +!PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders +!PREFERENCES_MAX;Maxi (Tile) +!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_MENUGROUPRANK;Group "Rank" +!PREFERENCES_MENUOPTIONS;Context Menu Options +!PREFERENCES_METADATA;Metadata +!PREFERENCES_MIN;Mini (100x115) +!PREFERENCES_MULTITABDUALMON;Multiple Editor Tabs In Own Window Mode +!PREFERENCES_MULTITAB;Multiple Editor Tabs 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_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_PROPERTY;Property +!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 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_SINGLETABVERTAB;Single Editor Tab Mode, Vertical Tabs +!PREFERENCES_SINGLETAB;Single Editor Tab Mode +!PREFERENCES_SLIMUI;Slim interface +!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_PERFORMANCE;Performance & Quality +!PREFERENCES_TAB_SOUND;Sounds +!PREFERENCES_TIMAX;High +!PREFERENCES_TINB;Number of tiles +!PREFERENCES_TISTD;Standard +!PREFERENCES_TP_LABEL;Tool panel: +!PREFERENCES_TP_USEICONORTEXT;Use tab icons instead of text +!PREFERENCES_TP_VSCROLLBAR;Hide vertical scrollbar +!PREFERENCES_TUNNELMETADATA;Copy IPTC/XMP unchanged to output file (when tagging with other program) +!PREFERENCES_USEBUNDLEDPROFILES;Use bundled profiles +!PREFERENCES_USESYSTEMTHEME;Use system theme +!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_WORKFLOW;Layout +!PROFILEPANEL_COPYPPASTE;Parameters to copy +!PROFILEPANEL_GLOBALPROFILES;Bundled profiles +!PROFILEPANEL_LOADPPASTE;Parameters to load +!PROFILEPANEL_MODE_TIP;Processing profile fill mode.\n\nButton pressed: partial profiles will be converted to full profiles; the missing values will be replaced with hard-coded defaults.\n\nButton released: profiles will be applied as they are, altering only those values which they contain. +!PROFILEPANEL_MYPROFILES;My profiles +!PROFILEPANEL_PASTEPPASTE;Parameters to paste +!PROFILEPANEL_PINTERNAL;Neutral +!PROFILEPANEL_SAVEPPASTE;Parameters to save +!PROGRESSBAR_LOADINGTHUMBS;Loading thumbnails... +!PROGRESSBAR_NOIMAGES;No images found +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing profile saved +!PROGRESSBAR_SNAPSHOT_ADDED;Snapshot added +!PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists +!SAVEDLG_FORCEFORMATOPTS;Force saving options +!SAVEDLG_SUBSAMP;Subsampling +!SAVEDLG_SUBSAMP_1;Best compression +!SAVEDLG_SUBSAMP_2;Balanced +!SAVEDLG_SUBSAMP_3;Best quality +!SAVEDLG_SUBSAMP_TOOLTIP;Best compression: 4:1:1\nBalanced: 4:2:2\nBest quality: 4:4:4 +!SAVEDLG_WARNFILENAME;File will be named +!SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. +!THRESHOLDSELECTOR_BL;Bottom-left +!THRESHOLDSELECTOR_BR;Bottom-right +!THRESHOLDSELECTOR_B;Bottom +!THRESHOLDSELECTOR_HINT;Hold the Shift key to move individual control points. +!THRESHOLDSELECTOR_TL;Top-left +!THRESHOLDSELECTOR_TR;Top-right +!THRESHOLDSELECTOR_T;Top +!TP_BWMIX_ALGO;Algorithm OYCPM +!TP_BWMIX_ALGO_LI;Linear +!TP_BWMIX_ALGO_SP;Special effects +!TP_BWMIX_ALGO_TOOLTIP;Linear: will produce a normal linear response.\nSpecial effects: will produce special effects by mixing channels non-linearly. +!TP_BWMIX_AUTOCH;Auto +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing Channel Mixer. +!TP_BWMIX_CC_ENABLED;Adjust complementary color +!TP_BWMIX_CC_TOOLTIP;Enable to allow automatic adjustment of complementary colors in ROYGCBPM mode. +!TP_BWMIX_CHANNEL;Luminance equalizer +!TP_BWMIX_CURVEEDITOR1;'Before' curve +!TP_BWMIX_CURVEEDITOR2;'After' curve +!TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Tone curve, after B&W conversion, at the end of treatment. +!TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Tone curve, just before B&W conversion.\nMay take into account the color components. +!TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H).\nPay attention to extreme values as they may cause artifacts. +!TP_BWMIX_FILTER;Color Filter +!TP_BWMIX_FILTER_BLUEGREEN;Blue-Green +!TP_BWMIX_FILTER_BLUE;Blue +!TP_BWMIX_FILTER_GREENYELLOW;Green-Yellow +!TP_BWMIX_FILTER_GREEN;Green +!TP_BWMIX_FILTER_NONE;None +!TP_BWMIX_FILTER_PURPLE;Purple +!TP_BWMIX_FILTER_REDYELLOW;Red-Yellow +!TP_BWMIX_FILTER_RED;Red +!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. +!TP_BWMIX_FILTER_YELLOW;Yellow +!TP_BWMIX_GAMMA;Gamma Correction +!TP_BWMIX_GAM_TOOLTIP;Correct gamma for each RGB channel. +!TP_BWMIX_LABEL;Black-and-White +!TP_BWMIX_MET;Method +!TP_BWMIX_MET_CHANMIX;Channel Mixer +!TP_BWMIX_MET_DESAT;Desaturation +!TP_BWMIX_MET_LUMEQUAL;Luminance Equalizer +!TP_BWMIX_MIXC;Mixer +!TP_BWMIX_NEUTRAL;Reset mixer +!TP_BWMIX_NEUTRAL_TIP;Reset all values (Color Filter, Channel Mixer) to default. +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all the mixer options.\n"Total" displays the sum of the RGB values:\n- always 100% in relative mode\n- higher (lighter) or lower (darker) than 100% in absolute mode. +!TP_BWMIX_RGB_TOOLTIP;Mix the RGB channels. Use presets for guidance.\nPay attention to negative values that may cause artifacts or erratic behavior. +!TP_BWMIX_SETTING;Presets +!TP_BWMIX_SETTING_TOOLTIP;Different presets (film, landscape, etc.) or manual Channel Mixer settings. +!TP_BWMIX_SET_HIGHCONTAST;High contrast +!TP_BWMIX_SET_HIGHSENSIT;High Sensitivity +!TP_BWMIX_SET_HYPERPANCHRO;Hyper Panchromatic +!TP_BWMIX_SET_INFRARED;Infrared +!TP_BWMIX_SET_LANDSCAPE;Landscape +!TP_BWMIX_SET_LOWSENSIT;Low Sensitivity +!TP_BWMIX_SET_LUMINANCE;Luminance +!TP_BWMIX_SET_NORMCONTAST;Normal Contrast +!TP_BWMIX_SET_ORTHOCHRO;Orthochromatic +!TP_BWMIX_SET_PANCHRO;Panchromatic +!TP_BWMIX_SET_PORTRAIT;Portrait +!TP_BWMIX_SET_RGBABS;Absolute RGB +!TP_BWMIX_SET_RGBREL;Relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Relative ROYGCBPM +!TP_BWMIX_TCMODE_FILMLIKE;B&W Film-like +!TP_BWMIX_TCMODE_SATANDVALBLENDING;B&W Saturation and Value Blending +!TP_BWMIX_TCMODE_STANDARD;B&W Standard +!TP_BWMIX_TCMODE_WEIGHTEDSTD;B&W Weighted Standard +!TP_BWMIX_VAL;L +!TP_CHROMATABERR_LABEL;Chromatic Aberration +!TP_COLORAPP_ADAPTSCENE;Scene luminosity +!TP_COLORAPP_ADAPTSCENE_TOOLTIP;Absolute luminance of the scene environement (cd/m²).\n1) Calculated from the Exif data:\nShutter speed - ISO speed - F number - camera exposure correction.\n2) Calculated from the raw white point and RT's Exposure Compensation slider. +!TP_COLORAPP_ADAPTVIEWING;Viewing luminosity (cd/m²) +!TP_COLORAPP_ADAPTVIEWING_TOOLTIP;Absolute luminance of the viewing environnement\n(usually 16cd/m²). +!TP_COLORAPP_ADAP_AUTO_TOOLTIP;If the checkbox is checked (recommended) RawTherapee calculates an optimum value from Exif data.\nTo set the value manually, uncheck the checkbox first. +!TP_COLORAPP_ALGO;Algorithm +!TP_COLORAPP_ALGO_ALL;All +!TP_COLORAPP_ALGO_JC;Lightness + Chroma (JC) +!TP_COLORAPP_ALGO_JS;Lightness + Saturation (JS) +!TP_COLORAPP_ALGO_QM;Brightness + Colorfulness (QM) +!TP_COLORAPP_ALGO_TOOLTIP;Lets you choose between parameter subsets or all parameters. +!TP_COLORAPP_BADPIXSL;Hot/bad pixel filter +!TP_COLORAPP_BADPIXSL_TOOLTIP;Suppression of hot/bad (brightly colored) pixels.\n0 = No effect\n1 = Median\n2 = Gaussian.\nAlternatively, adjust the image to avoid very dark shadows.\n\nThese artifacts are due to limitations of CIECAM02. +!TP_COLORAPP_BRIGHT;Brightness (Q) +!TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from L*a*b* and RGB brightness. +!TP_COLORAPP_CHROMA;Chroma (C) +!TP_COLORAPP_CHROMA_M;Colorfulnes (M) +!TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM02 differs from L*a*b* and RGB colorfulness. +!TP_COLORAPP_CHROMA_S;Saturation (S) +!TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from L*a*b* and RGB saturation. +!TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from L*a*b* and RGB chroma. +!TP_COLORAPP_CIECAT_DEGREE;CAT02 adaptation +!TP_COLORAPP_CONTRAST;Contrast (J) +!TP_COLORAPP_CONTRAST_Q;Contrast (Q) +!TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrast in CIECAM02 for the Q slider; it differs from L*a*b* and RGB contrast. +!TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from L*a*b* and RGB contrast. +!TP_COLORAPP_CURVEEDITOR1;Tone curve 1 +!TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L* (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of J or Q after CIECAM02.\n\nJ and Q are not shown in the main histogram panel.\n\nFor final output refer to the main histogram panel. +!TP_COLORAPP_CURVEEDITOR2;Tone curve 2 +!TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Same usage as with the second exposure tone curve. +!TP_COLORAPP_CURVEEDITOR3;Color curve +!TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Adjust either chroma, saturation or colorfulness.\n\nShows the histogram of chromaticity (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of C, s or M after CIECAM02.\n\nC, s and M are not shown in the main histogram panel.\nFor final output refer to the main histogram panel. +!TP_COLORAPP_DATACIE;CIECAM02 output histograms in curves +!TP_COLORAPP_DATACIE_TOOLTIP;When enabled, histograms in CIECAM02 curves show approximate values/ranges for J or Q, and C, s or M after the CIECAM02 adjustments.\nThis selection does not impact the main histogram panel.\n\nWhen disabled, histograms in CIECAM02 curves show L*a*b* values before CIECAM02 adjustments. +!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RawTherapee calculates an optimum value, which is then used by CAT02, and also for the entire CIECAM02.\nTo set the value manually, uncheck the check-box first (values above 65 are recommended). +!TP_COLORAPP_DEGREE_TOOLTIP;Amount of CIE Chromatic Adaptation Transform 2002. +!TP_COLORAPP_GAMUT;Gamut control (L*a*b*) +!TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in L*a*b* mode. +!TP_COLORAPP_HUE;Hue (h) +!TP_COLORAPP_HUE_TOOLTIP;Hue (h) - angle between 0° and 360°. +!TP_COLORAPP_LABEL;CIE Color Appearance Model 2002 +!TP_COLORAPP_LABEL_CAM02;Image Adjustments +!TP_COLORAPP_LABEL_SCENE;Scene Conditions +!TP_COLORAPP_LABEL_VIEWING;Viewing Conditions +!TP_COLORAPP_LIGHT;Lightness (J) +!TP_COLORAPP_LIGHT_TOOLTIP;Lightness in CIECAM02 differs from L*a*b* and RGB lightness. +!TP_COLORAPP_MODEL;WP Model +!TP_COLORAPP_MODEL_TOOLTIP;White-Point Model.\n\nWB [RT] + [output]: RT's white balance is used for the scene, CIECAM02 is set to D50, and the output device's white balance is set in Preferences > Color Management.\n\nWB [RT+CAT02] + [output]: RT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences - Color Management. +!TP_COLORAPP_RSTPRO;Red & skin-tones protection +!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin-tones protection affects both sliders and curves. +!TP_COLORAPP_SHARPCIE;--unused-- +!TP_COLORAPP_SHARPCIE_TOOLTIP;--unused-- +!TP_COLORAPP_SURROUND;Surround +!TP_COLORAPP_SURROUND_AVER;Average +!TP_COLORAPP_SURROUND_DARK;Dark +!TP_COLORAPP_SURROUND_DIM;Dim +!TP_COLORAPP_SURROUND_EXDARK;Extremly Dark (Cutsheet) +!TP_COLORAPP_SURROUND_TOOLTIP;Changes tones and colors to take into account the viewing conditions of the output device.\n\nAverage: Average light environment (standard). The image will not change.\n\nDim: Dim environment (TV). The image will become slighty dark.\n\nDark: Dark environment (projector). The image will become more dark.\n\nExtremly Dark: Extremly dark environment (cutsheet). The image will become very dark. +!TP_COLORAPP_SURSOURCE;Dark surround +!TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if image has a dark border. +!TP_COLORAPP_TCMODE_BRIGHTNESS;Brightness +!TP_COLORAPP_TCMODE_CHROMA;Chroma +!TP_COLORAPP_TCMODE_COLORF;Colorfulness +!TP_COLORAPP_TCMODE_LABEL1;Curve mode 1 +!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_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] +!TP_COLORAPP_WBRT;WB [RT] + [output] +!TP_COLORTONING_AB;o C/L +!TP_COLORTONING_AUTOSAT;Automatic +!TP_COLORTONING_BALANCE;Balance +!TP_COLORTONING_BY;o C/L +!TP_COLORTONING_CHROMAC;Opacity +!TP_COLORTONING_COLOR;Color +!TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;Chroma opacity as a function of luminance oC=f(L) +!TP_COLORTONING_HIGHLIGHT;Highlights +!TP_COLORTONING_HUE;Hue +!TP_COLORTONING_LABEL;Color Toning +!TP_COLORTONING_LAB;L*a*b* blending +!TP_COLORTONING_LUMAMODE;Preserve luminance +!TP_COLORTONING_LUMAMODE_TOOLTIP;If enabled, when you change color (red, green, cyan, blue, etc.) the luminance of each pixel is preserved. +!TP_COLORTONING_LUMA;Luminance +!TP_COLORTONING_METHOD;Method +!TP_COLORTONING_METHOD_TOOLTIP;"L*a*b* blending", "RGB sliders" and "RGB curves" use interpolated color blending.\n"Color balance (Shadows/Midtones/Highlights)" and "Saturation 2 colors" use direct colors.\n\nThe Black-and-White tool can be enabled when using any color toning method, which allows for color toning. +!TP_COLORTONING_MIDTONES;Midtones +!TP_COLORTONING_NEUTRAL;Reset sliders +!TP_COLORTONING_NEUTRAL_TIP;Reset all values (Shadows, Midtones, Highlights) to default. +!TP_COLORTONING_OPACITY;Opacity +!TP_COLORTONING_RGBCURVES;RGB - Curves +!TP_COLORTONING_RGBSLIDERS;RGB - Sliders +!TP_COLORTONING_SATURATEDOPACITY;Strength +!TP_COLORTONING_SATURATIONTHRESHOLD;Threshold +!TP_COLORTONING_SA;Saturation Protection +!TP_COLORTONING_SHADOWS;Shadows +!TP_COLORTONING_SPLITCOCO;Color Balance Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITCO;Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITLR;Saturation 2 colors +!TP_COLORTONING_STRENGTH;Strength +!TP_COLORTONING_STR;Strength +!TP_COLORTONING_TWO2;Special chroma '2 colors' +!TP_COLORTONING_TWOALL;Special chroma +!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_GTFRAME;Frame +!TP_CROP_GTGRID;Grid +!TP_CROP_GTHARMMEANS;Harmonic Means +!TP_CROP_GTTRIANGLE1;Golden Triangles 1 +!TP_CROP_GTTRIANGLE2;Golden Triangles 2 +!TP_CROP_PPI;PPI= +!TP_DARKFRAME_AUTOSELECT;Auto-selection +!TP_DARKFRAME_LABEL;Dark-Frame +!TP_DEFRINGE_LABEL;Defringe +!TP_DEFRINGE_RADIUS;Radius +!TP_DEFRINGE_THRESHOLD;Threshold +!TP_DIRPYRDENOISE_33;3×3 strong +!TP_DIRPYRDENOISE_55SOFT;5×5 +!TP_DIRPYRDENOISE_55;5×5 strong +!TP_DIRPYRDENOISE_77;7×7 (slow) +!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_ABM;Chroma only +!TP_DIRPYRDENOISE_AUTO;Automatic global +!TP_DIRPYRDENOISE_AUTO_TOOLTIP;Try to evaluate chroma noise\nBe careful, this calculation is average, and is quite subjective ! +!TP_DIRPYRDENOISE_AUT;Automatic global +!TP_DIRPYRDENOISE_BLUE;Chrominance - Blue-Yellow +!TP_DIRPYRDENOISE_C2TYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CCCURVE;Chrominance curve +!TP_DIRPYRDENOISE_CHROMAFR;Chrominance +!TP_DIRPYRDENOISE_CHROMA;Chrominance - Master +!TP_DIRPYRDENOISE_CTYPE;Auto method +!TP_DIRPYRDENOISE_CTYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nAutomatic multi-zones\nNo preview - works only during saving, but using the "Preview" method by matching the tile size and center to the preview size and center you can get an idea of the expected results.\nThe image is divided into tiles (about 10 to 70 depending on image size) and each tile receives its own chrominance noise reduction settings.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CURVEEDITOR_CC;Chroma +!TP_DIRPYRDENOISE_CURVEEDITOR_CC_TOOLTIP;Increase (multiply) the value of all chrominance sliders.\nThis curve lets you adjust the strength of chromatic noise reduction as a function of chromaticity, for instance to increase the action in areas of low saturation and to decrease it in those of high saturation. +!TP_DIRPYRDENOISE_CURVEEDITOR_L_TOOLTIP;Modulates action of 'Luminance' denoise +!TP_DIRPYRDENOISE_CUR;Curve +!TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on the gamma of the input color profile. An sRGB gamma is assumed, thus if the image uses an input color profile of a different gamma, the effects of luminance noise reduction will differ. +!TP_DIRPYRDENOISE_ENH;Enhanced mode +!TP_DIRPYRDENOISE_ENH_TOOLTIP;Increases noise reduction quality at the expense of a 20% processing time increase. +!TP_DIRPYRDENOISE_GAMMA;Gamma +!TP_DIRPYRDENOISE_GAMMA_TOOLTIP;Gamma varies noise reduction strength across the range of tones. Smaller values will target shadows, while larger values will stretch the effect to the brighter tones. +!TP_DIRPYRDENOISE_LABEL;Noise Reduction +!TP_DIRPYRDENOISE_LABM;L*a*b* +!TP_DIRPYRDENOISE_LAB;L*a*b* +!TP_DIRPYRDENOISE_LCURVE;Luminance curve +!TP_DIRPYRDENOISE_LDETAIL;Luminance - Detail +!TP_DIRPYRDENOISE_LM;Luminance only +!TP_DIRPYRDENOISE_LPLABM;Weighted L* (little) + a*b* (normal) +!TP_DIRPYRDENOISE_LTYPE;Luminance control +!TP_DIRPYRDENOISE_LUMAFR;Luminance +!TP_DIRPYRDENOISE_LUMAFR_TOOLTIP;Wavelet on luminance and Fourier transform for luminance detail +!TP_DIRPYRDENOISE_LUMA;Luminance +!TP_DIRPYRDENOISE_MANU;Manual +!TP_DIRPYRDENOISE_MAN;Manual +!TP_DIRPYRDENOISE_MEDMETHOD;Median method +!TP_DIRPYRDENOISE_MEDTYPE;Median type +!TP_DIRPYRDENOISE_MED;Median Filter +!TP_DIRPYRDENOISE_MED_TOOLTIP;Enabled median denoising +!TP_DIRPYRDENOISE_METHOD11;Quality +!TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. +!TP_DIRPYRDENOISE_METHOD;Method +!TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or L*a*b* methods can be used.\n\nFor non-raw images the L*a*b* method will be used, regardless of the selection. +!TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - +!TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 +!TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. +!TP_DIRPYRDENOISE_PASSES;Median iterations +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PON;Auto multi-zones +!TP_DIRPYRDENOISE_PREVLABEL;Preview size=%1, Center: Px=%2 Py=%3 +!TP_DIRPYRDENOISE_PREV;Preview +!TP_DIRPYRDENOISE_PRE;Preview multi-zones +!TP_DIRPYRDENOISE_RED;Chrominance - Red-Green +!TP_DIRPYRDENOISE_RGBM;RGB +!TP_DIRPYRDENOISE_RGB;RGB +!TP_DIRPYRDENOISE_SHALBI;High +!TP_DIRPYRDENOISE_SHAL;Standard +!TP_DIRPYRDENOISE_SLI;Slider +!TP_DIRPYRDENOISE_SOFT;3x3 +!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_LUMAFINEST;Finest +!TP_DIRPYREQUALIZER_LUMANEUTRAL;Neutral +!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_THRESHOLD;Threshold +!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;Auto Distortion Correction +!TP_DISTORTION_AUTO_TIP;Correct lens distortion automatically for some cameras (Micro 4/3, some compact digital cameras, etc.). +!TP_EPD_EDGESTOPPING;Edge stopping +!TP_EPD_GAMMA;Gamma +!TP_EPD_LABEL;Tone Mapping +!TP_EPD_REWEIGHTINGITERATES;Reweighting iterates +!TP_EPD_SCALE;Scale +!TP_EPD_STRENGTH;Strength +!TP_EPD_TOOLTIP;Tone mapping is possible in L*a*b* mode (standard) and CIECAM02 mode.\n\nWhen in L*a*b* mode, tone mapping can also be used on the residual image of the Wavelet Levels tool.\n\nTo engage CIECAM02 tone mapping mode enable the following settings:\n1. CIECAM02\n2. Algorithm="Brightness + Colorfulness (QM)"\n3. "Tone mapping using CIECAM02 brightness (Q)" +!TP_EXPOSURE_AUTOLEVELS_TIP;Toggles execution of Auto Levels to automatically set Exposure slider values based on an image analysis.\nEnables Highlight Reconstruction if necessary. +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in Auto Levels operation. +!TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Highlight compression threshold +!TP_EXPOSURE_CURVEEDITOR1;Tone curve 1 +!TP_EXPOSURE_CURVEEDITOR2;Tone curve 2 +!TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Please refer to the "Exposure > Tone Curves" RawPedia article to learn how to achieve the best results by using two tone curves. +!TP_EXPOSURE_SATURATION;Saturation +!TP_EXPOSURE_TCMODE_FILMLIKE;Film-like +!TP_EXPOSURE_TCMODE_LABEL1;Curve mode 1 +!TP_EXPOSURE_TCMODE_LABEL2;Curve mode 2 +!TP_EXPOSURE_TCMODE_LUMINANCE;Luminance +!TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Saturation and Value Blending +!TP_EXPOSURE_TCMODE_STANDARD;Standard +!TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard +!TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points +!TP_EXPOS_WHITEPOINT_LABEL;Raw White Points +!TP_FILMSIMULATION_LABEL;Film Simulation +!TP_FILMSIMULATION_STRENGTH;Strength +!TP_FILMSIMULATION_ZEROCLUTSFOUND;Set HaldCLUT directory in Preferences +!TP_FLATFIELD_AUTOSELECT;Auto-selection +!TP_FLATFIELD_BLURRADIUS;Blur radius +!TP_FLATFIELD_BLURTYPE;Blur type +!TP_FLATFIELD_BT_AREA;Area +!TP_FLATFIELD_BT_HORIZONTAL;Horizontal +!TP_FLATFIELD_BT_VERTHORIZ;Vertical + Horizontal +!TP_FLATFIELD_BT_VERTICAL;Vertical +!TP_FLATFIELD_CLIPCONTROL;Clip control +!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. +!TP_FLATFIELD_LABEL;Flat-Field +!TP_GAMMA_CURV;Gamma +!TP_GAMMA_FREE;Free gamma +!TP_GAMMA_OUTPUT;Output gamma +!TP_GAMMA_SLOP;Slope (linear) +!TP_GENERAL_11SCALE_TOOLTIP;The effects of this tool are only visible or only accurate at a preview scale of 1:1. +!TP_GRADIENT_CENTER;Center +!TP_GRADIENT_CENTER_X;Center X +!TP_GRADIENT_CENTER_X_TOOLTIP;Shift gradient to the left (negative values) or right (positive values). +!TP_GRADIENT_CENTER_Y;Center Y +!TP_GRADIENT_CENTER_Y_TOOLTIP;Shift gradient up (negative values) or down (positive values). +!TP_GRADIENT_DEGREE;Angle +!TP_GRADIENT_DEGREE_TOOLTIP;Rotation angle in degrees. +!TP_GRADIENT_FEATHER;Feather +!TP_GRADIENT_FEATHER_TOOLTIP;Gradient width in percent of the image diagonal. +!TP_GRADIENT_LABEL;Graduated Filter +!TP_GRADIENT_STRENGTH;Strength +!TP_GRADIENT_STRENGTH_TOOLTIP;Filter strength in stops. +!TP_HLREC_BLEND;Blend +!TP_HLREC_ENA_TOOLTIP;Could be activated by Auto Levels. +!TP_HSVEQUALIZER_CHANNEL;Channel +!TP_HSVEQUALIZER_HUE;H +!TP_HSVEQUALIZER_LABEL;HSV Equalizer +!TP_HSVEQUALIZER_SAT;S +!TP_HSVEQUALIZER_VAL;V +!TP_ICM_BLENDCMSMATRIX;Blend ICC highlights with matrix +!TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover clipped highlights when using LUT-based ICC profiles. +!TP_ICM_DCPILLUMINANT;Illuminant +!TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolated +!TP_ICM_DCPILLUMINANT_TOOLTIP;Select which embedded DCP illuminant to employ. Default is "interpolated" which is a mix between the two based on white balance. The setting is only enabled if a Dual-Illuminant DCP with interpolation support is selected. +!TP_ICM_INPUTCAMERAICC;Auto-matched camera profile +!TP_ICM_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input color profiles. These profiles are more precise than simpler matrix ones. They are not available for all cameras. These profiles are stored in the /iccprofiles/input and /dcpprofiles folders and are automatically retrieved based on a file name matching to the exact model name of the camera. +!TP_ICM_INPUTCAMERA_TOOLTIP;Use a simple color matrix from dcraw, an enhanced RawTherapee version (whichever is available based on camera model) or one embedded in the DNG. +!TP_ICM_INPUTCUSTOM_TOOLTIP;Select your own DCP/ICC color profile file for the camera. +!TP_ICM_INPUTEMBEDDED_TOOLTIP;Use color profile embedded in non-raw files. +!TP_ICM_INPUTNONE;No profile +!TP_ICM_INPUTNONE_TOOLTIP;Use no input color profile at all.\nUse only in special cases. +!TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance +!TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. The result can be used for calibration purposes and generation of a camera profile. +!TP_ICM_TONECURVE;Use DCP's tone curve +!TP_ICM_TONECURVE_TOOLTIP;Employ the embedded DCP tone curve. The setting is only enabled if the selected DCP has a tone curve. +!TP_IMPULSEDENOISE_LABEL;Impulse Noise Reduction +!TP_IMPULSEDENOISE_THRESH;Threshold +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid color shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction. +!TP_LABCURVE_BRIGHTNESS;Lightness +!TP_LABCURVE_CHROMATICITY;Chromaticity +!TP_LABCURVE_CHROMA_TOOLTIP;To apply B&W toning, set Chromaticity to -100. +!TP_LABCURVE_CONTRAST;Contrast +!TP_LABCURVE_CURVEEDITOR;Luminance Curve +!TP_LABCURVE_CURVEEDITOR_A_RANGE1;Green Saturated +!TP_LABCURVE_CURVEEDITOR_A_RANGE2;Green Pastel +!TP_LABCURVE_CURVEEDITOR_A_RANGE3;Red Pastel +!TP_LABCURVE_CURVEEDITOR_A_RANGE4;Red Saturated +!TP_LABCURVE_CURVEEDITOR_B_RANGE1;Blue Saturated +!TP_LABCURVE_CURVEEDITOR_B_RANGE2;Blue Pastel +!TP_LABCURVE_CURVEEDITOR_B_RANGE3;Yellow Pastel +!TP_LABCURVE_CURVEEDITOR_B_RANGE4;Yellow Saturated +!TP_LABCURVE_CURVEEDITOR_CC;CC +!TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutral +!TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Dull +!TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastel +!TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Saturated +!TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Chromaticity according to chromaticity C=f(C) +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to hue C=f(H) +!TP_LABCURVE_CURVEEDITOR_CL;CL +!TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Chromaticity according to luminance C=f(L) +!TP_LABCURVE_CURVEEDITOR_HH;HH +!TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Hue according to hue H=f(H) +!TP_LABCURVE_CURVEEDITOR_LC;LC +!TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminance according to chromaticity L=f(C) +!TP_LABCURVE_CURVEEDITOR_LH;LH +!TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H) +!TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminance according to luminance L=f(L) +!TP_LABCURVE_LABEL;L*a*b* Adjustments +!TP_LABCURVE_LCREDSK;Restrict LC to red and skin-tones +!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_LENSGEOM_AUTOCROP;Auto-Crop +!TP_LENSGEOM_FILL;Auto-fill +!TP_LENSGEOM_LABEL;Lens / Geometry +!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_USECA;Chromatic aberration correction +!TP_LENSPROFILE_USEDIST;Distortion correction +!TP_LENSPROFILE_USEVIGN;Vignetting correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Resets exposure sliders to neutral values.\nApplies to the same controls that Auto Levels applies to, regardless of whether you used Auto Levels or not. +!TP_PCVIGNETTE_FEATHER;Feather +!TP_PCVIGNETTE_FEATHER_TOOLTIP;Feathering:\n0 = corners only,\n50 = halfway to center,\n100 = to center. +!TP_PCVIGNETTE_LABEL;Vignette Filter +!TP_PCVIGNETTE_ROUNDNESS;Roundness +!TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness:\n0 = rectangle,\n50 = fitted ellipse,\n100 = circle. +!TP_PCVIGNETTE_STRENGTH;Strength +!TP_PCVIGNETTE_STRENGTH_TOOLTIP;Filter strength in stops (reached in corners). +!TP_PERSPECTIVE_HORIZONTAL;Horizontal +!TP_PERSPECTIVE_LABEL;Perspective +!TP_PERSPECTIVE_VERTICAL;Vertical +!TP_PFCURVE_CURVEEDITOR_CH;Hue +!TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Controls defringe strength by color.\nHigher = more,\nLower = less. +!TP_PREPROCESS_DEADPIXFILT;Dead pixel filter +!TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Tries to suppress dead pixels. +!TP_PREPROCESS_GREENEQUIL;Green equilibration +!TP_PREPROCESS_HOTPIXFILT;Hot pixel filter +!TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Tries to suppress hot pixels. +!TP_PREPROCESS_LABEL;Preprocessing +!TP_PREPROCESS_LINEDENOISE;Line noise filter +!TP_PREPROCESS_NO_FOUND;None found +!TP_RAWCACORR_AUTO;Auto-correction +!TP_RAWCACORR_CABLUE;Blue +!TP_RAWCACORR_CARED;Red +!TP_RAWEXPOS_BLACKS;Black Levels +!TP_RAWEXPOS_BLACK_0;Green 1 (lead) +!TP_RAWEXPOS_BLACK_1;Red +!TP_RAWEXPOS_BLACK_2;Blue +!TP_RAWEXPOS_BLACK_3;Green 2 +!TP_RAWEXPOS_BLACK_BLUE;Blue +!TP_RAWEXPOS_BLACK_GREEN;Green +!TP_RAWEXPOS_BLACK_RED;Red +!TP_RAWEXPOS_LINEAR;White-point correction +!TP_RAWEXPOS_PRESER;Highlight preservation +!TP_RAWEXPOS_RGB;Red, Green, Blue +!TP_RAWEXPOS_TWOGREEN;Link greens +!TP_RAW_DCBENHANCE;DCB enhancement +!TP_RAW_DCBITERATIONS;Number of DCB iterations +!TP_RAW_DMETHOD_PROGRESSBAR;%1 demosaicing... +!TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Demosaicing refinement... +!TP_RAW_DMETHOD_TOOLTIP;Note: IGV and LMMSE are dedicated to high ISO images to aid in noise reduction without leading to maze patterns, posterization or a washed-out look. +!TP_RAW_HD;Threshold +!TP_RAW_HD_TOOLTIP;Lower values make hot/dead pixel detection more aggressive, but false positives may lead to artifacts. If you notice any artifacts appearing when enabling the Hot/Dead Pixel Filters, gradually increase the threshold value until they disappear. +!TP_RAW_LABEL;Demosaicing +!TP_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!TP_RAW_LMMSE_TOOLTIP;Adds gamma (step 1), median (steps 2-4) and refinement (steps 5-6) to reduce artifacts and improve the signal-to-noise ratio. +!TP_RAW_SENSOR_BAYER_LABEL;Sensor with Bayer Matrix +!TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;3-pass gives best results (recommended for low ISO images).\n1-pass is almost undistinguishable from 3-pass for high ISO images and is faster. +!TP_RAW_SENSOR_XTRANS_LABEL;Sensor with X-Trans Matrix +!TP_RESIZE_APPLIESTO;Applies to: +!TP_RESIZE_CROPPEDAREA;Cropped Area +!TP_RESIZE_FITBOX;Bounding Box +!TP_RESIZE_FULLIMAGE;Full Image +!TP_RESIZE_HEIGHT;Height +!TP_RESIZE_LANCZOS;Lanczos +!TP_RESIZE_SPECIFY;Specify: +!TP_RESIZE_WIDTH;Width +!TP_RGBCURVES_BLUE;B +!TP_RGBCURVES_CHANNEL;Channel +!TP_RGBCURVES_GREEN;G +!TP_RGBCURVES_LABEL;RGB Curves +!TP_RGBCURVES_LUMAMODE;Luminosity mode +!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_RGBCURVES_RED;R +!TP_SAVEDIALOG_OK_TIP;Shortcut: Ctrl-Enter +!TP_SHADOWSHLIGHTS_SHARPMASK;Sharp mask +!TP_SHARPENEDGE_AMOUNT;Quantity +!TP_SHARPENEDGE_LABEL;Edges +!TP_SHARPENEDGE_PASSES;Iterations +!TP_SHARPENEDGE_THREE;Luminance only +!TP_SHARPENING_TOOLTIP;Expect a slightly different effect when using with CIECAM02. If difference is observed, adjust to taste. +!TP_SHARPENMICRO_AMOUNT;Quantity +!TP_SHARPENMICRO_LABEL;Microcontrast +!TP_SHARPENMICRO_MATRIX;3×3 matrix instead of 5×5 +!TP_SHARPENMICRO_UNIFORMITY;Uniformity +!TP_VIBRANCE_AVOIDCOLORSHIFT;Avoid color shift +!TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Red/Purple +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Red +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Red/Yellow +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Yellow +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Hue according to hue H=f(H) +!TP_VIBRANCE_LABEL;Vibrance +!TP_VIBRANCE_PASTELS;Pastel Tones +!TP_VIBRANCE_PASTSATTOG;Link pastel and saturated tones +!TP_VIBRANCE_PROTECTSKINS;Protect skin-tones +!TP_VIBRANCE_PSTHRESHOLD;Pastel/saturated tones threshold +!TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Saturation threshold +!TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;The vertical axis represents pastel tones at the bottom and saturated tones at the top.\nThe horizontal axis represents the saturation range. +!TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Pastel/saturated transition's weighting +!TP_VIBRANCE_SATURATED;Saturated Tones +!TP_VIGNETTING_CENTER;Center +!TP_VIGNETTING_CENTER_X;Center X +!TP_VIGNETTING_CENTER_Y;Center Y +!TP_VIGNETTING_STRENGTH;Strength +!TP_WAVELET_1;Level 1 +!TP_WAVELET_2;Level 2 +!TP_WAVELET_3;Level 3 +!TP_WAVELET_4;Level 4 +!TP_WAVELET_5;Level 5 +!TP_WAVELET_6;Level 6 +!TP_WAVELET_7;Level 7 +!TP_WAVELET_8;Level 8 +!TP_WAVELET_9;Level 9 +!TP_WAVELET_ALL;All levels in all directions +!TP_WAVELET_APPLYTO;Apply To +!TP_WAVELET_AVOID;Avoid color shift +!TP_WAVELET_B0;Black +!TP_WAVELET_B1;Grey +!TP_WAVELET_B2;Residual +!TP_WAVELET_BACUR;Curve +!TP_WAVELET_BALANCE;Contrast balance d/v-h +!TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chromaticity or residual tone mapping are activated, the effect due to balance is amplified. +!TP_WAVELET_BALCHRO;Chroma balance +!TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chromaticity balance. +!TP_WAVELET_BANONE;None +!TP_WAVELET_BASLI;Slider +!TP_WAVELET_BATYPE;Contrast balance method +!TP_WAVELET_CCURVE;Local contrast +!TP_WAVELET_CH1;Whole chromaticity range +!TP_WAVELET_CH2;Saturated/pastel +!TP_WAVELET_CH3;Link contrast levels +!TP_WAVELET_CHCU;Curve +!TP_WAVELET_CHRO;Saturated/pastel threshold +!TP_WAVELET_CHRO_TOOLTIP;Sets the wavelet level which will be the threshold between saturated and pastel colors.\n1-x: saturated\nx-9: pastel\n\nIf the value exceeds the amount of wavelet levels you are using then it will be ignored. +!TP_WAVELET_CHR;Chroma-contrast link strength +!TP_WAVELET_CHR_TOOLTIP;Adjusts chromaticity as a function of "contrast levels" and "chroma-contrast link strength" +!TP_WAVELET_CHSL;Sliders +!TP_WAVELET_CHTYPE;Chrominance method +!TP_WAVELET_COLORT;Opacity Red-Green +!TP_WAVELET_COMBOTH;Both +!TP_WAVELET_COMPCONT;Contrast +!TP_WAVELET_COMPGAMMA;Compression gamma +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjusting the gamma of the residual image allow you to equilibrate the data and histogram. +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjust gamma for residual image and compression.\nAllow to equilibrate data and histogram +!TP_WAVELET_COMPTM;Tone mapping +!TP_WAVELET_CONTEDIT;'After' Contrast curve +!TP_WAVELET_CONTEDIT;'After' contrast curve +!TP_WAVELET_CONTRAST_MINUS;Contrast - +!TP_WAVELET_CONTRAST_PLUS;Contrast + +!TP_WAVELET_CONTRA;Contrast +!TP_WAVELET_CONTRA_TOOLTIP;Changes contrast of the residual image. +!TP_WAVELET_CONTR;Gamut +!TP_WAVELET_CTYPE;Chrominance control +!TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modifies local contrast as a function of the original local contrast (absciss)\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 100..300)\n66% absciss represents standard deviation of local contrast (real value about 300..800)\n100% represents maximum (real value about 3000..8000) +!TP_WAVELET_CURVEEDITOR_CH;Contrast levels=f(Hue) +!TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modifies each level's contrast as a function oh hue.\nTake care not to overwrite changes made with the Gamut Hue controls.\nThe curve will only have an effect when wavelet contrast level sliders are non-zero. +!TP_WAVELET_CURVEEDITOR_CL;L +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Applies a final contrast luminance curve at the end of the wavelet treatment. +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Apply a contrast luminance curve at the end of wavelet level threatment +!TP_WAVELET_CURVEEDITOR_HH;HH +!TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modifies the residual image's hue as a function of hue. +!TP_WAVELET_DALL;All directions +!TP_WAVELET_DAUB;Edge performance +!TP_WAVELET_DAUB_TOOLTIP;Changes Daubechies coefficients:\nD4 = Standard,\nD14 = Often best performance, 10% more time-intensive.\n\nAffects edge detection as well as the general quality of the firsts levels. However the quality is not strictly related to this coefficient and can vary with images and uses. +!TP_WAVELET_DISP;Preview Settings +!TP_WAVELET_DONE;Vertical +!TP_WAVELET_DTHR;Diagonal +!TP_WAVELET_DTWO;Horizontal +!TP_WAVELET_EDCU;Curve +!TP_WAVELET_EDGCONT;Local contrast +!TP_WAVELET_EDGCONT_TOOLTIP;Adjusting the points to the left decreases contrast, and to the right increases it.\nBottom-left, Top-Left, Top-Right, Bottom-right represent respectively local contast for low values, mean, mean+stdev, maxima +!TP_WAVELET_EDGEDETECTTHR2;Threshold high (detection) +!TP_WAVELET_EDGEDETECTTHR;Threshold low (noise) +!TP_WAVELET_EDGEDETECTTHR_TOOLTIP;This adjuster lets you target edge detection for example to avoid applying edge sharpness to fine details, such as noise in the sky. +!TP_WAVELET_EDGEDETECT;Gradient sensitivity +!TP_WAVELET_EDGEDETECT_TOOLTIP;Moving the slider to the right increases edge sensitivity. This affects local contrast, edge settings and noise. +!TP_WAVELET_EDGE;Edge Sharpness +!TP_WAVELET_EDGREINF_TOOLTIP;Reinforce or reduce the action of the first level, do the opposite to the second level, and leave the rest unchanged. +!TP_WAVELET_EDGTHRESH;Detail +!TP_WAVELET_EDGTHRESH_TOOLTIP;Change the repartition between the first levels and the others. The higher the threshold the more the action is centred on the first levels. Be careful with negative values, they increase the action of high levels and can introduce artifacts. +!TP_WAVELET_EDRAD;Radius +!TP_WAVELET_EDRAD_TOOLTIP;This radius adjustment is very different from those in other sharpening tools. Its value is compared to each level through a complex function. In this sense, a value of zero still has an effect. +!TP_WAVELET_EDSL;Threshold Sliders +!TP_WAVELET_EDTYPE;Local contrast method +!TP_WAVELET_EDVAL;Strength +!TP_WAVELET_FINAL;Final Touchup +!TP_WAVELET_FINEST;Finest +!TP_WAVELET_HIGHLIGHT;Highlight luminance range +!TP_WAVELET_HS1;Whole luminance range +!TP_WAVELET_HS2;Shadows/Highlights +!TP_WAVELET_HUESKIN;Skin hue +!TP_WAVELET_HUESKIN_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_HUESKY;Sky hue +!TP_WAVELET_HUESKY_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_INF;Below or equal the level +!TP_WAVELET_ITER;Delta balance levels +!TP_WAVELET_ITER_TOOLTIP;Left: increase low levels and reduce high levels,\nRight: reduce low levels and increase high levels. +!TP_WAVELET_LABEL;Wavelet levels +!TP_WAVELET_LARGEST;Coarsest +!TP_WAVELET_LEVCH;Chromaticity +!TP_WAVELET_LEVELS;Wavelet levels +!TP_WAVELET_LEVELS_TOOLTIP;Choose the number of detail levels the image is to be decomposed into. More levels require more RAM and require a longer processing time. +!TP_WAVELET_LEVF;Contrast +!TP_WAVELET_LEVLABEL;Preview maximum possible levels = %1 +!TP_WAVELET_LEVONE;Level 2 +!TP_WAVELET_LEVTWO;Level 3 +!TP_WAVELET_LEVZERO;Level 1 +!TP_WAVELET_LINKEDG;Link with Edge Sharpness' Strength +!TP_WAVELET_LIPST;Enhanced algorithm +!TP_WAVELET_LIPST_TOOLTIP;This algorithm uses Lipschitz regularity to increase edge detection quality at a cost of increased processing time and memory requirements. +!TP_WAVELET_LOWLIGHT;Shadow luminance range +!TP_WAVELET_MEDGREINF;First level +!TP_WAVELET_MEDILEV;Edge detection +!TP_WAVELET_MEDI;Reduce artifacts in blue sky +!TP_WAVELET_NEUTRAL;Neutral +!TP_WAVELET_NOISE;Denoise and Refine +!TP_WAVELET_NOIS;Denoise +!TP_WAVELET_ONE;One level +!TP_WAVELET_OPACITYWL;Final local contrast +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify final local contrast in function of last local contrast (absciss) for all levels decomposition\nTake into account: \na)contrast levels \nb)edge sharpness \nc)contrast balance\nd)decomposition-recomposition\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 200..1000)\n66% absciss represents standard deviation of local contrast (real value about 1000..2000)\n100% represents maximum (real value about 5000..13000) +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify the final local contrast at the end of the wavelet treatment.\n\nThe left side represents the smallest local contrast, progressing to the largest local contrast on the right. +!TP_WAVELET_OPACITYW;Contrast balance d/v-h curve +!TP_WAVELET_OPACITY;Opacity Blue-Yellow +!TP_WAVELET_PASTEL;Pastel chromaticity +!TP_WAVELET_PREVIEWBACK;Background +!TP_WAVELET_PREVIEWLEVELS;Preview +!TP_WAVELET_RE1;Reinforced +!TP_WAVELET_RE2;Unchanged +!TP_WAVELET_RE3;Reduced +!TP_WAVELET_RESCHRO;Chromaticity +!TP_WAVELET_RESCONH;Highlights +!TP_WAVELET_RESCON;Shadows +!TP_WAVELET_RESID;Residual image +!TP_WAVELET_SAT;Saturated chromaticity +!TP_WAVELET_SETTINGS;Wavelet Settings +!TP_WAVELET_SKIN;Skin targetting/protection +!TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected. +!TP_WAVELET_SKY;Sky targetting/protection +!TP_WAVELET_SKY_TOOLTIP;At -100 sky-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 sky-tones are protected while all other tones are affected. +!TP_WAVELET_STRENGTH;Strength +!TP_WAVELET_STREN;Strength +!TP_WAVELET_SUPE;Extra +!TP_WAVELET_SUP;Above the level +!TP_WAVELET_THRESHOLD2;Shadow levels +!TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels between 9 and 9 minus the value will be affected by the shadow luminance range. Other levels will be fully treated. The highest level possible is limited by the highlight level value (9 minus highlight level value). +!TP_WAVELET_THRESHOLD;Highlight levels +!TP_WAVELET_THRESHOLD_TOOLTIP;Only levels beyond the chosen value will be affected by the highlight luminance range. Other levels will be fully treated. The chosen value here limits the highest possible value of the shadow levels. +!TP_WAVELET_THRH;Highlights threshold +!TP_WAVELET_THR;Shadows threshold +!TP_WAVELET_TILESBIG;Big tiles +!TP_WAVELET_TILESFULL;Full image +!TP_WAVELET_TILESIZE;Tiling method +!TP_WAVELET_TILESLIT;Little tiles +!TP_WAVELET_TILES_TOOLTIP;Processing the full image leads to better quality and is the recommended option, while using tiles is a fall-back solution for users with little RAM. Refer to RawPedia for memory requirements. +!TP_WAVELET_TMHIGH;High +!TP_WAVELET_TMLOWHIGH;Low+High +!TP_WAVELET_TMNONE;None +!TP_WAVELET_TMSTD;Standard +!TP_WAVELET_TMSTRENGTH;Compression strength +!TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image. When the value is different from 0, the Strength and Gamma sliders of the Tone Mapping tool in the Exposure tab will become grayed out. +!TP_WAVELET_TMTYPE;Compression method +!TP_WAVELET_TON;Toning +!TP_WAVELET_daub2;D2 - low +!TP_WAVELET_daub4;D4 - standard +!TP_WAVELET_daub6;D6 - standard plus +!TP_WAVELET_daub10;D10 - medium +!TP_WAVELET_daub14;D14 - high +!TP_WBALANCE_CLOUDY;Cloudy +!TP_WBALANCE_DAYLIGHT;Daylight (sunny) +!TP_WBALANCE_EQBLUERED;Blue/Red equalizer +!TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behavior of "white balance" by modulating the blue/red balance.\nThis can be useful when shooting conditions:\na) are far from the standard illuminant (e.g. underwater),\nb) are far from conditions where calibrations were performed,\nc) where the matrices or ICC profiles are unsuitable. +!TP_WBALANCE_FLASH55;Leica +!TP_WBALANCE_FLASH60;Standard, Canon, Pentax, Olympus +!TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta +!TP_WBALANCE_FLASH_HEADER;Flash +!TP_WBALANCE_FLUO1;F1 - Daylight +!TP_WBALANCE_FLUO2;F2 - Cool White +!TP_WBALANCE_FLUO3;F3 - White +!TP_WBALANCE_FLUO4;F4 - Warm White +!TP_WBALANCE_FLUO5;F5 - Daylight +!TP_WBALANCE_FLUO6;F6 - Lite White +!TP_WBALANCE_FLUO7;F7 - D65 Daylight Simulator +!TP_WBALANCE_FLUO8;F8 - D50 / Sylvania F40 Design +!TP_WBALANCE_FLUO9;F9 - Cool White Deluxe +!TP_WBALANCE_FLUO10;F10 - Philips TL85 +!TP_WBALANCE_FLUO11;F11 - Philips TL84 +!TP_WBALANCE_FLUO12;F12 - Philips TL83 +!TP_WBALANCE_FLUO_HEADER;Fluorescent +!TP_WBALANCE_GTI;GTI +!TP_WBALANCE_HMI;HMI +!TP_WBALANCE_JUDGEIII;JudgeIII +!TP_WBALANCE_LAMP_HEADER;Lamp +!TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 +!TP_WBALANCE_LED_HEADER;LED +!TP_WBALANCE_LED_LSI;LSI Lumelex 2040 +!TP_WBALANCE_SHADE;Shade +!TP_WBALANCE_SOLUX35;Solux 3500K +!TP_WBALANCE_SOLUX41;Solux 4100K +!TP_WBALANCE_SOLUX47;Solux 4700K (vendor) +!TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) +!TP_WBALANCE_TUNGSTEN;Tungsten +!TP_WBALANCE_WATER1;UnderWater 1 +!TP_WBALANCE_WATER2;UnderWater 2 +!TP_WBALANCE_WATER_HEADER;UnderWater +!ZOOMPANEL_100;(100%) +!ZOOMPANEL_NEWCROPWINDOW;Open (new) detail window +!ZOOMPANEL_ZOOM100;Zoom to 100%\nShortcut: z +!ZOOMPANEL_ZOOMFITCROPSCREEN;Fit crop to screen\nShortcut: Alt-f +!ZOOMPANEL_ZOOMFITSCREEN;Fit whole image to screen\nShortcut: f +!ZOOMPANEL_ZOOMIN;Zoom In\nShortcut: + +!ZOOMPANEL_ZOOMOUT;Zoom Out\nShortcut: - diff --git a/rtdata/languages/Swedish b/rtdata/languages/Swedish new file mode 100644 index 000000000..59e08e859 --- /dev/null +++ b/rtdata/languages/Swedish @@ -0,0 +1,1853 @@ +#01 2008-01-22 Emil Ericsson +#02 2010-2013 Updated by Johan Thor +#03 2014-02-09 Last updated by Johan Thor + +ABOUT_TAB_BUILD;Version +ABOUT_TAB_CREDITS;Erkännande +ABOUT_TAB_LICENSE;Licens +ABOUT_TAB_RELEASENOTES;Versionsnyheter +ABOUT_TAB_SPLASH;Splash +ADJUSTER_RESET_TO_DEFAULT;Återställ till standard +BATCHQUEUE_AUTOSTART;Autostart +BATCHQUEUE_DESTFILENAME;Sökväg och filnamn +BATCH_PROCESSING;Batchbehandling +CURVEEDITOR_CURVES;Kurvor +CURVEEDITOR_CURVE;Kurva +CURVEEDITOR_CUSTOM;Egen +CURVEEDITOR_DARKS;Mörka partier +CURVEEDITOR_HIGHLIGHTS;Högdagrar +CURVEEDITOR_LIGHTS;Ljusa partier +CURVEEDITOR_LINEAR;Linjär +CURVEEDITOR_LOADDLGLABEL;Ladda kurva... +CURVEEDITOR_MINMAXCPOINTS;Minimi/Maxima kontrollpunkter +CURVEEDITOR_NURBS;Kontrollerad justering +CURVEEDITOR_PARAMETRIC;Parametisk +CURVEEDITOR_SAVEDLGLABEL;Spara kurva... +CURVEEDITOR_SHADOWS;Skuggor +CURVEEDITOR_TOOLTIPCOPY;Kopiera nuvarande kurva till klippbordet +CURVEEDITOR_TOOLTIPLINEAR;Återställ kurva till linjär +CURVEEDITOR_TOOLTIPLOAD;Ladda kurva från fil +CURVEEDITOR_TOOLTIPPASTE;Klistra in kurva från klippbordet +CURVEEDITOR_TOOLTIPSAVE;Spara nuvarande kurva +CURVEEDITOR_TYPE;Typ: +DIRBROWSER_FOLDERS;Mappar +EDITWINDOW_TITLE;Bildredigering +EXIFFILTER_APERTURE;Bländare +EXIFFILTER_CAMERA;Kamera +EXIFFILTER_EXPOSURECOMPENSATION;Exponeringskompensation (EV) +EXIFFILTER_FILETYPE;Filtyp +EXIFFILTER_FOCALLEN;Brännvidd +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Objektiv +EXIFFILTER_METADATAFILTER;Använd metadatafilter +EXIFFILTER_SHUTTER;Slutartid +EXIFPANEL_ADDEDITHINT;Lägg till en ny eller redigera en etikett +EXIFPANEL_ADDEDIT;Lägg till/Redigera +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Ange värde +EXIFPANEL_ADDTAGDLG_SELECTTAG;Välj etikett +EXIFPANEL_ADDTAGDLG_TITLE;Lägg till/redigera etikett +EXIFPANEL_KEEPHINT;Behåll de valda etiketterna vid spara +EXIFPANEL_KEEP;Behåll +EXIFPANEL_REMOVEHINT;Ta bort de valda etiketterna vid spara +EXIFPANEL_REMOVE;Ta bort +EXIFPANEL_RESETALLHINT;Återställ alla etiketter till deras originalvärden +EXIFPANEL_RESETALL;Återställ alla +EXIFPANEL_RESETHINT;Återställ de valda etiketterna till deras originalvärden +EXIFPANEL_RESET;Återställ +EXIFPANEL_SUBDIRECTORY;Underkatalog +EXPORT_BYPASS_ALL;Markera/Avmarkera allt +EXPORT_BYPASS_DEFRINGE;Förbigå överstrålning +EXPORT_BYPASS_DIRPYRDENOISE;Förbigå brusreducering +EXPORT_BYPASS_DIRPYREQUALIZER;Förbigå kontrast genom detaljnivåer +EXPORT_BYPASS_RAW_CA;Förbigå reducering av kromatiska abberationer (För råbilder) +EXPORT_BYPASS_RAW_CCSTEPS;Förbigå undertryckande av falska färger (För råbilder) +EXPORT_BYPASS_RAW_DCB_ENHANCE;Förbigå förbättringssteg för DCB (För råbilder) +EXPORT_BYPASS_RAW_DCB_ITERATIONS;Förbigå DCB-iterationer (För råbilder) +EXPORT_BYPASS_RAW_DF;Förbigå svartbild (För råbilder) +EXPORT_BYPASS_RAW_FF;Förbigå plattfält (För råbilder) +EXPORT_BYPASS_RAW_GREENTHRESH;Förbigå grönbalansering (För råbilder) +EXPORT_BYPASS_RAW_LINENOISE;Förbigå Linjärt brusfilter (För råbilder) +EXPORT_BYPASS_RAW_LMMSE_ITERATIONS;Förbigå förbättringssteg för LMMSE (För råbilder) +EXPORT_BYPASS_SHARPENEDGE;Förbigå kantskärpning +EXPORT_BYPASS_SHARPENING;Förbigå skärpning +EXPORT_BYPASS_SHARPENMICRO;Förbigå mikrokontrast +EXPORT_BYPASS_SH_HQ;Förbigå skuggor/högdagrar (hög kvalitet) +EXPORT_FASTEXPORTOPTIONS;Inställningar för snabbexport +EXPORT_INSTRUCTIONS;Snabbexport erbjuder snabbare konvertering genom att åsidosätta tidskrävande verktyg och framkallningsinställningar. Batchkön körs då med dessa, mindre krävande, inställningar istället så länge det här alternativet är valt. Den här metoden rekommenderas för de konverteringar där användningsområdet tillåter en lägre kvalitet på de färdiga bilderna. Genom att använda det här alternativet görs inga modifieringar i bildens normala framkallningsinställningar. +EXPORT_MAXHEIGHT;Maximal höjd: +EXPORT_MAXWIDTH;Maximal vidd: +EXPORT_PUTTOQUEUEFAST; Lägg till i kö för snabbexport +EXPORT_RAW_DMETHOD;Demosaic-metod +EXTPROGTARGET_1;Rå +EXTPROGTARGET_2;köhanterad +FILEBROWSER_ADDDELTEMPLATE;Lägg till/ta bort förinställningar... +FILEBROWSER_APPLYPROFILE;Använd profil +FILEBROWSER_APPLYPROFILE_PARTIAL;Applicera profil (partiell) +FILEBROWSER_AUTODARKFRAME;Automatisk svartbild +FILEBROWSER_AUTOFLATFIELD;Automatisk plattfältskorrigering +FILEBROWSER_BROWSEPATHBUTTONHINT;Klicka för att komma till vald sökväg +FILEBROWSER_BROWSEPATHHINT;Skriv in en sökväg och tryck Enter (Ctrl-Enter i filhanteraren).\nCtrl-O för att komma till sökfältet.\nEnter / Ctrl-Enter för att bläddra;\nEsc för att rensa ändringar.\nShift-Esc för att ta bort fokus från sökfältet.\n\n\nPath kortkommando:\n ~ - användarens hemkatalog\n ! - användarens bildkatalog +FILEBROWSER_CACHECLEARFROMFULL;Rensa från cachen - fullständigt +FILEBROWSER_CACHECLEARFROMPARTIAL;Rensa från cachen - delvis +FILEBROWSER_CACHE;Cache +FILEBROWSER_CLEARPROFILE;Återställ profilen +FILEBROWSER_COLORLABEL_TOOLTIP;Färgetikett\n\nAnvänd menyn eller kortkommandona:\nShift-Ctrl-0 No Color\nShift-Ctrl-1 Röd\nShift-Ctrl-2 Gul\nShift-Ctrl-3 Grön\nShift-Ctrl-4 Blå\nShift-Ctrl-5 Lila +FILEBROWSER_COPYPROFILE;Kopiera profil +FILEBROWSER_CURRENT_NAME;Nuvarande namn: +FILEBROWSER_DARKFRAME;Svartbild +FILEBROWSER_DELETEDLGLABEL;Bekräftelse vid borttag +FILEBROWSER_DELETEDLGMSGINCLPROC;Är du säker på att du vill ta bort de valda filerna %1 OCH den behandlade versionen? +FILEBROWSER_DELETEDLGMSG;Är du säker på att du vill ta bort de valda %1 filerna? +FILEBROWSER_EMPTYTRASHHINT;Ta bort papperskorgens filer permanent +FILEBROWSER_EMPTYTRASH;Töm papperskorgen +FILEBROWSER_EXEC_CPB;Egen profilskapare +FILEBROWSER_EXTPROGMENU;Öppna med +FILEBROWSER_FLATFIELD;Plattfält +FILEBROWSER_MOVETODARKFDIR;Flytta till katalogen för svartbilder +FILEBROWSER_MOVETOFLATFIELDDIR;Flytta till plattfältskatalogen +FILEBROWSER_NEW_NAME;Nytt namn: +FILEBROWSER_OPENDEFAULTVIEWER;Windows standardsvisare (köbehandlas) +FILEBROWSER_PARTIALPASTEPROFILE;Klistra in partiell profil +FILEBROWSER_PASTEPROFILE;Klistra in profil +FILEBROWSER_POPUPCANCELJOB;Avbryt +FILEBROWSER_POPUPCOLORLABEL;Färgetikett +FILEBROWSER_POPUPCOPYTO;Kopiera till... +FILEBROWSER_POPUPFILEOPERATIONS;Filaktiviteter +FILEBROWSER_POPUPMOVEEND;Flytta till slutet av behandlingskön +FILEBROWSER_POPUPMOVEHEAD;Flytta till början av behandlingskön +FILEBROWSER_POPUPMOVETO;Flytta till... +FILEBROWSER_POPUPOPENINEDITOR;Öppna i Editor +FILEBROWSER_POPUPOPEN;Öppna +FILEBROWSER_POPUPPROCESSFAST;Lägg till i kön (Snabbexport) +FILEBROWSER_POPUPPROCESS;Flytta till behandlingskön +FILEBROWSER_POPUPPROFILEOPERATIONS;Profilaktiviteter +FILEBROWSER_POPUPRANK;Betyg +FILEBROWSER_POPUPREMOVEINCLPROC;Ta bort från filsystemet inkl. den behandlade +FILEBROWSER_POPUPREMOVE;Ta bort från filsystemet +FILEBROWSER_POPUPRENAME;Byt namn +FILEBROWSER_POPUPSELECTALL;Markera allt +FILEBROWSER_POPUPTRASH;Flytta till papperskorgen +FILEBROWSER_POPUPUNRANK;Ta bort betyg +FILEBROWSER_POPUPUNTRASH;Ta bort från papperskorgen +FILEBROWSER_QUERYBUTTONHINT;Rensa sökfältet +FILEBROWSER_QUERYHINT;Skriv en del av ett filnamn för att söka efter en kommaseparerad lista.\nT. ex. 1001,1004,1199\n\nCtrl-F för att komma till sökfältet.\nEnter för att starta sökningen.\nEsc för att rensa.\nShift-Esc för att ta bort fokus från sökfältet. +FILEBROWSER_QUERYLABEL; Hitta: +FILEBROWSER_RANK1_TOOLTIP;Betyg 1 *\nKortkommando: Shift-1 +FILEBROWSER_RANK2_TOOLTIP;Betyg 2 *\nKortkommando: Shift-2 +FILEBROWSER_RANK3_TOOLTIP;Betyg 3 *\nKortkommando: Shift-3 +FILEBROWSER_RANK4_TOOLTIP;Betyg 4 *\nKortkommando: Shift-4 +FILEBROWSER_RANK5_TOOLTIP;Betyg 5 *\nKortkommando: Shift-5 +FILEBROWSER_RENAMEDLGLABEL;Byt namn +FILEBROWSER_RENAMEDLGMSG;Byt namn på "%1" till: +FILEBROWSER_SELECTDARKFRAME;Välj svartbild... +FILEBROWSER_SELECTFLATFIELD;Välj plattfält... +FILEBROWSER_SHOWCOLORLABEL1HINT;Visa bilder märkta som röda.\nKortkommando: Alt-1 +FILEBROWSER_SHOWCOLORLABEL2HINT;Visa bilder märkta som gula.\nKortkommando:Alt-2 +FILEBROWSER_SHOWCOLORLABEL3HINT;Visa bilder märkta som gröna.\nKortkommando:Alt-3 +FILEBROWSER_SHOWCOLORLABEL4HINT;Visa bilder märkta som blåa.\nKortkommando:Alt-4 +FILEBROWSER_SHOWCOLORLABEL5HINT;Visa bilder märkta som lila.\nKortkommando: Alt-5 +FILEBROWSER_SHOWDIRHINT;Återställ alla sökfilter.\nKortkommando: d +FILEBROWSER_SHOWEDITEDHINT;Visa redigerade bilder.\nKortkommando: 7 +FILEBROWSER_SHOWEDITEDNOTHINT;Visa ickeredigerade bilder.\nKortkommando: 6 +FILEBROWSER_SHOWEXIFINFO;Visa EXIF-information.\nKortkommando: i\n\nKortkommando i enkelbildsläget: Alt-i +FILEBROWSER_SHOWRANK1HINT;Visa bilder med betyg 1.\nKortkommando: 1 +FILEBROWSER_SHOWRANK2HINT;Visa bilder med betyg 2.\nKortkommando: 2 +FILEBROWSER_SHOWRANK3HINT;Visa bilder med betyg 3.\nKortkommando: 3 +FILEBROWSER_SHOWRANK4HINT;Visa bilder med betyg 4.\nKortkommando: 4 +FILEBROWSER_SHOWRANK5HINT;Visa bilder med betyg 5.\nKortkommando: 5 +FILEBROWSER_SHOWRECENTLYSAVEDHINT;Visa bilder som nyligen sparats\nKortkommando: Alt-7 +FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Visa bilder som inte nyligen sparats\nKortkommando: Alt-6 +FILEBROWSER_SHOWTRASHHINT;Visa innehållet i papperskorgen +FILEBROWSER_SHOWUNCOLORHINT;Visa bilder utan färgetikett\nKortkommando: Alt-0 +FILEBROWSER_SHOWUNRANKHINT;Visa icke-betygsatta bilder +FILEBROWSER_STARTPROCESSINGHINT;Starta behandlingen och spara bilderna i behandlingskön +FILEBROWSER_STARTPROCESSING;Starta behandlingen +FILEBROWSER_STOPPROCESSINGHINT;Avbryt behandlingen av bilderna +FILEBROWSER_STOPPROCESSING;Avbryt behandlingen +FILEBROWSER_THUMBSIZE;Miniatyrbildens storlek +FILEBROWSER_TOOLTIP_STOPPROCESSING;Starta behandlingen automatiskt när en ny bild kommer in +FILEBROWSER_UNRANK_TOOLTIP;Ta bort betyg\nKortkommando: Shift-0 +FILEBROWSER_ZOOMINHINT;Förstora miniatyrbilderna.\nKortkommando: +\nKortkommado i enkelbildsläget: Alt-+ +FILEBROWSER_ZOOMOUTHINT;Förminska miniatyrbilderna.\nKortkommando: -\nKortkommado i enkelbildsläget: Alt-- +GENERAL_ABOUT;Om +GENERAL_AFTER;Efter +GENERAL_AUTO;Automatisk +GENERAL_BEFORE;Före +GENERAL_CANCEL;Avbryt +GENERAL_CLOSE;Stäng +GENERAL_DISABLED;Avaktiverad +GENERAL_DISABLE;Avaktivera +GENERAL_ENABLED;Aktiverad +GENERAL_ENABLE;Aktivera +GENERAL_FILE;Fil +GENERAL_LANDSCAPE;Landskap +GENERAL_NA;Ej tillgänglig +GENERAL_NONE;Inga +GENERAL_NO;Nej +GENERAL_OK;Ok +GENERAL_PORTRAIT;Porträtt +GENERAL_SAVE;Spara +GENERAL_UNCHANGED;(Oförändrad) +GENERAL_WARNING;Varning +HISTOGRAM_TOOLTIP_BAR;Visa/dölj RBG-indikatorer\nKlicka på höger musknapp på förhandsvisningen för att frysa +HISTOGRAM_TOOLTIP_B;Visa/dölj blått histogram +HISTOGRAM_TOOLTIP_CHRO;Visa/Dölj kromananshistogrammet +HISTOGRAM_TOOLTIP_FULL;Växla mellan fullt eller skalat histogram +HISTOGRAM_TOOLTIP_G;Visa/dölj grönt histogram +HISTOGRAM_TOOLTIP_L;Visa/dölj CIELAB histogram för luminans +HISTOGRAM_TOOLTIP_RAW;Visa/dölj råbildens histogram +HISTOGRAM_TOOLTIP_R;Visa/dölj rött histogram +HISTORY_CHANGED;Ändrad +HISTORY_CUSTOMCURVE;Egen kurva +HISTORY_DELSNAPSHOT;Ta bort +HISTORY_FROMCLIPBOARD;Från klippbordet +HISTORY_LABEL;Historia +HISTORY_MSG_1;Fotot laddades +HISTORY_MSG_2;Profil laddad +HISTORY_MSG_3;Profil ändrad +HISTORY_MSG_4;Historia-bläddrande +HISTORY_MSG_5;Ljusstyrka +HISTORY_MSG_6;Kontrast +HISTORY_MSG_7;Svärta +HISTORY_MSG_8;Exponeringskompensation +HISTORY_MSG_9;Högdageråterställning +HISTORY_MSG_10;Skuggkomprimering +HISTORY_MSG_11;Tonkurva 1 +HISTORY_MSG_12;Autonivåer +HISTORY_MSG_13;Exponeringsmarkering +HISTORY_MSG_14;Lab - Ljushet +HISTORY_MSG_15;Lab - Kontrast +HISTORY_MSG_16;Svart luminans +HISTORY_MSG_17;Luminans högdagerkompr. +HISTORY_MSG_18;Luminans skuggkompr. +HISTORY_MSG_19;'L'-kurva +HISTORY_MSG_20;Skärpning +HISTORY_MSG_21;USM - Radie +HISTORY_MSG_22;USM - Mängd +HISTORY_MSG_23;USM - Tröskelvärde +HISTORY_MSG_24;USM - Skärp bara kanter +HISTORY_MSG_25;USM - Radie för kantdetektering +HISTORY_MSG_26;USM - Kanttolerans +HISTORY_MSG_27;USM - Halokontroll +HISTORY_MSG_28;USM - Mängd för halokontroll +HISTORY_MSG_29;Metod för skärpning +HISTORY_MSG_30;RLD - Radie +HISTORY_MSG_31;RLD - Mängd +HISTORY_MSG_32;RLD - Dämpning +HISTORY_MSG_33;RLD - Upprepningar +HISTORY_MSG_34;LCP distorsionskorrigering +HISTORY_MSG_35;LCP vinjetteringskorrigering +HISTORY_MSG_36;LCP Kromatiska aberattioner +HISTORY_MSG_37;Autonivåer +HISTORY_MSG_38;Vitbalansmetod +HISTORY_MSG_39;VB - Färgtemperatur +HISTORY_MSG_40;VB - Färgton +HISTORY_MSG_41;Tonkurva läge 1 +HISTORY_MSG_42;Tonkurva 2 +HISTORY_MSG_43;Tonkurva läge 2 +HISTORY_MSG_44;Brusreduceringsradie +HISTORY_MSG_45;Kanttolerans för lum.brusreducering +HISTORY_MSG_46;Färgbrusreducering +HISTORY_MSG_47;Mixa högdagrar med matris +HISTORY_MSG_48;Använd tonkurvan i DCP +HISTORY_MSG_49;DCP ljuskälla +HISTORY_MSG_50;Skuggor/Högdagrar +HISTORY_MSG_51;S/H - Högdagrar +HISTORY_MSG_52;S/H - Skuggor +HISTORY_MSG_53;S/H - Högdagertonvidd +HISTORY_MSG_54;S/H - Skuggtonvidd +HISTORY_MSG_55;S/H - Lokal kontrast +HISTORY_MSG_56;S/H - Radie +HISTORY_MSG_57;Enkel rotering +HISTORY_MSG_58;Vänd horisontellt +HISTORY_MSG_59;Vänd vertikalt +HISTORY_MSG_60;Rotering +HISTORY_MSG_61;Fyll automatiskt +HISTORY_MSG_62;Korrigering av objektivdistorsion +HISTORY_MSG_63;Bokmärke valt +HISTORY_MSG_64;Beskär +HISTORY_MSG_65;Korrigera kromatiska abberationer +HISTORY_MSG_66;Högdageråterställning +HISTORY_MSG_67;Mängd på högdageråterställning +HISTORY_MSG_68;Metod för högdageråterställning +HISTORY_MSG_69;Färgrymd +HISTORY_MSG_70;Utmatningsfärgrymd +HISTORY_MSG_71;Inmatningsfärgrymd +HISTORY_MSG_72;VK - Mängd +HISTORY_MSG_73;Kanalmixer +HISTORY_MSG_74;Ändra storleksskala +HISTORY_MSG_75;Metod för ändring av storlek +HISTORY_MSG_76;Exif Metadata +HISTORY_MSG_77;IPTC Metadata +HISTORY_MSG_78;Data som ska ändra storlek +HISTORY_MSG_79;Storleksändring, bredd +HISTORY_MSG_80;Storleksändring, höjd +HISTORY_MSG_81;Storleksändring +HISTORY_MSG_82;Profilen ändrades +HISTORY_MSG_83;S/H - Skarp mask +HISTORY_MSG_84;Korrigering av perspektiv +HISTORY_MSG_85;LCP +HISTORY_MSG_86;RGB-kurvor - Luminansläge +HISTORY_MSG_87;Brusreducering med stegsvar +HISTORY_MSG_88;Tröskelvärde för brusreducering med stegsvar +HISTORY_MSG_89;Brusreducering +HISTORY_MSG_90;Brusreducering - Luminans +HISTORY_MSG_91;Brusreducering - Kroma +HISTORY_MSG_92;Brusreducering - Gamma +HISTORY_MSG_93;Kontrast genom detaljnivåvärden +HISTORY_MSG_94;Kontrast genom detaljnivåer +HISTORY_MSG_95;Lab - kroma +HISTORY_MSG_96;'a'-kurvan +HISTORY_MSG_97;'b'-kurvan +HISTORY_MSG_98;Metod för demozaicing +HISTORY_MSG_99;Het/dödpixelfilter +HISTORY_MSG_100;Mättnad +HISTORY_MSG_101;HSV - Nyans +HISTORY_MSG_102;HSV - Mättnad +HISTORY_MSG_103;HSV - Värde +HISTORY_MSG_104;HSV Equalizer +HISTORY_MSG_105;Överstrålningsreduktion +HISTORY_MSG_106;Radie, överstrålningsreduktion +HISTORY_MSG_107;Tröskelvärde för överstrålningsreduktion +HISTORY_MSG_108;Högdagerkompr., tröskelvärde +HISTORY_MSG_109;Gränsområde, storleksändring +HISTORY_MSG_110;Storleksändring tillämpas på +HISTORY_MSG_111;Lab - Undvik färgklipp +HISTORY_MSG_112;--oanvänd-- +HISTORY_MSG_113;Lab - Skydd +HISTORY_MSG_114;DCB-iterationer +HISTORY_MSG_115;Undertryck falska färger +HISTORY_MSG_116;Förbättrad DCB +HISTORY_MSG_117;Röd CA korrigering +HISTORY_MSG_118;Blå CA korrigering +HISTORY_MSG_119;Linjärt brusfilter +HISTORY_MSG_120;Grönbalansering +HISTORY_MSG_121;Automat. CA-reducering +HISTORY_MSG_122;Automat. svartbildsval +HISTORY_MSG_123;Svartbildsfil +HISTORY_MSG_124;Vitpunktskorrigering +HISTORY_MSG_125;Högdagerbevarande +HISTORY_MSG_126;Plattfältsfil +HISTORY_MSG_127;Automatiskt val av plattfält +HISTORY_MSG_128;Oskärperadie för plattfält +HISTORY_MSG_129;Oskärpetyp hos plattfältet +HISTORY_MSG_130;Autodistorion +HISTORY_MSG_131;Brusreducering, luminans +HISTORY_MSG_132;Brusreducering, kroma +HISTORY_MSG_133;Utmatningsgamma +HISTORY_MSG_134;Obunden gamma +HISTORY_MSG_135;Obunden gamma +HISTORY_MSG_136;Gammalutning +HISTORY_MSG_137;Svartpunktsnivå grön 1 +HISTORY_MSG_138;Svartpunktsnivå röd +HISTORY_MSG_139;Svartpunktsnivå blå +HISTORY_MSG_140;Svartpunktsnivå grön 2 +HISTORY_MSG_141;Svartpunktsnivå kopplade gröna +HISTORY_MSG_142;Kantskärpning - Iterationer +HISTORY_MSG_143;Kantskärpning - Mängd +HISTORY_MSG_144;Mikrokontrast - Mängd +HISTORY_MSG_145;Mikrokontrast - Enhetlighet +HISTORY_MSG_146;Kantskärpning +HISTORY_MSG_147;Kantskärpning - Endast luminans +HISTORY_MSG_148;Mikrokontrast +HISTORY_MSG_149;Mikrokontrast - 3x3-matris +HISTORY_MSG_150;Reducering av artefakter och brus e. demosaicing +HISTORY_MSG_151;Lyster +HISTORY_MSG_152;Lyster - Pastelltoner +HISTORY_MSG_153;Lyster - Mättade toner +HISTORY_MSG_154;Lyster - Skydda hudtoner +HISTORY_MSG_155;Lyster - Undvik färgskiftningar +HISTORY_MSG_156;Lyster - Koppla pastell- och mättade färger +HISTORY_MSG_157;Lyster - Tröskelvärde för pastell- och mättade färger +HISTORY_MSG_158;Tonmappning - Styrka +HISTORY_MSG_159;Tonmappning - Stoppa vid kanter. +HISTORY_MSG_160;Tonmappning - Skala +HISTORY_MSG_161;Tonmappning - Återviktade iterationer +HISTORY_MSG_162;Tonmappning +HISTORY_MSG_163;RGB-kurvor - Röd +HISTORY_MSG_164;RGB-kurvor - Grön +HISTORY_MSG_165;RGB-kurvor - Blå +HISTORY_MSG_166;Neutrala nivåer +HISTORY_MSG_167;--oanvänd-- +HISTORY_MSG_168;'CC'-kurvan +HISTORY_MSG_169;'CH'-kurvan +HISTORY_MSG_170;Lyster-kurvan +HISTORY_MSG_171;'LC'-kurvan +HISTORY_MSG_172;Begränsa LC till röda färger och hudtoner +HISTORY_MSG_173;Brusreducering - Luminansdetalj +HISTORY_MSG_174;CIECAM02 +HISTORY_MSG_175;CAM02 - Cat02-anpassning +HISTORY_MSG_176;CAM02 - Vyns mörka omgivning +HISTORY_MSG_177;CAM02 - Bildens anpassning av luminans +HISTORY_MSG_178;CAM02 - Vyns anpassning av luminans +HISTORY_MSG_179;CAM02 - Vitpunktsmodell +HISTORY_MSG_180;CAM02 - Ljushet (J) +HISTORY_MSG_181;CAM02 - Kroma (C) +HISTORY_MSG_182;CAM02 - Automatisk CAT02 +HISTORY_MSG_183;CAM02 - Kontrast (J) +HISTORY_MSG_184;CAM02 - Bild med mörk omgivning +HISTORY_MSG_185;CAM02 - Kontroll av gamut +HISTORY_MSG_186;CAM02 - Algoritm +HISTORY_MSG_187;CAM02 - Bevarande av röda färger och hudtoner +HISTORY_MSG_188;CAM02 - Intensitet (Q) +HISTORY_MSG_189;CAM02 - Kontrast (Q) +HISTORY_MSG_190;CAM02 - Mättnad (S) +HISTORY_MSG_191;CAM02 - Färgmättnad (M) +HISTORY_MSG_192;CAM02 - Nyans (h) +HISTORY_MSG_193;CAM02 - Tonkurva 1 +HISTORY_MSG_194;CAM02 - Tonkurva 2 +HISTORY_MSG_195;CAM02 - Tonkurva 1 +HISTORY_MSG_196;CAM02 - Tonkurva 2 +HISTORY_MSG_197;CAM02 - Färgkurva +HISTORY_MSG_198;CAM02 - Färgkurva +HISTORY_MSG_199;CAM02 - Utmatningshistogram +HISTORY_MSG_200;CAM02 - Tonmappning +HISTORY_MSG_201;NR - Krominans röd-grön +HISTORY_MSG_202;NR - Krominans blå-gul +HISTORY_MSG_203;Brusreducering - metod +HISTORY_MSG_204;LMMSE förbättringssteg +HISTORY_MSG_205;CAM02 - Heta/dåliga pixlar +HISTORY_MSG_206;CAT02 - Anpassa automatiskt till bilden +HISTORY_MSG_207;Överstrålning - Nyanskurva +HISTORY_MSG_208;Vitbalans - Blå/Röd equalizer +HISTORY_MSG_210;Graderat filter - Vinkel +HISTORY_MSG_211;Graderat filter +HISTORY_MSG_212;Vinjetteringsfilter - Styrka +HISTORY_MSG_213;Vinjetteringsfilter +HISTORY_MSG_214;Svartvitt +HISTORY_MSG_215;S/V kanalmixer Röd +HISTORY_MSG_216;S/V kanalmixer Grön +HISTORY_MSG_217;S/V kanalmixer Blå +HISTORY_MSG_218;S/V Röd gamma +HISTORY_MSG_219;S/V Grön gamma +HISTORY_MSG_220;S/V Blå gamma +HISTORY_MSG_221;S/V Färgfilter +HISTORY_MSG_222;S/V Förinställningar +HISTORY_MSG_223;S/V Kanalmixer Orange +HISTORY_MSG_224;S/V Kanalmixer Gul +HISTORY_MSG_225;S/V Kanalmixer Cyan +HISTORY_MSG_226;S/V Kanalmixer Magenta +HISTORY_MSG_227;S/V Kanalmixer Lila +HISTORY_MSG_228;S/V Luminansequalizer +HISTORY_MSG_229;S/V Luminansequalizer +HISTORY_MSG_230;S/V Svartvittläge +HISTORY_MSG_231;S/V 'Före'-kurva +HISTORY_MSG_232;S/V 'Före'-kurvtyp +HISTORY_MSG_233;S/V 'Efter'-kurva +HISTORY_MSG_234;S/V 'Efter'-kurvtyp +HISTORY_MSG_235;S/V Automatisk kanalmixer +HISTORY_MSG_236;--oanvänd-- +HISTORY_MSG_237;S/V Mixer +HISTORY_MSG_238;Graderat filter - Fjäder +HISTORY_MSG_239;Graderat filter - Styrka +HISTORY_MSG_240;Graderat filter - Centrum +HISTORY_MSG_241;Vinjetteringsfilter - Fjäder +HISTORY_MSG_242;Vinjetteringsfilter - Rundhet +HISTORY_MSG_243;Vinjettering - Radie +HISTORY_MSG_244;Vinjettering - Styrka +HISTORY_MSG_245;Vinjettering - Centrum +HISTORY_MSG_246;'CL'-kurva +HISTORY_MSG_247;'LH'-kurva +HISTORY_MSG_248;'HH'-kurva +HISTORY_MSG_249;Kontrast genom detaljnivåer +HISTORY_MSG_250;Brusreduceringsförbättring +HISTORY_MSG_251;B&W - Algoritm +HISTORY_MSG_252;CbDL Hudtoner +HISTORY_MSG_253;CbDL Reducera artefakter +HISTORY_MSG_254;CbDL - Nyans på hudtoner +HISTORY_MSG_255;CbDL - Algoritm +HISTORY_NEWSNAPSHOT;Nytt +HISTORY_NEWSNAPSHOT_TOOLTIP;Kortkommando: Alt-s +HISTORY_SNAPSHOTS;Bokmärken +HISTORY_SNAPSHOT;Bokmärke +IPTCPANEL_AUTHORSPOSITIONHINT;Titeln på upphovsmannen/männen (byline) +IPTCPANEL_AUTHORSPOSITION;Upphovmannens position +IPTCPANEL_AUTHOR;Upphovsman +IPTCPANEL_CAPTIONHINT;En beskrivning av informationen +IPTCPANEL_CAPTIONWRITERHINT;Namnet på den person som är involverad i att skapa, redigera eller korrigera bilden +IPTCPANEL_CAPTIONWRITER;Upphovsman +IPTCPANEL_CAPTION;Rubrik +IPTCPANEL_CATEGORYHINT;Identifierar bildens titel enligt tillhandahållaren. +IPTCPANEL_CATEGORY;Kategori +IPTCPANEL_CITYHINT;Staden där bilden togs +IPTCPANEL_CITY;Stad +IPTCPANEL_COPYHINT;Kopiera IPTC-inställningarna till klippbordet +IPTCPANEL_COPYRIGHTHINT;Nödvändig upphovsrättslig information +IPTCPANEL_COPYRIGHT;Upphovsrätt +IPTCPANEL_COUNTRYHINT;Namnet på landet/platsen där bilden togs +IPTCPANEL_COUNTRY;Land +IPTCPANEL_CREDITHINT;Identifierar tillhandahållaren av bilden, ej nödvändigtvis upphovsmannen +IPTCPANEL_CREDIT;Erkännande +IPTCPANEL_DATECREATEDHINT;Datumet då innehållet av bilden skapades. Format: ÅÅÅÅMMDD. +IPTCPANEL_DATECREATED;Skapad datum +IPTCPANEL_EMBEDDEDHINT;Återställ IPTC-informationen till innehållet i bildfilen. +IPTCPANEL_EMBEDDED;Inbäddad +IPTCPANEL_HEADLINEHINT;En sammanfattning av vad bilden innehåller. +IPTCPANEL_HEADLINE;Rubrik +IPTCPANEL_INSTRUCTIONSHINT;Andra instruktioner som rör användandet av bilden. +IPTCPANEL_INSTRUCTIONS;Instruktioner +IPTCPANEL_KEYWORDSHINT;Indikerar nyckelord +IPTCPANEL_KEYWORDS;Nyckelord +IPTCPANEL_PASTEHINT;Klistra in IPTC-inställningar från klippbordet +IPTCPANEL_PROVINCEHINT;Den provins eller stat från vilken bilden härrör. +IPTCPANEL_PROVINCE;Provins +IPTCPANEL_RESETHINT;Återställ till standardprofilen +IPTCPANEL_RESET;Återställ +IPTCPANEL_SOURCEHINT;Den ursprungliga ägaren av innehållet. +IPTCPANEL_SOURCE;Källa +IPTCPANEL_SUPPCATEGORIESHINT;Ytterligare beskrivning av bilden +IPTCPANEL_SUPPCATEGORIES;Övriga kategorier +IPTCPANEL_TITLEHINT;En kortfattad bildreferens +IPTCPANEL_TITLE;Titel +IPTCPANEL_TRANSREFERENCEHINT;En kod som representerar platsen för överföring +IPTCPANEL_TRANSREFERENCE;Överföringsreferens +MAIN_BUTTON_FULLSCREEN;Helskärm +MAIN_BUTTON_NAVNEXT_TOOLTIP;Flytta till nästa bild relativt den bild som är öppen i redigeringsvyn\nKortkommando: Shift-F4\n\nFlytta till nästa bild relativt den valda miniatyrbilden i filvyn\nKortkommando: F4 +MAIN_BUTTON_NAVPREV_TOOLTIP;Flytta till föregående bild relativt den bild som är öppen i redigeringsvyn\nKortkommando: Shift-F3\n\nFlytta till föregående bild relativt den valda miniatyrbilden i filvyn\nKortkommando: F3 +MAIN_BUTTON_NAVSYNC_TOOLTIP;Synkronisera filvyn med redigeringsvyn för att uppdatera förhandsgranskningen av den nu öppna bilden, och för att nollställa filtren i filvyn.\nKortkommando: x\n\nSom ovan, men utan att nollställa filtren i filvyn\nKortkommando: y\n(Notera att förhandsgranskningen av den öppna bildens miniatyrbilder ej visas om den är filtrerad.). +MAIN_BUTTON_PREFERENCES;Inställningar +MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Lägg till nuvarande bild i behandlingskön.\nKortkommando: Ctrl+b +MAIN_BUTTON_SAVE;Spara +MAIN_BUTTON_SAVE_TOOLTIP;Spara nuvarande bild.\nKortkommando: Ctrl+s +MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Redigera nuvarande bild i externt bildredigeringsprogram.\nKortkommando: Ctrl+e +MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Visa/dölj alla sidopaneler.\nKortkommando: m +MAIN_BUTTON_UNFULLSCREEN;Avsluta helskärmsläget +MAIN_FRAME_BATCHQUEUE;Batchkö +MAIN_FRAME_BATCHQUEUE_TOOLTIP; Batchkö\nKortkommando: Ctrl-F3 +MAIN_FRAME_EDITOR;Redigeringsvy +MAIN_FRAME_EDITOR_TOOLTIP;Redigeringsvy\nKortkommando: Ctrl-F4 +MAIN_FRAME_FILEBROWSER;Filvy +MAIN_FRAME_FILEBROWSER_TOOLTIP; Filvy\nKortkommandoCtrl-F2 +MAIN_FRAME_PLACES;Platser +MAIN_FRAME_PLACES_ADD;Lägg till +MAIN_FRAME_PLACES_DEL;Ta bort +MAIN_FRAME_RECENT;Nyligen använda kataloger +MAIN_MSG_ALREADYEXISTS;Filen existerar redan. +MAIN_MSG_CANNOTLOAD;Kan inte ladda bilden +MAIN_MSG_CANNOTSAVE;Fel uppstod när bilden sparades +MAIN_MSG_CANNOTSTARTEDITOR;Kan ej starta externt redigeringsprogram +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Var vänlig och ange rätt sökväg i inställningarna +MAIN_MSG_EMPTYFILENAME;Ospecificerat filnamn! +MAIN_MSG_IMAGEUNPROCESSED;Det här kommandot kräver att alla valda bilder behandlas i kön först. +MAIN_MSG_NAVIGATOR;Översiktsvy +MAIN_MSG_OPERATIONCANCELLED;Åtgärden avbröts +MAIN_MSG_PATHDOESNTEXIST;Sökvägen\n\n%1\n\nfinns ej. Var vänlig och ange en korrekt sökväg i inställningarna. +MAIN_MSG_QOVERWRITE;Vill du skriva över den? +MAIN_MSG_SETPATHFIRST;Du måste först ange en sökväg i\ninställningarna för att använda denna funktion! +MAIN_MSG_WRITEFAILED;Misslyckades att skriva\n\n"%1"\n\nFörsäkra dig om att katalogen existerar och att du har rättighet att skriva där. +MAIN_TAB_COLOR;Färger +MAIN_TAB_COLOR_TOOLTIP;Kortkommando: Alt-c +MAIN_TAB_DETAIL;Detaljer +MAIN_TAB_DETAIL_TOOLTIP;Kortkommando: Alt-d +MAIN_TAB_DEVELOP;Framkalla +MAIN_TAB_EXIF;EXIF +MAIN_TAB_EXPORT; Snabbexport +MAIN_TAB_EXPOSURE;Exponering +MAIN_TAB_EXPOSURE_TOOLTIP;Kortkommando: Alt-e +MAIN_TAB_FILTER;Filter +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadata +MAIN_TAB_METADATA_TOOLTIP;Kortkommando: Alt-m +MAIN_TAB_RAW;Råbild +MAIN_TAB_RAW_TOOLTIP;Kortkommando: Alt-r +MAIN_TAB_TRANSFORM;Omvandla +MAIN_TAB_TRANSFORM_TOOLTIP;Kortkommando: Alt-t +MAIN_TOOLTIP_BACKCOLOR0;Bakgrundsfärg: Temabaserad\nKortkommando: 9 +MAIN_TOOLTIP_BACKCOLOR1;Bakgrundsfärg: Svart\nKortkommando: 9 +MAIN_TOOLTIP_BACKCOLOR2;Bakgrundsfärg: Vit\nKortkommando: 9 +MAIN_TOOLTIP_BEFOREAFTERLOCK;Lås / Lås upp före-vyn\n\nLås: behåll före-vyn oförändrad.\nAnvändbart för att utvärdera den sammanlagda effekten av flera stegs redigering. Dessutom kan jämförelser göras gentemot varje annat steg i historiken.\n\nLås upp: Före-vyn kommer hela tiden visa ett tidigare steg jämfört med efter-vyn, och visar därmed effekten av det verktyg som användes senast. +MAIN_TOOLTIP_HIDEHP;Visa/göm den vänstra panelen. Kortkommando: l +MAIN_TOOLTIP_INDCLIPPEDH;Markera högdagerindikation.\nKortkommando: < +MAIN_TOOLTIP_INDCLIPPEDS;Markera skuggindikation.\nKortkommando: > +MAIN_TOOLTIP_PREVIEWB;Förhandsgranska den blå kanalen.\nGenväg: b +MAIN_TOOLTIP_PREVIEWFOCUSMASK;Förhandsgranska fokusmasken.\nKortkommando: Shift-f\n\nNoggrannare på bilder med kort skärpedjup, lågt brus och där en hög zoom-grad är vald.\n\nFör att förbättra detekteringen för brusiga bilder, utvärdera vid en zoom-grad om 10-30%\n\nFörhandsvisningen görs långsammare med fokusmasken påslagen. +MAIN_TOOLTIP_PREVIEWG;Förhandsgranska den gröna kanalen.\nGenväg: g +MAIN_TOOLTIP_PREVIEWL;Förhandsgranska ljusstyrkan.\nShortcut: v\n\n0.299*R + 0.587*G + 0.114*B +MAIN_TOOLTIP_PREVIEWR;Förhandsgranska den röda kanalen.\nGenväg: r +MAIN_TOOLTIP_QINFO;Visa kortfattad information om bilden\nKortkommando: i +MAIN_TOOLTIP_SHOWHIDELP1;Visa/dölj vänstra panelen l +MAIN_TOOLTIP_SHOWHIDERP1;Visa/dölj den högra panelen Alt-l +MAIN_TOOLTIP_SHOWHIDETP1;Visa/dölj den översta panelen Shift-L +MAIN_TOOLTIP_THRESHOLD;Tröskelvärde +MAIN_TOOLTIP_TOGGLE;Växla före/efter vy.\nKortkommando: Shift-b +NAVIGATOR_XY_FULL;Bredd = %1, Höjd = %2 +NAVIGATOR_XY_NA;x = -, y = - +OPTIONS_DEFIMG_MISSING;Standardprofilen för icke-råbilder kunde inte hittas eller är inte angiven.\n\nVar vänlig kontrollera din profilmapp: den kanske ej finns eller är skadad.\n\nInterna värden kommer att användas som standard. +OPTIONS_DEFRAW_MISSING;Standardprofilen för råbilder kunde inte hittas eller är den ej angiven.\n\nVar vänlig kontrollera din profilmapp: kanske finns den ej eller är filen skadad.\n\nInterna värden kommer att användas som standard. +PARTIALPASTE_BASICGROUP;Grundläggande inställningar +PARTIALPASTE_CACORRECTION;Reducera kromatiska abberationer +PARTIALPASTE_CHANNELMIXERBW;Svartvitt +PARTIALPASTE_CHANNELMIXER;Kanalmixer +PARTIALPASTE_COARSETRANS;Rotering 90-grader +PARTIALPASTE_COLORAPP;CIE Color Appearance Model 2002 +PARTIALPASTE_COLORGROUP;Färgrelaterade inställningar +PARTIALPASTE_COMMONTRANSFORMPARAMS;Autofyll +PARTIALPASTE_COMPOSITIONGROUP;Komponeringsinställningar +PARTIALPASTE_CROP;Beskär +PARTIALPASTE_DARKFRAMEAUTOSELECT;Automatiskt val av svartbild +PARTIALPASTE_DARKFRAMEFILE;Svartbildsfil +PARTIALPASTE_DEFRINGE;Fyll ut överstrålning +PARTIALPASTE_DETAILGROUP;Detaljinställningar +PARTIALPASTE_DIALOGLABEL;Partiell inklistring av profiler +PARTIALPASTE_DIRPYRDENOISE;Brusreducering +PARTIALPASTE_DIRPYREQUALIZER;Kontrast genom detaljnivåer +PARTIALPASTE_DISTORTION;Distortionskorrigering +PARTIALPASTE_EPD;Tonmappning +PARTIALPASTE_EVERYTHING;Allt +PARTIALPASTE_EXIFCHANGES;Förändringar i Exif-informationen +PARTIALPASTE_EXPOSURE;Exponering +PARTIALPASTE_FLATFIELDAUTOSELECT;Välj plattfält automatiskt +PARTIALPASTE_FLATFIELDBLURRADIUS;Oskärperadie för plattfält +PARTIALPASTE_FLATFIELDBLURTYPE;Oskärpetyp hos plattfältet +PARTIALPASTE_FLATFIELDFILE;Plattfältsfil +PARTIALPASTE_GRADIENT;Graderat filter +PARTIALPASTE_HSVEQUALIZER;HSV-equalizer +PARTIALPASTE_ICMGAMMA;Utmatningsgamma +PARTIALPASTE_ICMSETTINGS;Färghanteringsinställningar +PARTIALPASTE_IMPULSEDENOISE;Brusreducering mha stegsvar +PARTIALPASTE_IPTCINFO;IPTC-info +PARTIALPASTE_LABCURVE;Labjusteringar +PARTIALPASTE_LENSGROUP;Objektivrelaterade inställningar +PARTIALPASTE_LENSPROFILE;Objektivkorrigeringsprofil +PARTIALPASTE_METAGROUP;Metadata +PARTIALPASTE_PCVIGNETTE;Vinjetteringsfilter +PARTIALPASTE_PERSPECTIVE;Perspektiv +PARTIALPASTE_PREPROCESS_GREENEQUIL;Grönbalansering +PARTIALPASTE_PREPROCESS_LINEDENOISE;Linjärt brusfilter +PARTIALPASTE_RAWCACORR_AUTO;Reducera kromatiska abberationer automatiskt +PARTIALPASTE_RAWCACORR_CABLUE;Blå +PARTIALPASTE_RAWCACORR_CARED;Röd +PARTIALPASTE_RAWEXPOS_BLACK;Svärta +PARTIALPASTE_RAWEXPOS_LINEAR;Vitpunktskorrigering +PARTIALPASTE_RAWEXPOS_PRESER;Korrigering av högdagrar +PARTIALPASTE_RAWGROUP;Råbildsinställningar +PARTIALPASTE_RAW_DCBENHANCE;DCB-förbättringssteg +PARTIALPASTE_RAW_DCBITERATIONS;Antal DCB-iterationer +PARTIALPASTE_RAW_DMETHOD;Metod för demosaicing +PARTIALPASTE_RAW_FALSECOLOR;Falskt färgbortträngningssteg +PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE förbättringssteg +PARTIALPASTE_RESIZE;Ändra storlek +PARTIALPASTE_RGBCURVES;RGB-kurvor +PARTIALPASTE_ROTATION;Rotering +PARTIALPASTE_SHADOWSHIGHLIGHTS;Skugg- och högdageråterställning +PARTIALPASTE_SHARPENEDGE;Kanter +PARTIALPASTE_SHARPENING;Skärpa (Oskarp mask/RL) +PARTIALPASTE_SHARPENMICRO;Mikrokontrast +PARTIALPASTE_VIBRANCE;Lyster +PARTIALPASTE_VIGNETTING;Reducera vinjettering +PARTIALPASTE_WHITEBALANCE;Vitbalans +PREFERENCES_ADD;Lägg till +PREFERENCES_APPLNEXTSTARTUP;Kräver omstart av RawTherapee +PREFERENCES_AUTOMONPROFILE;Använd operativsystemets skärmfärgprofil +PREFERENCES_BATCH_PROCESSING;Batchbehandling +PREFERENCES_BEHADDALLHINT;Sätt alla parametrar till Lägg till-läge.\nFörändringar i parametrar batch-verktyget kommer att vara skillnader gentemot de lagrade värdena. +PREFERENCES_BEHADDALL;Sätt allt till 'Lägg till' +PREFERENCES_BEHAVIOR;Uppträdande +PREFERENCES_BEHSETALLHINT;Sätt alla parametrar till Ange-läge.\nFörändringar i parametrar i batch-verktyget kommer att vara absoluta och de faktiska värdena kommer att visas. +PREFERENCES_BEHSETALL;Sätt allt till 'Ange' +PREFERENCES_BLACKBODY;Glödlampa +PREFERENCES_CACHECLEARALL;Återställ alla +PREFERENCES_CACHECLEARPROFILES;Återställ profiler +PREFERENCES_CACHECLEARTHUMBS;Ta bort cachade miniatyrbilder +PREFERENCES_CACHEMAXENTRIES;Maximalt antal cachefiler +PREFERENCES_CACHEOPTS;Cacheinställningar +PREFERENCES_CACHETHUMBHEIGHT;Maximal höjd på miniatyrbilderna +PREFERENCES_CIEART;CIECAM02-optimering +PREFERENCES_CIEART_LABEL;Använd flyttalsprecision istället för dubbel +PREFERENCES_CIEART_TOOLTIP;Om aktiverat, så kommer alla CIECAM02-beräkningar att utföras med enkel precision i flyttalsformatet istället för med dubbel precision. Detta ger en liten sänkning av beräkningstiden, till ett pris av en försumbar kvalitetsförsämring. +PREFERENCES_CLIPPINGIND;Klippindikering +PREFERENCES_CMETRICINTENT;Kolorimetrisk återgivning +PREFERENCES_CUSTPROFBUILDHINT;Exekverbar (eller skript) fil som anropas när en ny initial profil skall genereras för en bild.\nMottar kommandoradparametrar för att tillåta generering av en regelbaserad .pp3-fil:n[Sökväg Råbild/JPG] [Sökväg till standardprofil] [bländartal] [exponering i sek] [brännvidd i mm] [ISO] [Objektiv] [Kamera] +PREFERENCES_CUSTPROFBUILDKEYFORMAT;Format för nycklar +PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME;Namn +PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;TagID +PREFERENCES_CUSTPROFBUILDPATH;Exekverbar sökväg +PREFERENCES_CUSTPROFBUILD;Custom Processing Profile Builder +PREFERENCES_CUTOVERLAYBRUSH;Bakgrundsfärg vid beskärning +PREFERENCES_D50;5000K +PREFERENCES_D55;5500K +PREFERENCES_D60;6000K +PREFERENCES_D65;6500K +PREFERENCES_DARKFRAMEFOUND;Hittade +PREFERENCES_DARKFRAMESHOTS;bilder +PREFERENCES_DARKFRAMETEMPLATES;mallar +PREFERENCES_DARKFRAME;Svartbild +PREFERENCES_DATEFORMATHINT;Du kan använda följande format:\n%y: år\n%m: månad\n%d: dag\n\nTill exempel är det svenska datumformatet:\n%y-%m-%d +PREFERENCES_DATEFORMAT;Datumformat +PREFERENCES_DEFAULTLANG;Förvalt språk +PREFERENCES_DEFAULTTHEME;Förvalt tema +PREFERENCES_DIRDARKFRAMES;Katalog för svartbilder +PREFERENCES_DIRHOME;Hemkatalog +PREFERENCES_DIRLAST;Senaste besökta katalog +PREFERENCES_DIROTHER;Annan +PREFERENCES_DIRSELECTDLG;Välj bildkatalog vid uppstart... +PREFERENCES_DIRSOFTWARE;Installationskatalog +PREFERENCES_EDITORCMDLINE;Annan kommandorad +PREFERENCES_EDITORLAYOUT;Layout för redigeringsvyn +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_FLATFIELDFOUND;Hittade +PREFERENCES_FLATFIELDSDIR;Plattfältskatalog +PREFERENCES_FLATFIELDSHOTS;bilder +PREFERENCES_FLATFIELDTEMPLATES;mallar +PREFERENCES_FLATFIELD;Plattfält +PREFERENCES_FLUOF2;Lysrör F2 +PREFERENCES_FLUOF7;Lysrör F7 +PREFERENCES_FLUOF11;Lysrör F11 +PREFERENCES_FORIMAGE;För bildfiler +PREFERENCES_FORRAW;För råbilder +PREFERENCES_GIMPPATH;Installationskatalog för GIMP +PREFERENCES_GREY05;Yb=05 CIE L#30 +PREFERENCES_GREY10;Yb=10 CIE L#40 +PREFERENCES_GREY15;Yb=15 CIE L#45 +PREFERENCES_GREY18;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_HISTOGRAMPOSITIONLEFT;Histogrammet till vänster +PREFERENCES_HLTHRESHOLD;Tröskelvärde för högdagrar +PREFERENCES_ICCDIR;Katalog för färgprofiler +PREFERENCES_IMPROCPARAMS;Standardprofiler +PREFERENCES_INTENT_ABSOLUTE;Totalkolorimetrisk +PREFERENCES_INTENT_PERCEPTUAL;Upplevd +PREFERENCES_INTENT_RELATIVE;Relativ kolorimetrisk +PREFERENCES_INTENT_SATURATION;Mättnad +PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Visa intern råbild om oredigerad +PREFERENCES_LANGAUTODETECT;Använd operativsystemets språkinställning +PREFERENCES_MENUGROUPEXTPROGS;Visa "Öppna med" +PREFERENCES_MENUGROUPFILEOPERATIONS;Visa "Filaktiviteter" +PREFERENCES_MENUGROUPLABEL;Visa "Etikett" +PREFERENCES_MENUGROUPPROFILEOPERATIONS;Visa "Profilaktiviteter" +PREFERENCES_MENUGROUPRANK;Visa "Betygsättning" +PREFERENCES_MENUOPTIONS;Menyval för högerklick +PREFERENCES_METADATA;Metadata +PREFERENCES_MONITORICC;Skärmprofil +PREFERENCES_MULTITABDUALMON;Visa bild på andra skärmen, om möjligt, i flerfliksläge +PREFERENCES_MULTITAB;Öppna bilderna i olika flikar +PREFERENCES_OUTDIRFOLDERHINT;Spara de behandlade bilderna i den valda katalogen +PREFERENCES_OUTDIRFOLDER;Spara till katalog +PREFERENCES_OUTDIRTEMPLATEHINT;Du kan använda följande format:\n%f, %d1, %d2, %p1, %p2\n\nDe här format hänvisar till katalogerna och underkatalogerna till råbildens sökväg.\n\nTill exempel, om /home/tom/bilder/2010-09-02/dsc0012.nefhar öppnats, betyder formatsträngen följande:\n%f=dsc0012\n%d1=2010-09-02\n%d2=bilder\n%p1=/home/tom/bilder/2010-09-02,\n%p2=/home/tom/bilder\n%p3=/home/tom\n\nOm du vill spara den behandlade filen där originalet finns, skriver du:\n%p1/%f\n\nOm du vill spara den behandlade filen i en katalog som heter "Konverterade filer", belägen i originalets katalog, skriver du:\n%p1/Konverterade filer/%f\n\nOm du vill spara den behandlade filen i en katalog "/home/tom/Konverterade filer" där du behåller samma underkatalog med datum, skriver du:\n%p2/Konverterade filer/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Använd förinställning +PREFERENCES_OUTDIR;Utmatningskatalog +PREFERENCES_OVERLAY_FILENAMES;Visa filnamn över miniatyrbilder +PREFERENCES_OVERWRITEOUTPUTFILE;Skriv över existerande utfiler +PREFERENCES_PANFACTORLABEL;Faktor +PREFERENCES_PARSEDEXTADDHINT;Skriv in en filändelse och tryck på den här knappen för att lägga till den i listan +PREFERENCES_PARSEDEXTADD;Lägg till filtyp +PREFERENCES_PARSEDEXTDELHINT;Ta bort de markerade filändelserna från listan +PREFERENCES_PARSEDEXT;Behandlade filtyper +PREFERENCES_PROFILEHANDLING;Hantering av bildbehandlingsparametrar +PREFERENCES_PROFILELOADPR;Laddningsprioritet för profil +PREFERENCES_PROFILEPRCACHE;Profil i cache +PREFERENCES_PROFILEPRFILE;Profil i indatafilen +PREFERENCES_PROFILESAVECACHE;Spara behandlingsparametrar till cachen +PREFERENCES_PROFILESAVEINPUT;Spara behandlingsparametrar med indatabildfilen +PREFERENCES_PROPERTY;Egenskaper +PREFERENCES_PSPATH;Adobe Photoshops installationskatalog +PREFERENCES_RGBDTL_LABEL;Maximalt antal trådar för brusreducering +PREFERENCES_RGBDTL_TOOLTIP;Brusreduceringen kräver ungefär 128MB RAM för en 10MPix bild och 512MB för en 40 MPix, och ytterligare 128MB per tråd. Ju fler trådar som körs parallellt, desto snabbare går beräkningarna. Ange värdet "0" för att automatiskt använda så många trådar som möjligt. +PREFERENCES_SELECTFONT;Välj typsnitt +PREFERENCES_SELECTLANG;Välj språk +PREFERENCES_SELECTTHEME;Välj tema +PREFERENCES_SET;Ange +PREFERENCES_SHOWBASICEXIF;Visa grundlig Exif-information +PREFERENCES_SHOWDATETIME;Visa datum och tid +PREFERENCES_SHOWEXPOSURECOMPENSATION;Lägg till exponeringskompensation +PREFERENCES_SHTHRESHOLD;Tröskelvärde för skuggor +PREFERENCES_SINGLETABVERTAB;Enkelfliksläge, vertikala flikar +PREFERENCES_SINGLETAB;Öppna en bild åt gången +PREFERENCES_SLIMUI;Slimmat gränssnitt +PREFERENCES_SND_BATCHQUEUEDONE;Batchkön färdig +PREFERENCES_SND_HELP;Fyll i en sökväg till ett ljud.\nI Windows kan "SystemDefault", "SystemAsterisk" o.s.v. användas.\nPå Linuxbaserade system kan du prova med "complete", "windows-attention" o.s.v. +PREFERENCES_SND_LNGEDITPROCDONE;När behandlingen är klar +PREFERENCES_SND_TRESHOLDSECS;Ljudet kommer efter så här många sekunder +PREFERENCES_STARTUPIMDIR;Bildkatalog som visas vid uppstart +PREFERENCES_TAB_BROWSER;Filbläddrare +PREFERENCES_TAB_COLORMGR;Färghantering +PREFERENCES_TAB_GENERAL;Allmän +PREFERENCES_TAB_IMPROC;Bildbehandling +PREFERENCES_TAB_PERFORMANCE;Prestanda +PREFERENCES_TAB_SOUND;Ljud +PREFERENCES_TP_LABEL;Verktygspanel: +PREFERENCES_TP_USEICONORTEXT;Använd ikoner istället för text +PREFERENCES_TP_VSCROLLBAR;Göm verktygpanelens vertikala skrollist +PREFERENCES_TUNNELMETADATA;Tunnla oförändrad IPTC/XMP till utfilen +PREFERENCES_USEBUNDLEDPROFILES;Visa förinstallerade profiler +PREFERENCES_USESYSTEMTHEME;Använd systemtema +PREFERENCES_VIEW;Utenhetens vitbalansvärde (datorskärm, TV, bildkanon, etc.) +PREFERENCES_WORKFLOW;Arbetsflöde +PROFILEPANEL_COPYPPASTE;Parametrar att kopiera +PROFILEPANEL_GLOBALPROFILES;Förinstallerade profiler +PROFILEPANEL_LABEL;Efterbehandlingsprofiler +PROFILEPANEL_LOADDLGLABEL;Ladda efterbehandlingsparametrar... +PROFILEPANEL_LOADPPASTE;Parametrar att ladda +PROFILEPANEL_MODE_TIP;Ifyllnadsläge för profil.\n\nKnappen nedtryckt: partiell profil konverteras till full profil; de saknade värdena kommer att fyllas i mha standardvärden.\n\nKnapp släppt: Profilen kommer att appliceras som den är, och förändrar bara de värden som den själv innehåller. +PROFILEPANEL_MYPROFILES;Mina profiler +PROFILEPANEL_PASTEPPASTE;Parametrar att klistra in +PROFILEPANEL_PCUSTOM;Egen +PROFILEPANEL_PFILE;Från fil +PROFILEPANEL_PINTERNAL;Neutral +PROFILEPANEL_PLASTSAVED;Senast sparad +PROFILEPANEL_SAVEDLGLABEL;Spara efterbehandlingsparametrar... +PROFILEPANEL_SAVEPPASTE;Parametrar att spara +PROFILEPANEL_TOOLTIPCOPY;Kopiera nuvarande profil till klippbordet.\nCtrl-vänsterklicka för att välja de parametrar du vill kopiera +PROFILEPANEL_TOOLTIPLOAD;Ladda profil.\nCtrl-klicka för att välja de parametrar du vill ladda +PROFILEPANEL_TOOLTIPPASTE; Klistra in profil från klippbordet.\nCtrl-klicka för att välja de parametrar du vill klistra in +PROFILEPANEL_TOOLTIPSAVE;Spara nuvarande profil.\nCtrl-klicka för att välja de parametrar du vill spara +PROGRESSBAR_LOADINGTHUMBS;Laddar miniatyrbilder... +PROGRESSBAR_LOADING;Laddar bild... +PROGRESSBAR_LOADJPEG;Laddar JPEG-fil... +PROGRESSBAR_LOADPNG;Laddar PNG-fil... +PROGRESSBAR_LOADTIFF;Laddar TIFF-fil... +PROGRESSBAR_NOIMAGES;Inga bilder funna. +PROGRESSBAR_PROCESSING;Bearbetar bild... +PROGRESSBAR_PROCESSING_PROFILESAVED;Efterbehandlingsprofil sparad +PROGRESSBAR_READY;Klar +PROGRESSBAR_SAVEJPEG;Sparar JPEG-fil... +PROGRESSBAR_SAVEPNG;Sparar PNG-fil... +PROGRESSBAR_SAVETIFF;Sparar TIFF-fil... +PROGRESSBAR_SNAPSHOT_ADDED;Bokmärke tillagt. +PROGRESSDLG_PROFILECHANGEDINBROWSER;Profilen har ändrats i filhanteraren +QINFO_ISO;ISO +QINFO_NOEXIF;Exif-information ej tillgänglig. +SAVEDLG_AUTOSUFFIX;Lägg automatiskt till en ändelse om filnamnet redan existerar +SAVEDLG_FILEFORMAT;Filformat +SAVEDLG_FORCEFORMATOPTS;Kräv att inställningar sparas +SAVEDLG_JPEGQUAL;JPEG-kvalitet +SAVEDLG_PNGCOMPR;PNG-komprimering +SAVEDLG_PUTTOQUEUEHEAD;Flytta längst fram i behandlingskön +SAVEDLG_PUTTOQUEUETAIL;Flytta längst bak i behandlingskön +SAVEDLG_PUTTOQUEUE;Lägg till i behandlingskön +SAVEDLG_SAVEIMMEDIATELY;Spara direkt +SAVEDLG_SAVESPP;Spara behandlingsparametrarna med bilderna +SAVEDLG_SUBSAMP_1;Högsta komprimering +SAVEDLG_SUBSAMP_2;Balanserad +SAVEDLG_SUBSAMP_3;Högsta kvalitet +SAVEDLG_SUBSAMP_TOOLTIP;Högsta komprimering: 4:1:1\nBalanserad: 4:2:2\nHögsta kvalitet: 4:4:4 +SAVEDLG_TIFFUNCOMPRESSED;Okomprimerad TIFF +SAVEDLG_WARNFILENAME;Filen kommer att heta +SHCSELECTOR_TOOLTIP;Klicka på höger musknapp för att återställa\nde tre reglagens positioner +THRESHOLDSELECTOR_BL;Nederst till vänster +THRESHOLDSELECTOR_BR;Nederst till höger +THRESHOLDSELECTOR_B;Nederst +THRESHOLDSELECTOR_HINT;Håll nere Shift tangenten för att flytta de olika kontrollpunkterna. +THRESHOLDSELECTOR_TL;Överst till vänster +THRESHOLDSELECTOR_TR;Överst till höger +THRESHOLDSELECTOR_T;Överst +TOOLBAR_TOOLTIP_CROP;Välj beskärningsområde.\nKortkommando: c\nFlytta beskärningsområdet genom att hålla nere Shift och vänstermusknapp och flytta musen. +TOOLBAR_TOOLTIP_HAND;Handverktyg.\nKortkommando:h +TOOLBAR_TOOLTIP_STRAIGHTEN;Räta upp.\nKortkommando:s\n\nDra en linje längs antingen en vertikal eller horisontell linje i bilden för att räta upp bilden. Roterationsvinkeln visas bredvid linjen du drar. Rotationscentrum är det geometriska mittpunkten i bilden. +TOOLBAR_TOOLTIP_WB;Mät vitbalans i bilden.\nKortkommando:w +TP_BWMIX_ALGO;Algoritm OYCPM +TP_BWMIX_ALGO_LI;Linjär +TP_BWMIX_ALGO_SP;Specialeffekter +TP_BWMIX_ALGO_TOOLTIP;Linjär: kommer att procudera ett normalt linjärt svar.\nSpecialeffekter: kommer att producera specialeffekter genom att miza kanalerna icke-linjärt. +TP_BWMIX_AUTOCH;Auto +TP_BWMIX_AUTOCH_TIP;Beräkna värden som optimerar kanalmixern +TP_BWMIX_CC_ENABLED;Justera komplementär färg +TP_BWMIX_CC_TOOLTIP;Aktivera för att tillåta automatisk justering av komplementär färg i ROYGCBPM-läget +TP_BWMIX_CHANNEL;Luminansequalizer +TP_BWMIX_CURVEEDITOR1;'Före'-kurva +TP_BWMIX_CURVEEDITOR2;'Efter'-kurva +TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Tonkurva efter S/V-konvertering, vid slutet av behandlingen +TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Tonkurva precis före S/V-konverteringen\nKan ta färgkomponenterna i beaktande +TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Ändra luminansen som en funktion av nyansen\nNotera extrema värden som kan orsaka artefakter +TP_BWMIX_FILTER;Färgfilter +TP_BWMIX_FILTER_BLUEGREEN;Blå-Grön +TP_BWMIX_FILTER_BLUE;Blå +TP_BWMIX_FILTER_GREENYELLOW;Grön-Gul +TP_BWMIX_FILTER_GREEN;Grön +TP_BWMIX_FILTER_NONE;Ingen +TP_BWMIX_FILTER_PURPLE;Lila +TP_BWMIX_FILTER_REDYELLOW;Röd-Gul +TP_BWMIX_FILTER_RED;Röd +TP_BWMIX_FILTER_TOOLTIP;Färgfiltret simulerar bilder tagna med ett färgat filter placerat framför objektivet. Färgade filter reducerar transmissionen av ett specifikt spektrum av färger och påverkar deras ljushet. T. ex. mörkar ett rött filter blå himmel. +TP_BWMIX_FILTER_YELLOW;Gul +TP_BWMIX_GAMMA;Gamma-korrigering +TP_BWMIX_GAM_TOOLTIP;Korrigera gamma för varje kanal i RGB +TP_BWMIX_LABEL;Svartvitt +TP_BWMIX_MET;Metod +TP_BWMIX_MET_CHANMIX;Kanalmixer +TP_BWMIX_MET_DESAT;Reducera mättnad +TP_BWMIX_MET_LUMEQUAL;Luminansequalizer +TP_BWMIX_MIXC;Blanda +TP_BWMIX_NEUTRAL;Återställ mixer +TP_BWMIX_NEUTRAL_TIP;Återställ alla värden (filter, kanalmixer) till standard +TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Totalt: %4%% +TP_BWMIX_RGBLABEL_HINT;Slutliga RGB-faktorer som tar hand om alla mixerinställningar\n"Totalt" visar summan av RGB-värden som faktiskt används:\n- alltid 100% i relativt läge\n- högre (ljusare) eller lägre (mörkare) än 100% i absolut läge. +TP_BWMIX_RGB_TOOLTIP;Blanda RGB-kanalerna. Använd förinställningar som en vägledning.\nNotera negativa värden som kan orsaka artefakter eller felaktiga beteenden. +TP_BWMIX_SETTING;Förinställningar +TP_BWMIX_SETTING_TOOLTIP;Olika förinställningar (film, landskap...) eller manuella inställningar av kanalmixern +TP_BWMIX_SET_HIGHCONTAST;Hög kontrast +TP_BWMIX_SET_HIGHSENSIT;Hög känslighet +TP_BWMIX_SET_HYPERPANCHRO;Hyperpankromatisk +TP_BWMIX_SET_INFRARED;Infraröd +TP_BWMIX_SET_LANDSCAPE;Landskap +TP_BWMIX_SET_LOWSENSIT;Låg känslighet +TP_BWMIX_SET_LUMINANCE;Luminans +TP_BWMIX_SET_NORMCONTAST;Normal kontrast +TP_BWMIX_SET_ORTHOCHRO;Orthokromatisk +TP_BWMIX_SET_PANCHRO;Pankromatisk +TP_BWMIX_SET_PORTRAIT;Porträtt +TP_BWMIX_SET_RGBABS;Kanalmixer, absolut RGB +TP_BWMIX_SET_RGBREL;Kanalmixer, relativt RGB +TP_BWMIX_SET_ROYGCBPMABS;Kanalmixer, absolut ROYGCBPM +TP_BWMIX_SET_ROYGCBPMREL;Kanalmixer, relativt ROYGCBPM +TP_BWMIX_TCMODE_FILMLIKE;S/V Filmlik +TP_BWMIX_TCMODE_SATANDVALBLENDING;S/V mättnad och värdeblandning +TP_BWMIX_TCMODE_STANDARD;S/V standard +TP_BWMIX_TCMODE_WEIGHTEDSTD;S/V viktad standard +TP_BWMIX_VAL;L +TP_CACORRECTION_BLUE;Blå +TP_CACORRECTION_LABEL;Reducera kromatiska abberationer +TP_CACORRECTION_RED;Röd +TP_CHMIXER_BLUE;Blå kanal +TP_CHMIXER_GREEN;Grön kanal +TP_CHMIXER_LABEL;Kanalmixer +TP_CHMIXER_RED;Röd kanal +TP_CHROMATABERR_LABEL;Kromatiska abberationer +TP_COARSETRAF_TOOLTIP_HFLIP;Vänd horisontellt +TP_COARSETRAF_TOOLTIP_ROTLEFT;Rotera åt vänster.\nKortkommando: [ +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Rotera åt höger.\nKortkommando: ] +TP_COARSETRAF_TOOLTIP_VFLIP;Vänd vertikalt +TP_COLORAPP_ADAPTSCENE;Luminans hos vyn +TP_COLORAPP_ADAPTSCENE_TOOLTIP;Absolut luminans hos vyn (cd/m²).\n1) Beräknas från exif-informationen:\nSlutartid - ISO-tal - Bländartal - exponeringskompensation gjord av kameran.\n2) Beräknas från vitpunkten hos råbilden och RT:s reglage för exponeringskompensation +TP_COLORAPP_ADAPTVIEWING;Betrakningsluminans (cd/m²) +TP_COLORAPP_ADAPTVIEWING_TOOLTIP;Absolut luminans hos betrakningsomgivningen\n(vanligtvis 16cd/m²) +TP_COLORAPP_ADAP_AUTO_TOOLTIP;Om checkboxen är aktiverad (rekommenderas) beräknar RT ett optimalt värde från exif-informationen.\nFör att sätta ett värde manuellt, avaktivera funktionen först +TP_COLORAPP_ALGO;Algoritm +TP_COLORAPP_ALGO_ALL;Alla +TP_COLORAPP_ALGO_JC;Ljushet + kroma (JC) +TP_COLORAPP_ALGO_JS;Ljushet + mättnad (JS) +TP_COLORAPP_ALGO_QM;Intensitet + färgmättnad (QM) +TP_COLORAPP_ALGO_TOOLTIP;Låter dig välja mellan delmängder av eller alla parametrar. +TP_COLORAPP_BADPIXSL;Filter för heta/dålia pixlar +TP_COLORAPP_BADPIXSL_TOOLTIP;Dämpa heta/dåliga (ljust färgade) pixlar.\n 0=ingen effekt 1=median 2=gaussian.\n\nDe här artefakterna kommer sig av tillkortakommanden i CIECAM02. Alternativt, justera bilden så att mycket mörka skuggor undviks +TP_COLORAPP_BRIGHT;Intensitet (Q) +TP_COLORAPP_BRIGHT_TOOLTIP;Intensitet i CIECAM02 tar i beaktande det vitas luminositet och skiljer sig från ljushet i Lab och RGB +TP_COLORAPP_CHROMA;Kroma (C) +TP_COLORAPP_CHROMA_M;Färgmättnad (M) +TP_COLORAPP_CHROMA_M_TOOLTIP;Färgmättnad i CIECAM02 skiljer sig från colofulness i Lab och RGB +TP_COLORAPP_CHROMA_S;Kroma (S) +TP_COLORAPP_CHROMA_S_TOOLTIP;Mättnad i CIECAM02 skiljer sig från mättnad i Lab och RGB +TP_COLORAPP_CHROMA_TOOLTIP;Kroma i CIECAM02 skiljer sig åt från kroma i Lab och RGB +TP_COLORAPP_CIECAT_DEGREE;CAT02-anpassning +TP_COLORAPP_CONTRAST;Kontrast (J) +TP_COLORAPP_CONTRAST_Q;Kontrast (Q) +TP_COLORAPP_CONTRAST_Q_TOOLTIP;Kontrast i CIECAM02 för Q-reglaget; skiljer sig från kontrast i Lab och RGB +TP_COLORAPP_CONTRAST_TOOLTIP;Kontrast i CIECAM02 för J-reglaget; skiljer sig från kontrast i Lab och RGB +TP_COLORAPP_CURVEEDITOR1;Tonkurva 1 +TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Visar histogrammet hos L (Lab) före CIECAM02.\nOm checkboxen "Show CIECAM02 output histograms in curves" är aktiverad, visas histogrammet för J och Q efter CIECAM02.\n\nJ och Q visas ej i histogrammet i huvudpanelen.\n\nFör slutligt resultat, se huvudpanelens histogram +TP_COLORAPP_CURVEEDITOR2;Tonkurva 2 +TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Används på samma sätt som med den andra tonkurvan. +TP_COLORAPP_CURVEEDITOR3;Färgkurva +TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Justera antingen kroma, mättnad eller colorfulness.\n\nVisar histogrammet hos kromaciteten (Lab) före CIECAM02.\nOm checkboxen "Show CIECAM02 output histograms in curves" är aktiverad, visas histogrammet för C, s eller M efter CIECAM02.\n\nC, s och M visas ej i histogrammet i huvudpanelen.\n\nFör slutligt resultat, se huvudpanelens histogram +TP_COLORAPP_DATACIE;Resultat av CIECAM02-histogram i kurvor +TP_COLORAPP_DATACIE_TOOLTIP;När detta är aktiverat, visar CIECAM02-histogram ungefärliga värden/intervall för J eller Q, och C, s eller M efter justeringar i CIECAM02.\nDet här valet påverkar inte huvudhistogrammet.\n\nNär detta är avaktiverat, visar histogrammet för CIECAM02-kurvor Lab-värden innan justeringar av CIECAM02 +TP_COLORAPP_DEGREE_AUTO_TOOLTIP;Om den här checkboxen är aktiverad (rekommenderas), beräknar RT ett optimalt värde som sedan dels används av CAT02 och dels för hela CIECAM02.\nFör att ange ett värde manuellt, avaktivera checkboxen först (värden över 65 rekommenderas) +TP_COLORAPP_DEGREE_TOOLTIP;Mängd CIE kromatisk anpassning 2002 +TP_COLORAPP_GAMUT;Kontroll av gamut (Lab) +TP_COLORAPP_GAMUT_TOOLTIP;Tillåt kontroll av gamut i Lab-läge +TP_COLORAPP_HUE;Nyans(h) +TP_COLORAPP_HUE_TOOLTIP;Nyans h) - vinkel mellan 0° och 360° +TP_COLORAPP_LABEL_CAM02;Bildjusteringar +TP_COLORAPP_LABEL_SCENE;Förhållanden då bilden togs +TP_COLORAPP_LABEL_VIEWING;Förhållanden vid betraktande +TP_COLORAPP_LIGHT;Ljushet (J) +TP_COLORAPP_LIGHT_TOOLTIP;Ljushet i CIECAM02 är ej lika som de i Lab och RGB +TP_COLORAPP_MODEL;Vitpunktsmodell +TP_COLORAPP_MODEL_TOOLTIP;Vitpunktsmodell\n\nWB [RT] + [output]:\nRT:s vitbalans används för bilden, CIECAM02 sätts till D50, utmatningsenhetens vitbalans sätts i Inställningar > Färghantering\n\nWB [RT+CAT02] + [output]:\nRT:s vitbalansinställningar används av CAT02 och utmatningsenhetens vitbalans sätts i Inställningar +TP_COLORAPP_RSTPRO;Bevara röda färger och hudtoner +TP_COLORAPP_RSTPRO_TOOLTIP;Bevara röda färger och hudtoner (reglage och kurvor) +TP_COLORAPP_SHARPCIE;Skärpa, Kontrast genom detaljnivåer, Mikrokontrast och Fyll ut överstrålning med kvalitetskontroll +TP_COLORAPP_SHARPCIE_TOOLTIP;Skärpa, Kontrast genom detaljnivåer, Mikrokontrast och Fyll ut överstrålning kommer att använda CIECAM02 om den är aktiverad +TP_COLORAPP_SURROUND;Omgivning +TP_COLORAPP_SURROUND_AVER;Medel +TP_COLORAPP_SURROUND_DARK;Mörk +TP_COLORAPP_SURROUND_DIM;Dunkelt +TP_COLORAPP_SURROUND_EXDARK;Extremt mörkt +TP_COLORAPP_SURROUND_TOOLTIP;Ändra toner och färger för att ta i beaktande betraktningsförhållandena för utmatningsenheten\n\nMedel:\nMedelljusa omgivningar (standard)\nBilden kommer ej att ändras\n\nDunkelt:\nDunkla omgivningar (TV)\nBilden kommer att bli aningen mörkare\n\nMörk:\nMörka omgivningar (projektor)\nBilden kommer att bli mörkare\n\nExtremt mörkt:\nExtremt mörka omgivningar (cutsheet)\nBilden kommer bli mycket mörk +TP_COLORAPP_SURSOURCE;Mörk omgivning +TP_COLORAPP_SURSOURCE_TOOLTIP;Kan användas om källbilden har en mörk kant. +TP_COLORAPP_TCMODE_BRIGHTNESS;Intensitet +TP_COLORAPP_TCMODE_CHROMA;Kroma +TP_COLORAPP_TCMODE_COLORF;Färgmättnad +TP_COLORAPP_TCMODE_LABEL1;Kurvläge 1 +TP_COLORAPP_TCMODE_LABEL2;Kurvläge 2 +TP_COLORAPP_TCMODE_LABEL3;Kromaläge för kurvor +TP_COLORAPP_TCMODE_LIGHTNESS;Ljushet +TP_COLORAPP_TCMODE_SATUR;Mättnad +TP_COLORAPP_TONECIE;Tonmappning som använder CIECAM02 ljushet (Q) +TP_COLORAPP_TONECIE_TOOLTIP;Om det här valet ej är aktiverat, görs tonmappningen i Lab.\nOm det här valet är aktiverat, görs tonmappningen mha CIECAM02.\nTonmappningsverktyget måste vara aktiverad för att den här inställningen ska ha någon effekt +TP_COLORAPP_WBCAM;Vitbalans [RT+CAT02] + [utmatning] +TP_COLORAPP_WBRT;Vitbalans [RT] + [utmatning] +TP_CROP_FIXRATIO;Fast proportion +TP_CROP_GTDIAGONALS;Diagonalregeln +TP_CROP_GTEPASSPORT;Biometriskt pass +TP_CROP_GTFRAME;Ram +TP_CROP_GTGRID;Rutnät +TP_CROP_GTNONE;Ingen +TP_CROP_GTRULETHIRDS;Tredjedelsregeln +TP_CROP_GUIDETYPE;Guidetyp: +TP_CROP_H;Höjd +TP_CROP_LABEL;Beskär +TP_CROP_PPI;PPI= +TP_CROP_SELECTCROP;Välj beskärningsområde +TP_CROP_W;Bredd +TP_CROP_X;x +TP_CROP_Y;y +TP_DARKFRAME_AUTOSELECT;Välj svartbild automatiskt +TP_DARKFRAME_LABEL;Svartbild +TP_DEFRINGE_LABEL;Fyll ut överstrålning +TP_DEFRINGE_RADIUS;Radie +TP_DEFRINGE_THRESHOLD;Tröskelvärde +TP_DIRPYRDENOISE_BLUE;Krominans - Blå-Gul +TP_DIRPYRDENOISE_CHROMA;Kroma +TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Kan användas på rå- och icke-råbilder.\n\nFör icke-råbilder beror brusreduceringen (~luminans) på in-profilens gamma. Gamma hos sRGB antas, och således: om bildens profil har ett annat gammavärde, så kommer brusreduceringen att variera. +TP_DIRPYRDENOISE_ENH;Förbättrat läge +TP_DIRPYRDENOISE_ENH_TOOLTIP;Ökar kvaliteten på brusreduceringen till priset av 20 % längre beräkningstid +TP_DIRPYRDENOISE_GAMMA;Gamma +TP_DIRPYRDENOISE_GAMMA_TOOLTIP;Gamma varierar brusreduceringens styrka över hela skalan av toner. Mindre värden riktar sig mot de mörka partierna i bilden, medan större värden utökar effekten till högdagrarna. +TP_DIRPYRDENOISE_LABEL;Brusreducering +TP_DIRPYRDENOISE_LAB;Lab +TP_DIRPYRDENOISE_LDETAIL;Luminansdetalj +TP_DIRPYRDENOISE_LUMA;Luminans +TP_DIRPYRDENOISE_METHOD;Metod +TP_DIRPYRDENOISE_METHOD_TOOLTIP;För råfiler kan antingen RGB- eller Labmetoder användas.\n\nFör icke-råfiler kommer Labmetoden att användas, oavsett vad som är valt. +TP_DIRPYRDENOISE_RED;Krominans - Röd-Grön +TP_DIRPYRDENOISE_RGB;RGB +TP_DIRPYREQUALIZER_ALGO;Algoritm för hudtoner +TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fin: närmre hudens färger, minimerar inverkan på andra färger\nStor: undvik än mer artefakter +TP_DIRPYREQUALIZER_HUESKIN;Nyans på hudtoner +TP_DIRPYREQUALIZER_LABEL;Kontrast genom detaljnivåer +TP_DIRPYREQUALIZER_LUMACOARSEST;Grövst +TP_DIRPYREQUALIZER_LUMACONTRAST_MINUS;Minska kontrasten +TP_DIRPYREQUALIZER_LUMACONTRAST_PLUS;Öka kontrasten +TP_DIRPYREQUALIZER_LUMAFINEST;Finast +TP_DIRPYREQUALIZER_LUMANEUTRAL;Neutralt +TP_DIRPYREQUALIZER_SKIN;Hudtoner Mål/Skydd +TP_DIRPYREQUALIZER_SKIN_TOOLTIP;Vid -100 påverkas hudtoner.\nVid 0 behandlas alla toner likvärdigt.\nVid +100 skyddas hudtoner medan alla andra toner är påverkade. +TP_DIRPYREQUALIZER_THRESHOLD;Tröskelvärde +TP_DIRPYREQUALIZER_TOOLTIP;Försöker reducera artefakter uppkomna av övergångarna mellan färgerna (nyans, kroma, luminans) på hyn och övriga i bilden +TP_DISTORTION_AMOUNT;Mängd +TP_DISTORTION_AUTO;Automatisk distorsionskorrigering +TP_DISTORTION_AUTO_TIP;(Experimentell) Korrigera automatiskt objektivdistorsion för vissa kameror (M4/3, vissa kompaktkameror, etc.) +TP_DISTORTION_LABEL;Distorsion +TP_EPD_EDGESTOPPING;Stoppa vid kanter +TP_EPD_LABEL;Tonmappning +TP_EPD_REWEIGHTINGITERATES;Återviktade iterationer +TP_EPD_SCALE;Skala +TP_EPD_STRENGTH;Styrka +TP_EPD_TOOLTIP;Tonmappning är möjligt via Lab-läge (standard) och CIECAM02-läge.\n\nFör att aktivera CIECAM02- tonmappningsläget, aktivera följande:\n1. CIECAM02\n2. Algoritm="Intensitet + Färgmättnad (QM)"\n3. "Tonmappning mha CIECAM02 intensitet (Q)" +TP_EXPOSURE_AUTOLEVELS;Autonivåer +TP_EXPOSURE_AUTOLEVELS_TIP;Slå av/på autonivåer för att automatiskt beräkna och använda värden baserat på bildanalys\nAktiverar högdageråterställning om nödvändigt +TP_EXPOSURE_BLACKLEVEL;Svärta +TP_EXPOSURE_BRIGHTNESS;Ljushet +TP_EXPOSURE_CLIP;Klippnivå % +TP_EXPOSURE_CLIP_TIP;Andelen pixlar som ska klippas när autonivåer används. +TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Högdageråterställning, tröskelvärde +TP_EXPOSURE_COMPRHIGHLIGHTS;Högdageråterställning +TP_EXPOSURE_COMPRSHADOWS;Skuggåterställning +TP_EXPOSURE_CONTRAST;Kontrast +TP_EXPOSURE_CURVEEDITOR1;Tonkurva 1 +TP_EXPOSURE_CURVEEDITOR2;Tonkurva 2 +TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Se följande del i manualen hur man uppnår bästa resultat med dubbla kurvor:\nThe Toolbox > Exposure Tab > Exposure Panel > Tone Curve +TP_EXPOSURE_EXPCOMP;Exponeringskompensation +TP_EXPOSURE_LABEL;Exponering +TP_EXPOSURE_SATURATION;Mättnad +TP_EXPOSURE_TCMODE_FILMLIKE;Filmlik +TP_EXPOSURE_TCMODE_LABEL1;Kurvläge 1 +TP_EXPOSURE_TCMODE_LABEL2;Kurvläge 2 +TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Mättnads- och värdeblandning +TP_EXPOSURE_TCMODE_STANDARD;Standard +TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Viktad standard +TP_FLATFIELD_AUTOSELECT;Autoval +TP_FLATFIELD_BLURRADIUS;Oskärperadie +TP_FLATFIELD_BLURTYPE;Oskärpetyp +TP_FLATFIELD_BT_AREA;Area +TP_FLATFIELD_BT_HORIZONTAL;Horisontell +TP_FLATFIELD_BT_VERTHORIZ;Vertikal + horisontell +TP_FLATFIELD_BT_VERTICAL;Vertikal +TP_FLATFIELD_LABEL;Plattfält +TP_GAMMA_CURV;gamma +TP_GAMMA_FREE;Obunden gamma +TP_GAMMA_OUTPUT;Utmatningsgamma +TP_GAMMA_SLOP;Lutning (linjär) +TP_GENERAL_11SCALE_TOOLTIP;Effekten från det här verktyget eller några av dess underkomponenter syns endast då de visas i 1:1-skala eller högre +TP_GRADIENT_CENTER;Centrum +TP_GRADIENT_CENTER_X;Centrum, X +TP_GRADIENT_CENTER_X_TOOLTIP;Rotationspunkt, X:\n -100=vänstra kanten\n 0=centrum\n +100=högra kanten +TP_GRADIENT_CENTER_Y;Centrum, Y +TP_GRADIENT_CENTER_Y_TOOLTIP;Rotationspunkt, Y:\n -100=övre kanten\n 0=centrum\n +100=nedersta kanten +TP_GRADIENT_DEGREE;Vinkel +TP_GRADIENT_DEGREE_TOOLTIP;Rotationsvinkel i grader +TP_GRADIENT_FEATHER;Fjäder +TP_GRADIENT_FEATHER_TOOLTIP;Bredd på gradienten i procent av bilddiagonalen +TP_GRADIENT_LABEL;Graderat filter +TP_GRADIENT_STRENGTH;Styrka +TP_GRADIENT_STRENGTH_TOOLTIP;Filterstyrka i steg +TP_HLREC_BLEND;Smält samman +TP_HLREC_CIELAB;CIELab +TP_HLREC_COLOR;Färgspridning +TP_HLREC_ENA_TOOLTIP;Kan aktiveras av autonivåer +TP_HLREC_LABEL;Högdageråterställning +TP_HLREC_LUMINANCE;Bättring av luminans +TP_HLREC_METHOD;Metod: +TP_HSVEQUALIZER_CHANNEL;Kanal +TP_HSVEQUALIZER_HUE;Nyans +TP_HSVEQUALIZER_LABEL;HSV-equalizer +TP_HSVEQUALIZER_SAT;Mättnad +TP_HSVEQUALIZER_VAL;Värde +TP_ICM_BLENDCMSMATRIX;Mixa högdagrar med matris +TP_ICM_BLENDCMSMATRIX_TOOLTIP;Möjliggör återskapande av utbrända högdagrar när LUT-baserade ICC-profiler används. +TP_ICM_DCPILLUMINANT;Ljuskälla +TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolerad ljuskälla +TP_ICM_DCPILLUMINANT_TOOLTIP;Välj vilken inbäddad DCP-ljuskälla som ska användas. Standard är "interpolerad" som är en blandning mellan de två baserad på vitbalans. Valet är endast aktiverat om en DCP från en dubbel ljuskälla med interpoleringsstöd är vald +TP_ICM_INPUTCAMERAICC;Automatiskt vald kameraprofil +TP_ICM_INPUTCAMERAICC_TOOLTIP;Använd RawTherapees kameraspecifika DCP- eller ICC-färgprofiler. Dessa profiler är mer exakta än enkla matrisprofiler, men finns inte för alla kameror. Profilerna lagras i /iccprofiles/input- och i /dcpprofiles-katalogerna och hämtas automatiskt baserat på ett filnamn som exakt matchar kameramodellen. +TP_ICM_INPUTCAMERA;Standard för kameran +TP_ICM_INPUTCAMERA_TOOLTIP;Använd enkel färgmatris från dcraw, förbättrad version från RawTherapee (oavsett vilken som är tillgänglig baserad på kameramodell) eller inbäddad från DNG. +TP_ICM_INPUTCUSTOM;Egen +TP_ICM_INPUTCUSTOM_TOOLTIP;Välj din egen DCP/ICC-profil för kameran. +TP_ICM_INPUTDLGLABEL;Välj färginmatningsprofil... +TP_ICM_INPUTEMBEDDED;Använd inbäddad, om möjligt +TP_ICM_INPUTEMBEDDED_TOOLTIP;Använd den färgprofil som är inbäddad i icke-råfiler. +TP_ICM_INPUTNONE;Ingen profil +TP_ICM_INPUTNONE_TOOLTIP;Använd ingen färginmatningsprofil alls. Används bara i specialfall. +TP_ICM_INPUTPROFILE;Inmatningsprofil +TP_ICM_LABEL;Färghantering +TP_ICM_NOICM;Ingen färghantering: sRGB-utmatning +TP_ICM_OUTPUTPROFILE;Utmatningsprofil +TP_ICM_SAVEREFERENCE;Spara referensbild för profilering +TP_ICM_SAVEREFERENCE_TOOLTIP;Spara den linjära TIFF-bilden innan inmatningsprofilen appliceras. Detta kan användas för kalibreringsändamål eller generering av en kameraprofil. +TP_ICM_TONECURVE;Använd DCP:s tonkurva +TP_ICM_TONECURVE_TOOLTIP;Aktivera för att använda tonkurvor som kan finnas i DCP-profilen. +TP_ICM_WORKINGPROFILE;Färgrymd +TP_IMPULSEDENOISE_LABEL;Brusreducering mha av stegsvar +TP_IMPULSEDENOISE_THRESH;Tröskelvärde +TP_LABCURVE_AVOIDCOLORSHIFT;Undvik färgskift +TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Passa färger i färgrymden och applicera Munsell-korrigering +TP_LABCURVE_BRIGHTNESS;Ljushet +TP_LABCURVE_CHROMATICITY;Kroma +TP_LABCURVE_CHROMA_TOOLTIP;För att åstadkomma en S/V-toning, sätt Kroma till -100 +TP_LABCURVE_CONTRAST;Kontrast +TP_LABCURVE_CURVEEDITOR;Luminanskurva +TP_LABCURVE_CURVEEDITOR_A_RANGE1;Grön mättad +TP_LABCURVE_CURVEEDITOR_A_RANGE2;Grön pastell +TP_LABCURVE_CURVEEDITOR_A_RANGE3;Röd pastell +TP_LABCURVE_CURVEEDITOR_A_RANGE4;Röd mättad +TP_LABCURVE_CURVEEDITOR_B_RANGE1;Blå mättad +TP_LABCURVE_CURVEEDITOR_B_RANGE2;Blå pastell +TP_LABCURVE_CURVEEDITOR_B_RANGE3;Gul pastell +TP_LABCURVE_CURVEEDITOR_B_RANGE4;Gul mättad +TP_LABCURVE_CURVEEDITOR_CC;CC +TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutral +TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Svag +TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastell +TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Mättad +TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Kroma enligt kroma C=f(C) +TP_LABCURVE_CURVEEDITOR_CH;CH +TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Kroma enligt nyans C=f(H) +TP_LABCURVE_CURVEEDITOR_CL;CL +TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Kroma enligt luminans C=f(L) +TP_LABCURVE_CURVEEDITOR_HH;HH +TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Nyans enligt nyans H=f(H) +TP_LABCURVE_CURVEEDITOR_LC;LC +TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminans enligt kroma L=f(C) +TP_LABCURVE_CURVEEDITOR_LH;LH +TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Luminans enligt nyans L=f(H) +TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminans enligt luminans L=f(L) +TP_LABCURVE_LABEL;Labjusteringar +TP_LABCURVE_LCREDSK;Begränsa LC till röda färger och hudtoner +TP_LABCURVE_LCREDSK_TIP;Om aktiverad så påverkar LC-kurvan enbart röda färger och hudtoner.\nOm ej aktiverad så appliceras den till alla färger och toner. +TP_LABCURVE_RSTPROTECTION;Skydda röda färger och hudtoner +TP_LABCURVE_RSTPRO_TOOLTIP;Kan användas med kromareglaget och CC-kurvan +TP_LENSGEOM_AUTOCROP;Autobeskärning +TP_LENSGEOM_FILL;Fyll automatiskt +TP_LENSGEOM_LABEL;Geometrisk- och distorsionskorrigering +TP_LENSPROFILE_LABEL;Objektivkorrigeringsprofil +TP_LENSPROFILE_USECA;Korrigera för kromatiska abberationer +TP_LENSPROFILE_USEDIST;Korrigera distorsion +TP_LENSPROFILE_USEVIGN;Korrigera vinjettering +TP_NEUTRAL;Neutral +TP_NEUTRAL_TIP;Återställ exponeringsreglagen till neutrala värden.\nGäller för samma reglage som autonivåer, oavsett om du använder autonivåer eller ej +TP_PCVIGNETTE_FEATHER;Fjäder +TP_PCVIGNETTE_FEATHER_TOOLTIP;Fjäder: 0=enbart kanter, 50=halvvägs till mitten, 100=i mitten +TP_PCVIGNETTE_LABEL;Vinjetteringsfilter +TP_PCVIGNETTE_ROUNDNESS;Rundhet +TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Rundhet: 0=rektangel, 50=passad ellips, 100=cirkel +TP_PCVIGNETTE_STRENGTH;Styrka +TP_PCVIGNETTE_STRENGTH_TOOLTIP;Filterstyrka i steg (som nått till kanterna) +TP_PERSPECTIVE_HORIZONTAL;Horisontell +TP_PERSPECTIVE_LABEL;Perspektiv +TP_PERSPECTIVE_VERTICAL;Vertikal +TP_PFCURVE_CURVEEDITOR_CH;Nyans +TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Kontrollerar överstrålning efter färg. Högre = mer, lägre = mindre. +TP_PREPROCESS_GREENEQUIL;Grönbalansering +TP_PREPROCESS_LABEL;Förbehandling +TP_PREPROCESS_LINEDENOISE;Linjärt brusfilter +TP_PREPROCESS_NO_FOUND;Inga hittade +TP_RAWCACORR_AUTO;Reducera automatiskt kromatiska abberationer +TP_RAWCACORR_CABLUE;Blå +TP_RAWCACORR_CARED;Röd +TP_RAWEXPOS_BLACKS;Svartpunktsnivåer +TP_RAWEXPOS_LINEAR;Vitpunktskorrigering +TP_RAWEXPOS_PRESER;Bevara högdagrar +TP_RAWEXPOS_TWOGREEN;Två gröna tillsammans +TP_RAW_DCBENHANCE;DCB-förbättringssteg +TP_RAW_DCBITERATIONS;Antal DCB-iterationer +TP_RAW_DMETHOD;Metod +TP_RAW_DMETHOD_PROGRESSBAR;%1 demosaicing... +TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Förfining av demosaicing... +TP_RAW_DMETHOD_TOOLTIP;Notera: IGV och LMMSE är avsedda för bilder där mycket brus förekommer. +TP_RAW_FALSECOLOR;Falskt färgbortträngningssteg +TP_RAW_LABEL;Demosaicing +TP_RAW_LMMSEITERATIONS;LMMSE förbättringssteg +TP_RAW_LMMSE_TOOLTIP;Adderar gamma (steg 1) - adderar median (steg 2,3 och 4), slutligen adderas ett förfiningssteg (steg 5 och 6) för att reducera artefakter och för att förbättra signal/brusförhållandet. +TP_RESIZE_APPLIESTO;Tillämpas på: +TP_RESIZE_CROPPEDAREA;Beskuren yta +TP_RESIZE_FITBOX;Begränsad yta +TP_RESIZE_FULLIMAGE;Hela bilden +TP_RESIZE_HEIGHT;Höjd +TP_RESIZE_H;H: +TP_RESIZE_LABEL;Ändra storlek +TP_RESIZE_LANCZOS;Lanczos +TP_RESIZE_METHOD;Metod: +TP_RESIZE_NEAREST;Närmast +TP_RESIZE_SCALE;Skala +TP_RESIZE_SPECIFY;Specificera: +TP_RESIZE_WIDTH;Bredd +TP_RESIZE_W;B: +TP_RGBCURVES_BLUE;B +TP_RGBCURVES_CHANNEL;Kanal +TP_RGBCURVES_GREEN;G +TP_RGBCURVES_LABEL;RGB-kurvor +TP_RGBCURVES_LUMAMODE;Luminansläge +TP_RGBCURVES_LUMAMODE_TOOLTIP;Luminansläget tillåter att bidraget från R-, G- och B-kanalerna varierar för bildens luminans utan att ändra färgerna +TP_RGBCURVES_RED;R +TP_ROTATE_DEGREE;Grader +TP_ROTATE_LABEL;Rotera +TP_ROTATE_SELECTLINE;Välj rak linje +TP_SAVEDIALOG_OK_TIP;Kortkommando: Ctrl-Enter +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Högdager +TP_SHADOWSHLIGHTS_HLTONALW;Tonvidd (Högdagrar) +TP_SHADOWSHLIGHTS_LABEL;Skugg- och högdageråterställning +TP_SHADOWSHLIGHTS_LOCALCONTR;Lokal kontrast +TP_SHADOWSHLIGHTS_RADIUS;Radie +TP_SHADOWSHLIGHTS_SHADOWS;Skuggor +TP_SHADOWSHLIGHTS_SHARPMASK;Skarp mask +TP_SHADOWSHLIGHTS_SHTONALW;Tonvidd (Skuggor) +TP_SHARPENEDGE_AMOUNT;Mängd +TP_SHARPENEDGE_LABEL;Kanter +TP_SHARPENEDGE_PASSES;Iterationer +TP_SHARPENEDGE_THREE;Endast luminans +TP_SHARPENING_AMOUNT;Mängd +TP_SHARPENING_EDRADIUS;Radie +TP_SHARPENING_EDTOLERANCE;Kanttolerans +TP_SHARPENING_HALOCONTROL;Halo-kontroll +TP_SHARPENING_HCAMOUNT;Mängd +TP_SHARPENING_LABEL;Skärpa +TP_SHARPENING_METHOD;Metod +TP_SHARPENING_ONLYEDGES;Skärp bara kanter +TP_SHARPENING_RADIUS;Radie +TP_SHARPENING_RLD;RL-dekonvolution +TP_SHARPENING_RLD_AMOUNT;Mängd +TP_SHARPENING_RLD_DAMPING;Dämpning +TP_SHARPENING_RLD_ITERATIONS;Upprepningar +TP_SHARPENING_THRESHOLD;Tröskelvärde +TP_SHARPENING_TOOLTIP;Förvänta dig en lite annorlunda effekt när denna används tillsammans med CIECAM02. +TP_SHARPENING_USM;Oskarp mask +TP_SHARPENMICRO_AMOUNT;Mängd +TP_SHARPENMICRO_LABEL;Mikrokontrast +TP_SHARPENMICRO_MATRIX;3×3-matris istället för 5×5 +TP_SHARPENMICRO_UNIFORMITY;Enhetlighet +TP_VIBRANCE_AVOIDCOLORSHIFT;Undivk färgskiftningar +TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH +TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Hudtoner +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Röd/Lila +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Röd +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Röd/Gul +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Gul +TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Nyans enligt nyans +TP_VIBRANCE_LABEL;Lyster +TP_VIBRANCE_PASTELS;Pastellfärger +TP_VIBRANCE_PASTSATTOG;Koppla pastell- och mättade toner +TP_VIBRANCE_PROTECTSKINS;Skydda hudfärger +TP_VIBRANCE_PSTHRESHOLD;Tröskelvärde för pastell- eller mättade toner +TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Tröskelvärde för mättnaden +TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;Den vertikala axeln representerar pastelltoner vid nederkanten och mättade toner vid överkanten.\nDen horisontella axeln representerar mättnadens omfattning. +TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Viktning av pastell- eller mättade övergångar +TP_VIBRANCE_SATURATED;Mättade färger +TP_VIGNETTING_AMOUNT;Mängd +TP_VIGNETTING_CENTER;Centrum +TP_VIGNETTING_CENTER_X;Centrum X +TP_VIGNETTING_CENTER_Y;Centrum Y +TP_VIGNETTING_LABEL;Vinjetteringskorrigering +TP_VIGNETTING_RADIUS;Radie +TP_VIGNETTING_STRENGTH;Styrka +TP_WBALANCE_AUTO;Auto +TP_WBALANCE_CAMERA;Kamera +TP_WBALANCE_CLOUDY;Molnigt +TP_WBALANCE_CUSTOM;Egen +TP_WBALANCE_DAYLIGHT;Dagsljus (soligt) +TP_WBALANCE_EQBLUERED;Blå/Röd equalizer +TP_WBALANCE_EQBLUERED_TOOLTIP;Tillåt att avvika från det normala beteendet för vitbalansen genom att modulera balansen mellan blått och rött.\nDet här kan vara användbart när förhållandena då bilden togs:\na) är långtifrån standardilluminansen (t. ex. under vattnet)\nb) är långt ifrån de förhållanden då kalibreringen gjordes\nc) där matriserna eller färgprofilerna ej är passande +TP_WBALANCE_FLASH55;Leica +TP_WBALANCE_FLASH60;Standard, Canon, Pentax, Olympus +TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta +TP_WBALANCE_FLASH_HEADER;Blixt +TP_WBALANCE_FLUO1;F1 - Dagsljus +TP_WBALANCE_FLUO2;F2 - Vit, kall +TP_WBALANCE_FLUO3;F3 - Vit +TP_WBALANCE_FLUO4;F4 - Vit, varm +TP_WBALANCE_FLUO5;F5 - Dagsljus +TP_WBALANCE_FLUO6;F6 - Vitt, ljus +TP_WBALANCE_FLUO7;F7 - D65 Dagsljussimulerat +TP_WBALANCE_FLUO8;F8 - D50 / Sylvania F40 Design +TP_WBALANCE_FLUO9;F9 - Vit, kall deluve +TP_WBALANCE_FLUO10;F10 - Philips TL85 +TP_WBALANCE_FLUO11;F11 - Philips TL84 +TP_WBALANCE_FLUO12;F12 - Philips TL83 +TP_WBALANCE_FLUO_HEADER;Lysrör +TP_WBALANCE_GREEN;Färgton +TP_WBALANCE_GTI;GTI +TP_WBALANCE_HMI;HMI +TP_WBALANCE_JUDGEIII;JudgeIII +TP_WBALANCE_LABEL;Vitbalans +TP_WBALANCE_LAMP_HEADER;Lampa +TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 +TP_WBALANCE_LED_HEADER;LED +TP_WBALANCE_LED_LSI;LSI Lumelex 2040 +TP_WBALANCE_METHOD;Metod +TP_WBALANCE_SHADE;Skugga +TP_WBALANCE_SIZE;Storlek: +TP_WBALANCE_SOLUX35;Solux 3500K +TP_WBALANCE_SOLUX41;Solux 4100K +TP_WBALANCE_SOLUX47;Solux 4700K (tillverkare) +TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) +TP_WBALANCE_SPOTWB;Punktmätning av vitbalansen +TP_WBALANCE_TEMPERATURE;Temperatur +TP_WBALANCE_TUNGSTEN;Glödlampa +TP_WBALANCE_WATER1;Under vattnet 1 +TP_WBALANCE_WATER2;Under vattnet 2 +TP_WBALANCE_WATER_HEADER;Under vattnet +ZOOMPANEL_100;(100%) +ZOOMPANEL_NEWCROPWINDOW;Öppna (nytt) detaljfönster. +ZOOMPANEL_ZOOM100;Förstora till 100%.\nKortkommando: z +ZOOMPANEL_ZOOMFITSCREEN;Passa till skärmen.\nKortkommando: f +ZOOMPANEL_ZOOMIN;Förstora.\nKortkommando: + +ZOOMPANEL_ZOOMOUT;Förminska.\nKortkommando: - + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!CURVEEDITOR_AXIS_IN;I: +!CURVEEDITOR_AXIS_LEFT_TAN;LT: +!CURVEEDITOR_AXIS_OUT;O: +!CURVEEDITOR_AXIS_RIGHT_TAN;RT: +!CURVEEDITOR_EDITPOINT_HINT;Enable edition of node in/out values.\n\nRight-click on a node to select it.\nRight-click on empty space to de-select the node. +!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. +!EXPORT_BYPASS_EQUALIZER;Bypass Wavelet Levels +!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_POPUPRANK0;Unrank +!FILEBROWSER_POPUPRANK1;Rank 1 * +!FILEBROWSER_POPUPRANK2;Rank 2 ** +!FILEBROWSER_POPUPRANK3;Rank 3 *** +!FILEBROWSER_POPUPRANK4;Rank 4 **** +!FILEBROWSER_POPUPRANK5;Rank 5 ***** +!FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!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_ASIMAGE;As Image +!HISTORY_MSG_256;NR - Median type +!HISTORY_MSG_257;Color Toning +!HISTORY_MSG_258;CT - Color curve +!HISTORY_MSG_259;CT - Opacity curve +!HISTORY_MSG_260;CT - a*[b*] opacity +!HISTORY_MSG_261;CT - Method +!HISTORY_MSG_262;CT - b* opacity +!HISTORY_MSG_263;CT - Shadows - Red +!HISTORY_MSG_264;CT - Shadows - Green +!HISTORY_MSG_265;CT - Shadows - Blue +!HISTORY_MSG_266;CT - Mid - Red +!HISTORY_MSG_267;CT - Mid - Green +!HISTORY_MSG_268;CT - Mid - Blue +!HISTORY_MSG_269;CT - High - Red +!HISTORY_MSG_270;CT - High - Green +!HISTORY_MSG_271;CT - High - Blue +!HISTORY_MSG_272;CT - Balance +!HISTORY_MSG_273;CT - Reset +!HISTORY_MSG_274;CT - Sat. Shadows +!HISTORY_MSG_275;CT - Sat. Highlights +!HISTORY_MSG_276;CT - Opacity +!HISTORY_MSG_277;--unused-- +!HISTORY_MSG_278;CT - Preserve luminance +!HISTORY_MSG_279;CT - Shadows +!HISTORY_MSG_280;CT - Highlights +!HISTORY_MSG_281;CT - Sat. strength +!HISTORY_MSG_282;CT - Sat. threshold +!HISTORY_MSG_283;CT - Strength +!HISTORY_MSG_284;CT - Auto sat. protection +!HISTORY_MSG_285;NR - Median - Method +!HISTORY_MSG_286;NR - Median - Type +!HISTORY_MSG_287;NR - Median - Iterations +!HISTORY_MSG_288;Flat Field - Clip control +!HISTORY_MSG_289;Flat Field - Clip control - Auto +!HISTORY_MSG_290;Black Level - Red +!HISTORY_MSG_291;Black Level - Green +!HISTORY_MSG_292;Black Level - Blue +!HISTORY_MSG_293;Film Simulation +!HISTORY_MSG_294;Film Simulation - Strength +!HISTORY_MSG_295;Film Simulation - Film +!HISTORY_MSG_296;NR - Luminance curve +!HISTORY_MSG_297;NR - Quality +!HISTORY_MSG_298;Dead pixel filter +!HISTORY_MSG_299;NR - Chrominance curve +!HISTORY_MSG_300;- +!HISTORY_MSG_301;NR - Luma control +!HISTORY_MSG_302;NR - Chroma method +!HISTORY_MSG_303;NR - Chroma method +!HISTORY_MSG_304;W - Contrast levels +!HISTORY_MSG_305;Wavelet Levels +!HISTORY_MSG_306;W - Preview +!HISTORY_MSG_307;W - Preview +!HISTORY_MSG_308;W - Preview direction +!HISTORY_MSG_309;W - ES - Detail +!HISTORY_MSG_310;W - Residual - Sky tar/prot +!HISTORY_MSG_311;W - Wavelet levels +!HISTORY_MSG_312;W - Residual - Shadows threshold +!HISTORY_MSG_313;W - Chroma - Sat/past +!HISTORY_MSG_314;W - Gamut - Reduce artifacts +!HISTORY_MSG_315;W - Residual - Contrast +!HISTORY_MSG_316;W - Gamut - Skin tar/prot +!HISTORY_MSG_317;W - Gamut - Skin hue +!HISTORY_MSG_318;W - Contrast - Highlight levels +!HISTORY_MSG_319;W - Contrast - Highlight range +!HISTORY_MSG_320;W - Contrast - Shadow range +!HISTORY_MSG_321;W - Contrast - Shadow levels +!HISTORY_MSG_322;W - Gamut - Avoid color shift +!HISTORY_MSG_323;W - ES - Local contrast +!HISTORY_MSG_324;W - Chroma - Pastel +!HISTORY_MSG_325;W - Chroma - Saturated +!HISTORY_MSG_326;W - Chroma - Method +!HISTORY_MSG_327;W - Contrast - Apply to +!HISTORY_MSG_328;W - Chroma - Link strength +!HISTORY_MSG_329;W - Toning - Opacity RG +!HISTORY_MSG_330;W - Toning - Opacity BY +!HISTORY_MSG_331;W - Contrast levels - Extra +!HISTORY_MSG_332;W - Tiling method +!HISTORY_MSG_333;W - Residual - Shadows +!HISTORY_MSG_334;W - Residual - Chroma +!HISTORY_MSG_335;W - Residual - Highlights +!HISTORY_MSG_336;W - Residual - Highlights threshold +!HISTORY_MSG_337;W - Residual - Sky hue +!HISTORY_MSG_338;W - ES - Radius +!HISTORY_MSG_339;W - ES - Strength +!HISTORY_MSG_340;W - Strength +!HISTORY_MSG_341;W - Edge performance +!HISTORY_MSG_342;W - ES - First level +!HISTORY_MSG_343;W - Chroma levels +!HISTORY_MSG_344;W - Meth chroma sl/cur +!HISTORY_MSG_345;W - ES - Local contrast +!HISTORY_MSG_346;W - ES - Local contrast method +!HISTORY_MSG_347;W - Denoise - Level 0 +!HISTORY_MSG_348;W - Denoise - Level 1 +!HISTORY_MSG_349;W - Denoise - Level 2 +!HISTORY_MSG_350;W - ES - Edge detection +!HISTORY_MSG_351;W - Residual - HH curve +!HISTORY_MSG_352;W - Background +!HISTORY_MSG_353;W - ES - Gradient sensitivity +!HISTORY_MSG_354;W - ES - Enhance +!HISTORY_MSG_355;W - ES - Threshold low +!HISTORY_MSG_356;W - ES - Threshold high +!HISTORY_MSG_357;W - Denoise - Link with ES +!HISTORY_MSG_358;W - Gamut - CH +!HISTORY_MSG_359;Hot/Dead - Threshold +!HISTORY_MSG_360;TM Gamma +!HISTORY_MSG_361;W - Final - Chroma balance +!HISTORY_MSG_362;W - Residual - Compression method +!HISTORY_MSG_363;W - Residual - Compression strength +!HISTORY_MSG_364;W - Final - Contrast balance +!HISTORY_MSG_365;W - Final - Delta balance +!HISTORY_MSG_366;W - Residual - Compression gamma +!HISTORY_MSG_367;W - ES - Local contrast curve +!HISTORY_MSG_368;W - Final - Contrast balance +!HISTORY_MSG_369;W - Final - Balance method +!HISTORY_MSG_370;W - Final - Local contrast curve +!MAIN_TAB_INSPECT; Inspect +!MAIN_TAB_WAVELET;Wavelet +!MAIN_TAB_WAVELET_TOOLTIP;Shortcut: Alt-w +!NAVIGATOR_B;B: +!NAVIGATOR_G;G: +!NAVIGATOR_H;H: +!NAVIGATOR_LAB_A;a*: +!NAVIGATOR_LAB_B;b*: +!NAVIGATOR_LAB_L;L*: +!NAVIGATOR_NA; -- +!NAVIGATOR_R;R: +!NAVIGATOR_S;S: +!NAVIGATOR_V;V: +!PARTIALPASTE_COLORTONING;Color Toning +!PARTIALPASTE_EQUALIZER;Wavelet Equalizer +!PARTIALPASTE_FILMSIMULATION;Film Simulation +!PARTIALPASTE_FLATFIELDCLIPCONTROL;Flat-field clip control +!PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter +!PARTIALPASTE_PREPROCESS_HOTPIXFILT;Hot pixel filter +!PARTIALPASTE_WAVELETGROUP;Wavelet processing +!PREFERENCES_AUTLISLOW;Low +!PREFERENCES_AUTLISMAX;Max - Average of all tiles +!PREFERENCES_AUTLISSTD;High +!PREFERENCES_AUTLISVLOW;None +!PREFERENCES_AUTLOW;Low +!PREFERENCES_AUTSTD;Standard +!PREFERENCES_CIEART_FRAME;CIECAM02-Specific Settings +!PREFERENCES_CLUTSCACHE;HaldCLUT Cache +!PREFERENCES_CLUTSCACHE_LABEL;Maximum number of cached CLUTs +!PREFERENCES_CLUTSDIR;HaldCLUT directory +!PREFERENCES_CURVEBBOXPOS;Position of curve copypasta buttons +!PREFERENCES_CURVEBBOXPOS_ABOVE;Above +!PREFERENCES_CURVEBBOXPOS_BELOW;Below +!PREFERENCES_CURVEBBOXPOS_LEFT;Left +!PREFERENCES_CURVEBBOXPOS_RIGHT;Right +!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_EXPAUT;Expert +!PREFERENCES_FILMSIMULATION;Film Simulation +!PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT;Same thumbnail height between the Editor's panel 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_GREYSC18;Yb=18 CIE L#50 +!PREFERENCES_GREYSCA;Automatic +!PREFERENCES_GREYSC;Scene Yb luminance (%) +!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_LEVAUTDN;Denoising level +!PREFERENCES_LEVDN;Cell size +!PREFERENCES_LISS;Auto multi-zone smoothing +!PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders +!PREFERENCES_MAX;Maxi (Tile) +!PREFERENCES_MED;Medium (Tile/2) +!PREFERENCES_MIN;Mini (100x115) +!PREFERENCES_NAVGUIDEBRUSH;Navigator guide color +!PREFERENCES_NAVIGATIONFRAME;Navigation +!PREFERENCES_NOISE;Noise Reduction +!PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP;Overlay filenames on thumbnails in the editor pannel +!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_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_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_SHOWFILMSTRIPTOOLBAR;Show filmstrip toolbar +!PREFERENCES_SIMPLAUT;Tool mode +!PREFERENCES_SMA;Small (250x287) +!PREFERENCES_STDAUT;Standard +!PREFERENCES_TIMAX;High +!PREFERENCES_TINB;Number of tiles +!PREFERENCES_TISTD;Standard +!PREFERENCES_WAVLEV;Increase wavelet level in quality 'high' +!PREFERENCES_WLONE;One level +!PREFERENCES_WLTWO;Two levels +!PREFERENCES_WLZER;No +!TP_COLORTONING_AB;o C/L +!TP_COLORTONING_AUTOSAT;Automatic +!TP_COLORTONING_BALANCE;Balance +!TP_COLORTONING_BY;o C/L +!TP_COLORTONING_CHROMAC;Opacity +!TP_COLORTONING_COLOR;Color +!TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;Chroma opacity as a function of luminance oC=f(L) +!TP_COLORTONING_HIGHLIGHT;Highlights +!TP_COLORTONING_HUE;Hue +!TP_COLORTONING_LABEL;Color Toning +!TP_COLORTONING_LAB;L*a*b* blending +!TP_COLORTONING_LUMAMODE;Preserve luminance +!TP_COLORTONING_LUMAMODE_TOOLTIP;If enabled, when you change color (red, green, cyan, blue, etc.) the luminance of each pixel is preserved. +!TP_COLORTONING_LUMA;Luminance +!TP_COLORTONING_METHOD;Method +!TP_COLORTONING_METHOD_TOOLTIP;"L*a*b* blending", "RGB sliders" and "RGB curves" use interpolated color blending.\n"Color balance (Shadows/Midtones/Highlights)" and "Saturation 2 colors" use direct colors.\n\nThe Black-and-White tool can be enabled when using any color toning method, which allows for color toning. +!TP_COLORTONING_MIDTONES;Midtones +!TP_COLORTONING_NEUTRAL;Reset sliders +!TP_COLORTONING_NEUTRAL_TIP;Reset all values (Shadows, Midtones, Highlights) to default. +!TP_COLORTONING_OPACITY;Opacity +!TP_COLORTONING_RGBCURVES;RGB - Curves +!TP_COLORTONING_RGBSLIDERS;RGB - Sliders +!TP_COLORTONING_SATURATEDOPACITY;Strength +!TP_COLORTONING_SATURATIONTHRESHOLD;Threshold +!TP_COLORTONING_SA;Saturation Protection +!TP_COLORTONING_SHADOWS;Shadows +!TP_COLORTONING_SPLITCOCO;Color Balance Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITCO;Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITLR;Saturation 2 colors +!TP_COLORTONING_STRENGTH;Strength +!TP_COLORTONING_STR;Strength +!TP_COLORTONING_TWO2;Special chroma '2 colors' +!TP_COLORTONING_TWOALL;Special chroma +!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_GTHARMMEANS;Harmonic Means +!TP_CROP_GTTRIANGLE1;Golden Triangles 1 +!TP_CROP_GTTRIANGLE2;Golden Triangles 2 +!TP_DIRPYRDENOISE_33;3×3 strong +!TP_DIRPYRDENOISE_55SOFT;5×5 +!TP_DIRPYRDENOISE_55;5×5 strong +!TP_DIRPYRDENOISE_77;7×7 (slow) +!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_ABM;Chroma only +!TP_DIRPYRDENOISE_AUTO;Automatic global +!TP_DIRPYRDENOISE_AUTO_TOOLTIP;Try to evaluate chroma noise\nBe careful, this calculation is average, and is quite subjective ! +!TP_DIRPYRDENOISE_AUT;Automatic global +!TP_DIRPYRDENOISE_C2TYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CCCURVE;Chrominance curve +!TP_DIRPYRDENOISE_CHROMAFR;Chrominance +!TP_DIRPYRDENOISE_CTYPE;Auto method +!TP_DIRPYRDENOISE_CTYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nAutomatic multi-zones\nNo preview - works only during saving, but using the "Preview" method by matching the tile size and center to the preview size and center you can get an idea of the expected results.\nThe image is divided into tiles (about 10 to 70 depending on image size) and each tile receives its own chrominance noise reduction settings.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CURVEEDITOR_CC;Chroma +!TP_DIRPYRDENOISE_CURVEEDITOR_CC_TOOLTIP;Increase (multiply) the value of all chrominance sliders.\nThis curve lets you adjust the strength of chromatic noise reduction as a function of chromaticity, for instance to increase the action in areas of low saturation and to decrease it in those of high saturation. +!TP_DIRPYRDENOISE_CURVEEDITOR_L_TOOLTIP;Modulates action of 'Luminance' denoise +!TP_DIRPYRDENOISE_CUR;Curve +!TP_DIRPYRDENOISE_LABM;L*a*b* +!TP_DIRPYRDENOISE_LCURVE;Luminance curve +!TP_DIRPYRDENOISE_LM;Luminance only +!TP_DIRPYRDENOISE_LPLABM;Weighted L* (little) + a*b* (normal) +!TP_DIRPYRDENOISE_LTYPE;Luminance control +!TP_DIRPYRDENOISE_LUMAFR;Luminance +!TP_DIRPYRDENOISE_LUMAFR_TOOLTIP;Wavelet on luminance and Fourier transform for luminance detail +!TP_DIRPYRDENOISE_MANU;Manual +!TP_DIRPYRDENOISE_MAN;Manual +!TP_DIRPYRDENOISE_MEDMETHOD;Median method +!TP_DIRPYRDENOISE_MEDTYPE;Median type +!TP_DIRPYRDENOISE_MED;Median Filter +!TP_DIRPYRDENOISE_MED_TOOLTIP;Enabled median denoising +!TP_DIRPYRDENOISE_METHOD11;Quality +!TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. +!TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - +!TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 +!TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. +!TP_DIRPYRDENOISE_PASSES;Median iterations +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PON;Auto multi-zones +!TP_DIRPYRDENOISE_PREVLABEL;Preview size=%1, Center: Px=%2 Py=%3 +!TP_DIRPYRDENOISE_PREV;Preview +!TP_DIRPYRDENOISE_PRE;Preview multi-zones +!TP_DIRPYRDENOISE_RGBM;RGB +!TP_DIRPYRDENOISE_SHALBI;High +!TP_DIRPYRDENOISE_SHAL;Standard +!TP_DIRPYRDENOISE_SLI;Slider +!TP_DIRPYRDENOISE_SOFT;3x3 +!TP_DIRPYRDENOISE_TILELABEL;Tile size=%1, Center: Tx=%2 Ty=%3 +!TP_DIRPYREQUALIZER_ARTIF;Reduce artifacts +!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_EPD_GAMMA;Gamma +!TP_EXPOSURE_TCMODE_LUMINANCE;Luminance +!TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points +!TP_EXPOS_WHITEPOINT_LABEL;Raw White Points +!TP_FILMSIMULATION_LABEL;Film Simulation +!TP_FILMSIMULATION_STRENGTH;Strength +!TP_FILMSIMULATION_ZEROCLUTSFOUND;Set HaldCLUT directory in Preferences +!TP_FLATFIELD_CLIPCONTROL;Clip control +!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. +!TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance +!TP_PREPROCESS_DEADPIXFILT;Dead pixel filter +!TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Tries to suppress dead pixels. +!TP_PREPROCESS_HOTPIXFILT;Hot pixel filter +!TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Tries to suppress hot pixels. +!TP_RAWEXPOS_BLACK_0;Green 1 (lead) +!TP_RAWEXPOS_BLACK_1;Red +!TP_RAWEXPOS_BLACK_2;Blue +!TP_RAWEXPOS_BLACK_3;Green 2 +!TP_RAWEXPOS_BLACK_BLUE;Blue +!TP_RAWEXPOS_BLACK_GREEN;Green +!TP_RAWEXPOS_BLACK_RED;Red +!TP_RAWEXPOS_RGB;Red, Green, Blue +!TP_RAW_HD;Threshold +!TP_RAW_HD_TOOLTIP;Lower values make hot/dead pixel detection more aggressive, but false positives may lead to artifacts. If you notice any artifacts appearing when enabling the Hot/Dead Pixel Filters, gradually increase the threshold value until they disappear. +!TP_RAW_SENSOR_BAYER_LABEL;Sensor with Bayer Matrix +!TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;3-pass gives best results (recommended for low ISO images).\n1-pass is almost undistinguishable from 3-pass for high ISO images and is faster. +!TP_RAW_SENSOR_XTRANS_LABEL;Sensor with X-Trans Matrix +!TP_WAVELET_1;Level 1 +!TP_WAVELET_2;Level 2 +!TP_WAVELET_3;Level 3 +!TP_WAVELET_4;Level 4 +!TP_WAVELET_5;Level 5 +!TP_WAVELET_6;Level 6 +!TP_WAVELET_7;Level 7 +!TP_WAVELET_8;Level 8 +!TP_WAVELET_9;Level 9 +!TP_WAVELET_ALL;All levels in all directions +!TP_WAVELET_APPLYTO;Apply To +!TP_WAVELET_AVOID;Avoid color shift +!TP_WAVELET_B0;Black +!TP_WAVELET_B1;Grey +!TP_WAVELET_B2;Residual +!TP_WAVELET_BACUR;Curve +!TP_WAVELET_BALANCE;Contrast balance d/v-h +!TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chromaticity or residual tone mapping are activated, the effect due to balance is amplified. +!TP_WAVELET_BALCHRO;Chroma balance +!TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chromaticity balance. +!TP_WAVELET_BANONE;None +!TP_WAVELET_BASLI;Slider +!TP_WAVELET_BATYPE;Contrast balance method +!TP_WAVELET_CCURVE;Local contrast +!TP_WAVELET_CH1;Whole chromaticity range +!TP_WAVELET_CH2;Saturated/pastel +!TP_WAVELET_CH3;Link contrast levels +!TP_WAVELET_CHCU;Curve +!TP_WAVELET_CHRO;Saturated/pastel threshold +!TP_WAVELET_CHRO_TOOLTIP;Sets the wavelet level which will be the threshold between saturated and pastel colors.\n1-x: saturated\nx-9: pastel\n\nIf the value exceeds the amount of wavelet levels you are using then it will be ignored. +!TP_WAVELET_CHR;Chroma-contrast link strength +!TP_WAVELET_CHR_TOOLTIP;Adjusts chromaticity as a function of "contrast levels" and "chroma-contrast link strength" +!TP_WAVELET_CHSL;Sliders +!TP_WAVELET_CHTYPE;Chrominance method +!TP_WAVELET_COLORT;Opacity Red-Green +!TP_WAVELET_COMBOTH;Both +!TP_WAVELET_COMPCONT;Contrast +!TP_WAVELET_COMPGAMMA;Compression gamma +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjusting the gamma of the residual image allow you to equilibrate the data and histogram. +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjust gamma for residual image and compression.\nAllow to equilibrate data and histogram +!TP_WAVELET_COMPTM;Tone mapping +!TP_WAVELET_CONTEDIT;'After' Contrast curve +!TP_WAVELET_CONTEDIT;'After' contrast curve +!TP_WAVELET_CONTRAST_MINUS;Contrast - +!TP_WAVELET_CONTRAST_PLUS;Contrast + +!TP_WAVELET_CONTRA;Contrast +!TP_WAVELET_CONTRA_TOOLTIP;Changes contrast of the residual image. +!TP_WAVELET_CONTR;Gamut +!TP_WAVELET_CTYPE;Chrominance control +!TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modifies local contrast as a function of the original local contrast (absciss)\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 100..300)\n66% absciss represents standard deviation of local contrast (real value about 300..800)\n100% represents maximum (real value about 3000..8000) +!TP_WAVELET_CURVEEDITOR_CH;Contrast levels=f(Hue) +!TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modifies each level's contrast as a function oh hue.\nTake care not to overwrite changes made with the Gamut Hue controls.\nThe curve will only have an effect when wavelet contrast level sliders are non-zero. +!TP_WAVELET_CURVEEDITOR_CL;L +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Applies a final contrast luminance curve at the end of the wavelet treatment. +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Apply a contrast luminance curve at the end of wavelet level threatment +!TP_WAVELET_CURVEEDITOR_HH;HH +!TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modifies the residual image's hue as a function of hue. +!TP_WAVELET_DALL;All directions +!TP_WAVELET_DAUB;Edge performance +!TP_WAVELET_DAUB_TOOLTIP;Changes Daubechies coefficients:\nD4 = Standard,\nD14 = Often best performance, 10% more time-intensive.\n\nAffects edge detection as well as the general quality of the firsts levels. However the quality is not strictly related to this coefficient and can vary with images and uses. +!TP_WAVELET_DISP;Preview Settings +!TP_WAVELET_DONE;Vertical +!TP_WAVELET_DTHR;Diagonal +!TP_WAVELET_DTWO;Horizontal +!TP_WAVELET_EDCU;Curve +!TP_WAVELET_EDGCONT;Local contrast +!TP_WAVELET_EDGCONT_TOOLTIP;Adjusting the points to the left decreases contrast, and to the right increases it.\nBottom-left, Top-Left, Top-Right, Bottom-right represent respectively local contast for low values, mean, mean+stdev, maxima +!TP_WAVELET_EDGEDETECTTHR2;Threshold high (detection) +!TP_WAVELET_EDGEDETECTTHR;Threshold low (noise) +!TP_WAVELET_EDGEDETECTTHR_TOOLTIP;This adjuster lets you target edge detection for example to avoid applying edge sharpness to fine details, such as noise in the sky. +!TP_WAVELET_EDGEDETECT;Gradient sensitivity +!TP_WAVELET_EDGEDETECT_TOOLTIP;Moving the slider to the right increases edge sensitivity. This affects local contrast, edge settings and noise. +!TP_WAVELET_EDGE;Edge Sharpness +!TP_WAVELET_EDGREINF_TOOLTIP;Reinforce or reduce the action of the first level, do the opposite to the second level, and leave the rest unchanged. +!TP_WAVELET_EDGTHRESH;Detail +!TP_WAVELET_EDGTHRESH_TOOLTIP;Change the repartition between the first levels and the others. The higher the threshold the more the action is centred on the first levels. Be careful with negative values, they increase the action of high levels and can introduce artifacts. +!TP_WAVELET_EDRAD;Radius +!TP_WAVELET_EDRAD_TOOLTIP;This radius adjustment is very different from those in other sharpening tools. Its value is compared to each level through a complex function. In this sense, a value of zero still has an effect. +!TP_WAVELET_EDSL;Threshold Sliders +!TP_WAVELET_EDTYPE;Local contrast method +!TP_WAVELET_EDVAL;Strength +!TP_WAVELET_FINAL;Final Touchup +!TP_WAVELET_FINEST;Finest +!TP_WAVELET_HIGHLIGHT;Highlight luminance range +!TP_WAVELET_HS1;Whole luminance range +!TP_WAVELET_HS2;Shadows/Highlights +!TP_WAVELET_HUESKIN;Skin hue +!TP_WAVELET_HUESKIN_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_HUESKY;Sky hue +!TP_WAVELET_HUESKY_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_INF;Below or equal the level +!TP_WAVELET_ITER;Delta balance levels +!TP_WAVELET_ITER_TOOLTIP;Left: increase low levels and reduce high levels,\nRight: reduce low levels and increase high levels. +!TP_WAVELET_LABEL;Wavelet levels +!TP_WAVELET_LARGEST;Coarsest +!TP_WAVELET_LEVCH;Chromaticity +!TP_WAVELET_LEVELS;Wavelet levels +!TP_WAVELET_LEVELS_TOOLTIP;Choose the number of detail levels the image is to be decomposed into. More levels require more RAM and require a longer processing time. +!TP_WAVELET_LEVF;Contrast +!TP_WAVELET_LEVLABEL;Preview maximum possible levels = %1 +!TP_WAVELET_LEVONE;Level 2 +!TP_WAVELET_LEVTWO;Level 3 +!TP_WAVELET_LEVZERO;Level 1 +!TP_WAVELET_LINKEDG;Link with Edge Sharpness' Strength +!TP_WAVELET_LIPST;Enhanced algorithm +!TP_WAVELET_LIPST_TOOLTIP;This algorithm uses Lipschitz regularity to increase edge detection quality at a cost of increased processing time and memory requirements. +!TP_WAVELET_LOWLIGHT;Shadow luminance range +!TP_WAVELET_MEDGREINF;First level +!TP_WAVELET_MEDILEV;Edge detection +!TP_WAVELET_MEDI;Reduce artifacts in blue sky +!TP_WAVELET_NEUTRAL;Neutral +!TP_WAVELET_NOISE;Denoise and Refine +!TP_WAVELET_NOIS;Denoise +!TP_WAVELET_ONE;One level +!TP_WAVELET_OPACITYWL;Final local contrast +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify final local contrast in function of last local contrast (absciss) for all levels decomposition\nTake into account: \na)contrast levels \nb)edge sharpness \nc)contrast balance\nd)decomposition-recomposition\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 200..1000)\n66% absciss represents standard deviation of local contrast (real value about 1000..2000)\n100% represents maximum (real value about 5000..13000) +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify the final local contrast at the end of the wavelet treatment.\n\nThe left side represents the smallest local contrast, progressing to the largest local contrast on the right. +!TP_WAVELET_OPACITYW;Contrast balance d/v-h curve +!TP_WAVELET_OPACITY;Opacity Blue-Yellow +!TP_WAVELET_PASTEL;Pastel chromaticity +!TP_WAVELET_PREVIEWBACK;Background +!TP_WAVELET_PREVIEWLEVELS;Preview +!TP_WAVELET_RE1;Reinforced +!TP_WAVELET_RE2;Unchanged +!TP_WAVELET_RE3;Reduced +!TP_WAVELET_RESCHRO;Chromaticity +!TP_WAVELET_RESCONH;Highlights +!TP_WAVELET_RESCON;Shadows +!TP_WAVELET_RESID;Residual image +!TP_WAVELET_SAT;Saturated chromaticity +!TP_WAVELET_SETTINGS;Wavelet Settings +!TP_WAVELET_SKIN;Skin targetting/protection +!TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected. +!TP_WAVELET_SKY;Sky targetting/protection +!TP_WAVELET_SKY_TOOLTIP;At -100 sky-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 sky-tones are protected while all other tones are affected. +!TP_WAVELET_STRENGTH;Strength +!TP_WAVELET_STREN;Strength +!TP_WAVELET_SUPE;Extra +!TP_WAVELET_SUP;Above the level +!TP_WAVELET_THRESHOLD2;Shadow levels +!TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels between 9 and 9 minus the value will be affected by the shadow luminance range. Other levels will be fully treated. The highest level possible is limited by the highlight level value (9 minus highlight level value). +!TP_WAVELET_THRESHOLD;Highlight levels +!TP_WAVELET_THRESHOLD_TOOLTIP;Only levels beyond the chosen value will be affected by the highlight luminance range. Other levels will be fully treated. The chosen value here limits the highest possible value of the shadow levels. +!TP_WAVELET_THRH;Highlights threshold +!TP_WAVELET_THR;Shadows threshold +!TP_WAVELET_TILESBIG;Big tiles +!TP_WAVELET_TILESFULL;Full image +!TP_WAVELET_TILESIZE;Tiling method +!TP_WAVELET_TILESLIT;Little tiles +!TP_WAVELET_TILES_TOOLTIP;Processing the full image leads to better quality and is the recommended option, while using tiles is a fall-back solution for users with little RAM. Refer to RawPedia for memory requirements. +!TP_WAVELET_TMHIGH;High +!TP_WAVELET_TMLOWHIGH;Low+High +!TP_WAVELET_TMNONE;None +!TP_WAVELET_TMSTD;Standard +!TP_WAVELET_TMSTRENGTH;Compression strength +!TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image. When the value is different from 0, the Strength and Gamma sliders of the Tone Mapping tool in the Exposure tab will become grayed out. +!TP_WAVELET_TMTYPE;Compression method +!TP_WAVELET_TON;Toning +!TP_WAVELET_daub2;D2 - low +!TP_WAVELET_daub4;D4 - standard +!TP_WAVELET_daub6;D6 - standard plus +!TP_WAVELET_daub10;D10 - medium +!TP_WAVELET_daub14;D14 - high +!ZOOMPANEL_ZOOMFITCROPSCREEN;Fit crop to screen\nShortcut: Alt-f diff --git a/rtdata/languages/Turkish b/rtdata/languages/Turkish new file mode 100644 index 000000000..0a7086a3e --- /dev/null +++ b/rtdata/languages/Turkish @@ -0,0 +1,1856 @@ +#01 2008-03-02 Oguz + +ADJUSTER_RESET_TO_DEFAULT;Varsayılana dön +CURVEEDITOR_LINEAR;Doğrusal +CURVEEDITOR_LOADDLGLABEL;Eğriyi yükle... +CURVEEDITOR_SAVEDLGLABEL;Eğriyi kaydet... +CURVEEDITOR_TOOLTIPLINEAR;Eğriyi düzelt +CURVEEDITOR_TOOLTIPLOAD;Kayıtlı bir eğriyi yü +CURVEEDITOR_TOOLTIPSAVE;Kullanılan eğriyi kaydet +DIRBROWSER_FOLDERS;Klasörler +EXIFFILTER_APERTURE;Aperture +EXIFFILTER_CAMERA;Camera +EXIFFILTER_FOCALLEN;Focal Length +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Lens +EXIFFILTER_SHUTTER;Shutter +EXIFPANEL_ADDEDITHINT;Add new tag or edit tag +EXIFPANEL_ADDEDIT;Add/Edit +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Enter value +EXIFPANEL_ADDTAGDLG_SELECTTAG;Select tag +EXIFPANEL_ADDTAGDLG_TITLE;Add/Edit Tag +EXIFPANEL_KEEPHINT;Keep the selected tags when writing output file +EXIFPANEL_KEEP;Keep +EXIFPANEL_REMOVEHINT;Remove the selected tags when writing output file +EXIFPANEL_REMOVE;Remove +EXIFPANEL_RESETALLHINT;Reset all tags to their original values +EXIFPANEL_RESETALL;Reset All +EXIFPANEL_RESETHINT;Reset the selected tags to their original values +EXIFPANEL_RESET;Reset +EXIFPANEL_SUBDIRECTORY;Subdirectory +FILEBROWSER_APPLYPROFILE;Apply profile +FILEBROWSER_CLEARPROFILE;Clear profile +FILEBROWSER_COPYPROFILE;Copy profile +FILEBROWSER_DELETEDLGLABEL;File delete confirmation +FILEBROWSER_DELETEDLGMSG;Are you sure you want to delete the selected %1 files? +FILEBROWSER_EMPTYTRASHHINT;Permanently delete the files of the trash +FILEBROWSER_EMPTYTRASH;Empty Trash +FILEBROWSER_PARTIALPASTEPROFILE;Partial paste +FILEBROWSER_PASTEPROFILE;Paste profile +FILEBROWSER_POPUPCANCELJOB;Cancel job +FILEBROWSER_POPUPMOVEEND;Move to end of queue +FILEBROWSER_POPUPMOVEHEAD;Move to head of queue +FILEBROWSER_POPUPOPENINEDITOR;Open in Editor +FILEBROWSER_POPUPOPEN;Open +FILEBROWSER_POPUPPROCESS;Put to processing queue +FILEBROWSER_POPUPREMOVE;Remove from filesystem +FILEBROWSER_POPUPRENAME;Rename +FILEBROWSER_POPUPSELECTALL;Select all +FILEBROWSER_POPUPTRASH;Move to trash +FILEBROWSER_POPUPUNRANK;Unrank +FILEBROWSER_POPUPUNTRASH;Remove from trash +FILEBROWSER_RENAMEDLGLABEL;Rename file +FILEBROWSER_RENAMEDLGMSG;Rename file "%1" to: +FILEBROWSER_SHOWDIRHINT;Show all images of the directory +FILEBROWSER_SHOWRANK1HINT;Show images ranked as 1 star +FILEBROWSER_SHOWRANK2HINT;Show images ranked as 2 star +FILEBROWSER_SHOWRANK3HINT;Show images ranked as 3 star +FILEBROWSER_SHOWRANK4HINT;Show images ranked as 4 star +FILEBROWSER_SHOWRANK5HINT;Show images ranked as 5 star +FILEBROWSER_SHOWTRASHHINT;Show content of the trash +FILEBROWSER_SHOWUNRANKHINT;Show unranked images +FILEBROWSER_STARTPROCESSINGHINT;Start processing/saving of images in the queue +FILEBROWSER_STARTPROCESSING;Start Processing +FILEBROWSER_STOPPROCESSINGHINT;Stop processing of images +FILEBROWSER_STOPPROCESSING;Stop processing +FILEBROWSER_THUMBSIZE;Thumb. size +FILEBROWSER_ZOOMINHINT;Increase thumbnail size +FILEBROWSER_ZOOMOUTHINT;Decrease thumbnail size +GENERAL_ABOUT;Hakkında +GENERAL_CANCEL;İptal +GENERAL_DISABLED;Devre dışı +GENERAL_DISABLE;Etkisizleştir +GENERAL_ENABLED;Etkin +GENERAL_ENABLE;Etkinleştir +GENERAL_LANDSCAPE;Yatay +GENERAL_NA;Uygun değil +GENERAL_NO;Hayır +GENERAL_OK;Tamam +GENERAL_PORTRAIT;Dikey +GENERAL_SAVE;Kaydet +HISTOGRAM_TOOLTIP_B;Mavi histogramını göster/gizle +HISTOGRAM_TOOLTIP_G;Yeşil histogramını göster/gizle +HISTOGRAM_TOOLTIP_L;CIELAB aydınlık histogramını göster/gizle +HISTOGRAM_TOOLTIP_R;Kırmızı histogramını göster/gizle +HISTORY_CHANGED;Changed +HISTORY_CUSTOMCURVE;Özel eğri +HISTORY_DELSNAPSHOT;Şipşağı sil +HISTORY_FROMCLIPBOARD;From clipboard +HISTORY_LABEL;Geçmiş +HISTORY_MSG_1;Fotoğraf yüklendi +HISTORY_MSG_2;Profil yüklendi +HISTORY_MSG_3;Profil değişti +HISTORY_MSG_4;Geçmişte gezinti +HISTORY_MSG_5;Parlaklık +HISTORY_MSG_6;Zıtlık +HISTORY_MSG_7;Siyah +HISTORY_MSG_8;Pozlama telafisi +HISTORY_MSG_9;Parıltı sıkıştırma +HISTORY_MSG_10;Karaltı sıkıştırma +HISTORY_MSG_11;Ton eğrisi +HISTORY_MSG_12;Otomatik pozlama +HISTORY_MSG_13;Pozlama kırpma +HISTORY_MSG_14;Aydınlık - parlaklık +HISTORY_MSG_15;Aydınlık - zıtlık +HISTORY_MSG_16;Aydınlık - siyah +HISTORY_MSG_17;Aydınlık - parıltı sıkıştırma +HISTORY_MSG_18;Aydınlık - karaltı sıkıştırma +HISTORY_MSG_19;Aydınlık eğrisi +HISTORY_MSG_20;Keskinleştirme +HISTORY_MSG_21;Keskinleştirme - çap +HISTORY_MSG_22;Keskinleştirme - miktar +HISTORY_MSG_23;Keskinleştirme - eşik +HISTORY_MSG_24;Sadece kenarları keskinleştir +HISTORY_MSG_25;Keskinleştirme - kenar bulma kuralları +HISTORY_MSG_26;Keskinleştirme - kenar payı +HISTORY_MSG_27;Keskinleştirme - hale denetimi +HISTORY_MSG_28;Hale denetimi - miktar +HISTORY_MSG_29;Keskinleştirme - yöntem +HISTORY_MSG_30;Ters evrişim - çap +HISTORY_MSG_31;Ters evrişim - miktar +HISTORY_MSG_32;Ters evrişim - düşürme +HISTORY_MSG_33;Ters evrişim - yineleme +HISTORY_MSG_34;Renk kırpmayı önle +HISTORY_MSG_35;Doygunluk kısıtlayıcı +HISTORY_MSG_36;Doygunluk sınırı +HISTORY_MSG_37;Renk iteleme +HISTORY_MSG_38;Beyaz ayarı - yöntem +HISTORY_MSG_39;Renk ısısı +HISTORY_MSG_40;Beyaz ayarı - tint +HISTORY_MSG_41;"A" renk kayması +HISTORY_MSG_42;"B" kayması +HISTORY_MSG_43;Aydınlık gürültü giderme +HISTORY_MSG_44;Aydınlık gürültü giderme - çap +HISTORY_MSG_45;Aydınlık gürültü giderme - kenar payı +HISTORY_MSG_46;Renk gürültü giderme +HISTORY_MSG_47;Renk gürültü giderme - çap +HISTORY_MSG_48;Renk gürültü giderme - kenar payı +HISTORY_MSG_49;Kenar duyarlı renk gürültüsü giderme +HISTORY_MSG_50;Karaltı/parıltı aracı +HISTORY_MSG_51;Parıltı iteleme +HISTORY_MSG_52;Karaltı iteleme +HISTORY_MSG_53;Parıltı - ton genişliği +HISTORY_MSG_54;Karaltı - ton genişliği +HISTORY_MSG_55;Bölgesel zıtlık +HISTORY_MSG_56;Karaltı/parıltı - zıtlık +HISTORY_MSG_57;Döndürme +HISTORY_MSG_58;Yatayda çevirme +HISTORY_MSG_59;Dikeyde çevirme +HISTORY_MSG_60;Döndürme +HISTORY_MSG_61;Döndürme +HISTORY_MSG_62;Lens bükülmesi düzeltme +HISTORY_MSG_63;Yer imi seçildi +HISTORY_MSG_64;Fotoğrafı kırp +HISTORY_MSG_65;Renk kayması düzeltme +HISTORY_MSG_66;Parıltı kurtarma +HISTORY_MSG_67;Parıltı kurtarma - miktar +HISTORY_MSG_68;Parıltı kurtarma - yöntem +HISTORY_MSG_69;Çalışma renk uzayı +HISTORY_MSG_70;Çıktı renk uzayı +HISTORY_MSG_71;Girdi renk uzayı +HISTORY_MSG_72;Çerçeve etkisi düzeltme +HISTORY_MSG_73;Kanal karıştırıcı +HISTORY_MSG_74;Yeniden boyutlandırma - ölçek +HISTORY_MSG_75;Yeniden boyutlandırma - yöntem +HISTORY_MSG_76;Exif Metadata +HISTORY_MSG_77;IPTC Metadata +HISTORY_MSG_78;Data specified for resize +HISTORY_MSG_79;Resize width +HISTORY_MSG_80;Resize height +HISTORY_MSG_81;Resize enabled +HISTORY_NEWSNAPSHOT;Yeni şipşak +HISTORY_SNAPSHOTS;Şipşaklar +HISTORY_SNAPSHOT;Şipşak +IPTCPANEL_AUTHORSPOSITIONHINT;Title of the creator or creators of the object (By-line Title). +IPTCPANEL_AUTHORSPOSITION;Author's position +IPTCPANEL_AUTHOR;Author +IPTCPANEL_CAPTIONHINT;A textual description of the data (Caption - Abstract). +IPTCPANEL_CAPTIONWRITERHINT;The name of the person involved in the writing, editing or correcting the image or caption/abstract (Writer - Editor). +IPTCPANEL_CAPTIONWRITER;Caption Writer +IPTCPANEL_CAPTION;Caption +IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider (Category). +IPTCPANEL_CATEGORY;Category +IPTCPANEL_CITYHINT;City of image origin (City). +IPTCPANEL_CITY;City +IPTCPANEL_COPYHINT;Copy IPTC settings to clipboard +IPTCPANEL_COPYRIGHTHINT;Any necessary copyright notice (Copyright Notice). +IPTCPANEL_COPYRIGHT;Copyright +IPTCPANEL_COUNTRYHINT;The name of the country/primary location where the image was created (Country - Primary Location Name). +IPTCPANEL_COUNTRY;Country +IPTCPANEL_CREDITHINT;Identifies the provider of the image, not necessarily the owner/creator (Credit). +IPTCPANEL_CREDIT;Credit +IPTCPANEL_DATECREATEDHINT;The date the intellectual content of the image was created; Format: JJJJMMTT (Date Created). +IPTCPANEL_DATECREATED;Date Created +IPTCPANEL_EMBEDDEDHINT;Reset to IPTC data embedded in the image file +IPTCPANEL_EMBEDDED;Embedded +IPTCPANEL_HEADLINEHINT;A publishable entry providing a synopsis of the contents of the image (Headline). +IPTCPANEL_HEADLINE;Headline +IPTCPANEL_INSTRUCTIONSHINT;Other editorial instructions concerning the use of the image (Special Instructions). +IPTCPANEL_INSTRUCTIONS;Instructions +IPTCPANEL_KEYWORDSHINT;Used to indicate specific information retrieval words (Keywords). +IPTCPANEL_KEYWORDS;Keywords +IPTCPANEL_PASTEHINT;Paste IPTC settings from clipboard +IPTCPANEL_PROVINCEHINT;The Province/State where the image originates (Province-State). +IPTCPANEL_PROVINCE;Province +IPTCPANEL_RESETHINT;Reset to profile default +IPTCPANEL_RESET;Reset +IPTCPANEL_SOURCEHINT;The original owner of the intellectual content of the image (Source). +IPTCPANEL_SOURCE;Source +IPTCPANEL_SUPPCATEGORIESHINT;Further refines the subject of the image (Supplemental Categories). +IPTCPANEL_SUPPCATEGORIES;Suppl. Categories +IPTCPANEL_TITLEHINT;A shorthand reference for the image (Object Name). +IPTCPANEL_TITLE;Title +IPTCPANEL_TRANSREFERENCEHINT;A code representing the location of original transmission (Original Transmission Reference). +IPTCPANEL_TRANSREFERENCE;Trans. Reference +MAIN_BUTTON_PREFERENCES;Seçenekler +MAIN_BUTTON_SAVE;Görüntüyü kaydet +MAIN_BUTTON_SENDTOEDITOR;Send to editor +MAIN_FRAME_BATCHQUEUE;Batch Queue +MAIN_FRAME_FILEBROWSER;File Browser +MAIN_FRAME_PLACES;Places +MAIN_FRAME_PLACES_ADD;Add +MAIN_FRAME_PLACES_DEL;Del +MAIN_FRAME_RECENT;Recent Folders +MAIN_MSG_ALREADYEXISTS;Dosya zaten var. +MAIN_MSG_CANNOTLOAD;Görüntü yüklenemiyor +MAIN_MSG_CANNOTSAVE;Dosya kaydetmede hata +MAIN_MSG_CANNOTSTARTEDITOR;Can not start editor. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Please set the correct path in the "Preferences" dialog. +MAIN_MSG_QOVERWRITE;Üzerine yazmak ister misiniz? +MAIN_TAB_COLOR;Color +MAIN_TAB_DETAIL;Detail +MAIN_TAB_DEVELOP;Develop +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPOSURE;Exposure +MAIN_TAB_FILTER;Filter +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadata +MAIN_TAB_TRANSFORM;Dönüşüm +MAIN_TOOLTIP_HIDEHP;Sol tablayı göster/gizle (geçmiş ile birlikte, shortcut key: H) +MAIN_TOOLTIP_INDCLIPPEDH;Kırpılmış parıltı gösterme +MAIN_TOOLTIP_INDCLIPPEDS;Kırpılmış karaltı gösterme +MAIN_TOOLTIP_QINFO;Görüntü hakkında kısa bilgi +PARTIALPASTE_BASICGROUP;Basic settings +PARTIALPASTE_CACORRECTION;C/A correction +PARTIALPASTE_COARSETRANS;90 deg rotation / flipping +PARTIALPASTE_COLORGROUP;Color related settings +PARTIALPASTE_COMPOSITIONGROUP;Composition settings +PARTIALPASTE_CROP;Crop +PARTIALPASTE_DIALOGLABEL;Partial paste processing profile +PARTIALPASTE_DISTORTION;Distortion correction +PARTIALPASTE_EXIFCHANGES;Changes to exif data +PARTIALPASTE_EXPOSURE;Exposure +PARTIALPASTE_ICMSETTINGS;ICM settings +PARTIALPASTE_IPTCINFO;IPTC info +PARTIALPASTE_LENSGROUP;Lens related settings +PARTIALPASTE_METAGROUP;Metadata +PARTIALPASTE_RESIZE;Resize +PARTIALPASTE_ROTATION;Rotation +PARTIALPASTE_SHADOWSHIGHLIGHTS;Shadows/Highlights +PARTIALPASTE_SHARPENING;Sharpening +PARTIALPASTE_VIGNETTING;Vignetting correction +PARTIALPASTE_WHITEBALANCE;White balance +PREFERENCES_APPLNEXTSTARTUP;Bir sonraki başlamada uygulacacak. +PREFERENCES_CACHECLEARALL;Clear All +PREFERENCES_CACHECLEARPROFILES;Clear Profiles +PREFERENCES_CACHECLEARTHUMBS;Clear Thumbnails +PREFERENCES_CACHEMAXENTRIES;Maximal Number of Cache Entries +PREFERENCES_CACHEOPTS;Cache Options +PREFERENCES_CACHETHUMBHEIGHT;Maximal Thumbnail Height +PREFERENCES_CLIPPINGIND;Kırpma gösterme +PREFERENCES_CMETRICINTENT;Renkölçer +PREFERENCES_DATEFORMATHINT;You can use the following formatting strings:\n%y : year\n%m : month\n%d : day\n\nFor example, the hungarian date format is:\n%y/%m/%d +PREFERENCES_DATEFORMAT;Tarih biçimi +PREFERENCES_DEFAULTLANG;Varsayılan dil +PREFERENCES_DEFAULTTHEME;Default theme +PREFERENCES_DIRHOME;Kullanıcı dizini +PREFERENCES_DIRLAST;Son gidilen dizin +PREFERENCES_DIROTHER;Diğer +PREFERENCES_DIRSELECTDLG;Başlangıç görüntü dizinini seç... +PREFERENCES_DIRSOFTWARE;Kurulum dizini +PREFERENCES_EDITORCMDLINE;Other command line +PREFERENCES_EXTERNALEDITOR;External editor +PREFERENCES_FBROWSEROPTS;Dosya gezgini seçenekleri +PREFERENCES_FILEFORMAT;Dosya biçimi +PREFERENCES_FORIMAGE;Gürüntü dosyaları için +PREFERENCES_FORRAW;RAW dosyaları için +PREFERENCES_GIMPPATH;GIMP installation directory +PREFERENCES_HLTHRESHOLD;Kırpılmış parıltılar için eşik +PREFERENCES_ICCDIR;ICC profilleri dizini +PREFERENCES_IMPROCPARAMS;Varsayılan görüntü işleme değişkenleri +PREFERENCES_INTENT_ABSOLUTE;Mutlak +PREFERENCES_INTENT_PERCEPTUAL;Algısal +PREFERENCES_INTENT_RELATIVE;Bağıl +PREFERENCES_INTENT_SATURATION;Doyum +PREFERENCES_MONITORICC;Ekran profili +PREFERENCES_OUTDIRFOLDERHINT;Put the saved images to the seledted folder +PREFERENCES_OUTDIRFOLDER;Save to folder +PREFERENCES_OUTDIRTEMPLATEHINT;You can use the following formatting strings:\n%f, %d1, %d2, ..., %p1, %p2, ...\n\nThese formatting strings refer to the directories and sub-paths of the path of the raw file.\n\nFor example, if /home/tom/image/02-09-2006/dsc0012.nefhas been opened, the meaning of the formatting strings are:\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\nIf you want to save the output image where the original is, write:\n%p1/%f\n\nIf you want to save the output image in a directory 'converted' located the directory of the original, write:\n%p1/converted/%f\n\nIf you want to save the output image in directory '/home/tom/converted' with keeping the same subdirectory of dates, write:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Use Template +PREFERENCES_OUTDIR;Çıktı dizini +PREFERENCES_PARSEDEXTADDHINT;Type an extension and press this button to append list +PREFERENCES_PARSEDEXTADD;Add Extension +PREFERENCES_PARSEDEXTDELHINT;Delete selected extension from the list +PREFERENCES_PARSEDEXT;Parsed Extensions +PREFERENCES_PROFILEHANDLING;Processing Profile Handling +PREFERENCES_PROFILELOADPR;Profile Loading Priority +PREFERENCES_PROFILEPRCACHE;Profile in Cache +PREFERENCES_PROFILEPRFILE;Profile Next to the Input File +PREFERENCES_PROFILESAVECACHE;Save Processing Parameters to the Cache +PREFERENCES_PROFILESAVEINPUT;Save Processing Parameters Next to the Input File +PREFERENCES_PSPATH;Adobe Photoshop installation directory +PREFERENCES_SELECTLANG;Dil seç +PREFERENCES_SELECTTHEME;Select theme +PREFERENCES_SHOWBASICEXIF;Temel exif bilgisini göster +PREFERENCES_SHOWDATETIME;Tarih ve saati göster +PREFERENCES_SHTHRESHOLD;Kırpılmış karaltılar için eşik +PREFERENCES_STARTUPIMDIR;Başlangıç görüntü dizini +PREFERENCES_TAB_BROWSER;Dosya gezgini +PREFERENCES_TAB_COLORMGR;Renk yönetimi +PREFERENCES_TAB_GENERAL;Genel +PREFERENCES_TAB_IMPROC;Görüntü işleme +PROFILEPANEL_LABEL;Art-işleme profilleri +PROFILEPANEL_LOADDLGLABEL;Art-işleme değişkenlerini yükle... +PROFILEPANEL_PCUSTOM;Özel +PROFILEPANEL_PFILE;Dosyadan +PROFILEPANEL_PLASTSAVED;Son kaydedilen +PROFILEPANEL_SAVEDLGLABEL;Art-işleme değişkenlerini kaydet... +PROFILEPANEL_TOOLTIPCOPY;Copy current profile to clipboard +PROFILEPANEL_TOOLTIPLOAD;Kayıtlı bir profil yükle +PROFILEPANEL_TOOLTIPPASTE; Paste profile from clipboard +PROFILEPANEL_TOOLTIPSAVE;Geçerli profili kaydet +PROGRESSBAR_LOADING;Görüntü yükleniyor... +PROGRESSBAR_LOADJPEG;JPEG dosyası yükleniyor... +PROGRESSBAR_LOADPNG;PNG dosyası yükleniyor... +PROGRESSBAR_LOADTIFF;TIFF dosyası yükleniyor... +PROGRESSBAR_PROCESSING;Görüntü işleniyor... +PROGRESSBAR_READY;Hazır +PROGRESSBAR_SAVEJPEG;JPEG dosyası kaydediliyor... +PROGRESSBAR_SAVEPNG;PNG dosyası kaydediliyor... +PROGRESSBAR_SAVETIFF;TIFF dosyası kaydediliyor... +QINFO_ISO;ISO +QINFO_NOEXIF;Exif bilgisi yok. +SAVEDLG_FILEFORMAT;Dosya biçimi +SAVEDLG_JPEGQUAL;JPEG kalitesi +SAVEDLG_PNGCOMPR;PNG sıkıştırma düzeyi +SAVEDLG_PUTTOQUEUEHEAD;Put to the head of the processing queue +SAVEDLG_PUTTOQUEUETAIL;Put to the end of the processing queue +SAVEDLG_PUTTOQUEUE;Put into processing queue +SAVEDLG_SAVEIMMEDIATELY;Save immediately +SAVEDLG_SAVESPP;İşeme değişkenlerini görüntü ile birlikte kaydet +SAVEDLG_TIFFUNCOMPRESSED;Uncompressed TIFF +TOOLBAR_TOOLTIP_CROP;Seçimi kırp (shorcut key: C) +TOOLBAR_TOOLTIP_HAND;El aracı (shortcut key: N) +TOOLBAR_TOOLTIP_STRAIGHTEN;Düz çizgi seçimi (shortcut key: S) +TOOLBAR_TOOLTIP_WB;Nokta beyaz ayarı (shortcut key: W) +TP_CACORRECTION_BLUE;Mavi +TP_CACORRECTION_LABEL;Renk sapması düzeltme +TP_CACORRECTION_RED;Kırmızı +TP_CHMIXER_BLUE;Mavi +TP_CHMIXER_GREEN;Yeşil +TP_CHMIXER_LABEL;Kanal karıştırıcı +TP_CHMIXER_RED;Kırmızı +TP_COARSETRAF_TOOLTIP_HFLIP;Yatayda çevir +TP_COARSETRAF_TOOLTIP_ROTLEFT;Sola döndür +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Sağa döndür +TP_COARSETRAF_TOOLTIP_VFLIP;Dikeyde çevir +TP_CROP_FIXRATIO;En-boy oranını düzelt: +TP_CROP_GTDIAGONALS;Çaprazlar kuralı +TP_CROP_GTNONE;Yok +TP_CROP_GTRULETHIRDS;Üçler kuralı +TP_CROP_GUIDETYPE;Kılavuz türü: +TP_CROP_H;Y +TP_CROP_LABEL;Kırp +TP_CROP_SELECTCROP; Kırpma alanı seç +TP_CROP_W;G +TP_CROP_X;x +TP_CROP_Y;y +TP_DISTORTION_AMOUNT;Miktar +TP_DISTORTION_LABEL;Bükme +TP_EXPOSURE_AUTOLEVELS;Otomatik seviyeler +TP_EXPOSURE_BLACKLEVEL;Siyah +TP_EXPOSURE_BRIGHTNESS;Parlaklık +TP_EXPOSURE_CLIP;Kırpma +TP_EXPOSURE_COMPRHIGHLIGHTS;Parıltı sıkıştırma +TP_EXPOSURE_COMPRSHADOWS;Karaltı sıkıştırma +TP_EXPOSURE_CONTRAST;Zıtlık +TP_EXPOSURE_CURVEEDITOR;Ton eğrisi +TP_EXPOSURE_EXPCOMP;Poz. telafisi +TP_EXPOSURE_LABEL;Pozlama +TP_HLREC_CIELAB;CIELab Blending +TP_HLREC_COLOR;Renk yayılımı +TP_HLREC_LABEL;Parıltı kurtarma +TP_HLREC_LUMINANCE;Aydınlık kurtarma +TP_HLREC_METHOD;Yöntem: +TP_ICM_INPUTCAMERA;Kamera varsayılanı +TP_ICM_INPUTCUSTOM;Özel +TP_ICM_INPUTDLGLABEL;Girdi ICC profilini seç... +TP_ICM_INPUTEMBEDDED;Mümkün olduğunda gömülü profili kullan +TP_ICM_INPUTPROFILE;Girdi Profili +TP_ICM_LABEL;ICM +TP_ICM_NOICM;No ICM: sRGB çıktı +TP_ICM_OUTPUTPROFILE;Çıktı profili +TP_ICM_SAVEREFERENCE;Save reference image for profiling +TP_ICM_WORKINGPROFILE;Çalışma profili +TP_RAW_DMETHOD;Yöntem +TP_RAW_FALSECOLOR;Hatalı-renk bastırma değerleri +TP_RESIZE_H;Y: +TP_RESIZE_LABEL;Boyutları değiştir +TP_RESIZE_METHOD;Yöntem: +TP_RESIZE_NEAREST;En yakın +TP_RESIZE_SCALE;Ölçekle +TP_RESIZE_W;G: +TP_ROTATE_DEGREE;Açı +TP_ROTATE_LABEL;Döndür +TP_ROTATE_SELECTLINE; Düz çizgi seç +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Parıltılar +TP_SHADOWSHLIGHTS_HLTONALW;Tonsal genişlik +TP_SHADOWSHLIGHTS_LABEL;Karaltılar/parıltılar +TP_SHADOWSHLIGHTS_LOCALCONTR;Bölgesel zıtlık +TP_SHADOWSHLIGHTS_RADIUS;Çap +TP_SHADOWSHLIGHTS_SHADOWS;Karaltılar +TP_SHADOWSHLIGHTS_SHTONALW;Tonsal genişlik +TP_SHARPENING_AMOUNT;Miktar +TP_SHARPENING_EDRADIUS;Çap +TP_SHARPENING_EDTOLERANCE;Kenar payı +TP_SHARPENING_HALOCONTROL;Hale denetimi +TP_SHARPENING_HCAMOUNT;Miktar +TP_SHARPENING_LABEL;Keskinleştirme +TP_SHARPENING_METHOD;Yöntem +TP_SHARPENING_ONLYEDGES;Sadece kenarları keskinleştir +TP_SHARPENING_RADIUS;Çap +TP_SHARPENING_RLD;R-L Ters evrişimi +TP_SHARPENING_RLD_AMOUNT;Miktar +TP_SHARPENING_RLD_DAMPING;Düşürme +TP_SHARPENING_RLD_ITERATIONS;Yineleme +TP_SHARPENING_THRESHOLD;Eşik +TP_SHARPENING_USM;Bulanıklık Maskesi +TP_VIGNETTING_AMOUNT;Miktar +TP_VIGNETTING_LABEL;Çerçeve etkisi giderme +TP_VIGNETTING_RADIUS;Çap +TP_WBALANCE_AUTO;Otomatik +TP_WBALANCE_CAMERA;Kamera +TP_WBALANCE_CUSTOM;Özel +TP_WBALANCE_GREEN;Tint +TP_WBALANCE_LABEL;Beyaz ayarı +TP_WBALANCE_METHOD;Yöntem +TP_WBALANCE_SIZE;Boyut: +TP_WBALANCE_SPOTWB;Spot BA +TP_WBALANCE_TEMPERATURE;Isı + +!!!!!!!!!!!!!!!!!!!!!!!!! +! Untranslated keys follow; remove the ! prefix after an entry is translated. +!!!!!!!!!!!!!!!!!!!!!!!!! + +!ABOUT_TAB_BUILD;Version +!ABOUT_TAB_CREDITS;Credits +!ABOUT_TAB_LICENSE;License +!ABOUT_TAB_RELEASENOTES;Release Notes +!ABOUT_TAB_SPLASH;Splash +!BATCHQUEUE_AUTOSTART;Auto-start +!BATCHQUEUE_DESTFILENAME;Path and file name +!BATCH_PROCESSING;Batch Processing +!CURVEEDITOR_AXIS_IN;I: +!CURVEEDITOR_AXIS_LEFT_TAN;LT: +!CURVEEDITOR_AXIS_OUT;O: +!CURVEEDITOR_AXIS_RIGHT_TAN;RT: +!CURVEEDITOR_CURVES;Curves +!CURVEEDITOR_CURVE;Curve +!CURVEEDITOR_CUSTOM;Custom +!CURVEEDITOR_DARKS;Darks +!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_HIGHLIGHTS;Highlights +!CURVEEDITOR_LIGHTS;Lights +!CURVEEDITOR_MINMAXCPOINTS;Equalizer +!CURVEEDITOR_NURBS;Control cage +!CURVEEDITOR_PARAMETRIC;Parametric +!CURVEEDITOR_SHADOWS;Shadows +!CURVEEDITOR_TOOLTIPCOPY;Copy current curve to clipboard. +!CURVEEDITOR_TOOLTIPPASTE;Paste curve from clipboard. +!CURVEEDITOR_TYPE;Type: +!EDITWINDOW_TITLE;Image Edit +!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_FILETYPE;File type +!EXIFFILTER_METADATAFILTER;Enable metadata filters +!EXPORT_BYPASS_ALL;Select / Unselect All +!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_FF;Bypass [raw] Flat-Field +!EXPORT_BYPASS_RAW_GREENTHRESH;Bypass [raw] Green Equilibration +!EXPORT_BYPASS_RAW_LINENOISE;Bypass [raw] Line Noise Filter +!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_FASTEXPORTOPTIONS;Fast Export Options +!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_MAXHEIGHT;Maximum height: +!EXPORT_MAXWIDTH;Maximum width: +!EXPORT_PUTTOQUEUEFAST; Put to queue for fast export +!EXPORT_RAW_DMETHOD;Demosaic method +!EXTPROGTARGET_1;raw +!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_CACHECLEARFROMFULL;Clear from cache - full +!FILEBROWSER_CACHECLEARFROMPARTIAL;Clear from cache - partial +!FILEBROWSER_CACHE;Cache +!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_CURRENT_NAME;Current name: +!FILEBROWSER_DARKFRAME;Dark-frame +!FILEBROWSER_DELETEDLGMSGINCLPROC;Are you sure you want to delete the selected %1 files including a queue-processed version? +!FILEBROWSER_EXEC_CPB;Custom Profile Builder +!FILEBROWSER_EXTPROGMENU;Open with +!FILEBROWSER_FLATFIELD;Flat-Field +!FILEBROWSER_MOVETODARKFDIR;Move to dark-frames directory +!FILEBROWSER_MOVETOFLATFIELDDIR;Move to flat-fields directory +!FILEBROWSER_NEW_NAME;New name: +!FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) +!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_POPUPCOLORLABEL;Color label +!FILEBROWSER_POPUPCOPYTO;Copy to... +!FILEBROWSER_POPUPFILEOPERATIONS;File operations +!FILEBROWSER_POPUPMOVETO;Move to... +!FILEBROWSER_POPUPPROCESSFAST;Put to queue (Fast export) +!FILEBROWSER_POPUPPROFILEOPERATIONS;Processing profile operations +!FILEBROWSER_POPUPRANK0;Unrank +!FILEBROWSER_POPUPRANK1;Rank 1 * +!FILEBROWSER_POPUPRANK2;Rank 2 ** +!FILEBROWSER_POPUPRANK3;Rank 3 *** +!FILEBROWSER_POPUPRANK4;Rank 4 **** +!FILEBROWSER_POPUPRANK5;Rank 5 ***** +!FILEBROWSER_POPUPRANK;Rank +!FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +!FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +!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_QUERYLABEL; Find: +!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_SELECTDARKFRAME;Select dark-frame... +!FILEBROWSER_SELECTFLATFIELD;Select flat-field... +!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 +!FILEBROWSER_SHOWCOLORLABEL4HINT;Show images labeled Blue.\nShortcut: Alt-4 +!FILEBROWSER_SHOWCOLORLABEL5HINT;Show images labeled Purple.\nShortcut: Alt-5 +!FILEBROWSER_SHOWEDITEDHINT;Show edited images.\nShortcut: 7 +!FILEBROWSER_SHOWEDITEDNOTHINT;Show not edited images.\nShortcut: 6 +!FILEBROWSER_SHOWEXIFINFO;Show Exif info.\n\nShortcuts:\ni - Multiple Editor Tabs Mode,\nAlt-i - Single Editor Tab Mode. +!FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +!FILEBROWSER_SHOWRECENTLYSAVEDHINT;Show saved images.\nShortcut: Alt-7 +!FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show unsaved images.\nShortcut: Alt-6 +!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_AFTER;After +!GENERAL_ASIMAGE;As Image +!GENERAL_AUTO;Automatic +!GENERAL_BEFORE;Before +!GENERAL_CLOSE;Close +!GENERAL_FILE;File +!GENERAL_NONE;None +!GENERAL_UNCHANGED;(Unchanged) +!GENERAL_WARNING;Warning +!HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar.\nRight-click on image preview to freeze/unfreeze. +!HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram. +!HISTOGRAM_TOOLTIP_FULL;Toggle full (off) or scaled (on) histogram. +!HISTOGRAM_TOOLTIP_RAW;Show/Hide raw histogram. +!HISTORY_MSG_82;Profile changed +!HISTORY_MSG_83;S/H - Sharp mask +!HISTORY_MSG_84;Perspective correction +!HISTORY_MSG_85;LCP +!HISTORY_MSG_86;RGB curves - Luminosity mode +!HISTORY_MSG_87;Impulse noise reduction +!HISTORY_MSG_88;Impulse NR threshold +!HISTORY_MSG_89;Noise Reduction +!HISTORY_MSG_90;NR - Luminance +!HISTORY_MSG_91;NR - Chrominance master +!HISTORY_MSG_92;NR - Gamma +!HISTORY_MSG_93;CbDL - Value +!HISTORY_MSG_94;Contrast by Detail Levels +!HISTORY_MSG_95;L*a*b* - Chromaticity +!HISTORY_MSG_96;L*a*b* - a* curve +!HISTORY_MSG_97;L*a*b* - b* curve +!HISTORY_MSG_98;Demosaicing method +!HISTORY_MSG_99;Hot pixel filter +!HISTORY_MSG_100;RGB Saturation +!HISTORY_MSG_101;HSV - Hue +!HISTORY_MSG_102;HSV - Saturation +!HISTORY_MSG_103;HSV - Value +!HISTORY_MSG_104;HSV Equalizer +!HISTORY_MSG_105;Defringe +!HISTORY_MSG_106;Defringe - Radius +!HISTORY_MSG_107;Defringe - Threshold +!HISTORY_MSG_108;Highlight Compr. Threshold +!HISTORY_MSG_109;Resize - Bounding box +!HISTORY_MSG_110;Resize - Applies to +!HISTORY_MSG_111;L*a*b* - Avoid color shift +!HISTORY_MSG_112;--unused-- +!HISTORY_MSG_113;L*a*b* - Red/skin prot. +!HISTORY_MSG_114;DCB iterations +!HISTORY_MSG_115;False color suppression +!HISTORY_MSG_116;DCB enhancement +!HISTORY_MSG_117;Raw CA correction - Red +!HISTORY_MSG_118;Raw CA correction - Blue +!HISTORY_MSG_119;Line noise filter +!HISTORY_MSG_120;Green equilibration +!HISTORY_MSG_121;Raw CA Correction - Auto +!HISTORY_MSG_122;Dark-Frame - Auto-selection +!HISTORY_MSG_123;Dark-Frame - File +!HISTORY_MSG_124;White point correction +!HISTORY_MSG_125;Highlight preservation +!HISTORY_MSG_126;Flat-Field - File +!HISTORY_MSG_127;Flat-Field - Auto-selection +!HISTORY_MSG_128;Flat-Field - Blur radius +!HISTORY_MSG_129;Flat-Field - Blur type +!HISTORY_MSG_130;Auto distorion correction +!HISTORY_MSG_131;NR - Luma +!HISTORY_MSG_132;NR - Chroma +!HISTORY_MSG_133;Output gamma +!HISTORY_MSG_134;Free gamma +!HISTORY_MSG_135;Free gamma +!HISTORY_MSG_136;Free gamma slope +!HISTORY_MSG_137;Black level - Green 1 +!HISTORY_MSG_138;Black level - Red +!HISTORY_MSG_139;Black level - Blue +!HISTORY_MSG_140;Black level - Green 2 +!HISTORY_MSG_141;Black level - Link greens +!HISTORY_MSG_142;ES - Iterations +!HISTORY_MSG_143;ES - Quantity +!HISTORY_MSG_144;Microcontrast - Quantity +!HISTORY_MSG_145;Microcontrast - Uniformity +!HISTORY_MSG_146;Edge sharpening +!HISTORY_MSG_147;ES - Luminance only +!HISTORY_MSG_148;Microcontrast +!HISTORY_MSG_149;Microcontrast - 3x3 matrix +!HISTORY_MSG_150;Post-demosaic artifact/noise red. +!HISTORY_MSG_151;Vibrance +!HISTORY_MSG_152;Vib - Pastel tones +!HISTORY_MSG_153;Vib - Saturated tones +!HISTORY_MSG_154;Vib - Protect skin-tones +!HISTORY_MSG_155;Vib - Avoid color shift +!HISTORY_MSG_156;Vib - Link pastel/saturated +!HISTORY_MSG_157;Vib - P/S threshold +!HISTORY_MSG_158;TM - Strength +!HISTORY_MSG_159;TM - Edge stopping +!HISTORY_MSG_160;TM - Scale +!HISTORY_MSG_161;TM - Reweighting iterates +!HISTORY_MSG_162;Tone Mapping +!HISTORY_MSG_163;RGB curves - Red +!HISTORY_MSG_164;RGB curves - Green +!HISTORY_MSG_165;RGB curves - Blue +!HISTORY_MSG_166;Neutral levels +!HISTORY_MSG_167;--unused-- +!HISTORY_MSG_168;L*a*b* - CC curve +!HISTORY_MSG_169;L*a*b* - CH curve +!HISTORY_MSG_170;Vibrance - HH curve +!HISTORY_MSG_171;L*a*b* - LC curve +!HISTORY_MSG_172;L*a*b* - Restrict LC +!HISTORY_MSG_173;NR - Luminance detail +!HISTORY_MSG_174;CIECAM02 +!HISTORY_MSG_175;CAM02 - CAT02 adaptation +!HISTORY_MSG_176;CAM02 - Viewing surround +!HISTORY_MSG_177;CAM02 - Scene luminosity +!HISTORY_MSG_178;CAM02 - Viewing luminosity +!HISTORY_MSG_179;CAM02 - White-point model +!HISTORY_MSG_180;CAM02 - Lightness (J) +!HISTORY_MSG_181;CAM02 - Chroma (C) +!HISTORY_MSG_182;CAM02 - Automatic CAT02 +!HISTORY_MSG_183;CAM02 - Contrast (J) +!HISTORY_MSG_184;CAM02 - Scene surround +!HISTORY_MSG_185;CAM02 - Gamut control +!HISTORY_MSG_186;CAM02 - Algorithm +!HISTORY_MSG_187;CAM02 - Red/skin prot. +!HISTORY_MSG_188;CAM02 - Brightness (Q) +!HISTORY_MSG_189;CAM02 - Contrast (Q) +!HISTORY_MSG_190;CAM02 - Saturation (S) +!HISTORY_MSG_191;CAM02 - Colorfulness (M) +!HISTORY_MSG_192;CAM02 - Hue (h) +!HISTORY_MSG_193;CAM02 - Tone curve 1 +!HISTORY_MSG_194;CAM02 - Tone curve 2 +!HISTORY_MSG_195;CAM02 - Tone curve 1 +!HISTORY_MSG_196;CAM02 - Tone curve 2 +!HISTORY_MSG_197;CAM02 - Color curve +!HISTORY_MSG_198;CAM02 - Color curve +!HISTORY_MSG_199;CAM02 - Output histograms +!HISTORY_MSG_200;CAM02 - Tone mapping +!HISTORY_MSG_201;NR - Chrominance - R&G +!HISTORY_MSG_202;NR - Chrominance - B&Y +!HISTORY_MSG_203;NR - Method +!HISTORY_MSG_204;LMMSE enhancement steps +!HISTORY_MSG_205;CAM02 - Hot/bad pixel filter +!HISTORY_MSG_206;CAT02 - Auto scene luminosity +!HISTORY_MSG_207;Defringe - Hue curve +!HISTORY_MSG_208;WB - B/R equalizer +!HISTORY_MSG_210;GF - Angle +!HISTORY_MSG_211;Graduated Filter +!HISTORY_MSG_212;VF - Strength +!HISTORY_MSG_213;Vignette Filter +!HISTORY_MSG_214;Black-and-White +!HISTORY_MSG_215;B&W - CM - Red +!HISTORY_MSG_216;B&W - CM - Green +!HISTORY_MSG_217;B&W - CM - Blue +!HISTORY_MSG_218;B&W - Gamma - Red +!HISTORY_MSG_219;B&W - Gamma - Green +!HISTORY_MSG_220;B&W - Gamma - Blue +!HISTORY_MSG_221;B&W - Color filter +!HISTORY_MSG_222;B&W - Presets +!HISTORY_MSG_223;B&W - CM - Orange +!HISTORY_MSG_224;B&W - CM - Yellow +!HISTORY_MSG_225;B&W - CM - Cyan +!HISTORY_MSG_226;B&W - CM - Magenta +!HISTORY_MSG_227;B&W - CM - Purple +!HISTORY_MSG_228;B&W - Luminance equalizer +!HISTORY_MSG_229;B&W - Luminance equalizer +!HISTORY_MSG_230;B&W - Mode +!HISTORY_MSG_231;B&W - 'Before' curve +!HISTORY_MSG_232;B&W - 'Before' curve type +!HISTORY_MSG_233;B&W - 'After' curve +!HISTORY_MSG_234;B&W - 'After' curve type +!HISTORY_MSG_235;B&W - Auto channel mixer +!HISTORY_MSG_236;--unused-- +!HISTORY_MSG_237;B&W - Mixer +!HISTORY_MSG_238;GF - Feather +!HISTORY_MSG_239;GF - Strength +!HISTORY_MSG_240;GF - Center +!HISTORY_MSG_241;VF - Feather +!HISTORY_MSG_242;VF - Roundness +!HISTORY_MSG_243;VC - Radius +!HISTORY_MSG_244;VC - Strength +!HISTORY_MSG_245;VC - Center +!HISTORY_MSG_246;L*a*b* - CL curve +!HISTORY_MSG_247;L*a*b* - LH curve +!HISTORY_MSG_248;L*a*b* - HH curve +!HISTORY_MSG_249;CbDL - Threshold +!HISTORY_MSG_250;NR - Enhanced +!HISTORY_MSG_251;B&W - Algorithm +!HISTORY_MSG_252;CbDL - Skin tar/prot +!HISTORY_MSG_253;CbDL - Reduce artifacts +!HISTORY_MSG_254;CbDL - Skin hue +!HISTORY_MSG_255;NR - Median filter +!HISTORY_MSG_256;NR - Median type +!HISTORY_MSG_257;Color Toning +!HISTORY_MSG_258;CT - Color curve +!HISTORY_MSG_259;CT - Opacity curve +!HISTORY_MSG_260;CT - a*[b*] opacity +!HISTORY_MSG_261;CT - Method +!HISTORY_MSG_262;CT - b* opacity +!HISTORY_MSG_263;CT - Shadows - Red +!HISTORY_MSG_264;CT - Shadows - Green +!HISTORY_MSG_265;CT - Shadows - Blue +!HISTORY_MSG_266;CT - Mid - Red +!HISTORY_MSG_267;CT - Mid - Green +!HISTORY_MSG_268;CT - Mid - Blue +!HISTORY_MSG_269;CT - High - Red +!HISTORY_MSG_270;CT - High - Green +!HISTORY_MSG_271;CT - High - Blue +!HISTORY_MSG_272;CT - Balance +!HISTORY_MSG_273;CT - Reset +!HISTORY_MSG_274;CT - Sat. Shadows +!HISTORY_MSG_275;CT - Sat. Highlights +!HISTORY_MSG_276;CT - Opacity +!HISTORY_MSG_277;--unused-- +!HISTORY_MSG_278;CT - Preserve luminance +!HISTORY_MSG_279;CT - Shadows +!HISTORY_MSG_280;CT - Highlights +!HISTORY_MSG_281;CT - Sat. strength +!HISTORY_MSG_282;CT - Sat. threshold +!HISTORY_MSG_283;CT - Strength +!HISTORY_MSG_284;CT - Auto sat. protection +!HISTORY_MSG_285;NR - Median - Method +!HISTORY_MSG_286;NR - Median - Type +!HISTORY_MSG_287;NR - Median - Iterations +!HISTORY_MSG_288;Flat Field - Clip control +!HISTORY_MSG_289;Flat Field - Clip control - Auto +!HISTORY_MSG_290;Black Level - Red +!HISTORY_MSG_291;Black Level - Green +!HISTORY_MSG_292;Black Level - Blue +!HISTORY_MSG_293;Film Simulation +!HISTORY_MSG_294;Film Simulation - Strength +!HISTORY_MSG_295;Film Simulation - Film +!HISTORY_MSG_296;NR - Luminance curve +!HISTORY_MSG_297;NR - Quality +!HISTORY_MSG_298;Dead pixel filter +!HISTORY_MSG_299;NR - Chrominance curve +!HISTORY_MSG_300;- +!HISTORY_MSG_301;NR - Luma control +!HISTORY_MSG_302;NR - Chroma method +!HISTORY_MSG_303;NR - Chroma method +!HISTORY_MSG_304;W - Contrast levels +!HISTORY_MSG_305;Wavelet Levels +!HISTORY_MSG_306;W - Preview +!HISTORY_MSG_307;W - Preview +!HISTORY_MSG_308;W - Preview direction +!HISTORY_MSG_309;W - ES - Detail +!HISTORY_MSG_310;W - Residual - Sky tar/prot +!HISTORY_MSG_311;W - Wavelet levels +!HISTORY_MSG_312;W - Residual - Shadows threshold +!HISTORY_MSG_313;W - Chroma - Sat/past +!HISTORY_MSG_314;W - Gamut - Reduce artifacts +!HISTORY_MSG_315;W - Residual - Contrast +!HISTORY_MSG_316;W - Gamut - Skin tar/prot +!HISTORY_MSG_317;W - Gamut - Skin hue +!HISTORY_MSG_318;W - Contrast - Highlight levels +!HISTORY_MSG_319;W - Contrast - Highlight range +!HISTORY_MSG_320;W - Contrast - Shadow range +!HISTORY_MSG_321;W - Contrast - Shadow levels +!HISTORY_MSG_322;W - Gamut - Avoid color shift +!HISTORY_MSG_323;W - ES - Local contrast +!HISTORY_MSG_324;W - Chroma - Pastel +!HISTORY_MSG_325;W - Chroma - Saturated +!HISTORY_MSG_326;W - Chroma - Method +!HISTORY_MSG_327;W - Contrast - Apply to +!HISTORY_MSG_328;W - Chroma - Link strength +!HISTORY_MSG_329;W - Toning - Opacity RG +!HISTORY_MSG_330;W - Toning - Opacity BY +!HISTORY_MSG_331;W - Contrast levels - Extra +!HISTORY_MSG_332;W - Tiling method +!HISTORY_MSG_333;W - Residual - Shadows +!HISTORY_MSG_334;W - Residual - Chroma +!HISTORY_MSG_335;W - Residual - Highlights +!HISTORY_MSG_336;W - Residual - Highlights threshold +!HISTORY_MSG_337;W - Residual - Sky hue +!HISTORY_MSG_338;W - ES - Radius +!HISTORY_MSG_339;W - ES - Strength +!HISTORY_MSG_340;W - Strength +!HISTORY_MSG_341;W - Edge performance +!HISTORY_MSG_342;W - ES - First level +!HISTORY_MSG_343;W - Chroma levels +!HISTORY_MSG_344;W - Meth chroma sl/cur +!HISTORY_MSG_345;W - ES - Local contrast +!HISTORY_MSG_346;W - ES - Local contrast method +!HISTORY_MSG_347;W - Denoise - Level 0 +!HISTORY_MSG_348;W - Denoise - Level 1 +!HISTORY_MSG_349;W - Denoise - Level 2 +!HISTORY_MSG_350;W - ES - Edge detection +!HISTORY_MSG_351;W - Residual - HH curve +!HISTORY_MSG_352;W - Background +!HISTORY_MSG_353;W - ES - Gradient sensitivity +!HISTORY_MSG_354;W - ES - Enhance +!HISTORY_MSG_355;W - ES - Threshold low +!HISTORY_MSG_356;W - ES - Threshold high +!HISTORY_MSG_357;W - Denoise - Link with ES +!HISTORY_MSG_358;W - Gamut - CH +!HISTORY_MSG_359;Hot/Dead - Threshold +!HISTORY_MSG_360;TM Gamma +!HISTORY_MSG_361;W - Final - Chroma balance +!HISTORY_MSG_362;W - Residual - Compression method +!HISTORY_MSG_363;W - Residual - Compression strength +!HISTORY_MSG_364;W - Final - Contrast balance +!HISTORY_MSG_365;W - Final - Delta balance +!HISTORY_MSG_366;W - Residual - Compression gamma +!HISTORY_MSG_367;W - ES - Local contrast curve +!HISTORY_MSG_368;W - Final - Contrast balance +!HISTORY_MSG_369;W - Final - Balance method +!HISTORY_MSG_370;W - Final - Local contrast curve +!HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s +!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 +!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). +!MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Put current image to processing queue.\nShortcut: Ctrl+b +!MAIN_BUTTON_SAVE_TOOLTIP;Save current image.\nShortcut: Ctrl+s +!MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Edit current image in external editor.\nShortcut: Ctrl+e +!MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Show/hide all side panels.\nShortcut: m +!MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen +!MAIN_FRAME_BATCHQUEUE_TOOLTIP;Processing queue.\nShortcut: Ctrl-F3 +!MAIN_FRAME_EDITOR;Editor +!MAIN_FRAME_EDITOR_TOOLTIP;Editor.\nShortcut: Ctrl-F4 +!MAIN_FRAME_FILEBROWSER_TOOLTIP;File browser.\nShortcut: Ctrl-F2 +!MAIN_MSG_EMPTYFILENAME;Filename unspecified! +!MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue-processed first. +!MAIN_MSG_NAVIGATOR;Navigator +!MAIN_MSG_OPERATIONCANCELLED;Operation cancelled +!MAIN_MSG_PATHDOESNTEXIST;The path\n\n%1\n\ndoes not exist. Please set a correct path in Preferences. +!MAIN_MSG_SETPATHFIRST;You first have to set a target path in Preferences in order to use this function! +!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_EXPORT; Fast Export +!MAIN_TAB_EXPOSURE_TOOLTIP;Shortcut: Alt-e +!MAIN_TAB_INSPECT; Inspect +!MAIN_TAB_METADATA_TOOLTIP;Shortcut: Alt-m +!MAIN_TAB_RAW;Raw +!MAIN_TAB_RAW_TOOLTIP;Shortcut: Alt-r +!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_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%. +!MAIN_TOOLTIP_PREVIEWG;Preview the Green channel.\nShortcut: g +!MAIN_TOOLTIP_PREVIEWL;Preview the Luminosity.\nShortcut: v\n\n0.299*R + 0.587*G + 0.114*B +!MAIN_TOOLTIP_PREVIEWR;Preview the Red channel.\nShortcut: r +!MAIN_TOOLTIP_SHOWHIDELP1;Show/Hide the left panel.\nShortcut: l +!MAIN_TOOLTIP_SHOWHIDERP1;Show/Hide the right panel.\nShortcut: Alt-l +!MAIN_TOOLTIP_SHOWHIDETP1;Show/Hide the top panel.\nShortcut: Shift-l +!MAIN_TOOLTIP_THRESHOLD;Threshold +!MAIN_TOOLTIP_TOGGLE;Toggle the Before/After view.\nShortcut: Shift-b +!NAVIGATOR_B;B: +!NAVIGATOR_G;G: +!NAVIGATOR_H;H: +!NAVIGATOR_LAB_A;a*: +!NAVIGATOR_LAB_B;b*: +!NAVIGATOR_LAB_L;L*: +!NAVIGATOR_NA; -- +!NAVIGATOR_R;R: +!NAVIGATOR_S;S: +!NAVIGATOR_V;V: +!NAVIGATOR_XY_FULL;Width: %1, Height: %2 +!NAVIGATOR_XY_NA;x: --, y: -- +!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_CHANNELMIXERBW;Black-and-White +!PARTIALPASTE_CHANNELMIXER;Channel mixer +!PARTIALPASTE_COLORAPP;CIECAM02 +!PARTIALPASTE_COLORTONING;Color Toning +!PARTIALPASTE_COMMONTRANSFORMPARAMS;Auto-fill +!PARTIALPASTE_DARKFRAMEAUTOSELECT;Dark-frame auto-selection +!PARTIALPASTE_DARKFRAMEFILE;Dark-frame file +!PARTIALPASTE_DEFRINGE;Defringe +!PARTIALPASTE_DETAILGROUP;Detail Settings +!PARTIALPASTE_DIRPYRDENOISE;Noise reduction +!PARTIALPASTE_DIRPYREQUALIZER;Contrast by detail levels +!PARTIALPASTE_EPD;Tone mapping +!PARTIALPASTE_EQUALIZER;Wavelet Equalizer +!PARTIALPASTE_EVERYTHING;Everything +!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_GRADIENT;Graduated filter +!PARTIALPASTE_HSVEQUALIZER;HSV equalizer +!PARTIALPASTE_ICMGAMMA;Output gamma +!PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction +!PARTIALPASTE_LABCURVE;L*a*b* adjustments +!PARTIALPASTE_LENSPROFILE;Lens correction profile +!PARTIALPASTE_PCVIGNETTE;Vignette filter +!PARTIALPASTE_PERSPECTIVE;Perspective +!PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter +!PARTIALPASTE_PREPROCESS_GREENEQUIL;Green equilibration +!PARTIALPASTE_PREPROCESS_HOTPIXFILT;Hot pixel filter +!PARTIALPASTE_PREPROCESS_LINEDENOISE;Line noise filter +!PARTIALPASTE_RAWCACORR_AUTO;CA auto-correction +!PARTIALPASTE_RAWCACORR_CABLUE;CA blue +!PARTIALPASTE_RAWCACORR_CARED;CA red +!PARTIALPASTE_RAWEXPOS_BLACK;Black levels +!PARTIALPASTE_RAWEXPOS_LINEAR;White point correction +!PARTIALPASTE_RAWEXPOS_PRESER;Highlight preservation +!PARTIALPASTE_RAWGROUP;Raw Settings +!PARTIALPASTE_RAW_DCBENHANCE;DCB enhancement +!PARTIALPASTE_RAW_DCBITERATIONS;Number of DCB iterations +!PARTIALPASTE_RAW_DMETHOD;Demosaic method +!PARTIALPASTE_RAW_FALSECOLOR;Demosaic false color suppression steps +!PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!PARTIALPASTE_RGBCURVES;RGB curves +!PARTIALPASTE_SHARPENEDGE;Edges +!PARTIALPASTE_SHARPENMICRO;Microcontrast +!PARTIALPASTE_VIBRANCE;Vibrance +!PARTIALPASTE_WAVELETGROUP;Wavelet processing +!PREFERENCES_ADD;Add +!PREFERENCES_AUTLISLOW;Low +!PREFERENCES_AUTLISMAX;Max - Average of all tiles +!PREFERENCES_AUTLISSTD;High +!PREFERENCES_AUTLISVLOW;None +!PREFERENCES_AUTLOW;Low +!PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +!PREFERENCES_AUTSTD;Standard +!PREFERENCES_BATCH_PROCESSING;Batch Processing +!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_BEHADDALL;All to 'Add' +!PREFERENCES_BEHAVIOR;Behavior +!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_BEHSETALL;All to 'Set' +!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_CURVEBBOXPOS;Position of curve copypasta buttons +!PREFERENCES_CURVEBBOXPOS_ABOVE;Above +!PREFERENCES_CURVEBBOXPOS_BELOW;Below +!PREFERENCES_CURVEBBOXPOS_LEFT;Left +!PREFERENCES_CURVEBBOXPOS_RIGHT;Right +!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_CUSTPROFBUILD;Custom Processing Profile Builder +!PREFERENCES_CUTOVERLAYBRUSH;Crop mask color/transparency +!PREFERENCES_D50;5000K +!PREFERENCES_D55;5500K +!PREFERENCES_D60;6000K +!PREFERENCES_D65;6500K +!PREFERENCES_DARKFRAMEFOUND;Found +!PREFERENCES_DARKFRAMESHOTS;shots +!PREFERENCES_DARKFRAMETEMPLATES;templates +!PREFERENCES_DARKFRAME;Dark-Frame +!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 (de-select for low resolution display) +!PREFERENCES_FILMSIMULATION;Film Simulation +!PREFERENCES_FLATFIELDFOUND;Found +!PREFERENCES_FLATFIELDSDIR;Flat-fields directory +!PREFERENCES_FLATFIELDSHOTS;shots +!PREFERENCES_FLATFIELDTEMPLATES;templates +!PREFERENCES_FLATFIELD;Flat-Field +!PREFERENCES_FLUOF2;Fluorescent F2 +!PREFERENCES_FLUOF7;Fluorescent F7 +!PREFERENCES_FLUOF11;Fluorescent F11 +!PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT;Same thumbnail height between the Editor's panel 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_GREY05;Yb=05 CIE L#30 +!PREFERENCES_GREY10;Yb=10 CIE L#40 +!PREFERENCES_GREY15;Yb=15 CIE L#45 +!PREFERENCES_GREY18;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_GREYSC18;Yb=18 CIE L#50 +!PREFERENCES_GREYSCA;Automatic +!PREFERENCES_GREYSC;Scene Yb luminance (%) +!PREFERENCES_GREY;Output device's Yb luminance (%) +!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_LANGAUTODETECT;Use system language +!PREFERENCES_LEVAUTDN;Denoising level +!PREFERENCES_LEVDN;Cell size +!PREFERENCES_LISS;Auto multi-zone smoothing +!PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders +!PREFERENCES_MAX;Maxi (Tile) +!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_MENUGROUPRANK;Group "Rank" +!PREFERENCES_MENUOPTIONS;Context Menu Options +!PREFERENCES_METADATA;Metadata +!PREFERENCES_MIN;Mini (100x115) +!PREFERENCES_MULTITABDUALMON;Multiple Editor Tabs In Own Window Mode +!PREFERENCES_MULTITAB;Multiple Editor Tabs 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_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_PROPERTY;Property +!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 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_SINGLETABVERTAB;Single Editor Tab Mode, Vertical Tabs +!PREFERENCES_SINGLETAB;Single Editor Tab Mode +!PREFERENCES_SLIMUI;Slim interface +!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_PERFORMANCE;Performance & Quality +!PREFERENCES_TAB_SOUND;Sounds +!PREFERENCES_TIMAX;High +!PREFERENCES_TINB;Number of tiles +!PREFERENCES_TISTD;Standard +!PREFERENCES_TP_LABEL;Tool panel: +!PREFERENCES_TP_USEICONORTEXT;Use tab icons instead of text +!PREFERENCES_TP_VSCROLLBAR;Hide vertical scrollbar +!PREFERENCES_TUNNELMETADATA;Copy IPTC/XMP unchanged to output file (when tagging with other program) +!PREFERENCES_USEBUNDLEDPROFILES;Use bundled profiles +!PREFERENCES_USESYSTEMTHEME;Use system theme +!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_WORKFLOW;Layout +!PROFILEPANEL_COPYPPASTE;Parameters to copy +!PROFILEPANEL_GLOBALPROFILES;Bundled profiles +!PROFILEPANEL_LOADPPASTE;Parameters to load +!PROFILEPANEL_MODE_TIP;Processing profile fill mode.\n\nButton pressed: partial profiles will be converted to full profiles; the missing values will be replaced with hard-coded defaults.\n\nButton released: profiles will be applied as they are, altering only those values which they contain. +!PROFILEPANEL_MYPROFILES;My profiles +!PROFILEPANEL_PASTEPPASTE;Parameters to paste +!PROFILEPANEL_PINTERNAL;Neutral +!PROFILEPANEL_SAVEPPASTE;Parameters to save +!PROGRESSBAR_LOADINGTHUMBS;Loading thumbnails... +!PROGRESSBAR_NOIMAGES;No images found +!PROGRESSBAR_PROCESSING_PROFILESAVED;Processing profile saved +!PROGRESSBAR_SNAPSHOT_ADDED;Snapshot added +!PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +!SAVEDLG_AUTOSUFFIX;Automatically add a suffix if the file already exists +!SAVEDLG_FORCEFORMATOPTS;Force saving options +!SAVEDLG_SUBSAMP;Subsampling +!SAVEDLG_SUBSAMP_1;Best compression +!SAVEDLG_SUBSAMP_2;Balanced +!SAVEDLG_SUBSAMP_3;Best quality +!SAVEDLG_SUBSAMP_TOOLTIP;Best compression: 4:1:1\nBalanced: 4:2:2\nBest quality: 4:4:4 +!SAVEDLG_WARNFILENAME;File will be named +!SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. +!THRESHOLDSELECTOR_BL;Bottom-left +!THRESHOLDSELECTOR_BR;Bottom-right +!THRESHOLDSELECTOR_B;Bottom +!THRESHOLDSELECTOR_HINT;Hold the Shift key to move individual control points. +!THRESHOLDSELECTOR_TL;Top-left +!THRESHOLDSELECTOR_TR;Top-right +!THRESHOLDSELECTOR_T;Top +!TP_BWMIX_ALGO;Algorithm OYCPM +!TP_BWMIX_ALGO_LI;Linear +!TP_BWMIX_ALGO_SP;Special effects +!TP_BWMIX_ALGO_TOOLTIP;Linear: will produce a normal linear response.\nSpecial effects: will produce special effects by mixing channels non-linearly. +!TP_BWMIX_AUTOCH;Auto +!TP_BWMIX_AUTOCH_TIP;Calculate values optimizing Channel Mixer. +!TP_BWMIX_CC_ENABLED;Adjust complementary color +!TP_BWMIX_CC_TOOLTIP;Enable to allow automatic adjustment of complementary colors in ROYGCBPM mode. +!TP_BWMIX_CHANNEL;Luminance equalizer +!TP_BWMIX_CURVEEDITOR1;'Before' curve +!TP_BWMIX_CURVEEDITOR2;'After' curve +!TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Tone curve, after B&W conversion, at the end of treatment. +!TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Tone curve, just before B&W conversion.\nMay take into account the color components. +!TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H).\nPay attention to extreme values as they may cause artifacts. +!TP_BWMIX_FILTER;Color Filter +!TP_BWMIX_FILTER_BLUEGREEN;Blue-Green +!TP_BWMIX_FILTER_BLUE;Blue +!TP_BWMIX_FILTER_GREENYELLOW;Green-Yellow +!TP_BWMIX_FILTER_GREEN;Green +!TP_BWMIX_FILTER_NONE;None +!TP_BWMIX_FILTER_PURPLE;Purple +!TP_BWMIX_FILTER_REDYELLOW;Red-Yellow +!TP_BWMIX_FILTER_RED;Red +!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. +!TP_BWMIX_FILTER_YELLOW;Yellow +!TP_BWMIX_GAMMA;Gamma Correction +!TP_BWMIX_GAM_TOOLTIP;Correct gamma for each RGB channel. +!TP_BWMIX_LABEL;Black-and-White +!TP_BWMIX_MET;Method +!TP_BWMIX_MET_CHANMIX;Channel Mixer +!TP_BWMIX_MET_DESAT;Desaturation +!TP_BWMIX_MET_LUMEQUAL;Luminance Equalizer +!TP_BWMIX_MIXC;Mixer +!TP_BWMIX_NEUTRAL;Reset mixer +!TP_BWMIX_NEUTRAL_TIP;Reset all values (Color Filter, Channel Mixer) to default. +!TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +!TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all the mixer options.\n"Total" displays the sum of the RGB values:\n- always 100% in relative mode\n- higher (lighter) or lower (darker) than 100% in absolute mode. +!TP_BWMIX_RGB_TOOLTIP;Mix the RGB channels. Use presets for guidance.\nPay attention to negative values that may cause artifacts or erratic behavior. +!TP_BWMIX_SETTING;Presets +!TP_BWMIX_SETTING_TOOLTIP;Different presets (film, landscape, etc.) or manual Channel Mixer settings. +!TP_BWMIX_SET_HIGHCONTAST;High contrast +!TP_BWMIX_SET_HIGHSENSIT;High Sensitivity +!TP_BWMIX_SET_HYPERPANCHRO;Hyper Panchromatic +!TP_BWMIX_SET_INFRARED;Infrared +!TP_BWMIX_SET_LANDSCAPE;Landscape +!TP_BWMIX_SET_LOWSENSIT;Low Sensitivity +!TP_BWMIX_SET_LUMINANCE;Luminance +!TP_BWMIX_SET_NORMCONTAST;Normal Contrast +!TP_BWMIX_SET_ORTHOCHRO;Orthochromatic +!TP_BWMIX_SET_PANCHRO;Panchromatic +!TP_BWMIX_SET_PORTRAIT;Portrait +!TP_BWMIX_SET_RGBABS;Absolute RGB +!TP_BWMIX_SET_RGBREL;Relative RGB +!TP_BWMIX_SET_ROYGCBPMABS;Absolute ROYGCBPM +!TP_BWMIX_SET_ROYGCBPMREL;Relative ROYGCBPM +!TP_BWMIX_TCMODE_FILMLIKE;B&W Film-like +!TP_BWMIX_TCMODE_SATANDVALBLENDING;B&W Saturation and Value Blending +!TP_BWMIX_TCMODE_STANDARD;B&W Standard +!TP_BWMIX_TCMODE_WEIGHTEDSTD;B&W Weighted Standard +!TP_BWMIX_VAL;L +!TP_CHROMATABERR_LABEL;Chromatic Aberration +!TP_COLORAPP_ADAPTSCENE;Scene luminosity +!TP_COLORAPP_ADAPTSCENE_TOOLTIP;Absolute luminance of the scene environement (cd/m²).\n1) Calculated from the Exif data:\nShutter speed - ISO speed - F number - camera exposure correction.\n2) Calculated from the raw white point and RT's Exposure Compensation slider. +!TP_COLORAPP_ADAPTVIEWING;Viewing luminosity (cd/m²) +!TP_COLORAPP_ADAPTVIEWING_TOOLTIP;Absolute luminance of the viewing environnement\n(usually 16cd/m²). +!TP_COLORAPP_ADAP_AUTO_TOOLTIP;If the checkbox is checked (recommended) RawTherapee calculates an optimum value from Exif data.\nTo set the value manually, uncheck the checkbox first. +!TP_COLORAPP_ALGO;Algorithm +!TP_COLORAPP_ALGO_ALL;All +!TP_COLORAPP_ALGO_JC;Lightness + Chroma (JC) +!TP_COLORAPP_ALGO_JS;Lightness + Saturation (JS) +!TP_COLORAPP_ALGO_QM;Brightness + Colorfulness (QM) +!TP_COLORAPP_ALGO_TOOLTIP;Lets you choose between parameter subsets or all parameters. +!TP_COLORAPP_BADPIXSL;Hot/bad pixel filter +!TP_COLORAPP_BADPIXSL_TOOLTIP;Suppression of hot/bad (brightly colored) pixels.\n0 = No effect\n1 = Median\n2 = Gaussian.\nAlternatively, adjust the image to avoid very dark shadows.\n\nThese artifacts are due to limitations of CIECAM02. +!TP_COLORAPP_BRIGHT;Brightness (Q) +!TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from L*a*b* and RGB brightness. +!TP_COLORAPP_CHROMA;Chroma (C) +!TP_COLORAPP_CHROMA_M;Colorfulnes (M) +!TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM02 differs from L*a*b* and RGB colorfulness. +!TP_COLORAPP_CHROMA_S;Saturation (S) +!TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from L*a*b* and RGB saturation. +!TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from L*a*b* and RGB chroma. +!TP_COLORAPP_CIECAT_DEGREE;CAT02 adaptation +!TP_COLORAPP_CONTRAST;Contrast (J) +!TP_COLORAPP_CONTRAST_Q;Contrast (Q) +!TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrast in CIECAM02 for the Q slider; it differs from L*a*b* and RGB contrast. +!TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from L*a*b* and RGB contrast. +!TP_COLORAPP_CURVEEDITOR1;Tone curve 1 +!TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L* (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of J or Q after CIECAM02.\n\nJ and Q are not shown in the main histogram panel.\n\nFor final output refer to the main histogram panel. +!TP_COLORAPP_CURVEEDITOR2;Tone curve 2 +!TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Same usage as with the second exposure tone curve. +!TP_COLORAPP_CURVEEDITOR3;Color curve +!TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Adjust either chroma, saturation or colorfulness.\n\nShows the histogram of chromaticity (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of C, s or M after CIECAM02.\n\nC, s and M are not shown in the main histogram panel.\nFor final output refer to the main histogram panel. +!TP_COLORAPP_DATACIE;CIECAM02 output histograms in curves +!TP_COLORAPP_DATACIE_TOOLTIP;When enabled, histograms in CIECAM02 curves show approximate values/ranges for J or Q, and C, s or M after the CIECAM02 adjustments.\nThis selection does not impact the main histogram panel.\n\nWhen disabled, histograms in CIECAM02 curves show L*a*b* values before CIECAM02 adjustments. +!TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RawTherapee calculates an optimum value, which is then used by CAT02, and also for the entire CIECAM02.\nTo set the value manually, uncheck the check-box first (values above 65 are recommended). +!TP_COLORAPP_DEGREE_TOOLTIP;Amount of CIE Chromatic Adaptation Transform 2002. +!TP_COLORAPP_GAMUT;Gamut control (L*a*b*) +!TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in L*a*b* mode. +!TP_COLORAPP_HUE;Hue (h) +!TP_COLORAPP_HUE_TOOLTIP;Hue (h) - angle between 0° and 360°. +!TP_COLORAPP_LABEL;CIE Color Appearance Model 2002 +!TP_COLORAPP_LABEL_CAM02;Image Adjustments +!TP_COLORAPP_LABEL_SCENE;Scene Conditions +!TP_COLORAPP_LABEL_VIEWING;Viewing Conditions +!TP_COLORAPP_LIGHT;Lightness (J) +!TP_COLORAPP_LIGHT_TOOLTIP;Lightness in CIECAM02 differs from L*a*b* and RGB lightness. +!TP_COLORAPP_MODEL;WP Model +!TP_COLORAPP_MODEL_TOOLTIP;White-Point Model.\n\nWB [RT] + [output]: RT's white balance is used for the scene, CIECAM02 is set to D50, and the output device's white balance is set in Preferences > Color Management.\n\nWB [RT+CAT02] + [output]: RT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences - Color Management. +!TP_COLORAPP_RSTPRO;Red & skin-tones protection +!TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin-tones protection affects both sliders and curves. +!TP_COLORAPP_SHARPCIE;--unused-- +!TP_COLORAPP_SHARPCIE_TOOLTIP;--unused-- +!TP_COLORAPP_SURROUND;Surround +!TP_COLORAPP_SURROUND_AVER;Average +!TP_COLORAPP_SURROUND_DARK;Dark +!TP_COLORAPP_SURROUND_DIM;Dim +!TP_COLORAPP_SURROUND_EXDARK;Extremly Dark (Cutsheet) +!TP_COLORAPP_SURROUND_TOOLTIP;Changes tones and colors to take into account the viewing conditions of the output device.\n\nAverage: Average light environment (standard). The image will not change.\n\nDim: Dim environment (TV). The image will become slighty dark.\n\nDark: Dark environment (projector). The image will become more dark.\n\nExtremly Dark: Extremly dark environment (cutsheet). The image will become very dark. +!TP_COLORAPP_SURSOURCE;Dark surround +!TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if image has a dark border. +!TP_COLORAPP_TCMODE_BRIGHTNESS;Brightness +!TP_COLORAPP_TCMODE_CHROMA;Chroma +!TP_COLORAPP_TCMODE_COLORF;Colorfulness +!TP_COLORAPP_TCMODE_LABEL1;Curve mode 1 +!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_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] +!TP_COLORAPP_WBRT;WB [RT] + [output] +!TP_COLORTONING_AB;o C/L +!TP_COLORTONING_AUTOSAT;Automatic +!TP_COLORTONING_BALANCE;Balance +!TP_COLORTONING_BY;o C/L +!TP_COLORTONING_CHROMAC;Opacity +!TP_COLORTONING_COLOR;Color +!TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;Chroma opacity as a function of luminance oC=f(L) +!TP_COLORTONING_HIGHLIGHT;Highlights +!TP_COLORTONING_HUE;Hue +!TP_COLORTONING_LABEL;Color Toning +!TP_COLORTONING_LAB;L*a*b* blending +!TP_COLORTONING_LUMAMODE;Preserve luminance +!TP_COLORTONING_LUMAMODE_TOOLTIP;If enabled, when you change color (red, green, cyan, blue, etc.) the luminance of each pixel is preserved. +!TP_COLORTONING_LUMA;Luminance +!TP_COLORTONING_METHOD;Method +!TP_COLORTONING_METHOD_TOOLTIP;"L*a*b* blending", "RGB sliders" and "RGB curves" use interpolated color blending.\n"Color balance (Shadows/Midtones/Highlights)" and "Saturation 2 colors" use direct colors.\n\nThe Black-and-White tool can be enabled when using any color toning method, which allows for color toning. +!TP_COLORTONING_MIDTONES;Midtones +!TP_COLORTONING_NEUTRAL;Reset sliders +!TP_COLORTONING_NEUTRAL_TIP;Reset all values (Shadows, Midtones, Highlights) to default. +!TP_COLORTONING_OPACITY;Opacity +!TP_COLORTONING_RGBCURVES;RGB - Curves +!TP_COLORTONING_RGBSLIDERS;RGB - Sliders +!TP_COLORTONING_SATURATEDOPACITY;Strength +!TP_COLORTONING_SATURATIONTHRESHOLD;Threshold +!TP_COLORTONING_SA;Saturation Protection +!TP_COLORTONING_SHADOWS;Shadows +!TP_COLORTONING_SPLITCOCO;Color Balance Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITCO;Shadows/Midtones/Highlights +!TP_COLORTONING_SPLITLR;Saturation 2 colors +!TP_COLORTONING_STRENGTH;Strength +!TP_COLORTONING_STR;Strength +!TP_COLORTONING_TWO2;Special chroma '2 colors' +!TP_COLORTONING_TWOALL;Special chroma +!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_GTFRAME;Frame +!TP_CROP_GTGRID;Grid +!TP_CROP_GTHARMMEANS;Harmonic Means +!TP_CROP_GTTRIANGLE1;Golden Triangles 1 +!TP_CROP_GTTRIANGLE2;Golden Triangles 2 +!TP_CROP_PPI;PPI= +!TP_DARKFRAME_AUTOSELECT;Auto-selection +!TP_DARKFRAME_LABEL;Dark-Frame +!TP_DEFRINGE_LABEL;Defringe +!TP_DEFRINGE_RADIUS;Radius +!TP_DEFRINGE_THRESHOLD;Threshold +!TP_DIRPYRDENOISE_33;3×3 strong +!TP_DIRPYRDENOISE_55SOFT;5×5 +!TP_DIRPYRDENOISE_55;5×5 strong +!TP_DIRPYRDENOISE_77;7×7 (slow) +!TP_DIRPYRDENOISE_99;9x9 (very slow) +!TP_DIRPYRDENOISE_ABM;Chroma only +!TP_DIRPYRDENOISE_AUTO;Automatic global +!TP_DIRPYRDENOISE_AUTO_TOOLTIP;Try to evaluate chroma noise\nBe careful, this calculation is average, and is quite subjective ! +!TP_DIRPYRDENOISE_AUT;Automatic global +!TP_DIRPYRDENOISE_BLUE;Chrominance - Blue-Yellow +!TP_DIRPYRDENOISE_C2TYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CCCURVE;Chrominance curve +!TP_DIRPYRDENOISE_CHROMAFR;Chrominance +!TP_DIRPYRDENOISE_CHROMA;Chrominance - Master +!TP_DIRPYRDENOISE_CTYPE;Auto method +!TP_DIRPYRDENOISE_CTYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nAutomatic multi-zones\nNo preview - works only during saving, but using the "Preview" method by matching the tile size and center to the preview size and center you can get an idea of the expected results.\nThe image is divided into tiles (about 10 to 70 depending on image size) and each tile receives its own chrominance noise reduction settings.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +!TP_DIRPYRDENOISE_CURVEEDITOR_CC;Chroma +!TP_DIRPYRDENOISE_CURVEEDITOR_CC_TOOLTIP;Increase (multiply) the value of all chrominance sliders.\nThis curve lets you adjust the strength of chromatic noise reduction as a function of chromaticity, for instance to increase the action in areas of low saturation and to decrease it in those of high saturation. +!TP_DIRPYRDENOISE_CURVEEDITOR_L_TOOLTIP;Modulates action of 'Luminance' denoise +!TP_DIRPYRDENOISE_CUR;Curve +!TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on the gamma of the input color profile. An sRGB gamma is assumed, thus if the image uses an input color profile of a different gamma, the effects of luminance noise reduction will differ. +!TP_DIRPYRDENOISE_ENH;Enhanced mode +!TP_DIRPYRDENOISE_ENH_TOOLTIP;Increases noise reduction quality at the expense of a 20% processing time increase. +!TP_DIRPYRDENOISE_GAMMA;Gamma +!TP_DIRPYRDENOISE_GAMMA_TOOLTIP;Gamma varies noise reduction strength across the range of tones. Smaller values will target shadows, while larger values will stretch the effect to the brighter tones. +!TP_DIRPYRDENOISE_LABEL;Noise Reduction +!TP_DIRPYRDENOISE_LABM;L*a*b* +!TP_DIRPYRDENOISE_LAB;L*a*b* +!TP_DIRPYRDENOISE_LCURVE;Luminance curve +!TP_DIRPYRDENOISE_LDETAIL;Luminance - Detail +!TP_DIRPYRDENOISE_LM;Luminance only +!TP_DIRPYRDENOISE_LPLABM;Weighted L* (little) + a*b* (normal) +!TP_DIRPYRDENOISE_LTYPE;Luminance control +!TP_DIRPYRDENOISE_LUMAFR;Luminance +!TP_DIRPYRDENOISE_LUMAFR_TOOLTIP;Wavelet on luminance and Fourier transform for luminance detail +!TP_DIRPYRDENOISE_LUMA;Luminance +!TP_DIRPYRDENOISE_MANU;Manual +!TP_DIRPYRDENOISE_MAN;Manual +!TP_DIRPYRDENOISE_MEDMETHOD;Median method +!TP_DIRPYRDENOISE_MEDTYPE;Median type +!TP_DIRPYRDENOISE_MED;Median Filter +!TP_DIRPYRDENOISE_MED_TOOLTIP;Enabled median denoising +!TP_DIRPYRDENOISE_METHOD11;Quality +!TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. +!TP_DIRPYRDENOISE_METHOD;Method +!TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or L*a*b* methods can be used.\n\nFor non-raw images the L*a*b* method will be used, regardless of the selection. +!TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. +!TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +!TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - +!TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 +!TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. +!TP_DIRPYRDENOISE_PASSES;Median iterations +!TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +!TP_DIRPYRDENOISE_PON;Auto multi-zones +!TP_DIRPYRDENOISE_PREVLABEL;Preview size=%1, Center: Px=%2 Py=%3 +!TP_DIRPYRDENOISE_PREV;Preview +!TP_DIRPYRDENOISE_PRE;Preview multi-zones +!TP_DIRPYRDENOISE_RED;Chrominance - Red-Green +!TP_DIRPYRDENOISE_RGBM;RGB +!TP_DIRPYRDENOISE_RGB;RGB +!TP_DIRPYRDENOISE_SHALBI;High +!TP_DIRPYRDENOISE_SHAL;Standard +!TP_DIRPYRDENOISE_SLI;Slider +!TP_DIRPYRDENOISE_SOFT;3x3 +!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_LUMAFINEST;Finest +!TP_DIRPYREQUALIZER_LUMANEUTRAL;Neutral +!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_THRESHOLD;Threshold +!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;Auto Distortion Correction +!TP_DISTORTION_AUTO_TIP;Correct lens distortion automatically for some cameras (Micro 4/3, some compact digital cameras, etc.). +!TP_EPD_EDGESTOPPING;Edge stopping +!TP_EPD_GAMMA;Gamma +!TP_EPD_LABEL;Tone Mapping +!TP_EPD_REWEIGHTINGITERATES;Reweighting iterates +!TP_EPD_SCALE;Scale +!TP_EPD_STRENGTH;Strength +!TP_EPD_TOOLTIP;Tone mapping is possible in L*a*b* mode (standard) and CIECAM02 mode.\n\nWhen in L*a*b* mode, tone mapping can also be used on the residual image of the Wavelet Levels tool.\n\nTo engage CIECAM02 tone mapping mode enable the following settings:\n1. CIECAM02\n2. Algorithm="Brightness + Colorfulness (QM)"\n3. "Tone mapping using CIECAM02 brightness (Q)" +!TP_EXPOSURE_AUTOLEVELS_TIP;Toggles execution of Auto Levels to automatically set Exposure slider values based on an image analysis.\nEnables Highlight Reconstruction if necessary. +!TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in Auto Levels operation. +!TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Highlight compression threshold +!TP_EXPOSURE_CURVEEDITOR1;Tone curve 1 +!TP_EXPOSURE_CURVEEDITOR2;Tone curve 2 +!TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Please refer to the "Exposure > Tone Curves" RawPedia article to learn how to achieve the best results by using two tone curves. +!TP_EXPOSURE_SATURATION;Saturation +!TP_EXPOSURE_TCMODE_FILMLIKE;Film-like +!TP_EXPOSURE_TCMODE_LABEL1;Curve mode 1 +!TP_EXPOSURE_TCMODE_LABEL2;Curve mode 2 +!TP_EXPOSURE_TCMODE_LUMINANCE;Luminance +!TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Saturation and Value Blending +!TP_EXPOSURE_TCMODE_STANDARD;Standard +!TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard +!TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points +!TP_EXPOS_WHITEPOINT_LABEL;Raw White Points +!TP_FILMSIMULATION_LABEL;Film Simulation +!TP_FILMSIMULATION_STRENGTH;Strength +!TP_FILMSIMULATION_ZEROCLUTSFOUND;Set HaldCLUT directory in Preferences +!TP_FLATFIELD_AUTOSELECT;Auto-selection +!TP_FLATFIELD_BLURRADIUS;Blur radius +!TP_FLATFIELD_BLURTYPE;Blur type +!TP_FLATFIELD_BT_AREA;Area +!TP_FLATFIELD_BT_HORIZONTAL;Horizontal +!TP_FLATFIELD_BT_VERTHORIZ;Vertical + Horizontal +!TP_FLATFIELD_BT_VERTICAL;Vertical +!TP_FLATFIELD_CLIPCONTROL;Clip control +!TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. +!TP_FLATFIELD_LABEL;Flat-Field +!TP_GAMMA_CURV;Gamma +!TP_GAMMA_FREE;Free gamma +!TP_GAMMA_OUTPUT;Output gamma +!TP_GAMMA_SLOP;Slope (linear) +!TP_GENERAL_11SCALE_TOOLTIP;The effects of this tool are only visible or only accurate at a preview scale of 1:1. +!TP_GRADIENT_CENTER;Center +!TP_GRADIENT_CENTER_X;Center X +!TP_GRADIENT_CENTER_X_TOOLTIP;Shift gradient to the left (negative values) or right (positive values). +!TP_GRADIENT_CENTER_Y;Center Y +!TP_GRADIENT_CENTER_Y_TOOLTIP;Shift gradient up (negative values) or down (positive values). +!TP_GRADIENT_DEGREE;Angle +!TP_GRADIENT_DEGREE_TOOLTIP;Rotation angle in degrees. +!TP_GRADIENT_FEATHER;Feather +!TP_GRADIENT_FEATHER_TOOLTIP;Gradient width in percent of the image diagonal. +!TP_GRADIENT_LABEL;Graduated Filter +!TP_GRADIENT_STRENGTH;Strength +!TP_GRADIENT_STRENGTH_TOOLTIP;Filter strength in stops. +!TP_HLREC_BLEND;Blend +!TP_HLREC_ENA_TOOLTIP;Could be activated by Auto Levels. +!TP_HSVEQUALIZER_CHANNEL;Channel +!TP_HSVEQUALIZER_HUE;H +!TP_HSVEQUALIZER_LABEL;HSV Equalizer +!TP_HSVEQUALIZER_SAT;S +!TP_HSVEQUALIZER_VAL;V +!TP_ICM_BLENDCMSMATRIX;Blend ICC highlights with matrix +!TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover clipped highlights when using LUT-based ICC profiles. +!TP_ICM_DCPILLUMINANT;Illuminant +!TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolated +!TP_ICM_DCPILLUMINANT_TOOLTIP;Select which embedded DCP illuminant to employ. Default is "interpolated" which is a mix between the two based on white balance. The setting is only enabled if a Dual-Illuminant DCP with interpolation support is selected. +!TP_ICM_INPUTCAMERAICC;Auto-matched camera profile +!TP_ICM_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input color profiles. These profiles are more precise than simpler matrix ones. They are not available for all cameras. These profiles are stored in the /iccprofiles/input and /dcpprofiles folders and are automatically retrieved based on a file name matching to the exact model name of the camera. +!TP_ICM_INPUTCAMERA_TOOLTIP;Use a simple color matrix from dcraw, an enhanced RawTherapee version (whichever is available based on camera model) or one embedded in the DNG. +!TP_ICM_INPUTCUSTOM_TOOLTIP;Select your own DCP/ICC color profile file for the camera. +!TP_ICM_INPUTEMBEDDED_TOOLTIP;Use color profile embedded in non-raw files. +!TP_ICM_INPUTNONE;No profile +!TP_ICM_INPUTNONE_TOOLTIP;Use no input color profile at all.\nUse only in special cases. +!TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance +!TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. The result can be used for calibration purposes and generation of a camera profile. +!TP_ICM_TONECURVE;Use DCP's tone curve +!TP_ICM_TONECURVE_TOOLTIP;Employ the embedded DCP tone curve. The setting is only enabled if the selected DCP has a tone curve. +!TP_IMPULSEDENOISE_LABEL;Impulse Noise Reduction +!TP_IMPULSEDENOISE_THRESH;Threshold +!TP_LABCURVE_AVOIDCOLORSHIFT;Avoid color shift +!TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction. +!TP_LABCURVE_BRIGHTNESS;Lightness +!TP_LABCURVE_CHROMATICITY;Chromaticity +!TP_LABCURVE_CHROMA_TOOLTIP;To apply B&W toning, set Chromaticity to -100. +!TP_LABCURVE_CONTRAST;Contrast +!TP_LABCURVE_CURVEEDITOR;Luminance Curve +!TP_LABCURVE_CURVEEDITOR_A_RANGE1;Green Saturated +!TP_LABCURVE_CURVEEDITOR_A_RANGE2;Green Pastel +!TP_LABCURVE_CURVEEDITOR_A_RANGE3;Red Pastel +!TP_LABCURVE_CURVEEDITOR_A_RANGE4;Red Saturated +!TP_LABCURVE_CURVEEDITOR_B_RANGE1;Blue Saturated +!TP_LABCURVE_CURVEEDITOR_B_RANGE2;Blue Pastel +!TP_LABCURVE_CURVEEDITOR_B_RANGE3;Yellow Pastel +!TP_LABCURVE_CURVEEDITOR_B_RANGE4;Yellow Saturated +!TP_LABCURVE_CURVEEDITOR_CC;CC +!TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutral +!TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Dull +!TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastel +!TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Saturated +!TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Chromaticity according to chromaticity C=f(C) +!TP_LABCURVE_CURVEEDITOR_CH;CH +!TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to hue C=f(H) +!TP_LABCURVE_CURVEEDITOR_CL;CL +!TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Chromaticity according to luminance C=f(L) +!TP_LABCURVE_CURVEEDITOR_HH;HH +!TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Hue according to hue H=f(H) +!TP_LABCURVE_CURVEEDITOR_LC;LC +!TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminance according to chromaticity L=f(C) +!TP_LABCURVE_CURVEEDITOR_LH;LH +!TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H) +!TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminance according to luminance L=f(L) +!TP_LABCURVE_LABEL;L*a*b* Adjustments +!TP_LABCURVE_LCREDSK;Restrict LC to red and skin-tones +!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_LENSGEOM_AUTOCROP;Auto-Crop +!TP_LENSGEOM_FILL;Auto-fill +!TP_LENSGEOM_LABEL;Lens / Geometry +!TP_LENSPROFILE_LABEL;Lens Correction Profile +!TP_LENSPROFILE_USECA;Chromatic aberration correction +!TP_LENSPROFILE_USEDIST;Distortion correction +!TP_LENSPROFILE_USEVIGN;Vignetting correction +!TP_NEUTRAL;Neutral +!TP_NEUTRAL_TIP;Resets exposure sliders to neutral values.\nApplies to the same controls that Auto Levels applies to, regardless of whether you used Auto Levels or not. +!TP_PCVIGNETTE_FEATHER;Feather +!TP_PCVIGNETTE_FEATHER_TOOLTIP;Feathering:\n0 = corners only,\n50 = halfway to center,\n100 = to center. +!TP_PCVIGNETTE_LABEL;Vignette Filter +!TP_PCVIGNETTE_ROUNDNESS;Roundness +!TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness:\n0 = rectangle,\n50 = fitted ellipse,\n100 = circle. +!TP_PCVIGNETTE_STRENGTH;Strength +!TP_PCVIGNETTE_STRENGTH_TOOLTIP;Filter strength in stops (reached in corners). +!TP_PERSPECTIVE_HORIZONTAL;Horizontal +!TP_PERSPECTIVE_LABEL;Perspective +!TP_PERSPECTIVE_VERTICAL;Vertical +!TP_PFCURVE_CURVEEDITOR_CH;Hue +!TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Controls defringe strength by color.\nHigher = more,\nLower = less. +!TP_PREPROCESS_DEADPIXFILT;Dead pixel filter +!TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Tries to suppress dead pixels. +!TP_PREPROCESS_GREENEQUIL;Green equilibration +!TP_PREPROCESS_HOTPIXFILT;Hot pixel filter +!TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Tries to suppress hot pixels. +!TP_PREPROCESS_LABEL;Preprocessing +!TP_PREPROCESS_LINEDENOISE;Line noise filter +!TP_PREPROCESS_NO_FOUND;None found +!TP_RAWCACORR_AUTO;Auto-correction +!TP_RAWCACORR_CABLUE;Blue +!TP_RAWCACORR_CARED;Red +!TP_RAWEXPOS_BLACKS;Black Levels +!TP_RAWEXPOS_BLACK_0;Green 1 (lead) +!TP_RAWEXPOS_BLACK_1;Red +!TP_RAWEXPOS_BLACK_2;Blue +!TP_RAWEXPOS_BLACK_3;Green 2 +!TP_RAWEXPOS_BLACK_BLUE;Blue +!TP_RAWEXPOS_BLACK_GREEN;Green +!TP_RAWEXPOS_BLACK_RED;Red +!TP_RAWEXPOS_LINEAR;White-point correction +!TP_RAWEXPOS_PRESER;Highlight preservation +!TP_RAWEXPOS_RGB;Red, Green, Blue +!TP_RAWEXPOS_TWOGREEN;Link greens +!TP_RAW_DCBENHANCE;DCB enhancement +!TP_RAW_DCBITERATIONS;Number of DCB iterations +!TP_RAW_DMETHOD_PROGRESSBAR;%1 demosaicing... +!TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Demosaicing refinement... +!TP_RAW_DMETHOD_TOOLTIP;Note: IGV and LMMSE are dedicated to high ISO images to aid in noise reduction without leading to maze patterns, posterization or a washed-out look. +!TP_RAW_HD;Threshold +!TP_RAW_HD_TOOLTIP;Lower values make hot/dead pixel detection more aggressive, but false positives may lead to artifacts. If you notice any artifacts appearing when enabling the Hot/Dead Pixel Filters, gradually increase the threshold value until they disappear. +!TP_RAW_LABEL;Demosaicing +!TP_RAW_LMMSEITERATIONS;LMMSE enhancement steps +!TP_RAW_LMMSE_TOOLTIP;Adds gamma (step 1), median (steps 2-4) and refinement (steps 5-6) to reduce artifacts and improve the signal-to-noise ratio. +!TP_RAW_SENSOR_BAYER_LABEL;Sensor with Bayer Matrix +!TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;3-pass gives best results (recommended for low ISO images).\n1-pass is almost undistinguishable from 3-pass for high ISO images and is faster. +!TP_RAW_SENSOR_XTRANS_LABEL;Sensor with X-Trans Matrix +!TP_RESIZE_APPLIESTO;Applies to: +!TP_RESIZE_CROPPEDAREA;Cropped Area +!TP_RESIZE_FITBOX;Bounding Box +!TP_RESIZE_FULLIMAGE;Full Image +!TP_RESIZE_HEIGHT;Height +!TP_RESIZE_LANCZOS;Lanczos +!TP_RESIZE_SPECIFY;Specify: +!TP_RESIZE_WIDTH;Width +!TP_RGBCURVES_BLUE;B +!TP_RGBCURVES_CHANNEL;Channel +!TP_RGBCURVES_GREEN;G +!TP_RGBCURVES_LABEL;RGB Curves +!TP_RGBCURVES_LUMAMODE;Luminosity mode +!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_RGBCURVES_RED;R +!TP_SAVEDIALOG_OK_TIP;Shortcut: Ctrl-Enter +!TP_SHADOWSHLIGHTS_SHARPMASK;Sharp mask +!TP_SHARPENEDGE_AMOUNT;Quantity +!TP_SHARPENEDGE_LABEL;Edges +!TP_SHARPENEDGE_PASSES;Iterations +!TP_SHARPENEDGE_THREE;Luminance only +!TP_SHARPENING_TOOLTIP;Expect a slightly different effect when using with CIECAM02. If difference is observed, adjust to taste. +!TP_SHARPENMICRO_AMOUNT;Quantity +!TP_SHARPENMICRO_LABEL;Microcontrast +!TP_SHARPENMICRO_MATRIX;3×3 matrix instead of 5×5 +!TP_SHARPENMICRO_UNIFORMITY;Uniformity +!TP_VIBRANCE_AVOIDCOLORSHIFT;Avoid color shift +!TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Red/Purple +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Red +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Red/Yellow +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Yellow +!TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Hue according to hue H=f(H) +!TP_VIBRANCE_LABEL;Vibrance +!TP_VIBRANCE_PASTELS;Pastel Tones +!TP_VIBRANCE_PASTSATTOG;Link pastel and saturated tones +!TP_VIBRANCE_PROTECTSKINS;Protect skin-tones +!TP_VIBRANCE_PSTHRESHOLD;Pastel/saturated tones threshold +!TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Saturation threshold +!TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;The vertical axis represents pastel tones at the bottom and saturated tones at the top.\nThe horizontal axis represents the saturation range. +!TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Pastel/saturated transition's weighting +!TP_VIBRANCE_SATURATED;Saturated Tones +!TP_VIGNETTING_CENTER;Center +!TP_VIGNETTING_CENTER_X;Center X +!TP_VIGNETTING_CENTER_Y;Center Y +!TP_VIGNETTING_STRENGTH;Strength +!TP_WAVELET_1;Level 1 +!TP_WAVELET_2;Level 2 +!TP_WAVELET_3;Level 3 +!TP_WAVELET_4;Level 4 +!TP_WAVELET_5;Level 5 +!TP_WAVELET_6;Level 6 +!TP_WAVELET_7;Level 7 +!TP_WAVELET_8;Level 8 +!TP_WAVELET_9;Level 9 +!TP_WAVELET_ALL;All levels in all directions +!TP_WAVELET_APPLYTO;Apply To +!TP_WAVELET_AVOID;Avoid color shift +!TP_WAVELET_B0;Black +!TP_WAVELET_B1;Grey +!TP_WAVELET_B2;Residual +!TP_WAVELET_BACUR;Curve +!TP_WAVELET_BALANCE;Contrast balance d/v-h +!TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chromaticity or residual tone mapping are activated, the effect due to balance is amplified. +!TP_WAVELET_BALCHRO;Chroma balance +!TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chromaticity balance. +!TP_WAVELET_BANONE;None +!TP_WAVELET_BASLI;Slider +!TP_WAVELET_BATYPE;Contrast balance method +!TP_WAVELET_CCURVE;Local contrast +!TP_WAVELET_CH1;Whole chromaticity range +!TP_WAVELET_CH2;Saturated/pastel +!TP_WAVELET_CH3;Link contrast levels +!TP_WAVELET_CHCU;Curve +!TP_WAVELET_CHRO;Saturated/pastel threshold +!TP_WAVELET_CHRO_TOOLTIP;Sets the wavelet level which will be the threshold between saturated and pastel colors.\n1-x: saturated\nx-9: pastel\n\nIf the value exceeds the amount of wavelet levels you are using then it will be ignored. +!TP_WAVELET_CHR;Chroma-contrast link strength +!TP_WAVELET_CHR_TOOLTIP;Adjusts chromaticity as a function of "contrast levels" and "chroma-contrast link strength" +!TP_WAVELET_CHSL;Sliders +!TP_WAVELET_CHTYPE;Chrominance method +!TP_WAVELET_COLORT;Opacity Red-Green +!TP_WAVELET_COMBOTH;Both +!TP_WAVELET_COMPCONT;Contrast +!TP_WAVELET_COMPGAMMA;Compression gamma +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjusting the gamma of the residual image allow you to equilibrate the data and histogram. +!TP_WAVELET_COMPGAMMA_TOOLTIP;Adjust gamma for residual image and compression.\nAllow to equilibrate data and histogram +!TP_WAVELET_COMPTM;Tone mapping +!TP_WAVELET_CONTEDIT;'After' Contrast curve +!TP_WAVELET_CONTEDIT;'After' contrast curve +!TP_WAVELET_CONTRAST_MINUS;Contrast - +!TP_WAVELET_CONTRAST_PLUS;Contrast + +!TP_WAVELET_CONTRA;Contrast +!TP_WAVELET_CONTRA_TOOLTIP;Changes contrast of the residual image. +!TP_WAVELET_CONTR;Gamut +!TP_WAVELET_CTYPE;Chrominance control +!TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modifies local contrast as a function of the original local contrast (absciss)\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 100..300)\n66% absciss represents standard deviation of local contrast (real value about 300..800)\n100% represents maximum (real value about 3000..8000) +!TP_WAVELET_CURVEEDITOR_CH;Contrast levels=f(Hue) +!TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modifies each level's contrast as a function oh hue.\nTake care not to overwrite changes made with the Gamut Hue controls.\nThe curve will only have an effect when wavelet contrast level sliders are non-zero. +!TP_WAVELET_CURVEEDITOR_CL;L +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Applies a final contrast luminance curve at the end of the wavelet treatment. +!TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Apply a contrast luminance curve at the end of wavelet level threatment +!TP_WAVELET_CURVEEDITOR_HH;HH +!TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modifies the residual image's hue as a function of hue. +!TP_WAVELET_DALL;All directions +!TP_WAVELET_DAUB;Edge performance +!TP_WAVELET_DAUB_TOOLTIP;Changes Daubechies coefficients:\nD4 = Standard,\nD14 = Often best performance, 10% more time-intensive.\n\nAffects edge detection as well as the general quality of the firsts levels. However the quality is not strictly related to this coefficient and can vary with images and uses. +!TP_WAVELET_DISP;Preview Settings +!TP_WAVELET_DONE;Vertical +!TP_WAVELET_DTHR;Diagonal +!TP_WAVELET_DTWO;Horizontal +!TP_WAVELET_EDCU;Curve +!TP_WAVELET_EDGCONT;Local contrast +!TP_WAVELET_EDGCONT_TOOLTIP;Adjusting the points to the left decreases contrast, and to the right increases it.\nBottom-left, Top-Left, Top-Right, Bottom-right represent respectively local contast for low values, mean, mean+stdev, maxima +!TP_WAVELET_EDGEDETECTTHR2;Threshold high (detection) +!TP_WAVELET_EDGEDETECTTHR;Threshold low (noise) +!TP_WAVELET_EDGEDETECTTHR_TOOLTIP;This adjuster lets you target edge detection for example to avoid applying edge sharpness to fine details, such as noise in the sky. +!TP_WAVELET_EDGEDETECT;Gradient sensitivity +!TP_WAVELET_EDGEDETECT_TOOLTIP;Moving the slider to the right increases edge sensitivity. This affects local contrast, edge settings and noise. +!TP_WAVELET_EDGE;Edge Sharpness +!TP_WAVELET_EDGREINF_TOOLTIP;Reinforce or reduce the action of the first level, do the opposite to the second level, and leave the rest unchanged. +!TP_WAVELET_EDGTHRESH;Detail +!TP_WAVELET_EDGTHRESH_TOOLTIP;Change the repartition between the first levels and the others. The higher the threshold the more the action is centred on the first levels. Be careful with negative values, they increase the action of high levels and can introduce artifacts. +!TP_WAVELET_EDRAD;Radius +!TP_WAVELET_EDRAD_TOOLTIP;This radius adjustment is very different from those in other sharpening tools. Its value is compared to each level through a complex function. In this sense, a value of zero still has an effect. +!TP_WAVELET_EDSL;Threshold Sliders +!TP_WAVELET_EDTYPE;Local contrast method +!TP_WAVELET_EDVAL;Strength +!TP_WAVELET_FINAL;Final Touchup +!TP_WAVELET_FINEST;Finest +!TP_WAVELET_HIGHLIGHT;Highlight luminance range +!TP_WAVELET_HS1;Whole luminance range +!TP_WAVELET_HS2;Shadows/Highlights +!TP_WAVELET_HUESKIN;Skin hue +!TP_WAVELET_HUESKIN_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_HUESKY;Sky hue +!TP_WAVELET_HUESKY_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +!TP_WAVELET_INF;Below or equal the level +!TP_WAVELET_ITER;Delta balance levels +!TP_WAVELET_ITER_TOOLTIP;Left: increase low levels and reduce high levels,\nRight: reduce low levels and increase high levels. +!TP_WAVELET_LABEL;Wavelet levels +!TP_WAVELET_LARGEST;Coarsest +!TP_WAVELET_LEVCH;Chromaticity +!TP_WAVELET_LEVELS;Wavelet levels +!TP_WAVELET_LEVELS_TOOLTIP;Choose the number of detail levels the image is to be decomposed into. More levels require more RAM and require a longer processing time. +!TP_WAVELET_LEVF;Contrast +!TP_WAVELET_LEVLABEL;Preview maximum possible levels = %1 +!TP_WAVELET_LEVONE;Level 2 +!TP_WAVELET_LEVTWO;Level 3 +!TP_WAVELET_LEVZERO;Level 1 +!TP_WAVELET_LINKEDG;Link with Edge Sharpness' Strength +!TP_WAVELET_LIPST;Enhanced algorithm +!TP_WAVELET_LIPST_TOOLTIP;This algorithm uses Lipschitz regularity to increase edge detection quality at a cost of increased processing time and memory requirements. +!TP_WAVELET_LOWLIGHT;Shadow luminance range +!TP_WAVELET_MEDGREINF;First level +!TP_WAVELET_MEDILEV;Edge detection +!TP_WAVELET_MEDI;Reduce artifacts in blue sky +!TP_WAVELET_NEUTRAL;Neutral +!TP_WAVELET_NOISE;Denoise and Refine +!TP_WAVELET_NOIS;Denoise +!TP_WAVELET_ONE;One level +!TP_WAVELET_OPACITYWL;Final local contrast +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify final local contrast in function of last local contrast (absciss) for all levels decomposition\nTake into account: \na)contrast levels \nb)edge sharpness \nc)contrast balance\nd)decomposition-recomposition\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 200..1000)\n66% absciss represents standard deviation of local contrast (real value about 1000..2000)\n100% represents maximum (real value about 5000..13000) +!TP_WAVELET_OPACITYWL_TOOLTIP;Modify the final local contrast at the end of the wavelet treatment.\n\nThe left side represents the smallest local contrast, progressing to the largest local contrast on the right. +!TP_WAVELET_OPACITYW;Contrast balance d/v-h curve +!TP_WAVELET_OPACITY;Opacity Blue-Yellow +!TP_WAVELET_PASTEL;Pastel chromaticity +!TP_WAVELET_PREVIEWBACK;Background +!TP_WAVELET_PREVIEWLEVELS;Preview +!TP_WAVELET_RE1;Reinforced +!TP_WAVELET_RE2;Unchanged +!TP_WAVELET_RE3;Reduced +!TP_WAVELET_RESCHRO;Chromaticity +!TP_WAVELET_RESCONH;Highlights +!TP_WAVELET_RESCON;Shadows +!TP_WAVELET_RESID;Residual image +!TP_WAVELET_SAT;Saturated chromaticity +!TP_WAVELET_SETTINGS;Wavelet Settings +!TP_WAVELET_SKIN;Skin targetting/protection +!TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected. +!TP_WAVELET_SKY;Sky targetting/protection +!TP_WAVELET_SKY_TOOLTIP;At -100 sky-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 sky-tones are protected while all other tones are affected. +!TP_WAVELET_STRENGTH;Strength +!TP_WAVELET_STREN;Strength +!TP_WAVELET_SUPE;Extra +!TP_WAVELET_SUP;Above the level +!TP_WAVELET_THRESHOLD2;Shadow levels +!TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels between 9 and 9 minus the value will be affected by the shadow luminance range. Other levels will be fully treated. The highest level possible is limited by the highlight level value (9 minus highlight level value). +!TP_WAVELET_THRESHOLD;Highlight levels +!TP_WAVELET_THRESHOLD_TOOLTIP;Only levels beyond the chosen value will be affected by the highlight luminance range. Other levels will be fully treated. The chosen value here limits the highest possible value of the shadow levels. +!TP_WAVELET_THRH;Highlights threshold +!TP_WAVELET_THR;Shadows threshold +!TP_WAVELET_TILESBIG;Big tiles +!TP_WAVELET_TILESFULL;Full image +!TP_WAVELET_TILESIZE;Tiling method +!TP_WAVELET_TILESLIT;Little tiles +!TP_WAVELET_TILES_TOOLTIP;Processing the full image leads to better quality and is the recommended option, while using tiles is a fall-back solution for users with little RAM. Refer to RawPedia for memory requirements. +!TP_WAVELET_TMHIGH;High +!TP_WAVELET_TMLOWHIGH;Low+High +!TP_WAVELET_TMNONE;None +!TP_WAVELET_TMSTD;Standard +!TP_WAVELET_TMSTRENGTH;Compression strength +!TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image. When the value is different from 0, the Strength and Gamma sliders of the Tone Mapping tool in the Exposure tab will become grayed out. +!TP_WAVELET_TMTYPE;Compression method +!TP_WAVELET_TON;Toning +!TP_WAVELET_daub2;D2 - low +!TP_WAVELET_daub4;D4 - standard +!TP_WAVELET_daub6;D6 - standard plus +!TP_WAVELET_daub10;D10 - medium +!TP_WAVELET_daub14;D14 - high +!TP_WBALANCE_CLOUDY;Cloudy +!TP_WBALANCE_DAYLIGHT;Daylight (sunny) +!TP_WBALANCE_EQBLUERED;Blue/Red equalizer +!TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behavior of "white balance" by modulating the blue/red balance.\nThis can be useful when shooting conditions:\na) are far from the standard illuminant (e.g. underwater),\nb) are far from conditions where calibrations were performed,\nc) where the matrices or ICC profiles are unsuitable. +!TP_WBALANCE_FLASH55;Leica +!TP_WBALANCE_FLASH60;Standard, Canon, Pentax, Olympus +!TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta +!TP_WBALANCE_FLASH_HEADER;Flash +!TP_WBALANCE_FLUO1;F1 - Daylight +!TP_WBALANCE_FLUO2;F2 - Cool White +!TP_WBALANCE_FLUO3;F3 - White +!TP_WBALANCE_FLUO4;F4 - Warm White +!TP_WBALANCE_FLUO5;F5 - Daylight +!TP_WBALANCE_FLUO6;F6 - Lite White +!TP_WBALANCE_FLUO7;F7 - D65 Daylight Simulator +!TP_WBALANCE_FLUO8;F8 - D50 / Sylvania F40 Design +!TP_WBALANCE_FLUO9;F9 - Cool White Deluxe +!TP_WBALANCE_FLUO10;F10 - Philips TL85 +!TP_WBALANCE_FLUO11;F11 - Philips TL84 +!TP_WBALANCE_FLUO12;F12 - Philips TL83 +!TP_WBALANCE_FLUO_HEADER;Fluorescent +!TP_WBALANCE_GTI;GTI +!TP_WBALANCE_HMI;HMI +!TP_WBALANCE_JUDGEIII;JudgeIII +!TP_WBALANCE_LAMP_HEADER;Lamp +!TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 +!TP_WBALANCE_LED_HEADER;LED +!TP_WBALANCE_LED_LSI;LSI Lumelex 2040 +!TP_WBALANCE_SHADE;Shade +!TP_WBALANCE_SOLUX35;Solux 3500K +!TP_WBALANCE_SOLUX41;Solux 4100K +!TP_WBALANCE_SOLUX47;Solux 4700K (vendor) +!TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) +!TP_WBALANCE_TUNGSTEN;Tungsten +!TP_WBALANCE_WATER1;UnderWater 1 +!TP_WBALANCE_WATER2;UnderWater 2 +!TP_WBALANCE_WATER_HEADER;UnderWater +!ZOOMPANEL_100;(100%) +!ZOOMPANEL_NEWCROPWINDOW;Open (new) detail window +!ZOOMPANEL_ZOOM100;Zoom to 100%\nShortcut: z +!ZOOMPANEL_ZOOMFITCROPSCREEN;Fit crop to screen\nShortcut: Alt-f +!ZOOMPANEL_ZOOMFITSCREEN;Fit whole image to screen\nShortcut: f +!ZOOMPANEL_ZOOMIN;Zoom In\nShortcut: + +!ZOOMPANEL_ZOOMOUT;Zoom Out\nShortcut: - diff --git a/rtdata/languages/default b/rtdata/languages/default new file mode 100644 index 000000000..186f0755c --- /dev/null +++ b/rtdata/languages/default @@ -0,0 +1,1885 @@ +#00 default translation file +#01 Developers should add translations to this file and then run the 'generateTranslationDiffs' Bash script to update other locales. +#02 Translators please append a comment with the date of translation and your name(s) as used in the RawTherapee forum or Google Code project to the top of your translation, e.g.: +#03 2525-12-24 Zager and Evans +ABOUT_TAB_BUILD;Version +ABOUT_TAB_CREDITS;Credits +ABOUT_TAB_LICENSE;License +ABOUT_TAB_RELEASENOTES;Release Notes +ABOUT_TAB_SPLASH;Splash +ADJUSTER_RESET_TO_DEFAULT;Reset to default +BATCHQUEUE_AUTOSTART;Auto-start +BATCHQUEUE_DESTFILENAME;Path and file name +BATCH_PROCESSING;Batch Processing +CURVEEDITOR_AXIS_IN;I: +CURVEEDITOR_AXIS_LEFT_TAN;LT: +CURVEEDITOR_AXIS_OUT;O: +CURVEEDITOR_AXIS_RIGHT_TAN;RT: +CURVEEDITOR_CURVES;Curves +CURVEEDITOR_CURVE;Curve +CURVEEDITOR_CUSTOM;Custom +CURVEEDITOR_DARKS;Darks +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_HIGHLIGHTS;Highlights +CURVEEDITOR_LIGHTS;Lights +CURVEEDITOR_LINEAR;Linear +CURVEEDITOR_LOADDLGLABEL;Load curve... +CURVEEDITOR_MINMAXCPOINTS;Equalizer +CURVEEDITOR_NURBS;Control cage +CURVEEDITOR_PARAMETRIC;Parametric +CURVEEDITOR_SAVEDLGLABEL;Save curve... +CURVEEDITOR_SHADOWS;Shadows +CURVEEDITOR_TOOLTIPCOPY;Copy current curve to clipboard. +CURVEEDITOR_TOOLTIPLINEAR;Reset curve to linear. +CURVEEDITOR_TOOLTIPLOAD;Load a curve from file. +CURVEEDITOR_TOOLTIPPASTE;Paste curve from clipboard. +CURVEEDITOR_TOOLTIPSAVE;Save current curve. +CURVEEDITOR_TYPE;Type: +DIRBROWSER_FOLDERS;Folders +EDITWINDOW_TITLE;Image Edit +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_APERTURE;Aperture +EXIFFILTER_CAMERA;Camera +EXIFFILTER_EXPOSURECOMPENSATION;Exposure compensation (EV) +EXIFFILTER_FILETYPE;File type +EXIFFILTER_FOCALLEN;Focal length +EXIFFILTER_ISO;ISO +EXIFFILTER_LENS;Lens +EXIFFILTER_METADATAFILTER;Enable metadata filters +EXIFFILTER_SHUTTER;Shutter +EXIFPANEL_ADDEDITHINT;Add new tag or edit tag. +EXIFPANEL_ADDEDIT;Add/Edit +EXIFPANEL_ADDTAGDLG_ENTERVALUE;Enter value +EXIFPANEL_ADDTAGDLG_SELECTTAG;Select tag +EXIFPANEL_ADDTAGDLG_TITLE;Add/Edit Tag +EXIFPANEL_KEEPHINT;Keep the selected tags when writing output file. +EXIFPANEL_KEEP;Keep +EXIFPANEL_REMOVEHINT;Remove the selected tags when writing output file. +EXIFPANEL_REMOVE;Remove +EXIFPANEL_RESETALLHINT;Reset all tags to their original values. +EXIFPANEL_RESETALL;Reset All +EXIFPANEL_RESETHINT;Reset the selected tags to their original values. +EXIFPANEL_RESET;Reset +EXIFPANEL_SUBDIRECTORY;Subdirectory +EXPORT_BYPASS_ALL;Select / Unselect All +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_FF;Bypass [raw] Flat-Field +EXPORT_BYPASS_RAW_GREENTHRESH;Bypass [raw] Green Equilibration +EXPORT_BYPASS_RAW_LINENOISE;Bypass [raw] Line Noise Filter +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_FASTEXPORTOPTIONS;Fast Export Options +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_MAXHEIGHT;Maximum height: +EXPORT_MAXWIDTH;Maximum width: +EXPORT_PUTTOQUEUEFAST; Put to queue for fast export +EXPORT_RAW_DMETHOD;Demosaic method +EXTPROGTARGET_1;raw +EXTPROGTARGET_2;queue-processed +FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... +FILEBROWSER_APPLYPROFILE;Apply +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_CACHECLEARFROMFULL;Clear from cache - full +FILEBROWSER_CACHECLEARFROMPARTIAL;Clear from cache - partial +FILEBROWSER_CACHE;Cache +FILEBROWSER_CLEARPROFILE;Clear +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_COPYPROFILE;Copy +FILEBROWSER_CURRENT_NAME;Current name: +FILEBROWSER_DARKFRAME;Dark-frame +FILEBROWSER_DELETEDLGLABEL;File delete confirmation +FILEBROWSER_DELETEDLGMSGINCLPROC;Are you sure you want to delete the selected %1 files including a queue-processed version? +FILEBROWSER_DELETEDLGMSG;Are you sure you want to delete the selected %1 files? +FILEBROWSER_EMPTYTRASHHINT;Permanently delete the files from trash. +FILEBROWSER_EMPTYTRASH;Empty trash +FILEBROWSER_EXEC_CPB;Custom Profile Builder +FILEBROWSER_EXTPROGMENU;Open with +FILEBROWSER_FLATFIELD;Flat-Field +FILEBROWSER_MOVETODARKFDIR;Move to dark-frames directory +FILEBROWSER_MOVETOFLATFIELDDIR;Move to flat-fields directory +FILEBROWSER_NEW_NAME;New name: +FILEBROWSER_OPENDEFAULTVIEWER;Windows default viewer (queue-processed) +FILEBROWSER_PARTIALPASTEPROFILE;Paste - partial +FILEBROWSER_PASTEPROFILE;Paste +FILEBROWSER_POPUPCANCELJOB;Cancel job +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_POPUPCOLORLABEL;Color label +FILEBROWSER_POPUPCOPYTO;Copy to... +FILEBROWSER_POPUPFILEOPERATIONS;File operations +FILEBROWSER_POPUPMOVEEND;Move to end of queue +FILEBROWSER_POPUPMOVEHEAD;Move to head of queue +FILEBROWSER_POPUPMOVETO;Move to... +FILEBROWSER_POPUPOPENINEDITOR;Open in Editor +FILEBROWSER_POPUPOPEN;Open +FILEBROWSER_POPUPPROCESSFAST;Put to queue (Fast export) +FILEBROWSER_POPUPPROCESS;Put to queue +FILEBROWSER_POPUPPROFILEOPERATIONS;Processing profile operations +FILEBROWSER_POPUPRANK0;Unrank +FILEBROWSER_POPUPRANK1;Rank 1 * +FILEBROWSER_POPUPRANK2;Rank 2 ** +FILEBROWSER_POPUPRANK3;Rank 3 *** +FILEBROWSER_POPUPRANK4;Rank 4 **** +FILEBROWSER_POPUPRANK5;Rank 5 ***** +FILEBROWSER_POPUPRANK;Rank +FILEBROWSER_POPUPREMOVEINCLPROC;Delete with output from queue +FILEBROWSER_POPUPREMOVE;Delete +FILEBROWSER_POPUPRENAME;Rename +FILEBROWSER_POPUPSELECTALL;Select all +FILEBROWSER_POPUPTRASH;Move to trash +FILEBROWSER_POPUPUNRANK;Unrank +FILEBROWSER_POPUPUNTRASH;Remove from trash +FILEBROWSER_QUERYBUTTONHINT;Clear the Find query +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_QUERYLABEL; Find: +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_RENAMEDLGLABEL;Rename file +FILEBROWSER_RENAMEDLGMSG;Rename file "%1" to: +FILEBROWSER_SELECTDARKFRAME;Select dark-frame... +FILEBROWSER_SELECTFLATFIELD;Select flat-field... +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 +FILEBROWSER_SHOWCOLORLABEL4HINT;Show images labeled Blue.\nShortcut: Alt-4 +FILEBROWSER_SHOWCOLORLABEL5HINT;Show images labeled Purple.\nShortcut: Alt-5 +FILEBROWSER_SHOWDIRHINT;Clear all filters.\nShortcut: d +FILEBROWSER_SHOWEDITEDHINT;Show edited images.\nShortcut: 7 +FILEBROWSER_SHOWEDITEDNOTHINT;Show not edited images.\nShortcut: 6 +FILEBROWSER_SHOWEXIFINFO;Show Exif info.\n\nShortcuts:\ni - Multiple Editor Tabs Mode,\nAlt-i - Single Editor Tab Mode. +FILEBROWSER_SHOWNOTTRASHHINT;Show only non-deleted images. +FILEBROWSER_SHOWRANK1HINT;Show images ranked as 1-star.\nShortcut: 1 +FILEBROWSER_SHOWRANK2HINT;Show images ranked as 2-star.\nShortcut: 2 +FILEBROWSER_SHOWRANK3HINT;Show images ranked as 3-star.\nShortcut: 3 +FILEBROWSER_SHOWRANK4HINT;Show images ranked as 4-star.\nShortcut: 4 +FILEBROWSER_SHOWRANK5HINT;Show images ranked as 5-star.\nShortcut: 5 +FILEBROWSER_SHOWRECENTLYSAVEDHINT;Show saved images.\nShortcut: Alt-7 +FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT;Show unsaved images.\nShortcut: Alt-6 +FILEBROWSER_SHOWTRASHHINT;Show contents of trash.\nShortcut: Ctrl-t +FILEBROWSER_SHOWUNCOLORHINT;Show images without a color label.\nShortcut: Alt-0 +FILEBROWSER_SHOWUNRANKHINT;Show unranked images.\nShortcut: 0 +FILEBROWSER_STARTPROCESSINGHINT;Start processing the images in the queue.\n\nShortcut: Ctrl+s +FILEBROWSER_STARTPROCESSING;Start processing +FILEBROWSER_STOPPROCESSINGHINT;Stop processing the images in the queue.\n\nShortcut: Ctrl+s +FILEBROWSER_STOPPROCESSING;Stop processing +FILEBROWSER_THUMBSIZE;Thumbnail size +FILEBROWSER_TOOLTIP_STOPPROCESSING;Start processing automatically when a new job arrives. +FILEBROWSER_UNRANK_TOOLTIP;Unrank.\nShortcut: Shift-0 +FILEBROWSER_ZOOMINHINT;Increase thumbnail size.\n\nShortcuts:\n+ - Multiple Editor Tabs Mode,\nAlt-+ - Single Editor Tab Mode. +FILEBROWSER_ZOOMOUTHINT;Decrease thumbnail size.\n\nShortcuts:\n- - Multiple Editor Tabs Mode,\nAlt-- - Single Editor Tab Mode. +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_ABOUT;About +GENERAL_AFTER;After +GENERAL_ASIMAGE;As Image +GENERAL_AUTO;Automatic +GENERAL_BEFORE;Before +GENERAL_CANCEL;Cancel +GENERAL_CLOSE;Close +GENERAL_DISABLED;Disabled +GENERAL_DISABLE;Disable +GENERAL_ENABLED;Enabled +GENERAL_ENABLE;Enable +GENERAL_FILE;File +GENERAL_LANDSCAPE;Landscape +GENERAL_NA;n/a +GENERAL_NONE;None +GENERAL_NO;No +GENERAL_OK;OK +GENERAL_PORTRAIT;Portrait +GENERAL_SAVE;Save +GENERAL_UNCHANGED;(Unchanged) +GENERAL_WARNING;Warning +HISTOGRAM_TOOLTIP_BAR;Show/Hide RGB indicator bar.\nRight-click on image preview to freeze/unfreeze. +HISTOGRAM_TOOLTIP_B;Show/Hide blue histogram. +HISTOGRAM_TOOLTIP_CHRO;Show/Hide chromaticity histogram. +HISTOGRAM_TOOLTIP_FULL;Toggle full (off) or scaled (on) histogram. +HISTOGRAM_TOOLTIP_G;Show/Hide green histogram. +HISTOGRAM_TOOLTIP_L;Show/Hide CIELab luminance histogram. +HISTOGRAM_TOOLTIP_RAW;Show/Hide raw histogram. +HISTOGRAM_TOOLTIP_R;Show/Hide red histogram. +HISTORY_CHANGED;Changed +HISTORY_CUSTOMCURVE;Custom curve +HISTORY_DELSNAPSHOT;Del +HISTORY_FROMCLIPBOARD;From clipboard +HISTORY_LABEL;History +HISTORY_MSG_1;Photo loaded +HISTORY_MSG_2;PP3 loaded +HISTORY_MSG_3;PP3 changed +HISTORY_MSG_4;History browsing +HISTORY_MSG_5;Exposure - Lightness +HISTORY_MSG_6;Exposure - Contrast +HISTORY_MSG_7;Exposure - Black +HISTORY_MSG_8;Exposure - Compensation +HISTORY_MSG_9;Exposure - Highlight compression +HISTORY_MSG_10;Exposure - Shadow compression +HISTORY_MSG_11;Exposure - Tone curve 1 +HISTORY_MSG_12;Exposure - Auto levels +HISTORY_MSG_13;Exposure - Clip +HISTORY_MSG_14;L*a*b* - Lightness +HISTORY_MSG_15;L*a*b* - Contrast +HISTORY_MSG_16;- +HISTORY_MSG_17;- +HISTORY_MSG_18;- +HISTORY_MSG_19;L*a*b* - L* curve +HISTORY_MSG_20;Sharpening +HISTORY_MSG_21;USM - Radius +HISTORY_MSG_22;USM - Amount +HISTORY_MSG_23;USM - Threshold +HISTORY_MSG_24;USM - Sharpen only edges +HISTORY_MSG_25;USM - Edge detection radius +HISTORY_MSG_26;USM - Edge tolerance +HISTORY_MSG_27;USM - Halo control +HISTORY_MSG_28;USM - Halo control amount +HISTORY_MSG_29;Sharpening - Method +HISTORY_MSG_30;RLD - Radius +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_37;Exposure - Auto levels +HISTORY_MSG_38;White Balance - Method +HISTORY_MSG_39;WB - Temperature +HISTORY_MSG_40;WB - Tint +HISTORY_MSG_41;Exposure - Tone curve 1 mode +HISTORY_MSG_42;Exposure - Tone curve 2 +HISTORY_MSG_43;Exposure - Tone curve 2 mode +HISTORY_MSG_44;Lum. denoising radius +HISTORY_MSG_45;Lum. denoising edge tolerance +HISTORY_MSG_46;Color denoising +HISTORY_MSG_47;Blend ICC highlights with matrix +HISTORY_MSG_48;Use DCP's tone curve +HISTORY_MSG_49;DCP illuminant +HISTORY_MSG_50;Shadows/Highlights +HISTORY_MSG_51;S/H - Highlights +HISTORY_MSG_52;S/H - Shadows +HISTORY_MSG_53;S/H - Highlights tonal width +HISTORY_MSG_54;S/H - Shadows tonal width +HISTORY_MSG_55;S/H - Local contrast +HISTORY_MSG_56;S/H - Radius +HISTORY_MSG_57;Coarse rotation +HISTORY_MSG_58;Horizontal flipping +HISTORY_MSG_59;Vertical flipping +HISTORY_MSG_60;Rotation +HISTORY_MSG_61;Auto-fill +HISTORY_MSG_62;Distortion correction +HISTORY_MSG_63;Snapshot selected +HISTORY_MSG_64;Crop +HISTORY_MSG_65;CA correction +HISTORY_MSG_66;Exposure - Highlight reconstruction +HISTORY_MSG_67;Exposure - HLR amount +HISTORY_MSG_68;Exposure - HLR method +HISTORY_MSG_69;Working color space +HISTORY_MSG_70;Output color space +HISTORY_MSG_71;Input color space +HISTORY_MSG_72;VC - Amount +HISTORY_MSG_73;Channel Mixer +HISTORY_MSG_74;Resize - Scale +HISTORY_MSG_75;Resize - Method +HISTORY_MSG_76;Exif metadata +HISTORY_MSG_77;IPTC metadata +HISTORY_MSG_78;- +HISTORY_MSG_79;Resize - Width +HISTORY_MSG_80;Resize - Height +HISTORY_MSG_81;Resize +HISTORY_MSG_82;Profile changed +HISTORY_MSG_83;S/H - Sharp mask +HISTORY_MSG_84;Perspective correction +HISTORY_MSG_85;LCP +HISTORY_MSG_86;RGB Curves - Luminosity mode +HISTORY_MSG_87;Impulse Noise Reduction +HISTORY_MSG_88;Impulse NR threshold +HISTORY_MSG_89;Noise Reduction +HISTORY_MSG_90;NR - Luminance +HISTORY_MSG_91;NR - Chrominance master +HISTORY_MSG_92;NR - Gamma +HISTORY_MSG_93;CbDL - Value +HISTORY_MSG_94;Contrast by Detail Levels +HISTORY_MSG_95;L*a*b* - Chromaticity +HISTORY_MSG_96;L*a*b* - a* curve +HISTORY_MSG_97;L*a*b* - b* curve +HISTORY_MSG_98;Demosaicing method +HISTORY_MSG_99;Hot pixel filter +HISTORY_MSG_100;Exposure - Saturation +HISTORY_MSG_101;HSV - Hue +HISTORY_MSG_102;HSV - Saturation +HISTORY_MSG_103;HSV - Value +HISTORY_MSG_104;HSV Equalizer +HISTORY_MSG_105;Defringe +HISTORY_MSG_106;Defringe - Radius +HISTORY_MSG_107;Defringe - Threshold +HISTORY_MSG_108;Exposure - HLC threshold +HISTORY_MSG_109;Resize - Bounding box +HISTORY_MSG_110;Resize - Applies to +HISTORY_MSG_111;L*a*b* - Avoid color shift +HISTORY_MSG_112;--unused-- +HISTORY_MSG_113;L*a*b* - Red/skin prot. +HISTORY_MSG_114;DCB iterations +HISTORY_MSG_115;False color suppression +HISTORY_MSG_116;DCB enhancement +HISTORY_MSG_117;Raw CA correction - Red +HISTORY_MSG_118;Raw CA correction - Blue +HISTORY_MSG_119;Line noise filter +HISTORY_MSG_120;Green equilibration +HISTORY_MSG_121;Raw CA Correction - Auto +HISTORY_MSG_122;Dark-Frame - Auto-selection +HISTORY_MSG_123;Dark-Frame - File +HISTORY_MSG_124;White point correction +HISTORY_MSG_125;Highlight preservation +HISTORY_MSG_126;Flat-Field - File +HISTORY_MSG_127;Flat-Field - Auto-selection +HISTORY_MSG_128;Flat-Field - Blur radius +HISTORY_MSG_129;Flat-Field - Blur type +HISTORY_MSG_130;Auto distorion correction +HISTORY_MSG_131;NR - Luma +HISTORY_MSG_132;NR - Chroma +HISTORY_MSG_133;Output gamma +HISTORY_MSG_134;Free gamma +HISTORY_MSG_135;Free gamma +HISTORY_MSG_136;Free gamma slope +HISTORY_MSG_137;Black level - Green 1 +HISTORY_MSG_138;Black level - Red +HISTORY_MSG_139;Black level - Blue +HISTORY_MSG_140;Black level - Green 2 +HISTORY_MSG_141;Black level - Link greens +HISTORY_MSG_142;ES - Iterations +HISTORY_MSG_143;ES - Quantity +HISTORY_MSG_144;Microcontrast - Quantity +HISTORY_MSG_145;Microcontrast - Uniformity +HISTORY_MSG_146;Edge sharpening +HISTORY_MSG_147;ES - Luminance only +HISTORY_MSG_148;Microcontrast +HISTORY_MSG_149;Microcontrast - 3x3 matrix +HISTORY_MSG_150;Post-demosaic artifact/noise red. +HISTORY_MSG_151;Vibrance +HISTORY_MSG_152;Vib - Pastel tones +HISTORY_MSG_153;Vib - Saturated tones +HISTORY_MSG_154;Vib - Protect skin-tones +HISTORY_MSG_155;Vib - Avoid color shift +HISTORY_MSG_156;Vib - Link pastel/saturated +HISTORY_MSG_157;Vib - P/S threshold +HISTORY_MSG_158;TM - Strength +HISTORY_MSG_159;TM - Edge stopping +HISTORY_MSG_160;TM - Scale +HISTORY_MSG_161;TM - Reweighting iterates +HISTORY_MSG_162;Tone Mapping +HISTORY_MSG_163;RGB Curves - Red +HISTORY_MSG_164;RGB Curves - Green +HISTORY_MSG_165;RGB Curves - Blue +HISTORY_MSG_166;Exposure - Neutral +HISTORY_MSG_167;--unused-- +HISTORY_MSG_168;L*a*b* - CC curve +HISTORY_MSG_169;L*a*b* - CH curve +HISTORY_MSG_170;Vibrance - HH curve +HISTORY_MSG_171;L*a*b* - LC curve +HISTORY_MSG_172;L*a*b* - Restrict LC +HISTORY_MSG_173;NR - Luminance detail +HISTORY_MSG_174;CIECAM02 +HISTORY_MSG_175;CAM02 - CAT02 adaptation +HISTORY_MSG_176;CAM02 - Viewing surround +HISTORY_MSG_177;CAM02 - Scene luminosity +HISTORY_MSG_178;CAM02 - Viewing luminosity +HISTORY_MSG_179;CAM02 - White-point model +HISTORY_MSG_180;CAM02 - Lightness (J) +HISTORY_MSG_181;CAM02 - Chroma (C) +HISTORY_MSG_182;CAM02 - Automatic CAT02 +HISTORY_MSG_183;CAM02 - Contrast (J) +HISTORY_MSG_184;CAM02 - Scene surround +HISTORY_MSG_185;CAM02 - Gamut control +HISTORY_MSG_186;CAM02 - Algorithm +HISTORY_MSG_187;CAM02 - Red/skin prot. +HISTORY_MSG_188;CAM02 - Brightness (Q) +HISTORY_MSG_189;CAM02 - Contrast (Q) +HISTORY_MSG_190;CAM02 - Saturation (S) +HISTORY_MSG_191;CAM02 - Colorfulness (M) +HISTORY_MSG_192;CAM02 - Hue (h) +HISTORY_MSG_193;CAM02 - Tone curve 1 +HISTORY_MSG_194;CAM02 - Tone curve 2 +HISTORY_MSG_195;CAM02 - Tone curve 1 +HISTORY_MSG_196;CAM02 - Tone curve 2 +HISTORY_MSG_197;CAM02 - Color curve +HISTORY_MSG_198;CAM02 - Color curve +HISTORY_MSG_199;CAM02 - Output histograms +HISTORY_MSG_200;CAM02 - Tone mapping +HISTORY_MSG_201;NR - Chrominance - R&G +HISTORY_MSG_202;NR - Chrominance - B&Y +HISTORY_MSG_203;NR - Method +HISTORY_MSG_204;LMMSE enhancement steps +HISTORY_MSG_205;CAM02 - Hot/bad pixel filter +HISTORY_MSG_206;CAT02 - Auto scene luminosity +HISTORY_MSG_207;Defringe - Hue curve +HISTORY_MSG_208;WB - B/R equalizer +HISTORY_MSG_210;GF - Angle +HISTORY_MSG_211;Graduated Filter +HISTORY_MSG_212;VF - Strength +HISTORY_MSG_213;Vignette Filter +HISTORY_MSG_214;Black-and-White +HISTORY_MSG_215;B&W - CM - Red +HISTORY_MSG_216;B&W - CM - Green +HISTORY_MSG_217;B&W - CM - Blue +HISTORY_MSG_218;B&W - Gamma - Red +HISTORY_MSG_219;B&W - Gamma - Green +HISTORY_MSG_220;B&W - Gamma - Blue +HISTORY_MSG_221;B&W - Color filter +HISTORY_MSG_222;B&W - Presets +HISTORY_MSG_223;B&W - CM - Orange +HISTORY_MSG_224;B&W - CM - Yellow +HISTORY_MSG_225;B&W - CM - Cyan +HISTORY_MSG_226;B&W - CM - Magenta +HISTORY_MSG_227;B&W - CM - Purple +HISTORY_MSG_228;B&W - Luminance equalizer +HISTORY_MSG_229;B&W - Luminance equalizer +HISTORY_MSG_230;B&W - Mode +HISTORY_MSG_231;B&W - 'Before' curve +HISTORY_MSG_232;B&W - 'Before' curve type +HISTORY_MSG_233;B&W - 'After' curve +HISTORY_MSG_234;B&W - 'After' curve type +HISTORY_MSG_235;B&W - Auto channel mixer +HISTORY_MSG_236;--unused-- +HISTORY_MSG_237;B&W - Mixer +HISTORY_MSG_238;GF - Feather +HISTORY_MSG_239;GF - Strength +HISTORY_MSG_240;GF - Center +HISTORY_MSG_241;VF - Feather +HISTORY_MSG_242;VF - Roundness +HISTORY_MSG_243;VC - Radius +HISTORY_MSG_244;VC - Strength +HISTORY_MSG_245;VC - Center +HISTORY_MSG_246;L*a*b* - CL curve +HISTORY_MSG_247;L*a*b* - LH curve +HISTORY_MSG_248;L*a*b* - HH curve +HISTORY_MSG_249;CbDL - Threshold +HISTORY_MSG_250;NR - Enhanced +HISTORY_MSG_251;B&W - Algorithm +HISTORY_MSG_252;CbDL - Skin tar/prot +HISTORY_MSG_253;CbDL - Reduce artifacts +HISTORY_MSG_254;CbDL - Skin hue +HISTORY_MSG_255;NR - Median filter +HISTORY_MSG_256;NR - Median type +HISTORY_MSG_257;Color Toning +HISTORY_MSG_258;CT - Color curve +HISTORY_MSG_259;CT - Opacity curve +HISTORY_MSG_260;CT - a*[b*] opacity +HISTORY_MSG_261;CT - Method +HISTORY_MSG_262;CT - b* opacity +HISTORY_MSG_263;CT - Shadows - Red +HISTORY_MSG_264;CT - Shadows - Green +HISTORY_MSG_265;CT - Shadows - Blue +HISTORY_MSG_266;CT - Mid - Red +HISTORY_MSG_267;CT - Mid - Green +HISTORY_MSG_268;CT - Mid - Blue +HISTORY_MSG_269;CT - High - Red +HISTORY_MSG_270;CT - High - Green +HISTORY_MSG_271;CT - High - Blue +HISTORY_MSG_272;CT - Balance +HISTORY_MSG_273;CT - Reset +HISTORY_MSG_274;CT - Sat. Shadows +HISTORY_MSG_275;CT - Sat. Highlights +HISTORY_MSG_276;CT - Opacity +HISTORY_MSG_277;--unused-- +HISTORY_MSG_278;CT - Preserve luminance +HISTORY_MSG_279;CT - Shadows +HISTORY_MSG_280;CT - Highlights +HISTORY_MSG_281;CT - Sat. strength +HISTORY_MSG_282;CT - Sat. threshold +HISTORY_MSG_283;CT - Strength +HISTORY_MSG_284;CT - Auto sat. protection +HISTORY_MSG_285;NR - Median - Method +HISTORY_MSG_286;NR - Median - Type +HISTORY_MSG_287;NR - Median - Iterations +HISTORY_MSG_288;Flat Field - Clip control +HISTORY_MSG_289;Flat Field - Clip control - Auto +HISTORY_MSG_290;Black Level - Red +HISTORY_MSG_291;Black Level - Green +HISTORY_MSG_292;Black Level - Blue +HISTORY_MSG_293;Film Simulation +HISTORY_MSG_294;Film Simulation - Strength +HISTORY_MSG_295;Film Simulation - Film +HISTORY_MSG_296;NR - Luminance curve +HISTORY_MSG_297;NR - Quality +HISTORY_MSG_298;Dead pixel filter +HISTORY_MSG_299;NR - Chrominance curve +HISTORY_MSG_300;- +HISTORY_MSG_301;NR - Luma control +HISTORY_MSG_302;NR - Chroma method +HISTORY_MSG_303;NR - Chroma method +HISTORY_MSG_304;W - Contrast levels +HISTORY_MSG_305;Wavelet Levels +HISTORY_MSG_306;W - Process +HISTORY_MSG_307;W - Process +HISTORY_MSG_308;W - Process direction +HISTORY_MSG_309;W - ES - Detail +HISTORY_MSG_310;W - Residual - Sky tar/prot +HISTORY_MSG_311;W - Wavelet levels +HISTORY_MSG_312;W - Residual - Shadows threshold +HISTORY_MSG_313;W - Chroma - Sat/past +HISTORY_MSG_314;W - Gamut - Reduce artifacts +HISTORY_MSG_315;W - Residual - Contrast +HISTORY_MSG_316;W - Gamut - Skin tar/prot +HISTORY_MSG_317;W - Gamut - Skin hue +HISTORY_MSG_318;W - Contrast - Highlight levels +HISTORY_MSG_319;W - Contrast - Highlight range +HISTORY_MSG_320;W - Contrast - Shadow range +HISTORY_MSG_321;W - Contrast - Shadow levels +HISTORY_MSG_322;W - Gamut - Avoid color shift +HISTORY_MSG_323;W - ES - Local contrast +HISTORY_MSG_324;W - Chroma - Pastel +HISTORY_MSG_325;W - Chroma - Saturated +HISTORY_MSG_326;W - Chroma - Method +HISTORY_MSG_327;W - Contrast - Apply to +HISTORY_MSG_328;W - Chroma - Link strength +HISTORY_MSG_329;W - Toning - Opacity RG +HISTORY_MSG_330;W - Toning - Opacity BY +HISTORY_MSG_331;W - Contrast levels - Extra +HISTORY_MSG_332;W - Tiling method +HISTORY_MSG_333;W - Residual - Shadows +HISTORY_MSG_334;W - Residual - Chroma +HISTORY_MSG_335;W - Residual - Highlights +HISTORY_MSG_336;W - Residual - Highlights threshold +HISTORY_MSG_337;W - Residual - Sky hue +HISTORY_MSG_338;W - ES - Radius +HISTORY_MSG_339;W - ES - Strength +HISTORY_MSG_340;W - Strength +HISTORY_MSG_341;W - Edge performance +HISTORY_MSG_342;W - ES - First level +HISTORY_MSG_343;W - Chroma levels +HISTORY_MSG_344;W - Meth chroma sl/cur +HISTORY_MSG_345;W - ES - Local contrast +HISTORY_MSG_346;W - ES - Local contrast method +HISTORY_MSG_347;W - Denoise - Level 0 +HISTORY_MSG_348;W - Denoise - Level 1 +HISTORY_MSG_349;W - Denoise - Level 2 +HISTORY_MSG_350;W - ES - Edge detection +HISTORY_MSG_351;W - Residual - HH curve +HISTORY_MSG_352;W - Background +HISTORY_MSG_353;W - ES - Gradient sensitivity +HISTORY_MSG_354;W - ES - Enhance +HISTORY_MSG_355;W - ES - Threshold low +HISTORY_MSG_356;W - ES - Threshold high +HISTORY_MSG_357;W - Denoise - Link with ES +HISTORY_MSG_358;W - Gamut - CH +HISTORY_MSG_359;Hot/Dead - Threshold +HISTORY_MSG_360;TM Gamma +HISTORY_MSG_361;W - Final - Chroma balance +HISTORY_MSG_362;W - Residual - Compression method +HISTORY_MSG_363;W - Residual - Compression strength +HISTORY_MSG_364;W - Final - Contrast balance +HISTORY_MSG_365;W - Final - Delta balance +HISTORY_MSG_366;W - Residual - Compression gamma +HISTORY_MSG_367;W - ES - Local contrast curve +HISTORY_MSG_368;W - Final - Contrast balance +HISTORY_MSG_369;W - Final - Balance method +HISTORY_MSG_370;W - Final - Local contrast curve +HISTORY_MSG_371;Post-Resize Sharpening +HISTORY_MSG_372;PRS USM - Radius +HISTORY_MSG_373;PRS USM - Amount +HISTORY_MSG_374;PRS USM - Threshold +HISTORY_MSG_375;PRS USM - Sharpen only edges +HISTORY_MSG_376;PRS USM - Edge detection radius +HISTORY_MSG_377;PRS USM - Edge tolerance +HISTORY_MSG_378;PRS USM - Halo control +HISTORY_MSG_379;PRS USM - Halo control amount +HISTORY_MSG_380;PRS - Method +HISTORY_MSG_381;PRS RLD - Radius +HISTORY_MSG_382;PRS RLD - Amount +HISTORY_MSG_383;PRS RLD - Damping +HISTORY_MSG_384;PRS RLD - Iterations +HISTORY_MSG_385;W - Residual - Color Balance +HISTORY_MSG_386;W - Residual - CB green high +HISTORY_MSG_387;W - Residual - CB blue high +HISTORY_MSG_388;W - Residual - CB green mid +HISTORY_MSG_389;W - Residual - CB blue mid +HISTORY_MSG_390;W - Residual - CB green low +HISTORY_MSG_391;W - Residual - CB blue low +HISTORY_MSG_392;W - Residual - CB Reset +HISTORY_MSG_393;Use DCP's look table +HISTORY_MSG_394;Use DCP's baseline exposure offset +HISTORY_MSG_395;Use DCP's base table +HISTORY_NEWSNAPSHOT;Add +HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s +HISTORY_SNAPSHOTS;Snapshots +HISTORY_SNAPSHOT;Snapshot +IPTCPANEL_AUTHORSPOSITIONHINT;Title of the creator or creators of the object (By-line Title). +IPTCPANEL_AUTHORSPOSITION;Author's position +IPTCPANEL_AUTHOR;Author +IPTCPANEL_CAPTIONHINT;A textual description of the data (Caption - Abstract). +IPTCPANEL_CAPTIONWRITERHINT;The name of the person involved in the writing, editing or correcting the image or caption/abstract (Writer - Editor). +IPTCPANEL_CAPTIONWRITER;Caption writer +IPTCPANEL_CAPTION;Caption +IPTCPANEL_CATEGORYHINT;Identifies the subject of the image in the opinion of the provider (Category). +IPTCPANEL_CATEGORY;Category +IPTCPANEL_CITYHINT;City of image origin (City). +IPTCPANEL_CITY;City +IPTCPANEL_COPYHINT;Copy IPTC settings to clipboard. +IPTCPANEL_COPYRIGHTHINT;Any necessary copyright notice (Copyright Notice). +IPTCPANEL_COPYRIGHT;Copyright +IPTCPANEL_COUNTRYHINT;The name of the country/primary location where the image was created (Country - Primary Location Name). +IPTCPANEL_COUNTRY;Country +IPTCPANEL_CREDITHINT;Identifies the provider of the image, not necessarily the owner/creator (Credit). +IPTCPANEL_CREDIT;Credit +IPTCPANEL_DATECREATEDHINT;The date the intellectual content of the image was created; Format: YYYYMMDD (Date Created). +IPTCPANEL_DATECREATED;Date created +IPTCPANEL_EMBEDDEDHINT;Reset to IPTC data embedded in the image file. +IPTCPANEL_EMBEDDED;Embedded +IPTCPANEL_HEADLINEHINT;A publishable entry providing a synopsis of the contents of the image (Headline). +IPTCPANEL_HEADLINE;Headline +IPTCPANEL_INSTRUCTIONSHINT;Other editorial instructions concerning the use of the image (Special Instructions). +IPTCPANEL_INSTRUCTIONS;Instructions +IPTCPANEL_KEYWORDSHINT;Used to indicate specific information retrieval words (Keywords). +IPTCPANEL_KEYWORDS;Keywords +IPTCPANEL_PASTEHINT;Paste IPTC settings from clipboard. +IPTCPANEL_PROVINCEHINT;The Province/State where the image originates (Province-State). +IPTCPANEL_PROVINCE;Province +IPTCPANEL_RESETHINT;Reset to profile default. +IPTCPANEL_RESET;Reset +IPTCPANEL_SOURCEHINT;The original owner of the intellectual content of the image (Source). +IPTCPANEL_SOURCE;Source +IPTCPANEL_SUPPCATEGORIESHINT;Further refines the subject of the image (Supplemental Categories). +IPTCPANEL_SUPPCATEGORIES;Suppl. categories +IPTCPANEL_TITLEHINT;A shorthand reference for the image (Object Name). +IPTCPANEL_TITLE;Title +IPTCPANEL_TRANSREFERENCEHINT;A code representing the location of the original transmission (Original Transmission Reference). +IPTCPANEL_TRANSREFERENCE;Trans. reference +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 +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). +MAIN_BUTTON_PREFERENCES;Preferences +MAIN_BUTTON_PUTTOQUEUE_TOOLTIP;Put current image to processing queue.\nShortcut: Ctrl+b +MAIN_BUTTON_SAVE_TOOLTIP;Save current image.\nShortcut: Ctrl+s +MAIN_BUTTON_SENDTOEDITOR_TOOLTIP;Edit current image in external editor.\nShortcut: Ctrl+e +MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP;Show/hide all side panels.\nShortcut: m +MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen +MAIN_FRAME_BATCHQUEUE;Queue +MAIN_FRAME_BATCHQUEUE_TOOLTIP;Processing queue.\nShortcut: Ctrl-F3 +MAIN_FRAME_EDITOR;Editor +MAIN_FRAME_EDITOR_TOOLTIP;Editor.\nShortcut: Ctrl-F4 +MAIN_FRAME_FILEBROWSER;File Browser +MAIN_FRAME_FILEBROWSER_TOOLTIP;File browser.\nShortcut: Ctrl-F2 +MAIN_FRAME_PLACES;Places +MAIN_FRAME_PLACES_ADD;Add +MAIN_FRAME_PLACES_DEL;Del +MAIN_FRAME_RECENT;Recent Folders +MAIN_MSG_ALREADYEXISTS;File already exists. +MAIN_MSG_CANNOTLOAD;Cannot load image +MAIN_MSG_CANNOTSAVE;File saving error +MAIN_MSG_CANNOTSTARTEDITOR;Cannot start editor. +MAIN_MSG_CANNOTSTARTEDITOR_SECONDARY;Please set the correct path in Preferences. +MAIN_MSG_EMPTYFILENAME;Filename unspecified! +MAIN_MSG_IMAGEUNPROCESSED;This command requires all selected images to be queue-processed first. +MAIN_MSG_NAVIGATOR;Navigator +MAIN_MSG_OPERATIONCANCELLED;Operation cancelled +MAIN_MSG_PATHDOESNTEXIST;The path\n\n%1\n\ndoes not exist. Please set a correct path in Preferences. +MAIN_MSG_QOVERWRITE;Do you want to overwrite it? +MAIN_MSG_SETPATHFIRST;You first have to set a target path in Preferences in order to use this function! +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;Color +MAIN_TAB_COLOR_TOOLTIP;Shortcut: Alt-c +MAIN_TAB_DETAIL;Detail +MAIN_TAB_DETAIL_TOOLTIP;Shortcut: Alt-d +MAIN_TAB_DEVELOP; Develop +MAIN_TAB_EXIF;Exif +MAIN_TAB_EXPORT; Fast Export +MAIN_TAB_EXPOSURE;Exposure +MAIN_TAB_EXPOSURE_TOOLTIP;Shortcut: Alt-e +MAIN_TAB_FILTER; Filter +MAIN_TAB_INSPECT; Inspect +MAIN_TAB_IPTC;IPTC +MAIN_TAB_METADATA;Metadata +MAIN_TAB_METADATA_TOOLTIP;Shortcut: Alt-m +MAIN_TAB_RAW;Raw +MAIN_TAB_RAW_TOOLTIP;Shortcut: Alt-r +MAIN_TAB_TRANSFORM;Transform +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_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: < +MAIN_TOOLTIP_INDCLIPPEDS;Clipped shadow indication.\nShortcut: > +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%. +MAIN_TOOLTIP_PREVIEWG;Preview the Green channel.\nShortcut: g +MAIN_TOOLTIP_PREVIEWL;Preview the Luminosity.\nShortcut: v\n\n0.299*R + 0.587*G + 0.114*B +MAIN_TOOLTIP_PREVIEWR;Preview the Red channel.\nShortcut: r +MAIN_TOOLTIP_QINFO;Quick info on the image.\nShortcut: i +MAIN_TOOLTIP_SHOWHIDELP1;Show/Hide the left panel.\nShortcut: l +MAIN_TOOLTIP_SHOWHIDERP1;Show/Hide the right panel.\nShortcut: Alt-l +MAIN_TOOLTIP_SHOWHIDETP1;Show/Hide the top panel.\nShortcut: Shift-l +MAIN_TOOLTIP_THRESHOLD;Threshold +MAIN_TOOLTIP_TOGGLE;Toggle the Before/After view.\nShortcut: Shift-b +NAVIGATOR_B;B: +NAVIGATOR_G;G: +NAVIGATOR_H;H: +NAVIGATOR_LAB_A;a*: +NAVIGATOR_LAB_B;b*: +NAVIGATOR_LAB_L;L*: +NAVIGATOR_NA; -- +NAVIGATOR_R;R: +NAVIGATOR_S;S: +NAVIGATOR_V;V: +NAVIGATOR_XY_FULL;Width: %1, Height: %2 +NAVIGATOR_XY_NA;x: --, y: -- +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_BASICGROUP;Basic Settings +PARTIALPASTE_CACORRECTION;Chromatic aberration correction +PARTIALPASTE_CHANNELMIXERBW;Black-and-white +PARTIALPASTE_CHANNELMIXER;Channel mixer +PARTIALPASTE_COARSETRANS;Coarse rotation/flipping +PARTIALPASTE_COLORAPP;CIECAM02 +PARTIALPASTE_COLORGROUP;Color Related Settings +PARTIALPASTE_COLORTONING;Color toning +PARTIALPASTE_COMMONTRANSFORMPARAMS;Auto-fill +PARTIALPASTE_COMPOSITIONGROUP;Composition Settings +PARTIALPASTE_CROP;Crop +PARTIALPASTE_DARKFRAMEAUTOSELECT;Dark-frame auto-selection +PARTIALPASTE_DARKFRAMEFILE;Dark-frame file +PARTIALPASTE_DEFRINGE;Defringe +PARTIALPASTE_DETAILGROUP;Detail Settings +PARTIALPASTE_DIALOGLABEL;Partial paste processing profile +PARTIALPASTE_DIRPYRDENOISE;Noise reduction +PARTIALPASTE_DIRPYREQUALIZER;Contrast by detail levels +PARTIALPASTE_DISTORTION;Distortion correction +PARTIALPASTE_EPD;Tone mapping +PARTIALPASTE_EQUALIZER;Wavelet levels +PARTIALPASTE_EVERYTHING;Everything +PARTIALPASTE_EXIFCHANGES;Exif +PARTIALPASTE_EXPOSURE;Exposure +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_GRADIENT;Graduated filter +PARTIALPASTE_HSVEQUALIZER;HSV equalizer +PARTIALPASTE_ICMGAMMA;Output gamma +PARTIALPASTE_ICMSETTINGS;Color management settings +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_METAGROUP;Metadata +PARTIALPASTE_PCVIGNETTE;Vignette filter +PARTIALPASTE_PERSPECTIVE;Perspective +PARTIALPASTE_PREPROCESS_DEADPIXFILT;Dead pixel filter +PARTIALPASTE_PREPROCESS_GREENEQUIL;Green equilibration +PARTIALPASTE_PREPROCESS_HOTPIXFILT;Hot pixel filter +PARTIALPASTE_PREPROCESS_LINEDENOISE;Line noise filter +PARTIALPASTE_RAWCACORR_AUTO;CA auto-correction +PARTIALPASTE_RAWCACORR_CABLUE;CA blue +PARTIALPASTE_RAWCACORR_CARED;CA red +PARTIALPASTE_RAWEXPOS_BLACK;Black levels +PARTIALPASTE_RAWEXPOS_LINEAR;White point correction +PARTIALPASTE_RAWEXPOS_PRESER;Highlight preservation +PARTIALPASTE_RAWGROUP;Raw Settings +PARTIALPASTE_RAW_DCBENHANCE;DCB enhancement +PARTIALPASTE_RAW_DCBITERATIONS;DCB iterations +PARTIALPASTE_RAW_DMETHOD;Demosaic method +PARTIALPASTE_RAW_FALSECOLOR;False color suppression +PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps +PARTIALPASTE_RESIZE;Resize +PARTIALPASTE_RGBCURVES;RGB curves +PARTIALPASTE_ROTATION;Rotation +PARTIALPASTE_SHADOWSHIGHLIGHTS;Shadows/highlights +PARTIALPASTE_SHARPENEDGE;Edges +PARTIALPASTE_SHARPENING;Sharpening (USM/RL) +PARTIALPASTE_SHARPENMICRO;Microcontrast +PARTIALPASTE_VIBRANCE;Vibrance +PARTIALPASTE_VIGNETTING;Vignetting correction +PARTIALPASTE_WAVELETGROUP;Wavelet Levels +PARTIALPASTE_WHITEBALANCE;White balance +PREFERENCES_ADD;Add +PREFERENCES_APPLNEXTSTARTUP;restart required +PREFERENCES_AUTLISLOW;Low +PREFERENCES_AUTLISMAX;Max - Average of all tiles +PREFERENCES_AUTLISSTD;High +PREFERENCES_AUTLISVLOW;None +PREFERENCES_AUTLOW;Low +PREFERENCES_AUTOMONPROFILE;Use operating system's main monitor color profile +PREFERENCES_AUTSTD;Standard +PREFERENCES_BATCH_PROCESSING;Batch Processing +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_BEHADDALL;All to 'Add' +PREFERENCES_BEHAVIOR;Behavior +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_BEHSETALL;All to 'Set' +PREFERENCES_BLACKBODY;Tungsten +PREFERENCES_CACHECLEARALL;Clear All +PREFERENCES_CACHECLEARPROFILES;Clear Processing Profiles +PREFERENCES_CACHECLEARTHUMBS;Clear Thumbnails +PREFERENCES_CACHEMAXENTRIES;Maximum number of cache entries +PREFERENCES_CACHEOPTS;Cache Options +PREFERENCES_CACHETHUMBHEIGHT;Maximum thumbnail height +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_CLIPPINGIND;Clipping Indication +PREFERENCES_CLUTSCACHE;HaldCLUT Cache +PREFERENCES_CLUTSCACHE_LABEL;Maximum number of cached CLUTs +PREFERENCES_CLUTSDIR;HaldCLUT directory +PREFERENCES_CMETRICINTENT;Colorimetric intent +PREFERENCES_CURVEBBOXPOS;Position of curve copypasta buttons +PREFERENCES_CURVEBBOXPOS_ABOVE;Above +PREFERENCES_CURVEBBOXPOS_BELOW;Below +PREFERENCES_CURVEBBOXPOS_LEFT;Left +PREFERENCES_CURVEBBOXPOS_RIGHT;Right +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_CUSTPROFBUILD;Custom Processing Profile Builder +PREFERENCES_CUTOVERLAYBRUSH;Crop mask color/transparency +PREFERENCES_D50;5000K +PREFERENCES_D55;5500K +PREFERENCES_D60;6000K +PREFERENCES_D65;6500K +PREFERENCES_DARKFRAMEFOUND;Found +PREFERENCES_DARKFRAMESHOTS;shots +PREFERENCES_DARKFRAMETEMPLATES;templates +PREFERENCES_DARKFRAME;Dark-Frame +PREFERENCES_DATEFORMATHINT;You can use the following formatting strings:\n%y - year\n%m - month\n%d - day\n\nFor example, the ISO 8601 standard dictates the date format as follows:\n%y-%m-%d +PREFERENCES_DATEFORMAT;Date format +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_DEFAULTLANG;Default Language +PREFERENCES_DEFAULTTHEME;Default Theme +PREFERENCES_DIRDARKFRAMES;Dark-frames directory +PREFERENCES_DIRHOME;Home directory +PREFERENCES_DIRLAST;Last visited directory +PREFERENCES_DIROTHER;Other +PREFERENCES_DIRSELECTDLG;Select Image Directory at Startup... +PREFERENCES_DIRSOFTWARE;Installation directory +PREFERENCES_EDITORCMDLINE;Other command line +PREFERENCES_EDITORLAYOUT;Editor Layout +PREFERENCES_EXPAUT;Expert +PREFERENCES_EXTERNALEDITOR;External Editor +PREFERENCES_FBROWSEROPTS;File Browser / Thumbnail Options +PREFERENCES_FILEBROWSERTOOLBARSINGLEROW;Single row file browser toolbar (de-select for low resolution display) +PREFERENCES_FILEFORMAT;File format +PREFERENCES_FILMSIMULATION;Film Simulation +PREFERENCES_FLATFIELDFOUND;Found +PREFERENCES_FLATFIELDSDIR;Flat-fields directory +PREFERENCES_FLATFIELDSHOTS;shots +PREFERENCES_FLATFIELDTEMPLATES;templates +PREFERENCES_FLATFIELD;Flat-Field +PREFERENCES_FLUOF2;Fluorescent F2 +PREFERENCES_FLUOF7;Fluorescent F7 +PREFERENCES_FLUOF11;Fluorescent F11 +PREFERENCES_FORIMAGE;For non-raw photos +PREFERENCES_FORRAW;For raw photos +PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT;Same thumbnail height between the Editor's panel 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 installation directory +PREFERENCES_GREY05;Yb=05 CIE L#30 +PREFERENCES_GREY10;Yb=10 CIE L#40 +PREFERENCES_GREY15;Yb=15 CIE L#45 +PREFERENCES_GREY18;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_GREYSC18;Yb=18 CIE L#50 +PREFERENCES_GREYSCA;Automatic +PREFERENCES_GREYSC;Scene Yb luminance (%) +PREFERENCES_GREY;Output device's Yb luminance (%) +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_HLTHRESHOLD;Threshold for clipped highlights +PREFERENCES_ICCDIR;Directory containing color profiles +PREFERENCES_IMG_RELOAD_NEEDED;These changes require the image to be reloaded (or a new image to be opened) to take effect. +PREFERENCES_IMPROCPARAMS;Default Processing Profile +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_INTENT_ABSOLUTE;Absolute Colorimetric +PREFERENCES_INTENT_PERCEPTUAL;Perceptual +PREFERENCES_INTENT_RELATIVE;Relative Colorimetric +PREFERENCES_INTENT_SATURATION;Saturation +PREFERENCES_INTERNALTHUMBIFUNTOUCHED;Show embedded JPEG thumbnail if raw is unedited +PREFERENCES_LANGAUTODETECT;Use system language +PREFERENCES_LEVAUTDN;Denoising level +PREFERENCES_LEVDN;Cell size +PREFERENCES_LISS;Auto multi-zone smoothing +PREFERENCES_MAXRECENTFOLDERS;Maximum number of recent folders +PREFERENCES_MAX;Maxi (Tile) +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_MENUGROUPRANK;Group "Rank" +PREFERENCES_MENUOPTIONS;Context Menu Options +PREFERENCES_METADATA;Metadata +PREFERENCES_MIN;Mini (100x115) +PREFERENCES_MONITORICC;Monitor color profile +PREFERENCES_MULTITABDUALMON;Multiple Editor Tabs In Own Window Mode +PREFERENCES_MULTITAB;Multiple Editor Tabs Mode +PREFERENCES_NAVGUIDEBRUSH;Navigator guide color +PREFERENCES_NAVIGATIONFRAME;Navigation +PREFERENCES_NOISE;Noise Reduction +PREFERENCES_OUTDIRFOLDERHINT;Save images to the selected folder. +PREFERENCES_OUTDIRFOLDER;Save to folder +PREFERENCES_OUTDIRTEMPLATEHINT;You can use the following formatting strings:\n%f, %d1, %d2, ..., %p1, %p2, ..., %r, %s1, %s2, ...\n\nThese formatting strings refer to the different parts of the photo's pathname, some attributes of the photo or an arbitrary sequence index in the batch job.\n\nFor example, if the photo being processed has the following pathname:\n/home/tom/photos/2010-10-31/dsc0042.nef\nthe meaning of the formatting strings are:\n%d4 = home\n%d3 = tom\n%d2 = photos\n%d1 = 2010-10-31\n%f = dsc0042\n%p1 = /home/tom/photos/2010-10-31/\n%p2 = /home/tom/photos/\n%p3 = /home/tom/\n%p4 = /home/\n\n%r will be replaced by the rank of the photo. If the photo is unranked, %r will be replaced by '0'. If the photo is in the trash bin, %r will be replaced by 'x'.\n\n%s1, %s2, etc. will be replaced by a sequence index which is padded to between 1 and 9 digits. The sequence index will start at one each time the queue processing is started and is incremented by one for each image processed.\n\nIf you want to save the output image where the original is, write:\n%p1/%f\n\nIf you want to save the output image in a directory named "converted" located in the directory of the opened image, write:\n%p1/converted/%f\n\nIf you want to save the output image in a directory named "/home/tom/photos/converted/2010-10-31", write:\n%p2/converted/%d1/%f +PREFERENCES_OUTDIRTEMPLATE;Use template +PREFERENCES_OUTDIR;Output Directory +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_PARSEDEXTADDHINT;Add entered extension to the list. +PREFERENCES_PARSEDEXTADD;Add extension +PREFERENCES_PARSEDEXTDELHINT;Delete selected extension from the list. +PREFERENCES_PARSEDEXT;Parsed Extensions +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_PROFILEHANDLING;Processing Profile Handling +PREFERENCES_PROFILELOADPR;Processing profile loading priority +PREFERENCES_PROFILEPRCACHE;Profile in cache +PREFERENCES_PROFILEPRFILE;Profile next to the input file +PREFERENCES_PROFILESAVECACHE;Save processing profile to the cache +PREFERENCES_PROFILESAVEINPUT;Save processing profile next to the input file +PREFERENCES_PROPERTY;Property +PREFERENCES_PSPATH;Adobe Photoshop installation directory +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 font +PREFERENCES_SELECTLANG;Select language +PREFERENCES_SELECTTHEME;Select theme +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_SHOWBASICEXIF;Show basic Exif info +PREFERENCES_SHOWDATETIME;Show date and time +PREFERENCES_SHOWEXPOSURECOMPENSATION;Append exposure compensation +PREFERENCES_SHOWFILMSTRIPTOOLBAR;Show filmstrip toolbar +PREFERENCES_SHTHRESHOLD;Threshold for clipped shadows +PREFERENCES_SIMPLAUT;Tool mode +PREFERENCES_SINGLETABVERTAB;Single Editor Tab Mode, Vertical Tabs +PREFERENCES_SINGLETAB;Single Editor Tab Mode +PREFERENCES_SLIMUI;Slim interface +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_STARTUPIMDIR;Image Directory at Startup +PREFERENCES_STDAUT;Standard +PREFERENCES_TAB_BROWSER;File Browser +PREFERENCES_TAB_COLORMGR;Color Management +PREFERENCES_TAB_GENERAL;General +PREFERENCES_TAB_IMPROC;Image Processing +PREFERENCES_TAB_PERFORMANCE;Performance & Quality +PREFERENCES_TAB_SOUND;Sounds +PREFERENCES_TIMAX;High +PREFERENCES_TINB;Number of tiles +PREFERENCES_TISTD;Standard +PREFERENCES_TP_LABEL;Tool panel: +PREFERENCES_TP_USEICONORTEXT;Use tab icons instead of text +PREFERENCES_TP_VSCROLLBAR;Hide vertical scrollbar +PREFERENCES_TUNNELMETADATA;Copy IPTC/XMP unchanged to output file (when tagging with other program) +PREFERENCES_USEBUNDLEDPROFILES;Use bundled profiles +PREFERENCES_USESYSTEMTHEME;Use system theme +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_WORKFLOW;Layout +PROFILEPANEL_COPYPPASTE;Parameters to copy +PROFILEPANEL_GLOBALPROFILES;Bundled profiles +PROFILEPANEL_LABEL;Processing Profiles +PROFILEPANEL_LOADDLGLABEL;Load Processing Parameters... +PROFILEPANEL_LOADPPASTE;Parameters to load +PROFILEPANEL_MODE_TIP;Processing profile fill mode.\n\nButton pressed: partial profiles will be converted to full profiles; the missing values will be replaced with hard-coded defaults.\n\nButton released: profiles will be applied as they are, altering only those values which they contain. +PROFILEPANEL_MYPROFILES;My profiles +PROFILEPANEL_PASTEPPASTE;Parameters to paste +PROFILEPANEL_PCUSTOM;Custom +PROFILEPANEL_PFILE;From file +PROFILEPANEL_PINTERNAL;Neutral +PROFILEPANEL_PLASTSAVED;Last Saved +PROFILEPANEL_SAVEDLGLABEL;Save Processing Parameters... +PROFILEPANEL_SAVEPPASTE;Parameters to save +PROFILEPANEL_TOOLTIPCOPY;Copy current processing profile to clipboard.\nCtrl-click to select the parameters to copy. +PROFILEPANEL_TOOLTIPLOAD;Load a profile from file.\nCtrl-click to select the parameters to load. +PROFILEPANEL_TOOLTIPPASTE;Paste profile from clipboard.\nCtrl-click to select the parameters to paste. +PROFILEPANEL_TOOLTIPSAVE;Save current profile.\nCtrl-click to select the parameters to save. +PROGRESSBAR_LOADINGTHUMBS;Loading thumbnails... +PROGRESSBAR_LOADING;Loading image... +PROGRESSBAR_LOADJPEG;Loading JPEG file... +PROGRESSBAR_LOADPNG;Loading PNG file... +PROGRESSBAR_LOADTIFF;Loading TIFF file... +PROGRESSBAR_NOIMAGES;No images found +PROGRESSBAR_PROCESSING;Processing image... +PROGRESSBAR_PROCESSING_PROFILESAVED;Processing profile saved +PROGRESSBAR_READY;Ready +PROGRESSBAR_SAVEJPEG;Saving JPEG file... +PROGRESSBAR_SAVEPNG;Saving PNG file... +PROGRESSBAR_SAVETIFF;Saving TIFF file... +PROGRESSBAR_SNAPSHOT_ADDED;Snapshot added +PROGRESSDLG_PROFILECHANGEDINBROWSER;Processing profile changed in browser +QINFO_ISO;ISO +QINFO_NOEXIF;Exif data not available. +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_PUTTOQUEUEHEAD;Put to the head of the processing queue +SAVEDLG_PUTTOQUEUETAIL;Put to the end of the processing queue +SAVEDLG_PUTTOQUEUE;Put into processing queue +SAVEDLG_SAVEIMMEDIATELY;Save immediately +SAVEDLG_SAVESPP;Save processing parameters with image +SAVEDLG_SUBSAMP;Subsampling +SAVEDLG_SUBSAMP_1;Best compression +SAVEDLG_SUBSAMP_2;Balanced +SAVEDLG_SUBSAMP_3;Best quality +SAVEDLG_SUBSAMP_TOOLTIP;Best compression: 4:1:1\nBalanced: 4:2:2\nBest quality: 4:4:4 +SAVEDLG_TIFFUNCOMPRESSED;Uncompressed TIFF +SAVEDLG_WARNFILENAME;File will be named +SHCSELECTOR_TOOLTIP;Click right mouse button to reset the position of those 3 sliders. +THRESHOLDSELECTOR_BL;Bottom-left +THRESHOLDSELECTOR_BR;Bottom-right +THRESHOLDSELECTOR_B;Bottom +THRESHOLDSELECTOR_HINT;Hold the Shift key to move individual control points. +THRESHOLDSELECTOR_TL;Top-left +THRESHOLDSELECTOR_TR;Top-right +THRESHOLDSELECTOR_T;Top +TOOLBAR_TOOLTIP_CROP;Crop selection.\nShortcut: c\nMove the crop area using Shift-mouse drag +TOOLBAR_TOOLTIP_HAND;Hand tool.\nShortcut: h +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. Center of rotation is the geometrical center of the image. +TOOLBAR_TOOLTIP_WB;Spot white balance.\nShortcut: w +TP_BWMIX_ALGO;Algorithm OYCPM +TP_BWMIX_ALGO_LI;Linear +TP_BWMIX_ALGO_SP;Special effects +TP_BWMIX_ALGO_TOOLTIP;Linear: will produce a normal linear response.\nSpecial effects: will produce special effects by mixing channels non-linearly. +TP_BWMIX_AUTOCH;Auto +TP_BWMIX_AUTOCH_TIP;Calculate values optimizing Channel Mixer. +TP_BWMIX_CC_ENABLED;Adjust complementary color +TP_BWMIX_CC_TOOLTIP;Enable to allow automatic adjustment of complementary colors in ROYGCBPM mode. +TP_BWMIX_CHANNEL;Luminance equalizer +TP_BWMIX_CURVEEDITOR1;'Before' curve +TP_BWMIX_CURVEEDITOR2;'After' curve +TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP;Tone curve, after B&W conversion, at the end of treatment. +TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP;Tone curve, just before B&W conversion.\nMay take into account the color components. +TP_BWMIX_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H).\nPay attention to extreme values as they may cause artifacts. +TP_BWMIX_FILTER;Color Filter +TP_BWMIX_FILTER_BLUEGREEN;Blue-Green +TP_BWMIX_FILTER_BLUE;Blue +TP_BWMIX_FILTER_GREENYELLOW;Green-Yellow +TP_BWMIX_FILTER_GREEN;Green +TP_BWMIX_FILTER_NONE;None +TP_BWMIX_FILTER_PURPLE;Purple +TP_BWMIX_FILTER_REDYELLOW;Red-Yellow +TP_BWMIX_FILTER_RED;Red +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. +TP_BWMIX_FILTER_YELLOW;Yellow +TP_BWMIX_GAMMA;Gamma Correction +TP_BWMIX_GAM_TOOLTIP;Correct gamma for each RGB channel. +TP_BWMIX_LABEL;Black-and-White +TP_BWMIX_MET;Method +TP_BWMIX_MET_CHANMIX;Channel Mixer +TP_BWMIX_MET_DESAT;Desaturation +TP_BWMIX_MET_LUMEQUAL;Luminance Equalizer +TP_BWMIX_MIXC;Mixer +TP_BWMIX_NEUTRAL;Reset mixer +TP_BWMIX_NEUTRAL_TIP;Reset all values (Color Filter, Channel Mixer) to default. +TP_BWMIX_RGBLABEL;R: %1%% G: %2%% B: %3%% Total: %4%% +TP_BWMIX_RGBLABEL_HINT;Final RGB factors that take care of all the mixer options.\n"Total" displays the sum of the RGB values:\n- always 100% in relative mode\n- higher (lighter) or lower (darker) than 100% in absolute mode. +TP_BWMIX_RGB_TOOLTIP;Mix the RGB channels. Use presets for guidance.\nPay attention to negative values that may cause artifacts or erratic behavior. +TP_BWMIX_SETTING;Presets +TP_BWMIX_SETTING_TOOLTIP;Different presets (film, landscape, etc.) or manual Channel Mixer settings. +TP_BWMIX_SET_HIGHCONTAST;High contrast +TP_BWMIX_SET_HIGHSENSIT;High Sensitivity +TP_BWMIX_SET_HYPERPANCHRO;Hyper Panchromatic +TP_BWMIX_SET_INFRARED;Infrared +TP_BWMIX_SET_LANDSCAPE;Landscape +TP_BWMIX_SET_LOWSENSIT;Low Sensitivity +TP_BWMIX_SET_LUMINANCE;Luminance +TP_BWMIX_SET_NORMCONTAST;Normal Contrast +TP_BWMIX_SET_ORTHOCHRO;Orthochromatic +TP_BWMIX_SET_PANCHRO;Panchromatic +TP_BWMIX_SET_PORTRAIT;Portrait +TP_BWMIX_SET_RGBABS;Absolute RGB +TP_BWMIX_SET_RGBREL;Relative RGB +TP_BWMIX_SET_ROYGCBPMABS;Absolute ROYGCBPM +TP_BWMIX_SET_ROYGCBPMREL;Relative ROYGCBPM +TP_BWMIX_TCMODE_FILMLIKE;B&W Film-like +TP_BWMIX_TCMODE_SATANDVALBLENDING;B&W Saturation and Value Blending +TP_BWMIX_TCMODE_STANDARD;B&W Standard +TP_BWMIX_TCMODE_WEIGHTEDSTD;B&W Weighted Standard +TP_BWMIX_VAL;L +TP_CACORRECTION_BLUE;Blue +TP_CACORRECTION_LABEL;Chromatic Aberration Correction +TP_CACORRECTION_RED;Red +TP_CHMIXER_BLUE;Blue channel +TP_CHMIXER_GREEN;Green channel +TP_CHMIXER_LABEL;Channel Mixer +TP_CHMIXER_RED;Red channel +TP_CHROMATABERR_LABEL;Chromatic Aberration +TP_COARSETRAF_TOOLTIP_HFLIP;Flip horizontally. +TP_COARSETRAF_TOOLTIP_ROTLEFT;Rotate left.\n\nShortcuts:\n[ - Multiple Editor Tabs Mode,\nAlt-[ - Single Editor Tab Mode. +TP_COARSETRAF_TOOLTIP_ROTRIGHT;Rotate right.\n\nShortcuts:\n] - Multiple Editor Tabs Mode,\nAlt-] - Single Editor Tab Mode. +TP_COARSETRAF_TOOLTIP_VFLIP;Flip vertically. +TP_COLORAPP_ADAPTSCENE;Scene luminosity +TP_COLORAPP_ADAPTSCENE_TOOLTIP;Absolute luminance of the scene environement (cd/m²).\n1) Calculated from the Exif data:\nShutter speed - ISO speed - F number - camera exposure correction.\n2) Calculated from the raw white point and RT's Exposure Compensation slider. +TP_COLORAPP_ADAPTVIEWING;Viewing luminosity (cd/m²) +TP_COLORAPP_ADAPTVIEWING_TOOLTIP;Absolute luminance of the viewing environnement\n(usually 16cd/m²). +TP_COLORAPP_ADAP_AUTO_TOOLTIP;If the checkbox is checked (recommended) RawTherapee calculates an optimum value from Exif data.\nTo set the value manually, uncheck the checkbox first. +TP_COLORAPP_ALGO;Algorithm +TP_COLORAPP_ALGO_ALL;All +TP_COLORAPP_ALGO_JC;Lightness + Chroma (JC) +TP_COLORAPP_ALGO_JS;Lightness + Saturation (JS) +TP_COLORAPP_ALGO_QM;Brightness + Colorfulness (QM) +TP_COLORAPP_ALGO_TOOLTIP;Lets you choose between parameter subsets or all parameters. +TP_COLORAPP_BADPIXSL;Hot/bad pixel filter +TP_COLORAPP_BADPIXSL_TOOLTIP;Suppression of hot/bad (brightly colored) pixels.\n0 = No effect\n1 = Median\n2 = Gaussian.\nAlternatively, adjust the image to avoid very dark shadows.\n\nThese artifacts are due to limitations of CIECAM02. +TP_COLORAPP_BRIGHT;Brightness (Q) +TP_COLORAPP_BRIGHT_TOOLTIP;Brightness in CIECAM02 takes into account the white's luminosity and differs from L*a*b* and RGB brightness. +TP_COLORAPP_CHROMA;Chroma (C) +TP_COLORAPP_CHROMA_M;Colorfulnes (M) +TP_COLORAPP_CHROMA_M_TOOLTIP;Colorfulness in CIECAM02 differs from L*a*b* and RGB colorfulness. +TP_COLORAPP_CHROMA_S;Saturation (S) +TP_COLORAPP_CHROMA_S_TOOLTIP;Saturation in CIECAM02 differs from L*a*b* and RGB saturation. +TP_COLORAPP_CHROMA_TOOLTIP;Chroma in CIECAM02 differs from L*a*b* and RGB chroma. +TP_COLORAPP_CIECAT_DEGREE;CAT02 adaptation +TP_COLORAPP_CONTRAST;Contrast (J) +TP_COLORAPP_CONTRAST_Q;Contrast (Q) +TP_COLORAPP_CONTRAST_Q_TOOLTIP;Contrast in CIECAM02 for the Q slider; it differs from L*a*b* and RGB contrast. +TP_COLORAPP_CONTRAST_TOOLTIP;Contrast in CIECAM02 for the J slider; it differs from L*a*b* and RGB contrast. +TP_COLORAPP_CURVEEDITOR1;Tone curve 1 +TP_COLORAPP_CURVEEDITOR1_TOOLTIP;Shows the histogram of L* (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of J or Q after CIECAM02.\n\nJ and Q are not shown in the main histogram panel.\n\nFor final output refer to the main histogram panel. +TP_COLORAPP_CURVEEDITOR2;Tone curve 2 +TP_COLORAPP_CURVEEDITOR2_TOOLTIP;Same usage as with the second exposure tone curve. +TP_COLORAPP_CURVEEDITOR3;Color curve +TP_COLORAPP_CURVEEDITOR3_TOOLTIP;Adjust either chroma, saturation or colorfulness.\n\nShows the histogram of chromaticity (L*a*b*) before CIECAM02.\nIf the "Show CIECAM02 output histograms in curves" checkbox is enabled, shows the histogram of C, s or M after CIECAM02.\n\nC, s and M are not shown in the main histogram panel.\nFor final output refer to the main histogram panel. +TP_COLORAPP_DATACIE;CIECAM02 output histograms in curves +TP_COLORAPP_DATACIE_TOOLTIP;When enabled, histograms in CIECAM02 curves show approximate values/ranges for J or Q, and C, s or M after the CIECAM02 adjustments.\nThis selection does not impact the main histogram panel.\n\nWhen disabled, histograms in CIECAM02 curves show L*a*b* values before CIECAM02 adjustments. +TP_COLORAPP_DEGREE_AUTO_TOOLTIP;If the check-box is checked (recommended), RawTherapee calculates an optimum value, which is then used by CAT02, and also for the entire CIECAM02.\nTo set the value manually, uncheck the check-box first (values above 65 are recommended). +TP_COLORAPP_DEGREE_TOOLTIP;Amount of CIE Chromatic Adaptation Transform 2002. +TP_COLORAPP_GAMUT;Gamut control (L*a*b*) +TP_COLORAPP_GAMUT_TOOLTIP;Allow gamut control in L*a*b* mode. +TP_COLORAPP_HUE;Hue (h) +TP_COLORAPP_HUE_TOOLTIP;Hue (h) - angle between 0° and 360°. +TP_COLORAPP_LABEL;CIE Color Appearance Model 2002 +TP_COLORAPP_LABEL_CAM02;Image Adjustments +TP_COLORAPP_LABEL_SCENE;Scene Conditions +TP_COLORAPP_LABEL_VIEWING;Viewing Conditions +TP_COLORAPP_LIGHT;Lightness (J) +TP_COLORAPP_LIGHT_TOOLTIP;Lightness in CIECAM02 differs from L*a*b* and RGB lightness. +TP_COLORAPP_MODEL;WP Model +TP_COLORAPP_MODEL_TOOLTIP;White-Point Model.\n\nWB [RT] + [output]: RT's white balance is used for the scene, CIECAM02 is set to D50, and the output device's white balance is set in Preferences > Color Management.\n\nWB [RT+CAT02] + [output]: RT's white balance settings are used by CAT02 and the output device's white balance is set in Preferences - Color Management. +TP_COLORAPP_RSTPRO;Red & skin-tones protection +TP_COLORAPP_RSTPRO_TOOLTIP;Red and skin-tones protection affects both sliders and curves. +TP_COLORAPP_SHARPCIE;--unused-- +TP_COLORAPP_SHARPCIE_TOOLTIP;--unused-- +TP_COLORAPP_SURROUND;Surround +TP_COLORAPP_SURROUND_AVER;Average +TP_COLORAPP_SURROUND_DARK;Dark +TP_COLORAPP_SURROUND_DIM;Dim +TP_COLORAPP_SURROUND_EXDARK;Extremly Dark (Cutsheet) +TP_COLORAPP_SURROUND_TOOLTIP;Changes tones and colors to take into account the viewing conditions of the output device.\n\nAverage: Average light environment (standard). The image will not change.\n\nDim: Dim environment (TV). The image will become slighty dark.\n\nDark: Dark environment (projector). The image will become more dark.\n\nExtremly Dark: Extremly dark environment (cutsheet). The image will become very dark. +TP_COLORAPP_SURSOURCE;Dark surround +TP_COLORAPP_SURSOURCE_TOOLTIP;Can be used if image has a dark border. +TP_COLORAPP_TCMODE_BRIGHTNESS;Brightness +TP_COLORAPP_TCMODE_CHROMA;Chroma +TP_COLORAPP_TCMODE_COLORF;Colorfulness +TP_COLORAPP_TCMODE_LABEL1;Curve mode 1 +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_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] +TP_COLORAPP_WBRT;WB [RT] + [output] +TP_COLORTONING_AB;o C/L +TP_COLORTONING_AUTOSAT;Automatic +TP_COLORTONING_BALANCE;Balance +TP_COLORTONING_BY;o C/L +TP_COLORTONING_CHROMAC;Opacity +TP_COLORTONING_COLOR;Color +TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP;Chroma opacity as a function of luminance oC=f(L) +TP_COLORTONING_HIGHLIGHT;Highlights +TP_COLORTONING_HUE;Hue +TP_COLORTONING_LABEL;Color Toning +TP_COLORTONING_LAB;L*a*b* blending +TP_COLORTONING_LUMAMODE;Preserve luminance +TP_COLORTONING_LUMAMODE_TOOLTIP;If enabled, when you change color (red, green, cyan, blue, etc.) the luminance of each pixel is preserved. +TP_COLORTONING_LUMA;Luminance +TP_COLORTONING_METHOD;Method +TP_COLORTONING_METHOD_TOOLTIP;"L*a*b* blending", "RGB sliders" and "RGB curves" use interpolated color blending.\n"Color balance (Shadows/Midtones/Highlights)" and "Saturation 2 colors" use direct colors.\n\nThe Black-and-White tool can be enabled when using any color toning method, which allows for color toning. +TP_COLORTONING_MIDTONES;Midtones +TP_COLORTONING_NEUTRAL;Reset sliders +TP_COLORTONING_NEUTRAL_TIP;Reset all values (Shadows, Midtones, Highlights) to default. +TP_COLORTONING_OPACITY;Opacity +TP_COLORTONING_RGBCURVES;RGB - Curves +TP_COLORTONING_RGBSLIDERS;RGB - Sliders +TP_COLORTONING_SATURATEDOPACITY;Strength +TP_COLORTONING_SATURATIONTHRESHOLD;Threshold +TP_COLORTONING_SA;Saturation Protection +TP_COLORTONING_SHADOWS;Shadows +TP_COLORTONING_SPLITCOCO;Color Balance Shadows/Midtones/Highlights +TP_COLORTONING_SPLITCO;Shadows/Midtones/Highlights +TP_COLORTONING_SPLITLR;Saturation 2 colors +TP_COLORTONING_STRENGTH;Strength +TP_COLORTONING_STR;Strength +TP_COLORTONING_TWO2;Special chroma '2 colors' +TP_COLORTONING_TWOALL;Special chroma +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_FIXRATIO;Lock ratio +TP_CROP_GTDIAGONALS;Rule of Diagonals +TP_CROP_GTEPASSPORT;Biometric Passport +TP_CROP_GTFRAME;Frame +TP_CROP_GTGRID;Grid +TP_CROP_GTHARMMEANS;Harmonic Means +TP_CROP_GTNONE;None +TP_CROP_GTRULETHIRDS;Rule of Thirds +TP_CROP_GTTRIANGLE1;Golden Triangles 1 +TP_CROP_GTTRIANGLE2;Golden Triangles 2 +TP_CROP_GUIDETYPE;Guide type: +TP_CROP_H;Height +TP_CROP_LABEL;Crop +TP_CROP_PPI;PPI= +TP_CROP_SELECTCROP;Select Crop +TP_CROP_W;Width +TP_CROP_X;X +TP_CROP_Y;Y +TP_DARKFRAME_AUTOSELECT;Auto-selection +TP_DARKFRAME_LABEL;Dark-Frame +TP_DEFRINGE_LABEL;Defringe +TP_DEFRINGE_RADIUS;Radius +TP_DEFRINGE_THRESHOLD;Threshold +TP_DIRPYRDENOISE_33;3×3 strong +TP_DIRPYRDENOISE_55SOFT;5×5 +TP_DIRPYRDENOISE_55;5×5 strong +TP_DIRPYRDENOISE_77;7×7 (slow) +TP_DIRPYRDENOISE_99;9x9 (very slow) +TP_DIRPYRDENOISE_ABM;Chroma only +TP_DIRPYRDENOISE_AUTO;Automatic global +TP_DIRPYRDENOISE_AUTO_TOOLTIP;Try to evaluate chroma noise\nBe careful, this calculation is average, and is quite subjective ! +TP_DIRPYRDENOISE_AUT;Automatic global +TP_DIRPYRDENOISE_BLUE;Chrominance - Blue-Yellow +TP_DIRPYRDENOISE_C2TYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +TP_DIRPYRDENOISE_CCCURVE;Chrominance curve +TP_DIRPYRDENOISE_CHROMAFR;Chrominance +TP_DIRPYRDENOISE_CHROMA;Chrominance - Master +TP_DIRPYRDENOISE_CTYPE;Auto method +TP_DIRPYRDENOISE_CTYPE_TOOLTIP;Manual\nActs on the full image.\nYou control the noise reduction settings manually.\n\nAutomatic global\nActs on the full image.\n9 zones are used to calculate a global chrominance noise reduction setting.\n\nAutomatic multi-zones\nNo preview - works only during saving, but using the "Preview" method by matching the tile size and center to the preview size and center you can get an idea of the expected results.\nThe image is divided into tiles (about 10 to 70 depending on image size) and each tile receives its own chrominance noise reduction settings.\n\nPreview\nActs on the whole image.\nThe part of the image visible in the preview is used to calculate global chrominance noise reduction settings. +TP_DIRPYRDENOISE_CURVEEDITOR_CC;Chroma +TP_DIRPYRDENOISE_CURVEEDITOR_CC_TOOLTIP;Increase (multiply) the value of all chrominance sliders.\nThis curve lets you adjust the strength of chromatic noise reduction as a function of chromaticity, for instance to increase the action in areas of low saturation and to decrease it in those of high saturation. +TP_DIRPYRDENOISE_CURVEEDITOR_L_TOOLTIP;Modulates action of 'Luminance' denoise +TP_DIRPYRDENOISE_CUR;Curve +TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on the gamma of the input color profile. An sRGB gamma is assumed, thus if the image uses an input color profile of a different gamma, the effects of luminance noise reduction will differ. +TP_DIRPYRDENOISE_ENH;Enhanced mode +TP_DIRPYRDENOISE_ENH_TOOLTIP;Increases noise reduction quality at the expense of a 20% processing time increase. +TP_DIRPYRDENOISE_GAMMA;Gamma +TP_DIRPYRDENOISE_GAMMA_TOOLTIP;Gamma varies noise reduction strength across the range of tones. Smaller values will target shadows, while larger values will stretch the effect to the brighter tones. +TP_DIRPYRDENOISE_LABEL;Noise Reduction +TP_DIRPYRDENOISE_LABM;L*a*b* +TP_DIRPYRDENOISE_LAB;L*a*b* +TP_DIRPYRDENOISE_LCURVE;Luminance curve +TP_DIRPYRDENOISE_LDETAIL;Luminance - Detail +TP_DIRPYRDENOISE_LM;Luminance only +TP_DIRPYRDENOISE_LPLABM;Weighted L* (little) + a*b* (normal) +TP_DIRPYRDENOISE_LTYPE;Luminance control +TP_DIRPYRDENOISE_LUMAFR;Luminance +TP_DIRPYRDENOISE_LUMAFR_TOOLTIP;Wavelet on luminance and Fourier transform for luminance detail +TP_DIRPYRDENOISE_LUMA;Luminance +TP_DIRPYRDENOISE_MANU;Manual +TP_DIRPYRDENOISE_MAN;Manual +TP_DIRPYRDENOISE_MEDMETHOD;Median method +TP_DIRPYRDENOISE_MEDTYPE;Median type +TP_DIRPYRDENOISE_MED;Median Filter +TP_DIRPYRDENOISE_MED_TOOLTIP;Enabled median denoising +TP_DIRPYRDENOISE_METHOD11;Quality +TP_DIRPYRDENOISE_METHOD11_TOOLTIP;Quality can be adapted to the noise pattern. A setting of "high" increases the noise reduction effect at a cost of extended processing time. +TP_DIRPYRDENOISE_METHOD;Method +TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or L*a*b* methods can be used.\n\nFor non-raw images the L*a*b* method will be used, regardless of the selection. +TP_DIRPYRDENOISE_METM_TOOLTIP;When using the "Luminance only" and "L*a*b*" methods, median filtering will be performed just after the wavelet step in the noise reduction pipeline.\nWhen using the "RGB" mode, it will be performed at the very end of the noise reduction pipeline. +TP_DIRPYRDENOISE_MET_TOOLTIP;Apply a median filter of the desired size. The larger the size, the longer it takes.\n\n3x3 soft: treats 5 pixels in a 1-pixel range.\n3x3: treats 9 pixels in a 1-pixel range.\n5x5 soft: treats 13 pixels in a 2-pixel range.\n5x5: treats 25 pixels in a 2-pixel range.\n7x7: treats 49 pixels in a 3-pixel range.\n9x9: treats 81 pixels in a 4-pixel range.\n\nSometimes it is possible to achieve higher quality running several iterations with a small range than one iteration with a large range. +TP_DIRPYRDENOISE_NOISELABELEMPTY;Preview noise: Mean= - High= - +TP_DIRPYRDENOISE_NOISELABEL;Preview noise: Mean=%1 High=%2 +TP_DIRPYRDENOISE_NRESID_TOOLTIP;Displays the remaining noise levels of the part of the image visible in the preview after wavelet.\n\n>300 Very noisy\n100-300 Noisy\n50-100 A little noisy\n<50 Very low noise\n\nBeware, the values will differ between RGB and L*a*b* mode. The RGB values are less accurate because the RGB mode does not completely separate luminance and chrominance. +TP_DIRPYRDENOISE_PASSES;Median iterations +TP_DIRPYRDENOISE_PASSES_TOOLTIP;Applying a 3x3 median filter with three iterations often leads to better results than applying 7x7 once. +TP_DIRPYRDENOISE_PON;Auto multi-zones +TP_DIRPYRDENOISE_PREVLABEL;Preview size=%1, Center: Px=%2 Py=%3 +TP_DIRPYRDENOISE_PREV;Preview +TP_DIRPYRDENOISE_PRE;Preview multi-zones +TP_DIRPYRDENOISE_RED;Chrominance - Red-Green +TP_DIRPYRDENOISE_RGBM;RGB +TP_DIRPYRDENOISE_RGB;RGB +TP_DIRPYRDENOISE_SHALBI;High +TP_DIRPYRDENOISE_SHAL;Standard +TP_DIRPYRDENOISE_SLI;Slider +TP_DIRPYRDENOISE_SOFT;3x3 +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_LUMAFINEST;Finest +TP_DIRPYREQUALIZER_LUMANEUTRAL;Neutral +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_THRESHOLD;Threshold +TP_DIRPYREQUALIZER_TOOLTIP;Attempts to reduce artifacts in the transitions between skin colors (hue, chroma, luma) and the rest of the image. +TP_DISTORTION_AMOUNT;Amount +TP_DISTORTION_AUTO;Auto Distortion Correction +TP_DISTORTION_AUTO_TIP;Correct lens distortion automatically for some cameras (Micro 4/3, some compact digital cameras, etc.). +TP_DISTORTION_LABEL;Distortion Correction +TP_EPD_EDGESTOPPING;Edge stopping +TP_EPD_GAMMA;Gamma +TP_EPD_LABEL;Tone Mapping +TP_EPD_REWEIGHTINGITERATES;Reweighting iterates +TP_EPD_SCALE;Scale +TP_EPD_STRENGTH;Strength +TP_EPD_TOOLTIP;Tone mapping is possible in L*a*b* mode (standard) and CIECAM02 mode.\n\nWhen in L*a*b* mode, tone mapping can also be used on the residual image of the Wavelet Levels tool.\n\nTo engage CIECAM02 tone mapping mode enable the following settings:\n1. CIECAM02\n2. Algorithm="Brightness + Colorfulness (QM)"\n3. "Tone mapping using CIECAM02 brightness (Q)" +TP_EXPOSURE_AUTOLEVELS;Auto Levels +TP_EXPOSURE_AUTOLEVELS_TIP;Toggles execution of Auto Levels to automatically set Exposure slider values based on an image analysis.\nEnables Highlight Reconstruction if necessary. +TP_EXPOSURE_BLACKLEVEL;Black +TP_EXPOSURE_BRIGHTNESS;Lightness +TP_EXPOSURE_CLIP;Clip % +TP_EXPOSURE_CLIP_TIP;The fraction of pixels to be clipped in Auto Levels operation. +TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD;Highlight compression threshold +TP_EXPOSURE_COMPRHIGHLIGHTS;Highlight compression +TP_EXPOSURE_COMPRSHADOWS;Shadow compression +TP_EXPOSURE_CONTRAST;Contrast +TP_EXPOSURE_CURVEEDITOR1;Tone curve 1 +TP_EXPOSURE_CURVEEDITOR2;Tone curve 2 +TP_EXPOSURE_CURVEEDITOR2_TOOLTIP;Please refer to the "Exposure > Tone Curves" RawPedia article to learn how to achieve the best results by using two tone curves. +TP_EXPOSURE_EXPCOMP;Exposure compensation +TP_EXPOSURE_LABEL;Exposure +TP_EXPOSURE_SATURATION;Saturation +TP_EXPOSURE_TCMODE_FILMLIKE;Film-like +TP_EXPOSURE_TCMODE_LABEL1;Curve mode 1 +TP_EXPOSURE_TCMODE_LABEL2;Curve mode 2 +TP_EXPOSURE_TCMODE_LUMINANCE;Luminance +TP_EXPOSURE_TCMODE_SATANDVALBLENDING;Saturation and Value Blending +TP_EXPOSURE_TCMODE_STANDARD;Standard +TP_EXPOSURE_TCMODE_WEIGHTEDSTD;Weighted Standard +TP_EXPOS_BLACKPOINT_LABEL;Raw Black Points +TP_EXPOS_WHITEPOINT_LABEL;Raw White Points +TP_FILMSIMULATION_LABEL;Film Simulation +TP_FILMSIMULATION_STRENGTH;Strength +TP_FILMSIMULATION_ZEROCLUTSFOUND;Set HaldCLUT directory in Preferences +TP_FLATFIELD_AUTOSELECT;Auto-selection +TP_FLATFIELD_BLURRADIUS;Blur radius +TP_FLATFIELD_BLURTYPE;Blur type +TP_FLATFIELD_BT_AREA;Area +TP_FLATFIELD_BT_HORIZONTAL;Horizontal +TP_FLATFIELD_BT_VERTHORIZ;Vertical + Horizontal +TP_FLATFIELD_BT_VERTICAL;Vertical +TP_FLATFIELD_CLIPCONTROL;Clip control +TP_FLATFIELD_CLIPCONTROL_TOOLTIP;Clip control avoids clipped highlights caused by applying the flat field. If there are already clipped highlights before applying the flat field, clip control can lead to color cast. +TP_FLATFIELD_LABEL;Flat-Field +TP_GAMMA_CURV;Gamma +TP_GAMMA_FREE;Free gamma +TP_GAMMA_OUTPUT;Output gamma +TP_GAMMA_SLOP;Slope (linear) +TP_GENERAL_11SCALE_TOOLTIP;The effects of this tool are only visible or only accurate at a preview scale of 1:1. +TP_GRADIENT_CENTER;Center +TP_GRADIENT_CENTER_X;Center X +TP_GRADIENT_CENTER_X_TOOLTIP;Shift gradient to the left (negative values) or right (positive values). +TP_GRADIENT_CENTER_Y;Center Y +TP_GRADIENT_CENTER_Y_TOOLTIP;Shift gradient up (negative values) or down (positive values). +TP_GRADIENT_DEGREE;Angle +TP_GRADIENT_DEGREE_TOOLTIP;Rotation angle in degrees. +TP_GRADIENT_FEATHER;Feather +TP_GRADIENT_FEATHER_TOOLTIP;Gradient width in percent of the image diagonal. +TP_GRADIENT_LABEL;Graduated Filter +TP_GRADIENT_STRENGTH;Strength +TP_GRADIENT_STRENGTH_TOOLTIP;Filter strength in stops. +TP_HLREC_BLEND;Blend +TP_HLREC_CIELAB;CIELab Blending +TP_HLREC_COLOR;Color Propagation +TP_HLREC_ENA_TOOLTIP;Could be activated by Auto Levels. +TP_HLREC_LABEL;Highlight reconstruction +TP_HLREC_LUMINANCE;Luminance Recovery +TP_HLREC_METHOD;Method: +TP_HSVEQUALIZER_CHANNEL;Channel +TP_HSVEQUALIZER_HUE;H +TP_HSVEQUALIZER_LABEL;HSV Equalizer +TP_HSVEQUALIZER_SAT;S +TP_HSVEQUALIZER_VAL;V +TP_ICM_APPLYBASELINEEXPOSUREOFFSET;Use DCP's baseline exposure offset +TP_ICM_APPLYBASELINEEXPOSUREOFFSET_TOOLTIP;Employ the embedded DCP baseline exposure offset. The setting is only enabled if the selected DCP has any. +TP_ICM_APPLYHUESATMAP;Use DCP's base table +TP_ICM_APPLYHUESATMAP_TOOLTIP;Employ the embedded DCP base table (HueSatMap). The setting is only enabled if the selected DCP has one. +TP_ICM_APPLYLOOKTABLE;Use DCP's look table +TP_ICM_APPLYLOOKTABLE_TOOLTIP;Employ the embedded DCP look table. The setting is only enabled if the selected DCP has one. +TP_ICM_BLENDCMSMATRIX;Blend ICC highlights with matrix +TP_ICM_BLENDCMSMATRIX_TOOLTIP;Enable to recover clipped highlights when using LUT-based ICC profiles. +TP_ICM_DCPILLUMINANT;Illuminant +TP_ICM_DCPILLUMINANT_INTERPOLATED;Interpolated +TP_ICM_DCPILLUMINANT_TOOLTIP;Select which embedded DCP illuminant to employ. Default is "interpolated" which is a mix between the two based on white balance. The setting is only enabled if a Dual-Illuminant DCP with interpolation support is selected. +TP_ICM_INPUTCAMERAICC;Auto-matched camera profile +TP_ICM_INPUTCAMERAICC_TOOLTIP;Use RawTherapee's camera-specific DCP or ICC input color profiles. These profiles are more precise than simpler matrix ones. They are not available for all cameras. These profiles are stored in the /iccprofiles/input and /dcpprofiles folders and are automatically retrieved based on a file name matching to the exact model name of the camera. +TP_ICM_INPUTCAMERA;Camera standard +TP_ICM_INPUTCAMERA_TOOLTIP;Use a simple color matrix from dcraw, an enhanced RawTherapee version (whichever is available based on camera model) or one embedded in the DNG. +TP_ICM_INPUTCUSTOM;Custom +TP_ICM_INPUTCUSTOM_TOOLTIP;Select your own DCP/ICC color profile file for the camera. +TP_ICM_INPUTDLGLABEL;Select Input DCP/ICC Profile... +TP_ICM_INPUTEMBEDDED;Use embedded, if possible +TP_ICM_INPUTEMBEDDED_TOOLTIP;Use color profile embedded in non-raw files. +TP_ICM_INPUTNONE;No profile +TP_ICM_INPUTNONE_TOOLTIP;Use no input color profile at all.\nUse only in special cases. +TP_ICM_INPUTPROFILE;Input Profile +TP_ICM_LABEL;Color Management +TP_ICM_NOICM;No ICM: sRGB Output +TP_ICM_OUTPUTPROFILE;Output Profile +TP_ICM_SAVEREFERENCE;Save Reference Image for Profiling +TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance +TP_ICM_SAVEREFERENCE_TOOLTIP;Save the linear TIFF image before the input profile is applied. The result can be used for calibration purposes and generation of a camera profile. +TP_ICM_TONECURVE;Use DCP's tone curve +TP_ICM_TONECURVE_TOOLTIP;Employ the embedded DCP tone curve. The setting is only enabled if the selected DCP has a tone curve. +TP_ICM_WORKINGPROFILE;Working Profile +TP_IMPULSEDENOISE_LABEL;Impulse Noise Reduction +TP_IMPULSEDENOISE_THRESH;Threshold +TP_LABCURVE_AVOIDCOLORSHIFT;Avoid color shift +TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP;Fit colors into gamut of the working color space and apply Munsell correction. +TP_LABCURVE_BRIGHTNESS;Lightness +TP_LABCURVE_CHROMATICITY;Chromaticity +TP_LABCURVE_CHROMA_TOOLTIP;To apply B&W toning, set Chromaticity to -100. +TP_LABCURVE_CONTRAST;Contrast +TP_LABCURVE_CURVEEDITOR;Luminance Curve +TP_LABCURVE_CURVEEDITOR_A_RANGE1;Green Saturated +TP_LABCURVE_CURVEEDITOR_A_RANGE2;Green Pastel +TP_LABCURVE_CURVEEDITOR_A_RANGE3;Red Pastel +TP_LABCURVE_CURVEEDITOR_A_RANGE4;Red Saturated +TP_LABCURVE_CURVEEDITOR_B_RANGE1;Blue Saturated +TP_LABCURVE_CURVEEDITOR_B_RANGE2;Blue Pastel +TP_LABCURVE_CURVEEDITOR_B_RANGE3;Yellow Pastel +TP_LABCURVE_CURVEEDITOR_B_RANGE4;Yellow Saturated +TP_LABCURVE_CURVEEDITOR_CC;CC +TP_LABCURVE_CURVEEDITOR_CC_RANGE1;Neutral +TP_LABCURVE_CURVEEDITOR_CC_RANGE2;Dull +TP_LABCURVE_CURVEEDITOR_CC_RANGE3;Pastel +TP_LABCURVE_CURVEEDITOR_CC_RANGE4;Saturated +TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP;Chromaticity according to chromaticity C=f(C) +TP_LABCURVE_CURVEEDITOR_CH;CH +TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP;Chromaticity according to hue C=f(H) +TP_LABCURVE_CURVEEDITOR_CL;CL +TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP;Chromaticity according to luminance C=f(L) +TP_LABCURVE_CURVEEDITOR_HH;HH +TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP;Hue according to hue H=f(H) +TP_LABCURVE_CURVEEDITOR_LC;LC +TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP;Luminance according to chromaticity L=f(C) +TP_LABCURVE_CURVEEDITOR_LH;LH +TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP;Luminance according to hue L=f(H) +TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP;Luminance according to luminance L=f(L) +TP_LABCURVE_LABEL;L*a*b* Adjustments +TP_LABCURVE_LCREDSK;Restrict LC to red and skin-tones +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_LENSGEOM_AUTOCROP;Auto-Crop +TP_LENSGEOM_FILL;Auto-fill +TP_LENSGEOM_LABEL;Lens / Geometry +TP_LENSPROFILE_LABEL;Lens Correction Profile +TP_LENSPROFILE_USECA;Chromatic aberration correction +TP_LENSPROFILE_USEDIST;Distortion correction +TP_LENSPROFILE_USEVIGN;Vignetting correction +TP_NEUTRAL;Neutral +TP_NEUTRAL_TIP;Resets exposure sliders to neutral values.\nApplies to the same controls that Auto Levels applies to, regardless of whether you used Auto Levels or not. +TP_PCVIGNETTE_FEATHER;Feather +TP_PCVIGNETTE_FEATHER_TOOLTIP;Feathering:\n0 = corners only,\n50 = halfway to center,\n100 = to center. +TP_PCVIGNETTE_LABEL;Vignette Filter +TP_PCVIGNETTE_ROUNDNESS;Roundness +TP_PCVIGNETTE_ROUNDNESS_TOOLTIP;Roundness:\n0 = rectangle,\n50 = fitted ellipse,\n100 = circle. +TP_PCVIGNETTE_STRENGTH;Strength +TP_PCVIGNETTE_STRENGTH_TOOLTIP;Filter strength in stops (reached in corners). +TP_PERSPECTIVE_HORIZONTAL;Horizontal +TP_PERSPECTIVE_LABEL;Perspective +TP_PERSPECTIVE_VERTICAL;Vertical +TP_PFCURVE_CURVEEDITOR_CH;Hue +TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Controls defringe strength by color.\nHigher = more,\nLower = less. +TP_PREPROCESS_DEADPIXFILT;Dead pixel filter +TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Tries to suppress dead pixels. +TP_PREPROCESS_GREENEQUIL;Green equilibration +TP_PREPROCESS_HOTPIXFILT;Hot pixel filter +TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Tries to suppress hot pixels. +TP_PREPROCESS_LABEL;Preprocessing +TP_PREPROCESS_LINEDENOISE;Line noise filter +TP_PREPROCESS_NO_FOUND;None found +TP_PRSHARPENING_LABEL;Post-Resize Sharpening +TP_PRSHARPENING_TOOLTIP;Sharpens the image after resizing. Only works when the "Lanczos" resizing method is used. It is impossible to preview the effects of this tool. See RawPedia for usage instructions. +TP_RAWCACORR_AUTO;Auto-correction +TP_RAWCACORR_CABLUE;Blue +TP_RAWCACORR_CARED;Red +TP_RAWEXPOS_BLACKS;Black Levels +TP_RAWEXPOS_BLACK_0;Green 1 (lead) +TP_RAWEXPOS_BLACK_1;Red +TP_RAWEXPOS_BLACK_2;Blue +TP_RAWEXPOS_BLACK_3;Green 2 +TP_RAWEXPOS_BLACK_BLUE;Blue +TP_RAWEXPOS_BLACK_GREEN;Green +TP_RAWEXPOS_BLACK_RED;Red +TP_RAWEXPOS_LINEAR;White-point correction +TP_RAWEXPOS_PRESER;Highlight preservation +TP_RAWEXPOS_RGB;Red, Green, Blue +TP_RAWEXPOS_TWOGREEN;Link greens +TP_RAW_DCBENHANCE;DCB enhancement +TP_RAW_DCBITERATIONS;Number of DCB iterations +TP_RAW_DMETHOD;Method +TP_RAW_DMETHOD_PROGRESSBAR;%1 demosaicing... +TP_RAW_DMETHOD_PROGRESSBAR_REFINE;Demosaicing refinement... +TP_RAW_DMETHOD_TOOLTIP;Note: IGV and LMMSE are dedicated to high ISO images to aid in noise reduction without leading to maze patterns, posterization or a washed-out look. +TP_RAW_FALSECOLOR;False color suppression steps +TP_RAW_HD;Threshold +TP_RAW_HD_TOOLTIP;Lower values make hot/dead pixel detection more aggressive, but false positives may lead to artifacts. If you notice any artifacts appearing when enabling the Hot/Dead Pixel Filters, gradually increase the threshold value until they disappear. +TP_RAW_LABEL;Demosaicing +TP_RAW_LMMSEITERATIONS;LMMSE enhancement steps +TP_RAW_LMMSE_TOOLTIP;Adds gamma (step 1), median (steps 2-4) and refinement (steps 5-6) to reduce artifacts and improve the signal-to-noise ratio. +TP_RAW_SENSOR_BAYER_LABEL;Sensor with Bayer Matrix +TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;3-pass gives best results (recommended for low ISO images).\n1-pass is almost undistinguishable from 3-pass for high ISO images and is faster. +TP_RAW_SENSOR_XTRANS_LABEL;Sensor with X-Trans Matrix +TP_RESIZE_APPLIESTO;Applies to: +TP_RESIZE_CROPPEDAREA;Cropped Area +TP_RESIZE_FITBOX;Bounding Box +TP_RESIZE_FULLIMAGE;Full Image +TP_RESIZE_HEIGHT;Height +TP_RESIZE_H;Height: +TP_RESIZE_LABEL;Resize +TP_RESIZE_LANCZOS;Lanczos +TP_RESIZE_METHOD;Method: +TP_RESIZE_NEAREST;Nearest +TP_RESIZE_SCALE;Scale +TP_RESIZE_SPECIFY;Specify: +TP_RESIZE_WIDTH;Width +TP_RESIZE_W;Width: +TP_RGBCURVES_BLUE;B +TP_RGBCURVES_CHANNEL;Channel +TP_RGBCURVES_GREEN;G +TP_RGBCURVES_LABEL;RGB Curves +TP_RGBCURVES_LUMAMODE;Luminosity mode +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_RGBCURVES_RED;R +TP_ROTATE_DEGREE;Degree +TP_ROTATE_LABEL;Rotate +TP_ROTATE_SELECTLINE;Select Straight Line +TP_SAVEDIALOG_OK_TIP;Shortcut: Ctrl-Enter +TP_SHADOWSHLIGHTS_HIGHLIGHTS;Highlights +TP_SHADOWSHLIGHTS_HLTONALW;Highlights tonal width +TP_SHADOWSHLIGHTS_LABEL;Shadows/Highlights +TP_SHADOWSHLIGHTS_LOCALCONTR;Local contrast +TP_SHADOWSHLIGHTS_RADIUS;Radius +TP_SHADOWSHLIGHTS_SHADOWS;Shadows +TP_SHADOWSHLIGHTS_SHARPMASK;Sharp mask +TP_SHADOWSHLIGHTS_SHTONALW;Shadows tonal width +TP_SHARPENEDGE_AMOUNT;Quantity +TP_SHARPENEDGE_LABEL;Edges +TP_SHARPENEDGE_PASSES;Iterations +TP_SHARPENEDGE_THREE;Luminance only +TP_SHARPENING_AMOUNT;Amount +TP_SHARPENING_EDRADIUS;Radius +TP_SHARPENING_EDTOLERANCE;Edge tolerance +TP_SHARPENING_HALOCONTROL;Halo control +TP_SHARPENING_HCAMOUNT;Amount +TP_SHARPENING_LABEL;Sharpening +TP_SHARPENING_METHOD;Method +TP_SHARPENING_ONLYEDGES;Sharpen only edges +TP_SHARPENING_RADIUS;Radius +TP_SHARPENING_RLD;RL Deconvolution +TP_SHARPENING_RLD_AMOUNT;Amount +TP_SHARPENING_RLD_DAMPING;Damping +TP_SHARPENING_RLD_ITERATIONS;Iterations +TP_SHARPENING_THRESHOLD;Threshold +TP_SHARPENING_TOOLTIP;Expect a slightly different effect when using with CIECAM02. If difference is observed, adjust to taste. +TP_SHARPENING_USM;Unsharp Mask +TP_SHARPENMICRO_AMOUNT;Quantity +TP_SHARPENMICRO_LABEL;Microcontrast +TP_SHARPENMICRO_MATRIX;3×3 matrix instead of 5×5 +TP_SHARPENMICRO_UNIFORMITY;Uniformity +TP_VIBRANCE_AVOIDCOLORSHIFT;Avoid color shift +TP_VIBRANCE_CURVEEDITOR_SKINTONES;HH +TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL;Skin-tones +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1;Red/Purple +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2;Red +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3;Red/Yellow +TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4;Yellow +TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP;Hue according to hue H=f(H) +TP_VIBRANCE_LABEL;Vibrance +TP_VIBRANCE_PASTELS;Pastel Tones +TP_VIBRANCE_PASTSATTOG;Link pastel and saturated tones +TP_VIBRANCE_PROTECTSKINS;Protect skin-tones +TP_VIBRANCE_PSTHRESHOLD;Pastel/saturated tones threshold +TP_VIBRANCE_PSTHRESHOLD_SATTHRESH;Saturation threshold +TP_VIBRANCE_PSTHRESHOLD_TOOLTIP;The vertical axis represents pastel tones at the bottom and saturated tones at the top.\nThe horizontal axis represents the saturation range. +TP_VIBRANCE_PSTHRESHOLD_WEIGTHING;Pastel/saturated transition's weighting +TP_VIBRANCE_SATURATED;Saturated Tones +TP_VIGNETTING_AMOUNT;Amount +TP_VIGNETTING_CENTER;Center +TP_VIGNETTING_CENTER_X;Center X +TP_VIGNETTING_CENTER_Y;Center Y +TP_VIGNETTING_LABEL;Vignetting Correction +TP_VIGNETTING_RADIUS;Radius +TP_VIGNETTING_STRENGTH;Strength +TP_WAVELET_1;Level 1 +TP_WAVELET_2;Level 2 +TP_WAVELET_3;Level 3 +TP_WAVELET_4;Level 4 +TP_WAVELET_5;Level 5 +TP_WAVELET_6;Level 6 +TP_WAVELET_7;Level 7 +TP_WAVELET_8;Level 8 +TP_WAVELET_9;Level 9 +TP_WAVELET_APPLYTO;Apply To +TP_WAVELET_AVOID;Avoid color shift +TP_WAVELET_B0;Black +TP_WAVELET_B1;Grey +TP_WAVELET_B2;Residual +TP_WAVELET_BACKGROUND;Background +TP_WAVELET_BACUR;Curve +TP_WAVELET_BALANCE;Contrast balance d/v-h +TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chromaticity or residual tone mapping are activated, the effect due to balance is amplified. +TP_WAVELET_BALCHRO;Chroma balance +TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chromaticity balance. +TP_WAVELET_BANONE;None +TP_WAVELET_BASLI;Slider +TP_WAVELET_BATYPE;Contrast balance method +TP_WAVELET_CBENAB;Toning and Color Balance +TP_WAVELET_CBTYPE;Toning and Color Balance +TP_WAVELET_CB_TOOLTIP;For strong values product color-toning by combining it or not with levels decomposition 'toning'\nFor low values you can change the white balance of the background (sky, ...) without changing that of the front plane, generally more contrasted +TP_WAVELET_CCURVE;Local contrast +TP_WAVELET_CH1;Whole chromaticity range +TP_WAVELET_CH2;Saturated/pastel +TP_WAVELET_CH3;Link contrast levels +TP_WAVELET_CHCU;Curve +TP_WAVELET_CHR;Chroma-contrast link strength +TP_WAVELET_CHRO;Saturated/pastel threshold +TP_WAVELET_CHRO_TOOLTIP;Sets the wavelet level which will be the threshold between saturated and pastel colors.\n1-x: saturated\nx-9: pastel\n\nIf the value exceeds the amount of wavelet levels you are using then it will be ignored. +TP_WAVELET_CHR_TOOLTIP;Adjusts chromaticity as a function of "contrast levels" and "chroma-contrast link strength" +TP_WAVELET_CHSL;Sliders +TP_WAVELET_CHTYPE;Chrominance method +TP_WAVELET_COLORT;Opacity Red-Green +TP_WAVELET_COMBOTH;Both +TP_WAVELET_COMPCONT;Contrast +TP_WAVELET_COMPGAMMA;Compression gamma +TP_WAVELET_COMPGAMMA_TOOLTIP;Adjust gamma for residual image and compression.\nAllow to equilibrate data and histogram +TP_WAVELET_COMPGAMMA_TOOLTIP;Adjusting the gamma of the residual image allow you to equilibrate the data and histogram. +TP_WAVELET_COMPTM;Tone mapping +TP_WAVELET_CONTEDIT;'After' Contrast curve +TP_WAVELET_CONTEDIT;'After' contrast curve +TP_WAVELET_CONTR;Gamut +TP_WAVELET_CONTRA;Contrast +TP_WAVELET_CONTRAST_MINUS;Contrast - +TP_WAVELET_CONTRAST_PLUS;Contrast + +TP_WAVELET_CONTRA_TOOLTIP;Changes contrast of the residual image. +TP_WAVELET_CTYPE;Chrominance control +TP_WAVELET_CURVEEDITOR_CC_TOOLTIP;Modifies local contrast as a function of the original local contrast (absciss)\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 100..300)\n66% absciss represents standard deviation of local contrast (real value about 300..800)\n100% represents maximum (real value about 3000..8000) +TP_WAVELET_CURVEEDITOR_CH;Contrast levels=f(Hue) +TP_WAVELET_CURVEEDITOR_CH_TOOLTIP;Modifies each level's contrast as a function oh hue.\nTake care not to overwrite changes made with the Gamut Hue controls.\nThe curve will only have an effect when wavelet contrast level sliders are non-zero. +TP_WAVELET_CURVEEDITOR_CL;L +TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Applies a final contrast luminance curve at the end of the wavelet treatment. +TP_WAVELET_CURVEEDITOR_CL_TOOLTIP;Apply a contrast luminance curve at the end of wavelet level threatment +TP_WAVELET_CURVEEDITOR_HH;HH +TP_WAVELET_CURVEEDITOR_HH_TOOLTIP;Modifies the residual image's hue as a function of hue. +TP_WAVELET_DALL;All directions +TP_WAVELET_DAUB10;D10 - medium +TP_WAVELET_DAUB14;D14 - high +TP_WAVELET_DAUB2;D2 - low +TP_WAVELET_DAUB4;D4 - standard +TP_WAVELET_DAUB6;D6 - standard plus +TP_WAVELET_DAUB;Edge performance +TP_WAVELET_DAUB_TOOLTIP;Changes Daubechies coefficients:\nD4 = Standard,\nD14 = Often best performance, 10% more time-intensive.\n\nAffects edge detection as well as the general quality of the firsts levels. However the quality is not strictly related to this coefficient and can vary with images and uses. +TP_WAVELET_DONE;Vertical +TP_WAVELET_DTHR;Diagonal +TP_WAVELET_DTWO;Horizontal +TP_WAVELET_EDCU;Curve +TP_WAVELET_EDGCONT;Local contrast +TP_WAVELET_EDGCONT_TOOLTIP;Adjusting the points to the left decreases contrast, and to the right increases it.\nBottom-left, Top-Left, Top-Right, Bottom-right represent respectively local contast for low values, mean, mean+stdev, maxima +TP_WAVELET_EDGE;Edge Sharpness +TP_WAVELET_EDGEDETECT;Gradient sensitivity +TP_WAVELET_EDGEDETECTTHR2;Threshold high (detection) +TP_WAVELET_EDGEDETECTTHR;Threshold low (noise) +TP_WAVELET_EDGEDETECTTHR_TOOLTIP;This adjuster lets you target edge detection for example to avoid applying edge sharpness to fine details, such as noise in the sky. +TP_WAVELET_EDGEDETECT_TOOLTIP;Moving the slider to the right increases edge sensitivity. This affects local contrast, edge settings and noise. +TP_WAVELET_EDGREINF_TOOLTIP;Reinforce or reduce the action of the first level, do the opposite to the second level, and leave the rest unchanged. +TP_WAVELET_EDGTHRESH;Detail +TP_WAVELET_EDGTHRESH_TOOLTIP;Change the repartition between the first levels and the others. The higher the threshold the more the action is centred on the first levels. Be careful with negative values, they increase the action of high levels and can introduce artifacts. +TP_WAVELET_EDRAD;Radius +TP_WAVELET_EDRAD_TOOLTIP;This radius adjustment is very different from those in other sharpening tools. Its value is compared to each level through a complex function. In this sense, a value of zero still has an effect. +TP_WAVELET_EDSL;Threshold Sliders +TP_WAVELET_EDTYPE;Local contrast method +TP_WAVELET_EDVAL;Strength +TP_WAVELET_FINAL;Final Touchup +TP_WAVELET_FINEST;Finest +TP_WAVELET_HIGHLIGHT;Highlight luminance range +TP_WAVELET_HS1;Whole luminance range +TP_WAVELET_HS2;Shadows/Highlights +TP_WAVELET_HUESKIN;Skin hue +TP_WAVELET_HUESKIN_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +TP_WAVELET_HUESKY;Sky hue +TP_WAVELET_HUESKY_TOOLTIP;The bottom points set the beginning of the transition zone, and the upper points the end of it, where the effect is at its maximum.\n\nIf you need to move the area significantly, or if there are artifacts, then the white balance is incorrect. +TP_WAVELET_ITER;Delta balance levels +TP_WAVELET_ITER_TOOLTIP;Left: increase low levels and reduce high levels,\nRight: reduce low levels and increase high levels. +TP_WAVELET_LABEL;Wavelet Levels +TP_WAVELET_LARGEST;Coarsest +TP_WAVELET_LEVCH;Chromaticity +TP_WAVELET_LEVDIR_ALL;All levels in all directions +TP_WAVELET_LEVDIR_INF;Below or equal the level +TP_WAVELET_LEVDIR_ONE;One level +TP_WAVELET_LEVDIR_SUP;Above the level +TP_WAVELET_LEVELS;Wavelet levels +TP_WAVELET_LEVELS_TOOLTIP;Choose the number of detail levels the image is to be decomposed into. More levels require more RAM and require a longer processing time. +TP_WAVELET_LEVF;Contrast +TP_WAVELET_LEVLABEL;Preview maximum possible levels = %1 +TP_WAVELET_LEVONE;Level 2 +TP_WAVELET_LEVTWO;Level 3 +TP_WAVELET_LEVZERO;Level 1 +TP_WAVELET_LINKEDG;Link with Edge Sharpness' Strength +TP_WAVELET_LIPST;Enhanced algorithm +TP_WAVELET_LIPST_TOOLTIP;This algorithm uses Lipschitz regularity to increase edge detection quality at a cost of increased processing time and memory requirements. +TP_WAVELET_LOWLIGHT;Shadow luminance range +TP_WAVELET_MEDGREINF;First level +TP_WAVELET_MEDI;Reduce artifacts in blue sky +TP_WAVELET_MEDILEV;Edge detection +TP_WAVELET_NEUTRAL;Neutral +TP_WAVELET_NOIS;Denoise +TP_WAVELET_NOISE;Denoise and Refine +TP_WAVELET_OPACITY;Opacity Blue-Yellow +TP_WAVELET_OPACITYW;Contrast balance d/v-h curve +TP_WAVELET_OPACITYWL;Final local contrast +TP_WAVELET_OPACITYWL_TOOLTIP;Modify final local contrast in function of last local contrast (absciss) for all levels decomposition\nTake into account: \na)contrast levels \nb)edge sharpness \nc)contrast balance\nd)decomposition-recomposition\nLow absciss represents small local contrast (real values about 10..20)\n50% absciss represents average of local contrast (real value about 200..1000)\n66% absciss represents standard deviation of local contrast (real value about 1000..2000)\n100% represents maximum (real value about 5000..13000) +TP_WAVELET_OPACITYWL_TOOLTIP;Modify the final local contrast at the end of the wavelet treatment.\n\nThe left side represents the smallest local contrast, progressing to the largest local contrast on the right. +TP_WAVELET_PASTEL;Pastel chromaticity +TP_WAVELET_PROC;Process +TP_WAVELET_RE1;Reinforced +TP_WAVELET_RE2;Unchanged +TP_WAVELET_RE3;Reduced +TP_WAVELET_RESCHRO;Chromaticity +TP_WAVELET_RESCON;Shadows +TP_WAVELET_RESCONH;Highlights +TP_WAVELET_RESID;Residual Image +TP_WAVELET_SAT;Saturated chromaticity +TP_WAVELET_SETTINGS;Wavelet Settings +TP_WAVELET_SKIN;Skin targetting/protection +TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected. +TP_WAVELET_SKY;Sky targetting/protection +TP_WAVELET_SKY_TOOLTIP;At -100 sky-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 sky-tones are protected while all other tones are affected. +TP_WAVELET_STREN;Strength +TP_WAVELET_STRENGTH;Strength +TP_WAVELET_SUPE;Extra +TP_WAVELET_THR;Shadows threshold +TP_WAVELET_THRESHOLD2;Shadow levels +TP_WAVELET_THRESHOLD2_TOOLTIP;Only levels between 9 and 9 minus the value will be affected by the shadow luminance range. Other levels will be fully treated. The highest level possible is limited by the highlight level value (9 minus highlight level value). +TP_WAVELET_THRESHOLD;Highlight levels +TP_WAVELET_THRESHOLD_TOOLTIP;Only levels beyond the chosen value will be affected by the highlight luminance range. Other levels will be fully treated. The chosen value here limits the highest possible value of the shadow levels. +TP_WAVELET_THRH;Highlights threshold +TP_WAVELET_TILESBIG;Big tiles +TP_WAVELET_TILESFULL;Full image +TP_WAVELET_TILESIZE;Tiling method +TP_WAVELET_TILESLIT;Little tiles +TP_WAVELET_TILES_TOOLTIP;Processing the full image leads to better quality and is the recommended option, while using tiles is a fall-back solution for users with little RAM. Refer to RawPedia for memory requirements. +TP_WAVELET_TMHIGH;High +TP_WAVELET_TMLOWHIGH;Low+High +TP_WAVELET_TMNONE;None +TP_WAVELET_TMSTD;Standard +TP_WAVELET_TMSTRENGTH;Compression strength +TP_WAVELET_TMSTRENGTH_TOOLTIP;Control the strength of tone mapping or contrast compression of the residual image. When the value is different from 0, the Strength and Gamma sliders of the Tone Mapping tool in the Exposure tab will become grayed out. +TP_WAVELET_TMTYPE;Compression method +TP_WAVELET_TON;Toning +TP_WBALANCE_AUTO;Auto +TP_WBALANCE_CAMERA;Camera +TP_WBALANCE_CLOUDY;Cloudy +TP_WBALANCE_CUSTOM;Custom +TP_WBALANCE_DAYLIGHT;Daylight (sunny) +TP_WBALANCE_EQBLUERED;Blue/Red equalizer +TP_WBALANCE_EQBLUERED_TOOLTIP;Allows to deviate from the normal behavior of "white balance" by modulating the blue/red balance.\nThis can be useful when shooting conditions:\na) are far from the standard illuminant (e.g. underwater),\nb) are far from conditions where calibrations were performed,\nc) where the matrices or ICC profiles are unsuitable. +TP_WBALANCE_FLASH55;Leica +TP_WBALANCE_FLASH60;Standard, Canon, Pentax, Olympus +TP_WBALANCE_FLASH65;Nikon, Panasonic, Sony, Minolta +TP_WBALANCE_FLASH_HEADER;Flash +TP_WBALANCE_FLUO1;F1 - Daylight +TP_WBALANCE_FLUO2;F2 - Cool White +TP_WBALANCE_FLUO3;F3 - White +TP_WBALANCE_FLUO4;F4 - Warm White +TP_WBALANCE_FLUO5;F5 - Daylight +TP_WBALANCE_FLUO6;F6 - Lite White +TP_WBALANCE_FLUO7;F7 - D65 Daylight Simulator +TP_WBALANCE_FLUO8;F8 - D50 / Sylvania F40 Design +TP_WBALANCE_FLUO9;F9 - Cool White Deluxe +TP_WBALANCE_FLUO10;F10 - Philips TL85 +TP_WBALANCE_FLUO11;F11 - Philips TL84 +TP_WBALANCE_FLUO12;F12 - Philips TL83 +TP_WBALANCE_FLUO_HEADER;Fluorescent +TP_WBALANCE_GREEN;Tint +TP_WBALANCE_GTI;GTI +TP_WBALANCE_HMI;HMI +TP_WBALANCE_JUDGEIII;JudgeIII +TP_WBALANCE_LABEL;White Balance +TP_WBALANCE_LAMP_HEADER;Lamp +TP_WBALANCE_LED_CRS;CRS SP12 WWMR16 +TP_WBALANCE_LED_HEADER;LED +TP_WBALANCE_LED_LSI;LSI Lumelex 2040 +TP_WBALANCE_METHOD;Method +TP_WBALANCE_SHADE;Shade +TP_WBALANCE_SIZE;Size: +TP_WBALANCE_SOLUX35;Solux 3500K +TP_WBALANCE_SOLUX41;Solux 4100K +TP_WBALANCE_SOLUX47;Solux 4700K (vendor) +TP_WBALANCE_SOLUX47_NG;Solux 4700K (Nat. Gallery) +TP_WBALANCE_SPOTWB;Spot WB +TP_WBALANCE_TEMPERATURE;Temperature +TP_WBALANCE_TUNGSTEN;Tungsten +TP_WBALANCE_WATER1;UnderWater 1 +TP_WBALANCE_WATER2;UnderWater 2 +TP_WBALANCE_WATER_HEADER;UnderWater +ZOOMPANEL_100;(100%) +ZOOMPANEL_NEWCROPWINDOW;Open (new) detail window +ZOOMPANEL_ZOOM100;Zoom to 100%\nShortcut: z +ZOOMPANEL_ZOOMFITCROPSCREEN;Fit crop to screen\nShortcut: Alt-f +ZOOMPANEL_ZOOMFITSCREEN;Fit whole image to screen\nShortcut: f +ZOOMPANEL_ZOOMIN;Zoom In\nShortcut: + +ZOOMPANEL_ZOOMOUT;Zoom Out\nShortcut: - diff --git a/rtdata/options/options.lin b/rtdata/options/options.lin new file mode 100644 index 000000000..bbc1de057 --- /dev/null +++ b/rtdata/options/options.lin @@ -0,0 +1,38 @@ +# Only important or pre-first run parameters are left in this global option file. +# After the first run, all the parameters will be available in this global option file +# or in a new local option file, depending on the MultiUser value below + +# Most ot the options are modifiable through the Preference window + +[General] +# Setting MultiUser to false will use the application's installation directory as cache directory, +# which can be usefull if you want to keep the application and all the cache datas in a single place, +# an external HD for example +MultiUser=true + +[File Browser] +# Image filename extensions to be looked for, and their corresponding search state (0/1 -> skip/include) +ParseExtensions=3fr;arw;cr2;crf;crw;dcr;dng;fff;iiq;jpg;jpeg;kdc;mef;mos;mrw;nef;nrw;orf;pef;png;raf;raw;rw2;rwl;rwz;sr2;srf;srw;tif;tiff;x3f; +ParseExtensionsEnabled=1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1; + +[Output] +PathTemplate=%p1/converted/%f + +[Profiles] +# if this is set to a path of a custom program, it will receive the EXIFs as parameters and must generate a PP3 preset file for the given raw/JPG +# Parameters: +CustomProfileBuilder= + +# Set here an absolute or relative path (to the rawtherapee.exe file) to the directory containing your own profiles. +# If MultiUser=true, each user will have their own "options" file, and can set a common or different absolu path +#Directory=profiles + +# Uncomment and set UseBundledProfiles to false if you don't want to be polluted by RawTherapee's bundled profiles +# Warning: if you don't set RawDefault and ImgDefault to one of your own profile, Internal values will be used instead +#UseBundledProfiles=true + +# Default profile name (without extension) to use for raw images +#RawDefault=${G}/Default + +# Default profile name (without extension) to use for standard (8bits) images +#ImgDefault=Neutral diff --git a/rtdata/options/options.osx b/rtdata/options/options.osx new file mode 100644 index 000000000..4d35255cd --- /dev/null +++ b/rtdata/options/options.osx @@ -0,0 +1,41 @@ +# Only important or pre-first run parameters are left in this global option file. +# After the first run, all the parameters will be available in this global option file +# or in a new local option file, depending on the MultiUser value below + +# Most ot the options are modifiable through the Preference window + +[General] +# Setting MultiUser to false will use the application's installation directory as cache directory, +# which can be usefull if you want to keep the application and all the cache datas in a single place, +# an external HD for example +MultiUser=true + +[File Browser] +# Image filename extensions to be looked for, and their corresponding search state (0/1 -> skip/include) +ParseExtensions=3fr;arw;cr2;crf;crw;dcr;dng;fff;iiq;jpg;jpeg;kdc;mef;mos;mrw;nef;nrw;orf;pef;png;raf;raw;rw2;rwl;rwz;sr2;srf;srw;tif;tiff;x3f; +ParseExtensionsEnabled=1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1; + +[Output] +PathTemplate=%p1/converted/%f + +[Profiles] +# if this is set to a path of a custom program, it will receive the EXIFs as parameters and must generate a PP3 preset file for the given raw/JPG +# Parameters: +CustomProfileBuilder= + +[GUI] +Font=Sans 12 + +# Set here an absolute or relative path (to the rawtherapee.exe file) to the directory containing your own profiles. +# If MultiUser=true, each user will have their own "options" file, and can set a common or different absolu path +#Directory=profiles + +# Uncomment and set UseBundledProfiles to false if you don't want to be polluted by RawTherapee's bundled profiles +# Warning: if you don't set RawDefault and ImgDefault to one of your own profile, Internal values will be used instead +#UseBundledProfiles=true + +# Default profile name (without extension) to use for raw images +#RawDefault=${G}/Default + +# Default profile name (without extension) to use for standard (8bits) images +#ImgDefault=Neutral diff --git a/rtdata/options/options.win b/rtdata/options/options.win new file mode 100644 index 000000000..3f309fd16 --- /dev/null +++ b/rtdata/options/options.win @@ -0,0 +1,40 @@ +# Only important or pre-first run parameters are left in this global option file. +# After the first run, all the parameters will be available in this global option file +# or in a new local option file, depending on the MultiUser value below + +# Most ot the options are modifiable through the Preference window + +[General] +# Setting MultiUser to false will use the application's installation directory as cache directory, +# which can be usefull if you want to keep the application and all the cache datas in a single place, +# an external HD for example +MultiUser=true +# Windows users should not use the system theme : some composed widget won't be usable +UseSystemTheme=false + +[File Browser] +# Image filename extensions to be looked for, and their corresponding search state (0/1 -> skip/include) +ParseExtensions=3fr;arw;cr2;crf;crw;dcr;dng;fff;iiq;jpg;jpeg;kdc;mef;mos;mrw;nef;nrw;orf;pef;png;raf;raw;rw2;rwl;rwz;sr2;srf;srw;tif;tiff;x3f; +ParseExtensionsEnabled=1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;0;1;1;1;1;1;1;1;1;1;1;1; + +[Output] +PathTemplate=%p1/converted/%f + +[Profiles] +# if this is set to a path of a custom program, it will receive the EXIFs as parameters and must generate a PP3 preset file for the given raw/JPG +# Parameters: +CustomProfileBuilder= + +# Set here an absolute or relative path (to the rawtherapee.exe file) to the directory containing your own profiles. +# If MultiUser=true, each user will have their own "options" file, and can set a common or different absolu path +#Directory=profiles + +# Uncomment and set UseBundledProfiles to false if you don't want to be polluted by RawTherapee's bundled profiles +# Warning: if you don't set RawDefault and ImgDefault to one of your own profile, Internal values will be used instead +#UseBundledProfiles=true + +# Default profile name (without extension) to use for raw images +#RawDefault=${G}\\Default + +# Default profile name (without extension) to use for standard (8bits) images +#ImgDefault=Neutral diff --git a/rtdata/osx/Info.plist.in b/rtdata/osx/Info.plist.in new file mode 100644 index 000000000..491d2ee85 --- /dev/null +++ b/rtdata/osx/Info.plist.in @@ -0,0 +1,167 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleDisplayName + RawTherapee + CFBundleDocumentTypes + + + CFBundleTypeExtensions + + pp3 + PP3 + + CFBundleTypeIconFile + profile.icns + CFBundleTypeName + RawTherapee Profile Data + CFBundleTypeRole + Editor + LSIsAppleDefaultForType + + LSItemContentTypes + + com.rawtherapee.pp3 + + + + CFBundleTypeExtensions + + 3FR + 3fr + ARW + arw + CR2 + cr2 + CRF + crf + CRW + crw + DCR + dcr + DNG + dng + FFF + fff + IIQ + iiq + KDC + kdc + MEF + mef + MOS + mos + MRW + mrw + NEF + nef + NRW + nrw + ORF + orf + PEF + pef + RAF + raf + RAW + raw + RW2 + rw2 + RWZ + rwz + SR2 + sr2 + SRF + srf + SRW + srw + + CFBundleTypeMIMETypes + + image/raw + + CFBundleTypeName + Camera Raw + CFBundleTypeRole + Viewer + + + CFBundleTypeExtensions + + JPEG + jpeg + JPG + jpg + PNG + png + TIF + tif + TIFF + tiff + + CFBundleTypeName + Image + CFBundleTypeRole + Viewer + + + CFBundleExecutable + rawtherapee + CFBundleGetInfoString + @version@, Copyright © 2004-2013 Gábor Horváth + CFBundleIconFile + rawtherapee.icns + CFBundleIdentifier + com.rawtherapee.rawtherapee + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + RawTherapee + CFBundlePackageType + APPL + CFBundleShortVersionString + @shortVersion@ + CFBundleSignature + ???? + CFBundleVersion + @version@ + LSExecutableArchitectures + + @arch@ + + NSHighResolutionCapable + + NSHumanReadableCopyright + Copyright © 2004-2013 Gábor Horváth + UTExportedTypeDeclarations + + + UTTypeConformsTo + + public.data + + UTTypeDescription + RawTherapee Profile Data + UTTypeIconFile + Icons.icns + UTTypeIdentifier + com.rawtherapee.pp3 + UTTypeReferenceURL + http://www.rawtherapee.com/ + UTTypeTagSpecification + + com.apple.ostype + PP3 + public.filename-extension + + pp3 + PP3 + + + + + + diff --git a/rtdata/osx/PkgInfo b/rtdata/osx/PkgInfo new file mode 100644 index 000000000..6f749b0f3 --- /dev/null +++ b/rtdata/osx/PkgInfo @@ -0,0 +1 @@ +APPL???? diff --git a/rtdata/osx/executable_loader.in b/rtdata/osx/executable_loader.in new file mode 100644 index 000000000..d56cd1dc1 --- /dev/null +++ b/rtdata/osx/executable_loader.in @@ -0,0 +1,30 @@ +#!/bin/bash + +cwd="$(cd "$(dirname "$0")"; pwd)" +app="${cwd%/Contents/*}" +etc="${cwd}"/etc + +# for different os x version (issue 1795) +cups_dir=/tmp/RT4 +install -d ${cups_dir} +cp -f /usr/lib/libcups.2.dylib ${cups_dir} + +export DYLD_LIBRARY_PATH="${cwd}"/lib:${cups_dir} +export GTK_EXE_PREFIX="${cwd}" +export GTK_DATA_PREFIX="${cwd}" +export GTK_IM_MODULE_FILE="${etc}"/gtk-2.0/gtk.immodules +export GDK_PIXBUF_MODULE_FILE="${etc}"/gtk-2.0/gdk-pixbuf.loaders +export XDG_DATA_DIRS="${cwd}"/share +export PANGO_RC_FILE="${etc}"/pango/pangorc + +# environment variables for X11 backend +if test -d "${etc}"/fonts; then + export FONTCONFIG_PATH="${etc}"/fonts +fi + +# strip out system argument +case $1 in -psn_*) shift;; esac + +ln -sf "${app}" /tmp + +exec "${cwd}"/rawtherapee-bin "$@" diff --git a/rtdata/osx/macosx_bundle.sh b/rtdata/osx/macosx_bundle.sh new file mode 100644 index 000000000..6667548c5 --- /dev/null +++ b/rtdata/osx/macosx_bundle.sh @@ -0,0 +1,183 @@ +#!/bin/bash + +# Required variables +# ------------------ +# these are very important variables. Must be set into rtdata/CMakeLists.txt! +# - PROJECT_NAME +# - PROJECT_SOURCE_DIR +# - PROJECT_VERSION (if without mercurial) +# - CMAKE_BUILD_TYPE +# - PROC_BIT_DEPTH +# - GTK_PREFIX + +function message { + printf '\e[34m-- %s\e[m\n' "$*" +} +function GetDependencies { + otool -L "$1" | awk 'NR >= 2 && $1 !~ /^(\/usr\/lib|\/System|@executable_path|@rpath)\// { print $1 }' +} +function CheckLink { + GetDependencies "$1" | while read; do + local dest="${LIB}/$(basename "${REPLY}")" + test -f "${dest}" || { ditto --arch ${arch} "${REPLY}" "${dest}"; CheckLink "${dest}"; } + done +} + +# source check +if test ! -d "${CMAKE_BUILD_TYPE}"; then + printf "\e[31m${PWD}/${CMAKE_BUILD_TYPE} directory is not found. Please execute 'make install' first.\e[m\n" + exit 1 +fi + +# update project version +if test -x $(which hg) -a -d "${PROJECT_SOURCE_DIR}/.hg"; then + PROJECT_VERSION=$(hg -R "${PROJECT_SOURCE_DIR}" parents --template "{latesttag}.{latesttagdistance}") +fi + +# if not specify CMAKE_OSX_DEPLOYMENT_TARGET when compiling, +# 'MINIMUM_VERSION' will be used host OS X version. +MINIMUM_SYSTEM_VERSION=$(otool -l "${CMAKE_BUILD_TYPE}"/rawtherapee | grep -A2 'LC_VERSION_MIN_MACOSX' | awk '$1 ~ /version/ { printf $2 }') +if test ! -n "${MINIMUM_SYSTEM_VERSION}"; then + MINIMUM_SYSTEM_VERSION=$(sw_vers -productVersion | cut -d. -f-2) +fi + +case ${PROC_BIT_DEPTH} in + 64) arch=x86_64;; + 32) arch=i386;; +esac + +cat <<__EOS__ +PROJECT_NAME: ${PROJECT_NAME} +PROJECT_VERSION: ${PROJECT_VERSION} +PROJECT_SOURCE_DIR: ${PROJECT_SOURCE_DIR} +CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE} +PROC_BIT_DEPTH: ${PROC_BIT_DEPTH} +MINIMUM_SYSTEM_VERSION: ${MINIMUM_SYSTEM_VERSION} +GTK_PREFIX: ${GTK_PREFIX} +PWD: ${PWD} +__EOS__ + +APP="${PROJECT_NAME}".app +CONTENTS="${APP}"/Contents +RESOURCES="${CONTENTS}"/Resources +MACOS="${CONTENTS}"/MacOS +LIB="${MACOS}"/lib +ETC="${MACOS}"/etc +EXECUTABLE="${MACOS}"/rawtherapee + +message "Removing old files" +rm -rf "${APP}" ${PROJECT_NAME}_*.dmg + +message "Creating bundle container" +install -d "${RESOURCES}" \ + "${MACOS}" \ + "${LIB}" \ + "${ETC}" + +message "Copying release files" +ditto "${CMAKE_BUILD_TYPE}" "${MACOS}" + +message "Copying dependencies from ${GTK_PREFIX}" +CheckLink "${EXECUTABLE}" + +message "Copying library modules from ${GTK_PREFIX}" +ditto --arch ${arch} {"${GTK_PREFIX}"/lib,"${LIB}"}/gdk-pixbuf-2.0 +ditto --arch ${arch} {"${GTK_PREFIX}"/lib,"${LIB}"}/gtk-2.0 +ditto --arch ${arch} {"${GTK_PREFIX}"/lib,"${LIB}"}/pango + +message "Removing static libraries and cache files" +find -E "${LIB}" -type f -regex '.*\.(a|la|cache)$' | while read; do rm "${REPLY}"; done + +message "Copying configuration files from ${GTK_PREFIX}" +install -d "${ETC}"/{gtk-2.0,pango} +cp "${GTK_PREFIX}"/etc/gtk-2.0/im-multipress.conf "${ETC}"/gtk-2.0 +"${GTK_PREFIX}"/bin/gdk-pixbuf-query-loaders "${LIB}"/gdk-pixbuf-2.0/*/loaders/*.so > "${ETC}"/gtk-2.0/gdk-pixbuf.loaders +"${GTK_PREFIX}"/bin/gtk-query-immodules-2.0 "${LIB}"/gtk-2.0/*/immodules/*.so > "${ETC}"/gtk-2.0/gtk.immodules +"${GTK_PREFIX}"/bin/pango-querymodules "${LIB}"/pango/*/modules/*.so > "${ETC}"/pango/pango.modules +sed -i "" -e "s|${PWD}|/tmp|" "${ETC}"/gtk-2.0/gdk-pixbuf.loaders \ + "${ETC}"/gtk-2.0/gtk.immodules \ + "${ETC}"/pango/pango.modules +printf "[Pango]\nModuleFiles = /tmp/${ETC}/pango/pango.modules" > "${ETC}"/pango/pangorc + + + +message "Copying shared files from ${GTK_PREFIX}" +cp -R "${GTK_PREFIX}"/share/mime "${MACOS}"/share +# gtk themes +ditto {"${GTK_PREFIX}","${MACOS}"}/share/themes/Mac/gtk-2.0-key/gtkrc +ditto {"${GTK_PREFIX}","${MACOS}"}/share/themes/Clearlooks/gtk-2.0/gtkrc +install -d "${MACOS}"/share/themes/Raleigh/gtk-2.0 +(cd "${MACOS}"/share/themes/Raleigh/gtk-2.0 && ln -s ../../Clearlooks/gtk-2.0/gtkrc) +# fontconfig files (X11 backend only) +if otool -L "${EXECUTABLE}" | grep -sq 'libgtk-x11-2.0'; then + message "Installing fontconfig files (Your library is X11 backend. 'FONTCONFIG_PATH' will be set by executable loader.)" + cp -RL "${GTK_PREFIX}"/etc/fonts "${ETC}" +fi + + + +# install names +find -E "${MACOS}" -type f -regex '.*/(rawtherapee|.*\.(dylib|so))' | while read x; do + message "Modifying install names: ${x}" + { + # id + case ${x} in *.dylib) echo " install_name_tool -id '@rpath/$(basename "${x}")' '${x}'";; esac + # names + GetDependencies "${x}" | while read y; do + echo " install_name_tool -change '${y}' '@rpath/$(basename "${y}")' '${x}'" + done + } | bash -v +done + +message "Registering @loader_path into the executable" +echo " install_name_tool -add_rpath @loader_path/lib '${EXECUTABLE}'" | bash -v + + + +message "Installing required application bundle files" +PROJECT_SOURCE_DATA_DIR="${PROJECT_SOURCE_DIR}"/rtdata/osx +# executable loader +# note: executable is renamed to 'rawtherapee-bin'. +mv "${MACOS}"/rawtherapee{,-bin} +install -m 0755 "${PROJECT_SOURCE_DATA_DIR}"/executable_loader.in "${MACOS}"/rawtherapee +# app bundle resources +cp "${PROJECT_SOURCE_DATA_DIR}"/{rawtherapee,profile}.icns "${RESOURCES}" +cp "${PROJECT_SOURCE_DATA_DIR}"/PkgInfo "${CONTENTS}" +install -m 0644 "${PROJECT_SOURCE_DATA_DIR}"/Info.plist.in "${CONTENTS}"/Info.plist +sed -i "" -e "s|@version@|${PROJECT_VERSION}| + s|@shortVersion@|$(echo ${PROJECT_VERSION} | cut -d. -f-3)| + s|@arch@|${arch}|" \ + "${CONTENTS}"/Info.plist +plutil -convert binary1 "${CONTENTS}"/Info.plist + + + +function CreateDmg { + local srcdir=$(mktemp -dt $$) + + message "Preparing disk image sources at ${srcdir}" + mv "${APP}" ${srcdir} + cp AboutThisBuild.txt ${srcdir} + ln -s /Applications ${srcdir} + + # web bookmarks + function CreateWebloc { + defaults write ${srcdir}/"$1" URL "$2" + mv ${srcdir}/"$1".{plist,webloc} + } + CreateWebloc 'RawTherapee Blog' 'http://www.rawtherapee.com' + CreateWebloc 'Online Manual' 'https://docs.google.com/document/d/1DHLb_6xNQsEInxiuU8pz1-sWNinnj09bpBUA4_Vl8w8/edit' + + # disk image name + dmg_name="${PROJECT_NAME// /_}_OSX_${MINIMUM_SYSTEM_VERSION}_${PROC_BIT_DEPTH}_${PROJECT_VERSION}" + if ! echo ${CMAKE_BUILD_TYPE} | grep -sqi "release"; then + dmg_name="${dmg_name}_$(echo ${CMAKE_BUILD_TYPE} | tr '[:upper:]' '[:lower:]')" + fi + + message "Creating disk image" + hdiutil create -format UDBZ -srcdir ${srcdir} -volname "${PROJECT_NAME}_${PROJECT_VERSION}" "${dmg_name}".dmg + + message "Removing disk image caches" + rm -rf ${srcdir} +} +CreateDmg diff --git a/rtdata/osx/profile.icns b/rtdata/osx/profile.icns new file mode 100644 index 000000000..fbe7831ec Binary files /dev/null and b/rtdata/osx/profile.icns differ diff --git a/rtdata/osx/rawtherapee.icns b/rtdata/osx/rawtherapee.icns new file mode 100644 index 000000000..49583ca23 Binary files /dev/null and b/rtdata/osx/rawtherapee.icns differ diff --git a/rtdata/profiles/BW/BW 1.pp3 b/rtdata/profiles/BW/BW 1.pp3 new file mode 100644 index 000000000..8ee75890b --- /dev/null +++ b/rtdata/profiles/BW/BW 1.pp3 @@ -0,0 +1,162 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=true +Clip=0.02 +Compensation=0 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=0 +HighlightComprThreshold=33 +ShadowCompr=50 +CurveMode=Standard +CurveMode2=Standard +Curve=1;0;0;0.04;0.03;0.17684498029510265;0.21732319394192093;0.70232558139534862;0.74883720930232545;1;1; +Curve2=0; + +[HLRecovery] +Enabled=false +Method=Blend + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Black & White] +Enabled=true +Method=Desaturation +Auto=false +ComplementaryColors=true +Setting=NormalContrast +Filter=None +MixerRed=43 +MixerOrange=33 +MixerYellow=33 +MixerGreen=33 +MixerCyan=33 +MixerBlue=30 +MixerMagenta=33 +MixerPurple=33 +GammaRed=0 +GammaGreen=0 +GammaBlue=0 +LuminanceCurve=0; +BeforeCurveMode=Standard +AfterCurveMode=Standard +BeforeCurve=0; +AfterCurve=0; + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=-100 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +lhCurve=0; +hhCurve=0; +LcCurve=0; +ClCurve=0; + +[Vibrance] +Enabled=false +Pastels=50 +Saturated=50 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false +Degree=90 +AutoDegree=true +Surround=Average +AdaptLum=16 +Badpixsl=0 +Model=RawT +Algorithm=JC +J-Light=0 +Q-Bright=0 +C-Chroma=0 +S-Chroma=0 +M-Chroma=0 +J-Contrast=0 +Q-Contrast=0 +H-Hue=0 +RSTProtection=0 +AdaptScene=2000 +AutoAdapscen=true +SurrSource=false +Gamut=true +Datacie=false +Tonecie=false +CurveMode=Lightness +CurveMode2=Lightness +CurveMode3=Chroma +Curve=0; +Curve2=0; +Curve3=0; + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.4 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=10 +HighlightTonalWidth=80 +Shadows=10 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=30 + +[Gradient] +Enabled=false +Degree=0 +Feather=25 +Strength=0.6 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0.6 +Feather=50 +Roundness=50 + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/BW/BW 2.pp3 b/rtdata/profiles/BW/BW 2.pp3 new file mode 100644 index 000000000..f45ce9eb8 --- /dev/null +++ b/rtdata/profiles/BW/BW 2.pp3 @@ -0,0 +1,162 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=true +Clip=0.02 +Compensation=0 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=0 +HighlightComprThreshold=33 +ShadowCompr=50 +CurveMode=Standard +CurveMode2=Standard +Curve=1;0;0;0.45754265471370759;0.57906737998843294;1;1; +Curve2=0; + +[HLRecovery] +Enabled=false +Method=Blend + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Black & White] +Enabled=true +Method=Desaturation +Auto=false +ComplementaryColors=true +Setting=NormalContrast +Filter=None +MixerRed=43 +MixerOrange=33 +MixerYellow=33 +MixerGreen=33 +MixerCyan=33 +MixerBlue=30 +MixerMagenta=33 +MixerPurple=33 +GammaRed=0 +GammaGreen=0 +GammaBlue=0 +LuminanceCurve=0; +BeforeCurveMode=Standard +AfterCurveMode=Standard +BeforeCurve=0; +AfterCurve=0; + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=-100 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=3;0;0;0.84892086330935235;0.69064748201438808;1;1; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +lhCurve=0; +hhCurve=0; +LcCurve=0; +ClCurve=0; + +[Vibrance] +Enabled=false +Pastels=50 +Saturated=50 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false +Degree=90 +AutoDegree=true +Surround=Average +AdaptLum=16 +Badpixsl=0 +Model=RawT +Algorithm=JC +J-Light=0 +Q-Bright=0 +C-Chroma=0 +S-Chroma=0 +M-Chroma=0 +J-Contrast=0 +Q-Contrast=0 +H-Hue=0 +RSTProtection=0 +AdaptScene=2000 +AutoAdapscen=true +SurrSource=false +Gamut=true +Datacie=false +Tonecie=false +CurveMode=Lightness +CurveMode2=Lightness +CurveMode3=Chroma +Curve=0; +Curve2=0; +Curve3=0; + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.4 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=10 +HighlightTonalWidth=80 +Shadows=10 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=30 + +[Gradient] +Enabled=false +Degree=0 +Feather=25 +Strength=0.6 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0.6 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/BW/BW 3.pp3 b/rtdata/profiles/BW/BW 3.pp3 new file mode 100644 index 000000000..ae512281a --- /dev/null +++ b/rtdata/profiles/BW/BW 3.pp3 @@ -0,0 +1,162 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=true +Clip=0.02 +Compensation=0 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=0 +HighlightComprThreshold=33 +ShadowCompr=50 +CurveMode=Standard +CurveMode2=Standard +Curve=0; +Curve2=0; + +[HLRecovery] +Enabled=false +Method=Blend + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Black & White] +Enabled=true +Method=Desaturation +Auto=false +ComplementaryColors=true +Setting=NormalContrast +Filter=None +MixerRed=43 +MixerOrange=33 +MixerYellow=33 +MixerGreen=33 +MixerCyan=33 +MixerBlue=30 +MixerMagenta=33 +MixerPurple=33 +GammaRed=0 +GammaGreen=0 +GammaBlue=0 +LuminanceCurve=0; +BeforeCurveMode=Standard +AfterCurveMode=Standard +BeforeCurve=0; +AfterCurve=0; + +[Luminance Curve] +Brightness=0 +Contrast=-25 +Chromaticity=-100 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=2;0.25;0.5;0.75;50;12;-12;-50; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +lhCurve=0; +hhCurve=0; +LcCurve=0; +ClCurve=0; + +[Vibrance] +Enabled=false +Pastels=50 +Saturated=50 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false +Degree=90 +AutoDegree=true +Surround=Average +AdaptLum=16 +Badpixsl=0 +Model=RawT +Algorithm=JC +J-Light=0 +Q-Bright=0 +C-Chroma=0 +S-Chroma=0 +M-Chroma=0 +J-Contrast=0 +Q-Contrast=0 +H-Hue=0 +RSTProtection=0 +AdaptScene=2000 +AutoAdapscen=true +SurrSource=false +Gamut=true +Datacie=false +Tonecie=false +CurveMode=Lightness +CurveMode2=Lightness +CurveMode3=Chroma +Curve=0; +Curve2=0; +Curve3=0; + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.4 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=10 +HighlightTonalWidth=80 +Shadows=10 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=30 + +[Gradient] +Enabled=false +Degree=0 +Feather=25 +Strength=0.6 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0.6 +Feather=50 +Roundness=50 + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/BW/BW 4.pp3 b/rtdata/profiles/BW/BW 4.pp3 new file mode 100644 index 000000000..630b5bafc --- /dev/null +++ b/rtdata/profiles/BW/BW 4.pp3 @@ -0,0 +1,162 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=true +Clip=0.02 +Compensation=0 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=0 +HighlightComprThreshold=33 +ShadowCompr=50 +CurveMode=Standard +CurveMode2=Standard +Curve=0; +Curve2=0; + +[HLRecovery] +Enabled=false +Method=Blend + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Black & White] +Enabled=true +Method=Desaturation +Auto=false +ComplementaryColors=true +Setting=NormalContrast +Filter=None +MixerRed=43 +MixerOrange=33 +MixerYellow=33 +MixerGreen=33 +MixerCyan=33 +MixerBlue=30 +MixerMagenta=33 +MixerPurple=33 +GammaRed=0 +GammaGreen=0 +GammaBlue=0 +LuminanceCurve=0; +BeforeCurveMode=Standard +AfterCurveMode=Standard +BeforeCurve=0; +AfterCurve=0; + +[Luminance Curve] +Brightness=0 +Contrast=-35 +Chromaticity=-100 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=3;0;0;0.18623481781376497;0.028340080971659902;0.50607287449392713;0.50607287449392713;0.77732793522267185;0.97975708502024295;1;1; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +lhCurve=0; +hhCurve=0; +LcCurve=0; +ClCurve=0; + +[Vibrance] +Enabled=false +Pastels=50 +Saturated=50 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false +Degree=90 +AutoDegree=true +Surround=Average +AdaptLum=16 +Badpixsl=0 +Model=RawT +Algorithm=JC +J-Light=0 +Q-Bright=0 +C-Chroma=0 +S-Chroma=0 +M-Chroma=0 +J-Contrast=0 +Q-Contrast=0 +H-Hue=0 +RSTProtection=0 +AdaptScene=2000 +AutoAdapscen=true +SurrSource=false +Gamut=true +Datacie=false +Tonecie=false +CurveMode=Lightness +CurveMode2=Lightness +CurveMode3=Chroma +Curve=0; +Curve2=0; +Curve3=0; + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.4 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=10 +HighlightTonalWidth=80 +Shadows=10 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=30 + +[Gradient] +Enabled=false +Degree=0 +Feather=25 +Strength=0.6 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0.6 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Default ISO High.pp3 b/rtdata/profiles/Default ISO High.pp3 new file mode 100644 index 000000000..691141e2c --- /dev/null +++ b/rtdata/profiles/Default ISO High.pp3 @@ -0,0 +1,161 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=true +Clip=0.02 +Saturation=0 +CurveMode=Standard +CurveMode2=Standard +Curve=0; +Curve2=0; + +[HLRecovery] +Enabled=true +Method=Blend + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Black & White] +Enabled=false + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=0 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +lhCurve=0; +hhCurve=0; +LcCurve=0; +ClCurve=0; + +[Sharpening] +Enabled=false +Method=usm +Radius=0.7 +Amount=250 +Threshold=20;80;2000;1200; +OnlyEdges=false +EdgedetectionRadius=1.9 +EdgeTolerance=1800 +HalocontrolEnabled=false +HalocontrolAmount=85 +DeconvRadius=0.75 +DeconvAmount=75 +DeconvDamping=20 +DeconvIterations=30 + +[Vibrance] +Enabled=false + +[SharpenEdge] +Enabled=false + +[SharpenMicro] +Enabled=false + +[White Balance] +Setting=Camera +Equal=1 + +[Color appearance] +Enabled=false + +[Impulse Denoising] +Enabled=false + +[Defringing] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Enhance=false +Median=true +Luma=0 +Ldetail=50 +Chroma=30 +Method=Lab +SMethod=shal +MedMethod=33 +RGBMethod=soft +MethodMed=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 +Passes=3 +LCurve=1;0.05;0.5;0.35;0.35;0.55;0.04;0.35;0.35; + +[EPD] +Enabled=false + +[Shadows & Highlights] +Enabled=false + +[Gradient] +Enabled=false + +[PCVignette] +Enabled=false + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + +[ColorToning] +Enabled=false + +[RAW] +DarkFrame=/szeva +DarkFrameAuto=false +FlatFieldFile=/szeva +FlatFieldAutoSelect=false +CA=true +HotPixelFilter=true +DeadPixelFilter=false +HotDeadPixelThresh=100 + +[RAW Bayer] +Method=lmmse +CcSteps=0 +PreBlack0=0 +PreBlack1=0 +PreBlack2=0 +PreBlack3=0 +PreTwoGreen=true +LineDenoise=0 +GreenEqThreshold=0 +DCBIterations=2 +DCBEnhance=true +LMMSEIterations=2 + +[RAW X-Trans] +Method=3-pass (best) +CcSteps=0 +PreBlackRed=0 +PreBlackGreen=0 +PreBlackBlue=0 + diff --git a/rtdata/profiles/Default ISO Medium.pp3 b/rtdata/profiles/Default ISO Medium.pp3 new file mode 100644 index 000000000..889911a85 --- /dev/null +++ b/rtdata/profiles/Default ISO Medium.pp3 @@ -0,0 +1,161 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=true +Clip=0.02 +Saturation=0 +CurveMode=Standard +CurveMode2=Standard +Curve=0; +Curve2=0; + +[HLRecovery] +Enabled=true +Method=Blend + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Black & White] +Enabled=false + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=0 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +lhCurve=0; +hhCurve=0; +LcCurve=0; +ClCurve=0; + +[Sharpening] +Enabled=true +Method=usm +Radius=0.7 +Amount=250 +Threshold=20;80;2000;1200; +OnlyEdges=false +EdgedetectionRadius=1.9 +EdgeTolerance=1800 +HalocontrolEnabled=false +HalocontrolAmount=85 +DeconvRadius=0.75 +DeconvAmount=75 +DeconvDamping=20 +DeconvIterations=30 + +[Vibrance] +Enabled=false + +[SharpenEdge] +Enabled=false + +[SharpenMicro] +Enabled=false + +[White Balance] +Setting=Camera +Equal=1 + +[Color appearance] +Enabled=false + +[Impulse Denoising] +Enabled=false + +[Defringing] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Enhance=false +Median=true +Luma=0 +Ldetail=85 +Chroma=15 +Method=Lab +SMethod=shal +MedMethod=33 +RGBMethod=soft +MethodMed=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 +Passes=1 +LCurve=1;0.05;0.15;0.35;0.35;0.55;0.04;0.35;0.35; + +[EPD] +Enabled=false + +[Shadows & Highlights] +Enabled=false + +[Gradient] +Enabled=false + +[PCVignette] +Enabled=false + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + +[ColorToning] +Enabled=false + +[RAW] +DarkFrame=/szeva +DarkFrameAuto=false +FlatFieldFile=/szeva +FlatFieldAutoSelect=false +CA=true +HotPixelFilter=true +DeadPixelFilter=false +HotDeadPixelThresh=100 + +[RAW Bayer] +Method=amaze +CcSteps=0 +PreBlack0=0 +PreBlack1=0 +PreBlack2=0 +PreBlack3=0 +PreTwoGreen=true +LineDenoise=0 +GreenEqThreshold=0 +DCBIterations=2 +DCBEnhance=true +LMMSEIterations=2 + +[RAW X-Trans] +Method=3-pass (best) +CcSteps=0 +PreBlackRed=0 +PreBlackGreen=0 +PreBlackBlue=0 + diff --git a/rtdata/profiles/Default.pp3 b/rtdata/profiles/Default.pp3 new file mode 100644 index 000000000..c4ea48b60 --- /dev/null +++ b/rtdata/profiles/Default.pp3 @@ -0,0 +1,149 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=true +Clip=0.02 +Saturation=0 +CurveMode=Standard +CurveMode2=Standard +Curve=0; +Curve2=0; + +[HLRecovery] +Enabled=true +Method=Blend + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Black & White] +Enabled=false + + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=0 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +lhCurve=0; +hhCurve=0; +LcCurve=0; +ClCurve=0; + +[Sharpening] +Enabled=true +Method=usm +Radius=0.5 +Amount=250 +Threshold=20;80;2000;1200; +OnlyEdges=false +EdgedetectionRadius=1.9 +EdgeTolerance=1800 +HalocontrolEnabled=false +HalocontrolAmount=85 +DeconvRadius=0.75 +DeconvAmount=75 +DeconvDamping=20 +DeconvIterations=30 + +[Vibrance] +Enabled=false + +[SharpenEdge] +Enabled=false + +[SharpenMicro] +Enabled=false + +[White Balance] +Setting=Camera +Equal=1 + +[Color appearance] +Enabled=false + +[Impulse Denoising] +Enabled=false + +[Defringing] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=false +Method=Lab + +[EPD] +Enabled=false + +[Shadows & Highlights] +Enabled=false + +[Gradient] +Enabled=false + +[PCVignette] +Enabled=false + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + +[ColorToning] +Enabled=false + +[RAW] +DarkFrame=/szeva +DarkFrameAuto=false +FlatFieldFile=/szeva +FlatFieldAutoSelect=false +CA=true +HotPixelFilter=true +DeadPixelFilter=false +HotDeadPixelThresh=100 + +[RAW Bayer] +Method=amaze +CcSteps=0 +PreBlack0=0 +PreBlack1=0 +PreBlack2=0 +PreBlack3=0 +PreTwoGreen=true +LineDenoise=0 +GreenEqThreshold=0 +DCBIterations=2 +DCBEnhance=true +LMMSEIterations=2 + +[RAW X-Trans] +Method=3-pass (best) +CcSteps=0 +PreBlackRed=0 +PreBlackGreen=0 +PreBlackBlue=0 + diff --git a/rtdata/profiles/Faded/Faded Amber 1 TM Bright.pp3 b/rtdata/profiles/Faded/Faded Amber 1 TM Bright.pp3 new file mode 100644 index 000000000..dc602e9f8 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Amber 1 TM Bright.pp3 @@ -0,0 +1,97 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=70 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=SatAndValueBlending +CurveMode2=FilmLike +Curve=3;0;0;0.23320158102766808;0.58893280632411094;0.69169960474308201;0.96047430830039549;1;1; +Curve2=3;0;0;0.12213438735177862;0.012648221343873525;0.46245059288537577;0.41250131169330889;1;1; + +[Channel Mixer] +Red=80;0;20; +Green=0;60;40; +Blue=-20;20;80; + +[Black & White] +Enabled=false + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=-29 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; +ClCurve=0; +lhCurve=0; +hhCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=0 +Chroma=20 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=true +Strength=0.25 +EdgeStopping=1.40 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +LumaMode=false +rCurve=3;0;0;0.047430830039525626;0.21343873517786571;1;1; +gCurve=3;0;0;1;1; +bCurve=3;0;0;0.22924901185770752;0.031620553359683806;1;1; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Faded/Faded Amber 1 TM.pp3 b/rtdata/profiles/Faded/Faded Amber 1 TM.pp3 new file mode 100644 index 000000000..9841feaf6 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Amber 1 TM.pp3 @@ -0,0 +1,97 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=70 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=SatAndValueBlending +CurveMode2=FilmLike +Curve=3;0;0;0.27667984189723321;0.47035573122529734;0.69169960474308201;0.96047430830039549;1;1; +Curve2=3;0;0;0.12213438735177862;0.012648221343873525;0.46245059288537577;0.41250131169330889;1;1; + +[Channel Mixer] +Red=80;0;20; +Green=0;60;40; +Blue=-20;20;80; + +[Black & White] +Enabled=false + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=-29 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; +ClCurve=0; +lhCurve=0; +hhCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=0 +Chroma=20 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=true +Strength=0.25 +EdgeStopping=1.40 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=3;0;0;0.047430830039525626;0.21343873517786571;1;1; +gCurve=3;0;0;1;1; +bCurve=3;0;0;0.22924901185770752;0.031620553359683806;1;1; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Faded/Faded Amber 1.pp3 b/rtdata/profiles/Faded/Faded Amber 1.pp3 new file mode 100644 index 000000000..f446ddfde --- /dev/null +++ b/rtdata/profiles/Faded/Faded Amber 1.pp3 @@ -0,0 +1,97 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=70 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=SatAndValueBlending +CurveMode2=FilmLike +Curve=3;0;0;0.23320158102766808;0.58893280632411094;0.69169960474308201;0.96047430830039549;1;1; +Curve2=3;0;0;0.12213438735177862;0.012648221343873525;0.46245059288537577;0.41250131169330889;1;1; + +[Channel Mixer] +Red=80;0;20; +Green=0;60;40; +Blue=-20;20;80; + +[Black & White] +Enabled=false + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=-29 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; +ClCurve=0; +lhCurve=0; +hhCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=0 +Chroma=20 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.40 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +LumaMode=false +rCurve=3;0;0;0.047430830039525626;0.21343873517786571;1;1; +gCurve=3;0;0;1;1; +bCurve=3;0;0;0.22924901185770752;0.031620553359683806;1;1; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Faded/Faded Blue 1 TM Bright.pp3 b/rtdata/profiles/Faded/Faded Blue 1 TM Bright.pp3 new file mode 100644 index 000000000..ca5cd1608 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Blue 1 TM Bright.pp3 @@ -0,0 +1,97 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=70 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=SatAndValueBlending +CurveMode2=FilmLike +Curve=3;0;0;0.23320158102766808;0.58893280632411094;0.69169960474308201;0.96047430830039549;1;1; +Curve2=3;0;0;0.12213438735177862;0.012648221343873525;0.46245059288537577;0.41250131169330889;1;1; + +[Channel Mixer] +Red=80;0;20; +Green=0;60;40; +Blue=-20;20;80; + +[Black & White] +Enabled=false + +[Luminance Curve] +Brightness=0 +Contrast=-25 +Chromaticity=-29 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; +ClCurve=0; +lhCurve=0; +hhCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=0 +Chroma=20 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=true +Strength=0.25 +EdgeStopping=1.40 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +LumaMode=false +rCurve=3;0;0;0.24505928853754988;0.055335968379447285;1;1; +gCurve=3;0;0;0.1146245059288528;0.023715415019764076;1;1; +bCurve=3;0;0;0.086956521739130363;0.21739130434782611;0.9446640316205519;0.69960474308300313;1;1; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Faded/Faded Blue 1 TM.pp3 b/rtdata/profiles/Faded/Faded Blue 1 TM.pp3 new file mode 100644 index 000000000..121969069 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Blue 1 TM.pp3 @@ -0,0 +1,97 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=70 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=SatAndValueBlending +CurveMode2=FilmLike +Curve=3;0;0;0.27667984189723321;0.47035573122529734;0.69169960474308201;0.96047430830039549;1;1; +Curve2=3;0;0;0.12213438735177862;0.012648221343873525;0.46245059288537577;0.41250131169330889;1;1; + +[Channel Mixer] +Red=80;0;20; +Green=0;60;40; +Blue=-20;20;80; + +[Black & White] +Enabled=false + +[Luminance Curve] +Brightness=0 +Contrast=-25 +Chromaticity=-29 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; +ClCurve=0; +lhCurve=0; +hhCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=0 +Chroma=20 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=true +Strength=0.25 +EdgeStopping=1.40 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[RGB Curves] +LumaMode=false +rCurve=3;0;0;0.24505928853754988;0.055335968379447285;1;1; +gCurve=3;0;0;0.1146245059288528;0.023715415019764076;1;1; +bCurve=3;0;0;0.086956521739130363;0.21739130434782611;0.9446640316205519;0.69960474308300313;1;1; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Faded/Faded Blue 1.pp3 b/rtdata/profiles/Faded/Faded Blue 1.pp3 new file mode 100644 index 000000000..55cdb7493 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Blue 1.pp3 @@ -0,0 +1,97 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=70 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=SatAndValueBlending +CurveMode2=FilmLike +Curve=3;0;0;0.23320158102766808;0.58893280632411094;0.69169960474308201;0.96047430830039549;1;1; +Curve2=3;0;0;0.12213438735177862;0.012648221343873525;0.46245059288537577;0.41250131169330889;1;1; + +[Channel Mixer] +Red=80;0;20; +Green=0;60;40; +Blue=-20;20;80; + +[Black & White] +Enabled=false + +[Luminance Curve] +Brightness=0 +Contrast=-25 +Chromaticity=-29 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; +ClCurve=0; +lhCurve=0; +hhCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=0 +Chroma=20 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.40 +Scale=0.25 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=3;0;0;0.24505928853754988;0.055335968379447285;1;1; +gCurve=3;0;0;0.1146245059288528;0.023715415019764076;1;1; +bCurve=3;0;0;0.086956521739130363;0.21739130434782611;0.9446640316205519;0.69960474308300313;1;1; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Faded/Faded Blue Pink TM.pp3 b/rtdata/profiles/Faded/Faded Blue Pink TM.pp3 new file mode 100644 index 000000000..571d11611 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Blue Pink TM.pp3 @@ -0,0 +1,97 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=70 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=SatAndValueBlending +CurveMode2=FilmLike +Curve=3;0;0;0.27667984189723321;0.47035573122529734;0.69169960474308201;0.96047430830039549;1;1; +Curve2=3;0;0;0.12213438735177862;0.012648221343873525;0.46245059288537577;0.41250131169330889;1;1; + +[Channel Mixer] +Red=80;0;20; +Green=0;60;40; +Blue=-20;20;80; + +[Black & White] +Enabled=false + +[Luminance Curve] +Brightness=0 +Contrast=-25 +Chromaticity=-29 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; +ClCurve=0; +lhCurve=0; +hhCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=0 +Chroma=20 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=true +Strength=0.25 +EdgeStopping=1.40 +Scale=0.25 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=3;0;0;0.24505928853754988;0.055335968379447285;0.81034482758620685;0.94827586206896552;1;1; +gCurve=3;0;0;0.1146245059288528;0.023715415019764076;1;1; +bCurve=3;0;0;0.086956521739130363;0.21739130434782611;0.9446640316205519;0.69960474308300313;1;1; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Faded/Faded Blue Pink.pp3 b/rtdata/profiles/Faded/Faded Blue Pink.pp3 new file mode 100644 index 000000000..c60fe23d2 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Blue Pink.pp3 @@ -0,0 +1,97 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=70 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=SatAndValueBlending +CurveMode2=FilmLike +Curve=3;0;0;0.23320158102766808;0.58893280632411094;0.69169960474308201;0.96047430830039549;1;1; +Curve2=3;0;0;0.12213438735177862;0.012648221343873525;0.46245059288537577;0.41250131169330889;1;1; + +[Channel Mixer] +Red=80;0;20; +Green=0;60;40; +Blue=-20;20;80; + +[Black & White] +Enabled=false + +[Luminance Curve] +Brightness=0 +Contrast=-25 +Chromaticity=-29 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; +ClCurve=0; +lhCurve=0; +hhCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=0 +Chroma=20 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.40 +Scale=0.25 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=3;0;0;0.24505928853754988;0.055335968379447285;0.81034482758620685;0.94827586206896552;1;1; +gCurve=3;0;0;0.1146245059288528;0.023715415019764076;1;1; +bCurve=3;0;0;0.086956521739130363;0.21739130434782611;0.9446640316205519;0.69960474308300313;1;1; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Faded/Faded Chocolate 1 TM Bright.pp3 b/rtdata/profiles/Faded/Faded Chocolate 1 TM Bright.pp3 new file mode 100644 index 000000000..3ae99186e --- /dev/null +++ b/rtdata/profiles/Faded/Faded Chocolate 1 TM Bright.pp3 @@ -0,0 +1,101 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=70 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=SatAndValueBlending +CurveMode2=FilmLike +Curve=3;0;0;0.23320158102766808;0.58893280632411094;0.69169960474308201;0.96047430830039549;1;1; +Curve2=3;0;0;0.12213438735177862;0.012648221343873525;0.46245059288537577;0.41250131169330889;1;1; + +[Channel Mixer] +Red=80;0;20; +Green=0;60;40; +Blue=-20;20;80; + +[Black & White] +Enabled=false + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=-29 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; +ClCurve=0; +lhCurve=0; +hhCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=0 +Chroma=20 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=true +Strength=0.25 +EdgeStopping=1.40 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false + +[HLRecovery] +Enabled=false +Method=Blend + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=3;0;0;0.16206896551724165;0.079310344827586171;1;1; +gCurve=3;0;0;0.1655172413793104;0.034482758620689787;1;1; +bCurve=3;0;0;0.55827995093362426;0.31529235382308862;0.91699604743083007;0.76284584980237169;1;1; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Faded/Faded Chocolate 2 TM Bright.pp3 b/rtdata/profiles/Faded/Faded Chocolate 2 TM Bright.pp3 new file mode 100644 index 000000000..3eb53a151 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Chocolate 2 TM Bright.pp3 @@ -0,0 +1,97 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=70 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=SatAndValueBlending +CurveMode2=FilmLike +Curve=3;0;0;0.15733951206215074;0.55445004770342121;0.69169960474308201;0.96047430830039549;1;1; +Curve2=3;0;0;0.12213438735177862;0.012648221343873525;0.46245059288537577;0.41250131169330889;1;1; + +[Channel Mixer] +Red=60;0;20; +Green=0;60;20; +Blue=-20;20;40; + +[Black & White] +Enabled=false + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=-29 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; +ClCurve=0; +lhCurve=0; +hhCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=0 +Chroma=20 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=true +Strength=0.25 +EdgeStopping=1.40 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=3;0;0;0.16206896551724165;0.079310344827586171;1;1; +gCurve=3;0;0;0.1655172413793104;0.034482758620689787;1;1; +bCurve=3;0;0;0.55827995093362426;0.31529235382308862;0.91699604743083007;0.76284584980237169;1;1; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Faded/Faded Golden 1.pp3 b/rtdata/profiles/Faded/Faded Golden 1.pp3 new file mode 100644 index 000000000..c8f5d26a4 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Golden 1.pp3 @@ -0,0 +1,101 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=70 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=SatAndValueBlending +CurveMode2=SatAndValueBlending +Curve=3;0;0;0.23320158102766808;0.58893280632411094;0.69169960474308201;0.96047430830039549;1;1; +Curve2=3;0;0;0.12213438735177862;0.012648221343873525;0.53359683794466362;0.72870684529014551;1;1; + +[Channel Mixer] +Red=60;0;20; +Green=0;60;20; +Blue=-20;20;40; + +[Black & White] +Enabled=false + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=56 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; +ClCurve=0; +lhCurve=0; +hhCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=0 +Chroma=20 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.40 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false + +[HLRecovery] +Enabled=false +Method=Blend + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=3;0;0;0.086956521739130432;0.090909090909090856;1;1; +gCurve=3;0;0;0.20266764462192638;0.12923950395936107;1;1; +bCurve=1;0;0;0.25296442687747034;0.22529644268774709;0.8656126482213431;0.80632411067193566;1;1; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Faded/Faded Golden 2.pp3 b/rtdata/profiles/Faded/Faded Golden 2.pp3 new file mode 100644 index 000000000..1e7bb927d --- /dev/null +++ b/rtdata/profiles/Faded/Faded Golden 2.pp3 @@ -0,0 +1,101 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=70 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=SatAndValueBlending +CurveMode2=SatAndValueBlending +Curve=3;0;0;0.23320158102766808;0.58893280632411094;0.69169960474308201;0.96047430830039549;1;1; +Curve2=3;0;0;0.12213438735177862;0.012648221343873525;0.53359683794466362;0.72870684529014551;1;1; + +[Channel Mixer] +Red=60;0;20; +Green=0;60;20; +Blue=-20;20;40; + +[Black & White] +Enabled=false + +[Luminance Curve] +Brightness=0 +Contrast=-25 +Chromaticity=56 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; +ClCurve=0; +lhCurve=0; +hhCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=0 +Chroma=20 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.40 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false + +[HLRecovery] +Enabled=false +Method=Blend + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=3;0;0;0.086956521739130432;0.090909090909090856;0.94466403162055268;0.89328063241106692;1;1; +gCurve=3;0;0;0.20266764462192638;0.12923950395936107;0.90118577075098805;0.88537549407114613;1;1; +bCurve=1;0;0;0.25296442687747034;0.22529644268774709;0.8656126482213431;0.80632411067193566;1;1; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Faded/Faded Green 1 TM Bright.pp3 b/rtdata/profiles/Faded/Faded Green 1 TM Bright.pp3 new file mode 100644 index 000000000..036c58fdc --- /dev/null +++ b/rtdata/profiles/Faded/Faded Green 1 TM Bright.pp3 @@ -0,0 +1,97 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=70 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=SatAndValueBlending +CurveMode2=FilmLike +Curve=3;0;0;0.23320158102766808;0.58893280632411094;0.69169960474308201;0.96047430830039549;1;1; +Curve2=3;0;0;0.12213438735177862;0.012648221343873525;0.46245059288537577;0.41250131169330889;1;1; + +[Channel Mixer] +Red=60;0;20; +Green=0;60;20; +Blue=-20;20;40; + +[Black & White] +Enabled=false + +[Luminance Curve] +Brightness=0 +Contrast=-25 +Chromaticity=-29 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; +ClCurve=0; +lhCurve=0; +hhCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=0 +Chroma=20 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=true +Strength=0.25 +EdgeStopping=1.40 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Faded/Faded Green 1 TM.pp3 b/rtdata/profiles/Faded/Faded Green 1 TM.pp3 new file mode 100644 index 000000000..d3f7c6adc --- /dev/null +++ b/rtdata/profiles/Faded/Faded Green 1 TM.pp3 @@ -0,0 +1,97 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=70 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=SatAndValueBlending +CurveMode2=FilmLike +Curve=3;0;0;0.27667984189723321;0.47035573122529734;0.69169960474308201;0.96047430830039549;1;1; +Curve2=3;0;0;0.12213438735177862;0.012648221343873525;0.46245059288537577;0.41250131169330889;1;1; + +[Channel Mixer] +Red=60;0;20; +Green=0;60;20; +Blue=-20;20;40; + +[Black & White] +Enabled=false + +[Luminance Curve] +Brightness=0 +Contrast=-25 +Chromaticity=-29 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; +ClCurve=0; +lhCurve=0; +hhCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=0 +Chroma=20 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=true +Strength=0.25 +EdgeStopping=1.40 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Faded/Faded Green 1.pp3 b/rtdata/profiles/Faded/Faded Green 1.pp3 new file mode 100644 index 000000000..7ee20b51a --- /dev/null +++ b/rtdata/profiles/Faded/Faded Green 1.pp3 @@ -0,0 +1,101 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=70 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=SatAndValueBlending +CurveMode2=FilmLike +Curve=3;0;0;0.23320158102766808;0.58893280632411094;0.69169960474308201;0.96047430830039549;1;1; +Curve2=3;0;0;0.12213438735177862;0.012648221343873525;0.46245059288537577;0.41250131169330889;1;1; + +[Channel Mixer] +Red=60;0;20; +Green=0;60;20; +Blue=-20;20;40; + +[Black & White] +Enabled=false + +[Luminance Curve] +Brightness=0 +Contrast=-25 +Chromaticity=-29 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; +ClCurve=0; +lhCurve=0; +hhCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=0 +Chroma=20 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.40 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false + +[HLRecovery] +Enabled=false +Method=Blend + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Faded/Faded Green 2.pp3 b/rtdata/profiles/Faded/Faded Green 2.pp3 new file mode 100644 index 000000000..2c908cf2e --- /dev/null +++ b/rtdata/profiles/Faded/Faded Green 2.pp3 @@ -0,0 +1,101 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=70 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=SatAndValueBlending +CurveMode2=FilmLike +Curve=3;0;0;0.23320158102766808;0.58893280632411094;0.69169960474308201;0.96047430830039549;1;1; +Curve2=3;0;0;0.12213438735177862;0.012648221343873525;0.46245059288537577;0.41250131169330889;1;1; + +[Channel Mixer] +Red=60;0;20; +Green=0;60;20; +Blue=-20;20;40; + +[Black & White] +Enabled=false + +[Luminance Curve] +Brightness=0 +Contrast=-25 +Chromaticity=-29 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; +ClCurve=0; +lhCurve=0; +hhCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=0 +Chroma=20 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.40 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false + +[HLRecovery] +Enabled=false +Method=Blend + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=3;0;0;0.083003952569169981;0.075098814229249022;0.74703557312252944;0.81422924901185822;1;1; +gCurve=3;0;0;0.32806324110671931;0.43083003952569182;1;1; +bCurve=3;0;0;0.040612308653546869;0.12528693478940064;0.85375494071146218;0.9130434782608694;1;1; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Faded/Faded Green 3.pp3 b/rtdata/profiles/Faded/Faded Green 3.pp3 new file mode 100644 index 000000000..570e4f291 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Green 3.pp3 @@ -0,0 +1,97 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=70 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=SatAndValueBlending +CurveMode2=FilmLike +Curve=3;0;0;0.23320158102766808;0.58893280632411094;0.69169960474308201;0.96047430830039549;1;1; +Curve2=3;0;0;0.11903093907591648;0.023682704102494199;0.46245059288537577;0.41250131169330889;1;1; + +[Channel Mixer] +Red=80;0;20; +Green=0;60;40; +Blue=-20;40;0; + +[Black & White] +Enabled=false + +[Luminance Curve] +Brightness=0 +Contrast=-25 +Chromaticity=-29 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; +ClCurve=0; +lhCurve=0; +hhCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=0 +Chroma=20 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.40 +Scale=0.25 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=3;0;0;0.24505928853754988;0.055335968379447285;0.81034482758620685;0.94827586206896552;1;1; +gCurve=3;0;0;0.1146245059288528;0.023715415019764076;1;1; +bCurve=3;0;0;0.086956521739130363;0.21739130434782611;0.9446640316205519;0.69960474308300313;1;1; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Faded/Faded Neutral TM.pp3 b/rtdata/profiles/Faded/Faded Neutral TM.pp3 new file mode 100644 index 000000000..2f2e856ed --- /dev/null +++ b/rtdata/profiles/Faded/Faded Neutral TM.pp3 @@ -0,0 +1,97 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=70 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=SatAndValueBlending +CurveMode2=FilmLike +Curve=3;0;0;0.27667984189723321;0.47035573122529734;0.69169960474308201;0.96047430830039549;1;1; +Curve2=3;0;0;0.12213438735177862;0.012648221343873525;0.46245059288537577;0.41250131169330889;1;1; + +[Channel Mixer] +Red=80;0;20; +Green=0;60;40; +Blue=-20;20;80; + +[Black & White] +Enabled=false + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=-29 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; +ClCurve=0; +lhCurve=0; +hhCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=0 +Chroma=20 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=true +Strength=0.25 +EdgeStopping=1.40 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=3;0;0;1;1; +gCurve=3;0;0;1;1; +bCurve=3;0;0;1;1; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Faded/Faded Neutral.pp3 b/rtdata/profiles/Faded/Faded Neutral.pp3 new file mode 100644 index 000000000..c01e7c09f --- /dev/null +++ b/rtdata/profiles/Faded/Faded Neutral.pp3 @@ -0,0 +1,97 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=70 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=SatAndValueBlending +CurveMode2=FilmLike +Curve=3;0;0;0.23320158102766808;0.58893280632411094;0.69169960474308201;0.96047430830039549;1;1; +Curve2=3;0;0;0.12213438735177862;0.012648221343873525;0.46245059288537577;0.41250131169330889;1;1; + +[Channel Mixer] +Red=80;0;20; +Green=0;60;40; +Blue=-20;20;80; + +[Black & White] +Enabled=false + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=-29 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; +ClCurve=0; +lhCurve=0; +hhCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=0 +Chroma=20 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.40 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=3;0;0;1;1; +gCurve=3;0;0;1;1; +bCurve=3;0;0;1;1; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Faded/Faded Purple 1 TM Bright.pp3 b/rtdata/profiles/Faded/Faded Purple 1 TM Bright.pp3 new file mode 100644 index 000000000..75250f299 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Purple 1 TM Bright.pp3 @@ -0,0 +1,97 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=70 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=SatAndValueBlending +CurveMode2=FilmLike +Curve=3;0;0;0.23320158102766808;0.58893280632411094;0.69169960474308201;0.96047430830039549;1;1; +Curve2=3;0;0;0.12213438735177862;0.012648221343873525;0.46245059288537577;0.41250131169330889;1;1; + +[Channel Mixer] +Red=60;0;20; +Green=0;60;20; +Blue=-20;20;40; + +[Black & White] +Enabled=false + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=-29 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; +ClCurve=0; +lhCurve=0; +hhCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=0 +Chroma=20 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=true +Strength=0.25 +EdgeStopping=1.40 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=3;0;0;0.15517241379310354;0.075862068965517254;1;1; +gCurve=3;0;0;0.13793103448275862;0.055172413793103607;1;1; +bCurve=3;0;0;0.051383399209486022;0.17391304347826081;0.91699604743083007;0.76284584980237169;1;1; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Faded/Faded Purple 1 TM.pp3 b/rtdata/profiles/Faded/Faded Purple 1 TM.pp3 new file mode 100644 index 000000000..24496dc67 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Purple 1 TM.pp3 @@ -0,0 +1,101 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=70 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=SatAndValueBlending +CurveMode2=FilmLike +Curve=3;0;0;0.27667984189723321;0.47035573122529734;0.69169960474308201;0.96047430830039549;1;1; +Curve2=3;0;0;0.12213438735177862;0.012648221343873525;0.46245059288537577;0.41250131169330889;1;1; + +[Channel Mixer] +Red=60;0;20; +Green=0;60;20; +Blue=-20;20;40; + +[Black & White] +Enabled=false + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=-29 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; +ClCurve=0; +lhCurve=0; +hhCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=0 +Chroma=20 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=true +Strength=0.25 +EdgeStopping=1.40 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false + +[HLRecovery] +Enabled=false +Method=Blend + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=3;0;0;0.15517241379310354;0.075862068965517254;1;1; +gCurve=3;0;0;0.13793103448275862;0.055172413793103607;1;1; +bCurve=3;0;0;0.051383399209486022;0.17391304347826081;0.91699604743083007;0.76284584980237169;1;1; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Faded/Faded Purple 1.pp3 b/rtdata/profiles/Faded/Faded Purple 1.pp3 new file mode 100644 index 000000000..a77d52afd --- /dev/null +++ b/rtdata/profiles/Faded/Faded Purple 1.pp3 @@ -0,0 +1,101 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=70 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=SatAndValueBlending +CurveMode2=FilmLike +Curve=3;0;0;0.23320158102766808;0.58893280632411094;0.69169960474308201;0.96047430830039549;1;1; +Curve2=3;0;0;0.12213438735177862;0.012648221343873525;0.46245059288537577;0.41250131169330889;1;1; + +[Channel Mixer] +Red=60;0;20; +Green=0;60;20; +Blue=-20;20;40; + +[Black & White] +Enabled=false + +[Luminance Curve] +Brightness=0 +Contrast=-25 +Chromaticity=-29 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; +ClCurve=0; +lhCurve=0; +hhCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=0 +Chroma=20 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.40 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false + +[HLRecovery] +Enabled=false +Method=Blend + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=3;0;0;0.15517241379310354;0.075862068965517254;1;1; +gCurve=3;0;0;0.13793103448275862;0.055172413793103607;1;1; +bCurve=3;0;0;0.051383399209486022;0.17391304347826081;0.91699604743083007;0.76284584980237169;1;1; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Faded/Faded Purple 2 TM.pp3 b/rtdata/profiles/Faded/Faded Purple 2 TM.pp3 new file mode 100644 index 000000000..93017a0b1 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Purple 2 TM.pp3 @@ -0,0 +1,101 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=70 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=SatAndValueBlending +CurveMode2=FilmLike +Curve=3;0;0;0.27667984189723321;0.47035573122529734;0.69169960474308201;0.96047430830039549;1;1; +Curve2=3;0;0;0.12213438735177862;0.012648221343873525;0.46245059288537577;0.41250131169330889;1;1; + +[Channel Mixer] +Red=60;0;20; +Green=0;60;20; +Blue=-20;20;40; + +[Black & White] +Enabled=false + +[Luminance Curve] +Brightness=0 +Contrast=-25 +Chromaticity=-29 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; +ClCurve=0; +lhCurve=0; +hhCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=0 +Chroma=20 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=true +Strength=0.25 +EdgeStopping=1.40 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false + +[HLRecovery] +Enabled=false +Method=Blend + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=3;0;0;0.15517241379310354;0.075862068965517254;0.7;0.9;1;1; +gCurve=3;0;0;0.13793103448275862;0.055172413793103607;0.69655172413793076;0.90689655172413808;1;1; +bCurve=3;0;0;0.051383399209486022;0.17391304347826081;0.91699604743083007;0.76284584980237169;1;1; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Faded/Faded Purple 2.pp3 b/rtdata/profiles/Faded/Faded Purple 2.pp3 new file mode 100644 index 000000000..650d38da6 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Purple 2.pp3 @@ -0,0 +1,101 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=70 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=SatAndValueBlending +CurveMode2=FilmLike +Curve=3;0;0;0.23320158102766808;0.58893280632411094;0.69169960474308201;0.96047430830039549;1;1; +Curve2=3;0;0;0.12213438735177862;0.012648221343873525;0.46245059288537577;0.41250131169330889;1;1; + +[Channel Mixer] +Red=60;0;20; +Green=0;60;20; +Blue=-20;20;40; + +[Black & White] +Enabled=false + +[Luminance Curve] +Brightness=0 +Contrast=-25 +Chromaticity=-29 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; +ClCurve=0; +lhCurve=0; +hhCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=0 +Chroma=20 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.40 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false + +[HLRecovery] +Enabled=false +Method=Blend + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=3;0;0;0.15517241379310354;0.075862068965517254;0.69999999999999973;0.90000000000000013;1;1; +gCurve=3;0;0;0.13793103448275862;0.055172413793103607;0.69655172413793076;0.90689655172413808;1;1; +bCurve=3;0;0;0.051383399209486022;0.17391304347826081;0.91699604743083007;0.76284584980237169;1;1; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Faded/Faded Teal Orange TM Bright.pp3 b/rtdata/profiles/Faded/Faded Teal Orange TM Bright.pp3 new file mode 100644 index 000000000..c9d2eaf7a --- /dev/null +++ b/rtdata/profiles/Faded/Faded Teal Orange TM Bright.pp3 @@ -0,0 +1,97 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=170 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=SatAndValueBlending +CurveMode2=FilmLike +Curve=3;0;0;0.29527054654490958;0.54755349597928327;0.69169960474308201;0.96047430830039549;1;1; +Curve2=3;0;0;0.068858525282812999;0.0083378765162873056;0.46245059288537577;0.41250131169330889;1;1; + +[Channel Mixer] +Red=80;0;20; +Green=0;60;40; +Blue=-20;20;80; + +[Black & White] +Enabled=false + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=0 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=3;0;0;0.094310344827586101;0.09189655172413784;0.9956896551724137;0.92051724137931046;1;1; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; +ClCurve=0; +lhCurve=0; +hhCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=0 +Chroma=20 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=true +Strength=0.25 +EdgeStopping=1.40 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false + +[HSV Equalizer] +HCurve=0; +SCurve=1;0.073578595317725717;0.69732441471571893;0.35;0.35;0.33333333333333331;0.5;0.35;0.35;0.5;0.5;0.35;0.35;0.66666666666666663;0.5;0.35;0.35;0.83333333333333326;0.5;0.35;0.35; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=3;0;0;0.18620689655172415;0.044827586206896544;0.85517241379310338;0.91379310344827591;1;1; +gCurve=3;0;0;0.13224137931034488;0.048793103448275733;0.95172413793103461;0.8655172413793103;1;1; +bCurve=3;0;0;0.12758620689655173;0.075862068965517226;0.90344827586206922;0.78620689655172393;1;1; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Faded/Faded Teal Orange TM.pp3 b/rtdata/profiles/Faded/Faded Teal Orange TM.pp3 new file mode 100644 index 000000000..2e4b33b10 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Teal Orange TM.pp3 @@ -0,0 +1,97 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=170 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=SatAndValueBlending +CurveMode2=FilmLike +Curve=3;0;0;0.29527054654490958;0.40962246149652437;0.69169960474308201;0.96047430830039549;1;1; +Curve2=3;0;0;0.068858525282812999;0.0083378765162873056;0.46245059288537577;0.41250131169330889;1;1; + +[Channel Mixer] +Red=80;0;20; +Green=0;60;40; +Blue=-20;20;80; + +[Black & White] +Enabled=false + +[Luminance Curve] +Brightness=0 +Contrast=-25 +Chromaticity=0 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=3;0;0;0.094310344827586101;0.09189655172413784;0.89568965517241339;0.9032758620689656;1;1; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; +ClCurve=0; +lhCurve=0; +hhCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=0 +Chroma=20 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=true +Strength=0.25 +EdgeStopping=1.40 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false + +[HSV Equalizer] +HCurve=0; +SCurve=1;0.073578595317725717;0.69732441471571893;0.35;0.35;0.33333333333333331;0.5;0.35;0.35;0.5;0.5;0.35;0.35;0.66666666666666663;0.5;0.35;0.35;0.83333333333333326;0.5;0.35;0.35; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=3;0;0;0.18620689655172415;0.044827586206896544;0.85517241379310338;0.91379310344827591;1;1; +gCurve=3;0;0;0.13224137931034488;0.048793103448275733;0.95172413793103461;0.8655172413793103;1;1; +bCurve=3;0;0;0.12758620689655173;0.075862068965517226;0.90344827586206922;0.78620689655172393;1;1; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Faded/Faded Teal Orange.pp3 b/rtdata/profiles/Faded/Faded Teal Orange.pp3 new file mode 100644 index 000000000..a2f4cf765 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Teal Orange.pp3 @@ -0,0 +1,97 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=70 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=SatAndValueBlending +CurveMode2=FilmLike +Curve=3;0;0;0.33320158102766828;0.53720866839307635;0.69169960474308201;0.96047430830039549;1;1; +Curve2=3;0;0;0.068858525282812999;0.0083378765162873056;0.46245059288537577;0.41250131169330889;1;1; + +[Channel Mixer] +Red=80;0;20; +Green=0;60;40; +Blue=-20;20;80; + +[Black & White] +Enabled=false + +[Luminance Curve] +Brightness=0 +Contrast=-25 +Chromaticity=0 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=3;0;0;0.094310344827586101;0.09189655172413784;0.89568965517241339;0.9032758620689656;1;1; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; +ClCurve=0; +lhCurve=0; +hhCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=0 +Chroma=20 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.40 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false + +[HSV Equalizer] +HCurve=0; +SCurve=1;0.073578595317725717;0.69732441471571893;0.35;0.35;0.33333333333333331;0.5;0.35;0.35;0.5;0.5;0.35;0.35;0.66666666666666663;0.5;0.35;0.35;0.83333333333333326;0.5;0.35;0.35; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=3;0;0;0.18620689655172415;0.044827586206896544;0.85517241379310338;0.91379310344827591;1;1; +gCurve=3;0;0;0.13224137931034488;0.048793103448275733;0.95172413793103461;0.8655172413793103;1;1; +bCurve=3;0;0;0.12758620689655173;0.075862068965517226;0.90344827586206922;0.78620689655172393;1;1; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Faded/Faded Warm 1 TM Bright.pp3 b/rtdata/profiles/Faded/Faded Warm 1 TM Bright.pp3 new file mode 100644 index 000000000..b742b71be --- /dev/null +++ b/rtdata/profiles/Faded/Faded Warm 1 TM Bright.pp3 @@ -0,0 +1,101 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=70 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=SatAndValueBlending +CurveMode2=FilmLike +Curve=3;0;0;0.23320158102766808;0.58893280632411094;0.69169960474308201;0.96047430830039549;1;1; +Curve2=3;0;0;0.12213438735177862;0.012648221343873525;0.46245059288537577;0.41250131169330889;1;1; + +[Channel Mixer] +Red=60;0;20; +Green=0;60;40; +Blue=-20;20;40; + +[Black & White] +Enabled=false + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=-29 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; +ClCurve=0; +lhCurve=0; +hhCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=0 +Chroma=20 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=true +Strength=0.25 +EdgeStopping=1.40 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false + +[HLRecovery] +Enabled=false +Method=Blend + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=3;0;0;0.051383399209486022;0.17391304347826081;1;1; +gCurve=3;0;0;1;1; +bCurve=3;0;0;0.051383399209486022;0.17391304347826081;0.91699604743083007;0.76284584980237169;1;1; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Faded/Faded Warm 1 TM.pp3 b/rtdata/profiles/Faded/Faded Warm 1 TM.pp3 new file mode 100644 index 000000000..3bea604e0 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Warm 1 TM.pp3 @@ -0,0 +1,101 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=70 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=SatAndValueBlending +CurveMode2=FilmLike +Curve=3;0;0;0.27667984189723321;0.47035573122529734;0.69169960474308201;0.96047430830039549;1;1; +Curve2=3;0;0;0.12213438735177862;0.012648221343873525;0.46245059288537577;0.41250131169330889;1;1; + +[Channel Mixer] +Red=60;0;20; +Green=0;60;40; +Blue=-20;20;40; + +[Black & White] +Enabled=false + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=-29 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; +ClCurve=0; +lhCurve=0; +hhCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=0 +Chroma=20 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=true +Strength=0.25 +EdgeStopping=1.40 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false + +[HLRecovery] +Enabled=false +Method=Blend + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=3;0;0;0.051383399209486022;0.17391304347826081;1;1; +gCurve=3;0;0;1;1; +bCurve=3;0;0;0.051383399209486022;0.17391304347826081;0.91699604743083007;0.76284584980237169;1;1; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Faded/Faded Warm 1.pp3 b/rtdata/profiles/Faded/Faded Warm 1.pp3 new file mode 100644 index 000000000..3f7e67442 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Warm 1.pp3 @@ -0,0 +1,101 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=70 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=SatAndValueBlending +CurveMode2=FilmLike +Curve=3;0;0;0.23320158102766808;0.58893280632411094;0.69169960474308201;0.96047430830039549;1;1; +Curve2=3;0;0;0.12213438735177862;0.012648221343873525;0.46245059288537577;0.41250131169330889;1;1; + +[Channel Mixer] +Red=60;0;20; +Green=0;60;40; +Blue=-20;20;40; + +[Black & White] +Enabled=false + +[Luminance Curve] +Brightness=0 +Contrast=-25 +Chromaticity=-29 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; +ClCurve=0; +lhCurve=0; +hhCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=0 +Chroma=20 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.40 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false + +[HLRecovery] +Enabled=false +Method=Blend + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=3;0;0;0.051383399209486022;0.17391304347826081;1;1; +gCurve=3;0;0;1;1; +bCurve=3;0;0;0.051383399209486022;0.17391304347826081;0.91699604743083007;0.76284584980237169;1;1; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Faded/Faded Warm 2.pp3 b/rtdata/profiles/Faded/Faded Warm 2.pp3 new file mode 100644 index 000000000..ab60ddb4e --- /dev/null +++ b/rtdata/profiles/Faded/Faded Warm 2.pp3 @@ -0,0 +1,97 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=70 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=SatAndValueBlending +CurveMode2=FilmLike +Curve=3;0;0;0.23320158102766808;0.58893280632411094;0.69169960474308201;0.96047430830039549;1;1; +Curve2=3;0;0;0.12213438735177862;0.012648221343873525;0.46245059288537577;0.41250131169330889;1;1; + +[Channel Mixer] +Red=80;0;20; +Green=0;60;40; +Blue=-20;20;20; + +[Black & White] +Enabled=false + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=-29 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; +ClCurve=0; +lhCurve=0; +hhCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=0 +Chroma=20 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.40 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=3;0;0;0.051383399209486022;0.17391304347826081;1;1; +gCurve=3;0;0;1;1; +bCurve=3;0;0;0.051383399209486022;0.17391304347826081;0.91699604743083007;0.76284584980237169;1;1; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Faded/Faded Warm 3.pp3 b/rtdata/profiles/Faded/Faded Warm 3.pp3 new file mode 100644 index 000000000..4a53330e8 --- /dev/null +++ b/rtdata/profiles/Faded/Faded Warm 3.pp3 @@ -0,0 +1,97 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=70 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=SatAndValueBlending +CurveMode2=FilmLike +Curve=3;0;0;0.23320158102766808;0.58893280632411094;0.69169960474308201;0.96047430830039549;1;1; +Curve2=3;0;0;0.12213438735177862;0.012648221343873525;0.46245059288537577;0.41250131169330889;1;1; + +[Channel Mixer] +Red=80;0;20; +Green=0;60;40; +Blue=-20;20;20; + +[Black & White] +Enabled=false + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=-29 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +LcCurve=0; +ClCurve=0; +lhCurve=0; +hhCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=true +Luma=0 +Ldetail=0 +Chroma=20 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.40 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=3;0;0;0.051383399209486022;0.17391304347826081;1;1; +gCurve=3;0;0;1;1; +bCurve=3;0;0;0.051383399209486022;0.17391304347826081;0.57312252964427013;0.95652173913043359;1;1; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Generic/Deep Shadows.pp3 b/rtdata/profiles/Generic/Deep Shadows.pp3 new file mode 100644 index 000000000..4fe3b95cb --- /dev/null +++ b/rtdata/profiles/Generic/Deep Shadows.pp3 @@ -0,0 +1,162 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Compensation=0 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=70 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=Standard +CurveMode2=Standard +Curve=3;0;0;0.10280701754385937;0;0.22561403508771805;0.081754385964912232;0.82456140350877249;0.82456140350877249;1;1; +Curve2=3;0;0;0.20585593677025255;0.44367403149511991;0.6315789473684208;0.89473684210526305;1;1; + +[HLRecovery] +Enabled=false +Method=Blend + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Black & White] +Enabled=false +Method=Desaturation +Auto=false +ComplementaryColors=true +Setting=NormalContrast +Filter=None +MixerRed=33 +MixerOrange=33 +MixerYellow=33 +MixerGreen=33 +MixerCyan=33 +MixerBlue=33 +MixerMagenta=33 +MixerPurple=33 +GammaRed=0 +GammaGreen=0 +GammaBlue=0 +LuminanceCurve=0; +BeforeCurveMode=Standard +AfterCurveMode=Standard +BeforeCurve=0; +AfterCurve=0; + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=0 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +lhCurve=0; +hhCurve=0; +LcCurve=0; +ClCurve=0; + +[Vibrance] +Enabled=true +Pastels=20 +Saturated=20 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false +Degree=90 +AutoDegree=true +Surround=Average +AdaptLum=16 +Badpixsl=0 +Model=RawT +Algorithm=No +J-Light=0 +Q-Bright=0 +C-Chroma=0 +S-Chroma=0 +M-Chroma=0 +J-Contrast=0 +Q-Contrast=0 +H-Hue=0 +RSTProtection=0 +AdaptScene=2000 +AutoAdapscen=true +SurrSource=false +Gamut=true +Datacie=false +Tonecie=false +CurveMode=Lightness +CurveMode2=Lightness +CurveMode3=Chroma +Curve=0; +Curve2=0; +Curve3=0; + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.4 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=0 +HighlightTonalWidth=80 +Shadows=0 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=40 + +[Gradient] +Enabled=false +Degree=0 +Feather=25 +Strength=0.6 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0.6 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Generic/Equilibrated.pp3 b/rtdata/profiles/Generic/Equilibrated.pp3 new file mode 100644 index 000000000..744f3032e --- /dev/null +++ b/rtdata/profiles/Generic/Equilibrated.pp3 @@ -0,0 +1,162 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Compensation=0 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=70 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=Standard +CurveMode2=WeightedStd +Curve=3;0;0;0.10641712584710848;0;0.22561403508771805;0.12507568560390137;0.82456140350877249;0.82456140350877249;1;1; +Curve2=3;0;0;0.20585593677025255;0.44367403149511991;0.6315789473684208;0.89473684210526305;1;1; + +[HLRecovery] +Enabled=false +Method=Blend + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Black & White] +Enabled=false +Method=Desaturation +Auto=false +ComplementaryColors=true +Setting=NormalContrast +Filter=None +MixerRed=33 +MixerOrange=33 +MixerYellow=33 +MixerGreen=33 +MixerCyan=33 +MixerBlue=33 +MixerMagenta=33 +MixerPurple=33 +GammaRed=0 +GammaGreen=0 +GammaBlue=0 +LuminanceCurve=0; +BeforeCurveMode=Standard +AfterCurveMode=Standard +BeforeCurve=0; +AfterCurve=0; + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=0 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +lhCurve=0; +hhCurve=0; +LcCurve=0; +ClCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false +Degree=90 +AutoDegree=true +Surround=Average +AdaptLum=16 +Badpixsl=0 +Model=RawT +Algorithm=No +J-Light=0 +Q-Bright=0 +C-Chroma=0 +S-Chroma=0 +M-Chroma=0 +J-Contrast=0 +Q-Contrast=0 +H-Hue=0 +RSTProtection=0 +AdaptScene=2000 +AutoAdapscen=true +SurrSource=false +Gamut=true +Datacie=false +Tonecie=false +CurveMode=Lightness +CurveMode2=Lightness +CurveMode3=Chroma +Curve=0; +Curve2=0; +Curve3=0; + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.4 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=0 +HighlightTonalWidth=80 +Shadows=0 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=40 + +[Gradient] +Enabled=false +Degree=0 +Feather=25 +Strength=0.6 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0.6 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Generic/High-Key.pp3 b/rtdata/profiles/Generic/High-Key.pp3 new file mode 100644 index 000000000..3046dd460 --- /dev/null +++ b/rtdata/profiles/Generic/High-Key.pp3 @@ -0,0 +1,162 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=true +Clip=0.02 +Compensation=0 +Brightness=0 +Contrast=0 +Saturation=-10 +Black=0 +HighlightCompr=0 +HighlightComprThreshold=33 +ShadowCompr=50 +CurveMode=Standard +CurveMode2=Standard +Curve=2;0.105;0.25;0.75;15;60;30;-70; +Curve2=0; + +[HLRecovery] +Enabled=false +Method=Blend + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Black & White] +Enabled=false +Method=Desaturation +Auto=false +ComplementaryColors=true +Setting=NormalContrast +Filter=None +MixerRed=33 +MixerOrange=33 +MixerYellow=33 +MixerGreen=33 +MixerCyan=33 +MixerBlue=33 +MixerMagenta=33 +MixerPurple=33 +GammaRed=0 +GammaGreen=0 +GammaBlue=0 +LuminanceCurve=0; +BeforeCurveMode=Standard +AfterCurveMode=Standard +BeforeCurve=0; +AfterCurve=0; + +[Luminance Curve] +Brightness=0 +Contrast=5 +Chromaticity=-10 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +lhCurve=0; +hhCurve=0; +LcCurve=0; +ClCurve=0; + +[Vibrance] +Enabled=false +Pastels=50 +Saturated=50 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false +Degree=90 +AutoDegree=true +Surround=Average +AdaptLum=16 +Badpixsl=0 +Model=RawT +Algorithm=JC +J-Light=0 +Q-Bright=0 +C-Chroma=0 +S-Chroma=0 +M-Chroma=0 +J-Contrast=0 +Q-Contrast=0 +H-Hue=0 +RSTProtection=0 +AdaptScene=2000 +AutoAdapscen=true +SurrSource=false +Gamut=true +Datacie=false +Tonecie=false +CurveMode=Lightness +CurveMode2=Lightness +CurveMode3=Chroma +Curve=0; +Curve2=0; +Curve3=0; + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.4 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=10 +HighlightTonalWidth=80 +Shadows=10 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=30 + +[Gradient] +Enabled=false +Degree=0 +Feather=25 +Strength=0.6 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0.6 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Generic/Natural 1.pp3 b/rtdata/profiles/Generic/Natural 1.pp3 new file mode 100644 index 000000000..8bfd2ffb0 --- /dev/null +++ b/rtdata/profiles/Generic/Natural 1.pp3 @@ -0,0 +1,162 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=true +Clip=0.02 +Compensation=0 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=0 +HighlightComprThreshold=33 +ShadowCompr=50 +CurveMode=Standard +CurveMode2=Standard +Curve=1;0;0;0.04;0.03;0.17684498029510265;0.21732319394192093;0.70232558139534862;0.74883720930232545;1;1; +Curve2=0; + +[HLRecovery] +Enabled=false +Method=Blend + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Black & White] +Enabled=false +Method=Desaturation +Auto=false +ComplementaryColors=true +Setting=NormalContrast +Filter=None +MixerRed=33 +MixerOrange=33 +MixerYellow=33 +MixerGreen=33 +MixerCyan=33 +MixerBlue=33 +MixerMagenta=33 +MixerPurple=33 +GammaRed=0 +GammaGreen=0 +GammaBlue=0 +LuminanceCurve=0; +BeforeCurveMode=Standard +AfterCurveMode=Standard +BeforeCurve=0; +AfterCurve=0; + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=0 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +lhCurve=0; +hhCurve=0; +LcCurve=0; +ClCurve=0; + +[Vibrance] +Enabled=false +Pastels=50 +Saturated=50 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false +Degree=90 +AutoDegree=true +Surround=Average +AdaptLum=16 +Badpixsl=0 +Model=RawT +Algorithm=JC +J-Light=0 +Q-Bright=0 +C-Chroma=0 +S-Chroma=0 +M-Chroma=0 +J-Contrast=0 +Q-Contrast=0 +H-Hue=0 +RSTProtection=0 +AdaptScene=2000 +AutoAdapscen=true +SurrSource=false +Gamut=true +Datacie=false +Tonecie=false +CurveMode=Lightness +CurveMode2=Lightness +CurveMode3=Chroma +Curve=0; +Curve2=0; +Curve3=0; + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.4 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=10 +HighlightTonalWidth=80 +Shadows=10 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=30 + +[Gradient] +Enabled=false +Degree=0 +Feather=25 +Strength=0.6 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0.6 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Generic/Natural 2.pp3 b/rtdata/profiles/Generic/Natural 2.pp3 new file mode 100644 index 000000000..940cab16e --- /dev/null +++ b/rtdata/profiles/Generic/Natural 2.pp3 @@ -0,0 +1,162 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=true +Clip=0.02 +Compensation=0 +Brightness=0 +Contrast=0 +Saturation=5 +Black=0 +HighlightCompr=0 +HighlightComprThreshold=33 +ShadowCompr=50 +CurveMode=Standard +CurveMode2=Standard +Curve=1;0;0;0.45754265471370759;0.57906737998843294;1;1; +Curve2=0; + +[HLRecovery] +Enabled=false +Method=Blend + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Black & White] +Enabled=false +Method=Desaturation +Auto=false +ComplementaryColors=true +Setting=NormalContrast +Filter=None +MixerRed=33 +MixerOrange=33 +MixerYellow=33 +MixerGreen=33 +MixerCyan=33 +MixerBlue=33 +MixerMagenta=33 +MixerPurple=33 +GammaRed=0 +GammaGreen=0 +GammaBlue=0 +LuminanceCurve=0; +BeforeCurveMode=Standard +AfterCurveMode=Standard +BeforeCurve=0; +AfterCurve=0; + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=5 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=3;0;0;0.84892086330935235;0.69064748201438808;1;1; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +lhCurve=0; +hhCurve=0; +LcCurve=0; +ClCurve=0; + +[Vibrance] +Enabled=false +Pastels=50 +Saturated=50 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false +Degree=90 +AutoDegree=true +Surround=Average +AdaptLum=16 +Badpixsl=0 +Model=RawT +Algorithm=JC +J-Light=0 +Q-Bright=0 +C-Chroma=0 +S-Chroma=0 +M-Chroma=0 +J-Contrast=0 +Q-Contrast=0 +H-Hue=0 +RSTProtection=0 +AdaptScene=2000 +AutoAdapscen=true +SurrSource=false +Gamut=true +Datacie=false +Tonecie=false +CurveMode=Lightness +CurveMode2=Lightness +CurveMode3=Chroma +Curve=0; +Curve2=0; +Curve3=0; + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.4 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=10 +HighlightTonalWidth=80 +Shadows=10 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=30 + +[Gradient] +Enabled=false +Degree=0 +Feather=25 +Strength=0.6 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0.6 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Generic/Punchy 1.pp3 b/rtdata/profiles/Generic/Punchy 1.pp3 new file mode 100644 index 000000000..ae6cdbb7e --- /dev/null +++ b/rtdata/profiles/Generic/Punchy 1.pp3 @@ -0,0 +1,162 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=true +Clip=0.02 +Compensation=0 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=0 +HighlightComprThreshold=33 +ShadowCompr=50 +CurveMode=Standard +CurveMode2=Standard +Curve=0; +Curve2=0; + +[HLRecovery] +Enabled=false +Method=Blend + +[Channel Mixer] +Red=120;-10;-10; +Green=-10;120;-10; +Blue=-10;-10;120; + +[Black & White] +Enabled=false +Method=Desaturation +Auto=false +ComplementaryColors=true +Setting=NormalContrast +Filter=None +MixerRed=33 +MixerOrange=33 +MixerYellow=33 +MixerGreen=33 +MixerCyan=33 +MixerBlue=33 +MixerMagenta=33 +MixerPurple=33 +GammaRed=0 +GammaGreen=0 +GammaBlue=0 +LuminanceCurve=0; +BeforeCurveMode=Standard +AfterCurveMode=Standard +BeforeCurve=0; +AfterCurve=0; + +[Luminance Curve] +Brightness=0 +Contrast=10 +Chromaticity=5 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +lhCurve=0; +hhCurve=0; +LcCurve=0; +ClCurve=0; + +[Vibrance] +Enabled=false +Pastels=50 +Saturated=50 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false +Degree=90 +AutoDegree=true +Surround=Average +AdaptLum=16 +Badpixsl=0 +Model=RawT +Algorithm=JC +J-Light=0 +Q-Bright=0 +C-Chroma=0 +S-Chroma=0 +M-Chroma=0 +J-Contrast=0 +Q-Contrast=0 +H-Hue=0 +RSTProtection=0 +AdaptScene=2000 +AutoAdapscen=true +SurrSource=false +Gamut=true +Datacie=false +Tonecie=false +CurveMode=Lightness +CurveMode2=Lightness +CurveMode3=Chroma +Curve=0; +Curve2=0; +Curve3=0; + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.4 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=10 +HighlightTonalWidth=80 +Shadows=10 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=30 + +[Gradient] +Enabled=false +Degree=0 +Feather=25 +Strength=0.6 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0.6 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Generic/Punchy 2.pp3 b/rtdata/profiles/Generic/Punchy 2.pp3 new file mode 100644 index 000000000..750b01565 --- /dev/null +++ b/rtdata/profiles/Generic/Punchy 2.pp3 @@ -0,0 +1,162 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=true +Clip=0.02 +Compensation=0 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=0 +HighlightComprThreshold=33 +ShadowCompr=50 +CurveMode=Standard +CurveMode2=Standard +Curve=0; +Curve2=0; + +[HLRecovery] +Enabled=false +Method=Blend + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Black & White] +Enabled=false +Method=Desaturation +Auto=false +ComplementaryColors=true +Setting=NormalContrast +Filter=None +MixerRed=33 +MixerOrange=33 +MixerYellow=33 +MixerGreen=33 +MixerCyan=33 +MixerBlue=33 +MixerMagenta=33 +MixerPurple=33 +GammaRed=0 +GammaGreen=0 +GammaBlue=0 +LuminanceCurve=0; +BeforeCurveMode=Standard +AfterCurveMode=Standard +BeforeCurve=0; +AfterCurve=0; + +[Luminance Curve] +Brightness=0 +Contrast=10 +Chromaticity=5 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +lhCurve=0; +hhCurve=0; +LcCurve=0; +ClCurve=0; + +[Vibrance] +Enabled=true +Pastels=50 +Saturated=50 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false +Degree=90 +AutoDegree=true +Surround=Average +AdaptLum=16 +Badpixsl=0 +Model=RawT +Algorithm=JC +J-Light=0 +Q-Bright=0 +C-Chroma=0 +S-Chroma=0 +M-Chroma=0 +J-Contrast=0 +Q-Contrast=0 +H-Hue=0 +RSTProtection=0 +AdaptScene=2000 +AutoAdapscen=true +SurrSource=false +Gamut=true +Datacie=false +Tonecie=false +CurveMode=Lightness +CurveMode2=Lightness +CurveMode3=Chroma +Curve=0; +Curve2=0; +Curve3=0; + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.4 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=10 +HighlightTonalWidth=80 +Shadows=10 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=30 + +[Gradient] +Enabled=false +Degree=0 +Feather=25 +Strength=0.6 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0.6 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Non-raw/Brighten.pp3 b/rtdata/profiles/Non-raw/Brighten.pp3 new file mode 100644 index 000000000..267aa4e0b --- /dev/null +++ b/rtdata/profiles/Non-raw/Brighten.pp3 @@ -0,0 +1,20 @@ +[Version] +AppVersion=4.2.2 +Version=322 + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=0 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=3;0;0;0.055044034166268768;0;0.52103559870550098;1;1;1; +aCurve=0; +bCurve=0; +ccCurve=3;0;0;0.10679611650485436;0.30420711974110037;1;1; +chCurve=0; +lhCurve=0; +hhCurve=0; +LcCurve=0; +ClCurve=3;0;0;0.3592233009708739;0.3592233009708739;0.40129449838187703;0.40129449838187703;1;0.0032362459546936488; diff --git a/rtdata/profiles/Pop/Pop 1.pp3 b/rtdata/profiles/Pop/Pop 1.pp3 new file mode 100644 index 000000000..61685727e --- /dev/null +++ b/rtdata/profiles/Pop/Pop 1.pp3 @@ -0,0 +1,131 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Compensation=1 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=70 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=FilmLike +CurveMode2=Standard +Curve=3;0;0;0.084;0;0.187;0.188;0.442;0.58;1;1; +Curve2=0; + +[HLRecovery] +Enabled=true +Method=Blend + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Black & White] +Enabled=false + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=0 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=3;0;0;0.5;0.4;1;1; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +lhCurve=0; +hhCurve=0; +LcCurve=0; +ClCurve=0; + +[Vibrance] +Enabled=false + +[White Balance] +Setting=Camera +Equal=1 + +[Color appearance] +Enabled=true +Degree=100 +AutoDegree=true +Surround=Average +AdaptLum=16 +Badpixsl=0 +Model=RawT +Algorithm=QM +J-Light=0 +Q-Bright=0 +C-Chroma=0 +S-Chroma=0 +M-Chroma=0 +J-Contrast=0 +Q-Contrast=0 +H-Hue=0 +RSTProtection=0 +AdaptScene=208 +AutoAdapscen=true +SurrSource=false +Gamut=true +Datacie=false +Tonecie=true +CurveMode=Brightness +CurveMode2=Lightness +CurveMode3=Colorfullness +Curve=0; +Curve2=3;0;0;0.15;0;0.67;0.91;1;1; +Curve3=3;0;0;0.08;0.02;0.3;0.5;1;1; + +[EPD] +Enabled=true +Strength=0.25 +EdgeStopping=2.4 +Scale=0.10 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false + +[Gradient] +Enabled=false + +[PCVignette] +Enabled=true +Strength=1 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + +[ColorToning] +Enabled=false + +[RAW] +CA=true +HotPixelFilter=true +DeadPixelFilter=false +HotDeadPixelThresh=100 diff --git a/rtdata/profiles/Pop/Pop 2 L.pp3 b/rtdata/profiles/Pop/Pop 2 L.pp3 new file mode 100644 index 000000000..13fe80293 --- /dev/null +++ b/rtdata/profiles/Pop/Pop 2 L.pp3 @@ -0,0 +1,131 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Compensation=1 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=70 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=FilmLike +CurveMode2=Standard +Curve=3;0;0;0.179;0;0.384;0.502;1;1; +Curve2=0; + +[HLRecovery] +Enabled=true +Method=Blend + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Black & White] +Enabled=false + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=0 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=3;0;0;0.12;0.3;0.5;0.46;1;1; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +lhCurve=0; +hhCurve=0; +LcCurve=0; +ClCurve=0; + +[Vibrance] +Enabled=false + +[White Balance] +Setting=Camera +Equal=1 + +[Color appearance] +Enabled=true +Degree=100 +AutoDegree=true +Surround=Average +AdaptLum=16 +Badpixsl=0 +Model=RawT +Algorithm=QM +J-Light=0 +Q-Bright=0 +C-Chroma=0 +S-Chroma=0 +M-Chroma=0 +J-Contrast=0 +Q-Contrast=0 +H-Hue=0 +RSTProtection=0 +AdaptScene=208 +AutoAdapscen=true +SurrSource=false +Gamut=true +Datacie=false +Tonecie=true +CurveMode=Brightness +CurveMode2=Lightness +CurveMode3=Colorfullness +Curve=0; +Curve2=3;0;0;0.15;0;0.67;0.91;1;1; +Curve3=3;0;0;0.08;0.02;0.3;0.5;1;1; + +[EPD] +Enabled=true +Strength=0.25 +EdgeStopping=2.4 +Scale=0.10 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false + +[Gradient] +Enabled=false + +[PCVignette] +Enabled=true +Strength=1 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + +[ColorToning] +Enabled=false + +[RAW] +CA=true +HotPixelFilter=true +DeadPixelFilter=false +HotDeadPixelThresh=100 diff --git a/rtdata/profiles/Pop/Pop 3 Skin.pp3 b/rtdata/profiles/Pop/Pop 3 Skin.pp3 new file mode 100644 index 000000000..90ce7e346 --- /dev/null +++ b/rtdata/profiles/Pop/Pop 3 Skin.pp3 @@ -0,0 +1,131 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Compensation=1 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=70 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=SatAndValueBlending +CurveMode2=Standard +Curve=3;0;0;0.084;0;0.187;0.188;0.442;0.58;1;1; +Curve2=0; + +[HLRecovery] +Enabled=true +Method=Blend + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Black & White] +Enabled=false + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=0 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=3;0;0;0.5;0.4;1;1; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +lhCurve=0; +hhCurve=0; +LcCurve=0; +ClCurve=0; + +[Vibrance] +Enabled=false + +[White Balance] +Setting=Camera +Equal=1 + +[Color appearance] +Enabled=true +Degree=100 +AutoDegree=true +Surround=Average +AdaptLum=16 +Badpixsl=0 +Model=RawT +Algorithm=QM +J-Light=0 +Q-Bright=0 +C-Chroma=0 +S-Chroma=0 +M-Chroma=0 +J-Contrast=0 +Q-Contrast=20 +H-Hue=0 +RSTProtection=50 +AdaptScene=208 +AutoAdapscen=true +SurrSource=false +Gamut=true +Datacie=false +Tonecie=true +CurveMode=Brightness +CurveMode2=Lightness +CurveMode3=Colorfullness +Curve=0; +Curve2=3;0;0;0.15;0;0.67;0.91;1;1; +Curve3=3;0;0;0.08;0.02;0.38;0.73;1;1; + +[EPD] +Enabled=true +Strength=0.25 +EdgeStopping=2.4 +Scale=0.10 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false + +[Gradient] +Enabled=false + +[PCVignette] +Enabled=true +Strength=1 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + +[ColorToning] +Enabled=false + +[RAW] +CA=true +HotPixelFilter=true +DeadPixelFilter=false +HotDeadPixelThresh=100 diff --git a/rtdata/profiles/Pop/Pop 4 BW.pp3 b/rtdata/profiles/Pop/Pop 4 BW.pp3 new file mode 100644 index 000000000..4277869a4 --- /dev/null +++ b/rtdata/profiles/Pop/Pop 4 BW.pp3 @@ -0,0 +1,153 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Compensation=0.66 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=70 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=SatAndValueBlending +CurveMode2=Standard +Curve=3;0;0;0.084;0;0.187;0.188;0.587;0.742;1;1; +Curve2=0; + +[HLRecovery] +Enabled=true +Method=Blend + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Black & White] +Enabled=true +Method=ChannelMixer +Auto=true +ComplementaryColors=true +Setting=RGB-Rel +Filter=None +MixerRed=-100 +MixerOrange=33 +MixerYellow=33 +MixerGreen=-100 +MixerCyan=33 +MixerBlue=0 +MixerMagenta=33 +MixerPurple=33 +GammaRed=0 +GammaGreen=0 +GammaBlue=0 +Algorithm=SP +LuminanceCurve=0; +BeforeCurveMode=Standard +AfterCurveMode=Standard +BeforeCurve=0; +AfterCurve=0; + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=0 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=3;0;0;0.212;0.119;0.674;0.773;1;1; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +lhCurve=0; +hhCurve=0; +LcCurve=0; +ClCurve=0; + +[Vibrance] +Enabled=false + +[White Balance] +Setting=Camera +Equal=1 + +[Color appearance] +Enabled=true +Degree=100 +AutoDegree=true +Surround=Average +AdaptLum=16 +Badpixsl=0 +Model=RawT +Algorithm=QM +J-Light=0 +Q-Bright=0 +C-Chroma=0 +S-Chroma=0 +M-Chroma=0 +J-Contrast=0 +Q-Contrast=0 +H-Hue=0 +RSTProtection=0 +AdaptScene=208 +AutoAdapscen=true +SurrSource=false +Gamut=true +Datacie=false +Tonecie=true +CurveMode=Lightness +CurveMode2=Lightness +CurveMode3=Colorfullness +Curve=3;0;0;0.15;0;0.545;1;1;1; +Curve2=0; +Curve3=0; + +[EPD] +Enabled=true +Strength=0.25 +EdgeStopping=2.4 +Scale=0.10 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false + +[Gradient] +Enabled=false + +[PCVignette] +Enabled=true +Strength=1 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + +[ColorToning] +Enabled=false + +[RAW] +CA=true +HotPixelFilter=true +DeadPixelFilter=false +HotDeadPixelThresh=100 diff --git a/rtdata/profiles/Portrait/Portrait Lejto.pp3 b/rtdata/profiles/Portrait/Portrait Lejto.pp3 new file mode 100644 index 000000000..0fe9d68ad --- /dev/null +++ b/rtdata/profiles/Portrait/Portrait Lejto.pp3 @@ -0,0 +1,162 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Compensation=0 +Brightness=0 +Contrast=25 +Saturation=0 +Black=0 +HighlightCompr=0 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=Standard +CurveMode2=SatAndValueBlending +Curve=1;0;0;0.079285714285714293;0.03;0.18041642857142856;0.21375157142857143;0.702326;0.748837;1;1; +Curve2=1;0;0;0.075;0.13571428571428609;0.3;0.42857142857142855;0.7214285714285712;0.74642857142857144;1;1; + +[HLRecovery] +Enabled=false +Method=Blend + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Black & White] +Enabled=false +Method=Desaturation +Auto=false +ComplementaryColors=true +Setting=NormalContrast +Filter=None +MixerRed=33 +MixerOrange=33 +MixerYellow=33 +MixerGreen=33 +MixerCyan=33 +MixerBlue=33 +MixerMagenta=33 +MixerPurple=33 +GammaRed=0 +GammaGreen=0 +GammaBlue=0 +LuminanceCurve=0; +BeforeCurveMode=Standard +AfterCurveMode=Standard +BeforeCurve=0; +AfterCurve=0; + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=0 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=1;0;0;1;1; +ccCurve=0; +chCurve=0; +lhCurve=0; +hhCurve=0; +LcCurve=0; +ClCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false +Degree=90 +AutoDegree=true +Surround=Average +AdaptLum=16 +Badpixsl=0 +Model=RawT +Algorithm=No +J-Light=0 +Q-Bright=0 +C-Chroma=0 +S-Chroma=0 +M-Chroma=0 +J-Contrast=0 +Q-Contrast=0 +H-Hue=0 +RSTProtection=0 +AdaptScene=2000 +AutoAdapscen=true +SurrSource=false +Gamut=true +Datacie=false +Tonecie=false +CurveMode=Lightness +CurveMode2=Lightness +CurveMode3=Chroma +Curve=0; +Curve2=0; +Curve3=0; + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.4 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=0 +HighlightTonalWidth=80 +Shadows=0 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=40 + +[Gradient] +Enabled=false +Degree=0 +Feather=25 +Strength=0.6 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0.6 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Portrait/Portrait Smooth.pp3 b/rtdata/profiles/Portrait/Portrait Smooth.pp3 new file mode 100644 index 000000000..26bb855dd --- /dev/null +++ b/rtdata/profiles/Portrait/Portrait Smooth.pp3 @@ -0,0 +1,139 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Compensation=0 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=70 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=FilmLike +CurveMode2=Standard +Curve=1;0;0;0.443;0.574;1;1; +Curve2=0; + +[HLRecovery] +Enabled=true +Method=Luminance + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Black & White] +Enabled=false + +[Luminance Curve] +Brightness=-20 +Contrast=-20 +Chromaticity=0 +AvoidColorShift=true +RedAndSkinTonesProtection=50 +LCredsk=true +LCurve=3;0;0;0.043;0.014;0.162;0.162;0.652;0.93;1;1; +aCurve=0; +bCurve=0; +ccCurve=1;0;0;0.254;0.3;1;1; +chCurve=0; +lhCurve=0; +hhCurve=0; +LcCurve=0; +ClCurve=0; + +[Sharpening] +Enabled=true +Method=usm +Radius=0.5 +Amount=250 +Threshold=20;80;2000;1200; +OnlyEdges=false +EdgedetectionRadius=1.9 +EdgeTolerance=1800 +HalocontrolEnabled=false +HalocontrolAmount=85 +DeconvRadius=0.75 +DeconvAmount=75 +DeconvDamping=20 +DeconvIterations=30 + +[Vibrance] +Enabled=false + +[SharpenEdge] +Enabled=false + +[SharpenMicro] +Enabled=false + +[White Balance] +Setting=Camera + +[Color appearance] +Enabled=false + +[Impulse Denoising] +Enabled=false + +[Defringing] +Enabled=false + +[Directional Pyramid Denoising] +Enabled=false + +[EPD] +Enabled=false + +[Shadows & Highlights] +Enabled=false + +[Crop] +Enabled=false + +[Gradient] +Enabled=false + +[PCVignette] +Enabled=false + +[Directional Pyramid Equalizer] +Enabled=true +Gamutlab=true +Mult0=1 +Mult1=1 +Mult2=1 +Mult3=0.6 +Mult4=0.6 +Threshold=0.2 +Skinprotect=0 +Hueskin=-5;25;170;120; + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + +[ColorToning] +Enabled=false + +[RAW] +CA=true + diff --git a/rtdata/profiles/Skintones/Skintones - Natural TM.pp3 b/rtdata/profiles/Skintones/Skintones - Natural TM.pp3 new file mode 100644 index 000000000..ba2ff3be4 --- /dev/null +++ b/rtdata/profiles/Skintones/Skintones - Natural TM.pp3 @@ -0,0 +1,173 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Compensation=0 +Brightness=0 +Contrast=0 +Saturation=0 +Black=-1500 +HighlightCompr=40 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=FilmLike +CurveMode2=FilmLike +Curve=1;0;0;0.49407114624505927;0.49407114624505927;1;1; +Curve2=1;0;0;0.055335968379446598;0.019762845849802379;0.12648221343873495;0.11067193675889311;1;0.94861660079051413; + +[HLRecovery] +Enabled=true +Method=Blend + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Black & White] +Enabled=false +Method=Desaturation +Auto=false +ComplementaryColors=true +Setting=NormalContrast +Filter=None +MixerRed=33 +MixerOrange=33 +MixerYellow=33 +MixerGreen=33 +MixerCyan=33 +MixerBlue=33 +MixerMagenta=33 +MixerPurple=33 +GammaRed=0 +GammaGreen=0 +GammaBlue=0 +LuminanceCurve=0; +BeforeCurveMode=Standard +AfterCurveMode=Standard +BeforeCurve=0; +AfterCurve=0; + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=0 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=3;0;0;0.063241106719367585;6.9388939039072284e-18;0.49407114624505927;0.50197628458498023;0.92885375494071132;0.99604743083003922;1;1; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +lhCurve=0; +hhCurve=0; +LcCurve=0; +ClCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=true +Degree=100 +AutoDegree=true +Surround=Average +AdaptLum=16 +Badpixsl=0 +Model=RawT +Algorithm=QM +J-Light=0 +Q-Bright=0 +C-Chroma=0 +S-Chroma=0 +M-Chroma=10 +J-Contrast=0 +Q-Contrast=0 +H-Hue=0 +RSTProtection=0 +AdaptScene=2000 +AutoAdapscen=true +SurrSource=false +Gamut=false +Datacie=false +Tonecie=true +CurveMode=Lightness +CurveMode2=Lightness +CurveMode3=Chroma +Curve=3;0;0;0.29629629629629628;0.19341563786008226;0.69547325102880675;0.80246913580246892;1;1; +Curve2=3;0;0;0.056806920298983779;0.020475350634080798;0.69802637104224341;0.88816662467456142;1;1; +Curve3=0; + +[Directional Pyramid Denoising] +Enabled=false +Enhance=false +Luma=0 +Ldetail=0 +Chroma=15 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=true +Strength=0.25 +EdgeStopping=1.4 +Scale=0.25 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=0 +HighlightTonalWidth=80 +Shadows=0 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=40 + +[Gradient] +Enabled=false +Degree=0 +Feather=25 +Strength=0.6 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0.6 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Skintones/Skintones - Natural.pp3 b/rtdata/profiles/Skintones/Skintones - Natural.pp3 new file mode 100644 index 000000000..fb05ab00f --- /dev/null +++ b/rtdata/profiles/Skintones/Skintones - Natural.pp3 @@ -0,0 +1,173 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Compensation=0 +Brightness=0 +Contrast=0 +Saturation=0 +Black=-1500 +HighlightCompr=30 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=FilmLike +CurveMode2=FilmLike +Curve=1;0;0;0.49802371541501977;0.49802371541501977;1;1; +Curve2=1;0;0;0.097430830039525476;0.066798418972331866;0.12648221343873495;0.11067193675889311;1;0.95256916996047469; + +[HLRecovery] +Enabled=true +Method=Blend + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Black & White] +Enabled=false +Method=Desaturation +Auto=false +ComplementaryColors=true +Setting=NormalContrast +Filter=None +MixerRed=33 +MixerOrange=33 +MixerYellow=33 +MixerGreen=33 +MixerCyan=33 +MixerBlue=33 +MixerMagenta=33 +MixerPurple=33 +GammaRed=0 +GammaGreen=0 +GammaBlue=0 +LuminanceCurve=0; +BeforeCurveMode=Standard +AfterCurveMode=Standard +BeforeCurve=0; +AfterCurve=0; + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=0 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=3;0;0;0.063241106719367585;6.9388939039072284e-18;0.49407114624505927;0.50197628458498023;0.92885375494071132;0.99604743083003922;1;1; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +lhCurve=0; +hhCurve=0; +LcCurve=0; +ClCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=true +Degree=100 +AutoDegree=true +Surround=Average +AdaptLum=16 +Badpixsl=0 +Model=RawT +Algorithm=QM +J-Light=0 +Q-Bright=0 +C-Chroma=0 +S-Chroma=0 +M-Chroma=8 +J-Contrast=0 +Q-Contrast=0 +H-Hue=0 +RSTProtection=0 +AdaptScene=2000 +AutoAdapscen=true +SurrSource=false +Gamut=true +Datacie=false +Tonecie=true +CurveMode=Lightness +CurveMode2=Lightness +CurveMode3=Chroma +Curve=3;0;0;0.19753086419753088;0.18106995884773661;0.58847736625514402;0.79012345679012241;1;1; +Curve2=3;0;0;0.056806920298983779;0.020475350634080798;0.69802637104224341;0.88816662467456142;1;1; +Curve3=0; + +[Directional Pyramid Denoising] +Enabled=true +Enhance=false +Luma=0 +Ldetail=0 +Chroma=15 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.4 +Scale=0.25 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=0 +HighlightTonalWidth=80 +Shadows=0 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=40 + +[Gradient] +Enabled=false +Degree=0 +Feather=25 +Strength=0.6 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0.6 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Skintones/Skintones - Pale TM Bright.pp3 b/rtdata/profiles/Skintones/Skintones - Pale TM Bright.pp3 new file mode 100644 index 000000000..7ed909f89 --- /dev/null +++ b/rtdata/profiles/Skintones/Skintones - Pale TM Bright.pp3 @@ -0,0 +1,173 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Compensation=0 +Brightness=10 +Contrast=10 +Saturation=0 +Black=0 +HighlightCompr=40 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=WeightedStd +CurveMode2=SatAndValueBlending +Curve=3;0;0;0.1013677790907735;0.011341564456759405;0.32302405498281778;0.2147079037800686;1;0.81422924901185889; +Curve2=3;0;0;0.16151202749140844;0.24319627128016638;0.59793814432989756;0.90034364261168354;1;1; + +[HLRecovery] +Enabled=true +Method=Blend + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Black & White] +Enabled=false +Method=Desaturation +Auto=false +ComplementaryColors=true +Setting=NormalContrast +Filter=None +MixerRed=33 +MixerOrange=33 +MixerYellow=33 +MixerGreen=33 +MixerCyan=33 +MixerBlue=33 +MixerMagenta=33 +MixerPurple=33 +GammaRed=0 +GammaGreen=0 +GammaBlue=0 +LuminanceCurve=0; +BeforeCurveMode=Standard +AfterCurveMode=Standard +BeforeCurve=0; +AfterCurve=0; + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=0 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=3;0;0;0.063241106719367585;6.9388939039072284e-18;0.49407114624505927;0.50197628458498023;0.92885375494071132;0.99604743083003922;1;1; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +lhCurve=0; +hhCurve=0; +LcCurve=0; +ClCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=true +Degree=100 +AutoDegree=true +Surround=Average +AdaptLum=16 +Badpixsl=0 +Model=RawT +Algorithm=QM +J-Light=0 +Q-Bright=0 +C-Chroma=0 +S-Chroma=0 +M-Chroma=0 +J-Contrast=0 +Q-Contrast=-5 +H-Hue=0 +RSTProtection=0 +AdaptScene=2000 +AutoAdapscen=true +SurrSource=false +Gamut=true +Datacie=false +Tonecie=true +CurveMode=Lightness +CurveMode2=Lightness +CurveMode3=Chroma +Curve=3;0;0;0.29629629629629628;0.19341563786008226;0.69547325102880675;0.80246913580246892;1;1; +Curve2=3;0;0;0.056806920298983779;0.020475350634080798;0.69802637104224341;0.88816662467456142;1;1; +Curve3=0; + +[Directional Pyramid Denoising] +Enabled=true +Enhance=false +Luma=0 +Ldetail=0 +Chroma=15 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=true +Strength=0.25 +EdgeStopping=1.4 +Scale=0.25 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=10 +HighlightTonalWidth=80 +Shadows=10 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=30 + +[Gradient] +Enabled=false +Degree=0 +Feather=25 +Strength=0.6 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0.6 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Skintones/Skintones - Pale TM.pp3 b/rtdata/profiles/Skintones/Skintones - Pale TM.pp3 new file mode 100644 index 000000000..3e3476e92 --- /dev/null +++ b/rtdata/profiles/Skintones/Skintones - Pale TM.pp3 @@ -0,0 +1,173 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Compensation=0 +Brightness=10 +Contrast=10 +Saturation=0 +Black=0 +HighlightCompr=40 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=WeightedStd +CurveMode2=SatAndValueBlending +Curve=3;0;0;0.1013677790907735;0.011341564456759405;0.32302405498281778;0.2147079037800686;1;0.81422924901185889; +Curve2=3;0;0;0.16151202749140844;0.24319627128016638;0.59793814432989756;0.90034364261168354;1;1; + +[HLRecovery] +Enabled=true +Method=Blend + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Black & White] +Enabled=false +Method=Desaturation +Auto=false +ComplementaryColors=true +Setting=NormalContrast +Filter=None +MixerRed=33 +MixerOrange=33 +MixerYellow=33 +MixerGreen=33 +MixerCyan=33 +MixerBlue=33 +MixerMagenta=33 +MixerPurple=33 +GammaRed=0 +GammaGreen=0 +GammaBlue=0 +LuminanceCurve=0; +BeforeCurveMode=Standard +AfterCurveMode=Standard +BeforeCurve=0; +AfterCurve=0; + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=0 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=3;0;0;0.063241106719367585;6.9388939039072284e-18;0.49407114624505927;0.50197628458498023;0.92885375494071132;0.99604743083003922;1;1; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +lhCurve=0; +hhCurve=0; +LcCurve=0; +ClCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=true +Degree=100 +AutoDegree=true +Surround=Average +AdaptLum=16 +Badpixsl=0 +Model=RawT +Algorithm=QM +J-Light=0 +Q-Bright=0 +C-Chroma=0 +S-Chroma=0 +M-Chroma=0 +J-Contrast=0 +Q-Contrast=-5 +H-Hue=0 +RSTProtection=0 +AdaptScene=2000 +AutoAdapscen=true +SurrSource=false +Gamut=true +Datacie=false +Tonecie=true +CurveMode=Lightness +CurveMode2=Lightness +CurveMode3=Chroma +Curve=3;0;0;0.29629629629629628;0.19341563786008226;0.69547325102880675;0.80246913580246892;1;1; +Curve2=3;0;0;0.14545;0;0.69802600000000004;0.88816700000000004;1;1; +Curve3=0; + +[Directional Pyramid Denoising] +Enabled=true +Enhance=false +Luma=0 +Ldetail=0 +Chroma=15 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=true +Strength=0.25 +EdgeStopping=1.4 +Scale=0.25 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=10 +HighlightTonalWidth=80 +Shadows=10 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=30 + +[Gradient] +Enabled=false +Degree=0 +Feather=25 +Strength=0.6 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0.6 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Skintones/Skintones - Pale.pp3 b/rtdata/profiles/Skintones/Skintones - Pale.pp3 new file mode 100644 index 000000000..7f6aa9c99 --- /dev/null +++ b/rtdata/profiles/Skintones/Skintones - Pale.pp3 @@ -0,0 +1,173 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Compensation=0 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=30 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=WeightedStd +CurveMode2=SatAndValueBlending +Curve=3;0;0;0.1013677790907735;0.011341564456759405;0.32302405498281778;0.2147079037800686;1;1; +Curve2=3;0;0;0.16151202749140844;0.24319627128016638;0.59793814432989756;0.90034364261168354;1;1; + +[HLRecovery] +Enabled=true +Method=Blend + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Black & White] +Enabled=false +Method=Desaturation +Auto=false +ComplementaryColors=true +Setting=NormalContrast +Filter=None +MixerRed=33 +MixerOrange=33 +MixerYellow=33 +MixerGreen=33 +MixerCyan=33 +MixerBlue=33 +MixerMagenta=33 +MixerPurple=33 +GammaRed=0 +GammaGreen=0 +GammaBlue=0 +LuminanceCurve=0; +BeforeCurveMode=Standard +AfterCurveMode=Standard +BeforeCurve=0; +AfterCurve=0; + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=0 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +lhCurve=0; +hhCurve=0; +LcCurve=0; +ClCurve=0; + +[Vibrance] +Enabled=false +Pastels=50 +Saturated=50 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false +Degree=90 +AutoDegree=true +Surround=Average +AdaptLum=16 +Badpixsl=0 +Model=RawT +Algorithm=JC +J-Light=0 +Q-Bright=0 +C-Chroma=0 +S-Chroma=0 +M-Chroma=0 +J-Contrast=0 +Q-Contrast=0 +H-Hue=0 +RSTProtection=0 +AdaptScene=2000 +AutoAdapscen=true +SurrSource=false +Gamut=true +Datacie=false +Tonecie=false +CurveMode=Lightness +CurveMode2=Lightness +CurveMode3=Chroma +Curve=0; +Curve2=0; +Curve3=0; + +[Directional Pyramid Denoising] +Enabled=true +Enhance=false +Luma=0 +Ldetail=0 +Chroma=15 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.4 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=10 +HighlightTonalWidth=80 +Shadows=10 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=30 + +[Gradient] +Enabled=false +Degree=0 +Feather=25 +Strength=0.6 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0.6 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Skintones/Skintones - Soft Texture.pp3 b/rtdata/profiles/Skintones/Skintones - Soft Texture.pp3 new file mode 100644 index 000000000..26815da33 --- /dev/null +++ b/rtdata/profiles/Skintones/Skintones - Soft Texture.pp3 @@ -0,0 +1,173 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Compensation=0 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=0 +HighlightComprThreshold=33 +ShadowCompr=50 +CurveMode=Standard +CurveMode2=Standard +Curve=0; +Curve2=0; + +[HLRecovery] +Enabled=false +Method=Blend + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Black & White] +Enabled=false +Method=Desaturation +Auto=false +ComplementaryColors=true +Setting=NormalContrast +Filter=None +MixerRed=33 +MixerOrange=33 +MixerYellow=33 +MixerGreen=33 +MixerCyan=33 +MixerBlue=33 +MixerMagenta=33 +MixerPurple=33 +GammaRed=0 +GammaGreen=0 +GammaBlue=0 +LuminanceCurve=0; +BeforeCurveMode=Standard +AfterCurveMode=Standard +BeforeCurve=0; +AfterCurve=0; + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=0 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +lhCurve=0; +hhCurve=0; +LcCurve=0; +ClCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false +Degree=90 +AutoDegree=true +Surround=Average +AdaptLum=16 +Badpixsl=0 +Model=RawT +Algorithm=No +J-Light=0 +Q-Bright=0 +C-Chroma=0 +S-Chroma=0 +M-Chroma=0 +J-Contrast=0 +Q-Contrast=0 +H-Hue=0 +RSTProtection=0 +AdaptScene=2000 +AutoAdapscen=true +SurrSource=false +Gamut=true +Datacie=false +Tonecie=false +CurveMode=Lightness +CurveMode2=Lightness +CurveMode3=Chroma +Curve=0; +Curve2=0; +Curve3=0; + +[Directional Pyramid Denoising] +Enabled=false +Enhance=false +Luma=0 +Ldetail=0 +Chroma=15 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.4 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=0 +HighlightTonalWidth=80 +Shadows=0 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=40 + +[Gradient] +Enabled=false +Degree=0 +Feather=25 +Strength=0.6 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0.6 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=true +rCurve=3;0;0;0.058419243986254393;0.28522336769759427;0.46735395189003465;0.890034364261168;1;1; +gCurve=3;0;0;0.96563573883161546;0.66323024054982871;1;1; +bCurve=0; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Skintones/Skintones - Strong Texture.pp3 b/rtdata/profiles/Skintones/Skintones - Strong Texture.pp3 new file mode 100644 index 000000000..691cc118d --- /dev/null +++ b/rtdata/profiles/Skintones/Skintones - Strong Texture.pp3 @@ -0,0 +1,173 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Compensation=0 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=0 +HighlightComprThreshold=33 +ShadowCompr=50 +CurveMode=Standard +CurveMode2=Standard +Curve=0; +Curve2=0; + +[HLRecovery] +Enabled=false +Method=Blend + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Black & White] +Enabled=false +Method=Desaturation +Auto=false +ComplementaryColors=true +Setting=NormalContrast +Filter=None +MixerRed=33 +MixerOrange=33 +MixerYellow=33 +MixerGreen=33 +MixerCyan=33 +MixerBlue=33 +MixerMagenta=33 +MixerPurple=33 +GammaRed=0 +GammaGreen=0 +GammaBlue=0 +LuminanceCurve=0; +BeforeCurveMode=Standard +AfterCurveMode=Standard +BeforeCurve=0; +AfterCurve=0; + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=0 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +lhCurve=0; +hhCurve=0; +LcCurve=0; +ClCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=false +Degree=90 +AutoDegree=true +Surround=Average +AdaptLum=16 +Badpixsl=0 +Model=RawT +Algorithm=No +J-Light=0 +Q-Bright=0 +C-Chroma=0 +S-Chroma=0 +M-Chroma=0 +J-Contrast=0 +Q-Contrast=0 +H-Hue=0 +RSTProtection=0 +AdaptScene=2000 +AutoAdapscen=true +SurrSource=false +Gamut=true +Datacie=false +Tonecie=false +CurveMode=Lightness +CurveMode2=Lightness +CurveMode3=Chroma +Curve=0; +Curve2=0; +Curve3=0; + +[Directional Pyramid Denoising] +Enabled=false +Enhance=false +Luma=0 +Ldetail=0 +Chroma=15 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.25 +EdgeStopping=1.4 +Scale=1 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=0 +HighlightTonalWidth=80 +Shadows=0 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=40 + +[Gradient] +Enabled=false +Degree=0 +Feather=25 +Strength=0.6 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0.6 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=true +rCurve=3;0;0;0.29209621993127149;0.054982817869415793;0.90034364261168398;0.46391752577319617;1;1; +gCurve=3;0;0;0.67697594501718261;0.95532646048109982;1;1; +bCurve=0; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Skintones/Skintones - Studio TM.pp3 b/rtdata/profiles/Skintones/Skintones - Studio TM.pp3 new file mode 100644 index 000000000..944670a23 --- /dev/null +++ b/rtdata/profiles/Skintones/Skintones - Studio TM.pp3 @@ -0,0 +1,173 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Compensation=0 +Brightness=0 +Contrast=0 +Saturation=0 +Black=-1500 +HighlightCompr=40 +HighlightComprThreshold=0 +ShadowCompr=0 +CurveMode=WeightedStd +CurveMode2=SatAndValueBlending +Curve=3;0;0;0.083003952569169939;0.21343873517786566;1;1; +Curve2=3;0;0;0.063063463161166899;0.13925774599931898;0.86956521739130421;0.76284584980237158;1;1; + +[HLRecovery] +Enabled=true +Method=Blend + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Black & White] +Enabled=false +Method=Desaturation +Auto=false +ComplementaryColors=true +Setting=NormalContrast +Filter=None +MixerRed=33 +MixerOrange=33 +MixerYellow=33 +MixerGreen=33 +MixerCyan=33 +MixerBlue=33 +MixerMagenta=33 +MixerPurple=33 +GammaRed=0 +GammaGreen=0 +GammaBlue=0 +LuminanceCurve=0; +BeforeCurveMode=Standard +AfterCurveMode=Standard +BeforeCurve=0; +AfterCurve=0; + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=0 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=3;0;0;0.15019762845849804;0.02766798418972332;0.31620553359683784;0.23715415019762845;0.49407114624505927;0.50197628458498023;0.92885375494071132;0.99604743083003922;1;1; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +lhCurve=0; +hhCurve=0; +LcCurve=0; +ClCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=true +Degree=100 +AutoDegree=true +Surround=Average +AdaptLum=16 +Badpixsl=0 +Model=RawT +Algorithm=QM +J-Light=0 +Q-Bright=10 +C-Chroma=0 +S-Chroma=0 +M-Chroma=0 +J-Contrast=0 +Q-Contrast=0 +H-Hue=0 +RSTProtection=0 +AdaptScene=2000 +AutoAdapscen=true +SurrSource=false +Gamut=true +Datacie=false +Tonecie=true +CurveMode=Lightness +CurveMode2=Lightness +CurveMode3=Chroma +Curve=3;0;0;0.06584362139917696;0.01234567901234568;0.24279835390946511;0.12757201646090524;0.46502057613168757;0.49324520929459226;0.67901234567901192;0.84773662551440199;1;1; +Curve2=0; +Curve3=1;0;0;0.86008230452674928;1; + +[Directional Pyramid Denoising] +Enabled=true +Enhance=false +Luma=0 +Ldetail=0 +Chroma=15 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=true +Strength=0.15 +EdgeStopping=1.4 +Scale=0.25 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=10 +HighlightTonalWidth=80 +Shadows=10 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=30 + +[Gradient] +Enabled=false +Degree=0 +Feather=25 +Strength=0.6 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0.6 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Skintones/Skintones - Studio.pp3 b/rtdata/profiles/Skintones/Skintones - Studio.pp3 new file mode 100644 index 000000000..d58c7be11 --- /dev/null +++ b/rtdata/profiles/Skintones/Skintones - Studio.pp3 @@ -0,0 +1,173 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Compensation=0 +Brightness=0 +Contrast=0 +Saturation=0 +Black=-1500 +HighlightCompr=30 +HighlightComprThreshold=0 +ShadowCompr=0 +CurveMode=WeightedStd +CurveMode2=SatAndValueBlending +Curve=3;0;0;0.083003952569169939;0.21343873517786566;1;1; +Curve2=3;0;0;0.063063463161166899;0.13925774599931898;0.86956521739130421;0.76284584980237158;1;1; + +[HLRecovery] +Enabled=true +Method=Blend + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Black & White] +Enabled=false +Method=Desaturation +Auto=false +ComplementaryColors=true +Setting=NormalContrast +Filter=None +MixerRed=33 +MixerOrange=33 +MixerYellow=33 +MixerGreen=33 +MixerCyan=33 +MixerBlue=33 +MixerMagenta=33 +MixerPurple=33 +GammaRed=0 +GammaGreen=0 +GammaBlue=0 +LuminanceCurve=0; +BeforeCurveMode=Standard +AfterCurveMode=Standard +BeforeCurve=0; +AfterCurve=0; + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=0 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=3;0;0;0.15019762845849804;0.02766798418972332;0.31620553359683784;0.23715415019762845;0.49407114624505927;0.50197628458498023;0.92885375494071132;0.99604743083003922;1;1; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +lhCurve=0; +hhCurve=0; +LcCurve=0; +ClCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=true +Degree=100 +AutoDegree=true +Surround=Average +AdaptLum=16 +Badpixsl=0 +Model=RawT +Algorithm=QM +J-Light=0 +Q-Bright=10 +C-Chroma=0 +S-Chroma=0 +M-Chroma=0 +J-Contrast=0 +Q-Contrast=0 +H-Hue=0 +RSTProtection=0 +AdaptScene=2000 +AutoAdapscen=true +SurrSource=false +Gamut=true +Datacie=false +Tonecie=true +CurveMode=Lightness +CurveMode2=Lightness +CurveMode3=Chroma +Curve=3;0;0;0.06584362139917696;0.01234567901234568;0.24279835390946511;0.12757201646090524;0.46502057613168757;0.49324520929459226;0.67901234567901192;0.84773662551440199;1;1; +Curve2=0; +Curve3=1;0;0;0.90534979423868323;1; + +[Directional Pyramid Denoising] +Enabled=true +Enhance=false +Luma=0 +Ldetail=0 +Chroma=15 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.15 +EdgeStopping=1.4 +Scale=0.25 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=0 +HighlightTonalWidth=80 +Shadows=0 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=40 + +[Gradient] +Enabled=false +Degree=0 +Feather=25 +Strength=0.6 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0.6 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Skintones/Skintones - StudioBase 1 TM.pp3 b/rtdata/profiles/Skintones/Skintones - StudioBase 1 TM.pp3 new file mode 100644 index 000000000..227cf09f9 --- /dev/null +++ b/rtdata/profiles/Skintones/Skintones - StudioBase 1 TM.pp3 @@ -0,0 +1,173 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Compensation=0 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=30 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=WeightedStd +CurveMode2=SatAndValueBlending +Curve=3;0;0;1;1; +Curve2=3;0;0;1;1; + +[HLRecovery] +Enabled=true +Method=Blend + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Black & White] +Enabled=false +Method=Desaturation +Auto=false +ComplementaryColors=true +Setting=NormalContrast +Filter=None +MixerRed=33 +MixerOrange=33 +MixerYellow=33 +MixerGreen=33 +MixerCyan=33 +MixerBlue=33 +MixerMagenta=33 +MixerPurple=33 +GammaRed=0 +GammaGreen=0 +GammaBlue=0 +LuminanceCurve=0; +BeforeCurveMode=Standard +AfterCurveMode=Standard +BeforeCurve=0; +AfterCurve=0; + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=0 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +lhCurve=0; +hhCurve=0; +LcCurve=0; +ClCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=true +Degree=100 +AutoDegree=true +Surround=Average +AdaptLum=16 +Badpixsl=0 +Model=RawT +Algorithm=QM +J-Light=0 +Q-Bright=0 +C-Chroma=0 +S-Chroma=0 +M-Chroma=0 +J-Contrast=0 +Q-Contrast=0 +H-Hue=0 +RSTProtection=0 +AdaptScene=2000 +AutoAdapscen=true +SurrSource=false +Gamut=true +Datacie=false +Tonecie=true +CurveMode=Lightness +CurveMode2=Lightness +CurveMode3=Chroma +Curve=3;0;0;0.11522633744855965;0.01234567901234568;0.49382716049382719;0.49382716049382719;0.76131687242798285;0.95473251028806605;1;1; +Curve2=0; +Curve3=1;0;0;1;1; + +[Directional Pyramid Denoising] +Enabled=true +Enhance=false +Luma=0 +Ldetail=0 +Chroma=15 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=true +Strength=0.15 +EdgeStopping=1.4 +Scale=0.25 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=0 +HighlightTonalWidth=80 +Shadows=0 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=40 + +[Gradient] +Enabled=false +Degree=0 +Feather=25 +Strength=0.6 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0.6 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + +[ColorToning] +Enabled=false + diff --git a/rtdata/profiles/Skintones/Skintones - StudioBase 1.pp3 b/rtdata/profiles/Skintones/Skintones - StudioBase 1.pp3 new file mode 100644 index 000000000..e0d38aefc --- /dev/null +++ b/rtdata/profiles/Skintones/Skintones - StudioBase 1.pp3 @@ -0,0 +1,173 @@ +[Version] +AppVersion=4.2.84 +Version=322 + +[Exposure] +Auto=false +Clip=0.02 +Compensation=0 +Brightness=0 +Contrast=0 +Saturation=0 +Black=0 +HighlightCompr=20 +HighlightComprThreshold=0 +ShadowCompr=50 +CurveMode=WeightedStd +CurveMode2=SatAndValueBlending +Curve=3;0;0;1;1; +Curve2=3;0;0;1;1; + +[HLRecovery] +Enabled=true +Method=Blend + +[Channel Mixer] +Red=100;0;0; +Green=0;100;0; +Blue=0;0;100; + +[Black & White] +Enabled=false +Method=Desaturation +Auto=false +ComplementaryColors=true +Setting=NormalContrast +Filter=None +MixerRed=33 +MixerOrange=33 +MixerYellow=33 +MixerGreen=33 +MixerCyan=33 +MixerBlue=33 +MixerMagenta=33 +MixerPurple=33 +GammaRed=0 +GammaGreen=0 +GammaBlue=0 +LuminanceCurve=0; +BeforeCurveMode=Standard +AfterCurveMode=Standard +BeforeCurve=0; +AfterCurve=0; + +[Luminance Curve] +Brightness=0 +Contrast=0 +Chromaticity=0 +AvoidColorShift=false +RedAndSkinTonesProtection=0 +LCredsk=true +LCurve=0; +aCurve=0; +bCurve=0; +ccCurve=0; +chCurve=0; +lhCurve=0; +hhCurve=0; +LcCurve=0; +ClCurve=0; + +[Vibrance] +Enabled=false +Pastels=0 +Saturated=0 +PSThreshold=0;75; +ProtectSkins=false +AvoidColorShift=false +PastSatTog=true +SkinTonesCurve=0; + +[Color appearance] +Enabled=true +Degree=100 +AutoDegree=true +Surround=Average +AdaptLum=16 +Badpixsl=0 +Model=RawT +Algorithm=QM +J-Light=0 +Q-Bright=0 +C-Chroma=0 +S-Chroma=0 +M-Chroma=0 +J-Contrast=0 +Q-Contrast=0 +H-Hue=0 +RSTProtection=0 +AdaptScene=2000 +AutoAdapscen=true +SurrSource=false +Gamut=true +Datacie=false +Tonecie=true +CurveMode=Lightness +CurveMode2=Lightness +CurveMode3=Chroma +Curve=3;0;0;0.10699588477366252;0.049382716049382713;0.49382716049382719;0.49382716049382719;0.76131687242798285;0.95473251028806605;1;1; +Curve2=0; +Curve3=1;0;0;1;1; + +[Directional Pyramid Denoising] +Enabled=true +Enhance=false +Luma=0 +Ldetail=0 +Chroma=15 +Method=Lab +Redchro=0 +Bluechro=0 +Gamma=1.7 + +[EPD] +Enabled=false +Strength=0.15 +EdgeStopping=1.4 +Scale=0.25 +ReweightingIterates=0 + +[Shadows & Highlights] +Enabled=false +HighQuality=false +Highlights=0 +HighlightTonalWidth=80 +Shadows=0 +ShadowTonalWidth=80 +LocalContrast=0 +Radius=40 + +[Gradient] +Enabled=false +Degree=0 +Feather=25 +Strength=0.6 +CenterX=0 +CenterY=0 + +[PCVignette] +Enabled=false +Strength=0.6 +Feather=50 +Roundness=50 + +[HSV Equalizer] +HCurve=0; +SCurve=0; +VCurve=0; + +[Film Simulation] +Enabled=false + +[Wavelet] +Enabled=false + +[RGB Curves] +LumaMode=false +rCurve=0; +gCurve=0; +bCurve=0; + +[ColorToning] +Enabled=false + diff --git a/rtdata/sounds/BatchComplete.wav b/rtdata/sounds/BatchComplete.wav new file mode 100644 index 000000000..9c09e2b39 Binary files /dev/null and b/rtdata/sounds/BatchComplete.wav differ diff --git a/rtdata/sounds/Empty.wav b/rtdata/sounds/Empty.wav new file mode 100644 index 000000000..3f102bff1 Binary files /dev/null and b/rtdata/sounds/Empty.wav differ diff --git a/rtdata/sounds/ProcessComplete.wav b/rtdata/sounds/ProcessComplete.wav new file mode 100644 index 000000000..a82b97c34 Binary files /dev/null and b/rtdata/sounds/ProcessComplete.wav differ diff --git a/rtdata/themes/09-Gray-Orange.gtkrc b/rtdata/themes/09-Gray-Orange.gtkrc new file mode 100644 index 000000000..080185d92 --- /dev/null +++ b/rtdata/themes/09-Gray-Orange.gtkrc @@ -0,0 +1,557 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2011 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 . +# + +# Please keep this gtkrc in sync with the other ones from Clearlooks based themes. + +gtk-color-scheme = "rt_salt_pinch:#C05F00\nrt_base_color:#0A0A0A\nrt_fg_color:#757575\nrt_tooltip_fg_color:#D2D2D2\nrt_selected_bg_color:#804d1d\nrt_selected_fg_color:#D0D0D0\nrt_text_color:#757575\nrt_bg_color:#181818\nrt_tooltip_bg_color:#5A5A5A\nrt_tool_bg:#212121\nrt_tool_border:#121212" + +style "clearlooks-default" { + xthickness = 1 + ythickness = 1 + + ####################### + # Style Properties + ####################### + GtkButton::child-displacement-x = 1 + GtkButton::child-displacement-y = 1 + GtkButton::default-border = { 0, 0, 0, 0 } + GtkButton::image-spacing = 4 + GtkToolButton::icon-spacing = 4 + + GtkCheckButton::indicator-size = 14 + + GtkPaned::handle-size = 6 + + GtkRange::trough-border = 0 + GtkRange::slider-width = 15 + GtkRange::stepper-size = 15 + + GtkScale::slider-width = 14 + GtkScale::slider-length = 30 + GtkScale::trough-side-details = 0 + + GtkScrollbar::min-slider-length = 30 + GtkMenuBar::internal-padding = 0 + GtkExpander::expander-size = 12 + GtkExpander::expander-spacing = 2 + GtkToolbar::internal-padding = 1 + GtkTreeView::expander-size = 12 + GtkTreeView::vertical-separator = 0 + + GtkMenu::horizontal-padding = 0 + GtkMenu::vertical-padding = 0 + + WnckTasklist::fade-overlay-rect = 0 + # The following line hints to gecko (and possibly other appliations) + # that the entry should be drawn transparently on the canvas. + # Without this, gecko will fill in the background of the entry. + GtkEntry::honors-transparent-bg-hint = 1 + + GtkEntry::progress-border = { 2, 2, 2, 2 } + + #################### + # Color Definitions + #################### + bg[NORMAL] = @rt_bg_color + bg[PRELIGHT] = shade (1.02, @rt_bg_color) + bg[SELECTED] = @rt_selected_bg_color + bg[INSENSITIVE] = @rt_bg_color + bg[ACTIVE] = shade (0.9, @rt_bg_color) + + fg[NORMAL] = @rt_fg_color + fg[PRELIGHT] = @rt_fg_color + fg[SELECTED] = @rt_selected_fg_color + fg[INSENSITIVE] = mix (0.2, @rt_fg_color, @rt_bg_color) + fg[ACTIVE] = @rt_fg_color + + text[NORMAL] = @rt_text_color + text[PRELIGHT] = @rt_text_color + text[SELECTED] = @rt_selected_fg_color + text[INSENSITIVE] = darker (@rt_bg_color) + text[ACTIVE] = @rt_selected_fg_color + + base[NORMAL] = @rt_base_color + base[PRELIGHT] = shade (0.95, @rt_bg_color) + base[SELECTED] = @rt_selected_bg_color + base[INSENSITIVE] = @rt_bg_color + base[ACTIVE] = shade (0.9, @rt_selected_bg_color) + + engine "clearlooks" { + colorize_scrollbar = TRUE + reliefstyle = 1 + menubarstyle = 2 + toolbarstyle = 1 + animation = FALSE + radius = 3.0 + # style between CLASSIC, GLOSSY, INVERTED and GUMMY + style = GUMMY + + # Set a hint to disable backward compatibility fallbacks. + hint = "use-hints" + } +} + +style "wide" { + xthickness = 2 + ythickness = 2 +} + +style "wider" { + xthickness = 3 + ythickness = 3 +} + +style "clearlooks-entry" { + xthickness = 3 + ythickness = 3 + + bg[SELECTED] = mix (1.4, @rt_selected_bg_color, @rt_base_color) + fg[SELECTED] = @rt_selected_fg_color + + engine "clearlooks" { + focus_color = shade (0.65, @rt_selected_bg_color) + } +} + +style "clearlooks-paned" { + + bg[PRELIGHT] = shade (0.8, @rt_bg_color) + + engine "clearlooks" { + hint = "paned" + } +} + +style "clearlooks-HSV" { + + engine "clearlooks" { + hint = "HSV" + disable_focus = TRUE + } +} + +style "clearlooks-spinbutton" { + + engine "clearlooks" { + hint = "spinbutton" + } +} + +style "clearlooks-axisadjuster" = "clearlooks-spinbutton" { + # background + base[INSENSITIVE] = @rt_tool_bg + # text + text[INSENSITIVE] = @rt_fg_color +} + +style "clearlooks-framelessspinbutton" { + + # IMPORTANT! + # base[NORMAL] must have the same color than clearlooks.toolContainer / bg[NORMAL] + base[NORMAL] = @rt_tool_bg + base[INSENSITIVE] = @rt_tool_bg + bg[NORMAL] = @rt_tool_bg + bg[INSENSITIVE] = @rt_tool_bg +} + +style "clearlooks-scale" { + xthickness = 2 + ythickness = 2 + + bg[NORMAL] = shade (2.20, @rt_bg_color) + bg[PRELIGHT] = shade (3.00, @rt_bg_color) + # when GtkScale::trough-side-details = 1, bg[SELECTED] set the color of the slider background on the left of the knob + #bg[SELECTED] = @rt_bg_color + + engine "clearlooks" { + focus_color = @rt_selected_bg_color + hint = "scale" + } +} + +style "clearlooks-thresholdselector" { + xthickness = 6 + ythickness = 6 + + bg[NORMAL] = @rt_tool_bg + bg[ACTIVE] = shade (2.25, @rt_bg_color) + bg[PRELIGHT] = shade (3.00, @rt_bg_color) + bg[SELECTED] = shade (4.00, @rt_bg_color) + + fg[PRELIGHT] = shade (2.00, @rt_fg_color) +} + +style "clearlooks-vscale" { + + engine "clearlooks" { + hint = "vscale" + } +} + +style "clearlooks-hscale" { + + engine "clearlooks" { + hint = "hscale" + } +} + +style "clearlooks-scrollbar" { + xthickness = 2 + ythickness = 2 + + bg[SELECTED] = shade (1.50, @rt_bg_color) + + engine "clearlooks" { + hint = "scrollbar" + } +} + +style "clearlooks-hscrollbar" { + + engine "clearlooks" { + hint = "hscrollbar" + } +} + +style "clearlooks-vscrollbar" { + + engine "clearlooks" { + hint = "vscrollbar" + } +} + +style "clearlooks-notebook_bg" { + + bg[NORMAL] = shade (1.02, @rt_bg_color) + bg[ACTIVE] = @rt_base_color +} + +style "clearlooks-toolContainer" { + xthickness = 0 + ythickness = 0 + + # IMPORTANT! + # If you modify bg[NORMAL] below, you must set clearlooks-framelessspinbutton -> base[NORMAL] to the very same value + bg[NORMAL] = @rt_tool_bg + bg[INSENSITIVE] = @rt_tool_bg +} + +style "clearlooks-separator" { + bg[NORMAL] = mix(0.85, @rt_tool_bg, @rt_tool_border) + bg[INSENSITIVE] = mix(0.60, @rt_tool_bg, @rt_tool_border) +} + +style "clearlooks-frame" { + bg[NORMAL] = mix(0.95, @rt_tool_bg, @rt_tool_border) + bg[INSENSITIVE] = mix(0.60, @rt_tool_bg, @rt_tool_border) +} + +style "clearlooks-toolFrame" = "clearlooks-toolContainer" { + bg[NORMAL] = @rt_tool_bg + + fg[NORMAL] = @rt_tool_border + fg[INSENSITIVE] = mix(0.5, @rt_bg_color, @rt_tool_border) +} + +style "clearlooks-toolExpanderBox" { + bg[NORMAL] = @rt_tool_bg + bg[INSENSITIVE] = @rt_tool_bg +} + +style "clearlooks-combobox" { + + text[NORMAL] = @rt_fg_color + text[PRELIGHT] = shade(1.15, @rt_fg_color) + text[SELECTED] = @rt_selected_fg_color + text[INSENSITIVE] = mix (0.2, @rt_fg_color, @rt_bg_color) + text[ACTIVE] = @rt_fg_color +} + +style "clearlooks-button" { + + bg[NORMAL] = shade (1.80, @rt_bg_color) + bg[PRELIGHT] = shade (2.20, @rt_bg_color) + bg[ACTIVE] = shade (3.00, @rt_bg_color) + + fg[NORMAL] = @rt_fg_color + fg[PRELIGHT] = shade(1.15, @rt_fg_color) + fg[SELECTED] = @rt_selected_fg_color + fg[INSENSITIVE] = mix (0.2, @rt_fg_color, @rt_bg_color) + fg[ACTIVE] = @rt_fg_color + + engine "clearlooks" + { + hint = "button" + } +} + +style "clearlooks-histButton" { + + GtkButton::child-displacement-x = 0 + GtkButton::child-displacement-y = 0 +} + +# The color is changed by the notebook_bg style, this style +# changes the x/ythickness +style "clearlooks-notebook" { + xthickness = 3 + ythickness = 3 + + bg[SELECTED] = @rt_salt_pinch +} + +style "clearlooks-statusbar" { + + engine "clearlooks" { + hint = "statusbar" + } +} + +style "clearlooks-comboboxentry" { + + engine "clearlooks" { + # Note: + # If you set the appears-as-list option on comboboxes in the theme, + # then you should set this hint on the combobox instead. + hint = "comboboxentry" + } +} + +style "clearlooks-expander" { + xthickness = 3 + ythickness = 3 + + fg[NORMAL] = "#8C8C8C" + fg[PRELIGHT] = "#B8B8B8" + fg[INSENSITIVE] = "#505050" + + bg[PRELIGHT] = mix(0.5, @rt_selected_bg_color, @rt_bg_color) + + base[NORMAL] = @rt_salt_pinch + base[PRELIGHT] = @rt_salt_pinch + base[INSENSITIVE] = @rt_salt_pinch +} + +style "clearlooks-subexpander" = "clearlooks-expander"{ + bg[NORMAL] = @rt_tool_bg +} + +style "clearlooks-menubar" { + + engine "clearlooks" { + hint = "menubar" + } +} + +style "clearlooks-menu" { + xthickness = 0 + ythickness = 0 + + bg[NORMAL] = shade (0.70, @rt_bg_color) + + engine "clearlooks" { + radius = 0.0 + } +} + +style "clearlooks-menu_item" { + xthickness = 2 + ythickness = 3 + + fg[PRELIGHT] = @rt_selected_fg_color + text[NORMAL] = @rt_fg_color + text[PRELIGHT] = @rt_selected_fg_color +} + +# This style is there to modify the separator menu items. The goals are: +# 1. Get a specific height. +# 2. The line should go to the edges (ie. no border at the left/right) +style "clearlooks-separator_menu_item" { + xthickness = 1 + ythickness = 0 + + GtkSeparatorMenuItem::horizontal-padding = 0 + GtkWidget::wide-separators = 1 + GtkWidget::separator-width = 1 + GtkWidget::separator-height = 7 +} + +style "clearlooks-frame_title" { + + fg[NORMAL] = shade (1.50, @rt_text_color) + fg[PRELIGHT] = shade (1.50, @rt_text_color) + fg[ACTIVE] = shade (1.50, @rt_text_color) + fg[SELECTED] = shade (1.50, @rt_text_color) +} + +style "clearlooks-partialPasteHeaderSep" { + + bg[NORMAL] = mix (0.25, @rt_fg_color, @rt_bg_color) +} + +style "clearlooks-checkbutton" { + + text[NORMAL] = @rt_salt_pinch + + fg[PRELIGHT] = @rt_fg_color + + bg[SELECTED] = @rt_base_color + bg[PRELIGHT] = @rt_base_color + bg[SELECTED] = @rt_base_color + + engine "clearlooks" + { + hint = "checkbutton" + } +} + +style "clearlooks-treeview" { + + base[ACTIVE] = mix(0.50, @rt_selected_bg_color, @rt_base_color) + + engine "clearlooks" { + hint = "treeview" + } +} + +# The almost useless progress bar style +style "clearlooks-progressbar" { + xthickness = 1 + ythickness = 1 + + fg[PRELIGHT] = @rt_selected_fg_color + + engine "clearlooks" { + # Explicitly set the radius for the progress bars inside menu items. + radius = 3.0 + + hint = "progressbar" + } +} + +# This style is based on the clearlooks-default style, so that the colors from the button +# style are overriden again. +style "clearlooks-treeview_header" = "clearlooks-default" { + xthickness = 2 + ythickness = 1 + + bg[NORMAL] = shade (1.35, @rt_bg_color) + + engine "clearlooks" { + radius = 0.0 + hint = "treeview-header" + } +} + +style "clearlooks-tooltips" { + xthickness = 4 + ythickness = 4 + + bg[NORMAL] = @rt_tooltip_bg_color + fg[NORMAL] = @rt_tooltip_fg_color +} + +############################################################################### +# The following part of the gtkrc applies the different styles to the widgets. +############################################################################### + +# The clearlooks-default style is applied to every widget +class "GtkWidget" style "clearlooks-default" + +class "GtkSeparator" style "wide" +class "GtkFrame" style "wide" +class "GtkCalendar" style "wide" +class "GtkCheckButton" style "wider" +class "GtkRadioButton" style "wider" +class "GtkEntry" style "clearlooks-entry" + +class "GtkPaned" style "clearlooks-paned" +class "GtkSpinButton" style "clearlooks-spinbutton" +class "GtkScale" style "clearlooks-scale" +class "GtkVScale" style "clearlooks-vscale" +class "GtkHScale" style "clearlooks-hscale" +class "GtkScrollbar" style "clearlooks-scrollbar" +class "GtkHScrollbar" style "clearlooks-hscrollbar" +class "GtkVScrollbar" style "clearlooks-vscrollbar" + +class "GtkHSV" style "clearlooks-HSV" + +# General matching follows. The order is choosen so that the right styles override +# each other. EG. progressbar needs to be more important than the menu match. +widget_class "*" style "clearlooks-notebook_bg" +# This is not perfect, it could be done better. +# (That is modify *every* widget in the notebook, and change those back that +# we really don't want changed) +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" + +widget_class "*." style "clearlooks-combobox" +widget_class "**" style "clearlooks-button" +widget_class "*" style "clearlooks-notebook" +widget_class "**" style "clearlooks-statusbar" + +#widget_class "**" style "clearlooks-comboboxentry" +widget_class "**" style "clearlooks-combobox" + +widget_class "**" style "clearlooks-checkbutton" +widget_class "**" style "clearlooks-menubar" +widget_class "**" style "clearlooks-menu" +widget_class "**" style "clearlooks-menu_item" +widget_class "**" style "clearlooks-separator_menu_item" + +widget_class "*." style "clearlooks-frame" +widget_class "*.." style "clearlooks-frame_title" +widget_class "*.*" style "clearlooks-treeview" + +widget_class "*" style "clearlooks-progressbar" + +# Treeview headers (and similar stock GTK+ widgets) +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*...*." style "clearlooks-separator" +widget_class "*...*." style "clearlooks-toolExpanderBox" + +widget "*.partialPasteHeader.*" style "clearlooks-frame_title" +widget "*.partialPasteHeaderSep" style "clearlooks-partialPasteHeaderSep" +widget "*.histButton" style "clearlooks-histButton" +widget "*.FramelessSpinButton" style "clearlooks-framelessspinbutton" +widget "*.ThresholdSelector" style "clearlooks-thresholdselector" +widget "*.MyExpanderTitle.*" style "clearlooks-expander" +widget "*.MyExpanderTitle" style "clearlooks-expander" +widget "*.ExpanderBox" style "clearlooks-toolFrame" +widget "*.ExpanderBox.*.MyExpanderTitle" style "clearlooks-subexpander" +widget "*.ExpanderBox.*.MyExpanderTitle.*" style "clearlooks-subexpander" +widget "*.AxisAdjuster" style "clearlooks-axisadjuster" + +# The window of the tooltip is called "gtk-tooltip" +################################################################## +# FIXME: +# This will not work if one embeds eg. a button into the tooltip. +# As far as I can tell right now we will need to rework the theme +# quite a bit to get this working correctly. +# (It will involve setting different priorities, etc.) +################################################################## +widget "gtk-tooltip*" style "clearlooks-tooltips" + +gtk-icon-theme-name="Dark" diff --git a/rtdata/themes/09-Gray-Orange.iconset b/rtdata/themes/09-Gray-Orange.iconset new file mode 100644 index 000000000..99ac20640 --- /dev/null +++ b/rtdata/themes/09-Gray-Orange.iconset @@ -0,0 +1,2 @@ +[General] +Iconset=Dark diff --git a/rtdata/themes/17-Gray-Red.gtkrc b/rtdata/themes/17-Gray-Red.gtkrc new file mode 100644 index 000000000..03fd95b96 --- /dev/null +++ b/rtdata/themes/17-Gray-Red.gtkrc @@ -0,0 +1,557 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2011 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 . +# + +# Please keep this gtkrc in sync with the other ones from Clearlooks based themes. + +gtk-color-scheme = "rt_salt_pinch:#800000\nrt_base_color:#404040\nrt_fg_color:#808080\nrt_tooltip_fg_color:#D2D2D2\nrt_selected_bg_color:#502828\nrt_selected_fg_color:#D0D0D0\nrt_text_color:#A0A0A0\nrt_bg_color:#2B2B2B\nrt_tooltip_bg_color:#5A5A5A\nrt_tool_bg:#333333\nrt_tool_border:#434343" + +style "clearlooks-default" { + xthickness = 1 + ythickness = 1 + + ####################### + # Style Properties + ####################### + GtkButton::child-displacement-x = 1 + GtkButton::child-displacement-y = 1 + GtkButton::default-border = { 0, 0, 0, 0 } + GtkButton::image-spacing = 4 + GtkToolButton::icon-spacing = 4 + + GtkCheckButton::indicator-size = 14 + + GtkPaned::handle-size = 6 + + GtkRange::trough-border = 0 + GtkRange::slider-width = 15 + GtkRange::stepper-size = 15 + + GtkScale::slider-width = 14 + GtkScale::slider-length = 30 + GtkScale::trough-side-details = 0 + + GtkScrollbar::min-slider-length = 30 + GtkMenuBar::internal-padding = 0 + GtkExpander::expander-size = 12 + GtkExpander::expander-spacing = 2 + GtkToolbar::internal-padding = 1 + GtkTreeView::expander-size = 12 + GtkTreeView::vertical-separator = 0 + + GtkMenu::horizontal-padding = 0 + GtkMenu::vertical-padding = 0 + + WnckTasklist::fade-overlay-rect = 0 + # The following line hints to gecko (and possibly other appliations) + # that the entry should be drawn transparently on the canvas. + # Without this, gecko will fill in the background of the entry. + GtkEntry::honors-transparent-bg-hint = 1 + + GtkEntry::progress-border = { 2, 2, 2, 2 } + + #################### + # Color Definitions + #################### + bg[NORMAL] = @rt_bg_color + bg[PRELIGHT] = shade (1.02, @rt_bg_color) + bg[SELECTED] = @rt_selected_bg_color + bg[INSENSITIVE] = @rt_bg_color + bg[ACTIVE] = shade (0.9, @rt_bg_color) + + fg[NORMAL] = @rt_fg_color + fg[PRELIGHT] = @rt_fg_color + fg[SELECTED] = @rt_selected_fg_color + fg[INSENSITIVE] = mix (0.2, @rt_fg_color, @rt_bg_color) + fg[ACTIVE] = @rt_fg_color + + text[NORMAL] = @rt_text_color + text[PRELIGHT] = @rt_text_color + text[SELECTED] = @rt_selected_fg_color + text[INSENSITIVE] = darker (@rt_bg_color) + text[ACTIVE] = @rt_selected_fg_color + + base[NORMAL] = @rt_base_color + base[PRELIGHT] = shade (0.95, @rt_bg_color) + base[SELECTED] = @rt_selected_bg_color + base[INSENSITIVE] = @rt_bg_color + base[ACTIVE] = shade (0.9, @rt_selected_bg_color) + + engine "clearlooks" { + colorize_scrollbar = TRUE + reliefstyle = 1 + menubarstyle = 2 + toolbarstyle = 1 + animation = FALSE + radius = 3.0 + # style between CLASSIC, GLOSSY, INVERTED and GUMMY + style = GUMMY + + # Set a hint to disable backward compatibility fallbacks. + hint = "use-hints" + } +} + +style "wide" { + xthickness = 2 + ythickness = 2 +} + +style "wider" { + xthickness = 3 + ythickness = 3 +} + +style "clearlooks-entry" { + xthickness = 3 + ythickness = 3 + + bg[SELECTED] = mix (1.4, @rt_selected_bg_color, @rt_base_color) + fg[SELECTED] = @rt_selected_fg_color + + engine "clearlooks" { + focus_color = shade (0.65, @rt_selected_bg_color) + } +} + +style "clearlooks-paned" { + + bg[PRELIGHT] = shade (0.9, @rt_bg_color) + + engine "clearlooks" { + hint = "paned" + } +} + +style "clearlooks-HSV" { + + engine "clearlooks" { + hint = "HSV" + disable_focus = TRUE + } +} + +style "clearlooks-spinbutton" { + + engine "clearlooks" { + hint = "spinbutton" + } +} + +style "clearlooks-axisadjuster" = "clearlooks-spinbutton" { + # background + base[INSENSITIVE] = @rt_tool_bg + # text + text[INSENSITIVE] = @rt_fg_color +} + +style "clearlooks-framelessspinbutton" { + + # IMPORTANT! + # base[NORMAL] must have the same color than clearlooks.toolContainer / bg[NORMAL] + base[NORMAL] = @rt_tool_bg + base[INSENSITIVE] = @rt_tool_bg + bg[NORMAL] = @rt_tool_bg + bg[INSENSITIVE] = @rt_tool_bg +} + +style "clearlooks-scale" { + xthickness = 2 + ythickness = 2 + + bg[NORMAL] = shade (1.30, @rt_tool_bg) + bg[PRELIGHT] = shade (1.50, @rt_tool_bg) + # when GtkScale::trough-side-details = 1, bg[SELECTED] set the color of the slider background on the left of the knob + #bg[SELECTED] = @rt_bg_color + + engine "clearlooks" { + focus_color = @rt_selected_bg_color + hint = "scale" + } +} + +style "clearlooks-thresholdselector" { + xthickness = 6 + ythickness = 6 + + bg[NORMAL] = @rt_tool_bg + bg[ACTIVE] = shade (1.45, @rt_bg_color) + bg[PRELIGHT] = shade (1.75, @rt_bg_color) + bg[SELECTED] = shade (1.75, @rt_bg_color) + + fg[PRELIGHT] = shade (1.60, @rt_fg_color) +} + +style "clearlooks-vscale" { + + engine "clearlooks" { + hint = "vscale" + } +} + +style "clearlooks-hscale" { + + engine "clearlooks" { + hint = "hscale" + } +} + +style "clearlooks-scrollbar" { + xthickness = 2 + ythickness = 2 + + bg[SELECTED] = shade (1.25, @rt_bg_color) + + engine "clearlooks" { + hint = "scrollbar" + } +} + +style "clearlooks-hscrollbar" { + + engine "clearlooks" { + hint = "hscrollbar" + } +} + +style "clearlooks-vscrollbar" { + + engine "clearlooks" { + hint = "vscrollbar" + } +} + +style "clearlooks-notebook_bg" { + + bg[NORMAL] = shade (1.02, @rt_bg_color) + bg[ACTIVE] = shade (0.80, @rt_bg_color) +} + +style "clearlooks-toolContainer" { + xthickness = 0 + ythickness = 0 + + # IMPORTANT! + # If you modify bg[NORMAL] below, you must set clearlooks-framelessspinbutton -> base[NORMAL] to the very same value + bg[NORMAL] = @rt_tool_bg + bg[INSENSITIVE] = @rt_tool_bg +} + +style "clearlooks-separator" { + bg[NORMAL] = mix(0.85, @rt_tool_bg, @rt_tool_border) + bg[INSENSITIVE] = mix(0.60, @rt_tool_bg, @rt_tool_border) +} + +style "clearlooks-frame" { + bg[NORMAL] = mix(0.85, @rt_tool_bg, @rt_tool_border) + bg[INSENSITIVE] = mix(0.60, @rt_tool_bg, @rt_tool_border) +} + +style "clearlooks-toolFrame" = "clearlooks-toolContainer" { + bg[NORMAL] = @rt_tool_bg + + fg[NORMAL] = @rt_tool_border + fg[INSENSITIVE] = mix(0.5, @rt_bg_color, @rt_tool_border) +} + +style "clearlooks-toolExpanderBox" { + bg[NORMAL] = @rt_tool_bg + bg[INSENSITIVE] = @rt_tool_bg +} + +style "clearlooks-combobox" { + + text[NORMAL] = @rt_fg_color + text[PRELIGHT] = shade(1.15, @rt_fg_color) + text[SELECTED] = @rt_selected_fg_color + text[INSENSITIVE] = mix (0.2, @rt_fg_color, @rt_bg_color) + text[ACTIVE] = @rt_fg_color +} + +style "clearlooks-button" { + + bg[NORMAL] = shade (1.20, @rt_tool_bg) + bg[PRELIGHT] = shade (1.40, @rt_tool_bg) + bg[ACTIVE] = shade (1.65, @rt_tool_bg) + + fg[NORMAL] = @rt_fg_color + fg[PRELIGHT] = shade(1.15, @rt_fg_color) + fg[SELECTED] = @rt_selected_fg_color + fg[INSENSITIVE] = mix (0.2, @rt_fg_color, @rt_bg_color) + fg[ACTIVE] = @rt_fg_color + + engine "clearlooks" + { + hint = "button" + } +} + +style "clearlooks-histButton" { + + GtkButton::child-displacement-x = 0 + GtkButton::child-displacement-y = 0 +} + +# The color is changed by the notebook_bg style, this style +# changes the x/ythickness +style "clearlooks-notebook" { + xthickness = 3 + ythickness = 3 + + bg[SELECTED] = @rt_salt_pinch +} + +style "clearlooks-statusbar" { + + engine "clearlooks" { + hint = "statusbar" + } +} + +style "clearlooks-comboboxentry" { + + engine "clearlooks" { + # Note: + # If you set the appears-as-list option on comboboxes in the theme, + # then you should set this hint on the combobox instead. + hint = "comboboxentry" + } +} + +style "clearlooks-expander" { + xthickness = 3 + ythickness = 3 + + fg[NORMAL] = "#a0a0a0" + fg[PRELIGHT] = "#d0d0d0" + fg[INSENSITIVE] = "#808080" + + bg[PRELIGHT] = mix(0.75, @rt_selected_bg_color, @rt_bg_color) + + base[NORMAL] = @rt_salt_pinch + base[PRELIGHT] = @rt_salt_pinch + base[INSENSITIVE] = @rt_salt_pinch +} + +style "clearlooks-subexpander" = "clearlooks-expander"{ + bg[NORMAL] = @rt_tool_bg +} + +style "clearlooks-menubar" { + + engine "clearlooks" { + hint = "menubar" + } +} + +style "clearlooks-menu" { + xthickness = 0 + ythickness = 0 + + bg[NORMAL] = shade (0.70, @rt_bg_color) + + engine "clearlooks" { + radius = 0.0 + } +} + +style "clearlooks-menu_item" { + xthickness = 2 + ythickness = 3 + + fg[PRELIGHT] = @rt_selected_fg_color + text[NORMAL] = @rt_fg_color + text[PRELIGHT] = @rt_selected_fg_color +} + +# This style is there to modify the separator menu items. The goals are: +# 1. Get a specific height. +# 2. The line should go to the edges (ie. no border at the left/right) +style "clearlooks-separator_menu_item" { + xthickness = 1 + ythickness = 0 + + GtkSeparatorMenuItem::horizontal-padding = 0 + GtkWidget::wide-separators = 1 + GtkWidget::separator-width = 1 + GtkWidget::separator-height = 7 +} + +style "clearlooks-frame_title" { + + fg[NORMAL] = lighter (@rt_fg_color) + fg[PRELIGHT] = lighter (@rt_fg_color) + fg[ACTIVE] = lighter (@rt_fg_color) + fg[SELECTED] = lighter (@rt_fg_color) +} + +style "clearlooks-partialPasteHeaderSep" { + + bg[NORMAL] = mix (0.25, @rt_fg_color, @rt_bg_color) +} + +style "clearlooks-checkbutton" { + + text[NORMAL] = @rt_selected_fg_color + + fg[PRELIGHT] = @rt_fg_color + + bg[SELECTED] = @rt_base_color + bg[PRELIGHT] = @rt_base_color + bg[SELECTED] = @rt_base_color + + engine "clearlooks" + { + hint = "checkbutton" + } +} + +style "clearlooks-treeview" { + + base[ACTIVE] = mix(0.50, @rt_selected_bg_color, @rt_base_color) + + engine "clearlooks" { + hint = "treeview" + } +} + +# The almost useless progress bar style +style "clearlooks-progressbar" { + xthickness = 1 + ythickness = 1 + + fg[PRELIGHT] = @rt_selected_fg_color + + engine "clearlooks" { + # Explicitly set the radius for the progress bars inside menu items. + radius = 3.0 + + hint = "progressbar" + } +} + +# This style is based on the clearlooks-default style, so that the colors from the button +# style are overriden again. +style "clearlooks-treeview_header" = "clearlooks-default" { + xthickness = 2 + ythickness = 1 + + bg[NORMAL] = shade (0.80, @rt_bg_color) + + engine "clearlooks" { + radius = 0.0 + hint = "treeview-header" + } +} + +style "clearlooks-tooltips" { + xthickness = 4 + ythickness = 4 + + bg[NORMAL] = @rt_tooltip_bg_color + fg[NORMAL] = @rt_tooltip_fg_color +} + +############################################################################### +# The following part of the gtkrc applies the different styles to the widgets. +############################################################################### + +# The clearlooks-default style is applied to every widget +class "GtkWidget" style "clearlooks-default" + +class "GtkSeparator" style "wide" +class "GtkFrame" style "wide" +class "GtkCalendar" style "wide" +class "GtkCheckButton" style "wider" +class "GtkRadioButton" style "wider" +class "GtkEntry" style "clearlooks-entry" + +class "GtkPaned" style "clearlooks-paned" +class "GtkSpinButton" style "clearlooks-spinbutton" +class "GtkScale" style "clearlooks-scale" +class "GtkVScale" style "clearlooks-vscale" +class "GtkHScale" style "clearlooks-hscale" +class "GtkScrollbar" style "clearlooks-scrollbar" +class "GtkHScrollbar" style "clearlooks-hscrollbar" +class "GtkVScrollbar" style "clearlooks-vscrollbar" + +class "GtkHSV" style "clearlooks-HSV" + +# General matching follows. The order is choosen so that the right styles override +# each other. EG. progressbar needs to be more important than the menu match. +widget_class "*" style "clearlooks-notebook_bg" +# This is not perfect, it could be done better. +# (That is modify *every* widget in the notebook, and change those back that +# we really don't want changed) +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" + +widget_class "*." style "clearlooks-combobox" +widget_class "**" style "clearlooks-button" +widget_class "*" style "clearlooks-notebook" +widget_class "**" style "clearlooks-statusbar" + +#widget_class "**" style "clearlooks-comboboxentry" +widget_class "**" style "clearlooks-combobox" + +widget_class "**" style "clearlooks-checkbutton" +widget_class "**" style "clearlooks-menubar" +widget_class "**" style "clearlooks-menu" +widget_class "**" style "clearlooks-menu_item" +widget_class "**" style "clearlooks-separator_menu_item" + +widget_class "*." style "clearlooks-frame" +widget_class "*.." style "clearlooks-frame_title" +widget_class "*.*" style "clearlooks-treeview" + +widget_class "*" style "clearlooks-progressbar" + +# Treeview headers (and similar stock GTK+ widgets) +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*...*." style "clearlooks-separator" +widget_class "*...*." style "clearlooks-toolExpanderBox" + +widget "*.partialPasteHeader.*" style "clearlooks-frame_title" +widget "*.partialPasteHeaderSep" style "clearlooks-partialPasteHeaderSep" +widget "*.histButton" style "clearlooks-histButton" +widget "*.FramelessSpinButton" style "clearlooks-framelessspinbutton" +widget "*.ThresholdSelector" style "clearlooks-thresholdselector" +widget "*.MyExpanderTitle.*" style "clearlooks-expander" +widget "*.MyExpanderTitle" style "clearlooks-expander" +widget "*.ExpanderBox" style "clearlooks-toolFrame" +widget "*.ExpanderBox.*.MyExpanderTitle" style "clearlooks-subexpander" +widget "*.ExpanderBox.*.MyExpanderTitle.*" style "clearlooks-subexpander" +widget "*.AxisAdjuster" style "clearlooks-axisadjuster" + +# The window of the tooltip is called "gtk-tooltip" +################################################################## +# FIXME: +# This will not work if one embeds eg. a button into the tooltip. +# As far as I can tell right now we will need to rework the theme +# quite a bit to get this working correctly. +# (It will involve setting different priorities, etc.) +################################################################## +widget "gtk-tooltip*" style "clearlooks-tooltips" + +gtk-icon-theme-name="Dark" diff --git a/rtdata/themes/17-Gray-Red.iconset b/rtdata/themes/17-Gray-Red.iconset new file mode 100644 index 000000000..99ac20640 --- /dev/null +++ b/rtdata/themes/17-Gray-Red.iconset @@ -0,0 +1,2 @@ +[General] +Iconset=Dark diff --git a/rtdata/themes/21-Gray-Gray.gtkrc b/rtdata/themes/21-Gray-Gray.gtkrc new file mode 100644 index 000000000..65bf68698 --- /dev/null +++ b/rtdata/themes/21-Gray-Gray.gtkrc @@ -0,0 +1,557 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2011 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 . +# + +# Please keep this gtkrc in sync with the other ones from Clearlooks based themes. + +gtk-color-scheme = "rt_salt_pinch:#B0B0B0\nrt_base_color:#1A1A1A\nrt_fg_color:#909090\nrt_tooltip_fg_color:#1A1A1A\nrt_selected_bg_color:#4A4A4A\nrt_selected_fg_color:#B0B0B0\nrt_text_color:#828282\nrt_bg_color:#363636\nrt_tooltip_bg_color:#909090\nrt_tool_bg:#252525\nrt_tool_border:#484848" + +style "clearlooks-default" { + xthickness = 1 + ythickness = 1 + + ####################### + # Style Properties + ####################### + GtkButton::child-displacement-x = 1 + GtkButton::child-displacement-y = 1 + GtkButton::default-border = { 0, 0, 0, 0 } + GtkButton::image-spacing = 4 + GtkToolButton::icon-spacing = 4 + + GtkCheckButton::indicator-size = 14 + + GtkPaned::handle-size = 6 + + GtkRange::trough-border = 0 + GtkRange::slider-width = 12 + GtkRange::stepper-size = 16 + + #GtkScale::slider-width = 12 + GtkScale::slider-length = 30 + GtkScale::trough-side-details = 0 + + GtkScrollbar::min-slider-length = 30 + GtkMenuBar::internal-padding = 0 + GtkExpander::expander-size = 12 + GtkExpander::expander-spacing = 2 + GtkToolbar::internal-padding = 1 + GtkTreeView::expander-size = 12 + GtkTreeView::vertical-separator = 1 + + GtkMenu::horizontal-padding = 0 + GtkMenu::vertical-padding = 0 + + WnckTasklist::fade-overlay-rect = 0 + # The following line hints to gecko (and possibly other appliations) + # that the entry should be drawn transparently on the canvas. + # Without this, gecko will fill in the background of the entry. + GtkEntry::honors-transparent-bg-hint = 1 + + GtkEntry::progress-border = { 2, 2, 2, 2 } + + #################### + # Color Definitions + #################### + bg[NORMAL] = @rt_bg_color + bg[PRELIGHT] = shade (1.02, @rt_bg_color) + bg[SELECTED] = @rt_selected_bg_color + bg[INSENSITIVE] = @rt_bg_color + bg[ACTIVE] = shade (0.9, @rt_bg_color) + + fg[NORMAL] = @rt_fg_color + fg[PRELIGHT] = @rt_fg_color + fg[SELECTED] = @rt_selected_fg_color + fg[INSENSITIVE] = mix (0.2, @rt_fg_color, @rt_bg_color) + fg[ACTIVE] = @rt_fg_color + + text[NORMAL] = @rt_text_color + text[PRELIGHT] = @rt_text_color + text[SELECTED] = @rt_selected_fg_color + text[INSENSITIVE] = lighter (@rt_bg_color) + text[ACTIVE] = @rt_selected_fg_color + + base[NORMAL] = @rt_base_color + base[PRELIGHT] = shade (0.95, @rt_bg_color) + base[SELECTED] = @rt_selected_bg_color + base[INSENSITIVE] = @rt_bg_color + base[ACTIVE] = shade (0.9, @rt_selected_bg_color) + + engine "clearlooks" { + colorize_scrollbar = TRUE + reliefstyle = 1 + menubarstyle = 2 + toolbarstyle = 1 + animation = FALSE + radius = 3.0 + # style between CLASSIC, GLOSSY, INVERTED and GUMMY + style = GUMMY + + # Set a hint to disable backward compatibility fallbacks. + hint = "use-hints" + } +} + +style "wide" { + xthickness = 2 + ythickness = 2 +} + +style "wider" { + xthickness = 3 + ythickness = 3 +} + +style "clearlooks-entry" { + xthickness = 3 + ythickness = 3 + + bg[SELECTED] = mix (1.4, @rt_selected_bg_color, @rt_base_color) + fg[SELECTED] = @rt_selected_fg_color + + engine "clearlooks" { + focus_color = shade (0.65, @rt_selected_bg_color) + } +} + +style "clearlooks-paned" { + + bg[PRELIGHT] = shade (0.8, @rt_bg_color) + + engine "clearlooks" { + hint = "paned" + } +} + +style "clearlooks-HSV" { + + engine "clearlooks" { + hint = "HSV" + disable_focus = TRUE + } +} + +style "clearlooks-spinbutton" { + + engine "clearlooks" { + hint = "spinbutton" + } +} + +style "clearlooks-axisadjuster" = "clearlooks-spinbutton" { + # background + base[INSENSITIVE] = @rt_tool_bg + # text + text[INSENSITIVE] = @rt_fg_color +} + +style "clearlooks-framelessspinbutton" { + + # IMPORTANT! + # base[NORMAL] must have the same color than clearlooks.toolContainer / bg[NORMAL] + base[NORMAL] = @rt_tool_bg + base[INSENSITIVE] = @rt_tool_bg + bg[NORMAL] = @rt_tool_bg + bg[INSENSITIVE] = @rt_tool_bg +} + +style "clearlooks-scale" { + xthickness = 2 + ythickness = 2 + + bg[NORMAL] = shade (1.35, @rt_bg_color) + bg[PRELIGHT] = shade (1.70, @rt_bg_color) + # when GtkScale::trough-side-details = 1, bg[SELECTED] set the color of the slider background on the left of the knob + #bg[SELECTED] = @rt_bg_color + + engine "clearlooks" { + focus_color = @rt_selected_bg_color + hint = "scale" + } +} + +style "clearlooks-thresholdselector" { + xthickness = 6 + ythickness = 6 + + bg[NORMAL] = @rt_tool_bg + bg[ACTIVE] = shade (1.45, @rt_bg_color) + bg[PRELIGHT] = shade (1.70, @rt_bg_color) + bg[SELECTED] = shade (2.00, @rt_bg_color) + + fg[PRELIGHT] = shade (1.30, @rt_fg_color) +} + +style "clearlooks-vscale" { + + engine "clearlooks" { + hint = "vscale" + } +} + +style "clearlooks-hscale" { + + engine "clearlooks" { + hint = "hscale" + } +} + +style "clearlooks-scrollbar" { + xthickness = 2 + ythickness = 2 + + bg[SELECTED] = shade (1.50, @rt_bg_color) + + engine "clearlooks" { + hint = "scrollbar" + } +} + +style "clearlooks-hscrollbar" { + + engine "clearlooks" { + hint = "hscrollbar" + } +} + +style "clearlooks-vscrollbar" { + + engine "clearlooks" { + hint = "vscrollbar" + } +} + +style "clearlooks-notebook_bg" { + + bg[NORMAL] = shade (1.02, @rt_bg_color) + bg[ACTIVE] = @rt_base_color +} + +style "clearlooks-toolContainer" { + xthickness = 0 + ythickness = 0 + + # IMPORTANT! + # If you modify bg[NORMAL] below, you must set clearlooks-framelessspinbutton -> base[NORMAL] to the very same value + bg[NORMAL] = @rt_tool_bg + bg[INSENSITIVE] = @rt_tool_bg +} + +style "clearlooks-separator" { + bg[NORMAL] = shade(0.85, @rt_bg_color) + bg[INSENSITIVE] = shade(0.85, @rt_bg_color) +} + +style "clearlooks-frame" { + bg[NORMAL] = shade(0.85, @rt_bg_color) + bg[INSENSITIVE] = shade(0.85, @rt_bg_color) +} + +style "clearlooks-toolFrame" = "clearlooks-toolContainer" { + bg[NORMAL] = @rt_tool_bg + + fg[NORMAL] = @rt_tool_border + fg[INSENSITIVE] = mix(0.5, @rt_bg_color, @rt_tool_border) +} + +style "clearlooks-toolExpanderBox" { + bg[NORMAL] = @rt_tool_bg + bg[INSENSITIVE] = @rt_tool_bg +} + +style "clearlooks-combobox" { + + text[NORMAL] = @rt_fg_color + text[PRELIGHT] = shade(1.15, @rt_fg_color) + text[SELECTED] = @rt_selected_fg_color + text[INSENSITIVE] = mix (0.2, @rt_fg_color, @rt_bg_color) + text[ACTIVE] = @rt_fg_color +} + +style "clearlooks-button" { + + bg[NORMAL] = shade (1.20, @rt_bg_color) + bg[PRELIGHT] = shade (1.30, @rt_bg_color) + bg[ACTIVE] = shade (1.90, @rt_bg_color) + + fg[NORMAL] = @rt_fg_color + fg[PRELIGHT] = shade(1.15, @rt_fg_color) + fg[SELECTED] = @rt_selected_fg_color + fg[INSENSITIVE] = mix (0.2, @rt_fg_color, @rt_bg_color) + fg[ACTIVE] = @rt_fg_color + + engine "clearlooks" + { + hint = "button" + } +} + +style "clearlooks-histButton" { + + GtkButton::child-displacement-x = 0 + GtkButton::child-displacement-y = 0 +} + +# The color is changed by the notebook_bg style, this style +# changes the x/ythickness +style "clearlooks-notebook" { + xthickness = 3 + ythickness = 3 + + bg[SELECTED] = @rt_salt_pinch +} + +style "clearlooks-statusbar" { + + engine "clearlooks" { + hint = "statusbar" + } +} + +style "clearlooks-comboboxentry" { + + engine "clearlooks" { + # Note: + # If you set the appears-as-list option on comboboxes in the theme, + # then you should set this hint on the combobox instead. + hint = "comboboxentry" + } +} + +style "clearlooks-expander" { + xthickness = 3 + ythickness = 3 + + fg[NORMAL] = "#a0a0a0" + fg[PRELIGHT] = "#d0d0d0" + fg[INSENSITIVE] = "#808080" + + bg[PRELIGHT] = mix(0.8, @rt_selected_bg_color, @rt_bg_color) + + base[NORMAL] = @rt_salt_pinch + base[PRELIGHT] = @rt_salt_pinch + base[INSENSITIVE] = @rt_salt_pinch +} + +style "clearlooks-subexpander" = "clearlooks-expander"{ + bg[NORMAL] = @rt_tool_bg +} + +style "clearlooks-menubar" { + + engine "clearlooks" { + hint = "menubar" + } +} + +style "clearlooks-menu" { + xthickness = 0 + ythickness = 0 + + bg[NORMAL] = @rt_base_color + + engine "clearlooks" { + radius = 0.0 + } +} + +style "clearlooks-menu_item" { + xthickness = 2 + ythickness = 3 + + fg[PRELIGHT] = @rt_selected_fg_color + text[NORMAL] = @rt_fg_color + text[PRELIGHT] = @rt_selected_fg_color +} + +# This style is there to modify the separator menu items. The goals are: +# 1. Get a specific height. +# 2. The line should go to the edges (ie. no border at the left/right) +style "clearlooks-separator_menu_item" { + xthickness = 1 + ythickness = 0 + + GtkSeparatorMenuItem::horizontal-padding = 0 + GtkWidget::wide-separators = 1 + GtkWidget::separator-width = 1 + GtkWidget::separator-height = 7 +} + +style "clearlooks-frame_title" { + + fg[NORMAL] = lighter (@rt_fg_color) + fg[PRELIGHT] = lighter (@rt_fg_color) + fg[ACTIVE] = lighter (@rt_fg_color) + fg[SELECTED] = lighter (@rt_fg_color) +} + +style "clearlooks-partialPasteHeaderSep" { + + bg[NORMAL] = mix (0.20, @rt_fg_color, @rt_bg_color) +} + +style "clearlooks-checkbutton" { + + text[NORMAL] = @rt_selected_fg_color + + fg[PRELIGHT] = @rt_fg_color + + bg[SELECTED] = @rt_base_color + bg[PRELIGHT] = @rt_base_color + bg[SELECTED] = @rt_base_color + + engine "clearlooks" + { + hint = "checkbutton" + } +} + +style "clearlooks-treeview" { + + base[ACTIVE] = mix(0.50, @rt_selected_bg_color, @rt_base_color) + + engine "clearlooks" { + hint = "treeview" + } +} + +# The almost useless progress bar style +style "clearlooks-progressbar" { + xthickness = 1 + ythickness = 1 + + fg[PRELIGHT] = @rt_selected_fg_color + + engine "clearlooks" { + # Explicitly set the radius for the progress bars inside menu items. + radius = 3.0 + + hint = "progressbar" + } +} + +# This style is based on the clearlooks-default style, so that the colors from the button +# style are overriden again. +style "clearlooks-treeview_header" = "clearlooks-default" { + xthickness = 2 + ythickness = 1 + + bg[NORMAL] = shade (0.80, @rt_bg_color) + + engine "clearlooks" { + radius = 0.0 + hint = "treeview-header" + } +} + +style "clearlooks-tooltips" { + xthickness = 4 + ythickness = 4 + + bg[NORMAL] = @rt_tooltip_bg_color + fg[NORMAL] = @rt_tooltip_fg_color +} + +############################################################################### +# The following part of the gtkrc applies the different styles to the widgets. +############################################################################### + +# The clearlooks-default style is applied to every widget +class "GtkWidget" style "clearlooks-default" + +class "GtkSeparator" style "wide" +class "GtkFrame" style "wide" +class "GtkCalendar" style "wide" +class "GtkCheckButton" style "wider" +class "GtkRadioButton" style "wider" +class "GtkEntry" style "clearlooks-entry" + +class "GtkPaned" style "clearlooks-paned" +class "GtkSpinButton" style "clearlooks-spinbutton" +class "GtkScale" style "clearlooks-scale" +class "GtkVScale" style "clearlooks-vscale" +class "GtkHScale" style "clearlooks-hscale" +class "GtkScrollbar" style "clearlooks-scrollbar" +class "GtkHScrollbar" style "clearlooks-hscrollbar" +class "GtkVScrollbar" style "clearlooks-vscrollbar" + +class "GtkHSV" style "clearlooks-HSV" + +# General matching follows. The order is choosen so that the right styles override +# each other. EG. progressbar needs to be more important than the menu match. +widget_class "*" style "clearlooks-notebook_bg" +# This is not perfect, it could be done better. +# (That is modify *every* widget in the notebook, and change those back that +# we really don't want changed) +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" + +widget_class "*." style "clearlooks-combobox" +widget_class "**" style "clearlooks-button" +widget_class "*" style "clearlooks-notebook" +widget_class "**" style "clearlooks-statusbar" + +#widget_class "**" style "clearlooks-comboboxentry" +widget_class "**" style "clearlooks-combobox" + +widget_class "**" style "clearlooks-checkbutton" +widget_class "**" style "clearlooks-menubar" +widget_class "**" style "clearlooks-menu" +widget_class "**" style "clearlooks-menu_item" +widget_class "**" style "clearlooks-separator_menu_item" + +widget_class "*." style "clearlooks-frame" +widget_class "*.." style "clearlooks-frame_title" +widget_class "*.*" style "clearlooks-treeview" + +widget_class "*" style "clearlooks-progressbar" + +# Treeview headers (and similar stock GTK+ widgets) +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*...*." style "clearlooks-separator" +widget_class "*...*." style "clearlooks-toolExpanderBox" + +widget "*.partialPasteHeader.*" style "clearlooks-frame_title" +widget "*.partialPasteHeaderSep" style "clearlooks-partialPasteHeaderSep" +widget "*.histButton" style "clearlooks-histButton" +widget "*.FramelessSpinButton" style "clearlooks-framelessspinbutton" +widget "*.ThresholdSelector" style "clearlooks-thresholdselector" +widget "*.MyExpanderTitle.*" style "clearlooks-expander" +widget "*.MyExpanderTitle" style "clearlooks-expander" +widget "*.ExpanderBox" style "clearlooks-toolFrame" +widget "*.ExpanderBox.*.MyExpanderTitle" style "clearlooks-subexpander" +widget "*.ExpanderBox.*.MyExpanderTitle.*" style "clearlooks-subexpander" +widget "*.AxisAdjuster" style "clearlooks-axisadjuster" + +# The window of the tooltip is called "gtk-tooltip" +################################################################## +# FIXME: +# This will not work if one embeds eg. a button into the tooltip. +# As far as I can tell right now we will need to rework the theme +# quite a bit to get this working correctly. +# (It will involve setting different priorities, etc.) +################################################################## +widget "gtk-tooltip*" style "clearlooks-tooltips" + +gtk-icon-theme-name="Dark" diff --git a/rtdata/themes/21-Gray-Gray.iconset b/rtdata/themes/21-Gray-Gray.iconset new file mode 100644 index 000000000..99ac20640 --- /dev/null +++ b/rtdata/themes/21-Gray-Gray.iconset @@ -0,0 +1,2 @@ +[General] +Iconset=Dark diff --git a/rtdata/themes/21-Gray-Orange.gtkrc b/rtdata/themes/21-Gray-Orange.gtkrc new file mode 100644 index 000000000..44eaaee34 --- /dev/null +++ b/rtdata/themes/21-Gray-Orange.gtkrc @@ -0,0 +1,557 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2011 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 . +# + +# Please keep this gtkrc in sync with the other ones from Clearlooks based themes. + +gtk-color-scheme = "rt_salt_pinch:#FF8000\nrt_base_color:#1A1A1A\nrt_fg_color:#909090\nrt_tooltip_fg_color:#1A1A1A\nrt_selected_bg_color:#B3641B\nrt_selected_fg_color:#B0B0B0\nrt_text_color:#828282\nrt_bg_color:#363636\nrt_tooltip_bg_color:#909090\nrt_tool_bg:#252525\nrt_tool_border:#484848" + +style "clearlooks-default" { + xthickness = 1 + ythickness = 1 + + ####################### + # Style Properties + ####################### + GtkButton::child-displacement-x = 1 + GtkButton::child-displacement-y = 1 + GtkButton::default-border = { 0, 0, 0, 0 } + GtkButton::image-spacing = 4 + GtkToolButton::icon-spacing = 4 + + GtkCheckButton::indicator-size = 14 + + GtkPaned::handle-size = 6 + + GtkRange::trough-border = 0 + GtkRange::slider-width = 12 + GtkRange::stepper-size = 16 + + #GtkScale::slider-width = 12 + GtkScale::slider-length = 30 + GtkScale::trough-side-details = 0 + + GtkScrollbar::min-slider-length = 30 + GtkMenuBar::internal-padding = 0 + GtkExpander::expander-size = 12 + GtkExpander::expander-spacing = 2 + GtkToolbar::internal-padding = 1 + GtkTreeView::expander-size = 12 + GtkTreeView::vertical-separator = 1 + + GtkMenu::horizontal-padding = 0 + GtkMenu::vertical-padding = 0 + + WnckTasklist::fade-overlay-rect = 0 + # The following line hints to gecko (and possibly other appliations) + # that the entry should be drawn transparently on the canvas. + # Without this, gecko will fill in the background of the entry. + GtkEntry::honors-transparent-bg-hint = 1 + + GtkEntry::progress-border = { 2, 2, 2, 2 } + + #################### + # Color Definitions + #################### + bg[NORMAL] = @rt_bg_color + bg[PRELIGHT] = shade (1.02, @rt_bg_color) + bg[SELECTED] = @rt_selected_bg_color + bg[INSENSITIVE] = @rt_bg_color + bg[ACTIVE] = shade (0.9, @rt_bg_color) + + fg[NORMAL] = @rt_fg_color + fg[PRELIGHT] = @rt_fg_color + fg[SELECTED] = @rt_selected_fg_color + fg[INSENSITIVE] = mix (0.2, @rt_fg_color, @rt_bg_color) + fg[ACTIVE] = @rt_fg_color + + text[NORMAL] = @rt_text_color + text[PRELIGHT] = @rt_text_color + text[SELECTED] = @rt_selected_fg_color + text[INSENSITIVE] = darker (@rt_bg_color) + text[ACTIVE] = @rt_selected_fg_color + + base[NORMAL] = @rt_base_color + base[PRELIGHT] = shade (0.95, @rt_bg_color) + base[SELECTED] = @rt_selected_bg_color + base[INSENSITIVE] = @rt_bg_color + base[ACTIVE] = shade (0.9, @rt_selected_bg_color) + + engine "clearlooks" { + colorize_scrollbar = TRUE + reliefstyle = 1 + menubarstyle = 2 + toolbarstyle = 1 + animation = FALSE + radius = 3.0 + # style between CLASSIC, GLOSSY, INVERTED and GUMMY + style = GUMMY + + # Set a hint to disable backward compatibility fallbacks. + hint = "use-hints" + } +} + +style "wide" { + xthickness = 2 + ythickness = 2 +} + +style "wider" { + xthickness = 3 + ythickness = 3 +} + +style "clearlooks-entry" { + xthickness = 3 + ythickness = 3 + + bg[SELECTED] = mix (1.4, @rt_selected_bg_color, @rt_base_color) + fg[SELECTED] = @rt_selected_fg_color + + engine "clearlooks" { + focus_color = shade (0.65, @rt_selected_bg_color) + } +} + +style "clearlooks-paned" { + + bg[PRELIGHT] = shade (0.8, @rt_bg_color) + + engine "clearlooks" { + hint = "paned" + } +} + +style "clearlooks-HSV" { + + engine "clearlooks" { + hint = "HSV" + disable_focus = TRUE + } +} + +style "clearlooks-spinbutton" { + + engine "clearlooks" { + hint = "spinbutton" + } +} + +style "clearlooks-axisadjuster" = "clearlooks-spinbutton" { + # background + base[INSENSITIVE] = @rt_tool_bg + # text + text[INSENSITIVE] = @rt_fg_color +} + +style "clearlooks-framelessspinbutton" { + + # IMPORTANT! + # base[NORMAL] must have the same color than clearlooks.toolContainer / bg[NORMAL] + base[NORMAL] = @rt_tool_bg + base[INSENSITIVE] = @rt_tool_bg + bg[NORMAL] = @rt_tool_bg + bg[INSENSITIVE] = @rt_tool_bg +} + +style "clearlooks-scale" { + xthickness = 2 + ythickness = 2 + + bg[NORMAL] = shade (1.35, @rt_bg_color) + bg[PRELIGHT] = shade (1.70, @rt_bg_color) + # when GtkScale::trough-side-details = 1, bg[SELECTED] set the color of the slider background on the left of the knob + #bg[SELECTED] = @rt_bg_color + + engine "clearlooks" { + focus_color = @rt_selected_bg_color + hint = "scale" + } +} + +style "clearlooks-thresholdselector" { + xthickness = 6 + ythickness = 6 + + bg[NORMAL] = @rt_tool_bg + bg[ACTIVE] = shade (1.45, @rt_bg_color) + bg[PRELIGHT] = shade (1.70, @rt_bg_color) + bg[SELECTED] = shade (2.00, @rt_bg_color) + + fg[PRELIGHT] = shade (1.30, @rt_fg_color) +} + +style "clearlooks-vscale" { + + engine "clearlooks" { + hint = "vscale" + } +} + +style "clearlooks-hscale" { + + engine "clearlooks" { + hint = "hscale" + } +} + +style "clearlooks-scrollbar" { + xthickness = 2 + ythickness = 2 + + bg[SELECTED] = shade (1.50, @rt_bg_color) + + engine "clearlooks" { + hint = "scrollbar" + } +} + +style "clearlooks-hscrollbar" { + + engine "clearlooks" { + hint = "hscrollbar" + } +} + +style "clearlooks-vscrollbar" { + + engine "clearlooks" { + hint = "vscrollbar" + } +} + +style "clearlooks-notebook_bg" { + + bg[NORMAL] = shade (1.02, @rt_bg_color) + bg[ACTIVE] = @rt_base_color +} + +style "clearlooks-toolContainer" { + xthickness = 0 + ythickness = 0 + + # IMPORTANT! + # If you modify bg[NORMAL] below, you must set clearlooks-framelessspinbutton -> base[NORMAL] to the very same value + bg[NORMAL] = @rt_tool_bg + bg[INSENSITIVE] = @rt_tool_bg +} + +style "clearlooks-separator" { + bg[NORMAL] = shade(0.85, @rt_bg_color) + bg[INSENSITIVE] = shade(0.85, @rt_bg_color) +} + +style "clearlooks-frame" { + bg[NORMAL] = shade(0.85, @rt_bg_color) + bg[INSENSITIVE] = shade(0.85, @rt_bg_color) +} + +style "clearlooks-toolFrame" = "clearlooks-toolContainer" { + bg[NORMAL] = @rt_tool_bg + + fg[NORMAL] = @rt_tool_border + fg[INSENSITIVE] = mix(0.5, @rt_bg_color, @rt_tool_border) +} + +style "clearlooks-toolExpanderBox" { + bg[NORMAL] = @rt_tool_bg + bg[INSENSITIVE] = @rt_tool_bg +} + +style "clearlooks-combobox" { + + text[NORMAL] = @rt_fg_color + text[PRELIGHT] = shade(1.15, @rt_fg_color) + text[SELECTED] = @rt_selected_fg_color + text[INSENSITIVE] = mix (0.2, @rt_fg_color, @rt_bg_color) + text[ACTIVE] = @rt_fg_color +} + +style "clearlooks-button" { + + bg[NORMAL] = shade (1.20, @rt_bg_color) + bg[PRELIGHT] = shade (1.30, @rt_bg_color) + bg[ACTIVE] = shade (1.90, @rt_bg_color) + + fg[NORMAL] = @rt_fg_color + fg[PRELIGHT] = shade(1.15, @rt_fg_color) + fg[SELECTED] = @rt_selected_fg_color + fg[INSENSITIVE] = mix (0.2, @rt_fg_color, @rt_bg_color) + fg[ACTIVE] = @rt_fg_color + + engine "clearlooks" + { + hint = "button" + } +} + +style "clearlooks-histButton" { + + GtkButton::child-displacement-x = 0 + GtkButton::child-displacement-y = 0 +} + +# The color is changed by the notebook_bg style, this style +# changes the x/ythickness +style "clearlooks-notebook" { + xthickness = 3 + ythickness = 3 + + bg[SELECTED] = @rt_salt_pinch +} + +style "clearlooks-statusbar" { + + engine "clearlooks" { + hint = "statusbar" + } +} + +style "clearlooks-comboboxentry" { + + engine "clearlooks" { + # Note: + # If you set the appears-as-list option on comboboxes in the theme, + # then you should set this hint on the combobox instead. + hint = "comboboxentry" + } +} + +style "clearlooks-expander" { + xthickness = 3 + ythickness = 3 + + fg[NORMAL] = "#a0a0a0" + fg[PRELIGHT] = "#d0d0d0" + fg[INSENSITIVE] = "#808080" + + bg[PRELIGHT] = mix(0.8, @rt_selected_bg_color, @rt_bg_color) + + base[NORMAL] = @rt_salt_pinch + base[PRELIGHT] = @rt_salt_pinch + base[INSENSITIVE] = @rt_salt_pinch +} + +style "clearlooks-subexpander" = "clearlooks-expander"{ + bg[NORMAL] = @rt_tool_bg +} + +style "clearlooks-menubar" { + + engine "clearlooks" { + hint = "menubar" + } +} + +style "clearlooks-menu" { + xthickness = 0 + ythickness = 0 + + bg[NORMAL] = @rt_base_color + + engine "clearlooks" { + radius = 0.0 + } +} + +style "clearlooks-menu_item" { + xthickness = 2 + ythickness = 3 + + fg[PRELIGHT] = @rt_selected_fg_color + text[NORMAL] = @rt_fg_color + text[PRELIGHT] = @rt_selected_fg_color +} + +# This style is there to modify the separator menu items. The goals are: +# 1. Get a specific height. +# 2. The line should go to the edges (ie. no border at the left/right) +style "clearlooks-separator_menu_item" { + xthickness = 1 + ythickness = 0 + + GtkSeparatorMenuItem::horizontal-padding = 0 + GtkWidget::wide-separators = 1 + GtkWidget::separator-width = 1 + GtkWidget::separator-height = 7 +} + +style "clearlooks-frame_title" { + + fg[NORMAL] = lighter (@rt_fg_color) + fg[PRELIGHT] = lighter (@rt_fg_color) + fg[ACTIVE] = lighter (@rt_fg_color) + fg[SELECTED] = lighter (@rt_fg_color) +} + +style "clearlooks-partialPasteHeaderSep" { + + bg[NORMAL] = mix (0.20, @rt_fg_color, @rt_bg_color) +} + +style "clearlooks-checkbutton" { + + text[NORMAL] = @rt_selected_fg_color + + fg[PRELIGHT] = @rt_fg_color + + bg[SELECTED] = @rt_base_color + bg[PRELIGHT] = @rt_base_color + bg[SELECTED] = @rt_base_color + + engine "clearlooks" + { + hint = "checkbutton" + } +} + +style "clearlooks-treeview" { + + base[ACTIVE] = mix(0.50, @rt_selected_bg_color, @rt_base_color) + + engine "clearlooks" { + hint = "treeview" + } +} + +# The almost useless progress bar style +style "clearlooks-progressbar" { + xthickness = 1 + ythickness = 1 + + fg[PRELIGHT] = @rt_selected_fg_color + + engine "clearlooks" { + # Explicitly set the radius for the progress bars inside menu items. + radius = 3.0 + + hint = "progressbar" + } +} + +# This style is based on the clearlooks-default style, so that the colors from the button +# style are overriden again. +style "clearlooks-treeview_header" = "clearlooks-default" { + xthickness = 2 + ythickness = 1 + + bg[NORMAL] = shade (0.80, @rt_bg_color) + + engine "clearlooks" { + radius = 0.0 + hint = "treeview-header" + } +} + +style "clearlooks-tooltips" { + xthickness = 4 + ythickness = 4 + + bg[NORMAL] = @rt_tooltip_bg_color + fg[NORMAL] = @rt_tooltip_fg_color +} + +############################################################################### +# The following part of the gtkrc applies the different styles to the widgets. +############################################################################### + +# The clearlooks-default style is applied to every widget +class "GtkWidget" style "clearlooks-default" + +class "GtkSeparator" style "wide" +class "GtkFrame" style "wide" +class "GtkCalendar" style "wide" +class "GtkCheckButton" style "wider" +class "GtkRadioButton" style "wider" +class "GtkEntry" style "clearlooks-entry" + +class "GtkPaned" style "clearlooks-paned" +class "GtkSpinButton" style "clearlooks-spinbutton" +class "GtkScale" style "clearlooks-scale" +class "GtkVScale" style "clearlooks-vscale" +class "GtkHScale" style "clearlooks-hscale" +class "GtkScrollbar" style "clearlooks-scrollbar" +class "GtkHScrollbar" style "clearlooks-hscrollbar" +class "GtkVScrollbar" style "clearlooks-vscrollbar" + +class "GtkHSV" style "clearlooks-HSV" + +# General matching follows. The order is choosen so that the right styles override +# each other. EG. progressbar needs to be more important than the menu match. +widget_class "*" style "clearlooks-notebook_bg" +# This is not perfect, it could be done better. +# (That is modify *every* widget in the notebook, and change those back that +# we really don't want changed) +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" + +widget_class "*." style "clearlooks-combobox" +widget_class "**" style "clearlooks-button" +widget_class "*" style "clearlooks-notebook" +widget_class "**" style "clearlooks-statusbar" + +#widget_class "**" style "clearlooks-comboboxentry" +widget_class "**" style "clearlooks-combobox" + +widget_class "**" style "clearlooks-checkbutton" +widget_class "**" style "clearlooks-menubar" +widget_class "**" style "clearlooks-menu" +widget_class "**" style "clearlooks-menu_item" +widget_class "**" style "clearlooks-separator_menu_item" + +widget_class "*." style "clearlooks-frame" +widget_class "*.." style "clearlooks-frame_title" +widget_class "*.*" style "clearlooks-treeview" + +widget_class "*" style "clearlooks-progressbar" + +# Treeview headers (and similar stock GTK+ widgets) +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*...*." style "clearlooks-separator" +widget_class "*...*." style "clearlooks-toolExpanderBox" + +widget "*.partialPasteHeader.*" style "clearlooks-frame_title" +widget "*.partialPasteHeaderSep" style "clearlooks-partialPasteHeaderSep" +widget "*.histButton" style "clearlooks-histButton" +widget "*.FramelessSpinButton" style "clearlooks-framelessspinbutton" +widget "*.ThresholdSelector" style "clearlooks-thresholdselector" +widget "*.MyExpanderTitle.*" style "clearlooks-expander" +widget "*.MyExpanderTitle" style "clearlooks-expander" +widget "*.ExpanderBox" style "clearlooks-toolFrame" +widget "*.ExpanderBox.*.MyExpanderTitle" style "clearlooks-subexpander" +widget "*.ExpanderBox.*.MyExpanderTitle.*" style "clearlooks-subexpander" +widget "*.AxisAdjuster" style "clearlooks-axisadjuster" + +# The window of the tooltip is called "gtk-tooltip" +################################################################## +# FIXME: +# This will not work if one embeds eg. a button into the tooltip. +# As far as I can tell right now we will need to rework the theme +# quite a bit to get this working correctly. +# (It will involve setting different priorities, etc.) +################################################################## +widget "gtk-tooltip*" style "clearlooks-tooltips" + +gtk-icon-theme-name="Dark" diff --git a/rtdata/themes/21-Gray-Orange.iconset b/rtdata/themes/21-Gray-Orange.iconset new file mode 100644 index 000000000..99ac20640 --- /dev/null +++ b/rtdata/themes/21-Gray-Orange.iconset @@ -0,0 +1,2 @@ +[General] +Iconset=Dark diff --git a/rtdata/themes/21-Gray-Purple.gtkrc b/rtdata/themes/21-Gray-Purple.gtkrc new file mode 100644 index 000000000..95f485640 --- /dev/null +++ b/rtdata/themes/21-Gray-Purple.gtkrc @@ -0,0 +1,557 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2011 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 . +# + +# Please keep this gtkrc in sync with the other ones from Clearlooks based themes. + +gtk-color-scheme = "rt_salt_pinch:#843382\nrt_base_color:#1A1A1A\nrt_fg_color:#909090\nrt_tooltip_fg_color:#1A1A1A\nrt_selected_bg_color:#5D235C\nrt_selected_fg_color:#B0B0B0\nrt_text_color:#828282\nrt_bg_color:#363636\nrt_tooltip_bg_color:#909090\nrt_tool_bg:#252525\nrt_tool_border:#484848" + +style "clearlooks-default" { + xthickness = 1 + ythickness = 1 + + ####################### + # Style Properties + ####################### + GtkButton::child-displacement-x = 1 + GtkButton::child-displacement-y = 1 + GtkButton::default-border = { 0, 0, 0, 0 } + GtkButton::image-spacing = 4 + GtkToolButton::icon-spacing = 4 + + GtkCheckButton::indicator-size = 14 + + GtkPaned::handle-size = 6 + + GtkRange::trough-border = 0 + GtkRange::slider-width = 12 + GtkRange::stepper-size = 16 + + #GtkScale::slider-width = 12 + GtkScale::slider-length = 30 + GtkScale::trough-side-details = 0 + + GtkScrollbar::min-slider-length = 30 + GtkMenuBar::internal-padding = 0 + GtkExpander::expander-size = 12 + GtkExpander::expander-spacing = 2 + GtkToolbar::internal-padding = 1 + GtkTreeView::expander-size = 12 + GtkTreeView::vertical-separator = 1 + + GtkMenu::horizontal-padding = 0 + GtkMenu::vertical-padding = 0 + + WnckTasklist::fade-overlay-rect = 0 + # The following line hints to gecko (and possibly other appliations) + # that the entry should be drawn transparently on the canvas. + # Without this, gecko will fill in the background of the entry. + GtkEntry::honors-transparent-bg-hint = 1 + + GtkEntry::progress-border = { 2, 2, 2, 2 } + + #################### + # Color Definitions + #################### + bg[NORMAL] = @rt_bg_color + bg[PRELIGHT] = shade (1.02, @rt_bg_color) + bg[SELECTED] = @rt_selected_bg_color + bg[INSENSITIVE] = @rt_bg_color + bg[ACTIVE] = shade (0.9, @rt_bg_color) + + fg[NORMAL] = @rt_fg_color + fg[PRELIGHT] = @rt_fg_color + fg[SELECTED] = @rt_selected_fg_color + fg[INSENSITIVE] = mix (0.2, @rt_fg_color, @rt_bg_color) + fg[ACTIVE] = @rt_fg_color + + text[NORMAL] = @rt_text_color + text[PRELIGHT] = @rt_text_color + text[SELECTED] = @rt_selected_fg_color + text[INSENSITIVE] = darker (@rt_bg_color) + text[ACTIVE] = @rt_selected_fg_color + + base[NORMAL] = @rt_base_color + base[PRELIGHT] = shade (0.95, @rt_bg_color) + base[SELECTED] = @rt_selected_bg_color + base[INSENSITIVE] = @rt_bg_color + base[ACTIVE] = shade (0.9, @rt_selected_bg_color) + + engine "clearlooks" { + colorize_scrollbar = TRUE + reliefstyle = 1 + menubarstyle = 2 + toolbarstyle = 1 + animation = FALSE + radius = 3.0 + # style between CLASSIC, GLOSSY, INVERTED and GUMMY + style = GUMMY + + # Set a hint to disable backward compatibility fallbacks. + hint = "use-hints" + } +} + +style "wide" { + xthickness = 2 + ythickness = 2 +} + +style "wider" { + xthickness = 3 + ythickness = 3 +} + +style "clearlooks-entry" { + xthickness = 3 + ythickness = 3 + + bg[SELECTED] = mix (1.4, @rt_selected_bg_color, @rt_base_color) + fg[SELECTED] = @rt_selected_fg_color + + engine "clearlooks" { + focus_color = shade (0.65, @rt_selected_bg_color) + } +} + +style "clearlooks-paned" { + + bg[PRELIGHT] = shade (0.8, @rt_bg_color) + + engine "clearlooks" { + hint = "paned" + } +} + +style "clearlooks-HSV" { + + engine "clearlooks" { + hint = "HSV" + disable_focus = TRUE + } +} + +style "clearlooks-spinbutton" { + + engine "clearlooks" { + hint = "spinbutton" + } +} + +style "clearlooks-axisadjuster" = "clearlooks-spinbutton" { + # background + base[INSENSITIVE] = @rt_tool_bg + # text + text[INSENSITIVE] = @rt_fg_color +} + +style "clearlooks-framelessspinbutton" { + + # IMPORTANT! + # base[NORMAL] must have the same color than clearlooks.toolContainer / bg[NORMAL] + base[NORMAL] = @rt_tool_bg + base[INSENSITIVE] = @rt_tool_bg + bg[NORMAL] = @rt_tool_bg + bg[INSENSITIVE] = @rt_tool_bg +} + +style "clearlooks-scale" { + xthickness = 2 + ythickness = 2 + + bg[NORMAL] = shade (1.35, @rt_bg_color) + bg[PRELIGHT] = shade (1.70, @rt_bg_color) + # when GtkScale::trough-side-details = 1, bg[SELECTED] set the color of the slider background on the left of the knob + #bg[SELECTED] = @rt_bg_color + + engine "clearlooks" { + focus_color = @rt_selected_bg_color + hint = "scale" + } +} + +style "clearlooks-thresholdselector" { + xthickness = 6 + ythickness = 6 + + bg[NORMAL] = @rt_tool_bg + bg[ACTIVE] = shade (1.45, @rt_bg_color) + bg[PRELIGHT] = shade (1.70, @rt_bg_color) + bg[SELECTED] = shade (2.00, @rt_bg_color) + + fg[PRELIGHT] = shade (1.30, @rt_fg_color) +} + +style "clearlooks-vscale" { + + engine "clearlooks" { + hint = "vscale" + } +} + +style "clearlooks-hscale" { + + engine "clearlooks" { + hint = "hscale" + } +} + +style "clearlooks-scrollbar" { + xthickness = 2 + ythickness = 2 + + bg[SELECTED] = shade (1.50, @rt_bg_color) + + engine "clearlooks" { + hint = "scrollbar" + } +} + +style "clearlooks-hscrollbar" { + + engine "clearlooks" { + hint = "hscrollbar" + } +} + +style "clearlooks-vscrollbar" { + + engine "clearlooks" { + hint = "vscrollbar" + } +} + +style "clearlooks-notebook_bg" { + + bg[NORMAL] = shade (1.02, @rt_bg_color) + bg[ACTIVE] = @rt_base_color +} + +style "clearlooks-toolContainer" { + xthickness = 0 + ythickness = 0 + + # IMPORTANT! + # If you modify bg[NORMAL] below, you must set clearlooks-framelessspinbutton -> base[NORMAL] to the very same value + bg[NORMAL] = @rt_tool_bg + bg[INSENSITIVE] = @rt_tool_bg +} + +style "clearlooks-separator" { + bg[NORMAL] = shade(0.85, @rt_bg_color) + bg[INSENSITIVE] = shade(0.85, @rt_bg_color) +} + +style "clearlooks-frame" { + bg[NORMAL] = shade(0.85, @rt_bg_color) + bg[INSENSITIVE] = shade(0.85, @rt_bg_color) +} + +style "clearlooks-toolFrame" = "clearlooks-toolContainer" { + bg[NORMAL] = @rt_tool_bg + + fg[NORMAL] = @rt_tool_border + fg[INSENSITIVE] = mix(0.5, @rt_bg_color, @rt_tool_border) +} + +style "clearlooks-toolExpanderBox" { + bg[NORMAL] = @rt_tool_bg + bg[INSENSITIVE] = @rt_tool_bg +} + +style "clearlooks-combobox" { + + text[NORMAL] = @rt_fg_color + text[PRELIGHT] = shade(1.15, @rt_fg_color) + text[SELECTED] = @rt_selected_fg_color + text[INSENSITIVE] = mix (0.2, @rt_fg_color, @rt_bg_color) + text[ACTIVE] = @rt_fg_color +} + +style "clearlooks-button" { + + bg[NORMAL] = shade (1.20, @rt_bg_color) + bg[PRELIGHT] = shade (1.30, @rt_bg_color) + bg[ACTIVE] = shade (1.90, @rt_bg_color) + + fg[NORMAL] = @rt_fg_color + fg[PRELIGHT] = shade(1.15, @rt_fg_color) + fg[SELECTED] = @rt_selected_fg_color + fg[INSENSITIVE] = mix (0.2, @rt_fg_color, @rt_bg_color) + fg[ACTIVE] = @rt_fg_color + + engine "clearlooks" + { + hint = "button" + } +} + +style "clearlooks-histButton" { + + GtkButton::child-displacement-x = 0 + GtkButton::child-displacement-y = 0 +} + +# The color is changed by the notebook_bg style, this style +# changes the x/ythickness +style "clearlooks-notebook" { + xthickness = 3 + ythickness = 3 + + bg[SELECTED] = @rt_salt_pinch +} + +style "clearlooks-statusbar" { + + engine "clearlooks" { + hint = "statusbar" + } +} + +style "clearlooks-comboboxentry" { + + engine "clearlooks" { + # Note: + # If you set the appears-as-list option on comboboxes in the theme, + # then you should set this hint on the combobox instead. + hint = "comboboxentry" + } +} + +style "clearlooks-expander" { + xthickness = 3 + ythickness = 3 + + fg[NORMAL] = "#a0a0a0" + fg[PRELIGHT] = "#d0d0d0" + fg[INSENSITIVE] = "#808080" + + bg[PRELIGHT] = mix(0.8, @rt_selected_bg_color, @rt_bg_color) + + base[NORMAL] = @rt_salt_pinch + base[PRELIGHT] = @rt_salt_pinch + base[INSENSITIVE] = @rt_salt_pinch +} + +style "clearlooks-subexpander" = "clearlooks-expander"{ + bg[NORMAL] = @rt_tool_bg +} + +style "clearlooks-menubar" { + + engine "clearlooks" { + hint = "menubar" + } +} + +style "clearlooks-menu" { + xthickness = 0 + ythickness = 0 + + bg[NORMAL] = @rt_base_color + + engine "clearlooks" { + radius = 0.0 + } +} + +style "clearlooks-menu_item" { + xthickness = 2 + ythickness = 3 + + fg[PRELIGHT] = @rt_selected_fg_color + text[NORMAL] = @rt_fg_color + text[PRELIGHT] = @rt_selected_fg_color +} + +# This style is there to modify the separator menu items. The goals are: +# 1. Get a specific height. +# 2. The line should go to the edges (ie. no border at the left/right) +style "clearlooks-separator_menu_item" { + xthickness = 1 + ythickness = 0 + + GtkSeparatorMenuItem::horizontal-padding = 0 + GtkWidget::wide-separators = 1 + GtkWidget::separator-width = 1 + GtkWidget::separator-height = 7 +} + +style "clearlooks-frame_title" { + + fg[NORMAL] = lighter (@rt_fg_color) + fg[PRELIGHT] = lighter (@rt_fg_color) + fg[ACTIVE] = lighter (@rt_fg_color) + fg[SELECTED] = lighter (@rt_fg_color) +} + +style "clearlooks-partialPasteHeaderSep" { + + bg[NORMAL] = mix (0.20, @rt_fg_color, @rt_bg_color) +} + +style "clearlooks-checkbutton" { + + text[NORMAL] = @rt_selected_fg_color + + fg[PRELIGHT] = @rt_fg_color + + bg[SELECTED] = @rt_base_color + bg[PRELIGHT] = @rt_base_color + bg[SELECTED] = @rt_base_color + + engine "clearlooks" + { + hint = "checkbutton" + } +} + +style "clearlooks-treeview" { + + base[ACTIVE] = mix(0.50, @rt_selected_bg_color, @rt_base_color) + + engine "clearlooks" { + hint = "treeview" + } +} + +# The almost useless progress bar style +style "clearlooks-progressbar" { + xthickness = 1 + ythickness = 1 + + fg[PRELIGHT] = @rt_selected_fg_color + + engine "clearlooks" { + # Explicitly set the radius for the progress bars inside menu items. + radius = 3.0 + + hint = "progressbar" + } +} + +# This style is based on the clearlooks-default style, so that the colors from the button +# style are overriden again. +style "clearlooks-treeview_header" = "clearlooks-default" { + xthickness = 2 + ythickness = 1 + + bg[NORMAL] = shade (0.80, @rt_bg_color) + + engine "clearlooks" { + radius = 0.0 + hint = "treeview-header" + } +} + +style "clearlooks-tooltips" { + xthickness = 4 + ythickness = 4 + + bg[NORMAL] = @rt_tooltip_bg_color + fg[NORMAL] = @rt_tooltip_fg_color +} + +############################################################################### +# The following part of the gtkrc applies the different styles to the widgets. +############################################################################### + +# The clearlooks-default style is applied to every widget +class "GtkWidget" style "clearlooks-default" + +class "GtkSeparator" style "wide" +class "GtkFrame" style "wide" +class "GtkCalendar" style "wide" +class "GtkCheckButton" style "wider" +class "GtkRadioButton" style "wider" +class "GtkEntry" style "clearlooks-entry" + +class "GtkPaned" style "clearlooks-paned" +class "GtkSpinButton" style "clearlooks-spinbutton" +class "GtkScale" style "clearlooks-scale" +class "GtkVScale" style "clearlooks-vscale" +class "GtkHScale" style "clearlooks-hscale" +class "GtkScrollbar" style "clearlooks-scrollbar" +class "GtkHScrollbar" style "clearlooks-hscrollbar" +class "GtkVScrollbar" style "clearlooks-vscrollbar" + +class "GtkHSV" style "clearlooks-HSV" + +# General matching follows. The order is choosen so that the right styles override +# each other. EG. progressbar needs to be more important than the menu match. +widget_class "*" style "clearlooks-notebook_bg" +# This is not perfect, it could be done better. +# (That is modify *every* widget in the notebook, and change those back that +# we really don't want changed) +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" + +widget_class "*." style "clearlooks-combobox" +widget_class "**" style "clearlooks-button" +widget_class "*" style "clearlooks-notebook" +widget_class "**" style "clearlooks-statusbar" + +#widget_class "**" style "clearlooks-comboboxentry" +widget_class "**" style "clearlooks-combobox" + +widget_class "**" style "clearlooks-checkbutton" +widget_class "**" style "clearlooks-menubar" +widget_class "**" style "clearlooks-menu" +widget_class "**" style "clearlooks-menu_item" +widget_class "**" style "clearlooks-separator_menu_item" + +widget_class "*." style "clearlooks-frame" +widget_class "*.." style "clearlooks-frame_title" +widget_class "*.*" style "clearlooks-treeview" + +widget_class "*" style "clearlooks-progressbar" + +# Treeview headers (and similar stock GTK+ widgets) +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*...*." style "clearlooks-separator" +widget_class "*...*." style "clearlooks-toolExpanderBox" + +widget "*.partialPasteHeader.*" style "clearlooks-frame_title" +widget "*.partialPasteHeaderSep" style "clearlooks-partialPasteHeaderSep" +widget "*.histButton" style "clearlooks-histButton" +widget "*.FramelessSpinButton" style "clearlooks-framelessspinbutton" +widget "*.ThresholdSelector" style "clearlooks-thresholdselector" +widget "*.MyExpanderTitle.*" style "clearlooks-expander" +widget "*.MyExpanderTitle" style "clearlooks-expander" +widget "*.ExpanderBox" style "clearlooks-toolFrame" +widget "*.ExpanderBox.*.MyExpanderTitle" style "clearlooks-subexpander" +widget "*.ExpanderBox.*.MyExpanderTitle.*" style "clearlooks-subexpander" +widget "*.AxisAdjuster" style "clearlooks-axisadjuster" + +# The window of the tooltip is called "gtk-tooltip" +################################################################## +# FIXME: +# This will not work if one embeds eg. a button into the tooltip. +# As far as I can tell right now we will need to rework the theme +# quite a bit to get this working correctly. +# (It will involve setting different priorities, etc.) +################################################################## +widget "gtk-tooltip*" style "clearlooks-tooltips" + +gtk-icon-theme-name="Dark" diff --git a/rtdata/themes/21-Gray-Purple.iconset b/rtdata/themes/21-Gray-Purple.iconset new file mode 100644 index 000000000..99ac20640 --- /dev/null +++ b/rtdata/themes/21-Gray-Purple.iconset @@ -0,0 +1,2 @@ +[General] +Iconset=Dark diff --git a/rtdata/themes/21-Gray-Red.gtkrc b/rtdata/themes/21-Gray-Red.gtkrc new file mode 100644 index 000000000..ca5378f40 --- /dev/null +++ b/rtdata/themes/21-Gray-Red.gtkrc @@ -0,0 +1,557 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2011 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 . +# + +# Please keep this gtkrc in sync with the other ones from Clearlooks based themes. + +gtk-color-scheme = "rt_salt_pinch:#800000\nrt_base_color:#1A1A1A\nrt_fg_color:#909090\nrt_tooltip_fg_color:#1A1A1A\nrt_selected_bg_color:#703535\nrt_selected_fg_color:#B0B0B0\nrt_text_color:#828282\nrt_bg_color:#363636\nrt_tooltip_bg_color:#909090\nrt_tool_bg:#252525\nrt_tool_border:#484848" + +style "clearlooks-default" { + xthickness = 1 + ythickness = 1 + + ####################### + # Style Properties + ####################### + GtkButton::child-displacement-x = 1 + GtkButton::child-displacement-y = 1 + GtkButton::default-border = { 0, 0, 0, 0 } + GtkButton::image-spacing = 4 + GtkToolButton::icon-spacing = 4 + + GtkCheckButton::indicator-size = 14 + + GtkPaned::handle-size = 6 + + GtkRange::trough-border = 0 + GtkRange::slider-width = 12 + GtkRange::stepper-size = 16 + + #GtkScale::slider-width = 12 + GtkScale::slider-length = 30 + GtkScale::trough-side-details = 0 + + GtkScrollbar::min-slider-length = 30 + GtkMenuBar::internal-padding = 0 + GtkExpander::expander-size = 12 + GtkExpander::expander-spacing = 2 + GtkToolbar::internal-padding = 1 + GtkTreeView::expander-size = 12 + GtkTreeView::vertical-separator = 1 + + GtkMenu::horizontal-padding = 0 + GtkMenu::vertical-padding = 0 + + WnckTasklist::fade-overlay-rect = 0 + # The following line hints to gecko (and possibly other appliations) + # that the entry should be drawn transparently on the canvas. + # Without this, gecko will fill in the background of the entry. + GtkEntry::honors-transparent-bg-hint = 1 + + GtkEntry::progress-border = { 2, 2, 2, 2 } + + #################### + # Color Definitions + #################### + bg[NORMAL] = @rt_bg_color + bg[PRELIGHT] = shade (1.02, @rt_bg_color) + bg[SELECTED] = @rt_selected_bg_color + bg[INSENSITIVE] = @rt_bg_color + bg[ACTIVE] = shade (0.9, @rt_bg_color) + + fg[NORMAL] = @rt_fg_color + fg[PRELIGHT] = @rt_fg_color + fg[SELECTED] = @rt_selected_fg_color + fg[INSENSITIVE] = mix (0.2, @rt_fg_color, @rt_bg_color) + fg[ACTIVE] = @rt_fg_color + + text[NORMAL] = @rt_text_color + text[PRELIGHT] = @rt_text_color + text[SELECTED] = @rt_selected_fg_color + text[INSENSITIVE] = darker (@rt_bg_color) + text[ACTIVE] = @rt_selected_fg_color + + base[NORMAL] = @rt_base_color + base[PRELIGHT] = shade (0.95, @rt_bg_color) + base[SELECTED] = @rt_selected_bg_color + base[INSENSITIVE] = @rt_bg_color + base[ACTIVE] = shade (0.9, @rt_selected_bg_color) + + engine "clearlooks" { + colorize_scrollbar = TRUE + reliefstyle = 1 + menubarstyle = 2 + toolbarstyle = 1 + animation = FALSE + radius = 3.0 + # style between CLASSIC, GLOSSY, INVERTED and GUMMY + style = GUMMY + + # Set a hint to disable backward compatibility fallbacks. + hint = "use-hints" + } +} + +style "wide" { + xthickness = 2 + ythickness = 2 +} + +style "wider" { + xthickness = 3 + ythickness = 3 +} + +style "clearlooks-entry" { + xthickness = 3 + ythickness = 3 + + bg[SELECTED] = mix (1.4, @rt_selected_bg_color, @rt_base_color) + fg[SELECTED] = @rt_selected_fg_color + + engine "clearlooks" { + focus_color = shade (0.65, @rt_selected_bg_color) + } +} + +style "clearlooks-paned" { + + bg[PRELIGHT] = shade (0.8, @rt_bg_color) + + engine "clearlooks" { + hint = "paned" + } +} + +style "clearlooks-HSV" { + + engine "clearlooks" { + hint = "HSV" + disable_focus = TRUE + } +} + +style "clearlooks-spinbutton" { + + engine "clearlooks" { + hint = "spinbutton" + } +} + +style "clearlooks-axisadjuster" = "clearlooks-spinbutton" { + # background + base[INSENSITIVE] = @rt_tool_bg + # text + text[INSENSITIVE] = @rt_fg_color +} + +style "clearlooks-framelessspinbutton" { + + # IMPORTANT! + # base[NORMAL] must have the same color than clearlooks.toolContainer / bg[NORMAL] + base[NORMAL] = @rt_tool_bg + base[INSENSITIVE] = @rt_tool_bg + bg[NORMAL] = @rt_tool_bg + bg[INSENSITIVE] = @rt_tool_bg +} + +style "clearlooks-scale" { + xthickness = 2 + ythickness = 2 + + bg[NORMAL] = shade (1.35, @rt_bg_color) + bg[PRELIGHT] = shade (1.70, @rt_bg_color) + # when GtkScale::trough-side-details = 1, bg[SELECTED] set the color of the slider background on the left of the knob + #bg[SELECTED] = @rt_bg_color + + engine "clearlooks" { + focus_color = @rt_selected_bg_color + hint = "scale" + } +} + +style "clearlooks-thresholdselector" { + xthickness = 6 + ythickness = 6 + + bg[NORMAL] = @rt_tool_bg + bg[ACTIVE] = shade (1.45, @rt_bg_color) + bg[PRELIGHT] = shade (1.70, @rt_bg_color) + bg[SELECTED] = shade (2.00, @rt_bg_color) + + fg[PRELIGHT] = shade (1.30, @rt_fg_color) +} + +style "clearlooks-vscale" { + + engine "clearlooks" { + hint = "vscale" + } +} + +style "clearlooks-hscale" { + + engine "clearlooks" { + hint = "hscale" + } +} + +style "clearlooks-scrollbar" { + xthickness = 2 + ythickness = 2 + + bg[SELECTED] = shade (1.50, @rt_bg_color) + + engine "clearlooks" { + hint = "scrollbar" + } +} + +style "clearlooks-hscrollbar" { + + engine "clearlooks" { + hint = "hscrollbar" + } +} + +style "clearlooks-vscrollbar" { + + engine "clearlooks" { + hint = "vscrollbar" + } +} + +style "clearlooks-notebook_bg" { + + bg[NORMAL] = shade (1.02, @rt_bg_color) + bg[ACTIVE] = @rt_base_color +} + +style "clearlooks-toolContainer" { + xthickness = 0 + ythickness = 0 + + # IMPORTANT! + # If you modify bg[NORMAL] below, you must set clearlooks-framelessspinbutton -> base[NORMAL] to the very same value + bg[NORMAL] = @rt_tool_bg + bg[INSENSITIVE] = @rt_tool_bg +} + +style "clearlooks-separator" { + bg[NORMAL] = shade(0.85, @rt_bg_color) + bg[INSENSITIVE] = shade(0.85, @rt_bg_color) +} + +style "clearlooks-frame" { + bg[NORMAL] = shade(0.85, @rt_bg_color) + bg[INSENSITIVE] = shade(0.85, @rt_bg_color) +} + +style "clearlooks-toolFrame" = "clearlooks-toolContainer" { + bg[NORMAL] = @rt_tool_bg + + fg[NORMAL] = @rt_tool_border + fg[INSENSITIVE] = mix(0.5, @rt_bg_color, @rt_tool_border) +} + +style "clearlooks-toolExpanderBox" { + bg[NORMAL] = @rt_tool_bg + bg[INSENSITIVE] = @rt_tool_bg +} + +style "clearlooks-combobox" { + + text[NORMAL] = @rt_fg_color + text[PRELIGHT] = shade(1.15, @rt_fg_color) + text[SELECTED] = @rt_selected_fg_color + text[INSENSITIVE] = mix (0.2, @rt_fg_color, @rt_bg_color) + text[ACTIVE] = @rt_fg_color +} + +style "clearlooks-button" { + + bg[NORMAL] = shade (1.20, @rt_bg_color) + bg[PRELIGHT] = shade (1.30, @rt_bg_color) + bg[ACTIVE] = shade (1.90, @rt_bg_color) + + fg[NORMAL] = @rt_fg_color + fg[PRELIGHT] = shade(1.15, @rt_fg_color) + fg[SELECTED] = @rt_selected_fg_color + fg[INSENSITIVE] = mix (0.2, @rt_fg_color, @rt_bg_color) + fg[ACTIVE] = @rt_fg_color + + engine "clearlooks" + { + hint = "button" + } +} + +style "clearlooks-histButton" { + + GtkButton::child-displacement-x = 0 + GtkButton::child-displacement-y = 0 +} + +# The color is changed by the notebook_bg style, this style +# changes the x/ythickness +style "clearlooks-notebook" { + xthickness = 3 + ythickness = 3 + + bg[SELECTED] = @rt_salt_pinch +} + +style "clearlooks-statusbar" { + + engine "clearlooks" { + hint = "statusbar" + } +} + +style "clearlooks-comboboxentry" { + + engine "clearlooks" { + # Note: + # If you set the appears-as-list option on comboboxes in the theme, + # then you should set this hint on the combobox instead. + hint = "comboboxentry" + } +} + +style "clearlooks-expander" { + xthickness = 3 + ythickness = 3 + + fg[NORMAL] = "#a0a0a0" + fg[PRELIGHT] = "#d0d0d0" + fg[INSENSITIVE] = "#808080" + + bg[PRELIGHT] = mix(0.8, @rt_selected_bg_color, @rt_bg_color) + + base[NORMAL] = @rt_salt_pinch + base[PRELIGHT] = @rt_salt_pinch + base[INSENSITIVE] = @rt_salt_pinch +} + +style "clearlooks-subexpander" = "clearlooks-expander"{ + bg[NORMAL] = @rt_tool_bg +} + +style "clearlooks-menubar" { + + engine "clearlooks" { + hint = "menubar" + } +} + +style "clearlooks-menu" { + xthickness = 0 + ythickness = 0 + + bg[NORMAL] = @rt_base_color + + engine "clearlooks" { + radius = 0.0 + } +} + +style "clearlooks-menu_item" { + xthickness = 2 + ythickness = 3 + + fg[PRELIGHT] = @rt_selected_fg_color + text[NORMAL] = @rt_fg_color + text[PRELIGHT] = @rt_selected_fg_color +} + +# This style is there to modify the separator menu items. The goals are: +# 1. Get a specific height. +# 2. The line should go to the edges (ie. no border at the left/right) +style "clearlooks-separator_menu_item" { + xthickness = 1 + ythickness = 0 + + GtkSeparatorMenuItem::horizontal-padding = 0 + GtkWidget::wide-separators = 1 + GtkWidget::separator-width = 1 + GtkWidget::separator-height = 7 +} + +style "clearlooks-frame_title" { + + fg[NORMAL] = lighter (@rt_fg_color) + fg[PRELIGHT] = lighter (@rt_fg_color) + fg[ACTIVE] = lighter (@rt_fg_color) + fg[SELECTED] = lighter (@rt_fg_color) +} + +style "clearlooks-partialPasteHeaderSep" { + + bg[NORMAL] = mix (0.20, @rt_fg_color, @rt_bg_color) +} + +style "clearlooks-checkbutton" { + + text[NORMAL] = @rt_selected_fg_color + + fg[PRELIGHT] = @rt_fg_color + + bg[SELECTED] = @rt_base_color + bg[PRELIGHT] = @rt_base_color + bg[SELECTED] = @rt_base_color + + engine "clearlooks" + { + hint = "checkbutton" + } +} + +style "clearlooks-treeview" { + + base[ACTIVE] = mix(0.50, @rt_selected_bg_color, @rt_base_color) + + engine "clearlooks" { + hint = "treeview" + } +} + +# The almost useless progress bar style +style "clearlooks-progressbar" { + xthickness = 1 + ythickness = 1 + + fg[PRELIGHT] = @rt_selected_fg_color + + engine "clearlooks" { + # Explicitly set the radius for the progress bars inside menu items. + radius = 3.0 + + hint = "progressbar" + } +} + +# This style is based on the clearlooks-default style, so that the colors from the button +# style are overriden again. +style "clearlooks-treeview_header" = "clearlooks-default" { + xthickness = 2 + ythickness = 1 + + bg[NORMAL] = shade (0.80, @rt_bg_color) + + engine "clearlooks" { + radius = 0.0 + hint = "treeview-header" + } +} + +style "clearlooks-tooltips" { + xthickness = 4 + ythickness = 4 + + bg[NORMAL] = @rt_tooltip_bg_color + fg[NORMAL] = @rt_tooltip_fg_color +} + +############################################################################### +# The following part of the gtkrc applies the different styles to the widgets. +############################################################################### + +# The clearlooks-default style is applied to every widget +class "GtkWidget" style "clearlooks-default" + +class "GtkSeparator" style "wide" +class "GtkFrame" style "wide" +class "GtkCalendar" style "wide" +class "GtkCheckButton" style "wider" +class "GtkRadioButton" style "wider" +class "GtkEntry" style "clearlooks-entry" + +class "GtkPaned" style "clearlooks-paned" +class "GtkSpinButton" style "clearlooks-spinbutton" +class "GtkScale" style "clearlooks-scale" +class "GtkVScale" style "clearlooks-vscale" +class "GtkHScale" style "clearlooks-hscale" +class "GtkScrollbar" style "clearlooks-scrollbar" +class "GtkHScrollbar" style "clearlooks-hscrollbar" +class "GtkVScrollbar" style "clearlooks-vscrollbar" + +class "GtkHSV" style "clearlooks-HSV" + +# General matching follows. The order is choosen so that the right styles override +# each other. EG. progressbar needs to be more important than the menu match. +widget_class "*" style "clearlooks-notebook_bg" +# This is not perfect, it could be done better. +# (That is modify *every* widget in the notebook, and change those back that +# we really don't want changed) +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" + +widget_class "*." style "clearlooks-combobox" +widget_class "**" style "clearlooks-button" +widget_class "*" style "clearlooks-notebook" +widget_class "**" style "clearlooks-statusbar" + +#widget_class "**" style "clearlooks-comboboxentry" +widget_class "**" style "clearlooks-combobox" + +widget_class "**" style "clearlooks-checkbutton" +widget_class "**" style "clearlooks-menubar" +widget_class "**" style "clearlooks-menu" +widget_class "**" style "clearlooks-menu_item" +widget_class "**" style "clearlooks-separator_menu_item" + +widget_class "*." style "clearlooks-frame" +widget_class "*.." style "clearlooks-frame_title" +widget_class "*.*" style "clearlooks-treeview" + +widget_class "*" style "clearlooks-progressbar" + +# Treeview headers (and similar stock GTK+ widgets) +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*...*." style "clearlooks-separator" +widget_class "*...*." style "clearlooks-toolExpanderBox" + +widget "*.partialPasteHeader.*" style "clearlooks-frame_title" +widget "*.partialPasteHeaderSep" style "clearlooks-partialPasteHeaderSep" +widget "*.histButton" style "clearlooks-histButton" +widget "*.FramelessSpinButton" style "clearlooks-framelessspinbutton" +widget "*.ThresholdSelector" style "clearlooks-thresholdselector" +widget "*.MyExpanderTitle.*" style "clearlooks-expander" +widget "*.MyExpanderTitle" style "clearlooks-expander" +widget "*.ExpanderBox" style "clearlooks-toolFrame" +widget "*.ExpanderBox.*.MyExpanderTitle" style "clearlooks-subexpander" +widget "*.ExpanderBox.*.MyExpanderTitle.*" style "clearlooks-subexpander" +widget "*.AxisAdjuster" style "clearlooks-axisadjuster" + +# The window of the tooltip is called "gtk-tooltip" +################################################################## +# FIXME: +# This will not work if one embeds eg. a button into the tooltip. +# As far as I can tell right now we will need to rework the theme +# quite a bit to get this working correctly. +# (It will involve setting different priorities, etc.) +################################################################## +widget "gtk-tooltip*" style "clearlooks-tooltips" + +gtk-icon-theme-name="Dark" diff --git a/rtdata/themes/21-Gray-Red.iconset b/rtdata/themes/21-Gray-Red.iconset new file mode 100644 index 000000000..99ac20640 --- /dev/null +++ b/rtdata/themes/21-Gray-Red.iconset @@ -0,0 +1,2 @@ +[General] +Iconset=Dark diff --git a/rtdata/themes/25-Gray-Gray.gtkrc b/rtdata/themes/25-Gray-Gray.gtkrc new file mode 100644 index 000000000..13372eb2a --- /dev/null +++ b/rtdata/themes/25-Gray-Gray.gtkrc @@ -0,0 +1,557 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2011 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 . +# + +# Please keep this gtkrc in sync with the other ones from Clearlooks based themes. + +gtk-color-scheme = "rt_salt_pinch:#606060\nrt_base_color:#525252\nrt_fg_color:#979797\nrt_tooltip_fg_color:#A0A0A0\nrt_selected_bg_color:#606060\nrt_selected_fg_color:#CDCDCD\nrt_text_color:#A2A2A2\nrt_bg_color:#404040\nrt_tooltip_bg_color:#252525\nrt_tool_bg:#3B3B3B\nrt_tool_border:#4D4D4D" + +style "clearlooks-default" { + xthickness = 1 + ythickness = 1 + + ####################### + # Style Properties + ####################### + GtkButton::child-displacement-x = 1 + GtkButton::child-displacement-y = 1 + GtkButton::default-border = { 0, 0, 0, 0 } + GtkButton::image-spacing = 4 + GtkToolButton::icon-spacing = 4 + + GtkCheckButton::indicator-size = 14 + + GtkPaned::handle-size = 6 + + GtkRange::trough-border = 0 + GtkRange::slider-width = 15 + GtkRange::stepper-size = 15 + + GtkScale::slider-width = 14 + GtkScale::slider-length = 30 + GtkScale::trough-side-details = 0 + + GtkScrollbar::min-slider-length = 30 + GtkMenuBar::internal-padding = 0 + GtkExpander::expander-size = 12 + GtkExpander::expander-spacing = 2 + GtkToolbar::internal-padding = 1 + GtkTreeView::expander-size = 12 + GtkTreeView::vertical-separator = 0 + + GtkMenu::horizontal-padding = 0 + GtkMenu::vertical-padding = 0 + + WnckTasklist::fade-overlay-rect = 0 + # The following line hints to gecko (and possibly other appliations) + # that the entry should be drawn transparently on the canvas. + # Without this, gecko will fill in the background of the entry. + GtkEntry::honors-transparent-bg-hint = 1 + + GtkEntry::progress-border = { 2, 2, 2, 2 } + + #################### + # Color Definitions + #################### + bg[NORMAL] = @rt_bg_color + bg[PRELIGHT] = shade (1.02, @rt_bg_color) + bg[SELECTED] = @rt_selected_bg_color + bg[INSENSITIVE] = @rt_bg_color + bg[ACTIVE] = shade (0.9, @rt_bg_color) + + fg[NORMAL] = @rt_fg_color + fg[PRELIGHT] = @rt_fg_color + fg[SELECTED] = @rt_selected_fg_color + fg[INSENSITIVE] = mix (0.2, @rt_fg_color, @rt_bg_color) + fg[ACTIVE] = @rt_fg_color + + text[NORMAL] = @rt_text_color + text[PRELIGHT] = @rt_text_color + text[SELECTED] = @rt_selected_fg_color + text[INSENSITIVE] = darker (@rt_bg_color) + text[ACTIVE] = @rt_selected_fg_color + + base[NORMAL] = @rt_base_color + base[PRELIGHT] = shade (0.95, @rt_bg_color) + base[SELECTED] = @rt_selected_bg_color + base[INSENSITIVE] = @rt_bg_color + base[ACTIVE] = shade (0.9, @rt_selected_bg_color) + + engine "clearlooks" { + colorize_scrollbar = TRUE + reliefstyle = 1 + menubarstyle = 2 + toolbarstyle = 1 + animation = FALSE + radius = 3.0 + # style between CLASSIC, GLOSSY, INVERTED and GUMMY + style = GUMMY + + # Set a hint to disable backward compatibility fallbacks. + hint = "use-hints" + } +} + +style "wide" { + xthickness = 2 + ythickness = 2 +} + +style "wider" { + xthickness = 3 + ythickness = 3 +} + +style "clearlooks-entry" { + xthickness = 3 + ythickness = 3 + + bg[SELECTED] = mix (1.4, @rt_selected_bg_color, @rt_base_color) + fg[SELECTED] = @rt_selected_fg_color + + engine "clearlooks" { + focus_color = shade (0.65, @rt_selected_bg_color) + } +} + +style "clearlooks-paned" { + + bg[PRELIGHT] = shade (0.9, @rt_bg_color) + + engine "clearlooks" { + hint = "paned" + } +} + +style "clearlooks-HSV" { + + engine "clearlooks" { + hint = "HSV" + disable_focus = TRUE + } +} + +style "clearlooks-spinbutton" { + + engine "clearlooks" { + hint = "spinbutton" + } +} + +style "clearlooks-axisadjuster" = "clearlooks-spinbutton" { + # background + base[INSENSITIVE] = @rt_tool_bg + # text + text[INSENSITIVE] = @rt_fg_color +} + +style "clearlooks-framelessspinbutton" { + + # IMPORTANT! + # base[NORMAL] must have the same color than clearlooks.toolContainer / bg[NORMAL] + base[NORMAL] = @rt_tool_bg + base[INSENSITIVE] = @rt_tool_bg + bg[NORMAL] = @rt_tool_bg + bg[INSENSITIVE] = @rt_tool_bg +} + +style "clearlooks-scale" { + xthickness = 2 + ythickness = 2 + + bg[NORMAL] = shade (1.35, @rt_bg_color) + bg[PRELIGHT] = shade (1.70, @rt_bg_color) + # when GtkScale::trough-side-details = 1, bg[SELECTED] set the color of the slider background on the left of the knob + #bg[SELECTED] = @rt_bg_color + + engine "clearlooks" { + focus_color = @rt_selected_bg_color + hint = "scale" + } +} + +style "clearlooks-thresholdselector" { + xthickness = 6 + ythickness = 6 + + bg[NORMAL] = @rt_tool_bg + bg[ACTIVE] = shade (1.45, @rt_bg_color) + bg[PRELIGHT] = shade (1.70, @rt_bg_color) + bg[SELECTED] = shade (2.00, @rt_bg_color) + + fg[PRELIGHT] = shade (1.30, @rt_fg_color) +} + +style "clearlooks-vscale" { + + engine "clearlooks" { + hint = "vscale" + } +} + +style "clearlooks-hscale" { + + engine "clearlooks" { + hint = "hscale" + } +} + +style "clearlooks-scrollbar" { + xthickness = 2 + ythickness = 2 + + bg[SELECTED] = shade (1.25, @rt_bg_color) + + engine "clearlooks" { + hint = "scrollbar" + } +} + +style "clearlooks-hscrollbar" { + + engine "clearlooks" { + hint = "hscrollbar" + } +} + +style "clearlooks-vscrollbar" { + + engine "clearlooks" { + hint = "vscrollbar" + } +} + +style "clearlooks-notebook_bg" { + + bg[NORMAL] = shade (1.02, @rt_bg_color) + bg[ACTIVE] = shade (0.80, @rt_bg_color) +} + +style "clearlooks-toolContainer" { + xthickness = 0 + ythickness = 0 + + # IMPORTANT! + # If you modify bg[NORMAL] below, you must set clearlooks-framelessspinbutton -> base[NORMAL] to the very same value + bg[NORMAL] = @rt_tool_bg + bg[INSENSITIVE] = @rt_tool_bg +} + +style "clearlooks-separator" { + bg[NORMAL] = mix(0.85, @rt_tool_bg, @rt_tool_border) + bg[INSENSITIVE] = mix(0.60, @rt_tool_bg, @rt_tool_border) +} + +style "clearlooks-frame" { + bg[NORMAL] = mix(0.85, @rt_tool_bg, @rt_tool_border) + bg[INSENSITIVE] = mix(0.60, @rt_tool_bg, @rt_tool_border) +} + +style "clearlooks-toolFrame" = "clearlooks-toolContainer" { + bg[NORMAL] = @rt_tool_bg + + fg[NORMAL] = @rt_tool_border + fg[INSENSITIVE] = mix(0.5, @rt_bg_color, @rt_tool_border) +} + +style "clearlooks-toolExpanderBox" { + bg[NORMAL] = @rt_tool_bg + bg[INSENSITIVE] = @rt_tool_bg +} + +style "clearlooks-combobox" { + + text[NORMAL] = @rt_fg_color + text[PRELIGHT] = shade(1.15, @rt_fg_color) + text[SELECTED] = @rt_selected_fg_color + text[INSENSITIVE] = mix (0.2, @rt_fg_color, @rt_bg_color) + text[ACTIVE] = @rt_fg_color +} + +style "clearlooks-button" { + + bg[NORMAL] = shade (0.93, @rt_tool_bg) + bg[PRELIGHT] = shade (0.85, @rt_tool_bg) + bg[ACTIVE] = shade (0.70, @rt_tool_bg) + + fg[NORMAL] = @rt_fg_color + fg[PRELIGHT] = shade(1.15, @rt_fg_color) + fg[SELECTED] = @rt_selected_fg_color + fg[INSENSITIVE] = mix (0.2, @rt_fg_color, @rt_bg_color) + fg[ACTIVE] = @rt_fg_color + + engine "clearlooks" + { + hint = "button" + } +} + +style "clearlooks-histButton" { + + GtkButton::child-displacement-x = 0 + GtkButton::child-displacement-y = 0 +} + +# The color is changed by the notebook_bg style, this style +# changes the x/ythickness +style "clearlooks-notebook" { + xthickness = 3 + ythickness = 3 + + bg[SELECTED] = @rt_salt_pinch +} + +style "clearlooks-statusbar" { + + engine "clearlooks" { + hint = "statusbar" + } +} + +style "clearlooks-comboboxentry" { + + engine "clearlooks" { + # Note: + # If you set the appears-as-list option on comboboxes in the theme, + # then you should set this hint on the combobox instead. + hint = "comboboxentry" + } +} + +style "clearlooks-expander" { + xthickness = 3 + ythickness = 3 + + fg[NORMAL] = "#a0a0a0" + fg[PRELIGHT] = "#d0d0d0" + fg[INSENSITIVE] = "#808080" + + bg[PRELIGHT] = mix(0.75, @rt_selected_bg_color, @rt_bg_color) + + base[NORMAL] = @rt_salt_pinch + base[PRELIGHT] = @rt_salt_pinch + base[INSENSITIVE] = @rt_salt_pinch +} + +style "clearlooks-subexpander" = "clearlooks-expander"{ + bg[NORMAL] = @rt_tool_bg +} + +style "clearlooks-menubar" { + + engine "clearlooks" { + hint = "menubar" + } +} + +style "clearlooks-menu" { + xthickness = 0 + ythickness = 0 + + bg[NORMAL] = shade (0.70, @rt_bg_color) + + engine "clearlooks" { + radius = 0.0 + } +} + +style "clearlooks-menu_item" { + xthickness = 2 + ythickness = 3 + + fg[PRELIGHT] = @rt_selected_fg_color + text[NORMAL] = @rt_fg_color + text[PRELIGHT] = @rt_selected_fg_color +} + +# This style is there to modify the separator menu items. The goals are: +# 1. Get a specific height. +# 2. The line should go to the edges (ie. no border at the left/right) +style "clearlooks-separator_menu_item" { + xthickness = 1 + ythickness = 0 + + GtkSeparatorMenuItem::horizontal-padding = 0 + GtkWidget::wide-separators = 1 + GtkWidget::separator-width = 1 + GtkWidget::separator-height = 7 +} + +style "clearlooks-frame_title" { + + fg[NORMAL] = lighter (@rt_fg_color) + fg[PRELIGHT] = lighter (@rt_fg_color) + fg[ACTIVE] = lighter (@rt_fg_color) + fg[SELECTED] = lighter (@rt_fg_color) +} + +style "clearlooks-partialPasteHeaderSep" { + + bg[NORMAL] = mix (0.25, @rt_fg_color, @rt_bg_color) +} + +style "clearlooks-checkbutton" { + + text[NORMAL] = @rt_selected_fg_color + + fg[PRELIGHT] = @rt_fg_color + + bg[SELECTED] = @rt_base_color + bg[PRELIGHT] = @rt_base_color + bg[SELECTED] = @rt_base_color + + engine "clearlooks" + { + hint = "checkbutton" + } +} + +style "clearlooks-treeview" { + + base[ACTIVE] = mix(0.50, @rt_selected_bg_color, @rt_base_color) + + engine "clearlooks" { + hint = "treeview" + } +} + +# The almost useless progress bar style +style "clearlooks-progressbar" { + xthickness = 1 + ythickness = 1 + + fg[PRELIGHT] = @rt_selected_fg_color + + engine "clearlooks" { + # Explicitly set the radius for the progress bars inside menu items. + radius = 3.0 + + hint = "progressbar" + } +} + +# This style is based on the clearlooks-default style, so that the colors from the button +# style are overriden again. +style "clearlooks-treeview_header" = "clearlooks-default" { + xthickness = 2 + ythickness = 1 + + bg[NORMAL] = shade (0.80, @rt_bg_color) + + engine "clearlooks" { + radius = 0.0 + hint = "treeview-header" + } +} + +style "clearlooks-tooltips" { + xthickness = 4 + ythickness = 4 + + bg[NORMAL] = @rt_tooltip_bg_color + fg[NORMAL] = @rt_tooltip_fg_color +} + +############################################################################### +# The following part of the gtkrc applies the different styles to the widgets. +############################################################################### + +# The clearlooks-default style is applied to every widget +class "GtkWidget" style "clearlooks-default" + +class "GtkSeparator" style "wide" +class "GtkFrame" style "wide" +class "GtkCalendar" style "wide" +class "GtkCheckButton" style "wider" +class "GtkRadioButton" style "wider" +class "GtkEntry" style "clearlooks-entry" + +class "GtkPaned" style "clearlooks-paned" +class "GtkSpinButton" style "clearlooks-spinbutton" +class "GtkScale" style "clearlooks-scale" +class "GtkVScale" style "clearlooks-vscale" +class "GtkHScale" style "clearlooks-hscale" +class "GtkScrollbar" style "clearlooks-scrollbar" +class "GtkHScrollbar" style "clearlooks-hscrollbar" +class "GtkVScrollbar" style "clearlooks-vscrollbar" + +class "GtkHSV" style "clearlooks-HSV" + +# General matching follows. The order is choosen so that the right styles override +# each other. EG. progressbar needs to be more important than the menu match. +widget_class "*" style "clearlooks-notebook_bg" +# This is not perfect, it could be done better. +# (That is modify *every* widget in the notebook, and change those back that +# we really don't want changed) +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" + +widget_class "*." style "clearlooks-combobox" +widget_class "**" style "clearlooks-button" +widget_class "*" style "clearlooks-notebook" +widget_class "**" style "clearlooks-statusbar" + +#widget_class "**" style "clearlooks-comboboxentry" +widget_class "**" style "clearlooks-combobox" + +widget_class "**" style "clearlooks-checkbutton" +widget_class "**" style "clearlooks-menubar" +widget_class "**" style "clearlooks-menu" +widget_class "**" style "clearlooks-menu_item" +widget_class "**" style "clearlooks-separator_menu_item" + +widget_class "*." style "clearlooks-frame" +widget_class "*.." style "clearlooks-frame_title" +widget_class "*.*" style "clearlooks-treeview" + +widget_class "*" style "clearlooks-progressbar" + +# Treeview headers (and similar stock GTK+ widgets) +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*...*." style "clearlooks-separator" +widget_class "*...*." style "clearlooks-toolExpanderBox" + +widget "*.partialPasteHeader.*" style "clearlooks-frame_title" +widget "*.partialPasteHeaderSep" style "clearlooks-partialPasteHeaderSep" +widget "*.histButton" style "clearlooks-histButton" +widget "*.FramelessSpinButton" style "clearlooks-framelessspinbutton" +widget "*.ThresholdSelector" style "clearlooks-thresholdselector" +widget "*.MyExpanderTitle.*" style "clearlooks-expander" +widget "*.MyExpanderTitle" style "clearlooks-expander" +widget "*.ExpanderBox" style "clearlooks-toolFrame" +widget "*.ExpanderBox.*.MyExpanderTitle" style "clearlooks-subexpander" +widget "*.ExpanderBox.*.MyExpanderTitle.*" style "clearlooks-subexpander" +widget "*.AxisAdjuster" style "clearlooks-axisadjuster" + +# The window of the tooltip is called "gtk-tooltip" +################################################################## +# FIXME: +# This will not work if one embeds eg. a button into the tooltip. +# As far as I can tell right now we will need to rework the theme +# quite a bit to get this working correctly. +# (It will involve setting different priorities, etc.) +################################################################## +widget "gtk-tooltip*" style "clearlooks-tooltips" + +gtk-icon-theme-name="Dark" diff --git a/rtdata/themes/25-Gray-Gray.iconset b/rtdata/themes/25-Gray-Gray.iconset new file mode 100644 index 000000000..99ac20640 --- /dev/null +++ b/rtdata/themes/25-Gray-Gray.iconset @@ -0,0 +1,2 @@ +[General] +Iconset=Dark diff --git a/rtdata/themes/25-Gray-Purple.gtkrc b/rtdata/themes/25-Gray-Purple.gtkrc new file mode 100644 index 000000000..79ae82175 --- /dev/null +++ b/rtdata/themes/25-Gray-Purple.gtkrc @@ -0,0 +1,557 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2011 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 . +# + +# Please keep this gtkrc in sync with the other ones from Clearlooks based themes. + +gtk-color-scheme = "rt_salt_pinch:#843382\nrt_base_color:#525252\nrt_fg_color:#979797\nrt_tooltip_fg_color:#A0A0A0\nrt_selected_bg_color:#5D235C\nrt_selected_fg_color:#CDCDCD\nrt_text_color:#A2A2A2\nrt_bg_color:#404040\nrt_tooltip_bg_color:#252525\nrt_tool_bg:#3B3B3B\nrt_tool_border:#4D4D4D" + +style "clearlooks-default" { + xthickness = 1 + ythickness = 1 + + ####################### + # Style Properties + ####################### + GtkButton::child-displacement-x = 1 + GtkButton::child-displacement-y = 1 + GtkButton::default-border = { 0, 0, 0, 0 } + GtkButton::image-spacing = 4 + GtkToolButton::icon-spacing = 4 + + GtkCheckButton::indicator-size = 14 + + GtkPaned::handle-size = 6 + + GtkRange::trough-border = 0 + GtkRange::slider-width = 15 + GtkRange::stepper-size = 15 + + GtkScale::slider-width = 14 + GtkScale::slider-length = 30 + GtkScale::trough-side-details = 0 + + GtkScrollbar::min-slider-length = 30 + GtkMenuBar::internal-padding = 0 + GtkExpander::expander-size = 12 + GtkExpander::expander-spacing = 2 + GtkToolbar::internal-padding = 1 + GtkTreeView::expander-size = 12 + GtkTreeView::vertical-separator = 0 + + GtkMenu::horizontal-padding = 0 + GtkMenu::vertical-padding = 0 + + WnckTasklist::fade-overlay-rect = 0 + # The following line hints to gecko (and possibly other appliations) + # that the entry should be drawn transparently on the canvas. + # Without this, gecko will fill in the background of the entry. + GtkEntry::honors-transparent-bg-hint = 1 + + GtkEntry::progress-border = { 2, 2, 2, 2 } + + #################### + # Color Definitions + #################### + bg[NORMAL] = @rt_bg_color + bg[PRELIGHT] = shade (1.02, @rt_bg_color) + bg[SELECTED] = @rt_selected_bg_color + bg[INSENSITIVE] = @rt_bg_color + bg[ACTIVE] = shade (0.9, @rt_bg_color) + + fg[NORMAL] = @rt_fg_color + fg[PRELIGHT] = @rt_fg_color + fg[SELECTED] = @rt_selected_fg_color + fg[INSENSITIVE] = mix (0.2, @rt_fg_color, @rt_bg_color) + fg[ACTIVE] = @rt_fg_color + + text[NORMAL] = @rt_text_color + text[PRELIGHT] = @rt_text_color + text[SELECTED] = @rt_selected_fg_color + text[INSENSITIVE] = darker (@rt_bg_color) + text[ACTIVE] = @rt_selected_fg_color + + base[NORMAL] = @rt_base_color + base[PRELIGHT] = shade (0.95, @rt_bg_color) + base[SELECTED] = @rt_selected_bg_color + base[INSENSITIVE] = @rt_bg_color + base[ACTIVE] = shade (0.9, @rt_selected_bg_color) + + engine "clearlooks" { + colorize_scrollbar = TRUE + reliefstyle = 1 + menubarstyle = 2 + toolbarstyle = 1 + animation = FALSE + radius = 3.0 + # style between CLASSIC, GLOSSY, INVERTED and GUMMY + style = GUMMY + + # Set a hint to disable backward compatibility fallbacks. + hint = "use-hints" + } +} + +style "wide" { + xthickness = 2 + ythickness = 2 +} + +style "wider" { + xthickness = 3 + ythickness = 3 +} + +style "clearlooks-entry" { + xthickness = 3 + ythickness = 3 + + bg[SELECTED] = mix (1.4, @rt_selected_bg_color, @rt_base_color) + fg[SELECTED] = @rt_selected_fg_color + + engine "clearlooks" { + focus_color = shade (0.65, @rt_selected_bg_color) + } +} + +style "clearlooks-paned" { + + bg[PRELIGHT] = shade (0.9, @rt_bg_color) + + engine "clearlooks" { + hint = "paned" + } +} + +style "clearlooks-HSV" { + + engine "clearlooks" { + hint = "HSV" + disable_focus = TRUE + } +} + +style "clearlooks-spinbutton" { + + engine "clearlooks" { + hint = "spinbutton" + } +} + +style "clearlooks-axisadjuster" = "clearlooks-spinbutton" { + # background + base[INSENSITIVE] = @rt_tool_bg + # text + text[INSENSITIVE] = @rt_fg_color +} + +style "clearlooks-framelessspinbutton" { + + # IMPORTANT! + # base[NORMAL] must have the same color than clearlooks.toolContainer / bg[NORMAL] + base[NORMAL] = @rt_tool_bg + base[INSENSITIVE] = @rt_tool_bg + bg[NORMAL] = @rt_tool_bg + bg[INSENSITIVE] = @rt_tool_bg +} + +style "clearlooks-scale" { + xthickness = 2 + ythickness = 2 + + bg[NORMAL] = shade (1.30, @rt_bg_color) + bg[PRELIGHT] = shade (1.40, @rt_bg_color) + # when GtkScale::trough-side-details = 1, bg[SELECTED] set the color of the slider background on the left of the knob + #bg[SELECTED] = @rt_bg_color + + engine "clearlooks" { + focus_color = @rt_selected_bg_color + hint = "scale" + } +} + +style "clearlooks-thresholdselector" { + xthickness = 6 + ythickness = 6 + + bg[NORMAL] = @rt_tool_bg + bg[ACTIVE] = shade (1.45, @rt_bg_color) + bg[PRELIGHT] = shade (1.70, @rt_bg_color) + bg[SELECTED] = shade (2.00, @rt_bg_color) + + fg[PRELIGHT] = shade (1.30, @rt_fg_color) +} + +style "clearlooks-vscale" { + + engine "clearlooks" { + hint = "vscale" + } +} + +style "clearlooks-hscale" { + + engine "clearlooks" { + hint = "hscale" + } +} + +style "clearlooks-scrollbar" { + xthickness = 2 + ythickness = 2 + + bg[SELECTED] = shade (1.15, @rt_bg_color) + + engine "clearlooks" { + hint = "scrollbar" + } +} + +style "clearlooks-hscrollbar" { + + engine "clearlooks" { + hint = "hscrollbar" + } +} + +style "clearlooks-vscrollbar" { + + engine "clearlooks" { + hint = "vscrollbar" + } +} + +style "clearlooks-notebook_bg" { + + bg[NORMAL] = shade (1.02, @rt_bg_color) + bg[ACTIVE] = shade (0.80, @rt_bg_color) +} + +style "clearlooks-toolContainer" { + xthickness = 0 + ythickness = 0 + + # IMPORTANT! + # If you modify bg[NORMAL] below, you must set clearlooks-framelessspinbutton -> base[NORMAL] to the very same value + bg[NORMAL] = @rt_tool_bg + bg[INSENSITIVE] = @rt_tool_bg +} + +style "clearlooks-separator" { + bg[NORMAL] = mix(0.85, @rt_tool_bg, @rt_tool_border) + bg[INSENSITIVE] = mix(0.60, @rt_tool_bg, @rt_tool_border) +} + +style "clearlooks-frame" { + bg[NORMAL] = mix(0.85, @rt_tool_bg, @rt_tool_border) + bg[INSENSITIVE] = mix(0.60, @rt_tool_bg, @rt_tool_border) +} + +style "clearlooks-toolFrame" = "clearlooks-toolContainer" { + bg[NORMAL] = @rt_tool_bg + + fg[NORMAL] = @rt_tool_border + fg[INSENSITIVE] = mix(0.5, @rt_bg_color, @rt_tool_border) +} + +style "clearlooks-toolExpanderBox" { + bg[NORMAL] = @rt_tool_bg + bg[INSENSITIVE] = @rt_tool_bg +} + +style "clearlooks-combobox" { + + text[NORMAL] = @rt_fg_color + text[PRELIGHT] = shade(1.15, @rt_fg_color) + text[SELECTED] = @rt_selected_fg_color + text[INSENSITIVE] = mix (0.2, @rt_fg_color, @rt_bg_color) + text[ACTIVE] = @rt_fg_color +} + +style "clearlooks-button" { + + bg[NORMAL] = shade (0.93, @rt_tool_bg) + bg[PRELIGHT] = shade (0.85, @rt_tool_bg) + bg[ACTIVE] = shade (0.70, @rt_tool_bg) + + fg[NORMAL] = @rt_fg_color + fg[PRELIGHT] = shade(1.15, @rt_fg_color) + fg[SELECTED] = @rt_selected_fg_color + fg[INSENSITIVE] = mix (0.2, @rt_fg_color, @rt_bg_color) + fg[ACTIVE] = @rt_fg_color + + engine "clearlooks" + { + hint = "button" + } +} + +style "clearlooks-histButton" { + + GtkButton::child-displacement-x = 0 + GtkButton::child-displacement-y = 0 +} + +# The color is changed by the notebook_bg style, this style +# changes the x/ythickness +style "clearlooks-notebook" { + xthickness = 3 + ythickness = 3 + + bg[SELECTED] = @rt_salt_pinch +} + +style "clearlooks-statusbar" { + + engine "clearlooks" { + hint = "statusbar" + } +} + +style "clearlooks-comboboxentry" { + + engine "clearlooks" { + # Note: + # If you set the appears-as-list option on comboboxes in the theme, + # then you should set this hint on the combobox instead. + hint = "comboboxentry" + } +} + +style "clearlooks-expander" { + xthickness = 3 + ythickness = 3 + + fg[NORMAL] = "#a0a0a0" + fg[PRELIGHT] = "#d0d0d0" + fg[INSENSITIVE] = "#808080" + + bg[PRELIGHT] = mix(0.75, @rt_selected_bg_color, @rt_bg_color) + + base[NORMAL] = @rt_salt_pinch + base[PRELIGHT] = @rt_salt_pinch + base[INSENSITIVE] = @rt_salt_pinch +} + +style "clearlooks-subexpander" = "clearlooks-expander"{ + bg[NORMAL] = @rt_tool_bg +} + +style "clearlooks-menubar" { + + engine "clearlooks" { + hint = "menubar" + } +} + +style "clearlooks-menu" { + xthickness = 0 + ythickness = 0 + + bg[NORMAL] = shade (0.70, @rt_bg_color) + + engine "clearlooks" { + radius = 0.0 + } +} + +style "clearlooks-menu_item" { + xthickness = 2 + ythickness = 3 + + fg[PRELIGHT] = @rt_selected_fg_color + text[NORMAL] = @rt_fg_color + text[PRELIGHT] = @rt_selected_fg_color +} + +# This style is there to modify the separator menu items. The goals are: +# 1. Get a specific height. +# 2. The line should go to the edges (ie. no border at the left/right) +style "clearlooks-separator_menu_item" { + xthickness = 1 + ythickness = 0 + + GtkSeparatorMenuItem::horizontal-padding = 0 + GtkWidget::wide-separators = 1 + GtkWidget::separator-width = 1 + GtkWidget::separator-height = 7 +} + +style "clearlooks-frame_title" { + + fg[NORMAL] = lighter (@rt_fg_color) + fg[PRELIGHT] = lighter (@rt_fg_color) + fg[ACTIVE] = lighter (@rt_fg_color) + fg[SELECTED] = lighter (@rt_fg_color) +} + +style "clearlooks-partialPasteHeaderSep" { + + bg[NORMAL] = mix (0.25, @rt_fg_color, @rt_bg_color) +} + +style "clearlooks-checkbutton" { + + text[NORMAL] = @rt_selected_fg_color + + fg[PRELIGHT] = @rt_fg_color + + bg[SELECTED] = @rt_base_color + bg[PRELIGHT] = @rt_base_color + bg[SELECTED] = @rt_base_color + + engine "clearlooks" + { + hint = "checkbutton" + } +} + +style "clearlooks-treeview" { + + base[ACTIVE] = mix(0.50, @rt_selected_bg_color, @rt_base_color) + + engine "clearlooks" { + hint = "treeview" + } +} + +# The almost useless progress bar style +style "clearlooks-progressbar" { + xthickness = 1 + ythickness = 1 + + fg[PRELIGHT] = @rt_selected_fg_color + + engine "clearlooks" { + # Explicitly set the radius for the progress bars inside menu items. + radius = 3.0 + + hint = "progressbar" + } +} + +# This style is based on the clearlooks-default style, so that the colors from the button +# style are overriden again. +style "clearlooks-treeview_header" = "clearlooks-default" { + xthickness = 2 + ythickness = 1 + + bg[NORMAL] = shade (0.80, @rt_bg_color) + + engine "clearlooks" { + radius = 0.0 + hint = "treeview-header" + } +} + +style "clearlooks-tooltips" { + xthickness = 4 + ythickness = 4 + + bg[NORMAL] = @rt_tooltip_bg_color + fg[NORMAL] = @rt_tooltip_fg_color +} + +############################################################################### +# The following part of the gtkrc applies the different styles to the widgets. +############################################################################### + +# The clearlooks-default style is applied to every widget +class "GtkWidget" style "clearlooks-default" + +class "GtkSeparator" style "wide" +class "GtkFrame" style "wide" +class "GtkCalendar" style "wide" +class "GtkCheckButton" style "wider" +class "GtkRadioButton" style "wider" +class "GtkEntry" style "clearlooks-entry" + +class "GtkPaned" style "clearlooks-paned" +class "GtkSpinButton" style "clearlooks-spinbutton" +class "GtkScale" style "clearlooks-scale" +class "GtkVScale" style "clearlooks-vscale" +class "GtkHScale" style "clearlooks-hscale" +class "GtkScrollbar" style "clearlooks-scrollbar" +class "GtkHScrollbar" style "clearlooks-hscrollbar" +class "GtkVScrollbar" style "clearlooks-vscrollbar" + +class "GtkHSV" style "clearlooks-HSV" + +# General matching follows. The order is choosen so that the right styles override +# each other. EG. progressbar needs to be more important than the menu match. +widget_class "*" style "clearlooks-notebook_bg" +# This is not perfect, it could be done better. +# (That is modify *every* widget in the notebook, and change those back that +# we really don't want changed) +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" + +widget_class "*." style "clearlooks-combobox" +widget_class "**" style "clearlooks-button" +widget_class "*" style "clearlooks-notebook" +widget_class "**" style "clearlooks-statusbar" + +#widget_class "**" style "clearlooks-comboboxentry" +widget_class "**" style "clearlooks-combobox" + +widget_class "**" style "clearlooks-checkbutton" +widget_class "**" style "clearlooks-menubar" +widget_class "**" style "clearlooks-menu" +widget_class "**" style "clearlooks-menu_item" +widget_class "**" style "clearlooks-separator_menu_item" + +widget_class "*." style "clearlooks-frame" +widget_class "*.." style "clearlooks-frame_title" +widget_class "*.*" style "clearlooks-treeview" + +widget_class "*" style "clearlooks-progressbar" + +# Treeview headers (and similar stock GTK+ widgets) +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*...*." style "clearlooks-separator" +widget_class "*...*." style "clearlooks-toolExpanderBox" + +widget "*.partialPasteHeader.*" style "clearlooks-frame_title" +widget "*.partialPasteHeaderSep" style "clearlooks-partialPasteHeaderSep" +widget "*.histButton" style "clearlooks-histButton" +widget "*.FramelessSpinButton" style "clearlooks-framelessspinbutton" +widget "*.ThresholdSelector" style "clearlooks-thresholdselector" +widget "*.MyExpanderTitle.*" style "clearlooks-expander" +widget "*.MyExpanderTitle" style "clearlooks-expander" +widget "*.ExpanderBox" style "clearlooks-toolFrame" +widget "*.ExpanderBox.*.MyExpanderTitle" style "clearlooks-subexpander" +widget "*.ExpanderBox.*.MyExpanderTitle.*" style "clearlooks-subexpander" +widget "*.AxisAdjuster" style "clearlooks-axisadjuster" + +# The window of the tooltip is called "gtk-tooltip" +################################################################## +# FIXME: +# This will not work if one embeds eg. a button into the tooltip. +# As far as I can tell right now we will need to rework the theme +# quite a bit to get this working correctly. +# (It will involve setting different priorities, etc.) +################################################################## +widget "gtk-tooltip*" style "clearlooks-tooltips" + +gtk-icon-theme-name="Dark" diff --git a/rtdata/themes/25-Gray-Purple.iconset b/rtdata/themes/25-Gray-Purple.iconset new file mode 100644 index 000000000..99ac20640 --- /dev/null +++ b/rtdata/themes/25-Gray-Purple.iconset @@ -0,0 +1,2 @@ +[General] +Iconset=Dark diff --git a/rtdata/themes/25-Gray-Red.gtkrc b/rtdata/themes/25-Gray-Red.gtkrc new file mode 100644 index 000000000..fcb6d34ea --- /dev/null +++ b/rtdata/themes/25-Gray-Red.gtkrc @@ -0,0 +1,557 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2011 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 . +# + +# Please keep this gtkrc in sync with the other ones from Clearlooks based themes. + +gtk-color-scheme = "rt_salt_pinch:#800000\nrt_base_color:#525252\nrt_fg_color:#979797\nrt_tooltip_fg_color:#A0A0A0\nrt_selected_bg_color:#703535\nrt_selected_fg_color:#CDCDCD\nrt_text_color:#A2A2A2\nrt_bg_color:#404040\nrt_tooltip_bg_color:#252525\nrt_tool_bg:#3B3B3B\nrt_tool_border:#4D4D4D" + +style "clearlooks-default" { + xthickness = 1 + ythickness = 1 + + ####################### + # Style Properties + ####################### + GtkButton::child-displacement-x = 1 + GtkButton::child-displacement-y = 1 + GtkButton::default-border = { 0, 0, 0, 0 } + GtkButton::image-spacing = 4 + GtkToolButton::icon-spacing = 4 + + GtkCheckButton::indicator-size = 14 + + GtkPaned::handle-size = 6 + + GtkRange::trough-border = 0 + GtkRange::slider-width = 15 + GtkRange::stepper-size = 15 + + GtkScale::slider-width = 14 + GtkScale::slider-length = 30 + GtkScale::trough-side-details = 0 + + GtkScrollbar::min-slider-length = 30 + GtkMenuBar::internal-padding = 0 + GtkExpander::expander-size = 12 + GtkExpander::expander-spacing = 2 + GtkToolbar::internal-padding = 1 + GtkTreeView::expander-size = 12 + GtkTreeView::vertical-separator = 0 + + GtkMenu::horizontal-padding = 0 + GtkMenu::vertical-padding = 0 + + WnckTasklist::fade-overlay-rect = 0 + # The following line hints to gecko (and possibly other appliations) + # that the entry should be drawn transparently on the canvas. + # Without this, gecko will fill in the background of the entry. + GtkEntry::honors-transparent-bg-hint = 1 + + GtkEntry::progress-border = { 2, 2, 2, 2 } + + #################### + # Color Definitions + #################### + bg[NORMAL] = @rt_bg_color + bg[PRELIGHT] = shade (1.02, @rt_bg_color) + bg[SELECTED] = @rt_selected_bg_color + bg[INSENSITIVE] = @rt_bg_color + bg[ACTIVE] = shade (0.9, @rt_bg_color) + + fg[NORMAL] = @rt_fg_color + fg[PRELIGHT] = @rt_fg_color + fg[SELECTED] = @rt_selected_fg_color + fg[INSENSITIVE] = mix (0.2, @rt_fg_color, @rt_bg_color) + fg[ACTIVE] = @rt_fg_color + + text[NORMAL] = @rt_text_color + text[PRELIGHT] = @rt_text_color + text[SELECTED] = @rt_selected_fg_color + text[INSENSITIVE] = darker (@rt_bg_color) + text[ACTIVE] = @rt_selected_fg_color + + base[NORMAL] = @rt_base_color + base[PRELIGHT] = shade (0.95, @rt_bg_color) + base[SELECTED] = @rt_selected_bg_color + base[INSENSITIVE] = @rt_bg_color + base[ACTIVE] = shade (0.9, @rt_selected_bg_color) + + engine "clearlooks" { + colorize_scrollbar = TRUE + reliefstyle = 1 + menubarstyle = 2 + toolbarstyle = 1 + animation = FALSE + radius = 3.0 + # style between CLASSIC, GLOSSY, INVERTED and GUMMY + style = GUMMY + + # Set a hint to disable backward compatibility fallbacks. + hint = "use-hints" + } +} + +style "wide" { + xthickness = 2 + ythickness = 2 +} + +style "wider" { + xthickness = 3 + ythickness = 3 +} + +style "clearlooks-entry" { + xthickness = 3 + ythickness = 3 + + bg[SELECTED] = mix (1.4, @rt_selected_bg_color, @rt_base_color) + fg[SELECTED] = @rt_selected_fg_color + + engine "clearlooks" { + focus_color = shade (0.65, @rt_selected_bg_color) + } +} + +style "clearlooks-paned" { + + bg[PRELIGHT] = shade (0.9, @rt_bg_color) + + engine "clearlooks" { + hint = "paned" + } +} + +style "clearlooks-HSV" { + + engine "clearlooks" { + hint = "HSV" + disable_focus = TRUE + } +} + +style "clearlooks-spinbutton" { + + engine "clearlooks" { + hint = "spinbutton" + } +} + +style "clearlooks-axisadjuster" = "clearlooks-spinbutton" { + # background + base[INSENSITIVE] = @rt_tool_bg + # text + text[INSENSITIVE] = @rt_fg_color +} + +style "clearlooks-framelessspinbutton" { + + # IMPORTANT! + # base[NORMAL] must have the same color than clearlooks.toolContainer / bg[NORMAL] + base[NORMAL] = @rt_tool_bg + base[INSENSITIVE] = @rt_tool_bg + bg[NORMAL] = @rt_tool_bg + bg[INSENSITIVE] = @rt_tool_bg +} + +style "clearlooks-scale" { + xthickness = 2 + ythickness = 2 + + bg[NORMAL] = shade (1.30, @rt_bg_color) + bg[PRELIGHT] = shade (1.40, @rt_bg_color) + # when GtkScale::trough-side-details = 1, bg[SELECTED] set the color of the slider background on the left of the knob + #bg[SELECTED] = @rt_bg_color + + engine "clearlooks" { + focus_color = @rt_selected_bg_color + hint = "scale" + } +} + +style "clearlooks-thresholdselector" { + xthickness = 6 + ythickness = 6 + + bg[NORMAL] = @rt_tool_bg + bg[ACTIVE] = shade (1.45, @rt_bg_color) + bg[PRELIGHT] = shade (1.70, @rt_bg_color) + bg[SELECTED] = shade (2.00, @rt_bg_color) + + fg[PRELIGHT] = shade (1.30, @rt_fg_color) +} + +style "clearlooks-vscale" { + + engine "clearlooks" { + hint = "vscale" + } +} + +style "clearlooks-hscale" { + + engine "clearlooks" { + hint = "hscale" + } +} + +style "clearlooks-scrollbar" { + xthickness = 2 + ythickness = 2 + + bg[SELECTED] = shade (1.15, @rt_bg_color) + + engine "clearlooks" { + hint = "scrollbar" + } +} + +style "clearlooks-hscrollbar" { + + engine "clearlooks" { + hint = "hscrollbar" + } +} + +style "clearlooks-vscrollbar" { + + engine "clearlooks" { + hint = "vscrollbar" + } +} + +style "clearlooks-notebook_bg" { + + bg[NORMAL] = shade (1.02, @rt_bg_color) + bg[ACTIVE] = shade (0.80, @rt_bg_color) +} + +style "clearlooks-toolContainer" { + xthickness = 0 + ythickness = 0 + + # IMPORTANT! + # If you modify bg[NORMAL] below, you must set clearlooks-framelessspinbutton -> base[NORMAL] to the very same value + bg[NORMAL] = @rt_tool_bg + bg[INSENSITIVE] = @rt_tool_bg +} + +style "clearlooks-separator" { + bg[NORMAL] = mix(0.85, @rt_tool_bg, @rt_tool_border) + bg[INSENSITIVE] = mix(0.60, @rt_tool_bg, @rt_tool_border) +} + +style "clearlooks-frame" { + bg[NORMAL] = mix(0.85, @rt_tool_bg, @rt_tool_border) + bg[INSENSITIVE] = mix(0.60, @rt_tool_bg, @rt_tool_border) +} + +style "clearlooks-toolFrame" = "clearlooks-toolContainer" { + bg[NORMAL] = @rt_tool_bg + + fg[NORMAL] = @rt_tool_border + fg[INSENSITIVE] = mix(0.5, @rt_bg_color, @rt_tool_border) +} + +style "clearlooks-toolExpanderBox" { + bg[NORMAL] = @rt_tool_bg + bg[INSENSITIVE] = @rt_tool_bg +} + +style "clearlooks-combobox" { + + text[NORMAL] = @rt_fg_color + text[PRELIGHT] = shade(1.15, @rt_fg_color) + text[SELECTED] = @rt_selected_fg_color + text[INSENSITIVE] = mix (0.2, @rt_fg_color, @rt_bg_color) + text[ACTIVE] = @rt_fg_color +} + +style "clearlooks-button" { + + bg[NORMAL] = shade (0.93, @rt_tool_bg) + bg[PRELIGHT] = shade (0.85, @rt_tool_bg) + bg[ACTIVE] = shade (0.70, @rt_tool_bg) + + fg[NORMAL] = @rt_fg_color + fg[PRELIGHT] = shade(1.15, @rt_fg_color) + fg[SELECTED] = @rt_selected_fg_color + fg[INSENSITIVE] = mix (0.2, @rt_fg_color, @rt_bg_color) + fg[ACTIVE] = @rt_fg_color + + engine "clearlooks" + { + hint = "button" + } +} + +style "clearlooks-histButton" { + + GtkButton::child-displacement-x = 0 + GtkButton::child-displacement-y = 0 +} + +# The color is changed by the notebook_bg style, this style +# changes the x/ythickness +style "clearlooks-notebook" { + xthickness = 3 + ythickness = 3 + + bg[SELECTED] = @rt_salt_pinch +} + +style "clearlooks-statusbar" { + + engine "clearlooks" { + hint = "statusbar" + } +} + +style "clearlooks-comboboxentry" { + + engine "clearlooks" { + # Note: + # If you set the appears-as-list option on comboboxes in the theme, + # then you should set this hint on the combobox instead. + hint = "comboboxentry" + } +} + +style "clearlooks-expander" { + xthickness = 3 + ythickness = 3 + + fg[NORMAL] = "#a0a0a0" + fg[PRELIGHT] = "#d0d0d0" + fg[INSENSITIVE] = "#808080" + + bg[PRELIGHT] = mix(0.75, @rt_selected_bg_color, @rt_bg_color) + + base[NORMAL] = @rt_salt_pinch + base[PRELIGHT] = @rt_salt_pinch + base[INSENSITIVE] = @rt_salt_pinch +} + +style "clearlooks-subexpander" = "clearlooks-expander"{ + bg[NORMAL] = @rt_tool_bg +} + +style "clearlooks-menubar" { + + engine "clearlooks" { + hint = "menubar" + } +} + +style "clearlooks-menu" { + xthickness = 0 + ythickness = 0 + + bg[NORMAL] = shade (0.70, @rt_bg_color) + + engine "clearlooks" { + radius = 0.0 + } +} + +style "clearlooks-menu_item" { + xthickness = 2 + ythickness = 3 + + fg[PRELIGHT] = @rt_selected_fg_color + text[NORMAL] = @rt_fg_color + text[PRELIGHT] = @rt_selected_fg_color +} + +# This style is there to modify the separator menu items. The goals are: +# 1. Get a specific height. +# 2. The line should go to the edges (ie. no border at the left/right) +style "clearlooks-separator_menu_item" { + xthickness = 1 + ythickness = 0 + + GtkSeparatorMenuItem::horizontal-padding = 0 + GtkWidget::wide-separators = 1 + GtkWidget::separator-width = 1 + GtkWidget::separator-height = 7 +} + +style "clearlooks-frame_title" { + + fg[NORMAL] = lighter (@rt_fg_color) + fg[PRELIGHT] = lighter (@rt_fg_color) + fg[ACTIVE] = lighter (@rt_fg_color) + fg[SELECTED] = lighter (@rt_fg_color) +} + +style "clearlooks-partialPasteHeaderSep" { + + bg[NORMAL] = mix (0.25, @rt_fg_color, @rt_bg_color) +} + +style "clearlooks-checkbutton" { + + text[NORMAL] = @rt_selected_fg_color + + fg[PRELIGHT] = @rt_fg_color + + bg[SELECTED] = @rt_base_color + bg[PRELIGHT] = @rt_base_color + bg[SELECTED] = @rt_base_color + + engine "clearlooks" + { + hint = "checkbutton" + } +} + +style "clearlooks-treeview" { + + base[ACTIVE] = mix(0.50, @rt_selected_bg_color, @rt_base_color) + + engine "clearlooks" { + hint = "treeview" + } +} + +# The almost useless progress bar style +style "clearlooks-progressbar" { + xthickness = 1 + ythickness = 1 + + fg[PRELIGHT] = @rt_selected_fg_color + + engine "clearlooks" { + # Explicitly set the radius for the progress bars inside menu items. + radius = 3.0 + + hint = "progressbar" + } +} + +# This style is based on the clearlooks-default style, so that the colors from the button +# style are overriden again. +style "clearlooks-treeview_header" = "clearlooks-default" { + xthickness = 2 + ythickness = 1 + + bg[NORMAL] = shade (0.80, @rt_bg_color) + + engine "clearlooks" { + radius = 0.0 + hint = "treeview-header" + } +} + +style "clearlooks-tooltips" { + xthickness = 4 + ythickness = 4 + + bg[NORMAL] = @rt_tooltip_bg_color + fg[NORMAL] = @rt_tooltip_fg_color +} + +############################################################################### +# The following part of the gtkrc applies the different styles to the widgets. +############################################################################### + +# The clearlooks-default style is applied to every widget +class "GtkWidget" style "clearlooks-default" + +class "GtkSeparator" style "wide" +class "GtkFrame" style "wide" +class "GtkCalendar" style "wide" +class "GtkCheckButton" style "wider" +class "GtkRadioButton" style "wider" +class "GtkEntry" style "clearlooks-entry" + +class "GtkPaned" style "clearlooks-paned" +class "GtkSpinButton" style "clearlooks-spinbutton" +class "GtkScale" style "clearlooks-scale" +class "GtkVScale" style "clearlooks-vscale" +class "GtkHScale" style "clearlooks-hscale" +class "GtkScrollbar" style "clearlooks-scrollbar" +class "GtkHScrollbar" style "clearlooks-hscrollbar" +class "GtkVScrollbar" style "clearlooks-vscrollbar" + +class "GtkHSV" style "clearlooks-HSV" + +# General matching follows. The order is choosen so that the right styles override +# each other. EG. progressbar needs to be more important than the menu match. +widget_class "*" style "clearlooks-notebook_bg" +# This is not perfect, it could be done better. +# (That is modify *every* widget in the notebook, and change those back that +# we really don't want changed) +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" + +widget_class "*." style "clearlooks-combobox" +widget_class "**" style "clearlooks-button" +widget_class "*" style "clearlooks-notebook" +widget_class "**" style "clearlooks-statusbar" + +#widget_class "**" style "clearlooks-comboboxentry" +widget_class "**" style "clearlooks-combobox" + +widget_class "**" style "clearlooks-checkbutton" +widget_class "**" style "clearlooks-menubar" +widget_class "**" style "clearlooks-menu" +widget_class "**" style "clearlooks-menu_item" +widget_class "**" style "clearlooks-separator_menu_item" + +widget_class "*." style "clearlooks-frame" +widget_class "*.." style "clearlooks-frame_title" +widget_class "*.*" style "clearlooks-treeview" + +widget_class "*" style "clearlooks-progressbar" + +# Treeview headers (and similar stock GTK+ widgets) +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*...*." style "clearlooks-separator" +widget_class "*...*." style "clearlooks-toolExpanderBox" + +widget "*.partialPasteHeader.*" style "clearlooks-frame_title" +widget "*.partialPasteHeaderSep" style "clearlooks-partialPasteHeaderSep" +widget "*.histButton" style "clearlooks-histButton" +widget "*.FramelessSpinButton" style "clearlooks-framelessspinbutton" +widget "*.ThresholdSelector" style "clearlooks-thresholdselector" +widget "*.MyExpanderTitle.*" style "clearlooks-expander" +widget "*.MyExpanderTitle" style "clearlooks-expander" +widget "*.ExpanderBox" style "clearlooks-toolFrame" +widget "*.ExpanderBox.*.MyExpanderTitle" style "clearlooks-subexpander" +widget "*.ExpanderBox.*.MyExpanderTitle.*" style "clearlooks-subexpander" +widget "*.AxisAdjuster" style "clearlooks-axisadjuster" + +# The window of the tooltip is called "gtk-tooltip" +################################################################## +# FIXME: +# This will not work if one embeds eg. a button into the tooltip. +# As far as I can tell right now we will need to rework the theme +# quite a bit to get this working correctly. +# (It will involve setting different priorities, etc.) +################################################################## +widget "gtk-tooltip*" style "clearlooks-tooltips" + +gtk-icon-theme-name="Dark" diff --git a/rtdata/themes/25-Gray-Red.iconset b/rtdata/themes/25-Gray-Red.iconset new file mode 100644 index 000000000..99ac20640 --- /dev/null +++ b/rtdata/themes/25-Gray-Red.iconset @@ -0,0 +1,2 @@ +[General] +Iconset=Dark diff --git a/rtdata/themes/37-Gray-Red-Textured.gtkrc b/rtdata/themes/37-Gray-Red-Textured.gtkrc new file mode 100644 index 000000000..34aa2bb78 --- /dev/null +++ b/rtdata/themes/37-Gray-Red-Textured.gtkrc @@ -0,0 +1,902 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2011 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 . +# + +# Please keep this gtkrc in sync with the other ones from Clearlooks based themes. + +gtk-color-scheme = "rt_salt_pinch:#800000\nrt_base_color:#707070\nrt_fg_color:#A9A9A9\nrt_tooltip_fg_color:#A5A5A5\nrt_selected_bg_color:#562020\nrt_selected_fg_color:#E2E2E2\nrt_text_color:#C0C0C0\nrt_bg_color:#5F5F5F\nrt_tooltip_bg_color:#404040\nrt_tool_bg:#575757\nrt_tool_border:#6F6F6F" + +style "clearlooks-default" { + xthickness = 1 + ythickness = 1 + + ####################### + # Style Properties + ####################### + GtkButton::child-displacement-x = 1 + GtkButton::child-displacement-y = 1 + GtkButton::default-border = { 0, 0, 0, 0 } + GtkButton::image-spacing = 4 + GtkToolButton::icon-spacing = 4 + + GtkCheckButton::indicator-size = 14 + + GtkPaned::handle-size = 6 + + GtkRange::trough-border = 0 + GtkRange::slider-width = 14 + GtkRange::stepper-size = 10 + + GtkScale::slider-width = 14 + GtkScale::slider-length = 30 + GtkScale::trough-side-details = 0 + + GtkScrollbar::min-slider-length = 30 + GtkMenuBar::internal-padding = 0 + GtkExpander::expander-size = 12 + GtkExpander::expander-spacing = 2 + GtkToolbar::internal-padding = 1 + GtkTreeView::expander-size = 12 + GtkTreeView::vertical-separator = 0 + + GtkMenu::horizontal-padding = 0 + GtkMenu::vertical-padding = 0 + + WnckTasklist::fade-overlay-rect = 0 + # The following line hints to gecko (and possibly other appliations) + # that the entry should be drawn transparently on the canvas. + # Without this, gecko will fill in the background of the entry. + GtkEntry::honors-transparent-bg-hint = 1 + + GtkEntry::progress-border = { 2, 2, 2, 2 } + + #################### + # Color Definitions + #################### + bg[NORMAL] = @rt_bg_color + bg[PRELIGHT] = shade (1.02, @rt_bg_color) + bg[SELECTED] = @rt_selected_bg_color + bg[INSENSITIVE] = shade (0.95, @rt_bg_color) + bg[ACTIVE] = shade (0.7, @rt_bg_color) + + fg[NORMAL] = @rt_fg_color + fg[PRELIGHT] = @rt_fg_color + fg[SELECTED] = @rt_selected_fg_color + fg[INSENSITIVE] = mix (0.2, @rt_fg_color, @rt_bg_color) + fg[ACTIVE] = @rt_fg_color + + text[NORMAL] = @rt_text_color + text[PRELIGHT] = @rt_text_color + text[SELECTED] = @rt_selected_fg_color + text[INSENSITIVE] = darker (@rt_bg_color) + text[ACTIVE] = @rt_selected_fg_color + + base[NORMAL] = @rt_base_color + base[PRELIGHT] = shade (1.05, @rt_bg_color) + base[SELECTED] = @rt_selected_bg_color + base[INSENSITIVE] = @rt_bg_color + base[ACTIVE] = @rt_selected_bg_color + + engine "clearlooks" { + colorize_scrollbar = TRUE + reliefstyle = 1 + menubarstyle = 2 + toolbarstyle = 1 + animation = FALSE + radius = 3.0 + # style between CLASSIC, GLOSSY, INVERTED and GUMMY + style = GUMMY + + # Set a hint to disable backward compatibility fallbacks. + hint = "use-hints" + } +} + +style "wide" { + xthickness = 2 + ythickness = 2 +} + +style "wider" { + xthickness = 3 + ythickness = 3 +} + +style "clearlooks-entry" { + xthickness = 3 + ythickness = 3 + + bg[SELECTED] = mix (0.4, @rt_selected_bg_color, @rt_base_color) + fg[SELECTED] = @rt_selected_fg_color + + engine "clearlooks" { + focus_color = shade (0.65, @rt_selected_bg_color) + } +} + +style "clearlooks-paned" { + + bg[PRELIGHT] = shade (0.9, @rt_bg_color) + + engine "clearlooks" { + hint = "paned" + } +} + +style "clearlooks-HSV" { + + engine "clearlooks" { + hint = "HSV" + disable_focus = TRUE + } +} + +style "clearlooks-spinbutton" { + + engine "clearlooks" { + hint = "spinbutton" + } +} + +style "clearlooks-axisadjuster" = "clearlooks-spinbutton" { + # background + base[INSENSITIVE] = @rt_tool_bg + # text + text[INSENSITIVE] = @rt_fg_color +} + +style "clearlooks-framelessspinbutton" { + + # IMPORTANT! + # base[NORMAL] must have the same color than clearlooks.toolContainer / bg[NORMAL] + base[NORMAL] = @rt_tool_bg + base[INSENSITIVE] = @rt_tool_bg + bg[NORMAL] = @rt_tool_bg + bg[INSENSITIVE] = @rt_tool_bg +} + +style "clearlooks-scale" { + xthickness = 2 + ythickness = 2 + + bg[NORMAL] = shade (0.96, @rt_bg_color) + bg[PRELIGHT] = shade (1.06, @rt_bg_color) + # when GtkScale::trough-side-details = 1, bg[SELECTED] set the color of the slider background on the left of the knob + #bg[SELECTED] = @rt_bg_color + + engine "clearlooks" { + focus_color = @rt_selected_bg_color + hint = "scale" + } +} + +style "clearlooks-thresholdselector" { + xthickness = 6 + ythickness = 6 + + bg[NORMAL] = @rt_tool_bg + bg[ACTIVE] = shade (1.45, @rt_bg_color) + bg[PRELIGHT] = shade (1.70, @rt_bg_color) + bg[SELECTED] = shade (2.00, @rt_bg_color) + + fg[PRELIGHT] = shade (1.30, @rt_fg_color) +} + +style "clearlooks-vscale" { + + engine "clearlooks" { + hint = "vscale" + } +} + +style "clearlooks-hscale" { + + engine "clearlooks" { + hint = "hscale" + } +} + +style "clearlooks-scrollbar" { + + #bg[SELECTED] = shade (1.09, @rt_bg_color) + + engine "pixmap" { + image + { + function = BOX + detail = "trough" + file = "gray_textured/trough2.png" + border = { 6,6,6,6 } + stretch = TRUE + orientation = VERTICAL + } + image + { + function = BOX + detail = "trough" + file = "gray_textured/trough2-h.png" + border = { 6,6,6,6 } + stretch = TRUE + orientation = HORIZONTAL + } + image + { + function = SLIDER + state = NORMAL + file = "gray_textured/slider-h.png" + border = { 6,6,2,2 } + stretch = TRUE + orientation = HORIZONTAL + } + image + { + function = SLIDER + state = PRELIGHT + file = "gray_textured/slider-h-pre.png" + border = { 6,6,2,2 } + stretch = TRUE + orientation = HORIZONTAL + } + image + { + function = SLIDER + state = INSENSITIVE + file = "gray_textured/slider-h-ins.png" + border = { 6,6,2,2 } + stretch = TRUE + orientation = HORIZONTAL + } + image + { + function = SLIDER + state = NORMAL + file = "gray_textured/slider-v.png" + border = { 2, 2, 6, 6 } + stretch = TRUE + orientation = VERTICAL + } + image + { + function = SLIDER + state = PRELIGHT + file = "gray_textured/slider-v-pre.png" + border = { 2, 2, 6, 6 } + stretch = TRUE + orientation = VERTICAL + } + image + { + function = SLIDER + state = INSENSITIVE + file = "gray_textured/slider-v-ins.png" + border = { 2,2,6,6 } + stretch = TRUE + orientation = VERTICAL + } + image + { + function = STEPPER + state = NORMAL + file = "gray_textured/null.png" + border = { 1,1,4,4 } + stretch = TRUE + arrow_direction = UP + overlay_file = "gray_textured/arrow-up.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = PRELIGHT + file = "gray_textured/null.png" + border = { 1,1,4,4 } + stretch = TRUE + arrow_direction = UP + overlay_file = "gray_textured/arrow-up-pre.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = ACTIVE + file = "gray_textured/null.png" + border = { 1,1,4,4 } + stretch = TRUE + arrow_direction = UP + overlay_file = "gray_textured/arrow-up.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = INSENSITIVE + file = "gray_textured/null.png" + border = { 1,1,4,4 } + stretch = TRUE + arrow_direction = UP + overlay_file = "gray_textured/arrow-up-ins.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = NORMAL + file = "gray_textured/null.png" + border = { 1,1,4,4 } + stretch = TRUE + arrow_direction = DOWN + overlay_file = "gray_textured/arrow-down.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = PRELIGHT + file = "gray_textured/null.png" + border = { 1,1,4,4 } + stretch = TRUE + arrow_direction = DOWN + overlay_file = "gray_textured/arrow-down-pre.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = ACTIVE + file = "gray_textured/null.png" + border = { 1,1,4,4 } + stretch = TRUE + arrow_direction = DOWN + overlay_file = "gray_textured/arrow-down.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = INSENSITIVE + file = "gray_textured/null.png" + border = { 1,1,4,4 } + stretch = TRUE + arrow_direction = DOWN + overlay_file = "gray_textured/arrow-down-ins.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = NORMAL + file = "gray_textured/null.png" + border = { 4,4,1,1 } + stretch = TRUE + arrow_direction = RIGHT + overlay_file = "gray_textured/arrow-right.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = PRELIGHT + file = "gray_textured/null.png" + border = { 4,4,1,1 } + stretch = TRUE + arrow_direction = RIGHT + overlay_file = "gray_textured/arrow-right-pre.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = ACTIVE + file = "gray_textured/null.png" + border = { 4,4,1,1 } + stretch = TRUE + arrow_direction = RIGHT + overlay_file = "gray_textured/arrow-right.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = INSENSITIVE + file = "gray_textured/null.png" + border = { 4,4,1,1 } + stretch = TRUE + arrow_direction = RIGHT + overlay_file = "gray_textured/arrow-right-ins.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = NORMAL + file = "gray_textured/null.png" + border = { 4,4,1,1 } + stretch = TRUE + arrow_direction = LEFT + overlay_file = "gray_textured/arrow-left.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = PRELIGHT + file = "gray_textured/null.png" + border = { 4,4,1,1 } + stretch = TRUE + arrow_direction = LEFT + overlay_file = "gray_textured/arrow-left-pre.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = ACTIVE + file = "gray_textured/null.png" + border = { 4,4,1,1 } + stretch = TRUE + arrow_direction = LEFT + overlay_file = "gray_textured/arrow-left.png" + overlay_stretch = FALSE + } + image + { + function = STEPPER + state = INSENSITIVE + file = "gray_textured/null.png" + border = { 4,4,1,1 } + stretch = TRUE + arrow_direction = LEFT + overlay_file = "gray_textured/arrow-left-ins.png" + overlay_stretch = FALSE + } + } +} + +style "clearlooks-hscrollbar" { + + engine "clearlooks" { + hint = "hscrollbar" + } +} + +style "clearlooks-vscrollbar" { + + engine "clearlooks" { + hint = "vscrollbar" + } +} + +style "clearlooks-range" { + + engine "pixmap" { + # image + # { + # function = FOCUS + # file = "gray_textured/null.png" + # stretch = TRUE + # } + image + { + function = BOX + detail = "trough" + file = "gray_textured/pbtroughh.png" + border = { 6, 6, 6, 6 } + stretch = TRUE + orientation = HORIZONTAL + } + image + { + function = BOX + detail = "trough" + file = "gray_textured/pbtroughv.png" + border = { 6, 6, 6, 6 } + stretch = TRUE + orientation = VERTICAL + } + image + { + function = SLIDER + state = NORMAL + file = "gray_textured/rangeslider.png" + border = { 6, 6, 6, 6 } + stretch = TRUE + orientation = HORIZONTAL + } + image + { + function = SLIDER + state = PRELIGHT + file = "gray_textured/rangeslider-pre.png" + border = { 6, 6, 6, 6 } + stretch = TRUE + orientation = HORIZONTAL + } + image + { + function = SLIDER + state = ACTIVE + file = "gray_textured/rangeslider-pre.png" + border = { 6, 6, 6, 6 } + stretch = TRUE + orientation = HORIZONTAL + } + image + { + function = SLIDER + state = INSENSITIVE + file = "gray_textured/rangeslider-ins.png" + border = { 6, 6, 6, 6 } + stretch = TRUE + orientation = HORIZONTAL + } + image + { + function = SLIDER + state = NORMAL + file = "gray_textured/rangeslider.png" + border = { 6, 6, 6, 6 } + stretch = TRUE + orientation = VERTICAL + } + image + { + function = SLIDER + state = PRELIGHT + file = "gray_textured/rangeslider-pre.png" + border = { 6, 6, 6, 6 } + stretch = TRUE + orientation = VERTICAL + } + image + { + function = SLIDER + state = ACTIVE + file = "gray_textured/rangeslider-pre.png" + border = { 6, 6, 6, 6 } + stretch = TRUE + orientation = VERTICAL + } + image + { + function = SLIDER + state = INSENSITIVE + file = "gray_textured/rangeslider-ins.png" + border = { 6, 6, 6, 6 } + stretch = TRUE + orientation = VERTICAL + } + } +} + +style "clearlooks-notebook_bg" { + + bg[NORMAL] = @rt_bg_color + bg[ACTIVE] = shade (0.85, @rt_bg_color) +} + +style "clearlooks-toolContainer" { + xthickness = 0 + ythickness = 0 + + # IMPORTANT! + # If you modify bg[NORMAL] below, you must set clearlooks-framelessspinbutton -> base[NORMAL] to the very same value + bg[NORMAL] = @rt_tool_bg + bg[INSENSITIVE] = @rt_tool_bg +} + +style "clearlooks-separator" { + bg[NORMAL] = mix(0.85, @rt_tool_bg, @rt_tool_border) + bg[INSENSITIVE] = mix(0.60, @rt_tool_bg, @rt_tool_border) +} + +style "clearlooks-frame" { + bg[NORMAL] = mix(0.95, @rt_tool_bg, @rt_tool_border) + bg[INSENSITIVE] = mix(0.60, @rt_tool_bg, @rt_tool_border) +} + +style "clearlooks-toolFrame" = "clearlooks-toolContainer" { + bg[NORMAL] = @rt_tool_bg + + fg[NORMAL] = @rt_tool_border + fg[INSENSITIVE] = mix(0.5, @rt_bg_color, @rt_tool_border) +} + +style "clearlooks-toolExpanderBox" { + bg[NORMAL] = @rt_tool_bg + bg[INSENSITIVE] = @rt_tool_bg +} + +style "clearlooks-combobox" { + + text[NORMAL] = @rt_fg_color + text[PRELIGHT] = shade(1.15, @rt_fg_color) + text[SELECTED] = @rt_selected_fg_color + text[INSENSITIVE] = mix (0.2, @rt_fg_color, @rt_bg_color) + text[ACTIVE] = @rt_fg_color +} + +style "clearlooks-button" { + + bg[NORMAL] = shade (0.93, @rt_tool_bg) + bg[PRELIGHT] = shade (0.85, @rt_tool_bg) + bg[ACTIVE] = shade (0.70, @rt_tool_bg) + + fg[NORMAL] = @rt_fg_color + fg[PRELIGHT] = shade(1.15, @rt_fg_color) + fg[SELECTED] = @rt_selected_fg_color + fg[INSENSITIVE] = mix (0.2, @rt_fg_color, @rt_bg_color) + fg[ACTIVE] = @rt_fg_color + + engine "clearlooks" + { + hint = "button" + } +} + +style "clearlooks-histButton" { + + GtkButton::child-displacement-x = 0 + GtkButton::child-displacement-y = 0 +} + +# The color is changed by the notebook_bg style, this style +# changes the x/ythickness +style "clearlooks-notebook" { + xthickness = 3 + ythickness = 3 + + bg[SELECTED] = @rt_salt_pinch +} + +style "clearlooks-statusbar" { + + engine "clearlooks" { + hint = "statusbar" + } +} + +style "clearlooks-comboboxentry" { + + engine "clearlooks" { + # Note: + # If you set the appears-as-list option on comboboxes in the theme, + # then you should set this hint on the combobox instead. + hint = "comboboxentry" + } +} + +style "clearlooks-expander" { + xthickness = 3 + ythickness = 3 + + fg[NORMAL] = "#a0a0a0" + fg[PRELIGHT] = "#d0d0d0" + fg[INSENSITIVE] = "#808080" + + bg[PRELIGHT] = mix (0.5, @rt_salt_pinch, @rt_bg_color) + + base[NORMAL] = @rt_salt_pinch + base[PRELIGHT] = @rt_salt_pinch + base[INSENSITIVE] = @rt_salt_pinch +} + +style "clearlooks-subexpander" = "clearlooks-expander"{ + bg[NORMAL] = @rt_tool_bg +} + +style "clearlooks-menubar" { + + engine "clearlooks" { + hint = "menubar" + } +} + +style "clearlooks-menu" { + xthickness = 0 + ythickness = 0 + + bg[NORMAL] = @rt_tooltip_bg_color + + engine "clearlooks" { + radius = 0.0 + } +} + +style "clearlooks-menu_item" { + xthickness = 2 + ythickness = 3 + + fg[PRELIGHT] = @rt_selected_fg_color + text[NORMAL] = @rt_fg_color + text[PRELIGHT] = @rt_selected_fg_color +} + +# This style is there to modify the separator menu items. The goals are: +# 1. Get a specific height. +# 2. The line should go to the edges (ie. no border at the left/right) +style "clearlooks-separator_menu_item" { + xthickness = 1 + ythickness = 0 + + GtkSeparatorMenuItem::horizontal-padding = 0 + GtkWidget::wide-separators = 1 + GtkWidget::separator-width = 1 + GtkWidget::separator-height = 7 +} + +style "clearlooks-frame_title" { + + fg[NORMAL] = lighter (@rt_fg_color) + fg[PRELIGHT] = lighter (@rt_fg_color) + fg[ACTIVE] = lighter (@rt_fg_color) + fg[SELECTED] = lighter (@rt_fg_color) +} + +style "clearlooks-partialPasteHeaderSep" { + + bg[NORMAL] = mix (0.25, @rt_fg_color, @rt_bg_color) +} + +style "clearlooks-checkbutton" { + + text[NORMAL] = @rt_selected_fg_color + + fg[PRELIGHT] = @rt_fg_color + + bg[SELECTED] = @rt_base_color + bg[PRELIGHT] = @rt_base_color + bg[SELECTED] = @rt_base_color + + engine "clearlooks" + { + hint = "checkbutton" + } +} + +style "clearlooks-treeview" { + + # For an unkown reason, shading 7C99AD produce a redish color, so we have to set the value manually + text[ACTIVE] = @rt_selected_fg_color + base[ACTIVE] = mix(0.50, @rt_selected_bg_color, @rt_base_color) + + engine "clearlooks" { + hint = "treeview" + } +} + +# The almost useless progress bar style +style "clearlooks-progressbar" { + xthickness = 1 + ythickness = 1 + + fg[PRELIGHT] = @rt_selected_fg_color + + engine "clearlooks" { + # Explicitly set the radius for the progress bars inside menu items. + radius = 3.0 + + hint = "progressbar" + } +} + +# This style is based on the clearlooks-default style, so that the colors from the button +# style are overriden again. +style "clearlooks-treeview_header" = "clearlooks-default" { + xthickness = 2 + ythickness = 1 + + bg[NORMAL] = shade (0.80, @rt_bg_color) + + engine "clearlooks" { + radius = 0.0 + hint = "treeview-header" + } +} + +style "clearlooks-tooltips" { + xthickness = 4 + ythickness = 4 + + bg[NORMAL] = @rt_tooltip_bg_color + fg[NORMAL] = @rt_tooltip_fg_color +} + +############################################################################### +# The following part of the gtkrc applies the different styles to the widgets. +############################################################################### + +# The clearlooks-default style is applied to every widget +class "GtkWidget" style "clearlooks-default" + +class "GtkSeparator" style "wide" +class "GtkFrame" style "wide" +class "GtkCalendar" style "wide" +class "GtkCheckButton" style "wider" +class "GtkRadioButton" style "wider" +class "GtkEntry" style "clearlooks-entry" + +class "GtkPaned" style "clearlooks-paned" +class "GtkSpinButton" style "clearlooks-spinbutton" +class "GtkRange" style "clearlooks-range" +class "GtkScrollbar" style "clearlooks-scrollbar" + +class "GtkHSV" style "clearlooks-HSV" + +# General matching follows. The order is choosen so that the right styles override +# each other. EG. progressbar needs to be more important than the menu match. +widget_class "*" style "clearlooks-notebook_bg" +# This is not perfect, it could be done better. +# (That is modify *every* widget in the notebook, and change those back that +# we really don't want changed) +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" + +widget_class "*." style "clearlooks-combobox" +widget_class "**" style "clearlooks-button" +widget_class "*" style "clearlooks-notebook" +widget_class "**" style "clearlooks-statusbar" + +#widget_class "**" style "clearlooks-comboboxentry" +widget_class "**" style "clearlooks-combobox" + +widget_class "**" style "clearlooks-checkbutton" +widget_class "**" style "clearlooks-menubar" +widget_class "**" style "clearlooks-menu" +widget_class "**" style "clearlooks-menu_item" +widget_class "**" style "clearlooks-separator_menu_item" + +widget_class "*." style "clearlooks-frame" +widget_class "*.." style "clearlooks-frame_title" +widget_class "*.*" style "clearlooks-treeview" + +widget_class "*" style "clearlooks-progressbar" + +# Treeview headers (and similar stock GTK+ widgets) +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*...*." style "clearlooks-separator" +widget_class "*...*." style "clearlooks-toolExpanderBox" + +widget "*.partialPasteHeader.*" style "clearlooks-frame_title" +widget "*.partialPasteHeaderSep" style "clearlooks-partialPasteHeaderSep" +widget "*.histButton" style "clearlooks-histButton" +widget "*.FramelessSpinButton" style "clearlooks-framelessspinbutton" +widget "*.ThresholdSelector" style "clearlooks-thresholdselector" +widget "*.MyExpanderTitle.*" style "clearlooks-expander" +widget "*.MyExpanderTitle" style "clearlooks-expander" +widget "*.ExpanderBox" style "clearlooks-toolFrame" +widget "*.ExpanderBox.*.MyExpanderTitle" style "clearlooks-subexpander" +widget "*.ExpanderBox.*.MyExpanderTitle.*" style "clearlooks-subexpander" +widget "*.AxisAdjuster" style "clearlooks-axisadjuster" + +# The window of the tooltip is called "gtk-tooltip" +################################################################## +# FIXME: +# This will not work if one embeds eg. a button into the tooltip. +# As far as I can tell right now we will need to rework the theme +# quite a bit to get this working correctly. +# (It will involve setting different priorities, etc.) +################################################################## +widget "gtk-tooltip*" style "clearlooks-tooltips" + +gtk-icon-theme-name="Dark" diff --git a/rtdata/themes/37-Gray-Red-Textured.iconset b/rtdata/themes/37-Gray-Red-Textured.iconset new file mode 100644 index 000000000..99ac20640 --- /dev/null +++ b/rtdata/themes/37-Gray-Red-Textured.iconset @@ -0,0 +1,2 @@ +[General] +Iconset=Dark diff --git a/rtdata/themes/37-Gray-Red.gtkrc b/rtdata/themes/37-Gray-Red.gtkrc new file mode 100644 index 000000000..481c8623d --- /dev/null +++ b/rtdata/themes/37-Gray-Red.gtkrc @@ -0,0 +1,559 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2011 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 . +# + +# Please keep this gtkrc in sync with the other ones from Clearlooks based themes. + +gtk-color-scheme = "rt_salt_pinch:#800000\nrt_base_color:#707070\nrt_fg_color:#A9A9A9\nrt_tooltip_fg_color:#A5A5A5\nrt_selected_bg_color:#562020\nrt_selected_fg_color:#E2E2E2\nrt_text_color:#C0C0C0\nrt_bg_color:#5F5F5F\nrt_tooltip_bg_color:#404040\nrt_tool_bg:#575757\nrt_tool_border:#6F6F6F" + +style "clearlooks-default" { + xthickness = 1 + ythickness = 1 + + ####################### + # Style Properties + ####################### + GtkButton::child-displacement-x = 1 + GtkButton::child-displacement-y = 1 + GtkButton::default-border = { 0, 0, 0, 0 } + GtkButton::image-spacing = 4 + GtkToolButton::icon-spacing = 4 + + GtkCheckButton::indicator-size = 14 + + GtkPaned::handle-size = 6 + + GtkRange::trough-border = 0 + GtkRange::slider-width = 15 + GtkRange::stepper-size = 15 + + GtkScale::slider-width = 14 + GtkScale::slider-length = 30 + GtkScale::trough-side-details = 0 + + GtkScrollbar::min-slider-length = 30 + GtkMenuBar::internal-padding = 0 + GtkExpander::expander-size = 12 + GtkExpander::expander-spacing = 2 + GtkToolbar::internal-padding = 1 + GtkTreeView::expander-size = 12 + GtkTreeView::vertical-separator = 0 + + GtkMenu::horizontal-padding = 0 + GtkMenu::vertical-padding = 0 + + WnckTasklist::fade-overlay-rect = 0 + # The following line hints to gecko (and possibly other appliations) + # that the entry should be drawn transparently on the canvas. + # Without this, gecko will fill in the background of the entry. + GtkEntry::honors-transparent-bg-hint = 1 + + GtkEntry::progress-border = { 2, 2, 2, 2 } + + #################### + # Color Definitions + #################### + bg[NORMAL] = @rt_bg_color + bg[PRELIGHT] = shade (1.02, @rt_bg_color) + bg[SELECTED] = @rt_selected_bg_color + bg[INSENSITIVE] = shade (0.95, @rt_bg_color) + bg[ACTIVE] = shade (0.7, @rt_bg_color) + + fg[NORMAL] = @rt_fg_color + fg[PRELIGHT] = @rt_fg_color + fg[SELECTED] = @rt_selected_fg_color + fg[INSENSITIVE] = mix (0.2, @rt_fg_color, @rt_bg_color) + fg[ACTIVE] = @rt_fg_color + + text[NORMAL] = @rt_text_color + text[PRELIGHT] = @rt_text_color + text[SELECTED] = @rt_selected_fg_color + text[INSENSITIVE] = darker (@rt_bg_color) + text[ACTIVE] = @rt_selected_fg_color + + base[NORMAL] = @rt_base_color + base[PRELIGHT] = shade (1.05, @rt_bg_color) + base[SELECTED] = @rt_selected_bg_color + base[INSENSITIVE] = @rt_bg_color + base[ACTIVE] = @rt_selected_bg_color + + engine "clearlooks" { + colorize_scrollbar = TRUE + reliefstyle = 1 + menubarstyle = 2 + toolbarstyle = 1 + animation = FALSE + radius = 3.0 + # style between CLASSIC, GLOSSY, INVERTED and GUMMY + style = GUMMY + + # Set a hint to disable backward compatibility fallbacks. + hint = "use-hints" + } +} + +style "wide" { + xthickness = 2 + ythickness = 2 +} + +style "wider" { + xthickness = 3 + ythickness = 3 +} + +style "clearlooks-entry" { + xthickness = 3 + ythickness = 3 + + bg[SELECTED] = mix (0.4, @rt_selected_bg_color, @rt_base_color) + fg[SELECTED] = @rt_selected_fg_color + + engine "clearlooks" { + focus_color = shade (0.65, @rt_selected_bg_color) + } +} + +style "clearlooks-paned" { + + bg[PRELIGHT] = shade (0.9, @rt_bg_color) + + engine "clearlooks" { + hint = "paned" + } +} + +style "clearlooks-HSV" { + + engine "clearlooks" { + hint = "HSV" + disable_focus = TRUE + } +} + +style "clearlooks-spinbutton" { + + engine "clearlooks" { + hint = "spinbutton" + } +} + +style "clearlooks-axisadjuster" = "clearlooks-spinbutton" { + # background + base[INSENSITIVE] = @rt_tool_bg + # text + text[INSENSITIVE] = @rt_fg_color +} + +style "clearlooks-framelessspinbutton" { + + # IMPORTANT! + # base[NORMAL] must have the same color than clearlooks.toolContainer / bg[NORMAL] + base[NORMAL] = @rt_tool_bg + base[INSENSITIVE] = @rt_tool_bg + bg[NORMAL] = @rt_tool_bg + bg[INSENSITIVE] = @rt_tool_bg +} + +style "clearlooks-scale" { + xthickness = 2 + ythickness = 2 + + bg[NORMAL] = shade (1.20, @rt_bg_color) + bg[PRELIGHT] = shade (1.30, @rt_bg_color) + # when GtkScale::trough-side-details = 1, bg[SELECTED] set the color of the slider background on the left of the knob + #bg[SELECTED] = @rt_bg_color + + engine "clearlooks" { + focus_color = @rt_selected_bg_color + hint = "scale" + } +} + +style "clearlooks-thresholdselector" { + xthickness = 6 + ythickness = 6 + + bg[NORMAL] = @rt_tool_bg + bg[ACTIVE] = shade (1.45, @rt_bg_color) + bg[PRELIGHT] = shade (1.70, @rt_bg_color) + bg[SELECTED] = shade (2.00, @rt_bg_color) + + fg[PRELIGHT] = shade (1.30, @rt_fg_color) +} + +style "clearlooks-vscale" { + + engine "clearlooks" { + hint = "vscale" + } +} + +style "clearlooks-hscale" { + + engine "clearlooks" { + hint = "hscale" + } +} + +style "clearlooks-scrollbar" { + xthickness = 2 + ythickness = 2 + + bg[SELECTED] = shade (1.16, @rt_bg_color) + + engine "clearlooks" { + hint = "scrollbar" + } +} + +style "clearlooks-hscrollbar" { + + engine "clearlooks" { + hint = "hscrollbar" + } +} + +style "clearlooks-vscrollbar" { + + engine "clearlooks" { + hint = "vscrollbar" + } +} + +style "clearlooks-notebook_bg" { + + bg[NORMAL] = @rt_bg_color + bg[ACTIVE] = shade (0.85, @rt_bg_color) +} + +style "clearlooks-toolContainer" { + xthickness = 0 + ythickness = 0 + + # IMPORTANT! + # If you modify bg[NORMAL] below, you must set clearlooks-framelessspinbutton -> base[NORMAL] to the very same value + bg[NORMAL] = @rt_tool_bg + bg[INSENSITIVE] = @rt_tool_bg +} + +style "clearlooks-separator" { + bg[NORMAL] = mix(0.85, @rt_tool_bg, @rt_tool_border) + bg[INSENSITIVE] = mix(0.60, @rt_tool_bg, @rt_tool_border) +} + +style "clearlooks-frame" { + bg[NORMAL] = mix(0.95, @rt_tool_bg, @rt_tool_border) + bg[INSENSITIVE] = mix(0.60, @rt_tool_bg, @rt_tool_border) +} + +style "clearlooks-toolFrame" = "clearlooks-toolContainer" { + bg[NORMAL] = @rt_tool_bg + + fg[NORMAL] = @rt_tool_border + fg[INSENSITIVE] = mix(0.5, @rt_bg_color, @rt_tool_border) +} + +style "clearlooks-toolExpanderBox" { + bg[NORMAL] = @rt_tool_bg + bg[INSENSITIVE] = @rt_tool_bg +} + +style "clearlooks-combobox" { + + text[NORMAL] = @rt_fg_color + text[PRELIGHT] = shade(1.15, @rt_fg_color) + text[SELECTED] = @rt_selected_fg_color + text[INSENSITIVE] = mix (0.2, @rt_fg_color, @rt_bg_color) + text[ACTIVE] = @rt_fg_color +} + +style "clearlooks-button" { + + bg[NORMAL] = shade (0.93, @rt_tool_bg) + bg[PRELIGHT] = shade (0.85, @rt_tool_bg) + bg[ACTIVE] = shade (0.70, @rt_tool_bg) + + fg[NORMAL] = @rt_fg_color + fg[PRELIGHT] = shade(1.15, @rt_fg_color) + fg[SELECTED] = @rt_selected_fg_color + fg[INSENSITIVE] = mix (0.2, @rt_fg_color, @rt_bg_color) + fg[ACTIVE] = @rt_fg_color + + engine "clearlooks" + { + hint = "button" + } +} + +style "clearlooks-histButton" { + + GtkButton::child-displacement-x = 0 + GtkButton::child-displacement-y = 0 +} + +# The color is changed by the notebook_bg style, this style +# changes the x/ythickness +style "clearlooks-notebook" { + xthickness = 3 + ythickness = 3 + + bg[SELECTED] = @rt_salt_pinch +} + +style "clearlooks-statusbar" { + + engine "clearlooks" { + hint = "statusbar" + } +} + +style "clearlooks-comboboxentry" { + + engine "clearlooks" { + # Note: + # If you set the appears-as-list option on comboboxes in the theme, + # then you should set this hint on the combobox instead. + hint = "comboboxentry" + } +} + +style "clearlooks-expander" { + xthickness = 3 + ythickness = 3 + + fg[NORMAL] = "#a0a0a0" + fg[PRELIGHT] = "#d0d0d0" + fg[INSENSITIVE] = "#808080" + + bg[PRELIGHT] = mix (0.5, @rt_salt_pinch, @rt_bg_color) + + base[NORMAL] = @rt_salt_pinch + base[PRELIGHT] = @rt_salt_pinch + base[INSENSITIVE] = @rt_salt_pinch +} + +style "clearlooks-subexpander" = "clearlooks-expander"{ + bg[NORMAL] = @rt_tool_bg +} + +style "clearlooks-menubar" { + + engine "clearlooks" { + hint = "menubar" + } +} + +style "clearlooks-menu" { + xthickness = 0 + ythickness = 0 + + bg[NORMAL] = @rt_tooltip_bg_color + + engine "clearlooks" { + radius = 0.0 + } +} + +style "clearlooks-menu_item" { + xthickness = 2 + ythickness = 3 + + fg[PRELIGHT] = @rt_selected_fg_color + text[NORMAL] = @rt_fg_color + text[PRELIGHT] = @rt_selected_fg_color +} + +# This style is there to modify the separator menu items. The goals are: +# 1. Get a specific height. +# 2. The line should go to the edges (ie. no border at the left/right) +style "clearlooks-separator_menu_item" { + xthickness = 1 + ythickness = 0 + + GtkSeparatorMenuItem::horizontal-padding = 0 + GtkWidget::wide-separators = 1 + GtkWidget::separator-width = 1 + GtkWidget::separator-height = 7 +} + +style "clearlooks-frame_title" { + + fg[NORMAL] = lighter (@rt_fg_color) + fg[PRELIGHT] = lighter (@rt_fg_color) + fg[ACTIVE] = lighter (@rt_fg_color) + fg[SELECTED] = lighter (@rt_fg_color) +} + +style "clearlooks-partialPasteHeaderSep" { + + bg[NORMAL] = mix (0.25, @rt_fg_color, @rt_bg_color) +} + +style "clearlooks-checkbutton" { + + text[NORMAL] = @rt_selected_fg_color + + fg[PRELIGHT] = @rt_fg_color + + bg[SELECTED] = @rt_base_color + bg[PRELIGHT] = @rt_base_color + bg[SELECTED] = @rt_base_color + + engine "clearlooks" + { + hint = "checkbutton" + } +} + +style "clearlooks-treeview" { + + # For an unkown reason, shading 7C99AD produce a redish color, so we have to set the value manually + text[ACTIVE] = @rt_selected_fg_color + base[ACTIVE] = mix(0.50, @rt_selected_bg_color, @rt_base_color) + + engine "clearlooks" { + hint = "treeview" + } +} + +# The almost useless progress bar style +style "clearlooks-progressbar" { + xthickness = 1 + ythickness = 1 + + fg[PRELIGHT] = @rt_selected_fg_color + + engine "clearlooks" { + # Explicitly set the radius for the progress bars inside menu items. + radius = 3.0 + + hint = "progressbar" + } +} + +# This style is based on the clearlooks-default style, so that the colors from the button +# style are overriden again. +style "clearlooks-treeview_header" = "clearlooks-default" { + xthickness = 2 + ythickness = 1 + + bg[NORMAL] = shade (0.80, @rt_bg_color) + + engine "clearlooks" { + radius = 0.0 + hint = "treeview-header" + } +} + +style "clearlooks-tooltips" { + xthickness = 4 + ythickness = 4 + + bg[NORMAL] = @rt_tooltip_bg_color + fg[NORMAL] = @rt_tooltip_fg_color +} + +############################################################################### +# The following part of the gtkrc applies the different styles to the widgets. +############################################################################### + +# The clearlooks-default style is applied to every widget +class "GtkWidget" style "clearlooks-default" + +class "GtkSeparator" style "wide" +class "GtkFrame" style "wide" +class "GtkCalendar" style "wide" +class "GtkCheckButton" style "wider" +class "GtkRadioButton" style "wider" +class "GtkEntry" style "clearlooks-entry" + +class "GtkPaned" style "clearlooks-paned" +class "GtkSpinButton" style "clearlooks-spinbutton" +class "GtkScale" style "clearlooks-scale" +class "GtkVScale" style "clearlooks-vscale" +class "GtkHScale" style "clearlooks-hscale" +class "GtkScrollbar" style "clearlooks-scrollbar" +class "GtkHScrollbar" style "clearlooks-hscrollbar" +class "GtkVScrollbar" style "clearlooks-vscrollbar" + +class "GtkHSV" style "clearlooks-HSV" + +# General matching follows. The order is choosen so that the right styles override +# each other. EG. progressbar needs to be more important than the menu match. +widget_class "*" style "clearlooks-notebook_bg" +# This is not perfect, it could be done better. +# (That is modify *every* widget in the notebook, and change those back that +# we really don't want changed) +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" + +widget_class "*." style "clearlooks-combobox" +widget_class "**" style "clearlooks-button" +widget_class "*" style "clearlooks-notebook" +widget_class "**" style "clearlooks-statusbar" + +#widget_class "**" style "clearlooks-comboboxentry" +widget_class "**" style "clearlooks-combobox" + +widget_class "**" style "clearlooks-checkbutton" +widget_class "**" style "clearlooks-menubar" +widget_class "**" style "clearlooks-menu" +widget_class "**" style "clearlooks-menu_item" +widget_class "**" style "clearlooks-separator_menu_item" + +widget_class "*." style "clearlooks-frame" +widget_class "*.." style "clearlooks-frame_title" +widget_class "*.*" style "clearlooks-treeview" + +widget_class "*" style "clearlooks-progressbar" + +# Treeview headers (and similar stock GTK+ widgets) +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*...*." style "clearlooks-separator" +widget_class "*...*." style "clearlooks-toolExpanderBox" + +widget "*.partialPasteHeader.*" style "clearlooks-frame_title" +widget "*.partialPasteHeaderSep" style "clearlooks-partialPasteHeaderSep" +widget "*.histButton" style "clearlooks-histButton" +widget "*.FramelessSpinButton" style "clearlooks-framelessspinbutton" +widget "*.ThresholdSelector" style "clearlooks-thresholdselector" +widget "*.MyExpanderTitle.*" style "clearlooks-expander" +widget "*.MyExpanderTitle" style "clearlooks-expander" +widget "*.ExpanderBox" style "clearlooks-toolFrame" +widget "*.ExpanderBox.*.MyExpanderTitle" style "clearlooks-subexpander" +widget "*.ExpanderBox.*.MyExpanderTitle.*" style "clearlooks-subexpander" +widget "*.AxisAdjuster" style "clearlooks-axisadjuster" + +# The window of the tooltip is called "gtk-tooltip" +################################################################## +# FIXME: +# This will not work if one embeds eg. a button into the tooltip. +# As far as I can tell right now we will need to rework the theme +# quite a bit to get this working correctly. +# (It will involve setting different priorities, etc.) +################################################################## +widget "gtk-tooltip*" style "clearlooks-tooltips" + +gtk-icon-theme-name="Dark" diff --git a/rtdata/themes/37-Gray-Red.iconset b/rtdata/themes/37-Gray-Red.iconset new file mode 100644 index 000000000..99ac20640 --- /dev/null +++ b/rtdata/themes/37-Gray-Red.iconset @@ -0,0 +1,2 @@ +[General] +Iconset=Dark diff --git a/rtdata/themes/63-Gray-Cyan.gtkrc b/rtdata/themes/63-Gray-Cyan.gtkrc new file mode 100644 index 000000000..3c56771ef --- /dev/null +++ b/rtdata/themes/63-Gray-Cyan.gtkrc @@ -0,0 +1,542 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2011 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 . +# + +# Please keep this gtkrc in sync with the other ones from Clearlooks based themes. + +gtk-color-scheme = "rt_salt_pinch:#95B0DB\nrt_base_color:#dddddd\nrt_fg_color:#0A0A0A\nrt_tooltip_fg_color:#000000\nrt_selected_bg_color:#95B0DB\nrt_selected_fg_color:#FFFFFF\nrt_text_color:#000000\nrt_bg_color:#A1A1A1\nrt_tooltip_bg_color:#F5F5B5\nrt_tool_bg:#a0a0a0\nrt_tool_border:#7d7d7d" + +style "clearlooks-default" { + xthickness = 1 + ythickness = 1 + + ####################### + # Style Properties + ####################### + GtkButton::child-displacement-x = 1 + GtkButton::child-displacement-y = 1 + GtkButton::default-border = { 0, 0, 0, 0 } + GtkButton::image-spacing = 4 + GtkToolButton::icon-spacing = 4 + + GtkCheckButton::indicator-size = 14 + + GtkPaned::handle-size = 6 + + GtkRange::trough-border = 0 + GtkRange::slider-width = 15 + GtkRange::stepper-size = 15 + + GtkScale::slider-width = 14 + GtkScale::slider-length = 30 + GtkScale::trough-side-details = 0 + + GtkScrollbar::min-slider-length = 30 + GtkMenuBar::internal-padding = 0 + GtkExpander::expander-size = 12 + GtkExpander::expander-spacing = 2 + GtkToolbar::internal-padding = 1 + GtkTreeView::expander-size = 12 + GtkTreeView::vertical-separator = 0 + + GtkMenu::horizontal-padding = 0 + GtkMenu::vertical-padding = 0 + + WnckTasklist::fade-overlay-rect = 0 + # The following line hints to gecko (and possibly other appliations) + # that the entry should be drawn transparently on the canvas. + # Without this, gecko will fill in the background of the entry. + GtkEntry::honors-transparent-bg-hint = 1 + + GtkEntry::progress-border = { 2, 2, 2, 2 } + + #################### + # Color Definitions + #################### + bg[NORMAL] = @rt_bg_color + bg[PRELIGHT] = shade (1.02, @rt_bg_color) + bg[SELECTED] = @rt_selected_bg_color + bg[INSENSITIVE] = @rt_bg_color + bg[ACTIVE] = shade (0.9, @rt_bg_color) + + fg[NORMAL] = @rt_fg_color + fg[PRELIGHT] = @rt_fg_color + fg[SELECTED] = @rt_selected_fg_color + fg[INSENSITIVE] = mix (0.2, @rt_fg_color, @rt_bg_color) + fg[ACTIVE] = @rt_fg_color + + text[NORMAL] = @rt_text_color + text[PRELIGHT] = @rt_text_color + text[SELECTED] = @rt_selected_fg_color + text[INSENSITIVE] = darker (@rt_bg_color) + text[ACTIVE] = @rt_selected_fg_color + + base[NORMAL] = @rt_base_color + base[PRELIGHT] = shade (0.95, @rt_bg_color) + base[SELECTED] = @rt_selected_bg_color + base[INSENSITIVE] = @rt_bg_color + base[ACTIVE] = shade (0.9, @rt_selected_bg_color) + + engine "clearlooks" { + colorize_scrollbar = TRUE + reliefstyle = 1 + menubarstyle = 2 + toolbarstyle = 1 + animation = FALSE + radius = 3.0 + # style between CLASSIC, GLOSSY, INVERTED and GUMMY + style = GUMMY + + # Set a hint to disable backward compatibility fallbacks. + hint = "use-hints" + } +} + +style "wide" { + xthickness = 2 + ythickness = 2 +} + +style "wider" { + xthickness = 3 + ythickness = 3 +} + +style "clearlooks-entry" { + xthickness = 3 + ythickness = 3 + + bg[SELECTED] = mix (1.4, @rt_selected_bg_color, @rt_base_color) + fg[SELECTED] = @rt_selected_fg_color + + engine "clearlooks" { + focus_color = shade (0.65, @rt_selected_bg_color) + } +} + +style "clearlooks-paned" { + + bg[PRELIGHT] = shade (0.9, @rt_bg_color) + + engine "clearlooks" { + hint = "paned" + } +} + +style "clearlooks-HSV" { + + engine "clearlooks" { + hint = "HSV" + disable_focus = TRUE + } +} + +style "clearlooks-spinbutton" { + + engine "clearlooks" { + hint = "spinbutton" + } +} + +style "clearlooks-axisadjuster" = "clearlooks-spinbutton" { + # background + base[INSENSITIVE] = @rt_tool_bg + # text + text[INSENSITIVE] = @rt_fg_color +} + +style "clearlooks-framelessspinbutton" { + + # IMPORTANT! + # base[NORMAL] must have the same color than clearlooks.toolContainer / bg[NORMAL] + base[NORMAL] = @rt_tool_bg + base[INSENSITIVE] = @rt_tool_bg + bg[NORMAL] = @rt_tool_bg + bg[INSENSITIVE] = @rt_tool_bg +} + +style "clearlooks-scale" { + xthickness = 2 + ythickness = 2 + + bg[NORMAL] = shade (1.15, @rt_bg_color) + bg[PRELIGHT] = shade (1.25, @rt_bg_color) + # when GtkScale::trough-side-details = 1, bg[SELECTED] set the color of the slider background on the left of the knob + #bg[SELECTED] = @rt_bg_color + + engine "clearlooks" { + focus_color = @rt_selected_bg_color + hint = "scale" + } +} + +style "clearlooks-thresholdselector" { + xthickness = 6 + ythickness = 6 + + bg[NORMAL] = @rt_tool_bg + bg[ACTIVE] = shade (1.20, @rt_bg_color) + bg[PRELIGHT] = shade (1.40, @rt_bg_color) + bg[SELECTED] = shade (1.65, @rt_bg_color) + + fg[PRELIGHT] = shade (1.30, @rt_fg_color) +} + +style "clearlooks-vscale" { + + engine "clearlooks" { + hint = "vscale" + } +} + +style "clearlooks-hscale" { + + engine "clearlooks" { + hint = "hscale" + } +} + +style "clearlooks-scrollbar" { + xthickness = 2 + ythickness = 2 + + #bg[NORMAL] = shade (1.07, @rt_bg_color) + + engine "clearlooks" { + hint = "scrollbar" + } +} + +style "clearlooks-hscrollbar" { + + engine "clearlooks" { + hint = "hscrollbar" + } +} + +style "clearlooks-vscrollbar" { + + engine "clearlooks" { + hint = "vscrollbar" + } +} + +style "clearlooks-notebook_bg" { + + bg[NORMAL] = shade (1.05, @rt_bg_color) + bg[ACTIVE] = shade (0.92, @rt_bg_color) +} + +style "clearlooks-toolContainer" { + xthickness = 0 + ythickness = 0 + + # IMPORTANT! + # If you modify bg[NORMAL] below, you must set clearlooks-framelessspinbutton -> base[NORMAL] to the very same value + bg[NORMAL] = @rt_tool_bg + bg[INSENSITIVE] = @rt_tool_bg +} + +style "clearlooks-separator" { + bg[NORMAL] = mix(0.85, @rt_tool_bg, @rt_tool_border) + bg[INSENSITIVE] = mix(0.60, @rt_tool_bg, @rt_tool_border) +} + +style "clearlooks-frame" { + bg[NORMAL] = mix(0.85, @rt_tool_bg, @rt_tool_border) + bg[INSENSITIVE] = mix(0.60, @rt_tool_bg, @rt_tool_border) +} + +style "clearlooks-toolFrame" = "clearlooks-toolContainer" { + bg[NORMAL] = @rt_tool_bg + + fg[NORMAL] = @rt_tool_border + fg[INSENSITIVE] = mix(0.5, @rt_bg_color, @rt_tool_border) +} + +style "clearlooks-toolExpanderBox" { + bg[NORMAL] = @rt_tool_bg + bg[INSENSITIVE] = @rt_tool_bg +} + +style "clearlooks-combobox" { + + text[NORMAL] = @rt_fg_color + text[PRELIGHT] = @rt_fg_color + text[SELECTED] = @rt_selected_fg_color + text[INSENSITIVE] = mix (0.2, @rt_fg_color, @rt_bg_color) + text[ACTIVE] = @rt_fg_color +} + +style "clearlooks-button" { + + bg[NORMAL] = shade (0.95, @rt_bg_color) + bg[PRELIGHT] = shade (1.08, @rt_bg_color) + bg[ACTIVE] = shade (0.80, @rt_bg_color) + + fg[NORMAL] = @rt_fg_color + fg[PRELIGHT] = @rt_fg_color + fg[SELECTED] = @rt_selected_fg_color + fg[INSENSITIVE] = mix (0.2, @rt_fg_color, @rt_bg_color) + fg[ACTIVE] = @rt_fg_color + + engine "clearlooks" + { + hint = "button" + radius = 5.0 + } +} + +style "clearlooks-histButton" { + + GtkButton::child-displacement-x = 0 + GtkButton::child-displacement-y = 0 +} + +# The color is changed by the notebook_bg style, this style +# changes the x/ythickness +style "clearlooks-notebook" { + xthickness = 3 + ythickness = 3 + + bg[SELECTED] = @rt_salt_pinch +} + +style "clearlooks-statusbar" { + + engine "clearlooks" { + hint = "statusbar" + } +} + +style "clearlooks-comboboxentry" { + + engine "clearlooks" { + # Note: + # If you set the appears-as-list option on comboboxes in the theme, + # then you should set this hint on the combobox instead. + hint = "comboboxentry" + } +} + +style "clearlooks-expander" { + xthickness = 3 + ythickness = 3 + + fg[NORMAL] = "#000000" + fg[PRELIGHT] = "#000000" + fg[INSENSITIVE] = mix (0.5, "#000000", @rt_bg_color) + + bg[PRELIGHT] = mix (0.5, @rt_selected_bg_color, @rt_bg_color) + + base[NORMAL] = mix (0.6, @rt_selected_bg_color, @rt_text_color) + base[PRELIGHT] = @rt_selected_fg_color + base[INSENSITIVE] = @rt_selected_bg_color +} + +style "clearlooks-subexpander" = "clearlooks-expander"{ + bg[NORMAL] = @rt_tool_bg +} + +style "clearlooks-menubar" { + + engine "clearlooks" { + hint = "menubar" + } +} + +style "clearlooks-menu" { + xthickness = 0 + ythickness = 0 + + bg[NORMAL] = shade (1.2, @rt_bg_color) + + engine "clearlooks" { + radius = 0.0 + } +} + +style "clearlooks-menu_item" { + xthickness = 2 + ythickness = 3 + + fg[PRELIGHT] = @rt_selected_fg_color + text[NORMAL] = @rt_fg_color + text[PRELIGHT] = @rt_selected_fg_color +} + +# This style is there to modify the separator menu items. The goals are: +# 1. Get a specific height. +# 2. The line should go to the edges (ie. no border at the left/right) +style "clearlooks-separator_menu_item" { + xthickness = 1 + ythickness = 0 + + GtkSeparatorMenuItem::horizontal-padding = 0 + GtkWidget::wide-separators = 1 + GtkWidget::separator-width = 1 + GtkWidget::separator-height = 7 +} + +style "clearlooks-frame_title" { + + fg[NORMAL] = shade (1.40, @rt_bg_color) + fg[PRELIGHT] = shade (1.40, @rt_bg_color) + fg[ACTIVE] = shade (1.40, @rt_bg_color) + fg[SELECTED] = shade (1.40, @rt_bg_color) +} + +style "clearlooks-partialPasteHeaderSep" { + + bg[NORMAL] = mix (0.10, @rt_fg_color, @rt_bg_color) +} + +style "clearlooks-treeview" { + + text[ACTIVE] = @rt_text_color + base[ACTIVE] = mix(0.50, @rt_selected_bg_color, @rt_base_color) + + engine "clearlooks" { + hint = "treeview" + } +} + +# The almost useless progress bar style +style "clearlooks-progressbar" { + xthickness = 1 + ythickness = 1 + + fg[PRELIGHT] = @rt_selected_fg_color + + engine "clearlooks" { + # Explicitly set the radius for the progress bars inside menu items. + radius = 3.0 + + hint = "progressbar" + } +} + +# This style is based on the clearlooks-default style, so that the colors from the button +# style are overriden again. +style "clearlooks-treeview_header" = "clearlooks-default" { + xthickness = 2 + ythickness = 1 + + bg[NORMAL] = shade (1.2, @rt_bg_color) + + engine "clearlooks" { + radius = 0.0 + hint = "treeview-header" + } +} + +style "clearlooks-tooltips" { + xthickness = 4 + ythickness = 4 + + bg[NORMAL] = @rt_tooltip_bg_color + fg[NORMAL] = @rt_tooltip_fg_color +} + +############################################################################### +# The following part of the gtkrc applies the different styles to the widgets. +############################################################################### + +# The clearlooks-default style is applied to every widget +class "GtkWidget" style "clearlooks-default" + +class "GtkSeparator" style "wide" +class "GtkFrame" style "wide" +class "GtkCalendar" style "wide" +class "GtkCheckButton" style "wider" +class "GtkRadioButton" style "wider" +class "GtkEntry" style "clearlooks-entry" + +class "GtkPaned" style "clearlooks-paned" +class "GtkSpinButton" style "clearlooks-spinbutton" +class "GtkScale" style "clearlooks-scale" +class "GtkVScale" style "clearlooks-vscale" +class "GtkHScale" style "clearlooks-hscale" +class "GtkScrollbar" style "clearlooks-scrollbar" +class "GtkHScrollbar" style "clearlooks-hscrollbar" +class "GtkVScrollbar" style "clearlooks-vscrollbar" + +class "GtkHSV" style "clearlooks-HSV" + +# General matching follows. The order is choosen so that the right styles override +# each other. EG. progressbar needs to be more important than the menu match. +widget_class "*" style "clearlooks-notebook_bg" +# This is not perfect, it could be done better. +# (That is modify *every* widget in the notebook, and change those back that +# we really don't want changed) +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" + +widget_class "*." style "clearlooks-combobox" +widget_class "**" style "clearlooks-button" +widget_class "*" style "clearlooks-notebook" +widget_class "**" style "clearlooks-statusbar" + +#widget_class "**" style "clearlooks-comboboxentry" +widget_class "**" style "clearlooks-combobox" + +widget_class "**" style "clearlooks-menubar" +widget_class "**" style "clearlooks-menu" +widget_class "**" style "clearlooks-menu_item" +widget_class "**" style "clearlooks-separator_menu_item" + +widget_class "*." style "clearlooks-frame" +widget_class "*.." style "clearlooks-frame_title" +widget_class "*.*" style "clearlooks-treeview" + +widget_class "*" style "clearlooks-progressbar" + +# Treeview headers (and similar stock GTK+ widgets) +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*...*." style "clearlooks-separator" +widget_class "*...*." style "clearlooks-toolExpanderBox" + +widget "*.partialPasteHeader.*" style "clearlooks-frame_title" +widget "*.partialPasteHeaderSep" style "clearlooks-partialPasteHeaderSep" +widget "*.histButton" style "clearlooks-histButton" +widget "*.FramelessSpinButton" style "clearlooks-framelessspinbutton" +widget "*.ThresholdSelector" style "clearlooks-thresholdselector" +widget "*.MyExpanderTitle.*" style "clearlooks-expander" +widget "*.MyExpanderTitle" style "clearlooks-expander" +widget "*.ExpanderBox" style "clearlooks-toolFrame" +widget "*.ExpanderBox.*.MyExpanderTitle" style "clearlooks-subexpander" +widget "*.ExpanderBox.*.MyExpanderTitle.*" style "clearlooks-subexpander" +widget "*.AxisAdjuster" style "clearlooks-axisadjuster" + +# The window of the tooltip is called "gtk-tooltip" +################################################################## +# FIXME: +# This will not work if one embeds eg. a button into the tooltip. +# As far as I can tell right now we will need to rework the theme +# quite a bit to get this working correctly. +# (It will involve setting different priorities, etc.) +################################################################## +widget "gtk-tooltip*" style "clearlooks-tooltips" + +gtk-icon-theme-name="Light" diff --git a/rtdata/themes/63-Gray-Cyan.iconset b/rtdata/themes/63-Gray-Cyan.iconset new file mode 100644 index 000000000..c51021175 --- /dev/null +++ b/rtdata/themes/63-Gray-Cyan.iconset @@ -0,0 +1,2 @@ +[General] +Iconset=Light diff --git a/rtdata/themes/92-Beige-DarkCyan.gtkrc b/rtdata/themes/92-Beige-DarkCyan.gtkrc new file mode 100644 index 000000000..f6489c4fc --- /dev/null +++ b/rtdata/themes/92-Beige-DarkCyan.gtkrc @@ -0,0 +1,537 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2011 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 . +# + +# Please keep this gtkrc in sync with the other ones from Clearlooks based themes. + +gtk-color-scheme = "rt_base_color:#ffffff\nrt_fg_color:#101010\nrt_tooltip_fg_color:#000000\nrt_selected_bg_color:#7C99AD\nrt_selected_fg_color:#ffffff\nrt_text_color:#000000\nrt_bg_color:#EFEBE7\nrt_tooltip_bg_color:#FFFFBF\nrt_tool_bg:#ebe5df\nrt_tool_border:#cbb9a8" + +style "clearlooks-default" { + xthickness = 1 + ythickness = 1 + + ####################### + # Style Properties + ####################### + GtkButton::child-displacement-x = 1 + GtkButton::child-displacement-y = 1 + GtkButton::default-border = { 0, 0, 0, 0 } + GtkButton::image-spacing = 4 + GtkToolButton::icon-spacing = 4 + + GtkCheckButton::indicator-size = 14 + + GtkPaned::handle-size = 6 + + GtkRange::trough-border = 0 + GtkRange::slider-width = 15 + GtkRange::stepper-size = 15 + + GtkScale::slider-width = 14 + GtkScale::slider-length = 30 + GtkScale::trough-side-details = 0 + + GtkScrollbar::min-slider-length = 30 + GtkMenuBar::internal-padding = 0 + GtkExpander::expander-size = 12 + GtkExpander::expander-spacing = 2 + GtkToolbar::internal-padding = 1 + GtkTreeView::expander-size = 12 + GtkTreeView::vertical-separator = 0 + + GtkMenu::horizontal-padding = 0 + GtkMenu::vertical-padding = 0 + + WnckTasklist::fade-overlay-rect = 0 + # The following line hints to gecko (and possibly other appliations) + # that the entry should be drawn transparently on the canvas. + # Without this, gecko will fill in the background of the entry. + GtkEntry::honors-transparent-bg-hint = 1 + + GtkEntry::progress-border = { 2, 2, 2, 2 } + + #################### + # Color Definitions + #################### + bg[NORMAL] = @rt_bg_color + bg[PRELIGHT] = shade (1.02, @rt_bg_color) + bg[SELECTED] = @rt_selected_bg_color + bg[INSENSITIVE] = @rt_bg_color + bg[ACTIVE] = shade (0.9, @rt_bg_color) + + fg[NORMAL] = @rt_fg_color + fg[PRELIGHT] = @rt_fg_color + fg[SELECTED] = @rt_selected_fg_color + fg[INSENSITIVE] = mix (0.2, @rt_fg_color, @rt_bg_color) + fg[ACTIVE] = @rt_fg_color + + text[NORMAL] = @rt_text_color + text[PRELIGHT] = @rt_text_color + text[SELECTED] = @rt_selected_fg_color + text[INSENSITIVE] = darker (@rt_bg_color) + text[ACTIVE] = @rt_selected_fg_color + + base[NORMAL] = @rt_base_color + base[PRELIGHT] = shade (0.95, @rt_bg_color) + base[SELECTED] = @rt_selected_bg_color + base[INSENSITIVE] = @rt_bg_color + base[ACTIVE] = shade (0.9, @rt_selected_bg_color) + + engine "clearlooks" { + colorize_scrollbar = TRUE + reliefstyle = 1 + menubarstyle = 2 + toolbarstyle = 1 + animation = FALSE + radius = 3.0 + # style between CLASSIC, GLOSSY, INVERTED and GUMMY + style = GUMMY + + # Set a hint to disable backward compatibility fallbacks. + hint = "use-hints" + } +} + +style "wide" { + xthickness = 2 + ythickness = 2 +} + +style "wider" { + xthickness = 3 + ythickness = 3 +} + +style "clearlooks-entry" { + xthickness = 3 + ythickness = 3 + + bg[SELECTED] = mix (0.4, @rt_selected_bg_color, @rt_base_color) + fg[SELECTED] = @rt_text_color + + engine "clearlooks" { + focus_color = shade (0.65, @rt_selected_bg_color) + } +} + +style "clearlooks-paned" { + + bg[PRELIGHT] = shade (0.9, @rt_bg_color) + + engine "clearlooks" { + hint = "paned" + } +} + +style "clearlooks-HSV" { + + engine "clearlooks" { + hint = "HSV" + disable_focus = TRUE + } +} + +style "clearlooks-spinbutton" { + + engine "clearlooks" { + hint = "spinbutton" + } +} + +style "clearlooks-axisadjuster" = "clearlooks-spinbutton" { + # background + base[INSENSITIVE] = @rt_tool_bg + # text + text[INSENSITIVE] = @rt_fg_color +} + +style "clearlooks-framelessspinbutton" { + + # IMPORTANT! + # base[NORMAL] must have the same color than clearlooks.toolContainer / bg[NORMAL] + base[NORMAL] = @rt_tool_bg + base[INSENSITIVE] = @rt_tool_bg + bg[NORMAL] = @rt_tool_bg + bg[INSENSITIVE] = @rt_tool_bg +} + +style "clearlooks-scale" { + xthickness = 2 + ythickness = 2 + + bg[NORMAL] = shade (1.15, @rt_bg_color) + bg[PRELIGHT] = shade (1.25, @rt_bg_color) + # when GtkScale::trough-side-details = 1, bg[SELECTED] set the color of the slider background on the left of the knob + #bg[SELECTED] = @rt_bg_color + + engine "clearlooks" { + focus_color = @rt_selected_bg_color + hint = "scale" + } +} + +style "clearlooks-thresholdselector" { + xthickness = 6 + ythickness = 6 + + bg[NORMAL] = @rt_tool_bg + bg[ACTIVE] = shade (1.20, @rt_bg_color) + bg[PRELIGHT] = shade (1.40, @rt_bg_color) + bg[SELECTED] = shade (1.65, @rt_bg_color) + + fg[PRELIGHT] = shade (1.30, @rt_fg_color) +} + +style "clearlooks-vscale" { + + engine "clearlooks" { + hint = "vscale" + } +} + +style "clearlooks-hscale" { + + engine "clearlooks" { + hint = "hscale" + } +} + +style "clearlooks-scrollbar" { + xthickness = 2 + ythickness = 2 + + #bg[SELECTED] = shade (1.50, @rt_bg_color) + + engine "clearlooks" { + hint = "scrollbar" + } +} + +style "clearlooks-hscrollbar" { + + engine "clearlooks" { + hint = "hscrollbar" + } +} + +style "clearlooks-vscrollbar" { + + engine "clearlooks" { + hint = "vscrollbar" + } +} + +style "clearlooks-notebook_bg" { + + bg[NORMAL] = shade (1.02, @rt_bg_color) +} + +style "clearlooks-toolContainer" { + xthickness = 0 + ythickness = 0 + + # IMPORTANT! + # If you modify bg[NORMAL] below, you must set clearlooks-framelessspinbutton -> base[NORMAL] to the very same value + bg[NORMAL] = @rt_tool_bg + bg[INSENSITIVE] = @rt_tool_bg +} + +style "clearlooks-separator" { + bg[NORMAL] = mix(0.85, @rt_tool_bg, @rt_tool_border) + bg[INSENSITIVE] = mix(0.60, @rt_tool_bg, @rt_tool_border) +} + +style "clearlooks-frame" { + bg[NORMAL] = mix(0.85, @rt_tool_bg, @rt_tool_border) + bg[INSENSITIVE] = mix(0.60, @rt_tool_bg, @rt_tool_border) +} + +style "clearlooks-toolFrame" = "clearlooks-toolContainer" { + bg[NORMAL] = @rt_tool_bg + + fg[NORMAL] = @rt_tool_border + fg[INSENSITIVE] = mix(0.5, @rt_bg_color, @rt_tool_border) +} + +style "clearlooks-toolExpanderBox" { + bg[NORMAL] = @rt_tool_bg + bg[INSENSITIVE] = @rt_tool_bg +} + +style "clearlooks-combobox" { + + text[NORMAL] = @rt_fg_color + text[PRELIGHT] = @rt_fg_color + text[SELECTED] = @rt_selected_fg_color + text[INSENSITIVE] = mix (0.2, @rt_fg_color, @rt_bg_color) + text[ACTIVE] = @rt_fg_color +} + +style "clearlooks-button" { + + bg[NORMAL] = shade (0.96, @rt_bg_color) + bg[PRELIGHT] = shade (1.06, @rt_bg_color) + bg[ACTIVE] = shade (0.85, @rt_bg_color) + + fg[NORMAL] = @rt_fg_color + fg[PRELIGHT] = @rt_fg_color + fg[SELECTED] = @rt_selected_fg_color + fg[INSENSITIVE] = mix (0.2, @rt_fg_color, @rt_bg_color) + fg[ACTIVE] = @rt_fg_color + + engine "clearlooks" + { + hint = "button" + } +} + +style "clearlooks-histButton" { + + GtkButton::child-displacement-x = 0 + GtkButton::child-displacement-y = 0 +} + +# The color is changed by the notebook_bg style, this style +# changes the x/ythickness +style "clearlooks-notebook" { + xthickness = 3 + ythickness = 3 +} + +style "clearlooks-statusbar" { + + engine "clearlooks" { + hint = "statusbar" + } +} + +style "clearlooks-comboboxentry" { + + engine "clearlooks" { + # Note: + # If you set the appears-as-list option on comboboxes in the theme, + # then you should set this hint on the combobox instead. + hint = "comboboxentry" + } +} + +style "clearlooks-expander" { + xthickness = 3 + ythickness = 3 + + fg[NORMAL] = "#000000" + fg[PRELIGHT] = "#000000" + fg[INSENSITIVE] = mix (0.5, "#000000", @rt_bg_color) + + bg[PRELIGHT] = mix (0.5, @rt_selected_bg_color, @rt_bg_color) + + base[NORMAL] = mix (0.6, @rt_selected_bg_color, @rt_text_color) + base[PRELIGHT] = @rt_selected_fg_color + base[INSENSITIVE] = @rt_selected_bg_color +} + +style "clearlooks-subexpander" = "clearlooks-expander"{ + bg[NORMAL] = @rt_tool_bg +} + +style "clearlooks-menubar" { + + engine "clearlooks" { + hint = "menubar" + } +} + +style "clearlooks-menu" { + xthickness = 0 + ythickness = 0 + + bg[NORMAL] = shade (1.08, @rt_bg_color) + + engine "clearlooks" { + radius = 0.0 + } +} + +style "clearlooks-menu_item" { + xthickness = 2 + ythickness = 3 + + fg[PRELIGHT] = @rt_selected_fg_color + text[NORMAL] = @rt_fg_color + text[PRELIGHT] = @rt_selected_fg_color +} + +# This style is there to modify the separator menu items. The goals are: +# 1. Get a specific height. +# 2. The line should go to the edges (ie. no border at the left/right) +style "clearlooks-separator_menu_item" { + xthickness = 1 + ythickness = 0 + + GtkSeparatorMenuItem::horizontal-padding = 0 + GtkWidget::wide-separators = 1 + GtkWidget::separator-width = 1 + GtkWidget::separator-height = 7 +} + +style "clearlooks-frame_title" { + + fg[NORMAL] = lighter (@rt_fg_color) + fg[PRELIGHT] = lighter (@rt_fg_color) + fg[ACTIVE] = lighter (@rt_fg_color) + fg[SELECTED] = lighter (@rt_fg_color) +} + +style "clearlooks-partialPasteHeaderSep" { + + bg[NORMAL] = mix (0.10, @rt_fg_color, @rt_bg_color) +} + +style "clearlooks-treeview" { + + # For an unkown reason, shading 7C99AD produce a redish color, so we have to set the value manually + text[ACTIVE] = @rt_text_color + base[ACTIVE] = mix(0.50, @rt_selected_bg_color, @rt_base_color) + + engine "clearlooks" { + hint = "treeview" + } +} + +# The almost useless progress bar style +style "clearlooks-progressbar" { + xthickness = 1 + ythickness = 1 + + fg[PRELIGHT] = @rt_selected_fg_color + + engine "clearlooks" { + # Explicitly set the radius for the progress bars inside menu items. + radius = 3.0 + + hint = "progressbar" + } +} + +# This style is based on the clearlooks-default style, so that the colors from the button +# style are overriden again. +style "clearlooks-treeview_header" = "clearlooks-default" { + xthickness = 2 + ythickness = 1 + + engine "clearlooks" { + radius = 0.0 + hint = "treeview-header" + } +} + +style "clearlooks-tooltips" { + xthickness = 4 + ythickness = 4 + + bg[NORMAL] = @rt_tooltip_bg_color + fg[NORMAL] = @rt_tooltip_fg_color +} + +############################################################################### +# The following part of the gtkrc applies the different styles to the widgets. +############################################################################### + +# The clearlooks-default style is applied to every widget +class "GtkWidget" style "clearlooks-default" + +class "GtkSeparator" style "wide" +class "GtkFrame" style "wide" +class "GtkCalendar" style "wide" +class "GtkCheckButton" style "wider" +class "GtkRadioButton" style "wider" +class "GtkEntry" style "clearlooks-entry" + +class "GtkPaned" style "clearlooks-paned" +class "GtkSpinButton" style "clearlooks-spinbutton" +class "GtkScale" style "clearlooks-scale" +class "GtkVScale" style "clearlooks-vscale" +class "GtkHScale" style "clearlooks-hscale" +class "GtkScrollbar" style "clearlooks-scrollbar" +class "GtkHScrollbar" style "clearlooks-hscrollbar" +class "GtkVScrollbar" style "clearlooks-vscrollbar" + +class "GtkHSV" style "clearlooks-HSV" + +# General matching follows. The order is choosen so that the right styles override +# each other. EG. progressbar needs to be more important than the menu match. +widget_class "*" style "clearlooks-notebook_bg" +# This is not perfect, it could be done better. +# (That is modify *every* widget in the notebook, and change those back that +# we really don't want changed) +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" +widget_class "**" style "clearlooks-notebook_bg" + +widget_class "*." style "clearlooks-combobox" +widget_class "**" style "clearlooks-button" +widget_class "*" style "clearlooks-notebook" +widget_class "**" style "clearlooks-statusbar" + +#widget_class "**" style "clearlooks-comboboxentry" +widget_class "**" style "clearlooks-combobox" + +widget_class "**" style "clearlooks-menubar" +widget_class "**" style "clearlooks-menu" +widget_class "**" style "clearlooks-menu_item" +widget_class "**" style "clearlooks-separator_menu_item" + +widget_class "*." style "clearlooks-frame" +widget_class "*.." style "clearlooks-frame_title" +widget_class "*.*" style "clearlooks-treeview" + +widget_class "*" style "clearlooks-progressbar" + +# Treeview headers (and similar stock GTK+ widgets) +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*.." style "clearlooks-treeview_header" +widget_class "*...*." style "clearlooks-separator" +widget_class "*...*." style "clearlooks-toolExpanderBox" + +widget "*.partialPasteHeader.*" style "clearlooks-frame_title" +widget "*.partialPasteHeaderSep" style "clearlooks-partialPasteHeaderSep" +widget "*.histButton" style "clearlooks-histButton" +widget "*.FramelessSpinButton" style "clearlooks-framelessspinbutton" +widget "*.ThresholdSelector" style "clearlooks-thresholdselector" +widget "*.MyExpanderTitle.*" style "clearlooks-expander" +widget "*.MyExpanderTitle" style "clearlooks-expander" +widget "*.ExpanderBox" style "clearlooks-toolFrame" +widget "*.ExpanderBox.*.MyExpanderTitle" style "clearlooks-subexpander" +widget "*.ExpanderBox.*.MyExpanderTitle.*" style "clearlooks-subexpander" +widget "*.AxisAdjuster" style "clearlooks-axisadjuster" + +# The window of the tooltip is called "gtk-tooltip" +################################################################## +# FIXME: +# This will not work if one embeds eg. a button into the tooltip. +# As far as I can tell right now we will need to rework the theme +# quite a bit to get this working correctly. +# (It will involve setting different priorities, etc.) +################################################################## +widget "gtk-tooltip*" style "clearlooks-tooltips" + +gtk-icon-theme-name="Light" diff --git a/rtdata/themes/92-Beige-DarkCyan.iconset b/rtdata/themes/92-Beige-DarkCyan.iconset new file mode 100644 index 000000000..c51021175 --- /dev/null +++ b/rtdata/themes/92-Beige-DarkCyan.iconset @@ -0,0 +1,2 @@ +[General] +Iconset=Light diff --git a/rtdata/themes/gray_textured/arrow-down-ins.png b/rtdata/themes/gray_textured/arrow-down-ins.png new file mode 100644 index 000000000..800c23932 Binary files /dev/null and b/rtdata/themes/gray_textured/arrow-down-ins.png differ diff --git a/rtdata/themes/gray_textured/arrow-down-pre.png b/rtdata/themes/gray_textured/arrow-down-pre.png new file mode 100644 index 000000000..9923b2912 Binary files /dev/null and b/rtdata/themes/gray_textured/arrow-down-pre.png differ diff --git a/rtdata/themes/gray_textured/arrow-down.png b/rtdata/themes/gray_textured/arrow-down.png new file mode 100644 index 000000000..962b2fd5b Binary files /dev/null and b/rtdata/themes/gray_textured/arrow-down.png differ diff --git a/rtdata/themes/gray_textured/arrow-left-ins.png b/rtdata/themes/gray_textured/arrow-left-ins.png new file mode 100644 index 000000000..e6e3e8344 Binary files /dev/null and b/rtdata/themes/gray_textured/arrow-left-ins.png differ diff --git a/rtdata/themes/gray_textured/arrow-left-pre.png b/rtdata/themes/gray_textured/arrow-left-pre.png new file mode 100644 index 000000000..f10f4e271 Binary files /dev/null and b/rtdata/themes/gray_textured/arrow-left-pre.png differ diff --git a/rtdata/themes/gray_textured/arrow-left.png b/rtdata/themes/gray_textured/arrow-left.png new file mode 100644 index 000000000..7ea71e8e2 Binary files /dev/null and b/rtdata/themes/gray_textured/arrow-left.png differ diff --git a/rtdata/themes/gray_textured/arrow-right-ins.png b/rtdata/themes/gray_textured/arrow-right-ins.png new file mode 100644 index 000000000..54bc784bd Binary files /dev/null and b/rtdata/themes/gray_textured/arrow-right-ins.png differ diff --git a/rtdata/themes/gray_textured/arrow-right-pre.png b/rtdata/themes/gray_textured/arrow-right-pre.png new file mode 100644 index 000000000..bdb7e99bd Binary files /dev/null and b/rtdata/themes/gray_textured/arrow-right-pre.png differ diff --git a/rtdata/themes/gray_textured/arrow-right.png b/rtdata/themes/gray_textured/arrow-right.png new file mode 100644 index 000000000..24123dd9a Binary files /dev/null and b/rtdata/themes/gray_textured/arrow-right.png differ diff --git a/rtdata/themes/gray_textured/arrow-up-ins.png b/rtdata/themes/gray_textured/arrow-up-ins.png new file mode 100644 index 000000000..b2be1a4ce Binary files /dev/null and b/rtdata/themes/gray_textured/arrow-up-ins.png differ diff --git a/rtdata/themes/gray_textured/arrow-up-pre.png b/rtdata/themes/gray_textured/arrow-up-pre.png new file mode 100644 index 000000000..bc5411fa9 Binary files /dev/null and b/rtdata/themes/gray_textured/arrow-up-pre.png differ diff --git a/rtdata/themes/gray_textured/arrow-up.png b/rtdata/themes/gray_textured/arrow-up.png new file mode 100644 index 000000000..69befd8dc Binary files /dev/null and b/rtdata/themes/gray_textured/arrow-up.png differ diff --git a/rtdata/themes/gray_textured/button-insensitive.png b/rtdata/themes/gray_textured/button-insensitive.png new file mode 100644 index 000000000..fa67fea9a Binary files /dev/null and b/rtdata/themes/gray_textured/button-insensitive.png differ diff --git a/rtdata/themes/gray_textured/button-normal.png b/rtdata/themes/gray_textured/button-normal.png new file mode 100644 index 000000000..573d19a92 Binary files /dev/null and b/rtdata/themes/gray_textured/button-normal.png differ diff --git a/rtdata/themes/gray_textured/button-normal.xcf b/rtdata/themes/gray_textured/button-normal.xcf new file mode 100644 index 000000000..6b2b2ddb0 Binary files /dev/null and b/rtdata/themes/gray_textured/button-normal.xcf differ diff --git a/rtdata/themes/gray_textured/button-prelight.png b/rtdata/themes/gray_textured/button-prelight.png new file mode 100644 index 000000000..00891f69a Binary files /dev/null and b/rtdata/themes/gray_textured/button-prelight.png differ diff --git a/rtdata/themes/gray_textured/button-pressed.png b/rtdata/themes/gray_textured/button-pressed.png new file mode 100644 index 000000000..f49ddd5e9 Binary files /dev/null and b/rtdata/themes/gray_textured/button-pressed.png differ diff --git a/rtdata/themes/gray_textured/null.png b/rtdata/themes/gray_textured/null.png new file mode 100644 index 000000000..82b2fb68e Binary files /dev/null and b/rtdata/themes/gray_textured/null.png differ diff --git a/rtdata/themes/gray_textured/pbtroughh.png b/rtdata/themes/gray_textured/pbtroughh.png new file mode 100644 index 000000000..b05fddaef Binary files /dev/null and b/rtdata/themes/gray_textured/pbtroughh.png differ diff --git a/rtdata/themes/gray_textured/pbtroughv.png b/rtdata/themes/gray_textured/pbtroughv.png new file mode 100644 index 000000000..2e749620f Binary files /dev/null and b/rtdata/themes/gray_textured/pbtroughv.png differ diff --git a/rtdata/themes/gray_textured/rangeslider-ins.png b/rtdata/themes/gray_textured/rangeslider-ins.png new file mode 100644 index 000000000..ee9141c33 Binary files /dev/null and b/rtdata/themes/gray_textured/rangeslider-ins.png differ diff --git a/rtdata/themes/gray_textured/rangeslider-pre.png b/rtdata/themes/gray_textured/rangeslider-pre.png new file mode 100644 index 000000000..d761d1755 Binary files /dev/null and b/rtdata/themes/gray_textured/rangeslider-pre.png differ diff --git a/rtdata/themes/gray_textured/rangeslider.png b/rtdata/themes/gray_textured/rangeslider.png new file mode 100644 index 000000000..208b877a6 Binary files /dev/null and b/rtdata/themes/gray_textured/rangeslider.png differ diff --git a/rtdata/themes/gray_textured/slider-h-ins.png b/rtdata/themes/gray_textured/slider-h-ins.png new file mode 100644 index 000000000..b4fcdc8f2 Binary files /dev/null and b/rtdata/themes/gray_textured/slider-h-ins.png differ diff --git a/rtdata/themes/gray_textured/slider-h-pre.png b/rtdata/themes/gray_textured/slider-h-pre.png new file mode 100644 index 000000000..7f5668cb6 Binary files /dev/null and b/rtdata/themes/gray_textured/slider-h-pre.png differ diff --git a/rtdata/themes/gray_textured/slider-h.png b/rtdata/themes/gray_textured/slider-h.png new file mode 100644 index 000000000..fb748cce3 Binary files /dev/null and b/rtdata/themes/gray_textured/slider-h.png differ diff --git a/rtdata/themes/gray_textured/slider-v-ins.png b/rtdata/themes/gray_textured/slider-v-ins.png new file mode 100644 index 000000000..63754bded Binary files /dev/null and b/rtdata/themes/gray_textured/slider-v-ins.png differ diff --git a/rtdata/themes/gray_textured/slider-v-pre.png b/rtdata/themes/gray_textured/slider-v-pre.png new file mode 100644 index 000000000..266a6d561 Binary files /dev/null and b/rtdata/themes/gray_textured/slider-v-pre.png differ diff --git a/rtdata/themes/gray_textured/slider-v.png b/rtdata/themes/gray_textured/slider-v.png new file mode 100644 index 000000000..0039af03d Binary files /dev/null and b/rtdata/themes/gray_textured/slider-v.png differ diff --git a/rtdata/themes/gray_textured/trough2-h.png b/rtdata/themes/gray_textured/trough2-h.png new file mode 100644 index 000000000..7deae8b70 Binary files /dev/null and b/rtdata/themes/gray_textured/trough2-h.png differ diff --git a/rtdata/themes/gray_textured/trough2.png b/rtdata/themes/gray_textured/trough2.png new file mode 100644 index 000000000..d8dc98143 Binary files /dev/null and b/rtdata/themes/gray_textured/trough2.png differ diff --git a/rtdata/themes/slim b/rtdata/themes/slim new file mode 100644 index 000000000..bc1c05937 --- /dev/null +++ b/rtdata/themes/slim @@ -0,0 +1,140 @@ +# +# This file is part of RawTherapee. +# +# Copyright (c) 2004-2011 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 . +# + +# Please keep this gtkrc in sync with the other ones from Clearlooks based themes. + +gtk-color-scheme = "salt_pinch:#95B0DB\nbase_color:#dddddd\nfg_color:#0A0A0A\ntooltip_fg_color:#000000\nselected_bg_color:#95B0DB\nselected_fg_color:#FFFFFF\ntext_color:#000000\nbg_color:#A1A1A1\ntooltip_bg_color:#F5F5B5" + +style "clearlooks-default" { + xthickness = 1 + ythickness = 1 + + ####################### + # Style Properties + ####################### + GtkButton::child-displacement-x = 0 + GtkButton::child-displacement-y = 0 + GtkButton::default-border = { 0, 0, 0, 0 } + GtkButton::image-spacing = 1 + GtkToolButton::icon-spacing = 1 + + GtkCheckButton::indicator-size = 12 + + GtkPaned::handle-size = 3 + + GtkRange::slider-width = 12 + GtkRange::stepper-size = 12 + + GtkScale::slider-width = 8 + GtkScrollbar::slider-width = 12 + + GtkMenuBar::internal-padding = 0 + GtkExpander::expander-size = 12 + GtkExpander::expander-spacing = 0 + GtkToolbar::internal-padding = 0 + GtkTreeView::expander-size = 10 + + GtkMenu::horizontal-padding = 0 + GtkMenu::vertical-padding = 0 + + GtkNotebook::tab-curvature = 0 + + GtkEntry::progress-border = { 2, 2, 2, 2 } + +} + +style "wide" { + xthickness = 1 + ythickness = 1 +} + +style "wider" { + xthickness = 2 + ythickness = 2 +} + +style "clearlooks-entry" { + xthickness = 1 + ythickness = 1 +} +style "clearlooks-scale" { + xthickness = 1 + ythickness = 1 +} + +style "clearlooks-scrollbar" { + xthickness = 1 + ythickness = 1 +} + +style "clearlooks-button" { + xthickness = 0 + ythickness = 0 +} + +# The color is changed by the notebook_bg style, this style +# changes the x/ythickness +style "clearlooks-notebook" { + xthickness = 1 + ythickness = 1 +} + +style "clearlooks-expander" { + xthickness = 0 + ythickness = 0 +} + +style "clearlooks-thresholdselector" { + xthickness = 1 + ythickness = 1 +} + +style "clearlooks-menu" { + xthickness = 0 + ythickness = 0 +} + +style "clearlooks-menu_item" { + xthickness = 2 + ythickness = 3 +} + +# This style is there to modify the separator menu items. The goals are: +# 1. Get a specific height. +# 2. The line should go to the edges (ie. no border at the left/right) +style "clearlooks-separator_menu_item" { + xthickness = 1 + ythickness = 0 + + GtkSeparatorMenuItem::horizontal-padding = 0 + GtkWidget::separator-height = 5 +} + +# The almost useless progress bar style +style "clearlooks-progressbar" { + xthickness = 1 + ythickness = 1 +} + +# This style is based on the clearlooks-default style, so that the colors from the button +# style are overriden again. +style "clearlooks-treeview_header" { + xthickness = 2 + ythickness = 1 +} diff --git a/rtdata/themes/system.iconset b/rtdata/themes/system.iconset new file mode 100644 index 000000000..c51021175 --- /dev/null +++ b/rtdata/themes/system.iconset @@ -0,0 +1,2 @@ +[General] +Iconset=Light diff --git a/rtdata/win/InnoSetup/WindowsInnoSetup.iss.in b/rtdata/win/InnoSetup/WindowsInnoSetup.iss.in new file mode 100644 index 000000000..9333bd86a --- /dev/null +++ b/rtdata/win/InnoSetup/WindowsInnoSetup.iss.in @@ -0,0 +1,133 @@ +; Script initially generated by the Inno Setup Script Wizard +; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! + + + +; This script has to be used by "INNO Setup" (http://www.jrsoftware.org/) to create a setup executable. +; When the "make install" process ends, you can double click on this file to load it into +; INNO Setup, then execute it to create the archive. It expect to find all the dependency libs +; in the root destination folder (the one of the 'make install' process), and the usual 'lib' directory. +; Please note that all *.dll files will be added, so be carefull on which dll are present in the directory +; before compiling the INNO Setup script. +; +; It also search for and bundles all "rawtherapee*.exe" files, which mean that you can bundle a Release and +; a Debug build at the same time (for conveniency), but official downloads must only contain the Release +; version. +; +; In all cases, you have to bundle at least one file named "rawtherapee.exe", which INNO Setup will require +; as a default executable to run. +; +; This script is configured to check that the operating system's bit depth is the same than the executable file. +; Please note that the ia64 architecture is not supported (is it really necessary?) + + + +#define MyAppName "RawTherapee" +#define MyAppVersion "${HG_VERSION}" +#define MyAppFullVersion "${HG_VERSION}.${HG_TAGDISTANCE}" +#define MyAppPublisher "rawtherapee.com" +#define MyAppURL "http://www.rawtherapee.com/" +#define MyAppExeName "rawtherapee.exe" +#define MyBuildBasePath "${CMAKE_INSTALL_PREFIX}" +#define MySourceBasePath "${PROJECT_SOURCE_DIR}" +#define MyBitDepth "${BUILD_BIT_DEPTH}" +#define MyTargetArchitecture "${ARCHITECTURE_ALLOWED}" +#define MyInstallMode "${INSTALL_MODE}" +#define MySystemName "${SYSTEM_NAME}" + +[Setup] +; NOTE: The value of AppId uniquely identifies this application. +; Do not use the same AppId value in installers for other applications. +; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) +AppId={{128459AB-59A7-430A-8BD0-3D8803D50400} +AppName={#MyAppName} +AppVersion={#MyAppVersion} +VersionInfoVersion={#MyAppFullVersion} +;AppVerName={#MyAppName} {#MyAppVersion} +AppPublisher={#MyAppPublisher} +AppPublisherURL={#MyAppURL} +AppSupportURL={#MyAppURL} +AppUpdatesURL={#MyAppURL} +DefaultDirName={pf}\{#MyAppName}-{#MyAppFullVersion} +DefaultGroupName={#MyAppName} {#MyAppFullVersion} +AllowNoIcons=yes +LicenseFile={#MyBuildBasePath}\LICENSE.txt +OutputDir={#MyBuildBasePath}\..\ +OutputBaseFilename={#MyAppName}_{#MySystemName}_{#MyBitDepth}_{#MyAppFullVersion} +SetupIconFile={#MySourceBasePath}\rtgui\RT.ico +WizardImageFile={#MySourceBasePath}\rtdata\win\InnoSetup\installerStrip.bmp +WizardImageBackColor=$2A2A2A +Compression=lzma +SolidCompression=yes +ArchitecturesAllowed={#MyTargetArchitecture} +ArchitecturesInstallIn64BitMode={#MyInstallMode} +PrivilegesRequired=none + +[Languages] +Name: "english"; MessagesFile: "compiler:Default.isl" +Name: "brazilianportuguese"; MessagesFile: "compiler:Languages\BrazilianPortuguese.isl" +Name: "catalan"; MessagesFile: "compiler:Languages\Catalan.isl" +Name: "corsican"; MessagesFile: "compiler:Languages\Corsican.isl" +Name: "czech"; MessagesFile: "compiler:Languages\Czech.isl" +Name: "danish"; MessagesFile: "compiler:Languages\Danish.isl" +Name: "dutch"; MessagesFile: "compiler:Languages\Dutch.isl" +Name: "finnish"; MessagesFile: "compiler:Languages\Finnish.isl" +Name: "french"; MessagesFile: "compiler:Languages\French.isl" +Name: "german"; MessagesFile: "compiler:Languages\German.isl" +Name: "greek"; MessagesFile: "compiler:Languages\Greek.isl" +Name: "hebrew"; MessagesFile: "compiler:Languages\Hebrew.isl" +Name: "hungarian"; MessagesFile: "compiler:Languages\Hungarian.isl" +Name: "italian"; MessagesFile: "compiler:Languages\Italian.isl" +Name: "japanese"; MessagesFile: "compiler:Languages\Japanese.isl" +Name: "nepali"; MessagesFile: "compiler:Languages\Nepali.islu" +Name: "norwegian"; MessagesFile: "compiler:Languages\Norwegian.isl" +Name: "polish"; MessagesFile: "compiler:Languages\Polish.isl" +Name: "portuguese"; MessagesFile: "compiler:Languages\Portuguese.isl" +Name: "russian"; MessagesFile: "compiler:Languages\Russian.isl" +Name: "serbiancyrillic"; MessagesFile: "compiler:Languages\SerbianCyrillic.isl" +Name: "serbianlatin"; MessagesFile: "compiler:Languages\SerbianLatin.isl" +Name: "slovenian"; MessagesFile: "compiler:Languages\Slovenian.isl" +Name: "spanish"; MessagesFile: "compiler:Languages\Spanish.isl" +Name: "ukrainian"; MessagesFile: "compiler:Languages\Ukrainian.isl" + +[Tasks] +Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked +;Name: "desktopicon\common"; Description: "For all users"; GroupDescription: "Additional icons:"; Flags: exclusive +;Name: "desktopicon\user"; Description: "For the current user only"; GroupDescription: "Additional icons:"; Flags: exclusive unchecked +Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 0,6.1 + +[Files] +Source: "{#MyBuildBasePath}\rawtherapee.exe"; DestDir: "{app}"; Flags: ignoreversion +Source: "{#MyBuildBasePath}\camconst.json"; DestDir: "{app}"; Flags: ignoreversion +Source: "{#MyBuildBasePath}\dcpprofiles\*"; DestDir: "{app}\dcpprofiles\"; Flags: ignoreversion recursesubdirs createallsubdirs +;Source: "{#MyBuildBasePath}\etc\*"; DestDir: "{app}\etc\"; Flags: ignoreversion recursesubdirs createallsubdirs +Source: "{#MyBuildBasePath}\iccprofiles\*"; DestDir: "{app}\iccprofiles\"; Flags: ignoreversion recursesubdirs createallsubdirs +Source: "{#MyBuildBasePath}\images\*"; DestDir: "{app}\images\"; Flags: ignoreversion recursesubdirs createallsubdirs +Source: "{#MyBuildBasePath}\languages\*"; DestDir: "{app}\languages\"; Flags: ignoreversion recursesubdirs createallsubdirs +Source: "{#MyBuildBasePath}\licenses\*"; DestDir: "{app}\licenses\"; Flags: ignoreversion recursesubdirs createallsubdirs +Source: "{#MyBuildBasePath}\lib\*"; DestDir: "{app}\lib\"; Flags: ignoreversion recursesubdirs createallsubdirs +Source: "{#MyBuildBasePath}\profiles\*"; DestDir: "{app}\profiles\"; Flags: ignoreversion recursesubdirs createallsubdirs +Source: "{#MyBuildBasePath}\sounds\*"; DestDir: "{app}\sounds\"; Flags: ignoreversion recursesubdirs createallsubdirs +Source: "{#MyBuildBasePath}\themes\*"; DestDir: "{app}\themes\"; Flags: ignoreversion recursesubdirs createallsubdirs +Source: "{#MyBuildBasePath}\AboutThisBuild.txt"; DestDir: "{app}"; Flags: ignoreversion +Source: "{#MyBuildBasePath}\AUTHORS.txt"; DestDir: "{app}"; Flags: ignoreversion +Source: "{#MyBuildBasePath}\LICENSE.txt"; DestDir: "{app}"; Flags: ignoreversion +Source: "{#MyBuildBasePath}\RELEASE_NOTES.txt"; DestDir: "{app}"; Flags: ignoreversion +Source: "{#MyBuildBasePath}\options"; DestDir: "{app}"; Flags: ignoreversion +Source: "{#MyBuildBasePath}\*.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "{#MyBuildBasePath}\gspawn-win{#MyBitDepth}-helper.exe"; DestDir: "{app}"; Flags: ignoreversion +Source: "{#MyBuildBasePath}\gspawn-win{#MyBitDepth}-helper-console.exe"; DestDir: "{app}"; Flags: ignoreversion + +Source: "{#MyBuildBasePath}\fonts\DroidSansMonoSlashed.ttf"; DestDir: "{fonts}"; FontInstall: "Droid Sans Mono Slashed"; Flags: onlyifdoesntexist uninsneveruninstall +; NOTE: Don't use "Flags: ignoreversion" on any shared system files + +[Icons] +Name: "{group}\{#MyAppName} {#MyAppFullVersion}"; Filename: "{app}\{#MyAppExeName}" +Name: "{group}\{cm:ProgramOnTheWeb,{#MyAppName}}"; Filename: "{#MyAppURL}" +Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}" +Name: "{commondesktop}\{#MyAppName}{#MyAppFullVersion}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon +Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\{#MyAppName} {#MyAppFullVersion}"; Filename: "{app}\{#MyAppExeName}"; Tasks: quicklaunchicon + +[Run] +Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent + diff --git a/rtdata/win/InnoSetup/installerStrip.bmp b/rtdata/win/InnoSetup/installerStrip.bmp new file mode 100644 index 000000000..032414c26 Binary files /dev/null and b/rtdata/win/InnoSetup/installerStrip.bmp differ diff --git a/rtdata/win/InnoSetup/installerStrip.svg b/rtdata/win/InnoSetup/installerStrip.svg new file mode 100644 index 000000000..eba47f3ff --- /dev/null +++ b/rtdata/win/InnoSetup/installerStrip.svg @@ -0,0 +1,671 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/rtdata/win/readme.txt b/rtdata/win/readme.txt new file mode 100644 index 000000000..f32cdb50a --- /dev/null +++ b/rtdata/win/readme.txt @@ -0,0 +1,14 @@ + +INSTALLER SCRIPTS +----------------- + +This "win" directory includes installer setup mechanisms for Windows 32/64. + +As requested in issue 1904 ( http://code.google.com/p/rawtherapee/issues/detail?id=1904 ), +the preferred choice of setup mechanism is Wix widgets. However an InnoSetup script has been +created before the definitive choice and has been added to the source tree, for convenience. + +Once the Wix setup mechanism will be operational, the InnoSetup can be supressed from the source +tree. + +All discussion about the present document and the setup scripts has to be done in issue 1904. \ No newline at end of file diff --git a/rtengine/CA_correct_RT.cc b/rtengine/CA_correct_RT.cc new file mode 100644 index 000000000..f03573e31 --- /dev/null +++ b/rtengine/CA_correct_RT.cc @@ -0,0 +1,1015 @@ +//////////////////////////////////////////////////////////////// +// +// Chromatic Aberration Auto-correction +// +// copyright (c) 2008-2010 Emil Martinec +// +// +// code dated: November 26, 2010 +// +// CA_correct_RT.cc is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +//////////////////////////////////////////////////////////////// +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +#include "rtengine.h" +#include "rawimagesource.h" +#include "rt_math.h" + +using namespace std; +using namespace rtengine; + +int RawImageSource::LinEqSolve(int nDim, double* pfMatr, double* pfVect, double* pfSolution) +{ +//============================================================================== +// return 1 if system not solving, 0 if system solved +// nDim - system dimension +// pfMatr - matrix with coefficients +// pfVect - vector with free members +// pfSolution - vector with system solution +// pfMatr becames trianglular after function call +// pfVect changes after function call +// +// Developer: Henry Guennadi Levkin +// +//============================================================================== + + double fMaxElem; + double fAcc; + + int i, j, k, m; + + for(k=0; k<(nDim-1); k++) {// base row of matrix + // search of line with max element + fMaxElem = fabsf( pfMatr[k*nDim + k] ); + m = k; + for (i=k+1; i=0; k--) { + pfSolution[k] = pfVect[k]; + for(i=(k+1); i(b)) {temp=(a);(a)=(b);(b)=temp;} } + + // Test for RGB cfa + for(int i=0;i<2;i++) + for(int j=0;j<2;j++) + if(FC(i,j) == 3) { + printf("CA correction supports only RGB Color filter arrays\n"); + return; + } + + volatile double progress = 0.0; + if(plistener) plistener->setProgress (progress); + + bool autoCA = (cared==0 && cablue==0); + // local variables + int width=W, height=H; + //temporary array to store simple interpolation of G + float (*Gtmp); + Gtmp = (float (*)) calloc ((height)*(width), sizeof *Gtmp); + + // temporary array to avoid race conflicts, only every second pixel needs to be saved here + float (*RawDataTmp); + RawDataTmp = (float*) malloc( height * width * sizeof(float)/2); + + float blockave[2][3]={{0,0,0},{0,0,0}}, blocksqave[2][3]={{0,0,0},{0,0,0}}, blockdenom[2][3]={{0,0,0},{0,0,0}}, blockvar[2][3]; + + // Because we can't break parallel processing, we need a switch do handle the errors + bool processpasstwo = true; + + //block CA shift values and weight assigned to block + char *buffer1; // vblsz*hblsz*(3*2+1) + float (*blockwt); // vblsz*hblsz + float (*blockshifts)[3][2]; // vblsz*hblsz*3*2 + + + const int border=8; + const int border2=16; + + int vz1, hz1; + if((height+border2)%(TS-border2)==0) vz1=1; else vz1=0; + if((width+border2)%(TS-border2)==0) hz1=1; else hz1=0; + + int vblsz, hblsz; + vblsz=ceil((float)(height+border2)/(TS-border2)+2+vz1); + hblsz=ceil((float)(width+border2)/(TS-border2)+2+hz1); + + buffer1 = (char *) malloc(vblsz*hblsz*(3*2+1)*sizeof(float)); + //merror(buffer1,"CA_correct()"); + memset(buffer1,0,vblsz*hblsz*(3*2+1)*sizeof(float)); + // block CA shifts + blockwt = (float (*)) (buffer1); + blockshifts = (float (*)[3][2]) (buffer1+(vblsz*hblsz*sizeof(float))); + + double fitparams[3][2][16]; + + //order of 2d polynomial fit (polyord), and numpar=polyord^2 + int polyord=4, numpar=16; + +#pragma omp parallel shared(Gtmp,width,height,blockave,blocksqave,blockdenom,blockvar,blockwt,blockshifts,fitparams,polyord,numpar) +{ + int progresscounter = 0; + + int rrmin, rrmax, ccmin, ccmax; + int top, left, row, col; + int rr, cc, c, indx, indx1, i, j, k, m, n, dir; + //number of pixels in a tile contributing to the CA shift diagnostic + int areawt[2][3]; + //direction of the CA shift in a tile + int GRBdir[2][3]; + //offset data of the plaquette where the optical R/B data are sampled + int offset[2][3]; + int shifthfloor[3], shiftvfloor[3], shifthceil[3], shiftvceil[3]; + //number of tiles in the image + int vblock, hblock; + //int verbose=1; + //flag indicating success or failure of polynomial fit + int res; + //shifts to location of vertical and diagonal neighbors + const int v1=TS, v2=2*TS, v3=3*TS, v4=4*TS;//, p1=-TS+1, p2=-2*TS+2, p3=-3*TS+3, m1=TS+1, m2=2*TS+2, m3=3*TS+3; + + float eps=1e-5f, eps2=1e-10f; //tolerance to avoid dividing by zero + + //adaptive weights for green interpolation + float wtu, wtd, wtl, wtr; + //local quadratic fit to shift data within a tile + float coeff[2][3][3]; + //measured CA shift parameters for a tile + float CAshift[2][3]; + //polynomial fit coefficients + //residual CA shift amount within a plaquette + float shifthfrac[3], shiftvfrac[3]; + //temporary storage for median filter + float temp, p[9]; + //temporary parameters for tile CA evaluation + float gdiff, deltgrb; + //interpolated G at edge of plaquette + float Ginthfloor, Ginthceil, Gint, RBint, gradwt; + //interpolated color difference at edge of plaquette + float grbdiffinthfloor, grbdiffinthceil, grbdiffint, grbdiffold; + //per thread data for evaluation of block CA shift variance + float blockavethr[2][3]={{0,0,0},{0,0,0}}, blocksqavethr[2][3]={{0,0,0},{0,0,0}}, blockdenomthr[2][3]={{0,0,0},{0,0,0}};//, blockvarthr[2][3]; + + //low and high pass 1D filters of G in vertical/horizontal directions + float glpfh, glpfv; + + //max allowed CA shift + const float bslim = 3.99; + //gaussians for low pass filtering of G and R/B + //static const float gaussg[5] = {0.171582, 0.15839, 0.124594, 0.083518, 0.0477063};//sig=2.5 + //static const float gaussrb[3] = {0.332406, 0.241376, 0.0924212};//sig=1.25 + + //block CA shift values and weight assigned to block + + char *buffer; // TS*TS*16 + //rgb data in a tile + float* rgb[3]; + //color differences + float (*grbdiff); // TS*TS*4 + //green interpolated to optical sample points for R/B + float (*gshift); // TS*TS*4 + //high pass filter for R/B in vertical direction + float (*rbhpfh); // TS*TS*4 + //high pass filter for R/B in horizontal direction + float (*rbhpfv); // TS*TS*4 + //low pass filter for R/B in horizontal direction + float (*rblpfh); // TS*TS*4 + //low pass filter for R/B in vertical direction + float (*rblpfv); // TS*TS*4 + //low pass filter for color differences in horizontal direction + float (*grblpfh); // TS*TS*4 + //low pass filter for color differences in vertical direction + float (*grblpfv); // TS*TS*4 + + + /* assign working space; this would not be necessary + if the algorithm is part of the larger pre-interpolation processing */ + buffer = (char *) malloc(3*sizeof(float)*TS*TS + 8*sizeof(float)*TS*TSH + 10*64 + 64); + //merror(buffer,"CA_correct()"); + memset(buffer,0,3*sizeof(float)*TS*TS + 8*sizeof(float)*TS*TSH + 10*64 + 64); + + char *data; + data = buffer; + +// buffers aligned to size of cacheline +// data = (char*)( ( uintptr_t(buffer) + uintptr_t(63)) / 64 * 64); + + + // shift the beginning of all arrays but the first by 64 bytes to avoid cache miss conflicts on CPUs which have <=4-way associative L1-Cache + 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); + grbdiff = (float (*)) (data + 3*sizeof(float)*TS*TS + 3*64); + gshift = (float (*)) (data + 3*sizeof(float)*TS*TS + sizeof(float)*TS*TSH + 4*64); + rbhpfh = (float (*)) (data + 4*sizeof(float)*TS*TS + 5*64); + rbhpfv = (float (*)) (data + 4*sizeof(float)*TS*TS + sizeof(float)*TS*TSH + 6*64); + rblpfh = (float (*)) (data + 5*sizeof(float)*TS*TS + 7*64); + rblpfv = (float (*)) (data + 5*sizeof(float)*TS*TS + sizeof(float)*TS*TSH + 8*64); + grblpfh = (float (*)) (data + 6*sizeof(float)*TS*TS + 9*64); + grblpfv = (float (*)) (data + 6*sizeof(float)*TS*TS + sizeof(float)*TS*TSH + 10*64); + + + if (autoCA) { + // Main algorithm: Tile loop +#pragma omp for collapse(2) schedule(dynamic) nowait + for (top=-border ; top < height; top += TS-border2) + for (left=-border; left < width; left += TS-border2) { + vblock = ((top+border)/(TS-border2))+1; + hblock = ((left+border)/(TS-border2))+1; + int bottom = min(top+TS,height+border); + int right = min(left+TS, width+border); + int rr1 = bottom - top; + int cc1 = right - left; + //t1_init = clock(); + if (top<0) {rrmin=border;} else {rrmin=0;} + if (left<0) {ccmin=border;} else {ccmin=0;} + if (bottom>height) {rrmax=height-top;} else {rrmax=rr1;} + if (right>width) {ccmax=width-left;} else {ccmax=cc1;} + + // rgb from input CFA data + // rgb values should be floating point number between 0 and 1 + // after white balance multipliers are applied + + for (rr=rrmin; rr < rrmax; rr++) + for (row=rr+top, cc=ccmin; cc < ccmax; cc++) { + col = cc+left; + c = FC(rr,cc); + indx=row*width+col; + indx1=rr*TS+cc; + rgb[c][indx1] = (rawData[row][col])/65535.0f; + //rgb[indx1][c] = image[indx][c]/65535.0f;//for dcraw implementation + } + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + //fill borders + if (rrmin>0) { + for (rr=0; rr0) { + for (rr=rrmin; rr0 && ccmin>0) { + for (rr=0; rr0 && ccmax0) { + for (rr=0; rr-1 && row-1 && col>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]))); + + /*ghpfv = fabsf(fabsf(rgb[indx][1]-rgb[indx+v4][1])+fabsf(rgb[indx][1]-rgb[indx-v4][1]) - + fabsf(rgb[indx+v4][1]-rgb[indx-v4][1])); + ghpfh = fabsf(fabsf(rgb[indx][1]-rgb[indx+4][1])+fabsf(rgb[indx][1]-rgb[indx-4][1]) - + fabsf(rgb[indx+4][1]-rgb[indx-4][1])); + rbhpfv[indx] = fabsf(ghpfv - fabsf(fabsf(rgb[indx][c]-rgb[indx+v4][c])+fabsf(rgb[indx][c]-rgb[indx-v4][c]) - + fabsf(rgb[indx+v4][c]-rgb[indx-v4][c]))); + rbhpfh[indx] = fabsf(ghpfh - fabsf(fabsf(rgb[indx][c]-rgb[indx+4][c])+fabsf(rgb[indx][c]-rgb[indx-4][c]) - + fabsf(rgb[indx+4][c]-rgb[indx-4][c])));*/ + + glpfv = 0.25*(2.0*rgb[1][indx]+rgb[1][indx+v2]+rgb[1][indx-v2]); + glpfh = 0.25*(2.0*rgb[1][indx]+rgb[1][indx+2]+rgb[1][indx-2]); + rblpfv[indx>>1] = eps+fabsf(glpfv - 0.25*(2.0*rgb[c][indx]+rgb[c][indx+v2]+rgb[c][indx-v2])); + rblpfh[indx>>1] = eps+fabsf(glpfh - 0.25*(2.0*rgb[c][indx]+rgb[c][indx+2]+rgb[c][indx-2])); + grblpfv[indx>>1] = glpfv + 0.25*(2.0*rgb[c][indx]+rgb[c][indx+v2]+rgb[c][indx-v2]); + grblpfh[indx>>1] = glpfh + 0.25*(2.0*rgb[c][indx]+rgb[c][indx+2]+rgb[c][indx-2]); + } + areawt[0][0]=areawt[1][0]=1; + areawt[0][2]=areawt[1][2]=1; + + // along line segments, find the point along each segment that minimizes the color variance + // averaged over the tile; evaluate for up/down and left/right away from R/B grid point + for (rr=8; rr < rr1-8; rr++) + for (cc=8+(FC(rr,2)&1), indx=rr*TS+cc, c = FC(rr,cc); cc < cc1-8; cc+=2, indx+=2) { + +// areawt[0][c]=areawt[1][c]=0; + + //in linear interpolation, color differences are a quadratic function of interpolation position; + //solve for the interpolation position that minimizes color difference variance over the tile + + //vertical + gdiff=0.3125*(rgb[1][indx+TS]-rgb[1][indx-TS])+0.09375*(rgb[1][indx+TS+1]-rgb[1][indx-TS+1]+rgb[1][indx+TS-1]-rgb[1][indx-TS-1]); + deltgrb=(rgb[c][indx]-rgb[1][indx]); + + gradwt=fabsf(0.25*rbhpfv[indx>>1]+0.125*(rbhpfv[(indx>>1)+1]+rbhpfv[(indx>>1)-1]) )*(grblpfv[(indx>>1)-v1]+grblpfv[(indx>>1)+v1])/(eps+0.1*grblpfv[(indx>>1)-v1]+rblpfv[(indx>>1)-v1]+0.1*grblpfv[(indx>>1)+v1]+rblpfv[(indx>>1)+v1]); + + coeff[0][0][c] += gradwt*deltgrb*deltgrb; + coeff[0][1][c] += gradwt*gdiff*deltgrb; + coeff[0][2][c] += gradwt*gdiff*gdiff; +// areawt[0][c]+=1; + + //horizontal + gdiff=0.3125*(rgb[1][indx+1]-rgb[1][indx-1])+0.09375*(rgb[1][indx+1+TS]-rgb[1][indx-1+TS]+rgb[1][indx+1-TS]-rgb[1][indx-1-TS]); + deltgrb=(rgb[c][indx]-rgb[1][indx]); + + gradwt=fabsf(0.25*rbhpfh[indx>>1]+0.125*(rbhpfh[(indx>>1)+v1]+rbhpfh[(indx>>1)-v1]) )*(grblpfh[(indx>>1)-1]+grblpfh[(indx>>1)+1])/(eps+0.1*grblpfh[(indx>>1)-1]+rblpfh[(indx>>1)-1]+0.1*grblpfh[(indx>>1)+1]+rblpfh[(indx>>1)+1]); + + coeff[1][0][c] += gradwt*deltgrb*deltgrb; + coeff[1][1][c] += gradwt*gdiff*deltgrb; + coeff[1][2][c] += gradwt*gdiff*gdiff; +// areawt[1][c]+=1; + + // In Mathematica, + // f[x_]=Expand[Total[Flatten[ + // ((1-x) RotateLeft[Gint,shift1]+x RotateLeft[Gint,shift2]-cfapad)^2[[dv;;-1;;2,dh;;-1;;2]]]]]; + // extremum = -.5Coefficient[f[x],x]/Coefficient[f[x],x^2] + } + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + /* + for (rr=4; rr < rr1-4; rr++) + for (cc=4+(FC(rr,2)&1), indx=rr*TS+cc, c = FC(rr,cc); cc < cc1-4; cc+=2, indx+=2) { + + + rbhpfv[indx] = SQR(fabs((rgb[indx][1]-rgb[indx][c])-(rgb[indx+v4][1]-rgb[indx+v4][c])) + + fabs((rgb[indx-v4][1]-rgb[indx-v4][c])-(rgb[indx][1]-rgb[indx][c])) - + fabs((rgb[indx-v4][1]-rgb[indx-v4][c])-(rgb[indx+v4][1]-rgb[indx+v4][c]))); + rbhpfh[indx] = SQR(fabs((rgb[indx][1]-rgb[indx][c])-(rgb[indx+4][1]-rgb[indx+4][c])) + + fabs((rgb[indx-4][1]-rgb[indx-4][c])-(rgb[indx][1]-rgb[indx][c])) - + fabs((rgb[indx-4][1]-rgb[indx-4][c])-(rgb[indx+4][1]-rgb[indx+4][c]))); + + + glpfv = 0.25*(2*rgb[indx][1]+rgb[indx+v2][1]+rgb[indx-v2][1]); + glpfh = 0.25*(2*rgb[indx][1]+rgb[indx+2][1]+rgb[indx-2][1]); + rblpfv[indx] = eps+fabs(glpfv - 0.25*(2*rgb[indx][c]+rgb[indx+v2][c]+rgb[indx-v2][c])); + rblpfh[indx] = eps+fabs(glpfh - 0.25*(2*rgb[indx][c]+rgb[indx+2][c]+rgb[indx-2][c])); + grblpfv[indx] = glpfv + 0.25*(2*rgb[indx][c]+rgb[indx+v2][c]+rgb[indx-v2][c]); + grblpfh[indx] = glpfh + 0.25*(2*rgb[indx][c]+rgb[indx+2][c]+rgb[indx-2][c]); + } + + for (c=0;c<3;c++) {areawt[0][c]=areawt[1][c]=0;} + + // along line segments, find the point along each segment that minimizes the color variance + // averaged over the tile; evaluate for up/down and left/right away from R/B grid point + for (rr=rrmin+8; rr < rrmax-8; rr++) + for (cc=ccmin+8+(FC(rr,2)&1), indx=rr*TS+cc, c = FC(rr,cc); cc < ccmax-8; cc+=2, indx+=2) { + + if (rgb[indx][c]>0.8*clip_pt || Gtmp[indx]>0.8*clip_pt) continue; + + //in linear interpolation, color differences are a quadratic function of interpolation position; + //solve for the interpolation position that minimizes color difference variance over the tile + + //vertical + gdiff=0.3125*(rgb[indx+TS][1]-rgb[indx-TS][1])+0.09375*(rgb[indx+TS+1][1]-rgb[indx-TS+1][1]+rgb[indx+TS-1][1]-rgb[indx-TS-1][1]); + deltgrb=(rgb[indx][c]-rgb[indx][1])-0.5*((rgb[indx-v4][c]-rgb[indx-v4][1])+(rgb[indx+v4][c]-rgb[indx+v4][1])); + + gradwt=fabs(0.25*rbhpfv[indx]+0.125*(rbhpfv[indx+2]+rbhpfv[indx-2]) );// *(grblpfv[indx-v2]+grblpfv[indx+v2])/(eps+0.1*grblpfv[indx-v2]+rblpfv[indx-v2]+0.1*grblpfv[indx+v2]+rblpfv[indx+v2]); + if (gradwt>eps) { + coeff[0][0][c] += gradwt*deltgrb*deltgrb; + coeff[0][1][c] += gradwt*gdiff*deltgrb; + coeff[0][2][c] += gradwt*gdiff*gdiff; + areawt[0][c]++; + } + + //horizontal + gdiff=0.3125*(rgb[indx+1][1]-rgb[indx-1][1])+0.09375*(rgb[indx+1+TS][1]-rgb[indx-1+TS][1]+rgb[indx+1-TS][1]-rgb[indx-1-TS][1]); + deltgrb=(rgb[indx][c]-rgb[indx][1])-0.5*((rgb[indx-4][c]-rgb[indx-4][1])+(rgb[indx+4][c]-rgb[indx+4][1])); + + gradwt=fabs(0.25*rbhpfh[indx]+0.125*(rbhpfh[indx+v2]+rbhpfh[indx-v2]) );// *(grblpfh[indx-2]+grblpfh[indx+2])/(eps+0.1*grblpfh[indx-2]+rblpfh[indx-2]+0.1*grblpfh[indx+2]+rblpfh[indx+2]); + if (gradwt>eps) { + coeff[1][0][c] += gradwt*deltgrb*deltgrb; + coeff[1][1][c] += gradwt*gdiff*deltgrb; + coeff[1][2][c] += gradwt*gdiff*gdiff; + areawt[1][c]++; + } + + // In Mathematica, + // f[x_]=Expand[Total[Flatten[ + // ((1-x) RotateLeft[Gint,shift1]+x RotateLeft[Gint,shift2]-cfapad)^2[[dv;;-1;;2,dh;;-1;;2]]]]]; + // extremum = -.5Coefficient[f[x],x]/Coefficient[f[x],x^2] + }*/ + for (c=0; c<3; c+=2){ + for (j=0; j<2; j++) {// vert/hor + //printf("hblock %d vblock %d j %d c %d areawt %d \n",hblock,vblock,j,c,areawt[j][c]); + //printf("hblock %d vblock %d j %d c %d areawt %d ",hblock,vblock,j,c,areawt[j][c]); + + if (areawt[j][c]>0 && coeff[j][2][c]>eps2) { + CAshift[j][c]=coeff[j][1][c]/coeff[j][2][c]; + blockwt[vblock*hblsz+hblock]= areawt[j][c]*coeff[j][2][c]/(eps+coeff[j][0][c]) ; + } else { + CAshift[j][c]=17.0; + blockwt[vblock*hblsz+hblock]=0; + } + //if (c==0 && j==0) printf("vblock= %d hblock= %d denom= %f areawt= %d \n",vblock,hblock,coeff[j][2][c],areawt[j][c]); + + //printf("%f \n",CAshift[j][c]); + + //data structure = CAshift[vert/hor][color] + //j=0=vert, 1=hor + + //offset gives NW corner of square containing the min; j=0=vert, 1=hor + + if (fabsf(CAshift[j][c])<2.0f) { + blockavethr[j][c] += CAshift[j][c]; + blocksqavethr[j][c] += SQR(CAshift[j][c]); + blockdenomthr[j][c] += 1; + } + }//vert/hor + }//color + + /* CAshift[j][c] are the locations + that minimize color difference variances; + This is the approximate _optical_ location of the R/B pixels */ + + for (c=0; c<3; c+=2) { + //evaluate the shifts to the location that minimizes CA within the tile + blockshifts[(vblock)*hblsz+hblock][c][0]=(CAshift[0][c]); //vert CA shift for R/B + blockshifts[(vblock)*hblsz+hblock][c][1]=(CAshift[1][c]); //hor CA shift for R/B + //data structure: blockshifts[blocknum][R/B][v/h] + //if (c==0) printf("vblock= %d hblock= %d blockshiftsmedian= %f \n",vblock,hblock,blockshifts[(vblock)*hblsz+hblock][c][0]); + } + if(plistener) { + progresscounter++; + if(progresscounter % 8 == 0) +#pragma omp critical + { + progress+=(double)(8.0*(TS-border2)*(TS-border2))/(2*height*width); + if (progress>1.0) + { + progress=1.0; + } + plistener->setProgress(progress); + } + } + + } + + //end of diagnostic pass +#pragma omp critical +{ + for (j=0; j<2; j++) + for (c=0; c<3; c+=2) { + blockdenom[j][c] += blockdenomthr[j][c]; + blocksqave[j][c] += blocksqavethr[j][c]; + blockave[j][c] += blockavethr[j][c]; + } +} +#pragma omp barrier + +#pragma omp single +{ + for (j=0; j<2; j++) + for (c=0; c<3; c+=2) { + if (blockdenom[j][c]) { + blockvar[j][c] = blocksqave[j][c]/blockdenom[j][c]-SQR(blockave[j][c]/blockdenom[j][c]); + } else { + processpasstwo = false; + printf ("blockdenom vanishes \n"); + break; + } + } + //printf ("tile variances %f %f %f %f \n",blockvar[0][0],blockvar[1][0],blockvar[0][2],blockvar[1][2] ); + + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + //now prepare for CA correction pass + //first, fill border blocks of blockshift array + if(processpasstwo) { + for (vblock=1; vblock4.0*blockvar[0][c] || SQR(bstemp[1])>4.0*blockvar[1][c]) + continue; + numblox[c]++; + for (dir=0; dir<2; dir++) { + for (i=0; iheight) {rrmax=height-top;} else {rrmax=rr1;} + if (right>width) {ccmax=width-left;} else {ccmax=cc1;} + + // rgb from input CFA data + // rgb values should be floating point number between 0 and 1 + // after white balance multipliers are applied + + for (rr=rrmin; rr < rrmax; rr++) + for (row=rr+top, cc=ccmin; cc < ccmax; cc++) { + col = cc+left; + c = FC(rr,cc); + indx=row*width+col; + indx1=rr*TS+cc; + //rgb[indx1][c] = image[indx][c]/65535.0f; + rgb[c][indx1] = (rawData[row][col])/65535.0f; + //rgb[indx1][c] = image[indx][c]/65535.0f;//for dcraw implementation + + if ((c&1)==0) rgb[1][indx1] = Gtmp[indx]; + } + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + //fill borders + if (rrmin>0) { + for (rr=0; rr0) { + for (rr=rrmin; rr0 && ccmin>0) { + for (rr=0; rr0 && ccmax0) { + for (rr=0; rr-1 && row-1 && col0) { + GRBdir[0][c] = 1; + } else { + GRBdir[0][c] = -1; + } + if (blockshifts[(vblock)*hblsz+hblock][c][1]>0) { + GRBdir[1][c] = 1; + } else { + GRBdir[1][c] = -1; + } + + } + + + for (rr=4; rr < rr1-4; rr++) + for (cc=4+(FC(rr,2)&1), c = FC(rr,cc); cc < cc1-4; cc+=2) { + //perform CA correction using color ratios or color differences + + Ginthfloor=(1-shifthfrac[c])*rgb[1][(rr+shiftvfloor[c])*TS+cc+shifthfloor[c]]+(shifthfrac[c])*rgb[1][(rr+shiftvfloor[c])*TS+cc+shifthceil[c]]; + Ginthceil=(1-shifthfrac[c])*rgb[1][(rr+shiftvceil[c])*TS+cc+shifthfloor[c]]+(shifthfrac[c])*rgb[1][(rr+shiftvceil[c])*TS+cc+shifthceil[c]]; + //Gint is blinear interpolation of G at CA shift point + Gint=(1-shiftvfrac[c])*Ginthfloor+(shiftvfrac[c])*Ginthceil; + + //determine R/B at grid points using color 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; + } + + for (rr=8; rr < rr1-8; rr++) + for (cc=8+(FC(rr,2)&1), c = FC(rr,cc), indx=rr*TS+cc; cc < cc1-8; cc+=2, indx+=2) { + + //if (rgb[indx][c]>clip_pt || Gtmp[indx]>clip_pt) continue; + + grbdiffold = rgb[1][indx]-rgb[c][indx]; + + //interpolate color difference from optical R/B locations to grid locations + grbdiffinthfloor=(1.0f-shifthfrac[c]/2.0f)*grbdiff[indx>>1]+(shifthfrac[c]/2.0f)*grbdiff[(indx-2*GRBdir[1][c])>>1]; + grbdiffinthceil=(1.0f-shifthfrac[c]/2.0f)*grbdiff[((rr-2*GRBdir[0][c])*TS+cc)>>1]+(shifthfrac[c]/2.0f)*grbdiff[((rr-2*GRBdir[0][c])*TS+cc-2*GRBdir[1][c])>>1]; + //grbdiffint is bilinear interpolation of G-R/G-B at grid point + grbdiffint=(1.0f-shiftvfrac[c]/2.0f)*grbdiffinthfloor+(shiftvfrac[c]/2.0f)*grbdiffinthceil; + + //now determine R/B at grid points using interpolated color differences and interpolated G value at grid point + RBint=rgb[1][indx]-grbdiffint; + + if (fabsf(RBint-rgb[c][indx])<0.25f*(RBint+rgb[c][indx])) { + if (fabsf(grbdiffold)>fabsf(grbdiffint) ) { + rgb[c][indx]=RBint; + } + } else { + + //gradient weights using difference from G at CA shift points and G at grid points + p[0]=1.0f/(eps+fabsf(rgb[1][indx]-gshift[indx>>1])); + p[1]=1.0f/(eps+fabsf(rgb[1][indx]-gshift[(indx-2*GRBdir[1][c])>>1])); + p[2]=1.0f/(eps+fabsf(rgb[1][indx]-gshift[((rr-2*GRBdir[0][c])*TS+cc)>>1])); + p[3]=1.0f/(eps+fabsf(rgb[1][indx]-gshift[((rr-2*GRBdir[0][c])*TS+cc-2*GRBdir[1][c])>>1])); + + grbdiffint = (p[0]*grbdiff[indx>>1]+p[1]*grbdiff[(indx-2*GRBdir[1][c])>>1]+ + p[2]*grbdiff[((rr-2*GRBdir[0][c])*TS+cc)>>1]+p[3]*grbdiff[((rr-2*GRBdir[0][c])*TS+cc-2*GRBdir[1][c])>>1])/(p[0]+p[1]+p[2]+p[3]); + + //now determine R/B at grid points using interpolated color differences and interpolated G value at grid point + if (fabsf(grbdiffold)>fabsf(grbdiffint) ) { + rgb[c][indx]=rgb[1][indx]-grbdiffint; + } + } + + //if color difference interpolation overshot the correction, just desaturate + if (grbdiffold*grbdiffint<0) { + rgb[c][indx]=rgb[1][indx]-0.5f*(grbdiffold+grbdiffint); + } + } + + // copy CA corrected results to temporary image matrix + for (rr=border; rr < rr1-border; rr++){ + c = FC(rr+top, left + border+FC(rr+top,2)&1); + for (row=rr+top, cc=border+(FC(rr,2)&1),indx=(row*width+cc+left)>>1; cc < cc1-border; cc+=2,indx++) { + col = cc + left; + RawDataTmp[indx] = 65535.0f*rgb[c][(rr)*TS+cc] + 0.5f; + //image[indx][c] = CLIP((int)(65535.0*rgb[(rr)*TS+cc][c] + 0.5));//for dcraw implementation + } + } + + if(plistener) { + progresscounter++; + if(progresscounter % 8 == 0) +#pragma omp critical + { + progress+=(double)(8.0*(TS-border2)*(TS-border2))/(2*height*width); + if (progress>1.0) + { + progress=1.0; + } + plistener->setProgress(progress); + } + } + + } + +#pragma omp barrier +// copy temporary image matrix back to image matrix +#pragma omp for + for(row=0;row>1;colsetProgress(1.0); + +#undef TS +#undef TSH +#undef PIX_SORT +} diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt new file mode 100644 index 000000000..0cda358e0 --- /dev/null +++ b/rtengine/CMakeLists.txt @@ -0,0 +1,45 @@ +include_directories (${EXTRA_INCDIR} ${GTHREAD_INCLUDE_DIRS} ${GOBJECT_INCLUDE_DIRS} ${GLIB2_INCLUDE_DIRS} + ${GLIBMM_INCLUDE_DIRS} ${IPTCDATA_INCLUDE_DIRS} ${LCMS_INCLUDE_DIRS} ${EXPAT_INCLUDE_DIRS} ${FFTW3F_INCLUDE_DIRS} + ${GTKMM_INCLUDE_DIRS} ${GTK_INCLUDE_DIRS}) +link_directories ("${PROJECT_SOURCE_DIR}/rtexif" ${EXTRA_LIBDIR} ${GTHREAD_LIBRARY_DIRS} + ${GOBJECT_LIBRARY_DIRS} ${GLIB2_LIBRARY_DIRS} ${GLIBMM_LIBRARY_DIRS} + ${IPTCDATA_LIBRARY_DIRS} ${LCMS_LIBRARY_DIRS} ${EXPAT_LIBRARY_DIRS} ${FFTW3F_LIBRARY_DIRS}) + +set (CAMCONSTSFILE "camconst.json") + +set (RTENGINESOURCEFILES safegtk.cc colortemp.cc curves.cc flatcurves.cc diagonalcurves.cc dcraw.cc iccstore.cc color.cc + dfmanager.cc ffmanager.cc rawimage.cc image8.cc image16.cc imagefloat.cc imagedata.cc imageio.cc improcfun.cc init.cc dcrop.cc + loadinitial.cc procparams.cc rawimagesource.cc demosaic_algos.cc shmap.cc simpleprocess.cc refreshmap.cc + fast_demo.cc amaze_demosaic_RT.cc CA_correct_RT.cc cfa_linedn_RT.cc green_equil_RT.cc hilite_recon.cc expo_before_b.cc + stdimagesource.cc myfile.cc iccjpeg.cc hlmultipliers.cc improccoordinator.cc editbuffer.cc + processingjob.cc rtthumbnail.cc utils.cc labimage.cc slicer.cc cieimage.cc + iplab2rgb.cc ipsharpen.cc iptransform.cc ipresize.cc ipvibrance.cc + imagedimensions.cc jpeg_memsrc.cc jdatasrc.cc iimage.cc + EdgePreservingDecomposition.cc cplx_wavelet_dec.cc FTblockDN.cc + PF_correct_RT.cc previewimage.cc ipwavelet.cc + dirpyr_equalizer.cc + calc_distort.cc lcp.cc dcp.cc + cJSON.c camconst.cc + klt/convolve.cc klt/error.cc klt/klt.cc klt/klt_util.cc klt/pnmio.cc klt/pyramid.cc klt/selectGoodFeatures.cc + klt/storeFeatures.cc klt/trackFeatures.cc klt/writeFeatures.cc + clutstore.cc + ciecam02.cc + ) + +include_directories (BEFORE "${CMAKE_CURRENT_BINARY_DIR}") + +add_library (rtengine ${RTENGINESOURCEFILES}) +add_dependencies (rtengine AboutFile) + +#It may be nice to store library version too +IF (BUILD_SHARED_LIBS) + install (TARGETS rtengine DESTINATION ${LIBDIR}) +ENDIF (BUILD_SHARED_LIBS) + +set_target_properties (rtengine PROPERTIES COMPILE_FLAGS "${RTENGINE_CXX_FLAGS}") + +target_link_libraries (rtengine rtexif ${EXTRA_LIB} ${GOBJECT_LIBRARIES} ${GTHREAD_LIBRARIES} + ${GLIB2_LIBRARIES} ${GLIBMM_LIBRARIES} ${LCMS_LIBRARIES} ${EXPAT_LIBRARIES} ${FFTW3F_LIBRARIES} ${IPTCDATA_LIBRARIES} + ${JPEG_LIBRARIES} ${PNG_LIBRARIES} ${TIFF_LIBRARIES} ${ZLIB_LIBRARIES}) + +install (FILES ${CAMCONSTSFILE} DESTINATION "${DATADIR}" PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ) diff --git a/rtengine/Doxyfile b/rtengine/Doxyfile new file mode 100644 index 000000000..5eb3c98fc --- /dev/null +++ b/rtengine/Doxyfile @@ -0,0 +1,1356 @@ +# Doxyfile 1.5.5 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = RawTherapee Image Processing Engine (RIPE) + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 1.0 + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = doc + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, +# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, +# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, +# and Ukrainian. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentstion. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = YES + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is enabled by default, which results in a transparent +# background. Warning: Depending on the platform used, enabling this option +# may lead to badly anti-aliased labels on the edges of a graph (i.e. they +# become hard to read). + +DOT_TRANSPARENT = YES + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/rtengine/EdgePreserveLab.cc b/rtengine/EdgePreserveLab.cc new file mode 100644 index 000000000..967555a94 --- /dev/null +++ b/rtengine/EdgePreserveLab.cc @@ -0,0 +1,229 @@ +#include "EdgePreserveLab.h" +#include "boxblur.h" +#include + +#ifdef _OPENMP +#include +#endif + +//#define MAX(a,b) ((a)<(b)?(b):(a)) +//#define MIN(a,b) ((a)>(b)?(b):(a)) + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +EdgePreserveLab::EdgePreserveLab(unsigned int width, unsigned int height){ + w = width; + h = height; + n = w*h; + + //Initialize the matrix just once at construction. + A = new MultiDiagonalSymmetricMatrix(n, 5); + if(!( + A->CreateDiagonal(0, 0) && + A->CreateDiagonal(1, 1) && + A->CreateDiagonal(2, w - 1) && + A->CreateDiagonal(3, w) && + A->CreateDiagonal(4, w + 1))){ + delete A; + A = NULL; + printf("Error in EdgePreserveLab construction: out of memory.\n"); + }else{ + a0 = A->Diagonals[0]; + a_1 = A->Diagonals[1]; + a_w1 = A->Diagonals[2]; + a_w = A->Diagonals[3]; + a_w_1 = A->Diagonals[4]; + } +} + +EdgePreserveLab::~EdgePreserveLab(){ + delete A; +} + +float *EdgePreserveLab::CreateBlur(float *Source, float LScale, float abScale, float EdgeStoppingLuma, float EdgeStoppingChroma, unsigned int Iterates, float *Blur, bool UseBlurForEdgeStop){ + if(Blur == NULL) + UseBlurForEdgeStop = false, //Use source if there's no supplied Blur. + Blur = new float[3*n]; + if(LScale == 0.0f){ + memcpy(Blur, Source, 3*n*sizeof(float)); + return Blur; + } + + //Create the edge stopping function a, rotationally symmetric and just one instead of (ax, ay). Maybe don't need Blur yet, so use its memory. + float *a, *b, *g; + if(UseBlurForEdgeStop) a = new float[n], g = Blur; + else a = Blur, g = Source; + //b = new float[n]; + + unsigned int x, y, i; + unsigned int w1 = w - 1, h1 = h - 1; + float eps = 0.0001f; + float scL = powf(100.0f,LScale); + float scab = powf(200.0f,abScale); + + float * var = new float[w*h]; + rtengine::boxvar(g, var, 1, 1, w, h); + +#ifdef _OPENMP +#pragma omp parallel for +#endif + for(y = 0; y < h1; y++){ + float *rg = &g[w*y]; + for(x = 0; x < w1; x++){ + //Estimate the central difference gradient in the center of a four pixel square. (gx, gy) is actually 2*gradient. + /*float gx = (fabs((rg[x + 1] - rg[x]) + (rg[x + w + 1] - rg[x + w]))); + float gy = (fabs((rg[x + w] - rg[x]) + (rg[x + w + 1] - rg[x + 1]))); + + //TODO: combine this with gx, gy if not needing separate quantities + float hx = (fabs((rg[x + 1 + n] - rg[x + n]) + (rg[x + w + 1 + n] - rg[x + w + n])) + \ + fabs((rg[x + 1 + 2*n] - rg[x + 2*n]) + (rg[x + w + 1 + 2*n] - rg[x + w + 2*n]))); + float hy = (fabs((rg[x + w + n] - rg[x + n]) + (rg[x + w + 1 + n] - rg[x + 1 + n])) + \ + fabs((rg[x + w + 2*n] - rg[x + 2*n]) + (rg[x + w + 1 + 2*n] - rg[x + 1 + 2*n]))); + */ + //float gradtot = (gx+gy+hx+hy); + //gradhisto[MAX(0,MIN(32767,(int)gradtot))] ++; + + //Apply power to the magnitude of the gradient to get the edge stopping function. + //a[x + w*y] = scL*expf(-100.0f*(gx + gy + hx + hy)/(EdgeStoppingLuma)); + //a[x + w*y] = scL*expf(-var[y*w+x]/SQR(0.02*EdgeStoppingLuma));///(0.1+rg[x]); + a[x + w*y] = scL*expf(-50.0f*sqrt(var[y*w+x])/(EdgeStoppingLuma+eps));///(0.1+rg[x]); + + //b[x + w*y] = (scab)*expf(-20.0f*(gx + gy + Lave*(hx + hy))/(EdgeStoppingChroma)); + //b[x + w*y] = (scab)*expf(-400.0f*SQR(gx + gy + Lave*(hx + hy))/SQR(EdgeStoppingChroma));; + + } + } + + /* Now setup the linear problem. I use the Maxima CAS, here's code for making an FEM formulation for the smoothness term: + p(x, y) := (1 - x)*(1 - y); + P(m, n) := A[m][n]*p(x, y) + A[m + 1][n]*p(1 - x, y) + A[m + 1][n + 1]*p(1 - x, 1 - y) + A[m][n + 1]*p(x, 1 - y); + Integrate(f) := integrate(integrate(f, x, 0, 1), y, 0, 1); + + Integrate(diff(P(u, v), x)*diff(p(x, y), x) + diff(P(u, v), y)*diff(p(x, y), y)); + Integrate(diff(P(u - 1, v), x)*diff(p(1 - x, y), x) + diff(P(u - 1, v), y)*diff(p(1 - x, y), y)); + Integrate(diff(P(u - 1, v - 1), x)*diff(p(1 - x, 1 - y), x) + diff(P(u - 1, v - 1), y)*diff(p(1 - x, 1 - y), y)); + Integrate(diff(P(u, v - 1), x)*diff(p(x, 1 - y), x) + diff(P(u, v - 1), y)*diff(p(x, 1 - y), y)); + So yeah. Use the numeric results of that to fill the matrix A.*/ + memset(a_1, 0, A->DiagonalLength(1)*sizeof(float)); + memset(a_w1, 0, A->DiagonalLength(w - 1)*sizeof(float)); + memset(a_w, 0, A->DiagonalLength(w)*sizeof(float)); + memset(a_w_1, 0, A->DiagonalLength(w + 1)*sizeof(float)); + +//TODO: OMP here? + for(i = y = 0; y != h; y++){ + for(x = 0; x != w; x++, i++){ + float ac; + a0[i] = 1.0; + + //Remember, only fill the lower triangle. Memory for upper is never made. It's symmetric. Trust. + if(x > 0 && y > 0) + ac = a[i - w - 1]/6.0f, + a_w_1[i - w - 1] -= 2.0f*ac, a_w[i - w] -= ac, + a_1[i - 1] -= ac, a0[i] += 4.0f*ac; + + if(x < w1 && y > 0) + ac = a[i - w]/6.0f, + a_w[i - w] -= ac, a_w1[i - w + 1] -= 2.0f*ac, + a0[i] += 4.0f*ac; + + if(x > 0 && y < h1) + ac = a[i - 1]/6.0f, + a_1[i - 1] -= ac, a0[i] += 4.0f*ac; + + if(x < w1 && y < h1) + a0[i] += 4.0f*a[i]/6.0f; + } + } + if(UseBlurForEdgeStop) delete[] a; + + + //Solve & return. + A->CreateIncompleteCholeskyFactorization(1); //Fill-in of 1 seems to work really good. More doesn't really help and less hurts (slightly). + if(!UseBlurForEdgeStop) memcpy(Blur, Source, 3*n*sizeof(float)); + // blur L channel + SparseConjugateGradient(A->PassThroughVectorProduct, Source, n, false, Blur, 0.0f, (void *)A, Iterates, A->PassThroughCholeskyBackSolve); + + //reset A for ab channels + /*memset(a_1, 0, A->DiagonalLength(1)*sizeof(float)); + memset(a_w1, 0, A->DiagonalLength(w - 1)*sizeof(float)); + memset(a_w, 0, A->DiagonalLength(w)*sizeof(float)); + memset(a_w_1, 0, A->DiagonalLength(w + 1)*sizeof(float)); + for(i = y = 0; y != h; y++){ + for(x = 0; x != w; x++, i++){ + float ac; + a0[i] = 1.0; + + //Remember, only fill the lower triangle. Memory for upper is never made. It's symmetric. Trust. + if(x > 0 && y > 0) + ac = b[i - w - 1]/6.0f, + a_w_1[i - w - 1] -= 2.0f*ac, a_w[i - w] -= ac, + a_1[i - 1] -= ac, a0[i] += 4.0f*ac; + + if(x < w1 && y > 0) + ac = b[i - w]/6.0f, + a_w[i - w] -= ac, a_w1[i - w + 1] -= 2.0f*ac, + a0[i] += 4.0f*ac; + + if(x > 0 && y < h1) + ac = b[i - 1]/6.0f, + a_1[i - 1] -= ac, a0[i] += 4.0f*ac; + + if(x < w1 && y < h1) + a0[i] += 4.0f*b[i]/6.0f; + } + }*/ + /*if(UseBlurForEdgeStop)*/ //delete[] b; + + // blur ab channels + //A->CreateIncompleteCholeskyFactorization(1); //Fill-in of 1 seems to work really good. More doesn't really help and less hurts (slightly). + //SparseConjugateGradient(A->PassThroughVectorProduct, Source+n, n, false, Blur+n, 0.0f, (void *)A, Iterates, A->PassThroughCholeskyBackSolve); + //SparseConjugateGradient(A->PassThroughVectorProduct, Source+2*n, n, false, Blur+2*n, 0.0f, (void *)A, Iterates, A->PassThroughCholeskyBackSolve); + + A->KillIncompleteCholeskyFactorization(); + return Blur; +} + +float *EdgePreserveLab::CreateIteratedBlur(float *Source, float LScale, float abScale, float EdgeStoppingLuma, float EdgeStoppingChroma, unsigned int Iterates, unsigned int Reweightings, float *Blur){ + //Simpler outcome? + if(Reweightings == 0) return CreateBlur(Source, LScale, abScale, EdgeStoppingLuma, EdgeStoppingChroma, Iterates, Blur); + + //Create a blur here, initialize. + if(Blur == NULL) Blur = new float[3*n]; + memcpy(Blur, Source, 3*n*sizeof(float)); + + //Iteratively improve the blur. + Reweightings++; + for(unsigned int i = 0; i != Reweightings; i++) + CreateBlur(Source, LScale, abScale, EdgeStoppingLuma, EdgeStoppingChroma, Iterates, Blur, true); + + return Blur; +} + +float *EdgePreserveLab::CompressDynamicRange(float *Source, float LScale, float abScale, float EdgeStoppingLuma, float EdgeStoppingChroma, float CompressionExponent, float DetailBoost, unsigned int Iterates, unsigned int Reweightings, float *Compressed){ + //We're working with luminance, which does better logarithmic. + unsigned int i; + //for(i = 0; i != n; i++) + // Source[i] = logf(Source[i] + 0.0001f); + + //Blur. Also setup memory for Compressed (we can just use u since each element of u is used in one calculation). + float *u = CreateIteratedBlur(Source, LScale, abScale, EdgeStoppingLuma, EdgeStoppingChroma, Iterates, Reweightings); + if(Compressed == NULL) Compressed = u; + + //Apply compression, detail boost, unlogging. Compression is done on the logged data and detail boost on unlogged. + for(i = 0; i != n; i++){ + //float ce = expf(Source[i] + u[i]*(CompressionExponent - 1.0f)) - 0.0001f; + //float ue = expf(u[i]) - 0.0001f; + //Source[i] = expf(Source[i]) - 0.0001f; + //Compressed[i] = ce + DetailBoost*(Source[i] - ue); + Compressed[i] = u[i];//ue;//for testing, to display blur + } + + if(Compressed != u) delete[] u; + return Compressed; +} + + + + diff --git a/rtengine/EdgePreserveLab.h b/rtengine/EdgePreserveLab.h new file mode 100644 index 000000000..7da795247 --- /dev/null +++ b/rtengine/EdgePreserveLab.h @@ -0,0 +1,76 @@ +#pragma once +/* +The EdgePreserveLab files contain standard C++ (standard except the first line) code for creating and, to a +limited extent (create your own uses!), messing with multi scale edge preserving decompositions of a 32 bit single channel +image. As a byproduct it contains a lot of linear algebra which can be useful for optimization problems that +you want to solve in rectangles on rectangular grids. + +Anyway. Basically, this is an implementation of what's presented in the following papers: + Edge-Preserving Decompositions for Multi-Scale Tone and Detail Manipulation + An Iterative Solution Method for Linear Systems of Which the Coefficient Matrix is a Symetric M-Matrix + Color correction for tone mapping + Wikipedia, the free encyclopedia + +First one is most of what matters, next two are details, last everything else. I did a few things differently, especially: + Reformulated the minimization with finite elements instead of finite differences. This results in better conditioning, + slightly better accuracy (less artifacts), the possibility of a better picked edge stopping function, but more memory consumption. + + A single rotationally invariant edge stopping function is used instead of two non-invariant ones. + + Incomplete Cholseky factorization instead of Szeliski's LAHBF. Slower, but not subject to any patents. + + For tone mapping, original images are decomposed instead of their logarithms, and just one decomposition is made; + I find that this way works plenty good (theirs isn't better or worse... just different) and is simpler. + +Written by ben_pcc in Portland, Oregon, USA; code modified by Emil Martinec. + + // EdgePreserveLab.h and EdgePreserveLab.cpp are free software: + // you can redistribute it and/or modify it + // under the terms of the GNU General Public License as published by + // the Free Software Foundation, either version 3 of the License, or + // (at your option) any later version. + // + // This program is distributed in the hope that it will be useful, + // but WITHOUT ANY WARRANTY; without even the implied warranty of + // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + // GNU General Public License for more details. + // + // You should have received a copy of the GNU General Public License + // along with this program. If not, see . + +*/ + + + +#include +#include +#include +#include "EdgePreservingDecomposition.h" + +class EdgePreserveLab{ +public: + EdgePreserveLab(unsigned int width, unsigned int height); + ~EdgePreserveLab(); + + //Create an edge preserving blur of Source. Will create and return, or fill into Blur if not NULL. In place not ok. + //If UseBlurForEdgeStop is true, supplied not NULL Blur is used to calculate the edge stopping function instead of Source. + float *CreateBlur(float *Source, float LScale, float abScale, float EdgeStoppingLuma, float EdgeStoppingChroma, unsigned int Iterates, float *Blur = NULL, bool UseBlurForEdgeStop = false); + + //Iterates CreateBlur such that the smoothness term approaches a specific norm via iteratively reweighted least squares. In place not ok. + float *CreateIteratedBlur(float *Source, float LScale, float abScale, float EdgeStoppingLuma, float EdgeStoppingChroma, unsigned int Iterates, unsigned int Reweightings, float *Blur = NULL); + + /*Lowers global contrast while preserving or boosting local contrast. Can fill into Compressed. The smaller Compression + the more compression is applied, with Compression = 1 giving no effect and above 1 the opposite effect. You can totally + use Compression = 1 and play with DetailBoost for some really sweet unsharp masking. If working on luma/grey, consider giving it a logarithm. + In place calculation to save memory (Source == Compressed) is totally ok. Reweightings > 0 invokes CreateIteratedBlur instead of CreateBlur. */ + float *CompressDynamicRange(float *Source, float LScale = 1.0f, float abScale = 5.0f, float EdgeStoppingLuma = 1.0f, float EdgeStoppingChroma = 1.0f, + float CompressionExponent = 0.8f, float DetailBoost = 0.1f, unsigned int Iterates = 20, + unsigned int Reweightings = 0, float *Compressed = NULL); + +private: + MultiDiagonalSymmetricMatrix *A; //The equations are simple enough to not mandate a matrix class, but fast solution NEEDS a complicated preconditioner. + unsigned int w, h, n; + + //Convenient access to the data in A. + float *a0, *a_1, *a_w, *a_w_1, *a_w1; +}; diff --git a/rtengine/EdgePreservingDecomposition.cc b/rtengine/EdgePreservingDecomposition.cc new file mode 100644 index 000000000..6f8a30033 --- /dev/null +++ b/rtengine/EdgePreservingDecomposition.cc @@ -0,0 +1,814 @@ +#include +#include "rt_math.h" +#include "EdgePreservingDecomposition.h" +#ifdef _OPENMP +#include +#endif +#include "sleef.c" +#include "opthelper.h" + +#define pow_F(a,b) (xexpf(b*xlogf(a))) + +#define DIAGONALS 5 +#define DIAGONALSP1 6 + +/* Solves A x = b by the conjugate gradient method, where instead of feeding it the matrix A you feed it a function which +calculates A x where x is some vector. Stops when rms residual < RMSResidual or when maximum iterates is reached. +Stops at n iterates if MaximumIterates = 0 since that many iterates gives exact solution. Applicable to symmetric positive +definite problems only, which is what unconstrained smooth optimization pretty much always is. +Parameter pass can be passed through, containing whatever info you like it to contain (matrix info?). +Takes less memory with OkToModify_b = true, and Preconditioner = NULL. */ +float *SparseConjugateGradient(void Ax(float *Product, float *x, void *Pass), float *b, int n, bool OkToModify_b, + float *x, float RMSResidual, void *Pass, int MaximumIterates, void Preconditioner(float *Product, float *x, void *Pass)){ + int iterate, i; + + char* buffer = (char*)malloc(2*n*sizeof(float)+128); + float *r = (float*)(buffer+64); + //Start r and x. + if(x == NULL){ + x = new float[n]; + + memset(x, 0, sizeof(float)*n); //Zero initial guess if x == NULL. + memcpy(r, b, sizeof(float)*n); + }else{ + Ax(r, x, Pass); +#ifdef _OPENMP +#pragma omp parallel for // removed schedule(dynamic,10) +#endif + for(int ii = 0; ii < n; ii++) + r[ii] = b[ii] - r[ii]; //r = b - A x. + } + //s is preconditionment of r. Without, direct to r. + float *s = r, rs = 0.0f; + if(Preconditioner != NULL){ + s = new float[n]; + + Preconditioner(s, r, Pass); + } +#ifdef _OPENMP +#pragma omp parallel for reduction(+:rs) // removed schedule(dynamic,10) +#endif + for(int ii = 0; ii < n; ii++) { + rs += r[ii]*s[ii]; + } + //Search direction d. + float *d = (float*)(buffer + n*sizeof(float) + 128); + + memcpy(d, s, sizeof(float)*n); + + //Store calculations of Ax in this. + float *ax = b; + if(!OkToModify_b) ax = new float[n]; + + //Start iterating! + if(MaximumIterates == 0) MaximumIterates = n; + for(iterate = 0; iterate < MaximumIterates; iterate++){ + //Get step size alpha, store ax while at it. + float ab = 0.0f; + Ax(ax, d, Pass); +#ifdef _OPENMP +#pragma omp parallel for reduction(+:ab) +#endif + for(int ii = 0; ii < n; ii++) + ab += d[ii]*ax[ii]; + + if(ab == 0.0f) break; //So unlikely. It means perfectly converged or singular, stop either way. + ab = rs/ab; + + //Update x and r with this step size. + float rms = 0.0; +#ifdef _OPENMP +#pragma omp parallel for reduction(+:rms) +#endif + for(int ii = 0; ii < n; ii++){ + x[ii] += ab*d[ii]; + r[ii] -= ab*ax[ii]; //"Fast recursive formula", use explicit r = b - Ax occasionally? + rms += r[ii]*r[ii]; + } + rms = sqrtf(rms/n); + //Quit? This probably isn't the best stopping condition, but ok. + if(rms < RMSResidual) break; + + if(Preconditioner != NULL) Preconditioner(s, r, Pass); + + //Get beta. + ab = rs; + rs = 0.0f; + +#ifdef _OPENMP +#pragma omp parallel +#endif +{ + float c = 0.0f; + float t; + float temp; +#ifdef _OPENMP +#pragma omp for reduction(+:rs) // Summation with error correction +#endif + for(int ii = 0; ii < n; ii++) { + temp = r[ii]*s[ii]; + t = rs + temp; + if( fabsf(rs) >= fabsf(temp) ) + c += ((rs-t) + temp); + else + c += ((temp-t)+rs); + rs = t; + } +#ifdef _OPENMP +#pragma omp critical +#endif + rs += c; +} + + ab = rs/ab; + + //Update search direction p. +#ifdef _OPENMP +#pragma omp parallel for +#endif + for(int ii = 0; ii < n; ii++) + d[ii] = s[ii] + ab*d[ii]; + + + } + + if(iterate == MaximumIterates) + if(iterate != n && RMSResidual != 0.0f) + printf("Warning: MaximumIterates (%u) reached in SparseConjugateGradient.\n", MaximumIterates); + + if(ax != b) delete[] ax; + if(s != r) delete[] s; + free(buffer); + return x; +} + +MultiDiagonalSymmetricMatrix::MultiDiagonalSymmetricMatrix(int Dimension, int NumberOfDiagonalsInLowerTriangle){ + n = Dimension; + m = NumberOfDiagonalsInLowerTriangle; + IncompleteCholeskyFactorization = NULL; + + Diagonals = new float *[m]; + StartRows = new int [m+1]; + memset(Diagonals, 0, sizeof(float *)*m); + memset(StartRows, 0, sizeof(int)*(m+1)); + StartRows[m] = n+1; +} + +MultiDiagonalSymmetricMatrix::~MultiDiagonalSymmetricMatrix(){ + if(DiagBuffer != NULL) + free(buffer); + else + for(int i=0;i try to allocate smaller blocks + DiagBuffer = NULL; + else { + DiagBuffer = (char*)( ( uintptr_t(buffer) + uintptr_t(63)) / 64 * 64); + } + } + if(index >= m){ + printf("Error in MultiDiagonalSymmetricMatrix::CreateDiagonal: invalid index.\n"); + return false; + } + if(index > 0) + if(StartRow <= StartRows[index - 1]){ + printf("Error in MultiDiagonalSymmetricMatrix::CreateDiagonal: each StartRow must exceed the previous.\n"); + return false; + } + + if(DiagBuffer != NULL) + Diagonals[index] = (float*)(DiagBuffer+(index*(n+padding)*sizeof(float))+((index+16)*64)); + else { + Diagonals[index] = new float[DiagonalLength(StartRow)]; + if(Diagonals[index] == NULL) { + printf("Error in MultiDiagonalSymmetricMatrix::CreateDiagonal: memory allocation failed. Out of memory?\n"); + return false; + } + memset(Diagonals[index], 0, sizeof(float)*DiagonalLength(StartRow)); + } + + StartRows[index] = StartRow; + return true; +} + +inline int MultiDiagonalSymmetricMatrix::FindIndex(int StartRow) { + //There's GOT to be a better way to do this. "Bidirectional map?" + // Issue 1895 : Changed start of loop from zero to one + // m is small (5 or 6) + for(int i = 1; i < m; i++) + if(StartRows[i] == StartRow) + return i; + return -1; +} + +bool MultiDiagonalSymmetricMatrix::LazySetEntry(float value, int row, int column){ + //On the strict upper triangle? Swap, this is ok due to symmetry. + int i, sr; + if(column > row) + i = column, + column = row, + row = i; + if(row >= n) return false; + sr = row - column; + + //Locate the relevant diagonal. + i = FindIndex(sr); + if(i < 0) return false; + + Diagonals[i][column] = value; + return true; +} + +SSEFUNCTION void MultiDiagonalSymmetricMatrix::VectorProduct(float* RESTRICT Product, float* RESTRICT x){ + + int srm = StartRows[m-1]; + int lm = DiagonalLength(srm); +#ifdef _OPENMP +#ifdef __SSE2__ + const int chunkSize = (lm-srm)/(omp_get_num_procs()*32); +#else + const int chunkSize = (lm-srm)/(omp_get_num_procs()*8); +#endif +#endif +#pragma omp parallel +{ + // First fill the big part in the middle + // This can be done without intermediate stores to memory and it can be parallelized too +#ifdef _OPENMP +#pragma omp for schedule(dynamic,chunkSize) nowait +#endif +#ifdef __SSE2__ + for(int j=srm;j0;i--) { + int s = StartRows[i]; + prodv += (LVFU(Diagonals[i][j - s])*LVFU(x[j - s])) + (LVFU(Diagonals[i][j])*LVFU(x[j + s])); + } + _mm_storeu_ps(&Product[j],prodv); + } +#else + for(int j=srm;j0;i--) { + int s = StartRows[i]; + prod += (Diagonals[i][j - s]*x[j - s]) + (Diagonals[i][j]*x[j + s]); + } + Product[j] = prod; + } + +#endif +#pragma omp single +{ +#ifdef __SSE2__ + for(int j=lm-((lm-srm)%4);j0;i--) { + int s = StartRows[i]; + prod += (Diagonals[i][j - s]*x[j - s]) + (Diagonals[i][j]*x[j + s]); + } + Product[j] = prod; + } +#endif + // Fill remaining area + // Loop over the stored diagonals. + for(int i = 0; i < m; i++){ + int sr = StartRows[i]; + float *a = Diagonals[i]; //One fewer dereference. + int l = DiagonalLength(sr); + if(sr == 0) { + for(int j = 0; j < srm; j++) + Product[j] = a[j]*x[j]; //Separate, fairly simple treatment for the main diagonal. + for(int j = lm; j < l; j++) + Product[j] = a[j]*x[j]; //Separate, fairly simple treatment for the main diagonal. + } else { +// Split the loop in 3 parts, so now the big one in the middle can be parallelized without race conditions + // updates 0 to sr - 1. Because sr is small (in the range of image-width) no benefit by omp + for(int j=0;jCreateDiagonal(0, 0); //There's always a main diagonal in this type of decomposition. + mic=1; + for(int ii = 1; ii < m; ii++){ + //Set j to the number of diagonals to be created corresponding to a diagonal on this source matrix... + j = rtengine::min(StartRows[ii] - StartRows[ii - 1], MaxFillAbove); + + //...and create those diagonals. I want to take a moment to tell you about how much I love minimalistic loops: very much. + while(j-- != 0) + if(!ic->CreateDiagonal(mic++, StartRows[ii] - j)){ + //Beware of out of memory, possible for large, sparse problems if you ask for too much fill. + printf("Error in MultiDiagonalSymmetricMatrix::CreateIncompleteCholeskyFactorization: Out of memory. Ask for less fill?\n"); + delete ic; + return false; + } + } + + //It's all initialized? Uhkay. Do the actual math then. + int sss, ss, s; + int k, MaxStartRow = StartRows[m - 1]; //Handy number. + float **l = ic->Diagonals; + float *d = ic->Diagonals[0]; //Describes D in LDLt. + int icm = ic->m; + int icn = ic->n; + int* RESTRICT icStartRows = ic->StartRows; + + //Loop over the columns. + + // create array for quicker access to ic->StartRows + struct s_diagmap { + int sss; + int ss; + int k; + }; + + + // Pass one: count number of needed entries + int entrycount = 0; + for(int i=1;iFindIndex( icStartRows[i] + icStartRows[j]) > 0) + entrycount ++; + } + } + + // now we can create the array + struct s_diagmap* RESTRICT DiagMap = new s_diagmap[entrycount]; + // we also need the maxvalues + int entrynumber = 0; + int index; + int* RESTRICT MaxIndizes = new int[icm]; + + for(int i=1;iFindIndex( icStartRows[i] + icStartRows[j]); + if(index > 0) { + DiagMap[entrynumber].ss = j; + DiagMap[entrynumber].sss = index; + DiagMap[entrynumber].k = icStartRows[j]; + entrynumber ++; + } + } + MaxIndizes[i] = entrynumber - 1; + } + + int* RESTRICT findmap = new int[icm]; + for(int j=0;j= jMax) + break; //Possible values of j are limited + + float temp = 0.0f; + while(mapindex <= MaxIndizes[s] && ( k = DiagMap[mapindex].k) <= j) { + temp -= l[DiagMap[mapindex].sss][j - k]*l[DiagMap[mapindex].ss][j - k]*d[j - k]; + mapindex ++; + } + sss = findmap[s]; + l[s][j] = id * (sss < 0 ? temp : (Diagonals[sss][j] + temp)); + } + } + delete[] DiagMap; + delete[] MaxIndizes; + delete[] findmap; + IncompleteCholeskyFactorization = ic; + return true; +} + +void MultiDiagonalSymmetricMatrix::KillIncompleteCholeskyFactorization(void){ + delete IncompleteCholeskyFactorization; +} + +void MultiDiagonalSymmetricMatrix::CholeskyBackSolve(float* RESTRICT x, float* RESTRICT b){ + //We want to solve L D Lt x = b where D is a diagonal matrix described by Diagonals[0] and L is a unit lower triagular matrix described by the rest of the diagonals. + //Let D Lt x = y. Then, first solve L y = b. + float* RESTRICT *d = IncompleteCholeskyFactorization->Diagonals; + int* RESTRICT s = IncompleteCholeskyFactorization->StartRows; + int M = IncompleteCholeskyFactorization->m, N = IncompleteCholeskyFactorization->n; + int i, j; + + if(M != DIAGONALSP1){ // can happen in theory + for(j = 0; j < N; j++){ + float sub = b[j]; // using local var to reduce memory writes, gave a big speedup + i = 1; + int c = j - s[i]; + while(c >= 0) { + sub -= d[i][c]*x[c]; + i++; + c = j - s[i]; + } + x[j] = sub; // only one memory-write per j + } + } else { // that's the case almost every time + for(j = 0; j <= s[M-1]; j++){ + float sub = b[j]; // using local var to reduce memory writes, gave a big speedup + i = 1; + int c = j - s[1]; + while(c >= 0) { + sub -= d[i][c]*x[c]; + i++; + c = j - s[i]; + } + x[j] = sub; // only one memory-write per j + } + for(j = s[M-1]+1; j0;i--){ // using a constant upperbound allows the compiler to unroll this loop (gives a good speedup) + sub -= d[i][j-s[i]]*x[j-s[i]]; + } + x[j] = sub; // only one memory-write per j + } + } + + //Now, solve x from D Lt x = y -> Lt x = D^-1 y +// Took this one out of the while, so it can be parallelized now, which speeds up, because division is expensive +#ifdef _OPENMP +#pragma omp parallel for +#endif + for(j = 0; j < N; j++) + x[j] = x[j]/d[0][j]; + + if(M != DIAGONALSP1){ // can happen in theory + while(j-- > 0){ + float sub = x[j]; // using local var to reduce memory writes, gave a big speedup + i=1; + int c = j+s[1]; + while(c < N) { + sub -= d[i][j]*x[c]; + i++; + c = j+s[i]; + } + x[j] = sub; // only one memory-write per j + } + } else { // that's the case almost every time + for(j=N-1;j>=(N-1)-s[M-1];j--) { + float sub = x[j]; // using local var to reduce memory writes, gave a big speedup + i=1; + int c = j+s[1]; + while(c < N) { + sub -= d[i][j]*x[j+s[i]]; + i++; + c = j+s[i]; + } + x[j] = sub; // only one memory-write per j + } + for(j=(N-2)-s[M-1];j>=0;j--) { + float sub = x[j]; // using local var to reduce memory writes, gave a big speedup + for(int i=DIAGONALSP1-1;i>0;i--){ // using a constant upperbound allows the compiler to unroll this loop (gives a good speedup) + sub -= d[i][j]*x[j + s[i]]; + } + x[j] = sub; // only one memory-write per j + } + } +} + +EdgePreservingDecomposition::EdgePreservingDecomposition(int width, int height){ + w = width; + h = height; + n = w*h; + + //Initialize the matrix just once at construction. + A = new MultiDiagonalSymmetricMatrix(n, DIAGONALS); + if(!( + A->CreateDiagonal(0, 0) && + A->CreateDiagonal(1, 1) && + A->CreateDiagonal(2, w - 1) && + A->CreateDiagonal(3, w) && + A->CreateDiagonal(4, w + 1))){ + delete A; + A = NULL; + printf("Error in EdgePreservingDecomposition construction: out of memory.\n"); + }else{ + a0 = A->Diagonals[0]; + a_1 = A->Diagonals[1]; + a_w1 = A->Diagonals[2]; + a_w = A->Diagonals[3]; + a_w_1 = A->Diagonals[4]; + } +} + +EdgePreservingDecomposition::~EdgePreservingDecomposition(){ + delete A; +} + +SSEFUNCTION float *EdgePreservingDecomposition::CreateBlur(float *Source, float Scale, float EdgeStopping, int Iterates, float *Blur, bool UseBlurForEdgeStop){ + + if(Blur == NULL) + UseBlurForEdgeStop = false, //Use source if there's no supplied Blur. + Blur = new float[n]; + + if(Scale == 0.0f){ + memcpy(Blur, Source, n*sizeof(float)); + return Blur; + } + + //Create the edge stopping function a, rotationally symmetric and just one instead of (ax, ay). Maybe don't need Blur yet, so use its memory. + float* RESTRICT a; + float* RESTRICT g; + if(UseBlurForEdgeStop) a = new float[n], g = Blur; + else a = Blur, g = Source; + + int i; + int w1 = w - 1, h1 = h - 1; +// float eps = 0.02f; + const float sqreps = 0.0004f; // removed eps*eps from inner loop + + +#ifdef _OPENMP +#pragma omp parallel +#endif +{ +#ifdef __SSE2__ + int x; + __m128 gxv,gyv; + __m128 Scalev = _mm_set1_ps( Scale ); + __m128 sqrepsv = _mm_set1_ps( sqreps ); + __m128 EdgeStoppingv = _mm_set1_ps( -EdgeStopping ); + __m128 zd5v = _mm_set1_ps( 0.5f ); +#endif +#ifdef _OPENMP +#pragma omp for +#endif + for(int y = 0; y < h1; y++){ + float *rg = &g[w*y]; +#ifdef __SSE2__ + for(x = 0; x < w1-3; x+=4){ + //Estimate the central difference gradient in the center of a four pixel square. (gx, gy) is actually 2*gradient. + gxv = (LVFU(rg[x + 1]) - LVFU(rg[x])) + (LVFU(rg[x + w + 1]) - LVFU(rg[x + w])); + gyv = (LVFU(rg[x + w]) - LVFU(rg[x])) + (LVFU(rg[x + w + 1]) - LVFU(rg[x + 1])); + //Apply power to the magnitude of the gradient to get the edge stopping function. + _mm_storeu_ps( &a[x + w*y], Scalev * pow_F((zd5v*_mm_sqrt_ps(gxv*gxv + gyv*gyv + sqrepsv)), EdgeStoppingv) ); + } + for(; x < w1; x++){ + //Estimate the central difference gradient in the center of a four pixel square. (gx, gy) is actually 2*gradient. + float gx = (rg[x + 1] - rg[x]) + (rg[x + w + 1] - rg[x + w]); + float gy = (rg[x + w] - rg[x]) + (rg[x + w + 1] - rg[x + 1]); + //Apply power to the magnitude of the gradient to get the edge stopping function. + a[x + w*y] = Scale*pow_F(0.5f*sqrtf(gx*gx + gy*gy + sqreps), -EdgeStopping); + } +#else + for(int x = 0; x < w1; x++){ + //Estimate the central difference gradient in the center of a four pixel square. (gx, gy) is actually 2*gradient. + float gx = (rg[x + 1] - rg[x]) + (rg[x + w + 1] - rg[x + w]); + float gy = (rg[x + w] - rg[x]) + (rg[x + w + 1] - rg[x + 1]); + + //Apply power to the magnitude of the gradient to get the edge stopping function. + a[x + w*y] = Scale*pow_F(0.5f*sqrtf(gx*gx + gy*gy + sqreps), -EdgeStopping); + } +#endif + } +} + + + /* Now setup the linear problem. I use the Maxima CAS, here's code for making an FEM formulation for the smoothness term: + p(x, y) := (1 - x)*(1 - y); + P(m, n) := A[m][n]*p(x, y) + A[m + 1][n]*p(1 - x, y) + A[m + 1][n + 1]*p(1 - x, 1 - y) + A[m][n + 1]*p(x, 1 - y); + Integrate(f) := integrate(integrate(f, x, 0, 1), y, 0, 1); + + Integrate(diff(P(u, v), x)*diff(p(x, y), x) + diff(P(u, v), y)*diff(p(x, y), y)); + Integrate(diff(P(u - 1, v), x)*diff(p(1 - x, y), x) + diff(P(u - 1, v), y)*diff(p(1 - x, y), y)); + Integrate(diff(P(u - 1, v - 1), x)*diff(p(1 - x, 1 - y), x) + diff(P(u - 1, v - 1), y)*diff(p(1 - x, 1 - y), y)); + Integrate(diff(P(u, v - 1), x)*diff(p(x, 1 - y), x) + diff(P(u, v - 1), y)*diff(p(x, 1 - y), y)); + So yeah. Use the numeric results of that to fill the matrix A.*/ + + memset(a_1, 0, A->DiagonalLength(1)*sizeof(float)); + memset(a_w1, 0, A->DiagonalLength(w - 1)*sizeof(float)); + memset(a_w, 0, A->DiagonalLength(w)*sizeof(float)); + memset(a_w_1, 0, A->DiagonalLength(w + 1)*sizeof(float)); + + +// checked for race condition here +// a0[] is read and write but adressed by i only +// a[] is read only +// a_w_1 is write only +// a_w is write only +// a_w1 is write only +// a_1 is write only +// So, there should be no race conditions + +#ifdef _OPENMP +#pragma omp parallel for +#endif + for(int y = 0; y < h; y++){ + int i = y*w; + for(int x = 0; x < w; x++, i++){ + float ac,a0temp; + a0temp = 0.25f; + + //Remember, only fill the lower triangle. Memory for upper is never made. It's symmetric. Trust. + if(x > 0 && y > 0) { + ac = a[i - w - 1]/6.0f; + a_w_1[i - w - 1] -= 2.0f*ac; + a_w[i - w] -= ac; + a_1[i - 1] -= ac; + a0temp += ac; + } + if(x < w1 && y > 0) { + ac = a[i - w]/6.0f; + a_w[i - w] -= ac; + a_w1[i - w + 1] -= 2.0f*ac; + a0temp += ac; + } + if(x > 0 && y < h1) { + ac = a[i - 1]/6.0f; + a_1[i - 1] -= ac; + a0temp += ac; + } + if(x < w1 && y < h1) + a0temp += a[i]/6.0f; + a0[i] = 4.0f*a0temp; + } + } + + if(UseBlurForEdgeStop) delete[] a; + //Solve & return. + bool success=A->CreateIncompleteCholeskyFactorization(1); //Fill-in of 1 seems to work really good. More doesn't really help and less hurts (slightly). + if(!success) { + fprintf(stderr,"Error: Tonemapping has failed.\n"); + memset(Blur, 0, sizeof(float)*n); // On failure, set the blur to zero. This is subsequently exponentiated in CompressDynamicRange. + return Blur; + } + if(!UseBlurForEdgeStop) memcpy(Blur, Source, n*sizeof(float)); + SparseConjugateGradient(A->PassThroughVectorProduct, Source, n, false, Blur, 0.0f, (void *)A, Iterates, A->PassThroughCholeskyBackSolve); + A->KillIncompleteCholeskyFactorization(); + return Blur; +} + +float *EdgePreservingDecomposition::CreateIteratedBlur(float *Source, float Scale, float EdgeStopping, int Iterates, int Reweightings, float *Blur){ + //Simpler outcome? + if(Reweightings == 0) return CreateBlur(Source, Scale, EdgeStopping, Iterates, Blur); + + //Create a blur here, initialize. + if(Blur == NULL) Blur = new float[n]; + memcpy(Blur, Source, n*sizeof(float)); + + //Iteratively improve the blur. + Reweightings++; + for(int i = 0; i < Reweightings; i++) + CreateBlur(Source, Scale, EdgeStopping, Iterates, Blur, true); + + return Blur; +} + +SSEFUNCTION float *EdgePreservingDecomposition::CompressDynamicRange(float *Source, float Scale, float EdgeStopping, float CompressionExponent, float DetailBoost, int Iterates, int Reweightings, float *Compressed){ + if(w<300 && h<300) // set number of Reweightings to zero for small images (thumbnails). We could try to find a better solution here. + Reweightings = 0; + + //Small number intended to prevent division by zero. This is different from the eps in CreateBlur. + const float eps = 0.0001f; + + //We're working with luminance, which does better logarithmic. +#ifdef __SSE2__ +#ifdef _OPENMP +#pragma omp parallel +#endif +{ + __m128 epsv = _mm_set1_ps( eps ); +#ifdef _OPENMP +#pragma omp for +#endif + for(int ii = 0; ii < n-3; ii+=4) + _mm_storeu_ps( &Source[ii], xlogf(LVFU(Source[ii]) + epsv)); +} + for(int ii = n-(n%4); ii < n; ii++) + Source[ii] = xlogf(Source[ii] + eps); + +#else +#ifdef _OPENMP +#pragma omp parallel for +#endif + for(int ii = 0; ii < n; ii++) + Source[ii] = xlogf(Source[ii] + eps); +#endif + + //Blur. Also setup memory for Compressed (we can just use u since each element of u is used in one calculation). + float *u = CreateIteratedBlur(Source, Scale, EdgeStopping, Iterates, Reweightings); + if(Compressed == NULL) Compressed = u; + + //Apply compression, detail boost, unlogging. Compression is done on the logged data and detail boost on unlogged. +// float temp = CompressionExponent - 1.0f; + float temp; + if(DetailBoost>0.f) { + float betemp=expf(-(2.f-DetailBoost+0.694f))-1.f;//0.694 = log(2) + temp = 1.2f*xlogf( -betemp); + } + else temp= CompressionExponent - 1.0f; +#ifdef __SSE2__ +#ifdef _OPENMP +#pragma omp parallel +#endif +{ + __m128 cev, uev, sourcev; + __m128 epsv = _mm_set1_ps( eps ); + __m128 DetailBoostv = _mm_set1_ps( DetailBoost ); + __m128 tempv = _mm_set1_ps( temp ); +#ifdef _OPENMP +#pragma omp for +#endif + for(int i = 0; i < n-3; i+=4){ + cev = xexpf(LVFU(Source[i]) + LVFU(u[i])*(tempv)) - epsv; + uev = xexpf(LVFU(u[i])) - epsv; + sourcev = xexpf(LVFU(Source[i])) - epsv; + _mm_storeu_ps( &Source[i], sourcev); + _mm_storeu_ps( &Compressed[i], cev + DetailBoostv * (sourcev - uev) ); + } +} + for(int i=n-(n%4); i < n; i++){ + float ce = xexpf(Source[i] + u[i]*(temp)) - eps; + float ue = xexpf(u[i]) - eps; + Source[i] = xexpf(Source[i]) - eps; + Compressed[i] = ce + DetailBoost*(Source[i] - ue); + } + +#else +#ifdef _OPENMP +#pragma omp parallel for +#endif + for(int i = 0; i < n; i++){ + float ce = xexpf(Source[i] + u[i]*(temp)) - eps; + float ue = xexpf(u[i]) - eps; + Source[i] = xexpf(Source[i]) - eps; + Compressed[i] = ce + DetailBoost*(Source[i] - ue); + } +#endif + + if(Compressed != u) delete[] u; + return Compressed; + +} + diff --git a/rtengine/EdgePreservingDecomposition.h b/rtengine/EdgePreservingDecomposition.h new file mode 100755 index 000000000..631ab7213 --- /dev/null +++ b/rtengine/EdgePreservingDecomposition.h @@ -0,0 +1,138 @@ +#pragma once +/* +The EdgePreservingDecomposition files contain standard C++ (standard except the first line) code for creating and, to a +limited extent (create your own uses!), messing with multi scale edge preserving decompositions of a 32 bit single channel +image. As a byproduct it contains a lot of linear algebra which can be useful for optimization problems that +you want to solve in rectangles on rectangular grids. + +Anyway. Basically, this is an implementation of what's presented in the following papers: + Edge-Preserving Decompositions for Multi-Scale Tone and Detail Manipulation + An Iterative Solution Method for Linear Systems of Which the Coefficient Matrix is a Symetric M-Matrix + Color correction for tone mapping + Wikipedia, the free encyclopedia + +First one is most of what matters, next two are details, last everything else. I did a few things differently, especially: + Reformulated the minimization with finite elements instead of finite differences. This results in better conditioning, + slightly better accuracy (less artifacts), the possibility of a better picked edge stopping function, but more memory consumption. + + A single rotationally invariant edge stopping function is used instead of two non-invariant ones. + + Incomplete Cholseky factorization instead of Szeliski's LAHBF. Slower, but not subject to any patents. + + For tone mapping, original images are decomposed instead of their logarithms, and just one decomposition is made; + I find that this way works plenty good (theirs isn't better or worse... just different) and is simpler. + +Written by ben_pcc in Portland, Oregon, USA. Some history: + Late April 2010, I develop interest in this stuff because photos of my ceramics lack local contrast. + Mid 2010, it works but is too slow to be useful. + Fall 2010, various unsuccessful attempts at speeding up are tried. + Early December 2010, I get off the path of least resistance and write a matrix storage class with incomplete Cholesky decomposition. + 31 December 2010, the FEM reformulation works very well. + 1 January 2011, I'm cleaning up this file and readying it for initial release. + 12 - 14 November 2011, further cleanup, improvements, bug fixes, integration into Raw Therapee. + +It's likely that I'll take apart and rerelease contents of this file (in the distant future) as most of it isn't edge preserving decomposition +and rather supporting material. SparseConjugateGradient alone is a workhorse I and a few others have been exploiting for a few years. + +EdgePreservingDecomposition.h and EdgePreservingDecomposition.cpp are released under the following licence: + � It's free. + � You may not incorporate this code as part of proprietary or commercial software, but via freeware you may use its output for profit. + � You may modify and redistribute, but keep this big comment block intact and not for profit in any way unless I give specific permission. + � If you're unsure about anything else, treat as public domain. + � Don't be a dick. + +My email address is my screen name followed by @yahoo.com. I'm also known as ben_s or nonbasketless. Enjoy! +*/ + + + +#include +#include +#include +#include +#include "opthelper.h" + +//This is for solving big symmetric positive definite linear problems. +float *SparseConjugateGradient(void Ax(float *Product, float *x, void *Pass), float *b, int n, bool OkToModify_b = true, float *x = NULL, float RMSResidual = 0.0f, void *Pass = NULL, int MaximumIterates = 0, void Preconditioner(float *Product, float *x, void *Pass) = NULL); + +//Storage and use class for symmetric matrices, the nonzero contents of which are confined to diagonals. +class MultiDiagonalSymmetricMatrix{ +public: + MultiDiagonalSymmetricMatrix(int Dimension, int NumberOfDiagonalsInLowerTriangle); + ~MultiDiagonalSymmetricMatrix(); + + /* Storage of matrix data, and a function to create memory for Diagonals[index]. + Here's the storage scheme, designed to be simple both on paper and in C++: + + Let's say you have some diagonal. The StartRows is the row on which, at the left edge of the matrix, the diagonal "starts", + and StartRows must strictly increase with its index. The main diagonal for example has start row 0, its subdiagonal has 1, etc. + Then, Diagonal[j] is the matrix entry on the diagonal at column j. For efficiency, you're expected to learn this and fill in + public Diagonals manually. Symmetric matrices are represented by this class, and all symmetry is handled internally, you + only every worry or think about the lower trianglular (including main diagonal) part of the matrix. + */ + float **Diagonals; + char *buffer; + char *DiagBuffer; + int *StartRows; + bool CreateDiagonal(int index, int StartRow); + int n, m; //The matrix is n x n, with m diagonals on the lower triangle. Don't change these. They should be private but aren't for convenience. + inline int DiagonalLength(int StartRow){ //Gives number of elements in a diagonal. + return n - StartRow; + }; + + //Not efficient, but you can use it if you're lazy, or for early tests. Returns false if the row + column falls on no loaded diagonal, true otherwise. + bool LazySetEntry(float value, int row, int column); + + //Calculates the matrix-vector product of the matrix represented by this class onto the vector x. + void VectorProduct(float *Product, float *x); + + //Given the start row, attempts to find the corresponding index, or -1 if the StartRow doesn't exist. + inline int FindIndex(int StartRow) __attribute__((always_inline)); + + //This is the same as above, but designed to take this class as a pass through variable. By this way you can feed + //the meat of this class into an independent function, such as SparseConjugateGradient. + static void PassThroughVectorProduct(float *Product, float *x, void *Pass){ + (static_cast(Pass))->VectorProduct(Product, x); + }; + + /* CreateIncompleteCholeskyFactorization creates another matrix which is an incomplete (or complete if MaxFillAbove is big enough) + LDLt factorization of this matrix. Storage is like this: the first diagonal is the diagonal matrix D and the remaining diagonals + describe all of L except its main diagonal, which is a bunch of ones. Read up on the LDLt Cholesky factorization for what all this means. + Note that VectorProduct is nonsense. More useful to you is CholeskyBackSolve which fills x, where LDLt x = b. */ + bool CreateIncompleteCholeskyFactorization(int MaxFillAbove = 0); + void KillIncompleteCholeskyFactorization(void); + void CholeskyBackSolve(float *x, float *b); + MultiDiagonalSymmetricMatrix *IncompleteCholeskyFactorization; + + static void PassThroughCholeskyBackSolve(float *Product, float *x, void *Pass){ + (static_cast(Pass))->CholeskyBackSolve(Product, x); + }; + +}; + +class EdgePreservingDecomposition{ +public: + EdgePreservingDecomposition(int width, int height); + ~EdgePreservingDecomposition(); + + //Create an edge preserving blur of Source. Will create and return, or fill into Blur if not NULL. In place not ok. + //If UseBlurForEdgeStop is true, supplied not NULL Blur is used to calculate the edge stopping function instead of Source. + float *CreateBlur(float *Source, float Scale, float EdgeStopping, int Iterates, float *Blur = NULL, bool UseBlurForEdgeStop = false); + + //Iterates CreateBlur such that the smoothness term approaches a specific norm via iteratively reweighted least squares. In place not ok. + float *CreateIteratedBlur(float *Source, float Scale, float EdgeStopping, int Iterates, int Reweightings, float *Blur = NULL); + + /*Lowers global contrast while preserving or boosting local contrast. Can fill into Compressed. The smaller Compression + the more compression is applied, with Compression = 1 giving no effect and above 1 the opposite effect. You can totally + use Compression = 1 and play with DetailBoost for some really sweet unsharp masking. If working on luma/grey, consider giving it a logarithm. + In place calculation to save memory (Source == Compressed) is totally ok. Reweightings > 0 invokes CreateIteratedBlur instead of CreateBlur. */ + float *CompressDynamicRange(float *Source, float Scale = 1.0f, float EdgeStopping = 1.4f, float CompressionExponent = 0.8f, float DetailBoost = 0.1f, int Iterates = 20, int Reweightings = 0, float *Compressed = NULL); + +private: + MultiDiagonalSymmetricMatrix *A; //The equations are simple enough to not mandate a matrix class, but fast solution NEEDS a complicated preconditioner. + int w, h, n; + + //Convenient access to the data in A. + float * RESTRICT a0, * RESTRICT a_1, * RESTRICT a_w, * RESTRICT a_w_1, * RESTRICT a_w1; +}; + diff --git a/rtengine/FTblockDN.cc b/rtengine/FTblockDN.cc new file mode 100644 index 000000000..2343ff865 --- /dev/null +++ b/rtengine/FTblockDN.cc @@ -0,0 +1,2944 @@ +//////////////////////////////////////////////////////////////// +// +// CFA denoise by wavelet transform, FT filtering +// +// copyright (c) 2008-2012 Emil Martinec +// +// +// code dated: March 9, 2012 +// +// FTblockDN.cc is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +//////////////////////////////////////////////////////////////// + +#include +#include +#include "../rtgui/threadutils.h" +#include "rtengine.h" +#include "improcfun.h" +#include "LUT.h" +#include "array2D.h" +#include "iccmatrices.h" +#include "boxblur.h" +#include "rt_math.h" +#include "mytime.h" +#include "sleef.c" +#include "opthelper.h" +#include "cplx_wavelet_dec.h" + +#ifdef _OPENMP +#include +#endif + +#define TS 64 // Tile size +#define offset 25 // shift between tiles +#define fTS ((TS/2+1)) // second dimension of Fourier tiles +#define blkrad 1 // radius of block averaging + +#define epsilon 0.001f/(TS*TS) //tolerance + +#define med2(a0,a1,a2,a3,a4,median) { \ +pp[0]=a0; pp[1]=a1; pp[2]=a2; pp[3]=a3; pp[4]=a4; \ +PIX_SORT(pp[0],pp[1]) ; PIX_SORT(pp[3],pp[4]) ; PIX_SORT(pp[0],pp[3]) ;\ +PIX_SORT(pp[1],pp[4]) ; PIX_SORT(pp[1],pp[2]) ; PIX_SORT(pp[2],pp[3]) ;\ +PIX_SORT(pp[1],pp[2]) ; median=pp[2] ;} + +#define med5(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20,a21,a22,a23,a24,median) { \ +pp[0]=a0; pp[1]=a1; pp[2]=a2; pp[3]=a3; pp[4]=a4; pp[5]=a5; pp[6]=a6; pp[7]=a7; pp[8]=a8; pp[9]=a9; pp[10]=a10; pp[11]=a11; pp[12]=a12; \ +pp[13]=a13; pp[14]=a14; pp[15]=a15; pp[16]=a16; pp[17]=a17; pp[18]=a18; pp[19]=a19; pp[20]=a20; pp[21]=a21; pp[22]=a22; pp[23]=a23; pp[24]=a24; \ +PIX_SORT(pp[0], pp[1]) ; PIX_SORT(pp[3], pp[4]) ; PIX_SORT(pp[2], pp[4]) ;\ +PIX_SORT(pp[2], pp[3]) ; PIX_SORT(pp[6], pp[7]) ; PIX_SORT(pp[5], pp[7]) ;\ +PIX_SORT(pp[5], pp[6]) ; PIX_SORT(pp[9], pp[10]) ; PIX_SORT(pp[8], pp[10]) ;\ +PIX_SORT(pp[8], pp[9]) ; PIX_SORT(pp[12], pp[13]) ; PIX_SORT(pp[11], pp[13]) ;\ +PIX_SORT(pp[11], pp[12]) ; PIX_SORT(pp[15], pp[16]) ; PIX_SORT(pp[14], pp[16]) ;\ +PIX_SORT(pp[14], pp[15]) ; PIX_SORT(pp[18], pp[19]) ; PIX_SORT(pp[17], pp[19]) ;\ +PIX_SORT(pp[17], pp[18]) ; PIX_SORT(pp[21], pp[22]) ; PIX_SORT(pp[20], pp[22]) ;\ +PIX_SORT(pp[20], pp[21]) ; PIX_SORT(pp[23], pp[24]) ; PIX_SORT(pp[2], pp[5]) ;\ +PIX_SORT(pp[3], pp[6]) ; PIX_SORT(pp[0], pp[6]) ; PIX_SORT(pp[0], pp[3]) ;\ +PIX_SORT(pp[4], pp[7]) ; PIX_SORT(pp[1], pp[7]) ; PIX_SORT(pp[1], pp[4]) ;\ +PIX_SORT(pp[11], pp[14]) ; PIX_SORT(pp[8], pp[14]) ; PIX_SORT(pp[8], pp[11]) ;\ +PIX_SORT(pp[12], pp[15]) ; PIX_SORT(pp[9], pp[15]) ; PIX_SORT(pp[9], pp[12]) ;\ +PIX_SORT(pp[13], pp[16]) ; PIX_SORT(pp[10], pp[16]) ; PIX_SORT(pp[10], pp[13]) ;\ +PIX_SORT(pp[20], pp[23]) ; PIX_SORT(pp[17], pp[23]) ; PIX_SORT(pp[17], pp[20]) ;\ +PIX_SORT(pp[21], pp[24]) ; PIX_SORT(pp[18], pp[24]) ; PIX_SORT(pp[18], pp[21]) ;\ +PIX_SORT(pp[19], pp[22]) ; PIX_SORT(pp[8], pp[17]) ; PIX_SORT(pp[9], pp[18]) ;\ +PIX_SORT(pp[0], pp[18]) ; PIX_SORT(pp[0], pp[9]) ; PIX_SORT(pp[10], pp[19]) ;\ +PIX_SORT(pp[1], pp[19]) ; PIX_SORT(pp[1], pp[10]) ; PIX_SORT(pp[11], pp[20]) ;\ +PIX_SORT(pp[2], pp[20]) ; PIX_SORT(pp[2], pp[11]) ; PIX_SORT(pp[12], pp[21]) ;\ +PIX_SORT(pp[3], pp[21]) ; PIX_SORT(pp[3], pp[12]) ; PIX_SORT(pp[13], pp[22]) ;\ +PIX_SORT(pp[4], pp[22]) ; PIX_SORT(pp[4], pp[13]) ; PIX_SORT(pp[14], pp[23]) ;\ +PIX_SORT(pp[5], pp[23]) ; PIX_SORT(pp[5], pp[14]) ; PIX_SORT(pp[15], pp[24]) ;\ +PIX_SORT(pp[6], pp[24]) ; PIX_SORT(pp[6], pp[15]) ; PIX_SORT(pp[7], pp[16]) ;\ +PIX_SORT(pp[7], pp[19]) ; PIX_SORT(pp[13], pp[21]) ; PIX_SORT(pp[15], pp[23]) ;\ +PIX_SORT(pp[7], pp[13]) ; PIX_SORT(pp[7], pp[15]) ; PIX_SORT(pp[1], pp[9]) ;\ +PIX_SORT(pp[3], pp[11]) ; PIX_SORT(pp[5], pp[17]) ; PIX_SORT(pp[11], pp[17]) ;\ +PIX_SORT(pp[9], pp[17]) ; PIX_SORT(pp[4], pp[10]) ; PIX_SORT(pp[6], pp[12]) ;\ +PIX_SORT(pp[7], pp[14]) ; PIX_SORT(pp[4], pp[6]) ; PIX_SORT(pp[4], pp[7]) ;\ +PIX_SORT(pp[12], pp[14]) ; PIX_SORT(pp[10], pp[14]) ; PIX_SORT(pp[6], pp[7]) ;\ +PIX_SORT(pp[10], pp[12]) ; PIX_SORT(pp[6], pp[10]) ; PIX_SORT(pp[6], pp[17]) ;\ +PIX_SORT(pp[12], pp[17]) ; PIX_SORT(pp[7], pp[17]) ; PIX_SORT(pp[7], pp[10]) ;\ +PIX_SORT(pp[12], pp[18]) ; PIX_SORT(pp[7], pp[12]) ; PIX_SORT(pp[10], pp[18]) ;\ +PIX_SORT(pp[12], pp[20]) ; PIX_SORT(pp[10], pp[20]) ; PIX_SORT(pp[10], pp[12]) ;\ +median=pp[12];} + +#define ELEM_FLOAT_SWAP(a,b) { register float t=(a);(a)=(b);(b)=t; } + +namespace rtengine { + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + /* + Structure of the algorithm: + + 1. Compute an initial denoise of the image via undecimated wavelet transform + and universal thresholding modulated by user input. + 2. Decompose the residual image into TSxTS size tiles, shifting by 'offset' each step + (so roughly each pixel is in (TS/offset)^2 tiles); Discrete Cosine transform the tiles. + 3. Filter the DCT data to pick out patterns missed by the wavelet denoise + 4. Inverse DCT the denoised tile data and combine the tiles into a denoised output image. + + */ + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +extern const Settings* settings; + +// Median calculation using quicksort +float fq_sort2(float arr[], int n) +{ + int low = 0; + int high = n-1; + int median = (low + high) / 2; + + for (;;) { + if (high <= low) + return arr[median] ; + if (high == low + 1) { + if (arr[low] > arr[high]) + ELEM_FLOAT_SWAP(arr[low], arr[high]) ; + return arr[median] ; + } + + int middle = (low + high) / 2; + if (arr[middle] > arr[high]) ELEM_FLOAT_SWAP(arr[middle], arr[high]) ; + if (arr[low] > arr[high]) ELEM_FLOAT_SWAP(arr[low], arr[high]) ; + if (arr[middle] > arr[low]) ELEM_FLOAT_SWAP(arr[middle], arr[low]) ; + + ELEM_FLOAT_SWAP(arr[middle], arr[low+1]) ; + int ll = low + 1; + int hh = high; + + for (;;) { + do ll++; while (arr[low] > arr[ll]) ; + do hh--; while (arr[hh] > arr[low]) ; + + if (hh < ll) + break; + + ELEM_FLOAT_SWAP(arr[ll], arr[hh]) ; + } + + ELEM_FLOAT_SWAP(arr[low], arr[hh]) ; + + if (hh <= median) + low = ll; + if (hh >= median) + high = hh - 1; + } + } + +float media(float *elements, int N) +{ + + // Order elements (only half of them) + for (int i = 0; i < (N >> 1) + 1; ++i) + { + // Find position of minimum element + int min = i; + for (int j = i + 1; j < N; ++j) + if (elements[j] < elements[min]) + min = j; + // Put found minimum element in its place + float temp = elements[i]; + elements[i] = elements[min]; + elements[min] = temp; + } + // Get result - the middle element + return elements[N >> 1]; +} + +void ImProcFunctions::Median_Denoise( float **src, float **dst, const int width, const int height, const mediantype medianType, const int iterations, const int numThreads, float **buffer) +{ + int border=1, numElements, middleElement; + switch(medianType) { + case MED_3X3SOFT: + case MED_3X3STRONG: + border = 1; + break; + case MED_5X5SOFT: + border = 2; + break; + case MED_5X5STRONG: + border = 2; + break; + case MED_7X7: + border = 3; + numElements = 49; + middleElement = 24; + break; + default: // includes MED_9X9 + border = 4; + numElements = 81; + middleElement = 40; + } + + float **allocBuffer = NULL; + float **medBuffer[2]; + medBuffer[0] = src; + // we need a buffer if src == dst or if (src != dst && iterations > 1) + if(src == dst || (src != dst && iterations>1)) { + if(buffer == NULL) { // we didn't get a buufer => create one + allocBuffer = new float*[height]; + for (int i=0; i use it + medBuffer[1] = buffer; + } + } else { // we can write directly into destination + medBuffer[1] = dst; + } + + float ** medianIn, ** medianOut; + int BufferIndex = 0; + for(int iteration=1;iteration<=iterations;iteration++){ + medianIn = medBuffer[BufferIndex]; + medianOut = medBuffer[BufferIndex^1]; + + if(iteration == 1) { // upper border + for (int i=0; i1) +#endif + for (int i=border; i1) +#endif + for(int i = border; i < height-border; i++ ) { + for(int j = border; j < width-border; j++) { + dst[i][j] = medianOut[i][j]; + } + } + } + if(allocBuffer != NULL) { // we allocated memory, so let's free it now + for (int i=0; icopyData(dst); + if(calclum) { + delete calclum; + calclum = NULL; + } + + return; + } + + static MyMutex 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/(float) settings->nrhigh : 1.0f; + const bool useNoiseCCurve = (noiseCCurve && noiseCCurve.getSum() > 5.f ); + const bool useNoiseLCurve = (noiseLCurve && noiseLCurve.getSum() >= 7.f ); + const bool autoch = (settings->leveldnautsimpl==1 && (dnparams.Cmethod=="AUT" || dnparams.Cmethod=="PRE")) || (settings->leveldnautsimpl==0 && (dnparams.C2method=="AUTO" || dnparams.C2method=="PREV")); + + float** lumcalc; + float* lumcalcBuffer; + float** ccalc; + float* ccalcBuffer; + + bool ponder=false; + float ponderCC=1.f; + if(settings->leveldnautsimpl==1 && params->dirpyrDenoise.Cmethod=="PON") {ponder=true;ponderCC=0.5f;} + if(settings->leveldnautsimpl==1 && params->dirpyrDenoise.Cmethod=="PRE") {ponderCC=0.5f;} + if(settings->leveldnautsimpl==0 && params->dirpyrDenoise.Cmethod=="PREV") {ponderCC=0.5f;} + + int metchoice=0; + if(dnparams.methodmed=="Lonly") metchoice=1; + else if(dnparams.methodmed=="Lab") metchoice=2; + else if(dnparams.methodmed=="ab") metchoice=3; + else if(dnparams.methodmed=="Lpab") metchoice=4; + + const bool denoiseMethodRgb = (dnparams.dmethod == "RGB"); + // init luma noisevarL + const float noiseluma=(float) dnparams.luma; + const float noisevarL = (useNoiseLCurve && (denoiseMethodRgb || !isRAW)) ? (float) (SQR(((noiseluma+1.0)/125.0)*(10.+ (noiseluma+1.0)/25.0))) : (float) (SQR((noiseluma/125.0)*(1.0+ noiseluma/25.0))); + const bool denoiseLuminance = (noisevarL > 0.00001f); + //printf("NL=%f \n",noisevarL); + if(useNoiseLCurve || useNoiseCCurve) { + int hei=calclum->height; + int wid=calclum->width; + TMatrix wprofi = iccStore->workingSpaceMatrix (params->icm.working); + + const float wpi[3][3] = { + {static_cast(wprofi[0][0]),static_cast(wprofi[0][1]),static_cast(wprofi[0][2])}, + {static_cast(wprofi[1][0]),static_cast(wprofi[1][1]),static_cast(wprofi[1][2])}, + {static_cast(wprofi[2][0]),static_cast(wprofi[2][1]),static_cast(wprofi[2][2])} + }; + lumcalcBuffer = new float[hei*wid]; + lumcalc = new float*[(hei)]; + for (int i=0; ir(ii,jj); + float GL = calclum->g(ii,jj); + float BL = calclum->b(ii,jj); + // determine luminance and chrominance for noisecurves + float XL,YL,ZL; + Color::rgbxyz(RL,GL,BL,XL,YL,ZL,wpi); + Color::XYZ2Lab(XL, YL, ZL, LLum, AAum, BBum); + if(useNoiseLCurve) { + float epsi = 0.01f; + if(LLum<2.f) + LLum = 2.f;//avoid divided by zero + if(LLum>32768.f) + LLum = 32768.f; // not strictly necessary + float kinterm = epsi + noiseLCurve[xdivf(LLum,15)*500.f]; + kinterm *= 100.f; + kinterm += noiseluma; + lumcalc[ii][jj] = SQR((kinterm/125.f)*(1.f+kinterm/25.f)); + } + if(useNoiseCCurve) { + float cN = sqrtf(SQR(AAum)+SQR(BBum)); + if(cN > 100) + ccalc[ii][jj] = SQR(1.f + ponderCC*(4.f*noiseCCurve[cN / 60.f])); + else + ccalc[ii][jj] = cn100Precalc; + } + } + } + delete calclum; + calclum = NULL; + } + + const short int imheight=src->height, imwidth=src->width; + + if (dnparams.luma!=0 || dnparams.chroma!=0 || dnparams.methodmed=="Lab" || dnparams.methodmed=="Lonly" ) { + // gamma transform for input data + float gam = dnparams.gamma; + float gamthresh = 0.001f; + if(!isRAW) {//reduce gamma under 1 for Lab mode ==> TIF and JPG + if(gam < 1.9f) + gam = 1.f - (1.9f-gam)/3.f;//minimum gamma 0.7 + else if (gam >= 1.9f && gam <= 3.f) + gam = (1.4f/1.1f)*gam - 1.41818f; + } + float gamslope = exp(log((double)gamthresh)/gam)/gamthresh; + + LUTf gamcurve(65536,LUT_CLIP_BELOW); + if(denoiseMethodRgb) { + for (int i=0; i<65536; i++) { + gamcurve[i] = (Color::gamma((double)i/65535.0, gam, gamthresh, gamslope, 1.0, 0.0)) * 32768.0f; + } + } else { + for (int i=0; i<65536; i++) { + gamcurve[i] = (Color::gamman((double)i/65535.0,gam)) * 32768.0f; + } + } + + // inverse gamma transform for output data + float igam = 1.f/gam; + float igamthresh = gamthresh*gamslope; + float igamslope = 1.f/gamslope; + + LUTf igamcurve(65536,LUT_CLIP_BELOW); + if(denoiseMethodRgb) { + for (int i=0; i<65536; i++) { + igamcurve[i] = (Color::gamma((float)i/32768.0f, igam, igamthresh, igamslope, 1.0, 0.0) * 65535.0f); + } + } else { + for (int i=0; i<65536; i++) { + igamcurve[i] = (Color::gamman((float)i/32768.0f,igam) * 65535.0f); + } + } + + const float gain = pow (2.0f, float(expcomp)); + float noisevar_Ldetail = SQR((float)(SQR(100.-dnparams.Ldetail) + 50.*(100.-dnparams.Ldetail)) * TS * 0.5f); + if(settings->verbose) + printf("Denoise Lab=%i\n",settings->denoiselabgamma); + + // To avoid branches in loops we access the gammatabs by pointers + // modify arbitrary data for Lab..I have test : nothing, gamma 2.6 11 - gamma 4 5 - gamma 5.5 10 + // we can put other as gamma g=2.6 slope=11, etc. + // but noting to do with real gamma !!!: it's only for data Lab # data RGB + // finally I opted fot gamma55 and with options we can change + + LUTf *denoisegamtab; + LUTf *denoiseigamtab; + switch(settings->denoiselabgamma) { + case 0: denoisegamtab = &(Color::gammatab_26_11); + denoiseigamtab = &(Color::igammatab_26_11); + break; + case 1: denoisegamtab = &(Color::gammatab_4); + denoiseigamtab = &(Color::igammatab_4); + break; + default: denoisegamtab = &(Color::gammatab_55); + denoiseigamtab = &(Color::igammatab_55); + break; + } + + array2D tilemask_in(TS,TS); + array2D tilemask_out(TS,TS); + if(denoiseLuminance) { + const int border = MAX(2,TS/16); + for (int i=0; iTS/2 ? i-TS+1 : i)); + float vmask = (i1TS/2 ? j-TS+1 : j)); + tilemask_in[i][j] = (vmask * (j1leveldnti ==0) { + tilesize = 1024; + overlap = 128; +} +if(settings->leveldnti ==1) { + tilesize = 768; + overlap = 96; +} + int numTries = 0; + if(ponder) + printf("Tiled denoise processing caused by Automatic Multizone mode\n"); + bool memoryAllocationFailed = false; + +do { + numTries++; + if(numTries == 2) + printf("1st denoise pass failed due to insufficient memory, starting 2nd (tiled) pass now...\n"); + int numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip; + + Tile_calc (tilesize, overlap, (options.rgbDenoiseThreadLimit == 0 && !ponder) ? (numTries == 1 ? 0 : 2) : 2, imwidth, imheight, numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip); + memoryAllocationFailed = false; + const int numtiles = numtiles_W * numtiles_H; + + //output buffer + Imagefloat * dsttmp; + if(numtiles == 1) + dsttmp = dst; + else { + dsttmp = new Imagefloat(imwidth,imheight); +#ifdef _OPENMP +#pragma omp parallel for +#endif + for(int i=0;ir(i,j) = 0.f; + dsttmp->g(i,j) = 0.f; + dsttmp->b(i,j) = 0.f; + } + } + + //now we have tile dimensions, overlaps + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + // According to FFTW-Doc 'it is safe to execute the same plan in parallel by multiple threads', so we now create 4 plans + // outside the parallel region and use them inside the parallel region. + + // calculate max size of numblox_W. + int max_numblox_W = ceil(((float)(MIN(imwidth,tilewidth)))/(offset))+2*blkrad; + // calculate min size of numblox_W. + int min_numblox_W = ceil(((float)((MIN(imwidth,((numtiles_W - 1) * tileWskip) + tilewidth) ) - ((numtiles_W - 1) * tileWskip)))/(offset))+2*blkrad; + + // these are needed only for creation of the plans and will be freed before entering the parallel loop + fftwf_plan plan_forward_blox[2]; + fftwf_plan plan_backward_blox[2]; + + if(denoiseLuminance) { + float *Lbloxtmp = (float*) fftwf_malloc(max_numblox_W*TS*TS*sizeof (float)); + float *fLbloxtmp = (float*) fftwf_malloc(max_numblox_W*TS*TS*sizeof (float)); + + int nfwd[2]={TS,TS}; + + //for DCT: + fftw_r2r_kind fwdkind[2] = {FFTW_REDFT10, FFTW_REDFT10}; + fftw_r2r_kind bwdkind[2] = {FFTW_REDFT01, FFTW_REDFT01}; + + // Creating the plans with FFTW_MEASURE instead of FFTW_ESTIMATE speeds up the execute a bit + plan_forward_blox[0] = fftwf_plan_many_r2r(2, nfwd, max_numblox_W, Lbloxtmp, NULL, 1, TS*TS, fLbloxtmp, NULL, 1, TS*TS, fwdkind, FFTW_MEASURE || FFTW_DESTROY_INPUT ); + plan_backward_blox[0] = fftwf_plan_many_r2r(2, nfwd, max_numblox_W, fLbloxtmp, NULL, 1, TS*TS, Lbloxtmp, NULL, 1, TS*TS, bwdkind, FFTW_MEASURE || FFTW_DESTROY_INPUT ); + plan_forward_blox[1] = fftwf_plan_many_r2r(2, nfwd, min_numblox_W, Lbloxtmp, NULL, 1, TS*TS, fLbloxtmp, NULL, 1, TS*TS, fwdkind, FFTW_MEASURE || FFTW_DESTROY_INPUT ); + plan_backward_blox[1] = fftwf_plan_many_r2r(2, nfwd, min_numblox_W, fLbloxtmp, NULL, 1, TS*TS, Lbloxtmp, NULL, 1, TS*TS, bwdkind, FFTW_MEASURE || FFTW_DESTROY_INPUT ); + fftwf_free ( Lbloxtmp ); + fftwf_free ( fLbloxtmp ); + } + +#ifndef _OPENMP + int numthreads = 1; +#else + // Calculate number of tiles. If less than omp_get_max_threads(), then limit num_threads to number of tiles + int numthreads = MIN(numtiles,omp_get_max_threads()); + if(options.rgbDenoiseThreadLimit > 0) + numthreads = MIN(numthreads,options.rgbDenoiseThreadLimit); +#ifdef _RT_NESTED_OPENMP + denoiseNestedLevels = omp_get_max_threads() / numthreads; + bool oldNested = omp_get_nested(); + if(denoiseNestedLevels < 2) + denoiseNestedLevels = 1; + else + omp_set_nested(true); + if(options.rgbDenoiseThreadLimit > 0) + while(denoiseNestedLevels*numthreads > options.rgbDenoiseThreadLimit) + denoiseNestedLevels--; +#endif + if(settings->verbose) + printf("RGB_denoise uses %d main thread(s) and up to %d nested thread(s) for each main thread\n",numthreads,denoiseNestedLevels); +#endif + float *LbloxArray[denoiseNestedLevels*numthreads]; + float *fLbloxArray[denoiseNestedLevels*numthreads]; + + if(numtiles > 1 && denoiseLuminance) + for(int i=0;iworkingSpaceInverseMatrix (params->icm.working); + //inverse matrix user select + const float wip[3][3] = { + {static_cast(wiprof[0][0]),static_cast(wiprof[0][1]),static_cast(wiprof[0][2])}, + {static_cast(wiprof[1][0]),static_cast(wiprof[1][1]),static_cast(wiprof[1][2])}, + {static_cast(wiprof[2][0]),static_cast(wiprof[2][1]),static_cast(wiprof[2][2])} + }; + + TMatrix wprof = iccStore->workingSpaceMatrix (params->icm.working); + + const float wp[3][3] = { + {static_cast(wprof[0][0]),static_cast(wprof[0][1]),static_cast(wprof[0][2])}, + {static_cast(wprof[1][0]),static_cast(wprof[1][1]),static_cast(wprof[1][2])}, + {static_cast(wprof[2][0]),static_cast(wprof[2][1]),static_cast(wprof[2][2])} + }; + + + // begin tile processing of image +#ifdef _OPENMP +#pragma omp parallel num_threads(numthreads) if(numthreads>1) +#endif + { + int pos; + float* noisevarlum; + float* noisevarchrom; + if(numtiles == 1 && isRAW && (useNoiseCCurve || useNoiseLCurve)) { + noisevarlum = lumcalcBuffer; + noisevarchrom = ccalcBuffer; + } else { + noisevarlum = new float[((tileheight+1)/2)*((tilewidth+1)/2)]; + noisevarchrom = new float[((tileheight+1)/2)*((tilewidth+1)/2)]; + } + +#ifdef _OPENMP +#pragma omp for schedule(dynamic) collapse(2) +#endif + + for (int tiletop=0; tiletop 0.) intermred=(dnparams.redchro/10.); else intermred= (float) dnparams.redchro/7.0;//increase slower than linear for more sensit + if(dnparams.bluechro > 0.) intermblue=(dnparams.bluechro/10.); else intermblue= (float) dnparams.bluechro/7.0;//increase slower than linear for more sensit + if(ponder && kall==2){interm_med=ch_M[pos]/10.f; intermred=max_r[pos]/10.f;intermblue=max_b[pos]/10.f;} + if(ponder && kall==0){interm_med=0.01f; intermred=0.f;intermblue=0.f;} + realred = interm_med + intermred; if (realred < 0.f) realred=0.001f; + realblue = interm_med + intermblue; if (realblue < 0.f) realblue=0.001f; + const float noisevarab_r = SQR(realred); + const float noisevarab_b = SQR(realblue); + + //input L channel + array2D *Lin; + //wavelet denoised image + LabImage * labdn = new LabImage(width,height); + + //fill tile from image; convert RGB to "luma/chroma" + const float maxNoiseVarab = max(noisevarab_b,noisevarab_r); + if (isRAW) {//image is raw; use channel differences for chroma channels + + if(!denoiseMethodRgb){//lab mode + //modification Jacques feb 2013 and july 2014 +#ifdef _RT_NESTED_OPENMP +#pragma omp parallel for num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) +#endif + for (int i=tiletop; ir(i,j); + float G_ = gain*src->g(i,j); + float B_ = gain*src->b(i,j); + + R_ = (*denoiseigamtab)[R_]; + G_ = (*denoiseigamtab)[G_]; + B_ = (*denoiseigamtab)[B_]; + + //apply gamma noise standard (slider) + R_ = R_<65535.0f ? gamcurve[R_] : (Color::gammanf(R_/65535.f, gam)*32768.0f); + G_ = G_<65535.0f ? gamcurve[G_] : (Color::gammanf(G_/65535.f, gam)*32768.0f); + B_ = B_<65535.0f ? gamcurve[B_] : (Color::gammanf(B_/65535.f, gam)*32768.0f); + + //true conversion xyz=>Lab + float X,Y,Z; + Color::rgbxyz(R_,G_,B_,X,Y,Z,wp); + + //convert to Lab + float L,a,b; + Color::XYZ2Lab(X, Y, Z, L, a, b); + + labdn->L[i1][j1] = L; + labdn->a[i1][j1] = a; + labdn->b[i1][j1] = b; + + if(((i1|j1)&1) == 0) { + if(numTries == 1) { + noisevarlum[(i1>>1)*width2+(j1>>1)] = useNoiseLCurve ? lumcalc[i>>1][j>>1] : noisevarL; + noisevarchrom[(i1>>1)*width2+(j1>>1)] = useNoiseCCurve ? maxNoiseVarab*ccalc[i>>1][j>>1] : 1.f; + } else { + noisevarlum[(i1>>1)*width2+(j1>>1)] = lumcalc[i>>1][j>>1]; + noisevarchrom[(i1>>1)*width2+(j1>>1)] = ccalc[i>>1][j>>1]; + } + } + //end chroma + } + } + } else {//RGB mode +#ifdef _RT_NESTED_OPENMP +#pragma omp parallel for num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) +#endif + for (int i=tiletop; ir(i,j); + float Y = gain*src->g(i,j); + float Z = gain*src->b(i,j); + //conversion colorspace to determine luminance with no gamma + X = X<65535.0f ? gamcurve[X] : (Color::gamma((double)X/65535.0, gam, gamthresh, gamslope, 1.0, 0.0)*32768.0f); + Y = Y<65535.0f ? gamcurve[Y] : (Color::gamma((double)Y/65535.0, gam, gamthresh, gamslope, 1.0, 0.0)*32768.0f); + Z = Z<65535.0f ? gamcurve[Z] : (Color::gamma((double)Z/65535.0, gam, gamthresh, gamslope, 1.0, 0.0)*32768.0f); + //end chroma + labdn->L[i1][j1] = Y; + labdn->a[i1][j1] = (X-Y); + labdn->b[i1][j1] = (Y-Z); + + if(((i1|j1)&1) == 0) { + if(numTries == 1) { + noisevarlum[(i1>>1)*width2+(j1>>1)] = useNoiseLCurve ? lumcalc[i>>1][j>>1] : noisevarL; + noisevarchrom[(i1>>1)*width2+(j1>>1)] = useNoiseCCurve ? maxNoiseVarab*ccalc[i>>1][j>>1] : 1.f; + } else { + noisevarlum[(i1>>1)*width2+(j1>>1)] = lumcalc[i>>1][j>>1]; + noisevarchrom[(i1>>1)*width2+(j1>>1)] = ccalc[i>>1][j>>1]; + } + } + } + } + } + } else {//image is not raw; use Lab parametrization +#ifdef _RT_NESTED_OPENMP +#pragma omp parallel for num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) +#endif + for (int i=tiletop; ir(i,j) ;//for denoise curves + float gLum=src->g(i,j) ; + float bLum=src->b(i,j) ; + + //use gamma sRGB, not good if TIF (JPG) Output profil not with gamma sRGB (eg : gamma =1.0, or 1.8...) + //very difficult to solve ! + // solution ==> save TIF with gamma sRGB and re open + float rtmp = Color::igammatab_srgb[ src->r(i,j) ]; + float gtmp = Color::igammatab_srgb[ src->g(i,j) ]; + float btmp = Color::igammatab_srgb[ src->b(i,j) ]; + //modification Jacques feb 2013 + // gamma slider different from raw + rtmp = rtmp<65535.0f ? gamcurve[rtmp] : (Color::gamman((double)rtmp/65535.0, gam)*32768.0f); + gtmp = gtmp<65535.0f ? gamcurve[gtmp] : (Color::gamman((double)gtmp/65535.0, gam)*32768.0f); + btmp = btmp<65535.0f ? gamcurve[btmp] : (Color::gamman((double)btmp/65535.0, gam)*32768.0f); + + float X,Y,Z; + Color::rgbxyz(rtmp,gtmp,btmp,X,Y,Z,wp); + + //convert Lab + Color::XYZ2Lab(X, Y, Z, L, a, b); + labdn->L[i1][j1] = L; + labdn->a[i1][j1] = a; + labdn->b[i1][j1] = b; + + if(((i1|j1)&1) == 0) { + float Llum,alum,blum; + if(useNoiseLCurve || useNoiseCCurve) { + float XL,YL,ZL; + Color::rgbxyz(rLum,gLum,bLum,XL,YL,ZL,wp); + Color::XYZ2Lab(XL, YL, ZL, Llum, alum, blum); + } + + if(useNoiseLCurve) { + float kN = Llum; + float epsi=0.01f; + if(kN<2.f) kN=2.f; + if(kN>32768.f) kN=32768.f; + float kinterm=epsi + noiseLCurve[xdivf(kN,15)*500.f]; + float ki=kinterm*100.f; + ki+=noiseluma; + noisevarlum[(i1>>1)*width2+(j1>>1)]=SQR((ki/125.f)*(1.f+ki/25.f)); + } else { + noisevarlum[(i1>>1)*width2+(j1>>1)] = noisevarL; + } + if(useNoiseCCurve) { + float aN=alum; + float bN=blum; + float cN=sqrtf(SQR(aN)+SQR(bN)); + if(cN < 100.f) + cN=100.f;//avoid divided by zero ??? + float Cinterm=1.f + ponderCC*4.f*noiseCCurve[cN/60.f]; + noisevarchrom[(i1>>1)*width2+(j1>>1)]= maxNoiseVarab*SQR(Cinterm); + } else { + noisevarchrom[(i1>>1)*width2+(j1>>1)] = 1.f; + } + } + } + } + } + + //now perform basic wavelet denoise + //arguments 4 and 5 of wavelet decomposition are max number of wavelet decomposition levels; + //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. + //actual implementation only works with subsampling set to 1 + float interm_medT = (float) dnparams.chroma/10.0; + bool execwavelet = true; + if(!denoiseLuminance && interm_medT < 0.05f && dnparams.median && (dnparams.methodmed=="Lab" || dnparams.methodmed=="Lonly")) + execwavelet=false;//do not exec wavelet if sliders luminance and chroma are very small and median need + //we considered user don't want wavelet + if(settings->leveldnautsimpl==1 && dnparams.Cmethod!="MAN") + execwavelet=true; + if(settings->leveldnautsimpl==0 && dnparams.C2method!="MANU") + execwavelet=true; + if(execwavelet) {//gain time if user choose only median sliders L <=1 slider chrom master < 1 + wavelet_decomposition* Ldecomp; + wavelet_decomposition* adecomp; + + int levwav=5; + float maxreal = max(realred, realblue); + //increase the level of wavelet if user increase much or very much sliders + if( maxreal < 8.f) levwav=5; + else if( maxreal < 10.f)levwav=6; + else if( maxreal < 15.f)levwav=7; + else levwav=8;//maximum ==> I have increase Maxlevel in cplx_wavelet_dec.h from 8 to 9 + if(nrQuality == QUALITY_HIGH) + levwav += settings->nrwavlevel;//increase level for enhanced mode + if(levwav>8) levwav=8; + int minsizetile=min(tilewidth, tileheight); + int maxlev2=8; + if(minsizetile < 256) maxlev2 = 7; + if(minsizetile < 128) maxlev2 = 6; + if(minsizetile < 64) maxlev2 = 5; + levwav=min(maxlev2,levwav); + + // if (settings->verbose) printf("levwavelet=%i noisevarA=%f noisevarB=%f \n",levwav, noisevarab_r, noisevarab_b ); + Ldecomp = new wavelet_decomposition (labdn->L[0], labdn->W, labdn->H, levwav, 1, 1, max(1,denoiseNestedLevels)); + if(Ldecomp->memoryAllocationFailed) { + memoryAllocationFailed = true; + } + float madL[8][3]; + if(!memoryAllocationFailed) { + // precalculate madL, because it's used in adecomp and bdecomp + int maxlvl = Ldecomp->maxlevel(); +#ifdef _RT_NESTED_OPENMP +#pragma omp parallel for schedule(dynamic) collapse(2) num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) +#endif + for (int lvl=0; lvllevel_W(lvl); + int Hlvl_L = Ldecomp->level_H(lvl); + + float ** WavCoeffs_L = Ldecomp->level_coeffs(lvl); + + if(!denoiseMethodRgb) { + madL[lvl][dir-1] = SQR(Mad(WavCoeffs_L[dir], Wlvl_L*Hlvl_L)); + } else { + madL[lvl][dir-1] = SQR(MadRgb(WavCoeffs_L[dir], Wlvl_L*Hlvl_L)); + } + } + } + } + + float chresid = 0.f; + float chresidtemp=0.f; + float chmaxresid = 0.f; + float chmaxresidtemp = 0.f; + + adecomp = new wavelet_decomposition (labdn->a[0], labdn->W, labdn->H,levwav, 1, 1, max(1,denoiseNestedLevels)); + if(adecomp->memoryAllocationFailed) { + memoryAllocationFailed = true; + } + if(!memoryAllocationFailed) { + if(nrQuality==QUALITY_STANDARD) { + if(!WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, noisevarab_r, useNoiseCCurve, autoch, denoiseMethodRgb ))//enhance mode + memoryAllocationFailed = true; + } else /*if(nrQuality==QUALITY_HIGH)*/ { + if(!WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *adecomp, noisevarchrom, madL, noisevarab_r, useNoiseCCurve, autoch, denoiseMethodRgb ))//enhance mode + memoryAllocationFailed = true; + if(!memoryAllocationFailed) + if(!WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, noisevarab_r, useNoiseCCurve, autoch, denoiseMethodRgb )) + memoryAllocationFailed = true; + } + } + if(!memoryAllocationFailed) { + if(kall == 0) { + Noise_residualAB(*adecomp, chresid, chmaxresid, denoiseMethodRgb); + chresidtemp=chresid; + chmaxresidtemp= chmaxresid; + } + adecomp->reconstruct(labdn->a[0]); + } + delete adecomp; + if(!memoryAllocationFailed) { + wavelet_decomposition* bdecomp = new wavelet_decomposition (labdn->b[0], labdn->W, labdn->H, levwav, 1, 1, max(1,denoiseNestedLevels)); + if(bdecomp->memoryAllocationFailed) { + memoryAllocationFailed = true; + } + if(!memoryAllocationFailed) { + if(nrQuality==QUALITY_STANDARD) { + if(!WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, noisevarab_b, useNoiseCCurve, autoch, denoiseMethodRgb ))//enhance mode + memoryAllocationFailed = true; + } else /*if(nrQuality==QUALITY_HIGH)*/ { + if(!WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *bdecomp, noisevarchrom, madL, noisevarab_b, useNoiseCCurve, autoch, denoiseMethodRgb ))//enhance mode + memoryAllocationFailed = true; + if(!memoryAllocationFailed) + if(!WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, noisevarab_b, useNoiseCCurve, autoch, denoiseMethodRgb )) + memoryAllocationFailed = true; + } + } + if(!memoryAllocationFailed) { + if(kall == 0) { + Noise_residualAB(*bdecomp, chresid, chmaxresid, denoiseMethodRgb); + chresid += chresidtemp; + chmaxresid += chmaxresidtemp; + chresid = sqrt(chresid/(6*(levwav))); + highresi = chresid + 0.66f*(sqrt(chmaxresid) - chresid);//evaluate sigma + nresi = chresid; + } + bdecomp->reconstruct(labdn->b[0]); + } + delete bdecomp; + if(!memoryAllocationFailed) { + if(denoiseLuminance) { + int edge=0; + if(nrQuality==QUALITY_STANDARD) { + if(!WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL, NULL, edge))//enhance mode + memoryAllocationFailed = true; + } else /*if(nrQuality==QUALITY_HIGH)*/ { + if(!WaveletDenoiseAll_BiShrinkL(*Ldecomp, noisevarlum, madL))//enhance mode + memoryAllocationFailed = true; + if(!memoryAllocationFailed) + if(!WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL, NULL, edge)) + memoryAllocationFailed = true; + } + if(!memoryAllocationFailed) { + // copy labdn->L to Lin before it gets modified by reconstruction + Lin = new array2D(width,height); +#ifdef _RT_NESTED_OPENMP +#pragma omp parallel for num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) +#endif + for(int i=0;iL[i][j]; + + Ldecomp->reconstruct(labdn->L[0]); + } + } + } + } + delete Ldecomp; + } + + if(!memoryAllocationFailed) { + if( (metchoice==1 || metchoice==2 || metchoice==3 || metchoice==4) && dnparams.median) { + float** tmL; + int wid=labdn->W; + int hei=labdn->H; + tmL = new float*[hei]; + for (int i=0; iL, labdn->L, wid, hei, medianTypeL, dnparams.passes, denoiseNestedLevels, tmL); + if(metchoice==2 || metchoice==3 || metchoice==4) { + Median_Denoise( labdn->a, labdn->a, wid, hei, medianTypeAB, dnparams.passes, denoiseNestedLevels, tmL); + Median_Denoise( labdn->b, labdn->b, wid, hei, medianTypeAB, dnparams.passes, denoiseNestedLevels, tmL); + } + + for (int i=0; i Ldetail(width,height,ARRAY2D_CLEAR_DATA); + //pixel weight + array2D totwt(width,height,ARRAY2D_CLEAR_DATA);//weight for combining DCT blocks + if(numtiles == 1) + for(int i=0;i1) +#endif +{ +#ifdef _RT_NESTED_OPENMP + int subThread = masterThread * denoiseNestedLevels + omp_get_thread_num(); +#else + int subThread = 0; +#endif + float blurbuffer[TS*TS] ALIGNED64; + float *Lblox = LbloxArray[subThread]; + float *fLblox = fLbloxArray[subThread]; + float pBuf[width + TS + 2*blkrad*offset] ALIGNED16; + float nbrwt[TS*TS] ALIGNED64; +#ifdef _RT_NESTED_OPENMP +#pragma omp for +#endif + for (int vblk=0; vblk=height) { + rr = MAX(0,2*height-2-row); + } + + for (int j=0; jW; j++) { + datarow[j] = ((*Lin)[rr][j]-labdn->L[rr][j]); + } + + for (int j=-blkrad*offset; j<0; j++) { + datarow[j] = datarow[MIN(-j,width-1)]; + } + for (int j=width; j=0 && top+i1) +#endif + for (int i=0; iL[i][j] += Ldetail[i][j]/totwt[i][j]; //note that labdn initially stores the denoised hipass data + } + } + } + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // transform denoised "Lab" to output RGB + + //calculate mask for feathering output tile overlaps + float Vmask[height+1] ALIGNED16; + float Hmask[width+1] ALIGNED16; + float newGain; + if(numtiles > 1) { + for (int i=0; i0) Vmask[i] = mask; + if (tilebottom0) Hmask[i] = mask/newGain; + if (tilerightxyz + float L = labdn->L[i1][j1]; + float a = labdn->a[i1][j1]; + float b = labdn->b[i1][j1]; + float c_h=SQR(a)+SQR(b); + if(c_h>9000000.f){ + a *= 1.f + qhighFactor*realred; + b *= 1.f + qhighFactor*realblue; + } + //convert XYZ + float X,Y,Z; + Color::Lab2XYZ(L, a, b, X, Y, Z); + //apply inverse gamma noise + float r_,g_,b_; + Color::xyz2rgb(X,Y,Z,r_,g_,b_,wip); + //inverse gamma standard (slider) + r_ = r_<32768.f ? igamcurve[r_] : (Color::gammanf(r_/32768.f, igam) * 65535.f); + g_ = g_<32768.f ? igamcurve[g_] : (Color::gammanf(g_/32768.f, igam) * 65535.f); + b_ = b_<32768.f ? igamcurve[b_] : (Color::gammanf(b_/32768.f, igam) * 65535.f); + + //readapt arbitrary gamma (inverse from beginning) + r_ = (*denoisegamtab)[r_]; + g_ = (*denoisegamtab)[g_]; + b_ = (*denoisegamtab)[b_]; + + if(numtiles == 1) { + dsttmp->r(i,j) = newGain*r_; + dsttmp->g(i,j) = newGain*g_; + dsttmp->b(i,j) = newGain*b_; + } else { + float factor = Vmask[i1]*Hmask[j1]; + dsttmp->r(i,j) += factor*r_; + dsttmp->g(i,j) += factor*g_; + dsttmp->b(i,j) += factor*b_; + } + } + } + } else {//RGB mode +#ifdef _RT_NESTED_OPENMP +#pragma omp parallel for num_threads(denoiseNestedLevels) +#endif + for (int i=tiletop; ia[i1][j1])+SQR(labdn->b[i1][j1])); + if(c_h>3000.f){ + labdn->a[i1][j1]*=1.f + qhighFactor*realred/100.f; + labdn->b[i1][j1]*=1.f + qhighFactor*realblue/100.f; + } + float Y = labdn->L[i1][j1]; + float X = (labdn->a[i1][j1]) + Y; + float Z = Y - (labdn->b[i1][j1]); + + + X = X<32768.0f ? igamcurve[X] : (Color::gamma((float)X/32768.0f, igam, igamthresh, igamslope, 1.0, 0.0) * 65535.0f); + Y = Y<32768.0f ? igamcurve[Y] : (Color::gamma((float)Y/32768.0f, igam, igamthresh, igamslope, 1.0, 0.0) * 65535.0f); + Z = Z<32768.0f ? igamcurve[Z] : (Color::gamma((float)Z/32768.0f, igam, igamthresh, igamslope, 1.0, 0.0) * 65535.0f); + + if(numtiles == 1) { + dsttmp->r(i,j) = newGain*X; + dsttmp->g(i,j) = newGain*Y; + dsttmp->b(i,j) = newGain*Z; + } else { + float factor = Vmask[i1]*Hmask[j1]; + dsttmp->r(i,j) += factor*X; + dsttmp->g(i,j) += factor*Y; + dsttmp->b(i,j) += factor*Z; + } + } + } + + } + } else { +#ifdef _RT_NESTED_OPENMP +#pragma omp parallel for num_threads(denoiseNestedLevels) +#endif + for (int i=tiletop; iL[i1][j1]; + float a = labdn->a[i1][j1]; + float b = labdn->b[i1][j1]; + float c_h=sqrt(SQR(a)+SQR(b)); + if(c_h>3000.f){ + a*=1.f + qhighFactor*realred/100.f; + b*=1.f + qhighFactor*realblue/100.f; + } + + float X,Y,Z; + Color::Lab2XYZ(L, a, b, X, Y, Z); + + float r_,g_,b_; + Color::xyz2rgb(X,Y,Z,r_,g_,b_,wip); + //gamma slider is different from Raw + r_ = r_<32768.0f ? igamcurve[r_] : (Color::gamman((float)r_/32768.0f, igam) * 65535.0f); + g_ = g_<32768.0f ? igamcurve[g_] : (Color::gamman((float)g_/32768.0f, igam) * 65535.0f); + b_ = b_<32768.0f ? igamcurve[b_] : (Color::gamman((float)b_/32768.0f, igam) * 65535.0f); + + if(numtiles == 1) { + dsttmp->r(i,j) = newGain*r_; + dsttmp->g(i,j) = newGain*g_; + dsttmp->b(i,j) = newGain*b_; + } else { + float factor = Vmask[i1]*Hmask[j1]; + dsttmp->r(i,j) += factor*r_; + dsttmp->g(i,j) += factor*g_; + dsttmp->b(i,j) += factor*b_; + } + } + } + } + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + } + delete labdn; + if(denoiseLuminance) + delete Lin; + + }//end of tile row + }//end of tile loop + if(numtiles > 1 || !isRAW || (!useNoiseCCurve && !useNoiseLCurve)) { + delete [] noisevarlum; + delete [] noisevarchrom; + } + + } + if(denoiseLuminance) { + for(int i=0;i1) { + if(!memoryAllocationFailed) + dsttmp->copyData(dst); + else if(dst != src) + src->copyData(dst); + delete dsttmp; + } + if (!isRAW && !memoryAllocationFailed) {//restore original image gamma +#ifdef _OPENMP +#pragma omp parallel for +#endif + for(int i=0;iheight;i++) + for(int j=0;jwidth;j++) { + dst->r(i,j) = Color::gammatab_srgb[ dst->r(i,j) ]; + dst->g(i,j) = Color::gammatab_srgb[ dst->g(i,j) ]; + dst->b(i,j) = Color::gammatab_srgb[ dst->b(i,j) ]; + } + } + + if(denoiseLuminance) { + // destroy the plans + fftwf_destroy_plan( plan_forward_blox[0] ); + fftwf_destroy_plan( plan_backward_blox[0] ); + fftwf_destroy_plan( plan_forward_blox[1] ); + fftwf_destroy_plan( plan_backward_blox[1] ); + fftwf_cleanup(); + } +} while(memoryAllocationFailed && numTries < 2 && (options.rgbDenoiseThreadLimit == 0) && !ponder); +if(memoryAllocationFailed) + printf("tiled denoise failed due to isufficient memory. Output is not denoised!\n"); + +} + + +//median 3x3 in complement on RGB +if(dnparams.methodmed=="RGB" && dnparams.median) { +//printf("RGB den\n"); + int wid=dst->width, hei=dst->height; + float** tm; + tm = new float*[hei]; + for (int i=0; ir(i,j),source->r(i-1,j),source->r(i+1,j),source->r(i,j+1),source->r(i,j-1),tm[i][j]);//3x3 soft + } + else + for (int j=1; jr(i,j),source->r(i-1,j),source->r(i+1,j),source->r(i,j+1),source->r(i,j-1),source->r(i-1,j-1),source->r(i-1,j+1),source->r(i+1,j-1),source->r(i+1,j+1),tm[i][j]);//3x3 + } + } + } else { +#pragma omp for + for (int i=2; ir(i,j),source->r(i-1,j),source->r(i+1,j),source->r(i,j+1),source->r(i,j-1),source->r(i-1,j-1),source->r(i-1,j+1),source->r(i+1,j-1),source->r(i+1,j+1), + source->r(i-2,j),source->r(i+2,j),source->r(i,j+2),source->r(i,j-2),source->r(i-2,j-2),source->r(i-2,j+2),source->r(i+2,j-2),source->r(i+2,j+2), + source->r(i-2,j+1),source->r(i+2,j+1),source->r(i-1,j+2),source->r(i-1,j-2),source->r(i-2,j-1),source->r(i+2,j-1),source->r(i+1,j+2),source->r(i+1,j-2), + tm[i][j]);//5x5 + } + } else + for (int j=2; jr(i,j);pp[1]=source->r(i-1,j); pp[2]=source->r(i+1,j);pp[3]=source->r(i,j+1);pp[4]=source->r(i,j-1);pp[5]=source->r(i-1,j-1);pp[6]=source->r(i-1,j+1); + pp[7]=source->r(i+1,j-1);pp[8]=source->r(i+1,j+1);pp[9]=source->r(i+2,j);pp[10]=source->r(i-2,j);pp[11]=source->r(i,j+2);pp[12]=source->r(i,j-2); + fq_sort2(pp,13); + tm[i][j]=pp[6];//5x5 soft + } + } + } +#ifdef _OPENMP +#pragma omp for nowait +#endif + for(int i = border; i < hei-border; i++ ) { + for(int j = border; j < wid-border; j++) { + dst->r(i,j) = tm[i][j]; + } + } + + if(methmed < 2) { +#pragma omp for + for (int i=1; ib(i,j),source->b(i-1,j),source->b(i+1,j),source->b(i,j+1),source->b(i,j-1),tm[i][j]); + } + else + for (int j=1; jb(i,j),source->b(i-1,j),source->b(i+1,j),source->b(i,j+1),source->b(i,j-1),source->b(i-1,j-1),source->b(i-1,j+1),source->b(i+1,j-1),source->b(i+1,j+1),tm[i][j]); + } + } + } else { +#pragma omp for + for (int i=2; ib(i,j),source->b(i-1,j),source->b(i+1,j),source->b(i,j+1),source->b(i,j-1),source->b(i-1,j-1),source->b(i-1,j+1),source->b(i+1,j-1),source->b(i+1,j+1), + source->b(i-2,j),source->b(i+2,j),source->b(i,j+2),source->b(i,j-2),source->b(i-2,j-2),source->b(i-2,j+2),source->b(i+2,j-2),source->b(i+2,j+2), + source->b(i-2,j+1),source->b(i+2,j+1),source->b(i-1,j+2),source->b(i-1,j-2),source->b(i-2,j-1),source->b(i+2,j-1),source->b(i+1,j+2),source->b(i+1,j-2), + tm[i][j]);//5x5 + } + } else + for (int j=2; jb(i,j);pp[1]=source->b(i-1,j); pp[2]=source->b(i+1,j);pp[3]=source->b(i,j+1);pp[4]=source->b(i,j-1);pp[5]=source->b(i-1,j-1);pp[6]=source->b(i-1,j+1); + pp[7]=source->b(i+1,j-1);pp[8]=source->b(i+1,j+1);pp[9]=source->b(i+2,j);pp[10]=source->b(i-2,j);pp[11]=source->b(i,j+2);pp[12]=source->b(i,j-2); + fq_sort2(pp,13); + tm[i][j]=pp[6];//5x5 soft + } + } + } + +#ifdef _OPENMP +#pragma omp for nowait +#endif + for(int i = border; i < hei-border; i++ ) { + for(int j = border; j < wid-border; j++) { + dst->b(i,j) = tm[i][j]; + } + } + + + if(methmed < 2) { +#pragma omp for + for (int i=1; ig(i,j),source->g(i-1,j),source->g(i+1,j),source->g(i,j+1),source->g(i,j-1),tm[i][j]); + } + else + for (int j=1; jg(i,j),source->g(i-1,j),source->g(i+1,j),source->g(i,j+1),source->g(i,j-1),source->g(i-1,j-1),source->g(i-1,j+1),source->g(i+1,j-1),source->g(i+1,j+1),tm[i][j]); + } + } + } else { +#pragma omp for + for (int i=2; ig(i,j),source->g(i-1,j),source->g(i+1,j),source->g(i,j+1),source->g(i,j-1),source->g(i-1,j-1),source->g(i-1,j+1),source->g(i+1,j-1),source->g(i+1,j+1), + source->g(i-2,j),source->g(i+2,j),source->g(i,j+2),source->g(i,j-2),source->g(i-2,j-2),source->g(i-2,j+2),source->g(i+2,j-2),source->g(i+2,j+2), + source->g(i-2,j+1),source->g(i+2,j+1),source->g(i-1,j+2),source->g(i-1,j-2),source->g(i-2,j-1),source->g(i+2,j-1),source->g(i+1,j+2),source->g(i+1,j-2), + tm[i][j]);//5x5 + } + } else + for (int j=2; jg(i,j);pp[1]=source->g(i-1,j); pp[2]=source->g(i+1,j);pp[3]=source->g(i,j+1);pp[4]=source->g(i,j-1);pp[5]=source->g(i-1,j-1);pp[6]=source->g(i-1,j+1); + pp[7]=source->g(i+1,j-1);pp[8]=source->g(i+1,j+1);pp[9]=source->g(i+2,j);pp[10]=source->g(i-2,j);pp[11]=source->g(i,j+2);pp[12]=source->g(i,j-2); + fq_sort2(pp,13); + tm[i][j]=pp[6];//5x5 soft + } + } + } + +#ifdef _OPENMP +#pragma omp for +#endif + for(int i = border; i < hei-border; i++ ) { + for(int j = border; j < wid-border; j++) { + dst->g(i,j) = tm[i][j]; + } + } +} +} + for (int i=0; iverbose) { + t2e.set(); + printf("Denoise performed in %d usec:\n", t2e.etime(t1e)); + } +//#endif + +}//end of main RGB_denoise + + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +SSEFUNCTION void ImProcFunctions::RGBtile_denoise (float * fLblox, int hblproc, float noisevar_Ldetail, float * nbrwt, float * blurbuffer ) //for DCT + { + int blkstart = hblproc*TS*TS; + + boxabsblur(fLblox+blkstart, nbrwt, 3, 3, TS, TS, blurbuffer);//blur neighbor weights for more robust estimation //for DCT + +#ifdef __SSE2__ + __m128 tempv; + __m128 noisevar_Ldetailv = _mm_set1_ps( noisevar_Ldetail ); + __m128 onev = _mm_set1_ps( 1.0f ); + for (int n=0; nmaxresid ) maxresid=madC; + } + } + + chresid = resid; + chmaxresid = maxresid; +} + +SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3]) { + int maxlvl = min(WaveletCoeffs_L.maxlevel(),5); + const float eps = 0.01f; + + int maxWL = 0, maxHL = 0; + for (int lvl=0; lvl maxWL) + maxWL = WaveletCoeffs_L.level_W(lvl); + if(WaveletCoeffs_L.level_H(lvl) > maxHL) + maxHL = WaveletCoeffs_L.level_H(lvl); + } + bool memoryAllocationFailed = false; +#ifdef _RT_NESTED_OPENMP +#pragma omp parallel num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) +#endif +{ + float *buffer[3]; + buffer[0] = new (std::nothrow) float[maxWL*maxHL+32]; + buffer[1] = new (std::nothrow) float[maxWL*maxHL+64]; + buffer[2] = new (std::nothrow) float[maxWL*maxHL+96]; + if(buffer[0] == NULL || buffer[1] == NULL || buffer[2] == NULL) { + memoryAllocationFailed = true; + } + + if(!memoryAllocationFailed) { + +#ifdef _RT_NESTED_OPENMP +#pragma omp for schedule(dynamic) collapse(2) +#endif + for (int lvl=maxlvl-1; lvl>=0; lvl--) {//for levels less than max, use level diff to make edge mask + for (int dir=1; dir<4; dir++) { + int Wlvl_L = WaveletCoeffs_L.level_W(lvl); + int Hlvl_L = WaveletCoeffs_L.level_H(lvl); + + float ** WavCoeffs_L = WaveletCoeffs_L.level_coeffs(lvl); + if (lvl==maxlvl-1) { + float vari[3]; + int edge=0; + ShrinkAllL(WaveletCoeffs_L, buffer, lvl, dir, noisevarlum, madL[lvl], NULL, edge ); + } else { + //simple wavelet shrinkage + float * sfave = buffer[0]+32; + float * sfaved = buffer[2]+96; + float * blurBuffer = buffer[1]+64; + + float mad_Lr = madL[lvl][dir-1]; + + float levelFactor = mad_Lr*5.f/(lvl+1); +#ifdef __SSE2__ + __m128 mad_Lv; + __m128 ninev = _mm_set1_ps( 9.0f ); + __m128 epsv = _mm_set1_ps(eps); + __m128 mag_Lv; + __m128 levelFactorv = _mm_set1_ps(levelFactor); + int coeffloc_L; + for (coeffloc_L=0; coeffloc_L=0;i--) + if(buffer[i] != NULL) + delete [] buffer[i]; + +} + return (!memoryAllocationFailed); +} + +SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(wavelet_decomposition &WaveletCoeffs_L, wavelet_decomposition &WaveletCoeffs_ab, + float *noisevarchrom, float madL[8][3], float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb) + { + int maxlvl = WaveletCoeffs_L.maxlevel(); + if(autoch && noisevar_ab <=0.001f) noisevar_ab=0.02f; + + float madab[8][3]; + + int maxWL = 0, maxHL = 0; + for (int lvl=0; lvl maxWL) + maxWL = WaveletCoeffs_L.level_W(lvl); + if(WaveletCoeffs_L.level_H(lvl) > maxHL) + maxHL = WaveletCoeffs_L.level_H(lvl); + } + bool memoryAllocationFailed = false; +#ifdef _RT_NESTED_OPENMP +#pragma omp parallel num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) +#endif +{ + float *buffer[3]; + buffer[0] = new (std::nothrow) float[maxWL*maxHL+32]; + buffer[1] = new (std::nothrow) float[maxWL*maxHL+64]; + buffer[2] = new (std::nothrow) float[maxWL*maxHL+96]; + if(buffer[0] == NULL || buffer[1] == NULL || buffer[2] == NULL) { + memoryAllocationFailed = true; + } + + if(!memoryAllocationFailed) { + + +#ifdef _RT_NESTED_OPENMP +#pragma omp for schedule(dynamic) collapse(2) +#endif + for (int lvl=0; lvl=0; lvl--) {//for levels less than max, use level diff to make edge mask + for (int dir=1; dir<4; dir++) { + int Wlvl_ab = WaveletCoeffs_ab.level_W(lvl); + int Hlvl_ab = WaveletCoeffs_ab.level_H(lvl); + + float ** WavCoeffs_L = WaveletCoeffs_L.level_coeffs(lvl); + float ** WavCoeffs_ab = WaveletCoeffs_ab.level_coeffs(lvl); + if (lvl==maxlvl-1) { + ShrinkAllAB(WaveletCoeffs_L, WaveletCoeffs_ab, buffer, lvl, dir, noisevarchrom, noisevar_ab, useNoiseCCurve, autoch, denoiseMethodRgb, madL[lvl], madab[lvl], true); + } else { + //simple wavelet shrinkage + + float mad_Lr = madL[lvl][dir-1]; + float mad_abr = useNoiseCCurve ? noisevar_ab*madab[lvl][dir-1] : SQR(noisevar_ab)*madab[lvl][dir-1]; + + if (noisevar_ab>0.001f) { + +#ifdef __SSE2__ + __m128 onev = _mm_set1_ps(1.f); + __m128 mad_abrv = _mm_set1_ps(mad_abr); + __m128 rmad_Lm9v = onev / _mm_set1_ps(mad_Lr * 9.f); + __m128 mad_abv; + __m128 mag_Lv, mag_abv; + __m128 tempabv; + int coeffloc_ab; + for (coeffloc_ab=0; coeffloc_ab=0;i--) + if(buffer[i] != NULL) + delete [] buffer[i]; + +} + return (!memoryAllocationFailed); + } + + + bool ImProcFunctions::WaveletDenoiseAllL(wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3], float * vari, int edge)//mod JD + + { + + int maxlvl = min(WaveletCoeffs_L.maxlevel(),5); + if(edge==1) maxlvl=3;//for refine denoise edge wavelet + int maxWL = 0, maxHL = 0; + for (int lvl=0; lvl maxWL) + maxWL = WaveletCoeffs_L.level_W(lvl); + if(WaveletCoeffs_L.level_H(lvl) > maxHL) + maxHL = WaveletCoeffs_L.level_H(lvl); + } + bool memoryAllocationFailed = false; +#ifdef _RT_NESTED_OPENMP +#pragma omp parallel num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) +#endif +{ + float *buffer[3]; + buffer[0] = new (std::nothrow) float[maxWL*maxHL+32]; + buffer[1] = new (std::nothrow) float[maxWL*maxHL+64]; + buffer[2] = new (std::nothrow) float[maxWL*maxHL+96]; + if(buffer[0] == NULL || buffer[1] == NULL || buffer[2] == NULL) { + memoryAllocationFailed = true; + } + + if(!memoryAllocationFailed) { +#ifdef _RT_NESTED_OPENMP +#pragma omp for schedule(dynamic) collapse(2) +#endif + for (int lvl=0; lvl=0;i--) + if(buffer[i] != NULL) + delete [] buffer[i]; +} + return (!memoryAllocationFailed); + } + + + bool ImProcFunctions::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)//mod JD + + { + + int maxlvl = WaveletCoeffs_L.maxlevel(); + int maxWL = 0, maxHL = 0; + for (int lvl=0; lvl maxWL) + maxWL = WaveletCoeffs_L.level_W(lvl); + if(WaveletCoeffs_L.level_H(lvl) > maxHL) + maxHL = WaveletCoeffs_L.level_H(lvl); + } + bool memoryAllocationFailed = false; +#ifdef _RT_NESTED_OPENMP +#pragma omp parallel num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) +#endif +{ + float *buffer[3]; + buffer[0] = new (std::nothrow) float[maxWL*maxHL+32]; + buffer[1] = new (std::nothrow) float[maxWL*maxHL+64]; + buffer[2] = new (std::nothrow) float[maxWL*maxHL+96]; + if(buffer[0] == NULL || buffer[1] == NULL || buffer[2] == NULL) { + memoryAllocationFailed = true; + } + + if(!memoryAllocationFailed) { +#ifdef _RT_NESTED_OPENMP +#pragma omp for schedule(dynamic) collapse(2) +#endif + for (int lvl=0; lvl=0;i--) + if(buffer[i] != NULL) + delete [] buffer[i]; +} + return (!memoryAllocationFailed); + } + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +SSEFUNCTION void ImProcFunctions::ShrinkAllL(wavelet_decomposition &WaveletCoeffs_L, float **buffer, int level, int dir, + float *noisevarlum, float * madL, float * vari, int edge ) + + { + //simple wavelet shrinkage + const float eps = 0.01f; + + float * sfave = buffer[0]+32; + float * sfaved = buffer[1]+64; + float * blurBuffer = buffer[2]+96; + + int W_L = WaveletCoeffs_L.level_W(level); + int H_L = WaveletCoeffs_L.level_H(level); + + float ** WavCoeffs_L = WaveletCoeffs_L.level_coeffs(level); + + float mad_L = madL[dir-1] ; + if(edge==1) { + noisevarlum = blurBuffer; // we need one buffer, but fortunately we don't have to allocate a new one because we can use blurBuffer + for (int i=0; i0.001f) { + madab = useNoiseCCurve ? madab : madab * noisevar_ab; +#ifdef __SSE2__ + __m128 onev = _mm_set1_ps(1.f); + __m128 mad_abrv = _mm_set1_ps(madab); + + __m128 rmadLm9v = onev / _mm_set1_ps(mad_L * 9.f); + __m128 mad_abv ; + __m128 mag_Lv, mag_abv; + int coeffloc_ab; + for (coeffloc_ab=0; coeffloc_ab -0.8f && noisevarhue[i][j] < 2.0f && noisevarchrom[i][j] > 10000.f) {//saturated red yellow + red_yel += noisevarchrom[i][j]; + nry++; + } + if(noisevarhue[i][j] > 0.f && noisevarhue[i][j] < 1.6f && noisevarchrom[i][j] < 10000.f) {//skin + skin_c += noisevarchrom[i][j]; + nsk++; + } + lume += noisevarlum[i][j]; + nL++; + devL += SQR(noisevarlum[i][j]-(lume/nL)); + } + } + if(nc>0) { + chromina=chro/nc; + sigma=sqrt(dev/nc); + nsknc=(float)nsk/(float)nc; + } else { + nsknc=(float)nsk; + } + if(nL>0) { + lumema=lume/nL; + sigma_L=sqrt(devL/nL); + } + if(nry>0) + redyel=red_yel/nry; + if(nsk>0) + skinc=skin_c/nsk; + } + + const float reduc = (schoice == 2) ? (float) settings->nrhigh : 1.f; + for (int dir=1; dir<4; dir++) { + float mada, madb; + if(!denoiseMethodRgb) + mada = SQR(Mad(WavCoeffs_a[dir], W_ab*H_ab)); + else + mada = SQR(MadRgb(WavCoeffs_a[dir], W_ab*H_ab)); + chred += mada; + if(mada > maxchred) + maxchred = mada; + if(mada < minchred) + minchred = mada; + maxredaut = sqrt(reduc*maxchred); + minredaut = sqrt(reduc*minchred); + + if(!denoiseMethodRgb) + madb = SQR(Mad(WavCoeffs_b[dir], W_ab*H_ab)); + else + madb = SQR(MadRgb(WavCoeffs_b[dir], W_ab*H_ab)); + chblue += madb; + if(madb > maxchblue) + maxchblue = madb; + if(madb < minchblue) + minchblue = madb; + maxblueaut = sqrt(reduc*maxchblue); + minblueaut = sqrt(reduc*minchblue); + + chau += (mada+madb); + nb++; + //here evaluation of automatic + chaut = sqrt(reduc*chau/(nb + nb)); + redaut = sqrt(reduc*chred/nb); + blueaut = sqrt(reduc*chblue/nb); + Nb = nb; + } + +} + + +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 ){ + + int maxlvl = levwav; + for (int lvl=0; lvl TIF and JPG + if(gam <1.9f) + gam=1.f - (1.9f-gam)/3.f;//minimum gamma 0.7 + else if (gam >= 1.9f && gam <= 3.f) + gam=(1.4f/1.1f)*gam - 1.41818f; + } + gamslope = exp(log((double)gamthresh)/gam)/gamthresh; + bool denoiseMethodRgb = (dnparams.dmethod=="RGB"); + if(denoiseMethodRgb) { + for (int i=0; i<65536; i++) { + gamcurve[i] = (Color::gamma((double)i/65535.0, gam, gamthresh, gamslope, 1.0, 0.0)) * 32768.0f; + } + } + else { + for (int i=0; i<65536; i++) { + gamcurve[i] = (Color::gamman((double)i/65535.0,gam)) * 32768.0f; + } + } +} + +void ImProcFunctions::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 reducdelta=1.f; + if (params->dirpyrDenoise.smethod == "shalbi") + reducdelta = (float)settings->nrhigh; + + chaut = (chaut*Nb-maxmax)/(Nb-1);//suppress maximum for chaut calcul + if ((redyel > 5000.f || skinc > 1000.f) && nsknc < 0.4f && chromina > 3000.f) + chaut *= 0.45f;//reduct action in red zone, except skin for high / med chroma + else if ((redyel>12000.f || skinc > 1200.f) && nsknc < 0.3f && chromina > 3000.f) + chaut *= 0.3f; + + if (mode==0 || mode==2) {//Preview or Auto multizone + if (chromina > 10000.f) chaut *= 0.7f;//decrease action for high chroma (visible noise) + else if (chromina > 6000.f) chaut *= 0.9f; + else if (chromina < 3000.f) chaut *= 1.2f;//increase action in low chroma==> 1.2 /==>2.0 ==> curve CC + else if (chromina < 2000.f) chaut *= 1.5f;//increase action in low chroma==> 1.5 / ==>2.7 + + if (lumema < 2500.f) chaut *= 1.3f;//increase action for low light + else if (lumema < 5000.f) chaut *= 1.2f; + else if (lumema > 20000.f) chaut *= 0.9f;//decrease for high light + } else if (mode == 1) {//auto ==> less coefficient because interaction + if (chromina > 10000.f) chaut *= 0.8f;//decrease action for high chroma (visible noise) + else if (chromina > 6000.f) chaut *= 0.9f; + else if (chromina < 3000.f) chaut *= 1.5f;//increase action in low chroma + else if (chromina < 2000.f) chaut *= 2.2f;//increase action in low chroma + if (lumema < 2500.f) chaut *= 1.2f;//increase action for low light + else if (lumema < 5000.f) chaut *= 1.1f; + else if (lumema > 20000.f) chaut *= 0.9f;//decrease for high light + } + + if(levaut==0) {//Low denoise + if(chaut > 300.f) + chaut = 0.714286f*chaut + 85.71428f; + } + + delta = maxmax-chaut; + delta *= reducdelta; + + if (lissage==1 || lissage==2) { + if (chaut < 200.f && delta < 200.f ) delta *= 0.95f; + else if (chaut < 200.f && delta < 400.f ) delta *= 0.5f; + else if (chaut < 200.f && delta >= 400.f ) delta = 200.f; + else if (chaut < 400.f && delta < 400.f ) delta *= 0.4f; + else if (chaut < 400.f && delta >= 400.f ) delta = 120.f; + else if (chaut < 550.f) delta *= 0.15f; + else if (chaut < 650.f) delta *= 0.1f; + else if (chaut >= 650.f) delta *= 0.07f; + if (mode==0 || mode==2) {//Preview or Auto multizone + if (chromina < 6000.f) delta *= 1.4f;//increase maxi + if (lumema < 5000.f) delta *= 1.4f; + } + else if (mode==1) {//Auto + if (chromina < 6000.f) delta *= 1.2f;//increase maxi + if (lumema < 5000.f) delta *= 1.2f; + } + } + if (lissage==0) { + if (chaut < 200.f && delta < 200.f ) delta *= 0.95f; + else if (chaut < 200.f && delta < 400.f ) delta *= 0.7f; + else if (chaut < 200.f && delta >= 400.f ) delta = 280.f; + else if (chaut < 400.f && delta < 400.f ) delta *= 0.6f; + else if (chaut < 400.f && delta >= 400.f ) delta = 200.f; + else if (chaut < 550.f) delta *= 0.3f; + else if (chaut < 650.f) delta *= 0.2f; + else if (chaut >= 650.f) delta *= 0.15f; + if (mode==0 || mode==2) {//Preview or Auto multizone + if (chromina < 6000.f) delta *= 1.4f;//increase maxi + if (lumema < 5000.f) delta *= 1.4f; + } + else if (mode==1) {//Auto + if (chromina < 6000.f) delta *= 1.2f;//increase maxi + if (lumema < 5000.f) delta *= 1.2f; + } + } + +} + +SSEFUNCTION void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat * provicalc, const 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 &nresi, float &highresi, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc, bool multiThread) +{ + if ((settings->leveldnautsimpl==1 && dnparams.Cmethod == "MAN") || (settings->leveldnautsimpl==0 && dnparams.C2method == "MANU")) { + //nothing to do + return; + } + + int hei,wid; + float** lumcalc; + float** acalc; + float** bcalc; + hei=provicalc->height; + wid=provicalc->width; + TMatrix wprofi = iccStore->workingSpaceMatrix (params->icm.working); + + const float wpi[3][3] = { + {static_cast(wprofi[0][0]),static_cast(wprofi[0][1]),static_cast(wprofi[0][2])}, + {static_cast(wprofi[1][0]),static_cast(wprofi[1][1]),static_cast(wprofi[1][2])}, + {static_cast(wprofi[2][0]),static_cast(wprofi[2][1]),static_cast(wprofi[2][2])} + }; + + lumcalc = new float*[hei]; + for (int i=0; ir(ii,jj); + float GL = provicalc->g(ii,jj); + float BL = provicalc->b(ii,jj); + // determine luminance for noisecurve + float XL,YL,ZL; + Color::rgbxyz(RL,GL,BL,XL,YL,ZL,wpi); + Color::XYZ2Lab(XL, YL, ZL, LLum, AAum, BBum); + lumcalc[ii][jj]=LLum; + acalc[ii][jj]=AAum; + bcalc[ii][jj]=BBum; + } + } + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + const int imheight=src->height, imwidth=src->width; + + bool denoiseMethodRgb = (dnparams.dmethod == "RGB"); + + const float gain = pow (2.0f, float(expcomp)); + + int tilesize; + int overlap; + if(settings->leveldnti == 0) { + tilesize = 1024; + overlap = 128; + } + if(settings->leveldnti == 1) { + tilesize = 768; + overlap = 96; + } + + int numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip; + + //always no Tiles + int kall=0; + Tile_calc (tilesize, overlap, kall, imwidth, imheight, numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip); + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + TMatrix wprof = iccStore->workingSpaceMatrix (params->icm.working); + const float wp[3][3] = { + {static_cast(wprof[0][0]),static_cast(wprof[0][1]),static_cast(wprof[0][2])}, + {static_cast(wprof[1][0]),static_cast(wprof[1][1]),static_cast(wprof[1][2])}, + {static_cast(wprof[2][0]),static_cast(wprof[2][1]),static_cast(wprof[2][2])} + }; + + float chau=0.f; + float chred=0.f; + float chblue=0.f; + float maxchred=0.f; + float maxchblue=0.f; + float minchred =100000000.f; + float minchblue=100000000.f; + int nb=0; + int comptlevel=0; + + // To avoid branches in loops we access the gammatabs by pointers + LUTf *denoiseigamtab; + switch(settings->denoiselabgamma) { + case 0: denoiseigamtab = &(Color::igammatab_26_11); + break; + case 1: denoiseigamtab = &(Color::igammatab_4); + break; + default: denoiseigamtab = &(Color::igammatab_55); + break; + } + + + for (int tiletop=0; tiletop 0.) + intermred = (dnparams.redchro/10.); + else + intermred = (float) dnparams.redchro/7.0;//increase slower than linear for more sensit + if(dnparams.bluechro > 0.) + intermblue =(dnparams.bluechro/10.); + else + intermblue = (float) dnparams.bluechro/7.0;//increase slower than linear for more sensit + realred = interm_med + intermred; + if (realred < 0.f) + realred = 0.001f; + realblue = interm_med + intermblue; + if (realblue < 0.f) + 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 +#ifdef _RT_NESTED_OPENMP +#pragma omp parallel for if(multiThread) +#endif + for (int i=tiletop; i>1][j>>1]); + bNv = LVFU(bcalc[i>>1][j>>1]); + _mm_storeu_ps(&noisevarhue[i1>>1][j1>>1], xatan2f(bNv,aNv)); + _mm_storeu_ps(&noisevarchrom[i1>>1][j1>>1], _mm_max_ps(c100v,_mm_sqrt_ps(SQRV(aNv)+SQRV(bNv)))); + } + for (; j>1][j>>1]; + float bN = bcalc[i>>1][j>>1]; + float cN = sqrtf(SQR(aN)+SQR(bN)); + noisevarhue[i1>>1][j1>>1] = xatan2f(bN,aN); + if(cN < 100.f) + cN=100.f;//avoid divided by zero + noisevarchrom[i1>>1][j1>>1] = cN; + } +#else + for (int j=tileleft; j>1][j>>1]; + float bN = bcalc[i>>1][j>>1]; + float cN = sqrtf(SQR(aN)+SQR(bN)); + float hN = xatan2f(bN,aN); + if(cN < 100.f) + cN = 100.f;//avoid divided by zero + noisevarchrom[i1>>1][j1>>1] = cN; + noisevarhue[i1>>1][j1>>1] = hN; + } +#endif + } +#ifdef _RT_NESTED_OPENMP +#pragma omp parallel for if(multiThread) +#endif + for (int i=tiletop; i>1][j>>1]; + Llum = Llum < 2.f ? 2.f : Llum; //avoid divided by zero ? + Llum = Llum > 32768.f ? 32768.f : Llum; // not strictly necessary + noisevarlum[i1>>1][j1>>1]= Llum; + } + } + if (!denoiseMethodRgb){//lab mode, modification Jacques feb 2013 and july 2014 + +#ifdef _RT_NESTED_OPENMP +#pragma omp parallel for if(multiThread) +#endif + for (int i=tiletop; ir(i,j); + float G_ = gain*src->g(i,j); + float B_ = gain*src->b(i,j); + + R_ = (*denoiseigamtab)[R_]; + G_ = (*denoiseigamtab)[G_]; + B_ = (*denoiseigamtab)[B_]; + + //apply gamma noise standard (slider) + R_ = R_<65535.0f ? gamcurve[R_] : (Color::gamman((double)R_/65535.0, gam)*32768.0f); + G_ = G_<65535.0f ? gamcurve[G_] : (Color::gamman((double)G_/65535.0, gam)*32768.0f); + B_ = B_<65535.0f ? gamcurve[B_] : (Color::gamman((double)B_/65535.0, gam)*32768.0f); + //true conversion xyz=>Lab + float X,Y,Z; + Color::rgbxyz(R_,G_,B_,X,Y,Z,wp); + + //convert to Lab + float L,a,b; + Color::XYZ2Lab(X, Y, Z, L, a, b); + + labdn->a[i1][j1] = a; + labdn->b[i1][j1] = b; + } + } + } + else {//RGB mode + + for (int i=tiletop/*, i1=0*/; ir(i,j); + float Y = gain*src->g(i,j); + float Z = gain*src->b(i,j); + + X = X<65535.0f ? gamcurve[X] : (Color::gamma((double)X/65535.0, gam, gamthresh, gamslope, 1.0, 0.0)*32768.0f); + Y = Y<65535.0f ? gamcurve[Y] : (Color::gamma((double)Y/65535.0, gam, gamthresh, gamslope, 1.0, 0.0)*32768.0f); + Z = Z<65535.0f ? gamcurve[Z] : (Color::gamma((double)Z/65535.0, gam, gamthresh, gamslope, 1.0, 0.0)*32768.0f); + + labdn->a[i1][j1] = (X-Y); + labdn->b[i1][j1] = (Y-Z); + } + } + } + + } else {//image is not raw; use Lab parametrization + for (int i=tiletop/*, i1=0*/; ir(i,j) ;//for luminance denoise curve + float gLum=src->g(i,j) ; + float bLum=src->b(i,j) ; + + //use gamma sRGB, not good if TIF (JPG) Output profil not with gamma sRGB (eg : gamma =1.0, or 1.8...) + //very difficult to solve ! + // solution ==> save TIF with gamma sRGB and re open + float rtmp = Color::igammatab_srgb[ src->r(i,j) ]; + float gtmp = Color::igammatab_srgb[ src->g(i,j) ]; + float btmp = Color::igammatab_srgb[ src->b(i,j) ]; + //modification Jacques feb 2013 + // gamma slider different from raw + rtmp = rtmp<65535.0f ? gamcurve[rtmp] : (Color::gamman((double)rtmp/65535.0, gam)*32768.0f); + gtmp = gtmp<65535.0f ? gamcurve[gtmp] : (Color::gamman((double)gtmp/65535.0, gam)*32768.0f); + btmp = btmp<65535.0f ? gamcurve[btmp] : (Color::gamman((double)btmp/65535.0, gam)*32768.0f); + + float X,Y,Z; + Color::rgbxyz(rtmp,gtmp,btmp,X,Y,Z,wp); + + //convert Lab + Color::XYZ2Lab(X, Y, Z, L, a, b); + + if(((i1|j1)&1) == 0) { + float Llum,alum,blum; + float XL,YL,ZL; + Color::rgbxyz(rLum,gLum,bLum,XL,YL,ZL,wp); + Color::XYZ2Lab(XL, YL, ZL, Llum, alum, blum); + float kN=Llum; + if(kN<2.f) kN=2.f; + if(kN>32768.f) kN=32768.f; + noisevarlum[i1>>1][j1>>1]=kN; + float aN=alum; + float bN=blum; + float hN=xatan2f(bN,aN); + float cN=sqrt(SQR(aN)+SQR(bN)); + if(cN < 100.f) cN=100.f;//avoid divided by zero + noisevarchrom[i1>>1][j1>>1]=cN; + noisevarhue[i1>>1][j1>>1]=hN; + } + labdn->a[i1][j1] = a; + labdn->b[i1][j1] = b; + } + } + } + int datalen = labdn->W * labdn->H; + + //now perform basic wavelet denoise + //last two arguments of wavelet decomposition are max number of wavelet decomposition levels; + //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; + + int schoice = 0;//shrink method + if (dnparams.smethod == "shalbi") + schoice=2; + + const int levwav=5; +#ifdef _RT_NESTED_OPENMP +#pragma omp parallel sections if(multiThread) +#endif +{ +#ifdef _RT_NESTED_OPENMP +#pragma omp section +#endif +{ + adecomp = new wavelet_decomposition (labdn->data+datalen, labdn->W, labdn->H, levwav, 1 ); +} +#ifdef _RT_NESTED_OPENMP +#pragma omp section +#endif +{ + bdecomp = new wavelet_decomposition (labdn->data+2*datalen, labdn->W, labdn->H, levwav, 1 ); +} +} + bool autoch = dnparams.autochroma; + if(comptlevel==0) WaveletDenoiseAll_info(levwav, *adecomp, *bdecomp, noisevarlum, noisevarchrom, noisevarhue, width, height, noisevarab_r, noisevarab_b, labdn, chaut, Nb, redaut, blueaut, maxredaut, maxblueaut, minredaut, minblueaut, schoice, autoch, chromina, sigma, lumema, sigma_L, redyel, skinc, nsknc,maxchred, maxchblue, minchred, minchblue, nb,chau ,chred, chblue, denoiseMethodRgb, multiThread);//enhance mode + comptlevel+=1; + float chresid,chmaxredresid,chmaxblueresid; + nresi=chresid; + highresi=chresid + 0.66f*(max(chmaxredresid,chmaxblueresid) - chresid);//evaluate sigma + delete adecomp; + delete bdecomp; + delete labdn; + for (int i=0; i<(height+1)/2; i++) + delete [] noisevarlum[i]; + delete [] noisevarlum; + for (int i=0; i<(height+1)/2; i++) + delete [] noisevarchrom[i]; + delete [] noisevarchrom; + for (int i=0; i<(height+1)/2; i++) + delete [] noisevarhue[i]; + delete [] noisevarhue; + + }//end of tile row + }//end of tile loop + + for (int i=0; i. + */ + +/* + * Declaration of flexible Lookup Tables + * + * Usage: + * + * LUT name (size); + * LUT name (size, flags); + * + * creates an array which is valid within the normal C/C++ scope "{ ... }" + * + * access to elements is a simple as: + * + * LUT my_lut (10); + * float value = my_lut[3]; + * float value = my_lut[2.5]; // this will interpolate + * + * when using a float type index it will interpolate the lookup values + * + * extra setting in flags: (clipping is set by default) + * LUT_CLIP_ABOVE + * LUT_CLIP_BELOW + * + * example: + * LUT my_lut (10,LUT_CLIP_BELOW); + * float value = my_lut[22.5]; // this will extrapolate + * float value = my_lut[-22.5]; // this will not extrapolate + * + * LUT my_lut (10,0); // this will extrapolate on either side + * + * shotcuts: + * + * LUTf stands for LUT + * LUTi stands for LUT + * LUTu stands for LUT + */ + +#ifndef LUT_H_ +#define LUT_H_ + +// bit representations of flags +#define LUT_CLIP_BELOW 1 +#define LUT_CLIP_ABOVE 2 + +#define LUTf LUT +#define LUTi LUT +#define LUTu LUT +#define LUTd LUT + +#include +#ifndef NDEBUG +#include +#include +#endif +#ifdef __SSE2__ +#include "sleefsseavx.c" +#endif +#include +#include "rt_math.h" + +template +class LUT { +protected: + // list of variables ordered to improve cache speed + unsigned int maxs; + float maxsf; + T * data; + unsigned int clip; + unsigned int size; + unsigned int upperBound; // always equals size-1, parameter created for performance reason +private: + unsigned int owner; +#if defined( __SSE2__ ) && defined( __x86_64__ ) + __m128 maxsv __attribute__ ((aligned (16))); + __m128 sizev __attribute__ ((aligned (16))); + __m128i maxsiv __attribute__ ((aligned (16))); + __m128i sizeiv __attribute__ ((aligned (16))); +#endif +public: + /// convenience flag! If one doesn't want to delete the buffer but want to flag it to be recomputed... + /// The user have to handle it itself, even if some method can (re)initialize it + bool dirty; + + LUT(int s, int flags = 0xfffffff) { + #ifndef NDEBUG + if (s<=0) + printf("s<=0!\n"); + assert (s>0); + #endif + dirty = true; + clip = flags; + data = new T[s]; + owner = 1; + size = s; + upperBound = size-1; + maxs=size-2; + maxsf = (float)maxs; +#if defined( __SSE2__ ) && defined( __x86_64__ ) + maxsv = _mm_set1_ps( maxs ); + maxsiv = _mm_cvttps_epi32( maxsv ); + sizeiv = _mm_set1_epi32( (int)(size-1) ); + sizev = _mm_set1_ps( size-1 ); +#endif + } + void operator ()(int s, int flags = 0xfffffff) { + #ifndef NDEBUG + if (s<=0) + printf("s<=0!\n"); + assert (s>0); + #endif + if (owner&&data) + delete[] data; + dirty = true; // Assumption! + clip = flags; + data = new T[s]; + owner = 1; + size = s; + upperBound = size-1; + maxs=size-2; + maxsf = (float)maxs; +#if defined( __SSE2__ ) && defined( __x86_64__ ) + maxsv = _mm_set1_ps( maxs ); + maxsiv = _mm_cvttps_epi32( maxsv ); + sizeiv = _mm_set1_epi32( (int)(size-1) ); + sizev = _mm_set1_ps( size-1 ); +#endif + } + + LUT(int s, T * source, int flags = 0xfffffff) { + #ifndef NDEBUG + if (s<=0) + printf("s<=0!\n"); + assert (s>0); + if (source==NULL) + printf("source is NULL!\n"); + assert (source != NULL); + #endif + dirty = false; // Assumption + clip = flags; + data = new T[s]; + owner = 1; + size = s; + upperBound = size-1; + maxs=size-2; + maxsf = (float)maxs; +#if defined( __SSE2__ ) && defined( __x86_64__ ) + maxsv = _mm_set1_ps( size - 2); + maxsiv = _mm_cvttps_epi32( maxsv ); + sizeiv = _mm_set1_epi32( (int)(size-1) ); + sizev = _mm_set1_ps( size-1 ); +#endif + for (int i = 0; i < s; i++) { + data[i] = source[i]; + } + } + + LUT() { + data = NULL; + reset(); + } + + ~LUT() { + if (owner) { + delete[] data; + #ifndef NDEBUG + data=(T*)0xBAADF00D; + #endif + } + } + + void setClip(int flags) { + clip = flags; + } + + /** @brief Get the number of element in the LUT (i.e. dimension of the array) + * For a LUT(500), it will return 500 + * @return number of element in the array + */ + int getSize() { + return size; + } + + /** @brief Get the highest value possible (i.e. dimension of the array) + * For a LUT(500), it will return 499, because 500 elements, starting from 0, goes up to 499 + * @return number of element in the array + */ + int getUpperBound() { + return size>0 ? upperBound : 0; + } + + LUT & operator=(LUT &rhs) { + if (this != &rhs) { + if (rhs.size>this->size) + { + delete [] this->data; + this->data=NULL; + } + if (this->data==NULL) this->data=new T[rhs.size]; + this->clip=rhs.clip; + this->owner=1; + memcpy(this->data,rhs.data,rhs.size*sizeof(T)); + this->size=rhs.size; + this->upperBound=rhs.upperBound; + this->maxs=this->size-2; + this->maxsf = (float)this->maxs; +#if defined( __SSE2__ ) && defined( __x86_64__ ) + this->maxsv = _mm_set1_ps( this->size - 2); + this->maxsiv = _mm_cvttps_epi32( this->maxsv ); + this->sizeiv = _mm_set1_epi32( (int)(this->size-1) ); + this->sizev = _mm_set1_ps( this->size-1 ); +#endif + } + + return *this; + } + // use with integer indices + T& operator[](int index) const { + return data[ rtengine::LIM(index, 0, upperBound) ]; + } + +#if defined( __SSE2__ ) && defined( __x86_64__ ) + __m128 operator[](__m128 indexv ) const { +// printf("don't use this operator. It's not ready for production"); + return _mm_setzero_ps(); + + // convert floats to ints + __m128i idxv = _mm_cvttps_epi32( indexv ); + __m128 tempv, resultv, p1v, p2v; + vmask maxmask = vmaskf_gt(indexv, maxsv); + idxv = _mm_castps_si128(vself(maxmask, maxsv, _mm_castsi128_ps(idxv))); + vmask minmask = vmaskf_lt(indexv, _mm_setzero_ps()); + idxv = _mm_castps_si128(vself(minmask, _mm_setzero_ps(), _mm_castsi128_ps(idxv))); + // access the LUT 4 times and shuffle the values into p1v and p2v + + int idx; + + // get 4th value + idx = _mm_cvtsi128_si32 (_mm_shuffle_epi32(idxv,_MM_SHUFFLE(3,3,3,3))); + tempv = LVFU(data[idx]); + p1v = _mm_shuffle_ps(tempv, tempv, _MM_SHUFFLE(0,0,0,0)); + p2v = _mm_shuffle_ps(tempv, tempv, _MM_SHUFFLE(1,1,1,1)); + // now p1v is 3 3 3 3 + // p2v is 3 3 3 3 + + // get 3rd value + idx = _mm_cvtsi128_si32 (_mm_shuffle_epi32(idxv,_MM_SHUFFLE(2,2,2,2))); + tempv = LVFU(data[idx]); + p1v = _mm_move_ss( p1v, tempv); + tempv = _mm_shuffle_ps(tempv, tempv, _MM_SHUFFLE(1,1,1,1)); + p2v = _mm_move_ss( p2v, tempv); + // now p1v is 3 3 3 2 + // p2v is 3 3 3 2 + + // get 2nd value + idx = _mm_cvtsi128_si32 (_mm_shuffle_epi32(idxv,_MM_SHUFFLE(1,1,1,1))); + tempv = LVFU(data[idx]); + p1v = _mm_shuffle_ps( p1v, p1v, _MM_SHUFFLE(1,0,1,0)); + p2v = _mm_shuffle_ps( p2v, p2v, _MM_SHUFFLE(1,0,1,0)); + // now p1v is 3 2 3 2 + // now p2v is 3 2 3 2 + p1v = _mm_move_ss( p1v, tempv ); + // now p1v is 3 2 3 1 + tempv = _mm_shuffle_ps(tempv, tempv, _MM_SHUFFLE(1,1,1,1)); + p2v = _mm_move_ss( p2v, tempv); + // now p1v is 3 2 3 1 + + // get 1st value + idx = _mm_cvtsi128_si32 (_mm_shuffle_epi32(idxv,_MM_SHUFFLE(0,0,0,0))); + tempv = LVFU(data[idx]); + p1v = _mm_shuffle_ps( p1v, p1v, _MM_SHUFFLE(3,2,0,0)); + // now p1v is 3 2 1 1 + p2v = _mm_shuffle_ps( p2v, p2v, _MM_SHUFFLE(3,2,0,0)); + // now p2v is 3 2 1 1 + p1v = _mm_move_ss( p1v, tempv ); + // now p1v is 3 2 1 0 + tempv = _mm_shuffle_ps(tempv, tempv, _MM_SHUFFLE(1,1,1,1)); + p2v = _mm_move_ss( p2v, tempv); + // now p2v is 3 2 1 0 + + __m128 diffv = indexv - _mm_cvtepi32_ps ( idxv ); + diffv = vself(vorm(maxmask,minmask), _mm_setzero_ps(), diffv); + resultv = p1v + p2v * diffv; + return resultv ; + } + + __m128 operator[](__m128i idxv ) const + { + __m128 tempv, p1v; + tempv = _mm_cvtepi32_ps(idxv); + tempv = _mm_min_ps( tempv, sizev ); + idxv = _mm_cvttps_epi32(_mm_max_ps( tempv, _mm_setzero_ps( ) )); + // access the LUT 4 times and shuffle the values into p1v + + int idx; + + // get 4th value + idx = _mm_cvtsi128_si32 (_mm_shuffle_epi32(idxv,_MM_SHUFFLE(3,3,3,3))); + tempv = _mm_load_ss(&data[idx]); + p1v = _mm_shuffle_ps(tempv, tempv, _MM_SHUFFLE(0,0,0,0)); + // now p1v is 3 3 3 3 + + // get 3rd value + idx = _mm_cvtsi128_si32 (_mm_shuffle_epi32(idxv,_MM_SHUFFLE(2,2,2,2))); + tempv = _mm_load_ss(&data[idx]); + p1v = _mm_move_ss( p1v, tempv); + // now p1v is 3 3 3 2 + + // get 2nd value + idx = _mm_cvtsi128_si32 (_mm_shuffle_epi32(idxv,_MM_SHUFFLE(1,1,1,1))); + tempv = _mm_load_ss(&data[idx]); + p1v = _mm_shuffle_ps( p1v, p1v, _MM_SHUFFLE(1,0,1,0)); + // now p1v is 3 2 3 2 + p1v = _mm_move_ss( p1v, tempv ); + // now p1v is 3 2 3 1 + + // get 1st value + idx = _mm_cvtsi128_si32 (idxv); + tempv = _mm_load_ss(&data[idx]); + p1v = _mm_shuffle_ps( p1v, p1v, _MM_SHUFFLE(3,2,0,0)); + // now p1v is 3 2 1 1 + p1v = _mm_move_ss( p1v, tempv ); + // now p1v is 3 2 1 0 + + return p1v; + } +#endif + + // use with float indices + T operator[](float index) const { + int idx = (int)index; // don't use floor! The difference in negative space is no problems here + if (index<0.f) + { + if (clip & LUT_CLIP_BELOW) + return data[0]; + idx=0; + } + else if (index > maxsf) + { + if (clip & LUT_CLIP_ABOVE) + return data[upperBound]; + idx =maxs; + } + float diff = index - (float) idx; + T p1 = data[idx]; + T p2 = data[idx + 1]-p1; + return (p1 + p2*diff); + } + + // Return the value for "index" that is in the [0-1] range. + T getVal01 (float index) const { + index *= float(upperBound); + int idx = (int)index; // don't use floor! The difference in negative space is no problems here + if (index<0.f) + { + if (clip & LUT_CLIP_BELOW) + return data[0]; + idx=0; + } + else if (index > maxsf) + { + if (clip & LUT_CLIP_ABOVE) + return data[upperBound]; + idx =maxs; + } + float diff = index - (float) idx; + T p1 = data[idx]; + T p2 = data[idx + 1]-p1; + return (p1 + p2*diff); + } + +#ifndef NDEBUG + // Debug facility ; dump the content of the LUT in a file. No control of the filename is done + void dump(Glib::ustring fname) { + if (size) { + Glib::ustring fname_ = fname + ".xyz"; // TopSolid'Design "plot" file format + std::ofstream f (fname_.c_str()); + f << "$" << std::endl; + for (unsigned int iter=0; iter0; + } + + void clear(void) { + if (data && size) + memset(data, 0, size * sizeof(T)); + } + + void reset(void) { + if (data) delete[] data; + dirty = true; + data = NULL; + owner = 1; + size = 0; + upperBound=0; + maxs=0; + } +}; + + + +// TODO: HOMBRE: HueLUT is actually unused, could we delete this class now that LUT::getVal01 has been created? + + +/** @brief LUT subclass handling hue values specifically. + The array has a fixed size of float values and have to be in the [0.; 1.] range in both axis (no error checking implemented) */ +class HueLUT : public LUTf { + public: + HueLUT() : LUTf() {} + HueLUT(bool createArray) : LUTf() { + if (createArray) + this->operator () (501, LUT_CLIP_BELOW|LUT_CLIP_ABOVE); + } + + void create() { + this->operator () (501, LUT_CLIP_BELOW|LUT_CLIP_ABOVE); + } + + // use with integer indices + float& operator[](int index) const { + return data[ rtengine::LIM(index, 0, upperBound) ]; + } + + // use with float indices in the [0.;1.] range + float operator[](float index) const { + int idx = int(index*500.f); // don't use floor! The difference in negative space is no problems here + if (index<0.f) + return data[0]; + else if (index > 1.f) + return data[upperBound]; + + float balance = index - float(idx/500.f); + float h1 = data[idx]; + float h2 = data[idx + 1]; + + if (h1==h2) + return h1; + if ((h1 > h2) && (h1-h2 > 0.5f)){ + h1 -= 1.f; + float value = h1 + balance * (h2-h1); + if (value < 0.f) + value += 1.f; + return value; + } + else if (h2-h1 > 0.5f) { + h2 -= 1.f; + float value = h1 + balance * (h2-h1); + if (value < 0.f) + value += 1.f; + return value; + } + else + return h1 + balance * (h2-h1); + } +}; + + +#endif /* LUT_H_ */ diff --git a/rtengine/PF_correct_RT.cc b/rtengine/PF_correct_RT.cc new file mode 100644 index 000000000..9da12afea --- /dev/null +++ b/rtengine/PF_correct_RT.cc @@ -0,0 +1,1489 @@ +//////////////////////////////////////////////////////////////// +// +// Chromatic Aberration Auto-correction +// +// copyright (c) 2008-2010 Emil Martinec +// +// +// code dated: November 24, 2010 +// optimized: September 2013, Ingo Weyrich +// +// PF_correct_RT.cc is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +//////////////////////////////////////////////////////////////// +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +#include "gauss.h" +#include "improcfun.h" +#include "sleef.c" +#include "mytime.h" +#include "../rtgui/myflatcurve.h" +#include "rt_math.h" +#include "opthelper.h" + +#ifdef _OPENMP +#include +#endif + +using namespace std; + +namespace rtengine { +extern const Settings* settings; + +SSEFUNCTION void ImProcFunctions::PF_correct_RT(LabImage * src, LabImage * dst, double radius, int thresh) +{ + const int halfwin = ceil(2*radius)+1; + + FlatCurve* chCurve = NULL; + if (params->defringe.huecurve.size() && FlatCurveType(params->defringe.huecurve.at(0)) > FCT_Linear) + chCurve = new FlatCurve(params->defringe.huecurve); + + // local variables + const int width=src->W, height=src->H; + //temporary array to store chromaticity + float (*fringe); + fringe = (float (*)) malloc (height * width * sizeof(*fringe)); + + LabImage * tmp1; + tmp1 = new LabImage(width, height); + +#ifdef _OPENMP +#pragma omp parallel +#endif + { + AlignedBufferMP buffer(max(src->W,src->H)); + gaussHorizontal (src->a, tmp1->a, buffer, src->W, src->H, radius); + gaussHorizontal (src->b, tmp1->b, buffer, src->W, src->H, radius); + gaussVertical (tmp1->a, tmp1->a, buffer, src->W, src->H, radius); + gaussVertical (tmp1->b, tmp1->b, buffer, src->W, src->H, radius); + } + +float chromave=0.0f; + +#ifdef __SSE2__ + if( chCurve ) { +// vectorized precalculation of the atan2 values +#ifdef _OPENMP +#pragma omp parallel +#endif + { + int j; +#ifdef _OPENMP +#pragma omp for +#endif + for(int i = 0; i < height; i++ ) { + for(j = 0; j < width-3; j+=4) + _mm_storeu_ps(&fringe[i*width+j], xatan2f(LVFU(src->b[i][j]),LVFU(src->a[i][j]))); + for(; j < width; j++) + fringe[i*width+j]=xatan2f(src->b[i][j],src->a[i][j]); + } + } + } +#endif + +#ifdef _OPENMP +#pragma omp parallel +#endif +{ + float chromaChfactor = 1.0f; +#ifdef _OPENMP +#pragma omp for reduction(+:chromave) +#endif + for(int i = 0; i < height; i++ ) { + for(int j = 0; j < width; j++) { + if (chCurve) { +#ifdef __SSE2__ + // use the precalculated atan values + float HH=fringe[i*width+j]; +#else + // no precalculated values without SSE => calculate + float HH=xatan2f(src->b[i][j],src->a[i][j]); +#endif + float chparam = float((chCurve->getVal((Color::huelab_to_huehsv2(HH)))-0.5f) * 2.0f);//get C=f(H) + if(chparam > 0.f) chparam /=2.f; // reduced action if chparam > 0 + chromaChfactor=1.0f+chparam; + } + float chroma = SQR(chromaChfactor*(src->a[i][j]-tmp1->a[i][j]))+SQR(chromaChfactor*(src->b[i][j]-tmp1->b[i][j]));//modulate chroma function hue + chromave += chroma; + fringe[i*width+j]=chroma; + } + } +} + + chromave /= (height*width); + float threshfactor = SQR(thresh/33.f)*chromave*5.0f; + + +// now chromave is calculated, so we postprocess fringe to reduce the number of divisions in future +#ifdef __SSE2__ +#ifdef _OPENMP +#pragma omp parallel +#endif +{ + __m128 sumv = _mm_set1_ps( chromave ); + __m128 onev = _mm_set1_ps( 1.0f ); +#ifdef _OPENMP +#pragma omp for +#endif + for(int j=0; j < width*height-3; j+=4) + _mm_storeu_ps( &fringe[j], onev/(LVFU(fringe[j])+sumv)); +} + for(int j=width*height - (width*height)%4; j < width*height; j++) + fringe[j] = 1.f/(fringe[j]+chromave); +#else +#ifdef _OPENMP +#pragma omp parallel for +#endif + for(int j = 0; j < width*height; j++) + fringe[j] = 1.f/(fringe[j]+chromave); +#endif + + // because we changed the values of fringe we also have to recalculate threshfactor + threshfactor = 1.0f/(threshfactor + chromave); + +// Issue 1674: +// often, CA isn't evenly distributed, e.g. a lot in contrasty regions and none in the sky. +// so it's better to schedule dynamic and let every thread only process 16 rows, to avoid running big threads out of work +// Measured it and in fact gives better performance than without schedule(dynamic,16). Of course, there could be a better +// choice for the chunk_size than 16 +// Issue 1972: Split this loop in three parts to avoid most of the min and max-operations +#ifdef _OPENMP +#pragma omp parallel for schedule(dynamic,16) +#endif + for(int i = 0; i < height; i++ ) { + int j; + for(j = 0; j < halfwin-1; j++) { + tmp1->a[i][j] = src->a[i][j]; + tmp1->b[i][j] = src->b[i][j]; + //test for pixel darker than some fraction of neighborhood ave, near an edge, more saturated than average + /*if (100*tmp1->L[i][j]>50*src->L[i][j] && \*/ + /*1000*abs(tmp1->L[i][j]-src->L[i][j])>thresh*(tmp1->L[i][j]+src->L[i][j]) && \*/ + if (fringe[i*width+j]a[i1][j1]; + btot += wt*src->b[i1][j1]; + norm += wt; + } + tmp1->a[i][j] = atot/norm; + tmp1->b[i][j] = btot/norm; + } + } + for(; j < width-halfwin+1; j++) { + tmp1->a[i][j] = src->a[i][j]; + tmp1->b[i][j] = src->b[i][j]; + //test for pixel darker than some fraction of neighborhood ave, near an edge, more saturated than average + /*if (100*tmp1->L[i][j]>50*src->L[i][j] && \*/ + /*1000*abs(tmp1->L[i][j]-src->L[i][j])>thresh*(tmp1->L[i][j]+src->L[i][j]) && \*/ + if (fringe[i*width+j]a[i1][j1]; + btot += wt*src->b[i1][j1]; + norm += wt; + } + tmp1->a[i][j] = atot/norm; + tmp1->b[i][j] = btot/norm; + } + } + for(; j < width; j++) { + tmp1->a[i][j] = src->a[i][j]; + tmp1->b[i][j] = src->b[i][j]; + //test for pixel darker than some fraction of neighborhood ave, near an edge, more saturated than average + /*if (100*tmp1->L[i][j]>50*src->L[i][j] && \*/ + /*1000*abs(tmp1->L[i][j]-src->L[i][j])>thresh*(tmp1->L[i][j]+src->L[i][j]) && \*/ + if (fringe[i*width+j]a[i1][j1]; + btot += wt*src->b[i1][j1]; + norm += wt; + } + tmp1->a[i][j] = atot/norm; + tmp1->b[i][j] = btot/norm; + } + } + }//end of ab channel averaging + + if(src != dst) +#ifdef _OPENMP +#pragma omp parallel for +#endif + for(int i = 0; i < height; i++ ) { + for(int j = 0; j < width; j++) { + dst->L[i][j] = src->L[i][j]; + } + } + +#ifdef _OPENMP +#pragma omp parallel for +#endif + for(int i = 0; i < height; i++ ) { + for(int j = 0; j < width; j++) { + dst->a[i][j] = tmp1->a[i][j]; + dst->b[i][j] = tmp1->b[i][j]; + } + } + + + delete tmp1; + if(chCurve) delete chCurve; + free(fringe); +} + +SSEFUNCTION void ImProcFunctions::PF_correct_RTcam(CieImage * src, CieImage * dst, double radius, int thresh) +{ + const int halfwin = ceil(2*radius)+1; + + FlatCurve* chCurve = NULL; + if (params->defringe.huecurve.size() && FlatCurveType(params->defringe.huecurve.at(0)) > FCT_Linear) + chCurve = new FlatCurve(params->defringe.huecurve); + + // local variables + const int width=src->W, height=src->H; + const float piid=3.14159265f/180.f; + const float eps2=0.01f; + + //temporary array to store chromaticity + float (*fringe); + fringe = (float (*)) malloc (height * width * sizeof(*fringe)); + + float** sraa; + sraa = new float*[height]; + for (int i=0; ih_p[i][j])); + _mm_storeu_ps(&sraa[i][j],LVFU(src->C_p[i][j])*sincosvalv.y); + _mm_storeu_ps(&srbb[i][j],LVFU(src->C_p[i][j])*sincosvalv.x); + } + for (; jh_p[i][j]); + sraa[i][j]=src->C_p[i][j]*sincosval.y; + srbb[i][j]=src->C_p[i][j]*sincosval.x; + } +#else + for (int j=0; jh_p[i][j]); + sraa[i][j]=src->C_p[i][j]*sincosval.y; + srbb[i][j]=src->C_p[i][j]*sincosval.x; + } +#endif + } +} + +#ifdef _OPENMP +#pragma omp parallel +#endif + { + AlignedBufferMP buffer(max(src->W,src->H)); + gaussHorizontal (sraa, tmaa, buffer, src->W, src->H, radius); + gaussHorizontal (srbb, tmbb, buffer, src->W, src->H, radius); + gaussVertical (tmaa, tmaa, buffer, src->W, src->H, radius); + gaussVertical (tmbb, tmbb, buffer, src->W, src->H, radius); + } + +float chromave=0.0f; + +#ifdef __SSE2__ +if( chCurve ) { +// vectorized precalculation of the atan2 values +#ifdef _OPENMP +#pragma omp parallel +#endif +{ + int j; +#ifdef _OPENMP +#pragma omp for +#endif + for(int i = 0; i < height; i++ ) { + for(j = 0; j < width-3; j+=4) + _mm_storeu_ps(&fringe[i*width+j], xatan2f(LVFU(srbb[i][j]),LVFU(sraa[i][j]))); + for(; j < width; j++) + fringe[i*width+j]=xatan2f(srbb[i][j],sraa[i][j]); + } +} +} +#endif + +#ifdef _OPENMP +#pragma omp parallel +#endif +{ + float chromaChfactor = 1.0f; +#ifdef _OPENMP +#pragma omp for reduction(+:chromave) +#endif + for(int i = 0; i < height; i++ ) { + for(int j = 0; j < width; j++) { + if (chCurve) { +#ifdef __SSE2__ + // use the precalculated atan values + float HH=fringe[i*width+j]; +#else + // no precalculated values without SSE => calculate + float HH=xatan2f(srbb[i][j],sraa[i][j]); +#endif + float chparam = float((chCurve->getVal((Color::huelab_to_huehsv2(HH)))-0.5f) * 2.0f);//get C=f(H) + if(chparam > 0.f) chparam /=2.f; // reduced action if chparam > 0 + chromaChfactor=1.0f+chparam; + } + float chroma = SQR(chromaChfactor*(sraa[i][j]-tmaa[i][j]))+SQR(chromaChfactor*(srbb[i][j]-tmbb[i][j]));//modulate chroma function hue + chromave += chroma; + fringe[i*width+j]=chroma; + } + } +} + + chromave /= (height*width); + float threshfactor = SQR(thresh/33.f)*chromave*5.0f; // Calculated once to eliminate mult inside the next loop + +// now chromave is calculated, so we postprocess fringe to reduce the number of divisions in future +#ifdef __SSE2__ +#ifdef _OPENMP +#pragma omp parallel +#endif +{ + __m128 sumv = _mm_set1_ps( chromave + eps2 ); + __m128 onev = _mm_set1_ps( 1.0f ); +#ifdef _OPENMP +#pragma omp for +#endif + for(int j=0; j < width*height-3; j+=4) + _mm_storeu_ps( &fringe[j], onev/(LVFU(fringe[j])+sumv)); +} + for(int j=width*height - (width*height)%4; j < width*height; j++) + fringe[j] = 1.f/(fringe[j]+chromave+eps2); +#else +#ifdef _OPENMP +#pragma omp parallel for +#endif + for(int j = 0; j < width*height; j++) + fringe[j] = 1.f/(fringe[j]+chromave+eps2); +#endif + + // because we changed the values of fringe we also have to recalculate threshfactor + threshfactor = 1.0f/(threshfactor + chromave + eps2); + +// Issue 1674: +// often, CA isn't evenly distributed, e.g. a lot in contrasty regions and none in the sky. +// so it's better to schedule dynamic and let every thread only process 16 rows, to avoid running big threads out of work +// Measured it and in fact gives better performance than without schedule(dynamic,16). Of course, there could be a better +// choice for the chunk_size than 16 +// Issue 1972: Split this loop in three parts to avoid most of the min and max-operations +#ifdef _OPENMP +#pragma omp parallel for schedule(dynamic,16) +#endif + for(int i = 0; i < height; i++ ) { + int j; + for(j = 0; j < halfwin-1; j++) { + tmaa[i][j] = sraa[i][j]; + tmbb[i][j] = srbb[i][j]; + + if (fringe[i*width+j] 0.f){ + tmaa[i][j] = (atot/norm); + tmbb[i][j] = (btot/norm); + } + } + } + for(; j < width-halfwin+1; j++) { + tmaa[i][j] = sraa[i][j]; + tmbb[i][j] = srbb[i][j]; + + if (fringe[i*width+j] 0.f){ + tmaa[i][j] = (atot/norm); + tmbb[i][j] = (btot/norm); + } + } + } + for(; j < width; j++) { + tmaa[i][j] = sraa[i][j]; + tmbb[i][j] = srbb[i][j]; + + if (fringe[i*width+j] 0.f){ + tmaa[i][j] = (atot/norm); + tmbb[i][j] = (btot/norm); + } + } + } + } //end of ab channel averaging + + +#ifdef _OPENMP +#pragma omp parallel +#endif +{ +#ifdef __SSE2__ + int j; + __m128 interav, interbv; + __m128 piidv = _mm_set1_ps(piid); +#endif +#ifdef _OPENMP +#pragma omp for +#endif + for(int i = 0; i < height; i++ ) { +#ifdef __SSE2__ + for(j = 0; j < width-3; j+=4) { + _mm_storeu_ps( &dst->sh_p[i][j], LVFU(src->sh_p[i][j])); + interav = LVFU(tmaa[i][j]); + interbv = LVFU(tmbb[i][j]); + _mm_storeu_ps(&dst->h_p[i][j],(xatan2f(interbv,interav))/piidv); + _mm_storeu_ps(&dst->C_p[i][j],_mm_sqrt_ps(SQRV(interbv)+SQRV(interav))); + } + for(; j < width; j++) { + dst->sh_p[i][j] = src->sh_p[i][j]; + float intera = tmaa[i][j]; + float interb = tmbb[i][j]; + dst->h_p[i][j]=(xatan2f(interb,intera))/piid; + dst->C_p[i][j]=sqrt(SQR(interb)+SQR(intera)); + } +#else + for(int j = 0; j < width; j++) { + dst->sh_p[i][j] = src->sh_p[i][j]; + float intera = tmaa[i][j]; + float interb = tmbb[i][j]; + dst->h_p[i][j]=(xatan2f(interb,intera))/piid; + dst->C_p[i][j]=sqrt(SQR(interb)+SQR(intera)); + } +#endif + } +} + + for (int i=0; iW, height=src->H; + const float piid=3.14159265f/180.f; + float shfabs, shmed; + + int i1, j1, tot; + const float eps = 1.0f; + const float eps2 = 0.01f; + float shsum, dirsh, norm, sum; + + float** sraa; + sraa = new float*[height]; + for (int i=0; ih_p[i][j])); + _mm_storeu_ps(&sraa[i][j],LVFU(src->C_p[i][j])*sincosvalv.y); + _mm_storeu_ps(&srbb[i][j],LVFU(src->C_p[i][j])*sincosvalv.x); + } + for (; jh_p[i][j]); + sraa[i][j]=src->C_p[i][j]*sincosval.y; + srbb[i][j]=src->C_p[i][j]*sincosval.x; + } +#else + for (int j=0; jh_p[i][j]); + sraa[i][j]=src->C_p[i][j]*sincosval.y; + srbb[i][j]=src->C_p[i][j]*sincosval.x; + } +#endif + } +} + +#ifdef _OPENMP +#pragma omp parallel +#endif + { + AlignedBufferMP buffer(max(src->W,src->H)); + //chroma a and b + if(mode==2) {//choice of gaussian blur + gaussHorizontal (sraa, tmaa, buffer, src->W, src->H, radius); + gaussHorizontal (srbb, tmbb, buffer, src->W, src->H, radius); + gaussVertical (tmaa, tmaa, buffer, src->W, src->H, radius); + gaussVertical (tmbb, tmbb, buffer, src->W, src->H, radius); + } + //luma sh_p + gaussHorizontal (src->sh_p, tmL, buffer, src->W, src->H, 2.0);//low value to avoid artifacts + gaussVertical (tmL, tmL, buffer, src->W, src->H, 2.0); + } + +if(mode==1){ //choice of median +#pragma omp parallel + { + int ip,in,jp,jn; + float pp[9],temp; +#pragma omp for nowait //nowait because next loop inside this parallel region is independent on this one + for (int i=0; iheight-3) {in=i-2;} else {in=i+2;} + for (int j=0; jwidth-3) {jn=j-2;} else {jn=j+2;} + med3(sraa[ip][jp],sraa[ip][j],sraa[ip][jn],sraa[i][jp],sraa[i][j],sraa[i][jn],sraa[in][jp],sraa[in][j],sraa[in][jn],tmaa[i][j]); + } + } +#pragma omp for + for (int i=0; iheight-3) {in=i-2;} else {in=i+2;} + for (int j=0; jwidth-3) {jn=j-2;} else {jn=j+2;} + med3(srbb[ip][jp],srbb[ip][j],srbb[ip][jn],srbb[i][jp],srbb[i][j],srbb[i][jn],srbb[in][jp],srbb[in][j],srbb[in][jn],tmbb[i][j]); + } + } + } +} + +//luma badpixels + const float sh_thr = 4.5f;//low value for luma sh_p to avoid artifacts + const float shthr = sh_thr / 24.0f; + +#ifdef _OPENMP +#pragma omp parallel +#endif +{ + int j; +#ifdef __SSE2__ + __m128 shfabsv, shmedv; + __m128 shthrv = _mm_set1_ps(shthr); + __m128 onev = _mm_set1_ps(1.0f); +#endif // __SSE2__ +#ifdef _OPENMP +#pragma omp for private(shfabs, shmed,i1,j1) +#endif + for (int i=0; i < height; i++) { + for (j=0; j < 2; j++) { + shfabs = fabs(src->sh_p[i][j]-tmL[i][j]); + shmed=0.0f; + for (i1=max(0,i-2); i1<=min(i+2,height-1); i1++ ) + for (j1=0; j1<=j+2; j1++ ) { + shmed += fabs(src->sh_p[i1][j1]-tmL[i1][j1]); + } + badpix[i*width+j] = (shfabs>((shmed-shfabs)*shthr)); + } + +#ifdef __SSE2__ + for (; j < width-5; j+=4) { + shfabsv = vabsf(LVFU(src->sh_p[i][j])-LVFU(tmL[i][j])); + shmedv = _mm_setzero_ps(); + for (i1=max(0,i-2); i1<=min(i+2,height-1); i1++ ) + for (j1=j-2; j1<=j+2; j1++ ) { + shmedv += vabsf(LVFU(src->sh_p[i1][j1])-LVFU(tmL[i1][j1])); + } + _mm_storeu_ps( &badpix[i*width+j], vself(vmaskf_gt(shfabsv,(shmedv - shfabsv)*shthrv), onev, _mm_setzero_ps())); + } + for (; j < width-2; j++) { + shfabs = fabs(src->sh_p[i][j]-tmL[i][j]); + shmed=0.0f; + for (i1=max(0,i-2); i1<=min(i+2,height-1); i1++ ) + for (j1=j-2; j1<=j+2; j1++ ) { + shmed += fabs(src->sh_p[i1][j1]-tmL[i1][j1]); + } + badpix[i*width+j] = (shfabs>((shmed-shfabs)*shthr)); + } +#else + for (; j < width-2; j++) { + shfabs = fabs(src->sh_p[i][j]-tmL[i][j]); + shmed=0.0f; + for (i1=max(0,i-2); i1<=min(i+2,height-1); i1++ ) + for (j1=j-2; j1<=j+2; j1++ ) { + shmed += fabs(src->sh_p[i1][j1]-tmL[i1][j1]); + } + badpix[i*width+j] = (shfabs>((shmed-shfabs)*shthr)); + } +#endif + for (; j < width; j++) { + shfabs = fabs(src->sh_p[i][j]-tmL[i][j]); + shmed=0.0f; + for (i1=max(0,i-2); i1<=min(i+2,height-1); i1++ ) + for (j1=j-2; j1sh_p[i1][j1]-tmL[i1][j1]); + } + badpix[i*width+j] = (shfabs>((shmed-shfabs)*shthr)); + } + } +} + + +#ifdef _OPENMP +#pragma omp parallel +#endif +{ + int j; +#ifdef _OPENMP +#pragma omp for private(shsum,norm,dirsh,sum,i1,j1) schedule(dynamic,16) +#endif + for (int i=0; i < height; i++) { + for (j=0; j < 2; j++) { + if (!badpix[i*width+j]) continue; + norm=0.0f; + shsum=0.0f; + sum=0.0f; + tot=0; + for (i1=max(0,i-2); i1<=min(i+2,height-1); i1++ ) + for (j1=0; j1<=j+2; j1++ ) { + if (i1==i && j1==j) continue; + if (badpix[i1*width+j1]) continue; + sum += src->sh_p[i1][j1]; + tot++; + dirsh = 1.f/(SQR(src->sh_p[i1][j1]-src->sh_p[i][j])+eps); + shsum += dirsh*src->sh_p[i1][j1]; + norm += dirsh; + } + if (norm > 0.f) { + src->sh_p[i][j]=shsum/norm; + } + else { + if(tot > 0) src->sh_p[i][j]=sum / tot; + } + } + for (; j < width-2; j++) { + if (!badpix[i*width+j]) continue; + norm=0.0f; + shsum=0.0f; + sum=0.0f; + tot=0; + for (i1=max(0,i-2); i1<=min(i+2,height-1); i1++ ) + for (j1=j-2; j1<=j+2; j1++ ) { + if (i1==i && j1==j) continue; + if (badpix[i1*width+j1]) continue; + sum += src->sh_p[i1][j1]; + tot++; + dirsh = 1.f/(SQR(src->sh_p[i1][j1]-src->sh_p[i][j])+eps); + shsum += dirsh*src->sh_p[i1][j1]; + norm += dirsh; + } + if (norm > 0.f) { + src->sh_p[i][j]=shsum/norm; + } + else { + if(tot > 0) src->sh_p[i][j]=sum / tot; + } + } + for (; j < width; j++) { + if (!badpix[i*width+j]) continue; + norm=0.0f; + shsum=0.0f; + sum=0.0f; + tot=0; + for (i1=max(0,i-2); i1<=min(i+2,height-1); i1++ ) + for (j1=j-2; j1sh_p[i1][j1]; + tot++; + dirsh = 1.f/(SQR(src->sh_p[i1][j1]-src->sh_p[i][j])+eps); + shsum += dirsh*src->sh_p[i1][j1]; + norm += dirsh; + } + if (norm > 0.f) { + src->sh_p[i][j]=shsum/norm; + } + else { + if(tot > 0) src->sh_p[i][j]=sum / tot; + } + } + } +} +// end luma badpixels + + +// begin chroma badpixels +float chrommed=0.f; +#ifdef _OPENMP +#pragma omp parallel for reduction(+:chrommed) +#endif + for(int i = 0; i < height; i++ ) { + for(int j = 0; j < width; j++) { + float chroma =SQR(sraa[i][j]-tmaa[i][j])+SQR(srbb[i][j]-tmbb[i][j]); + chrommed += chroma; + badpix[i*width+j]=chroma; + } + } + chrommed /= (height*width); + float threshfactor = (thresh*chrommed)/33.f; + +// now chrommed is calculated, so we postprocess badpix to reduce the number of divisions in future +#ifdef __SSE2__ +#ifdef _OPENMP +#pragma omp parallel +#endif +{ + int j; + __m128 sumv = _mm_set1_ps( chrommed + eps2 ); + __m128 onev = _mm_set1_ps( 1.0f ); +#ifdef _OPENMP +#pragma omp for +#endif + for(int i = 0; i 0.f){ + tmaa[i][j] = (atot/norm); + tmbb[i][j] = (btot/norm); + } + } + } + for(; j < width-halfwin; j++) { + tmaa[i][j] = sraa[i][j]; + tmbb[i][j] = srbb[i][j]; + + if (badpix[i*width+j] 0.f){ + tmaa[i][j] = (atot/norm); + tmbb[i][j] = (btot/norm); + } + } + } + for(; j < width; j++) { + tmaa[i][j] = sraa[i][j]; + tmbb[i][j] = srbb[i][j]; + + if (badpix[i*width+j] 0.f){ + tmaa[i][j] = (atot/norm); + tmbb[i][j] = (btot/norm); + } + } + } + } +} + +#ifdef _OPENMP +#pragma omp parallel +#endif +{ +#ifdef _OPENMP +#pragma omp for +#endif + for(int i = 0; i < height; i++ ) { + for(int j = 0; j < width; j++) { + float intera = tmaa[i][j]; + float interb = tmbb[i][j]; + float CC=sqrt(SQR(interb)+SQR(intera)); + if(hotbad==0) { + if(CC < chrom && skinprot !=0.f){ + dst->h_p[i][j]=(xatan2f(interb,intera))/piid; + dst->C_p[i][j]=sqrt(SQR(interb)+SQR(intera)); + } + } + else { + dst->h_p[i][j]=(xatan2f(interb,intera))/piid; + dst->C_p[i][j]=sqrt(SQR(interb)+SQR(intera)); + } + } + } +} + + if(src != dst) { +#ifdef _OPENMP +#pragma omp parallel for +#endif + for(int i = 0; i < height; i++ ) + for(int j = 0; j < width; j++) + dst->sh_p[i][j] = src->sh_p[i][j]; + } + + + for (int i=0; iverbose ) + printf("Ciecam badpixels:- %d usec\n", t2.etime(t1)); + + +} + +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) +{ + const int halfwin = ceil(2*radius)+1; + MyTime t1,t2; + t1.set(); + + const int width=src->W, height=src->H; +// const float piid=3.14159265f/180.f; + float shfabs, shmed; + + int i1, j1, tot; + const float eps = 1.0f; + const float eps2 = 0.01f; + float shsum, dirsh, norm, sum; + + float** sraa; + sraa = new float*[height]; + for (int i=0; ia[i][j])); + _mm_storeu_ps(&srbb[i][j],LVFU(src->b[i][j])); + } + for (; ja[i][j]; + srbb[i][j]=src->b[i][j]; + } +#else + for (int j=0; ja[i][j]; + srbb[i][j]=src->b[i][j]; + } +#endif + } +} + +#ifdef _OPENMP +#pragma omp parallel +#endif + { + AlignedBufferMP buffer(max(src->W,src->H)); + //chroma a and b + if(mode>=2) {//choice of gaussian blur + gaussHorizontal (sraa, tmaa, buffer, src->W, src->H, radius); + gaussHorizontal (srbb, tmbb, buffer, src->W, src->H, radius); + gaussVertical (tmaa, tmaa, buffer, src->W, src->H, radius); + gaussVertical (tmbb, tmbb, buffer, src->W, src->H, radius); + } + //luma sh_p + gaussHorizontal (src->L, tmL, buffer, src->W, src->H, 2.0);//low value to avoid artifacts + gaussVertical (tmL, tmL, buffer, src->W, src->H, 2.0); + } + +if(mode==1){ //choice of median +#pragma omp parallel + { + int ip,in,jp,jn; + float pp[9],temp; +#pragma omp for nowait //nowait because next loop inside this parallel region is independent on this one + for (int i=0; iheight-3) {in=i-2;} else {in=i+2;} + for (int j=0; jwidth-3) {jn=j-2;} else {jn=j+2;} + med3(sraa[ip][jp],sraa[ip][j],sraa[ip][jn],sraa[i][jp],sraa[i][j],sraa[i][jn],sraa[in][jp],sraa[in][j],sraa[in][jn],tmaa[i][j]); + } + } +#pragma omp for + for (int i=0; iheight-3) {in=i-2;} else {in=i+2;} + for (int j=0; jwidth-3) {jn=j-2;} else {jn=j+2;} + med3(srbb[ip][jp],srbb[ip][j],srbb[ip][jn],srbb[i][jp],srbb[i][j],srbb[i][jn],srbb[in][jp],srbb[in][j],srbb[in][jn],tmbb[i][j]); + } + } + } +} + +//luma badpixels + const float sh_thr = 4.5f;//low value for luma sh_p to avoid artifacts + const float shthr = sh_thr / 24.0f; + +#ifdef _OPENMP +#pragma omp parallel +#endif +{ + int j; +#ifdef __SSE2__ + __m128 shfabsv, shmedv; + __m128 shthrv = _mm_set1_ps(shthr); + __m128 onev = _mm_set1_ps(1.0f); +#endif // __SSE2__ +#ifdef _OPENMP +#pragma omp for private(shfabs, shmed,i1,j1) +#endif + for (int i=0; i < height; i++) { + for (j=0; j < 2; j++) { + shfabs = fabs(src->L[i][j]-tmL[i][j]); + shmed=0.0f; + for (i1=max(0,i-2); i1<=min(i+2,height-1); i1++ ) + for (j1=0; j1<=j+2; j1++ ) { + shmed += fabs(src->L[i1][j1]-tmL[i1][j1]); + } + badpix[i*width+j] = (shfabs>((shmed-shfabs)*shthr)); + } + +#ifdef __SSE2__ + for (; j < width-5; j+=4) { + shfabsv = vabsf(LVFU(src->L[i][j])-LVFU(tmL[i][j])); + shmedv = _mm_setzero_ps(); + for (i1=max(0,i-2); i1<=min(i+2,height-1); i1++ ) + for (j1=j-2; j1<=j+2; j1++ ) { + shmedv += vabsf(LVFU(src->L[i1][j1])-LVFU(tmL[i1][j1])); + } + _mm_storeu_ps( &badpix[i*width+j], vself(vmaskf_gt(shfabsv,(shmedv - shfabsv)*shthrv), onev, _mm_setzero_ps())); + } + for (; j < width-2; j++) { + shfabs = fabs(src->L[i][j]-tmL[i][j]); + shmed=0.0f; + for (i1=max(0,i-2); i1<=min(i+2,height-1); i1++ ) + for (j1=j-2; j1<=j+2; j1++ ) { + shmed += fabs(src->L[i1][j1]-tmL[i1][j1]); + } + badpix[i*width+j] = (shfabs>((shmed-shfabs)*shthr)); + } +#else + for (; j < width-2; j++) { + shfabs = fabs(src->L[i][j]-tmL[i][j]); + shmed=0.0f; + for (i1=max(0,i-2); i1<=min(i+2,height-1); i1++ ) + for (j1=j-2; j1<=j+2; j1++ ) { + shmed += fabs(src->L[i1][j1]-tmL[i1][j1]); + } + badpix[i*width+j] = (shfabs>((shmed-shfabs)*shthr)); + } +#endif + for (; j < width; j++) { + shfabs = fabs(src->L[i][j]-tmL[i][j]); + shmed=0.0f; + for (i1=max(0,i-2); i1<=min(i+2,height-1); i1++ ) + for (j1=j-2; j1L[i1][j1]-tmL[i1][j1]); + } + badpix[i*width+j] = (shfabs>((shmed-shfabs)*shthr)); + } + } +} + + +#ifdef _OPENMP +#pragma omp parallel +#endif +{ + int j; +#ifdef _OPENMP +#pragma omp for private(shsum,norm,dirsh,sum,i1,j1) schedule(dynamic,16) +#endif + for (int i=0; i < height; i++) { + for (j=0; j < 2; j++) { + if (!badpix[i*width+j]) continue; + norm=0.0f; + shsum=0.0f; + sum=0.0f; + tot=0; + for (i1=max(0,i-2); i1<=min(i+2,height-1); i1++ ) + for (j1=0; j1<=j+2; j1++ ) { + if (i1==i && j1==j) continue; + if (badpix[i1*width+j1]) continue; + sum += src->L[i1][j1]; + tot++; + dirsh = 1.f/(SQR(src->L[i1][j1]-src->L[i][j])+eps); + shsum += dirsh*src->L[i1][j1]; + norm += dirsh; + } + if (norm > 0.f) { + src->L[i][j]=shsum/norm; + } + else { + if(tot > 0) src->L[i][j]=sum / tot; + } + } + for (; j < width-2; j++) { + if (!badpix[i*width+j]) continue; + norm=0.0f; + shsum=0.0f; + sum=0.0f; + tot=0; + for (i1=max(0,i-2); i1<=min(i+2,height-1); i1++ ) + for (j1=j-2; j1<=j+2; j1++ ) { + if (i1==i && j1==j) continue; + if (badpix[i1*width+j1]) continue; + sum += src->L[i1][j1]; + tot++; + dirsh = 1.f/(SQR(src->L[i1][j1]-src->L[i][j])+eps); + shsum += dirsh*src->L[i1][j1]; + norm += dirsh; + } + if (norm > 0.f) { + src->L[i][j]=shsum/norm; + } + else { + if(tot > 0) src->L[i][j]=sum / tot; + } + } + for (; j < width; j++) { + if (!badpix[i*width+j]) continue; + norm=0.0f; + shsum=0.0f; + sum=0.0f; + tot=0; + for (i1=max(0,i-2); i1<=min(i+2,height-1); i1++ ) + for (j1=j-2; j1L[i1][j1]; + tot++; + dirsh = 1.f/(SQR(src->L[i1][j1]-src->L[i][j])+eps); + shsum += dirsh*src->L[i1][j1]; + norm += dirsh; + } + if (norm > 0.f) { + src->L[i][j]=shsum/norm; + } + else { + if(tot > 0) src->L[i][j]=sum / tot; + } + } + } +} +// end luma badpixels + +if(mode==3) { +// begin chroma badpixels +float chrommed=0.f; +#ifdef _OPENMP +#pragma omp parallel for reduction(+:chrommed) +#endif + for(int i = 0; i < height; i++ ) { + for(int j = 0; j < width; j++) { + float chroma =SQR(sraa[i][j]-tmaa[i][j])+SQR(srbb[i][j]-tmbb[i][j]); + chrommed += chroma; + badpix[i*width+j]=chroma; + } + } + chrommed /= (height*width); + float threshfactor = (thresh*chrommed)/33.f; + +// now chrommed is calculated, so we postprocess badpix to reduce the number of divisions in future +#ifdef __SSE2__ +#ifdef _OPENMP +#pragma omp parallel +#endif +{ + int j; + __m128 sumv = _mm_set1_ps( chrommed + eps2 ); + __m128 onev = _mm_set1_ps( 1.0f ); +#ifdef _OPENMP +#pragma omp for +#endif + for(int i = 0; i 0.f){ + tmaa[i][j] = (atot/norm); + tmbb[i][j] = (btot/norm); + } + } + } + for(; j < width-halfwin; j++) { + tmaa[i][j] = sraa[i][j]; + tmbb[i][j] = srbb[i][j]; + + if (badpix[i*width+j] 0.f){ + tmaa[i][j] = (atot/norm); + tmbb[i][j] = (btot/norm); + } + } + } + for(; j < width; j++) { + tmaa[i][j] = sraa[i][j]; + tmbb[i][j] = srbb[i][j]; + + if (badpix[i*width+j] 0.f){ + tmaa[i][j] = (atot/norm); + tmbb[i][j] = (btot/norm); + } + } + } + } +} + +#ifdef _OPENMP +#pragma omp parallel +#endif +{ +#ifdef _OPENMP +#pragma omp for +#endif + for(int i = 0; i < height; i++ ) { + for(int j = 0; j < width; j++) { + float intera = tmaa[i][j]; + float interb = tmbb[i][j]; + float CC=sqrt(SQR(interb/327.68)+SQR(intera/327.68f)); + if(CC < chrom && skinprot !=0.f){ + dst->a[i][j]=intera; + dst->b[i][j]=interb; + } + } + } +} +} + if(src != dst) { +#ifdef _OPENMP +#pragma omp parallel for +#endif + for(int i = 0; i < height; i++ ) + for(int j = 0; j < width; j++) + dst->L[i][j] = src->L[i][j]; + } + + + for (int i=0; iverbose ) + printf("Lab artifacts:- %d usec\n", t2.etime(t1)); + + +} + +} diff --git a/rtengine/StopWatch.h b/rtengine/StopWatch.h new file mode 100644 index 000000000..468f0817c --- /dev/null +++ b/rtengine/StopWatch.h @@ -0,0 +1,55 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + * + * Author: reine + */ + +#ifndef STOPWATCH_H +#define STOPWATCH_H +#include +#include "mytime.h" + +class StopWatch { +public: + StopWatch( ) { stopped = false; } + StopWatch( const char* msg) { message = msg; start(); stopped = false; } + ~StopWatch() { if(!stopped) stop(); } + void start() + { + startTime.set(); + }; + void stop() + { + stopTime.set(); + long elapsedTime = stopTime.etime(startTime) / 1000; + std::cout << message << " took " << elapsedTime << " ms" <, Oliver Duis + * + * 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 _ALIGNEDBUFFER_ +#define _ALIGNEDBUFFER_ +#include +#include +#include +#include +#include "../rtgui/threadutils.h" + +// Aligned buffer that should be faster +template class AlignedBuffer { + +private: + void* real ; + char alignment; + size_t allocatedSize; + int unitSize; + +public: + T* data ; + bool inUse; + + /** @brief Allocate aligned memory + * @param size Number of elements of size T to allocate, i.e. allocated size will be sizeof(T)*size ; set it to 0 if you want to defer the allocation + * @param align Expressed in bytes; SSE instructions need 128 bits alignment, which mean 16 bytes, which is the default value + */ + AlignedBuffer (size_t size=0, size_t align=16) : real(NULL), alignment(align), allocatedSize(0), unitSize(0), data(NULL), inUse(false) { + if (size) + resize(size); + } + + ~AlignedBuffer () { + if (real) free(real); + } + + /** @brief Return true if there's no memory allocated + */ + bool isEmpty() { + return allocatedSize==0; + } + + /** @brief Allocate the the "size" amount of elements of "structSize" length each + * @param size number of elements to allocate + * @param structSize if non null, will let you override the default struct's size (unit: byte) + * @return True is everything went fine, including freeing memory when size==0, false if the allocation failed + */ + bool resize(size_t size, int structSize=0) { + if (allocatedSize != size) { + if (!size) { + // The user want to free the memory + if (real) free(real); + real = NULL; + data = NULL; + inUse = false; + allocatedSize = 0; + unitSize = 0; + } + else { + unitSize = structSize ? structSize : sizeof(T); + size_t oldAllocatedSize = allocatedSize; + allocatedSize = size*unitSize; + + // realloc were used here to limit memory fragmentation, specially when the size was smaller than the previous one. + // But realloc copies the content to the eventually new location, which is unnecessary. To avoid this performance penalty, + // we're freeing the memory and allocate it again if the new size is bigger. + + if (allocatedSize < oldAllocatedSize) + real = realloc(real, allocatedSize+alignment); + else { + if (real) free (real); + real = malloc(allocatedSize+alignment); + } + + 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 { + allocatedSize = 0; + unitSize = 0; + data = NULL; + inUse = false; + return false; + } + } + } + return true; + } + + void swap(AlignedBuffer &other) { + void *tmpReal = other.real; + other.real = real; + real = tmpReal; + + char tmpAlignt = other.alignment; + other.alignment = alignment; + alignment = tmpAlignt; + + size_t tmpAllocSize = other.allocatedSize; + other.allocatedSize = allocatedSize; + allocatedSize = tmpAllocSize; + + T* tmpData = other.data; + other.data = data; + data = tmpData; + + bool tmpInUse = other.inUse; + other.inUse = inUse; + inUse = tmpInUse; + } + + unsigned int getSize() { + return unitSize ? allocatedSize/unitSize : 0; + } +}; + +// Multi processor version, use with OpenMP +template class AlignedBufferMP { +private: + MyMutex mtx; + std::vector*> buffers; + size_t size; + +public: + AlignedBufferMP(size_t sizeP) { + size=sizeP; + } + + ~AlignedBufferMP() { + for (size_t i=0;i* acquire() { + MyMutex::MyLock lock(mtx); + + // Find available buffer + for (size_t i=0;iinUse) { + 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/amaze_demosaic_RT.cc b/rtengine/amaze_demosaic_RT.cc new file mode 100644 index 000000000..03efa62cd --- /dev/null +++ b/rtengine/amaze_demosaic_RT.cc @@ -0,0 +1,1420 @@ +//////////////////////////////////////////////////////////////// +// +// AMaZE demosaic algorithm +// (Aliasing Minimization and Zipper Elimination) +// +// copyright (c) 2008-2010 Emil Martinec +// +// incorporating ideas of Luis Sanz Rodrigues and Paul Lee +// +// code dated: May 27, 2010 +// +// amaze_interpolate_RT.cc is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +//////////////////////////////////////////////////////////////// + +#include "rtengine.h" +#include "rawimagesource.h" +#include "rt_math.h" +#include "../rtgui/multilangmgr.h" +#include "procparams.h" +#include "sleef.c" +#include "opthelper.h" + +namespace rtengine { + +SSEFUNCTION void RawImageSource::amaze_demosaic_RT(int winx, int winy, int winw, int winh) { + +#define HCLIP(x) x //is this still necessary??? + //min(clip_pt,x) + + int width=winw, height=winh; + + + const float clip_pt = 1/initialGain; + const float clip_pt8 = 0.8f/initialGain; + + +#define TS 160 // Tile size; the image is processed in square tiles to lower memory requirements and facilitate multi-threading +#define TSH 80 // half of Tile size + + // local variables + + + //offset of R pixel within a Bayer quartet + int ex, ey; + + //shifts of pointer value to access pixels in vertical and diagonal directions + static const int v1=TS, v2=2*TS, v3=3*TS, p1=-TS+1, p2=-2*TS+2, p3=-3*TS+3, m1=TS+1, m2=2*TS+2, m3=3*TS+3; + + //tolerance to avoid dividing by zero + static const float eps=1e-5, epssq=1e-10; //tolerance to avoid dividing by zero + + //adaptive ratios threshold + static const float arthresh=0.75; + //nyquist texture test threshold + static const float nyqthresh=0.5; + + //gaussian on 5x5 quincunx, sigma=1.2 + static const float gaussodd[4] = {0.14659727707323927f, 0.103592713382435f, 0.0732036125103057f, 0.0365543548389495f}; + //gaussian on 5x5, sigma=1.2 + static const float gaussgrad[6] = {0.07384411893421103f, 0.06207511968171489f, 0.0521818194747806f, + 0.03687419286733595f, 0.03099732204057846f, 0.018413194161458882f}; + //gaussian on 5x5 alt quincunx, sigma=1.5 + static const float gausseven[2] = {0.13719494435797422f, 0.05640252782101291f}; + //guassian on quincunx grid + static const float gquinc[4] = {0.169917f, 0.108947f, 0.069855f, 0.0287182f}; + + volatile double progress = 0.0; + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +// Issue 1676 +// Moved from inside the parallel section + if (plistener) { + plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::amaze])); + plistener->setProgress (0.0); + } + struct s_hv { + float h; + float v; + }; + +#pragma omp parallel +{ + int progresscounter=0; + //position of top/left corner of the tile + int top, left; + // beginning of storage block for tile + char *buffer; + // green values + float (*rgbgreen); + + // sum of square of horizontal gradient and square of vertical gradient + float (*delhvsqsum); + // gradient based directional weights for interpolation + float (*dirwts0); + float (*dirwts1); + + // vertically interpolated color differences G-R, G-B + float (*vcd); + // horizontally interpolated color differences + float (*hcd); + // alternative vertical interpolation + float (*vcdalt); + // alternative horizontal interpolation + float (*hcdalt); + // square of average color difference + float (*cddiffsq); + // weight to give horizontal vs vertical interpolation + float (*hvwt); + // final interpolated color difference + float (*Dgrb)[TS*TSH]; +// float (*Dgrb)[2]; + // gradient in plus (NE/SW) direction + float (*delp); + // gradient in minus (NW/SE) direction + float (*delm); + // diagonal interpolation of R+B + float (*rbint); + // horizontal and vertical curvature of interpolated G (used to refine interpolation in Nyquist texture regions) + s_hv (*Dgrb2); + // difference between up/down interpolations of G + float (*dgintv); + // difference between left/right interpolations of G + float (*dginth); + // diagonal (plus) color difference R-B or G1-G2 +// float (*Dgrbp1); + // diagonal (minus) color difference R-B or G1-G2 +// float (*Dgrbm1); + float (*Dgrbsq1m); + float (*Dgrbsq1p); +// s_mp (*Dgrbsq1); + // square of diagonal color difference +// float (*Dgrbpsq1); + // square of diagonal color difference +// float (*Dgrbmsq1); + // tile raw data + float (*cfa); + // relative weight for combining plus and minus diagonal interpolations + float (*pmwt); + // interpolated color difference R-B in minus and plus direction + float (*rbm); + float (*rbp); + + // nyquist texture flag 1=nyquist, 0=not nyquist + char (*nyquist); + +#define CLF 1 + // assign working space + buffer = (char *) calloc(22*sizeof(float)*TS*TS + sizeof(char)*TS*TSH+23*CLF*64 + 63, 1); + char *data; + data = (char*)( ( uintptr_t(buffer) + uintptr_t(63)) / 64 * 64); + + //merror(buffer,"amaze_interpolate()"); + rgbgreen = (float (*)) data; //pointers to array + delhvsqsum = (float (*)) ((char*)rgbgreen + sizeof(float)*TS*TS + CLF*64); + dirwts0 = (float (*)) ((char*)delhvsqsum + sizeof(float)*TS*TS + CLF*64); + dirwts1 = (float (*)) ((char*)dirwts0 + sizeof(float)*TS*TS + CLF*64); + vcd = (float (*)) ((char*)dirwts1 + sizeof(float)*TS*TS + CLF*64); + hcd = (float (*)) ((char*)vcd + sizeof(float)*TS*TS + CLF*64); + vcdalt = (float (*)) ((char*)hcd + sizeof(float)*TS*TS + CLF*64); + hcdalt = (float (*)) ((char*)vcdalt + sizeof(float)*TS*TS + CLF*64); + cddiffsq = (float (*)) ((char*)hcdalt + sizeof(float)*TS*TS + CLF*64); + hvwt = (float (*)) ((char*)cddiffsq + sizeof(float)*TS*TS + CLF*64); + Dgrb = (float (*)[TS*TSH]) ((char*)hvwt + sizeof(float)*TS*TSH + CLF*64); + delp = (float (*)) ((char*)Dgrb + sizeof(float)*TS*TS + CLF*64); + delm = (float (*)) ((char*)delp + sizeof(float)*TS*TSH + CLF*64); + rbint = (float (*)) ((char*)delm + sizeof(float)*TS*TSH + CLF*64); + Dgrb2 = (s_hv (*)) ((char*)rbint + sizeof(float)*TS*TSH + CLF*64); + dgintv = (float (*)) ((char*)Dgrb2 + sizeof(float)*TS*TS + CLF*64); + dginth = (float (*)) ((char*)dgintv + sizeof(float)*TS*TS + CLF*64); + Dgrbsq1m = (float (*)) ((char*)dginth + sizeof(float)*TS*TS + CLF*64); + Dgrbsq1p = (float (*)) ((char*)Dgrbsq1m + sizeof(float)*TS*TSH + CLF*64); + cfa = (float (*)) ((char*)Dgrbsq1p + sizeof(float)*TS*TSH + CLF*64); + pmwt = (float (*)) ((char*)cfa + sizeof(float)*TS*TS + CLF*64); + rbm = (float (*)) ((char*)pmwt + sizeof(float)*TS*TSH + CLF*64); + rbp = (float (*)) ((char*)rbm + sizeof(float)*TS*TSH + CLF*64); + + nyquist = (char (*)) ((char*)rbp + sizeof(float)*TS*TSH + CLF*64); +#undef CLF + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + //determine GRBG coset; (ey,ex) is the offset of the R subarray + if (FC(0,0)==1) {//first pixel is G + if (FC(0,1)==0) {ey=0; ex=1;} else {ey=1; ex=0;} + } else {//first pixel is R or B + if (FC(0,0)==0) {ey=0; ex=0;} else {ey=1; ex=1;} + } + + // Main algorithm: Tile loop + //#pragma omp parallel for shared(rawData,height,width,red,green,blue) private(top,left) schedule(dynamic) + //code is openmp ready; just have to pull local tile variable declarations inside the tile loop + +// Issue 1676 +// use collapse(2) to collapse the 2 loops to one large loop, so there is better scaling +#pragma omp for schedule(dynamic) collapse(2) nowait + for (top=winy-16; top < winy+height; top += TS-32) + for (left=winx-16; left < winx+width; left += TS-32) { + memset(nyquist, 0, sizeof(char)*TS*TSH); + memset(rbint, 0, sizeof(float)*TS*TSH); + //location of tile bottom edge + int bottom = min(top+TS,winy+height+16); + //location of tile right edge + int right = min(left+TS, winx+width+16); + //tile width (=TS except for right edge of image) + int rr1 = bottom - top; + //tile height (=TS except for bottom edge of image) + int cc1 = right - left; + + //tile vars + //counters for pixel location in the image + int row, col; + //min and max row/column in the tile + int rrmin, rrmax, ccmin, ccmax; + //counters for pixel location within the tile + int rr, cc; + //color index 0=R, 1=G, 2=B + int c; + //pointer counters within the tile + int indx, indx1; + //dummy indices + int i, j; + + //color ratios in up/down/left/right directions + float cru, crd, crl, crr; + //adaptive weights for vertical/horizontal/plus/minus directions + float vwt, hwt, pwt, mwt; + //vertical and horizontal G interpolations + float Gintv, Ginth; + //G interpolated in vert/hor directions using adaptive ratios + float guar, gdar, glar, grar; + //G interpolated in vert/hor directions using Hamilton-Adams method + float guha, gdha, glha, grha; + //interpolated G from fusing left/right or up/down + float Ginthar, Ginthha, Gintvar, Gintvha; + //color difference (G-R or G-B) variance in up/down/left/right directions + float Dgrbvvaru, Dgrbvvard, Dgrbhvarl, Dgrbhvarr; + + float uave, dave, lave, rave; + + //color difference variances in vertical and horizontal directions + float vcdvar, hcdvar, vcdvar1, hcdvar1, hcdaltvar, vcdaltvar; + //adaptive interpolation weight using variance of color differences + float varwt; // 639 - 644 + //adaptive interpolation weight using difference of left-right and up-down G interpolations + float diffwt; // 640 - 644 + //alternative adaptive weight for combining horizontal/vertical interpolations + float hvwtalt; // 745 - 748 + //interpolation of G in four directions + float gu, gd, gl, gr; + //variance of G in vertical/horizontal directions + float gvarh, gvarv; + + //Nyquist texture test + float nyqtest; // 658 - 681 + //accumulators for Nyquist texture interpolation + float sumh, sumv, sumsqh, sumsqv, areawt; + + //color ratios in diagonal directions + float crse, crnw, crne, crsw; + //color differences in diagonal directions + float rbse, rbnw, rbne, rbsw; + //adaptive weights for combining diagonal interpolations + float wtse, wtnw, wtsw, wtne; + //alternate weight for combining diagonal interpolations + float pmwtalt; // 885 - 888 + //variance of R-B in plus/minus directions + float rbvarm; // 843 - 848 + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + // rgb from input CFA data + // rgb values should be floating point number between 0 and 1 + // after white balance multipliers are applied + // a 16 pixel border is added to each side of the image + + // bookkeeping for borders + if (top(winy+height)) {rrmax=winy+height-top;} else {rrmax=rr1;} + if (right>(winx+width)) {ccmax=winx+width-left;} else {ccmax=cc1;} + +#ifdef __SSE2__ + const __m128 c65535v = _mm_set1_ps( 65535.0f ); + __m128 tempv; + for (rr=rrmin; rr < rrmax; rr++){ + for (row=rr+top, cc=ccmin; cc < ccmax-3; cc+=4) { + indx1=rr*TS+cc; + tempv = LVFU(rawData[row][cc+left]) / c65535v; + _mm_store_ps( &cfa[indx1], tempv ); + _mm_store_ps( &rgbgreen[indx1], tempv ); + } + for (; cc < ccmax; cc++) { + indx1=rr*TS+cc; + cfa[indx1] = (rawData[row][cc+left])/65535.0f; + if(FC(rr,cc)==1) + rgbgreen[indx1] = cfa[indx1]; + + } + + } + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + //fill borders + if (rrmin>0) { + for (rr=0; rr<16; rr++) + for (cc=ccmin,row = 32-rr+top; cc0) { + for (rr=rrmin; rr0 && ccmin>0) { + for (rr=0; rr<16; rr++) + for (cc=0; cc<16; cc+=4) { + indx1 = (rr)*TS+cc; + tempv = LVFU(rawData[winy+32-rr][winx+32-cc]) / c65535v; + _mm_store_ps( &cfa[indx1], tempv ); + _mm_store_ps( &rgbgreen[indx1], tempv ); + } + } + if (rrmax0 && ccmax0) { + for (rr=0; rr<16; rr++) + for (cc=0; cc<16; cc++) { + cfa[(rrmax+rr)*TS+cc] = (rawData[(winy+height-rr-2)][(winx+32-cc)])/65535.0f; + if(FC(rr,cc)==1) + rgbgreen[(rrmax+rr)*TS+cc] = cfa[(rrmax+rr)*TS+cc]; + } + } + +#else + for (rr=rrmin; rr < rrmax; rr++) + for (row=rr+top, cc=ccmin; cc < ccmax; cc++) { + indx1=rr*TS+cc; + cfa[indx1] = (rawData[row][cc+left])/65535.0f; + if(FC(rr,cc)==1) + rgbgreen[indx1] = cfa[indx1]; + + } + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + //fill borders + if (rrmin>0) { + for (rr=0; rr<16; rr++) + for (cc=ccmin,row = 32-rr+top; cc0) { + for (rr=rrmin; rr0 && ccmin>0) { + for (rr=0; rr<16; rr++) + for (cc=0; cc<16; cc++) { + cfa[(rr)*TS+cc] = (rawData[winy+32-rr][winx+32-cc])/65535.0f; + if(FC(rr,cc)==1) + rgbgreen[(rr)*TS+cc] = cfa[(rr)*TS+cc]; + } + } + if (rrmax0 && ccmax0) { + for (rr=0; rr<16; rr++) + for (cc=0; cc<16; cc++) { + cfa[(rrmax+rr)*TS+cc] = (rawData[(winy+height-rr-2)][(winx+32-cc)])/65535.0f; + if(FC(rr,cc)==1) + rgbgreen[(rrmax+rr)*TS+cc] = cfa[(rrmax+rr)*TS+cc]; + } + } +#endif + + //end of border fill + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +#ifdef __SSE2__ + __m128 delhv,delvv; + const __m128 epsv = _mm_set1_ps( eps ); + + for (rr=2; rr < rr1-2; rr++) { + for (cc=0, indx=(rr)*TS+cc; cc < cc1; cc+=4, indx+=4) { + delhv = vabsf( LVFU( cfa[indx+1] ) - LVFU( cfa[indx-1] ) ); + delvv = vabsf( LVF( cfa[indx+v1] ) - LVF( cfa[indx-v1] ) ); + _mm_store_ps( &dirwts1[indx], epsv + vabsf( LVFU( cfa[indx+2] ) - LVF( cfa[indx] )) + vabsf( LVF( cfa[indx] ) - LVFU( cfa[indx-2] )) + delhv ); + delhv = delhv * delhv; + _mm_store_ps( &dirwts0[indx], epsv + vabsf( LVF( cfa[indx+v2] ) - LVF( cfa[indx] )) + vabsf( LVF( cfa[indx] ) - LVF( cfa[indx-v2] )) + delvv ); + delvv = delvv * delvv; + _mm_store_ps( &delhvsqsum[indx], delhv + delvv); + } + } +#else + // horizontal and vedrtical gradient + float delh,delv; + for (rr=2; rr < rr1-2; rr++) + for (cc=2, indx=(rr)*TS+cc; cc < cc1-2; cc++, indx++) { + delh = fabsf(cfa[indx+1]-cfa[indx-1]); + delv = fabsf(cfa[indx+v1]-cfa[indx-v1]); + dirwts0[indx] = eps+fabsf(cfa[indx+v2]-cfa[indx])+fabsf(cfa[indx]-cfa[indx-v2])+delv; + dirwts1[indx] = eps+fabsf(cfa[indx+2]-cfa[indx])+fabsf(cfa[indx]-cfa[indx-2])+delh;//+fabsf(cfa[indx+2]-cfa[indx-2]); + delhvsqsum[indx] = SQR(delh) + SQR(delv); + } +#endif + +#ifdef __SSE2__ + __m128 Dgrbsq1pv, Dgrbsq1mv,temp2v; + for (rr=6; rr < rr1-6; rr++){ + if((FC(rr,2)&1)==0) { + for (cc=6, indx=(rr)*TS+cc; cc < cc1-6; cc+=8, indx+=8) { + tempv = LC2VFU(cfa[indx+1]); + Dgrbsq1pv = (SQRV(tempv-LC2VFU(cfa[indx+1-p1]))+SQRV(tempv-LC2VFU(cfa[indx+1+p1]))); + _mm_storeu_ps( &delp[indx>>1], vabsf(LC2VFU(cfa[indx+p1])-LC2VFU(cfa[indx-p1]))); + _mm_storeu_ps( &delm[indx>>1], vabsf(LC2VFU(cfa[indx+m1])-LC2VFU(cfa[indx-m1]))); + Dgrbsq1mv = (SQRV(tempv-LC2VFU(cfa[indx+1-m1]))+SQRV(tempv-LC2VFU(cfa[indx+1+m1]))); + _mm_storeu_ps( &Dgrbsq1m[indx>>1], Dgrbsq1mv ); + _mm_storeu_ps( &Dgrbsq1p[indx>>1], Dgrbsq1pv ); + } + } + else { + for (cc=6, indx=(rr)*TS+cc; cc < cc1-6; cc+=8, indx+=8) { + tempv = LC2VFU(cfa[indx]); + Dgrbsq1pv = (SQRV(tempv-LC2VFU(cfa[indx-p1]))+SQRV(tempv-LC2VFU(cfa[indx+p1]))); + _mm_storeu_ps( &delp[indx>>1], vabsf(LC2VFU(cfa[indx+1+p1])-LC2VFU(cfa[indx+1-p1]))); + _mm_storeu_ps( &delm[indx>>1], vabsf(LC2VFU(cfa[indx+1+m1])-LC2VFU(cfa[indx+1-m1]))); + Dgrbsq1mv = (SQRV(tempv-LC2VFU(cfa[indx-m1]))+SQRV(tempv-LC2VFU(cfa[indx+m1]))); + _mm_storeu_ps( &Dgrbsq1m[indx>>1], Dgrbsq1mv ); + _mm_storeu_ps( &Dgrbsq1p[indx>>1], Dgrbsq1pv ); + } + } + } +#else + for (rr=6; rr < rr1-6; rr++){ + if((FC(rr,2)&1)==0) { + for (cc=6, indx=(rr)*TS+cc; cc < cc1-6; cc+=2, indx+=2) { + delp[indx>>1] = fabsf(cfa[indx+p1]-cfa[indx-p1]); + delm[indx>>1] = fabsf(cfa[indx+m1]-cfa[indx-m1]); + Dgrbsq1p[indx>>1]=(SQR(cfa[indx+1]-cfa[indx+1-p1])+SQR(cfa[indx+1]-cfa[indx+1+p1])); + Dgrbsq1m[indx>>1]=(SQR(cfa[indx+1]-cfa[indx+1-m1])+SQR(cfa[indx+1]-cfa[indx+1+m1])); + } + } + else { + for (cc=6, indx=(rr)*TS+cc; cc < cc1-6; cc+=2, indx+=2) { + Dgrbsq1p[indx>>1]=(SQR(cfa[indx]-cfa[indx-p1])+SQR(cfa[indx]-cfa[indx+p1])); + Dgrbsq1m[indx>>1]=(SQR(cfa[indx]-cfa[indx-m1])+SQR(cfa[indx]-cfa[indx+m1])); + delp[indx>>1] = fabsf(cfa[indx+1+p1]-cfa[indx+1-p1]); + delm[indx>>1] = fabsf(cfa[indx+1+m1]-cfa[indx+1-m1]); + } + } + } +#endif + + // end of tile initialization + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + //interpolate vertical and horizontal color differences + +#ifdef __SSE2__ + __m128 sgnv,cruv,crdv,crlv,crrv,guhav,gdhav,glhav,grhav,hwtv,vwtv,Gintvhav,Ginthhav,guarv,gdarv,glarv,grarv; + vmask clipmask; + if( !(FC(4,4)&1) ) + sgnv = _mm_set_ps( 1.0f, -1.0f, 1.0f, -1.0f ); + else + sgnv = _mm_set_ps( -1.0f, 1.0f, -1.0f, 1.0f ); + + __m128 zd5v = _mm_set1_ps( 0.5f ); + __m128 onev = _mm_set1_ps( 1.0f ); + __m128 arthreshv = _mm_set1_ps( arthresh ); + __m128 clip_pt8v = _mm_set1_ps( clip_pt8 ); + + for (rr=4; rr clip_pt8 || Gintvha > clip_pt8 || Ginthha > clip_pt8) { + //use HA if highlights are (nearly) clipped + guar=guha; gdar=gdha; glar=glha; grar=grha; + vcd[indx]=vcdalt[indx]; hcd[indx]=hcdalt[indx]; + } + + //differences of interpolations in opposite directions + dgintv[indx]=min(SQR(guha-gdha),SQR(guar-gdar)); + dginth[indx]=min(SQR(glha-grha),SQR(glar-grar)); + + } + + + } +#endif + +#ifdef __SSE2__ + __m128 hcdvarv, vcdvarv; + __m128 hcdaltvarv,vcdaltvarv,hcdv,vcdv,hcdaltv,vcdaltv,sgn3v,Ginthv,Gintvv,hcdoldv,vcdoldv; + __m128 threev = _mm_set1_ps( 3.0f ); + __m128 clip_ptv = _mm_set1_ps( clip_pt ); + __m128 nsgnv; + vmask hcdmask, vcdmask,tempmask; + + if( !(FC(4,4)&1) ) + sgnv = _mm_set_ps( 1.0f, -1.0f, 1.0f, -1.0f ); + else + sgnv = _mm_set_ps( -1.0f, 1.0f, -1.0f, 1.0f ); + + sgn3v = threev * sgnv; + for (rr=4; rr0) { + if (3.0f*hcd[indx] > (Ginth+cfa[indx])) { + hcd[indx]=-ULIM(Ginth,cfa[indx-1],cfa[indx+1])+cfa[indx]; + } else { + hwt = 1.0f -3.0f*hcd[indx]/(eps+Ginth+cfa[indx]); + hcd[indx]=hwt*hcd[indx] + (1.0f-hwt)*(-ULIM(Ginth,cfa[indx-1],cfa[indx+1])+cfa[indx]); + } + } + if (vcd[indx]>0) { + if (3.0f*vcd[indx] > (Gintv+cfa[indx])) { + vcd[indx]=-ULIM(Gintv,cfa[indx-v1],cfa[indx+v1])+cfa[indx]; + } else { + vwt = 1.0f -3.0f*vcd[indx]/(eps+Gintv+cfa[indx]); + vcd[indx]=vwt*vcd[indx] + (1.0f-vwt)*(-ULIM(Gintv,cfa[indx-v1],cfa[indx+v1])+cfa[indx]); + } + } + + if (Ginth > clip_pt) hcd[indx]=-ULIM(Ginth,cfa[indx-1],cfa[indx+1])+cfa[indx];//for RT implementation + if (Gintv > clip_pt) vcd[indx]=-ULIM(Gintv,cfa[indx-v1],cfa[indx+v1])+cfa[indx]; + //if (Ginth > pre_mul[c]) hcd[indx]=-ULIM(Ginth,cfa[indx-1],cfa[indx+1])+cfa[indx];//for dcraw implementation + //if (Gintv > pre_mul[c]) vcd[indx]=-ULIM(Gintv,cfa[indx-v1],cfa[indx+v1])+cfa[indx]; + + } else {//R or B site + + Ginth = hcd[indx]+cfa[indx];//interpolated G + Gintv = vcd[indx]+cfa[indx]; + + if (hcd[indx]<0) { + if (3.0f*hcd[indx] < -(Ginth+cfa[indx])) { + hcd[indx]=ULIM(Ginth,cfa[indx-1],cfa[indx+1])-cfa[indx]; + } else { + hwt = 1.0f +3.0f*hcd[indx]/(eps+Ginth+cfa[indx]); + hcd[indx]=hwt*hcd[indx] + (1.0f-hwt)*(ULIM(Ginth,cfa[indx-1],cfa[indx+1])-cfa[indx]); + } + } + if (vcd[indx]<0) { + if (3.0f*vcd[indx] < -(Gintv+cfa[indx])) { + vcd[indx]=ULIM(Gintv,cfa[indx-v1],cfa[indx+v1])-cfa[indx]; + } else { + vwt = 1.0f +3.0f*vcd[indx]/(eps+Gintv+cfa[indx]); + vcd[indx]=vwt*vcd[indx] + (1.0f-vwt)*(ULIM(Gintv,cfa[indx-v1],cfa[indx+v1])-cfa[indx]); + } + } + + if (Ginth > clip_pt) hcd[indx]=ULIM(Ginth,cfa[indx-1],cfa[indx+1])-cfa[indx];//for RT implementation + if (Gintv > clip_pt) vcd[indx]=ULIM(Gintv,cfa[indx-v1],cfa[indx+v1])-cfa[indx]; + //if (Ginth > pre_mul[c]) hcd[indx]=ULIM(Ginth,cfa[indx-1],cfa[indx+1])-cfa[indx];//for dcraw implementation + //if (Gintv > pre_mul[c]) vcd[indx]=ULIM(Gintv,cfa[indx-v1],cfa[indx+v1])-cfa[indx]; + cddiffsq[indx] = SQR(vcd[indx]-hcd[indx]); + } + c = !c; + } + } +#endif + +#ifdef __SSE2__ + __m128 uavev,davev,lavev,ravev,Dgrbvvaruv,Dgrbvvardv,Dgrbhvarlv,Dgrbhvarrv,varwtv,diffwtv,vcdvar1v,hcdvar1v; + __m128 epssqv = _mm_set1_ps( epssq ); + vmask decmask; + for (rr=6; rr>1], vself( decmask, varwtv, diffwtv)); + } + } +#else + for (rr=6; rr0 && fabsf(0.5-diffwt)>1]=varwt;} else {hvwt[indx>>1]=diffwt;} + + //hvwt[indx]=varwt; + } + } + +#endif + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // Nyquist test + for (rr=6; rr0) + nyquist[indx>>1]=1;//nyquist=1 for nyquist region + } + + unsigned int nyquisttemp; + for (rr=8; rr>1]+nyquist[(indx-m1)>>1]+nyquist[(indx+p1)>>1]+ + nyquist[(indx-2)>>1]+nyquist[indx>>1]+nyquist[(indx+2)>>1]+ + nyquist[(indx-p1)>>1]+nyquist[(indx+m1)>>1]+nyquist[(indx+v2)>>1]); + //if most of your neighbors are named Nyquist, it's likely that you're one too + if (nyquisttemp>4) nyquist[indx>>1]=1; + //or not + if (nyquisttemp<4) nyquist[indx>>1]=0; + } + } + // end of Nyquist test + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + // in areas of Nyquist texture, do area interpolation + for (rr=8; rr>1]) { + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // area interpolation + + sumh=sumv=sumsqh=sumsqv=areawt=0; + for (i=-6; i<7; i+=2) + for (j=-6; j<7; j+=2) { + indx1=(rr+i)*TS+cc+j; + if (nyquist[indx1>>1]) { + sumh += cfa[indx1]-xdiv2f(cfa[indx1-1]+cfa[indx1+1]); + sumv += cfa[indx1]-xdiv2f(cfa[indx1-v1]+cfa[indx1+v1]); + sumsqh += xdiv2f(SQR(cfa[indx1]-cfa[indx1-1])+SQR(cfa[indx1]-cfa[indx1+1])); + sumsqv += xdiv2f(SQR(cfa[indx1]-cfa[indx1-v1])+SQR(cfa[indx1]-cfa[indx1+v1])); + areawt +=1; + } + } + + //horizontal and vertical color differences, and adaptive weight + hcdvar=epssq+fabsf(areawt*sumsqh-sumh*sumh); + vcdvar=epssq+fabsf(areawt*sumsqv-sumv*sumv); + hvwt[indx>>1]=hcdvar/(vcdvar+hcdvar); + + // end of area interpolation + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + } + } + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + //populate G at R/B sites + for (rr=8; rr>1]+hvwt[(indx+p1)>>1]+hvwt[(indx-p1)>>1]+hvwt[(indx+m1)>>1],2); +// hvwtalt = 0.25*(hvwt[(indx-m1)>>1]+hvwt[(indx+p1)>>1]+hvwt[(indx-p1)>>1]+hvwt[(indx+m1)>>1]); +// vo=fabsf(0.5-hvwt[indx>>1]); +// ve=fabsf(0.5-hvwtalt); + if (fabsf(0.5-hvwt[indx>>1])>1]=hvwtalt;}//a better result was obtained from the neighbors +// if (vo>1]=hvwtalt;}//a better result was obtained from the neighbors + + + + Dgrb[0][indx>>1] = (hcd[indx]*(1.0f-hvwt[indx>>1]) + vcd[indx]*hvwt[indx>>1]);//evaluate color differences + //if (hvwt[indx]<0.5) Dgrb[indx][0]=hcd[indx]; + //if (hvwt[indx]>0.5) Dgrb[indx][0]=vcd[indx]; + rgbgreen[indx] = cfa[indx] + Dgrb[0][indx>>1];//evaluate G (finally!) + + //local curvature in G (preparation for nyquist refinement step) + if (nyquist[indx>>1]) { + Dgrb2[indx>>1].h = SQR(rgbgreen[indx] - xdiv2f(rgbgreen[indx-1]+rgbgreen[indx+1])); + Dgrb2[indx>>1].v = SQR(rgbgreen[indx] - xdiv2f(rgbgreen[indx-v1]+rgbgreen[indx+v1])); + } else { + Dgrb2[indx>>1].h = Dgrb2[indx>>1].v = 0; + } + } + + //end of standard interpolation + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // refine Nyquist areas using G curvatures + + for (rr=8; rr>1]) { + //local averages (over Nyquist pixels only) of G curvature squared + gvarh = epssq + (gquinc[0]*Dgrb2[indx>>1].h+ + gquinc[1]*(Dgrb2[(indx-m1)>>1].h+Dgrb2[(indx+p1)>>1].h+Dgrb2[(indx-p1)>>1].h+Dgrb2[(indx+m1)>>1].h)+ + gquinc[2]*(Dgrb2[(indx-v2)>>1].h+Dgrb2[(indx-2)>>1].h+Dgrb2[(indx+2)>>1].h+Dgrb2[(indx+v2)>>1].h)+ + gquinc[3]*(Dgrb2[(indx-m2)>>1].h+Dgrb2[(indx+p2)>>1].h+Dgrb2[(indx-p2)>>1].h+Dgrb2[(indx+m2)>>1].h)); + gvarv = epssq + (gquinc[0]*Dgrb2[indx>>1].v+ + gquinc[1]*(Dgrb2[(indx-m1)>>1].v+Dgrb2[(indx+p1)>>1].v+Dgrb2[(indx-p1)>>1].v+Dgrb2[(indx+m1)>>1].v)+ + gquinc[2]*(Dgrb2[(indx-v2)>>1].v+Dgrb2[(indx-2)>>1].v+Dgrb2[(indx+2)>>1].v+Dgrb2[(indx+v2)>>1].v)+ + gquinc[3]*(Dgrb2[(indx-m2)>>1].v+Dgrb2[(indx+p2)>>1].v+Dgrb2[(indx-p2)>>1].v+Dgrb2[(indx+m2)>>1].v)); + //use the results as weights for refined G interpolation + Dgrb[0][indx>>1] = (hcd[indx]*gvarv + vcd[indx]*gvarh)/(gvarv+gvarh); + rgbgreen[indx] = cfa[indx] + Dgrb[0][indx>>1]; + } + } + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + // diagonal interpolation correction + +#ifdef __SSE2__ + __m128 rbsev,rbnwv,rbnev,rbswv,cfav,rbmv,rbpv,temp1v,wtv; + __m128 wtsev, wtnwv, wtnev, wtswv, rbvarmv; + __m128 gausseven0v = _mm_set1_ps(gausseven[0]); + __m128 gausseven1v = _mm_set1_ps(gausseven[1]); + __m128 twov = _mm_set1_ps(2.0f); +#endif + for (rr=8; rr>1; cc>1])+LVFU(delm[(indx+m2)>>1]);//same as for wtu,wtd,wtl,wtr + wtnwv= temp1v+LVFU(delm[(indx-m1)>>1])+LVFU(delm[(indx-m2)>>1]); + + rbmv = (wtsev*rbnwv+wtnwv*rbsev)/(wtsev+wtnwv); + + temp1v = ULIMV(rbmv ,LC2VFU(cfa[indx-m1]),LC2VFU(cfa[indx+m1])); + wtv = twov * (cfav-rbmv)/(epsv+rbmv+cfav); + temp2v = wtv * rbmv + (onev-wtv)*temp1v; + + temp2v = vself(vmaskf_lt(rbmv + rbmv, cfav), temp1v, temp2v); + temp2v = vself(vmaskf_lt(rbmv, cfav), temp2v, rbmv); + _mm_storeu_ps(&rbm[indx1], vself(vmaskf_gt(temp2v, clip_ptv), ULIMV(temp2v ,LC2VFU(cfa[indx-m1]),LC2VFU(cfa[indx+m1])), temp2v )); + + + temp1v = LC2VFU(cfa[indx+p1]); + temp2v = LC2VFU(cfa[indx+p2]); + rbnev = (temp1v + temp1v) / (epsv + cfav + temp2v ); + rbnev = vself(vmaskf_lt(vabsf(onev - rbnev), arthreshv), cfav * rbnev, temp1v + zd5v * (cfav - temp2v)); + + temp1v = LC2VFU(cfa[indx-p1]); + temp2v = LC2VFU(cfa[indx-p2]); + rbswv = (temp1v + temp1v) / (epsv + cfav + temp2v ); + rbswv = vself(vmaskf_lt(vabsf(onev - rbswv), arthreshv), cfav * rbswv, temp1v + zd5v * (cfav - temp2v)); + + temp1v = epsv + LVFU(delp[indx1]); + wtnev= temp1v+LVFU(delp[(indx+p1)>>1])+LVFU(delp[(indx+p2)>>1]); + wtswv= temp1v+LVFU(delp[(indx-p1)>>1])+LVFU(delp[(indx-p2)>>1]); + + rbpv = (wtnev*rbswv+wtswv*rbnev)/(wtnev+wtswv); + + temp1v = ULIMV(rbpv ,LC2VFU(cfa[indx-p1]),LC2VFU(cfa[indx+p1])); + wtv = twov * (cfav-rbpv)/(epsv+rbpv+cfav); + temp2v = wtv * rbpv + (onev-wtv)*temp1v; + + temp2v = vself(vmaskf_lt(rbpv + rbpv, cfav), temp1v, temp2v); + temp2v = vself(vmaskf_lt(rbpv, cfav), temp2v, rbpv); + _mm_storeu_ps(&rbp[indx1], vself(vmaskf_gt(temp2v, clip_ptv), ULIMV(temp2v ,LC2VFU(cfa[indx-p1]),LC2VFU(cfa[indx+p1])), temp2v )); + + + + rbvarmv = epssqv + (gausseven0v*(LVFU(Dgrbsq1m[(indx-v1)>>1])+LVFU(Dgrbsq1m[(indx-1)>>1])+LVFU(Dgrbsq1m[(indx+1)>>1])+LVFU(Dgrbsq1m[(indx+v1)>>1])) + + gausseven1v*(LVFU(Dgrbsq1m[(indx-v2-1)>>1])+LVFU(Dgrbsq1m[(indx-v2+1)>>1])+LVFU(Dgrbsq1m[(indx-2-v1)>>1])+LVFU(Dgrbsq1m[(indx+2-v1)>>1])+ + LVFU(Dgrbsq1m[(indx-2+v1)>>1])+LVFU(Dgrbsq1m[(indx+2+v1)>>1])+LVFU(Dgrbsq1m[(indx+v2-1)>>1])+LVFU(Dgrbsq1m[(indx+v2+1)>>1]))); + _mm_storeu_ps(&pmwt[indx1] , rbvarmv/((epssqv + (gausseven0v*(LVFU(Dgrbsq1p[(indx-v1)>>1])+LVFU(Dgrbsq1p[(indx-1)>>1])+LVFU(Dgrbsq1p[(indx+1)>>1])+LVFU(Dgrbsq1p[(indx+v1)>>1])) + + gausseven1v*(LVFU(Dgrbsq1p[(indx-v2-1)>>1])+LVFU(Dgrbsq1p[(indx-v2+1)>>1])+LVFU(Dgrbsq1p[(indx-2-v1)>>1])+LVFU(Dgrbsq1p[(indx+2-v1)>>1])+ + LVFU(Dgrbsq1p[(indx-2+v1)>>1])+LVFU(Dgrbsq1p[(indx+2+v1)>>1])+LVFU(Dgrbsq1p[(indx+v2-1)>>1])+LVFU(Dgrbsq1p[(indx+v2+1)>>1]))))+rbvarmv)); + + } + +#else + for (cc=8+(FC(rr,2)&1),indx=rr*TS+cc,indx1=indx>>1; cc>1]+delm[(indx+m2)>>1];//same as for wtu,wtd,wtl,wtr + wtnw= eps+delm[indx1]+delm[(indx-m1)>>1]+delm[(indx-m2)>>1]; + wtne= eps+delp[indx1]+delp[(indx+p1)>>1]+delp[(indx+p2)>>1]; + wtsw= eps+delp[indx1]+delp[(indx-p1)>>1]+delp[(indx-p2)>>1]; + + + rbm[indx1] = (wtse*rbnw+wtnw*rbse)/(wtse+wtnw); + rbp[indx1] = (wtne*rbsw+wtsw*rbne)/(wtne+wtsw); +/* + rbvarp = epssq + (gausseven[0]*(Dgrbsq1[indx-v1].p+Dgrbsq1[indx-1].p+Dgrbsq1[indx+1].p+Dgrbsq1[indx+v1].p) + + gausseven[1]*(Dgrbsq1[indx-v2-1].p+Dgrbsq1[indx-v2+1].p+Dgrbsq1[indx-2-v1].p+Dgrbsq1[indx+2-v1].p+ + Dgrbsq1[indx-2+v1].p+Dgrbsq1[indx+2+v1].p+Dgrbsq1[indx+v2-1].p+Dgrbsq1[indx+v2+1].p)); +*/ + rbvarm = epssq + (gausseven[0]*(Dgrbsq1m[(indx-v1)>>1]+Dgrbsq1m[(indx-1)>>1]+Dgrbsq1m[(indx+1)>>1]+Dgrbsq1m[(indx+v1)>>1]) + + gausseven[1]*(Dgrbsq1m[(indx-v2-1)>>1]+Dgrbsq1m[(indx-v2+1)>>1]+Dgrbsq1m[(indx-2-v1)>>1]+Dgrbsq1m[(indx+2-v1)>>1]+ + Dgrbsq1m[(indx-2+v1)>>1]+Dgrbsq1m[(indx+2+v1)>>1]+Dgrbsq1m[(indx+v2-1)>>1]+Dgrbsq1m[(indx+v2+1)>>1])); + pmwt[indx1] = rbvarm/((epssq + (gausseven[0]*(Dgrbsq1p[(indx-v1)>>1]+Dgrbsq1p[(indx-1)>>1]+Dgrbsq1p[(indx+1)>>1]+Dgrbsq1p[(indx+v1)>>1]) + + gausseven[1]*(Dgrbsq1p[(indx-v2-1)>>1]+Dgrbsq1p[(indx-v2+1)>>1]+Dgrbsq1p[(indx-2-v1)>>1]+Dgrbsq1p[(indx+2-v1)>>1]+ + Dgrbsq1p[(indx-2+v1)>>1]+Dgrbsq1p[(indx+2+v1)>>1]+Dgrbsq1p[(indx+v2-1)>>1]+Dgrbsq1p[(indx+v2+1)>>1])))+rbvarm); + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + //bound the interpolation in regions of high saturation + if (rbp[indx1] clip_pt) rbp[indx1]=ULIM(rbp[indx1],cfa[indx-p1],cfa[indx+p1]);//for RT implementation + if (rbm[indx1] > clip_pt) rbm[indx1]=ULIM(rbm[indx1],cfa[indx-m1],cfa[indx+m1]); + //c=2-FC(rr,cc);//for dcraw implementation + //if (rbp[indx] > pre_mul[c]) rbp[indx]=ULIM(rbp[indx],cfa[indx-p1],cfa[indx+p1]); + //if (rbm[indx] > pre_mul[c]) rbm[indx]=ULIM(rbm[indx],cfa[indx-m1],cfa[indx+m1]); + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + //rbint[indx] = 0.5*(cfa[indx] + (rbp*rbvarm+rbm*rbvarp)/(rbvarp+rbvarm));//this is R+B, interpolated + } +#endif + } + +#ifdef __SSE2__ + __m128 pmwtaltv; + __m128 zd25v = _mm_set1_ps(0.25f); +#endif + for (rr=10; rr>1; cc>1])+LVFU(pmwt[(indx+p1)>>1])+LVFU(pmwt[(indx-p1)>>1])+LVFU(pmwt[(indx+m1)>>1])); + tempv = LVFU(pmwt[indx1]); + tempv = vself(vmaskf_lt(vabsf(zd5v-tempv), vabsf(zd5v-pmwtaltv)), pmwtaltv, tempv); + _mm_storeu_ps( &pmwt[indx1], tempv); + _mm_storeu_ps( &rbint[indx1], zd5v * (LC2VFU(cfa[indx]) + LVFU(rbm[indx1]) * (onev - tempv) + LVFU(rbp[indx1]) * tempv)); + } + +#else + for (cc=10+(FC(rr,2)&1),indx=rr*TS+cc,indx1=indx>>1; cc>1]+pmwt[(indx+p1)>>1]+pmwt[(indx-p1)>>1]+pmwt[(indx+m1)>>1],2); + if (fabsf(0.5-pmwt[indx1])>1; cc>1])>1]) ) + continue; + + //now interpolate G vertically/horizontally using R+B values + //unfortunately, since G interpolation cannot be done diagonally this may lead to color shifts + //color ratios for G interpolation + + cru = cfa[indx-v1]*2.0/(eps+rbint[indx1]+rbint[(indx1-v1)]); + crd = cfa[indx+v1]*2.0/(eps+rbint[indx1]+rbint[(indx1+v1)]); + crl = cfa[indx-1]*2.0/(eps+rbint[indx1]+rbint[(indx1-1)]); + crr = cfa[indx+1]*2.0/(eps+rbint[indx1]+rbint[(indx1+1)]); + + //interpolated G via adaptive ratios or Hamilton-Adams in each cardinal direction + if (fabsf(1.0f-cru) clip_pt) Ginth=ULIM(Ginth,cfa[indx-1],cfa[indx+1]);//for RT implementation + if (Gintv > clip_pt) Gintv=ULIM(Gintv,cfa[indx-v1],cfa[indx+v1]); + //c=FC(rr,cc);//for dcraw implementation + //if (Ginth > pre_mul[c]) Ginth=ULIM(Ginth,cfa[indx-1],cfa[indx+1]); + //if (Gintv > pre_mul[c]) Gintv=ULIM(Gintv,cfa[indx-v1],cfa[indx+v1]); + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + rgbgreen[indx] = Ginth*(1.0f-hvwt[indx1]) + Gintv*hvwt[indx1]; + //rgb[indx][1] = 0.5*(rgb[indx][1]+0.25*(rgb[indx-v1][1]+rgb[indx+v1][1]+rgb[indx-1][1]+rgb[indx+1][1])); + Dgrb[0][indx>>1] = rgbgreen[indx]-cfa[indx]; + + //rgb[indx][2-FC(rr,cc)]=2*rbint[indx]-cfa[indx]; + } + //end of diagonal interpolation correction + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + //fancy chrominance interpolation + //(ey,ex) is location of R site + for (rr=13-ey; rr>1; cc>1])-LVFU(Dgrb[c][(indx+m1)>>1]))+vabsf(LVFU(Dgrb[c][(indx-m1)>>1])-LVFU(Dgrb[c][(indx-m3)>>1]))+vabsf(LVFU(Dgrb[c][(indx+m1)>>1])-LVFU(Dgrb[c][(indx-m3)>>1]))); + wtnev=onev/(epsv+vabsf(LVFU(Dgrb[c][(indx+p1)>>1])-LVFU(Dgrb[c][(indx-p1)>>1]))+vabsf(LVFU(Dgrb[c][(indx+p1)>>1])-LVFU(Dgrb[c][(indx+p3)>>1]))+vabsf(LVFU(Dgrb[c][(indx-p1)>>1])-LVFU(Dgrb[c][(indx+p3)>>1]))); + wtswv=onev/(epsv+vabsf(LVFU(Dgrb[c][(indx-p1)>>1])-LVFU(Dgrb[c][(indx+p1)>>1]))+vabsf(LVFU(Dgrb[c][(indx-p1)>>1])-LVFU(Dgrb[c][(indx+m3)>>1]))+vabsf(LVFU(Dgrb[c][(indx+p1)>>1])-LVFU(Dgrb[c][(indx-p3)>>1]))); + wtsev=onev/(epsv+vabsf(LVFU(Dgrb[c][(indx+m1)>>1])-LVFU(Dgrb[c][(indx-m1)>>1]))+vabsf(LVFU(Dgrb[c][(indx+m1)>>1])-LVFU(Dgrb[c][(indx-p3)>>1]))+vabsf(LVFU(Dgrb[c][(indx-m1)>>1])-LVFU(Dgrb[c][(indx+m3)>>1]))); + + //Dgrb[indx][c]=(wtnw*Dgrb[indx-m1][c]+wtne*Dgrb[indx+p1][c]+wtsw*Dgrb[indx-p1][c]+wtse*Dgrb[indx+m1][c])/(wtnw+wtne+wtsw+wtse); + + _mm_storeu_ps(&Dgrb[c][indx>>1], (wtnwv*(oned325v*LVFU(Dgrb[c][(indx-m1)>>1])-zd175v*LVFU(Dgrb[c][(indx-m3)>>1])-zd075v*LVFU(Dgrb[c][(indx-m1-2)>>1])-zd075v*LVFU(Dgrb[c][(indx-m1-v2)>>1]) )+ + wtnev*(oned325v*LVFU(Dgrb[c][(indx+p1)>>1])-zd175v*LVFU(Dgrb[c][(indx+p3)>>1])-zd075v*LVFU(Dgrb[c][(indx+p1+2)>>1])-zd075v*LVFU(Dgrb[c][(indx+p1+v2)>>1]) )+ + wtswv*(oned325v*LVFU(Dgrb[c][(indx-p1)>>1])-zd175v*LVFU(Dgrb[c][(indx-p3)>>1])-zd075v*LVFU(Dgrb[c][(indx-p1-2)>>1])-zd075v*LVFU(Dgrb[c][(indx-p1-v2)>>1]) )+ + wtsev*(oned325v*LVFU(Dgrb[c][(indx+m1)>>1])-zd175v*LVFU(Dgrb[c][(indx+m3)>>1])-zd075v*LVFU(Dgrb[c][(indx+m1+2)>>1])-zd075v*LVFU(Dgrb[c][(indx+m1+v2)>>1]) ))/(wtnwv+wtnev+wtswv+wtsev)); + } + +#else + for (cc=14+(FC(rr,2)&1),indx=rr*TS+cc,c=1-FC(rr,cc)/2; cc>1]-Dgrb[c][(indx+m1)>>1])+fabsf(Dgrb[c][(indx-m1)>>1]-Dgrb[c][(indx-m3)>>1])+fabsf(Dgrb[c][(indx+m1)>>1]-Dgrb[c][(indx-m3)>>1])); + wtne=1.0f/(eps+fabsf(Dgrb[c][(indx+p1)>>1]-Dgrb[c][(indx-p1)>>1])+fabsf(Dgrb[c][(indx+p1)>>1]-Dgrb[c][(indx+p3)>>1])+fabsf(Dgrb[c][(indx-p1)>>1]-Dgrb[c][(indx+p3)>>1])); + wtsw=1.0f/(eps+fabsf(Dgrb[c][(indx-p1)>>1]-Dgrb[c][(indx+p1)>>1])+fabsf(Dgrb[c][(indx-p1)>>1]-Dgrb[c][(indx+m3)>>1])+fabsf(Dgrb[c][(indx+p1)>>1]-Dgrb[c][(indx-p3)>>1])); + wtse=1.0f/(eps+fabsf(Dgrb[c][(indx+m1)>>1]-Dgrb[c][(indx-m1)>>1])+fabsf(Dgrb[c][(indx+m1)>>1]-Dgrb[c][(indx-p3)>>1])+fabsf(Dgrb[c][(indx-m1)>>1]-Dgrb[c][(indx+m3)>>1])); + + //Dgrb[indx][c]=(wtnw*Dgrb[indx-m1][c]+wtne*Dgrb[indx+p1][c]+wtsw*Dgrb[indx-p1][c]+wtse*Dgrb[indx+m1][c])/(wtnw+wtne+wtsw+wtse); + + Dgrb[c][indx>>1]=(wtnw*(1.325f*Dgrb[c][(indx-m1)>>1]-0.175f*Dgrb[c][(indx-m3)>>1]-0.075f*Dgrb[c][(indx-m1-2)>>1]-0.075f*Dgrb[c][(indx-m1-v2)>>1] )+ + wtne*(1.325f*Dgrb[c][(indx+p1)>>1]-0.175f*Dgrb[c][(indx+p3)>>1]-0.075f*Dgrb[c][(indx+p1+2)>>1]-0.075f*Dgrb[c][(indx+p1+v2)>>1] )+ + wtsw*(1.325f*Dgrb[c][(indx-p1)>>1]-0.175f*Dgrb[c][(indx-p3)>>1]-0.075f*Dgrb[c][(indx-p1-2)>>1]-0.075f*Dgrb[c][(indx-p1-v2)>>1] )+ + wtse*(1.325f*Dgrb[c][(indx+m1)>>1]-0.175f*Dgrb[c][(indx+m3)>>1]-0.075f*Dgrb[c][(indx+m1+2)>>1]-0.075f*Dgrb[c][(indx+m1+v2)>>1] ))/(wtnw+wtne+wtsw+wtse); + } +#endif + float temp; + for (rr=16; rr>1])+(1.0f-hvwt[(indx+1)>>1])+(1.0f-hvwt[(indx-1)>>1])+(hvwt[(indx+v1)>>1])); + red[row][col]=65535.0f*(rgbgreen[indx]- ((hvwt[(indx-v1)>>1])*Dgrb[0][(indx-v1)>>1]+(1.0f-hvwt[(indx+1)>>1])*Dgrb[0][(indx+1)>>1]+(1.0f-hvwt[(indx-1)>>1])*Dgrb[0][(indx-1)>>1]+(hvwt[(indx+v1)>>1])*Dgrb[0][(indx+v1)>>1])* + temp); + blue[row][col]=65535.0f*(rgbgreen[indx]- ((hvwt[(indx-v1)>>1])*Dgrb[1][(indx-v1)>>1]+(1.0f-hvwt[(indx+1)>>1])*Dgrb[1][(indx+1)>>1]+(1.0f-hvwt[(indx-1)>>1])*Dgrb[1][(indx-1)>>1]+(hvwt[(indx+v1)>>1])*Dgrb[1][(indx+v1)>>1])* + temp); + + indx++; + col++; + red[row][col]=65535.0f*(rgbgreen[indx]-Dgrb[0][indx>>1]); + blue[row][col]=65535.0f*(rgbgreen[indx]-Dgrb[1][indx>>1]); + } + if(cc1&1) { // width of tile is odd + col = cc + left; + temp = 1.0f/((hvwt[(indx-v1)>>1])+(1.0f-hvwt[(indx+1)>>1])+(1.0f-hvwt[(indx-1)>>1])+(hvwt[(indx+v1)>>1])); + red[row][col]=65535.0f*(rgbgreen[indx]- ((hvwt[(indx-v1)>>1])*Dgrb[0][(indx-v1)>>1]+(1.0f-hvwt[(indx+1)>>1])*Dgrb[0][(indx+1)>>1]+(1.0f-hvwt[(indx-1)>>1])*Dgrb[0][(indx-1)>>1]+(hvwt[(indx+v1)>>1])*Dgrb[0][(indx+v1)>>1])* + temp); + blue[row][col]=65535.0f*(rgbgreen[indx]- ((hvwt[(indx-v1)>>1])*Dgrb[1][(indx-v1)>>1]+(1.0f-hvwt[(indx+1)>>1])*Dgrb[1][(indx+1)>>1]+(1.0f-hvwt[(indx-1)>>1])*Dgrb[1][(indx-1)>>1]+(hvwt[(indx+v1)>>1])*Dgrb[1][(indx+v1)>>1])* + temp); + } + } + else { + for (cc=16,indx=rr*TS+cc,row=rr+top; cc>1]); + blue[row][col]=65535.0f*(rgbgreen[indx]-Dgrb[1][indx>>1]); + + indx++; + col++; + temp = 1.0f/((hvwt[(indx-v1)>>1])+(1.0f-hvwt[(indx+1)>>1])+(1.0f-hvwt[(indx-1)>>1])+(hvwt[(indx+v1)>>1])); + red[row][col]=65535.0f*(rgbgreen[indx]- ((hvwt[(indx-v1)>>1])*Dgrb[0][(indx-v1)>>1]+(1.0f-hvwt[(indx+1)>>1])*Dgrb[0][(indx+1)>>1]+(1.0f-hvwt[(indx-1)>>1])*Dgrb[0][(indx-1)>>1]+(hvwt[(indx+v1)>>1])*Dgrb[0][(indx+v1)>>1])* + temp); + blue[row][col]=65535.0f*(rgbgreen[indx]- ((hvwt[(indx-v1)>>1])*Dgrb[1][(indx-v1)>>1]+(1.0f-hvwt[(indx+1)>>1])*Dgrb[1][(indx+1)>>1]+(1.0f-hvwt[(indx-1)>>1])*Dgrb[1][(indx-1)>>1]+(hvwt[(indx+v1)>>1])*Dgrb[1][(indx+v1)>>1])* + temp); + } + if(cc1&1) { // width of tile is odd + col = cc + left; + red[row][col]=65535.0f*(rgbgreen[indx]-Dgrb[0][indx>>1]); + blue[row][col]=65535.0f*(rgbgreen[indx]-Dgrb[1][indx>>1]); + } + } + } + + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + // copy smoothed results back to image matrix + for (rr=16; rr < rr1-16; rr++){ +#ifdef __SSE2__ + for (row=rr+top, cc=16; cc < cc1-19; cc+=4) { + _mm_storeu_ps(&green[row][cc + left], LVF(rgbgreen[rr*TS+cc]) * c65535v); + } +#else + for (row=rr+top, cc=16; cc < cc1-16; cc++) { + col = cc + left; + indx=rr*TS+cc; + green[row][col] = ((65535.0f*rgbgreen[indx])); + + //for dcraw implementation + //for (c=0; c<3; c++){ + // image[indx][c] = CLIP((int)(65535.0f*rgb[rr*TS+cc][c] + 0.5f)); + //} + } +#endif + } + //end of main loop + + if(plistener) { + progresscounter++; + if(progresscounter % 4 == 0) { +#pragma omp critical +{ + progress+=(double)4*((TS-32)*(TS-32))/(height*width); + if (progress>1.0) + { + progress=1.0; + } + plistener->setProgress(progress); +} + } + } + } + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + + // clean up + free(buffer); +} + if(plistener) + plistener->setProgress(1.0); + + + // done + +#undef TS + +} +} diff --git a/rtengine/array2D.h b/rtengine/array2D.h new file mode 100644 index 000000000..b80f1d1e8 --- /dev/null +++ b/rtengine/array2D.h @@ -0,0 +1,271 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2011 Jan Rinze Peterzon (janrinze@gmail.com) + * + * RawTherapee is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * RawTherapee is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ + +/* + * Declaration of flexible 2D arrays + * + * Usage: + * + * array2D name (X-size,Y-size); + * array2D name (X-size,Y-size type ** data); + * + * creates an array which is valid within the normal C/C++ scope "{ ... }" + * + * access to elements is a simple as: + * + * array2D my_array (10,10); // creates 10x10 array of floats + * value = my_array[3][5]; + * my_array[4][6]=value; + * + * or copy an existing 2D array + * + * float ** mydata; + * array2D my_array (10,10,mydata); + * + * + * Useful extra pointers + * + * ** my_array gives access to the pointer for access with [][] + * * my_array gives access to the flat stored data. + * + * Advanced usage: + * array2D my_array ; // empty container. + * my_array(10,10) ; // resize to 10x10 array + * my_array(10,10,ARRAY2D_CLEAR_DATA) ; // resize to 10x10 and clear data + * my_array(10,10,ARRAY2D_CLEAR_DATA|ARRAY2D_LOCK_DATA) ; same but set a lock on changes + * + * !! locked arrays cannot be resized and cannot be unlocked again !! + */ +#ifndef ARRAY2D_H_ +#define ARRAY2D_H_ +#include // for raise() +#include + +// flags for use +#define ARRAY2D_LOCK_DATA 1 +#define ARRAY2D_CLEAR_DATA 2 +#define ARRAY2D_BYREFERENCE 4 +#define ARRAY2D_VERBOSE 8 + +#include +#include + +template +class array2D { + +private: + int x, y, owner, flags; + T ** ptr; + T * data; + bool lock; // useful lock to ensure data is not changed anymore. + void ar_realloc(int w, int h) { + if ((ptr) && ((h > y) || (4 * h < y))) { + delete[] ptr; + ptr = NULL; + } + if ((data) && (((h * w) > (x * y)) || ((h * w) < ((x * y) / 4)))) { + delete[] data; + data = NULL; + } + if (ptr == NULL) + ptr = new T*[h]; + if (data == NULL) + data = new T[h * w]; + + x = w; + y = h; + for (int i = 0; i < h; i++) + ptr[i] = data + w * i; + owner = 1; + } +public: + + // use as empty declaration, resize before use! + // very useful as a member object + array2D() : + x(0), y(0), owner(0), ptr(NULL), data(NULL), lock(0) { + //printf("got empty array2D init\n"); + } + + // creator type1 + array2D(int w, int h, unsigned int flgs = 0) { + flags = flgs; + lock = flags & ARRAY2D_LOCK_DATA; + data = new T[h * w]; + owner = 1; + x = w; + y = h; + ptr = new T*[h]; + for (int i = 0; i < h; i++) + ptr[i] = data + i * w; + if (flags & ARRAY2D_CLEAR_DATA) + memset(data, 0, w * h * sizeof(T)); + } + + // creator type 2 + array2D(int w, int h, T ** source, unsigned int flgs = 0) { + flags = flgs; + //if (lock) { printf("array2D attempt to overwrite data\n");raise(SIGSEGV);} + lock |= flags & ARRAY2D_LOCK_DATA; + // when by reference + // TODO: improve this code with ar_realloc() + owner = (flags & ARRAY2D_BYREFERENCE) ? 0 : 1; + if (owner) + data = new T[h * w]; + else + data = NULL; + x = w; + y = h; + ptr = new T*[h]; + for (int i = 0; i < h; i++) { + if (owner) { + ptr[i] = data + i * w; + for (int j = 0; j < w; j++) + ptr[i][j] = source[i][j]; + } else + ptr[i] = source[i]; + } + } + + // destructor + ~array2D() { + + if (flags & ARRAY2D_VERBOSE) + printf(" deleting array2D size %dx%d \n", x, y); + + if ((owner) && (data)) + delete[] data; + if (ptr) + delete[] ptr; + } + + // use with indices + T * operator[](int index) { + assert((index>=0) && (index < y)); + return ptr[index]; + } + + // use as pointer to T** + operator T**() { + return ptr; + } + + // use as pointer to data + operator T*() { + // only if owner this will return a valid pointer + return data; + } + + + // useful within init of parent object + // or use as resize of 2D array + void operator()(int w, int h, unsigned int flgs = 0) { + flags = flgs; + if (flags & ARRAY2D_VERBOSE) { + printf("got init request %dx%d flags=%u\n", w, h, flags); + printf("previous was data %p ptr %p \n", data, ptr); + } + if (lock) // our object was locked so don't allow a change. + { + printf("got init request but object was locked!\n"); + raise( SIGSEGV); + } + lock = flags & ARRAY2D_LOCK_DATA; + + ar_realloc(w,h); + if (flags & ARRAY2D_CLEAR_DATA) + memset(data, 0, w * h * sizeof(T)); + } + + // import from flat data + void operator()(int w, int h, T* copy, unsigned int flgs = 0) { + flags = flgs; + if (flags & ARRAY2D_VERBOSE) { + printf("got init request %dx%d flags=%u\n", w, h, flags); + printf("previous was data %p ptr %p \n", data, ptr); + } + if (lock) // our object was locked so don't allow a change. + { + printf("got init request but object was locked!\n"); + raise( SIGSEGV); + } + lock = flags & ARRAY2D_LOCK_DATA; + + ar_realloc(w,h); + memcpy(data, copy, w * h * sizeof(T)); + } + int width() { + return x; + } + int height() { + return y; + } + + operator bool() { + return (x > 0 && y > 0); + } + + array2D & operator=( array2D & rhs) { + if (this != &rhs) + + { + if (!owner) // we can only copy same size data + { + if ((x != rhs.x) || (y != rhs.y)) { + printf(" assignment error in array2D\n"); + printf(" sizes differ and not owner\n"); + raise( SIGSEGV); + } + + } else { + ar_realloc(rhs.x, rhs.y); + } + // we could have been created from a different + // array format where each row is created by 'new' + for (int i=0;i +class multi_array2D { +private: + array2D list[num]; + +public: + multi_array2D(int x, int y, int flags = 0) { + for (size_t i = 0; i < num; i++) + list[i](x, y, flags); + } + + ~multi_array2D() { + //printf("trying to delete the list of array2D objects\n"); + } + + array2D & operator[](int index) { + if (static_cast(index) >= num) { + printf("index %0u is out of range[0..%0lu]", index, num - 1); + raise( SIGSEGV); + } + return list[index]; + } +}; +#endif /* array2D_H_ */ diff --git a/rtengine/bilateral2.h b/rtengine/bilateral2.h new file mode 100644 index 000000000..1743965a0 --- /dev/null +++ b/rtengine/bilateral2.h @@ -0,0 +1,526 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _BILATERAL2_ +#define _BILATERAL2_ + +#include +#include +#include +#include + +#include "rtengine.h" +#include "rt_math.h" +#include "alignedbuffer.h" +#include "mytime.h" +#include "gauss.h" + +#include "array2D.h" +#ifdef _OPENMP +#include +#endif + +using namespace rtengine; + +// This seems ugly, but way faster than any other solutions I tried +#define ELEM(a,b) (src[i - a][j - b] * ec[src[i - a][j - b]-src[i][j]+65536.0f]) +#define SULY(a,b) (ec[src[i - a][j - b]-src[i][j]+65536.0f]) +//#define SULY(a,b) (ec[((int)(src[i - a][j - b]-src[i][j]+0x10000))]) +#define BL_BEGIN(a,b) double scale = (a); \ + LUTf ec (0x20000); \ + for (int i=0; i<0x20000; i++) \ + ec[i] = (exp(-(double)(i-0x10000)*(double)(i-0x10000) / (2.0*sens*sens))*scale); \ + int rstart = b; \ + int rend = H-b; \ + int cstart = b; \ + int cend = W-b; + +#define BL_FREE buffer[i][j] = v; }}; +#define BL_END(b) for (int i=0; i=rend || j>=cend) \ + dst[i][j] = src[i][j]; \ + else \ + dst[i][j] = buffer[i][j]; + +#define BL_OPER3(a11,a12,a21,a22) for (int i=rstart; i void bilateral05 (T** src, T** dst, T** buffer, int W, int H, double sens, bool multiThread) { + + BL_BEGIN(318,1) + #pragma omp for + BL_OPER3(1,7,7,55) + BL_FREE +#pragma omp for + BL_END(1) +} + +// sigma = 0.6 +template void bilateral06 (T** src, T** dst, T** buffer, int W, int H, double sens, bool multiThread) { + + BL_BEGIN(768,1) + #pragma omp for + BL_OPER3(1,4,4,16) + BL_FREE +#pragma omp for + BL_END(1) +} + +// sigma = 0.7 +template void bilateral07 (T** src, T** dst, T** buffer, int W, int H, double sens, bool multiThread) { + + BL_BEGIN(366,2) + #pragma omp for + BL_OPER5(0,0,1,0,8,21,1,21,59) + BL_FREE +#pragma omp for + BL_END(2) +} + +// sigma = 0.8 +template void bilateral08 (T** src, T** dst, T** buffer, int W, int H, double sens, bool multiThread) { + + BL_BEGIN(753,2) + #pragma omp for + BL_OPER5(0,0,1,0,5,10,1,10,23) + BL_FREE +#pragma omp for + BL_END(2) +} + +// sigma = 0.9 +template void bilateral09 (T** src, T** dst, T** buffer, int W, int H, double sens, bool multiThread) { + + BL_BEGIN(595,2) + #pragma omp for + BL_OPER5(0,1,2,1,6,12,2,12,22) + BL_FREE +#pragma omp for + BL_END(2) +} + +// sigma = 1.0 +template void bilateral10 (T** src, T** dst, T** buffer, int W, int H, double sens, bool multiThread) { + + BL_BEGIN(910,2) + #pragma omp for + BL_OPER5(0,1,2,1,4,7,2,7,12) + BL_FREE +#pragma omp for + BL_END(2) +} + +// sigma = 1.1 +template void bilateral11 (T** src, T** dst, T** buffer, int W, int H, double sens, bool multiThread) { + + BL_BEGIN(209,3) + #pragma omp for + BL_OPER7(0,0,1,1,0,2,5,8,1,5,18,27,1,8,27,41) + BL_FREE +#pragma omp for + BL_END(3) +} + +// sigma = 1.2 +template void bilateral12 (T** src, T** dst, T** buffer, int W, int H, double sens, bool multiThread) { + + BL_BEGIN(322,3) + #pragma omp for + BL_OPER7(0,0,1,1,0,1,4,6,1,4,11,16,1,6,16,23) + BL_FREE +#pragma omp for + BL_END(3) +} + +// sigma = 1.3 +template void bilateral13 (T** src, T** dst, T** buffer, int W, int H, double sens, bool multiThread) { + + BL_BEGIN(336,3) + #pragma omp for + BL_OPER7(0,0,1,1,0,2,4,6,1,4,11,14,1,6,14,19) + BL_FREE +#pragma omp for + BL_END(3) +} + +// sigma = 1.4 +template void bilateral14 (T** src, T** dst, T** buffer, int W, int H, double sens, bool multiThread) { + + BL_BEGIN(195,3) + #pragma omp for + BL_OPER7(0,1,2,3,1,4,8,10,2,8,17,21,3,10,21,28) + BL_FREE +#pragma omp for + BL_END(3) +} + +// sigma = 1.5 +template void bilateral15 (T** src, T** dst, T** buffer, int W, int H, double sens, bool multiThread) { + + BL_BEGIN(132,4) + #pragma omp for + BL_OPER9(0,0,0,1,1,0,1,2,4,5,0,2,6,12,14,1,4,12,22,28,1,5,14,28,35) + BL_FREE +#pragma omp for + BL_END(4) +} + +// sigma = 1.6 +template void bilateral16 (T** src, T** dst, T** buffer, int W, int H, double sens, bool multiThread) { + + BL_BEGIN(180,4) + #pragma omp for + BL_OPER9(0,0,0,1,1,0,1,2,3,4,0,2,5,9,10,1,3,9,15,19,1,4,10,19,23) + BL_FREE +#pragma omp for + BL_END(4) +} + +// sigma = 1.7 +template void bilateral17 (T** src, T** dst, T** buffer, int W, int H, double sens, bool multiThread) { + + BL_BEGIN(195,4) + #pragma omp for + BL_OPER9(0,0,1,1,1,0,1,2,3,4,1,2,5,8,9,1,3,8,13,16,1,4,9,16,19) + BL_FREE +#pragma omp for + BL_END(4) +} + +// sigma = 1.8 +template void bilateral18 (T** src, T** dst, T** buffer, int W, int H, double sens, bool multiThread) { + + BL_BEGIN(151,4) + #pragma omp for + BL_OPER9(0,0,1,2,2,0,1,3,5,5,1,3,6,10,12,2,5,10,16,19,2,5,12,19,22) + BL_FREE +#pragma omp for + BL_END(4) +} + +// sigma = 1.9 +template void bilateral19 (T** src, T** dst, T** buffer, int W, int H, double sens, bool multiThread) { + + BL_BEGIN(151,4) + #pragma omp for + BL_OPER9(0,0,1,2,2,0,1,3,4,5,1,3,5,8,9,2,4,8,12,14,2,5,9,14,16) + BL_FREE +#pragma omp for + BL_END(4) +} + +// sigma = 2 +template void bilateral20 (T** src, T** dst, T** buffer, int W, int H, double sens, bool multiThread) { + + BL_BEGIN(116,5) + #pragma omp for + BL_OPER11(0,0,0,1,1,1,0,0,1,2,3,3,0,1,2,4,7,7,1,2,4,8,12,14,1,3,7,12,18,20,1,3,7,14,20,23) + BL_FREE +#pragma omp for + BL_END(5) +} + +// sigma = 2.1 +template void bilateral21 (T** src, T** dst, T** buffer, int W, int H, double sens, bool multiThread) { + + BL_BEGIN(127,5) + #pragma omp for + BL_OPER11(0,0,0,1,1,1,0,0,1,2,3,3,0,1,2,4,6,7,1,2,4,8,11,12,1,3,6,11,15,17,1,3,7,12,17,19) + BL_FREE +#pragma omp for + BL_END(5) +} + +// sigma = 2.2 +template void bilateral22 (T** src, T** dst, T** buffer, int W, int H, double sens, bool multiThread) { + + BL_BEGIN(109,5) + #pragma omp for + BL_OPER11(0,0,0,1,1,2,0,1,2,3,3,4,1,2,3,5,7,8,1,3,5,9,12,13,1,3,7,12,16,18,2,4,8,13,18,20) + BL_FREE +#pragma omp for + BL_END(5) +} + +// sigma = 2.3 +template void bilateral23 (T** src, T** dst, T** buffer, int W, int H, double sens, bool multiThread) { + + BL_BEGIN(132,5) + #pragma omp for + BL_OPER11(0,0,1,1,1,1,0,1,1,2,3,3,1,1,3,5,6,7,1,2,5,7,10,11,1,3,6,10,13,14,1,3,7,11,14,16) + BL_FREE +#pragma omp for + BL_END(5) +} + +// sigma = 2.4 +template void bilateral24 (T** src, T** dst, T** buffer, int W, int H, double sens, bool multiThread) { + + BL_BEGIN(156,5) + #pragma omp for + BL_OPER11(0,0,1,1,1,1,0,1,1,2,3,3,1,1,3,4,5,6,1,2,4,6,8,9,1,3,5,8,10,11,1,3,6,9,11,12) + BL_FREE +#pragma omp for + BL_END(5) +} + +// sigma = 2.5 +template void bilateral25 (T** src, T** dst, T** buffer, int W, int H, double sens, bool multiThread) { + + BL_BEGIN(173,5) + #pragma omp for + BL_OPER11(0,0,1,1,1,1,0,1,1,2,3,3,1,1,2,4,5,5,1,2,4,5,7,7,1,3,5,7,9,9,1,3,5,7,9,10) + BL_FREE +#pragma omp for + BL_END(5) +} + +// main bilateral filter +template void bilateral (T** src, T** dst, T** buffer, int W, int H, double sigma, double sens, bool multiThread) { +//parallel if (multiThread) + if (sigma<0.45) +#ifdef _OPENMP +#pragma omp for +#endif + for (int i=0; i (src, dst, buffer, W, H, sens, multiThread); + else if (sigma<0.65) + bilateral06 (src, dst, buffer, W, H, sens, multiThread); + else if (sigma<0.75) + bilateral07 (src, dst, buffer, W, H, sens, multiThread); + else if (sigma<0.85) + bilateral08 (src, dst, buffer, W, H, sens, multiThread); + else if (sigma<0.95) + bilateral09 (src, dst, buffer, W, H, sens, multiThread); + else if (sigma<1.05) + bilateral10 (src, dst, buffer, W, H, sens, multiThread); + else if (sigma<1.15) + bilateral11 (src, dst, buffer, W, H, sens, multiThread); + else if (sigma<1.25) + bilateral12 (src, dst, buffer, W, H, sens, multiThread); + else if (sigma<1.35) + bilateral13 (src, dst, buffer, W, H, sens, multiThread); + else if (sigma<1.45) + bilateral14 (src, dst, buffer, W, H, sens, multiThread); + else if (sigma<1.55) + bilateral15 (src, dst, buffer, W, H, sens, multiThread); + else if (sigma<1.65) + bilateral16 (src, dst, buffer, W, H, sens, multiThread); + else if (sigma<1.75) + bilateral17 (src, dst, buffer, W, H, sens, multiThread); + else if (sigma<1.85) + bilateral18 (src, dst, buffer, W, H, sens, multiThread); + else if (sigma<1.95) + bilateral19 (src, dst, buffer, W, H, sens, multiThread); + else if (sigma<2.05) + bilateral20 (src, dst, buffer, W, H, sens, multiThread); + else if (sigma<2.15) + bilateral21 (src, dst, buffer, W, H, sens, multiThread); + else if (sigma<2.25) + bilateral22 (src, dst, buffer, W, H, sens, multiThread); + else if (sigma<2.35) + bilateral23 (src, dst, buffer, W, H, sens, multiThread); + else if (sigma<2.45) + bilateral24 (src, dst, buffer, W, H, sens, multiThread); + else + bilateral25 (src, dst, buffer, W, H, sens, multiThread); +} + +// START OF EXPERIMENTAL CODE: O(1) bilateral box filter +// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +#define BINBIT 7 //bit depth of histogram -- there are 2^BINBIT discrete levels +#define TRANSBIT 9 //bit shift = 16-BINBIT taking short ints to bit depth BINBIT + +template void bilateral (T** src, T** dst, int W, int H, int sigmar, double sigmas, int row_from, int row_to) { + + // range weights + /*LUTf ec(0x20000); + for (int i=0; i<0x20000; i++) + ec[i] = exp(-(double)(i-0x10000)*(double)(i-0x10000) / (2.0*sigmar*sigmar)); */ + + // histogram + LUTu hist (1< buff_final(W,H,ARRAY2D_CLEAR_DATA); + + int r = sigmas; + + // calculate histogram at the beginning of the row + rhist.clear(); + for (int x = MAX(0,row_from-r); x<=MIN(H,row_from+r); x++) + for (int y = 0; y>TRANSBIT]++; + + sigmar*=2; + + for (int i=row_from; ir) + for (int x = 0; x<=MIN(H,r); x++) + rhist[((int)src[i-r-1][x])>>TRANSBIT]--; + if (i>TRANSBIT]++; + + hist=rhist; + for (int j=0; jr) + for (int x=MAX(0,i-r); x<=MIN(i+r,H-1); x++) + hist[(int)(src[x][j-r-1])>>TRANSBIT]--; + if (j>TRANSBIT]++; + + // calculate pixel value + float totwt = 0.0, weight; + for (int k=0; k<=(sigmar>>TRANSBIT); k++) { + float w = 1.0 - (double)k/(sigmar>>TRANSBIT); + int v = (int)(src[i][j])>>TRANSBIT; + //float frac = ((float)(src[i][j]-(v<= 0) { + weight = hist [v-k/*+frac*/] * w; + totwt += weight; + buff_final[i][j] += weight * (src[i][j]-(k< + * + * 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 +#include + +#include "gauss.h" + +#define ELEM(a,b) (src[i-a][j-b] * ec[(((src[i-a][j-b]>>8)+1)<<8) / ((src[i][j]>>8)+1)]) +//#define ELEM(a,b) (src[i-a][j-b] * ec[src[i-a][j-b]-src[i][j]+0x10000]) +//#define SULY(a,b) (ec[src[i-a][j-b]-src[i][j]+0x10000]) +#define SULY(a,b) (ec[(((src[i-a][j-b]>>8)+1)<<8) / ((src[i][j]>>8)+1)]) + +#define BL_BEGIN(a,b) double scale = (a); \ + LUTf ec (0x10001); \ + ec[0] = 1; \ + for (int i=1; i<0x10001; i++) \ + ec[i] = (exp(-log(i/256.0)*log(i/256.0) / (2.0*sens/1000*sens/1000*i/256.0))*scale); \ +/* ec[i] = (int)(exp(-(double)(i-0x10000)*(double)(i-0x10000) / (2.0*sens*sens))*scale); */\ + int start = row_from; \ + if (start<(b)) start = (b); \ + int end = row_to; \ + if (end>H-(b)) end = H-(b); \ + for (int i=start; i=end || j>=W-(b)) \ + dst[i][j] = src[i][j]; \ + else \ + dst[i][j] = buffer[i][j]; + +#define BL_OPER3(a11,a12,a21,a22) A v = a11*ELEM(-1,-1) + a12*ELEM(-1,0) + a11*ELEM(-1,1) + \ + a21*ELEM(0,-1) + a22*ELEM(0,0) + a21*ELEM(0,1) + \ + a11*ELEM(1,-1) + a12*ELEM(1,0) + a11*ELEM(1,1); \ + v /= a11*SULY(-1,-1) + a12*SULY(-1,0) + a11*SULY(-1,1) + \ + a21*SULY(0,-1) + a22*SULY(0,0) + a21*SULY(0,1) + \ + a11*SULY(1,-1) + a12*SULY(1,0) + a11*SULY(1,1); + + +#define BL_OPER5(a11,a12,a13,a21,a22,a23,a31,a32,a33) A v = a11*ELEM(-2,-2) + a12*ELEM(-2,-1) + a13*ELEM(-2,0) + a12*ELEM(-2,1) + a11*ELEM(-2,2) + \ + a21*ELEM(-1,-2) + a22*ELEM(-1,-1) + a23*ELEM(-1,0) + a22*ELEM(-1,1) + a21*ELEM(-1,2) + \ + a31*ELEM(0,-2) + a32*ELEM(0,-1) + a33*ELEM(0,0) + a32*ELEM(0,1) + a31*ELEM(0,2) + \ + a21*ELEM(1,-2) + a22*ELEM(1,-1) + a23*ELEM(1,0) + a22*ELEM(1,1) + a21*ELEM(1,2) + \ + a11*ELEM(2,-2) + a12*ELEM(2,-1) + a13*ELEM(2,0) + a12*ELEM(2,1) + a11*ELEM(2,2); \ + v /= a11*SULY(-2,-2) + a12*SULY(-2,-1) + a13*SULY(-2,0) + a12*SULY(-2,1) + a11*SULY(-2,2) + \ + a21*SULY(-1,-2) + a22*SULY(-1,-1) + a23*SULY(-1,0) + a22*SULY(-1,1) + a21*SULY(-1,2) + \ + a31*SULY(0,-2) + a32*SULY(0,-1) + a33*SULY(0,0) + a32*SULY(0,1) + a31*SULY(0,2) + \ + a21*SULY(1,-2) + a22*SULY(1,-1) + a23*SULY(1,0) + a22*SULY(1,1) + a21*SULY(1,2) + \ + a11*SULY(2,-2) + a12*SULY(2,-1) + a13*SULY(2,0) + a12*SULY(2,1) + a11*SULY(2,2); + +#define BL_OPER7(a11,a12,a13,a14,a21,a22,a23,a24,a31,a32,a33,a34,a41,a42,a43,a44) \ + A v = a11*ELEM(-3,-3) + a12*ELEM(-3,-2) + a13*ELEM(-3,-1) + a14*ELEM(-3,0) + a13*ELEM(-3,1) + a12*ELEM(-3,2) + a11*ELEM(-3,3) + \ + a21*ELEM(-2,-3) + a22*ELEM(-2,-2) + a23*ELEM(-2,-1) + a24*ELEM(-2,0) + a23*ELEM(-2,1) + a22*ELEM(-2,2) + a21*ELEM(-2,3) + \ + a31*ELEM(-1,-3) + a32*ELEM(-1,-2) + a33*ELEM(-1,-1) + a34*ELEM(-1,0) + a33*ELEM(-1,1) + a32*ELEM(-1,2) + a31*ELEM(-1,3) + \ + a41*ELEM(0,-3) + a42*ELEM(0,-2) + a43*ELEM(0,-1) + a44*ELEM(0,0) + a43*ELEM(0,1) + a42*ELEM(0,2) + a41*ELEM(0,3) + \ + a31*ELEM(1,-3) + a32*ELEM(1,-2) + a33*ELEM(1,-1) + a34*ELEM(1,0) + a33*ELEM(1,1) + a32*ELEM(1,2) + a31*ELEM(1,3) + \ + a21*ELEM(2,-3) + a22*ELEM(2,-2) + a23*ELEM(2,-1) + a24*ELEM(2,0) + a23*ELEM(2,1) + a22*ELEM(2,2) + a21*ELEM(2,3) + \ + a11*ELEM(3,-3) + a12*ELEM(3,-2) + a13*ELEM(3,-1) + a14*ELEM(3,0) + a13*ELEM(3,1) + a12*ELEM(3,2) + a11*ELEM(3,3); \ + v /= a11*SULY(-3,-3) + a12*SULY(-3,-2) + a13*SULY(-3,-1) + a14*SULY(-3,0) + a13*SULY(-3,1) + a12*SULY(-3,2) + a11*SULY(-3,3) + \ + a21*SULY(-2,-3) + a22*SULY(-2,-2) + a23*SULY(-2,-1) + a24*SULY(-2,0) + a23*SULY(-2,1) + a22*SULY(-2,2) + a21*SULY(-2,3) + \ + a31*SULY(-1,-3) + a32*SULY(-1,-2) + a33*SULY(-1,-1) + a34*SULY(-1,0) + a33*SULY(-1,1) + a32*SULY(-1,2) + a31*SULY(-1,3) + \ + a41*SULY(0,-3) + a42*SULY(0,-2) + a43*SULY(0,-1) + a44*SULY(0,0) + a43*SULY(0,1) + a42*SULY(0,2) + a41*SULY(0,3) + \ + a31*SULY(1,-3) + a32*SULY(1,-2) + a33*SULY(1,-1) + a34*SULY(1,0) + a33*SULY(1,1) + a32*SULY(1,2) + a31*SULY(1,3) + \ + a21*SULY(2,-3) + a22*SULY(2,-2) + a23*SULY(2,-1) + a24*SULY(2,0) + a23*SULY(2,1) + a22*SULY(2,2) + a21*SULY(2,3) + \ + a11*SULY(3,-3) + a12*SULY(3,-2) + a13*SULY(3,-1) + a14*SULY(3,0) + a13*SULY(3,1) + a12*SULY(3,2) + a11*SULY(3,3); + + +#define BL_OPER9(a11,a12,a13,a14,a15,a21,a22,a23,a24,a25,a31,a32,a33,a34,a35,a41,a42,a43,a44,a45,a51,a52,a53,a54,a55) \ + A v = a11*ELEM(-4,-4) + a12*ELEM(-4,-3) + a13*ELEM(-4,-2) + a14*ELEM(-4,-1) + a15*ELEM(-4,0) + a14*ELEM(-4,1) + a13*ELEM(-4,2) + a12*ELEM(-4,3) + a11*ELEM(-4,4) + \ + a21*ELEM(-3,-4) + a22*ELEM(-3,-3) + a23*ELEM(-3,-2) + a24*ELEM(-3,-1) + a25*ELEM(-3,0) + a24*ELEM(-3,1) + a23*ELEM(-3,2) + a22*ELEM(-3,3) + a21*ELEM(-3,4) + \ + a31*ELEM(-2,-4) + a32*ELEM(-2,-3) + a33*ELEM(-2,-2) + a34*ELEM(-2,-1) + a35*ELEM(-2,0) + a34*ELEM(-2,1) + a33*ELEM(-2,2) + a32*ELEM(-2,3) + a31*ELEM(-2,4) + \ + a41*ELEM(-1,-4) + a42*ELEM(-1,-3) + a43*ELEM(-1,-2) + a44*ELEM(-1,-1) + a45*ELEM(-1,0) + a44*ELEM(-1,1) + a43*ELEM(-1,2) + a42*ELEM(-1,3) + a41*ELEM(-1,4) + \ + a51*ELEM(0,-4) + a52*ELEM(0,-3) + a53*ELEM(0,-2) + a54*ELEM(0,-1) + a55*ELEM(0,0) + a54*ELEM(0,1) + a53*ELEM(0,2) + a52*ELEM(0,3) + a51*ELEM(0,4) + \ + a41*ELEM(1,-4) + a42*ELEM(1,-3) + a43*ELEM(1,-2) + a44*ELEM(1,-1) + a45*ELEM(1,0) + a44*ELEM(1,1) + a43*ELEM(1,2) + a42*ELEM(1,3) + a41*ELEM(1,4) + \ + a31*ELEM(2,-4) + a32*ELEM(2,-3) + a33*ELEM(2,-2) + a34*ELEM(2,-1) + a35*ELEM(2,0) + a34*ELEM(2,1) + a33*ELEM(2,2) + a32*ELEM(2,3) + a31*ELEM(2,4) + \ + a21*ELEM(3,-4) + a22*ELEM(3,-3) + a23*ELEM(3,-2) + a24*ELEM(3,-1) + a25*ELEM(3,0) + a24*ELEM(3,1) + a23*ELEM(3,2) + a22*ELEM(3,3) + a21*ELEM(3,4) + \ + a11*ELEM(4,-4) + a12*ELEM(4,-3) + a13*ELEM(4,-2) + a14*ELEM(4,-1) + a15*ELEM(4,0) + a14*ELEM(4,1) + a13*ELEM(4,2) + a12*ELEM(4,3) + a11*ELEM(4,4); \ + v /= a11*SULY(-4,-4) + a12*SULY(-4,-3) + a13*SULY(-4,-2) + a14*SULY(-4,-1) + a15*SULY(-4,0) + a14*SULY(-4,1) + a13*SULY(-4,2) + a12*SULY(-4,3) + a11*SULY(-4,4) + \ + a21*SULY(-3,-4) + a22*SULY(-3,-3) + a23*SULY(-3,-2) + a24*SULY(-3,-1) + a25*SULY(-3,0) + a24*SULY(-3,1) + a23*SULY(-3,2) + a22*SULY(-3,3) + a21*SULY(-3,4) + \ + a31*SULY(-2,-4) + a32*SULY(-2,-3) + a33*SULY(-2,-2) + a34*SULY(-2,-1) + a35*SULY(-2,0) + a34*SULY(-2,1) + a33*SULY(-2,2) + a32*SULY(-2,3) + a31*SULY(-2,4) + \ + a41*SULY(-1,-4) + a42*SULY(-1,-3) + a43*SULY(-1,-2) + a44*SULY(-1,-1) + a45*SULY(-1,0) + a44*SULY(-1,1) + a43*SULY(-1,2) + a42*SULY(-1,3) + a41*SULY(-1,4) + \ + a51*SULY(0,-4) + a52*SULY(0,-3) + a53*SULY(0,-2) + a54*SULY(0,-1) + a55*SULY(0,0) + a54*SULY(0,1) + a53*SULY(0,2) + a52*SULY(0,3) + a51*SULY(0,4) + \ + a41*SULY(1,-4) + a42*SULY(1,-3) + a43*SULY(1,-2) + a44*SULY(1,-1) + a45*SULY(1,0) + a44*SULY(1,1) + a43*SULY(1,2) + a42*SULY(1,3) + a41*SULY(1,4) + \ + a31*SULY(2,-4) + a32*SULY(2,-3) + a33*SULY(2,-2) + a34*SULY(2,-1) + a35*SULY(2,0) + a34*SULY(2,1) + a33*SULY(2,2) + a32*SULY(2,3) + a31*SULY(2,4) + \ + a21*SULY(3,-4) + a22*SULY(3,-3) + a23*SULY(3,-2) + a24*SULY(3,-1) + a25*SULY(3,0) + a24*SULY(3,1) + a23*SULY(3,2) + a22*SULY(3,3) + a21*SULY(3,4) + \ + a11*SULY(4,-4) + a12*SULY(4,-3) + a13*SULY(4,-2) + a14*SULY(4,-1) + a15*SULY(4,0) + a14*SULY(4,1) + a13*SULY(4,2) + a12*SULY(4,3) + a11*SULY(4,4); + +#define BL_OPER11(a11,a12,a13,a14,a15,a16,a21,a22,a23,a24,a25,a26,a31,a32,a33,a34,a35,a36,a41,a42,a43,a44,a45,a46,a51,a52,a53,a54,a55,a56,a61,a62,a63,a64,a65,a66) \ + A v = a11*ELEM(-5,-5) + a12*ELEM(-5,-4) + a13*ELEM(-5,-3) + a14*ELEM(-5,-2) + a15*ELEM(-5,-1) + a16*ELEM(-5,0) + a15*ELEM(-5,1) + a14*ELEM(-5,2) + a13*ELEM(-5,3) + a12*ELEM(-5,4) + a11*ELEM(-5,5) + \ + a21*ELEM(-4,-5) + a22*ELEM(-4,-4) + a23*ELEM(-4,-3) + a24*ELEM(-4,-2) + a25*ELEM(-4,-1) + a26*ELEM(-4,0) + a25*ELEM(-4,1) + a24*ELEM(-4,2) + a23*ELEM(-4,3) + a22*ELEM(-4,4) + a21*ELEM(-4,5) + \ + a31*ELEM(-3,-5) + a32*ELEM(-3,-4) + a33*ELEM(-3,-3) + a34*ELEM(-3,-2) + a35*ELEM(-3,-1) + a36*ELEM(-3,0) + a35*ELEM(-3,1) + a34*ELEM(-3,2) + a33*ELEM(-3,3) + a32*ELEM(-3,4) + a31*ELEM(-3,5) + \ + a41*ELEM(-2,-5) + a42*ELEM(-2,-4) + a43*ELEM(-2,-3) + a44*ELEM(-2,-2) + a45*ELEM(-2,-1) + a46*ELEM(-2,0) + a45*ELEM(-2,1) + a44*ELEM(-2,2) + a43*ELEM(-2,3) + a42*ELEM(-2,4) + a41*ELEM(-4,5) + \ + a51*ELEM(-1,-5) + a52*ELEM(-1,-4) + a53*ELEM(-1,-3) + a54*ELEM(-1,-2) + a55*ELEM(-1,-1) + a56*ELEM(-1,0) + a55*ELEM(-1,1) + a54*ELEM(-1,2) + a53*ELEM(-1,3) + a52*ELEM(-1,4) + a51*ELEM(-1,5) + \ + a61*ELEM(0,-5) + a62*ELEM(0,-4) + a63*ELEM(0,-3) + a64*ELEM(0,-2) + a65*ELEM(0,-1) + a66*ELEM(0,0) + a65*ELEM(0,1) + a64*ELEM(0,2) + a63*ELEM(0,3) + a62*ELEM(0,4) + a61*ELEM(0,5) + \ + a51*ELEM(1,-5) + a52*ELEM(1,-4) + a53*ELEM(1,-3) + a54*ELEM(1,-2) + a55*ELEM(1,-1) + a56*ELEM(1,0) + a55*ELEM(1,1) + a54*ELEM(1,2) + a53*ELEM(1,3) + a52*ELEM(1,4) + a51*ELEM(1,5) + \ + a41*ELEM(2,-5) + a42*ELEM(2,-4) + a43*ELEM(2,-3) + a44*ELEM(2,-2) + a45*ELEM(2,-1) + a46*ELEM(2,0) + a45*ELEM(2,1) + a44*ELEM(2,2) + a43*ELEM(2,3) + a42*ELEM(2,4) + a41*ELEM(2,5) + \ + a31*ELEM(3,-5) + a32*ELEM(3,-4) + a33*ELEM(3,-3) + a34*ELEM(3,-2) + a35*ELEM(3,-1) + a36*ELEM(3,0) + a35*ELEM(3,1) + a34*ELEM(3,2) + a33*ELEM(3,3) + a32*ELEM(3,4) + a31*ELEM(3,5) + \ + a21*ELEM(4,-5) + a22*ELEM(4,-4) + a23*ELEM(4,-3) + a24*ELEM(4,-2) + a25*ELEM(4,-1) + a26*ELEM(4,0) + a25*ELEM(4,1) + a24*ELEM(4,2) + a23*ELEM(4,3) + a22*ELEM(4,4) + a21*ELEM(4,5) + \ + a11*ELEM(5,-5) + a12*ELEM(5,-4) + a13*ELEM(5,-3) + a14*ELEM(5,-2) + a15*ELEM(5,-1) + a16*ELEM(5,0) + a15*ELEM(5,1) + a14*ELEM(5,2) + a13*ELEM(5,3) + a12*ELEM(5,4) + a11*ELEM(5,5); \ + v /= a11*SULY(-5,-5) + a12*SULY(-5,-4) + a13*SULY(-5,-3) + a14*SULY(-5,-2) + a15*SULY(-5,-1) + a16*SULY(-5,0) + a15*SULY(-5,1) + a14*SULY(-5,2) + a13*SULY(-5,3) + a12*SULY(-5,4) + a11*SULY(-5,5) + \ + a21*SULY(-4,-5) + a22*SULY(-4,-4) + a23*SULY(-4,-3) + a24*SULY(-4,-2) + a25*SULY(-4,-1) + a26*SULY(-4,0) + a25*SULY(-4,1) + a24*SULY(-4,2) + a23*SULY(-4,3) + a22*SULY(-4,4) + a21*SULY(-4,5) + \ + a31*SULY(-3,-5) + a32*SULY(-3,-4) + a33*SULY(-3,-3) + a34*SULY(-3,-2) + a35*SULY(-3,-1) + a36*SULY(-3,0) + a35*SULY(-3,1) + a34*SULY(-3,2) + a33*SULY(-3,3) + a32*SULY(-3,4) + a31*SULY(-3,5) + \ + a41*SULY(-2,-5) + a42*SULY(-2,-4) + a43*SULY(-2,-3) + a44*SULY(-2,-2) + a45*SULY(-2,-1) + a46*SULY(-2,0) + a45*SULY(-2,1) + a44*SULY(-2,2) + a43*SULY(-2,3) + a42*SULY(-2,4) + a41*SULY(-4,5) + \ + a51*SULY(-1,-5) + a52*SULY(-1,-4) + a53*SULY(-1,-3) + a54*SULY(-1,-2) + a55*SULY(-1,-1) + a56*SULY(-1,0) + a55*SULY(-1,1) + a54*SULY(-1,2) + a53*SULY(-1,3) + a52*SULY(-1,4) + a51*SULY(-1,5) + \ + a61*SULY(0,-5) + a62*SULY(0,-4) + a63*SULY(0,-3) + a64*SULY(0,-2) + a65*SULY(0,-1) + a66*SULY(0,0) + a65*SULY(0,1) + a64*SULY(0,2) + a63*SULY(0,3) + a62*SULY(0,4) + a61*SULY(0,5) + \ + a51*SULY(1,-5) + a52*SULY(1,-4) + a53*SULY(1,-3) + a54*SULY(1,-2) + a55*SULY(1,-1) + a56*SULY(1,0) + a55*SULY(1,1) + a54*SULY(1,2) + a53*SULY(1,3) + a52*SULY(1,4) + a51*SULY(1,5) + \ + a41*SULY(2,-5) + a42*SULY(2,-4) + a43*SULY(2,-3) + a44*SULY(2,-2) + a45*SULY(2,-1) + a46*SULY(2,0) + a45*SULY(2,1) + a44*SULY(2,2) + a43*SULY(2,3) + a42*SULY(2,4) + a41*SULY(2,5) + \ + a31*SULY(3,-5) + a32*SULY(3,-4) + a33*SULY(3,-3) + a34*SULY(3,-2) + a35*SULY(3,-1) + a36*SULY(3,0) + a35*SULY(3,1) + a34*SULY(3,2) + a33*SULY(3,3) + a32*SULY(3,4) + a31*SULY(3,5) + \ + a21*SULY(4,-5) + a22*SULY(4,-4) + a23*SULY(4,-3) + a24*SULY(4,-2) + a25*SULY(4,-1) + a26*SULY(4,0) + a25*SULY(4,1) + a24*SULY(4,2) + a23*SULY(4,3) + a22*SULY(4,4) + a21*SULY(4,5) + \ + a11*SULY(5,-5) + a12*SULY(5,-4) + a13*SULY(5,-3) + a14*SULY(5,-2) + a15*SULY(5,-1) + a16*SULY(5,0) + a15*SULY(5,1) + a14*SULY(5,2) + a13*SULY(5,3) + a12*SULY(5,4) + a11*SULY(5,5); \ + + +// sigma = 0.5 +template void bilateral05 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(318,1) + BL_OPER3(1,7,7,55) + BL_END(1) +} + +// sigma = 0.6 +template void bilateral06 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(768,1) + BL_OPER3(1,4,4,16) + BL_END(1) +} + +// sigma = 0.7 +template void bilateral07 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(366,2) + BL_OPER5(0,0,1,0,8,21,1,21,59) + BL_END(2) +} + +// sigma = 0.8 +template void bilateral08 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(753,2) + BL_OPER5(0,0,1,0,5,10,1,10,23) + BL_END(2) +} + +// sigma = 0.9 +template void bilateral09 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(595,2) + BL_OPER5(0,1,2,1,6,12,2,12,22) + BL_END(2) +} + +// sigma = 1.0 +template void bilateral10 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(910,2) + BL_OPER5(0,1,2,1,4,7,2,7,12) + BL_END(2) +} + +// sigma = 1.1 +template void bilateral11 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(209,3) + BL_OPER7(0,0,1,1,0,2,5,8,1,5,18,27,1,8,27,41) + BL_END(3) +} + +// sigma = 1.2 +template void bilateral12 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(322,3) + BL_OPER7(0,0,1,1,0,1,4,6,1,4,11,16,1,6,16,23) + BL_END(3) +} + +// sigma = 1.3 +template void bilateral13 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(336,3) + BL_OPER7(0,0,1,1,0,2,4,6,1,4,11,14,1,6,14,19) + BL_END(3) +} + +// sigma = 1.4 +template void bilateral14 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(195,3) + BL_OPER7(0,1,2,3,1,4,8,10,2,8,17,21,3,10,21,28) + BL_END(3) +} + +// sigma = 1.5 +template void bilateral15 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(132,4) + BL_OPER9(0,0,0,1,1,0,1,2,4,5,0,2,6,12,14,1,4,12,22,28,1,5,14,28,35) + BL_END(4) +} + +// sigma = 1.6 +template void bilateral16 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(180,4) + BL_OPER9(0,0,0,1,1,0,1,2,3,4,0,2,5,9,10,1,3,9,15,19,1,4,10,19,23) + BL_END(4) +} + +// sigma = 1.7 +template void bilateral17 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(195,4) + BL_OPER9(0,0,1,1,1,0,1,2,3,4,1,2,5,8,9,1,3,8,13,16,1,4,9,16,19) + BL_END(4) +} + +// sigma = 1.8 +template void bilateral18 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(151,4) + BL_OPER9(0,0,1,2,2,0,1,3,5,5,1,3,6,10,12,2,5,10,16,19,2,5,12,19,22) + BL_END(4) +} + +// sigma = 1.9 +template void bilateral19 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(151,4) + BL_OPER9(0,0,1,2,2,0,1,3,4,5,1,3,5,8,9,2,4,8,12,14,2,5,9,14,16) + BL_END(4) +} + +// sigma = 2 +template void bilateral20 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(116,5) + BL_OPER11(0,0,0,1,1,1,0,0,1,2,3,3,0,1,2,4,7,7,1,2,4,8,12,14,1,3,7,12,18,20,1,3,7,14,20,23) + BL_END(5) +} + +// sigma = 2.1 +template void bilateral21 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(127,5) + BL_OPER11(0,0,0,1,1,1,0,0,1,2,3,3,0,1,2,4,6,7,1,2,4,8,11,12,1,3,6,11,15,17,1,3,7,12,17,19) + BL_END(5) +} + +// sigma = 2.2 +template void bilateral22 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(109,5) + BL_OPER11(0,0,0,1,1,2,0,1,2,3,3,4,1,2,3,5,7,8,1,3,5,9,12,13,1,3,7,12,16,18,2,4,8,13,18,20) + BL_END(5) +} + +// sigma = 2.3 +template void bilateral23 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(132,5) + BL_OPER11(0,0,1,1,1,1,0,1,1,2,3,3,1,1,3,5,6,7,1,2,5,7,10,11,1,3,6,10,13,14,1,3,7,11,14,16) + BL_END(5) +} + +// sigma = 2.4 +template void bilateral24 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(156,5) + BL_OPER11(0,0,1,1,1,1,0,1,1,2,3,3,1,1,3,4,5,6,1,2,4,6,8,9,1,3,5,8,10,11,1,3,6,9,11,12) + BL_END(5) +} + +// sigma = 2.5 +template void bilateral25 (T** src, T** dst, T** buffer, int W, int H, int row_from, int row_to, double sens) { + + BL_BEGIN(173,5) + BL_OPER11(0,0,1,1,1,1,0,1,1,2,3,3,1,1,2,4,5,5,1,2,4,5,7,7,1,3,5,7,9,9,1,3,5,7,9,10) + BL_END(5) +} + +class Dim { + + public: + int W, H, row_from, row_to; + + Dim (int w, int h, int rf, int rt) : W(w), H(h), row_from(rf), row_to(rt) {} + +}; + +// main bilateral filter +template void bilateral (T** src, T** dst, T** buffer, Dim dim, double sigma, double sens) { + + int W = dim.W; + int H = dim.H; + int row_from = dim.row_from; + int row_to = dim.row_to; + + if (sigma<0.45) + for (int i=row_from; i (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<0.65) + bilateral06 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<0.75) + bilateral07 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<0.85) + bilateral08 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<0.95) + bilateral09 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<1.05) + bilateral10 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<1.15) + bilateral11 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<1.25) + bilateral12 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<1.35) + bilateral13 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<1.45) + bilateral14 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<1.55) + bilateral15 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<1.65) + bilateral16 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<1.75) + bilateral17 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<1.85) + bilateral18 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<1.95) + bilateral19 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<2.05) + bilateral20 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<2.15) + bilateral21 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<2.25) + bilateral22 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<2.35) + bilateral23 (src, dst, buffer, W, H, row_from, row_to, sens); + else if (sigma<2.45) + bilateral24 (src, dst, buffer, W, H, row_from, row_to, sens); + else + bilateral25 (src, dst, buffer, W, H, row_from, row_to, sens); +} + +void bilateral_unsigned (unsigned short** src, unsigned short** dst, unsigned short** buffer, Dim dim, double sigma, double sens) { + + bilateral (src, dst, buffer, dim, sigma, sens); +} + +void bilateral_signed (short** src, short** dst, short** buffer, Dim dim, double sigma, double sens) { + + bilateral (src, dst, buffer, dim, sigma, sens); +} + + + +/* +template void bilateral (T** src, int** dst, int W, int H, int sigmar, double sigmas) { + + time_t t1 = clock (); + + int r = 2.0*sigmas + 0.5; + + double scaleg = 1024.0; + + double MAXINT = 65536.0*65536.0; + double sgmax = 275000/(MAXINT/2.0/sigmar/sigmar+(r+1)*(r+1)/sigmas/sigmas); + printf ("sgmax = %lf\n", sgmax); + if (scaleg>sgmax) + scaleg = sgmax; + + // kernel vector for the spatial gaussian filter * 1024 + int* kernel = new int[1+2*r]; + for (int i=0; i<2*r+1; i++) { + kernel[i] = scaleg / (2.0*sigmas*sigmas) * (i-r)*(i-r) + 0.25; + printf ("kerneli = %d\n", kernel[i]); + } + + // exponential lookup table + int scale = (2.0*sigmar*sigmar) / scaleg; + int scalem = 65535/((1+2*r)*(1+2*r)); + int *ec = new int[256000]; + for (int i=0; i<256000; i++) + ec[i] = exp (-i/scaleg) * scalem; + + for (int i=r; i void bilateral (T** src, T** dst, T** buffer, int W, int H, int sigmar, double sigmas) { + + time_t t1 = clock (); + + // buffer for the final image + float** buff_final = new float*[H]; + float * real_buff_final = new float [W*H]; + for (int i=0; i + * + * 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 _BOXBLUR_H_ +#define _BOXBLUR_H_ + +#include +#include +#include +#include "alignedbuffer.h" +#ifdef _OPENMP +#include +#endif + +#include "rt_math.h" +#include "opthelper.h" + + +//using namespace rtengine; + +namespace rtengine { + +// classical filtering if the support window is small: + +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); + float* temp = buffer->data; + + if (radx==0) { +#ifdef _OPENMP +#pragma omp parallel for +#endif + for (int row=0; row SSEFUNCTION void boxblur (T* src, A* dst, A* buffer, int radx, int rady, int W, int H) { + +//printf("boxblur\n"); + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + //box blur image; box range = (radx,rady) i.e. box size is (2*radx+1)x(2*rady+1) + + float* temp = buffer; + if (radx==0) { + for (int row=0; row= 0; row--) { + int len = radx + 1; + float tempval = (float)src[row*W]; + for (int j=1; j<=radx; j++) { + tempval += (float)src[row*W+j]; + } + tempval = tempval/len; + temp[row*W] = tempval; + for (int col=1; col<=radx; col++) { + tempval = (tempval*len + src[row*W+col+radx])/(len+1); + temp[row*W+col] = tempval; + len ++; + } + float reclen = 1.f/len; + for (int col = radx+1; col < W-radx; col++) { + tempval = tempval + ((float)(src[row*W+col+radx] - src[row*W+col-radx-1]))*reclen; + temp[row*W+col] = tempval; + } + for (int col=W-radx; col 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* 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 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 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 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; row0 ? (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 SSEFUNCTION void boxabsblur (T* src, A* dst, int radx, int rady, int W, int H, float * temp) { + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + //box blur image; box range = (radx,rady) i.e. box size is (2*radx+1)x(2*rady+1) + + if (radx==0) { + for (int row=0; row +#include +#include +#include +#include +#include +#include +#include "cJSON.h" + +static const char *ep; + +const char *cJSON_GetErrorPtr(void) {return ep;} + +static int cJSON_strcasecmp(const char *s1,const char *s2) +{ + if (!s1) return (s1==s2)?0:1;if (!s2) return 1; + for(; tolower(*s1) == tolower(*s2); ++s1, ++s2) if(*s1 == 0) return 0; + return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2); +} + +static void *(*cJSON_malloc)(size_t sz) = malloc; +static void (*cJSON_free)(void *ptr) = free; + +static char* cJSON_strdup(const char* str) +{ + size_t len; + char* copy; + + len = strlen(str) + 1; + if (!(copy = (char*)cJSON_malloc(len))) return 0; + memcpy(copy,str,len); + return copy; +} + +void cJSON_InitHooks(cJSON_Hooks* hooks) +{ + if (!hooks) { /* Reset hooks */ + cJSON_malloc = malloc; + cJSON_free = free; + return; + } + + cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc; + cJSON_free = (hooks->free_fn)?hooks->free_fn:free; +} + +/* Internal constructor. */ +static cJSON *cJSON_New_Item(void) +{ + cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON)); + if (node) memset(node,0,sizeof(cJSON)); + return node; +} + +/* Delete a cJSON structure. */ +void cJSON_Delete(cJSON *c) +{ + cJSON *next; + while (c) + { + next=c->next; + if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child); + if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring); + if (c->string) cJSON_free(c->string); + cJSON_free(c); + c=next; + } +} + +/* Parse the input text to generate a number, and populate the result into item. */ +static const char *parse_number(cJSON *item,const char *num) +{ + double n=0,sign=1,scale=0;int subscale=0,signsubscale=1; + + if (*num=='-') sign=-1,num++; /* Has sign? */ + if (*num=='0') num++; /* is zero */ + if (*num>='1' && *num<='9') do n=(n*10.0)+(*num++ -'0'); while (*num>='0' && *num<='9'); /* Number? */ + if (*num=='.' && num[1]>='0' && num[1]<='9') {num++; do n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');} /* Fractional part? */ + if (*num=='e' || *num=='E') /* Exponent? */ + { num++;if (*num=='+') num++; else if (*num=='-') signsubscale=-1,num++; /* With sign? */ + while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0'); /* Number? */ + } + + n=sign*n*pow(10.0,(scale+subscale*signsubscale)); /* number = +/- number.fraction * 10^+/- exponent */ + + item->valuedouble=n; + item->valueint=(int)n; + item->type=cJSON_Number; + return num; +} + +/* Render the number nicely from the given item into a string. */ +static char *print_number(cJSON *item) +{ + char *str; + double d=item->valuedouble; + if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN) + { + str=(char*)cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */ + if (str) sprintf(str,"%d",item->valueint); + } + else + { + str=(char*)cJSON_malloc(64); /* This is a nice tradeoff. */ + if (str) + { + if (fabs(floor(d)-d)<=DBL_EPSILON && fabs(d)<1.0e60)sprintf(str,"%.0f",d); + else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) sprintf(str,"%e",d); + else sprintf(str,"%f",d); + } + } + return str; +} + +static unsigned parse_hex4(const char *str) +{ + unsigned h=0; + if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0; + h=h<<4;str++; + if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0; + h=h<<4;str++; + if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0; + h=h<<4;str++; + if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0; + return h; +} + +/* Parse the input text into an unescaped cstring, and populate item. */ +static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; +static const char *parse_string(cJSON *item,const char *str) +{ + const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2; + if (*str!='\"') {ep=str;return 0;} /* not a string! */ + + while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */ + + out=(char*)cJSON_malloc(len+1); /* This is how long we need for the string, roughly. */ + if (!out) return 0; + + ptr=str+1;ptr2=out; + while (*ptr!='\"' && *ptr) + { + if (*ptr!='\\') *ptr2++=*ptr++; + else + { + ptr++; + switch (*ptr) + { + case 'b': *ptr2++='\b'; break; + case 'f': *ptr2++='\f'; break; + case 'n': *ptr2++='\n'; break; + case 'r': *ptr2++='\r'; break; + case 't': *ptr2++='\t'; break; + case 'u': /* transcode utf16 to utf8. */ + uc=parse_hex4(ptr+1);ptr+=4; /* get the unicode char. */ + + if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0) break; /* check for invalid. */ + + if (uc>=0xD800 && uc<=0xDBFF) /* UTF16 surrogate pairs. */ + { + if (ptr[1]!='\\' || ptr[2]!='u') break; /* missing second-half of surrogate. */ + uc2=parse_hex4(ptr+3);ptr+=6; + if (uc2<0xDC00 || uc2>0xDFFF) break; /* invalid second-half of surrogate. */ + uc=0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF)); + } + + len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len; + + 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]); + } + ptr2+=len; + break; + default: *ptr2++=*ptr; break; + } + ptr++; + } + } + *ptr2=0; + if (*ptr=='\"') ptr++; + item->valuestring=out; + item->type=cJSON_String; + return ptr; +} + +/* Render the cstring provided to an escaped version that can be printed. */ +static char *print_string_ptr(const char *str) +{ + const char *ptr;char *ptr2,*out;int len=0;unsigned char token; + + if (!str) return cJSON_strdup(""); + ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;} + + out=(char*)cJSON_malloc(len+3); + if (!out) return 0; + + ptr2=out;ptr=str; + *ptr2++='\"'; + while (*ptr) + { + if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++; + else + { + *ptr2++='\\'; + switch (token=*ptr++) + { + case '\\': *ptr2++='\\'; break; + case '\"': *ptr2++='\"'; break; + case '\b': *ptr2++='b'; break; + case '\f': *ptr2++='f'; break; + case '\n': *ptr2++='n'; break; + case '\r': *ptr2++='r'; break; + case '\t': *ptr2++='t'; break; + default: sprintf(ptr2,"u%04x",token);ptr2+=5; break; /* escape and print */ + } + } + } + *ptr2++='\"';*ptr2++=0; + return out; +} +/* Invote print_string_ptr (which is useful) on an item. */ +static char *print_string(cJSON *item) {return print_string_ptr(item->valuestring);} + +/* Predeclare these prototypes. */ +static const char *parse_value(cJSON *item,const char *value); +static char *print_value(cJSON *item,int depth,int fmt); +static const char *parse_array(cJSON *item,const char *value); +static char *print_array(cJSON *item,int depth,int fmt); +static const char *parse_object(cJSON *item,const char *value); +static char *print_object(cJSON *item,int depth,int fmt); + +/* Utility to jump whitespace and cr/lf */ +static const char *skip(const char *in) {while (in && *in && (unsigned char)*in<=32) in++; return in;} + +/* Parse an object - create a new root, and populate. */ +cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated) +{ + const char *end=0; + cJSON *c=cJSON_New_Item(); + ep=0; + if (!c) return 0; /* memory fail */ + + end=parse_value(c,skip(value)); + if (!end) {cJSON_Delete(c);return 0;} /* parse failure. ep is set. */ + + /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */ + if (require_null_terminated) {end=skip(end);if (*end) {cJSON_Delete(c);ep=end;return 0;}} + if (return_parse_end) *return_parse_end=end; + return c; +} +/* Default options for cJSON_Parse */ +cJSON *cJSON_Parse(const char *value) {return cJSON_ParseWithOpts(value,0,0);} + +/* Render a cJSON item/entity/structure to text. */ +char *cJSON_Print(cJSON *item) {return print_value(item,0,1);} +char *cJSON_PrintUnformatted(cJSON *item) {return print_value(item,0,0);} + +/* Parser core - when encountering text, process appropriately. */ +static const char *parse_value(cJSON *item,const char *value) +{ + if (!value) return 0; /* Fail on null. */ + if (!strncmp(value,"null",4)) { item->type=cJSON_NULL; return value+4; } + if (!strncmp(value,"false",5)) { item->type=cJSON_False; return value+5; } + if (!strncmp(value,"true",4)) { item->type=cJSON_True; item->valueint=1; return value+4; } + if (*value=='\"') { return parse_string(item,value); } + if (*value=='-' || (*value>='0' && *value<='9')) { return parse_number(item,value); } + if (*value=='[') { return parse_array(item,value); } + if (*value=='{') { return parse_object(item,value); } + + ep=value;return 0; /* failure. */ +} + +/* Render a value to text. */ +static char *print_value(cJSON *item,int depth,int fmt) +{ + char *out=0; + if (!item) return 0; + switch ((item->type)&255) + { + case cJSON_NULL: out=cJSON_strdup("null"); break; + case cJSON_False: out=cJSON_strdup("false");break; + case cJSON_True: out=cJSON_strdup("true"); break; + case cJSON_Number: out=print_number(item);break; + case cJSON_String: out=print_string(item);break; + case cJSON_Array: out=print_array(item,depth,fmt);break; + case cJSON_Object: out=print_object(item,depth,fmt);break; + } + return out; +} + +/* Build an array from input text. */ +static const char *parse_array(cJSON *item,const char *value) +{ + cJSON *child; + if (*value!='[') {ep=value;return 0;} /* not an array! */ + + item->type=cJSON_Array; + value=skip(value+1); + if (*value==']') return value+1; /* empty array. */ + + item->child=child=cJSON_New_Item(); + if (!item->child) return 0; /* memory fail */ + value=skip(parse_value(child,skip(value))); /* skip any spacing, get the value. */ + if (!value) return 0; + + while (*value==',') + { + cJSON *new_item; + if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */ + child->next=new_item;new_item->prev=child;child=new_item; + value=skip(parse_value(child,skip(value+1))); + if (!value) return 0; /* memory fail */ + } + + if (*value==']') return value+1; /* end of array */ + ep=value;return 0; /* malformed. */ +} + +/* Render an array to text */ +static char *print_array(cJSON *item,int depth,int fmt) +{ + char **entries; + char *out=0,*ptr,*ret;int len=5; + cJSON *child=item->child; + int numentries=0,i=0,fail=0; + + /* How many entries in the array? */ + while (child) numentries++,child=child->next; + /* Explicitly handle numentries==0 */ + if (!numentries) + { + out=(char*)cJSON_malloc(3); + if (out) strcpy(out,"[]"); + return out; + } + /* Allocate an array to hold the values for each */ + entries=(char**)cJSON_malloc(numentries*sizeof(char*)); + if (!entries) return 0; + memset(entries,0,numentries*sizeof(char*)); + /* Retrieve all the results: */ + child=item->child; + while (child && !fail) + { + ret=print_value(child,depth+1,fmt); + entries[i++]=ret; + if (ret) len+=strlen(ret)+2+(fmt?1:0); else fail=1; + child=child->next; + } + + /* If we didn't fail, try to malloc the output string */ + if (!fail) out=(char*)cJSON_malloc(len); + /* If that fails, we fail. */ + if (!out) fail=1; + + /* Handle failure. */ + if (fail) + { + for (i=0;itype=cJSON_Object; + value=skip(value+1); + if (*value=='}') return value+1; /* empty array. */ + + item->child=child=cJSON_New_Item(); + if (!item->child) return 0; + value=skip(parse_string(child,skip(value))); + if (!value) return 0; + child->string=child->valuestring;child->valuestring=0; + if (*value!=':') {ep=value;return 0;} /* fail! */ + value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */ + if (!value) return 0; + + while (*value==',') + { + cJSON *new_item; + if (!(new_item=cJSON_New_Item())) return 0; /* memory fail */ + child->next=new_item;new_item->prev=child;child=new_item; + value=skip(parse_string(child,skip(value+1))); + if (!value) return 0; + child->string=child->valuestring;child->valuestring=0; + if (*value!=':') {ep=value;return 0;} /* fail! */ + value=skip(parse_value(child,skip(value+1))); /* skip any spacing, get the value. */ + if (!value) return 0; + } + + if (*value=='}') return value+1; /* end of array */ + ep=value;return 0; /* malformed. */ +} + +/* Render an object to text. */ +static char *print_object(cJSON *item,int depth,int fmt) +{ + char **entries=0,**names=0; + char *out=0,*ptr,*ret,*str;int len=7,i=0,j; + cJSON *child=item->child; + int numentries=0,fail=0; + /* Count the number of entries. */ + while (child) numentries++,child=child->next; + /* Explicitly handle empty object case */ + if (!numentries) + { + out=(char*)cJSON_malloc(fmt?depth+4:3); + if (!out) return 0; + ptr=out;*ptr++='{'; + if (fmt) {*ptr++='\n';for (i=0;ichild;depth++;if (fmt) len+=depth; + while (child) + { + names[i]=str=print_string_ptr(child->string); + entries[i++]=ret=print_value(child,depth,fmt); + if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1; + child=child->next; + } + + /* Try to allocate the output string */ + if (!fail) out=(char*)cJSON_malloc(len); + if (!out) fail=1; + + /* Handle failure */ + if (fail) + { + for (i=0;ichild;int i=0;while(c)i++,c=c->next;return i;} +cJSON *cJSON_GetArrayItem(cJSON *array,int item) {cJSON *c=array->child; while (c && item>0) item--,c=c->next; return c;} +cJSON *cJSON_GetObjectItem(cJSON *object,const char *string) {cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;} + +/* Utility for array list handling. */ +static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;} +/* Utility for handling references. */ +static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();if (!ref) return 0;memcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;} + +/* Add item to array/object. */ +void cJSON_AddItemToArray(cJSON *array, cJSON *item) {cJSON *c=array->child;if (!item) return; if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}} +void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item) {if (!item) return; if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);} +void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) {cJSON_AddItemToArray(array,create_reference(item));} +void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item) {cJSON_AddItemToObject(object,string,create_reference(item));} + +cJSON *cJSON_DetachItemFromArray(cJSON *array,int which) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0; + if (c->prev) c->prev->next=c->next;if (c->next) c->next->prev=c->prev;if (c==array->child) array->child=c->next;c->prev=c->next=0;return c;} +void cJSON_DeleteItemFromArray(cJSON *array,int which) {cJSON_Delete(cJSON_DetachItemFromArray(array,which));} +cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string) {int i=0;cJSON *c=object->child;while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;if (c) return cJSON_DetachItemFromArray(object,i);return 0;} +void cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));} + +/* Replace array/object items with new ones. */ +void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem) {cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return; + newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem; + if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);} +void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}} + +/* Create basic types: */ +cJSON *cJSON_CreateNull(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;} +cJSON *cJSON_CreateTrue(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;} +cJSON *cJSON_CreateFalse(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;} +cJSON *cJSON_CreateBool(int b) {cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;} +cJSON *cJSON_CreateNumber(double num) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;}return item;} +cJSON *cJSON_CreateString(const char *string) {cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;} +cJSON *cJSON_CreateArray(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;} +cJSON *cJSON_CreateObject(void) {cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;} + +/* Create Arrays: */ +cJSON *cJSON_CreateIntArray(const int *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && ichild=n;else suffix_object(p,n);p=n;}return a;} +cJSON *cJSON_CreateFloatArray(const float *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && ichild=n;else suffix_object(p,n);p=n;}return a;} +cJSON *cJSON_CreateDoubleArray(const double *numbers,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && ichild=n;else suffix_object(p,n);p=n;}return a;} +cJSON *cJSON_CreateStringArray(const char **strings,int count) {int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && ichild=n;else suffix_object(p,n);p=n;}return a;} + +/* Duplication */ +cJSON *cJSON_Duplicate(cJSON *item,int recurse) +{ + cJSON *newitem,*cptr,*nptr=0,*newchild; + /* Bail on bad ptr */ + if (!item) return 0; + /* Create new item */ + newitem=cJSON_New_Item(); + if (!newitem) return 0; + /* Copy over all vars */ + newitem->type=item->type&(~cJSON_IsReference),newitem->valueint=item->valueint,newitem->valuedouble=item->valuedouble; + if (item->valuestring) {newitem->valuestring=cJSON_strdup(item->valuestring); if (!newitem->valuestring) {cJSON_Delete(newitem);return 0;}} + if (item->string) {newitem->string=cJSON_strdup(item->string); if (!newitem->string) {cJSON_Delete(newitem);return 0;}} + /* If non-recursive, then we're done! */ + if (!recurse) return newitem; + /* Walk the ->next chain for the child. */ + cptr=item->child; + while (cptr) + { + newchild=cJSON_Duplicate(cptr,1); /* Duplicate (with recurse) each item in the ->next chain */ + if (!newchild) {cJSON_Delete(newitem);return 0;} + if (nptr) {nptr->next=newchild,newchild->prev=nptr;nptr=newchild;} /* If newitem->child already set, then crosswire ->prev and ->next and move on */ + else {newitem->child=newchild;nptr=newchild;} /* Set newitem->child and move to it */ + cptr=cptr->next; + } + return newitem; +} + +void cJSON_Minify(char *json) +{ + char *into=json; + while (*json) + { + if (*json==' ') json++; + else if (*json=='\t') json++; // Whitespace characters. + else if (*json=='\r') json++; + else if (*json=='\n') json++; + else if (*json=='/' && json[1]=='/') while (*json && *json!='\n') json++; // double-slash comments, to end of line. + else if (*json=='/' && json[1]=='*') {while (*json && !(*json=='*' && json[1]=='/')) json++;json+=2;} // multiline comments. + else if (*json=='\"'){*into++=*json++;while (*json && *json!='\"'){if (*json=='\\') *into++=*json++;*into++=*json++;}*into++=*json++;} // string literals, which are \" sensitive. + else *into++=*json++; // All other characters. + } + *into=0; // and null-terminate. +} \ No newline at end of file diff --git a/rtengine/cJSON.h b/rtengine/cJSON.h new file mode 100644 index 000000000..867b7c32f --- /dev/null +++ b/rtengine/cJSON.h @@ -0,0 +1,143 @@ +/* + Copyright (c) 2009 Dave Gamble + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#ifndef cJSON__h +#define cJSON__h + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* cJSON Types: */ +#define cJSON_False 0 +#define cJSON_True 1 +#define cJSON_NULL 2 +#define cJSON_Number 3 +#define cJSON_String 4 +#define cJSON_Array 5 +#define cJSON_Object 6 + +#define cJSON_IsReference 256 + +/* The cJSON structure: */ +typedef struct cJSON { + struct cJSON *next,*prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */ + struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */ + + int type; /* The type of the item, as above. */ + + char *valuestring; /* The item's string, if type==cJSON_String */ + int valueint; /* The item's number, if type==cJSON_Number */ + double valuedouble; /* The item's number, if type==cJSON_Number */ + + char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */ +} cJSON; + +typedef struct cJSON_Hooks { + void *(*malloc_fn)(size_t sz); + void (*free_fn)(void *ptr); +} cJSON_Hooks; + +/* Supply malloc, realloc and free functions to cJSON */ +extern void cJSON_InitHooks(cJSON_Hooks* hooks); + + +/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */ +extern cJSON *cJSON_Parse(const char *value); +/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */ +extern char *cJSON_Print(cJSON *item); +/* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */ +extern char *cJSON_PrintUnformatted(cJSON *item); +/* Delete a cJSON entity and all subentities. */ +extern void cJSON_Delete(cJSON *c); + +/* Returns the number of items in an array (or object). */ +extern int cJSON_GetArraySize(cJSON *array); +/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */ +extern cJSON *cJSON_GetArrayItem(cJSON *array,int item); +/* Get item "string" from object. Case insensitive. */ +extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string); + +/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */ +extern const char *cJSON_GetErrorPtr(void); + +/* These calls create a cJSON item of the appropriate type. */ +extern cJSON *cJSON_CreateNull(void); +extern cJSON *cJSON_CreateTrue(void); +extern cJSON *cJSON_CreateFalse(void); +extern cJSON *cJSON_CreateBool(int b); +extern cJSON *cJSON_CreateNumber(double num); +extern cJSON *cJSON_CreateString(const char *string); +extern cJSON *cJSON_CreateArray(void); +extern cJSON *cJSON_CreateObject(void); + +/* These utilities create an Array of count items. */ +extern cJSON *cJSON_CreateIntArray(const int *numbers,int count); +extern cJSON *cJSON_CreateFloatArray(const float *numbers,int count); +extern cJSON *cJSON_CreateDoubleArray(const double *numbers,int count); +extern cJSON *cJSON_CreateStringArray(const char **strings,int count); + +/* Append item to the specified array/object. */ +extern void cJSON_AddItemToArray(cJSON *array, cJSON *item); +extern void cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item); +/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */ +extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item); +extern void cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item); + +/* Remove/Detatch items from Arrays/Objects. */ +extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which); +extern void cJSON_DeleteItemFromArray(cJSON *array,int which); +extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string); +extern void cJSON_DeleteItemFromObject(cJSON *object,const char *string); + +/* Update array items. */ +extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem); +extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem); + +/* Duplicate a cJSON item */ +extern cJSON *cJSON_Duplicate(cJSON *item,int recurse); +/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will +need to be released. With recurse!=0, it will duplicate any children connected to the item. +The item->next and ->prev pointers are always zero on return from Duplicate. */ + +/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */ +extern cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated); + +extern void cJSON_Minify(char *json); + +/* Macros for creating things quickly. */ +#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull()) +#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue()) +#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse()) +#define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b)) +#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n)) +#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s)) + +/* When assigning an integer value, it needs to be propagated to valuedouble too. */ +#define cJSON_SetIntValue(object,val) ((object)?(object)->valueint=(object)->valuedouble=(val):(val)) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/rtengine/calc_distort.cc b/rtengine/calc_distort.cc new file mode 100644 index 000000000..90ac64954 --- /dev/null +++ b/rtengine/calc_distort.cc @@ -0,0 +1,235 @@ +/********************************************************************** +Finds the N_FEATURES best features in an image, and tracks these +features to the next image. Saves the feature +locations (before and after tracking) to text files and to PPM files, +and prints the features to the screen. +**********************************************************************/ + +#include "klt/pnmio.h" +#include "klt/klt.h" +#include +#include + +#define N_FEATURES 100 +#define DELTA_1 0.05 +#define DELTA_2 0.01 +#define RXY_LIMIT 0.6 +#define CENTER_R 0.3 + +//#define DEBUG_IMG + +#ifdef DEBUG_IMG +void drawDotXY(unsigned char* img, int ncols, int nrows, int x, int y, int color) +{ + img[x+y*ncols] = color; +} + +void drawDot(unsigned char* img, int ncols, int nrows, double r0, double r10, int color) +{ + if (r0>=0 && r0<1 && r10 >=0.8 && r10 <1.2) + drawDotXY (img, ncols, nrows, (int)(r0*ncols), (int)((r10-0.8)*2.5*nrows), color); +} +#endif + +int calcDistortion(unsigned char* img1, unsigned char* img2, int ncols, int nrows, int nfactor, double &distortion) +{ + KLT_TrackingContext tc; + KLT_FeatureList fl; + KLT_FeatureTable ft; + int i,n; + double radius, wc, hc; + + double r0[N_FEATURES*nfactor]; + memset(r0,0,N_FEATURES*nfactor*sizeof(double)); + double r10[N_FEATURES*nfactor]; + memset(r10,0,N_FEATURES*nfactor*sizeof(double)); + + tc = KLTCreateTrackingContext(); + //tc->mindist = 20; + tc->lighting_insensitive = TRUE; + tc->nSkippedPixels = 5; + tc->step_factor = 2.0; + tc->max_iterations = 20; + //KLTPrintTrackingContext(tc); + fl = KLTCreateFeatureList(N_FEATURES*nfactor); + ft = KLTCreateFeatureTable(2, N_FEATURES*nfactor); + + radius = sqrt(ncols*ncols+nrows*nrows)/2.0; + wc=((double)ncols)/2.0-0.5; + hc=((double)nrows)/2.0-0.5; + + KLTSelectGoodFeatures(tc, img1, ncols, nrows, fl); + KLTStoreFeatureList(fl, ft, 0); + + KLTTrackFeatures(tc, img1, img2, ncols, nrows, fl); + KLTStoreFeatureList(fl, ft, 1); + + // add a shade to img2, we want to draw something on top of it. + for (i=0;ifeature[i][1]->val>=0) { + double x0,y0,x1,y1; + x0=ft->feature[i][0]->x; + y0=ft->feature[i][0]->y; + x1=ft->feature[i][1]->x; + y1=ft->feature[i][1]->y; + + r0[n]=sqrt((x0-wc)*(x0-wc)+(y0-hc)*(y0-hc))/radius; + // dots too close to the center tends to have big diviation and create noise, extract them + if (r0[n]feature[i][0]->x=-1.0; + ft->feature[i][0]->y=-1.0; + } + } + + if (n < 5) { + printf ("Not sufficient features.\n"); + distortion = 0.0; + return -1; + } + + double avg_r10 = total_r10 / n; + double avg_r0 = total_r0 / n; + double Sxx = 0.0; + double Sxy = 0.0; + double Syy = 0.0; + + for (i=0;i= 0 ? delta : -delta; + +#ifdef DEBUG_IMG + drawDot(img2, ncols, nrows, r0[i], r10[i], 255); +#endif + + if (delta >= DELTA_1) { + total_r10 -= r10[i]; + total_r0 -= r0[i]; + r0[i] = -1.0; + new_n--; + } + + total_delta += delta; + } + + printf ("distortion amount=%lf scale=%lf deviation=%lf, rxy=%lf\n", a, b, total_delta/n, rxy); + + if (new_n < 5) { + printf ("Not sufficient features.\n"); + distortion = 0.0; + return -1; + } + + printf ("Removed %d outstading data points\n", n-new_n); + avg_r10 = total_r10 / new_n; + avg_r0 = total_r0 / new_n; + Sxx = 0.0; + Sxy = 0.0; + Syy = 0.0; + + for (i=0;i=0.8 && val <1.2) { + if (img2[i+((int)((val-0.8)*2.5*nrows))*ncols] != 255) + img2[i+((int)((val-0.8)*2.5*nrows))*ncols] = 0; + } + val += DELTA_1; + if (val >=0.8 && val <1.2) { + if (img2[i+((int)((val-0.8)*2.5*nrows))*ncols] != 255) + img2[i+((int)((val-0.8)*2.5*nrows))*ncols] = 8; + } + val -= DELTA_1*2; + if (val >=0.8 && val <1.2) { + if (img2[i+((int)((val-0.8)*2.5*nrows))*ncols] != 255) + img2[i+((int)((val-0.8)*2.5*nrows))*ncols] = 8; + } + val += DELTA_1+DELTA_2; + if (val >=0.8 && val <1.2) { + if (img2[i+((int)((val-0.8)*2.5*nrows))*ncols] != 255) + img2[i+((int)((val-0.8)*2.5*nrows))*ncols] = 16; + } + val -= DELTA_2*2; + if (val >=0.8 && val <1.2) { + if (img2[i+((int)((val-0.8)*2.5*nrows))*ncols] != 255) + img2[i+((int)((val-0.8)*2.5*nrows))*ncols] = 16; + } + } + + KLTExtractFeatureList(fl, ft, 0); + KLTWriteFeatureListToPPM(fl,img1,ncols,nrows,"/tmp/feat0.ppm"); + KLTExtractFeatureList(fl, ft, 1); + KLTWriteFeatureListToPPM(fl,img2,ncols,nrows,"/tmp/feat1.ppm"); +#endif + + // calculate deviation + for (i=0;i= 0 ? delta : -delta; + total_delta += delta; + } + + printf ("distortion amount=%lf scale=%lf deviation=%lf, rxy=%lf\n", a, b, total_delta/n, rxy); + + if (total_delta / new_n > DELTA_2) { + printf ("Deviation is too big.\n"); + distortion = 0.0; + return -2; + } + + if (rxy < RXY_LIMIT) { + printf ("Not linear enough\n"); + distortion = 0.0; + return -3; + } + + printf ("distortion amount=%lf scale=%lf deviation=%lf, rxy=%lf\n", a, b, total_delta/n, rxy); + distortion = a; + return 1; +} + diff --git a/rtengine/calc_distort.h b/rtengine/calc_distort.h new file mode 100644 index 000000000..5ecff8d2f --- /dev/null +++ b/rtengine/calc_distort.h @@ -0,0 +1,4 @@ +#ifndef CALC_DISTORTION__H +#define CALC_DISTORTION__H + int calcDistortion (unsigned char* img1, unsigned char* img2, int ncols, int nrows, int nfactor, double &distortion); +#endif diff --git a/rtengine/camconst.cc b/rtengine/camconst.cc new file mode 100755 index 000000000..6fc200a31 --- /dev/null +++ b/rtengine/camconst.cc @@ -0,0 +1,613 @@ +/* + * This file is part of RawTherapee. + */ +#include "camconst.h" +#include "settings.h" +#include "safegtk.h" +#include "rt_math.h" +#include +#include + +// cJSON is a very minimal JSON parser lib in C, not for threaded stuff etc, so if we're going to use JSON more than just +// here we should probably replace cJSON with something beefier. +#include "cJSON.h" +#include +#include +#include + +namespace rtengine { + +extern const Settings* settings; + +CameraConst::CameraConst() +{ + memset(dcraw_matrix, 0, sizeof(dcraw_matrix)); + memset(raw_crop, 0, sizeof(raw_crop)); + memset(raw_mask, 0, sizeof(raw_mask)); + white_max = 0; +} + +CameraConst::~CameraConst() +{ +} + +bool +CameraConst::parseApertureScaling(CameraConst *cc, void *ji_) +{ + cJSON *ji = (cJSON *)ji_; + if (ji->type != cJSON_Array) { + fprintf(stderr, "\"ranges\":\"aperture_scaling\" must be an array\n"); + return false; + } + for (ji = ji->child; ji != NULL; ji = ji->next) { + cJSON *js = cJSON_GetObjectItem(ji, "aperture"); + if (!js) { + fprintf(stderr, "missing \"ranges\":\"aperture_scaling\":\"aperture\" object item.\n"); + return false; + } else if (js->type != cJSON_Number) { + fprintf(stderr, "\"ranges\":\"aperture_scaling\":\"aperture\" must be a number.\n"); + return false; + } + float aperture = (float)js->valuedouble; + js = cJSON_GetObjectItem(ji, "scale_factor"); + if (!js) { + fprintf(stderr, "missing \"ranges\":\"aperture_scaling\":\"scale_factor\" object item.\n"); + return false; + } else if (js->type != cJSON_Number) { + fprintf(stderr, "\"ranges\":\"aperture_scaling\":\"scale_factor\" must be a number.\n"); + return false; + } + float scale_factor = (float)js->valuedouble; + cc->mApertureScaling.insert(std::pair(aperture, scale_factor)); + } + return true; +} + +bool +CameraConst::parseLevels(CameraConst *cc, int bw, void *ji_) +{ + cJSON *ji = (cJSON *)ji_; + + if (ji->type == cJSON_Number) { + struct camera_const_levels lvl; + lvl.levels[0] = lvl.levels[1] = lvl.levels[2] = lvl.levels[3] = ji->valueint; + cc->mLevels[bw].insert(std::pair(0, lvl)); + return true; + } else if (ji->type != cJSON_Array) { + fprintf(stderr, "\"ranges\":\"%s\" must be a number or an array\n", bw ? "white" : "black"); + return false; + } + + if (ji->child->type == cJSON_Number) { + struct camera_const_levels lvl; + int i; + cJSON *js; + for (js = ji->child, i = 0; js != NULL && i < 4; js = js->next, i++) { + lvl.levels[i] = js->valueint; + } + if (i == 3) { + lvl.levels[3] = lvl.levels[1]; // G2 = G1 + } else if (i == 1) { + lvl.levels[3] = lvl.levels[2] = lvl.levels[1] = lvl.levels[0]; + } else if (i != 4 || js != NULL) { + fprintf(stderr, "\"ranges\":\"%s\" array must have 1, 3 or 4 numbers.\n", bw ? "white" : "black"); + return false; + } + cc->mLevels[bw].insert(std::pair(0, lvl)); + return true; + } + + for (ji = ji->child; ji != NULL; ji = ji->next) { + int iso[1000] = { 0 }; + int iso_count = 0; + cJSON *js = cJSON_GetObjectItem(ji, "iso"); + if (!js) { + fprintf(stderr, "missing \"ranges\":\"%s\":\"iso\" object item.\n", bw ? "white" : "black"); + return false; + } else if (js->type == cJSON_Number) { + iso[0] = js->valueint; + iso_count = 1; + } else if (js->type == cJSON_Array) { + int i; + for (js = js->child, i = 0; js != NULL && i < 1000; js = js->next, i++) { + if (js->type != cJSON_Number) { + fprintf(stderr, "\"ranges\":\"%s\":\"iso\" must be a number or an array of numbers.\n", bw ? "white" : "black"); + return false; + } + iso[i] = js->valueint; + } + iso_count = i; + } else { + fprintf(stderr, "\"ranges\":\"%s\":\"iso\" must be an array or a number.\n", bw ? "white" : "black"); + return false; + } + js = cJSON_GetObjectItem(ji, "levels"); + if (!js) { + fprintf(stderr, "missing \"ranges\":\"%s\":\"levels\".\n", bw ? "white" : "black"); + return false; + } + struct camera_const_levels lvl; + if (js->type == cJSON_Number) { + lvl.levels[0] = lvl.levels[1] = lvl.levels[2] = lvl.levels[3] = js->valueint; + } else if (js->type == cJSON_Array) { + int i; + for (js = js->child, i = 0; js != NULL && i < 4; js = js->next, i++) { + if (js->type != cJSON_Number) { + fprintf(stderr, "\"ranges\":\"%s\":\"levels\" must be a number or an array of numbers.\n", bw ? "white" : "black"); + return false; + } + lvl.levels[i] = js->valueint; + } + if (i == 3) { + lvl.levels[3] = lvl.levels[1]; // G2 = G1 + } else if (i == 1) { + lvl.levels[3] = lvl.levels[2] = lvl.levels[1] = lvl.levels[0]; + } else if (i != 4 || js != NULL) { + fprintf(stderr, "\"ranges\":\"%s\":\"levels\" array must have 1, 3 or 4 numbers.\n", bw ? "white" : "black"); + return false; + } + } else { + fprintf(stderr, "\"ranges\":\"%s\":\"levels\" must be a number or an array of numbers.\n", bw ? "white" : "black"); + return false; + } + for (int i = 0; i < iso_count; i++) { + cc->mLevels[bw].insert(std::pair(iso[i], lvl)); + } + } + return true; +} + +CameraConst * +CameraConst::parseEntry(void *cJSON_, const char *make_model) +{ + CameraConst *cc = 0; + cJSON *js, *ji, *jranges; + js = (cJSON *)cJSON_; + + cc = new CameraConst; + cc->make_model = Glib::ustring(make_model); + + ji = cJSON_GetObjectItem(js, "dcraw_matrix"); + if (ji) { + if (ji->type != cJSON_Array) { + fprintf(stderr, "\"dcraw_matrix\" must be an array\n"); + goto parse_error; + } + int i; + for (i = 0, ji = ji->child; i < 12 && ji != NULL; i++, ji = ji->next) { + if (ji->type != cJSON_Number) { + fprintf(stderr, "\"dcraw_matrix\" array must contain numbers\n"); + goto parse_error; + } + cc->dcraw_matrix[i] = (short)ji->valueint; + } + } + ji = cJSON_GetObjectItem(js, "raw_crop"); + if (ji) { + if (ji->type != cJSON_Array) { + fprintf(stderr, "\"raw_crop\" must be an array\n"); + goto parse_error; + } + int i; + for (i = 0, ji = ji->child; i < 4 && ji != NULL; i++, ji = ji->next) { + if (ji->type != cJSON_Number) { + fprintf(stderr, "\"raw_crop\" array must contain numbers\n"); + goto parse_error; + } + cc->raw_crop[i] = ji->valueint; + } + if (i != 4 || ji != NULL) { + fprintf(stderr, "\"raw_crop\" must contain 4 numbers\n"); + goto parse_error; + } + } + ji = cJSON_GetObjectItem(js, "masked_areas"); + if (ji) { + if (ji->type != cJSON_Array) { + fprintf(stderr, "\"masked_areas\" must be an array\n"); + goto parse_error; + } + int i; + for (i = 0, ji = ji->child; i < 8 * 4 && ji != NULL; i++, ji = ji->next) { + if (ji->type != cJSON_Number) { + fprintf(stderr, "\"masked_areas\" array must contain numbers\n"); + goto parse_error; + } + cc->raw_mask[i/4][i%4] = ji->valueint; + } + if (i % 4 != 0) { + fprintf(stderr, "\"masked_areas\" array length must be divisable by 4\n"); + goto parse_error; + } + } + jranges = cJSON_GetObjectItem(js, "ranges"); + if (jranges) { + ji = cJSON_GetObjectItem(jranges, "black"); + if (ji) { + if (!parseLevels(cc, 0, ji)) { + goto parse_error; + } + } + ji = cJSON_GetObjectItem(jranges, "white"); + if (ji) { + if (!parseLevels(cc, 1, ji)) { + goto parse_error; + } + } + ji = cJSON_GetObjectItem(jranges, "white_max"); + if (ji) { + if (ji->type != cJSON_Number) { + fprintf(stderr, "\"ranges\":\"white_max\" must be a number\n"); + goto parse_error; + } + cc->white_max = (int)ji->valueint; + } + ji = cJSON_GetObjectItem(jranges, "aperture_scaling"); + if (ji) { + if (!parseApertureScaling(cc, ji)) { + goto parse_error; + } + } + } + for (int bw = 0; bw < 2; bw++) { + struct camera_const_levels lvl; + if (!cc->get_Levels(lvl, bw, 0, 0)) { + std::map::iterator it; + it = cc->mLevels[bw].begin(); + if (it != cc->mLevels[bw].end()) { + // insert levels with lowest iso as the default (iso 0) + struct camera_const_levels lvl = it->second; + cc->mLevels[bw].insert(std::pair(0, lvl)); + } + } + } + return cc; + +parse_error: + return 0; +} + +bool +CameraConst::has_dcrawMatrix(void) +{ + return dcraw_matrix[0] != 0; +} + +void +CameraConst::update_dcrawMatrix(const short *other) { + if (!other) + return; + + for (int i=0; i<12; ++i) + dcraw_matrix[i] = other[i]; +} + +const short * +CameraConst::get_dcrawMatrix(void) +{ + if (!has_dcrawMatrix()) { + return 0; + } + return dcraw_matrix; +} + +bool +CameraConst::has_rawCrop(void) +{ + return raw_crop[0] != 0 || raw_crop[1] != 0 || raw_crop[2] != 0 || raw_crop[3] != 0; +} + +void +CameraConst::get_rawCrop(int& left_margin, int& top_margin, int& width, int& height) +{ + left_margin = raw_crop[0]; + top_margin = raw_crop[1]; + width = raw_crop[2]; + height = raw_crop[3]; +} + +bool +CameraConst::has_rawMask(int idx) +{ + if (idx < 0 || idx > 7) + return false; + return (raw_mask[idx][0] | raw_mask[idx][1] | raw_mask[idx][2] | raw_mask[idx][3]) != 0; +} + +void +CameraConst::get_rawMask(int idx, int& top, int& left, int& bottom, int& right) +{ + top = left = bottom = right = 0; + if (idx < 0 || idx > 7) + return; + top = raw_mask[idx][0]; + left = raw_mask[idx][1]; + bottom = raw_mask[idx][2]; + right = raw_mask[idx][3]; +} + +void +CameraConst::update_Levels(const CameraConst *other) { + if (!other) + return; + + if (other->mLevels[0].size()) { + mLevels[0].clear(); + mLevels[0] = other->mLevels[0]; + } + if (other->mLevels[1].size()) { + mLevels[1].clear(); + mLevels[1] = other->mLevels[1]; + } + if (other->mApertureScaling.size()) { + mApertureScaling.clear(); + mApertureScaling = other->mApertureScaling; + } + if (other->white_max) + white_max = other->white_max; + +// for (std::map::iterator i=other->mLevels[0].begin(); i!=other->mLevels[0].end(); i++) { +// } +} + +bool +CameraConst::get_Levels(struct camera_const_levels & lvl, int bw, int iso, float fnumber) +{ + std::map::iterator it; + it = mLevels[bw].find(iso); + if (it == mLevels[bw].end()) { + std::map::iterator best_it = mLevels[bw].begin(); + if (iso > 0) { + for (it = mLevels[bw].begin(); it != mLevels[bw].end(); it++) { + if (abs(it->first - iso) <= abs(best_it->first - iso)) { + best_it = it; + } else { + break; + } + } + } + it = best_it; + if (it == mLevels[bw].end()) { + return false; + } + } + lvl = it->second; + + if (bw == 1 && fnumber > 0 && mApertureScaling.size() > 0) { + std::map::iterator it; + it = mApertureScaling.find(fnumber); + if (it == mApertureScaling.end()) { + // fnumber may be an exact aperture, eg 1.414, or a rounded eg 1.4. In our map we + // should have rounded numbers so we translate and retry the lookup + + // table with traditional 1/3 stop f-number rounding used by most cameras, we only + // have in the range 0.7 - 10.0, but aperture scaling rarely happen past f/4.0 + const float fn_tab[8][3] = { + { 0.7, 0.8, 0.9 }, + { 1.0, 1.1, 1.2 }, + { 1.4, 1.6, 1.8 }, + { 2.0, 2.2, 2.5 }, + { 2.8, 3.2, 3.5 }, + { 4.0, 4.5, 5.0 }, + { 5.6, 6.3, 7.1 }, + { 8.0, 9.0, 10.0 } + }; + for (int avh = 0; avh < 8; avh++) { + for (int k = 0; k < 3; k++) { + float av = (avh-1) + (float)k / 3; + float aperture = sqrtf(powf(2, av)); + if (fnumber > aperture*0.97 && fnumber < aperture/0.97) { + fnumber = fn_tab[avh][k]; + it = mApertureScaling.find(fnumber); + avh = 7; + break; + } + } + } + } + float scaling = 1.0; + if (it == mApertureScaling.end()) { + std::map::reverse_iterator it; + for (it = mApertureScaling.rbegin(); it != mApertureScaling.rend(); it++) { + if (it->first > fnumber) { + scaling = it->second; + } else { + break; + } + } + } else { + scaling = it->second; + } + if (scaling > 1.0) { + for (int i = 0; i < 4; i++) { + lvl.levels[i] *= scaling; + if (white_max > 0 && lvl.levels[i] > white_max) { + lvl.levels[i] = white_max; + } + } + } + } + return true; +} + +int +CameraConst::get_BlackLevel(const int idx, const int iso_speed) +{ + assert(idx >= 0 && idx <= 3); + struct camera_const_levels lvl; + if (!get_Levels(lvl, 0, iso_speed, 0.0)) { + return -1; + } + return lvl.levels[idx]; +} + +int +CameraConst::get_WhiteLevel(const int idx, const int iso_speed, const float fnumber) +{ + assert(idx >= 0 && idx <= 3); + struct camera_const_levels lvl; + if (!get_Levels(lvl, 1, iso_speed, fnumber)) { + return -1; + } + return lvl.levels[idx]; +} + +bool +CameraConstantsStore::parse_camera_constants_file(Glib::ustring filename_) +{ + // read the file into a single long string + const char *filename = filename_.c_str(); + FILE *stream = fopen(filename, "rt"); + if (stream == NULL) { + fprintf(stderr, "Could not open camera constants file \"%s\": %s\n", filename, strerror(errno)); + return false; + } + size_t bufsize = 4096; + size_t datasize = 0, ret; + char *buf = (char *)malloc(bufsize); + while ((ret = fread(&buf[datasize], 1, bufsize - datasize, stream)) != 0) { + datasize += ret; + if (datasize == bufsize) { + bufsize += 4096; + buf = (char *)realloc(buf, bufsize); + } + } + if (!feof(stream)) { + fclose(stream); + free(buf); + fprintf(stderr, "Failed to read camera constants file \"%s\"\n", filename); + return false; + } + fclose(stream); + buf = (char *)realloc(buf, datasize + 1); + buf[datasize] = '\0'; + + // remove comments + cJSON_Minify(buf); + + // parse + cJSON *jsroot = cJSON_Parse(buf); + if (!jsroot) { + char str[128]; + const char *ep = cJSON_GetErrorPtr() - 10; + if ((uintptr_t)ep < (uintptr_t)buf) { + ep = buf; + } + strncpy(str, ep, sizeof(str)); + str[sizeof(str)-1] = '\0'; + fprintf(stderr, "JSON parse error in file \"%s\" near '%s'\n", filename, str); + free(buf); + return false; + } + free(buf); + /*{ + char *js_str = cJSON_Print(jsroot); + printf("%s\n", js_str); + free(js_str); + }*/ + cJSON *js = cJSON_GetObjectItem(jsroot, "camera_constants"); + if (!js) { + fprintf(stderr, "missing \"camera_constants\" object item\n"); + goto parse_error; + } + for (js = js->child; js != NULL; js = js->next) { + cJSON *ji = cJSON_GetObjectItem(js, "make_model"); + if (!ji) { + fprintf(stderr, "missing \"make_model\" object item\n"); + goto parse_error; + } + bool is_array = false; + if (ji->type == cJSON_Array) { + ji = ji->child; + is_array = true; + } + while (ji != NULL) { + if (ji->type != cJSON_String) { + fprintf(stderr, "\"make_model\" must be a string or an array of strings\n"); + goto parse_error; + } + CameraConst *cc = CameraConst::parseEntry((void *)js, ji->valuestring); + if (!cc) { + goto parse_error; + } + Glib::ustring make_model(ji->valuestring); + make_model = make_model.uppercase(); + std::map::iterator existingccIter = mCameraConstants.find(make_model); + + if (existingccIter == mCameraConstants.end()) { + // add the new CamConst to the map + mCameraConstants.insert(std::pair(make_model, cc)); + if (settings->verbose) { + printf("Add camera constants for \"%s\"\n", make_model.c_str()); + } + } else { + // The CameraConst already exist for this camera make/model -> we merge the values + CameraConst *existingcc = existingccIter->second; + + // updating the dcraw matrix + existingcc->update_dcrawMatrix(cc->get_dcrawMatrix()); + // deleting all the existing levels, replaced by the new ones + existingcc->update_Levels(cc); + if (settings->verbose) { + printf("Merging camera constants for \"%s\"\n", make_model.c_str()); + } + } + if (is_array) { + ji = ji->next; + } else { + ji = NULL; + } + } + } + cJSON_Delete(jsroot); + return true; + +parse_error: + fprintf(stderr, "failed to parse camera constants file \"%s\"\n", filename); + mCameraConstants.clear(); + cJSON_Delete(jsroot); + return false; +} + +CameraConstantsStore::CameraConstantsStore() +{ +} + +static CameraConstantsStore *global_instance; + +void CameraConstantsStore::initCameraConstants(Glib::ustring baseDir, Glib::ustring userSettingsDir) +{ + if (global_instance) { + // should only be called once during init. + abort(); + } + global_instance = new CameraConstantsStore(); + global_instance->parse_camera_constants_file(Glib::build_filename(baseDir, "camconst.json")); + + Glib::ustring userFile(Glib::build_filename(userSettingsDir, "camconst.json")); + if (safe_file_test(userFile, Glib::FILE_TEST_EXISTS)) + global_instance->parse_camera_constants_file(userFile); +} + +CameraConstantsStore * +CameraConstantsStore::getInstance(void) +{ + return global_instance; +} + +CameraConst * +CameraConstantsStore::get(const char make[], const char model[]) +{ + Glib::ustring key(make); + key += " "; + key += model; + key = key.uppercase(); + std::map::iterator it; + it = mCameraConstants.find(key); + if (it == mCameraConstants.end()) { + return 0; + } + return it->second; +} + +} // namespace rtengine diff --git a/rtengine/camconst.h b/rtengine/camconst.h new file mode 100755 index 000000000..cb04c4c49 --- /dev/null +++ b/rtengine/camconst.h @@ -0,0 +1,61 @@ +/* + * This file is part of RawTherapee. + */ +#ifndef __CAMCONST__ +#define __CAMCONST__ + +#include +#include + +namespace rtengine { + +struct camera_const_levels { + int levels[4]; +}; + +class CameraConst { + private: + Glib::ustring make_model; + short dcraw_matrix[12]; + int raw_crop[4]; + int raw_mask[8][4]; + int white_max; + std::map mLevels[2]; + std::map mApertureScaling; + + CameraConst(); + ~CameraConst(); + static bool parseLevels(CameraConst *cc, int bw, void *ji); + static bool parseApertureScaling(CameraConst *cc, void *ji); + bool get_Levels(struct camera_const_levels & lvl, int bw, int iso, float fnumber); + + public: + static CameraConst *parseEntry(void *cJSON, const char *make_model); + bool has_dcrawMatrix(void); + void update_dcrawMatrix(const short *other); + const short *get_dcrawMatrix(void); + bool has_rawCrop(void); + void get_rawCrop(int& left_margin, int& top_margin, int& width, int& height); + bool has_rawMask(int idx); + void get_rawMask(int idx, int& top, int& left, int& bottom, int& right); + int get_BlackLevel(int idx, int iso_speed); + int get_WhiteLevel(int idx, int iso_speed, float fnumber); + void update_Levels(const CameraConst *other); +}; + +class CameraConstantsStore { + private: + std::map mCameraConstants; + + CameraConstantsStore(); + bool parse_camera_constants_file(Glib::ustring filename); + + public: + static void initCameraConstants(Glib::ustring baseDir, Glib::ustring userSettingsDir); + static CameraConstantsStore *getInstance(void); + CameraConst *get(const char make[], const char model[]); +}; + +} + +#endif diff --git a/rtengine/camconst.json b/rtengine/camconst.json new file mode 100755 index 000000000..b2e5f3a4e --- /dev/null +++ b/rtengine/camconst.json @@ -0,0 +1,1539 @@ +/* + + DO NOT EDIT THIS FILE! + + All changes made here will be lost on software update. + If you want to add custom values or changes existing ones, + create a "camconst.json" file next to your personal "options" file. + Its values will then override and/or complete the ones of this file. + + If you add values for your own camera and are okay to share them with + RawTherapee's community, please drop a link on the user's forum + + IMPORTANT: + ---------- + + 1. If you set the dcraw matrix in your user file for an already existing entry + in RT's file (same camera, same model), your values will replace RT's ones. + 2. If you set the Black level(s) values in your user file for an already existing + entry in RT's file, your values will replace RT's ones, even if RT's ones are + more complete and/or detailed. You might want to copy/paste RT's levels first + (if provided) to your user's file and complete/modify it. + + Same for the White level(s), independently from the Black level(s). + + +---------------------------------------------------------------------------------- + + +This file is in JSON format and contains camera constants which RawTherapee uses +when parsing raw files. + +Raw files themselves unfortunately do not contain all information needed for making +a raw conversion, typically color response information and black/white levels are +missing. That's why this file is needed. + +It's read once during startup, so if the file is updated you need to restart +RawTherapee in order to take effect. The file is not intended for modification by +the casual user, but advanced users can add missing camera information to this file. +If you do so please report at http://code.google.com/p/rawtherapee/issues so we can +extend the distributed version of this file so your provided camera information +becomes available to all. + +RawTherapee uses DCRAW as the raw format parser. DCRAW contains hard-coded camera +constants, but not for all cameras and not always accurate information. For example +DCRAW only support one white level, while some cameras have different white levels +per channel and per ISO. If a camera is not listed in this file the constants from +DCRAW will be used, if listed here this information will override any constants in +DCRAW (if any). + +Some cameras may only have partial information here, for example if the raw file +itself contains a color matrix it's not entered here. A camera whose black level +is measured on special pixels in the raw file should only have white levels here +etc. + +Examples: + + { + // make and model separated with single space, must match make + // and model as provided by dcraw (case-insensitive). + "make_model": "ManufacturerA ModelB", + // ColorMatrix with D65 Calibration Illuminant, in dcraw format + "dcraw_matrix": [ 7530, -1942, -255, -4318, 11390, 3362, -926, 1694, 7649 ], + // black level (or black offset if a base black is already extracted from exif by Dcraw, see Panasonic, resent Nikon ) + // and white level same for all colors at all ISOs + "ranges": { "black": 10, "white": 1000 }, + // crop away masked sensor borders, 10 pixels left, 20 pixels top, resulting image width/height 4000x3000 + // instead of width/height you can write a negative number which specifies how much of right/bottom border + that should be removed but keep in mind that sometimes after converting to DNG the borders are already + cropped so the "negative number" way is not totally safe. + "raw_crop": [ 10, 20, 4000, 3000 ], + // Almost same as MaskedAreas DNG tag, used for black level measuring here two areas defined + "masked_areas": [ 51, 2, 3804, 156, 51, 5794, 3804, 5792 ], + The difference here is the meaning of the numbers which here are expressing the absolute distance (in pixels) + of each side of each rectangular "masked area" from the top and left side of the sensor + - the first number is the distance of the top edge from the sensor's top + - the second is the distance of the left side from the sensor's left + - the third is the distance of the bottom side from the sensor's top + - the fourth is the distance of the right side from the sensor's left + }, + + { + "make_model": "ManufacturerA ModelB", + "dcraw_matrix": [ 7530,-1942,-255,-4318,11390,3362,-926,1694,7649 ], + // black and white levels per ISO per channel + // this example only two ISOs, normally the list should be more populated. + // When RawTherapee asks for black/white levels for a specific ISO the closest + // match is picked. + "ranges": { + "black": [ + { "iso": 100, "levels": 10 }, // here only one level, same level for all channels + { "iso": 3200, "levels": [ 50, 60, 50 ] } // 3 levels, G2 same as G1 + ], + "white": [ + { "iso": 100, "levels": [ 10000, 11000, 10000, 12000 ] }, // 4 levels, G1 and G2 different + { "iso": 3200, "levels": [ 11000, 11000, 10000, 12000 ] } + ] + } + } + +How to measure white levels: +---------------------------- + +Dcraw which provides the default values to RawTherapee often provides too high +white levels, and only provides a single value regardless of color channel, ISO +or aperture. If you open an image with a large clipped area and that is +rendered in a pink/magenta color rather than white it usually means that the +white level constant is too high. You can fix this by adjusting the +"Raw White Point" in the raw tab inside RawTherapee, or permanently fix it by +measuring and providing a more exact white level in camconst.json so +RawTherapee gets to know from start where the camera actually clips. + +Providing a complete and detailed white-level profile can be a quite large +and complicated effort. As an alternative you can provide a simpler profile. +We suggest one of the following alternatives in rising difficulty (and +generally diminishing return): + +A) Provide a single white-level value measured on the native ISO (base ISO). + For many cameras this will actually be complete information, those that + don't vary on channel, ISO or aperture. +B) Check through all ISOs and if there are differences in white level provide + an array with white level per ISO. +C) In addition to ISO, check for aperture scaling and add that. +D) In addition to ISO and aperture scaling check for color channel + differences and add that. + +Doing A) is often better than nothing, as dcraw's default is often too high. +B) can also be worthwhile for some cameras (or else you'll get pink highlights +for some ISOs), while C) and D) can generally be seen as fine-tuning. + +Here follows a guide how to measure white levels (clipping levels): + +Shoot with your camera into a bright light source, such as a lamp, and make +sure the shutter speed is long enough to get overexposure (we want +clipping!). Preferably overexpose lightly, say 1 or 2 stops if you can. The +reason for this is that some cameras with fuzzy white levels may look less +fuzzy than they actually are if over-exposure is heavy. + +Use f/5.6 or smaller aperture (=larger f-number) to avoid any raw scaling +the camera might have for large apertures. + +Open the file in a raw analyzer such as Rawdigger and check the pixel values +for the clipped areas (if you are using Rawdigger, make sure you have disabled +"subtract black" in preferences or else sample values can be wrong). In this +stage we always look at white level before black level subtraction! White +levels can be different on color channel (R, G1, B, G2, note the two greens, +most often both green channels have the same white level though) and vary +depending on ISO setting, so if you want to provide a complete profile make +one shoot for each ISO (even 1/3 steps, so yes it can be quite a lot of +pictures to shoot and check). + +In addition, many cameras scale the raw values for large apertures. It's +generally not that important to cover this, but if you want to extract most +out of the camera you should cover this too. Then you need to shoot with a +wide aperture lens (ideally the widest available from the manufacturer) and +test each aperture (1/3 steps) from the widest (say f/1.2) until the camera +stops scaling the raw values (usually f/2.8 or f/4.0). If the camera also +have ISO scaling you need to shoot at these different ISOs to detect any +differences in scaling, there can be a bit of variation. If you don't have +access to the widest lens available for the system (say only an f/1.8 lens +instead of an f/1.2) it can still be valuable to have the values down to +what you can provide. Brands known to have models that have aperture scaling +of white levels include Canon and Nikon. Note that if white levels are not +scaled the camera may have raw scaling anyway (Sony for example), but as +such scaling will not affect raw decoding we don't need to care about that. + +PROVIDE CONSERVATIVE VALUES. Most cameras have a little noise at the white +level, and some can have a lot. In your raw analyzer, move around and look at +the values in the clipped areas to get a sense of the variation, and/or look +at the histogram. While it's common to with very little variation, say only ++/-2 units, some can have +/-500 or more (some may have different variation +depending on ISO). There can also be camera-to-camera variation. + +If the white level is set too high RawTherapee will not think the pixels are +clipped and you can get discoloured highlights (usually pink), this is what +we want to avoid. If white level is set too low RawTherapee will clip early, ie +you lose a little highlight detail, but the color is rendered correctly and +highlight reconstruction can work properly, so this is not as bad. This is why +we want conservative values. + +By conservative values we mean that if you see a white level of most often +15760 and occassionally 15759 (ie very small variation of white level which +is a common case), you set the white level around 40-80 14bit units below or +10-20 12bit units. Say at 15700 in this example, or 4080 instead of 4095 for +12bit raws. This way we get a little margin from noise and camera variation. +Since sensor raw values are linear you lose in this example log2(1-50/15760) = +-0.005 stop of detail, ie irrelevant. Thus it's better to provide RawTherapee +with knowledge where the image clips rather than keeping that last 0.005 stop +of highlight information and risking that clipping will not be detected +properly. + +It is very usual for white level to be a bell distribution instead of a candle +when the camera applies long exposure noise reduction by subtracting a black frame +and/or when the system is destabilized due to temperature. Some models have +always a bell distribution at WL. +If you have a fuzzy white level look at the linear histogram; you will probably +see a normal/gaussian distribution (bell shape) noise peak at clipping and +probably also a peak at a hard raw data clip level usually at or close to a +power of two - 1, such as 4095 or 16383. Then you pick a value just before the +bell shape rises, ie to the left of the bell meaning that you cut away the +whole fuzzy noise peak. If a little of the starting edge of the noise will be +included it's not harmful, but 99% of it should be above. +This would mean that it's better to measure white level on long exposure/ high temp +raws but since this if difficult and time consuming we choose to measure on normal +raws and cover the abnormalities whith the conservative WL values. + +If you have used Adobe's DNG Converter and analyzed it's output you may have +noticed that it's very conservative regarding white levels, ie it cuts away +quite a lot from the top. While we also recommend to be conservative, you can +generally be a little bit less so than Adobe's DNG Converter. RawTherapee is +meant to max out what you can get from your camera, and the white levels should +mirror that, within reason. + +The aperture scaling feature is meant to raise the white level to not miss out +on highlight detail when the camera has scaled the raw values (and thus +raised white levels). Many cameras do this, but not all, and can only do it +for lenses that report aperture to the camera (ie you see it in the EXIF +data). Providing proper aperture scaling values is a bit more advanced task, +so if you are unsure we recommend to skip that part. + +Beware that the raw format may have a ceiling so that it clips scaled values, +for example the Canon 5D mark II maxes out at 16383 which happens at f/1.8 +for ISOs with the white level at 15750, but for ISO160 when the white level +is 12800 it does not max out. If there is such a raw limit it must also be +provided ("ranges":"white_max"). Usually you will not need a margin on +white_max as it clips there as a result of an in-camera math operation. + +Note that aperture scaling can be quite small, for the 5D mark II it's only +0.2 stop down to f/1.2 and then it can be discussed if it's worthwhile to care. +The "worst" cameras scale about 0.6 stops though, and then it's more +valuable to compensate. If you skip aperture scaling RawTherapee will clip the +files a little bit too early and you miss that last fraction of highlight +detail, but you get no processing problems. Setting unconservative scale +factors can on the other hand cause a too high whitelevel and break highlight +processing, so be careful. + +Scaling can vary sligthly depending on ISO (if white levels vary) so make +sure to provide conservative scalings so regardless of ISO you don't get a +too high white level. We recommend to keep a small margin here also +white levels, ie 0.5% lower or so. For example if base (not conservative!) +white level is 15750 and the scaled is 16221 we have a scaling factor of +16221/15750=1.0299 ie +2.9% we set the factor to 1.025 to keep a margin. +The abnormal cases are already covered by setting conservative per ISO White levels. + +The scale factor you provide here is applied on the white level before black +level subtraction (if any), ie directly on the white level value you provide in +the camconst.json file. Black level (if provided) is not scaled. Please report +to us if you come across a camera which scales black levels, then we can add +that as an option. Usually the camera applies an offset to shift back the +black level to the standard level after scaling. + +If RawTherapee doesn't find an entry for the aperture used in the image, it +will pick the closest above. Ie if the apertures 1.0 and 2.0 is in the table +and the image has aperture 1.2, it will pick scaling for 2.0, even if 1.0 is +the closer aperture. The reason for always checking the closest above is that +we rather get a bit too low white level than too high, as discussed before. + +Some cameras have different white levels on different color channels. When +this is the case the difference is often so small so you can just provide a +single value instead, ie a conservative value based on the lowest clipping. + +What we know at the time of writing about different brands/models (not +complete info): + + - Canon CR2: typically same clipping per channel, but significant variations + on ISO and aperture. Maxes out at 16383, black level measured on masked + black pixels, ie don't provide that. + - Nikon NEF: sometimes different clipping per color (most often negligible + though). Will do aperture and ISO scaling, but often to a lesser extent + than Canon files, ie not as much to gain. + - Sony ARW2: no scaling. Generally black level around 512, and white level + 16350 and to be conservative say 16300. + +Note that some raw formats may go through a certain amount of pre-processing +based on meta data, such as curve and levels adjustments and various +calibrations. The Phase One IIQ is one example, and this means that if you +look at the data in a raw analyzer such as RawDigger it may perform a +different type of preprocessing than RawTherapee's loader does, and you may +end up providing incompatible black/white levels. + +You can use RawTherapee for analysis too, it's safer as you are using it's +own raw decoder but it's not as user-friendly: enable verbose mode in options +so you get output on the console. When you load a file you will see a message +of current black and white levels and if they came from dcraw or camconst.json. +If you're adjusting an existing camconst.json value you can just read what it is in +the file and not need to enable verbose output. + +Reset exposure sliders to neutral, and zoom in on a large clipped highlight. +Move around the mouse pointer within, it should show stable 100% on R G B. If +so, the white level is not too high, it could however be too low. To test that, +go to the raw tab and adjust the "whitepoint linear correction factor", reduce +it until one of the channels is no longer 100%, and then increase in steps of +0.01 until all are 100 again. Usually you play around in the range 0.90 to +0.99, ie a very small adjustment. When you've found this factor you should +apply it on the old white level to find a new larger one. As RT's "whitepoint +linear correction factor" work after blacklevel subtraction and camconst.json +want values without it we need to do some math: + +BL = black level (typically something near 0, 256, 512, 1024 or 2048 find it in the + verbose output or if available in camconst.json) +F = whitepoint linear correction factor you just found out (typically in the + range 0.90 to 0.99 if you need to increase white level, 1.01 to 1.10 if + decrease) +oldWL = old white level, found in verbose output or in camconst.json if + available. + +new white level = BL + (oldWL - BL) / F + +Note that if black level is 0 which it is for many cameras, the formula +simplifies to: new white level = oldWL / F. + +Here's an example from a Canon 1000D: black level is 256, old white level is +3651, whitepoint correction factor becomes 0.90, then new white level is +256 + (3651 - 256) / 0.9 = 4028. + +If your camera have different black levels per channel use the one which +yields the smallest white level (can be the largest or smallest, test!). + +This new white level you then enter in your camconst.json file. The same +procedure can be used if the white level is too high, ie if you see pink +highlights, then increase the correction factor above 1.0 until you just start +seeing stable 100% on all channels, you use the same formula to calculate the +new smaller white level. + +About black levels: +------------------- + +Unlike for white levels it's much more common that black levels can be +derived from the format. Either it's simply 0 (typical for old Nikon cameras, +newer Nikons (year2013-14) have a BL at around 150 12bit or 600/768 14bit ), +or it can be derived from masked pixels (typical for Canon cameras) or otherwise +be extracted from some tag. +Some formats have built-in subtraction information and are pre-processed by DCRaw +to end up at a black level of zero(Phase One's IIQ). +For Panasonic raws beginning from Dcraw v9.21 Dcraw/RT reads base BL from exif data +(tags 0x001c BlackLevelRed, 0x001d BlackLevelGreen, 0x001e BlackLevelBlue)and we +define in "ranges": { "black": the needed offset of around 15. The (total) BL RT displays is base+offset +In all, you typically should not care about the black level in camconst.json, +any information that can be derived from the raw file itself should not be specified in camconst.json! +Sony's ARW2 is one of the few exceptions (with single black level around 512, or 800 for RX10/100 models), +but DCraw generally has good constants for these already. + +Currently we have chosen not to provide any guide how to measure black levels +as we don't think it will be a common task (it's also more difficult to do +than measure white levels). If you experience a black level issue it's more +likely due to a format parsing bug which should be fixed in DCRaw and/or +RawTherapee's raw format parser. + +How does a black level issue look? If the image has a color cast and is +possibly duller than normal it's likely that black levels are off. The color +cast is typically stronger in darker colors but it can be hard to see, it's +more often experienced as a cast over the whole image. + +*/ +{"camera_constants": [ + +/* + +When adding camera constants please set a quality level so we know the status for future updates + +Quality A: complete information, no need to add more, to the best of our knowledge +Quality B: not complete, but very little to gain from adding more +Quality C: complementing with additional information would provide significant gain +Quality X: unknown, ie we knowing to little about the camera properties to know if + we have enough info or not. + +*/ + + { // quality A + "make_model": "Canon EOS 5D Mark II", + "dcraw_matrix": [ 4716,603,-830,-7798,15474,2480,-1496,1937,6651 ], + "ranges": { + // black levels are read from raw masked pixels + // white levels are same for all colors, but vary on ISO + "white": [ + { "iso": 50, "levels": 15600 }, // typical: 15760 + { "iso": 100, "levels": 15600 }, + { "iso": 125, "levels": 15600 }, + { "iso": 160, "levels": 12700 }, + { "iso": 200, "levels": 15600 }, + { "iso": 250, "levels": 15600 }, + { "iso": 320, "levels": 12700 }, // typical: 12810 + { "iso": 400, "levels": 15600 }, + { "iso": 500, "levels": 15600 }, + { "iso": 640, "levels": 12700 }, + { "iso": 800, "levels": 15600 }, + { "iso": 1000, "levels": 15600 }, + { "iso": 1250, "levels": 12700 }, + { "iso": 1600, "levels": 15600 }, + { "iso": 2000, "levels": 15600 }, + { "iso": 2500, "levels": 15600 }, + { "iso": 3200, "levels": 15600 }, + { "iso": 4000, "levels": 15600 }, + { "iso": 5000, "levels": 15600 }, + { "iso": 6400, "levels": 16200 }, // typical: 16383 + { "iso": 12800, "levels": 16200 }, + { "iso": 25600, "levels": 16200 } + ], + "white_max": 16383, + "aperture_scaling": [ + /* note: no scale factors known for and f/1.0 (had no lenses to test with), but the + typical 15700 white level maxes out at "white_max" for f/1.8 and below anyway. */ + { "aperture": 1.2, "scale_factor": 1.100 }, // guessed by relative 5DIII data + { "aperture": 1.4, "scale_factor": 1.077 }, + { "aperture": 1.6, "scale_factor": 1.054 }, + { "aperture": 1.8, "scale_factor": 1.039 }, + { "aperture": 2.0, "scale_factor": 1.031 }, + { "aperture": 2.2, "scale_factor": 1.021 }, + { "aperture": 2.5, "scale_factor": 1.016 }, + { "aperture": 2.8, "scale_factor": 1.010 }, + { "aperture": 3.2, "scale_factor": 1.004 }, + { "aperture": 3.5, "scale_factor": 1.003 } + ] + } + }, + { // quality A, + "make_model": "Canon EOS 5D Mark III", + "dcraw_matrix": [ 6722,-635,-963,-4287,12460,2028,-908,2162,5668 ], + "ranges": { + // black levels are read from raw masked pixels + // white levels are same for all colors, but vary on ISO + "white": [ + { "iso": [ 50, 100, 125, 200, 250, 400, 500, 800, 1000, 1600, 2000, 3200, 4000, 6400, 8000, 12800, 16000, 20000 ], "levels": 15180 }, // typical: 15282 + { "iso": [ 160, 320, 640, 1250, 2500, 5000, 10000 ], "levels": 13200 }, // typical: 13306 + { "iso": [ 25600, 32000, 40000, 51200, 102400 ], "levels": 16200 } + ], + "white_max": 16383, + "aperture_scaling": [ + { "aperture": 1.2, "scale_factor": 1.130 }, + { "aperture": 1.4, "scale_factor": 1.090 }, + { "aperture": 1.6, "scale_factor": 1.065 }, + { "aperture": 1.8, "scale_factor": 1.040 }, + { "aperture": 2.0, "scale_factor": 1.025 }, + { "aperture": 2.2, "scale_factor": 1.020 }, + { "aperture": 2.5, "scale_factor": 1.015 }, + { "aperture": 2.8, "scale_factor": 1.010 }, + { "aperture": 3.2, "scale_factor": 1.005 }, + { "aperture": 3.5, "scale_factor": 1.002 } + ] + } + }, + + { // Quality C, intermediate ISO samples missing but safely guessed, aperture scaling measures missing + "make_model": [ "Canon EOS 5DS R", "Canon EOS 5DS" ], + // "dcraw_matrix": [ 6848,-1661,-221,-3904,10931,3434,-470,1251,6039 ], // DNG_V9.0 A + "dcraw_matrix": [ 6250,-711,-808,-5153,12794,2636,-1249,2198,5610 ], // DNG_V9.0 D65 + "raw_crop": [ 192, 96, 8696, 5800 ], // 800, 300, 7500, 4700 - 160,64,8730x5800 - sensor 8896x5920 top64, left160, official crop left196, top100, right 8883, bottom 5891, 8688X5792 + "masked_areas": [ 100, 40, 5892, 158 ], // left out 40 first columns from calculations because possibly the BL is still imbalanced there + "ranges": { + "white": [ + { "iso": 100, "levels": 14650 }, // typical 14733 + { "iso": [ 160, 320, 640, 1250, 2500, 5000 ], "levels": 15280 }, // typical 15383 + { "iso": [ 125, 200, 250, 400, 500, 800, 1000, 1600, 2000, 3200 ], "levels": 15280 }, // typical 15383 + { "iso": [ 4000, 6400, 8000, 10000, 12800, 16000, 20000, 25600 ], "levels": 15100 } // clippings at R 15200-15280, G1,G2,B 15360-15390 + ], + "white_max": 16383, + "aperture_scaling": [ + /* note: scale factors measured for f/2.8 only, */ + { "aperture": 1.4, "scale_factor": 1.055 }, // guessed + { "aperture": 1.6, "scale_factor": 1.034 }, // guessed + { "aperture": 1.8, "scale_factor": 1.021 }, // guessed + { "aperture": 2.0, "scale_factor": 1.013 }, // guessed + { "aperture": 2.2, "scale_factor": 1.008 }, // guessed + { "aperture": 2.5, "scale_factor": 1.005 }, // guessed + { "aperture": 2.8, "scale_factor": 1.003 }, // 14783/14733 + { "aperture": 3.2, "scale_factor": 1.000 }, // guessed + { "aperture": 3.5, "scale_factor": 1.000 } + ] + } + }, + + { // Quality A, some missing scaling factors are safelly guessed - most samples by sfink16 at RT forums + "make_model": "Canon EOS 6D", + "dcraw_matrix": [ 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 ], + "ranges": { + "white": [ + { "iso": [ 50, 100, 125, 200, 250, 400, 500, 800, 1000, 1600, 2000, 3200, 4000, 6400, 8000, 12800, 16000, 25600 ], "levels": 15180 }, // typical 15283 + { "iso": [ 160, 320, 640, 1250, 2500, 5000, 10000, 20000 ], "levels": 13100 }, // typical 13225 + { "iso": [ 51200, 102400 ], "levels": 16280 } // typical 16383 + ], + "white_max": 16383, + "aperture_scaling": [ + /* note: no scale factors known for f/1.0 (had no lenses to test with), but the + ISO 160-320... 12650 white levels maxes out at "white_max" for f/1.2 and below anyway. */ + { "aperture": 1.2, "scale_factor": 1.130 }, // from histogramm 1 gap in every 7 levels + { "aperture": 1.4, "scale_factor": 1.090 }, // histogram 3 gaps in every 32 levels + { "aperture": 1.6, "scale_factor": 1.060 }, // 16213/15283 + { "aperture": 1.8, "scale_factor": 1.040 }, // guessed + { "aperture": 2.0, "scale_factor": 1.030 }, // 15800/15283 + { "aperture": 2.2, "scale_factor": 1.020 }, // guessed + { "aperture": 2.5, "scale_factor": 1.015 }, // 15541/15283 + { "aperture": 2.8, "scale_factor": 1.010 }, // 15437/15283 + { "aperture": 3.2, "scale_factor": 1.005 }, // 15361/15283 + { "aperture": 3.5, "scale_factor": 1.000 } // no sample + ] + } + }, + { // Quality A, ISO and aperture WL data by CharlyW at RawTherapee forums, missing samples safely guessed + "make_model": "Canon EOS 7D", + "dcraw_matrix": [ 5962,-171,-732,-4189,12307,2099,-911,1981,6304 ], // Colin Walker + // "dcraw_matrix": [ 6844,-996,-856,-3876,11761,2396,-593,1772,6198 ], // dcraw + "ranges": { + "white": [ + { "iso": [ 100, 125 ], "levels": 13480 }, // typical 13584 + { "iso": [ 160, 320, 640, 1250, 2500 ], "levels": 12550 }, // typical 12650 + { "iso": [ 200, 250, 400, 500, 800, 1000, 1600, 2000, 3200, 4000, 5000, 6400, 12800 ], "levels": 15200 } // typical 15304 + ], + "white_max": 16383, + "aperture_scaling": [ + /* note: no scale factors known for f/1.2 and f/1.0 (no lenses to test with), but the + typical 12650 white levels maxes out at "white_max" for f/1.4 and below anyway. */ + { "aperture": 1.4, "scale_factor": 1.250 }, // guessed + { "aperture": 1.6, "scale_factor": 1.150 }, // guessed + { "aperture": 1.8, "scale_factor": 1.110 }, // 15196/13584 + { "aperture": 2.0, "scale_factor": 1.080 }, // 14734/13584 + { "aperture": 2.2, "scale_factor": 1.050 }, // 14386/13584 + { "aperture": 2.5, "scale_factor": 1.040 }, // 14272/13584 + { "aperture": 2.8, "scale_factor": 1.030 }, // 14042/13584 + { "aperture": 3.2, "scale_factor": 1.015 }, // guessed + { "aperture": 3.5, "scale_factor": 1.000 } // guessed negligible + ] + } + }, + + { // Quality b, ISO and aperture WL data by ..... at RawTherapee forums, missing samples safely guessed + "make_model": "Canon EOS 550D", + "dcraw_matrix": [ 6941,-1164,-857,-3825,11597,2534,-416,1540,6039 ], // dcraw 550d + "ranges": { + "white": [ + { "iso": [ 100, 125 ], "levels": 13480 }, // typical 13584 + { "iso": [ 160, 320, 640, 1250, 2500 ], "levels": 12550 }, // typical 12650 + { "iso": [ 200, 250, 400, 500, 800, 1000, 1600, 2000, 3200, 4000, 5000, 6400, 12800 ], "levels": 15200 } // typical 15304 + ], + "white_max": 16383, + "aperture_scaling": [ + /* note: no scale factors known for f/1.2 and f/1.0 (no lenses to test with), but the + typical 12650 white levels maxes out at "white_max" for f/1.4 and below anyway. */ + { "aperture": 1.4, "scale_factor": 1.250 }, // guessed + { "aperture": 1.6, "scale_factor": 1.150 }, // guessed + { "aperture": 1.8, "scale_factor": 1.110 }, // 15196/13584 + { "aperture": 2.0, "scale_factor": 1.080 }, // 14734/13584 + { "aperture": 2.2, "scale_factor": 1.050 }, // 14386/13584 + { "aperture": 2.5, "scale_factor": 1.040 }, // 14272/13584 + { "aperture": 2.8, "scale_factor": 1.030 }, // 14042/13584 + { "aperture": 3.2, "scale_factor": 1.015 }, // guessed + { "aperture": 3.5, "scale_factor": 1.000 } // guessed negligible + ] + } + }, + { // Quality A, f/1.6 aperture scale factor missing but safely guessed, ISO and aperture data by charlyw at RT forums + "make_model": "Canon EOS 7D Mark II", + "dcraw_matrix": [ 7268,-1082,-969,-4186,11839,2663,-825,2029,5839 ], // dng_v8.7 d65 + // "dcraw_matrix": [ 6285,-147,-821,-4080,11695,2714,-1045,2459,5497 ], // DXO D50 + "ranges": { + "white": [ + { "iso": [ 100, 125 ], "levels": 13500 }, // typical 13583 - LENR 13550 + { "iso": [ 160, 320, 640, 1250, 2500, 5000 ], "levels": 12500 }, // typical 12559 + { "iso": [ 200, 250, 400, 500, 800, 1000, 1600, 2000, 3200, 4000 ], "levels": 15200 }, // typical 15303 - LENR 15270,15260,15240,15220, + { "iso": [ 6400, 8000, 10000, 12800, 16000, 20000, 25600 ], "levels": 15100 }, // typical G1,G2 15303, R,B = 15430 LENR 15200 .. 15100 + { "iso": 51200, "levels": 16300 } // typical 16383 red 16371 + ], + "white_max": 16383, + "aperture_scaling": [ + /* note: no scale factors known for f/1.6, f/1.0 (had no lenses to test with) */ + { "aperture": 1.4, "scale_factor": 1.200 }, // 15100/12277 exif + { "aperture": 1.6, "scale_factor": 1.100 }, // guessed + { "aperture": 1.8, "scale_factor": 1.050 }, // 14372/13583 - 13283 + { "aperture": 2.0, "scale_factor": 1.030 }, // 14034/13583 - 12973 + { "aperture": 2.2, "scale_factor": 1.015 }, // 13808/13583 - 12766 + { "aperture": 2.5, "scale_factor": 1.007 }, // 13696/13583 - 12662 + { "aperture": 2.8, "scale_factor": 1.007 }, // 13696/13583 - 12663 + { "aperture": 3.2, "scale_factor": 1.000 }, // 13583/13583 - 12559 + { "aperture": 3.5, "scale_factor": 1.000 } + ] + } + }, + + { // Quality A - ISO and aperture WL data by Ilias at Avclub gr forums + "make_model": "Canon EOS 40D", + "dcraw_matrix": [ 6071,-747,-856,-7653,15365,2441,-2025,2553,7315 ], + "raw_crop": [ 30, 18, 3908, 2602 ], + "masked_areas": [ 20, 2, 2616, 20 ], + "ranges": { + "white": [ + { "iso": 100, "levels": 13700 }, // typical 13825 + { "iso": [ 125, 250, 500, 1000, 3200 ], "levels": 16280 }, // typical 16383 + { "iso": [ 160, 320, 640 ], "levels": 12600 }, // typical 12744 + { "iso": [ 200, 400 ], "levels": 16100 }, // typical 16224 + { "iso": 800, "levels": 15900 }, // gaussian histogram 15900-16224 + { "iso": 1600, "levels": 14900 }, // gaussian histogram 14900-15750 + { "iso": 1250, "levels": 11900 } // gaussian histogram 11900-12500 + ], + "white_max": 16383, + "aperture_scaling": [ + /* note: no scale factors known for f/1.2 and f/1.0 (had no lenses to test with), but the + typical 12700 white levels maxes out at "white_max" for f/1.4 and below anyway. */ + { "aperture": 1.4, "scale_factor": 1.265 }, // 16142/12744 + { "aperture": 1.6, "scale_factor": 1.145 }, // 15872/13825 + { "aperture": 1.8, "scale_factor": 1.090 }, // 15103/13825 + { "aperture": 2.0, "scale_factor": 1.035 }, // 14334/13825 + { "aperture": 2.2, "scale_factor": 1.005 }, // 13950/13825 + { "aperture": 2.5, "scale_factor": 1.000 } // 13825/13825 + ] + } + }, + { // Quality A, ISO and aperture WL data by Ayshih at Magic Lantern forums + "make_model": "Canon EOS 50D", + "dcraw_matrix": [ 4920,616,-593,-6493,13964,2784,-1774,3178,7005 ], + "ranges": { + "white": [ + { "iso": [ 100, 125 ], "levels": 13300 }, // typical 13432 + { "iso": [ 160, 320, 640, 1250 ], "levels": 12700 }, // typical 12790-12810 + { "iso": [ 200, 250, 400, 500, 800, 1000, 1600, 2000, 2500, 3200 ], "levels": 15630 }, // typical 15763-15733 + { "iso": [ 6400, 12800 ], "levels": 16200 } // typical 16383 + ], + "white_max": 16383, + "aperture_scaling": [ + { "aperture": 1.4, "scale_factor": 1.270 }, + { "aperture": 1.6, "scale_factor": 1.150 }, + { "aperture": 1.8, "scale_factor": 1.090 }, + { "aperture": 2.0, "scale_factor": 1.040 }, + { "aperture": 2.2, "scale_factor": 1.020 }, + { "aperture": 2.5, "scale_factor": 1.010 }, + { "aperture": 2.8, "scale_factor": 1.000 }, + { "aperture": 3.2, "scale_factor": 1.000 } + ] + } + }, + { // Quality A, ISO and aperture WL data copyed from Shalrath's 60D data at RawTherapee forums + "make_model": "Canon EOS 60Da", + "dcraw_matrix": [ 17492,-7240,-2023,-1791,10323,1701,-186,1329,5406 ], // 60Da dng d65 + "ranges": { + "white": [ + { "iso": [ 100, 125 ], "levels": 13480 }, // typical 13583 + { "iso": [ 160, 320, 640, 1250, 2500 ], "levels": 12550 }, // typical 12650 + { "iso": [ 200, 250, 400, 500, 800, 1000, 1600, 2000, 3200, 4000, 5000, 6400, 12800 ], "levels": 15200 } // typical 15304 + ], + "white_max": 16383, + "aperture_scaling": [ + /* note: no scale factors known for f/1.2 and f/1.0 (had no lenses to test with), but the + typical 12650 white levels maxes out at "white_max" for f/1.4 and below anyway. */ + { "aperture": 1.4, "scale_factor": 1.300 }, // gaps 81of301 + { "aperture": 1.6, "scale_factor": 1.200 }, + { "aperture": 1.8, "scale_factor": 1.140 }, + { "aperture": 2.0, "scale_factor": 1.080 }, // gaps 1of11 + { "aperture": 2.2, "scale_factor": 1.060 }, + { "aperture": 2.5, "scale_factor": 1.050 }, + { "aperture": 2.8, "scale_factor": 1.030 }, + { "aperture": 3.2, "scale_factor": 1.015 }, + { "aperture": 3.5, "scale_factor": 1.000 } // no sample but it would be negligible + ] + } + }, + { // Quality A, ISO and aperture WL data by Shalrath at RawTherapee forums + "make_model": "Canon EOS 60D", + "dcraw_matrix": [ 6719,-994,-925,-4408,12426,2211,-887,2129,6051 ], + "ranges": { + "white": [ + { "iso": [ 100, 125 ], "levels": 13480 }, // typical 13583 + { "iso": [ 160, 320, 640, 1250, 2500 ], "levels": 12550 }, // typical 12650 + { "iso": [ 200, 250, 400, 500, 800, 1000, 1600, 2000, 3200, 4000, 5000, 6400, 12800 ], "levels": 15200 } // typical 15304 + ], + "white_max": 16383, + "aperture_scaling": [ + /* note: no scale factors known for f/1.2 and f/1.0 (had no lenses to test with), but the + typical 12650 white levels maxes out at "white_max" for f/1.4 and below anyway. */ + { "aperture": 1.4, "scale_factor": 1.300 }, // gaps 81of301 + { "aperture": 1.6, "scale_factor": 1.200 }, + { "aperture": 1.8, "scale_factor": 1.140 }, + { "aperture": 2.0, "scale_factor": 1.080 }, // gaps 1of11 + { "aperture": 2.2, "scale_factor": 1.060 }, + { "aperture": 2.5, "scale_factor": 1.050 }, + { "aperture": 2.8, "scale_factor": 1.030 }, + { "aperture": 3.2, "scale_factor": 1.015 }, + { "aperture": 3.5, "scale_factor": 1.000 } // no sample but it would be negligible + ] + } + }, + { // Quality B, more aperture scale factors needed + "make_model": "Canon EOS 70D", + "dcraw_matrix": [ 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 ], // DNG D65 + "ranges": { + "white": [ + { "iso": [ 100, 125 ], "levels": 13480 }, // typical 13583 + { "iso": [ 160, 320, 640, 1250, 2500, 5000 ], "levels": 12450 }, // typical 12559 + { "iso": [ 200, 250, 400, 500, 800, 1000, 1600, 2000, 3200, 4000, 6400, 8000, 10000 ], "levels": 15200 }, // typical 15303 - ISO 8000-10000 guessed + { "iso": [ 12800, 25600 ], "levels": 16200 } // typical 16383 + ], + "white_max": 16383, + "aperture_scaling": [ + /* note: no scale factors known for f/1.2 and f/1.0 (had no lenses to test with), but even with the + 12500 white levels nearly maxes out for f/1.4 and below anyway. */ + { "aperture": 1.4, "scale_factor": 1.240 }, // guessed + { "aperture": 1.6, "scale_factor": 1.160 }, // guessed + { "aperture": 1.8, "scale_factor": 1.110 }, // 31of35 + { "aperture": 2.0, "scale_factor": 1.060 }, // guessed + { "aperture": 2.2, "scale_factor": 1.030 }, // guessed + { "aperture": 2.5, "scale_factor": 1.015 }, // guessed + { "aperture": 2.8, "scale_factor": 1.008 }, // 15432/15303 + { "aperture": 3.2, "scale_factor": 1.000 }, + { "aperture": 3.5, "scale_factor": 1.000 } + ] + } + }, + + { // Quality b, scaling factors missing but guessed safely + "make_model": [ "Canon EOS 1200D", "Canon EOS Rebel T5", "Canon EOS 600D", "Canon EOS Rebel T3i" ], + "dcraw_matrix": [ 6461,-907,-882,-4300,12184,2378,-819,1944,5931 ], // dcp D65 colormatrix2 + "ranges": { + "white": [ + { "iso": [ 100, 125 ], "levels": 13480 }, // typical 13583 + { "iso": [ 160, 320, 640, 1250, 2500, 5000, 10000 ], "levels": 12550 }, // typical 12650 + { "iso": [ 200, 250, 400, 500, 800, 1000, 1600, 2000, 3200, 4000, 6400, 8000, 12800 ], "levels": 15200 } // typical 15303 + ], + "white_max": 16383, + "aperture_scaling": [ + /* note: no scale factors known for f/1.2 and f/1.0 (had no lenses to test with), but the + typical 12650 white levels maxes out at "white_max" for f/1.4 and below anyway. */ + { "aperture": 1.4, "scale_factor": 1.290 }, // guessed from 60D data + { "aperture": 1.6, "scale_factor": 1.190 }, // guessed + { "aperture": 1.8, "scale_factor": 1.140 }, // guessed + { "aperture": 2.0, "scale_factor": 1.090 }, // 12293/11222 = 1.095 + { "aperture": 2.2, "scale_factor": 1.060 }, // 11971/11222 = 1.066 + { "aperture": 2.5, "scale_factor": 1.050 }, // guessed + { "aperture": 2.8, "scale_factor": 1.030 }, // iso100: 14042/13584=1.0336 - iso200 15820/15303 = 1.0348 + { "aperture": 3.2, "scale_factor": 1.000 }, // + { "aperture": 3.5, "scale_factor": 1.000 } // + ] + } + }, + + { // Quality A, only one scaling factor missing and guessed safely + "make_model": [ "Canon EOS 650D", "Canon EOS Rebel T4i" ], + "dcraw_matrix": [ 6602,-841,-939,-4472,12458,2247,-975,2039,6148 ], + "ranges": { + "white": [ + { "iso": [ 100, 125 ], "levels": 13480 }, // typical 13583 + { "iso": [ 160, 320, 640, 1250, 2500, 5000, 10000 ], "levels": 12550 }, // typical 12650 + { "iso": [ 200, 250, 400, 500, 800, 1000, 1600, 2000, 3200, 4000, 6400, 8000 ], "levels": 15200 }, // typical 15303 + { "iso": [ 12800, 25600 ], "levels": 16200 } // typical 16383 + ], + "white_max": 16383, + "aperture_scaling": [ + /* note: no scale factors known for f/1.2 and f/1.0 (had no lenses to test with), but the + typical 12650 white levels maxes out at "white_max" for f/1.4 and below anyway. */ + { "aperture": 1.4, "scale_factor": 1.200 }, // 16332/13583 + { "aperture": 1.6, "scale_factor": 1.080 }, // guessed + { "aperture": 1.8, "scale_factor": 1.055 }, // 14372/13583 + { "aperture": 2.0, "scale_factor": 1.030 }, // 14034/13583 + { "aperture": 2.2, "scale_factor": 1.025 }, // 13921/13583 + { "aperture": 2.5, "scale_factor": 1.020 }, // + { "aperture": 2.8, "scale_factor": 1.000 }, // + { "aperture": 3.2, "scale_factor": 1.000 }, // + { "aperture": 3.5, "scale_factor": 1.000 } // + ] + } + }, + + { // Quality C, aperture scale factors and intermediate ISOs missing but safely guessed + "make_model": [ "Canon EOS 750D", "Canon EOS Rebel T6i", "Canon EOS 760D", "Canon EOS Rebel T6s" ], + "dcraw_matrix": [ 6362,-823,-847,-4426,12109,2616,-743,1857,5635 ], // dng_v9.0 d65 + "raw_crop": [ 72, 34, 6024, 4022 ], // full size 6096x4056, official crop 84,46,6083,4045 + "masked_areas": [ 40, 16, 4000, 54 ], + "ranges": { + "white": [ + { "iso": [ 100, 125 ], "levels": 13300 }, // typical 13583 + { "iso": [ 160, 320, 640, 1250, 2500, 5000 ], "levels": 12500 }, // typical 12600 + { "iso": [ 200, 250, 400, 500, 800, 1000, 1600, 2000, 3200, 4000 ], "levels": 15200 }, // typical 15303 + { "iso": [ 6400, 8000, 10000, 12800, 16000, 20000 ], "levels": 15100 }, // typical 15303 + { "iso": 25600, "levels": 16300 } // typical 16383 + ], + "white_max": 16383, + "aperture_scaling": [ + /* note: all scale factors are guessed to be same as 7DII */ + { "aperture": 1.4, "scale_factor": 1.200 }, // guessed + { "aperture": 1.6, "scale_factor": 1.100 }, // guessed + { "aperture": 1.8, "scale_factor": 1.050 }, // guessed + { "aperture": 2.0, "scale_factor": 1.030 }, // guessed + { "aperture": 2.2, "scale_factor": 1.015 }, // guessed + { "aperture": 2.5, "scale_factor": 1.007 }, // guessed + { "aperture": 2.8, "scale_factor": 1.007 }, // guessed + { "aperture": 3.2, "scale_factor": 1.000 }, // guessed + { "aperture": 3.5, "scale_factor": 1.000 } + ] + } + }, + + { // Quality B, missing scaling factors are guessed safely from 650D relative data + "make_model": "Canon EOS M", + "dcraw_matrix": [ 6602,-841,-939,-4472,12458,2247,-975,2039,6148 ], + "ranges": { + "white": [ + { "iso": [ 100, 125 ], "levels": 13480 }, // typical 13583 + { "iso": [ 160, 320, 640, 1250, 2500, 5000, 10000 ], "levels": 12550 }, // typical 12650 + { "iso": [ 200, 250, 400, 500, 800, 1000, 1600, 2000, 3200, 4000, 6400, 8000 ], "levels": 15200 }, // typical 15303 + { "iso": [ 12800, 25600 ], "levels": 16200 } // typical 16383 + ], + "white_max": 16383, + "aperture_scaling": [ + /* note: no scale factors known for f/1.2 and f/1.0 (had no lenses to test with), but the + typical 12650 white levels maxes out at "white_max" for f/1.4 and below anyway. */ + { "aperture": 1.4, "scale_factor": 1.200 }, // guessed + { "aperture": 1.6, "scale_factor": 1.080 }, // guessed + { "aperture": 1.8, "scale_factor": 1.055 }, // guessed + { "aperture": 2.0, "scale_factor": 1.030 }, // 15821/15303 + { "aperture": 2.2, "scale_factor": 1.025 }, // 15691/15303 + { "aperture": 2.5, "scale_factor": 1.020 }, // 12947/12650 + { "aperture": 2.8, "scale_factor": 1.000 }, // + { "aperture": 3.2, "scale_factor": 1.000 }, // + { "aperture": 3.5, "scale_factor": 1.000 } // + ] + } + }, + + { // Quality C, White Levels not properly indicated, aperture scaling..missing scaling factors are guessed + "make_model": "Canon EOS M3", + "dcraw_matrix": [ 6362,-823,-847,-4426,12109,2616,-743,1857,5635 ], // DNG_V8.8 D65 + "raw_crop": [ 72, 34, 6024, 4022 ], // full size 6096x4056, official crop 84,46,6083,4045 + "masked_areas": [ 40, 16, 4000, 54 ], + "ranges": { + "white": [ + { "iso": [ 100, 125, 160 ], "levels": 16300 }, // 16383 + { "iso": [ 320, 640, 1250, 2500, 5000, 10000 ], "levels": 12600 }, // 12632..14500 + { "iso": [ 200, 250, 400, 500, 800, 1000, 1600, 2000, 3200, 4000 ], "levels": 15000 }, // 15095, 15488 + { "iso": [ 6400, 8000, 12800, 25600 ], "levels": 16200 } // 16383 + ], + "white_max": 16383, + "aperture_scaling": [ + /* note: need for more data to properly fill all scale factors */ + { "aperture": 1.4, "scale_factor": 1.200 }, // guessed + { "aperture": 1.6, "scale_factor": 1.080 }, // guessed + { "aperture": 1.8, "scale_factor": 1.055 }, // guessed + { "aperture": 2.0, "scale_factor": 1.030 }, // guessed + { "aperture": 2.2, "scale_factor": 1.025 }, // guessed + { "aperture": 2.5, "scale_factor": 1.020 }, // guessed + { "aperture": 2.8, "scale_factor": 1.000 }, // + { "aperture": 3.2, "scale_factor": 1.000 }, // + { "aperture": 3.5, "scale_factor": 1.000 } // + ] + } + }, + { /* Quality B, needs a way to auto apply 3/2 or 4/3 crops (read exif tags ..) to work better with auto distortion, + for the moment just comment-uncomment the desired raw crop */ + "make_model": "Canon PowerShot G1 X Mark II", + "dcraw_matrix": [ 7378,-1255,-1043,-4088,12251,2048,-876,1946,5805 ], // D65 matrix from adobe dcp + // "raw_crop": [ 80, 50, 4400, 3316 ], // full frame 4480x3366 borders 80,50 - much shade in corners, no/wrong auto distortion + // "raw_crop": [ 104, 144, 4360, 3128 ], // Mixed best average frame, width is 4352 from 3/2, height 3120 from 4/3 - auto distortion does not work correctly + // "raw_crop": [ 200, 144, 4168, 3128 ], // Optional official 4/3 frame 4160x3120, 4pix borders, Left Border 204-4, Top Border 148-4 + "raw_crop": [ 104, 252, 4360, 2912 ], // Default official 3/2 frame 4352X2904, 4pix borders, Left Border 108-4, Top border 256-4 + "masked_areas": [ 148, 2, 3340, 78 ], + "ranges": { "white": 16300 } + }, + + { // Quality B, not supported by the current Dcraw 9.22 + "make_model": "Canon PowerShot G7 X", + "dcraw_matrix": [ 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 ], // DNG_V8.7 D65 + // "raw_crop": [ 116, 24, 5504, 3680 ], // Sensor size 5632x3710. Largest usefull frame 120-5616X28-3702 = 5504x3682, 4pix RTborders, Left Border 120-4, Top border 28-4 + "raw_crop": [ 128, 36, 5480, 3656 ], // Default official 3/2 frame 5472X3648, 4pix borders, Left Border 132-4, Top border 40-4 + "masked_areas": [ 40, 4, 3680, 76 ], + "ranges": { "white": 4080 } + }, + + { // Quality A, changes for raw crop which is wrong (larger) in Dcraw + "make_model": "Canon PowerShot S120", + "dcraw_matrix": [ 6961,-1685,-695,-4625,12945,1836,-1114,2152,5518 ], + "raw_crop": [ 120, 30, 4024, 3030 ], + "masked_areas": [ 32, 2, 3028, 80 ], + "ranges": { "white": 4050 } + }, + + { // Quality B + "make_model": "Canon PowerShot SX60 HS", + "dcraw_matrix": [ 13161,-5451,-1344,-1989,10654,1531,-47,1271,4955 ], // DNG_V8.7 D65 + "raw_crop": [ 120, 34, 4616, 3464 ], // full raw 4768x3516, Usable 96,16,4672,3498 - Canon official 4608x3456 left 124 top 38, + "masked_areas": [ 20, 2, 3480, 80 ], + "ranges": { "white": 4050 } // nominal 4080-4093 + }, + + { // Quality A + "make_model": "FUJIFILM S1", + "dcraw_matrix": [ 12297,-4882,-1202,-2106,10691,1623,-88,1312,4790 ] // DNG_v8.5 D65 + }, + + { // Quality B, + "make_model": [ "FUJIFILM X100S", "FUJIFILM X100T" ], + "dcraw_matrix": [ 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 ], // DNG_v8.7 D65 + "ranges": { "white": 16100 } + }, + + { // Quality B + "make_model": "FUJIFILM X-A2", + "dcraw_matrix": [ 10763,-4560,-917,-3346,11311,2322,-475,1135,5843 ], // DNG D65 + "ranges": { "white": 4050 } + }, + { // Quality B + "make_model": [ "FUJIFILM X-T1", "FUJIFILM X-E2" ], + "dcraw_matrix": [ 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 ], // DNG D65 +// "dcraw_matrix": [ 9289,-3279,-632,-3539,11137,2758,-1049,1950,6544 ], // X-RITE D55 + "ranges": { "white": 16100 } + }, + + { // Quality B + "make_model": "FUJIFILM X30", + "dcraw_matrix": [ 12328,-5256,-1144,-4469,12927,1675,-87,1291,4351 ], // DNG_v8.7 D65 + "ranges": { "white": 4040 } + }, + + { // Quality B + "make_model": "FUJIFILM XQ2", + "dcraw_matrix": [ 9252,-2704,-1064,-5893,14265,1717,-1101,2341,4349 ], // DNG_v8.8 D65 + "ranges": { "white": 4040 } + }, + { // Quality A + "make_model": [ "Nikon 1 V3", "Nikon 1 J4" ], // Same format + "dcraw_matrix": [ 5958,-1559,-571,-4021,11453,2939,-634,1548,5087 ], // matrix from DNG_v8.5 d65 + // "dcraw_matrix": [ 5306,-1066,-469,-3865,11189,3076,-399,1341,5120 ], // matrix dXo D50, + "ranges": { "white": 4080 } // Black is auto extracted from exif, lower WL to 4080 from 4095 due to some non linearity detected at raw highlights + }, + + { // Quality C, color data from preliminary measures instead of the Dcraw's matrix + "make_model": "Nikon 1 J5", // + "dcraw_matrix": [ 7651,-2102,-751,-3299,11101,1651,-1011,2242,5770 ], // matrix from ICC converted to Dcraw format XYZ on ImagingResource stillife sample + "ranges": { + "white": [ + { "iso": [ 160, 200 ], "levels": 4000 }, // typical G1/G2 4020-4028, R/B 4088 + { "iso": [ 400, 800, 1600, 3200 ], "levels": 4000 }, // g1/g2 4030-4040, r/b 4088 + { "iso": [ 6400, 12800 ], "levels": 4080 } // 4090 + ] + } + }, + + { // Quality A, + "make_model": "Nikon 1 S2", // + "dcraw_matrix": [ 6612,-1342,-618,-3338,11055,2623,-174,1792,5075 ], // matrix from DNG_v8.5 d65 + "ranges": { "white": 4080 } // BL autodetected from exif + }, + + { // quality B, lacks aperture and ISO scaling, known to exist, but little to gain as the levels are so close to white_max + "make_model": "Nikon D7000", + "dcraw_matrix": [ 7530,-1942,-255,-4318,11390,3362,-926,1694,7649 ], // matrix provided by Tanveer(tsk1979) + "ranges": { + // measured at ISO 100. ISO differences not measured, but known to exist + "white": [ 16370, 15760, 16370 ], // typical R 16383, G 15778, B 16383 + "white_max": 16383 + // aperture scaling not measured, but known to exist, at f/1.8 the G channels hits white_max + } + }, + + { // Quality B, aperture scaling used to scale WL at safer levels + "make_model": "Nikon D5300", + "dcraw_matrix": [ 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 ], // adobe dng_v8.8 d65 + "ranges": { "white": 16300 } // attention.. WL value is for 14bit files, has to be 4070 for 12bit files. WL typical 16383 set to 16300 for safety + }, + + { // Quality B, aperture scaling used to scale WL at safer levels + "make_model": "Nikon D5500", + "dcraw_matrix": [ 8821,-2938,-785,-4178,12142,2287,-824,1651,6860 ], // adobe dng_v9.0 d65 + "ranges": { "white": 16300 } // attention.. WL value is for 14bit files, has to be 4070 for 12bit files. WL typical 16383 set to 16300 for safety + }, + + { // Quality B, color matrix from DNG_v9.0 instead of internal Dcraw_v9.25_r1.475, + "make_model": "Nikon D7200", + "dcraw_matrix": [ 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 ], // adobe dng_v9.0 d65 + "ranges": { "white": 16300 } // attention.. WL values are for 14bit files, has to be WL4070 for 12bit files. WL typical 16383 set to 16300 for safety, + }, + + { // quality B, samples by joachip at RT forums, are measures at long exposures with LongExposureNoiseReduction + // aperture scaling known to exist, but little to gain as the levels are so close to white_max + "make_model": "Nikon D600", + "dcraw_matrix": [ 8178,-2245,-609,-4857,12394,2776,-1207,2086,7298 ], // dcp d65 + // "raw_crop": [ 0, 0, 6034, 4028 ], // dcraw + "ranges": { + "white": [ + { "iso": [ 50, 100 ], "levels": [ 15800, 15800, 15350 ] }, // typical G1/G2/R 15879, B 15395-15670 lowered to 15800, 15350, 3969 B3917 + { "iso": [ 200, 400, 800 ], "levels": [ 16300, 15700, 16300 ] }, // 15878, 16383 + { "iso": 1000, "levels": [ 16300, 16100, 16300 ] }, // 12bit lossless r4095, 3981-10, b4041- 12bit lossy r,g1,g2 3961 - b3917, + { "iso": 1600, "levels": [ 16300, 16100, 16300 ] }, // 16145-165, 16383 + { "iso": [ 3200, 6400, 12800, 25600 ], "levels": [ 16300, 16300, 16300 ] } // 16383 + ], + "white_max": 16383 + } + }, + { // quality B, lacks WL measures at intermediate ISOs (160-250-320 ..) and measures at long exposures with LongExposureNoiseReduction + // aperture scaling known to exist, but little to gain as the levels are so close to white_max + "make_model": "Nikon D610", + "dcraw_matrix": [ 8178,-2245,-609,-4857,12394,2776,-1207,2086,7298 ], // dcp d65 + "raw_crop": [ 0, 0, 6034, 4028 ], // Dcraw has no raw crop for D610 + "ranges": { + "white": [ + { "iso": [ 50, 100 ], "levels": [ 15800, 15700, 15800 ] }, // typical G1/G2 15778, R/B 15879 lowered to 15700, 15800 for possible WL distribution under LENR + { "iso": [ 200, 400, 800 ], "levels": [ 16300, 15700, 16300 ] }, // 15878, 16383 + { "iso": 1600, "levels": [ 16300, 16100, 16300 ] }, // 16145-165, 16383 + { "iso": [ 3200, 6400, 12800, 25600 ], "levels": [ 16300, 16300, 16300 ] } // 16383 + ], + "white_max": 16383 + } + }, + + { // quality B; Data from RusselCottrell at RT forums. sensor is not uniform + "make_model": "Nikon D700", + "dcraw_matrix": [ 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 ], + "ranges": { "white": 15750 } // Non linearities start at 15750 (hi ISOs) 15850 (low ISOs) with long exposures (>2sec) and LENR ON .. nominal 15892 + // white 15750 is correct for 14bit files, 12 bit files need white level at 3900 + }, + + { // Quality B, + "make_model": "Nikon D750", + "dcraw_matrix": [ 9020,-2890,-715,-4535,12436,2348,-934,1919,7086 ], // adobe dcp d65 DNGv8.7 + "ranges": { "white": 16300 } // attention.. WL values are for 14bit files, has to be WL4070 for 12bit files. WL typical 16383 set to 16300 for safety + }, + + { // quality B; Data from RussellCottrell at RT forums. Largest aperture scale factor is 1.013, about 1/50th of a stop + "make_model": "Nikon D800E", + "dcraw_matrix": [ 7866,-2108,-555,-4869,12483,2681,-1176,2069,7501 ], // D800/D800E from dcraw.c + "ranges": { + "white": [ + { "iso": [ 100, 125, 160, 200, 250, 320, 400, 500, 640, 800, 1000, 1250 ], "levels": [ 16300, 15700, 16300 ] }, // 15779-15781 + { "iso": [ 1600 ], "levels": 16000 }, // 16085-16113 + { "iso": [ 2000, 2500, 3200, 4000, 5000, 6400, 12800, 25600 ], "levels": 16300 } // 16383 + ] + } + }, + { // quality B, WL set at 16300 from nominal 16380 for possible non linearities with LENR + "make_model": "Nikon D810", + "dcraw_matrix": [ 9369,-3195,-791,-4488,12430,2301,-893,1796,6872 ], // dcp_v8.6 d65 + "raw_crop": [ 0, 0, 7380, 4928 ], // Official raw crop 7380x4928, + "ranges": { "white": 16300 } // attention WL 16300 is for 14bit raws and has to be 4070 for 12 bit raws. Typical WL at 16383 + }, + { // Quality b, 16Mp and 64Mp raw frames + "make_model": "OLYMPUS E-M5MarkII", + "dcraw_matrix": [ 9422,-3258,-711,-2655,10898,2015,-512,1354,5512 ], // DNG_v8.8 D65 + "raw_crop": [ 0, 0, -6, -6 ], // largest valid, full 64Mp 9280x6938, official crop 0 0 9216 6912 - safe 5755 + "ranges": { + "white": [ + { "iso": [ 100, 200 ], "levels": 3950 }, // normal 4080-4095, HR Dpreview 4047, IR 3956 + { "iso": [ 400, 800, 1600, 3200 ], "levels": 4070 }, // 4070-4095 + { "iso": [ 6400, 12800, 25600 ], "levels": 4040 } // 4000-4095 + ] + } + }, + + { // Quality b, crop correction + "make_model": "OLYMPUS E-M10", + "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 + "ranges": { "white": 4080 } + }, + { // Quality A, white level correction + "make_model": "OLYMPUS E-PM2", + "dcraw_matrix": [ 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 ], + "ranges": { "white": 4040 } // nominal 4056 + }, + + { // Quality B, with long exposure noise reduction White Level gets WL-BL = around 256_12bit levels less + "make_model": "OLYMPUS E-PL7", + "dcraw_matrix": [ 9197,-3190,-659,-2606,10830,2039,-458,1250,5458 ], // DNG_V8.7 D65 + "ranges": { "white": 4080 } // nominal 4093 + }, + + /* since Dcraw_v9.21 Panasonic base BL is read from exif (tags 0x001c BlackLevelRed15 is BL offstet. + Dcraw/RT read the base offset from exif and calculates total BL = BLbase+BLoffset, 0x001d BlackLevelGreen, 0x001e BlackLevelBlue + and we define here the needed offset of around 15. The total BL is base+offset */ + + { // Quality B, CameraPhone, some samples are missing but has the same sensor as FZ1000 .. + "make_model": "Panasonic DMC-CM1", + "dcraw_matrix": [ 8770,-3194,-820,-2871,11281,1803,-513,1552,4434 ], // dcp_v8.7 d65 + "ranges": { + "black": 15, // 15 is BL offstet. Dcraw/RT read the base BL from exif and calculates total BL = BLbase+BLoffset + "white": [ + { "iso": 80, "levels": 3600 }, // exif:3277 distribution peak at 3700 up to +/- 100 + { "iso": [ 100, 125, 200, 400, 800, 1600 ], "levels": 4050 }, // exif 4095 distribution 4050-4095 + { "iso": [ 3200, 6400, 12600, 25600 ], "levels": 4080 } // exif 4095 distribution 4080-4095 + ] + } + }, + + { // 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 + "ranges": { "black": 15, "white": 4050 } // 15 is BL offstet. Dcraw/RT read the base offset from exif and calculates total BL = BLbase+BLoffset + }, + + { // Quality A, samples by helices at Rt forums + "make_model": [ "Panasonic DMC-FZ1000", "Leica V-LUX (Typ 114)" ], + "dcraw_matrix": [ 7830,-2696,-763,-3325,11667,1866,-641,1712,4824 ], // dcp_v8.6 d65 + "ranges": { + "black": 15, // 15 is BL offstet. Dcraw/RT read the base BL from exif and calculates total BL = BLbase+BLoffset + "white": [ + { "iso": 80, "levels": 3600 }, // exif:3277 distribution peak at 3700 up to +/- 100 + { "iso": [ 100, 125, 200, 400, 800, 1600 ], "levels": 4050 }, // exif 4095 distribution 4050-4095 + { "iso": [ 3200, 6400, 12600, 25600 ], "levels": 4080 } // exif 4095 distribution 4080-4095 + ] + } + }, + + { // Quality A + "make_model": [ "Panasonic DMC-LF1", "Leica C (Typ 112)" ], + "dcraw_matrix": [ 9379,-3267,-816,-3227,11560,1881,-926,1928,5340 ], + "ranges": { "black": 15, "white": 4050 } // 15 is BL offstet. Dcraw/RT read the base offset from exif and calculates total BL = BLbase+BLoffset + }, + { // Quality A + "make_model": [ "Panasonic DMC-TZ60", "Panasonic DMC-TZ61", "Panasonic DMC-ZS40", "Panasonic DMC-ZS41" ], + "dcraw_matrix": [ 8607,-2822,-808,-3755,11930,2049,-820,2060,5224 ], // matrix from Adobe dcp v8.4 + "raw_crop": [ 8, 8, -8, -8 ], // crop according to exif 4896 X 3672 plus 4 pixels borders. RT's frame gets smaller than Dcraw but works better with auto distortion + "ranges": { "black": 14, "white": 4050 } // 15 is BL offstet. Dcraw/RT read the base offset from exif and calculates total BL = BLbase+BLoffset + }, + { // 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 + "ranges": { "black": 14, "white": 4050 } // 12+1+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 + "make_model": [ "Panasonic DMC-G10", "Panasonic DMC-G2" ], + "dcraw_matrix": [ 8310,-1811,-960,-4941,12990,2151,-1378,2468,6860 ], // Colin Walker + "ranges": { + "black": 15, // 15 is black offset, Dcraw/RT read the base black from exif and calculates total BL = BLbase+BLoffset + "white": [ + { "iso": [ 100, 200, 400, 800 ], "levels": 3920 }, // exif:3967 distribution peak at 3967 +/- up to 50 + { "iso": [ 1600, 3200, 6400 ], "levels": 4060 } // exif 3967, histogram peak 4095 and distribution down to 4070 + ] + } + }, + { // Quality A, Replicated from rawimage.cc + "make_model": "Panasonic DMC-G1", + "dcraw_matrix": [ 7477,-1615,-651,-5016,12769,2506,-1380,2475,7240 ], // Colin Walker + "ranges": { + "black": 15, // 15 is BL offstet. Dcraw/RT read the base black from exif and calculates total BL = BLbase+BLoffset + "white": [ + { "iso": [ 100, 200, 400, 800 ], "levels": 3920 }, // exif:4095 distribution peak at 3977 +/- up to 50 + { "iso": [ 1600, 3200 ], "levels": 4060 } // exif 4095, histogram peak 4095 and distribution down to 4070 + ] + } + }, + { // Quality A, Replicated from rawimage.cc + "make_model": "Panasonic DMC-G3", + "dcraw_matrix": [ 6051,-1406,-671,-4015,11505,2868,-1654,2667,6219 ], // Colin Walker + "ranges": { + "black": 15, // 15 is BL offstet. Dcraw/RT read the base black from exif and calculates total BL = BLbase+BLoffset + "white": 4060 } // exif:4095 normal distribution 4080-4095, 4070-4095 on long exposure NR + }, + { // Quality A, Replicated from rawimage.cc + "make_model": "Panasonic DMC-G5", + "dcraw_matrix": [ 7122,-2092,-419,-4643,11769,3283,-1363,2413,5944 ], // RT + "ranges": { + "black": 15, // 15 is BL offstet. Dcraw/RT read the base black from exif and calculates total BL = BLbase+BLoffset + "white": 4060 } // exif:4095 normal distribution 4080-4095, 4070-4095 on long exposure NR + }, + { // Quality A, Replicated from rawimage.cc + "make_model": "Panasonic DMC-GF1", + "dcraw_matrix": [ 7863,-2080,-668,-4623,12331,2578,-1020,2066,7266 ], // Colin Walker + "ranges": { + "black": 15, // 15 is BL offstet. Dcraw/RT read the base black from exif and calculates total BL = BLbase+BLoffset + "white": [ + { "iso": [ 100, 200, 400, 800 ], "levels": 3920 }, // exif:4095 distribution peak at 3977 +/- up to 50 + { "iso": [ 1600, 3200 ], "levels": 4060 } // exif 4095, histogram peak 4095 and distribution down to 4070 + ] + } + }, + + { // Quality A, Replicated from rawimage.cc + "make_model": "Panasonic DMC-GF2", + "dcraw_matrix": [ 7694,-1791,-745,-4917,12818,2332,-1221,2322,7197 ], // Colin Walker + "ranges": { + "black": 15, // 15 is BL offstet. Dcraw/RT read the base black from exif and calculates total BL = BLbase+BLoffset + "white": 4050 } // exif:4095 normal distribution 4080-4095, 4050-4095 on long exposure NR + }, + { // Quality A, Replicated from rawimage.cc + "make_model": "Panasonic DMC-GF3", + "dcraw_matrix": [ 8074,-1846,-861,-5026,12999,2239,-1320,2375,7422 ], // Colin Walker + "ranges": { + "black": 15, // 15 is BL offstet. Dcraw/RT read the base black from exif and calculates total BL = BLbase+BLoffset + "white": 4050 } // exif:4095 normal distribution 4080-4095, 4050-4095 on long exposure NR + }, + { // Quality A, Replicated from rawimage.cc + "make_model": "Panasonic DMC-GH1", + "dcraw_matrix": [ 6360,-1557,-375,-4201,11504,3086,-1378,2518,5843 ], // Colin Walker + "ranges": { + "black": 15, // 15 is BL offstet. Dcraw/RT read the base black from exif and calculates total BL = BLbase+BLoffset + "white": [ + { "iso": [ 100, 200, 400, 800 ], "levels": 3930 }, // exif:4095 distribution peak at 3982 +/- up to 50 + { "iso": [ 1600, 3200 ], "levels": 4060 } // exif 4095, histogram peak 4095 and distribution down to 4070 + ] + } + }, + { // Quality A, Replicated from rawimage.cc + "make_model": "Panasonic DMC-GH2", + // "dcraw_matrix": [ 6855,-1765,-456,-4223,11600,2996,-1450,2602,5761 ], // Colin Walker - disabled due to problems with underwater + "dcraw_matrix": [ 7780,-2410,-806,-3913,11724,2484,-1018,2390,5298 ], // Dcraw d65 + "ranges": { + "black": 15, // 15 is BL offstet. Dcraw/RT read the base black from exif and calculates total BL = BLbase+BLoffset + "white": [ + { "iso": [ 100, 200, 400, 800 ], "levels": 3930 }, // exif:4095 distribution peak at 3982 +/- up to 50 + { "iso": [ 1600, 3200, 6400, 12800 ], "levels": 4060 } // exif 4095, histogram peak 4095 and distribution down to 4070 + ] + } + }, + + { // Quality B, variable WL + "make_model": "Panasonic DMC-GH3", + "dcraw_matrix": [ 6559,-1752,-491,-3672,11407,2586,-962,1875,5130 ], // dcp d65 + "ranges": { + "black": 16, // 16 is BL offstet. Dcraw/RT read the base black from exif and calculates total BL = BLbase+BLoffset + "white": [ + { "iso": 125, "levels": 3500 }, // gaussian 3600-4095 + { "iso": [ 160, 200, 250, 320, 400, 500, 640, 800, 1000, 1250, 1600, 2000, 2500, 3200, 4000, 5000, 6400, 12800, 25600 ], "levels": 4080 } // nominal 4095 + ] + } + }, + + { // Quality B, some ISO WLevels are safely guessed + "make_model": "Panasonic DMC-GH4", + "dcraw_matrix": [ 7122,-2108,-512,-3155,11201,2231,-541,1423,5045 ], // dng_v8.5 d65 + "ranges": { + "black": 16, // 16 is BL offstet. Dcraw/RT read the base black from exif and calculates total BL = BLbase+BLoffset + "white": [ + { "iso": 100, "levels": 2700 }, // gaussian center at 2870-2920 range +/- 150, exif 2111 + { "iso": 125, "levels": 3100 }, // guessed + { "iso": [ 160, 200, 250, 320, 400, 500, 640, 800, 1000, 1250, 1600, 2000, 2500, 3200, 4000, 5000, 6400, 12800, 25600 ], "levels": 4080 } // nominal 4095 + ] + } + }, + + { // Quality A, + "make_model": "Panasonic DMC-GM1", + "dcraw_matrix": [ 6770,-1895,-744,-5232,13145,2303,-1664,2691,5703 ], + "ranges": { + "black": 15, // 15 is BL offstet. Dcraw/RT read the base offset from exif and calculates total BL = BLbase+BLoffset + "white": [ + { "iso": 125, "levels": 3100 }, // bell shape 3150-3650 - exif 2616 + { "iso": 160, "levels": 3600 }, // guessed from relative GX7 data + { "iso": [ 200, 250, 320, 400, 500, 640, 800, 1000, 1250, 1600, 2000, 2500, 3200, 4000, 5000, 6400, 12800, 25600 ], "levels": 4080 } // nominal 4095 + ] + } + }, + + { // Quality B, uncertainty about ISO100 WL + "make_model": "Panasonic DMC-GM5", + "dcraw_matrix": [ 8238,-3244,-679,-3921,11814,2384,-836,2022,5852 ], // dng_v8.7 d65 + "ranges": { + "black": 15, // 15 is BL offstet. Dcraw/RT read the base offset from exif and calculates total BL = BLbase+BLoffset + "white": [ + { "iso": 100, "levels": 2800 }, // bell shape 2850-3250 - exif 2111 + { "iso": [ 200, 250, 320, 400, 500, 640, 800, 1000, 1250, 1600, 2000, 2500, 3200, 4000, 5000, 6400, 12800, 25600 ], "levels": 4080 } // nominal 4095 + ] + } + }, + { // Quality A, + "make_model": [ "Panasonic DMC-GX7", "Panasonic DMC-GF7" ], + "dcraw_matrix": [ 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 ], + "ranges": { + "black": 15, // 15 is BL offstet. Dcraw/RT read the base offset from exif and calculates total BL = BLbase+BLoffset + "white": [ + { "iso": 125, "levels": 3100 }, + { "iso": 160, "levels": 3600 }, + { "iso": [ 200, 250, 320, 400,500, 640, 800, 1000, 1250, 1600, 2000, 2500, 3200, 4000, 5000, 6400, 12800, 25600 ], "levels": 4080 } // nominal 4095 + ] + } + }, + + { // Quality B, uncertainty about ISO 100 WL + "make_model": [ "Panasonic DMC-LX100", "Leica D-LUX (Typ 109)" ], + "dcraw_matrix": [ 8844,-3538,-768,-3709,11762,2200,-698,1792,5220 ], // DNG_V8.7 d65 + // "dcraw_matrix": [ 6538,-1614,-549,-5475,13096,2646,-1780,2799,5612 ], // calculated from DxO D50 + "ranges": { + "black": 15, // 15 is BL offstet calculated from exif data. + "white": [ + { "iso": 100, "levels": 2300 }, // gaussian 2400-2700 exif_linearitylimit 2111 + { "iso": [ 160, 200, 250, 320, 400, 500, 640, 800, 1000, 1250, 1600, 2000, 2500, 3200, 4000, 5000, 6400, 12800, 25600 ], "levels": 4080 } // nominal 4095 + ] + } + }, + + { // Quality B, intermediate ISOs info missing + "make_model": [ "RICOH PENTAX K-3", "PENTAX K-3" ], + "dcraw_matrix": [ 7415,-2052,-721,-5186,12788,2682,-1446,2157,6773 ], // adobe dcp d65 +// "dcraw_matrix": [ 8542,-2581,-1144,-3995,12301,1881,863,1514,5755 ], // pentax DNG +// "dcraw_matrix": [ 6464,-1574,-422,-5324,12712,2934,-1129,1724,6900 ], // DxO + "raw_crop": [ 10, 4, 6028, 4024 ], + "ranges": { + "white": [ + { "iso": 100, "levels": 16310 }, // 16317 or 16350 + { "iso": 200, "levels": 16120 }, // 16254 or 16125 + { "iso": 400, "levels": 15860 }, // 16125 or 15868 + { "iso": 800, "levels": 15360 }, // 15868 or 15364-15370 + { "iso": [ 1600, 3200, 6400, 12800, 25600, 51200 ], "levels": 16300 } // 16383 - pentax dng tag is 15868-15350 + ] + } + }, + + { // Quality B, intermediate ISOs info missing, spread due to blackframe subtraction guessed to be around 10levels + "make_model": "PENTAX K10D", + "dcraw_matrix": [ 9566,-2863,-803,-7170,15172,2112,-818,803,9705 ], // adobe DNG d65 + // "raw_crop": [ 0, 0, 3888, 2608 ], + "ranges": { + "white": [ + { "iso": 100, "levels": 4080 }, // R,G1,B = 4095 G2= 4087 + { "iso": 200, "levels": 4080 }, // R,G1,B = 4093-94 G2= 4087or94 + { "iso": 400, "levels": 4080 }, // R,G1 = 4093-94, B=4094 G2= 4087or93or94 + { "iso": 800, "levels": 4070 }, // R,G1 = 4091-4093, B=4091-92 G2= 4078or82or84-86 + { "iso": [ 1600, 3200 ], "levels": 4060 } // 4067or4073-76 + ] + } + }, + + { // Quality B, corrections for raw crop vs Dcraw9.21, matched to Samsung's default + "make_model": "Samsung NX mini", + "dcraw_matrix": [ 5222,-1196,-550,-6540,14649,2009,-1666,2819,5657 ], // dng 8.6 d65 + "raw_crop": [ 128, 36, 5480, 3656 ], // jpeg 5472x3648 - full raw: 5664 x 3710 - Samsung's official crop: 132, 40, 5604, 3688 + "ranges": { "white": 4030 } // double clipping point for each channel at a) 4095 and b) bell distribution with peak at 4038 .. used the conservative one + }, + { // Quality A, Conflict with "Samsung NX30" in Dcraw_v9.21_r1.414, frame corrections and color data + "make_model": "Samsung NX3000", + "dcraw_matrix": [ 8060,-2933,-761,-4504,12890,1762,-630,1489,5227 ], // DNG_v8.7.1 D65 + "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 + "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 + // "dcraw_matrix": [ 9598,-3268,-634,-5678,14795,824,-1255,2675,4523 ], // SAMSUNG DNG CONVERTER + "ranges": { + "white": [ + { "iso": 100, "levels": 16000 }, // typical 16084, LE 16120 and 16383, LENR 16280 + { "iso": [ 200, 400, 800, 1600, 3200, 6400, 12800 ], "levels": 16300 }, // 16383 + { "iso": [ 25600, 51200 ], "levels": 16300 } // 16383 + ] + } + }, + + { // Quality c, corrections for frame size, black and white levels not declared properly + "make_model": "Sigma SD9", + "dcraw_matrix": [ 14996,-3468,-1425,5576,3642,972,1761,3773,3720 ], // experimental calculated from sun0.icc data + "ranges": { "black": 0, "white": 16383 },// black is already subtracted by dcraw, white copied from x3dump data + "raw_crop": [ 20, 8, -18, -12 ] + }, + { // Quality c, corrections for frame size, black level not declared properly + "make_model": "Sigma SD10", + "dcraw_matrix": [ 12555,-1865,-1125,5093,4120,867,1929,3810,3507 ], // experimental calculated from .icc data + "ranges": { "black": 0, "white": 16383 },// black is already subtracted by dcraw, white copied from x3dump data + // "raw_crop": [ 0, 0, -0, -0 ] + "raw_crop": [ 20, 8, -18, -12 ] + }, + { // Quality c, corrections for frame size, black and white levels not declared properly + "make_model": "Sigma SD14", + "dcraw_matrix": [ 16411,-4764,-2383,8110,2603,-645,3135,3878,1984 ], // experimental inverted icc wp12 - build with BL=15 + // "dcraw_matrix": [ 13804,-4156,-1896,6917,1909,-431,2768,2989,1741 ], // experimental inverted icc wp10 - build with BL=15 + "ranges": { "black": 0, "white": 16383 },// peripheral black stripes give BL around 37 + "raw_crop": [ 0, 0, -0, -0 ] + // "raw_crop": [ 18, 12, 2652, 1768 ] + }, + + { // Quality c, correction for frame width + "make_model": "Sigma SD1", + "dcraw_matrix": [ 5270,42,-814,3737,5506,124,1112,9714,4510 ], // experimental from icm 1.04477,-0.74838,1.01617, -0.54028,2.52690,-3.83257, 0.54869,-0.69556,3.73746 + "ranges": { "black": 16, "white": 4070 },// BL is 16 or 31, should be measured at the horizontal black stripe at the top + "raw_crop": [ 12, 52, -110, -8 ] + }, + { // Quality C, correction for frame width, color matrix investigated .. + "make_model": "Sigma SD1 Merrill", + "dcraw_matrix": [ 7211,-1577,-769,4996,3428,440,2717,7117,4699 ], // experimental inverted icc cloudy8140 d65 + // "dcraw_matrix": [ 5666,139,-892,3780,5428,270,1366,9757,4526 ], // experimental inverted icc sunny8161 + // "dcraw_matrix": [ 10288,-2449,-1718,8976,1868,-1608,7011,5039,-249 ], // experimental inverted icc tungsten8130 wp11 + // "dcraw_matrix": [ 5864,679,-1491,2963,7635,-919,-640,13738,2790 ], // experimental inverted icc sunny8160 + // "dcraw_matrix": [ 14032,-2231,-1016,-5263,14816,170,-112,183,9113 ], // hardcoded + "ranges": { "black": 16, "white": 4070 }, // BL is 16 or 31, should be measured at the horizontal black stripe at the top + "raw_crop": [ 12, 52, -110, -8 ] // for small size all numbers/2 + }, + { // Quality C, correction for frame width, color matrix guessed .. + "make_model": [ "Sigma DP1 Merrill", "Sigma DP2 Merrill", "Sigma DP3 Merrill" ], + "dcraw_matrix": [ 5666,139,-892,3780,5428,270,1366,9757,4526 ], // copy fron SD1 Merrill icc cloudy8140 d65 + "ranges": { "black": 16, "white": 4070 }, // BL is 16 or 31, should be measured at the horizontal black stripe at the bottom + "raw_crop": [ 12, 0, -110, -62 ] // for small size all numbers/2 + }, + + + { // Quality A, correction for color matrix from Colin Walker's d50 to dng d65 + "make_model": "Sony NEX-C3", + // "dcraw_matrix": [ 5130,-1055,-269,-4473,11797,3050,-701,1310,7121 ], // Colin walker's d50 kept for possible consistency issues + "dcraw_matrix": [ 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 ], + "ranges": { "black": 512, "white": 16300 } + }, + + { // Quality A, correction for frame width + "make_model": "Sony NEX-5N", + "dcraw_matrix": [ 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 ], + "raw_crop": [ 0, 0, 4920, 3276 ], + "ranges": { "black": 512, "white": 16300 } + }, + { // Quality A, + "make_model": "Sony ILCA-77M2", + "dcraw_matrix": [ 5991,-1732,-443,-4100,11989,2381,-704,1467,5992 ], // adobe dcp d65 + "raw_crop": [ 0, 0, 6024, 4024 ], + "ranges": { "black": 512, "white": 16300 } + }, + + { // Quality A, correction for frame width + "make_model": [ "Sony ILCE-3000", "Sony ILCE-3500", "Sony ILCE-5000", "Sony ILCE-QX1" ], + "dcraw_matrix": [ 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 ], // adobe dcp d65 + "ranges": { "black": 512, "white": 16300 }, + "raw_crop": [ 0, 0, 5476, 3656 ] + }, + { // Quality A, + "make_model": "Sony ILCE-5100", + "dcraw_matrix": [ 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 ], // adobe dcp d65 + "raw_crop": [ 0, 0, 6024, 4024 ], + "ranges": { "black": 512, "white": 16300 } + }, + { // Quality A + "make_model": "Sony ILCE-6000", + "dcraw_matrix": [ 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 ], // adobe dcp d65 + "raw_crop": [ 0, 0, 6024, 4024 ], + "ranges": { "black": 512, "white": 16300 } + }, + { // Quality A + "make_model": "Sony ILCE-7M2", + "dcraw_matrix": [ 5271,-712,-347,-6153,13653,2763,-1601,2366,7242 ], // DNGv8.7.1 + "ranges": { "black": 512, "white": 16300 } + }, + { // Quality A, correction for frame width + "make_model": "Sony ILCE-7R", + "dcraw_matrix": [ 4913,-541,-202,-6130,13513,2906,-1564,2151,7183 ], + "raw_crop": [ 0, 0, 7372, 4920 ], + "ranges": { "black": 512, "white": 16300 } + }, + { // Quality B, correction for frame width + "make_model": "Sony ILCE-7S", + "dcraw_matrix": [ 5838,-1430,-246,-3497,11477,2297,-748,1885,5778 ], // DNG D65 + "raw_crop": [ 0, 0, 4254, 2848 ], + "ranges": { "black": 512, "white": 16300 } + }, + { // Quality A, + "make_model": "Sony DSC-RX100M3", + "dcraw_matrix": [ 6596,-2079,-562,-4782,13016,1933,-970,1581,5181 ], // DNG D65 + "ranges": { "black": 800, "white": 16300 } + }, + + /* Phase One: color matrices borrowed from Adobe DNG Converter, black/white levels tested on actual raw files. + Note: the dcraw decoder makes black level subtraction and various corrections to the raw values based on + metadata embedded in the IIQ format, so what we see here is the result after that, ie black level is 0, + and white level is typically at or close to 65535. However sensors vary a bit and can be noisy around clip + so we cut away 0.05 stop from top down to 63300 to be a bit conservative. */ + { // quality A + "make_model": [ "Phase One P40+", "Phase One IQ140", "Leaf Credo 40", "Phase One P65+", "Phase One IQ160", "Leaf Credo 60", "Phase One IQ260" ], + "dcraw_matrix": [ 8035,435,-962,-6001,13872,2320,-1159,3065,5434 ], + "ranges": { "black": 0, "white": 63300 } + }, + { // quality A + "make_model": [ "Phase One IQ180", "Leaf Credo 80", "Phase One IQ280" ], + "dcraw_matrix": [ 6294,686,-712,-5435,13417,2211,-1006,2435,5042 ], + "ranges": { "black": 0, "white": 63300 } + }, + { // quality A + "make_model": [ "Phase One P20", "Phase One P20+", "Phase One P25", "Phase One P25+" ], + "dcraw_matrix": [ 2905,732,-237,-8135,16626,1476,-3038,4253,7517 ], + "ranges": { "black": 0, "white": 63300 } + }, + { // quality A + "make_model": [ "Phase One P21", "Phase One P21+" ], + "dcraw_matrix": [ 6516,-2050,-507,-8217,16703,1479,-3492,4741,8489 ], + "ranges": { "black": 0, "white": 63300 } + }, + { // quality A + "make_model": [ "Phase One P30", "Phase One P30+"], + "dcraw_matrix": [ 4516,-244,-36,-7020,14976,2174,-3206,4670,7087 ], + "ranges": { "black": 0, "white": 63300 } + }, + { // quality A + "make_model": [ "Phase One P45", "Phase One P45+" ], + "dcraw_matrix": [ 5053,-24,-117,-5685,14077,1703,-2619,4491,5850 ], + "ranges": { "black": 0, "white": 63300 } + }, + { // quality X, matrix taken from H5D-50c which has the same sensor, probably with the same CFA. Color looks good to the eye with files tested. + "make_model": [ "Phase One IQ250", "Leaf Credo 50" ], + "dcraw_matrix": [ 4932, -835, 141, -4878, 11868, 3437, -1138, 1961, 7067 ], + "ranges": { "black": 0, "white": 64400 } // CMOS sensor, we dare to set white level a bit higher than for the more varying Phase One CCDs + }, + + { // Quality A for tested CFV, the other models have the same sensor (16 megapixel square sensor) + "make_model": [ "Hasselblad V96C", "Hasselblad CFV", "Hasselblad CFV-II" ], + "dcraw_matrix": [ 8519, -3260, -280, -5081, 13459, 1738, -1449, 2960, 7809 ] // borrowed from Adobe's DNG converter + }, + { // Quality A for tested CF-22, the other models have the same sensor + "make_model": [ "Hasselblad CF-22", "Hasselblad CF-22MS", "Hasselblad CFH-22", "Hasselblad H3D-22", "Hasselblad H3DII-22" ], + "dcraw_matrix": [ 8519, -3260, -280, -5081, 13459, 1738, -1449, 2960, 7809 ] // borrowed from Adobe's DNG converter + }, + { // Quality A for tested H3D-31, the other models have the same sensor + "make_model": [ "Hasselblad H3D-31", "Hasselblad H3DII-31", "Hasselblad H4D-31" ], + "dcraw_matrix": [ 5458, -1448, 145, -4479, 12338, 2401, -1659, 3086, 6710 ] // borrowed from Adobe's DNG converter + }, + { // Quality A for tested CFV-39, the other models have the same sensor. Small filter differences may exist so some might do better with a slightly different profile + "make_model": [ "Hasselblad CF-39", "Hasselblad CF-39MS", "Hasselblad CFH-39", "Hasselblad CFV-39", "Hasselblad H3D-39", "Hasselblad H3DII-39", "Hasselblad H3DII-39MS" ], + "dcraw_matrix": [ 3857, 452, -46, -6008, 14477, 1596, -2627, 4481, 5718 ] // borrowed from Adobe's DNG converter + }, + { // Quality A for tested CFV-50, the other models have the same sensor + "make_model": [ "Hasselblad CFV-50", "Hasselblad H3DII-50", "Hasselblad H3DII-50MS", "Hasselblad H4D-50", "Hasselblad H4D-50MS", "Hasselblad H4D-200MS", "Hasselblad H5D-50", "Hasselblad H5D-50MS", "Hasselblad H5D-200MS" ], + "dcraw_matrix": [ 5656, -659, -346, -3923, 12306, 1791, -1602, 3509, 5442 ] // borrowed from Adobe's DNG converter + }, + { // Quality A + "make_model": [ "Hasselblad H4D-40", "Hasselblad H5D-40" ], + "dcraw_matrix": [ 6159, -1402, -177, -5439, 12762, 3007, -955, 2200, 7104 ] // borrowed from Adobe's DNG converter + }, + { // Quality A for tested H4D-60, the other models have the same sensor + "make_model": [ "Hasselblad H4D-60", "Hasselblad H5D-60" ], + "dcraw_matrix": [ 9662, -684, -279, -4903, 12293, 2950, -344, 1669, 6024 ] // borrowed from Adobe's DNG converter + }, + { // Quality A + "make_model": [ "Hasselblad H5D-50c", "Hasselblad CFV-50c" ], + "dcraw_matrix": [ 4932, -835, 141, -4878, 11868, 3437, -1138, 1961, 7067 ] + }, + + // dummy test entry to test the parser and show the format with all entries active + { + "make_model": "DummyMake DummyModel", + "dcraw_matrix": [ 7530,-1942,-255,-4318,11390,3362,-926,1694,7649 ], + "raw_crop": [ 10, 20, 4000, 3000 ], + "masked_areas": [ 51, 2, 3804, 156, 51, 5794, 3804, 5792 ], + "ranges": { + "aperture_scaling": [ + { "aperture": 1.2, "scale_factor": 1.1 }, + { "aperture": 1.4, "scale_factor": 1.08 } + ], + "black": [ + { "iso": 100 , "levels": [ 10, 20, 10, 20 ] }, + { "iso": [100, 200] , "levels": [ 30, 40, 30 ] }, + { "iso": 3200, "levels": [ 50, 60, 50, 60 ] } + ], + "white": [ + { "iso": 100 , "levels": [ 10000, 11000, 10000, 11000 ] }, + { "iso": 3200, "levels": [ 11000, 11000, 10000, 11000 ] } + ], + "white_max": 16383 + } + } +]} diff --git a/rtengine/cfa_linedn_RT.cc b/rtengine/cfa_linedn_RT.cc new file mode 100644 index 000000000..3bb8aaeae --- /dev/null +++ b/rtengine/cfa_linedn_RT.cc @@ -0,0 +1,427 @@ +//////////////////////////////////////////////////////////////// +// +// CFA line denoise by DCT filtering +// +// copyright (c) 2008-2010 Emil Martinec +// parallelized 2013 by Ingo Weyrich +// +// code dated: June 7, 2010 +// +// cfa_linedn_RT.cc is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +//////////////////////////////////////////////////////////////// + +#include + +#include "rtengine.h" +#include "rawimagesource.h" +#include "rt_math.h" + +#define TS 224 // Tile size of 224 instead of 512 speeds up processing + +#define CLASS + +// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +using namespace std; +using namespace rtengine; + +// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void RawImageSource::CLASS cfa_linedn(float noise) +{ + // local variables + int height=H, width=W; + + const float clip_pt = 0.8*initialGain* 65535.0; + + float eps=1e-5; //tolerance to avoid dividing by zero + + const float gauss[5] = {0.20416368871516755, 0.18017382291138087, 0.1238315368057753, 0.0662822452863612, 0.02763055063889883}; + const float rolloff[8] = {0, 0.135335, 0.249352, 0.411112, 0.606531, 0.800737, 0.945959, 1}; //gaussian with sigma=3 + const float window[8] = {0, .25, .75, 1, 1, .75, .25, 0}; //sine squared + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + if (plistener) { + plistener->setProgressStr ("Line Denoise..."); + plistener->setProgress (0.0); + } + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + float noisevar=SQR(3*noise*65535); // _noise_ (as a fraction of saturation) is input to the algorithm + float noisevarm4 = 4.0f * noisevar; + volatile double progress = 0.0; + float* RawDataTmp = (float*)malloc( width*height*sizeof(float)); +#pragma omp parallel + { + + // allocate memory and assure the arrays don't have same 64 byte boundary to avoid L1 conflict misses + char *buffer = (char*)malloc(4 * TS * TS * sizeof(float)+ 3*64); + float *cfain = (float*)(buffer); + float *cfablur =(float*)(buffer+(TS*TS*sizeof(float))+ 1 * 64); + float *cfadiff =(float*)(buffer+(2*TS*TS*sizeof(float))+ 2 * 64); + float *cfadn =(float*)(buffer+(3*TS*TS*sizeof(float))+ 3 * 64); + + + float linehvar[4], linevvar[4], noisefactor[4][8][2], coeffsq; + float dctblock[4][8][8]; + +#pragma omp for + for(int i=0;i(linehvar[0]+linehvar[1])) {//horizontal lines + for (int i=1; i<8; i++) { + dctblock[0][0][i] *= 0.5f*(noisefactor[0][i][1]+noisefactor[1][i][1]);//or should we use MIN??? + dctblock[1][0][i] *= 0.5f*(noisefactor[0][i][1]+noisefactor[1][i][1]);//or should we use MIN??? + } + } + if (noisevarm4>(linehvar[2]+linehvar[3])) {//horizontal lines + for (int i=1; i<8; i++) { + dctblock[2][0][i] *= 0.5f*(noisefactor[2][i][1]+noisefactor[3][i][1]);//or should we use MIN??? + dctblock[3][0][i] *= 0.5f*(noisefactor[2][i][1]+noisefactor[3][i][1]);//or should we use MIN??? + } + } + + //vertical lines + if (noisevarm4>(linevvar[0]+linevvar[2])) {//vertical lines + for (int i=1; i<8; i++) { + dctblock[0][i][0] *= 0.5f*(noisefactor[0][i][0]+noisefactor[2][i][0]);//or should we use MIN??? + dctblock[2][i][0] *= 0.5f*(noisefactor[0][i][0]+noisefactor[2][i][0]);//or should we use MIN??? + } + } + if (noisevarm4>(linevvar[1]+linevvar[3])) {//vertical lines + for (int i=1; i<8; i++) { + dctblock[1][i][0] *= 0.5f*(noisefactor[1][i][0]+noisefactor[3][i][0]);//or should we use MIN??? + dctblock[3][i][0] *= 0.5f*(noisefactor[1][i][0]+noisefactor[3][i][0]);//or should we use MIN??? + } + } + + for (int ey=0; ey<2; ey++) // (ex,ey) specify RGGB subarray + for (int ex=0; ex<2; ex++) { + ddct8x8s(1, dctblock[2*ey+ex]); //inverse DCT + //multiply by window fn and add to output (cfadn) + for (int i=0; i<8; i++) + for (int j=0; j<8; j++) { + cfadn[(rr+2*i+ey)*TS+cc+2*j+ex] += window[i]*window[j]*dctblock[2*ey+ex][i][j]; + } + } + } + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // copy smoothed results to temporary buffer + for (int rr=16; rr < numrows-16; rr++) { + int row = rr + top; + for (int col=16+left, indx=rr*TS+16; indx < rr*TS+numcols-16; indx++, col++) { + if (rawData[row][col]1.0) + { + progress=1.0; + } + plistener->setProgress(progress); + } + + } + // clean up + free(buffer); + +// copy temporary buffer back to image matrix +#pragma omp for + for(int i=0;i Normalized 8x8 IDCT + C[k1][k2] = (1/4) * sum_j1=0^7 sum_j2=0^7 + a[j1][j2] * s[j1] * s[j2] * + cos(pi*j1*(k1+1/2)/8) * + cos(pi*j2*(k2+1/2)/8), 0<=k1<8, 0<=k2<8 + (s[0] = 1/sqrt(2), s[j] = 1, j > 0) + Normalized 8x8 DCT + C[k1][k2] = (1/4) * s[k1] * s[k2] * sum_j1=0^7 sum_j2=0^7 + a[j1][j2] * + cos(pi*(j1+1/2)*k1/8) * + cos(pi*(j2+1/2)*k2/8), 0<=k1<8, 0<=k2<8 + (s[0] = 1/sqrt(2), s[j] = 1, j > 0) + [usage] + + ddct8x8s(1, a); + + ddct8x8s(-1, a); + [parameters] + a[0...7][0...7] :input/output data (double **) + output data + a[k1][k2] = C[k1][k2], 0<=k1<8, 0<=k2<8 + */ + + +/* Cn_kR = sqrt(2.0/n) * cos(pi/2*k/n) */ +/* Cn_kI = sqrt(2.0/n) * sin(pi/2*k/n) */ +/* Wn_kR = cos(pi/2*k/n) */ +/* Wn_kI = sin(pi/2*k/n) */ +#define C8_1R 0.49039264020161522456 +#define C8_1I 0.09754516100806413392 +#define C8_2R 0.46193976625564337806 +#define C8_2I 0.19134171618254488586 +#define C8_3R 0.41573480615127261854 +#define C8_3I 0.27778511650980111237 +#define C8_4R 0.35355339059327376220 +#define W8_4R 0.70710678118654752440 + + +void RawImageSource::ddct8x8s(int isgn, float a[8][8]) +{ + int j; + float x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i; + float xr, xi; + + if (isgn < 0) { + for (j = 0; j <= 7; j++) { + x0r = a[0][j] + a[7][j]; + x1r = a[0][j] - a[7][j]; + x0i = a[2][j] + a[5][j]; + x1i = a[2][j] - a[5][j]; + x2r = a[4][j] + a[3][j]; + x3r = a[4][j] - a[3][j]; + x2i = a[6][j] + a[1][j]; + x3i = a[6][j] - a[1][j]; + xr = x0r + x2r; + xi = x0i + x2i; + a[0][j] = C8_4R * (xr + xi); + a[4][j] = C8_4R * (xr - xi); + xr = x0r - x2r; + xi = x0i - x2i; + a[2][j] = C8_2R * xr - C8_2I * xi; + a[6][j] = C8_2R * xi + C8_2I * xr; + xr = W8_4R * (x1i - x3i); + x1i = W8_4R * (x1i + x3i); + x3i = x1i - x3r; + x1i += x3r; + x3r = x1r - xr; + x1r += xr; + a[1][j] = C8_1R * x1r - C8_1I * x1i; + a[7][j] = C8_1R * x1i + C8_1I * x1r; + a[3][j] = C8_3R * x3r - C8_3I * x3i; + a[5][j] = C8_3R * x3i + C8_3I * x3r; + } + for (j = 0; j <= 7; j++) { + x0r = a[j][0] + a[j][7]; + x1r = a[j][0] - a[j][7]; + x0i = a[j][2] + a[j][5]; + x1i = a[j][2] - a[j][5]; + x2r = a[j][4] + a[j][3]; + x3r = a[j][4] - a[j][3]; + x2i = a[j][6] + a[j][1]; + x3i = a[j][6] - a[j][1]; + xr = x0r + x2r; + xi = x0i + x2i; + a[j][0] = C8_4R * (xr + xi); + a[j][4] = C8_4R * (xr - xi); + xr = x0r - x2r; + xi = x0i - x2i; + a[j][2] = C8_2R * xr - C8_2I * xi; + a[j][6] = C8_2R * xi + C8_2I * xr; + xr = W8_4R * (x1i - x3i); + x1i = W8_4R * (x1i + x3i); + x3i = x1i - x3r; + x1i += x3r; + x3r = x1r - xr; + x1r += xr; + a[j][1] = C8_1R * x1r - C8_1I * x1i; + a[j][7] = C8_1R * x1i + C8_1I * x1r; + a[j][3] = C8_3R * x3r - C8_3I * x3i; + a[j][5] = C8_3R * x3i + C8_3I * x3r; + } + } else { + for (j = 0; j <= 7; j++) { + x1r = C8_1R * a[1][j] + C8_1I * a[7][j]; + x1i = C8_1R * a[7][j] - C8_1I * a[1][j]; + x3r = C8_3R * a[3][j] + C8_3I * a[5][j]; + x3i = C8_3R * a[5][j] - C8_3I * a[3][j]; + xr = x1r - x3r; + xi = x1i + x3i; + x1r += x3r; + x3i -= x1i; + x1i = W8_4R * (xr + xi); + x3r = W8_4R * (xr - xi); + xr = C8_2R * a[2][j] + C8_2I * a[6][j]; + xi = C8_2R * a[6][j] - C8_2I * a[2][j]; + x0r = C8_4R * (a[0][j] + a[4][j]); + x0i = C8_4R * (a[0][j] - a[4][j]); + x2r = x0r - xr; + x2i = x0i - xi; + x0r += xr; + x0i += xi; + a[0][j] = x0r + x1r; + a[7][j] = x0r - x1r; + a[2][j] = x0i + x1i; + a[5][j] = x0i - x1i; + a[4][j] = x2r - x3i; + a[3][j] = x2r + x3i; + a[6][j] = x2i - x3r; + a[1][j] = x2i + x3r; + } + for (j = 0; j <= 7; j++) { + x1r = C8_1R * a[j][1] + C8_1I * a[j][7]; + x1i = C8_1R * a[j][7] - C8_1I * a[j][1]; + x3r = C8_3R * a[j][3] + C8_3I * a[j][5]; + x3i = C8_3R * a[j][5] - C8_3I * a[j][3]; + xr = x1r - x3r; + xi = x1i + x3i; + x1r += x3r; + x3i -= x1i; + x1i = W8_4R * (xr + xi); + x3r = W8_4R * (xr - xi); + xr = C8_2R * a[j][2] + C8_2I * a[j][6]; + xi = C8_2R * a[j][6] - C8_2I * a[j][2]; + x0r = C8_4R * (a[j][0] + a[j][4]); + x0i = C8_4R * (a[j][0] - a[j][4]); + x2r = x0r - xr; + x2i = x0i - xi; + x0r += xr; + x0i += xi; + a[j][0] = x0r + x1r; + a[j][7] = x0r - x1r; + a[j][2] = x0i + x1i; + a[j][5] = x0i - x1i; + a[j][4] = x2r - x3i; + a[j][3] = x2r + x3i; + a[j][6] = x2i - x3r; + a[j][1] = x2i + x3r; + } + } +} + diff --git a/rtengine/ciecam02.cc b/rtengine/ciecam02.cc new file mode 100644 index 000000000..c01faa670 --- /dev/null +++ b/rtengine/ciecam02.cc @@ -0,0 +1,1069 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "ciecam02.h" +#include "rtengine.h" +#include "curves.h" +#include +#include "sleef.c" + +#ifdef _DEBUG +#include "settings.h" +#include +#endif + +#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 +{ + +#ifdef _DEBUG +extern const Settings* settings; +#endif + +void Ciecam02::curvecolor(double satind, double satval, double &sres, double parsat) +{ + if (satind >=0.0) { + sres = (1.-(satind)/100.)*satval+(satind)/100.*(1.-SQR(SQR(1.-min(satval,1.0)))); + if (sres>parsat) { sres=parsat; } + if (sres<0.) { sres=0.; } + } else { + if (satind < -0.1) { + sres = satval*(1.+(satind)/100.); + } + } +} + +void Ciecam02::curvecolorfloat(float satind, float satval, float &sres, float parsat) +{ + if (satind > 0.f) { + if (satval >= 1.f) { // The calculation below goes wrong direction when satval > 1 + sres = satval; + } else { + sres = (1.f-(satind)/100.f)*satval+(satind)/100.f*(1.f-SQR(SQR(1.f-min(satval,1.0f)))); + } + if (sres>parsat) { + sres = max(parsat,satval); + } + } else if (satind < 0.f) { + sres = satval*(1.f+(satind)/100.f); + } else { // satind == 0 means we don't want to change the value at all + sres = satval; + } +} + +void Ciecam02::curveJ (double br, double contr, int db, LUTf & outCurve, LUTu & histogram ) +{ + LUTf dcurve(65536,0); + int skip=1; + + // check if brightness curve is needed + if (br>0.00001 || br<-0.00001) { + + std::vector brightcurvePoints; + brightcurvePoints.resize(9); + brightcurvePoints.at(0) = double(DCT_NURBS); + + brightcurvePoints.at(1) = 0.; // black point. Value in [0 ; 1] range + brightcurvePoints.at(2) = 0.; // black point. Value in [0 ; 1] range + + if (br>0) { + brightcurvePoints.at(3) = 0.1; // toe point + brightcurvePoints.at(4) = 0.1+br/150.0; //value at toe point + + brightcurvePoints.at(5) = 0.7; // shoulder point + brightcurvePoints.at(6) = min(1.0,0.7+br/300.0); //value at shoulder point + } else { + brightcurvePoints.at(3) = 0.1-br/150.0; // toe point + brightcurvePoints.at(4) = 0.1; // value at toe point + + brightcurvePoints.at(5) = min(1.0,0.7-br/300.0); // shoulder point + brightcurvePoints.at(6) = 0.7; // value at shoulder point + } + brightcurvePoints.at(7) = 1.; // white point + brightcurvePoints.at(8) = 1.; // value at white point + + DiagonalCurve* brightcurve = new DiagonalCurve (brightcurvePoints, CURVES_MIN_POLY_POINTS/skip); + + // Applying brightness curve + for (int i=0; i<32768; i++) { + + // change to [0,1] range + float val = (float)i / 32767.0; + + // apply brightness curve + val = brightcurve->getVal (val); + + // store result in a temporary array + dcurve[i] = CLIPD(val); + } + delete brightcurve; + } else { + // for (int i=0; i<32768; i++) { // L values range up to 32767, higher values are for highlight overflow + for (int i=0; i<(32768*db); i++) { // L values range up to 32767, higher values are for highlight overflow + + // set the identity curve in the temporary array + dcurve[i] = (float)i / (db*32768.0f); + } + } + + + if (contr>0.00001 || contr<-0.00001) { + + // compute mean luminance of the image with the curve applied + int sum = 0; + float avg = 0; + //float sqavg = 0; + for (int i=0; i<32768; i++) { + avg += dcurve[i] * histogram[i];//approximation for average : usage of L (lab) instead of J + sum += histogram[i]; + } + avg /= sum; + std::vector contrastcurvePoints; + contrastcurvePoints.resize(9); + contrastcurvePoints.at(0) = double(DCT_NURBS); + + contrastcurvePoints.at(1) = 0.; // black point. Value in [0 ; 1] range + contrastcurvePoints.at(2) = 0.; // black point. Value in [0 ; 1] range + + contrastcurvePoints.at(3) = avg-avg*(0.6-contr/250.0); // toe point + contrastcurvePoints.at(4) = avg-avg*(0.6+contr/250.0); // value at toe point + + contrastcurvePoints.at(5) = avg+(1-avg)*(0.6-contr/250.0); // shoulder point + contrastcurvePoints.at(6) = avg+(1-avg)*(0.6+contr/250.0); // value at shoulder point + + contrastcurvePoints.at(7) = 1.; // white point + contrastcurvePoints.at(8) = 1.; // value at white point + + DiagonalCurve* contrastcurve = new DiagonalCurve (contrastcurvePoints, CURVES_MIN_POLY_POINTS/skip); + + // apply contrast enhancement + for (int i=0; i<(32768*db); i++) { + dcurve[i] = contrastcurve->getVal (dcurve[i]); + } + + delete contrastcurve; + } + + // for (int i=0; i<32768; i++) outCurve[i] = 32768.0*dcurve[i]; + for (int i=0; i<(db*32768); i++) { outCurve[i] = db*32768.0*dcurve[i]; } +} + +void Ciecam02::curveJfloat (float br, float contr, int db, LUTf & outCurve, LUTu & histogram ) +{ + LUTf dcurve(65536,0); + int skip=1; + + // check if brightness curve is needed + if (br>0.00001f || br<-0.00001f) { + + std::vector brightcurvePoints; + brightcurvePoints.resize(9); + brightcurvePoints.at(0) = double(DCT_NURBS); + + brightcurvePoints.at(1) = 0.f; // black point. Value in [0 ; 1] range + brightcurvePoints.at(2) = 0.f; // black point. Value in [0 ; 1] range + + if (br>0) { + brightcurvePoints.at(3) = 0.1f; // toe point + brightcurvePoints.at(4) = 0.1f+br/150.0f; //value at toe point + + brightcurvePoints.at(5) = 0.7f; // shoulder point + brightcurvePoints.at(6) = min(1.0f,0.7f+br/300.0f); //value at shoulder point + } else { + brightcurvePoints.at(3) = 0.1f-br/150.0f; // toe point + brightcurvePoints.at(4) = 0.1f; // value at toe point + + brightcurvePoints.at(5) = min(1.0f,0.7f-br/300.0f); // shoulder point + brightcurvePoints.at(6) = 0.7f; // value at shoulder point + } + brightcurvePoints.at(7) = 1.f; // white point + brightcurvePoints.at(8) = 1.f; // value at white point + + DiagonalCurve* brightcurve = new DiagonalCurve (brightcurvePoints, CURVES_MIN_POLY_POINTS/skip); + + // Applying brightness curve + for (int i=0; i<32768; i++) { + + // change to [0,1] range + float val = (float)i / 32767.0f; + + // apply brightness curve + val = brightcurve->getVal (val); + + // store result in a temporary array + dcurve[i] = CLIPD(val); + } + delete brightcurve; + } else { + // for (int i=0; i<32768; i++) { // L values range up to 32767, higher values are for highlight overflow + for (int i=0; i<(32768*db); i++) { // L values range up to 32767, higher values are for highlight overflow + + // set the identity curve in the temporary array + dcurve[i] = (float)i / (db*32768.0f); + } + } + + + if (contr>0.00001f || contr<-0.00001f) { + + // compute mean luminance of the image with the curve applied + int sum = 0; + float avg = 0; + //float sqavg = 0; + for (int i=0; i<32768; i++) { + avg += dcurve[i] * histogram[i];//approximation for average : usage of L (lab) instead of J + sum += histogram[i]; + } + avg /= sum; + //printf("avg=%f\n",avg); + std::vector contrastcurvePoints; + contrastcurvePoints.resize(9); + contrastcurvePoints.at(0) = double(DCT_NURBS); + + contrastcurvePoints.at(1) = 0.f; // black point. Value in [0 ; 1] range + contrastcurvePoints.at(2) = 0.f; // black point. Value in [0 ; 1] range + + contrastcurvePoints.at(3) = avg-avg*(0.6f-contr/250.0f); // toe point + contrastcurvePoints.at(4) = avg-avg*(0.6f+contr/250.0f); // value at toe point + + contrastcurvePoints.at(5) = avg+(1-avg)*(0.6f-contr/250.0f); // shoulder point + contrastcurvePoints.at(6) = avg+(1-avg)*(0.6f+contr/250.0f); // value at shoulder point + + contrastcurvePoints.at(7) = 1.f; // white point + contrastcurvePoints.at(8) = 1.f; // value at white point + + DiagonalCurve* contrastcurve = new DiagonalCurve (contrastcurvePoints, CURVES_MIN_POLY_POINTS/skip); + + // apply contrast enhancement + for (int i=0; i<(32768*db); i++) { + dcurve[i] = contrastcurve->getVal (dcurve[i]); + } + + delete contrastcurve; + } + + // for (int i=0; i<32768; i++) outCurve[i] = 32768.0*dcurve[i]; + for (int i=0; i<(db*32768); i++) { outCurve[i] = db*32768.0f*dcurve[i]; } +} + +/** + * Copyright (c) 2003 Billy Biggs + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +double Ciecam02::d_factor( double f, double la ) +{ + return f * (1.0 - ((1.0 / 3.6) * exp((-la - 42.0) / 92.0))); +} + +float Ciecam02::d_factorfloat( float f, float la ) +{ + return f * (1.0f - ((1.0f / 3.6f) * xexpf((-la - 42.0f) / 92.0f))); +} + +double Ciecam02::calculate_fl_from_la_ciecam02( double la ) +{ + double la5 = la * 5.0; + double k = 1.0 / (la5 + 1.0); + + /* Calculate k^4. */ + k = k * k; + k = k * k; + + return (0.2 * k * la5) + (0.1 * (1.0 - k) * (1.0 - k) * pow(la5, 1.0 / 3.0)); +} + +float Ciecam02::calculate_fl_from_la_ciecam02float( float la ) +{ + float la5 = la * 5.0f; + float k = 1.0f / (la5 + 1.0f); + + /* Calculate k^4. */ + k = k * k; + k = k * k; + + return (0.2f * k * la5) + (0.1f * (1.0f - k) * (1.0f - k) * pow_F(la5, 1.0f / 3.0f)); +} + +double Ciecam02::achromatic_response_to_white( double x, double y, double z, double d, double fl, double nbb, int gamu ) +{ + double r, g, b; + double rc, gc, bc; + double rp, gp, bp; + double rpa, gpa, bpa; + gamu=1; + xyz_to_cat02( r, g, b, x, y, z, gamu ); + + rc = r * (((y * d) / r) + (1.0 - d)); + gc = g * (((y * d) / g) + (1.0 - d)); + bc = b * (((y * d) / b) + (1.0 - d)); + + cat02_to_hpe( rp, gp, bp, rc, gc, bc, gamu ); + if (gamu==1) { //gamut correction M.H.Brill S.Susstrunk + rp=MAXR(rp,0.0); + gp=MAXR(gp,0.0); + bp=MAXR(bp,0.0); + } + + rpa = nonlinear_adaptation( rp, fl ); + gpa = nonlinear_adaptation( gp, fl ); + bpa = nonlinear_adaptation( bp, fl ); + + return ((2.0 * rpa) + gpa + ((1.0 / 20.0) * bpa) - 0.305) * nbb; +} + +float Ciecam02::achromatic_response_to_whitefloat( float x, float y, float z, float d, float fl, float nbb, int gamu ) +{ + float r, g, b; + float rc, gc, bc; + float rp, gp, bp; + float rpa, gpa, bpa; + gamu=1; + xyz_to_cat02float( r, g, b, x, y, z, gamu ); + + rc = r * (((y * d) / r) + (1.0f - d)); + gc = g * (((y * d) / g) + (1.0f - d)); + bc = b * (((y * d) / b) + (1.0f - d)); + + cat02_to_hpefloat( rp, gp, bp, rc, gc, bc, gamu ); + if (gamu==1) { //gamut correction M.H.Brill S.Susstrunk + rp=MAXR(rp,0.0f); + gp=MAXR(gp,0.0f); + bp=MAXR(bp,0.0f); + } + + rpa = nonlinear_adaptationfloat( rp, fl ); + gpa = nonlinear_adaptationfloat( gp, fl ); + bpa = nonlinear_adaptationfloat( bp, fl ); + + return ((2.0f * rpa) + gpa + ((1.0f / 20.0f) * bpa) - 0.305f) * nbb; +} + +void Ciecam02::xyz_to_cat02( double &r, double &g, double &b, double x, double y, double z, int gamu ) +{ + gamu=1; + if (gamu==0) { + r = ( 0.7328 * x) + (0.4296 * y) - (0.1624 * z); + g = (-0.7036 * x) + (1.6975 * y) + (0.0061 * z); + b = ( 0.0030 * x) + (0.0136 * y) + (0.9834 * z); + } else if (gamu==1) { //gamut correction M.H.Brill S.Susstrunk + //r = ( 0.7328 * x) + (0.4296 * y) - (0.1624 * z); + //g = (-0.7036 * x) + (1.6975 * y) + (0.0061 * z); + //b = ( 0.0000 * x) + (0.0000 * y) + (1.0000 * z); + r = ( 1.007245 * x) + (0.011136* y) - (0.018381 * z);//Changjun Li + g = (-0.318061 * x) + (1.314589 * y) + (0.003471 * z); + b = ( 0.0000 * x) + (0.0000 * y) + (1.0000 * z); + } +} + +void Ciecam02::xyz_to_cat02float( float &r, float &g, float &b, float x, float y, float z, int gamu ) +{ + gamu=1; + if (gamu==0) { + r = ( 0.7328f * x) + (0.4296f * y) - (0.1624f * z); + g = (-0.7036f * x) + (1.6975f * y) + (0.0061f * z); + b = ( 0.0030f * x) + (0.0136f * y) + (0.9834f * z); + } else if (gamu==1) { //gamut correction M.H.Brill S.Susstrunk + //r = ( 0.7328 * x) + (0.4296 * y) - (0.1624 * z); + //g = (-0.7036 * x) + (1.6975 * y) + (0.0061 * z); + //b = ( 0.0000 * x) + (0.0000 * y) + (1.0000 * z); + r = ( 1.007245f * x) + (0.011136f* y) - (0.018381f * z);//Changjun Li + g = (-0.318061f * x) + (1.314589f * y) + (0.003471f * z); + b = ( 0.0000f * x) + (0.0000f * y) + (1.0000f * z); + } +} +#ifdef __SSE2__ +void Ciecam02::xyz_to_cat02float( vfloat &r, vfloat &g, vfloat &b, vfloat x, vfloat y, vfloat z ) +{ + //gamut correction M.H.Brill S.Susstrunk + r = ( F2V(1.007245f) * x) + (F2V(0.011136f) * y) - (F2V(0.018381f) * z);//Changjun Li + g = (F2V(-0.318061f) * x) + (F2V(1.314589f) * y) + (F2V(0.003471f) * z); + b = z; +} +#endif + +void Ciecam02::cat02_to_xyz( double &x, double &y, double &z, double r, double g, double b, int gamu ) +{ + gamu=1; + if (gamu==0) { + x = ( 1.096124 * r) - (0.278869 * g) + (0.182745 * b); + y = ( 0.454369 * r) + (0.473533 * g) + (0.072098 * b); + z = (-0.009628 * r) - (0.005698 * g) + (1.015326 * b); + } else if (gamu==1) { //gamut correction M.H.Brill S.Susstrunk + //x = ( 1.0978566 * r) - (0.277843 * g) + (0.179987 * b); + //y = ( 0.455053 * r) + (0.473938 * g) + (0.0710096* b); + //z = ( 0.000000 * r) - (0.000000 * g) + (1.000000 * b); + x = ( 0.99015849 * r) - (0.00838772* g) + (0.018229217 * b);//Changjun Li + y = ( 0.239565979 * r) + (0.758664642 * g) + (0.001770137* b); + z = ( 0.000000 * r) - (0.000000 * g) + (1.000000 * b); + } +} + +#ifndef __SSE2__ +void Ciecam02::cat02_to_xyzfloat( float &x, float &y, float &z, float r, float g, float b, int gamu ) +{ + gamu=1; + if (gamu==0) { + x = ( 1.096124f * r) - (0.278869f * g) + (0.182745f * b); + y = ( 0.454369f * r) + (0.473533f * g) + (0.072098f * b); + z = (-0.009628f * r) - (0.005698f * g) + (1.015326f * b); + } else if (gamu==1) { //gamut correction M.H.Brill S.Susstrunk + //x = ( 1.0978566 * r) - (0.277843 * g) + (0.179987 * b); + //y = ( 0.455053 * r) + (0.473938 * g) + (0.0710096* b); + //z = ( 0.000000 * r) - (0.000000 * g) + (1.000000 * b); + x = ( 0.99015849f * r) - (0.00838772f* g) + (0.018229217f * b);//Changjun Li + y = ( 0.239565979f * r) + (0.758664642f * g) + (0.001770137f* b); + z = ( 0.000000f * r) - (0.000000f * g) + (1.000000f * b); + } +} +#else +void Ciecam02::cat02_to_xyzfloat( vfloat &x, vfloat &y, vfloat &z, vfloat r, vfloat g, vfloat b ) +{ + //gamut correction M.H.Brill S.Susstrunk + x = ( F2V(0.99015849f) * r) - (F2V(0.00838772f)* g) + (F2V(0.018229217f) * b);//Changjun Li + y = ( F2V(0.239565979f) * r) + (F2V(0.758664642f) * g) + (F2V(0.001770137f)* b); + z = b; +} +#endif + +void Ciecam02::hpe_to_xyz( double &x, double &y, double &z, double r, double g, double b ) +{ + x = (1.910197 * r) - (1.112124 * g) + (0.201908 * b); + y = (0.370950 * r) + (0.629054 * g) - (0.000008 * b); + z = b; +} + +#ifndef __SSE2__ +void Ciecam02::hpe_to_xyzfloat( float &x, float &y, float &z, float r, float g, float b ) +{ + x = (1.910197f * r) - (1.112124f * g) + (0.201908f * b); + y = (0.370950f * r) + (0.629054f * g) - (0.000008f * b); + z = b; +} +#else +void Ciecam02::hpe_to_xyzfloat( vfloat &x, vfloat &y, vfloat &z, vfloat r, vfloat g, vfloat b ) +{ + x = (F2V(1.910197f) * r) - (F2V(1.112124f) * g) + (F2V(0.201908f) * b); + y = (F2V(0.370950f) * r) + (F2V(0.629054f) * g) - (F2V(0.000008f) * b); + z = b; +} +#endif + +void Ciecam02::cat02_to_hpe( double &rh, double &gh, double &bh, double r, double g, double b, int gamu ) +{ + gamu=1; + if (gamu==0) { + rh = ( 0.7409792 * r) + (0.2180250 * g) + (0.0410058 * b); + gh = ( 0.2853532 * r) + (0.6242014 * g) + (0.0904454 * b); + bh = (-0.0096280 * r) - (0.0056980 * g) + (1.0153260 * b); + } else if (gamu==1) { //Changjun Li + rh = ( 0.550930835 * r) + (0.519435987* g) - ( 0.070356303* b); + gh = ( 0.055954056 * r) + (0.89973132 * g) + (0.044315524 * b); + bh = (0.0 * r) - (0.0* g) + (1.0 * b); + } +} + +void Ciecam02::cat02_to_hpefloat( float &rh, float &gh, float &bh, float r, float g, float b, int gamu ) +{ + gamu=1; + if (gamu==0) { + rh = ( 0.7409792f * r) + (0.2180250f * g) + (0.0410058f * b); + gh = ( 0.2853532f * r) + (0.6242014f * g) + (0.0904454f * b); + bh = (-0.0096280f * r) - (0.0056980f * g) + (1.0153260f * b); + } else if (gamu==1) { //Changjun Li + rh = ( 0.550930835f * r) + (0.519435987f* g) - ( 0.070356303f* b); + gh = ( 0.055954056f * r) + (0.89973132f * g) + (0.044315524f * b); + bh = (0.0f * r) - (0.0f* g) + (1.0f * b); + } +} + +#ifdef __SSE2__ +void Ciecam02::cat02_to_hpefloat( vfloat &rh, vfloat &gh, vfloat &bh, vfloat r, vfloat g, vfloat b) +{ + //Changjun Li + rh = ( F2V(0.550930835f) * r) + (F2V(0.519435987f)* g) - ( F2V(0.070356303f)* b); + gh = ( F2V(0.055954056f) * r) + (F2V(0.89973132f) * g) + (F2V(0.044315524f) * b); + bh = b; +} +#endif + +void Ciecam02::Aab_to_rgb( double &r, double &g, double &b, double A, double aa, double bb, double nbb ) +{ + double x = (A / nbb) + 0.305; + + /* c1 c2 c3 */ + r = (0.32787 * x) + (0.32145 * aa) + (0.20527 * bb); + /* c1 c4 c5 */ + g = (0.32787 * x) - (0.63507 * aa) - (0.18603 * bb); + /* c1 c6 c7 */ + b = (0.32787 * x) - (0.15681 * aa) - (4.49038 * bb); +} + +#ifndef __SSE2__ +void Ciecam02::Aab_to_rgbfloat( float &r, float &g, float &b, float A, float aa, float bb, float nbb ) +{ + float x = (A / nbb) + 0.305f; + + /* c1 c2 c3 */ + r = (0.32787f * x) + (0.32145f * aa) + (0.20527f * bb); + /* c1 c4 c5 */ + g = (0.32787f * x) - (0.63507f * aa) - (0.18603f * bb); + /* c1 c6 c7 */ + b = (0.32787f * x) - (0.15681f * aa) - (4.49038f * bb); +} +#else +void Ciecam02::Aab_to_rgbfloat( vfloat &r, vfloat &g, vfloat &b, vfloat A, vfloat aa, vfloat bb, vfloat nbb ) +{ + vfloat c1 = F2V(0.32787f) * ((A / nbb) + F2V(0.305f)); + + /* c1 c2 c3 */ + r = c1 + (F2V(0.32145f) * aa) + (F2V(0.20527f) * bb); + /* c1 c4 c5 */ + g = c1 - (F2V(0.63507f) * aa) - (F2V(0.18603f) * bb); + /* c1 c6 c7 */ + b = c1 - (F2V(0.15681f) * aa) - (F2V(4.49038f) * bb); +} +#endif + +void Ciecam02::calculate_ab( double &aa, double &bb, double h, double e, double t, double nbb, double a ) +{ + double hrad = (h * M_PI) / 180.0; + double sinh = sin( hrad ); + double cosh = cos( hrad ); + double x = (a / nbb) + 0.305; + double p3 = 21.0/20.0; + if ( fabs( sinh ) >= fabs( cosh ) ) { + bb = ((0.32787 * x) * (2.0 + p3)) / + ((e / (t * sinh)) - + // ((0.32145 - 0.63507 - (p3 * 0.15681)) * (cosh / sinh)) - + // (0.20527 - 0.18603 - (p3 * 4.49038))); + ((-0.31362 - (p3 * 0.15681)) * (cosh / sinh)) - + (0.01924 - (p3 * 4.49038))); + + aa = (bb * cosh) / sinh; + } else { + aa = ((0.32787 * x) * (2.0 + p3)) / + ((e / (t * cosh)) - + // (0.32145 - 0.63507 - (p3 * 0.15681)) - + // ((0.20527 - 0.18603 - (p3 * 4.49038)) * (sinh / cosh))); + (-0.31362 - (p3 * 0.15681)) - + ((0.01924 - (p3 * 4.49038)) * (sinh / cosh))); + + bb = (aa * sinh) / cosh; + } +} +#ifndef __SSE2__ +void Ciecam02::calculate_abfloat( float &aa, float &bb, float h, float e, float t, float nbb, float a ) +{ + float2 sincosval = xsincosf((h * M_PI) / 180.0f); + float sinh = sincosval.x; + float cosh = sincosval.y; + float x = (a / nbb) + 0.305f; + float p3 = 1.05f; + bool swapValues = fabs( sinh ) > fabs( cosh ); + if (swapValues) { + std::swap(sinh,cosh); + } + + float div = ((e / (t * cosh)) - (-0.31362f - (p3 * 0.15681f)) - ((0.01924f - (p3 * 4.49038f)) * (sinh / cosh))); + // for large values of t the above calculation can change its sign which results in a hue shift of 180 degree + // so we have to check the sign to avoid this shift. + // Additionally it seems useful to limit the minimum value of div + // I limited it, but I'm sure the actual limit is not the best one + + if (signf(div) != signf(cosh) || fabsf(div) <= fabsf(cosh) * 2.f) { + div = cosh * 2.f; + } + + aa = ((0.32787f * x) * (2.0f + p3)) / div; + bb = (aa * sinh) / cosh; + + if (swapValues) { + std::swap(aa,bb); + } +} +#else +void Ciecam02::calculate_abfloat( vfloat &aa, vfloat &bb, vfloat h, vfloat e, vfloat t, vfloat nbb, vfloat a ) +{ + vfloat2 sincosval = xsincosf((h * F2V(M_PI)) / F2V(180.0f)); + vfloat sinh = sincosval.x; + vfloat cosh = sincosval.y; + vfloat x = (a / nbb) + F2V(0.305f); + vfloat p3 = F2V(1.05f); + vmask swapMask = vmaskf_gt(vabsf(sinh), vabsf(cosh)); + vswap(swapMask, sinh, cosh); + + vfloat div = ((e / (t * cosh)) - (F2V(-0.31362f) - (p3 * F2V(0.15681f))) - ((F2V(0.01924f) - (p3 * F2V(4.49038f))) * (sinh / cosh))); + // for large values of t the above calculation can change its sign which results in a hue shift of 180 degree + // so we have to check the sign to avoid this shift. + // Additionally it seems useful to limit the minimum value of div + // I limited it, but I'm sure the actual limit is not the best one + + vmask limitMask = vmaskf_neq(vsignf(div), vsignf(cosh)); + limitMask = vorm(limitMask, vmaskf_le(vabsf(div), vabsf(cosh) * F2V(2.f))); + div = vself(limitMask, cosh * F2V(2.f), div); + + aa = ((F2V(0.32787f) * x) * (F2V(2.0f) + p3)) / div; + bb = (aa * sinh) / cosh; + + vswap(swapMask, aa, bb); +} + +#endif + +void Ciecam02::initcam1(double gamu, double yb, double pilotd, double f, double la, double xw, double yw, double zw, double &n, double &d, double &nbb, double &ncb, + double &cz, double &aw, double &wh, double &pfl, double &fl, double &c) +{ + n = yb / yw; + if (pilotd==2.0) { d = d_factor( f, la ); } + else { d=pilotd; } + fl = calculate_fl_from_la_ciecam02( la ); + nbb = ncb = 0.725 * pow( 1.0 / n, 0.2 ); + cz = 1.48 + sqrt( n ); + aw = achromatic_response_to_white( xw, yw, zw, d, fl, nbb, gamu ); + wh =( 4.0 / c ) * ( aw + 4.0 ) * pow( fl, 0.25 ); + pfl = pow( fl, 0.25 ); +#ifdef _DEBUG + if (settings->verbose) { printf("Source double d=%f aw=%f fl=%f wh=%f\n",d,aw,fl,wh); } +#endif +} + +void Ciecam02::initcam1float(float gamu, float yb, float pilotd, float f, float la, float xw, float yw, float zw, float &n, float &d, float &nbb, float &ncb, + float &cz, float &aw, float &wh, float &pfl, float &fl, float &c) +{ + n = yb / yw; + if (pilotd==2.0) { d = d_factorfloat( f, la ); } + else { d=pilotd; } + fl = calculate_fl_from_la_ciecam02float( la ); + nbb = ncb = 0.725f * pow_F( 1.0f / n, 0.2f ); + cz = 1.48f + sqrt( n ); + aw = achromatic_response_to_whitefloat( xw, yw, zw, d, fl, nbb, gamu ); + wh =( 4.0f / c ) * ( aw + 4.0f ) * pow_F( fl, 0.25f ); + pfl = pow_F( fl, 0.25f ); +#ifdef _DEBUG + if (settings->verbose) { printf("Source float d=%f aw=%f fl=%f wh=%f c=%f awc=%f\n",d,aw,fl,wh,c,(4.f/c)*(aw+4.f)); } +#endif +} + +void Ciecam02::initcam2(double gamu, double yb, double f, double la, double xw, double yw, double zw, double &n, double &d, double &nbb, double &ncb, + double &cz, double &aw, double &fl) +{ + n = yb / yw; + d = d_factor( f, la ); + fl = calculate_fl_from_la_ciecam02( la ); + nbb = ncb = 0.725 * pow( 1.0 / n, 0.2 ); + cz = 1.48 + sqrt( n ); + aw = achromatic_response_to_white( xw, yw, zw, d, fl, nbb, gamu ); +#ifdef _DEBUG + if (settings->verbose) { printf("Viewing double d=%f aw=%f fl=%f n=%f\n",d,aw,fl,n); } +#endif +} + +void Ciecam02::initcam2float(float gamu, float yb, float f, float la, float xw, float yw, float zw, float &n, float &d, float &nbb, float &ncb, + float &cz, float &aw, float &fl) +{ + n = yb / yw; + d = d_factorfloat( f, la ); + fl = calculate_fl_from_la_ciecam02float( la ); + nbb = ncb = 0.725f * pow_F( 1.0f / n, 0.2f ); + cz = 1.48f + sqrt( n ); + aw = achromatic_response_to_whitefloat( xw, yw, zw, d, fl, nbb, gamu ); +#ifdef _DEBUG + if (settings->verbose) { printf("Viewing float d=%f aw=%f fl=%f n=%f\n",d,aw,fl,n); } +#endif +} + +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 r, g, b; + double rw, gw, bw; + double rc, gc, bc; + double rp, gp, bp; + double rpa, gpa, bpa; + double a, ca, cb; + double e, t; + double myh; + gamu=1; + xyz_to_cat02( r, g, b, x, y, z, gamu ); + xyz_to_cat02( rw, gw, bw, xw, yw, zw, gamu ); + rc = r * (((yw * d) / rw) + (1.0 - d)); + gc = g * (((yw * d) / gw) + (1.0 - d)); + bc = b * (((yw * d) / bw) + (1.0 - d)); + + cat02_to_hpe( rp, gp, bp, rc, gc, bc, gamu ); + if (gamu==1) { //gamut correction M.H.Brill S.Susstrunk + rp=MAXR(rp,0.0); + gp=MAXR(gp,0.0); + bp=MAXR(bp,0.0); + } + rpa = nonlinear_adaptation( rp, fl ); + gpa = nonlinear_adaptation( gp, fl ); + bpa = nonlinear_adaptation( bp, fl ); + + ca = rpa - ((12.0 * gpa) / 11.0) + (bpa / 11.0); + cb = (1.0 / 9.0) * (rpa + gpa - (2.0 * bpa)); + + myh = (180.0 / M_PI) * atan2( cb, ca ); + if ( myh < 0.0 ) { myh += 360.0; } + //we can also calculate H, if necessary...but it's using time...for what usage ? + /*double temp; + if(myh<20.14) { + temp = ((myh + 122.47)/1.2) + ((20.14 - myh)/0.8); + H = 300 + (100*((myh + 122.47)/1.2)) / temp; + } + else if(myh < 90.0) { + temp = ((myh - 20.14)/0.8) + ((90.00 - myh)/0.7); + H = (100*((myh - 20.14)/0.8)) / temp; + } + else if (myh < 164.25) { + temp = ((myh - 90.00)/0.7) + ((164.25 - myh)/1.0); + H = 100 + ((100*((myh - 90.00)/0.7)) / temp); + } + else if (myh < 237.53) { + temp = ((myh - 164.25)/1.0) + ((237.53 - myh)/1.2); + H = 200 + ((100*((myh - 164.25)/1.0)) / temp); + } + else { + temp = ((myh - 237.53)/1.2) + ((360 - myh + 20.14)/0.8); + H = 300 + ((100*((myh - 237.53)/1.2)) / temp); + } + */ + a = ((2.0 * rpa) + gpa + ((1.0 / 20.0) * bpa) - 0.305) * nbb; + if (gamu==1) { a=MAXR(a,0.0); }//gamut correction M.H.Brill S.Susstrunk + J = 100.0 * pow( a / aw, c * cz ); + + e = ((12500.0 / 13.0) * nc * ncb) * (cos( ((myh * M_PI) / 180.0) + 2.0 ) + 3.8); + t = (e * sqrt( (ca * ca) + (cb * cb) )) / (rpa + gpa + ((21.0 / 20.0) * bpa)); + + C = pow( t, 0.9 ) * sqrt( J / 100.0 ) + * pow( 1.64 - pow( 0.29, n ), 0.73 ); + + Q = wh * sqrt( J / 100.0 ); + M = C * pfl; + s = 100.0 * sqrt( M / Q ); + h = myh; +} + +void Ciecam02::xyz2jchqms_ciecam02float( float &J, float &C, float &h, float &Q, float &M, float &s,float &aw, float &fl, float &wh, + float x, float y, float z, float xw, float yw, float zw, + float yb, float la, float f, float c, float nc, float pilotd, int gamu, float pow1, float nbb, float ncb, float pfl, float cz, float d) + +{ + float r, g, b; + float rw, gw, bw; + float rc, gc, bc; + float rp, gp, bp; + float rpa, gpa, bpa; + float a, ca, cb; + float e, t; + float myh; + gamu=1; + xyz_to_cat02float( r, g, b, x, y, z, gamu ); + xyz_to_cat02float( rw, gw, bw, xw, yw, zw, gamu ); + rc = r * (((yw * d) / rw) + (1.0 - d)); + gc = g * (((yw * d) / gw) + (1.0 - d)); + bc = b * (((yw * d) / bw) + (1.0 - d)); + + cat02_to_hpefloat( rp, gp, bp, rc, gc, bc, gamu ); + if (gamu==1) { //gamut correction M.H.Brill S.Susstrunk + rp=MAXR(rp,0.0f); + gp=MAXR(gp,0.0f); + bp=MAXR(bp,0.0f); + } + rpa = nonlinear_adaptationfloat( rp, fl ); + gpa = nonlinear_adaptationfloat( gp, fl ); + bpa = nonlinear_adaptationfloat( bp, fl ); + + ca = rpa - ((12.0f * gpa) - bpa) / 11.0f; + cb = (0.11111111f) * (rpa + gpa - (2.0f * bpa)); + + myh = xatan2f( cb, ca ); + if ( myh < 0.0f ) { + myh += (2.f * M_PI); + } + + a = ((2.0f * rpa) + gpa + (0.05f * bpa) - 0.305f) * nbb; + if (gamu==1) { + a=MAXR(a,0.0f); //gamut correction M.H.Brill S.Susstrunk + } + + J = pow_F( a / aw, c * cz * 0.5f); + + e = ((961.53846f) * nc * ncb) * (xcosf( myh + 2.0f ) + 3.8f); + t = (e * sqrtf( (ca * ca) + (cb * cb) )) / (rpa + gpa + (1.05f * bpa)); + + C = pow_F( t, 0.9f ) * J * pow1; + + Q = wh * J; + J *= J * 100.0f; + M = C * pfl; + Q = (Q == 0.f ? 0.0001f : Q); // avoid division by zero + s = 100.0f * sqrtf( M / Q ); + h = (myh * 180.f) / (float)M_PI; +} +#ifdef __SSE2__ +void Ciecam02::xyz2jchqms_ciecam02float( vfloat &J, vfloat &C, vfloat &h, vfloat &Q, vfloat &M, vfloat &s, vfloat aw, vfloat fl, vfloat wh, + vfloat x, vfloat y, vfloat z, vfloat xw, vfloat yw, vfloat zw, + vfloat yb, vfloat la, vfloat f, vfloat c, vfloat nc, vfloat pow1, vfloat nbb, vfloat ncb, vfloat pfl, vfloat cz, vfloat d) + +{ + vfloat r, g, b; + vfloat rw, gw, bw; + vfloat rc, gc, bc; + vfloat rp, gp, bp; + vfloat rpa, gpa, bpa; + vfloat a, ca, cb; + vfloat e, t; + + xyz_to_cat02float( r, g, b, x, y, z); + xyz_to_cat02float( rw, gw, bw, xw, yw, zw); + vfloat onev = F2V(1.f); + rc = r * (((yw * d) / rw) + (onev - d)); + gc = g * (((yw * d) / gw) + (onev - d)); + bc = b * (((yw * d) / bw) + (onev - d)); + + cat02_to_hpefloat( rp, gp, bp, rc, gc, bc); + //gamut correction M.H.Brill S.Susstrunk + rp = _mm_max_ps(rp,ZEROV); + gp = _mm_max_ps(gp,ZEROV); + bp = _mm_max_ps(bp,ZEROV); + rpa = nonlinear_adaptationfloat( rp, fl ); + gpa = nonlinear_adaptationfloat( gp, fl ); + bpa = nonlinear_adaptationfloat( bp, fl ); + + ca = rpa - ((F2V(12.0f) * gpa) - bpa) / F2V(11.0f); + cb = F2V(0.11111111f) * (rpa + gpa - (bpa + bpa)); + + vfloat myh = xatan2f( cb, ca ); + vfloat temp = F2V(M_PI); + temp += temp; + temp += myh; + myh = vself(vmaskf_lt(myh, ZEROV), temp, myh); + + a = ((rpa + rpa) + gpa + (F2V(0.05f) * bpa) - F2V(0.305f)) * nbb; + a = _mm_max_ps(a,ZEROV); //gamut correction M.H.Brill S.Susstrunk + + J = pow_F( a / aw, c * cz * F2V(0.5f)); + + e = ((F2V(961.53846f)) * nc * ncb) * (xcosf( myh + F2V(2.0f) ) + F2V(3.8f)); + t = (e * _mm_sqrt_ps( (ca * ca) + (cb * cb) )) / (rpa + gpa + (F2V(1.05f) * bpa)); + + C = pow_F( t, F2V(0.9f) ) * J * pow1; + + Q = wh * J; + J *= J * F2V(100.0f); + M = C * pfl; + Q = _mm_max_ps(Q,F2V(0.0001f)); // avoid division by zero + s = F2V(100.0f) * _mm_sqrt_ps( M / Q ); + h = (myh * F2V(180.f)) / F2V(M_PI); +} +#endif + +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 r, g, b; + double rc, gc, bc; + double rp, gp, bp; + double rpa, gpa, bpa; + double rw, gw, bw; + double a, ca, cb; + double e, t; + gamu=1; + xyz_to_cat02( rw, gw, bw, xw, yw, zw, gamu ); + e = ((12500.0 / 13.0) * nc * ncb) * (cos( ((h * M_PI) / 180.0) + 2.0 ) + 3.8); + a = pow( J / 100.0, 1.0 / (c * cz) ) * aw; + t = pow( C / (sqrt( J / 100) * pow( 1.64 - pow( 0.29, n ), 0.73 )), 10.0 / 9.0 ); + + calculate_ab( ca, cb, h, e, t, nbb, a ); + Aab_to_rgb( rpa, gpa, bpa, a, ca, cb, nbb ); + + rp = inverse_nonlinear_adaptation( rpa, fl ); + gp = inverse_nonlinear_adaptation( gpa, fl ); + bp = inverse_nonlinear_adaptation( bpa, fl ); + + hpe_to_xyz( x, y, z, rp, gp, bp ); + xyz_to_cat02( rc, gc, bc, x, y, z, gamu ); + + r = rc / (((yw * d) / rw) + (1.0 - d)); + g = gc / (((yw * d) / gw) + (1.0 - d)); + b = bc / (((yw * d) / bw) + (1.0 - d)); + + cat02_to_xyz( x, y, z, r, g, b, gamu ); +} +#ifndef __SSE2__ +void Ciecam02::jch2xyz_ciecam02float( float &x, float &y, float &z, float J, float C, float h, + float xw, float yw, float zw, float yb, float la, + float f, 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; + float rp, gp, bp; + float rpa, gpa, bpa; + float rw, gw, bw; + float a, ca, cb; + float e, t; + gamu=1; + xyz_to_cat02float( rw, gw, bw, xw, yw, zw, gamu ); + e = ((961.53846f) * nc * ncb) * (xcosf( ((h * M_PI) / 180.0f) + 2.0f ) + 3.8f); + a = pow_F( J / 100.0f, 1.0f / (c * cz) ) * aw; + t = pow_F( 10.f * C / (sqrtf( J ) * pow1), 1.1111111f ); + + calculate_abfloat( ca, cb, h, e, t, nbb, a ); + Aab_to_rgbfloat( rpa, gpa, bpa, a, ca, cb, nbb ); + + rp = inverse_nonlinear_adaptationfloat( rpa, fl ); + gp = inverse_nonlinear_adaptationfloat( gpa, fl ); + bp = inverse_nonlinear_adaptationfloat( bpa, fl ); + + hpe_to_xyzfloat( x, y, z, rp, gp, bp ); + xyz_to_cat02float( rc, gc, bc, x, y, z, gamu ); + + r = rc / (((yw * d) / rw) + (1.0f - d)); + g = gc / (((yw * d) / gw) + (1.0f - d)); + b = bc / (((yw * d) / bw) + (1.0f - d)); + + cat02_to_xyzfloat( x, y, z, r, g, b, gamu ); +} + +#else +void Ciecam02::jch2xyz_ciecam02float( vfloat &x, vfloat &y, vfloat &z, vfloat J, vfloat C, vfloat h, + vfloat xw, vfloat yw, vfloat zw, vfloat yb, vfloat la, + vfloat f, vfloat nc, vfloat pow1, vfloat nbb, vfloat ncb, vfloat fl, vfloat d, vfloat aw, vfloat reccmcz) +{ + vfloat r, g, b; + vfloat rc, gc, bc; + vfloat rp, gp, bp; + vfloat rpa, gpa, bpa; + vfloat rw, gw, bw; + vfloat a, ca, cb; + vfloat e, t; + xyz_to_cat02float( rw, gw, bw, xw, yw, zw); + e = ((F2V(961.53846f)) * nc * ncb) * (xcosf( ((h * F2V(M_PI)) / F2V(180.0f)) + F2V(2.0f) ) + F2V(3.8f)); + a = pow_F( J / F2V(100.0f), reccmcz ) * aw; + t = pow_F( F2V(10.f) * C / (_mm_sqrt_ps( J ) * pow1), F2V(1.1111111f) ); + + calculate_abfloat( ca, cb, h, e, t, nbb, a ); + Aab_to_rgbfloat( rpa, gpa, bpa, a, ca, cb, nbb ); + + rp = inverse_nonlinear_adaptationfloat( rpa, fl ); + gp = inverse_nonlinear_adaptationfloat( gpa, fl ); + bp = inverse_nonlinear_adaptationfloat( bpa, fl ); + + hpe_to_xyzfloat( x, y, z, rp, gp, bp ); + xyz_to_cat02float( rc, gc, bc, x, y, z ); + + r = rc / (((yw * d) / rw) + (F2V(1.0f) - d)); + g = gc / (((yw * d) / gw) + (F2V(1.0f) - d)); + b = bc / (((yw * d) / bw) + (F2V(1.0f) - d)); + + cat02_to_xyzfloat( x, y, z, r, g, b ); +} +#endif + +double Ciecam02::nonlinear_adaptation( double c, double fl ) +{ + double p; + if (c<0.0) { p = pow( (-1.0*fl * c) / 100.0, 0.42 ); return ((-1.0*400.0 * p) / (27.13 + p)) + 0.1;} + else {p = pow( (fl * c) / 100.0, 0.42 ); return ((400.0 * p) / (27.13 + p)) + 0.1;} +} + +float Ciecam02::nonlinear_adaptationfloat( float c, float fl ) +{ + float p; + if (c<0.0f) { p = pow_F( (-1.0f*fl * c) / 100.0f, 0.42f ); return ((-1.0f*400.0f * p) / (27.13f + p)) + 0.1f;} + else {p = pow_F( (fl * c) / 100.0f, 0.42f ); return ((400.0f * p) / (27.13f + p)) + 0.1f;} +} + +#ifdef __SSE2__ +vfloat Ciecam02::nonlinear_adaptationfloat( vfloat c, vfloat fl ) +{ + vfloat c100 = F2V(100.f); + vfloat czd42 = F2V(0.42f); + vfloat c400 = vmulsignf(F2V(400.f),c); + fl = vmulsignf(fl,c); + vfloat p = pow_F( (fl * c) / c100, czd42 ); + vfloat c27d13 = F2V(27.13); + vfloat czd1 = F2V(0.1f); + return ((c400 * p) / (c27d13 + p)) + czd1; +} +#endif + +double Ciecam02::inverse_nonlinear_adaptation( double c, double fl ) +{ + int c1; + if (c-0.1 < 0.0) { c1=-1; } + else { c1=1; } + return c1*(100.0 / fl) * pow( (27.13 * fabs( c - 0.1 )) / (400.0 - fabs( c - 0.1 )), 1.0 / 0.42 ); +} + +#ifndef __SSE2__ +float Ciecam02::inverse_nonlinear_adaptationfloat( float c, float fl ) +{ + c -= 0.1f; + if (c < 0.f) { + fl *= -1.f; + if (c < -399.99f) { // avoid nan values + c = -399.99f; + } + } else if (c > 399.99f) { // avoid nan values + c = 399.99f; + } + return (100.0f / fl) * pow_F( (27.13f * fabsf( c )) / (400.0f - fabsf( c )), 2.38095238f ); +} + +#else +vfloat Ciecam02::inverse_nonlinear_adaptationfloat( vfloat c, vfloat fl ) +{ + c -= F2V(0.1f); + fl = vmulsignf(fl,c); + c = vabsf(c); + c = _mm_min_ps( c, F2V(399.99f)); + return (F2V(100.0f) / fl) * pow_F( (F2V(27.13f) * c) / (F2V(400.0f) - c), F2V(2.38095238f) ); +} +#endif +//end CIECAM Billy Bigg + +} diff --git a/rtengine/ciecam02.h b/rtengine/ciecam02.h new file mode 100644 index 000000000..c3dd0c745 --- /dev/null +++ b/rtengine/ciecam02.h @@ -0,0 +1,143 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _CIECAM02_ +#define _CIECAM02_ +#include +#include "LUT.h" +#include "opthelper.h" + +namespace rtengine +{ + +class Ciecam02 +{ +private: + static double d_factor( double f, double la ); + static float d_factorfloat( float f, float la ); + static double calculate_fl_from_la_ciecam02( double la ); + static float calculate_fl_from_la_ciecam02float( float la ); + static double achromatic_response_to_white( double x, double y, double z, double d, double fl, double nbb, int gamu ); + static float achromatic_response_to_whitefloat( float x, float y, float z, float d, float fl, float nbb, int gamu ); + static void xyz_to_cat02 ( double &r, double &g, double &b, double x, double y, double z, int gamu ); + static void cat02_to_hpe ( double &rh, double &gh, double &bh, double r, double g, double b, int gamu ); + static void cat02_to_xyz ( double &x, double &y, double &z, double r, double g, double b, int gamu ); + static void hpe_to_xyz ( double &x, double &y, double &z, double r, double g, double b ); + + static void xyz_to_cat02float ( float &r, float &g, float &b, float x, float y, float z, int gamu ); + static void cat02_to_hpefloat ( float &rh, float &gh, float &bh, float r, float g, float b, int gamu ); + +#ifdef __SSE2__ + static void xyz_to_cat02float ( vfloat &r, vfloat &g, vfloat &b, vfloat x, vfloat y, vfloat z ); + static void cat02_to_hpefloat ( vfloat &rh, vfloat &gh, vfloat &bh, vfloat r, vfloat g, vfloat b ); + static vfloat nonlinear_adaptationfloat( vfloat c, vfloat fl ); +#endif + + static void Aab_to_rgb( double &r, double &g, double &b, double A, double aa, double bb, double nbb ); + static void calculate_ab( double &aa, double &bb, double h, double e, double t, double nbb, double a ); + + static double nonlinear_adaptation( double c, double fl ); + static float nonlinear_adaptationfloat( float c, float fl ); + static double inverse_nonlinear_adaptation( double c, double fl ); + +#ifndef __SSE2__ + static float inverse_nonlinear_adaptationfloat( float c, float fl ); + static void calculate_abfloat( float &aa, float &bb, float h, float e, float t, float nbb, float a ); + static void Aab_to_rgbfloat( float &r, float &g, float &b, float A, float aa, float bb, float nbb ); + static void hpe_to_xyzfloat ( float &x, float &y, float &z, float r, float g, float b ); + static void cat02_to_xyzfloat ( float &x, float &y, float &z, float r, float g, float b, int gamu ); +#else + static vfloat inverse_nonlinear_adaptationfloat( vfloat c, vfloat fl ); + static void calculate_abfloat( vfloat &aa, vfloat &bb, vfloat h, vfloat e, vfloat t, vfloat nbb, vfloat a ); + static void Aab_to_rgbfloat( vfloat &r, vfloat &g, vfloat &b, vfloat A, vfloat aa, vfloat bb, vfloat nbb ); + static void hpe_to_xyzfloat ( vfloat &x, vfloat &y, vfloat &z, vfloat r, vfloat g, vfloat b ); + static void cat02_to_xyzfloat ( vfloat &x, vfloat &y, vfloat &z, vfloat r, vfloat g, vfloat b ); +#endif + +public: + Ciecam02 () {} + static void curvecolor(double satind, double satval, double &sres, double parsat); + static void curvecolorfloat(float satind, float satval, float &sres, float parsat); + static void curveJ (double br, double contr, int db, LUTf & outCurve , LUTu & histogram ) ; + static void curveJfloat (float br, float contr, int db, LUTf & outCurve , LUTu & histogram ) ; + + /** + * Inverse transform from CIECAM02 JCh to XYZ. + */ + 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); + +#ifndef __SSE2__ + static void jch2xyz_ciecam02float( float &x, float &y, float &z, + float J, float C, float h, + float xw, float yw, float zw, + float yb, float la, + float f, float c, float nc,int gamu,float n, float nbb, float ncb, float fl, float cz, float d, float aw ); +#else + static void jch2xyz_ciecam02float( vfloat &x, vfloat &y, vfloat &z, + vfloat J, vfloat C, vfloat h, + vfloat xw, vfloat yw, vfloat zw, + vfloat yb, vfloat la, + vfloat f, vfloat nc, vfloat n, vfloat nbb, vfloat ncb, vfloat fl, vfloat d, vfloat aw, vfloat reccmcz ); +#endif + /** + * Forward transform from XYZ to CIECAM02 JCh. + */ + static void initcam1(double gamu, double yb, double pilotd, double f, double la, double xw, double yw, double zw, double &n, double &d, double &nbb, double &ncb, + double &cz, double &aw, double &wh, double &pfl, double &fl, double &c); + + static void initcam2(double gamu, double yb, double f, double la, double xw, double yw, double zw, double &n, double &d, double &nbb, double &ncb, + double &cz, double &aw, double &fl); + + static void initcam1float(float gamu, float yb, float pilotd, float f, float la, float xw, float yw, float zw, float &n, float &d, float &nbb, float &ncb, + float &cz, float &aw, float &wh, float &pfl, float &fl, float &c); + + static void initcam2float(float gamu, float yb, float f, float la, float xw, float yw, float zw, float &n, float &d, float &nbb, float &ncb, + float &cz, float &aw, float &fl); + + static void 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 ); + + static void xyz2jchqms_ciecam02float( float &J, float &C, float &h, + float &Q, float &M, float &s,float &aw, float &fl, float &wh, + float x, float y, float z, + float xw, float yw, float zw, + float yb, float la, + float f, float c, float nc, float pilotd, int gamu, float n, float nbb, float ncb, float pfl, float cz, float d ); + +#ifdef __SSE2__ + static void xyz2jchqms_ciecam02float( vfloat &J, vfloat &C, vfloat &h, + vfloat &Q, vfloat &M, vfloat &s,vfloat aw, vfloat fl, vfloat wh, + vfloat x, vfloat y, vfloat z, + vfloat xw, vfloat yw, vfloat zw, + vfloat yb, vfloat la, + vfloat f, vfloat c, vfloat nc, vfloat n, vfloat nbb, vfloat ncb, vfloat pfl, vfloat cz, vfloat d ); + + +#endif + +}; +} +#endif diff --git a/rtengine/cieimage.cc b/rtengine/cieimage.cc new file mode 100644 index 000000000..ae66f92b8 --- /dev/null +++ b/rtengine/cieimage.cc @@ -0,0 +1,99 @@ +#include "cieimage.h" +#include +namespace rtengine { + +CieImage::CieImage (int w, int h) : fromImage(false), W(w), H(h) { + J_p = new float*[H]; + Q_p = new float*[H]; + M_p = new float*[H]; + C_p = new float*[H]; + sh_p = new float*[H]; + // ch_p = new float*[H]; + h_p = new float*[H]; + + // Initialize the pointers to zero + for (unsigned int c=0; c<6; ++c) + data[c] = NULL; + + // Trying to allocate all in one block + data[0] = new (std::nothrow) float [W*H*6]; + + if (data[0]) { + float * index = data[0]; + for (int i=0; idata, W*H*6*sizeof(float)); + else + // Separate allocation + for (unsigned int c=0; c<6; ++c) + memcpy(data[c], Img->data[c], W*H*sizeof(float)); +} + +} diff --git a/rtengine/cieimage.h b/rtengine/cieimage.h new file mode 100644 index 000000000..0688ad053 --- /dev/null +++ b/rtengine/cieimage.h @@ -0,0 +1,49 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _CIEIMAGE_H_ +#define _CIEIMAGE_H_ + +#include "image16.h" + +namespace rtengine { + +class CieImage { +private: + bool fromImage; + +public: + int W, H; + float * data[6]; + float** J_p; + float** Q_p; + float** M_p; + float** C_p; + float** sh_p; +// float** ch_p; + float** h_p; + + CieImage (int w, int h); + ~CieImage (); + + //Copies image data in Img into this instance. + void CopyFrom(CieImage *Img); +}; + +} +#endif diff --git a/rtengine/clutstore.cc b/rtengine/clutstore.cc new file mode 100644 index 000000000..119bbecc5 --- /dev/null +++ b/rtengine/clutstore.cc @@ -0,0 +1,394 @@ +#include "clutstore.h" +#include "rt_math.h" +#include "stdimagesource.h" +#include "safegtk.h" +#include "../rtgui/options.h" + +rtengine::CLUTStore clutStore; + +using namespace rtengine; + +const float MAXVAL8 = 255.; + +CLUTStore::CLUTStore() +{ +} + +CLUT* CLUTStore::getClut( const Glib::ustring& filename ) +{ + CLUT *result = 0; + m_mutex.lock(); + Cluts::iterator cluts_it = m_cluts.find(filename); + if (cluts_it == m_cluts.end()) { + if (m_cluts.size() >= options.clutCacheSize) { + // Evict a "random" entry from cache + Cluts::iterator victim_it = m_cluts.begin(); + if (--victim_it->second.first == -1) { + delete victim_it->second.second; + m_cluts.erase(victim_it); + } + } + cluts_it = m_cluts.insert(std::make_pair(filename, std::make_pair(0, new HaldCLUT))).first; + cluts_it->second.second->load( filename ); + } + if (cluts_it->second.second->isValid()) { + result = cluts_it->second.second; + ++cluts_it->second.first; + } else { + delete cluts_it->second.second; + m_cluts.erase(cluts_it); + } + m_mutex.unlock(); + + return result; +} + +void CLUTStore::releaseClut( const CLUT* clut ) +{ + m_mutex.lock(); + for (Cluts::iterator cluts_it = m_cluts.begin(); cluts_it != m_cluts.end(); ++cluts_it) { + if (cluts_it->second.second == clut) { + if (--cluts_it->second.first == -1) { + delete cluts_it->second.second; + m_cluts.erase(cluts_it); + } + break; + } + } + m_mutex.unlock(); +} + +void CLUTStore::clearCache() +{ + m_mutex.lock(); + for (Cluts::iterator cluts_it = m_cluts.begin(); cluts_it != m_cluts.end();) { + if (--cluts_it->second.first == -1) { + delete cluts_it->second.second; + Cluts::iterator tmp = cluts_it; + ++cluts_it; + m_cluts.erase(tmp); + } else { + ++cluts_it; + } + } + m_mutex.unlock(); +} + +void rtengine::splitClutFilename( Glib::ustring filename, Glib::ustring &name, Glib::ustring &extension, Glib::ustring &profileName ) +{ + filename = Glib::path_get_basename( filename ); + name = filename; + //remove dirs + size_t lastSlashPos = filename.find_last_of( "/" ); + if ( lastSlashPos == Glib::ustring::npos ) { + lastSlashPos = filename.find_last_of( "\\" ); + } + + size_t lastDotPos = filename.find_last_of( '.' ); + if ( lastDotPos != Glib::ustring::npos ) { + name = filename.substr( 0, lastDotPos ); + extension = filename.substr( lastDotPos + 1, Glib::ustring::npos ); + } + + profileName = "sRGB"; // sRGB by default + static std::vector workingProfiles = rtengine::getWorkingProfiles(); + for ( std::vector::iterator it = workingProfiles.begin(); it != workingProfiles.end(); ++it ) { + Glib::ustring ¤tProfile = *it; + if ( std::search( name.rbegin(), name.rend(), currentProfile.rbegin(), currentProfile.rend() ) == name.rbegin() ) { + profileName = currentProfile; + name = name.substr( 0, name.size() - currentProfile.size() ); + break; + } + } +} + +//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +HaldCLUT::HaldCLUT() +: m_clutImage( 0 ), + m_level (0), + m_profile( "sRGB" ) +{ +} + +HaldCLUT::~HaldCLUT() +{ + if ( m_clutImage ) { + m_clutImage->free(); + m_clutImage = 0; + } +} + +void HaldCLUT::load( Glib::ustring filename ) +{ + m_clutImage = loadFile( filename, "", m_level ); + Glib::ustring name, ext; + splitClutFilename( filename, name, ext, m_profile ); + if ( m_clutImage ) { + m_filename = filename; + } +} + +Glib::ustring HaldCLUT::profile() const +{ + return m_profile; +} + +Imagefloat* HaldCLUT::loadFile( Glib::ustring filename, Glib::ustring workingColorSpace, int &outLevel ) +{ + Imagefloat *result = 0; + StdImageSource imgSrc; + if ( !safe_file_test( filename, Glib::FILE_TEST_EXISTS ) || imgSrc.load(filename) ) { + return result; + } + + int fw, fh; + imgSrc.getFullSize (fw, fh, TR_NONE); + + bool valid = false; + //test on Hald format, copypasted from http://www.quelsolaar.com/technology/clut.html + if ( fw == fh ) { + outLevel = 1; + for(; outLevel * outLevel * outLevel < fw; outLevel++); + if( !( outLevel * outLevel * outLevel > fw ) ) { + valid = true; + } + } + + if ( valid ) { + ColorTemp currWB = imgSrc.getWB(); + Imagefloat* baseImg = new Imagefloat (fw, fh); + PreviewProps pp (0, 0, fw, fh, 1); + + procparams::ColorManagementParams icm; + icm.working = workingColorSpace; + + imgSrc.getImage (currWB, TR_NONE, baseImg, pp, procparams::ToneCurveParams(), icm, procparams::RAWParams()); + if ( !workingColorSpace.empty() ) { + imgSrc.convertColorSpace(baseImg, icm, currWB); + } + result = baseImg; + } + return result; +} + +void HaldCLUT::loadClut( Imagefloat *img, RawClut &outClut ) +{ + img->normalizeFloatTo1(); + int y_size = img->getH(); + int x_size = img->getW(); + outClut.resize( x_size * y_size * 3 ); + int clutIdx = 0; + //int level = m_level * m_level; (unused) + for(int y = 0; y < y_size; y++) { + for(int x = 0; x < x_size; x++) { + outClut[ clutIdx * 3 ] = img->r( y, x ) * MAXVAL8; + outClut[ clutIdx * 3 + 1 ] = img->g( y, x ) * MAXVAL8; + outClut[ clutIdx * 3 + 2 ] = img->b( y, x ) * MAXVAL8; + + ++clutIdx; + } + } +} + +Imagefloat* HaldCLUT::generateIdentImage( int level ) +{ + int imageWidth = level * level * level; + Imagefloat *resultImg = new Imagefloat( imageWidth, imageWidth ); + + int cubeSideSize = level * level; + float step = MAXVALF / (cubeSideSize - 1); + int pos = 0; + for( int b = 0; b < cubeSideSize; ++b ) { + for ( int g = 0; g < cubeSideSize; ++g ) { + for ( int r = 0; r < cubeSideSize; ++r ) { + int x = pos / imageWidth; + int y = pos % imageWidth; + resultImg->r( x, y ) = step * r; + resultImg->g( x, y ) = step * g; + resultImg->b( x, y ) = step * b; + ++pos; + } + } + } + return resultImg; +} + + +bool HaldCLUT::isValid() const +{ + return m_clutImage != 0; +} + +void HaldCLUT::getRGB( float rr, float gg, float bb, float &outR, float &outG, float &outB ) const +{ + rr /= MAXVALF; + gg /= MAXVALF; + bb /= MAXVALF; + correct( *m_clutImage, m_level, rr, gg, bb, outR, outG, outB ); +} + +inline float valF( unsigned char val ) +{ + return float( val ) / MAXVAL8; +} + +// copypasted from http://www.quelsolaar.com/technology/clut.html +void HaldCLUT::correct( const HaldCLUT::RawClut& clut, int level, float rr, float gg, float bb, float &outR, float &outG, float &outB ) +{ + int color, red, green, blue, i, j; + float tmp[6], r, g, b; + level = level * level; + + red = rr * (float)(level - 1); + if(red > level - 2) + red = (float)level - 2; + if(red < 0) + red = 0; + + green = gg * (float)(level - 1); + if(green > level - 2) + green = (float)level - 2; + if(green < 0) + green = 0; + + blue = bb * (float)(level - 1); + if(blue > level - 2) + blue = (float)level - 2; + if(blue < 0) + blue = 0; + + r = rr * (float)(level - 1) - red; + g = gg * (float)(level - 1) - green; + b = bb * (float)(level - 1) - blue; + + color = red + green * level + blue * level * level; + + i = color * 3; + j = (color + 1) * 3; + + tmp[0] = valF( clut[i++] ) * (1 - r) + valF( clut[j++] ) * r; + tmp[1] = valF( clut[i++] ) * (1 - r) + valF( clut[j++] ) * r; + tmp[2] = valF( clut[i] ) * (1 - r) + valF( clut[j] ) * r; + + i = (color + level) * 3; + j = (color + level + 1) * 3; + + tmp[3] = valF( clut[i++] ) * (1 - r) + valF( clut[j++] ) * r; + tmp[4] = valF( clut[i++] ) * (1 - r) + valF( clut[j++] ) * r; + tmp[5] = valF( clut[i] ) * (1 - r) + valF( clut[j] ) * r; + + outR = tmp[0] * (1 - g) + tmp[3] * g; + outG = tmp[1] * (1 - g) + tmp[4] * g; + outB = tmp[2] * (1 - g) + tmp[5] * g; + + i = (color + level * level) * 3; + j = (color + level * level + 1) * 3; + + tmp[0] = valF( clut[i++] ) * (1 - r) + valF( clut[j++] ) * r; + tmp[1] = valF( clut[i++] ) * (1 - r) + valF( clut[j++] ) * r; + tmp[2] = valF( clut[i] ) * (1 - r) + valF( clut[j] ) * r; + + i = (color + level + level * level) * 3; + j = (color + level + level * level + 1) * 3; + + tmp[3] = valF( clut[i++] ) * (1 - r) + valF( clut[j++] ) * r; + tmp[4] = valF( clut[i++] ) * (1 - r) + valF( clut[j++] ) * r; + tmp[5] = valF( clut[i] ) * (1 - r) + valF( clut[j] ) * r; + + tmp[0] = tmp[0] * (1 - g) + tmp[3] * g; + tmp[1] = tmp[1] * (1 - g) + tmp[4] * g; + tmp[2] = tmp[2] * (1 - g) + tmp[5] * g; + + outR = outR * (1 - b) + tmp[0] * b; + outG = outG * (1 - b) + tmp[1] * b; + outB = outB * (1 - b) + tmp[2] * b; +} + +inline void pos2xy( int pos, int imageSideSize, int &outX, int &outY ) +{ + outX = pos / imageSideSize; + outY = pos % imageSideSize; +} + +void HaldCLUT::correct( Imagefloat &clutImage, int level, float rr, float gg, float bb, float &outR, float &outG, float &outB ) +{ + int color, red, green, blue, i, j; + float tmp[6], r, g, b; + level = level * level; + int imageSideSize = clutImage.getW(); + + red = rr * (float)(level - 1); + if(red > level - 2) + red = (float)level - 2; + if(red < 0) + red = 0; + + green = gg * (float)(level - 1); + if(green > level - 2) + green = (float)level - 2; + if(green < 0) + green = 0; + + blue = bb * (float)(level - 1); + if(blue > level - 2) + blue = (float)level - 2; + if(blue < 0) + blue = 0; + + r = rr * (float)(level - 1) - red; + g = gg * (float)(level - 1) - green; + b = bb * (float)(level - 1) - blue; + + color = red + green * level + blue * level * level; + + + i = color; + j = color + 1; + int xi, yi, xj, yj; + pos2xy( i, imageSideSize, xi, yi ); + pos2xy( j, imageSideSize, xj, yj ); + + tmp[0] = clutImage.r( xi, yi ) * (1 - r) + clutImage.r( xj, yj ) * r; + tmp[1] = clutImage.g( xi, yi ) * (1 - r) + clutImage.g( xj, yj ) * r; + tmp[2] = clutImage.b( xi, yi ) * (1 - r) + clutImage.b( xj, yj ) * r; + + i = color + level; + j = color + level + 1; + pos2xy( i, imageSideSize, xi, yi ); + pos2xy( j, imageSideSize, xj, yj ); + + tmp[3] = clutImage.r( xi, yi ) * (1 - r) + clutImage.r( xj, yj ) * r; + tmp[4] = clutImage.g( xi, yi ) * (1 - r) + clutImage.g( xj, yj ) * r; + tmp[5] = clutImage.b( xi, yi ) * (1 - r) + clutImage.b( xj, yj ) * r; + + outR = tmp[0] * (1 - g) + tmp[3] * g; + outG = tmp[1] * (1 - g) + tmp[4] * g; + outB = tmp[2] * (1 - g) + tmp[5] * g; + + i = color + level * level; + j = color + level * level + 1; + pos2xy( i, imageSideSize, xi, yi ); + pos2xy( j, imageSideSize, xj, yj ); + + tmp[0] = clutImage.r( xi, yi ) * (1 - r) + clutImage.r( xj, yj ) * r; + tmp[1] = clutImage.g( xi, yi ) * (1 - r) + clutImage.g( xj, yj ) * r; + tmp[2] = clutImage.b( xi, yi ) * (1 - r) + clutImage.b( xj, yj ) * r; + + i = color + level + level * level; + j = color + level + level * level + 1; + pos2xy( i, imageSideSize, xi, yi ); + pos2xy( j, imageSideSize, xj, yj ); + + tmp[3] = clutImage.r( xi, yi ) * (1 - r) + clutImage.r( xj, yj ) * r; + tmp[4] = clutImage.g( xi, yi ) * (1 - r) + clutImage.g( xj, yj ) * r; + tmp[5] = clutImage.b( xi, yi ) * (1 - r) + clutImage.b( xj, yj ) * r; + + tmp[0] = tmp[0] * (1 - g) + tmp[3] * g; + tmp[1] = tmp[1] * (1 - g) + tmp[4] * g; + tmp[2] = tmp[2] * (1 - g) + tmp[5] * g; + + outR = outR * (1 - b) + tmp[0] * b; + outG = outG * (1 - b) + tmp[1] * b; + outB = outB * (1 - b) + tmp[2] * b; +} diff --git a/rtengine/clutstore.h b/rtengine/clutstore.h new file mode 100644 index 000000000..2ef9de490 --- /dev/null +++ b/rtengine/clutstore.h @@ -0,0 +1,93 @@ +#ifndef CLUT_STORE_INCLUDED +#define CLUT_STORE_INCLUDED + +#include +#include "../rtgui/threadutils.h" +#include "imagefloat.h" +#include +#include + +namespace rtengine { + +// simple CLUT interface +class CLUT +{ +public: + virtual void getRGB( float r, float g, float b, float &outR, float &outG, float &outB ) const = 0; + virtual Glib::ustring profile() const = 0; +protected: + virtual ~CLUT() {}; +}; + +class HaldCLUT : public CLUT +{ +public: + HaldCLUT(); + ~HaldCLUT(); + void load( Glib::ustring filename ); + bool isValid() const; + + void getRGB( float r, float g, float b, float &outR, float &outG, float &outB ) const; + Glib::ustring profile() const; + + typedef std::vector RawClut; // using 8 bit for reduce memory usage + static void correct( const RawClut&, int level, float r, float g, float b, float &outR, float &outG, float &outB ); + static void correct( Imagefloat &clutImage, int level, float rr, float gg, float bb, float &outR, float &outG, float &outB ); + static Imagefloat* generateIdentImage( int level ); + static Imagefloat* loadFile( Glib::ustring filename, Glib::ustring workingColorSpace, int &outLevel ); + +private: + + void loadClut( Imagefloat *img, RawClut &outClut ); + + Imagefloat *m_clutImage; + int m_level; + Glib::ustring m_filename; + Glib::ustring m_profile; +}; + +// CLUT cache +class CLUTStore +{ +public: + CLUTStore(); + + CLUT* getClut( const Glib::ustring& filename ); + void releaseClut( const CLUT* clut ); + + void clearCache(); + +private: + typedef std::map > Cluts; + + Cluts m_cluts; + MyMutex m_mutex; +}; + +void splitClutFilename( Glib::ustring filename, Glib::ustring &name, Glib::ustring &extension, Glib::ustring &profileName ); + +}; //namespace rtengine + +extern rtengine::CLUTStore clutStore; + +namespace rtengine { + +//support class for automate call of clutStore.releaseClut() +class ClutPtr +{ +public: + ClutPtr() : m_point( 0 ) {} + explicit ClutPtr(CLUT *p) : m_point( p ) {} + ~ClutPtr() { clutStore.releaseClut( m_point ); } + const CLUT* operator-> () const { return m_point; } + operator bool() const { return m_point != 0; } + void set( CLUT *p ) { m_point = p; } + +private: + ClutPtr& operator=(ClutPtr const& cp ); + CLUT *m_point; +}; + +}; //namespace rtengine + +#endif diff --git a/rtengine/color.cc b/rtengine/color.cc new file mode 100644 index 000000000..099612923 --- /dev/null +++ b/rtengine/color.cc @@ -0,0 +1,3584 @@ +/* +* This file is part of RawTherapee. +* +* Copyright (c) 2004-2010 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 "rtengine.h" +#include "color.h" +#include "iccmatrices.h" +#include "mytime.h" +#include "sleef.c" +#include "opthelper.h" + +using namespace std; + +namespace rtengine { + + extern const Settings* settings; + + cmsToneCurve* Color::linearGammaTRC; + LUTf Color::cachef; + LUTf Color::gamma2curve; + + LUTf Color::gammatab; + LUTf Color::igammatab_srgb; + LUTf Color::gammatab_srgb; + // LUTf Color::igammatab_709; +// LUTf Color::gammatab_709; + LUTf Color::igammatab_55; + LUTf Color::gammatab_55; + LUTf Color::igammatab_4; + LUTf Color::gammatab_4; + + LUTf Color::igammatab_26_11; + LUTf Color::gammatab_26_11; + LUTf Color::igammatab_24_17; + LUTf Color::gammatab_24_17a; + LUTf Color::gammatab_13_2; + + // Wikipedia sRGB: Unlike most other RGB color spaces, the sRGB gamma cannot be expressed as a single numerical value. + // The overall gamma is approximately 2.2, consisting of a linear (gamma 1.0) section near black, and a non-linear section elsewhere involving a 2.4 exponent + // and a gamma (slope of log output versus log input) changing from 1.0 through about 2.3. + const double Color::sRGBGamma = 2.2; + const double Color::sRGBGammaCurve = 2.4; + + const double Color::eps_max=580.40756; //(MAXVALF* 216.0f/24389.0); + const double Color::eps=216.0f/24389.0;//0.008856 + const double Color::kappa=24389.0/27.0;//903.29630; + + const float Color::D50x=0.9642f; //0.96422; + const float Color::D50z=0.8249f; //0.82521; + const double Color::u0=4.0*D50x/(D50x+15+3*D50z); + const double Color::v0=9.0/(D50x+15+3*D50z); + const double Color::epskap=8.0; + /* + * Munsell Lch correction + * Copyright (c) 2011 Jacques Desmis + */ + // Munsell Lch LUTf : 195 LUT + // about 70% data are corrected with significative corrections + // almost all data are taken for BG, YR, G excepted a few extreme values with a slight correction + // No LUTf for BG and Y : low corrections + // Only between 5B and 5PB for L > 40 : under very low corrections for L < 40 + + //give hue in function of L and C : Munsell correction + LUTf Color::_4P10, Color::_4P20, Color::_4P30, Color::_4P40, Color::_4P50, Color::_4P60; + LUTf Color::_1P10, Color::_1P20, Color::_1P30, Color::_1P40, Color::_1P50, Color::_1P60; + LUTf Color::_10PB10, Color::_10PB20, Color::_10PB30, Color::_10PB40, Color::_10PB50, Color::_10PB60; + LUTf Color::_9PB10, Color::_9PB20, Color::_9PB30, Color::_9PB40, Color::_9PB50, Color::_9PB60, Color::_9PB70, Color::_9PB80; + LUTf Color::_75PB10, Color::_75PB20, Color::_75PB30, Color::_75PB40, Color::_75PB50, Color::_75PB60, Color::_75PB70, Color::_75PB80; + LUTf Color::_6PB10, Color::_6PB20, Color::_6PB30, Color::_6PB40, Color::_6PB50, Color::_6PB60, Color::_6PB70, Color::_6PB80; + LUTf Color::_45PB10, Color::_45PB20, Color::_45PB30, Color::_45PB40, Color::_45PB50, Color::_45PB60, Color::_45PB70, Color::_45PB80; + LUTf Color::_3PB10, Color::_3PB20, Color::_3PB30, Color::_3PB40, Color::_3PB50, Color::_3PB60, Color::_3PB70, Color::_3PB80; + LUTf Color::_15PB10, Color::_15PB20, Color::_15PB30, Color::_15PB40, Color::_15PB50, Color::_15PB60, Color::_15PB70, Color::_15PB80; + LUTf Color::_05PB40, Color::_05PB50, Color::_05PB60, Color::_05PB70, Color::_05PB80; + LUTf Color::_10B40, Color::_10B50, Color::_10B60, Color::_10B70, Color::_10B80; + LUTf Color::_9B40, Color::_9B50, Color::_9B60, Color::_9B70, Color::_9B80; + LUTf Color::_7B40, Color::_7B50, Color::_7B60, Color::_7B70, Color::_7B80; + LUTf Color::_5B40, Color::_5B50, Color::_5B60, Color::_5B70, Color::_5B80; + LUTf Color::_10YR20, Color::_10YR30, Color::_10YR40, Color::_10YR50, Color::_10YR60, Color::_10YR70, Color::_10YR80, Color::_10YR90; + LUTf Color::_85YR20, Color::_85YR30, Color::_85YR40, Color::_85YR50, Color::_85YR60, Color::_85YR70, Color::_85YR80, Color::_85YR90; + LUTf Color::_7YR30, Color::_7YR40, Color::_7YR50, Color::_7YR60, Color::_7YR70, Color::_7YR80; + LUTf Color::_55YR30, Color::_55YR40, Color::_55YR50, Color::_55YR60, Color::_55YR70, Color::_55YR80, Color::_55YR90; + LUTf Color::_4YR30, Color::_4YR40, Color::_4YR50, Color::_4YR60, Color::_4YR70, Color::_4YR80; + LUTf Color::_25YR30, Color::_25YR40, Color::_25YR50, Color::_25YR60, Color::_25YR70; + LUTf Color::_10R30, Color::_10R40, Color::_10R50, Color::_10R60, Color::_10R70; + LUTf Color::_9R30, Color::_9R40, Color::_9R50, Color::_9R60, Color::_9R70; + LUTf Color::_7R30, Color::_7R40, Color::_7R50, Color::_7R60, Color::_7R70; + LUTf Color::_5R10, Color::_5R20, Color::_5R30; + LUTf Color::_25R10, Color::_25R20, Color::_25R30; + LUTf Color::_10RP10, Color::_10RP20, Color::_10RP30; + LUTf Color::_7G30, Color::_7G40, Color::_7G50, Color::_7G60, Color::_7G70, Color::_7G80; + LUTf Color::_5G30, Color::_5G40, Color::_5G50, Color::_5G60, Color::_5G70, Color::_5G80; + LUTf Color::_25G30, Color::_25G40, Color::_25G50, Color::_25G60, Color::_25G70, Color::_25G80; + LUTf Color::_1G30, Color::_1G40, Color::_1G50, Color::_1G60, Color::_1G70, Color::_1G80; + LUTf Color::_10GY30, Color::_10GY40, Color::_10GY50, Color::_10GY60, Color::_10GY70, Color::_10GY80; + LUTf Color::_75GY30, Color::_75GY40, Color::_75GY50, Color::_75GY60, Color::_75GY70, Color::_75GY80; + LUTf Color::_5GY30, Color::_5GY40, Color::_5GY50, Color::_5GY60, Color::_5GY70, Color::_5GY80; + +#ifdef _DEBUG + MunsellDebugInfo::MunsellDebugInfo() { + reinitValues(); + } + void MunsellDebugInfo::reinitValues() { + maxdhue[0]=maxdhue[1]=maxdhue[2]=maxdhue[3]=0.0f; + maxdhuelum[0]=maxdhuelum[1]=maxdhuelum[2]=maxdhuelum[3]=0.0f; + depass=depassLum=0; + } +#endif + + + void Color::init () { + + int maxindex = 65536; + cachef(maxindex,LUT_CLIP_BELOW); + + gamma2curve(maxindex,LUT_CLIP_BELOW|LUT_CLIP_ABOVE); + + for (int i=0; ieps_max) { + cachef[i] = 327.68*( exp(1.0/3.0 * log((double)i / MAXVALF) )); + } + else { + cachef[i] = 327.68*((kappa*i/MAXVALF+16.0)/116.0); + } + } + + for (int i=0; i-0.00001) { // no fabs, slow! + h = 0.f; + s = 0.f; + } + else { + double h_; + if (l_ <= 0.5) + s = float( (M-m) / (M+m) ); + else + s = float( (M-m) / (2.0-M-m) ); + + if ( var_R == M ) h_ = (var_G - var_B)/C; + else if ( var_G == M ) h_ = 2. + (var_B - var_R)/C; + else h_ = 4. + (var_R - var_G)/C; + h = float(h_ /= 6.0); + + if ( h < 0.f ) h += 1.f; + if ( h > 1.f ) h -= 1.f; + } + } + + double Color::hue2rgb(double p, double q, double t){ + if (t < 0.) t += 6.; + else if( t > 6.) t -= 6.; + + if (t < 1.) return p + (q - p) * t; + else if (t < 3.) return q; + else if (t < 4.) return p + (q - p) * (4. - t); + else return p; + } + + void Color::hsl2rgb (float h, float s, float l, float &r, float &g, float &b) { + + if (s == 0) + r = g = b = 65535.0f * l; // achromatic + else { + double m2; + double h_ = double(h); + double s_ = double(s); + double l_ = double(l); + + if (l <= 0.5f) + m2 = l_ * (1.0 + s_); + else { + m2 = l_ + s_ - l_ * s_; + } + + double m1 = 2.0 * l_ - m2; + + r = float(65535.0 * hue2rgb (m1, m2, h_ * 6.0 + 2.0)); + g = float(65535.0 * hue2rgb (m1, m2, h_ * 6.0)); + b = float(65535.0 * hue2rgb (m1, m2, h_ * 6.0 - 2.0)); + } + } + + void Color::hsl2rgb01 (float h, float s, float l, float &r, float &g, float &b) { + + if (s == 0) + r = g = b = l; // achromatic + else { + double m2; + double h_ = double(h); + double s_ = double(s); + double l_ = double(l); + + if (l <= 0.5f) + m2 = l_ * (1.0 + s_); + else { + m2 = l_ + s_ - l_ * s_; + } + + double m1 = 2.0 * l_ - m2; + + r = float(hue2rgb (m1, m2, h_ * 6.0 + 2.0)); + g = float(hue2rgb (m1, m2, h_ * 6.0)); + b = float(hue2rgb (m1, m2, h_ * 6.0 - 2.0)); + } + } + + void Color::rgb2hsv(float r, float g, float b, float &h, float &s, float &v) { + double var_R = r / 65535.0; + double var_G = g / 65535.0; + double var_B = b / 65535.0; + + double var_Min = min(var_R,var_G,var_B); + double var_Max = max(var_R,var_G,var_B); + double del_Max = var_Max - var_Min; + v = var_Max; + if (del_Max<0.00001 && del_Max>-0.00001) { // no fabs, slow! + h = 0; + s = 0; + } + else { + s = del_Max/var_Max; + + if ( var_R == var_Max ) h = (var_G - var_B)/del_Max; + else if ( var_G == var_Max ) h = 2.0 + (var_B - var_R)/del_Max; + else if ( var_B == var_Max ) h = 4.0 + (var_R - var_G)/del_Max; + h /= 6.0; + + if ( h < 0 ) h += 1; + if ( h > 1 ) h -= 1; + } + } + + void Color::hsv2rgb (float h, float s, float v, float &r, float &g, float &b) { + + float h1 = h*6.f; // sector 0 to 5 + int i = (int)h1; // floor() is very slow, and h1 is always >0 + float f = h1 - i; // fractional part of h + + float p = v * ( 1.f - s ); + float q = v * ( 1.f - s * f ); + float t = v * ( 1.f - s * ( 1.f - f ) ); + + float r1,g1,b1; + + if (i==1) {r1 = q; g1 = v; b1 = p;} + else if (i==2) {r1 = p; g1 = v; b1 = t;} + else if (i==3) {r1 = p; g1 = q; b1 = v;} + else if (i==4) {r1 = t; g1 = p; b1 = v;} + else if (i==5) {r1 = v; g1 = p; b1 = q;} + else /*i==(0|6)*/ {r1 = v; g1 = t; b1 = p;} + + r = ((r1)*65535.0f); + g = ((g1)*65535.0f); + b = ((b1)*65535.0f); + } + + // Function copied for speed concerns + // Not exactly the same as above ; this one return a result in the [0.0 ; 1.0] range + void Color::hsv2rgb01 (float h, float s, float v, float &r, float &g, float &b) { + float h1 = h*6; // sector 0 to 5 + int i = int(h1); + float f = h1 - i; // fractional part of h + + float p = v * ( 1 - s ); + float q = v * ( 1 - s * f ); + float t = v * ( 1 - s * ( 1 - f ) ); + + if (i==1) {r = q; g = v; b = p;} + else if (i==2) {r = p; g = v; b = t;} + else if (i==3) {r = p; g = q; b = v;} + else if (i==4) {r = t; g = p; b = v;} + else if (i==5) {r = v; g = p; b = q;} + else /*(i==0|6)*/ {r = v; g = t; b = p;} + } + + void Color::hsv2rgb (float h, float s, float v, int &r, int &g, int &b) { + + float h1 = h*6; // sector 0 to 5 + int i = floor( h1 ); + float f = h1 - i; // fractional part of h + + float p = v * ( 1 - s ); + float q = v * ( 1 - s * f ); + float t = v * ( 1 - s * ( 1 - f ) ); + + float r1,g1,b1; + + if (i==0) {r1 = v; g1 = t; b1 = p;} + else if (i==1) {r1 = q; g1 = v; b1 = p;} + else if (i==2) {r1 = p; g1 = v; b1 = t;} + else if (i==3) {r1 = p; g1 = q; b1 = v;} + else if (i==4) {r1 = t; g1 = p; b1 = v;} + else if (i==5) {r1 = v; g1 = p; b1 = q;} + + r = (int)( r1 * 65535); + g = (int)( g1 * 65535); + b = (int)( b1 * 65535); + } + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + void Color::xyz2srgb (float x, float y, float z, float &r, float &g, float &b) { + + //Transform to output color. Standard sRGB is D65, but internal representation is D50 + //Note that it is only at this point that we should have need of clipping color data + + /*float x65 = d65_d50[0][0]*x + d65_d50[0][1]*y + d65_d50[0][2]*z ; + float y65 = d65_d50[1][0]*x + d65_d50[1][1]*y + d65_d50[1][2]*z ; + float z65 = d65_d50[2][0]*x + d65_d50[2][1]*y + d65_d50[2][2]*z ; + + r = sRGB_xyz[0][0]*x65 + sRGB_xyz[0][1]*y65 + sRGB_xyz[0][2]*z65; + g = sRGB_xyz[1][0]*x65 + sRGB_xyz[1][1]*y65 + sRGB_xyz[1][2]*z65; + b = sRGB_xyz[2][0]*x65 + sRGB_xyz[2][1]*y65 + sRGB_xyz[2][2]*z65;*/ + + /*r = sRGBd65_xyz[0][0]*x + sRGBd65_xyz[0][1]*y + sRGBd65_xyz[0][2]*z ; + g = sRGBd65_xyz[1][0]*x + sRGBd65_xyz[1][1]*y + sRGBd65_xyz[1][2]*z ; + b = sRGBd65_xyz[2][0]*x + sRGBd65_xyz[2][1]*y + sRGBd65_xyz[2][2]*z ;*/ + + r = ((sRGB_xyz[0][0]*x + sRGB_xyz[0][1]*y + sRGB_xyz[0][2]*z)) ; + g = ((sRGB_xyz[1][0]*x + sRGB_xyz[1][1]*y + sRGB_xyz[1][2]*z)) ; + b = ((sRGB_xyz[2][0]*x + sRGB_xyz[2][1]*y + sRGB_xyz[2][2]*z)) ; + + } + void Color::xyz2Prophoto (float x, float y, float z, float &r, float &g, float &b) { + r = ((prophoto_xyz[0][0]*x + prophoto_xyz[0][1]*y + prophoto_xyz[0][2]*z)) ; + g = ((prophoto_xyz[1][0]*x + prophoto_xyz[1][1]*y + prophoto_xyz[1][2]*z)) ; + b = ((prophoto_xyz[2][0]*x + prophoto_xyz[2][1]*y + prophoto_xyz[2][2]*z)) ; + } + void Color::Prophotoxyz (float r, float g, float b, float &x, float &y, float &z) { + x = ((xyz_prophoto[0][0]*r + xyz_prophoto[0][1]*g + xyz_prophoto[0][2]*b)) ; + y = ((xyz_prophoto[1][0]*r + xyz_prophoto[1][1]*g + xyz_prophoto[1][2]*b)) ; + z = ((xyz_prophoto[2][0]*r + xyz_prophoto[2][1]*g + xyz_prophoto[2][2]*b)) ; + } + + void Color::rgbxyz (float r, float g, float b, float &x, float &y, float &z, const double xyz_rgb[3][3]) { + x = ((xyz_rgb[0][0]*r + xyz_rgb[0][1]*g + xyz_rgb[0][2]*b)) ; + y = ((xyz_rgb[1][0]*r + xyz_rgb[1][1]*g + xyz_rgb[1][2]*b)) ; + z = ((xyz_rgb[2][0]*r + xyz_rgb[2][1]*g + xyz_rgb[2][2]*b)) ; + } + + void Color::rgbxyz (float r, float g, float b, float &x, float &y, float &z, const float xyz_rgb[3][3]) { + x = ((xyz_rgb[0][0]*r + xyz_rgb[0][1]*g + xyz_rgb[0][2]*b)) ; + y = ((xyz_rgb[1][0]*r + xyz_rgb[1][1]*g + xyz_rgb[1][2]*b)) ; + z = ((xyz_rgb[2][0]*r + xyz_rgb[2][1]*g + xyz_rgb[2][2]*b)) ; + } + + void Color::xyz2rgb (float x, float y, float z, float &r, float &g, float &b, const double rgb_xyz[3][3]) { + //Transform to output color. Standard sRGB is D65, but internal representation is D50 + //Note that it is only at this point that we should have need of clipping color data + + /*float x65 = d65_d50[0][0]*x + d65_d50[0][1]*y + d65_d50[0][2]*z ; + float y65 = d65_d50[1][0]*x + d65_d50[1][1]*y + d65_d50[1][2]*z ; + float z65 = d65_d50[2][0]*x + d65_d50[2][1]*y + d65_d50[2][2]*z ; + + r = sRGB_xyz[0][0]*x65 + sRGB_xyz[0][1]*y65 + sRGB_xyz[0][2]*z65; + g = sRGB_xyz[1][0]*x65 + sRGB_xyz[1][1]*y65 + sRGB_xyz[1][2]*z65; + b = sRGB_xyz[2][0]*x65 + sRGB_xyz[2][1]*y65 + sRGB_xyz[2][2]*z65;*/ + + /*r = sRGBd65_xyz[0][0]*x + sRGBd65_xyz[0][1]*y + sRGBd65_xyz[0][2]*z ; + g = sRGBd65_xyz[1][0]*x + sRGBd65_xyz[1][1]*y + sRGBd65_xyz[1][2]*z ; + b = sRGBd65_xyz[2][0]*x + sRGBd65_xyz[2][1]*y + sRGBd65_xyz[2][2]*z ;*/ + + r = ((rgb_xyz[0][0]*x + rgb_xyz[0][1]*y + rgb_xyz[0][2]*z)) ; + g = ((rgb_xyz[1][0]*x + rgb_xyz[1][1]*y + rgb_xyz[1][2]*z)) ; + b = ((rgb_xyz[2][0]*x + rgb_xyz[2][1]*y + rgb_xyz[2][2]*z)) ; + } + + // same for float + void Color::xyz2rgb (float x, float y, float z, float &r, float &g, float &b, const float rgb_xyz[3][3]) { + r = ((rgb_xyz[0][0]*x + rgb_xyz[0][1]*y + rgb_xyz[0][2]*z)) ; + g = ((rgb_xyz[1][0]*x + rgb_xyz[1][1]*y + rgb_xyz[1][2]*z)) ; + b = ((rgb_xyz[2][0]*x + rgb_xyz[2][1]*y + rgb_xyz[2][2]*z)) ; + } + + void Color::trcGammaBW (float &r, float &g, float &b, float gammabwr, float gammabwg, float gammabwb) { + // correct gamma for black and white image : pseudo TRC curve of ICC profil + b/=65535.0f; + b= pow (max(b,0.0f), gammabwb); + b *=65535.0f; + r/=65535.0f; + r= pow (max(r,0.0f), gammabwr); + r *=65535.0f; + g/=65535.0f; + g= pow (max(g,0.0f), gammabwg); + g *=65535.0f; + } + + /** @brief Compute the B&W constants for the B&W processing and its tool's GUI + * + * @param setting BlackWhite::setting + * @param setting BlackWhite::filter + */ + void Color::computeBWMixerConstants (const Glib::ustring &setting, const Glib::ustring &filter, const Glib::ustring &algo, float &filcor, float &mixerRed, float &mixerGreen, + float &mixerBlue, float mixerOrange, float mixerYellow, float mixerCyan, float mixerPurple, float mixerMagenta, + bool autoc, bool complement, float &kcorec, double &rrm, double &ggm, double &bbm) + { + float somm; + float som = mixerRed+mixerGreen+mixerBlue; + // rM = mixerRed, gM = mixerGreen, bM = mixerBlue ! + //presets + if (setting=="RGB-Abs" || setting=="ROYGCBPM-Abs") + kcorec=som/100.f; + + if (!autoc) { + //if (setting=="RGB-Abs" || setting=="ROYGCBPM-Abs") {} //Keep the RGB mixer values as is! + //else if(setting=="RGB-Rel" || setting=="ROYGCBPM-Rel") {} //Keep the RGB mixer values as is! + if (setting=="NormalContrast") { mixerRed=43.f ; mixerGreen=33.f; mixerBlue=30.f; } + else if(setting=="Panchromatic") { mixerRed=33.3f; mixerGreen=33.3f; mixerBlue=33.3f; } + else if(setting=="HyperPanchromatic") { mixerRed=41.f ; mixerGreen=25.f; mixerBlue=34.f; } + else if(setting=="LowSensitivity") { mixerRed=27.f ; mixerGreen=27.f; mixerBlue=46.f; } + else if(setting=="HighSensitivity") { mixerRed=30.f ; mixerGreen=28.f; mixerBlue=42.f; } + else if(setting=="Orthochromatic") { mixerRed=0.f ; mixerGreen=42.f; mixerBlue=58.f; } + else if(setting=="HighContrast") { mixerRed=40.f ; mixerGreen=34.f; mixerBlue=60.f; } + else if(setting=="Luminance") { mixerRed=30.f ; mixerGreen=59.f; mixerBlue=11.f; } + else if(setting=="Landscape") { mixerRed=66.f ; mixerGreen=24.f; mixerBlue=10.f; } + else if(setting=="Portrait") { mixerRed=54.f ; mixerGreen=44.f; mixerBlue=12.f; } + else if(setting=="InfraRed") { mixerRed=-40.f; mixerGreen=200.f; mixerBlue=-17.f; } + } + + rrm=mixerRed; + ggm=mixerGreen; + bbm=mixerBlue; + + somm=mixerRed+mixerGreen+mixerBlue; + mixerRed=mixerRed/somm; mixerGreen=mixerGreen/somm; mixerBlue=mixerBlue/somm; + float koymcp=0.f; + + if(setting=="ROYGCBPM-Abs" || setting=="ROYGCBPM-Rel") { + float obM=0.f; + float ogM=0.f; + float orM=0.f; + + float ybM=0.f; + float yrM=0.f; + float ygM=0.f; + + float mgM=0.f; + float mrM=0.f; + float mbM=0.f; + + float pgM=0.f; + float prM=0.f; + float pbM=0.f; + + float crM=0.f; + float cgM=0.f; + float cbM=0.f; + //printf("mixred=%f\n",mixerRed); + + float fcompl = 1.f; + if(complement && algo=="SP") fcompl = 3.f;//special + else if(complement && algo=="LI") fcompl = 1.5f;//linear + // ponderate filters: report to R=G=B=33 + // I ponder RGB channel, not only orange or yellow or cyan, etc...it's my choice ! + if(mixerOrange != 33) { + if (algo=="SP") {//special + if (mixerOrange >= 33) orM = fcompl*(mixerOrange*0.67f - 22.11f)/100.f; else orM = fcompl*(-0.3f*mixerOrange +9.9f)/100.f; + if (mixerOrange >= 33) ogM = fcompl*(-0.164f*mixerOrange+5.412f)/100.f; else ogM = fcompl*(0.4f*mixerOrange-13.2f)/100.f; + } + else if (algo=="LI") {//linear + orM = fcompl*(mixerOrange - 33.f)/100.f; + ogM = fcompl*(0.5f*mixerOrange-16.5f)/100.f; + } + if(complement) obM =(-0.492f*mixerOrange+16.236f)/100.f; + mixerRed += orM; + mixerGreen += ogM; + mixerBlue += obM; + koymcp += (orM+ogM+obM); + // printf("mixred+ORange=%f\n",mixerRed); + + } + if(mixerYellow != 33) { + if (algo=="SP") yrM = fcompl*(-0.134f*mixerYellow+4.422f)/100.f;//22.4 + else if (algo=="LI")yrM = fcompl*(0.5f*mixerYellow-16.5f)/100.f;//22.4 + ygM = fcompl*(0.5f *mixerYellow-16.5f )/100.f; + if(complement) ybM =(-0.492f*mixerYellow+16.236f)/100.f; + mixerRed += yrM; + mixerGreen += ygM; + mixerBlue += ybM; + koymcp += (yrM+ygM+ybM); + } + if(mixerMagenta != 33) { + if (algo=="SP"){ + if(mixerMagenta >= 33) mrM = fcompl*( 0.67f *mixerMagenta-22.11f)/100.f; else mrM = fcompl*(-0.3f*mixerMagenta +9.9f)/100.f; + if(mixerMagenta >= 33) mbM = fcompl*(-0.164f*mixerMagenta+5.412f)/100.f; else mbM = fcompl*( 0.4f*mixerMagenta-13.2f)/100.f; + } + else if (algo=="LI"){ + mrM = fcompl*(mixerMagenta-33.f)/100.f; + mbM = fcompl*(0.5f*mixerMagenta-16.5f)/100.f; + } + if(complement) mgM =(-0.492f*mixerMagenta+16.236f)/100.f; + mixerRed += mrM; + mixerGreen += mgM; + mixerBlue += mbM; + koymcp += (mrM+mgM+mbM); + } + if(mixerPurple != 33) { + if (algo=="SP") prM = fcompl*(-0.134f*mixerPurple+4.422f)/100.f; + else if (algo=="LI")prM = fcompl*(0.5f*mixerPurple-16.5f)/100.f; + pbM = fcompl*(0.5f*mixerPurple-16.5f)/100.f; + if(complement) pgM = (-0.492f*mixerPurple+16.236f)/100.f; + mixerRed += prM; + mixerGreen += pgM; + mixerBlue += pbM; + koymcp += (prM+pgM+pbM); + } + if(mixerCyan != 33) { + if (algo=="SP")cgM = fcompl*(-0.134f*mixerCyan +4.422f)/100.f; + else if (algo=="LI")cgM = fcompl*(0.5f*mixerCyan -16.5f)/100.f; + cbM = fcompl*(0.5f*mixerCyan-16.5f)/100.f; + if(complement) crM = (-0.492f*mixerCyan+16.236f)/100.f; + mixerRed += crM; + mixerGreen += cgM; + mixerBlue += cbM; + koymcp += (crM+cgM+cbM); + } + } + if(setting=="ROYGCBPM-Abs") + kcorec = koymcp+som/100.f; + //Color filters + float filred,filgreen,filblue; + filred=1.f;filgreen=1.f;filblue=1.f;filcor=1.f; + if (filter=="None") {filred=1.f; filgreen=1.f; filblue=1.f; filcor=1.f;} + else if (filter=="Red") {filred=1.f; filgreen=0.05f;filblue=0.f; filcor=1.08f;} + else if (filter=="Orange") {filred=1.f; filgreen=0.6f; filblue=0.f; filcor=1.35f;} + else if (filter=="Yellow") {filred=1.f; filgreen=1.f; filblue=0.05f;filcor=1.23f;} + else if (filter=="YellowGreen") {filred=0.6f; filgreen=1.f; filblue=0.3f;filcor=1.32f;} + else if (filter=="Green") {filred=0.2f; filgreen=1.f; filblue=0.3f;filcor=1.41f;} + else if (filter=="Cyan") {filred=0.05f;filgreen=1.f; filblue=1.f; filcor=1.23f;} + else if (filter=="Blue") {filred=0.f; filgreen=0.05f;filblue=1.f; filcor=1.20f;} + else if (filter=="Purple") {filred=1.f; filgreen=0.05f;filblue=1.f; filcor=1.23f;} + mixerRed = mixerRed * filred; + mixerGreen = mixerGreen * filgreen; + mixerBlue = mixerBlue * filblue; + + mixerRed = filcor*mixerRed / (mixerRed + mixerGreen + mixerBlue); + mixerGreen = filcor*mixerGreen / (mixerRed + mixerGreen + mixerBlue); + mixerBlue = filcor*mixerBlue / (mixerRed + mixerGreen + mixerBlue); + + if(filter!="None") { + som = mixerRed+mixerGreen+mixerBlue; + if(setting=="RGB-Abs" || setting=="ROYGCBPM-Abs") kcorec = kcorec*som; + } + + } + + void Color::interpolateRGBColor (const float balance, const float r1, const float g1, const float b1, const float r2, const float g2, const float b2, int toDo, const double xyz_rgb[3][3], const double rgb_xyz[3][3], float &ro, float &go, float &bo) { + float X1, Y1, Z1, X2, Y2, Z2, X, Y, Z; + float L1, L2, a_1, b_1, a_2, b_2, a, b; + float c1, c2, h1, h2; + float RR,GG,BB; + float Lr; + + // converting color 1 to Lch + Color::rgbxyz(r1, g1, b1, X1, Y1, Z1, xyz_rgb); + Color::XYZ2Lab(X1, Y1, Z1, L1, a_1, b_1); + Color::Lab2Lch(a_1, b_1, c1, h1); + Lr=L1/327.68f;//for gamutlch + //gamut control on r1 g1 b1 + #ifndef NDEBUG + bool neg=false; + bool more_rgb=false; + + //gamut control : Lab values are in gamut + Color::gamutLchonly(h1,Lr,c1, RR, GG, BB, xyz_rgb, false, 0.15f, 0.96f, neg, more_rgb); + #else + Color::gamutLchonly(h1,Lr,c1, RR, GG, BB, xyz_rgb, false, 0.15f, 0.96f); + #endif + + L1=Lr*327.68f; + + // converting color 2 to Lch + Color::rgbxyz(r2, g2, b2, X2, Y2, Z2, xyz_rgb); + Color::XYZ2Lab(X2, Y2, Z2, L2, a_2, b_2); + Color::Lab2Lch(a_2, b_2, c2, h2); + + Lr=L2/327.68f;//for gamutlch + //gamut control on r2 g2 b2 + #ifndef NDEBUG + neg=false; + more_rgb=false; + //gamut control : Lab values are in gamut + Color::gamutLchonly(h2,Lr,c2, RR, GG, BB, xyz_rgb, false, 0.15f, 0.96f, neg, more_rgb); + #else + Color::gamutLchonly(h2,Lr,c2, RR, GG, BB, xyz_rgb, false, 0.15f, 0.96f); + #endif + L2=Lr*327.68f; + + // interpolating Lch values + if (toDo & CHANNEL_LIGHTNESS) { L1 = L1 + (L2-L1)*balance;if(L1<0.f) L1=0.f;}//do not allow negative L + if (toDo & CHANNEL_CHROMATICITY) {c1 = c1 + (c2-c1)*balance;if(c1<0.f) c1=0.f; if(c1>180.f) c1=180.f;}//limit C to reasonable value + if (toDo & CHANNEL_HUE) h1 = interpolatePolarHue_PI(h1, h2, balance); + + // here I have put gamut control with gamutlchonly on final process + Lr=L1/327.68f;//for gamutlch + #ifndef NDEBUG + neg=false; + more_rgb=false; + //gamut control : Lab values are in gamut + Color::gamutLchonly(h1,Lr,c1, RR, GG, BB, xyz_rgb, false, 0.15f, 0.96f, neg, more_rgb); + #else + //gamut control : Lab values are in gamut + Color::gamutLchonly(h1,Lr,c1, RR, GG, BB, xyz_rgb, false, 0.15f, 0.96f); + #endif + //convert CH ==> ab + L1=Lr*327.68f; + + // converting back to rgb + Color::Lch2Lab(c1, h1, a, b); + Color::Lab2XYZ(L1, a, b, X, Y, Z); + Color::xyz2rgb(X, Y, Z, ro, go, bo, rgb_xyz); + } + + + 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, + 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) + { + float X1, Y1, Z1, X2, Y2, Z2, X, Y, Z,XL,YL,ZL; + float L1, L2, LL, a_1, b_1, a_2, b_2, a, b,a_L,b_L; + float c1, c2, h1, h2,cL,hL; + float RR,GG,BB; + float Lr; + float slc=0.f; + float hh=0.f; + float ll=0.f; + float sh=0.f; + bool LCH=false; + + float ha,hb,hc,ba; + float c_1,h_1; + // converting color 1 to Lab (image) + Color::rgbxyz(r1, g1, b1, X1, Y1, Z1, xyz_rgb); + if(algm == 1) {//use H interpolate + Color::XYZ2Lab(X1, Y1, Z1, L1, a_1, b_1); + //Color::Lab2Lch(a_1, b_1, c_1, h_1) ; + } + // converting color l lab(low) first color + if(twoc==0) { // 2 colours + //Color::rgbxyz(rl, gl, bl, XL, YL, ZL, xyz_rgb); + XL=xl; + YL=yl; + ZL=zl; + if(algm <= 1) {//use H interpolate + Color::XYZ2Lab(XL, YL, ZL, LL, a_L, b_L); + } + } + + // converting color 2 to lab (universal or high) + X2=x2; + Y2=y2; + Z2=z2; + float c_2,h_2; + if(algm == 1 ) { + Color::XYZ2Lab(X2, Y2, Z2, L2, a_2, b_2); + //Color::Lab2Lch(a_2, b_2, c_2, h_2) ; + } + float bal,balH,cal,calH,calm; + bal=balH=balance; + cal=calH=calm=1.f-chromat; + float med=(iphigh+iplow)/2.f; + float medH=(iphigh+iplow)/2.f; + float medL=(iphigh+iplow)/2.f; + + med=1.f;medH=0.f;//new algo for 2 colors + float calan; + calan=chromat; + + float calby; + calby=luma; + + if(twoc==0) { // 2 colours + calan=chromat; + + //calculate new balance in function of (arbitrary) "med".. I hope no error !! + if (realL > iplow && realL<=med) bal = realL*balance/(iplow-med) - med*balance/(iplow-med); + else if (realL <= iplow) bal = realL*balance/iplow; + + if (realL > medH && realL <= iphigh) balH = realL*balance/(iphigh-medH) - medH*balance/(iphigh-medH); + else if (realL > iphigh) balH = realL*balance*(iphigh-1.f) - balance*(iphigh-1.f); + + //calculate new balance chroma + if (realL > iplow && realL<=med) cal = realL*calan/(iplow-med) - med*calan/(iplow-med); + else if (realL <= iplow) cal = realL*calan/iplow; + + if (realL > medH && realL <= iphigh) calH = realL*calan/(iphigh-medH) - medH*calan/(iphigh-medH); + else if (realL > iphigh) calH = realL*calan;//*(iphigh-1.f) - calan*(iphigh-1.f);//it is better without transition in highlight + } + + float hX=0.f; + float hLL,hH,ccL,ccH,llH,aaH,bbH; + + if(algm <=1){ + if(twoc==0 && metchrom==3) { // 2 colours only with special "ab" + if(algm==1) { + aaH=a_1 + (a_2-a_1)*calH;bbH=b_1 + (b_2-b_1)*calH;//pass to line after + a_1=aaH + (a_L-aaH)*cal*balance;b_1=bbH + (b_L-bbH)*cal*balance; + } + } + else if(twoc==1) { + if(metchrom==0) { + a_1=a_1 + (a_2-a_1)*balance; + b_1=b_1 + (b_2-b_1)*balance; + } + else if(metchrom==1){ + a_1=a_1 + (a_2-a_1)*calan*balance; + b_1=b_1 + (b_2-b_1)*calan*balance; + } + else if(metchrom==2) { + a_1=a_1 + (a_2-a_1)*calan*balance; + b_1=b_1 + (b_2-b_1)*calby*balance; + } + } + } + else + h1=hX; + + Color::Lab2XYZ(L1, a_1, b_1, X, Y, Z); + + Color::xyz2rgb(X, Y, Z, ro, go, bo, rgb_xyz);// ro go bo in gamut + } + + void Color::calcGamma (double pwr, double ts, int mode, int imax, double &gamma0, double &gamma1, double &gamma2, double &gamma3, double &gamma4, double &gamma5) { + //from Dcraw (D.Coffin) + int i; + double g[6], bnd[2]={0,0}; + + g[0] = pwr; + g[1] = ts; + g[2] = g[3] = g[4] = 0; + bnd[g[1] >= 1] = 1; + if (g[1] && (g[1]-1)*(g[0]-1) <= 0) { + for (i=0; i < 48; i++) { + g[2] = (bnd[0] + bnd[1])/2; + if (g[0]) + bnd[(pow(g[2]/g[1],-g[0]) - 1)/g[0] - 1/g[2] > -1] = g[2]; + else + bnd[g[2]/exp(1-1/g[2]) < g[1]] = g[2]; + } + g[3] = g[2] / g[1]; + if (g[0]) g[4] = g[2] * (1/g[0] - 1); + } + if (g[0]) + g[5] = 1 / (g[1]*SQR(g[3])/2 - g[4]*(1 - g[3]) + (1 - pow(g[3],1+g[0]))*(1 + g[4])/(1 + g[0])) - 1; + else + g[5] = 1 / (g[1]*SQR(g[3])/2 + 1 - g[2] - g[3] - g[2]*g[3]*(log(g[3]) - 1)) - 1; + if (!mode--) { + gamma0=g[0];gamma1=g[1];gamma2=g[2];gamma3=g[3];gamma4=g[4];gamma5=g[5]; + return; + } + } + + void Color::Lab2XYZ(float L, float a, float b, float &x, float &y, float &z) { + float LL=L/327.68f; + float aa=a/327.68f; + float bb=b/327.68f; + float fy = (0.00862069f * LL) + 0.137932f; // (L+16)/116 + float fx = (0.002f * aa) + fy; + float fz = fy - (0.005f * bb); + x = 65535.0f*f2xyz(fx)*D50x; + z = 65535.0f*f2xyz(fz)*D50z; + y=(LL>epskap) ? 65535.0f*fy*fy*fy : 65535.0f*LL/kappa; + } + +#ifdef __SSE2__ + void Color::Lab2XYZ(vfloat L, vfloat a, vfloat b, vfloat &x, vfloat &y, vfloat &z) { + vfloat c327d68 = F2V(327.68f); + L /= c327d68; + a /= c327d68; + b /= c327d68; + vfloat fy = F2V(0.00862069f) * L + F2V(0.137932f); + vfloat fx = F2V(0.002f) * a + fy; + vfloat fz = fy - (F2V(0.005f) * b); + vfloat c65535 = F2V(65535.f); + x = c65535*f2xyz(fx)*F2V(D50x); + z = c65535*f2xyz(fz)*F2V(D50z); + vfloat res1 = fy*fy*fy; + vfloat res2 = L / F2V(kappa); + y = vself(vmaskf_gt(L, F2V(epskap)), res1, res2); + y *= c65535; + } +#endif // __SSE2__ + + void Color::XYZ2Lab(float X, float Y, float Z, float &L, float &a, float &b) { + + float x = X/D50x; + float z = Z/D50z; + float y= Y; + float fx,fy,fz; + + fx = (x<=65535.0f ? cachef[x] : (327.68f*xcbrtf(x/MAXVALF))); + fy = (y<=65535.0f ? cachef[y] : (327.68f*xcbrtf(y/MAXVALF))); + fz = (z<=65535.0f ? cachef[z] : (327.68f*xcbrtf(z/MAXVALF))); + + L = (116.0f * fy - 5242.88f); //5242.88=16.0*327.68; + a = (500.0f * (fx - fy) ); + b = (200.0f * (fy - fz) ); + } + + void Color::Lab2Yuv(float L, float a, float b, float &Y, float &u, float &v) { + float fy = (0.00862069 * L/327.68) + 0.137932; // (L+16)/116 + float fx = (0.002 * a/327.68) + fy; + float fz = fy - (0.005 * b/327.68); + float LL=L/327.68; + + float X = 65535.0*f2xyz(fx)*D50x; + // Y = 65535.0*f2xyz(fy); + float Z = 65535.0*f2xyz(fz)*D50z; + Y=(LL/327.68f>epskap) ? 65535.0*fy*fy*fy : 65535.0*LL/kappa; + + u = 4.0*X/(X+15*Y+3*Z)-u0; + v = 9.0*Y/(X+15*Y+3*Z)-v0; + } + + void Color::Yuv2Lab(float Yin, float u, float v, float &L, float &a, float &b, double wp[3][3]) { + float u1 = u + u0; + float v1 = v + v0; + + float Y = Yin; + float X = (9*u1*Y)/(4*v1*D50x); + float Z = (12 - 3*u1 - 20*v1)*Y/(4*v1*D50z); + + gamutmap(X,Y,Z,wp); + + float fx = (X<=65535.0 ? cachef[X] : (327.68*exp(log(X/MAXVALF)/3.0 ))); + float fy = (Y<=65535.0 ? cachef[Y] : (327.68*exp(log(Y/MAXVALF)/3.0 ))); + float fz = (Z<=65535.0 ? cachef[Z] : (327.68*exp(log(Z/MAXVALF)/3.0 ))); + + L = (116.0 * fy - 5242.88); //5242.88=16.0*327.68; + a = (500.0 * (fx - fy) ); + b = (200.0 * (fy - fz) ); + } + + void Color::Lab2Lch(float a, float b, float &c, float &h) { + c = (sqrtf(a*a+b*b))/327.68f; + h = xatan2f(b, a); + } + + void Color::Lch2Lab(float c, float h, float &a, float &b) { + float2 sincosval = xsincosf(h); + a = 327.68f * c * sincosval.y; + b = 327.68f * c * sincosval.x; + } + + void Color::Luv2Lch(float u, float v, float &c, float &h) { + c = sqrtf(u*u+v*v); + h = xatan2f(v, u); //WARNING: should we care of division by zero here? + if (h < 0.f) + h += 1.f; + } + + void Color::Lch2Luv(float c, float h, float &u, float &v) { + float2 sincosval = xsincosf(h); + u = c * sincosval.x; + v = c * sincosval.y; + } + + // NOT TESTED + void Color::XYZ2Luv (float X, float Y, float Z, float &L, float &u, float &v) { + + X /= 65535.f; + Y /= 65535.f; + Z /= 65535.f; + + if (Y > float(eps)) + L = 116.f * pow(Y, 1.f/3.f) -16.f; + else + L = float(kappa) * Y; + u = 13.f * L * float(u0); + v = 13.f * L * float(v0); + } + + // NOT TESTED + void Color::Luv2XYZ (float L, float u, float v, float &X, float &Y, float &Z) { + if (L > float(epskap)) { + float t = (L+16.f) / 116.f; + Y = t*t*t; + } + else + Y = L/float(kappa); + + float a = ((52.f*L) / (u+13.f*L*float(u0)) -1.f) / 3.f; + float d = Y * (((39*L) / (v+13*float(v0))) -5.f); + float b = -5.f*Y; + X = (d-b) / (a+1.f/3.f); + + Z = X*a+b; + + X *= 65535.f; + Y *= 65535.f; + Z *= 65535.f; + } + + /* + * Gamut mapping algorithm + * Copyright (c) 2010-2011 Emil Martinec + * + * Solutions to scaling u and v to XYZ paralleliped boundaries + * Some equations: + * + * fu(X,Y,Z) = 4 X/(X + 15 Y + 3 Z); + * fv(X,Y,Z) = 9 Y/(X + 15 Y + 3 Z); + * + * take the plane spanned by X=a*Xr+b*Xg+c*Xb etc with one of a,b,c equal to 0 or 1, + * and itersect with the line u0+lam*u, or in other words solve + * + * u0+lam*u=fu(X,Y,Z) + * v0+lam*v=fv(X,Y,Z) + * + * The value of lam is the scale factor that takes the color to the gamut boundary + * columns of the matrix p=xyz_rgb are RGB tristimulus primaries in XYZ + * c is the color fixed on the boundary; and m=0 for c=0, m=1 for c=255 + */ + void Color::gamutmap(float &X, float &Y, float &Z, const double p[3][3]) + { + float u = 4*X/(X+15*Y+3*Z)-u0; + float v = 9*Y/(X+15*Y+3*Z)-v0; + + float lam[3][2]; + float lam_min = 1.0; + + for (int c=0; c<3; c++) + for (int m=0; m<2; m++) { + + int c1=(c+1)%3; + int c2=(c+2)%3; + + lam[c][m] = (-(p[0][c1]*p[1][c]*((-12 + 3*u0 + 20*v0)*Y + 4*m*65535*v0*p[2][c2])) + + p[0][c]*p[1][c1]*((-12 + 3*u0 + 20*v0)*Y + 4*m*65535*v0*p[2][c2]) - + 4*v0*p[0][c1]*(Y - m*65535*p[1][c2])*p[2][c] + 4*v0*p[0][c]*(Y - m*65535*p[1][c2])*p[2][c1] - + (4*m*65535*v0*p[0][c2] - 9*u0*Y)*(p[1][c1]*p[2][c] - p[1][c]*p[2][c1])); + + lam[c][m] /= (3*u*Y*(p[0][c1]*p[1][c] - p[1][c1]*(p[0][c] + 3*p[2][c]) + 3*p[1][c]*p[2][c1]) + + 4*v*(p[0][c1]*(5*Y*p[1][c] + m*65535*p[1][c]*p[2][c2] + Y*p[2][c] - m*65535*p[1][c2]*p[2][c]) - + p[0][c]*(5*Y*p[1][c1] + m*65535*p[1][c1]*p[2][c2] + Y*p[2][c1] - m*65535*p[1][c2]*p[2][c1]) + + m*65535*p[0][c2]*(p[1][c1]*p[2][c] - p[1][c]*p[2][c1]))); + + if (lam[c][m]0) lam_min=lam[c][m]; + + } + + u = u*lam_min + u0; + v = v*lam_min + v0; + + X = (9*u*Y)/(4*v); + Z = (12 - 3*u - 20*v)*Y/(4*v); + } + + void Color::skinred ( double J, double h, double sres, double Sp, float dred, float protect_red, int sk, float rstprotection, float ko, double &s) + { + float factorskin, factorsat,factor, factorskinext, interm; + float scale = 100.0f/100.1f;//reduction in normal zone + float scaleext=1.0f;//reduction in transition zone + float protect_redh; + float deltaHH=0.3f;//HH value transition : I have choice 0.3 radians + float HH; + bool doskin=false; + //rough correspondence between h (JC) and H (lab) that has relatively little importance because transitions that blur the correspondence is not linear + if ((float)h>8.6f && (float)h<=74.f ) {HH=(1.15f/65.4f)*(float)h-0.0012f; doskin=true;}//H > 0.15 H<1.3 + else if((float)h>0.f && (float)h<=8.6f ) {HH=(0.19f/8.6f )*(float)h-0.04f; doskin=true;}//H>-0.04 H < 0.15 + else if((float)h>355.f && (float)h<=360.f) {HH=(0.11f/5.0f )*(float)h-7.96f; doskin=true;}//H>-0.15 <-0.04 + else if((float)h>74.f && (float)h<95.f ) {HH=(0.30f/21.0f)*(float)h+0.24285f; doskin=true;}//H>1.3 H<1.6 + + if(doskin) + { + float chromapro=sres/Sp; + if(sk==1){//in C mode to adapt dred to J + if (J<16.0) dred = 40.0f; + else if(J<22.0) dred = (4.1666f)*(float)J -26.6f; + else if(J<60.0) dred = 55.0f; + else if(J<70.0) dred = -1.5f*(float)J +145.0f; + else dred = 40.0f; + } + if(chromapro>0.0) Color::scalered ( rstprotection, chromapro, 0.0, HH, deltaHH, scale, scaleext);//Scale factor + if(chromapro>1.0) {interm=(chromapro-1.0f)*100.0f; + factorskin= 1.0f+(interm*scale)/100.0f; + factorskinext=1.0f+(interm*scaleext)/100.0f;} + else { + factorskin= chromapro ; + factorskinext= chromapro ; + } + factorsat=chromapro; + factor=factorsat; + Color::transitred ( HH, s, dred, factorskin, protect_red, factorskinext, deltaHH, factorsat, factor); //transition + s*=factor; + } + else s=ko*sres; + + } + void Color::skinredfloat ( float J, float h, float sres, float Sp, float dred, float protect_red, int sk, float rstprotection, float ko, float &s) + { + float HH; + bool doskin=false; + //rough correspondence between h (JC) and H (lab) that has relatively little importance because transitions that blur the correspondence is not linear + if ((float)h>8.6f && (float)h<=74.f ) {HH=(1.15f/65.4f)*(float)h-0.0012f; doskin=true;}//H > 0.15 H<1.3 + else if((float)h>0.f && (float)h<=8.6f ) {HH=(0.19f/8.6f )*(float)h-0.04f; doskin=true;}//H>-0.04 H < 0.15 + else if((float)h>355.f && (float)h<=360.f) {HH=(0.11f/5.0f )*(float)h-7.96f; doskin=true;}//H>-0.15 <-0.04 + else if((float)h>74.f && (float)h<95.f ) {HH=(0.30f/21.0f)*(float)h+0.24285f; doskin=true;}//H>1.3 H<1.6 + + if(doskin) + { + float factorskin, factorsat,factor, factorskinext; + float protect_redh; + float deltaHH=0.3f;//HH value transition : I have choice 0.3 radians + float chromapro=sres/Sp; + if(sk==1){//in C mode to adapt dred to J + if (J<16.0) dred = 40.0f; + else if(J<22.0) dred = (4.1666f)*(float)J -26.6f; + else if(J<60.0) dred = 55.0f; + else if(J<70.0) dred = -1.5f*(float)J +145.0f; + else dred = 40.0f; + } + if(chromapro>1.0) { + float scale = 0.999000999f; // 100.0f/100.1f; reduction in normal zone + float scaleext=1.0f;//reduction in transition zone + Color::scalered ( rstprotection, chromapro, 0.0, HH, deltaHH, scale, scaleext);//Scale factor + float interm=(chromapro-1.0f); + factorskin= 1.0f+(interm*scale); + factorskinext=1.0f+(interm*scaleext); + } + else { + factorskin= chromapro ; + factorskinext= chromapro ; + } + factorsat=chromapro; + factor=factorsat; + Color::transitred ( HH, s, dred, factorskin, protect_red, factorskinext, deltaHH, factorsat, factor); //transition + s*=factor; + } + else s=ko*sres; + + } + + + + + + + void Color::scalered ( const float rstprotection, const float param, const float limit, const float HH, const float deltaHH, float &scale, float &scaleext) + { + if(rstprotection<99.9999f) { + if(param > limit) + scale = rstprotection/100.1f; + if((HH< (1.3f+deltaHH) && HH >=1.3f)) + // scaleext=HH*(1.0f-scale)/deltaHH + 1.0f - (1.3f+deltaHH)*(1.0f-scale)/deltaHH; //transition for Hue (red - yellow) + // optimized formula + scaleext=(HH*(1.0f-scale) + deltaHH - (1.3f+deltaHH)*(1.0f-scale))/deltaHH; //transition for Hue (red - yellow) + else if((HH< 0.15f && HH >(0.15f-deltaHH))) + // scaleext=HH*(scale-1.0f)/deltaHH + 1.0f - (0.15f-deltaHH)*(scale-1.0f)/deltaHH; //transition for hue (red purple) + // optimized formula + scaleext=(HH*(scale-1.0f) + deltaHH - (0.15f-deltaHH)*(scale-1.0f))/deltaHH; //transition for hue (red purple) + } + } + + void Color::transitred (const float HH, float const Chprov1, const float dred, const float factorskin, const float protect_red, const float factorskinext, const float deltaHH, const float factorsat, float &factor) + { + if(HH>=0.15f && HH<1.3f) { + if (Chprov1(0.15f-deltaHH) || HH<(1.3f+deltaHH) ) { + if (Chprov1 < dred) + factor = factorskinext;// C=dred=55 => real max of skin tones + else if (Chprov1 < (dred+protect_red))// transition + // factor = (factorsat-factorskinext)/protect_red*Chprov1+factorsat-(dred+protect_red)*(factorsat-factorskinext)/protect_red; + // optimized formula + factor = ((factorsat-factorskinext)*Chprov1 + factorsat*protect_red - (dred+protect_red)*(factorsat-factorskinext))/protect_red; + } + } + + /* + * AllMunsellLch correction + * Copyright (c) 2012 Jacques Desmis + * + * This function corrects the color (hue) for changes in chromaticity and luminance + * to use in a "for" or "do while" statement + * + * Parameters: + * bool lumaMuns : true => luminance correction (for delta L > 10) and chroma correction ; false : only chroma + * float Lprov1 , Loldd : luminance after and before + * float HH: hue before + * float Chprov1, CC : chroma after and before + * float coorectionHuechroma : correction Hue for chromaticity (saturation) + * float correctlum : correction Hue for luminance (brigtness, contrast,...) + * MunsellDebugInfo* munsDbgInfo: (Debug target only) object to collect information. + */ +#ifdef _DEBUG + void Color::AllMunsellLch(bool lumaMuns, float Lprov1,float Loldd,float HH,float Chprov1,float CC,float &correctionHuechroma,float &correctlum, MunsellDebugInfo* munsDbgInfo) +#else + void Color::AllMunsellLch(bool lumaMuns, float Lprov1, float Loldd, float HH, float Chprov1, float CC, float &correctionHuechroma, float &correctlum) +#endif + { + + bool contin1,contin2; + float correctionHue=0.0,correctionHueLum=0.0; + bool correctL; + if(CC >= 6.0 && CC < 140) { //if C > 140 we say C=140 (only in Prophoto ...with very large saturation) + static const float huelimit[8]={-2.48,-0.55,0.44,1.52,1.87,3.09,-0.27,0.44};//limits hue of blue-purple, red-yellow, green-yellow, red-purple + if (Chprov1 > 140.f) + Chprov1=139.f; //limits of LUTf + if (Chprov1 < 6.f) + Chprov1=6.f; + for(int zo=1;zo<=4;zo++) { + if(HH>huelimit[2*zo-2] && HHmaxdhue[idx] = MAX(munsDbgInfo->maxdhue[idx], absCorrectionHue); +} + } + if(absCorrectionHue > 0.45) +#pragma omp atomic + munsDbgInfo->depass++; //verify if no bug in calculation +#endif + correctionHuechroma=correctionHue; //preserve + if(lumaMuns) { + float correctlumprov=0.f; + float correctlumprov2=0.f; + if(correctL) { + //for Munsell luminance correction + correctlumprov=correctionHueLum; + contin1=true; + correctL=false; + } + correctionHueLum=0.0; + correctionHue=0.0; + if(fabs(Lprov1-Loldd) > 6.0) { + // correction if delta L significative..Munsell luminance + MunsellLch (Loldd, HH,Chprov1, Chprov1, correctionHue, zo, correctionHueLum, correctL); + + if(correctL) { + correctlumprov2=correctionHueLum; + contin2=true; + correctL=false; + } + correctionHueLum=0.0; + + if(contin1==true && contin2==true) + correctlum=correctlumprov2-correctlumprov; +#ifdef _DEBUG + float absCorrectLum = fabs(correctlum); + if(correctlum !=0.0) { + int idx=zo-1; +#pragma omp critical (maxdhuelum) +{ + munsDbgInfo->maxdhuelum[idx] = MAX(munsDbgInfo->maxdhuelum[idx],absCorrectLum); +} + } + if(absCorrectLum > 0.35) +#pragma omp atomic + munsDbgInfo->depassLum++; //verify if no bug in calculation +#endif + } + } + } + } + + } + +#ifdef _DEBUG + if (correctlum < -0.35f) correctlum =-0.35f; + else if(correctlum > 0.35f) correctlum = 0.35f; + if (correctionHuechroma<-0.45f) correctionHuechroma=-0.45f; + else if(correctionHuechroma> 0.45f) correctionHuechroma= 0.45f; +#endif + + } + + /* + * GamutLchonly correction + * Copyright (c)2012 Jacques Desmis and Jean-Christophe Frisch + * + * This function puts the data (Lab) in the gamut of "working profile": + * it returns the corrected values of the chromaticity and luminance + * + * float HH : hue + * float Lprov1 : input luminance value, sent back corrected + * float Chprov1: input chroma value, sent back corrected + * float R,G,B : red, green and blue value of the corrected color + * double wip : working profile + * bool isHLEnabled : if "highlight reconstruction " is enabled + * float coef : a float number between [0.95 ; 1.0[... the nearest it is from 1.0, the more precise it will be... and the longer too as more iteration will be necessary) + * bool neg and moreRGB : only in DEBUG mode to calculate iterations for negatives values and > 65535 + */ +#ifdef _DEBUG + void Color::gamutLchonly (float HH, float &Lprov1, float &Chprov1, float &R, float &G, float &B, const double wip[3][3], const bool isHLEnabled, const float lowerCoef, const float higherCoef, bool &neg, bool &more_rgb) +#else + void Color::gamutLchonly (float HH, float &Lprov1, float &Chprov1, float &R, float &G, float &B, const double wip[3][3], const bool isHLEnabled, const float lowerCoef, const float higherCoef) +#endif + { + const float ClipLevel = 65535.0f; + bool inGamut; +#ifdef _DEBUG + neg=false, more_rgb=false; +#endif + float2 sincosval = xsincosf(HH); + do { + inGamut=true; + + //Lprov1=LL; + float aprov1=Chprov1*sincosval.y; + float bprov1=Chprov1*sincosval.x; + + //conversion Lab RGB to limit Lab values - this conversion is useful before Munsell correction + float fy = (0.00862069f *Lprov1 )+ 0.137932f; + float fx = (0.002f * aprov1) + fy; + float fz = fy - (0.005f * bprov1); + + float x_ = 65535.0f * f2xyz(fx)*D50x; + // float y_ = 65535.0f * f2xyz(fy); + float z_ = 65535.0f * f2xyz(fz)*D50z; + float y_=(Lprov1>epskap) ? 65535.0*fy*fy*fy : 65535.0*Lprov1/kappa; + + xyz2rgb(x_,y_,z_,R,G,B,wip); + + // gamut control before saturation to put Lab values in future gamut, but not RGB + if (R<0.0f || G<0.0f || B<0.0f) { +#ifdef _DEBUG + neg=true; +#endif + if (Lprov1 < 0.1f) Lprov1 = 0.1f; + //gamut for L with ultra blue : we can improve the algorithm ... thinner, and other color ??? + if(HH < -0.9f && HH > -1.55f ) {//ultra blue + if(Chprov1 > 160.f) if (Lprov1 < 5.f) Lprov1 = 5.f;//very very very very high chroma + if(Chprov1 > 140.f) if (Lprov1 < 3.5f) Lprov1 = 3.5f; + if(Chprov1 > 120.f) if (Lprov1 < 2.f) Lprov1 = 2.f; + if(Chprov1 > 105.f) if (Lprov1 < 1.f) Lprov1 = 1.f; + if(Chprov1 > 90.f) if (Lprov1 < 0.7f) Lprov1 = 0.7f; + if(Chprov1 > 50.f) if (Lprov1 < 0.5f) Lprov1 = 0.5f; + if(Chprov1 > 20.f) if (Lprov1 < 0.4f) Lprov1 = 0.4f; + } + Chprov1 *= higherCoef; // decrease the chromaticity value + if (Chprov1 <= 3.0f) + Lprov1 += lowerCoef; + inGamut = false; + } else if (!isHLEnabled && (R>ClipLevel || G>ClipLevel || B>ClipLevel)) { + + // if "highlight reconstruction" is enabled or the point is completely white (clipped, no color), don't control Gamut +#ifdef _DEBUG + more_rgb=true; +#endif + if (Lprov1 > 99.999f) + Lprov1 = 99.98f; + Chprov1 *= higherCoef; + if (Chprov1 <= 3.0f) + Lprov1 -= lowerCoef; + inGamut = false; + } + } + while (!inGamut); + //end first gamut control + } + + /* + * GamutLchonly correction + * Copyright (c)2012 Jacques Desmis and Jean-Christophe Frisch + * + * This function puts the data (Lab) in the gamut of "working profile": + * it returns the corrected values of the chromaticity and luminance + * + * float HH : hue + * float2 sincosval : sin and cos of HH + * float Lprov1 : input luminance value, sent back corrected + * float Chprov1: input chroma value, sent back corrected + * float R,G,B : red, green and blue value of the corrected color + * double wip : working profile + * bool isHLEnabled : if "highlight reconstruction " is enabled + * float coef : a float number between [0.95 ; 1.0[... the nearest it is from 1.0, the more precise it will be... and the longer too as more iteration will be necessary) + * bool neg and moreRGB : only in DEBUG mode to calculate iterations for negatives values and > 65535 + */ +#ifdef _DEBUG + void Color::gamutLchonly (float HH, float2 sincosval, float &Lprov1, float &Chprov1, float &R, float &G, float &B, const double wip[3][3], const bool isHLEnabled, const float lowerCoef, const float higherCoef, bool &neg, bool &more_rgb) +#else + void Color::gamutLchonly (float HH, float2 sincosval, float &Lprov1, float &Chprov1, float &R, float &G, float &B, const double wip[3][3], const bool isHLEnabled, const float lowerCoef, const float higherCoef) +#endif + { + const float ClipLevel = 65535.0f; + bool inGamut; +#ifdef _DEBUG + neg=false, more_rgb=false; +#endif + do { + inGamut=true; + + //Lprov1=LL; + float aprov1=Chprov1*sincosval.y; + float bprov1=Chprov1*sincosval.x; + + //conversion Lab RGB to limit Lab values - this conversion is useful before Munsell correction + float fy = (0.00862069f *Lprov1 )+ 0.137932f; + float fx = (0.002f * aprov1) + fy; + float fz = fy - (0.005f * bprov1); + + float x_ = 65535.0f * f2xyz(fx)*D50x; + // float y_ = 65535.0f * f2xyz(fy); + float z_ = 65535.0f * f2xyz(fz)*D50z; + float y_=(Lprov1>epskap) ? 65535.0*fy*fy*fy : 65535.0*Lprov1/kappa; + + xyz2rgb(x_,y_,z_,R,G,B,wip); + + // gamut control before saturation to put Lab values in future gamut, but not RGB + if (R<0.0f || G<0.0f || B<0.0f) { +#ifdef _DEBUG + neg=true; +#endif + if (Lprov1 < 0.1f) Lprov1 = 0.1f; + //gamut for L with ultra blue : we can improve the algorithm ... thinner, and other color ??? + if(HH < -0.9f && HH > -1.55f ) {//ultra blue + if(Chprov1 > 160.f) if (Lprov1 < 5.f) Lprov1 = 5.f;//very very very very high chroma + if(Chprov1 > 140.f) if (Lprov1 < 3.5f) Lprov1 = 3.5f; + if(Chprov1 > 120.f) if (Lprov1 < 2.f) Lprov1 = 2.f; + if(Chprov1 > 105.f) if (Lprov1 < 1.f) Lprov1 = 1.f; + if(Chprov1 > 90.f) if (Lprov1 < 0.7f) Lprov1 = 0.7f; + if(Chprov1 > 50.f) if (Lprov1 < 0.5f) Lprov1 = 0.5f; + if(Chprov1 > 20.f) if (Lprov1 < 0.4f) Lprov1 = 0.4f; + } + Chprov1 *= higherCoef; // decrease the chromaticity value + if (Chprov1 <= 3.0f) + Lprov1 += lowerCoef; + inGamut = false; + } else if (!isHLEnabled && (R>ClipLevel || G>ClipLevel || B>ClipLevel)) { + + // if "highlight reconstruction" is enabled or the point is completely white (clipped, no color), don't control Gamut +#ifdef _DEBUG + more_rgb=true; +#endif + if (Lprov1 > 99.999f) + Lprov1 = 99.98f; + Chprov1 *= higherCoef; + if (Chprov1 <= 3.0f) + Lprov1 -= lowerCoef; + inGamut = false; + } + } + while (!inGamut); + //end first gamut control + } + + +#ifdef _DEBUG + void Color::gamutLchonly (float2 sincosval, float &Lprov1, float &Chprov1, const float wip[3][3], const bool isHLEnabled, const float lowerCoef, const float higherCoef, bool &neg, bool &more_rgb) +#else + void Color::gamutLchonly (float2 sincosval, float &Lprov1, float &Chprov1, const float wip[3][3], const bool isHLEnabled, const float lowerCoef, const float higherCoef) +#endif + { + const float ClipLevel = 65535.0f; + bool inGamut; +#ifdef _DEBUG + neg=false, more_rgb=false; +#endif + do { + inGamut=true; + + //Lprov1=LL; + float aprov1=Chprov1*sincosval.y; + float bprov1=Chprov1*sincosval.x; + + //conversion Lab RGB to limit Lab values - this conversion is useful before Munsell correction + float fy = (0.00862069f *Lprov1 )+ 0.137932f; + float fx = (0.002f * aprov1) + fy; + float fz = fy - (0.005f * bprov1); + + float x_ = 65535.0f * f2xyz(fx)*D50x; + // float y_ = 65535.0f * f2xyz(fy); + float z_ = 65535.0f * f2xyz(fz)*D50z; + float y_=(Lprov1>epskap) ? 65535.0*fy*fy*fy : 65535.0*Lprov1/kappa; + + float R,G,B; + xyz2rgb(x_,y_,z_,R,G,B,wip); + + // gamut control before saturation to put Lab values in future gamut, but not RGB + if (R<0.0f || G<0.0f || B<0.0f) { +#ifdef _DEBUG + neg=true; +#endif + if (Lprov1 < 0.01f) + Lprov1 = 0.01f; + Chprov1 *= higherCoef; // decrease the chromaticity value + if (Chprov1 <= 3.0f) + Lprov1 += lowerCoef; + inGamut = false; + } else if (!isHLEnabled && (R>ClipLevel || G>ClipLevel || B>ClipLevel)) { + + // if "highlight reconstruction" is enabled or the point is completely white (clipped, no color), don't control Gamut +#ifdef _DEBUG + more_rgb=true; +#endif + if (Lprov1 > 99.999f) + Lprov1 = 99.98f; + Chprov1 *= higherCoef; + if (Chprov1 <= 3.0f) + Lprov1 -= lowerCoef; + inGamut = false; + } + } + while (!inGamut); + //end first gamut control + } + /* + * LabGamutMunsell + * Copyright (c) 2012 Jacques Desmis + * + * This function is the overall Munsell's corrections, but only on global statement: I think it's better to use local statement with AllMunsellLch + * not for use in a "for" or "do while" loop + * they are named accordingly : gamutLchonly and AllMunsellLch + * it can be used before and after treatment (saturation, gamma, luminance, ...) + * + * Parameters: + * float *labL : RT Lab L channel data + * float *laba : RT Lab a channel data + * float *labb : RT Lab b channel data + * bool corMunsell : performs Munsell correction + * bool lumaMuns : (used only if corMuns=true) + * true: apply luma + chroma Munsell correction if delta L > 10; + * false: only chroma correction only + * bool gamut : performs gamutLch + * 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 ) { +#ifdef _DEBUG + MyTime t1e,t2e; + t1e.set(); + int negat=0, moreRGB=0; + MunsellDebugInfo* MunsDebugInfo=NULL; + if (corMunsell) + MunsDebugInfo = new MunsellDebugInfo(); +#endif + float correctlum = 0.f; + float correctionHuechroma = 0.f; +#ifdef __SSE2__ + // precalculate H and C using SSE + float HHBuffer[N]; + float CCBuffer[N]; + __m128 c327d68v = _mm_set1_ps(327.68f); + __m128 av,bv; + int k; + for (k=0; kverbose) { + printf("Color::LabGamutMunsell (correction performed in %d usec):\n", t2e.etime(t1e)); + printf(" Gamut : G1negat=%iiter G165535=%iiter \n",negat,moreRGB); + if (MunsDebugInfo) { + printf(" Munsell chrominance: MaxBP=%1.2frad MaxRY=%1.2frad MaxGY=%1.2frad MaxRP=%1.2frad depass=%i\n", MunsDebugInfo->maxdhue[0], MunsDebugInfo->maxdhue[1], MunsDebugInfo->maxdhue[2], MunsDebugInfo->maxdhue[3], MunsDebugInfo->depass); + printf(" Munsell luminance : MaxBP=%1.2frad MaxRY=%1.2frad MaxGY=%1.2frad MaxRP=%1.2frad depass=%i\n", MunsDebugInfo->maxdhuelum[0] ,MunsDebugInfo->maxdhuelum[1], MunsDebugInfo->maxdhuelum[2], MunsDebugInfo->maxdhuelum[3], MunsDebugInfo->depassLum); + } + else { + printf(" Munsell correction wasn't requested\n"); + } + } + if (MunsDebugInfo) + delete MunsDebugInfo; +#endif + + } + + /* + * MunsellLch correction + * Copyright (c) 2012 Jacques Desmis + * + * Find the right LUT and calculate the correction + */ + void Color::MunsellLch (float lum, float hue, float chrom, float memChprov, float &correction, int zone, float &lbe, bool &correctL) { + + int x = int(memChprov); + int y = int(chrom); + + //begin PB correction + sky + if(zone==1) { + if(lum > 5.0) { + if(lum <15.0) { + if( (hue >= (_15PB10[x] - 0.035)) && (hue < (_15PB10[x] + 0.052) && x<=45)) {if(y>49) y=49;correction = _15PB10[y] - _15PB10[x] ;lbe=_15PB10[y];correctL=true;} + else if (( hue>=( _3PB10[x] -0.052)) && (hue < (_45PB10[x] + _3PB10[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _3PB10[y] - _3PB10[x]; lbe =_3PB10[y];correctL=true;} + else if (( hue>=(_45PB10[x] + _3PB10[x])/2.0) && (hue < (_45PB10[x] +0.052)) && x <= 85) {if(y>89) y=89;correction = _45PB10[y] - _45PB10[x] ;lbe=_45PB10[y];correctL=true;} + else if (( hue>=(_6PB10[x] -0.052) && (hue < (_6PB10[x] + _75PB10[x])/2.0))) {correction = _6PB10[y] - _6PB10[x] ;lbe=_6PB10[y];correctL=true;} + else if (( hue>=(_6PB10[x] + _75PB10[x])/2.0) && (hue < (_9PB10[x] + _75PB10[x])/2.0)) {correction = _75PB10[y] - _75PB10[x] ;lbe=_75PB10[y];correctL=true;} + else if (( hue>=(_9PB10[x] + _75PB10[x])/2.0) && (hue < (_9PB10[x] + _10PB10[x])/2.0)) {correction = _9PB10[y] - _9PB10[x] ; lbe=_9PB10[y];correctL=true;} + else if (( hue>=(_10PB10[x] + _9PB10[x])/2.0) && (hue < (_1P10[x] + _10PB10[x])/2.0)) {correction = _10PB10[y] - _10PB10[x] ;lbe=_10PB10[y];correctL=true;} + else if (( hue>=(_10PB10[x] + _1P10[x])/2.0) && (hue < (_1P10[x] + _4P10[x])/2.0)) {correction = _1P10[y] - _1P10[x];lbe=_1P10[y];correctL=true;} + else if (( hue>=(_1P10[x] + _4P10[x])/2.0) && (hue < (0.035 + _4P10[x])/2.0)) {correction = _4P10[y] - _4P10[x] ;lbe=_4P10[y];correctL=true;} + } + else if (lum <25.0) { + if( (hue >= (_15PB20[x] - 0.035)) && (hue < (_15PB20[x] + _3PB20[x])/2.0) && x<=85) {if(y>89) y=89;correction = _15PB20[y] - _15PB20[x] ;lbe= _15PB20[y];correctL=true;} + else if (( hue>=(_15PB20[x] + _3PB20[x])/2.0) && (hue < (_45PB20[x] + _3PB20[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _3PB20[y] - _3PB20[x] ;lbe= _3PB20[y];correctL=true;} + else if (( hue>=(_45PB20[x] + _3PB20[x])/2.0) && (hue < ( _45PB20[x] + 0.052)) && x <= 85) {if(y>89) y=89;correction = _45PB20[y] - _45PB20[x] ;lbe=_45PB20[y];correctL=true;} + else if (( hue>=(_45PB20[x] + 0.052)) && (hue < (_6PB20[x] + _75PB20[x])/2.0)) {correction = _6PB20[y] - _6PB20[x];lbe=_6PB20[y];correctL=true;} + else if (( hue>=(_6PB20[x] + _75PB20[x])/2.0) && (hue < (_9PB20[x] + _75PB20[x])/2.0)) {correction = _75PB20[y] - _75PB20[x] ;lbe=_75PB20[y];correctL=true;} + else if (( hue>=(_9PB20[x] + _75PB20[x])/2.0) && (hue < (_9PB20[x] + _10PB20[x])/2.0)) {correction = _9PB20[y] - _9PB20[x] ;lbe= _9PB20[y];correctL=true; } + else if (( hue>=(_10PB20[x] + _9PB20[x])/2.0) && (hue < (_1P20[x] + _10PB20[x])/2.0)) {correction = _10PB20[y] - _10PB20[x] ;lbe= _10PB20[y];correctL=true;} + else if (( hue>=(_10PB20[x] + _1P20[x])/2.0) && (hue < (_1P20[x] + _4P20[x])/2.0)) {correction = _1P20[y] - _1P20[x] ; lbe=_1P20[y];correctL=true;} + else if (( hue>=(_1P20[x] + _4P20[x])/2.0) && (hue < (0.035 + _4P20[x])/2.0)) {correction = _4P20[y] - _4P20[x] ; lbe=_4P20[y];correctL=true;} + } + else if (lum <35.0) { + if( (hue >= (_15PB30[x] - 0.035)) && (hue < (_15PB30[x] + _3PB30[x])/2.0) && x<=85 ) {if(y>89) y=89;correction = _15PB30[y] - _15PB30[x] ;lbe=_15PB30[y];correctL=true;} + else if (( hue>=(_15PB30[x] + _3PB30[x])/2.0) && (hue < (_45PB30[x] + _3PB30[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _3PB30[y] - _3PB30[x] ;lbe=_3PB30[y];correctL=true;} + else if (( hue>=(_45PB30[x] + _3PB30[x])/2.0) && (hue < (_45PB30[x]+0.052)) && x <= 85) {if(y>89) y=89;correction = _45PB30[y] - _45PB30[x] ;lbe= _45PB30[y];correctL=true;} + else if (( hue>=( _45PB30[x]+ 0.052)) && (hue < (_6PB30[x] + _75PB30[x])/2.0)) {correction = _6PB30[y] - _6PB30[x] ; lbe=_6PB30[y];correctL=true;} + else if (( hue>=(_6PB30[x] + _75PB30[x])/2.0) && (hue < (_9PB30[x] + _75PB30[x])/2.0)) {correction = _75PB30[y] - _75PB30[x] ;lbe= _75PB30[y] ;correctL=true;} + else if (( hue>=(_9PB30[x] + _75PB30[x])/2.0) && (hue < (_9PB30[x] + _10PB30[x])/2.0)) {correction = _9PB30[y] - _9PB30[x] ;lbe=_9PB30[y]; correctL=true;} + else if (( hue>=(_10PB30[x] + _9PB30[x])/2.0) && (hue < (_1P30[x] + _10PB30[x])/2.0)) {correction = _10PB30[y] - _10PB30[x] ;lbe=_10PB30[y];correctL=true;} + else if (( hue>=(_10PB30[x] + _1P30[x])/2.0) && (hue < (_1P30[x] + _4P30[x])/2.0)) {correction = _1P30[y] - _1P30[x] ;lbe=_1P30[y];correctL=true; } + else if (( hue>=(_1P30[x] + _4P30[x])/2.0) && (hue < (0.035 + _4P30[x])/2.0)) {correction = _4P30[y] - _4P30[x] ;lbe=_4P30[y];correctL=true;} + } + else if (lum <45.0) { + if( (hue <= (_05PB40[x] + _15PB40[x])/2.0) && (hue > (_05PB40[x] + _10B40[x])/2.0) && x<75 ) {if(y>75) y=75; correction = _05PB40[y] - _05PB40[x] ;lbe=_05PB40[y];correctL=true;} + else if( (hue <= (_05PB40[x] + _10B40[x])/2.0) && (hue >(_10B40[x] + _9B40[x])/2.0) && x<70 ) {if(y>70) y=70;correction = _10B40[y] - _10B40[x] ;lbe=_10B40[y];correctL=true;} + else if( (hue <= (_10B40[x] + _9B40[x])/2.0) && (hue >(_9B40[x] + _7B40[x])/2.0) && x<70 ) {if(y>70) y=70;correction = _9B40[y] - _9B40[x] ;lbe=_9B40[y];correctL=true;} + else if( (hue <= (_9B40[x] + _7B40[x])/2.0) && (hue >(_5B40[x] + _7B40[x])/2.0) && x<70 ) {if(y>70) y=70;correction = _7B40[y] - _7B40[x] ;lbe= _7B40[y];correctL=true;} + else if (( hue<=(_5B40[x] + _7B40[x])/2.0) && (hue > (_5B40[x]-0.035)) && x < 70) {if(y>70) y=70; correction = _5B40[y] - _5B40[x] ;lbe= _5B40[y];correctL=true;} // + + else if( (hue >= (_15PB40[x] - 0.035)) && (hue < (_15PB40[x] + _3PB40[x])/2.0) && x<=85 ) {if(y>89) y=89;correction = _15PB40[y] - _15PB40[x] ; lbe= _15PB40[y];correctL=true;} + else if (( hue>=(_15PB40[x] + _3PB40[x])/2.0) && (hue < (_45PB40[x] + _3PB40[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _3PB40[y] - _3PB40[x] ;lbe=_3PB40[y];correctL=true;} + else if (( hue>=(_45PB40[x] + _3PB40[x])/2.0) && (hue < (_45PB40[x]+0.052)) && x <= 85) {if(y>89) y=89;correction = _45PB40[y] - _45PB40[x] ;lbe=_45PB40[y] ;correctL=true;} + else if (( hue>=(_45PB40[x]+0.052)) && (hue < (_6PB40[x] + _75PB40[x])/2.0)) {correction = _6PB40[y] - _6PB40[x] ;lbe=_6PB40[y];correctL=true; } + else if (( hue>=(_6PB40[x] + _75PB40[x])/2.0) && (hue < (_9PB40[x] + _75PB40[x])/2.0)) {correction = _75PB40[y] - _75PB40[x] ; lbe=_75PB40[y];correctL=true;} + else if (( hue>=(_9PB40[x] + _75PB40[x])/2.0) && (hue < (_9PB40[x] + _10PB40[x])/2.0)) {correction = _9PB40[y] - _9PB40[x] ;lbe= _9PB40[y]; correctL=true;} + else if (( hue>=(_10PB40[x] + _9PB40[x])/2.0) && (hue < (_1P40[x] + _10PB40[x])/2.0)) {correction = _10PB40[y] - _10PB40[x] ;lbe=_10PB40[y];correctL=true;} + else if (( hue>=(_10PB40[x] + _1P40[x])/2.0) && (hue < (_1P40[x] + _4P40[x])/2.0)) {correction = _1P40[y] - _1P40[x] ;lbe=_1P40[y];correctL=true;} + else if (( hue>=(_1P40[x] + _4P40[x])/2.0) && (hue < (0.035 + _4P40[x])/2.0)) {correction = _4P40[y] - _4P40[x] ;lbe= _4P40[y];correctL=true;} + } + else if (lum <55.0) { + if( (hue <= (_05PB50[x] + _15PB50[x])/2.0) && (hue > (_05PB50[x] + _10B50[x])/2.0) && x<79 ) {if(y>79) y=79; correction = _05PB50[y] - _05PB50[x] ;lbe= _05PB50[y];correctL=true;} + else if( (hue <= (_05PB50[x] + _10B50[x])/2.0) && (hue >(_10B50[x] + _9B50[x])/2.0) && x<79 ) {if(y>79) y=79;correction = _10B50[y] - _10B50[x] ;lbe=_10B50[y];correctL=true;} + else if( (hue <= (_10B50[x] + _9B50[x])/2.0) && (hue >(_9B50[x] + _7B50[x])/2.0) && x<79 ) {if(y>79) y=79;correction = _9B50[y] - _9B50[x] ;lbe=_9B50[y];correctL=true;} + else if( (hue <= (_9B50[x] + _7B50[x])/2.0) && (hue >(_5B50[x] + _7B50[x])/2.0) && x<79 ) {if(y>79) y=79;correction = _7B50[y] - _7B50[x] ;lbe=_7B50[y];correctL=true;} + else if (( hue<=(_5B50[x] + _7B50[x])/2.0) && (hue > (_5B50[x]-0.035)) && x < 79) {if(y>79) y=79; correction = _5B50[y] - _5B50[x] ;lbe=_5B50[y];correctL=true; } // + + else if( (hue >= (_15PB50[x] - 0.035)) && (hue < (_15PB50[x] + _3PB50[x])/2.0) && x<=85 ) {if(y>89) y=89;correction = _15PB50[y] - _15PB50[x] ; lbe= _15PB50[y];correctL=true;} + else if (( hue>=(_15PB50[x] + _3PB50[x])/2.0) && (hue < (_45PB50[x] + _3PB50[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _3PB50[y] - _3PB50[x] ;lbe=_3PB50[y];correctL=true;} + else if (( hue>=(_45PB50[x] + _3PB50[x])/2.0) && (hue < (_6PB50[x] + _45PB50[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _45PB50[y] - _45PB50[x] ;lbe=_45PB50[y];correctL=true; } + else if (( hue>=(_6PB50[x] + _45PB50[x])/2.0) && (hue < (_6PB50[x] + _75PB50[x])/2.0) && x <=85) {if(y>89) y=89;correction = _6PB50[y] - _6PB50[x] ;lbe=_6PB50[y];correctL=true;} + else if (( hue>=(_6PB50[x] + _75PB50[x])/2.0) && (hue < (_9PB50[x] + _75PB50[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _75PB50[y] - _75PB50[x] ;lbe=_75PB50[y];correctL=true;} + else if (( hue>=(_9PB50[x] + _75PB50[x])/2.0) && (hue < (_9PB50[x] + _10PB50[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _9PB50[y] - _9PB50[x] ;lbe=_9PB50[y];correctL=true;} + else if (( hue>=(_10PB50[x] + _9PB50[x])/2.0) && (hue < (_1P50[x] + _10PB50[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _10PB50[y] - _10PB50[x] ;lbe=_10PB50[y];correctL=true;} + else if (( hue>=(_10PB50[x] + _1P50[x])/2.0) && (hue < (_1P50[x] + _4P50[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _1P50[y] - _1P50[x] ;lbe=_1P50[y];correctL=true; } + else if (( hue>=(_1P50[x] + _4P50[x])/2.0) && (hue < (0.035 + _4P50[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _4P50[y] - _4P50[x] ;lbe=_4P50[y];correctL=true;} + } + else if (lum <65.0) { + if( (hue <= (_05PB60[x] + _15PB60[x])/2.0) && (hue > (_05PB60[x] + _10B60[x])/2.0) && x<79 ) {if(y>79) y=79; correction = _05PB60[y] - _05PB60[x] ;lbe=_05PB60[y];correctL=true;} + else if( (hue <= (_05PB60[x] + _10B60[x])/2.0) && (hue >(_10B60[x] + _9B60[x])/2.0) && x<79 ) {if(y>79) y=79;correction = _10B60[y] - _10B60[x] ;lbe= _10B60[y];correctL=true;} + else if( (hue <= (_10B60[x] + _9B60[x])/2.0) && (hue >(_9B60[x] + _7B60[x])/2.0) && x<79 ) {if(y>79) y=79;correction = _9B60[y] - _9B60[x] ;lbe=_9B60[y];correctL=true;} + else if( (hue <= (_9B60[x] + _7B60[x])/2.0) && (hue >(_5B60[x] + _7B60[x])/2.0) && x<79 ) {if(y>79) y=79;correction = _7B60[y] - _7B60[x] ;lbe= _7B60[y];correctL=true;} + else if (( hue<=(_5B60[x] + _7B60[x])/2.0) && (hue > (_5B60[x]-0.035)) && x < 79) {if(y>79) y=79; correction = _5B60[y] - _5B60[x] ;lbe= _5B60[y];correctL=true;} // + + else if( (hue >= (_15PB60[x] - 0.035)) && (hue < (_15PB60[x] + _3PB60[x])/2.0) && x<=85 ) {if(y>89) y=89;correction = _15PB60[y] - _15PB60[x] ;lbe=_15PB60[y];correctL=true; } + else if (( hue>=(_15PB60[x] + _3PB60[x])/2.0) && (hue < (_45PB60[x] + _3PB60[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _3PB60[y] - _3PB60[x] ;lbe=_3PB60[y];correctL=true;} + else if (( hue>=(_45PB60[x] + _3PB60[x])/2.0) && (hue < (_6PB60[x] + _45PB60[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _45PB60[y] - _45PB60[x] ;lbe=_45PB60[y];correctL=true;} + else if (( hue>=(_6PB60[x] + _45PB60[x])/2.0) && (hue < (_6PB60[x] + _75PB60[x])/2.0) && x <=85) {if(y>89) y=89;correction = _6PB60[y] - _6PB60[x] ;lbe= _6PB60[y];correctL=true;} + else if (( hue>=(_6PB60[x] + _75PB60[x])/2.0) && (hue < (_9PB60[x] + _75PB60[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _75PB60[y] - _75PB60[x] ;lbe= _75PB60[y];correctL=true;} + else if (( hue>=(_9PB60[x] + _75PB60[x])/2.0) && (hue < (_9PB60[x] + _10PB60[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _9PB60[y] - _9PB60[x] ;lbe= _9PB60[y];correctL=true;} + else if (( hue>=(_10PB60[x] + _9PB60[x])/2.0) && (hue < (_1P60[x] + _10PB60[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _10PB60[y] - _10PB60[x] ;lbe=_10PB60[y]; correctL=true;} + else if (( hue>=(_10PB60[x] + _1P60[x])/2.0) && (hue < (_1P60[x] + _4P60[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _1P60[y] - _1P60[x] ; lbe= _1P60[y];correctL=true;} + else if (( hue>=(_1P60[x] + _4P60[x])/2.0) && (hue < (0.035 + _4P60[x])/2.0) && x <= 85) {if(y>89) y=89;correction = _4P60[y] - _4P60[x] ;lbe=_4P60[y];correctL=true; } + } + else if (lum < 75.0) { + if( (hue <= (_05PB70[x] + _15PB70[x])/2.0) && (hue > (_05PB70[x] + _10B70[x])/2.0) && x<50 ) {if(y>49) y=49; correction = _05PB70[y] - _05PB70[x] ;lbe=_05PB70[y];correctL=true;} + else if( (hue <= (_05PB70[x] + _10B70[x])/2.0) && (hue >(_10B70[x] + _9B70[x])/2.0) && x<50 ) {if(y>49) y=49;correction = _10B70[y] - _10B70[x] ;lbe=_10B70[y];correctL=true;} + else if( (hue <= (_10B70[x] + _9B70[x])/2.0) && (hue >(_9B70[x] + _7B70[x])/2.0) && x<50 ) {if(y>49) y=49;correction = _9B70[y] - _9B70[x] ;lbe= _9B70[y];correctL=true;} + else if( (hue <= (_9B70[x] + _7B70[x])/2.0) && (hue >(_5B70[x] + _7B70[x])/2.0) && x<50 ) {if(y>49) y=49;correction = _7B70[y] - _7B70[x] ;lbe=_7B70[y];correctL=true;} + else if (( hue<=(_5B70[x] + _7B70[x])/2.0) && (hue > (_5B70[x]-0.035)) && x < 50) {if(y>49) y=49; correction = _5B70[y] - _5B70[x] ;lbe= _5B70[y];correctL=true;} // + + else if( (hue >= (_15PB70[x] - 0.035)) && (hue < (_15PB70[x] + _3PB70[x])/2.0) && x<50 ) {if(y>49) y=49;correction = _15PB70[y] - _15PB70[x] ;lbe=_15PB70[y];correctL=true; } + else if (( hue>=(_45PB70[x] + _3PB70[x])/2.0) && (hue < (_6PB70[x] + _45PB70[x])/2.0) && x < 50) {if(y>49) y=49;correction = _45PB70[y] - _45PB70[x] ;lbe=_45PB70[y];correctL=true;} + else if (( hue>=(_6PB70[x] + _45PB70[x])/2.0) && (hue < (_6PB70[x] + _75PB70[x])/2.0) && x <50) {if(y>49) y=49;correction = _6PB70[y] - _6PB70[x] ;lbe=_6PB70[y];correctL=true;} + else if (( hue>=(_6PB70[x] + _75PB70[x])/2.0) && (hue < (_9PB70[x] + _75PB70[x])/2.0) && x <50) {if(y>49) y=49;correction = _75PB70[y] - _75PB70[x] ;lbe=_75PB70[y];correctL=true; } + else if (( hue>=(_9PB70[x] + _75PB70[x])/2.0) && (hue < (_9PB70[x] + 0.035)) && x <50) {if(y>49) y=49;correction = _9PB70[y] - _9PB70[x] ;lbe=_9PB70[y];correctL=true;} + } + else if (lum < 85.0) { + if( (hue <= (_05PB80[x] + _15PB80[x])/2.0) && (hue > (_05PB80[x] + _10B80[x])/2.0) && x<40 ) {if(y>39) y=39; correction = _05PB80[y] - _05PB80[x] ;lbe=_05PB80[y] ;correctL=true;} + else if( (hue <= (_05PB80[x] + _10B80[x])/2.0) && (hue >(_10B80[x] + _9B80[x])/2.0) && x<40 ) {if(y>39) y=39;correction = _10B80[y] - _10B80[x] ;lbe=_10B80[y];correctL=true;} + else if( (hue <= (_10B80[x] + _9B80[x])/2.0) && (hue >(_9B80[x] + _7B80[x])/2.0) && x<40 ) {if(y>39) y=39;correction = _9B80[y] - _9B80[x] ;lbe= _9B80[y];correctL=true;} + else if( (hue <= (_9B80[x] + _7B80[x])/2.0) && (hue >(_5B80[x] + _7B80[x])/2.0) && x<50 ) {if(y>49) y=49;correction = _7B80[y] - _7B80[x] ;lbe=_7B80[y];correctL=true;} + else if (( hue<=(_5B80[x] + _7B80[x])/2.0) && (hue > (_5B80[x]-0.035)) && x < 50) {if(y>49) y=49; correction = _5B80[y] - _5B80[x] ; lbe=_5B80[y];correctL=true;} // + + else if( (hue >= (_15PB80[x] - 0.035)) && (hue < (_15PB80[x] + _3PB80[x])/2.0) && x<50 ) {if(y>49) y=49;correction = _15PB80[y] - _15PB80[x] ; lbe=_15PB80[y];correctL=true;} + else if (( hue>=(_45PB80[x] + _3PB80[x])/2.0) && (hue < (_6PB80[x] + _45PB80[x])/2.0) && x < 50) {if(y>49) y=49;correction = _45PB80[y] - _45PB80[x] ;lbe= _45PB80[y];correctL=true;} + else if (( hue>=(_6PB80[x] + _45PB80[x])/2.0) && (hue < (_6PB80[x] + _75PB80[x])/2.0) && x <50) {if(y>49) y=49;correction = _6PB80[y] - _6PB80[x] ;lbe=_6PB80[y];correctL=true;} + else if (( hue>=(_6PB80[x] + _75PB80[x])/2.0) && (hue < (_9PB80[x] + _75PB80[x])/2.0) && x <50) {if(y>49) y=49;correction = _75PB80[y] - _75PB80[x] ;lbe=_75PB80[y];correctL=true; } + else if (( hue>=(_9PB80[x] + _75PB80[x])/2.0) && (hue < (_9PB80[x] + 0.035)) && x <50) {if(y>49) y=49;correction = _9PB80[y] - _9PB80[x] ;lbe=_9PB80[y]; correctL=true;} + } + } + } + // end PB correction + + //red yellow correction + else if(zone==2) { + if(lum > 15.0) { + if(lum < 25.0) { + if( (hue <= (_10YR20[x] + 0.035)) && (hue > (_10YR20[x] + _85YR20[x])/2.0) && x<=45) {if(y>49) y=49;correction = _10YR20[y] - _10YR20[x] ;lbe=_10YR20[y];correctL=true;} + else if (( hue<=(_85YR20[x] + _10YR20[x])/2.0) && (hue > (_85YR20[x] + 0.035) && x <= 45)) {if(y>49) y=49;correction = _85YR20[y] - _85YR20[x] ;lbe= _85YR20[y];correctL=true;} + } + else if (lum <35.0) { + if( (hue <= (_10YR30[x] + 0.035)) && (hue > (_10YR30[x] + _85YR30[x])/2.0) && x < 85) {if(y>89) y=89;correction = _10YR30[y] - _10YR30[x] ;lbe=_10YR30[y];correctL=true;} + else if( (hue <= (_10YR30[x] + _85YR30[x])/2.0) && (hue >(_85YR30[x] + _7YR30[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _85YR30[y] - _85YR30[x] ;lbe= _85YR30[y];correctL=true;} + else if (( hue<=(_85YR30[x] + _7YR30[x])/2.0) && (hue > (_7YR30[x] + _55YR30[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _7YR30[y] - _7YR30[x] ;lbe=_7YR30[y];correctL=true;} + else if (( hue<=(_7YR30[x] + _55YR30[x])/2.0) && (hue > (_55YR30[x] + _4YR30[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _55YR30[y] - _55YR30[x] ;lbe=_55YR30[y];correctL=true; } + else if (( hue<=(_55YR30[x] + _4YR30[x])/2.0) && (hue > (_4YR30[x] + _25YR30[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _4YR30[y] - _4YR30[x] ;lbe= _4YR30[y];correctL=true;} + else if (( hue<=(_4YR30[x] + _25YR30[x])/2.0) && (hue > (_25YR30[x] + _10R30[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _25YR30[y] - _25YR30[x] ;lbe=_25YR30[y];correctL=true;} + else if (( hue<=(_25YR30[x] + _10R30[x])/2.0) && (hue > (_10R30[x] + _9R30[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _10R30[y] - _10R30[x] ; lbe=_10R30[y];correctL=true;} + else if (( hue<=(_10R30[x] + _9R30[x])/2.0) && (hue > (_9R30[x] + _7R30[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _9R30[y] - _9R30[x] ;lbe=_9R30[y];correctL=true;} + else if (( hue<=(_9R30[x] + _7R30[x])/2.0) && (hue > (_7R30[x] -0.035))&& x < 85) {if(y>89) y=89;correction = _7R30[y] - _7R30[x] ; lbe=_7R30[y] ;correctL=true;} + } + else if (lum <45.0) { + if( (hue <= (_10YR40[x] + 0.035)) && (hue > (_10YR40[x] + _85YR40[x])/2.0)&& x<85) {if(y>89) y=89;correction = _10YR40[y] - _10YR40[x] ;lbe=_10YR40[y];correctL=true;} + else if( (hue <= (_10YR40[x] + _85YR40[x])/2.0) && (hue >(_85YR40[x] + _7YR40[x])/2.0)&& x < 85 ) {if(y>89) y=89;correction = _85YR40[y] - _85YR40[x] ;lbe= _85YR40[y];correctL=true;} + else if (( hue<=(_85YR40[x] + _7YR40[x])/2.0) && (hue > (_7YR40[x] + _55YR40[x])/2.0) && x < 85) {if(y>89) y=89;correction = _7YR40[y] - _7YR40[x] ;lbe= _7YR40[y];correctL=true;} + else if (( hue<=(_7YR40[x] + _55YR40[x])/2.0) && (hue > (_55YR40[x] + _4YR40[x])/2.0)&& x < 85 ) {if(y>89) y=89;correction = _55YR40[y] - _55YR40[x] ;lbe=_55YR40[y];correctL=true; } + else if (( hue<=(_55YR40[x] + _4YR40[x])/2.0) && (hue > (_4YR40[x] + _25YR40[x])/2.0)&& x < 85 ) {if(y>89) y=89;correction = _4YR40[y] - _4YR40[x] ;lbe=_4YR40[y]; correctL=true;} + else if (( hue<=(_4YR40[x] + _25YR40[x])/2.0) && (hue > (_25YR40[x] + _10R40[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _25YR40[y] - _25YR40[x] ;lbe=_25YR40[y] ;correctL=true;} + else if (( hue<=(_25YR40[x] + _10R40[x])/2.0) && (hue > (_10R40[x] + _9R40[x])/2.0) && x < 85) {if(y>89) y=89;correction = _10R40[y] - _10R40[x] ; lbe=_10R40[y];correctL=true;} + else if (( hue<=(_10R40[x] + _9R40[x])/2.0) && (hue > (_9R40[x] + _7R40[x])/2.0)&& x < 85 ) {if(y>89) y=89;correction = _9R40[y] - _9R40[x] ;lbe=_9R40[y];correctL=true;} + else if (( hue<=(_9R40[x] + _7R40[x])/2.0) && (hue > (_7R40[x] -0.035))&& x < 85 ) {if(y>89) y=89;correction = _7R40[y] - _7R40[x] ; lbe=_7R40[y];correctL=true;} + } + else if (lum <55.0) { + if( (hue <= (_10YR50[x] + 0.035)) && (hue > (_10YR50[x] + _85YR50[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _10YR50[y] - _10YR50[x] ;lbe=_10YR50[y];correctL=true;} + else if( (hue <= (_10YR50[x] + _85YR50[x])/2.0) && (hue >(_85YR50[x] + _7YR50[x])/2.0)&& x < 85 ) {if(y>89) y=89;correction = _85YR50[y] - _85YR50[x] ;lbe=_85YR50[y];correctL=true;} + else if (( hue<=(_85YR50[x] + _7YR50[x])/2.0) && (hue > (_7YR50[x] + _55YR50[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _7YR50[y] - _7YR50[x] ;lbe=_7YR50[y];correctL=true;} + else if (( hue<=(_7YR50[x] + _55YR50[x])/2.0) && (hue > (_55YR50[x] + _4YR50[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _55YR50[y] - _55YR50[x] ; lbe=_55YR50[y];correctL=true;} + else if (( hue<=(_55YR50[x] + _4YR50[x])/2.0) && (hue > (_4YR50[x] + _25YR50[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _4YR50[y] - _4YR50[x] ;lbe=_4YR50[y]; correctL=true;} + else if (( hue<=(_4YR50[x] + _25YR50[x])/2.0) && (hue > (_25YR50[x] + _10R50[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _25YR50[y] - _25YR50[x] ;lbe=_25YR50[y];correctL=true;} + else if (( hue<=(_25YR50[x] + _10R50[x])/2.0) && (hue > (_10R50[x] + _9R50[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _10R50[y] - _10R50[x] ;lbe= _10R50[y]; correctL=true;} + else if (( hue<=(_10R50[x] + _9R50[x])/2.0) && (hue > (_9R50[x] + _7R50[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _9R50[y] - _9R50[x] ;lbe=_9R50[y];correctL=true;} + else if (( hue<=(_9R50[x] + _7R50[x])/2.0) && (hue > (_7R50[x] -0.035))&& x < 85) {if(y>89) y=89;correction = _7R50[y] - _7R50[x] ; lbe=_7R50[y];correctL=true;} + } + else if (lum <65.0) { + if( (hue <= (_10YR60[x] + 0.035)) && (hue > (_10YR60[x] + _85YR60[x])/2.0)) {;correction = _10YR60[y] - _10YR60[x] ;lbe= _10YR60[y];correctL=true;} + else if( (hue <= (_10YR60[x] + _85YR60[x])/2.0) && (hue >(_85YR60[x] + _7YR60[x])/2.0) ) {;correction = _85YR60[y] - _85YR60[x] ;lbe= _85YR60[y];correctL=true;} + else if (( hue<=(_85YR60[x] + _7YR60[x])/2.0) && (hue > (_7YR60[x] + _55YR60[x])/2.0)) {correction = _7YR60[y] - _7YR60[x] ;lbe=_7YR60[y];correctL=true;} + else if (( hue<=(_7YR60[x] + _55YR60[x])/2.0) && (hue > (_55YR60[x] + _4YR60[x])/2.0)) {correction = _55YR60[y] - _55YR60[x] ;lbe= _55YR60[y];correctL=true;} + else if (( hue<=(_55YR60[x] + _4YR60[x])/2.0) && (hue > (_4YR60[x] + _25YR60[x])/2.0)) {correction = _4YR60[y] - _4YR60[x] ;lbe=_4YR60[y]; correctL=true;} + else if (( hue<=(_4YR60[x] + _25YR60[x])/2.0) && (hue > (_25YR60[x] + _10R60[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _25YR60[y] - _25YR60[x] ;lbe=_25YR60[y];correctL=true;} + else if (( hue<=(_25YR60[x] + _10R60[x])/2.0) && (hue > (_10R60[x] + _9R60[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _10R60[y] - _10R60[x] ;lbe= _10R60[y];correctL=true; } + else if (( hue<=(_10R60[x] + _9R60[x])/2.0) && (hue > (_9R60[x] + _7R60[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _9R60[y] - _9R60[x] ;lbe=_9R60[y];correctL=true;} + else if (( hue<=(_9R60[x] + _7R60[x])/2.0) && (hue > (_7R60[x] -0.035))&& x < 85) {if(y>89) y=89;correction = _7R60[y] - _7R60[x] ;lbe=_7R60[y]; correctL=true;} + } + else if (lum <75.0) { + if( (hue <= (_10YR70[x] + 0.035)) && (hue > (_10YR70[x] + _85YR70[x])/2.0)) {correction = _10YR70[y] - _10YR70[x] ;lbe= _10YR70[y];correctL=true;} + else if( (hue <= (_10YR70[x] + _85YR70[x])/2.0) && (hue >(_85YR70[x] + _7YR70[x])/2.0)) {correction = _85YR70[y] - _85YR70[x] ;lbe=_85YR70[y];correctL=true;} + if (( hue<=(_85YR70[x] + _7YR70[x])/2.0) && (hue > (_7YR70[x] + _55YR70[x])/2.0)) {correction = _7YR70[y] - _7YR70[x] ;lbe=_7YR70[y];correctL=true;} + else if (( hue<=(_7YR70[x] + _55YR70[x])/2.0) && (hue > (_55YR70[x] + _4YR70[x])/2.0)) {correction = _55YR70[y] - _55YR70[x] ;lbe=_55YR70[y];correctL=true; } + else if (( hue<=(_55YR70[x] + _4YR70[x])/2.0) && (hue > (_4YR70[x] + _25YR70[x])/2.0)) {correction = _4YR70[y] - _4YR70[x] ;lbe=_4YR70[y];correctL=true; } + else if (( hue<=(_4YR70[x] + _25YR70[x])/2.0) && (hue > (_25YR70[x] + _10R70[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _25YR70[y] - _25YR70[x] ;lbe= _25YR70[y];correctL=true;} + else if (( hue<=(_25YR70[x] + _10R70[x])/2.0) && (hue > (_10R70[x] + _9R70[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _10R70[y] - _10R70[x] ;lbe= _10R70[y];correctL=true;} + else if (( hue<=(_10R70[x] + _9R70[x])/2.0) && (hue > (_9R70[x] + _7R70[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _9R70[y] - _9R70[x] ;lbe= _9R70[y] ;correctL=true;} + else if (( hue<=(_9R70[x] + _7R70[x])/2.0) && (hue > (_7R70[x] -0.035))&& x < 85) {if(y>89) y=89;correction = _7R70[y] - _7R70[x] ;lbe=_7R70[y];correctL=true; } + } + else if (lum <85.0) { + if( (hue <= (_10YR80[x] + 0.035)) && (hue > (_10YR80[x] + _85YR80[x])/2.0)) {correction = _10YR80[y] - _10YR80[x] ;lbe=_10YR80[y];correctL=true;} + else if( (hue <= (_10YR80[x] + _85YR80[x])/2.0) && (hue >(_85YR80[x] + _7YR80[x])/2.0)) {correction = _85YR80[y] - _85YR80[x] ;lbe= _85YR80[y];} + else if (( hue<=(_85YR80[x] + _7YR80[x])/2.0) && (hue > (_7YR80[x] + _55YR80[x])/2.0) && x<85) {if(y>89) y=89;correction = _7YR80[y] - _7YR80[x] ;lbe=_7YR80[y];correctL=true;} + else if (( hue<=(_7YR80[x] + _55YR80[x])/2.0) && (hue > (_55YR80[x] + _4YR80[x])/2.0) && x <45) {correction = _55YR80[y] - _55YR80[x] ;lbe=_55YR80[y];correctL=true; } + else if (( hue<=(_55YR80[x] + _4YR80[x])/2.0) && (hue > (_4YR80[x] - 0.035) && x<45)) {if(y>49) y=49;correction = _4YR80[y] - _4YR80[x] ; lbe=_4YR80[y] ;correctL=true;} + } + else if (lum <95.0) { + if( (hue <= (_10YR90[x] + 0.035)) && (hue > (_10YR90[x] -0.035) && x<85)) {if(y>89) y=89;correction = _10YR90[y] - _10YR90[x] ;lbe= _10YR90[y];correctL=true;} + else if ( hue<=(_85YR90[x] + 0.035) && hue > (_85YR90[x] -0.035) && x<85) {if(y>89) y=89;correction = _85YR90[y] - _85YR90[x] ;lbe=_85YR90[y];correctL=true;} + else if (( hue<=(_55YR90[x] + 0.035) && (hue > (_55YR90[x] - 0.035) && x<45))) {if(y>49) y=49;correction = _55YR90[y] - _55YR90[x] ;lbe= _55YR90[y];correctL=true; } + } + } + } + //end red yellow + + //Green yellow correction + else if(zone==3) { + if (lum >= 25.0) { + if (lum <35.0) { + if( (hue <= (_7G30[x] + 0.035)) && (hue > (_7G30[x] + _5G30[x])/2.0) ) {correction = _7G30[y] - _7G30[x] ;lbe=_7G30[y];correctL=true;} + else if( (hue <= (_7G30[x] + _5G30[x])/2.0) && (hue >(_5G30[x] + _25G30[x])/2.0)) {correction = _5G30[y] - _5G30[x] ;lbe= _5G30[y];correctL=true;} + else if (( hue<=(_25G30[x] + _5G30[x])/2.0) && (hue > (_25G30[x] + _1G30[x])/2.0)) {correction = _25G30[y] - _25G30[x] ;lbe=_25G30[y];correctL=true;} + else if (( hue<=(_1G30[x] + _25G30[x])/2.0) && (hue > (_1G30[x] + _10GY30[x])/2.0)) {correction = _1G30[y] - _1G30[x] ;lbe= _1G30[y];correctL=true;} + else if (( hue<=(_1G30[x] + _10GY30[x])/2.0) && (hue > (_10GY30[x] + _75GY30[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _10GY30[y] - _10GY30[x] ;lbe= _10GY30[y];correctL=true;} + else if (( hue<=(_10GY30[x] + _75GY30[x])/2.0) && (hue > (_75GY30[x] + _5GY30[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _75GY30[y] - _75GY30[x] ;lbe=_75GY30[y];correctL=true;} + else if (( hue<=(_5GY30[x] + _75GY30[x])/2.0) && (hue > (_5GY30[x] -0.035))&& x < 85) {if(y>89) y=89;correction = _5GY30[y] - _5GY30[x] ;lbe= _5GY30[y] ;correctL=true; } + } + else if (lum <45.0) { + if( (hue <= (_7G40[x] + 0.035)) && (hue > (_7G40[x] + _5G40[x])/2.0) ) {correction = _7G40[y] - _7G40[x] ;lbe= _7G40[y];correctL=true;} + else if( (hue <= (_7G40[x] + _5G40[x])/2.0) && (hue >(_5G40[x] + _25G40[x])/2.0)) {correction = _5G40[y] - _5G40[x] ;lbe=_5G40[y];correctL=true;} + else if (( hue<=(_25G40[x] + _5G40[x])/2.0) && (hue > (_25G40[x] + _1G40[x])/2.0)) {correction = _25G40[y] - _25G40[x] ;lbe=_25G40[y];correctL=true;} + else if (( hue<=(_1G40[x] + _25G40[x])/2.0) && (hue > (_1G40[x] + _10GY40[x])/2.0)) {correction = _1G40[y] - _1G40[x] ;lbe=_1G40[y];correctL=true; } + else if (( hue<=(_1G40[x] + _10GY40[x])/2.0) && (hue > (_10GY40[x] + _75GY40[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _10GY40[y] - _10GY40[x] ;lbe=_10GY40[y];correctL=true; } + else if (( hue<=(_10GY40[x] + _75GY40[x])/2.0) && (hue > (_75GY40[x] + _5GY40[x])/2.0)&& x < 85) {if(y>89) y=89;correction = _75GY40[y] - _75GY40[x] ;lbe=_75GY40[y];correctL=true;} + else if (( hue<=(_5GY40[x] + _75GY40[x])/2.0) && (hue > (_5GY40[x]-0.035)) && x < 85) {if(y>89) y=89; correction = _5GY40[y] - _5GY40[x] ;lbe=_5GY40[y];correctL=true; } // + } + else if (lum <55.0) { + if( (hue <= (_7G50[x] + 0.035)) && (hue > (_7G50[x] + _5G50[x])/2.0) ) {correction = _7G50[y] - _7G50[x] ;lbe=_7G50[y];correctL=true;} + else if( (hue <= (_7G50[x] + _5G50[x])/2.0) && (hue >(_5G50[x] + _25G50[x])/2.0)) {correction = _5G50[y] - _5G50[x] ;lbe=_5G50[y];correctL=true;} + else if (( hue<=(_25G50[x] + _5G50[x])/2.0) && (hue > (_25G50[x] + _1G50[x])/2.0)) {correction = _25G50[y] - _25G50[x] ;lbe= _25G50[y];correctL=true;} + else if (( hue<=(_1G50[x] + _25G50[x])/2.0) && (hue > (_1G50[x] + _10GY50[x])/2.0)) {correction = _1G50[y] - _1G50[x] ; lbe=_1G50[y];correctL=true;} + else if (( hue<=(_1G50[x] + _10GY50[x])/2.0) && (hue > (_10GY50[x] + _75GY50[x])/2.0)) {correction = _10GY50[y] - _10GY50[x] ;lbe= _10GY50[y];correctL=true;} + else if (( hue<=(_10GY50[x] + _75GY50[x])/2.0) && (hue > (_75GY50[x] + _5GY50[x])/2.0)) {correction = _75GY50[y] - _75GY50[x] ;lbe=_75GY50[y];correctL=true;} + else if (( hue<=(_5GY50[x] + _75GY50[x])/2.0) && (hue > (_5GY50[x] -0.035))) {correction = _5GY50[y] - _5GY50[x] ; lbe=_5GY50[y];correctL=true;} + } + else if (lum <65.0) { + if( (hue <= (_7G60[x] + 0.035)) && (hue > (_7G60[x] + _5G60[x])/2.0) ) {correction = _7G60[y] - _7G60[x] ;lbe=_7G60[y];correctL=true;} + else if( (hue <= (_7G60[x] + _5G60[x])/2.0) && (hue >(_5G60[x] + _25G60[x])/2.0)) {correction = _5G60[y] - _5G60[x] ;lbe=_5G60[y];correctL=true;} + else if (( hue<=(_25G60[x] + _5G60[x])/2.0) && (hue > (_25G60[x] + _1G60[x])/2.0)) {correction = _25G60[y] - _25G60[x] ;lbe=_25G60[y];correctL=true;} + else if (( hue<=(_1G60[x] + _25G60[x])/2.0) && (hue > (_1G60[x] + _10GY60[x])/2.0)) {correction = _1G60[y] - _1G60[x] ; lbe=_1G60[y];correctL=true;} + else if (( hue<=(_1G60[x] + _10GY60[x])/2.0) && (hue > (_10GY60[x] + _75GY60[x])/2.0)) {correction = _10GY60[y] - _10GY60[x] ;lbe= _10GY60[y];correctL=true;} + else if (( hue<=(_10GY60[x] + _75GY60[x])/2.0) && (hue > (_75GY60[x] + _5GY60[x])/2.0)) {correction = _75GY60[y] - _75GY60[x] ;lbe=_75GY60[y] ;correctL=true;} + else if (( hue<=(_5GY60[x] + _75GY60[x])/2.0) && (hue > (_5GY60[x] -0.035))) {correction = _5GY60[y] - _5GY60[x] ; lbe=_5GY60[y];correctL=true;} + } + else if (lum <75.0) { + if( (hue <= (_7G70[x] + 0.035)) && (hue > (_7G70[x] + _5G70[x])/2.0) ) {correction = _7G70[y] - _7G70[x] ;lbe= _7G70[y];correctL=true;} + else if( (hue <= (_7G70[x] + _5G70[x])/2.0) && (hue >(_5G70[x] + _25G70[x])/2.0)) {correction = _5G70[y] - _5G70[x] ;lbe= _5G70[y];correctL=true;} + else if (( hue<=(_25G70[x] + _5G70[x])/2.0) && (hue > (_25G70[x] + _1G70[x])/2.0)) {correction = _25G70[y] - _25G70[x] ;lbe=_25G70[y];correctL=true;} + else if (( hue<=(_1G70[x] + _25G70[x])/2.0) && (hue > (_1G70[x] + _10GY70[x])/2.0)) {correction = _1G70[y] - _1G70[x] ;lbe= _1G70[y] ;correctL=true;} + else if (( hue<=(_1G70[x] + _10GY70[x])/2.0) && (hue > (_10GY70[x] + _75GY70[x])/2.0)) {correction = _10GY70[y] - _10GY70[x] ; lbe=_10GY70[y];correctL=true;} + else if (( hue<=(_10GY70[x] + _75GY70[x])/2.0) && (hue > (_75GY70[x] + _5GY70[x])/2.0)) {correction = _75GY70[y] - _75GY70[x] ;lbe=_75GY70[y];correctL=true;} + else if (( hue<=(_5GY70[x] + _75GY70[x])/2.0) && (hue > (_5GY70[x] -0.035))) {correction = _5GY70[y] - _5GY70[x] ;lbe= _5GY70[y];correctL=true;} + } + else if (lum <85.0) { + if( (hue <= (_7G80[x] + 0.035)) && (hue > (_7G80[x] + _5G80[x])/2.0) ) {correction = _7G80[y] - _7G80[x] ;lbe=_7G80[y];correctL=true;} + else if( (hue <= (_7G80[x] + _5G80[x])/2.0) && (hue >(_5G80[x] + _25G80[x])/2.0)) {correction = _5G80[y] - _5G80[x] ;lbe=_5G80[y];correctL=true;} + else if (( hue<=(_25G80[x] + _5G80[x])/2.0) && (hue > (_25G80[x] + _1G80[x])/2.0)) {correction = _25G80[y] - _25G80[x] ;lbe=_25G80[y];correctL=true;} + else if (( hue<=(_1G80[x] + _25G80[x])/2.0) && (hue > (_1G80[x] + _10GY80[x])/2.0)) {correction = _1G80[y] - _1G80[x] ; lbe= _1G80[y];correctL=true;} + else if (( hue<=(_1G80[x] + _10GY80[x])/2.0) && (hue > (_10GY80[x] + _75GY80[x])/2.0)) {correction = _10GY80[y] - _10GY80[x] ;lbe=_10GY80[y];correctL=true; } + else if (( hue<=(_10GY80[x] + _75GY80[x])/2.0) && (hue > (_75GY80[x] + _5GY80[x])/2.0)) {correction = _75GY80[y] - _75GY80[x] ;lbe=_75GY80[y];correctL=true;} + else if (( hue<=(_5GY80[x] + _75GY80[x])/2.0) && (hue > (_5GY80[x] -0.035))) {correction = _5GY80[y] - _5GY80[x] ; lbe=_5GY80[y];correctL=true;} + } + } + } + //end green yellow + + //Red purple correction : only for L < 30 + else if(zone==4) { + if (lum > 5.0) { + if (lum < 15.0) { + if( (hue <= (_5R10[x] + 0.035)) && (hue > (_5R10[x] - 0.043)) && x<45) {if(y>44) y=44;correction = _5R10[y] - _5R10[x] ;lbe=_5R10[y];correctL=true;} + else if( (hue <= (_25R10[x] + 0.043)) && (hue >(_25R10[x] + _10RP10[x])/2.0) && x<45 ) {if(y>44) y=44;correction = _25R10[y] - _25R10[x] ;lbe= _25R10[y];correctL=true;} + else if ( (hue <=(_25R10[x] + _10RP10[x])/2.0) && (hue > (_10RP10[x] -0.035) ) && x<45){if(y>44) y=44; correction = _10RP10[y] - _10RP10[x] ;lbe=_10RP10[y];correctL=true;} + } + else if (lum <25.0) { + if( (hue <= (_5R20[x] + 0.035)) && (hue > (_5R20[x] + _25R20[x])/2.0) && x<70 ) {if(y>70) y=70;correction = _5R20[y] - _5R20[x] ;lbe= _5R20[y];correctL=true;} + else if( (hue <= (_5R20[x] + _25R20[x])/2.0) && (hue >(_10RP20[x] + _25R20[x])/2.0) && x<70) {if(y>70) y=70;correction = _25R20[y] - _25R20[x] ;lbe=_25R20[y];correctL=true;} + else if (( hue<=(_10RP20[x] + _25R20[x])/2.0) && (hue > (_10RP20[x] -0.035)) && x<70) {if(y>70) y=70; correction = _10RP20[y] - _10RP20[x] ;lbe=_10RP20[y];correctL=true;} + } + else if (lum <35.0) { + if( (hue <= (_5R30[x] + 0.035)) && (hue > (_5R30[x] + _25R30[x])/2.0) && x<85 ) {if(y>85) y=85;correction = _5R30[y] - _5R30[x] ;lbe= _5R30[y];correctL=true;} + else if( (hue <= (_5R30[x] + _25R30[x])/2.0) && (hue >(_10RP30[x] + _25R30[x])/2.0) && x< 85) {if(y>85) y=85;correction = _25R30[y] - _25R30[x] ;lbe=_25R30[y];correctL=true;} + else if (( hue<=(_10RP30[x] + _25R30[x])/2.0) && (hue > (_10RP30[x] -0.035)) && x<85) {if(y>85) y=85; correction = _10RP30[y] - _10RP30[x] ;lbe= _10RP30[y];correctL=true;} + } + } + } + //end red purple + } + + + /* + * SkinSat + * Copyright (c)2011 Jacques Desmis + * + * skin color: mixed from NX2 skin color palette, Von Luschan, and photos of people white, + * black, yellow....there are some little exceptions...cover 99% case + * pay attention to white balance, and do not change hue and saturation, upstream of the modification + * + */ + void Color::SkinSat (float lum, float hue, float chrom, float &satreduc) { + + // to be adapted...by tests + float reduction=0.3f; // use "reduction" for "real" skin color : take into account a slightly usage of contrast and saturation in RT if option "skin" = 1 + float extendedreduction=0.4f; // use "extendedreduction" for wide area skin color, useful if not accurate colorimetry or if the user has changed hue and saturation + float extendedreduction2=0.6f; // use "extendedreduction2" for wide area for transition + + float C9=8.0, C8=15.0, C7=12.0, C4=7.0, C3=5.0, C2=5.0, C1=5.0; + float H9=0.05, H8=0.25, H7=0.1, H4=0.02, H3=0.02, H2=0.1, H1=0.1, H10=-0.2,H11=-0.2; //H10 and H11 are curious...H11=-0.8 ?? + + if (lum >= 85.f) { + if((hue > (0.78f-H9) && hue < (1.18f+H9)) && (chrom > 8.f && chrom < (14.f+C9))) satreduc=reduction; + else if (lum >= 92.f) { + if((hue > 0.8f && hue < 1.65f) && (chrom > 7.f && chrom < (15.f))) satreduc=extendedreduction; + else if ((hue > -0.1f && hue < 1.65f) && (chrom > 7.f && chrom < (18.f))) satreduc=extendedreduction2; + } + else if ((hue > 0.7f && hue < 1.4f) && (chrom > 7.f && chrom < (26.f+C9))) satreduc=extendedreduction; + else if (lum < 92.f && (hue > 0.f && hue < 1.65f) && (chrom > 7.f && chrom < (35.f+C9))) satreduc=extendedreduction2; + } + else if (lum >= 70.f) { + if((hue > 0.4f && hue < (1.04f+H8)) && (chrom > 8.f && chrom < (35.f+C8))) satreduc=reduction; + else if ((hue > (0.02f + H11) && hue < 1.5f) && (chrom > 7.0f && chrom < (48.f+C9) )) satreduc=extendedreduction; + else if ((hue > (0.02f + H11) && hue < 1.65f) && (chrom > 7.f && chrom < (55.f+C9) )) satreduc=extendedreduction2; + } + else if (lum >= 52.f) { + if((hue > 0.3f && hue < (1.27f+H7)) && (chrom > 11.f && chrom < (35.f+C7))) satreduc=reduction; + else if ((hue > (0.02f + H11) && hue < 1.5f) && (chrom > 7.0f && chrom < (48.f+C9) )) satreduc=extendedreduction; + else if ((hue > (0.02f + H11) && hue < 1.65f) && (chrom > 7.f && chrom < (55.f+C9) )) satreduc=extendedreduction2; + } + else if (lum >= 35.f) { + if((hue > 0.3f && hue < (1.25f+H4)) && (chrom > 13.f && chrom < (37.f+C4))) satreduc=reduction; + else if ((hue > (0.02f + H11) && hue < 1.5f) && (chrom > 7.0f && chrom < (48.f+C9) )) satreduc=extendedreduction; + else if ((hue > (0.02f + H11) && hue < 1.65f) && (chrom > 7.f && chrom < (55.f+C9) )) satreduc=extendedreduction2; + } + else if (lum >= 20.f) { + if((hue > 0.3f && hue < (1.2f+H3)) && (chrom > 7.f && chrom <(35.f+C3) )) satreduc=reduction; + else if ((hue > (0.02f + H11) && hue < 1.5f) && (chrom > 7.0f && chrom < (48.f+C9) )) satreduc=extendedreduction; + else if ((hue > (0.02f + H11) && hue < 1.65f) && (chrom > 7.f && chrom < (55.f+C9) )) satreduc=extendedreduction2; + } + else if (lum > 10.f) { + if((hue > (0.f + H10) && hue < (0.95f +H2)) && (chrom > 8.f && chrom < (23.f+C2))) satreduc=reduction; + else if ((hue > (0.02f+H11) && hue < 1.f) && (chrom > 7.f && chrom < (35.f+C1) )) satreduc=extendedreduction; + else if ((hue > (0.02f+H11) && hue < 1.6f) && (chrom > 7.f && chrom < (45.f+C1) )) satreduc=extendedreduction2; + } + else { + if((hue > (0.02f + H10) && hue < (0.9f+H1)) && (chrom > 8.f && chrom < (23.f+C1))) satreduc=reduction; // no data : extrapolate + else if ((hue > (0.02f+H11) && hue < 1.f) && (chrom > 7.f && chrom < (35.f+C1) )) satreduc=extendedreduction; + else if ((hue > (0.02f+H11) && hue < 1.6f) && (chrom > 7.f && chrom < (45.f+C1) )) satreduc=extendedreduction2; + + } + + } + + /* + * Munsell Lch correction + * Copyright (c) 2011 Jacques Desmis + * + * data (Munsell ==> Lab) obtained with WallKillcolor and http://www.cis.rit.edu/research/mcsl2/online/munsell.php + * each LUT give Hue in function of C, for each color Munsell and Luminance + * eg: _6PB20 : color Munsell 6PB for L=20 c=5 c=45 c=85 c=125..139 when possible: interpolation betwwen values + * no value for C<5 (gray) + * low memory footprint -- maximum: 195 LUTf * 140 values + * errors due to small number of samples in LUT and linearization are very low (1 to 2%) + * errors due to a different illuminant "Daylight" than "C" are low, about 10%. For example, a theoretical correction of 0.1 radian will be made with a real correction of 0.09 or 0.11 depending on the color illuminant D50 + * errors due to the use of a very different illuminant "C", for example illuminant "A" (tungsten) are higher, about 20%. Theoretical correction of 0.52 radians will be made with a real correction of 0.42 + */ + void Color::initMunsell () { + #ifdef _DEBUG + MyTime t1e,t2e; + t1e.set(); + #endif + + const int maxInd = 140; + const int maxInd2 = 90; + const int maxInd3 = 50; + + //blue for sky + _5B40(maxInd2); + _5B40.clear(); + for (int i=0; i5) _5B40[i] = -2.3 + 0.0025*(i-5); + else if (i<90 && i>=45) _5B40[i] = -2.2 + 0.00*(i-45); + } + //printf("5B %1.2f %1.2f\n",_5B40[44],_5B40[89]); + _5B50(maxInd2); + _5B50.clear(); + for (int i=0; i5) _5B50[i] = -2.34 + 0.0025*(i-5); + else if (i<90 && i>=45) _5B50[i] = -2.24+0.0003*(i-45); + } + //printf("5B %1.2f %1.2f\n",_5B50[44],_5B50[89]); + _5B60(maxInd2); + _5B60.clear(); + for (int i=0; i5) _5B60[i] = -2.4 + 0.003*(i-5); + else if (i<90 && i>=45) _5B60[i] = -2.28+0.0005*(i-45); + } + //printf("5B %1.2f %1.2f\n",_5B60[44],_5B60[89]); + _5B70(maxInd2); + _5B70.clear(); + for (int i=0; i5) _5B70[i] = -2.41 + 0.00275*(i-5); + else if (i<90 && i>=45) _5B70[i] = -2.30+0.00025*(i-45); + } + //printf("5B %1.2f %1.2f\n",_5B70[44],_5B70[89]); + _5B80(maxInd3); + _5B80.clear(); + for (int i=0; i5) _5B80[i] = -2.45 +0.003*(i-5); + } + //printf("5B %1.2f\n",_5B80[49]); + + _7B40(maxInd2); + _7B40.clear(); + for (int i=0; i5) _7B40[i] = -2.15 + 0.0027*(i-5); + else if (i<90 && i>=45) _7B40[i] = -2.04 + 0.00*(i-45); + } + //printf("7B %1.2f %1.2f\n",_7B40[44],_7B40[89]); + _7B50(maxInd2); + _7B50.clear(); + for (int i=0; i5) _7B50[i] = -2.20 + 0.003*(i-5); + else if (i<90 && i>=45) _7B50[i] = -2.08 + 0.001*(i-45); + } + //printf("7B %1.2f %1.2f\n",_7B50[44],_7B50[79]); + _7B60(maxInd2); + _7B60.clear(); + for (int i=0; i5) _7B60[i] = -2.26 + 0.0035*(i-5); + else if (i<90 && i>=45) _7B60[i] = -2.12 + 0.001*(i-45); + } + //printf("7B %1.2f %1.2f\n",_7B60[44],_7B60[79]); + _7B70(maxInd2); + _7B70.clear(); + for (int i=0; i5) _7B70[i] = -2.28 + 0.003*(i-5); + else if (i<90 && i>=45) _7B70[i] = -2.16 + 0.0015*(i-45); + } + //printf("7B %1.2f %1.2f\n",_7B70[44],_7B70[64]); + _7B80(maxInd3); + _7B80.clear(); + for (int i=0; i5) _7B80[i] = -2.30 +0.0028*(i-5); + } + //printf("5B %1.2f\n",_7B80[49]); + + _9B40(maxInd2); + _9B40.clear(); + for (int i=0; i5) _9B40[i] = -1.99 + 0.0022*(i-5); + else if (i<90 && i>=45) _9B40[i] = -1.90 + 0.0008*(i-45); + } + //printf("9B %1.2f %1.2f\n",_9B40[44],_9B40[69]); + _9B50(maxInd2); + _9B50.clear(); + for (int i=0; i5) _9B50[i] = -2.04 + 0.0025*(i-5); + else if (i<90 && i>=45) _9B50[i] = -1.94 + 0.0013*(i-45); + } + //printf("9B %1.2f %1.2f\n",_9B50[44],_9B50[77]); + _9B60(maxInd2); + _9B60.clear(); + for (int i=0; i5) _9B60[i] = -2.10 + 0.0033*(i-5); + else if (i<90 && i>=45) _9B60[i] = -1.97 + 0.001*(i-45); + } + //printf("9B %1.2f %1.2f\n",_9B60[44],_9B60[79]); + _9B70(maxInd2); + _9B70.clear(); + for (int i=0; i5) _9B70[i] = -2.12 + 0.003*(i-5); + else if (i<90 && i>=45) _9B70[i] = -2.00 + 0.001*(i-45); + } + //printf("9B %1.2f %1.2f\n",_9B70[44],_9B70[54]); + _9B80(maxInd3); + _9B80.clear(); + for (int i=0; i5) _9B80[i] = -2.16 +0.0025*(i-5); + } + //printf("9B %1.2f\n",_9B80[49]); + + _10B40(maxInd2); + _10B40.clear(); + for (int i=0; i5) _10B40[i] = -1.92 + 0.0022*(i-5); + else if (i<90 && i>=45) _10B40[i] = -1.83 + 0.0012*(i-45); + } + //printf("10B %1.2f %1.2f\n",_10B40[44],_10B40[76]); + _10B50(maxInd2); + _10B50.clear(); + for (int i=0; i5) _10B50[i] = -1.95 + 0.0022*(i-5); + else if (i<90 && i>=45) _10B50[i] = -1.86 + 0.0008*(i-45); + } + //printf("10B %1.2f %1.2f\n",_10B50[44],_10B50[85]); + _10B60(maxInd2); + _10B60.clear(); + for (int i=0; i5) _10B60[i] = -2.01 + 0.0027*(i-5); + else if (i<90 && i>=45) _10B60[i] = -1.90 + 0.0012*(i-45); + } + //printf("10B %1.2f %1.2f\n",_10B60[44],_10B60[70]); + _10B70(maxInd3); + _10B70.clear(); + for (int i=0; i5) _10B70[i] = -2.03 +0.0025*(i-5); + } + //printf("10B %1.2f\n",_10B70[49]); + _10B80(maxInd3); + _10B80.clear(); + for (int i=0; i5) _10B80[i] = -2.08 +0.0032*(i-5); + } + //printf("10B %1.2f\n",_10B80[39]); + + _05PB40(maxInd2); + _05PB40.clear(); + for (int i=0; i5) _05PB40[i] = -1.87 + 0.0022*(i-5); + else if (i<90 && i>=45) _05PB40[i] = -1.78 + 0.0015*(i-45); + } + //printf("05PB %1.2f %1.2f\n",_05PB40[44],_05PB40[74]); + _05PB50(maxInd2); + _05PB50.clear(); + for (int i=0; i5) _05PB50[i] = -1.91 + 0.0022*(i-5); + else if (i<90 && i>=45) _05PB50[i] = -1.82 + 0.001*(i-45); + } + //printf("05PB %1.2f %1.2f\n",_05PB50[44],_05PB50[85]); + _05PB60(maxInd2); + _05PB60.clear(); + for (int i=0; i5) _05PB60[i] = -1.96 + 0.0027*(i-5); + else if (i<90 && i>=45) _05PB60[i] = -1.85 + 0.0013*(i-45); + } + //printf("05PB %1.2f %1.2f\n",_05PB60[44],_05PB60[70]); + _05PB70(maxInd2); + _05PB70.clear(); + for (int i=0; i5) _05PB70[i] = -1.99 + 0.0027*(i-5); + else if (i<90 && i>=45) _05PB70[i] = -1.88 + 0.001*(i-45); + } + //printf("05PB %1.2f %1.2f\n",_05PB70[44],_05PB70[54]); + _05PB80(maxInd3); + _05PB80.clear(); + for (int i=0; i5) _05PB80[i] = -2.03 +0.003*(i-5); + } + //printf("05PB %1.2f\n",_05PB80[39]); + + + + //blue purple correction + //between 15PB to 4P + //maximum deviation 75PB + + //15PB + _15PB10(maxInd3); + _15PB10.clear(); + for (int i=0; i5) _15PB10[i] = -1.66 +0.0035*(i-5); + } + //printf("15 %1.2f\n",_15PB10[49]); + _15PB20(maxInd2); + _15PB20.clear(); + for (int i=0; i5) _15PB20[i] = -1.71 +0.00275*(i-5); + else if (i<90 && i>=45) _15PB20[i] = -1.60+0.0012*(i-45); + } + //printf("15 %1.2f %1.2f\n",_15PB20[44],_15PB20[89]); + + _15PB30(maxInd2); + _15PB30.clear(); + for (int i=0; i5) _15PB30[i] = -1.75 +0.0025*(i-5); + else if (i<90 && i>=45) _15PB30[i] = -1.65+0.002*(i-45); + } + //printf("15 %1.2f %1.2f\n",_15PB30[44],_15PB30[89]); + + _15PB40(maxInd2); + _15PB40.clear(); + for (int i=0; i5) _15PB40[i] = -1.79 +0.002*(i-5); + else if (i<90 && i>=45) _15PB40[i] = -1.71+0.002*(i-45); + } + //printf("15 %1.2f %1.2f\n",_15PB40[44],_15PB40[89]); + + _15PB50(maxInd2); + _15PB50.clear(); + for (int i=0; i5) _15PB50[i] = -1.82 +0.002*(i-5); + else if (i<90 && i>=45) _15PB50[i] = -1.74+0.0011*(i-45); + } + //printf("15 %1.2f %1.2f\n",_15PB50[44],_15PB50[89]); + + _15PB60(maxInd2); + _15PB60.clear(); + for (int i=0; i5) _15PB60[i] = -1.87 +0.0025*(i-5); + else if (i<90 && i>=45) _15PB60[i] = -1.77+0.001*(i-45); + } + //printf("15 %1.2f %1.2f\n",_15PB60[44],_15PB60[89]); + _15PB70(maxInd3); + _15PB70.clear(); + for (int i=0; i5) _15PB70[i] = -1.90 +0.0027*(i-5); + } + // printf("15 %1.2f\n",_15PB70[49]); + _15PB80(maxInd3); + _15PB80.clear(); + for (int i=0; i5) _15PB80[i] = -1.93 +0.0027*(i-5); + } + //printf("15 %1.2f %1.2f\n",_15PB80[38], _15PB80[49]); + + //3PB + _3PB10(maxInd2); + _3PB10.clear(); + for (int i=0; i5) _3PB10[i] = -1.56 +0.005*(i-5); + else if (i<90 && i>=45) _3PB10[i] = -1.36+0.001*(i-45); + } + //printf("30 %1.2f %1.2f\n",_3PB10[44],_3PB10[89]); + + _3PB20(maxInd2); + _3PB20.clear(); + for (int i=0; i5) _3PB20[i] = -1.59 +0.00275*(i-5); + else if (i<90 && i>=45) _3PB20[i] = -1.48+0.003*(i-45); + } + //printf("30 %1.2f %1.2f\n",_3PB20[44],_3PB20[89]); + + _3PB30(maxInd2); + _3PB30.clear(); + for (int i=0; i5) _3PB30[i] = -1.62 +0.00225*(i-5); + else if (i<90 && i>=45) _3PB30[i] = -1.53+0.0032*(i-45); + } + //printf("30 %1.2f %1.2f\n",_3PB30[44],_3PB30[89]); + + _3PB40(maxInd2); + _3PB40.clear(); + for (int i=0; i5) _3PB40[i] = -1.64 +0.0015*(i-5); + else if (i<90 && i>=45) _3PB40[i] = -1.58+0.0025*(i-45); + } + //printf("30 %1.2f %1.2f\n",_3PB40[44],_3PB40[89]); + + _3PB50(maxInd2); + _3PB50.clear(); + for (int i=0; i5) _3PB50[i] = -1.69 +0.00175*(i-5); + else if (i<90 && i>=45) _3PB50[i] = -1.62+0.002*(i-45); + } + //printf("30 %1.2f %1.2f\n",_3PB50[44],_3PB50[89]); + + _3PB60(maxInd2); + _3PB60.clear(); + for (int i=0; i5) _3PB60[i] = -1.73 +0.002*(i-5); + else if (i<90 && i>=45) _3PB60[i] = -1.65+0.0012*(i-45); + } + //printf("30 %1.2f %1.2f\n",_3PB60[44],_3PB60[89]); + _3PB70(maxInd3); + _3PB70.clear(); + for (int i=0; i5) _3PB70[i] = -1.76 +0.002*(i-5); + } + //printf("30 %1.2f\n",_3PB70[49]); + _3PB80(maxInd3); + _3PB80.clear(); + for (int i=0; i5) _3PB80[i] = -1.78 +0.0025*(i-5); + } + //printf("30 %1.2f %1.2f\n",_3PB80[38], _3PB80[49]); + + //45PB + _45PB10(maxInd2); + _45PB10.clear(); + for (int i=0; i5) _45PB10[i] = -1.46 +0.0045*(i-5); + else if (i<90 && i>=45) _45PB10[i] = -1.28+0.0025*(i-45); + } + //printf("45 %1.2f %1.2f\n",_45PB10[44],_45PB10[89]); + + _45PB20(maxInd2); + _45PB20.clear(); + for (int i=0; i5) _45PB20[i] = -1.48 +0.00275*(i-5); + else if (i<90 && i>=45) _45PB20[i] = -1.37+0.0025*(i-45); + } + //printf("45 %1.2f %1.2f\n",_45PB20[44],_45PB20[89]); + + _45PB30(maxInd2); + _45PB30.clear(); + for (int i=0; i5) _45PB30[i] = -1.51 +0.00175*(i-5); + else if (i<90 && i>=45) _45PB30[i] = -1.44+0.0035*(i-45); + } + //printf("45 %1.2f %1.2f\n",_45PB30[44],_45PB30[89]); + + _45PB40(maxInd2); + _45PB40.clear(); + for (int i=0; i5) _45PB40[i] = -1.52 +0.001*(i-5); + else if (i<90 && i>=45) _45PB40[i] = -1.48+0.003*(i-45); + } + //printf("45 %1.2f %1.2f\n",_45PB40[44],_45PB40[89]); + + _45PB50(maxInd2); + _45PB50.clear(); + for (int i=0; i5) _45PB50[i] = -1.55 +0.001*(i-5); + else if (i<90 && i>=45) _45PB50[i] = -1.51+0.0022*(i-45); + } + //printf("45 %1.2f %1.2f\n",_45PB50[44],_45PB50[89]); + + _45PB60(maxInd2); + _45PB60.clear(); + for (int i=0; i5) _45PB60[i] = -1.6 +0.0015*(i-5); + else if (i<90 && i>=45) _45PB60[i] = -1.54+0.001*(i-45); + } + //printf("45 %1.2f %1.2f\n",_45PB60[44],_45PB60[89]); + _45PB70(maxInd3); + _45PB70.clear(); + for (int i=0; i5) _45PB70[i] = -1.63 +0.0017*(i-5); + } + //printf("45 %1.2f\n",_45PB70[49]); + _45PB80(maxInd3); + _45PB80.clear(); + for (int i=0; i5) _45PB80[i] = -1.67 +0.0025*(i-5); + } + //printf("45 %1.2f %1.2f\n",_45PB80[38], _45PB80[49]); + + //_6PB + _6PB10(maxInd); + _6PB10.clear(); + for (int i=0; i140 + if (i<45 && i>5) _6PB10[i] = -1.33 +0.005*(i-5); + else if (i<85 && i>=45) _6PB10[i] = -1.13+0.0045*(i-45); + else if (i<140 && i >=85) _6PB10[i] = -0.95+0.0015*(i-85); + } + //printf("60 %1.2f %1.2f %1.2f\n",_6PB10[44],_6PB10[84],_6PB10[139]); + + _6PB20(maxInd); + _6PB20.clear(); + for (int i=0; i140 + if (i<45 && i>5) _6PB20[i] = -1.36 +0.004*(i-5); + else if (i<85 && i>=45) _6PB20[i] = -1.20+0.00375*(i-45); + else if (i<140 && i >=85) _6PB20[i] = -1.05+0.0017*(i-85); + } + //printf("60 %1.2f %1.2f %1.2f\n",_6PB20[44],_6PB20[84],_6PB20[139]); + + _6PB30(maxInd); + _6PB30.clear(); + for (int i=0; i140 + if (i<45 && i>5) _6PB30[i] = -1.38 +0.00225*(i-5); + else if (i<85 && i>=45) _6PB30[i] = -1.29+0.00375*(i-45); + else if (i<140 && i >=85) _6PB30[i] = -1.14+0.002*(i-85); + } + //printf("60 %1.2f %1.2f %1.2f\n",_6PB30[44],_6PB30[84],_6PB30[139]); + + _6PB40(maxInd); + _6PB40.clear(); + for (int i=0; i140 + if (i<45 && i>5) _6PB40[i] = -1.39 +0.00125*(i-5); + else if (i<85 && i>=45) _6PB40[i] = -1.34+0.00275*(i-45); + else if (i<140 && i >=85) _6PB40[i] = -1.23+0.002*(i-85); + } + //printf("60 %1.2f %1.2f %1.2f\n",_6PB40[44],_6PB40[84],_6PB40[139]); + + _6PB50(maxInd2);//limits -1.3 -1.11 + _6PB50.clear(); + for (int i=0; i5) _6PB50[i] = -1.43 +0.00125*(i-5); + else if (i<90 && i>=45) _6PB50[i] = -1.38+0.00225*(i-45); + } + //printf("60 %1.2f %1.2f \n",_6PB50[44],_6PB50[89]); + + _6PB60(maxInd2);//limits -1.3 -1.11 + _6PB60.clear(); + for (int i=0; i5) _6PB60[i] = -1.46 +0.0012*(i-5); + else if (i<90 && i>=45) _6PB60[i] = -1.40+0.000875*(i-45); + } + //printf("60 %1.2f %1.2f\n",_6PB60[44],_6PB60[89]); + _6PB70(maxInd3); + _6PB70.clear(); + for (int i=0; i5) _6PB70[i] = -1.49 +0.0018*(i-5); + } + //printf("6 %1.2f\n",_6PB70[49]); + _6PB80(maxInd3); + _6PB80.clear(); + for (int i=0; i5) _6PB80[i] = -1.52 +0.0022*(i-5); + } + //printf("6 %1.2f %1.2f\n",_6PB80[38], _6PB80[49]); + + + //_75PB : notation Munsell for maximum deviation blue purple + _75PB10(maxInd);//limits hue -1.23 -0.71 _75PBx x=Luminance eg_75PB10 for L >5 and L<=15 + _75PB10.clear(); + for (int i=0; i140 + if (i<45 && i>5) _75PB10[i] = -1.23 +0.0065*(i-5); + else if (i<85 && i>=45) _75PB10[i] = -0.97+0.00375*(i-45); + else if (i<140 && i >=85) _75PB10[i] = -0.82+0.0015*(i-85); + } + //printf("75 %1.2f %1.2f %1.2f\n",_75PB10[44],_75PB10[84],_75PB10[139]); + + _75PB20(maxInd);//limits -1.24 -0.79 for L>15 <=25 + _75PB20.clear(); + for (int i=0; i5) _75PB20[i] = -1.24 +0.004*(i-5); + else if (i<85 && i>=45) _75PB20[i] = -1.08+0.00425*(i-45); + else if (i<140 && i >=85) _75PB20[i] = -0.91+0.0017*(i-85); + } + //printf("75 %1.2f %1.2f %1.2f\n",_75PB20[44],_75PB20[84],_75PB20[139]); + + _75PB30(maxInd);//limits -1.25 -0.85 + _75PB30.clear(); + for (int i=0; i5) _75PB30[i] = -1.25 +0.00275*(i-5); + else if (i<85 && i>=45) _75PB30[i] = -1.14+0.004*(i-45); + else if (i<140 && i >=85) _75PB30[i] = -0.98+0.0015*(i-85); + } + //printf("75 %1.2f %1.2f %1.2f\n",_75PB30[44],_75PB30[84],_75PB30[139]); + + _75PB40(maxInd);//limits -1.27 -0.92 + _75PB40.clear(); + for (int i=0; i5) _75PB40[i] = -1.27 +0.002*(i-5); + else if (i<85 && i>=45) _75PB40[i] = -1.19+0.003*(i-45); + else if (i<140 && i >=85) _75PB40[i] = -1.07+0.0022*(i-85); + } + //printf("75 %1.2f %1.2f %1.2f\n",_75PB40[44],_75PB40[84],_75PB40[139]); + + _75PB50(maxInd2);//limits -1.3 -1.11 + _75PB50.clear(); + for (int i=0; i5) _75PB50[i] = -1.3 +0.00175*(i-5); + else if (i<90 && i>=45) _75PB50[i] = -1.23+0.0025*(i-45); + } + //printf("75 %1.2f %1.2f\n",_75PB50[44],_75PB50[89]); + + _75PB60(maxInd2); + _75PB60.clear(); + for (int i=0; i5) _75PB60[i] = -1.32 +0.0015*(i-5); + else if (i<90 && i>=45) _75PB60[i] = -1.26+0.002*(i-45); + } + //printf("75 %1.2f %1.2f \n",_75PB60[44],_75PB60[89]); + + _75PB70(maxInd3); + _75PB70.clear(); + for (int i=0; i5) _75PB70[i] = -1.34 +0.002*(i-5); + } + _75PB80(maxInd3); + _75PB80.clear(); + for (int i=0; i5) _75PB80[i] = -1.35 +0.00125*(i-5); + } + + + _9PB10(maxInd); + _9PB10.clear(); + for (int i=0; i140 + if (i<45 && i>5) _9PB10[i] = -1.09 +0.00475*(i-5); + else if (i<85 && i>=45) _9PB10[i] = -0.9+0.003*(i-45); + else if (i<140 && i >=85) _9PB10[i] = -0.78+0.0013*(i-85); + } + //printf("90 %1.2f %1.2f %1.2f\n",_9PB10[44],_9PB10[84],_9PB10[139]); + + _9PB20(maxInd); + _9PB20.clear(); + for (int i=0; i140 + if (i<45 && i>5) _9PB20[i] = -1.12 +0.0035*(i-5); + else if (i<85 && i>=45) _9PB20[i] = -0.98+0.00325*(i-45); + else if (i<140 && i >=85) _9PB20[i] = -0.85+0.0015*(i-85); + } + //printf("90 %1.2f %1.2f %1.2f\n",_9PB20[44],_9PB20[84],_9PB20[139]); + + _9PB30(maxInd); + _9PB30.clear(); + for (int i=0; i140 + if (i<45 && i>5) _9PB30[i] = -1.14 +0.0028*(i-5); + else if (i<85 && i>=45) _9PB30[i] = -1.03+0.003*(i-45); + else if (i<140 && i >=85) _9PB30[i] = -0.91+0.0017*(i-85); + } + //printf("90 %1.2f %1.2f %1.2f\n",_9PB30[44],_9PB30[84],_9PB30[139]); + + _9PB40(maxInd); + _9PB40.clear(); + for (int i=0; i140 + if (i<45 && i>5) _9PB40[i] = -1.16 +0.002*(i-5); + else if (i<85 && i>=45) _9PB40[i] = -1.08+0.00275*(i-45); + else if (i<140 && i >=85) _9PB40[i] = -0.97+0.0016*(i-85); + } + //printf("90 %1.2f %1.2f %1.2f\n",_9PB40[44],_9PB40[84],_9PB40[139]); + + _9PB50(maxInd2); + _9PB50.clear(); + for (int i=0; i5) _9PB50[i] = -1.19 +0.00175*(i-5); + else if (i<90 && i>=45) _9PB50[i] = -1.12+0.00225*(i-45); + } + //printf("90 %1.2f %1.2f \n",_9PB50[44],_9PB50[84]); + + _9PB60(maxInd2); + _9PB60.clear(); + for (int i=0; i5) _9PB60[i] = -1.21 +0.0015*(i-5); + else if (i<90 && i>=45) _9PB60[i] = -1.15+0.002*(i-45); + } + //printf("90 %1.2f %1.2f \n",_9PB60[44],_9PB60[89]); + _9PB70(maxInd3); + _9PB70.clear(); + for (int i=0; i5) _9PB70[i] = -1.23 +0.0018*(i-5); + } + //printf("9 %1.2f\n",_9PB70[49]); + _9PB80(maxInd3); + _9PB80.clear(); + for (int i=0; i5) _9PB80[i] = -1.24 +0.002*(i-5); + } + //printf("9 %1.2f %1.2f\n",_9PB80[38], _9PB80[49]); + + + //10PB + _10PB10(maxInd); + _10PB10.clear(); + for (int i=0; i5) _10PB10[i] = -1.02 +0.00425*(i-5); + else if (i<85 && i>=45) _10PB10[i] = -0.85+0.0025*(i-45); + else if (i<140 && i >=85) _10PB10[i] = -0.75+0.0012*(i-85); + } + //printf("10 %1.2f %1.2f %1.2f\n",_10PB10[44],_10PB10[84],_10PB10[139]); + + _10PB20(maxInd); + _10PB20.clear(); + for (int i=0; i5) _10PB20[i] = -1.05 +0.00325*(i-5); + else if (i<85 && i>=45) _10PB20[i] = -0.92+0.00275*(i-45); + else if (i<140 && i >=85) _10PB20[i] = -0.81+0.0014*(i-85); + } + //printf("10 %1.2f %1.2f %1.2f\n",_10PB20[44],_10PB20[84],_10PB20[139]); + + _10PB30(maxInd); + _10PB30.clear(); + for (int i=0; i5) _10PB30[i] = -1.07 +0.00275*(i-5); + else if (i<85 && i>=45) _10PB30[i] = -0.96+0.0025*(i-45); + else if (i<140 && i >=85) _10PB30[i] = -0.86+0.0015*(i-85); + } + //printf("10 %1.2f %1.2f %1.2f\n",_10PB30[44],_10PB30[84],_10PB30[139]); + + _10PB40(maxInd); + _10PB40.clear(); + for (int i=0; i5) _10PB40[i] = -1.09 +0.002*(i-5); + else if (i<85 && i>=45) _10PB40[i] = -1.01+0.00225*(i-45); + else if (i<140 && i >=85) _10PB40[i] = -0.92+0.0016*(i-85); + } + //printf("10 %1.2f %1.2f %1.2f\n",_10PB40[44],_10PB40[84],_10PB40[139]); + + _10PB50(maxInd2); + _10PB50.clear(); + for (int i=0; i5) _10PB50[i] = -1.12 +0.00175*(i-5); + else if (i<90 && i>=45) _10PB50[i] = -1.05+0.00225*(i-45); + } + //printf("10 %1.2f %1.2f\n",_10PB50[44],_10PB50[84]); + + _10PB60(maxInd2); + _10PB60.clear(); + for (int i=0; i5) _10PB60[i] = -1.14 +0.0015*(i-5); + else if (i<90 && i>=45) _10PB60[i] = -1.08+0.00225*(i-45); + } + //printf("10 %1.2f %1.2f\n",_10PB60[44],_10PB60[89]); + + + //1P + _1P10(maxInd); + _1P10.clear(); + for (int i=0; i5) _1P10[i] = -0.96 +0.00375*(i-5); + else if (i<85 && i>=45) _1P10[i] = -0.81+0.00225*(i-45); + else if (i<140 && i >=85) _1P10[i] = -0.72+0.001*(i-85); + } + //printf("1P %1.2f %1.2f %1.2f\n",_1P10[44],_1P10[84],_1P10[139]); + + _1P20(maxInd); + _1P20.clear(); + for (int i=0; i5) _1P20[i] = -1.0 +0.00325*(i-5); + else if (i<85 && i>=45) _1P20[i] = -0.87+0.0025*(i-45); + else if (i<140 && i >=85) _1P20[i] = -0.77+0.0012*(i-85); + } + //printf("1P %1.2f %1.2f %1.2f\n",_1P20[44],_1P20[84],_1P20[139]); + + _1P30(maxInd); + _1P30.clear(); + for (int i=0; i5) _1P30[i] = -1.02 +0.00275*(i-5); + else if (i<85 && i>=45) _1P30[i] = -0.91+0.00225*(i-45); + else if (i<140 && i >=85) _1P30[i] = -0.82+0.0011*(i-85); + } + //printf("1P %1.2f %1.2f %1.2f\n",_1P30[44],_1P30[84],_1P30[139]); + + _1P40(maxInd); + _1P40.clear(); + for (int i=0; i5) _1P40[i] = -1.04 +0.00225*(i-5); + else if (i<85 && i>=45) _1P40[i] = -0.95+0.00225*(i-45); + else if (i<140 && i >=85) _1P40[i] = -0.86+0.0015*(i-85); + } + //printf("1P %1.2f %1.2f %1.2f\n",_1P40[44],_1P40[84],_1P40[139]); + + _1P50(maxInd2); + _1P50.clear(); + for (int i=0; i5) _1P50[i] = -1.06 +0.002*(i-5); + else if (i<90 && i>=45) _1P50[i] = -0.98+0.00175*(i-45); + } + //printf("1P %1.2f %1.2f \n",_1P50[44],_1P50[89]); + + _1P60(maxInd2); + _1P60.clear(); + for (int i=0; i5) _1P60[i] = -1.07 +0.0015*(i-5); + else if (i<90 && i>=45) _1P60[i] = -1.01+0.00175*(i-45); + } + //printf("1P %1.2f %1.2f \n",_1P60[44],_1P60[84],_1P60[139]); + + //4P + _4P10(maxInd); + _4P10.clear(); + for (int i=0; i5) _4P10[i] = -0.78 +0.002*(i-5); + else if (i<85 && i>=45) _4P10[i] = -0.7+0.00125*(i-45); + else if (i<140 && i >=85) _4P10[i] = -0.65+0.001*(i-85); + } + //printf("4P %1.2f %1.2f %1.2f\n",_4P10[44],_4P10[84],_4P10[139]); + + _4P20(maxInd); + _4P20.clear(); + for (int i=0; i5) _4P20[i] = -0.84 +0.0025*(i-5); + else if (i<85 && i>=45) _4P20[i] = -0.74+0.00175*(i-45); + else if (i<140 && i >=85) _4P20[i] = -0.67+0.00085*(i-85); + } + //printf("4P %1.2f %1.2f %1.2f\n",_4P20[44],_4P20[84],_4P20[139]); + + _4P30(maxInd); + _4P30.clear(); + for (int i=0; i5) _4P30[i] = -0.85 +0.00225*(i-5); + else if (i<85 && i>=45) _4P30[i] = -0.76+0.00125*(i-45); + else if (i<140 && i >=85) _4P30[i] = -0.71+0.001*(i-85); + } + //printf("4P %1.2f %1.2f %1.2f\n",_4P30[44],_4P30[84],_4P30[139]); + + _4P40(maxInd); + _4P40.clear(); + for (int i=0; i5) _4P40[i] = -0.87 +0.00175*(i-5); + else if (i<85 && i>=45) _4P40[i] = -0.8+0.00175*(i-45); + else if (i<140 && i >=85) _4P40[i] = -0.73+0.00075*(i-85); + } + //printf("4P %1.2f %1.2f %1.2f\n",_4P40[44],_4P40[84],_4P40[139]); + + _4P50(maxInd2); + _4P50.clear(); + for (int i=0; i5) _4P50[i] = -0.88 +0.0015*(i-5); + else if (i<90 && i>=45) _4P50[i] = -0.82+0.0015*(i-45); + } + //printf("4P %1.2f %1.2f \n",_4P50[44],_4P50[89]); + + _4P60(maxInd2); + _4P60.clear(); + for (int i=0; i5) _4P60[i] = -0.89 +0.00125*(i-5); + else if (i<90 && i>=45) _4P60[i] = -0.84+0.00125*(i-45); + } + //printf("4P %1.2f %1.2f\n",_4P60[44],_4P60[89]); + + + //red yellow correction + _10YR20(maxInd2); + _10YR20.clear(); + for (int i=0; i5) _10YR20[i] = 1.22 +0.002*(i-5); + else if (i<90 && i>=45) _10YR20[i] = 1.30+0.006*(i-45); + } + //printf("10YR %1.2f %1.2f\n",_10YR20[44],_10YR20[56]); + _10YR30(maxInd2); + _10YR30.clear(); + for (int i=0; i5) _10YR30[i] = 1.27 +0.00175*(i-5); + else if (i<90 && i>=45) _10YR30[i] = 1.34+0.0017*(i-45); + } + //printf("10YR %1.2f %1.2f\n",_10YR30[44],_10YR30[75]); + _10YR40(maxInd2); + _10YR40.clear(); + for (int i=0; i5) _10YR40[i] = 1.32 +0.00025*(i-5); + else if (i<90 && i>=45) _10YR40[i] = 1.33+0.0015*(i-45); + } + //printf("10YR %1.2f %1.2f\n",_10YR40[44],_10YR40[85]); + _10YR50(maxInd2); + _10YR50.clear(); + for (int i=0; i5) _10YR50[i] = 1.35 +0.000*(i-5); + else if (i<90 && i>=45) _10YR50[i] = 1.35+0.0012*(i-45); + } + //printf("10YR %1.2f %1.2f\n",_10YR50[44],_10YR50[80]); + _10YR60(maxInd); + _10YR60.clear(); + for (int i=0; i5) _10YR60[i] = 1.38 - 0.00025*(i-5); + else if (i<85 && i>=45) _10YR60[i] = 1.37+0.0005*(i-45); + else if (i<140 && i >=85) _10YR60[i] = 1.39+0.0013*(i-85); + } + //printf("10YR %1.2f %1.2f %1.2f\n",_10YR60[44],_10YR60[85],_10YR60[139] ); + _10YR70(maxInd); + _10YR70.clear(); + for (int i=0; i5) _10YR70[i] = 1.41 - 0.0005*(i-5); + else if (i<85 && i>=45) _10YR70[i] = 1.39+0.000*(i-45); + else if (i<140 && i >=85) _10YR70[i] = 1.39+0.0013*(i-85); + } + //printf("10YR %1.2f %1.2f %1.2f\n",_10YR70[44],_10YR70[85],_10YR70[139] ); + _10YR80(maxInd); + _10YR80.clear(); + for (int i=0; i5) _10YR80[i] = 1.45 - 0.00125*(i-5); + else if (i<85 && i>=45) _10YR80[i] = 1.40+0.000*(i-45); + else if (i<140 && i >=85) _10YR80[i] = 1.40+0.00072*(i-85);//1.436 + } + //printf("10YR %1.2f %1.2f %1.2f\n",_10YR80[44],_10YR80[84],_10YR80[139] ); + _10YR90(maxInd2); + _10YR90.clear(); + for (int i=0; i5) _10YR90[i] = 1.48 -0.001*(i-5); + else if (i<90 && i>=45) _10YR90[i] = 1.44-0.0009*(i-45); + } + //printf("10YR %1.2f %1.2f\n",_10YR90[45],_10YR90[80]); + _85YR20(maxInd3); + _85YR20.clear(); + for (int i=0; i5) _85YR20[i] = 1.12 +0.004*(i-5); + } + + //printf("85YR %1.2f \n",_85YR20[44]); + _85YR30(maxInd2); + _85YR30.clear(); + for (int i=0; i5) _85YR30[i] = 1.16 + 0.0025*(i-5); + else if (i<90 && i>=45) _85YR30[i] = 1.26+0.0028*(i-45); + } + //printf("85YR %1.2f %1.2f\n",_85YR30[44],_85YR30[75]); + _85YR40(maxInd2); + _85YR40.clear(); + for (int i=0; i5) _85YR40[i] = 1.20 + 0.0015*(i-5); + else if (i<90 && i>=45) _85YR40[i] = 1.26+0.0024*(i-45); + } + //printf("85YR %1.2f %1.2f\n",_85YR40[44],_85YR40[75]); + _85YR50(maxInd); + _85YR50.clear(); + for (int i=0; i5) _85YR50[i] = 1.24 + 0.0005*(i-5); + else if (i<85 && i>=45) _85YR50[i] = 1.26+0.002*(i-45); + else if (i<140 && i >=85) _85YR50[i] = 1.34+0.0015*(i-85); + } + //printf("85YR %1.2f %1.2f %1.2f\n",_85YR50[44],_85YR50[85],_85YR50[110] ); + _85YR60(maxInd); + _85YR60.clear(); + for (int i=0; i5) _85YR60[i] = 1.27 + 0.00025*(i-5); + else if (i<85 && i>=45) _85YR60[i] = 1.28+0.0015*(i-45); + else if (i<140 && i >=85) _85YR60[i] = 1.34+0.0012*(i-85); + } + //printf("85YR %1.2f %1.2f %1.2f\n",_85YR60[44],_85YR60[85],_85YR60[139] ); + + _85YR70(maxInd); + _85YR70.clear(); + for (int i=0; i5) _85YR70[i] = 1.31 - 0.00025*(i-5); + else if (i<85 && i>=45) _85YR70[i] = 1.30+0.0005*(i-45); + else if (i<140 && i >=85) _85YR70[i] = 1.32+0.0012*(i-85); + } + //printf("85YR %1.2f %1.2f %1.2f\n",_85YR70[44],_85YR70[85],_85YR70[139] ); + _85YR80(maxInd); + _85YR80.clear(); + for (int i=0; i5) _85YR80[i] = 1.35 - 0.00075*(i-5); + else if (i<85 && i>=45) _85YR80[i] = 1.32+0.00025*(i-45); + else if (i<140 && i >=85) _85YR80[i] = 1.33+0.00125*(i-85); + } + //printf("85YR %1.2f %1.2f %1.2f\n",_85YR80[44],_85YR80[85],_85YR80[139] ); + _85YR90(maxInd2); + _85YR90.clear(); + for (int i=0; i5) _85YR90[i] = 1.39 - 0.00125*(i-5); + else if (i<90 && i>=45) _85YR90[i] = 1.34+0.00*(i-45); + } + //printf("85YR %1.2f %1.2f\n",_85YR90[44],_85YR90[85]); + + //7YR + _7YR30(maxInd2); + _7YR30.clear(); + for (int i=0; i5) _7YR30[i] = 1.06 + 0.0028*(i-5); + else if (i<90 && i>=45) _7YR30[i] = 1.17+0.0045*(i-45); + } + //printf("7YR %1.2f %1.2f\n",_7YR30[44],_7YR30[66]); + _7YR40(maxInd2); + _7YR40.clear(); + for (int i=0; i5) _7YR40[i] = 1.10 + 0.0018*(i-5); + else if (i<90 && i>=45) _7YR40[i] = 1.17+0.0035*(i-45); + } + //printf("7YR %1.2f %1.2f\n",_7YR40[44],_7YR40[89]); + _7YR50(maxInd2); + _7YR50.clear(); + for (int i=0; i5) _7YR50[i] = 1.14 + 0.00125*(i-5); + else if (i<90 && i>=45) _7YR50[i] = 1.19+0.002*(i-45); + } + //printf("7YR %1.2f %1.2f\n",_7YR50[44],_7YR50[89] ); + _7YR60(maxInd); + _7YR60.clear(); + for (int i=0; i5) _7YR60[i] = 1.17 + 0.00075*(i-5); + else if (i<85 && i>=45) _7YR60[i] = 1.20+0.00175*(i-45); + else if (i<140 && i >=85) _7YR60[i] = 1.27+0.002*(i-85); + } + //printf("7YR %1.2f %1.2f %1.2f\n",_7YR60[44],_7YR60[84],_7YR60[125] ); + + _7YR70(maxInd); + _7YR70.clear(); + for (int i=0; i5) _7YR70[i] = 1.20 + 0.0005*(i-5); + else if (i<85 && i>=45) _7YR70[i] = 1.22+0.00125*(i-45); + else if (i<140 && i >=85) _7YR70[i] = 1.27+0.0015*(i-85); + } + //printf("7YR %1.2f %1.2f %1.2f\n",_7YR70[44],_7YR70[84],_7YR70[125] ); + _7YR80(maxInd3); + _7YR80.clear(); + for (int i=0; i5) _7YR80[i] = 1.29 - 0.0008*(i-5); + } + //printf("7YR %1.2f \n",_7YR80[44] ); + _55YR30(maxInd3); + _55YR30.clear(); + for (int i=0; i5) _55YR30[i] = 0.96 + 0.0038*(i-5); + } + //printf("55YR %1.2f \n",_55YR30[44] ); + _55YR40(maxInd2); + _55YR40.clear(); + for (int i=0; i5) _55YR40[i] = 1.01 + 0.0022*(i-5); + else if (i<90 && i>=45) _55YR40[i] = 1.10+0.0037*(i-45); + } + //printf("55YR %1.2f %1.2f\n",_55YR40[44],_55YR40[89] ); + _55YR50(maxInd); + _55YR50.clear(); + for (int i=0; i5) _55YR50[i] = 1.06 + 0.0015*(i-5); + else if (i<85 && i>=45) _55YR50[i] = 1.12+0.00225*(i-45); + else if (i<140 && i >=85) _55YR50[i] = 1.21+0.0015*(i-85); + } + //printf("55YR %1.2f %1.2f %1.2f\n",_55YR50[44],_55YR50[84],_55YR50[125] ); + _55YR60(maxInd); + _55YR60.clear(); + for (int i=0; i5) _55YR60[i] = 1.08 + 0.0012*(i-5); + else if (i<85 && i>=45) _55YR60[i] = 1.13+0.0018*(i-45); + else if (i<140 && i >=85) _55YR60[i] = 1.20+0.0025*(i-85); + } + //printf("55YR %1.2f %1.2f %1.2f\n",_55YR60[44],_55YR60[84],_55YR60[125] ); + _55YR70(maxInd); + _55YR70.clear(); + for (int i=0; i5) _55YR70[i] = 1.11 + 0.00075*(i-5); + else if (i<85 && i>=45) _55YR70[i] = 1.14+0.0012*(i-45); + else if (i<140 && i >=85) _55YR70[i] = 1.19+0.00225*(i-85); + } + //printf("55YR %1.2f %1.2f %1.2f\n",_55YR70[44],_55YR70[84],_55YR70[125] ); + _55YR80(maxInd); + _55YR80.clear(); + for (int i=0; i5) _55YR80[i] = 1.16 + 0.00*(i-5); + else if (i<85 && i>=45) _55YR80[i] = 1.16+0.00075*(i-45); + else if (i<140 && i >=85) _55YR80[i] = 1.19+0.00175*(i-85); + } + //printf("55YR %1.2f %1.2f %1.2f\n",_55YR80[44],_55YR80[84],_55YR80[125] ); + _55YR90(maxInd3); + _55YR90.clear(); + for (int i=0; i5) _55YR90[i] = 1.19 - 0.0005*(i-5); + } + //printf("55YR %1.2f \n",_55YR90[44] ); + + _4YR30(maxInd2); + _4YR30.clear(); + for (int i=0; i5) _4YR30[i] = 0.87 + 0.0035*(i-5); + else if (i<90 && i>=45) _4YR30[i] = 1.01+0.0043*(i-45); + } + //printf("4YR %1.2f %1.2f\n",_4YR30[44],_4YR30[78] ); + _4YR40(maxInd2); + _4YR40.clear(); + for (int i=0; i5) _4YR40[i] = 0.92 + 0.0025*(i-5); + else if (i<90 && i>=45) _4YR40[i] = 1.02+0.0033*(i-45); + } + //printf("4YR %1.2f %1.2f\n",_4YR40[44],_4YR40[74] ); + _4YR50(maxInd2); + _4YR50.clear(); + for (int i=0; i5) _4YR50[i] = 0.97 + 0.0015*(i-5); + else if (i<90 && i>=45) _4YR50[i] = 1.03+0.0025*(i-45); + } + //printf("4YR %1.2f %1.2f\n",_4YR50[44],_4YR50[85] ); + _4YR60(maxInd); + _4YR60.clear(); + for (int i=0; i5) _4YR60[i] = 0.99 + 0.00125*(i-5); + else if (i<85 && i>=45) _4YR60[i] = 1.04+0.002*(i-45); + else if (i<140 && i >=85) _4YR60[i] = 1.12+0.003*(i-85); + } + //printf("4YR %1.2f %1.2f %1.2f\n",_4YR60[44],_4YR60[84],_4YR60[125] ); + _4YR70(maxInd); + _4YR70.clear(); + for (int i=0; i5) _4YR70[i] = 1.02 + 0.00075*(i-5); + else if (i<85 && i>=45) _4YR70[i] = 1.05+0.00175*(i-45); + else if (i<140 && i >=85) _4YR70[i] = 1.12+0.002*(i-85); + } + //printf("4YR %1.2f %1.2f %1.2f\n",_4YR70[44],_4YR70[84],_4YR70[125] ); + _4YR80(maxInd3); + _4YR80.clear(); + for (int i=0; i5) _4YR80[i] = 1.09 - 0.0002*(i-5); + } + //printf("4YR %1.2f \n",_4YR80[41] ); + + _25YR30(maxInd2); + _25YR30.clear(); + for (int i=0; i5) _25YR30[i] = 0.77 + 0.004*(i-5); + else if (i<90 && i>=45) _25YR30[i] = 0.94+0.004*(i-45); + } + //printf("25YR %1.2f %1.2f\n",_25YR30[44],_25YR30[74] ); + _25YR40(maxInd2); + _25YR40.clear(); + for (int i=0; i5) _25YR40[i] = 0.82 + 0.003*(i-5); + else if (i<90 && i>=45) _25YR40[i] = 0.94+0.002*(i-45); + } + //printf("25YR %1.2f %1.2f\n",_25YR40[44],_25YR40[84] ); + _25YR50(maxInd2); + _25YR50.clear(); + for (int i=0; i5) _25YR50[i] = 0.87+ 0.002*(i-5); + else if (i<90 && i>=45) _25YR50[i] = 0.95+0.003*(i-45); + } + //printf("25YR %1.2f %1.2f\n",_25YR50[44],_25YR50[84] ); + _25YR60(maxInd2); + _25YR60.clear(); + for (int i=0; i5) _25YR60[i] = 0.89+ 0.0015*(i-5); + else if (i<90 && i>=45) _25YR60[i] = 0.95+0.004*(i-45); + } + //printf("25YR %1.2f %1.2f\n",_25YR60[44],_25YR60[84] ); + _25YR70(maxInd2); + _25YR70.clear(); + for (int i=0; i5) _25YR70[i] = 0.92+ 0.001*(i-5); + else if (i<90 && i>=45) _25YR70[i] = 0.96+0.003*(i-45); + } + //printf("25YR %1.2f %1.2f\n",_25YR70[44],_25YR70[84] ); + + _10R30(maxInd2); + _10R30.clear(); + for (int i=0; i5) _10R30[i] = 0.62 + 0.00225*(i-5); + else if (i<90 && i>=45) _10R30[i] = 0.71+0.003*(i-45); + } + //printf("10R %1.2f %1.2f\n",_10R30[44],_10R30[84] ); + _10R40(maxInd2); + _10R40.clear(); + for (int i=0; i5) _10R40[i] = 0.66 + 0.0025*(i-5); + else if (i<90 && i>=45) _10R40[i] = 0.76+0.0035*(i-45); + } + //printf("10R %1.2f %1.2f\n",_10R40[44],_10R40[84] ); + _10R50(maxInd2); + _10R50.clear(); + for (int i=0; i5) _10R50[i] = 0.71 + 0.002*(i-5); + else if (i<90 && i>=45) _10R50[i] = 0.79+0.0043*(i-45); + } + //printf("10R %1.2f %1.2f\n",_10R50[44],_10R50[84] ); + _10R60(maxInd); + _10R60.clear(); + for (int i=0; i5) _10R60[i] = 0.73 + 0.00175*(i-5); + else if (i<85 && i>=45) _10R60[i] = 0.80 +0.0033*(i-45); + else if (i<140 && i >=85) _10R60[i] = 0.93+0.0018*(i-85); + } + //printf("10R %1.2f %1.2f %1.2f\n",_10R60[44],_10R60[84],_10R60[125] ); + _10R70(maxInd); + _10R70.clear(); + for (int i=0; i5) _10R70[i] = 0.75 + 0.0015*(i-5); + else if (i<85 && i>=45) _10R70[i] = 0.81 +0.0017*(i-45); + else if (i<140 && i >=85) _10R70[i] = 0.88+0.0025*(i-85); + } + //printf("10R %1.2f %1.2f %1.2f\n",_10R70[44],_10R70[84],_10R70[125] ); + + _9R30(maxInd2); + _9R30.clear(); + for (int i=0; i5) _9R30[i] = 0.57 + 0.002*(i-5); + else if (i<90 && i>=45) _9R30[i] = 0.65+0.0018*(i-45); + } + //printf("9R %1.2f %1.2f\n",_9R30[44],_9R30[84] ); + _9R40(maxInd2); + _9R40.clear(); + for (int i=0; i5) _9R40[i] = 0.61 + 0.002*(i-5); + else if (i<90 && i>=45) _9R40[i] = 0.69+0.0025*(i-45); + } + //printf("9R %1.2f %1.2f\n",_9R40[44],_9R40[84] ); + _9R50(maxInd); + _9R50.clear(); + for (int i=0; i5) _9R50[i] = 0.66 + 0.00175*(i-5); + else if (i<85 && i>=45) _9R50[i] = 0.73 +0.0025*(i-45); + else if (i<140 && i >=85) _9R50[i] = 0.83+0.0035*(i-85); + } + //printf("9R %1.2f %1.2f %1.2f\n",_9R50[44],_9R50[84],_9R50[125] ); + _9R60(maxInd); + _9R60.clear(); + for (int i=0; i5) _9R60[i] = 0.68 + 0.0015*(i-5); + else if (i<85 && i>=45) _9R60[i] = 0.74 +0.0022*(i-45); + else if (i<140 && i >=85) _9R60[i] = 0.93+0.0022*(i-85); + } + //printf("9R %1.2f %1.2f %1.2f\n",_9R60[44],_9R60[84],_9R60[125] ); + _9R70(maxInd2); + _9R70.clear(); + for (int i=0; i5) _9R70[i] = 0.70 + 0.0012*(i-5); + else if (i<90 && i>=45) _9R70[i] = 0.75+0.0013*(i-45); + } + //printf("9R %1.2f %1.2f\n",_9R70[44],_9R70[84] ); + + _7R30(maxInd2); + _7R30.clear(); + for (int i=0; i5) _7R30[i] = 0.48 + 0.0015*(i-5); + else if (i<90 && i>=45) _7R30[i] = 0.54-0.0005*(i-45); + } + //printf("7R %1.2f %1.2f\n",_7R30[44],_7R30[84] ); + _7R40(maxInd2); + _7R40.clear(); + for (int i=0; i5) _7R40[i] = 0.51 + 0.0015*(i-5); + else if (i<90 && i>=45) _7R40[i] = 0.57+0.0005*(i-45); + } + //printf("7R %1.2f %1.2f\n",_7R40[44],_7R40[84] ); + _7R50(maxInd); + _7R50.clear(); + for (int i=0; i5) _7R50[i] = 0.54 + 0.0015*(i-5); + else if (i<85 && i>=45) _7R50[i] = 0.60 +0.0005*(i-45); + else if (i<140 && i >=85) _7R50[i] = 0.62+0.0025*(i-85); + } + //printf("7R %1.2f %1.2f %1.2f\n",_7R50[44],_7R50[84],_7R50[125] ); + _7R60(maxInd); + _7R60.clear(); + for (int i=0; i5) _7R60[i] = 0.58 + 0.00075*(i-5); + else if (i<85 && i>=45) _7R60[i] = 0.61 +0.00075*(i-45); + else if (i<140 && i >=85) _7R60[i] = 0.64+0.001*(i-85); + } + //printf("7R %1.2f %1.2f %1.2f\n",_7R60[44],_7R60[84],_7R60[107] ); + _7R70(maxInd2); + _7R70.clear(); + for (int i=0; i5) _7R70[i] = 0.59 + 0.00075*(i-5); + else if (i<90 && i>=45) _7R70[i] = 0.62+0.00075*(i-45); + } + //printf("7R %1.2f %1.2f\n",_7R70[44],_7R70[84] ); + + //5R 1 2 3 + + //5R + _5R10(maxInd2); + _5R10.clear(); + for (int i=0; i5) _5R10[i] = 0.10 - 0.0018*(i-5); + else if (i<90 && i>=45) _5R10[i] = 0.035-0.003*(i-45); + } + //printf("5R %1.2f %1.2f\n",_5R10[44],_5R10[51] ); + _5R20(maxInd2); + _5R20.clear(); + for (int i=0; i5) _5R20[i] = 0.26 - 0.00075*(i-5); + else if (i<90 && i>=45) _5R20[i] = 0.023-0.0002*(i-45); + } + //printf("5R %1.2f %1.2f\n",_5R20[44],_5R20[70] ); + _5R30(maxInd2); + _5R30.clear(); + for (int i=0; i5) _5R30[i] = 0.39 + 0.00075*(i-5); + else if (i<90 && i>=45) _5R30[i] = 0.42-0.0007*(i-45); + } + //printf("5R %1.2f %1.2f\n",_5R30[44],_5R30[85] ); + + //25R + _25R10(maxInd3); + _25R10.clear(); + for (int i=0; i5) _25R10[i] = -0.03 - 0.002*(i-5); + } + //printf("25R %1.2f \n",_25R10[44]); + _25R20(maxInd2); + _25R20.clear(); + for (int i=0; i5) _25R20[i] = 0.13 - 0.0012*(i-5); + else if (i<90 && i>=45) _25R20[i] = 0.08-0.002*(i-45); + } + //printf("25R %1.2f %1.2f\n",_25R20[44],_25R20[69] ); + //25R30: 0.28, 0.26, 0.22 + _25R30(maxInd2); + _25R30.clear(); + for (int i=0; i5) _25R30[i] = 0.28 - 0.0005*(i-5); + else if (i<90 && i>=45) _25R30[i] = 0.26-0.0009*(i-45); + } + //printf("25R %1.2f %1.2f\n",_25R30[44],_25R30[85] ); + + + _10RP10(maxInd3); + _10RP10.clear(); + for (int i=0; i5) _10RP10[i] = -0.16 - 0.0017*(i-5); + } + //printf("10RP %1.2f \n",_10RP10[44]); + _10RP20(maxInd2); + _10RP20.clear(); + for (int i=0; i5) _10RP20[i] = 0.0 - 0.0018*(i-5); + else if (i<90 && i>=45) _10RP20[i] = -0.07-0.0012*(i-45); + } + //printf("10RP %1.2f %1.2f\n",_10RP20[44],_10RP20[69] ); + _10RP30(maxInd2); + _10RP30.clear(); + for (int i=0; i5) _10RP30[i] = 0.15 - 0.001*(i-5); + else if (i<90 && i>=45) _10RP30[i] = 0.11-0.0012*(i-45); + } + //printf("10RP %1.2f %1.2f\n",_10RP30[44],_10RP30[85] ); + + //7G + _7G30(maxInd); + _7G30.clear(); + for (int i=0; i5) _7G30[i] = 2.90 + 0.0027*(i-5); + else if (i<85 && i>=45) _7G30[i] = 3.01+0.0005*(i-45); + else if (i<140 && i >=85) _7G30[i] = 3.03+0.00075*(i-85); + } + //printf("7G %1.2f %1.2f %1.2f\n",_7G30[44],_7G30[84],_7G30[125] ); + _7G40(maxInd); + _7G40.clear(); + for (int i=0; i5) _7G40[i] = 2.89 + 0.00125*(i-5); + else if (i<85 && i>=45) _7G40[i] = 2.94+0.0015*(i-45); + else if (i<140 && i >=85) _7G40[i] = 3.0+0.001*(i-85); + } + //printf("7G %1.2f %1.2f %1.2f\n",_7G40[44],_7G40[84],_7G40[125] ); + _7G50(maxInd); + _7G50.clear(); + for (int i=0; i5) _7G50[i] = 2.87 + 0.0015*(i-5); + else if (i<85 && i>=45) _7G50[i] = 2.93+0.00125*(i-45); + else if (i<140 && i >=85) _7G50[i] = 2.98+0.001*(i-85); + } + //printf("7G %1.2f %1.2f %1.2f\n",_7G50[44],_7G50[84],_7G50[125] ); + _7G60(maxInd); + _7G60.clear(); + for (int i=0; i5) _7G60[i] = 2.86 + 0.00125*(i-5); + else if (i<85 && i>=45) _7G60[i] = 2.91+0.00125*(i-45); + else if (i<140 && i >=85) _7G60[i] = 2.96+0.00075*(i-85); + } + //printf("7G %1.2f %1.2f %1.2f\n",_7G60[44],_7G60[84],_7G60[125] ); + _7G70(maxInd); + _7G70.clear(); + for (int i=0; i5) _7G70[i] = 2.85 + 0.001*(i-5); + else if (i<85 && i>=45) _7G70[i] = 2.89+0.00125*(i-45); + else if (i<140 && i >=85) _7G70[i] = 2.94+0.00075*(i-85); + } + //printf("7G %1.2f %1.2f %1.2f\n",_7G70[44],_7G70[84],_7G70[125] ); + _7G80(maxInd); + _7G80.clear(); + for (int i=0; i5) _7G80[i] = 2.84 + 0.001*(i-5); + else if (i<85 && i>=45) _7G80[i] = 2.88+0.001*(i-45); + else if (i<140 && i >=85) _7G80[i] = 2.92+0.001*(i-85); + } + //printf("7G %1.2f %1.2f %1.2f\n",_7G80[44],_7G80[84],_7G80[125] ); + + + //5G + _5G30(maxInd); + _5G30.clear(); + for (int i=0; i5) _5G30[i] = 2.82 + 0.00175*(i-5); + else if (i<85 && i>=45) _5G30[i] = 2.89+0.0018*(i-45); + else if (i<140 && i >=85) _5G30[i] = 2.96+0.0012*(i-85); + } + //printf("5G %1.2f %1.2f %1.2f\n",_5G30[44],_5G30[84],_5G30[125] ); + _5G40(maxInd); + _5G40.clear(); + for (int i=0; i5) _5G40[i] = 2.80 + 0.0015*(i-5); + else if (i<85 && i>=45) _5G40[i] = 2.86+0.00175*(i-45); + else if (i<140 && i >=85) _5G40[i] = 2.93+0.00125*(i-85); + } + //printf("5G %1.2f %1.2f %1.2f\n",_5G40[44],_5G40[84],_5G40[125] ); + _5G50(maxInd); + _5G50.clear(); + for (int i=0; i5) _5G50[i] = 2.79 + 0.001*(i-5); + else if (i<85 && i>=45) _5G50[i] = 2.84+0.0015*(i-45); + else if (i<140 && i >=85) _5G50[i] = 2.90+0.0015*(i-85); + } + //printf("5G %1.2f %1.2f %1.2f\n",_5G50[44],_5G50[84],_5G50[125] ); + _5G60(maxInd); + _5G60.clear(); + for (int i=0; i5) _5G60[i] = 2.78 + 0.001*(i-5); + else if (i<85 && i>=45) _5G60[i] = 2.82+0.00175*(i-45); + else if (i<140 && i >=85) _5G60[i] = 2.89+0.001*(i-85); + } + //printf("5G %1.2f %1.2f %1.2f\n",_5G60[44],_5G60[84],_5G60[125] ); + _5G70(maxInd); + _5G70.clear(); + for (int i=0; i5) _5G70[i] = 2.77 + 0.001*(i-5); + else if (i<85 && i>=45) _5G70[i] = 2.81+0.00125*(i-45); + else if (i<140 && i >=85) _5G70[i] = 2.86+0.00125*(i-85); + } + //printf("5G %1.2f %1.2f %1.2f\n",_5G70[44],_5G70[84],_5G70[125] ); + _5G80(maxInd); + _5G80.clear(); + for (int i=0; i5) _5G80[i] = 2.76 + 0.001*(i-5); + else if (i<85 && i>=45) _5G80[i] = 2.8+0.00125*(i-45); + else if (i<140 && i >=85) _5G80[i] = 2.85+0.00125*(i-85); + } + //printf("5G %1.2f %1.2f %1.2f\n",_5G80[44],_5G80[84],_5G80[125] ); + + //25G + _25G30(maxInd); + _25G30.clear(); + for (int i=0; i5) _25G30[i] = 2.68 + 0.0015*(i-5); + else if (i<85 && i>=45) _25G30[i] = 2.74+0.0018*(i-45); + else if (i<140 && i >=85) _25G30[i] = 2.81+0.002*(i-85); + } + //printf("25G %1.2f %1.2f %1.2f\n",_25G30[44],_25G30[84],_25G30[125] ); + _25G40(maxInd); + _25G40.clear(); + for (int i=0; i5) _25G40[i] = 2.68 + 0.00075*(i-5); + else if (i<85 && i>=45) _25G40[i] = 2.71+0.0015*(i-45); + else if (i<140 && i >=85) _25G40[i] = 2.77+0.00125*(i-85); + } + //printf("25G %1.2f %1.2f %1.2f\n",_25G40[44],_25G40[84],_25G40[125] ); + _25G50(maxInd); + _25G50.clear(); + for (int i=0; i5) _25G50[i] = 2.65 + 0.00075*(i-5); + else if (i<85 && i>=45) _25G50[i] = 2.68+0.00125*(i-45); + else if (i<140 && i >=85) _25G50[i] = 2.73+0.00125*(i-85); + } + //printf("25G %1.2f %1.2f %1.2f\n",_25G50[44],_25G50[84],_25G50[125] ); + _25G60(maxInd); + _25G60.clear(); + for (int i=0; i5) _25G60[i] = 2.64 + 0.0005*(i-5); + else if (i<85 && i>=45) _25G60[i] = 2.66+0.001*(i-45); + else if (i<140 && i >=85) _25G60[i] = 2.70+0.001*(i-85); + } + //printf("25G %1.2f %1.2f %1.2f\n",_25G60[44],_25G60[84],_25G60[125] ); + _25G70(maxInd); + _25G70.clear(); + for (int i=0; i5) _25G70[i] = 2.64 + 0.00*(i-5); + else if (i<85 && i>=45) _25G70[i] = 2.64+0.00075*(i-45); + else if (i<140 && i >=85) _25G70[i] = 2.67+0.001*(i-85); + } + //printf("25G %1.2f %1.2f %1.2f\n",_25G70[44],_25G70[84],_25G70[125] ); + _25G80(maxInd); + _25G80.clear(); + for (int i=0; i5) _25G80[i] = 2.63 + 0.00*(i-5); + else if (i<85 && i>=45) _25G80[i] = 2.63+0.0005*(i-45); + else if (i<140 && i >=85) _25G80[i] = 2.65+0.0005*(i-85); + } + //printf("25G %1.2f %1.2f %1.2f\n",_25G80[44],_25G80[84],_25G80[125] ); + + + //1G + _1G30(maxInd); + _1G30.clear(); + for (int i=0; i5) _1G30[i] = 2.58 + 0.00025*(i-5); + else if (i<85 && i>=45) _1G30[i] = 2.59+0.001*(i-45); + else if (i<140 && i >=85) _1G30[i] = 2.63+0.00125*(i-85); + } + //printf("1G %1.2f %1.2f %1.2f\n",_1G30[44],_1G30[84],_1G30[125] ); + _1G40(maxInd); + _1G40.clear(); + for (int i=0; i5) _1G40[i] = 2.56 - 0.00025*(i-5); + else if (i<85 && i>=45) _1G40[i] = 2.55+0.0005*(i-45); + else if (i<140 && i >=85) _1G40[i] = 2.57+0.0005*(i-85); + } + //printf("1G %1.2f %1.2f %1.2f\n",_1G40[44],_1G40[84],_1G40[125] ); + _1G50(maxInd); + _1G50.clear(); + for (int i=0; i5) _1G50[i] = 2.55 - 0.00025*(i-5); + else if (i<85 && i>=45) _1G50[i] = 2.54+0.00025*(i-45); + else if (i<140 && i >=85) _1G50[i] = 2.55+0.0005*(i-85); + } + //printf("1G %1.2f %1.2f %1.2f\n",_1G50[44],_1G50[84],_1G50[125] ); + _1G60(maxInd); + _1G60.clear(); + for (int i=0; i5) _1G60[i] = 2.54 - 0.0005*(i-5); + else if (i<85 && i>=45) _1G60[i] = 2.52+0.00025*(i-45); + else if (i<140 && i >=85) _1G60[i] = 2.53+0.00025*(i-85); + } + //printf("1G %1.2f %1.2f %1.2f\n",_1G60[44],_1G60[84],_1G60[125] ); + _1G70(maxInd); + _1G70.clear(); + for (int i=0; i5) _1G70[i] = 2.53 - 0.0005*(i-5); + else if (i<85 && i>=45) _1G70[i] = 2.51+0.0*(i-45); + else if (i<140 && i >=85) _1G70[i] = 2.51+0.00025*(i-85); + } + //printf("1G %1.2f %1.2f %1.2f\n",_1G70[44],_1G70[84],_1G70[125] ); + _1G80(maxInd); + _1G80.clear(); + for (int i=0; i5) _1G80[i] = 2.52 - 0.0005*(i-5); + else if (i<85 && i>=45) _1G80[i] = 2.50+0.00*(i-45); + else if (i<140 && i >=85) _1G80[i] = 2.50+0.00*(i-85); + } + //printf("1G %1.2f %1.2f %1.2f\n",_1G80[44],_1G80[84],_1G80[125] ); + + + //10GY + _10GY30(maxInd); + _10GY30.clear(); + for (int i=0; i5) _10GY30[i] = 2.52 - 0.001*(i-5); + else if (i<85 && i>=45) _10GY30[i] = 2.48-0.002*(i-45); + else if (i<140 && i >=85) _10GY30[i] = 2.40+0.0025*(i-85); + } + //printf("10GY %1.2f %1.2f %1.2f\n",_10GY30[44],_10GY30[84],_10GY30[125] ); + _10GY40(maxInd); + _10GY40.clear(); + for (int i=0; i5) _10GY40[i] = 2.48 - 0.0005*(i-5); + else if (i<85 && i>=45) _10GY40[i] = 2.46-0.0005*(i-45); + else if (i<140 && i >=85) _10GY40[i] = 2.44-0.0015*(i-85); + } + //printf("10GY %1.2f %1.2f %1.2f\n",_10GY40[44],_10GY40[84],_10GY40[125] ); + _10GY50(maxInd); + _10GY50.clear(); + for (int i=0; i5) _10GY50[i] = 2.48 - 0.00075*(i-5); + else if (i<85 && i>=45) _10GY50[i] = 2.45-0.00075*(i-45); + else if (i<140 && i >=85) _10GY50[i] = 2.42-0.00175*(i-85); + } + //printf("10GY %1.2f %1.2f %1.2f\n",_10GY50[44],_10GY50[84],_10GY50[125] ); + _10GY60(maxInd); + _10GY60.clear(); + for (int i=0; i5) _10GY60[i] = 2.47 - 0.00125*(i-5); + else if (i<85 && i>=45) _10GY60[i] = 2.42-0.00025*(i-45); + else if (i<140 && i >=85) _10GY60[i] = 2.41-0.0005*(i-85); + } + //printf("10GY %1.2f %1.2f %1.2f\n",_10GY60[44],_10GY60[84],_10GY60[125] ); + _10GY70(maxInd); + _10GY70.clear(); + for (int i=0; i5) _10GY70[i] = 2.46 - 0.001*(i-5); + else if (i<85 && i>=45) _10GY70[i] = 2.42+0.0*(i-45); + else if (i<140 && i >=85) _10GY70[i] = 2.42-0.001*(i-85); + } + //printf("10GY %1.2f %1.2f %1.2f\n",_10GY70[44],_10GY70[84],_10GY70[125] ); + _10GY80(maxInd); + _10GY80.clear(); + for (int i=0; i5) _10GY80[i] = 2.45 - 0.00075*(i-5); + else if (i<85 && i>=45) _10GY80[i] = 2.42 - 0.0005*(i-45); + else if (i<140 && i >=85) _10GY80[i] = 2.40-0.0005*(i-85); + } + //printf("10GY %1.2f %1.2f %1.2f\n",_10GY80[44],_10GY80[84],_10GY80[125] ); + + + //75GY + _75GY30(maxInd2); + _75GY30.clear(); + for (int i=0; i5) _75GY30[i] = 2.36 - 0.0025*(i-5); + else if (i<90 && i>=45) _75GY30[i] = 2.26-0.00175*(i-45); + } + //printf("75GY %1.2f %1.2f\n",_75GY30[44],_75GY30[84] ); + _75GY40(maxInd2); + _75GY40.clear(); + for (int i=0; i5) _75GY40[i] = 2.34 - 0.00175*(i-5); + else if (i<90 && i>=45) _75GY40[i] = 2.27-0.00225*(i-45); + } + //printf("75GY %1.2f %1.2f \n",_75GY40[44],_75GY40[84] ); + _75GY50(maxInd); + _75GY50.clear(); + for (int i=0; i5) _75GY50[i] = 2.32 - 0.0015*(i-5); + else if (i<85 && i>=45) _75GY50[i] = 2.26-0.00175*(i-45); + else if (i<140 && i >=85) _75GY50[i] = 2.19-0.00325*(i-85); + } + //printf("75GY %1.2f %1.2f %1.2f %1.2f\n",_75GY50[44],_75GY50[84],_75GY50[125],_75GY50[139] ); + _75GY60(maxInd); + _75GY60.clear(); + for (int i=0; i5) _75GY60[i] = 2.30 - 0.00125*(i-5); + else if (i<85 && i>=45) _75GY60[i] = 2.25-0.001*(i-45); + else if (i<140 && i >=85) _75GY60[i] = 2.21-0.0027*(i-85); + } + //printf("75GY %1.2f %1.2f %1.2f\n",_75GY60[44],_75GY60[84],_75GY60[125] ); + _75GY70(maxInd); + _75GY70.clear(); + for (int i=0; i5) _75GY70[i] = 2.29 - 0.00125*(i-5); + else if (i<85 && i>=45) _75GY70[i] = 2.24-0.0015*(i-45); + else if (i<140 && i >=85) _75GY70[i] = 2.18-0.00175*(i-85); + } + //printf("75GY %1.2f %1.2f %1.2f\n",_75GY70[44],_75GY70[84],_75GY70[125] ); + _75GY80(maxInd); + _75GY80.clear(); + for (int i=0; i5) _75GY80[i] = 2.27 - 0.001*(i-5); + else if (i<85 && i>=45) _75GY80[i] = 2.23 - 0.001*(i-45); + else if (i<140 && i >=85) _75GY80[i] = 2.19-0.00175*(i-85); + } + //printf("75GY %1.2f %1.2f %1.2f\n",_75GY80[44],_75GY80[84],_75GY80[125] ); + + + //55GY + _5GY30(maxInd2); + _5GY30.clear(); + for (int i=0; i5) _5GY30[i] = 2.16 - 0.002*(i-5); + else if (i<90 && i>=45) _5GY30[i] = 2.07-0.0025*(i-45); + } + //printf("5GY %1.2f %1.2f\n",_5GY30[44],_5GY30[84] ); + + //5GY4: 2.14,2.04, 1.96, 1.91 //95 + + _5GY40(maxInd2); + _5GY40.clear(); + for (int i=0; i5) _5GY40[i] = 2.14 - 0.0025*(i-5); + else if (i<90 && i>=45) _5GY40[i] = 2.04-0.003*(i-45); + } + //printf("5GY %1.2f %1.2f \n",_5GY40[44],_5GY40[84] ); + _5GY50(maxInd); + _5GY50.clear(); + for (int i=0; i5) _5GY50[i] = 2.13 - 0.00175*(i-5); + else if (i<85 && i>=45) _5GY50[i] = 2.06-0.002*(i-45); + else if (i<140 && i >=85) _5GY50[i] = 1.98-0.00225*(i-85); + } + //printf("5GY %1.2f %1.2f %1.2f\n",_5GY50[44],_5GY50[84],_5GY50[125] ); + _5GY60(maxInd); + _5GY60.clear(); + for (int i=0; i5) _5GY60[i] = 2.11 - 0.0015*(i-5); + else if (i<85 && i>=45) _5GY60[i] = 2.05-0.002*(i-45); + else if (i<140 && i >=85) _5GY60[i] = 1.97-0.00275*(i-85); + } + //printf("5GY %1.2f %1.2f %1.2f\n",_5GY60[44],_5GY60[84],_5GY60[125] ); + _5GY70(maxInd); + _5GY70.clear(); + for (int i=0; i5) _5GY70[i] = 2.09 - 0.001*(i-5); + else if (i<85 && i>=45) _5GY70[i] = 2.05-0.00175*(i-45); + else if (i<140 && i >=85) _5GY70[i] = 1.98-0.002*(i-85); + } + //printf("5GY %1.2f %1.2f %1.2f\n",_5GY70[44],_5GY70[84],_5GY70[125] ); + _5GY80(maxInd); + _5GY80.clear(); + for (int i=0; i5) _5GY80[i] = 2.07 - 0.001*(i-5); + else if (i<85 && i>=45) _5GY80[i] = 2.03 - 0.00075*(i-45); + else if (i<140 && i >=85) _5GY80[i] = 2.0-0.002*(i-85); + } + //printf("5GY %1.2f %1.2f %1.2f\n",_5GY80[44],_5GY80[84],_5GY80[125] ); + + #ifdef _DEBUG + t2e.set(); + if (settings->verbose) + printf("Lutf Munsell %d usec\n", t2e.etime(t1e)); + #endif + } + +} diff --git a/rtengine/color.h b/rtengine/color.h new file mode 100644 index 000000000..cae156375 --- /dev/null +++ b/rtengine/color.h @@ -0,0 +1,1311 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ + +#ifndef _COLOR_H_ +#define _COLOR_H_ + +#include "rt_math.h" +#include "LUT.h" +#include "labimage.h" +#include "iccstore.h" +#include "iccmatrices.h" +#include "sleef.c" +#define SAT(a,b,c) ((float)max(a,b,c)-(float)min(a,b,c))/(float)max(a,b,c) + +namespace rtengine { + +#ifdef _DEBUG + +class MunsellDebugInfo { +public: + float maxdhuelum[4]; + float maxdhue[4]; + unsigned int depass; + unsigned int depassLum; + + MunsellDebugInfo(); + void reinitValues(); +}; + +#endif + +class Color { + +private: + // Jacques' 195 LUTf for Munsell Lch correction + static LUTf _4P10,_4P20,_4P30,_4P40,_4P50,_4P60; + static LUTf _1P10,_1P20,_1P30,_1P40,_1P50,_1P60; + static LUTf _5B40,_5B50,_5B60, _5B70,_5B80; + static LUTf _7B40,_7B50,_7B60, _7B70,_7B80; + static LUTf _9B40,_9B50,_9B60, _9B70,_9B80; + static LUTf _10B40,_10B50,_10B60, _10B70,_10B80; + static LUTf _05PB40,_05PB50,_05PB60, _05PB70,_05PB80; + static LUTf _10PB10,_10PB20,_10PB30,_10PB40,_10PB50,_10PB60; + static LUTf _9PB10,_9PB20,_9PB30,_9PB40,_9PB50,_9PB60,_9PB70,_9PB80; + static LUTf _75PB10,_75PB20,_75PB30,_75PB40,_75PB50,_75PB60,_75PB70,_75PB80; + static LUTf _6PB10,_6PB20,_6PB30,_6PB40,_6PB50,_6PB60,_6PB70,_6PB80; + static LUTf _45PB10,_45PB20,_45PB30,_45PB40,_45PB50,_45PB60,_45PB70,_45PB80; + static LUTf _3PB10,_3PB20,_3PB30,_3PB40,_3PB50,_3PB60,_3PB70,_3PB80; + static LUTf _15PB10,_15PB20,_15PB30,_15PB40,_15PB50,_15PB60, _15PB70,_15PB80; + static LUTf _10YR20, _10YR30, _10YR40,_10YR50,_10YR60,_10YR70,_10YR80,_10YR90; + static LUTf _85YR20, _85YR30, _85YR40,_85YR50,_85YR60,_85YR70,_85YR80,_85YR90; + static LUTf _7YR30, _7YR40,_7YR50,_7YR60,_7YR70,_7YR80; + static LUTf _55YR30, _55YR40,_55YR50,_55YR60,_55YR70,_55YR80,_55YR90; + static LUTf _4YR30, _4YR40,_4YR50,_4YR60,_4YR70,_4YR80; + static LUTf _25YR30, _25YR40,_25YR50,_25YR60,_25YR70; + static LUTf _10R30, _10R40,_10R50,_10R60,_10R70; + static LUTf _9R30, _9R40,_9R50,_9R60,_9R70; + static LUTf _7R30, _7R40,_7R50,_7R60,_7R70; + static LUTf _5R10, _5R20,_5R30; + static LUTf _25R10, _25R20,_25R30; + static LUTf _10RP10, _10RP20,_10RP30; + static LUTf _7G30, _7G40,_7G50,_7G60,_7G70,_7G80; + static LUTf _5G30, _5G40,_5G50,_5G60,_5G70,_5G80; + static LUTf _25G30, _25G40,_25G50,_25G60,_25G70,_25G80; + static LUTf _1G30, _1G40,_1G50,_1G60,_1G70,_1G80; + static LUTf _10GY30, _10GY40,_10GY50,_10GY60,_10GY70,_10GY80; + static LUTf _75GY30, _75GY40,_75GY50,_75GY60,_75GY70,_75GY80; + static LUTf _5GY30, _5GY40,_5GY50,_5GY60,_5GY70,_5GY80; + + // Separated from init() to keep the code clear + static void initMunsell (); + static double hue2rgb(double p, double q, double t); + +public: + + typedef enum Channel { + CHANNEL_RED = 1<<0, + CHANNEL_GREEN = 1<<1, + CHANNEL_BLUE = 1<<2, + CHANNEL_HUE = 1<<3, + CHANNEL_SATURATION = 1<<4, + CHANNEL_VALUE = 1<<5, + CHANNEL_LIGHTNESS = 1<<6, + CHANNEL_CHROMATICITY = 1<<7 + } eChannel; + + typedef enum InterpolationPath { + IP_SHORTEST, /// Interpolate color using the shortest path between 2 hues + IP_LONGEST, /// Interpolate color using the longest path between 2 hues + } eInterpolationPath; + + typedef enum InterpolationDirection { + ID_UP, /// Interpolate color by increasing the hue value, crossing the upper limit + ID_DOWN /// Interpolate color by decreasing the hue value, crossing the lower limit + } eInterpolationDirection; + + const static double sRGBGamma; // standard average gamma + const static double sRGBGammaCurve; // 2.4 in the curve + const static double eps, eps_max, kappa, epskap; + const static float D50x, D50z; + const static double u0, v0; + + static cmsToneCurve* linearGammaTRC; + + static LUTf cachef; + static LUTf gamma2curve; + + // look-up tables for the standard srgb gamma and its inverse (filled by init()) + static LUTf igammatab_srgb; + static LUTf gammatab_srgb; +// static LUTf igammatab_709; +// static LUTf gammatab_709; + static LUTf igammatab_55; + static LUTf gammatab_55; + static LUTf igammatab_4; + static LUTf gammatab_4; + + static LUTf igammatab_26_11; + static LUTf gammatab_26_11; + static LUTf igammatab_24_17; + static LUTf gammatab_24_17a; + static LUTf gammatab_13_2; + + // look-up tables for the simple exponential gamma + static LUTf gammatab; + + + static void init (); + static void cleanup (); + + + /** + * @brief Extract luminance "sRGB" from red/green/blue values + * The range of the r, g and b channel has no importance ([0 ; 1] or [0 ; 65535]...) ; r,g,b can be negatives or > max, but must be in "sRGB" + * @param r red channel + * @param g green channel + * @param b blue channel + * @return luminance value + */ + // xyz_sRGBD65 : conversion matrix from XYZ to sRGB for D65 illuminant: we use diagonal values + static float rgbLuminance(float r, float g, float b) { + // WArning: The sum of xyz_sRGBd65[1][] is > 1.0 (i.e. 1.0000001), so we use our own adapted values) + // 0.2126729, 0.7151521, 0.0721750 + return r*0.2126729f + g*0.7151521f + b*0.0721750f; + } + static double rgbLuminance(double r, double g, double b) { + return r*0.2126729 + g*0.7151521 + b*0.0721750; + } + + + /** + * @brief Convert red/green/blue to hue/saturation/luminance + * @param r red channel [0 ; 65535] + * @param g green channel [0 ; 65535] + * @param b blue channel [0 ; 65535] + * @param h hue channel [0 ; 1] (return value) + * @param s saturation channel [0 ; 1] (return value) + * @param l luminance channel [0; 1] (return value) + */ + static void rgb2hsl (float r, float g, float b, float &h, float &s, float &l); + + + /** + * @brief Convert hue/saturation/luminance in red/green/blue + * @param h hue channel [0 ; 1] + * @param s saturation channel [0 ; 1] + * @param l luminance channel [0 ; 1] + * @param r red channel [0 ; 65535] (return value) + * @param g green channel [0 ; 65535] (return value) + * @param b blue channel [0 ; 65535] (return value) + */ + static void hsl2rgb (float h, float s, float l, float &r, float &g, float &b); + + /** + * @brief Convert hue/saturation/luminance in red/green/blue + * @param h hue channel [0 ; 1] + * @param s saturation channel [0 ; 1] + * @param l luminance channel [0 ; 1] + * @param r red channel [0 ; 1] (return value) + * @param g green channel [0 ; 1] (return value) + * @param b blue channel [0 ; 1] (return value) + */ + static void hsl2rgb01 (float h, float s, float l, float &r, float &g, float &b); + + + /** + * @brief Convert red green blue to hue saturation value + * @param r red channel [0 ; 65535] + * @param g green channel [0 ; 65535] + * @param b blue channel [0 ; 65535] + * @param h hue channel [0 ; 1] (return value) + * @param s saturation channel [0 ; 1] (return value) + * @param v value channel [0 ; 1] (return value) + */ + static void rgb2hsv (float r, float g, float b, float &h, float &s, float &v); + + + /** + * @brief Convert hue saturation value in red green blue + * @param h hue channel [0 ; 1] + * @param s saturation channel [0 ; 1] + * @param v value channel [0 ; 1] + * @param r red channel [0 ; 65535] (return value) + * @param g green channel [0 ; 65535] (return value) + * @param b blue channel [0 ; 65535] (return value) + */ + static void hsv2rgb (float h, float s, float v, float &r, float &g, float &b); + static void hsv2rgb (float h, float s, float v, int &r, int &g, int &b); + + + /** + * @brief Convert hue saturation value in red green blue + * @param h hue channel [0 ; 1] + * @param s saturation channel [0 ; 1] + * @param v value channel [0 ; 1] + * @param r red channel [0 ; 1] (return value) + * @param g green channel [0 ; 1] (return value) + * @param b blue channel [0 ; 1] (return value) + */ + static void hsv2rgb01 (float h, float s, float v, float &r, float &g, float &b); + + + /** + * @brief Convert xyz to red/green/blue + * Color space : sRGB - illuminant D50 - use matrix sRGB_xyz[] + * @param x X coordinate [0 ; 1] or [0 ; 65535] + * @param y Y coordinate [0 ; 1] or [0 ; 65535] + * @param z Z coordinate [0 ; 1] or [0 ; 65535] + * @param r red channel [same range than xyz channel] (return value) + * @param g green channel [same range than xyz channel] (return value) + * @param b blue channel [same range than xyz channel] (return value) + */ + static void xyz2srgb (float x, float y, float z, float &r, float &g, float &b); + + + /** + * @brief Convert xyz to red/green/blue + * Color space : Prophoto - illuminant D50 - use the Prophoto_xyz[] matrix + * @param x X coordinate [0 ; 1] or [0 ; 65535] + * @param y Y coordinate [0 ; 1] or [0 ; 65535] + * @param z Z coordinate [0 ; 1] or [0 ; 65535] + * @param r red channel [same range than xyz channel] (return value) + * @param g green channel [same range than xyz channel] (return value) + * @param b blue channel [same range than xyz channel] (return value) + */ + static void xyz2Prophoto (float x, float y, float z, float &r, float &g, float &b); + + + /** + * @brief Convert rgb in xyz + * Color space : Prophoto - illuminant D50 - use matrix xyz_prophoto[] + * @param r red channel [0 ; 1] or [0 ; 65535] (return value) + * @param g green channel [0 ; 1] or [0 ; 65535] (return value) + * @param b blue channel [0 ; 1] or [0 ; 65535] (return value) + * @param x X coordinate [same range than xyz channel] + * @param y Y coordinate [same range than xyz channel] + * @param z Z coordinate [same range than xyz channel] + */ + static void Prophotoxyz (float r, float g, float b, float &x, float &y, float &z); + + + /** + * @brief Convert xyz in rgb + * Color space : undefined - use adhoc matrix: rgb_xyz[3][3] (iccmatrice.h) in function of working space + * @param x X coordinate [0 ; 1] or [0 ; 65535] + * @param y Y coordinate [0 ; 1] or [0 ; 65535] + * @param z Z coordinate [0 ; 1] or [0 ; 65535] + * @param r red channel [same range than xyz channel] (return value) + * @param g green channel [same range than xyz channel] (return value) + * @param b blue channel [same range than xyz channel] (return value) + * @param rgb_xyz[3][3] transformation matrix to use for the conversion + */ + static void xyz2rgb (float x, float y, float z, float &r, float &g, float &b, const double rgb_xyz[3][3]); + static void xyz2rgb (float x, float y, float z, float &r, float &g, float &b, const float rgb_xyz[3][3]); + + + /** + * @brief Convert rgb in xyz + * Color space : undefined - use adhoc matrix : xyz_rgb[3][3] (iccmatrice.h) in function of working space + * @param r red channel [0 ; 1] or [0 ; 65535] + * @param g green channel [0 ; 1] or [0 ; 65535] + * @param b blue channel [0 ; 1] or [0 ; 65535] + * @param x X coordinate [same range than rgb channel] (return value) + * @param y Y coordinate [same range than rgb channel] (return value) + * @param z Z coordinate [same range than rgb channel] (return value) + * @param xyz_rgb[3][3] transformation matrix to use for the conversion + */ + static void rgbxyz (float r, float g, float b, float &x, float &y, float &z, const double xyz_rgb[3][3]); + static void rgbxyz (float r, float g, float b, float &x, float &y, float &z, const float xyz_rgb[3][3]); + + + /** + * @brief Convert Lab in xyz + * @param L L channel [0 ; 32768] ; L can be negative rarely or superior 32768 + * @param a channel [-42000 ; +42000] ; can be more than 42000 + * @param b channel [-42000 ; +42000] ; can be more than 42000 + * @param x X coordinate [0 ; 65535] ; can be negative! (return value) + * @param y Y coordinate [0 ; 65535] ; can be negative! (return value) + * @param z Z coordinate [0 ; 65535] ; can be negative! (return value) + */ + static void Lab2XYZ(float L, float a, float b, float &x, float &y, float &z); + +#ifdef __SSE2__ + static void Lab2XYZ(vfloat L, vfloat a, vfloat b, vfloat &x, vfloat &y, vfloat &z); +#endif // __SSE2__ + + /** + * @brief Convert xyz in Lab + * @param x X coordinate [0 ; 65535] ; can be negative or superior to 65535 + * @param y Y coordinate [0 ; 65535] ; can be negative or superior to 65535 + * @param z Z coordinate [0 ; 65535] ; can be negative or superior to 65535 + * @param L L channel [0 ; 32768] ; L can be negative rarely or superior 32768 (return value) + * @param a channel [-42000 ; +42000] ; can be more than 42000 (return value) + * @param b channel [-42000 ; +42000] ; can be more than 42000 (return value) + */ + static void XYZ2Lab(float x, float y, float z, float &L, float &a, float &b); + + + /** + * @brief Convert Lab in Yuv + * @param L L channel [0 ; 32768] ; L can be negative rarely or superior 32768 + * @param a channel [-42000 ; +42000] ; can be more than 42000 + * @param b channel [-42000 ; +42000] ; can be more than 42000 + * @param Y luminance channel [0 ; 65535] (return value) + * @param u red chrominance channel [0 ; 65535] (return value) + * @param v blue chrominance channel [0 ; 65535] (return value) + */ + static void Lab2Yuv(float L, float a, float b, float &Y, float &u, float &v); + + + /** + * @brief Convert Yuv in Lab + * @param Y luminance channel [0 ; 65535] + * @param u red chrominance channel [0 ; 65535] + * @param v blue chrominance channel [0 ; 65535] + * @param L L channel [0 ; 32768] ; L can be negative rarely or superior 32768 (return value) + * @param a channel [-42000 ; +42000] ; can be more than 42000 (return value) + * @param b channel [-42000 ; +42000] ; can be more than 42000 (return value) + */ + static void Yuv2Lab(float Y, float u, float v, float &L, float &a, float &b, double wp[3][3]); + + + /** + * @brief Convert the 'a' and 'b' channels of the L*a*b color space to 'c' and 'h' channels of the Lch color space (channel 'L' is identical [0 ; 32768]) + * @param a 'a' channel [-42000 ; +42000] ; can be more than 42000 + * @param b 'b' channel [-42000 ; +42000] ; can be more than 42000 + * @param c 'c' channel return value, in [0 ; 42000] ; can be more than 42000 (return value) + * @param h 'h' channel return value, in [-PI ; +PI] (return value) + */ + static void Lab2Lch(float a, float b, float &c, float &h); + + + /** + * @brief Convert 'c' and 'h' channels of the Lch color space to the 'a' and 'b' channels of the L*a*b color space (channel 'L' is identical [0 ; 32768]) + * @param c 'c' channel value, in [0 ; 42000] + * @param h 'h' channel value, in [-PI ; +PI] + * @param a 'a' channel [-42000 ; +42000] ; can be more than 42000 (return value) + * @param b 'b' channel [-42000 ; +42000] ; can be more than 42000 (return value) + */ + static void Lch2Lab(float c, float h, float &a, float &b); + + + /** + * @brief Convert the 'u' and 'v' channels of the Luv color space to 'c' and 'h' channels of the Lch color space ('L' channel is identical) + * @param u 'u' channel [unknown range!] + * @param v 'v' channel [unknown range!] + * @param c 'c' channel [unknown range!] (return value) + * @param h 'h' channel [-PI ; +PI] (return value) + */ + static void Luv2Lch(float u, float v, float &c, float &h); + + + /** + * @brief Convert 'c' and 'h' channels of the Lch color space to the 'u' and 'v' channels of the Luv color space ('L' channel is identical) + * @param c 'c' channel [unknown range!] ; can be more than 42000 + * @param h 'h' channel [-PI ; +PI] + * @param u 'u' channel [unknown range!] (return value) + * @param v 'v' channel [unknown range!] (return value) + */ + static void Lch2Luv(float c, float h, float &u, float &v); + + + /** + * @brief Convert the XYZ values to Luv values + * Warning: this method has never been used/tested so far + * @param x X coordinate [0 ; 65535] ; can be negative or superior to 65535 + * @param y Y coordinate [0 ; 65535] ; can be negative or superior to 65535 + * @param z Z coordinate [0 ; 65535] ; can be negative or superior to 65535 + * @param L 'L' channel [0 ; 32768] (return value) + * @param u 'u' channel [-42000 ; 42000] ; can be more than 42000 (return value) + * @param v 'v' channel [-42000 ; 42000] ; can be more than 42000 (return value) + */ + static void XYZ2Luv (float X, float Y, float Z, float &L, float &u, float &v); + + + /** + * @brief Convert the Luv values to XYZ values + * Warning: this method has never been used/tested so far + * @param L 'L' channel [0 ; 32768] + * @param u 'u' channel [-42000 ; 42000] ; can be more than 42000 + * @param v 'v' channel [-42000 ; 42000] ; can be more than 42000 + * @param x X coordinate [0 ; 65535] ; can be negative or superior to 65535 (return value) + * @param y Y coordinate [0 ; 65535] ; can be negative or superior to 65535 (return value) + * @param z Z coordinate [0 ; 65535] ; can be negative or superior to 65535 (return value) + */ + static void Luv2XYZ (float L, float u, float v, float &X, float &Y, float &Z); + + + /** + * @brief Return "f" in function of CIE's kappa and epsilon constants + * @param f f can be fx fy fz where: + * fx=a/500 + fy a=chroma green red [-128 ; +128] + * fy=(L+16)/116 L=luminance [0 ; 100] + * fz=fy-b/200 b=chroma blue yellow [-128 ; +128] + */ + static inline double f2xyz(double f) { + const double epsilonExpInv3 = 6.0/29.0; + const double kappaInv = 27.0/24389.0; // inverse of kappa + + return (f > epsilonExpInv3) ? f*f*f : (116. * f - 16.) * kappaInv; + + } + static inline float f2xyz(float f) { + const float epsilonExpInv3 = 0.20689655f; // 6.0f/29.0f; + const float kappaInv = 0.0011070565f; // 27.0f/24389.0f; // inverse of kappa + + return (f > epsilonExpInv3) ? f*f*f : (116.f * f - 16.f) * kappaInv; + } +#ifdef __SSE2__ + static inline vfloat f2xyz(vfloat f) { + const vfloat epsilonExpInv3 = F2V(0.20689655f); // 6.0f/29.0f; + const vfloat kappaInv = F2V(0.0011070565f); // 27.0f/24389.0f; // inverse of kappa + vfloat res1 = f*f*f; + vfloat res2 = (F2V(116.f) * f - F2V(16.f)) * kappaInv; + return vself(vmaskf_gt(f, epsilonExpInv3), res1, res2); + } +#endif + + /** + * @brief Calculate the effective direction (up or down) to linearly interpolating 2 colors so that it follows the shortest or longest path + * @param h1 First hue [0 ; 1] + * @param h2 Second hue [0 ; 1] + * @param path Path to follow (shortest/longest) + * @return The interpolation direction + */ + static inline eInterpolationDirection getHueInterpolationDirection (double h1, double h2, eInterpolationPath path) { + if (path==IP_SHORTEST) { + if (h2>h1) { + if (h2-h1<=0.5) + return ID_UP; + else + return ID_DOWN; + } + else { + if (h1-h2<=0.5) + return ID_DOWN; + else + return ID_UP; + } + } + else { + if (h2>h1) { + if (h2-h1<=0.5) + return ID_DOWN; + else + return ID_UP; + } + else { + if (h1-h2<=0.5) + return ID_UP; + else + return ID_DOWN; + } + } + } + + + /** + * @brief Calculate a color by linearly interpolating 2 colors + * @param h1 First hue + * @param h2 Second hue + * @param balance Factor from 0 (first hue) to 1 (second hue) + * @param dir Tells which direction the interpolation have to follow. You can get the value with getHueInterpolationDirection + * @return The interpolated hue + */ + static inline double interpolateHueHSV (double h1, double h2, double balance, eInterpolationDirection dir) { + if (h1==h2) + return h1; + if (dir==ID_DOWN) { + if (h1 < h2){ + double temp = h1; + h1 = h2-1.; + h2 = temp; + balance = 1. - balance; + } + double h3 = h1 + balance * (h2-h1); + if (h3<0.) + h3 += 1.; + return h3; + } + else { + if (h1 > h2){ + h2 += 1.; + } + double h3 = h1 + balance * (h2-h1); + if (h3>1.) + h3 -= 1.; + return h3; + } + } + + /** + * @brief Interpolate 2 colors from their respective red/green/blue channels, with a balance factor + * @param balance gives weight to the first and second color [0 ; 1] + * 0. = output color == first color + * 0.5 = output color == equally mixed colors + * 1. = output color == second color + * @param r1 red channel of color 1 [0 ; 65535] + * @param g1 green channel of color 1 [0 ; 65535] + * @param b1 blue channel of color 1 [0 ; 65535] + * @param r2 red channel of color 2 [0 ; 65535] + * @param g2 green channel of color 2 [0 ; 65535] + * @param b2 blue channel of color 2 [0 ; 65535] + * @param channels bitfield of channel to interpolate (CHANNEL_LIGHTNESS|CHANNEL_CHROMATICITY|CHANNEL_HUE) + * @param xyz_rgb color space + * @param ro red channel of output color [0 ; 65535] (return value) + * @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 (const float balance, const float r1, const float g1, const float b1, const float r2, const float g2, const float b2, int channels, const double xyz_rgb[3][3], const double rgb_xyz[3][3], float &ro, float &go, float &bo); + + /** + * @brief Interpolate 2 colors from their respective red/green/blue channels, with a balance factor + * @param realL luminance hsl [0; 1] + * @param iplow low luminance for rl [0;1] + * @param ihigh high luminance for r2 [0;1] + * @param algm algorithm [0;2] + * @param balance gives weight to the first and second color [0 ; 1] + * 0. = output color == first color + * 0.5 = output color == equally mixed colors + * 1. = output color == second color + * @param twoc 2 colors or 512 int + * @param r1 red channel of color 1 [0 ; 65535] + * @param g1 green channel of color 1 [0 ; 65535] + * @param b1 blue channel of color 1 [0 ; 65535] + * @param rl red channel of color low [0 ; 65535] + * @param gl green channel of color low [0 ; 65535] + * @param bl blue channel of color low [0 ; 65535] + + * @param r2 red channel of color 2 or high[0 ; 65535] + * @param g2 green channel of color 2 or high[0 ; 65535] + * @param b2 blue channel of color 2 [or high 0 ; 65535] + * @param channels bitfield of channel to interpolate (CHANNEL_LIGHTNESS|CHANNEL_CHROMATICITY|CHANNEL_HUE) + * @param xyz_rgb color space + * @param rgb_xyz inverse color space + * @param ro red channel of output color [0 ; 65535] (return value) + * @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); + + + /** + * @brief Interpolate a hue value as the angle of a polar coordinate with hue in the [0;1] range + * Chose the shorter path from hue 1 to hue 2. + * @param h1 First hue [0; 1] + * @param h2 Second hue [0; 1] + * @param balance Interpolation factor [0 ; 1] where 0.=h1, 1.=h2 + * @return the interpolated value [0;1] + */ + /*template + static inline T interpolatePolarHue_01 (T h1, T h2, U balance) { + + if (h1==h2) + return h1; + if ((h1 > h2) && (h1-h2 > T(0.5))){ + h1 -= T(1.); + double value = h1 + T(balance) * (h2-h1); + if (value < T(0.)) + value += T(1.); + return value; + } + else if (h2-h1 > T(0.5)) { + h2 -= T(1.); + double value = h1 + T(balance) * (h2-h1); + if (value < T(0.)) + value += T(1.); + return value; + } + else + return h1 + T(balance) * (h2-h1); + }*/ + + + /** + * @brief Interpolate a hue value as the angle of a polar coordinate with hue in the [-PI ; +PI] range + * Chose the shorter path from hue 1 to hue 2. + * @param h1 First hue [-PI ; +PI] + * @param h2 Second hue [-PI ; +PI] + * @param balance Interpolation factor [0 ; 1] where 0.=h1, 1.=h2 + * @return the interpolated value [-PI ; +PI] + */ + /*template + static inline T interpolatePolarHue_PI (T h1, T h2, U balance) { + if (h1==h2) + return h1; + if ((h1 > h2) && (h1-h2 > T(M_PI))){ + h1 -= T(2*M_PI); + T value = h1 + T(balance) * (h2-h1); + if (value < T(-M_PI)) + value += T(2*M_PI); + return value; + } + else if (h2-h1 > T(M_PI)) { + h2 -= T(2*M_PI); + T value = h1 + T(balance) * (h2-h1); + if (value < T(0)) + value += T(2*M_PI); + return value; + } + else + return h1 + T(balance) * (h2-h1); + }*/ + + + /** + * @brief Interpolate a hue value as the angle of a polar coordinate with hue in the [0;1] range + * Chose the shorter path from hue 1 to hue 2. + * @param h1 First hue [0; 1] + * @param h2 Second hue [0; 1] + * @param balance Interpolation factor [0 ; 1] where 0.=h1, 1.=h2 + * @return the interpolated value [0;1] + */ + template + static inline T interpolatePolarHue_01 (T h1, T h2, U balance) { + float d = h2 - h1; + float f; + f=T(balance); + double h; + if (h1 > h2){ + std::swap(h1,h2); + d = -d; + f=1.f-f; + } + if (d < T(-M_PI) || d < T(0) || d > T(M_PI)) { //there was an inversion here !! d > T(M_PI) + h1 += T(2*M_PI); + h = h1 + f*(h2-h1); + h = std::fmod(h,2*M_PI); + } + else h = h1 + f * d; + // not strictly necessary..but in case of + if(h < T(-M_PI)) h=T(2*M_PI)-h; + if(h > T(M_PI)) h=h-T(2*M_PI); + + return h; + } + + + /** + * @brief Interpolate a hue value as the angle of a polar coordinate with hue in the [-PI ; +PI] range + * Chose the shorter path from hue 1 to hue 2. + * @param h1 First hue [-PI ; +PI] + * @param h2 Second hue [-PI ; +PI] + * @param balance Interpolation factor [0 ; 1] where 0.=h1, 1.=h2 + * @return the interpolated value [-PI ; +PI ] + */ + template + static inline T interpolatePolarHue_PI (T h1, T h2, U balance) { + float d = h2 - h1; + float f; + f=T(balance); + double h; + if (h1 > h2){ + std::swap(h1,h2); + d = -d; + f=1.f-f; + } + if (d < T(0) || d < T(0.5) || d > T(1.)) { //there was an inversion here !! d > T(M_PI) + h1 += T(1.); + h = h1 + f*(h2-h1); + h = std::fmod(h,1.); + } + else h = h1 + f * d; + // not strictly necessary..but in case of + if(h < T(0)) h=T(1.)-h; + if(h > T(1)) h=h-T(1.); + + return h; + } + + + /** + * @brief Get the gamma curves' parameters used by LCMS2 + * @param pwr gamma value [>1] + * @param ts slope [0 ; 20] + * @param mode [always 0] + * @imax imax [always 0] + * @param gamma0 used in ip2Lab2rgb [0 ; 1], usually near 0.5 (return value) + * @param gamma1 used in ip2Lab2rgb [0 ; 20], can be superior to 20, but it's quite unusual(return value) + * @param gamma2 used in ip2Lab2rgb [0 ; 1], usually near 0.03(return value) + * @param gamma3 used in ip2Lab2rgb [0 ; 1], usually near 0.003(return value) + * @param gamma4 used in ip2Lab2rgb [0 ; 1], usually near 0.03(return value) + * @param gamma5 used in ip2Lab2rgb [0 ; 1], usually near 0.5 (return value) + */ + static void calcGamma (double pwr, double ts, int mode, int imax, double &gamma0, double &gamma1, double &gamma2, double &gamma3, double &gamma4,double &gamma5); + + + /** + * @brief Used by Black and White to correct gamma for each channel red, green and blue channel + * @param r red channel input and output value [0 ; 65535] + * @param g green channel input and output value [0 ; 65535] + * @param b blue channel input and output value [0 ; 65535] + * @param gammabwr gamma value for red channel [>0] + * @param gammabwg gamma value for red channel [>0] + * @param gammabwb gamma value for red channel [>0] + */ + static void trcGammaBW (float &r, float &g, float &b, float gammabwr, float gammabwg, float gammabwb); + + + /** @brief Compute the B&W constants for the Black and White processing and its GUI + * @param setting main mode + * @param filter string of the filter effect to use + * @param algo choice between linear and special for OYCPM colors + * @param mixerRed red channel value of the channel mixer [-100 ; +200] + * @param mixerGreen green channel value of the channel mixer [-100 ; +200] + * @param mixerBlue blue channel value of the channel mixer [-100 ; +200] + * @param mixerOrange orange channel value of the channel mixer [-100 ; +200] + * @param mixerYellow yellow channel value of the channel mixer [-100 ; +200] + * @param mixerCyan cyan channel value of the channel mixer [-100 ; +200] + * @param mixerPurple purple channel value of the channel mixer [-100 ; +200] + * @param mixerMagenta magenta channel value of the channel mixer [-100 ; +200] + * @param autoc automatic mode of the channel mixer + * @param complement adjust complementary channel + * @param kcorec in absolute mode, value to correct the mixer [1 ; 3], usually near 1 (return value) + * @param rrm red channel of the mixer (return value) + * @param ggm green channel of the mixer (return value) + * @param bbm blue channel of the mixer (return value) + */ + static void computeBWMixerConstants (const Glib::ustring &setting, const Glib::ustring &filter, const Glib::ustring &algo, float &filcor, float &mixerRed, float &mixerGreen, + float &mixerBlue, float mixerOrange, float mixerYellow, float mixerCyan, float mixerPurple, float mixerMagenta, + bool autoc, bool complement, float &kcorec, double &rrm, double &ggm, double &bbm); + + + // standard srgb gamma and its inverse + + /** + * @brief sRGB gamma + * See also calcGamma above with the following values: pwr=2.4 ts=12.92 mode=0.003041 imax=0.055011 + * @param x red, green or blue channel's value [0 ; 1] + * @return the gamma modified's value [0 ; 1] + */ + static inline double gamma2 (double x) { // g3 1+g4 + return x <= 0.003041 ? x*12.92 : 1.055011*exp(log(x)/sRGBGammaCurve)-0.055011; + } + + + /** + * @brief Inverse sRGB gamma + * See also calcGamma above with the following values: pwr=2.4 ts=12.92 mode=0.003041 imax=0.055011 + * @param x red, green or blue channel's value [0 ; 1] + * @return the inverse gamma modified's value [0 ; 1] + */ + static inline double igamma2 (double x) { //g2 + return x <= 0.039293 ? x/12.92 : exp(log((x+0.055011)/1.055011)*sRGBGammaCurve); + } + + + /** + * @brief Get the gamma value for Gamma=5.5 Slope=10 + * @param x red, green or blue channel's value [0 ; 1] + * @return the gamma modified's value [0 ; 1] + */ + static inline double gamma55 (double x) { // g3 1+g4 + return x <= 0.013189 ? x*10.0 : 1.593503*exp(log(x)/5.5)-0.593503;// 5.5 10 + } + + + /** + * @brief Get the inverse gamma value for Gamma=5.5 Slope=10 + * @param x red, green or blue channel's value [0 ; 1] + * @return the inverse gamma modified's value [0 ; 1] + */ + static inline double igamma55 (double x) { //g2 + return x <= 0.131889 ? x/10.0 : exp(log((x+0.593503)/1.593503)*5.5); // 5.5 10 + } + + + /** + * @brief Get the gamma value for Gamma=4 Slope=5 + * @param x red, green or blue channel's value [0 ; 1] + * @return the gamma modified's value [0 ; 1] + */ + static inline double gamma4 (double x) { // g3 1+g4 + return x <= 0.03089 ? x*5.0 : 1.478793*exp(log(x)/4.1)-0.478793;// 4 5 + } + + + /** + * @brief Get the inverse gamma value for Gamma=4 Slope=5 + * @param x red, green or blue channel's value [0 ; 1] + * @return the inverse gamma modified's value [0 ; 1] + */ + static inline double igamma4 (double x) { //g2 + return x <= 0.154449 ? x/5.0 : exp(log((x+0.478793)/1.478793)*4.1);// 4 5 + } + + + /* + * @brief Get the gamma value for Gamma=2.2 Slope=4.5 + * @param x red, green or blue channel's value [0 ; 1] + * @return the gamma modified's value [0 ; 1] + * + static inline double gamma709 (double x) { + return x <= 0.0176 ? x*4.5 : 1.0954*exp(log(x)/2.2)-0.0954; + } + + * @brief Get the inverse gamma value for Gamma=2.2 Slope=4.5 + * @param x red, green or blue channel's value [0 ; 1] + * @return the inverse gamma modified's value [0 ; 1] + * + static inline double igamma709 (double x) { + return x <= 0.0795 ? x/4.5 : exp(log((x+0.0954)/1.0954)*2.2); + } + */ + + + + /** + * @brief Get the gamma value for Gamma=2.4 Slope=17 + * @param x red, green or blue channel's value [0 ; 1] + * @return the gamma modified's value [0 ; 1] + */ + static inline double gamma24_17 (double x) { + return x <= 0.001867 ? x*17.0 : 1.044445*exp(log(x)/2.4)-0.044445; + } + + + /** + * @brief Get the inverse gamma value for Gamma=2.4 Slope=17 + * @param x red, green or blue channel's value [0 ; 1] + * @return the inverse gamma modified's value [0 ; 1] + */ + static inline double igamma24_17 (double x) { + return x <= 0.031746 ? x/17.0 : exp(log((x+0.044445)/1.044445)*2.4); + } + + + /** + * @brief Get the gamma value for Gamma=2.6 Slope=11 + * @param x red, green or blue channel's value [0 ; 1] + * @return the gamma modified's value [0 ; 1] + */ + static inline double gamma26_11 (double x) { + return x <= 0.004921 ? x*11.0 : 1.086603*exp(log(x)/2.6)-0.086603; + } + + + /** + * @brief Get the inverse gamma value for Gamma=2.6 Slope=11 + * @param x red, green or blue channel's value [0 ; 1] + * @return the inverse gamma modified's value [0 ; 1] + */ + static inline double igamma26_11 (double x) { + return x <= 0.054127 ? x/11.0 : exp(log((x+0.086603)/1.086603)*2.6); + } + /** + * @brief Get the gamma value for Gamma=1.3 Slope=2 + * @param x red, green or blue channel's value [0 ; 1] + * @return the gamma modified's value [0 ; 1] + */ + static inline double gamma13_2 (double x) { + return x <= 0.016613 ? x*2.0 : 1.009968*exp(log(x)/1.3)-0.016613; + } + + + // gamma function with adjustable parameters + //same as above with values calculate with Calcgamma above + // X range 0..1 + static inline double gamma (double x, double gamma, double start, double slope, double mul, double add){ + return (x <= start ? x*slope : exp(log(x)/gamma)*mul-add); + } + static inline double igamma (double x, double gamma, double start, double slope, double mul, double add){ + return (x <= start*slope ? x/slope : exp(log((x+add)/mul)*gamma) ); + } + + + /** + * @brief Very basic gamma + * @param x red, green or blue channel's value [0 ; 1] + * @param gamma gamma value [1 ; 5] + * @return the gamma modified's value [0 ; 1] + */ + static inline double gamman (double x, double gamma) { //standard gamma without slope... + return (x =exp(log(x)/gamma)); + } + + /** + * @brief Very basic gamma + * @param x red, green or blue channel's value [0 ; 1] + * @param gamma gamma value [1 ; 5] + * @return the gamma modified's value [0 ; 1] + */ + static inline float gammanf (float x, float gamma) { //standard gamma without slope... + return (x =xexpf(xlogf(x)/gamma)); + } + + + /** + * @brief Very simply inverse gamma + * @param x red, green or blue channel's value [0 ; 1] + * @param gamma gamma value [1 ; 5] + * @return the inverse gamma modified's value [0 ; 1] + */ + static inline double igamman (double x, double gamma){ //standard inverse gamma without slope... + return (x = exp(log(x)*gamma) ); + } + + + /** + * @brief Get the gamma value out of look-up tables + * Calculated with gamma function above. e.g. : + * for (int i=0; i<65536; i++) + * gammatab_srgb[i] = (65535.0 * gamma2 (i/65535.0)); + * @param x [0 ; 1] + * @return the gamma modified's value [0 ; 65535] + */ + static inline float gamma_srgb (char x) { return gammatab_srgb[x]; } + static inline float gamma (char x) { return gammatab[x]; } + static inline float igamma_srgb (char x) { return igammatab_srgb[x]; } + static inline float gamma_srgb (int x) { return gammatab_srgb[x]; } + static inline float gamma (int x) { return gammatab[x]; } + static inline float igamma_srgb (int x) { return igammatab_srgb[x]; } + static inline float gamma_srgb (float x) { return gammatab_srgb[x]; } + static inline float gamma (float x) { return gammatab[x]; } + static inline float igamma_srgb (float x) { return igammatab_srgb[x]; } + //static inline float gamma_srgb (double x) { return gammatab_srgb[x]; } + //static inline float gamma (double x) { return gammatab[x]; } + //static inline float igamma_srgb (double x) { return igammatab_srgb[x]; } + + + + // -------------------------------- Jacques's Munsell correction + + + /** + * @brief Corrects the color (hue) depending on chromaticity and luminance changes + * + * To use in a "for" or "do while" statement. + * + * @param lumaMuns true => luminance correction (for delta L > 10) and chroma correction ; false => only chroma + * @param Lprov1 luminance after [0 ; 100] + * @param Loldd luminance before [0 ; 100] + * @param HH hue before [-PI ; +PI] + * @param Chprov1 chroma after [0 ; 180 (can be superior)] + * @param CC chroma before [0 ; 180] + * @param corectionHuechroma hue correction depending on chromaticity (saturation), in radians [0 ; 0.45] (return value) + * @param correctlum hue correction depending on luminance (brightness, contrast,...), in radians [0 ; 0.45] (return value) + * @param munsDbgInfo (Debug target only) object to collect informations + */ + +#ifdef _DEBUG + static void AllMunsellLch (bool lumaMuns, float Lprov1, float Loldd, float HH, float Chprov1, float CC, float &correctionHueChroma, float &correctlum, MunsellDebugInfo* munsDbgInfo); +#else + static void AllMunsellLch (bool lumaMuns, float Lprov1, float Loldd, float HH, float Chprov1, float CC, float &correctionHueChroma, float &correctlum); +#endif + + + /** + * @brief Correct chromaticity and luminance so that the color stays in the working profile's gamut + * + * This function puts the data (Lab) in the gamut of "working profile": + * it returns the corrected values of the chromaticity and luminance + * + * @param HH : hue, in radians [-PI ; +PI] + * @param Lprov1 : input luminance value, sent back corrected [0 ; 100] (input & output value) + * @param Chprov1: input chroma value, sent back corrected [0 ; 180 (can be superior)] (input & output value) + * @param R red value of the corrected color [0 ; 65535 but can be negative or superior to 65535] (return value) + * @param G green value of the corrected color [0 ; 65535 but can be negative or superior to 65535] (return value) + * @param B blue value of the corrected color [0 ; 65535 but can be negative or superior to 65535] (return value) + * @param wip working profile + * @param isHLEnabled true if "Highlight Reconstruction " is enabled + * @param lowerCoef a float number between [0.95 ; 1.0[ + * The nearest it is from 1.0, the more precise it will be, and the longer too as more iteration will be necessary + * @param higherCoef a float number between [0.95 ; 1.0[ + * The nearest it is from 1.0, the more precise it will be, and the longer too as more iteration will be necessary + * @param neg (Debug target only) to calculate iterations for negatives values + * @param moreRGB (Debug target only) to calculate iterations for values >65535 + */ +#ifdef _DEBUG + static void gamutLchonly (float HH, float &Lprov1, float &Chprov1, float &R, float &G, float &B, const double wip[3][3], const bool isHLEnabled, const float lowerCoef, const float higherCoef, bool &neg, bool &more_rgb); + static void gamutLchonly (float HH, float2 sincosval, float &Lprov1, float &Chprov1, float &R, float &G, float &B, const double wip[3][3], const bool isHLEnabled, const float lowerCoef, const float higherCoef, bool &neg, bool &more_rgb); + static void gamutLchonly (float2 sincosval, float &Lprov1, float &Chprov1, const float wip[3][3], const bool isHLEnabled, const float lowerCoef, const float higherCoef, bool &neg, bool &more_rgb); +#else + static void gamutLchonly (float HH, float &Lprov1, float &Chprov1, float &R, float &G, float &B, const double wip[3][3], const bool isHLEnabled, const float lowerCoef, const float higherCoef); + static void gamutLchonly (float HH, float2 sincosval,float &Lprov1, float &Chprov1, float &R, float &G, float &B, const double wip[3][3], const bool isHLEnabled, const float lowerCoef, const float higherCoef); + static void gamutLchonly (float2 sincosval, float &Lprov1, float &Chprov1, const float wip[3][3], const bool isHLEnabled, const float lowerCoef, const float higherCoef); +#endif + + + /** + * @brief Munsell gamut correction + * + * This function is the overall Munsell's corrections, but only on global statement. It may be better to use local statement with AllMunsellLch. + * They are named accordingly : gamutLchonly and AllMunsellLch + * It can be used before and after treatment (saturation, gamma, luminance, ...) + * + * @param labL L channel input and output image + * L channel's usual range is [0 ; 100], but values can be negative or >100 + * @param laba a channel input and output image + * @param labb b channel input and output image + * a and b channel's range is usually [-128 ; +128], but values can be >128 + * @param N Number of pixels to process + * @param corMunsell performs Munsell correction + * @param lumaMuns whether to apply luma correction or not (used only if corMuns=true) + * true: apply luma + chroma Munsell correction if delta L > 10; + * false: leaves luma untouched + * @param gamut performs gamutLch + * @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 ); + + + /* + * @brief Skin tone protection factor + * Skin colors: mixed from NX2 skin color palette, Von Luschan, and photos of white, black, yellow people... + * There are some little exceptions, but it should cover 99% case. + * Pay attention to white balance, and do not change hue and saturation, upstream of the modification + * Used by vibrance + * @param lum luma value [0 ; 100] + * @param hue hue value [-PI ; +PI] + * @param chrom chroma value [0 ; 180] + * @param satreduc [0.1 ; 1] (return value) + * @param chromx [0 or 1], actually only 0 is used + */ + static void SkinSat (float lum, float hue, float chrom, float &satreduc);//jacques Skin color + + + /** + * @brief Munsell Lch correction + * Find the right LUT and calculate the correction + * @param lum luma value [0 ; 100] + * @param hue hue value [-PI ; +PI] + * @param chrom chroma value [0 ; 180] + * @param memChprov store chroma [0 ; 180] + * @param correction correction value, in radians [0 ; 0.45] + * @param lbe hue in function of chroma, in radian [-PI ; +PI] + * @param zone [1 ; 4] 1=PB correction + sky 2=red yellow correction 3=Green yellow correction 4=Red purple correction + * @param correctL true=enable the Luminance correction + */ + static void MunsellLch (float lum, float hue, float chrom, float memChprov, float &correction, int zone, float &lbe, bool &correctL);//jacques: Munsell correction + + + // -------------------------------- end Munsell + + + static void scalered ( const float rstprotection, const float param, const float limit, const float HH, const float deltaHH, float &scale, float &scaleext); + static void transitred (const float HH, const float Chprov1, const float dred, const float factorskin, const float protect_red, const float factorskinext, const float deltaHH, const float factorsat, float &factor); + static void skinred ( double J, double h, double sres, double Sp, float dred, float protect_red, int sk, float rstprotection, float ko, double &s); + static void skinredfloat ( float J, float h, float sres, float Sp, float dred, float protect_red, int sk, float rstprotection, float ko, float &s); +// static void scaleredcdbl ( float skinprot, float param, float limit, float HH, float deltaHH, float &scale,float &scaleext); + + static inline void SkinSatCbdl (float lum, float hue, float chrom, float skinprot, float &scale, bool neg, float b_l, float t_l, float t_r) { + + static const float C9=8.f, C8=15.f, C7=12.f, C4=7.f, C3=5.f, C2=5.f, C1=5.f; + static const float H9=0.05f, H8=0.25f, H7=0.1f, H4=0.02f, H3=0.02f, H2=0.1f, H1=0.1f, H10=-0.2f,H11=-0.2f; + + // "real" skin color : take into account a slightly usage of contrast and saturation in RT if option "skin" = 1, uses imolicit factor 1.0 + // wide area skin color, useful if not accurate colorimetry or if the user has changed hue and saturation, uses explicit facor 0.6 + // wide area for transition, uses explicit factor 0.4 + + if (lum >= 85.0f) { + if((hue > (t_l+0.53f-H9) && hue < (t_r+H9)) && (chrom > 8.0f && chrom < (14.0f+C9))) scale = (100.f-skinprot)/100.1f; + else if (lum >= 92.0f) { + if((hue > t_l+0.4f && hue < t_r) && (chrom > 7.0f && chrom < (15.0f))) scale = (100.f-skinprot*0.6f)/100.1f; + else if ((hue > b_l && hue < t_r) && (chrom > 7.0f && chrom < (18.0f))) scale = (100.f-skinprot*0.4f)/100.1f; + } + else if ((hue > t_l+0.4f && hue < t_r-0.3f) && (chrom > 7.0f && chrom < (26.0f+C9))) scale = (100.f-skinprot*0.6f)/100.1f; + else if ((hue > b_l+0.05f && hue < t_r) && (chrom > 7.0f && chrom < (35.0f+C9))) scale = (100.f-skinprot*0.4f)/100.1f; + } + else if (lum >= 70.0f) { + if((hue > t_l+0.15f && hue < (t_r-0.2f+H8)) && (chrom > 8.0f && chrom < (35.0f+C8))) scale = (100.f-skinprot)/100.1f; + else if ((hue > (b_l+0.07f + H11) && hue < t_r-0.2f) && (chrom > 7.0f && chrom < (48.0f+C9) )) scale = (100.f-skinprot*0.6f)/100.1f; + else if ((hue > (b_l+0.07f + H11) && hue < t_r) && (chrom > 7.0f && chrom < (55.0f+C9) )) scale = (100.f-skinprot*0.4f)/100.1f; + } + else if (lum >= 52.0f) { + if((hue > t_l && hue < (t_r+H7)) && (chrom > 11.0f && chrom < (35.0f+C7))) scale = (100.f-skinprot)/100.1f; + else if ((hue > (b_l+0.07f + H11) && hue < t_r-0.2f) && (chrom > 7.0f && chrom < (48.0f+C9) )) scale = (100.f-skinprot*0.6f)/100.1f; + else if ((hue > (b_l+0.07f + H11) && hue < t_r) && (chrom > 7.0f && chrom < (55.0f+C9) )) scale = (100.f-skinprot*0.4f)/100.1f; + } + else if (lum >= 35.0f) { + if((hue > t_l && hue < (t_r+H4)) && (chrom > 13.0f && chrom < (37.0f+C4))) scale = (100.f-skinprot)/100.1f; + else if ((hue > (b_l+0.07f + H11) && hue < t_r-0.2f) && (chrom > 7.0f && chrom < (48.0f+C9) )) scale = (100.f-skinprot*0.6f)/100.1f; + else if ((hue > (b_l+0.07f + H11) && hue < t_r) && (chrom > 7.0f && chrom < (55.0f+C9) )) scale = (100.f-skinprot*0.4f)/100.1f; + } + else if (lum >= 20.0f) { + if((hue > t_l && hue < (t_r+H3)) && (chrom > 7.0f && chrom <(35.0f+C3) )) scale = (100.f-skinprot)/100.1f; + else if ((hue > (b_l+0.07f + H11) && hue < t_r-0.2f) && (chrom > 7.0f && chrom < (48.0f+C9) )) scale = (100.f-skinprot*0.6f)/100.1f; + else if ((hue > (b_l+0.07f + H11) && hue < t_r) && (chrom > 7.0f && chrom < (55.0f+C9) )) scale = (100.f-skinprot*0.4f)/100.1f; + } + else if (lum >= 10.0f) { + if((hue > (t_l-0.25f + H10) && hue < (t_r-0.3f +H2)) && (chrom > 8.0f && chrom < (23.0f+C2))) scale = (100.f-skinprot)/100.1f; + else if ((hue > (b_l+0.07f+H11) && hue < t_r-0.2f) && (chrom > 7.0f && chrom < (35.0f+C1) )) scale = (100.f-skinprot*0.6f)/100.1f; + else if ((hue > (b_l+0.07f+H11) && hue < t_r-0.1f) && (chrom > 7.0f && chrom < (45.0f+C1) )) scale = (100.f-skinprot*0.4f)/100.1f; + } + else if ((hue > (t_l -0.2f + H10) && hue < (t_r-0.3f+H1)) && (chrom > 8.0f && chrom < (23.0f+C1))) scale = (100.f-skinprot)/100.1f; + else if ((hue > (b_l+0.07f+H11) && hue < t_r-0.2f) && (chrom > 7.0f && chrom < (35.0f+C1) )) scale = (100.f-skinprot*0.6f)/100.1f; + else if ((hue > (b_l+0.07f+H11) && hue < t_r-0.1f) && (chrom > 7.0f && chrom < (45.0f+C1) )) scale = (100.f-skinprot*0.4f)/100.1f; + + //extended zone for hair, beard and if user adjust high value for skinprot + if(skinprot > 85.f && chrom < 20.f && neg) { + float modula = -0.0666f * skinprot + 6.66f; + scale *= modula; + } + } + + static inline void SkinSatCbdl2 (float lum, float hue, float chrom, float skinprot, float &scale, bool neg, float b_l, float t_l, float t_r, float b_r, int basc) { + + static const float C9=8.f, C8=15.f, C7=12.f, C4=7.f, C3=5.f, C2=5.f, C1=5.f; + static const float H9=0.05f, H8=0.25f, H7=0.1f, H4=0.02f, H3=0.02f, H2=0.1f, H1=0.1f, H10=-0.2f,H11=-0.2f; + + // "real" skin color : take into account a slightly usage of contrast and saturation in RT if option "skin" = 1, uses imolicit factor 1.0 + // wide area skin color, useful if not accurate colorimetry or if the user has changed hue and saturation, uses explicit facor 0.6 + // wide area for transition, uses explicit factor 0.4 + if((b_l > -0.3f && b_r < 2.f) || basc==0) { //range maxi skin + if (lum >= 85.0f) { + if((hue > (t_l+0.53f-H9) && hue < (t_r+H9)) && (chrom > 8.0f && chrom < (14.0f+C9))) scale = (100.f-skinprot)/100.1f; + else if (lum >= 92.0f) { + if((hue > t_l+0.4f && hue < t_r) && (chrom > 7.0f && chrom < (15.0f))) scale = (100.f-skinprot*0.6f)/100.1f; + else if ((hue > b_l && hue < t_r) && (chrom > 7.0f && chrom < (18.0f))) scale = (100.f-skinprot*0.4f)/100.1f; + } + else if ((hue > t_l+0.4f && hue < t_r-0.3f) && (chrom > 7.0f && chrom < (26.0f+C9))) scale = (100.f-skinprot*0.6f)/100.1f; + else if ((hue > b_l+0.05f && hue < t_r) && (chrom > 7.0f && chrom < (35.0f+C9))) scale = (100.f-skinprot*0.4f)/100.1f; + } + else if (lum >= 70.0f) { + if((hue > t_l+0.15f && hue < (t_r-0.2f+H8)) && (chrom > 8.0f && chrom < (35.0f+C8))) scale = (100.f-skinprot)/100.1f; + else if ((hue > (b_l+0.07f + H11) && hue < t_r-0.2f) && (chrom > 7.0f && chrom < (48.0f+C9) )) scale = (100.f-skinprot*0.6f)/100.1f; + else if ((hue > (b_l+0.07f + H11) && hue < t_r) && (chrom > 7.0f && chrom < (55.0f+C9) )) scale = (100.f-skinprot*0.4f)/100.1f; + } + else if (lum >= 52.0f) { + if((hue > t_l && hue < (t_r+H7)) && (chrom > 11.0f && chrom < (35.0f+C7))) scale = (100.f-skinprot)/100.1f; + else if ((hue > (b_l+0.07f + H11) && hue < t_r-0.2f) && (chrom > 7.0f && chrom < (48.0f+C9) )) scale = (100.f-skinprot*0.6f)/100.1f; + else if ((hue > (b_l+0.07f + H11) && hue < t_r) && (chrom > 7.0f && chrom < (55.0f+C9) )) scale = (100.f-skinprot*0.4f)/100.1f; + } + else if (lum >= 35.0f) { + if((hue > t_l && hue < (t_r+H4)) && (chrom > 13.0f && chrom < (37.0f+C4))) scale = (100.f-skinprot)/100.1f; + else if ((hue > (b_l+0.07f + H11) && hue < t_r-0.2f) && (chrom > 7.0f && chrom < (48.0f+C9) )) scale = (100.f-skinprot*0.6f)/100.1f; + else if ((hue > (b_l+0.07f + H11) && hue < t_r) && (chrom > 7.0f && chrom < (55.0f+C9) )) scale = (100.f-skinprot*0.4f)/100.1f; + } + else if (lum >= 20.0f) { + if((hue > t_l && hue < (t_r+H3)) && (chrom > 7.0f && chrom <(35.0f+C3) )) scale = (100.f-skinprot)/100.1f; + else if ((hue > (b_l+0.07f + H11) && hue < t_r-0.2f) && (chrom > 7.0f && chrom < (48.0f+C9) )) scale = (100.f-skinprot*0.6f)/100.1f; + else if ((hue > (b_l+0.07f + H11) && hue < t_r) && (chrom > 7.0f && chrom < (55.0f+C9) )) scale = (100.f-skinprot*0.4f)/100.1f; + } + else if (lum >= 10.0f) { + if((hue > (t_l-0.25f + H10) && hue < (t_r-0.3f +H2)) && (chrom > 8.0f && chrom < (23.0f+C2))) scale = (100.f-skinprot)/100.1f; + else if ((hue > (b_l+0.07f+H11) && hue < t_r-0.2f) && (chrom > 7.0f && chrom < (35.0f+C1) )) scale = (100.f-skinprot*0.6f)/100.1f; + else if ((hue > (b_l+0.07f+H11) && hue < t_r-0.1f) && (chrom > 7.0f && chrom < (45.0f+C1) )) scale = (100.f-skinprot*0.4f)/100.1f; + } + else if ((hue > (t_l -0.2f + H10) && hue < (t_r-0.3f+H1)) && (chrom > 8.0f && chrom < (23.0f+C1))) scale = (100.f-skinprot)/100.1f; + else if ((hue > (b_l+0.07f+H11) && hue < t_r-0.2f) && (chrom > 7.0f && chrom < (35.0f+C1) )) scale = (100.f-skinprot*0.6f)/100.1f; + else if ((hue > (b_l+0.07f+H11) && hue < t_r-0.1f) && (chrom > 7.0f && chrom < (45.0f+C1) )) scale = (100.f-skinprot*0.4f)/100.1f; + + //extended zone for hair, beard and if user adjust high value for skinprot + if(skinprot > 85.f && chrom < 20.f && neg) { + float modula = -0.0666f * skinprot + 6.66f; + scale *= modula; + } + } + //end hue skin algo + else if (basc==1) {//not hue skin linear transition or mod chroma curve + if(hue >= t_l && hue <= t_r) scale = (100.f-skinprot)/100.1f; + else if(hue > b_l && hue < t_l) { + float sc=(100.f-skinprot)/100.1f; + float aa=(1.f-sc)/(b_l-t_l); + float bb=1.f-aa*b_l; + scale=aa*hue + bb; + } + else if(hue > t_r && hue < b_r) { + float sc=(100.f-skinprot)/100.1f; + float aa=(sc-1.f)/(t_r-b_r); + float bb=1.f-aa*b_r; + scale=aa*hue + bb; + } + } + } + + + + static inline void SkinSatCbdlCam (float lum, float hue, float chrom, float skinprot, float &scale, bool neg, float b_l, float t_l, float t_r) { + + static const float C9=8.f, C8=15.f, C7=12.f, C4=7.f, C3=5.f, C2=5.f, C1=5.f; + static const float H9=0.05f, H8=0.25f, H7=0.1f, H4=0.02f, H3=0.02f, H2=0.1f, H1=0.1f, H10=-0.2f,H11=-0.2f; + + float HH = 0.f; + if (hue>8.6f && hue<=74.f ) {HH=(1.15f/65.4f)*hue-0.0012f;} //H > 0.15 H<1.3 + else if(hue>0.f && hue<=8.6f ) {HH=(0.19f/8.6f )*hue-0.04f;} //H>-0.04 H < 0.15 + else if(hue>355.f && hue<=360.f) {HH=(0.11f/5.0f )*hue-7.96f;} //H>-0.15 <-0.04 + else if(hue>74.f && hue<95.f ) {HH=(0.30f/21.0f)*hue+0.24285f;} //H>1.3 H<1.6 + else if(hue>=95.f && hue<137.5f) {HH= 0.01882f*hue-0.18823f;} // H>1.6 H<2.4 + else if(hue>285.f && hue<=355.f) {HH=0.1642f*hue -5.982f;} //HH>-1.3 HH <-0.15 + + hue=HH; + + // "real" skin color : take into account a slightly usage of contrast and saturation in RT if option "skin" = 1, uses imolicit factor 1.0 + // wide area skin color, useful if not accurate colorimetry or if the user has changed hue and saturation, uses explicit facor 0.6 + // wide area for transition, uses explicit factor 0.4 + + if (lum >= 85.0f) { + if((hue > (t_l+0.53f-H9) && hue < (t_r+H9)) && (chrom > 8.0f && chrom < (14.0f+C9))) scale = (100.f-skinprot)/100.1f; + else if (lum >= 92.0f) { + if((hue > t_l+0.4f && hue < t_r) && (chrom > 7.0f && chrom < (15.0f))) scale = (100.f-skinprot*0.6f)/100.1f; + else if ((hue > b_l && hue < t_r) && (chrom > 7.0f && chrom < (18.0f))) scale = (100.f-skinprot*0.4f)/100.1f; + } + else if ((hue > t_l+0.4f && hue < t_r-0.3f) && (chrom > 7.0f && chrom < (26.0f+C9))) scale = (100.f-skinprot*0.6f)/100.1f; + else if ((hue > b_l+0.05f && hue < t_r) && (chrom > 7.0f && chrom < (35.0f+C9))) scale = (100.f-skinprot*0.4f)/100.1f; + } + else if (lum >= 70.0f) { + if((hue > t_l+0.15f && hue < (t_r-0.2f+H8)) && (chrom > 8.0f && chrom < (35.0f+C8))) scale = (100.f-skinprot)/100.1f; + else if ((hue > (b_l+0.07f + H11) && hue < t_r-0.2f) && (chrom > 7.0f && chrom < (48.0f+C9) )) scale = (100.f-skinprot*0.6f)/100.1f; + else if ((hue > (b_l+0.07f + H11) && hue < t_r) && (chrom > 7.0f && chrom < (55.0f+C9) )) scale = (100.f-skinprot*0.4f)/100.1f; + } + else if (lum >= 52.0f) { + if((hue > t_l && hue < (t_r+H7)) && (chrom > 11.0f && chrom < (35.0f+C7))) scale = (100.f-skinprot)/100.1f; + else if ((hue > (b_l+0.07f + H11) && hue < t_r-0.2f) && (chrom > 7.0f && chrom < (48.0f+C9) )) scale = (100.f-skinprot*0.6f)/100.1f; + else if ((hue > (b_l+0.07f + H11) && hue < t_r) && (chrom > 7.0f && chrom < (55.0f+C9) )) scale = (100.f-skinprot*0.4f)/100.1f; + } + else if (lum >= 35.0f) { + if((hue > t_l && hue < (t_r+H4)) && (chrom > 13.0f && chrom < (37.0f+C4))) scale = (100.f-skinprot)/100.1f; + else if ((hue > (b_l+0.07f + H11) && hue < t_r-0.2f) && (chrom > 7.0f && chrom < (48.0f+C9) )) scale = (100.f-skinprot*0.6f)/100.1f; + else if ((hue > (b_l+0.07f + H11) && hue < t_r) && (chrom > 7.0f && chrom < (55.0f+C9) )) scale = (100.f-skinprot*0.4f)/100.1f; + } + else if (lum >= 20.0f) { + if((hue > t_l && hue < (t_r+H3)) && (chrom > 7.0f && chrom <(35.0f+C3) )) scale = (100.f-skinprot)/100.1f; + else if ((hue > (b_l+0.07f + H11) && hue < t_r-0.2f) && (chrom > 7.0f && chrom < (48.0f+C9) )) scale = (100.f-skinprot*0.6f)/100.1f; + else if ((hue > (b_l+0.07f + H11) && hue < t_r) && (chrom > 7.0f && chrom < (55.0f+C9) )) scale = (100.f-skinprot*0.4f)/100.1f; + } + else if (lum >= 10.0f) { + if((hue > (t_l-0.25f + H10) && hue < (t_r-0.3f +H2)) && (chrom > 8.0f && chrom < (23.0f+C2))) scale = (100.f-skinprot)/100.1f; + else if ((hue > (b_l+0.07f+H11) && hue < t_r-0.2f) && (chrom > 7.0f && chrom < (35.0f+C1) )) scale = (100.f-skinprot*0.6f)/100.1f; + else if ((hue > (b_l+0.07f+H11) && hue < t_r-0.1f) && (chrom > 7.0f && chrom < (45.0f+C1) )) scale = (100.f-skinprot*0.4f)/100.1f; + } + else if ((hue > (t_l -0.2f + H10) && hue < (t_r-0.3f+H1)) && (chrom > 8.0f && chrom < (23.0f+C1))) scale = (100.f-skinprot)/100.1f; + else if ((hue > (b_l+0.07f+H11) && hue < t_r-0.2f) && (chrom > 7.0f && chrom < (35.0f+C1) )) scale = (100.f-skinprot*0.6f)/100.1f; + else if ((hue > (b_l+0.07f+H11) && hue < t_r-0.1f) && (chrom > 7.0f && chrom < (45.0f+C1) )) scale = (100.f-skinprot*0.4f)/100.1f; + + //extended zone for hair, beard and if user adjust high value for skinprot + if(skinprot > 85.f && chrom < 20.f && neg) { + float modula = -0.0666f * skinprot + 6.66f; + scale *= modula; + } + } + + + /** + * @brief Gamut correction in the XYZ color space + * @param X X channel input value and corrected output value [0 ; 65535] + * @param Y Y channel input value and corrected output value [0 ; 65535] + * @param Z Z channel input value and corrected output value [0 ; 65535] + * @param p working profile + */ + static void gamutmap(float &X, float &Y, float &Z, const double p[3][3]); + + + /** + * @brief Get HSV's hue from the Lab's hue + * @param HH Lab's hue value, in radians [-PI ; +PI] + * @return HSV's hue value [0 ; 1] + */ + static inline double huelab_to_huehsv2 (float HH){ + //hr=translate Hue Lab value (-Pi +Pi) in approximative hr (hsv values) (0 1) [red 1/6 yellow 1/6 green 1/6 cyan 1/6 blue 1/6 magenta 1/6 ] + // with multi linear correspondances (I expect there is no error !!) + double hr = 0.0; + //allways put h between 0 and 1 + + if (HH>=0.f && HH < 0.6f ) hr=0.11666*double(HH) + 0.93; //hr 0.93 1.00 full red + else if (HH>=0.6f && HH < 1.4f ) hr=0.1125 *double(HH) - 0.0675; //hr 0.00 0.09 red yellow orange + else if (HH>=1.4f && HH < 2.f ) hr=0.2666 *double(HH) - 0.2833; //hr 0.09 0.25 orange yellow + else if (HH>=2.f && HH < 3.14159f) hr=0.1489 *double(HH) - 0.04785; //hr 0.25 0.42 yellow green green + else if (HH>=-3.14159f && HH < -2.8f ) hr=0.23419*double(HH) + 1.1557; //hr 0.42 0.50 green + else if (HH>=-2.8f && HH < -2.3f ) hr=0.16 *double(HH) + 0.948; //hr 0.50 0.58 cyan + else if (HH>=-2.3f && HH < -0.9f ) hr=0.12143*double(HH) + 0.85928; //hr 0.58 0.75 blue blue-sky + else if (HH>=-0.9f && HH < -0.1f ) hr=0.2125 *double(HH) + 0.94125; //hr 0.75 0.92 purple magenta + else if (HH>=-0.1f && HH < 0.f ) hr=0.1 *double(HH) + 0.93; //hr 0.92 0.93 red + // in case of ! + if (hr<0.0) hr += 1.0; + else if(hr>1.0) hr -= 1.0; + return (hr); + } + +}; + +} + +#endif diff --git a/rtengine/colorclip.h b/rtengine/colorclip.h new file mode 100644 index 000000000..0526af83d --- /dev/null +++ b/rtengine/colorclip.h @@ -0,0 +1,159 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +inline double tightestroot (double L, double a, double b, double r1, double r2, double r3); + +#ifndef __COLORCLIP__ +#define __COLORCLIP__ + +#include +#include "median.h" + +// gives back the tightest >0 amplification by which color clipping occures + +inline double tightestroot (double L, double a, double b, double r1, double r2, double r3) { + + double an = a/500.0, bn = b/200.0, p = (L+16.0)/116.0; + + double coeff3 = r1*an*an*an - r3*bn*bn*bn; + double coeff2 = 3.0 * p * (r1*an*an + r3*bn*bn); + double coeff1 = 3.0 * p*p * (r1*an - r3*bn); + double coeff0 = p*p*p*(r1+r2+r3) - 1.0; + + double a1 = coeff2 / coeff3; + double a2 = coeff1 / coeff3; + double a3 = coeff0 / coeff3; + + double Q = (a1 * a1 - 3.0 * a2) / 9.0; + double R = (2.0 * a1 * a1 * a1 - 9.0 * a1 * a2 + 27.0 * a3) / 54.0; + double Qcubed = Q * Q * Q; + double d = Qcubed - R * R; + +// printf ("input L=%g, a=%g, b=%g\n", L, a, b); +// printf ("c1=%g, c2=%g, c3=%g, c4=%g\n", coeff3, coeff2, coeff1, coeff0); + + + /* Three real roots */ + if (d >= 0) { + double theta = acos(R / sqrt(Qcubed)); + double sqrtQ = sqrt(Q); + double x0 = -2.0 * sqrtQ * cos( theta / 3.0) - a1 / 3.0; + double x1 = -2.0 * sqrtQ * cos((theta + 2.0 * M_PI) / 3.0) - a1 / 3.0; + double x2 = -2.0 * sqrtQ * cos((theta + 4.0 * M_PI) / 3.0) - a1 / 3.0; + +// printf ("3 roots: %g, %g, %g\n", x0, x1, x2); + + SORT3 (x0,x1,x2,a1,a2,a3); + if (a1>0) + return a1; + if (a2>0) + return a2; + if (a3>0) + return a3; + return -1; + } + + /* One real root */ + else { +// double e = pow(sqrt(-d) + fabs(R), 1.0 / 3.0); + double e = exp (1.0 / 3.0 * log (sqrt(-d) + fabs(R))); + + if (R > 0) + e = -e; + + double x0 = (e + Q / e) - a1 / 3.0; + +// printf ("1 root: %g\n", x0); + + if (x0<0) + return -1; + else + return x0; + } +} + + +/******************************************************************************* + * FindCubicRoots + * -------------- + * + * Copyright (C) 1997-2001 Ken Turkowski. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * ------------------------------------------------------------------------ + * + * Solve: + * coeff[3] * x^3 + coeff[2] * x^2 + coeff[1] * x + coeff[0] = 0 + * + * returns: + * 3 - 3 real roots + * 1 - 1 real root (2 complex conjugate) + * + *******************************************************************************/ + +/*long +FindCubicRoots(const FLOAT coeff[4], FLOAT x[3]) +{ + FLOAT a1 = coeff[2] / coeff[3]; + FLOAT a2 = coeff[1] / coeff[3]; + FLOAT a3 = coeff[0] / coeff[3]; + + double_t Q = (a1 * a1 - 3 * a2) / 9; + double_t R = (2 * a1 * a1 * a1 - 9 * a1 * a2 + 27 * a3) / 54; + double_t Qcubed = Q * Q * Q; + double_t d = Qcubed - R * R; + + // Three real roots + if (d >= 0) { + double_t theta = acos(R / sqrt(Qcubed)); + double_t sqrtQ = sqrt(Q); + x[0] = -2 * sqrtQ * cos( theta / 3) - a1 / 3; + x[1] = -2 * sqrtQ * cos((theta + 2 * pi) / 3) - a1 / 3; + x[2] = -2 * sqrtQ * cos((theta + 4 * pi) / 3) - a1 / 3; + return (3); + } + + // One real root + else { + double_t e = pow(sqrt(-d) + fabs(R), 1. / 3.); + if (R > 0) + e = -e; + x[0] = (e + Q / e) - a1 / 3.; + return (1); + } +} +*/ +#endif diff --git a/rtengine/colortemp.cc b/rtengine/colortemp.cc new file mode 100644 index 000000000..db473ec70 --- /dev/null +++ b/rtengine/colortemp.cc @@ -0,0 +1,1696 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "colortemp.h" +#include "rtengine.h" +#include +#include +#include +#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 { + + extern const Settings* settings; + + static const double cie_colour_match_jd[97][3] = {//350nm to 830nm 5 nm J.Desmis observer 2� + {0.0000000,0.000000,0.000000}, {0.0000000,0.000000,0.000000}, {0.0001299,0.0003917,0.0006061}, + {0.0002321,0.000006965,0.001086}, {0.0004149,0.00001239,0.001946}, {0.0007416,0.00002202,0.003846}, + {0.001368,0.000039,0.006450001}, {0.002236,0.000064,0.01054999}, {0.004243,0.000120,0.02005001}, + {0.007650,0.000217,0.036210}, {0.014310,0.000396,0.06785001}, {0.023190,0.000640,0.110200}, + {0.043510,0.001210,0.207400}, {0.077630,0.002180,0.371300}, {0.134380,0.004000,0.645600}, + {0.214770,0.007300,1.0390501}, {0.283900,0.011600,1.385600}, {0.328500,0.016840,1.622960}, + {0.348280,0.023000,1.747060}, {0.348060,0.029800,1.782600}, {0.336200,0.038000,1.772110}, + {0.318700,0.048000,1.744100}, {0.290800,0.060000,1.669200}, {0.251100,0.073900,1.528100}, + {0.195360,0.090980,1.287640}, {0.142100,0.112600,1.041900}, {0.095640,0.139020,0.8129501}, + {0.05795001,0.169300,0.616200}, {0.032010,0.208020,0.465180}, {0.014700,0.258600,0.353300}, + {0.004900,0.323000,0.272000}, {0.002400,0.407300,0.212300}, {0.009300,0.503000,0.158200}, + {0.029100,0.608200,0.111700}, {0.063270,0.710000,0.07824999}, {0.109600,0.793200,0.05725001}, + {0.165500,0.862000,0.042160}, {0.2257499,0.9148501,0.029840}, {0.290400,0.954000,0.020300}, + {0.359700,0.980300,0.013400}, {0.43344990,0.9949501,0.008749999}, {0.5120501,1.000000,0.005749999}, + {0.594500,0.995000,0.003900}, {0.678400,0.978600,0.002749999}, {0.762100,0.952000,0.002100}, + {0.842500,0.915400,0.001800}, {0.916300,0.870000,0.001650001}, {0.978600,0.816300,0.001400}, + {1.026300,0.757000,0.001100}, {1.056700,0.694900,0.001000}, {1.062200,0.631000,0.000800}, + {1.045600,0.566800,0.000600}, {1.002600,0.503000,0.000340}, {0.938400,0.441200,0.000240}, + {0.8544499,0.381000,0.000190}, {0.751400,0.321000,0.000100}, {0.642400,0.265000,0.00004999999}, + {0.541900,0.217000,0.000030}, {0.447900,0.175000,0.000020}, {0.360800,0.138200,0.000010}, + {0.283500,0.107000,0.000000}, {0.218700,0.081600,0.000000}, {0.164900,0.061000,0.000000}, + {0.121200,0.044580,0.000000}, {0.087400,0.032000,0.000000}, {0.063600,0.023200,0.000000}, + {0.046770,0.017000,0.000000}, {0.032900,0.011920,0.000000}, {0.022700,0.008210,0.000000}, + {0.015840,0.005723,0.000000}, {0.01135916,0.004102,0.000000}, {0.008110916,0.002929,0.000000}, + {0.005790346,0.002091,0.000000}, {0.004109457,0.001484,0.000000}, {0.002899327,0.001047,0.000000}, + {0.00204919,0.000740,0.000000}, {0.001439971,0.000520,0.000000}, {0.0009999493,0.0003611,0.000000}, + {0.0006900786,0.0002492,0.000000}, {0.0004760213,0.0001719,0.000000}, {0.0003323011,0.000120,0.000000}, + {0.0002348261,0.0000848,0.000000}, {0.0001661505,0.000060,0.000000}, {0.000117413,0.0000424,0.000000}, + {0.00008307527,0.000030,0.000000}, {0.00005870652,0.0000212,0.000000}, {0.00004150994,0.00001499,0.000000}, + {0.00002935326,0.0000106,0.000000}, {0.00002067383,0.0000074657,0.000000}, {0.00001455977,0.0000052578,0.000000}, + {0.00001025398,0.0000037029,0.000000}, {0.000007221456,0.00000260778,0.000000}, {0.000005085868,0.0000018366,0.000000}, + {0.000003581652,0.0000012934,0.000000}, {0.000002522525,0.00000091093,0.000000}, {0.000001776509,0.00000064153,0.000000}, + {0.000001251141,0.00000045181,0.000000} + }; + +ColorTemp::ColorTemp (double t, double g, double e, Glib::ustring 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; +} + +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; +} + +ColorTemp::ColorTemp (double mulr, double mulg, double mulb, double e) : equal(e) { + method = "Custom"; + mul2temp (mulr, mulg, mulb, equal, temp, green); +} + +void ColorTemp::mul2temp (const double rmul, const double gmul, const double bmul, const double equal, double& temp, double& green) { + + double maxtemp=double(MAXTEMP), mintemp=double(MINTEMP); + double tmpr, tmpg, tmpb; + temp=(maxtemp+mintemp)/2; + + while (maxtemp-mintemp>1) { + temp2mul (temp, 1.0, equal, tmpr, tmpg, tmpb); + if (tmpb/tmpr > bmul/rmul) + maxtemp = temp; + else + mintemp = temp; + temp=(maxtemp+mintemp)/2; + } + green = (tmpg/tmpr) / (gmul/rmul); + clip (temp, green); +} + + +// spectral data for Daylight direct Sun: I have choose 5300K because Nikon=5200K, Olympus=5300K, Panasonic=5500K, Leica=5400K, Minolta=5100K +const double ColorTemp::Daylight5300_spect[97] = { + 24.82,26.27,27.72,28.97,30.22,29.71,29.19,31.95,34.71,45.49,56.26,59.97,63.68,65.30,66.92,65.39,63.86,72.59,81.32,87.53,93.73,95.15,96.56,96.55,96.54,98.13,99.73,97.70,95.66,97.19,98.72, + 98.90,99.08,98.98,98.87,101.13,103.39,102.48,101.57,102.14,102.71,101.36,100.00,98.71,97.42,97.81,98.21,95.20,92.20,93.92,95.63,96.15,96.67,96.34,96.01,94.21,92.41,93.58,94.74,93.05,91.36,92.29, + 93.21,95.25,97.28,95.30,93.32,87.92,82.51,84.29,86.06,86.94,87.81,80.24,72.68,77.32,81.96,84.88,87.79,81.01,74.22,64.41,54.60,66.55,78.51,76.35,74.20,74.79,75.38,72.48,69.58,65.11,60.64, + 63.88,67.13,68.85,70.57 +}; + +//spectral data for Daylight Cloudy: I have choose 6200K because Nikon=6000K, Olympus=6000K, Panasonic=6200K, Leica=6400K, Minolta=6500K +const double ColorTemp::Cloudy6200_spect[97] = { + 39.50,40.57,41.63,43.85,46.08,45.38,44.69,47.20,49.71,63.06,76.41,80.59,84.77,85.91,87.05,84.14,81.23,90.29,99.35,105.47,111.58,112.23,112.87,111.74,110.62,111.41,112.20,108.98,105.76,106.32, + 106.89,106.34,105.79,104.62,103.45,105.09,106.72,105.24,103.76,103.75,103.75,101.87,100.00,98.29,96.58,96.46,96.34,92.85,89.37,90.25,91.12,91.06,90.99,90.17,89.35,87.22,85.10,85.48,85.85, + 84.03,82.20,82.45,82.69,83.92,85.15,83.14,81.13,76.65,72.17,73.27,74.36,75.65,76.95,70.34,63.74,67.98,72.22,74.88,77.54,71.59,65.65,56.82,47.99,58.53,69.06,67.27,65.47,65.96,66.44,63.92,61.41,57.52, + 53.63,56.47,59.31,60.80,62.29 +}; + +//spectral data for Daylight Shade: I have choose 7600K because Nikon=8000K, Olympus=7500K, Panasonic=7500K, Leica=7500K, Minolta=7500K +const double ColorTemp::Shade7600_spect[97] = { + 64.42,64.46,64.51,68.35,72.20,70.22,68.24,69.79,71.35,87.49,103.64,108.68,113.72,114.12,114.53,109.54,104.55,113.59,122.63,128.52,134.41,134.02,133.63,131.02,128.41,128.08,127.75,123.16, + 118.57,117.89,117.22,115.72,114.22,111.60,108.99,109.84,110.68,108.57,106.45,105.71,104.98,102.49,100.00,97.78,95.55,94.82,94.08,90.47,86.87,86.94,87.01,86.45,85.88,84.57,83.27,80.83,78.40,78.21, + 78.03,76.22,74.42,74.15,73.89,74.41,74.92,73.01,71.09,67.26,63.42,64.01,64.60,66.10,67.60,61.83,56.06,59.94,63.82,66.27,68.71,63.49,58.26,50.30,42.34,51.64,60.95,59.45,57.95,58.35,58.76,56.57, + 54.38,51.00,47.62,50.10,52.58,53.88,55.19 +}; + +//spectral data for tungsten - incandescent 2856K +const double ColorTemp::A2856_spect[97] = { + 4.75,5.42,6.15,6.95,7.83,8.78,9.80,10.91,12.09,13.36,14.72,16.16,17.69,19.30,21.01,22.80,24.68,26.65,28.71,30.86,33.10,35.42,37.82,40.31,42.88,45.53,48.25,51.05,53.92,56.87,59.87,62.94,66.07,69.26,72.50, + 75.80,79.14,82.53,85.95,89.42,92.91,96.44,100.00,103.58,107.18,110.80,114.43,118.07,121.72,125.38,129.03,132.68,136.33,139.97,143.60,147.21,150.81,154.39,157.95,161.48,164.99,168.47,171.92,175.34, + 178.72,182.07,185.38,188.65,191.88,195.06,198.20,201.30,204.34,207.34,210.29,213.19,216.04,218.84,221.58,224.28,226.91,229.49,232.02,234.49,236.91,239.27,241.57,243.82,246.01,248.14,250.21,252.23,254.19, + 256.10,257.95,259.74,261.47 +}; + +//spectral data for fluo F1 Daylight 6430K +const double ColorTemp::FluoF1_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0,1.87,2.36,2.94,3.47,5.17,19.49,6.13,6.24,7.01,7.79,8.56,43.67,16.94,10.72,11.35,11.89,12.37,12.75,13.00,13.15,13.23,13.17,13.13,12.85,12.52, + 12.20,11.83,11.50,11.22,11.05,11.03,11.18,11.53,27.74,17.05,13.55,14.33,15.01,15.52,18.29,19.55,15.48,14.91,14.15,13.22,12.19,11.12,10.03,8.95,7.96,7.02,6.20,5.42,4.73,4.15,3.64,3.20,2.81, + 2.47,2.18,1.93,1.72,1.67,1.43,1.29,1.19,1.08,0.96,0.88,0.81,0.77,0.75,0.73,0.68,0.69,0.64,0.68,0.69,0.61,0.52,0.43,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data for fluo F2 Cool white 4230K +const double ColorTemp::FluoF2_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0,1.18,1.48,1.84,2.15,3.44,15.69,3.85,3.74,4.19,4.62,5.06,34.98,11.81,6.27,6.63,6.93,7.19,7.40,7.54,7.62,7.65,7.62,7.62,7.45,7.28,7.15,7.05,7.04,7.16,7.47,8.04,8.88,10.01,24.88,16.64,14.59,16.16,17.60,18.62,21.47,22.79,19.29,18.66,17.73,16.54,15.21,13.80,12.36,10.95,9.65,8.40,7.32,6.31,5.43,4.68,4.02,3.45, + 2.96,2.55,2.19,1.89,1.64,1.53,1.27,1.10,0.99,0.88,0.76,0.68,0.61,0.56,0.54,0.51,0.47,0.47,0.43,0.46,0.47,0.40,0.33,0.27,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data for fluo F3 White 3450K +const double ColorTemp::FluoF3_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0,0.82,1.02,1.26,1.44,2.57,14.36,2.70,2.45,2.73,3.00,3.28,31.85,9.47,4.02,4.25,4.44,4.59,4.72,4.80,4.86,4.87,4.85,4.88,4.77,4.67,4.62,4.62,4.73,4.99,5.48,6.25, + 7.34,8.78,23.82,16.14,14.59,16.63,18.49,19.95,23.11,24.69,21.41,20.85,19.93,18.67,17.22,15.65,14.04,12.45,10.95,9.51,8.27,7.11,6.09,5.22,4.45,3.80,3.23,2.75,2.33,1.99,1.70,1.55, + 1.27,1.09,0.96,0.83,0.71,0.62,0.54,0.49,0.46,0.43,0.39,0.39,0.35,0.38,0.39,0.33,0.28,0.21,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data for fluo F4 Warm white 2940K +const double ColorTemp::FluoF4_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0,0.57,0.70,0.87,0.98,2.01,13.75,1.95,1.59,1.76,1.93,2.10,30.28,8.03,2.55,2.70,2.82,2.91,2.99,3.04,3.08,3.09,3.09,3.14,3.06,3.00,2.98,3.01, + 3.14,3.41,3.90,4.69,5.81,7.32,22.59,15.11,13.88,16.33,18.68,20.64,24.28,26.26,23.28,22.94,22.14,20.91,19.43,17.74,16.00,14.42,12.56,10.93,9.52,8.18,7.01,6.00,5.11,4.36,3.69,3.13,2.64, + 2.24,1.91,1.70,1.39,1.18,1.03,0.88,0.74,0.64,0.54,0.49,0.46,0.42,0.37,0.37,0.33,0.35,0.36,0.31,0.26,0.19,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data for fluo F5 Daylight 6350K +const double ColorTemp::FluoF5_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0,1.87,2.35,2.92,3.45,5.10,18.91,6.00,6.11,6.85,7.58,8.31,40.76,16.06,10.32,10.91,11.40,11.83,12.17,12.40,12.54,12.58,12.52,12.47,12.20,11.89, + 11.61,11.33,11.10,10.96,10.97,11.16,11.54,12.12,27.78,17.73,14.47,15.20,15.77,16.10,18.54,19.50,15.39,14.64,13.72,12.69,11.57,10.45,9.35,8.29,7.32,6.41,5.63,4.90,4.26, + 3.72,3.25,2.83,2.49,2.19,1.93,1.71,1.52,1.43,1.26,1.13,1.05,0.96,0.85,0.78,0.72,0.68,0.67,0.65,0.61,0.62,0.59,0.62,0.64,0.55,0.47,0.40,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data for fluo F6 Lite white 4150K +const double ColorTemp::FluoF6_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0,1.05,1.31,1.63,1.90,3.11,14.8,3.43,3.30,3.68,4.07,4.45,32.61,10.74,5.48,5.78,6.03,6.25,6.41,6.52,6.58,6.59,6.56,6.56,6.42,6.28,6.20,6.19,6.30,6.60,7.12,7.94,9.07,10.49,25.22,17.46,15.63,17.22,18.53, + 19.43,21.97,23.01,19.41,18.56,17.42,16.09,14.64,13.15,11.68,10.25,8.96,7.74,6.69,5.71,4.87,4.16,3.55,3.02,2.57,2.20,1.87,1.60,1.37,1.29,1.05,0.91,0.81,0.71,0.61,0.54,0.48,0.44, + 0.43,0.40,0.37,0.38,0.35,0.39,0.41,0.33,0.26,0.21,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data for fluo F7 D65 Daylight simulator 6500K +const double ColorTemp::FluoF7_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0,2.56,3.18,3.84,4.53,6.15,19.37,7.37,7.05,7.71,8.41,9.15,44.14,17.52,11.35,12.00,12.58,13.08,13.45,13.71,13.88,13.95,13.93,13.82,13.64,13.43,13.25,13.08,12.93,12.78,12.60, + 12.44,12.33,12.26,29.52,17.05,12.44,12.58,12.72,12.83,15.46,16.75,12.83,12.67,12.43,12.19,11.89,11.60,11.35,11.12,10.95,10.76,10.42,10.11,10.04,10.02,10.11,9.87,8.65,7.27,6.44,5.83,5.41, + 5.04,4.57,4.12,3.77,3.46,3.08,2.73,2.47,2.25,2.06,1.90,1.75,1.62,1.54,1.45,1.32,1.17,0.99,0.81,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data for fluo F8 D50 simulator Sylvania F40 Design 5000K +const double ColorTemp::FluoF8_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0,1.21,1.5,1.81,2.13,3.17,13.08,3.83,3.45,3.86,4.42,5.09,34.1,12.42,7.68,8.60,9.46,10.24,10.84,11.33,11.71,11.98,12.17,12.28,12.32,12.35,12.44,12.55,12.68,12.77,12.72, + 12.60,12.43,12.22,28.96,16.51,11.79,11.76,11.77,11.84,14.61,16.11,12.34,13.61,13.87,14.07,14.20,14.16,14.13,14.34,14.50,14.46,14.00,12.58,10.99,9.98,9.22,8.62,8.07,7.39,6.71,6.16,5.63,5.03,4.46,4.02,3.66, + 3.36,3.09,2.85,2.65,2.51,2.37,2.15,1.89,1.61,1.32,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data for fluo F9 Cool white deluxe 4150K +const double ColorTemp::FluoF9_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0,0.9,1.12,1.36,1.60,2.59,12.8,3.05,2.56,2.86,3.30,3.82,32.62,10.77,5.84,6.57,7.25,7.86,8.35,8.75,9.06,9.31,9.48,9.61,9.68,10.04,10.26,10.48,10.63,10.76,10.96, + 11.18,27.71,16.29,12.28,12.74,13.21,13.65,16.57,18.14,14.55,14.65,14.66,14.61,14.50,14.39,14.40,14.47,14.62,14.72,14.55,14.4,14.58,14.88,15.51,15.47,13.20,10.57,9.18,8.25,7.57,7.03, + 6.35,5.72,5.25,4.80,4.29,3.80,3.43,3.12,2.86,2.64,2.43,2.26,2.14,2.02,1.83,1.61,1.38,1.12,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data for fluo F10 Philips TL85 - 5000K +const double ColorTemp::FluoF10_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0,1.11,0.63,0.62,0.57,1.48,12.16,2.12,2.70,3.74,5.14,6.75,34.39,14.86,10.4,10.76,10.11,9.27,8.29,7.29,7.91,16.64,16.73,10.44,5.94,3.34,2.35,1.88,1.59,1.47, + 1.80,5.71,40.98,73.69,33.61,8.24,3.38,2.47,4.86,11.45,14.79,12.16,8.97,6.52,8.81,44.12,34.55,12.09,12.15,10.52,4.43,1.95,2.19,3.19,2.77,2.29,2.00,1.52,1.35,1.47,1.79,1.74,1.02,1.14, + 3.32,4.49,2.05,0.49,0.24,0.21,0.21,0.24,0.24,0.21,0.17,0.21,0.22,0.17,0.12,0.09,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data for fluo F11 Philips TL84 4150K +const double ColorTemp::FluoF11_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0,0.91,0.63,0.46,0.37,1.29,12.68,1.59,1.79,2.46,3.38,4.49,33.94,12.13,6.95,7.19,7.12,6.72,6.13,5.46,4.79,5.66,14.29,14.96,8.97,4.72,2.33,1.47,1.10,0.89,0.83,1.18,4.90,39.59, + 72.84,32.61,7.52,2.83,1.96,1.67,4.43,11.28,14.76,12.73,9.74,7.33,9.72,55.27,42.58,13.18,13.16,12.26,5.11,2.07,2.34,3.58,3.01,2.48,2.14,1.54,1.33,1.46,1.94,2.00,1.20,1.35,4.10,5.58, + 2.51,0.57,0.27,0.23,0.21,0.24,0.24,0.20,0.24,0.32,0.26,0.16,0.12,0.09,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data for fluo F12 Philips TL83 3000K +const double ColorTemp::FluoF12_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0,0.96,0.64,0.45,0.33,1.19,12.48,1.12,0.94,1.08,1.37,1.78,29.05,7.90,2.65,2.71,2.65,2.49,2.33,2.10,1.91,3.01,10.83,11.88,6.88,3.43,1.49,0.92,0.71,0.60,0.63,1.10,4.56,34.4,65.40,29.48, + 7.16,3.08,2.47,2.27,5.09,11.96,15.32,14.27,11.86,9.28,12.31,68.53,53.02,14.67,14.38,14.71,6.46,2.57,2.75,4.18,3.44,2.81,2.42,1.64,1.36,1.49,2.14,2.34,1.42,1.61,5.04,6.98,3.19,0.71,0.30,0.26,0.23,0.28,0.28,0.21, + 0.17,0.21,0.19,0.15,0.10,0.05,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data for HMI lamp studio "Osram" 4800K (for film, spectacle, studio...) +const double ColorTemp::HMI_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0,9.66,11.45,13.24,14.93,16.63,17.90,19.20,20.12,21.03,23.84,26.65,26.38,26.12,26.52,27.92,31.15,34.37,34.98,35.61,35.71,35.81,34.90,34.02,34.06,34.08,34.68,35.28,34.72,34.20,33.63, + 33.05,34.70,36.35,38.01,39.48,37.29,35.10,36.22,37.28,38.76,40.24,39.56,38.90,39.35,39.79,38.90,38.01,38.05,38.10,37.45,36.64,35.82,35.00,35.06,33.13,33.85,34.55,35.26,35.77,34.92, + 34.09,33.40,32.72,32.08,31.45,26.83,22.23,21.50,20.79,21.41,22.03,11.01,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data for GTI lamp : Graphiclite & ColorMatch for Photography 5000K +const double ColorTemp::GTI_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0,3.26,4.71,6.17,12.71,19.27,20.53,21.80,19.15,16.53,28.25,39.97,48.52,57.06,43.66,30.27,30.22,30.16,31.48,32.98,34.01,35.04,35.83,36.62,37.12,37.62,37.99,38.19,38.29,38.48, + 38.82,39.16,45.40,51.63,51.83,62.04,52.41,42.80,42.95,43.09,45.64,48.20,46.23,44.27,43.74,43.22,43.30,43.41,43.10,42.78,42.03,41.29,40.29,39.29,37.89,36.58,34.92,33.27,31.47,29.68,27.90, + 26.13,24.55,22.98,21.42,19.86,18.40,16.92,14.46,13.99,12.36,11.73,5.86,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data for JudgeIII Lamp D50 +const double ColorTemp::JudgeIII_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0,4.08,4.25,4.43,6.90,9.40,9.75,10.11,9.30,8.54,14.90,21.16,26.01,30.83,24.90,19.00,19.00,19.00,19.56,20.13,20.28,20.44,20.64,20.85,21.05,21.24,21.65,22.11,22.85,23.58,24.00,24.43, + 27.75,31.27,33.90,36.59,30.90,25.32,25.05,24.76,26.03,27.31,25.90,24.48,23.85,23.29,23.10,22.94,23.24,23.53,24.02,24.52,23.80,23.13,24.51,25.76,27.90,29.15,24.70,20.25,16.60,12.98,11.63,10.27,9.30,8.34, + 7.60,6.91,6.25,5.67,5.15,4.68,2.34,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data for Solux lamp : 3500K +const double ColorTemp::Solux3500_spect[97] = { + 0.5268,0.93,1.3278,1.51,1.6987,2.65,3.6100,3.80,3.9927,6.08,8.1680,11.02,13.863,15.66,17.4600,18.78,20.130,21.43,22.749,24.02,25.290,27.40,29.504,31.77,34.031,36.35,38.672,40.55,42.426,44.15,45.865,47.37,48.879, + 49.71,50.531,51.2,51.872,51.9,51.928,52.97,54.015,55.93,57.846,60.25,62.650,64.36,66.065,66.72,67.369,68.81,70.260,71.37,72.487,72.53,72.578,72.51,72.447,72.46,72.471, + 72.76,73.047,74.25,75.449,76.5,77.543,78.79,80.040,80.72,81.394,82.12,82.840,83.23,83.614,83.36,83.100,82.36,81.615,80.11,78.606,75.91,73.221,69.61,66.006,62.43,58.844,56.07,53.292, + 51.07,48.839,46.93,45.013,43.54,42.070,40.61,39.150,37.79,36.425 +}; + +//spectral data for Solux lamp : 4100K +const double ColorTemp::Solux4100_spect[97] = { + 0.5717,0.70,0.8286,1.16,1.522,2.01,2.384,3.45,4.57,6.46,8.4548,11.31,14.205,16.10,17.949,19.51,21.068,22.60,24.197,25.37,26.566,28.15,29.742,30.90,32.060,33.26,34.481,34.80,35.130,35.42,35.697,36.20,36.763, + 37.90,39.004,40.26,41.494,43.10,44.690,45.80,46.900,47.45,47.885,47.75,47.635,47.00,46.410,46.22,46.058,46.70,47.344,48.65,50.005,51.02,52.045,53.55,55.075,55.98,56.823, + 56.85,56.884,56.15,55.523,54.60,53.732,52.55,51.425,50.30,49.1830,48.76,48.273,48.22,48.169,49.92,49.915,51.90,53.099,54.95,56.852,58.45,60.090,61.67,63.2530,63.55,63.834,63.55,63.468, + 62.40,61.373,59.75,58.1810,56.25,54.395,51.90,49.496,47.05,44.620 +}; + +//spectral data for Solux lamp : near Daylight (for example "mus�e d'Orsay..") - 4700K +const double ColorTemp::Solux4700_spect[97] = { + 0.4590,0.83,1.2011,1.53,1.8647,2.15,2.5338,3.06,3.5809,3.99,4.4137,4.82,5.2228,5.63,6.0387,6.53,6.9944,7.55,8.0266,8.475,8.9276,8.90,9.7840,10.20,10.6390,11.00,11.3600,11.75,12.1340,12.36,12.5880,12.74,12.8790, + 13.07,13.2560,13.38,13.5220,13.41,13.3070,13.35,13.3990,13.37,13.3420,13.39,13.4220,13.65,13.2710,13.25,13.2330,13.12,13.0110,12.93,12.8470,12.805,12.7630,12.66,12.5760,12.563,12.5490, + 12.59,12.6330,12.617,12.6010,12.616,12.6310,12.6275,12.6240,12.70,12.7710,12.776,12.7810,12.786,12.7950,12.74,12.6850,12.64,12.5950,12.55,12.5420,12.43,12.3180,12.07,11.8340,11.72,11.6190,11.55,11.5020, + 11.32,11.1510,11.05,10.9530,10.80,10.6550,10.495,10.4390,10.31,10.1790 +}; + +//spectral data for Solux lamp : near Daylight 4400K - test National Gallery +const double ColorTemp::NG_Solux4700_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0,139,152,170,185,202,223,240,257,270,282,293,305,317,329,342,355,367,378,387,395,401,405,408,411,414,415,416,415,414,414,416,419,423,427,432,437,442,447,452, + 456,461,467,475,483,488,490,491,490,487,485,481,477,472,466,461,455,449,442,434,427,419,411,403,395,386,377,367,359,351,343,335,327,322,316,312,306,305,301,299,299,298, + 0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.0 +}; + +//spectral data for LED LSI Lumelex 2040 - test National Gallery +const double ColorTemp::NG_LEDLSI2040_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0,1.5,1.2,0.5,0.7,0.6,1.6,1.7,7.0,16.6,35.5,64,106,162.5,230.5,272.2,249,213.4,214,227.6,231.9,233,235.2,241.4,253.7,270.3,288.5,306.2,322.3,337.6,352.5,367.2,381.7,395.9,409.6,416.2,423.2,429.7,435.8,442.8, + 451.7,464.2,480.3,501,526.3,555.9,587.5,625.4,655.1,681.7,705.3,721.5,728.5,729,719.8,702.5,676.7,646.2,611.5,571.7,530.3,488.3,445.9,404,365.2,326.8,290.8,257.6,226.9,199.8,175.2,154.2,133.8,116.4,101.5,88.5,76.6,67.3,57.9,50.7,44.2,38.2, + 0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.0 +}; + +//spectral data for LED CRS SP12 WWMR16 - test National Gallery +const double ColorTemp::NG_CRSSP12WWMR16_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0,0.,0.,0.,0.,0.,0.14,0.33,1.31,3.34,7.9,17.4,36.5,72.6,145.4,260.5,359.2,365.3,303.1,256.1,221.7,193.6,185.8,191.4,207.3,232.8,257.5,285.1,310.5,333.4,351.5,368.8,383.7,398.8,411.6,424.7,435.6,447.9,459.7,471.7, + 484.6,497.9,512.3,531.1,548.9,567.9,587.5,608.6,625.3,640.1,648.6,654.0,654.3,647.2,633.9,616.1,590.5,561.5,526.5,494.8,457.9,420.8,382.4,347.3,309.9,280.5,249.2,220.0,194.9,170.8,149.1,130.0,112.3,97.5,84.9,73.2,63.1,54.1,45.6,39.0,32.6,27.4, + 0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.0 +}; + + +//Data for flash : +// in theory, should be the spectral data of each owner flash (Nikon, Canon, Sony ...) or studio flash (Profoto. ..) +// but: 1) I did not, 2) the data vary depending on the power used ... so by default, although this is not true, I chose the values "Daylight" for temp... +// CRI for flash near of 95 - 97 !! + +//spectral data for Flash daylight 5500K (Leica...) +const double ColorTemp::Flash5500_spect[97] = { + 27.77,29.17,30.58,32.02,33.47,33.00,32.53,35.28,38.04,49.46,60.88,64.68,68.48,69.99,71.51,69.68,67.85,76.70,85.54,91.74,97.93,99.17,100.41,100.14,99.86,101.28,102.70,100.37,98.04,99.35,100.65, + 100.66,100.67,100.32,99.97,102.08,104.20,103.15,102.09,102.53,102.96,101.48,100.00,98.61,97.22,97.49,97.76,94.60,91.44,92.94,94.44,94.80,95.16,94.70,94.25,92.36,90.48,91.42,92.36,90.63, + 88.89,89.62,90.36,92.18,94.00,92.00,90.00,84.86,79.72,81.30,82.88,83.88,84.89,77.58,70.27,74.80,82.19,85.03,78.47,71.91,62.37,52.82,64.39,75.96,73.91,71.85,72.41,72.97,70.17,67.38,63.07, + 58.75,61.89,65.02,66.68,68.34 +}; + +//spectral data for Flash daylight 6000K (Canon, Pentax, Olympus,...Standard) +const double ColorTemp::Flash6000_spect[97] = { + 36.00,37.18,38.36,40.36,42.35,41.77,41.19,43.79,46.40,59.24,72.09,76.15,80.22,81.47,82.71,80.12,77.52,86.54,95.56,101.70,107.85,108.66,109.46,108.57,107.68,108.65,109.61,106.63,103.65,104.42, + 105.19,104.79,104.39,103.45,102.51,104.28,106.05,104.68,103.31,103.42,103.54,101.77,100.00,98.38,96.75,96.74,96.72,93.30,89.89,90.92,91.95,91.99,92.03,91.30,90.57,88.51,86.45,86.96, + 87.47,85.66,83.85,84.21,84.57,85.95,87.32,85.31,83.30,78.66,74.03,75.24,76.45,77.68,78.91,72.13,65.35,69.67,73.98,76.68,79.39,73.29,67.19,58.19,49.19,59.98,70.77,68.91,67.05,67.55,68.05, + 65.47,62.88,58.89,54.90,57.81,60.72,62.25,63.78 +}; + +//spectral data for Flash daylight 6500K (Nikon, Minolta, Panasonic, Sony...) +const double ColorTemp::Flash6500_spect[97] = { + 44.86,45.72,46.59,49.16,51.74,50.83,49.92,52.26,54.60,68.65,82.69,87.06,91.42,92.39,93.37,90.00,86.63,95.72,104.81,110.88,116.96,117.36,117.76,116.29,114.82,115.35,115.89,112.33,108.78,109.06, + 109.33,108.56,107.78,106.28,104.78,106.23,107.68,106.04,104.40,104.22,104.04,102.02,100.00,98.17,96.34,96.06,95.79,92.24,88.69,89.35,90.02,89.81,89.61,88.66,87.71,85.51,83.30,83.51,83.72, + 81.88,80.05,80.14,80.24,81.27,82.30,80.31,78.31,74.03,69.74,70.69,71.63,73.00,74.37,68.00,61.62,65.76,69.91,72.51,75.11,69.36,63.61,55.02,46.43,56.63,66.83,65.11,63.40,63.86,64.32,61.90,59.47, + 55.72,51.97,54.72,57.46,58.89,60.33 +}; + +// Data for Color ==> CRI (Color Rendering Index and Palette +// actually 20 color that must be good enough for CRI + +// I think 40 color for palette (Skin, Sky, gray) + +//spectral data Colorchecker24 : Red C3 +const double ColorTemp::ColorchechredC3_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.0478,0.0476,0.0474,0.0472,0.0470,0.0466,0.0461,0.0460,0.0459,0.0456,0.0453,0.0451,0.0449,0.0448,0.0447,0.0446,0.0445,0.0441,0.0437,0.0432,0.0427,0.0424,0.0421,0.0419, + 0.0417,0.0415,0.0412,0.0412,0.0412,0.0413,0.0413,0.0415,0.0416,0.0421,0.0426,0.0436,0.0446,0.0469,0.0491,0.0549,0.0607,0.0773,0.0939,0.1376,0.1812,0.2568,0.3323,0.4070,0.4816,0.5308, + 0.5800,0.6059,0.6317,0.6447,0.6577,0.6653,0.6728,0.6761,0.6793,0.6820,0.6847,0.6878,0.6909,0.6945,0.6980,0.7013,0.7046,0.7065,0.7084,0.7107,0.7129,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data Colorchecker24 : Orange A2 +const double ColorTemp::ColorchechOraA2_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.0520,0.0530,0.0540,0.0535,0.0530,0.0532,0.0534,0.0532,0.0529,0.0529,0.0528,0.0530,0.0532,0.0537,0.0542,0.0550,0.0557,0.0565,0.0573,0.0585,0.0597,0.0613,0.0628,0.0656,0.0683,0.0793, + 0.0902,0.1085,0.1268,0.1414,0.1559,0.1645,0.1730,0.1837,0.1944,0.2184,0.2424,0.2877,0.3329,0.3923,0.4517,0.5021,0.5525,0.5739,0.5952,0.5967,0.5982,0.5962,0.5942,0.5932,0.5922,0.5927, + 0.5932,0.5938,0.5944,0.5988,0.6032,0.6105,0.6178,0.6284,0.6389,0.6498,0.6607,0.6699,0.6791,0.6839,0.6886,0.6879,0.6871,0.6886,0.6901,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data Colorchecker24 :yellow D3 +const double ColorTemp::ColorchechYelD3_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.0476,0.0482,0.0488,0.0492,0.0496,0.0498,0.0499,0.0498,0.0496,0.0501,0.0506,0.0516,0.0526,0.0547,0.0567,0.0610,0.0652,0.0733,0.0813,0.0962,0.1110,0.1333,0.1556,0.1884,0.2211, + 0.2782,0.3353,0.4023,0.4692,0.5198,0.5703,0.5976,0.6249,0.6400,0.6551,0.6667,0.6783,0.6901,0.7018,0.7095,0.7171,0.7231,0.7290,0.7329,0.7367,0.7395,0.7423,0.7447,0.7471,0.7490,0.7508, + 0.7533,0.7558,0.7578,0.7598,0.7623,0.7647,0.7654,0.7661,0.7677,0.7693,0.7720,0.7746,0.7780,0.7814,0.7845,0.7876,0.7889,0.7902,0.7920,0.7938, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data Colorchecker24 : Green E2 +const double ColorTemp::ColorchechGreE2_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.0560,0.0583,0.0605,0.0626,0.0646,0.0650,0.0653,0.0657,0.0661,0.0669,0.0676,0.0692,0.0708,0.0737,0.0765,0.0816,0.0867,0.0956,0.1044,0.1194,0.1344,0.1581,0.1818,0.2196,0.2574,0.3166,0.3757, + 0.4297,0.4837,0.5142,0.5446,0.5541,0.5636,0.5608,0.5579,0.5480,0.5381,0.5258,0.5135,0.4959,0.4783,0.4570,0.4356,0.4124,0.3891,0.3710,0.3529,0.3425,0.3320,0.3266,0.3211,0.3180,0.3149, + 0.3129,0.3108,0.3123,0.3137,0.3193,0.3248,0.3335,0.3422,0.3518,0.3613,0.3693,0.3772,0.3810,0.3847,0.3838,0.3829,0.3838,0.3847,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data Colorchecker24 : Green B3 +const double ColorTemp::ColorchechGreB3_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.0531,0.0545,0.0559,0.0563,0.0566,0.0571,0.0576,0.0576,0.0575,0.0581,0.0586,0.0596,0.0606,0.0629,0.0652,0.0699,0.0745,0.0839,0.0932,0.1101,0.1270,0.1521,0.1771,0.2098,0.2424, + 0.2789,0.3154,0.3312,0.3470,0.3431,0.3392,0.3303,0.3213,0.3089,0.2964,0.2788,0.2612,0.2442,0.2271,0.2117,0.1962,0.1815,0.1667,0.1527,0.1386,0.1284,0.1182,0.1124,0.1066,0.1035,0.1003, + 0.0987,0.0971,0.0961,0.0950,0.0950,0.0950,0.0962,0.0973,0.0994,0.1014,0.1045,0.1075,0.1106,0.1137,0.1157,0.1176,0.1175,0.1173,0.1173,0.1173, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data Colorchecker24 : Cyan F3 +const double ColorTemp::ColorchechCyaF3_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.0813,0.1048,0.1282,0.1611,0.1940,0.2198,0.2456,0.2575,0.2693,0.2807,0.2921,0.3079,0.3237,0.3424,0.3611,0.3820,0.4029,0.4234,0.4439,0.4547,0.4654,0.4638,0.4621,0.4482,0.4342,0.4119,0.3895, + 0.3656,0.3417,0.3160,0.2903,0.2654,0.2404,0.2167,0.1929,0.1720,0.1510,0.1368,0.1226,0.1138,0.1049,0.0993,0.0936,0.0890,0.0844,0.0810,0.0776,0.0759,0.0742,0.0733,0.0724,0.0723,0.0722,0.0727, + 0.0732,0.0745,0.0757,0.0763,0.0768,0.0764,0.0759,0.0748,0.0736,0.0723,0.0710,0.0703,0.0696,0.0707,0.0718,0.0756,0.0793,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data Colorchecker24 : Purple D2 +const double ColorTemp::ColorchechPurD2_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.0854,0.1047,0.1240,0.1468,0.1696,0.1826,0.1955,0.1963,0.1970,0.1910,0.1849,0.1750,0.1651,0.1541,0.1430,0.1322,0.1213,0.1117,0.1020,0.0944,0.0868,0.0809,0.0750,0.0703,0.0655, + 0.0627,0.0599,0.0583,0.0567,0.0550,0.0533,0.0525,0.0517,0.0518,0.0519,0.0523,0.0526,0.0525,0.0524,0.0520,0.0516,0.0523,0.0529,0.0560,0.0591,0.0662,0.0732,0.0828,0.0924,0.1021, + 0.1117,0.1222,0.1327,0.1469,0.1610,0.1796,0.1981,0.2173,0.2365,0.2532,0.2698,0.2826,0.2953,0.3022,0.3090,0.3126,0.3161,0.3238,0.3314,0.3504,0.3694,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data Colorchecker24 : Magenta E3 +const double ColorTemp::ColorchechMagE3_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.1112,0.1438,0.1763,0.2294,0.2824,0.3188,0.3552,0.3623,0.3693,0.3653,0.3612,0.3510,0.3407,0.3269,0.3130,0.2981,0.2832,0.2686,0.2539,0.2385,0.2230,0.2083,0.1935,0.1818,0.1700,0.1600,0.1499, + 0.1394,0.1288,0.1188,0.1088,0.1051,0.1014,0.1026,0.1038,0.1041,0.1043,0.1064,0.1085,0.1225,0.1364,0.1701,0.2037,0.2532,0.3027,0.3587,0.4147,0.4683,0.5219,0.5672,0.6124,0.6455,0.6785,0.7009, + 0.7232,0.7391,0.7550,0.7629,0.7707,0.7737,0.7766,0.7778,0.7790,0.7803,0.7815,0.7835,0.7854,0.7896,0.7937,0.8026,0.8114,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data Colorchecker24 : Skin A1 +//use also for palette WB +const double ColorTemp::ColorchechSkiA138_13_14_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.0479,0.051,0.0553,0.058,0.0610,0.062,0.0626,0.0622,0.0619,0.0617,0.0616,0.0615,0.0614,0.0614,0.0615,0.0617,0.0618,0.0618,0.0619,0.0618,0.0618,0.062,0.0622,0.063,0.0638,0.066,0.0696, + 0.073,0.0767,0.078,0.0801,0.0807,0.0817,0.0831,0.0845,0.0870,0.0902,0.0955,0.1017,0.1096,0.1175,0.1250,0.1336,0.1385,0.1435,0.1455,0.1479,0.1490,0.1514,0.1547,0.1580,0.1625,0.1675, + 0.173,0.1772,0.181,0.1842,0.1846,0.1853,0.1831,0.1811,0.1788,0.1765,0.1769,0.1773,0.181,0.1834,0.1874,0.1914,0.1965,0.2018,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data Colorchecker24 : Gray C4 L=67 +//use also for palette WB +const double ColorTemp::ColorchechGraC4_67_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.1074,0.1380,0.1704,0.22,0.2705,0.305,0.3409,0.35,0.3601,0.3628,0.3655,0.3675,0.3698,0.371,0.3724,0.373,0.3733,0.3725,0.3715,0.3705,0.3692, + 0.369,0.3689,0.368,0.3673,0.3678,0.3684,0.37,0.3711,0.3712,0.3714,0.3714,0.3714,0.371,0.3707,0.37,0.3694,0.3697,0.3703,0.3697,0.3692,0.3688,0.3685,0.3675,0.3669,0.3657,0.3647,0.3635,0.3625,0.361, + 0.3596,0.3585,0.3579,0.357,0.3560,0.3555,0.3548,0.3535,0.3526,0.3513,0.3500,0.349,0.3475,0.3467,0.3460,0.3452,0.3444,0.3431,0.3421,0.3411,0.3403,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data Colorchecker24 : Skin B1 +//use also for palette WB +const double ColorTemp::ColorchechSkiB166_18_18_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.0962,0.114,0.1328,0.152,0.1706,0.1755,0.1877,0.189,0.1903,0.1913,0.1923,0.1946,0.1971,0.2015,0.2064,0.215,0.2245,0.239,0.2535,0.273,0.2922,0.31,0.3274,0.337,0.3473, + 0.348,0.3489,0.335,0.3224,0.303,0.2835,0.275,0.2671,0.27,0.2728,0.2735,0.2741,0.279,0.2836,0.308,0.3334,0.375,0.4183,0.457,0.4950,0.516,0.5409,0.5515,0.5625,0.568,0.5731,0.5786, + 0.5820,0.586,0.5902,0.596,0.6025,0.611,0.6174,0.627,0.6375,0.65,0.6626,0.677,0.6910,0.704,0.7171,0.723,0.7339,0.741,0.7475, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data Colorchecker24 : blue sky C1 +//use also for palette WB +const double ColorTemp::ColorchechBluC150_m5_m22_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.1053,0.134,0.1633,0.2075,0.2518,0.283,0.3163,0.324,0.3325,0.334,0.3355,0.3352,0.3349,0.332,0.3294,0.325,0.3199,0.3127,0.3055,0.2955,0.2863,0.28,0.2737,0.267,0.2612,0.249,0.2378,0.228,0.2199, + 0.218,0.2173,0.2146,0.2118,0.20,0.1884,0.178,0.1682,0.166,0.1639,0.162,0.1613,0.158,0.1550,0.1504,0.1458,0.1415,0.1375,0.135,0.1327,0.1316,0.1305,0.1304,0.1302,0.131,0.1322,0.1342,0.1362, + 0.1367,0.1372,0.1356,0.1340,0.1311,0.1288,0.1253,0.1227,0.1205,0.1187,0.1195,0.1205,0.1255,0.1303,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data ColorcheckerDC : blue sky N8 +//use also for palette WB +const double ColorTemp::ColorchechDCBluN881_m7_m14_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.1371,0.17,0.2029,0.291,0.3790,0.495,0.6100,0.67,0.7249,0.737,0.7501,0.7545,0.7597,0.764,0.7677,0.7685,0.7693,0.7677,0.7662,0.763,0.7593,0.753,0.7471,0.737,0.7289,0.718,0.7077,0.705,0.6819,0.666,0.6515,0.636,0.6244, + 0.61,0.5948,0.577,0.5581,0.544,0.5293,0.522,0.5147,0.512,0.5091,0.506,0.5029,0.499,0.4950,0.494,0.4931,0.497,0.5007,0.508,0.5176,0.527,0.5359,0.542,0.5487,0.549,0.5494,0.544, + 0.5375,0.531,0.5244,0.522,0.5207,0.524,0.5264,0.532,0.5369,0.542,0.5505,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data ColorcheckerSG : Skin F7 +//use also for palette WB +const double ColorTemp::ColorchechSGSkiF763_14_26_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0,0.0508,0.64,0.0776,0.903,0.1099,0.1128,0.1256,0.128,0.1307,0.133,0.1357,0.139,0.1425,0.148,0.1523,0.159,0.1669,0.177,0.1871,0.20,0.2118,0.2235,0.2355,0.2445,0.2537,0.259,0.2655,0.268, + 0.2700,0.2708,0.2716,0.2743,0.2770,0.2803,0.2827,0.283,0.2832,0.283,0.2828,0.295,0.3079,0.344,0.3803,0.4105,0.4409,0.455,0.4694,0.477,0.4851,0.4896,0.4962,0.501,0.5066,0.511,0.5160,0.521, + 0.5256,0.529,0.5318,0.535,0.5383,0.541,0.5451,0.549,0.5524,0.556,0.5597,0.562,0.5650,0.568,0.5709,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data ColorcheckerSG : Skin K2 85 11 17 +//use also for palette WB +const double ColorTemp::ColorchechSGSkiK285_11_17_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.1122,0.149,0.1866,0.259,0.3318,0.393,0.4547,0.469,0.4846,0.4845,0.4844,0.4838,0.4834,0.4837,0.4840,0.4847,0.4854,0.4852,0.4849,0.4842,0.4835,0.4832,0.4828,0.485, + 0.4874,0.501,0.5150,0.536,0.5572,0.5685,0.5798,0.586,0.5932,0.5987,0.6142,0.6342,0.6541,0.683,0.7119,0.734,0.7571,0.769,0.7829,0.788,0.7932,0.795,0.7968,0.7973, + 0.7977,0.7974,0.7969,0.797,0.7972,0.7973,0.7975,0.7983,0.7990,0.7978,0.7965,0.7957,0.7949,0.7944,0.7940,0.794,0.7941,0.7943,0.7946,0.7938,0.7930,0.7929,0.7928, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data Colorcheck24 : White A4 L=96 +//use also for palette WB +const double ColorTemp::ColorchechWhiA496_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.1267,0.172,0.2179,0.317,0.4164,0.505,0.6780,0.758,0.8397,0.865,0.8911,0.897,0.9035,0.9062,0.9092,0.9124,0.9154,0.9167,0.9180,0.9187,0.9194,0.92,0.9225,0.9217,0.9209,0.921, + 0.9212,0.9227,0.9242,0.9235,0.9227,0.9232,0.9238,0.9243,0.9248,0.9237,0.9227,0.9239,0.9252,0.924,0.9233,0.9238,0.9242,0.924,0.9239,0.9239,0.9239,0.924,0.9242,0.9239, + 0.9237,0.925,0.9264,0.9276,0.9288,0.9298,0.9308,0.9296,0.9284,0.928,0.9276,0.928,0.9284,0.9294,0.9304,0.9316,0.9328,0.9328,0.9328,0.9337,0.9345, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data Colorcheck24 : foliage Green D1 +const double ColorTemp::ColorchechGreD1_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.0477,0.0492,0.0507,0.0517,0.0527,0.0532,0.0537,0.054,0.0544,0.0554,0.0563,0.0573,0.0584,0.0592,0.0601,0.0607,0.0611,0.0613,0.0619,0.626,0.0634,0.0646,0.0659,0.069, + 0.0721,0.0837,0.0958,0.117,0.1386,0.156,0.1748,0.1802,0.1855,0.1795,0.1742,0.1636,0.1529,0.144,0.1351,0.13,0.1239,0.1202,0.1171,0.1138,0.1106,0.108,0.1048,0.1035, + 0.1022,0.1025,0.1030,0.1041,0.1052,0.106,0.1068,0.107,0.1073,0.1066,0.1060,0.1047,0.1035,0.1028,0.1021,0.1029,0.1034,0.105,0.1069,0.1086,0.1104,0.1127,0.1150, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data ColorchecSG : black N3 L=6 +//use also for palette WB +const double ColorTemp::ColorchechSGBlaN3_6_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.0066,0.0069,0.0071,0.0072,0.0074,0.0073,0.0072,0.0073,0.0074,0.0074,0.0074,0.0074,0.0074,0.0073,0.0073,0.0073,0.0073,0.0072,0.0072,0.0072,0.0072,0.0071,0.0071,0.0071, + 0.0071,0.0071,0.0071,0.0071,0.0071,0.0071,0.0071,0.0071,0.0071,0.0071,0.0071,0.0071,0.0070,0.0070,0.0071,0.0071,0.0071,0.0071,0.0071,0.0071,0.0071,0.0070, + 0.0070,0.0070,0.0070,0.0069,0.0069,0.0069,0.0068,0.0068,0.0068,0.0068,0.0068,0.0068,0.0067,0.0067,0.0067,0.0067,0.0066,0.0066,0.0066,0.0066,0.0066,0.0066,0.0066,0.0067, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data 468 color : gray K14 L=44 +//use also for palette WB +const double ColorTemp::JDC468_GraK14_44_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.04240,0.0485,0.05500,0.0624,0.06930,0.084,0.09820,0.109,0.12160,0.127,0.13300,0.13490,0.13690,0.1379,0.13890,0.1396,0.14060,0.1407,0.14080,0.1423,0.14380,0.1488,0.15370,0.157,0.16040, + 0.157,0.15360,0.1482,0.14290,0.1436,0.14470,0.1454,0.14620,0.137,0.12870,0.1205,0.11250,0.116,0.11930,0.1261,0.13350,0.1367,0.13990,0.139,0.13810,0.1371,0.13610,0.1372,0.13820, + 0.1408,0.14330,0.1475,0.15170,0.1583,0.16500,0.172,0.17940,0.1836,0.18780,0.188,0.18820,0.186,0.18430,0.1801,0.17620,0.1741,0.17210,0.179,0.18420,0.1991,0.21430, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data 468 color : Blue H10 - Gamut > WidegamutRGB +const double ColorTemp::JDC468_BluH10_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.01590,0.028,0.03970,0.0697,0.09970,0.1526,0.20550,0.253,0.30110,0.3412,0.38180,0.423,0.46610,0.4683,0.51030,0.4999,0.49950,0.4785,0.45810,0.429,0.39950,0.374,0.35010,0.3135,0.29630, + 0.2587,0.22070,0.182,0.14450,0.1125,0.09060,0.072,0.04810,0.033,0.01740,0.0113,0.00520,0.004,0.00290,0.0028,0.00270,0.0027,0.00270,0.0027,0.00280,0.0027,0.00270,0.0028,0.00280, + 0.0029,0.00300,0.0029,0.00290,0.0029,0.0029,0.00290,0.0029,0.00290,0.0029,0.00290,0.0029,0.00290,0.0029,0.00290,0.0029,0.0031,0.00320,0.0035,0.00380,0.047,0.00560, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data ColorLab : Skin 35 15 17 +const double ColorTemp::ColabSkin35_15_17_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.0211,0.022, 0.0225,0.0234, 0.0244,0.0294, 0.0349,0.038, 0.0411,0.0425, 0.0441,0.0455, 0.0472,0.0473, 0.0475,0.0463, 0.0452,0.0435, 0.0417,0.0397, 0.0377, + 0.0375, 0.0372,0.0412, 0.0452,0.052, 0.0603,0.0655, 0.0707,0.0722, 0.0736,0.0738, 0.0741,0.0737, 0.0731,0.0721, 0.0711,0.0707, 0.0704,0.071, 0.0717, + 0.0782, 0.0846,0.099, 0.1159,0.1298, 0.1432,0.1497, 0.1581,0.1603, 0.1644,0.1659, 0.1673,0.1679, 0.1690,0.1696, 0.1702,0.1704, 0.1705,0.1706, 0.1707,0.1707, 0.1707,0.1707, 0.1706,0.1706, 0.1707,0.1707, 0.1706,0.1712, 0.1719, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data ColorLab : Skin 57 22 18 +const double ColorTemp::ColabSkin57_22_18_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.0647,0.0677, 0.0709,0.0754, 0.0797,0.099, 0.1181,0.1296, 0.1409,0.1469, 0.1529,0.1594, 0.1657,0.1672, 0.1683,0.1648, 0.1615,0.1561, 0.1506,0.144, 0.1375,0.136, 0.1339, + 0.1437, 0.1531,0.172, 0.1911,0.2032, 0.2153,0.2171, 0.2190,0.2176, 0.2164,0.213, 0.2095,0.2048, 0.2005,0.1985, 0.1965,0.198, 0.1997,0.2196, 0.2396,0.288, 0.3362,0.378, + 0.4209,0.444, 0.4671,0.477, 0.4865,0.491, 0.4955,0.498, 0.5007,0.5027, 0.5048,0.5055, 0.5061,0.5063, 0.5066,0.5065, 0.5063,0.506, 0.5057,0.5056, 0.5055,0.5056, 0.5057,0.5078, 0.5099, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data ColorLab : Skin 40 17 17 +const double ColorTemp::ColabSkin40_17_17_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.0296,0.0306, 0.0317,0.0332, 0.0346,0.042, 0.0498,0.0543, 0.0588,0.061, 0.0632,0.0624, 0.0678,0.068, 0.0682,0.0663, 0.0649,0.0625, 0.0598,0.057, 0.0540,0.0535, 0.0529,0.057, + 0.0631,0.072, 0.0827,0.089, 0.0959,0.0975, 0.0994,0.0996, 0.0997,0.0988, 0.0980,0.0966, 0.0951,0.0945, 0.0939,0.0948, 0.0957,0.105, 0.1143,0.136, 0.1589,0.178, 0.1980, + 0.2095, 0.2194,0.224, 0.2283,0.2302, 0.2325,0.2337, 0.2348,0.2357, 0.2366,0.2369, 0.2371,0.2372, 0.2373,0.2373, 0.2373,0.2373, 0.2372,0.2372, 0.2372,0.2372, 0.2372,0.238, 0.2389, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data ColorLab : Skin 91 4 14 +const double ColorTemp::ColabSkin91_4_14_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.1430,0.16, 0.1778,0.202, 0.2303,0.301, 0.3813,0.4245, 0.4692,0.499, 0.5287,0.5635, 0.5977,0.6175, 0.6372,0.6394, 0.6418,0.638, 0.6341,0.6228, 0.6117,0.6121, 0.6125, + 0.646, 0.6807,0.742, 0.8032,0.8355, 0.8687,0.8595, 0.8510,0.828, 0.8059,0.778, 0.7490,0.721, 0.6914,0.676, 0.6608,0.657, 0.6530,0.6565, 0.7001,0.7609, 0.8219, + 0.876, 0.9297,0.9598, 0.9901,1.003, 1.0156,1.021, 1.0289,1.0346, 1.0396,1.045, 1.0513,1.0538, 1.0561,1.0559, 1.0557,1.054, 1.0523,1.049, 1.0466,1.045, 1.0436,1.0445, 1.0455,1.053, 1.0605, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data ColorLab : Skin 87 8 8 +const double ColorTemp::ColabSkin87_8_8_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.1433,0.161, 0.1780,0.204, 0.2305,0.306, 0.3828,0.428, 0.4722,0.502, 0.5317,0.5645, 0.5997,0.618, 0.6366,0.6368, 0.6370,0.631, 0.6251,0.6120, 0.5994,0.596, + 0.5931,0.618, 0.6420,0.705, 0.7347,0.757, 0.7785,0.765, 0.7532,0.71, 0.7062,0.677, 0.6491,0.62, 0.5922,0.577, 0.5619,0.5586, 0.5556,0.579, 0.6121, + 0.684, 0.7563,0.82, 0.8837,0.918, 0.9545,0.969, 0.9843,0.992, 0.9991,1.005, 1.0104,1.016, 1.0223,1.0248, 1.0273,1.0272, 1.0271,1.025, 1.0238,1.02, 1.0182,1.017, 1.0151,1.016, 1.0171,1.024, 1.0321, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data ColorLab : Skin 89 8 21 +const double ColorTemp::ColabSkin89_8_21_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.1394,0.152, 0.1659,0.1855, 0.2052,0.266, 0.3277,0.363, 0.3988,0.422, 0.4450,0.472, 0.4984,0.512, 0.5270,0.5274, 0.5278,0.522, 0.5177,0.5065, 0.4960,0.4975, + 0.4995,0.535, 0.5721,0.637, 0.7016,0.7395, 0.7786,0.7777, 0.7767,0.763, 0.7485,0.728, 0.7081,0.687, 0.6649,0.653, 0.6425,0.641, 0.6391,0.665, 0.6925,0.76, + 0.8266,0.885, 0.9447,0.975, 1.0106,1.025, 1.0383,1.045, 1.0525,1.058, 1.0628,1.068, 1.0730,1.075, 1.0768,1.0768, 1.0769,1.0755, 1.0744,1.0724, 1.0704,1.069, 1.0685,1.0691, 1.0697,1.075, 1.0823, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data ColorLab : Skin 75 8 4 +const double ColorTemp::ColabSkin75_8_4_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.1030,0.116, 0.1294,0.1495, 0.1696,0.227, 0.2847,0.319, 0.3524,0.375, 0.3977,0.423, 0.4492,0.462, 0.4770,0.4768, 0.4767,0.471, 0.4675,0.458, 0.4480,0.444, 0.4408, + 0.455, 0.4688,0.496, 0.5243,0.535, 0.5465,0.534, 0.5228,0.503, 0.4851,0.463, 0.4408,0.419, 0.3974,0.385, 0.3741,0.371, 0.3692,0.391, 0.4110,0.464, 0.5180, + 0.565, 0.6126,0.638, 0.6651,0.676, 0.6871,0.692, 0.6979,0.702, 0.7062,0.71, 0.7151,0.717, 0.7189,0.7188, 0.7187,0.717, 0.7162,0.714, 0.7119,0.7105, 0.7095,0.7097, 0.7110,0.716, 0.7223, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data ColorLab : Skin 75 10 33 +const double ColorTemp::ColabSkin75_10_33_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.0873,0.091, 0.0967,0.103, 0.1097,0.135, 0.1617,0.177, 0.1913,0.198, 0.2086,0.218, 0.2289,0.234, 0.2383,0.2375, 0.2370,0.2335, 0.2299,0.223, 0.2180,0.222, + 0.2259,0.256, 0.2860,0.338, 0.3905,0.426, 0.4613,0.47, 0.4786,0.478, 0.4772,0.471, 0.4668,0.459, 0.4522,0.449, 0.4454,0.446, 0.4467,0.464, 0.4834,0.527, + 0.5727,0.609, 0.6511,0.673, 0.6946,0.703, 0.7130,0.718, 0.7224,0.725, 0.7285,0.731, 0.7337,0.7345, 0.7351,0.7353, 0.7355,0.735, 0.7348,0.7342, 0.7337,0.7336, 0.7335,0.7335, 0.7336,0.737, 0.7395, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data ColorLab : Skin 65 33 11 +const double ColorTemp::ColabSkin65_33_11_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.1067,0.113, 0.1182,0.126, 0.1346,0.165, 0.2033,0.224, 0.2448,0.259, 0.2666,0.277, 0.2891,0.291, 0.2927,0.285, 0.2783,0.268, 0.2569,0.244, 0.2323,0.225, 0.2195, + 0.225, 0.2323,0.248, 0.2655,0.275, 0.2832,0.281, 0.2797,0.275, 0.2708,0.264, 0.2567,0.248, 0.2403,0.236, 0.2326,0.235, 0.2386,0.274, 0.3116,0.40, 0.4885,0.56, + 0.6435,0.688, 0.7279,0.745, 0.7633,0.772, 0.7791,0.783, 0.7883,0.792, 0.7955,0.7965, 0.7978,0.7982, 0.7989,0.7985, 0.7983,0.7975, 0.7971,0.7968, 0.7966,0.7968, 0.7970,0.801, 0.8043, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data ColorLab : Skin 65 7 24 +const double ColorTemp::ColabSkin65_7_24_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.0619,0.066, 0.0710,0.077, 0.0840,0.106, 0.1288,0.142, 0.1546,0.163, 0.1706,0.179, 0.1893,0.194, 0.1989,0.1988, 0.1987,0.196, 0.1941,0.189, 0.1853,0.188, 0.1894, + 0.209, 0.2282,0.262, 0.2962,0.318, 0.3402,0.343, 0.3469,0.343, 0.3407,0.334, 0.3285,0.321, 0.3140,0.31, 0.3069,0.308, 0.3066,0.319, 0.3311,0.362, 0.3918,0.418, + 0.4451,0.459, 0.4747,0.481, 0.4873,0.491, 0.4937,0.496, 0.4981,0.501, 0.5022,0.503, 0.5035,0.5035, 0.5036,0.5032, 0.5029,0.5022, 0.5016,0.5013, 0.5011,0.5013, 0.5014,0.504, 0.5063, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data ColorLab : Skin 57 19 6 +const double ColorTemp::ColabSkin57_19_6_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.0662,0.071, 0.0773,0.085, 0.0939,0.115, 0.1491,0.165, 0.1821,0.192, 0.2019,0.214, 0.2236,0.228, 0.2321,0.2298, 0.2266,0.221, 0.2161,0.208, 0.2019,0.199, + 0.1951,0.201, 0.2066,0.219, 0.2325,0.239, 0.2443,0.241, 0.2366,0.23, 0.2235,0.215, 0.2068,0.199, 0.1895,0.185, 0.1806,0.1811, 0.1816,0.20, 0.2197,0.267, 0.3135, + 0.355, 0.3960,0.418, 0.4411,0.449, 0.4600,0.4643, 0.4687,0.471, 0.4743,0.477, 0.4792,0.48, 0.4811,0.4813, 0.4815,0.481, 0.4806,0.4798, 0.4790,0.4786, 0.4782,0.4786, 0.4788,0.481, 0.4844, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data ColorLab : Skin 57 4 19 +const double ColorTemp::ColabSkin57_4_19_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.0430,0.047, 0.0505,0.056, 0.0614,0.077, 0.0963,0.1063, 0.1164,0.123, 0.1294,0.137, 0.1448,0.149, 0.1533,0.154, 0.1544,0.153, 0.1521,0.149, 0.1463,0.148, + 0.1496,0.164, 0.1780,0.202, 0.2273,0.242, 0.2585,0.26, 0.2616,0.258, 0.2550,0.2495, 0.2442,0.238, 0.2320,0.229, 0.2258,0.2253, 0.2247,0.232, 0.2394, + 0.258, 0.2763,0.292, 0.3087,0.318, 0.3269,0.331, 0.3346,0.337, 0.3387,0.341, 0.3417,0.343, 0.3447,0.345, 0.3457,0.3457, 0.3457,0.3455, 0.3451,0.3445, 0.3439,0.3437, 0.3435,0.3437, 0.3438,0.346, 0.3475, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data ColorLab : Skin 57 10 28 +const double ColorTemp::ColabSkin57_10_28_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.0463,0.048, 0.0505,0.053, 0.0563,0.069, 0.0816,0.088, 0.0961,0.102, 0.1041,0.1085, 0.1135,0.1155, 0.1174,0.1168, 0.1161,0.114, 0.1118,0.1085, 0.1054,0.1074, 0.1094,0.124, + 0.1406,0.168, 0.1951,0.223, 0.2325,0.238, 0.2426,0.243, 0.2432,0.242, 0.2391,0.239, 0.2326,0.231, 0.2297,0.234, 0.2309,0.242, 0.2516,0.277, 0.3017,0.324, + 0.3456,0.358, 0.3700,0.375, 0.3802,0.3827, 0.3854,0.387, 0.3887,0.39, 0.3913,0.3916, 0.3920,0.3921, 0.3923,0.3921, 0.3920,0.3918, 0.3916,0.3916, 0.3915,0.3915, 0.3915,0.393, 0.3945, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data ColorLab : Skin 40 7 19 +const double ColorTemp::ColabSkin40_7_19_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.0215,0.023, 0.0240,0.026, 0.0275,0.033, 0.0409,0.044, 0.0487,0.051, 0.0532,0.056, 0.0585,0.0595, 0.0608,0.0605, 0.0602,0.059, 0.0581,0.057, 0.0549,0.0555, 0.0562, + 0.061, 0.0692,0.08, 0.0922,0.099, 0.1075,0.109, 0.1107,0.11, 0.1098,0.1082, 0.1069,0.1045, 0.1031,0.102, 0.1013,0.1015, 0.1016,0.106, 0.1112,0.123, 0.1348,0.145, + 0.1554,0.161, 0.1668,0.169, 0.1716,0.1728, 0.1741,0.175, 0.1756,0.1763, 0.1769,0.1771, 0.1773,0.1773, 0.1774,0.1773, 0.1772,0.177, 0.1769,0.1769, 0.1769,0.1769, 0.1769,0.1777, 0.1784, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data ColorLab : Skin 40 17 6 +const double ColorTemp::ColabSkin40_17_6_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.0314,0.033, 0.0359,0.039, 0.0427,0.054, 0.0668,0.074, 0.0812,0.085, 0.0895,0.094, 0.0985,0.10, 0.1015,0.0991, 0.0984,0.096, 0.0930,0.089, 0.0861,0.085, 0.0828, + 0.085, 0.0878,0.094, 0.0995,0.103, 0.1052,0.1035, 0.1026,0.10, 0.0976,0.094, 0.0911,0.088, 0.0840,0.083, 0.0805,0.081, 0.0814,0.09, 0.1006,0.124, + 0.1474,0.1685, 0.1885,0.1995, 0.2110,0.216, 0.2204,0.223, 0.2247,0.226, 0.2273,0.2284, 0.2296,0.230, 0.2304,0.2305, 0.2306,0.2305, 0.2303,0.23, 0.2297,0.2296, 0.2294,0.2295, 0.2296,0.231, 0.2321, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data ColorLab : Skin 40 4 11 +const double ColorTemp::ColabSkin40_4_11_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.0209,0.023, 0.0250,0.028, 0.0310,0.039, 0.0497,0.056, 0.0605,0.064, 0.0675,0.072, 0.0758,0.078, 0.0802,0.0803, 0.0804,0.0797, 0.0790,0.078, 0.0758,0.076, 0.0764,0.082, + 0.0875,0.098, 0.1072,0.113, 0.1189,0.1187, 0.1185,0.116, 0.1141,0.111, 0.1078,0.104, 0.1012,0.099, 0.0977,0.098, 0.0971,0.101, 0.1049,0.115, 0.1245,0.133, + 0.1417,0.147, 0.1513,0.153, 0.1554,0.1564, 0.1575,0.158, 0.1590,0.1598, 0.1606,0.1608, 0.1611,0.1611, 0.1611,0.1609, 0.1608,0.1604, 0.1601,0.160, 0.1598,0.1599, 0.1600,0.1609, 0.1619, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data ColorLab : Skin 33 6 15 +const double ColorTemp::ColabSkin33_6_15_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.0143,0.015, 0.0162,0.0175, 0.0189,0.023, 0.0286,0.031, 0.0342,0.036, 0.0376,0.039, 0.0415,0.0425, 0.0434,0.0432, 0.0431,0.0425, 0.0418,0.041, 0.0396,0.04, + 0.0404,0.0444, 0.0488,0.056, 0.0638,0.0689, 0.0735,0.074, 0.0752,0.0745, 0.0741,0.073, 0.0717,0.070, 0.0688,0.0681, 0.0673,0.0673, 0.0674,0.0710, 0.0737,0.0810, + 0.0889,0.0960, 0.1023,0.1065, 0.1098,0.1120, 0.1129,0.1135, 0.1145,0.1150, 0.1155,0.1160, 0.1164,0.1165, 0.1167,0.1167, 0.1168,0.1167, 0.1166,0.1165, 0.1164,0.1164, 0.1163,0.1163, 0.1164,0.1170, 0.1174, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data ColorLab : Skin 33 15 5 +const double ColorTemp::ColabSkin33_15_5_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.0212,0.023, 0.0243,0.0265, 0.0289,0.037, 0.0451,0.051, 0.0549,0.058, 0.0605,0.063, 0.0666,0.0675, 0.0686,0.0672, 0.0664,0.065, 0.0627,0.0061, 0.0580,0.0565, 0.0557, + 0.057, 0.0590,0.063, 0.0666,0.069, 0.0703,0.0694, 0.0684,0.0666, 0.0651,0.063, 0.0607,0.0585, 0.0559,0.0545, 0.0535,0.0540, 0.0542,0.0610, 0.0672,0.0832, + 0.0992,0.1132, 0.1272,0.1345, 0.1425,0.1455, 0.1489,0.1505, 0.1518,0.1527, 0.1536,0.1545, 0.1552,0.1555, 0.1557,0.1558, 0.1559,0.1558, 0.1557,0.1155, 0.1552,0.1551, 0.1550,0.1551, 0.1552,0.1560, 0.1569, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; +//spectral data ColorLab : Skin 33 10 15 +const double ColorTemp::ColabSkin33_10_15_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.0166,0.0175, 0.0183,0.0194, 0.0207,0.0260, 0.0306,0.033, 0.0364,0.0380, 0.0396,0.0415, 0.0431,0.0437, 0.0443,0.0438, 0.0432,0.0420, 0.0409,0.0395, 0.0380,0.0380, + 0.0381,0.0415, 0.0456,0.0525, 0.0595,0.0645, 0.0686,0.0695, 0.0705,0.0702, 0.0700,0.0690, 0.0681,0.0667, 0.0655,0.065, 0.0644,0.0648, 0.0650,0.0695, 0.0739,0.0852, + 0.0955,0.1040, 0.1145,0.1196, 0.1249,0.1271, 0.1293,0.1305, 0.1314,0.1322, 0.1327,0.1332, 0.1337,0.1338, 0.1340,0.1340, 0.1341,0.1340, 0.1340,0.1339, 0.1338,0.1338, 0.1338,0.1338, 0.1338,0.1345, 0.1349, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data ColorLab : Skin 24 5 6 +const double ColorTemp::ColabSkin24_5_6_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.0086,0.0095, 0.0102,0.0112, 0.0127,0.0167, 0.0203,0.0225, 0.0248,0.0265, 0.0277,0.0295, 0.0309,0.0315, 0.0325,0.0324, 0.0323,0.0319, 0.0315,0.0307, 0.0299,0.0298, + 0.0297,0.0315, 0.0330,0.0365, 0.0392,0.0412, 0.0427,0.0424, 0.0421,0.0410, 0.0402,0.0390, 0.0377,0.0365, 0.0351,0.0345, 0.0337,0.0337, 0.0336,0.0356, 0.0374,0.0415, + 0.0470,0.0512, 0.0554,0.0575, 0.0601,0.0610, 0.0620,0.0625, 0.0630,0.0634, 0.0637,0.0640, 0.0643,0.0645, 0.0646,0.0646, 0.0646,0.0645, 0.0644,0.0643, 0.0642,0.0642, 0.0641,0.0641, 0.0641,0.0645, 0.0649, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data ColorLab : Skin 26 18 18 +const double ColorTemp::ColabSkin26_18_18_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.0135,0.0137, 0.0138,0.0139, 0.0140,0.0163, 0.0187,0.0202, 0.0215,0.0220, 0.0224,0.0228, 0.0231,0.0227, 0.0222,0.0212, 0.0202,0.0189, 0.0174,0.0161, 0.0146,0.0143, + 0.0140,0.0163, 0.0184,0.0224, 0.0268,0.0291, 0.0331,0.0348, 0.0358,0.0366, 0.0374,0.0378, 0.0380,0.0380, 0.0379,0.0380, 0.0381,0.0388, 0.0394,0.0440, 0.0490, + 0.0605, 0.0720,0.0821, 0.0921,0.0976, 0.1030,0.1056, 0.1076,0.1087, 0.1097,0.1103, 0.1108,0.1111, 0.1115,0.1115, 0.1116,0.1117, 0.1118,0.1118, 0.1119,0.1119, 0.1120,0.1120, 0.1121,0.1121, 0.1120,0.1123, 0.1126, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data ColorLab : Skin 24 7 5 +const double ColorTemp::ColabSkin24_7_5_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.0093,0.0105, 0.0111,0.0125, 0.0137,0.0180, 0.0221,0.0245, 0.0270,0.0285, 0.0301,0.0316, 0.0336,0.0345, 0.0353,0.0350, 0.0349,0.0343, 0.0338,0.0329, 0.0320,0.0317, 0.0315, + 0.0328, 0.0342,0.0368, 0.0397,0.0412, 0.0424,0.0420, 0.0415,0.0404, 0.0393,0.0379, 0.0366,0.0352, 0.0337,0.0330, 0.0323,0.0322, 0.0322,0.0344, 0.0367,0.0422, 0.0479,0.0529, + 0.0578,0.0606, 0.0633,0.0644, 0.0656,0.0662, 0.0667,0.0670, 0.0674,0.0678, 0.0681,0.0683, 0.0684,0.0684, 0.0684,0.0683, 0.0683,0.0682, 0.0680,0.0679, 0.0678,0.0678, 0.0679,0.0683, 0.0688, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data ColorLab : Skin 24 4 2 +const double ColorTemp::ColabSkin20_4_2_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.0064,0.0074, 0.0080,0.00903, 0.0104,0.0139, 0.0174,0.0189, 0.0216,0.0222, 0.0243,0.0258, 0.0274,0.0282, 0.0291,0.0290, 0.0290,0.0288, 0.0284,0.0278, 0.0272,0.0270, 0.0267,0.0276, + 0.0285,0.0302, 0.0320,0.0327, 0.0335,0.0328, 0.0321,0.0311, 0.0299,0.0280, 0.0272,0.0259, 0.0246,0.0239, 0.0232,0.0230, 0.0229,0.0243, 0.0256,0.0291, 0.0324,0.0354, + 0.0385,0.0401, 0.0418,0.0425, 0.0432,0.0435, 0.0439,0.0442, 0.0444,0.0447, 0.0450,0.0451, 0.0452,0.0452, 0.0452,0.0451, 0.0450,0.0449, 0.0448,0.0447, 0.0446,0.0447, 0.0447,0.0450, 0.0454, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data ColorLab : Skin 98 -2 10 +const double ColorTemp::ColabSkin98_m2_10_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.1627,0.1870, 0.2115,0.2480, 0.2860,0.3870, 0.4878,0.5460, 0.6050,0.6460, 0.6874,0.7355, 0.7836,0.8130, 0.8424,0.8494, 0.8543,0.8520, 0.8508,0.8390, 0.8267,0.8274, 0.8280, + 0.8680, 0.9076,0.9600, 1.0497,1.089, 1.1190,1.10, 1.0836,1.045, 1.0140,0.975, 0.9305,0.884, 0.8486,0.826, 0.8042,0.7980, 0.7895,0.8093, 0.8292,0.884, 0.9376,0.987, + 1.0341,1.059, 1.0892,1.104, 1.1125,1.1253, 1.1255,1.131, 1.1375,1.145, 1.1520,1.155, 1.1585,1.158, 1.1574,1.1548, 1.1523,1.148, 1.1439,1.141, 1.1394,1.141, 1.1423,1.151, 1.1619, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data ColorLab : Skin 90 -1 20 +const double ColorTemp::ColabSkin90_m1_20_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.1228,0.138, 0.1532,0.175, 0.1987,0.261, 0.3279,0.365, 0.4022,0.428, 0.4537,0.4842, 0.5147,0.5337, 0.5521,0.557, 0.5611,0.5602, 0.5593,0.551, 0.5438,0.548, + 0.5527,0.593, 0.6334,0.703, 0.7732,0.8135, 0.8543,0.851, 0.8474,0.829, 0.8105,0.786, 0.7613,0.736, 0.7105,0.697, 0.6835,0.679, 0.6750,0.6895, 0.7045,0.743, + 0.7832,0.818, 0.8530,0.873, 0.8929,0.899, 0.9099,0.914, 0.9197,0.924, 0.9282,0.933, 0.9380,0.9395, 0.9419,0.9416, 0.9413,0.9398, 0.9382,0.9357, 0.9332,0.9322, 0.9306,0.9315, 0.9322,0.939, 0.9452, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data ColorLab : Skin 95 0 4 +const double ColorTemp::ColabSkin95_0_4_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.1614,0.1865, 0.2118,0.2495, 0.2889,0.392, 0.4969,0.557, 0.6185,0.6605, 0.7035,0.749, 0.8018,0.832, 0.8605,0.865, 0.8696,0.866, 0.8633,0.849, 0.8365,0.834, + 0.8308,0.861, 0.8911,0.946, 1.0030,1.025, 1.0490,1.025, 1.0030,0.964, 0.9278,0.884, 0.8407,0.7985, 0.7565,0.734, 0.7107,0.6985, 0.6962,0.718, 0.7416,0.803, + 0.8642,0.919, 0.9733,1.001, 1.0349,1.051, 1.0609,1.068, 1.0747,1.081, 1.0872,1.095, 1.1021,1.105, 1.1089,1.1085, 1.1079,1.1055, 1.1027,1.098, 1.0940,1.091, 1.0892,1.0905, 1.0923,1.102, 1.1123, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data ColorLab : Skin 81 2 14 +const double ColorTemp::ColabSkin81_2_14_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.1029,0.116, 0.1285,0.148, 0.1672,0.222, 0.2774,0.311, 0.3412,0.362, 0.3849,0.410, 0.4359,0.451, 0.4659,0.468, 0.4706,0.4685, 0.4664,0.4685, 0.4512,0.4525, 0.4536, + 0.461, 0.5076,0.551, 0.6035,0.6295, 0.6559,0.6495, 0.6442,0.627, 0.6112,0.5905, 0.5691,0.537, 0.5266,0.515, 0.5039,0.501, 0.4975,0.5125, 0.5283,0.568, 0.6087,0.643, + 0.6799,0.700, 0.7200,0.729, 0.7370,0.7415, 0.7461,0.750, 0.7536,0.759, 0.7620,0.764, 0.7655,0.7653, 0.7651,0.764, 0.7626,0.761, 0.7583,0.7572, 0.7561,0.7567, 0.7575,0.758, 0.7685, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data ColorLab : Skin 87 3 10 +const double ColorTemp::ColabSkin87_3_10_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.1295,0.146, 0.1639,0.190, 0.2160,0.291, 0.3626,0.405, 0.4480,0.476, 0.5066,0.541, 0.5743,0.593, 0.6136,0.616, 0.6186,0.614, 0.6119,0.601, 0.5911,0.5905, + 0.5897,0.623, 0.6460,0.697, 0.7483,0.773, 0.7992,0.788, 0.7759,0.752, 0.7287,0.699, 0.6712,0.642, 0.6141,0.598, 0.5835,0.579, 0.5750,0.596, 0.6162,0.669, + 0.7239,0.772, 0.8193,0.845, 0.8728,0.888, 0.8954,0.901, 0.9073,0.912, 0.9171,0.922, 0.9281,0.931, 0.9328,0.9325, 0.9323,0.931, 0.9289,0.926, 0.9232,0.9215, 0.9201,0.921, 0.9220,0.929, 0.9364, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data ColorLab : Skin 77 12 21 +const double ColorTemp::ColabSkin77_12_21_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.1039,0.111, 0.1205,0.132, 0.1448,0.185, 0.2261,0.249, 0.2734,0.287, 0.3028,0.318, 0.3364,0.345, 0.3525,0.351, 0.3499,0.345, 0.3397,0.3295, 0.3224,0.329, 0.3234, + 0.349, 0.3729,0.418, 0.4625,0.490, 0.5173,0.5185, 0.5196,0.511, 0.5045,0.492, 0.4807,0.467, 0.4543,0.447, 0.4410,0.4409, 0.4407,0.464, 0.4872,0.544, 0.6020,0.6522, + 0.7029,0.731, 0.7588,0.771, 0.7823,0.787, 0.7939,0.798, 0.8017,0.805, 0.8090,0.8103, 0.8115,0.8117, 0.8118,0.8111, 0.8104,0.8193, 0.8081,0.8076, 0.8070,0.8073, 0.8077,0.812, 0.8162, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data ColorLab : Skin 70 7 32 +const double ColorTemp::ColabSkin70_7_32_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.0695,0.074, 0.0777,0.084, 0.0890,0.104, 0.1321,0.144, 0.1565,0.164, 0.1713,0.1795, 0.1889,0.194, 0.1978,0.198, 0.1983,0.196, 0.1939,0.189, 0.1853,0.189, + 0.1933,0.219, 0.2458,0.291, 0.3362,0.367, 0.3974,0.405, 0.4120,0.411, 0.4101,0.406, 0.4007,0.394, 0.3877,0.385, 0.3816,0.3817, 0.3819,0.395, 0.4081,0.440, + 0.4721,0.498, 0.5284,0.544, 0.5598,0.566, 0.5730,0.577, 0.5801,0.5825, 0.5848,0.587, 0.5890,0.5895, 0.5901,0.5903, 0.5903,0.59, 0.5897,0.5892, 0.5887,0.5885, 0.5884,0.5885, 0.5886,0.5896, 0.5934, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data ColorLab : Sky 60 0 -31 +const double ColorTemp::ColabSky60_0_m31_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.0752,0.094, 0.1121,0.141, 0.1699,0.243, 0.3150,0.357, 0.4015,0.432, 0.4631,0.497, 0.5325,0.553, 0.5730,0.574, 0.5758,0.572, 0.5695,0.559, 0.5503,0.539, + 0.5284,0.5175, 0.5066,0.493, 0.4800,0.459, 0.4336,0.401, 0.3684,0.333, 0.3003,0.265, 0.2313,0.199, 0.1695,0.167, 0.1349,0.129, 0.1234,0.136, 0.1489,0.184, + 0.2212,0.253, 0.2858,0.303, 0.3218,0.329, 0.3370,0.341, 0.3440,0.348, 0.3512,0.355, 0.3606,0.363, 0.3658,0.3653, 0.3649,0.3625, 0.3611,0.358, 0.3544,0.352, 0.3502,0.3512, 0.3529,0.359, 0.3660, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +//spectral data ColorLab : Sky 42 0 -24 +const double ColorTemp::ColabSky42_0_m24_spect[97] = { + 0.0,0.0,0.0,0.0,0.0,0.0, + 0.0336,0.041, 0.0501,0.063, 0.0761,0.103, 0.1412,0.151, 0.1799,0.193, 0.2076,0.223, 0.2387,0.248, 0.2569,0.2575, 0.2581,0.256, 0.2553,0.250, 0.2466,0.2411, + 0.2368,0.2318, 0.2268,0.2205, 0.2145,0.204, 0.1935,0.179, 0.1641,0.149, 0.1335,0.118, 0.1025,0.087, 0.0748,0.067, 0.0593,0.056, 0.0541,0.059, 0.0655,0.081, + 0.0979,0.112, 0.1269,0.134, 0.1430,0.147, 0.1497,0.151, 0.1529,0.1545, 0.1561,0.158, 0.1603,0.1616, 0.1627,0.1625, 0.1623,0.1614, 0.1605,0.159, 0.1575,0.1567, 0.1557,0.1563, 0.1569,0.159, 0.1627, + 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 +}; + +/* + * Name: XYZtoCorColorTemp.c + * + * Author: Bruce Justin Lindbloom + * + * Copyright (c) 2003 Bruce Justin Lindbloom. All rights reserved. + * + * + * Description: + * This is an implementation of Robertson's method of computing the correlated color + * temperature of an XYZ color. It can compute correlated color temperatures in the + * range [1666.7K, infinity]. + * + * Reference: + * "Color Science: Concepts and Methods, Quantitative Data and Formulae", Second Edition, + * 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) +{ + + typedef struct UVT { + double u; + double v; + double t; + } UVT; + + double rt[31] = { /* reciprocal temperature (K) */ + DBL_MIN, 10.0e-6, 20.0e-6, 30.0e-6, 40.0e-6, 50.0e-6, + 60.0e-6, 70.0e-6, 80.0e-6, 90.0e-6, 100.0e-6, 125.0e-6, + 150.0e-6, 175.0e-6, 200.0e-6, 225.0e-6, 250.0e-6, 275.0e-6, + 300.0e-6, 325.0e-6, 350.0e-6, 375.0e-6, 400.0e-6, 425.0e-6, + 450.0e-6, 475.0e-6, 500.0e-6, 525.0e-6, 550.0e-6, 575.0e-6, + 600.0e-6 + }; + + UVT uvt[31] = { + {0.18006, 0.26352, -0.24341}, + {0.18066, 0.26589, -0.25479}, + {0.18133, 0.26846, -0.26876}, + {0.18208, 0.27119, -0.28539}, + {0.18293, 0.27407, -0.30470}, + {0.18388, 0.27709, -0.32675}, + {0.18494, 0.28021, -0.35156}, + {0.18611, 0.28342, -0.37915}, + {0.18740, 0.28668, -0.40955}, + {0.18880, 0.28997, -0.44278}, + {0.19032, 0.29326, -0.47888}, + {0.19462, 0.30141, -0.58204}, + {0.19962, 0.30921, -0.70471}, + {0.20525, 0.31647, -0.84901}, + {0.21142, 0.32312, -1.0182}, + {0.21807, 0.32909, -1.2168}, + {0.22511, 0.33439, -1.4512}, + {0.23247, 0.33904, -1.7298}, + {0.24010, 0.34308, -2.0637}, + {0.24792, 0.34655, -2.4681}, + {0.25591, 0.34951, -2.9641}, + {0.26400, 0.35200, -3.5814}, + {0.27218, 0.35407, -4.3633}, + {0.28039, 0.35577, -5.3762}, + {0.28863, 0.35714, -6.7262}, + {0.29685, 0.35823, -8.5955}, + {0.30505, 0.35907, -11.324}, + {0.31320, 0.35968, -15.628}, + {0.32129, 0.36011, -23.325}, + {0.32931, 0.36038, -40.770}, + {0.33724, 0.36051, -116.45} + }; + + double us, vs, p, di, dm; + int i; + if ((x0 < 1.0e-20) && (y0 < 1.0e-20) && (z0 < 1.0e-20)) + return -1; /* protect against possible divide-by-zero failure */ + us = (4.0 * x0) / (x0 + 15.0 * y0 + 3.0 * z0); + vs = (6.0 * y0) / (x0 + 15.0 * y0 + 3.0 * z0); + dm = 0.0; + for (i = 0; i < 31; i++) { + di = (vs - uvt[i].v) - uvt[i].t * (us - uvt[i].u); + if ((i > 0) && (((di < 0.0) && (dm >= 0.0)) || ((di >= 0.0) && (dm < 0.0)))) + break; /* found lines bounding (us, vs) : i-1 and i */ + dm = di; + } + if (i == 31) + 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)); + temp = p; + return 0; /* success */ +} + +void ColorTemp::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 ) { + +// CIECAT02 - J.Desmis January 2012 review September 2012 + const double whiteD50p[3]={0.9646019585,1.0,0.8244507152};//calculate with these tools + + double cam_dest[3]={0.,0.,0.}; + double cam_orig[3]={0.,0.,0.}; + const double CAT02[3][3] = {{0.7328, 0.4296, -0.1624},//CAT02 2002 + {-0.7036, 1.6975, 0.0061}, + {0.0030, 0.0136, 0.9834}}; + const double INVCAT02[3][3] = {{1.09612382083551, -0.278869000218287, 0.182745179382773}, //Inverse CAT02 + {0.454369041975359, 0.4735331543070412, 0.0720978037172291}, + {-0.009627608738442936, -0.00569803121611342, 1.01532563995454}}; + + double inv_white_orig[3][3]={{0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}}; + double intermed[3][3]={{0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}}; + + double intermed_2[3][3]={{0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}}; + double CAM02[3][3]= {{0., 0., 0.}, + {0., 0., 0.}, + {0., 0., 0.}}; + double D=adap; + + //white destination Wd : RT use always D50 + cam_dest[0]=CAT02[0][0]*whiteD50p[0]+CAT02[0][1]*whiteD50p[1]+CAT02[0][2]*whiteD50p[2];//Cone reponse RoD + cam_dest[1]=CAT02[1][0]*whiteD50p[0]+CAT02[1][1]*whiteD50p[1]+CAT02[1][2]*whiteD50p[2];//GaD + cam_dest[2]=CAT02[2][0]*whiteD50p[0]+CAT02[2][1]*whiteD50p[1]+CAT02[2][2]*whiteD50p[2];//BeD + + //origin white Ws : A, D65, custom, etc. + cam_orig[0]=CAT02[0][0]*Xw+CAT02[0][1]*Yw+CAT02[0][2]*Zw;//Cone reponse RoS + cam_orig[1]=CAT02[1][0]*Xw+CAT02[1][1]*Yw+CAT02[1][2]*Zw; + cam_orig[2]=CAT02[2][0]*Xw+CAT02[2][1]*Yw+CAT02[2][2]*Zw; + + //inverse white + inv_white_orig[0][0]=1./cam_orig[0];// 1/RoS + inv_white_orig[1][1]=1./cam_orig[1];// 1/GaS + inv_white_orig[2][2]=1./cam_orig[2];// 1/BeS + + //intermediates computation + for(int i=0; i< 3;i++) + for(int j=0; j<3 ; j++) + intermed[i][j]=inv_white_orig[i][i]*CAT02[i][j]; + + for(int i=0; i< 3;i++) + for(int j=0; j<3 ; j++) + intermed_2[i][j]=cam_dest[i]*intermed[i][j]; + //and CAM02 + for(int i=0; i<3; i++) + for(int j=0; j<3; j++) + for(int k=0; k<3; k++) + CAM02[i][j]+=INVCAT02[i][k]*intermed_2[k][j]; + + //adaptation jdc : slightly different from CIECAM02 : Rc=(Yw(D/Rw)+(1-D))*R , but it's work ! true at 0 and 1 + CAM02[1][1]=(CAM02[1][1]-1.0)*D + 1.0; + CAM02[0][0]=(CAM02[0][0]-1.0)*D + 1.0; + CAM02[2][2]=(CAM02[2][2]-1.0)*D + 1.0; + CAM02[0][1]*=D; + CAM02[0][2]*=D; + CAM02[1][0]*=D; + CAM02[1][2]*=D; + CAM02[2][0]*=D; + CAM02[2][1]*=D; + //CAT02 matrix with D adaptation + CAM02BB00=CAM02[0][0];CAM02BB01=CAM02[0][1];CAM02BB02=CAM02[0][2]; + CAM02BB10=CAM02[1][0];CAM02BB11=CAM02[1][1];CAM02BB12=CAM02[1][2]; + CAM02BB20=CAM02[2][0];CAM02BB21=CAM02[2][1];CAM02BB22=CAM02[2][2]; + +} + +void ColorTemp::temp2mulxyz (double tem, double gree, 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) { + + 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 + bool CRI_type=false; + double xD, yD, x_D, y_D, interm; + double m1, m2; + double xp,yp; + + double x, y, z, xx, yy, zz; + 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 Xcam02pal[50],Ycam02pal[50],Zcam02pal[50]; + + double XchkLamp[50],YchkLamp[50],ZchkLamp[50]; + double Xcam02Lamp[50],Ycam02Lamp[50],Zcam02Lamp[50]; + double Xpal[50],Ypal[50],Zpal[50]; + double tempw; + 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]; + double Llamp[50],alamp[50],blamp[50]; + double Lbb[50],abb[50],bbb[50]; + double Lpal[50],apal[50],bpal[50]; + + int palet=-1; + 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);palet=0; /*tempalet=5300;*/ } + else if(method == "Cloudy" ) {spectrum_to_xyz_preset(Cloudy6200_spect, x, y, z);palet=1; /*tempalet=6200;*/ } + else if(method == "Shade" ) {spectrum_to_xyz_preset(Shade7600_spect, x, y, z);palet=2; /*tempalet=7600;*/ } + else if(method == "Tungsten" ) {spectrum_to_xyz_preset(A2856_spect, x, y, z);palet=3; /*tempalet=2856;*/ } + else if(method == "Fluo F1" ) {spectrum_to_xyz_preset(FluoF1_spect, x, y, z);palet=4; /*tempalet=6430;*/ } + else if(method == "Fluo F2" ) {spectrum_to_xyz_preset(FluoF2_spect, x, y, z);palet=5; /*tempalet=4230;*/ } + else if(method == "Fluo F3" ) {spectrum_to_xyz_preset(FluoF3_spect, x, y, z);palet=6; /*tempalet=3450;*/ } + else if(method == "Fluo F4" ) {spectrum_to_xyz_preset(FluoF4_spect, x, y, z);palet=7; /*tempalet=2940;*/ } + else if(method == "Fluo F5" ) {spectrum_to_xyz_preset(FluoF5_spect, x, y, z);palet=8; /*tempalet=6350;*/ } + else if(method == "Fluo F6" ) {spectrum_to_xyz_preset(FluoF6_spect, x, y, z);palet=9; /*tempalet=4150;*/ } + else if(method == "Fluo F7" ) {spectrum_to_xyz_preset(FluoF7_spect, x, y, z);palet=10; /*tempalet=6500;*/ } + else if(method == "Fluo F8" ) {spectrum_to_xyz_preset(FluoF8_spect, x, y, z);palet=11; /*tempalet=5020;*/ } + else if(method == "Fluo F9" ) {spectrum_to_xyz_preset(FluoF9_spect, x, y, z);palet=12; /*tempalet=4330;*/ } + else if(method == "Fluo F10" ) {spectrum_to_xyz_preset(FluoF10_spect, x, y, z);palet=13; /*tempalet=5300;*/ } + else if(method == "Fluo F11" ) {spectrum_to_xyz_preset(FluoF11_spect, x, y, z);palet=14; /*tempalet=4000;*/ } + else if(method == "Fluo F12" ) {spectrum_to_xyz_preset(FluoF12_spect, x, y, z);palet=15; /*tempalet=3000;*/ } + else if(method == "HMI Lamp" ) {spectrum_to_xyz_preset(HMI_spect, x, y, z);palet=16; /*tempalet=4760;*/ } + else if(method == "GTI Lamp" ) {spectrum_to_xyz_preset(GTI_spect, x, y, z);palet=17; /*tempalet=5000;*/ } + else if(method == "JudgeIII Lamp" ) {spectrum_to_xyz_preset(JudgeIII_spect, x, y, z);palet=18; /*tempalet=5100;*/ } + else if(method == "Solux Lamp 3500K" ) {spectrum_to_xyz_preset(Solux3500_spect, x, y, z);palet=19; /*tempalet=3480;*/ } + else if(method == "Solux Lamp 4100K" ) {spectrum_to_xyz_preset(Solux4100_spect, x, y, z);palet=20; /*tempalet=3930;*/ } + else if(method == "Solux Lamp 4700K" ) {spectrum_to_xyz_preset(Solux4700_spect, x, y, z);palet=21; /*tempalet=4700;*/ } + else if(method == "NG Solux Lamp 4700K" ) {spectrum_to_xyz_preset(NG_Solux4700_spect, x, y, z);palet=22; /*tempalet=4480;*/ } + else if(method == "LED LSI Lumelex 2040") {spectrum_to_xyz_preset(NG_LEDLSI2040_spect, x, y, z);palet=23; /*tempalet=2970;*/ } + else if(method == "LED CRS SP12 WWMR16" ) {spectrum_to_xyz_preset(NG_CRSSP12WWMR16_spect, x, y, z);palet=24; /*tempalet=3050;*/ } + else if(method == "Flash 5500K" ) {spectrum_to_xyz_preset(Flash5500_spect, x, y, z);palet=25; /*tempalet=5500;*/ } + else if(method == "Flash 6000K" ) {spectrum_to_xyz_preset(Flash6000_spect, x, y, z);palet=26; /*tempalet=6000;*/ } + else if(method == "Flash 6500K" ) {spectrum_to_xyz_preset(Flash6500_spect, x, y, z);palet=27; /*tempalet=6500;*/ } + else { + // otherwise we use the Temp+Green generic solution + if (temp <= 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(temp, x, y, z);palet=28; + } + else { + // from 4000K up to 25000K: using the D illuminant (daylight) which is standard + palet=29; + 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 !) + + 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; + spectrum_to_xyz_daylight(m1, m2, x, y, z); + xD=x;yD=y; + } + } + + xD=x; yD=y; + 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; + double correl_temp; + + + 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; + gmul = sRGB_xyz[1][0]*X + sRGB_xyz[1][1]*Y + sRGB_xyz[1][2]*Z; + 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; + //}; + 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; + rmul /= max; + gmul /= max; + bmul /= max; + + if(palette) // palette of color : 32 skin, 4 grey, 4 blue sky + //calculate L a b in function of color and illuminant + //J.Desmis january 2012 + { + double x_x,y_y,z_z; + // illuminants + const double* spect_illummax[] = { + Daylight5300_spect,Cloudy6200_spect,Shade7600_spect,A2856_spect,FluoF1_spect,FluoF2_spect,FluoF3_spect,FluoF4_spect,FluoF5_spect,FluoF6_spect,FluoF7_spect, + FluoF8_spect,FluoF9_spect,FluoF10_spect,FluoF11_spect,FluoF12_spect,HMI_spect,GTI_spect,JudgeIII_spect,Solux3500_spect,Solux4100_spect,Solux4700_spect,NG_Solux4700_spect,NG_CRSSP12WWMR16_spect,NG_CRSSP12WWMR16_spect, + Flash5500_spect,Flash6000_spect,Flash6500_spect + }; + // color + const double* spec_colorpalet[] = { + ColabSkin98_m2_10_spect, ColabSkin95_0_4_spect,ColabSkin91_4_14_spect, ColabSkin90_m1_20_spect, + ColorchechSGSkiK285_11_17_spect,ColabSkin87_8_8_spect,ColabSkin87_3_10_spect,ColabSkin89_8_21_spect, + ColabSkin70_7_32_spect,ColabSkin77_12_21_spect,ColabSkin75_8_4_spect,ColabSkin75_10_33_spect, + ColorchechSkiB166_18_18_spect,ColabSkin65_7_24_spect,ColorchechSGSkiF763_14_26_spect,ColabSkin65_33_11_spect, + ColabSkin57_19_6_spect,ColabSkin57_4_19_spect,ColabSkin57_10_28_spect,ColabSkin57_22_18_spect, + ColabSkin40_17_17_spect,ColabSkin40_7_19_spect,ColabSkin40_4_11_spect,ColabSkin40_17_6_spect, + ColorchechSkiA138_13_14_spect,ColabSkin33_6_15_spect,ColabSkin35_15_17_spect,ColabSkin33_15_5_spect, + ColabSkin26_18_18_spect,ColabSkin24_7_5_spect,ColabSkin24_5_6_spect,ColabSkin20_4_2_spect, + ColabSky42_0_m24_spect,ColorchechBluC150_m5_m22_spect,ColorchechWhiA496_spect, ColorchechSGBlaN3_6_spect, + JDC468_GraK14_44_spect,ColorchechGraC4_67_spect,ColabSky60_0_m31_spect,ColorchechDCBluN881_m7_m14_spect + //ColabSkin33_10_15_spect, + //ColabSkin81_2_14_spect, + }; + + int N_col = sizeof(spec_colorpalet)/sizeof(spec_colorpalet[0]);//number of color + + if(palet < 28) { + for(int i=0;i=28) { + if(temp epsilon + if(xr[i]> epsilon) fx[i]=pow(xr[i],0.333);else fx[i]=(903.3*xr[i]+16.0)/116.0; + if(yr[i]> epsilon) fy[i]=pow(yr[i],0.333);else fy[i]=(903.3*yr[i]+16.0)/116.0; + if(zr[i]> epsilon) fz[i]=pow(zr[i],0.333);else fz[i]=(903.3*zr[i]+16.0)/116.0; + } + //Lab values in function of color and illuminant + //these values can be compared to preview values when using white-balance (skin / sky / BW) + for(int i=0;iCRI_color != 0) printf("Lpal=%2.2f apal=%2.2f bpal=%2.2f\n", Lpal[0],apal[0],bpal[0]);//sample + //} + + } //end palette + + // 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 + // CRI_color-1 = dispaly Lab values of color CRI_color -1 + { + int illum; + int numero_color=settings->CRI_color - 1; + + //spectral data illuminant (actually 21): only those necessary (lamp, fluorescent, LED) others CRI=100 (not Flash...) + const double* spect_illum[] = { + Daylight5300_spect,Cloudy6200_spect,Shade7600_spect,A2856_spect,FluoF1_spect,FluoF2_spect,FluoF3_spect, + FluoF4_spect,FluoF5_spect,FluoF6_spect,FluoF7_spect,FluoF8_spect,FluoF9_spect,FluoF10_spect,FluoF11_spect, + FluoF12_spect,HMI_spect,GTI_spect,JudgeIII_spect,Solux3500_spect,Solux4100_spect,Solux4700_spect, + NG_Solux4700_spect,NG_CRSSP12WWMR16_spect,NG_CRSSP12WWMR16_spect + }; + const double* spec_color[] = { + ColorchechredC3_spect, ColorchechOraA2_spect,ColorchechYelD3_spect,ColorchechGreE2_spect,ColorchechGreB3_spect, + ColorchechCyaF3_spect, ColorchechPurD2_spect,ColorchechMagE3_spect,ColorchechSkiA138_13_14_spect,ColorchechGraC4_67_spect, + ColorchechSkiB166_18_18_spect,ColorchechBluC150_m5_m22_spect,ColorchechDCBluN881_m7_m14_spect,ColorchechSGSkiF763_14_26_spect, + ColorchechSGSkiK285_11_17_spect,ColorchechWhiA496_spect, ColorchechGreD1_spect, ColorchechSGBlaN3_6_spect, + JDC468_GraK14_44_spect,JDC468_BluH10_spect + }; + + int N_c = sizeof(spec_color)/sizeof(spec_color[0]);//number of color + + if (method == "Fluo F1") {CRI_type=true; tempw=6430; illum=1;} + else if (method == "Fluo F2") {CRI_type=true; tempw=4230; illum=2;} + else if (method == "Fluo F3") {CRI_type=true; tempw=3450; illum=3;} + else if (method == "Fluo F4") {CRI_type=true; tempw=2940; illum=4;} + else if (method == "Fluo F5") {CRI_type=true; tempw=6350; illum=5;} + else if (method == "Fluo F6") {CRI_type=true; tempw=4150; illum=6;} + else if (method == "Fluo F7") {CRI_type=true; tempw=6500; illum=7;} + else if (method == "Fluo F8") {CRI_type=true; tempw=5020; illum=8;} + else if (method == "Fluo F9") {CRI_type=true; tempw=4330; illum=9;} + else if (method == "Fluo F10") {CRI_type=true; tempw=5300; illum=10;} + else if (method == "Fluo F11") {CRI_type=true; tempw=4000; illum=11;} + else if (method == "Fluo F12") {CRI_type=true; tempw=3000; illum=12;} + else if (method == "HMI Lamp") {CRI_type=true; tempw=4760; illum=13;} + else if (method == "GTI Lamp") {CRI_type=true; tempw=5000; illum=14;} + else if (method == "JudgeIII Lamp") {CRI_type=true; tempw=5100; illum=15;} + else if (method == "Solux Lamp 3500K") {CRI_type=true; tempw=3480; illum=16;} + else if (method == "Solux Lamp 4100K") {CRI_type=true; tempw=3930; illum=17;} + else if (method == "Solux Lamp 4700K" ) {CRI_type=true; tempw=4700; illum=18;} + else if (method == "NG Solux Lamp 4700K") {CRI_type=true; tempw=4480; illum=19;} + else if (method == "LED LSI Lumelex 2040") {CRI_type=true; tempw=2970; illum=20;} + else if (method == "LED CRS SP12 WWMR16") {CRI_type=true; tempw=3050; illum=21;} + else {CRI_type=false;} + + if (CRI_type) { + float DeltaE[50], DeltaEs[8]; + float quadCRI=0.0f,quadCRIs=0.0f; + float CRI_RT=0.0, CRI[50]; + float CRI_RTs=0.0, CRIs[8]; + + for(int i=0;i x_D y_D + //S(lamda)=So(lambda)+m1*s1(lambda)+m2*s2(lambda) + interm2=(0.0241+0.2562*x_DD-0.734*y_DD); + m11=(-1.3515-1.7703*x_DD+5.9114*y_DD)/interm2; + m22=(0.03-31.4424*x_DD+30.0717*y_DD)/interm2; + + for(int i=0;iverbose) { + printf("Correlated temperature (lamp)=%i\n", (int) correl_temp); //use only for lamp...otherwise It give an information!! + } + + double Xwb_bb = x/y;//white balance for blackbody + double Ywb_bb = 1.0; + double Zwb_bb = (1.0-x-y)/y; + + //calculate Matrix CAM02 : better than Von Kries and Bradford==> for Lamp + double adap=1.0; + cieCAT02(Xwb, Ywb, Zwb, CAM02BB00,CAM02BB01,CAM02BB02,CAM02BB10,CAM02BB11,CAM02BB12,CAM02BB20,CAM02BB21,CAM02BB22,adap); + //here new value of X,Y,Z for lamp with chromatic CAM02 adaptation + for(int i=0;i epsilon + if(xr[i]> epsilon) fx[i]=pow(xr[i],0.333);else fx[i]=(903.3*xr[i]+16.0)/116.0; + if(yr[i]> epsilon) fy[i]=pow(yr[i],0.333);else fy[i]=(903.3*yr[i]+16.0)/116.0; + if(zr[i]> epsilon) fz[i]=pow(zr[i],0.333);else fz[i]=(903.3*zr[i]+16.0)/116.0; + } + + for(int i=0;i epsilon) fx[i]=pow(xr[i],0.333);else fx[i]=(903.3*xr[i]+16.0)/116.0; + if(yr[i]> epsilon) fy[i]=pow(yr[i],0.333);else fy[i]=(903.3*yr[i]+16.0)/116.0; + if(zr[i]> epsilon) fz[i]=pow(zr[i],0.333);else fz[i]=(903.3*zr[i]+16.0)/116.0; + } + + for(int i=0;iCRI_color != 0) { + printf("Color Number %i\n",numero_color); + printf("L_refer=%2.2f a=%2.2f b=%2.2f\n", Lbb[numero_color],abb[numero_color],bbb[numero_color]); + printf("L_lamp=%2.2f al=%2.2f bl=%2.2f\n", Llamp[numero_color],alamp[numero_color],blamp[numero_color]); + } + + //then calculate DeltaE CIE 1976 + for(int i=0;i<8;i++) + DeltaEs[i]=sqrt((Lbb[i]-Llamp[i])*(Lbb[i]-Llamp[i])+(abb[i]-alamp[i])*(abb[i]-alamp[i])+(bbb[i]-blamp[i])*(bbb[i]-blamp[i])); + + for(int i=0;i<8;i++) + CRIs[i]=100-3.0*DeltaEs[i]; //3.0 coef to adapt ==> same results than CRI "official" + + for(int i=0;i<8;i++) + CRI_RTs+=CRIs[i]; + CRI_RTs/=8; + + for(int i=0;i<8;i++) + quadCRIs+=(CRIs[i]-CRI_RTs)*(CRIs[i]-CRI_RTs); + quadCRIs/=8; + + for(int i=0;i same results than CRI "official" + + for(int i=0;iCRI_color != 0) { + printf("CRI_standard=%i CRI:1->8=%i %i %i %i %i %i %i %i Sigma=%2.1f\n",(int) CRI_RTs, (int) CRIs[0], (int) CRIs[1],(int) CRIs[2],(int) CRIs[3],(int) CRIs[4],(int) CRIs[5],(int) CRIs[6],(int) CRIs[7],sqrt(quadCRIs)); + printf("CRI_RT_exten=%i CRI:9->20=%i %i %i %i %i %i %i %i %i %i %i %i Sigma=%2.1f\n",(int) CRI_RT,(int) CRI[8],(int) CRI[9], (int) CRI[10],(int) CRI[11],(int) CRI[12],(int) CRI[13],(int) CRI[14],(int) CRI[15],(int) CRI[16],(int) CRI[17],(int) CRI[18],(int) CRI[19],sqrt(quadCRI)); + } + } + } +} + +/* + Calculate Planck's radiation +*/ + //calculate spectral data for blackbody at temp! +double ColorTemp::blackbody_spect(double wavelength, double temperature) +{ + double wlm = wavelength * 1e-9; /* Wavelength in meters */ + return (3.7417715247e-16 / pow(wlm, 5)) / //3.7417..= c1 = 2*Pi*h*c2 where h=Planck constant, c=velocity of light + (xexp(1.438786e-2 / (wlm * temperature)) - 1.0); //1.4387..= c2 = h*c/k where k=Boltzmann constant +} + +/* +The next 3 methods are inspired from: + + a) Colour Rendering of Spectra by John Walker + http://www.fourmilab.ch/ + This program is in the public domain. + + b) Bruce Lindbloom + Adapted to Rawtherapee by J.Desmis + +this values are often called xBar yBar zBar and are characteristics of a color / illuminant + +values cie_colour_match[][3] = Observer 2� x2, y2, z2 +E.g. for 380nm: x2=0.001368 y2=0.000039 z2=0.006451 round in J.Walker to 0.0014 0.0000 0.0065 above +I have increase precision used by J.Walker and pass to 350nm to 830nm +*/ + +void ColorTemp::spectrum_to_xyz_daylight(double _m1, double _m2, double &x, double &y, double &z) +{ + int i; + double lambda, X = 0, Y = 0, Z = 0, XYZ; + + for (i=0, lambda=350.; lambda<830.1; i++, lambda+=5.) { + double Me = daylight_spect(lambda, _m1, _m2); + X += Me * cie_colour_match_jd[i][0]; + Y += Me * cie_colour_match_jd[i][1]; + Z += Me * cie_colour_match_jd[i][2]; + } + XYZ = (X + Y + Z); + x = X / XYZ; + y = Y / XYZ; + z = Z / XYZ; +} + +void ColorTemp::spectrum_to_xyz_blackbody(double _temp, double &x, double &y, double &z) +{ + int i; + double lambda, X = 0, Y = 0, Z = 0, XYZ; + + for (i=0, lambda=350.; lambda<830.1; i++, lambda+=5.) { + double Me = blackbody_spect(lambda, _temp); + X += Me * cie_colour_match_jd[i][0]; + Y += Me * cie_colour_match_jd[i][1]; + Z += Me * cie_colour_match_jd[i][2]; + } + XYZ = (X + Y + Z); + x = X / XYZ; + y = Y / XYZ; + z = Z / XYZ; +} + +void ColorTemp::spectrum_to_xyz_preset(const double* spec_intens, double &x, double &y, double &z) +{ + int i; + double lambda, X = 0, Y = 0, Z = 0, XYZ; + + /* + Inspired from: + + a) Colour Rendering of Spectra by John Walker + http://www.fourmilab.ch/ + This program is in the public domain. + + b) Bruce Lindbloom + Adapted to RawTherapee by J.Desmis + + this values are often called xBar yBar zBar and are characteristics of a color / illuminant + + values cie_colour_match[][3] = Observer 2� x2, y2, z2 + E.g. for 380nm: x2=0.001368 y2=0.000039 z2=0.006451 round in J.Walker to 0.0014 0.0000 0.0065 above + I have increased the precision used by J.Walker and pass from 350nm to 830nm + */ + for (i=0, lambda=350.; lambda<830.1; i++, lambda+=5.) { + double Me = get_spectral_color(lambda, spec_intens); + X += Me * cie_colour_match_jd[i][0]; + Y += Me * cie_colour_match_jd[i][1]; + Z += Me * cie_colour_match_jd[i][2]; + } + XYZ = (X + Y + Z); + x = X / XYZ; + y = Y / XYZ; + z = Z / XYZ; +} + +//calculate XYZ from spectrum data (color) and illuminant : J.Desmis December 2011 +void ColorTemp::spectrum_to_color_xyz_preset(const double* spec_color, const double* spec_intens, double &xx, double &yy, double &zz) +{ + int i; + double lambda, X = 0, Y = 0, Z = 0, Yo=0; + for (i = 0, lambda = 350; lambda < 830.1; i++, lambda += 5) { + + double Me; + double Mc; + + Me = get_spectral_color(lambda, spec_color); + Mc = get_spectral_color(lambda, spec_intens); + X += Mc * cie_colour_match_jd[i][0] * Me; + Y += Mc * cie_colour_match_jd[i][1] * Me; + Z += Mc * cie_colour_match_jd[i][2] * Me; + } + for (i = 0, lambda = 350; lambda < 830.1; i++, lambda += 5) { + + double Ms; + + Ms = get_spectral_color(lambda, spec_intens); + Yo += cie_colour_match_jd[i][1] * Ms; + } + + xx = X / Yo; + yy = Y / Yo; + zz = Z / Yo; +} + +//calculate XYZ from spectrum data (color) and illuminant : J.Desmis december 2011 +void ColorTemp::spectrum_to_color_xyz_daylight(const double* spec_color, double _m1, double _m2, double &xx, double &yy, double &zz) +{ + int i; + double lambda, X = 0, Y = 0, Z = 0, Yo=0; + for (i = 0, lambda = 350; lambda < 830.1; i++, lambda += 5) { + + double Me; + double Mc; + + Me = get_spectral_color(lambda, spec_color); + Mc = daylight_spect(lambda,_m1, _m2); + X += Mc * cie_colour_match_jd[i][0] * Me; + Y += Mc * cie_colour_match_jd[i][1] * Me; + Z += Mc * cie_colour_match_jd[i][2] * Me; + } + for (i = 0, lambda = 350; lambda < 830.1; i++, lambda += 5) { + + double Ms; + + Ms = daylight_spect(lambda,_m1, _m2); + Yo += cie_colour_match_jd[i][1] * Ms; + } + + xx = X / Yo; + yy = Y / Yo; + zz = Z / Yo; +} + +//calculate XYZ from spectrum data (color) and illuminant : J.Desmis december 2011 +void ColorTemp::spectrum_to_color_xyz_blackbody(const double* spec_color, double _temp, double &xx, double &yy, double &zz) +{ + int i; + double lambda, X = 0, Y = 0, Z = 0, Yo=0; + for (i = 0, lambda = 350; lambda < 830.1; i++, lambda += 5) { + + double Me; + double Mc; + + Me = get_spectral_color(lambda, spec_color); + Mc = blackbody_spect(lambda, _temp); + X += Mc * cie_colour_match_jd[i][0] * Me; + Y += Mc * cie_colour_match_jd[i][1] * Me; + Z += Mc * cie_colour_match_jd[i][2] * Me; + } + for (i = 0, lambda = 350; lambda < 830.1; i++, lambda += 5) { + + double Ms; + + Ms = blackbody_spect(lambda, _temp); + Yo += cie_colour_match_jd[i][1] * Ms; + } + + xx = X / Yo; + yy = Y / Yo; + zz = Z / Yo; +} + +double ColorTemp::daylight_spect(double wavelength, double m1, double m2) +{ + //Values for Daylight illuminant: s0 s1 s2 + //s0 + static const double s0[97]={61.80,61.65,61.50,65.15,68.80,66.10,63.40,64.60,65.80,80.30,94.80,99.80,104.80,105.35,105.90,101.35,96.80,105.35,113.90,119.75,125.60,125.55,125.50,123.40,121.30,121.30,121.30,117.40,113.50,113.30, + 113.10,111.95,110.80,108.65,106.50,107.65,108.80,107.05,105.30,104.85,104.40,102.20,100.00,98.00,96.00,95.55,95.10,92.10,89.10,89.80,90.50,90.40,90.30,89.35,88.40,86.20,84.00,84.55,85.10, + 83.50,81.90,82.25,82.60,83.75,84.90,83.10,81.30,76.60,71.90,73.10,74.30,75.35,76.40,69.85,63.30,67.50,71.70,74.35,77.00,71.10,65.20,56.45,47.70,58.15,68.60,66.80,65.00,65.50,66.00,63.50,61.00,57.15, + 53.30,56.10,58.90,60.40,61.90}; + //s1 + static const double s1[97]={41.60,39.80,38.00,40.70,43.40,40.95,38.50,36.75,35.00,39.20,43.40,44.85,46.30,45.10,43.90,40.50,37.10,36.90,36.70,36.30,35.90,34.25,32.60,30.25,27.90,26.10,24.30,22.20,20.10,18.15,16.20,14.70, + 13.20,10.90,8.60,7.35,6.10,5.15,4.20,3.05,1.90,0.95,0.00,-0.80,-1.60,-2.55,-3.50,-3.50,-3.50,-4.65,-5.80,-6.50,-7.20,-7.90,-8.60,-9.05,-9.50,-10.20,-10.90,-10.80,-10.70,-11.35,-12.00,-13.00,-14.00, + -13.80,-13.60,-12.80,-12.00,-12.65,-13.30,-13.10,-12.90,-11.75,-10.60,-11.10,-11.60,-11.90,-12.20,-11.20,-10.20,-9.00,-7.80,-9.50,-11.20,-10.80,-10.50,-10.60,-10.15,-9.70,-9.00,-8.30, + -8.80,-9.30,-9.55,-9.80}; + //s2 + static const double s2[97]={6.70,6.00,5.30,5.70,6.10,4.55,3.00,2.10,1.20,0.05,-1.10,-0.80,-0.50,-0.60,-0.70,-0.95,-1.20,-1.90,-2.60,-2.75,-2.90,-2.85,-2.80,-2.70,-2.60,-2.60,-2.60,-2.20,-1.80,-1.65,-1.50,-1.40,-1.30, + -1.25,-1.20,-1.10,-1.00,-0.75,-0.50,-0.40,-0.30,-0.15,0.00,0.10,0.20,0.35,0.50,1.30,2.10,2.65,3.65,4.10,4.40,4.70,4.90,5.10,5.90,6.70,7.00,7.30,7.95,8.60,9.20,9.80,10.00,10.20,9.25,8.30,8.95, + 9.60,9.05,8.50,7.75,7.00,7.30,7.60,7.80,8.00,7.35,6.70,5.95,5.20,6.30,7.40,7.10,6.80,6.90,7.00,6.70,6.40,5.95,5.50,5.80,6.10,6.30,6.50}; + + int wlm = (int) ((wavelength -350.)/5.); + return (s0[wlm]+m1*s1[wlm]+m2*s2[wlm]); +} + + +} + diff --git a/rtengine/colortemp.h b/rtengine/colortemp.h new file mode 100644 index 000000000..7b1686ed8 --- /dev/null +++ b/rtengine/colortemp.h @@ -0,0 +1,178 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _COLORTEMP_ +#define _COLORTEMP_ + +#include +#include + +#define pow_F(a,b) (xexpf(b*xlogf(a))) + +namespace rtengine { + +#define MINTEMP 1500 +#define MAXTEMP 60000 +#define MINGREEN 0.02 +#define MAXGREEN 5.0 +#define MINEQUAL 0.8 +#define MAXEQUAL 1.5 + +#define INITIALBLACKBODY 4000 + + +class ColorTemp { + + private: + double temp; + double green; + double equal; + std::string method; + static void clip (double &temp, double &green); + static void clip (double &temp, double &green, double &equal); + + public: + + ColorTemp () : temp(-1.), green(-1.), equal (1.), method("Custom") {} + ColorTemp (double e) : temp(-1.), green(-1.), equal (e), method("Custom") {} + ColorTemp (double t, double g, double e, Glib::ustring m); + ColorTemp (double mulr, double mulg, double mulb, double e); + + void update (const double rmul, const double gmul, const double bmul, const double equal) { this->equal = equal; mul2temp (rmul, gmul, bmul, this->equal, temp, green); } + void useDefaults (const double equal) { temp = 6504; green = 1.0; this->equal = equal; } // Values copied from procparams.cc + + inline std::string getMethod() { return method; } + inline double getTemp () { return temp; } + inline double getGreen () { return green; } + inline double getEqual () { return equal; } + + void getMultipliers (double &mulr, double &mulg, double &mulb) { temp2mul (temp, green, equal, mulr, mulg, mulb); } + + void mul2temp (const double rmul, const double gmul, const double bmul, const double equal, double& temp, double& green); + void temp2mul (double temp, double green, double equal, double& rmul, double& gmul, double& bmul); + static void temp2mulxyz (double tem, double gree, std::string method, double &Xxyz, double &Zxyz); + + int XYZtoCorColorTemp(double x0,double y0 ,double z0, double &temp); + 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); + //static void ciecam_02 (LabImage* lab, const ProcParams* params); + + bool operator== (const ColorTemp& other) { return fabs(temp-other.temp)<1e-10 && fabs(green-other.green)<1e-10; } + bool operator!= (const ColorTemp& other) { return !(*this==other); } + + static double blackbody_spect (double wavelength, double temperature); + static double daylight_spect (double wavelength, double m1, double m2); + static const double Cloudy6200_spect[97]; + static const double Daylight5300_spect[97]; + static const double Shade7600_spect[97]; + static const double A2856_spect[97]; + static const double FluoF1_spect[97]; + static const double FluoF2_spect[97]; + static const double FluoF3_spect[97]; + static const double FluoF4_spect[97]; + static const double FluoF5_spect[97]; + static const double FluoF6_spect[97]; + static const double FluoF7_spect[97]; + static const double FluoF8_spect[97]; + static const double FluoF9_spect[97]; + static const double FluoF10_spect[97]; + static const double FluoF11_spect[97]; + static const double FluoF12_spect[97]; + static const double HMI_spect[97]; + static const double GTI_spect[97]; + static const double JudgeIII_spect[97]; + static const double Solux3500_spect[97]; + static const double Solux4100_spect[97]; + static const double Solux4700_spect[97]; + static const double NG_Solux4700_spect[97]; + static const double NG_LEDLSI2040_spect[97]; + static const double NG_CRSSP12WWMR16_spect[97]; + static const double Flash5500_spect[97]; + static const double Flash6000_spect[97]; + static const double Flash6500_spect[97]; + + //spectral data 8 color Colorchecker24 + static double get_spectral_color (double wavelength, const double* array) { + int wlm = (int) ((wavelength -350.)/5.); + return (array[wlm]); + } + + static const double ColorchechredC3_spect[97]; + static const double ColorchechOraA2_spect[97]; + static const double ColorchechYelD3_spect[97]; + static const double ColorchechGreE2_spect[97]; + static const double ColorchechGreB3_spect[97]; + static const double ColorchechCyaF3_spect[97]; + static const double ColorchechPurD2_spect[97]; + static const double ColorchechMagE3_spect[97]; + static const double ColorchechSkiA138_13_14_spect[97]; + static const double ColorchechGraC4_67_spect[97]; + static const double ColorchechSkiB166_18_18_spect[97]; + static const double ColorchechBluC150_m5_m22_spect[97]; + static const double ColorchechDCBluN881_m7_m14_spect[97];//ColorChecker DC N8 + static const double ColorchechSGSkiF763_14_26_spect[97];//ColorChecker SG F7 + static const double ColorchechSGSkiK285_11_17_spect[97];//ColorChecker SG K2 + static const double ColorchechWhiA496_spect[97]; + static const double ColorchechGreD1_spect[97]; + static const double ColorchechSGBlaN3_6_spect[97];//ColorChecker SG N3 + static const double JDC468_GraK14_44_spect[97];//468 K14 + static const double JDC468_BluH10_spect[97];//468 H10 + static const double ColabSkin35_15_17_spect[97];//Skin L 35 + static const double ColabSkin57_22_18_spect[97];//Skin L 57 + static const double ColabSkin40_17_17_spect[97];//Skin L 40 + static const double ColabSkin91_4_14_spect[97];//Skin L 91 + static const double ColabSkin87_8_8_spect[97];//Skin L 87 + static const double ColabSkin89_8_21_spect[97];//Skin L 89 + static const double ColabSkin75_8_4_spect[97];//Skin L 75 + static const double ColabSkin75_10_33_spect[97];//Skin L 75 + static const double ColabSkin65_33_11_spect[97];//Skin L 65 + static const double ColabSkin65_7_24_spect[97];//Skin L 65 + static const double ColabSkin57_19_6_spect[97];//Skin L 57 + static const double ColabSkin57_4_19_spect[97];//Skin L 57 + static const double ColabSkin57_10_28_spect[97];//Skin L 57 + static const double ColabSkin40_7_19_spect[97];//Skin L 57 + static const double ColabSkin40_17_6_spect[97];//Skin L 40 + static const double ColabSkin40_4_11_spect[97];//Skin L 40 + static const double ColabSkin33_6_15_spect[97];//Skin L 33 + static const double ColabSkin33_15_5_spect[97];//Skin L 33 + static const double ColabSkin33_10_15_spect[97];//Skin L 33 + static const double ColabSkin24_5_6_spect[97];//Skin L 24 + static const double ColabSkin26_18_18_spect[97];//Skin L 26 + static const double ColabSkin24_7_5_spect[97];//Skin L 24 + static const double ColabSkin20_4_2_spect[97];//Skin L 20 + static const double ColabSkin98_m2_10_spect[97];//Skin L 98 + static const double ColabSkin90_m1_20_spect[97];//Skin L 90 + static const double ColabSkin95_0_4_spect[97];//Skin L 95 + static const double ColabSkin81_2_14_spect[97];//Skin L 81 + static const double ColabSkin87_3_10_spect[97];//Skin L 87 + static const double ColabSkin77_12_21_spect[97];//Skin L 77 + static const double ColabSkin70_7_32_spect[97];//Skin L 77 + static const double ColabSky60_0_m31_spect[97];//Sky L=60 + static const double ColabSky42_0_m24_spect[97];//Sky L=42 + + static void spectrum_to_xyz_daylight (double _m1, double _m2, double &x, double &y, double &z); + static void spectrum_to_xyz_blackbody (double _temp, double &x, double &y, double &z); + static void spectrum_to_xyz_preset (const double* spec_intens, double &x, double &y, double &z); + + static void spectrum_to_color_xyz_daylight (const double* spec_color, double _m1, double _m2, double &xx, double &yy, double &zz); + static void spectrum_to_color_xyz_blackbody (const double* spec_color, double _temp, double &xx, double &yy, double &zz); + static void spectrum_to_color_xyz_preset (const double* spec_color, const double* spec_intens, double &xx, double &yy, double &zz); + +}; +} +#endif diff --git a/rtengine/coord2d.h b/rtengine/coord2d.h new file mode 100644 index 000000000..fb9fd1616 --- /dev/null +++ b/rtengine/coord2d.h @@ -0,0 +1,33 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef __COORD2D__ +#define __COORD2D__ + +namespace rtengine { + +class Coord2D { + + public: + double x, y; + Coord2D (double x_, double y_) : x(x_), y(y_) {} + Coord2D () {} + void set (double x_, double y_) { x = x_; y = y_; } +}; +} +#endif diff --git a/rtengine/cplx_wavelet_dec.cc b/rtengine/cplx_wavelet_dec.cc new file mode 100644 index 000000000..4a35cd371 --- /dev/null +++ b/rtengine/cplx_wavelet_dec.cc @@ -0,0 +1,38 @@ +/* + * This file is part of RawTherapee. + * + * 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 . + * + * 2010 Ilya Popov + * 2012 Emil Martinec + */ + +#include "cplx_wavelet_dec.h" + +namespace rtengine { + + wavelet_decomposition::~wavelet_decomposition() + { + for(int i = 0; i <= lvltot; i++) { + if(wavelet_decomp[i] != NULL) + delete wavelet_decomp[i]; + } + delete[] wavfilt_anal; + delete[] wavfilt_synth; + if(coeff0) + delete [] coeff0; + } + +}; + diff --git a/rtengine/cplx_wavelet_dec.h b/rtengine/cplx_wavelet_dec.h new file mode 100644 index 000000000..b178adc2a --- /dev/null +++ b/rtengine/cplx_wavelet_dec.h @@ -0,0 +1,245 @@ +/* + * This file is part of RawTherapee. + * + * 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 . + * + * 2010 Ilya Popov + * 2012 Emil Martinec + */ + +#ifndef CPLX_WAVELET_DEC_H_INCLUDED +#define CPLX_WAVELET_DEC_H_INCLUDED + +#include +#include + +#include "cplx_wavelet_level.h" +#include "cplx_wavelet_filter_coeffs.h" + +namespace rtengine { + + class wavelet_decomposition + { + public: + + typedef float internal_type; + float *coeff0; + bool memoryAllocationFailed; + + private: + + static const int maxlevels = 10;//should be greater than any conceivable order of decimation + + int lvltot, subsamp; + int numThreads; + int m_w, m_h;//dimensions + + int wavfilt_len, wavfilt_offset; + float *wavfilt_anal; + float *wavfilt_synth; + + + wavelet_level * wavelet_decomp[maxlevels]; + + public: + + template + wavelet_decomposition(E * src, int width, int height, int maxlvl, int subsampling, int skipcrop = 1, int numThreads = 1, int Daub4Len = 6); + + ~wavelet_decomposition(); + + internal_type ** level_coeffs(int level) const + { + return wavelet_decomp[level]->subbands(); + } + + int level_W(int level) const + { + return wavelet_decomp[level]->width(); + } + + int level_H(int level) const + { + return wavelet_decomp[level]->height(); + } + + int level_stride(int level) const + { + return wavelet_decomp[level]->stride(); + } + + int maxlevel() const + { + return lvltot+1; + } + + int subsample() const + { + return subsamp; + } + template + void reconstruct(E * dst, const float blend = 1.f); + }; + + template + wavelet_decomposition::wavelet_decomposition(E * src, int width, int height, int maxlvl, int subsampling, int skipcrop, int numThreads, int Daub4Len) + : coeff0(NULL), memoryAllocationFailed(false), lvltot(0), subsamp(subsampling), numThreads(numThreads), m_w(width), m_h(height) + { + + //initialize wavelet filters + wavfilt_len = Daub4Len; + wavfilt_offset = Daub4_offset; + wavfilt_anal = new float[2*wavfilt_len]; + wavfilt_synth = new float[2*wavfilt_len]; + + if(wavfilt_len==6) { + for (int n=0; n<2; n++) { + for (int i=0; i(src, buffer[bufferindex^1], lvltot/*level*/, subsamp, m_w, m_h, \ + wavfilt_anal, wavfilt_anal, wavfilt_len, wavfilt_offset, skipcrop, numThreads); + if(wavelet_decomp[lvltot]->memoryAllocationFailed) + memoryAllocationFailed = true; + while(lvltot < maxlvl-1) { + lvltot++; + bufferindex ^= 1; + wavelet_decomp[lvltot] = new wavelet_level(buffer[bufferindex], buffer[bufferindex^1]/*lopass*/, lvltot/*level*/, subsamp, \ + wavelet_decomp[lvltot-1]->width(), wavelet_decomp[lvltot-1]->height(), \ + wavfilt_anal, wavfilt_anal, wavfilt_len, wavfilt_offset, skipcrop, numThreads); + if(wavelet_decomp[lvltot]->memoryAllocationFailed) + memoryAllocationFailed = true; + } + coeff0 = buffer[bufferindex^1]; + delete[] buffer[bufferindex]; + } + + template + void wavelet_decomposition::reconstruct(E * dst, const float blend) { + + if(memoryAllocationFailed) + return; + // data structure is wavcoeffs[scale][channel={lo,hi1,hi2,hi3}][pixel_array] + + if(lvltot >= 1) { + int width = wavelet_decomp[1]->m_w; + int height = wavelet_decomp[1]->m_h; + + E *tmpHi = new (std::nothrow) E[width*height]; + if(tmpHi == NULL) { + memoryAllocationFailed = true; + return; + } + + for (int lvl=lvltot; lvl>0; lvl--) { + E *tmpLo = wavelet_decomp[lvl]->wavcoeffs[2]; // we can use this as buffer + wavelet_decomp[lvl]->reconstruct_level(tmpLo, tmpHi, coeff0, coeff0, wavfilt_synth, wavfilt_synth, wavfilt_len, wavfilt_offset); + delete wavelet_decomp[lvl]; + wavelet_decomp[lvl] = NULL; + } + delete[] tmpHi; + } + + int width = wavelet_decomp[0]->m_w; + int height = wavelet_decomp[0]->m_h2; + E *tmpLo; + if(wavelet_decomp[0]->bigBlockOfMemoryUsed()) // bigBlockOfMemoryUsed means that wavcoeffs[2] points to a block of memory big enough to hold the data + tmpLo = wavelet_decomp[0]->wavcoeffs[2]; + else { // allocate new block of memory + tmpLo = new (std::nothrow) E[width*height]; + if(tmpLo == NULL) { + memoryAllocationFailed = true; + return; + } + } + E *tmpHi = new (std::nothrow) E[width*height]; + if(tmpHi == NULL) { + memoryAllocationFailed = true; + if(!wavelet_decomp[0]->bigBlockOfMemoryUsed()) + delete[] tmpLo; + return; + } + + + wavelet_decomp[0]->reconstruct_level(tmpLo, tmpHi, coeff0, dst, wavfilt_synth, wavfilt_synth, wavfilt_len, wavfilt_offset, blend); + if(!wavelet_decomp[0]->bigBlockOfMemoryUsed()) + delete[] tmpLo; + delete[] tmpHi; + delete wavelet_decomp[0]; + wavelet_decomp[0] = NULL; + delete[] coeff0; + coeff0 = NULL; + } + +}; + +#endif diff --git a/rtengine/cplx_wavelet_filter_coeffs.h b/rtengine/cplx_wavelet_filter_coeffs.h new file mode 100644 index 000000000..39fce5a03 --- /dev/null +++ b/rtengine/cplx_wavelet_filter_coeffs.h @@ -0,0 +1,48 @@ +/* + * This file is part of RawTherapee. + * + * 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 . + * + * 2012 Emil Martinec + * 2014 Jacques Desmis + */ + + +namespace rtengine { + +const int Daub4_offset=2; + +const float Daub4_anal0[2][4] ALIGNED16 = {//analysis filter 2 Hall + {0.f, 0.f, 0.5f, 0.5f}, + {-0.5f, 0.5f, 0.f, 0.f}}; + +const float Daub4_anal[2][6] ALIGNED16 = {//Daub4 + {0.f, 0.f, 0.34150635f, 0.59150635f, 0.15849365f, -0.091506351f}, + {-0.091506351f, -0.15849365f, 0.59150635f, -0.34150635f, 0.f, 0.f}}; + +const float Daub4_anal8[2][8] ALIGNED16 = {//Daub6 + {0.f, 0.f, 0.235233605f, 0.57055846f, 0.3251825f, -0.09546721f, -0.060416105f, 0.02490875f}, + {-0.02490875f, -0.060416105f, 0.09546721f, 0.3251825f, -0.57055846f , 0.235233605f, 0.f, 0.f}}; + +const float Daub4_anal12[2][12] ALIGNED16 = {//Daub10 + {0.f, 0.f, 0.11320949f, 0.42697177f, 0.51216347f, 0.09788348f, -0.171328355f, -0.022800565f, 0.054851325f, -0.0044134f, -0.008895935f, 0.002358714f}, + {-0.002358714f, -0.008895935f, 0.0044134f, 0.054851325f, 0.022800565f , -0.171328355f, -0.09788348f, 0.51216347f, -0.42697177f, 0.11320949f, 0.f, 0.f}}; + +const float Daub4_anal16[2][16] ALIGNED16 = {//Daub 14 + {0.f, 0.f, 0.055049715f, 0.28039564f, 0.515574245f, 0.33218624f, -0.10175691f, -0.158417505f, 0.05042335f, 0.057001725f, -0.026891225f, -0.01171997f, 0.008874895f, 0.0003037575f, -0.0012739524f, 0.0002501134f}, + {-0.0002501134f, -0.0012739524f, -0.0003037575f, 0.008874895f, 0.01171997f , -0.026891225f, -0.057001725f, 0.05042335f, 0.158417505f, -0.10175691f, -0.33218624f, 0.515574245f, -0.28039564f, 0.055049715f, 0.f, 0.f}}; + +// if necessary ?? we can add D20 !! +}; + diff --git a/rtengine/cplx_wavelet_level.h b/rtengine/cplx_wavelet_level.h new file mode 100644 index 000000000..1c1efde27 --- /dev/null +++ b/rtengine/cplx_wavelet_level.h @@ -0,0 +1,654 @@ +/* + * This file is part of RawTherapee. + * + * 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 . + * + * 2010 Ilya Popov + * 2012 Emil Martinec + * 2014 Ingo Weyrich + */ + +#ifndef CPLX_WAVELET_LEVEL_H_INCLUDED +#define CPLX_WAVELET_LEVEL_H_INCLUDED + +#include +#include "rt_math.h" +#include "opthelper.h" +#include "stdio.h" +namespace rtengine { + + template + class wavelet_level + { + + // level of decomposition + int lvl; + + // whether to subsample the output + bool subsamp_out; + + int numThreads; + + // spacing of filter taps + int skip; + + bool bigBlockOfMemory; + // allocation and destruction of data storage + T ** create(int n); + void destroy(T ** subbands); + + // load a row/column of input data, possibly with padding + + void AnalysisFilterHaarVertical (const T * const srcbuffer, T * dstLo, T * dstHi, const int width, const int height, const int row); + void AnalysisFilterHaarHorizontal (const T * const srcbuffer, T * dstLo, T * dstHi, const int width, const int row); + void SynthesisFilterHaarHorizontal (const T * const srcLo, const T * const srcHi, T * dst, const int width, const int height); + void SynthesisFilterHaarVertical (const T * const srcLo, const T * const srcHi, T * dst, const int width, const int height); + + void AnalysisFilterSubsampHorizontal (T * srcbuffer, T * dstLo, T * dstHi, float *filterLo, float *filterHi, + const int taps, const int offset, const int srcwidth, const int dstwidth, const int row); +#ifdef __SSE2__ + void AnalysisFilterSubsampVertical (T * srcbuffer, T * dstLo, T * dstHi, float (*filterLo)[4], float (*filterHi)[4], + const int taps, const int offset, const int width, const int height, const int row); +#else + void AnalysisFilterSubsampVertical (T * srcbuffer, T * dstLo, T * dstHi, float *filterLo, float *filterHi, + int const taps, const int offset, const int width, const int height, const int row); +#endif + void SynthesisFilterSubsampHorizontal (T * srcLo, T * srcHi, T * dst, + float *filterLo, float *filterHi, const int taps, const int offset, const int scrwidth, const int dstwidth, const int height); +#ifdef __SSE2__ + void SynthesisFilterSubsampVertical (T * srcLo, T * srcHi, T * dst, float (*filterLo)[4], float (*filterHi)[4], const int taps, const int offset, const int width, const int srcheight, const int dstheight, const float blend); +#else + void SynthesisFilterSubsampVertical (T * srcLo, T * srcHi, T * dst, float *filterLo, float *filterHi, const int taps, const int offset, const int width, const int srcheight, const int dstheight, const float blend); +#endif + public: + bool memoryAllocationFailed; + + T ** wavcoeffs; + // full size + int m_w, m_h; + + // size of low frequency part + int m_w2, m_h2; + + template + wavelet_level(E * src, E * dst, int level, int subsamp, int w, int h, float *filterV, float *filterH, int len, int offset, int skipcrop, int numThreads) + : lvl(level), subsamp_out((subsamp>>level)&1), numThreads(numThreads), skip(1<>n)&1); + } + skip /= skipcrop; + if(skip < 1) skip=1; + + } + m_w2 = (subsamp_out ? (w+1)/2 : w); + m_h2 = (subsamp_out ? (h+1)/2 : h); + + wavcoeffs = create((m_w2)*(m_h2)); + if(!memoryAllocationFailed) + decompose_level(src, dst, filterV, filterH, len, offset); + + } + + ~wavelet_level() { + destroy(wavcoeffs); + } + + T ** subbands() const { + return wavcoeffs; + } + + T * lopass() const { + return wavcoeffs[0]; + } + + int width() const { + return m_w2; + } + + int height() const { + return m_h2; + } + + int stride() const { + return skip; + } + + bool bigBlockOfMemoryUsed() const { + return bigBlockOfMemory; + } + + template + void decompose_level(E *src, E *dst, float *filterV, float *filterH, int len, int offset); + + template + void reconstruct_level(E* tmpLo, E* tmpHi, E *src, E *dst, float *filterV, float *filterH, int taps, int offset, const float blend = 1.f); + }; + + template + T ** wavelet_level::create(int n) { + T * data = new (std::nothrow) T[3*n]; + if(data == NULL) { + bigBlockOfMemory = false; + } + T ** subbands = new T*[4]; + for(int j = 1; j < 4; j++) { + if(bigBlockOfMemory) + subbands[j] = data + n * (j-1); + else { + subbands[j] = new (std::nothrow) T[n]; + if(subbands[j] == NULL) { + printf("Couldn't allocate memory in level %d of wavelet\n",lvl); + memoryAllocationFailed = true; + } + } + } + return subbands; + } + + template + void wavelet_level::destroy(T ** subbands) { + if(subbands) { + if(bigBlockOfMemory) + delete[] subbands[1]; + else { + for(int j = 1; j < 4; j++) { + if(subbands[j] != NULL) + delete[] subbands[j]; + } + } + delete[] subbands; + } + } + + template + void wavelet_level::AnalysisFilterHaarHorizontal (const T * const RESTRICT srcbuffer, T * RESTRICT dstLo, T * RESTRICT dstHi, const int width, const int row) { + /* Basic convolution code + * Applies a Haar filter + */ + for(int i = 0; i < (width - skip); i++) { + dstLo[row*width+i] = (srcbuffer[i] + srcbuffer[i+skip]); + dstHi[row*width+i] = (srcbuffer[i] - srcbuffer[i+skip]); + } + for(int i = max(width-skip,skip); i < (width); i++) { + dstLo[row*width+i] = (srcbuffer[i] + srcbuffer[i-skip]); + dstHi[row*width+i] = (srcbuffer[i] - srcbuffer[i-skip]); + } + } + + template void wavelet_level::AnalysisFilterHaarVertical (const T * const RESTRICT srcbuffer, T * RESTRICT dstLo, T * RESTRICT dstHi, const int width, const int height, const int row) { + /* Basic convolution code + * Applies a Haar filter + */ + if(row < (height - skip)) { + for(int j=0;j=max(height-skip,skip)) { + for(int j=0;j void wavelet_level::SynthesisFilterHaarHorizontal (const T * const RESTRICT srcLo, const T * const RESTRICT srcHi, T * RESTRICT dst, const int width, const int height) { + + /* Basic convolution code + * Applies a Haar filter + * + */ +#ifdef _RT_NESTED_OPENMP +#pragma omp parallel for num_threads(numThreads) if(numThreads>1) +#endif + for (int k=0; k void wavelet_level::SynthesisFilterHaarVertical (const T * const RESTRICT srcLo, const T * const RESTRICT srcHi, T * RESTRICT dst, const int width, const int height) { + + /* Basic convolution code + * Applies a Haar filter + * + */ +#ifdef _RT_NESTED_OPENMP +#pragma omp parallel num_threads(numThreads) if(numThreads>1) +#endif +{ +#ifdef _RT_NESTED_OPENMP +#pragma omp for nowait +#endif + for(int i = 0; i < skip; i++) { + for(int j=0;j + void wavelet_level::AnalysisFilterSubsampHorizontal (T * RESTRICT srcbuffer, T * RESTRICT dstLo, T * RESTRICT dstHi, float * RESTRICT filterLo, float *RESTRICT filterHi, + const int taps, const int offset, const int srcwidth, const int dstwidth, const int row) { + /* Basic convolution code + * Applies an FIR filter 'filter' with filter length 'taps', + * aligning the 'offset' element of the filter with + * the input pixel, and skipping 'skip' pixels between taps + * Output is subsampled by two + */ + // calculate coefficients + for(int i = 0; i < srcwidth; i+=2) { + float lo = 0.f, hi = 0.f; + if (LIKELY(i>skip*taps && i SSEFUNCTION void wavelet_level::AnalysisFilterSubsampVertical (T * RESTRICT srcbuffer, T * RESTRICT dstLo, T * RESTRICT dstHi, float (* RESTRICT filterLo)[4], float (* RESTRICT filterHi)[4], + const int taps, const int offset, const int width, const int height, const int row) { + + /* Basic convolution code + * Applies an FIR filter 'filter' with filter length 'taps', + * aligning the 'offset' element of the filter with + * the input pixel, and skipping 'skip' pixels between taps + * Output is subsampled by two + */ + + // calculate coefficients + if (LIKELY(row>skip*taps && row void wavelet_level::AnalysisFilterSubsampVertical (T * RESTRICT srcbuffer, T * RESTRICT dstLo, T * RESTRICT dstHi, float * RESTRICT filterLo, float * RESTRICT filterHi, + const int taps, const int offset, const int width, const int height, const int row) { + + /* Basic convolution code + * Applies an FIR filter 'filter' with filter length 'taps', + * aligning the 'offset' element of the filter with + * the input pixel, and skipping 'skip' pixels between taps + * Output is subsampled by two + */ + + // calculate coefficients + if (LIKELY(row>skip*taps && row void wavelet_level::SynthesisFilterSubsampHorizontal (T * RESTRICT srcLo, T * RESTRICT srcHi, T * RESTRICT dst, float * RESTRICT filterLo, float * RESTRICT filterHi, const int taps, const int offset, const int srcwidth, const int dstwidth, const int height) { + + /* Basic convolution code + * Applies an FIR filter 'filter' with filter length 'taps', + * aligning the 'offset' element of the filter with + * the input pixel, and skipping 'skip' pixels between taps + * Output is subsampled by two + */ + + // calculate coefficients + int shift = skip*(taps-offset-1);//align filter with data +#ifdef _RT_NESTED_OPENMP +#pragma omp parallel for num_threads(numThreads) if(numThreads>1) +#endif + for (int k=0; k SSEFUNCTION void wavelet_level::SynthesisFilterSubsampVertical (T * RESTRICT srcLo, T * RESTRICT srcHi, T * RESTRICT dst, float (* RESTRICT filterLo)[4], float (* RESTRICT filterHi)[4], const int taps, const int offset, const int width, const int srcheight, const int dstheight, const float blend) + { + + /* Basic convolution code + * Applies an FIR filter 'filter' with filter length 'taps', + * aligning the 'offset' element of the filter with + * the input pixel, and skipping 'skip' pixels between taps + * Output is subsampled by two + */ + const float srcFactor = 1.f - blend; + // calculate coefficients + int shift=skip*(taps-offset-1);//align filter with data + __m128 fourv = _mm_set1_ps(4.f); + __m128 srcFactorv = _mm_set1_ps(srcFactor); + __m128 dstFactorv = _mm_set1_ps(blend); +#ifdef _RT_NESTED_OPENMP +#pragma omp parallel for num_threads(numThreads) if(numThreads>1) +#endif + for(int i = 0; i < dstheight; i++) { + int i_src = (i+shift)/2; + int begin = (i+shift)%2; + //TODO: this is correct only if skip=1; otherwise, want to work with cosets of length 'skip' + if (LIKELY(i>skip*taps && i<(dstheight-skip*taps))) {//bulk + int k; + for (k=0; k void wavelet_level::SynthesisFilterSubsampVertical (T * RESTRICT srcLo, T * RESTRICT srcHi, T * RESTRICT dst, float * RESTRICT filterLo, float * RESTRICT filterHi, const int taps, const int offset, const int width, const int srcheight, const int dstheight, const float blend) + { + + /* Basic convolution code + * Applies an FIR filter 'filter' with filter length 'taps', + * aligning the 'offset' element of the filter with + * the input pixel, and skipping 'skip' pixels between taps + * Output is subsampled by two + */ + + const float srcFactor = 1.f - blend; + // calculate coefficients + int shift=skip*(taps-offset-1);//align filter with data + +#ifdef _RT_NESTED_OPENMP +#pragma omp parallel for num_threads(numThreads) if(numThreads>1) +#endif + for(int i = 0; i < dstheight; i++) { + int i_src = (i+shift)/2; + int begin = (i+shift)%2; + //TODO: this is correct only if skip=1; otherwise, want to work with cosets of length 'skip' + if (LIKELY(i>skip*taps && i<(dstheight-skip*taps))) {//bulk + for (int k=0; k template SSEFUNCTION void wavelet_level::decompose_level(E *src, E *dst, float *filterV, float *filterH, int taps, int offset) { + + /* filter along rows and columns */ + float filterVarray[2*taps][4] ALIGNED64; + if(subsamp_out) { + for(int i=0;i<2*taps;i++) { + for(int j=0;j<4;j++) { + filterVarray[i][j] = filterV[i]; + } + } + } +#ifdef _RT_NESTED_OPENMP +#pragma omp parallel num_threads(numThreads) if(numThreads>1) +#endif +{ + T tmpLo[m_w] ALIGNED64; + T tmpHi[m_w] ALIGNED64; + if(subsamp_out) { +#ifdef _RT_NESTED_OPENMP +#pragma omp for +#endif + for(int row=0;row template void wavelet_level::decompose_level(E *src, E *dst, float *filterV, float *filterH, int taps, int offset) { + +#ifdef _RT_NESTED_OPENMP +#pragma omp parallel num_threads(numThreads) if(numThreads>1) +#endif +{ + T tmpLo[m_w] ALIGNED64; + T tmpHi[m_w] ALIGNED64; + /* filter along rows and columns */ + if(subsamp_out) { +#ifdef _RT_NESTED_OPENMP +#pragma omp for +#endif + for(int row=0;row template SSEFUNCTION void wavelet_level::reconstruct_level(E* tmpLo, E* tmpHi, E * src, E *dst, float *filterV, float *filterH, int taps, int offset, const float blend) { + if(memoryAllocationFailed) + return; + + /* filter along rows and columns */ + if (subsamp_out) { + float filterVarray[2*taps][4] ALIGNED64; + for(int i=0;i<2*taps;i++) { + for(int j=0;j<4;j++) { + filterVarray[i][j] = filterV[i]; + } + } + SynthesisFilterSubsampHorizontal (wavcoeffs[2], wavcoeffs[3], tmpHi, filterH, filterH+taps, taps, offset, m_w2, m_w, m_h2); + SynthesisFilterSubsampHorizontal (src, wavcoeffs[1], tmpLo, filterH, filterH+taps, taps, offset, m_w2, m_w, m_h2); + SynthesisFilterSubsampVertical (tmpLo, tmpHi, dst, filterVarray, filterVarray+taps, taps, offset, m_w, m_h2, m_h, blend); + } else { + SynthesisFilterHaarHorizontal (wavcoeffs[2], wavcoeffs[3], tmpHi, m_w, m_h2); + SynthesisFilterHaarHorizontal (src, wavcoeffs[1], tmpLo, m_w, m_h2); + SynthesisFilterHaarVertical (tmpLo, tmpHi, dst, m_w, m_h); + } + } +#else + template template void wavelet_level::reconstruct_level(E* tmpLo, E* tmpHi, E * src, E *dst, float *filterV, float *filterH, int taps, int offset, const float blend) { + if(memoryAllocationFailed) + return; + /* filter along rows and columns */ + if (subsamp_out) { + SynthesisFilterSubsampHorizontal (wavcoeffs[2], wavcoeffs[3], tmpHi, filterH, filterH+taps, taps, offset, m_w2, m_w, m_h2); + SynthesisFilterSubsampHorizontal (src, wavcoeffs[1], tmpLo, filterH, filterH+taps, taps, offset, m_w2, m_w, m_h2); + SynthesisFilterSubsampVertical (tmpLo, tmpHi, dst, filterV, filterV+taps, taps, offset, m_w, m_h2, m_h, blend); + } else { + SynthesisFilterHaarHorizontal (wavcoeffs[2], wavcoeffs[3], tmpHi, m_w, m_h2); + SynthesisFilterHaarHorizontal (src, wavcoeffs[1], tmpLo, m_w, m_h2); + SynthesisFilterHaarVertical (tmpLo, tmpHi, dst, m_w, m_h); + } + } +#endif +}; + +#endif diff --git a/rtengine/curves.cc b/rtengine/curves.cc new file mode 100644 index 000000000..17f5d0fd5 --- /dev/null +++ b/rtengine/curves.cc @@ -0,0 +1,1623 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 +#include +#include +#include + +#include "rt_math.h" + +#include "mytime.h" +#include "array2D.h" +#include "LUT.h" +#include "curves.h" +#include "opthelper.h" +#undef CLIPD +#define CLIPD(a) ((a)>0.0f?((a)<1.0f?(a):1.0f):0.0f) + +using namespace std; + +namespace rtengine { + + Curve::Curve () : N(0), x(NULL), y(NULL), ypp(NULL), hashSize(1000 /* has to be initialized to the maximum value */ ) {} + + void Curve::AddPolygons () + { + if (firstPointIncluded) { + poly_x.push_back(x1); + poly_y.push_back(y1); + } + for (int k=1; k<(nbr_points-1); k++) { + double t = k*increment; + double t2 = t*t; + double tr = 1.-t; + double tr2 = tr*tr; + double tr2t = tr*2*t; + + // adding a point to the polyline + poly_x.push_back( tr2*x1 + tr2t*x2 + t2*x3); + poly_y.push_back( tr2*y1 + tr2t*y2 + t2*y3); + } + // adding the last point of the sub-curve + poly_x.push_back(x3); + poly_y.push_back(y3); + } + + void Curve::fillHash() { + hash.resize(hashSize+2); + + unsigned int polyIter = 0; + double const increment = 1./hashSize; + double milestone = 0.; + + for (unsigned short i=0; i<(hashSize+1);) { + while(poly_x[polyIter] <= milestone) ++polyIter; + hash.at(i).smallerValue = polyIter-1; + ++i; + milestone = i*increment; + } + milestone = 0.; + polyIter = 0; + for (unsigned int i=0; i<(hashSize+1);) { + while(poly_x[polyIter] < (milestone+increment)) ++polyIter; + hash.at(i).higherValue = polyIter; + ++i; + milestone = i*increment; + } + hash.at(hashSize+1).smallerValue = poly_x.size()-1; + hash.at(hashSize+1).higherValue = poly_x.size(); + + /* + * Uncoment the code below to dump the polygon points and the hash table in files + if (poly_x.size() > 500) { + printf("Files generated (%d points)\n", poly_x.size()); + FILE* f = fopen ("hash.txt", "wt"); + for (unsigned int i=0; ix && cpNum < N) { + x = this->x[cpNum]; + y = this->y[cpNum]; + } + else { + x = y = -1.; + } + } + + // Wikipedia sRGB: Unlike most other RGB color spaces, the sRGB gamma cannot be expressed as a single numerical value. + // The overall gamma is approximately 2.2, consisting of a linear (gamma 1.0) section near black, and a non-linear section elsewhere involving a 2.4 exponent + // and a gamma (slope of log output versus log input) changing from 1.0 through about 2.3. + const double CurveFactory::sRGBGamma = 2.2; + const double CurveFactory::sRGBGammaCurve = 2.4; + + SSEFUNCTION void fillCurveArray(DiagonalCurve* diagCurve, LUTf &outCurve, int skip, bool needed) { + + if (needed) { + LUTf lutCurve (65536); + + for (int i=0; i<=0xffff; i+= i<0xffff-skip ? skip : 1 ) { + // change to [0,1] range + float val = (float)i / 65535.f; + // apply custom/parametric/NURBS curve, if any + val = diagCurve->getVal (val); + // store result in a temporary array + lutCurve[i] = (val); + } + + // if skip>1, let apply linear interpolation in the skipped points of the curve + if (skip > 1) { + int prev = 0; + for (int i=1; i<=0xffff-skip; i++) { + if (i%skip==0) { + prev+=skip; + continue; + } + lutCurve[i] = ( lutCurve[prev] * (skip - i%skip) + lutCurve[prev+skip] * (i%skip) ) / skip; + } + } + + for (int i=0; i<=0xffff; i++) { + outCurve[i] = (65535.f * lutCurve[i]); + } + } + else { +#ifdef __SSE2__ + __m128 fourv = _mm_set1_ps(4.f); + __m128 iv = _mm_set_ps(3.f,2.f,1.f,0.f); + for (int i=0; i<=0xfffc; i+=4) { + _mm_storeu_ps(&outCurve[i],iv); + iv += fourv; + } +#else + for (int i=0; i<=0xffff; i++) { + outCurve[i] = (float)i; + } +#endif + } + + } + +void CurveFactory::updatechroma ( + const std::vector& cccurvePoints, + LUTu & histogramC, LUTu & outBeforeCCurveHistogramC,//for chroma + int skip) +{ + LUTf dCcurve(65536,0); + float val; + for (int i=0; i<48000; i++) {//32768*1.414 + ... + val = (double)i / 47999.0; + dCcurve[i] = CLIPD(val); + } + + outBeforeCCurveHistogramC.clear(); + bool histNeededC = false; + + + if (!cccurvePoints.empty() && cccurvePoints[0]!=0) { + if (outBeforeCCurveHistogramC /*&& histogramCropped*/) + histNeededC = true; + } + for (int i=0; i<48000; i++) {//32768*1.414 + ... + float val; + if (histNeededC) { + float hval = dCcurve[i]; + int hi = (int)(255.0*CLIPD(hval)); // + outBeforeCCurveHistogramC[hi] += histogramC[i] ; + } + } +} + + +void CurveFactory::curveLightBrightColor ( + procparams::ColorAppearanceParams::eTCModeId curveMode1, const std::vector& curvePoints1, + procparams::ColorAppearanceParams::eTCModeId curveMode2, const std::vector& curvePoints2, + procparams::ColorAppearanceParams::eCTCModeId curveMode3, const std::vector& curvePoints3, + LUTu & histogram, LUTu & histogramCropped, LUTu & outBeforeCCurveHistogram,//for Luminance + LUTu & histogramC, LUTu & outBeforeCCurveHistogramC,//for chroma + ColorAppearance & customColCurve1, + ColorAppearance & customColCurve2, + ColorAppearance & customColCurve3, + int skip) +{ + + outBeforeCCurveHistogram.clear(); + outBeforeCCurveHistogramC.clear(); + bool histNeededC = false; + + bool histNeeded = false; + DiagonalCurve* tcurve = NULL; + customColCurve3.Reset(); + + if (!curvePoints3.empty() && curvePoints3[0]>DCT_Linear && curvePoints3[0]isIdentity()) { + delete tcurve; + tcurve = NULL; + } + else + customColCurve3.Set(tcurve); + delete tcurve; + tcurve = NULL; + } + + customColCurve2.Reset(); + + if (!curvePoints2.empty() && curvePoints2[0]>DCT_Linear && curvePoints2[0]isIdentity()) { + delete tcurve; + tcurve = NULL; + } + else + customColCurve2.Set(tcurve); + delete tcurve; + tcurve = NULL; + } + // create first curve if needed + customColCurve1.Reset(); + + if (!curvePoints1.empty() && curvePoints1[0]>DCT_Linear && curvePoints1[0]isIdentity()) { + delete tcurve; + tcurve = NULL; + } + else { + customColCurve1.Set(tcurve); + delete tcurve; + tcurve = NULL; + } + } + if (histNeeded) { + for (int i=0; i<32768; i++) { + double hval = CLIPD((double)i / 32767.0); + int hi = (int)(255.0*hval); + outBeforeCCurveHistogram[hi] += histogram[i] ; + } + } + if (histNeededC) { + for (int i=0; i<48000; i++) {//32768*1.414 + ... + double hval = CLIPD((double)i / 47999.0); + int hi = (int)(255.0*hval); // + outBeforeCCurveHistogramC[hi] += histogramC[i] ; + } + } + + if (tcurve) delete tcurve; + +} +// add curve Denoise : C=f(C) +void CurveFactory::denoiseCC ( bool & ccdenoiseutili,const std::vector& cccurvePoints, LUTf & NoiseCCcurve,int skip){ + bool needed; + DiagonalCurve* dCurve = NULL; + LUTf dCcurve(65536,0); + + float val; + for (int i=0; i<48000; i++) { + dCcurve[i] = (float)i / 47999.0; + } + + needed = false; + if (!cccurvePoints.empty() && cccurvePoints[0]!=0) { + dCurve = new DiagonalCurve (cccurvePoints, CURVES_MIN_POLY_POINTS/skip); + + if (dCurve && !dCurve->isIdentity()) + {needed = true;ccdenoiseutili=true;} + } + fillCurveArray(dCurve, NoiseCCcurve, skip, needed); + //NoiseCCcurve.dump("Noise"); + + if (dCurve) { + delete dCurve; + dCurve = NULL; + } +} + + +void CurveFactory::curveBW ( + const std::vector& curvePointsbw, const std::vector& curvePointsbw2, + LUTu & histogrambw, LUTu & outBeforeCCurveHistogrambw,//for Luminance + ToneCurve & customToneCurvebw1, ToneCurve & customToneCurvebw2, int skip) +{ + + outBeforeCCurveHistogrambw.clear(); + bool histNeeded = false; + + DiagonalCurve* tcurve = NULL; + customToneCurvebw2.Reset(); + + if (!curvePointsbw2.empty() && curvePointsbw2[0]>DCT_Linear && curvePointsbw2[0]isIdentity()) + customToneCurvebw2.Set(tcurve); + delete tcurve; + tcurve = NULL; + } + + customToneCurvebw1.Reset(); + + if (!curvePointsbw.empty() && curvePointsbw[0]>DCT_Linear && curvePointsbw[0]isIdentity()) + customToneCurvebw1.Set(tcurve); + delete tcurve; + tcurve = NULL; + } + // create first curve if needed + if (histNeeded) { + LUTf dcurve(65536,0); + + float val; + for (int i=0; i<32768; i++) { + val = (float)i / 32767.f; + dcurve[i] = CLIPD(val); + } + + for (int i=0; i<32768; i++) { + float hval = dcurve[i]; + int hi = (int)(255.0*CLIPD(hval)); + outBeforeCCurveHistogrambw[hi] += histogrambw[i] ; + } + } + + if (tcurve) delete tcurve; + +} +// add curve Lab : C=f(L) +void CurveFactory::curveCL ( bool & clcutili,const std::vector& clcurvePoints, LUTf & clCurve, LUTu & histogramcl, LUTu & outBeforeCLurveHistogram,int skip){ + bool needed; + DiagonalCurve* dCurve = NULL; + + if (outBeforeCLurveHistogram) + outBeforeCLurveHistogram.clear(); + bool histNeededCL = false; + + needed = false; + if (!clcurvePoints.empty() && clcurvePoints[0]!=0) { + dCurve = new DiagonalCurve (clcurvePoints, CURVES_MIN_POLY_POINTS/skip); + if (outBeforeCLurveHistogram) + histNeededCL = true; + + if (dCurve && !dCurve->isIdentity()) + {needed = true;clcutili=true;} + } + if(histNeededCL) + for (int i=0; i<50000; i++) {//32768*1.414 + ... + int hi = (int)(255.0*CLIPD((float)i / 49999.0)); // + outBeforeCLurveHistogram[hi] += histogramcl[i] ; + } + + + fillCurveArray(dCurve, clCurve, skip, needed); + if (dCurve) { + delete dCurve; + dCurve = NULL; + } +} +// add curve Lab wavelet : Cont=f(L) +void CurveFactory::curveWavContL ( bool & wavcontlutili,const std::vector& wavclcurvePoints, LUTf & wavclCurve, /*LUTu & histogramwavcl, LUTu & outBeforeWavCLurveHistogram,*/int skip){ + bool needed; + DiagonalCurve* dCurve = NULL; + + // if (outBeforeWavCLurveHistogram) + // outBeforeWavCLurveHistogram.clear(); + bool histNeededCL = false; + + needed = false; + if (!wavclcurvePoints.empty() && wavclcurvePoints[0]!=0) { + dCurve = new DiagonalCurve (wavclcurvePoints, CURVES_MIN_POLY_POINTS/skip); + // if (outBeforeWavCLurveHistogram) + // histNeededCL = true; + + if (dCurve && !dCurve->isIdentity()) + {needed = true;wavcontlutili=true;} + } + // if(histNeededCL) + for (int i=0; i<32768; i++) {//32768*1.414 + ... + int hi = (int)(255.0*CLIPD((float)i / 32767.0)); // + // outBeforeWavCLurveHistogram[hi] += histogramwavcl[i] ; + } + + + fillCurveArray(dCurve, wavclCurve, skip, needed); + // wavclCurve.dump("WL"); + + if (dCurve) { + delete dCurve; + dCurve = NULL; + } +} + +// add curve Colortoning : C=f(L) +void CurveFactory::curveToningCL ( bool & clctoningutili,const std::vector& clcurvePoints, LUTf & clToningCurve,int skip){ + bool needed; + DiagonalCurve* dCurve = NULL; + + needed = false; + if (!clcurvePoints.empty() && clcurvePoints[0]!=0) { + dCurve = new DiagonalCurve (clcurvePoints, CURVES_MIN_POLY_POINTS/skip); + + if (dCurve && !dCurve->isIdentity()) + {needed = true;clctoningutili=true;} + } + fillCurveArray(dCurve, clToningCurve, skip, needed); + // clToningCurve.dump("CLToning"); + if (dCurve) { + delete dCurve; + dCurve = NULL; + } +} + +// add curve Colortoning : CLf(L) +void CurveFactory::curveToningLL ( bool & llctoningutili,const std::vector& llcurvePoints, LUTf & llToningCurve, int skip){ + bool needed; + DiagonalCurve* dCurve = NULL; + + needed = false; + if (!llcurvePoints.empty() && llcurvePoints[0]!=0) { + dCurve = new DiagonalCurve (llcurvePoints, CURVES_MIN_POLY_POINTS/skip); + + if (dCurve && !dCurve->isIdentity()) + {needed = true;llctoningutili=true;} + } + fillCurveArray(dCurve, llToningCurve, skip, needed); +// llToningCurve.dump("LLToning"); + + if (dCurve) { + delete dCurve; + dCurve = NULL; + } +} + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + void CurveFactory::complexsgnCurve (float adjustr, bool & autili, bool & butili, bool & ccutili, bool & cclutili, double saturation, double rstprotection, + const std::vector& acurvePoints, const std::vector& bcurvePoints,const std::vector& cccurvePoints, + const std::vector& lccurvePoints, LUTf & aoutCurve, LUTf & boutCurve, LUTf & satCurve, LUTf & lhskCurve, + LUTu & histogramC, LUTu & histogramLC, LUTu & outBeforeCCurveHistogram,LUTu & outBeforeLCurveHistogram, //for chroma + int skip) { + + + //----------------------------------------------------- + + bool needed; + DiagonalCurve* dCurve = NULL; + LUTf dCcurve(65536,0); + int k=48000;//32768*1.41 + if(outBeforeCCurveHistogram || outBeforeLCurveHistogram) { + for (int i=0; iisIdentity()) { + needed = true; + autili=true; + } + } + fillCurveArray(dCurve, aoutCurve, skip, needed); + //if(autili) aoutCurve.dump("acurve"); + + if (dCurve) { + delete dCurve; + dCurve = NULL; + } + + //----------------------------------------------------- + + needed = false; + if (!bcurvePoints.empty() && bcurvePoints[0]!=0) { + dCurve = new DiagonalCurve (bcurvePoints, CURVES_MIN_POLY_POINTS/skip); + if (dCurve && !dCurve->isIdentity()) { + needed = true; + butili=true; + } + } + fillCurveArray(dCurve, boutCurve, skip, needed); + if (dCurve) { + delete dCurve; + dCurve = NULL; + } + + //----------------------------------------------- + needed = false; + if (!cccurvePoints.empty() && cccurvePoints[0]!=0) { + dCurve = new DiagonalCurve (cccurvePoints, CURVES_MIN_POLY_POINTS/skip); + if (outBeforeCCurveHistogram /*&& histogramCropped*/) + histNeededC = true; + + if (dCurve && !dCurve->isIdentity()) + {needed = true;ccutili=true;} + } + if (histNeededC) { + for (int i=0; iisIdentity()) + {needed = true;cclutili=true;} + } + if (histNeededLC) { + for (int i=0; i& curvePoints, + procparams::ToneCurveParams::eTCModeId curveMode2, const std::vector& curvePoints2, + LUTu & histogram, LUTu & histogramCropped, + LUTf & hlCurve, LUTf & shCurve, LUTf & outCurve, + LUTu & outBeforeCCurveHistogram, + ToneCurve & customToneCurve1, + ToneCurve & customToneCurve2, + int skip) { + + + //double def_mul = pow (2.0, defmul); + + /*printf ("def_mul= %f ecomp= %f black= %f hlcompr= %f shcompr= %f br= %f contr= %f defmul= %f + gamma= %f, skip= %d \n",def_mul,ecomp,black,hlcompr,shcompr,br,contr,defmul,gamma_,skip);*/ + + // compute parameters of the gamma curve + /*double start = exp(gamma_*log( -0.099 / ((1.0/gamma_-1.0)*1.099 ))); + double slope = 1.099 * pow (start, 1.0/gamma_-1) - 0.099/start; + double mul = 1.099; + double add = 0.099; + // gamma BT709*/ + + //normalize gamma to sRGB + double start = exp(gamma_*log( -0.055 / ((1.0/gamma_-1.0)*1.055 ))); + double slope = 1.055 * pow (start, 1.0/gamma_-1) - 0.055/start; + double mul = 1.055; + double add = 0.055; + + // a: slope of the curve, black: starting point at the x axis + double a = pow (2.0, ecomp); + + + // check if inverse gamma is needed at the end + bool needigamma = igamma_ && gamma_>1.; + + // clear array that stores histogram valid before applying the custom curve + outBeforeCCurveHistogram.clear(); + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // tone curve base. a: slope (from exp.comp.), b: black, def_mul: max. x value (can be>1), hr,sr: highlight,shadow recovery + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + DiagonalCurve* brightcurve = NULL; + + // check if brightness curve is needed + if (br>0.00001 || br<-0.00001) { + + std::vector brightcurvePoints; + brightcurvePoints.resize(9); + brightcurvePoints.at(0) = double(DCT_NURBS); + + brightcurvePoints.at(1) = 0.; //black point. Value in [0 ; 1] range + brightcurvePoints.at(2) = 0.; //black point. Value in [0 ; 1] range + + if(br>0) { + brightcurvePoints.at(3) = 0.1; //toe point + brightcurvePoints.at(4) = 0.1+br/150.0; //value at toe point + + brightcurvePoints.at(5) = 0.7; //shoulder point + brightcurvePoints.at(6) = min(1.0,0.7+br/300.0); //value at shoulder point + } else { + brightcurvePoints.at(3) = max(0.0,0.1-br/150.0); //toe point + brightcurvePoints.at(4) = 0.1; //value at toe point + + brightcurvePoints.at(5) = 0.7-br/300.0; //shoulder point + brightcurvePoints.at(6) = 0.7; //value at shoulder point + } + brightcurvePoints.at(7) = 1.; // white point + brightcurvePoints.at(8) = 1.; // value at white point + + brightcurve = new DiagonalCurve (brightcurvePoints, CURVES_MIN_POLY_POINTS/skip); + } + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + hlCurve.setClip(LUT_CLIP_BELOW); // used LUT_CLIP_BELOW, because we want to have a baseline of 2^expcomp in this curve. If we don't clip the lut we get wrong values, see Issue 2621 #14 for details + float exp_scale = a; + float scale = 65536.0; + float comp = (max(0.0,ecomp) + 1.0)*hlcompr/100.0; + float shoulder = ((scale/max(1.0f,exp_scale))*(hlcomprthresh/200.0))+0.1; + //printf("shoulder = %e\n",shoulder); + //printf ("exp_scale= %f comp= %f def_mul=%f a= %f \n",exp_scale,comp,def_mul,a); + + if (comp<=0.0f) + for (int i=0; i<0x10000; i++) + hlCurve[i]=exp_scale; + else { + for (int i=0; i<=shoulder; i++) + hlCurve[i]=exp_scale; + float scalemshoulder = scale - shoulder; + + for (int i=shoulder+1; i<0x10000; i++) { + // change to [0,1] range + float val = (float)i-shoulder; + float R = val*comp/(scalemshoulder); + hlCurve[i] = xlog(1.0+R*exp_scale)/R; // don't use xlogf or 1.f here. Leads to errors caused by too low precision + } + } + + + // curve without contrast + LUTf dcurve(0x10000); + + //%%%%%%%%%%%%%%%%%%%%%%%%%% + // change to [0,1] range + shCurve.setClip(LUT_CLIP_ABOVE); // used LUT_CLIP_ABOVE, because the curve converges to 1.0 at the upper end and we don't want to exceed this value. + float val = 1.f/65535.f; + float val2 = simplebasecurve (val, black, 0.015*shcompr); + shCurve[0] = CLIPD(val2)/val; + val = 0.0; + // gamma correction + if (gamma_>1.) + val = gamma (val, gamma_, start, slope, mul, add); + + // apply brightness curve + if (brightcurve) + val = brightcurve->getVal (val); // TODO: getVal(double) is very slow! Optimize with a LUTf + + // store result in a temporary array + dcurve[0] = CLIPD(val); + +#pragma omp parallel for + for (int i=1; i<0x10000; i++) { + float val; + val = (float)i / 65535.0f; + + float val2 = simplebasecurve (val, black, 0.015*shcompr); + shCurve[i] = CLIPD(val2)/val; + + // gamma correction + if (gamma_>1.) + val = gamma (val, gamma_, start, slope, mul, add); + + // apply brightness curve + if (brightcurve) + val = brightcurve->getVal (val); // TODO: getVal(double) is very slow! Optimize with a LUTf + + // store result in a temporary array + dcurve[i] = CLIPD(val); + } + + if (brightcurve) + delete brightcurve; + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + // check if contrast curve is needed + if (contr>0.00001 || contr<-0.00001) { + + // compute mean luminance of the image with the curve applied + unsigned int sum = 0; + float avg = 0; + //double sqavg = 0; + for (int i=0; i<=0xffff; i++) { + float fi=i; + fi *= hlCurve[i]; + avg += dcurve[(int)(shCurve[fi]*fi)] * histogram[i]; + //sqavg += dcurve[i]*dcurve[i] * histogram[i]; + sum += histogram[i]; + } + + avg /= sum; + //sqavg /= sum; + //double stddev = sqrt(sqavg-avg*avg); + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + std::vector contrastcurvePoints; + contrastcurvePoints.resize(9); + contrastcurvePoints.at(0) = double(DCT_NURBS); + + contrastcurvePoints.at(1) = 0; //black point. Value in [0 ; 1] range + contrastcurvePoints.at(2) = 0; //black point. Value in [0 ; 1] range + + contrastcurvePoints.at(3) = avg-avg*(0.6-contr/250.0); //toe point + contrastcurvePoints.at(4) = avg-avg*(0.6+contr/250.0); //value at toe point + + contrastcurvePoints.at(5) = avg+(1-avg)*(0.6-contr/250.0); //shoulder point + contrastcurvePoints.at(6) = avg+(1-avg)*(0.6+contr/250.0); //value at shoulder point + + contrastcurvePoints.at(7) = 1.; // white point + contrastcurvePoints.at(8) = 1.; // value at white point + + DiagonalCurve* contrastcurve = new DiagonalCurve (contrastcurvePoints, CURVES_MIN_POLY_POINTS/skip); + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // apply contrast enhancement + for (int i=0; i<=0xffff; i++) { + dcurve[i] = contrastcurve->getVal (dcurve[i]); + } + + delete contrastcurve; + } + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + // create second curve if needed + bool histNeeded = false; + DiagonalCurve* tcurve = NULL; + customToneCurve2.Reset(); + + if (!curvePoints2.empty() && curvePoints2[0]>DCT_Linear && curvePoints2[0]isIdentity()) + customToneCurve2.Set(tcurve); + delete tcurve; + tcurve = NULL; + } + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + // create first curve if needed + customToneCurve1.Reset(); + + if (!curvePoints.empty() && curvePoints[0]>DCT_Linear && curvePoints[0]isIdentity()) + customToneCurve1.Set(tcurve); + delete tcurve; + tcurve = NULL; + } + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + // create curve bw + // curve 2 +/* DiagonalCurve* tbwcurve = NULL; + customToneCurvebw2.Reset(); + + if (!curvePointsbw2.empty() && curvePointsbw2[0]>DCT_Linear && curvePointsbw2[0]isIdentity()) { + delete tbwcurve; + tbwcurve = NULL; + } + else + customToneCurvebw2.Set(tbwcurve); + delete tbwcurve; + tbwcurve = NULL; + } + + customToneCurvebw1.Reset(); + + if (!curvePointsbw.empty() && curvePointsbw[0]>DCT_Linear && curvePointsbw[0]isIdentity()) { + delete tbwcurve; + tbwcurve = NULL; + } + else if (curveModeb != procparams::BlackWhiteParams::TC_MODE_STD_BW) { + customToneCurvebw1.Set(tbwcurve); + delete tbwcurve; + tbwcurve = NULL; + } + } + */ + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + for (int i=0; i<=0xffff; i++) { + float val = dcurve[i]; + + if (histNeeded) { + float fi=i; + float hval = hlCurve[i]*fi; + hval = dcurve[shCurve[hval]*hval]; + //if (needigamma) + // hval = igamma2 (hval); + int hi = (int)(255.0*(hval)); + outBeforeCCurveHistogram[hi] += histogram/*Cropped*/[i] ; + } + + // if inverse gamma is needed, do it (standard sRGB inverse gamma is applied) + if (needigamma) + val = igamma (val, gamma_, start, slope, mul, add); + + outCurve[i] = (65535.f * val); + } + + if (tcurve) delete tcurve; + + /*if (outBeforeCCurveHistogram) { + for (int i=0; i<256; i++) printf("i= %d bchist= %d \n",i,outBeforeCCurveHistogram[i]); + }*/ + } + + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + void CurveFactory::complexLCurve (double br, double contr, const std::vector& curvePoints, + LUTu & histogram, LUTu & histogramCropped, LUTf & outCurve, + LUTu & outBeforeCCurveHistogram, int skip, bool & utili) { + + // curve without contrast + LUTf dcurve(65536,0); + + // clear array that stores histogram valid before applying the custom curve + if (outBeforeCCurveHistogram) + outBeforeCCurveHistogram.clear(); + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // tone curve base. a: slope (from exp.comp.), b: black, def_mul: max. x value (can be>1), hr,sr: highlight,shadow recovery + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + // check if brightness curve is needed + if (br>0.00001 || br<-0.00001) { + utili=true; + + std::vector brightcurvePoints; + brightcurvePoints.resize(9); + brightcurvePoints.at(0) = double(DCT_NURBS); + + brightcurvePoints.at(1) = 0.; // black point. Value in [0 ; 1] range + brightcurvePoints.at(2) = 0.; // black point. Value in [0 ; 1] range + + if (br>0) { + brightcurvePoints.at(3) = 0.1; // toe point + brightcurvePoints.at(4) = 0.1+br/150.0; //value at toe point + + brightcurvePoints.at(5) = 0.7; // shoulder point + brightcurvePoints.at(6) = min(1.0,0.7+br/300.0); //value at shoulder point + } else { + brightcurvePoints.at(3) = 0.1-br/150.0; // toe point + brightcurvePoints.at(4) = 0.1; // value at toe point + + brightcurvePoints.at(5) = min(1.0,0.7-br/300.0); // shoulder point + brightcurvePoints.at(6) = 0.7; // value at shoulder point + } + brightcurvePoints.at(7) = 1.; // white point + brightcurvePoints.at(8) = 1.; // value at white point + + DiagonalCurve* brightcurve = new DiagonalCurve (brightcurvePoints, CURVES_MIN_POLY_POINTS/skip); + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + // Applying brightness curve + for (int i=0; i<32768; i++) { // L values range up to 32767, higher values are for highlight overflow + + // change to [0,1] range + float val = (float)i / 32767.0; + + // apply brightness curve + val = brightcurve->getVal (val); + + // store result in a temporary array + dcurve[i] = CLIPD(val); + } + delete brightcurve; + } + else { + for (int i=0; i<32768; i++) { // L values range up to 32767, higher values are for highlight overflow + // set the identity curve in the temporary array + dcurve[i] = (float)i / 32767.0; + } + } + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + // check if contrast curve is needed + if (contr>0.00001 || contr<-0.00001) { + utili=true; + + DiagonalCurve* contrastcurve = NULL; + + // compute mean luminance of the image with the curve applied + int sum = 0; + float avg = 0; + //float sqavg = 0; + for (int i=0; i<32768; i++) { + avg += dcurve[i] * histogram[i]; + //sqavg += dcurve[i]*dcurve[i] * histogram[i]; + sum += histogram[i]; + } + if(sum) { + avg /= sum; + //sqavg /= sum; + //float stddev = sqrt(sqavg-avg*avg); + // printf("avg=%f\n",avg); + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + std::vector contrastcurvePoints; + contrastcurvePoints.resize(9); + contrastcurvePoints.at(0) = double(DCT_NURBS); + + contrastcurvePoints.at(1) = 0.; // black point. Value in [0 ; 1] range + contrastcurvePoints.at(2) = 0.; // black point. Value in [0 ; 1] range + + contrastcurvePoints.at(3) = avg-avg*(0.6-contr/250.0); // toe point + contrastcurvePoints.at(4) = avg-avg*(0.6+contr/250.0); // value at toe point + + contrastcurvePoints.at(5) = avg+(1-avg)*(0.6-contr/250.0); // shoulder point + contrastcurvePoints.at(6) = avg+(1-avg)*(0.6+contr/250.0); // value at shoulder point + + contrastcurvePoints.at(7) = 1.; // white point + contrastcurvePoints.at(8) = 1.; // value at white point + + contrastcurve = new DiagonalCurve (contrastcurvePoints, CURVES_MIN_POLY_POINTS/skip); + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + } else { + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // sum has an invalid value (next to 0, producing a division by zero, so we create a fake contrast curve, producing a white image + std::vector contrastcurvePoints; + contrastcurvePoints.resize(5); + contrastcurvePoints.at(0) = double(DCT_NURBS); + + contrastcurvePoints.at(1) = 0.; // black point. Value in [0 ; 1] range + contrastcurvePoints.at(2) = 1.; // black point. Value in [0 ; 1] range + + contrastcurvePoints.at(3) = 1.; // white point + contrastcurvePoints.at(4) = 1.; // value at white point + + contrastcurve = new DiagonalCurve (contrastcurvePoints, CURVES_MIN_POLY_POINTS/skip); + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + } + // apply contrast enhancement + for (int i=0; i<32768; i++) { + dcurve[i] = contrastcurve->getVal (dcurve[i]); + } + + delete contrastcurve; + } + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + // create a curve if needed + DiagonalCurve* tcurve = NULL; + bool histNeeded = false; + if (!curvePoints.empty() && curvePoints[0]!=0) { + tcurve = new DiagonalCurve (curvePoints, CURVES_MIN_POLY_POINTS/skip); + if (outBeforeCCurveHistogram /*&& histogramCropped*/) + histNeeded = true; + } + if (tcurve && tcurve->isIdentity()) { + delete tcurve; + tcurve = NULL; + } + + if (tcurve) { + utili=true;//if active + + // L values go up to 32767, last stop is for highlight overflow + for (int i=0; i<32768; i++) { + float val; + + if (histNeeded) { + float hval = dcurve[i]; + int hi = (int)(255.0*CLIPD(hval)); + outBeforeCCurveHistogram[hi]+=histogram/*Cropped*/[i] ; + } + + // apply custom/parametric/NURBS curve, if any + val = tcurve->getVal (dcurve[i]); + + outCurve[i] = (32767.0 * val); + } + } + else { + // Skip the slow getval method if no curve is used (or an identity curve) + // L values go up to 32767, last stop is for highlight overflow + for (int i=0; i<32768; i++) { + if (histNeeded) { + float hval = dcurve[i]; + int hi = (int)(255.0*CLIPD(hval)); + outBeforeCCurveHistogram[hi]+=histogram/*Cropped*/[i] ; + } + + outCurve[i] = 32767.0*dcurve[i]; + } + } + for (int i=32768; i<65536; i++) outCurve[i]=(float)i; + + if (tcurve) + delete tcurve; + + /*if (outBeforeCCurveHistogram) { + for (int i=0; i<256; i++) printf("i= %d bchist= %d \n",i,outBeforeCCurveHistogram[i]); + }*/ + } + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + void CurveFactory::RGBCurve (const std::vector& curvePoints, LUTf & outCurve, int skip) { + + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + // create a curve if needed + DiagonalCurve* tcurve = NULL; + if (!curvePoints.empty() && curvePoints[0]!=0) { + tcurve = new DiagonalCurve (curvePoints, CURVES_MIN_POLY_POINTS/skip); + } + if (tcurve && tcurve->isIdentity()) { + delete tcurve; + tcurve = NULL; + } + + if (tcurve) { + if (!outCurve) + outCurve(65536, 0); + for (int i=0; i<65536; i++) { + // apply custom/parametric/NURBS curve, if any + float val = tcurve->getVal ((float)i/65536.0f); + outCurve[i] = (65536.0f * val); + } + delete tcurve; + } + // let the LUTf empty for identity curves + else { + outCurve.reset(); + } + + } + + +void ColorAppearance::Reset() { + lutColCurve.reset(); +} + +// Fill a LUT with X/Y, ranged 0xffff +void ColorAppearance::Set(Curve *pCurve) { + lutColCurve(65536); + for (int i=0; i<65536; i++) lutColCurve[i] = pCurve->getVal(double(i)/65535.) * 65535.; +} + +void ToneCurve::Reset() { + lutToneCurve.reset(); +} + +// Fill a LUT with X/Y, ranged 0xffff +void ToneCurve::Set(Curve *pCurve) { + lutToneCurve(65536); + for (int i=0; i<65536; i++) lutToneCurve[i] = pCurve->getVal(double(i)/65535.) * 65535.; +} + +void OpacityCurve::Reset() { + lutOpacityCurve.reset(); +} + +void OpacityCurve::Set(const Curve *pCurve) { + if (pCurve->isIdentity()) { + lutOpacityCurve.reset(); // raise this value if the quality suffers from this number of samples + return; + } + lutOpacityCurve(501); // raise this value if the quality suffers from this number of samples + + for (int i=0; i<501; i++) lutOpacityCurve[i] = pCurve->getVal(double(i)/500.); + //lutOpacityCurve.dump("opacity"); +} + +void OpacityCurve::Set(const std::vector &curvePoints, bool &opautili) { + FlatCurve* tcurve = NULL; + + if (!curvePoints.empty() && curvePoints[0]>FCT_Linear && curvePoints[0]setIdentityValue(0.); + } + if (tcurve) { + Set(tcurve);opautili=true; + delete tcurve; + tcurve = NULL; + } +} + + +WavCurve::WavCurve() : sum(0.f) {}; + +void WavCurve::Reset() { + lutWavCurve.reset(); + sum = 0.f; +} + +void WavCurve::Set(const Curve &pCurve) { + if (pCurve.isIdentity()) { + Reset(); // raise this value if the quality suffers from this number of samples + return; + } + lutWavCurve(501); // raise this value if the quality suffers from this number of samples + sum=0.f; + for (int i=0; i<501; i++) { + lutWavCurve[i] = pCurve.getVal(double(i)/500.); + if(lutWavCurve[i] < 0.02f) + lutWavCurve[i] = 0.02f;//avoid 0.f for wavelet : under 0.01f quasi no action for each value + sum += lutWavCurve[i]; + } + //lutWavCurve.dump("wav"); +} +void WavCurve::Set(const std::vector &curvePoints) { + + if (!curvePoints.empty() && curvePoints[0]>FCT_Linear && curvePoints[0] &curvePoints) { + if (!curvePoints.empty() && curvePoints[0]>FCT_Linear && curvePoints[0] &curvePoints) { + if (!curvePoints.empty() && curvePoints[0]>FCT_Linear && curvePoints[0] &curvePoints) { + if (!curvePoints.empty() && curvePoints[0]>FCT_Linear && curvePoints[0] &curvePoints) { + if (!curvePoints.empty() && curvePoints[0]>FCT_Linear && curvePoints[0] &curvePoints) { + + if (!curvePoints.empty() && curvePoints[0]>FCT_Linear && curvePoints[0]isIdentity()) { + lut1.reset(); + lut2.reset(); + lut3.reset(); + return; + } + if (!lut1) { + lut1(501); + lut2(501); + lut3(501); + } + + float r, g, b, xx, yy, zz; + float lr1,lr2; + int upperBound = lut1.getUpperBound(); + if (pCurve->isIdentity()) { + Color::hsv2rgb(0.5f, satur, lumin, r, g, b); + Color::rgbxyz(r, g, b, xx, yy, zz, xyz_rgb); + + for (int i=0; i<=500; ++i) { + // WARNING: set the identity value according to what is set in the GUI + lut1[i] = xx; + lut2[i] = yy; + lut3[i] = zz; + } + return; + } + + int nPoints = pCurve->getSize(); + int ptNum = 0; + double nextX, nextY; + pCurve->getControlPoint(ptNum, nextX, nextY); + double prevY = nextY; + double dY = 0.; + low=nextX; + lr1=(0.5f+low)/2.f;//optimize use of gamut in low light..one can optimize more using directly low ? + //lr1=low; + + for (int i=0; i<=upperBound; ++i) { + double x = double(i)/double(upperBound); + + if (x > nextX) { + ++ptNum; + if (ptNum < nPoints) { + prevY = nextY; + pCurve->getControlPoint(ptNum, nextX, nextY); + dY = nextY - prevY; + high=nextX; + lr2=(0.5f + high)/2.f;//optimize use of gamut in high light..one can optimize more using directly high ? + //lr2=high; + } + } + + if (!ptNum) { + Color::hsv2rgb(float(prevY), satur, lr1, r, g, b); + Color::rgbxyz(r, g, b, xx, yy, zz, xyz_rgb); + lut1[i] = xx; + lut2[i] = yy; + lut3[i] = zz; + } + else if (ptNum >= nPoints) { + Color::hsv2rgb(float(nextY), satur, lr2, r, g, b); + Color::rgbxyz(r, g, b, xx, yy, zz, xyz_rgb); + lut1[i] = xx; + lut2[i] = yy; + lut3[i] = zz; + } + else { + double currY = pCurve->getVal(x) - prevY; + if (dY > 0.000001 || dY < -0.000001) { + float r1, g1, b1, r2, g2, b2, ro, go, bo; + Color::hsv2rgb(float(prevY), satur, lr1, r1, g1, b1); + Color::hsv2rgb(float(nextY), satur, lr2, r2, g2, b2); + bool chr = false; + bool lum = true; + LUTf dum; + float X1,X2,Y1,Y2,Z1,Z2,L1,a_1,b_1,c1,h1; + Color::rgbxyz(r2, g2, b2, X2, Y2, Z2, xyz_rgb); + Color::rgbxyz(r1, g1, b1, X1, Y1, Z1, xyz_rgb); + //I use XYZ to mix color 1 and 2 rather than rgb (gamut) and rather than Lab artifacts + X1 = X1 + (X2-X1)*currY/dY; if(X1<0.f) X1=0.f;//negative value not good + Y1 = Y1 + (Y2-Y1)*currY/dY; if(Y1<0.f) Y1=0.f; + Z1 = Z1 + (Z2-Z1)*currY/dY; if(Z1<0.f) Z1=0.f; + Color::XYZ2Lab(X1, Y1, Z1, L1, a_1, b_1);//prepare to gamut control + Color::Lab2Lch(a_1, b_1, c1, h1); + float Lr=L1/327.68f; + float RR,GG,BB; + #ifndef NDEBUG + bool neg=false; + bool more_rgb=false; + //gamut control : Lab values are in gamut + Color::gamutLchonly(h1,Lr,c1, RR, GG, BB, xyz_rgb, false, 0.15f, 0.96f, neg, more_rgb); + #else + Color::gamutLchonly(h1,Lr,c1, RR, GG, BB, xyz_rgb, false, 0.15f, 0.96f); + #endif + L1=Lr*327.68f; + float a,b,X,Y,Z; + // converting back to rgb + Color::Lch2Lab(c1, h1, a, b); + Color::Lab2XYZ(L1, a, b, X, Y, Z); + lut1[i] = X; + lut2[i] = Y; + lut3[i] = Z; + } + else { + Color::hsv2rgb(float(nextY), satur, lumin, r, g, b); + Color::rgbxyz(r, g, b, xx, yy, zz, xyz_rgb); + lut1[i] = xx; + lut2[i] = yy; + lut3[i] = zz; + } + } + } + /* + #ifndef NDEBUG + lutRed.dump("red"); + lutGreen.dump("green"); + lutBlue.dump("blue"); + #endif + */ +} + +void ColorGradientCurve::SetXYZ(const std::vector &curvePoints, const double xyz_rgb[3][3], const double rgb_xyz[3][3], float satur, float lumin) { + FlatCurve* tcurve = NULL; + + if (!curvePoints.empty() && curvePoints[0]>FCT_Linear && curvePoints[0]isIdentity()) { + lut1.reset(); + lut2.reset(); + lut3.reset(); + return; + } + if (!lut1) { + lut1(501); + lut2(501); + lut3(501); + } + + float r, g, b; + + int upperBound = lut1.getUpperBound(); + + int nPoints = pCurve->getSize(); + int ptNum = 0; + double nextX, nextY; + pCurve->getControlPoint(ptNum, nextX, nextY); + double prevY = nextY; + double dY = 0.; + Color::eInterpolationDirection dir = Color::ID_DOWN; + for (int i=0; i<=upperBound; ++i) { + double x = double(i)/double(upperBound); + + if (x > nextX) { + ++ptNum; + if (ptNum < nPoints) { + prevY = nextY; + pCurve->getControlPoint(ptNum, nextX, nextY); + dY = nextY - prevY; + dir = Color::getHueInterpolationDirection(prevY, nextY, Color::IP_SHORTEST); + } + } + + if (!ptNum) { + Color::hsv2rgb(float(prevY), 1.f, 1.f, r, g, b); + lut1[i] = r; + lut2[i] = g; + lut3[i] = b; + } + else if (ptNum >= nPoints) { + Color::hsv2rgb(float(nextY), 1.f, 1.f, r, g, b); + lut1[i] = r; + lut2[i] = g; + lut3[i] = b; + } + else { + double currY = pCurve->getVal(x) - prevY; + if (dY > 0.0000001 || dY < -0.0000001) { + #if 1 + float ro, go, bo; + double h2 = Color::interpolateHueHSV(prevY, nextY, currY/dY, dir); + Color::hsv2rgb(h2, 1.f, 1.f, ro, go, bo); + #else + float r1, g1, b1, r2, g2, b2, ro, go, bo; + Color::hsv2rgb(float(prevY), 1., 1., r1, g1, b1); + Color::hsv2rgb(float(nextY), 1., 1., r2, g2, b2); + Color::interpolateRGBColor(currY/dY, r1, g1, b1, r2, g2, b2, Color::CHANNEL_LIGHTNESS|Color::CHANNEL_CHROMATICITY|Color::CHANNEL_HUE, xyz_rgb, rgb_xyz, ro, go, bo); + #endif + lut1[i] = ro; + lut2[i] = go; + lut3[i] = bo; + } + else { + Color::hsv2rgb(float(nextY), 1.f, 1.f, r, g, b); + lut1[i] = r; + lut2[i] = g; + lut3[i] = b; + } + } + } + /* + #ifndef NDEBUG + lut1.dump("red"); + lut2.dump("green"); + lut3.dump("blue"); + #endif + */ +} + +void ColorGradientCurve::SetRGB(const std::vector &curvePoints, const double xyz_rgb[3][3], const double rgb_xyz[3][3]) { + FlatCurve* tcurve = NULL; + + if (!curvePoints.empty() && curvePoints[0]>FCT_Linear && curvePoints[0] + * + * 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 __CURVES_H__ +#define __CURVES_H__ + +#include +#include +#include +#include "rt_math.h" +#include "../rtgui/mycurve.h" +#include "../rtgui/myflatcurve.h" +#include "../rtgui/mydiagonalcurve.h" +#include "color.h" +#include "procparams.h" +#include "editbuffer.h" + +#include "LUT.h" + +#define CURVES_MIN_POLY_POINTS 1000 + +#include "rt_math.h" + +#define CLIPI(a) ((a)>0?((a)<65534?(a):65534):0) + +using namespace std; + +namespace rtengine { + class ToneCurve; + class ColorAppearance; + +class CurveFactory { + + friend class Curve; + + protected: + + // functions calculating the parameters of the contrast curve based on the desired slope at the center + static double solve_upper (double m, double c, double deriv); + static double solve_lower (double m, double c, double deriv); + static double dupper (const double b, const double m, const double c); + static double dlower (const double b, const double m, const double c); + + // basic convex function between (0,0) and (1,1). m1 and m2 controls the slope at the start and end point + static inline double basel (double x, double m1, double m2) { + if (x==0.0) + return 0.0; + double k = sqrt ((m1-1.0)*(m1-m2)*0.5) / (1.0-m2); + double l = (m1-m2) / (1.0-m2) + k; + double lx = xlog(x); + return m2*x + (1.0-m2)*(2.0 - xexp(k*lx))*xexp(l*lx); + } + // basic concave function between (0,0) and (1,1). m1 and m2 controls the slope at the start and end point + static inline double baseu (double x, double m1, double m2) { + return 1.0 - basel(1.0-x, m1, m2); + } + // convex curve between (0,0) and (1,1) with slope m at (0,0). hr controls the highlight recovery + static inline double cupper (double x, double m, double hr) { + if (hr>1.0) + return baseu (x, m, 2.0*(hr-1.0)/m); + double x1 = (1.0-hr)/m; + double x2 = x1 + hr; + if (x>=x2) return 1.0; + if (x=x2) return 1.0; + if (xx1 || sr<0.001) + return 1-(1-x)*m; + else + { + double y1 = 1-(1-x1)*m; + return y1+m*(x-x1)-(1-m)*SQR(SQR(1-x/x1)); + } + } + // tone curve base. a: slope (from exp.comp.), b: black point normalized by 65535, + // D: max. x value (can be>1), hr,sr: highlight,shadow recovery + static inline double basecurve (double x, double a, double b, double D, double hr, double sr) { + if (b<0) { + double m = 0.5;//midpoint + double slope = 1.0+b;//slope of straight line between (0,-b) and (1,1) + double y = -b+m*slope;//value at midpoint + if (x>m) + return y + (x - m)*slope;//value on straight line between (m,y) and (1,1) + else + return y*clower2(x/m, slope*m/y, 2.0-sr); + } else { + double slope = a/(1.0-b); + double m = a*D>1.0 ? b/a+(0.25)/slope : b+(1-b)/4; + double y = a*D>1.0 ? 0.25 : (m-b/a)*slope; + if (x<=m) + return b==0 ? x*slope : clower (x/m, slope*m/y, sr) * y; + else if (a*D>1.0) + return y+(1.0-y)*cupper2((x-m)/(D-m), slope*(D-m)/(1.0-y), hr); + else + return y+(x-m)*slope; + } + } + static inline double simplebasecurve (double x, double b, double sr) { + // a = 1, D = 1, hr = 0 (unused for a = D = 1) + if (b<0) { + double m = 0.5;//midpoint + double slope = 1.0+b;//slope of straight line between (0,-b) and (1,1) + double y = -b+m*slope;//value at midpoint + if (x>m) + return y + (x - m)*slope;//value on straight line between (m,y) and (1,1) + else + return y*clower2(x/m, slope*m/y, 2.0-sr); + } else { + double slope = 1.0/(1.0-b); + double m = b+(1-b)*0.25; + double y = (m-b)*slope; + if (x<=m) + return b==0 ? x*slope : clower (x/m, slope*m/y, sr) * y; + else + return y+(x-m)*slope; + } + } + + + public: + const static double sRGBGamma; // standard average gamma + const static double sRGBGammaCurve; // 2.4 in the curve + + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // accurately determine value from integer array with float as index + //linearly interpolate from ends of range if arg is out of bounds + static inline float interp(int *array,float f) + { + int index = CLIPI(floor(f)); + float part = (float)((f)-index)*(float)(array[index+1]-array[index]); + return (float)array[index]+part; + } + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // accurately determine value from float array with float as index + //linearly interpolate from ends of range if arg is out of bounds + static inline float flinterp(float *array,float f) + { + int index = CLIPI(floor(f)); + float part = ((f)-(float)index)*(array[index+1]-array[index]); + return array[index]+part; + } + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + static inline double centercontrast (double x, double b, double m); + + // standard srgb gamma and its inverse + static inline double gamma2 (double x) { + return x <= 0.00304 ? x*12.92 : 1.055*exp(log(x)/sRGBGammaCurve)-0.055; + } + static inline double igamma2 (double x) { + return x <= 0.03928 ? x/12.92 : exp(log((x+0.055)/1.055)*sRGBGammaCurve); + } + // gamma function with adjustable parameters + static inline double gamma (double x, double gamma, double start, double slope, double mul, double add){ + return (x <= start ? x*slope : exp(log(x)/gamma)*mul-add); + } + static inline double igamma (double x, double gamma, double start, double slope, double mul, double add){ + return (x <= start*slope ? x/slope : exp(log((x+add)/mul)*gamma) ); + } + + static inline float hlcurve (const float exp_scale, const float comp, const float hlrange, float level) + { + if (comp>0.0) { + float val = level+(hlrange-65536.0); + if(val == 0.0f) // to avoid division by zero + val = 0.000001f; + float Y = val*exp_scale/hlrange; + Y *= comp; + if(Y <= -1.0) // to avoid log(<=0) + Y = -.999999f; + float R = hlrange/(val*comp); + return log(1.0+Y)*R; + } else { + return exp_scale; + } + } + + public: + static void complexCurve (double ecomp, double black, double hlcompr, double hlcomprthresh, double shcompr, double br, double contr, + double gamma_, bool igamma_, procparams::ToneCurveParams::eTCModeId curveMode, const std::vector& curvePoints, procparams::ToneCurveParams::eTCModeId curveMode2, const std::vector& curvePoints2, + + LUTu & histogram, LUTu & histogramCropped, + LUTf & hlCurve, LUTf & shCurve,LUTf & outCurve, LUTu & outBeforeCCurveHistogram, ToneCurve & outToneCurve, ToneCurve & outToneCurve2, + + int skip=1); + static void curveBW (const std::vector& curvePointsbw, const std::vector& curvePointsbw2, LUTu & histogrambw, LUTu & outBeforeCCurveHistogrambw, + ToneCurve & customToneCurvebw1, ToneCurve & customToneCurvebw2, int skip); + + static void curveCL ( bool & clcutili, const std::vector& clcurvePoints, LUTf & clCurve, LUTu & histogramcl, LUTu & outBeforeCLurveHistogram, int skip); + + static void curveWavContL ( bool & wavcontlutili,const std::vector& wavclcurvePoints, LUTf & wavclCurve,/* LUTu & histogramwavcl, LUTu & outBeforeWavCLurveHistogram,*/int skip); + + static void curveToningCL ( bool & clctoningutili, const std::vector& clcurvePoints, LUTf & clToningCurve, int skip); + static void curveToningLL ( bool & llctoningutili, const std::vector& llcurvePoints, LUTf & llToningCurve, int skip); + static void denoiseCC ( bool & ccdenoiseutili, const std::vector& cccurvePoints, LUTf & NoiseCCcurve,int skip); + + static void complexsgnCurve ( float adjustr, bool & autili, bool & butili, bool & ccutili, bool & clcutili, double saturation, double rstprotection, const std::vector& acurvePoints, + const std::vector& bcurvePoints,const std::vector& cccurvePoints,const std::vector& lccurvePoints, LUTf & aoutCurve, LUTf & boutCurve, LUTf & satCurve, LUTf & lhskCurve, + LUTu & histogramC, LUTu & histogramLC, LUTu & outBeforeCCurveHistogram,LUTu & outBeforeLCurveHistogram,///for chroma + int skip=1); + static void complexLCurve (double br, double contr, const std::vector& curvePoints, LUTu & histogram, LUTu & histogramCropped, + LUTf & outCurve, LUTu & outBeforeCCurveHistogram, int skip, bool & utili); + + static void updatechroma ( + const std::vector& cccurvePoints, + LUTu & histogramC, LUTu & outBeforeCCurveHistogramC,//for chroma + int skip=1); + + static void curveLightBrightColor ( + procparams::ColorAppearanceParams::eTCModeId curveMode, const std::vector& curvePoints, + procparams::ColorAppearanceParams::eTCModeId curveMode2, const std::vector& curvePoints2, + procparams::ColorAppearanceParams::eCTCModeId curveMode3, const std::vector& curvePoints3, + LUTu & histogram, LUTu & histogramCropped, LUTu & outBeforeCCurveHistogram, + LUTu & histogramC, LUTu & outBeforeCCurveHistogramC, + ColorAppearance & outColCurve1, + ColorAppearance & outColCurve2, + ColorAppearance & outColCurve3, + int skip=1); + static void RGBCurve (const std::vector& curvePoints, LUTf & outCurve, int skip); + +}; + +class Curve { + + class HashEntry { + public: + unsigned short smallerValue; + unsigned short higherValue; + }; + protected: + int N; + int ppn; // targeted polyline point number + double* x; + double* y; + // begin of variables used in Parametric curves only + double mc; + double mfc; + double msc; + double mhc; + // end of variables used in Parametric curves only + std::vector poly_x; // X points of the faceted curve + std::vector poly_y; // Y points of the faceted curve + std::vector hash; + unsigned short hashSize; // hash table's size, between [10, 100, 1000] + + double* ypp; + + // Fields for the elementary curve polygonisation + double x1, y1, x2, y2, x3, y3; + bool firstPointIncluded; + double increment; + int nbr_points; + + static inline double p00 (double x, double prot) { return CurveFactory::clower (x, 2.0, prot); } + static inline double p11 (double x, double prot) { return CurveFactory::cupper (x, 2.0, prot); } + static inline double p01 (double x, double prot) { return x<=0.5 ? CurveFactory::clower (x*2, 2.0, prot)/2.0 : 0.5 + CurveFactory::cupper ((x-0.5)*2, 2.0, prot)/2.0; } + static inline double p10 (double x, double prot) { return x<=0.5 ? CurveFactory::cupper (x*2, 2.0, prot)/2.0 : 0.5 + CurveFactory::clower ((x-0.5)*2, 2.0, prot)/2.0; } + static inline double pfull (double x, double prot, double sh, double hl) { return (1-sh)*(1-hl)*p00(x,prot) + sh*hl*p11(x,prot) + (1-sh)*hl*p01(x,prot) + sh*(1-hl)*p10(x,prot); } + + void fillHash(); + + public: + Curve (); + virtual ~Curve () {}; + void AddPolygons (); + int getSize () const; // return the number of control points + void getControlPoint(int cpNum, double &x, double &y) const; + virtual double getVal (double t) const = 0; + virtual void getVal (const std::vector& t, std::vector& res) const = 0; + + virtual bool isIdentity () const = 0; +}; + +class DiagonalCurve : public Curve { + + protected: + DiagonalCurveType kind; + + void spline_cubic_set (); + void NURBS_set (); + + public: + DiagonalCurve (const std::vector& points, int ppn=CURVES_MIN_POLY_POINTS); + virtual ~DiagonalCurve (); + + double getVal (double t) const; + void getVal (const std::vector& t, std::vector& res) const; + bool isIdentity () const { return kind==DCT_Empty; }; +}; + +class FlatCurve : public Curve { + + protected: + FlatCurveType kind; + double* leftTangent; + double* rightTangent; + double identityValue; + bool periodic; + + void CtrlPoints_set (); + + public: + + FlatCurve (const std::vector& points, bool isPeriodic = true, int ppn=CURVES_MIN_POLY_POINTS); + virtual ~FlatCurve (); + + double getVal (double t) const; + void getVal (const std::vector& t, std::vector& res) const; + bool setIdentityValue (double iVal); + bool isIdentity () const { return kind==FCT_Empty; }; +}; + +class ToneCurve { + public: + LUTf lutToneCurve; // 0xffff range + + virtual ~ToneCurve() {}; + + void Reset(); + void Set(Curve *pCurve); + operator bool (void) const { return lutToneCurve; } +}; + +class OpacityCurve { + public: + LUTf lutOpacityCurve; // 0xffff range + + virtual ~OpacityCurve() {}; + + void Reset(); + void Set(const Curve *pCurve); + void Set(const std::vector &curvePoints, bool &opautili); + + // TODO: transfer this method to the Color class... + float blend (float x, float lower, float upper) const { + return (upper-lower)*lutOpacityCurve[x*500.f] + lower; + } + void blend3f (float x, float lower1, float upper1, float &result1, float lower2, float upper2, float &result2, float lower3, float upper3, float &result3) const { + float opacity = lutOpacityCurve[x*500.f]; + result1 = (upper1-lower1)*opacity + lower1; + result2 = (upper2-lower2)*opacity + lower2; + result3 = (upper3-lower3)*opacity + lower3; + } + + operator bool (void) const { return lutOpacityCurve; } +}; + +class WavCurve { + private: + LUTf lutWavCurve; // 0xffff range + void Set(const Curve &pCurve); + + public: + float sum; + + virtual ~WavCurve() {}; + WavCurve(); + void Reset(); + void Set(const std::vector &curvePoints); + float getSum() const {return sum;} + + float operator[](float index) const { return lutWavCurve[index]; } + operator bool (void) const { return lutWavCurve; } +}; + +class WavOpacityCurveRG { + private: + LUTf lutOpacityCurveRG; // 0xffff range + void Set(const Curve &pCurve); + public: + virtual ~WavOpacityCurveRG() {}; + WavOpacityCurveRG(); + + void Reset(); + // void Set(const std::vector &curvePoints, bool &opautili); + void Set(const std::vector &curvePoints); + float operator[](float index) const { return lutOpacityCurveRG[index]; } + + operator bool (void) const { return lutOpacityCurveRG; } +}; +class WavOpacityCurveBY { + private: + LUTf lutOpacityCurveBY; // 0xffff range + void Set(const Curve &pCurve); + + public: + virtual ~WavOpacityCurveBY() {}; + WavOpacityCurveBY(); + + void Reset(); + void Set(const Curve *pCurve); + void Set(const std::vector &curvePoints); + float operator[](float index) const { return lutOpacityCurveBY[index]; } + + operator bool (void) const { return lutOpacityCurveBY; } +}; +class WavOpacityCurveW { + private: + LUTf lutOpacityCurveW; // 0xffff range + void Set(const Curve &pCurve); + + public: + virtual ~WavOpacityCurveW() {}; + WavOpacityCurveW(); + + void Reset(); + void Set(const Curve *pCurve); + void Set(const std::vector &curvePoints); + float operator[](float index) const { return lutOpacityCurveW[index]; } + + operator bool (void) const { return lutOpacityCurveW; } +}; + +class WavOpacityCurveWL { + private: + LUTf lutOpacityCurveWL; // 0xffff range + void Set(const Curve &pCurve); + + public: + virtual ~WavOpacityCurveWL() {}; + WavOpacityCurveWL(); + + void Reset(); + void Set(const Curve *pCurve); + void Set(const std::vector &curvePoints); + float operator[](float index) const { return lutOpacityCurveWL[index]; } + + operator bool (void) const { return lutOpacityCurveWL; } +}; + +class NoiseCurve { + private: + LUTf lutNoiseCurve; // 0xffff range + float sum; + void Set(const Curve &pCurve); + + public: + virtual ~NoiseCurve() {}; + NoiseCurve(); + void Reset(); + void Set(const std::vector &curvePoints); + + float getSum() const {return sum;} + float operator[](float index) const { return lutNoiseCurve[index]; } + operator bool (void) const { return lutNoiseCurve; } +}; + +class ColorGradientCurve { + public: + LUTf lut1; // [0.;1.] range (float values) + LUTf lut2; // [0.;1.] range (float values) + LUTf lut3; // [0.;1.] range (float values) + double low; + double high; + + 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]); + + /** + * @brief Get the value of Red, Green and Blue corresponding to the requested index + * @param index value in the [0 ; 1] range + * @param r corresponding red value [0 ; 65535] (return value) + * @param g corresponding green value [0 ; 65535] (return value) + * @param b corresponding blue value [0 ; 65535] (return value) + */ + void getVal(float index, float &r, float &g, float &b) const; + operator bool (void) const { return lut1 && lut2 && lut3; } +}; + +class ColorAppearance { + public: + LUTf lutColCurve; // 0xffff range + + virtual ~ColorAppearance() {}; + + void Reset(); + void Set(Curve *pCurve); + operator bool (void) const { return lutColCurve; } +}; + +class Lightcurve : public ColorAppearance { + public: + void Apply(float& Li) const; +}; + +//lightness curve +inline void Lightcurve::Apply (float& Li) const { + + assert (lutColCurve); + + Li = lutColCurve[Li]; +} + +class Brightcurve : public ColorAppearance { + public: + void Apply(float& Br) const; +}; + +//brightness curve +inline void Brightcurve::Apply (float& Br) const { + + assert (lutColCurve); + + Br = lutColCurve[Br]; +} + +class Chromacurve : public ColorAppearance { + public: + void Apply(float& Cr) const; +}; + +//Chroma curve +inline void Chromacurve::Apply (float& Cr) const { + + assert (lutColCurve); + + Cr = lutColCurve[Cr]; +} +class Saturcurve : public ColorAppearance { + public: + void Apply(float& Sa) const; +}; + +//Saturation curve +inline void Saturcurve::Apply (float& Sa) const { + + assert (lutColCurve); + + Sa = lutColCurve[Sa]; +} + +class Colorfcurve : public ColorAppearance { + public: + void Apply(float& Cf) const; +}; + +//Colorfullness curve +inline void Colorfcurve::Apply (float& Cf) const { + + assert (lutColCurve); + + Cf = lutColCurve[Cf]; +} + + +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 { + 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 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: + float Triangle(float refX, float refY, float X2) const; + public: + void Apply(float& r, float& g, float& b) const; +}; + +class LuminanceToneCurve : public ToneCurve { + public: + void Apply(float& r, float& g, float& b) 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 { + + assert (lutToneCurve); + + r = lutToneCurve[r]; + 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 +// inlined to make sure there will be no cache flush when used +inline void AdobeToneCurve::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 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 { + float rold=r,gold=g,bold=b; + + r = lutToneCurve[rold]; + 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 { + assert (lutToneCurve); + + float currLuminance = r*0.2126729f + g*0.7151521f + b*0.0721750f; + float newLuminance = lutToneCurve[currLuminance]; + float coef = newLuminance/currLuminance; + r = LIM(r*coef, 0.f, 65535.f); + g = LIM(g*coef, 0.f, 65535.f); + b = LIM(b*coef, 0.f, 65535.f); +} + +inline float WeightedStdToneCurve::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; +} +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 +inline void WeightedStdToneCurve::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); +} + +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 { + + 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); + } +} + +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); + } +} + +} + +#undef CLIPI + +#endif diff --git a/rtengine/dcp.cc b/rtengine/dcp.cc new file mode 100644 index 000000000..3afca58db --- /dev/null +++ b/rtengine/dcp.cc @@ -0,0 +1,1595 @@ +/* +* This file is part of RawTherapee. +* +* Copyright (c) 2012 Oliver Duis +* +* 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 "dcp.h" +#include "safegtk.h" +#include "iccmatrices.h" +#include "iccstore.h" +#include "rawimagesource.h" +#include "improcfun.h" +#include "rt_math.h" + +using namespace std; +using namespace rtengine; +using namespace rtexif; + +static const float adobe_camera_raw_default_curve[] = { + 0.00000f, 0.00078f, 0.00160f, 0.00242f, + 0.00314f, 0.00385f, 0.00460f, 0.00539f, + 0.00623f, 0.00712f, 0.00806f, 0.00906f, + 0.01012f, 0.01122f, 0.01238f, 0.01359f, + 0.01485f, 0.01616f, 0.01751f, 0.01890f, + 0.02033f, 0.02180f, 0.02331f, 0.02485f, + 0.02643f, 0.02804f, 0.02967f, 0.03134f, + 0.03303f, 0.03475f, 0.03648f, 0.03824f, + 0.04002f, 0.04181f, 0.04362f, 0.04545f, + 0.04730f, 0.04916f, 0.05103f, 0.05292f, + 0.05483f, 0.05675f, 0.05868f, 0.06063f, + 0.06259f, 0.06457f, 0.06655f, 0.06856f, + 0.07057f, 0.07259f, 0.07463f, 0.07668f, + 0.07874f, 0.08081f, 0.08290f, 0.08499f, + 0.08710f, 0.08921f, 0.09134f, 0.09348f, + 0.09563f, 0.09779f, 0.09996f, 0.10214f, + 0.10433f, 0.10652f, 0.10873f, 0.11095f, + 0.11318f, 0.11541f, 0.11766f, 0.11991f, + 0.12218f, 0.12445f, 0.12673f, 0.12902f, + 0.13132f, 0.13363f, 0.13595f, 0.13827f, + 0.14061f, 0.14295f, 0.14530f, 0.14765f, + 0.15002f, 0.15239f, 0.15477f, 0.15716f, + 0.15956f, 0.16197f, 0.16438f, 0.16680f, + 0.16923f, 0.17166f, 0.17410f, 0.17655f, + 0.17901f, 0.18148f, 0.18395f, 0.18643f, + 0.18891f, 0.19141f, 0.19391f, 0.19641f, + 0.19893f, 0.20145f, 0.20398f, 0.20651f, + 0.20905f, 0.21160f, 0.21416f, 0.21672f, + 0.21929f, 0.22185f, 0.22440f, 0.22696f, + 0.22950f, 0.23204f, 0.23458f, 0.23711f, + 0.23963f, 0.24215f, 0.24466f, 0.24717f, + 0.24967f, 0.25216f, 0.25465f, 0.25713f, + 0.25961f, 0.26208f, 0.26454f, 0.26700f, + 0.26945f, 0.27189f, 0.27433f, 0.27676f, + 0.27918f, 0.28160f, 0.28401f, 0.28641f, + 0.28881f, 0.29120f, 0.29358f, 0.29596f, + 0.29833f, 0.30069f, 0.30305f, 0.30540f, + 0.30774f, 0.31008f, 0.31241f, 0.31473f, + 0.31704f, 0.31935f, 0.32165f, 0.32395f, + 0.32623f, 0.32851f, 0.33079f, 0.33305f, + 0.33531f, 0.33756f, 0.33981f, 0.34205f, + 0.34428f, 0.34650f, 0.34872f, 0.35093f, + 0.35313f, 0.35532f, 0.35751f, 0.35969f, + 0.36187f, 0.36404f, 0.36620f, 0.36835f, + 0.37050f, 0.37264f, 0.37477f, 0.37689f, + 0.37901f, 0.38112f, 0.38323f, 0.38533f, + 0.38742f, 0.38950f, 0.39158f, 0.39365f, + 0.39571f, 0.39777f, 0.39982f, 0.40186f, + 0.40389f, 0.40592f, 0.40794f, 0.40996f, + 0.41197f, 0.41397f, 0.41596f, 0.41795f, + 0.41993f, 0.42191f, 0.42388f, 0.42584f, + 0.42779f, 0.42974f, 0.43168f, 0.43362f, + 0.43554f, 0.43747f, 0.43938f, 0.44129f, + 0.44319f, 0.44509f, 0.44698f, 0.44886f, + 0.45073f, 0.45260f, 0.45447f, 0.45632f, + 0.45817f, 0.46002f, 0.46186f, 0.46369f, + 0.46551f, 0.46733f, 0.46914f, 0.47095f, + 0.47275f, 0.47454f, 0.47633f, 0.47811f, + 0.47989f, 0.48166f, 0.48342f, 0.48518f, + 0.48693f, 0.48867f, 0.49041f, 0.49214f, + 0.49387f, 0.49559f, 0.49730f, 0.49901f, + 0.50072f, 0.50241f, 0.50410f, 0.50579f, + 0.50747f, 0.50914f, 0.51081f, 0.51247f, + 0.51413f, 0.51578f, 0.51742f, 0.51906f, + 0.52069f, 0.52232f, 0.52394f, 0.52556f, + 0.52717f, 0.52878f, 0.53038f, 0.53197f, + 0.53356f, 0.53514f, 0.53672f, 0.53829f, + 0.53986f, 0.54142f, 0.54297f, 0.54452f, + 0.54607f, 0.54761f, 0.54914f, 0.55067f, + 0.55220f, 0.55371f, 0.55523f, 0.55673f, + 0.55824f, 0.55973f, 0.56123f, 0.56271f, + 0.56420f, 0.56567f, 0.56715f, 0.56861f, + 0.57007f, 0.57153f, 0.57298f, 0.57443f, + 0.57587f, 0.57731f, 0.57874f, 0.58017f, + 0.58159f, 0.58301f, 0.58443f, 0.58583f, + 0.58724f, 0.58864f, 0.59003f, 0.59142f, + 0.59281f, 0.59419f, 0.59556f, 0.59694f, + 0.59830f, 0.59966f, 0.60102f, 0.60238f, + 0.60373f, 0.60507f, 0.60641f, 0.60775f, + 0.60908f, 0.61040f, 0.61173f, 0.61305f, + 0.61436f, 0.61567f, 0.61698f, 0.61828f, + 0.61957f, 0.62087f, 0.62216f, 0.62344f, + 0.62472f, 0.62600f, 0.62727f, 0.62854f, + 0.62980f, 0.63106f, 0.63232f, 0.63357f, + 0.63482f, 0.63606f, 0.63730f, 0.63854f, + 0.63977f, 0.64100f, 0.64222f, 0.64344f, + 0.64466f, 0.64587f, 0.64708f, 0.64829f, + 0.64949f, 0.65069f, 0.65188f, 0.65307f, + 0.65426f, 0.65544f, 0.65662f, 0.65779f, + 0.65897f, 0.66013f, 0.66130f, 0.66246f, + 0.66362f, 0.66477f, 0.66592f, 0.66707f, + 0.66821f, 0.66935f, 0.67048f, 0.67162f, + 0.67275f, 0.67387f, 0.67499f, 0.67611f, + 0.67723f, 0.67834f, 0.67945f, 0.68055f, + 0.68165f, 0.68275f, 0.68385f, 0.68494f, + 0.68603f, 0.68711f, 0.68819f, 0.68927f, + 0.69035f, 0.69142f, 0.69249f, 0.69355f, + 0.69461f, 0.69567f, 0.69673f, 0.69778f, + 0.69883f, 0.69988f, 0.70092f, 0.70196f, + 0.70300f, 0.70403f, 0.70506f, 0.70609f, + 0.70711f, 0.70813f, 0.70915f, 0.71017f, + 0.71118f, 0.71219f, 0.71319f, 0.71420f, + 0.71520f, 0.71620f, 0.71719f, 0.71818f, + 0.71917f, 0.72016f, 0.72114f, 0.72212f, + 0.72309f, 0.72407f, 0.72504f, 0.72601f, + 0.72697f, 0.72794f, 0.72890f, 0.72985f, + 0.73081f, 0.73176f, 0.73271f, 0.73365f, + 0.73460f, 0.73554f, 0.73647f, 0.73741f, + 0.73834f, 0.73927f, 0.74020f, 0.74112f, + 0.74204f, 0.74296f, 0.74388f, 0.74479f, + 0.74570f, 0.74661f, 0.74751f, 0.74842f, + 0.74932f, 0.75021f, 0.75111f, 0.75200f, + 0.75289f, 0.75378f, 0.75466f, 0.75555f, + 0.75643f, 0.75730f, 0.75818f, 0.75905f, + 0.75992f, 0.76079f, 0.76165f, 0.76251f, + 0.76337f, 0.76423f, 0.76508f, 0.76594f, + 0.76679f, 0.76763f, 0.76848f, 0.76932f, + 0.77016f, 0.77100f, 0.77183f, 0.77267f, + 0.77350f, 0.77432f, 0.77515f, 0.77597f, + 0.77680f, 0.77761f, 0.77843f, 0.77924f, + 0.78006f, 0.78087f, 0.78167f, 0.78248f, + 0.78328f, 0.78408f, 0.78488f, 0.78568f, + 0.78647f, 0.78726f, 0.78805f, 0.78884f, + 0.78962f, 0.79040f, 0.79118f, 0.79196f, + 0.79274f, 0.79351f, 0.79428f, 0.79505f, + 0.79582f, 0.79658f, 0.79735f, 0.79811f, + 0.79887f, 0.79962f, 0.80038f, 0.80113f, + 0.80188f, 0.80263f, 0.80337f, 0.80412f, + 0.80486f, 0.80560f, 0.80634f, 0.80707f, + 0.80780f, 0.80854f, 0.80926f, 0.80999f, + 0.81072f, 0.81144f, 0.81216f, 0.81288f, + 0.81360f, 0.81431f, 0.81503f, 0.81574f, + 0.81645f, 0.81715f, 0.81786f, 0.81856f, + 0.81926f, 0.81996f, 0.82066f, 0.82135f, + 0.82205f, 0.82274f, 0.82343f, 0.82412f, + 0.82480f, 0.82549f, 0.82617f, 0.82685f, + 0.82753f, 0.82820f, 0.82888f, 0.82955f, + 0.83022f, 0.83089f, 0.83155f, 0.83222f, + 0.83288f, 0.83354f, 0.83420f, 0.83486f, + 0.83552f, 0.83617f, 0.83682f, 0.83747f, + 0.83812f, 0.83877f, 0.83941f, 0.84005f, + 0.84069f, 0.84133f, 0.84197f, 0.84261f, + 0.84324f, 0.84387f, 0.84450f, 0.84513f, + 0.84576f, 0.84639f, 0.84701f, 0.84763f, + 0.84825f, 0.84887f, 0.84949f, 0.85010f, + 0.85071f, 0.85132f, 0.85193f, 0.85254f, + 0.85315f, 0.85375f, 0.85436f, 0.85496f, + 0.85556f, 0.85615f, 0.85675f, 0.85735f, + 0.85794f, 0.85853f, 0.85912f, 0.85971f, + 0.86029f, 0.86088f, 0.86146f, 0.86204f, + 0.86262f, 0.86320f, 0.86378f, 0.86435f, + 0.86493f, 0.86550f, 0.86607f, 0.86664f, + 0.86720f, 0.86777f, 0.86833f, 0.86889f, + 0.86945f, 0.87001f, 0.87057f, 0.87113f, + 0.87168f, 0.87223f, 0.87278f, 0.87333f, + 0.87388f, 0.87443f, 0.87497f, 0.87552f, + 0.87606f, 0.87660f, 0.87714f, 0.87768f, + 0.87821f, 0.87875f, 0.87928f, 0.87981f, + 0.88034f, 0.88087f, 0.88140f, 0.88192f, + 0.88244f, 0.88297f, 0.88349f, 0.88401f, + 0.88453f, 0.88504f, 0.88556f, 0.88607f, + 0.88658f, 0.88709f, 0.88760f, 0.88811f, + 0.88862f, 0.88912f, 0.88963f, 0.89013f, + 0.89063f, 0.89113f, 0.89163f, 0.89212f, + 0.89262f, 0.89311f, 0.89360f, 0.89409f, + 0.89458f, 0.89507f, 0.89556f, 0.89604f, + 0.89653f, 0.89701f, 0.89749f, 0.89797f, + 0.89845f, 0.89892f, 0.89940f, 0.89987f, + 0.90035f, 0.90082f, 0.90129f, 0.90176f, + 0.90222f, 0.90269f, 0.90316f, 0.90362f, + 0.90408f, 0.90454f, 0.90500f, 0.90546f, + 0.90592f, 0.90637f, 0.90683f, 0.90728f, + 0.90773f, 0.90818f, 0.90863f, 0.90908f, + 0.90952f, 0.90997f, 0.91041f, 0.91085f, + 0.91130f, 0.91173f, 0.91217f, 0.91261f, + 0.91305f, 0.91348f, 0.91392f, 0.91435f, + 0.91478f, 0.91521f, 0.91564f, 0.91606f, + 0.91649f, 0.91691f, 0.91734f, 0.91776f, + 0.91818f, 0.91860f, 0.91902f, 0.91944f, + 0.91985f, 0.92027f, 0.92068f, 0.92109f, + 0.92150f, 0.92191f, 0.92232f, 0.92273f, + 0.92314f, 0.92354f, 0.92395f, 0.92435f, + 0.92475f, 0.92515f, 0.92555f, 0.92595f, + 0.92634f, 0.92674f, 0.92713f, 0.92753f, + 0.92792f, 0.92831f, 0.92870f, 0.92909f, + 0.92947f, 0.92986f, 0.93025f, 0.93063f, + 0.93101f, 0.93139f, 0.93177f, 0.93215f, + 0.93253f, 0.93291f, 0.93328f, 0.93366f, + 0.93403f, 0.93440f, 0.93478f, 0.93515f, + 0.93551f, 0.93588f, 0.93625f, 0.93661f, + 0.93698f, 0.93734f, 0.93770f, 0.93807f, + 0.93843f, 0.93878f, 0.93914f, 0.93950f, + 0.93986f, 0.94021f, 0.94056f, 0.94092f, + 0.94127f, 0.94162f, 0.94197f, 0.94231f, + 0.94266f, 0.94301f, 0.94335f, 0.94369f, + 0.94404f, 0.94438f, 0.94472f, 0.94506f, + 0.94540f, 0.94573f, 0.94607f, 0.94641f, + 0.94674f, 0.94707f, 0.94740f, 0.94774f, + 0.94807f, 0.94839f, 0.94872f, 0.94905f, + 0.94937f, 0.94970f, 0.95002f, 0.95035f, + 0.95067f, 0.95099f, 0.95131f, 0.95163f, + 0.95194f, 0.95226f, 0.95257f, 0.95289f, + 0.95320f, 0.95351f, 0.95383f, 0.95414f, + 0.95445f, 0.95475f, 0.95506f, 0.95537f, + 0.95567f, 0.95598f, 0.95628f, 0.95658f, + 0.95688f, 0.95718f, 0.95748f, 0.95778f, + 0.95808f, 0.95838f, 0.95867f, 0.95897f, + 0.95926f, 0.95955f, 0.95984f, 0.96013f, + 0.96042f, 0.96071f, 0.96100f, 0.96129f, + 0.96157f, 0.96186f, 0.96214f, 0.96242f, + 0.96271f, 0.96299f, 0.96327f, 0.96355f, + 0.96382f, 0.96410f, 0.96438f, 0.96465f, + 0.96493f, 0.96520f, 0.96547f, 0.96574f, + 0.96602f, 0.96629f, 0.96655f, 0.96682f, + 0.96709f, 0.96735f, 0.96762f, 0.96788f, + 0.96815f, 0.96841f, 0.96867f, 0.96893f, + 0.96919f, 0.96945f, 0.96971f, 0.96996f, + 0.97022f, 0.97047f, 0.97073f, 0.97098f, + 0.97123f, 0.97149f, 0.97174f, 0.97199f, + 0.97223f, 0.97248f, 0.97273f, 0.97297f, + 0.97322f, 0.97346f, 0.97371f, 0.97395f, + 0.97419f, 0.97443f, 0.97467f, 0.97491f, + 0.97515f, 0.97539f, 0.97562f, 0.97586f, + 0.97609f, 0.97633f, 0.97656f, 0.97679f, + 0.97702f, 0.97725f, 0.97748f, 0.97771f, + 0.97794f, 0.97817f, 0.97839f, 0.97862f, + 0.97884f, 0.97907f, 0.97929f, 0.97951f, + 0.97973f, 0.97995f, 0.98017f, 0.98039f, + 0.98061f, 0.98082f, 0.98104f, 0.98125f, + 0.98147f, 0.98168f, 0.98189f, 0.98211f, + 0.98232f, 0.98253f, 0.98274f, 0.98295f, + 0.98315f, 0.98336f, 0.98357f, 0.98377f, + 0.98398f, 0.98418f, 0.98438f, 0.98458f, + 0.98478f, 0.98498f, 0.98518f, 0.98538f, + 0.98558f, 0.98578f, 0.98597f, 0.98617f, + 0.98636f, 0.98656f, 0.98675f, 0.98694f, + 0.98714f, 0.98733f, 0.98752f, 0.98771f, + 0.98789f, 0.98808f, 0.98827f, 0.98845f, + 0.98864f, 0.98882f, 0.98901f, 0.98919f, + 0.98937f, 0.98955f, 0.98973f, 0.98991f, + 0.99009f, 0.99027f, 0.99045f, 0.99063f, + 0.99080f, 0.99098f, 0.99115f, 0.99133f, + 0.99150f, 0.99167f, 0.99184f, 0.99201f, + 0.99218f, 0.99235f, 0.99252f, 0.99269f, + 0.99285f, 0.99302f, 0.99319f, 0.99335f, + 0.99351f, 0.99368f, 0.99384f, 0.99400f, + 0.99416f, 0.99432f, 0.99448f, 0.99464f, + 0.99480f, 0.99495f, 0.99511f, 0.99527f, + 0.99542f, 0.99558f, 0.99573f, 0.99588f, + 0.99603f, 0.99619f, 0.99634f, 0.99649f, + 0.99664f, 0.99678f, 0.99693f, 0.99708f, + 0.99722f, 0.99737f, 0.99751f, 0.99766f, + 0.99780f, 0.99794f, 0.99809f, 0.99823f, + 0.99837f, 0.99851f, 0.99865f, 0.99879f, + 0.99892f, 0.99906f, 0.99920f, 0.99933f, + 0.99947f, 0.99960f, 0.99974f, 0.99987f, + 1.00000f +}; + +// This sRGB gamma is taken from DNG reference code, with the added linear extension past 1.0, as we run clipless here +static float sRGBGammaForward (const float x) { + if (x <= 0.0031308) + return x * 12.92; + else if (x > 1.0) + return 1.0 + (x - 1.0) * (1.055*(1.0/2.4)); // linear extension + else + return 1.055 * pow (x, 1.0 / 2.4) - 0.055; +} +static float sRGBGammaInverse (const float y) { + if (y <= 0.0031308 * 12.92) + return y * (1.0 / 12.92); + else if (y > 1.0) + return 1.0 + (y - 1.0) / (1.055*(1.0/2.4)); + else + return pow ((y + 0.055) * (1.0 / 1.055), 2.4); +} + +static void Invert3x3(const double (*A)[3], double (*B)[3]) { + + double a00 = A[0][0]; + double a01 = A[0][1]; + double a02 = A[0][2]; + double a10 = A[1][0]; + double a11 = A[1][1]; + double a12 = A[1][2]; + double a20 = A[2][0]; + double a21 = A[2][1]; + double a22 = A[2][2]; + double temp [3][3]; + + temp[0][0] = a11 * a22 - a21 * a12; + temp[0][1] = a21 * a02 - a01 * a22; + temp[0][2] = a01 * a12 - a11 * a02; + temp[1][0] = a20 * a12 - a10 * a22; + temp[1][1] = a00 * a22 - a20 * a02; + temp[1][2] = a10 * a02 - a00 * a12; + temp[2][0] = a10 * a21 - a20 * a11; + temp[2][1] = a20 * a01 - a00 * a21; + temp[2][2] = a00 * a11 - a10 * a01; + + double det = a00 * temp[0][0] + a01 * temp[1][0] + a02 * temp[2][0]; + + if (fabs(det) < 1.0E-10) { + abort(); // can't be inverted, we shouldn't be dealing with such matrices + } + + for (int j = 0; j < 3; j++) { + for (int k = 0; k < 3; k++) { + B[j][k] = temp[j][k] / det; + } + } +} + +static void Multiply3x3(const double (*A)[3], const double (*B)[3], double (*C)[3]) { + + // use temp to support having output same as input + double M[3][3]; + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + M[i][j] = 0; + for (int k = 0; k < 3; k++) { + M[i][j] += A[i][k] * B[k][j]; + } + } + } + memcpy(C, M, 3 * 3 * sizeof(double)); +} + +static void Multiply3x3_v3(const double (*A)[3], const double B[3], double C[3]) { + + // use temp to support having output same as input + double M[3] = { 0, 0, 0 }; + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + M[i] += A[i][j] * B[j]; + } + } + memcpy(C, M, 3 * sizeof(double)); +} + +static void Mix3x3(const double (*A)[3], double mulA, const double (*B)[3], double mulB, double (*C)[3]) { + + double M[3][3]; + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + M[i][j] = A[i][j] * mulA + B[i][j] * mulB; + } + } + memcpy(C, M, 3 * 3 * sizeof(double)); +} + +static void MapWhiteMatrix(const double white1[3], const double white2[3], double (*B)[3]) { + + // code adapted from dng_color_spec::MapWhiteMatrix + + // Use the linearized Bradford adaptation matrix. + double Mb[3][3] = { { 0.8951, 0.2664, -0.1614 }, { -0.7502, 1.7135, 0.0367 }, { 0.0389, -0.0685, 1.0296 }}; + + double w1[3]; + Multiply3x3_v3(Mb, white1, w1); + double w2[3]; + Multiply3x3_v3(Mb, white2, w2); + + // Negative white coordinates are kind of meaningless. + w1[0] = std::max(w1[0], 0.0); + w1[1] = std::max(w1[1], 0.0); + w1[2] = std::max(w1[2], 0.0); + w2[0] = std::max(w2[0], 0.0); + w2[1] = std::max(w2[1], 0.0); + w2[2] = std::max(w2[2], 0.0); + + // Limit scaling to something reasonable. + double A[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + A[0][0] = std::max(0.1, std::min(w1[0] > 0.0 ? w2[0] / w1[0] : 10.0, 10.0)); + A[1][1] = std::max(0.1, std::min(w1[1] > 0.0 ? w2[1] / w1[1] : 10.0, 10.0)); + A[2][2] = std::max(0.1, std::min(w1[2] > 0.0 ? w2[2] / w1[2] : 10.0, 10.0)); + + double temp[3][3]; + Invert3x3(Mb, temp); + Multiply3x3(temp, A, temp); + Multiply3x3(temp, Mb, B); +} + +static void XYZtoXY(const double XYZ[3], double XY[2]) { + double X = XYZ[0]; + double Y = XYZ[1]; + double Z = XYZ[2]; + double total = X + Y + Z; + if (total > 0.0) { + XY[0] = X / total; + XY[1] = Y / total; + } else { + XY[0] = 0.3457; + XY[1] = 0.3585; + } +} + +static void XYtoXYZ(const double XY[2], double XYZ[3]) { + double temp[2] = { XY[0], XY[1] }; + // Restrict xy coord to someplace inside the range of real xy coordinates. + // This prevents math from doing strange things when users specify + // extreme temperature/tint coordinates. + temp[0] = std::max(0.000001, std::min(temp[0], 0.999999)); + temp[1] = std::max(0.000001, std::min(temp[1], 0.999999)); + if (temp[0] + temp[1] > 0.999999) { + double scale = 0.999999 / (temp[0] + temp[1]); + temp[0] *= scale; + temp[1] *= scale; + } + XYZ[0] = temp[0] / temp[1]; + XYZ[1] = 1.0; + XYZ[2] = (1.0 - temp[0] - temp[1]) / temp[1]; +} + +enum dngCalibrationIlluminant { + lsUnknown = 0, + lsDaylight = 1, + lsFluorescent = 2, + lsTungsten = 3, + lsFlash = 4, + lsFineWeather = 9, + lsCloudyWeather = 10, + lsShade = 11, + lsDaylightFluorescent = 12, // D 5700 - 7100K + lsDayWhiteFluorescent = 13, // N 4600 - 5500K + lsCoolWhiteFluorescent = 14, // W 3800 - 4500K + lsWhiteFluorescent = 15, // WW 3250 - 3800K + lsWarmWhiteFluorescent = 16, // L 2600 - 3250K + lsStandardLightA = 17, + lsStandardLightB = 18, + lsStandardLightC = 19, + lsD55 = 20, + lsD65 = 21, + lsD75 = 22, + lsD50 = 23, + lsISOStudioTungsten = 24, + lsOther = 255 +}; + +// should probably be moved to colortemp.cc +static double calibrationIlluminantToTemperature(int light) { + + // these temperatures are those found in DNG SDK reference code. + switch (light) { + case lsStandardLightA: + case lsTungsten: + return 2850.0; + case lsISOStudioTungsten: + return 3200.0; + case lsD50: + return 5000.0; + case lsD55: + case lsDaylight: + case lsFineWeather: + case lsFlash: + case lsStandardLightB: + return 5500.0; + case lsD65: + case lsStandardLightC: + case lsCloudyWeather: + return 6500.0; + case lsD75: + case lsShade: + return 7500.0; + case lsDaylightFluorescent: + return (5700.0 + 7100.0) * 0.5; + case lsDayWhiteFluorescent: + return (4600.0 + 5500.0) * 0.5; + case lsCoolWhiteFluorescent: + case lsFluorescent: + return (3800.0 + 4500.0) * 0.5; + case lsWhiteFluorescent: + return (3250.0 + 3800.0) * 0.5; + case lsWarmWhiteFluorescent: + return (2600.0 + 3250.0) * 0.5; + default: + return 0.0; + } +} +void DCPProfile::MakeXYZCAM(ColorTemp &wb, double pre_mul[3], double camWbMatrix[3][3], int preferredIlluminant, double (*mXYZCAM)[3]) const +{ + // code adapted from dng_color_spec::FindXYZtoCamera + // note that we do not support monochrome or colorplanes > 3 (no reductionMatrix support) + // we do not support cameracalibration either + + double neutral[3]; // same as the DNG "AsShotNeutral" tag if white balance is Camera's own + { + /* A bit messy matrixing and conversions to get the neutral[] array from RT's own white balance which is stored in + sRGB space, while the DCP code needs multipliers in CameraRGB space */ + double r, g, b; + wb.getMultipliers(r, g, b); + + // camWbMatrix == imatrices.xyz_cam + double cam_xyz[3][3]; + Invert3x3(camWbMatrix, cam_xyz); + double cam_rgb[3][3]; + Multiply3x3(cam_xyz, xyz_sRGB, cam_rgb); + double camwb_red = cam_rgb[0][0]*r + cam_rgb[0][1]*g + cam_rgb[0][2]*b; + double camwb_green = cam_rgb[1][0]*r + cam_rgb[1][1]*g + cam_rgb[1][2]*b; + double camwb_blue = cam_rgb[2][0]*r + cam_rgb[2][1]*g + cam_rgb[2][2]*b; + neutral[0] = camwb_red / pre_mul[0]; + neutral[1] = camwb_green / pre_mul[1]; + neutral[2] = camwb_blue / pre_mul[2]; + double maxentry = 0; + for (int i = 0; i < 3; i++) { + if (neutral[i] > maxentry) { + maxentry = neutral[i]; + } + } + for (int i = 0; i < 3; i++) { + neutral[i] /= maxentry; + } + } + + /* Calculate what the RGB multipliers corresponds to as a white XY coordinate, based on the + DCP ColorMatrix or ColorMatrices if dual-illuminant. This is the DNG reference code way to + do it, which is a bit different from RT's own white balance model at the time of writing. + When RT's white balance can make use of the DCP color matrices we could use that instead. */ + double white_xy[2]; + dngref_NeutralToXY(neutral, preferredIlluminant, white_xy); + + bool hasFwd1 = hasForwardMatrix1; + bool hasFwd2 = hasForwardMatrix2; + bool hasCol1 = hasColorMatrix1; + bool hasCol2 = hasColorMatrix2; + if (preferredIlluminant == 1) { + if (hasFwd1) hasFwd2 = false; + if (hasCol1) hasCol2 = false; + } else if (preferredIlluminant == 2) { + if (hasFwd2) hasFwd1 = false; + if (hasCol2) hasCol1 = false; + } + + // mix if we have two matrices + double mix = 1.0; + if ((hasCol1 && hasCol2) || (hasFwd1 && hasFwd2)) { + double wbtemp; + /* DNG ref way to convert XY to temperature, which affect matrix mixing. A different model here + typically does not affect the result too much, ie it's probably not strictly necessary to + use the DNG reference code here, but we do it for now. */ + dngref_XYCoord2Temperature(white_xy, &wbtemp, NULL); + if (wbtemp <= temperature1) { + mix = 1.0; + } else if (wbtemp >= temperature2) { + mix = 0.0; + } else { + double invT = 1.0 / wbtemp; + mix = (invT - (1.0 / temperature2)) / ((1.0 / temperature1) - (1.0 / temperature2)); + } + } + + // Colormatrix + double mCol[3][3]; + if (hasCol1 && hasCol2) { + // interpolate + if (mix >= 1.0) { + memcpy(mCol, mColorMatrix1, sizeof(mCol)); + } else if (mix <= 0.0) { + memcpy(mCol, mColorMatrix2, sizeof(mCol)); + } else { + Mix3x3(mColorMatrix1, mix, mColorMatrix2, 1.0 - mix, mCol); + } + } else if (hasCol1) { + memcpy(mCol, mColorMatrix1, sizeof(mCol)); + } else { + memcpy(mCol, mColorMatrix2, sizeof(mCol)); + } + + /* + The exact position of the white XY coordinate affects the result very much, thus + it's important that the result is very similar or the same as DNG reference code. + Especially important is it that the raw-embedded "AsShot" multipliers is translated + to the same white XY coordinate as the DNG reference code, or else third party DCPs + will show incorrect color. + */ + + double white_xyz[3]; + XYtoXYZ(white_xy, white_xyz); + + double cam_xyz[3][3]; + if (hasFwd1 || hasFwd2) { + // always prefer ForwardMatrix ahead of ColorMatrix + double mFwd[3][3]; + if (hasFwd1 && hasFwd2) { + // interpolate + if (mix >= 1.0) { + memcpy(mFwd, mForwardMatrix1, sizeof(mFwd)); + } else if (mix <= 0.0) { + memcpy(mFwd, mForwardMatrix2, sizeof(mFwd)); + } else { + Mix3x3(mForwardMatrix1, mix, mForwardMatrix2, 1.0 - mix, mFwd); + } + } else if (hasFwd1) { + memcpy(mFwd, mForwardMatrix1, sizeof(mFwd)); + } else { + memcpy(mFwd, mForwardMatrix2, sizeof(mFwd)); + } + // adapted from dng_color_spec::SetWhiteXY + double CameraWhite[3]; + Multiply3x3_v3(mCol, white_xyz, CameraWhite); + + double whiteDiag[3][3] = {{CameraWhite[0], 0, 0}, {0, CameraWhite[1], 0}, {0, 0, CameraWhite[2]}}; + double whiteDiagInv[3][3]; + Invert3x3(whiteDiag, whiteDiagInv); + + double xyz_cam[3][3]; + Multiply3x3(mFwd, whiteDiagInv, xyz_cam); + Invert3x3(xyz_cam, cam_xyz); + } else { + double whiteMatrix[3][3]; + const double white_d50[3] = { 0.3457, 0.3585, 0.2958 }; // D50 + MapWhiteMatrix(white_d50, white_xyz, whiteMatrix); + Multiply3x3(mCol, whiteMatrix, cam_xyz); + } + + // convert cam_xyz (XYZ D50 to CameraRGB, "PCS to Camera" in DNG terminology) to mXYZCAM + + { + // This block can probably be simplified, seems unnecessary to pass through the sRGB matrix + // (probably dcraw legacy), it does no harm though as we don't clip anything. + int i,j,k; + + // Multiply out XYZ colorspace + double cam_rgb[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + for (i=0; i < 3; i++) + for (j=0; j < 3; j++) + for (k=0; k < 3; k++) + cam_rgb[i][j] += cam_xyz[i][k] * xyz_sRGB[k][j]; + + // Normalize cam_rgb so that: cam_rgb * (1,1,1) is (1,1,1,1) + double num; + for (i=0; i<3; i++) { + for (num=j=0; j<3; j++) num += cam_rgb[i][j]; + for (j=0; j<3; j++) cam_rgb[i][j] /= num; + } + + double rgb_cam[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + RawImageSource::inverse33 (cam_rgb, rgb_cam); + + for (i=0; i<3; i++) + for (j=0; j<3; j++) mXYZCAM[i][j]=0; + for (i=0; i<3; i++) + for (j=0; j<3; j++) + for (k=0; k<3; k++) + mXYZCAM[i][j] += xyz_sRGB[i][k] * rgb_cam[k][j]; + } +} + +const DCPProfile::HSBModify* DCPProfile::MakeHueSatMap(ColorTemp &wb, int preferredIlluminant, HSBModify **deleteHandle) const { + + *deleteHandle = NULL; + if (!aDeltas1) { + return NULL; + } + if (!aDeltas2) { + return aDeltas1; + } + + if (preferredIlluminant == 1) { + return aDeltas1; + } else if (preferredIlluminant == 2) { + return aDeltas2; + } + + // Interpolate based on color temperature. + if (temperature1 <= 0.0 || temperature2 <= 0.0 || temperature1 == temperature2) { + return aDeltas1; + } + bool reverseOrder = temperature1 > temperature2; + double t1, t2; + if (reverseOrder) { + t1 = temperature2; + t2 = temperature1; + } else { + t1 = temperature1; + t2 = temperature2; + } + + double mix; + if (wb.getTemp() <= t1) { + mix = 1.0; + } else if (wb.getTemp() >= t2) { + mix = 0.0; + } else { + double invT = 1.0 / wb.getTemp(); + mix = (invT - (1.0 / t2)) / ((1.0 / t1) - (1.0 / t2)); + } + + if (reverseOrder) { + mix = 1.0 - mix; + } + + if (mix >= 1.0) { + return aDeltas1; + } else if (mix <= 0.0) { + return aDeltas2; + } + + // Interpolate between the tables. + HSBModify *aDeltas = new HSBModify[DeltaInfo.iArrayCount]; + *deleteHandle = aDeltas; + float w1 = (float)mix; + float w2 = 1.0f - (float)mix; + for (int i = 0; i < DeltaInfo.iArrayCount; i++) { + aDeltas[i].fHueShift = w1 * aDeltas1[i].fHueShift + w2 * aDeltas2[i].fHueShift; + aDeltas[i].fSatScale = w1 * aDeltas1[i].fSatScale + w2 * aDeltas2[i].fSatScale; + aDeltas[i].fValScale = w1 * aDeltas1[i].fValScale + w2 * aDeltas2[i].fValScale; + } + return aDeltas; +} + +DCPProfile::DCPProfile(Glib::ustring fname, bool isRTProfile) { + const int TIFFFloatSize=4; + const int TagColorMatrix1=50721, TagColorMatrix2=50722, TagProfileHueSatMapDims=50937; + const int TagForwardMatrix1=50964, TagForwardMatrix2=50965; + const int TagProfileHueSatMapData1=50938, TagProfileHueSatMapData2=50939; + const int TagCalibrationIlluminant1=50778, TagCalibrationIlluminant2=50779; + const int TagProfileLookTableData=50982, TagProfileLookTableDims=50981; // ProfileLookup is the low quality variant + const int TagProfileHueSatMapEncoding=51107, TagProfileLookTableEncoding=51108; + const int TagProfileToneCurve=50940, TagBaselineExposureOffset=51109; + const int TagProfileCopyright=50942; + + aDeltas1=aDeltas2=aLookTable=NULL; + + FILE *pFile = safe_g_fopen(fname, "rb"); + + TagDirectory *tagDir=ExifManager::parseTIFF(pFile, false); + + Tag* tag = tagDir->getTag(TagCalibrationIlluminant1); iLightSource1 = (tag!=NULL ? tag->toInt(0,rtexif::SHORT) : -1); + tag = tagDir->getTag(TagCalibrationIlluminant2); iLightSource2 = (tag!=NULL ? tag->toInt(0,rtexif::SHORT) : -1); + temperature1 = calibrationIlluminantToTemperature(iLightSource1); + temperature2 = calibrationIlluminantToTemperature(iLightSource2); + + bool hasSecondHueSat = tagDir->getTag(TagProfileHueSatMapData2)!=NULL; // some profiles have two matrices, but just one huesat + + // Fetch Forward Matrices, if any + hasForwardMatrix1 = false; + hasForwardMatrix2 = false; + hasColorMatrix1 = false; + hasColorMatrix2 = false; + hasToneCurve = false; + hasBaselineExposureOffset = false; + baselineExposureOffset = 0; + tag = tagDir->getTag(TagForwardMatrix1); + if (tag) { + hasForwardMatrix1 = true; + for (int row=0;row<3;row++) { + for (int col=0;col<3;col++) { + mForwardMatrix1[row][col]=(float)tag->toDouble((col+row*3)*8); + } + } + } + tag = tagDir->getTag(TagForwardMatrix2); + if (tag) { + hasForwardMatrix2 = true; + for (int row=0;row<3;row++) { + for (int col=0;col<3;col++) { + mForwardMatrix2[row][col]=(float)tag->toDouble((col+row*3)*8); + } + } + } + + // Color Matrix (1 is always there) + tag = tagDir->getTag(TagColorMatrix1); + if (!tag) { + // FIXME: better error handling + fprintf(stderr, "Bad DCP, no ColorMatrix1\n"); + abort(); + } + hasColorMatrix1 = true; + + for (int row=0;row<3;row++) { + for (int col=0;col<3;col++) { + mColorMatrix1[row][col]=(float)tag->toDouble((col+row*3)*8); + } + } + + tag=tagDir->getTag(TagProfileLookTableDims); + if (tag!=NULL) { + LookInfo.iHueDivisions=tag->toInt(0); LookInfo.iSatDivisions=tag->toInt(4); LookInfo.iValDivisions=tag->toInt(8); + + tag = tagDir->getTag(TagProfileLookTableEncoding); + LookInfo.sRGBGamma = tag != NULL && tag->toInt(0); + + tag = tagDir->getTag(TagProfileLookTableData); + LookInfo.iArrayCount = tag->getCount()/3; + + aLookTable =new HSBModify[LookInfo.iArrayCount]; + + for (int i=0;itoDouble((i*3)*TIFFFloatSize); + aLookTable[i].fSatScale=tag->toDouble((i*3+1)*TIFFFloatSize); + aLookTable[i].fValScale=tag->toDouble((i*3+2)*TIFFFloatSize); + } + + // precalculated constants for table application + LookInfo.pc.hScale = (LookInfo.iHueDivisions < 2) ? 0.0f : (LookInfo.iHueDivisions * (1.0f / 6.0f)); + LookInfo.pc.sScale = (float) (LookInfo.iSatDivisions - 1); + LookInfo.pc.vScale = (float) (LookInfo.iValDivisions - 1); + LookInfo.pc.maxHueIndex0 = LookInfo.iHueDivisions - 1; + LookInfo.pc.maxSatIndex0 = LookInfo.iSatDivisions - 2; + LookInfo.pc.maxValIndex0 = LookInfo.iValDivisions - 2; + LookInfo.pc.hueStep = LookInfo.iSatDivisions; + LookInfo.pc.valStep = LookInfo.iHueDivisions * LookInfo.pc.hueStep; + } + + tag = tagDir->getTag(TagProfileHueSatMapDims); + if (tag!=NULL) { + DeltaInfo.iHueDivisions=tag->toInt(0); DeltaInfo.iSatDivisions=tag->toInt(4); DeltaInfo.iValDivisions=tag->toInt(8); + + tag = tagDir->getTag(TagProfileHueSatMapEncoding); + DeltaInfo.sRGBGamma = tag != NULL && tag->toInt(0); + + tag = tagDir->getTag(TagProfileHueSatMapData1); + DeltaInfo.iArrayCount = tag->getCount()/3; + + aDeltas1=new HSBModify[DeltaInfo.iArrayCount]; + + for (int i=0;itoDouble((i*3)*TIFFFloatSize); + aDeltas1[i].fSatScale=tag->toDouble((i*3+1)*TIFFFloatSize); + aDeltas1[i].fValScale=tag->toDouble((i*3+2)*TIFFFloatSize); + } + + DeltaInfo.pc.hScale = (DeltaInfo.iHueDivisions < 2) ? 0.0f : (DeltaInfo.iHueDivisions * (1.0f / 6.0f)); + DeltaInfo.pc.sScale = (float) (DeltaInfo.iSatDivisions - 1); + DeltaInfo.pc.vScale = (float) (DeltaInfo.iValDivisions - 1); + DeltaInfo.pc.maxHueIndex0 = DeltaInfo.iHueDivisions - 1; + DeltaInfo.pc.maxSatIndex0 = DeltaInfo.iSatDivisions - 2; + DeltaInfo.pc.maxValIndex0 = DeltaInfo.iValDivisions - 2; + DeltaInfo.pc.hueStep = DeltaInfo.iSatDivisions; + DeltaInfo.pc.valStep = DeltaInfo.iHueDivisions * DeltaInfo.pc.hueStep; + } + + if (iLightSource2!=-1) { + // Second matrix + tag = tagDir->getTag(TagColorMatrix2); + hasColorMatrix2 = true; + + for (int row=0;row<3;row++) { + for (int col=0;col<3;col++) { + mColorMatrix2[row][col]= (tag!=NULL ? (float)tag->toDouble((col+row*3)*8) : mColorMatrix1[row][col]); + } + } + + // Second huesatmap + if (hasSecondHueSat) { + aDeltas2=new HSBModify[DeltaInfo.iArrayCount]; + + // Saturation maps. Need to be unwinded. + tag = tagDir->getTag(TagProfileHueSatMapData2); + + for (int i=0;itoDouble((i*3)*TIFFFloatSize); + aDeltas2[i].fSatScale=tag->toDouble((i*3+1)*TIFFFloatSize); + aDeltas2[i].fValScale=tag->toDouble((i*3+2)*TIFFFloatSize); + } + } + } + + tag = tagDir->getTag(TagBaselineExposureOffset); + if (tag) { + hasBaselineExposureOffset = true; + baselineExposureOffset = tag->toDouble(); + } + + // Read tone curve points, if any, but disable to RTs own profiles + tag = tagDir->getTag(TagProfileToneCurve); + if (tag!=NULL && !isRTProfile) { + std::vector cPoints; + cPoints.push_back(double(DCT_Spline)); // The first value is the curve type + + // push back each X/Y coordinates in a loop + bool curve_is_linear = true; + for (int i=0;igetCount(); i+= 2) { + double x = tag->toDouble((i+0)*TIFFFloatSize); + double y = tag->toDouble((i+1)*TIFFFloatSize); + if (x != y) { + curve_is_linear = false; + } + cPoints.push_back( x ); + cPoints.push_back( y ); + } + + if (!curve_is_linear) { + // Create the curve + DiagonalCurve rawCurve(cPoints, CURVES_MIN_POLY_POINTS); + + toneCurve.Set((Curve*)&rawCurve); + hasToneCurve = true; + } + } else if (tag == NULL) { + tag = tagDir->getTag(TagProfileCopyright); + if (tag!=NULL && tag->valueToString().find("Adobe Systems") != std::string::npos) { + // an Adobe profile without tone curve is expected to have the Adobe Default Curve, we add that + std::vector cPoints; + cPoints.push_back(double(DCT_Spline)); + const size_t tc_len = sizeof(adobe_camera_raw_default_curve)/sizeof(adobe_camera_raw_default_curve[0]); + for (size_t i = 0; i < tc_len; i++) { + double x = (double)i / (tc_len - 1); + double y = (double)adobe_camera_raw_default_curve[i]; + cPoints.push_back( x ); + cPoints.push_back( y ); + } + DiagonalCurve rawCurve(cPoints, CURVES_MIN_POLY_POINTS); + toneCurve.Set((Curve*)&rawCurve); + hasToneCurve = true; + } + } + + willInterpolate = false; + if (hasForwardMatrix1) { + if (hasForwardMatrix2) { + if (memcmp(mForwardMatrix1, mForwardMatrix2, sizeof(mForwardMatrix1)) != 0) { + // common that forward matrices are the same! + willInterpolate = true; + } + if (aDeltas1 && aDeltas2) { + // we assume tables are different + willInterpolate = true; + } + } + } + if (hasColorMatrix1 && hasColorMatrix2) { + if (memcmp(mColorMatrix1, mColorMatrix2, sizeof(mColorMatrix1)) != 0) { + willInterpolate = true; + } + if (aDeltas1 && aDeltas2) { + willInterpolate = true; + } + } + + if (pFile!=NULL) fclose(pFile); + delete tagDir; +} + +DCPProfile::~DCPProfile() { + delete[] aDeltas1; + delete[] aDeltas2; + delete[] aLookTable; +} + +void DCPProfile::HSDApply(const HSDTableInfo &ti, const HSBModify *tableBase, float &h, float &s, float &v) const { + + // Apply the HueSatMap. Ported from Adobes reference implementation + float hueShift, satScale, valScale; + float vEncoded = v; + + if (ti.iValDivisions < 2) // Optimize most common case of "2.5D" table. + { + float hScaled = h * ti.pc.hScale; + float sScaled = s * ti.pc.sScale; + + int hIndex0 = max((int)hScaled, 0); + int sIndex0 = max(min((int)sScaled,ti.pc.maxSatIndex0),0); + + int hIndex1 = hIndex0 + 1; + + if (hIndex0 >= ti.pc.maxHueIndex0) + { + hIndex0 = ti.pc.maxHueIndex0; + hIndex1 = 0; + } + + float hFract1 = hScaled - (float) hIndex0; + float sFract1 = sScaled - (float) sIndex0; + + float hFract0 = 1.0f - hFract1; + float sFract0 = 1.0f - sFract1; + + const HSBModify *entry00 = tableBase + hIndex0 * ti.pc.hueStep + sIndex0; + const HSBModify *entry01 = entry00 + (hIndex1 - hIndex0) * ti.pc.hueStep; + + float hueShift0 = hFract0 * entry00->fHueShift + hFract1 * entry01->fHueShift; + float satScale0 = hFract0 * entry00->fSatScale + hFract1 * entry01->fSatScale; + float valScale0 = hFract0 * entry00->fValScale + hFract1 * entry01->fValScale; + + entry00++; + entry01++; + + float hueShift1 = hFract0 * entry00->fHueShift + + hFract1 * entry01->fHueShift; + + float satScale1 = hFract0 * entry00->fSatScale + + hFract1 * entry01->fSatScale; + + float valScale1 = hFract0 * entry00->fValScale + + hFract1 * entry01->fValScale; + + hueShift = sFract0 * hueShift0 + sFract1 * hueShift1; + satScale = sFract0 * satScale0 + sFract1 * satScale1; + valScale = sFract0 * valScale0 + sFract1 * valScale1; + + } else { + + float hScaled = h * ti.pc.hScale; + float sScaled = s * ti.pc.sScale; + if (ti.sRGBGamma) vEncoded = sRGBGammaForward(v); + float vScaled = vEncoded * ti.pc.vScale; + + int hIndex0 = (int) hScaled; + int sIndex0 = max(min((int)sScaled,ti.pc.maxSatIndex0),0); + int vIndex0 = max(min((int)vScaled,ti.pc.maxValIndex0),0); + + int hIndex1 = hIndex0 + 1; + + if (hIndex0 >= ti.pc.maxHueIndex0) + { + hIndex0 = ti.pc.maxHueIndex0; + hIndex1 = 0; + } + + float hFract1 = hScaled - (float) hIndex0; + float sFract1 = sScaled - (float) sIndex0; + float vFract1 = vScaled - (float) vIndex0; + + float hFract0 = 1.0f - hFract1; + float sFract0 = 1.0f - sFract1; + float vFract0 = 1.0f - vFract1; + + const HSBModify *entry00 = tableBase + vIndex0 * ti.pc.valStep + hIndex0 * ti.pc.hueStep + sIndex0; + + const HSBModify *entry01 = entry00 + (hIndex1 - hIndex0) * ti.pc.hueStep; + + const HSBModify *entry10 = entry00 + ti.pc.valStep; + const HSBModify *entry11 = entry01 + ti.pc.valStep; + + float hueShift0 = vFract0 * (hFract0 * entry00->fHueShift + + hFract1 * entry01->fHueShift) + + vFract1 * (hFract0 * entry10->fHueShift + + hFract1 * entry11->fHueShift); + + float satScale0 = vFract0 * (hFract0 * entry00->fSatScale + + hFract1 * entry01->fSatScale) + + vFract1 * (hFract0 * entry10->fSatScale + + hFract1 * entry11->fSatScale); + + float valScale0 = vFract0 * (hFract0 * entry00->fValScale + + hFract1 * entry01->fValScale) + + vFract1 * (hFract0 * entry10->fValScale + + hFract1 * entry11->fValScale); + + entry00++; + entry01++; + entry10++; + entry11++; + + float hueShift1 = vFract0 * (hFract0 * entry00->fHueShift + + hFract1 * entry01->fHueShift) + + vFract1 * (hFract0 * entry10->fHueShift + + hFract1 * entry11->fHueShift); + + float satScale1 = vFract0 * (hFract0 * entry00->fSatScale + + hFract1 * entry01->fSatScale) + + vFract1 * (hFract0 * entry10->fSatScale + + hFract1 * entry11->fSatScale); + + float valScale1 = vFract0 * (hFract0 * entry00->fValScale + + hFract1 * entry01->fValScale) + + vFract1 * (hFract0 * entry10->fValScale + + hFract1 * entry11->fValScale); + + hueShift = sFract0 * hueShift0 + sFract1 * hueShift1; + satScale = sFract0 * satScale0 + sFract1 * satScale1; + valScale = sFract0 * valScale0 + sFract1 * valScale1; + } + + hueShift *= (6.0f / 360.0f); // Convert to internal hue range. + + h += hueShift; + s *= satScale; // no clipping here, we are RT float :-) + if (ti.sRGBGamma) { + v = sRGBGammaInverse(vEncoded * valScale); + } else { + v *= valScale; + } +} + +struct ruvt { + double r; + double u; + double v; + double t; +}; + +static const double kTintScale = -3000.0; +static const ruvt kTempTable [] = + { + { 0, 0.18006, 0.26352, -0.24341 }, + { 10, 0.18066, 0.26589, -0.25479 }, + { 20, 0.18133, 0.26846, -0.26876 }, + { 30, 0.18208, 0.27119, -0.28539 }, + { 40, 0.18293, 0.27407, -0.30470 }, + { 50, 0.18388, 0.27709, -0.32675 }, + { 60, 0.18494, 0.28021, -0.35156 }, + { 70, 0.18611, 0.28342, -0.37915 }, + { 80, 0.18740, 0.28668, -0.40955 }, + { 90, 0.18880, 0.28997, -0.44278 }, + { 100, 0.19032, 0.29326, -0.47888 }, + { 125, 0.19462, 0.30141, -0.58204 }, + { 150, 0.19962, 0.30921, -0.70471 }, + { 175, 0.20525, 0.31647, -0.84901 }, + { 200, 0.21142, 0.32312, -1.0182 }, + { 225, 0.21807, 0.32909, -1.2168 }, + { 250, 0.22511, 0.33439, -1.4512 }, + { 275, 0.23247, 0.33904, -1.7298 }, + { 300, 0.24010, 0.34308, -2.0637 }, + { 325, 0.24702, 0.34655, -2.4681 }, + { 350, 0.25591, 0.34951, -2.9641 }, + { 375, 0.26400, 0.35200, -3.5814 }, + { 400, 0.27218, 0.35407, -4.3633 }, + { 425, 0.28039, 0.35577, -5.3762 }, + { 450, 0.28863, 0.35714, -6.7262 }, + { 475, 0.29685, 0.35823, -8.5955 }, + { 500, 0.30505, 0.35907, -11.324 }, + { 525, 0.31320, 0.35968, -15.628 }, + { 550, 0.32129, 0.36011, -23.325 }, + { 575, 0.32931, 0.36038, -40.770 }, + { 600, 0.33724, 0.36051, -116.45 } + }; + +void DCPProfile::dngref_XYCoord2Temperature(const double whiteXY[2], double *temp, double *tint) const { + double fTemperature = 0; + double fTint = 0; + + // Convert to uv space. + double u = 2.0 * whiteXY[0] / (1.5 - whiteXY[0] + 6.0 * whiteXY[1]); + double v = 3.0 * whiteXY[1] / (1.5 - whiteXY[0] + 6.0 * whiteXY[1]); + + // Search for line pair coordinate is between. + double last_dt = 0.0; + double last_dv = 0.0; + double last_du = 0.0; + + for (uint32_t index = 1; index <= 30; index++) { + // Convert slope to delta-u and delta-v, with length 1. + double du = 1.0; + double dv = kTempTable [index] . t; + double len = sqrt (1.0 + dv * dv); + du /= len; + dv /= len; + + // Find delta from black body point to test coordinate. + double uu = u - kTempTable [index] . u; + double vv = v - kTempTable [index] . v; + + // Find distance above or below line. + double dt = - uu * dv + vv * du; + + // If below line, we have found line pair. + if (dt <= 0.0 || index == 30) { + // Find fractional weight of two lines. + if (dt > 0.0) + dt = 0.0; + dt = -dt; + double f; + if (index == 1) + { + f = 0.0; + } + else + { + f = dt / (last_dt + dt); + } + + // Interpolate the temperature. + fTemperature = 1.0E6 / (kTempTable [index - 1] . r * f + + kTempTable [index ] . r * (1.0 - f)); + + // Find delta from black body point to test coordinate. + uu = u - (kTempTable [index - 1] . u * f + + kTempTable [index ] . u * (1.0 - f)); + vv = v - (kTempTable [index - 1] . v * f + + kTempTable [index ] . v * (1.0 - f)); + // Interpolate vectors along slope. + du = du * (1.0 - f) + last_du * f; + dv = dv * (1.0 - f) + last_dv * f; + len = sqrt (du * du + dv * dv); + du /= len; + dv /= len; + + // Find distance along slope. + fTint = (uu * du + vv * dv) * kTintScale; + break; + } + // Try next line pair. + last_dt = dt; + last_du = du; + last_dv = dv; + } + if (temp != NULL) + *temp = fTemperature; + if (tint != NULL) + *tint = fTint; +} + +void DCPProfile::dngref_FindXYZtoCamera(const double whiteXY[2], int preferredIlluminant, double (*xyzToCamera)[3]) const { + + bool hasCol1 = hasColorMatrix1; + bool hasCol2 = hasColorMatrix2; + if (preferredIlluminant == 1) { + if (hasCol1) hasCol2 = false; + } else if (preferredIlluminant == 2) { + if (hasCol2) hasCol1 = false; + } + + // mix if we have two matrices + double mix; + if (hasCol1 && hasCol2) { + double wbtemp; + /* + Note: we're using DNG SDK reference code for XY to temperature translation to get the exact same mix as + the reference code does. + */ + dngref_XYCoord2Temperature(whiteXY, &wbtemp, NULL); + if (wbtemp <= temperature1) { + mix = 1.0; + } else if (wbtemp >= temperature2) { + mix = 0.0; + } else { + double invT = 1.0 / wbtemp; + mix = (invT - (1.0 / temperature2)) / ((1.0 / temperature1) - (1.0 / temperature2)); + } + } + + // Interpolate the color matrix. + double mCol[3][3]; + if (hasCol1 && hasCol2) { + // interpolate + if (mix >= 1.0) { + memcpy(mCol, mColorMatrix1, sizeof(mCol)); + } else if (mix <= 0.0) { + memcpy(mCol, mColorMatrix2, sizeof(mCol)); + } else { + Mix3x3(mColorMatrix1, mix, mColorMatrix2, 1.0 - mix, mCol); + } + } else if (hasCol1) { + memcpy(mCol, mColorMatrix1, sizeof(mCol)); + } else { + memcpy(mCol, mColorMatrix2, sizeof(mCol)); + } + memcpy(xyzToCamera, mCol, sizeof(mCol)); +} + +void DCPProfile::dngref_NeutralToXY(double neutral[3], int preferredIlluminant, double XY[2]) const { + const int kMaxPasses = 30; + double lastXY[2] = { 0.3457, 0.3585 }; // D50 + for (int pass = 0; pass < kMaxPasses; pass++) { + double xyzToCamera[3][3]; + dngref_FindXYZtoCamera(lastXY, preferredIlluminant, xyzToCamera); + + double invM[3][3], nextXYZ[3], nextXY[2]; + Invert3x3(xyzToCamera, invM); + Multiply3x3_v3(invM, neutral, nextXYZ); + XYZtoXY(nextXYZ, nextXY); + + if (fabs(nextXY[0] - lastXY[0]) + + fabs(nextXY[1] - lastXY[1]) < 0.0000001) + { + XY[0] = nextXY[0]; + XY[1] = nextXY[1]; + return; + } + // If we reach the limit without converging, we are most likely + // in a two value oscillation. So take the average of the last + // two estimates and give up. + if (pass == kMaxPasses - 1) { + nextXY[0] = (lastXY[0] + nextXY[0]) * 0.5; + nextXY[1] = (lastXY[1] + nextXY[1]) * 0.5; + } + lastXY[0] = nextXY[0]; + lastXY[1] = nextXY[1]; + } + XY[0] = lastXY[0]; + XY[1] = lastXY[1]; +} + +void DCPProfile::Apply(Imagefloat *pImg, int preferredIlluminant, Glib::ustring workingSpace, ColorTemp &wb, double pre_mul[3], double camWbMatrix[3][3], bool useToneCurve, bool applyHueSatMap, bool applyLookTable) const { + + TMatrix mWork = iccStore->workingSpaceInverseMatrix (workingSpace); + + double mXYZCAM[3][3]; // Camera RGB to XYZ D50 matrix + MakeXYZCAM(wb, pre_mul, camWbMatrix, preferredIlluminant, mXYZCAM); + HSBModify *deleteTableHandle; + const HSBModify *deltaBase = MakeHueSatMap(wb, preferredIlluminant, &deleteTableHandle); + if (!deltaBase) applyHueSatMap = false; + if (!aLookTable) applyLookTable = false; + + useToneCurve&=toneCurve; + + if (!applyHueSatMap && !applyLookTable && !useToneCurve) { + //===== The fast path: no LUT and not tone curve- Calculate matrix for direct conversion raw>working space + double mat[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + mat[i][j] += mWork[i][k] * mXYZCAM[k][j]; + + // Apply the matrix part +#pragma omp parallel for + for (int y=0; yheight; y++) { + float newr, newg, newb; + for (int x=0; xwidth; x++) { + newr = mat[0][0]*pImg->r(y,x) + mat[0][1]*pImg->g(y,x) + mat[0][2]*pImg->b(y,x); + newg = mat[1][0]*pImg->r(y,x) + mat[1][1]*pImg->g(y,x) + mat[1][2]*pImg->b(y,x); + newb = mat[2][0]*pImg->r(y,x) + mat[2][1]*pImg->g(y,x) + mat[2][2]*pImg->b(y,x); + + pImg->r(y,x) = newr; pImg->g(y,x) = newg; pImg->b(y,x) = newb; + } + } + } + else { + //===== LUT available- Calculate matrix for conversion raw>ProPhoto + double m2ProPhoto[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + m2ProPhoto[i][j] += prophoto_xyz[i][k] * mXYZCAM[k][j]; + + double m2Work[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + m2Work[i][j] += mWork[i][k] * xyz_prophoto[k][j]; + + // Convert to prophoto and apply LUT +#pragma omp parallel for + for (int y=0; yheight; y++) { + float newr, newg, newb, h,s,v,hs,ss,vs; + for (int x=0; xwidth; x++) { + newr = m2ProPhoto[0][0]*pImg->r(y,x) + m2ProPhoto[0][1]*pImg->g(y,x) + m2ProPhoto[0][2]*pImg->b(y,x); + newg = m2ProPhoto[1][0]*pImg->r(y,x) + m2ProPhoto[1][1]*pImg->g(y,x) + m2ProPhoto[1][2]*pImg->b(y,x); + newb = m2ProPhoto[2][0]*pImg->r(y,x) + m2ProPhoto[2][1]*pImg->g(y,x) + m2ProPhoto[2][2]*pImg->b(y,x); + + // if point is in negative area, just the matrix, but not the LUT + if ((applyHueSatMap || applyLookTable) && newr>=0 && newg>=0 && newb>=0) { + Color::rgb2hsv(newr, newg, newb, h , s, v); + h*=6.f; // RT calculates in [0,1] + + if (applyHueSatMap) { + HSDApply(DeltaInfo, deltaBase, h, s, v); + } + if (applyLookTable) { + HSDApply(LookInfo, aLookTable, h, s, v); + } + + // RT range correction + if (h < 0.0f) h += 6.0f; + if (h >= 6.0f) h -= 6.0f; + h/=6.f; + Color::hsv2rgb( h, s, v, newr, newg, newb); + } + // tone curve + if (useToneCurve) toneCurve.Apply(newr, newg, newb); + + pImg->r(y,x) = m2Work[0][0]*newr + m2Work[0][1]*newg + m2Work[0][2]*newb; + pImg->g(y,x) = m2Work[1][0]*newr + m2Work[1][1]*newg + m2Work[1][2]*newb; + pImg->b(y,x) = m2Work[2][0]*newr + m2Work[2][1]*newg + m2Work[2][2]*newb; + } + } + } + + if (deleteTableHandle) delete[] deleteTableHandle; +} + +void DCPProfile::setStep2ApplyState(Glib::ustring workingSpace, bool useToneCurve, bool applyLookTable, bool applyBaselineExposure) { + + applyState.useToneCurve = useToneCurve; + applyState.applyLookTable = applyLookTable; + applyState.blScale = 1.0; + if (!aLookTable) applyState.applyLookTable = false; + if (!hasToneCurve) applyState.useToneCurve = false; + if (hasBaselineExposureOffset && applyBaselineExposure) { + applyState.blScale = powf(2, baselineExposureOffset); + } + + if (workingSpace == "ProPhoto") { + applyState.alreadyProPhoto = true; + } else { + applyState.alreadyProPhoto = false; + TMatrix mWork; + + mWork = iccStore->workingSpaceMatrix (workingSpace); + memset(applyState.m2ProPhoto, 0, sizeof(applyState.m2ProPhoto)); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + applyState.m2ProPhoto[i][j] += prophoto_xyz[i][k] * mWork[k][j]; + + mWork = iccStore->workingSpaceInverseMatrix (workingSpace); + memset(applyState.m2Work, 0, sizeof(applyState.m2Work)); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + applyState.m2Work[i][j] += mWork[i][k] * xyz_prophoto[k][j]; + } +} + +void DCPProfile::step2ApplyTile(float *rc, float *gc, float *bc, int width, int height, int tileWidth, float exp_scale) const { + +#define FCLIP(a) ((a)>0.0?((a)<65535.5?(a):65535.5):0.0) +#define CLIP01(a) ((a)>0?((a)<1?(a):1):0) + + exp_scale *= applyState.blScale; + if (!applyState.useToneCurve && !applyState.applyLookTable) { + if (exp_scale == 1.0) { + return; + } + for (int y=0; y= 6.0f) h -= 6.0f; + h/=6.f; + Color::hsv2rgb( h, s, v, newr, newg, newb); + } + if (applyState.useToneCurve) { + toneCurve.Apply(newr, newg, newb); + } + + if (applyState.alreadyProPhoto) { + rc[y*tileWidth+x] = newr; + gc[y*tileWidth+x] = newg; + bc[y*tileWidth+x] = newb; + } else { + rc[y*tileWidth+x] = applyState.m2Work[0][0]*newr + applyState.m2Work[0][1]*newg + applyState.m2Work[0][2]*newb; + gc[y*tileWidth+x] = applyState.m2Work[1][0]*newr + applyState.m2Work[1][1]*newg + applyState.m2Work[1][2]*newb; + bc[y*tileWidth+x] = applyState.m2Work[2][0]*newr + applyState.m2Work[2][1]*newg + applyState.m2Work[2][2]*newb; + } + } + } + } +} + +// Generates as singleton +DCPStore* DCPStore::getInstance() +{ + static DCPStore* instance_ = 0; + if ( instance_ == 0 ) + { + static MyMutex smutex_; + MyMutex::MyLock lock(smutex_); + if ( instance_ == 0 ) + { + instance_ = new DCPStore(); + } + } + return instance_; +} + +// Reads all profiles from the given profiles dir +void DCPStore::init (Glib::ustring rtProfileDir) { + MyMutex::MyLock lock(mtx); + + fileStdProfiles.clear(); + + Glib::ustring rootDirName=rtProfileDir; + + if (rootDirName!="") { + std::deque qDirs; + + qDirs.push_front(rootDirName); + + while (!qDirs.empty()) { + // process directory + Glib::ustring dirname = qDirs.back(); + qDirs.pop_back(); + + Glib::Dir* dir = NULL; + try { + if (!safe_file_test (dirname, Glib::FILE_TEST_IS_DIR)) return; + dir = new Glib::Dir (dirname); + } + catch (Glib::Exception& fe) { + return; + } + dirname = dirname + "/"; + for (Glib::DirIterator i = dir->begin(); i!=dir->end(); ++i) { + Glib::ustring fname = dirname + *i; + Glib::ustring sname = *i; + // ignore directories + if (!safe_file_test (fname, Glib::FILE_TEST_IS_DIR)) { + size_t lastdot = sname.find_last_of ('.'); + if (lastdot!=Glib::ustring::npos && lastdot<=sname.size()-4 && (!sname.casefold().compare (lastdot, 4, ".dcp"))) { + Glib::ustring camShortName = sname.substr(0,lastdot).uppercase(); + fileStdProfiles[camShortName]=fname; // they will be loaded and cached on demand + } + } else qDirs.push_front(fname); // for later scanning + } + delete dir; + } + } +} + +DCPProfile* DCPStore::getProfile (Glib::ustring filename, bool isRTProfile) { + MyMutex::MyLock lock(mtx); + + std::map::iterator r = profileCache.find (filename); + if (r!=profileCache.end()) return r->second; + + // Add profile + profileCache[filename]=new DCPProfile(filename, isRTProfile); + + return profileCache[filename]; +} + +DCPProfile* DCPStore::getStdProfile(Glib::ustring camShortName) { + Glib::ustring name2=camShortName.uppercase(); + + // Warning: do NOT use map.find(), since it does not seem to work reliably here + for (std::map::iterator i=fileStdProfiles.begin();i!=fileStdProfiles.end();i++) + if (name2==(*i).first) return getProfile((*i).second, true); + + return NULL; +} + +bool DCPStore::isValidDCPFileName(Glib::ustring filename) const { + if (!safe_file_test (filename, Glib::FILE_TEST_EXISTS) || safe_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, ".dcp") || !filename.casefold().compare (pos, 4, ".dng")); +} diff --git a/rtengine/dcp.h b/rtengine/dcp.h new file mode 100644 index 000000000..0ce82b590 --- /dev/null +++ b/rtengine/dcp.h @@ -0,0 +1,115 @@ +/* +* This file is part of RawTherapee. +* +* Copyright (c) 2012 Oliver Duis +* +* 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 _DCP_ +#define _DCP_ + +#include "imagefloat.h" +#include "curves.h" +#include "colortemp.h" +#include "../rtgui/threadutils.h" +#include +#include +#include + +namespace rtengine { + + class DCPProfile { + struct HSBModify + { + float fHueShift; + float fSatScale; + float fValScale; + }; + struct HSDTableInfo + { + int iHueDivisions, iSatDivisions, iValDivisions; + int iHueStep, iValStep, iArrayCount; + bool sRGBGamma; + struct + { + float hScale, sScale, vScale; + int maxHueIndex0, maxSatIndex0, maxValIndex0; + int hueStep, valStep; + } pc; + }; + + double mColorMatrix1[3][3],mColorMatrix2[3][3]; + bool hasColorMatrix1, hasColorMatrix2, hasForwardMatrix1, hasForwardMatrix2, hasToneCurve, hasBaselineExposureOffset, willInterpolate; + double mForwardMatrix1[3][3],mForwardMatrix2[3][3]; + double temperature1, temperature2; + double baselineExposureOffset; + HSBModify *aDeltas1,*aDeltas2,*aLookTable; + HSDTableInfo DeltaInfo,LookInfo; + short iLightSource1,iLightSource2; + + AdobeToneCurve toneCurve; + struct { + double m2ProPhoto[3][3]; + double m2Work[3][3]; + bool alreadyProPhoto; + bool useToneCurve; + bool applyLookTable; + float blScale; + } applyState; + + void dngref_XYCoord2Temperature(const double whiteXY[2], double *temp, double *tint) const; + void dngref_FindXYZtoCamera(const double whiteXY[2], int preferredIlluminant, double (*xyzToCamera)[3]) const; + void dngref_NeutralToXY(double neutral[3], int preferredIlluminant, double XY[2]) const; + void MakeXYZCAM(ColorTemp &wb, double pre_mul[3], double camWbMatrix[3][3], int preferredIlluminant, double (*mXYZCAM)[3]) const; + const HSBModify* MakeHueSatMap(ColorTemp &wb, int preferredIlluminant, HSBModify **deleteHandle) const; + void HSDApply(const HSDTableInfo &ti, const HSBModify *tableBase, float &h, float &s, float &v) const; + + public: + DCPProfile(Glib::ustring fname, bool isRTProfile); + ~DCPProfile(); + + bool getHasToneCurve() { return hasToneCurve; } + bool getHasLookTable() { return !!aLookTable; } + bool getHasHueSatMap() { return !!aDeltas1; } + bool getHasBaselineExposureOffset() { return hasBaselineExposureOffset; } + void getIlluminants(int &i1, double &temp1, int &i2, double &temp2, bool &willInterpolate_) { i1 = iLightSource1; i2 = iLightSource2; temp1 = temperature1, temp2 = temperature2; willInterpolate_ = willInterpolate; }; + void Apply(Imagefloat *pImg, int preferredIlluminant, Glib::ustring workingSpace, ColorTemp &wb, double pre_mul[3], double camMatrix[3][3], bool useToneCurve=false, bool applyHueSatMap=true, bool applyLookTable=false) const; + void setStep2ApplyState(Glib::ustring workingSpace, bool useToneCurve, bool applyLookTable, bool applyBaselineExposure); + void step2ApplyTile(float *r, float *g, float *b, int width, int height, int tileWidth, float exp_scale) const; + }; + + class DCPStore { + MyMutex mtx; + + // these contain standard profiles from RT. keys are all in uppercase, file path is value + std::map fileStdProfiles; + + // Maps file name to profile as cache + std::map profileCache; + + public: + void init(Glib::ustring rtProfileDir); + + bool isValidDCPFileName(Glib::ustring filename) const; + + DCPProfile* getProfile(Glib::ustring filename, bool isRTProfile=false); + DCPProfile* getStdProfile(Glib::ustring camShortName); + + static DCPStore* getInstance(); + }; + + #define dcpStore DCPStore::getInstance() +} +#endif diff --git a/rtengine/dcraw.c b/rtengine/dcraw.c new file mode 100644 index 000000000..cf1afe4ac --- /dev/null +++ b/rtengine/dcraw.c @@ -0,0 +1,10050 @@ +/* + dcraw.c -- Dave Coffin's raw photo decoder + Copyright 1997-2015 by Dave Coffin, dcoffin a cybercom o net + + This is a command-line ANSI C program to convert raw photos from + any digital camera on any computer running any operating system. + + No license is required to download and use dcraw.c. However, + to lawfully redistribute dcraw, you must either (a) offer, at + no extra charge, full source code* for all executable files + containing RESTRICTED functions, (b) distribute this code under + the GPL Version 2 or later, (c) remove all RESTRICTED functions, + re-implement them, or copy them from an earlier, unrestricted + Revision of dcraw.c, or (d) purchase a license from the author. + + The functions that process Foveon images have been RESTRICTED + since Revision 1.237. All other code remains free for all uses. + + *If you have not modified dcraw.c in any way, a link to my + homepage qualifies as "full source code". + + $Revision: 1.475 $ + $Date: 2015/04/11 00:08:36 $ + */ + +#define DCRAW_VERSION "9.25" + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#define _USE_MATH_DEFINES +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(DJGPP) || defined(__MINGW32__) +#define fseeko fseek +#define ftello ftell +#else +#define fgetc getc_unlocked +#endif +#ifdef __CYGWIN__ +#include +#endif +#ifdef WIN32 +#include +#include +#pragma comment(lib, "ws2_32.lib") +#define snprintf _snprintf +#define strcasecmp stricmp +#define strncasecmp strnicmp +typedef __int64 INT64; +typedef unsigned __int64 UINT64; +#else +#include +#include +#include +typedef long long INT64; +typedef unsigned long long UINT64; +#endif + +#ifdef NODEPS +#define NO_JASPER +#define NO_JPEG +#define NO_LCMS +#endif +#ifndef NO_JASPER +#include /* Decode Red camera movies */ +#endif +#ifndef NO_JPEG +#include /* Decode compressed Kodak DC120 photos */ +#endif /* and Adobe Lossy DNGs */ +#ifndef NO_LCMS +#include /* Support color profiles */ +#endif +#ifdef LOCALEDIR +#include +#define _(String) gettext(String) +#else +#define _(String) (String) +#endif + +#ifdef LJPEG_DECODE +#error Please compile dcraw.c by itself. +#error Do not link it with ljpeg_decode. +#endif + +#ifndef LONG_BIT +#define LONG_BIT (8 * sizeof (long)) +#endif + +#if !defined(uchar) +#define uchar unsigned char +#endif +#if !defined(ushort) +#define ushort unsigned short +#endif + +/* + All global variables are defined here, and all functions that + access them are prefixed with "CLASS". Note that a thread-safe + C++ class cannot have non-const static local variables. + */ +FILE *ifp, *ofp; +short order; +const char *ifname; +char *meta_data, xtrans[6][6], xtrans_abs[6][6]; +char cdesc[5], desc[512], make[64], model[64], model2[64], artist[64]; +float flash_used, canon_ev, iso_speed, shutter, aperture, focal_len; +time_t timestamp; +off_t strip_offset, data_offset; +off_t thumb_offset, meta_offset, profile_offset; +unsigned shot_order, kodak_cbpp, exif_cfa, unique_id; +unsigned thumb_length, meta_length, profile_length; +unsigned thumb_misc, *oprof, fuji_layout, shot_select=0, multi_out=0; +unsigned tiff_nifds, tiff_samples, tiff_bps, tiff_compress; +unsigned black, maximum, mix_green, raw_color, zero_is_bad; +unsigned zero_after_ff, is_raw, dng_version, is_foveon, data_error; +unsigned tile_width, tile_length, gpsdata[32], load_flags; +unsigned flip, tiff_flip, filters, colors; +ushort raw_height, raw_width, height, width, top_margin, left_margin; +ushort shrink, iheight, iwidth, fuji_width, thumb_width, thumb_height; +ushort *raw_image, (*image)[4], cblack[4102]; +ushort white[8][8], curve[0x10000], cr2_slice[3], sraw_mul[4]; +double pixel_aspect, aber[4]={1,1,1,1}, gamm[6]={ 0.45,4.5,0,0,0,0 }; +float bright=1, user_mul[4]={0,0,0,0}, threshold=0; +int mask[8][4]; +int half_size=0, four_color_rgb=0, document_mode=0, highlight=0; +int verbose=0, use_auto_wb=0, use_camera_wb=0, use_camera_matrix=1; +int output_color=1, output_bps=8, output_tiff=0, med_passes=0; +int no_auto_bright=0; +unsigned greybox[4] = { 0, 0, UINT_MAX, UINT_MAX }; +float cam_mul[4], pre_mul[4], cmatrix[3][4], rgb_cam[3][4]; +const double xyz_rgb[3][3] = { /* XYZ from RGB */ + { 0.412453, 0.357580, 0.180423 }, + { 0.212671, 0.715160, 0.072169 }, + { 0.019334, 0.119193, 0.950227 } }; +const float d65_white[3] = { 0.950456, 1, 1.088754 }; +int histogram[4][0x2000]; +void (*write_thumb)(), (*write_fun)(); +void (*load_raw)(), (*thumb_load_raw)(); +jmp_buf failure; + +struct decode { + struct decode *branch[2]; + int leaf; +} first_decode[2048], *second_decode, *free_decode; + +struct tiff_ifd { + int width, height, bps, comp, phint, offset, flip, samples, bytes; + int tile_width, tile_length; +} tiff_ifd[10]; + +struct ph1 { + int format, key_off, tag_21a; + int black, split_col, black_col, split_row, black_row; + float tag_210; +} ph1; + +#define CLASS + +#define FORC(cnt) for (c=0; c < cnt; c++) +#define FORC3 FORC(3) +#define FORC4 FORC(4) +#define FORCC FORC(colors) + +#define SQR(x) ((x)*(x)) +#define ABS(x) (((int)(x) ^ ((int)(x) >> 31)) - ((int)(x) >> 31)) +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#define LIM(x,min,max) MAX(min,MIN(x,max)) +#define ULIM(x,y,z) ((y) < (z) ? LIM(x,y,z) : LIM(x,z,y)) +#define CLIP(x) LIM(x,0,65535) +#define SWAP(a,b) { a=a+b; b=a-b; a=a-b; } + +/* + In order to inline this calculation, I make the risky + assumption that all filter patterns can be described + by a repeating pattern of eight rows and two columns + + Do not use the FC or BAYER macros with the Leaf CatchLight, + because its pattern is 16x16, not 2x8. + + Return values are either 0/1/2/3 = G/M/C/Y or 0/1/2/3 = R/G1/B/G2 + + PowerShot 600 PowerShot A50 PowerShot Pro70 Pro90 & G1 + 0xe1e4e1e4: 0x1b4e4b1e: 0x1e4b4e1b: 0xb4b4b4b4: + + 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 + 0 G M G M G M 0 C Y C Y C Y 0 Y C Y C Y C 0 G M G M G M + 1 C Y C Y C Y 1 M G M G M G 1 M G M G M G 1 Y C Y C Y C + 2 M G M G M G 2 Y C Y C Y C 2 C Y C Y C Y + 3 C Y C Y C Y 3 G M G M G M 3 G M G M G M + 4 C Y C Y C Y 4 Y C Y C Y C + PowerShot A5 5 G M G M G M 5 G M G M G M + 0x1e4e1e4e: 6 Y C Y C Y C 6 C Y C Y C Y + 7 M G M G M G 7 M G M G M G + 0 1 2 3 4 5 + 0 C Y C Y C Y + 1 G M G M G M + 2 C Y C Y C Y + 3 M G M G M G + + All RGB cameras use one of these Bayer grids: + + 0x16161616: 0x61616161: 0x49494949: 0x94949494: + + 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 + 0 B G B G B G 0 G R G R G R 0 G B G B G B 0 R G R G R G + 1 G R G R G R 1 B G B G B G 1 R G R G R G 1 G B G B G B + 2 B G B G B G 2 G R G R G R 2 G B G B G B 2 R G R G R G + 3 G R G R G R 3 B G B G B G 3 R G R G R G 3 G B G B G B + */ + +#define RAW(row,col) \ + raw_image[(row)*raw_width+(col)] + +#define FC(row,col) \ + (filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3) + +#define BAYER(row,col) \ + image[((row) >> shrink)*iwidth + ((col) >> shrink)][FC(row,col)] + +#define BAYER2(row,col) \ + image[((row) >> shrink)*iwidth + ((col) >> shrink)][fcol(row,col)] + +int CLASS fcol (int row, int col) +{ + static const char filter[16][16] = + { { 2,1,1,3,2,3,2,0,3,2,3,0,1,2,1,0 }, + { 0,3,0,2,0,1,3,1,0,1,1,2,0,3,3,2 }, + { 2,3,3,2,3,1,1,3,3,1,2,1,2,0,0,3 }, + { 0,1,0,1,0,2,0,2,2,0,3,0,1,3,2,1 }, + { 3,1,1,2,0,1,0,2,1,3,1,3,0,1,3,0 }, + { 2,0,0,3,3,2,3,1,2,0,2,0,3,2,2,1 }, + { 2,3,3,1,2,1,2,1,2,1,1,2,3,0,0,1 }, + { 1,0,0,2,3,0,0,3,0,3,0,3,2,1,2,3 }, + { 2,3,3,1,1,2,1,0,3,2,3,0,2,3,1,3 }, + { 1,0,2,0,3,0,3,2,0,1,1,2,0,1,0,2 }, + { 0,1,1,3,3,2,2,1,1,3,3,0,2,1,3,2 }, + { 2,3,2,0,0,1,3,0,2,0,1,2,3,0,1,0 }, + { 1,3,1,2,3,2,3,2,0,2,0,1,1,0,3,0 }, + { 0,2,0,3,1,0,0,1,1,3,3,2,3,2,2,1 }, + { 2,1,3,2,3,1,2,1,0,3,0,2,0,2,0,2 }, + { 0,3,1,0,0,2,0,3,2,1,3,1,1,3,1,3 } }; + + if (filters == 1) return filter[(row+top_margin)&15][(col+left_margin)&15]; + if (filters == 9) return xtrans[(row+6) % 6][(col+6) % 6]; + return FC(row,col); +} + +#ifndef __GLIBC__ +char *my_memmem (char *haystack, size_t haystacklen, + char *needle, size_t needlelen) +{ + char *c; + for (c = haystack; c <= haystack + haystacklen - needlelen; c++) + if (!memcmp (c, needle, needlelen)) + return c; + return 0; +} +#define memmem my_memmem +char *my_strcasestr (char *haystack, const char *needle) +{ + char *c; + for (c = haystack; *c; c++) + if (!strncasecmp(c, needle, strlen(needle))) + return c; + return 0; +} +#define strcasestr my_strcasestr +#endif + +void CLASS merror (void *ptr, const char *where) +{ + if (ptr) return; + fprintf (stderr,_("%s: Out of memory in %s\n"), ifname, where); + longjmp (failure, 1); +} + +void CLASS derror() +{ + if (!data_error) { + fprintf (stderr, "%s: ", ifname); + if (feof(ifp)) + fprintf (stderr,_("Unexpected end of file\n")); + else + fprintf (stderr,_("Corrupt data near 0x%llx\n"), (INT64) ftello(ifp)); + } + data_error++; +} + +ushort CLASS sget2 (uchar *s) +{ + if (order == 0x4949) /* "II" means little-endian */ + return s[0] | s[1] << 8; + else /* "MM" means big-endian */ + return s[0] << 8 | s[1]; +} + +ushort CLASS get2() +{ + uchar str[2] = { 0xff,0xff }; + fread (str, 1, 2, ifp); + return sget2(str); +} + +unsigned CLASS sget4 (uchar *s) +{ + if (order == 0x4949) + return s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24; + else + return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]; +} +#define sget4(s) sget4((uchar *)s) + +unsigned CLASS get4() +{ + uchar str[4] = { 0xff,0xff,0xff,0xff }; + fread (str, 1, 4, ifp); + return sget4(str); +} + +unsigned CLASS getint (int type) +{ + return type == 3 ? get2() : get4(); +} + +float CLASS int_to_float (int i) +{ + union { int i; float f; } u; + u.i = i; + return u.f; +} + +double CLASS getreal (int type) +{ + union { char c[8]; double d; } u; + int i, rev; + + switch (type) { + case 3: return (unsigned short) get2(); + case 4: return (unsigned int) get4(); + case 5: u.d = (unsigned int) get4(); + return u.d / (unsigned int) get4(); + case 8: return (signed short) get2(); + case 9: return (signed int) get4(); + case 10: u.d = (signed int) get4(); + return u.d / (signed int) get4(); + case 11: return int_to_float (get4()); + case 12: + rev = 7 * ((order == 0x4949) == (ntohs(0x1234) == 0x1234)); + for (i=0; i < 8; i++) + u.c[i ^ rev] = fgetc(ifp); + return u.d; + default: return fgetc(ifp); + } +} + +void CLASS read_shorts (ushort *pixel, int count) +{ + if (fread (pixel, 2, count, ifp) < count) derror(); + if ((order == 0x4949) == (ntohs(0x1234) == 0x1234)) + swab (pixel, pixel, count*2); +} + +void CLASS cubic_spline (const int *x_, const int *y_, const int len) +{ + float **A, *b, *c, *d, *x, *y; + int i, j; + + A = (float **) calloc (((2*len + 4)*sizeof **A + sizeof *A), 2*len); + if (!A) return; + A[0] = (float *) (A + 2*len); + for (i = 1; i < 2*len; i++) + A[i] = A[0] + 2*len*i; + y = len + (x = i + (d = i + (c = i + (b = A[0] + i*i)))); + for (i = 0; i < len; i++) { + x[i] = x_[i] / 65535.0; + y[i] = y_[i] / 65535.0; + } + for (i = len-1; i > 0; i--) { + b[i] = (y[i] - y[i-1]) / (x[i] - x[i-1]); + d[i-1] = x[i] - x[i-1]; + } + for (i = 1; i < len-1; i++) { + A[i][i] = 2 * (d[i-1] + d[i]); + if (i > 1) { + A[i][i-1] = d[i-1]; + A[i-1][i] = d[i-1]; + } + A[i][len-1] = 6 * (b[i+1] - b[i]); + } + for(i = 1; i < len-2; i++) { + float v = A[i+1][i] / A[i][i]; + for(j = 1; j <= len-1; j++) + A[i+1][j] -= v * A[i][j]; + } + for(i = len-2; i > 0; i--) { + float acc = 0; + for(j = i; j <= len-2; j++) + acc += A[i][j]*c[j]; + c[i] = (A[i][len-1] - acc) / A[i][i]; + } + for (i = 0; i < 0x10000; i++) { + float x_out = (float)(i / 65535.0); + float y_out = 0; + for (j = 0; j < len-1; j++) { + if (x[j] <= x_out && x_out <= x[j+1]) { + float v = x_out - x[j]; + y_out = y[j] + + ((y[j+1] - y[j]) / d[j] - (2 * d[j] * c[j] + c[j+1] * d[j])/6) * v + + (c[j] * 0.5) * v*v + ((c[j+1] - c[j]) / (6 * d[j])) * v*v*v; + } + } + curve[i] = y_out < 0.0 ? 0 : (y_out >= 1.0 ? 65535 : + (ushort)(y_out * 65535.0 + 0.5)); + } + free (A); +} + +void CLASS canon_600_fixed_wb (int temp) +{ + static const short mul[4][5] = { + { 667, 358,397,565,452 }, + { 731, 390,367,499,517 }, + { 1119, 396,348,448,537 }, + { 1399, 485,431,508,688 } }; + int lo, hi, i; + float frac=0; + + for (lo=4; --lo; ) + if (*mul[lo] <= temp) break; + for (hi=0; hi < 3; hi++) + if (*mul[hi] >= temp) break; + if (lo != hi) + frac = (float) (temp - *mul[lo]) / (*mul[hi] - *mul[lo]); + for (i=1; i < 5; i++) + pre_mul[i-1] = 1 / (frac * mul[hi][i] + (1-frac) * mul[lo][i]); +} + +/* Return values: 0 = white 1 = near white 2 = not white */ +int CLASS canon_600_color (int ratio[2], int mar) +{ + int clipped=0, target, miss; + + if (flash_used) { + if (ratio[1] < -104) + { ratio[1] = -104; clipped = 1; } + if (ratio[1] > 12) + { ratio[1] = 12; clipped = 1; } + } else { + if (ratio[1] < -264 || ratio[1] > 461) return 2; + if (ratio[1] < -50) + { ratio[1] = -50; clipped = 1; } + if (ratio[1] > 307) + { ratio[1] = 307; clipped = 1; } + } + target = flash_used || ratio[1] < 197 + ? -38 - (398 * ratio[1] >> 10) + : -123 + (48 * ratio[1] >> 10); + if (target - mar <= ratio[0] && + target + 20 >= ratio[0] && !clipped) return 0; + miss = target - ratio[0]; + if (abs(miss) >= mar*4) return 2; + if (miss < -20) miss = -20; + if (miss > mar) miss = mar; + ratio[0] = target - miss; + return 1; +} + +void CLASS canon_600_auto_wb() +{ + int mar, row, col, i, j, st, count[] = { 0,0 }; + int test[8], total[2][8], ratio[2][2], stat[2]; + + memset (&total, 0, sizeof total); + i = canon_ev + 0.5; + if (i < 10) mar = 150; + else if (i > 12) mar = 20; + else mar = 280 - 20 * i; + if (flash_used) mar = 80; + for (row=14; row < height-14; row+=4) + for (col=10; col < width; col+=2) { + for (i=0; i < 8; i++) + test[(i & 4) + FC(row+(i >> 1),col+(i & 1))] = + BAYER(row+(i >> 1),col+(i & 1)); + for (i=0; i < 8; i++) + if (test[i] < 150 || test[i] > 1500) goto next; + for (i=0; i < 4; i++) + if (abs(test[i] - test[i+4]) > 50) goto next; + for (i=0; i < 2; i++) { + for (j=0; j < 4; j+=2) + ratio[i][j >> 1] = ((test[i*4+j+1]-test[i*4+j]) << 10) / test[i*4+j]; + stat[i] = canon_600_color (ratio[i], mar); + } + if ((st = stat[0] | stat[1]) > 1) goto next; + for (i=0; i < 2; i++) + if (stat[i]) + for (j=0; j < 2; j++) + test[i*4+j*2+1] = test[i*4+j*2] * (0x400 + ratio[i][j]) >> 10; + for (i=0; i < 8; i++) + total[st][i] += test[i]; + count[st]++; +next: ; + } + if (count[0] | count[1]) { + st = count[0]*200 < count[1]; + for (i=0; i < 4; i++) + pre_mul[i] = 1.0 / (total[st][i] + total[st][i+4]); + } +} + +void CLASS canon_600_coeff() +{ + static const short table[6][12] = { + { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 }, + { -1203,1715,-1136,1648, 1388,-876,267,245, -1641,2153,3921,-3409 }, + { -615,1127,-1563,2075, 1437,-925,509,3, -756,1268,2519,-2007 }, + { -190,702,-1886,2398, 2153,-1641,763,-251, -452,964,3040,-2528 }, + { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 }, + { -807,1319,-1785,2297, 1388,-876,769,-257, -230,742,2067,-1555 } }; + int t=0, i, c; + float mc, yc; + + mc = pre_mul[1] / pre_mul[2]; + yc = pre_mul[3] / pre_mul[2]; + if (mc > 1 && mc <= 1.28 && yc < 0.8789) t=1; + if (mc > 1.28 && mc <= 2) { + if (yc < 0.8789) t=3; + else if (yc <= 2) t=4; + } + if (flash_used) t=5; + for (raw_color = i=0; i < 3; i++) + FORCC rgb_cam[i][c] = table[t][i*4 + c] / 1024.0; +} + +void CLASS canon_600_load_raw() +{ + uchar data[1120], *dp; + ushort *pix; + int irow, row; + + for (irow=row=0; irow < height; irow++) { + if (fread (data, 1, 1120, ifp) < 1120) derror(); + pix = raw_image + row*raw_width; + for (dp=data; dp < data+1120; dp+=10, pix+=8) { + pix[0] = (dp[0] << 2) + (dp[1] >> 6 ); + pix[1] = (dp[2] << 2) + (dp[1] >> 4 & 3); + pix[2] = (dp[3] << 2) + (dp[1] >> 2 & 3); + pix[3] = (dp[4] << 2) + (dp[1] & 3); + pix[4] = (dp[5] << 2) + (dp[9] & 3); + pix[5] = (dp[6] << 2) + (dp[9] >> 2 & 3); + pix[6] = (dp[7] << 2) + (dp[9] >> 4 & 3); + pix[7] = (dp[8] << 2) + (dp[9] >> 6 ); + } + if ((row+=2) > height) row = 1; + } +} + +void CLASS canon_600_correct() +{ + int row, col, val; + static const short mul[4][2] = + { { 1141,1145 }, { 1128,1109 }, { 1178,1149 }, { 1128,1109 } }; + + for (row=0; row < height; row++) + for (col=0; col < width; col++) { + if ((val = BAYER(row,col) - black) < 0) val = 0; + val = val * mul[row & 3][col & 1] >> 9; + BAYER(row,col) = val; + } + canon_600_fixed_wb(1311); + canon_600_auto_wb(); + canon_600_coeff(); + maximum = (0x3ff - black) * 1109 >> 9; + black = 0; +} + +int CLASS canon_s2is() +{ + unsigned row; + + for (row=0; row < 100; row++) { + fseek (ifp, row*3340 + 3284, SEEK_SET); + if (getc(ifp) > 15) return 1; + } + return 0; +} + +unsigned CLASS getbithuff (int nbits, ushort *huff) +{ + static unsigned bitbuf=0; + static int vbits=0, reset=0; + unsigned c; + + if (nbits > 25) return 0; + if (nbits < 0) + return bitbuf = vbits = reset = 0; + if (nbits == 0 || vbits < 0) return 0; + while (!reset && vbits < nbits && (c = fgetc(ifp)) != EOF && + !(reset = zero_after_ff && c == 0xff && fgetc(ifp))) { + bitbuf = (bitbuf << 8) + (uchar) c; + vbits += 8; + } + c = bitbuf << (32-vbits) >> (32-nbits); + if (huff) { + vbits -= huff[c] >> 8; + c = (uchar) huff[c]; + } else + vbits -= nbits; + if (vbits < 0) derror(); + return c; +} + +#define getbits(n) getbithuff(n,0) +#define gethuff(h) getbithuff(*h,h+1) + +/* + Construct a decode tree according the specification in *source. + The first 16 bytes specify how many codes should be 1-bit, 2-bit + 3-bit, etc. Bytes after that are the leaf values. + + For example, if the source is + + { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0, + 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff }, + + then the code is + + 00 0x04 + 010 0x03 + 011 0x05 + 100 0x06 + 101 0x02 + 1100 0x07 + 1101 0x01 + 11100 0x08 + 11101 0x09 + 11110 0x00 + 111110 0x0a + 1111110 0x0b + 1111111 0xff + */ +ushort * CLASS make_decoder_ref (const uchar **source) +{ + int max, len, h, i, j; + const uchar *count; + ushort *huff; + + count = (*source += 16) - 17; + for (max=16; max && !count[max]; max--); + huff = (ushort *) calloc (1 + (1 << max), sizeof *huff); + merror (huff, "make_decoder()"); + huff[0] = max; + for (h=len=1; len <= max; len++) + for (i=0; i < count[len]; i++, ++*source) + for (j=0; j < 1 << (max-len); j++) + if (h <= 1 << max) + huff[h++] = len << 8 | **source; + return huff; +} + +ushort * CLASS make_decoder (const uchar *source) +{ + return make_decoder_ref (&source); +} + +void CLASS crw_init_tables (unsigned table, ushort *huff[2]) +{ + static const uchar first_tree[3][29] = { + { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0, + 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff }, + { 0,2,2,3,1,1,1,1,2,0,0,0,0,0,0,0, + 0x03,0x02,0x04,0x01,0x05,0x00,0x06,0x07,0x09,0x08,0x0a,0x0b,0xff }, + { 0,0,6,3,1,1,2,0,0,0,0,0,0,0,0,0, + 0x06,0x05,0x07,0x04,0x08,0x03,0x09,0x02,0x00,0x0a,0x01,0x0b,0xff }, + }; + static const uchar second_tree[3][180] = { + { 0,2,2,2,1,4,2,1,2,5,1,1,0,0,0,139, + 0x03,0x04,0x02,0x05,0x01,0x06,0x07,0x08, + 0x12,0x13,0x11,0x14,0x09,0x15,0x22,0x00,0x21,0x16,0x0a,0xf0, + 0x23,0x17,0x24,0x31,0x32,0x18,0x19,0x33,0x25,0x41,0x34,0x42, + 0x35,0x51,0x36,0x37,0x38,0x29,0x79,0x26,0x1a,0x39,0x56,0x57, + 0x28,0x27,0x52,0x55,0x58,0x43,0x76,0x59,0x77,0x54,0x61,0xf9, + 0x71,0x78,0x75,0x96,0x97,0x49,0xb7,0x53,0xd7,0x74,0xb6,0x98, + 0x47,0x48,0x95,0x69,0x99,0x91,0xfa,0xb8,0x68,0xb5,0xb9,0xd6, + 0xf7,0xd8,0x67,0x46,0x45,0x94,0x89,0xf8,0x81,0xd5,0xf6,0xb4, + 0x88,0xb1,0x2a,0x44,0x72,0xd9,0x87,0x66,0xd4,0xf5,0x3a,0xa7, + 0x73,0xa9,0xa8,0x86,0x62,0xc7,0x65,0xc8,0xc9,0xa1,0xf4,0xd1, + 0xe9,0x5a,0x92,0x85,0xa6,0xe7,0x93,0xe8,0xc1,0xc6,0x7a,0x64, + 0xe1,0x4a,0x6a,0xe6,0xb3,0xf1,0xd3,0xa5,0x8a,0xb2,0x9a,0xba, + 0x84,0xa4,0x63,0xe5,0xc5,0xf3,0xd2,0xc4,0x82,0xaa,0xda,0xe4, + 0xf2,0xca,0x83,0xa3,0xa2,0xc3,0xea,0xc2,0xe2,0xe3,0xff,0xff }, + { 0,2,2,1,4,1,4,1,3,3,1,0,0,0,0,140, + 0x02,0x03,0x01,0x04,0x05,0x12,0x11,0x06, + 0x13,0x07,0x08,0x14,0x22,0x09,0x21,0x00,0x23,0x15,0x31,0x32, + 0x0a,0x16,0xf0,0x24,0x33,0x41,0x42,0x19,0x17,0x25,0x18,0x51, + 0x34,0x43,0x52,0x29,0x35,0x61,0x39,0x71,0x62,0x36,0x53,0x26, + 0x38,0x1a,0x37,0x81,0x27,0x91,0x79,0x55,0x45,0x28,0x72,0x59, + 0xa1,0xb1,0x44,0x69,0x54,0x58,0xd1,0xfa,0x57,0xe1,0xf1,0xb9, + 0x49,0x47,0x63,0x6a,0xf9,0x56,0x46,0xa8,0x2a,0x4a,0x78,0x99, + 0x3a,0x75,0x74,0x86,0x65,0xc1,0x76,0xb6,0x96,0xd6,0x89,0x85, + 0xc9,0xf5,0x95,0xb4,0xc7,0xf7,0x8a,0x97,0xb8,0x73,0xb7,0xd8, + 0xd9,0x87,0xa7,0x7a,0x48,0x82,0x84,0xea,0xf4,0xa6,0xc5,0x5a, + 0x94,0xa4,0xc6,0x92,0xc3,0x68,0xb5,0xc8,0xe4,0xe5,0xe6,0xe9, + 0xa2,0xa3,0xe3,0xc2,0x66,0x67,0x93,0xaa,0xd4,0xd5,0xe7,0xf8, + 0x88,0x9a,0xd7,0x77,0xc4,0x64,0xe2,0x98,0xa5,0xca,0xda,0xe8, + 0xf3,0xf6,0xa9,0xb2,0xb3,0xf2,0xd2,0x83,0xba,0xd3,0xff,0xff }, + { 0,0,6,2,1,3,3,2,5,1,2,2,8,10,0,117, + 0x04,0x05,0x03,0x06,0x02,0x07,0x01,0x08, + 0x09,0x12,0x13,0x14,0x11,0x15,0x0a,0x16,0x17,0xf0,0x00,0x22, + 0x21,0x18,0x23,0x19,0x24,0x32,0x31,0x25,0x33,0x38,0x37,0x34, + 0x35,0x36,0x39,0x79,0x57,0x58,0x59,0x28,0x56,0x78,0x27,0x41, + 0x29,0x77,0x26,0x42,0x76,0x99,0x1a,0x55,0x98,0x97,0xf9,0x48, + 0x54,0x96,0x89,0x47,0xb7,0x49,0xfa,0x75,0x68,0xb6,0x67,0x69, + 0xb9,0xb8,0xd8,0x52,0xd7,0x88,0xb5,0x74,0x51,0x46,0xd9,0xf8, + 0x3a,0xd6,0x87,0x45,0x7a,0x95,0xd5,0xf6,0x86,0xb4,0xa9,0x94, + 0x53,0x2a,0xa8,0x43,0xf5,0xf7,0xd4,0x66,0xa7,0x5a,0x44,0x8a, + 0xc9,0xe8,0xc8,0xe7,0x9a,0x6a,0x73,0x4a,0x61,0xc7,0xf4,0xc6, + 0x65,0xe9,0x72,0xe6,0x71,0x91,0x93,0xa6,0xda,0x92,0x85,0x62, + 0xf3,0xc5,0xb2,0xa4,0x84,0xba,0x64,0xa5,0xb3,0xd2,0x81,0xe5, + 0xd3,0xaa,0xc4,0xca,0xf2,0xb1,0xe4,0xd1,0x83,0x63,0xea,0xc3, + 0xe2,0x82,0xf1,0xa3,0xc2,0xa1,0xc1,0xe3,0xa2,0xe1,0xff,0xff } + }; + if (table > 2) table = 2; + huff[0] = make_decoder ( first_tree[table]); + huff[1] = make_decoder (second_tree[table]); +} + +/* + Return 0 if the image starts with compressed data, + 1 if it starts with uncompressed low-order bits. + + In Canon compressed data, 0xff is always followed by 0x00. + */ +int CLASS canon_has_lowbits() +{ + uchar test[0x4000]; + int ret=1, i; + + fseek (ifp, 0, SEEK_SET); + fread (test, 1, sizeof test, ifp); + for (i=540; i < sizeof test - 1; i++) + if (test[i] == 0xff) { + if (test[i+1]) return 1; + ret=0; + } + return ret; +} + +void CLASS canon_load_raw() +{ + ushort *pixel, *prow, *huff[2]; + int nblocks, lowbits, i, c, row, r, save, val; + int block, diffbuf[64], leaf, len, diff, carry=0, pnum=0, base[2]; + + crw_init_tables (tiff_compress, huff); + lowbits = canon_has_lowbits(); + if (!lowbits) maximum = 0x3ff; + fseek (ifp, 540 + lowbits*raw_height*raw_width/4, SEEK_SET); + zero_after_ff = 1; + getbits(-1); + for (row=0; row < raw_height; row+=8) { + pixel = raw_image + row*raw_width; + nblocks = MIN (8, raw_height-row) * raw_width >> 6; + for (block=0; block < nblocks; block++) { + memset (diffbuf, 0, sizeof diffbuf); + for (i=0; i < 64; i++ ) { + leaf = gethuff(huff[i > 0]); + if (leaf == 0 && i) break; + if (leaf == 0xff) continue; + i += leaf >> 4; + len = leaf & 15; + if (len == 0) continue; + diff = getbits(len); + if ((diff & (1 << (len-1))) == 0) + diff -= (1 << len) - 1; + if (i < 64) diffbuf[i] = diff; + } + diffbuf[0] += carry; + carry = diffbuf[0]; + for (i=0; i < 64; i++ ) { + if (pnum++ % raw_width == 0) + base[0] = base[1] = 512; + if ((pixel[(block << 6) + i] = base[i & 1] += diffbuf[i]) >> 10) + derror(); + } + } + if (lowbits) { + save = ftell(ifp); + fseek (ifp, 26 + row*raw_width/4, SEEK_SET); + for (prow=pixel, i=0; i < raw_width*2; i++) { + c = fgetc(ifp); + for (r=0; r < 8; r+=2, prow++) { + val = (*prow << 2) + ((c >> r) & 3); + if (raw_width == 2672 && val < 512) val += 2; + *prow = val; + } + } + fseek (ifp, save, SEEK_SET); + } + } + FORC(2) free (huff[c]); +} + +/* + Not a full implementation of Lossless JPEG, just + enough to decode Canon, Kodak and Adobe DNG images. + */ +struct jhead { + int bits, high, wide, clrs, sraw, psv, restart, vpred[6]; + ushort *huff[6], *free[4], *row; +}; + +int CLASS ljpeg_start (struct jhead *jh, int info_only) +{ + int c, tag, len; + uchar data[0x10000]; + const uchar *dp; + + memset (jh, 0, sizeof *jh); + jh->restart = INT_MAX; + fread (data, 2, 1, ifp); + if (data[1] != 0xd8) return 0; + do { + fread (data, 2, 2, ifp); + tag = data[0] << 8 | data[1]; + len = (data[2] << 8 | data[3]) - 2; + if (tag <= 0xff00) return 0; + fread (data, 1, len, ifp); + switch (tag) { + case 0xffc3: + jh->sraw = ((data[7] >> 4) * (data[7] & 15) - 1) & 3; + case 0xffc0: + jh->bits = data[0]; + jh->high = data[1] << 8 | data[2]; + jh->wide = data[3] << 8 | data[4]; + jh->clrs = data[5] + jh->sraw; + if (len == 9 && !dng_version) getc(ifp); + break; + case 0xffc4: + if (info_only) break; + for (dp = data; dp < data+len && (c = *dp++) < 4; ) + jh->free[c] = jh->huff[c] = make_decoder_ref (&dp); + break; + case 0xffda: + jh->psv = data[1+data[0]*2]; + jh->bits -= data[3+data[0]*2] & 15; + break; + case 0xffdd: + jh->restart = data[0] << 8 | data[1]; + } + } while (tag != 0xffda); + if (info_only) return 1; + if (jh->clrs > 6 || !jh->huff[0]) return 0; + FORC(5) if (!jh->huff[c+1]) jh->huff[c+1] = jh->huff[c]; + if (jh->sraw) { + FORC(4) jh->huff[2+c] = jh->huff[1]; + FORC(jh->sraw) jh->huff[1+c] = jh->huff[0]; + } + jh->row = (ushort *) calloc (jh->wide*jh->clrs, 4); + merror (jh->row, "ljpeg_start()"); + return zero_after_ff = 1; +} + +void CLASS ljpeg_end (struct jhead *jh) +{ + int c; + FORC4 if (jh->free[c]) free (jh->free[c]); + free (jh->row); +} + +int CLASS ljpeg_diff (ushort *huff) +{ + int len, diff; + + len = gethuff(huff); + if (len == 16 && (!dng_version || dng_version >= 0x1010000)) + return -32768; + diff = getbits(len); + if ((diff & (1 << (len-1))) == 0) + diff -= (1 << len) - 1; + return diff; +} + +ushort * CLASS ljpeg_row (int jrow, struct jhead *jh) +{ + int col, c, diff, pred, spred=0; + ushort mark=0, *row[3]; + + if (jrow * jh->wide % jh->restart == 0) { + FORC(6) jh->vpred[c] = 1 << (jh->bits-1); + if (jrow) { + fseek (ifp, -2, SEEK_CUR); + do mark = (mark << 8) + (c = fgetc(ifp)); + while (c != EOF && mark >> 4 != 0xffd); + } + getbits(-1); + } + FORC3 row[c] = jh->row + jh->wide*jh->clrs*((jrow+c) & 1); + for (col=0; col < jh->wide; col++) + FORC(jh->clrs) { + diff = ljpeg_diff (jh->huff[c]); + if (jh->sraw && c <= jh->sraw && (col | c)) + pred = spred; + else if (col) pred = row[0][-jh->clrs]; + else pred = (jh->vpred[c] += diff) - diff; + if (jrow && col) switch (jh->psv) { + case 1: break; + case 2: pred = row[1][0]; break; + case 3: pred = row[1][-jh->clrs]; break; + case 4: pred = pred + row[1][0] - row[1][-jh->clrs]; break; + case 5: pred = pred + ((row[1][0] - row[1][-jh->clrs]) >> 1); break; + case 6: pred = row[1][0] + ((pred - row[1][-jh->clrs]) >> 1); break; + case 7: pred = (pred + row[1][0]) >> 1; break; + default: pred = 0; + } + if ((**row = pred + diff) >> jh->bits) derror(); + if (c <= jh->sraw) spred = **row; + row[0]++; row[1]++; + } + return row[2]; +} + +void CLASS lossless_jpeg_load_raw() +{ + int jwide, jrow, jcol, val, jidx, i, j, row=0, col=0; + struct jhead jh; + ushort *rp; + + if (!ljpeg_start (&jh, 0)) return; + jwide = jh.wide * jh.clrs; + + for (jrow=0; jrow < jh.high; jrow++) { + rp = ljpeg_row (jrow, &jh); + if (load_flags & 1) + row = jrow & 1 ? height-1-jrow/2 : jrow/2; + for (jcol=0; jcol < jwide; jcol++) { + val = curve[*rp++]; + if (cr2_slice[0]) { + jidx = jrow*jwide + jcol; + i = jidx / (cr2_slice[1]*raw_height); + if ((j = i >= cr2_slice[0])) + i = cr2_slice[0]; + jidx -= i * (cr2_slice[1]*raw_height); + row = jidx / cr2_slice[1+j]; + col = jidx % cr2_slice[1+j] + i*cr2_slice[1]; + } + if (raw_width == 3984 && (col -= 2) < 0) + col += (row--,raw_width); + if ((unsigned) row < raw_height) RAW(row,col) = val; + if (++col >= raw_width) + col = (row++,0); + } + } + ljpeg_end (&jh); +} + +void CLASS canon_sraw_load_raw() +{ + struct jhead jh; + short *rp=0, (*ip)[4]; + int jwide, slice, scol, ecol, row, col, jrow=0, jcol=0, pix[3], c; + int v[3]={0,0,0}, ver, hue; + char *cp; + + if (!ljpeg_start (&jh, 0) || jh.clrs < 4) return; + jwide = (jh.wide >>= 1) * jh.clrs; + + for (ecol=slice=0; slice <= cr2_slice[0]; slice++) { + scol = ecol; + ecol += cr2_slice[1] * 2 / jh.clrs; + if (!cr2_slice[0] || ecol > raw_width-1) ecol = raw_width & -2; + for (row=0; row < height; row += (jh.clrs >> 1) - 1) { + ip = (short (*)[4]) image + row*width; + for (col=scol; col < ecol; col+=2, jcol+=jh.clrs) { + if ((jcol %= jwide) == 0) + rp = (short *) ljpeg_row (jrow++, &jh); + if (col >= width) continue; + FORC (jh.clrs-2) + ip[col + (c >> 1)*width + (c & 1)][0] = rp[jcol+c]; + ip[col][1] = rp[jcol+jh.clrs-2] - 16384; + ip[col][2] = rp[jcol+jh.clrs-1] - 16384; + } + } + } + for (cp=model2; *cp && !isdigit(*cp); cp++); + sscanf (cp, "%d.%d.%d", v, v+1, v+2); + ver = (v[0]*1000 + v[1])*1000 + v[2]; + hue = (jh.sraw+1) << 2; + if (unique_id >= 0x80000281 || (unique_id == 0x80000218 && ver > 1000006)) + hue = jh.sraw << 1; + ip = (short (*)[4]) image; + rp = ip[0]; + for (row=0; row < height; row++, ip+=width) { + if (row & (jh.sraw >> 1)) + for (col=0; col < width; col+=2) + for (c=1; c < 3; c++) + if (row == height-1) + ip[col][c] = ip[col-width][c]; + else ip[col][c] = (ip[col-width][c] + ip[col+width][c] + 1) >> 1; + for (col=1; col < width; col+=2) + for (c=1; c < 3; c++) + if (col == width-1) + ip[col][c] = ip[col-1][c]; + else ip[col][c] = (ip[col-1][c] + ip[col+1][c] + 1) >> 1; + } + for ( ; rp < ip[0]; rp+=4) { + if (unique_id == 0x80000218 || + unique_id == 0x80000250 || + unique_id == 0x80000261 || + unique_id == 0x80000281 || + unique_id == 0x80000287) { + rp[1] = (rp[1] << 2) + hue; + rp[2] = (rp[2] << 2) + hue; + pix[0] = rp[0] + (( 50*rp[1] + 22929*rp[2]) >> 14); + pix[1] = rp[0] + ((-5640*rp[1] - 11751*rp[2]) >> 14); + pix[2] = rp[0] + ((29040*rp[1] - 101*rp[2]) >> 14); + } else { + if (unique_id < 0x80000218) rp[0] -= 512; + pix[0] = rp[0] + rp[2]; + pix[2] = rp[0] + rp[1]; + pix[1] = rp[0] + ((-778*rp[1] - (rp[2] << 11)) >> 12); + } + FORC3 rp[c] = CLIP(pix[c] * sraw_mul[c] >> 10); + } + ljpeg_end (&jh); + maximum = 0x3fff; +} + +void CLASS adobe_copy_pixel (unsigned row, unsigned col, ushort **rp) +{ + int c; + + if (is_raw == 2 && shot_select) (*rp)++; + if (raw_image) { + if (row < raw_height && col < raw_width) + RAW(row,col) = curve[**rp]; + *rp += is_raw; + } else { + if (row < height && col < width) + FORC(tiff_samples) + image[row*width+col][c] = curve[(*rp)[c]]; + *rp += tiff_samples; + } + if (is_raw == 2 && shot_select) (*rp)--; +} + +void CLASS lossless_dng_load_raw() +{ + unsigned save, trow=0, tcol=0, jwide, jrow, jcol, row, col; + struct jhead jh; + ushort *rp; + + while (trow < raw_height) { + save = ftell(ifp); + if (tile_length < INT_MAX) + fseek (ifp, get4(), SEEK_SET); + if (!ljpeg_start (&jh, 0)) break; + jwide = jh.wide; + if (filters) jwide *= jh.clrs; + jwide /= is_raw; + for (row=col=jrow=0; jrow < jh.high; jrow++) { + rp = ljpeg_row (jrow, &jh); + for (jcol=0; jcol < jwide; jcol++) { + adobe_copy_pixel (trow+row, tcol+col, &rp); + if (++col >= tile_width || col >= raw_width) + row += 1 + (col = 0); + } + } + fseek (ifp, save+4, SEEK_SET); + if ((tcol += tile_width) >= raw_width) + trow += tile_length + (tcol = 0); + ljpeg_end (&jh); + } +} + +void CLASS packed_dng_load_raw() +{ + ushort *pixel, *rp; + int row, col; + + pixel = (ushort *) calloc (raw_width, tiff_samples*sizeof *pixel); + merror (pixel, "packed_dng_load_raw()"); + for (row=0; row < raw_height; row++) { + if (tiff_bps == 16) + read_shorts (pixel, raw_width * tiff_samples); + else { + getbits(-1); + for (col=0; col < raw_width * tiff_samples; col++) + pixel[col] = getbits(tiff_bps); + } + for (rp=pixel, col=0; col < raw_width; col++) + adobe_copy_pixel (row, col, &rp); + } + free (pixel); +} + +void CLASS pentax_load_raw() +{ + ushort bit[2][15], huff[4097]; + int dep, row, col, diff, c, i; + ushort vpred[2][2] = {{0,0},{0,0}}, hpred[2]; + + fseek (ifp, meta_offset, SEEK_SET); + dep = (get2() + 12) & 15; + fseek (ifp, 12, SEEK_CUR); + FORC(dep) bit[0][c] = get2(); + FORC(dep) bit[1][c] = fgetc(ifp); + FORC(dep) + for (i=bit[0][c]; i <= ((bit[0][c]+(4096 >> bit[1][c])-1) & 4095); ) + huff[++i] = bit[1][c] << 8 | c; + huff[0] = 12; + fseek (ifp, data_offset, SEEK_SET); + getbits(-1); + for (row=0; row < raw_height; row++) + for (col=0; col < raw_width; col++) { + diff = ljpeg_diff (huff); + if (col < 2) hpred[col] = vpred[row & 1][col] += diff; + else hpred[col & 1] += diff; + RAW(row,col) = hpred[col & 1]; + if (hpred[col & 1] >> tiff_bps) derror(); + } +} + +void CLASS nikon_load_raw() +{ + static const uchar nikon_tree[][32] = { + { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0, /* 12-bit lossy */ + 5,4,3,6,2,7,1,0,8,9,11,10,12 }, + { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0, /* 12-bit lossy after split */ + 0x39,0x5a,0x38,0x27,0x16,5,4,3,2,1,0,11,12,12 }, + { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0, /* 12-bit lossless */ + 5,4,6,3,7,2,8,1,9,0,10,11,12 }, + { 0,1,4,3,1,1,1,1,1,2,0,0,0,0,0,0, /* 14-bit lossy */ + 5,6,4,7,8,3,9,2,1,0,10,11,12,13,14 }, + { 0,1,5,1,1,1,1,1,1,1,2,0,0,0,0,0, /* 14-bit lossy after split */ + 8,0x5c,0x4b,0x3a,0x29,7,6,5,4,3,2,1,0,13,14 }, + { 0,1,4,2,2,3,1,2,0,0,0,0,0,0,0,0, /* 14-bit lossless */ + 7,6,8,5,9,4,10,3,11,12,2,0,1,13,14 } }; + ushort *huff, ver0, ver1, vpred[2][2], hpred[2], csize; + int i, min, max, step=0, tree=0, split=0, row, col, len, shl, diff; + + fseek (ifp, meta_offset, SEEK_SET); + ver0 = fgetc(ifp); + ver1 = fgetc(ifp); + if (ver0 == 0x49 || ver1 == 0x58) + fseek (ifp, 2110, SEEK_CUR); + if (ver0 == 0x46) tree = 2; + if (tiff_bps == 14) tree += 3; + read_shorts (vpred[0], 4); + max = 1 << tiff_bps & 0x7fff; + if ((csize = get2()) > 1) + step = max / (csize-1); + if (ver0 == 0x44 && ver1 == 0x20 && step > 0) { + for (i=0; i < csize; i++) + curve[i*step] = get2(); + for (i=0; i < max; i++) + curve[i] = ( curve[i-i%step]*(step-i%step) + + curve[i-i%step+step]*(i%step) ) / step; + fseek (ifp, meta_offset+562, SEEK_SET); + split = get2(); + } else if (ver0 != 0x46 && csize <= 0x4001) + read_shorts (curve, max=csize); + while (curve[max-2] == curve[max-1]) max--; + huff = make_decoder (nikon_tree[tree]); + fseek (ifp, data_offset, SEEK_SET); + getbits(-1); + for (min=row=0; row < height; row++) { + if (split && row == split) { + free (huff); + huff = make_decoder (nikon_tree[tree+1]); + max += (min = 16) << 1; + } + for (col=0; col < raw_width; col++) { + i = gethuff(huff); + len = i & 15; + shl = i >> 4; + diff = ((getbits(len-shl) << 1) + 1) << shl >> 1; + if ((diff & (1 << (len-1))) == 0) + diff -= (1 << len) - !shl; + if (col < 2) hpred[col] = vpred[row & 1][col] += diff; + else hpred[col & 1] += diff; + if ((ushort)(hpred[col & 1] + min) >= max) derror(); + RAW(row,col) = curve[LIM((short)hpred[col & 1],0,0x3fff)]; + } + } + free (huff); +} + +void CLASS nikon_yuv_load_raw() +{ + int row, col, yuv[4], rgb[3], b, c; + UINT64 bitbuf=0; + + for (row=0; row < raw_height; row++) + for (col=0; col < raw_width; col++) { + if (!(b = col & 1)) { + bitbuf = 0; + FORC(6) bitbuf |= (UINT64) fgetc(ifp) << c*8; + FORC(4) yuv[c] = (bitbuf >> c*12 & 0xfff) - (c >> 1 << 11); + } + rgb[0] = yuv[b] + 1.370705*yuv[3]; + rgb[1] = yuv[b] - 0.337633*yuv[2] - 0.698001*yuv[3]; + rgb[2] = yuv[b] + 1.732446*yuv[2]; + FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,0xfff)] / cam_mul[c]; + } +} + +/* + Returns 1 for a Coolpix 995, 0 for anything else. + */ +int CLASS nikon_e995() +{ + int i, histo[256]; + const uchar often[] = { 0x00, 0x55, 0xaa, 0xff }; + + memset (histo, 0, sizeof histo); + fseek (ifp, -2000, SEEK_END); + for (i=0; i < 2000; i++) + histo[fgetc(ifp)]++; + for (i=0; i < 4; i++) + if (histo[often[i]] < 200) + return 0; + return 1; +} + +/* + Returns 1 for a Coolpix 2100, 0 for anything else. + */ +int CLASS nikon_e2100() +{ + uchar t[12]; + int i; + + fseek (ifp, 0, SEEK_SET); + for (i=0; i < 1024; i++) { + fread (t, 1, 12, ifp); + if (((t[2] & t[4] & t[7] & t[9]) >> 4 + & t[1] & t[6] & t[8] & t[11] & 3) != 3) + return 0; + } + return 1; +} + +void CLASS nikon_3700() +{ + int bits, i; + uchar dp[24]; + static const struct { + int bits; + char make[12], model[15]; + } table[] = { + { 0x00, "Pentax", "Optio 33WR" }, + { 0x03, "Nikon", "E3200" }, + { 0x32, "Nikon", "E3700" }, + { 0x33, "Olympus", "C740UZ" } }; + + fseek (ifp, 3072, SEEK_SET); + fread (dp, 1, 24, ifp); + bits = (dp[8] & 3) << 4 | (dp[20] & 3); + for (i=0; i < sizeof table / sizeof *table; i++) + if (bits == table[i].bits) { + strcpy (make, table[i].make ); + strcpy (model, table[i].model); + } +} + +/* + Separates a Minolta DiMAGE Z2 from a Nikon E4300. + */ +int CLASS minolta_z2() +{ + int i, nz; + char tail[424]; + + fseek (ifp, -sizeof tail, SEEK_END); + fread (tail, 1, sizeof tail, ifp); + for (nz=i=0; i < sizeof tail; i++) + if (tail[i]) nz++; + return nz > 20; +} + +void CLASS jpeg_thumb(); + +void CLASS ppm_thumb() +{ + char *thumb; + thumb_length = thumb_width*thumb_height*3; + thumb = (char *) malloc (thumb_length); + merror (thumb, "ppm_thumb()"); + fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height); + fread (thumb, 1, thumb_length, ifp); + fwrite (thumb, 1, thumb_length, ofp); + free (thumb); +} + +void CLASS ppm16_thumb() +{ + int i; + char *thumb; + thumb_length = thumb_width*thumb_height*3; + thumb = (char *) calloc (thumb_length, 2); + merror (thumb, "ppm16_thumb()"); + read_shorts ((ushort *) thumb, thumb_length); + for (i=0; i < thumb_length; i++) + thumb[i] = ((ushort *) thumb)[i] >> 8; + fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height); + fwrite (thumb, 1, thumb_length, ofp); + free (thumb); +} + +void CLASS layer_thumb() +{ + int i, c; + char *thumb, map[][4] = { "012","102" }; + + colors = thumb_misc >> 5 & 7; + thumb_length = thumb_width*thumb_height; + thumb = (char *) calloc (colors, thumb_length); + merror (thumb, "layer_thumb()"); + fprintf (ofp, "P%d\n%d %d\n255\n", + 5 + (colors >> 1), thumb_width, thumb_height); + fread (thumb, thumb_length, colors, ifp); + for (i=0; i < thumb_length; i++) + FORCC putc (thumb[i+thumb_length*(map[thumb_misc >> 8][c]-'0')], ofp); + free (thumb); +} + +void CLASS rollei_thumb() +{ + unsigned i; + ushort *thumb; + + thumb_length = thumb_width * thumb_height; + thumb = (ushort *) calloc (thumb_length, 2); + merror (thumb, "rollei_thumb()"); + fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height); + read_shorts (thumb, thumb_length); + for (i=0; i < thumb_length; i++) { + putc (thumb[i] << 3, ofp); + putc (thumb[i] >> 5 << 2, ofp); + putc (thumb[i] >> 11 << 3, ofp); + } + free (thumb); +} + +void CLASS rollei_load_raw() +{ + uchar pixel[10]; + unsigned iten=0, isix, i, buffer=0, todo[16]; + + isix = raw_width * raw_height * 5 / 8; + while (fread (pixel, 1, 10, ifp) == 10) { + for (i=0; i < 10; i+=2) { + todo[i] = iten++; + todo[i+1] = pixel[i] << 8 | pixel[i+1]; + buffer = pixel[i] >> 2 | buffer << 6; + } + for ( ; i < 16; i+=2) { + todo[i] = isix++; + todo[i+1] = buffer >> (14-i)*5; + } + for (i=0; i < 16; i+=2) + raw_image[todo[i]] = (todo[i+1] & 0x3ff); + } + maximum = 0x3ff; +} + +int CLASS raw (unsigned row, unsigned col) +{ + return (row < raw_height && col < raw_width) ? RAW(row,col) : 0; +} + +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]; + + 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]; + } + } + 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; + + 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; + } + 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() +{ + int a, b, i; + ushort akey, bkey, mask; + + fseek (ifp, ph1.key_off, SEEK_SET); + akey = get2(); + bkey = get2(); + mask = ph1.format == 1 ? 0x5555:0x1354; + fseek (ifp, data_offset, SEEK_SET); + read_shorts (raw_image, raw_width*raw_height); + if (ph1.format) + for (i=0; i < raw_width*raw_height; i+=2) { + a = raw_image[i+0] ^ akey; + b = raw_image[i+1] ^ bkey; + raw_image[i+0] = (a & mask) | (b & ~mask); + raw_image[i+1] = (b & mask) | (a & ~mask); + } +} + +unsigned CLASS ph1_bithuff (int nbits, ushort *huff) +{ + static UINT64 bitbuf=0; + static int vbits=0; + unsigned c; + + if (nbits == -1) + return bitbuf = vbits = 0; + if (nbits == 0) return 0; + if (vbits < nbits) { + bitbuf = bitbuf << 32 | get4(); + vbits += 32; + } + c = bitbuf << (64-vbits) >> (64-nbits); + if (huff) { + vbits -= huff[c] >> 8; + return (uchar) huff[c]; + } + vbits -= nbits; + return c; +} +#define ph1_bits(n) ph1_bithuff(n,0) +#define ph1_huff(h) ph1_bithuff(*h,h+1) + +void CLASS phase_one_load_raw_c() +{ + static const int length[] = { 8,7,6,9,11,10,5,12,14,13 }; + int *offset, len[2], pred[2], row, col, i, j; + ushort *pixel; + short (*cblack)[2], (*rblack)[2]; + + pixel = (ushort *) calloc (raw_width*3 + raw_height*4, 2); + merror (pixel, "phase_one_load_raw_c()"); + offset = (int *) (pixel + raw_width); + fseek (ifp, strip_offset, SEEK_SET); + for (row=0; row < raw_height; row++) + offset[row] = get4(); + cblack = (short (*)[2]) (offset + raw_height); + fseek (ifp, ph1.black_col, SEEK_SET); + if (ph1.black_col) + read_shorts ((ushort *) cblack[0], raw_height*2); + rblack = cblack + raw_height; + fseek (ifp, ph1.black_row, SEEK_SET); + if (ph1.black_row) + read_shorts ((ushort *) rblack[0], raw_width*2); + for (i=0; i < 256; i++) + curve[i] = i*i / 3.969 + 0.5; + for (row=0; row < raw_height; row++) { + fseek (ifp, data_offset + offset[row], SEEK_SET); + ph1_bits(-1); + pred[0] = pred[1] = 0; + for (col=0; col < raw_width; col++) { + if (col >= (raw_width & -8)) + len[0] = len[1] = 14; + else if ((col & 7) == 0) + for (i=0; i < 2; i++) { + for (j=0; j < 5 && !ph1_bits(1); j++); + if (j--) len[i] = length[j*2 + ph1_bits(1)]; + } + if ((i = len[col & 1]) == 14) + pixel[col] = pred[col & 1] = ph1_bits(16); + else + pixel[col] = pred[col & 1] += ph1_bits(i) + 1 - (1 << (i - 1)); + if (pred[col & 1] >> 16) derror(); + if (ph1.format == 5 && pixel[col] < 256) + pixel[col] = curve[pixel[col]]; + } + for (col=0; col < raw_width; col++) { + i = (pixel[col] << 2) - ph1.black + + cblack[row][col >= ph1.split_col] + + rblack[col][row >= ph1.split_row]; + if (i > 0) RAW(row,col) = i; + } + } + free (pixel); + maximum = 0xfffc - ph1.black; +} + +void CLASS hasselblad_load_raw() +{ + struct jhead jh; + int shot, row, col, *back[5], len[2], diff[12], pred, sh, f, s, c; + unsigned upix, urow, ucol; + ushort *ip; + + if (!ljpeg_start (&jh, 0)) return; + order = 0x4949; + ph1_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; + cblack[6] >>= sh = tiff_samples > 1; + shot = LIM(shot_select, 1, tiff_samples) - 1; + for (row=0; row < raw_height; row++) { + FORC4 back[(c+3) & 3] = back[c]; + for (col=0; col < raw_width; col+=2) { + 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]); + 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; + } + } + for (s=col; s < col+2; s++) { + pred = 0x8000 + load_flags; + if (col) pred = back[2][s-2]; + if (col && row > 1) switch (jh.psv) { + case 11: pred += back[0][s]/2 - back[0][s-2]/2; break; + } + f = (row & 1)*3 ^ ((col+s) & 1); + FORC (tiff_samples) { + pred += diff[(s & 1)*tiff_samples+c]; + upix = pred >> sh & 0xffff; + if (raw_image && c == shot) + RAW(row,s) = upix; + if (image) { + urow = row-top_margin + (c & 1); + ucol = col-left_margin - ((c >> 1) & 1); + ip = &image[urow*width+ucol][f]; + if (urow < height && ucol < width) + *ip = c < 4 ? upix : (*ip + upix) >> 1; + } + } + back[2][s] = pred; + } + } + } + free (back[4]); + ljpeg_end (&jh); + if (image) mix_green = 1; +} + +void CLASS leaf_hdr_load_raw() +{ + ushort *pixel=0; + unsigned tile=0, r, c, row, col; + + if (!filters) { + pixel = (ushort *) calloc (raw_width, sizeof *pixel); + merror (pixel, "leaf_hdr_load_raw()"); + } + FORC(tiff_samples) + for (r=0; r < raw_height; r++) { + if (r % tile_length == 0) { + fseek (ifp, data_offset + 4*tile++, SEEK_SET); + fseek (ifp, get4(), SEEK_SET); + } + if (filters && c != shot_select) continue; + if (filters) pixel = raw_image + r*raw_width; + read_shorts (pixel, raw_width); + if (!filters && (row = r - top_margin) < height) + for (col=0; col < width; col++) + image[row*width+col][c] = pixel[col+left_margin]; + } + if (!filters) { + maximum = 0xffff; + raw_color = 1; + free (pixel); + } +} + +void CLASS unpacked_load_raw() +{ + int row, col, bits=0; + + while (1 << ++bits < maximum); + read_shorts (raw_image, raw_width*raw_height); + for (row=0; row < raw_height; row++) + for (col=0; col < raw_width; col++) + if ((RAW(row,col) >>= load_flags) >> bits + && (unsigned) (row-top_margin) < height + && (unsigned) (col-left_margin) < width) derror(); +} + +void CLASS sinar_4shot_load_raw() +{ + ushort *pixel; + unsigned shot, row, col, r, c; + + if (raw_image) { + shot = LIM (shot_select, 1, 4) - 1; + fseek (ifp, data_offset + shot*4, SEEK_SET); + fseek (ifp, get4(), SEEK_SET); + unpacked_load_raw(); + return; + } + pixel = (ushort *) calloc (raw_width, sizeof *pixel); + merror (pixel, "sinar_4shot_load_raw()"); + for (shot=0; shot < 4; shot++) { + fseek (ifp, data_offset + shot*4, SEEK_SET); + fseek (ifp, get4(), SEEK_SET); + for (row=0; row < raw_height; row++) { + read_shorts (pixel, raw_width); + if ((r = row-top_margin - (shot >> 1 & 1)) >= height) continue; + for (col=0; col < raw_width; col++) { + if ((c = col-left_margin - (shot & 1)) >= width) continue; + image[r*width+c][(row & 1)*3 ^ (~col & 1)] = pixel[col]; + } + } + } + free (pixel); + mix_green = 1; +} + +void CLASS imacon_full_load_raw() +{ + int row, col; + + if (!image) return; + for (row=0; row < height; row++) + for (col=0; col < width; col++) + read_shorts (image[row*width+col], 3); +} + +void CLASS packed_load_raw() +{ + int vbits=0, bwide, rbits, bite, half, irow, row, col, val, i; + UINT64 bitbuf=0; + + bwide = raw_width * tiff_bps / 8; + bwide += bwide & load_flags >> 7; + rbits = bwide * 8 - raw_width * tiff_bps; + if (load_flags & 1) bwide = bwide * 16 / 15; + bite = 8 + (load_flags & 24); + half = (raw_height+1) >> 1; + for (irow=0; irow < raw_height; irow++) { + row = irow; + if (load_flags & 2 && + (row = irow % half * 2 + irow / half) == 1 && + load_flags & 4) { + if (vbits=0, tiff_compress) + fseek (ifp, data_offset - (-half*bwide & -2048), SEEK_SET); + else { + fseek (ifp, 0, SEEK_END); + fseek (ifp, ftell(ifp) >> 3 << 2, SEEK_SET); + } + } + for (col=0; col < raw_width; col++) { + for (vbits -= tiff_bps; vbits < 0; vbits += bite) { + bitbuf <<= bite; + for (i=0; i < bite; i+=8) + bitbuf |= (unsigned) (fgetc(ifp) << i); + } + val = bitbuf << (64-tiff_bps-vbits) >> (64-tiff_bps); + RAW(row,col ^ (load_flags >> 6 & 1)) = val; + if (load_flags & 1 && (col % 10) == 9 && fgetc(ifp) && + row < height+top_margin && col < width+left_margin) derror(); + } + vbits -= rbits; + } +} + +void CLASS nokia_load_raw() +{ + uchar *data, *dp; + int rev, dwide, row, col, c; + double sum[]={0,0}; + + rev = 3 * (order == 0x4949); + dwide = (raw_width * 5 + 1) / 4; + data = (uchar *) malloc (dwide*2); + merror (data, "nokia_load_raw()"); + for (row=0; row < raw_height; row++) { + if (fread (data+dwide, 1, dwide, ifp) < dwide) derror(); + FORC(dwide) data[c] = data[dwide+(c ^ rev)]; + for (dp=data, col=0; col < raw_width; dp+=5, col+=4) + FORC4 RAW(row,col+c) = (dp[c] << 2) | (dp[4] >> (c << 1) & 3); + } + free (data); + maximum = 0x3ff; + if (strcmp(make,"OmniVision")) return; + row = raw_height/2; + FORC(width-1) { + sum[ c & 1] += SQR(RAW(row,c)-RAW(row+1,c+1)); + sum[~c & 1] += SQR(RAW(row+1,c)-RAW(row,c+1)); + } + if (sum[1] > sum[0]) filters = 0x4b4b4b4b; +} + +void CLASS canon_rmf_load_raw() +{ + int row, col, bits, orow, ocol, c; + + for (row=0; row < raw_height; row++) + for (col=0; col < raw_width-2; col+=3) { + bits = get4(); + FORC3 { + orow = row; + if ((ocol = col+c-4) < 0) { + ocol += raw_width; + if ((orow -= 2) < 0) + orow += raw_height; + } + RAW(orow,ocol) = curve[bits >> (10*c+2) & 0x3ff]; + } + } + maximum = curve[0x3ff]; +} + +unsigned CLASS pana_bits (int nbits) +{ + static uchar buf[0x4000]; + static int vbits; + int byte; + + if (!nbits) return vbits=0; + if (!vbits) { + fread (buf+load_flags, 1, 0x4000-load_flags, ifp); + fread (buf, 1, load_flags, ifp); + } + vbits = (vbits - nbits) & 0x1ffff; + byte = vbits >> 3 ^ 0x3ff0; + return (buf[byte] | buf[byte+1] << 8) >> (vbits & 7) & ~(-1 << nbits); +} + +void CLASS panasonic_load_raw() +{ + int row, col, i, j, sh=0, pred[2], nonz[2]; + + pana_bits(0); + for (row=0; row < height; row++) + for (col=0; col < raw_width; col++) { + if ((i = col % 14) == 0) + pred[0] = pred[1] = nonz[0] = nonz[1] = 0; + if (i % 3 == 2) sh = 4 >> (3 - pana_bits(2)); + if (nonz[i & 1]) { + if ((j = pana_bits(8))) { + if ((pred[i & 1] -= 0x80 << sh) < 0 || sh == 4) + pred[i & 1] &= ~(-1 << sh); + pred[i & 1] += j << sh; + } + } else if ((nonz[i & 1] = pana_bits(8)) || i > 11) + pred[i & 1] = nonz[i & 1] << 4 | pana_bits(4); + if ((RAW(row,col) = pred[col & 1]) > 4098 && col < width) derror(); + } +} + +void CLASS olympus_load_raw() +{ + ushort huff[4096]; + int row, col, nbits, sign, low, high, i, c, w, n, nw; + int acarry[2][3], *carry, pred, diff; + + huff[n=0] = 0xc0c; + for (i=12; i--; ) + FORC(2048 >> i) huff[++n] = (i+1) << 8 | i; + fseek (ifp, 7, SEEK_CUR); + getbits(-1); + for (row=0; row < height; row++) { + memset (acarry, 0, sizeof acarry); + for (col=0; col < raw_width; col++) { + carry = acarry[col & 1]; + i = 2 * (carry[2] < 3); + for (nbits=2+i; (ushort) carry[0] >> (nbits+i); nbits++); + low = (sign = getbits(3)) & 3; + sign = sign << 29 >> 31; + if ((high = getbithuff(12,huff)) == 12) + high = getbits(16-nbits) >> 1; + carry[0] = (high << nbits) | getbits(nbits); + diff = (carry[0] ^ sign) + carry[1]; + carry[1] = (diff*3 + carry[1]) >> 5; + carry[2] = carry[0] > 16 ? 0 : carry[2]+1; + if (col >= width) continue; + if (row < 2 && col < 2) pred = 0; + else if (row < 2) pred = RAW(row,col-2); + else if (col < 2) pred = RAW(row-2,col); + else { + w = RAW(row,col-2); + n = RAW(row-2,col); + nw = RAW(row-2,col-2); + if ((w < nw && nw < n) || (n < nw && nw < w)) { + if (ABS(w-nw) > 32 || ABS(n-nw) > 32) + pred = w + n - nw; + else pred = (w + n) >> 1; + } else pred = ABS(w-nw) > ABS(n-nw) ? w : n; + } + if ((RAW(row,col) = pred + ((diff << 2) | low)) >> 12) derror(); + } + } +} + +void CLASS minolta_rd175_load_raw() +{ + uchar pixel[768]; + unsigned irow, box, row, col; + + for (irow=0; irow < 1481; irow++) { + if (fread (pixel, 1, 768, ifp) < 768) derror(); + box = irow / 82; + row = irow % 82 * 12 + ((box < 12) ? box | 1 : (box-12)*2); + switch (irow) { + case 1477: case 1479: continue; + case 1476: row = 984; break; + case 1480: row = 985; break; + case 1478: row = 985; box = 1; + } + if ((box < 12) && (box & 1)) { + for (col=0; col < 1533; col++, row ^= 1) + if (col != 1) RAW(row,col) = (col+1) & 2 ? + pixel[col/2-1] + pixel[col/2+1] : pixel[col/2] << 1; + RAW(row,1) = pixel[1] << 1; + RAW(row,1533) = pixel[765] << 1; + } else + for (col=row & 1; col < 1534; col+=2) + RAW(row,col) = pixel[col/2] << 1; + } + maximum = 0xff << 1; +} + +void CLASS quicktake_100_load_raw() +{ + uchar pixel[484][644]; + static const short gstep[16] = + { -89,-60,-44,-32,-22,-15,-8,-2,2,8,15,22,32,44,60,89 }; + static const short rstep[6][4] = + { { -3,-1,1,3 }, { -5,-1,1,5 }, { -8,-2,2,8 }, + { -13,-3,3,13 }, { -19,-4,4,19 }, { -28,-6,6,28 } }; + static const short curve[256] = + { 0,1,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27, + 28,29,30,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,53, + 54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,74,75,76,77,78, + 79,80,81,82,83,84,86,88,90,92,94,97,99,101,103,105,107,110,112,114,116, + 118,120,123,125,127,129,131,134,136,138,140,142,144,147,149,151,153,155, + 158,160,162,164,166,168,171,173,175,177,179,181,184,186,188,190,192,195, + 197,199,201,203,205,208,210,212,214,216,218,221,223,226,230,235,239,244, + 248,252,257,261,265,270,274,278,283,287,291,296,300,305,309,313,318,322, + 326,331,335,339,344,348,352,357,361,365,370,374,379,383,387,392,396,400, + 405,409,413,418,422,426,431,435,440,444,448,453,457,461,466,470,474,479, + 483,487,492,496,500,508,519,531,542,553,564,575,587,598,609,620,631,643, + 654,665,676,687,698,710,721,732,743,754,766,777,788,799,810,822,833,844, + 855,866,878,889,900,911,922,933,945,956,967,978,989,1001,1012,1023 }; + int rb, row, col, sharp, val=0; + + getbits(-1); + memset (pixel, 0x80, sizeof pixel); + for (row=2; row < height+2; row++) { + for (col=2+(row & 1); col < width+2; col+=2) { + val = ((pixel[row-1][col-1] + 2*pixel[row-1][col+1] + + pixel[row][col-2]) >> 2) + gstep[getbits(4)]; + pixel[row][col] = val = LIM(val,0,255); + if (col < 4) + pixel[row][col-2] = pixel[row+1][~row & 1] = val; + if (row == 2) + pixel[row-1][col+1] = pixel[row-1][col+3] = val; + } + pixel[row][col] = val; + } + for (rb=0; rb < 2; rb++) + for (row=2+rb; row < height+2; row+=2) + for (col=3-(row & 1); col < width+2; col+=2) { + if (row < 4 || col < 4) sharp = 2; + else { + val = ABS(pixel[row-2][col] - pixel[row][col-2]) + + ABS(pixel[row-2][col] - pixel[row-2][col-2]) + + ABS(pixel[row][col-2] - pixel[row-2][col-2]); + sharp = val < 4 ? 0 : val < 8 ? 1 : val < 16 ? 2 : + val < 32 ? 3 : val < 48 ? 4 : 5; + } + val = ((pixel[row-2][col] + pixel[row][col-2]) >> 1) + + rstep[sharp][getbits(2)]; + pixel[row][col] = val = LIM(val,0,255); + if (row < 4) pixel[row-2][col+2] = val; + if (col < 4) pixel[row+2][col-2] = val; + } + for (row=2; row < height+2; row++) + for (col=3-(row & 1); col < width+2; col+=2) { + val = ((pixel[row][col-1] + (pixel[row][col] << 2) + + pixel[row][col+1]) >> 1) - 0x100; + pixel[row][col] = LIM(val,0,255); + } + for (row=0; row < height; row++) + for (col=0; col < width; col++) + RAW(row,col) = curve[pixel[row+2][col+2]]; + maximum = 0x3ff; +} + +#define radc_token(tree) ((signed char) getbithuff(8,huff[tree])) + +#define FORYX for (y=1; y < 3; y++) for (x=col+1; x >= col; x--) + +#define PREDICTOR (c ? (buf[c][y-1][x] + buf[c][y][x+1]) / 2 \ +: (buf[c][y-1][x+1] + 2*buf[c][y-1][x] + buf[c][y][x+1]) / 4) + +void CLASS kodak_radc_load_raw() +{ + static const char src[] = { + 1,1, 2,3, 3,4, 4,2, 5,7, 6,5, 7,6, 7,8, + 1,0, 2,1, 3,3, 4,4, 5,2, 6,7, 7,6, 8,5, 8,8, + 2,1, 2,3, 3,0, 3,2, 3,4, 4,6, 5,5, 6,7, 6,8, + 2,0, 2,1, 2,3, 3,2, 4,4, 5,6, 6,7, 7,5, 7,8, + 2,1, 2,4, 3,0, 3,2, 3,3, 4,7, 5,5, 6,6, 6,8, + 2,3, 3,1, 3,2, 3,4, 3,5, 3,6, 4,7, 5,0, 5,8, + 2,3, 2,6, 3,0, 3,1, 4,4, 4,5, 4,7, 5,2, 5,8, + 2,4, 2,7, 3,3, 3,6, 4,1, 4,2, 4,5, 5,0, 5,8, + 2,6, 3,1, 3,3, 3,5, 3,7, 3,8, 4,0, 5,2, 5,4, + 2,0, 2,1, 3,2, 3,3, 4,4, 4,5, 5,6, 5,7, 4,8, + 1,0, 2,2, 2,-2, + 1,-3, 1,3, + 2,-17, 2,-5, 2,5, 2,17, + 2,-7, 2,2, 2,9, 2,18, + 2,-18, 2,-9, 2,-2, 2,7, + 2,-28, 2,28, 3,-49, 3,-9, 3,9, 4,49, 5,-79, 5,79, + 2,-1, 2,13, 2,26, 3,39, 4,-16, 5,55, 6,-37, 6,76, + 2,-26, 2,-13, 2,1, 3,-39, 4,16, 5,-55, 6,-76, 6,37 + }; + ushort huff[19][256]; + int row, col, tree, nreps, rep, step, i, c, s, r, x, y, val; + short last[3] = { 16,16,16 }, mul[3], buf[3][3][386]; + static const ushort pt[] = + { 0,0, 1280,1344, 2320,3616, 3328,8000, 4095,16383, 65535,16383 }; + + for (i=2; i < 12; i+=2) + for (c=pt[i-2]; c <= pt[i]; c++) + curve[c] = (float) + (c-pt[i-2]) / (pt[i]-pt[i-2]) * (pt[i+1]-pt[i-1]) + pt[i-1] + 0.5; + for (s=i=0; i < sizeof src; i+=2) + FORC(256 >> src[i]) + ((ushort *)huff)[s++] = src[i] << 8 | (uchar) src[i+1]; + s = kodak_cbpp == 243 ? 2 : 3; + FORC(256) huff[18][c] = (8-s) << 8 | c >> s << s | 1 << (s-1); + getbits(-1); + for (i=0; i < sizeof(buf)/sizeof(short); i++) + ((short *)buf)[i] = 2048; + for (row=0; row < height; row+=4) { + FORC3 mul[c] = getbits(6); + FORC3 { + val = ((0x1000000/last[c] + 0x7ff) >> 12) * mul[c]; + s = val > 65564 ? 10:12; + x = ~(-1 << (s-1)); + val <<= 12-s; + for (i=0; i < sizeof(buf[0])/sizeof(short); i++) + ((short *)buf[c])[i] = (((short *)buf[c])[i] * val + x) >> s; + last[c] = mul[c]; + for (r=0; r <= !c; r++) { + buf[c][1][width/2] = buf[c][2][width/2] = mul[c] << 7; + for (tree=1, col=width/2; col > 0; ) { + if ((tree = radc_token(tree))) { + col -= 2; + if (tree == 8) + FORYX buf[c][y][x] = (uchar) radc_token(18) * mul[c]; + else + FORYX buf[c][y][x] = radc_token(tree+10) * 16 + PREDICTOR; + } else + do { + nreps = (col > 2) ? radc_token(9) + 1 : 1; + for (rep=0; rep < 8 && rep < nreps && col > 0; rep++) { + col -= 2; + FORYX buf[c][y][x] = PREDICTOR; + if (rep & 1) { + step = radc_token(10) << 4; + FORYX buf[c][y][x] += step; + } + } + } while (nreps == 9); + } + for (y=0; y < 2; y++) + for (x=0; x < width/2; x++) { + val = (buf[c][y+1][x] << 4) / mul[c]; + if (val < 0) val = 0; + if (c) RAW(row+y*2+c-1,x*2+2-c) = val; + else RAW(row+r*2+y,x*2+y) = val; + } + memcpy (buf[c][0]+!c, buf[c][2], sizeof buf[c][0]-2*!c); + } + } + for (y=row; y < row+4; y++) + for (x=0; x < width; x++) + if ((x+y) & 1) { + r = x ? x-1 : x+1; + s = x+1 < width ? x+1 : x-1; + val = (RAW(y,x)-2048)*2 + (RAW(y,r)+RAW(y,s))/2; + if (val < 0) val = 0; + RAW(y,x) = val; + } + } + for (i=0; i < height*width; i++) + raw_image[i] = curve[raw_image[i]]; + maximum = 0x3fff; +} + +#undef FORYX +#undef PREDICTOR + +#ifdef NO_JPEG +void CLASS kodak_jpeg_load_raw() {} +void CLASS lossy_dng_load_raw() {} +#else + +METHODDEF(boolean) +fill_input_buffer (j_decompress_ptr cinfo) +{ + static uchar jpeg_buffer[4096]; + size_t nbytes; + + nbytes = fread (jpeg_buffer, 1, 4096, ifp); + swab (jpeg_buffer, jpeg_buffer, nbytes); + cinfo->src->next_input_byte = jpeg_buffer; + cinfo->src->bytes_in_buffer = nbytes; + return TRUE; +} + +void CLASS kodak_jpeg_load_raw() +{ + struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr jerr; + JSAMPARRAY buf; + JSAMPLE (*pixel)[3]; + int row, col; + + cinfo.err = jpeg_std_error (&jerr); + jpeg_create_decompress (&cinfo); + jpeg_stdio_src (&cinfo, ifp); + cinfo.src->fill_input_buffer = fill_input_buffer; + jpeg_read_header (&cinfo, TRUE); + jpeg_start_decompress (&cinfo); + if ((cinfo.output_width != width ) || + (cinfo.output_height*2 != height ) || + (cinfo.output_components != 3 )) { + fprintf (stderr,_("%s: incorrect JPEG dimensions\n"), ifname); + jpeg_destroy_decompress (&cinfo); + longjmp (failure, 3); + } + buf = (*cinfo.mem->alloc_sarray) + ((j_common_ptr) &cinfo, JPOOL_IMAGE, width*3, 1); + + while (cinfo.output_scanline < cinfo.output_height) { + row = cinfo.output_scanline * 2; + jpeg_read_scanlines (&cinfo, buf, 1); + pixel = (JSAMPLE (*)[3]) buf[0]; + for (col=0; col < width; col+=2) { + RAW(row+0,col+0) = pixel[col+0][1] << 1; + RAW(row+1,col+1) = pixel[col+1][1] << 1; + RAW(row+0,col+1) = pixel[col][0] + pixel[col+1][0]; + RAW(row+1,col+0) = pixel[col][2] + pixel[col+1][2]; + } + } + jpeg_finish_decompress (&cinfo); + jpeg_destroy_decompress (&cinfo); + maximum = 0xff << 1; +} + +void CLASS gamma_curve (double pwr, double ts, int mode, int imax); + +void CLASS lossy_dng_load_raw() +{ + struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr jerr; + JSAMPARRAY buf; + JSAMPLE (*pixel)[3]; + unsigned sorder=order, ntags, opcode, deg, i, j, c; + unsigned save=data_offset-4, trow=0, tcol=0, row, col; + ushort cur[3][256]; + double coeff[9], tot; + + if (meta_offset) { + fseek (ifp, meta_offset, SEEK_SET); + order = 0x4d4d; + ntags = get4(); + while (ntags--) { + opcode = get4(); get4(); get4(); + if (opcode != 8) + { fseek (ifp, get4(), SEEK_CUR); continue; } + fseek (ifp, 20, SEEK_CUR); + if ((c = get4()) > 2) break; + fseek (ifp, 12, SEEK_CUR); + if ((deg = get4()) > 8) break; + for (i=0; i <= deg && i < 9; i++) + coeff[i] = getreal(12); + for (i=0; i < 256; i++) { + for (tot=j=0; j <= deg; j++) + tot += coeff[j] * pow(i/255.0, j); + cur[c][i] = tot*0xffff; + } + } + order = sorder; + } else { + gamma_curve (1/2.4, 12.92, 1, 255); + FORC3 memcpy (cur[c], curve, sizeof cur[0]); + } + cinfo.err = jpeg_std_error (&jerr); + jpeg_create_decompress (&cinfo); + while (trow < raw_height) { + fseek (ifp, save+=4, SEEK_SET); + if (tile_length < INT_MAX) + fseek (ifp, get4(), SEEK_SET); + jpeg_stdio_src (&cinfo, ifp); + jpeg_read_header (&cinfo, TRUE); + jpeg_start_decompress (&cinfo); + buf = (*cinfo.mem->alloc_sarray) + ((j_common_ptr) &cinfo, JPOOL_IMAGE, cinfo.output_width*3, 1); + while (cinfo.output_scanline < cinfo.output_height && + (row = trow + cinfo.output_scanline) < height) { + jpeg_read_scanlines (&cinfo, buf, 1); + pixel = (JSAMPLE (*)[3]) buf[0]; + for (col=0; col < cinfo.output_width && tcol+col < width; col++) { + FORC3 image[row*width+tcol+col][c] = cur[c][pixel[col][c]]; + } + } + jpeg_abort_decompress (&cinfo); + if ((tcol += tile_width) >= raw_width) + trow += tile_length + (tcol = 0); + } + jpeg_destroy_decompress (&cinfo); + maximum = 0xffff; +} +#endif + +void CLASS kodak_dc120_load_raw() +{ + static const int mul[4] = { 162, 192, 187, 92 }; + static const int add[4] = { 0, 636, 424, 212 }; + uchar pixel[848]; + int row, shift, col; + + for (row=0; row < height; row++) { + if (fread (pixel, 1, 848, ifp) < 848) derror(); + shift = row * mul[row & 3] + add[row & 3]; + for (col=0; col < width; col++) + RAW(row,col) = (ushort) pixel[(col + shift) % 848]; + } + maximum = 0xff; +} + +void CLASS eight_bit_load_raw() +{ + uchar *pixel; + unsigned row, col; + + pixel = (uchar *) calloc (raw_width, sizeof *pixel); + merror (pixel, "eight_bit_load_raw()"); + for (row=0; row < raw_height; row++) { + if (fread (pixel, 1, raw_width, ifp) < raw_width) derror(); + for (col=0; col < raw_width; col++) + RAW(row,col) = curve[pixel[col]]; + } + free (pixel); + maximum = curve[0xff]; +} + +void CLASS kodak_c330_load_raw() +{ + uchar *pixel; + int row, col, y, cb, cr, rgb[3], c; + + pixel = (uchar *) calloc (raw_width, 2*sizeof *pixel); + merror (pixel, "kodak_c330_load_raw()"); + for (row=0; row < height; row++) { + if (fread (pixel, raw_width, 2, ifp) < 2) derror(); + if (load_flags && (row & 31) == 31) + fseek (ifp, raw_width*32, SEEK_CUR); + for (col=0; col < width; col++) { + y = pixel[col*2]; + cb = pixel[(col*2 & -4) | 1] - 128; + cr = pixel[(col*2 & -4) | 3] - 128; + rgb[1] = y - ((cb + cr + 2) >> 2); + rgb[2] = rgb[1] + cb; + rgb[0] = rgb[1] + cr; + FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,255)]; + } + } + free (pixel); + maximum = curve[0xff]; +} + +void CLASS kodak_c603_load_raw() +{ + uchar *pixel; + int row, col, y, cb, cr, rgb[3], c; + + pixel = (uchar *) calloc (raw_width, 3*sizeof *pixel); + merror (pixel, "kodak_c603_load_raw()"); + for (row=0; row < height; row++) { + if (~row & 1) + if (fread (pixel, raw_width, 3, ifp) < 3) derror(); + for (col=0; col < width; col++) { + y = pixel[width*2*(row & 1) + col]; + cb = pixel[width + (col & -2)] - 128; + cr = pixel[width + (col & -2)+1] - 128; + rgb[1] = y - ((cb + cr + 2) >> 2); + rgb[2] = rgb[1] + cb; + rgb[0] = rgb[1] + cr; + FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,255)]; + } + } + free (pixel); + maximum = curve[0xff]; +} + +void CLASS kodak_262_load_raw() +{ + static const uchar kodak_tree[2][26] = + { { 0,1,5,1,1,2,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9 }, + { 0,3,1,1,1,1,1,2,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9 } }; + ushort *huff[2]; + uchar *pixel; + int *strip, ns, c, row, col, chess, pi=0, pi1, pi2, pred, val; + + FORC(2) huff[c] = make_decoder (kodak_tree[c]); + ns = (raw_height+63) >> 5; + pixel = (uchar *) malloc (raw_width*32 + ns*4); + merror (pixel, "kodak_262_load_raw()"); + strip = (int *) (pixel + raw_width*32); + order = 0x4d4d; + FORC(ns) strip[c] = get4(); + for (row=0; row < raw_height; row++) { + if ((row & 31) == 0) { + fseek (ifp, strip[row >> 5], SEEK_SET); + getbits(-1); + pi = 0; + } + for (col=0; col < raw_width; col++) { + chess = (row + col) & 1; + pi1 = chess ? pi-2 : pi-raw_width-1; + pi2 = chess ? pi-2*raw_width : pi-raw_width+1; + if (col <= chess) pi1 = -1; + if (pi1 < 0) pi1 = pi2; + if (pi2 < 0) pi2 = pi1; + if (pi1 < 0 && col > 1) pi1 = pi2 = pi-2; + pred = (pi1 < 0) ? 0 : (pixel[pi1] + pixel[pi2]) >> 1; + pixel[pi] = val = pred + ljpeg_diff (huff[chess]); + if (val >> 8) derror(); + val = curve[pixel[pi++]]; + RAW(row,col) = val; + } + } + free (pixel); + FORC(2) free (huff[c]); +} + +int CLASS kodak_65000_decode (short *out, int bsize) +{ + uchar c, blen[768]; + ushort raw[6]; + INT64 bitbuf=0; + int save, bits=0, i, j, len, diff; + + save = ftell(ifp); + bsize = (bsize + 3) & -4; + for (i=0; i < bsize; i+=2) { + c = fgetc(ifp); + if ((blen[i ] = c & 15) > 12 || + (blen[i+1] = c >> 4) > 12 ) { + fseek (ifp, save, SEEK_SET); + for (i=0; i < bsize; i+=8) { + read_shorts (raw, 6); + out[i ] = raw[0] >> 12 << 8 | raw[2] >> 12 << 4 | raw[4] >> 12; + out[i+1] = raw[1] >> 12 << 8 | raw[3] >> 12 << 4 | raw[5] >> 12; + for (j=0; j < 6; j++) + out[i+2+j] = raw[j] & 0xfff; + } + return 1; + } + } + if ((bsize & 7) == 4) { + bitbuf = fgetc(ifp) << 8; + bitbuf += fgetc(ifp); + bits = 16; + } + for (i=0; i < bsize; i++) { + len = blen[i]; + if (bits < len) { + for (j=0; j < 32; j+=8) + bitbuf += (INT64) fgetc(ifp) << (bits+(j^8)); + bits += 32; + } + diff = bitbuf & (0xffff >> (16-len)); + bitbuf >>= len; + bits -= len; + if ((diff & (1 << (len-1))) == 0) + diff -= (1 << len) - 1; + out[i] = diff; + } + return 0; +} + +void CLASS kodak_65000_load_raw() +{ + short buf[256]; + int row, col, len, pred[2], ret, i; + + for (row=0; row < height; row++) + for (col=0; col < width; col+=256) { + 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(); + } +} + +void CLASS kodak_ycbcr_load_raw() +{ + short buf[384], *bp; + int row, col, len, c, i, j, k, y[2][2], cb, cr, rgb[3]; + ushort *ip; + + if (!image) return; + for (row=0; row < height; row+=2) + for (col=0; col < width; col+=128) { + len = MIN (128, width-col); + kodak_65000_decode (buf, len*3); + y[0][1] = y[1][1] = cb = cr = 0; + for (bp=buf, i=0; i < len; i+=2, bp+=2) { + cb += bp[4]; + cr += bp[5]; + rgb[1] = -((cb + cr + 2) >> 2); + rgb[2] = rgb[1] + cb; + rgb[0] = rgb[1] + cr; + for (j=0; j < 2; j++) + for (k=0; k < 2; k++) { + if ((y[j][k] = y[j][k^1] + *bp++) >> 10) derror(); + ip = image[(row+j)*width + col+i+k]; + FORC3 ip[c] = curve[LIM(y[j][k]+rgb[c], 0, 0xfff)]; + } + } + } +} + +void CLASS kodak_rgb_load_raw() +{ + short buf[768], *bp; + int row, col, len, c, i, rgb[3]; + ushort *ip=image[0]; + + for (row=0; row < height; row++) + for (col=0; col < width; col+=256) { + len = MIN (256, width-col); + kodak_65000_decode (buf, len*3); + memset (rgb, 0, sizeof rgb); + for (bp=buf, i=0; i < len; i++, ip+=4) + FORC3 if ((ip[c] = rgb[c] += *bp++) >> 12) derror(); + } +} + +void CLASS kodak_thumb_load_raw() +{ + int row, col; + colors = thumb_misc >> 5; + for (row=0; row < height; row++) + for (col=0; col < width; col++) + read_shorts (image[row*width+col], colors); + maximum = (1 << (thumb_misc & 31)) - 1; +} + +void CLASS sony_decrypt (unsigned *data, int len, int start, int key) +{ + static unsigned pad[128], p; + + if (start) { + for (p=0; p < 4; p++) + pad[p] = key = key * 48828125 + 1; + pad[3] = pad[3] << 1 | (pad[0]^pad[2]) >> 31; + for (p=4; p < 127; p++) + pad[p] = (pad[p-4]^pad[p-2]) << 1 | (pad[p-3]^pad[p-1]) >> 31; + for (p=0; p < 127; p++) + pad[p] = htonl(pad[p]); + } + while (len-- && p++) + *data++ ^= pad[(p-1) & 127] = pad[p & 127] ^ pad[(p+64) & 127]; +} + +void CLASS sony_load_raw() +{ + uchar head[40]; + ushort *pixel; + unsigned i, key, row, col; + + fseek (ifp, 200896, SEEK_SET); + fseek (ifp, (unsigned) fgetc(ifp)*4 - 1, SEEK_CUR); + order = 0x4d4d; + key = get4(); + fseek (ifp, 164600, SEEK_SET); + fread (head, 1, 40, ifp); + sony_decrypt ((unsigned *) head, 10, 1, key); + for (i=26; i-- > 22; ) + key = key << 8 | head[i]; + fseek (ifp, data_offset, SEEK_SET); + for (row=0; row < raw_height; row++) { + pixel = raw_image + row*raw_width; + if (fread (pixel, 2, raw_width, ifp) < raw_width) derror(); + sony_decrypt ((unsigned *) pixel, raw_width/2, !row, key); + for (col=0; col < raw_width; col++) + if ((pixel[col] = ntohs(pixel[col])) >> 14) derror(); + } + maximum = 0x3ff0; +} + +void CLASS sony_arw_load_raw() +{ + ushort huff[32770]; + static const ushort tab[18] = + { 0xf11,0xf10,0xe0f,0xd0e,0xc0d,0xb0c,0xa0b,0x90a,0x809, + 0x708,0x607,0x506,0x405,0x304,0x303,0x300,0x202,0x201 }; + int i, c, n, col, row, sum=0; + + huff[0] = 15; + for (n=i=0; i < 18; i++) + FORC(32768 >> (tab[i] >> 8)) huff[++n] = tab[i]; + getbits(-1); + for (col = raw_width; col--; ) + for (row=0; row < raw_height+1; row+=2) { + if (row == raw_height) row = 1; + if ((sum += ljpeg_diff(huff)) >> 12) derror(); + if (row < height) RAW(row,col) = sum; + } +} + +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; + col -= col & 1 ? 1:31; + } + } + free (data); +} + +void CLASS samsung_load_raw() +{ + int row, col, c, i, dir, op[4], len[4]; + + order = 0x4949; + 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); + 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); + FORC4 switch (op[c]) { + case 3: len[c] = ph1_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)) + + (dir ? RAW(row+(~c | -2),col+c) : col ? RAW(row,col+(c | -2)) : 128); + if (c == 14) c = -1; + } + } + } + for (row=0; row < raw_height-1; row+=2) + for (col=0; col < raw_width-1; col+=2) + SWAP (RAW(row,col+1), RAW(row+1,col)); +} + +void CLASS samsung2_load_raw() +{ + static const ushort tab[14] = + { 0x304,0x307,0x206,0x205,0x403,0x600,0x709, + 0x80a,0x90b,0xa0c,0xa0d,0x501,0x408,0x402 }; + ushort huff[1026], vpred[2][2] = {{0,0},{0,0}}, hpred[2]; + int i, c, n, row, col, diff; + + huff[0] = 10; + for (n=i=0; i < 14; i++) + FORC(1024 >> (tab[i] >> 8)) huff[++n] = tab[i]; + getbits(-1); + for (row=0; row < raw_height; row++) + for (col=0; col < raw_width; col++) { + diff = ljpeg_diff (huff); + if (col < 2) hpred[col] = vpred[row & 1][col] += diff; + else hpred[col & 1] += diff; + RAW(row,col) = hpred[col & 1]; + if (hpred[col & 1] >> tiff_bps) derror(); + } +} + +void CLASS samsung3_load_raw() +{ + int opt, init, mag, pmode, row, tab, col, pred, diff, i, c; + ushort lent[3][2], len[4], *prow[2]; + + order = 0x4949; + fseek (ifp, 9, SEEK_CUR); + opt = fgetc(ifp); + init = (get2(),get2()); + for (row=0; row < raw_height; row++) { + fseek (ifp, (data_offset-ftell(ifp)) & 15, SEEK_CUR); + ph1_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); + } + 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); + FORC4 { + i = ((row & 1) << 1 | (c & 1)) % 3; + len[c] = len[c] < 3 ? lent[i][0]-'1'+"120"[len[c]] : ph1_bits(4); + lent[i][0] = lent[i][1]; + lent[i][1] = len[c]; + } + } + FORC(16) { + col = tab + (((c & 7) << 1)^(c >> 3)^(row & 1)); + pred = (pmode == 7 || row < 2) + ? (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]); + if (diff >> (i-1)) diff -= 1 << i; + diff = diff * (mag*2+1) + mag; + RAW(row,col) = pred + diff; + } + } + } +} + +#define HOLE(row) ((holes >> (((row) - raw_height) & 7)) & 1) + +/* Kudos to Rich Taylor for figuring out SMaL's compression algorithm. */ +void CLASS smal_decode_segment (unsigned seg[2][2], int holes) +{ + uchar hist[3][13] = { + { 7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0 }, + { 7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0 }, + { 3, 3, 0, 0, 63, 47, 31, 15, 0 } }; + int low, high=0xff, carry=0, nbits=8; + int pix, s, count, bin, next, i, sym[3]; + uchar diff, pred[]={0,0}; + ushort data=0, range=0; + + fseek (ifp, seg[0][1]+1, SEEK_SET); + getbits(-1); + for (pix=seg[0][0]; pix < seg[1][0]; pix++) { + for (s=0; s < 3; s++) { + data = data << nbits | getbits(nbits); + if (carry < 0) + carry = (nbits += carry+1) < 1 ? nbits-1 : 0; + while (--nbits >= 0) + if ((data >> nbits & 0xff) == 0xff) break; + if (nbits > 0) + data = ((data & ((1 << (nbits-1)) - 1)) << 1) | + ((data + (((data & (1 << (nbits-1)))) << 1)) & (-1 << nbits)); + if (nbits >= 0) { + data += getbits(1); + carry = nbits - 8; + } + count = ((((data-range+1) & 0xffff) << 2) - 1) / (high >> 4); + for (bin=0; hist[s][bin+5] > count; bin++); + low = hist[s][bin+5] * (high >> 4) >> 2; + if (bin) high = hist[s][bin+4] * (high >> 4) >> 2; + high -= low; + for (nbits=0; high << nbits < 128; nbits++); + range = (range+low) << nbits; + high <<= nbits; + next = hist[s][1]; + if (++hist[s][2] > hist[s][3]) { + next = (next+1) & hist[s][0]; + hist[s][3] = (hist[s][next+4] - hist[s][next+5]) >> 2; + hist[s][2] = 1; + } + if (hist[s][hist[s][1]+4] - hist[s][hist[s][1]+5] > 1) { + if (bin < hist[s][1]) + for (i=bin; i < hist[s][1]; i++) hist[s][i+5]--; + else if (next <= bin) + for (i=hist[s][1]; i < bin; i++) hist[s][i+5]++; + } + hist[s][1] = next; + sym[s] = bin; + } + diff = sym[2] << 5 | sym[1] << 2 | (sym[0] & 3); + if (sym[0] & 4) + diff = diff ? -diff : 0x80; + if (ftell(ifp) + 12 >= seg[1][1]) + diff = 0; + raw_image[pix] = pred[pix & 1] += diff; + if (!(pix & 1) && HOLE(pix / raw_width)) pix += 2; + } + maximum = 0xff; +} + +void CLASS smal_v6_load_raw() +{ + unsigned seg[2][2]; + + fseek (ifp, 16, SEEK_SET); + seg[0][0] = 0; + seg[0][1] = get2(); + seg[1][0] = raw_width * raw_height; + seg[1][1] = INT_MAX; + smal_decode_segment (seg, 0); +} + +int CLASS median4 (int *p) +{ + int min, max, sum, i; + + min = max = sum = p[0]; + for (i=1; i < 4; i++) { + sum += p[i]; + if (min > p[i]) min = p[i]; + if (max < p[i]) max = p[i]; + } + return (sum - min - max) >> 1; +} + +void CLASS fill_holes (int holes) +{ + int row, col, val[4]; + + for (row=2; row < height-2; row++) { + if (!HOLE(row)) continue; + for (col=1; col < width-1; col+=4) { + val[0] = RAW(row-1,col-1); + val[1] = RAW(row-1,col+1); + val[2] = RAW(row+1,col-1); + val[3] = RAW(row+1,col+1); + RAW(row,col) = median4(val); + } + for (col=2; col < width-2; col+=4) + if (HOLE(row-2) || HOLE(row+2)) + RAW(row,col) = (RAW(row,col-2) + RAW(row,col+2)) >> 1; + else { + val[0] = RAW(row,col-2); + val[1] = RAW(row,col+2); + val[2] = RAW(row-2,col); + val[3] = RAW(row+2,col); + RAW(row,col) = median4(val); + } + } +} + +void CLASS smal_v9_load_raw() +{ + unsigned seg[256][2], offset, nseg, holes, i; + + fseek (ifp, 67, SEEK_SET); + offset = get4(); + nseg = (uchar) fgetc(ifp); + fseek (ifp, offset, SEEK_SET); + for (i=0; i < nseg*2; i++) + ((unsigned *)seg)[i] = get4() + data_offset*(i & 1); + fseek (ifp, 78, SEEK_SET); + holes = fgetc(ifp); + fseek (ifp, 88, SEEK_SET); + seg[nseg][0] = raw_height * raw_width; + seg[nseg][1] = get4() + data_offset; + for (i=0; i < nseg; i++) + smal_decode_segment (seg+i, holes); + if (holes) fill_holes (holes); +} + +void CLASS redcine_load_raw() +{ +#ifndef NO_JASPER + int c, row, col; + jas_stream_t *in; + jas_image_t *jimg; + jas_matrix_t *jmat; + jas_seqent_t *data; + ushort *img, *pix; + + jas_init(); + in = jas_stream_fopen (ifname, "rb"); + jas_stream_seek (in, data_offset+20, SEEK_SET); + jimg = jas_image_decode (in, -1, 0); + if (!jimg) longjmp (failure, 3); + jmat = jas_matrix_create (height/2, width/2); + merror (jmat, "redcine_load_raw()"); + img = (ushort *) calloc ((height+2), (width+2)*2); + merror (img, "redcine_load_raw()"); + FORC4 { + jas_image_readcmpt (jimg, c, 0, 0, width/2, height/2, jmat); + data = jas_matrix_getref (jmat, 0, 0); + for (row = c >> 1; row < height; row+=2) + for (col = c & 1; col < width; col+=2) + img[(row+1)*(width+2)+col+1] = data[(row/2)*(width/2)+col/2]; + } + for (col=1; col <= width; col++) { + img[col] = img[2*(width+2)+col]; + img[(height+1)*(width+2)+col] = img[(height-1)*(width+2)+col]; + } + for (row=0; row < height+2; row++) { + img[row*(width+2)] = img[row*(width+2)+2]; + img[(row+1)*(width+2)-1] = img[(row+1)*(width+2)-3]; + } + for (row=1; row <= height; row++) { + pix = img + row*(width+2) + (col = 1 + (FC(row,1) & 1)); + for ( ; col <= width; col+=2, pix+=2) { + c = (((pix[0] - 0x800) << 3) + + pix[-(width+2)] + pix[width+2] + pix[-1] + pix[1]) >> 2; + pix[0] = LIM(c,0,4095); + } + } + for (row=0; row < height; row++) + for (col=0; col < width; col++) + RAW(row,col) = curve[img[(row+1)*(width+2)+col+1]]; + free (img); + jas_matrix_destroy (jmat); + jas_image_destroy (jimg); + jas_stream_close (in); +#endif +} + +/* RESTRICTED code starts here */ + +void CLASS foveon_decoder (unsigned size, unsigned code) +{ + static unsigned huff[1024]; + struct decode *cur; + int i, len; + + if (!code) { + for (i=0; i < size; i++) + huff[i] = get4(); + memset (first_decode, 0, sizeof first_decode); + free_decode = first_decode; + } + cur = free_decode++; + if (free_decode > first_decode+2048) { + fprintf (stderr,_("%s: decoder table overflow\n"), ifname); + longjmp (failure, 2); + } + if (code) + for (i=0; i < size; i++) + if (huff[i] == code) { + cur->leaf = i; + return; + } + if ((len = code >> 27) > 26) return; + code = (len+1) << 27 | (code & 0x3ffffff) << 1; + + cur->branch[0] = free_decode; + foveon_decoder (size, code); + cur->branch[1] = free_decode; + foveon_decoder (size, code+1); +} + +void CLASS foveon_thumb() +{ + unsigned bwide, row, col, bitbuf=0, bit=1, c, i; + char *buf; + struct decode *dindex; + short pred[3]; + + bwide = get4(); + fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height); + if (bwide > 0) { + if (bwide < thumb_width*3) return; + buf = (char *) malloc (bwide); + merror (buf, "foveon_thumb()"); + for (row=0; row < thumb_height; row++) { + fread (buf, 1, bwide, ifp); + fwrite (buf, 3, thumb_width, ofp); + } + free (buf); + return; + } + foveon_decoder (256, 0); + + for (row=0; row < thumb_height; row++) { + memset (pred, 0, sizeof pred); + if (!bit) get4(); + for (bit=col=0; col < thumb_width; col++) + FORC3 { + for (dindex=first_decode; dindex->branch[0]; ) { + if ((bit = (bit-1) & 31) == 31) + for (i=0; i < 4; i++) + bitbuf = (bitbuf << 8) + fgetc(ifp); + dindex = dindex->branch[bitbuf >> bit & 1]; + } + pred[c] += dindex->leaf; + fputc (pred[c], ofp); + } + } +} + +void CLASS foveon_sd_load_raw() +{ + struct decode *dindex; + short diff[1024]; + unsigned bitbuf=0; + int pred[3], row, col, bit=-1, c, i; + + read_shorts ((ushort *) diff, 1024); + if (!load_flags) foveon_decoder (1024, 0); + + for (row=0; row < height; row++) { + memset (pred, 0, sizeof pred); + if (!bit && !load_flags && atoi(model+2) < 14) get4(); + for (col=bit=0; col < width; col++) { + if (load_flags) { + bitbuf = get4(); + FORC3 pred[2-c] += diff[bitbuf >> c*10 & 0x3ff]; + } + else FORC3 { + for (dindex=first_decode; dindex->branch[0]; ) { + if ((bit = (bit-1) & 31) == 31) + for (i=0; i < 4; i++) + bitbuf = (bitbuf << 8) + fgetc(ifp); + dindex = dindex->branch[bitbuf >> bit & 1]; + } + pred[c] += diff[dindex->leaf]; + if (pred[c] >> 16 && ~pred[c] >> 16) derror(); + } + FORC3 image[row*width+col][c] = pred[c]; + } + } +} + +void CLASS foveon_huff (ushort *huff) +{ + int i, j, clen, code; + + huff[0] = 8; + for (i=0; i < 13; i++) { + clen = getc(ifp); + code = getc(ifp); + for (j=0; j < 256 >> clen; ) + huff[code+ ++j] = clen << 8 | i; + } + get2(); +} + +void CLASS foveon_dp_load_raw() +{ + unsigned c, roff[4], row, col, diff; + ushort huff[512], vpred[2][2], hpred[2]; + + fseek (ifp, 8, SEEK_CUR); + foveon_huff (huff); + roff[0] = 48; + FORC3 roff[c+1] = -(-(roff[c] + get4()) & -16); + FORC3 { + fseek (ifp, data_offset+roff[c], SEEK_SET); + getbits(-1); + vpred[0][0] = vpred[0][1] = vpred[1][0] = vpred[1][1] = 512; + for (row=0; row < height; row++) { + for (col=0; col < width; col++) { + diff = ljpeg_diff(huff); + if (col < 2) hpred[col] = vpred[row & 1][col] += diff; + else hpred[col & 1] += diff; + image[row*width+col][c] = hpred[col & 1]; + } + } + } +} + +void CLASS foveon_load_camf() +{ + unsigned type, wide, high, i, j, row, col, diff; + ushort huff[258], vpred[2][2] = {{512,512},{512,512}}, hpred[2]; + + fseek (ifp, meta_offset, SEEK_SET); + type = get4(); get4(); get4(); + wide = get4(); + high = get4(); + if (type == 2) { + fread (meta_data, 1, meta_length, ifp); + for (i=0; i < meta_length; i++) { + high = (high * 1597 + 51749) % 244944; + wide = high * (INT64) 301593171 >> 24; + meta_data[i] ^= ((((high << 8) - wide) >> 1) + wide) >> 17; + } + } else if (type == 4) { + free (meta_data); + meta_data = (char *) malloc (meta_length = wide*high*3/2); + merror (meta_data, "foveon_load_camf()"); + foveon_huff (huff); + get4(); + getbits(-1); + for (j=row=0; row < high; row++) { + for (col=0; col < wide; col++) { + diff = ljpeg_diff(huff); + if (col < 2) hpred[col] = vpred[row & 1][col] += diff; + else hpred[col & 1] += diff; + if (col & 1) { + meta_data[j++] = hpred[0] >> 4; + meta_data[j++] = hpred[0] << 4 | hpred[1] >> 8; + meta_data[j++] = hpred[1]; + } + } + } + } else + fprintf (stderr,_("%s has unknown CAMF type %d.\n"), ifname, type); +} + +const char * CLASS foveon_camf_param (const char *block, const char *param) +{ + unsigned idx, num; + char *pos, *cp, *dp; + + for (idx=0; idx < meta_length; idx += sget4(pos+8)) { + pos = meta_data + idx; + if (strncmp (pos, "CMb", 3)) break; + if (pos[3] != 'P') continue; + if (strcmp (block, pos+sget4(pos+12))) continue; + cp = pos + sget4(pos+16); + num = sget4(cp); + dp = pos + sget4(cp+4); + while (num--) { + cp += 8; + if (!strcmp (param, dp+sget4(cp))) + return dp+sget4(cp+4); + } + } + return 0; +} + +void * CLASS foveon_camf_matrix (unsigned dim[3], const char *name) +{ + unsigned i, idx, type, ndim, size, *mat; + char *pos, *cp, *dp; + double dsize; + + for (idx=0; idx < meta_length; idx += sget4(pos+8)) { + pos = meta_data + idx; + if (strncmp (pos, "CMb", 3)) break; + if (pos[3] != 'M') continue; + if (strcmp (name, pos+sget4(pos+12))) continue; + dim[0] = dim[1] = dim[2] = 1; + cp = pos + sget4(pos+16); + type = sget4(cp); + if ((ndim = sget4(cp+4)) > 3) break; + dp = pos + sget4(cp+8); + for (i=ndim; i--; ) { + cp += 12; + dim[i] = sget4(cp); + } + if ((dsize = (double) dim[0]*dim[1]*dim[2]) > meta_length/4) break; + mat = (unsigned *) malloc ((size = dsize) * 4); + merror (mat, "foveon_camf_matrix()"); + for (i=0; i < size; i++) + if (type && type != 6) + mat[i] = sget4(dp + i*4); + else + mat[i] = sget4(dp + i*2) & 0xffff; + return mat; + } + fprintf (stderr,_("%s: \"%s\" matrix not found!\n"), ifname, name); + return 0; +} + +int CLASS foveon_fixed (void *ptr, int size, const char *name) +{ + void *dp; + unsigned dim[3]; + + if (!name) return 0; + dp = foveon_camf_matrix (dim, name); + if (!dp) return 0; + memcpy (ptr, dp, size*4); + free (dp); + return 1; +} + +float CLASS foveon_avg (short *pix, int range[2], float cfilt) +{ + int i; + float val, min=FLT_MAX, max=-FLT_MAX, sum=0; + + for (i=range[0]; i <= range[1]; i++) { + sum += val = pix[i*4] + (pix[i*4]-pix[(i-1)*4]) * cfilt; + if (min > val) min = val; + if (max < val) max = val; + } + if (range[1] - range[0] == 1) return sum/2; + return (sum - min - max) / (range[1] - range[0] - 1); +} + +short * CLASS foveon_make_curve (double max, double mul, double filt) +{ + short *curve; + unsigned i, size; + double x; + + if (!filt) filt = 0.8; + size = 4*M_PI*max / filt; + if (size == UINT_MAX) size--; + curve = (short *) calloc (size+1, sizeof *curve); + merror (curve, "foveon_make_curve()"); + curve[0] = size; + for (i=0; i < size; i++) { + x = i*filt/max/4; + curve[i+1] = (cos(x)+1)/2 * tanh(i*filt/mul) * mul + 0.5; + } + return curve; +} + +void CLASS foveon_make_curves + (short **curvep, float dq[3], float div[3], float filt) +{ + double mul[3], max=0; + int c; + + FORC3 mul[c] = dq[c]/div[c]; + FORC3 if (max < mul[c]) max = mul[c]; + FORC3 curvep[c] = foveon_make_curve (max, mul[c], filt); +} + +int CLASS foveon_apply_curve (short *curve, int i) +{ + if (abs(i) >= curve[0]) return 0; + return i < 0 ? -curve[1-i] : curve[1+i]; +} + +#define image ((short (*)[4]) image) + +void CLASS foveon_interpolate() +{ + static const short hood[] = { -1,-1, -1,0, -1,1, 0,-1, 0,1, 1,-1, 1,0, 1,1 }; + short *pix, prev[3], *curve[8], (*shrink)[3]; + float cfilt=0, ddft[3][3][2], ppm[3][3][3]; + float cam_xyz[3][3], correct[3][3], last[3][3], trans[3][3]; + float chroma_dq[3], color_dq[3], diag[3][3], div[3]; + float (*black)[3], (*sgain)[3], (*sgrow)[3]; + float fsum[3], val, frow, num; + int row, col, c, i, j, diff, sgx, irow, sum, min, max, limit; + int dscr[2][2], dstb[4], (*smrow[7])[3], total[4], ipix[3]; + int work[3][3], smlast, smred, smred_p=0, dev[3]; + int satlev[3], keep[4], active[4]; + unsigned dim[3], *badpix; + double dsum=0, trsum[3]; + char str[128]; + const char* cp; + + if (verbose) + fprintf (stderr,_("Foveon interpolation...\n")); + + foveon_load_camf(); + foveon_fixed (dscr, 4, "DarkShieldColRange"); + foveon_fixed (ppm[0][0], 27, "PostPolyMatrix"); + foveon_fixed (satlev, 3, "SaturationLevel"); + foveon_fixed (keep, 4, "KeepImageArea"); + foveon_fixed (active, 4, "ActiveImageArea"); + foveon_fixed (chroma_dq, 3, "ChromaDQ"); + foveon_fixed (color_dq, 3, + foveon_camf_param ("IncludeBlocks", "ColorDQ") ? + "ColorDQ" : "ColorDQCamRGB"); + if (foveon_camf_param ("IncludeBlocks", "ColumnFilter")) + foveon_fixed (&cfilt, 1, "ColumnFilter"); + + memset (ddft, 0, sizeof ddft); + if (!foveon_camf_param ("IncludeBlocks", "DarkDrift") + || !foveon_fixed (ddft[1][0], 12, "DarkDrift")) + for (i=0; i < 2; i++) { + foveon_fixed (dstb, 4, i ? "DarkShieldBottom":"DarkShieldTop"); + for (row = dstb[1]; row <= dstb[3]; row++) + for (col = dstb[0]; col <= dstb[2]; col++) + FORC3 ddft[i+1][c][1] += (short) image[row*width+col][c]; + FORC3 ddft[i+1][c][1] /= (dstb[3]-dstb[1]+1) * (dstb[2]-dstb[0]+1); + } + + if (!(cp = foveon_camf_param ("WhiteBalanceIlluminants", model2))) + { fprintf (stderr,_("%s: Invalid white balance \"%s\"\n"), ifname, model2); + return; } + foveon_fixed (cam_xyz, 9, cp); + foveon_fixed (correct, 9, + foveon_camf_param ("WhiteBalanceCorrections", model2)); + memset (last, 0, sizeof last); + for (i=0; i < 3; i++) + for (j=0; j < 3; j++) + FORC3 last[i][j] += correct[i][c] * cam_xyz[c][j]; + + #define LAST(x,y) last[(i+x)%3][(c+y)%3] + for (i=0; i < 3; i++) + FORC3 diag[c][i] = LAST(1,1)*LAST(2,2) - LAST(1,2)*LAST(2,1); + #undef LAST + FORC3 div[c] = diag[c][0]*0.3127 + diag[c][1]*0.329 + diag[c][2]*0.3583; + sprintf (str, "%sRGBNeutral", model2); + if (foveon_camf_param ("IncludeBlocks", str)) + foveon_fixed (div, 3, str); + num = 0; + FORC3 if (num < div[c]) num = div[c]; + FORC3 div[c] /= num; + + memset (trans, 0, sizeof trans); + for (i=0; i < 3; i++) + for (j=0; j < 3; j++) + FORC3 trans[i][j] += rgb_cam[i][c] * last[c][j] * div[j]; + FORC3 trsum[c] = trans[c][0] + trans[c][1] + trans[c][2]; + dsum = (6*trsum[0] + 11*trsum[1] + 3*trsum[2]) / 20; + for (i=0; i < 3; i++) + FORC3 last[i][c] = trans[i][c] * dsum / trsum[i]; + memset (trans, 0, sizeof trans); + for (i=0; i < 3; i++) + for (j=0; j < 3; j++) + FORC3 trans[i][j] += (i==c ? 32 : -1) * last[c][j] / 30; + + foveon_make_curves (curve, color_dq, div, cfilt); + FORC3 chroma_dq[c] /= 3; + foveon_make_curves (curve+3, chroma_dq, div, cfilt); + FORC3 dsum += chroma_dq[c] / div[c]; + curve[6] = foveon_make_curve (dsum, dsum, cfilt); + curve[7] = foveon_make_curve (dsum*2, dsum*2, cfilt); + + sgain = (float (*)[3]) foveon_camf_matrix (dim, "SpatialGain"); + if (!sgain) return; + sgrow = (float (*)[3]) calloc (dim[1], sizeof *sgrow); + sgx = (width + dim[1]-2) / (dim[1]-1); + + black = (float (*)[3]) calloc (height, sizeof *black); + for (row=0; row < height; row++) { + for (i=0; i < 6; i++) + ((float *)ddft[0])[i] = ((float *)ddft[1])[i] + + row / (height-1.0) * (((float *)ddft[2])[i] - ((float *)ddft[1])[i]); + FORC3 black[row][c] = + ( foveon_avg (image[row*width]+c, dscr[0], cfilt) + + foveon_avg (image[row*width]+c, dscr[1], cfilt) * 3 + - ddft[0][c][0] ) / 4 - ddft[0][c][1]; + } + memcpy (black, black+8, sizeof *black*8); + memcpy (black+height-11, black+height-22, 11*sizeof *black); + memcpy (last, black, sizeof last); + + for (row=1; row < height-1; row++) { + FORC3 if (last[1][c] > last[0][c]) { + if (last[1][c] > last[2][c]) + black[row][c] = (last[0][c] > last[2][c]) ? last[0][c]:last[2][c]; + } else + if (last[1][c] < last[2][c]) + black[row][c] = (last[0][c] < last[2][c]) ? last[0][c]:last[2][c]; + memmove (last, last+1, 2*sizeof last[0]); + memcpy (last[2], black[row+1], sizeof last[2]); + } + FORC3 black[row][c] = (last[0][c] + last[1][c])/2; + FORC3 black[0][c] = (black[1][c] + black[3][c])/2; + + val = 1 - exp(-1/24.0); + memcpy (fsum, black, sizeof fsum); + for (row=1; row < height; row++) + FORC3 fsum[c] += black[row][c] = + (black[row][c] - black[row-1][c])*val + black[row-1][c]; + memcpy (last[0], black[height-1], sizeof last[0]); + FORC3 fsum[c] /= height; + for (row = height; row--; ) + FORC3 last[0][c] = black[row][c] = + (black[row][c] - fsum[c] - last[0][c])*val + last[0][c]; + + memset (total, 0, sizeof total); + for (row=2; row < height; row+=4) + for (col=2; col < width; col+=4) { + FORC3 total[c] += (short) image[row*width+col][c]; + total[3]++; + } + for (row=0; row < height; row++) + FORC3 black[row][c] += fsum[c]/2 + total[c]/(total[3]*100.0); + + for (row=0; row < height; row++) { + for (i=0; i < 6; i++) + ((float *)ddft[0])[i] = ((float *)ddft[1])[i] + + row / (height-1.0) * (((float *)ddft[2])[i] - ((float *)ddft[1])[i]); + pix = image[row*width]; + memcpy (prev, pix, sizeof prev); + frow = row / (height-1.0) * (dim[2]-1); + if ((irow = frow) == dim[2]-1) irow--; + frow -= irow; + for (i=0; i < dim[1]; i++) + FORC3 sgrow[i][c] = sgain[ irow *dim[1]+i][c] * (1-frow) + + sgain[(irow+1)*dim[1]+i][c] * frow; + for (col=0; col < width; col++) { + FORC3 { + diff = pix[c] - prev[c]; + prev[c] = pix[c]; + ipix[c] = pix[c] + floor ((diff + (diff*diff >> 14)) * cfilt + - ddft[0][c][1] - ddft[0][c][0] * ((float) col/width - 0.5) + - black[row][c] ); + } + FORC3 { + work[0][c] = ipix[c] * ipix[c] >> 14; + work[2][c] = ipix[c] * work[0][c] >> 14; + work[1][2-c] = ipix[(c+1) % 3] * ipix[(c+2) % 3] >> 14; + } + FORC3 { + for (val=i=0; i < 3; i++) + for ( j=0; j < 3; j++) + val += ppm[c][i][j] * work[i][j]; + ipix[c] = floor ((ipix[c] + floor(val)) * + ( sgrow[col/sgx ][c] * (sgx - col%sgx) + + sgrow[col/sgx+1][c] * (col%sgx) ) / sgx / div[c]); + if (ipix[c] > 32000) ipix[c] = 32000; + pix[c] = ipix[c]; + } + pix += 4; + } + } + free (black); + free (sgrow); + free (sgain); + + if ((badpix = (unsigned *) foveon_camf_matrix (dim, "BadPixels"))) { + for (i=0; i < dim[0]; i++) { + col = (badpix[i] >> 8 & 0xfff) - keep[0]; + row = (badpix[i] >> 20 ) - keep[1]; + if ((unsigned)(row-1) > height-3 || (unsigned)(col-1) > width-3) + continue; + memset (fsum, 0, sizeof fsum); + for (sum=j=0; j < 8; j++) + if (badpix[i] & (1 << j)) { + FORC3 fsum[c] += (short) + image[(row+hood[j*2])*width+col+hood[j*2+1]][c]; + sum++; + } + if (sum) FORC3 image[row*width+col][c] = fsum[c]/sum; + } + free (badpix); + } + + /* Array for 5x5 Gaussian averaging of red values */ + smrow[6] = (int (*)[3]) calloc (width*5, sizeof **smrow); + merror (smrow[6], "foveon_interpolate()"); + for (i=0; i < 5; i++) + smrow[i] = smrow[6] + i*width; + + /* Sharpen the reds against these Gaussian averages */ + for (smlast=-1, row=2; row < height-2; row++) { + while (smlast < row+2) { + for (i=0; i < 6; i++) + smrow[(i+5) % 6] = smrow[i]; + pix = image[++smlast*width+2]; + for (col=2; col < width-2; col++) { + smrow[4][col][0] = + (pix[0]*6 + (pix[-4]+pix[4])*4 + pix[-8]+pix[8] + 8) >> 4; + pix += 4; + } + } + pix = image[row*width+2]; + for (col=2; col < width-2; col++) { + smred = ( 6 * smrow[2][col][0] + + 4 * (smrow[1][col][0] + smrow[3][col][0]) + + smrow[0][col][0] + smrow[4][col][0] + 8 ) >> 4; + if (col == 2) + smred_p = smred; + i = pix[0] + ((pix[0] - ((smred*7 + smred_p) >> 3)) >> 3); + if (i > 32000) i = 32000; + pix[0] = i; + smred_p = smred; + pix += 4; + } + } + + /* Adjust the brighter pixels for better linearity */ + min = 0xffff; + FORC3 { + i = satlev[c] / div[c]; + if (min > i) min = i; + } + limit = min * 9 >> 4; + for (pix=image[0]; pix < image[height*width]; pix+=4) { + if (pix[0] <= limit || pix[1] <= limit || pix[2] <= limit) + continue; + min = max = pix[0]; + for (c=1; c < 3; c++) { + if (min > pix[c]) min = pix[c]; + if (max < pix[c]) max = pix[c]; + } + if (min >= limit*2) { + pix[0] = pix[1] = pix[2] = max; + } else { + i = 0x4000 - ((min - limit) << 14) / limit; + i = 0x4000 - (i*i >> 14); + i = i*i >> 14; + FORC3 pix[c] += (max - pix[c]) * i >> 14; + } + } +/* + Because photons that miss one detector often hit another, + the sum R+G+B is much less noisy than the individual colors. + So smooth the hues without smoothing the total. + */ + for (smlast=-1, row=2; row < height-2; row++) { + while (smlast < row+2) { + for (i=0; i < 6; i++) + smrow[(i+5) % 6] = smrow[i]; + pix = image[++smlast*width+2]; + for (col=2; col < width-2; col++) { + FORC3 smrow[4][col][c] = (pix[c-4]+2*pix[c]+pix[c+4]+2) >> 2; + pix += 4; + } + } + pix = image[row*width+2]; + for (col=2; col < width-2; col++) { + FORC3 dev[c] = -foveon_apply_curve (curve[7], pix[c] - + ((smrow[1][col][c] + 2*smrow[2][col][c] + smrow[3][col][c]) >> 2)); + sum = (dev[0] + dev[1] + dev[2]) >> 3; + FORC3 pix[c] += dev[c] - sum; + pix += 4; + } + } + for (smlast=-1, row=2; row < height-2; row++) { + while (smlast < row+2) { + for (i=0; i < 6; i++) + smrow[(i+5) % 6] = smrow[i]; + pix = image[++smlast*width+2]; + for (col=2; col < width-2; col++) { + FORC3 smrow[4][col][c] = + (pix[c-8]+pix[c-4]+pix[c]+pix[c+4]+pix[c+8]+2) >> 2; + pix += 4; + } + } + pix = image[row*width+2]; + for (col=2; col < width-2; col++) { + for (total[3]=375, sum=60, c=0; c < 3; c++) { + for (total[c]=i=0; i < 5; i++) + total[c] += smrow[i][col][c]; + total[3] += total[c]; + sum += pix[c]; + } + if (sum < 0) sum = 0; + j = total[3] > 375 ? (sum << 16) / total[3] : sum * 174; + FORC3 pix[c] += foveon_apply_curve (curve[6], + ((j*total[c] + 0x8000) >> 16) - pix[c]); + pix += 4; + } + } + + /* Transform the image to a different colorspace */ + for (pix=image[0]; pix < image[height*width]; pix+=4) { + FORC3 pix[c] -= foveon_apply_curve (curve[c], pix[c]); + sum = (pix[0]+pix[1]+pix[1]+pix[2]) >> 2; + FORC3 pix[c] -= foveon_apply_curve (curve[c], pix[c]-sum); + FORC3 { + for (dsum=i=0; i < 3; i++) + dsum += trans[c][i] * pix[i]; + if (dsum < 0) dsum = 0; + if (dsum > 24000) dsum = 24000; + ipix[c] = dsum + 0.5; + } + FORC3 pix[c] = ipix[c]; + } + + /* Smooth the image bottom-to-top and save at 1/4 scale */ + shrink = (short (*)[3]) calloc ((height/4), (width/4)*sizeof *shrink); + merror (shrink, "foveon_interpolate()"); + for (row = height/4; row--; ) + for (col=0; col < width/4; col++) { + ipix[0] = ipix[1] = ipix[2] = 0; + for (i=0; i < 4; i++) + for (j=0; j < 4; j++) + FORC3 ipix[c] += image[(row*4+i)*width+col*4+j][c]; + FORC3 + if (row+2 > height/4) + shrink[row*(width/4)+col][c] = ipix[c] >> 4; + else + shrink[row*(width/4)+col][c] = + (shrink[(row+1)*(width/4)+col][c]*1840 + ipix[c]*141 + 2048) >> 12; + } + /* From the 1/4-scale image, smooth right-to-left */ + for (row=0; row < (height & ~3); row++) { + ipix[0] = ipix[1] = ipix[2] = 0; + if ((row & 3) == 0) + for (col = width & ~3 ; col--; ) + FORC3 smrow[0][col][c] = ipix[c] = + (shrink[(row/4)*(width/4)+col/4][c]*1485 + ipix[c]*6707 + 4096) >> 13; + + /* Then smooth left-to-right */ + ipix[0] = ipix[1] = ipix[2] = 0; + for (col=0; col < (width & ~3); col++) + FORC3 smrow[1][col][c] = ipix[c] = + (smrow[0][col][c]*1485 + ipix[c]*6707 + 4096) >> 13; + + /* Smooth top-to-bottom */ + if (row == 0) + memcpy (smrow[2], smrow[1], sizeof **smrow * width); + else + for (col=0; col < (width & ~3); col++) + FORC3 smrow[2][col][c] = + (smrow[2][col][c]*6707 + smrow[1][col][c]*1485 + 4096) >> 13; + + /* Adjust the chroma toward the smooth values */ + for (col=0; col < (width & ~3); col++) { + for (i=j=30, c=0; c < 3; c++) { + i += smrow[2][col][c]; + j += image[row*width+col][c]; + } + j = (j << 16) / i; + for (sum=c=0; c < 3; c++) { + ipix[c] = foveon_apply_curve (curve[c+3], + ((smrow[2][col][c] * j + 0x8000) >> 16) - image[row*width+col][c]); + sum += ipix[c]; + } + sum >>= 3; + FORC3 { + i = image[row*width+col][c] + ipix[c] - sum; + if (i < 0) i = 0; + image[row*width+col][c] = i; + } + } + } + free (shrink); + free (smrow[6]); + for (i=0; i < 8; i++) + free (curve[i]); + + /* Trim off the black border */ + active[1] -= keep[1]; + active[3] -= 2; + i = active[2] - active[0]; + for (row=0; row < active[3]-active[1]; row++) + memcpy (image[row*i], image[(row+active[1])*width+active[0]], + i * sizeof *image); + width = i; + height = row; +} +#undef image + +/* RESTRICTED code ends here */ + +void CLASS crop_masked_pixels() +{ + int row, col; + unsigned r, c, m, mblack[8], zero, val; + + if (load_raw == &CLASS phase_one_load_raw || + load_raw == &CLASS phase_one_load_raw_c) + phase_one_correct(); + if (fuji_width) { + for (row=0; row < raw_height-top_margin*2; row++) { + for (col=0; col < fuji_width << !fuji_layout; col++) { + if (fuji_layout) { + r = fuji_width - 1 - col + (row >> 1); + c = col + ((row+1) >> 1); + } else { + r = fuji_width - 1 + row - (col >> 1); + c = row + ((col+1) >> 1); + } + if (r < height && c < width) + BAYER(r,c) = RAW(row+top_margin,col+left_margin); + } + } + } else { + for (row=0; row < height; row++) + for (col=0; col < width; col++) + BAYER2(row,col) = RAW(row+top_margin,col+left_margin); + } + if (mask[0][3] > 0) goto mask_set; + if (load_raw == &CLASS canon_load_raw || + load_raw == &CLASS lossless_jpeg_load_raw) { + mask[0][1] = mask[1][1] += 2; + mask[0][3] -= 2; + goto sides; + } + if (load_raw == &CLASS canon_600_load_raw || + load_raw == &CLASS sony_load_raw || + (load_raw == &CLASS eight_bit_load_raw && strncmp(model,"DC2",3)) || + load_raw == &CLASS kodak_262_load_raw || + (load_raw == &CLASS packed_load_raw && (load_flags & 32))) { +sides: + mask[0][0] = mask[1][0] = top_margin; + mask[0][2] = mask[1][2] = top_margin+height; + mask[0][3] += left_margin; + mask[1][1] += left_margin+width; + mask[1][3] += raw_width; + } + if (load_raw == &CLASS nokia_load_raw) { + mask[0][2] = top_margin; + mask[0][3] = width; + } +mask_set: + memset (mblack, 0, sizeof mblack); + for (zero=m=0; m < 8; m++) + for (row=MAX(mask[m][0],0); row < MIN(mask[m][2],raw_height); row++) + for (col=MAX(mask[m][1],0); col < MIN(mask[m][3],raw_width); col++) { + c = FC(row-top_margin,col-left_margin); + mblack[c] += val = RAW(row,col); + mblack[4+c]++; + zero += !val; + } + if (load_raw == &CLASS canon_600_load_raw && width < raw_width) { + black = (mblack[0]+mblack[1]+mblack[2]+mblack[3]) / + (mblack[4]+mblack[5]+mblack[6]+mblack[7]) - 4; + canon_600_correct(); + } else if (zero < mblack[4] && mblack[5] && mblack[6] && mblack[7]) { + FORC4 cblack[c] = mblack[c] / mblack[4+c]; + cblack[4] = cblack[5] = cblack[6] = 0; + } +} + +void CLASS remove_zeroes() +{ + unsigned row, col, tot, n, r, c; + + for (row=0; row < height; row++) + for (col=0; col < width; col++) + if (BAYER(row,col) == 0) { + tot = n = 0; + for (r = row-2; r <= row+2; r++) + for (c = col-2; c <= col+2; c++) + if (r < height && c < width && + FC(r,c) == FC(row,col) && BAYER(r,c)) + tot += (n++,BAYER(r,c)); + if (n) BAYER(row,col) = tot/n; + } +} + +/* + Seach from the current directory up to the root looking for + a ".badpixels" file, and fix those pixels now. + */ +void CLASS bad_pixels (const char *cfname) +{ + FILE *fp=0; + char *fname, *cp, line[128]; + int len, time, row, col, r, c, rad, tot, n, fixed=0; + + if (!filters) return; + if (cfname) + fp = fopen (cfname, "r"); + else { + for (len=32 ; ; len *= 2) { + fname = (char *) malloc (len); + if (!fname) return; + if (getcwd (fname, len-16)) break; + free (fname); + if (errno != ERANGE) return; + } +#if defined(WIN32) || defined(DJGPP) + if (fname[1] == ':') + memmove (fname, fname+2, len-2); + for (cp=fname; *cp; cp++) + if (*cp == '\\') *cp = '/'; +#endif + cp = fname + strlen(fname); + if (cp[-1] == '/') cp--; + while (*fname == '/') { + strcpy (cp, "/.badpixels"); + if ((fp = fopen (fname, "r"))) break; + if (cp == fname) break; + while (*--cp != '/'); + } + free (fname); + } + if (!fp) return; + while (fgets (line, 128, fp)) { + cp = strchr (line, '#'); + if (cp) *cp = 0; + if (sscanf (line, "%d %d %d", &col, &row, &time) != 3) continue; + if ((unsigned) col >= width || (unsigned) row >= height) continue; + if (time > timestamp) continue; + for (tot=n=0, rad=1; rad < 3 && n==0; rad++) + for (r = row-rad; r <= row+rad; r++) + for (c = col-rad; c <= col+rad; c++) + if ((unsigned) r < height && (unsigned) c < width && + (r != row || c != col) && fcol(r,c) == fcol(row,col)) { + tot += BAYER2(r,c); + n++; + } + BAYER2(row,col) = tot/n; + if (verbose) { + if (!fixed++) + fprintf (stderr,_("Fixed dead pixels at:")); + fprintf (stderr, " %d,%d", col, row); + } + } + if (fixed) fputc ('\n', stderr); + fclose (fp); +} + +void CLASS subtract (const char *fname) +{ + FILE *fp; + int dim[3]={0,0,0}, comment=0, number=0, error=0, nd=0, c, row, col; + ushort *pixel; + + if (!(fp = fopen (fname, "rb"))) { + perror (fname); return; + } + if (fgetc(fp) != 'P' || fgetc(fp) != '5') error = 1; + while (!error && nd < 3 && (c = fgetc(fp)) != EOF) { + if (c == '#') comment = 1; + if (c == '\n') comment = 0; + if (comment) continue; + if (isdigit(c)) number = 1; + if (number) { + if (isdigit(c)) dim[nd] = dim[nd]*10 + c -'0'; + else if (isspace(c)) { + number = 0; nd++; + } else error = 1; + } + } + if (error || nd < 3) { + fprintf (stderr,_("%s is not a valid PGM file!\n"), fname); + fclose (fp); return; + } else if (dim[0] != width || dim[1] != height || dim[2] != 65535) { + fprintf (stderr,_("%s has the wrong dimensions!\n"), fname); + fclose (fp); return; + } + pixel = (ushort *) calloc (width, sizeof *pixel); + merror (pixel, "subtract()"); + for (row=0; row < height; row++) { + fread (pixel, 2, width, fp); + for (col=0; col < width; col++) + BAYER(row,col) = MAX (BAYER(row,col) - ntohs(pixel[col]), 0); + } + free (pixel); + fclose (fp); + memset (cblack, 0, sizeof cblack); + black = 0; +} + +void CLASS gamma_curve (double pwr, double ts, int mode, int imax) +{ + int i; + double g[6], bnd[2]={0,0}, r; + + g[0] = pwr; + g[1] = ts; + g[2] = g[3] = g[4] = 0; + bnd[g[1] >= 1] = 1; + if (g[1] && (g[1]-1)*(g[0]-1) <= 0) { + for (i=0; i < 48; i++) { + g[2] = (bnd[0] + bnd[1])/2; + if (g[0]) bnd[(pow(g[2]/g[1],-g[0]) - 1)/g[0] - 1/g[2] > -1] = g[2]; + else bnd[g[2]/exp(1-1/g[2]) < g[1]] = g[2]; + } + g[3] = g[2] / g[1]; + if (g[0]) g[4] = g[2] * (1/g[0] - 1); + } + if (g[0]) g[5] = 1 / (g[1]*SQR(g[3])/2 - g[4]*(1 - g[3]) + + (1 - pow(g[3],1+g[0]))*(1 + g[4])/(1 + g[0])) - 1; + else g[5] = 1 / (g[1]*SQR(g[3])/2 + 1 + - g[2] - g[3] - g[2]*g[3]*(log(g[3]) - 1)) - 1; + if (!mode--) { + memcpy (gamm, g, sizeof gamm); + return; + } + for (i=0; i < 0x10000; i++) { + curve[i] = 0xffff; + if ((r = (double) i / imax) < 1) + curve[i] = 0x10000 * ( mode + ? (r < g[3] ? r*g[1] : (g[0] ? pow( r,g[0])*(1+g[4])-g[4] : log(r)*g[2]+1)) + : (r < g[2] ? r/g[1] : (g[0] ? pow((r+g[4])/(1+g[4]),1/g[0]) : exp((r-1)/g[2])))); + } +} + +void CLASS pseudoinverse (double (*in)[3], double (*out)[3], int size) +{ + double work[3][6], num; + int i, j, k; + + for (i=0; i < 3; i++) { + for (j=0; j < 6; j++) + work[i][j] = j == i+3; + for (j=0; j < 3; j++) + for (k=0; k < size; k++) + work[i][j] += in[k][i] * in[k][j]; + } + for (i=0; i < 3; i++) { + num = work[i][i]; + for (j=0; j < 6; j++) + work[i][j] /= num; + for (k=0; k < 3; k++) { + if (k==i) continue; + num = work[k][i]; + for (j=0; j < 6; j++) + work[k][j] -= work[i][j] * num; + } + } + for (i=0; i < size; i++) + for (j=0; j < 3; j++) + for (out[i][j]=k=0; k < 3; k++) + out[i][j] += work[j][k+3] * in[i][k]; +} + +void CLASS cam_xyz_coeff (float rgb_cam[3][4], double cam_xyz[4][3]) +{ + double cam_rgb[4][3], inverse[4][3], num; + int i, j, k; + + for (i=0; i < colors; i++) /* Multiply out XYZ colorspace */ + for (j=0; j < 3; j++) + for (cam_rgb[i][j] = k=0; k < 3; k++) + cam_rgb[i][j] += cam_xyz[i][k] * xyz_rgb[k][j]; + + for (i=0; i < colors; i++) { /* Normalize cam_rgb so that */ + for (num=j=0; j < 3; j++) /* cam_rgb * (1,1,1) is (1,1,1,1) */ + num += cam_rgb[i][j]; + for (j=0; j < 3; j++) + cam_rgb[i][j] /= num; + pre_mul[i] = 1 / num; + } + pseudoinverse (cam_rgb, inverse, colors); + for (i=0; i < 3; i++) + for (j=0; j < colors; j++) + rgb_cam[i][j] = inverse[j][i]; +} + +#ifdef COLORCHECK +void CLASS colorcheck() +{ +#define NSQ 24 +// Coordinates of the GretagMacbeth ColorChecker squares +// width, height, 1st_column, 1st_row + int cut[NSQ][4]; // you must set these +// ColorChecker Chart under 6500-kelvin illumination + static const double gmb_xyY[NSQ][3] = { + { 0.400, 0.350, 10.1 }, // Dark Skin + { 0.377, 0.345, 35.8 }, // Light Skin + { 0.247, 0.251, 19.3 }, // Blue Sky + { 0.337, 0.422, 13.3 }, // Foliage + { 0.265, 0.240, 24.3 }, // Blue Flower + { 0.261, 0.343, 43.1 }, // Bluish Green + { 0.506, 0.407, 30.1 }, // Orange + { 0.211, 0.175, 12.0 }, // Purplish Blue + { 0.453, 0.306, 19.8 }, // Moderate Red + { 0.285, 0.202, 6.6 }, // Purple + { 0.380, 0.489, 44.3 }, // Yellow Green + { 0.473, 0.438, 43.1 }, // Orange Yellow + { 0.187, 0.129, 6.1 }, // Blue + { 0.305, 0.478, 23.4 }, // Green + { 0.539, 0.313, 12.0 }, // Red + { 0.448, 0.470, 59.1 }, // Yellow + { 0.364, 0.233, 19.8 }, // Magenta + { 0.196, 0.252, 19.8 }, // Cyan + { 0.310, 0.316, 90.0 }, // White + { 0.310, 0.316, 59.1 }, // Neutral 8 + { 0.310, 0.316, 36.2 }, // Neutral 6.5 + { 0.310, 0.316, 19.8 }, // Neutral 5 + { 0.310, 0.316, 9.0 }, // Neutral 3.5 + { 0.310, 0.316, 3.1 } }; // Black + double gmb_cam[NSQ][4], gmb_xyz[NSQ][3]; + double inverse[NSQ][3], cam_xyz[4][3], balance[4], num; + int c, i, j, k, sq, row, col, pass, count[4]; + + memset (gmb_cam, 0, sizeof gmb_cam); + for (sq=0; sq < NSQ; sq++) { + FORCC count[c] = 0; + for (row=cut[sq][3]; row < cut[sq][3]+cut[sq][1]; row++) + for (col=cut[sq][2]; col < cut[sq][2]+cut[sq][0]; col++) { + c = FC(row,col); + if (c >= colors) c -= 2; + gmb_cam[sq][c] += BAYER2(row,col); + BAYER2(row,col) = black + (BAYER2(row,col)-black)/2; + count[c]++; + } + FORCC gmb_cam[sq][c] = gmb_cam[sq][c]/count[c] - black; + gmb_xyz[sq][0] = gmb_xyY[sq][2] * gmb_xyY[sq][0] / gmb_xyY[sq][1]; + gmb_xyz[sq][1] = gmb_xyY[sq][2]; + gmb_xyz[sq][2] = gmb_xyY[sq][2] * + (1 - gmb_xyY[sq][0] - gmb_xyY[sq][1]) / gmb_xyY[sq][1]; + } + pseudoinverse (gmb_xyz, inverse, NSQ); + for (pass=0; pass < 2; pass++) { + for (raw_color = i=0; i < colors; i++) + for (j=0; j < 3; j++) + for (cam_xyz[i][j] = k=0; k < NSQ; k++) + cam_xyz[i][j] += gmb_cam[k][i] * inverse[k][j]; + cam_xyz_coeff (rgb_cam, cam_xyz); + FORCC balance[c] = pre_mul[c] * gmb_cam[20][c]; + for (sq=0; sq < NSQ; sq++) + FORCC gmb_cam[sq][c] *= balance[c]; + } + if (verbose) { + printf (" { \"%s %s\", %d,\n\t{", make, model, black); + num = 10000 / (cam_xyz[1][0] + cam_xyz[1][1] + cam_xyz[1][2]); + FORCC for (j=0; j < 3; j++) + printf ("%c%d", (c | j) ? ',':' ', (int) (cam_xyz[c][j] * num + 0.5)); + puts (" } },"); + } +#undef NSQ +} +#endif + +void CLASS hat_transform (float *temp, float *base, int st, int size, int sc) +{ + int i; + for (i=0; i < sc; i++) + temp[i] = 2*base[st*i] + base[st*(sc-i)] + base[st*(i+sc)]; + for (; i+sc < size; i++) + temp[i] = 2*base[st*i] + base[st*(i-sc)] + base[st*(i+sc)]; + for (; i < size; i++) + temp[i] = 2*base[st*i] + base[st*(i-sc)] + base[st*(2*size-2-(i+sc))]; +} + +void CLASS wavelet_denoise() +{ + float *fimg=0, *temp, thold, mul[2], avg, diff; + int scale=1, size, lev, hpass, lpass, row, col, nc, c, i, wlast, blk[2]; + ushort *window[4]; + static const float noise[] = + { 0.8002,0.2735,0.1202,0.0585,0.0291,0.0152,0.0080,0.0044 }; + + if (verbose) fprintf (stderr,_("Wavelet denoising...\n")); + + while (maximum << scale < 0x10000) scale++; + maximum <<= --scale; + black <<= scale; + FORC4 cblack[c] <<= scale; + if ((size = iheight*iwidth) < 0x15550000) + fimg = (float *) malloc ((size*3 + iheight + iwidth) * sizeof *fimg); + merror (fimg, "wavelet_denoise()"); + temp = fimg + size*3; + if ((nc = colors) == 3 && filters) nc++; + FORC(nc) { /* denoise R,G1,B,G3 individually */ + for (i=0; i < size; i++) + fimg[i] = 256 * sqrt(image[i][c] << scale); + for (hpass=lev=0; lev < 5; lev++) { + lpass = size*((lev & 1)+1); + for (row=0; row < iheight; row++) { + hat_transform (temp, fimg+hpass+row*iwidth, 1, iwidth, 1 << lev); + for (col=0; col < iwidth; col++) + fimg[lpass + row*iwidth + col] = temp[col] * 0.25; + } + for (col=0; col < iwidth; col++) { + hat_transform (temp, fimg+lpass+col, iwidth, iheight, 1 << lev); + for (row=0; row < iheight; row++) + fimg[lpass + row*iwidth + col] = temp[row] * 0.25; + } + thold = threshold * noise[lev]; + for (i=0; i < size; i++) { + fimg[hpass+i] -= fimg[lpass+i]; + if (fimg[hpass+i] < -thold) fimg[hpass+i] += thold; + else if (fimg[hpass+i] > thold) fimg[hpass+i] -= thold; + else fimg[hpass+i] = 0; + if (hpass) fimg[i] += fimg[hpass+i]; + } + hpass = lpass; + } + for (i=0; i < size; i++) + image[i][c] = CLIP(SQR(fimg[i]+fimg[lpass+i])/0x10000); + } + if (filters && colors == 3) { /* pull G1 and G3 closer together */ + for (row=0; row < 2; row++) { + mul[row] = 0.125 * pre_mul[FC(row+1,0) | 1] / pre_mul[FC(row,0) | 1]; + blk[row] = cblack[FC(row,0) | 1]; + } + for (i=0; i < 4; i++) + window[i] = (ushort *) fimg + width*i; + for (wlast=-1, row=1; row < height-1; row++) { + while (wlast < row+1) { + for (wlast++, i=0; i < 4; i++) + window[(i+3) & 3] = window[i]; + for (col = FC(wlast,1) & 1; col < width; col+=2) + window[2][col] = BAYER(wlast,col); + } + thold = threshold/512; + for (col = (FC(row,0) & 1)+1; col < width-1; col+=2) { + avg = ( window[0][col-1] + window[0][col+1] + + window[2][col-1] + window[2][col+1] - blk[~row & 1]*4 ) + * mul[row & 1] + (window[1][col] + blk[row & 1]) * 0.5; + avg = avg < 0 ? 0 : sqrt(avg); + diff = sqrt(BAYER(row,col)) - avg; + if (diff < -thold) diff += thold; + else if (diff > thold) diff -= thold; + else diff = 0; + BAYER(row,col) = CLIP(SQR(avg+diff) + 0.5); + } + } + } + free (fimg); +} + +void CLASS scale_colors() +{ + unsigned bottom, right, size, row, col, ur, uc, i, x, y, c, sum[8]; + int val, dark, sat; + double dsum[8], dmin, dmax; + float scale_mul[4], fr, fc; + ushort *img=0, *pix; + + if (user_mul[0]) + memcpy (pre_mul, user_mul, sizeof pre_mul); + if (use_auto_wb || (use_camera_wb && cam_mul[0] == -1)) { + memset (dsum, 0, sizeof dsum); + bottom = MIN (greybox[1]+greybox[3], height); + right = MIN (greybox[0]+greybox[2], width); + for (row=greybox[1]; row < bottom; row += 8) + for (col=greybox[0]; col < right; col += 8) { + memset (sum, 0, sizeof sum); + for (y=row; y < row+8 && y < bottom; y++) + for (x=col; x < col+8 && x < right; x++) + FORC4 { + if (filters) { + c = fcol(y,x); + val = BAYER2(y,x); + } else + val = image[y*width+x][c]; + if (val > maximum-25) goto skip_block; + if ((val -= cblack[c]) < 0) val = 0; + sum[c] += val; + sum[c+4]++; + if (filters) break; + } + FORC(8) dsum[c] += sum[c]; +skip_block: ; + } + FORC4 if (dsum[c]) pre_mul[c] = dsum[c+4] / dsum[c]; + } + if (use_camera_wb && cam_mul[0] != -1) { + memset (sum, 0, sizeof sum); + for (row=0; row < 8; row++) + for (col=0; col < 8; col++) { + c = FC(row,col); + if ((val = white[row][col] - cblack[c]) > 0) + sum[c] += val; + sum[c+4]++; + } + if (sum[0] && sum[1] && sum[2] && sum[3]) + FORC4 pre_mul[c] = (float) sum[c+4] / sum[c]; + else if (cam_mul[0] && cam_mul[2]) + memcpy (pre_mul, cam_mul, sizeof pre_mul); + else + fprintf (stderr,_("%s: Cannot use camera white balance.\n"), ifname); + } + if (pre_mul[1] == 0) pre_mul[1] = 1; + if (pre_mul[3] == 0) pre_mul[3] = colors < 4 ? pre_mul[1] : 1; + dark = black; + sat = maximum; + if (threshold) wavelet_denoise(); + maximum -= black; + for (dmin=DBL_MAX, dmax=c=0; c < 4; c++) { + if (dmin > pre_mul[c]) + dmin = pre_mul[c]; + if (dmax < pre_mul[c]) + dmax = pre_mul[c]; + } + if (!highlight) dmax = dmin; + FORC4 scale_mul[c] = (pre_mul[c] /= dmax) * 65535.0 / maximum; + if (verbose) { + fprintf (stderr, + _("Scaling with darkness %d, saturation %d, and\nmultipliers"), dark, sat); + FORC4 fprintf (stderr, " %f", pre_mul[c]); + fputc ('\n', stderr); + } + if (filters > 1000 && (cblack[4]+1)/2 == 1 && (cblack[5]+1)/2 == 1) { + FORC4 cblack[FC(c/2,c%2)] += + cblack[6 + c/2 % cblack[4] * cblack[5] + c%2 % cblack[5]]; + cblack[4] = cblack[5] = 0; + } + size = iheight*iwidth; + for (i=0; i < size*4; i++) { + if (!(val = ((ushort *)image)[i])) continue; + if (cblack[4] && cblack[5]) + val -= cblack[6 + i/4 / iwidth % cblack[4] * cblack[5] + + i/4 % iwidth % cblack[5]]; + val -= cblack[i & 3]; + val *= scale_mul[i & 3]; + ((ushort *)image)[i] = CLIP(val); + } + if ((aber[0] != 1 || aber[2] != 1) && colors == 3) { + if (verbose) + fprintf (stderr,_("Correcting chromatic aberration...\n")); + for (c=0; c < 4; c+=2) { + if (aber[c] == 1) continue; + img = (ushort *) malloc (size * sizeof *img); + merror (img, "scale_colors()"); + for (i=0; i < size; i++) + img[i] = image[i][c]; + for (row=0; row < iheight; row++) { + ur = fr = (row - iheight*0.5) * aber[c] + iheight*0.5; + if (ur > iheight-2) continue; + fr -= ur; + for (col=0; col < iwidth; col++) { + uc = fc = (col - iwidth*0.5) * aber[c] + iwidth*0.5; + if (uc > iwidth-2) continue; + fc -= uc; + pix = img + ur*iwidth + uc; + image[row*iwidth+col][c] = + (pix[ 0]*(1-fc) + pix[ 1]*fc) * (1-fr) + + (pix[iwidth]*(1-fc) + pix[iwidth+1]*fc) * fr; + } + } + free(img); + } + } +} + +void CLASS pre_interpolate() +{ + ushort (*img)[4]; + int row, col, c; + + if (shrink) { + if (half_size) { + height = iheight; + width = iwidth; + if (filters == 9) { + for (row=0; row < 3; row++) + for (col=1; col < 4; col++) + if (!(image[row*width+col][0] | image[row*width+col][2])) + goto break2; break2: + for ( ; row < height; row+=3) + for (col=(col-1)%3+1; col < width-1; col+=3) { + img = image + row*width+col; + for (c=0; c < 3; c+=2) + img[0][c] = (img[-1][c] + img[1][c]) >> 1; + } + } + } else { + img = (ushort (*)[4]) calloc (height, width*sizeof *img); + merror (img, "pre_interpolate()"); + for (row=0; row < height; row++) + for (col=0; col < width; col++) { + c = fcol(row,col); + img[row*width+col][c] = image[(row >> 1)*iwidth+(col >> 1)][c]; + } + free (image); + image = img; + shrink = 0; + } + } + if (filters > 1000 && colors == 3) { + mix_green = four_color_rgb ^ half_size; + if (four_color_rgb | half_size) colors++; + else { + for (row = FC(1,0) >> 1; row < height; row+=2) + for (col = FC(row,1) & 1; col < width; col+=2) + image[row*width+col][1] = image[row*width+col][3]; + filters &= ~((filters & 0x55555555) << 1); + } + } + if (half_size) filters = 0; +} + +void CLASS border_interpolate (int border) +{ + unsigned row, col, y, x, f, c, sum[8]; + + for (row=0; row < height; row++) + for (col=0; col < width; col++) { + if (col==border && row >= border && row < height-border) + col = width-border; + memset (sum, 0, sizeof sum); + for (y=row-1; y != row+2; y++) + for (x=col-1; x != col+2; x++) + if (y < height && x < width) { + f = fcol(y,x); + sum[f] += image[y*width+x][f]; + sum[f+4]++; + } + f = fcol(row,col); + FORCC if (c != f && sum[c+4]) + image[row*width+col][c] = sum[c] / sum[c+4]; + } +} + +void CLASS lin_interpolate() +{ + int code[16][16][32], size=16, *ip, sum[4]; + int f, c, i, x, y, row, col, shift, color; + ushort *pix; + + if (verbose) fprintf (stderr,_("Bilinear interpolation...\n")); + if (filters == 9) size = 6; + border_interpolate(1); + for (row=0; row < size; row++) + for (col=0; col < size; col++) { + ip = code[row][col]+1; + f = fcol(row,col); + memset (sum, 0, sizeof sum); + for (y=-1; y <= 1; y++) + for (x=-1; x <= 1; x++) { + shift = (y==0) + (x==0); + color = fcol(row+y,col+x); + if (color == f) continue; + *ip++ = (width*y + x)*4 + color; + *ip++ = shift; + *ip++ = color; + sum[color] += 1 << shift; + } + code[row][col][0] = (ip - code[row][col]) / 3; + FORCC + if (c != f) { + *ip++ = c; + *ip++ = 256 / sum[c]; + } + } + for (row=1; row < height-1; row++) + for (col=1; col < width-1; col++) { + pix = image[row*width+col]; + ip = code[row % size][col % size]; + memset (sum, 0, sizeof sum); + for (i=*ip++; i--; ip+=3) + sum[ip[2]] += pix[ip[0]] << ip[1]; + for (i=colors; --i; ip+=2) + pix[ip[0]] = sum[ip[0]] * ip[1] >> 8; + } +} + +/* + This algorithm is officially called: + + "Interpolation using a Threshold-based variable number of gradients" + + described in http://scien.stanford.edu/pages/labsite/1999/psych221/projects/99/tingchen/algodep/vargra.html + + I've extended the basic idea to work with non-Bayer filter arrays. + Gradients are numbered clockwise from NW=0 to W=7. + */ +void CLASS vng_interpolate() +{ + static const signed char *cp, terms[] = { + -2,-2,+0,-1,0,0x01, -2,-2,+0,+0,1,0x01, -2,-1,-1,+0,0,0x01, + -2,-1,+0,-1,0,0x02, -2,-1,+0,+0,0,0x03, -2,-1,+0,+1,1,0x01, + -2,+0,+0,-1,0,0x06, -2,+0,+0,+0,1,0x02, -2,+0,+0,+1,0,0x03, + -2,+1,-1,+0,0,0x04, -2,+1,+0,-1,1,0x04, -2,+1,+0,+0,0,0x06, + -2,+1,+0,+1,0,0x02, -2,+2,+0,+0,1,0x04, -2,+2,+0,+1,0,0x04, + -1,-2,-1,+0,0,0x80, -1,-2,+0,-1,0,0x01, -1,-2,+1,-1,0,0x01, + -1,-2,+1,+0,1,0x01, -1,-1,-1,+1,0,0x88, -1,-1,+1,-2,0,0x40, + -1,-1,+1,-1,0,0x22, -1,-1,+1,+0,0,0x33, -1,-1,+1,+1,1,0x11, + -1,+0,-1,+2,0,0x08, -1,+0,+0,-1,0,0x44, -1,+0,+0,+1,0,0x11, + -1,+0,+1,-2,1,0x40, -1,+0,+1,-1,0,0x66, -1,+0,+1,+0,1,0x22, + -1,+0,+1,+1,0,0x33, -1,+0,+1,+2,1,0x10, -1,+1,+1,-1,1,0x44, + -1,+1,+1,+0,0,0x66, -1,+1,+1,+1,0,0x22, -1,+1,+1,+2,0,0x10, + -1,+2,+0,+1,0,0x04, -1,+2,+1,+0,1,0x04, -1,+2,+1,+1,0,0x04, + +0,-2,+0,+0,1,0x80, +0,-1,+0,+1,1,0x88, +0,-1,+1,-2,0,0x40, + +0,-1,+1,+0,0,0x11, +0,-1,+2,-2,0,0x40, +0,-1,+2,-1,0,0x20, + +0,-1,+2,+0,0,0x30, +0,-1,+2,+1,1,0x10, +0,+0,+0,+2,1,0x08, + +0,+0,+2,-2,1,0x40, +0,+0,+2,-1,0,0x60, +0,+0,+2,+0,1,0x20, + +0,+0,+2,+1,0,0x30, +0,+0,+2,+2,1,0x10, +0,+1,+1,+0,0,0x44, + +0,+1,+1,+2,0,0x10, +0,+1,+2,-1,1,0x40, +0,+1,+2,+0,0,0x60, + +0,+1,+2,+1,0,0x20, +0,+1,+2,+2,0,0x10, +1,-2,+1,+0,0,0x80, + +1,-1,+1,+1,0,0x88, +1,+0,+1,+2,0,0x08, +1,+0,+2,-1,0,0x40, + +1,+0,+2,+1,0,0x10 + }, chood[] = { -1,-1, -1,0, -1,+1, 0,+1, +1,+1, +1,0, +1,-1, 0,-1 }; + ushort (*brow[5])[4], *pix; + int prow=8, pcol=2, *ip, *code[16][16], gval[8], gmin, gmax, sum[4]; + int row, col, x, y, x1, x2, y1, y2, t, weight, grads, color, diag; + int g, diff, thold, num, c; + + lin_interpolate(); + if (verbose) fprintf (stderr,_("VNG interpolation...\n")); + + if (filters == 1) prow = pcol = 16; + if (filters == 9) prow = pcol = 6; + ip = (int *) calloc (prow*pcol, 1280); + merror (ip, "vng_interpolate()"); + for (row=0; row < prow; row++) /* Precalculate for VNG */ + for (col=0; col < pcol; col++) { + code[row][col] = ip; + for (cp=terms, t=0; t < 64; t++) { + y1 = *cp++; x1 = *cp++; + y2 = *cp++; x2 = *cp++; + weight = *cp++; + grads = *cp++; + color = fcol(row+y1,col+x1); + if (fcol(row+y2,col+x2) != color) continue; + diag = (fcol(row,col+1) == color && fcol(row+1,col) == color) ? 2:1; + if (abs(y1-y2) == diag && abs(x1-x2) == diag) continue; + *ip++ = (y1*width + x1)*4 + color; + *ip++ = (y2*width + x2)*4 + color; + *ip++ = weight; + for (g=0; g < 8; g++) + if (grads & 1< gval[g]) gmin = gval[g]; + if (gmax < gval[g]) gmax = gval[g]; + } + if (gmax == 0) { + memcpy (brow[2][col], pix, sizeof *image); + continue; + } + thold = gmin + (gmax >> 1); + memset (sum, 0, sizeof sum); + color = fcol(row,col); + for (num=g=0; g < 8; g++,ip+=2) { /* Average the neighbors */ + if (gval[g] <= thold) { + FORCC + if (c == color && ip[1]) + sum[c] += (pix[c] + pix[ip[1]]) >> 1; + else + sum[c] += pix[ip[0] + c]; + num++; + } + } + FORCC { /* Save to buffer */ + t = pix[color]; + if (c != color) + t += (sum[c] - sum[color]) / num; + brow[2][col][c] = CLIP(t); + } + } + if (row > 3) /* Write buffer to image */ + memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image); + for (g=0; g < 4; g++) + brow[(g-1) & 3] = brow[g]; + } + memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image); + memcpy (image[(row-1)*width+2], brow[1]+2, (width-4)*sizeof *image); + free (brow[4]); + free (code[0][0]); +} + +/* + Patterned Pixel Grouping Interpolation by Alain Desbiolles +*/ +void CLASS ppg_interpolate() +{ + int dir[5] = { 1, width, -1, -width, 1 }; + int row, col, diff[2], guess[2], c, d, i; + ushort (*pix)[4]; + + border_interpolate(3); + if (verbose) fprintf (stderr,_("PPG interpolation...\n")); + +/* Fill in the green layer with gradients and pattern recognition: */ + for (row=3; row < height-3; row++) + for (col=3+(FC(row,3) & 1), c=FC(row,col); col < width-3; col+=2) { + pix = image + row*width+col; + for (i=0; (d=dir[i]) > 0; i++) { + guess[i] = (pix[-d][1] + pix[0][c] + pix[d][1]) * 2 + - pix[-2*d][c] - pix[2*d][c]; + diff[i] = ( ABS(pix[-2*d][c] - pix[ 0][c]) + + ABS(pix[ 2*d][c] - pix[ 0][c]) + + ABS(pix[ -d][1] - pix[ d][1]) ) * 3 + + ( ABS(pix[ 3*d][1] - pix[ d][1]) + + ABS(pix[-3*d][1] - pix[-d][1]) ) * 2; + } + d = dir[i = diff[0] > diff[1]]; + pix[0][1] = ULIM(guess[i] >> 2, pix[d][1], pix[-d][1]); + } +/* Calculate red and blue for each green pixel: */ + for (row=1; row < height-1; row++) + for (col=1+(FC(row,2) & 1), c=FC(row,col+1); col < width-1; col+=2) { + pix = image + row*width+col; + for (i=0; (d=dir[i]) > 0; c=2-c, i++) + pix[0][c] = CLIP((pix[-d][c] + pix[d][c] + 2*pix[0][1] + - pix[-d][1] - pix[d][1]) >> 1); + } +/* Calculate blue for red pixels and vice versa: */ + for (row=1; row < height-1; row++) + for (col=1+(FC(row,1) & 1), c=2-FC(row,col); col < width-1; col+=2) { + pix = image + row*width+col; + for (i=0; (d=dir[i]+dir[i+1]) > 0; i++) { + diff[i] = ABS(pix[-d][c] - pix[d][c]) + + ABS(pix[-d][1] - pix[0][1]) + + ABS(pix[ d][1] - pix[0][1]); + guess[i] = pix[-d][c] + pix[d][c] + 2*pix[0][1] + - pix[-d][1] - pix[d][1]; + } + if (diff[0] != diff[1]) + pix[0][c] = CLIP(guess[diff[0] > diff[1]] >> 1); + else + pix[0][c] = CLIP((guess[0]+guess[1]) >> 2); + } +} + +void CLASS cielab (ushort rgb[3], short lab[3]) +{ + int c, i, j, k; + float r, xyz[3]; + static float cbrt[0x10000], xyz_cam[3][4]; + + if (!rgb) { + for (i=0; i < 0x10000; i++) { + r = i / 65535.0; + cbrt[i] = r > 0.008856 ? pow(r,1/3.0) : 7.787*r + 16/116.0; + } + for (i=0; i < 3; i++) + for (j=0; j < colors; j++) + for (xyz_cam[i][j] = k=0; k < 3; k++) + xyz_cam[i][j] += xyz_rgb[i][k] * rgb_cam[k][j] / d65_white[i]; + return; + } + xyz[0] = xyz[1] = xyz[2] = 0.5; + FORCC { + xyz[0] += xyz_cam[0][c] * rgb[c]; + xyz[1] += xyz_cam[1][c] * rgb[c]; + xyz[2] += xyz_cam[2][c] * rgb[c]; + } + xyz[0] = cbrt[CLIP((int) xyz[0])]; + xyz[1] = cbrt[CLIP((int) xyz[1])]; + xyz[2] = cbrt[CLIP((int) xyz[2])]; + lab[0] = 64 * (116 * xyz[1] - 16); + lab[1] = 64 * 500 * (xyz[0] - xyz[1]); + lab[2] = 64 * 200 * (xyz[1] - xyz[2]); +} + +#define TS 512 /* Tile Size */ +#define fcol(row,col) xtrans[(row+6) % 6][(col+6) % 6] + +/* + Frank Markesteijn's algorithm for Fuji X-Trans sensors + */ +void CLASS xtrans_interpolate (int passes) +{ + int c, d, f, g, h, i, v, ng, row, col, top, left, mrow, mcol; + int val, ndir, pass, hm[8], avg[4], color[3][8]; + static const short orth[12] = { 1,0,0,1,-1,0,0,-1,1,0,0,1 }, + patt[2][16] = { { 0,1,0,-1,2,0,-1,0,1,1,1,-1,0,0,0,0 }, + { 0,1,0,-2,1,0,-2,0,1,1,-2,-2,1,-1,-1,1 } }, + dir[4] = { 1,TS,TS+1,TS-1 }; + short allhex[3][3][2][8], *hex; + ushort min, max, sgrow, sgcol; + ushort (*rgb)[TS][TS][3], (*rix)[3], (*pix)[4]; + short (*lab) [TS][3], (*lix)[3]; + float (*drv)[TS][TS], diff[6], tr; + char (*homo)[TS][TS], *buffer; + + if (verbose) + fprintf (stderr,_("%d-pass X-Trans interpolation...\n"), passes); + + cielab (0,0); + ndir = 4 << (passes > 1); + buffer = (char *) malloc (TS*TS*(ndir*11+6)); + merror (buffer, "xtrans_interpolate()"); + rgb = (ushort(*)[TS][TS][3]) buffer; + lab = (short (*) [TS][3])(buffer + TS*TS*(ndir*6)); + drv = (float (*)[TS][TS]) (buffer + TS*TS*(ndir*6+6)); + homo = (char (*)[TS][TS]) (buffer + TS*TS*(ndir*10+6)); + +/* Map a green hexagon around each non-green pixel and vice versa: */ + for (row=0; row < 3; row++) + for (col=0; col < 3; col++) + for (ng=d=0; d < 10; d+=2) { + g = fcol(row,col) == 1; + if (fcol(row+orth[d],col+orth[d+2]) == 1) ng=0; else ng++; + if (ng == 4) { sgrow = row; sgcol = col; } + if (ng == g+1) FORC(8) { + v = orth[d ]*patt[g][c*2] + orth[d+1]*patt[g][c*2+1]; + h = orth[d+2]*patt[g][c*2] + orth[d+3]*patt[g][c*2+1]; + allhex[row][col][0][c^(g*2 & d)] = h + v*width; + allhex[row][col][1][c^(g*2 & d)] = h + v*TS; + } + } + +/* Set green1 and green3 to the minimum and maximum allowed values: */ + for (row=2; row < height-2; row++) + for (min=~(max=0), col=2; col < width-2; col++) { + if (fcol(row,col) == 1 && (min=~(max=0))) continue; + pix = image + row*width + col; + hex = allhex[row % 3][col % 3][0]; + if (!max) FORC(6) { + val = pix[hex[c]][1]; + if (min > val) min = val; + if (max < val) max = val; + } + pix[0][1] = min; + pix[0][3] = max; + switch ((row-sgrow) % 3) { + case 1: if (row < height-3) { row++; col--; } break; + case 2: if ((min=~(max=0)) && (col+=2) < width-3 && row > 2) row--; + } + } + + for (top=3; top < height-19; top += TS-16) + for (left=3; left < width-19; left += TS-16) { + mrow = MIN (top+TS, height-3); + mcol = MIN (left+TS, width-3); + for (row=top; row < mrow; row++) + for (col=left; col < mcol; col++) + memcpy (rgb[0][row-top][col-left], image[row*width+col], 6); + FORC3 memcpy (rgb[c+1], rgb[0], sizeof *rgb); + +/* Interpolate green horizontally, vertically, and along both diagonals: */ + for (row=top; row < mrow; row++) + for (col=left; col < mcol; col++) { + if ((f = fcol(row,col)) == 1) continue; + pix = image + row*width + col; + hex = allhex[row % 3][col % 3][0]; + color[1][0] = 174 * (pix[ hex[1]][1] + pix[ hex[0]][1]) - + 46 * (pix[2*hex[1]][1] + pix[2*hex[0]][1]); + color[1][1] = 223 * pix[ hex[3]][1] + pix[ hex[2]][1] * 33 + + 92 * (pix[ 0 ][f] - pix[ -hex[2]][f]); + FORC(2) color[1][2+c] = + 164 * pix[hex[4+c]][1] + 92 * pix[-2*hex[4+c]][1] + 33 * + (2*pix[0][f] - pix[3*hex[4+c]][f] - pix[-3*hex[4+c]][f]); + FORC4 rgb[c^!((row-sgrow) % 3)][row-top][col-left][1] = + LIM(color[1][c] >> 8,pix[0][1],pix[0][3]); + } + + for (pass=0; pass < passes; pass++) { + if (pass == 1) + memcpy (rgb+=4, buffer, 4*sizeof *rgb); + +/* Recalculate green from interpolated values of closer pixels: */ + if (pass) { + for (row=top+2; row < mrow-2; row++) + for (col=left+2; col < mcol-2; col++) { + if ((f = fcol(row,col)) == 1) continue; + pix = image + row*width + col; + hex = allhex[row % 3][col % 3][1]; + for (d=3; d < 6; d++) { + rix = &rgb[(d-2)^!((row-sgrow) % 3)][row-top][col-left]; + val = rix[-2*hex[d]][1] + 2*rix[hex[d]][1] + - rix[-2*hex[d]][f] - 2*rix[hex[d]][f] + 3*rix[0][f]; + rix[0][1] = LIM(val/3,pix[0][1],pix[0][3]); + } + } + } + +/* Interpolate red and blue values for solitary green pixels: */ + for (row=(top-sgrow+4)/3*3+sgrow; row < mrow-2; row+=3) + for (col=(left-sgcol+4)/3*3+sgcol; col < mcol-2; col+=3) { + rix = &rgb[0][row-top][col-left]; + h = fcol(row,col+1); + memset (diff, 0, sizeof diff); + for (i=1, d=0; d < 6; d++, i^=TS^1, h^=2) { + for (c=0; c < 2; c++, h^=2) { + g = 2*rix[0][1] - rix[i< 1) + diff[d] += SQR (rix[i< 1 && (d & 1)) + if (diff[d-1] < diff[d]) + FORC(2) color[c*2][d] = color[c*2][d-1]; + if (d < 2 || (d & 1)) { + FORC(2) rix[0][c*2] = CLIP(color[c*2][d]/2); + rix += TS*TS; + } + } + } + +/* Interpolate red for blue pixels and vice versa: */ + for (row=top+3; row < mrow-3; row++) + for (col=left+3; col < mcol-3; col++) { + if ((f = 2-fcol(row,col)) == 1) continue; + rix = &rgb[0][row-top][col-left]; + c = (row-sgrow) % 3 ? TS:1; + h = 3 * (c ^ TS ^ 1); + for (d=0; d < 4; d++, rix += TS*TS) { + i = d > 1 || ((d ^ c) & 1) || + ((ABS(rix[0][1]-rix[c][1])+ABS(rix[0][1]-rix[-c][1])) < + 2*(ABS(rix[0][1]-rix[h][1])+ABS(rix[0][1]-rix[-h][1]))) ? c:h; + rix[0][f] = CLIP((rix[i][f] + rix[-i][f] + + 2*rix[0][1] - rix[i][1] - rix[-i][1])/2); + } + } + +/* Fill in red and blue for 2x2 blocks of green: */ + for (row=top+2; row < mrow-2; row++) if ((row-sgrow) % 3) + for (col=left+2; col < mcol-2; col++) if ((col-sgcol) % 3) { + rix = &rgb[0][row-top][col-left]; + hex = allhex[row % 3][col % 3][1]; + for (d=0; d < ndir; d+=2, rix += TS*TS) + if (hex[d] + hex[d+1]) { + g = 3*rix[0][1] - 2*rix[hex[d]][1] - rix[hex[d+1]][1]; + for (c=0; c < 4; c+=2) rix[0][c] = + CLIP((g + 2*rix[hex[d]][c] + rix[hex[d+1]][c])/3); + } else { + g = 2*rix[0][1] - rix[hex[d]][1] - rix[hex[d+1]][1]; + for (c=0; c < 4; c+=2) rix[0][c] = + CLIP((g + rix[hex[d]][c] + rix[hex[d+1]][c])/2); + } + } + } + rgb = (ushort(*)[TS][TS][3]) buffer; + mrow -= top; + mcol -= left; + +/* Convert to CIELab and differentiate in all directions: */ + for (d=0; d < ndir; d++) { + for (row=2; row < mrow-2; row++) + for (col=2; col < mcol-2; col++) + cielab (rgb[d][row][col], lab[row][col]); + for (f=dir[d & 3],row=3; row < mrow-3; row++) + for (col=3; col < mcol-3; col++) { + lix = &lab[row][col]; + g = 2*lix[0][0] - lix[f][0] - lix[-f][0]; + drv[d][row][col] = SQR(g) + + SQR((2*lix[0][1] - lix[f][1] - lix[-f][1] + g*500/232)) + + SQR((2*lix[0][2] - lix[f][2] - lix[-f][2] - g*500/580)); + } + } + +/* Build homogeneity maps from the derivatives: */ + memset(homo, 0, ndir*TS*TS); + for (row=4; row < mrow-4; row++) + for (col=4; col < mcol-4; col++) { + for (tr=FLT_MAX, d=0; d < ndir; d++) + if (tr > drv[d][row][col]) + tr = drv[d][row][col]; + tr *= 8; + for (d=0; d < ndir; d++) + for (v=-1; v <= 1; v++) + for (h=-1; h <= 1; h++) + if (drv[d][row+v][col+h] <= tr) + homo[d][row][col]++; + } + +/* Average the most homogenous pixels for the final result: */ + if (height-top < TS+4) mrow = height-top+2; + if (width-left < TS+4) mcol = width-left+2; + for (row = MIN(top,8); row < mrow-8; row++) + for (col = MIN(left,8); col < mcol-8; col++) { + for (d=0; d < ndir; d++) + for (hm[d]=0, v=-2; v <= 2; v++) + for (h=-2; h <= 2; h++) + hm[d] += homo[d][row+v][col+h]; + for (d=0; d < ndir-4; d++) + if (hm[d] < hm[d+4]) hm[d ] = 0; else + if (hm[d] > hm[d+4]) hm[d+4] = 0; + for (max=hm[0],d=1; d < ndir; d++) + if (max < hm[d]) max = hm[d]; + max -= max >> 3; + memset (avg, 0, sizeof avg); + for (d=0; d < ndir; d++) + if (hm[d] >= max) { + FORC3 avg[c] += rgb[d][row][col][c]; + avg[3]++; + } + FORC3 image[(row+top)*width+col+left][c] = avg[c]/avg[3]; + } + } + free(buffer); + border_interpolate(8); +} +#undef fcol + +/* + Adaptive Homogeneity-Directed interpolation is based on + the work of Keigo Hirakawa, Thomas Parks, and Paul Lee. + */ +void CLASS ahd_interpolate() +{ + int i, j, top, left, row, col, tr, tc, c, d, val, hm[2]; + static const int dir[4] = { -1, 1, -TS, TS }; + unsigned ldiff[2][4], abdiff[2][4], leps, abeps; + ushort (*rgb)[TS][TS][3], (*rix)[3], (*pix)[4]; + short (*lab)[TS][TS][3], (*lix)[3]; + char (*homo)[TS][TS], *buffer; + + if (verbose) fprintf (stderr,_("AHD interpolation...\n")); + + cielab (0,0); + border_interpolate(5); + buffer = (char *) malloc (26*TS*TS); + merror (buffer, "ahd_interpolate()"); + rgb = (ushort(*)[TS][TS][3]) buffer; + lab = (short (*)[TS][TS][3])(buffer + 12*TS*TS); + homo = (char (*)[TS][TS]) (buffer + 24*TS*TS); + + for (top=2; top < height-5; top += TS-6) + for (left=2; left < width-5; left += TS-6) { + +/* Interpolate green horizontally and vertically: */ + for (row=top; row < top+TS && row < height-2; row++) { + col = left + (FC(row,left) & 1); + for (c = FC(row,col); col < left+TS && col < width-2; col+=2) { + pix = image + row*width+col; + val = ((pix[-1][1] + pix[0][c] + pix[1][1]) * 2 + - pix[-2][c] - pix[2][c]) >> 2; + rgb[0][row-top][col-left][1] = ULIM(val,pix[-1][1],pix[1][1]); + val = ((pix[-width][1] + pix[0][c] + pix[width][1]) * 2 + - pix[-2*width][c] - pix[2*width][c]) >> 2; + rgb[1][row-top][col-left][1] = ULIM(val,pix[-width][1],pix[width][1]); + } + } +/* Interpolate red and blue, and convert to CIELab: */ + for (d=0; d < 2; d++) + for (row=top+1; row < top+TS-1 && row < height-3; row++) + for (col=left+1; col < left+TS-1 && col < width-3; col++) { + pix = image + row*width+col; + rix = &rgb[d][row-top][col-left]; + lix = &lab[d][row-top][col-left]; + if ((c = 2 - FC(row,col)) == 1) { + c = FC(row+1,col); + val = pix[0][1] + (( pix[-1][2-c] + pix[1][2-c] + - rix[-1][1] - rix[1][1] ) >> 1); + rix[0][2-c] = CLIP(val); + val = pix[0][1] + (( pix[-width][c] + pix[width][c] + - rix[-TS][1] - rix[TS][1] ) >> 1); + } else + val = rix[0][1] + (( pix[-width-1][c] + pix[-width+1][c] + + pix[+width-1][c] + pix[+width+1][c] + - rix[-TS-1][1] - rix[-TS+1][1] + - rix[+TS-1][1] - rix[+TS+1][1] + 1) >> 2); + rix[0][c] = CLIP(val); + c = FC(row,col); + rix[0][c] = pix[0][c]; + cielab (rix[0],lix[0]); + } +/* Build homogeneity maps from the CIELab images: */ + memset (homo, 0, 2*TS*TS); + for (row=top+2; row < top+TS-2 && row < height-4; row++) { + tr = row-top; + for (col=left+2; col < left+TS-2 && col < width-4; col++) { + tc = col-left; + for (d=0; d < 2; d++) { + lix = &lab[d][tr][tc]; + for (i=0; i < 4; i++) { + ldiff[d][i] = ABS(lix[0][0]-lix[dir[i]][0]); + abdiff[d][i] = SQR(lix[0][1]-lix[dir[i]][1]) + + SQR(lix[0][2]-lix[dir[i]][2]); + } + } + leps = MIN(MAX(ldiff[0][0],ldiff[0][1]), + MAX(ldiff[1][2],ldiff[1][3])); + abeps = MIN(MAX(abdiff[0][0],abdiff[0][1]), + MAX(abdiff[1][2],abdiff[1][3])); + for (d=0; d < 2; d++) + for (i=0; i < 4; i++) + if (ldiff[d][i] <= leps && abdiff[d][i] <= abeps) + homo[d][tr][tc]++; + } + } +/* Combine the most homogenous pixels for the final result: */ + for (row=top+3; row < top+TS-3 && row < height-5; row++) { + tr = row-top; + for (col=left+3; col < left+TS-3 && col < width-5; col++) { + tc = col-left; + for (d=0; d < 2; d++) + for (hm[d]=0, i=tr-1; i <= tr+1; i++) + for (j=tc-1; j <= tc+1; j++) + hm[d] += homo[d][i][j]; + if (hm[0] != hm[1]) + FORC3 image[row*width+col][c] = rgb[hm[1] > hm[0]][tr][tc][c]; + else + FORC3 image[row*width+col][c] = + (rgb[0][tr][tc][c] + rgb[1][tr][tc][c]) >> 1; + } + } + } + free (buffer); +} +#undef TS + +void CLASS median_filter() +{ + ushort (*pix)[4]; + int pass, c, i, j, k, med[9]; + static const uchar opt[] = /* Optimal 9-element median search */ + { 1,2, 4,5, 7,8, 0,1, 3,4, 6,7, 1,2, 4,5, 7,8, + 0,3, 5,8, 4,7, 3,6, 1,4, 2,5, 4,7, 4,2, 6,4, 4,2 }; + + for (pass=1; pass <= med_passes; pass++) { + if (verbose) + fprintf (stderr,_("Median filter pass %d...\n"), pass); + for (c=0; c < 3; c+=2) { + for (pix = image; pix < image+width*height; pix++) + pix[0][3] = pix[0][c]; + for (pix = image+width; pix < image+width*(height-1); pix++) { + if ((pix-image+1) % width < 2) continue; + for (k=0, i = -width; i <= width; i += width) + for (j = i-1; j <= i+1; j++) + med[k++] = pix[j][3] - pix[j][1]; + for (i=0; i < sizeof opt; i+=2) + if (med[opt[i]] > med[opt[i+1]]) + SWAP (med[opt[i]] , med[opt[i+1]]); + pix[0][c] = CLIP(med[4] + pix[0][1]); + } + } + } +} + +void CLASS blend_highlights() +{ + int clip=INT_MAX, row, col, c, i, j; + static const float trans[2][4][4] = + { { { 1,1,1 }, { 1.7320508,-1.7320508,0 }, { -1,-1,2 } }, + { { 1,1,1,1 }, { 1,-1,1,-1 }, { 1,1,-1,-1 }, { 1,-1,-1,1 } } }; + static const float itrans[2][4][4] = + { { { 1,0.8660254,-0.5 }, { 1,-0.8660254,-0.5 }, { 1,0,1 } }, + { { 1,1,1,1 }, { 1,-1,1,-1 }, { 1,1,-1,-1 }, { 1,-1,-1,1 } } }; + float cam[2][4], lab[2][4], sum[2], chratio; + + if ((unsigned) (colors-3) > 1) return; + if (verbose) fprintf (stderr,_("Blending highlights...\n")); + FORCC if (clip > (i = 65535*pre_mul[c])) clip = i; + for (row=0; row < height; row++) + for (col=0; col < width; col++) { + FORCC if (image[row*width+col][c] > clip) break; + if (c == colors) continue; + FORCC { + cam[0][c] = image[row*width+col][c]; + cam[1][c] = MIN(cam[0][c],clip); + } + for (i=0; i < 2; i++) { + FORCC for (lab[i][c]=j=0; j < colors; j++) + lab[i][c] += trans[colors-3][c][j] * cam[i][j]; + for (sum[i]=0,c=1; c < colors; c++) + sum[i] += SQR(lab[i][c]); + } + chratio = sqrt(sum[1]/sum[0]); + for (c=1; c < colors; c++) + lab[0][c] *= chratio; + FORCC for (cam[0][c]=j=0; j < colors; j++) + cam[0][c] += itrans[colors-3][c][j] * lab[0][j]; + FORCC image[row*width+col][c] = cam[0][c] / colors; + } +} + +#define SCALE (4 >> shrink) +void CLASS recover_highlights() +{ + float *map, sum, wgt, grow; + int hsat[4], count, spread, change, val, i; + unsigned high, wide, mrow, mcol, row, col, kc, c, d, y, x; + ushort *pixel; + static const signed char dir[8][2] = + { {-1,-1}, {-1,0}, {-1,1}, {0,1}, {1,1}, {1,0}, {1,-1}, {0,-1} }; + + if (verbose) fprintf (stderr,_("Rebuilding highlights...\n")); + + grow = pow (2, 4-highlight); + FORCC hsat[c] = 32000 * pre_mul[c]; + for (kc=0, c=1; c < colors; c++) + if (pre_mul[kc] < pre_mul[c]) kc = c; + high = height / SCALE; + wide = width / SCALE; + map = (float *) calloc (high, wide*sizeof *map); + merror (map, "recover_highlights()"); + FORCC if (c != kc) { + memset (map, 0, high*wide*sizeof *map); + for (mrow=0; mrow < high; mrow++) + for (mcol=0; mcol < wide; mcol++) { + sum = wgt = count = 0; + for (row = mrow*SCALE; row < (mrow+1)*SCALE; row++) + for (col = mcol*SCALE; col < (mcol+1)*SCALE; col++) { + pixel = image[row*width+col]; + if (pixel[c] / hsat[c] == 1 && pixel[kc] > 24000) { + sum += pixel[c]; + wgt += pixel[kc]; + count++; + } + } + if (count == SCALE*SCALE) + map[mrow*wide+mcol] = sum / wgt; + } + for (spread = 32/grow; spread--; ) { + for (mrow=0; mrow < high; mrow++) + for (mcol=0; mcol < wide; mcol++) { + if (map[mrow*wide+mcol]) continue; + sum = count = 0; + for (d=0; d < 8; d++) { + y = mrow + dir[d][0]; + x = mcol + dir[d][1]; + if (y < high && x < wide && map[y*wide+x] > 0) { + sum += (1 + (d & 1)) * map[y*wide+x]; + count += 1 + (d & 1); + } + } + if (count > 3) + map[mrow*wide+mcol] = - (sum+grow) / (count+grow); + } + for (change=i=0; i < high*wide; i++) + if (map[i] < 0) { + map[i] = -map[i]; + change = 1; + } + if (!change) break; + } + for (i=0; i < high*wide; i++) + if (map[i] == 0) map[i] = 1; + for (mrow=0; mrow < high; mrow++) + for (mcol=0; mcol < wide; mcol++) { + for (row = mrow*SCALE; row < (mrow+1)*SCALE; row++) + for (col = mcol*SCALE; col < (mcol+1)*SCALE; col++) { + pixel = image[row*width+col]; + if (pixel[c] / hsat[c] > 1) { + val = pixel[kc] * map[mrow*wide+mcol]; + if (pixel[c] < val) pixel[c] = CLIP(val); + } + } + } + } + free (map); +} +#undef SCALE + +void CLASS tiff_get (unsigned base, + unsigned *tag, unsigned *type, unsigned *len, unsigned *save) +{ + *tag = get2(); + *type = get2(); + *len = get4(); + *save = ftell(ifp) + 4; + if (*len * ("11124811248484"[*type < 14 ? *type:0]-'0') > 4) + fseek (ifp, get4()+base, SEEK_SET); +} + +void CLASS parse_thumb_note (int base, unsigned toff, unsigned tlen) +{ + unsigned entries, tag, type, len, save; + + entries = get2(); + while (entries--) { + tiff_get (base, &tag, &type, &len, &save); + if (tag == toff) thumb_offset = get4()+base; + if (tag == tlen) thumb_length = get4(); + fseek (ifp, save, SEEK_SET); + } +} + +int CLASS parse_tiff_ifd (int base); + +void CLASS parse_makernote (int base, int uptag) +{ + static const uchar xlat[2][256] = { + { 0xc1,0xbf,0x6d,0x0d,0x59,0xc5,0x13,0x9d,0x83,0x61,0x6b,0x4f,0xc7,0x7f,0x3d,0x3d, + 0x53,0x59,0xe3,0xc7,0xe9,0x2f,0x95,0xa7,0x95,0x1f,0xdf,0x7f,0x2b,0x29,0xc7,0x0d, + 0xdf,0x07,0xef,0x71,0x89,0x3d,0x13,0x3d,0x3b,0x13,0xfb,0x0d,0x89,0xc1,0x65,0x1f, + 0xb3,0x0d,0x6b,0x29,0xe3,0xfb,0xef,0xa3,0x6b,0x47,0x7f,0x95,0x35,0xa7,0x47,0x4f, + 0xc7,0xf1,0x59,0x95,0x35,0x11,0x29,0x61,0xf1,0x3d,0xb3,0x2b,0x0d,0x43,0x89,0xc1, + 0x9d,0x9d,0x89,0x65,0xf1,0xe9,0xdf,0xbf,0x3d,0x7f,0x53,0x97,0xe5,0xe9,0x95,0x17, + 0x1d,0x3d,0x8b,0xfb,0xc7,0xe3,0x67,0xa7,0x07,0xf1,0x71,0xa7,0x53,0xb5,0x29,0x89, + 0xe5,0x2b,0xa7,0x17,0x29,0xe9,0x4f,0xc5,0x65,0x6d,0x6b,0xef,0x0d,0x89,0x49,0x2f, + 0xb3,0x43,0x53,0x65,0x1d,0x49,0xa3,0x13,0x89,0x59,0xef,0x6b,0xef,0x65,0x1d,0x0b, + 0x59,0x13,0xe3,0x4f,0x9d,0xb3,0x29,0x43,0x2b,0x07,0x1d,0x95,0x59,0x59,0x47,0xfb, + 0xe5,0xe9,0x61,0x47,0x2f,0x35,0x7f,0x17,0x7f,0xef,0x7f,0x95,0x95,0x71,0xd3,0xa3, + 0x0b,0x71,0xa3,0xad,0x0b,0x3b,0xb5,0xfb,0xa3,0xbf,0x4f,0x83,0x1d,0xad,0xe9,0x2f, + 0x71,0x65,0xa3,0xe5,0x07,0x35,0x3d,0x0d,0xb5,0xe9,0xe5,0x47,0x3b,0x9d,0xef,0x35, + 0xa3,0xbf,0xb3,0xdf,0x53,0xd3,0x97,0x53,0x49,0x71,0x07,0x35,0x61,0x71,0x2f,0x43, + 0x2f,0x11,0xdf,0x17,0x97,0xfb,0x95,0x3b,0x7f,0x6b,0xd3,0x25,0xbf,0xad,0xc7,0xc5, + 0xc5,0xb5,0x8b,0xef,0x2f,0xd3,0x07,0x6b,0x25,0x49,0x95,0x25,0x49,0x6d,0x71,0xc7 }, + { 0xa7,0xbc,0xc9,0xad,0x91,0xdf,0x85,0xe5,0xd4,0x78,0xd5,0x17,0x46,0x7c,0x29,0x4c, + 0x4d,0x03,0xe9,0x25,0x68,0x11,0x86,0xb3,0xbd,0xf7,0x6f,0x61,0x22,0xa2,0x26,0x34, + 0x2a,0xbe,0x1e,0x46,0x14,0x68,0x9d,0x44,0x18,0xc2,0x40,0xf4,0x7e,0x5f,0x1b,0xad, + 0x0b,0x94,0xb6,0x67,0xb4,0x0b,0xe1,0xea,0x95,0x9c,0x66,0xdc,0xe7,0x5d,0x6c,0x05, + 0xda,0xd5,0xdf,0x7a,0xef,0xf6,0xdb,0x1f,0x82,0x4c,0xc0,0x68,0x47,0xa1,0xbd,0xee, + 0x39,0x50,0x56,0x4a,0xdd,0xdf,0xa5,0xf8,0xc6,0xda,0xca,0x90,0xca,0x01,0x42,0x9d, + 0x8b,0x0c,0x73,0x43,0x75,0x05,0x94,0xde,0x24,0xb3,0x80,0x34,0xe5,0x2c,0xdc,0x9b, + 0x3f,0xca,0x33,0x45,0xd0,0xdb,0x5f,0xf5,0x52,0xc3,0x21,0xda,0xe2,0x22,0x72,0x6b, + 0x3e,0xd0,0x5b,0xa8,0x87,0x8c,0x06,0x5d,0x0f,0xdd,0x09,0x19,0x93,0xd0,0xb9,0xfc, + 0x8b,0x0f,0x84,0x60,0x33,0x1c,0x9b,0x45,0xf1,0xf0,0xa3,0x94,0x3a,0x12,0x77,0x33, + 0x4d,0x44,0x78,0x28,0x3c,0x9e,0xfd,0x65,0x57,0x16,0x94,0x6b,0xfb,0x59,0xd0,0xc8, + 0x22,0x36,0xdb,0xd2,0x63,0x98,0x43,0xa1,0x04,0x87,0x86,0xf7,0xa6,0x26,0xbb,0xd6, + 0x59,0x4d,0xbf,0x6a,0x2e,0xaa,0x2b,0xef,0xe6,0x78,0xb6,0x4e,0xe0,0x2f,0xdc,0x7c, + 0xbe,0x57,0x19,0x32,0x7e,0x2a,0xd0,0xb8,0xba,0x29,0x00,0x3c,0x52,0x7d,0xa8,0x49, + 0x3b,0x2d,0xeb,0x25,0x49,0xfa,0xa3,0xaa,0x39,0xa7,0xc5,0xa7,0x50,0x11,0x36,0xfb, + 0xc6,0x67,0x4a,0xf5,0xa5,0x12,0x65,0x7e,0xb0,0xdf,0xaf,0x4e,0xb3,0x61,0x7f,0x2f } }; + unsigned offset=0, entries, tag, type, len, save, c; + unsigned ver97=0, serial=0, i, wbi=0, wb[4]={0,0,0,0}; + uchar buf97[324], ci, cj, ck; + short morder, sorder=order; + char buf[10]; +/* + The MakerNote might have its own TIFF header (possibly with + its own byte-order!), or it might just be a table. + */ + if (!strcmp(make,"Nokia")) return; + fread (buf, 1, 10, ifp); + if (!strncmp (buf,"KDK" ,3) || /* these aren't TIFF tables */ + !strncmp (buf,"VER" ,3) || + !strncmp (buf,"IIII",4) || + !strncmp (buf,"MMMM",4)) return; + if (!strncmp (buf,"KC" ,2) || /* Konica KD-400Z, KD-510Z */ + !strncmp (buf,"MLY" ,3)) { /* Minolta DiMAGE G series */ + order = 0x4d4d; + while ((i=ftell(ifp)) < data_offset && i < 16384) { + wb[0] = wb[2]; wb[2] = wb[1]; wb[1] = wb[3]; + wb[3] = get2(); + if (wb[1] == 256 && wb[3] == 256 && + wb[0] > 256 && wb[0] < 640 && wb[2] > 256 && wb[2] < 640) + FORC4 cam_mul[c] = wb[c]; + } + goto quit; + } + if (!strcmp (buf,"Nikon")) { + base = ftell(ifp); + order = get2(); + if (get2() != 42) goto quit; + offset = get4(); + fseek (ifp, offset-8, SEEK_CUR); + } else if (!strcmp (buf,"OLYMPUS") || + !strcmp (buf,"PENTAX ")) { + base = ftell(ifp)-10; + fseek (ifp, -2, SEEK_CUR); + order = get2(); + if (buf[0] == 'O') get2(); + } else if (!strncmp (buf,"SONY",4) || + !strcmp (buf,"Panasonic")) { + goto nf; + } else if (!strncmp (buf,"FUJIFILM",8)) { + base = ftell(ifp)-10; +nf: order = 0x4949; + fseek (ifp, 2, SEEK_CUR); + } else if (!strcmp (buf,"OLYMP") || + !strcmp (buf,"LEICA") || + !strcmp (buf,"Ricoh") || + !strcmp (buf,"EPSON")) + fseek (ifp, -2, SEEK_CUR); + else if (!strcmp (buf,"AOC") || + !strcmp (buf,"QVC")) + fseek (ifp, -4, SEEK_CUR); + else { + fseek (ifp, -10, SEEK_CUR); + if (!strncmp(make,"SAMSUNG",7)) + base = ftell(ifp); + } + entries = get2(); + if (entries > 1000) return; + morder = order; + while (entries--) { + order = morder; + tiff_get (base, &tag, &type, &len, &save); + tag |= uptag << 16; + if (tag == 2 && strstr(make,"NIKON") && !iso_speed) + iso_speed = (get2(),get2()); + if (tag == 4 && len > 26 && len < 35) { + if ((i=(get4(),get2())) != 0x7fff && !iso_speed) + iso_speed = 50 * pow (2, i/32.0 - 4); + if ((i=(get2(),get2())) != 0x7fff && !aperture) + aperture = pow (2, i/64.0); + if ((i=get2()) != 0xffff && !shutter) + shutter = pow (2, (short) i/-32.0); + wbi = (get2(),get2()); + shot_order = (get2(),get2()); + } + if ((tag == 4 || tag == 0x114) && !strncmp(make,"KONICA",6)) { + fseek (ifp, tag == 4 ? 140:160, SEEK_CUR); + switch (get2()) { + case 72: flip = 0; break; + case 76: flip = 6; break; + case 82: flip = 5; break; + } + } + if (tag == 7 && type == 2 && len > 20) + fgets (model2, 64, ifp); + if (tag == 8 && type == 4) + shot_order = get4(); + if (tag == 9 && !strcmp(make,"Canon")) + fread (artist, 64, 1, ifp); + if (tag == 0xc && len == 4) + FORC3 cam_mul[(c << 1 | c >> 1) & 3] = getreal(type); + if (tag == 0xd && type == 7 && get2() == 0xaaaa) { + for (c=i=2; (ushort) c != 0xbbbb && i < len; i++) + c = c << 8 | fgetc(ifp); + while ((i+=4) < len-5) + if (get4() == 257 && (i=len) && (c = (get4(),fgetc(ifp))) < 3) + flip = "065"[c]-'0'; + } + if (tag == 0x10 && type == 4) + unique_id = get4(); + if (tag == 0x11 && is_raw && !strncmp(make,"NIKON",5)) { + fseek (ifp, get4()+base, SEEK_SET); + parse_tiff_ifd (base); + } + if (tag == 0x14 && type == 7) { + if (len == 2560) { + fseek (ifp, 1248, SEEK_CUR); + goto get2_256; + } + fread (buf, 1, 10, ifp); + if (!strncmp(buf,"NRW ",4)) { + fseek (ifp, strcmp(buf+4,"0100") ? 46:1546, SEEK_CUR); + cam_mul[0] = get4() << 2; + cam_mul[1] = get4() + get4(); + cam_mul[2] = get4() << 2; + } + } + if (tag == 0x15 && type == 2 && is_raw) + fread (model, 64, 1, ifp); + if (strstr(make,"PENTAX")) { + if (tag == 0x1b) tag = 0x1018; + if (tag == 0x1c) tag = 0x1017; + } + if (tag == 0x1d) + while ((c = fgetc(ifp)) && c != EOF) + serial = serial*10 + (isdigit(c) ? c - '0' : c % 10); + if (tag == 0x29 && type == 1) { + c = wbi < 18 ? "012347800000005896"[wbi]-'0' : 0; + fseek (ifp, 8 + c*32, SEEK_CUR); + FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get4(); + } + if (tag == 0x3d && type == 3 && len == 4) + FORC4 cblack[c ^ c >> 1] = get2() >> (14-tiff_ifd[2].bps); + if (tag == 0x81 && type == 4) { + data_offset = get4(); + fseek (ifp, data_offset + 41, SEEK_SET); + raw_height = get2() * 2; + raw_width = get2(); + filters = 0x61616161; + } + if ((tag == 0x81 && type == 7) || + (tag == 0x100 && type == 7) || + (tag == 0x280 && type == 1)) { + thumb_offset = ftell(ifp); + thumb_length = len; + } + if (tag == 0x88 && type == 4 && (thumb_offset = get4())) + thumb_offset += base; + if (tag == 0x89 && type == 4) + thumb_length = get4(); + if (tag == 0x8c || tag == 0x96) + meta_offset = ftell(ifp); + if (tag == 0x97) { + for (i=0; i < 4; i++) + ver97 = ver97 * 10 + fgetc(ifp)-'0'; + switch (ver97) { + case 100: + fseek (ifp, 68, SEEK_CUR); + FORC4 cam_mul[(c >> 1) | ((c & 1) << 1)] = get2(); + break; + case 102: + fseek (ifp, 6, SEEK_CUR); + goto get2_rggb; + case 103: + fseek (ifp, 16, SEEK_CUR); + FORC4 cam_mul[c] = get2(); + } + if (ver97 >= 200) { + if (ver97 != 205) fseek (ifp, 280, SEEK_CUR); + fread (buf97, 324, 1, ifp); + } + } + if (tag == 0xa1 && type == 7) { + order = 0x4949; + fseek (ifp, 140, SEEK_CUR); + FORC3 cam_mul[c] = get4(); + } + if (tag == 0xa4 && type == 3) { + fseek (ifp, wbi*48, SEEK_CUR); + FORC3 cam_mul[c] = get2(); + } + if (tag == 0xa7 && (unsigned) (ver97-200) < 17) { + ci = xlat[0][serial & 0xff]; + cj = xlat[1][fgetc(ifp)^fgetc(ifp)^fgetc(ifp)^fgetc(ifp)]; + ck = 0x60; + for (i=0; i < 324; i++) + buf97[i] ^= (cj += ci * ck++); + i = "66666>666;6A;:;55"[ver97-200] - '0'; + FORC4 cam_mul[c ^ (c >> 1) ^ (i & 1)] = + sget2 (buf97 + (i & -2) + c*2); + } + if (tag == 0x200 && len == 3) + shot_order = (get4(),get4()); + if (tag == 0x200 && len == 4) + FORC4 cblack[c ^ c >> 1] = get2(); + if (tag == 0x201 && len == 4) + goto get2_rggb; + if (tag == 0x220 && type == 7) + meta_offset = ftell(ifp); + if (tag == 0x401 && type == 4 && len == 4) + FORC4 cblack[c ^ c >> 1] = get4(); + if (tag == 0xe01) { /* Nikon Capture Note */ + order = 0x4949; + fseek (ifp, 22, SEEK_CUR); + for (offset=22; offset+22 < len; offset += 22+i) { + tag = get4(); + fseek (ifp, 14, SEEK_CUR); + i = get4()-4; + if (tag == 0x76a43207) flip = get2(); + else fseek (ifp, i, SEEK_CUR); + } + } + if (tag == 0xe80 && len == 256 && type == 7) { + fseek (ifp, 48, SEEK_CUR); + cam_mul[0] = get2() * 508 * 1.078 / 0x10000; + cam_mul[2] = get2() * 382 * 1.173 / 0x10000; + } + if (tag == 0xf00 && type == 7) { + if (len == 614) + fseek (ifp, 176, SEEK_CUR); + else if (len == 734 || len == 1502) + fseek (ifp, 148, SEEK_CUR); + else goto next; + goto get2_256; + } + if ((tag == 0x1011 && len == 9) || tag == 0x20400200) + for (i=0; i < 3; i++) + FORC3 cmatrix[i][c] = ((short) get2()) / 256.0; + if ((tag == 0x1012 || tag == 0x20400600) && len == 4) + FORC4 cblack[c ^ c >> 1] = get2(); + if (tag == 0x1017 || tag == 0x20400100) + cam_mul[0] = get2() / 256.0; + if (tag == 0x1018 || tag == 0x20400100) + cam_mul[2] = get2() / 256.0; + if (tag == 0x2011 && len == 2) { +get2_256: + order = 0x4d4d; + cam_mul[0] = get2() / 256.0; + cam_mul[2] = get2() / 256.0; + } + if ((tag | 0x70) == 0x2070 && (type == 4 || type == 13)) + fseek (ifp, get4()+base, SEEK_SET); + if (tag == 0x2020) + parse_thumb_note (base, 257, 258); + if (tag == 0x2040) + parse_makernote (base, 0x2040); + if (tag == 0xb028) { + fseek (ifp, get4()+base, SEEK_SET); + parse_thumb_note (base, 136, 137); + } + if (tag == 0x4001 && len > 500) { + i = len == 582 ? 50 : len == 653 ? 68 : len == 5120 ? 142 : 126; + fseek (ifp, i, SEEK_CUR); +get2_rggb: + FORC4 cam_mul[c ^ (c >> 1)] = get2(); + i = len >> 3 == 164 || len == 1506 ? 112:22; + fseek (ifp, i, SEEK_CUR); + FORC4 sraw_mul[c ^ (c >> 1)] = get2(); + } + if (tag == 0x4021 && get4() && get4()) + FORC4 cam_mul[c] = 1024; + if (tag == 0xa021) + FORC4 cam_mul[c ^ (c >> 1)] = get4(); + if (tag == 0xa028) + FORC4 cam_mul[c ^ (c >> 1)] -= get4(); + if (tag == 0xb001) + unique_id = get2(); +next: + fseek (ifp, save, SEEK_SET); + } +quit: + order = sorder; +} + +/* + Since the TIFF DateTime string has no timezone information, + assume that the camera's clock was set to Universal Time. + */ +void CLASS get_timestamp (int reversed) +{ + struct tm t; + char str[20]; + int i; + + str[19] = 0; + if (reversed) + for (i=19; i--; ) str[i] = fgetc(ifp); + else + fread (str, 19, 1, ifp); + memset (&t, 0, sizeof t); + if (sscanf (str, "%d:%d:%d %d:%d:%d", &t.tm_year, &t.tm_mon, + &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec) != 6) + return; + t.tm_year -= 1900; + t.tm_mon -= 1; + t.tm_isdst = -1; + if (mktime(&t) > 0) + timestamp = mktime(&t); +} + +void CLASS parse_exif (int base) +{ + unsigned kodak, entries, tag, type, len, save, c; + double expo; + + kodak = !strncmp(make,"EASTMAN",7) && tiff_nifds < 3; + entries = get2(); + while (entries--) { + tiff_get (base, &tag, &type, &len, &save); + switch (tag) { + case 33434: shutter = getreal(type); break; + case 33437: aperture = getreal(type); break; + case 34855: iso_speed = get2(); break; + case 36867: + case 36868: get_timestamp(0); break; + case 37377: if ((expo = -getreal(type)) < 128) + shutter = pow (2, expo); break; + case 37378: aperture = pow (2, getreal(type)/2); break; + case 37386: focal_len = getreal(type); break; + case 37500: parse_makernote (base, 0); break; + case 40962: if (kodak) raw_width = get4(); break; + case 40963: if (kodak) raw_height = get4(); break; + case 41730: + if (get4() == 0x20002) + for (exif_cfa=c=0; c < 8; c+=2) + exif_cfa |= fgetc(ifp) * 0x01010101 << c; + } + fseek (ifp, save, SEEK_SET); + } +} + +void CLASS parse_gps (int base) +{ + unsigned entries, tag, type, len, save, c; + + entries = get2(); + while (entries--) { + tiff_get (base, &tag, &type, &len, &save); + switch (tag) { + case 1: case 3: case 5: + gpsdata[29+tag/2] = getc(ifp); break; + case 2: case 4: case 7: + FORC(6) gpsdata[tag/3*6+c] = get4(); break; + case 6: + FORC(2) gpsdata[18+c] = get4(); break; + case 18: case 29: + fgets ((char *) (gpsdata+14+tag/3), MIN(len,12), ifp); + } + fseek (ifp, save, SEEK_SET); + } +} + +void CLASS romm_coeff (float romm_cam[3][3]) +{ + static const float rgb_romm[3][3] = /* ROMM == Kodak ProPhoto */ + { { 2.034193, -0.727420, -0.306766 }, + { -0.228811, 1.231729, -0.002922 }, + { -0.008565, -0.153273, 1.161839 } }; + int i, j, k; + + for (i=0; i < 3; i++) + for (j=0; j < 3; j++) + for (cmatrix[i][j] = k=0; k < 3; k++) + cmatrix[i][j] += rgb_romm[i][k] * romm_cam[k][j]; +} + +void CLASS parse_mos (int offset) +{ + char data[40]; + int skip, from, i, c, neut[4], planes=0, frot=0; + static const char *mod[] = + { "","DCB2","Volare","Cantare","CMost","Valeo 6","Valeo 11","Valeo 22", + "Valeo 11p","Valeo 17","","Aptus 17","Aptus 22","Aptus 75","Aptus 65", + "Aptus 54S","Aptus 65S","Aptus 75S","AFi 5","AFi 6","AFi 7", + "AFi-II 7","Aptus-II 7","","Aptus-II 6","","","Aptus-II 10","Aptus-II 5", + "","","","","Aptus-II 10R","Aptus-II 8","","Aptus-II 12","","AFi-II 12" }; + float romm_cam[3][3]; + + fseek (ifp, offset, SEEK_SET); + while (1) { + if (get4() != 0x504b5453) break; + get4(); + fread (data, 1, 40, ifp); + skip = get4(); + from = ftell(ifp); + if (!strcmp(data,"JPEG_preview_data")) { + thumb_offset = from; + thumb_length = skip; + } + if (!strcmp(data,"icc_camera_profile")) { + profile_offset = from; + profile_length = skip; + } + if (!strcmp(data,"ShootObj_back_type")) { + fscanf (ifp, "%d", &i); + if ((unsigned) i < sizeof mod / sizeof (*mod)) + strcpy (model, mod[i]); + } + if (!strcmp(data,"icc_camera_to_tone_matrix")) { + for (i=0; i < 9; i++) + ((float *)romm_cam)[i] = int_to_float(get4()); + romm_coeff (romm_cam); + } + if (!strcmp(data,"CaptProf_color_matrix")) { + for (i=0; i < 9; i++) + fscanf (ifp, "%f", (float *)romm_cam + i); + romm_coeff (romm_cam); + } + if (!strcmp(data,"CaptProf_number_of_planes")) + fscanf (ifp, "%d", &planes); + if (!strcmp(data,"CaptProf_raw_data_rotation")) + fscanf (ifp, "%d", &flip); + if (!strcmp(data,"CaptProf_mosaic_pattern")) + FORC4 { + fscanf (ifp, "%d", &i); + if (i == 1) frot = c ^ (c >> 1); + } + if (!strcmp(data,"ImgProf_rotation_angle")) { + fscanf (ifp, "%d", &i); + flip = i - flip; + } + if (!strcmp(data,"NeutObj_neutrals") && !cam_mul[0]) { + FORC4 fscanf (ifp, "%d", neut+c); + FORC3 cam_mul[c] = (float) neut[0] / neut[c+1]; + } + if (!strcmp(data,"Rows_data")) + load_flags = get4(); + parse_mos (from); + fseek (ifp, skip+from, SEEK_SET); + } + if (planes) + filters = (planes == 1) * 0x01010101 * + (uchar) "\x94\x61\x16\x49"[(flip/90 + frot) & 3]; +} + +void CLASS linear_table (unsigned len) +{ + int i; + if (len > 0x1000) len = 0x1000; + read_shorts (curve, len); + for (i=len; i < 0x1000; i++) + curve[i] = curve[i-1]; + maximum = curve[0xfff]; +} + +void CLASS parse_kodak_ifd (int base) +{ + unsigned entries, tag, type, len, save; + int i, c, wbi=-2, wbtemp=6500; + float mul[3]={1,1,1}, num; + static const int wbtag[] = { 64037,64040,64039,64041,-1,-1,64042 }; + + entries = get2(); + if (entries > 1024) return; + while (entries--) { + tiff_get (base, &tag, &type, &len, &save); + if (tag == 1020) wbi = getint(type); + if (tag == 1021 && len == 72) { /* WB set in software */ + fseek (ifp, 40, SEEK_CUR); + FORC3 cam_mul[c] = 2048.0 / get2(); + wbi = -2; + } + if (tag == 2118) wbtemp = getint(type); + if (tag == 2120 + wbi && wbi >= 0) + FORC3 cam_mul[c] = 2048.0 / getreal(type); + if (tag == 2130 + wbi) + FORC3 mul[c] = getreal(type); + if (tag == 2140 + wbi && wbi >= 0) + FORC3 { + for (num=i=0; i < 4; i++) + num += getreal(type) * pow (wbtemp/100.0, i); + cam_mul[c] = 2048 / (num * mul[c]); + } + if (tag == 2317) linear_table (len); + if (tag == 6020) iso_speed = getint(type); + if (tag == 64013) wbi = fgetc(ifp); + if ((unsigned) wbi < 7 && tag == wbtag[wbi]) + FORC3 cam_mul[c] = get4(); + if (tag == 64019) width = getint(type); + if (tag == 64020) height = (getint(type)+1) & -2; + fseek (ifp, save, SEEK_SET); + } +} + +void CLASS parse_minolta (int base); +int CLASS parse_tiff (int base); + +int CLASS parse_tiff_ifd (int base) +{ + unsigned entries, tag, type, len, plen=16, save; + int ifd, use_cm=0, cfa, i, j, c, ima_len=0; + char software[64], *cbuf, *cp; + uchar cfa_pat[16], cfa_pc[] = { 0,1,2,3 }, tab[256]; + double cc[4][4], cm[4][3], cam_xyz[4][3], num; + double ab[]={ 1,1,1,1 }, asn[] = { 0,0,0,0 }, xyz[] = { 1,1,1 }; + unsigned sony_curve[] = { 0,0,0,0,0,4095 }; + unsigned *buf, sony_offset=0, sony_length=0, sony_key=0; + struct jhead jh; + FILE *sfp; + + if (tiff_nifds >= sizeof tiff_ifd / sizeof tiff_ifd[0]) + return 1; + ifd = tiff_nifds++; + for (j=0; j < 4; j++) + for (i=0; i < 4; i++) + cc[j][i] = i == j; + entries = get2(); + if (entries > 512) return 1; + while (entries--) { + tiff_get (base, &tag, &type, &len, &save); + switch (tag) { + case 5: width = get2(); break; + case 6: height = get2(); break; + case 7: width += get2(); break; + case 9: if ((i = get2())) filters = i; break; + case 17: case 18: + if (type == 3 && len == 1) + cam_mul[(tag-17)*2] = get2() / 256.0; + break; + case 23: + if (type == 3) iso_speed = get2(); + break; + case 28: case 29: case 30: + cblack[tag-28] = get2(); + cblack[3] = cblack[1]; + break; + case 36: case 37: case 38: + cam_mul[tag-36] = get2(); + break; + case 39: + if (len < 50 || cam_mul[0]) break; + fseek (ifp, 12, SEEK_CUR); + FORC3 cam_mul[c] = get2(); + break; + case 46: + if (type != 7 || fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) break; + thumb_offset = ftell(ifp) - 2; + thumb_length = len; + break; + case 61440: /* Fuji HS10 table */ + fseek (ifp, get4()+base, SEEK_SET); + parse_tiff_ifd (base); + break; + case 2: case 256: case 61441: /* ImageWidth */ + tiff_ifd[ifd].width = getint(type); + break; + case 3: case 257: case 61442: /* ImageHeight */ + tiff_ifd[ifd].height = getint(type); + break; + case 258: /* BitsPerSample */ + case 61443: + tiff_ifd[ifd].samples = len & 7; + tiff_ifd[ifd].bps = getint(type); + break; + case 61446: + raw_height = 0; + if (tiff_ifd[ifd].bps > 12) break; + load_raw = &CLASS packed_load_raw; + load_flags = get4() ? 24:80; + break; + case 259: /* Compression */ + tiff_ifd[ifd].comp = getint(type); + break; + case 262: /* PhotometricInterpretation */ + tiff_ifd[ifd].phint = get2(); + break; + case 270: /* ImageDescription */ + fread (desc, 512, 1, ifp); + break; + case 271: /* Make */ + fgets (make, 64, ifp); + break; + case 272: /* Model */ + fgets (model, 64, ifp); + break; + case 280: /* Panasonic RW2 offset */ + if (type != 4) break; + load_raw = &CLASS panasonic_load_raw; + load_flags = 0x2008; + case 273: /* StripOffset */ + case 513: /* JpegIFOffset */ + case 61447: + tiff_ifd[ifd].offset = get4()+base; + if (!tiff_ifd[ifd].bps && tiff_ifd[ifd].offset > 0) { + fseek (ifp, tiff_ifd[ifd].offset, SEEK_SET); + if (ljpeg_start (&jh, 1)) { + tiff_ifd[ifd].comp = 6; + tiff_ifd[ifd].width = jh.wide; + tiff_ifd[ifd].height = jh.high; + tiff_ifd[ifd].bps = jh.bits; + tiff_ifd[ifd].samples = jh.clrs; + if (!(jh.sraw || (jh.clrs & 1))) + tiff_ifd[ifd].width *= jh.clrs; + if ((tiff_ifd[ifd].width > 4*tiff_ifd[ifd].height) & ~jh.clrs) { + tiff_ifd[ifd].width /= 2; + tiff_ifd[ifd].height *= 2; + } + i = order; + parse_tiff (tiff_ifd[ifd].offset + 12); + order = i; + } + } + break; + case 274: /* Orientation */ + tiff_ifd[ifd].flip = "50132467"[get2() & 7]-'0'; + break; + case 277: /* SamplesPerPixel */ + tiff_ifd[ifd].samples = getint(type) & 7; + break; + case 279: /* StripByteCounts */ + case 514: + case 61448: + tiff_ifd[ifd].bytes = get4(); + break; + case 61454: + FORC3 cam_mul[(4-c) % 3] = getint(type); + break; + case 305: case 11: /* Software */ + fgets (software, 64, ifp); + if (!strncmp(software,"Adobe",5) || + !strncmp(software,"dcraw",5) || + !strncmp(software,"UFRaw",5) || + !strncmp(software,"Bibble",6) || + !strncmp(software,"Nikon Scan",10) || + !strcmp (software,"Digital Photo Professional")) + is_raw = 0; + break; + case 306: /* DateTime */ + get_timestamp(0); + break; + case 315: /* Artist */ + fread (artist, 64, 1, ifp); + break; + case 322: /* TileWidth */ + tiff_ifd[ifd].tile_width = getint(type); + break; + case 323: /* TileLength */ + tiff_ifd[ifd].tile_length = getint(type); + break; + case 324: /* TileOffsets */ + tiff_ifd[ifd].offset = len > 1 ? ftell(ifp) : get4(); + if (len == 1) + tiff_ifd[ifd].tile_width = tiff_ifd[ifd].tile_length = 0; + if (len == 4) { + load_raw = &CLASS sinar_4shot_load_raw; + is_raw = 5; + } + break; + case 330: /* SubIFDs */ + if (!strcmp(model,"DSLR-A100") && tiff_ifd[ifd].width == 3872) { + load_raw = &CLASS sony_arw_load_raw; + data_offset = get4()+base; + ifd++; break; + } + while (len--) { + i = ftell(ifp); + fseek (ifp, get4()+base, SEEK_SET); + if (parse_tiff_ifd (base)) break; + fseek (ifp, i+4, SEEK_SET); + } + break; + case 400: + strcpy (make, "Sarnoff"); + maximum = 0xfff; + break; + case 28688: + FORC4 sony_curve[c+1] = get2() >> 2 & 0xfff; + for (i=0; i < 5; i++) + for (j = sony_curve[i]+1; j <= sony_curve[i+1]; j++) + curve[j] = curve[j-1] + (1 << i); + break; + case 29184: sony_offset = get4(); break; + case 29185: sony_length = get4(); break; + case 29217: sony_key = get4(); break; + case 29264: + parse_minolta (ftell(ifp)); + raw_width = 0; + break; + case 29443: + FORC4 cam_mul[c ^ (c < 2)] = get2(); + break; + case 29459: + FORC4 cam_mul[c] = get2(); + i = (cam_mul[1] == 1024 && cam_mul[2] == 1024) << 1; + SWAP (cam_mul[i],cam_mul[i+1]) + break; + case 33405: /* Model2 */ + fgets (model2, 64, ifp); + break; + case 33421: /* CFARepeatPatternDim */ + if (get2() == 6 && get2() == 6) + filters = 9; + break; + case 33422: /* CFAPattern */ + if (filters == 9) { + FORC(36) ((char *)xtrans)[c] = fgetc(ifp) & 3; + break; + } + case 64777: /* Kodak P-series */ + if ((plen=len) > 16) plen = 16; + fread (cfa_pat, 1, plen, ifp); + for (colors=cfa=i=0; i < plen && colors < 4; i++) { + colors += !(cfa & (1 << cfa_pat[i])); + cfa |= 1 << cfa_pat[i]; + } + if (cfa == 070) memcpy (cfa_pc,"\003\004\005",3); /* CMY */ + if (cfa == 072) memcpy (cfa_pc,"\005\003\004\001",4); /* GMCY */ + goto guess_cfa_pc; + case 33424: + case 65024: + fseek (ifp, get4()+base, SEEK_SET); + parse_kodak_ifd (base); + break; + case 33434: /* ExposureTime */ + shutter = getreal(type); + break; + case 33437: /* FNumber */ + aperture = getreal(type); + break; + case 34306: /* Leaf white balance */ + FORC4 cam_mul[c ^ 1] = 4096.0 / get2(); + break; + case 34307: /* Leaf CatchLight color matrix */ + fread (software, 1, 7, ifp); + if (strncmp(software,"MATRIX",6)) break; + colors = 4; + for (raw_color = i=0; i < 3; i++) { + FORC4 fscanf (ifp, "%f", &rgb_cam[i][c^1]); + if (!use_camera_wb) continue; + num = 0; + FORC4 num += rgb_cam[i][c]; + FORC4 rgb_cam[i][c] /= num; + } + break; + case 34310: /* Leaf metadata */ + parse_mos (ftell(ifp)); + case 34303: + strcpy (make, "Leaf"); + break; + case 34665: /* EXIF tag */ + fseek (ifp, get4()+base, SEEK_SET); + parse_exif (base); + break; + case 34853: /* GPSInfo tag */ + fseek (ifp, get4()+base, SEEK_SET); + parse_gps (base); + break; + case 34675: /* InterColorProfile */ + case 50831: /* AsShotICCProfile */ + profile_offset = ftell(ifp); + profile_length = len; + break; + case 37122: /* CompressedBitsPerPixel */ + kodak_cbpp = get4(); + break; + case 37386: /* FocalLength */ + focal_len = getreal(type); + break; + case 37393: /* ImageNumber */ + shot_order = getint(type); + break; + case 37400: /* old Kodak KDC tag */ + for (raw_color = i=0; i < 3; i++) { + getreal(type); + FORC3 rgb_cam[i][c] = getreal(type); + } + break; + case 40976: + strip_offset = get4(); + switch (tiff_ifd[ifd].comp) { + case 32770: load_raw = &CLASS samsung_load_raw; break; + case 32772: load_raw = &CLASS samsung2_load_raw; break; + case 32773: load_raw = &CLASS samsung3_load_raw; break; + } + break; + case 46275: /* Imacon tags */ + strcpy (make, "Imacon"); + data_offset = ftell(ifp); + ima_len = len; + break; + case 46279: + if (!ima_len) break; + fseek (ifp, 38, SEEK_CUR); + case 46274: + fseek (ifp, 40, SEEK_CUR); + raw_width = get4(); + raw_height = get4(); + left_margin = get4() & 7; + width = raw_width - left_margin - (get4() & 7); + top_margin = get4() & 7; + height = raw_height - top_margin - (get4() & 7); + if (raw_width == 7262) { + height = 5444; + width = 7244; + left_margin = 7; + } + fseek (ifp, 52, SEEK_CUR); + FORC3 cam_mul[c] = getreal(11); + fseek (ifp, 114, SEEK_CUR); + flip = (get2() >> 7) * 90; + if (width * height * 6 == ima_len) { + if (flip % 180 == 90) SWAP(width,height); + raw_width = width; + raw_height = height; + left_margin = top_margin = filters = flip = 0; + } + sprintf (model, "Ixpress %d-Mp", height*width/1000000); + load_raw = &CLASS imacon_full_load_raw; + if (filters) { + if (left_margin & 1) filters = 0x61616161; + load_raw = &CLASS unpacked_load_raw; + } + maximum = 0xffff; + break; + case 50454: /* Sinar tag */ + case 50455: + if (!(cbuf = (char *) malloc(len))) break; + fread (cbuf, 1, len, ifp); + for (cp = cbuf-1; cp && cp < cbuf+len; cp = strchr(cp,'\n')) + if (!strncmp (++cp,"Neutral ",8)) + sscanf (cp+8, "%f %f %f", cam_mul, cam_mul+1, cam_mul+2); + free (cbuf); + break; + case 50458: + if (!make[0]) strcpy (make, "Hasselblad"); + break; + case 50459: /* Hasselblad tag */ + i = order; + j = ftell(ifp); + c = tiff_nifds; + order = get2(); + fseek (ifp, j+(get2(),get4()), SEEK_SET); + parse_tiff_ifd (j); + maximum = 0xffff; + tiff_nifds = c; + order = i; + break; + case 50706: /* DNGVersion */ + FORC4 dng_version = (dng_version << 8) + fgetc(ifp); + if (!make[0]) strcpy (make, "DNG"); + is_raw = 1; + break; + case 50710: /* CFAPlaneColor */ + if (filters == 9) break; + if (len > 4) len = 4; + colors = len; + fread (cfa_pc, 1, colors, ifp); +guess_cfa_pc: + FORCC tab[cfa_pc[c]] = c; + cdesc[c] = 0; + for (i=16; i--; ) + filters = filters << 2 | tab[cfa_pat[i % plen]]; + filters -= !filters; + break; + case 50711: /* CFALayout */ + if (get2() == 2) { + fuji_width = 1; + filters = 0x49494949; + } + break; + case 291: + case 50712: /* LinearizationTable */ + linear_table (len); + break; + case 50713: /* BlackLevelRepeatDim */ + cblack[4] = get2(); + cblack[5] = get2(); + if (cblack[4] * cblack[5] > sizeof cblack / sizeof *cblack - 6) + cblack[4] = cblack[5] = 1; + break; + case 61450: + cblack[4] = cblack[5] = MIN(sqrt(len),64); + case 50714: /* BlackLevel */ + if (!(cblack[4] * cblack[5])) + cblack[4] = cblack[5] = 1; + FORC (cblack[4] * cblack[5]) + cblack[6+c] = getreal(type); + black = 0; + break; + case 50715: /* BlackLevelDeltaH */ + case 50716: /* BlackLevelDeltaV */ + for (num=i=0; i < len; i++) + num += getreal(type); + black += num/len + 0.5; + break; + case 50717: /* WhiteLevel */ + maximum = getint(type); + break; + case 50718: /* DefaultScale */ + pixel_aspect = getreal(type); + pixel_aspect /= getreal(type); + break; + case 50721: /* ColorMatrix1 */ + case 50722: /* ColorMatrix2 */ + FORCC for (j=0; j < 3; j++) + cm[c][j] = getreal(type); + use_cm = 1; + break; + case 50723: /* CameraCalibration1 */ + case 50724: /* CameraCalibration2 */ + for (i=0; i < colors; i++) + FORCC cc[i][c] = getreal(type); + break; + case 50727: /* AnalogBalance */ + FORCC ab[c] = getreal(type); + break; + case 50728: /* AsShotNeutral */ + FORCC asn[c] = getreal(type); + break; + case 50729: /* AsShotWhiteXY */ + xyz[0] = getreal(type); + xyz[1] = getreal(type); + xyz[2] = 1 - xyz[0] - xyz[1]; + FORC3 xyz[c] /= d65_white[c]; + break; + case 50740: /* DNGPrivateData */ + if (dng_version) break; + parse_minolta (j = get4()+base); + fseek (ifp, j, SEEK_SET); + parse_tiff_ifd (base); + break; + case 50752: + read_shorts (cr2_slice, 3); + break; + case 50829: /* ActiveArea */ + top_margin = getint(type); + left_margin = getint(type); + height = getint(type) - top_margin; + width = getint(type) - left_margin; + break; + case 50830: /* MaskedAreas */ + for (i=0; i < len && i < 32; i++) + ((int *)mask)[i] = getint(type); + black = 0; + break; + case 51009: /* OpcodeList2 */ + meta_offset = ftell(ifp); + break; + case 64772: /* Kodak P-series */ + if (len < 13) break; + fseek (ifp, 16, SEEK_CUR); + data_offset = get4(); + fseek (ifp, 28, SEEK_CUR); + data_offset += get4(); + load_raw = &CLASS packed_load_raw; + break; + case 65026: + if (type == 2) fgets (model2, 64, ifp); + } + fseek (ifp, save, SEEK_SET); + } + if (sony_length && (buf = (unsigned *) malloc(sony_length))) { + fseek (ifp, sony_offset, SEEK_SET); + fread (buf, sony_length, 1, ifp); + sony_decrypt (buf, sony_length/4, 1, sony_key); + sfp = ifp; + if ((ifp = tmpfile())) { + fwrite (buf, sony_length, 1, ifp); + fseek (ifp, 0, SEEK_SET); + parse_tiff_ifd (-sony_offset); + fclose (ifp); + } + ifp = sfp; + free (buf); + } + for (i=0; i < colors; i++) + FORCC cc[i][c] *= ab[i]; + if (use_cm) { + FORCC for (i=0; i < 3; i++) + for (cam_xyz[c][i]=j=0; j < colors; j++) + cam_xyz[c][i] += cc[c][j] * cm[j][i] * xyz[i]; + cam_xyz_coeff (cmatrix, cam_xyz); + } + if (asn[0]) { + cam_mul[3] = 0; + FORCC cam_mul[c] = 1 / asn[c]; + } + if (!use_cm) + FORCC pre_mul[c] /= cc[c][c]; + return 0; +} + +int CLASS parse_tiff (int base) +{ + int doff; + + fseek (ifp, base, SEEK_SET); + order = get2(); + if (order != 0x4949 && order != 0x4d4d) return 0; + get2(); + while ((doff = get4())) { + fseek (ifp, doff+base, SEEK_SET); + if (parse_tiff_ifd (base)) break; + } + return 1; +} + +void CLASS apply_tiff() +{ + int max_samp=0, raw=-1, thm=-1, i; + struct jhead jh; + + thumb_misc = 16; + if (thumb_offset) { + fseek (ifp, thumb_offset, SEEK_SET); + if (ljpeg_start (&jh, 1)) { + thumb_misc = jh.bits; + thumb_width = jh.wide; + thumb_height = jh.high; + } + } + for (i=0; i < tiff_nifds; i++) { + if (max_samp < tiff_ifd[i].samples) + max_samp = tiff_ifd[i].samples; + if (max_samp > 3) max_samp = 3; + if ((tiff_ifd[i].comp != 6 || tiff_ifd[i].samples != 3) && + (tiff_ifd[i].width | tiff_ifd[i].height) < 0x10000 && + tiff_ifd[i].width*tiff_ifd[i].height > raw_width*raw_height) { + raw_width = tiff_ifd[i].width; + raw_height = tiff_ifd[i].height; + tiff_bps = tiff_ifd[i].bps; + tiff_compress = tiff_ifd[i].comp; + data_offset = tiff_ifd[i].offset; + tiff_flip = tiff_ifd[i].flip; + tiff_samples = tiff_ifd[i].samples; + tile_width = tiff_ifd[i].tile_width; + tile_length = tiff_ifd[i].tile_length; + raw = i; + } + } + if (!tile_width ) tile_width = INT_MAX; + if (!tile_length) tile_length = INT_MAX; + for (i=tiff_nifds; i--; ) + if (tiff_ifd[i].flip) tiff_flip = tiff_ifd[i].flip; + if (raw >= 0 && !load_raw) + switch (tiff_compress) { + case 32767: + if (tiff_ifd[raw].bytes == raw_width*raw_height) { + tiff_bps = 12; + load_raw = &CLASS sony_arw2_load_raw; break; + } + if (tiff_ifd[raw].bytes*8 != raw_width*raw_height*tiff_bps) { + raw_height += 8; + load_raw = &CLASS sony_arw_load_raw; break; + } + load_flags = 79; + case 32769: + load_flags++; + case 32770: + case 32773: goto slr; + case 0: case 1: + if (!strncmp(make,"OLYMPUS",7) && + tiff_ifd[raw].bytes*2 == raw_width*raw_height*3) + load_flags = 24; + if (tiff_ifd[raw].bytes*5 == raw_width*raw_height*8) { + load_flags = 81; + tiff_bps = 12; + } slr: + switch (tiff_bps) { + case 8: load_raw = &CLASS eight_bit_load_raw; break; + case 12: if (tiff_ifd[raw].phint == 2) + load_flags = 6; + load_raw = &CLASS packed_load_raw; break; + case 14: load_flags = 0; + case 16: load_raw = &CLASS unpacked_load_raw; + if (!strncmp(make,"OLYMPUS",7) && + tiff_ifd[raw].bytes*7 > raw_width*raw_height) + load_raw = &CLASS olympus_load_raw; + } + break; + case 6: case 7: case 99: + load_raw = &CLASS lossless_jpeg_load_raw; break; + case 262: + load_raw = &CLASS kodak_262_load_raw; break; + case 34713: + if ((raw_width+9)/10*16*raw_height == tiff_ifd[raw].bytes) { + load_raw = &CLASS packed_load_raw; + load_flags = 1; + } else if (raw_width*raw_height*3 == tiff_ifd[raw].bytes*2) { + load_raw = &CLASS packed_load_raw; + if (model[0] == 'N') load_flags = 80; + } else if (raw_width*raw_height*3 == tiff_ifd[raw].bytes) { + load_raw = &CLASS nikon_yuv_load_raw; + gamma_curve (1/2.4, 12.92, 1, 4095); + memset (cblack, 0, sizeof cblack); + filters = 0; + } else if (raw_width*raw_height*2 == tiff_ifd[raw].bytes) { + load_raw = &CLASS unpacked_load_raw; + load_flags = 4; + order = 0x4d4d; + } else + load_raw = &CLASS nikon_load_raw; break; + case 65535: + load_raw = &CLASS pentax_load_raw; break; + case 65000: + switch (tiff_ifd[raw].phint) { + case 2: load_raw = &CLASS kodak_rgb_load_raw; filters = 0; break; + case 6: load_raw = &CLASS kodak_ycbcr_load_raw; filters = 0; break; + case 32803: load_raw = &CLASS kodak_65000_load_raw; + } + case 32867: case 34892: break; + default: is_raw = 0; + } + if (!dng_version) + if ( (tiff_samples == 3 && tiff_ifd[raw].bytes && tiff_bps != 14 && + (tiff_compress & -16) != 32768) + || (tiff_bps == 8 && !strcasestr(make,"Kodak") && + !strstr(model2,"DEBUG RAW"))) + is_raw = 0; + for (i=0; i < tiff_nifds; i++) + if (i != raw && tiff_ifd[i].samples == max_samp && + tiff_ifd[i].width * tiff_ifd[i].height / (SQR(tiff_ifd[i].bps)+1) > + thumb_width * thumb_height / (SQR(thumb_misc)+1) + && tiff_ifd[i].comp != 34892) { + thumb_width = tiff_ifd[i].width; + thumb_height = tiff_ifd[i].height; + thumb_offset = tiff_ifd[i].offset; + thumb_length = tiff_ifd[i].bytes; + thumb_misc = tiff_ifd[i].bps; + thm = i; + } + if (thm >= 0) { + thumb_misc |= tiff_ifd[thm].samples << 5; + switch (tiff_ifd[thm].comp) { + case 0: + write_thumb = &CLASS layer_thumb; + break; + case 1: + if (tiff_ifd[thm].bps <= 8) + write_thumb = &CLASS ppm_thumb; + else if (!strcmp(make,"Imacon")) + write_thumb = &CLASS ppm16_thumb; + else + thumb_load_raw = &CLASS kodak_thumb_load_raw; + break; + case 65000: + thumb_load_raw = tiff_ifd[thm].phint == 6 ? + &CLASS kodak_ycbcr_load_raw : &CLASS kodak_rgb_load_raw; + } + } +} + +void CLASS parse_minolta (int base) +{ + int save, tag, len, offset, high=0, wide=0, i, c; + short sorder=order; + + fseek (ifp, base, SEEK_SET); + if (fgetc(ifp) || fgetc(ifp)-'M' || fgetc(ifp)-'R') return; + order = fgetc(ifp) * 0x101; + offset = base + get4() + 8; + while ((save=ftell(ifp)) < offset) { + for (tag=i=0; i < 4; i++) + tag = tag << 8 | fgetc(ifp); + len = get4(); + switch (tag) { + case 0x505244: /* PRD */ + fseek (ifp, 8, SEEK_CUR); + high = get2(); + wide = get2(); + break; + case 0x574247: /* WBG */ + get4(); + i = strcmp(model,"DiMAGE A200") ? 0:3; + FORC4 cam_mul[c ^ (c >> 1) ^ i] = get2(); + break; + case 0x545457: /* TTW */ + parse_tiff (ftell(ifp)); + data_offset = offset; + } + fseek (ifp, save+len+8, SEEK_SET); + } + raw_height = high; + raw_width = wide; + order = sorder; +} + +/* + Many cameras have a "debug mode" that writes JPEG and raw + at the same time. The raw file has no header, so try to + to open the matching JPEG file and read its metadata. + */ +void CLASS parse_external_jpeg() +{ + const char *file, *ext; + char *jname, *jfile, *jext; + FILE *save=ifp; + + ext = strrchr (ifname, '.'); + file = strrchr (ifname, '/'); + if (!file) file = strrchr (ifname, '\\'); + if (!file) file = ifname-1; + file++; + if (!ext || strlen(ext) != 4 || ext-file != 8) return; + jname = (char *) malloc (strlen(ifname) + 1); + merror (jname, "parse_external_jpeg()"); + strcpy (jname, ifname); + jfile = file - ifname + jname; + jext = ext - ifname + jname; + if (strcasecmp (ext, ".jpg")) { + strcpy (jext, isupper(ext[1]) ? ".JPG":".jpg"); + if (isdigit(*file)) { + memcpy (jfile, file+4, 4); + memcpy (jfile+4, file, 4); + } + } else + while (isdigit(*--jext)) { + if (*jext != '9') { + (*jext)++; + break; + } + *jext = '0'; + } + if (strcmp (jname, ifname)) { + if ((ifp = fopen (jname, "rb"))) { + if (verbose) + fprintf (stderr,_("Reading metadata from %s ...\n"), jname); + parse_tiff (12); + thumb_offset = 0; + is_raw = 1; + fclose (ifp); + } + } + if (!timestamp) + fprintf (stderr,_("Failed to read metadata from %s\n"), jname); + free (jname); + ifp = save; +} + +/* + CIFF block 0x1030 contains an 8x8 white sample. + Load this into white[][] for use in scale_colors(). + */ +void CLASS ciff_block_1030() +{ + static const ushort key[] = { 0x410, 0x45f3 }; + int i, bpp, row, col, vbits=0; + unsigned long bitbuf=0; + + if ((get2(),get4()) != 0x80008 || !get4()) return; + bpp = get2(); + if (bpp != 10 && bpp != 12) return; + for (i=row=0; row < 8; row++) + for (col=0; col < 8; col++) { + if (vbits < bpp) { + bitbuf = bitbuf << 16 | (get2() ^ key[i++ & 1]); + vbits += 16; + } + white[row][col] = + bitbuf << (LONG_BIT - vbits) >> (LONG_BIT - bpp); + vbits -= bpp; + } +} + +/* + Parse a CIFF file, better known as Canon CRW format. + */ +void CLASS parse_ciff (int offset, int length, int depth) +{ + int tboff, nrecs, c, type, len, save, wbi=-1; + ushort key[] = { 0x410, 0x45f3 }; + + fseek (ifp, offset+length-4, SEEK_SET); + tboff = get4() + offset; + fseek (ifp, tboff, SEEK_SET); + nrecs = get2(); + if ((nrecs | depth) > 127) return; + while (nrecs--) { + type = get2(); + len = get4(); + save = ftell(ifp) + 4; + fseek (ifp, offset+get4(), SEEK_SET); + if ((((type >> 8) + 8) | 8) == 0x38) + parse_ciff (ftell(ifp), len, depth+1); /* Parse a sub-table */ + if (type == 0x0810) + fread (artist, 64, 1, ifp); + if (type == 0x080a) { + fread (make, 64, 1, ifp); + fseek (ifp, strlen(make) - 63, SEEK_CUR); + fread (model, 64, 1, ifp); + } + if (type == 0x1810) { + width = get4(); + height = get4(); + pixel_aspect = int_to_float(get4()); + flip = get4(); + } + if (type == 0x1835) /* Get the decoder table */ + tiff_compress = get4(); + if (type == 0x2007) { + thumb_offset = ftell(ifp); + thumb_length = len; + } + if (type == 0x1818) { + shutter = pow (2, -int_to_float((get4(),get4()))); + aperture = pow (2, int_to_float(get4())/2); + } + if (type == 0x102a) { + iso_speed = pow (2, (get4(),get2())/32.0 - 4) * 50; + aperture = pow (2, (get2(),(short)get2())/64.0); + shutter = pow (2,-((short)get2())/32.0); + wbi = (get2(),get2()); + if (wbi > 17) wbi = 0; + fseek (ifp, 32, SEEK_CUR); + if (shutter > 1e6) shutter = get2()/10.0; + } + if (type == 0x102c) { + if (get2() > 512) { /* Pro90, G1 */ + fseek (ifp, 118, SEEK_CUR); + FORC4 cam_mul[c ^ 2] = get2(); + } else { /* G2, S30, S40 */ + fseek (ifp, 98, SEEK_CUR); + FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2(); + } + } + if (type == 0x0032) { + if (len == 768) { /* EOS D30 */ + fseek (ifp, 72, SEEK_CUR); + FORC4 cam_mul[c ^ (c >> 1)] = 1024.0 / get2(); + if (!wbi) cam_mul[0] = -1; /* use my auto white balance */ + } else if (!cam_mul[0]) { + if (get2() == key[0]) /* Pro1, G6, S60, S70 */ + c = (strstr(model,"Pro1") ? + "012346000000000000":"01345:000000006008")[wbi]-'0'+ 2; + else { /* G3, G5, S45, S50 */ + c = "023457000000006000"[wbi]-'0'; + key[0] = key[1] = 0; + } + fseek (ifp, 78 + c*8, SEEK_CUR); + FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2() ^ key[c & 1]; + if (!wbi) cam_mul[0] = -1; + } + } + if (type == 0x10a9) { /* D60, 10D, 300D, and clones */ + if (len > 66) wbi = "0134567028"[wbi]-'0'; + fseek (ifp, 2 + wbi*8, SEEK_CUR); + FORC4 cam_mul[c ^ (c >> 1)] = get2(); + } + if (type == 0x1030 && (0x18040 >> wbi & 1)) + ciff_block_1030(); /* all that don't have 0x10a9 */ + if (type == 0x1031) { + raw_width = (get2(),get2()); + raw_height = get2(); + } + if (type == 0x5029) { + focal_len = len >> 16; + if ((len & 0xffff) == 2) focal_len /= 32; + } + if (type == 0x5813) flash_used = int_to_float(len); + if (type == 0x5814) canon_ev = int_to_float(len); + if (type == 0x5817) shot_order = len; + if (type == 0x5834) unique_id = len; + if (type == 0x580e) timestamp = len; + if (type == 0x180e) timestamp = get4(); +#ifdef LOCALTIME + if ((type | 0x4000) == 0x580e) + timestamp = mktime (gmtime (×tamp)); +#endif + fseek (ifp, save, SEEK_SET); + } +} + +void CLASS parse_rollei() +{ + char line[128], *val; + struct tm t; + + fseek (ifp, 0, SEEK_SET); + memset (&t, 0, sizeof t); + do { + fgets (line, 128, ifp); + if ((val = strchr(line,'='))) + *val++ = 0; + else + val = line + strlen(line); + if (!strcmp(line,"DAT")) + sscanf (val, "%d.%d.%d", &t.tm_mday, &t.tm_mon, &t.tm_year); + if (!strcmp(line,"TIM")) + sscanf (val, "%d:%d:%d", &t.tm_hour, &t.tm_min, &t.tm_sec); + if (!strcmp(line,"HDR")) + thumb_offset = atoi(val); + if (!strcmp(line,"X ")) + raw_width = atoi(val); + if (!strcmp(line,"Y ")) + raw_height = atoi(val); + if (!strcmp(line,"TX ")) + thumb_width = atoi(val); + if (!strcmp(line,"TY ")) + thumb_height = atoi(val); + } while (strncmp(line,"EOHD",4)); + data_offset = thumb_offset + thumb_width * thumb_height * 2; + t.tm_year -= 1900; + t.tm_mon -= 1; + if (mktime(&t) > 0) + timestamp = mktime(&t); + strcpy (make, "Rollei"); + strcpy (model,"d530flex"); + write_thumb = &CLASS rollei_thumb; +} + +void CLASS parse_sinar_ia() +{ + int entries, off; + char str[8], *cp; + + order = 0x4949; + fseek (ifp, 4, SEEK_SET); + entries = get4(); + fseek (ifp, get4(), SEEK_SET); + while (entries--) { + off = get4(); get4(); + fread (str, 8, 1, ifp); + if (!strcmp(str,"META")) meta_offset = off; + if (!strcmp(str,"THUMB")) thumb_offset = off; + if (!strcmp(str,"RAW0")) data_offset = off; + } + fseek (ifp, meta_offset+20, SEEK_SET); + fread (make, 64, 1, ifp); + make[63] = 0; + if ((cp = strchr(make,' '))) { + strcpy (model, cp+1); + *cp = 0; + } + raw_width = get2(); + raw_height = get2(); + load_raw = &CLASS unpacked_load_raw; + thumb_width = (get4(),get2()); + thumb_height = get2(); + write_thumb = &CLASS ppm_thumb; + maximum = 0x3fff; +} + +void CLASS parse_phase_one (int base) +{ + unsigned entries, tag, type, len, data, save, i, c; + float romm_cam[3][3]; + char *cp; + + memset (&ph1, 0, sizeof ph1); + fseek (ifp, base, SEEK_SET); + order = get4() & 0xffff; + if (get4() >> 8 != 0x526177) return; /* "Raw" */ + fseek (ifp, get4()+base, SEEK_SET); + entries = get4(); + get4(); + while (entries--) { + tag = get4(); + type = get4(); + len = get4(); + data = get4(); + save = ftell(ifp); + fseek (ifp, base+data, SEEK_SET); + switch (tag) { + case 0x100: flip = "0653"[data & 3]-'0'; break; + case 0x106: + for (i=0; i < 9; i++) + ((float *)romm_cam)[i] = getreal(11); + romm_coeff (romm_cam); + break; + case 0x107: + FORC3 cam_mul[c] = getreal(11); + break; + case 0x108: raw_width = data; break; + case 0x109: raw_height = data; break; + case 0x10a: left_margin = data; break; + case 0x10b: top_margin = data; break; + case 0x10c: width = data; break; + case 0x10d: height = data; break; + case 0x10e: ph1.format = data; break; + case 0x10f: data_offset = data+base; break; + case 0x110: meta_offset = data+base; + meta_length = len; break; + case 0x112: ph1.key_off = save - 4; break; + case 0x210: ph1.tag_210 = int_to_float(data); break; + case 0x21a: ph1.tag_21a = data; break; + case 0x21c: strip_offset = data+base; break; + case 0x21d: ph1.black = data; break; + case 0x222: ph1.split_col = data; break; + case 0x223: ph1.black_col = data+base; break; + case 0x224: ph1.split_row = data; break; + case 0x225: ph1.black_row = data+base; break; + case 0x301: + model[63] = 0; + fread (model, 1, 63, ifp); + if ((cp = strstr(model," camera"))) *cp = 0; + } + fseek (ifp, save, SEEK_SET); + } + load_raw = ph1.format < 3 ? + &CLASS phase_one_load_raw : &CLASS phase_one_load_raw_c; + maximum = 0xffff; + strcpy (make, "Phase One"); + if (model[0]) return; + switch (raw_height) { + case 2060: strcpy (model,"LightPhase"); break; + case 2682: strcpy (model,"H 10"); break; + case 4128: strcpy (model,"H 20"); break; + case 5488: strcpy (model,"H 25"); break; + } +} + +void CLASS parse_fuji (int offset) +{ + unsigned entries, tag, len, save, c; + + fseek (ifp, offset, SEEK_SET); + entries = get4(); + if (entries > 255) return; + while (entries--) { + tag = get2(); + len = get2(); + save = ftell(ifp); + if (tag == 0x100) { + raw_height = get2(); + raw_width = get2(); + } else if (tag == 0x121) { + height = get2(); + if ((width = get2()) == 4284) width += 3; + } else if (tag == 0x130) { + fuji_layout = fgetc(ifp) >> 7; + fuji_width = !(fgetc(ifp) & 8); + } else if (tag == 0x131) { + filters = 9; + FORC(36) xtrans_abs[0][35-c] = fgetc(ifp) & 3; + } else if (tag == 0x2ff0) { + FORC4 cam_mul[c ^ 1] = get2(); + } else if (tag == 0xc000) { + c = order; + order = 0x4949; + if ((tag = get4()) > 10000) tag = get4(); + width = tag; + height = get4(); + order = c; + } + fseek (ifp, save+len, SEEK_SET); + } + height <<= fuji_layout; + width >>= fuji_layout; +} + +int CLASS parse_jpeg (int offset) +{ + int len, save, hlen, mark; + + fseek (ifp, offset, SEEK_SET); + if (fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) return 0; + + while (fgetc(ifp) == 0xff && (mark = fgetc(ifp)) != 0xda) { + order = 0x4d4d; + len = get2() - 2; + save = ftell(ifp); + if (mark == 0xc0 || mark == 0xc3) { + fgetc(ifp); + raw_height = get2(); + raw_width = get2(); + } + order = get2(); + hlen = get4(); + if (get4() == 0x48454150) /* "HEAP" */ + parse_ciff (save+hlen, len-hlen, 0); + if (parse_tiff (save+6)) apply_tiff(); + fseek (ifp, save+len, SEEK_SET); + } + return 1; +} + +void CLASS parse_riff() +{ + unsigned i, size, end; + char tag[4], date[64], month[64]; + static const char mon[12][4] = + { "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" }; + struct tm t; + + order = 0x4949; + fread (tag, 4, 1, ifp); + size = get4(); + end = ftell(ifp) + size; + if (!memcmp(tag,"RIFF",4) || !memcmp(tag,"LIST",4)) { + get4(); + while (ftell(ifp)+7 < end && !feof(ifp)) + parse_riff(); + } else if (!memcmp(tag,"nctg",4)) { + while (ftell(ifp)+7 < end) { + i = get2(); + size = get2(); + if ((i+1) >> 1 == 10 && size == 20) + get_timestamp(0); + else fseek (ifp, size, SEEK_CUR); + } + } else if (!memcmp(tag,"IDIT",4) && size < 64) { + fread (date, 64, 1, ifp); + date[size] = 0; + memset (&t, 0, sizeof t); + if (sscanf (date, "%*s %s %d %d:%d:%d %d", month, &t.tm_mday, + &t.tm_hour, &t.tm_min, &t.tm_sec, &t.tm_year) == 6) { + for (i=0; i < 12 && strcasecmp(mon[i],month); i++); + t.tm_mon = i; + t.tm_year -= 1900; + if (mktime(&t) > 0) + timestamp = mktime(&t); + } + } else + fseek (ifp, size, SEEK_CUR); +} + +void CLASS parse_qt (int end) +{ + unsigned save, size; + char tag[4]; + + order = 0x4d4d; + while (ftell(ifp)+7 < end) { + save = ftell(ifp); + if ((size = get4()) < 8) return; + fread (tag, 4, 1, ifp); + if (!memcmp(tag,"moov",4) || + !memcmp(tag,"udta",4) || + !memcmp(tag,"CNTH",4)) + parse_qt (save+size); + if (!memcmp(tag,"CNDA",4)) + parse_jpeg (ftell(ifp)); + fseek (ifp, save+size, SEEK_SET); + } +} + +void CLASS parse_smal (int offset, int fsize) +{ + int ver; + + fseek (ifp, offset+2, SEEK_SET); + order = 0x4949; + ver = fgetc(ifp); + if (ver == 6) + fseek (ifp, 5, SEEK_CUR); + if (get4() != fsize) return; + if (ver > 6) data_offset = get4(); + raw_height = height = get2(); + raw_width = width = get2(); + strcpy (make, "SMaL"); + sprintf (model, "v%d %dx%d", ver, width, height); + if (ver == 6) load_raw = &CLASS smal_v6_load_raw; + if (ver == 9) load_raw = &CLASS smal_v9_load_raw; +} + +void CLASS parse_cine() +{ + unsigned off_head, off_setup, off_image, i; + + order = 0x4949; + fseek (ifp, 4, SEEK_SET); + is_raw = get2() == 2; + fseek (ifp, 14, SEEK_CUR); + is_raw *= get4(); + off_head = get4(); + off_setup = get4(); + off_image = get4(); + timestamp = get4(); + if ((i = get4())) timestamp = i; + fseek (ifp, off_head+4, SEEK_SET); + raw_width = get4(); + raw_height = get4(); + switch (get2(),get2()) { + case 8: load_raw = &CLASS eight_bit_load_raw; break; + case 16: load_raw = &CLASS unpacked_load_raw; + } + fseek (ifp, off_setup+792, SEEK_SET); + strcpy (make, "CINE"); + sprintf (model, "%d", get4()); + fseek (ifp, 12, SEEK_CUR); + switch ((i=get4()) & 0xffffff) { + case 3: filters = 0x94949494; break; + case 4: filters = 0x49494949; break; + default: is_raw = 0; + } + fseek (ifp, 72, SEEK_CUR); + switch ((get4()+3600) % 360) { + case 270: flip = 4; break; + case 180: flip = 1; break; + case 90: flip = 7; break; + case 0: flip = 2; + } + cam_mul[0] = getreal(11); + cam_mul[2] = getreal(11); + maximum = ~(-1 << get4()); + fseek (ifp, 668, SEEK_CUR); + shutter = get4()/1000000000.0; + fseek (ifp, off_image, SEEK_SET); + if (shot_select < is_raw) + fseek (ifp, shot_select*8, SEEK_CUR); + data_offset = (INT64) get4() + 8; + data_offset += (INT64) get4() << 32; +} + +void CLASS parse_redcine() +{ + unsigned i, len, rdvo; + + order = 0x4d4d; + is_raw = 0; + fseek (ifp, 52, SEEK_SET); + width = get4(); + height = get4(); + fseek (ifp, 0, SEEK_END); + fseek (ifp, -(i = ftello(ifp) & 511), SEEK_CUR); + if (get4() != i || get4() != 0x52454f42) { + fprintf (stderr,_("%s: Tail is missing, parsing from head...\n"), ifname); + fseek (ifp, 0, SEEK_SET); + while ((len = get4()) != EOF) { + if (get4() == 0x52454456) + if (is_raw++ == shot_select) + data_offset = ftello(ifp) - 8; + fseek (ifp, len-8, SEEK_CUR); + } + } else { + rdvo = get4(); + fseek (ifp, 12, SEEK_CUR); + is_raw = get4(); + fseeko (ifp, rdvo+8 + shot_select*4, SEEK_SET); + data_offset = get4(); + } +} + +char * CLASS foveon_gets (int offset, char *str, int len) +{ + int i; + fseek (ifp, offset, SEEK_SET); + for (i=0; i < len-1; i++) + if ((str[i] = get2()) == 0) break; + str[i] = 0; + return str; +} + +void CLASS parse_foveon() +{ + int entries, img=0, off, len, tag, save, i, wide, high, pent, poff[256][2]; + char name[64], value[64]; + + order = 0x4949; /* Little-endian */ + fseek (ifp, 36, SEEK_SET); + flip = get4(); + fseek (ifp, -4, SEEK_END); + fseek (ifp, get4(), SEEK_SET); + if (get4() != 0x64434553) return; /* SECd */ + entries = (get4(),get4()); + while (entries--) { + off = get4(); + len = get4(); + tag = get4(); + save = ftell(ifp); + fseek (ifp, off, SEEK_SET); + if (get4() != (0x20434553 | (tag << 24))) return; + switch (tag) { + case 0x47414d49: /* IMAG */ + case 0x32414d49: /* IMA2 */ + fseek (ifp, 8, SEEK_CUR); + pent = get4(); + wide = get4(); + high = get4(); + if (wide > raw_width && high > raw_height) { + switch (pent) { + case 5: load_flags = 1; + case 6: load_raw = &CLASS foveon_sd_load_raw; break; + case 30: load_raw = &CLASS foveon_dp_load_raw; break; + default: load_raw = 0; + } + raw_width = wide; + raw_height = high; + data_offset = off+28; + is_foveon = 1; + } + fseek (ifp, off+28, SEEK_SET); + if (fgetc(ifp) == 0xff && fgetc(ifp) == 0xd8 + && thumb_length < len-28) { + thumb_offset = off+28; + thumb_length = len-28; + write_thumb = &CLASS jpeg_thumb; + } + if (++img == 2 && !thumb_length) { + thumb_offset = off+24; + thumb_width = wide; + thumb_height = high; + write_thumb = &CLASS foveon_thumb; + } + break; + case 0x464d4143: /* CAMF */ + meta_offset = off+8; + meta_length = len-28; + break; + case 0x504f5250: /* PROP */ + pent = (get4(),get4()); + fseek (ifp, 12, SEEK_CUR); + off += pent*8 + 24; + if ((unsigned) pent > 256) pent=256; + for (i=0; i < pent*2; i++) + ((int *)poff)[i] = off + get4()*2; + for (i=0; i < pent; i++) { + foveon_gets (poff[i][0], name, 64); + foveon_gets (poff[i][1], value, 64); + if (!strcmp (name, "ISO")) + iso_speed = atoi(value); + if (!strcmp (name, "CAMMANUF")) + strcpy (make, value); + if (!strcmp (name, "CAMMODEL")) + strcpy (model, value); + if (!strcmp (name, "WB_DESC")) + strcpy (model2, value); + if (!strcmp (name, "TIME")) + timestamp = atoi(value); + if (!strcmp (name, "EXPTIME")) + shutter = atoi(value) / 1000000.0; + if (!strcmp (name, "APERTURE")) + aperture = atof(value); + if (!strcmp (name, "FLENGTH")) + focal_len = atof(value); + } +#ifdef LOCALTIME + timestamp = mktime (gmtime (×tamp)); +#endif + } + fseek (ifp, save, SEEK_SET); + } +} + +/* + All matrices are from Adobe DNG Converter unless otherwise noted. + */ +void CLASS adobe_coeff (const char *make, const char *model) +{ + static const struct { + const char *prefix; + short black, maximum, trans[12]; + } table[] = { + { "AgfaPhoto DC-833m", 0, 0, /* DJC */ + { 11438,-3762,-1115,-2409,9914,2497,-1227,2295,5300 } }, + { "Apple QuickTake", 0, 0, /* DJC */ + { 21392,-5653,-3353,2406,8010,-415,7166,1427,2078 } }, + { "Canon EOS D2000", 0, 0, + { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } }, + { "Canon EOS D6000", 0, 0, + { 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } }, + { "Canon EOS D30", 0, 0, + { 9805,-2689,-1312,-5803,13064,3068,-2438,3075,8775 } }, + { "Canon EOS D60", 0, 0xfa0, + { 6188,-1341,-890,-7168,14489,2937,-2640,3228,8483 } }, + { "Canon EOS 5DS", 0, 0x3c96, /* DJC */ + { 6885,-753,-856,-4416,11752,2665,-1266,2393,5468 } }, + { "Canon EOS 5D Mark III", 0, 0x3c80, + { 6722,-635,-963,-4287,12460,2028,-908,2162,5668 } }, + { "Canon EOS 5D Mark II", 0, 0x3cf0, + { 4716,603,-830,-7798,15474,2480,-1496,1937,6651 } }, + { "Canon EOS 5D", 0, 0xe6c, + { 6347,-479,-972,-8297,15954,2480,-1968,2131,7649 } }, + { "Canon EOS 6D", 0, 0x3c82, + { 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } }, + { "Canon EOS 7D Mark II", 0, 0x3510, + { 7268,-1082,-969,-4186,11839,2663,-825,2029,5839 } }, + { "Canon EOS 7D", 0, 0x3510, + { 6844,-996,-856,-3876,11761,2396,-593,1772,6198 } }, + { "Canon EOS 10D", 0, 0xfa0, + { 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } }, + { "Canon EOS 20Da", 0, 0, + { 14155,-5065,-1382,-6550,14633,2039,-1623,1824,6561 } }, + { "Canon EOS 20D", 0, 0xfff, + { 6599,-537,-891,-8071,15783,2424,-1983,2234,7462 } }, + { "Canon EOS 30D", 0, 0, + { 6257,-303,-1000,-7880,15621,2396,-1714,1904,7046 } }, + { "Canon EOS 40D", 0, 0x3f60, + { 6071,-747,-856,-7653,15365,2441,-2025,2553,7315 } }, + { "Canon EOS 50D", 0, 0x3d93, + { 4920,616,-593,-6493,13964,2784,-1774,3178,7005 } }, + { "Canon EOS 60D", 0, 0x2ff7, + { 6719,-994,-925,-4408,12426,2211,-887,2129,6051 } }, + { "Canon EOS 70D", 0, 0x3bc7, + { 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } }, + { "Canon EOS 100D", 0, 0x350f, + { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } }, + { "Canon EOS 300D", 0, 0xfa0, + { 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } }, + { "Canon EOS 350D", 0, 0xfff, + { 6018,-617,-965,-8645,15881,2975,-1530,1719,7642 } }, + { "Canon EOS 400D", 0, 0xe8e, + { 7054,-1501,-990,-8156,15544,2812,-1278,1414,7796 } }, + { "Canon EOS 450D", 0, 0x390d, + { 5784,-262,-821,-7539,15064,2672,-1982,2681,7427 } }, + { "Canon EOS 500D", 0, 0x3479, + { 4763,712,-646,-6821,14399,2640,-1921,3276,6561 } }, + { "Canon EOS 550D", 0, 0x3dd7, + { 6941,-1164,-857,-3825,11597,2534,-416,1540,6039 } }, + { "Canon EOS 600D", 0, 0x3510, + { 6461,-907,-882,-4300,12184,2378,-819,1944,5931 } }, + { "Canon EOS 650D", 0, 0x354d, + { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } }, + { "Canon EOS 700D", 0, 0x3c00, + { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } }, + { "Canon EOS 1000D", 0, 0xe43, + { 6771,-1139,-977,-7818,15123,2928,-1244,1437,7533 } }, + { "Canon EOS 1100D", 0, 0x3510, + { 6444,-904,-893,-4563,12308,2535,-903,2016,6728 } }, + { "Canon EOS 1200D", 0, 0x37c2, + { 6461,-907,-882,-4300,12184,2378,-819,1944,5931 } }, + { "Canon EOS M", 0, 0, + { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } }, + { "Canon EOS-1Ds Mark III", 0, 0x3bb0, + { 5859,-211,-930,-8255,16017,2353,-1732,1887,7448 } }, + { "Canon EOS-1Ds Mark II", 0, 0xe80, + { 6517,-602,-867,-8180,15926,2378,-1618,1771,7633 } }, + { "Canon EOS-1D Mark IV", 0, 0x3bb0, + { 6014,-220,-795,-4109,12014,2361,-561,1824,5787 } }, + { "Canon EOS-1D Mark III", 0, 0x3bb0, + { 6291,-540,-976,-8350,16145,2311,-1714,1858,7326 } }, + { "Canon EOS-1D Mark II N", 0, 0xe80, + { 6240,-466,-822,-8180,15825,2500,-1801,1938,8042 } }, + { "Canon EOS-1D Mark II", 0, 0xe80, + { 6264,-582,-724,-8312,15948,2504,-1744,1919,8664 } }, + { "Canon EOS-1DS", 0, 0xe20, + { 4374,3631,-1743,-7520,15212,2472,-2892,3632,8161 } }, + { "Canon EOS-1D C", 0, 0x3c4e, + { 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } }, + { "Canon EOS-1D X", 0, 0x3c4e, + { 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } }, + { "Canon EOS-1D", 0, 0xe20, + { 6806,-179,-1020,-8097,16415,1687,-3267,4236,7690 } }, + { "Canon EOS C500", 853, 0, /* DJC */ + { 17851,-10604,922,-7425,16662,763,-3660,3636,22278 } }, + { "Canon PowerShot A530", 0, 0, + { 0 } }, /* don't want the A5 matrix */ + { "Canon PowerShot A50", 0, 0, + { -5300,9846,1776,3436,684,3939,-5540,9879,6200,-1404,11175,217 } }, + { "Canon PowerShot A5", 0, 0, + { -4801,9475,1952,2926,1611,4094,-5259,10164,5947,-1554,10883,547 } }, + { "Canon PowerShot G10", 0, 0, + { 11093,-3906,-1028,-5047,12492,2879,-1003,1750,5561 } }, + { "Canon PowerShot G11", 0, 0, + { 12177,-4817,-1069,-1612,9864,2049,-98,850,4471 } }, + { "Canon PowerShot G12", 0, 0, + { 13244,-5501,-1248,-1508,9858,1935,-270,1083,4366 } }, + { "Canon PowerShot G15", 0, 0, + { 7474,-2301,-567,-4056,11456,2975,-222,716,4181 } }, + { "Canon PowerShot G16", 0, 0, + { 8020,-2687,-682,-3704,11879,2052,-965,1921,5556 } }, + { "Canon PowerShot G1 X", 0, 0, + { 7378,-1255,-1043,-4088,12251,2048,-876,1946,5805 } }, + { "Canon PowerShot G1", 0, 0, + { -4778,9467,2172,4743,-1141,4344,-5146,9908,6077,-1566,11051,557 } }, + { "Canon PowerShot G2", 0, 0, + { 9087,-2693,-1049,-6715,14382,2537,-2291,2819,7790 } }, + { "Canon PowerShot G3", 0, 0, + { 9212,-2781,-1073,-6573,14189,2605,-2300,2844,7664 } }, + { "Canon PowerShot G5", 0, 0, + { 9757,-2872,-933,-5972,13861,2301,-1622,2328,7212 } }, + { "Canon PowerShot G6", 0, 0, + { 9877,-3775,-871,-7613,14807,3072,-1448,1305,7485 } }, + { "Canon PowerShot G7 X", 0, 0, + { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } }, + { "Canon PowerShot G9", 0, 0, + { 7368,-2141,-598,-5621,13254,2625,-1418,1696,5743 } }, + { "Canon PowerShot Pro1", 0, 0, + { 10062,-3522,-999,-7643,15117,2730,-765,817,7323 } }, + { "Canon PowerShot Pro70", 34, 0, + { -4155,9818,1529,3939,-25,4522,-5521,9870,6610,-2238,10873,1342 } }, + { "Canon PowerShot Pro90", 0, 0, + { -4963,9896,2235,4642,-987,4294,-5162,10011,5859,-1770,11230,577 } }, + { "Canon PowerShot S30", 0, 0, + { 10566,-3652,-1129,-6552,14662,2006,-2197,2581,7670 } }, + { "Canon PowerShot S40", 0, 0, + { 8510,-2487,-940,-6869,14231,2900,-2318,2829,9013 } }, + { "Canon PowerShot S45", 0, 0, + { 8163,-2333,-955,-6682,14174,2751,-2077,2597,8041 } }, + { "Canon PowerShot S50", 0, 0, + { 8882,-2571,-863,-6348,14234,2288,-1516,2172,6569 } }, + { "Canon PowerShot S60", 0, 0, + { 8795,-2482,-797,-7804,15403,2573,-1422,1996,7082 } }, + { "Canon PowerShot S70", 0, 0, + { 9976,-3810,-832,-7115,14463,2906,-901,989,7889 } }, + { "Canon PowerShot S90", 0, 0, + { 12374,-5016,-1049,-1677,9902,2078,-83,852,4683 } }, + { "Canon PowerShot S95", 0, 0, + { 13440,-5896,-1279,-1236,9598,1931,-180,1001,4651 } }, + { "Canon PowerShot S100", 0, 0, + { 7968,-2565,-636,-2873,10697,2513,180,667,4211 } }, + { "Canon PowerShot S110", 0, 0, + { 8039,-2643,-654,-3783,11230,2930,-206,690,4194 } }, + { "Canon PowerShot S120", 0, 0, + { 6961,-1685,-695,-4625,12945,1836,-1114,2152,5518 } }, + { "Canon PowerShot SX1 IS", 0, 0, + { 6578,-259,-502,-5974,13030,3309,-308,1058,4970 } }, + { "Canon PowerShot SX50 HS", 0, 0, + { 12432,-4753,-1247,-2110,10691,1629,-412,1623,4926 } }, + { "Canon PowerShot SX60 HS", 0, 0, + { 13161,-5451,-1344,-1989,10654,1531,-47,1271,4955 } }, + { "Canon PowerShot A3300", 0, 0, /* DJC */ + { 10826,-3654,-1023,-3215,11310,1906,0,999,4960 } }, + { "Canon PowerShot A470", 0, 0, /* DJC */ + { 12513,-4407,-1242,-2680,10276,2405,-878,2215,4734 } }, + { "Canon PowerShot A610", 0, 0, /* DJC */ + { 15591,-6402,-1592,-5365,13198,2168,-1300,1824,5075 } }, + { "Canon PowerShot A620", 0, 0, /* DJC */ + { 15265,-6193,-1558,-4125,12116,2010,-888,1639,5220 } }, + { "Canon PowerShot A630", 0, 0, /* DJC */ + { 14201,-5308,-1757,-6087,14472,1617,-2191,3105,5348 } }, + { "Canon PowerShot A640", 0, 0, /* DJC */ + { 13124,-5329,-1390,-3602,11658,1944,-1612,2863,4885 } }, + { "Canon PowerShot A650", 0, 0, /* DJC */ + { 9427,-3036,-959,-2581,10671,1911,-1039,1982,4430 } }, + { "Canon PowerShot A720", 0, 0, /* DJC */ + { 14573,-5482,-1546,-1266,9799,1468,-1040,1912,3810 } }, + { "Canon PowerShot S3 IS", 0, 0, /* DJC */ + { 14062,-5199,-1446,-4712,12470,2243,-1286,2028,4836 } }, + { "Canon PowerShot SX110 IS", 0, 0, /* DJC */ + { 14134,-5576,-1527,-1991,10719,1273,-1158,1929,3581 } }, + { "Canon PowerShot SX220", 0, 0, /* DJC */ + { 13898,-5076,-1447,-1405,10109,1297,-244,1860,3687 } }, + { "Casio EX-S20", 0, 0, /* DJC */ + { 11634,-3924,-1128,-4968,12954,2015,-1588,2648,7206 } }, + { "Casio EX-Z750", 0, 0, /* DJC */ + { 10819,-3873,-1099,-4903,13730,1175,-1755,3751,4632 } }, + { "Casio EX-Z10", 128, 0xfff, /* DJC */ + { 9790,-3338,-603,-2321,10222,2099,-344,1273,4799 } }, + { "CINE 650", 0, 0, + { 3390,480,-500,-800,3610,340,-550,2336,1192 } }, + { "CINE 660", 0, 0, + { 3390,480,-500,-800,3610,340,-550,2336,1192 } }, + { "CINE", 0, 0, + { 20183,-4295,-423,-3940,15330,3985,-280,4870,9800 } }, + { "Contax N Digital", 0, 0xf1e, + { 7777,1285,-1053,-9280,16543,2916,-3677,5679,7060 } }, + { "Epson R-D1", 0, 0, + { 6827,-1878,-732,-8429,16012,2564,-704,592,7145 } }, + { "Fujifilm E550", 0, 0, + { 11044,-3888,-1120,-7248,15168,2208,-1531,2277,8069 } }, + { "Fujifilm E900", 0, 0, + { 9183,-2526,-1078,-7461,15071,2574,-2022,2440,8639 } }, + { "Fujifilm F5", 0, 0, + { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, + { "Fujifilm F6", 0, 0, + { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, + { "Fujifilm F77", 0, 0xfe9, + { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, + { "Fujifilm F7", 0, 0, + { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } }, + { "Fujifilm F8", 0, 0, + { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, + { "Fujifilm S100FS", 514, 0, + { 11521,-4355,-1065,-6524,13767,3058,-1466,1984,6045 } }, + { "Fujifilm S1", 0, 0, + { 12297,-4882,-1202,-2106,10691,1623,-88,1312,4790 } }, + { "Fujifilm S20Pro", 0, 0, + { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } }, + { "Fujifilm S20", 512, 0x3fff, + { 11401,-4498,-1312,-5088,12751,2613,-838,1568,5941 } }, + { "Fujifilm S2Pro", 128, 0, + { 12492,-4690,-1402,-7033,15423,1647,-1507,2111,7697 } }, + { "Fujifilm S3Pro", 0, 0, + { 11807,-4612,-1294,-8927,16968,1988,-2120,2741,8006 } }, + { "Fujifilm S5Pro", 0, 0, + { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } }, + { "Fujifilm S5000", 0, 0, + { 8754,-2732,-1019,-7204,15069,2276,-1702,2334,6982 } }, + { "Fujifilm S5100", 0, 0, + { 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } }, + { "Fujifilm S5500", 0, 0, + { 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } }, + { "Fujifilm S5200", 0, 0, + { 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } }, + { "Fujifilm S5600", 0, 0, + { 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } }, + { "Fujifilm S6", 0, 0, + { 12628,-4887,-1401,-6861,14996,1962,-2198,2782,7091 } }, + { "Fujifilm S7000", 0, 0, + { 10190,-3506,-1312,-7153,15051,2238,-2003,2399,7505 } }, + { "Fujifilm S9000", 0, 0, + { 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } }, + { "Fujifilm S9500", 0, 0, + { 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } }, + { "Fujifilm S9100", 0, 0, + { 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } }, + { "Fujifilm S9600", 0, 0, + { 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } }, + { "Fujifilm SL1000", 0, 0, + { 11705,-4262,-1107,-2282,10791,1709,-555,1713,4945 } }, + { "Fujifilm IS-1", 0, 0, + { 21461,-10807,-1441,-2332,10599,1999,289,875,7703 } }, + { "Fujifilm IS Pro", 0, 0, + { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } }, + { "Fujifilm HS10 HS11", 0, 0xf68, + { 12440,-3954,-1183,-1123,9674,1708,-83,1614,4086 } }, + { "Fujifilm HS2", 0, 0, + { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, + { "Fujifilm HS3", 0, 0, + { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, + { "Fujifilm HS50EXR", 0, 0, + { 12085,-4727,-953,-3257,11489,2002,-511,2046,4592 } }, + { "Fujifilm F900EXR", 0, 0, + { 12085,-4727,-953,-3257,11489,2002,-511,2046,4592 } }, + { "Fujifilm X100S", 0, 0, + { 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 } }, + { "Fujifilm X100T", 0, 0, + { 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 } }, + { "Fujifilm X100", 0, 0, + { 12161,-4457,-1069,-5034,12874,2400,-795,1724,6904 } }, + { "Fujifilm X10", 0, 0, + { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, + { "Fujifilm X20", 0, 0, + { 11768,-4971,-1133,-4904,12927,2183,-480,1723,4605 } }, + { "Fujifilm X30", 0, 0, + { 12328,-5256,-1144,-4469,12927,1675,-87,1291,4351 } }, + { "Fujifilm X-Pro1", 0, 0, + { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, + { "Fujifilm X-A1", 0, 0, + { 11086,-4555,-839,-3512,11310,2517,-815,1341,5940 } }, + { "Fujifilm X-A2", 0, 0, + { 10763,-4560,-917,-3346,11311,2322,-475,1135,5843 } }, + { "Fujifilm X-E1", 0, 0, + { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, + { "Fujifilm X-E2", 0, 0, + { 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 } }, + { "Fujifilm X-M1", 0, 0, + { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, + { "Fujifilm X-S1", 0, 0, + { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, + { "Fujifilm X-T1", 0, 0, + { 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 } }, + { "Fujifilm XF1", 0, 0, + { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, + { "Fujifilm XQ", 0, 0, // XQ1 and XQ2 + { 9252,-2704,-1064,-5893,14265,1717,-1101,2341,4349 } }, + { "Imacon Ixpress", 0, 0, /* DJC */ + { 7025,-1415,-704,-5188,13765,1424,-1248,2742,6038 } }, + { "Kodak NC2000", 0, 0, + { 13891,-6055,-803,-465,9919,642,2121,82,1291 } }, + { "Kodak DCS315C", 8, 0, + { 17523,-4827,-2510,756,8546,-137,6113,1649,2250 } }, + { "Kodak DCS330C", 8, 0, + { 20620,-7572,-2801,-103,10073,-396,3551,-233,2220 } }, + { "Kodak DCS420", 0, 0, + { 10868,-1852,-644,-1537,11083,484,2343,628,2216 } }, + { "Kodak DCS460", 0, 0, + { 10592,-2206,-967,-1944,11685,230,2206,670,1273 } }, + { "Kodak EOSDCS1", 0, 0, + { 10592,-2206,-967,-1944,11685,230,2206,670,1273 } }, + { "Kodak EOSDCS3B", 0, 0, + { 9898,-2700,-940,-2478,12219,206,1985,634,1031 } }, + { "Kodak DCS520C", 178, 0, + { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } }, + { "Kodak DCS560C", 177, 0, + { 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } }, + { "Kodak DCS620C", 177, 0, + { 23617,-10175,-3149,-2054,11749,-272,2586,-489,3453 } }, + { "Kodak DCS620X", 176, 0, + { 13095,-6231,154,12221,-21,-2137,895,4602,2258 } }, + { "Kodak DCS660C", 173, 0, + { 18244,-6351,-2739,-791,11193,-521,3711,-129,2802 } }, + { "Kodak DCS720X", 0, 0, + { 11775,-5884,950,9556,1846,-1286,-1019,6221,2728 } }, + { "Kodak DCS760C", 0, 0, + { 16623,-6309,-1411,-4344,13923,323,2285,274,2926 } }, + { "Kodak DCS Pro SLR", 0, 0, + { 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } }, + { "Kodak DCS Pro 14nx", 0, 0, + { 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } }, + { "Kodak DCS Pro 14", 0, 0, + { 7791,3128,-776,-8588,16458,2039,-2455,4006,6198 } }, + { "Kodak ProBack645", 0, 0, + { 16414,-6060,-1470,-3555,13037,473,2545,122,4948 } }, + { "Kodak ProBack", 0, 0, + { 21179,-8316,-2918,-915,11019,-165,3477,-180,4210 } }, + { "Kodak P712", 0, 0, + { 9658,-3314,-823,-5163,12695,2768,-1342,1843,6044 } }, + { "Kodak P850", 0, 0xf7c, + { 10511,-3836,-1102,-6946,14587,2558,-1481,1792,6246 } }, + { "Kodak P880", 0, 0xfff, + { 12805,-4662,-1376,-7480,15267,2360,-1626,2194,7904 } }, + { "Kodak EasyShare Z980", 0, 0, + { 11313,-3559,-1101,-3893,11891,2257,-1214,2398,4908 } }, + { "Kodak EasyShare Z981", 0, 0, + { 12729,-4717,-1188,-1367,9187,2582,274,860,4411 } }, + { "Kodak EasyShare Z990", 0, 0xfed, + { 11749,-4048,-1309,-1867,10572,1489,-138,1449,4522 } }, + { "Kodak EASYSHARE Z1015", 0, 0xef1, + { 11265,-4286,-992,-4694,12343,2647,-1090,1523,5447 } }, + { "Leaf CMost", 0, 0, + { 3952,2189,449,-6701,14585,2275,-4536,7349,6536 } }, + { "Leaf Valeo 6", 0, 0, + { 3952,2189,449,-6701,14585,2275,-4536,7349,6536 } }, + { "Leaf Aptus 54S", 0, 0, + { 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 } }, + { "Leaf Aptus 65", 0, 0, + { 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } }, + { "Leaf Aptus 75", 0, 0, + { 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } }, + { "Leaf", 0, 0, + { 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 } }, + { "Mamiya ZD", 0, 0, + { 7645,2579,-1363,-8689,16717,2015,-3712,5941,5961 } }, + { "Micron 2010", 110, 0, /* DJC */ + { 16695,-3761,-2151,155,9682,163,3433,951,4904 } }, + { "Minolta DiMAGE 5", 0, 0xf7d, + { 8983,-2942,-963,-6556,14476,2237,-2426,2887,8014 } }, + { "Minolta DiMAGE 7Hi", 0, 0xf7d, + { 11368,-3894,-1242,-6521,14358,2339,-2475,3056,7285 } }, + { "Minolta DiMAGE 7", 0, 0xf7d, + { 9144,-2777,-998,-6676,14556,2281,-2470,3019,7744 } }, + { "Minolta DiMAGE A1", 0, 0xf8b, + { 9274,-2547,-1167,-8220,16323,1943,-2273,2720,8340 } }, + { "Minolta DiMAGE A200", 0, 0, + { 8560,-2487,-986,-8112,15535,2771,-1209,1324,7743 } }, + { "Minolta DiMAGE A2", 0, 0xf8f, + { 9097,-2726,-1053,-8073,15506,2762,-966,981,7763 } }, + { "Minolta DiMAGE Z2", 0, 0, /* DJC */ + { 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } }, + { "Minolta DYNAX 5", 0, 0xffb, + { 10284,-3283,-1086,-7957,15762,2316,-829,882,6644 } }, + { "Minolta DYNAX 7", 0, 0xffb, + { 10239,-3104,-1099,-8037,15727,2451,-927,925,6871 } }, + { "Motorola PIXL", 0, 0, /* DJC */ + { 8898,-989,-1033,-3292,11619,1674,-661,3178,5216 } }, + { "Nikon D100", 0, 0, + { 5902,-933,-782,-8983,16719,2354,-1402,1455,6464 } }, + { "Nikon D1H", 0, 0, + { 7577,-2166,-926,-7454,15592,1934,-2377,2808,8606 } }, + { "Nikon D1X", 0, 0, + { 7702,-2245,-975,-9114,17242,1875,-2679,3055,8521 } }, + { "Nikon D1", 0, 0, /* multiplied by 2.218750, 1.0, 1.148438 */ + { 16772,-4726,-2141,-7611,15713,1972,-2846,3494,9521 } }, + { "Nikon D200", 0, 0xfbc, + { 8367,-2248,-763,-8758,16447,2422,-1527,1550,8053 } }, + { "Nikon D2H", 0, 0, + { 5710,-901,-615,-8594,16617,2024,-2975,4120,6830 } }, + { "Nikon D2X", 0, 0, + { 10231,-2769,-1255,-8301,15900,2552,-797,680,7148 } }, + { "Nikon D3000", 0, 0, + { 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } }, + { "Nikon D3100", 0, 0, + { 7911,-2167,-813,-5327,13150,2408,-1288,2483,7968 } }, + { "Nikon D3200", 0, 0xfb9, + { 7013,-1408,-635,-5268,12902,2640,-1470,2801,7379 } }, + { "Nikon D3300", 0, 0, + { 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 } }, + { "Nikon D300", 0, 0, + { 9030,-1992,-715,-8465,16302,2255,-2689,3217,8069 } }, + { "Nikon D3X", 0, 0, + { 7171,-1986,-648,-8085,15555,2718,-2170,2512,7457 } }, + { "Nikon D3S", 0, 0, + { 8828,-2406,-694,-4874,12603,2541,-660,1509,7587 } }, + { "Nikon D3", 0, 0, + { 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } }, + { "Nikon D40X", 0, 0, + { 8819,-2543,-911,-9025,16928,2151,-1329,1213,8449 } }, + { "Nikon D40", 0, 0, + { 6992,-1668,-806,-8138,15748,2543,-874,850,7897 } }, + { "Nikon D4S", 0, 0, + { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } }, + { "Nikon D4", 0, 0, + { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } }, + { "Nikon Df", 0, 0, + { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } }, + { "Nikon D5000", 0, 0xf00, + { 7309,-1403,-519,-8474,16008,2622,-2433,2826,8064 } }, + { "Nikon D5100", 0, 0x3de6, + { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } }, + { "Nikon D5200", 0, 0, + { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } }, + { "Nikon D5300", 0, 0, + { 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 } }, + { "Nikon D5500", 0, 0, + { 8821,-2938,-785,-4178,12142,2287,-824,1651,6860 } }, + { "Nikon D50", 0, 0, + { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } }, + { "Nikon D600", 0, 0x3e07, + { 8178,-2245,-609,-4857,12394,2776,-1207,2086,7298 } }, + { "Nikon D610", 0, 0, + { 8178,-2245,-609,-4857,12394,2776,-1207,2086,7298 } }, + { "Nikon D60", 0, 0, + { 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } }, + { "Nikon D7000", 0, 0, + { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } }, + { "Nikon D7100", 0, 0, + { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } }, + { "Nikon D7200", 0, 0, /* DJC */ + { 6111,-2759,-358,-5108,10766,4343,-769,1691,8030 } }, + { "Nikon D750", 0, 0, + { 9020,-2890,-715,-4535,12436,2348,-934,1919,7086 } }, + { "Nikon D700", 0, 0, + { 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } }, + { "Nikon D70", 0, 0, + { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } }, + { "Nikon D810", 0, 0, + { 9369,-3195,-791,-4488,12430,2301,-893,1796,6872 } }, + { "Nikon D800", 0, 0, + { 7866,-2108,-555,-4869,12483,2681,-1176,2069,7501 } }, + { "Nikon D80", 0, 0, + { 8629,-2410,-883,-9055,16940,2171,-1490,1363,8520 } }, + { "Nikon D90", 0, 0xf00, + { 7309,-1403,-519,-8474,16008,2622,-2434,2826,8064 } }, + { "Nikon E700", 0, 0x3dd, /* DJC */ + { -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } }, + { "Nikon E800", 0, 0x3dd, /* DJC */ + { -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } }, + { "Nikon E950", 0, 0x3dd, /* DJC */ + { -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } }, + { "Nikon E995", 0, 0, /* copied from E5000 */ + { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } }, + { "Nikon E2100", 0, 0, /* copied from Z2, new white balance */ + { 13142,-4152,-1596,-4655,12374,2282,-1769,2696,6711} }, + { "Nikon E2500", 0, 0, + { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } }, + { "Nikon E3200", 0, 0, /* DJC */ + { 9846,-2085,-1019,-3278,11109,2170,-774,2134,5745 } }, + { "Nikon E4300", 0, 0, /* copied from Minolta DiMAGE Z2 */ + { 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } }, + { "Nikon E4500", 0, 0, + { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } }, + { "Nikon E5000", 0, 0, + { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } }, + { "Nikon E5400", 0, 0, + { 9349,-2987,-1001,-7919,15766,2266,-2098,2680,6839 } }, + { "Nikon E5700", 0, 0, + { -5368,11478,2368,5537,-113,3148,-4969,10021,5782,778,9028,211 } }, + { "Nikon E8400", 0, 0, + { 7842,-2320,-992,-8154,15718,2599,-1098,1342,7560 } }, + { "Nikon E8700", 0, 0, + { 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 } }, + { "Nikon E8800", 0, 0, + { 7971,-2314,-913,-8451,15762,2894,-1442,1520,7610 } }, + { "Nikon COOLPIX A", 0, 0, + { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } }, + { "Nikon COOLPIX P330", 200, 0, + { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } }, + { "Nikon COOLPIX P340", 200, 0, + { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } }, + { "Nikon COOLPIX P6000", 0, 0, + { 9698,-3367,-914,-4706,12584,2368,-837,968,5801 } }, + { "Nikon COOLPIX P7000", 0, 0, + { 11432,-3679,-1111,-3169,11239,2202,-791,1380,4455 } }, + { "Nikon COOLPIX P7100", 0, 0, + { 11053,-4269,-1024,-1976,10182,2088,-526,1263,4469 } }, + { "Nikon COOLPIX P7700", 200, 0, + { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } }, + { "Nikon COOLPIX P7800", 200, 0, + { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } }, + { "Nikon 1 V3", 0, 0, + { 5958,-1559,-571,-4021,11453,2939,-634,1548,5087 } }, + { "Nikon 1 J4", 0, 0, + { 5958,-1559,-571,-4021,11453,2939,-634,1548,5087 } }, + { "Nikon 1 J5", 0, 0, /* DJC */ + { 2621,-856,500,-4471,8761,5711,-1321,2644,11945 } }, + { "Nikon 1 S2", 200, 0, + { 6612,-1342,-618,-3338,11055,2623,-174,1792,5075 } }, + { "Nikon 1 V2", 0, 0, + { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } }, + { "Nikon 1 J3", 0, 0, + { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } }, + { "Nikon 1 AW1", 0, 0, + { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } }, + { "Nikon 1 ", 0, 0, /* J1, J2, S1, V1 */ + { 8994,-2667,-865,-4594,12324,2552,-699,1786,6260 } }, + { "Olympus C5050", 0, 0, + { 10508,-3124,-1273,-6079,14294,1901,-1653,2306,6237 } }, + { "Olympus C5060", 0, 0, + { 10445,-3362,-1307,-7662,15690,2058,-1135,1176,7602 } }, + { "Olympus C7070", 0, 0, + { 10252,-3531,-1095,-7114,14850,2436,-1451,1723,6365 } }, + { "Olympus C70", 0, 0, + { 10793,-3791,-1146,-7498,15177,2488,-1390,1577,7321 } }, + { "Olympus C80", 0, 0, + { 8606,-2509,-1014,-8238,15714,2703,-942,979,7760 } }, + { "Olympus E-10", 0, 0xffc, + { 12745,-4500,-1416,-6062,14542,1580,-1934,2256,6603 } }, + { "Olympus E-1", 0, 0, + { 11846,-4767,-945,-7027,15878,1089,-2699,4122,8311 } }, + { "Olympus E-20", 0, 0xffc, + { 13173,-4732,-1499,-5807,14036,1895,-2045,2452,7142 } }, + { "Olympus E-300", 0, 0, + { 7828,-1761,-348,-5788,14071,1830,-2853,4518,6557 } }, + { "Olympus E-330", 0, 0, + { 8961,-2473,-1084,-7979,15990,2067,-2319,3035,8249 } }, + { "Olympus E-30", 0, 0xfbc, + { 8144,-1861,-1111,-7763,15894,1929,-1865,2542,7607 } }, + { "Olympus E-3", 0, 0xf99, + { 9487,-2875,-1115,-7533,15606,2010,-1618,2100,7389 } }, + { "Olympus E-400", 0, 0, + { 6169,-1483,-21,-7107,14761,2536,-2904,3580,8568 } }, + { "Olympus E-410", 0, 0xf6a, + { 8856,-2582,-1026,-7761,15766,2082,-2009,2575,7469 } }, + { "Olympus E-420", 0, 0xfd7, + { 8746,-2425,-1095,-7594,15612,2073,-1780,2309,7416 } }, + { "Olympus E-450", 0, 0xfd2, + { 8745,-2425,-1095,-7594,15613,2073,-1780,2309,7416 } }, + { "Olympus E-500", 0, 0, + { 8136,-1968,-299,-5481,13742,1871,-2556,4205,6630 } }, + { "Olympus E-510", 0, 0xf6a, + { 8785,-2529,-1033,-7639,15624,2112,-1783,2300,7817 } }, + { "Olympus E-520", 0, 0xfd2, + { 8344,-2322,-1020,-7596,15635,2048,-1748,2269,7287 } }, + { "Olympus E-5", 0, 0xeec, + { 11200,-3783,-1325,-4576,12593,2206,-695,1742,7504 } }, + { "Olympus E-600", 0, 0xfaf, + { 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } }, + { "Olympus E-620", 0, 0xfaf, + { 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } }, + { "Olympus E-P1", 0, 0xffd, + { 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } }, + { "Olympus E-P2", 0, 0xffd, + { 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } }, + { "Olympus E-P3", 0, 0, + { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } }, + { "Olympus E-P5", 0, 0, + { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, + { "Olympus E-PL1s", 0, 0, + { 11409,-3872,-1393,-4572,12757,2003,-709,1810,7415 } }, + { "Olympus E-PL1", 0, 0, + { 11408,-4289,-1215,-4286,12385,2118,-387,1467,7787 } }, + { "Olympus E-PL2", 0, 0xcf3, + { 15030,-5552,-1806,-3987,12387,1767,-592,1670,7023 } }, + { "Olympus E-PL3", 0, 0, + { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } }, + { "Olympus E-PL5", 0, 0xfcb, + { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, + { "Olympus E-PL6", 0, 0, + { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, + { "Olympus E-PL7", 0, 0, + { 9197,-3190,-659,-2606,10830,2039,-458,1250,5458 } }, + { "Olympus E-PM1", 0, 0, + { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } }, + { "Olympus E-PM2", 0, 0, + { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, + { "Olympus E-M10", 0, 0, + { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, + { "Olympus E-M1", 0, 0, + { 7687,-1984,-606,-4327,11928,2721,-1381,2339,6452 } }, + { "Olympus E-M5MarkII", 0, 0, + { 9422,-3258,-711,-2655,10898,2015,-512,1354,5512 } }, + { "Olympus E-M5", 0, 0xfe1, + { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, + { "Olympus SP350", 0, 0, + { 12078,-4836,-1069,-6671,14306,2578,-786,939,7418 } }, + { "Olympus SP3", 0, 0, + { 11766,-4445,-1067,-6901,14421,2707,-1029,1217,7572 } }, + { "Olympus SP500UZ", 0, 0xfff, + { 9493,-3415,-666,-5211,12334,3260,-1548,2262,6482 } }, + { "Olympus SP510UZ", 0, 0xffe, + { 10593,-3607,-1010,-5881,13127,3084,-1200,1805,6721 } }, + { "Olympus SP550UZ", 0, 0xffe, + { 11597,-4006,-1049,-5432,12799,2957,-1029,1750,6516 } }, + { "Olympus SP560UZ", 0, 0xff9, + { 10915,-3677,-982,-5587,12986,2911,-1168,1968,6223 } }, + { "Olympus SP570UZ", 0, 0, + { 11522,-4044,-1146,-4736,12172,2904,-988,1829,6039 } }, + { "Olympus STYLUS1", 0, 0, + { 8360,-2420,-880,-3928,12353,1739,-1381,2416,5173 } }, + { "Olympus XZ-10", 0, 0, + { 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } }, + { "Olympus XZ-1", 0, 0, + { 10901,-4095,-1074,-1141,9208,2293,-62,1417,5158 } }, + { "Olympus XZ-2", 0, 0, + { 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } }, + { "OmniVision", 0, 0, /* DJC */ + { 12782,-4059,-379,-478,9066,1413,1340,1513,5176 } }, + { "Pentax *ist DL2", 0, 0, + { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } }, + { "Pentax *ist DL", 0, 0, + { 10829,-2838,-1115,-8339,15817,2696,-837,680,11939 } }, + { "Pentax *ist DS2", 0, 0, + { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } }, + { "Pentax *ist DS", 0, 0, + { 10371,-2333,-1206,-8688,16231,2602,-1230,1116,11282 } }, + { "Pentax *ist D", 0, 0, + { 9651,-2059,-1189,-8881,16512,2487,-1460,1345,10687 } }, + { "Pentax K10D", 0, 0, + { 9566,-2863,-803,-7170,15172,2112,-818,803,9705 } }, + { "Pentax K1", 0, 0, + { 11095,-3157,-1324,-8377,15834,2720,-1108,947,11688 } }, + { "Pentax K20D", 0, 0, + { 9427,-2714,-868,-7493,16092,1373,-2199,3264,7180 } }, + { "Pentax K200D", 0, 0, + { 9186,-2678,-907,-8693,16517,2260,-1129,1094,8524 } }, + { "Pentax K2000", 0, 0, + { 11057,-3604,-1155,-5152,13046,2329,-282,375,8104 } }, + { "Pentax K-m", 0, 0, + { 11057,-3604,-1155,-5152,13046,2329,-282,375,8104 } }, + { "Pentax K-x", 0, 0, + { 8843,-2837,-625,-5025,12644,2668,-411,1234,7410 } }, + { "Pentax K-r", 0, 0, + { 9895,-3077,-850,-5304,13035,2521,-883,1768,6936 } }, + { "Pentax K-3", 0, 0, + { 7415,-2052,-721,-5186,12788,2682,-1446,2157,6773 } }, + { "Pentax K-5 II", 0, 0, + { 8170,-2725,-639,-4440,12017,2744,-771,1465,6599 } }, + { "Pentax K-5", 0, 0, + { 8713,-2833,-743,-4342,11900,2772,-722,1543,6247 } }, + { "Pentax K-7", 0, 0, + { 9142,-2947,-678,-8648,16967,1663,-2224,2898,8615 } }, + { "Pentax K-S1", 0, 0, + { 8512,-3211,-787,-4167,11966,2487,-638,1288,6054 } }, + { "Pentax 645D", 0, 0x3e00, + { 10646,-3593,-1158,-3329,11699,1831,-667,2874,6287 } }, + { "Panasonic DMC-CM1", 15, 0, + { 8770,-3194,-820,-2871,11281,1803,-513,1552,4434 } }, + { "Panasonic DMC-FZ8", 0, 0xf7f, + { 8986,-2755,-802,-6341,13575,3077,-1476,2144,6379 } }, + { "Panasonic DMC-FZ18", 0, 0, + { 9932,-3060,-935,-5809,13331,2753,-1267,2155,5575 } }, + { "Panasonic DMC-FZ28", 15, 0xf96, + { 10109,-3488,-993,-5412,12812,2916,-1305,2140,5543 } }, + { "Panasonic DMC-FZ30", 0, 0xf94, + { 10976,-4029,-1141,-7918,15491,2600,-1670,2071,8246 } }, + { "Panasonic DMC-FZ3", 15, 0, + { 9938,-2780,-890,-4604,12393,2480,-1117,2304,4620 } }, + { "Panasonic DMC-FZ4", 15, 0, + { 13639,-5535,-1371,-1698,9633,2430,316,1152,4108 } }, + { "Panasonic DMC-FZ50", 0, 0, + { 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } }, + { "Panasonic DMC-FZ7", 15, 0, + { 11532,-4324,-1066,-2375,10847,1749,-564,1699,4351 } }, + { "Leica V-LUX1", 0, 0, + { 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } }, + { "Panasonic DMC-L10", 15, 0xf96, + { 8025,-1942,-1050,-7920,15904,2100,-2456,3005,7039 } }, + { "Panasonic DMC-L1", 0, 0xf7f, + { 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 } }, + { "Leica DIGILUX 3", 0, 0xf7f, + { 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 } }, + { "Panasonic DMC-LC1", 0, 0, + { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } }, + { "Leica DIGILUX 2", 0, 0, + { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } }, + { "Panasonic DMC-LX100", 15, 0, + { 8844,-3538,-768,-3709,11762,2200,-698,1792,5220 } }, + { "Leica D-LUX (Typ 109)", 15, 0, + { 8844,-3538,-768,-3709,11762,2200,-698,1792,5220 } }, + { "Panasonic DMC-LF1", 15, 0, + { 9379,-3267,-816,-3227,11560,1881,-926,1928,5340 } }, + { "Leica C (Typ 112)", 15, 0, + { 9379,-3267,-816,-3227,11560,1881,-926,1928,5340 } }, + { "Panasonic DMC-LX1", 0, 0xf7f, + { 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } }, + { "Leica D-LUX2", 0, 0xf7f, + { 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } }, + { "Panasonic DMC-LX2", 0, 0, + { 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } }, + { "Leica D-LUX3", 0, 0, + { 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } }, + { "Panasonic DMC-LX3", 15, 0, + { 8128,-2668,-655,-6134,13307,3161,-1782,2568,6083 } }, + { "Leica D-LUX 4", 15, 0, + { 8128,-2668,-655,-6134,13307,3161,-1782,2568,6083 } }, + { "Panasonic DMC-LX5", 15, 0, + { 10909,-4295,-948,-1333,9306,2399,22,1738,4582 } }, + { "Leica D-LUX 5", 15, 0, + { 10909,-4295,-948,-1333,9306,2399,22,1738,4582 } }, + { "Panasonic DMC-LX7", 15, 0, + { 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } }, + { "Leica D-LUX 6", 15, 0, + { 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } }, + { "Panasonic DMC-FZ1000", 15, 0, + { 7830,-2696,-763,-3325,11667,1866,-641,1712,4824 } }, + { "Leica V-LUX (Typ 114)", 15, 0, + { 7830,-2696,-763,-3325,11667,1866,-641,1712,4824 } }, + { "Panasonic DMC-FZ100", 15, 0xfff, + { 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } }, + { "Leica V-LUX 2", 15, 0xfff, + { 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } }, + { "Panasonic DMC-FZ150", 15, 0xfff, + { 11904,-4541,-1189,-2355,10899,1662,-296,1586,4289 } }, + { "Leica V-LUX 3", 15, 0xfff, + { 11904,-4541,-1189,-2355,10899,1662,-296,1586,4289 } }, + { "Panasonic DMC-FZ200", 15, 0xfff, + { 8112,-2563,-740,-3730,11784,2197,-941,2075,4933 } }, + { "Leica V-LUX 4", 15, 0xfff, + { 8112,-2563,-740,-3730,11784,2197,-941,2075,4933 } }, + { "Panasonic DMC-FX150", 15, 0xfff, + { 9082,-2907,-925,-6119,13377,3058,-1797,2641,5609 } }, + { "Panasonic DMC-G10", 0, 0, + { 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } }, + { "Panasonic DMC-G1", 15, 0xf94, + { 8199,-2065,-1056,-8124,16156,2033,-2458,3022,7220 } }, + { "Panasonic DMC-G2", 15, 0xf3c, + { 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } }, + { "Panasonic DMC-G3", 15, 0xfff, + { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } }, + { "Panasonic DMC-G5", 15, 0xfff, + { 7798,-2562,-740,-3879,11584,2613,-1055,2248,5434 } }, + { "Panasonic DMC-G6", 15, 0xfff, + { 8294,-2891,-651,-3869,11590,2595,-1183,2267,5352 } }, + { "Panasonic DMC-GF1", 15, 0xf92, + { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } }, + { "Panasonic DMC-GF2", 15, 0xfff, + { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } }, + { "Panasonic DMC-GF3", 15, 0xfff, + { 9051,-2468,-1204,-5212,13276,2121,-1197,2510,6890 } }, + { "Panasonic DMC-GF5", 15, 0xfff, + { 8228,-2945,-660,-3938,11792,2430,-1094,2278,5793 } }, + { "Panasonic DMC-GF6", 15, 0, + { 8130,-2801,-946,-3520,11289,2552,-1314,2511,5791 } }, + { "Panasonic DMC-GF7", 15, 0, + { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } }, + { "Panasonic DMC-GH1", 15, 0xf92, + { 6299,-1466,-532,-6535,13852,2969,-2331,3112,5984 } }, + { "Panasonic DMC-GH2", 15, 0xf95, + { 7780,-2410,-806,-3913,11724,2484,-1018,2390,5298 } }, + { "Panasonic DMC-GH3", 15, 0, + { 6559,-1752,-491,-3672,11407,2586,-962,1875,5130 } }, + { "Panasonic DMC-GH4", 15, 0, + { 7122,-2108,-512,-3155,11201,2231,-541,1423,5045 } }, + { "Panasonic DMC-GM1", 15, 0, + { 6770,-1895,-744,-5232,13145,2303,-1664,2691,5703 } }, + { "Panasonic DMC-GM5", 15, 0, + { 8238,-3244,-679,-3921,11814,2384,-836,2022,5852 } }, + { "Panasonic DMC-GX1", 15, 0, + { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } }, + { "Panasonic DMC-GX7", 15, 0, + { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } }, + { "Panasonic DMC-TZ6", 15, 0, + { 8607,-2822,-808,-3755,11930,2049,-820,2060,5224 } }, + { "Panasonic DMC-ZS4", 15, 0, + { 8607,-2822,-808,-3755,11930,2049,-820,2060,5224 } }, + { "Panasonic DMC-TZ7", 15, 0, + { 8802,-3135,-789,-3151,11468,1904,-550,1745,4810 } }, + { "Panasonic DMC-ZS5", 15, 0, + { 8802,-3135,-789,-3151,11468,1904,-550,1745,4810 } }, + { "Phase One H 20", 0, 0, /* DJC */ + { 1313,1855,-109,-6715,15908,808,-327,1840,6020 } }, + { "Phase One H 25", 0, 0, + { 2905,732,-237,-8134,16626,1476,-3038,4253,7517 } }, + { "Phase One P 2", 0, 0, + { 2905,732,-237,-8134,16626,1476,-3038,4253,7517 } }, + { "Phase One P 30", 0, 0, + { 4516,-245,-37,-7020,14976,2173,-3206,4671,7087 } }, + { "Phase One P 45", 0, 0, + { 5053,-24,-117,-5684,14076,1702,-2619,4492,5849 } }, + { "Phase One P40", 0, 0, + { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } }, + { "Phase One P65", 0, 0, + { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } }, + { "Red One", 704, 0xffff, /* DJC */ + { 21014,-7891,-2613,-3056,12201,856,-2203,5125,8042 } }, + { "Samsung EX1", 0, 0x3e00, + { 8898,-2498,-994,-3144,11328,2066,-760,1381,4576 } }, + { "Samsung EX2F", 0, 0x7ff, + { 10648,-3897,-1055,-2022,10573,1668,-492,1611,4742 } }, + { "Samsung EK-GN120", 0, 0, + { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } }, + { "Samsung NX mini", 0, 0, + { 5222,-1196,-550,-6540,14649,2009,-1666,2819,5657 } }, + { "Samsung NX3000", 0, 0, + { 8060,-2933,-761,-4504,12890,1762,-630,1489,5227 } }, + { "Samsung NX30", 0, 0, /* NX30, NX300, NX300M */ + { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } }, + { "Samsung NX2000", 0, 0, + { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } }, + { "Samsung NX2", 0, 0xfff, /* NX20, NX200, NX210 */ + { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } }, + { "Samsung NX1000", 0, 0, + { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } }, + { "Samsung NX1100", 0, 0, + { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } }, + { "Samsung NX11", 0, 0, + { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } }, + { "Samsung NX10", 0, 0, /* also NX100 */ + { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } }, + { "Samsung NX500", 0, 0, /* DJC */ + { 10196,-4532,-272,-3888,11489,2400,-1203,2424,9173 } }, + { "Samsung NX5", 0, 0, + { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } }, + { "Samsung NX1", 0, 0, + { 10686,-4042,-1052,-3595,13238,276,-464,1259,5931 } }, + { "Samsung WB2000", 0, 0xfff, + { 12093,-3557,-1155,-1000,9534,1733,-22,1787,4576 } }, + { "Samsung GX-1", 0, 0, + { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } }, + { "Samsung GX20", 0, 0, /* copied from Pentax K20D */ + { 9427,-2714,-868,-7493,16092,1373,-2199,3264,7180 } }, + { "Samsung S85", 0, 0, /* DJC */ + { 11885,-3968,-1473,-4214,12299,1916,-835,1655,5549 } }, + { "Sinar", 0, 0, /* DJC */ + { 16442,-2956,-2422,-2877,12128,750,-1136,6066,4559 } }, + { "Sony DSC-F828", 0, 0, + { 7924,-1910,-777,-8226,15459,2998,-1517,2199,6818,-7242,11401,3481 } }, + { "Sony DSC-R1", 512, 0, + { 8512,-2641,-694,-8042,15670,2526,-1821,2117,7414 } }, + { "Sony DSC-V3", 0, 0, + { 7511,-2571,-692,-7894,15088,3060,-948,1111,8128 } }, + { "Sony DSC-RX100M", 200, 0, /* M2 and M3 */ + { 6596,-2079,-562,-4782,13016,1933,-970,1581,5181 } }, + { "Sony DSC-RX100", 200, 0, + { 8651,-2754,-1057,-3464,12207,1373,-568,1398,4434 } }, + { "Sony DSC-RX10", 200, 0, + { 6679,-1825,-745,-5047,13256,1953,-1580,2422,5183 } }, + { "Sony DSC-RX1", 128, 0, + { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } }, + { "Sony DSLR-A100", 0, 0xfeb, + { 9437,-2811,-774,-8405,16215,2290,-710,596,7181 } }, + { "Sony DSLR-A290", 0, 0, + { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } }, + { "Sony DSLR-A2", 0, 0, + { 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } }, + { "Sony DSLR-A300", 0, 0, + { 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } }, + { "Sony DSLR-A330", 0, 0, + { 9847,-3091,-929,-8485,16346,2225,-714,595,7103 } }, + { "Sony DSLR-A350", 0, 0xffc, + { 6038,-1484,-578,-9146,16746,2513,-875,746,7217 } }, + { "Sony DSLR-A380", 0, 0, + { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } }, + { "Sony DSLR-A390", 0, 0, + { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } }, + { "Sony DSLR-A450", 128, 0xfeb, + { 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } }, + { "Sony DSLR-A580", 128, 0xfeb, + { 5932,-1492,-411,-4813,12285,2856,-741,1524,6739 } }, + { "Sony DSLR-A500", 128, 0xfeb, + { 6046,-1127,-278,-5574,13076,2786,-691,1419,7625 } }, + { "Sony DSLR-A5", 128, 0xfeb, + { 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } }, + { "Sony DSLR-A700", 128, 0, + { 5775,-805,-359,-8574,16295,2391,-1943,2341,7249 } }, + { "Sony DSLR-A850", 128, 0, + { 5413,-1162,-365,-5665,13098,2866,-608,1179,8440 } }, + { "Sony DSLR-A900", 128, 0, + { 5209,-1072,-397,-8845,16120,2919,-1618,1803,8654 } }, + { "Sony ILCA-77M2", 128, 0, + { 5991,-1732,-443,-4100,11989,2381,-704,1467,5992 } }, + { "Sony ILCE-7M2", 128, 0, + { 5271,-712,-347,-6153,13653,2763,-1601,2366,7242 } }, + { "Sony ILCE-7S", 128, 0, + { 5838,-1430,-246,-3497,11477,2297,-748,1885,5778 } }, + { "Sony ILCE-7R", 128, 0, + { 4913,-541,-202,-6130,13513,2906,-1564,2151,7183 } }, + { "Sony ILCE-7", 128, 0, + { 5271,-712,-347,-6153,13653,2763,-1601,2366,7242 } }, + { "Sony ILCE", 128, 0, /* 3000, 5000, 5100, 6000, and QX1 */ + { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, + { "Sony NEX-5N", 128, 0, + { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, + { "Sony NEX-5R", 128, 0, + { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } }, + { "Sony NEX-5T", 128, 0, + { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } }, + { "Sony NEX-3N", 128, 0, + { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } }, + { "Sony NEX-3", 138, 0, /* DJC */ + { 6907,-1256,-645,-4940,12621,2320,-1710,2581,6230 } }, + { "Sony NEX-5", 116, 0, /* DJC */ + { 6807,-1350,-342,-4216,11649,2567,-1089,2001,6420 } }, + { "Sony NEX-3", 128, 0, /* Adobe */ + { 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } }, + { "Sony NEX-5", 128, 0, /* Adobe */ + { 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } }, + { "Sony NEX-6", 128, 0, + { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } }, + { "Sony NEX-7", 128, 0, + { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } }, + { "Sony NEX", 128, 0, /* NEX-C3, NEX-F3 */ + { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, + { "Sony SLT-A33", 128, 0, + { 6069,-1221,-366,-5221,12779,2734,-1024,2066,6834 } }, + { "Sony SLT-A35", 128, 0, + { 5986,-1618,-415,-4557,11820,3120,-681,1404,6971 } }, + { "Sony SLT-A37", 128, 0, + { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, + { "Sony SLT-A55", 128, 0, + { 5932,-1492,-411,-4813,12285,2856,-741,1524,6739 } }, + { "Sony SLT-A57", 128, 0, + { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, + { "Sony SLT-A58", 128, 0, + { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, + { "Sony SLT-A65", 128, 0, + { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } }, + { "Sony SLT-A77", 128, 0, + { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } }, + { "Sony SLT-A99", 128, 0, + { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } }, + }; + double cam_xyz[4][3]; + char name[130]; + int i, j; + + sprintf (name, "%s %s", make, model); + for (i=0; i < sizeof table / sizeof *table; i++) + if (!strncmp (name, table[i].prefix, strlen(table[i].prefix))) { + if (table[i].black) black = (ushort) table[i].black; + if (table[i].maximum) maximum = (ushort) table[i].maximum; + if (table[i].trans[0]) { + for (raw_color = j=0; j < 12; j++) + ((double *)cam_xyz)[j] = table[i].trans[j] / 10000.0; + cam_xyz_coeff (rgb_cam, cam_xyz); + } + break; + } +} + +void CLASS simple_coeff (int index) +{ + static const float table[][12] = { + /* index 0 -- all Foveon cameras */ + { 1.4032,-0.2231,-0.1016,-0.5263,1.4816,0.017,-0.0112,0.0183,0.9113 }, + /* index 1 -- Kodak DC20 and DC25 */ + { 2.25,0.75,-1.75,-0.25,-0.25,0.75,0.75,-0.25,-0.25,-1.75,0.75,2.25 }, + /* index 2 -- Logitech Fotoman Pixtura */ + { 1.893,-0.418,-0.476,-0.495,1.773,-0.278,-1.017,-0.655,2.672 }, + /* index 3 -- Nikon E880, E900, and E990 */ + { -1.936280, 1.800443, -1.448486, 2.584324, + 1.405365, -0.524955, -0.289090, 0.408680, + -1.204965, 1.082304, 2.941367, -1.818705 } + }; + int i, c; + + for (raw_color = i=0; i < 3; i++) + FORCC rgb_cam[i][c] = table[index][i*colors+c]; +} + +short CLASS guess_byte_order (int words) +{ + uchar test[4][2]; + int t=2, msb; + double diff, sum[2] = {0,0}; + + fread (test[0], 2, 2, ifp); + for (words-=2; words--; ) { + fread (test[t], 2, 1, ifp); + for (msb=0; msb < 2; msb++) { + diff = (test[t^2][msb] << 8 | test[t^2][!msb]) + - (test[t ][msb] << 8 | test[t ][!msb]); + sum[msb] += diff*diff; + } + t = (t+1) & 3; + } + return sum[0] < sum[1] ? 0x4d4d : 0x4949; +} + +float CLASS find_green (int bps, int bite, int off0, int off1) +{ + UINT64 bitbuf=0; + int vbits, col, i, c; + ushort img[2][2064]; + double sum[]={0,0}; + + FORC(2) { + fseek (ifp, c ? off1:off0, SEEK_SET); + for (vbits=col=0; col < width; col++) { + for (vbits -= bps; vbits < 0; vbits += bite) { + bitbuf <<= bite; + for (i=0; i < bite; i+=8) + bitbuf |= (unsigned) (fgetc(ifp) << i); + } + img[c][col] = bitbuf << (64-bps-vbits) >> (64-bps); + } + } + FORC(width-1) { + sum[ c & 1] += ABS(img[0][c]-img[1][c+1]); + sum[~c & 1] += ABS(img[1][c]-img[0][c+1]); + } + return 100 * log(sum[0]/sum[1]); +} + +/* + Identify which camera created this file, and set global variables + accordingly. + */ +void CLASS identify() +{ + static const short pana[][6] = { + { 3130, 1743, 4, 0, -6, 0 }, + { 3130, 2055, 4, 0, -6, 0 }, + { 3130, 2319, 4, 0, -6, 0 }, + { 3170, 2103, 18, 0,-42, 20 }, + { 3170, 2367, 18, 13,-42,-21 }, + { 3177, 2367, 0, 0, -1, 0 }, + { 3304, 2458, 0, 0, -1, 0 }, + { 3330, 2463, 9, 0, -5, 0 }, + { 3330, 2479, 9, 0,-17, 4 }, + { 3370, 1899, 15, 0,-44, 20 }, + { 3370, 2235, 15, 0,-44, 20 }, + { 3370, 2511, 15, 10,-44,-21 }, + { 3690, 2751, 3, 0, -8, -3 }, + { 3710, 2751, 0, 0, -3, 0 }, + { 3724, 2450, 0, 0, 0, -2 }, + { 3770, 2487, 17, 0,-44, 19 }, + { 3770, 2799, 17, 15,-44,-19 }, + { 3880, 2170, 6, 0, -6, 0 }, + { 4060, 3018, 0, 0, 0, -2 }, + { 4290, 2391, 3, 0, -8, -1 }, + { 4330, 2439, 17, 15,-44,-19 }, + { 4508, 2962, 0, 0, -3, -4 }, + { 4508, 3330, 0, 0, -3, -6 }, + }; + static const ushort canon[][11] = { + { 1944, 1416, 0, 0, 48, 0 }, + { 2144, 1560, 4, 8, 52, 2, 0, 0, 0, 25 }, + { 2224, 1456, 48, 6, 0, 2 }, + { 2376, 1728, 12, 6, 52, 2 }, + { 2672, 1968, 12, 6, 44, 2 }, + { 3152, 2068, 64, 12, 0, 0, 16 }, + { 3160, 2344, 44, 12, 4, 4 }, + { 3344, 2484, 4, 6, 52, 6 }, + { 3516, 2328, 42, 14, 0, 0 }, + { 3596, 2360, 74, 12, 0, 0 }, + { 3744, 2784, 52, 12, 8, 12 }, + { 3944, 2622, 30, 18, 6, 2 }, + { 3948, 2622, 42, 18, 0, 2 }, + { 3984, 2622, 76, 20, 0, 2, 14 }, + { 4104, 3048, 48, 12, 24, 12 }, + { 4116, 2178, 4, 2, 0, 0 }, + { 4152, 2772, 192, 12, 0, 0 }, + { 4160, 3124, 104, 11, 8, 65 }, + { 4176, 3062, 96, 17, 8, 0, 0, 16, 0, 7, 0x49 }, + { 4192, 3062, 96, 17, 24, 0, 0, 16, 0, 0, 0x49 }, + { 4312, 2876, 22, 18, 0, 2 }, + { 4352, 2874, 62, 18, 0, 0 }, + { 4476, 2954, 90, 34, 0, 0 }, + { 4480, 3348, 12, 10, 36, 12, 0, 0, 0, 18, 0x49 }, + { 4480, 3366, 80, 50, 0, 0 }, + { 4496, 3366, 80, 50, 12, 0 }, + { 4768, 3516, 96, 16, 0, 0, 0, 16 }, + { 4832, 3204, 62, 26, 0, 0 }, + { 4832, 3228, 62, 51, 0, 0 }, + { 5108, 3349, 98, 13, 0, 0 }, + { 5120, 3318, 142, 45, 62, 0 }, + { 5280, 3528, 72, 52, 0, 0 }, + { 5344, 3516, 142, 51, 0, 0 }, + { 5344, 3584, 126,100, 0, 2 }, + { 5360, 3516, 158, 51, 0, 0 }, + { 5568, 3708, 72, 38, 0, 0 }, + { 5632, 3710, 96, 17, 0, 0, 0, 16, 0, 0, 0x49 }, + { 5712, 3774, 62, 20, 10, 2 }, + { 5792, 3804, 158, 51, 0, 0 }, + { 5920, 3950, 122, 80, 2, 0 }, + { 8896, 5920, 160, 64, 0, 0 }, + }; + static const struct { + ushort id; + char model[20]; + } unique[] = { + { 0x168, "EOS 10D" }, { 0x001, "EOS-1D" }, + { 0x175, "EOS 20D" }, { 0x174, "EOS-1D Mark II" }, + { 0x234, "EOS 30D" }, { 0x232, "EOS-1D Mark II N" }, + { 0x190, "EOS 40D" }, { 0x169, "EOS-1D Mark III" }, + { 0x261, "EOS 50D" }, { 0x281, "EOS-1D Mark IV" }, + { 0x287, "EOS 60D" }, { 0x167, "EOS-1DS" }, + { 0x325, "EOS 70D" }, + { 0x170, "EOS 300D" }, { 0x188, "EOS-1Ds Mark II" }, + { 0x176, "EOS 450D" }, { 0x215, "EOS-1Ds Mark III" }, + { 0x189, "EOS 350D" }, { 0x324, "EOS-1D C" }, + { 0x236, "EOS 400D" }, { 0x269, "EOS-1D X" }, + { 0x252, "EOS 500D" }, { 0x213, "EOS 5D" }, + { 0x270, "EOS 550D" }, { 0x218, "EOS 5D Mark II" }, + { 0x286, "EOS 600D" }, { 0x285, "EOS 5D Mark III" }, + { 0x301, "EOS 650D" }, { 0x302, "EOS 6D" }, + { 0x326, "EOS 700D" }, { 0x250, "EOS 7D" }, + { 0x254, "EOS 1000D" }, + { 0x288, "EOS 1100D" }, + { 0x327, "EOS 1200D" }, + { 0x346, "EOS 100D" }, + }, sonique[] = { + { 0x002, "DSC-R1" }, { 0x100, "DSLR-A100" }, + { 0x101, "DSLR-A900" }, { 0x102, "DSLR-A700" }, + { 0x103, "DSLR-A200" }, { 0x104, "DSLR-A350" }, + { 0x105, "DSLR-A300" }, { 0x108, "DSLR-A330" }, + { 0x109, "DSLR-A230" }, { 0x10a, "DSLR-A290" }, + { 0x10d, "DSLR-A850" }, { 0x111, "DSLR-A550" }, + { 0x112, "DSLR-A500" }, { 0x113, "DSLR-A450" }, + { 0x116, "NEX-5" }, { 0x117, "NEX-3" }, + { 0x118, "SLT-A33" }, { 0x119, "SLT-A55V" }, + { 0x11a, "DSLR-A560" }, { 0x11b, "DSLR-A580" }, + { 0x11c, "NEX-C3" }, { 0x11d, "SLT-A35" }, + { 0x11e, "SLT-A65V" }, { 0x11f, "SLT-A77V" }, + { 0x120, "NEX-5N" }, { 0x121, "NEX-7" }, + { 0x123, "SLT-A37" }, { 0x124, "SLT-A57" }, + { 0x125, "NEX-F3" }, { 0x126, "SLT-A99V" }, + { 0x127, "NEX-6" }, { 0x128, "NEX-5R" }, + { 0x129, "DSC-RX100" }, { 0x12a, "DSC-RX1" }, + { 0x12e, "ILCE-3000" }, { 0x12f, "SLT-A58" }, + { 0x131, "NEX-3N" }, { 0x132, "ILCE-7" }, + { 0x133, "NEX-5T" }, { 0x134, "DSC-RX100M2" }, + { 0x135, "DSC-RX10" }, { 0x136, "DSC-RX1R" }, + { 0x137, "ILCE-7R" }, { 0x138, "ILCE-6000" }, + { 0x139, "ILCE-5000" }, { 0x13d, "DSC-RX100M3" }, + { 0x13e, "ILCE-7S" }, { 0x13f, "ILCA-77M2" }, + { 0x153, "ILCE-5100" }, { 0x154, "ILCE-7M2" }, + { 0x15a, "ILCE-QX1" }, + }; + static const struct { + unsigned fsize; + ushort rw, rh; + uchar lm, tm, rm, bm, lf, cf, max, flags; + char make[10], model[20]; + ushort offset; + } table[] = { + { 786432,1024, 768, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-080C" }, + { 1447680,1392,1040, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-145C" }, + { 1920000,1600,1200, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-201C" }, + { 5067304,2588,1958, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-510C" }, + { 5067316,2588,1958, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-510C",12 }, + { 10134608,2588,1958, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-510C" }, + { 10134620,2588,1958, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-510C",12 }, + { 16157136,3272,2469, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-810C" }, + { 15980544,3264,2448, 0, 0, 0, 0, 8,0x61,0,1,"AgfaPhoto","DC-833m" }, + { 9631728,2532,1902, 0, 0, 0, 0,96,0x61,0,0,"Alcatel","5035D" }, + { 2868726,1384,1036, 0, 0, 0, 0,64,0x49,0,8,"Baumer","TXG14",1078 }, + { 5298000,2400,1766,12,12,44, 2,40,0x94,0,2,"Canon","PowerShot SD300" }, + { 6553440,2664,1968, 4, 4,44, 4,40,0x94,0,2,"Canon","PowerShot A460" }, + { 6573120,2672,1968,12, 8,44, 0,40,0x94,0,2,"Canon","PowerShot A610" }, + { 6653280,2672,1992,10, 6,42, 2,40,0x94,0,2,"Canon","PowerShot A530" }, + { 7710960,2888,2136,44, 8, 4, 0,40,0x94,0,2,"Canon","PowerShot S3 IS" }, + { 9219600,3152,2340,36,12, 4, 0,40,0x94,0,2,"Canon","PowerShot A620" }, + { 9243240,3152,2346,12, 7,44,13,40,0x49,0,2,"Canon","PowerShot A470" }, + { 10341600,3336,2480, 6, 5,32, 3,40,0x94,0,2,"Canon","PowerShot A720 IS" }, + { 10383120,3344,2484,12, 6,44, 6,40,0x94,0,2,"Canon","PowerShot A630" }, + { 12945240,3736,2772,12, 6,52, 6,40,0x94,0,2,"Canon","PowerShot A640" }, + { 15636240,4104,3048,48,12,24,12,40,0x94,0,2,"Canon","PowerShot A650" }, + { 15467760,3720,2772, 6,12,30, 0,40,0x94,0,2,"Canon","PowerShot SX110 IS" }, + { 15534576,3728,2778,12, 9,44, 9,40,0x94,0,2,"Canon","PowerShot SX120 IS" }, + { 18653760,4080,3048,24,12,24,12,40,0x94,0,2,"Canon","PowerShot SX20 IS" }, + { 19131120,4168,3060,92,16, 4, 1,40,0x94,0,2,"Canon","PowerShot SX220 HS" }, + { 21936096,4464,3276,25,10,73,12,40,0x16,0,2,"Canon","PowerShot SX30 IS" }, + { 24724224,4704,3504, 8,16,56, 8,40,0x94,0,2,"Canon","PowerShot A3300 IS" }, + { 1976352,1632,1211, 0, 2, 0, 1, 0,0x94,0,1,"Casio","QV-2000UX" }, + { 3217760,2080,1547, 0, 0,10, 1, 0,0x94,0,1,"Casio","QV-3*00EX" }, + { 6218368,2585,1924, 0, 0, 9, 0, 0,0x94,0,1,"Casio","QV-5700" }, + { 7816704,2867,2181, 0, 0,34,36, 0,0x16,0,1,"Casio","EX-Z60" }, + { 2937856,1621,1208, 0, 0, 1, 0, 0,0x94,7,13,"Casio","EX-S20" }, + { 4948608,2090,1578, 0, 0,32,34, 0,0x94,7,1,"Casio","EX-S100" }, + { 6054400,2346,1720, 2, 0,32, 0, 0,0x94,7,1,"Casio","QV-R41" }, + { 7426656,2568,1928, 0, 0, 0, 0, 0,0x94,0,1,"Casio","EX-P505" }, + { 7530816,2602,1929, 0, 0,22, 0, 0,0x94,7,1,"Casio","QV-R51" }, + { 7542528,2602,1932, 0, 0,32, 0, 0,0x94,7,1,"Casio","EX-Z50" }, + { 7562048,2602,1937, 0, 0,25, 0, 0,0x16,7,1,"Casio","EX-Z500" }, + { 7753344,2602,1986, 0, 0,32,26, 0,0x94,7,1,"Casio","EX-Z55" }, + { 9313536,2858,2172, 0, 0,14,30, 0,0x94,7,1,"Casio","EX-P600" }, + { 10834368,3114,2319, 0, 0,27, 0, 0,0x94,0,1,"Casio","EX-Z750" }, + { 10843712,3114,2321, 0, 0,25, 0, 0,0x94,0,1,"Casio","EX-Z75" }, + { 10979200,3114,2350, 0, 0,32,32, 0,0x94,7,1,"Casio","EX-P700" }, + { 12310144,3285,2498, 0, 0, 6,30, 0,0x94,0,1,"Casio","EX-Z850" }, + { 12489984,3328,2502, 0, 0,47,35, 0,0x94,0,1,"Casio","EX-Z8" }, + { 15499264,3754,2752, 0, 0,82, 0, 0,0x94,0,1,"Casio","EX-Z1050" }, + { 18702336,4096,3044, 0, 0,24, 0,80,0x94,7,1,"Casio","EX-ZR100" }, + { 7684000,2260,1700, 0, 0, 0, 0,13,0x94,0,1,"Casio","QV-4000" }, + { 787456,1024, 769, 0, 1, 0, 0, 0,0x49,0,0,"Creative","PC-CAM 600" }, + { 28829184,4384,3288, 0, 0, 0, 0,36,0x61,0,0,"DJI" }, + { 15151104,4608,3288, 0, 0, 0, 0, 0,0x94,0,0,"Matrix" }, + { 3840000,1600,1200, 0, 0, 0, 0,65,0x49,0,0,"Foculus","531C" }, + { 307200, 640, 480, 0, 0, 0, 0, 0,0x94,0,0,"Generic" }, + { 62464, 256, 244, 1, 1, 6, 1, 0,0x8d,0,0,"Kodak","DC20" }, + { 124928, 512, 244, 1, 1,10, 1, 0,0x8d,0,0,"Kodak","DC20" }, + { 1652736,1536,1076, 0,52, 0, 0, 0,0x61,0,0,"Kodak","DCS200" }, + { 4159302,2338,1779, 1,33, 1, 2, 0,0x94,0,0,"Kodak","C330" }, + { 4162462,2338,1779, 1,33, 1, 2, 0,0x94,0,0,"Kodak","C330",3160 }, + { 2247168,1232, 912, 0, 0,16, 0, 0,0x00,0,0,"Kodak","C330" }, + { 3370752,1232, 912, 0, 0,16, 0, 0,0x00,0,0,"Kodak","C330" }, + { 6163328,2864,2152, 0, 0, 0, 0, 0,0x94,0,0,"Kodak","C603" }, + { 6166488,2864,2152, 0, 0, 0, 0, 0,0x94,0,0,"Kodak","C603",3160 }, + { 460800, 640, 480, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","C603" }, + { 9116448,2848,2134, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","C603" }, + { 12241200,4040,3030, 2, 0, 0,13, 0,0x49,0,0,"Kodak","12MP" }, + { 12272756,4040,3030, 2, 0, 0,13, 0,0x49,0,0,"Kodak","12MP",31556 }, + { 18000000,4000,3000, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","12MP" }, + { 614400, 640, 480, 0, 3, 0, 0,64,0x94,0,0,"Kodak","KAI-0340" }, + { 15360000,3200,2400, 0, 0, 0, 0,96,0x16,0,0,"Lenovo","A820" }, + { 3884928,1608,1207, 0, 0, 0, 0,96,0x16,0,0,"Micron","2010",3212 }, + { 1138688,1534, 986, 0, 0, 0, 0, 0,0x61,0,0,"Minolta","RD175",513 }, + { 1581060,1305, 969, 0, 0,18, 6, 6,0x1e,4,1,"Nikon","E900" }, + { 2465792,1638,1204, 0, 0,22, 1, 6,0x4b,5,1,"Nikon","E950" }, + { 2940928,1616,1213, 0, 0, 0, 7,30,0x94,0,1,"Nikon","E2100" }, + { 4771840,2064,1541, 0, 0, 0, 1, 6,0xe1,0,1,"Nikon","E990" }, + { 4775936,2064,1542, 0, 0, 0, 0,30,0x94,0,1,"Nikon","E3700" }, + { 5865472,2288,1709, 0, 0, 0, 1, 6,0xb4,0,1,"Nikon","E4500" }, + { 5869568,2288,1710, 0, 0, 0, 0, 6,0x16,0,1,"Nikon","E4300" }, + { 7438336,2576,1925, 0, 0, 0, 1, 6,0xb4,0,1,"Nikon","E5000" }, + { 8998912,2832,2118, 0, 0, 0, 0,30,0x94,7,1,"Nikon","COOLPIX S6" }, + { 5939200,2304,1718, 0, 0, 0, 0,30,0x16,0,0,"Olympus","C770UZ" }, + { 3178560,2064,1540, 0, 0, 0, 0, 0,0x94,0,1,"Pentax","Optio S" }, + { 4841984,2090,1544, 0, 0,22, 0, 0,0x94,7,1,"Pentax","Optio S" }, + { 6114240,2346,1737, 0, 0,22, 0, 0,0x94,7,1,"Pentax","Optio S4" }, + { 10702848,3072,2322, 0, 0, 0,21,30,0x94,0,1,"Pentax","Optio 750Z" }, + { 13248000,2208,3000, 0, 0, 0, 0,13,0x61,0,0,"Pixelink","A782" }, + { 6291456,2048,1536, 0, 0, 0, 0,96,0x61,0,0,"RoverShot","3320AF" }, + { 311696, 644, 484, 0, 0, 0, 0, 0,0x16,0,8,"ST Micro","STV680 VGA" }, + { 16098048,3288,2448, 0, 0,24, 0, 9,0x94,0,1,"Samsung","S85" }, + { 16215552,3312,2448, 0, 0,48, 0, 9,0x94,0,1,"Samsung","S85" }, + { 20487168,3648,2808, 0, 0, 0, 0,13,0x94,5,1,"Samsung","WB550" }, + { 24000000,4000,3000, 0, 0, 0, 0,13,0x94,5,1,"Samsung","WB550" }, + { 12582980,3072,2048, 0, 0, 0, 0,33,0x61,0,0,"Sinar","",68 }, + { 33292868,4080,4080, 0, 0, 0, 0,33,0x61,0,0,"Sinar","",68 }, + { 44390468,4080,5440, 0, 0, 0, 0,33,0x61,0,0,"Sinar","",68 }, + { 1409024,1376,1024, 0, 0, 1, 0, 0,0x49,0,0,"Sony","XCD-SX910CR" }, + { 2818048,1376,1024, 0, 0, 1, 0,97,0x49,0,0,"Sony","XCD-SX910CR" }, + }; + static const char *corp[] = + { "AgfaPhoto", "Canon", "Casio", "Epson", "Fujifilm", + "Mamiya", "Minolta", "Motorola", "Kodak", "Konica", "Leica", + "Nikon", "Nokia", "Olympus", "Pentax", "Phase One", "Ricoh", + "Samsung", "Sigma", "Sinar", "Sony" }; + char head[32], *cp; + int hlen, flen, fsize, zero_fsize=1, i, c; + struct jhead jh; + + tiff_flip = flip = filters = UINT_MAX; /* unknown */ + raw_height = raw_width = fuji_width = fuji_layout = cr2_slice[0] = 0; + maximum = height = width = top_margin = left_margin = 0; + cdesc[0] = desc[0] = artist[0] = make[0] = model[0] = model2[0] = 0; + iso_speed = shutter = aperture = focal_len = unique_id = 0; + tiff_nifds = 0; + memset (tiff_ifd, 0, sizeof tiff_ifd); + memset (gpsdata, 0, sizeof gpsdata); + memset (cblack, 0, sizeof cblack); + memset (white, 0, sizeof white); + memset (mask, 0, sizeof mask); + thumb_offset = thumb_length = thumb_width = thumb_height = 0; + load_raw = thumb_load_raw = 0; + write_thumb = &CLASS jpeg_thumb; + data_offset = meta_offset = meta_length = tiff_bps = tiff_compress = 0; + kodak_cbpp = zero_after_ff = dng_version = load_flags = 0; + timestamp = shot_order = tiff_samples = black = is_foveon = 0; + mix_green = profile_length = data_error = zero_is_bad = 0; + pixel_aspect = is_raw = raw_color = 1; + tile_width = tile_length = 0; + for (i=0; i < 4; i++) { + cam_mul[i] = i == 1; + pre_mul[i] = i < 3; + FORC3 cmatrix[c][i] = 0; + FORC3 rgb_cam[c][i] = c == i; + } + colors = 3; + for (i=0; i < 0x10000; i++) curve[i] = i; + + order = get2(); + hlen = get4(); + fseek (ifp, 0, SEEK_SET); + fread (head, 1, 32, ifp); + fseek (ifp, 0, SEEK_END); + flen = fsize = ftell(ifp); + if ((cp = (char *) memmem (head, 32, "MMMM", 4)) || + (cp = (char *) memmem (head, 32, "IIII", 4))) { + parse_phase_one (cp-head); + if (cp-head && parse_tiff(0)) apply_tiff(); + } else if (order == 0x4949 || order == 0x4d4d) { + if (!memcmp (head+6,"HEAPCCDR",8)) { + data_offset = hlen; + parse_ciff (hlen, flen-hlen, 0); + load_raw = &CLASS canon_load_raw; + } else if (parse_tiff(0)) apply_tiff(); + } else if (!memcmp (head,"\xff\xd8\xff\xe1",4) && + !memcmp (head+6,"Exif",4)) { + fseek (ifp, 4, SEEK_SET); + data_offset = 4 + get2(); + fseek (ifp, data_offset, SEEK_SET); + if (fgetc(ifp) != 0xff) + parse_tiff(12); + thumb_offset = 0; + } else if (!memcmp (head+25,"ARECOYK",7)) { + strcpy (make, "Contax"); + strcpy (model,"N Digital"); + fseek (ifp, 33, SEEK_SET); + get_timestamp(1); + fseek (ifp, 60, SEEK_SET); + FORC4 cam_mul[c ^ (c >> 1)] = get4(); + } else if (!strcmp (head, "PXN")) { + strcpy (make, "Logitech"); + strcpy (model,"Fotoman Pixtura"); + } else if (!strcmp (head, "qktk")) { + strcpy (make, "Apple"); + strcpy (model,"QuickTake 100"); + load_raw = &CLASS quicktake_100_load_raw; + } else if (!strcmp (head, "qktn")) { + strcpy (make, "Apple"); + strcpy (model,"QuickTake 150"); + load_raw = &CLASS kodak_radc_load_raw; + } else if (!memcmp (head,"FUJIFILM",8)) { + fseek (ifp, 84, SEEK_SET); + thumb_offset = get4(); + thumb_length = get4(); + fseek (ifp, 92, SEEK_SET); + parse_fuji (get4()); + if (thumb_offset > 120) { + fseek (ifp, 120, SEEK_SET); + is_raw += (i = get4()) && 1; + if (is_raw == 2 && shot_select) + parse_fuji (i); + } + load_raw = &CLASS unpacked_load_raw; + fseek (ifp, 100+28*(shot_select > 0), SEEK_SET); + parse_tiff (data_offset = get4()); + parse_tiff (thumb_offset+12); + apply_tiff(); + } else if (!memcmp (head,"RIFF",4)) { + fseek (ifp, 0, SEEK_SET); + parse_riff(); + } else if (!memcmp (head+4,"ftypqt ",9)) { + fseek (ifp, 0, SEEK_SET); + parse_qt (fsize); + is_raw = 0; + } else if (!memcmp (head,"\0\001\0\001\0@",6)) { + fseek (ifp, 6, SEEK_SET); + fread (make, 1, 8, ifp); + fread (model, 1, 8, ifp); + fread (model2, 1, 16, ifp); + data_offset = get2(); + get2(); + raw_width = get2(); + raw_height = get2(); + load_raw = &CLASS nokia_load_raw; + filters = 0x61616161; + } else if (!memcmp (head,"NOKIARAW",8)) { + strcpy (make, "NOKIA"); + order = 0x4949; + fseek (ifp, 300, SEEK_SET); + data_offset = get4(); + i = get4(); + width = get2(); + height = get2(); + switch (tiff_bps = i*8 / (width * height)) { + case 8: load_raw = &CLASS eight_bit_load_raw; break; + case 10: load_raw = &CLASS nokia_load_raw; + } + raw_height = height + (top_margin = i / (width * tiff_bps/8) - height); + mask[0][3] = 1; + filters = 0x61616161; + } else if (!memcmp (head,"ARRI",4)) { + order = 0x4949; + fseek (ifp, 20, SEEK_SET); + width = get4(); + height = get4(); + strcpy (make, "ARRI"); + fseek (ifp, 668, SEEK_SET); + fread (model, 1, 64, ifp); + data_offset = 4096; + load_raw = &CLASS packed_load_raw; + load_flags = 88; + filters = 0x61616161; + } else if (!memcmp (head,"XPDS",4)) { + order = 0x4949; + fseek (ifp, 0x800, SEEK_SET); + fread (make, 1, 41, ifp); + raw_height = get2(); + raw_width = get2(); + fseek (ifp, 56, SEEK_CUR); + fread (model, 1, 30, ifp); + data_offset = 0x10000; + load_raw = &CLASS canon_rmf_load_raw; + gamma_curve (0, 12.25, 1, 1023); + } else if (!memcmp (head+4,"RED1",4)) { + strcpy (make, "Red"); + strcpy (model,"One"); + parse_redcine(); + load_raw = &CLASS redcine_load_raw; + gamma_curve (1/2.4, 12.92, 1, 4095); + filters = 0x49494949; + } else if (!memcmp (head,"DSC-Image",9)) + parse_rollei(); + else if (!memcmp (head,"PWAD",4)) + parse_sinar_ia(); + else if (!memcmp (head,"\0MRM",4)) + parse_minolta(0); + else if (!memcmp (head,"FOVb",4)) + parse_foveon(); + else if (!memcmp (head,"CI",2)) + parse_cine(); + else + for (zero_fsize=i=0; i < sizeof table / sizeof *table; i++) + if (fsize == table[i].fsize) { + strcpy (make, table[i].make ); + strcpy (model, table[i].model); + flip = table[i].flags >> 2; + zero_is_bad = table[i].flags & 2; + if (table[i].flags & 1) + parse_external_jpeg(); + data_offset = table[i].offset; + raw_width = table[i].rw; + raw_height = table[i].rh; + left_margin = table[i].lm; + top_margin = table[i].tm; + width = raw_width - left_margin - table[i].rm; + height = raw_height - top_margin - table[i].bm; + filters = 0x1010101 * table[i].cf; + colors = 4 - !((filters & filters >> 1) & 0x5555); + load_flags = table[i].lf; + switch (tiff_bps = (fsize-data_offset)*8 / (raw_width*raw_height)) { + case 6: + load_raw = &CLASS minolta_rd175_load_raw; break; + case 8: + load_raw = &CLASS eight_bit_load_raw; break; + case 10: case 12: + load_flags |= 128; + load_raw = &CLASS packed_load_raw; break; + case 16: + order = 0x4949 | 0x404 * (load_flags & 1); + tiff_bps -= load_flags >> 4; + tiff_bps -= load_flags = load_flags >> 1 & 7; + load_raw = &CLASS unpacked_load_raw; + } + maximum = (1 << tiff_bps) - (1 << table[i].max); + } + if (zero_fsize) fsize = 0; + if (make[0] == 0) parse_smal (0, flen); + if (make[0] == 0) { + parse_jpeg(0); + if (!(strncmp(model,"ov",2) && strncmp(model,"RP_OV",5)) && + !fseek (ifp, -6404096, SEEK_END) && + fread (head, 1, 32, ifp) && !strcmp(head,"BRCMn")) { + strcpy (make, "OmniVision"); + data_offset = ftell(ifp) + 0x8000-32; + width = raw_width; + raw_width = 2611; + load_raw = &CLASS nokia_load_raw; + filters = 0x16161616; + } else is_raw = 0; + } + + for (i=0; i < sizeof corp / sizeof *corp; i++) + if (strcasestr (make, corp[i])) /* Simplify company names */ + strcpy (make, corp[i]); + if ((!strcmp(make,"Kodak") || !strcmp(make,"Leica")) && + ((cp = strcasestr(model," DIGITAL CAMERA")) || + (cp = strstr(model,"FILE VERSION")))) + *cp = 0; + if (!strncasecmp(model,"PENTAX",6)) + strcpy (make, "Pentax"); + cp = make + strlen(make); /* Remove trailing spaces */ + while (*--cp == ' ') *cp = 0; + cp = model + strlen(model); + while (*--cp == ' ') *cp = 0; + i = strlen(make); /* Remove make from model */ + if (!strncasecmp (model, make, i) && model[i++] == ' ') + memmove (model, model+i, 64-i); + if (!strncmp (model,"FinePix ",8)) + strcpy (model, model+8); + if (!strncmp (model,"Digital Camera ",15)) + strcpy (model, model+15); + desc[511] = artist[63] = make[63] = model[63] = model2[63] = 0; + if (!is_raw) goto notraw; + + if (!height) height = raw_height; + if (!width) width = raw_width; + if (height == 2624 && width == 3936) /* Pentax K10D and Samsung GX10 */ + { height = 2616; width = 3896; } + if (height == 3136 && width == 4864) /* Pentax K20D and Samsung GX20 */ + { height = 3124; width = 4688; filters = 0x16161616; } + if (width == 4352 && (!strcmp(model,"K-r") || !strcmp(model,"K-x"))) + { width = 4309; filters = 0x16161616; } + if (width >= 4960 && !strncmp(model,"K-5",3)) + { left_margin = 10; width = 4950; filters = 0x16161616; } + if (width == 4736 && !strcmp(model,"K-7")) + { height = 3122; width = 4684; filters = 0x16161616; top_margin = 2; } + if (width == 6080 && !strcmp(model,"K-3")) + { left_margin = 4; width = 6040; } + if (width == 7424 && !strcmp(model,"645D")) + { height = 5502; width = 7328; filters = 0x61616161; top_margin = 29; + left_margin = 48; } + if (height == 3014 && width == 4096) /* Ricoh GX200 */ + width = 4014; + if (dng_version) { + if (filters == UINT_MAX) filters = 0; + if (filters) is_raw = tiff_samples; + else colors = tiff_samples; + switch (tiff_compress) { + case 1: load_raw = &CLASS packed_dng_load_raw; break; + case 7: load_raw = &CLASS lossless_dng_load_raw; break; + case 34892: load_raw = &CLASS lossy_dng_load_raw; break; + default: load_raw = 0; + } + goto dng_skip; + } + if (!strcmp(make,"Canon") && !fsize && tiff_bps != 15) { + if (!load_raw) + load_raw = &CLASS lossless_jpeg_load_raw; + for (i=0; i < sizeof canon / sizeof *canon; i++) + if (raw_width == canon[i][0] && raw_height == canon[i][1]) { + width = raw_width - (left_margin = canon[i][2]); + height = raw_height - (top_margin = canon[i][3]); + width -= canon[i][4]; + height -= canon[i][5]; + mask[0][1] = canon[i][6]; + mask[0][3] = -canon[i][7]; + mask[1][1] = canon[i][8]; + mask[1][3] = -canon[i][9]; + if (canon[i][10]) filters = canon[i][10] * 0x01010101; + } + if ((unique_id | 0x20000) == 0x2720000) { + left_margin = 8; + top_margin = 16; + } + } + for (i=0; i < sizeof unique / sizeof *unique; i++) + if (unique_id == 0x80000000 + unique[i].id) { + adobe_coeff ("Canon", unique[i].model); + if (model[4] == 'K' && strlen(model) == 8) + strcpy (model, unique[i].model); + } + for (i=0; i < sizeof sonique / sizeof *sonique; i++) + if (unique_id == sonique[i].id) + strcpy (model, sonique[i].model); + if (!strcmp(make,"Nikon")) { + if (!load_raw) + load_raw = &CLASS packed_load_raw; + if (model[0] == 'E') + load_flags |= !data_offset << 2 | 2; + } + +/* Set parameters based on camera name (for non-DNG files). */ + + if (!strcmp(model,"KAI-0340") + && find_green (16, 16, 3840, 5120) < 25) { + height = 480; + top_margin = filters = 0; + strcpy (model,"C603"); + } + if (is_foveon) { + if (height*2 < width) pixel_aspect = 0.5; + if (height > width) pixel_aspect = 2; + filters = 0; + simple_coeff(0); + } else if (!strcmp(make,"Canon") && tiff_bps == 15) { + switch (width) { + case 3344: width -= 66; + case 3872: width -= 6; + } + if (height > width) { + SWAP(height,width); + SWAP(raw_height,raw_width); + } + filters = 0; + tiff_samples = colors = 3; + load_raw = &CLASS canon_sraw_load_raw; + } else if (!strcmp(model,"PowerShot 600")) { + height = 613; + width = 854; + raw_width = 896; + colors = 4; + filters = 0xe1e4e1e4; + load_raw = &CLASS canon_600_load_raw; + } else if (!strcmp(model,"PowerShot A5") || + !strcmp(model,"PowerShot A5 Zoom")) { + height = 773; + width = 960; + raw_width = 992; + pixel_aspect = 256/235.0; + filters = 0x1e4e1e4e; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A50")) { + height = 968; + width = 1290; + raw_width = 1320; + filters = 0x1b4e4b1e; + goto canon_a5; + } else if (!strcmp(model,"PowerShot Pro70")) { + height = 1024; + width = 1552; + filters = 0x1e4b4e1b; +canon_a5: + colors = 4; + tiff_bps = 10; + load_raw = &CLASS packed_load_raw; + load_flags = 40; + } else if (!strcmp(model,"PowerShot Pro90 IS") || + !strcmp(model,"PowerShot G1")) { + colors = 4; + filters = 0xb4b4b4b4; + } else if (!strcmp(model,"PowerShot A610")) { + if (canon_s2is()) strcpy (model+10, "S2 IS"); + } else if (!strcmp(model,"PowerShot SX220 HS")) { + mask[1][3] = -4; + } else if (!strcmp(model,"EOS D2000C")) { + filters = 0x61616161; + black = curve[200]; + } else if (!strcmp(model,"D1")) { + cam_mul[0] *= 256/527.0; + cam_mul[2] *= 256/317.0; + } else if (!strcmp(model,"D1X")) { + width -= 4; + pixel_aspect = 0.5; + } else if (!strcmp(model,"D40X") || + !strcmp(model,"D60") || + !strcmp(model,"D80") || + !strcmp(model,"D3000")) { + height -= 3; + width -= 4; + } else if (!strcmp(model,"D3") || + !strcmp(model,"D3S") || + !strcmp(model,"D700")) { + width -= 4; + left_margin = 2; + } else if (!strcmp(model,"D3100")) { + width -= 28; + left_margin = 6; + } else if (!strcmp(model,"D5000") || + !strcmp(model,"D90")) { + width -= 42; + } else if (!strcmp(model,"D5100") || + !strcmp(model,"D7000") || + !strcmp(model,"COOLPIX A")) { + width -= 44; + } else if (!strcmp(model,"D3200") || + !strncmp(model,"D6",2) || + !strncmp(model,"D800",4)) { + width -= 46; + } else if (!strcmp(model,"D4") || + !strcmp(model,"Df")) { + width -= 52; + left_margin = 2; + } else if (!strncmp(model,"D40",3) || + !strncmp(model,"D50",3) || + !strncmp(model,"D70",3)) { + width--; + } else if (!strcmp(model,"D100")) { + if (load_flags) + raw_width = (width += 3) + 3; + } else if (!strcmp(model,"D200")) { + left_margin = 1; + width -= 4; + filters = 0x94949494; + } else if (!strncmp(model,"D2H",3)) { + left_margin = 6; + width -= 14; + } else if (!strncmp(model,"D2X",3)) { + if (width == 3264) width -= 32; + else width -= 8; + } else if (!strncmp(model,"D300",4)) { + width -= 32; + } else if (!strncmp(model,"COOLPIX P",9) && raw_width != 4032) { + load_flags = 24; + filters = 0x94949494; + if (model[9] == '7' && iso_speed >= 400) + black = 255; + } else if (!strncmp(model,"1 ",2)) { + height -= 2; + } else if (fsize == 1581060) { + simple_coeff(3); + pre_mul[0] = 1.2085; + pre_mul[1] = 1.0943; + pre_mul[3] = 1.1103; + } else if (fsize == 3178560) { + cam_mul[0] *= 4; + cam_mul[2] *= 4; + } else if (fsize == 4771840) { + if (!timestamp && nikon_e995()) + strcpy (model, "E995"); + if (strcmp(model,"E995")) { + filters = 0xb4b4b4b4; + simple_coeff(3); + pre_mul[0] = 1.196; + pre_mul[1] = 1.246; + pre_mul[2] = 1.018; + } + } else if (fsize == 2940928) { + if (!timestamp && !nikon_e2100()) + strcpy (model,"E2500"); + if (!strcmp(model,"E2500")) { + height -= 2; + load_flags = 6; + colors = 4; + filters = 0x4b4b4b4b; + } + } else if (fsize == 4775936) { + if (!timestamp) nikon_3700(); + if (model[0] == 'E' && atoi(model+1) < 3700) + filters = 0x49494949; + if (!strcmp(model,"Optio 33WR")) { + flip = 1; + filters = 0x16161616; + } + if (make[0] == 'O') { + i = find_green (12, 32, 1188864, 3576832); + c = find_green (12, 32, 2383920, 2387016); + if (abs(i) < abs(c)) { + SWAP(i,c); + load_flags = 24; + } + if (i < 0) filters = 0x61616161; + } + } else if (fsize == 5869568) { + if (!timestamp && minolta_z2()) { + strcpy (make, "Minolta"); + strcpy (model,"DiMAGE Z2"); + } + load_flags = 6 + 24*(make[0] == 'M'); + } else if (fsize == 6291456) { + fseek (ifp, 0x300000, SEEK_SET); + if ((order = guess_byte_order(0x10000)) == 0x4d4d) { + height -= (top_margin = 16); + width -= (left_margin = 28); + maximum = 0xf5c0; + strcpy (make, "ISG"); + model[0] = 0; + } + } else if (!strcmp(make,"Fujifilm")) { + if (!strcmp(model+7,"S2Pro")) { + strcpy (model,"S2Pro"); + height = 2144; + width = 2880; + flip = 6; + } else if (load_raw != &CLASS packed_load_raw) + maximum = (is_raw == 2 && shot_select) ? 0x2f00 : 0x3e00; + top_margin = (raw_height - height) >> 2 << 1; + left_margin = (raw_width - width ) >> 2 << 1; + if (width == 2848 || width == 3664) filters = 0x16161616; + if (width == 4032 || width == 4952) left_margin = 0; + if (width == 3328 && (width -= 66)) left_margin = 34; + if (width == 4936) left_margin = 4; + if (!strcmp(model,"HS50EXR") || + !strcmp(model,"F900EXR")) { + width += 2; + left_margin = 0; + filters = 0x16161616; + } + if (fuji_layout) raw_width *= is_raw; + if (filters == 9) + FORC(36) ((char *)xtrans)[c] = + xtrans_abs[(c/6+top_margin) % 6][(c+left_margin) % 6]; + } else if (!strcmp(model,"KD-400Z")) { + height = 1712; + width = 2312; + raw_width = 2336; + goto konica_400z; + } else if (!strcmp(model,"KD-510Z")) { + goto konica_510z; + } else if (!strcasecmp(make,"Minolta")) { + if (!load_raw && (maximum = 0xfff)) + load_raw = &CLASS unpacked_load_raw; + if (!strncmp(model,"DiMAGE A",8)) { + if (!strcmp(model,"DiMAGE A200")) + filters = 0x49494949; + tiff_bps = 12; + load_raw = &CLASS packed_load_raw; + } else if (!strncmp(model,"ALPHA",5) || + !strncmp(model,"DYNAX",5) || + !strncmp(model,"MAXXUM",6)) { + sprintf (model+20, "DYNAX %-10s", model+6+(model[0]=='M')); + adobe_coeff (make, model+20); + load_raw = &CLASS packed_load_raw; + } else if (!strncmp(model,"DiMAGE G",8)) { + if (model[8] == '4') { + height = 1716; + width = 2304; + } else if (model[8] == '5') { +konica_510z: + height = 1956; + width = 2607; + raw_width = 2624; + } else if (model[8] == '6') { + height = 2136; + width = 2848; + } + data_offset += 14; + filters = 0x61616161; +konica_400z: + load_raw = &CLASS unpacked_load_raw; + maximum = 0x3df; + order = 0x4d4d; + } + } else if (!strcmp(model,"*ist D")) { + load_raw = &CLASS unpacked_load_raw; + data_error = -1; + } else if (!strcmp(model,"*ist DS")) { + height -= 2; + } else if (!strcmp(make,"Samsung") && raw_width == 4704) { + height -= top_margin = 8; + width -= 2 * (left_margin = 8); + load_flags = 32; + } else if (!strcmp(make,"Samsung") && raw_height == 3714) { + height -= top_margin = 18; + left_margin = raw_width - (width = 5536); + if (raw_width != 5600) + left_margin = top_margin = 0; + filters = 0x61616161; + colors = 3; + } else if (!strcmp(make,"Samsung") && raw_width == 5632) { + order = 0x4949; + height = 3694; + top_margin = 2; + width = 5574 - (left_margin = 32 + tiff_bps); + if (tiff_bps == 12) load_flags = 80; + } else if (!strcmp(make,"Samsung") && raw_width == 5664) { + height -= top_margin = 17; + left_margin = 96; + width = 5544; + filters = 0x49494949; + } else if (!strcmp(make,"Samsung") && raw_width == 6496) { + filters = 0x61616161; + black = 1 << (tiff_bps - 7); + } else if (!strcmp(model,"EX1")) { + order = 0x4949; + height -= 20; + top_margin = 2; + if ((width -= 6) > 3682) { + height -= 10; + width -= 46; + top_margin = 8; + } + } else if (!strcmp(model,"WB2000")) { + order = 0x4949; + height -= 3; + top_margin = 2; + if ((width -= 10) > 3718) { + height -= 28; + width -= 56; + top_margin = 8; + } + } else if (strstr(model,"WB550")) { + strcpy (model, "WB550"); + } else if (!strcmp(model,"EX2F")) { + height = 3045; + width = 4070; + top_margin = 3; + order = 0x4949; + filters = 0x49494949; + load_raw = &CLASS unpacked_load_raw; + } else if (!strcmp(model,"STV680 VGA")) { + black = 16; + } else if (!strcmp(model,"N95")) { + height = raw_height - (top_margin = 2); + } else if (!strcmp(model,"640x480")) { + gamma_curve (0.45, 4.5, 1, 255); + } else if (!strcmp(make,"Hasselblad")) { + if (load_raw == &CLASS lossless_jpeg_load_raw) + load_raw = &CLASS hasselblad_load_raw; + if (raw_width == 7262) { + height = 5444; + width = 7248; + top_margin = 4; + left_margin = 7; + filters = 0x61616161; + } else if (raw_width == 7410 || raw_width == 8282) { + height -= 84; + width -= 82; + top_margin = 4; + left_margin = 41; + filters = 0x61616161; + } else if (raw_width == 9044) { + height = 6716; + width = 8964; + top_margin = 8; + left_margin = 40; + black += load_flags = 256; + maximum = 0x8101; + } else if (raw_width == 4090) { + strcpy (model, "V96C"); + height -= (top_margin = 6); + width -= (left_margin = 3) + 7; + filters = 0x61616161; + } + if (tiff_samples > 1) { + is_raw = tiff_samples+1; + if (!shot_select && !half_size) filters = 0; + } + } else if (!strcmp(make,"Sinar")) { + if (!load_raw) load_raw = &CLASS unpacked_load_raw; + if (is_raw > 1 && !shot_select && !half_size) filters = 0; + maximum = 0x3fff; + } else if (!strcmp(make,"Leaf")) { + maximum = 0x3fff; + fseek (ifp, data_offset, SEEK_SET); + if (ljpeg_start (&jh, 1) && jh.bits == 15) + maximum = 0x1fff; + if (tiff_samples > 1) filters = 0; + if (tiff_samples > 1 || tile_length < raw_height) { + load_raw = &CLASS leaf_hdr_load_raw; + raw_width = tile_width; + } + if ((width | height) == 2048) { + if (tiff_samples == 1) { + filters = 1; + strcpy (cdesc, "RBTG"); + strcpy (model, "CatchLight"); + top_margin = 8; left_margin = 18; height = 2032; width = 2016; + } else { + strcpy (model, "DCB2"); + top_margin = 10; left_margin = 16; height = 2028; width = 2022; + } + } else if (width+height == 3144+2060) { + if (!model[0]) strcpy (model, "Cantare"); + if (width > height) { + top_margin = 6; left_margin = 32; height = 2048; width = 3072; + filters = 0x61616161; + } else { + left_margin = 6; top_margin = 32; width = 2048; height = 3072; + filters = 0x16161616; + } + if (!cam_mul[0] || model[0] == 'V') filters = 0; + else is_raw = tiff_samples; + } else if (width == 2116) { + strcpy (model, "Valeo 6"); + height -= 2 * (top_margin = 30); + width -= 2 * (left_margin = 55); + filters = 0x49494949; + } else if (width == 3171) { + strcpy (model, "Valeo 6"); + height -= 2 * (top_margin = 24); + width -= 2 * (left_margin = 24); + filters = 0x16161616; + } + } else if (!strcmp(make,"Leica") || !strcmp(make,"Panasonic")) { + if ((flen - data_offset) / (raw_width*8/7) == raw_height) + load_raw = &CLASS panasonic_load_raw; + if (!load_raw) { + load_raw = &CLASS unpacked_load_raw; + load_flags = 4; + } + zero_is_bad = 1; + if ((height += 12) > raw_height) height = raw_height; + for (i=0; i < sizeof pana / sizeof *pana; i++) + if (raw_width == pana[i][0] && raw_height == pana[i][1]) { + left_margin = pana[i][2]; + top_margin = pana[i][3]; + width += pana[i][4]; + height += pana[i][5]; + } + filters = 0x01010101 * (uchar) "\x94\x61\x49\x16" + [((filters-1) ^ (left_margin & 1) ^ (top_margin << 1)) & 3]; + } else if (!strcmp(model,"C770UZ")) { + height = 1718; + width = 2304; + filters = 0x16161616; + load_raw = &CLASS packed_load_raw; + load_flags = 30; + } else if (!strcmp(make,"Olympus")) { + height += height & 1; + if (exif_cfa) filters = exif_cfa; + if (width == 4100) width -= 4; + if (width == 4080) width -= 24; + if (width == 9280) { width -= 6; height -= 6; } + if (load_raw == &CLASS unpacked_load_raw) + load_flags = 4; + tiff_bps = 12; + if (!strcmp(model,"E-300") || + !strcmp(model,"E-500")) { + width -= 20; + if (load_raw == &CLASS unpacked_load_raw) { + maximum = 0xfc3; + memset (cblack, 0, sizeof cblack); + } + } else if (!strcmp(model,"E-330")) { + width -= 30; + if (load_raw == &CLASS unpacked_load_raw) + maximum = 0xf79; + } else if (!strcmp(model,"SP550UZ")) { + thumb_length = flen - (thumb_offset = 0xa39800); + thumb_height = 480; + thumb_width = 640; + } + } else if (!strcmp(model,"N Digital")) { + height = 2047; + width = 3072; + filters = 0x61616161; + data_offset = 0x1a00; + load_raw = &CLASS packed_load_raw; + } else if (!strcmp(model,"DSC-F828")) { + width = 3288; + left_margin = 5; + mask[1][3] = -17; + data_offset = 862144; + load_raw = &CLASS sony_load_raw; + filters = 0x9c9c9c9c; + colors = 4; + strcpy (cdesc, "RGBE"); + } else if (!strcmp(model,"DSC-V3")) { + width = 3109; + left_margin = 59; + mask[0][1] = 9; + data_offset = 787392; + load_raw = &CLASS sony_load_raw; + } else if (!strcmp(make,"Sony") && raw_width == 3984) { + width = 3925; + order = 0x4d4d; + } else if (!strcmp(make,"Sony") && raw_width == 4288) { + width -= 32; + } else if (!strcmp(make,"Sony") && raw_width == 4928) { + if (height < 3280) width -= 8; + } else if (!strcmp(make,"Sony") && raw_width == 5504) { + width -= height > 3664 ? 8 : 32; + } else if (!strcmp(make,"Sony") && raw_width == 6048) { + width -= 24; + if (strstr(model,"RX1") || strstr(model,"A99")) + width -= 6; + } else if (!strcmp(make,"Sony") && raw_width == 7392) { + width -= 30; + } else if (!strcmp(model,"DSLR-A100")) { + if (width == 3880) { + height--; + width = ++raw_width; + } else { + height -= 4; + width -= 4; + order = 0x4d4d; + load_flags = 2; + } + filters = 0x61616161; + } else if (!strcmp(model,"DSLR-A350")) { + height -= 4; + } else if (!strcmp(model,"PIXL")) { + height -= top_margin = 4; + width -= left_margin = 32; + gamma_curve (0, 7, 1, 255); + } else if (!strcmp(model,"C603") || !strcmp(model,"C330") + || !strcmp(model,"12MP")) { + order = 0x4949; + if (filters && data_offset) { + fseek (ifp, data_offset < 4096 ? 168 : 5252, SEEK_SET); + read_shorts (curve, 256); + } else gamma_curve (0, 3.875, 1, 255); + load_raw = filters ? &CLASS eight_bit_load_raw : + strcmp(model,"C330") ? &CLASS kodak_c603_load_raw : + &CLASS kodak_c330_load_raw; + load_flags = tiff_bps > 16; + tiff_bps = 8; + } else if (!strncasecmp(model,"EasyShare",9)) { + data_offset = data_offset < 0x15000 ? 0x15000 : 0x17000; + load_raw = &CLASS packed_load_raw; + } else if (!strcasecmp(make,"Kodak")) { + if (filters == UINT_MAX) filters = 0x61616161; + if (!strncmp(model,"NC2000",6) || + !strncmp(model,"EOSDCS",6) || + !strncmp(model,"DCS4",4)) { + width -= 4; + left_margin = 2; + if (model[6] == ' ') model[6] = 0; + if (!strcmp(model,"DCS460A")) goto bw; + } else if (!strcmp(model,"DCS660M")) { + black = 214; + goto bw; + } else if (!strcmp(model,"DCS760M")) { +bw: colors = 1; + filters = 0; + } + if (!strcmp(model+4,"20X")) + strcpy (cdesc, "MYCY"); + if (strstr(model,"DC25")) { + strcpy (model, "DC25"); + data_offset = 15424; + } + if (!strncmp(model,"DC2",3)) { + raw_height = 2 + (height = 242); + if (flen < 100000) { + raw_width = 256; width = 249; + pixel_aspect = (4.0*height) / (3.0*width); + } else { + raw_width = 512; width = 501; + pixel_aspect = (493.0*height) / (373.0*width); + } + top_margin = left_margin = 1; + colors = 4; + filters = 0x8d8d8d8d; + simple_coeff(1); + pre_mul[1] = 1.179; + pre_mul[2] = 1.209; + pre_mul[3] = 1.036; + load_raw = &CLASS eight_bit_load_raw; + } else if (!strcmp(model,"40")) { + strcpy (model, "DC40"); + height = 512; + width = 768; + data_offset = 1152; + load_raw = &CLASS kodak_radc_load_raw; + } else if (strstr(model,"DC50")) { + strcpy (model, "DC50"); + height = 512; + width = 768; + data_offset = 19712; + load_raw = &CLASS kodak_radc_load_raw; + } else if (strstr(model,"DC120")) { + strcpy (model, "DC120"); + height = 976; + width = 848; + pixel_aspect = height/0.75/width; + load_raw = tiff_compress == 7 ? + &CLASS kodak_jpeg_load_raw : &CLASS kodak_dc120_load_raw; + } else if (!strcmp(model,"DCS200")) { + thumb_height = 128; + thumb_width = 192; + thumb_offset = 6144; + thumb_misc = 360; + write_thumb = &CLASS layer_thumb; + black = 17; + } + } else if (!strcmp(model,"Fotoman Pixtura")) { + height = 512; + width = 768; + data_offset = 3632; + load_raw = &CLASS kodak_radc_load_raw; + filters = 0x61616161; + simple_coeff(2); + } else if (!strncmp(model,"QuickTake",9)) { + if (head[5]) strcpy (model+10, "200"); + fseek (ifp, 544, SEEK_SET); + height = get2(); + width = get2(); + data_offset = (get4(),get2()) == 30 ? 738:736; + if (height > width) { + SWAP(height,width); + fseek (ifp, data_offset-6, SEEK_SET); + flip = ~get2() & 3 ? 5:6; + } + filters = 0x61616161; + } else if (!strcmp(make,"Rollei") && !load_raw) { + switch (raw_width) { + case 1316: + height = 1030; + width = 1300; + top_margin = 1; + left_margin = 6; + break; + case 2568: + height = 1960; + width = 2560; + top_margin = 2; + left_margin = 8; + } + filters = 0x16161616; + load_raw = &CLASS rollei_load_raw; + } + if (!model[0]) + sprintf (model, "%dx%d", width, height); + if (filters == UINT_MAX) filters = 0x94949494; + if (thumb_offset && !thumb_height) { + fseek (ifp, thumb_offset, SEEK_SET); + if (ljpeg_start (&jh, 1)) { + thumb_width = jh.wide; + thumb_height = jh.high; + } + } +dng_skip: + if ((use_camera_matrix & (use_camera_wb || dng_version)) + && cmatrix[0][0] > 0.125) { + memcpy (rgb_cam, cmatrix, sizeof cmatrix); + raw_color = 0; + } + if (raw_color) adobe_coeff (make, model); + if (load_raw == &CLASS kodak_radc_load_raw) + if (raw_color) adobe_coeff ("Apple","Quicktake"); + if (fuji_width) { + fuji_width = width >> !fuji_layout; + if (~fuji_width & 1) filters = 0x49494949; + width = (height >> fuji_layout) + fuji_width; + height = width - 1; + pixel_aspect = 1; + } else { + if (raw_height < height) raw_height = height; + if (raw_width < width ) raw_width = width; + } + if (!tiff_bps) tiff_bps = 12; + if (!maximum) maximum = (1 << tiff_bps) - 1; + if (!load_raw || height < 22 || width < 22 || + tiff_bps > 16 || tiff_samples > 6 || colors > 4) + is_raw = 0; +#ifdef NO_JASPER + if (load_raw == &CLASS redcine_load_raw) { + fprintf (stderr,_("%s: You must link dcraw with %s!!\n"), + ifname, "libjasper"); + is_raw = 0; + } +#endif +#ifdef NO_JPEG + if (load_raw == &CLASS kodak_jpeg_load_raw || + load_raw == &CLASS lossy_dng_load_raw) { + fprintf (stderr,_("%s: You must link dcraw with %s!!\n"), + ifname, "libjpeg"); + is_raw = 0; + } +#endif + if (!cdesc[0]) + strcpy (cdesc, colors == 3 ? "RGBG":"GMCY"); + if (!raw_height) raw_height = height; + if (!raw_width ) raw_width = width; + if (filters > 999 && colors == 3) + filters |= ((filters >> 2 & 0x22222222) | + (filters << 2 & 0x88888888)) & filters << 1; +notraw: + if (flip == UINT_MAX) flip = tiff_flip; + if (flip == UINT_MAX) flip = 0; +} + +#ifndef NO_LCMS +void CLASS apply_profile (const char *input, const char *output) +{ + char *prof; + cmsHPROFILE hInProfile=0, hOutProfile=0; + cmsHTRANSFORM hTransform; + FILE *fp; + unsigned size; + + if (strcmp (input, "embed")) + hInProfile = cmsOpenProfileFromFile (input, "r"); + else if (profile_length) { + prof = (char *) malloc (profile_length); + merror (prof, "apply_profile()"); + fseek (ifp, profile_offset, SEEK_SET); + fread (prof, 1, profile_length, ifp); + hInProfile = cmsOpenProfileFromMem (prof, profile_length); + free (prof); + } else + fprintf (stderr,_("%s has no embedded profile.\n"), ifname); + if (!hInProfile) return; + if (!output) + hOutProfile = cmsCreate_sRGBProfile(); + else if ((fp = fopen (output, "rb"))) { + fread (&size, 4, 1, fp); + fseek (fp, 0, SEEK_SET); + oprof = (unsigned *) malloc (size = ntohl(size)); + merror (oprof, "apply_profile()"); + fread (oprof, 1, size, fp); + fclose (fp); + if (!(hOutProfile = cmsOpenProfileFromMem (oprof, size))) { + free (oprof); + oprof = 0; + } + } else + fprintf (stderr,_("Cannot open file %s!\n"), output); + if (!hOutProfile) goto quit; + if (verbose) + fprintf (stderr,_("Applying color profile...\n")); + hTransform = cmsCreateTransform (hInProfile, TYPE_RGBA_16, + hOutProfile, TYPE_RGBA_16, INTENT_PERCEPTUAL, 0); + cmsDoTransform (hTransform, image, image, width*height); + raw_color = 1; /* Don't use rgb_cam with a profile */ + cmsDeleteTransform (hTransform); + cmsCloseProfile (hOutProfile); +quit: + cmsCloseProfile (hInProfile); +} +#endif + +void CLASS convert_to_rgb() +{ + int row, col, c, i, j, k; + ushort *img; + float out[3], out_cam[3][4]; + double num, inverse[3][3]; + static const double xyzd50_srgb[3][3] = + { { 0.436083, 0.385083, 0.143055 }, + { 0.222507, 0.716888, 0.060608 }, + { 0.013930, 0.097097, 0.714022 } }; + static const double rgb_rgb[3][3] = + { { 1,0,0 }, { 0,1,0 }, { 0,0,1 } }; + static const double adobe_rgb[3][3] = + { { 0.715146, 0.284856, 0.000000 }, + { 0.000000, 1.000000, 0.000000 }, + { 0.000000, 0.041166, 0.958839 } }; + static const double wide_rgb[3][3] = + { { 0.593087, 0.404710, 0.002206 }, + { 0.095413, 0.843149, 0.061439 }, + { 0.011621, 0.069091, 0.919288 } }; + static const double prophoto_rgb[3][3] = + { { 0.529317, 0.330092, 0.140588 }, + { 0.098368, 0.873465, 0.028169 }, + { 0.016879, 0.117663, 0.865457 } }; + static const double (*out_rgb[])[3] = + { rgb_rgb, adobe_rgb, wide_rgb, prophoto_rgb, xyz_rgb }; + static const char *name[] = + { "sRGB", "Adobe RGB (1998)", "WideGamut D65", "ProPhoto D65", "XYZ" }; + static const unsigned phead[] = + { 1024, 0, 0x2100000, 0x6d6e7472, 0x52474220, 0x58595a20, 0, 0, 0, + 0x61637370, 0, 0, 0x6e6f6e65, 0, 0, 0, 0, 0xf6d6, 0x10000, 0xd32d }; + unsigned pbody[] = + { 10, 0x63707274, 0, 36, /* cprt */ + 0x64657363, 0, 40, /* desc */ + 0x77747074, 0, 20, /* wtpt */ + 0x626b7074, 0, 20, /* bkpt */ + 0x72545243, 0, 14, /* rTRC */ + 0x67545243, 0, 14, /* gTRC */ + 0x62545243, 0, 14, /* bTRC */ + 0x7258595a, 0, 20, /* rXYZ */ + 0x6758595a, 0, 20, /* gXYZ */ + 0x6258595a, 0, 20 }; /* bXYZ */ + static const unsigned pwhite[] = { 0xf351, 0x10000, 0x116cc }; + unsigned pcurve[] = { 0x63757276, 0, 1, 0x1000000 }; + + gamma_curve (gamm[0], gamm[1], 0, 0); + memcpy (out_cam, rgb_cam, sizeof out_cam); + raw_color |= colors == 1 || document_mode || + output_color < 1 || output_color > 5; + if (!raw_color) { + oprof = (unsigned *) calloc (phead[0], 1); + merror (oprof, "convert_to_rgb()"); + memcpy (oprof, phead, sizeof phead); + if (output_color == 5) oprof[4] = oprof[5]; + oprof[0] = 132 + 12*pbody[0]; + for (i=0; i < pbody[0]; i++) { + oprof[oprof[0]/4] = i ? (i > 1 ? 0x58595a20 : 0x64657363) : 0x74657874; + pbody[i*3+2] = oprof[0]; + oprof[0] += (pbody[i*3+3] + 3) & -4; + } + memcpy (oprof+32, pbody, sizeof pbody); + oprof[pbody[5]/4+2] = strlen(name[output_color-1]) + 1; + memcpy ((char *)oprof+pbody[8]+8, pwhite, sizeof pwhite); + pcurve[3] = (short)(256/gamm[5]+0.5) << 16; + for (i=4; i < 7; i++) + memcpy ((char *)oprof+pbody[i*3+2], pcurve, sizeof pcurve); + pseudoinverse ((double (*)[3]) out_rgb[output_color-1], inverse, 3); + for (i=0; i < 3; i++) + for (j=0; j < 3; j++) { + for (num = k=0; k < 3; k++) + num += xyzd50_srgb[i][k] * inverse[j][k]; + oprof[pbody[j*3+23]/4+i+2] = num * 0x10000 + 0.5; + } + for (i=0; i < phead[0]/4; i++) + oprof[i] = htonl(oprof[i]); + strcpy ((char *)oprof+pbody[2]+8, "auto-generated by dcraw"); + strcpy ((char *)oprof+pbody[5]+12, name[output_color-1]); + for (i=0; i < 3; i++) + for (j=0; j < colors; j++) + for (out_cam[i][j] = k=0; k < 3; k++) + out_cam[i][j] += out_rgb[output_color-1][i][k] * rgb_cam[k][j]; + } + if (verbose) + fprintf (stderr, raw_color ? _("Building histograms...\n") : + _("Converting to %s colorspace...\n"), name[output_color-1]); + + memset (histogram, 0, sizeof histogram); + for (img=image[0], row=0; row < height; row++) + for (col=0; col < width; col++, img+=4) { + if (!raw_color) { + out[0] = out[1] = out[2] = 0; + FORCC { + out[0] += out_cam[0][c] * img[c]; + out[1] += out_cam[1][c] * img[c]; + out[2] += out_cam[2][c] * img[c]; + } + FORC3 img[c] = CLIP((int) out[c]); + } + else if (document_mode) + img[0] = img[fcol(row,col)]; + FORCC histogram[c][img[c] >> 3]++; + } + if (colors == 4 && output_color) colors = 3; + if (document_mode && filters) colors = 1; +} + +void CLASS fuji_rotate() +{ + int i, row, col; + double step; + float r, c, fr, fc; + unsigned ur, uc; + ushort wide, high, (*img)[4], (*pix)[4]; + + if (!fuji_width) return; + if (verbose) + fprintf (stderr,_("Rotating image 45 degrees...\n")); + fuji_width = (fuji_width - 1 + shrink) >> shrink; + step = sqrt(0.5); + wide = fuji_width / step; + high = (height - fuji_width) / step; + img = (ushort (*)[4]) calloc (high, wide*sizeof *img); + merror (img, "fuji_rotate()"); + + for (row=0; row < high; row++) + for (col=0; col < wide; col++) { + ur = r = fuji_width + (row-col)*step; + uc = c = (row+col)*step; + if (ur > height-2 || uc > width-2) continue; + fr = r - ur; + fc = c - uc; + pix = image + ur*width + uc; + for (i=0; i < colors; i++) + img[row*wide+col][i] = + (pix[ 0][i]*(1-fc) + pix[ 1][i]*fc) * (1-fr) + + (pix[width][i]*(1-fc) + pix[width+1][i]*fc) * fr; + } + free (image); + width = wide; + height = high; + image = img; + fuji_width = 0; +} + +void CLASS stretch() +{ + ushort newdim, (*img)[4], *pix0, *pix1; + int row, col, c; + double rc, frac; + + if (pixel_aspect == 1) return; + if (verbose) fprintf (stderr,_("Stretching the image...\n")); + if (pixel_aspect < 1) { + newdim = height / pixel_aspect + 0.5; + img = (ushort (*)[4]) calloc (width, newdim*sizeof *img); + merror (img, "stretch()"); + for (rc=row=0; row < newdim; row++, rc+=pixel_aspect) { + frac = rc - (c = rc); + pix0 = pix1 = image[c*width]; + if (c+1 < height) pix1 += width*4; + for (col=0; col < width; col++, pix0+=4, pix1+=4) + FORCC img[row*width+col][c] = pix0[c]*(1-frac) + pix1[c]*frac + 0.5; + } + height = newdim; + } else { + newdim = width * pixel_aspect + 0.5; + img = (ushort (*)[4]) calloc (height, newdim*sizeof *img); + merror (img, "stretch()"); + for (rc=col=0; col < newdim; col++, rc+=1/pixel_aspect) { + frac = rc - (c = rc); + pix0 = pix1 = image[c]; + if (c+1 < width) pix1 += 4; + for (row=0; row < height; row++, pix0+=width*4, pix1+=width*4) + FORCC img[row*newdim+col][c] = pix0[c]*(1-frac) + pix1[c]*frac + 0.5; + } + width = newdim; + } + free (image); + image = img; +} + +int CLASS flip_index (int row, int col) +{ + if (flip & 4) SWAP(row,col); + if (flip & 2) row = iheight - 1 - row; + if (flip & 1) col = iwidth - 1 - col; + return row * iwidth + col; +} + +struct tiff_tag { + ushort tag, type; + int count; + union { char c[4]; short s[2]; int i; } val; +}; + +struct tiff_hdr { + ushort order, magic; + int ifd; + ushort pad, ntag; + struct tiff_tag tag[23]; + int nextifd; + ushort pad2, nexif; + struct tiff_tag exif[4]; + ushort pad3, ngps; + struct tiff_tag gpst[10]; + short bps[4]; + int rat[10]; + unsigned gps[26]; + char desc[512], make[64], model[64], soft[32], date[20], artist[64]; +}; + +void CLASS tiff_set (ushort *ntag, + ushort tag, ushort type, int count, int val) +{ + struct tiff_tag *tt; + int c; + + tt = (struct tiff_tag *)(ntag+1) + (*ntag)++; + tt->tag = tag; + tt->type = type; + tt->count = count; + if (type < 3 && count <= 4) + FORC(4) tt->val.c[c] = val >> (c << 3); + else if (type == 3 && count <= 2) + FORC(2) tt->val.s[c] = val >> (c << 4); + else tt->val.i = val; +} + +#define TOFF(ptr) ((char *)(&(ptr)) - (char *)th) + +void CLASS tiff_head (struct tiff_hdr *th, int full) +{ + int c, psize=0; + struct tm *t; + + memset (th, 0, sizeof *th); + th->order = htonl(0x4d4d4949) >> 16; + th->magic = 42; + th->ifd = 10; + if (full) { + tiff_set (&th->ntag, 254, 4, 1, 0); + tiff_set (&th->ntag, 256, 4, 1, width); + tiff_set (&th->ntag, 257, 4, 1, height); + tiff_set (&th->ntag, 258, 3, colors, output_bps); + if (colors > 2) + th->tag[th->ntag-1].val.i = TOFF(th->bps); + FORC4 th->bps[c] = output_bps; + tiff_set (&th->ntag, 259, 3, 1, 1); + tiff_set (&th->ntag, 262, 3, 1, 1 + (colors > 1)); + } + tiff_set (&th->ntag, 270, 2, 512, TOFF(th->desc)); + tiff_set (&th->ntag, 271, 2, 64, TOFF(th->make)); + tiff_set (&th->ntag, 272, 2, 64, TOFF(th->model)); + if (full) { + if (oprof) psize = ntohl(oprof[0]); + tiff_set (&th->ntag, 273, 4, 1, sizeof *th + psize); + tiff_set (&th->ntag, 277, 3, 1, colors); + tiff_set (&th->ntag, 278, 4, 1, height); + tiff_set (&th->ntag, 279, 4, 1, height*width*colors*output_bps/8); + } else + tiff_set (&th->ntag, 274, 3, 1, "12435867"[flip]-'0'); + tiff_set (&th->ntag, 282, 5, 1, TOFF(th->rat[0])); + tiff_set (&th->ntag, 283, 5, 1, TOFF(th->rat[2])); + tiff_set (&th->ntag, 284, 3, 1, 1); + tiff_set (&th->ntag, 296, 3, 1, 2); + tiff_set (&th->ntag, 305, 2, 32, TOFF(th->soft)); + tiff_set (&th->ntag, 306, 2, 20, TOFF(th->date)); + tiff_set (&th->ntag, 315, 2, 64, TOFF(th->artist)); + tiff_set (&th->ntag, 34665, 4, 1, TOFF(th->nexif)); + if (psize) tiff_set (&th->ntag, 34675, 7, psize, sizeof *th); + tiff_set (&th->nexif, 33434, 5, 1, TOFF(th->rat[4])); + tiff_set (&th->nexif, 33437, 5, 1, TOFF(th->rat[6])); + tiff_set (&th->nexif, 34855, 3, 1, iso_speed); + tiff_set (&th->nexif, 37386, 5, 1, TOFF(th->rat[8])); + if (gpsdata[1]) { + tiff_set (&th->ntag, 34853, 4, 1, TOFF(th->ngps)); + tiff_set (&th->ngps, 0, 1, 4, 0x202); + tiff_set (&th->ngps, 1, 2, 2, gpsdata[29]); + tiff_set (&th->ngps, 2, 5, 3, TOFF(th->gps[0])); + tiff_set (&th->ngps, 3, 2, 2, gpsdata[30]); + tiff_set (&th->ngps, 4, 5, 3, TOFF(th->gps[6])); + tiff_set (&th->ngps, 5, 1, 1, gpsdata[31]); + tiff_set (&th->ngps, 6, 5, 1, TOFF(th->gps[18])); + tiff_set (&th->ngps, 7, 5, 3, TOFF(th->gps[12])); + tiff_set (&th->ngps, 18, 2, 12, TOFF(th->gps[20])); + tiff_set (&th->ngps, 29, 2, 12, TOFF(th->gps[23])); + memcpy (th->gps, gpsdata, sizeof th->gps); + } + th->rat[0] = th->rat[2] = 300; + th->rat[1] = th->rat[3] = 1; + FORC(6) th->rat[4+c] = 1000000; + th->rat[4] *= shutter; + th->rat[6] *= aperture; + th->rat[8] *= focal_len; + strncpy (th->desc, desc, 512); + strncpy (th->make, make, 64); + strncpy (th->model, model, 64); + strcpy (th->soft, "dcraw v"DCRAW_VERSION); + t = localtime (×tamp); + sprintf (th->date, "%04d:%02d:%02d %02d:%02d:%02d", + t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec); + strncpy (th->artist, artist, 64); +} + +void CLASS jpeg_thumb() +{ + char *thumb; + ushort exif[5]; + struct tiff_hdr th; + + thumb = (char *) malloc (thumb_length); + merror (thumb, "jpeg_thumb()"); + fread (thumb, 1, thumb_length, ifp); + fputc (0xff, ofp); + fputc (0xd8, ofp); + if (strcmp (thumb+6, "Exif")) { + memcpy (exif, "\xff\xe1 Exif\0\0", 10); + exif[1] = htons (8 + sizeof th); + fwrite (exif, 1, sizeof exif, ofp); + tiff_head (&th, 0); + fwrite (&th, 1, sizeof th, ofp); + } + fwrite (thumb+2, 1, thumb_length-2, ofp); + free (thumb); +} + +void CLASS write_ppm_tiff() +{ + struct tiff_hdr th; + uchar *ppm; + ushort *ppm2; + int c, row, col, soff, rstep, cstep; + int perc, val, total, white=0x2000; + + perc = width * height * 0.01; /* 99th percentile white level */ + if (fuji_width) perc /= 2; + if (!((highlight & ~2) || no_auto_bright)) + for (white=c=0; c < colors; c++) { + for (val=0x2000, total=0; --val > 32; ) + if ((total += histogram[c][val]) > perc) break; + if (white < val) white = val; + } + gamma_curve (gamm[0], gamm[1], 2, (white << 3)/bright); + iheight = height; + iwidth = width; + if (flip & 4) SWAP(height,width); + ppm = (uchar *) calloc (width, colors*output_bps/8); + ppm2 = (ushort *) ppm; + merror (ppm, "write_ppm_tiff()"); + if (output_tiff) { + tiff_head (&th, 1); + fwrite (&th, sizeof th, 1, ofp); + if (oprof) + fwrite (oprof, ntohl(oprof[0]), 1, ofp); + } else if (colors > 3) + fprintf (ofp, + "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n", + width, height, colors, (1 << output_bps)-1, cdesc); + else + fprintf (ofp, "P%d\n%d %d\n%d\n", + colors/2+5, width, height, (1 << output_bps)-1); + soff = flip_index (0, 0); + cstep = flip_index (0, 1) - soff; + rstep = flip_index (1, 0) - flip_index (0, width); + for (row=0; row < height; row++, soff += rstep) { + for (col=0; col < width; col++, soff += cstep) + if (output_bps == 8) + FORCC ppm [col*colors+c] = curve[image[soff][c]] >> 8; + else FORCC ppm2[col*colors+c] = curve[image[soff][c]]; + if (output_bps == 16 && !output_tiff && htons(0x55aa) != 0x55aa) + swab (ppm2, ppm2, width*colors*2); + fwrite (ppm, colors*output_bps/8, width, ofp); + } + free (ppm); +} + +int CLASS main (int argc, const char **argv) +{ + int arg, status=0, quality, i, c; + int timestamp_only=0, thumbnail_only=0, identify_only=0; + int user_qual=-1, user_black=-1, user_sat=-1, user_flip=-1; + int use_fuji_rotate=1, write_to_stdout=0, read_from_stdin=0; + const char *sp, *bpfile=0, *dark_frame=0, *write_ext; + char opm, opt, *ofname, *cp; + struct utimbuf ut; +#ifndef NO_LCMS + const char *cam_profile=0, *out_profile=0; +#endif + +#ifndef LOCALTIME + putenv ((char *) "TZ=UTC"); +#endif +#ifdef LOCALEDIR + setlocale (LC_CTYPE, ""); + setlocale (LC_MESSAGES, ""); + bindtextdomain ("dcraw", LOCALEDIR); + textdomain ("dcraw"); +#endif + + if (argc == 1) { + printf(_("\nRaw photo decoder \"dcraw\" v%s"), DCRAW_VERSION); + printf(_("\nby Dave Coffin, dcoffin a cybercom o net\n")); + printf(_("\nUsage: %s [OPTION]... [FILE]...\n\n"), argv[0]); + puts(_("-v Print verbose messages")); + puts(_("-c Write image data to standard output")); + puts(_("-e Extract embedded thumbnail image")); + puts(_("-i Identify files without decoding them")); + puts(_("-i -v Identify files and show metadata")); + puts(_("-z Change file dates to camera timestamp")); + puts(_("-w Use camera white balance, if possible")); + puts(_("-a Average the whole image for white balance")); + puts(_("-A Average a grey box for white balance")); + puts(_("-r Set custom white balance")); + puts(_("+M/-M Use/don't use an embedded color matrix")); + puts(_("-C Correct chromatic aberration")); + puts(_("-P Fix the dead pixels listed in this file")); + puts(_("-K Subtract dark frame (16-bit raw PGM)")); + puts(_("-k Set the darkness level")); + puts(_("-S Set the saturation level")); + puts(_("-n Set threshold for wavelet denoising")); + puts(_("-H [0-9] Highlight mode (0=clip, 1=unclip, 2=blend, 3+=rebuild)")); + puts(_("-t [0-7] Flip image (0=none, 3=180, 5=90CCW, 6=90CW)")); + puts(_("-o [0-5] Output colorspace (raw,sRGB,Adobe,Wide,ProPhoto,XYZ)")); +#ifndef NO_LCMS + puts(_("-o Apply output ICC profile from file")); + puts(_("-p Apply camera ICC profile from file or \"embed\"")); +#endif + puts(_("-d Document mode (no color, no interpolation)")); + puts(_("-D Document mode without scaling (totally raw)")); + puts(_("-j Don't stretch or rotate raw pixels")); + puts(_("-W Don't automatically brighten the image")); + puts(_("-b Adjust brightness (default = 1.0)")); + puts(_("-g

Set custom gamma curve (default = 2.222 4.5)")); + puts(_("-q [0-3] Set the interpolation quality")); + puts(_("-h Half-size color image (twice as fast as \"-q 0\")")); + puts(_("-f Interpolate RGGB as four colors")); + puts(_("-m Apply a 3x3 median filter to R-G and B-G")); + puts(_("-s [0..N-1] Select one raw image or \"all\" from each file")); + puts(_("-6 Write 16-bit instead of 8-bit")); + puts(_("-4 Linear 16-bit, same as \"-6 -W -g 1 1\"")); + puts(_("-T Write TIFF instead of PPM")); + puts(""); + return 1; + } + argv[argc] = ""; + for (arg=1; (((opm = argv[arg][0]) - 2) | 2) == '+'; ) { + opt = argv[arg++][1]; + if ((cp = (char *) strchr (sp="nbrkStqmHACg", opt))) + for (i=0; i < "114111111422"[cp-sp]-'0'; i++) + if (!isdigit(argv[arg+i][0])) { + fprintf (stderr,_("Non-numeric argument to \"-%c\"\n"), opt); + return 1; + } + switch (opt) { + case 'n': threshold = atof(argv[arg++]); break; + case 'b': bright = atof(argv[arg++]); break; + case 'r': + FORC4 user_mul[c] = atof(argv[arg++]); break; + case 'C': aber[0] = 1 / atof(argv[arg++]); + aber[2] = 1 / atof(argv[arg++]); break; + case 'g': gamm[0] = atof(argv[arg++]); + gamm[1] = atof(argv[arg++]); + if (gamm[0]) gamm[0] = 1/gamm[0]; break; + case 'k': user_black = atoi(argv[arg++]); break; + case 'S': user_sat = atoi(argv[arg++]); break; + case 't': user_flip = atoi(argv[arg++]); break; + case 'q': user_qual = atoi(argv[arg++]); break; + case 'm': med_passes = atoi(argv[arg++]); break; + case 'H': highlight = atoi(argv[arg++]); break; + case 's': + shot_select = abs(atoi(argv[arg])); + multi_out = !strcmp(argv[arg++],"all"); + break; + case 'o': + if (isdigit(argv[arg][0]) && !argv[arg][1]) + output_color = atoi(argv[arg++]); +#ifndef NO_LCMS + else out_profile = argv[arg++]; + break; + case 'p': cam_profile = argv[arg++]; +#endif + break; + case 'P': bpfile = argv[arg++]; break; + case 'K': dark_frame = argv[arg++]; break; + case 'z': timestamp_only = 1; break; + case 'e': thumbnail_only = 1; break; + case 'i': identify_only = 1; break; + case 'c': write_to_stdout = 1; break; + case 'v': verbose = 1; break; + case 'h': half_size = 1; break; + case 'f': four_color_rgb = 1; break; + case 'A': FORC4 greybox[c] = atoi(argv[arg++]); + case 'a': use_auto_wb = 1; break; + case 'w': use_camera_wb = 1; break; + case 'M': use_camera_matrix = 3 * (opm == '+'); break; + case 'I': read_from_stdin = 1; break; + case 'E': document_mode++; + case 'D': document_mode++; + case 'd': document_mode++; + case 'j': use_fuji_rotate = 0; break; + case 'W': no_auto_bright = 1; break; + case 'T': output_tiff = 1; break; + case '4': gamm[0] = gamm[1] = + no_auto_bright = 1; + case '6': output_bps = 16; break; + default: + fprintf (stderr,_("Unknown option \"-%c\".\n"), opt); + return 1; + } + } + if (arg == argc) { + fprintf (stderr,_("No files to process.\n")); + return 1; + } + if (write_to_stdout) { + if (isatty(1)) { + fprintf (stderr,_("Will not write an image to the terminal!\n")); + return 1; + } +#if defined(WIN32) || defined(DJGPP) || defined(__CYGWIN__) + if (setmode(1,O_BINARY) < 0) { + perror ("setmode()"); + return 1; + } +#endif + } + for ( ; arg < argc; arg++) { + status = 1; + raw_image = 0; + image = 0; + oprof = 0; + meta_data = ofname = 0; + ofp = stdout; + if (setjmp (failure)) { + if (fileno(ifp) > 2) fclose(ifp); + if (fileno(ofp) > 2) fclose(ofp); + status = 1; + goto cleanup; + } + ifname = argv[arg]; + if (!(ifp = fopen (ifname, "rb"))) { + perror (ifname); + continue; + } + status = (identify(),!is_raw); + if (user_flip >= 0) + flip = user_flip; + switch ((flip+3600) % 360) { + case 270: flip = 5; break; + case 180: flip = 3; break; + case 90: flip = 6; + } + if (timestamp_only) { + if ((status = !timestamp)) + fprintf (stderr,_("%s has no timestamp.\n"), ifname); + else if (identify_only) + printf ("%10ld%10d %s\n", (long) timestamp, shot_order, ifname); + else { + if (verbose) + fprintf (stderr,_("%s time set to %d.\n"), ifname, (int) timestamp); + ut.actime = ut.modtime = timestamp; + utime (ifname, &ut); + } + goto next; + } + write_fun = &CLASS write_ppm_tiff; + if (thumbnail_only) { + if ((status = !thumb_offset)) { + fprintf (stderr,_("%s has no thumbnail.\n"), ifname); + goto next; + } else if (thumb_load_raw) { + load_raw = thumb_load_raw; + data_offset = thumb_offset; + height = thumb_height; + width = thumb_width; + filters = 0; + colors = 3; + } else { + fseek (ifp, thumb_offset, SEEK_SET); + write_fun = write_thumb; + goto thumbnail; + } + } + if (load_raw == &CLASS kodak_ycbcr_load_raw) { + height += height & 1; + width += width & 1; + } + if (identify_only && verbose && make[0]) { + printf (_("\nFilename: %s\n"), ifname); + printf (_("Timestamp: %s"), ctime(×tamp)); + printf (_("Camera: %s %s\n"), make, model); + if (artist[0]) + printf (_("Owner: %s\n"), artist); + if (dng_version) { + printf (_("DNG Version: ")); + for (i=24; i >= 0; i -= 8) + printf ("%d%c", dng_version >> i & 255, i ? '.':'\n'); + } + printf (_("ISO speed: %d\n"), (int) iso_speed); + printf (_("Shutter: ")); + if (shutter > 0 && shutter < 1) + shutter = (printf ("1/"), 1 / shutter); + printf (_("%0.1f sec\n"), shutter); + printf (_("Aperture: f/%0.1f\n"), aperture); + printf (_("Focal length: %0.1f mm\n"), focal_len); + printf (_("Embedded ICC profile: %s\n"), profile_length ? _("yes"):_("no")); + printf (_("Number of raw images: %d\n"), is_raw); + if (pixel_aspect != 1) + printf (_("Pixel Aspect Ratio: %0.6f\n"), pixel_aspect); + if (thumb_offset) + printf (_("Thumb size: %4d x %d\n"), thumb_width, thumb_height); + printf (_("Full size: %4d x %d\n"), raw_width, raw_height); + } else if (!is_raw) + fprintf (stderr,_("Cannot decode file %s\n"), ifname); + if (!is_raw) goto next; + shrink = filters && (half_size || (!identify_only && + (threshold || aber[0] != 1 || aber[2] != 1))); + iheight = (height + shrink) >> shrink; + iwidth = (width + shrink) >> shrink; + if (identify_only) { + if (verbose) { + if (document_mode == 3) { + top_margin = left_margin = fuji_width = 0; + height = raw_height; + width = raw_width; + } + iheight = (height + shrink) >> shrink; + iwidth = (width + shrink) >> shrink; + if (use_fuji_rotate) { + if (fuji_width) { + fuji_width = (fuji_width - 1 + shrink) >> shrink; + iwidth = fuji_width / sqrt(0.5); + iheight = (iheight - fuji_width) / sqrt(0.5); + } else { + if (pixel_aspect < 1) iheight = iheight / pixel_aspect + 0.5; + if (pixel_aspect > 1) iwidth = iwidth * pixel_aspect + 0.5; + } + } + if (flip & 4) + SWAP(iheight,iwidth); + printf (_("Image size: %4d x %d\n"), width, height); + printf (_("Output size: %4d x %d\n"), iwidth, iheight); + printf (_("Raw colors: %d"), colors); + if (filters) { + int fhigh = 2, fwide = 2; + if ((filters ^ (filters >> 8)) & 0xff) fhigh = 4; + if ((filters ^ (filters >> 16)) & 0xffff) fhigh = 8; + if (filters == 1) fhigh = fwide = 16; + if (filters == 9) fhigh = fwide = 6; + printf (_("\nFilter pattern: ")); + for (i=0; i < fhigh; i++) + for (c = i && putchar('/') && 0; c < fwide; c++) + putchar (cdesc[fcol(i,c)]); + } + printf (_("\nDaylight multipliers:")); + FORCC printf (" %f", pre_mul[c]); + if (cam_mul[0] > 0) { + printf (_("\nCamera multipliers:")); + FORC4 printf (" %f", cam_mul[c]); + } + putchar ('\n'); + } else + printf (_("%s is a %s %s image.\n"), ifname, make, model); +next: + fclose(ifp); + continue; + } + if (meta_length) { + meta_data = (char *) malloc (meta_length); + merror (meta_data, "main()"); + } + if (filters || colors == 1) { + raw_image = (ushort *) calloc ((raw_height+7), raw_width*2); + merror (raw_image, "main()"); + } else { + image = (ushort (*)[4]) calloc (iheight, iwidth*sizeof *image); + merror (image, "main()"); + } + if (verbose) + fprintf (stderr,_("Loading %s %s image from %s ...\n"), + make, model, ifname); + if (shot_select >= is_raw) + fprintf (stderr,_("%s: \"-s %d\" requests a nonexistent image!\n"), + ifname, shot_select); + fseeko (ifp, data_offset, SEEK_SET); + if (raw_image && read_from_stdin) + fread (raw_image, 2, raw_height*raw_width, stdin); + else (*load_raw)(); + if (document_mode == 3) { + top_margin = left_margin = fuji_width = 0; + height = raw_height; + width = raw_width; + } + iheight = (height + shrink) >> shrink; + iwidth = (width + shrink) >> shrink; + if (raw_image) { + image = (ushort (*)[4]) calloc (iheight, iwidth*sizeof *image); + merror (image, "main()"); + crop_masked_pixels(); + free (raw_image); + } + if (zero_is_bad) remove_zeroes(); + bad_pixels (bpfile); + if (dark_frame) subtract (dark_frame); + quality = 2 + !fuji_width; + if (user_qual >= 0) quality = user_qual; + i = cblack[3]; + FORC3 if (i > cblack[c]) i = cblack[c]; + FORC4 cblack[c] -= i; + black += i; + i = cblack[6]; + FORC (cblack[4] * cblack[5]) + if (i > cblack[6+c]) i = cblack[6+c]; + FORC (cblack[4] * cblack[5]) + cblack[6+c] -= i; + black += i; + if (user_black >= 0) black = user_black; + FORC4 cblack[c] += black; + if (user_sat > 0) maximum = user_sat; +#ifdef COLORCHECK + colorcheck(); +#endif + if (is_foveon) { + if (document_mode || load_raw == &CLASS foveon_dp_load_raw) { + for (i=0; i < height*width*4; i++) + if ((short) image[0][i] < 0) image[0][i] = 0; + } else foveon_interpolate(); + } else if (document_mode < 2) + scale_colors(); + pre_interpolate(); + if (filters && !document_mode) { + if (quality == 0) + lin_interpolate(); + else if (quality == 1 || colors > 3) + vng_interpolate(); + else if (quality == 2 && filters > 1000) + ppg_interpolate(); + else if (filters == 9) + xtrans_interpolate (quality*2-3); + else + ahd_interpolate(); + } + if (mix_green) + for (colors=3, i=0; i < height*width; i++) + image[i][1] = (image[i][1] + image[i][3]) >> 1; + if (!is_foveon && colors == 3) median_filter(); + if (!is_foveon && highlight == 2) blend_highlights(); + if (!is_foveon && highlight > 2) recover_highlights(); + if (use_fuji_rotate) fuji_rotate(); +#ifndef NO_LCMS + if (cam_profile) apply_profile (cam_profile, out_profile); +#endif + convert_to_rgb(); + if (use_fuji_rotate) stretch(); +thumbnail: + if (write_fun == &CLASS jpeg_thumb) + write_ext = ".jpg"; + else if (output_tiff && write_fun == &CLASS write_ppm_tiff) + write_ext = ".tiff"; + else + write_ext = ".pgm\0.ppm\0.ppm\0.pam" + colors*5-5; + ofname = (char *) malloc (strlen(ifname) + 64); + merror (ofname, "main()"); + if (write_to_stdout) + strcpy (ofname,_("standard output")); + else { + strcpy (ofname, ifname); + if ((cp = strrchr (ofname, '.'))) *cp = 0; + if (multi_out) + sprintf (ofname+strlen(ofname), "_%0*d", + snprintf(0,0,"%d",is_raw-1), shot_select); + if (thumbnail_only) + strcat (ofname, ".thumb"); + strcat (ofname, write_ext); + ofp = fopen (ofname, "wb"); + if (!ofp) { + status = 1; + perror (ofname); + goto cleanup; + } + } + if (verbose) + fprintf (stderr,_("Writing data to %s ...\n"), ofname); + (*write_fun)(); + fclose(ifp); + if (ofp != stdout) fclose(ofp); +cleanup: + if (meta_data) free (meta_data); + if (ofname) free (ofname); + if (oprof) free (oprof); + if (image) free (image); + if (multi_out) { + if (++shot_select < is_raw) arg--; + else shot_select = 0; + } + } + return status; +} diff --git a/rtengine/dcraw.cc b/rtengine/dcraw.cc new file mode 100644 index 000000000..785e43377 --- /dev/null +++ b/rtengine/dcraw.cc @@ -0,0 +1,9614 @@ +/*RT*/#include +/*RT*/#include +/*RT*/#undef MAX +/*RT*/#undef MIN +/*RT*/#undef ABS +/*RT*/#include "rt_math.h" +/*RT*/#define NO_LCMS +/*RT*/#define NO_JPEG +/*RT*/#define NO_JASPER +/*RT*/#define LOCALTIME +/*RT*/#define DJGPP + +/* + dcraw.c -- Dave Coffin's raw photo decoder + Copyright 1997-2015 by Dave Coffin, dcoffin a cybercom o net + + This is a command-line ANSI C program to convert raw photos from + any digital camera on any computer running any operating system. + + No license is required to download and use dcraw.c. However, + to lawfully redistribute dcraw, you must either (a) offer, at + no extra charge, full source code* for all executable files + containing RESTRICTED functions, (b) distribute this code under + the GPL Version 2 or later, (c) remove all RESTRICTED functions, + re-implement them, or copy them from an earlier, unrestricted + Revision of dcraw.c, or (d) purchase a license from the author. + + The functions that process Foveon images have been RESTRICTED + since Revision 1.237. All other code remains free for all uses. + + *If you have not modified dcraw.c in any way, a link to my + homepage qualifies as "full source code". + + $Revision: 1.475 $ + $Date: 2015/04/11 00:08:36 $ + */ + +#define DCRAW_VERSION "9.25" + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#define _USE_MATH_DEFINES +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(DJGPP) || defined(__MINGW32__) +#define fseeko fseek +#define ftello ftell +#else +#define fgetc getc_unlocked +#endif +#ifdef __CYGWIN__ +#include +#endif +#ifdef WIN32 +#include +#include +#define snprintf _snprintf +#define strcasecmp stricmp +#define strncasecmp strnicmp +typedef __int64 INT64; +typedef unsigned __int64 UINT64; +#else +#include +#include +#include +typedef long long INT64; +typedef unsigned long long UINT64; +#endif + +#ifdef NODEPS +#define NO_JASPER +#define NO_JPEG +#define NO_LCMS +#endif +#ifndef NO_JASPER +#include /* Decode Red camera movies */ +#endif +#ifndef NO_JPEG +#include /* Decode compressed Kodak DC120 photos */ +#endif /* and Adobe Lossy DNGs */ +#ifndef NO_LCMS +#include /* Support color profiles */ +#endif +#ifdef LOCALEDIR +#include +#define _(String) gettext(String) +#else +#define _(String) (String) +#endif + +#ifdef LJPEG_DECODE +#error Please compile dcraw.c by itself. +#error Do not link it with ljpeg_decode. +#endif + +#ifndef LONG_BIT +#define LONG_BIT (8 * sizeof (long)) +#endif + +#define ushort UshORt +typedef unsigned char uchar; +typedef unsigned short ushort; + +#include "dcraw.h" +/* + RT All global variables are defined here, and all functions that + access them are prefixed with "CLASS". Note that a thread-safe + C++ class cannot have non-const static local variables. + */ + +const double xyz_rgb[3][3] = { // XYZ from RGB + { 0.412453, 0.357580, 0.180423 }, + { 0.212671, 0.715160, 0.072169 }, + { 0.019334, 0.119193, 0.950227 } }; +const float d65_white[3] = { 0.950456, 1, 1.088754 }; + +/* RT: Removed unused structs */ +#define CLASS DCraw:: + +#define FORC(cnt) for (c=0; c < cnt; c++) +#define FORC3 FORC(3) +#define FORC4 FORC(4) +#define FORCC FORC(colors) + +#define SQR(x) rtengine::SQR(x) +#define ABS(x) (((int)(x) ^ ((int)(x) >> 31)) - ((int)(x) >> 31)) +#define MIN(a,b) rtengine::min(a,static_cast(b)) +#define MAX(a,b) rtengine::max(a,static_cast(b)) +#define LIM(x,min,max) rtengine::LIM(x,static_cast(min),static_cast(max)) +#define ULIM(x,y,z) rtengine::ULIM(x,static_cast(y),static_cast(z)) +#define CLIP(x) rtengine::CLIP(x) +#define SWAP(a,b) { a=a+b; b=a-b; a=a-b; } + +/* + In order to inline this calculation, I make the risky + assumption that all filter patterns can be described + by a repeating pattern of eight rows and two columns + + Do not use the FC or BAYER macros with the Leaf CatchLight, + because its pattern is 16x16, not 2x8. + + Return values are either 0/1/2/3 = G/M/C/Y or 0/1/2/3 = R/G1/B/G2 + + PowerShot 600 PowerShot A50 PowerShot Pro70 Pro90 & G1 + 0xe1e4e1e4: 0x1b4e4b1e: 0x1e4b4e1b: 0xb4b4b4b4: + + 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 + 0 G M G M G M 0 C Y C Y C Y 0 Y C Y C Y C 0 G M G M G M + 1 C Y C Y C Y 1 M G M G M G 1 M G M G M G 1 Y C Y C Y C + 2 M G M G M G 2 Y C Y C Y C 2 C Y C Y C Y + 3 C Y C Y C Y 3 G M G M G M 3 G M G M G M + 4 C Y C Y C Y 4 Y C Y C Y C + PowerShot A5 5 G M G M G M 5 G M G M G M + 0x1e4e1e4e: 6 Y C Y C Y C 6 C Y C Y C Y + 7 M G M G M G 7 M G M G M G + 0 1 2 3 4 5 + 0 C Y C Y C Y + 1 G M G M G M + 2 C Y C Y C Y + 3 M G M G M G + + All RGB cameras use one of these Bayer grids: + + 0x16161616: 0x61616161: 0x49494949: 0x94949494: + + 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 + 0 B G B G B G 0 G R G R G R 0 G B G B G B 0 R G R G R G + 1 G R G R G R 1 B G B G B G 1 R G R G R G 1 G B G B G B + 2 B G B G B G 2 G R G R G R 2 G B G B G B 2 R G R G R G + 3 G R G R G R 3 B G B G B G 3 R G R G R G 3 G B G B G B + */ + +#define RAW(row,col) \ + raw_image[(row)*raw_width+(col)] + +#define FC(row,col) \ + (filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3) + +#define BAYER(row,col) \ + image[((row) >> shrink)*iwidth + ((col) >> shrink)][FC(row,col)] + +#define BAYER2(row,col) \ + image[((row) >> shrink)*iwidth + ((col) >> shrink)][fcol(row,col)] + +int CLASS fcol (int row, int col) +{ + static const char filter[16][16] = + { { 2,1,1,3,2,3,2,0,3,2,3,0,1,2,1,0 }, + { 0,3,0,2,0,1,3,1,0,1,1,2,0,3,3,2 }, + { 2,3,3,2,3,1,1,3,3,1,2,1,2,0,0,3 }, + { 0,1,0,1,0,2,0,2,2,0,3,0,1,3,2,1 }, + { 3,1,1,2,0,1,0,2,1,3,1,3,0,1,3,0 }, + { 2,0,0,3,3,2,3,1,2,0,2,0,3,2,2,1 }, + { 2,3,3,1,2,1,2,1,2,1,1,2,3,0,0,1 }, + { 1,0,0,2,3,0,0,3,0,3,0,3,2,1,2,3 }, + { 2,3,3,1,1,2,1,0,3,2,3,0,2,3,1,3 }, + { 1,0,2,0,3,0,3,2,0,1,1,2,0,1,0,2 }, + { 0,1,1,3,3,2,2,1,1,3,3,0,2,1,3,2 }, + { 2,3,2,0,0,1,3,0,2,0,1,2,3,0,1,0 }, + { 1,3,1,2,3,2,3,2,0,2,0,1,1,0,3,0 }, + { 0,2,0,3,1,0,0,1,1,3,3,2,3,2,2,1 }, + { 2,1,3,2,3,1,2,1,0,3,0,2,0,2,0,2 }, + { 0,3,1,0,0,2,0,3,2,1,3,1,1,3,1,3 } }; + + if (filters == 1) return filter[(row+top_margin)&15][(col+left_margin)&15]; + if (filters == 9) return xtrans[(row+6) % 6][(col+6) % 6]; + + return FC(row,col); +} + +#ifndef __GLIBC__ +char *my_memmem (char *haystack, size_t haystacklen, + char *needle, size_t needlelen) +{ + char *c; + for (c = haystack; c <= haystack + haystacklen - needlelen; c++) + if (!memcmp (c, needle, needlelen)) + return c; + return 0; +} +#define memmem my_memmem +char *my_strcasestr (char *haystack, const char *needle) +{ + char *c; + for (c = haystack; *c; c++) + if (!strncasecmp(c, needle, strlen(needle))) + return c; + return 0; +} +#define strcasestr my_strcasestr +#endif + +void CLASS merror (void *ptr, const char *where) +{ + if (ptr) return; + fprintf (stderr,_("%s: Out of memory in %s\n"), ifname, where); + longjmp (failure, 1); +} + +void CLASS derror() +{ + if (!data_error) { + fprintf (stderr, "%s: ", ifname); + if (feof(ifp)) + fprintf (stderr,_("Unexpected end of file\n")); + else + fprintf (stderr,_("Corrupt data near 0x%llx\n"), (INT64) ftello(ifp)); + } + data_error++; +/*RT Issue 2467 longjmp (failure, 1);*/ +} + +ushort CLASS sget2 (uchar *s) +{ + if (order == 0x4949) /* "II" means little-endian */ + return s[0] | s[1] << 8; + else /* "MM" means big-endian */ + return s[0] << 8 | s[1]; +} + +ushort CLASS get2() +{ + uchar str[2] = { 0xff,0xff }; + fread (str, 1, 2, ifp); + return sget2(str); +} + +unsigned CLASS sget4 (uchar *s) +{ + if (order == 0x4949) + return s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24; + else + return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]; +} +#define sget4(s) sget4((uchar *)s) + +unsigned CLASS get4() +{ + uchar str[4] = { 0xff,0xff,0xff,0xff }; + fread (str, 1, 4, ifp); + return sget4(str); +} + +unsigned CLASS getint (int type) +{ + return type == 3 ? get2() : get4(); +} + +float CLASS int_to_float (int i) +{ + union { int i; float f; } u; + u.i = i; + return u.f; +} + +double CLASS getreal (int type) +{ + union { char c[8]; double d; } u; + int i, rev; + + switch (type) { + case 3: return (unsigned short) get2(); + case 4: return (unsigned int) get4(); + case 5: u.d = (unsigned int) get4(); + return u.d / (unsigned int) get4(); + case 8: return (signed short) get2(); + case 9: return (signed int) get4(); + case 10: u.d = (signed int) get4(); + return u.d / (signed int) get4(); + case 11: return int_to_float (get4()); + case 12: + rev = 7 * ((order == 0x4949) == (ntohs(0x1234) == 0x1234)); + for (i=0; i < 8; i++) + u.c[i ^ rev] = fgetc(ifp); + return u.d; + default: return fgetc(ifp); + } +} + +void CLASS read_shorts (ushort *pixel, int count) +{ + if (fread (pixel, 2, count, ifp) < count) derror(); + if ((order == 0x4949) == (ntohs(0x1234) == 0x1234)) + swab ((char*)pixel, (char*)pixel, count*2); +} + +void CLASS cubic_spline (const int *x_, const int *y_, const int len) +{ + float **A, *b, *c, *d, *x, *y; + int i, j; + + A = (float **) calloc (((2*len + 4)*sizeof **A + sizeof *A), 2*len); + if (!A) return; + A[0] = (float *) (A + 2*len); + for (i = 1; i < 2*len; i++) + A[i] = A[0] + 2*len*i; + y = len + (x = i + (d = i + (c = i + (b = A[0] + i*i)))); + for (i = 0; i < len; i++) { + x[i] = x_[i] / 65535.0; + y[i] = y_[i] / 65535.0; + } + for (i = len-1; i > 0; i--) { + b[i] = (y[i] - y[i-1]) / (x[i] - x[i-1]); + d[i-1] = x[i] - x[i-1]; + } + for (i = 1; i < len-1; i++) { + A[i][i] = 2 * (d[i-1] + d[i]); + if (i > 1) { + A[i][i-1] = d[i-1]; + A[i-1][i] = d[i-1]; + } + A[i][len-1] = 6 * (b[i+1] - b[i]); + } + for(i = 1; i < len-2; i++) { + float v = A[i+1][i] / A[i][i]; + for(j = 1; j <= len-1; j++) + A[i+1][j] -= v * A[i][j]; + } + for(i = len-2; i > 0; i--) { + float acc = 0; + for(j = i; j <= len-2; j++) + acc += A[i][j]*c[j]; + c[i] = (A[i][len-1] - acc) / A[i][i]; + } + for (i = 0; i < 0x10000; i++) { + float x_out = (float)(i / 65535.0); + float y_out = 0; + for (j = 0; j < len-1; j++) { + if (x[j] <= x_out && x_out <= x[j+1]) { + float v = x_out - x[j]; + y_out = y[j] + + ((y[j+1] - y[j]) / d[j] - (2 * d[j] * c[j] + c[j+1] * d[j])/6) * v + + (c[j] * 0.5) * v*v + ((c[j+1] - c[j]) / (6 * d[j])) * v*v*v; + } + } + curve[i] = y_out < 0.0 ? 0 : (y_out >= 1.0 ? 65535 : + (ushort)(y_out * 65535.0 + 0.5)); + } + free (A); +} + +void CLASS canon_600_fixed_wb (int temp) +{ + static const short mul[4][5] = { + { 667, 358,397,565,452 }, + { 731, 390,367,499,517 }, + { 1119, 396,348,448,537 }, + { 1399, 485,431,508,688 } }; + int lo, hi, i; + float frac=0; + + for (lo=4; --lo; ) + if (*mul[lo] <= temp) break; + for (hi=0; hi < 3; hi++) + if (*mul[hi] >= temp) break; + if (lo != hi) + frac = (float) (temp - *mul[lo]) / (*mul[hi] - *mul[lo]); + for (i=1; i < 5; i++) + pre_mul[i-1] = 1 / (frac * mul[hi][i] + (1-frac) * mul[lo][i]); +} + +/* Return values: 0 = white 1 = near white 2 = not white */ +int CLASS canon_600_color (int ratio[2], int mar) +{ + int clipped=0, target, miss; + + if (flash_used) { + if (ratio[1] < -104) + { ratio[1] = -104; clipped = 1; } + if (ratio[1] > 12) + { ratio[1] = 12; clipped = 1; } + } else { + if (ratio[1] < -264 || ratio[1] > 461) return 2; + if (ratio[1] < -50) + { ratio[1] = -50; clipped = 1; } + if (ratio[1] > 307) + { ratio[1] = 307; clipped = 1; } + } + target = flash_used || ratio[1] < 197 + ? -38 - (398 * ratio[1] >> 10) + : -123 + (48 * ratio[1] >> 10); + if (target - mar <= ratio[0] && + target + 20 >= ratio[0] && !clipped) return 0; + miss = target - ratio[0]; + if (abs(miss) >= mar*4) return 2; + if (miss < -20) miss = -20; + if (miss > mar) miss = mar; + ratio[0] = target - miss; + return 1; +} + +void CLASS canon_600_auto_wb() +{ + int mar, row, col, i, j, st, count[] = { 0,0 }; + int test[8], total[2][8], ratio[2][2], stat[2]; + + memset (&total, 0, sizeof total); + i = canon_ev + 0.5; + if (i < 10) mar = 150; + else if (i > 12) mar = 20; + else mar = 280 - 20 * i; + if (flash_used) mar = 80; + for (row=14; row < height-14; row+=4) + for (col=10; col < width; col+=2) { + for (i=0; i < 8; i++) + test[(i & 4) + FC(row+(i >> 1),col+(i & 1))] = + BAYER(row+(i >> 1),col+(i & 1)); + for (i=0; i < 8; i++) + if (test[i] < 150 || test[i] > 1500) goto next; + for (i=0; i < 4; i++) + if (abs(test[i] - test[i+4]) > 50) goto next; + for (i=0; i < 2; i++) { + for (j=0; j < 4; j+=2) + ratio[i][j >> 1] = ((test[i*4+j+1]-test[i*4+j]) << 10) / test[i*4+j]; + stat[i] = canon_600_color (ratio[i], mar); + } + if ((st = stat[0] | stat[1]) > 1) goto next; + for (i=0; i < 2; i++) + if (stat[i]) + for (j=0; j < 2; j++) + test[i*4+j*2+1] = test[i*4+j*2] * (0x400 + ratio[i][j]) >> 10; + for (i=0; i < 8; i++) + total[st][i] += test[i]; + count[st]++; +next: ; + } + if (count[0] | count[1]) { + st = count[0]*200 < count[1]; + for (i=0; i < 4; i++) + pre_mul[i] = 1.0 / (total[st][i] + total[st][i+4]); + } +} + +void CLASS canon_600_coeff() +{ + static const short table[6][12] = { + { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 }, + { -1203,1715,-1136,1648, 1388,-876,267,245, -1641,2153,3921,-3409 }, + { -615,1127,-1563,2075, 1437,-925,509,3, -756,1268,2519,-2007 }, + { -190,702,-1886,2398, 2153,-1641,763,-251, -452,964,3040,-2528 }, + { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 }, + { -807,1319,-1785,2297, 1388,-876,769,-257, -230,742,2067,-1555 } }; + int t=0, i, c; + float mc, yc; + + mc = pre_mul[1] / pre_mul[2]; + yc = pre_mul[3] / pre_mul[2]; + if (mc > 1 && mc <= 1.28 && yc < 0.8789) t=1; + if (mc > 1.28 && mc <= 2) { + if (yc < 0.8789) t=3; + else if (yc <= 2) t=4; + } + if (flash_used) t=5; + for (raw_color = i=0; i < 3; i++) + FORCC rgb_cam[i][c] = table[t][i*4 + c] / 1024.0; +} + +void CLASS canon_600_load_raw() +{ + uchar data[1120], *dp; + ushort *pix; + int irow, row; + + for (irow=row=0; irow < height; irow++) { + if (fread (data, 1, 1120, ifp) < 1120) derror(); + pix = raw_image + row*raw_width; + for (dp=data; dp < data+1120; dp+=10, pix+=8) { + pix[0] = (dp[0] << 2) + (dp[1] >> 6 ); + pix[1] = (dp[2] << 2) + (dp[1] >> 4 & 3); + pix[2] = (dp[3] << 2) + (dp[1] >> 2 & 3); + pix[3] = (dp[4] << 2) + (dp[1] & 3); + pix[4] = (dp[5] << 2) + (dp[9] & 3); + pix[5] = (dp[6] << 2) + (dp[9] >> 2 & 3); + pix[6] = (dp[7] << 2) + (dp[9] >> 4 & 3); + pix[7] = (dp[8] << 2) + (dp[9] >> 6 ); + } + if ((row+=2) > height) row = 1; + } +} + +void CLASS canon_600_correct() +{ + int row, col, val; + static const short mul[4][2] = + { { 1141,1145 }, { 1128,1109 }, { 1178,1149 }, { 1128,1109 } }; + + for (row=0; row < height; row++) + for (col=0; col < width; col++) { + if ((val = BAYER(row,col) - black) < 0) val = 0; + val = val * mul[row & 3][col & 1] >> 9; + BAYER(row,col) = val; + } + canon_600_fixed_wb(1311); + canon_600_auto_wb(); + canon_600_coeff(); + maximum = (0x3ff - black) * 1109 >> 9; + black = 0; +} + +int CLASS canon_s2is() +{ + unsigned row; + + for (row=0; row < 100; row++) { + fseek (ifp, row*3340 + 3284, SEEK_SET); + if (getc(ifp) > 15) return 1; + } + return 0; +} + +unsigned CLASS getbithuff_t::operator() (int nbits, ushort *huff) +{ +/*RT static unsigned bitbuf=0; */ +/*RT static int vbits=0, reset=0; */ + unsigned c; + + if (nbits > 25) return 0; + if (nbits < 0) + return bitbuf = vbits = reset = 0; + if (nbits == 0 || vbits < 0) return 0; + while (!reset && vbits < nbits && (c = fgetc(ifp)) != EOF && + !(reset = zero_after_ff && c == 0xff && fgetc(ifp))) { + bitbuf = (bitbuf << 8) + (uchar) c; + vbits += 8; + } + c = bitbuf << (32-vbits) >> (32-nbits); + if (huff) { + vbits -= huff[c] >> 8; + c = (uchar) huff[c]; + } else + vbits -= nbits; + if (vbits < 0) derror(); + return c; +} + +#define getbits(n) getbithuff(n,0) +#define gethuff(h) getbithuff(*h,h+1) + +/* + Construct a decode tree according the specification in *source. + The first 16 bytes specify how many codes should be 1-bit, 2-bit + 3-bit, etc. Bytes after that are the leaf values. + + For example, if the source is + + { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0, + 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff }, + + then the code is + + 00 0x04 + 010 0x03 + 011 0x05 + 100 0x06 + 101 0x02 + 1100 0x07 + 1101 0x01 + 11100 0x08 + 11101 0x09 + 11110 0x00 + 111110 0x0a + 1111110 0x0b + 1111111 0xff + */ +ushort * CLASS make_decoder_ref (const uchar **source) +{ + int max, len, h, i, j; + const uchar *count; + ushort *huff; + + count = (*source += 16) - 17; + for (max=16; max && !count[max]; max--); + huff = (ushort *) calloc (1 + (1 << max), sizeof *huff); + merror (huff, "make_decoder()"); + huff[0] = max; + for (h=len=1; len <= max; len++) + for (i=0; i < count[len]; i++, ++*source) + for (j=0; j < 1 << (max-len); j++) + if (h <= 1 << max) + huff[h++] = len << 8 | **source; + return huff; +} + +ushort * CLASS make_decoder (const uchar *source) +{ + return make_decoder_ref (&source); +} + +void CLASS crw_init_tables (unsigned table, ushort *huff[2]) +{ + static const uchar first_tree[3][29] = { + { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0, + 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff }, + { 0,2,2,3,1,1,1,1,2,0,0,0,0,0,0,0, + 0x03,0x02,0x04,0x01,0x05,0x00,0x06,0x07,0x09,0x08,0x0a,0x0b,0xff }, + { 0,0,6,3,1,1,2,0,0,0,0,0,0,0,0,0, + 0x06,0x05,0x07,0x04,0x08,0x03,0x09,0x02,0x00,0x0a,0x01,0x0b,0xff }, + }; + static const uchar second_tree[3][180] = { + { 0,2,2,2,1,4,2,1,2,5,1,1,0,0,0,139, + 0x03,0x04,0x02,0x05,0x01,0x06,0x07,0x08, + 0x12,0x13,0x11,0x14,0x09,0x15,0x22,0x00,0x21,0x16,0x0a,0xf0, + 0x23,0x17,0x24,0x31,0x32,0x18,0x19,0x33,0x25,0x41,0x34,0x42, + 0x35,0x51,0x36,0x37,0x38,0x29,0x79,0x26,0x1a,0x39,0x56,0x57, + 0x28,0x27,0x52,0x55,0x58,0x43,0x76,0x59,0x77,0x54,0x61,0xf9, + 0x71,0x78,0x75,0x96,0x97,0x49,0xb7,0x53,0xd7,0x74,0xb6,0x98, + 0x47,0x48,0x95,0x69,0x99,0x91,0xfa,0xb8,0x68,0xb5,0xb9,0xd6, + 0xf7,0xd8,0x67,0x46,0x45,0x94,0x89,0xf8,0x81,0xd5,0xf6,0xb4, + 0x88,0xb1,0x2a,0x44,0x72,0xd9,0x87,0x66,0xd4,0xf5,0x3a,0xa7, + 0x73,0xa9,0xa8,0x86,0x62,0xc7,0x65,0xc8,0xc9,0xa1,0xf4,0xd1, + 0xe9,0x5a,0x92,0x85,0xa6,0xe7,0x93,0xe8,0xc1,0xc6,0x7a,0x64, + 0xe1,0x4a,0x6a,0xe6,0xb3,0xf1,0xd3,0xa5,0x8a,0xb2,0x9a,0xba, + 0x84,0xa4,0x63,0xe5,0xc5,0xf3,0xd2,0xc4,0x82,0xaa,0xda,0xe4, + 0xf2,0xca,0x83,0xa3,0xa2,0xc3,0xea,0xc2,0xe2,0xe3,0xff,0xff }, + { 0,2,2,1,4,1,4,1,3,3,1,0,0,0,0,140, + 0x02,0x03,0x01,0x04,0x05,0x12,0x11,0x06, + 0x13,0x07,0x08,0x14,0x22,0x09,0x21,0x00,0x23,0x15,0x31,0x32, + 0x0a,0x16,0xf0,0x24,0x33,0x41,0x42,0x19,0x17,0x25,0x18,0x51, + 0x34,0x43,0x52,0x29,0x35,0x61,0x39,0x71,0x62,0x36,0x53,0x26, + 0x38,0x1a,0x37,0x81,0x27,0x91,0x79,0x55,0x45,0x28,0x72,0x59, + 0xa1,0xb1,0x44,0x69,0x54,0x58,0xd1,0xfa,0x57,0xe1,0xf1,0xb9, + 0x49,0x47,0x63,0x6a,0xf9,0x56,0x46,0xa8,0x2a,0x4a,0x78,0x99, + 0x3a,0x75,0x74,0x86,0x65,0xc1,0x76,0xb6,0x96,0xd6,0x89,0x85, + 0xc9,0xf5,0x95,0xb4,0xc7,0xf7,0x8a,0x97,0xb8,0x73,0xb7,0xd8, + 0xd9,0x87,0xa7,0x7a,0x48,0x82,0x84,0xea,0xf4,0xa6,0xc5,0x5a, + 0x94,0xa4,0xc6,0x92,0xc3,0x68,0xb5,0xc8,0xe4,0xe5,0xe6,0xe9, + 0xa2,0xa3,0xe3,0xc2,0x66,0x67,0x93,0xaa,0xd4,0xd5,0xe7,0xf8, + 0x88,0x9a,0xd7,0x77,0xc4,0x64,0xe2,0x98,0xa5,0xca,0xda,0xe8, + 0xf3,0xf6,0xa9,0xb2,0xb3,0xf2,0xd2,0x83,0xba,0xd3,0xff,0xff }, + { 0,0,6,2,1,3,3,2,5,1,2,2,8,10,0,117, + 0x04,0x05,0x03,0x06,0x02,0x07,0x01,0x08, + 0x09,0x12,0x13,0x14,0x11,0x15,0x0a,0x16,0x17,0xf0,0x00,0x22, + 0x21,0x18,0x23,0x19,0x24,0x32,0x31,0x25,0x33,0x38,0x37,0x34, + 0x35,0x36,0x39,0x79,0x57,0x58,0x59,0x28,0x56,0x78,0x27,0x41, + 0x29,0x77,0x26,0x42,0x76,0x99,0x1a,0x55,0x98,0x97,0xf9,0x48, + 0x54,0x96,0x89,0x47,0xb7,0x49,0xfa,0x75,0x68,0xb6,0x67,0x69, + 0xb9,0xb8,0xd8,0x52,0xd7,0x88,0xb5,0x74,0x51,0x46,0xd9,0xf8, + 0x3a,0xd6,0x87,0x45,0x7a,0x95,0xd5,0xf6,0x86,0xb4,0xa9,0x94, + 0x53,0x2a,0xa8,0x43,0xf5,0xf7,0xd4,0x66,0xa7,0x5a,0x44,0x8a, + 0xc9,0xe8,0xc8,0xe7,0x9a,0x6a,0x73,0x4a,0x61,0xc7,0xf4,0xc6, + 0x65,0xe9,0x72,0xe6,0x71,0x91,0x93,0xa6,0xda,0x92,0x85,0x62, + 0xf3,0xc5,0xb2,0xa4,0x84,0xba,0x64,0xa5,0xb3,0xd2,0x81,0xe5, + 0xd3,0xaa,0xc4,0xca,0xf2,0xb1,0xe4,0xd1,0x83,0x63,0xea,0xc3, + 0xe2,0x82,0xf1,0xa3,0xc2,0xa1,0xc1,0xe3,0xa2,0xe1,0xff,0xff } + }; + if (table > 2) table = 2; + huff[0] = make_decoder ( first_tree[table]); + huff[1] = make_decoder (second_tree[table]); +} + +/* + Return 0 if the image starts with compressed data, + 1 if it starts with uncompressed low-order bits. + + In Canon compressed data, 0xff is always followed by 0x00. + */ +int CLASS canon_has_lowbits() +{ + uchar test[0x4000]; + int ret=1, i; + + fseek (ifp, 0, SEEK_SET); + fread (test, 1, sizeof test, ifp); + for (i=540; i < sizeof test - 1; i++) + if (test[i] == 0xff) { + if (test[i+1]) return 1; + ret=0; + } + return ret; +} + +void CLASS canon_load_raw() +{ + ushort *pixel, *prow, *huff[2]; + int nblocks, lowbits, i, c, row, r, save, val; + int block, diffbuf[64], leaf, len, diff, carry=0, pnum=0, base[2]; + + crw_init_tables (tiff_compress, huff); + lowbits = canon_has_lowbits(); + if (!lowbits) maximum = 0x3ff; + fseek (ifp, 540 + lowbits*raw_height*raw_width/4, SEEK_SET); + zero_after_ff = 1; + getbits(-1); + for (row=0; row < raw_height; row+=8) { + pixel = raw_image + row*raw_width; + nblocks = MIN (8, raw_height-row) * raw_width >> 6; + for (block=0; block < nblocks; block++) { + memset (diffbuf, 0, sizeof diffbuf); + for (i=0; i < 64; i++ ) { + leaf = gethuff(huff[i > 0]); + if (leaf == 0 && i) break; + if (leaf == 0xff) continue; + i += leaf >> 4; + len = leaf & 15; + if (len == 0) continue; + diff = getbits(len); + if ((diff & (1 << (len-1))) == 0) + diff -= (1 << len) - 1; + if (i < 64) diffbuf[i] = diff; + } + diffbuf[0] += carry; + carry = diffbuf[0]; + for (i=0; i < 64; i++ ) { + if (pnum++ % raw_width == 0) + base[0] = base[1] = 512; + if ((pixel[(block << 6) + i] = base[i & 1] += diffbuf[i]) >> 10) + derror(); + } + } + if (lowbits) { + save = ftell(ifp); + fseek (ifp, 26 + row*raw_width/4, SEEK_SET); + for (prow=pixel, i=0; i < raw_width*2; i++) { + c = fgetc(ifp); + for (r=0; r < 8; r+=2, prow++) { + val = (*prow << 2) + ((c >> r) & 3); + if (raw_width == 2672 && val < 512) val += 2; + *prow = val; + } + } + fseek (ifp, save, SEEK_SET); + } + } + FORC(2) free (huff[c]); +} + +/* + Not a full implementation of Lossless JPEG, just + enough to decode Canon, Kodak and Adobe DNG images. + */ +struct jhead { + int bits, high, wide, clrs, sraw, psv, restart, vpred[6]; + ushort *huff[6], *free[4], *row; +}; + +int CLASS ljpeg_start (struct jhead *jh, int info_only) +{ + int c, tag; + ushort len; + uchar data[0x10000]; + const uchar *dp; + + memset (jh, 0, sizeof *jh); + jh->restart = INT_MAX; + fread (data, 2, 1, ifp); + if (data[1] != 0xd8) return 0; + do { + fread (data, 2, 2, ifp); + tag = data[0] << 8 | data[1]; + len = (data[2] << 8 | data[3]) - 2; + if (tag <= 0xff00) return 0; + fread (data, 1, len, ifp); + switch (tag) { + case 0xffc3: + jh->sraw = ((data[7] >> 4) * (data[7] & 15) - 1) & 3; + case 0xffc0: + jh->bits = data[0]; + jh->high = data[1] << 8 | data[2]; + jh->wide = data[3] << 8 | data[4]; + jh->clrs = data[5] + jh->sraw; + if (len == 9 && !dng_version) getc(ifp); + break; + case 0xffc4: + if (info_only) break; + for (dp = data; dp < data+len && (c = *dp++) < 4; ) + jh->free[c] = jh->huff[c] = make_decoder_ref (&dp); + break; + case 0xffda: + jh->psv = data[1+data[0]*2]; + jh->bits -= data[3+data[0]*2] & 15; + break; + case 0xffdd: + jh->restart = data[0] << 8 | data[1]; + } + } while (tag != 0xffda); + if (info_only) return 1; + if (jh->clrs > 6 || !jh->huff[0]) return 0; + FORC(5) if (!jh->huff[c+1]) jh->huff[c+1] = jh->huff[c]; + if (jh->sraw) { + FORC(4) jh->huff[2+c] = jh->huff[1]; + FORC(jh->sraw) jh->huff[1+c] = jh->huff[0]; + } + jh->row = (ushort *) calloc (jh->wide*jh->clrs, 4); + merror (jh->row, "ljpeg_start()"); + return zero_after_ff = 1; +} + +void CLASS ljpeg_end (struct jhead *jh) +{ + int c; + FORC4 if (jh->free[c]) free (jh->free[c]); + free (jh->row); +} + +int CLASS ljpeg_diff (ushort *huff) +{ + int len, diff; + + len = gethuff(huff); + if (len == 16 && (!dng_version || dng_version >= 0x1010000)) + return -32768; + diff = getbits(len); + if ((diff & (1 << (len-1))) == 0) + diff -= (1 << len) - 1; + return diff; +} + +ushort * CLASS ljpeg_row (int jrow, struct jhead *jh) +{ + int col, c, diff, pred, spred=0; + ushort mark=0, *row[3]; + + if (jrow * jh->wide % jh->restart == 0) { + FORC(6) jh->vpred[c] = 1 << (jh->bits-1); + if (jrow) { + fseek (ifp, -2, SEEK_CUR); + do mark = (mark << 8) + (c = fgetc(ifp)); + while (c != EOF && mark >> 4 != 0xffd); + } + getbits(-1); + } + FORC3 row[c] = jh->row + jh->wide*jh->clrs*((jrow+c) & 1); + for (col=0; col < jh->wide; col++) + FORC(jh->clrs) { + diff = ljpeg_diff (jh->huff[c]); + if (jh->sraw && c <= jh->sraw && (col | c)) + pred = spred; + else if (col) pred = row[0][-jh->clrs]; + else pred = (jh->vpred[c] += diff) - diff; + if (jrow && col) switch (jh->psv) { + case 1: break; + case 2: pred = row[1][0]; break; + case 3: pred = row[1][-jh->clrs]; break; + case 4: pred = pred + row[1][0] - row[1][-jh->clrs]; break; + case 5: pred = pred + ((row[1][0] - row[1][-jh->clrs]) >> 1); break; + case 6: pred = row[1][0] + ((pred - row[1][-jh->clrs]) >> 1); break; + case 7: pred = (pred + row[1][0]) >> 1; break; + default: pred = 0; + } + if ((**row = pred + diff) >> jh->bits) derror(); + if (c <= jh->sraw) spred = **row; + row[0]++; row[1]++; + } + return row[2]; +} + +void CLASS lossless_jpeg_load_raw() +{ + int jwide, jrow, jcol, val, jidx, i, j, row=0, col=0; + struct jhead jh; + ushort *rp; + + if (!ljpeg_start (&jh, 0)) return; + jwide = jh.wide * jh.clrs; + + for (jrow=0; jrow < jh.high; jrow++) { + rp = ljpeg_row (jrow, &jh); + if (load_flags & 1) + row = jrow & 1 ? height-1-jrow/2 : jrow/2; + for (jcol=0; jcol < jwide; jcol++) { + val = curve[*rp++]; + if (cr2_slice[0]) { + jidx = jrow*jwide + jcol; + i = jidx / (cr2_slice[1]*raw_height); + if ((j = i >= cr2_slice[0])) + i = cr2_slice[0]; + jidx -= i * (cr2_slice[1]*raw_height); + row = jidx / cr2_slice[1+j]; + col = jidx % cr2_slice[1+j] + i*cr2_slice[1]; + } + if (raw_width == 3984 && (col -= 2) < 0) + col += (row--,raw_width); + if ((unsigned) row < raw_height) RAW(row,col) = val; + if (++col >= raw_width) + col = (row++,0); + } + } + ljpeg_end (&jh); +} + +void CLASS canon_sraw_load_raw() +{ + struct jhead jh; + short *rp=0, (*ip)[4]; + int jwide, slice, scol, ecol, row, col, jrow=0, jcol=0, pix[3], c; + int v[3]={0,0,0}, ver, hue; + char *cp; + + if (!ljpeg_start (&jh, 0) || jh.clrs < 4) return; + jwide = (jh.wide >>= 1) * jh.clrs; + + for (ecol=slice=0; slice <= cr2_slice[0]; slice++) { + scol = ecol; + ecol += cr2_slice[1] * 2 / jh.clrs; + if (!cr2_slice[0] || ecol > raw_width-1) ecol = raw_width & -2; + for (row=0; row < height; row += (jh.clrs >> 1) - 1) { + ip = (short (*)[4]) image + row*width; + for (col=scol; col < ecol; col+=2, jcol+=jh.clrs) { + if ((jcol %= jwide) == 0) + rp = (short *) ljpeg_row (jrow++, &jh); + if (col >= width) continue; + FORC (jh.clrs-2) + ip[col + (c >> 1)*width + (c & 1)][0] = rp[jcol+c]; + ip[col][1] = rp[jcol+jh.clrs-2] - 16384; + ip[col][2] = rp[jcol+jh.clrs-1] - 16384; + } + } + } + for (cp=model2; *cp && !isdigit(*cp); cp++); + sscanf (cp, "%d.%d.%d", v, v+1, v+2); + ver = (v[0]*1000 + v[1])*1000 + v[2]; + hue = (jh.sraw+1) << 2; + if (unique_id >= 0x80000281 || (unique_id == 0x80000218 && ver > 1000006)) + hue = jh.sraw << 1; + ip = (short (*)[4]) image; + rp = ip[0]; + for (row=0; row < height; row++, ip+=width) { + if (row & (jh.sraw >> 1)) + for (col=0; col < width; col+=2) + for (c=1; c < 3; c++) + if (row == height-1) + ip[col][c] = ip[col-width][c]; + else ip[col][c] = (ip[col-width][c] + ip[col+width][c] + 1) >> 1; + for (col=1; col < width; col+=2) + for (c=1; c < 3; c++) + if (col == width-1) + ip[col][c] = ip[col-1][c]; + else ip[col][c] = (ip[col-1][c] + ip[col+1][c] + 1) >> 1; + } + for ( ; rp < ip[0]; rp+=4) { + if (unique_id == 0x80000218 || + unique_id == 0x80000250 || + unique_id == 0x80000261 || + unique_id == 0x80000281 || + unique_id == 0x80000287) { + rp[1] = (rp[1] << 2) + hue; + rp[2] = (rp[2] << 2) + hue; + pix[0] = rp[0] + (( 50*rp[1] + 22929*rp[2]) >> 14); + pix[1] = rp[0] + ((-5640*rp[1] - 11751*rp[2]) >> 14); + pix[2] = rp[0] + ((29040*rp[1] - 101*rp[2]) >> 14); + } else { + if (unique_id < 0x80000218) rp[0] -= 512; + pix[0] = rp[0] + rp[2]; + pix[2] = rp[0] + rp[1]; + pix[1] = rp[0] + ((-778*rp[1] - (rp[2] << 11)) >> 12); + } + FORC3 rp[c] = CLIP(pix[c] * sraw_mul[c] >> 10); + } + ljpeg_end (&jh); + maximum = 0x3fff; +} + +void CLASS adobe_copy_pixel (unsigned row, unsigned col, ushort **rp) +{ + int c; + + if (is_raw == 2 && shot_select) (*rp)++; + if (raw_image) { + if (row < raw_height && col < raw_width) + RAW(row,col) = curve[**rp]; + *rp += is_raw; + } else { + if (row < height && col < width) + FORC(tiff_samples) + image[row*width+col][c] = curve[(*rp)[c]]; + *rp += tiff_samples; + } + if (is_raw == 2 && shot_select) (*rp)--; +} + +void CLASS lossless_dng_load_raw() +{ + unsigned save, trow=0, tcol=0, jwide, jrow, jcol, row, col; + struct jhead jh; + ushort *rp; + + while (trow < raw_height) { + save = ftell(ifp); + if (tile_length < INT_MAX) + fseek (ifp, get4(), SEEK_SET); + if (!ljpeg_start (&jh, 0)) break; + jwide = jh.wide; + if (filters) jwide *= jh.clrs; + jwide /= is_raw; + for (row=col=jrow=0; jrow < jh.high; jrow++) { + rp = ljpeg_row (jrow, &jh); + for (jcol=0; jcol < jwide; jcol++) { + adobe_copy_pixel (trow+row, tcol+col, &rp); + if (++col >= tile_width || col >= raw_width) + row += 1 + (col = 0); + } + } + fseek (ifp, save+4, SEEK_SET); + if ((tcol += tile_width) >= raw_width) + trow += tile_length + (tcol = 0); + ljpeg_end (&jh); + } +} + +void CLASS packed_dng_load_raw() +{ + ushort *pixel, *rp; + int row, col; + + pixel = (ushort *) calloc (raw_width, tiff_samples*sizeof *pixel); + merror (pixel, "packed_dng_load_raw()"); + for (row=0; row < raw_height; row++) { + if (tiff_bps == 16) + read_shorts (pixel, raw_width * tiff_samples); + else { + getbits(-1); + for (col=0; col < raw_width * tiff_samples; col++) + pixel[col] = getbits(tiff_bps); + } + for (rp=pixel, col=0; col < raw_width; col++) + adobe_copy_pixel (row, col, &rp); + } + free (pixel); +} + +void CLASS pentax_load_raw() +{ + ushort bit[2][15], huff[4097]; + int dep, row, col, diff, c, i; + ushort vpred[2][2] = {{0,0},{0,0}}, hpred[2]; + + fseek (ifp, meta_offset, SEEK_SET); + dep = (get2() + 12) & 15; + fseek (ifp, 12, SEEK_CUR); + FORC(dep) bit[0][c] = get2(); + FORC(dep) bit[1][c] = fgetc(ifp); + FORC(dep) + for (i=bit[0][c]; i <= ((bit[0][c]+(4096 >> bit[1][c])-1) & 4095); ) + huff[++i] = bit[1][c] << 8 | c; + huff[0] = 12; + fseek (ifp, data_offset, SEEK_SET); + getbits(-1); + for (row=0; row < raw_height; row++) + for (col=0; col < raw_width; col++) { + diff = ljpeg_diff (huff); + if (col < 2) hpred[col] = vpred[row & 1][col] += diff; + else hpred[col & 1] += diff; + RAW(row,col) = hpred[col & 1]; + if (hpred[col & 1] >> tiff_bps) derror(); + } +} + +void CLASS nikon_load_raw() +{ + static const uchar nikon_tree[][32] = { + { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0, /* 12-bit lossy */ + 5,4,3,6,2,7,1,0,8,9,11,10,12 }, + { 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0, /* 12-bit lossy after split */ + 0x39,0x5a,0x38,0x27,0x16,5,4,3,2,1,0,11,12,12 }, + { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0, /* 12-bit lossless */ + 5,4,6,3,7,2,8,1,9,0,10,11,12 }, + { 0,1,4,3,1,1,1,1,1,2,0,0,0,0,0,0, /* 14-bit lossy */ + 5,6,4,7,8,3,9,2,1,0,10,11,12,13,14 }, + { 0,1,5,1,1,1,1,1,1,1,2,0,0,0,0,0, /* 14-bit lossy after split */ + 8,0x5c,0x4b,0x3a,0x29,7,6,5,4,3,2,1,0,13,14 }, + { 0,1,4,2,2,3,1,2,0,0,0,0,0,0,0,0, /* 14-bit lossless */ + 7,6,8,5,9,4,10,3,11,12,2,0,1,13,14 } }; + ushort *huff, ver0, ver1, vpred[2][2], hpred[2], csize; + int i, min, max, step=0, tree=0, split=0, row, col, len, shl, diff; + + fseek (ifp, meta_offset, SEEK_SET); + ver0 = fgetc(ifp); + ver1 = fgetc(ifp); + if (ver0 == 0x49 || ver1 == 0x58) + fseek (ifp, 2110, SEEK_CUR); + if (ver0 == 0x46) tree = 2; + if (tiff_bps == 14) tree += 3; + read_shorts (vpred[0], 4); + max = 1 << tiff_bps & 0x7fff; + if ((csize = get2()) > 1) + step = max / (csize-1); + if (ver0 == 0x44 && ver1 == 0x20 && step > 0) { + for (i=0; i < csize; i++) + curve[i*step] = get2(); + for (i=0; i < max; i++) + curve[i] = ( curve[i-i%step]*(step-i%step) + + curve[i-i%step+step]*(i%step) ) / step; + fseek (ifp, meta_offset+562, SEEK_SET); + split = get2(); + } else if (ver0 != 0x46 && csize <= 0x4001) + read_shorts (curve, max=csize); + while (curve[max-2] == curve[max-1]) max--; + huff = make_decoder (nikon_tree[tree]); + fseek (ifp, data_offset, SEEK_SET); + getbits(-1); + for (min=row=0; row < height; row++) { + if (split && row == split) { + free (huff); + huff = make_decoder (nikon_tree[tree+1]); + max += (min = 16) << 1; + } + for (col=0; col < raw_width; col++) { + i = gethuff(huff); + len = i & 15; + shl = i >> 4; + diff = ((getbits(len-shl) << 1) + 1) << shl >> 1; + if ((diff & (1 << (len-1))) == 0) + diff -= (1 << len) - !shl; + if (col < 2) hpred[col] = vpred[row & 1][col] += diff; + else hpred[col & 1] += diff; + if ((ushort)(hpred[col & 1] + min) >= max) derror(); + RAW(row,col) = curve[LIM((short)hpred[col & 1],0,0x3fff)]; + } + } + free (huff); +} + +void CLASS nikon_yuv_load_raw() +{ + int row, col, yuv[4], rgb[3], b, c; + UINT64 bitbuf=0; + + for (row=0; row < raw_height; row++) + for (col=0; col < raw_width; col++) { + if (!(b = col & 1)) { + bitbuf = 0; + FORC(6) bitbuf |= (UINT64) fgetc(ifp) << c*8; + FORC(4) yuv[c] = (bitbuf >> c*12 & 0xfff) - (c >> 1 << 11); + } + rgb[0] = yuv[b] + 1.370705*yuv[3]; + rgb[1] = yuv[b] - 0.337633*yuv[2] - 0.698001*yuv[3]; + rgb[2] = yuv[b] + 1.732446*yuv[2]; + FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,0xfff)] / cam_mul[c]; + } +} + +/* + Returns 1 for a Coolpix 995, 0 for anything else. + */ +int CLASS nikon_e995() +{ + int i, histo[256]; + const uchar often[] = { 0x00, 0x55, 0xaa, 0xff }; + + memset (histo, 0, sizeof histo); + fseek (ifp, -2000, SEEK_END); + for (i=0; i < 2000; i++) + histo[fgetc(ifp)]++; + for (i=0; i < 4; i++) + if (histo[often[i]] < 200) + return 0; + return 1; +} + +/* + Returns 1 for a Coolpix 2100, 0 for anything else. + */ +int CLASS nikon_e2100() +{ + uchar t[12]; + int i; + + fseek (ifp, 0, SEEK_SET); + for (i=0; i < 1024; i++) { + fread (t, 1, 12, ifp); + if (((t[2] & t[4] & t[7] & t[9]) >> 4 + & t[1] & t[6] & t[8] & t[11] & 3) != 3) + return 0; + } + return 1; +} + +void CLASS nikon_3700() +{ + int bits, i; + uchar dp[24]; + static const struct { + int bits; + char make[12], model[15]; + } table[] = { + { 0x00, "Pentax", "Optio 33WR" }, + { 0x03, "Nikon", "E3200" }, + { 0x32, "Nikon", "E3700" }, + { 0x33, "Olympus", "C740UZ" } }; + + fseek (ifp, 3072, SEEK_SET); + fread (dp, 1, 24, ifp); + bits = (dp[8] & 3) << 4 | (dp[20] & 3); + for (i=0; i < sizeof table / sizeof *table; i++) + if (bits == table[i].bits) { + strcpy (make, table[i].make ); + strcpy (model, table[i].model); + } +} + +/* + Separates a Minolta DiMAGE Z2 from a Nikon E4300. + */ +int CLASS minolta_z2() +{ + int i, nz; + char tail[424]; + + fseek (ifp, -(int)sizeof tail, SEEK_END); + fread (tail, 1, sizeof tail, ifp); + for (nz=i=0; i < sizeof tail; i++) + if (tail[i]) nz++; + return nz > 20; +} + +/*RT void CLASS jpeg_thumb(); */ + +void CLASS ppm_thumb() +{ + char *thumb; + thumb_length = thumb_width*thumb_height*3; + thumb = (char *) malloc (thumb_length); + merror (thumb, "ppm_thumb()"); + fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height); + fread (thumb, 1, thumb_length, ifp); + fwrite (thumb, 1, thumb_length, ofp); + free (thumb); +} + +void CLASS ppm16_thumb() +{ + int i; + char *thumb; + thumb_length = thumb_width*thumb_height*3; + thumb = (char *) calloc (thumb_length, 2); + merror (thumb, "ppm16_thumb()"); + read_shorts ((ushort *) thumb, thumb_length); + for (i=0; i < thumb_length; i++) + thumb[i] = ((ushort *) thumb)[i] >> 8; + fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height); + fwrite (thumb, 1, thumb_length, ofp); + free (thumb); +} + +void CLASS layer_thumb() +{ + int i, c; + char *thumb, map[][4] = { "012","102" }; + + colors = thumb_misc >> 5 & 7; + thumb_length = thumb_width*thumb_height; + thumb = (char *) calloc (colors, thumb_length); + merror (thumb, "layer_thumb()"); + fprintf (ofp, "P%d\n%d %d\n255\n", + 5 + (colors >> 1), thumb_width, thumb_height); + fread (thumb, thumb_length, colors, ifp); + for (i=0; i < thumb_length; i++) + FORCC putc (thumb[i+thumb_length*(map[thumb_misc >> 8][c]-'0')], ofp); + free (thumb); +} + +void CLASS rollei_thumb() +{ + unsigned i; + ushort *thumb; + + thumb_length = thumb_width * thumb_height; + thumb = (ushort *) calloc (thumb_length, 2); + merror (thumb, "rollei_thumb()"); + fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height); + read_shorts (thumb, thumb_length); + for (i=0; i < thumb_length; i++) { + putc (thumb[i] << 3, ofp); + putc (thumb[i] >> 5 << 2, ofp); + putc (thumb[i] >> 11 << 3, ofp); + } + free (thumb); +} + +void CLASS rollei_load_raw() +{ + uchar pixel[10]; + unsigned iten=0, isix, i, buffer=0, todo[16]; + + isix = raw_width * raw_height * 5 / 8; + while (fread (pixel, 1, 10, ifp) == 10) { + for (i=0; i < 10; i+=2) { + todo[i] = iten++; + todo[i+1] = pixel[i] << 8 | pixel[i+1]; + buffer = pixel[i] >> 2 | buffer << 6; + } + for ( ; i < 16; i+=2) { + todo[i] = isix++; + todo[i+1] = buffer >> (14-i)*5; + } + for (i=0; i < 16; i+=2) + raw_image[todo[i]] = (todo[i+1] & 0x3ff); + } + maximum = 0x3ff; +} + +int CLASS raw (unsigned row, unsigned col) +{ + return (row < raw_height && col < raw_width) ? RAW(row,col) : 0; +} + +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]; + + 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]; + } + } + 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; + + 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; + } + 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() +{ + int a, b, i; + ushort akey, bkey, mask; + + fseek (ifp, ph1.key_off, SEEK_SET); + akey = get2(); + bkey = get2(); + mask = ph1.format == 1 ? 0x5555:0x1354; + fseek (ifp, data_offset, SEEK_SET); + read_shorts (raw_image, raw_width*raw_height); + if (ph1.format) + for (i=0; i < raw_width*raw_height; i+=2) { + a = raw_image[i+0] ^ akey; + b = raw_image[i+1] ^ bkey; + raw_image[i+0] = (a & mask) | (b & ~mask); + raw_image[i+1] = (b & mask) | (a & ~mask); + } +} + +unsigned CLASS ph1_bithuff_t::operator() (int nbits, ushort *huff) +{ +/*RT static UINT64 bitbuf=0; */ +/*RT static int vbits=0; */ + unsigned c; + + if (nbits == -1) + return bitbuf = vbits = 0; + if (nbits == 0) return 0; + if (vbits < nbits) { + bitbuf = bitbuf << 32 | get4(); + vbits += 32; + } + c = bitbuf << (64-vbits) >> (64-nbits); + if (huff) { + vbits -= huff[c] >> 8; + return (uchar) huff[c]; + } + vbits -= nbits; + return c; +} +#define ph1_bits(n) ph1_bithuff(n,0) +#define ph1_huff(h) ph1_bithuff(*h,h+1) + +void CLASS phase_one_load_raw_c() +{ + static const int length[] = { 8,7,6,9,11,10,5,12,14,13 }; + int *offset, len[2], pred[2], row, col, i, j; + ushort *pixel; + short (*cblack)[2], (*rblack)[2]; + + pixel = (ushort *) calloc (raw_width*3 + raw_height*4, 2); + merror (pixel, "phase_one_load_raw_c()"); + offset = (int *) (pixel + raw_width); + fseek (ifp, strip_offset, SEEK_SET); + for (row=0; row < raw_height; row++) + offset[row] = get4(); + cblack = (short (*)[2]) (offset + raw_height); + fseek (ifp, ph1.black_col, SEEK_SET); + if (ph1.black_col) + read_shorts ((ushort *) cblack[0], raw_height*2); + rblack = cblack + raw_height; + fseek (ifp, ph1.black_row, SEEK_SET); + if (ph1.black_row) + read_shorts ((ushort *) rblack[0], raw_width*2); + for (i=0; i < 256; i++) + curve[i] = i*i / 3.969 + 0.5; + for (row=0; row < raw_height; row++) { + fseek (ifp, data_offset + offset[row], SEEK_SET); + ph1_bits(-1); + pred[0] = pred[1] = 0; + for (col=0; col < raw_width; col++) { + if (col >= (raw_width & -8)) + len[0] = len[1] = 14; + else if ((col & 7) == 0) + for (i=0; i < 2; i++) { + for (j=0; j < 5 && !ph1_bits(1); j++); + if (j--) len[i] = length[j*2 + ph1_bits(1)]; + } + if ((i = len[col & 1]) == 14) + pixel[col] = pred[col & 1] = ph1_bits(16); + else + pixel[col] = pred[col & 1] += ph1_bits(i) + 1 - (1 << (i - 1)); + if (pred[col & 1] >> 16) derror(); + if (ph1.format == 5 && pixel[col] < 256) + pixel[col] = curve[pixel[col]]; + } + for (col=0; col < raw_width; col++) { + i = (pixel[col] << 2) - ph1.black + + cblack[row][col >= ph1.split_col] + + rblack[col][row >= ph1.split_row]; + if (i > 0) RAW(row,col) = i; + } + } + free (pixel); + maximum = 0xfffc - ph1.black; +} + +void CLASS parse_hasselblad_gain() +{ + /* + Reverse-engineer's notes: + + The Hasselblad gain tag (0x19 in makernotes) is only available in the 3FR format and + is applied and removed when Hasselblad Phocus converts it to the FFF format. It's + always 0x300000 bytes large regardless of (tested) model, not all space in it is + used though. + + It contains individual calibration information from the factory to tune the sensor + performance. + + There is more calibration data in the tag than what is applied in conversion to FFF, + I've only cared to figure out the data which is actually used, but have some leads on + remaining info. + + The format is not equal between all models. Due to lack of 3FR files (harder to get + than FFF) only a subset of the models have been reverse-engineered. + + The header space is 512 bytes and is a mix of 16 and 32 bit values. Offset to blocks + are 32 bit values, but all information seems to be encoded in 16 bit values. Many + values in the header can be zeroed with no effect on FFF conversion, and their + meaning, if any, have not been further investigated. + + Formats: + hdr16[22] = raw width + hdr16[23] = raw height + hdr32[24] = offset to level corr block + Data block format. Seems to differ depending on sensor type. For tested H4D-50 + and H3D-31: 10 16 bit signed values per row + value 0: a correction factor (k) used on even columns, where the new pixel value is + calulated as follows: + new_value = old_value + (2 * ((k * (old_value_on_row_above-256)) / 32767) - 2) + note the connection to the value on the row above, seems to be some sort of signal + leakage correction. + value 1: same as value 0 but using old value on row below instead of above + value 2-3: same as value 0-1 but for odd columns + value 4-9: has some effect if non-zero (probably similar to the others) but not + investigated which, as it's seems to be always zero for the tested cameras. + + hdr32[25] = probably offset to "bad/unreliable pixels" info, always 512 as it starts + directly after the header. Not applied in FFF conversion (at least + typically). + Data block format guess: raw_height packets of + + + hdr32[27] = offset to unknown data (bad colulmns?), of the form: + <0> + packet: . + + hdr32[34] = curves offset, seems to be A/D curves (one per channel) on newer models + and some sort of a film curve on older. Not applied in FFF conversion. + + hdr32[36] = flatfield correction, not available in older models. Data format: + <1><11 * 2 pad> + packet: + + The header pad is not zeroed and might seem to contain some sort of + information, but it makes no difference if set to zero. See + hasselblad_correct() how the flatfield is applied. + + Applied in FFF conversion is levels, flatfield correction, and the bad columns(?) + data. A/D curves are surprisingly not applied, maybe pre-applied in hardware and + only available as information? Levels are applied before flatfield, further + ordering has not been investigated. + + Not all combinations/models have been tested so there may be gaps. + + Most clipped pixels in a 3FR is at 65535, but there's also some at 65534. Both + are set to 65535 when calibrated, while 65533 is treated as a normal value. In + the calibration process smaller values can be scaled to 65534 (which should + not be seen as clipped). + */ + + ushort raw_h, count, ch_count, u16; + int i, offset; + off_t base; + + base = ftell(ifp); + fseek(ifp, 2 * 23, SEEK_CUR); + raw_h = get2(); + fseek(ifp, 48, SEEK_CUR); + offset = get4(); + hbd.levels = offset ? base + offset : 0; + fseek(ifp, 8, SEEK_CUR); + offset = get4(); + hbd.unknown1 = offset ? base + offset : 0; + fseek(ifp, 32, SEEK_CUR); + offset = get4(); + hbd.flatfield = offset ? base + offset : 0; +} + +void CLASS hasselblad_correct() +{ + unsigned col, row; + + /* + + This function applies 3FR calibration data. At the time of writing it supports a + subset, so here's a todo list: + + TODO: + - Support all gain tag formats + - The 0x19 tag varies a bit between models. We don't have parsers for all models. + - The reference model used was during inital reverse-engineering was a H4D-50, + we probably support the Hasselblads with Kodak 31, 39, 40 and 50 megapixels + well, but more work is needed for Kodak 16 and 22, Dalsa 60 and Sony 50. + - Apply bad column(?) data (hbd.unknown1) + - It was left out in this initial release since the effect is very small. + - Apply black(?) data, tag 0x1a and 0x1b is not parsed, it has however marginal + effect (at least for shorter exposures) so it's not too important. + + While there are things to do, the current implementation supports the most + important aspects, the faltfield and levels calibrations applied can have strong + visible effects. + + */ + + if (hbd.levels) { + int i; + fseek(ifp, hbd.levels, SEEK_SET); + /* skip the first set (not used as we don't apply on first/last row), we look at it though to see if + the levels format is one that we support (there are other formats on some models which is not + supported here) */ + short test[10]; + for (i = 0; i < 10; i++) test[i] = (short)get2(); + if (test[5] == 0 && test[6] == 0 && test[7] == 0 && test[8] == 0 && test[9] == 0) { + int corr[4]; + ushort *row_above = (ushort *)malloc(sizeof(ushort) * raw_width); // we need to cache row above as we write new values as we go + for (col = 0; col < raw_width; col++) row_above[col] = RAW(0,col); + for (row = 1; row < raw_height-1; row++) { + for (i = 0; i < 4; i++) corr[i] = (short)get2(); + fseek(ifp, 6 * 2, SEEK_CUR); + for (col = 0; col < raw_width; col++) { + unsigned v = RAW(row,col); + if (v >= 65534) { + v = 65535; + } else { + if (corr[((col & 1)<<1)+0] && row_above[col] > black) v += 2 * ((corr[((col & 1)<<1)+0] * (row_above[col]-(int)black)) / 32767) - 2; + if (corr[((col & 1)<<1)+1] && RAW(row+1,col) > black) v += 2 * ((corr[((col & 1)<<1)+1] * (RAW(row+1,col)-(int)black)) / 32767) - 2; + } + row_above[col] = RAW(row,col); + RAW(row,col) = CLIP(v); + } + } + free(row_above); + } + } + + if (hbd.flatfield) { + int bw, bh, ffrows, ffcols, i, c; + ushort ref[4], ref_max; + fseek(ifp, hbd.flatfield, SEEK_SET); + get2(); + bw = get2(); + bh = get2(); + ffcols = get2(); + ffrows = get2(); + fseek(ifp, hbd.flatfield + 16 * 2, SEEK_SET); + + ushort *ffmap = (ushort *)malloc(sizeof(*ffmap) * 4 * ffcols * ffrows); + for (i = 0; i < 4 * ffcols * ffrows; i++) ffmap[i] = get2(); + + /* Get reference values from center of field. This seems to be what Phocus does too, + but haven't cared to figure out exactly at which coordinate */ + i = 4 * (ffcols * ffrows / 2 + ffcols / 2); + ref[0] = ffmap[i+0]; + ref[1] = ffmap[i+1]; + ref[3] = ffmap[i+2]; // G2 = index 3 in dcraw, 2 in 3FR + ref[2] = ffmap[i+3]; + ref_max = 0; + FORC4 if (ref[c] > ref_max) ref_max = ref[c]; + if (ref_max == 0) ref[0] = ref[1] = ref[2] = ref[3] = ref_max = 10000; + + /* Convert measured flatfield values to actual multipliers. The measured flatfield + can have vignetting which should be normalized, only color cast should be corrected. */ + for (i = 0; i < 4 * ffcols * ffrows; i += 4) { + double base, min = 65535.0, max = 0; + double cur[4]; + cur[0] = (double)ffmap[i+0] / ref[0]; + cur[1] = (double)ffmap[i+1] / ref[1]; + cur[3] = (double)ffmap[i+2] / ref[3]; // G2 index differs in dcraw and 3FR + cur[2] = (double)ffmap[i+3] / ref[2]; + FORC4 { + if (cur[c] < min) min = cur[c]; + if (cur[c] > max) max = cur[c]; + } + if (max == 0) max = 1.0; + base = (cur[0]+cur[1]+cur[2]+cur[3])/(max*4); + FORC4 cur[c] = cur[c] == 0 ? 1.0 : (base * max) / cur[c]; + /* convert to integer multiplier and store back to ffmap, we limit + range to 4 (16384*4) which should be fine for flatfield */ + FORC4 { + cur[c] *= 16384.0; + if (cur[c] > 65535.0) cur[c] = 65535.0; + ffmap[i+c] = (ushort)cur[c]; + } + } + + // of the cameras we've tested we know the exact placement of the flatfield map + int row_offset, col_offset; + switch (raw_width) { + case 8282: // 50 megapixel Kodak + row_offset = 21; + col_offset = 71; + break; + default: + /* Default case for camera models we've not tested. We center the map, which may + not be exactly where it should be but close enough for the smooth flatfield */ + row_offset = (raw_height - bh * ffrows) / 2; + col_offset = (raw_width - bw * ffcols) / 2; + break; + } + + /* + Concerning smoothing between blocks in the map Phocus makes it only vertically, + probably because it's simpler and faster. Looking at actual flatfield data it seems + like it's better to smooth in both directions. Possibly flatfield could be used for + correcting tiling on Dalsa sensors (H4D-60) like partly done in Phase One IIQ format, + and then sharp edges may be beneficial at least at the tiling seams, but at the time + of writing I've had no H4D-60 3FR files to test with to verify that. + + Meanwhile we do both vertical and horizontal smoothing/blurring. + */ + + /* pre-calculate constants for blurring. We probably should make a more efficient + blur than this, but this does not need any buffer and makes nice-looking + radial gradients */ + ushort *corners_weight = (ushort *)malloc(bw*bh*9*sizeof(*corners_weight)); + const char corners_mix[9][4][2] = { { {0,0}, {0,1}, {1,0}, {1,1} }, + { {0,1}, {1,1}, {-1,-1}, {-1,-1} }, + { {0,1}, {0,2}, {1,1}, {1,2} }, + { {1,0}, {1,1}, {-1,-1}, {-1,-1} }, + { {1,1}, {-1,-1}, {-1,-1}, {-1,-1} }, + { {1,1}, {1,2}, {-1,-1}, {-1,-1} }, + { {1,0}, {1,1}, {2,0}, {2,1} }, + { {1,1}, {2,1}, {-1,-1}, {-1,-1} }, + { {1,1}, {1,2}, {2,1}, {2,2} } }; + const ushort corners_shift[9] = { 2, 1, 2, 1, 0, 1, 2, 1, 2 }; + for (row = 0; row < bh; row++) { + const ushort maxdist = bw < bh ? bw/2-1 : bh/2-1; + const unsigned corners[9][2] = {{0,0}, {0,bw/2}, {0,bw-1}, + {bh/2,0},{bh/2,bw/2},{bh/2,bw-1}, + {bh-1,0},{bh-1,bw/2},{bh-1,bw-1}}; + for (col = 0; col < bw; col++) { + for (i = 0; i < 9; i++) { + ushort dist = (ushort)sqrt(abs(corners[i][0] - row) * abs(corners[i][0] - row) + abs(corners[i][1] - col) * abs(corners[i][1] - col)); + ushort weight = dist > maxdist ? 0 : maxdist - dist; + corners_weight[9*(row*bw+col)+i] = weight; + } + } + } + + // apply flatfield +#pragma omp parallel for + for (int row = 0; row < raw_height; row++) { + int ffs, cur_ffr, i, c; + if (row < row_offset) { + cur_ffr = row_offset; + ffs = 0; + } else if (row >= row_offset + ffrows * bh) { + cur_ffr = row_offset + (ffrows-1) * bh; + ffs = 4 * ffcols * (ffrows-1); + } else { + cur_ffr = row_offset + bh * ((row - row_offset) / bh); + ffs = 4 * ffcols * ((row - row_offset) / bh); + } + int next_ffc = 0, cur_ffc = col_offset; + int ffc = ffs; + ushort *cur[3][3]; // points to local ffmap entries with center at cur[1][1] + for (int col = 0; col < raw_width; col++) { + if (col == next_ffc) { + int rowsub = ffs == 0 ? 0 : ffcols*4; + int rowadd = ffs == 4 * ffcols * (ffrows-1) ? 0 : ffcols * 4; + int colsub = ffc == ffs ? 0 : 4; + int coladd = ffc == ffs + 4 * (ffcols-1) ? 0 : 4; + if (col != 0) cur_ffc = next_ffc; + else next_ffc += col_offset; + next_ffc += bw; + + cur[0][0] = &ffmap[ffc-rowsub-colsub]; + cur[0][1] = &ffmap[ffc-rowsub]; + cur[0][2] = &ffmap[ffc-rowsub+coladd]; + + cur[1][0] = &ffmap[ffc-colsub]; + cur[1][1] = &ffmap[ffc]; + cur[1][2] = &ffmap[ffc+coladd]; + + cur[2][0] = &ffmap[ffc+rowadd-colsub]; + cur[2][1] = &ffmap[ffc+rowadd]; + cur[2][2] = &ffmap[ffc+rowadd+coladd]; + + ffc += 4; + if (ffc == ffs + 4 * ffcols) next_ffc += raw_width; // last col in map, avoid stepping further + } + unsigned v = RAW(row,col); + if (v > black && v < 65535) { + c = FC(row,col); + unsigned x = col < cur_ffc ? 0 : col - cur_ffc; + unsigned y = row < cur_ffr ? 0 : row - cur_ffr; + if (x >= bw) x = bw-1; + if (y >= bh) y = bh-1; + unsigned wsum = 0; + unsigned mul = 0; + for (i = 0; i < 9; i++) { + ushort cw = corners_weight[9*(y*bw+x)+i]; + if (cw) { + unsigned m = 0; + int j; + for (j = 0; j < 1 << corners_shift[i]; j++) { + int cr = corners_mix[i][j][0], cc = corners_mix[i][j][1]; + m += cur[cr][cc][c]; + } + m >>= corners_shift[i]; + mul += m * cw; + wsum += cw; + } + } + mul /= wsum; + v = black + ((v-black) * mul) / 16384; + RAW(row,col) = v > 65535 ? 65535 : v; + } + } + } + free(ffmap); + free(corners_weight); + } +} + +void CLASS hasselblad_load_raw() +{ + struct jhead jh; + int shot, row, col, *back[5], len[2], diff[12], pred, sh, f, s, c; + unsigned upix, urow, ucol; + ushort *ip; + + if (!ljpeg_start (&jh, 0)) return; + order = 0x4949; + ph1_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; + cblack[6] >>= sh = tiff_samples > 1; + shot = LIM(shot_select, 1, tiff_samples) - 1; + for (row=0; row < raw_height; row++) { + FORC4 back[(c+3) & 3] = back[c]; + for (col=0; col < raw_width; col+=2) { + 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]); + 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; + } + } + for (s=col; s < col+2; s++) { + pred = 0x8000 + load_flags; + if (col) pred = back[2][s-2]; + if (col && row > 1) switch (jh.psv) { + case 11: pred += back[0][s]/2 - back[0][s-2]/2; break; + } + f = (row & 1)*3 ^ ((col+s) & 1); + FORC (tiff_samples) { + pred += diff[(s & 1)*tiff_samples+c]; + upix = pred >> sh & 0xffff; + if (raw_image && c == shot) + RAW(row,s) = upix; + if (image) { + urow = row-top_margin + (c & 1); + ucol = col-left_margin - ((c >> 1) & 1); + ip = &image[urow*width+ucol][f]; + if (urow < height && ucol < width) + *ip = c < 4 ? upix : (*ip + upix) >> 1; + } + } + back[2][s] = pred; + } + } + } + free (back[4]); + ljpeg_end (&jh); + if (image) mix_green = 1; +} + +void CLASS leaf_hdr_load_raw() +{ + ushort *pixel=0; + unsigned tile=0, r, c, row, col; + + if (!filters) { + pixel = (ushort *) calloc (raw_width, sizeof *pixel); + merror (pixel, "leaf_hdr_load_raw()"); + } + FORC(tiff_samples) + for (r=0; r < raw_height; r++) { + if (r % tile_length == 0) { + fseek (ifp, data_offset + 4*tile++, SEEK_SET); + fseek (ifp, get4(), SEEK_SET); + } + if (filters && c != shot_select) continue; + if (filters) pixel = raw_image + r*raw_width; + read_shorts (pixel, raw_width); + if (!filters && (row = r - top_margin) < height) + for (col=0; col < width; col++) + image[row*width+col][c] = pixel[col+left_margin]; + } + if (!filters) { + maximum = 0xffff; + raw_color = 1; + free (pixel); + } +} + +void CLASS unpacked_load_raw() +{ + int row, col, bits=0; + + while (1 << ++bits < maximum); + read_shorts (raw_image, raw_width*raw_height); + for (row=0; row < raw_height; row++) + for (col=0; col < raw_width; col++) + if ((RAW(row,col) >>= load_flags) >> bits + && (unsigned) (row-top_margin) < height + && (unsigned) (col-left_margin) < width) derror(); +} + +void CLASS sinar_4shot_load_raw() +{ + ushort *pixel; + unsigned shot, row, col, r, c; + + if (raw_image) { + shot = LIM (shot_select, 1, 4) - 1; + fseek (ifp, data_offset + shot*4, SEEK_SET); + fseek (ifp, get4(), SEEK_SET); + unpacked_load_raw(); + return; + } + pixel = (ushort *) calloc (raw_width, sizeof *pixel); + merror (pixel, "sinar_4shot_load_raw()"); + for (shot=0; shot < 4; shot++) { + fseek (ifp, data_offset + shot*4, SEEK_SET); + fseek (ifp, get4(), SEEK_SET); + for (row=0; row < raw_height; row++) { + read_shorts (pixel, raw_width); + if ((r = row-top_margin - (shot >> 1 & 1)) >= height) continue; + for (col=0; col < raw_width; col++) { + if ((c = col-left_margin - (shot & 1)) >= width) continue; + image[r*width+c][(row & 1)*3 ^ (~col & 1)] = pixel[col]; + } + } + } + free (pixel); + mix_green = 1; +} + +void CLASS imacon_full_load_raw() +{ + int row, col; + + if (!image) return; + for (row=0; row < height; row++) + for (col=0; col < width; col++) + read_shorts (image[row*width+col], 3); +} + +void CLASS packed_load_raw() +{ + int vbits=0, bwide, rbits, bite, half, irow, row, col, val, i; + UINT64 bitbuf=0; + + bwide = raw_width * tiff_bps / 8; + bwide += bwide & load_flags >> 7; + rbits = bwide * 8 - raw_width * tiff_bps; + if (load_flags & 1) bwide = bwide * 16 / 15; + bite = 8 + (load_flags & 24); + half = (raw_height+1) >> 1; + for (irow=0; irow < raw_height; irow++) { + row = irow; + if (load_flags & 2 && + (row = irow % half * 2 + irow / half) == 1 && + load_flags & 4) { + if (vbits=0, tiff_compress) + fseek (ifp, data_offset - (-half*bwide & -2048), SEEK_SET); + else { + fseek (ifp, 0, SEEK_END); + fseek (ifp, ftell(ifp) >> 3 << 2, SEEK_SET); + } + } + for (col=0; col < raw_width; col++) { + for (vbits -= tiff_bps; vbits < 0; vbits += bite) { + bitbuf <<= bite; + for (i=0; i < bite; i+=8) + bitbuf |= (unsigned) (fgetc(ifp) << i); + } + val = bitbuf << (64-tiff_bps-vbits) >> (64-tiff_bps); + RAW(row,col ^ (load_flags >> 6 & 1)) = val; + if (load_flags & 1 && (col % 10) == 9 && fgetc(ifp) && + row < height+top_margin && col < width+left_margin) derror(); + } + vbits -= rbits; + } +} + +void CLASS nokia_load_raw() +{ + uchar *data, *dp; + int rev, dwide, row, col, c; + double sum[]={0,0}; + + rev = 3 * (order == 0x4949); + dwide = (raw_width * 5 + 1) / 4; + data = (uchar *) malloc (dwide*2); + merror (data, "nokia_load_raw()"); + for (row=0; row < raw_height; row++) { + if (fread (data+dwide, 1, dwide, ifp) < dwide) derror(); + FORC(dwide) data[c] = data[dwide+(c ^ rev)]; + for (dp=data, col=0; col < raw_width; dp+=5, col+=4) + FORC4 RAW(row,col+c) = (dp[c] << 2) | (dp[4] >> (c << 1) & 3); + } + free (data); + maximum = 0x3ff; + if (strcmp(make,"OmniVision")) return; + row = raw_height/2; + FORC(width-1) { + sum[ c & 1] += SQR(RAW(row,c)-RAW(row+1,c+1)); + sum[~c & 1] += SQR(RAW(row+1,c)-RAW(row,c+1)); + } + if (sum[1] > sum[0]) filters = 0x4b4b4b4b; +} + +void CLASS canon_rmf_load_raw() +{ + int row, col, bits, orow, ocol, c; + + for (row=0; row < raw_height; row++) + for (col=0; col < raw_width-2; col+=3) { + bits = get4(); + FORC3 { + orow = row; + if ((ocol = col+c-4) < 0) { + ocol += raw_width; + if ((orow -= 2) < 0) + orow += raw_height; + } + RAW(orow,ocol) = curve[bits >> (10*c+2) & 0x3ff]; + } + } + maximum = curve[0x3ff]; +} + +unsigned CLASS pana_bits_t::operator() (int nbits) +{ +/*RT static uchar buf[0x4000]; */ +/*RT static int vbits;*/ + int byte; + + if (!nbits) return vbits=0; + if (!vbits) { + fread (buf+load_flags, 1, 0x4000-load_flags, ifp); + fread (buf, 1, load_flags, ifp); + } + vbits = (vbits - nbits) & 0x1ffff; + byte = vbits >> 3 ^ 0x3ff0; + return (buf[byte] | buf[byte+1] << 8) >> (vbits & 7) & ~(-1 << nbits); +} + +void CLASS panasonic_load_raw() +{ + int row, col, i, j, sh=0, pred[2], nonz[2]; + + pana_bits(0); + for (row=0; row < height; row++) + for (col=0; col < raw_width; col++) { + if ((i = col % 14) == 0) + pred[0] = pred[1] = nonz[0] = nonz[1] = 0; + if (i % 3 == 2) sh = 4 >> (3 - pana_bits(2)); + if (nonz[i & 1]) { + if ((j = pana_bits(8))) { + if ((pred[i & 1] -= 0x80 << sh) < 0 || sh == 4) + pred[i & 1] &= ~(-1 << sh); + pred[i & 1] += j << sh; + } + } else if ((nonz[i & 1] = pana_bits(8)) || i > 11) + pred[i & 1] = nonz[i & 1] << 4 | pana_bits(4); + if ((RAW(row,col) = pred[col & 1]) > 4098 && col < width) derror(); + } +} + +void CLASS olympus_load_raw() +{ + ushort huff[4096]; + int row, col, nbits, sign, low, high, i, c, w, n, nw; + int acarry[2][3], *carry, pred, diff; + + huff[n=0] = 0xc0c; + for (i=12; i--; ) + FORC(2048 >> i) huff[++n] = (i+1) << 8 | i; + fseek (ifp, 7, SEEK_CUR); + getbits(-1); + for (row=0; row < height; row++) { + memset (acarry, 0, sizeof acarry); + for (col=0; col < raw_width; col++) { + carry = acarry[col & 1]; + i = 2 * (carry[2] < 3); + for (nbits=2+i; (ushort) carry[0] >> (nbits+i); nbits++); + low = (sign = getbits(3)) & 3; + sign = sign << 29 >> 31; + if ((high = getbithuff(12,huff)) == 12) + high = getbits(16-nbits) >> 1; + carry[0] = (high << nbits) | getbits(nbits); + diff = (carry[0] ^ sign) + carry[1]; + carry[1] = (diff*3 + carry[1]) >> 5; + carry[2] = carry[0] > 16 ? 0 : carry[2]+1; + if (col >= width) continue; + if (row < 2 && col < 2) pred = 0; + else if (row < 2) pred = RAW(row,col-2); + else if (col < 2) pred = RAW(row-2,col); + else { + w = RAW(row,col-2); + n = RAW(row-2,col); + nw = RAW(row-2,col-2); + if ((w < nw && nw < n) || (n < nw && nw < w)) { + if (ABS(w-nw) > 32 || ABS(n-nw) > 32) + pred = w + n - nw; + else pred = (w + n) >> 1; + } else pred = ABS(w-nw) > ABS(n-nw) ? w : n; + } + if ((RAW(row,col) = pred + ((diff << 2) | low)) >> 12) derror(); + } + } +} + +void CLASS minolta_rd175_load_raw() +{ + uchar pixel[768]; + unsigned irow, box, row, col; + + for (irow=0; irow < 1481; irow++) { + if (fread (pixel, 1, 768, ifp) < 768) derror(); + box = irow / 82; + row = irow % 82 * 12 + ((box < 12) ? box | 1 : (box-12)*2); + switch (irow) { + case 1477: case 1479: continue; + case 1476: row = 984; break; + case 1480: row = 985; break; + case 1478: row = 985; box = 1; + } + if ((box < 12) && (box & 1)) { + for (col=0; col < 1533; col++, row ^= 1) + if (col != 1) RAW(row,col) = (col+1) & 2 ? + pixel[col/2-1] + pixel[col/2+1] : pixel[col/2] << 1; + RAW(row,1) = pixel[1] << 1; + RAW(row,1533) = pixel[765] << 1; + } else + for (col=row & 1; col < 1534; col+=2) + RAW(row,col) = pixel[col/2] << 1; + } + maximum = 0xff << 1; +} + +void CLASS quicktake_100_load_raw() +{ + uchar pixel[484][644]; + static const short gstep[16] = + { -89,-60,-44,-32,-22,-15,-8,-2,2,8,15,22,32,44,60,89 }; + static const short rstep[6][4] = + { { -3,-1,1,3 }, { -5,-1,1,5 }, { -8,-2,2,8 }, + { -13,-3,3,13 }, { -19,-4,4,19 }, { -28,-6,6,28 } }; + static const short curve[256] = + { 0,1,2,3,4,5,6,7,8,9,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27, + 28,29,30,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,53, + 54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,74,75,76,77,78, + 79,80,81,82,83,84,86,88,90,92,94,97,99,101,103,105,107,110,112,114,116, + 118,120,123,125,127,129,131,134,136,138,140,142,144,147,149,151,153,155, + 158,160,162,164,166,168,171,173,175,177,179,181,184,186,188,190,192,195, + 197,199,201,203,205,208,210,212,214,216,218,221,223,226,230,235,239,244, + 248,252,257,261,265,270,274,278,283,287,291,296,300,305,309,313,318,322, + 326,331,335,339,344,348,352,357,361,365,370,374,379,383,387,392,396,400, + 405,409,413,418,422,426,431,435,440,444,448,453,457,461,466,470,474,479, + 483,487,492,496,500,508,519,531,542,553,564,575,587,598,609,620,631,643, + 654,665,676,687,698,710,721,732,743,754,766,777,788,799,810,822,833,844, + 855,866,878,889,900,911,922,933,945,956,967,978,989,1001,1012,1023 }; + int rb, row, col, sharp, val=0; + + getbits(-1); + memset (pixel, 0x80, sizeof pixel); + for (row=2; row < height+2; row++) { + for (col=2+(row & 1); col < width+2; col+=2) { + val = ((pixel[row-1][col-1] + 2*pixel[row-1][col+1] + + pixel[row][col-2]) >> 2) + gstep[getbits(4)]; + pixel[row][col] = val = LIM(val,0,255); + if (col < 4) + pixel[row][col-2] = pixel[row+1][~row & 1] = val; + if (row == 2) + pixel[row-1][col+1] = pixel[row-1][col+3] = val; + } + pixel[row][col] = val; + } + for (rb=0; rb < 2; rb++) + for (row=2+rb; row < height+2; row+=2) + for (col=3-(row & 1); col < width+2; col+=2) { + if (row < 4 || col < 4) sharp = 2; + else { + val = ABS(pixel[row-2][col] - pixel[row][col-2]) + + ABS(pixel[row-2][col] - pixel[row-2][col-2]) + + ABS(pixel[row][col-2] - pixel[row-2][col-2]); + sharp = val < 4 ? 0 : val < 8 ? 1 : val < 16 ? 2 : + val < 32 ? 3 : val < 48 ? 4 : 5; + } + val = ((pixel[row-2][col] + pixel[row][col-2]) >> 1) + + rstep[sharp][getbits(2)]; + pixel[row][col] = val = LIM(val,0,255); + if (row < 4) pixel[row-2][col+2] = val; + if (col < 4) pixel[row+2][col-2] = val; + } + for (row=2; row < height+2; row++) + for (col=3-(row & 1); col < width+2; col+=2) { + val = ((pixel[row][col-1] + (pixel[row][col] << 2) + + pixel[row][col+1]) >> 1) - 0x100; + pixel[row][col] = LIM(val,0,255); + } + for (row=0; row < height; row++) + for (col=0; col < width; col++) + RAW(row,col) = curve[pixel[row+2][col+2]]; + maximum = 0x3ff; +} + +#define radc_token(tree) ((signed char) getbithuff(8,huff[tree])) + +#define FORYX for (y=1; y < 3; y++) for (x=col+1; x >= col; x--) + +#define PREDICTOR (c ? (buf[c][y-1][x] + buf[c][y][x+1]) / 2 \ +: (buf[c][y-1][x+1] + 2*buf[c][y-1][x] + buf[c][y][x+1]) / 4) + +void CLASS kodak_radc_load_raw() +{ + static const char src[] = { + 1,1, 2,3, 3,4, 4,2, 5,7, 6,5, 7,6, 7,8, + 1,0, 2,1, 3,3, 4,4, 5,2, 6,7, 7,6, 8,5, 8,8, + 2,1, 2,3, 3,0, 3,2, 3,4, 4,6, 5,5, 6,7, 6,8, + 2,0, 2,1, 2,3, 3,2, 4,4, 5,6, 6,7, 7,5, 7,8, + 2,1, 2,4, 3,0, 3,2, 3,3, 4,7, 5,5, 6,6, 6,8, + 2,3, 3,1, 3,2, 3,4, 3,5, 3,6, 4,7, 5,0, 5,8, + 2,3, 2,6, 3,0, 3,1, 4,4, 4,5, 4,7, 5,2, 5,8, + 2,4, 2,7, 3,3, 3,6, 4,1, 4,2, 4,5, 5,0, 5,8, + 2,6, 3,1, 3,3, 3,5, 3,7, 3,8, 4,0, 5,2, 5,4, + 2,0, 2,1, 3,2, 3,3, 4,4, 4,5, 5,6, 5,7, 4,8, + 1,0, 2,2, 2,-2, + 1,-3, 1,3, + 2,-17, 2,-5, 2,5, 2,17, + 2,-7, 2,2, 2,9, 2,18, + 2,-18, 2,-9, 2,-2, 2,7, + 2,-28, 2,28, 3,-49, 3,-9, 3,9, 4,49, 5,-79, 5,79, + 2,-1, 2,13, 2,26, 3,39, 4,-16, 5,55, 6,-37, 6,76, + 2,-26, 2,-13, 2,1, 3,-39, 4,16, 5,-55, 6,-76, 6,37 + }; + ushort huff[19][256]; + int row, col, tree, nreps, rep, step, i, c, s, r, x, y, val; + short last[3] = { 16,16,16 }, mul[3], buf[3][3][386]; + static const ushort pt[] = + { 0,0, 1280,1344, 2320,3616, 3328,8000, 4095,16383, 65535,16383 }; + + for (i=2; i < 12; i+=2) + for (c=pt[i-2]; c <= pt[i]; c++) + curve[c] = (float) + (c-pt[i-2]) / (pt[i]-pt[i-2]) * (pt[i+1]-pt[i-1]) + pt[i-1] + 0.5; + for (s=i=0; i < sizeof src; i+=2) + FORC(256 >> src[i]) + ((ushort *)huff)[s++] = src[i] << 8 | (uchar) src[i+1]; + s = kodak_cbpp == 243 ? 2 : 3; + FORC(256) huff[18][c] = (8-s) << 8 | c >> s << s | 1 << (s-1); + getbits(-1); + for (i=0; i < sizeof(buf)/sizeof(short); i++) + ((short *)buf)[i] = 2048; + for (row=0; row < height; row+=4) { + FORC3 mul[c] = getbits(6); + FORC3 { + val = ((0x1000000/last[c] + 0x7ff) >> 12) * mul[c]; + s = val > 65564 ? 10:12; + x = ~(-1 << (s-1)); + val <<= 12-s; + for (i=0; i < sizeof(buf[0])/sizeof(short); i++) + ((short *)buf[c])[i] = (((short *)buf[c])[i] * val + x) >> s; + last[c] = mul[c]; + for (r=0; r <= !c; r++) { + buf[c][1][width/2] = buf[c][2][width/2] = mul[c] << 7; + for (tree=1, col=width/2; col > 0; ) { + if ((tree = radc_token(tree))) { + col -= 2; + if (tree == 8) + FORYX buf[c][y][x] = (uchar) radc_token(18) * mul[c]; + else + FORYX buf[c][y][x] = radc_token(tree+10) * 16 + PREDICTOR; + } else + do { + nreps = (col > 2) ? radc_token(9) + 1 : 1; + for (rep=0; rep < 8 && rep < nreps && col > 0; rep++) { + col -= 2; + FORYX buf[c][y][x] = PREDICTOR; + if (rep & 1) { + step = radc_token(10) << 4; + FORYX buf[c][y][x] += step; + } + } + } while (nreps == 9); + } + for (y=0; y < 2; y++) + for (x=0; x < width/2; x++) { + val = (buf[c][y+1][x] << 4) / mul[c]; + if (val < 0) val = 0; + if (c) RAW(row+y*2+c-1,x*2+2-c) = val; + else RAW(row+r*2+y,x*2+y) = val; + } + memcpy (buf[c][0]+!c, buf[c][2], sizeof buf[c][0]-2*!c); + } + } + for (y=row; y < row+4; y++) + for (x=0; x < width; x++) + if ((x+y) & 1) { + r = x ? x-1 : x+1; + s = x+1 < width ? x+1 : x-1; + val = (RAW(y,x)-2048)*2 + (RAW(y,r)+RAW(y,s))/2; + if (val < 0) val = 0; + RAW(y,x) = val; + } + } + for (i=0; i < height*width; i++) + raw_image[i] = curve[raw_image[i]]; + maximum = 0x3fff; +} + +#undef FORYX +#undef PREDICTOR + +#ifdef NO_JPEG +void CLASS kodak_jpeg_load_raw() {} +void CLASS lossy_dng_load_raw() {} +#else + +METHODDEF(boolean) +fill_input_buffer (j_decompress_ptr cinfo) +{ +/*RT static uchar jpeg_buffer[4096]; */ + size_t nbytes; + + nbytes = fread (jpeg_buffer, 1, 4096, ifp); + swab ((char*)jpeg_buffer, (char*)jpeg_buffer, nbytes); + cinfo->src->next_input_byte = jpeg_buffer; + cinfo->src->bytes_in_buffer = nbytes; + return TRUE; +} + +void CLASS kodak_jpeg_load_raw() +{ + struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr jerr; + JSAMPARRAY buf; + JSAMPLE (*pixel)[3]; + int row, col; + + cinfo.err = jpeg_std_error (&jerr); + jpeg_create_decompress (&cinfo); + jpeg_stdio_src (&cinfo, ifp); + cinfo.src->fill_input_buffer = fill_input_buffer; + jpeg_read_header (&cinfo, TRUE); + jpeg_start_decompress (&cinfo); + if ((cinfo.output_width != width ) || + (cinfo.output_height*2 != height ) || + (cinfo.output_components != 3 )) { + fprintf (stderr,_("%s: incorrect JPEG dimensions\n"), ifname); + jpeg_destroy_decompress (&cinfo); + longjmp (failure, 3); + } + buf = (*cinfo.mem->alloc_sarray) + ((j_common_ptr) &cinfo, JPOOL_IMAGE, width*3, 1); + + while (cinfo.output_scanline < cinfo.output_height) { + row = cinfo.output_scanline * 2; + jpeg_read_scanlines (&cinfo, buf, 1); + pixel = (JSAMPLE (*)[3]) buf[0]; + for (col=0; col < width; col+=2) { + RAW(row+0,col+0) = pixel[col+0][1] << 1; + RAW(row+1,col+1) = pixel[col+1][1] << 1; + RAW(row+0,col+1) = pixel[col][0] + pixel[col+1][0]; + RAW(row+1,col+0) = pixel[col][2] + pixel[col+1][2]; + } + } + jpeg_finish_decompress (&cinfo); + jpeg_destroy_decompress (&cinfo); + maximum = 0xff << 1; +} + +void CLASS gamma_curve (double pwr, double ts, int mode, int imax); + +void CLASS lossy_dng_load_raw() +{ + struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr jerr; + JSAMPARRAY buf; + JSAMPLE (*pixel)[3]; + unsigned sorder=order, ntags, opcode, deg, i, j, c; + unsigned save=data_offset-4, trow=0, tcol=0, row, col; + ushort cur[3][256]; + double coeff[9], tot; + + if (meta_offset) { + fseek (ifp, meta_offset, SEEK_SET); + order = 0x4d4d; + ntags = get4(); + while (ntags--) { + opcode = get4(); get4(); get4(); + if (opcode != 8) + { fseek (ifp, get4(), SEEK_CUR); continue; } + fseek (ifp, 20, SEEK_CUR); + if ((c = get4()) > 2) break; + fseek (ifp, 12, SEEK_CUR); + if ((deg = get4()) > 8) break; + for (i=0; i <= deg && i < 9; i++) + coeff[i] = getreal(12); + for (i=0; i < 256; i++) { + for (tot=j=0; j <= deg; j++) + tot += coeff[j] * pow(i/255.0, j); + cur[c][i] = tot*0xffff; + } + } + order = sorder; + } else { + gamma_curve (1/2.4, 12.92, 1, 255); + FORC3 memcpy (cur[c], curve, sizeof cur[0]); + } + cinfo.err = jpeg_std_error (&jerr); + jpeg_create_decompress (&cinfo); + while (trow < raw_height) { + fseek (ifp, save+=4, SEEK_SET); + if (tile_length < INT_MAX) + fseek (ifp, get4(), SEEK_SET); + jpeg_stdio_src (&cinfo, ifp); + jpeg_read_header (&cinfo, TRUE); + jpeg_start_decompress (&cinfo); + buf = (*cinfo.mem->alloc_sarray) + ((j_common_ptr) &cinfo, JPOOL_IMAGE, cinfo.output_width*3, 1); + while (cinfo.output_scanline < cinfo.output_height && + (row = trow + cinfo.output_scanline) < height) { + jpeg_read_scanlines (&cinfo, buf, 1); + pixel = (JSAMPLE (*)[3]) buf[0]; + for (col=0; col < cinfo.output_width && tcol+col < width; col++) { + FORC3 image[row*width+tcol+col][c] = cur[c][pixel[col][c]]; + } + } + jpeg_abort_decompress (&cinfo); + if ((tcol += tile_width) >= raw_width) + trow += tile_length + (tcol = 0); + } + jpeg_destroy_decompress (&cinfo); + maximum = 0xffff; +} +#endif + +void CLASS kodak_dc120_load_raw() +{ + static const int mul[4] = { 162, 192, 187, 92 }; + static const int add[4] = { 0, 636, 424, 212 }; + uchar pixel[848]; + int row, shift, col; + + for (row=0; row < height; row++) { + if (fread (pixel, 1, 848, ifp) < 848) derror(); + shift = row * mul[row & 3] + add[row & 3]; + for (col=0; col < width; col++) + RAW(row,col) = (ushort) pixel[(col + shift) % 848]; + } + maximum = 0xff; +} + +void CLASS eight_bit_load_raw() +{ + uchar *pixel; + unsigned row, col; + + pixel = (uchar *) calloc (raw_width, sizeof *pixel); + merror (pixel, "eight_bit_load_raw()"); + for (row=0; row < raw_height; row++) { + if (fread (pixel, 1, raw_width, ifp) < raw_width) derror(); + for (col=0; col < raw_width; col++) + RAW(row,col) = curve[pixel[col]]; + } + free (pixel); + maximum = curve[0xff]; +} + +void CLASS kodak_c330_load_raw() +{ + uchar *pixel; + int row, col, y, cb, cr, rgb[3], c; + + pixel = (uchar *) calloc (raw_width, 2*sizeof *pixel); + merror (pixel, "kodak_c330_load_raw()"); + for (row=0; row < height; row++) { + if (fread (pixel, raw_width, 2, ifp) < 2) derror(); + if (load_flags && (row & 31) == 31) + fseek (ifp, raw_width*32, SEEK_CUR); + for (col=0; col < width; col++) { + y = pixel[col*2]; + cb = pixel[(col*2 & -4) | 1] - 128; + cr = pixel[(col*2 & -4) | 3] - 128; + rgb[1] = y - ((cb + cr + 2) >> 2); + rgb[2] = rgb[1] + cb; + rgb[0] = rgb[1] + cr; + FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,255)]; + } + } + free (pixel); + maximum = curve[0xff]; +} + +void CLASS kodak_c603_load_raw() +{ + uchar *pixel; + int row, col, y, cb, cr, rgb[3], c; + + pixel = (uchar *) calloc (raw_width, 3*sizeof *pixel); + merror (pixel, "kodak_c603_load_raw()"); + for (row=0; row < height; row++) { + if (~row & 1) + if (fread (pixel, raw_width, 3, ifp) < 3) derror(); + for (col=0; col < width; col++) { + y = pixel[width*2*(row & 1) + col]; + cb = pixel[width + (col & -2)] - 128; + cr = pixel[width + (col & -2)+1] - 128; + rgb[1] = y - ((cb + cr + 2) >> 2); + rgb[2] = rgb[1] + cb; + rgb[0] = rgb[1] + cr; + FORC3 image[row*width+col][c] = curve[LIM(rgb[c],0,255)]; + } + } + free (pixel); + maximum = curve[0xff]; +} + +void CLASS kodak_262_load_raw() +{ + static const uchar kodak_tree[2][26] = + { { 0,1,5,1,1,2,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9 }, + { 0,3,1,1,1,1,1,2,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9 } }; + ushort *huff[2]; + uchar *pixel; + int *strip, ns, c, row, col, chess, pi=0, pi1, pi2, pred, val; + + FORC(2) huff[c] = make_decoder (kodak_tree[c]); + ns = (raw_height+63) >> 5; + pixel = (uchar *) malloc (raw_width*32 + ns*4); + merror (pixel, "kodak_262_load_raw()"); + strip = (int *) (pixel + raw_width*32); + order = 0x4d4d; + FORC(ns) strip[c] = get4(); + for (row=0; row < raw_height; row++) { + if ((row & 31) == 0) { + fseek (ifp, strip[row >> 5], SEEK_SET); + getbits(-1); + pi = 0; + } + for (col=0; col < raw_width; col++) { + chess = (row + col) & 1; + pi1 = chess ? pi-2 : pi-raw_width-1; + pi2 = chess ? pi-2*raw_width : pi-raw_width+1; + if (col <= chess) pi1 = -1; + if (pi1 < 0) pi1 = pi2; + if (pi2 < 0) pi2 = pi1; + if (pi1 < 0 && col > 1) pi1 = pi2 = pi-2; + pred = (pi1 < 0) ? 0 : (pixel[pi1] + pixel[pi2]) >> 1; + pixel[pi] = val = pred + ljpeg_diff (huff[chess]); + if (val >> 8) derror(); + val = curve[pixel[pi++]]; + RAW(row,col) = val; + } + } + free (pixel); + FORC(2) free (huff[c]); +} + +int CLASS kodak_65000_decode (short *out, int bsize) +{ + uchar c, blen[768]; + ushort raw[6]; + INT64 bitbuf=0; + int save, bits=0, i, j, len, diff; + + save = ftell(ifp); + bsize = (bsize + 3) & -4; + for (i=0; i < bsize; i+=2) { + c = fgetc(ifp); + if ((blen[i ] = c & 15) > 12 || + (blen[i+1] = c >> 4) > 12 ) { + fseek (ifp, save, SEEK_SET); + for (i=0; i < bsize; i+=8) { + read_shorts (raw, 6); + out[i ] = raw[0] >> 12 << 8 | raw[2] >> 12 << 4 | raw[4] >> 12; + out[i+1] = raw[1] >> 12 << 8 | raw[3] >> 12 << 4 | raw[5] >> 12; + for (j=0; j < 6; j++) + out[i+2+j] = raw[j] & 0xfff; + } + return 1; + } + } + if ((bsize & 7) == 4) { + bitbuf = fgetc(ifp) << 8; + bitbuf += fgetc(ifp); + bits = 16; + } + for (i=0; i < bsize; i++) { + len = blen[i]; + if (bits < len) { + for (j=0; j < 32; j+=8) + bitbuf += (INT64) fgetc(ifp) << (bits+(j^8)); + bits += 32; + } + diff = bitbuf & (0xffff >> (16-len)); + bitbuf >>= len; + bits -= len; + if ((diff & (1 << (len-1))) == 0) + diff -= (1 << len) - 1; + out[i] = diff; + } + return 0; +} + +void CLASS kodak_65000_load_raw() +{ + short buf[256]; + int row, col, len, pred[2], ret, i; + + for (row=0; row < height; row++) + for (col=0; col < width; col+=256) { + 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(); + } +} + +void CLASS kodak_ycbcr_load_raw() +{ + short buf[384], *bp; + int row, col, len, c, i, j, k, y[2][2], cb, cr, rgb[3]; + ushort *ip; + + if (!image) return; + for (row=0; row < height; row+=2) + for (col=0; col < width; col+=128) { + len = MIN (128, width-col); + kodak_65000_decode (buf, len*3); + y[0][1] = y[1][1] = cb = cr = 0; + for (bp=buf, i=0; i < len; i+=2, bp+=2) { + cb += bp[4]; + cr += bp[5]; + rgb[1] = -((cb + cr + 2) >> 2); + rgb[2] = rgb[1] + cb; + rgb[0] = rgb[1] + cr; + for (j=0; j < 2; j++) + for (k=0; k < 2; k++) { + if ((y[j][k] = y[j][k^1] + *bp++) >> 10) derror(); + ip = image[(row+j)*width + col+i+k]; + FORC3 ip[c] = curve[LIM(y[j][k]+rgb[c], 0, 0xfff)]; + } + } + } +} + +void CLASS kodak_rgb_load_raw() +{ + short buf[768], *bp; + int row, col, len, c, i, rgb[3]; + ushort *ip=image[0]; + + for (row=0; row < height; row++) + for (col=0; col < width; col+=256) { + len = MIN (256, width-col); + kodak_65000_decode (buf, len*3); + memset (rgb, 0, sizeof rgb); + for (bp=buf, i=0; i < len; i++, ip+=4) + FORC3 if ((ip[c] = rgb[c] += *bp++) >> 12) derror(); + } +} + +void CLASS kodak_thumb_load_raw() +{ + int row, col; + colors = thumb_misc >> 5; + for (row=0; row < height; row++) + for (col=0; col < width; col++) + read_shorts (image[row*width+col], colors); + maximum = (1 << (thumb_misc & 31)) - 1; +} + +void CLASS sony_decrypt_t::operator()(unsigned *data, int len, int start, int key) +{ +/*RT static unsigned pad[128], p;*/ + if (start) { + for (p=0; p < 4; p++) + pad[p] = key = key * 48828125 + 1; + pad[3] = pad[3] << 1 | (pad[0]^pad[2]) >> 31; + for (p=4; p < 127; p++) + pad[p] = (pad[p-4]^pad[p-2]) << 1 | (pad[p-3]^pad[p-1]) >> 31; + for (p=0; p < 127; p++) + pad[p] = htonl(pad[p]); + } + while (len-- && p++) + *data++ ^= pad[(p-1) & 127] = pad[p & 127] ^ pad[(p+64) & 127]; +} + +void CLASS sony_load_raw() +{ + uchar head[40]; + ushort *pixel; + unsigned i, key, row, col; + + fseek (ifp, 200896, SEEK_SET); + fseek (ifp, (unsigned) fgetc(ifp)*4 - 1, SEEK_CUR); + order = 0x4d4d; + key = get4(); + fseek (ifp, 164600, SEEK_SET); + fread (head, 1, 40, ifp); + sony_decrypt ((unsigned *) head, 10, 1, key); + for (i=26; i-- > 22; ) + key = key << 8 | head[i]; + fseek (ifp, data_offset, SEEK_SET); + for (row=0; row < raw_height; row++) { + pixel = raw_image + row*raw_width; + if (fread (pixel, 2, raw_width, ifp) < raw_width) derror(); + sony_decrypt ((unsigned *) pixel, raw_width/2, !row, key); + for (col=0; col < raw_width; col++) + if ((pixel[col] = ntohs(pixel[col])) >> 14) derror(); + } + maximum = 0x3ff0; +} + +void CLASS sony_arw_load_raw() +{ + ushort huff[32770]; + static const ushort tab[18] = + { 0xf11,0xf10,0xe0f,0xd0e,0xc0d,0xb0c,0xa0b,0x90a,0x809, + 0x708,0x607,0x506,0x405,0x304,0x303,0x300,0x202,0x201 }; + int i, c, n, col, row, sum=0; + + huff[0] = 15; + for (n=i=0; i < 18; i++) + FORC(32768 >> (tab[i] >> 8)) huff[++n] = tab[i]; + getbits(-1); + for (col = raw_width; col--; ) + for (row=0; row < raw_height+1; row+=2) { + if (row == raw_height) row = 1; + if ((sum += ljpeg_diff(huff)) >> 12) derror(); + if (row < height) RAW(row,col) = sum; + } +} + +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; + } + } + free (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. +} + +void CLASS samsung_load_raw() +{ + int row, col, c, i, dir, op[4], len[4]; + + order = 0x4949; + 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); + 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); + FORC4 switch (op[c]) { + case 3: len[c] = ph1_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)) + + (dir ? RAW(row+(~c | -2),col+c) : col ? RAW(row,col+(c | -2)) : 128); + if (c == 14) c = -1; + } + } + } + for (row=0; row < raw_height-1; row+=2) + for (col=0; col < raw_width-1; col+=2) + SWAP (RAW(row,col+1), RAW(row+1,col)); +} + +void CLASS samsung2_load_raw() +{ + static const ushort tab[14] = + { 0x304,0x307,0x206,0x205,0x403,0x600,0x709, + 0x80a,0x90b,0xa0c,0xa0d,0x501,0x408,0x402 }; + ushort huff[1026], vpred[2][2] = {{0,0},{0,0}}, hpred[2]; + int i, c, n, row, col, diff; + + huff[0] = 10; + for (n=i=0; i < 14; i++) + FORC(1024 >> (tab[i] >> 8)) huff[++n] = tab[i]; + getbits(-1); + for (row=0; row < raw_height; row++) + for (col=0; col < raw_width; col++) { + diff = ljpeg_diff (huff); + if (col < 2) hpred[col] = vpred[row & 1][col] += diff; + else hpred[col & 1] += diff; + RAW(row,col) = hpred[col & 1]; + if (hpred[col & 1] >> tiff_bps) derror(); + } +} + +void CLASS samsung3_load_raw() +{ + int opt, init, mag, pmode, row, tab, col, pred, diff, i, c; + ushort lent[3][2], len[4], *prow[2]; + + order = 0x4949; + fseek (ifp, 9, SEEK_CUR); + opt = fgetc(ifp); + init = (get2(),get2()); + for (row=0; row < raw_height; row++) { + fseek (ifp, (data_offset-ftell(ifp)) & 15, SEEK_CUR); + ph1_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); + } + 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); + FORC4 { + i = ((row & 1) << 1 | (c & 1)) % 3; + len[c] = len[c] < 3 ? lent[i][0]-'1'+"120"[len[c]] : ph1_bits(4); + lent[i][0] = lent[i][1]; + lent[i][1] = len[c]; + } + } + FORC(16) { + col = tab + (((c & 7) << 1)^(c >> 3)^(row & 1)); + pred = (pmode == 7 || row < 2) + ? (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]); + if (diff >> (i-1)) diff -= 1 << i; + diff = diff * (mag*2+1) + mag; + RAW(row,col) = pred + diff; + } + } + } +} + +#define HOLE(row) ((holes >> (((row) - raw_height) & 7)) & 1) + +/* Kudos to Rich Taylor for figuring out SMaL's compression algorithm. */ +void CLASS smal_decode_segment (unsigned seg[2][2], int holes) +{ + uchar hist[3][13] = { + { 7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0 }, + { 7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0 }, + { 3, 3, 0, 0, 63, 47, 31, 15, 0 } }; + int low, high=0xff, carry=0, nbits=8; + int pix, s, count, bin, next, i, sym[3]; + uchar diff, pred[]={0,0}; + ushort data=0, range=0; + + fseek (ifp, seg[0][1]+1, SEEK_SET); + getbits(-1); + for (pix=seg[0][0]; pix < seg[1][0]; pix++) { + for (s=0; s < 3; s++) { + data = data << nbits | getbits(nbits); + if (carry < 0) + carry = (nbits += carry+1) < 1 ? nbits-1 : 0; + while (--nbits >= 0) + if ((data >> nbits & 0xff) == 0xff) break; + if (nbits > 0) + data = ((data & ((1 << (nbits-1)) - 1)) << 1) | + ((data + (((data & (1 << (nbits-1)))) << 1)) & (-1 << nbits)); + if (nbits >= 0) { + data += getbits(1); + carry = nbits - 8; + } + count = ((((data-range+1) & 0xffff) << 2) - 1) / (high >> 4); + for (bin=0; hist[s][bin+5] > count; bin++); + low = hist[s][bin+5] * (high >> 4) >> 2; + if (bin) high = hist[s][bin+4] * (high >> 4) >> 2; + high -= low; + for (nbits=0; high << nbits < 128; nbits++); + range = (range+low) << nbits; + high <<= nbits; + next = hist[s][1]; + if (++hist[s][2] > hist[s][3]) { + next = (next+1) & hist[s][0]; + hist[s][3] = (hist[s][next+4] - hist[s][next+5]) >> 2; + hist[s][2] = 1; + } + if (hist[s][hist[s][1]+4] - hist[s][hist[s][1]+5] > 1) { + if (bin < hist[s][1]) + for (i=bin; i < hist[s][1]; i++) hist[s][i+5]--; + else if (next <= bin) + for (i=hist[s][1]; i < bin; i++) hist[s][i+5]++; + } + hist[s][1] = next; + sym[s] = bin; + } + diff = sym[2] << 5 | sym[1] << 2 | (sym[0] & 3); + if (sym[0] & 4) + diff = diff ? -diff : 0x80; + if (ftell(ifp) + 12 >= seg[1][1]) + diff = 0; + raw_image[pix] = pred[pix & 1] += diff; + if (!(pix & 1) && HOLE(pix / raw_width)) pix += 2; + } + maximum = 0xff; +} + +void CLASS smal_v6_load_raw() +{ + unsigned seg[2][2]; + + fseek (ifp, 16, SEEK_SET); + seg[0][0] = 0; + seg[0][1] = get2(); + seg[1][0] = raw_width * raw_height; + seg[1][1] = INT_MAX; + smal_decode_segment (seg, 0); +} + +int CLASS median4 (int *p) +{ + int min, max, sum, i; + + min = max = sum = p[0]; + for (i=1; i < 4; i++) { + sum += p[i]; + if (min > p[i]) min = p[i]; + if (max < p[i]) max = p[i]; + } + return (sum - min - max) >> 1; +} + +void CLASS fill_holes (int holes) +{ + int row, col, val[4]; + + for (row=2; row < height-2; row++) { + if (!HOLE(row)) continue; + for (col=1; col < width-1; col+=4) { + val[0] = RAW(row-1,col-1); + val[1] = RAW(row-1,col+1); + val[2] = RAW(row+1,col-1); + val[3] = RAW(row+1,col+1); + RAW(row,col) = median4(val); + } + for (col=2; col < width-2; col+=4) + if (HOLE(row-2) || HOLE(row+2)) + RAW(row,col) = (RAW(row,col-2) + RAW(row,col+2)) >> 1; + else { + val[0] = RAW(row,col-2); + val[1] = RAW(row,col+2); + val[2] = RAW(row-2,col); + val[3] = RAW(row+2,col); + RAW(row,col) = median4(val); + } + } +} + +void CLASS smal_v9_load_raw() +{ + unsigned seg[256][2], offset, nseg, holes, i; + + fseek (ifp, 67, SEEK_SET); + offset = get4(); + nseg = (uchar) fgetc(ifp); + fseek (ifp, offset, SEEK_SET); + for (i=0; i < nseg*2; i++) + ((unsigned *)seg)[i] = get4() + data_offset*(i & 1); + fseek (ifp, 78, SEEK_SET); + holes = fgetc(ifp); + fseek (ifp, 88, SEEK_SET); + seg[nseg][0] = raw_height * raw_width; + seg[nseg][1] = get4() + data_offset; + for (i=0; i < nseg; i++) + smal_decode_segment (seg+i, holes); + if (holes) fill_holes (holes); +} + +void CLASS redcine_load_raw() +{ +#ifndef NO_JASPER + int c, row, col; + jas_stream_t *in; + jas_image_t *jimg; + jas_matrix_t *jmat; + jas_seqent_t *data; + ushort *img, *pix; + + jas_init(); + in = jas_stream_fopen (ifname, "rb"); + jas_stream_seek (in, data_offset+20, SEEK_SET); + jimg = jas_image_decode (in, -1, 0); + if (!jimg) longjmp (failure, 3); + jmat = jas_matrix_create (height/2, width/2); + merror (jmat, "redcine_load_raw()"); + img = (ushort *) calloc ((height+2), (width+2)*2); + merror (img, "redcine_load_raw()"); + FORC4 { + jas_image_readcmpt (jimg, c, 0, 0, width/2, height/2, jmat); + data = jas_matrix_getref (jmat, 0, 0); + for (row = c >> 1; row < height; row+=2) + for (col = c & 1; col < width; col+=2) + img[(row+1)*(width+2)+col+1] = data[(row/2)*(width/2)+col/2]; + } + for (col=1; col <= width; col++) { + img[col] = img[2*(width+2)+col]; + img[(height+1)*(width+2)+col] = img[(height-1)*(width+2)+col]; + } + for (row=0; row < height+2; row++) { + img[row*(width+2)] = img[row*(width+2)+2]; + img[(row+1)*(width+2)-1] = img[(row+1)*(width+2)-3]; + } + for (row=1; row <= height; row++) { + pix = img + row*(width+2) + (col = 1 + (FC(row,1) & 1)); + for ( ; col <= width; col+=2, pix+=2) { + c = (((pix[0] - 0x800) << 3) + + pix[-(width+2)] + pix[width+2] + pix[-1] + pix[1]) >> 2; + pix[0] = LIM(c,0,4095); + } + } + for (row=0; row < height; row++) + for (col=0; col < width; col++) + RAW(row,col) = curve[img[(row+1)*(width+2)+col+1]]; + free (img); + jas_matrix_destroy (jmat); + jas_image_destroy (jimg); + jas_stream_close (in); +#endif +} + +/* RESTRICTED code starts here */ + +void CLASS foveon_decoder (unsigned size, unsigned code) +{ +/*RT static unsigned huff[1024];*/ + struct decode *cur; + int i, len; + + if (!code) { + for (i=0; i < size; i++) + huff[i] = get4(); + memset (first_decode, 0, sizeof first_decode); + free_decode = first_decode; + } + cur = free_decode++; + if (free_decode > first_decode+2048) { + fprintf (stderr,_("%s: decoder table overflow\n"), ifname); + longjmp (failure, 2); + } + if (code) + for (i=0; i < size; i++) + if (huff[i] == code) { + cur->leaf = i; + return; + } + if ((len = code >> 27) > 26) return; + code = (len+1) << 27 | (code & 0x3ffffff) << 1; + + cur->branch[0] = free_decode; + foveon_decoder (size, code); + cur->branch[1] = free_decode; + foveon_decoder (size, code+1); +} + +void CLASS foveon_thumb() +{ + unsigned bwide, row, col, bitbuf=0, bit=1, c, i; + char *buf; + struct decode *dindex; + short pred[3]; + + bwide = get4(); + fprintf (ofp, "P6\n%d %d\n255\n", thumb_width, thumb_height); + if (bwide > 0) { + if (bwide < thumb_width*3) return; + buf = (char *) malloc (bwide); + merror (buf, "foveon_thumb()"); + for (row=0; row < thumb_height; row++) { + fread (buf, 1, bwide, ifp); + fwrite (buf, 3, thumb_width, ofp); + } + free (buf); + return; + } + foveon_decoder (256, 0); + + for (row=0; row < thumb_height; row++) { + memset (pred, 0, sizeof pred); + if (!bit) get4(); + for (bit=col=0; col < thumb_width; col++) + FORC3 { + for (dindex=first_decode; dindex->branch[0]; ) { + if ((bit = (bit-1) & 31) == 31) + for (i=0; i < 4; i++) + bitbuf = (bitbuf << 8) + fgetc(ifp); + dindex = dindex->branch[bitbuf >> bit & 1]; + } + pred[c] += dindex->leaf; + fputc (pred[c], ofp); + } + } +} + +void CLASS foveon_sd_load_raw() +{ + struct decode *dindex; + short diff[1024]; + unsigned bitbuf=0; + int pred[3], row, col, bit=-1, c, i; + + read_shorts ((ushort *) diff, 1024); + if (!load_flags) foveon_decoder (1024, 0); + + for (row=0; row < height; row++) { + memset (pred, 0, sizeof pred); + if (!bit && !load_flags && atoi(model+2) < 14) get4(); + for (col=bit=0; col < width; col++) { + if (load_flags) { + bitbuf = get4(); + FORC3 pred[2-c] += diff[bitbuf >> c*10 & 0x3ff]; + } + else FORC3 { + for (dindex=first_decode; dindex->branch[0]; ) { + if ((bit = (bit-1) & 31) == 31) + for (i=0; i < 4; i++) + bitbuf = (bitbuf << 8) + fgetc(ifp); + dindex = dindex->branch[bitbuf >> bit & 1]; + } + pred[c] += diff[dindex->leaf]; + if (pred[c] >> 16 && ~pred[c] >> 16) derror(); + } + FORC3 image[row*width+col][c] = pred[c] < 0 ? 0 : pred[c]; + } + } +} + +void CLASS foveon_huff (ushort *huff) +{ + int i, j, clen, code; + + huff[0] = 8; + for (i=0; i < 13; i++) { + clen = getc(ifp); + code = getc(ifp); + for (j=0; j < 256 >> clen; ) + huff[code+ ++j] = clen << 8 | i; + } + get2(); +} + +void CLASS foveon_dp_load_raw() +{ + unsigned c, roff[4], row, col, diff; + ushort huff[512], vpred[2][2], hpred[2]; + + fseek (ifp, 8, SEEK_CUR); + foveon_huff (huff); + roff[0] = 48; + FORC3 roff[c+1] = -(-(roff[c] + get4()) & -16); + FORC3 { + fseek (ifp, data_offset+roff[c], SEEK_SET); + getbits(-1); + vpred[0][0] = vpred[0][1] = vpred[1][0] = vpred[1][1] = 512; + for (row=0; row < height; row++) { + for (col=0; col < width; col++) { + diff = ljpeg_diff(huff); + if (col < 2) hpred[col] = vpred[row & 1][col] += diff; + else hpred[col & 1] += diff; + image[row*width+col][c] = hpred[col & 1]; + } + } + } +} + +void CLASS foveon_load_camf() +{ + unsigned type, wide, high, i, j, row, col, diff; + ushort huff[258], vpred[2][2] = {{512,512},{512,512}}, hpred[2]; + + fseek (ifp, meta_offset, SEEK_SET); + type = get4(); get4(); get4(); + wide = get4(); + high = get4(); + if (type == 2) { + fread (meta_data, 1, meta_length, ifp); + for (i=0; i < meta_length; i++) { + high = (high * 1597 + 51749) % 244944; + wide = high * (INT64) 301593171 >> 24; + meta_data[i] ^= ((((high << 8) - wide) >> 1) + wide) >> 17; + } + } else if (type == 4) { + free (meta_data); + meta_data = (char *) malloc (meta_length = wide*high*3/2); + merror (meta_data, "foveon_load_camf()"); + foveon_huff (huff); + get4(); + getbits(-1); + for (j=row=0; row < high; row++) { + for (col=0; col < wide; col++) { + diff = ljpeg_diff(huff); + if (col < 2) hpred[col] = vpred[row & 1][col] += diff; + else hpred[col & 1] += diff; + if (col & 1) { + meta_data[j++] = hpred[0] >> 4; + meta_data[j++] = hpred[0] << 4 | hpred[1] >> 8; + meta_data[j++] = hpred[1]; + } + } + } + } else + fprintf (stderr,_("%s has unknown CAMF type %d.\n"), ifname, type); +} + +const char * CLASS foveon_camf_param (const char *block, const char *param) +{ + unsigned idx, num; + char *pos, *cp, *dp; + + for (idx=0; idx < meta_length; idx += sget4(pos+8)) { + pos = meta_data + idx; + if (strncmp (pos, "CMb", 3)) break; + if (pos[3] != 'P') continue; + if (strcmp (block, pos+sget4(pos+12))) continue; + cp = pos + sget4(pos+16); + num = sget4(cp); + dp = pos + sget4(cp+4); + while (num--) { + cp += 8; + if (!strcmp (param, dp+sget4(cp))) + return dp+sget4(cp+4); + } + } + return 0; +} + +void * CLASS foveon_camf_matrix (unsigned dim[3], const char *name) +{ + unsigned i, idx, type, ndim, size, *mat; + char *pos, *cp, *dp; + double dsize; + + for (idx=0; idx < meta_length; idx += sget4(pos+8)) { + pos = meta_data + idx; + if (strncmp (pos, "CMb", 3)) break; + if (pos[3] != 'M') continue; + if (strcmp (name, pos+sget4(pos+12))) continue; + dim[0] = dim[1] = dim[2] = 1; + cp = pos + sget4(pos+16); + type = sget4(cp); + if ((ndim = sget4(cp+4)) > 3) break; + dp = pos + sget4(cp+8); + for (i=ndim; i--; ) { + cp += 12; + dim[i] = sget4(cp); + } + if ((dsize = (double) dim[0]*dim[1]*dim[2]) > meta_length/4) break; + mat = (unsigned *) malloc ((size = dsize) * 4); + merror (mat, "foveon_camf_matrix()"); + for (i=0; i < size; i++) + if (type && type != 6) + mat[i] = sget4(dp + i*4); + else + mat[i] = sget4(dp + i*2) & 0xffff; + return mat; + } + fprintf (stderr,_("%s: \"%s\" matrix not found!\n"), ifname, name); + return 0; +} + +int CLASS foveon_fixed (void *ptr, int size, const char *name) +{ + void *dp; + unsigned dim[3]; + + if (!name) return 0; + dp = foveon_camf_matrix (dim, name); + if (!dp) return 0; + memcpy (ptr, dp, size*4); + free (dp); + return 1; +} + +float CLASS foveon_avg (short *pix, int range[2], float cfilt) +{ + int i; + float val, min=FLT_MAX, max=-FLT_MAX, sum=0; + + for (i=range[0]; i <= range[1]; i++) { + sum += val = pix[i*4] + (pix[i*4]-pix[(i-1)*4]) * cfilt; + if (min > val) min = val; + if (max < val) max = val; + } + if (range[1] - range[0] == 1) return sum/2; + return (sum - min - max) / (range[1] - range[0] - 1); +} + +short * CLASS foveon_make_curve (double max, double mul, double filt) +{ + short *curve; + unsigned i, size; + double x; + + if (!filt) filt = 0.8; + size = 4*M_PI*max / filt; + if (size == UINT_MAX) size--; + curve = (short *) calloc (size+1, sizeof *curve); + merror (curve, "foveon_make_curve()"); + curve[0] = size; + for (i=0; i < size; i++) { + x = i*filt/max/4; + curve[i+1] = (cos(x)+1)/2 * tanh(i*filt/mul) * mul + 0.5; + } + return curve; +} + +void CLASS foveon_make_curves + (short **curvep, float dq[3], float div[3], float filt) +{ + double mul[3], max=0; + int c; + + FORC3 mul[c] = dq[c]/div[c]; + FORC3 if (max < mul[c]) max = mul[c]; + FORC3 curvep[c] = foveon_make_curve (max, mul[c], filt); +} + +int CLASS foveon_apply_curve (short *curve, int i) +{ + if (abs(i) >= curve[0]) return 0; + return i < 0 ? -curve[1-i] : curve[1+i]; +} + +#define image ((short (*)[4]) image) + +void CLASS foveon_interpolate() +{ + static const short hood[] = { -1,-1, -1,0, -1,1, 0,-1, 0,1, 1,-1, 1,0, 1,1 }; + short *pix, prev[3], *curve[8], (*shrink)[3]; + float cfilt=0, ddft[3][3][2], ppm[3][3][3]; + float cam_xyz[3][3], correct[3][3], last[3][3], trans[3][3]; + float chroma_dq[3], color_dq[3], diag[3][3], div[3]; + float (*black)[3], (*sgain)[3], (*sgrow)[3]; + float fsum[3], val, frow, num; + int row, col, c, i, j, diff, sgx, irow, sum, min, max, limit; + int dscr[2][2], dstb[4], (*smrow[7])[3], total[4], ipix[3]; + int work[3][3], smlast, smred, smred_p=0, dev[3]; + int satlev[3], keep[4], active[4]; + unsigned dim[3], *badpix; + double dsum=0, trsum[3]; + char str[128]; + const char* cp; + + if (verbose) + fprintf (stderr,_("Foveon interpolation...\n")); + + foveon_load_camf(); + foveon_fixed (dscr, 4, "DarkShieldColRange"); + foveon_fixed (ppm[0][0], 27, "PostPolyMatrix"); + foveon_fixed (satlev, 3, "SaturationLevel"); + foveon_fixed (keep, 4, "KeepImageArea"); + foveon_fixed (active, 4, "ActiveImageArea"); + foveon_fixed (chroma_dq, 3, "ChromaDQ"); + foveon_fixed (color_dq, 3, + foveon_camf_param ("IncludeBlocks", "ColorDQ") ? + "ColorDQ" : "ColorDQCamRGB"); + if (foveon_camf_param ("IncludeBlocks", "ColumnFilter")) + foveon_fixed (&cfilt, 1, "ColumnFilter"); + + memset (ddft, 0, sizeof ddft); + if (!foveon_camf_param ("IncludeBlocks", "DarkDrift") + || !foveon_fixed (ddft[1][0], 12, "DarkDrift")) + for (i=0; i < 2; i++) { + foveon_fixed (dstb, 4, i ? "DarkShieldBottom":"DarkShieldTop"); + for (row = dstb[1]; row <= dstb[3]; row++) + for (col = dstb[0]; col <= dstb[2]; col++) + FORC3 ddft[i+1][c][1] += (short) image[row*width+col][c]; + FORC3 ddft[i+1][c][1] /= (dstb[3]-dstb[1]+1) * (dstb[2]-dstb[0]+1); + } + + if (!(cp = foveon_camf_param ("WhiteBalanceIlluminants", model2))) + { fprintf (stderr,_("%s: Invalid white balance \"%s\"\n"), ifname, model2); + return; } + foveon_fixed (cam_xyz, 9, cp); + foveon_fixed (correct, 9, + foveon_camf_param ("WhiteBalanceCorrections", model2)); + memset (last, 0, sizeof last); + for (i=0; i < 3; i++) + for (j=0; j < 3; j++) + FORC3 last[i][j] += correct[i][c] * cam_xyz[c][j]; + + #define LAST(x,y) last[(i+x)%3][(c+y)%3] + for (i=0; i < 3; i++) + FORC3 diag[c][i] = LAST(1,1)*LAST(2,2) - LAST(1,2)*LAST(2,1); + #undef LAST + FORC3 div[c] = diag[c][0]*0.3127 + diag[c][1]*0.329 + diag[c][2]*0.3583; + sprintf (str, "%sRGBNeutral", model2); + if (foveon_camf_param ("IncludeBlocks", str)) + foveon_fixed (div, 3, str); + num = 0; + FORC3 if (num < div[c]) num = div[c]; + FORC3 div[c] /= num; + + memset (trans, 0, sizeof trans); + for (i=0; i < 3; i++) + for (j=0; j < 3; j++) + FORC3 trans[i][j] += rgb_cam[i][c] * last[c][j] * div[j]; + FORC3 trsum[c] = trans[c][0] + trans[c][1] + trans[c][2]; + dsum = (6*trsum[0] + 11*trsum[1] + 3*trsum[2]) / 20; + for (i=0; i < 3; i++) + FORC3 last[i][c] = trans[i][c] * dsum / trsum[i]; + memset (trans, 0, sizeof trans); + for (i=0; i < 3; i++) + for (j=0; j < 3; j++) + FORC3 trans[i][j] += (i==c ? 32 : -1) * last[c][j] / 30; + + foveon_make_curves (curve, color_dq, div, cfilt); + FORC3 chroma_dq[c] /= 3; + foveon_make_curves (curve+3, chroma_dq, div, cfilt); + FORC3 dsum += chroma_dq[c] / div[c]; + curve[6] = foveon_make_curve (dsum, dsum, cfilt); + curve[7] = foveon_make_curve (dsum*2, dsum*2, cfilt); + + sgain = (float (*)[3]) foveon_camf_matrix (dim, "SpatialGain"); + if (!sgain) return; + sgrow = (float (*)[3]) calloc (dim[1], sizeof *sgrow); + sgx = (width + dim[1]-2) / (dim[1]-1); + + black = (float (*)[3]) calloc (height, sizeof *black); + for (row=0; row < height; row++) { + for (i=0; i < 6; i++) + ((float *)ddft[0])[i] = ((float *)ddft[1])[i] + + row / (height-1.0) * (((float *)ddft[2])[i] - ((float *)ddft[1])[i]); + FORC3 black[row][c] = + ( foveon_avg (image[row*width]+c, dscr[0], cfilt) + + foveon_avg (image[row*width]+c, dscr[1], cfilt) * 3 + - ddft[0][c][0] ) / 4 - ddft[0][c][1]; + } + memcpy (black, black+8, sizeof *black*8); + memcpy (black+height-11, black+height-22, 11*sizeof *black); + memcpy (last, black, sizeof last); + + for (row=1; row < height-1; row++) { + FORC3 if (last[1][c] > last[0][c]) { + if (last[1][c] > last[2][c]) + black[row][c] = (last[0][c] > last[2][c]) ? last[0][c]:last[2][c]; + } else + if (last[1][c] < last[2][c]) + black[row][c] = (last[0][c] < last[2][c]) ? last[0][c]:last[2][c]; + memmove (last, last+1, 2*sizeof last[0]); + memcpy (last[2], black[row+1], sizeof last[2]); + } + FORC3 black[row][c] = (last[0][c] + last[1][c])/2; + FORC3 black[0][c] = (black[1][c] + black[3][c])/2; + + val = 1 - exp(-1/24.0); + memcpy (fsum, black, sizeof fsum); + for (row=1; row < height; row++) + FORC3 fsum[c] += black[row][c] = + (black[row][c] - black[row-1][c])*val + black[row-1][c]; + memcpy (last[0], black[height-1], sizeof last[0]); + FORC3 fsum[c] /= height; + for (row = height; row--; ) + FORC3 last[0][c] = black[row][c] = + (black[row][c] - fsum[c] - last[0][c])*val + last[0][c]; + + memset (total, 0, sizeof total); + for (row=2; row < height; row+=4) + for (col=2; col < width; col+=4) { + FORC3 total[c] += (short) image[row*width+col][c]; + total[3]++; + } + for (row=0; row < height; row++) + FORC3 black[row][c] += fsum[c]/2 + total[c]/(total[3]*100.0); + + for (row=0; row < height; row++) { + for (i=0; i < 6; i++) + ((float *)ddft[0])[i] = ((float *)ddft[1])[i] + + row / (height-1.0) * (((float *)ddft[2])[i] - ((float *)ddft[1])[i]); + pix = image[row*width]; + memcpy (prev, pix, sizeof prev); + frow = row / (height-1.0) * (dim[2]-1); + if ((irow = frow) == dim[2]-1) irow--; + frow -= irow; + for (i=0; i < dim[1]; i++) + FORC3 sgrow[i][c] = sgain[ irow *dim[1]+i][c] * (1-frow) + + sgain[(irow+1)*dim[1]+i][c] * frow; + for (col=0; col < width; col++) { + FORC3 { + diff = pix[c] - prev[c]; + prev[c] = pix[c]; + ipix[c] = pix[c] + floor ((diff + (diff*diff >> 14)) * cfilt + - ddft[0][c][1] - ddft[0][c][0] * ((float) col/width - 0.5) + - black[row][c] ); + } + FORC3 { + work[0][c] = ipix[c] * ipix[c] >> 14; + work[2][c] = ipix[c] * work[0][c] >> 14; + work[1][2-c] = ipix[(c+1) % 3] * ipix[(c+2) % 3] >> 14; + } + FORC3 { + for (val=i=0; i < 3; i++) + for ( j=0; j < 3; j++) + val += ppm[c][i][j] * work[i][j]; + ipix[c] = floor ((ipix[c] + floor(val)) * + ( sgrow[col/sgx ][c] * (sgx - col%sgx) + + sgrow[col/sgx+1][c] * (col%sgx) ) / sgx / div[c]); + if (ipix[c] > 32000) ipix[c] = 32000; + pix[c] = ipix[c]; + } + pix += 4; + } + } + free (black); + free (sgrow); + free (sgain); + + if ((badpix = (unsigned *) foveon_camf_matrix (dim, "BadPixels"))) { + for (i=0; i < dim[0]; i++) { + col = (badpix[i] >> 8 & 0xfff) - keep[0]; + row = (badpix[i] >> 20 ) - keep[1]; + if ((unsigned)(row-1) > height-3 || (unsigned)(col-1) > width-3) + continue; + memset (fsum, 0, sizeof fsum); + for (sum=j=0; j < 8; j++) + if (badpix[i] & (1 << j)) { + FORC3 fsum[c] += (short) + image[(row+hood[j*2])*width+col+hood[j*2+1]][c]; + sum++; + } + if (sum) FORC3 image[row*width+col][c] = fsum[c]/sum; + } + free (badpix); + } + + /* Array for 5x5 Gaussian averaging of red values */ + smrow[6] = (int (*)[3]) calloc (width*5, sizeof **smrow); + merror (smrow[6], "foveon_interpolate()"); + for (i=0; i < 5; i++) + smrow[i] = smrow[6] + i*width; + + /* Sharpen the reds against these Gaussian averages */ + for (smlast=-1, row=2; row < height-2; row++) { + while (smlast < row+2) { + for (i=0; i < 6; i++) + smrow[(i+5) % 6] = smrow[i]; + pix = image[++smlast*width+2]; + for (col=2; col < width-2; col++) { + smrow[4][col][0] = + (pix[0]*6 + (pix[-4]+pix[4])*4 + pix[-8]+pix[8] + 8) >> 4; + pix += 4; + } + } + pix = image[row*width+2]; + for (col=2; col < width-2; col++) { + smred = ( 6 * smrow[2][col][0] + + 4 * (smrow[1][col][0] + smrow[3][col][0]) + + smrow[0][col][0] + smrow[4][col][0] + 8 ) >> 4; + if (col == 2) + smred_p = smred; + i = pix[0] + ((pix[0] - ((smred*7 + smred_p) >> 3)) >> 3); + if (i > 32000) i = 32000; + pix[0] = i; + smred_p = smred; + pix += 4; + } + } + + /* Adjust the brighter pixels for better linearity */ + min = 0xffff; + FORC3 { + i = satlev[c] / div[c]; + if (min > i) min = i; + } + limit = min * 9 >> 4; + for (pix=image[0]; pix < image[height*width]; pix+=4) { + if (pix[0] <= limit || pix[1] <= limit || pix[2] <= limit) + continue; + min = max = pix[0]; + for (c=1; c < 3; c++) { + if (min > pix[c]) min = pix[c]; + if (max < pix[c]) max = pix[c]; + } + if (min >= limit*2) { + pix[0] = pix[1] = pix[2] = max; + } else { + i = 0x4000 - ((min - limit) << 14) / limit; + i = 0x4000 - (i*i >> 14); + i = i*i >> 14; + FORC3 pix[c] += (max - pix[c]) * i >> 14; + } + } +/* + Because photons that miss one detector often hit another, + the sum R+G+B is much less noisy than the individual colors. + So smooth the hues without smoothing the total. + */ + for (smlast=-1, row=2; row < height-2; row++) { + while (smlast < row+2) { + for (i=0; i < 6; i++) + smrow[(i+5) % 6] = smrow[i]; + pix = image[++smlast*width+2]; + for (col=2; col < width-2; col++) { + FORC3 smrow[4][col][c] = (pix[c-4]+2*pix[c]+pix[c+4]+2) >> 2; + pix += 4; + } + } + pix = image[row*width+2]; + for (col=2; col < width-2; col++) { + FORC3 dev[c] = -foveon_apply_curve (curve[7], pix[c] - + ((smrow[1][col][c] + 2*smrow[2][col][c] + smrow[3][col][c]) >> 2)); + sum = (dev[0] + dev[1] + dev[2]) >> 3; + FORC3 pix[c] += dev[c] - sum; + pix += 4; + } + } + for (smlast=-1, row=2; row < height-2; row++) { + while (smlast < row+2) { + for (i=0; i < 6; i++) + smrow[(i+5) % 6] = smrow[i]; + pix = image[++smlast*width+2]; + for (col=2; col < width-2; col++) { + FORC3 smrow[4][col][c] = + (pix[c-8]+pix[c-4]+pix[c]+pix[c+4]+pix[c+8]+2) >> 2; + pix += 4; + } + } + pix = image[row*width+2]; + for (col=2; col < width-2; col++) { + for (total[3]=375, sum=60, c=0; c < 3; c++) { + for (total[c]=i=0; i < 5; i++) + total[c] += smrow[i][col][c]; + total[3] += total[c]; + sum += pix[c]; + } + if (sum < 0) sum = 0; + j = total[3] > 375 ? (sum << 16) / total[3] : sum * 174; + FORC3 pix[c] += foveon_apply_curve (curve[6], + ((j*total[c] + 0x8000) >> 16) - pix[c]); + pix += 4; + } + } + + /* Transform the image to a different colorspace */ + for (pix=image[0]; pix < image[height*width]; pix+=4) { + FORC3 pix[c] -= foveon_apply_curve (curve[c], pix[c]); + sum = (pix[0]+pix[1]+pix[1]+pix[2]) >> 2; + FORC3 pix[c] -= foveon_apply_curve (curve[c], pix[c]-sum); + FORC3 { + for (dsum=i=0; i < 3; i++) + dsum += trans[c][i] * pix[i]; + if (dsum < 0) dsum = 0; + if (dsum > 24000) dsum = 24000; + ipix[c] = dsum + 0.5; + } + FORC3 pix[c] = ipix[c]; + } + + /* Smooth the image bottom-to-top and save at 1/4 scale */ + shrink = (short (*)[3]) calloc ((height/4), (width/4)*sizeof *shrink); + merror (shrink, "foveon_interpolate()"); + for (row = height/4; row--; ) + for (col=0; col < width/4; col++) { + ipix[0] = ipix[1] = ipix[2] = 0; + for (i=0; i < 4; i++) + for (j=0; j < 4; j++) + FORC3 ipix[c] += image[(row*4+i)*width+col*4+j][c]; + FORC3 + if (row+2 > height/4) + shrink[row*(width/4)+col][c] = ipix[c] >> 4; + else + shrink[row*(width/4)+col][c] = + (shrink[(row+1)*(width/4)+col][c]*1840 + ipix[c]*141 + 2048) >> 12; + } + /* From the 1/4-scale image, smooth right-to-left */ + for (row=0; row < (height & ~3); row++) { + ipix[0] = ipix[1] = ipix[2] = 0; + if ((row & 3) == 0) + for (col = width & ~3 ; col--; ) + FORC3 smrow[0][col][c] = ipix[c] = + (shrink[(row/4)*(width/4)+col/4][c]*1485 + ipix[c]*6707 + 4096) >> 13; + + /* Then smooth left-to-right */ + ipix[0] = ipix[1] = ipix[2] = 0; + for (col=0; col < (width & ~3); col++) + FORC3 smrow[1][col][c] = ipix[c] = + (smrow[0][col][c]*1485 + ipix[c]*6707 + 4096) >> 13; + + /* Smooth top-to-bottom */ + if (row == 0) + memcpy (smrow[2], smrow[1], sizeof **smrow * width); + else + for (col=0; col < (width & ~3); col++) + FORC3 smrow[2][col][c] = + (smrow[2][col][c]*6707 + smrow[1][col][c]*1485 + 4096) >> 13; + + /* Adjust the chroma toward the smooth values */ + for (col=0; col < (width & ~3); col++) { + for (i=j=30, c=0; c < 3; c++) { + i += smrow[2][col][c]; + j += image[row*width+col][c]; + } + j = (j << 16) / i; + for (sum=c=0; c < 3; c++) { + ipix[c] = foveon_apply_curve (curve[c+3], + ((smrow[2][col][c] * j + 0x8000) >> 16) - image[row*width+col][c]); + sum += ipix[c]; + } + sum >>= 3; + FORC3 { + i = image[row*width+col][c] + ipix[c] - sum; + if (i < 0) i = 0; + image[row*width+col][c] = i; + } + } + } + free (shrink); + free (smrow[6]); + for (i=0; i < 8; i++) + free (curve[i]); + + /* Trim off the black border */ + active[1] -= keep[1]; + active[3] -= 2; + i = active[2] - active[0]; + for (row=0; row < active[3]-active[1]; row++) + memcpy (image[row*i], image[(row+active[1])*width+active[0]], + i * sizeof *image); + width = i; + height = row; +} +#undef image + +/* RESTRICTED code ends here */ + +void CLASS crop_masked_pixels() +{ + int row, col; + unsigned r, c, m, mblack[8], zero, val; + + if (load_raw == &CLASS phase_one_load_raw || + load_raw == &CLASS phase_one_load_raw_c) + phase_one_correct(); + if (load_raw == &CLASS hasselblad_load_raw) // RT + hasselblad_correct(); // RT + if (fuji_width) { + for (row=0; row < raw_height-top_margin*2; row++) { + for (col=0; col < fuji_width << !fuji_layout; col++) { + if (fuji_layout) { + r = fuji_width - 1 - col + (row >> 1); + c = col + ((row+1) >> 1); + } else { + r = fuji_width - 1 + row - (col >> 1); + c = row + ((col+1) >> 1); + } + if (r < height && c < width) + BAYER(r,c) = RAW(row+top_margin,col+left_margin); + } + } + } else { + +#pragma omp parallel for + for (int row=0; row < height; row++) + for (int col=0; col < width; col++) + BAYER2(row,col) = RAW(row+top_margin,col+left_margin); + } + + if (mask[0][3] > 0) goto mask_set; + if (load_raw == &CLASS canon_load_raw || + load_raw == &CLASS lossless_jpeg_load_raw) { + mask[0][1] = mask[1][1] += 2; + mask[0][3] -= 2; + goto sides; + } + if (load_raw == &CLASS canon_600_load_raw || + load_raw == &CLASS sony_load_raw || + (load_raw == &CLASS eight_bit_load_raw && strncmp(model,"DC2",3)) || + load_raw == &CLASS kodak_262_load_raw || + (load_raw == &CLASS packed_load_raw && (load_flags & 32))) { +sides: + mask[0][0] = mask[1][0] = top_margin; + mask[0][2] = mask[1][2] = top_margin+height; + mask[0][3] += left_margin; + mask[1][1] += left_margin+width; + mask[1][3] += raw_width; + } + if (load_raw == &CLASS nokia_load_raw) { + mask[0][2] = top_margin; + mask[0][3] = width; + } +mask_set: + memset (mblack, 0, sizeof mblack); + for (zero=m=0; m < 8; m++) + for (row=MAX(mask[m][0],0); row < MIN(mask[m][2],raw_height); row++) + for (col=MAX(mask[m][1],0); col < MIN(mask[m][3],raw_width); col++) { + c = FC(row-top_margin,col-left_margin); + mblack[c] += val = RAW(row,col); + mblack[4+c]++; + zero += !val; + } + if (load_raw == &CLASS canon_600_load_raw && width < raw_width) { + black = (mblack[0]+mblack[1]+mblack[2]+mblack[3]) / + (mblack[4]+mblack[5]+mblack[6]+mblack[7]) - 4; + canon_600_correct(); + } else if (zero < mblack[4] && mblack[5] && mblack[6] && mblack[7]) { + FORC4 cblack[c] = mblack[c] / mblack[4+c]; + cblack[4] = cblack[5] = cblack[6] = 0; + } +} + +void CLASS remove_zeroes() +{ + unsigned row, col, tot, n, r, c; + + for (row=0; row < height; row++) + for (col=0; col < width; col++) + if (BAYER(row,col) == 0) { + tot = n = 0; + for (r = row-2; r <= row+2; r++) + for (c = col-2; c <= col+2; c++) + if (r < height && c < width && + FC(r,c) == FC(row,col) && BAYER(r,c)) + tot += (n++,BAYER(r,c)); + if (n) BAYER(row,col) = tot/n; + } +} + +/* + Seach from the current directory up to the root looking for + a ".badpixels" file, and fix those pixels now. + */ +void CLASS bad_pixels (const char *cfname) +{ + FILE *fp=0; + char *fname, *cp, line[128]; + int len, time, row, col, r, c, rad, tot, n, fixed=0; + + if (!filters) return; + if (cfname) + fp = fopen (cfname, "r"); + else { + for (len=32 ; ; len *= 2) { + fname = (char *) malloc (len); + if (!fname) return; + if (getcwd (fname, len-16)) break; + free (fname); + if (errno != ERANGE) return; + } +#if defined(WIN32) || defined(DJGPP) + if (fname[1] == ':') + memmove (fname, fname+2, len-2); + for (cp=fname; *cp; cp++) + if (*cp == '\\') *cp = '/'; +#endif + cp = fname + strlen(fname); + if (cp[-1] == '/') cp--; + while (*fname == '/') { + strcpy (cp, "/.badpixels"); + if ((fp = fopen (fname, "r"))) break; + if (cp == fname) break; + while (*--cp != '/'); + } + free (fname); + } + if (!fp) return; + while (fgets (line, 128, fp)) { + cp = strchr (line, '#'); + if (cp) *cp = 0; + if (sscanf (line, "%d %d %d", &col, &row, &time) != 3) continue; + if ((unsigned) col >= width || (unsigned) row >= height) continue; + if (time > timestamp) continue; + for (tot=n=0, rad=1; rad < 3 && n==0; rad++) + for (r = row-rad; r <= row+rad; r++) + for (c = col-rad; c <= col+rad; c++) + if ((unsigned) r < height && (unsigned) c < width && + (r != row || c != col) && fcol(r,c) == fcol(row,col)) { + tot += BAYER2(r,c); + n++; + } + BAYER2(row,col) = tot/n; + if (verbose) { + if (!fixed++) + fprintf (stderr,_("Fixed dead pixels at:")); + fprintf (stderr, " %d,%d", col, row); + } + } + if (fixed) fputc ('\n', stderr); + fclose (fp); +} + +void CLASS subtract (const char *fname) +{ + FILE *fp; + int dim[3]={0,0,0}, comment=0, number=0, error=0, nd=0, c, row, col; + ushort *pixel; + + if (!(fp = fopen (fname, "rb"))) { + perror (fname); return; + } + if (fgetc(fp) != 'P' || fgetc(fp) != '5') error = 1; + while (!error && nd < 3 && (c = fgetc(fp)) != EOF) { + if (c == '#') comment = 1; + if (c == '\n') comment = 0; + if (comment) continue; + if (isdigit(c)) number = 1; + if (number) { + if (isdigit(c)) dim[nd] = dim[nd]*10 + c -'0'; + else if (isspace(c)) { + number = 0; nd++; + } else error = 1; + } + } + if (error || nd < 3) { + fprintf (stderr,_("%s is not a valid PGM file!\n"), fname); + fclose (fp); return; + } else if (dim[0] != width || dim[1] != height || dim[2] != 65535) { + fprintf (stderr,_("%s has the wrong dimensions!\n"), fname); + fclose (fp); return; + } + pixel = (ushort *) calloc (width, sizeof *pixel); + merror (pixel, "subtract()"); + for (row=0; row < height; row++) { + fread (pixel, 2, width, fp); + for (col=0; col < width; col++) + BAYER(row,col) = MAX (BAYER(row,col) - ntohs(pixel[col]), 0); + } + free (pixel); + fclose (fp); + memset (cblack, 0, sizeof cblack); + black = 0; +} + +void CLASS gamma_curve (double pwr, double ts, int mode, int imax) +{ + int i; + double g[6], bnd[2]={0,0}, r; + + g[0] = pwr; + g[1] = ts; + g[2] = g[3] = g[4] = 0; + bnd[g[1] >= 1] = 1; + if (g[1] && (g[1]-1)*(g[0]-1) <= 0) { + for (i=0; i < 48; i++) { + g[2] = (bnd[0] + bnd[1])/2; + if (g[0]) bnd[(pow(g[2]/g[1],-g[0]) - 1)/g[0] - 1/g[2] > -1] = g[2]; + else bnd[g[2]/exp(1-1/g[2]) < g[1]] = g[2]; + } + g[3] = g[2] / g[1]; + if (g[0]) g[4] = g[2] * (1/g[0] - 1); + } + if (g[0]) g[5] = 1 / (g[1]*SQR(g[3])/2 - g[4]*(1 - g[3]) + + (1 - pow(g[3],1+g[0]))*(1 + g[4])/(1 + g[0])) - 1; + else g[5] = 1 / (g[1]*SQR(g[3])/2 + 1 + - g[2] - g[3] - g[2]*g[3]*(log(g[3]) - 1)) - 1; + if (!mode--) { + memcpy (gamm, g, sizeof gamm); + return; + } + for (i=0; i < 0x10000; i++) { + curve[i] = 0xffff; + if ((r = (double) i / imax) < 1) + curve[i] = 0x10000 * ( mode + ? (r < g[3] ? r*g[1] : (g[0] ? pow( r,g[0])*(1+g[4])-g[4] : log(r)*g[2]+1)) + : (r < g[2] ? r/g[1] : (g[0] ? pow((r+g[4])/(1+g[4]),1/g[0]) : exp((r-1)/g[2])))); + } +} + +void CLASS pseudoinverse (double (*in)[3], double (*out)[3], int size) +{ + double work[3][6], num; + int i, j, k; + + for (i=0; i < 3; i++) { + for (j=0; j < 6; j++) + work[i][j] = j == i+3; + for (j=0; j < 3; j++) + for (k=0; k < size; k++) + work[i][j] += in[k][i] * in[k][j]; + } + for (i=0; i < 3; i++) { + num = work[i][i]; + for (j=0; j < 6; j++) + work[i][j] /= num; + for (k=0; k < 3; k++) { + if (k==i) continue; + num = work[k][i]; + for (j=0; j < 6; j++) + work[k][j] -= work[i][j] * num; + } + } + for (i=0; i < size; i++) + for (j=0; j < 3; j++) + for (out[i][j]=k=0; k < 3; k++) + out[i][j] += work[j][k+3] * in[i][k]; +} + +void CLASS cam_xyz_coeff (float rgb_cam[3][4], double cam_xyz[4][3]) +{ + double cam_rgb[4][3], inverse[4][3], num; + int i, j, k; + + for (i=0; i < colors; i++) /* Multiply out XYZ colorspace */ + for (j=0; j < 3; j++) + for (cam_rgb[i][j] = k=0; k < 3; k++) + cam_rgb[i][j] += cam_xyz[i][k] * xyz_rgb[k][j]; + + for (i=0; i < colors; i++) { /* Normalize cam_rgb so that */ + for (num=j=0; j < 3; j++) /* cam_rgb * (1,1,1) is (1,1,1,1) */ + num += cam_rgb[i][j]; + for (j=0; j < 3; j++) + cam_rgb[i][j] /= num; + pre_mul[i] = 1 / num; + } + pseudoinverse (cam_rgb, inverse, colors); + for (i=0; i < 3; i++) + for (j=0; j < colors; j++) + rgb_cam[i][j] = inverse[j][i]; +} + +#ifdef COLORCHECK +void CLASS colorcheck() +{ +#define NSQ 24 +// Coordinates of the GretagMacbeth ColorChecker squares +// width, height, 1st_column, 1st_row + int cut[NSQ][4]; // you must set these +// ColorChecker Chart under 6500-kelvin illumination + static const double gmb_xyY[NSQ][3] = { + { 0.400, 0.350, 10.1 }, // Dark Skin + { 0.377, 0.345, 35.8 }, // Light Skin + { 0.247, 0.251, 19.3 }, // Blue Sky + { 0.337, 0.422, 13.3 }, // Foliage + { 0.265, 0.240, 24.3 }, // Blue Flower + { 0.261, 0.343, 43.1 }, // Bluish Green + { 0.506, 0.407, 30.1 }, // Orange + { 0.211, 0.175, 12.0 }, // Purplish Blue + { 0.453, 0.306, 19.8 }, // Moderate Red + { 0.285, 0.202, 6.6 }, // Purple + { 0.380, 0.489, 44.3 }, // Yellow Green + { 0.473, 0.438, 43.1 }, // Orange Yellow + { 0.187, 0.129, 6.1 }, // Blue + { 0.305, 0.478, 23.4 }, // Green + { 0.539, 0.313, 12.0 }, // Red + { 0.448, 0.470, 59.1 }, // Yellow + { 0.364, 0.233, 19.8 }, // Magenta + { 0.196, 0.252, 19.8 }, // Cyan + { 0.310, 0.316, 90.0 }, // White + { 0.310, 0.316, 59.1 }, // Neutral 8 + { 0.310, 0.316, 36.2 }, // Neutral 6.5 + { 0.310, 0.316, 19.8 }, // Neutral 5 + { 0.310, 0.316, 9.0 }, // Neutral 3.5 + { 0.310, 0.316, 3.1 } }; // Black + double gmb_cam[NSQ][4], gmb_xyz[NSQ][3]; + double inverse[NSQ][3], cam_xyz[4][3], balance[4], num; + int c, i, j, k, sq, row, col, pass, count[4]; + + memset (gmb_cam, 0, sizeof gmb_cam); + for (sq=0; sq < NSQ; sq++) { + FORCC count[c] = 0; + for (row=cut[sq][3]; row < cut[sq][3]+cut[sq][1]; row++) + for (col=cut[sq][2]; col < cut[sq][2]+cut[sq][0]; col++) { + c = FC(row,col); + if (c >= colors) c -= 2; + gmb_cam[sq][c] += BAYER2(row,col); + BAYER2(row,col) = black + (BAYER2(row,col)-black)/2; + count[c]++; + } + FORCC gmb_cam[sq][c] = gmb_cam[sq][c]/count[c] - black; + gmb_xyz[sq][0] = gmb_xyY[sq][2] * gmb_xyY[sq][0] / gmb_xyY[sq][1]; + gmb_xyz[sq][1] = gmb_xyY[sq][2]; + gmb_xyz[sq][2] = gmb_xyY[sq][2] * + (1 - gmb_xyY[sq][0] - gmb_xyY[sq][1]) / gmb_xyY[sq][1]; + } + pseudoinverse (gmb_xyz, inverse, NSQ); + for (pass=0; pass < 2; pass++) { + for (raw_color = i=0; i < colors; i++) + for (j=0; j < 3; j++) + for (cam_xyz[i][j] = k=0; k < NSQ; k++) + cam_xyz[i][j] += gmb_cam[k][i] * inverse[k][j]; + cam_xyz_coeff (rgb_cam, cam_xyz); + FORCC balance[c] = pre_mul[c] * gmb_cam[20][c]; + for (sq=0; sq < NSQ; sq++) + FORCC gmb_cam[sq][c] *= balance[c]; + } + if (verbose) { + printf (" { \"%s %s\", %d,\n\t{", make, model, black); + num = 10000 / (cam_xyz[1][0] + cam_xyz[1][1] + cam_xyz[1][2]); + FORCC for (j=0; j < 3; j++) + printf ("%c%d", (c | j) ? ',':' ', (int) (cam_xyz[c][j] * num + 0.5)); + puts (" } },"); + } +#undef NSQ +} +#endif + +void CLASS hat_transform (float *temp, float *base, int st, int size, int sc) +{ + int i; + for (i=0; i < sc; i++) + temp[i] = 2*base[st*i] + base[st*(sc-i)] + base[st*(i+sc)]; + for (; i+sc < size; i++) + temp[i] = 2*base[st*i] + base[st*(i-sc)] + base[st*(i+sc)]; + for (; i < size; i++) + temp[i] = 2*base[st*i] + base[st*(i-sc)] + base[st*(2*size-2-(i+sc))]; +} + +void CLASS wavelet_denoise() +{ + float *fimg=0, *temp, thold, mul[2], avg, diff; + int scale=1, size, lev, hpass, lpass, row, col, nc, c, i, wlast, blk[2]; + ushort *window[4]; + static const float noise[] = + { 0.8002,0.2735,0.1202,0.0585,0.0291,0.0152,0.0080,0.0044 }; + + if (verbose) fprintf (stderr,_("Wavelet denoising...\n")); + + while (maximum << scale < 0x10000) scale++; + maximum <<= --scale; + black <<= scale; + FORC4 cblack[c] <<= scale; + if ((size = iheight*iwidth) < 0x15550000) + fimg = (float *) malloc ((size*3 + iheight + iwidth) * sizeof *fimg); + merror (fimg, "wavelet_denoise()"); + temp = fimg + size*3; + if ((nc = colors) == 3 && filters) nc++; + FORC(nc) { /* denoise R,G1,B,G3 individually */ + for (i=0; i < size; i++) + fimg[i] = 256 * sqrt(image[i][c] << scale); + for (hpass=lev=0; lev < 5; lev++) { + lpass = size*((lev & 1)+1); + for (row=0; row < iheight; row++) { + hat_transform (temp, fimg+hpass+row*iwidth, 1, iwidth, 1 << lev); + for (col=0; col < iwidth; col++) + fimg[lpass + row*iwidth + col] = temp[col] * 0.25; + } + for (col=0; col < iwidth; col++) { + hat_transform (temp, fimg+lpass+col, iwidth, iheight, 1 << lev); + for (row=0; row < iheight; row++) + fimg[lpass + row*iwidth + col] = temp[row] * 0.25; + } + thold = threshold * noise[lev]; + for (i=0; i < size; i++) { + fimg[hpass+i] -= fimg[lpass+i]; + if (fimg[hpass+i] < -thold) fimg[hpass+i] += thold; + else if (fimg[hpass+i] > thold) fimg[hpass+i] -= thold; + else fimg[hpass+i] = 0; + if (hpass) fimg[i] += fimg[hpass+i]; + } + hpass = lpass; + } + for (i=0; i < size; i++) + image[i][c] = CLIP(SQR(fimg[i]+fimg[lpass+i])/0x10000); + } + if (filters && colors == 3) { /* pull G1 and G3 closer together */ + for (row=0; row < 2; row++) { + mul[row] = 0.125 * pre_mul[FC(row+1,0) | 1] / pre_mul[FC(row,0) | 1]; + blk[row] = cblack[FC(row,0) | 1]; + } + for (i=0; i < 4; i++) + window[i] = (ushort *) fimg + width*i; + for (wlast=-1, row=1; row < height-1; row++) { + while (wlast < row+1) { + for (wlast++, i=0; i < 4; i++) + window[(i+3) & 3] = window[i]; + for (col = FC(wlast,1) & 1; col < width; col+=2) + window[2][col] = BAYER(wlast,col); + } + thold = threshold/512; + for (col = (FC(row,0) & 1)+1; col < width-1; col+=2) { + avg = ( window[0][col-1] + window[0][col+1] + + window[2][col-1] + window[2][col+1] - blk[~row & 1]*4 ) + * mul[row & 1] + (window[1][col] + blk[row & 1]) * 0.5; + avg = avg < 0 ? 0 : sqrt(avg); + diff = sqrt(BAYER(row,col)) - avg; + if (diff < -thold) diff += thold; + else if (diff > thold) diff -= thold; + else diff = 0; + BAYER(row,col) = CLIP(SQR(avg+diff) + 0.5); + } + } + } + free (fimg); +} + +void CLASS scale_colors() +{ + unsigned bottom, right, size, row, col, ur, uc, i, x, y, c, sum[8]; + int val, dark, sat; + double dsum[8], dmin, dmax; + float scale_mul[4], fr, fc; + ushort *img=0, *pix; + + if (user_mul[0]) + memcpy (pre_mul, user_mul, sizeof pre_mul); + if (use_auto_wb || (use_camera_wb && cam_mul[0] == -1)) { + memset (dsum, 0, sizeof dsum); + bottom = MIN (greybox[1]+greybox[3], height); + right = MIN (greybox[0]+greybox[2], width); + for (row=greybox[1]; row < bottom; row += 8) + for (col=greybox[0]; col < right; col += 8) { + memset (sum, 0, sizeof sum); + for (y=row; y < row+8 && y < bottom; y++) + for (x=col; x < col+8 && x < right; x++) + FORC4 { + if (filters) { + c = fcol(y,x); + val = BAYER2(y,x); + } else + val = image[y*width+x][c]; + if (val > maximum-25) goto skip_block; + if ((val -= cblack[c]) < 0) val = 0; + sum[c] += val; + sum[c+4]++; + if (filters) break; + } + FORC(8) dsum[c] += sum[c]; +skip_block: ; + } + FORC4 if (dsum[c]) pre_mul[c] = dsum[c+4] / dsum[c]; + } + if (use_camera_wb && cam_mul[0] != -1) { + memset (sum, 0, sizeof sum); + for (row=0; row < 8; row++) + for (col=0; col < 8; col++) { + c = FC(row,col); + if ((val = white[row][col] - cblack[c]) > 0) + sum[c] += val; + sum[c+4]++; + } + if (sum[0] && sum[1] && sum[2] && sum[3]) + FORC4 pre_mul[c] = (float) sum[c+4] / sum[c]; + else if (cam_mul[0] && cam_mul[2]) + memcpy (pre_mul, cam_mul, sizeof pre_mul); + else + fprintf (stderr,_("%s: Cannot use camera white balance.\n"), ifname); + } + if (pre_mul[1] == 0) pre_mul[1] = 1; + if (pre_mul[3] == 0) pre_mul[3] = colors < 4 ? pre_mul[1] : 1; + dark = black; + sat = maximum; + if (threshold) wavelet_denoise(); + maximum -= black; + for (dmin=DBL_MAX, dmax=c=0; c < 4; c++) { + if (dmin > pre_mul[c]) + dmin = pre_mul[c]; + if (dmax < pre_mul[c]) + dmax = pre_mul[c]; + } + if (!highlight) dmax = dmin; + FORC4 scale_mul[c] = (pre_mul[c] /= dmax) * 65535.0 / maximum; + if (verbose) { + fprintf (stderr, + _("Scaling with darkness %d, saturation %d, and\nmultipliers"), dark, sat); + FORC4 fprintf (stderr, " %f", pre_mul[c]); + fputc ('\n', stderr); + } + if (filters > 1000 && (cblack[4]+1)/2 == 1 && (cblack[5]+1)/2 == 1) { + FORC4 cblack[FC(c/2,c%2)] += + cblack[6 + c/2 % cblack[4] * cblack[5] + c%2 % cblack[5]]; + cblack[4] = cblack[5] = 0; + } + size = iheight*iwidth; + for (i=0; i < size*4; i++) { + if (!(val = ((ushort *)image)[i])) continue; + if (cblack[4] && cblack[5]) + val -= cblack[6 + i/4 / iwidth % cblack[4] * cblack[5] + + i/4 % iwidth % cblack[5]]; + val -= cblack[i & 3]; + val *= scale_mul[i & 3]; + ((ushort *)image)[i] = CLIP(val); + } + if ((aber[0] != 1 || aber[2] != 1) && colors == 3) { + if (verbose) + fprintf (stderr,_("Correcting chromatic aberration...\n")); + for (c=0; c < 4; c+=2) { + if (aber[c] == 1) continue; + img = (ushort *) malloc (size * sizeof *img); + merror (img, "scale_colors()"); + for (i=0; i < size; i++) + img[i] = image[i][c]; + for (row=0; row < iheight; row++) { + ur = fr = (row - iheight*0.5) * aber[c] + iheight*0.5; + if (ur > iheight-2) continue; + fr -= ur; + for (col=0; col < iwidth; col++) { + uc = fc = (col - iwidth*0.5) * aber[c] + iwidth*0.5; + if (uc > iwidth-2) continue; + fc -= uc; + pix = img + ur*iwidth + uc; + image[row*iwidth+col][c] = + (pix[ 0]*(1-fc) + pix[ 1]*fc) * (1-fr) + + (pix[iwidth]*(1-fc) + pix[iwidth+1]*fc) * fr; + } + } + free(img); + } + } +} + +void CLASS pre_interpolate() +{ + ushort (*img)[4]; + int row, col, c; + + if (shrink) { + if (half_size) { + height = iheight; + width = iwidth; + if (filters == 9) { + for (row=0; row < 3; row++) + for (col=1; col < 4; col++) + if (!(image[row*width+col][0] | image[row*width+col][2])) + goto break2; break2: + for ( ; row < height; row+=3) + for (col=(col-1)%3+1; col < width-1; col+=3) { + img = image + row*width+col; + for (c=0; c < 3; c+=2) + img[0][c] = (img[-1][c] + img[1][c]) >> 1; + } + } + } else { + img = (ushort (*)[4]) calloc (height, width*sizeof *img); + merror (img, "pre_interpolate()"); + for (row=0; row < height; row++) + for (col=0; col < width; col++) { + c = fcol(row,col); + img[row*width+col][c] = image[(row >> 1)*iwidth+(col >> 1)][c]; + } + free (image); + image = img; + shrink = 0; + } + } + if (filters > 1000 && colors == 3) { + mix_green = four_color_rgb ^ half_size; + if (four_color_rgb | half_size) colors++; + else { + for (row = FC(1,0) >> 1; row < height; row+=2) + for (col = FC(row,1) & 1; col < width; col+=2) + image[row*width+col][1] = image[row*width+col][3]; + filters &= ~((filters & 0x55555555) << 1); + } + } + if (half_size) filters = 0; +} + +void CLASS border_interpolate (int border) +{ + unsigned row, col, y, x, f, c, sum[8]; + + for (row=0; row < height; row++) + for (col=0; col < width; col++) { + if (col==border && row >= border && row < height-border) + col = width-border; + memset (sum, 0, sizeof sum); + for (y=row-1; y != row+2; y++) + for (x=col-1; x != col+2; x++) + if (y < height && x < width) { + f = fcol(y,x); + sum[f] += image[y*width+x][f]; + sum[f+4]++; + } + f = fcol(row,col); + FORCC if (c != f && sum[c+4]) + image[row*width+col][c] = sum[c] / sum[c+4]; + } +} + +/* RT: delete interpolation functions */ + + +void CLASS cielab (ushort rgb[3], short lab[3]) +{ + int c, i, j, k; + float r, xyz[3]; + static float cbrt[0x10000], xyz_cam[3][4]; + + if (!rgb) { + for (i=0; i < 0x10000; i++) { + r = i / 65535.0; + cbrt[i] = r > 0.008856 ? pow(r,1/3.0) : 7.787*r + 16/116.0; + } + for (i=0; i < 3; i++) + for (j=0; j < colors; j++) + for (xyz_cam[i][j] = k=0; k < 3; k++) + xyz_cam[i][j] += xyz_rgb[i][k] * rgb_cam[k][j] / d65_white[i]; + return; + } + xyz[0] = xyz[1] = xyz[2] = 0.5; + FORCC { + xyz[0] += xyz_cam[0][c] * rgb[c]; + xyz[1] += xyz_cam[1][c] * rgb[c]; + xyz[2] += xyz_cam[2][c] * rgb[c]; + } + xyz[0] = cbrt[CLIP((int) xyz[0])]; + xyz[1] = cbrt[CLIP((int) xyz[1])]; + xyz[2] = cbrt[CLIP((int) xyz[2])]; + lab[0] = 64 * (116 * xyz[1] - 16); + lab[1] = 64 * 500 * (xyz[0] - xyz[1]); + lab[2] = 64 * 200 * (xyz[1] - xyz[2]); +} + +#define TS 512 /* Tile Size */ +#define fcol(row,col) xtrans[(row+6) % 6][(col+6) % 6] + +/* + Frank Markesteijn's algorithm for Fuji X-Trans sensors + */ +void CLASS xtrans_interpolate (int passes) +{ + int c, d, f, g, h, i, v, ng, row, col, top, left, mrow, mcol; + int val, ndir, pass, hm[8], avg[4], color[3][8]; + static const short orth[12] = { 1,0,0,1,-1,0,0,-1,1,0,0,1 }, + patt[2][16] = { { 0,1,0,-1,2,0,-1,0,1,1,1,-1,0,0,0,0 }, + { 0,1,0,-2,1,0,-2,0,1,1,-2,-2,1,-1,-1,1 } }, + dir[4] = { 1,TS,TS+1,TS-1 }; + short allhex[3][3][2][8], *hex; + ushort min, max, sgrow, sgcol; + ushort (*rgb)[TS][TS][3], (*rix)[3], (*pix)[4]; + short (*lab) [TS][3], (*lix)[3]; + float (*drv)[TS][TS], diff[6], tr; + char (*homo)[TS][TS], *buffer; + + if (verbose) + fprintf (stderr,_("%d-pass X-Trans interpolation...\n"), passes); + + cielab (0,0); + ndir = 4 << (passes > 1); + buffer = (char *) malloc (TS*TS*(ndir*11+6)); + merror (buffer, "xtrans_interpolate()"); + rgb = (ushort(*)[TS][TS][3]) buffer; + lab = (short (*) [TS][3])(buffer + TS*TS*(ndir*6)); + drv = (float (*)[TS][TS]) (buffer + TS*TS*(ndir*6+6)); + homo = (char (*)[TS][TS]) (buffer + TS*TS*(ndir*10+6)); + +/* Map a green hexagon around each non-green pixel and vice versa: */ + for (row=0; row < 3; row++) + for (col=0; col < 3; col++) + for (ng=d=0; d < 10; d+=2) { + g = fcol(row,col) == 1; + if (fcol(row+orth[d],col+orth[d+2]) == 1) ng=0; else ng++; + if (ng == 4) { sgrow = row; sgcol = col; } + if (ng == g+1) FORC(8) { + v = orth[d ]*patt[g][c*2] + orth[d+1]*patt[g][c*2+1]; + h = orth[d+2]*patt[g][c*2] + orth[d+3]*patt[g][c*2+1]; + allhex[row][col][0][c^(g*2 & d)] = h + v*width; + allhex[row][col][1][c^(g*2 & d)] = h + v*TS; + } + } + +/* Set green1 and green3 to the minimum and maximum allowed values: */ + for (row=2; row < height-2; row++) + for (min=~(max=0), col=2; col < width-2; col++) { + if (fcol(row,col) == 1 && (min=~(max=0))) continue; + pix = image + row*width + col; + hex = allhex[row % 3][col % 3][0]; + if (!max) FORC(6) { + val = pix[hex[c]][1]; + if (min > val) min = val; + if (max < val) max = val; + } + pix[0][1] = min; + pix[0][3] = max; + switch ((row-sgrow) % 3) { + case 1: if (row < height-3) { row++; col--; } break; + case 2: if ((min=~(max=0)) && (col+=2) < width-3 && row > 2) row--; + } + } + + for (top=3; top < height-19; top += TS-16) + for (left=3; left < width-19; left += TS-16) { + mrow = MIN (top+TS, height-3); + mcol = MIN (left+TS, width-3); + for (row=top; row < mrow; row++) + for (col=left; col < mcol; col++) + memcpy (rgb[0][row-top][col-left], image[row*width+col], 6); + FORC3 memcpy (rgb[c+1], rgb[0], sizeof *rgb); + +/* Interpolate green horizontally, vertically, and along both diagonals: */ + for (row=top; row < mrow; row++) + for (col=left; col < mcol; col++) { + if ((f = fcol(row,col)) == 1) continue; + pix = image + row*width + col; + hex = allhex[row % 3][col % 3][0]; + color[1][0] = 174 * (pix[ hex[1]][1] + pix[ hex[0]][1]) - + 46 * (pix[2*hex[1]][1] + pix[2*hex[0]][1]); + color[1][1] = 223 * pix[ hex[3]][1] + pix[ hex[2]][1] * 33 + + 92 * (pix[ 0 ][f] - pix[ -hex[2]][f]); + FORC(2) color[1][2+c] = + 164 * pix[hex[4+c]][1] + 92 * pix[-2*hex[4+c]][1] + 33 * + (2*pix[0][f] - pix[3*hex[4+c]][f] - pix[-3*hex[4+c]][f]); + FORC4 rgb[c^!((row-sgrow) % 3)][row-top][col-left][1] = + LIM(color[1][c] >> 8,pix[0][1],pix[0][3]); + } + + for (pass=0; pass < passes; pass++) { + if (pass == 1) + memcpy (rgb+=4, buffer, 4*sizeof *rgb); + +/* Recalculate green from interpolated values of closer pixels: */ + if (pass) { + for (row=top+2; row < mrow-2; row++) + for (col=left+2; col < mcol-2; col++) { + if ((f = fcol(row,col)) == 1) continue; + pix = image + row*width + col; + hex = allhex[row % 3][col % 3][1]; + for (d=3; d < 6; d++) { + rix = &rgb[(d-2)^!((row-sgrow) % 3)][row-top][col-left]; + val = rix[-2*hex[d]][1] + 2*rix[hex[d]][1] + - rix[-2*hex[d]][f] - 2*rix[hex[d]][f] + 3*rix[0][f]; + rix[0][1] = LIM(val/3,pix[0][1],pix[0][3]); + } + } + } + +/* Interpolate red and blue values for solitary green pixels: */ + for (row=(top-sgrow+4)/3*3+sgrow; row < mrow-2; row+=3) + for (col=(left-sgcol+4)/3*3+sgcol; col < mcol-2; col+=3) { + rix = &rgb[0][row-top][col-left]; + h = fcol(row,col+1); + memset (diff, 0, sizeof diff); + for (i=1, d=0; d < 6; d++, i^=TS^1, h^=2) { + for (c=0; c < 2; c++, h^=2) { + g = 2*rix[0][1] - rix[i< 1) + diff[d] += SQR (rix[i< 1 && (d & 1)) + if (diff[d-1] < diff[d]) + FORC(2) color[c*2][d] = color[c*2][d-1]; + if (d < 2 || (d & 1)) { + FORC(2) rix[0][c*2] = CLIP(color[c*2][d]/2); + rix += TS*TS; + } + } + } + +/* Interpolate red for blue pixels and vice versa: */ + for (row=top+3; row < mrow-3; row++) + for (col=left+3; col < mcol-3; col++) { + if ((f = 2-fcol(row,col)) == 1) continue; + rix = &rgb[0][row-top][col-left]; + c = (row-sgrow) % 3 ? TS:1; + h = 3 * (c ^ TS ^ 1); + for (d=0; d < 4; d++, rix += TS*TS) { + i = d > 1 || ((d ^ c) & 1) || + ((ABS(rix[0][1]-rix[c][1])+ABS(rix[0][1]-rix[-c][1])) < + 2*(ABS(rix[0][1]-rix[h][1])+ABS(rix[0][1]-rix[-h][1]))) ? c:h; + rix[0][f] = CLIP((rix[i][f] + rix[-i][f] + + 2*rix[0][1] - rix[i][1] - rix[-i][1])/2); + } + } + +/* Fill in red and blue for 2x2 blocks of green: */ + for (row=top+2; row < mrow-2; row++) if ((row-sgrow) % 3) + for (col=left+2; col < mcol-2; col++) if ((col-sgcol) % 3) { + rix = &rgb[0][row-top][col-left]; + hex = allhex[row % 3][col % 3][1]; + for (d=0; d < ndir; d+=2, rix += TS*TS) + if (hex[d] + hex[d+1]) { + g = 3*rix[0][1] - 2*rix[hex[d]][1] - rix[hex[d+1]][1]; + for (c=0; c < 4; c+=2) rix[0][c] = + CLIP((g + 2*rix[hex[d]][c] + rix[hex[d+1]][c])/3); + } else { + g = 2*rix[0][1] - rix[hex[d]][1] - rix[hex[d+1]][1]; + for (c=0; c < 4; c+=2) rix[0][c] = + CLIP((g + rix[hex[d]][c] + rix[hex[d+1]][c])/2); + } + } + } + rgb = (ushort(*)[TS][TS][3]) buffer; + mrow -= top; + mcol -= left; + +/* Convert to CIELab and differentiate in all directions: */ + for (d=0; d < ndir; d++) { + for (row=2; row < mrow-2; row++) + for (col=2; col < mcol-2; col++) + cielab (rgb[d][row][col], lab[row][col]); + for (f=dir[d & 3],row=3; row < mrow-3; row++) + for (col=3; col < mcol-3; col++) { + lix = &lab[row][col]; + g = 2*lix[0][0] - lix[f][0] - lix[-f][0]; + drv[d][row][col] = SQR(g) + + SQR((2*lix[0][1] - lix[f][1] - lix[-f][1] + g*500/232)) + + SQR((2*lix[0][2] - lix[f][2] - lix[-f][2] - g*500/580)); + } + } + +/* Build homogeneity maps from the derivatives: */ + memset(homo, 0, ndir*TS*TS); + for (row=4; row < mrow-4; row++) + for (col=4; col < mcol-4; col++) { + for (tr=FLT_MAX, d=0; d < ndir; d++) + if (tr > drv[d][row][col]) + tr = drv[d][row][col]; + tr *= 8; + for (d=0; d < ndir; d++) + for (v=-1; v <= 1; v++) + for (h=-1; h <= 1; h++) + if (drv[d][row+v][col+h] <= tr) + homo[d][row][col]++; + } + +/* Average the most homogenous pixels for the final result: */ + if (height-top < TS+4) mrow = height-top+2; + if (width-left < TS+4) mcol = width-left+2; + for (row = MIN(top,8); row < mrow-8; row++) + for (col = MIN(left,8); col < mcol-8; col++) { + for (d=0; d < ndir; d++) + for (hm[d]=0, v=-2; v <= 2; v++) + for (h=-2; h <= 2; h++) + hm[d] += homo[d][row+v][col+h]; + for (d=0; d < ndir-4; d++) + if (hm[d] < hm[d+4]) hm[d ] = 0; else + if (hm[d] > hm[d+4]) hm[d+4] = 0; + for (max=hm[0],d=1; d < ndir; d++) + if (max < hm[d]) max = hm[d]; + max -= max >> 3; + memset (avg, 0, sizeof avg); + for (d=0; d < ndir; d++) + if (hm[d] >= max) { + FORC3 avg[c] += rgb[d][row][col][c]; + avg[3]++; + } + FORC3 image[(row+top)*width+col+left][c] = avg[c]/avg[3]; + } + } + free(buffer); + border_interpolate(8); +} +#undef fcol + + +#undef TS + +void CLASS median_filter() +{ + ushort (*pix)[4]; + int pass, c, i, j, k, med[9]; + static const uchar opt[] = /* Optimal 9-element median search */ + { 1,2, 4,5, 7,8, 0,1, 3,4, 6,7, 1,2, 4,5, 7,8, + 0,3, 5,8, 4,7, 3,6, 1,4, 2,5, 4,7, 4,2, 6,4, 4,2 }; + + for (pass=1; pass <= med_passes; pass++) { + if (verbose) + fprintf (stderr,_("Median filter pass %d...\n"), pass); + for (c=0; c < 3; c+=2) { + for (pix = image; pix < image+width*height; pix++) + pix[0][3] = pix[0][c]; + for (pix = image+width; pix < image+width*(height-1); pix++) { + if ((pix-image+1) % width < 2) continue; + for (k=0, i = -width; i <= width; i += width) + for (j = i-1; j <= i+1; j++) + med[k++] = pix[j][3] - pix[j][1]; + for (i=0; i < sizeof opt; i+=2) + if (med[opt[i]] > med[opt[i+1]]) + SWAP (med[opt[i]] , med[opt[i+1]]); + pix[0][c] = CLIP(med[4] + pix[0][1]); + } + } + } +} + +void CLASS blend_highlights() +{ + int clip=INT_MAX, row, col, c, i, j; + static const float trans[2][4][4] = + { { { 1,1,1 }, { 1.7320508,-1.7320508,0 }, { -1,-1,2 } }, + { { 1,1,1,1 }, { 1,-1,1,-1 }, { 1,1,-1,-1 }, { 1,-1,-1,1 } } }; + static const float itrans[2][4][4] = + { { { 1,0.8660254,-0.5 }, { 1,-0.8660254,-0.5 }, { 1,0,1 } }, + { { 1,1,1,1 }, { 1,-1,1,-1 }, { 1,1,-1,-1 }, { 1,-1,-1,1 } } }; + float cam[2][4], lab[2][4], sum[2], chratio; + + if ((unsigned) (colors-3) > 1) return; + if (verbose) fprintf (stderr,_("Blending highlights...\n")); + FORCC if (clip > (i = 65535*pre_mul[c])) clip = i; + for (row=0; row < height; row++) + for (col=0; col < width; col++) { + FORCC if (image[row*width+col][c] > clip) break; + if (c == colors) continue; + FORCC { + cam[0][c] = image[row*width+col][c]; + cam[1][c] = MIN(cam[0][c],clip); + } + for (i=0; i < 2; i++) { + FORCC for (lab[i][c]=j=0; j < colors; j++) + lab[i][c] += trans[colors-3][c][j] * cam[i][j]; + for (sum[i]=0,c=1; c < colors; c++) + sum[i] += SQR(lab[i][c]); + } + chratio = sqrt(sum[1]/sum[0]); + for (c=1; c < colors; c++) + lab[0][c] *= chratio; + FORCC for (cam[0][c]=j=0; j < colors; j++) + cam[0][c] += itrans[colors-3][c][j] * lab[0][j]; + FORCC image[row*width+col][c] = cam[0][c] / colors; + } +} + +#define SCALE (4 >> shrink) +void CLASS recover_highlights() +{ + float *map, sum, wgt, grow; + int hsat[4], count, spread, change, val, i; + unsigned high, wide, mrow, mcol, row, col, kc, c, d, y, x; + ushort *pixel; + static const signed char dir[8][2] = + { {-1,-1}, {-1,0}, {-1,1}, {0,1}, {1,1}, {1,0}, {1,-1}, {0,-1} }; + + if (verbose) fprintf (stderr,_("Rebuilding highlights...\n")); + + grow = pow (2, 4-highlight); + FORCC hsat[c] = 32000 * pre_mul[c]; + for (kc=0, c=1; c < colors; c++) + if (pre_mul[kc] < pre_mul[c]) kc = c; + high = height / SCALE; + wide = width / SCALE; + map = (float *) calloc (high, wide*sizeof *map); + merror (map, "recover_highlights()"); + FORCC if (c != kc) { + memset (map, 0, high*wide*sizeof *map); + for (mrow=0; mrow < high; mrow++) + for (mcol=0; mcol < wide; mcol++) { + sum = wgt = count = 0; + for (row = mrow*SCALE; row < (mrow+1)*SCALE; row++) + for (col = mcol*SCALE; col < (mcol+1)*SCALE; col++) { + pixel = image[row*width+col]; + if (pixel[c] / hsat[c] == 1 && pixel[kc] > 24000) { + sum += pixel[c]; + wgt += pixel[kc]; + count++; + } + } + if (count == SCALE*SCALE) + map[mrow*wide+mcol] = sum / wgt; + } + for (spread = 32/grow; spread--; ) { + for (mrow=0; mrow < high; mrow++) + for (mcol=0; mcol < wide; mcol++) { + if (map[mrow*wide+mcol]) continue; + sum = count = 0; + for (d=0; d < 8; d++) { + y = mrow + dir[d][0]; + x = mcol + dir[d][1]; + if (y < high && x < wide && map[y*wide+x] > 0) { + sum += (1 + (d & 1)) * map[y*wide+x]; + count += 1 + (d & 1); + } + } + if (count > 3) + map[mrow*wide+mcol] = - (sum+grow) / (count+grow); + } + for (change=i=0; i < high*wide; i++) + if (map[i] < 0) { + map[i] = -map[i]; + change = 1; + } + if (!change) break; + } + for (i=0; i < high*wide; i++) + if (map[i] == 0) map[i] = 1; + for (mrow=0; mrow < high; mrow++) + for (mcol=0; mcol < wide; mcol++) { + for (row = mrow*SCALE; row < (mrow+1)*SCALE; row++) + for (col = mcol*SCALE; col < (mcol+1)*SCALE; col++) { + pixel = image[row*width+col]; + if (pixel[c] / hsat[c] > 1) { + val = pixel[kc] * map[mrow*wide+mcol]; + if (pixel[c] < val) pixel[c] = CLIP(val); + } + } + } + } + free (map); +} +#undef SCALE + +void CLASS tiff_get (unsigned base, + unsigned *tag, unsigned *type, unsigned *len, unsigned *save) +{ + *tag = get2(); + *type = get2(); + *len = get4(); + *save = ftell(ifp) + 4; + if (*len * ("11124811248484"[*type < 14 ? *type:0]-'0') > 4) + fseek (ifp, get4()+base, SEEK_SET); +} + +void CLASS parse_thumb_note (int base, unsigned toff, unsigned tlen) +{ + unsigned entries, tag, type, len, save; + + entries = get2(); + while (entries--) { + tiff_get (base, &tag, &type, &len, &save); + if (tag == toff) thumb_offset = get4()+base; + if (tag == tlen) thumb_length = get4(); + fseek (ifp, save, SEEK_SET); + } +} + +/*RT int CLASS parse_tiff_ifd (int base);*/ + +void CLASS parse_makernote (int base, int uptag) +{ + static const uchar xlat[2][256] = { + { 0xc1,0xbf,0x6d,0x0d,0x59,0xc5,0x13,0x9d,0x83,0x61,0x6b,0x4f,0xc7,0x7f,0x3d,0x3d, + 0x53,0x59,0xe3,0xc7,0xe9,0x2f,0x95,0xa7,0x95,0x1f,0xdf,0x7f,0x2b,0x29,0xc7,0x0d, + 0xdf,0x07,0xef,0x71,0x89,0x3d,0x13,0x3d,0x3b,0x13,0xfb,0x0d,0x89,0xc1,0x65,0x1f, + 0xb3,0x0d,0x6b,0x29,0xe3,0xfb,0xef,0xa3,0x6b,0x47,0x7f,0x95,0x35,0xa7,0x47,0x4f, + 0xc7,0xf1,0x59,0x95,0x35,0x11,0x29,0x61,0xf1,0x3d,0xb3,0x2b,0x0d,0x43,0x89,0xc1, + 0x9d,0x9d,0x89,0x65,0xf1,0xe9,0xdf,0xbf,0x3d,0x7f,0x53,0x97,0xe5,0xe9,0x95,0x17, + 0x1d,0x3d,0x8b,0xfb,0xc7,0xe3,0x67,0xa7,0x07,0xf1,0x71,0xa7,0x53,0xb5,0x29,0x89, + 0xe5,0x2b,0xa7,0x17,0x29,0xe9,0x4f,0xc5,0x65,0x6d,0x6b,0xef,0x0d,0x89,0x49,0x2f, + 0xb3,0x43,0x53,0x65,0x1d,0x49,0xa3,0x13,0x89,0x59,0xef,0x6b,0xef,0x65,0x1d,0x0b, + 0x59,0x13,0xe3,0x4f,0x9d,0xb3,0x29,0x43,0x2b,0x07,0x1d,0x95,0x59,0x59,0x47,0xfb, + 0xe5,0xe9,0x61,0x47,0x2f,0x35,0x7f,0x17,0x7f,0xef,0x7f,0x95,0x95,0x71,0xd3,0xa3, + 0x0b,0x71,0xa3,0xad,0x0b,0x3b,0xb5,0xfb,0xa3,0xbf,0x4f,0x83,0x1d,0xad,0xe9,0x2f, + 0x71,0x65,0xa3,0xe5,0x07,0x35,0x3d,0x0d,0xb5,0xe9,0xe5,0x47,0x3b,0x9d,0xef,0x35, + 0xa3,0xbf,0xb3,0xdf,0x53,0xd3,0x97,0x53,0x49,0x71,0x07,0x35,0x61,0x71,0x2f,0x43, + 0x2f,0x11,0xdf,0x17,0x97,0xfb,0x95,0x3b,0x7f,0x6b,0xd3,0x25,0xbf,0xad,0xc7,0xc5, + 0xc5,0xb5,0x8b,0xef,0x2f,0xd3,0x07,0x6b,0x25,0x49,0x95,0x25,0x49,0x6d,0x71,0xc7 }, + { 0xa7,0xbc,0xc9,0xad,0x91,0xdf,0x85,0xe5,0xd4,0x78,0xd5,0x17,0x46,0x7c,0x29,0x4c, + 0x4d,0x03,0xe9,0x25,0x68,0x11,0x86,0xb3,0xbd,0xf7,0x6f,0x61,0x22,0xa2,0x26,0x34, + 0x2a,0xbe,0x1e,0x46,0x14,0x68,0x9d,0x44,0x18,0xc2,0x40,0xf4,0x7e,0x5f,0x1b,0xad, + 0x0b,0x94,0xb6,0x67,0xb4,0x0b,0xe1,0xea,0x95,0x9c,0x66,0xdc,0xe7,0x5d,0x6c,0x05, + 0xda,0xd5,0xdf,0x7a,0xef,0xf6,0xdb,0x1f,0x82,0x4c,0xc0,0x68,0x47,0xa1,0xbd,0xee, + 0x39,0x50,0x56,0x4a,0xdd,0xdf,0xa5,0xf8,0xc6,0xda,0xca,0x90,0xca,0x01,0x42,0x9d, + 0x8b,0x0c,0x73,0x43,0x75,0x05,0x94,0xde,0x24,0xb3,0x80,0x34,0xe5,0x2c,0xdc,0x9b, + 0x3f,0xca,0x33,0x45,0xd0,0xdb,0x5f,0xf5,0x52,0xc3,0x21,0xda,0xe2,0x22,0x72,0x6b, + 0x3e,0xd0,0x5b,0xa8,0x87,0x8c,0x06,0x5d,0x0f,0xdd,0x09,0x19,0x93,0xd0,0xb9,0xfc, + 0x8b,0x0f,0x84,0x60,0x33,0x1c,0x9b,0x45,0xf1,0xf0,0xa3,0x94,0x3a,0x12,0x77,0x33, + 0x4d,0x44,0x78,0x28,0x3c,0x9e,0xfd,0x65,0x57,0x16,0x94,0x6b,0xfb,0x59,0xd0,0xc8, + 0x22,0x36,0xdb,0xd2,0x63,0x98,0x43,0xa1,0x04,0x87,0x86,0xf7,0xa6,0x26,0xbb,0xd6, + 0x59,0x4d,0xbf,0x6a,0x2e,0xaa,0x2b,0xef,0xe6,0x78,0xb6,0x4e,0xe0,0x2f,0xdc,0x7c, + 0xbe,0x57,0x19,0x32,0x7e,0x2a,0xd0,0xb8,0xba,0x29,0x00,0x3c,0x52,0x7d,0xa8,0x49, + 0x3b,0x2d,0xeb,0x25,0x49,0xfa,0xa3,0xaa,0x39,0xa7,0xc5,0xa7,0x50,0x11,0x36,0xfb, + 0xc6,0x67,0x4a,0xf5,0xa5,0x12,0x65,0x7e,0xb0,0xdf,0xaf,0x4e,0xb3,0x61,0x7f,0x2f } }; + unsigned offset=0, entries, tag, type, len, save, c; + unsigned ver97=0, serial=0, i, wbi=0, wb[4]={0,0,0,0}; + uchar buf97[324], ci, cj, ck; + short morder, sorder=order; + char buf[10]; +/* + The MakerNote might have its own TIFF header (possibly with + its own byte-order!), or it might just be a table. + */ + if (!strcmp(make,"Nokia")) return; + fread (buf, 1, 10, ifp); + if (!strncmp (buf,"KDK" ,3) || /* these aren't TIFF tables */ + !strncmp (buf,"VER" ,3) || + !strncmp (buf,"IIII",4) || + !strncmp (buf,"MMMM",4)) return; + if (!strncmp (buf,"KC" ,2) || /* Konica KD-400Z, KD-510Z */ + !strncmp (buf,"MLY" ,3)) { /* Minolta DiMAGE G series */ + order = 0x4d4d; + while ((i=ftell(ifp)) < data_offset && i < 16384) { + wb[0] = wb[2]; wb[2] = wb[1]; wb[1] = wb[3]; + wb[3] = get2(); + if (wb[1] == 256 && wb[3] == 256 && + wb[0] > 256 && wb[0] < 640 && wb[2] > 256 && wb[2] < 640) + FORC4 cam_mul[c] = wb[c]; + } + goto quit; + } + if (!strcmp (buf,"Nikon")) { + base = ftell(ifp); + order = get2(); + if (get2() != 42) goto quit; + offset = get4(); + fseek (ifp, offset-8, SEEK_CUR); + } else if (!strcmp (buf,"OLYMPUS") || + !strcmp (buf,"PENTAX ")) { + base = ftell(ifp)-10; + fseek (ifp, -2, SEEK_CUR); + order = get2(); + if (buf[0] == 'O') get2(); + } else if (!strncmp (buf,"SONY",4) || + !strcmp (buf,"Panasonic")) { + goto nf; + } else if (!strncmp (buf,"FUJIFILM",8)) { + base = ftell(ifp)-10; +nf: order = 0x4949; + fseek (ifp, 2, SEEK_CUR); + } else if (!strcmp (buf,"OLYMP") || + !strcmp (buf,"LEICA") || + !strcmp (buf,"Ricoh") || + !strcmp (buf,"EPSON")) + fseek (ifp, -2, SEEK_CUR); + else if (!strcmp (buf,"AOC") || + !strcmp (buf,"QVC")) + fseek (ifp, -4, SEEK_CUR); + else { + fseek (ifp, -10, SEEK_CUR); + if (!strncmp(make,"SAMSUNG",7)) + base = ftell(ifp); + } + entries = get2(); + if (entries > 1000) return; + morder = order; + while (entries--) { + order = morder; + tiff_get (base, &tag, &type, &len, &save); + tag |= uptag << 16; + if (tag == 2 && strstr(make,"NIKON") && !iso_speed) + iso_speed = (get2(),get2()); + if (tag == 4 && len > 26 && len < 35) { + if ((i=(get4(),get2())) != 0x7fff && !iso_speed) + iso_speed = 50 * pow (2, i/32.0 - 4); + if ((i=(get2(),get2())) != 0x7fff && !aperture) + aperture = pow (2, i/64.0); + if ((i=get2()) != 0xffff && !shutter) + shutter = pow (2, (short) i/-32.0); + wbi = (get2(),get2()); + shot_order = (get2(),get2()); + } + if ((tag == 4 || tag == 0x114) && !strncmp(make,"KONICA",6)) { + fseek (ifp, tag == 4 ? 140:160, SEEK_CUR); + switch (get2()) { + case 72: flip = 0; break; + case 76: flip = 6; break; + case 82: flip = 5; break; + } + } + if (tag == 7 && type == 2 && len > 20) + fgets (model2, 64, ifp); + if (tag == 8 && type == 4) + shot_order = get4(); + if (tag == 9 && !strcmp(make,"Canon")) + fread (artist, 64, 1, ifp); + if (tag == 0xc && len == 4) + FORC3 cam_mul[(c << 1 | c >> 1) & 3] = getreal(type); + if (tag == 0xd && type == 7 && get2() == 0xaaaa) { + for (c=i=2; (ushort) c != 0xbbbb && i < len; i++) + c = c << 8 | fgetc(ifp); + while ((i+=4) < len-5) + if (get4() == 257 && (i=len) && (c = (get4(),fgetc(ifp))) < 3) + flip = "065"[c]-'0'; + } + if (tag == 0x10 && type == 4) + unique_id = get4(); + if (tag == 0x11 && is_raw && !strncmp(make,"NIKON",5)) { + fseek (ifp, get4()+base, SEEK_SET); + parse_tiff_ifd (base); + } + if (tag == 0x14 && type == 7) { + if (len == 2560) { + fseek (ifp, 1248, SEEK_CUR); + goto get2_256; + } + fread (buf, 1, 10, ifp); + if (!strncmp(buf,"NRW ",4)) { + fseek (ifp, strcmp(buf+4,"0100") ? 46:1546, SEEK_CUR); + cam_mul[0] = get4() << 2; + cam_mul[1] = get4() + get4(); + cam_mul[2] = get4() << 2; + } + } + //if (tag == 0x15 && type == 2 && is_raw) + if (tag == 0x15 && type == 2 && is_raw && strstr(model, "Hasselblad ") != model) // RT: don't overwrite already parsed Hasselblad model + fread (model, 64, 1, ifp); + if (strstr(make,"PENTAX")) { + if (tag == 0x1b) tag = 0x1018; + if (tag == 0x1c) tag = 0x1017; + } + if (tag == 0x19 && !strcmp(make,"Hasselblad") && len == 0x300000) { // RT + parse_hasselblad_gain(); // RT + } // RT + if (tag == 0x1d) + while ((c = fgetc(ifp)) && c != EOF) + serial = serial*10 + (isdigit(c) ? c - '0' : c % 10); + if (tag == 0x29 && type == 1) { + c = wbi < 18 ? "012347800000005896"[wbi]-'0' : 0; + fseek (ifp, 8 + c*32, SEEK_CUR); + FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get4(); + } + if (tag == 0x3d && type == 3 && len == 4) + FORC4 cblack[c ^ c >> 1] = get2() >> (14-tiff_ifd[2].bps); + if (tag == 0x81 && type == 4) { + data_offset = get4(); + fseek (ifp, data_offset + 41, SEEK_SET); + raw_height = get2() * 2; + raw_width = get2(); + filters = 0x61616161; + } + if ((tag == 0x81 && type == 7) || + (tag == 0x100 && type == 7) || + (tag == 0x280 && type == 1)) { + thumb_offset = ftell(ifp); + thumb_length = len; + } + if (tag == 0x88 && type == 4 && (thumb_offset = get4())) + thumb_offset += base; + if (tag == 0x89 && type == 4) + thumb_length = get4(); + if (tag == 0x8c || tag == 0x96) + meta_offset = ftell(ifp); + if (tag == 0x97) { + for (i=0; i < 4; i++) + ver97 = ver97 * 10 + fgetc(ifp)-'0'; + switch (ver97) { + case 100: + fseek (ifp, 68, SEEK_CUR); + FORC4 cam_mul[(c >> 1) | ((c & 1) << 1)] = get2(); + break; + case 102: + fseek (ifp, 6, SEEK_CUR); + goto get2_rggb; + case 103: + fseek (ifp, 16, SEEK_CUR); + FORC4 cam_mul[c] = get2(); + } + if (ver97 >= 200) { + if (ver97 != 205) fseek (ifp, 280, SEEK_CUR); + fread (buf97, 324, 1, ifp); + } + } + if (tag == 0xa1 && type == 7) { + order = 0x4949; + fseek (ifp, 140, SEEK_CUR); + FORC3 cam_mul[c] = get4(); + } + if (tag == 0xa4 && type == 3) { + fseek (ifp, wbi*48, SEEK_CUR); + FORC3 cam_mul[c] = get2(); + } + if (tag == 0xa7 && (unsigned) (ver97-200) < 17) { + ci = xlat[0][serial & 0xff]; + cj = xlat[1][fgetc(ifp)^fgetc(ifp)^fgetc(ifp)^fgetc(ifp)]; + ck = 0x60; + for (i=0; i < 324; i++) + buf97[i] ^= (cj += ci * ck++); + i = "66666>666;6A;:;55"[ver97-200] - '0'; + FORC4 cam_mul[c ^ (c >> 1) ^ (i & 1)] = + sget2 (buf97 + (i & -2) + c*2); + } + if (tag == 0x200 && len == 3) + shot_order = (get4(),get4()); + if (tag == 0x200 && len == 4) + FORC4 cblack[c ^ c >> 1] = get2(); + if (tag == 0x201 && len == 4) + goto get2_rggb; + if (tag == 0x220 && type == 7) + meta_offset = ftell(ifp); + if (tag == 0x401 && type == 4 && len == 4) + FORC4 cblack[c ^ c >> 1] = get4(); + if (tag == 0xe01) { /* Nikon Capture Note */ + order = 0x4949; + fseek (ifp, 22, SEEK_CUR); + for (offset=22; offset+22 < len; offset += 22+i) { + tag = get4(); + fseek (ifp, 14, SEEK_CUR); + i = get4()-4; + if (tag == 0x76a43207) flip = get2(); + else fseek (ifp, i, SEEK_CUR); + } + } + if (tag == 0xe80 && len == 256 && type == 7) { + fseek (ifp, 48, SEEK_CUR); + cam_mul[0] = get2() * 508 * 1.078 / 0x10000; + cam_mul[2] = get2() * 382 * 1.173 / 0x10000; + } + if (tag == 0xf00 && type == 7) { + if (len == 614) + fseek (ifp, 176, SEEK_CUR); + else if (len == 734 || len == 1502) + fseek (ifp, 148, SEEK_CUR); + else goto next; + goto get2_256; + } + if ((tag == 0x1011 && len == 9) || tag == 0x20400200) + for (i=0; i < 3; i++) + FORC3 cmatrix[i][c] = ((short) get2()) / 256.0; + if ((tag == 0x1012 || tag == 0x20400600) && len == 4) + FORC4 cblack[c ^ c >> 1] = get2(); + if (tag == 0x1017 || tag == 0x20400100) + cam_mul[0] = get2() / 256.0; + if (tag == 0x1018 || tag == 0x20400100) + cam_mul[2] = get2() / 256.0; + if (tag == 0x2011 && len == 2) { +get2_256: + order = 0x4d4d; + cam_mul[0] = get2() / 256.0; + cam_mul[2] = get2() / 256.0; + } + if ((tag | 0x70) == 0x2070 && (type == 4 || type == 13)) + fseek (ifp, get4()+base, SEEK_SET); + if (tag == 0x2020) + parse_thumb_note (base, 257, 258); + if (tag == 0x2040) + parse_makernote (base, 0x2040); + if (tag == 0xb028) { + fseek (ifp, get4()+base, SEEK_SET); + parse_thumb_note (base, 136, 137); + } + if (tag == 0x4001 && len > 500) { + i = len == 582 ? 50 : len == 653 ? 68 : len == 5120 ? 142 : 126; + fseek (ifp, i, SEEK_CUR); +get2_rggb: + FORC4 cam_mul[c ^ (c >> 1)] = get2(); + i = len >> 3 == 164 || len == 1506 ? 112:22; + fseek (ifp, i, SEEK_CUR); + FORC4 sraw_mul[c ^ (c >> 1)] = get2(); + } + if (tag == 0x4021 && get4() && get4()) + FORC4 cam_mul[c] = 1024; + if (tag == 0xa021) + FORC4 cam_mul[c ^ (c >> 1)] = get4(); + if (tag == 0xa028) + FORC4 cam_mul[c ^ (c >> 1)] -= get4(); + if (tag == 0xb001) + unique_id = get2(); +next: + fseek (ifp, save, SEEK_SET); + } +quit: + order = sorder; +} + +/* + Since the TIFF DateTime string has no timezone information, + assume that the camera's clock was set to Universal Time. + */ +void CLASS get_timestamp (int reversed) +{ + struct tm t; + char str[20]; + int i; + + str[19] = 0; + if (reversed) + for (i=19; i--; ) str[i] = fgetc(ifp); + else + fread (str, 19, 1, ifp); + memset (&t, 0, sizeof t); + if (sscanf (str, "%d:%d:%d %d:%d:%d", &t.tm_year, &t.tm_mon, + &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec) != 6) + return; + t.tm_year -= 1900; + t.tm_mon -= 1; + t.tm_isdst = -1; + if (mktime(&t) > 0) + timestamp = mktime(&t); +} + +void CLASS parse_exif (int base) +{ + unsigned kodak, entries, tag, type, len, save, c; + double expo; + + kodak = !strncmp(make,"EASTMAN",7) && tiff_nifds < 3; + entries = get2(); + while (entries--) { + tiff_get (base, &tag, &type, &len, &save); + switch (tag) { + case 33434: shutter = getreal(type); break; + case 33437: aperture = getreal(type); break; + case 34855: iso_speed = get2(); break; + case 36867: + case 36868: get_timestamp(0); break; + case 37377: if ((expo = -getreal(type)) < 128) + shutter = pow (2, expo); break; + case 37378: aperture = pow (2, getreal(type)/2); break; + case 37386: focal_len = getreal(type); break; + case 37500: parse_makernote (base, 0); break; + case 40962: if (kodak) raw_width = get4(); break; + case 40963: if (kodak) raw_height = get4(); break; + case 41730: + if (get4() == 0x20002) + for (exif_cfa=c=0; c < 8; c+=2) + exif_cfa |= fgetc(ifp) * 0x01010101 << c; + } + fseek (ifp, save, SEEK_SET); + } +} + +void CLASS parse_gps (int base) +{ + unsigned entries, tag, type, len, save, c; + + entries = get2(); + while (entries--) { + tiff_get (base, &tag, &type, &len, &save); + switch (tag) { + case 1: case 3: case 5: + gpsdata[29+tag/2] = getc(ifp); break; + case 2: case 4: case 7: + FORC(6) gpsdata[tag/3*6+c] = get4(); break; + case 6: + FORC(2) gpsdata[18+c] = get4(); break; + case 18: case 29: + fgets ((char *) (gpsdata+14+tag/3), MIN(len,12), ifp); + } + fseek (ifp, save, SEEK_SET); + } +} + +void CLASS romm_coeff (float romm_cam[3][3]) +{ + static const float rgb_romm[3][3] = /* ROMM == Kodak ProPhoto */ + { { 2.034193, -0.727420, -0.306766 }, + { -0.228811, 1.231729, -0.002922 }, + { -0.008565, -0.153273, 1.161839 } }; + int i, j, k; + + for (i=0; i < 3; i++) + for (j=0; j < 3; j++) + for (cmatrix[i][j] = k=0; k < 3; k++) + cmatrix[i][j] += rgb_romm[i][k] * romm_cam[k][j]; +} + +void CLASS parse_mos (int offset) +{ + char data[40]; + int skip, from, i, c, neut[4], planes=0, frot=0; + static const char *mod[] = + { "","DCB2","Volare","Cantare","CMost","Valeo 6","Valeo 11","Valeo 22", + "Valeo 11p","Valeo 17","","Aptus 17","Aptus 22","Aptus 75","Aptus 65", + "Aptus 54S","Aptus 65S","Aptus 75S","AFi 5","AFi 6","AFi 7", + "AFi-II 7","Aptus-II 7","","Aptus-II 6","","","Aptus-II 10","Aptus-II 5", + "","","","","Aptus-II 10R","Aptus-II 8","","Aptus-II 12","","AFi-II 12" }; + float romm_cam[3][3]; + + fseek (ifp, offset, SEEK_SET); + while (1) { + if (get4() != 0x504b5453) break; + get4(); + fread (data, 1, 40, ifp); + skip = get4(); + from = ftell(ifp); + if (!strcmp(data,"JPEG_preview_data")) { + thumb_offset = from; + thumb_length = skip; + } + if (!strcmp(data,"icc_camera_profile")) { + profile_offset = from; + profile_length = skip; + } + if (!strcmp(data,"ShootObj_back_type")) { + fscanf (ifp, "%d", &i); + if ((unsigned) i < sizeof mod / sizeof (*mod)) + strcpy (model, mod[i]); + } + if (!strcmp(data,"icc_camera_to_tone_matrix")) { + for (i=0; i < 9; i++) + ((float *)romm_cam)[i] = int_to_float(get4()); + romm_coeff (romm_cam); + } + if (!strcmp(data,"CaptProf_color_matrix")) { + for (i=0; i < 9; i++) + fscanf (ifp, "%f", (float *)romm_cam + i); + romm_coeff (romm_cam); + } + if (!strcmp(data,"CaptProf_number_of_planes")) + fscanf (ifp, "%d", &planes); + if (!strcmp(data,"CaptProf_raw_data_rotation")) + fscanf (ifp, "%d", &flip); + if (!strcmp(data,"CaptProf_mosaic_pattern")) + FORC4 { + fscanf (ifp, "%d", &i); + if (i == 1) frot = c ^ (c >> 1); + } + if (!strcmp(data,"ImgProf_rotation_angle")) { + fscanf (ifp, "%d", &i); + flip = i - flip; + } + if (!strcmp(data,"NeutObj_neutrals") && !cam_mul[0]) { + FORC4 fscanf (ifp, "%d", neut+c); + FORC3 cam_mul[c] = (float) neut[0] / neut[c+1]; + } + if (!strcmp(data,"Rows_data")) + load_flags = get4(); + parse_mos (from); + fseek (ifp, skip+from, SEEK_SET); + } + if (planes) + filters = (planes == 1) * 0x01010101 * + (uchar) "\x94\x61\x16\x49"[(flip/90 + frot) & 3]; +} + +void CLASS linear_table (unsigned len) +{ + int i; + if (len > 0x1000) len = 0x1000; + read_shorts (curve, len); + for (i=len; i < 0x1000; i++) + curve[i] = curve[i-1]; + maximum = curve[0xfff]; +} + +void CLASS parse_kodak_ifd (int base) +{ + unsigned entries, tag, type, len, save; + int i, c, wbi=-2, wbtemp=6500; + float mul[3]={1,1,1}, num; + static const int wbtag[] = { 64037,64040,64039,64041,-1,-1,64042 }; + + entries = get2(); + if (entries > 1024) return; + while (entries--) { + tiff_get (base, &tag, &type, &len, &save); + if (tag == 1020) wbi = getint(type); + if (tag == 1021 && len == 72) { /* WB set in software */ + fseek (ifp, 40, SEEK_CUR); + FORC3 cam_mul[c] = 2048.0 / get2(); + wbi = -2; + } + if (tag == 2118) wbtemp = getint(type); + if (tag == 2120 + wbi && wbi >= 0) + FORC3 cam_mul[c] = 2048.0 / getreal(type); + if (tag == 2130 + wbi) + FORC3 mul[c] = getreal(type); + if (tag == 2140 + wbi && wbi >= 0) + FORC3 { + for (num=i=0; i < 4; i++) + num += getreal(type) * pow (wbtemp/100.0, i); + cam_mul[c] = 2048 / (num * mul[c]); + } + if (tag == 2317) linear_table (len); + if (tag == 6020) iso_speed = getint(type); + if (tag == 64013) wbi = fgetc(ifp); + if ((unsigned) wbi < 7 && tag == wbtag[wbi]) + FORC3 cam_mul[c] = get4(); + if (tag == 64019) width = getint(type); + if (tag == 64020) height = (getint(type)+1) & -2; + fseek (ifp, save, SEEK_SET); + } +} + +/*RT void CLASS parse_minolta (int base); */ +/*RT int CLASS parse_tiff (int base);*/ + +int CLASS parse_tiff_ifd (int base) +{ + unsigned entries, tag, type, len, plen=16, save; + int ifd, use_cm=0, cfa, i, j, c, ima_len=0,cm_D65=0; + char software[64], *cbuf, *cp; + uchar cfa_pat[16], cfa_pc[] = { 0,1,2,3 }, tab[256]; + double cc[2][4][4], cm[2][4][3], cam_xyz[4][3], num; + double ab[]={ 1,1,1,1 }, asn[] = { 0,0,0,0 }, xyz[] = { 1,1,1 }; + unsigned sony_curve[] = { 0,0,0,0,0,4095 }; + unsigned *buf, sony_offset=0, sony_length=0, sony_key=0; + struct jhead jh; +/*RT*/ IMFILE *sfp; + + if (tiff_nifds >= sizeof tiff_ifd / sizeof tiff_ifd[0]) + return 1; + ifd = tiff_nifds++; + for (j=0; j < 4; j++) + for (i=0; i < 4; i++) + { + cc[0][j][i] = i == j; + cc[1][j][i] = i == j; + } + entries = get2(); + if (entries > 512) return 1; + while (entries--) { + tiff_get (base, &tag, &type, &len, &save); + switch (tag) { + case 5: width = get2(); break; + case 6: height = get2(); break; + case 7: width += get2(); break; + case 9: if ((i = get2())) filters = i; break; + case 17: case 18: + if (type == 3 && len == 1) + cam_mul[(tag-17)*2] = get2() / 256.0; + break; + case 23: + if (type == 3) iso_speed = get2(); + break; + case 28: case 29: case 30: + cblack[tag-28] = get2(); + cblack[3] = cblack[1]; + break; + case 36: case 37: case 38: + cam_mul[tag-36] = get2(); + break; + case 39: + if (len < 50 || cam_mul[0]) break; + fseek (ifp, 12, SEEK_CUR); + FORC3 cam_mul[c] = get2(); + break; + case 46: + if (type != 7 || fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) break; + thumb_offset = ftell(ifp) - 2; + thumb_length = len; + break; + case 61440: /* Fuji HS10 table */ + fseek (ifp, get4()+base, SEEK_SET); + parse_tiff_ifd (base); + break; + case 2: case 256: case 61441: /* ImageWidth */ + tiff_ifd[ifd].width = getint(type); + break; + case 3: case 257: case 61442: /* ImageHeight */ + tiff_ifd[ifd].height = getint(type); + break; + case 258: /* BitsPerSample */ + case 61443: + tiff_ifd[ifd].samples = len & 7; + tiff_ifd[ifd].bps = getint(type); + break; + case 61446: + raw_height = 0; + if (tiff_ifd[ifd].bps > 12) break; + load_raw = &CLASS packed_load_raw; + load_flags = get4() ? 24:80; + break; + case 259: /* Compression */ + tiff_ifd[ifd].comp = getint(type); + break; + case 262: /* PhotometricInterpretation */ + tiff_ifd[ifd].phint = get2(); + break; + case 270: /* ImageDescription */ + fread (desc, 512, 1, ifp); + break; + case 271: /* Make */ + fgets (make, 64, ifp); + break; + case 272: /* Model */ + if (strstr(model, "Hasselblad ") != model) // RT: if Hasselblad, only parse the first model name (otherwise it can change from say Hasselblad CFV-50 to Hasselblad CW (ie the camera body model, not the back model which we are interested in) + fgets (model, 64, ifp); + break; + case 280: /* Panasonic RW2 offset */ + if (type != 4) break; + load_raw = &CLASS panasonic_load_raw; + load_flags = 0x2008; + case 273: /* StripOffset */ + case 513: /* JpegIFOffset */ + case 61447: + tiff_ifd[ifd].offset = get4()+base; + if (!tiff_ifd[ifd].bps && tiff_ifd[ifd].offset > 0) { + fseek (ifp, tiff_ifd[ifd].offset, SEEK_SET); + if (ljpeg_start (&jh, 1)) { + tiff_ifd[ifd].comp = 6; + tiff_ifd[ifd].width = jh.wide; + tiff_ifd[ifd].height = jh.high; + tiff_ifd[ifd].bps = jh.bits; + tiff_ifd[ifd].samples = jh.clrs; + if (!(jh.sraw || (jh.clrs & 1))) + tiff_ifd[ifd].width *= jh.clrs; + if ((tiff_ifd[ifd].width > 4*tiff_ifd[ifd].height) & ~jh.clrs) { + tiff_ifd[ifd].width /= 2; + tiff_ifd[ifd].height *= 2; + } + i = order; + parse_tiff (tiff_ifd[ifd].offset + 12); + order = i; + } + } + break; + case 274: /* Orientation */ + tiff_ifd[ifd].flip = "50132467"[get2() & 7]-'0'; + break; + case 277: /* SamplesPerPixel */ + tiff_ifd[ifd].samples = getint(type) & 7; + break; + case 279: /* StripByteCounts */ + case 514: + case 61448: + tiff_ifd[ifd].bytes = get4(); + break; + case 61454: + FORC3 cam_mul[(4-c) % 3] = getint(type); + break; + case 305: case 11: /* Software */ + fgets (software, 64, ifp); + if (!strncmp(software,"Adobe",5) || + !strncmp(software,"dcraw",5) || + !strncmp(software,"UFRaw",5) || + !strncmp(software,"Bibble",6) || + !strncmp(software,"Nikon Scan",10) || + !strcmp (software,"Digital Photo Professional")) + is_raw = 0; + break; + case 306: /* DateTime */ + get_timestamp(0); + break; + case 315: /* Artist */ + fread (artist, 64, 1, ifp); + break; + case 317: /* Predictor */ + tiff_ifd[ifd].predictor = getint(type); + break; + case 322: /* TileWidth */ + tiff_ifd[ifd].tile_width = getint(type); + break; + case 323: /* TileLength */ + tiff_ifd[ifd].tile_length = getint(type); + break; + case 324: /* TileOffsets */ + tiff_ifd[ifd].offset = len > 1 ? ftell(ifp) : get4(); + if (len == 1) + tiff_ifd[ifd].tile_width = tiff_ifd[ifd].tile_length = 0; + if (len == 4) { + load_raw = &CLASS sinar_4shot_load_raw; + is_raw = 5; + } + break; + case 325: /* TileByteCounts */ + tiff_ifd[ifd].bytes = len > 1 ? ftell(ifp) : get4(); + break; + case 330: /* SubIFDs */ + if (!strcmp(model,"DSLR-A100") && tiff_ifd[ifd].width == 3872) { + load_raw = &CLASS sony_arw_load_raw; + data_offset = get4()+base; + ifd++; break; + } + while (len--) { + i = ftell(ifp); + fseek (ifp, get4()+base, SEEK_SET); + if (parse_tiff_ifd (base)) break; + fseek (ifp, i+4, SEEK_SET); + } + break; + case 339: + tiff_ifd[ifd].sample_format = getint(type); + break; + case 400: + strcpy (make, "Sarnoff"); + maximum = 0xfff; + break; + case 28688: + FORC4 sony_curve[c+1] = get2() >> 2 & 0xfff; + for (i=0; i < 5; i++) + for (j = sony_curve[i]+1; j <= sony_curve[i+1]; j++) + curve[j] = curve[j-1] + (1 << i); + break; + case 29184: sony_offset = get4(); break; + case 29185: sony_length = get4(); break; + case 29217: sony_key = get4(); break; + case 29264: + parse_minolta (ftell(ifp)); + raw_width = 0; + break; + case 29443: + FORC4 cam_mul[c ^ (c < 2)] = get2(); + break; + case 29459: + FORC4 cam_mul[c] = get2(); + i = (cam_mul[1] == 1024 && cam_mul[2] == 1024) << 1; + SWAP (cam_mul[i],cam_mul[i+1]) + break; + case 33405: /* Model2 */ + fgets (model2, 64, ifp); + break; + case 33421: /* CFARepeatPatternDim */ + if (get2() == 6 && get2() == 6) + filters = 9; + break; + case 33422: /* CFAPattern */ + if (filters == 9) { + FORC(36) ((char *)xtrans)[c] = fgetc(ifp) & 3; + break; + } + case 64777: /* Kodak P-series */ + if ((plen=len) > 16) plen = 16; + fread (cfa_pat, 1, plen, ifp); + for (colors=cfa=i=0; i < plen && colors < 4; i++) { + colors += !(cfa & (1 << cfa_pat[i])); + cfa |= 1 << cfa_pat[i]; + } + if (cfa == 070) memcpy (cfa_pc,"\003\004\005",3); /* CMY */ + if (cfa == 072) memcpy (cfa_pc,"\005\003\004\001",4); /* GMCY */ + goto guess_cfa_pc; + case 33424: + case 65024: + fseek (ifp, get4()+base, SEEK_SET); + parse_kodak_ifd (base); + break; + case 33434: /* ExposureTime */ + shutter = getreal(type); + break; + case 33437: /* FNumber */ + aperture = getreal(type); + break; + case 34306: /* Leaf white balance */ + FORC4 cam_mul[c ^ 1] = 4096.0 / get2(); + break; + case 34307: /* Leaf CatchLight color matrix */ + fread (software, 1, 7, ifp); + if (strncmp(software,"MATRIX",6)) break; + colors = 4; + for (raw_color = i=0; i < 3; i++) { + FORC4 fscanf (ifp, "%f", &rgb_cam[i][c^1]); + if (!use_camera_wb) continue; + num = 0; + FORC4 num += rgb_cam[i][c]; + FORC4 rgb_cam[i][c] /= num; + } + break; + case 34310: /* Leaf metadata */ + parse_mos (ftell(ifp)); + case 34303: + strcpy (make, "Leaf"); + break; + case 34665: /* EXIF tag */ + fseek (ifp, get4()+base, SEEK_SET); + parse_exif (base); + break; + case 34853: /* GPSInfo tag */ + fseek (ifp, get4()+base, SEEK_SET); + parse_gps (base); + break; + case 34675: /* InterColorProfile */ + case 50831: /* AsShotICCProfile */ + profile_offset = ftell(ifp); + profile_length = len; + break; + case 37122: /* CompressedBitsPerPixel */ + kodak_cbpp = get4(); + break; + case 37386: /* FocalLength */ + focal_len = getreal(type); + break; + case 37393: /* ImageNumber */ + shot_order = getint(type); + break; + case 37400: /* old Kodak KDC tag */ + for (raw_color = i=0; i < 3; i++) { + getreal(type); + FORC3 rgb_cam[i][c] = getreal(type); + } + break; + case 40976: + strip_offset = get4(); + switch (tiff_ifd[ifd].comp) { + case 32770: load_raw = &CLASS samsung_load_raw; break; + case 32772: load_raw = &CLASS samsung2_load_raw; break; + case 32773: load_raw = &CLASS samsung3_load_raw; break; + } + break; + case 46275: /* Imacon tags */ + strcpy (make, "Imacon"); + data_offset = ftell(ifp); + ima_len = len; + break; + case 46279: + if (!ima_len) break; + fseek (ifp, 38, SEEK_CUR); + case 46274: + fseek (ifp, 40, SEEK_CUR); + raw_width = get4(); + raw_height = get4(); + left_margin = get4() & 7; + width = raw_width - left_margin - (get4() & 7); + top_margin = get4() & 7; + height = raw_height - top_margin - (get4() & 7); + if (raw_width == 7262) { + height = 5444; + width = 7244; + left_margin = 7; + } + fseek (ifp, 52, SEEK_CUR); + FORC3 cam_mul[c] = getreal(11); + fseek (ifp, 114, SEEK_CUR); + flip = (get2() >> 7) * 90; + if (width * height * 6 == ima_len) { + if (flip % 180 == 90) SWAP(width,height); + raw_width = width; + raw_height = height; + left_margin = top_margin = filters = flip = 0; + } + sprintf (model, "Ixpress %d-Mp", height*width/1000000); + load_raw = &CLASS imacon_full_load_raw; + if (filters) { + if (left_margin & 1) filters = 0x61616161; + load_raw = &CLASS unpacked_load_raw; + } + maximum = 0xffff; + break; + case 50454: /* Sinar tag */ + case 50455: + if (!(cbuf = (char *) malloc(len))) break; + fread (cbuf, 1, len, ifp); + for (cp = cbuf-1; cp && cp < cbuf+len; cp = strchr(cp,'\n')) + if (!strncmp (++cp,"Neutral ",8)) + sscanf (cp+8, "%f %f %f", cam_mul, cam_mul+1, cam_mul+2); + free (cbuf); + break; + case 50458: + if (!make[0]) strcpy (make, "Hasselblad"); + break; + case 50459: /* Hasselblad tag */ + i = order; + j = ftell(ifp); + c = tiff_nifds; + order = get2(); + fseek (ifp, j+(get2(),get4()), SEEK_SET); + parse_tiff_ifd (j); + maximum = 0xffff; + tiff_nifds = c; + order = i; + break; + case 50706: /* DNGVersion */ + FORC4 dng_version = (dng_version << 8) + fgetc(ifp); + if (!make[0]) strcpy (make, "DNG"); + is_raw = 1; + break; + case 50708: /* UniqueCameraModel */ + fgets (model3, 64, ifp); + break; + case 50710: /* CFAPlaneColor */ + if (filters == 9) break; + if (len > 4) len = 4; + colors = len; + fread (cfa_pc, 1, colors, ifp); +guess_cfa_pc: + FORCC tab[cfa_pc[c]] = c; + cdesc[c] = 0; + for (i=16; i--; ) + filters = filters << 2 | tab[cfa_pat[i % plen]]; + filters -= !filters; + break; + case 50711: /* CFALayout */ + if (get2() == 2) { + fuji_width = 1; + filters = 0x49494949; + } + break; + case 291: + case 50712: /* LinearizationTable */ + linear_table (len); + break; + case 50713: /* BlackLevelRepeatDim */ + cblack[4] = get2(); + cblack[5] = get2(); + if (cblack[4] * cblack[5] > sizeof cblack / sizeof *cblack - 6) + cblack[4] = cblack[5] = 1; + break; + case 61450: + cblack[4] = cblack[5] = MIN(sqrt(len),64); + case 50714: /* BlackLevel */ + if(cblack[4] * cblack[5] == 0) { + int dblack[] = { 0,0,0,0 }; + black = getreal(type); + if ((unsigned)(filters+1) < 1000) break; + dblack[0] = dblack[1] = dblack[2] = dblack[3] = black; + if (colors == 3) + filters |= ((filters >> 2 & 0x22222222) | + (filters << 2 & 0x88888888)) & filters << 1; + FORC4 cblack[filters >> (c << 1) & 3] = dblack[c]; + } else { + FORC (cblack[4] * cblack[5]) + cblack[6+c] = getreal(type); + } + black = 0; + break; + case 50715: /* BlackLevelDeltaH */ + case 50716: /* BlackLevelDeltaV */ + for (num=i=0; i < len; i++) + num += getreal(type); + black += num/len + 0.5; + break; + case 50717: /* WhiteLevel */ + maximum = getint(type); + break; + case 50718: /* DefaultScale */ + pixel_aspect = getreal(type); + pixel_aspect /= getreal(type); + break; + case 50721: /* ColorMatrix1 */ + case 50722: /* ColorMatrix2 */ + FORCC for (j=0; j < 3; j++) + cm[tag-50721][c][j] = getreal(type); + use_cm = 1; + break; + case 50723: /* CameraCalibration1 */ + case 50724: /* CameraCalibration2 */ + for (i=0; i < colors; i++) + FORCC cc[tag-50723][i][c] = getreal(type); + break; + case 50727: /* AnalogBalance */ + FORCC ab[c] = getreal(type); + break; + case 50728: /* AsShotNeutral */ + FORCC asn[c] = getreal(type); + break; + case 50729: /* AsShotWhiteXY */ + xyz[0] = getreal(type); + xyz[1] = getreal(type); + xyz[2] = 1 - xyz[0] - xyz[1]; + FORC3 xyz[c] /= d65_white[c]; + break; + case 50740: /* DNGPrivateData */ + if (dng_version) break; + parse_minolta (j = get4()+base); + fseek (ifp, j, SEEK_SET); + parse_tiff_ifd (base); + break; + case 50752: + read_shorts (cr2_slice, 3); + break; + case 50778: + case 50779: + if( get2() == 21 ) + cm_D65 = (tag-50778); + break; + case 50829: /* ActiveArea */ + top_margin = getint(type); + left_margin = getint(type); + height = getint(type) - top_margin; + width = getint(type) - left_margin; + break; + case 50830: /* MaskedAreas */ + for (i=0; i < len && i < 32; i++) + ((int *)mask)[i] = getint(type); + black = 0; + break; + case 51009: /* OpcodeList2 */ + meta_offset = ftell(ifp); + break; + case 64772: /* Kodak P-series */ + if (len < 13) break; + fseek (ifp, 16, SEEK_CUR); + data_offset = get4(); + fseek (ifp, 28, SEEK_CUR); + data_offset += get4(); + load_raw = &CLASS packed_load_raw; + break; + case 65026: + if (type == 2) fgets (model2, 64, ifp); + } + fseek (ifp, save, SEEK_SET); + } + if (sony_length && (buf = (unsigned *) malloc(sony_length))) { + fseek (ifp, sony_offset, SEEK_SET); + fread (buf, sony_length, 1, ifp); + sony_decrypt (buf, sony_length/4, 1, sony_key); + sfp = ifp; +/*RT*/ ifp = fopen (buf, sony_length); +// if ((ifp = tmpfile())) { +// fwrite (buf, sony_length, 1, ifp); +// fseek (ifp, 0, SEEK_SET); + parse_tiff_ifd (-sony_offset); +// fclose (ifp); +// } + if(ifp) + fclose(ifp); + ifp = sfp; + free (buf); + } + for (i=0; i < colors; i++) + FORCC cc[cm_D65][i][c] *= ab[i]; + if (use_cm) { + FORCC for (i=0; i < 3; i++) + for (cam_xyz[c][i]=j=0; j < colors; j++) + cam_xyz[c][i] += cc[cm_D65][c][j] * cm[cm_D65][j][i] * xyz[i]; + cam_xyz_coeff (cmatrix, cam_xyz); + } + if (asn[0]) { + cam_mul[3] = 0; + FORCC cam_mul[c] = 1 / asn[c]; + } + if (!use_cm) + FORCC pre_mul[c] /= cc[cm_D65][c][c]; + return 0; +} + +int CLASS parse_tiff (int base) +{ + int doff; + /*RT*/ if (exif_base == -1) exif_base = base; + + fseek (ifp, base, SEEK_SET); + order = get2(); + if (order != 0x4949 && order != 0x4d4d) return 0; + get2(); + while ((doff = get4())) { + fseek (ifp, doff+base, SEEK_SET); + if (parse_tiff_ifd (base)) break; + } + return 1; +} + +void CLASS apply_tiff() +{ + int max_samp=0, raw=-1, thm=-1, i; + struct jhead jh; + + thumb_misc = 16; + if (thumb_offset) { + fseek (ifp, thumb_offset, SEEK_SET); + if (ljpeg_start (&jh, 1)) { + thumb_misc = jh.bits; + thumb_width = jh.wide; + thumb_height = jh.high; + } + } + for (i=0; i < tiff_nifds; i++) { + if (max_samp < tiff_ifd[i].samples) + max_samp = tiff_ifd[i].samples; + if (max_samp > 3) max_samp = 3; + if ((tiff_ifd[i].comp != 6 || tiff_ifd[i].samples != 3) && + (tiff_ifd[i].width | tiff_ifd[i].height) < 0x10000 && + tiff_ifd[i].width*tiff_ifd[i].height > raw_width*raw_height) { + raw_width = tiff_ifd[i].width; + raw_height = tiff_ifd[i].height; + tiff_bps = tiff_ifd[i].bps; + tiff_compress = tiff_ifd[i].comp; + data_offset = tiff_ifd[i].offset; + tiff_flip = tiff_ifd[i].flip; + tiff_samples = tiff_ifd[i].samples; + tile_width = tiff_ifd[i].tile_width; + tile_length = tiff_ifd[i].tile_length; + raw = i; + } + } + if (!tile_width ) tile_width = INT_MAX; + if (!tile_length) tile_length = INT_MAX; + for (i=tiff_nifds; i--; ) + if (tiff_ifd[i].flip) tiff_flip = tiff_ifd[i].flip; + if (raw >= 0 && !load_raw) + switch (tiff_compress) { + case 32767: + if (tiff_ifd[raw].bytes == raw_width*raw_height) { + tiff_bps = 12; + load_raw = &CLASS sony_arw2_load_raw; break; + } + if (tiff_ifd[raw].bytes*8 != raw_width*raw_height*tiff_bps) { + raw_height += 8; + load_raw = &CLASS sony_arw_load_raw; break; + } + load_flags = 79; + case 32769: + load_flags++; + case 32770: + case 32773: goto slr; + case 0: case 1: + if (!strncmp(make,"OLYMPUS",7) && + tiff_ifd[raw].bytes*2 == raw_width*raw_height*3) + load_flags = 24; + if (tiff_ifd[raw].bytes*5 == raw_width*raw_height*8) { + load_flags = 81; + tiff_bps = 12; + } slr: + switch (tiff_bps) { + case 8: load_raw = &CLASS eight_bit_load_raw; break; + case 12: if (tiff_ifd[raw].phint == 2) + load_flags = 6; + load_raw = &CLASS packed_load_raw; break; + case 14: load_flags = 0; + case 16: load_raw = &CLASS unpacked_load_raw; + if (!strncmp(make,"OLYMPUS",7) && + tiff_ifd[raw].bytes*7 > raw_width*raw_height) + load_raw = &CLASS olympus_load_raw; + } + break; + case 6: case 7: case 99: + load_raw = &CLASS lossless_jpeg_load_raw; break; + case 262: + load_raw = &CLASS kodak_262_load_raw; break; + case 34713: + if ((raw_width+9)/10*16*raw_height == tiff_ifd[raw].bytes) { + load_raw = &CLASS packed_load_raw; + load_flags = 1; + } else if (raw_width*raw_height*3 == tiff_ifd[raw].bytes*2) { + load_raw = &CLASS packed_load_raw; + if (model[0] == 'N') load_flags = 80; + } else if (raw_width*raw_height*3 == tiff_ifd[raw].bytes) { + load_raw = &CLASS nikon_yuv_load_raw; + gamma_curve (1/2.4, 12.92, 1, 4095); + memset (cblack, 0, sizeof cblack); + filters = 0; + } else if (raw_width*raw_height*2 == tiff_ifd[raw].bytes) { + load_raw = &CLASS unpacked_load_raw; + load_flags = 4; + order = 0x4d4d; + } else + load_raw = &CLASS nikon_load_raw; break; + case 65535: + load_raw = &CLASS pentax_load_raw; break; + case 65000: + switch (tiff_ifd[raw].phint) { + case 2: load_raw = &CLASS kodak_rgb_load_raw; filters = 0; break; + case 6: load_raw = &CLASS kodak_ycbcr_load_raw; filters = 0; break; + case 32803: load_raw = &CLASS kodak_65000_load_raw; + } + case 32867: case 34892: break; + case 8: break; + default: is_raw = 0; + } + if (!dng_version) + if ( (tiff_samples == 3 && tiff_ifd[raw].bytes && tiff_bps != 14 && + (tiff_compress & -16) != 32768) + || (tiff_bps == 8 && !strcasestr(make,"Kodak") && + !strstr(model2,"DEBUG RAW"))) + is_raw = 0; + for (i=0; i < tiff_nifds; i++) + if (i != raw && tiff_ifd[i].samples == max_samp && + tiff_ifd[i].width * tiff_ifd[i].height / (SQR(tiff_ifd[i].bps)+1) > + thumb_width * thumb_height / (SQR(thumb_misc)+1) + && tiff_ifd[i].comp != 34892) { + thumb_width = tiff_ifd[i].width; + thumb_height = tiff_ifd[i].height; + thumb_offset = tiff_ifd[i].offset; + thumb_length = tiff_ifd[i].bytes; + thumb_misc = tiff_ifd[i].bps; + thm = i; + } + if (thm >= 0) { + thumb_misc |= tiff_ifd[thm].samples << 5; + switch (tiff_ifd[thm].comp) { + case 0: + write_thumb = &CLASS layer_thumb; + break; + case 1: + if (tiff_ifd[thm].bps <= 8) + write_thumb = &CLASS ppm_thumb; + else if (!strcmp(make,"Imacon")) + write_thumb = &CLASS ppm16_thumb; + else + thumb_load_raw = &CLASS kodak_thumb_load_raw; + break; + case 65000: + thumb_load_raw = tiff_ifd[thm].phint == 6 ? + &CLASS kodak_ycbcr_load_raw : &CLASS kodak_rgb_load_raw; + } + } +} + +void CLASS parse_minolta (int base) +{ + int save, tag, len, offset, high=0, wide=0, i, c; + short sorder=order; + + fseek (ifp, base, SEEK_SET); + if (fgetc(ifp) || fgetc(ifp)-'M' || fgetc(ifp)-'R') return; + order = fgetc(ifp) * 0x101; + offset = base + get4() + 8; + while ((save=ftell(ifp)) < offset) { + for (tag=i=0; i < 4; i++) + tag = tag << 8 | fgetc(ifp); + len = get4(); + switch (tag) { + case 0x505244: /* PRD */ + fseek (ifp, 8, SEEK_CUR); + high = get2(); + wide = get2(); + break; + case 0x574247: /* WBG */ + get4(); + i = strcmp(model,"DiMAGE A200") ? 0:3; + FORC4 cam_mul[c ^ (c >> 1) ^ i] = get2(); + break; + case 0x545457: /* TTW */ + parse_tiff (ftell(ifp)); + data_offset = offset; + } + fseek (ifp, save+len+8, SEEK_SET); + } + raw_height = high; + raw_width = wide; + order = sorder; +} + +/* + Many cameras have a "debug mode" that writes JPEG and raw + at the same time. The raw file has no header, so try to + to open the matching JPEG file and read its metadata. + */ +void CLASS parse_external_jpeg() +{ + const char *file, *ext; + char *jname, *jfile, *jext; +/*RT*/ IMFILE *save=ifp; + + ext = strrchr (ifname, '.'); + file = strrchr (ifname, '/'); + if (!file) file = strrchr (ifname, '\\'); + if (!file) file = ifname-1; + file++; + if (!ext || strlen(ext) != 4 || ext-file != 8) return; + jname = (char *) malloc (strlen(ifname) + 1); + merror (jname, "parse_external_jpeg()"); + strcpy (jname, ifname); + jfile = file - ifname + jname; + jext = ext - ifname + jname; + if (strcasecmp (ext, ".jpg")) { + strcpy (jext, isupper(ext[1]) ? ".JPG":".jpg"); + if (isdigit(*file)) { + memcpy (jfile, file+4, 4); + memcpy (jfile+4, file, 4); + } + } else + while (isdigit(*--jext)) { + if (*jext != '9') { + (*jext)++; + break; + } + *jext = '0'; + } + if (strcmp (jname, ifname)) { +/*RT*/ if ((ifp = fopen (jname))) { +// if ((ifp = fopen (jname, "rb"))) { + if (verbose) + fprintf (stderr,_("Reading metadata from %s ...\n"), jname); + parse_tiff (12); + thumb_offset = 0; + is_raw = 1; + fclose (ifp); + } + } + if (!timestamp) + fprintf (stderr,_("Failed to read metadata from %s\n"), jname); + free (jname); + ifp = save; +} + +/* + CIFF block 0x1030 contains an 8x8 white sample. + Load this into white[][] for use in scale_colors(). + */ +void CLASS ciff_block_1030() +{ + static const ushort key[] = { 0x410, 0x45f3 }; + int i, bpp, row, col, vbits=0; + unsigned long bitbuf=0; + + if ((get2(),get4()) != 0x80008 || !get4()) return; + bpp = get2(); + if (bpp != 10 && bpp != 12) return; + for (i=row=0; row < 8; row++) + for (col=0; col < 8; col++) { + if (vbits < bpp) { + bitbuf = bitbuf << 16 | (get2() ^ key[i++ & 1]); + vbits += 16; + } + white[row][col] = + bitbuf << (LONG_BIT - vbits) >> (LONG_BIT - bpp); + vbits -= bpp; + } +} + +/* + Parse a CIFF file, better known as Canon CRW format. + */ +void CLASS parse_ciff (int offset, int length, int depth) +{ + int tboff, nrecs, c, type, len, save, wbi=-1; + ushort key[] = { 0x410, 0x45f3 }; + + fseek (ifp, offset+length-4, SEEK_SET); + tboff = get4() + offset; + fseek (ifp, tboff, SEEK_SET); + nrecs = get2(); + if ((nrecs | depth) > 127) return; + while (nrecs--) { + type = get2(); + len = get4(); + save = ftell(ifp) + 4; + fseek (ifp, offset+get4(), SEEK_SET); + if ((((type >> 8) + 8) | 8) == 0x38) + parse_ciff (ftell(ifp), len, depth+1); /* Parse a sub-table */ + if (type == 0x0810) + fread (artist, 64, 1, ifp); + if (type == 0x080a) { + fread (make, 64, 1, ifp); + fseek (ifp, strlen(make) - 63, SEEK_CUR); + fread (model, 64, 1, ifp); + } + if (type == 0x1810) { + width = get4(); + height = get4(); + pixel_aspect = int_to_float(get4()); + flip = get4(); + } + if (type == 0x1835) /* Get the decoder table */ + tiff_compress = get4(); + if (type == 0x2007) { + thumb_offset = ftell(ifp); + thumb_length = len; + } + if (type == 0x1818) { + shutter = pow (2, -int_to_float((get4(),get4()))); + aperture = pow (2, int_to_float(get4())/2); + } + if (type == 0x102a) { + iso_speed = pow (2, (get4(),get2())/32.0 - 4) * 50; + aperture = pow (2, (get2(),(short)get2())/64.0); + shutter = pow (2,-((short)get2())/32.0); + wbi = (get2(),get2()); + if (wbi > 17) wbi = 0; + fseek (ifp, 32, SEEK_CUR); + if (shutter > 1e6) shutter = get2()/10.0; + } + if (type == 0x102c) { + if (get2() > 512) { /* Pro90, G1 */ + fseek (ifp, 118, SEEK_CUR); + FORC4 cam_mul[c ^ 2] = get2(); + } else { /* G2, S30, S40 */ + fseek (ifp, 98, SEEK_CUR); + FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2(); + } + } + if (type == 0x0032) { + if (len == 768) { /* EOS D30 */ + fseek (ifp, 72, SEEK_CUR); + FORC4 cam_mul[c ^ (c >> 1)] = 1024.0 / get2(); + if (!wbi) cam_mul[0] = -1; /* use my auto white balance */ + } else if (!cam_mul[0]) { + if (get2() == key[0]) /* Pro1, G6, S60, S70 */ + c = (strstr(model,"Pro1") ? + "012346000000000000":"01345:000000006008")[wbi]-'0'+ 2; + else { /* G3, G5, S45, S50 */ + c = "023457000000006000"[wbi]-'0'; + key[0] = key[1] = 0; + } + fseek (ifp, 78 + c*8, SEEK_CUR); + FORC4 cam_mul[c ^ (c >> 1) ^ 1] = get2() ^ key[c & 1]; + if (!wbi) cam_mul[0] = -1; + } + } + if (type == 0x10a9) { /* D60, 10D, 300D, and clones */ + if (len > 66) wbi = "0134567028"[wbi]-'0'; + fseek (ifp, 2 + wbi*8, SEEK_CUR); + FORC4 cam_mul[c ^ (c >> 1)] = get2(); + } + if (type == 0x1030 && (0x18040 >> wbi & 1)) + ciff_block_1030(); /* all that don't have 0x10a9 */ + if (type == 0x1031) { + raw_width = (get2(),get2()); + raw_height = get2(); + } + if (type == 0x5029) { + focal_len = len >> 16; + if ((len & 0xffff) == 2) focal_len /= 32; + } + if (type == 0x5813) flash_used = int_to_float(len); + if (type == 0x5814) canon_ev = int_to_float(len); + if (type == 0x5817) shot_order = len; + if (type == 0x5834) unique_id = len; + if (type == 0x580e) timestamp = len; + if (type == 0x180e) timestamp = get4(); +#ifdef LOCALTIME + if ((type | 0x4000) == 0x580e) + timestamp = mktime (gmtime (×tamp)); +#endif + fseek (ifp, save, SEEK_SET); + } +} + +void CLASS parse_rollei() +{ + char line[128], *val; + struct tm t; + + fseek (ifp, 0, SEEK_SET); + memset (&t, 0, sizeof t); + do { + fgets (line, 128, ifp); + if ((val = strchr(line,'='))) + *val++ = 0; + else + val = line + strlen(line); + if (!strcmp(line,"DAT")) + sscanf (val, "%d.%d.%d", &t.tm_mday, &t.tm_mon, &t.tm_year); + if (!strcmp(line,"TIM")) + sscanf (val, "%d:%d:%d", &t.tm_hour, &t.tm_min, &t.tm_sec); + if (!strcmp(line,"HDR")) + thumb_offset = atoi(val); + if (!strcmp(line,"X ")) + raw_width = atoi(val); + if (!strcmp(line,"Y ")) + raw_height = atoi(val); + if (!strcmp(line,"TX ")) + thumb_width = atoi(val); + if (!strcmp(line,"TY ")) + thumb_height = atoi(val); + } while (strncmp(line,"EOHD",4)); + data_offset = thumb_offset + thumb_width * thumb_height * 2; + t.tm_year -= 1900; + t.tm_mon -= 1; + if (mktime(&t) > 0) + timestamp = mktime(&t); + strcpy (make, "Rollei"); + strcpy (model,"d530flex"); + write_thumb = &CLASS rollei_thumb; +} + +void CLASS parse_sinar_ia() +{ + int entries, off; + char str[8], *cp; + + order = 0x4949; + fseek (ifp, 4, SEEK_SET); + entries = get4(); + fseek (ifp, get4(), SEEK_SET); + while (entries--) { + off = get4(); get4(); + fread (str, 8, 1, ifp); + if (!strcmp(str,"META")) meta_offset = off; + if (!strcmp(str,"THUMB")) thumb_offset = off; + if (!strcmp(str,"RAW0")) data_offset = off; + } + fseek (ifp, meta_offset+20, SEEK_SET); + fread (make, 64, 1, ifp); + make[63] = 0; + if ((cp = strchr(make,' '))) { + strcpy (model, cp+1); + *cp = 0; + } + raw_width = get2(); + raw_height = get2(); + load_raw = &CLASS unpacked_load_raw; + thumb_width = (get4(),get2()); + thumb_height = get2(); + write_thumb = &CLASS ppm_thumb; + maximum = 0x3fff; +} + +void CLASS parse_phase_one (int base) +{ + unsigned entries, tag, type, len, data, save, i, c; + float romm_cam[3][3]; + char *cp; + + memset (&ph1, 0, sizeof ph1); + fseek (ifp, base, SEEK_SET); + order = get4() & 0xffff; + if (get4() >> 8 != 0x526177) return; /* "Raw" */ + fseek (ifp, get4()+base, SEEK_SET); + entries = get4(); + get4(); + while (entries--) { + tag = get4(); + type = get4(); + len = get4(); + data = get4(); + save = ftell(ifp); + fseek (ifp, base+data, SEEK_SET); + switch (tag) { + case 0x100: flip = "0653"[data & 3]-'0'; break; + case 0x106: + for (i=0; i < 9; i++) + ((float *)romm_cam)[i] = getreal(11); + romm_coeff (romm_cam); + break; + case 0x107: + FORC3 cam_mul[c] = getreal(11); + break; + case 0x108: raw_width = data; break; + case 0x109: raw_height = data; break; + case 0x10a: left_margin = data; break; + case 0x10b: top_margin = data; break; + case 0x10c: width = data; break; + case 0x10d: height = data; break; + case 0x10e: ph1.format = data; break; + case 0x10f: data_offset = data+base; break; + case 0x110: meta_offset = data+base; + meta_length = len; break; + case 0x112: ph1.key_off = save - 4; break; + case 0x210: ph1.tag_210 = int_to_float(data); break; + case 0x21a: ph1.tag_21a = data; break; + case 0x21c: strip_offset = data+base; break; + case 0x21d: ph1.black = data; break; + case 0x222: ph1.split_col = data; break; + case 0x223: ph1.black_col = data+base; break; + case 0x224: ph1.split_row = data; break; + case 0x225: ph1.black_row = data+base; break; + case 0x301: + model[63] = 0; + fread (model, 1, 63, ifp); + if ((cp = strstr(model," camera"))) *cp = 0; + } + fseek (ifp, save, SEEK_SET); + } + load_raw = ph1.format < 3 ? + &CLASS phase_one_load_raw : &CLASS phase_one_load_raw_c; + maximum = 0xffff; + tiff_bps = 16; + strcpy (make, "Phase One"); + if (model[0]) return; + switch (raw_height) { + case 2060: strcpy (model,"LightPhase"); break; + case 2682: strcpy (model,"H 10"); break; + case 4128: strcpy (model,"H 20"); break; + case 5488: strcpy (model,"H 25"); break; + } +} + +void CLASS parse_fuji (int offset) +{ + unsigned entries, tag, len, save, c; + + fseek (ifp, offset, SEEK_SET); + entries = get4(); + if (entries > 255) return; + while (entries--) { + tag = get2(); + len = get2(); + save = ftell(ifp); + if (tag == 0x100) { + raw_height = get2(); + raw_width = get2(); + } else if (tag == 0x121) { + height = get2(); + if ((width = get2()) == 4284) width += 3; + } else if (tag == 0x130) { + fuji_layout = fgetc(ifp) >> 7; + fuji_width = !(fgetc(ifp) & 8); + } else if (tag == 0x131) { + filters = 9; + FORC(36) xtrans_abs[0][35-c] = fgetc(ifp) & 3; + } else if (tag == 0x2ff0) { + FORC4 cam_mul[c ^ 1] = get2(); + } else if (tag == 0xc000) { + c = order; + order = 0x4949; + if ((tag = get4()) > 10000) tag = get4(); + width = tag; + height = get4(); + order = c; + } + fseek (ifp, save+len, SEEK_SET); + } + height <<= fuji_layout; + width >>= fuji_layout; +} + +int CLASS parse_jpeg (int offset) +{ + int len, save, hlen, mark; + + fseek (ifp, offset, SEEK_SET); + if (fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) return 0; + + while (fgetc(ifp) == 0xff && (mark = fgetc(ifp)) != 0xda) { + order = 0x4d4d; + len = get2() - 2; + save = ftell(ifp); + if (mark == 0xc0 || mark == 0xc3) { + fgetc(ifp); + raw_height = get2(); + raw_width = get2(); + } + order = get2(); + hlen = get4(); + if (get4() == 0x48454150) /* "HEAP" */ +/*RT*/ { +/*RT*/ ciff_base = save+hlen; +/*RT*/ ciff_len = len-hlen; + parse_ciff (save+hlen, len-hlen, 0); +/*RT*/ } + if (parse_tiff (save+6)) apply_tiff(); + fseek (ifp, save+len, SEEK_SET); + } + return 1; +} + +void CLASS parse_riff() +{ + unsigned i, size, end; + char tag[4], date[64], month[64]; + static const char mon[12][4] = + { "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" }; + struct tm t; + + order = 0x4949; + fread (tag, 4, 1, ifp); + size = get4(); + end = ftell(ifp) + size; + if (!memcmp(tag,"RIFF",4) || !memcmp(tag,"LIST",4)) { + get4(); + while (ftell(ifp)+7 < end && !feof(ifp)) + parse_riff(); + } else if (!memcmp(tag,"nctg",4)) { + while (ftell(ifp)+7 < end) { + i = get2(); + size = get2(); + if ((i+1) >> 1 == 10 && size == 20) + get_timestamp(0); + else fseek (ifp, size, SEEK_CUR); + } + } else if (!memcmp(tag,"IDIT",4) && size < 64) { + fread (date, 64, 1, ifp); + date[size] = 0; + memset (&t, 0, sizeof t); + if (sscanf (date, "%*s %s %d %d:%d:%d %d", month, &t.tm_mday, + &t.tm_hour, &t.tm_min, &t.tm_sec, &t.tm_year) == 6) { + for (i=0; i < 12 && strcasecmp(mon[i],month); i++); + t.tm_mon = i; + t.tm_year -= 1900; + if (mktime(&t) > 0) + timestamp = mktime(&t); + } + } else + fseek (ifp, size, SEEK_CUR); +} + +void CLASS parse_qt (int end) +{ + unsigned save, size; + char tag[4]; + + order = 0x4d4d; + while (ftell(ifp)+7 < end) { + save = ftell(ifp); + if ((size = get4()) < 8) return; + fread (tag, 4, 1, ifp); + if (!memcmp(tag,"moov",4) || + !memcmp(tag,"udta",4) || + !memcmp(tag,"CNTH",4)) + parse_qt (save+size); + if (!memcmp(tag,"CNDA",4)) + parse_jpeg (ftell(ifp)); + fseek (ifp, save+size, SEEK_SET); + } +} + +void CLASS parse_smal (int offset, int fsize) +{ + int ver; + + fseek (ifp, offset+2, SEEK_SET); + order = 0x4949; + ver = fgetc(ifp); + if (ver == 6) + fseek (ifp, 5, SEEK_CUR); + if (get4() != fsize) return; + if (ver > 6) data_offset = get4(); + raw_height = height = get2(); + raw_width = width = get2(); + strcpy (make, "SMaL"); + sprintf (model, "v%d %dx%d", ver, width, height); + if (ver == 6) load_raw = &CLASS smal_v6_load_raw; + if (ver == 9) load_raw = &CLASS smal_v9_load_raw; +} + +void CLASS parse_cine() +{ + unsigned off_head, off_setup, off_image, i; + + order = 0x4949; + fseek (ifp, 4, SEEK_SET); + is_raw = get2() == 2; + fseek (ifp, 14, SEEK_CUR); + is_raw *= get4(); + off_head = get4(); + off_setup = get4(); + off_image = get4(); + timestamp = get4(); + if ((i = get4())) timestamp = i; + fseek (ifp, off_head+4, SEEK_SET); + raw_width = get4(); + raw_height = get4(); + switch (get2(),get2()) { + case 8: load_raw = &CLASS eight_bit_load_raw; break; + case 16: load_raw = &CLASS unpacked_load_raw; + } + fseek (ifp, off_setup+792, SEEK_SET); + strcpy (make, "CINE"); + sprintf (model, "%d", get4()); + fseek (ifp, 12, SEEK_CUR); + switch ((i=get4()) & 0xffffff) { + case 3: filters = 0x94949494; break; + case 4: filters = 0x49494949; break; + default: is_raw = 0; + } + fseek (ifp, 72, SEEK_CUR); + switch ((get4()+3600) % 360) { + case 270: flip = 4; break; + case 180: flip = 1; break; + case 90: flip = 7; break; + case 0: flip = 2; + } + cam_mul[0] = getreal(11); + cam_mul[2] = getreal(11); + maximum = ~(-1 << get4()); + fseek (ifp, 668, SEEK_CUR); + shutter = get4()/1000000000.0; + fseek (ifp, off_image, SEEK_SET); + if (shot_select < is_raw) + fseek (ifp, shot_select*8, SEEK_CUR); + data_offset = (INT64) get4() + 8; + data_offset += (INT64) get4() << 32; +} + +void CLASS parse_redcine() +{ + unsigned i, len, rdvo; + + order = 0x4d4d; + is_raw = 0; + fseek (ifp, 52, SEEK_SET); + width = get4(); + height = get4(); + fseek (ifp, 0, SEEK_END); + fseek (ifp, -(i = ftello(ifp) & 511), SEEK_CUR); + if (get4() != i || get4() != 0x52454f42) { + fprintf (stderr,_("%s: Tail is missing, parsing from head...\n"), ifname); + fseek (ifp, 0, SEEK_SET); + while ((len = get4()) != EOF) { + if (get4() == 0x52454456) + if (is_raw++ == shot_select) + data_offset = ftello(ifp) - 8; + fseek (ifp, len-8, SEEK_CUR); + } + } else { + rdvo = get4(); + fseek (ifp, 12, SEEK_CUR); + is_raw = get4(); + fseeko (ifp, rdvo+8 + shot_select*4, SEEK_SET); + data_offset = get4(); + } +} + +char * CLASS foveon_gets (int offset, char *str, int len) +{ + int i; + fseek (ifp, offset, SEEK_SET); + for (i=0; i < len-1; i++) + if ((str[i] = get2()) == 0) break; + str[i] = 0; + return str; +} + +void CLASS parse_foveon() +{ + int entries, img=0, off, len, tag, save, i, wide, high, pent, poff[256][2]; + char name[64], value[64]; + + order = 0x4949; /* Little-endian */ + fseek (ifp, 36, SEEK_SET); + flip = get4(); + fseek (ifp, -4, SEEK_END); + fseek (ifp, get4(), SEEK_SET); + if (get4() != 0x64434553) return; /* SECd */ + entries = (get4(),get4()); + while (entries--) { + off = get4(); + len = get4(); + tag = get4(); + save = ftell(ifp); + fseek (ifp, off, SEEK_SET); + if (get4() != (0x20434553 | (tag << 24))) return; + switch (tag) { + case 0x47414d49: /* IMAG */ + case 0x32414d49: /* IMA2 */ + fseek (ifp, 8, SEEK_CUR); + pent = get4(); + wide = get4(); + high = get4(); + if (wide > raw_width && high > raw_height) { + switch (pent) { + case 5: load_flags = 1; + case 6: load_raw = &CLASS foveon_sd_load_raw; break; + case 30: load_raw = &CLASS foveon_dp_load_raw; break; + default: load_raw = 0; + } + raw_width = wide; + raw_height = high; + data_offset = off+28; + is_foveon = 1; + } + fseek (ifp, off+28, SEEK_SET); + if (fgetc(ifp) == 0xff && fgetc(ifp) == 0xd8 + && thumb_length < len-28) { + thumb_offset = off+28; + thumb_length = len-28; + write_thumb = &CLASS jpeg_thumb; + } + if (++img == 2 && !thumb_length) { + thumb_offset = off+24; + thumb_width = wide; + thumb_height = high; + write_thumb = &CLASS foveon_thumb; + } + break; + case 0x464d4143: /* CAMF */ + meta_offset = off+8; + meta_length = len-28; + break; + case 0x504f5250: /* PROP */ + pent = (get4(),get4()); + fseek (ifp, 12, SEEK_CUR); + off += pent*8 + 24; + if ((unsigned) pent > 256) pent=256; + for (i=0; i < pent*2; i++) + ((int *)poff)[i] = off + get4()*2; + for (i=0; i < pent; i++) { + foveon_gets (poff[i][0], name, 64); + foveon_gets (poff[i][1], value, 64); + if (!strcmp (name, "ISO")) + iso_speed = atoi(value); + if (!strcmp (name, "CAMMANUF")) + strcpy (make, value); + if (!strcmp (name, "CAMMODEL")) + strcpy (model, value); + if (!strcmp (name, "WB_DESC")) + strcpy (model2, value); + if (!strcmp (name, "TIME")) + timestamp = atoi(value); + if (!strcmp (name, "EXPTIME")) + shutter = atoi(value) / 1000000.0; + if (!strcmp (name, "APERTURE")) + aperture = atof(value); + if (!strcmp (name, "FLENGTH")) + focal_len = atof(value); + } +#ifdef LOCALTIME + timestamp = mktime (gmtime (×tamp)); +#endif + } + fseek (ifp, save, SEEK_SET); + } +} + +/* + All matrices are from Adobe DNG Converter unless otherwise noted. + */ +void CLASS adobe_coeff (const char *make, const char *model) +{ + static const struct { + const char *prefix; + unsigned short black, maximum; // RT: Change to UShort + short trans[12]; + } table[] = { + { "AgfaPhoto DC-833m", 0, 0, /* DJC */ + { 11438,-3762,-1115,-2409,9914,2497,-1227,2295,5300 } }, + { "Apple QuickTake", 0, 0, /* DJC */ + { 21392,-5653,-3353,2406,8010,-415,7166,1427,2078 } }, + { "Canon EOS D2000", 0, 0, + { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } }, + { "Canon EOS D6000", 0, 0, + { 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } }, + { "Canon EOS D30", 0, 0, + { 9805,-2689,-1312,-5803,13064,3068,-2438,3075,8775 } }, + { "Canon EOS D60", 0, 0xfa0, + { 6188,-1341,-890,-7168,14489,2937,-2640,3228,8483 } }, + { "Canon EOS 5DS", 0, 0x3c96, /* DJC */ + { 6885,-753,-856,-4416,11752,2665,-1266,2393,5468 } }, + { "Canon EOS 5D Mark III", 0, 0x3c80, + { 6722,-635,-963,-4287,12460,2028,-908,2162,5668 } }, + { "Canon EOS 5D Mark II", 0, 0x3cf0, + { 4716,603,-830,-7798,15474,2480,-1496,1937,6651 } }, + { "Canon EOS 5D", 0, 0xe6c, + { 6347,-479,-972,-8297,15954,2480,-1968,2131,7649 } }, + { "Canon EOS 6D", 0, 0x3c82, + { 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } }, + { "Canon EOS 7D Mark II", 0, 0x3510, + { 7268,-1082,-969,-4186,11839,2663,-825,2029,5839 } }, + { "Canon EOS 7D", 0, 0x3510, + { 6844,-996,-856,-3876,11761,2396,-593,1772,6198 } }, + { "Canon EOS 10D", 0, 0xfa0, + { 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } }, + { "Canon EOS 20Da", 0, 0, + { 14155,-5065,-1382,-6550,14633,2039,-1623,1824,6561 } }, + { "Canon EOS 20D", 0, 0xfff, + { 6599,-537,-891,-8071,15783,2424,-1983,2234,7462 } }, + { "Canon EOS 30D", 0, 0, + { 6257,-303,-1000,-7880,15621,2396,-1714,1904,7046 } }, + { "Canon EOS 40D", 0, 0x3f60, + { 6071,-747,-856,-7653,15365,2441,-2025,2553,7315 } }, + { "Canon EOS 50D", 0, 0x3d93, + { 4920,616,-593,-6493,13964,2784,-1774,3178,7005 } }, + { "Canon EOS 60D", 0, 0x2ff7, + { 6719,-994,-925,-4408,12426,2211,-887,2129,6051 } }, + { "Canon EOS 70D", 0, 0x3bc7, + { 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } }, + { "Canon EOS 100D", 0, 0x350f, + { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } }, + { "Canon EOS 300D", 0, 0xfa0, + { 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } }, + { "Canon EOS 350D", 0, 0xfff, + { 6018,-617,-965,-8645,15881,2975,-1530,1719,7642 } }, + { "Canon EOS 400D", 0, 0xe8e, + { 7054,-1501,-990,-8156,15544,2812,-1278,1414,7796 } }, + { "Canon EOS 450D", 0, 0x390d, + { 5784,-262,-821,-7539,15064,2672,-1982,2681,7427 } }, + { "Canon EOS 500D", 0, 0x3479, + { 4763,712,-646,-6821,14399,2640,-1921,3276,6561 } }, + { "Canon EOS 550D", 0, 0x3dd7, + { 6941,-1164,-857,-3825,11597,2534,-416,1540,6039 } }, + { "Canon EOS 600D", 0, 0x3510, + { 6461,-907,-882,-4300,12184,2378,-819,1944,5931 } }, + { "Canon EOS 650D", 0, 0x354d, + { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } }, + { "Canon EOS 700D", 0, 0x3c00, + { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } }, + { "Canon EOS 1000D", 0, 0xe43, + { 6771,-1139,-977,-7818,15123,2928,-1244,1437,7533 } }, + { "Canon EOS 1100D", 0, 0x3510, + { 6444,-904,-893,-4563,12308,2535,-903,2016,6728 } }, + { "Canon EOS 1200D", 0, 0x37c2, + { 6461,-907,-882,-4300,12184,2378,-819,1944,5931 } }, + { "Canon EOS M", 0, 0, + { 6602,-841,-939,-4472,12458,2247,-975,2039,6148 } }, + { "Canon EOS-1Ds Mark III", 0, 0x3bb0, + { 5859,-211,-930,-8255,16017,2353,-1732,1887,7448 } }, + { "Canon EOS-1Ds Mark II", 0, 0xe80, + { 6517,-602,-867,-8180,15926,2378,-1618,1771,7633 } }, + { "Canon EOS-1D Mark IV", 0, 0x3bb0, + { 6014,-220,-795,-4109,12014,2361,-561,1824,5787 } }, + { "Canon EOS-1D Mark III", 0, 0x3bb0, + { 6291,-540,-976,-8350,16145,2311,-1714,1858,7326 } }, + { "Canon EOS-1D Mark II N", 0, 0xe80, + { 6240,-466,-822,-8180,15825,2500,-1801,1938,8042 } }, + { "Canon EOS-1D Mark II", 0, 0xe80, + { 6264,-582,-724,-8312,15948,2504,-1744,1919,8664 } }, + { "Canon EOS-1DS", 0, 0xe20, + { 4374,3631,-1743,-7520,15212,2472,-2892,3632,8161 } }, + { "Canon EOS-1D C", 0, 0x3c4e, + { 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } }, + { "Canon EOS-1D X", 0, 0x3c4e, + { 6847,-614,-1014,-4669,12737,2139,-1197,2488,6846 } }, + { "Canon EOS-1D", 0, 0xe20, + { 6806,-179,-1020,-8097,16415,1687,-3267,4236,7690 } }, + { "Canon EOS C500", 853, 0, /* DJC */ + { 17851,-10604,922,-7425,16662,763,-3660,3636,22278 } }, + { "Canon PowerShot A530", 0, 0, + { 0 } }, /* don't want the A5 matrix */ + { "Canon PowerShot A50", 0, 0, + { -5300,9846,1776,3436,684,3939,-5540,9879,6200,-1404,11175,217 } }, + { "Canon PowerShot A5", 0, 0, + { -4801,9475,1952,2926,1611,4094,-5259,10164,5947,-1554,10883,547 } }, + { "Canon PowerShot G10", 0, 0, + { 11093,-3906,-1028,-5047,12492,2879,-1003,1750,5561 } }, + { "Canon PowerShot G11", 0, 0, + { 12177,-4817,-1069,-1612,9864,2049,-98,850,4471 } }, + { "Canon PowerShot G12", 0, 0, + { 13244,-5501,-1248,-1508,9858,1935,-270,1083,4366 } }, + { "Canon PowerShot G15", 0, 0, + { 7474,-2301,-567,-4056,11456,2975,-222,716,4181 } }, + { "Canon PowerShot G16", 0, 0, + { 8020,-2687,-682,-3704,11879,2052,-965,1921,5556 } }, + { "Canon PowerShot G1 X", 0, 0, + { 7378,-1255,-1043,-4088,12251,2048,-876,1946,5805 } }, + { "Canon PowerShot G1", 0, 0, + { -4778,9467,2172,4743,-1141,4344,-5146,9908,6077,-1566,11051,557 } }, + { "Canon PowerShot G2", 0, 0, + { 9087,-2693,-1049,-6715,14382,2537,-2291,2819,7790 } }, + { "Canon PowerShot G3", 0, 0, + { 9212,-2781,-1073,-6573,14189,2605,-2300,2844,7664 } }, + { "Canon PowerShot G5", 0, 0, + { 9757,-2872,-933,-5972,13861,2301,-1622,2328,7212 } }, + { "Canon PowerShot G6", 0, 0, + { 9877,-3775,-871,-7613,14807,3072,-1448,1305,7485 } }, + { "Canon PowerShot G7 X", 0, 0, + { 9602,-3823,-937,-2984,11495,1675,-407,1415,5049 } }, + { "Canon PowerShot G9", 0, 0, + { 7368,-2141,-598,-5621,13254,2625,-1418,1696,5743 } }, + { "Canon PowerShot Pro1", 0, 0, + { 10062,-3522,-999,-7643,15117,2730,-765,817,7323 } }, + { "Canon PowerShot Pro70", 34, 0, + { -4155,9818,1529,3939,-25,4522,-5521,9870,6610,-2238,10873,1342 } }, + { "Canon PowerShot Pro90", 0, 0, + { -4963,9896,2235,4642,-987,4294,-5162,10011,5859,-1770,11230,577 } }, + { "Canon PowerShot S30", 0, 0, + { 10566,-3652,-1129,-6552,14662,2006,-2197,2581,7670 } }, + { "Canon PowerShot S40", 0, 0, + { 8510,-2487,-940,-6869,14231,2900,-2318,2829,9013 } }, + { "Canon PowerShot S45", 0, 0, + { 8163,-2333,-955,-6682,14174,2751,-2077,2597,8041 } }, + { "Canon PowerShot S50", 0, 0, + { 8882,-2571,-863,-6348,14234,2288,-1516,2172,6569 } }, + { "Canon PowerShot S60", 0, 0, + { 8795,-2482,-797,-7804,15403,2573,-1422,1996,7082 } }, + { "Canon PowerShot S70", 0, 0, + { 9976,-3810,-832,-7115,14463,2906,-901,989,7889 } }, + { "Canon PowerShot S90", 0, 0, + { 12374,-5016,-1049,-1677,9902,2078,-83,852,4683 } }, + { "Canon PowerShot S95", 0, 0, + { 13440,-5896,-1279,-1236,9598,1931,-180,1001,4651 } }, + { "Canon PowerShot S100", 0, 0, + { 7968,-2565,-636,-2873,10697,2513,180,667,4211 } }, + { "Canon PowerShot S110", 0, 0, + { 8039,-2643,-654,-3783,11230,2930,-206,690,4194 } }, + { "Canon PowerShot S120", 0, 0, + { 6961,-1685,-695,-4625,12945,1836,-1114,2152,5518 } }, + { "Canon PowerShot SX1 IS", 0, 0, + { 6578,-259,-502,-5974,13030,3309,-308,1058,4970 } }, + { "Canon PowerShot SX50 HS", 0, 0, + { 12432,-4753,-1247,-2110,10691,1629,-412,1623,4926 } }, + { "Canon PowerShot SX60 HS", 0, 0, + { 13161,-5451,-1344,-1989,10654,1531,-47,1271,4955 } }, + { "Canon PowerShot A3300", 0, 0, /* DJC */ + { 10826,-3654,-1023,-3215,11310,1906,0,999,4960 } }, + { "Canon PowerShot A470", 0, 0, /* DJC */ + { 12513,-4407,-1242,-2680,10276,2405,-878,2215,4734 } }, + { "Canon PowerShot A610", 0, 0, /* DJC */ + { 15591,-6402,-1592,-5365,13198,2168,-1300,1824,5075 } }, + { "Canon PowerShot A620", 0, 0, /* DJC */ + { 15265,-6193,-1558,-4125,12116,2010,-888,1639,5220 } }, + { "Canon PowerShot A630", 0, 0, /* DJC */ + { 14201,-5308,-1757,-6087,14472,1617,-2191,3105,5348 } }, + { "Canon PowerShot A640", 0, 0, /* DJC */ + { 13124,-5329,-1390,-3602,11658,1944,-1612,2863,4885 } }, + { "Canon PowerShot A650", 0, 0, /* DJC */ + { 9427,-3036,-959,-2581,10671,1911,-1039,1982,4430 } }, + { "Canon PowerShot A720", 0, 0, /* DJC */ + { 14573,-5482,-1546,-1266,9799,1468,-1040,1912,3810 } }, + { "Canon PowerShot S3 IS", 0, 0, /* DJC */ + { 14062,-5199,-1446,-4712,12470,2243,-1286,2028,4836 } }, + { "Canon PowerShot SX110 IS", 0, 0, /* DJC */ + { 14134,-5576,-1527,-1991,10719,1273,-1158,1929,3581 } }, + { "Canon PowerShot SX220", 0, 0, /* DJC */ + { 13898,-5076,-1447,-1405,10109,1297,-244,1860,3687 } }, + { "Casio EX-S20", 0, 0, /* DJC */ + { 11634,-3924,-1128,-4968,12954,2015,-1588,2648,7206 } }, + { "Casio EX-Z750", 0, 0, /* DJC */ + { 10819,-3873,-1099,-4903,13730,1175,-1755,3751,4632 } }, + { "Casio EX-Z10", 128, 0xfff, /* DJC */ + { 9790,-3338,-603,-2321,10222,2099,-344,1273,4799 } }, + { "CINE 650", 0, 0, + { 3390,480,-500,-800,3610,340,-550,2336,1192 } }, + { "CINE 660", 0, 0, + { 3390,480,-500,-800,3610,340,-550,2336,1192 } }, + { "CINE", 0, 0, + { 20183,-4295,-423,-3940,15330,3985,-280,4870,9800 } }, + { "Contax N Digital", 0, 0xf1e, + { 7777,1285,-1053,-9280,16543,2916,-3677,5679,7060 } }, + { "Epson R-D1", 0, 0, + { 6827,-1878,-732,-8429,16012,2564,-704,592,7145 } }, + { "Fujifilm E550", 0, 0, + { 11044,-3888,-1120,-7248,15168,2208,-1531,2277,8069 } }, + { "Fujifilm E900", 0, 0, + { 9183,-2526,-1078,-7461,15071,2574,-2022,2440,8639 } }, + { "Fujifilm F5", 0, 0, + { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, + { "Fujifilm F6", 0, 0, + { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, + { "Fujifilm F77", 0, 0xfe9, + { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, + { "Fujifilm F7", 0, 0, + { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } }, + { "Fujifilm F8", 0, 0, + { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, + { "Fujifilm S100FS", 514, 0, + { 11521,-4355,-1065,-6524,13767,3058,-1466,1984,6045 } }, + { "Fujifilm S1", 0, 0, + { 12297,-4882,-1202,-2106,10691,1623,-88,1312,4790 } }, + { "Fujifilm S20Pro", 0, 0, + { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } }, + { "Fujifilm S20", 512, 0x3fff, + { 11401,-4498,-1312,-5088,12751,2613,-838,1568,5941 } }, + { "Fujifilm S2Pro", 128, 0, + { 12492,-4690,-1402,-7033,15423,1647,-1507,2111,7697 } }, + { "Fujifilm S3Pro", 0, 0, + { 11807,-4612,-1294,-8927,16968,1988,-2120,2741,8006 } }, + { "Fujifilm S5Pro", 0, 0, + { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } }, + { "Fujifilm S5000", 0, 0, + { 8754,-2732,-1019,-7204,15069,2276,-1702,2334,6982 } }, + { "Fujifilm S5100", 0, 0, + { 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } }, + { "Fujifilm S5500", 0, 0, + { 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } }, + { "Fujifilm S5200", 0, 0, + { 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } }, + { "Fujifilm S5600", 0, 0, + { 9636,-2804,-988,-7442,15040,2589,-1803,2311,8621 } }, + { "Fujifilm S6", 0, 0, + { 12628,-4887,-1401,-6861,14996,1962,-2198,2782,7091 } }, + { "Fujifilm S7000", 0, 0, + { 10190,-3506,-1312,-7153,15051,2238,-2003,2399,7505 } }, + { "Fujifilm S9000", 0, 0, + { 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } }, + { "Fujifilm S9500", 0, 0, + { 10491,-3423,-1145,-7385,15027,2538,-1809,2275,8692 } }, + { "Fujifilm S9100", 0, 0, + { 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } }, + { "Fujifilm S9600", 0, 0, + { 12343,-4515,-1285,-7165,14899,2435,-1895,2496,8800 } }, + { "Fujifilm SL1000", 0, 0, + { 11705,-4262,-1107,-2282,10791,1709,-555,1713,4945 } }, + { "Fujifilm IS-1", 0, 0, + { 21461,-10807,-1441,-2332,10599,1999,289,875,7703 } }, + { "Fujifilm IS Pro", 0, 0, + { 12300,-5110,-1304,-9117,17143,1998,-1947,2448,8100 } }, + { "Fujifilm HS10 HS11", 0, 0xf68, + { 12440,-3954,-1183,-1123,9674,1708,-83,1614,4086 } }, + { "Fujifilm HS2", 0, 0, + { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, + { "Fujifilm HS3", 0, 0, + { 13690,-5358,-1474,-3369,11600,1998,-132,1554,4395 } }, + { "Fujifilm HS50EXR", 0, 0, + { 12085,-4727,-953,-3257,11489,2002,-511,2046,4592 } }, + { "Fujifilm F900EXR", 0, 0, + { 12085,-4727,-953,-3257,11489,2002,-511,2046,4592 } }, + { "Fujifilm X100S", 0, 0, + { 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 } }, + { "Fujifilm X100T", 0, 0, + { 10592,-4262,-1008,-3514,11355,2465,-870,2025,6386 } }, + { "Fujifilm X100", 0, 0, + { 12161,-4457,-1069,-5034,12874,2400,-795,1724,6904 } }, + { "Fujifilm X10", 0, 0, + { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, + { "Fujifilm X20", 0, 0, + { 11768,-4971,-1133,-4904,12927,2183,-480,1723,4605 } }, + { "Fujifilm X30", 0, 0, + { 12328,-5256,-1144,-4469,12927,1675,-87,1291,4351 } }, + { "Fujifilm X-Pro1", 0, 0, + { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, + { "Fujifilm X-A1", 0, 0, + { 11086,-4555,-839,-3512,11310,2517,-815,1341,5940 } }, + { "Fujifilm X-A2", 0, 0, + { 10763,-4560,-917,-3346,11311,2322,-475,1135,5843 } }, + { "Fujifilm X-E1", 0, 0, + { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, + { "Fujifilm X-E2", 0, 0, + { 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 } }, + { "Fujifilm X-M1", 0, 0, + { 10413,-3996,-993,-3721,11640,2361,-733,1540,6011 } }, + { "Fujifilm X-S1", 0, 0, + { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, + { "Fujifilm X-T1", 0, 0, + { 8458,-2451,-855,-4597,12447,2407,-1475,2482,6526 } }, + { "Fujifilm XF1", 0, 0, + { 13509,-6199,-1254,-4430,12733,1865,-331,1441,5022 } }, + { "Fujifilm XQ", 0, 0, // XQ1 and XQ2 + { 9252,-2704,-1064,-5893,14265,1717,-1101,2341,4349 } }, + { "Imacon Ixpress", 0, 0, /* DJC */ + { 7025,-1415,-704,-5188,13765,1424,-1248,2742,6038 } }, + { "Kodak NC2000", 0, 0, + { 13891,-6055,-803,-465,9919,642,2121,82,1291 } }, + { "Kodak DCS315C", 8, 0, + { 17523,-4827,-2510,756,8546,-137,6113,1649,2250 } }, + { "Kodak DCS330C", 8, 0, + { 20620,-7572,-2801,-103,10073,-396,3551,-233,2220 } }, + { "Kodak DCS420", 0, 0, + { 10868,-1852,-644,-1537,11083,484,2343,628,2216 } }, + { "Kodak DCS460", 0, 0, + { 10592,-2206,-967,-1944,11685,230,2206,670,1273 } }, + { "Kodak EOSDCS1", 0, 0, + { 10592,-2206,-967,-1944,11685,230,2206,670,1273 } }, + { "Kodak EOSDCS3B", 0, 0, + { 9898,-2700,-940,-2478,12219,206,1985,634,1031 } }, + { "Kodak DCS520C", 178, 0, + { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } }, + { "Kodak DCS560C", 177, 0, + { 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } }, + { "Kodak DCS620C", 177, 0, + { 23617,-10175,-3149,-2054,11749,-272,2586,-489,3453 } }, + { "Kodak DCS620X", 176, 0, + { 13095,-6231,154,12221,-21,-2137,895,4602,2258 } }, + { "Kodak DCS660C", 173, 0, + { 18244,-6351,-2739,-791,11193,-521,3711,-129,2802 } }, + { "Kodak DCS720X", 0, 0, + { 11775,-5884,950,9556,1846,-1286,-1019,6221,2728 } }, + { "Kodak DCS760C", 0, 0, + { 16623,-6309,-1411,-4344,13923,323,2285,274,2926 } }, + { "Kodak DCS Pro SLR", 0, 0, + { 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } }, + { "Kodak DCS Pro 14nx", 0, 0, + { 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } }, + { "Kodak DCS Pro 14", 0, 0, + { 7791,3128,-776,-8588,16458,2039,-2455,4006,6198 } }, + { "Kodak ProBack645", 0, 0, + { 16414,-6060,-1470,-3555,13037,473,2545,122,4948 } }, + { "Kodak ProBack", 0, 0, + { 21179,-8316,-2918,-915,11019,-165,3477,-180,4210 } }, + { "Kodak P712", 0, 0, + { 9658,-3314,-823,-5163,12695,2768,-1342,1843,6044 } }, + { "Kodak P850", 0, 0xf7c, + { 10511,-3836,-1102,-6946,14587,2558,-1481,1792,6246 } }, + { "Kodak P880", 0, 0xfff, + { 12805,-4662,-1376,-7480,15267,2360,-1626,2194,7904 } }, + { "Kodak EasyShare Z980", 0, 0, + { 11313,-3559,-1101,-3893,11891,2257,-1214,2398,4908 } }, + { "Kodak EasyShare Z981", 0, 0, + { 12729,-4717,-1188,-1367,9187,2582,274,860,4411 } }, + { "Kodak EasyShare Z990", 0, 0xfed, + { 11749,-4048,-1309,-1867,10572,1489,-138,1449,4522 } }, + { "Kodak EASYSHARE Z1015", 0, 0xef1, + { 11265,-4286,-992,-4694,12343,2647,-1090,1523,5447 } }, + { "Leaf CMost", 0, 0, + { 3952,2189,449,-6701,14585,2275,-4536,7349,6536 } }, + { "Leaf Valeo 6", 0, 0, + { 3952,2189,449,-6701,14585,2275,-4536,7349,6536 } }, + { "Leaf Aptus 54S", 0, 0, + { 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 } }, + { "Leaf Aptus 65", 0, 0, + { 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } }, + { "Leaf Aptus 75", 0, 0, + { 7914,1414,-1190,-8777,16582,2280,-2811,4605,5562 } }, + { "Leaf", 0, 0, + { 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 } }, + { "Mamiya ZD", 0, 0, + { 7645,2579,-1363,-8689,16717,2015,-3712,5941,5961 } }, + { "Micron 2010", 110, 0, /* DJC */ + { 16695,-3761,-2151,155,9682,163,3433,951,4904 } }, + { "Minolta DiMAGE 5", 0, 0xf7d, + { 8983,-2942,-963,-6556,14476,2237,-2426,2887,8014 } }, + { "Minolta DiMAGE 7Hi", 0, 0xf7d, + { 11368,-3894,-1242,-6521,14358,2339,-2475,3056,7285 } }, + { "Minolta DiMAGE 7", 0, 0xf7d, + { 9144,-2777,-998,-6676,14556,2281,-2470,3019,7744 } }, + { "Minolta DiMAGE A1", 0, 0xf8b, + { 9274,-2547,-1167,-8220,16323,1943,-2273,2720,8340 } }, + { "Minolta DiMAGE A200", 0, 0, + { 8560,-2487,-986,-8112,15535,2771,-1209,1324,7743 } }, + { "Minolta DiMAGE A2", 0, 0xf8f, + { 9097,-2726,-1053,-8073,15506,2762,-966,981,7763 } }, + { "Minolta DiMAGE Z2", 0, 0, /* DJC */ + { 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } }, + { "Minolta DYNAX 5", 0, 0xffb, + { 10284,-3283,-1086,-7957,15762,2316,-829,882,6644 } }, + { "Minolta DYNAX 7", 0, 0xffb, + { 10239,-3104,-1099,-8037,15727,2451,-927,925,6871 } }, + { "Motorola PIXL", 0, 0, /* DJC */ + { 8898,-989,-1033,-3292,11619,1674,-661,3178,5216 } }, + { "Nikon D100", 0, 0, + { 5902,-933,-782,-8983,16719,2354,-1402,1455,6464 } }, + { "Nikon D1H", 0, 0, + { 7577,-2166,-926,-7454,15592,1934,-2377,2808,8606 } }, + { "Nikon D1X", 0, 0, + { 7702,-2245,-975,-9114,17242,1875,-2679,3055,8521 } }, + { "Nikon D1", 0, 0, /* multiplied by 2.218750, 1.0, 1.148438 */ + { 16772,-4726,-2141,-7611,15713,1972,-2846,3494,9521 } }, + { "Nikon D200", 0, 0xfbc, + { 8367,-2248,-763,-8758,16447,2422,-1527,1550,8053 } }, + { "Nikon D2H", 0, 0, + { 5710,-901,-615,-8594,16617,2024,-2975,4120,6830 } }, + { "Nikon D2X", 0, 0, + { 10231,-2769,-1255,-8301,15900,2552,-797,680,7148 } }, + { "Nikon D3000", 0, 0, + { 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } }, + { "Nikon D3100", 0, 0, + { 7911,-2167,-813,-5327,13150,2408,-1288,2483,7968 } }, + { "Nikon D3200", 0, 0xfb9, + { 7013,-1408,-635,-5268,12902,2640,-1470,2801,7379 } }, + { "Nikon D3300", 0, 0, + { 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 } }, + { "Nikon D300", 0, 0, + { 9030,-1992,-715,-8465,16302,2255,-2689,3217,8069 } }, + { "Nikon D3X", 0, 0, + { 7171,-1986,-648,-8085,15555,2718,-2170,2512,7457 } }, + { "Nikon D3S", 0, 0, + { 8828,-2406,-694,-4874,12603,2541,-660,1509,7587 } }, + { "Nikon D3", 0, 0, + { 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } }, + { "Nikon D40X", 0, 0, + { 8819,-2543,-911,-9025,16928,2151,-1329,1213,8449 } }, + { "Nikon D40", 0, 0, + { 6992,-1668,-806,-8138,15748,2543,-874,850,7897 } }, + { "Nikon D4S", 0, 0, + { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } }, + { "Nikon D4", 0, 0, + { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } }, + { "Nikon Df", 0, 0, + { 8598,-2848,-857,-5618,13606,2195,-1002,1773,7137 } }, + { "Nikon D5000", 0, 0xf00, + { 7309,-1403,-519,-8474,16008,2622,-2433,2826,8064 } }, + { "Nikon D5100", 0, 0x3de6, + { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } }, + { "Nikon D5200", 0, 0, + { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } }, + { "Nikon D5300", 0, 0, + { 6988,-1384,-714,-5631,13410,2447,-1485,2204,7318 } }, + { "Nikon D5500", 0, 0, + { 8821,-2938,-785,-4178,12142,2287,-824,1651,6860 } }, + { "Nikon D50", 0, 0, + { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } }, + { "Nikon D600", 0, 0x3e07, + { 8178,-2245,-609,-4857,12394,2776,-1207,2086,7298 } }, + { "Nikon D610", 0, 0, + { 8178,-2245,-609,-4857,12394,2776,-1207,2086,7298 } }, + { "Nikon D60", 0, 0, + { 8736,-2458,-935,-9075,16894,2251,-1354,1242,8263 } }, + { "Nikon D7000", 0, 0, + { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } }, + { "Nikon D7100", 0, 0, + { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } }, + { "Nikon D7200", 0, 0, /* DJC */ + { 6111,-2759,-358,-5108,10766,4343,-769,1691,8030 } }, + { "Nikon D750", 0, 0, + { 9020,-2890,-715,-4535,12436,2348,-934,1919,7086 } }, + { "Nikon D700", 0, 0, + { 8139,-2171,-663,-8747,16541,2295,-1925,2008,8093 } }, + { "Nikon D70", 0, 0, + { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } }, + { "Nikon D810", 0, 0, + { 9369,-3195,-791,-4488,12430,2301,-893,1796,6872 } }, + { "Nikon D800", 0, 0, + { 7866,-2108,-555,-4869,12483,2681,-1176,2069,7501 } }, + { "Nikon D80", 0, 0, + { 8629,-2410,-883,-9055,16940,2171,-1490,1363,8520 } }, + { "Nikon D90", 0, 0xf00, + { 7309,-1403,-519,-8474,16008,2622,-2434,2826,8064 } }, + { "Nikon E700", 0, 0x3dd, /* DJC */ + { -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } }, + { "Nikon E800", 0, 0x3dd, /* DJC */ + { -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } }, + { "Nikon E950", 0, 0x3dd, /* DJC */ + { -3746,10611,1665,9621,-1734,2114,-2389,7082,3064,3406,6116,-244 } }, + { "Nikon E995", 0, 0, /* copied from E5000 */ + { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } }, + { "Nikon E2100", 0, 0, /* copied from Z2, new white balance */ + { 13142,-4152,-1596,-4655,12374,2282,-1769,2696,6711} }, + { "Nikon E2500", 0, 0, + { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } }, + { "Nikon E3200", 0, 0, /* DJC */ + { 9846,-2085,-1019,-3278,11109,2170,-774,2134,5745 } }, + { "Nikon E4300", 0, 0, /* copied from Minolta DiMAGE Z2 */ + { 11280,-3564,-1370,-4655,12374,2282,-1423,2168,5396 } }, + { "Nikon E4500", 0, 0, + { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } }, + { "Nikon E5000", 0, 0, + { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } }, + { "Nikon E5400", 0, 0, + { 9349,-2987,-1001,-7919,15766,2266,-2098,2680,6839 } }, + { "Nikon E5700", 0, 0, + { -5368,11478,2368,5537,-113,3148,-4969,10021,5782,778,9028,211 } }, + { "Nikon E8400", 0, 0, + { 7842,-2320,-992,-8154,15718,2599,-1098,1342,7560 } }, + { "Nikon E8700", 0, 0, + { 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 } }, + { "Nikon E8800", 0, 0, + { 7971,-2314,-913,-8451,15762,2894,-1442,1520,7610 } }, + { "Nikon COOLPIX A", 0, 0, + { 8198,-2239,-724,-4871,12389,2798,-1043,2050,7181 } }, + { "Nikon COOLPIX P330", 200, 0, + { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } }, + { "Nikon COOLPIX P340", 200, 0, + { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } }, + { "Nikon COOLPIX P6000", 0, 0, + { 9698,-3367,-914,-4706,12584,2368,-837,968,5801 } }, + { "Nikon COOLPIX P7000", 0, 0, + { 11432,-3679,-1111,-3169,11239,2202,-791,1380,4455 } }, + { "Nikon COOLPIX P7100", 0, 0, + { 11053,-4269,-1024,-1976,10182,2088,-526,1263,4469 } }, + { "Nikon COOLPIX P7700", 200, 0, + { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } }, + { "Nikon COOLPIX P7800", 200, 0, + { 10321,-3920,-931,-2750,11146,1824,-442,1545,5539 } }, + { "Nikon 1 V3", 0, 0, + { 5958,-1559,-571,-4021,11453,2939,-634,1548,5087 } }, + { "Nikon 1 J4", 0, 0, + { 5958,-1559,-571,-4021,11453,2939,-634,1548,5087 } }, + { "Nikon 1 J5", 0, 0, /* DJC */ + { 2621,-856,500,-4471,8761,5711,-1321,2644,11945 } }, + { "Nikon 1 S2", 200, 0, + { 6612,-1342,-618,-3338,11055,2623,-174,1792,5075 } }, + { "Nikon 1 V2", 0, 0, + { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } }, + { "Nikon 1 J3", 0, 0, + { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } }, + { "Nikon 1 AW1", 0, 0, + { 6588,-1305,-693,-3277,10987,2634,-355,2016,5106 } }, + { "Nikon 1 ", 0, 0, /* J1, J2, S1, V1 */ + { 8994,-2667,-865,-4594,12324,2552,-699,1786,6260 } }, + { "Olympus C5050", 0, 0, + { 10508,-3124,-1273,-6079,14294,1901,-1653,2306,6237 } }, + { "Olympus C5060", 0, 0, + { 10445,-3362,-1307,-7662,15690,2058,-1135,1176,7602 } }, + { "Olympus C7070", 0, 0, + { 10252,-3531,-1095,-7114,14850,2436,-1451,1723,6365 } }, + { "Olympus C70", 0, 0, + { 10793,-3791,-1146,-7498,15177,2488,-1390,1577,7321 } }, + { "Olympus C80", 0, 0, + { 8606,-2509,-1014,-8238,15714,2703,-942,979,7760 } }, + { "Olympus E-10", 0, 0xffc, + { 12745,-4500,-1416,-6062,14542,1580,-1934,2256,6603 } }, + { "Olympus E-1", 0, 0, + { 11846,-4767,-945,-7027,15878,1089,-2699,4122,8311 } }, + { "Olympus E-20", 0, 0xffc, + { 13173,-4732,-1499,-5807,14036,1895,-2045,2452,7142 } }, + { "Olympus E-300", 0, 0, + { 7828,-1761,-348,-5788,14071,1830,-2853,4518,6557 } }, + { "Olympus E-330", 0, 0, + { 8961,-2473,-1084,-7979,15990,2067,-2319,3035,8249 } }, + { "Olympus E-30", 0, 0xfbc, + { 8144,-1861,-1111,-7763,15894,1929,-1865,2542,7607 } }, + { "Olympus E-3", 0, 0xf99, + { 9487,-2875,-1115,-7533,15606,2010,-1618,2100,7389 } }, + { "Olympus E-400", 0, 0, + { 6169,-1483,-21,-7107,14761,2536,-2904,3580,8568 } }, + { "Olympus E-410", 0, 0xf6a, + { 8856,-2582,-1026,-7761,15766,2082,-2009,2575,7469 } }, + { "Olympus E-420", 0, 0xfd7, + { 8746,-2425,-1095,-7594,15612,2073,-1780,2309,7416 } }, + { "Olympus E-450", 0, 0xfd2, + { 8745,-2425,-1095,-7594,15613,2073,-1780,2309,7416 } }, + { "Olympus E-500", 0, 0, + { 8136,-1968,-299,-5481,13742,1871,-2556,4205,6630 } }, + { "Olympus E-510", 0, 0xf6a, + { 8785,-2529,-1033,-7639,15624,2112,-1783,2300,7817 } }, + { "Olympus E-520", 0, 0xfd2, + { 8344,-2322,-1020,-7596,15635,2048,-1748,2269,7287 } }, + { "Olympus E-5", 0, 0xeec, + { 11200,-3783,-1325,-4576,12593,2206,-695,1742,7504 } }, + { "Olympus E-600", 0, 0xfaf, + { 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } }, + { "Olympus E-620", 0, 0xfaf, + { 8453,-2198,-1092,-7609,15681,2008,-1725,2337,7824 } }, + { "Olympus E-P1", 0, 0xffd, + { 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } }, + { "Olympus E-P2", 0, 0xffd, + { 8343,-2050,-1021,-7715,15705,2103,-1831,2380,8235 } }, + { "Olympus E-P3", 0, 0, + { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } }, + { "Olympus E-P5", 0, 0, + { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, + { "Olympus E-PL1s", 0, 0, + { 11409,-3872,-1393,-4572,12757,2003,-709,1810,7415 } }, + { "Olympus E-PL1", 0, 0, + { 11408,-4289,-1215,-4286,12385,2118,-387,1467,7787 } }, + { "Olympus E-PL2", 0, 0xcf3, + { 15030,-5552,-1806,-3987,12387,1767,-592,1670,7023 } }, + { "Olympus E-PL3", 0, 0, + { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } }, + { "Olympus E-PL5", 0, 0xfcb, + { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, + { "Olympus E-PL6", 0, 0, + { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, + { "Olympus E-PL7", 0, 0, + { 9197,-3190,-659,-2606,10830,2039,-458,1250,5458 } }, + { "Olympus E-PM1", 0, 0, + { 7575,-2159,-571,-3722,11341,2725,-1434,2819,6271 } }, + { "Olympus E-PM2", 0, 0, + { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, + { "Olympus E-M10", 0, 0, + { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, + { "Olympus E-M1", 0, 0, + { 7687,-1984,-606,-4327,11928,2721,-1381,2339,6452 } }, + { "Olympus E-M5MarkII", 0, 0, + { 9422,-3258,-711,-2655,10898,2015,-512,1354,5512 } }, + { "Olympus E-M5", 0, 0xfe1, + { 8380,-2630,-639,-2887,10725,2496,-627,1427,5438 } }, + { "Olympus SP350", 0, 0, + { 12078,-4836,-1069,-6671,14306,2578,-786,939,7418 } }, + { "Olympus SP3", 0, 0, + { 11766,-4445,-1067,-6901,14421,2707,-1029,1217,7572 } }, + { "Olympus SP500UZ", 0, 0xfff, + { 9493,-3415,-666,-5211,12334,3260,-1548,2262,6482 } }, + { "Olympus SP510UZ", 0, 0xffe, + { 10593,-3607,-1010,-5881,13127,3084,-1200,1805,6721 } }, + { "Olympus SP550UZ", 0, 0xffe, + { 11597,-4006,-1049,-5432,12799,2957,-1029,1750,6516 } }, + { "Olympus SP560UZ", 0, 0xff9, + { 10915,-3677,-982,-5587,12986,2911,-1168,1968,6223 } }, + { "Olympus SP570UZ", 0, 0, + { 11522,-4044,-1146,-4736,12172,2904,-988,1829,6039 } }, + { "Olympus STYLUS1", 0, 0, + { 8360,-2420,-880,-3928,12353,1739,-1381,2416,5173 } }, + { "Olympus XZ-10", 0, 0, + { 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } }, + { "Olympus XZ-1", 0, 0, + { 10901,-4095,-1074,-1141,9208,2293,-62,1417,5158 } }, + { "Olympus XZ-2", 0, 0, + { 9777,-3483,-925,-2886,11297,1800,-602,1663,5134 } }, + { "OmniVision", 0, 0, /* DJC */ + { 12782,-4059,-379,-478,9066,1413,1340,1513,5176 } }, + { "Pentax *ist DL2", 0, 0, + { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } }, + { "Pentax *ist DL", 0, 0, + { 10829,-2838,-1115,-8339,15817,2696,-837,680,11939 } }, + { "Pentax *ist DS2", 0, 0, + { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } }, + { "Pentax *ist DS", 0, 0, + { 10371,-2333,-1206,-8688,16231,2602,-1230,1116,11282 } }, + { "Pentax *ist D", 0, 0, + { 9651,-2059,-1189,-8881,16512,2487,-1460,1345,10687 } }, + { "Pentax K10D", 0, 0, + { 9566,-2863,-803,-7170,15172,2112,-818,803,9705 } }, + { "Pentax K1", 0, 0, + { 11095,-3157,-1324,-8377,15834,2720,-1108,947,11688 } }, + { "Pentax K20D", 0, 0, + { 9427,-2714,-868,-7493,16092,1373,-2199,3264,7180 } }, + { "Pentax K200D", 0, 0, + { 9186,-2678,-907,-8693,16517,2260,-1129,1094,8524 } }, + { "Pentax K2000", 0, 0, + { 11057,-3604,-1155,-5152,13046,2329,-282,375,8104 } }, + { "Pentax K-m", 0, 0, + { 11057,-3604,-1155,-5152,13046,2329,-282,375,8104 } }, + { "Pentax K-x", 0, 0, + { 8843,-2837,-625,-5025,12644,2668,-411,1234,7410 } }, + { "Pentax K-r", 0, 0, + { 9895,-3077,-850,-5304,13035,2521,-883,1768,6936 } }, + { "Pentax K-3", 0, 0, + { 7415,-2052,-721,-5186,12788,2682,-1446,2157,6773 } }, + { "Pentax K-5 II", 0, 0, + { 8170,-2725,-639,-4440,12017,2744,-771,1465,6599 } }, + { "Pentax K-5", 0, 0, + { 8713,-2833,-743,-4342,11900,2772,-722,1543,6247 } }, + { "Pentax K-7", 0, 0, + { 9142,-2947,-678,-8648,16967,1663,-2224,2898,8615 } }, + { "Pentax K-S1", 0, 0, + { 8512,-3211,-787,-4167,11966,2487,-638,1288,6054 } }, + { "Pentax 645D", 0, 0x3e00, + { 10646,-3593,-1158,-3329,11699,1831,-667,2874,6287 } }, + { "Panasonic DMC-CM1", 15, 0, + { 8770,-3194,-820,-2871,11281,1803,-513,1552,4434 } }, + { "Panasonic DMC-FZ8", 0, 0xf7f, + { 8986,-2755,-802,-6341,13575,3077,-1476,2144,6379 } }, + { "Panasonic DMC-FZ18", 0, 0, + { 9932,-3060,-935,-5809,13331,2753,-1267,2155,5575 } }, + { "Panasonic DMC-FZ28", 15, 0xf96, + { 10109,-3488,-993,-5412,12812,2916,-1305,2140,5543 } }, + { "Panasonic DMC-FZ30", 0, 0xf94, + { 10976,-4029,-1141,-7918,15491,2600,-1670,2071,8246 } }, + { "Panasonic DMC-FZ3", 15, 0, + { 9938,-2780,-890,-4604,12393,2480,-1117,2304,4620 } }, + { "Panasonic DMC-FZ4", 15, 0, + { 13639,-5535,-1371,-1698,9633,2430,316,1152,4108 } }, + { "Panasonic DMC-FZ50", 0, 0, + { 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } }, + { "Panasonic DMC-FZ7", 15, 0, + { 11532,-4324,-1066,-2375,10847,1749,-564,1699,4351 } }, + { "Leica V-LUX1", 0, 0, + { 7906,-2709,-594,-6231,13351,3220,-1922,2631,6537 } }, + { "Panasonic DMC-L10", 15, 0xf96, + { 8025,-1942,-1050,-7920,15904,2100,-2456,3005,7039 } }, + { "Panasonic DMC-L1", 0, 0xf7f, + { 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 } }, + { "Leica DIGILUX 3", 0, 0xf7f, + { 8054,-1885,-1025,-8349,16367,2040,-2805,3542,7629 } }, + { "Panasonic DMC-LC1", 0, 0, + { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } }, + { "Leica DIGILUX 2", 0, 0, + { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } }, + { "Panasonic DMC-LX100", 15, 0, + { 8844,-3538,-768,-3709,11762,2200,-698,1792,5220 } }, + { "Leica D-LUX (Typ 109)", 15, 0, + { 8844,-3538,-768,-3709,11762,2200,-698,1792,5220 } }, + { "Panasonic DMC-LF1", 15, 0, + { 9379,-3267,-816,-3227,11560,1881,-926,1928,5340 } }, + { "Leica C (Typ 112)", 15, 0, + { 9379,-3267,-816,-3227,11560,1881,-926,1928,5340 } }, + { "Panasonic DMC-LX1", 0, 0xf7f, + { 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } }, + { "Leica D-LUX2", 0, 0xf7f, + { 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } }, + { "Panasonic DMC-LX2", 0, 0, + { 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } }, + { "Leica D-LUX3", 0, 0, + { 8048,-2810,-623,-6450,13519,3272,-1700,2146,7049 } }, + { "Panasonic DMC-LX3", 15, 0, + { 8128,-2668,-655,-6134,13307,3161,-1782,2568,6083 } }, + { "Leica D-LUX 4", 15, 0, + { 8128,-2668,-655,-6134,13307,3161,-1782,2568,6083 } }, + { "Panasonic DMC-LX5", 15, 0, + { 10909,-4295,-948,-1333,9306,2399,22,1738,4582 } }, + { "Leica D-LUX 5", 15, 0, + { 10909,-4295,-948,-1333,9306,2399,22,1738,4582 } }, + { "Panasonic DMC-LX7", 15, 0, + { 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } }, + { "Leica D-LUX 6", 15, 0, + { 10148,-3743,-991,-2837,11366,1659,-701,1893,4899 } }, + { "Panasonic DMC-FZ1000", 15, 0, + { 7830,-2696,-763,-3325,11667,1866,-641,1712,4824 } }, + { "Leica V-LUX (Typ 114)", 15, 0, + { 7830,-2696,-763,-3325,11667,1866,-641,1712,4824 } }, + { "Panasonic DMC-FZ100", 15, 0xfff, + { 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } }, + { "Leica V-LUX 2", 15, 0xfff, + { 16197,-6146,-1761,-2393,10765,1869,366,2238,5248 } }, + { "Panasonic DMC-FZ150", 15, 0xfff, + { 11904,-4541,-1189,-2355,10899,1662,-296,1586,4289 } }, + { "Leica V-LUX 3", 15, 0xfff, + { 11904,-4541,-1189,-2355,10899,1662,-296,1586,4289 } }, + { "Panasonic DMC-FZ200", 15, 0xfff, + { 8112,-2563,-740,-3730,11784,2197,-941,2075,4933 } }, + { "Leica V-LUX 4", 15, 0xfff, + { 8112,-2563,-740,-3730,11784,2197,-941,2075,4933 } }, + { "Panasonic DMC-FX150", 15, 0xfff, + { 9082,-2907,-925,-6119,13377,3058,-1797,2641,5609 } }, + { "Panasonic DMC-G10", 0, 0, + { 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } }, + { "Panasonic DMC-G1", 15, 0xf94, + { 8199,-2065,-1056,-8124,16156,2033,-2458,3022,7220 } }, + { "Panasonic DMC-G2", 15, 0xf3c, + { 10113,-3400,-1114,-4765,12683,2317,-377,1437,6710 } }, + { "Panasonic DMC-G3", 15, 0xfff, + { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } }, + { "Panasonic DMC-G5", 15, 0xfff, + { 7798,-2562,-740,-3879,11584,2613,-1055,2248,5434 } }, + { "Panasonic DMC-G6", 15, 0xfff, + { 8294,-2891,-651,-3869,11590,2595,-1183,2267,5352 } }, + { "Panasonic DMC-GF1", 15, 0xf92, + { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } }, + { "Panasonic DMC-GF2", 15, 0xfff, + { 7888,-1902,-1011,-8106,16085,2099,-2353,2866,7330 } }, + { "Panasonic DMC-GF3", 15, 0xfff, + { 9051,-2468,-1204,-5212,13276,2121,-1197,2510,6890 } }, + { "Panasonic DMC-GF5", 15, 0xfff, + { 8228,-2945,-660,-3938,11792,2430,-1094,2278,5793 } }, + { "Panasonic DMC-GF6", 15, 0, + { 8130,-2801,-946,-3520,11289,2552,-1314,2511,5791 } }, + { "Panasonic DMC-GF7", 15, 0, + { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } }, + { "Panasonic DMC-GH1", 15, 0xf92, + { 6299,-1466,-532,-6535,13852,2969,-2331,3112,5984 } }, + { "Panasonic DMC-GH2", 15, 0xf95, + { 7780,-2410,-806,-3913,11724,2484,-1018,2390,5298 } }, + { "Panasonic DMC-GH3", 15, 0, + { 6559,-1752,-491,-3672,11407,2586,-962,1875,5130 } }, + { "Panasonic DMC-GH4", 15, 0, + { 7122,-2108,-512,-3155,11201,2231,-541,1423,5045 } }, + { "Panasonic DMC-GM1", 15, 0, + { 6770,-1895,-744,-5232,13145,2303,-1664,2691,5703 } }, + { "Panasonic DMC-GM5", 15, 0, + { 8238,-3244,-679,-3921,11814,2384,-836,2022,5852 } }, + { "Panasonic DMC-GX1", 15, 0, + { 6763,-1919,-863,-3868,11515,2684,-1216,2387,5879 } }, + { "Panasonic DMC-GX7", 15, 0, + { 7610,-2780,-576,-4614,12195,2733,-1375,2393,6490 } }, + { "Panasonic DMC-TZ6", 15, 0, + { 8607,-2822,-808,-3755,11930,2049,-820,2060,5224 } }, + { "Panasonic DMC-ZS4", 15, 0, + { 8607,-2822,-808,-3755,11930,2049,-820,2060,5224 } }, + { "Panasonic DMC-TZ7", 15, 0, + { 8802,-3135,-789,-3151,11468,1904,-550,1745,4810 } }, + { "Panasonic DMC-ZS5", 15, 0, + { 8802,-3135,-789,-3151,11468,1904,-550,1745,4810 } }, + { "Phase One H 20", 0, 0, /* DJC */ + { 1313,1855,-109,-6715,15908,808,-327,1840,6020 } }, + { "Phase One H 25", 0, 0, + { 2905,732,-237,-8134,16626,1476,-3038,4253,7517 } }, + { "Phase One P 2", 0, 0, + { 2905,732,-237,-8134,16626,1476,-3038,4253,7517 } }, + { "Phase One P 30", 0, 0, + { 4516,-245,-37,-7020,14976,2173,-3206,4671,7087 } }, + { "Phase One P 45", 0, 0, + { 5053,-24,-117,-5684,14076,1702,-2619,4492,5849 } }, + { "Phase One P40", 0, 0, + { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } }, + { "Phase One P65", 0, 0, + { 8035,435,-962,-6001,13872,2320,-1159,3065,5434 } }, + { "Red One", 704, 0xffff, /* DJC */ + { 21014,-7891,-2613,-3056,12201,856,-2203,5125,8042 } }, + { "Samsung EX1", 0, 0x3e00, + { 8898,-2498,-994,-3144,11328,2066,-760,1381,4576 } }, + { "Samsung EX2F", 0, 0x7ff, + { 10648,-3897,-1055,-2022,10573,1668,-492,1611,4742 } }, + { "Samsung EK-GN120", 0, 0, + { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } }, + { "Samsung NX mini", 0, 0, + { 5222,-1196,-550,-6540,14649,2009,-1666,2819,5657 } }, + { "Samsung NX3000", 0, 0, + { 8060,-2933,-761,-4504,12890,1762,-630,1489,5227 } }, + { "Samsung NX30", 0, 0, /* NX30, NX300, NX300M */ + { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } }, + { "Samsung NX2000", 0, 0, + { 7557,-2522,-739,-4679,12949,1894,-840,1777,5311 } }, + { "Samsung NX2", 0, 0xfff, /* NX20, NX200, NX210 */ + { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } }, + { "Samsung NX1000", 0, 0, + { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } }, + { "Samsung NX1100", 0, 0, + { 6933,-2268,-753,-4921,13387,1647,-803,1641,6096 } }, + { "Samsung NX11", 0, 0, + { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } }, + { "Samsung NX10", 0, 0, /* also NX100 */ + { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } }, + { "Samsung NX500", 0, 0, /* DJC */ + { 10196,-4532,-272,-3888,11489,2400,-1203,2424,9173 } }, + { "Samsung NX5", 0, 0, + { 10332,-3234,-1168,-6111,14639,1520,-1352,2647,8331 } }, + { "Samsung NX1", 0, 0, + { 10686,-4042,-1052,-3595,13238,276,-464,1259,5931 } }, + { "Samsung WB2000", 0, 0xfff, + { 12093,-3557,-1155,-1000,9534,1733,-22,1787,4576 } }, + { "Samsung GX-1", 0, 0, + { 10504,-2438,-1189,-8603,16207,2531,-1022,863,12242 } }, + { "Samsung GX20", 0, 0, /* copied from Pentax K20D */ + { 9427,-2714,-868,-7493,16092,1373,-2199,3264,7180 } }, + { "Samsung S85", 0, 0, /* DJC */ + { 11885,-3968,-1473,-4214,12299,1916,-835,1655,5549 } }, + { "Sinar", 0, 0, /* DJC */ + { 16442,-2956,-2422,-2877,12128,750,-1136,6066,4559 } }, + { "Sony DSC-F828", 0, 0, + { 7924,-1910,-777,-8226,15459,2998,-1517,2199,6818,-7242,11401,3481 } }, + { "Sony DSC-R1", 512, 0, + { 8512,-2641,-694,-8042,15670,2526,-1821,2117,7414 } }, + { "Sony DSC-V3", 0, 0, + { 7511,-2571,-692,-7894,15088,3060,-948,1111,8128 } }, + { "Sony DSC-RX100M", 200, 0, /* M2 and M3 */ + { 6596,-2079,-562,-4782,13016,1933,-970,1581,5181 } }, + { "Sony DSC-RX100", 200, 0, + { 8651,-2754,-1057,-3464,12207,1373,-568,1398,4434 } }, + { "Sony DSC-RX10", 200, 0, + { 6679,-1825,-745,-5047,13256,1953,-1580,2422,5183 } }, + { "Sony DSC-RX1", 128, 0, + { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } }, + { "Sony DSLR-A100", 0, 0xfeb, + { 9437,-2811,-774,-8405,16215,2290,-710,596,7181 } }, + { "Sony DSLR-A290", 0, 0, + { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } }, + { "Sony DSLR-A2", 0, 0, + { 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } }, + { "Sony DSLR-A300", 0, 0, + { 9847,-3091,-928,-8485,16345,2225,-715,595,7103 } }, + { "Sony DSLR-A330", 0, 0, + { 9847,-3091,-929,-8485,16346,2225,-714,595,7103 } }, + { "Sony DSLR-A350", 0, 0xffc, + { 6038,-1484,-578,-9146,16746,2513,-875,746,7217 } }, + { "Sony DSLR-A380", 0, 0, + { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } }, + { "Sony DSLR-A390", 0, 0, + { 6038,-1484,-579,-9145,16746,2512,-875,746,7218 } }, + { "Sony DSLR-A450", 128, 0xfeb, + { 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } }, + { "Sony DSLR-A580", 128, 0xfeb, + { 5932,-1492,-411,-4813,12285,2856,-741,1524,6739 } }, + { "Sony DSLR-A500", 128, 0xfeb, + { 6046,-1127,-278,-5574,13076,2786,-691,1419,7625 } }, + { "Sony DSLR-A5", 128, 0xfeb, + { 4950,-580,-103,-5228,12542,3029,-709,1435,7371 } }, + { "Sony DSLR-A700", 128, 0, + { 5775,-805,-359,-8574,16295,2391,-1943,2341,7249 } }, + { "Sony DSLR-A850", 128, 0, + { 5413,-1162,-365,-5665,13098,2866,-608,1179,8440 } }, + { "Sony DSLR-A900", 128, 0, + { 5209,-1072,-397,-8845,16120,2919,-1618,1803,8654 } }, + { "Sony ILCA-77M2", 128, 0, + { 5991,-1732,-443,-4100,11989,2381,-704,1467,5992 } }, + { "Sony ILCE-7M2", 128, 0, + { 5271,-712,-347,-6153,13653,2763,-1601,2366,7242 } }, + { "Sony ILCE-7S", 128, 0, + { 5838,-1430,-246,-3497,11477,2297,-748,1885,5778 } }, + { "Sony ILCE-7R", 128, 0, + { 4913,-541,-202,-6130,13513,2906,-1564,2151,7183 } }, + { "Sony ILCE-7", 128, 0, + { 5271,-712,-347,-6153,13653,2763,-1601,2366,7242 } }, + { "Sony ILCE", 128, 0, /* 3000, 5000, 5100, 6000, and QX1 */ + { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, + { "Sony NEX-5N", 128, 0, + { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, + { "Sony NEX-5R", 128, 0, + { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } }, + { "Sony NEX-5T", 128, 0, + { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } }, + { "Sony NEX-3N", 128, 0, + { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } }, + { "Sony NEX-3", 138, 0, /* DJC */ + { 6907,-1256,-645,-4940,12621,2320,-1710,2581,6230 } }, + { "Sony NEX-5", 116, 0, /* DJC */ + { 6807,-1350,-342,-4216,11649,2567,-1089,2001,6420 } }, + { "Sony NEX-3", 128, 0, /* Adobe */ + { 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } }, + { "Sony NEX-5", 128, 0, /* Adobe */ + { 6549,-1550,-436,-4880,12435,2753,-854,1868,6976 } }, + { "Sony NEX-6", 128, 0, + { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } }, + { "Sony NEX-7", 128, 0, + { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } }, + { "Sony NEX", 128, 0, /* NEX-C3, NEX-F3 */ + { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, + { "Sony SLT-A33", 128, 0, + { 6069,-1221,-366,-5221,12779,2734,-1024,2066,6834 } }, + { "Sony SLT-A35", 128, 0, + { 5986,-1618,-415,-4557,11820,3120,-681,1404,6971 } }, + { "Sony SLT-A37", 128, 0, + { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, + { "Sony SLT-A55", 128, 0, + { 5932,-1492,-411,-4813,12285,2856,-741,1524,6739 } }, + { "Sony SLT-A57", 128, 0, + { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, + { "Sony SLT-A58", 128, 0, + { 5991,-1456,-455,-4764,12135,2980,-707,1425,6701 } }, + { "Sony SLT-A65", 128, 0, + { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } }, + { "Sony SLT-A77", 128, 0, + { 5491,-1192,-363,-4951,12342,2948,-911,1722,7192 } }, + { "Sony SLT-A99", 128, 0, + { 6344,-1612,-462,-4863,12477,2681,-865,1786,6899 } }, + }; + double cam_xyz[4][3]; + char name[130]; + int i, j; + + sprintf (name, "%s %s", make, model); + for (i=0; i < sizeof table / sizeof *table; i++) + if (!strncmp (name, table[i].prefix, strlen(table[i].prefix))) { + if (table[i].black) black = (ushort) table[i].black; + if (table[i].maximum) maximum = (ushort) table[i].maximum; + if (table[i].trans[0]) { + for (raw_color = j=0; j < 12; j++) + ((double *)cam_xyz)[j] = table[i].trans[j] / 10000.0; + cam_xyz_coeff (rgb_cam, cam_xyz); + } + break; + } + if (load_raw == &CLASS sony_arw2_load_raw) { // RT: arw2 scale fix + black <<= 2; + tiff_bps += 2; + } + { /* Check for RawTherapee table overrides and extensions */ + int black_level, white_level; + short trans[12]; + if (dcraw_coeff_overrides(make, model, iso_speed, trans, &black_level, &white_level)) { + if (black_level > -1) { + black = (ushort)black_level; + } + if (white_level > -1) { + maximum = (ushort)white_level; + if(tiff_bps > 0) { + unsigned compare = ((uint64_t)1 << tiff_bps) - 1; // use uint64_t to avoid overflow if tiff_bps == 32 + while(maximum > compare) + maximum >>= 1; + } + } + if (trans[0]) { + for (j=0; j < 12; j++) { + ((double *)cam_xyz)[j] = trans[j] / 10000.0; + } + cam_xyz_coeff (rgb_cam,cam_xyz); + } + } + } +} + +void CLASS simple_coeff (int index) +{ + static const float table[][12] = { + /* index 0 -- all Foveon cameras */ + { 1.4032,-0.2231,-0.1016,-0.5263,1.4816,0.017,-0.0112,0.0183,0.9113 }, + /* index 1 -- Kodak DC20 and DC25 */ + { 2.25,0.75,-1.75,-0.25,-0.25,0.75,0.75,-0.25,-0.25,-1.75,0.75,2.25 }, + /* index 2 -- Logitech Fotoman Pixtura */ + { 1.893,-0.418,-0.476,-0.495,1.773,-0.278,-1.017,-0.655,2.672 }, + /* index 3 -- Nikon E880, E900, and E990 */ + { -1.936280, 1.800443, -1.448486, 2.584324, + 1.405365, -0.524955, -0.289090, 0.408680, + -1.204965, 1.082304, 2.941367, -1.818705 } + }; + int i, c; + + for (raw_color = i=0; i < 3; i++) + FORCC rgb_cam[i][c] = table[index][i*colors+c]; +} + +short CLASS guess_byte_order (int words) +{ + uchar test[4][2]; + int t=2, msb; + double diff, sum[2] = {0,0}; + + fread (test[0], 2, 2, ifp); + for (words-=2; words--; ) { + fread (test[t], 2, 1, ifp); + for (msb=0; msb < 2; msb++) { + diff = (test[t^2][msb] << 8 | test[t^2][!msb]) + - (test[t ][msb] << 8 | test[t ][!msb]); + sum[msb] += diff*diff; + } + t = (t+1) & 3; + } + return sum[0] < sum[1] ? 0x4d4d : 0x4949; +} + +float CLASS find_green (int bps, int bite, int off0, int off1) +{ + UINT64 bitbuf=0; + int vbits, col, i, c; + ushort img[2][2064]; + double sum[]={0,0}; + + FORC(2) { + fseek (ifp, c ? off1:off0, SEEK_SET); + for (vbits=col=0; col < width; col++) { + for (vbits -= bps; vbits < 0; vbits += bite) { + bitbuf <<= bite; + for (i=0; i < bite; i+=8) + bitbuf |= (unsigned) (fgetc(ifp) << i); + } + img[c][col] = bitbuf << (64-bps-vbits) >> (64-bps); + } + } + FORC(width-1) { + sum[ c & 1] += ABS(img[0][c]-img[1][c+1]); + sum[~c & 1] += ABS(img[1][c]-img[0][c+1]); + } + return 100 * log(sum[0]/sum[1]); +} + +/* + Identify which camera created this file, and set global variables + accordingly. + */ +void CLASS identify() +{ + static const short pana[][6] = { + { 3130, 1743, 4, 0, -6, 0 }, + { 3130, 2055, 4, 0, -6, 0 }, + { 3130, 2319, 4, 0, -6, 0 }, + { 3170, 2103, 18, 0,-42, 20 }, + { 3170, 2367, 18, 13,-42,-21 }, + { 3177, 2367, 0, 0, -1, 0 }, + { 3304, 2458, 0, 0, -1, 0 }, + { 3330, 2463, 9, 0, -5, 0 }, + { 3330, 2479, 9, 0,-17, 4 }, + { 3370, 1899, 15, 0,-44, 20 }, + { 3370, 2235, 15, 0,-44, 20 }, + { 3370, 2511, 15, 10,-44,-21 }, + { 3690, 2751, 3, 0, -8, -3 }, + { 3710, 2751, 0, 0, -3, 0 }, + { 3724, 2450, 0, 0, 0, -2 }, + { 3770, 2487, 17, 0,-44, 19 }, + { 3770, 2799, 17, 15,-44,-19 }, + { 3880, 2170, 6, 0, -6, 0 }, + { 4060, 3018, 0, 0, 0, -2 }, + { 4290, 2391, 3, 0, -8, -1 }, + { 4330, 2439, 17, 15,-44,-19 }, + { 4508, 2962, 0, 0, -3, -4 }, + { 4508, 3330, 0, 0, -3, -6 }, + }; + static const ushort canon[][11] = { + { 1944, 1416, 0, 0, 48, 0 }, + { 2144, 1560, 4, 8, 52, 2, 0, 0, 0, 25 }, + { 2224, 1456, 48, 6, 0, 2 }, + { 2376, 1728, 12, 6, 52, 2 }, + { 2672, 1968, 12, 6, 44, 2 }, + { 3152, 2068, 64, 12, 0, 0, 16 }, + { 3160, 2344, 44, 12, 4, 4 }, + { 3344, 2484, 4, 6, 52, 6 }, + { 3516, 2328, 42, 14, 0, 0 }, + { 3596, 2360, 74, 12, 0, 0 }, + { 3744, 2784, 52, 12, 8, 12 }, + { 3944, 2622, 30, 18, 6, 2 }, + { 3948, 2622, 42, 18, 0, 2 }, + { 3984, 2622, 76, 20, 0, 2, 14 }, + { 4104, 3048, 48, 12, 24, 12 }, + { 4116, 2178, 4, 2, 0, 0 }, + { 4152, 2772, 192, 12, 0, 0 }, + { 4160, 3124, 104, 11, 8, 65 }, + { 4176, 3062, 96, 17, 8, 0, 0, 16, 0, 7, 0x49 }, + { 4192, 3062, 96, 17, 24, 0, 0, 16, 0, 0, 0x49 }, + { 4312, 2876, 22, 18, 0, 2 }, + { 4352, 2874, 62, 18, 0, 0 }, + { 4476, 2954, 90, 34, 0, 0 }, + { 4480, 3348, 12, 10, 36, 12, 0, 0, 0, 18, 0x49 }, + { 4480, 3366, 80, 50, 0, 0 }, + { 4496, 3366, 80, 50, 12, 0 }, + { 4768, 3516, 96, 16, 0, 0, 0, 16 }, + { 4832, 3204, 62, 26, 0, 0 }, + { 4832, 3228, 62, 51, 0, 0 }, + { 5108, 3349, 98, 13, 0, 0 }, + { 5120, 3318, 142, 45, 62, 0 }, + { 5280, 3528, 72, 52, 0, 0 }, + { 5344, 3516, 142, 51, 0, 0 }, + { 5344, 3584, 126,100, 0, 2 }, + { 5360, 3516, 158, 51, 0, 0 }, + { 5568, 3708, 72, 38, 0, 0 }, + { 5632, 3710, 96, 17, 0, 0, 0, 16, 0, 0, 0x49 }, + { 5712, 3774, 62, 20, 10, 2 }, + { 5792, 3804, 158, 51, 0, 0 }, + { 5920, 3950, 122, 80, 2, 0 }, + { 8896, 5920, 160, 64, 0, 0 }, + }; + static const struct { + ushort id; + char model[20]; + } unique[] = { + { 0x168, "EOS 10D" }, { 0x001, "EOS-1D" }, + { 0x175, "EOS 20D" }, { 0x174, "EOS-1D Mark II" }, + { 0x234, "EOS 30D" }, { 0x232, "EOS-1D Mark II N" }, + { 0x190, "EOS 40D" }, { 0x169, "EOS-1D Mark III" }, + { 0x261, "EOS 50D" }, { 0x281, "EOS-1D Mark IV" }, + { 0x287, "EOS 60D" }, { 0x167, "EOS-1DS" }, + { 0x325, "EOS 70D" }, + { 0x170, "EOS 300D" }, { 0x188, "EOS-1Ds Mark II" }, + { 0x176, "EOS 450D" }, { 0x215, "EOS-1Ds Mark III" }, + { 0x189, "EOS 350D" }, { 0x324, "EOS-1D C" }, + { 0x236, "EOS 400D" }, { 0x269, "EOS-1D X" }, + { 0x252, "EOS 500D" }, { 0x213, "EOS 5D" }, + { 0x270, "EOS 550D" }, { 0x218, "EOS 5D Mark II" }, + { 0x286, "EOS 600D" }, { 0x285, "EOS 5D Mark III" }, + { 0x301, "EOS 650D" }, { 0x302, "EOS 6D" }, + { 0x326, "EOS 700D" }, { 0x250, "EOS 7D" }, + { 0x254, "EOS 1000D" }, + { 0x288, "EOS 1100D" }, + { 0x327, "EOS 1200D" }, + { 0x346, "EOS 100D" }, + }, sonique[] = { + { 0x002, "DSC-R1" }, { 0x100, "DSLR-A100" }, + { 0x101, "DSLR-A900" }, { 0x102, "DSLR-A700" }, + { 0x103, "DSLR-A200" }, { 0x104, "DSLR-A350" }, + { 0x105, "DSLR-A300" }, { 0x108, "DSLR-A330" }, + { 0x109, "DSLR-A230" }, { 0x10a, "DSLR-A290" }, + { 0x10d, "DSLR-A850" }, { 0x111, "DSLR-A550" }, + { 0x112, "DSLR-A500" }, { 0x113, "DSLR-A450" }, + { 0x116, "NEX-5" }, { 0x117, "NEX-3" }, + { 0x118, "SLT-A33" }, { 0x119, "SLT-A55V" }, + { 0x11a, "DSLR-A560" }, { 0x11b, "DSLR-A580" }, + { 0x11c, "NEX-C3" }, { 0x11d, "SLT-A35" }, + { 0x11e, "SLT-A65V" }, { 0x11f, "SLT-A77V" }, + { 0x120, "NEX-5N" }, { 0x121, "NEX-7" }, + { 0x123, "SLT-A37" }, { 0x124, "SLT-A57" }, + { 0x125, "NEX-F3" }, { 0x126, "SLT-A99V" }, + { 0x127, "NEX-6" }, { 0x128, "NEX-5R" }, + { 0x129, "DSC-RX100" }, { 0x12a, "DSC-RX1" }, + { 0x12e, "ILCE-3000" }, { 0x12f, "SLT-A58" }, + { 0x131, "NEX-3N" }, { 0x132, "ILCE-7" }, + { 0x133, "NEX-5T" }, { 0x134, "DSC-RX100M2" }, + { 0x135, "DSC-RX10" }, { 0x136, "DSC-RX1R" }, + { 0x137, "ILCE-7R" }, { 0x138, "ILCE-6000" }, + { 0x139, "ILCE-5000" }, { 0x13d, "DSC-RX100M3" }, + { 0x13e, "ILCE-7S" }, { 0x13f, "ILCA-77M2" }, + { 0x153, "ILCE-5100" }, { 0x154, "ILCE-7M2" }, + { 0x15a, "ILCE-QX1" }, + }; + static const struct { + unsigned fsize; + ushort rw, rh; + uchar lm, tm, rm, bm, lf, cf, max, flags; + char make[10], model[20]; + ushort offset; + } table[] = { + { 786432,1024, 768, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-080C" }, + { 1447680,1392,1040, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-145C" }, + { 1920000,1600,1200, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-201C" }, + { 5067304,2588,1958, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-510C" }, + { 5067316,2588,1958, 0, 0, 0, 0, 0,0x94,0,0,"AVT","F-510C",12 }, + { 10134608,2588,1958, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-510C" }, + { 10134620,2588,1958, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-510C",12 }, + { 16157136,3272,2469, 0, 0, 0, 0, 9,0x94,0,0,"AVT","F-810C" }, + { 15980544,3264,2448, 0, 0, 0, 0, 8,0x61,0,1,"AgfaPhoto","DC-833m" }, + { 9631728,2532,1902, 0, 0, 0, 0,96,0x61,0,0,"Alcatel","5035D" }, + { 2868726,1384,1036, 0, 0, 0, 0,64,0x49,0,8,"Baumer","TXG14",1078 }, + { 5298000,2400,1766,12,12,44, 2,40,0x94,0,2,"Canon","PowerShot SD300" }, + { 6553440,2664,1968, 4, 4,44, 4,40,0x94,0,2,"Canon","PowerShot A460" }, + { 6573120,2672,1968,12, 8,44, 0,40,0x94,0,2,"Canon","PowerShot A610" }, + { 6653280,2672,1992,10, 6,42, 2,40,0x94,0,2,"Canon","PowerShot A530" }, + { 7710960,2888,2136,44, 8, 4, 0,40,0x94,0,2,"Canon","PowerShot S3 IS" }, + { 9219600,3152,2340,36,12, 4, 0,40,0x94,0,2,"Canon","PowerShot A620" }, + { 9243240,3152,2346,12, 7,44,13,40,0x49,0,2,"Canon","PowerShot A470" }, + { 10341600,3336,2480, 6, 5,32, 3,40,0x94,0,2,"Canon","PowerShot A720 IS" }, + { 10383120,3344,2484,12, 6,44, 6,40,0x94,0,2,"Canon","PowerShot A630" }, + { 12945240,3736,2772,12, 6,52, 6,40,0x94,0,2,"Canon","PowerShot A640" }, + { 15636240,4104,3048,48,12,24,12,40,0x94,0,2,"Canon","PowerShot A650" }, + { 15467760,3720,2772, 6,12,30, 0,40,0x94,0,2,"Canon","PowerShot SX110 IS" }, + { 15534576,3728,2778,12, 9,44, 9,40,0x94,0,2,"Canon","PowerShot SX120 IS" }, + { 18653760,4080,3048,24,12,24,12,40,0x94,0,2,"Canon","PowerShot SX20 IS" }, + { 19131120,4168,3060,92,16, 4, 1,40,0x94,0,2,"Canon","PowerShot SX220 HS" }, + { 21936096,4464,3276,25,10,73,12,40,0x16,0,2,"Canon","PowerShot SX30 IS" }, + { 24724224,4704,3504, 8,16,56, 8,40,0x94,0,2,"Canon","PowerShot A3300 IS" }, + { 1976352,1632,1211, 0, 2, 0, 1, 0,0x94,0,1,"Casio","QV-2000UX" }, + { 3217760,2080,1547, 0, 0,10, 1, 0,0x94,0,1,"Casio","QV-3*00EX" }, + { 6218368,2585,1924, 0, 0, 9, 0, 0,0x94,0,1,"Casio","QV-5700" }, + { 7816704,2867,2181, 0, 0,34,36, 0,0x16,0,1,"Casio","EX-Z60" }, + { 2937856,1621,1208, 0, 0, 1, 0, 0,0x94,7,13,"Casio","EX-S20" }, + { 4948608,2090,1578, 0, 0,32,34, 0,0x94,7,1,"Casio","EX-S100" }, + { 6054400,2346,1720, 2, 0,32, 0, 0,0x94,7,1,"Casio","QV-R41" }, + { 7426656,2568,1928, 0, 0, 0, 0, 0,0x94,0,1,"Casio","EX-P505" }, + { 7530816,2602,1929, 0, 0,22, 0, 0,0x94,7,1,"Casio","QV-R51" }, + { 7542528,2602,1932, 0, 0,32, 0, 0,0x94,7,1,"Casio","EX-Z50" }, + { 7562048,2602,1937, 0, 0,25, 0, 0,0x16,7,1,"Casio","EX-Z500" }, + { 7753344,2602,1986, 0, 0,32,26, 0,0x94,7,1,"Casio","EX-Z55" }, + { 9313536,2858,2172, 0, 0,14,30, 0,0x94,7,1,"Casio","EX-P600" }, + { 10834368,3114,2319, 0, 0,27, 0, 0,0x94,0,1,"Casio","EX-Z750" }, + { 10843712,3114,2321, 0, 0,25, 0, 0,0x94,0,1,"Casio","EX-Z75" }, + { 10979200,3114,2350, 0, 0,32,32, 0,0x94,7,1,"Casio","EX-P700" }, + { 12310144,3285,2498, 0, 0, 6,30, 0,0x94,0,1,"Casio","EX-Z850" }, + { 12489984,3328,2502, 0, 0,47,35, 0,0x94,0,1,"Casio","EX-Z8" }, + { 15499264,3754,2752, 0, 0,82, 0, 0,0x94,0,1,"Casio","EX-Z1050" }, + { 18702336,4096,3044, 0, 0,24, 0,80,0x94,7,1,"Casio","EX-ZR100" }, + { 7684000,2260,1700, 0, 0, 0, 0,13,0x94,0,1,"Casio","QV-4000" }, + { 787456,1024, 769, 0, 1, 0, 0, 0,0x49,0,0,"Creative","PC-CAM 600" }, + { 28829184,4384,3288, 0, 0, 0, 0,36,0x61,0,0,"DJI" }, + { 15151104,4608,3288, 0, 0, 0, 0, 0,0x94,0,0,"Matrix" }, + { 3840000,1600,1200, 0, 0, 0, 0,65,0x49,0,0,"Foculus","531C" }, + { 307200, 640, 480, 0, 0, 0, 0, 0,0x94,0,0,"Generic" }, + { 62464, 256, 244, 1, 1, 6, 1, 0,0x8d,0,0,"Kodak","DC20" }, + { 124928, 512, 244, 1, 1,10, 1, 0,0x8d,0,0,"Kodak","DC20" }, + { 1652736,1536,1076, 0,52, 0, 0, 0,0x61,0,0,"Kodak","DCS200" }, + { 4159302,2338,1779, 1,33, 1, 2, 0,0x94,0,0,"Kodak","C330" }, + { 4162462,2338,1779, 1,33, 1, 2, 0,0x94,0,0,"Kodak","C330",3160 }, + { 2247168,1232, 912, 0, 0,16, 0, 0,0x00,0,0,"Kodak","C330" }, + { 3370752,1232, 912, 0, 0,16, 0, 0,0x00,0,0,"Kodak","C330" }, + { 6163328,2864,2152, 0, 0, 0, 0, 0,0x94,0,0,"Kodak","C603" }, + { 6166488,2864,2152, 0, 0, 0, 0, 0,0x94,0,0,"Kodak","C603",3160 }, + { 460800, 640, 480, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","C603" }, + { 9116448,2848,2134, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","C603" }, + { 12241200,4040,3030, 2, 0, 0,13, 0,0x49,0,0,"Kodak","12MP" }, + { 12272756,4040,3030, 2, 0, 0,13, 0,0x49,0,0,"Kodak","12MP",31556 }, + { 18000000,4000,3000, 0, 0, 0, 0, 0,0x00,0,0,"Kodak","12MP" }, + { 614400, 640, 480, 0, 3, 0, 0,64,0x94,0,0,"Kodak","KAI-0340" }, + { 15360000,3200,2400, 0, 0, 0, 0,96,0x16,0,0,"Lenovo","A820" }, + { 3884928,1608,1207, 0, 0, 0, 0,96,0x16,0,0,"Micron","2010",3212 }, + { 1138688,1534, 986, 0, 0, 0, 0, 0,0x61,0,0,"Minolta","RD175",513 }, + { 1581060,1305, 969, 0, 0,18, 6, 6,0x1e,4,1,"Nikon","E900" }, + { 2465792,1638,1204, 0, 0,22, 1, 6,0x4b,5,1,"Nikon","E950" }, + { 2940928,1616,1213, 0, 0, 0, 7,30,0x94,0,1,"Nikon","E2100" }, + { 4771840,2064,1541, 0, 0, 0, 1, 6,0xe1,0,1,"Nikon","E990" }, + { 4775936,2064,1542, 0, 0, 0, 0,30,0x94,0,1,"Nikon","E3700" }, + { 5865472,2288,1709, 0, 0, 0, 1, 6,0xb4,0,1,"Nikon","E4500" }, + { 5869568,2288,1710, 0, 0, 0, 0, 6,0x16,0,1,"Nikon","E4300" }, + { 7438336,2576,1925, 0, 0, 0, 1, 6,0xb4,0,1,"Nikon","E5000" }, + { 8998912,2832,2118, 0, 0, 0, 0,30,0x94,7,1,"Nikon","COOLPIX S6" }, + { 5939200,2304,1718, 0, 0, 0, 0,30,0x16,0,0,"Olympus","C770UZ" }, + { 3178560,2064,1540, 0, 0, 0, 0, 0,0x94,0,1,"Pentax","Optio S" }, + { 4841984,2090,1544, 0, 0,22, 0, 0,0x94,7,1,"Pentax","Optio S" }, + { 6114240,2346,1737, 0, 0,22, 0, 0,0x94,7,1,"Pentax","Optio S4" }, + { 10702848,3072,2322, 0, 0, 0,21,30,0x94,0,1,"Pentax","Optio 750Z" }, + { 13248000,2208,3000, 0, 0, 0, 0,13,0x61,0,0,"Pixelink","A782" }, + { 6291456,2048,1536, 0, 0, 0, 0,96,0x61,0,0,"RoverShot","3320AF" }, + { 311696, 644, 484, 0, 0, 0, 0, 0,0x16,0,8,"ST Micro","STV680 VGA" }, + { 16098048,3288,2448, 0, 0,24, 0, 9,0x94,0,1,"Samsung","S85" }, + { 16215552,3312,2448, 0, 0,48, 0, 9,0x94,0,1,"Samsung","S85" }, + { 20487168,3648,2808, 0, 0, 0, 0,13,0x94,5,1,"Samsung","WB550" }, + { 24000000,4000,3000, 0, 0, 0, 0,13,0x94,5,1,"Samsung","WB550" }, + { 12582980,3072,2048, 0, 0, 0, 0,33,0x61,0,0,"Sinar","",68 }, + { 33292868,4080,4080, 0, 0, 0, 0,33,0x61,0,0,"Sinar","",68 }, + { 44390468,4080,5440, 0, 0, 0, 0,33,0x61,0,0,"Sinar","",68 }, + { 1409024,1376,1024, 0, 0, 1, 0, 0,0x49,0,0,"Sony","XCD-SX910CR" }, + { 2818048,1376,1024, 0, 0, 1, 0,97,0x49,0,0,"Sony","XCD-SX910CR" }, + }; + static const char *corp[] = + { "AgfaPhoto", "Canon", "Casio", "Epson", "Fujifilm", + "Mamiya", "Minolta", "Motorola", "Kodak", "Konica", "Leica", + "Nikon", "Nokia", "Olympus", "Pentax", "Phase One", "Ricoh", + "Samsung", "Sigma", "Sinar", "Sony" }; + char head[32], *cp; + int hlen, flen, fsize, zero_fsize=1, i, c; + struct jhead jh; + + tiff_flip = flip = filters = UINT_MAX; /* unknown */ + raw_height = raw_width = fuji_width = fuji_layout = cr2_slice[0] = 0; + maximum = height = width = top_margin = left_margin = 0; + cdesc[0] = desc[0] = artist[0] = make[0] = model[0] = model2[0] = model3[0] = 0; + iso_speed = shutter = aperture = focal_len = unique_id = 0; + tiff_nifds = 0; + memset (tiff_ifd, 0, sizeof tiff_ifd); + memset (gpsdata, 0, sizeof gpsdata); + memset (cblack, 0, sizeof cblack); + memset (white, 0, sizeof white); + memset (mask, 0, sizeof mask); + thumb_offset = thumb_length = thumb_width = thumb_height = 0; + load_raw = thumb_load_raw = 0; + write_thumb = &CLASS jpeg_thumb; + data_offset = meta_offset = meta_length = tiff_bps = tiff_compress = 0; + kodak_cbpp = zero_after_ff = dng_version = load_flags = 0; + timestamp = shot_order = tiff_samples = black = is_foveon = 0; + mix_green = profile_length = data_error = zero_is_bad = 0; + pixel_aspect = is_raw = raw_color = 1; + tile_width = tile_length = 0; + for (i=0; i < 4; i++) { + cam_mul[i] = i == 1; + pre_mul[i] = i < 3; + FORC3 cmatrix[c][i] = 0; + FORC3 rgb_cam[c][i] = c == i; + } + colors = 3; + for (i=0; i < 0x10000; i++) curve[i] = i; + + order = get2(); + hlen = get4(); + fseek (ifp, 0, SEEK_SET); + fread (head, 1, 32, ifp); + fseek (ifp, 0, SEEK_END); + flen = fsize = ftell(ifp); + /*RT*/ if (fsize<100000) { + is_raw = 0; + return; + } + /* RT: changed string constant */ + if ((cp = (char *) memmem (head, 32, (char*)"MMMM", 4)) || + (cp = (char *) memmem (head, 32, (char*)"IIII", 4))) { + parse_phase_one (cp-head); + if (cp-head && parse_tiff(0)) apply_tiff(); + } else if (order == 0x4949 || order == 0x4d4d) { + if (!memcmp (head+6,"HEAPCCDR",8)) { + data_offset = hlen; +/*RT*/ ciff_base = hlen; +/*RT*/ ciff_len = fsize - hlen; + parse_ciff (hlen, flen-hlen, 0); + load_raw = &CLASS canon_load_raw; + } else if (parse_tiff(0)) apply_tiff(); + } else if (!memcmp (head,"\xff\xd8\xff\xe1",4) && + !memcmp (head+6,"Exif",4)) { + fseek (ifp, 4, SEEK_SET); + data_offset = 4 + get2(); + fseek (ifp, data_offset, SEEK_SET); + if (fgetc(ifp) != 0xff) + parse_tiff(12); + thumb_offset = 0; + } else if (!memcmp (head+25,"ARECOYK",7)) { + strcpy (make, "Contax"); + strcpy (model,"N Digital"); + fseek (ifp, 33, SEEK_SET); + get_timestamp(1); + fseek (ifp, 60, SEEK_SET); + FORC4 cam_mul[c ^ (c >> 1)] = get4(); + } else if (!strcmp (head, "PXN")) { + strcpy (make, "Logitech"); + strcpy (model,"Fotoman Pixtura"); + } else if (!strcmp (head, "qktk")) { + strcpy (make, "Apple"); + strcpy (model,"QuickTake 100"); + load_raw = &CLASS quicktake_100_load_raw; + } else if (!strcmp (head, "qktn")) { + strcpy (make, "Apple"); + strcpy (model,"QuickTake 150"); + load_raw = &CLASS kodak_radc_load_raw; + } else if (!memcmp (head,"FUJIFILM",8)) { + fseek (ifp, 84, SEEK_SET); + thumb_offset = get4(); + thumb_length = get4(); + fseek (ifp, 92, SEEK_SET); + parse_fuji (get4()); + if (thumb_offset > 120) { + fseek (ifp, 120, SEEK_SET); + is_raw += (i = get4()) && 1; + if (is_raw == 2 && shot_select) + parse_fuji (i); + } + load_raw = &CLASS unpacked_load_raw; + fseek (ifp, 100+28*(shot_select > 0), SEEK_SET); + parse_tiff (data_offset = get4()); + parse_tiff (thumb_offset+12); +/*RT*/ exif_base = thumb_offset+12; + apply_tiff(); + } else if (!memcmp (head,"RIFF",4)) { + fseek (ifp, 0, SEEK_SET); + parse_riff(); + } else if (!memcmp (head+4,"ftypqt ",9)) { + fseek (ifp, 0, SEEK_SET); + parse_qt (fsize); + is_raw = 0; + } else if (!memcmp (head,"\0\001\0\001\0@",6)) { + fseek (ifp, 6, SEEK_SET); + fread (make, 1, 8, ifp); + fread (model, 1, 8, ifp); + fread (model2, 1, 16, ifp); + data_offset = get2(); + get2(); + raw_width = get2(); + raw_height = get2(); + load_raw = &CLASS nokia_load_raw; + filters = 0x61616161; + } else if (!memcmp (head,"NOKIARAW",8)) { + strcpy (make, "NOKIA"); + order = 0x4949; + fseek (ifp, 300, SEEK_SET); + data_offset = get4(); + i = get4(); + width = get2(); + height = get2(); + switch (tiff_bps = i*8 / (width * height)) { + case 8: load_raw = &CLASS eight_bit_load_raw; break; + case 10: load_raw = &CLASS nokia_load_raw; + } + raw_height = height + (top_margin = i / (width * tiff_bps/8) - height); + mask[0][3] = 1; + filters = 0x61616161; + } else if (!memcmp (head,"ARRI",4)) { + order = 0x4949; + fseek (ifp, 20, SEEK_SET); + width = get4(); + height = get4(); + strcpy (make, "ARRI"); + fseek (ifp, 668, SEEK_SET); + fread (model, 1, 64, ifp); + data_offset = 4096; + load_raw = &CLASS packed_load_raw; + load_flags = 88; + filters = 0x61616161; + } else if (!memcmp (head,"XPDS",4)) { + order = 0x4949; + fseek (ifp, 0x800, SEEK_SET); + fread (make, 1, 41, ifp); + raw_height = get2(); + raw_width = get2(); + fseek (ifp, 56, SEEK_CUR); + fread (model, 1, 30, ifp); + data_offset = 0x10000; + load_raw = &CLASS canon_rmf_load_raw; + gamma_curve (0, 12.25, 1, 1023); + } else if (!memcmp (head+4,"RED1",4)) { + strcpy (make, "Red"); + strcpy (model,"One"); + parse_redcine(); + load_raw = &CLASS redcine_load_raw; + gamma_curve (1/2.4, 12.92, 1, 4095); + filters = 0x49494949; + } else if (!memcmp (head,"DSC-Image",9)) + parse_rollei(); + else if (!memcmp (head,"PWAD",4)) + parse_sinar_ia(); + else if (!memcmp (head,"\0MRM",4)) + parse_minolta(0); + else if (!memcmp (head,"FOVb",4)) + parse_foveon(); + else if (!memcmp (head,"CI",2)) + parse_cine(); + else + for (zero_fsize=i=0; i < sizeof table / sizeof *table; i++) + if (fsize == table[i].fsize) { + strcpy (make, table[i].make ); + strcpy (model, table[i].model); + flip = table[i].flags >> 2; + zero_is_bad = table[i].flags & 2; + if (table[i].flags & 1) + parse_external_jpeg(); + data_offset = table[i].offset; + raw_width = table[i].rw; + raw_height = table[i].rh; + left_margin = table[i].lm; + top_margin = table[i].tm; + width = raw_width - left_margin - table[i].rm; + height = raw_height - top_margin - table[i].bm; + filters = 0x1010101 * table[i].cf; + colors = 4 - !((filters & filters >> 1) & 0x5555); + load_flags = table[i].lf; + switch (tiff_bps = (fsize-data_offset)*8 / (raw_width*raw_height)) { + case 6: + load_raw = &CLASS minolta_rd175_load_raw; break; + case 8: + load_raw = &CLASS eight_bit_load_raw; break; + case 10: case 12: + load_flags |= 128; + load_raw = &CLASS packed_load_raw; break; + case 16: + order = 0x4949 | 0x404 * (load_flags & 1); + tiff_bps -= load_flags >> 4; + tiff_bps -= load_flags = load_flags >> 1 & 7; + load_raw = &CLASS unpacked_load_raw; + } + maximum = (1 << tiff_bps) - (1 << table[i].max); + } + if (zero_fsize) fsize = 0; + if (make[0] == 0) parse_smal (0, flen); + if (make[0] == 0) { + parse_jpeg(0); + //RT fix for the use of fseek below + if (!(strncmp(model,"ov",2) && strncmp(model,"RP_OV",5))) { + fseek (ifp, -6404096, SEEK_END); + if (fread (head, 1, 32, ifp) && !strcmp(head,"BRCMn")) { + strcpy (make, "OmniVision"); + data_offset = ftell(ifp) + 0x8000-32; + width = raw_width; + raw_width = 2611; + load_raw = &CLASS nokia_load_raw; + filters = 0x16161616; + } else is_raw = 0; + } + } + + for (i=0; i < sizeof corp / sizeof *corp; i++) + if (strcasestr (make, corp[i])) /* Simplify company names */ + strcpy (make, corp[i]); + if ((!strcmp(make,"Kodak") || !strcmp(make,"Leica")) && + ((cp = strcasestr(model," DIGITAL CAMERA")) || + (cp = strstr(model,"FILE VERSION")))) + *cp = 0; + if (!strncasecmp(model,"PENTAX",6)) + strcpy (make, "Pentax"); + cp = make + strlen(make); /* Remove trailing spaces */ + while (*--cp == ' ') *cp = 0; + cp = model + strlen(model); + while (*--cp == ' ') *cp = 0; + i = strlen(make); /* Remove make from model */ + if (!strncasecmp (model, make, i) && model[i++] == ' ') + memmove (model, model+i, 64-i); + if (!strncmp (model,"FinePix ",8)) + strcpy (model, model+8); + if (!strncmp (model,"Digital Camera ",15)) + strcpy (model, model+15); + desc[511] = artist[63] = make[63] = model[63] = model2[63] = 0; + if (!is_raw) goto notraw; + + if (!height) height = raw_height; + if (!width) width = raw_width; + if (height == 2624 && width == 3936) /* Pentax K10D and Samsung GX10 */ + { height = 2616; width = 3896; } + if (height == 3136 && width == 4864) /* Pentax K20D and Samsung GX20 */ + { height = 3124; width = 4688; filters = 0x16161616; } + if (width == 4352 && (!strcmp(model,"K-r") || !strcmp(model,"K-x"))) +/*RT*/ { width = 4308; filters = 0x16161616; } + if (width >= 4960 && !strncmp(model,"K-5",3)) + { left_margin = 10; width = 4950; filters = 0x16161616; } + if (width == 4736 && !strcmp(model,"K-7")) + { height = 3122; width = 4684; filters = 0x16161616; top_margin = 2; } + if (width == 6080 && !strcmp(model,"K-3")) + { left_margin = 4; width = 6040; } + if (width == 7424 && !strcmp(model,"645D")) + { height = 5502; width = 7328; filters = 0x61616161; top_margin = 29; + left_margin = 48; } + if (height == 3014 && width == 4096) /* Ricoh GX200 */ + width = 4014; + if (dng_version) { + if (filters == UINT_MAX) filters = 0; + if (filters) is_raw = tiff_samples; + else colors = tiff_samples; + switch (tiff_compress) { + case 1: load_raw = &CLASS packed_dng_load_raw; break; + case 7: load_raw = &CLASS lossless_dng_load_raw; break; + case 8: load_raw = &CLASS deflate_dng_load_raw; break; + case 34892: load_raw = &CLASS lossy_dng_load_raw; break; + default: load_raw = 0; + } + goto dng_skip; + } + if (!strcmp(make,"Canon") && !fsize && tiff_bps != 15) { + if (!load_raw) + load_raw = &CLASS lossless_jpeg_load_raw; + for (i=0; i < sizeof canon / sizeof *canon; i++) + if (raw_width == canon[i][0] && raw_height == canon[i][1]) { + width = raw_width - (left_margin = canon[i][2]); + height = raw_height - (top_margin = canon[i][3]); + width -= canon[i][4]; + height -= canon[i][5]; + mask[0][1] = canon[i][6]; + mask[0][3] = -canon[i][7]; + mask[1][1] = canon[i][8]; + mask[1][3] = -canon[i][9]; + if (canon[i][10]) filters = canon[i][10] * 0x01010101; + } + if ((unique_id | 0x20000) == 0x2720000) { + left_margin = 8; + top_margin = 16; + } + } + for (i=0; i < sizeof unique / sizeof *unique; i++) + if (unique_id == 0x80000000 + unique[i].id) { + adobe_coeff ("Canon", unique[i].model); + if (model[4] == 'K' && strlen(model) == 8) + strcpy (model, unique[i].model); + } + for (i=0; i < sizeof sonique / sizeof *sonique; i++) + if (unique_id == sonique[i].id) + strcpy (model, sonique[i].model); + if (!strcmp(make,"Nikon")) { + if (!load_raw) + load_raw = &CLASS packed_load_raw; + if (model[0] == 'E') + load_flags |= !data_offset << 2 | 2; + } + +/* Set parameters based on camera name (for non-DNG files). */ + + if (!strcmp(model,"KAI-0340") + && find_green (16, 16, 3840, 5120) < 25) { + height = 480; + top_margin = filters = 0; + strcpy (model,"C603"); + } + if (is_foveon) { + if (height*2 < width) pixel_aspect = 0.5; + if (height > width) pixel_aspect = 2; + filters = 0; + simple_coeff(0); + adobe_coeff (make, model); + } else if (!strcmp(make,"Canon") && tiff_bps == 15) { + switch (width) { + case 3344: width -= 66; + case 3872: width -= 6; + } + if (height > width) { + SWAP(height,width); + SWAP(raw_height,raw_width); + } + filters = 0; + tiff_samples = colors = 3; + load_raw = &CLASS canon_sraw_load_raw; + } else if (!strcmp(model,"PowerShot 600")) { + height = 613; + width = 854; + raw_width = 896; + colors = 4; + filters = 0xe1e4e1e4; + load_raw = &CLASS canon_600_load_raw; + } else if (!strcmp(model,"PowerShot A5") || + !strcmp(model,"PowerShot A5 Zoom")) { + height = 773; + width = 960; + raw_width = 992; + pixel_aspect = 256/235.0; + filters = 0x1e4e1e4e; + goto canon_a5; + } else if (!strcmp(model,"PowerShot A50")) { + height = 968; + width = 1290; + raw_width = 1320; + filters = 0x1b4e4b1e; + goto canon_a5; + } else if (!strcmp(model,"PowerShot Pro70")) { + height = 1024; + width = 1552; + filters = 0x1e4b4e1b; +canon_a5: + colors = 4; + tiff_bps = 10; + load_raw = &CLASS packed_load_raw; + load_flags = 40; + } else if (!strcmp(model,"PowerShot Pro90 IS") || + !strcmp(model,"PowerShot G1")) { + colors = 4; + filters = 0xb4b4b4b4; + } else if (!strcmp(model,"PowerShot A610")) { + if (canon_s2is()) strcpy (model+10, "S2 IS"); + } else if (!strcmp(model,"PowerShot SX220 HS")) { + mask[1][3] = -4; + } else if (!strcmp(model,"EOS D2000C")) { + filters = 0x61616161; + black = curve[200]; + } else if (!strcmp(model,"D1")) { + cam_mul[0] *= 256/527.0; + cam_mul[2] *= 256/317.0; + } else if (!strcmp(model,"D1X")) { + width -= 4; + pixel_aspect = 0.5; + } else if (!strcmp(model,"D40X") || + !strcmp(model,"D60") || + !strcmp(model,"D80") || + !strcmp(model,"D3000")) { + height -= 3; + width -= 4; + } else if (!strcmp(model,"D3") || + !strcmp(model,"D3S") || + !strcmp(model,"D700")) { + width -= 4; + left_margin = 2; + } else if (!strcmp(model,"D3100")) { + width -= 28; + left_margin = 6; + } else if (!strcmp(model,"D5000") || + !strcmp(model,"D90")) { + width -= 42; + } else if (!strcmp(model,"D5100") || + !strcmp(model,"D7000") || + !strcmp(model,"COOLPIX A")) { + width -= 44; + } else if (!strcmp(model,"D3200") || + !strncmp(model,"D6",2) || + !strncmp(model,"D800",4)) { + width -= 46; + } else if (!strcmp(model,"D4") || + !strcmp(model,"Df")) { + width -= 52; + left_margin = 2; + } else if (!strncmp(model,"D40",3) || + !strncmp(model,"D50",3) || + !strncmp(model,"D70",3)) { + width--; + } else if (!strcmp(model,"D100")) { + if (load_flags) + raw_width = (width += 3) + 3; + } else if (!strcmp(model,"D200")) { + left_margin = 1; + width -= 4; + filters = 0x94949494; + } else if (!strncmp(model,"D2H",3)) { + left_margin = 6; + width -= 14; + } else if (!strncmp(model,"D2X",3)) { + if (width == 3264) width -= 32; + else width -= 8; + } else if (!strncmp(model,"D300",4)) { + width -= 32; + } else if (!strncmp(model,"COOLPIX P",9) && raw_width != 4032) { + load_flags = 24; + filters = 0x94949494; + if (model[9] == '7' && iso_speed >= 400) + black = 255; + } else if (!strncmp(model,"1 ",2)) { + height -= 2; + } else if (fsize == 1581060) { + simple_coeff(3); + pre_mul[0] = 1.2085; + pre_mul[1] = 1.0943; + pre_mul[3] = 1.1103; + } else if (fsize == 3178560) { + cam_mul[0] *= 4; + cam_mul[2] *= 4; + } else if (fsize == 4771840) { + if (!timestamp && nikon_e995()) + strcpy (model, "E995"); + if (strcmp(model,"E995")) { + filters = 0xb4b4b4b4; + simple_coeff(3); + pre_mul[0] = 1.196; + pre_mul[1] = 1.246; + pre_mul[2] = 1.018; + } + } else if (fsize == 2940928) { + if (!timestamp && !nikon_e2100()) + strcpy (model,"E2500"); + if (!strcmp(model,"E2500")) { + height -= 2; + load_flags = 6; + colors = 4; + filters = 0x4b4b4b4b; + } + } else if (fsize == 4775936) { + if (!timestamp) nikon_3700(); + if (model[0] == 'E' && atoi(model+1) < 3700) + filters = 0x49494949; + if (!strcmp(model,"Optio 33WR")) { + flip = 1; + filters = 0x16161616; + } + if (make[0] == 'O') { + i = find_green (12, 32, 1188864, 3576832); + c = find_green (12, 32, 2383920, 2387016); + if (abs(i) < abs(c)) { + SWAP(i,c); + load_flags = 24; + } + if (i < 0) filters = 0x61616161; + } + } else if (fsize == 5869568) { + if (!timestamp && minolta_z2()) { + strcpy (make, "Minolta"); + strcpy (model,"DiMAGE Z2"); + } + load_flags = 6 + 24*(make[0] == 'M'); + } else if (fsize == 6291456) { + fseek (ifp, 0x300000, SEEK_SET); + if ((order = guess_byte_order(0x10000)) == 0x4d4d) { + height -= (top_margin = 16); + width -= (left_margin = 28); + maximum = 0xf5c0; + strcpy (make, "ISG"); + model[0] = 0; + } + } else if (!strcmp(make,"Fujifilm")) { + if (!strcmp(model+7,"S2Pro")) { + strcpy (model,"S2Pro"); + height = 2144; + width = 2880; + flip = 6; + } else if (load_raw != &CLASS packed_load_raw) + maximum = (is_raw == 2 && shot_select) ? 0x2f00 : 0x3e00; + top_margin = (raw_height - height) >> 2 << 1; + left_margin = (raw_width - width ) >> 2 << 1; + if (width == 2848 || width == 3664) filters = 0x16161616; + if (width == 4032 || width == 4952) left_margin = 0; + if (width == 3328 && (width -= 66)) left_margin = 34; + if (width == 4936) left_margin = 4; + if (!strcmp(model,"HS50EXR") || + !strcmp(model,"F900EXR")) { + width += 2; + left_margin = 0; + filters = 0x16161616; + } + if (fuji_layout) raw_width *= is_raw; + if (filters == 9) + FORC(36) ((char *)xtrans)[c] = + xtrans_abs[(c/6+top_margin) % 6][(c+left_margin) % 6]; + } else if (!strcmp(model,"KD-400Z")) { + height = 1712; + width = 2312; + raw_width = 2336; + goto konica_400z; + } else if (!strcmp(model,"KD-510Z")) { + goto konica_510z; + } else if (!strcasecmp(make,"Minolta")) { + if (!load_raw && (maximum = 0xfff)) + load_raw = &CLASS unpacked_load_raw; + if (!strncmp(model,"DiMAGE A",8)) { + if (!strcmp(model,"DiMAGE A200")) + filters = 0x49494949; + tiff_bps = 12; + load_raw = &CLASS packed_load_raw; + } else if (!strncmp(model,"ALPHA",5) || + !strncmp(model,"DYNAX",5) || + !strncmp(model,"MAXXUM",6)) { + sprintf (model+20, "DYNAX %-10s", model+6+(model[0]=='M')); + adobe_coeff (make, model+20); + load_raw = &CLASS packed_load_raw; + } else if (!strncmp(model,"DiMAGE G",8)) { + if (model[8] == '4') { + height = 1716; + width = 2304; + } else if (model[8] == '5') { +konica_510z: + height = 1956; + width = 2607; + raw_width = 2624; + } else if (model[8] == '6') { + height = 2136; + width = 2848; + } + data_offset += 14; + filters = 0x61616161; +konica_400z: + load_raw = &CLASS unpacked_load_raw; + maximum = 0x3df; + order = 0x4d4d; + } + } else if (!strcmp(model,"*ist D")) { + load_raw = &CLASS unpacked_load_raw; + data_error = -1; + } else if (!strcmp(model,"*ist DS")) { + height -= 2; + } else if (!strcmp(make,"Samsung") && raw_width == 4704) { + height -= top_margin = 8; + width -= 2 * (left_margin = 8); + load_flags = 32; + } else if (!strcmp(make,"Samsung") && raw_height == 3714) { + height -= top_margin = 18; + left_margin = raw_width - (width = 5536); + if (raw_width != 5600) + left_margin = top_margin = 0; + filters = 0x61616161; + colors = 3; + } else if (!strcmp(make,"Samsung") && raw_width == 5632) { + order = 0x4949; + height = 3694; + top_margin = 2; + width = 5574 - (left_margin = 32 + tiff_bps); + if (tiff_bps == 12) load_flags = 80; + } else if (!strcmp(make,"Samsung") && raw_width == 5664) { + height -= top_margin = 17; + left_margin = 96; + width = 5544; + filters = 0x49494949; + } else if (!strcmp(make,"Samsung") && raw_width == 6496) { + filters = 0x61616161; + black = 1 << (tiff_bps - 7); + } else if (!strcmp(model,"EX1")) { + order = 0x4949; + height -= 20; + top_margin = 2; + if ((width -= 6) > 3682) { + height -= 10; + width -= 46; + top_margin = 8; + } + } else if (!strcmp(model,"WB2000")) { + order = 0x4949; + height -= 3; + top_margin = 2; + if ((width -= 10) > 3718) { + height -= 28; + width -= 56; + top_margin = 8; + } + } else if (strstr(model,"WB550")) { + strcpy (model, "WB550"); + } else if (!strcmp(model,"EX2F")) { + height = 3045; + width = 4070; + top_margin = 3; + order = 0x4949; + filters = 0x49494949; + load_raw = &CLASS unpacked_load_raw; + } else if (!strcmp(model,"STV680 VGA")) { + black = 16; + } else if (!strcmp(model,"N95")) { + height = raw_height - (top_margin = 2); + } else if (!strcmp(model,"640x480")) { + gamma_curve (0.45, 4.5, 1, 255); + } else if (!strcmp(make,"Hasselblad")) { + if (load_raw == &CLASS lossless_jpeg_load_raw) + load_raw = &CLASS hasselblad_load_raw; + if (raw_width == 7262) { + if (!strcmp(model, "H3D")) strcpy(model, "H3D-39"); // RT + height = 5444; + width = 7248; + top_margin = 4; + left_margin = 7; + filters = 0x61616161; + } else if (raw_width == 7410) { + if (!strcmp(model, "H4D")) strcpy(model, "H4D-40"); // RT + height = 5502; + width = 7328; + top_margin = 4; + left_margin = 41; + filters = 0x61616161; + } else if (raw_width == 6542) { // RT, H3D-31, H3DII-31, H4D-31 + if (!strcmp(model, "H3D")) strcpy(model, "H3D-31"); + if (!strcmp(model, "H4D")) strcpy(model, "H4D-31"); + height = 4904; + width = 6524; + top_margin = 4; + left_margin = 8; + } else if (raw_width == 8282) { // RT, H3DII-50, H3DII-50MS, CFV-50, H4D-50 + if (!strcmp(model, "H3D")) strcpy(model, "H3DII-50"); + if (!strcmp(model, "H4D")) strcpy(model, "H4D-50"); + height = 6152; + width = 8196; + top_margin = 4; + left_margin = 44; + } else if (raw_width == 8374) { // RT, CFV-50c, H5D-50c, "H5D-50c MS", "H5D-200c MS" + if (!strcmp(model, "H5D")) strcpy(model, "H5D-50c"); + if (!strcmp(model, "CFV-2")) strcpy(model, "CFV-50c"); + height = 6208; + width = 8280; + top_margin = 96; + left_margin = 48; + } else if (raw_width == 9044) { + height = 6716; + width = 8964; + top_margin = 8; + left_margin = 40; + // RT: removed black level / maximum adjustment, as it does not seem to be correct when there are clipped highlights. Tested with Hasselblad H4D-60. + //black += load_flags = 256; + //maximum = 0x8101; + } else if (raw_width == 4096) { // RT: CF-22 etc + if (!strcmp(model, "H3D")) strcpy(model, "H3D-22"); + else if (strstr(model3, "Hasselblad ") == model3) strcpy(model, &model3[11]); + if (strstr(model3, "ixpressCF132")) strcpy(model, "CF-22"); // ixpressCF132 / CF132 is same as CF-22, we use the simpler name + else if (strstr(model3, "Hasselblad96")) strcpy(model, "CFV"); // popularly called CFV-16 + } else if (raw_width == 4090) { + strcpy (model, "V96C"); + height -= (top_margin = 6); + width -= (left_margin = 3) + 7; + filters = 0x61616161; + } + if (tiff_samples > 1) { + is_raw = tiff_samples+1; + if (!shot_select && !half_size) filters = 0; + } + } else if (!strcmp(make,"Sinar")) { + if (!load_raw) load_raw = &CLASS unpacked_load_raw; + if (is_raw > 1 && !shot_select && !half_size) filters = 0; + maximum = 0x3fff; + } else if (!strcmp(make,"Leaf")) { + maximum = 0x3fff; + fseek (ifp, data_offset, SEEK_SET); + if (ljpeg_start (&jh, 1) && jh.bits == 15) + maximum = 0x1fff; + if (tiff_samples > 1) filters = 0; + if (tiff_samples > 1 || tile_length < raw_height) { + load_raw = &CLASS leaf_hdr_load_raw; + raw_width = tile_width; + } + if ((width | height) == 2048) { + if (tiff_samples == 1) { + filters = 1; + strcpy (cdesc, "RBTG"); + strcpy (model, "CatchLight"); + top_margin = 8; left_margin = 18; height = 2032; width = 2016; + } else { + strcpy (model, "DCB2"); + top_margin = 10; left_margin = 16; height = 2028; width = 2022; + } + } else if (width+height == 3144+2060) { + if (!model[0]) strcpy (model, "Cantare"); + if (width > height) { + top_margin = 6; left_margin = 32; height = 2048; width = 3072; + filters = 0x61616161; + } else { + left_margin = 6; top_margin = 32; width = 2048; height = 3072; + filters = 0x16161616; + } + if (!cam_mul[0] || model[0] == 'V') filters = 0; + else is_raw = tiff_samples; + } else if (width == 2116) { + strcpy (model, "Valeo 6"); + height -= 2 * (top_margin = 30); + width -= 2 * (left_margin = 55); + filters = 0x49494949; + } else if (width == 3171) { + strcpy (model, "Valeo 6"); + height -= 2 * (top_margin = 24); + width -= 2 * (left_margin = 24); + filters = 0x16161616; + } + } else if (!strcmp(make,"Leica") || !strcmp(make,"Panasonic")) { + if(raw_width > 0) { // avoid divide by zero + if ((flen - data_offset) / (raw_width*8/7) == raw_height) + load_raw = &CLASS panasonic_load_raw; + if (!load_raw) { + load_raw = &CLASS unpacked_load_raw; + load_flags = 4; + } + zero_is_bad = 1; + if ((height += 12) > raw_height) height = raw_height; + for (i=0; i < sizeof pana / sizeof *pana; i++) + if (raw_width == pana[i][0] && raw_height == pana[i][1]) { + left_margin = pana[i][2]; + top_margin = pana[i][3]; + width += pana[i][4]; + height += pana[i][5]; + } + filters = 0x01010101 * (uchar) "\x94\x61\x49\x16" + [((filters-1) ^ (left_margin & 1) ^ (top_margin << 1)) & 3]; + } + } else if (!strcmp(model,"C770UZ")) { + height = 1718; + width = 2304; + filters = 0x16161616; + load_raw = &CLASS packed_load_raw; + load_flags = 30; + } else if (!strcmp(make,"Olympus")) { + height += height & 1; + if (exif_cfa) filters = exif_cfa; + if (width == 4100) width -= 4; + if (width == 4080) width -= 24; + if (width == 9280) { width -= 6; height -= 6; } + if (load_raw == &CLASS unpacked_load_raw) + load_flags = 4; + tiff_bps = 12; + if (!strcmp(model,"E-300") || + !strcmp(model,"E-500")) { + width -= 20; + if (load_raw == &CLASS unpacked_load_raw) { + maximum = 0xfc3; + memset (cblack, 0, sizeof cblack); + } + } else if (!strcmp(model,"E-330")) { + width -= 30; + if (load_raw == &CLASS unpacked_load_raw) + maximum = 0xf79; + } else if (!strcmp(model,"SP550UZ")) { + thumb_length = flen - (thumb_offset = 0xa39800); + thumb_height = 480; + thumb_width = 640; + } + } else if (!strcmp(model,"N Digital")) { + height = 2047; + width = 3072; + filters = 0x61616161; + data_offset = 0x1a00; + load_raw = &CLASS packed_load_raw; + } else if (!strcmp(model,"DSC-F828")) { + width = 3288; + left_margin = 5; + mask[1][3] = -17; + data_offset = 862144; + load_raw = &CLASS sony_load_raw; + filters = 0x9c9c9c9c; + colors = 4; + strcpy (cdesc, "RGBE"); + } else if (!strcmp(model,"DSC-V3")) { + width = 3109; + left_margin = 59; + mask[0][1] = 9; + data_offset = 787392; + load_raw = &CLASS sony_load_raw; + } else if (!strcmp(make,"Sony") && raw_width == 3984) { + width = 3925; + order = 0x4d4d; + } else if (!strcmp(make,"Sony") && raw_width == 4288) { + width -= 32; + } else if (!strcmp(make,"Sony") && raw_width == 4928) { + if (height < 3280) width -= 8; + } else if (!strcmp(make,"Sony") && raw_width == 5504) { + width -= height > 3664 ? 8 : 32; + } else if (!strcmp(make,"Sony") && raw_width == 6048) { + width -= 24; + if (strstr(model,"RX1") || strstr(model,"A99")) + width -= 6; + } else if (!strcmp(make,"Sony") && raw_width == 7392) { + width -= 30; + } else if (!strcmp(model,"DSLR-A100")) { + if (width == 3880) { + height--; + width = ++raw_width; + } else { + height -= 4; + width -= 4; + order = 0x4d4d; + load_flags = 2; + } + filters = 0x61616161; + } else if (!strcmp(model,"DSLR-A350")) { + height -= 4; + } else if (!strcmp(model,"PIXL")) { + height -= top_margin = 4; + width -= left_margin = 32; + gamma_curve (0, 7, 1, 255); + } else if (!strcmp(model,"C603") || !strcmp(model,"C330") + || !strcmp(model,"12MP")) { + order = 0x4949; + if (filters && data_offset) { + fseek (ifp, data_offset < 4096 ? 168 : 5252, SEEK_SET); + read_shorts (curve, 256); + } else gamma_curve (0, 3.875, 1, 255); + load_raw = filters ? &CLASS eight_bit_load_raw : + strcmp(model,"C330") ? &CLASS kodak_c603_load_raw : + &CLASS kodak_c330_load_raw; + load_flags = tiff_bps > 16; + tiff_bps = 8; + } else if (!strncasecmp(model,"EasyShare",9)) { + data_offset = data_offset < 0x15000 ? 0x15000 : 0x17000; + load_raw = &CLASS packed_load_raw; + } else if (!strcasecmp(make,"Kodak")) { + if (filters == UINT_MAX) filters = 0x61616161; + if (!strncmp(model,"NC2000",6) || + !strncmp(model,"EOSDCS",6) || + !strncmp(model,"DCS4",4)) { + width -= 4; + left_margin = 2; + if (model[6] == ' ') model[6] = 0; + if (!strcmp(model,"DCS460A")) goto bw; + } else if (!strcmp(model,"DCS660M")) { + black = 214; + goto bw; + } else if (!strcmp(model,"DCS760M")) { +bw: colors = 1; + filters = 0; + } + if (!strcmp(model+4,"20X")) + strcpy (cdesc, "MYCY"); + if (strstr(model,"DC25")) { + strcpy (model, "DC25"); + data_offset = 15424; + } + if (!strncmp(model,"DC2",3)) { + raw_height = 2 + (height = 242); + if (flen < 100000) { + raw_width = 256; width = 249; + pixel_aspect = (4.0*height) / (3.0*width); + } else { + raw_width = 512; width = 501; + pixel_aspect = (493.0*height) / (373.0*width); + } + top_margin = left_margin = 1; + colors = 4; + filters = 0x8d8d8d8d; + simple_coeff(1); + pre_mul[1] = 1.179; + pre_mul[2] = 1.209; + pre_mul[3] = 1.036; + load_raw = &CLASS eight_bit_load_raw; + } else if (!strcmp(model,"40")) { + strcpy (model, "DC40"); + height = 512; + width = 768; + data_offset = 1152; + load_raw = &CLASS kodak_radc_load_raw; + } else if (strstr(model,"DC50")) { + strcpy (model, "DC50"); + height = 512; + width = 768; + data_offset = 19712; + load_raw = &CLASS kodak_radc_load_raw; + } else if (strstr(model,"DC120")) { + strcpy (model, "DC120"); + height = 976; + width = 848; + pixel_aspect = height/0.75/width; + load_raw = tiff_compress == 7 ? + &CLASS kodak_jpeg_load_raw : &CLASS kodak_dc120_load_raw; + } else if (!strcmp(model,"DCS200")) { + thumb_height = 128; + thumb_width = 192; + thumb_offset = 6144; + thumb_misc = 360; + write_thumb = &CLASS layer_thumb; + black = 17; + } + } else if (!strcmp(model,"Fotoman Pixtura")) { + height = 512; + width = 768; + data_offset = 3632; + load_raw = &CLASS kodak_radc_load_raw; + filters = 0x61616161; + simple_coeff(2); + } else if (!strncmp(model,"QuickTake",9)) { + if (head[5]) strcpy (model+10, "200"); + fseek (ifp, 544, SEEK_SET); + height = get2(); + width = get2(); + data_offset = (get4(),get2()) == 30 ? 738:736; + if (height > width) { + SWAP(height,width); + fseek (ifp, data_offset-6, SEEK_SET); + flip = ~get2() & 3 ? 5:6; + } + filters = 0x61616161; + } else if (!strcmp(make,"Rollei") && !load_raw) { + switch (raw_width) { + case 1316: + height = 1030; + width = 1300; + top_margin = 1; + left_margin = 6; + break; + case 2568: + height = 1960; + width = 2560; + top_margin = 2; + left_margin = 8; + } + filters = 0x16161616; + load_raw = &CLASS rollei_load_raw; + } + if (!model[0]) + sprintf (model, "%dx%d", width, height); + if (filters == UINT_MAX) filters = 0x94949494; + if (thumb_offset && !thumb_height) { + fseek (ifp, thumb_offset, SEEK_SET); + if (ljpeg_start (&jh, 1)) { + thumb_width = jh.wide; + thumb_height = jh.high; + } + } +dng_skip: + if ((use_camera_matrix & (use_camera_wb || dng_version)) + && cmatrix[0][0] > 0.125) { + memcpy (rgb_cam, cmatrix, sizeof cmatrix); + raw_color = 0; + } + 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)) + adobe_coeff (make, model); + if (raw_color) adobe_coeff (make, model); + if (load_raw == &CLASS kodak_radc_load_raw) + if (raw_color) adobe_coeff ("Apple","Quicktake"); + if (fuji_width) { + fuji_width = width >> !fuji_layout; + if (~fuji_width & 1) filters = 0x49494949; + width = (height >> fuji_layout) + fuji_width; + height = width - 1; + pixel_aspect = 1; + } else { + if (raw_height < height) raw_height = height; + if (raw_width < width ) raw_width = width; + } + if (!tiff_bps) tiff_bps = 12; + if (!maximum) maximum = ((uint64_t)1 << tiff_bps) - 1; // use uint64_t to avoid overflow if tiff_bps == 32 + if (!load_raw || height < 22 || width < 22 || + tiff_samples > 6 || colors > 4) + is_raw = 0; +#ifdef NO_JASPER + if (load_raw == &CLASS redcine_load_raw) { + fprintf (stderr,_("%s: You must link dcraw with %s!!\n"), + ifname, "libjasper"); + is_raw = 0; + } +#endif +#ifdef NO_JPEG + if (load_raw == &CLASS kodak_jpeg_load_raw || + load_raw == &CLASS lossy_dng_load_raw) { + fprintf (stderr,_("%s: You must link dcraw with %s!!\n"), + ifname, "libjpeg"); + is_raw = 0; + } +#endif + if (!cdesc[0]) + strcpy (cdesc, colors == 3 ? "RGBG":"GMCY"); + if (!raw_height) raw_height = height; + if (!raw_width ) raw_width = width; + if (filters > 999 && colors == 3) + filters |= ((filters >> 2 & 0x22222222) | + (filters << 2 & 0x88888888)) & filters << 1; +notraw: + if (flip == UINT_MAX) flip = tiff_flip; + if (flip == UINT_MAX) flip = 0; +} + +#ifndef NO_LCMS +void CLASS apply_profile (const char *input, const char *output) +{ + char *prof; + cmsHPROFILE hInProfile=0, hOutProfile=0; + cmsHTRANSFORM hTransform; + FILE *fp; + unsigned size; + + if (strcmp (input, "embed")) + hInProfile = cmsOpenProfileFromFile (input, "r"); + else if (profile_length) { + prof = (char *) malloc (profile_length); + merror (prof, "apply_profile()"); + fseek (ifp, profile_offset, SEEK_SET); + fread (prof, 1, profile_length, ifp); + hInProfile = cmsOpenProfileFromMem (prof, profile_length); + free (prof); + } else + fprintf (stderr,_("%s has no embedded profile.\n"), ifname); + if (!hInProfile) return; + if (!output) + hOutProfile = cmsCreate_sRGBProfile(); + else if ((fp = fopen (output, "rb"))) { + fread (&size, 4, 1, fp); + fseek (fp, 0, SEEK_SET); + oprof = (unsigned *) malloc (size = ntohl(size)); + merror (oprof, "apply_profile()"); + fread (oprof, 1, size, fp); + fclose (fp); + if (!(hOutProfile = cmsOpenProfileFromMem (oprof, size))) { + free (oprof); + oprof = 0; + } + } else + fprintf (stderr,_("Cannot open file %s!\n"), output); + if (!hOutProfile) goto quit; + if (verbose) + fprintf (stderr,_("Applying color profile...\n")); + hTransform = cmsCreateTransform (hInProfile, TYPE_RGBA_16, + hOutProfile, TYPE_RGBA_16, INTENT_PERCEPTUAL, 0); + cmsDoTransform (hTransform, image, image, width*height); + raw_color = 1; /* Don't use rgb_cam with a profile */ + cmsDeleteTransform (hTransform); + cmsCloseProfile (hOutProfile); +quit: + cmsCloseProfile (hInProfile); +} +#endif + +/* RT: DNG Float */ + +#include +#include + +static void decodeFPDeltaRow(Bytef * src, Bytef * dst, size_t tileWidth, size_t realTileWidth, int bytesps, int factor) { + // DecodeDeltaBytes + for (size_t col = factor; col < realTileWidth*bytesps; ++col) { + src[col] += src[col - factor]; + } + // Reorder bytes into the image + // 16 and 32-bit versions depend on local architecture, 24-bit does not + if (bytesps == 3) { + for (size_t col = 0; col < tileWidth; ++col) { + dst[col*3] = src[col]; + dst[col*3 + 1] = src[col + realTileWidth]; + dst[col*3 + 2] = src[col + realTileWidth*2]; + } + } else { + union X { uint32_t x; uint8_t c; }; + if (((union X){1}).c) { + for (size_t col = 0; col < tileWidth; ++col) { + for (size_t byte = 0; byte < bytesps; ++byte) + dst[col*bytesps + byte] = src[col + realTileWidth*(bytesps-byte-1)]; // Little endian + } + } else { + for (size_t col = 0; col < tileWidth; ++col) { + for (size_t byte = 0; byte < bytesps; ++byte) + dst[col*bytesps + byte] = src[col + realTileWidth*byte]; + } + } + } + +} + +// From DNG SDK dng_utils.h +static inline uint32_t DNG_HalfToFloat(uint16_t halfValue) { + int32_t sign = (halfValue >> 15) & 0x00000001; + int32_t exponent = (halfValue >> 10) & 0x0000001f; + int32_t mantissa = halfValue & 0x000003ff; + if (exponent == 0) { + if (mantissa == 0) { + // Plus or minus zero + return (uint32_t) (sign << 31); + } else { + // Denormalized number -- renormalize it + while (!(mantissa & 0x00000400)) { + mantissa <<= 1; + exponent -= 1; + } + exponent += 1; + mantissa &= ~0x00000400; + } + } else if (exponent == 31) { + if (mantissa == 0) { + // Positive or negative infinity, convert to maximum (16 bit) values. + return (uint32_t) ((sign << 31) | ((0x1eL + 127 - 15) << 23) | (0x3ffL << 13)); + } else { + // Nan -- Just set to zero. + return 0; + } + } + // Normalized number + exponent += (127 - 15); + mantissa <<= 13; + // Assemble sign, exponent and mantissa. + return (uint32_t) ((sign << 31) | (exponent << 23) | mantissa); +} + +static inline uint32_t DNG_FP24ToFloat(const uint8_t * input) { + int32_t sign = (input [0] >> 7) & 0x01; + int32_t exponent = (input [0] ) & 0x7F; + int32_t mantissa = (((int32_t) input [1]) << 8) | input[2]; + if (exponent == 0) { + if (mantissa == 0) { + // Plus or minus zero + return (uint32_t) (sign << 31); + } else { + // Denormalized number -- renormalize it + while (!(mantissa & 0x00010000)) { + mantissa <<= 1; + exponent -= 1; + } + exponent += 1; + mantissa &= ~0x00010000; + } + } else if (exponent == 127) { + if (mantissa == 0) { + // Positive or negative infinity, convert to maximum (24 bit) values. + return (uint32_t) ((sign << 31) | ((0x7eL + 128 - 64) << 23) | (0xffffL << 7)); + } else { + // Nan -- Just set to zero. + return 0; + } + } + // Normalized number + exponent += (128 - 64); + mantissa <<= 7; + // Assemble sign, exponent and mantissa. + return (uint32_t) ((sign << 31) | (exponent << 23) | mantissa); +} + +static void expandFloats(Bytef * dst, int tileWidth, int bytesps) { + if (bytesps == 2) { + uint16_t * dst16 = (uint16_t *) dst; + uint32_t * dst32 = (uint32_t *) dst; + for (int index = tileWidth - 1; index >= 0; --index) { + dst32[index] = DNG_HalfToFloat(dst16[index]); + } + } else if (bytesps == 3) { + uint8_t * dst8 = ((uint8_t *) dst) + (tileWidth - 1) * 3; + uint32_t * dst32 = (uint32_t *) dst; + for (int index = tileWidth - 1; index >= 0; --index, dst8 -= 3) { + dst32[index] = DNG_FP24ToFloat(dst8); + } + } +} + +static void copyFloatDataToInt(float * src, ushort * dst, size_t size, float max) { + bool negative = false, nan = false; + +#ifdef _OPENMP +#pragma omp parallel for +#endif + for (size_t i = 0; i < size; ++i) { + if (src[i] < 0.0f) { + negative = true; + src[i] = 0.0f; + } else if (std::isnan(src[i])) { + nan = true; + src[i] = max; + } + // Copy the data to the integer buffer to build the thumbnail + dst[i] = (ushort)src[i]; + } + if (negative) + fprintf(stderr, "DNG Float: Negative data found in input file\n"); + if (nan) + fprintf(stderr, "DNG Float: NaN data found in input file\n"); +} + +void CLASS deflate_dng_load_raw() { + struct tiff_ifd * ifd = &tiff_ifd[0]; + while (ifd < &tiff_ifd[tiff_nifds] && ifd->offset != data_offset) ++ifd; + if (ifd == &tiff_ifd[tiff_nifds]) { + fprintf(stderr, "DNG Deflate: Raw image not found???\n"); + return; + } + + int predFactor; + switch(ifd->predictor) { + case 3: predFactor = 1; break; + case 34894: predFactor = 2; break; + case 34895: predFactor = 4; break; + default: predFactor = 0; break; + } + + if (ifd->sample_format == 3) { // Floating point data + float_raw_image = new float[raw_width * raw_height]; + +#ifdef _OPENMP +#pragma omp parallel for +#endif + for (size_t i = 0; i < raw_width * raw_height; ++i) + float_raw_image[i] = 0.0f; + } + + // NOTE: This reader is based on the official DNG SDK from Adobe. + // It assumes tiles without subtiles, but the standard does not say that + // subtiles or strips couldn't be used. + if (tile_length < INT_MAX) { + size_t tilesWide = (raw_width + tile_width - 1) / tile_width; + size_t tilesHigh = (raw_height + tile_length - 1) / tile_length; + size_t tileCount = tilesWide * tilesHigh; + //fprintf(stderr, "%dx%d tiles, %d total\n", tilesWide, tilesHigh, tileCount); + size_t tileOffsets[tileCount]; + for (size_t t = 0; t < tileCount; ++t) { + tileOffsets[t] = get4(); + } + size_t tileBytes[tileCount]; + uLongf maxCompressed = 0; + if (tileCount == 1) { + tileBytes[0] = maxCompressed = ifd->bytes; + } else { + fseek(ifp, ifd->bytes, SEEK_SET); + for (size_t t = 0; t < tileCount; ++t) { + tileBytes[t] = get4(); + //fprintf(stderr, "Tile %d at %d, size %d\n", t, tileOffsets[t], tileBytes[t]); + if (maxCompressed < tileBytes[t]) + maxCompressed = tileBytes[t]; + } + } + uLongf dstLen = tile_width * tile_length * 4; + +#ifdef _OPENMP +#pragma omp parallel +#endif +{ + Bytef * cBuffer = new Bytef[maxCompressed]; + Bytef * uBuffer = new Bytef[dstLen]; + +#ifdef _OPENMP +#pragma omp for collapse(2) 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); +#pragma omp critical +{ + 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 + } + } + } + + delete [] cBuffer; + delete [] uBuffer; +} + } + + if (ifd->sample_format == 3) { // Floating point data + copyFloatDataToInt(float_raw_image, raw_image, raw_width*raw_height, maximum); + } +} + +/* RT: removed unused functions */ + +struct tiff_tag { + ushort tag, type; + int count; + union { char c[4]; short s[2]; int i; } val; +}; + +struct tiff_hdr { + ushort order, magic; + int ifd; + ushort pad, ntag; + struct tiff_tag tag[23]; + int nextifd; + ushort pad2, nexif; + struct tiff_tag exif[4]; + ushort pad3, ngps; + struct tiff_tag gpst[10]; + short bps[4]; + int rat[10]; + unsigned gps[26]; + char desc[512], make[64], model[64], soft[32], date[20], artist[64]; +}; + +/* RT: Delete from here */ +/*RT*/#undef SQR +/*RT*/#undef MAX +/*RT*/#undef MIN +/*RT*/#undef ABS +/*RT*/#undef LIM +/*RT*/#undef ULIM +/*RT*/#undef CLIP diff --git a/rtengine/dcraw.h b/rtengine/dcraw.h new file mode 100644 index 000000000..3317a68bf --- /dev/null +++ b/rtengine/dcraw.h @@ -0,0 +1,404 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2010 Fabio Suprani + * + * 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 DCRAW_H +#define DCRAW_H + +#include "myfile.h" +#include + + +class DCraw +{ +public: + typedef unsigned short ushort; + typedef unsigned char uchar; + typedef unsigned short (*dcrawImage_t)[4]; +#ifdef WIN32 + typedef __int64 INT64; + typedef unsigned __int64 UINT64; +#else + typedef long long INT64; + typedef unsigned long long UINT64; +#endif + + + DCraw() + :exif_base(-1) + ,ciff_base(-1) + ,ciff_len(0) + ,ifp(NULL),ofp(NULL) + ,order(0x4949) + ,ifname(NULL) + ,meta_data(NULL) + ,shot_select(0),multi_out(0) + ,float_raw_image(NULL) + ,image(NULL) + ,bright(1.),threshold(0.) + ,half_size(0),four_color_rgb(0),document_mode(0),highlight(0) + ,verbose(0) + ,use_auto_wb(0),use_camera_wb(0),use_camera_matrix(1) + ,output_color(1),output_bps(8),output_tiff(0),med_passes(0),no_auto_bright(0) + ,RT_whitelevel_from_constant(0) + ,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; + gamm[0]=0.45;gamm[1]=4.5;gamm[2]=gamm[3]=gamm[4]=gamm[5]=0; + user_mul[0]=user_mul[1]=user_mul[2]=user_mul[3]=0; + 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; + FILE *ofp; + short order; + const char *ifname; + char *meta_data, xtrans[6][6],xtrans_abs[6][6]; + char cdesc[5], desc[512], make[64], model[64], model2[64], model3[64], artist[64]; + float flash_used, canon_ev, iso_speed, shutter, aperture, focal_len; + time_t timestamp; + unsigned shot_order, kodak_cbpp, filters, exif_cfa, unique_id; + off_t strip_offset, data_offset; + off_t thumb_offset, meta_offset, profile_offset; + unsigned thumb_length, meta_length, profile_length; + unsigned thumb_misc, *oprof, fuji_layout, shot_select, multi_out; + unsigned tiff_nifds, tiff_samples, tiff_bps, tiff_compress; + unsigned black, cblack[4102], maximum, mix_green, raw_color, zero_is_bad; + unsigned zero_after_ff, is_raw, dng_version, is_foveon, data_error; + unsigned tile_width, tile_length, gpsdata[32], load_flags; + ushort raw_height, raw_width, height, width, top_margin, left_margin; + ushort shrink, iheight, iwidth, fuji_width, thumb_width, thumb_height; + ushort *raw_image; + float * float_raw_image; + ushort white[8][8], curve[0x10000], cr2_slice[3], sraw_mul[4]; + int mask[8][4], flip, tiff_flip, colors; + double pixel_aspect; + double aber[4]; + double gamm[6]; + dcrawImage_t image; + float bright, threshold, user_mul[4]; + + int half_size, four_color_rgb, document_mode, highlight; + int verbose, use_auto_wb, use_camera_wb, use_camera_matrix; + int output_color, output_bps, output_tiff, med_passes; + int no_auto_bright; + unsigned greybox[4] ; + int RT_whitelevel_from_constant; + int RT_blacklevel_from_constant; + int RT_matrix_from_constant; + + float cam_mul[4], pre_mul[4], cmatrix[3][4], rgb_cam[3][4]; + + int histogram[4][0x2000]; + void (DCraw::*write_thumb)(), (DCraw::*write_fun)(); + void (DCraw::*load_raw)(), (DCraw::*thumb_load_raw)(); + jmp_buf failure; + + unsigned huff[1024]; // static inside foveon_decoder + + struct decode { + struct decode *branch[2]; + int leaf; + } first_decode[2048], *second_decode, *free_decode; + + struct tiff_ifd { + int width, height, bps, comp, phint, offset, flip, samples, bytes; + int tile_width, tile_length, sample_format, predictor; + } tiff_ifd[10]; + + struct ph1 { + int format, key_off, tag_21a; + int black, split_col, black_col, split_row, black_row; + float tag_210; + } ph1; + struct hbd { + off_t levels, unknown1, flatfield; + } hbd; + + struct jhead { + int bits, high, wide, clrs, sraw, psv, restart, vpred[6]; + ushort *huff[6], *free[4], *row; + }; + + struct tiff_tag { + ushort tag, type; + int count; + union { char c[4]; short s[2]; int i; } val; + }; + + struct tiff_hdr { + ushort order, magic; + int ifd; + ushort pad, ntag; + struct tiff_tag tag[23]; + int nextifd; + ushort pad2, nexif; + struct tiff_tag exif[4]; + ushort pad3, ngps; + struct tiff_tag gpst[10]; + short bps[4]; + int rat[10]; + unsigned gps[26]; + char desc[512], make[64], model[64], soft[32], date[20], artist[64]; + }; +protected: + +int fcol (int row, int col); +void merror (void *ptr, const char *where); +void derror(); +ushort sget2 (uchar *s); +ushort get2(); +unsigned sget4 (uchar *s); +unsigned get4(); +unsigned getint (int type); +float int_to_float (int i); +double getreal (int type); +void read_shorts (ushort *pixel, int count); +void cubic_spline(const int *x_, const int *y_, const int len); +void canon_600_fixed_wb (int temp); +int canon_600_color (int ratio[2], int mar); +void canon_600_auto_wb(); +void canon_600_coeff(); +void canon_600_load_raw(); +void canon_600_correct(); +int canon_s2is(); +void redcine_load_raw(); +void parse_redcine(); + +// getbithuff(int nbits, ushort *huff); +class getbithuff_t +{ +public: + getbithuff_t(DCraw *p,IMFILE *&i, unsigned &z):parent(p),bitbuf(0),vbits(0),reset(0),ifp(i),zero_after_ff(z){} + unsigned operator()(int nbits, ushort *huff); + +private: + void derror(){ + parent->derror(); + } + DCraw *parent; + unsigned bitbuf; + int vbits, reset; + IMFILE *&ifp; + unsigned &zero_after_ff; +}; +getbithuff_t getbithuff; + +ushort * make_decoder_ref (const uchar **source); +ushort * make_decoder (const uchar *source); +void crw_init_tables (unsigned table, ushort *huff[2]); +int canon_has_lowbits(); +void canon_load_raw(); +int ljpeg_start (struct jhead *jh, int info_only); +void ljpeg_end (struct jhead *jh); +int ljpeg_diff (ushort *huff); +ushort * ljpeg_row (int jrow, struct jhead *jh); +void lossless_jpeg_load_raw(); + +void canon_sraw_load_raw(); +void adobe_copy_pixel (unsigned row, unsigned col, ushort **rp); +void lossless_dng_load_raw(); +void packed_dng_load_raw(); +void deflate_dng_load_raw(); +void pentax_load_raw(); +void nikon_load_raw(); +int nikon_is_compressed(); +int nikon_e995(); +int nikon_e2100(); +void nikon_3700(); +int minolta_z2(); +void ppm_thumb(); +void ppm16_thumb(); +void layer_thumb(); +void rollei_thumb(); +void rollei_load_raw(); +int raw (unsigned row, unsigned col); +void phase_one_flat_field (int is_float, int nc); +void phase_one_correct(); +void phase_one_load_raw(); +void nikon_yuv_load_raw(); +void kodak_c330_load_raw(); +void kodak_c603_load_raw(); +void samsung3_load_raw(); +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){} + unsigned operator()(int nbits, ushort *huff); +private: + unsigned get4(){ + return parent->get4(); + } + DCraw *parent; + short ℴ + IMFILE *&ifp; + UINT64 bitbuf; + int vbits; +}; +ph1_bithuff_t ph1_bithuff; + +void phase_one_load_raw_c(); +void hasselblad_correct(); +void parse_hasselblad_gain(); +void hasselblad_load_raw(); +void leaf_hdr_load_raw(); +void unpacked_load_raw(); +void sinar_4shot_load_raw(); +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){} + unsigned operator()(int nbits); +private: + IMFILE *&ifp; + unsigned &load_flags; + uchar buf[0x4000]; + int vbits; +}; +pana_bits_t pana_bits; + +void canon_rmf_load_raw(); +void panasonic_load_raw(); +void olympus_load_raw(); +void minolta_rd175_load_raw(); +void quicktake_100_load_raw(); +void kodak_radc_load_raw(); +void samsung_load_raw(); +void samsung2_load_raw(); +void kodak_jpeg_load_raw(); +void lossy_dng_load_raw(); +void kodak_dc120_load_raw(); +void eight_bit_load_raw(); +void kodak_yrgb_load_raw(); +void kodak_262_load_raw(); +int kodak_65000_decode (short *out, int bsize); +void kodak_65000_load_raw(); +void kodak_ycbcr_load_raw(); +void kodak_rgb_load_raw(); +void kodak_thumb_load_raw(); + +// sony_decrypt(unsigned *data, int len, int start, int key); +class sony_decrypt_t{ +public: + void operator()(unsigned *data, int len, int start, int key); +private: + unsigned pad[128], p; +}; +sony_decrypt_t sony_decrypt; + +void sony_load_raw(); +void sony_arw_load_raw(); +void sony_arw2_load_raw(); +void smal_decode_segment (unsigned seg[2][2], int holes); +void smal_v6_load_raw(); + +int median4 (int *p); +void fill_holes (int holes); +void smal_v9_load_raw(); + +void foveon_decoder (unsigned size, unsigned code); +void foveon_thumb(); +void foveon_sd_load_raw(); +void foveon_load_camf(); +void foveon_load_raw(); +void foveon_huff (ushort *huff); +void foveon_dp_load_raw(); +const char * foveon_camf_param (const char *block, const char *param); +void *foveon_camf_matrix (unsigned dim[3], const char *name); +int foveon_fixed (void *ptr, int size, const char *name); +float foveon_avg (short *pix, int range[2], float cfilt); +short *foveon_make_curve (double max, double mul, double filt); +void foveon_make_curves(short **curvep, float dq[3], float div[3], float filt); +int foveon_apply_curve (short *curve, int i); +void foveon_interpolate(); + +void xtrans_interpolate (int passes); +void cielab (ushort rgb[3], short lab[3]); + +void remove_zeroes(); +void bad_pixels (const char *cfname); +void subtract (const char *fname); +void gamma_curve (double pwr, double ts, int mode, int imax); +void pseudoinverse (double (*in)[3], double (*out)[3], int size); +void cam_xyz_coeff (float rgb_cam[3][4], double cam_xyz[4][3]); +void hat_transform (float *temp, float *base, int st, int size, int sc); +void wavelet_denoise(); +void scale_colors(); +void pre_interpolate(); +void border_interpolate (int border); +void median_filter(); +void blend_highlights(); +void recover_highlights(); +void crop_masked_pixels(); + +void tiff_get (unsigned base, unsigned *tag, unsigned *type, unsigned *len, unsigned *save); +void parse_thumb_note (int base, unsigned toff, unsigned tlen); +int parse_tiff_ifd (int base); +void parse_makernote (int base, int uptag); +void get_timestamp (int reversed); +void parse_exif (int base); +void parse_gps (int base); +void romm_coeff (float romm_cam[3][3]); +void parse_mos (int offset); +void linear_table (unsigned len); +void parse_kodak_ifd (int base); + +void parse_minolta (int base); +int parse_tiff (int base); +void apply_tiff(); +void parse_external_jpeg(); +void ciff_block_1030(); +void parse_ciff (int offset, int length, int depth); +void parse_rollei(); +void parse_sinar_ia(); +void parse_phase_one (int base); +void parse_fuji (int offset); +int parse_jpeg (int offset); +void parse_riff(); +void parse_smal (int offset, int fsize); +void parse_cine(); +char *foveon_gets (int offset, char *str, int len); +void parse_foveon(); + +void adobe_coeff (const char *make, const char *model); +void simple_coeff (int index); +short guess_byte_order (int words); +float find_green (int bps, int bite, int off0, int off1); +void identify(); +void apply_profile (const char *input, const char *output); +void jpeg_thumb() {} // not needed +bool dcraw_coeff_overrides(const char make[], const char model[], int iso_speed, short trans[12], int *black_level, int *white_level); + +}; + + +#endif //DCRAW_H diff --git a/rtengine/dcraw.patch b/rtengine/dcraw.patch new file mode 100755 index 000000000..4d24c779e --- /dev/null +++ b/rtengine/dcraw.patch @@ -0,0 +1,2572 @@ +--- dcraw.c 2015-05-29 16:41:35 +0000 ++++ dcraw.cc 2015-06-01 11:04:42 +0000 +@@ -1,3 +1,15 @@ ++/*RT*/#include ++/*RT*/#include ++/*RT*/#undef MAX ++/*RT*/#undef MIN ++/*RT*/#undef ABS ++/*RT*/#include "rt_math.h" ++/*RT*/#define NO_LCMS ++/*RT*/#define NO_JPEG ++/*RT*/#define NO_JASPER ++/*RT*/#define LOCALTIME ++/*RT*/#define DJGPP ++ + /* + dcraw.c -- Dave Coffin's raw photo decoder + Copyright 1997-2015 by Dave Coffin, dcoffin a cybercom o net +@@ -29,17 +41,17 @@ + #define _GNU_SOURCE + #endif + #define _USE_MATH_DEFINES +-#include +-#include ++#include ++#include + #include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + #include + + #if defined(DJGPP) || defined(__MINGW32__) +@@ -54,7 +66,6 @@ + #ifdef WIN32 + #include + #include +-#pragma comment(lib, "ws2_32.lib") + #define snprintf _snprintf + #define strcasecmp stricmp + #define strncasecmp strnicmp +@@ -98,88 +109,38 @@ + #define LONG_BIT (8 * sizeof (long)) + #endif + +-#if !defined(uchar) +-#define uchar unsigned char +-#endif +-#if !defined(ushort) +-#define ushort unsigned short +-#endif ++#define ushort UshORt ++typedef unsigned char uchar; ++typedef unsigned short ushort; + ++#include "dcraw.h" + /* +- All global variables are defined here, and all functions that ++ RT All global variables are defined here, and all functions that + access them are prefixed with "CLASS". Note that a thread-safe + C++ class cannot have non-const static local variables. + */ +-FILE *ifp, *ofp; +-short order; +-const char *ifname; +-char *meta_data, xtrans[6][6], xtrans_abs[6][6]; +-char cdesc[5], desc[512], make[64], model[64], model2[64], artist[64]; +-float flash_used, canon_ev, iso_speed, shutter, aperture, focal_len; +-time_t timestamp; +-off_t strip_offset, data_offset; +-off_t thumb_offset, meta_offset, profile_offset; +-unsigned shot_order, kodak_cbpp, exif_cfa, unique_id; +-unsigned thumb_length, meta_length, profile_length; +-unsigned thumb_misc, *oprof, fuji_layout, shot_select=0, multi_out=0; +-unsigned tiff_nifds, tiff_samples, tiff_bps, tiff_compress; +-unsigned black, maximum, mix_green, raw_color, zero_is_bad; +-unsigned zero_after_ff, is_raw, dng_version, is_foveon, data_error; +-unsigned tile_width, tile_length, gpsdata[32], load_flags; +-unsigned flip, tiff_flip, filters, colors; +-ushort raw_height, raw_width, height, width, top_margin, left_margin; +-ushort shrink, iheight, iwidth, fuji_width, thumb_width, thumb_height; +-ushort *raw_image, (*image)[4], cblack[4102]; +-ushort white[8][8], curve[0x10000], cr2_slice[3], sraw_mul[4]; +-double pixel_aspect, aber[4]={1,1,1,1}, gamm[6]={ 0.45,4.5,0,0,0,0 }; +-float bright=1, user_mul[4]={0,0,0,0}, threshold=0; +-int mask[8][4]; +-int half_size=0, four_color_rgb=0, document_mode=0, highlight=0; +-int verbose=0, use_auto_wb=0, use_camera_wb=0, use_camera_matrix=1; +-int output_color=1, output_bps=8, output_tiff=0, med_passes=0; +-int no_auto_bright=0; +-unsigned greybox[4] = { 0, 0, UINT_MAX, UINT_MAX }; +-float cam_mul[4], pre_mul[4], cmatrix[3][4], rgb_cam[3][4]; +-const double xyz_rgb[3][3] = { /* XYZ from RGB */ ++ ++const double xyz_rgb[3][3] = { // XYZ from RGB + { 0.412453, 0.357580, 0.180423 }, + { 0.212671, 0.715160, 0.072169 }, + { 0.019334, 0.119193, 0.950227 } }; + const float d65_white[3] = { 0.950456, 1, 1.088754 }; +-int histogram[4][0x2000]; +-void (*write_thumb)(), (*write_fun)(); +-void (*load_raw)(), (*thumb_load_raw)(); +-jmp_buf failure; +- +-struct decode { +- struct decode *branch[2]; +- int leaf; +-} first_decode[2048], *second_decode, *free_decode; +- +-struct tiff_ifd { +- int width, height, bps, comp, phint, offset, flip, samples, bytes; +- int tile_width, tile_length; +-} tiff_ifd[10]; +- +-struct ph1 { +- int format, key_off, tag_21a; +- int black, split_col, black_col, split_row, black_row; +- float tag_210; +-} ph1; + +-#define CLASS ++/* RT: Removed unused structs */ ++#define CLASS DCraw:: + + #define FORC(cnt) for (c=0; c < cnt; c++) + #define FORC3 FORC(3) + #define FORC4 FORC(4) + #define FORCC FORC(colors) + +-#define SQR(x) ((x)*(x)) ++#define SQR(x) rtengine::SQR(x) + #define ABS(x) (((int)(x) ^ ((int)(x) >> 31)) - ((int)(x) >> 31)) +-#define MIN(a,b) ((a) < (b) ? (a) : (b)) +-#define MAX(a,b) ((a) > (b) ? (a) : (b)) +-#define LIM(x,min,max) MAX(min,MIN(x,max)) +-#define ULIM(x,y,z) ((y) < (z) ? LIM(x,y,z) : LIM(x,z,y)) +-#define CLIP(x) LIM(x,0,65535) ++#define MIN(a,b) rtengine::min(a,static_cast(b)) ++#define MAX(a,b) rtengine::max(a,static_cast(b)) ++#define LIM(x,min,max) rtengine::LIM(x,static_cast(min),static_cast(max)) ++#define ULIM(x,y,z) rtengine::ULIM(x,static_cast(y),static_cast(z)) ++#define CLIP(x) rtengine::CLIP(x) + #define SWAP(a,b) { a=a+b; b=a-b; a=a-b; } + + /* +@@ -255,6 +216,7 @@ + + if (filters == 1) return filter[(row+top_margin)&15][(col+left_margin)&15]; + if (filters == 9) return xtrans[(row+6) % 6][(col+6) % 6]; ++ + return FC(row,col); + } + +@@ -297,6 +259,7 @@ + fprintf (stderr,_("Corrupt data near 0x%llx\n"), (INT64) ftello(ifp)); + } + data_error++; ++/*RT Issue 2467 longjmp (failure, 1);*/ + } + + ushort CLASS sget2 (uchar *s) +@@ -370,7 +333,7 @@ + { + if (fread (pixel, 2, count, ifp) < count) derror(); + if ((order == 0x4949) == (ntohs(0x1234) == 0x1234)) +- swab (pixel, pixel, count*2); ++ swab ((char*)pixel, (char*)pixel, count*2); + } + + void CLASS cubic_spline (const int *x_, const int *y_, const int len) +@@ -597,10 +560,10 @@ + return 0; + } + +-unsigned CLASS getbithuff (int nbits, ushort *huff) ++unsigned CLASS getbithuff_t::operator() (int nbits, ushort *huff) + { +- static unsigned bitbuf=0; +- static int vbits=0, reset=0; ++/*RT static unsigned bitbuf=0; */ ++/*RT static int vbits=0, reset=0; */ + unsigned c; + + if (nbits > 25) return 0; +@@ -824,7 +787,8 @@ + + int CLASS ljpeg_start (struct jhead *jh, int info_only) + { +- int c, tag, len; ++ int c, tag; ++ ushort len; + uchar data[0x10000]; + const uchar *dp; + +@@ -1284,14 +1248,14 @@ + int i, nz; + char tail[424]; + +- fseek (ifp, -sizeof tail, SEEK_END); ++ fseek (ifp, -(int)sizeof tail, SEEK_END); + fread (tail, 1, sizeof tail, ifp); + for (nz=i=0; i < sizeof tail; i++) + if (tail[i]) nz++; + return nz > 20; + } + +-void CLASS jpeg_thumb(); ++/*RT void CLASS jpeg_thumb(); */ + + void CLASS ppm_thumb() + { +@@ -1653,10 +1617,10 @@ + } + } + +-unsigned CLASS ph1_bithuff (int nbits, ushort *huff) ++unsigned CLASS ph1_bithuff_t::operator() (int nbits, ushort *huff) + { +- static UINT64 bitbuf=0; +- static int vbits=0; ++/*RT static UINT64 bitbuf=0; */ ++/*RT static int vbits=0; */ + unsigned c; + + if (nbits == -1) +@@ -1731,6 +1695,336 @@ + maximum = 0xfffc - ph1.black; + } + ++void CLASS parse_hasselblad_gain() ++{ ++ /* ++ Reverse-engineer's notes: ++ ++ The Hasselblad gain tag (0x19 in makernotes) is only available in the 3FR format and ++ is applied and removed when Hasselblad Phocus converts it to the FFF format. It's ++ always 0x300000 bytes large regardless of (tested) model, not all space in it is ++ used though. ++ ++ It contains individual calibration information from the factory to tune the sensor ++ performance. ++ ++ There is more calibration data in the tag than what is applied in conversion to FFF, ++ I've only cared to figure out the data which is actually used, but have some leads on ++ remaining info. ++ ++ The format is not equal between all models. Due to lack of 3FR files (harder to get ++ than FFF) only a subset of the models have been reverse-engineered. ++ ++ The header space is 512 bytes and is a mix of 16 and 32 bit values. Offset to blocks ++ are 32 bit values, but all information seems to be encoded in 16 bit values. Many ++ values in the header can be zeroed with no effect on FFF conversion, and their ++ meaning, if any, have not been further investigated. ++ ++ Formats: ++ hdr16[22] = raw width ++ hdr16[23] = raw height ++ hdr32[24] = offset to level corr block ++ Data block format. Seems to differ depending on sensor type. For tested H4D-50 ++ and H3D-31: 10 16 bit signed values per row ++ value 0: a correction factor (k) used on even columns, where the new pixel value is ++ calulated as follows: ++ new_value = old_value + (2 * ((k * (old_value_on_row_above-256)) / 32767) - 2) ++ note the connection to the value on the row above, seems to be some sort of signal ++ leakage correction. ++ value 1: same as value 0 but using old value on row below instead of above ++ value 2-3: same as value 0-1 but for odd columns ++ value 4-9: has some effect if non-zero (probably similar to the others) but not ++ investigated which, as it's seems to be always zero for the tested cameras. ++ ++ hdr32[25] = probably offset to "bad/unreliable pixels" info, always 512 as it starts ++ directly after the header. Not applied in FFF conversion (at least ++ typically). ++ Data block format guess: raw_height packets of ++ ++ ++ hdr32[27] = offset to unknown data (bad colulmns?), of the form: ++ <0> ++ packet: . ++ ++ hdr32[34] = curves offset, seems to be A/D curves (one per channel) on newer models ++ and some sort of a film curve on older. Not applied in FFF conversion. ++ ++ hdr32[36] = flatfield correction, not available in older models. Data format: ++ <1><11 * 2 pad> ++ packet: ++ ++ The header pad is not zeroed and might seem to contain some sort of ++ information, but it makes no difference if set to zero. See ++ hasselblad_correct() how the flatfield is applied. ++ ++ Applied in FFF conversion is levels, flatfield correction, and the bad columns(?) ++ data. A/D curves are surprisingly not applied, maybe pre-applied in hardware and ++ only available as information? Levels are applied before flatfield, further ++ ordering has not been investigated. ++ ++ Not all combinations/models have been tested so there may be gaps. ++ ++ Most clipped pixels in a 3FR is at 65535, but there's also some at 65534. Both ++ are set to 65535 when calibrated, while 65533 is treated as a normal value. In ++ the calibration process smaller values can be scaled to 65534 (which should ++ not be seen as clipped). ++ */ ++ ++ ushort raw_h, count, ch_count, u16; ++ int i, offset; ++ off_t base; ++ ++ base = ftell(ifp); ++ fseek(ifp, 2 * 23, SEEK_CUR); ++ raw_h = get2(); ++ fseek(ifp, 48, SEEK_CUR); ++ offset = get4(); ++ hbd.levels = offset ? base + offset : 0; ++ fseek(ifp, 8, SEEK_CUR); ++ offset = get4(); ++ hbd.unknown1 = offset ? base + offset : 0; ++ fseek(ifp, 32, SEEK_CUR); ++ offset = get4(); ++ hbd.flatfield = offset ? base + offset : 0; ++} ++ ++void CLASS hasselblad_correct() ++{ ++ unsigned col, row; ++ ++ /* ++ ++ This function applies 3FR calibration data. At the time of writing it supports a ++ subset, so here's a todo list: ++ ++ TODO: ++ - Support all gain tag formats ++ - The 0x19 tag varies a bit between models. We don't have parsers for all models. ++ - The reference model used was during inital reverse-engineering was a H4D-50, ++ we probably support the Hasselblads with Kodak 31, 39, 40 and 50 megapixels ++ well, but more work is needed for Kodak 16 and 22, Dalsa 60 and Sony 50. ++ - Apply bad column(?) data (hbd.unknown1) ++ - It was left out in this initial release since the effect is very small. ++ - Apply black(?) data, tag 0x1a and 0x1b is not parsed, it has however marginal ++ effect (at least for shorter exposures) so it's not too important. ++ ++ While there are things to do, the current implementation supports the most ++ important aspects, the faltfield and levels calibrations applied can have strong ++ visible effects. ++ ++ */ ++ ++ if (hbd.levels) { ++ int i; ++ fseek(ifp, hbd.levels, SEEK_SET); ++ /* skip the first set (not used as we don't apply on first/last row), we look at it though to see if ++ the levels format is one that we support (there are other formats on some models which is not ++ supported here) */ ++ short test[10]; ++ for (i = 0; i < 10; i++) test[i] = (short)get2(); ++ if (test[5] == 0 && test[6] == 0 && test[7] == 0 && test[8] == 0 && test[9] == 0) { ++ int corr[4]; ++ ushort *row_above = (ushort *)malloc(sizeof(ushort) * raw_width); // we need to cache row above as we write new values as we go ++ for (col = 0; col < raw_width; col++) row_above[col] = RAW(0,col); ++ for (row = 1; row < raw_height-1; row++) { ++ for (i = 0; i < 4; i++) corr[i] = (short)get2(); ++ fseek(ifp, 6 * 2, SEEK_CUR); ++ for (col = 0; col < raw_width; col++) { ++ unsigned v = RAW(row,col); ++ if (v >= 65534) { ++ v = 65535; ++ } else { ++ if (corr[((col & 1)<<1)+0] && row_above[col] > black) v += 2 * ((corr[((col & 1)<<1)+0] * (row_above[col]-(int)black)) / 32767) - 2; ++ if (corr[((col & 1)<<1)+1] && RAW(row+1,col) > black) v += 2 * ((corr[((col & 1)<<1)+1] * (RAW(row+1,col)-(int)black)) / 32767) - 2; ++ } ++ row_above[col] = RAW(row,col); ++ RAW(row,col) = CLIP(v); ++ } ++ } ++ free(row_above); ++ } ++ } ++ ++ if (hbd.flatfield) { ++ int bw, bh, ffrows, ffcols, i, c; ++ ushort ref[4], ref_max; ++ fseek(ifp, hbd.flatfield, SEEK_SET); ++ get2(); ++ bw = get2(); ++ bh = get2(); ++ ffcols = get2(); ++ ffrows = get2(); ++ fseek(ifp, hbd.flatfield + 16 * 2, SEEK_SET); ++ ++ ushort *ffmap = (ushort *)malloc(sizeof(*ffmap) * 4 * ffcols * ffrows); ++ for (i = 0; i < 4 * ffcols * ffrows; i++) ffmap[i] = get2(); ++ ++ /* Get reference values from center of field. This seems to be what Phocus does too, ++ but haven't cared to figure out exactly at which coordinate */ ++ i = 4 * (ffcols * ffrows / 2 + ffcols / 2); ++ ref[0] = ffmap[i+0]; ++ ref[1] = ffmap[i+1]; ++ ref[3] = ffmap[i+2]; // G2 = index 3 in dcraw, 2 in 3FR ++ ref[2] = ffmap[i+3]; ++ ref_max = 0; ++ FORC4 if (ref[c] > ref_max) ref_max = ref[c]; ++ if (ref_max == 0) ref[0] = ref[1] = ref[2] = ref[3] = ref_max = 10000; ++ ++ /* Convert measured flatfield values to actual multipliers. The measured flatfield ++ can have vignetting which should be normalized, only color cast should be corrected. */ ++ for (i = 0; i < 4 * ffcols * ffrows; i += 4) { ++ double base, min = 65535.0, max = 0; ++ double cur[4]; ++ cur[0] = (double)ffmap[i+0] / ref[0]; ++ cur[1] = (double)ffmap[i+1] / ref[1]; ++ cur[3] = (double)ffmap[i+2] / ref[3]; // G2 index differs in dcraw and 3FR ++ cur[2] = (double)ffmap[i+3] / ref[2]; ++ FORC4 { ++ if (cur[c] < min) min = cur[c]; ++ if (cur[c] > max) max = cur[c]; ++ } ++ if (max == 0) max = 1.0; ++ base = (cur[0]+cur[1]+cur[2]+cur[3])/(max*4); ++ FORC4 cur[c] = cur[c] == 0 ? 1.0 : (base * max) / cur[c]; ++ /* convert to integer multiplier and store back to ffmap, we limit ++ range to 4 (16384*4) which should be fine for flatfield */ ++ FORC4 { ++ cur[c] *= 16384.0; ++ if (cur[c] > 65535.0) cur[c] = 65535.0; ++ ffmap[i+c] = (ushort)cur[c]; ++ } ++ } ++ ++ // of the cameras we've tested we know the exact placement of the flatfield map ++ int row_offset, col_offset; ++ switch (raw_width) { ++ case 8282: // 50 megapixel Kodak ++ row_offset = 21; ++ col_offset = 71; ++ break; ++ default: ++ /* Default case for camera models we've not tested. We center the map, which may ++ not be exactly where it should be but close enough for the smooth flatfield */ ++ row_offset = (raw_height - bh * ffrows) / 2; ++ col_offset = (raw_width - bw * ffcols) / 2; ++ break; ++ } ++ ++ /* ++ Concerning smoothing between blocks in the map Phocus makes it only vertically, ++ probably because it's simpler and faster. Looking at actual flatfield data it seems ++ like it's better to smooth in both directions. Possibly flatfield could be used for ++ correcting tiling on Dalsa sensors (H4D-60) like partly done in Phase One IIQ format, ++ and then sharp edges may be beneficial at least at the tiling seams, but at the time ++ of writing I've had no H4D-60 3FR files to test with to verify that. ++ ++ Meanwhile we do both vertical and horizontal smoothing/blurring. ++ */ ++ ++ /* pre-calculate constants for blurring. We probably should make a more efficient ++ blur than this, but this does not need any buffer and makes nice-looking ++ radial gradients */ ++ ushort *corners_weight = (ushort *)malloc(bw*bh*9*sizeof(*corners_weight)); ++ const char corners_mix[9][4][2] = { { {0,0}, {0,1}, {1,0}, {1,1} }, ++ { {0,1}, {1,1}, {-1,-1}, {-1,-1} }, ++ { {0,1}, {0,2}, {1,1}, {1,2} }, ++ { {1,0}, {1,1}, {-1,-1}, {-1,-1} }, ++ { {1,1}, {-1,-1}, {-1,-1}, {-1,-1} }, ++ { {1,1}, {1,2}, {-1,-1}, {-1,-1} }, ++ { {1,0}, {1,1}, {2,0}, {2,1} }, ++ { {1,1}, {2,1}, {-1,-1}, {-1,-1} }, ++ { {1,1}, {1,2}, {2,1}, {2,2} } }; ++ const ushort corners_shift[9] = { 2, 1, 2, 1, 0, 1, 2, 1, 2 }; ++ for (row = 0; row < bh; row++) { ++ const ushort maxdist = bw < bh ? bw/2-1 : bh/2-1; ++ const unsigned corners[9][2] = {{0,0}, {0,bw/2}, {0,bw-1}, ++ {bh/2,0},{bh/2,bw/2},{bh/2,bw-1}, ++ {bh-1,0},{bh-1,bw/2},{bh-1,bw-1}}; ++ for (col = 0; col < bw; col++) { ++ for (i = 0; i < 9; i++) { ++ ushort dist = (ushort)sqrt(abs(corners[i][0] - row) * abs(corners[i][0] - row) + abs(corners[i][1] - col) * abs(corners[i][1] - col)); ++ ushort weight = dist > maxdist ? 0 : maxdist - dist; ++ corners_weight[9*(row*bw+col)+i] = weight; ++ } ++ } ++ } ++ ++ // apply flatfield ++#pragma omp parallel for ++ for (int row = 0; row < raw_height; row++) { ++ int ffs, cur_ffr, i, c; ++ if (row < row_offset) { ++ cur_ffr = row_offset; ++ ffs = 0; ++ } else if (row >= row_offset + ffrows * bh) { ++ cur_ffr = row_offset + (ffrows-1) * bh; ++ ffs = 4 * ffcols * (ffrows-1); ++ } else { ++ cur_ffr = row_offset + bh * ((row - row_offset) / bh); ++ ffs = 4 * ffcols * ((row - row_offset) / bh); ++ } ++ int next_ffc = 0, cur_ffc = col_offset; ++ int ffc = ffs; ++ ushort *cur[3][3]; // points to local ffmap entries with center at cur[1][1] ++ for (int col = 0; col < raw_width; col++) { ++ if (col == next_ffc) { ++ int rowsub = ffs == 0 ? 0 : ffcols*4; ++ int rowadd = ffs == 4 * ffcols * (ffrows-1) ? 0 : ffcols * 4; ++ int colsub = ffc == ffs ? 0 : 4; ++ int coladd = ffc == ffs + 4 * (ffcols-1) ? 0 : 4; ++ if (col != 0) cur_ffc = next_ffc; ++ else next_ffc += col_offset; ++ next_ffc += bw; ++ ++ cur[0][0] = &ffmap[ffc-rowsub-colsub]; ++ cur[0][1] = &ffmap[ffc-rowsub]; ++ cur[0][2] = &ffmap[ffc-rowsub+coladd]; ++ ++ cur[1][0] = &ffmap[ffc-colsub]; ++ cur[1][1] = &ffmap[ffc]; ++ cur[1][2] = &ffmap[ffc+coladd]; ++ ++ cur[2][0] = &ffmap[ffc+rowadd-colsub]; ++ cur[2][1] = &ffmap[ffc+rowadd]; ++ cur[2][2] = &ffmap[ffc+rowadd+coladd]; ++ ++ ffc += 4; ++ if (ffc == ffs + 4 * ffcols) next_ffc += raw_width; // last col in map, avoid stepping further ++ } ++ unsigned v = RAW(row,col); ++ if (v > black && v < 65535) { ++ c = FC(row,col); ++ unsigned x = col < cur_ffc ? 0 : col - cur_ffc; ++ unsigned y = row < cur_ffr ? 0 : row - cur_ffr; ++ if (x >= bw) x = bw-1; ++ if (y >= bh) y = bh-1; ++ unsigned wsum = 0; ++ unsigned mul = 0; ++ for (i = 0; i < 9; i++) { ++ ushort cw = corners_weight[9*(y*bw+x)+i]; ++ if (cw) { ++ unsigned m = 0; ++ int j; ++ for (j = 0; j < 1 << corners_shift[i]; j++) { ++ int cr = corners_mix[i][j][0], cc = corners_mix[i][j][1]; ++ m += cur[cr][cc][c]; ++ } ++ m >>= corners_shift[i]; ++ mul += m * cw; ++ wsum += cw; ++ } ++ } ++ mul /= wsum; ++ v = black + ((v-black) * mul) / 16384; ++ RAW(row,col) = v > 65535 ? 65535 : v; ++ } ++ } ++ } ++ free(ffmap); ++ free(corners_weight); ++ } ++} ++ + void CLASS hasselblad_load_raw() + { + struct jhead jh; +@@ -1954,10 +2248,10 @@ + maximum = curve[0x3ff]; + } + +-unsigned CLASS pana_bits (int nbits) ++unsigned CLASS pana_bits_t::operator() (int nbits) + { +- static uchar buf[0x4000]; +- static int vbits; ++/*RT static uchar buf[0x4000]; */ ++/*RT static int vbits;*/ + int byte; + + if (!nbits) return vbits=0; +@@ -2246,11 +2540,11 @@ + METHODDEF(boolean) + fill_input_buffer (j_decompress_ptr cinfo) + { +- static uchar jpeg_buffer[4096]; ++/*RT static uchar jpeg_buffer[4096]; */ + size_t nbytes; + + nbytes = fread (jpeg_buffer, 1, 4096, ifp); +- swab (jpeg_buffer, jpeg_buffer, nbytes); ++ swab ((char*)jpeg_buffer, (char*)jpeg_buffer, nbytes); + cinfo->src->next_input_byte = jpeg_buffer; + cinfo->src->bytes_in_buffer = nbytes; + return TRUE; +@@ -2600,10 +2894,9 @@ + maximum = (1 << (thumb_misc & 31)) - 1; + } + +-void CLASS sony_decrypt (unsigned *data, int len, int start, int key) ++void CLASS sony_decrypt_t::operator()(unsigned *data, int len, int start, int key) + { +- static unsigned pad[128], p; +- ++/*RT static unsigned pad[128], p;*/ + if (start) { + for (p=0; p < 4; p++) + pad[p] = key = key * 48828125 + 1; +@@ -2688,11 +2981,13 @@ + bit += 7; + } + for (i=0; i < 16; i++, col+=2) +- RAW(row,col) = curve[pix[i] << 1] >> 2; ++ RAW(row,col) = curve[pix[i] << 1]; // >> 2; RT: disabled shifting to avoid precision loss + col -= col & 1 ? 1:31; + } + } + free (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. + } + + void CLASS samsung_load_raw() +@@ -2988,7 +3283,7 @@ + + void CLASS foveon_decoder (unsigned size, unsigned code) + { +- static unsigned huff[1024]; ++/*RT static unsigned huff[1024];*/ + struct decode *cur; + int i, len; + +@@ -3085,7 +3380,7 @@ + pred[c] += diff[dindex->leaf]; + if (pred[c] >> 16 && ~pred[c] >> 16) derror(); + } +- FORC3 image[row*width+col][c] = pred[c]; ++ FORC3 image[row*width+col][c] = pred[c] < 0 ? 0 : pred[c]; + } + } + } +@@ -3696,6 +3991,8 @@ + if (load_raw == &CLASS phase_one_load_raw || + load_raw == &CLASS phase_one_load_raw_c) + phase_one_correct(); ++ if (load_raw == &CLASS hasselblad_load_raw) // RT ++ hasselblad_correct(); // RT + if (fuji_width) { + for (row=0; row < raw_height-top_margin*2; row++) { + for (col=0; col < fuji_width << !fuji_layout; col++) { +@@ -3711,10 +4008,13 @@ + } + } + } else { +- for (row=0; row < height; row++) +- for (col=0; col < width; col++) ++ ++#pragma omp parallel for ++ for (int row=0; row < height; row++) ++ for (int col=0; col < width; col++) + BAYER2(row,col) = RAW(row+top_margin,col+left_margin); + } ++ + if (mask[0][3] > 0) goto mask_set; + if (load_raw == &CLASS canon_load_raw || + load_raw == &CLASS lossless_jpeg_load_raw) { +@@ -4316,239 +4616,8 @@ + } + } + +-void CLASS lin_interpolate() +-{ +- int code[16][16][32], size=16, *ip, sum[4]; +- int f, c, i, x, y, row, col, shift, color; +- ushort *pix; +- +- if (verbose) fprintf (stderr,_("Bilinear interpolation...\n")); +- if (filters == 9) size = 6; +- border_interpolate(1); +- for (row=0; row < size; row++) +- for (col=0; col < size; col++) { +- ip = code[row][col]+1; +- f = fcol(row,col); +- memset (sum, 0, sizeof sum); +- for (y=-1; y <= 1; y++) +- for (x=-1; x <= 1; x++) { +- shift = (y==0) + (x==0); +- color = fcol(row+y,col+x); +- if (color == f) continue; +- *ip++ = (width*y + x)*4 + color; +- *ip++ = shift; +- *ip++ = color; +- sum[color] += 1 << shift; +- } +- code[row][col][0] = (ip - code[row][col]) / 3; +- FORCC +- if (c != f) { +- *ip++ = c; +- *ip++ = 256 / sum[c]; +- } +- } +- for (row=1; row < height-1; row++) +- for (col=1; col < width-1; col++) { +- pix = image[row*width+col]; +- ip = code[row % size][col % size]; +- memset (sum, 0, sizeof sum); +- for (i=*ip++; i--; ip+=3) +- sum[ip[2]] += pix[ip[0]] << ip[1]; +- for (i=colors; --i; ip+=2) +- pix[ip[0]] = sum[ip[0]] * ip[1] >> 8; +- } +-} +- +-/* +- This algorithm is officially called: +- +- "Interpolation using a Threshold-based variable number of gradients" +- +- described in http://scien.stanford.edu/pages/labsite/1999/psych221/projects/99/tingchen/algodep/vargra.html +- +- I've extended the basic idea to work with non-Bayer filter arrays. +- Gradients are numbered clockwise from NW=0 to W=7. +- */ +-void CLASS vng_interpolate() +-{ +- static const signed char *cp, terms[] = { +- -2,-2,+0,-1,0,0x01, -2,-2,+0,+0,1,0x01, -2,-1,-1,+0,0,0x01, +- -2,-1,+0,-1,0,0x02, -2,-1,+0,+0,0,0x03, -2,-1,+0,+1,1,0x01, +- -2,+0,+0,-1,0,0x06, -2,+0,+0,+0,1,0x02, -2,+0,+0,+1,0,0x03, +- -2,+1,-1,+0,0,0x04, -2,+1,+0,-1,1,0x04, -2,+1,+0,+0,0,0x06, +- -2,+1,+0,+1,0,0x02, -2,+2,+0,+0,1,0x04, -2,+2,+0,+1,0,0x04, +- -1,-2,-1,+0,0,0x80, -1,-2,+0,-1,0,0x01, -1,-2,+1,-1,0,0x01, +- -1,-2,+1,+0,1,0x01, -1,-1,-1,+1,0,0x88, -1,-1,+1,-2,0,0x40, +- -1,-1,+1,-1,0,0x22, -1,-1,+1,+0,0,0x33, -1,-1,+1,+1,1,0x11, +- -1,+0,-1,+2,0,0x08, -1,+0,+0,-1,0,0x44, -1,+0,+0,+1,0,0x11, +- -1,+0,+1,-2,1,0x40, -1,+0,+1,-1,0,0x66, -1,+0,+1,+0,1,0x22, +- -1,+0,+1,+1,0,0x33, -1,+0,+1,+2,1,0x10, -1,+1,+1,-1,1,0x44, +- -1,+1,+1,+0,0,0x66, -1,+1,+1,+1,0,0x22, -1,+1,+1,+2,0,0x10, +- -1,+2,+0,+1,0,0x04, -1,+2,+1,+0,1,0x04, -1,+2,+1,+1,0,0x04, +- +0,-2,+0,+0,1,0x80, +0,-1,+0,+1,1,0x88, +0,-1,+1,-2,0,0x40, +- +0,-1,+1,+0,0,0x11, +0,-1,+2,-2,0,0x40, +0,-1,+2,-1,0,0x20, +- +0,-1,+2,+0,0,0x30, +0,-1,+2,+1,1,0x10, +0,+0,+0,+2,1,0x08, +- +0,+0,+2,-2,1,0x40, +0,+0,+2,-1,0,0x60, +0,+0,+2,+0,1,0x20, +- +0,+0,+2,+1,0,0x30, +0,+0,+2,+2,1,0x10, +0,+1,+1,+0,0,0x44, +- +0,+1,+1,+2,0,0x10, +0,+1,+2,-1,1,0x40, +0,+1,+2,+0,0,0x60, +- +0,+1,+2,+1,0,0x20, +0,+1,+2,+2,0,0x10, +1,-2,+1,+0,0,0x80, +- +1,-1,+1,+1,0,0x88, +1,+0,+1,+2,0,0x08, +1,+0,+2,-1,0,0x40, +- +1,+0,+2,+1,0,0x10 +- }, chood[] = { -1,-1, -1,0, -1,+1, 0,+1, +1,+1, +1,0, +1,-1, 0,-1 }; +- ushort (*brow[5])[4], *pix; +- int prow=8, pcol=2, *ip, *code[16][16], gval[8], gmin, gmax, sum[4]; +- int row, col, x, y, x1, x2, y1, y2, t, weight, grads, color, diag; +- int g, diff, thold, num, c; +- +- lin_interpolate(); +- if (verbose) fprintf (stderr,_("VNG interpolation...\n")); +- +- if (filters == 1) prow = pcol = 16; +- if (filters == 9) prow = pcol = 6; +- ip = (int *) calloc (prow*pcol, 1280); +- merror (ip, "vng_interpolate()"); +- for (row=0; row < prow; row++) /* Precalculate for VNG */ +- for (col=0; col < pcol; col++) { +- code[row][col] = ip; +- for (cp=terms, t=0; t < 64; t++) { +- y1 = *cp++; x1 = *cp++; +- y2 = *cp++; x2 = *cp++; +- weight = *cp++; +- grads = *cp++; +- color = fcol(row+y1,col+x1); +- if (fcol(row+y2,col+x2) != color) continue; +- diag = (fcol(row,col+1) == color && fcol(row+1,col) == color) ? 2:1; +- if (abs(y1-y2) == diag && abs(x1-x2) == diag) continue; +- *ip++ = (y1*width + x1)*4 + color; +- *ip++ = (y2*width + x2)*4 + color; +- *ip++ = weight; +- for (g=0; g < 8; g++) +- if (grads & 1< gval[g]) gmin = gval[g]; +- if (gmax < gval[g]) gmax = gval[g]; +- } +- if (gmax == 0) { +- memcpy (brow[2][col], pix, sizeof *image); +- continue; +- } +- thold = gmin + (gmax >> 1); +- memset (sum, 0, sizeof sum); +- color = fcol(row,col); +- for (num=g=0; g < 8; g++,ip+=2) { /* Average the neighbors */ +- if (gval[g] <= thold) { +- FORCC +- if (c == color && ip[1]) +- sum[c] += (pix[c] + pix[ip[1]]) >> 1; +- else +- sum[c] += pix[ip[0] + c]; +- num++; +- } +- } +- FORCC { /* Save to buffer */ +- t = pix[color]; +- if (c != color) +- t += (sum[c] - sum[color]) / num; +- brow[2][col][c] = CLIP(t); +- } +- } +- if (row > 3) /* Write buffer to image */ +- memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image); +- for (g=0; g < 4; g++) +- brow[(g-1) & 3] = brow[g]; +- } +- memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image); +- memcpy (image[(row-1)*width+2], brow[1]+2, (width-4)*sizeof *image); +- free (brow[4]); +- free (code[0][0]); +-} +- +-/* +- Patterned Pixel Grouping Interpolation by Alain Desbiolles +-*/ +-void CLASS ppg_interpolate() +-{ +- int dir[5] = { 1, width, -1, -width, 1 }; +- int row, col, diff[2], guess[2], c, d, i; +- ushort (*pix)[4]; ++/* RT: delete interpolation functions */ + +- border_interpolate(3); +- if (verbose) fprintf (stderr,_("PPG interpolation...\n")); +- +-/* Fill in the green layer with gradients and pattern recognition: */ +- for (row=3; row < height-3; row++) +- for (col=3+(FC(row,3) & 1), c=FC(row,col); col < width-3; col+=2) { +- pix = image + row*width+col; +- for (i=0; (d=dir[i]) > 0; i++) { +- guess[i] = (pix[-d][1] + pix[0][c] + pix[d][1]) * 2 +- - pix[-2*d][c] - pix[2*d][c]; +- diff[i] = ( ABS(pix[-2*d][c] - pix[ 0][c]) + +- ABS(pix[ 2*d][c] - pix[ 0][c]) + +- ABS(pix[ -d][1] - pix[ d][1]) ) * 3 + +- ( ABS(pix[ 3*d][1] - pix[ d][1]) + +- ABS(pix[-3*d][1] - pix[-d][1]) ) * 2; +- } +- d = dir[i = diff[0] > diff[1]]; +- pix[0][1] = ULIM(guess[i] >> 2, pix[d][1], pix[-d][1]); +- } +-/* Calculate red and blue for each green pixel: */ +- for (row=1; row < height-1; row++) +- for (col=1+(FC(row,2) & 1), c=FC(row,col+1); col < width-1; col+=2) { +- pix = image + row*width+col; +- for (i=0; (d=dir[i]) > 0; c=2-c, i++) +- pix[0][c] = CLIP((pix[-d][c] + pix[d][c] + 2*pix[0][1] +- - pix[-d][1] - pix[d][1]) >> 1); +- } +-/* Calculate blue for red pixels and vice versa: */ +- for (row=1; row < height-1; row++) +- for (col=1+(FC(row,1) & 1), c=2-FC(row,col); col < width-1; col+=2) { +- pix = image + row*width+col; +- for (i=0; (d=dir[i]+dir[i+1]) > 0; i++) { +- diff[i] = ABS(pix[-d][c] - pix[d][c]) + +- ABS(pix[-d][1] - pix[0][1]) + +- ABS(pix[ d][1] - pix[0][1]); +- guess[i] = pix[-d][c] + pix[d][c] + 2*pix[0][1] +- - pix[-d][1] - pix[d][1]; +- } +- if (diff[0] != diff[1]) +- pix[0][c] = CLIP(guess[diff[0] > diff[1]] >> 1); +- else +- pix[0][c] = CLIP((guess[0]+guess[1]) >> 2); +- } +-} + + void CLASS cielab (ushort rgb[3], short lab[3]) + { +@@ -4814,112 +4883,7 @@ + } + #undef fcol + +-/* +- Adaptive Homogeneity-Directed interpolation is based on +- the work of Keigo Hirakawa, Thomas Parks, and Paul Lee. +- */ +-void CLASS ahd_interpolate() +-{ +- int i, j, top, left, row, col, tr, tc, c, d, val, hm[2]; +- static const int dir[4] = { -1, 1, -TS, TS }; +- unsigned ldiff[2][4], abdiff[2][4], leps, abeps; +- ushort (*rgb)[TS][TS][3], (*rix)[3], (*pix)[4]; +- short (*lab)[TS][TS][3], (*lix)[3]; +- char (*homo)[TS][TS], *buffer; +- +- if (verbose) fprintf (stderr,_("AHD interpolation...\n")); +- +- cielab (0,0); +- border_interpolate(5); +- buffer = (char *) malloc (26*TS*TS); +- merror (buffer, "ahd_interpolate()"); +- rgb = (ushort(*)[TS][TS][3]) buffer; +- lab = (short (*)[TS][TS][3])(buffer + 12*TS*TS); +- homo = (char (*)[TS][TS]) (buffer + 24*TS*TS); +- +- for (top=2; top < height-5; top += TS-6) +- for (left=2; left < width-5; left += TS-6) { + +-/* Interpolate green horizontally and vertically: */ +- for (row=top; row < top+TS && row < height-2; row++) { +- col = left + (FC(row,left) & 1); +- for (c = FC(row,col); col < left+TS && col < width-2; col+=2) { +- pix = image + row*width+col; +- val = ((pix[-1][1] + pix[0][c] + pix[1][1]) * 2 +- - pix[-2][c] - pix[2][c]) >> 2; +- rgb[0][row-top][col-left][1] = ULIM(val,pix[-1][1],pix[1][1]); +- val = ((pix[-width][1] + pix[0][c] + pix[width][1]) * 2 +- - pix[-2*width][c] - pix[2*width][c]) >> 2; +- rgb[1][row-top][col-left][1] = ULIM(val,pix[-width][1],pix[width][1]); +- } +- } +-/* Interpolate red and blue, and convert to CIELab: */ +- for (d=0; d < 2; d++) +- for (row=top+1; row < top+TS-1 && row < height-3; row++) +- for (col=left+1; col < left+TS-1 && col < width-3; col++) { +- pix = image + row*width+col; +- rix = &rgb[d][row-top][col-left]; +- lix = &lab[d][row-top][col-left]; +- if ((c = 2 - FC(row,col)) == 1) { +- c = FC(row+1,col); +- val = pix[0][1] + (( pix[-1][2-c] + pix[1][2-c] +- - rix[-1][1] - rix[1][1] ) >> 1); +- rix[0][2-c] = CLIP(val); +- val = pix[0][1] + (( pix[-width][c] + pix[width][c] +- - rix[-TS][1] - rix[TS][1] ) >> 1); +- } else +- val = rix[0][1] + (( pix[-width-1][c] + pix[-width+1][c] +- + pix[+width-1][c] + pix[+width+1][c] +- - rix[-TS-1][1] - rix[-TS+1][1] +- - rix[+TS-1][1] - rix[+TS+1][1] + 1) >> 2); +- rix[0][c] = CLIP(val); +- c = FC(row,col); +- rix[0][c] = pix[0][c]; +- cielab (rix[0],lix[0]); +- } +-/* Build homogeneity maps from the CIELab images: */ +- memset (homo, 0, 2*TS*TS); +- for (row=top+2; row < top+TS-2 && row < height-4; row++) { +- tr = row-top; +- for (col=left+2; col < left+TS-2 && col < width-4; col++) { +- tc = col-left; +- for (d=0; d < 2; d++) { +- lix = &lab[d][tr][tc]; +- for (i=0; i < 4; i++) { +- ldiff[d][i] = ABS(lix[0][0]-lix[dir[i]][0]); +- abdiff[d][i] = SQR(lix[0][1]-lix[dir[i]][1]) +- + SQR(lix[0][2]-lix[dir[i]][2]); +- } +- } +- leps = MIN(MAX(ldiff[0][0],ldiff[0][1]), +- MAX(ldiff[1][2],ldiff[1][3])); +- abeps = MIN(MAX(abdiff[0][0],abdiff[0][1]), +- MAX(abdiff[1][2],abdiff[1][3])); +- for (d=0; d < 2; d++) +- for (i=0; i < 4; i++) +- if (ldiff[d][i] <= leps && abdiff[d][i] <= abeps) +- homo[d][tr][tc]++; +- } +- } +-/* Combine the most homogenous pixels for the final result: */ +- for (row=top+3; row < top+TS-3 && row < height-5; row++) { +- tr = row-top; +- for (col=left+3; col < left+TS-3 && col < width-5; col++) { +- tc = col-left; +- for (d=0; d < 2; d++) +- for (hm[d]=0, i=tr-1; i <= tr+1; i++) +- for (j=tc-1; j <= tc+1; j++) +- hm[d] += homo[d][i][j]; +- if (hm[0] != hm[1]) +- FORC3 image[row*width+col][c] = rgb[hm[1] > hm[0]][tr][tc][c]; +- else +- FORC3 image[row*width+col][c] = +- (rgb[0][tr][tc][c] + rgb[1][tr][tc][c]) >> 1; +- } +- } +- } +- free (buffer); +-} + #undef TS + + void CLASS median_filter() +@@ -5089,7 +5053,7 @@ + } + } + +-int CLASS parse_tiff_ifd (int base); ++/*RT int CLASS parse_tiff_ifd (int base);*/ + + void CLASS parse_makernote (int base, int uptag) + { +@@ -5246,12 +5210,16 @@ + cam_mul[2] = get4() << 2; + } + } +- if (tag == 0x15 && type == 2 && is_raw) ++ //if (tag == 0x15 && type == 2 && is_raw) ++ if (tag == 0x15 && type == 2 && is_raw && strstr(model, "Hasselblad ") != model) // RT: don't overwrite already parsed Hasselblad model + fread (model, 64, 1, ifp); + if (strstr(make,"PENTAX")) { + if (tag == 0x1b) tag = 0x1018; + if (tag == 0x1c) tag = 0x1017; + } ++ if (tag == 0x19 && !strcmp(make,"Hasselblad") && len == 0x300000) { // RT ++ parse_hasselblad_gain(); // RT ++ } // RT + if (tag == 0x1d) + while ((c = fgetc(ifp)) && c != EOF) + serial = serial*10 + (isdigit(c) ? c - '0' : c % 10); +@@ -5613,28 +5581,31 @@ + } + } + +-void CLASS parse_minolta (int base); +-int CLASS parse_tiff (int base); ++/*RT void CLASS parse_minolta (int base); */ ++/*RT int CLASS parse_tiff (int base);*/ + + int CLASS parse_tiff_ifd (int base) + { + unsigned entries, tag, type, len, plen=16, save; +- int ifd, use_cm=0, cfa, i, j, c, ima_len=0; ++ int ifd, use_cm=0, cfa, i, j, c, ima_len=0,cm_D65=0; + char software[64], *cbuf, *cp; + uchar cfa_pat[16], cfa_pc[] = { 0,1,2,3 }, tab[256]; +- double cc[4][4], cm[4][3], cam_xyz[4][3], num; ++ double cc[2][4][4], cm[2][4][3], cam_xyz[4][3], num; + double ab[]={ 1,1,1,1 }, asn[] = { 0,0,0,0 }, xyz[] = { 1,1,1 }; + unsigned sony_curve[] = { 0,0,0,0,0,4095 }; + unsigned *buf, sony_offset=0, sony_length=0, sony_key=0; + struct jhead jh; +- FILE *sfp; ++/*RT*/ IMFILE *sfp; + + if (tiff_nifds >= sizeof tiff_ifd / sizeof tiff_ifd[0]) + return 1; + ifd = tiff_nifds++; + for (j=0; j < 4; j++) + for (i=0; i < 4; i++) +- cc[j][i] = i == j; ++ { ++ cc[0][j][i] = i == j; ++ cc[1][j][i] = i == j; ++ } + entries = get2(); + if (entries > 512) return 1; + while (entries--) { +@@ -5702,7 +5673,8 @@ + fgets (make, 64, ifp); + break; + case 272: /* Model */ +- fgets (model, 64, ifp); ++ if (strstr(model, "Hasselblad ") != model) // RT: if Hasselblad, only parse the first model name (otherwise it can change from say Hasselblad CFV-50 to Hasselblad CW (ie the camera body model, not the back model which we are interested in) ++ fgets (model, 64, ifp); + break; + case 280: /* Panasonic RW2 offset */ + if (type != 4) break; +@@ -5762,6 +5734,9 @@ + case 315: /* Artist */ + fread (artist, 64, 1, ifp); + break; ++ case 317: /* Predictor */ ++ tiff_ifd[ifd].predictor = getint(type); ++ break; + case 322: /* TileWidth */ + tiff_ifd[ifd].tile_width = getint(type); + break; +@@ -5777,6 +5752,9 @@ + is_raw = 5; + } + break; ++ case 325: /* TileByteCounts */ ++ tiff_ifd[ifd].bytes = len > 1 ? ftell(ifp) : get4(); ++ break; + case 330: /* SubIFDs */ + if (!strcmp(model,"DSLR-A100") && tiff_ifd[ifd].width == 3872) { + load_raw = &CLASS sony_arw_load_raw; +@@ -5790,6 +5768,9 @@ + fseek (ifp, i+4, SEEK_SET); + } + break; ++ case 339: ++ tiff_ifd[ifd].sample_format = getint(type); ++ break; + case 400: + strcpy (make, "Sarnoff"); + maximum = 0xfff; +@@ -5971,6 +5952,9 @@ + if (!make[0]) strcpy (make, "DNG"); + is_raw = 1; + break; ++ case 50708: /* UniqueCameraModel */ ++ fgets (model3, 64, ifp); ++ break; + case 50710: /* CFAPlaneColor */ + if (filters == 9) break; + if (len > 4) len = 4; +@@ -6002,12 +5986,21 @@ + case 61450: + cblack[4] = cblack[5] = MIN(sqrt(len),64); + case 50714: /* BlackLevel */ +- if (!(cblack[4] * cblack[5])) +- cblack[4] = cblack[5] = 1; +- FORC (cblack[4] * cblack[5]) +- cblack[6+c] = getreal(type); +- black = 0; +- break; ++ if(cblack[4] * cblack[5] == 0) { ++ int dblack[] = { 0,0,0,0 }; ++ black = getreal(type); ++ if ((unsigned)(filters+1) < 1000) break; ++ dblack[0] = dblack[1] = dblack[2] = dblack[3] = black; ++ if (colors == 3) ++ filters |= ((filters >> 2 & 0x22222222) | ++ (filters << 2 & 0x88888888)) & filters << 1; ++ FORC4 cblack[filters >> (c << 1) & 3] = dblack[c]; ++ } else { ++ FORC (cblack[4] * cblack[5]) ++ cblack[6+c] = getreal(type); ++ } ++ black = 0; ++ break; + case 50715: /* BlackLevelDeltaH */ + case 50716: /* BlackLevelDeltaV */ + for (num=i=0; i < len; i++) +@@ -6024,13 +6017,13 @@ + case 50721: /* ColorMatrix1 */ + case 50722: /* ColorMatrix2 */ + FORCC for (j=0; j < 3; j++) +- cm[c][j] = getreal(type); ++ cm[tag-50721][c][j] = getreal(type); + use_cm = 1; + break; + case 50723: /* CameraCalibration1 */ + case 50724: /* CameraCalibration2 */ + for (i=0; i < colors; i++) +- FORCC cc[i][c] = getreal(type); ++ FORCC cc[tag-50723][i][c] = getreal(type); + break; + case 50727: /* AnalogBalance */ + FORCC ab[c] = getreal(type); +@@ -6053,6 +6046,11 @@ + case 50752: + read_shorts (cr2_slice, 3); + break; ++ case 50778: ++ case 50779: ++ if( get2() == 21 ) ++ cm_D65 = (tag-50778); ++ break; + case 50829: /* ActiveArea */ + top_margin = getint(type); + left_margin = getint(type); +@@ -6085,21 +6083,24 @@ + fread (buf, sony_length, 1, ifp); + sony_decrypt (buf, sony_length/4, 1, sony_key); + sfp = ifp; +- if ((ifp = tmpfile())) { +- fwrite (buf, sony_length, 1, ifp); +- fseek (ifp, 0, SEEK_SET); +- parse_tiff_ifd (-sony_offset); +- fclose (ifp); +- } ++/*RT*/ ifp = fopen (buf, sony_length); ++// if ((ifp = tmpfile())) { ++// fwrite (buf, sony_length, 1, ifp); ++// fseek (ifp, 0, SEEK_SET); ++ parse_tiff_ifd (-sony_offset); ++// fclose (ifp); ++// } ++ if(ifp) ++ fclose(ifp); + ifp = sfp; + free (buf); + } + for (i=0; i < colors; i++) +- FORCC cc[i][c] *= ab[i]; ++ FORCC cc[cm_D65][i][c] *= ab[i]; + if (use_cm) { + FORCC for (i=0; i < 3; i++) + for (cam_xyz[c][i]=j=0; j < colors; j++) +- cam_xyz[c][i] += cc[c][j] * cm[j][i] * xyz[i]; ++ cam_xyz[c][i] += cc[cm_D65][c][j] * cm[cm_D65][j][i] * xyz[i]; + cam_xyz_coeff (cmatrix, cam_xyz); + } + if (asn[0]) { +@@ -6107,13 +6108,14 @@ + FORCC cam_mul[c] = 1 / asn[c]; + } + if (!use_cm) +- FORCC pre_mul[c] /= cc[c][c]; ++ FORCC pre_mul[c] /= cc[cm_D65][c][c]; + return 0; + } + + int CLASS parse_tiff (int base) + { + int doff; ++ /*RT*/ if (exif_base == -1) exif_base = base; + + fseek (ifp, base, SEEK_SET); + order = get2(); +@@ -6191,7 +6193,7 @@ + case 8: load_raw = &CLASS eight_bit_load_raw; break; + case 12: if (tiff_ifd[raw].phint == 2) + load_flags = 6; +- load_raw = &CLASS packed_load_raw; break; ++ load_raw = &CLASS packed_load_raw; break; + case 14: load_flags = 0; + case 16: load_raw = &CLASS unpacked_load_raw; + if (!strncmp(make,"OLYMPUS",7) && +@@ -6230,6 +6232,7 @@ + case 32803: load_raw = &CLASS kodak_65000_load_raw; + } + case 32867: case 34892: break; ++ case 8: break; + default: is_raw = 0; + } + if (!dng_version) +@@ -6315,7 +6318,7 @@ + { + const char *file, *ext; + char *jname, *jfile, *jext; +- FILE *save=ifp; ++/*RT*/ IMFILE *save=ifp; + + ext = strrchr (ifname, '.'); + file = strrchr (ifname, '/'); +@@ -6337,13 +6340,14 @@ + } else + while (isdigit(*--jext)) { + if (*jext != '9') { +- (*jext)++; ++ (*jext)++; + break; + } + *jext = '0'; + } + if (strcmp (jname, ifname)) { +- if ((ifp = fopen (jname, "rb"))) { ++/*RT*/ if ((ifp = fopen (jname))) { ++// if ((ifp = fopen (jname, "rb"))) { + if (verbose) + fprintf (stderr,_("Reading metadata from %s ...\n"), jname); + parse_tiff (12); +@@ -6620,6 +6624,7 @@ + load_raw = ph1.format < 3 ? + &CLASS phase_one_load_raw : &CLASS phase_one_load_raw_c; + maximum = 0xffff; ++ tiff_bps = 16; + strcpy (make, "Phase One"); + if (model[0]) return; + switch (raw_height) { +@@ -6688,7 +6693,11 @@ + order = get2(); + hlen = get4(); + if (get4() == 0x48454150) /* "HEAP" */ ++/*RT*/ { ++/*RT*/ ciff_base = save+hlen; ++/*RT*/ ciff_len = len-hlen; + parse_ciff (save+hlen, len-hlen, 0); ++/*RT*/ } + if (parse_tiff (save+6)) apply_tiff(); + fseek (ifp, save+len, SEEK_SET); + } +@@ -6960,7 +6969,8 @@ + { + static const struct { + const char *prefix; +- short black, maximum, trans[12]; ++ unsigned short black, maximum; // RT: Change to UShort ++ short trans[12]; + } table[] = { + { "AgfaPhoto DC-833m", 0, 0, /* DJC */ + { 11438,-3762,-1115,-2409,9914,2497,-1227,2295,5300 } }, +@@ -7919,6 +7929,33 @@ + } + break; + } ++ if (load_raw == &CLASS sony_arw2_load_raw) { // RT: arw2 scale fix ++ black <<= 2; ++ tiff_bps += 2; ++ } ++ { /* Check for RawTherapee table overrides and extensions */ ++ int black_level, white_level; ++ short trans[12]; ++ if (dcraw_coeff_overrides(make, model, iso_speed, trans, &black_level, &white_level)) { ++ if (black_level > -1) { ++ black = (ushort)black_level; ++ } ++ if (white_level > -1) { ++ maximum = (ushort)white_level; ++ if(tiff_bps > 0) { ++ unsigned compare = ((uint64_t)1 << tiff_bps) - 1; // use uint64_t to avoid overflow if tiff_bps == 32 ++ while(maximum > compare) ++ maximum >>= 1; ++ } ++ } ++ if (trans[0]) { ++ for (j=0; j < 12; j++) { ++ ((double *)cam_xyz)[j] = trans[j] / 10000.0; ++ } ++ cam_xyz_coeff (rgb_cam,cam_xyz); ++ } ++ } ++ } + } + + void CLASS simple_coeff (int index) +@@ -8229,7 +8266,7 @@ + tiff_flip = flip = filters = UINT_MAX; /* unknown */ + raw_height = raw_width = fuji_width = fuji_layout = cr2_slice[0] = 0; + maximum = height = width = top_margin = left_margin = 0; +- cdesc[0] = desc[0] = artist[0] = make[0] = model[0] = model2[0] = 0; ++ cdesc[0] = desc[0] = artist[0] = make[0] = model[0] = model2[0] = model3[0] = 0; + iso_speed = shutter = aperture = focal_len = unique_id = 0; + tiff_nifds = 0; + memset (tiff_ifd, 0, sizeof tiff_ifd); +@@ -8261,13 +8298,20 @@ + fread (head, 1, 32, ifp); + fseek (ifp, 0, SEEK_END); + flen = fsize = ftell(ifp); +- if ((cp = (char *) memmem (head, 32, "MMMM", 4)) || +- (cp = (char *) memmem (head, 32, "IIII", 4))) { ++ /*RT*/ if (fsize<100000) { ++ is_raw = 0; ++ return; ++ } ++ /* RT: changed string constant */ ++ if ((cp = (char *) memmem (head, 32, (char*)"MMMM", 4)) || ++ (cp = (char *) memmem (head, 32, (char*)"IIII", 4))) { + parse_phase_one (cp-head); + if (cp-head && parse_tiff(0)) apply_tiff(); + } else if (order == 0x4949 || order == 0x4d4d) { + if (!memcmp (head+6,"HEAPCCDR",8)) { + data_offset = hlen; ++/*RT*/ ciff_base = hlen; ++/*RT*/ ciff_len = fsize - hlen; + parse_ciff (hlen, flen-hlen, 0); + load_raw = &CLASS canon_load_raw; + } else if (parse_tiff(0)) apply_tiff(); +@@ -8313,6 +8357,7 @@ + fseek (ifp, 100+28*(shot_select > 0), SEEK_SET); + parse_tiff (data_offset = get4()); + parse_tiff (thumb_offset+12); ++/*RT*/ exif_base = thumb_offset+12; + apply_tiff(); + } else if (!memcmp (head,"RIFF",4)) { + fseek (ifp, 0, SEEK_SET); +@@ -8426,9 +8471,10 @@ + if (make[0] == 0) parse_smal (0, flen); + if (make[0] == 0) { + parse_jpeg(0); +- if (!(strncmp(model,"ov",2) && strncmp(model,"RP_OV",5)) && +- !fseek (ifp, -6404096, SEEK_END) && +- fread (head, 1, 32, ifp) && !strcmp(head,"BRCMn")) { ++ //RT fix for the use of fseek below ++ if (!(strncmp(model,"ov",2) && strncmp(model,"RP_OV",5))) { ++ fseek (ifp, -6404096, SEEK_END); ++ if (fread (head, 1, 32, ifp) && !strcmp(head,"BRCMn")) { + strcpy (make, "OmniVision"); + data_offset = ftell(ifp) + 0x8000-32; + width = raw_width; +@@ -8437,6 +8483,7 @@ + filters = 0x16161616; + } else is_raw = 0; + } ++ } + + for (i=0; i < sizeof corp / sizeof *corp; i++) + if (strcasestr (make, corp[i])) /* Simplify company names */ +@@ -8468,7 +8515,7 @@ + if (height == 3136 && width == 4864) /* Pentax K20D and Samsung GX20 */ + { height = 3124; width = 4688; filters = 0x16161616; } + if (width == 4352 && (!strcmp(model,"K-r") || !strcmp(model,"K-x"))) +- { width = 4309; filters = 0x16161616; } ++/*RT*/ { width = 4308; filters = 0x16161616; } + if (width >= 4960 && !strncmp(model,"K-5",3)) + { left_margin = 10; width = 4950; filters = 0x16161616; } + if (width == 4736 && !strcmp(model,"K-7")) +@@ -8487,6 +8534,7 @@ + switch (tiff_compress) { + case 1: load_raw = &CLASS packed_dng_load_raw; break; + case 7: load_raw = &CLASS lossless_dng_load_raw; break; ++ case 8: load_raw = &CLASS deflate_dng_load_raw; break; + case 34892: load_raw = &CLASS lossy_dng_load_raw; break; + default: load_raw = 0; + } +@@ -8541,6 +8589,7 @@ + if (height > width) pixel_aspect = 2; + filters = 0; + simple_coeff(0); ++ adobe_coeff (make, model); + } else if (!strcmp(make,"Canon") && tiff_bps == 15) { + switch (width) { + case 3344: width -= 66; +@@ -8846,24 +8895,53 @@ + if (load_raw == &CLASS lossless_jpeg_load_raw) + load_raw = &CLASS hasselblad_load_raw; + if (raw_width == 7262) { ++ if (!strcmp(model, "H3D")) strcpy(model, "H3D-39"); // RT + height = 5444; + width = 7248; + top_margin = 4; + left_margin = 7; + filters = 0x61616161; +- } else if (raw_width == 7410 || raw_width == 8282) { +- height -= 84; +- width -= 82; ++ } else if (raw_width == 7410) { ++ if (!strcmp(model, "H4D")) strcpy(model, "H4D-40"); // RT ++ height = 5502; ++ width = 7328; + top_margin = 4; + left_margin = 41; + filters = 0x61616161; ++ } else if (raw_width == 6542) { // RT, H3D-31, H3DII-31, H4D-31 ++ if (!strcmp(model, "H3D")) strcpy(model, "H3D-31"); ++ if (!strcmp(model, "H4D")) strcpy(model, "H4D-31"); ++ height = 4904; ++ width = 6524; ++ top_margin = 4; ++ left_margin = 8; ++ } else if (raw_width == 8282) { // RT, H3DII-50, H3DII-50MS, CFV-50, H4D-50 ++ if (!strcmp(model, "H3D")) strcpy(model, "H3DII-50"); ++ if (!strcmp(model, "H4D")) strcpy(model, "H4D-50"); ++ height = 6152; ++ width = 8196; ++ top_margin = 4; ++ left_margin = 44; ++ } else if (raw_width == 8374) { // RT, CFV-50c, H5D-50c, "H5D-50c MS", "H5D-200c MS" ++ if (!strcmp(model, "H5D")) strcpy(model, "H5D-50c"); ++ if (!strcmp(model, "CFV-2")) strcpy(model, "CFV-50c"); ++ height = 6208; ++ width = 8280; ++ top_margin = 96; ++ left_margin = 48; + } else if (raw_width == 9044) { + height = 6716; + width = 8964; + top_margin = 8; + left_margin = 40; +- black += load_flags = 256; +- maximum = 0x8101; ++ // RT: removed black level / maximum adjustment, as it does not seem to be correct when there are clipped highlights. Tested with Hasselblad H4D-60. ++ //black += load_flags = 256; ++ //maximum = 0x8101; ++ } else if (raw_width == 4096) { // RT: CF-22 etc ++ if (!strcmp(model, "H3D")) strcpy(model, "H3D-22"); ++ else if (strstr(model3, "Hasselblad ") == model3) strcpy(model, &model3[11]); ++ if (strstr(model3, "ixpressCF132")) strcpy(model, "CF-22"); // ixpressCF132 / CF132 is same as CF-22, we use the simpler name ++ else if (strstr(model3, "Hasselblad96")) strcpy(model, "CFV"); // popularly called CFV-16 + } else if (raw_width == 4090) { + strcpy (model, "V96C"); + height -= (top_margin = 6); +@@ -8921,6 +8999,7 @@ + filters = 0x16161616; + } + } else if (!strcmp(make,"Leica") || !strcmp(make,"Panasonic")) { ++ if(raw_width > 0) { // avoid divide by zero + if ((flen - data_offset) / (raw_width*8/7) == raw_height) + load_raw = &CLASS panasonic_load_raw; + if (!load_raw) { +@@ -8938,6 +9017,7 @@ + } + filters = 0x01010101 * (uchar) "\x94\x61\x49\x16" + [((filters-1) ^ (left_margin & 1) ^ (top_margin << 1)) & 3]; ++ } + } else if (!strcmp(model,"C770UZ")) { + height = 1718; + width = 2304; +@@ -9155,6 +9235,14 @@ + memcpy (rgb_cam, cmatrix, sizeof cmatrix); + raw_color = 0; + } ++ 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)) ++ adobe_coeff (make, model); + if (raw_color) adobe_coeff (make, model); + if (load_raw == &CLASS kodak_radc_load_raw) + if (raw_color) adobe_coeff ("Apple","Quicktake"); +@@ -9169,9 +9257,9 @@ + if (raw_width < width ) raw_width = width; + } + if (!tiff_bps) tiff_bps = 12; +- if (!maximum) maximum = (1 << tiff_bps) - 1; ++ if (!maximum) maximum = ((uint64_t)1 << tiff_bps) - 1; // use uint64_t to avoid overflow if tiff_bps == 32 + if (!load_raw || height < 22 || width < 22 || +- tiff_bps > 16 || tiff_samples > 6 || colors > 4) ++ tiff_samples > 6 || colors > 4) + is_raw = 0; + #ifdef NO_JASPER + if (load_raw == &CLASS redcine_load_raw) { +@@ -9250,194 +9338,249 @@ + } + #endif + +-void CLASS convert_to_rgb() +-{ +- int row, col, c, i, j, k; +- ushort *img; +- float out[3], out_cam[3][4]; +- double num, inverse[3][3]; +- static const double xyzd50_srgb[3][3] = +- { { 0.436083, 0.385083, 0.143055 }, +- { 0.222507, 0.716888, 0.060608 }, +- { 0.013930, 0.097097, 0.714022 } }; +- static const double rgb_rgb[3][3] = +- { { 1,0,0 }, { 0,1,0 }, { 0,0,1 } }; +- static const double adobe_rgb[3][3] = +- { { 0.715146, 0.284856, 0.000000 }, +- { 0.000000, 1.000000, 0.000000 }, +- { 0.000000, 0.041166, 0.958839 } }; +- static const double wide_rgb[3][3] = +- { { 0.593087, 0.404710, 0.002206 }, +- { 0.095413, 0.843149, 0.061439 }, +- { 0.011621, 0.069091, 0.919288 } }; +- static const double prophoto_rgb[3][3] = +- { { 0.529317, 0.330092, 0.140588 }, +- { 0.098368, 0.873465, 0.028169 }, +- { 0.016879, 0.117663, 0.865457 } }; +- static const double (*out_rgb[])[3] = +- { rgb_rgb, adobe_rgb, wide_rgb, prophoto_rgb, xyz_rgb }; +- static const char *name[] = +- { "sRGB", "Adobe RGB (1998)", "WideGamut D65", "ProPhoto D65", "XYZ" }; +- static const unsigned phead[] = +- { 1024, 0, 0x2100000, 0x6d6e7472, 0x52474220, 0x58595a20, 0, 0, 0, +- 0x61637370, 0, 0, 0x6e6f6e65, 0, 0, 0, 0, 0xf6d6, 0x10000, 0xd32d }; +- unsigned pbody[] = +- { 10, 0x63707274, 0, 36, /* cprt */ +- 0x64657363, 0, 40, /* desc */ +- 0x77747074, 0, 20, /* wtpt */ +- 0x626b7074, 0, 20, /* bkpt */ +- 0x72545243, 0, 14, /* rTRC */ +- 0x67545243, 0, 14, /* gTRC */ +- 0x62545243, 0, 14, /* bTRC */ +- 0x7258595a, 0, 20, /* rXYZ */ +- 0x6758595a, 0, 20, /* gXYZ */ +- 0x6258595a, 0, 20 }; /* bXYZ */ +- static const unsigned pwhite[] = { 0xf351, 0x10000, 0x116cc }; +- unsigned pcurve[] = { 0x63757276, 0, 1, 0x1000000 }; +- +- gamma_curve (gamm[0], gamm[1], 0, 0); +- memcpy (out_cam, rgb_cam, sizeof out_cam); +- raw_color |= colors == 1 || document_mode || +- output_color < 1 || output_color > 5; +- if (!raw_color) { +- oprof = (unsigned *) calloc (phead[0], 1); +- merror (oprof, "convert_to_rgb()"); +- memcpy (oprof, phead, sizeof phead); +- if (output_color == 5) oprof[4] = oprof[5]; +- oprof[0] = 132 + 12*pbody[0]; +- for (i=0; i < pbody[0]; i++) { +- oprof[oprof[0]/4] = i ? (i > 1 ? 0x58595a20 : 0x64657363) : 0x74657874; +- pbody[i*3+2] = oprof[0]; +- oprof[0] += (pbody[i*3+3] + 3) & -4; +- } +- memcpy (oprof+32, pbody, sizeof pbody); +- oprof[pbody[5]/4+2] = strlen(name[output_color-1]) + 1; +- memcpy ((char *)oprof+pbody[8]+8, pwhite, sizeof pwhite); +- pcurve[3] = (short)(256/gamm[5]+0.5) << 16; +- for (i=4; i < 7; i++) +- memcpy ((char *)oprof+pbody[i*3+2], pcurve, sizeof pcurve); +- pseudoinverse ((double (*)[3]) out_rgb[output_color-1], inverse, 3); +- for (i=0; i < 3; i++) +- for (j=0; j < 3; j++) { +- for (num = k=0; k < 3; k++) +- num += xyzd50_srgb[i][k] * inverse[j][k]; +- oprof[pbody[j*3+23]/4+i+2] = num * 0x10000 + 0.5; +- } +- for (i=0; i < phead[0]/4; i++) +- oprof[i] = htonl(oprof[i]); +- strcpy ((char *)oprof+pbody[2]+8, "auto-generated by dcraw"); +- strcpy ((char *)oprof+pbody[5]+12, name[output_color-1]); +- for (i=0; i < 3; i++) +- for (j=0; j < colors; j++) +- for (out_cam[i][j] = k=0; k < 3; k++) +- out_cam[i][j] += out_rgb[output_color-1][i][k] * rgb_cam[k][j]; ++/* RT: DNG Float */ ++ ++#include ++#include ++ ++static void decodeFPDeltaRow(Bytef * src, Bytef * dst, size_t tileWidth, size_t realTileWidth, int bytesps, int factor) { ++ // DecodeDeltaBytes ++ for (size_t col = factor; col < realTileWidth*bytesps; ++col) { ++ src[col] += src[col - factor]; ++ } ++ // Reorder bytes into the image ++ // 16 and 32-bit versions depend on local architecture, 24-bit does not ++ if (bytesps == 3) { ++ for (size_t col = 0; col < tileWidth; ++col) { ++ dst[col*3] = src[col]; ++ dst[col*3 + 1] = src[col + realTileWidth]; ++ dst[col*3 + 2] = src[col + realTileWidth*2]; ++ } ++ } else { ++ union X { uint32_t x; uint8_t c; }; ++ if (((union X){1}).c) { ++ for (size_t col = 0; col < tileWidth; ++col) { ++ for (size_t byte = 0; byte < bytesps; ++byte) ++ dst[col*bytesps + byte] = src[col + realTileWidth*(bytesps-byte-1)]; // Little endian ++ } ++ } else { ++ for (size_t col = 0; col < tileWidth; ++col) { ++ for (size_t byte = 0; byte < bytesps; ++byte) ++ dst[col*bytesps + byte] = src[col + realTileWidth*byte]; ++ } ++ } ++ } ++ ++} ++ ++// From DNG SDK dng_utils.h ++static inline uint32_t DNG_HalfToFloat(uint16_t halfValue) { ++ int32_t sign = (halfValue >> 15) & 0x00000001; ++ int32_t exponent = (halfValue >> 10) & 0x0000001f; ++ int32_t mantissa = halfValue & 0x000003ff; ++ if (exponent == 0) { ++ if (mantissa == 0) { ++ // Plus or minus zero ++ return (uint32_t) (sign << 31); ++ } else { ++ // Denormalized number -- renormalize it ++ while (!(mantissa & 0x00000400)) { ++ mantissa <<= 1; ++ exponent -= 1; ++ } ++ exponent += 1; ++ mantissa &= ~0x00000400; ++ } ++ } else if (exponent == 31) { ++ if (mantissa == 0) { ++ // Positive or negative infinity, convert to maximum (16 bit) values. ++ return (uint32_t) ((sign << 31) | ((0x1eL + 127 - 15) << 23) | (0x3ffL << 13)); ++ } else { ++ // Nan -- Just set to zero. ++ return 0; ++ } + } +- if (verbose) +- fprintf (stderr, raw_color ? _("Building histograms...\n") : +- _("Converting to %s colorspace...\n"), name[output_color-1]); ++ // Normalized number ++ exponent += (127 - 15); ++ mantissa <<= 13; ++ // Assemble sign, exponent and mantissa. ++ return (uint32_t) ((sign << 31) | (exponent << 23) | mantissa); ++} + +- memset (histogram, 0, sizeof histogram); +- for (img=image[0], row=0; row < height; row++) +- for (col=0; col < width; col++, img+=4) { +- if (!raw_color) { +- out[0] = out[1] = out[2] = 0; +- FORCC { +- out[0] += out_cam[0][c] * img[c]; +- out[1] += out_cam[1][c] * img[c]; +- out[2] += out_cam[2][c] * img[c]; +- } +- FORC3 img[c] = CLIP((int) out[c]); +- } +- else if (document_mode) +- img[0] = img[fcol(row,col)]; +- FORCC histogram[c][img[c] >> 3]++; +- } +- if (colors == 4 && output_color) colors = 3; +- if (document_mode && filters) colors = 1; +-} +- +-void CLASS fuji_rotate() +-{ +- int i, row, col; +- double step; +- float r, c, fr, fc; +- unsigned ur, uc; +- ushort wide, high, (*img)[4], (*pix)[4]; ++static inline uint32_t DNG_FP24ToFloat(const uint8_t * input) { ++ int32_t sign = (input [0] >> 7) & 0x01; ++ int32_t exponent = (input [0] ) & 0x7F; ++ int32_t mantissa = (((int32_t) input [1]) << 8) | input[2]; ++ if (exponent == 0) { ++ if (mantissa == 0) { ++ // Plus or minus zero ++ return (uint32_t) (sign << 31); ++ } else { ++ // Denormalized number -- renormalize it ++ while (!(mantissa & 0x00010000)) { ++ mantissa <<= 1; ++ exponent -= 1; ++ } ++ exponent += 1; ++ mantissa &= ~0x00010000; ++ } ++ } else if (exponent == 127) { ++ if (mantissa == 0) { ++ // Positive or negative infinity, convert to maximum (24 bit) values. ++ return (uint32_t) ((sign << 31) | ((0x7eL + 128 - 64) << 23) | (0xffffL << 7)); ++ } else { ++ // Nan -- Just set to zero. ++ return 0; ++ } ++ } ++ // Normalized number ++ exponent += (128 - 64); ++ mantissa <<= 7; ++ // Assemble sign, exponent and mantissa. ++ return (uint32_t) ((sign << 31) | (exponent << 23) | mantissa); ++} + +- if (!fuji_width) return; +- if (verbose) +- fprintf (stderr,_("Rotating image 45 degrees...\n")); +- fuji_width = (fuji_width - 1 + shrink) >> shrink; +- step = sqrt(0.5); +- wide = fuji_width / step; +- high = (height - fuji_width) / step; +- img = (ushort (*)[4]) calloc (high, wide*sizeof *img); +- merror (img, "fuji_rotate()"); +- +- for (row=0; row < high; row++) +- for (col=0; col < wide; col++) { +- ur = r = fuji_width + (row-col)*step; +- uc = c = (row+col)*step; +- if (ur > height-2 || uc > width-2) continue; +- fr = r - ur; +- fc = c - uc; +- pix = image + ur*width + uc; +- for (i=0; i < colors; i++) +- img[row*wide+col][i] = +- (pix[ 0][i]*(1-fc) + pix[ 1][i]*fc) * (1-fr) + +- (pix[width][i]*(1-fc) + pix[width+1][i]*fc) * fr; +- } +- free (image); +- width = wide; +- height = high; +- image = img; +- fuji_width = 0; ++static void expandFloats(Bytef * dst, int tileWidth, int bytesps) { ++ if (bytesps == 2) { ++ uint16_t * dst16 = (uint16_t *) dst; ++ uint32_t * dst32 = (uint32_t *) dst; ++ for (int index = tileWidth - 1; index >= 0; --index) { ++ dst32[index] = DNG_HalfToFloat(dst16[index]); ++ } ++ } else if (bytesps == 3) { ++ uint8_t * dst8 = ((uint8_t *) dst) + (tileWidth - 1) * 3; ++ uint32_t * dst32 = (uint32_t *) dst; ++ for (int index = tileWidth - 1; index >= 0; --index, dst8 -= 3) { ++ dst32[index] = DNG_FP24ToFloat(dst8); ++ } ++ } + } + +-void CLASS stretch() ++static void copyFloatDataToInt(float * src, ushort * dst, size_t size, float max) { ++ bool negative = false, nan = false; ++ ++#ifdef _OPENMP ++#pragma omp parallel for ++#endif ++ for (size_t i = 0; i < size; ++i) { ++ if (src[i] < 0.0f) { ++ negative = true; ++ src[i] = 0.0f; ++ } else if (std::isnan(src[i])) { ++ nan = true; ++ src[i] = max; ++ } ++ // Copy the data to the integer buffer to build the thumbnail ++ dst[i] = (ushort)src[i]; ++ } ++ if (negative) ++ fprintf(stderr, "DNG Float: Negative data found in input file\n"); ++ if (nan) ++ fprintf(stderr, "DNG Float: NaN data found in input file\n"); ++} ++ ++void CLASS deflate_dng_load_raw() { ++ struct tiff_ifd * ifd = &tiff_ifd[0]; ++ while (ifd < &tiff_ifd[tiff_nifds] && ifd->offset != data_offset) ++ifd; ++ if (ifd == &tiff_ifd[tiff_nifds]) { ++ fprintf(stderr, "DNG Deflate: Raw image not found???\n"); ++ return; ++ } ++ ++ int predFactor; ++ switch(ifd->predictor) { ++ case 3: predFactor = 1; break; ++ case 34894: predFactor = 2; break; ++ case 34895: predFactor = 4; break; ++ default: predFactor = 0; break; ++ } ++ ++ if (ifd->sample_format == 3) { // Floating point data ++ float_raw_image = new float[raw_width * raw_height]; ++ ++#ifdef _OPENMP ++#pragma omp parallel for ++#endif ++ for (size_t i = 0; i < raw_width * raw_height; ++i) ++ float_raw_image[i] = 0.0f; ++ } ++ ++ // NOTE: This reader is based on the official DNG SDK from Adobe. ++ // It assumes tiles without subtiles, but the standard does not say that ++ // subtiles or strips couldn't be used. ++ if (tile_length < INT_MAX) { ++ size_t tilesWide = (raw_width + tile_width - 1) / tile_width; ++ size_t tilesHigh = (raw_height + tile_length - 1) / tile_length; ++ size_t tileCount = tilesWide * tilesHigh; ++ //fprintf(stderr, "%dx%d tiles, %d total\n", tilesWide, tilesHigh, tileCount); ++ size_t tileOffsets[tileCount]; ++ for (size_t t = 0; t < tileCount; ++t) { ++ tileOffsets[t] = get4(); ++ } ++ size_t tileBytes[tileCount]; ++ uLongf maxCompressed = 0; ++ if (tileCount == 1) { ++ tileBytes[0] = maxCompressed = ifd->bytes; ++ } else { ++ fseek(ifp, ifd->bytes, SEEK_SET); ++ for (size_t t = 0; t < tileCount; ++t) { ++ tileBytes[t] = get4(); ++ //fprintf(stderr, "Tile %d at %d, size %d\n", t, tileOffsets[t], tileBytes[t]); ++ if (maxCompressed < tileBytes[t]) ++ maxCompressed = tileBytes[t]; ++ } ++ } ++ uLongf dstLen = tile_width * tile_length * 4; ++ ++#ifdef _OPENMP ++#pragma omp parallel ++#endif + { +- ushort newdim, (*img)[4], *pix0, *pix1; +- int row, col, c; +- double rc, frac; ++ Bytef * cBuffer = new Bytef[maxCompressed]; ++ Bytef * uBuffer = new Bytef[dstLen]; + +- if (pixel_aspect == 1) return; +- if (verbose) fprintf (stderr,_("Stretching the image...\n")); +- if (pixel_aspect < 1) { +- newdim = height / pixel_aspect + 0.5; +- img = (ushort (*)[4]) calloc (width, newdim*sizeof *img); +- merror (img, "stretch()"); +- for (rc=row=0; row < newdim; row++, rc+=pixel_aspect) { +- frac = rc - (c = rc); +- pix0 = pix1 = image[c*width]; +- if (c+1 < height) pix1 += width*4; +- for (col=0; col < width; col++, pix0+=4, pix1+=4) +- FORCC img[row*width+col][c] = pix0[c]*(1-frac) + pix1[c]*frac + 0.5; ++#ifdef _OPENMP ++#pragma omp for collapse(2) 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); ++#pragma omp critical ++{ ++ 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 ++ } ++ } + } +- height = newdim; +- } else { +- newdim = width * pixel_aspect + 0.5; +- img = (ushort (*)[4]) calloc (height, newdim*sizeof *img); +- merror (img, "stretch()"); +- for (rc=col=0; col < newdim; col++, rc+=1/pixel_aspect) { +- frac = rc - (c = rc); +- pix0 = pix1 = image[c]; +- if (c+1 < width) pix1 += 4; +- for (row=0; row < height; row++, pix0+=width*4, pix1+=width*4) +- FORCC img[row*newdim+col][c] = pix0[c]*(1-frac) + pix1[c]*frac + 0.5; +- } +- width = newdim; +- } +- free (image); +- image = img; +-} +- +-int CLASS flip_index (int row, int col) +-{ +- if (flip & 4) SWAP(row,col); +- if (flip & 2) row = iheight - 1 - row; +- if (flip & 1) col = iwidth - 1 - col; +- return row * iwidth + col; ++ ++ delete [] cBuffer; ++ delete [] uBuffer; + } ++ } ++ ++ if (ifd->sample_format == 3) { // Floating point data ++ copyFloatDataToInt(float_raw_image, raw_image, raw_width*raw_height, maximum); ++ } ++} ++ ++/* RT: removed unused functions */ + + struct tiff_tag { + ushort tag, type; +@@ -9461,590 +9604,11 @@ + char desc[512], make[64], model[64], soft[32], date[20], artist[64]; + }; + +-void CLASS tiff_set (ushort *ntag, +- ushort tag, ushort type, int count, int val) +-{ +- struct tiff_tag *tt; +- int c; +- +- tt = (struct tiff_tag *)(ntag+1) + (*ntag)++; +- tt->tag = tag; +- tt->type = type; +- tt->count = count; +- if (type < 3 && count <= 4) +- FORC(4) tt->val.c[c] = val >> (c << 3); +- else if (type == 3 && count <= 2) +- FORC(2) tt->val.s[c] = val >> (c << 4); +- else tt->val.i = val; +-} +- +-#define TOFF(ptr) ((char *)(&(ptr)) - (char *)th) +- +-void CLASS tiff_head (struct tiff_hdr *th, int full) +-{ +- int c, psize=0; +- struct tm *t; +- +- memset (th, 0, sizeof *th); +- th->order = htonl(0x4d4d4949) >> 16; +- th->magic = 42; +- th->ifd = 10; +- if (full) { +- tiff_set (&th->ntag, 254, 4, 1, 0); +- tiff_set (&th->ntag, 256, 4, 1, width); +- tiff_set (&th->ntag, 257, 4, 1, height); +- tiff_set (&th->ntag, 258, 3, colors, output_bps); +- if (colors > 2) +- th->tag[th->ntag-1].val.i = TOFF(th->bps); +- FORC4 th->bps[c] = output_bps; +- tiff_set (&th->ntag, 259, 3, 1, 1); +- tiff_set (&th->ntag, 262, 3, 1, 1 + (colors > 1)); +- } +- tiff_set (&th->ntag, 270, 2, 512, TOFF(th->desc)); +- tiff_set (&th->ntag, 271, 2, 64, TOFF(th->make)); +- tiff_set (&th->ntag, 272, 2, 64, TOFF(th->model)); +- if (full) { +- if (oprof) psize = ntohl(oprof[0]); +- tiff_set (&th->ntag, 273, 4, 1, sizeof *th + psize); +- tiff_set (&th->ntag, 277, 3, 1, colors); +- tiff_set (&th->ntag, 278, 4, 1, height); +- tiff_set (&th->ntag, 279, 4, 1, height*width*colors*output_bps/8); +- } else +- tiff_set (&th->ntag, 274, 3, 1, "12435867"[flip]-'0'); +- tiff_set (&th->ntag, 282, 5, 1, TOFF(th->rat[0])); +- tiff_set (&th->ntag, 283, 5, 1, TOFF(th->rat[2])); +- tiff_set (&th->ntag, 284, 3, 1, 1); +- tiff_set (&th->ntag, 296, 3, 1, 2); +- tiff_set (&th->ntag, 305, 2, 32, TOFF(th->soft)); +- tiff_set (&th->ntag, 306, 2, 20, TOFF(th->date)); +- tiff_set (&th->ntag, 315, 2, 64, TOFF(th->artist)); +- tiff_set (&th->ntag, 34665, 4, 1, TOFF(th->nexif)); +- if (psize) tiff_set (&th->ntag, 34675, 7, psize, sizeof *th); +- tiff_set (&th->nexif, 33434, 5, 1, TOFF(th->rat[4])); +- tiff_set (&th->nexif, 33437, 5, 1, TOFF(th->rat[6])); +- tiff_set (&th->nexif, 34855, 3, 1, iso_speed); +- tiff_set (&th->nexif, 37386, 5, 1, TOFF(th->rat[8])); +- if (gpsdata[1]) { +- tiff_set (&th->ntag, 34853, 4, 1, TOFF(th->ngps)); +- tiff_set (&th->ngps, 0, 1, 4, 0x202); +- tiff_set (&th->ngps, 1, 2, 2, gpsdata[29]); +- tiff_set (&th->ngps, 2, 5, 3, TOFF(th->gps[0])); +- tiff_set (&th->ngps, 3, 2, 2, gpsdata[30]); +- tiff_set (&th->ngps, 4, 5, 3, TOFF(th->gps[6])); +- tiff_set (&th->ngps, 5, 1, 1, gpsdata[31]); +- tiff_set (&th->ngps, 6, 5, 1, TOFF(th->gps[18])); +- tiff_set (&th->ngps, 7, 5, 3, TOFF(th->gps[12])); +- tiff_set (&th->ngps, 18, 2, 12, TOFF(th->gps[20])); +- tiff_set (&th->ngps, 29, 2, 12, TOFF(th->gps[23])); +- memcpy (th->gps, gpsdata, sizeof th->gps); +- } +- th->rat[0] = th->rat[2] = 300; +- th->rat[1] = th->rat[3] = 1; +- FORC(6) th->rat[4+c] = 1000000; +- th->rat[4] *= shutter; +- th->rat[6] *= aperture; +- th->rat[8] *= focal_len; +- strncpy (th->desc, desc, 512); +- strncpy (th->make, make, 64); +- strncpy (th->model, model, 64); +- strcpy (th->soft, "dcraw v"DCRAW_VERSION); +- t = localtime (×tamp); +- sprintf (th->date, "%04d:%02d:%02d %02d:%02d:%02d", +- t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec); +- strncpy (th->artist, artist, 64); +-} +- +-void CLASS jpeg_thumb() +-{ +- char *thumb; +- ushort exif[5]; +- struct tiff_hdr th; +- +- thumb = (char *) malloc (thumb_length); +- merror (thumb, "jpeg_thumb()"); +- fread (thumb, 1, thumb_length, ifp); +- fputc (0xff, ofp); +- fputc (0xd8, ofp); +- if (strcmp (thumb+6, "Exif")) { +- memcpy (exif, "\xff\xe1 Exif\0\0", 10); +- exif[1] = htons (8 + sizeof th); +- fwrite (exif, 1, sizeof exif, ofp); +- tiff_head (&th, 0); +- fwrite (&th, 1, sizeof th, ofp); +- } +- fwrite (thumb+2, 1, thumb_length-2, ofp); +- free (thumb); +-} +- +-void CLASS write_ppm_tiff() +-{ +- struct tiff_hdr th; +- uchar *ppm; +- ushort *ppm2; +- int c, row, col, soff, rstep, cstep; +- int perc, val, total, white=0x2000; +- +- perc = width * height * 0.01; /* 99th percentile white level */ +- if (fuji_width) perc /= 2; +- if (!((highlight & ~2) || no_auto_bright)) +- for (white=c=0; c < colors; c++) { +- for (val=0x2000, total=0; --val > 32; ) +- if ((total += histogram[c][val]) > perc) break; +- if (white < val) white = val; +- } +- gamma_curve (gamm[0], gamm[1], 2, (white << 3)/bright); +- iheight = height; +- iwidth = width; +- if (flip & 4) SWAP(height,width); +- ppm = (uchar *) calloc (width, colors*output_bps/8); +- ppm2 = (ushort *) ppm; +- merror (ppm, "write_ppm_tiff()"); +- if (output_tiff) { +- tiff_head (&th, 1); +- fwrite (&th, sizeof th, 1, ofp); +- if (oprof) +- fwrite (oprof, ntohl(oprof[0]), 1, ofp); +- } else if (colors > 3) +- fprintf (ofp, +- "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n", +- width, height, colors, (1 << output_bps)-1, cdesc); +- else +- fprintf (ofp, "P%d\n%d %d\n%d\n", +- colors/2+5, width, height, (1 << output_bps)-1); +- soff = flip_index (0, 0); +- cstep = flip_index (0, 1) - soff; +- rstep = flip_index (1, 0) - flip_index (0, width); +- for (row=0; row < height; row++, soff += rstep) { +- for (col=0; col < width; col++, soff += cstep) +- if (output_bps == 8) +- FORCC ppm [col*colors+c] = curve[image[soff][c]] >> 8; +- else FORCC ppm2[col*colors+c] = curve[image[soff][c]]; +- if (output_bps == 16 && !output_tiff && htons(0x55aa) != 0x55aa) +- swab (ppm2, ppm2, width*colors*2); +- fwrite (ppm, colors*output_bps/8, width, ofp); +- } +- free (ppm); +-} +- +-int CLASS main (int argc, const char **argv) +-{ +- int arg, status=0, quality, i, c; +- int timestamp_only=0, thumbnail_only=0, identify_only=0; +- int user_qual=-1, user_black=-1, user_sat=-1, user_flip=-1; +- int use_fuji_rotate=1, write_to_stdout=0, read_from_stdin=0; +- const char *sp, *bpfile=0, *dark_frame=0, *write_ext; +- char opm, opt, *ofname, *cp; +- struct utimbuf ut; +-#ifndef NO_LCMS +- const char *cam_profile=0, *out_profile=0; +-#endif +- +-#ifndef LOCALTIME +- putenv ((char *) "TZ=UTC"); +-#endif +-#ifdef LOCALEDIR +- setlocale (LC_CTYPE, ""); +- setlocale (LC_MESSAGES, ""); +- bindtextdomain ("dcraw", LOCALEDIR); +- textdomain ("dcraw"); +-#endif +- +- if (argc == 1) { +- printf(_("\nRaw photo decoder \"dcraw\" v%s"), DCRAW_VERSION); +- printf(_("\nby Dave Coffin, dcoffin a cybercom o net\n")); +- printf(_("\nUsage: %s [OPTION]... [FILE]...\n\n"), argv[0]); +- puts(_("-v Print verbose messages")); +- puts(_("-c Write image data to standard output")); +- puts(_("-e Extract embedded thumbnail image")); +- puts(_("-i Identify files without decoding them")); +- puts(_("-i -v Identify files and show metadata")); +- puts(_("-z Change file dates to camera timestamp")); +- puts(_("-w Use camera white balance, if possible")); +- puts(_("-a Average the whole image for white balance")); +- puts(_("-A Average a grey box for white balance")); +- puts(_("-r Set custom white balance")); +- puts(_("+M/-M Use/don't use an embedded color matrix")); +- puts(_("-C Correct chromatic aberration")); +- puts(_("-P Fix the dead pixels listed in this file")); +- puts(_("-K Subtract dark frame (16-bit raw PGM)")); +- puts(_("-k Set the darkness level")); +- puts(_("-S Set the saturation level")); +- puts(_("-n Set threshold for wavelet denoising")); +- puts(_("-H [0-9] Highlight mode (0=clip, 1=unclip, 2=blend, 3+=rebuild)")); +- puts(_("-t [0-7] Flip image (0=none, 3=180, 5=90CCW, 6=90CW)")); +- puts(_("-o [0-5] Output colorspace (raw,sRGB,Adobe,Wide,ProPhoto,XYZ)")); +-#ifndef NO_LCMS +- puts(_("-o Apply output ICC profile from file")); +- puts(_("-p Apply camera ICC profile from file or \"embed\"")); +-#endif +- puts(_("-d Document mode (no color, no interpolation)")); +- puts(_("-D Document mode without scaling (totally raw)")); +- puts(_("-j Don't stretch or rotate raw pixels")); +- puts(_("-W Don't automatically brighten the image")); +- puts(_("-b Adjust brightness (default = 1.0)")); +- puts(_("-g

Set custom gamma curve (default = 2.222 4.5)")); +- puts(_("-q [0-3] Set the interpolation quality")); +- puts(_("-h Half-size color image (twice as fast as \"-q 0\")")); +- puts(_("-f Interpolate RGGB as four colors")); +- puts(_("-m Apply a 3x3 median filter to R-G and B-G")); +- puts(_("-s [0..N-1] Select one raw image or \"all\" from each file")); +- puts(_("-6 Write 16-bit instead of 8-bit")); +- puts(_("-4 Linear 16-bit, same as \"-6 -W -g 1 1\"")); +- puts(_("-T Write TIFF instead of PPM")); +- puts(""); +- return 1; +- } +- argv[argc] = ""; +- for (arg=1; (((opm = argv[arg][0]) - 2) | 2) == '+'; ) { +- opt = argv[arg++][1]; +- if ((cp = (char *) strchr (sp="nbrkStqmHACg", opt))) +- for (i=0; i < "114111111422"[cp-sp]-'0'; i++) +- if (!isdigit(argv[arg+i][0])) { +- fprintf (stderr,_("Non-numeric argument to \"-%c\"\n"), opt); +- return 1; +- } +- switch (opt) { +- case 'n': threshold = atof(argv[arg++]); break; +- case 'b': bright = atof(argv[arg++]); break; +- case 'r': +- FORC4 user_mul[c] = atof(argv[arg++]); break; +- case 'C': aber[0] = 1 / atof(argv[arg++]); +- aber[2] = 1 / atof(argv[arg++]); break; +- case 'g': gamm[0] = atof(argv[arg++]); +- gamm[1] = atof(argv[arg++]); +- if (gamm[0]) gamm[0] = 1/gamm[0]; break; +- case 'k': user_black = atoi(argv[arg++]); break; +- case 'S': user_sat = atoi(argv[arg++]); break; +- case 't': user_flip = atoi(argv[arg++]); break; +- case 'q': user_qual = atoi(argv[arg++]); break; +- case 'm': med_passes = atoi(argv[arg++]); break; +- case 'H': highlight = atoi(argv[arg++]); break; +- case 's': +- shot_select = abs(atoi(argv[arg])); +- multi_out = !strcmp(argv[arg++],"all"); +- break; +- case 'o': +- if (isdigit(argv[arg][0]) && !argv[arg][1]) +- output_color = atoi(argv[arg++]); +-#ifndef NO_LCMS +- else out_profile = argv[arg++]; +- break; +- case 'p': cam_profile = argv[arg++]; +-#endif +- break; +- case 'P': bpfile = argv[arg++]; break; +- case 'K': dark_frame = argv[arg++]; break; +- case 'z': timestamp_only = 1; break; +- case 'e': thumbnail_only = 1; break; +- case 'i': identify_only = 1; break; +- case 'c': write_to_stdout = 1; break; +- case 'v': verbose = 1; break; +- case 'h': half_size = 1; break; +- case 'f': four_color_rgb = 1; break; +- case 'A': FORC4 greybox[c] = atoi(argv[arg++]); +- case 'a': use_auto_wb = 1; break; +- case 'w': use_camera_wb = 1; break; +- case 'M': use_camera_matrix = 3 * (opm == '+'); break; +- case 'I': read_from_stdin = 1; break; +- case 'E': document_mode++; +- case 'D': document_mode++; +- case 'd': document_mode++; +- case 'j': use_fuji_rotate = 0; break; +- case 'W': no_auto_bright = 1; break; +- case 'T': output_tiff = 1; break; +- case '4': gamm[0] = gamm[1] = +- no_auto_bright = 1; +- case '6': output_bps = 16; break; +- default: +- fprintf (stderr,_("Unknown option \"-%c\".\n"), opt); +- return 1; +- } +- } +- if (arg == argc) { +- fprintf (stderr,_("No files to process.\n")); +- return 1; +- } +- if (write_to_stdout) { +- if (isatty(1)) { +- fprintf (stderr,_("Will not write an image to the terminal!\n")); +- return 1; +- } +-#if defined(WIN32) || defined(DJGPP) || defined(__CYGWIN__) +- if (setmode(1,O_BINARY) < 0) { +- perror ("setmode()"); +- return 1; +- } +-#endif +- } +- for ( ; arg < argc; arg++) { +- status = 1; +- raw_image = 0; +- image = 0; +- oprof = 0; +- meta_data = ofname = 0; +- ofp = stdout; +- if (setjmp (failure)) { +- if (fileno(ifp) > 2) fclose(ifp); +- if (fileno(ofp) > 2) fclose(ofp); +- status = 1; +- goto cleanup; +- } +- ifname = argv[arg]; +- if (!(ifp = fopen (ifname, "rb"))) { +- perror (ifname); +- continue; +- } +- status = (identify(),!is_raw); +- if (user_flip >= 0) +- flip = user_flip; +- switch ((flip+3600) % 360) { +- case 270: flip = 5; break; +- case 180: flip = 3; break; +- case 90: flip = 6; +- } +- if (timestamp_only) { +- if ((status = !timestamp)) +- fprintf (stderr,_("%s has no timestamp.\n"), ifname); +- else if (identify_only) +- printf ("%10ld%10d %s\n", (long) timestamp, shot_order, ifname); +- else { +- if (verbose) +- fprintf (stderr,_("%s time set to %d.\n"), ifname, (int) timestamp); +- ut.actime = ut.modtime = timestamp; +- utime (ifname, &ut); +- } +- goto next; +- } +- write_fun = &CLASS write_ppm_tiff; +- if (thumbnail_only) { +- if ((status = !thumb_offset)) { +- fprintf (stderr,_("%s has no thumbnail.\n"), ifname); +- goto next; +- } else if (thumb_load_raw) { +- load_raw = thumb_load_raw; +- data_offset = thumb_offset; +- height = thumb_height; +- width = thumb_width; +- filters = 0; +- colors = 3; +- } else { +- fseek (ifp, thumb_offset, SEEK_SET); +- write_fun = write_thumb; +- goto thumbnail; +- } +- } +- if (load_raw == &CLASS kodak_ycbcr_load_raw) { +- height += height & 1; +- width += width & 1; +- } +- if (identify_only && verbose && make[0]) { +- printf (_("\nFilename: %s\n"), ifname); +- printf (_("Timestamp: %s"), ctime(×tamp)); +- printf (_("Camera: %s %s\n"), make, model); +- if (artist[0]) +- printf (_("Owner: %s\n"), artist); +- if (dng_version) { +- printf (_("DNG Version: ")); +- for (i=24; i >= 0; i -= 8) +- printf ("%d%c", dng_version >> i & 255, i ? '.':'\n'); +- } +- printf (_("ISO speed: %d\n"), (int) iso_speed); +- printf (_("Shutter: ")); +- if (shutter > 0 && shutter < 1) +- shutter = (printf ("1/"), 1 / shutter); +- printf (_("%0.1f sec\n"), shutter); +- printf (_("Aperture: f/%0.1f\n"), aperture); +- printf (_("Focal length: %0.1f mm\n"), focal_len); +- printf (_("Embedded ICC profile: %s\n"), profile_length ? _("yes"):_("no")); +- printf (_("Number of raw images: %d\n"), is_raw); +- if (pixel_aspect != 1) +- printf (_("Pixel Aspect Ratio: %0.6f\n"), pixel_aspect); +- if (thumb_offset) +- printf (_("Thumb size: %4d x %d\n"), thumb_width, thumb_height); +- printf (_("Full size: %4d x %d\n"), raw_width, raw_height); +- } else if (!is_raw) +- fprintf (stderr,_("Cannot decode file %s\n"), ifname); +- if (!is_raw) goto next; +- shrink = filters && (half_size || (!identify_only && +- (threshold || aber[0] != 1 || aber[2] != 1))); +- iheight = (height + shrink) >> shrink; +- iwidth = (width + shrink) >> shrink; +- if (identify_only) { +- if (verbose) { +- if (document_mode == 3) { +- top_margin = left_margin = fuji_width = 0; +- height = raw_height; +- width = raw_width; +- } +- iheight = (height + shrink) >> shrink; +- iwidth = (width + shrink) >> shrink; +- if (use_fuji_rotate) { +- if (fuji_width) { +- fuji_width = (fuji_width - 1 + shrink) >> shrink; +- iwidth = fuji_width / sqrt(0.5); +- iheight = (iheight - fuji_width) / sqrt(0.5); +- } else { +- if (pixel_aspect < 1) iheight = iheight / pixel_aspect + 0.5; +- if (pixel_aspect > 1) iwidth = iwidth * pixel_aspect + 0.5; +- } +- } +- if (flip & 4) +- SWAP(iheight,iwidth); +- printf (_("Image size: %4d x %d\n"), width, height); +- printf (_("Output size: %4d x %d\n"), iwidth, iheight); +- printf (_("Raw colors: %d"), colors); +- if (filters) { +- int fhigh = 2, fwide = 2; +- if ((filters ^ (filters >> 8)) & 0xff) fhigh = 4; +- if ((filters ^ (filters >> 16)) & 0xffff) fhigh = 8; +- if (filters == 1) fhigh = fwide = 16; +- if (filters == 9) fhigh = fwide = 6; +- printf (_("\nFilter pattern: ")); +- for (i=0; i < fhigh; i++) +- for (c = i && putchar('/') && 0; c < fwide; c++) +- putchar (cdesc[fcol(i,c)]); +- } +- printf (_("\nDaylight multipliers:")); +- FORCC printf (" %f", pre_mul[c]); +- if (cam_mul[0] > 0) { +- printf (_("\nCamera multipliers:")); +- FORC4 printf (" %f", cam_mul[c]); +- } +- putchar ('\n'); +- } else +- printf (_("%s is a %s %s image.\n"), ifname, make, model); +-next: +- fclose(ifp); +- continue; +- } +- if (meta_length) { +- meta_data = (char *) malloc (meta_length); +- merror (meta_data, "main()"); +- } +- if (filters || colors == 1) { +- raw_image = (ushort *) calloc ((raw_height+7), raw_width*2); +- merror (raw_image, "main()"); +- } else { +- image = (ushort (*)[4]) calloc (iheight, iwidth*sizeof *image); +- merror (image, "main()"); +- } +- if (verbose) +- fprintf (stderr,_("Loading %s %s image from %s ...\n"), +- make, model, ifname); +- if (shot_select >= is_raw) +- fprintf (stderr,_("%s: \"-s %d\" requests a nonexistent image!\n"), +- ifname, shot_select); +- fseeko (ifp, data_offset, SEEK_SET); +- if (raw_image && read_from_stdin) +- fread (raw_image, 2, raw_height*raw_width, stdin); +- else (*load_raw)(); +- if (document_mode == 3) { +- top_margin = left_margin = fuji_width = 0; +- height = raw_height; +- width = raw_width; +- } +- iheight = (height + shrink) >> shrink; +- iwidth = (width + shrink) >> shrink; +- if (raw_image) { +- image = (ushort (*)[4]) calloc (iheight, iwidth*sizeof *image); +- merror (image, "main()"); +- crop_masked_pixels(); +- free (raw_image); +- } +- if (zero_is_bad) remove_zeroes(); +- bad_pixels (bpfile); +- if (dark_frame) subtract (dark_frame); +- quality = 2 + !fuji_width; +- if (user_qual >= 0) quality = user_qual; +- i = cblack[3]; +- FORC3 if (i > cblack[c]) i = cblack[c]; +- FORC4 cblack[c] -= i; +- black += i; +- i = cblack[6]; +- FORC (cblack[4] * cblack[5]) +- if (i > cblack[6+c]) i = cblack[6+c]; +- FORC (cblack[4] * cblack[5]) +- cblack[6+c] -= i; +- black += i; +- if (user_black >= 0) black = user_black; +- FORC4 cblack[c] += black; +- if (user_sat > 0) maximum = user_sat; +-#ifdef COLORCHECK +- colorcheck(); +-#endif +- if (is_foveon) { +- if (document_mode || load_raw == &CLASS foveon_dp_load_raw) { +- for (i=0; i < height*width*4; i++) +- if ((short) image[0][i] < 0) image[0][i] = 0; +- } else foveon_interpolate(); +- } else if (document_mode < 2) +- scale_colors(); +- pre_interpolate(); +- if (filters && !document_mode) { +- if (quality == 0) +- lin_interpolate(); +- else if (quality == 1 || colors > 3) +- vng_interpolate(); +- else if (quality == 2 && filters > 1000) +- ppg_interpolate(); +- else if (filters == 9) +- xtrans_interpolate (quality*2-3); +- else +- ahd_interpolate(); +- } +- if (mix_green) +- for (colors=3, i=0; i < height*width; i++) +- image[i][1] = (image[i][1] + image[i][3]) >> 1; +- if (!is_foveon && colors == 3) median_filter(); +- if (!is_foveon && highlight == 2) blend_highlights(); +- if (!is_foveon && highlight > 2) recover_highlights(); +- if (use_fuji_rotate) fuji_rotate(); +-#ifndef NO_LCMS +- if (cam_profile) apply_profile (cam_profile, out_profile); +-#endif +- convert_to_rgb(); +- if (use_fuji_rotate) stretch(); +-thumbnail: +- if (write_fun == &CLASS jpeg_thumb) +- write_ext = ".jpg"; +- else if (output_tiff && write_fun == &CLASS write_ppm_tiff) +- write_ext = ".tiff"; +- else +- write_ext = ".pgm\0.ppm\0.ppm\0.pam" + colors*5-5; +- ofname = (char *) malloc (strlen(ifname) + 64); +- merror (ofname, "main()"); +- if (write_to_stdout) +- strcpy (ofname,_("standard output")); +- else { +- strcpy (ofname, ifname); +- if ((cp = strrchr (ofname, '.'))) *cp = 0; +- if (multi_out) +- sprintf (ofname+strlen(ofname), "_%0*d", +- snprintf(0,0,"%d",is_raw-1), shot_select); +- if (thumbnail_only) +- strcat (ofname, ".thumb"); +- strcat (ofname, write_ext); +- ofp = fopen (ofname, "wb"); +- if (!ofp) { +- status = 1; +- perror (ofname); +- goto cleanup; +- } +- } +- if (verbose) +- fprintf (stderr,_("Writing data to %s ...\n"), ofname); +- (*write_fun)(); +- fclose(ifp); +- if (ofp != stdout) fclose(ofp); +-cleanup: +- if (meta_data) free (meta_data); +- if (ofname) free (ofname); +- if (oprof) free (oprof); +- if (image) free (image); +- if (multi_out) { +- if (++shot_select < is_raw) arg--; +- else shot_select = 0; +- } +- } +- return status; +-} ++/* RT: Delete from here */ ++/*RT*/#undef SQR ++/*RT*/#undef MAX ++/*RT*/#undef MIN ++/*RT*/#undef ABS ++/*RT*/#undef LIM ++/*RT*/#undef ULIM ++/*RT*/#undef CLIP diff --git a/rtengine/dcraw.patch.README b/rtengine/dcraw.patch.README new file mode 100644 index 000000000..22b2323d7 --- /dev/null +++ b/rtengine/dcraw.patch.README @@ -0,0 +1,8 @@ +Patch for vanilla dcraw. Please run this against any new dcraw version copied here. + Instructions for patching: +1) Download newest dcraw.c file, and copy to this folder. +2) Run 'patch -p0 < dcraw.patch' to patch the file. If there are any rejections, please fix them manually. +3) Move the patched dcraw.c to dcraw.cc +4) Re-copy the vanilla downloaded dcraw.c back to this folder, and update the patch: 'diff -u dcraw.c dcraw.cc > dcraw.patch' + + diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc new file mode 100644 index 000000000..1d2cb7d45 --- /dev/null +++ b/rtengine/dcrop.cc @@ -0,0 +1,1023 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 + * 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 "dcrop.h" +#include "curves.h" +#include "mytime.h" +#include "refreshmap.h" +#include "rt_math.h" +// "ceil" rounding +#define SKIPS(a,b) ((a) / (b) + ((a) % (b) > 0)) + +namespace rtengine { + +extern const Settings* settings; + +Crop::Crop (ImProcCoordinator* parent, EditDataProvider *editDataProvider, bool isDetailWindow) + : EditBuffer(editDataProvider), origCrop(NULL), laboCrop(NULL), labnCrop(NULL), + cropImg(NULL), cbuf_real(NULL), cshmap(NULL), transCrop(NULL), cieCrop(NULL), cbuffer(NULL), + updating(false), newUpdatePending(false), skip(10), + cropx(0), cropy(0), cropw(-1), croph(-1), + trafx(0), trafy(0), trafw(-1), trafh(-1), + rqcropx(0), rqcropy(0), rqcropw(-1), rqcroph(-1), + borderRequested(32), upperBorder(0), leftBorder(0), + cropAllocated(false), + cropImageListener(NULL), parent(parent), isDetailWindow(isDetailWindow) +{ + parent->crops.push_back (this); +} + +Crop::~Crop () { + + MyMutex::MyLock cropLock(cropMutex); + + std::vector::iterator i = std::find (parent->crops.begin(), parent->crops.end(), this); + if (i!=parent->crops.end ()) + parent->crops.erase (i); + + MyMutex::MyLock processingLock(parent->mProcessing); + freeAll (); +} + +void Crop::destroy () { + MyMutex::MyLock lock(cropMutex); + MyMutex::MyLock processingLock(parent->mProcessing); + freeAll(); +} + +void Crop::setListener (DetailedCropListener* il) { + // We can make reads in the IF, because the mProcessing lock is only needed for change + if (cropImageListener!=il) { + MyMutex::MyLock lock(cropMutex); + cropImageListener = il; + } +} + +EditUniqueID Crop::getCurrEditID() { + EditSubscriber *subscriber = EditBuffer::dataProvider ? EditBuffer::dataProvider->getCurrSubscriber() : NULL; + return subscriber ? subscriber->getEditID() : EUID_None; +} + +/* + * Delete the edit image buffer if there's no subscriber anymore. + * If allocation has to be done, it is deferred to Crop::update + */ +void Crop::setEditSubscriber(EditSubscriber* newSubscriber) { + MyMutex::MyLock lock(cropMutex); + + // At this point, editCrop.dataProvider->currSubscriber is the old subscriber + EditSubscriber *oldSubscriber = EditBuffer::dataProvider ? EditBuffer::dataProvider->getCurrSubscriber() : NULL; + if (newSubscriber == NULL || (oldSubscriber != NULL && oldSubscriber->getEditBufferType() != newSubscriber->getEditBufferType())) { + if (EditBuffer::imgFloatBuffer!=NULL) { + delete EditBuffer::imgFloatBuffer; + EditBuffer::imgFloatBuffer = NULL; + } + if (EditBuffer::LabBuffer!=NULL) { + delete EditBuffer::LabBuffer; + EditBuffer::LabBuffer = NULL; + } + if (EditBuffer::singlePlaneBuffer.getW()!=-1) { + EditBuffer::singlePlaneBuffer.flushData(); + } + } + if (newSubscriber == NULL && oldSubscriber != NULL && oldSubscriber->getEditingType() == ET_OBJECTS) { + printf("Free object buffers\n"); + EditBuffer::resize(0, 0); // This will delete the objects buffer + } + else if (newSubscriber && newSubscriber->getEditingType() == ET_OBJECTS) { + EditBuffer::resize(cropw, croph, newSubscriber); + } + // If oldSubscriber == NULL && newSubscriber != NULL -> the image will be allocated when necessary +} + +void Crop::update (int todo) { + MyMutex::MyLock cropLock(cropMutex); + + ProcParams& params = parent->params; + // CropGUIListener* cropgl; + + // No need to update todo here, since it has already been changed in ImprocCoordinator::updatePreviewImage, + // and Crop::update ask to do ALL anyway + + // give possibility to the listener to modify crop window (as the full image dimensions are already known at this point) + int wx, wy, ww, wh, ws; + bool overrideWindow = false; + if (cropImageListener) + overrideWindow = cropImageListener->getWindow (wx, wy, ww, wh, ws); + // re-allocate sub-images and arrays if their dimensions changed + bool needsinitupdate = false; + if (!overrideWindow) + needsinitupdate = setCropSizes (rqcropx, rqcropy, rqcropw, rqcroph, skip, true); + else + needsinitupdate = setCropSizes (wx, wy, ww, wh, ws, true); // this set skip=ws + // it something has been reallocated, all processing steps have to be performed + if (needsinitupdate || (todo & M_HIGHQUAL)) + todo = ALL; + + // Tells to the ImProcFunctions' tool what is the preview scale, which may lead to some simplifications + parent->ipf.setScale (skip); + + Imagefloat* baseCrop = origCrop; + int widIm = parent->fw;//full image + int heiIm = parent->fh; + + bool needstransform = parent->ipf.needsTransform(); + + if (todo & (M_INIT|M_LINDENOISE)) { + MyMutex::MyLock lock(parent->minit); // Also used in improccoord + + int tr = getCoarseBitMask(params.coarse); + if (!needsinitupdate) + setCropSizes (rqcropx, rqcropy, rqcropw, rqcroph, skip, true); + + // printf("x=%d y=%d crow=%d croh=%d skip=%d\n",rqcropx, rqcropy, rqcropw, rqcroph, skip); + // printf("trafx=%d trafyy=%d trafwsk=%d trafHs=%d \n",trafx, trafy, trafw*skip, trafh*skip); + + Imagefloat *calclum = NULL;//for Luminance denoise curve + NoiseCurve noiseLCurve; + NoiseCurve noiseCCurve; + float autoNR = (float) settings->nrauto;// + float autoNRmax = (float) settings->nrautomax;// + + params.dirpyrDenoise.getCurves(noiseLCurve, noiseCCurve); + + int tilesize; + int overlap; + if(settings->leveldnti ==0) { + tilesize = 1024; + overlap = 128; + } + if(settings->leveldnti ==1) { + tilesize = 768; + overlap = 96; + } + + int numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip; + int kall=2; + + parent->ipf.Tile_calc (tilesize, overlap, kall, widIm, heiIm, numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip); + kall=0; + + float *ch_M = new float [9];//allocate memory + float *max_r = new float [9]; + float *max_b = new float [9]; + float *min_b = new float [9]; + float *min_r = new float [9]; + float *lumL = new float [9]; + float *chromC = new float [9]; + float *ry = new float [9]; + float *sk = new float [9]; + float *pcsk = new float [9]; + int *centerTile_X = new int [numtiles_W]; + int *centerTile_Y = new int [numtiles_H]; + for(int cX=0;cXleveldnautsimpl==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, origCrop, pp, params.toneCurve, params.icm, params.raw ); + } + } else { + if(params.dirpyrDenoise.C2method=="MANU") { + PreviewProps pp (trafx, trafy, trafw*skip, trafh*skip, skip); + parent->imgsrc->getImage (parent->currWB, tr, origCrop, pp, params.toneCurve, params.icm, 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, origCrop, pp, params.toneCurve, params.icm, params.raw ); + if((!isDetailWindow) && parent->adnListener && skip==1 && params.dirpyrDenoise.enabled) { + float lowdenoise=1.f; + int levaut=settings->leveldnaut; + if(levaut==1) //Standard + lowdenoise=0.7f; + int CenterPreview_X=trafx+(trafw*skip)/2; + int CenterPreview_Y=trafy+(trafh*skip)/2; + int minimuX=20000; + int minimuY=20000; + int poscenterX=0; + int poscenterY=0; + for(int cc=0;ccleveldnv ==0) {crW=100;} + if(settings->leveldnv ==1) {crW=250;} + // if(settings->leveldnv ==2) {crW=int(tileWskip/2);crH=int((tileWskip/2));}//adapted to scale of preview + if(settings->leveldnv ==2) {crW=int(tileWskip/2);} + if(settings->leveldnv ==3) {crW=tileWskip-10;} + + float adjustr=1.f; + if (params.icm.working=="ProPhoto") {adjustr =1.f;} + else if (params.icm.working=="Adobe RGB") {adjustr = 1.f/1.3f;} + else if (params.icm.working=="sRGB") {adjustr = 1.f/1.3f;} + else if (params.icm.working=="WideGamut") {adjustr =1.f/1.1f;} + else if (params.icm.working=="Beta RGB") {adjustr =1.f/1.2f;} + else if (params.icm.working=="BestRGB") {adjustr =1.f/1.2f;} + else if (params.icm.working=="BruceRGB") {adjustr =1.f/1.2f;} + if(parent->adnListener) + parent->adnListener->noiseTilePrev (centerTile_X[poscenterX], centerTile_Y[poscenterY],CenterPreview_X,CenterPreview_Y,crW, trafw*skip); + // I have tried "blind" some solutions..to move review ...but GUI is not my truc ! + // int W,H; + // cropgl->cropMoved (centerTile_X[poscenterX],centerTile_Y[poscenterY] , W, H); + // cropImageListener->setPosition (int x, int y, bool update=true); + // bool update; + // cropImageListener->setPosition (centerTile_X[poscenterX],centerTile_Y[poscenterY] , true); + //setCropSizes (centerTile_X[poscenterX], centerTile_Y[poscenterY], trafw*skip,trafh*skip , skip, true); + + // we only need image reduced to 1/4 here + 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;iir(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); + } + } + parent->imgsrc->convertColorSpace(provicalc, params.icm, parent->currWB);//for denoise luminance curve + + float maxr=0.f; + float maxb=0.f; + float chaut, redaut, blueaut, maxredaut, maxblueaut, minredaut, minblueaut, nresi, highresi, chromina, sigma, lumema, sigma_L, redyel, skinc, nsknc; + int Nb; + + chaut=0.f;redaut=0.f; blueaut=0.f; maxredaut=0.f; maxblueaut=0.f;minredaut=0.f; minblueaut=0.f; + 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(origCrop, provicalc, parent->imgsrc->isRAW(), gamcurve, gam, gamthresh, gamslope, params.dirpyrDenoise, parent->imgsrc->getDirPyrDenoiseExpComp(), chaut, Nb, redaut, blueaut, maxredaut, maxblueaut, minredaut, minblueaut,nresi, highresi, 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; + if(!parent->imgsrc->isRAW()) multip=2.f;//take into account gamma for TIF / JPG approximate value...not good for gamma=1 + + float maxmax=max(maxredaut,maxblueaut); + float delta; + int mode=0; + // float redyel, skinc, nsknc; + int lissage=settings->leveldnliss; + parent->ipf.calcautodn_info (chaut, delta, Nb, levaut, maxmax, lumema, chromina, mode, lissage, redyel, skinc, nsknc); + + + if(maxredaut > maxblueaut) { + // maxr=(maxredaut-chaut)/((autoNRmax*multip*adjustr)/2.f); + maxr=(delta)/((autoNRmax*multip*adjustr*lowdenoise)/2.f); + if(minblueaut <= minredaut && minblueaut < chaut) maxb=(-chaut+minblueaut)/(autoNRmax*multip*adjustr*lowdenoise); + } + else { + // maxb=(maxblueaut-chaut)/((autoNRmax*multip*adjustr)/2.f); + maxb=(delta)/((autoNRmax*multip*adjustr*lowdenoise)/2.f); + if(minredaut <= minblueaut && minredaut < chaut) maxr=(-chaut+minredaut)/(autoNRmax*multip*adjustr*lowdenoise); + }//maxb mxr - empirical evaluation red / blue + + + params.dirpyrDenoise.chroma=chaut/(autoNR*multip*adjustr*lowdenoise); + params.dirpyrDenoise.redchro=maxr; + params.dirpyrDenoise.bluechro=maxb; + parent->adnListener->chromaChanged(params.dirpyrDenoise.chroma, params.dirpyrDenoise.redchro, params.dirpyrDenoise.bluechro); + + delete provicalc; + } + } + + if(skip==1 && params.dirpyrDenoise.enabled && ((settings->leveldnautsimpl==1 && params.dirpyrDenoise.Cmethod=="AUT") || (settings->leveldnautsimpl==0 && params.dirpyrDenoise.C2method=="AUTO"))) { + MyTime t1aue,t2aue; + t1aue.set(); + + int crW,crH; + if(settings->leveldnv ==0) {crW=100;crH=100;} + if(settings->leveldnv ==1) {crW=250;crH=250;} + // if(settings->leveldnv ==2) {crW=int(tileWskip/2);crH=int((tileWskip/2));}//adapted to scale of preview + if(settings->leveldnv ==2) {crW=int(tileWskip/2);crH=int(tileHskip/2);} + if(settings->leveldnv ==3) {crW=tileWskip-10;crH=tileHskip-10;} + float lowdenoise=1.f; + int levaut=settings->leveldnaut; + if(levaut==1) //Standard + lowdenoise=0.7f; + + LUTf gamcurve(65536,0); + float gam, gamthresh, gamslope; + parent->ipf.RGB_denoise_infoGamCurve(params.dirpyrDenoise, parent->imgsrc->isRAW(), gamcurve, gam, gamthresh, gamslope); + int Nb[9]; +#ifdef _OPENMP +#pragma omp parallel +#endif +{ + Imagefloat *origCropPart = new Imagefloat (crW, crH);//allocate memory + Imagefloat *provicalc = new Imagefloat ((crW+1)/2, (crH+1)/2);//for denoise curves + + int coordW[3];//coordonate of part of image to mesure noise + int coordH[3]; + int begW=50; + int begH=50; + coordW[0]=begW;coordW[1]=widIm/2-crW/2;coordW[2]=widIm-crW-begW; + coordH[0]=begH;coordH[1]=heiIm/2-crH/2;coordH[2]=heiIm-crH-begH; +#ifdef _OPENMP +#pragma omp for schedule(dynamic) collapse(2) nowait +#endif + 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 ); + + // we only need image reduced to 1/4 here + for(int ii=0;iir(ii>>1,jj>>1) = origCropPart->r(ii,jj); + provicalc->g(ii>>1,jj>>1) = origCropPart->g(ii,jj); + provicalc->b(ii>>1,jj>>1) = origCropPart->b(ii,jj); + } + } + parent->imgsrc->convertColorSpace(provicalc, params.icm, parent->currWB);//for denoise luminance curve + + float pondcorrec=1.0f; + float chaut=0.f, redaut=0.f, blueaut=0.f, maxredaut=0.f, maxblueaut=0.f, minredaut=0.f, minblueaut=0.f, nresi=0.f, highresi=0.f, chromina=0.f, sigma=0.f, lumema=0.f, sigma_L=0.f, redyel=0.f, skinc=0.f, nsknc=0.f; + int nb=0; + parent->ipf.RGB_denoise_info(origCropPart, provicalc, parent->imgsrc->isRAW(), gamcurve, gam, gamthresh, gamslope, params.dirpyrDenoise, parent->imgsrc->getDirPyrDenoiseExpComp(), chaut, nb, redaut, blueaut, maxredaut, maxblueaut, minredaut, minblueaut, nresi, highresi, chromina, sigma, lumema, sigma_L, redyel, skinc, nsknc); + + //printf("DCROP skip=%d cha=%f red=%f bl=%f redM=%f bluM=%f chrom=%f sigm=%f lum=%f\n",skip, chaut,redaut,blueaut, maxredaut, maxblueaut, chromina, sigma, lumema); + Nb[hcr*3 + wcr] = nb; + ch_M[hcr*3 + wcr]=pondcorrec*chaut; + max_r[hcr*3 + wcr]=pondcorrec*maxredaut; + max_b[hcr*3 + wcr]=pondcorrec*maxblueaut; + min_r[hcr*3 + wcr]=pondcorrec*minredaut; + min_b[hcr*3 + wcr]=pondcorrec*minblueaut; + lumL[hcr*3 + wcr]=lumema; + chromC[hcr*3 + wcr]=chromina; + ry[hcr*3 + wcr]=redyel; + sk[hcr*3 + wcr]=skinc; + pcsk[hcr*3 + wcr]=nsknc; + + } + } + delete provicalc; + delete origCropPart; +} + float chM=0.f; + float MaxR=0.f; + float MaxB=0.f; + float MinR=100000000000.f; + float MinB=100000000000.f; + float maxr=0.f; + float maxb=0.f; + float Max_R[9]={0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f}; + float Max_B[9]={0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f}; + float Min_R[9]; + float Min_B[9]; + float MaxRMoy=0.f; + float MaxBMoy=0.f; + float MinRMoy=0.f; + float MinBMoy=0.f; + + float multip=1.f; + if(!parent->imgsrc->isRAW()) multip=2.f;//take into account gamma for TIF / JPG approximate value...not good fot gamma=1 + float adjustr=1.f; + if (params.icm.working=="ProPhoto") {adjustr =1.f;}// + else if (params.icm.working=="Adobe RGB") {adjustr = 1.f/1.3f;} + else if (params.icm.working=="sRGB") {adjustr = 1.f/1.3f;} + else if (params.icm.working=="WideGamut") {adjustr =1.f/1.1f;} + else if (params.icm.working=="Beta RGB") {adjustr =1.f/1.2f;} + else if (params.icm.working=="BestRGB") {adjustr =1.f/1.2f;} + else if (params.icm.working=="BruceRGB") {adjustr =1.f/1.2f;} + + float delta[9]; + int mode=1; + int lissage=settings->leveldnliss; + for (int k=0;k<9;k++) { + float maxmax=max(max_r[k],max_b[k]); + parent->ipf.calcautodn_info (ch_M[k], delta[k], Nb[k], levaut, maxmax,lumL[k],chromC[k], mode, lissage, ry[k], sk[k], pcsk[k]); + // printf("ch_M=%f delta=%f\n",ch_M[k], delta[k]); + } + for (int k=0;k<9;k++) { + if(max_r[k] > max_b[k]) { + Max_R[k]=(delta[k])/((autoNRmax*multip*adjustr*lowdenoise)/2.f); + Min_B[k]= -(ch_M[k]- min_b[k])/(autoNRmax*multip*adjustr*lowdenoise); + Max_B[k]=0.f; + Min_R[k]=0.f; + } + else { + Max_B[k]=(delta[k])/((autoNRmax*multip*adjustr*lowdenoise)/2.f); + Min_R[k]=- (ch_M[k]-min_r[k]) / (autoNRmax*multip*adjustr*lowdenoise); + Min_B[k]=0.f; + Max_R[k]=0.f; + } + } + + for (int k=0;k<9;k++) { + // printf("ch_M= %f Max_R=%f Max_B=%f min_r=%f min_b=%f\n",ch_M[k],Max_R[k], Max_B[k],Min_R[k], Min_B[k]); + chM+=ch_M[k]; + MaxBMoy+=Max_B[k]; + MaxRMoy+=Max_R[k]; + MinRMoy+=Min_R[k]; + MinBMoy+=Min_B[k]; + + if(Max_R[k]>MaxR) MaxR=Max_R[k]; + if(Max_B[k]>MaxB) MaxB=Max_B[k]; + if(Min_R[k] MaxB) { + maxr=MaxRMoy + (MaxR-MaxRMoy)*0.66f;//#std Dev + //maxb=MinB; + maxb=MinBMoy + (MinB-MinBMoy)*0.66f; + } + else { + maxb=MaxBMoy + (MaxB-MaxBMoy)*0.66f; + maxr=MinRMoy + (MinR-MinRMoy)*0.66f; + } + +// printf("DCROP skip=%d cha=%f red=%f bl=%f \n",skip, chM,maxr,maxb); + params.dirpyrDenoise.chroma=chM/(autoNR*multip*adjustr); + params.dirpyrDenoise.redchro=maxr; + params.dirpyrDenoise.bluechro=maxb; + if(parent->adnListener) { + parent->adnListener->chromaChanged(params.dirpyrDenoise.chroma, params.dirpyrDenoise.redchro, params.dirpyrDenoise.bluechro); + } + if (settings->verbose) { + t2aue.set(); + printf("Info denoise auto performed in %d usec:\n", t2aue.etime(t1aue)); + } + + //end evaluate noise + } + // 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, origCrop, pp, params.toneCurve, params.icm, params.raw ); + } + DirPyrDenoiseParams denoiseParams = params.dirpyrDenoise; + + if(params.dirpyrDenoise.Lmethod == "CUR") { + if(noiseLCurve) + denoiseParams.luma = 0.5f; //very small value to init process - select curve or slider + else + denoiseParams.luma = 0.0f; + } else if(denoiseParams.Lmethod == "SLI") + noiseLCurve.Reset(); + + 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 = origCrop->getWidth(); + int H = origCrop->getHeight(); + calclum = new Imagefloat ((W+1)/2, (H+1)/2);//for denoise curves + for(int ii=0;iir(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); + } + } + + parent->imgsrc->convertColorSpace(calclum, params.icm, parent->currWB);//for denoise luminance curve + } + + if(skip!=1) if(parent->adnListener) parent->adnListener->noiseChanged(0.f, 0.f); + + if (todo & M_LINDENOISE) { + if (skip==1 && denoiseParams.enabled) { + int kall=0; + + float chaut, redaut, blueaut, maxredaut, maxblueaut, nresi, highresi; + parent->ipf.RGB_denoise(kall, origCrop, origCrop, calclum, ch_M, max_r, max_b, parent->imgsrc->isRAW(), /*Roffset,*/ denoiseParams, parent->imgsrc->getDirPyrDenoiseExpComp(), noiseLCurve, noiseCCurve, chaut, redaut, blueaut, maxredaut, maxblueaut, nresi, highresi); + if (parent->adnListener) parent->adnListener->noiseChanged(nresi, highresi); + if (settings->leveldnautsimpl == 1) { + if ((denoiseParams.Cmethod == "AUT" || denoiseParams.Cmethod == "PRE") && (parent->adnListener)) // force display value of sliders + parent->adnListener->chromaChanged(denoiseParams.chroma, denoiseParams.redchro, denoiseParams.bluechro); + } else { + if((denoiseParams.C2method == "AUTO" || denoiseParams.C2method == "PREV") && (parent->adnListener)) // force display value of sliders + parent->adnListener->chromaChanged(denoiseParams.chroma, denoiseParams.redchro, denoiseParams.bluechro); + } + + } + } + parent->imgsrc->convertColorSpace(origCrop, params.icm, parent->currWB); + + delete [] ch_M; + delete [] max_r; + delete [] max_b; + delete [] min_r; + delete [] min_b; + delete [] lumL; + delete [] chromC; + delete [] ry; + delete [] sk; + delete [] pcsk; + delete [] centerTile_X; + delete [] centerTile_Y; + + } + + // 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); + + // transform + if (needstransform) { + if (!transCrop) + transCrop = new Imagefloat (cropw, croph); + + if ((todo & M_TRANSFORM) && 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->getRotateDegree(), false); + if (transCrop) + baseCrop = transCrop; + } + else { + if (transCrop) delete transCrop; + transCrop = NULL; + } + + // blurmap for shadow & highlights + if ((todo & M_BLURMAP) && params.sh.enabled) { + double radius = sqrt (double(SKIPS(parent->fw,skip)*SKIPS(parent->fw,skip)+SKIPS(parent->fh,skip)*SKIPS(parent->fh,skip))) / 2.0; + double shradius = params.sh.radius; + if (!params.sh.hq) shradius *= radius / 1800.0; + if(!cshmap) + cshmap = new SHMap (cropw, croph, true); + cshmap->update (baseCrop, shradius, parent->ipf.lumimul, params.sh.hq, skip); + if(parent->shmap->min_f < 65535.f) // don't call forceStat with wrong values + cshmap->forceStat (parent->shmap->max_f, parent->shmap->min_f, parent->shmap->avg); + } + + // shadows & highlights & tone curve & convert to cielab + /*int xref,yref; + xref=000;yref=000; + if (colortest && cropw>115 && croph>115) + for(int j=1;j<5;j++){ + xref+=j*30;yref+=j*30; + if (settings->verbose) printf("before rgbProc RGB Xr%i Yr%i Skip=%d R=%f G=%f B=%f gamma=%f \n",xref,yref,skip, + baseCrop->r[(int)(xref/skip)][(int)(yref/skip)]/256, + baseCrop->g[(int)(xref/skip)][(int)(yref/skip)]/256, + baseCrop->b[(int)(xref/skip)][(int)(yref/skip)]/256, + parent->imgsrc->getGamma()); + }*/ + float satLimit = float(params.colorToning.satProtectionThreshold)/100.f*0.7f+0.3f; + float satLimitOpacity = 1.f-(float(params.colorToning.saturatedOpacity)/100.f); + + if(params.colorToning.enabled && params.colorToning.autosat){//for colortoning evaluation of saturation settings + float moyS=0.f; + float eqty=0.f; + parent->ipf.moyeqt (baseCrop, moyS, eqty);//return image : mean saturation and standard dev of saturation + //printf("moy=%f ET=%f\n", moyS,eqty); + float satp=((moyS+1.5f*eqty)-0.3f)/0.7f;//1.5 sigma ==> 93% pixels with high saturation -0.3 / 0.7 convert to Hombre scale + if(satp >= 0.92f) satp=0.92f;//avoid values too high (out of gamut) + if(satp <= 0.15f) satp=0.15f;//avoid too low values + satLimit= 100.f*satp; + satLimitOpacity= 100.f*(moyS-0.85f*eqty);//-0.85 sigma==>20% pixels with low saturation + } + + if (todo & M_RGBCURVE) { + double rrm, ggm, bbm; + DCPProfile *dcpProf = parent->imgsrc->getDCP(params.icm, parent->currWB); + parent->ipf.rgbProc (baseCrop, laboCrop, this, parent->hltonecurve, parent->shtonecurve, parent->tonecurve, cshmap, + params.toneCurve.saturation, parent->rCurve, parent->gCurve, parent->bCurve, satLimit ,satLimitOpacity, parent->ctColorCurve, parent->ctOpacityCurve, parent->opautili, parent->clToningcurve,parent->cl2Toningcurve, + parent->customToneCurve1, parent->customToneCurve2, parent->beforeToneCurveBW, parent->afterToneCurveBW,rrm, ggm, bbm, + parent->bwAutoR, parent->bwAutoG, parent->bwAutoB, dcpProf); + } + /*xref=000;yref=000; + if (colortest && cropw>115 && croph>115) + for(int j=1;j<5;j++){ + xref+=j*30;yref+=j*30; + if (settings->verbose) { + printf("after rgbProc RGB Xr%i Yr%i Skip=%d R=%f G=%f B=%f \n",xref,yref,skip, + baseCrop->r[(int)(xref/skip)][(int)(yref/skip)]/256, + baseCrop->g[(int)(xref/skip)][(int)(yref/skip)]/256, + baseCrop->b[(int)(xref/skip)][(int)(yref/skip)]/256); + printf("after rgbProc Lab Xr%i Yr%i Skip=%d l=%f a=%f b=%f \n",xref,yref,skip, + laboCrop->L[(int)(xref/skip)][(int)(yref/skip)]/327, + laboCrop->a[(int)(xref/skip)][(int)(yref/skip)]/327, + laboCrop->b[(int)(xref/skip)][(int)(yref/skip)]/327); + } + }*/ + + // apply luminance operations + if (todo & (M_LUMINANCE+M_COLOR)) { + //I made a little change here. Rather than have luminanceCurve (and others) use in/out lab images, we can do more if we copy right here. + labnCrop->CopyFrom(laboCrop); + + + //parent->ipf.luminanceCurve (labnCrop, labnCrop, parent->lumacurve); + bool utili=parent->utili; + bool autili=parent->autili; + bool butili=parent->butili; + bool ccutili=parent->ccutili; + bool clcutili=parent->clcutili; + bool cclutili=parent->cclutili; + bool wavcontlutili=parent->wavcontlutili; + + LUTu dummy; + parent->ipf.chromiLuminanceCurve (this, 1,labnCrop, labnCrop, parent->chroma_acurve, parent->chroma_bcurve, parent->satcurve, parent->lhskcurve, parent->clcurve, parent->lumacurve, utili, autili, butili, ccutili,cclutili, clcutili, dummy, dummy, dummy, dummy); + parent->ipf.vibrance (labnCrop); + if((params.colorappearance.enabled && !params.colorappearance.tonecie) || (!params.colorappearance.enabled)) parent->ipf.EPDToneMap(labnCrop,5,1); + //parent->ipf.EPDToneMap(labnCrop, 5, 1); //Go with much fewer than normal iterates for fast redisplay. + // for all treatments Defringe, Sharpening, Contrast detail , Microcontrast they are activated if "CIECAM" function are disabled + if (skip==1) { + if((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) { + parent->ipf.impulsedenoise (labnCrop);} + if((params.colorappearance.enabled && !settings->autocielab) ||(!params.colorappearance.enabled) ) {parent->ipf.defringe (labnCrop);} + parent->ipf.MLsharpen (labnCrop); + if((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) { + parent->ipf.MLmicrocontrast (labnCrop); + parent->ipf.sharpening (labnCrop, (float**)cbuffer, params.sharpening); + } + } + // if (skip==1) { + WaveletParams WaveParams = params.wavelet; + + if((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) { + parent->ipf.dirpyrequalizer (labnCrop, skip); + // parent->ipf.Lanczoslab (labnCrop,labnCrop , 1.f/skip); + } + + + int kall=0; + int minwin=min(labnCrop->W,labnCrop->H); + int maxlevelcrop=10; + // if(cp.mul[9]!=0)maxlevelcrop=10; + // adap maximum level wavelet to size of crop + if(minwin*skip < 1024) maxlevelcrop = 9;//sampling wavelet 512 + if(minwin*skip < 512) maxlevelcrop = 8;//sampling wavelet 256 + if(minwin*skip < 256) maxlevelcrop = 7;//sampling 128 + if(minwin*skip < 128) maxlevelcrop = 6; + if(minwin < 64) maxlevelcrop = 5; + + int realtile; + if(params.wavelet.Tilesmethod=="big") realtile=22; + if(params.wavelet.Tilesmethod=="lit") realtile=12; + + int tilesize; + int overlap; + tilesize = 1024; + overlap = 128; + tilesize=128*realtile; + //overlap=(int) tilesize*params->wavelet.overl; + overlap=(int) tilesize*0.125f; + // printf("overl=%d\n",overlap); + int numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip; + + parent->ipf.Tile_calc (tilesize, overlap, kall, labnCrop->W, labnCrop->H, numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip); + //now we have tile dimensions, overlaps + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + int minsizetile=min(tilewidth, tileheight); + int maxlev2=10; + if(minsizetile < 1024 && maxlevelcrop==10) maxlev2 = 9; + if(minsizetile < 512) maxlev2 = 8; + if(minsizetile < 256) maxlev2 = 7; + if(minsizetile < 128) maxlev2 = 6; + int maxL=min(maxlev2,maxlevelcrop); + + if(parent->awavListener) parent->awavListener->wavChanged(float(maxL)); + + if((params.wavelet.enabled)) { + WavCurve wavCLVCurve; + WavOpacityCurveRG waOpacityCurveRG; + WavOpacityCurveBY waOpacityCurveBY; + WavOpacityCurveW waOpacityCurveW; + WavOpacityCurveWL waOpacityCurveWL; + LUTf wavclCurve; + LUTu dummy; + + 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); + } + + // } + + // } + if(params.colorappearance.enabled){ + float fnum = parent->imgsrc->getMetaData()->getFNumber (); // F number + float fiso = parent->imgsrc->getMetaData()->getISOSpeed () ; // ISO + float fspeed = parent->imgsrc->getMetaData()->getShutterSpeed () ; // Speed + double fcomp = parent->imgsrc->getMetaData()->getExpComp (); // Compensation +/- + double adap; // Scene's luminosity adaptation factor + if(fnum < 0.3f || fiso < 5.f || fspeed < 0.00001f) { //if no exif data or wrong + adap=2000.; + } + else { + double E_V = fcomp + log2 (double((fnum*fnum) / fspeed / (fiso/100.f))); + E_V += params.toneCurve.expcomp;// exposure compensation in tonecurve ==> direct EV + E_V += log2(params.raw.expos);// exposure raw white point ; log2 ==> linear to EV + adap= pow(2., E_V-3.);// cd / m2 + // end calculation adaptation scene luminosity + } + + int begh = 0, endh = labnCrop->H; + bool execsharp=false; + if(skip==1) execsharp=true; + + if (!cieCrop) + { cieCrop = new CieImage (cropw, croph); } + + if(settings->ciecamfloat) { + float d; // not used after this block + parent->ipf.ciecam_02float (cieCrop, float(adap), begh, endh, 1, 2, labnCrop, ¶ms, parent->customColCurve1, parent->customColCurve2, parent->customColCurve3, + dummy, dummy, parent->CAMBrightCurveJ, parent->CAMBrightCurveQ, parent->CAMMean, 5, 1, execsharp, d, skip, 1); + } + else { + double dd; // 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, 1, execsharp, dd, skip, 1); + } + } + else { + // CIECAM is disbaled, we free up its image buffer to save some space + if (cieCrop) delete cieCrop; cieCrop=NULL; + } + } + + // all pipette buffer processing should be finished now + EditBuffer::setReady(); + + // switch back to rgb + parent->ipf.lab2monitorRgb (labnCrop, cropImg); + + //parent->ipf.lab2monitorRgb (laboCrop, cropImg); + + //cropImg = baseCrop->to8(); + /* + // int xref,yref; + xref=000;yref=000; + if (colortest && cropw>115 && croph>115) + for(int j=1;j<5;j++){ + xref+=j*30;yref+=j*30; + int rlin = (CurveFactory::igamma2((float)cropImg->data[3*((int)(xref/skip)*cropImg->width+(int)(yref/skip))]/255.0) * 255.0); + int glin = (CurveFactory::igamma2((float)cropImg->data[3*((int)(xref/skip)*cropImg->width+(int)(yref/skip))+1]/255.0) * 255.0); + int blin = (CurveFactory::igamma2((float)cropImg->data[3*((int)(xref/skip)*cropImg->width+(int)(yref/skip))+2]/255.0) * 255.0); + + printf("after lab2rgb RGB lab2 Xr%i Yr%i Skip=%d R=%d G=%d B=%d \n",xref,yref,skip, + rlin,glin,blin); + //cropImg->data[3*((int)(xref/skip)*cropImg->width+(int)(yref/skip))], + //cropImg->data[(3*((int)(xref/skip)*cropImg->width+(int)(yref/skip))+1)], + //cropImg->data[(3*((int)(xref/skip)*cropImg->width+(int)(yref/skip))+2)]); + //printf("after lab2rgb Lab lab2 Xr%i Yr%i Skip=%d l=%f a=%f b=%f \n",xref,yref,skip, labnCrop->L[(int)(xref/skip)][(int)(yref/skip)]/327,labnCrop->a[(int)(xref/skip)][(int)(yref/skip)]/327,labnCrop->b[(int)(xref/skip)][(int)(yref/skip)]/327); + printf("after lab2rgb Lab Xr%i Yr%i Skip=%d l=%f a=%f b=%f \n",xref,yref,skip, + labnCrop->L[(int)(xref/skip)][(int)(yref/skip)]/327, + labnCrop->a[(int)(xref/skip)][(int)(yref/skip)]/327, + labnCrop->b[(int)(xref/skip)][(int)(yref/skip)]/327)q; + } + */ + /* + if (colortest && cropImg->height>115 && cropImg->width>115) {//for testing + xref=000;yref=000; + printf("dcrop final R= %d G= %d B= %d \n", + cropImg->data[3*xref/(skip)*(cropImg->width+1)], + cropImg->data[3*xref/(skip)*(cropImg->width+1)+1], + cropImg->data[3*xref/(skip)*(cropImg->width+1)+2]); + } + */ + if (cropImageListener) { + // this in output space held in parallel to allow analysis like shadow/highlight + Glib::ustring outProfile=params.icm.output; + Glib::ustring workProfile=params.icm.working; + Image8 *cropImgtrue; + if(settings->HistogramWorking) cropImgtrue = parent->ipf.lab2rgb (labnCrop, 0,0,cropw,croph, workProfile, false); + else { + if (params.icm.output=="" || params.icm.output==ColorManagementParams::NoICMString) outProfile="sRGB"; + cropImgtrue = parent->ipf.lab2rgb (labnCrop, 0,0,cropw,croph, outProfile, false); + } + + int finalW = rqcropw; + if (cropImg->getWidth()-leftBorder < finalW) + finalW = cropImg->getWidth()-leftBorder; + int finalH = rqcroph; + if (cropImg->getHeight()-upperBorder < finalH) + finalH = cropImg->getHeight()-upperBorder; + + Image8* final = new Image8 (finalW, finalH); + Image8* finaltrue = new Image8 (finalW, finalH); + for (int i=0; idata + 3*i*finalW, cropImg->data + 3*(i+upperBorder)*cropw + 3*leftBorder, 3*finalW); + memcpy (finaltrue->data + 3*i*finalW, cropImgtrue->data + 3*(i+upperBorder)*cropw + 3*leftBorder, 3*finalW); + } + cropImageListener->setDetailedCrop (final, finaltrue, params.icm, params.crop, rqcropx, rqcropy, rqcropw, rqcroph, skip); + delete final; + delete finaltrue; + delete cropImgtrue; + } +} + +void Crop::freeAll () { + + if (settings->verbose) printf ("freeallcrop starts %d\n", (int)cropAllocated); + + if (cropAllocated) { + if (origCrop ) { delete origCrop; origCrop=NULL; } + if (transCrop) { delete transCrop; transCrop=NULL; } + if (laboCrop ) { delete laboCrop; laboCrop=NULL; } + if (labnCrop ) { delete labnCrop; labnCrop=NULL; } + if (cropImg ) { delete cropImg; cropImg=NULL; } + if (cieCrop ) { delete cieCrop; cieCrop=NULL; } + if (cbuf_real) { delete [] cbuf_real; cbuf_real=NULL; } + if (cbuffer ) { delete [] cbuffer; cbuffer=NULL; } + if (cshmap ) { delete cshmap; cshmap=NULL; } + + EditBuffer::flush(); + } + cropAllocated = false; +} + +/** @brief Handles crop's image buffer reallocation and trigger sizeChanged of SizeListener[s] + * If the scale changes, this method will free all buffers and reallocate ones of the new size. + * It will then tell to the SizeListener that size has changed (sizeChanged) + */ +bool Crop::setCropSizes (int rcx, int rcy, int rcw, int rch, int skip, bool internal) { + +if (settings->verbose) printf ("setcropsizes before lock\n"); + + if (!internal) + cropMutex.lock (); + + bool changed = false; + + rqcropx = rcx; + rqcropy = rcy; + rqcropw = rcw; + rqcroph = rch; + + // store and set requested crop size + int rqx1 = LIM(rqcropx,0,parent->fullw-1); + int rqy1 = LIM(rqcropy,0,parent->fullh-1); + int rqx2 = rqx1 + rqcropw - 1; + int rqy2 = rqy1 + rqcroph - 1; + rqx2 = LIM(rqx2,0,parent->fullw-1); + rqy2 = LIM(rqy2,0,parent->fullh-1); + + this->skip = skip; + + // add border, if possible + int bx1 = rqx1 - skip*borderRequested; + int by1 = rqy1 - skip*borderRequested; + int bx2 = rqx2 + skip*borderRequested; + int by2 = rqy2 + skip*borderRequested; + // clip it to fit into image area + bx1 = LIM(bx1,0,parent->fullw-1); + by1 = LIM(by1,0,parent->fullh-1); + bx2 = LIM(bx2,0,parent->fullw-1); + by2 = LIM(by2,0,parent->fullh-1); + int bw = bx2 - bx1 + 1; + int bh = by2 - by1 + 1; + + // determine which part of the source image is required to compute the crop rectangle + int orx, ory, orw, orh; + ProcParams& params = parent->params; + parent->ipf.transCoord (parent->fw, parent->fh, bx1, by1, bw, bh, orx, ory, orw, orh); + + int tr = getCoarseBitMask(params.coarse); + + PreviewProps cp (orx, ory, orw, orh, skip); + int orW, orH; + parent->imgsrc->getSize (tr, cp, orW, orH); + + 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); + + if (cw!=cropw || ch!=croph || orW!=trafw || orH!=trafh) { + + cropw = cw; + croph = ch; + trafw = orW; + trafh = orH; + + if (!origCrop) + origCrop = new Imagefloat; + origCrop->allocate(trafw, trafh); // Resizing the buffer (optimization) + + // if transCrop doesn't exist yet, it'll be created where necessary + if (transCrop) transCrop->allocate(cropw, croph); + + if (laboCrop) delete laboCrop; // laboCrop can't be resized + laboCrop = new LabImage (cropw, croph); + + if (labnCrop) delete labnCrop; // labnCrop can't be resized + labnCrop = new LabImage (cropw, croph); + + if (!cropImg) + cropImg = new Image8; + cropImg->allocate(cropw, croph); // Resizing the buffer (optimization) + + //cieCrop is only used in Crop::update, it is destroyed now but will be allocated on first use + if (cieCrop) { delete cieCrop; cieCrop=NULL; } + + if (cbuffer ) delete [] cbuffer; + if (cbuf_real) delete [] cbuf_real; + if (cshmap ) { delete cshmap; cshmap = NULL;} + cbuffer = new float*[croph]; + cbuf_real= new float[(croph+2)*cropw]; + for (int i=0; iverbose) printf ("setsizes ends\n"); + + if (!internal) + cropMutex.unlock (); + + return changed; +} + +/** @brief Look out if a new thread has to be started to process the update + * + * @return If true, a new updating thread has to be created. If false, the current updating thread will be used + */ +bool Crop::tryUpdate() { + bool needsNewThread = true; + + if (updating) { + // tells to the updater thread that a new update is pending + newUpdatePending = true; + // no need for a new thread, the current one will do the job + needsNewThread = false; + } + else + // the crop is now being updated ...well, when fullUpdate will be called + updating = true; + + return needsNewThread; +} + +/* @brief Handles Crop updating in its own thread + * + * This method will cycle updates as long as Crop::newUpdatePending will be true. During the processing, + * intermediary update will be automatically flushed by Crop::tryUpdate. + * + * This method is called when the visible part of the crop has changed (resize, zoom, etc..), so it needs a full update + */ +void Crop::fullUpdate () { + + parent->updaterThreadStart.lock (); + if (parent->updaterRunning && parent->thread) { + // Do NOT reset changes here, since in a long chain of events it will lead to chroma_scale not being updated, + // causing Color::lab2rgb to return a black image on some opens + //parent->changeSinceLast = 0; + parent->thread->join (); + } + + if (parent->plistener) + parent->plistener->setProgressState (true); + + // If there are more update request, the following WHILE will collect it + newUpdatePending = true; + while (newUpdatePending) { + newUpdatePending = false; + update (ALL); + } + updating = false; // end of crop update + + if (parent->plistener) + parent->plistener->setProgressState (false); + parent->updaterThreadStart.unlock (); +} + +} + diff --git a/rtengine/dcrop.h b/rtengine/dcrop.h new file mode 100644 index 000000000..6f858779f --- /dev/null +++ b/rtengine/dcrop.h @@ -0,0 +1,99 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _CROP_H_ +#define _CROP_H_ + +#include "improccoordinator.h" +#include "rtengine.h" +#include "improcfun.h" +#include "image8.h" +#include "image16.h" +#include "imagesource.h" +#include "procevents.h" +#include "editbuffer.h" +#include "../rtgui/threadutils.h" + +namespace rtengine { + +using namespace procparams; + +class ImProcCoordinator; + +class Crop : public DetailedCrop, public EditBuffer { + + protected: + // --- permanently allocated in RAM and only renewed on size changes + Imagefloat* origCrop; // "one chunk" allocation + LabImage* laboCrop; // "one chunk" allocation + LabImage* labnCrop; // "one chunk" allocation + Image8* cropImg; // "one chunk" allocation + float * cbuf_real; // "one chunk" allocation + SHMap* cshmap; // per line allocation + + // --- automatically allocated and deleted when necessary, and only renewed on size changes + Imagefloat* transCrop; // "one chunk" allocation, allocated if necessary + CieImage* cieCrop; // allocating 6 images, each in "one chunk" allocation + // ----------------------------------------------------------------- + float** cbuffer; + + bool updating; /// Flag telling if an updater thread is currently processing + bool newUpdatePending; /// Flag telling the updater thread that a new update is pending + int skip; + int cropx, cropy, cropw, croph; /// size of the detail crop image ('skip' taken into account), with border + int trafx, trafy, trafw, trafh; /// the size and position to get from the imagesource that is transformed to the requested crop area + int rqcropx, rqcropy, rqcropw, rqcroph; /// size of the requested detail crop image (the image might be smaller) (without border) + int borderRequested; /// requested extra border size for image processing + int upperBorder, leftBorder; /// extra border size really allocated for image processing + + bool cropAllocated; + DetailedCropListener* cropImageListener; + + MyMutex cropMutex; + ImProcCoordinator* parent; + bool isDetailWindow; + EditUniqueID getCurrEditID(); + bool setCropSizes (int cx, int cy, int cw, int ch, int skip, bool internal); + void freeAll (); + + public: + Crop (ImProcCoordinator* parent, EditDataProvider *editDataProvider, bool isDetailWindow); + virtual ~Crop (); + + void mLock () { cropMutex.lock(); } + void mUnlock () { cropMutex.lock(); } + void setEditSubscriber(EditSubscriber* newSubscriber); + bool hasListener () { return cropImageListener; } + void update (int todo); + void setWindow (int cx, int cy, int cw, int ch, int skip) { setCropSizes (cx, cy, cw, ch, skip, false); } + + /** @brief Synchronously look out if a full update is necessary + * First try, only make fullUpdate if this returns false + */ + bool tryUpdate (); + /** @brief Asynchronously reprocess the detailed crop */ + void fullUpdate (); // called via thread + + void setListener (DetailedCropListener* il); + void destroy (); + int get_skip () { return skip;} + int getLeftBorder () { return leftBorder; } + int getUpperBorder () { return upperBorder; } +}; +} +#endif diff --git a/rtengine/demosaic_algos.cc b/rtengine/demosaic_algos.cc new file mode 100644 index 000000000..e986270ff --- /dev/null +++ b/rtengine/demosaic_algos.cc @@ -0,0 +1,4005 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "rawimagesource.h" +#include "rawimagesource_i.h" +#include "median.h" +#include "rawimage.h" +#include "mytime.h" +#include "iccmatrices.h" +#include "iccstore.h" +#include "image8.h" +#include "curves.h" +#include "dfmanager.h" +#include "slicer.h" +#include "rt_math.h" +#include "color.h" +#include "../rtgui/multilangmgr.h" +#include "procparams.h" +#include "sleef.c" +#include "opthelper.h" + +#ifdef _OPENMP +#include +#endif + +using namespace std; + +namespace rtengine { +#undef ABS +#undef DIST + +#define ABS(a) ((a)<0?-(a):(a)) +#define DIST(a,b) (ABS(a-b)) +#define CLIREF(x) LIM(x,-200000.0f,200000.0f) // avoid overflow : do not act directly on image[] or pix[] +#define x1125(a) (a + xdivf(a, 3)) +#define x0875(a) (a - xdivf(a, 3)) +#define x0250(a) xdivf(a, 2) +#define x00625(a) xdivf(a, 4) +#define x0125(a) xdivf(a, 3) + + +#define PIX_SORT(a,b) { if ((a)>(b)) {temp=(a);(a)=(b);(b)=temp;} } +#define PIX_SORTV(av,bv) tempv = _mm_min_ps(av,bv); bv = _mm_max_ps(av,bv); av = tempv; +extern const Settings* settings; +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void RawImageSource::eahd_demosaic () { + if (plistener) { + plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::eahd])); + plistener->setProgress (0.0); + } + + // prepare cache and constants for cielab conversion + //TODO: revisit after conversion to D50 illuminant + lc00 = (0.412453 * imatrices.rgb_cam[0][0] + 0.357580 * imatrices.rgb_cam[0][1] + 0.180423 * imatrices.rgb_cam[0][2]) ;// / 0.950456; + lc01 = (0.412453 * imatrices.rgb_cam[1][0] + 0.357580 * imatrices.rgb_cam[1][1] + 0.180423 * imatrices.rgb_cam[1][2]) ;// / 0.950456; + lc02 = (0.412453 * imatrices.rgb_cam[2][0] + 0.357580 * imatrices.rgb_cam[2][1] + 0.180423 * imatrices.rgb_cam[2][2]) ;// / 0.950456; + + lc10 = 0.212671 * imatrices.rgb_cam[0][0] + 0.715160 * imatrices.rgb_cam[0][1] + 0.072169 * imatrices.rgb_cam[0][2]; + lc11 = 0.212671 * imatrices.rgb_cam[1][0] + 0.715160 * imatrices.rgb_cam[1][1] + 0.072169 * imatrices.rgb_cam[1][2]; + lc12 = 0.212671 * imatrices.rgb_cam[2][0] + 0.715160 * imatrices.rgb_cam[2][1] + 0.072169 * imatrices.rgb_cam[2][2]; + + lc20 = (0.019334 * imatrices.rgb_cam[0][0] + 0.119193 * imatrices.rgb_cam[0][1] + 0.950227 * imatrices.rgb_cam[0][2]) ;// / 1.088754; + lc21 = (0.019334 * imatrices.rgb_cam[1][0] + 0.119193 * imatrices.rgb_cam[1][1] + 0.950227 * imatrices.rgb_cam[1][2]) ;// / 1.088754; + lc22 = (0.019334 * imatrices.rgb_cam[2][0] + 0.119193 * imatrices.rgb_cam[2][1] + 0.950227 * imatrices.rgb_cam[2][2]) ;// / 1.088754; + + int maxindex = 3*65536;//2*65536 3 = avoid crash 3/2013 J.Desmis + cache = new double[maxindex]; + threshold = (int)(0.008856*MAXVALD); + for (int i=0; isv) { // fixate horizontal pixel + dLmaph[dmi] = DIST(lLh[ix][j], lLh[idx][j+y]); + dCamaph[dmi] = DIST(lah[ix][j], lah[idx][j+y]); + dCbmaph[dmi] = DIST(lbh[ix][j], lbh[idx][j+y]); + dLmapv[dmi] = DIST(lLv[ix][j], lLh[idx][j+y]); + dCamapv[dmi] = DIST(lav[ix][j], lah[idx][j+y]); + dCbmapv[dmi] = DIST(lbv[ix][j], lbh[idx][j+y]); + } + else if (shISGREEN(i-1,j)) + green[i-1][j] = rawData[i-1][j]; + else { + hc = homh[imx][j]; + vc = homv[imx][j]; + if (hc > vc) + green[i-1][j] = gh[(i-1)%4][j]; + else if (hc < vc) + green[i-1][j] = gv[(i-1)%4][j]; + else + green[i-1][j] = (gh[(i-1)%4][j] + gv[(i-1)%4][j]) / 2; + } + } + + if (!(i%20) && plistener) + plistener->setProgress ((double)i / (H-2)); + } + // finish H-2th and H-1th row, homogenity value is still valailable + int hc, vc; + for (int i=H-1; i vc) + green[i-1][j] = gh[(i-1)%4][j]; + else if (hc < vc) + green[i-1][j] = gv[(i-1)%4][j]; + else + green[i-1][j] = (gh[(i-1)%4][j] + gv[(i-1)%4][j]) / 2; + } + + freeArray2(rh, 3); + freeArray2(gh, 4); + freeArray2(bh, 3); + freeArray2(rv, 3); + freeArray2(gv, 4); + freeArray2(bv, 3); + freeArray2(lLh, 3); + freeArray2(lah, 3); + freeArray2(lbh, 3); + freeArray2(homh, 3); + freeArray2(lLv, 3); + freeArray2(lav, 3); + freeArray2(lbv, 3); + freeArray2(homv, 3); + + // Interpolate R and B + for (int i=0; iISGREEN(i,j)) + green[i][j] = rawData[i][j]; + else { + if (hpmap[i][j]==1) { + int g2 = rawData[i][j+1] + ((rawData[i][j] - rawData[i][j+2]) /2); + int g4 = rawData[i][j-1] + ((rawData[i][j] - rawData[i][j-2]) /2); + + int dx = rawData[i][j+1] - rawData[i][j-1]; + int d1 = rawData[i][j+3] - rawData[i][j+1]; + int d2 = rawData[i][j+2] - rawData[i][j]; + int d3 = (rawData[i-1][j+2] - rawData[i-1][j]) /2; + int d4 = (rawData[i+1][j+2] - rawData[i+1][j]) /2; + + double e2 = 1.0 / (1.0 + ABS(dx) + ABS(d1) + ABS(d2) + ABS(d3) + ABS(d4)); + + d1 = rawData[i][j-3] - rawData[i][j-1]; + d2 = rawData[i][j-2] - rawData[i][j]; + d3 = (rawData[i-1][j-2] - rawData[i-1][j]) /2; + d4 = (rawData[i+1][j-2] - rawData[i+1][j]) /2; + + double e4 = 1.0 / (1.0 + ABS(dx) + ABS(d1) + ABS(d2) + ABS(d3) + ABS(d4)); + + green[i][j] = (e2 * g2 + e4 * g4) / (e2 + e4); + } + else if (hpmap[i][j]==2) { + int g1 = rawData[i-1][j] + ((rawData[i][j] - rawData[i-2][j]) /2); + int g3 = rawData[i+1][j] + ((rawData[i][j] - rawData[i+2][j]) /2); + + int dy = rawData[i+1][j] - rawData[i-1][j]; + int d1 = rawData[i-1][j] - rawData[i-3][j]; + int d2 = rawData[i][j] - rawData[i-2][j]; + int d3 = (rawData[i][j-1] - rawData[i-2][j-1]) /2; + int d4 = (rawData[i][j+1] - rawData[i-2][j+1]) /2; + + double e1 = 1.0 / (1.0 + ABS(dy) + ABS(d1) + ABS(d2) + ABS(d3) + ABS(d4)); + + d1 = rawData[i+1][j] - rawData[i+3][j]; + d2 = rawData[i][j] - rawData[i+2][j]; + d3 = (rawData[i][j-1] - rawData[i+2][j-1]) /2; + d4 = (rawData[i][j+1] - rawData[i+2][j+1]) /2; + + double e3 = 1.0 / (1.0 + ABS(dy) + ABS(d1) + ABS(d2) + ABS(d3) + ABS(d4)); + + green[i][j] = (e1 * g1 + e3 * g3) / (e1 + e3); + } + else { + int g1 = rawData[i-1][j] + ((rawData[i][j] - rawData[i-2][j]) /2); + int g2 = rawData[i][j+1] + ((rawData[i][j] - rawData[i][j+2]) /2); + int g3 = rawData[i+1][j] + ((rawData[i][j] - rawData[i+2][j]) /2); + int g4 = rawData[i][j-1] + ((rawData[i][j] - rawData[i][j-2]) /2); + + int dx = rawData[i][j+1] - rawData[i][j-1]; + int dy = rawData[i+1][j] - rawData[i-1][j]; + + int d1 = rawData[i-1][j] - rawData[i-3][j]; + int d2 = rawData[i][j] - rawData[i-2][j]; + int d3 = (rawData[i][j-1] - rawData[i-2][j-1]) /2; + int d4 = (rawData[i][j+1] - rawData[i-2][j+1]) /2; + + double e1 = 1.0 / (1.0 + ABS(dy) + ABS(d1) + ABS(d2) + ABS(d3) + ABS(d4)); + + d1 = rawData[i][j+3] - rawData[i][j+1]; + d2 = rawData[i][j+2] - rawData[i][j]; + d3 = (rawData[i-1][j+2] - rawData[i-1][j]) /2; + d4 = (rawData[i+1][j+2] - rawData[i+1][j]) /2; + + double e2 = 1.0 / (1.0 + ABS(dx) + ABS(d1) + ABS(d2) + ABS(d3) + ABS(d4)); + + d1 = rawData[i+1][j] - rawData[i+3][j]; + d2 = rawData[i][j] - rawData[i+2][j]; + d3 = (rawData[i][j-1] - rawData[i+2][j-1]) /2; + d4 = (rawData[i][j+1] - rawData[i+2][j+1]) /2; + + double e3 = 1.0 / (1.0 + ABS(dy) + ABS(d1) + ABS(d2) + ABS(d3) + ABS(d4)); + + d1 = rawData[i][j-3] - rawData[i][j-1]; + d2 = rawData[i][j-2] - rawData[i][j]; + d3 = (rawData[i-1][j-2] - rawData[i-1][j]) /2; + d4 = (rawData[i+1][j-2] - rawData[i+1][j]) /2; + + double e4 = 1.0 / (1.0 + ABS(dx) + ABS(d1) + ABS(d2) + ABS(d3) + ABS(d4)); + + green[i][j] = (e1*g1 + e2*g2 + e3*g3 + e4*g4) / (e1 + e2 + e3 + e4); + } + } + } + } +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void RawImageSource::hphd_demosaic () { + if (plistener) { + plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::hphd])); + plistener->setProgress (0.0); + } + + float** hpmap = allocArray< float >(W,H, true); + +#ifdef _OPENMP + #pragma omp parallel + { + int tid = omp_get_thread_num(); + int nthreads = omp_get_num_threads(); + int blk = W/nthreads; + + if (tidsetProgress (0.33); + + for (int i=0; i(hpmap, H);//TODO: seems to cause sigabrt ??? why??? + + if (plistener) + plistener->setProgress (0.66); + + for (int i=0; isetProgress (1.0); +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +#define fc(row,col) (prefilters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3) +typedef unsigned short ushort; +void RawImageSource::vng4_demosaic () { + const signed short int *cp, terms[] = { + -2,-2,+0,-1,0,0x01, -2,-2,+0,+0,1,0x01, -2,-1,-1,+0,0,0x01, + -2,-1,+0,-1,0,0x02, -2,-1,+0,+0,0,0x03, -2,-1,+0,+1,1,0x01, + -2,+0,+0,-1,0,0x06, -2,+0,+0,+0,1,0x02, -2,+0,+0,+1,0,0x03, + -2,+1,-1,+0,0,0x04, -2,+1,+0,-1,1,0x04, -2,+1,+0,+0,0,0x06, + -2,+1,+0,+1,0,0x02, -2,+2,+0,+0,1,0x04, -2,+2,+0,+1,0,0x04, + -1,-2,-1,+0,0,0x80, -1,-2,+0,-1,0,0x01, -1,-2,+1,-1,0,0x01, + -1,-2,+1,+0,1,0x01, -1,-1,-1,+1,0,0x88, -1,-1,+1,-2,0,0x40, + -1,-1,+1,-1,0,0x22, -1,-1,+1,+0,0,0x33, -1,-1,+1,+1,1,0x11, + -1,+0,-1,+2,0,0x08, -1,+0,+0,-1,0,0x44, -1,+0,+0,+1,0,0x11, + -1,+0,+1,-2,1,0x40, -1,+0,+1,-1,0,0x66, -1,+0,+1,+0,1,0x22, + -1,+0,+1,+1,0,0x33, -1,+0,+1,+2,1,0x10, -1,+1,+1,-1,1,0x44, + -1,+1,+1,+0,0,0x66, -1,+1,+1,+1,0,0x22, -1,+1,+1,+2,0,0x10, + -1,+2,+0,+1,0,0x04, -1,+2,+1,+0,1,0x04, -1,+2,+1,+1,0,0x04, + +0,-2,+0,+0,1,0x80, +0,-1,+0,+1,1,0x88, +0,-1,+1,-2,0,0x40, + +0,-1,+1,+0,0,0x11, +0,-1,+2,-2,0,0x40, +0,-1,+2,-1,0,0x20, + +0,-1,+2,+0,0,0x30, +0,-1,+2,+1,1,0x10, +0,+0,+0,+2,1,0x08, + +0,+0,+2,-2,1,0x40, +0,+0,+2,-1,0,0x60, +0,+0,+2,+0,1,0x20, + +0,+0,+2,+1,0,0x30, +0,+0,+2,+2,1,0x10, +0,+1,+1,+0,0,0x44, + +0,+1,+1,+2,0,0x10, +0,+1,+2,-1,1,0x40, +0,+1,+2,+0,0,0x60, + +0,+1,+2,+1,0,0x20, +0,+1,+2,+2,0,0x10, +1,-2,+1,+0,0,0x80, + +1,-1,+1,+1,0,0x88, +1,+0,+1,+2,0,0x08, +1,+0,+2,-1,0,0x40, + +1,+0,+2,+1,0,0x10 + }, + chood[] = { -1,-1, -1,0, -1,+1, 0,+1, +1,+1, +1,0, +1,-1, 0,-1 }; + + double progress = 0.0; + const bool plistenerActive = plistener; + + if (plistenerActive) { + plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::vng4])); + plistener->setProgress (progress); + } + + const unsigned prefilters = ri->prefilters; + const int width=W, height=H; + const int colors=4; + float (*image)[4]; + + image = (float (*)[4]) calloc (height*width, sizeof *image); + +#ifdef _OPENMP +#pragma omp parallel for +#endif + for (int ii=0; iisetProgress (progress); + } + + +#ifdef _OPENMP +#pragma omp parallel +#endif +{ + float gval[8], thold, sum[3]; + int g; + const int progressStep = 64; + const double progressInc = (0.98-progress)/((height-2)/progressStep); +#ifdef _OPENMP +#pragma omp for nowait +#endif + for (int row=2; row < height-2; row++) { /* Do VNG interpolation */ + for (int col=2; col < width-2; col++) { + float * pix = image[row*width+col]; + int * ip = code[row & prow][col & pcol]; + memset (gval, 0, sizeof gval); + while ((g = ip[0]) != INT_MAX) { /* Calculate gradients */ + float diff = fabsf(pix[g] - pix[ip[1]]) * (1<< ip[2]); + gval[ip[3]] += diff; + ip+=4; + while ((g = *ip++) != -1) + gval[g] += diff; + } + ip++; + { + float gmin, gmax; + gmin = gmax = gval[0]; /* Choose a threshold */ + for (g=1; g < 8; g++) { + if (gmin > gval[g]) + gmin = gval[g]; + if (gmax < gval[g]) + gmax = gval[g]; + } + thold = gmin + (gmax /2); + } + memset (sum, 0, sizeof sum); + float t1,t2; + int color = fc(row,col); + t1 = t2 = pix[color]; + if(color&1) { + int num = 0; + for (g=0; g < 8; g++,ip+=2) { /* Average the neighbors */ + if (gval[g] <= thold) { + if(ip[1]) + sum[0] += (t1 + pix[ip[1]])*0.5f; + sum[1] += pix[ip[0] + (color ^ 2)]; + num++; + } + } + t1 += (sum[1] - sum[0]) / num; + } else { + int num = 0; + for (g=0; g < 8; g++,ip+=2) { /* Average the neighbors */ + if (gval[g] <= thold) { + sum[1] += pix[ip[0] + 1]; + sum[2] += pix[ip[0] + 3]; + if(ip[1]) + sum[0] += (t1 + pix[ip[1]])*0.5f; + num++; + } + } + t1 += (sum[1] - sum[0]) / num; + t2 += (sum[2] - sum[0]) / num; + } + green[row][col] = 0.5f * (t1 + t2); + } + if(plistenerActive) { + if((row % progressStep) == 0) +#ifdef _OPENMP +#pragma omp critical (updateprogress) +#endif +{ + progress += progressInc; + plistener->setProgress (progress); +} + } + } + +} + free (code[0][0]); + free (image); + if(plistenerActive) + plistener->setProgress (0.98); + + // Interpolate R and B +#ifdef _OPENMP +#pragma omp parallel for +#endif + for (int i=0; isetProgress (1.0); +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +#undef fc +#define fc(row,col) \ + (ri->get_filters() >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3) + +#define FORCC for (int c=0; c < colors; c++) + +/* + Patterned Pixel Grouping Interpolation by Alain Desbiolles +*/ +void RawImageSource::ppg_demosaic() +{ + int width=W, height=H; + int dir[5] = { 1, width, -1, -width, 1 }; + int row, col, diff[2], guess[2], c, d, i; + float (*pix)[4]; + + float (*image)[4]; + + if (plistener) { + // looks like ppg isn't supported anymore + //plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::ppg])); + plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), "xxx")); + plistener->setProgress (0.0); + } + + image = (float (*)[4]) calloc (H*W, sizeof *image); + for (int ii=0; ii 0; i++) { + guess[i] = (pix[-d][1] + pix[0][c] + pix[d][1]) * 2 + - pix[-2*d][c] - pix[2*d][c]; + diff[i] = ( ABS(pix[-2*d][c] - pix[ 0][c]) + + ABS(pix[ 2*d][c] - pix[ 0][c]) + + ABS(pix[ -d][1] - pix[ d][1]) ) * 3 + + ( ABS(pix[ 3*d][1] - pix[ d][1]) + + ABS(pix[-3*d][1] - pix[-d][1]) ) * 2; + } + d = dir[i = diff[0] > diff[1]]; + pix[0][1] = ULIM(static_cast(guess[i] >> 2), pix[d][1], pix[-d][1]); + } + if(plistener) plistener->setProgress(0.33*row/(height-3)); + } +/* Calculate red and blue for each green pixel: */ + for (row=1; row < height-1; row++) { + for (col=1+(FC(row,2) & 1), c=FC(row,col+1); col < width-1; col+=2) { + pix = image + row*width+col; + for (i=0; (d=dir[i]) > 0; c=2-c, i++) + pix[0][c] = CLIP(0.5*(pix[-d][c] + pix[d][c] + 2*pix[0][1] + - pix[-d][1] - pix[d][1]) ); + } + if(plistener) plistener->setProgress(0.33 + 0.33*row/(height-1)); + } +/* Calculate blue for red pixels and vice versa: */ + for (row=1; row < height-1; row++) { + for (col=1+(FC(row,1) & 1), c=2-FC(row,col); col < width-1; col+=2) { + pix = image + row*width+col; + for (i=0; (d=dir[i]+dir[i+1]) > 0; i++) { + diff[i] = ABS(pix[-d][c] - pix[d][c]) + + ABS(pix[-d][1] - pix[0][1]) + + ABS(pix[ d][1] - pix[0][1]); + guess[i] = pix[-d][c] + pix[d][c] + 2*pix[0][1] + - pix[-d][1] - pix[d][1]; + } + if (diff[0] != diff[1]) + pix[0][c] = CLIP(guess[diff[0] > diff[1]] /2); + else + pix[0][c] = CLIP((guess[0]+guess[1]) /4); + } + if(plistener) plistener->setProgress(0.67 + 0.33*row/(height-1)); + } + + red(W,H); + for (int i=0; i= border && row < height-border) + col = width-border; + memset (sum, 0, sizeof sum); + for (y=row-1; y != row+2; y++) + for (x=col-1; x != col+2; x++) + if (y < height && x < width) { + f = fc(y,x); + sum[f] += image[y*width+x][f]; + sum[f+4]++; + } + f = fc(row,col); + FORCC if (c != f && sum[c+4]) + image[row*width+col][c] = sum[c] / sum[c+4]; + } +} + +void RawImageSource::border_interpolate2( int winw, int winh, int lborders) +{ +int bord=lborders; +int width=winw; +int height=winh; + for (int i=0; i -1) && (i1 < height) && (j1 > -1)) { + int c = FC(i1,j1); + sum[c] += rawData[i1][j1]; + sum[c+3]++; + } + } + int c=FC(i,j); + if (c==1) { + red[i][j]=sum[0]/sum[3]; + green[i][j]=rawData[i][j]; + blue[i][j]=sum[2]/sum[5]; + } else { + green[i][j]=sum[1]/sum[4]; + if (c==0) { + red[i][j]=rawData[i][j]; + blue[i][j]=sum[2]/sum[5]; + } else { + red[i][j]=sum[0]/sum[3]; + blue[i][j]=rawData[i][j]; + } + } + }//j + + for (int j=width-bord; j -1) && (i1 < height ) && (j1 < width)) { + int c = FC(i1,j1); + sum[c] += rawData[i1][j1]; + sum[c+3]++; + } + } + int c=FC(i,j); + if (c==1) { + red[i][j]=sum[0]/sum[3]; + green[i][j]=rawData[i][j]; + blue[i][j]=sum[2]/sum[5]; + } else { + green[i][j]=sum[1]/sum[4]; + if (c==0) { + red[i][j]=rawData[i][j]; + blue[i][j]=sum[2]/sum[5]; + } else { + red[i][j]=sum[0]/sum[3]; + blue[i][j]=rawData[i][j]; + } + } + }//j + }//i + for (int i=0; i -1) && (i1 < height) && (j1 > -1)) { + int c = FC(i1,j1); + sum[c] += rawData[i1][j1]; + sum[c+3]++; + } + } + int c=FC(i,j); + if (c==1) { + red[i][j]=sum[0]/sum[3]; + green[i][j]=rawData[i][j]; + blue[i][j]=sum[2]/sum[5]; + } else { + green[i][j]=sum[1]/sum[4]; + if (c==0) { + red[i][j]=rawData[i][j]; + blue[i][j]=sum[2]/sum[5]; + } else { + red[i][j]=sum[0]/sum[3]; + blue[i][j]=rawData[i][j]; + } + } + }//j + } + + for (int i=height-bord; i -1) && (i1 < height) && (j1 < width)) { + int c = FC(i1,j1); + sum[c] += rawData[i1][j1]; + sum[c+3]++; + } + } + int c=FC(i,j); + if (c==1) { + red[i][j]=sum[0]/sum[3]; + green[i][j]=rawData[i][j]; + blue[i][j]=sum[2]/sum[5]; + } else { + green[i][j]=sum[1]/sum[4]; + if (c==0) { + red[i][j]=rawData[i][j]; + blue[i][j]=sum[2]/sum[5]; + } else { + red[i][j]=sum[0]/sum[3]; + blue[i][j]=rawData[i][j]; + } + } + }//j + } + +} + +// Joint Demosaicing and Denoising using High Order Interpolation Techniques +// Revision 0.9.1a - 09/02/2010 - Contact info: luis.sanz.rodriguez@gmail.com +// Copyright Luis Sanz Rodriguez 2010 +// Adapted to RT by Jacques Desmis 3/2013 + +void RawImageSource::jdl_interpolate_omp() // from "Lassus" +{ + int width=W, height=H; + int row,col,c,d,i,u=width,v=2*u,w=3*u,x=4*u,y=5*u,z=6*u,indx,(*dif)[2],(*chr)[2]; + float f[4],g[4]; + float (*image)[4]; + image = (float (*)[4]) calloc (width*height, sizeof *image); + dif = (int (*)[2]) calloc(width*height, sizeof *dif); + chr = (int (*)[2]) calloc(width*height, sizeof *chr); + if (plistener) { + // this function seems to be unused + //plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::jdl])); + plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), "xxx")); + plistener->setProgress (0.0); + } + +#ifdef _OPENMP +#pragma omp parallel default(none) shared(image,width,height,u,w,v,y,x,z,dif,chr) private(row,col,f,g,indx,c,d,i) +#endif +{ +#ifdef _OPENMP +#pragma omp for +#endif + for (int ii=0; ii(0.725f*dif[indx][0]+0.1375f*dif[indx-v][0]+0.1375f*dif[indx+v][0],dif[indx-v][0],dif[indx+v][0]); + g[1]=ULIM(0.725f*dif[indx][1]+0.1375f*dif[indx-2][1]+0.1375f*dif[indx+2][1],dif[indx-2][1],dif[indx+2][1]); + chr[indx][c]=(f[1]*g[0]+f[0]*g[1])/(f[0]+f[1]); + } +#ifdef _OPENMP +#pragma omp for +#endif + for (row=6; rowsetProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::lmmse])); + plistener->setProgress (0.0); + } + + + LUTf *gamtab; + if(applyGamma) + gamtab = &(Color::gammatab_24_17a); + else { + gamtab = new LUTf(65536, LUT_CLIP_ABOVE | LUT_CLIP_BELOW); + for(int i=0;i<65536;i++) + (*gamtab)[i] = (float)i / 65535.f; + } + + +#ifdef _OPENMP +#pragma omp parallel private(rix) +#endif +{ +#ifdef _OPENMP +#pragma omp for +#endif + for (int rrr=ba; rrr < rr1-ba; rrr++) { + for (int ccc=ba, row=rrr-ba; ccc < cc1-ba; ccc++) { + int col = ccc - ba; + float *rix = qix[4] + rrr*cc1 + ccc; + rix[0] = (*gamtab)[rawData[row][col]]; + } + } + +#ifdef _OPENMP +#pragma omp single +#endif +{ + if (plistener) plistener->setProgress (0.1); +} + + // G-R(B) +#ifdef _OPENMP +#pragma omp for schedule(dynamic,16) +#endif + for (int rr=2; rr < rr1-2; rr++) { + // G-R(B) at R(B) location + for (int cc=2+(FC(rr,2)&1); cc < cc1-2; cc+=2) { + rix[4] = qix[4] + rr*cc1 + cc; + float v0 = x00625(rix[4][-w1-1]+rix[4][-w1+1]+rix[4][w1-1]+rix[4][w1+1]) +x0250(rix[4][0]); + // horizontal + rix[0] = qix[0] + rr*cc1 + cc; + rix[0][0] = - x0250(rix[4][ -2] + rix[4][ 2])+ xdiv2f(rix[4][ -1] + rix[4][0] + rix[4][ 1]); + float Y = v0 + xdiv2f(rix[0][0]); + if (rix[4][0] > 1.75f*Y) + rix[0][0] = ULIM(rix[0][0],rix[4][ -1],rix[4][ 1]); + else + rix[0][0] = LIM(rix[0][0],0.0f,1.0f); + rix[0][0] -= rix[4][0]; + // vertical + rix[1] = qix[1] + rr*cc1 + cc; + rix[1][0] = -x0250(rix[4][-w2] + rix[4][w2])+ xdiv2f(rix[4][-w1] + rix[4][0] + rix[4][w1]); + Y = v0 + xdiv2f(rix[1][0]); + if (rix[4][0] > 1.75f*Y) + rix[1][0] = ULIM(rix[1][0],rix[4][-w1],rix[4][w1]); + else + rix[1][0] = LIM(rix[1][0],0.0f,1.0f); + rix[1][0] -= rix[4][0]; + } + // G-R(B) at G location + for (int ccc=2+(FC(rr,3)&1); ccc < cc1-2; ccc+=2) { + rix[0] = qix[0] + rr*cc1 + ccc; + rix[1] = qix[1] + rr*cc1 + ccc; + rix[4] = qix[4] + rr*cc1 + ccc; + rix[0][0] = x0250(rix[4][ -2] + rix[4][ 2])- xdiv2f(rix[4][ -1] + rix[4][0] + rix[4][ 1]); + rix[1][0] = x0250(rix[4][-w2] + rix[4][w2])- xdiv2f(rix[4][-w1] + rix[4][0] + rix[4][w1]); + rix[0][0] = LIM(rix[0][0],-1.0f,0.0f) + rix[4][0]; + rix[1][0] = LIM(rix[1][0],-1.0f,0.0f) + rix[4][0]; + } + } +#ifdef _OPENMP +#pragma omp single +#endif +{ + if (plistener) plistener->setProgress (0.2); +} + + + // apply low pass filter on differential colors +#ifdef _OPENMP +#pragma omp for +#endif + for (int rr=4; rr < rr1-4; rr++) + for (int cc=4; cc < cc1-4; cc++) { + rix[0] = qix[0] + rr*cc1 + cc; + rix[2] = qix[2] + rr*cc1 + cc; + rix[2][0] = h0*rix[0][0] + h1*(rix[0][ -1] + rix[0][ 1]) + h2*(rix[0][ -2] + rix[0][ 2]) + h3*(rix[0][ -3] + rix[0][ 3]) + h4*(rix[0][ -4] + rix[0][ 4]); + rix[1] = qix[1] + rr*cc1 + cc; + rix[3] = qix[3] + rr*cc1 + cc; + rix[3][0] = h0*rix[1][0] + h1*(rix[1][-w1] + rix[1][w1]) + h2*(rix[1][-w2] + rix[1][w2]) + h3*(rix[1][-w3] + rix[1][w3]) + h4*(rix[1][-w4] + rix[1][w4]); + } +#ifdef _OPENMP +#pragma omp single +#endif +{ + if (plistener) plistener->setProgress (0.3); +} + + // interpolate G-R(B) at R(B) +#ifdef _OPENMP +#pragma omp for +#endif + for (int rr=4; rr < rr1-4; rr++) { + int cc=4+(FC(rr,4)&1); +#ifdef __SSE2__ + __m128 p1v, p2v, p3v, p4v, p5v, p6v, p7v, p8v, p9v, muv, vxv, vnv, xhv, vhv, xvv, vvv; + __m128 epsv = _mm_set1_ps(1e-7); + __m128 ninev = _mm_set1_ps(9.f); + for (; cc < cc1-10; cc+=8) { + rix[0] = qix[0] + rr*cc1 + cc; + rix[1] = qix[1] + rr*cc1 + cc; + rix[2] = qix[2] + rr*cc1 + cc; + rix[3] = qix[3] + rr*cc1 + cc; + rix[4] = qix[4] + rr*cc1 + cc; + // horizontal + p1v = LC2VFU(rix[2][-4]); + p2v = LC2VFU(rix[2][-3]); + p3v = LC2VFU(rix[2][-2]); + p4v = LC2VFU(rix[2][-1]); + p5v = LC2VFU(rix[2][ 0]); + p6v = LC2VFU(rix[2][ 1]); + p7v = LC2VFU(rix[2][ 2]); + p8v = LC2VFU(rix[2][ 3]); + p9v = LC2VFU(rix[2][ 4]); + muv = (p1v + p2v + p3v + p4v + p5v + p6v + p7v + p8v + p9v) / ninev; + vxv = epsv+SQRV(p1v-muv)+SQRV(p2v-muv)+SQRV(p3v-muv)+SQRV(p4v-muv)+SQRV(p5v-muv)+SQRV(p6v-muv)+SQRV(p7v-muv)+SQRV(p8v-muv)+SQRV(p9v-muv); + p1v -= LC2VFU(rix[0][-4]); + p2v -= LC2VFU(rix[0][-3]); + p3v -= LC2VFU(rix[0][-2]); + p4v -= LC2VFU(rix[0][-1]); + p5v -= LC2VFU(rix[0][ 0]); + p6v -= LC2VFU(rix[0][ 1]); + p7v -= LC2VFU(rix[0][ 2]); + p8v -= LC2VFU(rix[0][ 3]); + p9v -= LC2VFU(rix[0][ 4]); + vnv = epsv+SQRV(p1v)+SQRV(p2v)+SQRV(p3v)+SQRV(p4v)+SQRV(p5v)+SQRV(p6v)+SQRV(p7v)+SQRV(p8v)+SQRV(p9v); + xhv = (LC2VFU(rix[0][0])*vxv + LC2VFU(rix[2][0])*vnv)/(vxv + vnv); + vhv = vxv*vnv/(vxv + vnv); + + // vertical + p1v = LC2VFU(rix[3][-w4]); + p2v = LC2VFU(rix[3][-w3]); + p3v = LC2VFU(rix[3][-w2]); + p4v = LC2VFU(rix[3][-w1]); + p5v = LC2VFU(rix[3][ 0]); + p6v = LC2VFU(rix[3][ w1]); + p7v = LC2VFU(rix[3][ w2]); + p8v = LC2VFU(rix[3][ w3]); + p9v = LC2VFU(rix[3][ w4]); + muv = (p1v + p2v + p3v + p4v + p5v + p6v + p7v + p8v + p9v) / ninev; + vxv = epsv+SQRV(p1v-muv)+SQRV(p2v-muv)+SQRV(p3v-muv)+SQRV(p4v-muv)+SQRV(p5v-muv)+SQRV(p6v-muv)+SQRV(p7v-muv)+SQRV(p8v-muv)+SQRV(p9v-muv); + p1v -= LC2VFU(rix[1][-w4]); + p2v -= LC2VFU(rix[1][-w3]); + p3v -= LC2VFU(rix[1][-w2]); + p4v -= LC2VFU(rix[1][-w1]); + p5v -= LC2VFU(rix[1][ 0]); + p6v -= LC2VFU(rix[1][ w1]); + p7v -= LC2VFU(rix[1][ w2]); + p8v -= LC2VFU(rix[1][ w3]); + p9v -= LC2VFU(rix[1][ w4]); + vnv = epsv+SQRV(p1v)+SQRV(p2v)+SQRV(p3v)+SQRV(p4v)+SQRV(p5v)+SQRV(p6v)+SQRV(p7v)+SQRV(p8v)+SQRV(p9v); + xvv = (LC2VFU(rix[1][0])*vxv + LC2VFU(rix[3][0])*vnv)/(vxv + vnv); + vvv = vxv*vnv/(vxv + vnv); + // interpolated G-R(B) + muv = (xhv*vvv + xvv*vhv)/(vhv + vvv); + STC2VFU(rix[4][0], muv); + } +#endif + for (; cc < cc1-4; cc+=2) { + rix[0] = qix[0] + rr*cc1 + cc; + rix[1] = qix[1] + rr*cc1 + cc; + rix[2] = qix[2] + rr*cc1 + cc; + rix[3] = qix[3] + rr*cc1 + cc; + rix[4] = qix[4] + rr*cc1 + cc; + // horizontal + float p1 = rix[2][-4]; + float p2 = rix[2][-3]; + float p3 = rix[2][-2]; + float p4 = rix[2][-1]; + float p5 = rix[2][ 0]; + float p6 = rix[2][ 1]; + float p7 = rix[2][ 2]; + float p8 = rix[2][ 3]; + float p9 = rix[2][ 4]; + float mu = (p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9) / 9.f; + float vx = 1e-7+SQR(p1-mu)+SQR(p2-mu)+SQR(p3-mu)+SQR(p4-mu)+SQR(p5-mu)+SQR(p6-mu)+SQR(p7-mu)+SQR(p8-mu)+SQR(p9-mu); + p1 -= rix[0][-4]; + p2 -= rix[0][-3]; + p3 -= rix[0][-2]; + p4 -= rix[0][-1]; + p5 -= rix[0][ 0]; + p6 -= rix[0][ 1]; + p7 -= rix[0][ 2]; + p8 -= rix[0][ 3]; + p9 -= rix[0][ 4]; + float vn = 1e-7+SQR(p1)+SQR(p2)+SQR(p3)+SQR(p4)+SQR(p5)+SQR(p6)+SQR(p7)+SQR(p8)+SQR(p9); + float xh = (rix[0][0]*vx + rix[2][0]*vn)/(vx + vn); + float vh = vx*vn/(vx + vn); + + // vertical + p1 = rix[3][-w4]; + p2 = rix[3][-w3]; + p3 = rix[3][-w2]; + p4 = rix[3][-w1]; + p5 = rix[3][ 0]; + p6 = rix[3][ w1]; + p7 = rix[3][ w2]; + p8 = rix[3][ w3]; + p9 = rix[3][ w4]; + mu = (p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8 + p9) / 9.f; + vx = 1e-7+SQR(p1-mu)+SQR(p2-mu)+SQR(p3-mu)+SQR(p4-mu)+SQR(p5-mu)+SQR(p6-mu)+SQR(p7-mu)+SQR(p8-mu)+SQR(p9-mu); + p1 -= rix[1][-w4]; + p2 -= rix[1][-w3]; + p3 -= rix[1][-w2]; + p4 -= rix[1][-w1]; + p5 -= rix[1][ 0]; + p6 -= rix[1][ w1]; + p7 -= rix[1][ w2]; + p8 -= rix[1][ w3]; + p9 -= rix[1][ w4]; + vn = 1e-7+SQR(p1)+SQR(p2)+SQR(p3)+SQR(p4)+SQR(p5)+SQR(p6)+SQR(p7)+SQR(p8)+SQR(p9); + float xv = (rix[1][0]*vx + rix[3][0]*vn)/(vx + vn); + float vv = vx*vn/(vx + vn); + // interpolated G-R(B) + rix[4][0] = (xh*vv + xv*vh)/(vh + vv); + } + } + +#ifdef _OPENMP +#pragma omp single +#endif +{ + if (plistener) plistener->setProgress (0.4); +} + + // copy CFA values +#ifdef _OPENMP +#pragma omp for +#endif + for (int rr=0; rr < rr1; rr++) + for (int cc=0, row=rr-ba; cc < cc1; cc++) { + int col=cc-ba; + int c = FC(rr,cc); + rix[c] = qix[c] + rr*cc1 + cc; + if ((row >= 0) & (row < height) & (col >= 0) & (col < width)) { + rix[c][0] = (*gamtab)[rawData[row][col]]; + } + else + rix[c][0] = 0.f; + if (c != 1) { + rix[1] = qix[1] + rr*cc1 + cc; + rix[4] = qix[4] + rr*cc1 + cc; + rix[1][0] = rix[c][0] + rix[4][0]; + } + } + +#ifdef _OPENMP +#pragma omp single +#endif +{ + if (plistener) plistener->setProgress (0.5); +} + + // bilinear interpolation for R/B + // interpolate R/B at G location +#ifdef _OPENMP +#pragma omp for +#endif + for (int rr=1; rr < rr1-1; rr++) + for (int cc=1+(FC(rr,2)&1), c=FC(rr,cc+1); cc < cc1-1; cc+=2) { + rix[c] = qix[c] + rr*cc1 + cc; + rix[1] = qix[1] + rr*cc1 + cc; + rix[c][0] = rix[1][0] + xdiv2f(rix[c][ -1] - rix[1][ -1] + rix[c][ 1] - rix[1][ 1]); + c = 2 - c; + rix[c] = qix[c] + rr*cc1 + cc; + rix[c][0] = rix[1][0]+ xdiv2f(rix[c][-w1] - rix[1][-w1] + rix[c][w1] - rix[1][w1]); + c = 2 - c; + } + +#ifdef _OPENMP +#pragma omp single +#endif +{ + if (plistener) plistener->setProgress (0.6); +} + + // interpolate R/B at B/R location +#ifdef _OPENMP +#pragma omp for +#endif + for (int rr=1; rr < rr1-1; rr++) + for (int cc=1+(FC(rr,1)&1), c=2-FC(rr,cc); cc < cc1-1; cc+=2) { + rix[c] = qix[c] + rr*cc1 + cc; + rix[1] = qix[1] + rr*cc1 + cc; + rix[c][0] = rix[1][0]+ x0250(rix[c][-w1] - rix[1][-w1] + rix[c][ -1] - rix[1][ -1]+ rix[c][ 1] - rix[1][ 1] + rix[c][ w1] - rix[1][ w1]); + } + +#ifdef _OPENMP +#pragma omp single +#endif +{ + if (plistener) plistener->setProgress (0.7); +} + +}// End of parallelization 1 + + // median filter/ + for (int pass=0; pass < iter; pass++) { + // Apply 3x3 median filter + // Compute median(R-G) and median(B-G) + +#ifdef _OPENMP +#pragma omp parallel for private(rix) +#endif + for (int rr=1; rr < rr1-1; rr++) { + for (int c=0; c < 3; c+=2) { + int d = c + 3 - (c == 0 ? 0 : 1); + int cc=1; +#ifdef __SSE2__ + __m128 p1v,p2v,p3v,p4v,p5v,p6v,p7v,p8v,p9v,tempv; + for (; cc < cc1-4; cc+=4) { + rix[d] = qix[d] + rr*cc1 + cc; + rix[c] = qix[c] + rr*cc1 + cc; + rix[1] = qix[1] + rr*cc1 + cc; + // Assign 3x3 differential color values + p1v = LVFU(rix[c][-w1-1])-LVFU(rix[1][-w1-1]); p2v = LVFU(rix[c][-w1])-LVFU(rix[1][-w1]); p3v = LVFU(rix[c][-w1+1])-LVFU(rix[1][-w1+1]); + p4v = LVFU(rix[c][ -1])-LVFU(rix[1][ -1]); p5v = LVFU(rix[c][ 0])-LVFU(rix[1][ 0]); p6v = LVFU(rix[c][ 1])-LVFU(rix[1][ 1]); + p7v = LVFU(rix[c][ w1-1])-LVFU(rix[1][ w1-1]); p8v = LVFU(rix[c][ w1])-LVFU(rix[1][ w1]); p9v = LVFU(rix[c][ w1+1])-LVFU(rix[1][ w1+1]); + // Sort for median of 9 values + PIX_SORTV(p2v,p3v); PIX_SORTV(p5v,p6v); PIX_SORTV(p8v,p9v); + PIX_SORTV(p1v,p2v); PIX_SORTV(p4v,p5v); PIX_SORTV(p7v,p8v); + PIX_SORTV(p2v,p3v); PIX_SORTV(p5v,p6v); PIX_SORTV(p8v,p9v); + p4v = _mm_max_ps(p1v,p4v); p6v = _mm_min_ps(p6v,p9v); PIX_SORTV(p5v,p8v); + p7v = _mm_max_ps(p4v,p7v); p5v = _mm_max_ps(p5v,p2v); p3v = _mm_min_ps(p3v,p6v); + p5v = _mm_min_ps(p5v,p8v); PIX_SORTV(p5v,p3v); p5v = _mm_max_ps(p7v,p5v); + p5v = _mm_min_ps(p3v,p5v); + _mm_storeu_ps(&rix[d][0], p5v); + } +#endif + for (; cc < cc1-1; cc++) { + float temp; + rix[d] = qix[d] + rr*cc1 + cc; + rix[c] = qix[c] + rr*cc1 + cc; + rix[1] = qix[1] + rr*cc1 + cc; + // Assign 3x3 differential color values + float p1 = rix[c][-w1-1]-rix[1][-w1-1]; float p2 = rix[c][-w1]-rix[1][-w1]; float p3 = rix[c][-w1+1]-rix[1][-w1+1]; + float p4 = rix[c][ -1]-rix[1][ -1]; float p5 = rix[c][ 0]-rix[1][ 0]; float p6 = rix[c][ 1]-rix[1][ 1]; + float p7 = rix[c][ w1-1]-rix[1][ w1-1]; float p8 = rix[c][ w1]-rix[1][ w1]; float p9 = rix[c][ w1+1]-rix[1][ w1+1]; + // Sort for median of 9 values + PIX_SORT(p2,p3); PIX_SORT(p5,p6); PIX_SORT(p8,p9); + PIX_SORT(p1,p2); PIX_SORT(p4,p5); PIX_SORT(p7,p8); + PIX_SORT(p2,p3); PIX_SORT(p5,p6); PIX_SORT(p8,p9); + PIX_SORT(p1,p4); PIX_SORT(p6,p9); PIX_SORT(p5,p8); + PIX_SORT(p4,p7); PIX_SORT(p2,p5); PIX_SORT(p3,p6); + PIX_SORT(p5,p8); PIX_SORT(p5,p3); PIX_SORT(p7,p5); + PIX_SORT(p5,p3); + rix[d][0] = p5; + } + } + } + + // red/blue at GREEN pixel locations & red/blue and green at BLUE/RED pixel locations +#ifdef _OPENMP +#pragma omp parallel for private (rix) +#endif + for (int rr=0; rr < rr1; rr++) { + rix[0] = qix[0] + rr*cc1; + rix[1] = qix[1] + rr*cc1; + rix[2] = qix[2] + rr*cc1; + rix[3] = qix[3] + rr*cc1; + rix[4] = qix[4] + rr*cc1; + int c0 = FC(rr,0); + int c1 = FC(rr,1); + if(c0 == 1){ + c1 = 2 - c1; + int d = c1 + 3 - (c1 == 0 ? 0 : 1); + int cc; + for (cc=0; cc < cc1-1; cc+=2) { + rix[0][0] = rix[1][0] + rix[3][0]; + rix[2][0] = rix[1][0] + rix[4][0]; + rix[0]++; rix[1]++; rix[2]++; rix[3]++; rix[4]++; + rix[c1][0] = rix[1][0] + rix[d][0]; + rix[1][0] = 0.5f * (rix[0][0] - rix[3][0] + rix[2][0] - rix[4][0]); + rix[0]++; rix[1]++; rix[2]++; rix[3]++; rix[4]++; + } + if(cc < cc1) { // remaining pixel, only if width is odd + rix[0][0] = rix[1][0] + rix[3][0]; + rix[2][0] = rix[1][0] + rix[4][0]; + } + } else { + c0 = 2 - c0; + int d = c0 + 3 - (c0 == 0 ? 0 : 1); + int cc; + for (cc=0; cc < cc1-1; cc+=2) { + rix[c0][0] = rix[1][0] + rix[d][0]; + rix[1][0] = 0.5f * (rix[0][0] - rix[3][0] + rix[2][0] - rix[4][0]); + rix[0]++; rix[1]++; rix[2]++; rix[3]++; rix[4]++; + rix[0][0] = rix[1][0] + rix[3][0]; + rix[2][0] = rix[1][0] + rix[4][0]; + rix[0]++; rix[1]++; rix[2]++; rix[3]++; rix[4]++; + } + if(cc < cc1) { // remaining pixel, only if width is odd + rix[c0][0] = rix[1][0] + rix[d][0]; + rix[1][0] = 0.5f * (rix[0][0] - rix[3][0] + rix[2][0] - rix[4][0]); + } + } + } + } + + if (plistener) plistener->setProgress (0.8); + + if(applyGamma) + gamtab = &(Color::igammatab_24_17); + else { + for(int i=0;i<65536;i++) + (*gamtab)[i] = (float)i + 0.5f; + } + + array2D (*rgb[3]); + rgb[0] = &red; + rgb[1] = &green; + rgb[2] = &blue; + + // copy result back to image matrix +#ifdef _OPENMP +#pragma omp parallel for +#endif + for (int row=0; row < height; row++) { + for (int col=0, rr=row+ba; col < width; col++) { + int cc = col+ba; + int c = FC(row,col); + for (int ii=0; ii < 3; ii++) + if (ii != c) { + float *rix = qix[ii] + rr*cc1 + cc; + (*(rgb[ii]))[row][col] = (*gamtab)[65535.f*rix[0]]; + } else { + (*(rgb[ii]))[row][col] = CLIP(rawData[row][col]); + } + } + } + + if (plistener) plistener->setProgress (1.0); + if(buffer) + free(buffer); + else + for(int i=0;i<5;i++) + free(qix[i]); + + if(!applyGamma) + delete gamtab; + + if(iterations > 4 && iterations <=6) refinement(passref); + else if(iterations > 6) refinement_lassus(passref); + +} + +/*** +* +* Bayer CFA Demosaicing using Integrated Gaussian Vector on Color Differences +* Revision 1.0 - 2013/02/28 +* +* Copyright (c) 2007-2013 Luis Sanz Rodriguez +* Using High Order Interpolation technique by Jim S, Jimmy Li, and Sharmil Randhawa +* +* Contact info: luis.sanz.rodriguez@gmail.com +* +* This code is distributed under a GNU General Public License, version 3. +* Visit for more information. +* +***/ +// Adapted to RT by Jacques Desmis 3/2013 +// SSE version by Ingo Weyrich 5/2013 +#ifdef __SSE2__ +#define CLIPV(a) LIMV(a,zerov,c65535v) +SSEFUNCTION void RawImageSource::igv_interpolate(int winw, int winh) +{ + static const float eps=1e-5f, epssq=1e-5f;//mod epssq -10f =>-5f Jacques 3/2013 to prevent artifact (divide by zero) + + static const int h1=1, h2=2, h3=3, h5=5; + const int width=winw, height=winh; + const int v1=1*width, v2=2*width, v3=3*width, v5=5*width; + float* rgb[2]; + float* chr[4]; + float *rgbarray, *vdif, *hdif, *chrarray; + rgbarray = (float (*)) malloc((width*height) * sizeof( float ) ); + rgb[0] = rgbarray; + rgb[1] = rgbarray + (width*height)/2; + + vdif = (float (*)) calloc( width*height/2, sizeof *vdif ); + hdif = (float (*)) calloc( width*height/2, sizeof *hdif ); + + chrarray = (float (*)) calloc( width*height, sizeof( float ) ); + chr[0] = chrarray; + chr[1] = chrarray + (width*height)/2; + + // mapped chr[2] and chr[3] to hdif and hdif, because these are out of use, when chr[2] and chr[3] are used + chr[2] = hdif; + chr[3] = vdif; + + border_interpolate2(winw,winh,7); + + if (plistener) { + plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::igv])); + plistener->setProgress (0.0); + } +#ifdef _OPENMP +#pragma omp parallel default(none) shared(rgb,vdif,hdif,chr) +#endif +{ + __m128 ngv, egv, wgv, sgv, nvv, evv, wvv, svv, nwgv, negv, swgv, segv, nwvv, nevv, swvv, sevv,tempv,temp1v,temp2v,temp3v,temp4v,temp5v,temp6v,temp7v,temp8v; + __m128 epsv = _mm_set1_ps( eps ); + __m128 epssqv = _mm_set1_ps( epssq ); + __m128 c65535v = _mm_set1_ps( 65535.f ); + __m128 c23v = _mm_set1_ps( 23.f ); + __m128 c40v = _mm_set1_ps( 40.f ); + __m128 c51v = _mm_set1_ps( 51.f ); + __m128 c32v = _mm_set1_ps( 32.f ); + __m128 c8v = _mm_set1_ps( 8.f ); + __m128 c7v = _mm_set1_ps( 7.f ); + __m128 c6v = _mm_set1_ps( 6.f ); + __m128 c10v = _mm_set1_ps( 10.f ); + __m128 c21v = _mm_set1_ps( 21.f ); + __m128 c78v = _mm_set1_ps( 78.f ); + __m128 c69v = _mm_set1_ps( 69.f ); + __m128 c3145680v = _mm_set1_ps( 3145680.f ); + __m128 onev = _mm_set1_ps ( 1.f ); + __m128 zerov = _mm_set1_ps ( 0.f ); + __m128 d725v = _mm_set1_ps ( 0.725f ); + __m128 d1375v = _mm_set1_ps ( 0.1375f ); + + float *dest1, *dest2; + float ng, eg, wg, sg, nv, ev, wv, sv, nwg, neg, swg, seg, nwv, nev, swv, sev; +#ifdef _OPENMP +#pragma omp for +#endif + for (int row=0; row>1], tempv ); + tempv = _mm_shuffle_ps( temp1v, temp2v, _MM_SHUFFLE( 3,1,3,1 ) ); + _mm_storeu_ps( &dest2[indx>>1], tempv ); + } + for (; col>1] = CLIP(rawData[row][col]); //rawData = RT datas + col++; + dest2[indx>>1] = CLIP(rawData[row][col]); //rawData = RT datas + } + } +#ifdef _OPENMP +#pragma omp single +#endif +{ + if (plistener) plistener->setProgress (0.13); +} + +#ifdef _OPENMP +#pragma omp for +#endif + for (int row=5; row>1; col>1])-LVFU(rgb[1][(indx-v3)>>1]))+vabsf(LVFU(rgb[0][indx1])-LVFU(rgb[0][(indx1-v1)])))/c65535v); + egv=(epsv+(vabsf(LVFU(rgb[1][(indx+h1)>>1])-LVFU(rgb[1][(indx+h3)>>1]))+vabsf(LVFU(rgb[0][indx1])-LVFU(rgb[0][(indx1+h1)])))/c65535v); + wgv=(epsv+(vabsf(LVFU(rgb[1][(indx-h1)>>1])-LVFU(rgb[1][(indx-h3)>>1]))+vabsf(LVFU(rgb[0][indx1])-LVFU(rgb[0][(indx1-h1)])))/c65535v); + sgv=(epsv+(vabsf(LVFU(rgb[1][(indx+v1)>>1])-LVFU(rgb[1][(indx+v3)>>1]))+vabsf(LVFU(rgb[0][indx1])-LVFU(rgb[0][(indx1+v1)])))/c65535v); + //N,E,W,S High Order Interpolation (Li & Randhawa) + //N,E,W,S Hamilton Adams Interpolation + // (48.f * 65535.f) = 3145680.f + tempv = c40v*LVFU(rgb[0][indx1]); + nvv=LIMV(((c23v*LVFU(rgb[1][(indx-v1)>>1])+c23v*LVFU(rgb[1][(indx-v3)>>1])+LVFU(rgb[1][(indx-v5)>>1])+LVFU(rgb[1][(indx+v1)>>1])+tempv-c32v*LVFU(rgb[0][(indx1-v1)])-c8v*LVFU(rgb[0][(indx1-v2)])))/c3145680v, zerov, onev); + evv=LIMV(((c23v*LVFU(rgb[1][(indx+h1)>>1])+c23v*LVFU(rgb[1][(indx+h3)>>1])+LVFU(rgb[1][(indx+h5)>>1])+LVFU(rgb[1][(indx-h1)>>1])+tempv-c32v*LVFU(rgb[0][(indx1+h1)])-c8v*LVFU(rgb[0][(indx1+h2)])))/c3145680v, zerov, onev); + wvv=LIMV(((c23v*LVFU(rgb[1][(indx-h1)>>1])+c23v*LVFU(rgb[1][(indx-h3)>>1])+LVFU(rgb[1][(indx-h5)>>1])+LVFU(rgb[1][(indx+h1)>>1])+tempv-c32v*LVFU(rgb[0][(indx1-h1)])-c8v*LVFU(rgb[0][(indx1-h2)])))/c3145680v, zerov, onev); + svv=LIMV(((c23v*LVFU(rgb[1][(indx+v1)>>1])+c23v*LVFU(rgb[1][(indx+v3)>>1])+LVFU(rgb[1][(indx+v5)>>1])+LVFU(rgb[1][(indx-v1)>>1])+tempv-c32v*LVFU(rgb[0][(indx1+v1)])-c8v*LVFU(rgb[0][(indx1+v2)])))/c3145680v, zerov, onev); + //Horizontal and vertical color differences + tempv = LVFU( rgb[0][indx1] ) / c65535v; + _mm_storeu_ps( &vdif[indx1], (sgv*nvv+ngv*svv)/(ngv+sgv)- tempv ); + _mm_storeu_ps( &hdif[indx1], (wgv*evv+egv*wvv)/(egv+wgv)- tempv ); + } + // borders without SSE + for (; col>1]-rgb[1][(indx-v3)>>1])+fabsf(rgb[0][indx1]-rgb[0][(indx1-v1)]))/65535.f);; + eg=(eps+(fabsf(rgb[1][(indx+h1)>>1]-rgb[1][(indx+h3)>>1])+fabsf(rgb[0][indx1]-rgb[0][(indx1+h1)]))/65535.f); + wg=(eps+(fabsf(rgb[1][(indx-h1)>>1]-rgb[1][(indx-h3)>>1])+fabsf(rgb[0][indx1]-rgb[0][(indx1-h1)]))/65535.f); + sg=(eps+(fabsf(rgb[1][(indx+v1)>>1]-rgb[1][(indx+v3)>>1])+fabsf(rgb[0][indx1]-rgb[0][(indx1+v1)]))/65535.f); + //N,E,W,S High Order Interpolation (Li & Randhawa) + //N,E,W,S Hamilton Adams Interpolation + // (48.f * 65535.f) = 3145680.f + nv=LIM(((23.0f*rgb[1][(indx-v1)>>1]+23.0f*rgb[1][(indx-v3)>>1]+rgb[1][(indx-v5)>>1]+rgb[1][(indx+v1)>>1]+40.0f*rgb[0][indx1]-32.0f*rgb[0][(indx1-v1)]-8.0f*rgb[0][(indx1-v2)]))/3145680.f, 0.0f, 1.0f); + ev=LIM(((23.0f*rgb[1][(indx+h1)>>1]+23.0f*rgb[1][(indx+h3)>>1]+rgb[1][(indx+h5)>>1]+rgb[1][(indx-h1)>>1]+40.0f*rgb[0][indx1]-32.0f*rgb[0][(indx1+h1)]-8.0f*rgb[0][(indx1+h2)]))/3145680.f, 0.0f, 1.0f); + wv=LIM(((23.0f*rgb[1][(indx-h1)>>1]+23.0f*rgb[1][(indx-h3)>>1]+rgb[1][(indx-h5)>>1]+rgb[1][(indx+h1)>>1]+40.0f*rgb[0][indx1]-32.0f*rgb[0][(indx1-h1)]-8.0f*rgb[0][(indx1-h2)]))/3145680.f, 0.0f, 1.0f); + sv=LIM(((23.0f*rgb[1][(indx+v1)>>1]+23.0f*rgb[1][(indx+v3)>>1]+rgb[1][(indx+v5)>>1]+rgb[1][(indx-v1)>>1]+40.0f*rgb[0][indx1]-32.0f*rgb[0][(indx1+v1)]-8.0f*rgb[0][(indx1+v2)]))/3145680.f, 0.0f, 1.0f); + //Horizontal and vertical color differences + vdif[indx1]=(sg*nv+ng*sv)/(ng+sg)-(rgb[0][indx1])/65535.f; + hdif[indx1]=(wg*ev+eg*wv)/(eg+wg)-(rgb[0][indx1])/65535.f; + } + } +#ifdef _OPENMP +#pragma omp single +#endif +{ + if (plistener) plistener->setProgress (0.26); +} +#ifdef _OPENMP +#pragma omp for +#endif + for (int row=7; row>1, d=FC(row,col)/2; colsetProgress (0.39); +} +#ifdef _OPENMP +#pragma omp for +#endif + for (int row=7; row>1])-LVFU(chr[c][(indx-v3-h3)>>1]))+vabsf(LVFU(chr[c][(indx+v1+h1)>>1])-LVFU(chr[c][(indx-v3-h3)>>1]))); + negv=onev/(epsv+vabsf(LVFU(chr[c][(indx-v1+h1)>>1])-LVFU(chr[c][(indx-v3+h3)>>1]))+vabsf(LVFU(chr[c][(indx+v1-h1)>>1])-LVFU(chr[c][(indx-v3+h3)>>1]))); + swgv=onev/(epsv+vabsf(LVFU(chr[c][(indx+v1-h1)>>1])-LVFU(chr[c][(indx+v3+h3)>>1]))+vabsf(LVFU(chr[c][(indx-v1+h1)>>1])-LVFU(chr[c][(indx+v3-h3)>>1]))); + segv=onev/(epsv+vabsf(LVFU(chr[c][(indx+v1+h1)>>1])-LVFU(chr[c][(indx+v3-h3)>>1]))+vabsf(LVFU(chr[c][(indx-v1-h1)>>1])-LVFU(chr[c][(indx+v3+h3)>>1]))); + //Limit NW,NE,SW,SE Color differences + nwvv=ULIMV(LVFU(chr[c][(indx-v1-h1)>>1]),LVFU(chr[c][(indx-v3-h1)>>1]),LVFU(chr[c][(indx-v1-h3)>>1])); + nevv=ULIMV(LVFU(chr[c][(indx-v1+h1)>>1]),LVFU(chr[c][(indx-v3+h1)>>1]),LVFU(chr[c][(indx-v1+h3)>>1])); + swvv=ULIMV(LVFU(chr[c][(indx+v1-h1)>>1]),LVFU(chr[c][(indx+v3-h1)>>1]),LVFU(chr[c][(indx+v1-h3)>>1])); + sevv=ULIMV(LVFU(chr[c][(indx+v1+h1)>>1]),LVFU(chr[c][(indx+v3+h1)>>1]),LVFU(chr[c][(indx+v1+h3)>>1])); + //Interpolate chrominance: R@B and B@R + tempv = (nwgv*nwvv+negv*nevv+swgv*swvv+segv*sevv)/(nwgv+negv+swgv+segv); + _mm_storeu_ps( &(chr[c][indx>>1]), tempv); + } + for (; col>1]-chr[c][(indx-v3-h3)>>1])+fabsf(chr[c][(indx+v1+h1)>>1]-chr[c][(indx-v3-h3)>>1])); + neg=1.0f/(eps+fabsf(chr[c][(indx-v1+h1)>>1]-chr[c][(indx-v3+h3)>>1])+fabsf(chr[c][(indx+v1-h1)>>1]-chr[c][(indx-v3+h3)>>1])); + swg=1.0f/(eps+fabsf(chr[c][(indx+v1-h1)>>1]-chr[c][(indx+v3+h3)>>1])+fabsf(chr[c][(indx-v1+h1)>>1]-chr[c][(indx+v3-h3)>>1])); + seg=1.0f/(eps+fabsf(chr[c][(indx+v1+h1)>>1]-chr[c][(indx+v3-h3)>>1])+fabsf(chr[c][(indx-v1-h1)>>1]-chr[c][(indx+v3+h3)>>1])); + //Limit NW,NE,SW,SE Color differences + nwv=ULIM(chr[c][(indx-v1-h1)>>1],chr[c][(indx-v3-h1)>>1],chr[c][(indx-v1-h3)>>1]); + nev=ULIM(chr[c][(indx-v1+h1)>>1],chr[c][(indx-v3+h1)>>1],chr[c][(indx-v1+h3)>>1]); + swv=ULIM(chr[c][(indx+v1-h1)>>1],chr[c][(indx+v3-h1)>>1],chr[c][(indx+v1-h3)>>1]); + sev=ULIM(chr[c][(indx+v1+h1)>>1],chr[c][(indx+v3+h1)>>1],chr[c][(indx+v1+h3)>>1]); + //Interpolate chrominance: R@B and B@R + chr[c][indx>>1]=(nwg*nwv+neg*nev+swg*swv+seg*sev)/(nwg+neg+swg+seg); + } + } +#ifdef _OPENMP +#pragma omp single +#endif +{ + if (plistener) plistener->setProgress (0.65); +} +#ifdef _OPENMP +#pragma omp for +#endif + for (int row=7; row>1])-LVFU(chr[0][(indx-v3)>>1]))+vabsf(LVFU(chr[0][(indx+v1)>>1])-LVFU(chr[0][(indx-v3)>>1]))); + egv=onev/(epsv+vabsf(LVFU(chr[0][(indx+h1)>>1])-LVFU(chr[0][(indx+h3)>>1]))+vabsf(LVFU(chr[0][(indx-h1)>>1])-LVFU(chr[0][(indx+h3)>>1]))); + wgv=onev/(epsv+vabsf(LVFU(chr[0][(indx-h1)>>1])-LVFU(chr[0][(indx-h3)>>1]))+vabsf(LVFU(chr[0][(indx+h1)>>1])-LVFU(chr[0][(indx-h3)>>1]))); + sgv=onev/(epsv+vabsf(LVFU(chr[0][(indx+v1)>>1])-LVFU(chr[0][(indx+v3)>>1]))+vabsf(LVFU(chr[0][(indx-v1)>>1])-LVFU(chr[0][(indx+v3)>>1]))); + //Interpolate chrominance: R@G and B@G + tempv = ((ngv*LVFU(chr[0][(indx-v1)>>1])+egv*LVFU(chr[0][(indx+h1)>>1])+wgv*LVFU(chr[0][(indx-h1)>>1])+sgv*LVFU(chr[0][(indx+v1)>>1]))/(ngv+egv+wgv+sgv)); + _mm_storeu_ps( &chr[0+2][indx>>1], tempv); + } + for (; col>1]-chr[0][(indx-v3)>>1])+fabsf(chr[0][(indx+v1)>>1]-chr[0][(indx-v3)>>1])); + eg=1.0f/(eps+fabsf(chr[0][(indx+h1)>>1]-chr[0][(indx+h3)>>1])+fabsf(chr[0][(indx-h1)>>1]-chr[0][(indx+h3)>>1])); + wg=1.0f/(eps+fabsf(chr[0][(indx-h1)>>1]-chr[0][(indx-h3)>>1])+fabsf(chr[0][(indx+h1)>>1]-chr[0][(indx-h3)>>1])); + sg=1.0f/(eps+fabsf(chr[0][(indx+v1)>>1]-chr[0][(indx+v3)>>1])+fabsf(chr[0][(indx-v1)>>1]-chr[0][(indx+v3)>>1])); + //Interpolate chrominance: R@G and B@G + chr[0+2][indx>>1]=((ng*chr[0][(indx-v1)>>1]+eg*chr[0][(indx+h1)>>1]+wg*chr[0][(indx-h1)>>1]+sg*chr[0][(indx+v1)>>1])/(ng+eg+wg+sg)); + } + } +#ifdef _OPENMP +#pragma omp single +#endif +{ + if (plistener) plistener->setProgress (0.78); +} +#ifdef _OPENMP +#pragma omp for +#endif + for (int row=7; row>1])-LVFU(chr[1][(indx-v3)>>1]))+vabsf(LVFU(chr[1][(indx+v1)>>1])-LVFU(chr[1][(indx-v3)>>1]))); + egv=onev/(epsv+vabsf(LVFU(chr[1][(indx+h1)>>1])-LVFU(chr[1][(indx+h3)>>1]))+vabsf(LVFU(chr[1][(indx-h1)>>1])-LVFU(chr[1][(indx+h3)>>1]))); + wgv=onev/(epsv+vabsf(LVFU(chr[1][(indx-h1)>>1])-LVFU(chr[1][(indx-h3)>>1]))+vabsf(LVFU(chr[1][(indx+h1)>>1])-LVFU(chr[1][(indx-h3)>>1]))); + sgv=onev/(epsv+vabsf(LVFU(chr[1][(indx+v1)>>1])-LVFU(chr[1][(indx+v3)>>1]))+vabsf(LVFU(chr[1][(indx-v1)>>1])-LVFU(chr[1][(indx+v3)>>1]))); + //Interpolate chrominance: R@G and B@G + tempv = ((ngv*LVFU(chr[1][(indx-v1)>>1])+egv*LVFU(chr[1][(indx+h1)>>1])+wgv*LVFU(chr[1][(indx-h1)>>1])+sgv*LVFU(chr[1][(indx+v1)>>1]))/(ngv+egv+wgv+sgv)); + _mm_storeu_ps( &chr[1+2][indx>>1], tempv); + } + for (; col>1]-chr[1][(indx-v3)>>1])+fabsf(chr[1][(indx+v1)>>1]-chr[1][(indx-v3)>>1])); + eg=1.0f/(eps+fabsf(chr[1][(indx+h1)>>1]-chr[1][(indx+h3)>>1])+fabsf(chr[1][(indx-h1)>>1]-chr[1][(indx+h3)>>1])); + wg=1.0f/(eps+fabsf(chr[1][(indx-h1)>>1]-chr[1][(indx-h3)>>1])+fabsf(chr[1][(indx+h1)>>1]-chr[1][(indx-h3)>>1])); + sg=1.0f/(eps+fabsf(chr[1][(indx+v1)>>1]-chr[1][(indx+v3)>>1])+fabsf(chr[1][(indx-v1)>>1]-chr[1][(indx+v3)>>1])); + //Interpolate chrominance: R@G and B@G + chr[1+2][indx>>1]=((ng*chr[1][(indx-v1)>>1]+eg*chr[1][(indx+h1)>>1]+wg*chr[1][(indx-h1)>>1]+sg*chr[1][(indx+v1)>>1])/(ng+eg+wg+sg)); + } + } +#ifdef _OPENMP +#pragma omp single +#endif +{ + if (plistener) plistener->setProgress (0.91); +} + float *src1, *src2, *redsrc0, *redsrc1, *bluesrc0, *bluesrc1; +#ifdef _OPENMP +#pragma omp for +#endif + for(int row=7; row>1] ); + temp2v = LVFU( src2[(indx+1)>>1] ); + tempv = _mm_shuffle_ps( temp1v, temp2v, _MM_SHUFFLE( 1,0,1,0 ) ); + tempv = _mm_shuffle_ps( tempv, tempv, _MM_SHUFFLE( 3,1,2,0 ) ); + _mm_storeu_ps( &green[row][col], CLIPV( tempv )); + temp5v = LVFU(redsrc0[indx>>1]); + temp6v = LVFU(redsrc1[(indx+1)>>1]); + temp3v = _mm_shuffle_ps( temp5v, temp6v, _MM_SHUFFLE( 1,0,1,0 ) ); + temp3v = _mm_shuffle_ps( temp3v, temp3v, _MM_SHUFFLE( 3,1,2,0 ) ); + temp3v = CLIPV( tempv - c65535v * temp3v ); + _mm_storeu_ps( &red[row][col], temp3v); + temp7v = LVFU(bluesrc0[indx>>1]); + temp8v = LVFU(bluesrc1[(indx+1)>>1]); + temp4v = _mm_shuffle_ps( temp7v, temp8v, _MM_SHUFFLE( 1,0,1,0 ) ); + temp4v = _mm_shuffle_ps( temp4v, temp4v, _MM_SHUFFLE( 3,1,2,0 ) ); + temp4v = CLIPV( tempv - c65535v * temp4v ); + _mm_storeu_ps( &blue[row][col], temp4v); + + tempv = _mm_shuffle_ps( temp1v, temp2v, _MM_SHUFFLE( 3,2,3,2 ) ); + tempv = _mm_shuffle_ps( tempv, tempv, _MM_SHUFFLE( 3,1,2,0 ) ); + _mm_storeu_ps( &green[row][col+4], CLIPV( tempv )); + + temp3v = _mm_shuffle_ps( temp5v, temp6v, _MM_SHUFFLE( 3,2,3,2 ) ); + temp3v = _mm_shuffle_ps( temp3v, temp3v, _MM_SHUFFLE( 3,1,2,0 ) ); + temp3v = CLIPV( tempv - c65535v * temp3v ); + _mm_storeu_ps( &red[row][col+4], temp3v); + temp4v = _mm_shuffle_ps( temp7v, temp8v, _MM_SHUFFLE( 3,2,3,2 ) ); + temp4v = _mm_shuffle_ps( temp4v, temp4v, _MM_SHUFFLE( 3,1,2,0 ) ); + temp4v = CLIPV( tempv - c65535v * temp4v ); + _mm_storeu_ps( &blue[row][col+4], temp4v); + } + + for(; col>1]-65535.f*redsrc0[indx>>1]); + green[row][col] = CLIP(src1[indx>>1]); + blue [row][col] = CLIP(src1[indx>>1]-65535.f*bluesrc0[indx>>1]); + col++; + red [row][col] = CLIP(src2[(indx+1)>>1]-65535.f*redsrc1[(indx+1)>>1]); + green[row][col] = CLIP(src2[(indx+1)>>1]); + blue [row][col] = CLIP(src2[(indx+1)>>1]-65535.f*bluesrc1[(indx+1)>>1]); + } + } +}// End of parallelization + if (plistener) plistener->setProgress (1.0); + + free(chrarray); free(rgbarray); + free(vdif); free(hdif); +} +#undef CLIPV +#else +void RawImageSource::igv_interpolate(int winw, int winh) +{ + static const float eps=1e-5f, epssq=1e-5f;//mod epssq -10f =>-5f Jacques 3/2013 to prevent artifact (divide by zero) + static const int h1=1, h2=2, h3=3, h4=4, h5=5, h6=6; + const int width=winw, height=winh; + const int v1=1*width, v2=2*width, v3=3*width, v4=4*width, v5=5*width, v6=6*width; + float* rgb[3]; + float* chr[2]; + float (*rgbarray), *vdif, *hdif, (*chrarray); + + rgbarray = (float (*)) calloc(width*height*3, sizeof( float)); + rgb[0] = rgbarray; + rgb[1] = rgbarray + (width*height); + rgb[2] = rgbarray + 2*(width*height); + + chrarray = (float (*)) calloc(width*height*2, sizeof( float)); + chr[0] = chrarray; + chr[1] = chrarray + (width*height); + + vdif = (float (*)) calloc(width*height/2, sizeof *vdif); + hdif = (float (*)) calloc(width*height/2, sizeof *hdif); + + border_interpolate2(winw,winh,7); + + if (plistener) { + plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::igv])); + plistener->setProgress (0.0); + } +#ifdef _OPENMP +#pragma omp parallel default(none) shared(rgb,vdif,hdif,chr) +#endif +{ + + float ng, eg, wg, sg, nv, ev, wv, sv, nwg, neg, swg, seg, nwv, nev, swv, sev; + +#ifdef _OPENMP +#pragma omp for +#endif + for (int row=0; rowsetProgress (0.13); +} + +#ifdef _OPENMP +#pragma omp for +#endif + for (int row=5; row>1]=(sg*nv+ng*sv)/(ng+sg)-(rgb[c][indx])/65535.f; + hdif[indx>>1]=(wg*ev+eg*wv)/(eg+wg)-(rgb[c][indx])/65535.f; + } + +#ifdef _OPENMP +#pragma omp single +#endif +{ + if (plistener) plistener->setProgress (0.26); +} + +#ifdef _OPENMP +#pragma omp for +#endif + for (int row=7; row>1])+69.0f*(SQR(vdif[(indx-v2)>>1])+SQR(vdif[(indx+v2)>>1]))+51.0f*(SQR(vdif[(indx-v4)>>1])+SQR(vdif[(indx+v4)>>1]))+21.0f*(SQR(vdif[(indx-v6)>>1])+SQR(vdif[(indx+v6)>>1]))-6.0f*SQR(vdif[(indx-v2)>>1]+vdif[indx>>1]+vdif[(indx+v2)>>1]) + -10.0f*(SQR(vdif[(indx-v4)>>1]+vdif[(indx-v2)>>1]+vdif[indx>>1])+SQR(vdif[indx>>1]+vdif[(indx+v2)>>1]+vdif[(indx+v4)>>1]))-7.0f*(SQR(vdif[(indx-v6)>>1]+vdif[(indx-v4)>>1]+vdif[(indx-v2)>>1])+SQR(vdif[(indx+v2)>>1]+vdif[(indx+v4)>>1]+vdif[(indx+v6)>>1])),0.f,1.f); + eg=LIM(epssq+78.0f*SQR(hdif[indx>>1])+69.0f*(SQR(hdif[(indx-h2)>>1])+SQR(hdif[(indx+h2)>>1]))+51.0f*(SQR(hdif[(indx-h4)>>1])+SQR(hdif[(indx+h4)>>1]))+21.0f*(SQR(hdif[(indx-h6)>>1])+SQR(hdif[(indx+h6)>>1]))-6.0f*SQR(hdif[(indx-h2)>>1]+hdif[indx>>1]+hdif[(indx+h2)>>1]) + -10.0f*(SQR(hdif[(indx-h4)>>1]+hdif[(indx-h2)>>1]+hdif[indx>>1])+SQR(hdif[indx>>1]+hdif[(indx+h2)>>1]+hdif[(indx+h4)>>1]))-7.0f*(SQR(hdif[(indx-h6)>>1]+hdif[(indx-h4)>>1]+hdif[(indx-h2)>>1])+SQR(hdif[(indx+h2)>>1]+hdif[(indx+h4)>>1]+hdif[(indx+h6)>>1])),0.f,1.f); + //Limit chrominance using H/V neighbourhood + nv=ULIM(0.725f*vdif[indx>>1]+0.1375f*vdif[(indx-v2)>>1]+0.1375f*vdif[(indx+v2)>>1],vdif[(indx-v2)>>1],vdif[(indx+v2)>>1]); + ev=ULIM(0.725f*hdif[indx>>1]+0.1375f*hdif[(indx-h2)>>1]+0.1375f*hdif[(indx+h2)>>1],hdif[(indx-h2)>>1],hdif[(indx+h2)>>1]); + //Chrominance estimation + chr[d][indx]=(eg*nv+ng*ev)/(ng+eg); + //Green channel population + rgb[1][indx]=rgb[c][indx]+65535.f*chr[d][indx]; + } + +#ifdef _OPENMP +#pragma omp single +#endif +{ + if (plistener) plistener->setProgress (0.39); +} + +// free(vdif); free(hdif); +#ifdef _OPENMP +#pragma omp for +#endif + for (int row=7; rowsetProgress (0.52); +} +#ifdef _OPENMP +#pragma omp for +#endif + for (int row=8; rowsetProgress (0.65); +} +#ifdef _OPENMP +#pragma omp for +#endif + for (int row=7; rowsetProgress (0.78); +} +#ifdef _OPENMP +#pragma omp for +#endif + for (int row=7; rowsetProgress (0.91); + + //Interpolate borders +// border_interpolate2(7, rgb); +} +/* +#ifdef _OPENMP +#pragma omp for +#endif + for (int row=0; row < height; row++) //borders + for (int col=0; col < width; col++) { + if (col==7 && row >= 7 && row < height-7) + col = width-7; + int indxc=row*width+col; + red [row][col] = rgb[indxc][0]; + green[row][col] = rgb[indxc][1]; + blue [row][col] = rgb[indxc][2]; + } +*/ + +#ifdef _OPENMP +#pragma omp for +#endif + for(int row=7; rowsetProgress (1.0); + + free(chrarray); free(rgbarray); + free(vdif); free(hdif); +} +#endif + + +/* + Adaptive Homogeneity-Directed interpolation is based on + the work of Keigo Hirakawa, Thomas Parks, and Paul Lee. + */ +#define TS 256 /* Tile Size */ +#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) +{ + int i, j, k, top, left, row, col, tr, tc, c, d, val, hm[2]; + float (*pix)[4], (*rix)[3]; + static const int dir[4] = { -1, 1, -TS, TS }; + float ldiff[2][4], abdiff[2][4], leps, abeps; + float xyz[3], xyz_cam[3][4]; + float (*cbrt); + float (*rgb)[TS][TS][3]; + float (*lab)[TS][TS][3]; + float (*lix)[3]; + char (*homo)[TS][TS], *buffer; + double r; + + int width=W, height=H; + float (*image)[4]; + int colors = 3; + + const double xyz_rgb[3][3] = { /* XYZ from RGB */ + { 0.412453, 0.357580, 0.180423 }, + { 0.212671, 0.715160, 0.072169 }, + { 0.019334, 0.119193, 0.950227 } + }; + + const float d65_white[3] = { 0.950456, 1, 1.088754 }; + + if (plistener) { + plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::ahd])); + plistener->setProgress (0.0); + } + + image = (float (*)[4]) calloc (H*W, sizeof *image); + for (int ii=0; ii 0.008856 ? pow(r,0.333333333) : 7.787*r + 16/116.0; + } + + for (i=0; i < 3; i++) + for (j=0; j < colors; j++) + for (xyz_cam[i][j] = k=0; k < 3; k++) + xyz_cam[i][j] += xyz_rgb[i][k] * imatrices.rgb_cam[k][j] / d65_white[i]; + + border_interpolate(5, image); + buffer = (char *) malloc (13*TS*TS*sizeof(float)); /* 1664 kB */ + //merror (buffer, "ahd_interpolate()"); + rgb = (float(*)[TS][TS][3]) buffer; + lab = (float(*)[TS][TS][3])(buffer + 6*TS*TS*sizeof(float)); + homo = (char (*)[TS][TS]) (buffer + 12*TS*TS*sizeof(float)); + + // helper variables for progress indication + int n_tiles = ((height-7 + (TS-7))/(TS-6)) * ((width-7 + (TS-7))/(TS-6)); + int tile = 0; + + for (top=2; top < height-5; top += TS-6) + for (left=2; left < width-5; left += TS-6) { + /* Interpolate green horizontally and vertically: */ + for (row = top; row < top+TS && row < height-2; row++) { + col = left + (FC(row,left) & 1); + for (c = FC(row,col); col < left+TS && col < width-2; col+=2) { + pix = image + (row*width+col); + val = 0.25*((pix[-1][1] + pix[0][c] + pix[1][1]) * 2 + - pix[-2][c] - pix[2][c]) ; + rgb[0][row-top][col-left][1] = ULIM(static_cast(val),pix[-1][1],pix[1][1]); + val = 0.25*((pix[-width][1] + pix[0][c] + pix[width][1]) * 2 + - pix[-2*width][c] - pix[2*width][c]) ; + rgb[1][row-top][col-left][1] = ULIM(static_cast(val),pix[-width][1],pix[width][1]); + } + } + + /* Interpolate red and blue, and convert to CIELab: */ + for (d=0; d < 2; d++) + for (row=top+1; row < top+TS-1 && row < height-3; row++) + for (col=left+1; col < left+TS-1 && col < width-3; col++) { + pix = image + (row*width+col); + rix = &rgb[d][row-top][col-left]; + lix = &lab[d][row-top][col-left]; + if ((c = 2 - FC(row,col)) == 1) { + c = FC(row+1,col); + val = pix[0][1] + (0.5*( pix[-1][2-c] + pix[1][2-c] + - rix[-1][1] - rix[1][1] ) ); + rix[0][2-c] = CLIP(val); + val = pix[0][1] + (0.5*( pix[-width][c] + pix[width][c] + - rix[-TS][1] - rix[TS][1] ) ); + } else + val = rix[0][1] + (0.25*( pix[-width-1][c] + pix[-width+1][c] + + pix[+width-1][c] + pix[+width+1][c] + - rix[-TS-1][1] - rix[-TS+1][1] + - rix[+TS-1][1] - rix[+TS+1][1]) ); + rix[0][c] = CLIP(val); + c = FC(row,col); + rix[0][c] = pix[0][c]; + xyz[0] = xyz[1] = xyz[2] = 0.0; + FORCC { + xyz[0] += xyz_cam[0][c] * rix[0][c]; + xyz[1] += xyz_cam[1][c] * rix[0][c]; + xyz[2] += xyz_cam[2][c] * rix[0][c]; + } + + xyz[0] = CurveFactory::flinterp(cbrt,xyz[0]); + xyz[1] = CurveFactory::flinterp(cbrt,xyz[1]); + xyz[2] = CurveFactory::flinterp(cbrt,xyz[2]); + + //xyz[0] = xyz[0] > 0.008856 ? pow(xyz[0]/65535,1/3.0) : 7.787*xyz[0] + 16/116.0; + //xyz[1] = xyz[1] > 0.008856 ? pow(xyz[1]/65535,1/3.0) : 7.787*xyz[1] + 16/116.0; + //xyz[2] = xyz[2] > 0.008856 ? pow(xyz[2]/65535,1/3.0) : 7.787*xyz[2] + 16/116.0; + + lix[0][0] = (116 * xyz[1] - 16); + lix[0][1] = 500 * (xyz[0] - xyz[1]); + lix[0][2] = 200 * (xyz[1] - xyz[2]); + } + + /* Build homogeneity maps from the CIELab images: */ + memset (homo, 0, 2*TS*TS); + for (row=top+2; row < top+TS-2 && row < height-4; row++) { + tr = row-top; + for (col=left+2; col < left+TS-2 && col < width-4; col++) { + tc = col-left; + for (d=0; d < 2; d++) { + lix = &lab[d][tr][tc]; + for (i=0; i < 4; i++) { + ldiff[d][i] = ABS(lix[0][0]-lix[dir[i]][0]); + abdiff[d][i] = SQR(lix[0][1]-lix[dir[i]][1]) + + SQR(lix[0][2]-lix[dir[i]][2]); + } + } + leps = min(max(ldiff[0][0],ldiff[0][1]), + max(ldiff[1][2],ldiff[1][3])); + abeps = min(max(abdiff[0][0],abdiff[0][1]), + max(abdiff[1][2],abdiff[1][3])); + for (d=0; d < 2; d++) + for (i=0; i < 4; i++) + if (ldiff[d][i] <= leps && abdiff[d][i] <= abeps) + homo[d][tr][tc]++; + } + } + + /* Combine the most homogenous pixels for the final result: */ + for (row=top+3; row < top+TS-3 && row < height-5; row++) { + tr = row-top; + for (col=left+3; col < left+TS-3 && col < width-5; col++) { + tc = col-left; + for (d=0; d < 2; d++) + for (hm[d]=0, i=tr-1; i <= tr+1; i++) + for (j=tc-1; j <= tc+1; j++) + hm[d] += homo[d][i][j]; + if (hm[0] != hm[1]) + FORC3 image[row*width+col][c] = rgb[hm[1] > hm[0]][tr][tc][c]; + else + FORC3 image[row*width+col][c] = + 0.5*(rgb[0][tr][tc][c] + rgb[1][tr][tc][c]) ; + } + } + + tile++; + if(plistener) { + plistener->setProgress((double)tile / n_tiles); + } + } + + if(plistener) plistener->setProgress (1.0); + free (buffer); + for (int i=0; igetSensorType()!=ST_FUJI_XTRANS){ + switch( FC(i,j)) { + case 0: red[i][j] = rawData[i][j]; green[i][j]=blue[i][j]=0; break; + case 1: green[i][j] = rawData[i][j]; red[i][j]=blue[i][j]=0; break; + case 2: blue[i][j] = rawData[i][j]; red[i][j]=green[i][j]=0; break; + } + } else { + switch( ri->XTRANSFC(i,j)) { + case 0: red[i][j] = rawData[i][j]; green[i][j]=blue[i][j]=0; break; + case 1: green[i][j] = rawData[i][j]; red[i][j]=blue[i][j]=0; break; + case 2: blue[i][j] = rawData[i][j]; red[i][j]=green[i][j]=0; break; + } + } + } + } +} + +/* + Refinement based on EECI demosaicing algorithm by L. Chang and Y.P. Tan + Paul Lee + Adapted for Rawtherapee - Jacques Desmis 04/2013 +*/ + +#ifdef __SSE2__ +#define CLIPV(a) LIMV(a,ZEROV,c65535v) +#endif +SSEFUNCTION void RawImageSource::refinement(int PassCount) +{ + MyTime t1e,t2e; + t1e.set(); + + int width=W; + int height=H; + int w1 = width; + int w2 = 2*w1; + if (plistener) { + plistener->setProgressStr (M("TP_RAW_DMETHOD_PROGRESSBAR_REFINE")); + } + + array2D *rgb[3]; + rgb[0] = &red; + rgb[1] = &green; + rgb[2] = &blue; + + for (int b=0; bsetProgress ((float)b/PassCount); + } + + +#ifdef _OPENMP +#pragma omp parallel +#endif +{ + float *pix[3]; + + /* Reinforce interpolated green pixels on RED/BLUE pixel locations */ +#ifdef _OPENMP +#pragma omp for +#endif + for (int row=2; row < height-2; row++) { + int col = 2+(FC(row,2) & 1); + int c = FC(row,col); +#ifdef __SSE2__ + __m128 dLv, dRv, dUv, dDv, v0v; + __m128 onev = _mm_set1_ps(1.f); + __m128 zd5v = _mm_set1_ps(0.5f); + __m128 c65535v = _mm_set1_ps(65535.f); + for (; col < width-8; col+=8) { + int indx = row*width+col; + pix[c] = (float*)(*rgb[c]) + indx; + pix[1] = (float*)(*rgb[1]) + indx; + dLv = onev/(onev+vabsf(LC2VFU(pix[c][ -2])-LC2VFU(pix[c][0]))+vabsf(LC2VFU(pix[1][ 1])-LC2VFU(pix[1][ -1]))); + dRv = onev/(onev+vabsf(LC2VFU(pix[c][ 2])-LC2VFU(pix[c][0]))+vabsf(LC2VFU(pix[1][ 1])-LC2VFU(pix[1][ -1]))); + dUv = onev/(onev+vabsf(LC2VFU(pix[c][-w2])-LC2VFU(pix[c][0]))+vabsf(LC2VFU(pix[1][w1])-LC2VFU(pix[1][-w1]))); + dDv = onev/(onev+vabsf(LC2VFU(pix[c][ w2])-LC2VFU(pix[c][0]))+vabsf(LC2VFU(pix[1][w1])-LC2VFU(pix[1][-w1]))); + v0v = CLIPV(LC2VFU(pix[c][0]) + zd5v +((LC2VFU(pix[1][-1])-LC2VFU(pix[c][-1]))*dLv +(LC2VFU(pix[1][1])-LC2VFU(pix[c][1]))*dRv +(LC2VFU(pix[1][-w1])-LC2VFU(pix[c][-w1]))*dUv + (LC2VFU(pix[1][w1])-LC2VFU(pix[c][w1]))*dDv ) / (dLv+dRv+dUv+dDv)); + STC2VFU(pix[1][0],v0v); + } +#endif + for (; col < width-2; col+=2) { + int indx = row*width+col; + pix[c] = (float*)(*rgb[c]) + indx; + pix[1] = (float*)(*rgb[1]) + indx; + float dL = 1.f/(1.f+fabsf(pix[c][ -2]-pix[c][0])+fabsf(pix[1][ 1]-pix[1][ -1])); + float dR = 1.f/(1.f+fabsf(pix[c][ 2]-pix[c][0])+fabsf(pix[1][ 1]-pix[1][ -1])); + float dU = 1.f/(1.f+fabsf(pix[c][-w2]-pix[c][0])+fabsf(pix[1][w1]-pix[1][-w1])); + float dD = 1.f/(1.f+fabsf(pix[c][ w2]-pix[c][0])+fabsf(pix[1][w1]-pix[1][-w1])); + float v0 = (pix[c][0] + 0.5f +((pix[1][ -1]-pix[c][ -1])*dL +(pix[1][ 1]-pix[c][ 1])*dR +(pix[1][-w1]-pix[c][-w1])*dU + (pix[1][ w1]-pix[c][ w1])*dD ) / (dL+dR+dU+dD)); + pix[1][0] = CLIP(v0); + } + } + /* Reinforce interpolated red/blue pixels on GREEN pixel locations */ +#ifdef _OPENMP +#pragma omp for +#endif + for (int row=2; row < height-2; row++) { + int col = 2+(FC(row,3) & 1); + int c = FC(row,col+1); +#ifdef __SSE2__ + __m128 dLv, dRv, dUv, dDv, v0v; + __m128 onev = _mm_set1_ps(1.f); + __m128 zd5v = _mm_set1_ps(0.5f); + __m128 c65535v = _mm_set1_ps(65535.f); + for (; col < width-8; col+=8) { + int indx = row*width+col; + pix[1] = (float*)(*rgb[1]) + indx; + for (int i=0; i < 2; c=2-c, i++) { + pix[c] = (float*)(*rgb[c]) + indx; + dLv = onev/(onev+vabsf(LC2VFU(pix[1][ -2])-LC2VFU(pix[1][0]))+vabsf(LC2VFU(pix[c][ 1])-LC2VFU(pix[c][ -1]))); + dRv = onev/(onev+vabsf(LC2VFU(pix[1][ 2])-LC2VFU(pix[1][0]))+vabsf(LC2VFU(pix[c][ 1])-LC2VFU(pix[c][ -1]))); + dUv = onev/(onev+vabsf(LC2VFU(pix[1][-w2])-LC2VFU(pix[1][0]))+vabsf(LC2VFU(pix[c][w1])-LC2VFU(pix[c][-w1]))); + dDv = onev/(onev+vabsf(LC2VFU(pix[1][ w2])-LC2VFU(pix[1][0]))+vabsf(LC2VFU(pix[c][w1])-LC2VFU(pix[c][-w1]))); + v0v = CLIPV(LC2VFU(pix[1][0]) + zd5v -((LC2VFU(pix[1][-1])-LC2VFU(pix[c][-1]))*dLv + (LC2VFU(pix[1][1])-LC2VFU(pix[c][1]))*dRv +(LC2VFU(pix[1][-w1])-LC2VFU(pix[c][-w1]))*dUv + (LC2VFU(pix[1][w1])-LC2VFU(pix[c][w1]))*dDv ) / (dLv+dRv+dUv+dDv)); + STC2VFU(pix[c][0],v0v); + } + } +#endif + for (; col < width-2; col+=2) { + int indx = row*width+col; + pix[1] = (float*)(*rgb[1]) + indx; + for (int i=0; i < 2; c=2-c, i++) { + pix[c] = (float*)(*rgb[c]) + indx; + float dL = 1.f/(1.f+fabsf(pix[1][ -2]-pix[1][0])+fabsf(pix[c][ 1]-pix[c][ -1])); + float dR = 1.f/(1.f+fabsf(pix[1][ 2]-pix[1][0])+fabsf(pix[c][ 1]-pix[c][ -1])); + float dU = 1.f/(1.f+fabsf(pix[1][-w2]-pix[1][0])+fabsf(pix[c][w1]-pix[c][-w1])); + float dD = 1.f/(1.f+fabsf(pix[1][ w2]-pix[1][0])+fabsf(pix[c][w1]-pix[c][-w1])); + float v0 = (pix[1][0] + 0.5f -((pix[1][ -1]-pix[c][ -1])*dL + (pix[1][ 1]-pix[c][ 1])*dR +(pix[1][-w1]-pix[c][-w1])*dU + (pix[1][ w1]-pix[c][ w1])*dD ) / (dL+dR+dU+dD)); + pix[c][0] = CLIP(v0); + } + } + } + /* Reinforce integrated red/blue pixels on BLUE/RED pixel locations */ +#ifdef _OPENMP +#pragma omp for +#endif + for (int row=2; row < height-2; row++) { + int col = 2+(FC(row,2) & 1); + int c = 2-FC(row,col); +#ifdef __SSE2__ + __m128 dLv, dRv, dUv, dDv, v0v; + __m128 onev = _mm_set1_ps(1.f); + __m128 zd5v = _mm_set1_ps(0.5f); + __m128 c65535v = _mm_set1_ps(65535.f); + for (; col < width-8; col+=8) { + int indx = row*width+col; + pix[0] = (float*)(*rgb[0]) + indx; + pix[1] = (float*)(*rgb[1]) + indx; + pix[2] = (float*)(*rgb[2]) + indx; + int d = 2 - c; + dLv = onev/(onev+vabsf(LC2VFU(pix[d][ -2])-LC2VFU(pix[d][0]))+vabsf(LC2VFU(pix[1][ 1])-LC2VFU(pix[1][ -1]))); + dRv = onev/(onev+vabsf(LC2VFU(pix[d][ 2])-LC2VFU(pix[d][0]))+vabsf(LC2VFU(pix[1][ 1])-LC2VFU(pix[1][ -1]))); + dUv = onev/(onev+vabsf(LC2VFU(pix[d][-w2])-LC2VFU(pix[d][0]))+vabsf(LC2VFU(pix[1][w1])-LC2VFU(pix[1][-w1]))); + dDv = onev/(onev+vabsf(LC2VFU(pix[d][ w2])-LC2VFU(pix[d][0]))+vabsf(LC2VFU(pix[1][w1])-LC2VFU(pix[1][-w1]))); + v0v = CLIPV(LC2VFU(pix[1][0]) + zd5v -((LC2VFU(pix[1][-1])-LC2VFU(pix[c][-1]))*dLv +(LC2VFU(pix[1][1])-LC2VFU(pix[c][1]))*dRv +(LC2VFU(pix[1][-w1])-LC2VFU(pix[c][-w1]))*dUv + (LC2VFU(pix[1][w1])-LC2VFU(pix[c][w1]))*dDv ) / (dLv+dRv+dUv+dDv)); + STC2VFU(pix[c][0],v0v); + } +#endif + for (; col < width-2; col+=2) { + int indx = row*width+col; + pix[0] = (float*)(*rgb[0]) + indx; + pix[1] = (float*)(*rgb[1]) + indx; + pix[2] = (float*)(*rgb[2]) + indx; + int d = 2 - c; + float dL = 1.f/(1.f+fabsf(pix[d][ -2]-pix[d][0])+fabsf(pix[1][ 1]-pix[1][ -1])); + float dR = 1.f/(1.f+fabsf(pix[d][ 2]-pix[d][0])+fabsf(pix[1][ 1]-pix[1][ -1])); + float dU = 1.f/(1.f+fabsf(pix[d][-w2]-pix[d][0])+fabsf(pix[1][w1]-pix[1][-w1])); + float dD = 1.f/(1.f+fabsf(pix[d][ w2]-pix[d][0])+fabsf(pix[1][w1]-pix[1][-w1])); + float v0 = (pix[1][0] + 0.5f -((pix[1][ -1]-pix[c][ -1])*dL +(pix[1][ 1]-pix[c][ 1])*dR +(pix[1][-w1]-pix[c][-w1])*dU + (pix[1][ w1]-pix[c][ w1])*dD ) / (dL+dR+dU+dD)); + pix[c][0] = CLIP(v0); + } + } +} // end parallel + } + t2e.set(); + if (settings->verbose) printf("Refinement Lee %d usec\n", t2e.etime(t1e)); +} +#ifdef __SSE2__ +#undef CLIPV +#endif + + +// Refinement based on EECI demozaicing algorithm by L. Chang and Y.P. Tan +// from "Lassus" : Luis Sanz Rodriguez, adapted by Jacques Desmis - JDC - and Oliver Duis for RawTherapee +// increases the signal to noise ratio (PSNR) # +1 to +2 dB : tested with Dcraw : eg: Lighthouse + AMaZE : whitout refinement:39.96dB, with refinement:41.86 dB +// reduce color artifacts, improves the interpolation +// but it's relatively slow +// +// Should be DISABLED if it decreases image quality by increases some image noise and generates blocky edges +void RawImageSource::refinement_lassus(int PassCount) +{ + // const int PassCount=1; + + // if (settings->verbose) printf("Refinement\n"); + + MyTime t1e,t2e; + t1e.set(); + int u=W, v=2*u, w=3*u, x=4*u, y=5*u; + float (*image)[3]; + image = (float(*)[3]) calloc(W*H, sizeof *image); +#ifdef _OPENMP +#pragma omp parallel shared(image) +#endif + { + // convert red, blue, green to image +#ifdef _OPENMP +#pragma omp for +#endif + for (int i=0;isetProgressStr (M("TP_RAW_DMETHOD_PROGRESSBAR_REFINE")); + plistener->setProgress ((float)b/PassCount); + } + + // Reinforce interpolated green pixels on RED/BLUE pixel locations +#ifdef _OPENMP +#pragma omp for +#endif + for (int row=6; rowverbose) printf("Refinement Lassus %d usec\n", t2e.etime(t1e)); +} + + +/* + * 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 the author 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 + * OWNER 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. + */ + +// If you want to use the code, you need to display name of the original authors in +// your software! + +/* DCB demosaicing by Jacek Gozdz (cuniek@kft.umcs.lublin.pl) + * the code is open source (BSD licence) +*/ + +#define TILESIZE 256 +#define TILEBORDER 10 +#define CACHESIZE (TILESIZE+2*TILEBORDER) + +inline void RawImageSource::dcb_initTileLimits(int &colMin, int &rowMin, int &colMax, int &rowMax, int x0, int y0, int border) +{ + rowMin = border; + colMin = border; + rowMax = CACHESIZE-border; + colMax = CACHESIZE-border; + if(!y0 ) rowMin = TILEBORDER+border; + if(!x0 ) colMin = TILEBORDER+border; + if( y0+TILESIZE+TILEBORDER >= H-border) rowMax = TILEBORDER+H-border-y0; + if( x0+TILESIZE+TILEBORDER >= W-border) colMax = TILEBORDER+W-border-x0; +} + +void RawImageSource::fill_raw( float (*cache )[4], int x0, int y0, float** rawData) +{ + int rowMin,colMin,rowMax,colMax; + dcb_initTileLimits(colMin,rowMin,colMax,rowMax,x0,y0,0); + + for (int row=rowMin,y=y0-TILEBORDER+rowMin; row= border && col < W - border && row >= border && row < H - border){ + col = W - border; + if(col >= x0+TILESIZE+TILEBORDER ) + break; + } + memset(sum, 0, sizeof sum); + for (y = row - 1; y != row + 2; y++) + for (x = col - 1; x != col + 2; x++) + if (y < H && y< y0+TILESIZE+TILEBORDER && x < W && x0) + cache[(row-y0+TILEBORDER) * CACHESIZE +TILEBORDER + col-x0][c] = sum[c] / sum[c + 4]; + } + } +} +// saves red and blue +void RawImageSource::copy_to_buffer( float (*buffer)[3], float (*image)[4]) +{ + for (int indx=0; indx < CACHESIZE*CACHESIZE; indx++) { + buffer[indx][0]=image[indx][0]; //R + buffer[indx][2]=image[indx][2]; //B + } +} + +// restores red and blue +void RawImageSource::restore_from_buffer(float (*image)[4], float (*buffer)[3]) +{ + for (int indx=0; indx < CACHESIZE*CACHESIZE; indx++) { + image[indx][0]=buffer[indx][0]; //R + image[indx][2]=buffer[indx][2]; //B + } +} + +// First pass green interpolation +void RawImageSource::dcb_hid(float (*image)[4],float (*bufferH)[3], float (*bufferV)[3], int x0, int y0) +{ + const int u=CACHESIZE, v=2*CACHESIZE; + int rowMin,colMin,rowMax,colMax; + dcb_initTileLimits(colMin,rowMin,colMax,rowMax,x0,y0,2); + + // green pixels + for (int row = rowMin; row < rowMax; row++) { + for (int col = colMin+(FC(y0-TILEBORDER+row,x0-TILEBORDER+colMin)&1),indx=row*CACHESIZE+col; col < colMax; col+=2, indx+=2) { + assert(indx-u>=0 && indx+u=0 && indx+u+1=0 && c<3); + + bufferH[indx][c] = ( 4.f * bufferH[indx][1] + - bufferH[indx+u+1][1] - bufferH[indx+u-1][1] - bufferH[indx-u+1][1] - bufferH[indx-u-1][1] + + image[indx+u+1][c] + image[indx+u-1][c] + image[indx-u+1][c] + image[indx-u-1][c] ) * 0.25f; + bufferV[indx][c] = ( 4.f * bufferV[indx][1] + - bufferV[indx+u+1][1] - bufferV[indx+u-1][1] - bufferV[indx-u+1][1] - bufferV[indx-u-1][1] + + image[indx+u+1][c] + image[indx+u-1][c] + image[indx-u+1][c] + image[indx-u-1][c] ) * 0.25f; + } + + // red or blue in green pixels + for (int row=rowMin; row=0 && indx+u=0 && c<3 && d>=0 && d<3); + bufferH[indx][c] = (image[indx+1][c] + image[indx-1][c]) * 0.5f; + bufferH[indx][d] = (2.f * bufferH[indx][1] - bufferH[indx+u][1] - bufferH[indx-u][1] + image[indx+u][d] + image[indx-u][d]) * 0.5f; + bufferV[indx][c] = (2.f * bufferV[indx][1] - bufferV[indx+1][1] - bufferV[indx-1][1] + image[indx+1][c] + image[indx-1][c]) * 0.5f; + bufferV[indx][d] = (image[indx+u][d] + image[indx-u][d]) * 0.5f; + } + + // Decide green pixels + for (int row = rowMin; row < rowMax; row++) + for (int col = colMin+(FC(y0-TILEBORDER+row,x0-TILEBORDER+colMin)&1),indx=row*CACHESIZE+col,c=FC(y0-TILEBORDER+row,x0-TILEBORDER+col),d=2-c; col < colMax; col+=2, indx+=2) { + float current = max(image[indx+v][c], image[indx-v][c], image[indx-2][c], image[indx+2][c]) - + min(image[indx+v][c], image[indx-v][c], image[indx-2][c], image[indx+2][c]) + + max(image[indx+1+u][d], image[indx+1-u][d], image[indx-1+u][d], image[indx-1-u][d]) - + min(image[indx+1+u][d], image[indx+1-u][d], image[indx-1+u][d], image[indx-1-u][d]); + + float currentH = max(bufferH[indx+v][d], bufferH[indx-v][d], bufferH[indx-2][d], bufferH[indx+2][d]) - + min(bufferH[indx+v][d], bufferH[indx-v][d], bufferH[indx-2][d], bufferH[indx+2][d]) + + max(bufferH[indx+1+u][c], bufferH[indx+1-u][c], bufferH[indx-1+u][c], bufferH[indx-1-u][c]) - + min(bufferH[indx+1+u][c], bufferH[indx+1-u][c], bufferH[indx-1+u][c], bufferH[indx-1-u][c]); + + float currentV = max(bufferV[indx+v][d], bufferV[indx-v][d], bufferV[indx-2][d], bufferV[indx+2][d]) - + min(bufferV[indx+v][d], bufferV[indx-v][d], bufferV[indx-2][d], bufferV[indx+2][d]) + + max(bufferV[indx+1+u][c], bufferV[indx+1-u][c], bufferV[indx-1+u][c], bufferV[indx-1-u][c]) - + min(bufferV[indx+1+u][c], bufferV[indx+1-u][c], bufferV[indx-1+u][c], bufferV[indx-1-u][c]); + + assert(indx>=0 && indx=0 && indx=0 && c<4); + image[indx][c] = ( 4.f * image[indx][1] + - image[indx+u+1][1] - image[indx+u-1][1] - image[indx-u+1][1] - image[indx-u-1][1] + + image[indx+u+1][c] + image[indx+u-1][c] + image[indx-u+1][c] + image[indx-u-1][c] ) * 0.25f; + } + + // red or blue in green pixels + for (int row=rowMin; row=0 && indx=0 && c<4); + image[indx][c] = (2.f * image[indx][1] - image[indx+1][1] - image[indx-1][1] + image[indx+1][c] + image[indx-1][c]) * 0.5f; + image[indx][d] = (2.f * image[indx][1] - image[indx+u][1] - image[indx-u][1] + image[indx+u][d] + image[indx-u][d]) * 0.5f; + } +} + +// green correction +void RawImageSource::dcb_hid2(float (*image)[4], int x0, int y0) +{ + const int u=CACHESIZE, v=2*CACHESIZE; + int rowMin,colMin,rowMax,colMax; + dcb_initTileLimits(colMin,rowMin,colMax,rowMax,x0,y0,2); + + for (int row=rowMin; row < rowMax; row++) { + for (int col = colMin+(FC(y0-TILEBORDER+row,x0-TILEBORDER+colMin)&1),indx=row*CACHESIZE+col,c=FC(y0-TILEBORDER+row,x0-TILEBORDER+col); col < colMax; col+=2, indx+=2) { + assert(indx-v>=0 && indx+v=0 && indx ( pix[-4] + pix[+4] + pix[-u] + pix[+u])/4 ) + image[indx][3] = ((min(pix[-4], pix[+4]) + pix[-4] + pix[+4] ) < (min(pix[-u], pix[+u]) + pix[-u] + pix[+u])); + else + image[indx][3] = ((max(pix[-4], pix[+4]) + pix[-4] + pix[+4] ) > (max(pix[-u], pix[+u]) + pix[-u] + pix[+u])); + } + } +} + +// interpolated green pixels are corrected using the map +void RawImageSource::dcb_correction(float (*image)[4], int x0, int y0) +{ + const int u=CACHESIZE, v=2*CACHESIZE; + int rowMin,colMin,rowMax,colMax; + dcb_initTileLimits(colMin,rowMin,colMax,rowMax,x0,y0,2); + + for (int row=rowMin; row < rowMax; row++) { + for (int col = colMin+(FC(y0-TILEBORDER+row,x0-TILEBORDER+colMin)&1),indx=row*CACHESIZE+col; col < colMax; col+=2, indx+=2) { + float current = 4.f * image[indx][3] + + 2.f * (image[indx+u][3] + image[indx-u][3] + image[indx+1][3] + image[indx-1][3]) + + image[indx+v][3] + image[indx-v][3] + image[indx+2][3] + image[indx-2][3]; + + assert(indx>=0 && indx=0 && indx=0 && indx=0 && indx=0 && indx=0 && c<4); + chroma[indx][d]=image[indx][c]-image[indx][1]; + } + + for (int row=rowMin; row=0 && indx=0 && c<2); + chroma[indx][c]=(f[0]*g[0]+f[1]*g[1]+f[2]*g[2]+f[3]*g[3])/(f[0]+f[1]+f[2]+f[3]); + } + for (int row=rowMin; row=0 && indx=0 && c<2); + chroma[indx][c]=(f[0]*g[0]+f[1]*g[1]+f[2]*g[2]+f[3]*g[3])/(f[0]+f[1]+f[2]+f[3]); + } + + for(int row=rowMin; row=0 && indxsetProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::dcb])); + plistener->setProgress (currentProgress); + } + + int wTiles = W/TILESIZE + (W%TILESIZE?1:0); + int hTiles = H/TILESIZE + (H%TILESIZE?1:0); + int numTiles = wTiles * hTiles; + int tilesDone=0; +#ifdef _OPENMP + int nthreads = omp_get_max_threads(); + float (**image)[4] = (float(**)[4]) calloc( nthreads,sizeof( void*) ); + float (**image2)[3] = (float(**)[3]) calloc( nthreads,sizeof( void*) ); + float (**image3)[3] = (float(**)[3]) calloc( nthreads,sizeof( void*) ); + float (**chroma)[2] = (float (**)[2]) calloc( nthreads,sizeof( void*) ); + for(int i=0; i0;i--) { + dcb_hid2(tile,x0,y0); + dcb_hid2(tile,x0,y0); + dcb_hid2(tile,x0,y0); + dcb_map(tile,x0,y0); + dcb_correction(tile,x0,y0); + } + dcb_color(tile,x0,y0); + dcb_pp(tile,x0,y0); + dcb_map(tile,x0,y0); + dcb_correction2(tile,x0,y0); + dcb_map(tile,x0,y0); + dcb_correction(tile,x0,y0); + dcb_color(tile,x0,y0); + dcb_map(tile,x0,y0); + dcb_correction(tile,x0,y0); + dcb_map(tile,x0,y0); + dcb_correction(tile,x0,y0); + dcb_map(tile,x0,y0); + restore_from_buffer(tile, buffer); + dcb_color(tile,x0,y0); + if (dcb_enhance) { + dcb_refinement(tile,x0,y0); + dcb_color_full(tile,x0,y0,chrm); + } + + for(int y=0;y currentProgress){ + currentProgress+=0.1; // Show progress each 10% + plistener->setProgress (currentProgress); + } + } +#ifdef _OPENMP +#pragma omp atomic +#endif + tilesDone++; + } + +#ifdef _OPENMP + for(int i=0; isetProgress (1.0); +} + +const double xyz_rgb[3][3] = { // XYZ from RGB + { 0.412453, 0.357580, 0.180423 }, + { 0.212671, 0.715160, 0.072169 }, + { 0.019334, 0.119193, 0.950227 } }; +const float d65_white[3] = { 0.950456, 1, 1.088754 }; + +void RawImageSource::cielab (const float (*rgb)[3], float* l, float* a, float *b, const int width, const int height, const int labWidth, const float xyz_cam[3][3]) +{ + static float cbrt[0x10000]; + static bool cbrtinit = false; + if (!rgb) { + int i, j, k; + float r; + if(!cbrtinit) { + for (i=0; i < 0x10000; i++) { + r = i / 65535.f; + cbrt[i] = r > 0.008856f ? xcbrtf(r) : 7.787f*r + 16.f/116.f; + } + cbrtinit = true; + } + return; + } + + int rgbOffset = (width - labWidth); + for(int i=0;igetXtransMatrix(xtrans); + + for (int row=0; row < height; row++) + for (int col=0; col < width; col++) { + if (col==border && row >= border && row < height-border) + col = width-border; + float sum[6] = {0.f}; + for (int y=MAX(0,row-1); y <= MIN(row+1,height-1); y++) + for (int x=MAX(0,col-1); x <= MIN(col+1,width-1); x++) { + int f = fcol(y,x); + sum[f] += rawData[y][x]; + sum[f+3]++; + } + + switch(fcol(row,col)) { + case 0: red[row][col] = rawData[row][col]; + green[row][col] = (sum[1]/sum[4]); + blue[row][col] = (sum[2]/sum[5]); + break; + case 1: if(sum[3]==0.f) { // at the 4 corner pixels it can happen, that we have only green pixels in 2x2 area + red[row][col] = green[row][col] = blue[row][col] = rawData[row][col]; + } else { + red[row][col] = (sum[0]/sum[3]); + green[row][col] = rawData[row][col]; + blue[row][col] = (sum[2]/sum[5]); + } + break; + case 2: red[row][col] = (sum[0]/sum[3]); + green[row][col] = (sum[1]/sum[4]); + blue[row][col] = rawData[row][col]; + } + } +} + +/* + Frank Markesteijn's algorithm for Fuji X-Trans sensors + adapted to RT by Ingo Weyrich 2014 +*/ + +#define TS 122 /* Tile Size */ + +void RawImageSource::xtrans_interpolate (int passes, bool useCieLab) +{ + double progress = 0.0; + const bool plistenerActive = plistener; + + if (plistenerActive) { + plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), "Xtrans")); + plistener->setProgress (progress); + } + + char xtrans[6][6]; + ri->getXtransMatrix(xtrans); + + static const short orth[12] = { 1,0,0,1,-1,0,0,-1,1,0,0,1 }, + patt[2][16] = { { 0,1,0,-1,2,0,-1,0,1,1,1,-1,0,0,0,0 }, + { 0,1,0,-2,1,0,-2,0,1,1,-2,-2,1,-1,-1,1 } }, + dir[4] = { 1,TS,TS+1,TS-1 }; + + short allhex[2][3][3][8]; + + // sgrow/sgcol is the offset in the sensor matrix of the solitary + // green pixels + ushort sgrow, sgcol; + + const int height = H, width = W; + + if (settings->verbose) + printf("%d-pass X-Trans interpolation using %s conversion...\n", passes, useCieLab ? "lab" : "yuv"); + + xtransborder_interpolate(6); + + float xyz_cam[3][3]; + { + float rgb_cam[3][4]; + ri->getRgbCam(rgb_cam); + int k; + for (int i=0; i < 3; i++) + for (int j=0; j < 3; j++) + for (xyz_cam[i][j] = k=0; k < 3; k++) + xyz_cam[i][j] += xyz_rgb[i][k] * rgb_cam[k][j] / d65_white[i]; + } + +/* Map a green hexagon around each non-green pixel and vice versa: */ +{ + int gint, d, h, v, ng, row, col, c; + + for (row=0; row < 3; row++) + for (col=0; col < 3; col++) { + gint = fcol(row,col) == 1; + for (ng=d=0; d < 10; d+=2) { + if (fcol(row+orth[d]+6,col+orth[d+2]+6) == 1) + ng=0; + else + ng++; + if (ng == 4) { + // if there are four non-green pixels adjacent in cardinal + // directions, this is the solitary green pixel + sgrow = row; + sgcol = col; + } + if (ng == gint+1) + FORC(8) { + v = orth[d]*patt[gint][c*2] + orth[d+1]*patt[gint][c*2+1]; + h = orth[d+2]*patt[gint][c*2] + orth[d+3]*patt[gint][c*2+1]; + allhex[0][row][col][c^(gint*2 & d)] = h + v*width; + allhex[1][row][col][c^(gint*2 & d)] = h + v*TS; + } + } + } + +} + if(plistenerActive) { + progress += 0.05; + plistener->setProgress(progress); + } + + + double progressInc = 36.0*(1.0-progress)/((H*W)/((TS-16)*(TS-16))); + const int ndir = 4 << (passes > 1); + cielab (0,0,0,0,0,0,0,0); + struct s_minmaxgreen { + float min; + float max; + }; + + int RightShift[6]; + for(int row=0;row<6;row++) { + // count number of green pixels in three cols + int greencount = 0; + for(int col=0;col<3;col++) + greencount += (fcol(row,col) == 1); + RightShift[row] = (greencount == 2); + } + + +#pragma omp parallel +{ + int progressCounter = 0; + short *hex; + int c, d, f, h, i, v, mrow, mcol; + int pass; + float color[3][8], g, val; + float (*rgb)[TS][TS][3], (*rix)[3]; + float (*lab)[TS-8][TS-8]; + float (*drv)[TS-10][TS-10], diff[6], tr; + s_minmaxgreen (*greenminmaxtile)[TS]; + uint8_t (*homo)[TS][TS]; + uint8_t (*homosum)[TS][TS]; + float *buffer; + buffer = (float *) malloc ((TS*TS*(ndir*3+11)+128)*sizeof(float)); + rgb = (float(*)[TS][TS][3]) buffer; + lab = (float (*) [TS-8][TS-8])(buffer + TS*TS*(ndir*3)); + drv = (float (*)[TS-10][TS-10]) (buffer + TS*TS*(ndir*3+3)); + homo = (uint8_t (*)[TS][TS]) (lab); // we can reuse the lab-buffer because they are not used together + greenminmaxtile = (s_minmaxgreen(*)[TS]) (lab); // we can reuse the lab-buffer because they are not used together + homosum = (uint8_t (*)[TS][TS]) (drv); // we can reuse the drv-buffer because they are not used together + +#pragma omp for collapse(2) schedule(dynamic) nowait + for (int top=3; top < height-19; top += TS-16) + for (int left=3; left < width-19; left += TS-16) { + int mrow = MIN (top+TS, height-3); + int mcol = MIN (left+TS, width-3); + memset(rgb,0,TS*TS*3*sizeof(float)); + for (int row=top; row < mrow; row++) + for (int col=left; col < mcol; col++) { + rgb[0][row-top][col-left][fcol(row,col)] = rawData[row][col]; + } + FORC3 memcpy (rgb[c+1], rgb[0], sizeof *rgb); + + /* Set green1 and green3 to the minimum and maximum allowed values: */ + for (int row=top; row < mrow; row++) { + float minval=FLT_MAX; + float maxval=0.f; + int shiftindex = RightShift[(row)%6]; + for (int col=left; col < mcol; col++) { + if (fcol(row,col) == 1) { + minval=FLT_MAX; + maxval=0.f; + continue; + } + float *pix = &rawData[row][col]; + hex = allhex[0][row % 3][col % 3]; + if (maxval==0.f) + FORC(6) { + val = pix[hex[c]]; + if (minval > val) + minval = val; + if (maxval < val) + maxval = val; + } + greenminmaxtile[row-top][(col-left)>>shiftindex].min = minval; + greenminmaxtile[row-top][(col-left)>>shiftindex].max = maxval; + switch ((row-sgrow) % 3) { + case 1: if (row < mrow-1) { + row++; + shiftindex = RightShift[(row)%6]; + col--; + } + break; + case 2: minval=FLT_MAX; + maxval=0.f; + if ((col+=2) < mcol-1 && row > top+1) { + row--; + shiftindex = RightShift[(row)%6]; + } + } + } + } + + /* Interpolate green horizontally, vertically, and along both diagonals: */ + for (int row=top; row < mrow; row++) { + // find first non-green pixel + int leftstart = left; + for(;leftstart>shiftindex].min,greenminmaxtile[row-top][(col-left)>>shiftindex].max); + } + } + for (pass=0; pass < passes; pass++) { + if (pass == 1) + memcpy (rgb+=4, buffer, 4*sizeof *rgb); + +/* Recalculate green from interpolated values of closer pixels: */ + if (pass) { + for (int row=top+2; row < mrow-2; row++) { + int leftstart = left+2; + for(;leftstart>shiftindex].min,greenminmaxtile[row-top][(col-left)>>shiftindex].max); + } + } + } + } + +/* Interpolate red and blue values for solitary green pixels: */ + for (int row=(top-sgrow+4)/3*3+sgrow; row < mrow-2; row+=3) + for (int col=(left-sgcol+4)/3*3+sgcol; col < mcol-2; col+=3) { + rix = &rgb[0][row-top][col-left]; + h = fcol(row,col+1); + memset (diff, 0, sizeof diff); + for (i=1, d=0; d < 6; d++, i^=TS^1, h^=2) { + for (c=0; c < 2; c++, h^=2) { + g = rix[0][1] + rix[0][1] - rix[i< 1) + diff[d] += SQR (rix[i< 2 && (d & 1)) // 3, 5 + if (diff[d-1] < diff[d]) + FORC(2) + color[c*2][d] = color[c*2][d-1]; + if ((d & 1) || d < 2) { // d: 0, 1, 3, 5 + FORC(2) + rix[0][c*2] = CLIP(0.5f*color[c*2][d]); + rix += TS*TS; + } + } + } + +/* Interpolate red for blue pixels and vice versa: */ + for (int row=top+3; row < mrow-3; row++) { + int leftstart = left+3; + for(;leftstart 1 || ((d ^ c) & 1) || + ((fabsf(rix[0][1]-rix[c][1])+fabsf(rix[0][1]-rix[-c][1])) < 2.f*(fabsf(rix[0][1]-rix[h][1])+fabsf(rix[0][1]-rix[-h][1]))) ? c:h; + + rix[0][f] = CLIP(0.5f*(rix[i][f] + rix[-i][f] + + rix[0][1] + rix[0][1] - rix[i][1] - rix[-i][1])); + } + } + } + +/* Fill in red and blue for 2x2 blocks of green: */ + for (int row=top+2; row < mrow-2; row++) + if ((row-sgrow) % 3) { + for (int col=left+2; col < mcol-2; col++) + if ((col-sgcol) % 3) { + rix = &rgb[0][row-top][col-left]; + hex = allhex[1][row%3][col % 3]; + for (d=0; d < ndir; d+=2, rix += TS*TS) + if (hex[d] + hex[d+1]) { + g = 3*rix[0][1] - 2*rix[hex[d]][1] - rix[hex[d+1]][1]; + for (c=0; c < 4; c+=2) + rix[0][c] = CLIP((g + 2*rix[hex[d]][c] + rix[hex[d+1]][c])*0.33333333f); + } else { + g = 2*rix[0][1] - rix[hex[d]][1] - rix[hex[d+1]][1]; + for (c=0; c < 4; c+=2) + rix[0][c] = CLIP((g + rix[hex[d]][c] + rix[hex[d+1]][c])*0.5f); + } + } + } + } + +// end of multipass part + rgb = (float(*)[TS][TS][3]) buffer; + mrow -= top; + mcol -= left; + + if(useCieLab) { + /* Convert to CIELab and differentiate in all directions: */ + // Original dcraw algorithm uses CIELab as perceptual space + // (presumably coming from original AHD) and converts taking + // camera matrix into account. We use this in RT. + for (d=0; d < ndir; d++) { + float *l = &lab[0][0][0]; + float *a = &lab[1][0][0]; + float *b = &lab[2][0][0]; + cielab(&rgb[d][4][4],l,a,b,TS,mrow-8,TS-8,xyz_cam); + int f = dir[d & 3]; + f = f == 1 ? 1 : f-8; + for (int row=5; row < mrow-5; row++) + for (int col=5; col < mcol-5; col++) { + float *l = &lab[0][row-4][col-4]; + float *a = &lab[1][row-4][col-4]; + float *b = &lab[2][row-4][col-4]; + + g = 2*l[0] - l[f] - l[-f]; + drv[d][row-5][col-5] = SQR(g) + + SQR((2*a[0] - a[f] - a[-f] + g*2.1551724f)) + + SQR((2*b[0] - b[f] - b[-f] - g*0.86206896f)); + } + + } + } else { + // Now use YPbPr which requires much + // less code and is nearly indistinguishable. It assumes the + // camera RGB is roughly linear. + // + for (d=0; d < ndir; d++) { + float (*yuv)[TS-8][TS-8] = lab; // we use the lab buffer, which has the same dimensions + for (int row=4; row < mrow-4; row++) + for (int col=4; col < mcol-4; col++) { + // use ITU-R BT.2020 YPbPr, which is great, but could use + // a better/simpler choice? note that imageop.h provides + // dt_iop_RGB_to_YCbCr which uses Rec. 601 conversion, + // which appears less good with specular highlights + float y = 0.2627f * rgb[d][row][col][0] + 0.6780f * rgb[d][row][col][1] + 0.0593f * rgb[d][row][col][2]; + yuv[0][row-4][col-4] = y; + yuv[1][row-4][col-4] = (rgb[d][row][col][2]-y)*0.56433f; + yuv[2][row-4][col-4] = (rgb[d][row][col][0]-y)*0.67815f; + } + int f=dir[d & 3]; + f = f == 1 ? 1 : f-8; + for (int row=5; row < mrow-5; row++) + for (int col=5; col < mcol-5; col++) { + float *y = &yuv[0][row-4][col-4]; + float *u = &yuv[1][row-4][col-4]; + float *v = &yuv[2][row-4][col-4]; + drv[d][row-5][col-5] = SQR(2*y[0] - y[f] - y[-f]) + + SQR(2*u[0] - u[f] - u[-f]) + + SQR(2*v[0] - v[f] - v[-f]); + } + } + } + +/* Build homogeneity maps from the derivatives: */ + memset(homo, 0, ndir*TS*TS*sizeof(uint8_t)); + for (int row=6; row < mrow-6; row++) + for (int col=6; col < mcol-6; col++) { + for (tr=FLT_MAX, d=0; d < ndir; d++) + tr = (drv[d][row-5][col-5] < tr ? drv[d][row-5][col-5] : tr); + tr *= 8; + for (d=0; d < ndir; d++) + for (v=-1; v <= 1; v++) + for (h=-1; h <= 1; h++) + homo[d][row][col] += (drv[d][row+v-5][col+h-5] <= tr ? 1:0) ; + } + + if (height-top < TS+4) + mrow = height-top+2; + if (width-left < TS+4) + mcol = width-left+2; + + +/* Build 5x5 sum of homogeneity maps */ + for(d=0;d hm[d]) + hm[d] = 0; + } + maxval -= maxval >> 3; + float avg[4] = {0.f}; + for (d=0; d < ndir; d++) + if (hm[d] >= maxval) { + FORC3 avg[c] += rgb[d][row][col][c]; + avg[3]++; + } + + red[row+top][col+left] = (avg[0]/avg[3]); + green[row+top][col+left] = (avg[1]/avg[3]); + blue[row+top][col+left] = (avg[2]/avg[3]); + } + + if(plistenerActive && ((++progressCounter) % 32 == 0)) { +#ifdef _OPENMP +#pragma omp critical (xtransdemosaic) +#endif +{ + progress += progressInc; + progress = min(1.0,progress); + plistener->setProgress (progress); +} + } + + + } + free(buffer); +} + +} + +#undef TS + +void RawImageSource::fast_xtrans_interpolate () +{ + if (settings->verbose) + printf("fast X-Trans interpolation...\n"); + + double progress = 0.0; + const bool plistenerActive = plistener; + + if (plistenerActive) { + plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), "fast Xtrans")); + plistener->setProgress (progress); + } + + const int height = H, width = W; + + xtransborder_interpolate (1); + char xtrans[6][6]; + ri->getXtransMatrix(xtrans); + +#pragma omp parallel for + for(int row=1;rowsetProgress (1.0); + } +} +#undef fcol + + + +#undef TILEBORDER +#undef TILESIZE +#undef CACHESIZE +} /* namespace */ diff --git a/rtengine/dfmanager.cc b/rtengine/dfmanager.cc new file mode 100644 index 000000000..42eae61bb --- /dev/null +++ b/rtengine/dfmanager.cc @@ -0,0 +1,487 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "dfmanager.h" +#include "../rtgui/options.h" +#include +#include "../rtgui/guiutils.h" +#include "safegtk.h" +#include "rawimage.h" +#include +#include +#include +#include "imagedata.h" +#include + +namespace rtengine{ + +extern const Settings* settings; + +// *********************** class dfInfo ************************************** + +inline dfInfo& dfInfo::operator =(const dfInfo &o){ + pathname = o.pathname; + maker = o.maker; + model = o.model; + iso = o.iso; + shutter = o.shutter; + timestamp = o.timestamp; + if( ri ){ + delete ri; + ri = NULL; + } + return *this; +} + +bool dfInfo::operator <(const dfInfo &e2) const +{ + if( this->maker.compare( e2.maker) >=0 ) + return false; + if( this->model.compare( e2.model) >=0 ) + return false; + if( this->iso >= e2.iso ) + return false; + if( this->shutter >= e2.shutter ) + return false; + if( this->timestamp >= e2.timestamp ) + return false; + return true; +} + +std::string dfInfo::key(const std::string &mak, const std::string &mod, int iso, double shut ) +{ + std::ostringstream s; + s << mak << " " << mod << " "; + s.width(5); + s << iso << "ISO "; + s.precision( 2 ); + s.width(4); + s << shut << "s"; + return s.str(); +} + +double dfInfo::distance(const std::string &mak, const std::string &mod, int iso, double shutter) const +{ + if( this->maker.compare( mak) != 0 ) + return INFINITY; + if( this->model.compare( mod) != 0 ) + return INFINITY; + double dISO= (log(this->iso/100.) - log(iso/100.))/log(2); + double dShutter = (log(this->shutter) - log(shutter))/log(2); + return sqrt( dISO*dISO + dShutter*dShutter); +} + +RawImage* dfInfo::getRawImage() +{ + if(ri) + return ri; + updateRawImage(); + updateBadPixelList( ri ); + + return ri; +} + +std::vector& dfInfo::getHotPixels() +{ + if( !ri ){ + updateRawImage(); + updateBadPixelList( ri ); + } + return badPixels; +} +/* updateRawImage() load into ri the actual pixel data from pathname if there is a single shot + * otherwise load each file from the pathNames list and extract a template from the media; + * the first file is used also for reading all information other than pixels + */ +void dfInfo::updateRawImage() +{ + typedef unsigned int acc_t; + if( !pathNames.empty() ){ + std::list::iterator iName = pathNames.begin(); + ri = new RawImage(*iName); // First file used also for extra pixels informations (width,height, shutter, filters etc.. ) + if( ri->loadRaw(true)){ + delete ri; + ri=NULL; + }else{ + int H = ri->get_height(); + int W = ri->get_width(); + ri->compress_image(); + int rSize = W*((ri->getSensorType()==ST_BAYER || ri->getSensorType()==ST_FUJI_XTRANS)?1:3); + acc_t **acc = new acc_t*[H]; + for( int row=0; rowdata[row][col]; + int nFiles = 1; // First file data already loaded + + for( iName++; iName != pathNames.end(); iName++){ + RawImage* temp = new RawImage(*iName); + if( !temp->loadRaw(true)){ + temp->compress_image(); //\ TODO would be better working on original, because is temporary + nFiles++; + if( ri->getSensorType()==ST_BAYER || ri->getSensorType()==ST_FUJI_XTRANS ){ + for( int row=0; rowdata[row][col]; + } + }else{ + for( int row=0; rowdata[row][3*col+0]; + acc[row][3*col+1] += temp->data[row][3*col+1]; + acc[row][3*col+2] += temp->data[row][3*col+2]; + } + } + } + } + delete temp; + } + for (int row = 0; row < H; row++){ + for (int col = 0; col < rSize; col++) + ri->data[row][col] = acc[row][col] / nFiles; + delete [] acc[row]; + } + delete [] acc; + } + }else{ + ri = new RawImage(pathname); + if( ri->loadRaw(true)){ + delete ri; + ri=NULL; + }else + ri->compress_image(); + } +} + +void dfInfo::updateBadPixelList( RawImage *df ) +{ + const float threshold=10.f/8.f; + if( ri->getSensorType()==ST_BAYER || ri->getSensorType()==ST_FUJI_XTRANS ){ + std::vector badPixelsTemp; + +#pragma omp parallel +{ + std::vector badPixelsThread; +#pragma omp for nowait + for( int row=2; rowget_height()-2; row++) + for( int col=2; col < df->get_width()-2; col++){ + float m = (df->data[row-2][col-2] + df->data[row-2][col] + df->data[row-2][col+2]+ + df->data[row][col-2] + df->data[row][col+2]+ + df->data[row+2][col-2] + df->data[row+2][col] + df->data[row+2][col+2]); + if( df->data[row][col] > m*threshold ) + badPixelsThread.push_back( badPix(col,row) ); + } +#pragma omp critical + badPixelsTemp.insert(badPixelsTemp.end(),badPixelsThread.begin(),badPixelsThread.end()); +} + badPixels.insert(badPixels.end(),badPixelsTemp.begin(),badPixelsTemp.end()); + }else{ + for( int row=1; rowget_height()-1; row++) + for( int col=1; col < df->get_width()-1; col++){ + float m[3]; + for( int c=0; c<3;c++){ + m[c] = (df->data[row-1][3*(col-1)+c] + df->data[row-1][3*col+c] + df->data[row-1][3*(col+1)+c]+ + df->data[row] [3*(col-1)+c] + df->data[row] [3*col+c]+ + df->data[row+1][3*(col-1)+c] + df->data[row+1][3*col+c] + df->data[row+1][3*(col+1)+c]); + } + if( df->data[row][3*col] > m[0]*threshold || df->data[row][3*col+1] > m[1]*threshold || df->data[row][3*col+2] > m[2]*threshold) + badPixels.push_back( badPix(col,row) ); + } + } + if( settings->verbose ){ + std::cout << "Extracted " << badPixels.size() << " pixels from darkframe:" << df->get_filename().c_str() << std::endl; + } +} + + +// ************************* class DFManager ********************************* + +void DFManager::init( Glib::ustring pathname ) +{ + std::vector names; + Glib::RefPtr dir = Gio::File::create_for_path (pathname); + if( dir && !dir->query_exists()) + return; + safe_build_file_list (dir, names, pathname); + + dfList.clear(); + bpList.clear(); + for (size_t i=0; i0 && settings->verbose) + printf("Loaded %s: %d pixels\n",names[i].c_str(),n); + continue; + } + try{ + addFileInfo(names[i]); + }catch( std::exception& e ){} + } + // Where multiple shots exist for same group, move filename to list + for( dfList_t::iterator iter = dfList.begin(); iter != dfList.end();iter++ ){ + dfInfo &i = iter->second; + if( !i.pathNames.empty() && !i.pathname.empty() ){ + i.pathNames.push_back( i.pathname ); + i.pathname.clear(); + } + if( settings->verbose ){ + if( !i.pathname.empty() ) + printf( "%s: %s\n",i.key().c_str(),i.pathname.c_str()); + else{ + printf( "%s: MEAN of \n ",i.key().c_str()); + for( std::list::iterator iter = i.pathNames.begin(); iter != i.pathNames.end();iter++ ) + printf( "%s, ", iter->c_str() ); + printf("\n"); + } + } + } + currentPath = pathname; + return; +} + +dfInfo *DFManager::addFileInfo(const Glib::ustring &filename ,bool pool ) +{ + Glib::RefPtr file = Gio::File::create_for_path(filename); + if (!file ) + return 0; + if( !file->query_exists()) + return 0; + Glib::RefPtr info = safe_query_file_info(file); + if (info && info->get_file_type() != Gio::FILE_TYPE_DIRECTORY && (!info->is_hidden() || !options.fbShowHidden)) { + size_t lastdot = info->get_name().find_last_of ('.'); + if (options.is_extention_enabled(lastdot!=Glib::ustring::npos ? info->get_name().substr (lastdot+1) : "")){ + RawImage ri(filename); + int res = ri.loadRaw(false); // Read informations about shot + if( !res ){ + dfList_t::iterator iter; + if(!pool){ + dfInfo n(filename,"","",0,0,0); + iter = dfList.insert(std::pair< std::string,dfInfo>( "", 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); + /* 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 ); + 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 ) ); + }else{ + 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 ); + 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 ) ); + } + } + return &(iter->second); + } + } + } + return 0; +} + +void DFManager::getStat( int &totFiles, int &totTemplates) +{ + totFiles=0; + totTemplates=0; + for( dfList_t::iterator iter = dfList.begin(); iter != dfList.end();iter++ ){ + dfInfo &i = iter->second; + if( i.pathname.empty() ){ + totTemplates++; + totFiles += i.pathNames.size(); + }else + totFiles++; + } +} + +/* The search for the best match is twofold: + * if perfect matches for iso and shutter are found, then the list is scanned for lesser distance in time + * otherwise if no match is found, the whole list is searched for lesser distance in iso and shutter + */ +dfInfo* DFManager::find( const std::string &mak, const std::string &mod, int isospeed, double shut, time_t t ) +{ + if( dfList.empty() ) + return 0; + std::string key( dfInfo::key(mak,mod,isospeed,shut) ); + dfList_t::iterator iter = dfList.find( key ); + + if( iter != dfList.end() ){ + dfList_t::iterator bestMatch = iter; + time_t bestDeltaTime = ABS(iter->second.timestamp - t); + for(iter++; iter != dfList.end() && !key.compare( iter->second.key() ); iter++ ){ + time_t d = ABS(iter->second.timestamp - t ); + if( d< bestDeltaTime ){ + bestMatch = iter; + bestDeltaTime = d; + } + } + return &(bestMatch->second); + }else{ + iter = dfList.begin(); + dfList_t::iterator bestMatch = iter; + double bestD = iter->second.distance( mak, mod, isospeed, shut ); + for( iter++; iter != dfList.end();iter++ ){ + double d = iter->second.distance( mak, mod, isospeed, shut ); + if( d < bestD ){ + bestD = d; + bestMatch = iter; + } + } + return bestD != INFINITY ? &(bestMatch->second) : 0 ; + } +} + +RawImage* DFManager::searchDarkFrame( const std::string &mak, const std::string &mod, int iso, double shut, time_t t ) +{ + dfInfo *df = find( ((Glib::ustring)mak).uppercase(), ((Glib::ustring)mod).uppercase(), iso, shut, t ); + if( df ) + return df->getRawImage(); + else + return 0; +} + +RawImage* DFManager::searchDarkFrame( const Glib::ustring filename ) +{ + for ( dfList_t::iterator iter = dfList.begin(); iter != dfList.end();iter++ ){ + if( iter->second.pathname.compare( filename )==0 ) + return iter->second.getRawImage(); + } + dfInfo *df = addFileInfo( filename, false ); + if(df) + return df->getRawImage(); + return 0; +} +std::vector *DFManager::getHotPixels ( const Glib::ustring filename ) +{ + for ( dfList_t::iterator iter = dfList.begin(); iter != dfList.end();iter++ ){ + if( iter->second.pathname.compare( filename )==0 ) + return &iter->second.getHotPixels(); + } + return 0; +} +std::vector *DFManager::getHotPixels ( const std::string &mak, const std::string &mod, int iso, double shut, time_t t ) +{ + dfInfo *df = find( ((Glib::ustring)mak).uppercase(), ((Glib::ustring)mod).uppercase(), iso, shut, t ); + if( df ){ + if( settings->verbose ) { + if( !df->pathname.empty() ) { + printf( "Searched hotpixels from %s\n",df->pathname.c_str()); + } else { + if( !df->pathNames.empty() ) { + printf( "Searched hotpixels from template (first %s)\n",df->pathNames.begin()->c_str()); + } + } + } + return &df->getHotPixels(); + }else + return 0; +} + +int DFManager::scanBadPixelsFile( Glib::ustring filename ) +{ + FILE *file = fopen( filename.c_str(),"r" ); + if( !file ) return false; + size_t lastdot = filename.find_last_of ('.'); + size_t dirpos1 = filename.find_last_of ('/'); + size_t dirpos2 = filename.find_last_of ('\\'); + if( dirpos1 == Glib::ustring::npos && dirpos2== Glib::ustring::npos ) + dirpos1 =0; + else if( dirpos1 != Glib::ustring::npos && dirpos2 != Glib::ustring::npos ) + dirpos1= (dirpos1> dirpos2 ? dirpos1: dirpos2); + else if( dirpos1 == Glib::ustring::npos ) + dirpos1= dirpos2; + + std::string makmodel(filename,dirpos1+1,lastdot-(dirpos1+1) ); + std::vector bp; + char line[256]; + if(fgets(line,sizeof(line),file )) { + int x,y; + int offset = 0; + int numparms = sscanf(line,"%d %d",&x,&y); + if( numparms == 1 ) // only one number in first line means, that this is the offset. + offset = x; + else if(numparms == 2) + bp.push_back( badPix(x+offset,y+offset) ); + while( fgets(line,sizeof(line),file ) ){ + if( sscanf(line,"%d %d",&x,&y) == 2 ) + bp.push_back( badPix(x+offset,y+offset) ); + } + } + int numPixels = bp.size(); + if( numPixels >0 ) + bpList[ makmodel ] = bp; + fclose(file); + return numPixels; +} + +std::vector *DFManager::getBadPixels ( const std::string &mak, const std::string &mod, const std::string &serial) +{ + bpList_t::iterator iter; + bool found = false; + if( !serial.empty() ) { + // search with sreial number first + std::ostringstream s; + s << mak << " " << mod << " " << serial; + iter = bpList.find( s.str() ); + if( iter != bpList.end() ) + found = true; + if( settings->verbose ) + if(found) + printf("%s.badpixels found\n",s.str().c_str()); + else + printf("%s.badpixels not found\n",s.str().c_str()); + + } + if(!found) { + // search without serial number + std::ostringstream s; + s << mak << " " <verbose ) + if(found) + printf("%s.badpixels found\n",s.str().c_str()); + else + printf("%s.badpixels not found\n",s.str().c_str()); + } + if(!found) { + return 0; + } else { + return &(iter->second); + } +} + +// Global variable +DFManager dfm; + + +} + diff --git a/rtengine/dfmanager.h b/rtengine/dfmanager.h new file mode 100644 index 000000000..11d110cc3 --- /dev/null +++ b/rtengine/dfmanager.h @@ -0,0 +1,94 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 +#include +#include "rawimage.h" + +namespace rtengine{ + +class dfInfo +{ +public: + + Glib::ustring pathname; // filename of dark frame + std::list pathNames; // other similar dark frames, used for average + std::string maker; ///< manufacturer + std::string model; ///< model + int iso; ///< ISO (gain) + double shutter; ///< shutter or exposure time in sec + time_t timestamp; ///< seconds since 1 Jan 1970 + + + dfInfo(const Glib::ustring &name, const std::string &mak, const std::string &mod,int iso,double shut,time_t t) + :pathname(name),maker(mak),model(mod),iso(iso),shutter(shut),timestamp(t),ri(NULL){} + + dfInfo( const dfInfo &o) + :pathname(o.pathname),maker(o.maker),model(o.model),iso(o.iso),shutter(o.shutter),timestamp(o.timestamp),ri(NULL){} + ~dfInfo() { if( ri ) delete ri; } + + + dfInfo &operator =(const dfInfo &o); + bool operator <(const dfInfo &e2) const; + + // Calculate virtual distance between two shots; different model return infinite + double distance(const std::string &mak, const std::string &mod, int iso, double shutter) const; + + static std::string key(const std::string &mak, const std::string &mod, int iso, double shut ); + std::string key(){ return key( maker,model,iso,shutter); } + + RawImage *getRawImage(); + std::vector &getHotPixels(); + +protected: + RawImage *ri; ///< Dark Frame raw data + std::vector badPixels; ///< Extracted hot pixels + + void updateBadPixelList( RawImage *df ); + void updateRawImage(); +}; + +class DFManager +{ +public: + void init( Glib::ustring pathname ); + Glib::ustring getPathname(){ return currentPath; }; + void getStat( int &totFiles, int &totTemplate); + RawImage *searchDarkFrame( const std::string &mak, const std::string &mod, int iso, double shut, time_t t ); + RawImage *searchDarkFrame( const Glib::ustring filename ); + std::vector *getHotPixels ( const std::string &mak, const std::string &mod, int iso, double shut, time_t t ); + std::vector *getHotPixels ( const Glib::ustring filename ); + std::vector *getBadPixels ( const std::string &mak, const std::string &mod, const std::string &serial); + +protected: + typedef std::multimap dfList_t; + typedef std::map > bpList_t; + dfList_t dfList; + bpList_t bpList; + bool initialized; + Glib::ustring currentPath; + dfInfo *addFileInfo(const Glib::ustring &filename, bool pool=true ); + dfInfo *find( const std::string &mak, const std::string &mod, int isospeed, double shut, time_t t ); + int scanBadPixelsFile( Glib::ustring filename ); +}; + +extern DFManager dfm; + +} diff --git a/rtengine/diagonalcurves.cc b/rtengine/diagonalcurves.cc new file mode 100644 index 000000000..20b22a916 --- /dev/null +++ b/rtengine/diagonalcurves.cc @@ -0,0 +1,326 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "curves.h" +#include +#include +#include "mytime.h" +#include + +#define CLIPD(a) ((a)>0.0?((a)<1.0?(a):1.0):0.0) + +namespace rtengine { + +DiagonalCurve::DiagonalCurve (const std::vector& p, int poly_pn) { + + ppn = poly_pn > 65500 ? 65500 : poly_pn; + bool identity = true; + + if (ppn < 500) hashSize = 100; // Arbitrary cut-off value, but mutliple of 10 + if (ppn < 50) hashSize = 10; // Arbitrary cut-off value, but mutliple of 10 + + if (p.size()<3) { + kind = DCT_Empty; + } + else { + kind = (DiagonalCurveType)p[0]; + if (kind==DCT_Linear || kind==DCT_Spline || kind==DCT_NURBS) { + N = (p.size()-1)/2; + x = new double[N]; + y = new double[N]; + int ix = 1; + for (int i=0; i 2) + spline_cubic_set (); + else if (kind==DCT_NURBS && N > 2) { + NURBS_set (); + fillHash(); + } + else kind=DCT_Linear; + } + } + else if (kind==DCT_Parametric) { + if ((p.size()==8 || p.size()==9) && (p.at(4)!=0.0f || p.at(5)!=0.0f || p.at(6)!=0.0f || p.at(7)!=0.0f)) { + identity = false; + + x = new double[9]; + x[0] = p[0]; + for (int i=1; i<4; i++) { + x[i] = min(max(p[i],0.001),0.99); + } + for (int i=4; i<8; i++) + x[i] = (p[i]+100.0)/200.0; + if (p.size()<9) + x[8] = 1.0; + else + x[8] = p[8]/100.0; + mc = -xlog(2.0)/xlog(x[2]); + double mbase = pfull (0.5, x[8], x[6], x[5]); + mfc = mbase<=1e-14 ? 0.0 : xexp(xlog(mbase)/mc); // value of the curve at the center point + msc = -xlog(2.0)/xlog(x[1]/x[2]); + mhc = -xlog(2.0)/xlog((x[3]-x[2])/(1-x[2])); + } + } + if (identity) { + kind = DCT_Empty; + } + } +} + +DiagonalCurve::~DiagonalCurve () { + + delete [] x; + delete [] y; + delete [] ypp; + poly_x.clear(); + poly_y.clear(); +} + +void DiagonalCurve::spline_cubic_set () { + + double* u = new double[N-1]; + delete [] ypp; // TODO: why do we delete ypp here since it should not be allocated yet? + ypp = new double [N]; + + ypp[0] = u[0] = 0.0; /* set lower boundary condition to "natural" */ + + for (int i = 1; i < N - 1; ++i) { + double sig = (x[i] - x[i - 1]) / (x[i + 1] - x[i - 1]); + double p = sig * ypp[i - 1] + 2.0; + ypp[i] = (sig - 1.0) / p; + u[i] = ((y[i + 1] - y[i]) + / (x[i + 1] - x[i]) - (y[i] - y[i - 1]) / (x[i] - x[i - 1])); + u[i] = (6.0 * u[i] / (x[i + 1] - x[i - 1]) - sig * u[i - 1]) / p; + } + + ypp[N - 1] = 0.0; + for (int k = N - 2; k >= 0; --k) + ypp[k] = ypp[k] * ypp[k + 1] + u[k]; + + delete [] u; +} + +void DiagonalCurve::NURBS_set () { + + int nbSubCurvesPoints = N + (N-3)*2; + + std::vector sc_x(nbSubCurvesPoints); // X sub-curve points ( XP0,XP1,XP2, XP2,XP3,XP4, ...) + std::vector sc_y(nbSubCurvesPoints); // Y sub-curve points ( YP0,YP1,YP2, YP2,YP3,YP4, ...) + std::vector sc_length(N+2); // Length of the subcurves + double total_length=0.; + + // Create the list of Bezier sub-curves + // NURBS_set is called if N > 2 and non identity only + + int j = 0; + int k = 0; + for (int i = 0; i < N-1;) { + double length; + double dx; + double dy; + + // first point (on the curve) + if (!i) { + sc_x[j] = x[i]; + sc_y[j++] = y[i++]; + } + else { + sc_x[j] = (x[i-1] + x[i]) / 2.; + sc_y[j++] = (y[i-1] + y[i]) / 2.; + } + + // second point (control point) + sc_x[j] = x[i]; + sc_y[j] = y[i++]; + + dx = sc_x[j] - sc_x[j-1]; + dy = sc_y[j] - sc_y[j-1]; + length = sqrt(dx*dx + dy*dy); + j++; + + // third point (on the curve) + if (i==N-1) { + sc_x[j] = x[i]; + sc_y[j] = y[i]; + } + else { + sc_x[j] = (x[i-1] + x[i]) / 2.; + sc_y[j] = (y[i-1] + y[i]) / 2.; + } + dx = sc_x[j] - sc_x[j-1]; + dy = sc_y[j] - sc_y[j-1]; + length += sqrt(dx*dx + dy*dy); + j++; + + // Storing the length of all sub-curves and the total length (to have a better distribution + // of the points along the curve) + sc_length[k++] = length; + total_length += length; + } + + poly_x.clear(); + poly_y.clear(); + unsigned int sc_xsize=j-1; + j = 0; + + // adding the initial horizontal segment, if any + if (x[0] > 0.) { + poly_x.push_back(0.); + poly_y.push_back(y[0]); + } + + // adding the initial horizontal segment, if any + // create the polyline with the number of points adapted to the X range of the sub-curve + for (unsigned int i=0; i < sc_xsize /*sc_x.size()*/; i+=3) { + // TODO: Speeding-up the interface by caching the polyline, instead of rebuilding it at each action on sliders !!! + nbr_points = (int)(((double)(ppn+N-2) * sc_length[i/3] )/ total_length); + if (nbr_points<0){ + for(size_t it=0;it < sc_x.size(); it+=3) printf("sc_length[%zu/3]=%f \n",it,sc_length[it/3]); + printf("NURBS diagonal curve: error detected!\n i=%d nbr_points=%d ppn=%d N=%d sc_length[i/3]=%f total_length=%f",i,nbr_points,ppn,N,sc_length[i/3],total_length); + exit(0); + } + // increment along the curve, not along the X axis + increment = 1.0 / (double)(nbr_points-1); + x1 = sc_x[i]; y1 = sc_y[i]; + x2 = sc_x[i+1]; y2 = sc_y[i+1]; + x3 = sc_x[i+2]; y3 = sc_y[i+2]; + firstPointIncluded = !i; + AddPolygons (); + } + + // adding the final horizontal segment, always (see under) + poly_x.push_back(3.0); // 3.0 is a hack for optimization purpose of the getVal method (the last value has to be beyond the normal range) + poly_y.push_back(y[N-1]); +} + +double DiagonalCurve::getVal (double t) const { + + switch (kind) { + + case DCT_Parametric : { + if (t<=1e-14) + return 0.0; + double tv = xexp(mc*xlog(t)); + double base = pfull (tv, x[8], x[6], x[5]); + double stretched = base<=1e-14 ? 0.0 : xexp(xlog(base)/mc); + + if (tx[N-1]) + return y[N-1]; + else if (t 1){ + int k = (k_hi + k_lo) / 2; + if (x[k] > t) + k_hi = k; + else + k_lo = k; + } + + double h = x[k_hi] - x[k_lo]; + // linear + if (kind==DCT_Linear) + return y[k_lo] + (t - x[k_lo]) * ( y[k_hi] - y[k_lo] ) / h; + // spline curve + else { // if (kind==Spline) { + double a = (x[k_hi] - t) / h; + double b = (t - x[k_lo]) / h; + double r = a*y[k_lo] + b*y[k_hi] + ((a*a*a - a)*ypp[k_lo] + (b*b*b - b)*ypp[k_hi]) * (h*h)/6.0; + return CLIPD(r); + } + break; + } + case DCT_NURBS : { + // get the hash table entry by rounding the value (previously multiplied by "hashSize") + unsigned short int i = (unsigned short int)(t*hashSize); + + if (i > (hashSize+1)) { + //printf("\nOVERFLOW: hash #%d is used while seeking for value %.8f, corresponding polygon's point #%d (out of %d point) x value: %.8f\n\n", i, t, hash.at(i), poly_x.size(), poly_x[hash.at(i)]); + printf("\nOVERFLOW: hash #%d is used while seeking for value %.8f\n\n", i, t); + return t; + } + + unsigned int k_lo; + unsigned int k_hi; + + k_lo = hash.at(i).smallerValue; + k_hi = hash.at(i).higherValue; + + // do a binary search for the right interval : + while (k_hi - k_lo > 1){ + unsigned int k = (k_hi + k_lo) / 2; + if (poly_x[k] > t) + k_hi = k; + else + k_lo = k; + } + if (k_lo == k_hi) + k_hi = k_lo+1; + + double dx = poly_x[k_hi] - poly_x[k_lo]; + double dy = poly_y[k_hi] - poly_y[k_lo]; + return poly_y[k_lo] + (t - poly_x[k_lo]) * ( dy ) / dx; + break; + } + case DCT_Empty : + default: + // all other (unknown) kind + return t; + } +} + +void DiagonalCurve::getVal (const std::vector& t, std::vector& res) const { + + res.resize (t.size()); + for (unsigned int i=0; i. + * + * � 2010 Emil Martinec + * + */ + +#include +#include +#include "curves.h" +#include "labimage.h" +#include "improcfun.h" +#include "array2D.h" +#include "rt_math.h" + +#ifdef _OPENMP +#include +#endif + +#define CLIPC(a) ((a)>-32000?((a)<32000?(a):32000):-32000) + +#define DIRWT_L(i1,j1,i,j) ( rangefn_L[(data_fine->L[i1][j1]-data_fine->L[i][j]+32768)] ) + +#define DIRWT_AB(i1,j1,i,j) ( rangefn_ab[(data_fine->a[i1][j1]-data_fine->a[i][j]+32768)] * \ +rangefn_ab[(data_fine->L[i1][j1]-data_fine->L[i][j]+32768)] * \ +rangefn_ab[(data_fine->b[i1][j1]-data_fine->b[i][j]+32768)] ) + +//#define NRWT_L(a) (nrwt_l[a] ) + +#define NRWT_AB (nrwt_ab[(hipass[1]+32768)] * nrwt_ab[(hipass[2]+32768)]) + + +#define med3(a,b,c) (a(b)) {temp=(a);(a)=(b);(b)=temp;} } + +#define med3x3(a0,a1,a2,a3,a4,a5,a6,a7,a8,median) { \ +p[0]=a0; p[1]=a1; p[2]=a2; p[3]=a3; p[4]=a4; p[5]=a5; p[6]=a6; p[7]=a7; p[8]=a8; \ +PIX_SORT(p[1],p[2]); PIX_SORT(p[4],p[5]); PIX_SORT(p[7],p[8]); \ +PIX_SORT(p[0],p[1]); PIX_SORT(p[3],p[4]); PIX_SORT(p[6],p[7]); \ +PIX_SORT(p[1],p[2]); PIX_SORT(p[4],p[5]); PIX_SORT(p[7],p[8]); \ +PIX_SORT(p[0],p[3]); PIX_SORT(p[5],p[8]); PIX_SORT(p[4],p[7]); \ +PIX_SORT(p[3],p[6]); PIX_SORT(p[1],p[4]); PIX_SORT(p[2],p[5]); \ +PIX_SORT(p[4],p[7]); PIX_SORT(p[4],p[2]); PIX_SORT(p[6],p[4]); \ +PIX_SORT(p[4],p[2]); median=p[4];} //a4 is the median + + +namespace rtengine { + + static const int maxlevel = 4; + + //sequence of scales + //static const int scales[8] = {1,2,4,8,16,32,64,128}; + //sequence of pitches + //static const int pitches[8] = {1,1,1,1,1,1,1,1}; + + //sequence of scales + //static const int scales[8] = {1,1,1,1,1,1,1,1}; + //sequence of pitches + //static const int pitches[8] = {2,2,2,2,2,2,2,2}; + + //sequence of scales + //static const int scales[8] = {1,1,2,2,4,4,8,8}; + //sequence of pitches + //static const int pitches[8] = {2,1,2,1,2,1,2,1}; + + //sequence of scales + static const int scales[8] = {1,1,2,4,8,16,32,64}; + //sequence of pitches + static const int pitches[8] = {2,1,1,1,1,1,1,1}; + + //pitch is spacing of subsampling + //scale is spacing of directional averaging weights + //example 1: no subsampling at any level -- pitch=1, scale=2^n + //example 2: subsampling by 2 every level -- pitch=2, scale=1 at each level + //example 3: no subsampling at first level, subsampling by 2 thereafter -- + // pitch =1, scale=1 at first level; pitch=2, scale=2 thereafter + + + + + void ImProcFunctions :: dirpyrLab_denoise(LabImage * src, LabImage * dst, const procparams::DirPyrDenoiseParams & dnparams ) + { + float gam = dnparams.gamma/3.0; + //float gam = 2.0;//min(3.0, 0.1*fabs(c[4])/3.0+0.001); + float gamthresh = 0.03; + float gamslope = exp(log((double)gamthresh)/gam)/gamthresh; + + LUTf gamcurve(65536,0); + + //DiagonalCurve* lumacurve = new DiagonalCurve (dnparams.lumcurve, CURVES_MIN_POLY_POINTS); + //DiagonalCurve* chromacurve = new DiagonalCurve (dnparams.chromcurve, CURVES_MIN_POLY_POINTS); + //LUTf Lcurve(65536); + //LUTf abcurve(65536); + for (int i=0; i<65536; i++) { + int g = (int)(CurveFactory::gamma((double)i/65535.0, gam, gamthresh, gamslope, 1.0, 0.0) * 65535.0); + gamcurve[i] = CLIP(g); + /*float val = (float)i/65535.0; + float Lval = (2*(lumacurve->getVal(val))); + float abval = (2*(chromacurve->getVal(val))); + + Lcurve[i] = SQR(Lval); + abcurve[i] = SQR(abval); + if (i % 1000 ==0) printf("%d Lmult=%f abmult=%f \n",i,Lcurve[i],abcurve[i]);*/ + } + //delete lumacurve; + //delete chromacurve; + + + + //#pragma omp parallel for if (multiThread) + for (int i=0; iH; i++) { + for (int j=0; jW; j++) { + //src->L[i][j] = CurveFactory::flinterp(gamcurve,src->L[i][j]); + src->L[i][j] = gamcurve[src->L[i][j]]; + } + } + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + + LUTf rangefn_L(65536); + LUTf nrwt_l(65536); + + LUTf rangefn_ab(65536); + LUTf nrwt_ab(65536); + + //set up NR weight functions + + //gamma correction for chroma in shadows + float nrwtl_norm = ((CurveFactory::gamma((double)65535.0/65535.0, gam, gamthresh, gamslope, 1.0, 0.0)) - + (CurveFactory::gamma((double)75535.0/65535.0, gam, gamthresh, gamslope, 1.0, 0.0))); + for (int i=0; i<65536; i++) { + nrwt_l[i] = ((CurveFactory::gamma((double)i/65535.0, gam, gamthresh, gamslope, 1.0, 0.0) - + CurveFactory::gamma((double)(i+10000)/65535.0, gam, gamthresh, gamslope, 1.0, 0.0)) )/nrwtl_norm; + //if (i % 100 ==0) printf("%d %f \n",i,nrwt_l[i]); + } + + float tonefactor = nrwt_l[32768]; + + float noise_L = 10.0*dnparams.luma; + float noisevar_L = SQR(noise_L); + + float noise_ab = 100.0*dnparams.chroma; + float noisevar_ab = SQR(noise_ab); + + + //set up range functions + for (int i=0; i<65536; i++) + rangefn_L[i] = (( exp(-(double)fabs(i-32768) * tonefactor / (1.0+noise_L)) * (1.0+noisevar_L)/((double)(i-32768)*(double)(i-32768) + noisevar_L+1.0))); + for (int i=0; i<65536; i++) + rangefn_ab[i] = (( exp(-(double)fabs(i-32768) * tonefactor / (1.0+3*noise_ab)) * (1.0+noisevar_ab)/((double)(i-32768)*(double)(i-32768) + noisevar_ab+1.0))); + + + for (int i=0; i<65536; i++) + nrwt_ab[i] = ((1.0+abs(i-32768)/(1.0+8*noise_ab)) * exp(-(double)fabs(i-32768)/ (1.0+8*noise_ab) ) ); + + + //for (int i=0; i<65536; i+=100) printf("%d %d \n",i,gamcurve[i]); + + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + + int level; + + LabImage * dirpyrLablo[maxlevel]; + int w = (int)((src->W-1)/pitches[0])+1; + int h = (int)((src->H-1)/pitches[0])+1; + dirpyrLablo[0] = new LabImage(w, h); + for (level=1; level 0; level--) + { + + int scale = scales[level]; + int pitch = pitches[level]; + idirpyr(dirpyrLablo[level], dirpyrLablo[level-1], level, rangefn_L, nrwt_l, nrwt_ab, pitch, scale, dnparams.luma, dnparams.chroma/*, Lcurve, abcurve*/ ); + } + + + scale = scales[0]; + pitch = pitches[0]; + // freeing as much memory as possible since the next call to idirpyr will need lots + for(int i = 1; i < maxlevel; i++) { + delete dirpyrLablo[i]; + } + + idirpyr(dirpyrLablo[0], dst, 0, rangefn_L, nrwt_l, nrwt_ab, pitch, scale, dnparams.luma, dnparams.chroma/*, Lcurve, abcurve*/ ); + + // freeing the last bunch of memory + delete dirpyrLablo[0]; + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + float igam = 1/gam; + float igamthresh = gamthresh*gamslope; + float igamslope = 1/gamslope; + for (int i=0; i<65536; i++) { + gamcurve[i] = (CurveFactory::gamma((float)i/65535.0, igam, igamthresh, igamslope, 1.0, 0.0) * 65535.0); + } + + + if (dnparams.luma>0) { + for (int i=0; iH; i++) + for (int j=0; jW; j++) { + dst->L[i][j] = gamcurve[dst->L[i][j]]; + } + } else { + for (int i=0; iH; i++) + for (int j=0; jW; j++) { + dst->L[i][j] = gamcurve[src->L[i][j]]; + } + } + + } + + void ImProcFunctions::dirpyr(LabImage* data_fine, LabImage* data_coarse, int level, + LUTf & rangefn_L, LUTf & rangefn_ab, int pitch, int scale, + const int luma, const int chroma ) + { + + //pitch is spacing of subsampling + //scale is spacing of directional averaging weights + //example 1: no subsampling at any level -- pitch=1, scale=2^n + //example 2: subsampling by 2 every level -- pitch=2, scale=1 at each level + //example 3: no subsampling at first level, subsampling by 2 thereafter -- + // pitch =1, scale=1 at first level; pitch=2, scale=2 thereafter + + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // calculate weights, compute directionally weighted average + + int width = data_fine->W; + int height = data_fine->H; + + //generate domain kernel + int halfwin = 3;//min(ceil(2*sig),3); + int scalewin = halfwin*scale; + +#ifdef _OPENMP +#pragma omp parallel for +#endif + + for(int i = 0; i < height; i+=pitch ) { int i1=i/pitch; + for(int j = 0, j1=0; j < width; j+=pitch, j1++) + { + float dirwt_l, dirwt_ab, norm_l, norm_ab; + //float lops,aops,bops; + float Lout, aout, bout; + norm_l = norm_ab = 0;//if we do want to include the input pixel in the sum + Lout = 0; + aout = 0; + bout = 0; + + for(int inbr=(i-scalewin); inbr<=(i+scalewin); inbr+=scale) { + if (inbr<0 || inbr>height-1) continue; + for (int jnbr=(j-scalewin); jnbr<=(j+scalewin); jnbr+=scale) { + if (jnbr<0 || jnbr>width-1) continue; + dirwt_l = DIRWT_L(inbr, jnbr, i, j); + dirwt_ab = DIRWT_AB(inbr, jnbr, i, j); + Lout += dirwt_l*data_fine->L[inbr][jnbr]; + aout += dirwt_ab*data_fine->a[inbr][jnbr]; + bout += dirwt_ab*data_fine->b[inbr][jnbr]; + norm_l += dirwt_l; + norm_ab += dirwt_ab; + } + } + //lops = Lout/norm;//diagnostic + //aops = aout/normab;//diagnostic + //bops = bout/normab;//diagnostic + + data_coarse->L[i1][j1]=Lout/norm_l;//low pass filter + data_coarse->a[i1][j1]=aout/norm_ab; + data_coarse->b[i1][j1]=bout/norm_ab; + + + /*if (level<2 && i>0 && i0 && jL[i-1][j-1], data_fine->L[i-1][j], data_fine->L[i-1][j+1], \ + data_fine->L[i][j-1], data_fine->L[i][j], data_fine->L[i][j+1], \ + data_fine->L[i+1][j-1], data_fine->L[i+1][j], data_fine->L[i+1][j+1]); + //med3x3(data_fine->L[i-1][j-1], data_fine->L[i-1][j], data_fine->L[i-1][j+1], \ + data_fine->L[i][j-1], data_fine->L[i][j], data_fine->L[i][j+1], \ + data_fine->L[i+1][j-1], data_fine->L[i+1][j], data_fine->L[i+1][j+1],Lmed); + + data_coarse->L[i1][j1] = Lhmf; + }*/ + } + } + + + + + } + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + void ImProcFunctions::idirpyr(LabImage* data_coarse, LabImage* data_fine, int level, LUTf &rangefn_L, LUTf & nrwt_l, LUTf & nrwt_ab, + int pitch, int scale, const int luma, const int chroma/*, LUTf & Lcurve, LUTf & abcurve*/ ) + { + + int width = data_fine->W; + int height = data_fine->H; + + array2D nrfactorL (width,height); + + //float eps = 0.0; + + // c[0] noise_L + // c[1] noise_ab (relative to noise_L) + // c[2] decrease of noise var with scale + // c[3] radius of domain blur at each level + // c[4] shadow smoothing + + float noisevar_L = 4*SQR(25.0 * luma); + float noisevar_ab = 2*SQR(100.0 * chroma); + float scalefactor = 1.0/pow(2.0,(level+1)*2);//change the last 2 to 1 for longer tail of higher scale NR + + noisevar_L *= scalefactor; + + // for coarsest level, take non-subsampled lopass image and subtract from lopass_fine to generate hipass image + + // denoise hipass image, add back into lopass_fine to generate denoised image at fine scale + + // now iterate: + // (1) take denoised image at level n, expand and smooth using gradient weights from lopass image at level n-1 + // the result is the smoothed image at level n-1 + // (2) subtract smoothed image at level n-1 from lopass image at level n-1 to make hipass image at level n-1 + // (3) denoise the hipass image at level n-1 + // (4) add the denoised image at level n-1 to the smoothed image at level n-1 to make the denoised image at level n-1 + + // note that the coarsest level amounts to skipping step (1) and doing (2,3,4). + // in other words, skip step one if pitch=1 + + // step (1) + + if (pitch==1) { + + // step (1-2-3-4) + +#ifdef _OPENMP +#pragma omp parallel +#endif +{ + +#ifdef _OPENMP +#pragma omp for +#endif + for(int i = 0; i < height; i++) + for(int j = 0; j < width; j++) { + float hipass[3], hpffluct[3], tonefactor, nrfactor; + + tonefactor = (nrwt_l[data_coarse->L[i][j]]); + + hipass[1] = data_fine->a[i][j]-data_coarse->a[i][j]; + hipass[2] = data_fine->b[i][j]-data_coarse->b[i][j]; + + //Wiener filter + //luma + if (level<2) { + hipass[0] = data_fine->L[i][j]-data_coarse->L[i][j]; + hpffluct[0]=SQR(hipass[0])+SQR(hipass[1])+SQR(hipass[2])+0.001; + nrfactorL[i][j] = (1.0+hpffluct[0])/(1.0+hpffluct[0]+noisevar_L /* * Lcurve[data_coarse->L[i][j]]*/); + //hipass[0] *= hpffluct[0]/(hpffluct[0]+noisevar_L); + //data_fine->L[i][j] = CLIP(hipass[0]+data_coarse->L[i][j]); + } + + //chroma + //hipass[1] = data_fine->a[i][j]-data_coarse->a[i][j]; + //hipass[2] = data_fine->b[i][j]-data_coarse->b[i][j]; + hpffluct[1]=SQR(hipass[1]*tonefactor)+0.001; + hpffluct[2]=SQR(hipass[2]*tonefactor)+0.001; + nrfactor = (hpffluct[1]+hpffluct[2]) /((hpffluct[1]+hpffluct[2]) + noisevar_ab * NRWT_AB); + + hipass[1] *= nrfactor; + hipass[2] *= nrfactor; + + data_fine->a[i][j] = hipass[1]+data_coarse->a[i][j]; + data_fine->b[i][j] = hipass[2]+data_coarse->b[i][j]; + } + + if (level<2) { +#ifdef _OPENMP +#pragma omp for +#endif + for(int i = 0; i < height; i++) + for(int j = 0; j < width; j++) { + + float dirwt_l, norm_l; + float nrfctrave=0; + norm_l = 0;//if we do want to include the input pixel in the sum + + for(int inbr=max(0,i-1); inbr<=min(height-1,i+1); inbr++) { + for (int jnbr=max(0,j-1); jnbr<=min(width-1,j+1); jnbr++) { + dirwt_l = DIRWT_L(inbr, jnbr, i, j); + nrfctrave += dirwt_l*nrfactorL[inbr][jnbr]; + norm_l += dirwt_l; + } + } + + nrfctrave /= norm_l; + //nrfctrave = nrfactorL[i][j]; + //nrfctrave=1; + + float hipass[3]; + + //luma + + /*if (i>0 && i0 && jL[i][j]-data_coarse->L[i][j]); + //hipass[0] = median*(data_fine->L[i][j]-data_coarse->L[i][j]); + //hipass[0] = nrfactorL[i][j]*(data_fine->L[i][j]-data_coarse->L[i][j]); + data_fine->L[i][j] = CLIP(hipass[0]+data_coarse->L[i][j]); + + //chroma + //hipass[1] = nrfactorab[i][j]*(data_fine->a[i][j]-data_coarse->a[i][j]); + //hipass[2] = nrfactorab[i][j]*(data_fine->b[i][j]-data_coarse->b[i][j]); + + //data_fine->a[i][j] = hipass[1]+data_coarse->a[i][j]; + //data_fine->b[i][j] = hipass[2]+data_coarse->b[i][j]; + } + }//end of luminance correction + + + +}//end of pitch=1 + + } else {//pitch>1 + + LabImage* smooth; + + smooth = new LabImage(width, height); +#ifdef _OPENMP +#pragma omp parallel +#endif + +{ + +#ifdef _OPENMP +#pragma omp for +#endif + for(int i = 0; i < height; i+=pitch) + { + int ix=i/pitch; + for(int j = 0, jx=0; j < width; j+=pitch, jx++) { + + //copy common pixels + smooth->L[i][j] = data_coarse->L[ix][jx]; + smooth->a[i][j] = data_coarse->a[ix][jx]; + smooth->b[i][j] = data_coarse->b[ix][jx]; + } + } + //if (pitch>1) {//pitch=2; step (1) expand coarse image, fill in missing data +#ifdef _OPENMP +#pragma omp for +#endif + for(int i = 0; i < height-1; i+=2) + for(int j = 0; j < width-1; j+=2) { + //do midpoint first + double norm=0.0,wtdsum[3]={0.0,0.0,0.0}; + //wtdsum[0]=wtdsum[1]=wtdsum[2]=0.0; + for(int ix=i; ixL[ix][jx]; + wtdsum[1] += smooth->a[ix][jx]; + wtdsum[2] += smooth->b[ix][jx]; + norm++; + } + norm = 1/norm; + smooth->L[i+1][j+1]=wtdsum[0]*norm; + smooth->a[i+1][j+1]=wtdsum[1]*norm; + smooth->b[i+1][j+1]=wtdsum[2]*norm; + } +#ifdef _OPENMP +#pragma omp for +#endif + + for(int i = 0; i < height-1; i+=2) + for(int j = 0; j < width-1; j+=2) { + //now right neighbor + if (j+1==width) continue; + double norm=0.0,wtdsum[3]={0.0,0.0,0.0}; + + for (int jx=j; jxL[i][jx]; + wtdsum[1] += smooth->a[i][jx]; + wtdsum[2] += smooth->b[i][jx]; + norm++; + } + for (int ix=max(0,i-1); ixL[ix][j+1]; + wtdsum[1] += smooth->a[ix][j+1]; + wtdsum[2] += smooth->b[ix][j+1]; + norm++; + } + norm = 1/norm; + smooth->L[i][j+1]=wtdsum[0]*norm; + smooth->a[i][j+1]=wtdsum[1]*norm; + smooth->b[i][j+1]=wtdsum[2]*norm; + + //now down neighbor + if (i+1==height) continue; + norm=0.0;wtdsum[0]=wtdsum[1]=wtdsum[2]=0.0; + for (int ix=i; ixL[ix][j]; + wtdsum[1] += smooth->a[ix][j]; + wtdsum[2] += smooth->b[ix][j]; + norm++; + } + for (int jx=max(0,j-1); jxL[i+1][jx]; + wtdsum[1] += smooth->a[i+1][jx]; + wtdsum[2] += smooth->b[i+1][jx]; + norm++; + } + norm=1/norm; + smooth->L[i+1][j]=wtdsum[0]*norm; + smooth->a[i+1][j]=wtdsum[1]*norm; + smooth->b[i+1][j]=wtdsum[2]*norm; + + } + +#ifdef _OPENMP +#pragma omp for +#endif + + // step (2-3-4) + for( int i = 0; i < height; i++) + for(int j = 0; j < width; j++) { + + float tonefactor = (nrwt_l[smooth->L[i][j]]); + //double wtdsum[3], norm; + float hipass[3], hpffluct[3], nrfactor; + + hipass[1] = data_fine->a[i][j]-smooth->a[i][j]; + hipass[2] = data_fine->b[i][j]-smooth->b[i][j]; + + //Wiener filter + //luma + if (level<2) { + hipass[0] = data_fine->L[i][j]-smooth->L[i][j]; + hpffluct[0]=SQR(hipass[0])+SQR(hipass[1])+SQR(hipass[2])+0.001; + nrfactorL[i][j] = (1.0+hpffluct[0])/(1.0+hpffluct[0]+noisevar_L /* * Lcurve[smooth->L[i][j]]*/); + //hipass[0] *= hpffluct[0]/(hpffluct[0]+noisevar_L); + //data_fine->L[i][j] = CLIP(hipass[0]+smooth->L[i][j]); + } + + //chroma + //hipass[1] = data_fine->a[i][j]-smooth->a[i][j]; + //hipass[2] = data_fine->b[i][j]-smooth->b[i][j]; + hpffluct[1]=SQR(hipass[1]*tonefactor)+0.001; + hpffluct[2]=SQR(hipass[2]*tonefactor)+0.001; + nrfactor = (hpffluct[1]+hpffluct[2]) /((hpffluct[1]+hpffluct[2]) + noisevar_ab * NRWT_AB /* * abcurve[smooth->L[i][j]]*/); + + hipass[1] *= nrfactor; + hipass[2] *= nrfactor; + + data_fine->a[i][j] = hipass[1]+smooth->a[i][j]; + data_fine->b[i][j] = hipass[2]+smooth->b[i][j]; + } + + + if (level<2) { +#ifdef _OPENMP +#pragma omp for +#endif + for(int i = 0; i < height; i++) + for(int j = 0; j < width; j++) { + + float dirwt_l, norm_l; + float nrfctrave=0; + norm_l = 0;//if we do want to include the input pixel in the sum + + for(int inbr=(i-pitch); inbr<=(i+pitch); inbr+=pitch) { + if (inbr<0 || inbr>height-1) continue; + for (int jnbr=(j-pitch); jnbr<=(j+pitch); jnbr+=pitch) { + if (jnbr<0 || jnbr>width-1) continue; + dirwt_l = DIRWT_L(inbr, jnbr, i, j); + nrfctrave += dirwt_l*nrfactorL[inbr][jnbr]; + norm_l += dirwt_l; + } + } + + nrfctrave /= norm_l; + //nrfctrave = nrfactorL[i][j]; + //nrfctrave=1; + + + float hipass[3]; + + //luma + + /*if (i>0 && i0 && jL[i][j]-smooth->L[i][j]); + //hipass[0] = median*(data_fine->L[i][j]-smooth->L[i][j]); + //hipass[0] = nrfactorL[i][j]*(data_fine->L[i][j]-data_coarse->L[i][j]); + data_fine->L[i][j] = CLIP(hipass[0]+smooth->L[i][j]); + + + //chroma + //hipass[1] = nrfactorab[i][j]*(data_fine->a[i][j]-data_coarse->a[i][j]); + //hipass[2] = nrfactorab[i][j]*(data_fine->b[i][j]-data_coarse->b[i][j]); + + //data_fine->a[i][j] = hipass[1]+data_coarse->a[i][j]; + //data_fine->b[i][j] = hipass[2]+data_coarse->b[i][j]; + } + }//end of luminance correction + + +} // end parallel + delete smooth; + }//end of pitch>1 + + } + + +#undef DIRWT_L +#undef DIRWT_AB + +//#undef NRWT_L +#undef NRWT_AB + +} + diff --git a/rtengine/dirpyrLab_equalizer.cc b/rtengine/dirpyrLab_equalizer.cc new file mode 100644 index 000000000..de7dd402d --- /dev/null +++ b/rtengine/dirpyrLab_equalizer.cc @@ -0,0 +1,491 @@ +/* + * This file is part of RawTherapee. + * + * 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 . + * + * © 2010 Emil Martinec + * + */ + +#include +#include +#include "curves.h" +#include "labimage.h" +#include "improcfun.h" +#include "rawimagesource.h" +#include "rt_math.h" + +#ifdef _OPENMP +#include +#endif + +#define CLIPC(a) ((a)>-32000?((a)<32000?(a):32000):-32000) + +#define DIRWT(i1,j1,i,j) (rangefn[abs((int)data_fine->L[i1][j1]-data_fine->L[i][j])+abs((int)data_fine->a[i1][j1]-data_fine->a[i][j])+abs((int)data_fine->b[i1][j1]-data_fine->b[i][j])] ) + +namespace rtengine { + + static const int maxlevel = 4; + + //sequence of scales + static const int scales[8] = {1,2,4,8,16,32,64,128}; + //sequence of pitches + static const int pitches[8] = {1,1,1,1,1,1,1,1}; + + //sequence of scales + //static const int scales[8] = {1,1,1,1,1,1,1,1}; + //sequence of pitches + //static const int pitches[8] = {2,2,2,2,2,2,2,2}; + + //sequence of scales + //static const int scales[8] = {1,3,6,10,15,21,28,36}; + //sequence of pitches + //static const int pitches[8] = {1,1,1,1,1,1,1,1}; + + //sequence of scales + //static const int scales[8] = {1,1,2,4,8,16,32,64}; + //sequence of pitches + //static const int pitches[8] = {2,1,1,1,1,1,1,1}; + + //pitch is spacing of subsampling + //scale is spacing of directional averaging weights + //example 1: no subsampling at any level -- pitch=1, scale=2^n + //example 2: subsampling by 2 every level -- pitch=2, scale=1 at each level + //example 3: no subsampling at first level, subsampling by 2 thereafter -- + // pitch =1, scale=1 at first level; pitch=2, scale=2 thereafter + + + + + void ImProcFunctions :: dirpyrLab_equalizer(LabImage * src, LabImage * dst, /*float luma, float chroma, float gamma*/ const double * mult ) + { + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + LUTf rangefn(0x20000); + + + //set up weights + float noise = 1500; + + + //set up range functions + + for (int i=0; i<0x20000; i++) + rangefn[i] = (int)((noise/((double)i + noise))); + + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + + int level; + int ** buffer[3]; + + + LabImage * dirpyrLablo[maxlevel]; + + int w = src->W; + int h = src->H; + + buffer[0] = allocArray (w+128, h+128); + buffer[1] = allocArray (w+128, h+128); + buffer[2] = allocArray (w+128, h+128); + + for (int i=0; iH; i+=totalpitch, i1++) + for(int j = 0, j1=0; j < src->W; j+=totalpitch, j1++) { + + //copy pixels + buffer[0][i][j] = dirpyrLablo[maxlevel-1]->L[i1][j1]; + buffer[1][i][j] = dirpyrLablo[maxlevel-1]->a[i1][j1]; + buffer[2][i][j] = dirpyrLablo[maxlevel-1]->b[i1][j1]; + + } + + //if we are not subsampling, this is lots faster but does the typecasting work??? + //memcpy(buffer[0],dirpyrLablo[maxlevel-1]->L,sizeof(buffer[0])); + //memcpy(buffer[1],dirpyrLablo[maxlevel-1]->a,sizeof(buffer[1])); + //memcpy(buffer[2],dirpyrLablo[maxlevel-1]->b,sizeof(buffer[2])); + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + + for(int level = maxlevel - 1; level > 0; level--) + { + + //int scale = scales[level]; + int pitch = pitches[level]; + + totalpitch /= pitch; + + idirpyr_eq(dirpyrLablo[level], dirpyrLablo[level-1], buffer, level, pitch, totalpitch, mult ); + + } + + + scale = scales[0]; + pitch = pitches[0]; + totalpitch /= pitch; + + idirpyr_eq(dirpyrLablo[0], dst, buffer, 0, pitch, totalpitch, mult ); + + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + for (int i=0; iH; i++) + for (int j=0; jW; j++) { + + // TODO: Is integer cast necessary here? + dst->L[i][j] = CLIP((int)( buffer[0][i][j] )); + dst->a[i][j] = CLIPC((int)( buffer[1][i][j] )); + dst->b[i][j] = CLIPC((int)( buffer[2][i][j] )); + + } + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + for(int i = 0; i < maxlevel; i++) + { + delete dirpyrLablo[i]; + } + + for (int c=0;c<3;c++) + freeArray(buffer[c], h+128); + + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + } + + void ImProcFunctions::dirpyr_eq(LabImage* data_fine, LabImage* data_coarse, LUTf & rangefn, int level, int pitch, int scale, const double * mult ) + { + + //pitch is spacing of subsampling + //scale is spacing of directional averaging weights + //example 1: no subsampling at any level -- pitch=1, scale=2^n + //example 2: subsampling by 2 every level -- pitch=2, scale=1 at each level + //example 3: no subsampling at first level, subsampling by 2 thereafter -- + // pitch =1, scale=1 at first level; pitch=2, scale=2 thereafter + + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // calculate weights, compute directionally weighted average + + int width = data_fine->W; + int height = data_fine->H; + + + + //generate domain kernel + int halfwin = 1;//min(ceil(2*sig),3); + int scalewin = halfwin*scale; + + +#ifdef _OPENMP +#pragma omp parallel for +#endif + for(int i = 0; i < height; i+=pitch) { int i1=i/pitch; + for(int j = 0, j1=0; j < width; j+=pitch, j1++) + { + float Lout, aout, bout; + float norm; + norm = 0;//if we do want to include the input pixel in the sum + Lout = 0; + aout = 0; + bout = 0; + + for(int inbr=max(0,i-scalewin); inbr<=min(height-1,i+scalewin); inbr+=scale) { + for (int jnbr=max(0,j-scalewin); jnbr<=min(width-1,j+scalewin); jnbr+=scale) { + float dirwt = DIRWT(inbr, jnbr, i, j); + Lout += dirwt*data_fine->L[inbr][jnbr]; + aout += dirwt*data_fine->a[inbr][jnbr]; + bout += dirwt*data_fine->b[inbr][jnbr]; + norm += dirwt; + } + } + data_coarse->L[i1][j1]=Lout/norm;//low pass filter + data_coarse->a[i1][j1]=aout/norm; + data_coarse->b[i1][j1]=bout/norm; + } + } + + + + + } + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + void ImProcFunctions::idirpyr_eq(LabImage* data_coarse, LabImage* data_fine, int *** buffer, int level, int pitch, int scale, const double * mult ) + { + + int width = data_fine->W; + int height = data_fine->H; + + float lumamult[4], chromamult[4]; + for (int i=0; i<4; i++) { + lumamult[i] = mult[i]; + chromamult[i] = mult[i+4]; + } + + float wtdsum[6], norm, dirwt; + float hipass[3]; + int i1, j1; + + + // for coarsest level, take non-subsampled lopass image and subtract from lopass_fine to generate hipass image + + // denoise hipass image, add back into lopass_fine to generate denoised image at fine scale + + // now iterate: + // (1) take denoised image at level n, expand and smooth using gradient weights from lopass image at level n-1 + // the result is the smoothed image at level n-1 + // (2) subtract smoothed image at level n-1 from lopass image at level n-1 to make hipass image at level n-1 + // (3) denoise the hipass image at level n-1 + // (4) add the denoised image at level n-1 to the smoothed image at level n-1 to make the denoised image at level n-1 + + // note that the coarsest level amounts to skipping step (1) and doing (2,3,4). + // in other words, skip step one if pitch=1 + + + + if (pitch==1) { + // step (1-2-3-4) +#ifdef _OPENMP +#pragma omp parallel for +#endif + for(int i = 0; i < height; i++) + for(int j = 0; j < width; j++) { + + //luma + float hipass0 = (float)data_fine->L[i][j]-data_coarse->L[i][j]; + buffer[0][i*scale][j*scale] += hipass0 * lumamult[level];//*luma; + + //chroma + float hipass1 = data_fine->a[i][j]-data_coarse->a[i][j]; + float hipass2 = data_fine->b[i][j]-data_coarse->b[i][j]; + buffer[1][i*scale][j*scale] += hipass1 * chromamult[level]; //*chroma; + buffer[2][i*scale][j*scale] += hipass2 * chromamult[level]; //*chroma; + } + + } else { + + // step (1) + //if (pitch>1), pitch=2; expand coarse image, fill in missing data + + LabImage* smooth; + smooth = new LabImage(width, height); +#ifdef _OPENMP +#pragma omp parallel +#endif + +{ +#ifdef _OPENMP +#pragma omp for +#endif + for(int i = 0; i < height; i+=pitch){ int i2=i/pitch; + for(int j = 0, j2=0; j < width; j+=pitch, j2++) { + + //copy common pixels + smooth->L[i][j] = data_coarse->L[i2][j2]; + smooth->a[i][j] = data_coarse->a[i2][j2]; + smooth->b[i][j] = data_coarse->b[i2][j2]; + } + } + +#ifdef _OPENMP +#pragma omp for +#endif + for(int i = 0; i < height-1; i+=2) + for(int j = 0; j < width-1; j+=2) { + //do midpoint first + norm=dirwt=0; + wtdsum[0]=wtdsum[1]=wtdsum[2]=wtdsum[3]=wtdsum[4]=wtdsum[5]=0.0; + for(i1=i; i1L[i1][j1]; + wtdsum[1] += dirwt*smooth->a[i1][j1]; + wtdsum[2] += dirwt*smooth->b[i1][j1]; + wtdsum[3] += dirwt*buffer[0][i1*scale][j1*scale];// not completely right if j1*scale or i1*scale is out of bounds of original image ??? + wtdsum[4] += dirwt*buffer[1][i1*scale][j1*scale];// also should we use directional average? + wtdsum[5] += dirwt*buffer[2][i1*scale][j1*scale]; + norm+=dirwt; + } + norm = 1/norm; + smooth->L[i+1][j+1]=wtdsum[0]*norm; + smooth->a[i+1][j+1]=wtdsum[1]*norm; + smooth->b[i+1][j+1]=wtdsum[2]*norm; + buffer[0][(i+1)*scale][(j+1)*scale]=wtdsum[3]*norm; + buffer[1][(i+1)*scale][(j+1)*scale]=wtdsum[4]*norm; + buffer[2][(i+1)*scale][(j+1)*scale]=wtdsum[5]*norm; + } +#ifdef _OPENMP +#pragma omp for +#endif + for(int i = 0; i < height-1; i+=2) + for(int j = 0; j < width-1; j+=2) { + //now right neighbor + if (j+1==width) continue; + norm=dirwt=0; + wtdsum[0]=wtdsum[1]=wtdsum[2]=wtdsum[3]=wtdsum[4]=wtdsum[5]=0.0; + for (j1=j; j1L[i][j1]; + wtdsum[1] += dirwt*smooth->a[i][j1]; + wtdsum[2] += dirwt*smooth->b[i][j1]; + wtdsum[3] += dirwt*buffer[0][i*scale][j1*scale]; + wtdsum[4] += dirwt*buffer[1][i*scale][j1*scale]; + wtdsum[5] += dirwt*buffer[2][i*scale][j1*scale]; + norm+=dirwt; + } + for (i1=max(0,i-1); i1L[i1][j+1]; + wtdsum[1] += dirwt*smooth->a[i1][j+1]; + wtdsum[2] += dirwt*smooth->b[i1][j+1]; + wtdsum[3] += dirwt*buffer[0][i1*scale][(j+1)*scale]; + wtdsum[4] += dirwt*buffer[1][i1*scale][(j+1)*scale]; + wtdsum[5] += dirwt*buffer[2][i1*scale][(j+1)*scale]; + norm+=dirwt; + } + norm = 1/norm; + smooth->L[i][j+1]=wtdsum[0]*norm; + smooth->a[i][j+1]=wtdsum[1]*norm; + smooth->b[i][j+1]=wtdsum[2]*norm; + buffer[0][i][(j+1)*scale]=wtdsum[3]*norm; + buffer[1][i][(j+1)*scale]=wtdsum[4]*norm; + buffer[2][i][(j+1)*scale]=wtdsum[5]*norm; + + //now down neighbor + if (i+1==height) continue; + norm=0; + wtdsum[0]=wtdsum[1]=wtdsum[2]=wtdsum[3]=wtdsum[4]=wtdsum[5]=0.0; + for (i1=i; i1L[i1][j]; + wtdsum[1] += dirwt*smooth->a[i1][j]; + wtdsum[2] += dirwt*smooth->b[i1][j]; + wtdsum[3] += dirwt*buffer[0][i1*scale][j*scale]; + wtdsum[4] += dirwt*buffer[1][i1*scale][j*scale]; + wtdsum[5] += dirwt*buffer[2][i1*scale][j*scale]; + norm+=dirwt; + } + for (j1=max(0,j-1); j1L[i+1][j1]; + wtdsum[1] += dirwt*smooth->a[i+1][j1]; + wtdsum[2] += dirwt*smooth->b[i+1][j1]; + wtdsum[3] += dirwt*buffer[0][(i+1)*scale][j1*scale]; + wtdsum[4] += dirwt*buffer[1][(i+1)*scale][j1*scale]; + wtdsum[5] += dirwt*buffer[2][(i+1)*scale][j1*scale]; + norm+=dirwt; + } + norm=1/norm; + smooth->L[i+1][j]=wtdsum[0]*norm; + smooth->a[i+1][j]=wtdsum[1]*norm; + smooth->b[i+1][j]=wtdsum[2]*norm; + buffer[0][(i+1)*scale][j*scale]=wtdsum[3]*norm; + buffer[1][(i+1)*scale][j*scale]=wtdsum[4]*norm; + buffer[2][(i+1)*scale][j*scale]=wtdsum[5]*norm; + + } + + + // step (2-3-4) +#ifdef _OPENMP +#pragma omp for +#endif + for(int i = 0; i < height; i++) + for(int j = 0; j < width; j++) { + + //luma + hipass[0] = (float)data_fine->L[i][j]-smooth->L[i][j]; + buffer[0][i*scale][j*scale] += hipass[0] * lumamult[level]; //*luma; + + //chroma + hipass[1] = data_fine->a[i][j]-smooth->a[i][j]; + hipass[2] = data_fine->b[i][j]-smooth->b[i][j]; + buffer[1][i*scale][j*scale] += hipass[1] * chromamult[level]; //*chroma; + buffer[2][i*scale][j*scale] += hipass[2] * chromamult[level]; //*chroma; + } +} // end parallel + delete smooth; + + } + } + + +#undef DIRWT_L +#undef DIRWT_AB + +#undef NRWT_L +#undef NRWT_AB + +} + diff --git a/rtengine/dirpyr_equalizer.cc b/rtengine/dirpyr_equalizer.cc new file mode 100644 index 000000000..ccd92b1ce --- /dev/null +++ b/rtengine/dirpyr_equalizer.cc @@ -0,0 +1,697 @@ +/* + * This file is part of RawTherapee. + * + * 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 . + * + * © 2010 Emil Martinec + * + */ + +#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; + + //sequence of scales + static const int scales[6] = {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) + { + int lastlevel=maxlevel; + if(settings->verbose) printf("Dirpyr scaleprev=%i\n",scaleprev); + float atten123=(float) settings->level123_cbdl; + if(atten123 > 50.f) atten123=50.f; + if(atten123 < 0.f) atten123=0.f; + float atten0=(float) settings->level0_cbdl; + if(atten0 > 40.f) atten123=40.f; + if(atten0 < 0.f) atten0=0.f; + + if((t_r-t_l)<0.55f) + t_l = t_r + 0.55f;//avoid too small range + + + while (lastlevel>0 && fabs(mult[lastlevel-1]-1)<0.001) { + lastlevel--; + //printf("last level to process %d \n",lastlevel); + } + if (lastlevel==0) return; + + int level; + float multi[6]={1.f,1.f,1.f,1.f,1.f,1.f}; + float scalefl[6]; + + for(int lv=0;lv<6;lv++) { + scalefl[lv]= ((float) scales[lv])/(float) scaleprev; + if(lv>=1) {if(scalefl[lv] < 1.f) multi[lv] = (atten123*((float) mult[lv] -1.f)/100.f)+1.f; else multi[lv]=(float) mult[lv];}//modulate action if zoom < 100% + else {if(scalefl[lv] < 1.f) multi[lv] = (atten0*((float) mult[lv] -1.f)/100.f)+1.f; else multi[lv]=(float) mult[lv];}//modulate action if zoom < 100% + + } + if(settings->verbose) printf("CbDL mult0=%f 1=%f 2=%f 3=%f 4=%f 5=%f\n",multi[0],multi[1],multi[2],multi[3],multi[4],multi[5]); + + multi_array2D dirpyrlo (srcwidth, srcheight); + + level = 0; + + //int thresh = 100 * mult[5]; + int scale = (int)(scales[level])/scaleprev; + if(scale < 1) scale=1; + + + dirpyr_channel(src, dirpyrlo[0], srcwidth, srcheight, 0, scale); + + level = 1; + + while(level < lastlevel) + { + + scale = (int)(scales[level])/scaleprev; + if(scale < 1) scale=1; + + dirpyr_channel(dirpyrlo[level-1], dirpyrlo[level], srcwidth, srcheight, level, scale); + + level ++; + } + + float **tmpHue,**tmpChr; + if(skinprot != 0.f) { + // precalculate hue and chroma, use SSE, if available + // by precalculating these values we can greatly reduce the number of calculations in idirpyr_eq_channel() + // but we need two additional buffers for this preprocessing + tmpHue = new float*[srcheight]; + for (int i=0; i 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 ); + } + + 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 ); + + if(skinprot != 0.f) { + for (int i=0; iverbose) printf("CAM dirpyr scaleprev=%i\n",scaleprev); + float atten123=(float) settings->level123_cbdl; + if(atten123 > 50.f) atten123=50.f; + if(atten123 < 0.f) atten123=0.f; +// printf("atten=%f\n",atten); + float atten0=(float) settings->level0_cbdl; + if(atten0 > 40.f) atten123=40.f; + if(atten0 < 0.f) atten0=0.f; + + if((t_r-t_l)<0.55f) + t_l = t_r + 0.55f;//avoid too small range + + while (fabs(mult[lastlevel-1]-1)<0.001 && lastlevel>0) { + lastlevel--; + //printf("last level to process %d \n",lastlevel); + } + if (lastlevel==0) return; + + int level; + + float multi[6]={1.f,1.f,1.f,1.f,1.f,1.f}; + float scalefl[6]; + + for(int lv=0;lv<6;lv++) { + scalefl[lv]= ((float) scales[lv])/(float) scaleprev; + // if(scalefl[lv] < 1.f) multi[lv] = 1.f; else multi[lv]=(float) mult[lv]; + if (lv>=1) {if(scalefl[lv] < 1.f) multi[lv] = (atten123*((float) mult[lv] -1.f)/100.f)+1.f; else multi[lv]=(float) mult[lv];} + else {if(scalefl[lv] < 1.f) multi[lv] = (atten0*((float) mult[lv] -1.f)/100.f)+1.f; else multi[lv]=(float) mult[lv];} + + + } + if(settings->verbose) printf("CAM CbDL mult0=%f 1=%f 2=%f 3=%f 4=%f 5=%f\n",multi[0],multi[1],multi[2],multi[3],multi[4],multi[5]); + + + + + multi_array2D dirpyrlo (srcwidth, srcheight); + + level = 0; + + int scale = (int)(scales[level])/scaleprev; + if(scale < 1) scale=1; + + dirpyr_channel(src, dirpyrlo[0], srcwidth, srcheight, 0, scale); + + level = 1; + + while(level < lastlevel) + { + scale = (int)(scales[level])/scaleprev; + if(scale < 1) scale=1; + + dirpyr_channel(dirpyrlo[level-1], dirpyrlo[level], srcwidth, srcheight, level, scale); + + level ++; + } + + + // with the current implementation of idirpyr_eq_channel we can safely use the buffer from last level as buffer, saves some memory + float ** buffer = dirpyrlo[lastlevel-1]; + + for(int level = lastlevel - 1; level > 0; level--) + { + idirpyr_eq_channelcam(dirpyrlo[level], dirpyrlo[level-1], buffer, srcwidth, srcheight, level, multi, dirpyrThreshold , h_p, C_p, skinprot, b_l,t_l,t_r); + } + + + scale = scales[0]; + + 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) +#endif + for (int i=0; iJ_p[i][j] > 8.f && ncie->J_p[i][j] < 92.f) + dst[i][j] = CLIP( buffer[i][j] ); // TODO: Really a clip necessary? + else + dst[i][j]=src[i][j]; + } + } + else + for (int i=0; i 1) { + //generate domain kernel + int domker[5][5] = {{1,1,1,1,1},{1,2,2,2,1},{1,2,2,2,1},{1,2,2,2,1},{1,1,1,1,1}}; + // int domker[5][5] = {{1,1,1,1,1},{1,1,1,1,1},{1,1,1,1,1},{1,1,1,1,1},{1,1,1,1,1}}; + static const int halfwin=2; + const int scalewin = halfwin*scale; +#ifdef _OPENMP +#pragma omp parallel +#endif +{ +#ifdef __SSE2__ + __m128 thousandv = _mm_set1_ps( 1000.0f ); + __m128 dirwtv, valv, normv, dftemp1v, dftemp2v; +// multiplied each value of domkerv by 1000 to avoid multiplication by 1000 inside the loop + float domkerv[5][5][4] __attribute__ ((aligned (16))) = {{{1000,1000,1000,1000},{1000,1000,1000,1000},{1000,1000,1000,1000},{1000,1000,1000,1000},{1000,1000,1000,1000}},{{1000,1000,1000,1000},{2000,2000,2000,2000},{2000,2000,2000,2000},{2000,2000,2000,2000},{1000,1000,1000,1000}},{{1000,1000,1000,1000},{2000,2000,2000,2000},{2000,2000,2000,2000},{2000,2000,2000,2000},{1000,1000,1000,1000}},{{1000,1000,1000,1000},{2000,2000,2000,2000},{2000,2000,2000,2000},{2000,2000,2000,2000},{1000,1000,1000,1000}},{{1000,1000,1000,1000},{1000,1000,1000,1000},{1000,1000,1000,1000},{1000,1000,1000,1000},{1000,1000,1000,1000}}}; +#endif // __SSE2__ + + int j; +#ifdef _OPENMP +#pragma omp for //schedule (dynamic,8) +#endif + for(int i = 0; i < height; i++) { + float dirwt; + for(j = 0; j < scalewin; j++) { + float val=0.f; + float norm=0.f; + + + for(int inbr=max(0,i-scalewin); inbr<=min(height-1,i+scalewin); inbr+=scale) { + for (int jnbr=max(0,j-scalewin); jnbr<=j+scalewin; jnbr+=scale) { + //printf("i=%d ",(inbr-i)/scale+halfwin); + dirwt = DIRWT(inbr, jnbr, i, j); + val += dirwt*data_fine[inbr][jnbr]; + norm += dirwt; + } + } + data_coarse[i][j]=val/norm;//low pass filter + } +#ifdef __SSE2__ + for(; j < width-scalewin-3; j+=4) + { + valv = _mm_setzero_ps(); + normv = _mm_setzero_ps(); + dftemp1v = LVFU(data_fine[i][j]); + for(int inbr=MAX(0,i-scalewin); inbr<=MIN(height-1,i+scalewin); inbr+=scale) { + int indexihlp = (inbr-i)/scale+halfwin; + for (int jnbr=j-scalewin, indexjhlp = 0; jnbr<=j+scalewin; jnbr+=scale,indexjhlp++) { + dftemp2v = LVFU(data_fine[inbr][jnbr]); + dirwtv = _mm_load_ps((float*)&domkerv[indexihlp][indexjhlp]) / (vabsf(dftemp1v-dftemp2v) + thousandv); + valv += dirwtv*dftemp2v; + normv += dirwtv; + } + } + _mm_storeu_ps( &data_coarse[i][j],valv/normv);//low pass filter + } + for(; j < width-scalewin; j++) + { + float val=0.f; + float norm=0.f; + + for(int inbr=max(0,i-scalewin); inbr<=min(height-1,i+scalewin); inbr+=scale) { + for (int jnbr=j-scalewin; jnbr<=j+scalewin; jnbr+=scale) { + dirwt = DIRWT(inbr, jnbr, i, j); + val += dirwt*data_fine[inbr][jnbr]; + norm += dirwt; + } + } + data_coarse[i][j]=val/norm;//low pass filter + } +#else + + for(; j < width-scalewin; j++) + { + float val=0.f; + float norm=0.f; + + for(int inbr=max(0,i-scalewin); inbr<=min(height-1,i+scalewin); inbr+=scale) { + for (int jnbr=j-scalewin; jnbr<=j+scalewin; jnbr+=scale) { + dirwt = DIRWT(inbr, jnbr, i, j); + val += dirwt*data_fine[inbr][jnbr]; + norm += dirwt; + } + } + data_coarse[i][j]=val/norm;//low pass filter + } +#endif + for(; j < width; j++) + { + float val=0.f; + float norm=0.f; + + for(int inbr=max(0,i-scalewin); inbr<=min(height-1,i+scalewin); inbr+=scale) { + for (int jnbr=j-scalewin; jnbr<=min(width-1,j+scalewin); jnbr+=scale) { + dirwt = DIRWT(inbr, jnbr, i, j); + val += dirwt*data_fine[inbr][jnbr]; + norm += dirwt; + } + } + data_coarse[i][j]=val/norm;//low pass filter + } + } +} + } else { // level <=1 means that all values of domker would be 1.0f, so no need for multiplication +// const int scalewin = scale; +#ifdef _OPENMP +#pragma omp parallel +#endif +{ +#ifdef __SSE2__ + __m128 thousandv = _mm_set1_ps( 1000.0f ); + __m128 dirwtv, valv, normv, dftemp1v, dftemp2v; +#endif // __SSE2__ + int j; +#ifdef _OPENMP +#pragma omp for schedule(dynamic,16) +#endif + for(int i = 0; i < height; i++) { + float dirwt; + for(j = 0; j < scale; j++) + { + float val=0.f; + float norm=0.f; + + for(int inbr=max(0,i-scale); inbr<=min(height-1,i+scale); inbr+=scale) { + for (int jnbr=max(0,j-scale); jnbr<=j+scale; jnbr+=scale) { + dirwt = RANGEFN(fabsf(data_fine[inbr][jnbr]-data_fine[i][j])); + val += dirwt*data_fine[inbr][jnbr]; + norm += dirwt; + } + } + data_coarse[i][j]=val/norm;//low pass filter + } +#ifdef __SSE2__ + for(; j < width-scale-3; j+=4) + { + valv = _mm_setzero_ps(); + normv = _mm_setzero_ps(); + dftemp1v = LVFU(data_fine[i][j]); + for(int inbr=MAX(0,i-scale); inbr<=MIN(height-1,i+scale); inbr+=scale) { + for (int jnbr=j-scale; jnbr<=j+scale; jnbr+=scale) { + dftemp2v = LVFU(data_fine[inbr][jnbr]); + dirwtv = thousandv / (vabsf(dftemp2v-dftemp1v) + thousandv); + valv += dirwtv*dftemp2v; + normv += dirwtv; + } + } + _mm_storeu_ps( &data_coarse[i][j], valv/normv);//low pass filter + } + + for(; j < width-scale; j++) + { + float val=0.f; + float norm=0.f; + + for(int inbr=max(0,i-scale); inbr<=min(height-1,i+scale); inbr+=scale) { + for (int jnbr=j-scale; jnbr<=j+scale; jnbr+=scale) { + dirwt = RANGEFN(fabsf(data_fine[inbr][jnbr]-data_fine[i][j])); + val += dirwt*data_fine[inbr][jnbr]; + norm += dirwt; + } + } + data_coarse[i][j]=val/norm;//low pass filter + } +#else + + for(; j < width-scale; j++) + { + float val=0.f; + float norm=0.f; + + for(int inbr=max(0,i-scale); inbr<=min(height-1,i+scale); inbr+=scale) { + for (int jnbr=j-scale; jnbr<=j+scale; jnbr+=scale) { + dirwt = RANGEFN(fabsf(data_fine[inbr][jnbr]-data_fine[i][j])); + val += dirwt*data_fine[inbr][jnbr]; + norm += dirwt; + } + } + data_coarse[i][j]=val/norm;//low pass filter + } +#endif + for(; j < width; j++) + { + float val=0.f; + float norm=0.f; + + for(int inbr=max(0,i-scale); inbr<=min(height-1,i+scale); inbr+=scale) { + for (int jnbr=j-scale; jnbr<=min(width-1,j+scale); jnbr+=scale) { + dirwt = RANGEFN(fabsf(data_fine[inbr][jnbr]-data_fine[i][j])); + val += dirwt*data_fine[inbr][jnbr]; + norm += dirwt; + } + } + data_coarse[i][j]=val/norm;//low pass filter + } + } +} + } +} + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + void ImProcFunctions::idirpyr_eq_channel(float ** data_coarse, float ** data_fine, float ** buffer, int width, int height, int level, float mult[5], 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) + { + const float skinprotneg = -skinprot; + const float factorHard = (1.f - skinprotneg/100.f); + + float offs; + if(skinprot==0.f) + offs = 0.f; + else + offs = -1.f; + float multbis[6]; + + multbis[level]=mult[level];//multbis to reduce artifacts for high values mult + if(level==4 && mult[level]> 1.f) multbis[level]=1.f+0.65f*(mult[level]-1.f); + if(level==5 && mult[level]> 1.f) multbis[level]=1.f+0.45f*(mult[level]-1.f); + + LUTf irangefn (0x20000); + { + const float noisehi = 1.33f*noise*dirpyrThreshold/expf(level*log(3.0)), noiselo = 0.66f*noise*dirpyrThreshold/expf(level*log(3.0)); + //printf("level=%i multlev=%f noisehi=%f noiselo=%f skinprot=%f\n",level,mult[level], noisehi, noiselo, skinprot); + + for (int i=0; i<0x20000; i++) { + if (abs(i-0x10000)>noisehi || multbis[level]<1.0) { + irangefn[i] = multbis[level] + offs; + } else { + if (abs(i-0x10000) 0.f) +#ifdef _OPENMP +#pragma omp parallel for schedule(dynamic,16) +#endif + for(int i = 0; i < height; i++) { + for(int j = 0; j < width; j++) { + float scale=1.f; + float hipass = (data_fine[i][j]-data_coarse[i][j]); + // These values are precalculated now + float modhue = hue[i][j]; + float modchro = chrom[i][j]; + Color::SkinSatCbdl ((data_fine[i][j])/327.68f, modhue, modchro, skinprot, scale, true, b_l, t_l, t_r); + buffer[i][j] += (1.f +(irangefn[hipass+0x10000])*scale) * hipass ; + } + } + else +#ifdef _OPENMP +#pragma omp parallel for schedule(dynamic,16) +#endif + for(int i = 0; i < height; i++) { + for(int j = 0; j < width; j++) { + float scale=1.f; + float hipass = (data_fine[i][j]-data_coarse[i][j]); + // These values are precalculated now + float modhue = hue[i][j]; + float modchro = chrom[i][j]; + Color::SkinSatCbdl ((data_fine[i][j])/327.68f, modhue, modchro, skinprotneg, scale, false, b_l, t_l, t_r); + float correct = irangefn[hipass+0x10000]; + if (scale == 1.f) {//image hard + buffer[i][j] += (1.f +(correct)* (factorHard)) * hipass ; + } + else {//image soft with scale < 1 ==> skin + buffer[i][j] += (1.f +(correct)) * hipass ; + } + } + } + } + + + void ImProcFunctions::idirpyr_eq_channelcam(float ** data_coarse, float ** data_fine, float ** buffer, int width, int height, int level, float mult[5], 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; + const float factorHard = (1.f - skinprotneg/100.f); + + float offs; + if(skinprot==0.f) + offs = 0.f; + else + offs = -1.f; + float multbis[6]; + + multbis[level]=mult[level];//multbis to reduce artifacts for high values mult + if(level==4 && mult[level]> 1.f) multbis[level]=1.f+0.65f*(mult[level]-1.f); + if(level==5 && mult[level]> 1.f) multbis[level]=1.f+0.45f*(mult[level]-1.f); + + LUTf irangefn (0x20000); + { + const float noisehi = 1.33f*noise*dirpyrThreshold/expf(level*log(3.0)), noiselo = 0.66f*noise*dirpyrThreshold/expf(level*log(3.0)); + //printf("level=%i multlev=%f noisehi=%f noiselo=%f skinprot=%f\n",level,mult[level], noisehi, noiselo, skinprot); + for (int i=0; i<0x20000; i++) { + if (abs(i-0x10000)>noisehi || multbis[level]<1.0) { + irangefn[i] = multbis[level] + offs; + } else { + if (abs(i-0x10000) 0.f) +#ifdef _OPENMP +#pragma omp parallel for schedule(dynamic,16) +#endif + for(int i = 0; i < height; i++) { + for(int j = 0; j < width; j++) { + float hipass = (data_fine[i][j]-data_coarse[i][j]); + float scale=1.f; + Color::SkinSatCbdlCam ((data_fine[i][j])/327.68f, l_a_h[i][j] ,l_b_c[i][j], skinprot, scale, true, b_l, t_l, t_r); + buffer[i][j] += (1.f +(irangefn[hipass+0x10000])*scale) * hipass ; + } + } + else +#ifdef _OPENMP +#pragma omp parallel for schedule(dynamic,16) +#endif + for(int i = 0; i < height; i++) { + for(int j = 0; j < width; j++) { + float hipass = (data_fine[i][j]-data_coarse[i][j]); + float scale=1.f; + float correct; + correct=irangefn[hipass+0x10000]; + Color::SkinSatCbdlCam ((data_fine[i][j])/327.68f, l_a_h[i][j],l_b_c[i][j] , skinprotneg, scale, false, b_l, t_l, t_r); + if (scale == 1.f) {//image hard + buffer[i][j] += (1.f +(correct)* factorHard) * hipass ; + + } + else {//image soft + buffer[i][j] += (1.f +(correct)) * hipass ; + } + } + } + // if(gamutlab) { + // ImProcFunctions::badpixcam (buffer[i][j], 6.0, 10, 2);//for bad pixels + // } + + /* if(gamutlab) {//disabled + float Lprov1=(buffer[i][j])/327.68f; + float R,G,B; +#ifdef _DEBUG + bool neg=false; + bool more_rgb=false; + //gamut control : Lab values are in gamut + Color::gamutLchonly(modhue,Lprov1,modchro, R, G, B, wip, highlight, 0.15f, 0.96f, neg, more_rgb); +#else + //gamut control : Lab values are in gamut + Color::gamutLchonly(modhue,Lprov1,modchro, R, G, B, wip, highlight, 0.15f, 0.96f); +#endif + // Color::gamutLchonly(modhue,Lprov1,modchro, R, G, B, wip, highlight, 0.15f, 0.96f);//gamut control in Lab mode ..not in CIECAM + buffer[i][j]=Lprov1*327.68f; + float2 sincosval = xsincosf(modhue); + l_a_h[i][j]=327.68f*modchro*sincosval.y; + l_b_c[i][j]=327.68f*modchro*sincosval.x; + } + */ + } + + // float hipass = (data_fine[i][j]-data_coarse[i][j]); + // buffer[i][j] += irangefn[hipass+0x10000] * hipass ; + +#undef DIRWT_L +#undef DIRWT_AB + +#undef NRWT_L +#undef NRWT_AB + +} + diff --git a/rtengine/editbuffer.cc b/rtengine/editbuffer.cc new file mode 100644 index 000000000..a72d05651 --- /dev/null +++ b/rtengine/editbuffer.cc @@ -0,0 +1,220 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "editbuffer.h" + +namespace rtengine { + +EditBuffer::EditBuffer(::EditDataProvider *dataProvider) : + objectMap(NULL), objectMap2(NULL), objectMode(OM_255), dataProvider(dataProvider), + imgFloatBuffer(NULL), LabBuffer(NULL), singlePlaneBuffer(), ready(false) {} + +EditBuffer::~EditBuffer() { + flush(); + #ifndef NDEBUG + imgFloatBuffer = (Imagefloat*)(0xbaadf00d); + #endif + #ifndef NDEBUG + LabBuffer = (LabImage*)(0xbaadf00d); + #endif +} + +void EditBuffer::createBuffer(int width, int height) { + //printf("Appel de createBuffer %d x %d\n", width, height); + resize (width, height); +} + +void EditBuffer::flush() { + if (imgFloatBuffer) { + delete imgFloatBuffer; + imgFloatBuffer = NULL; + } + if (LabBuffer) { + delete LabBuffer; + LabBuffer = NULL; + } + singlePlaneBuffer.flushData(); + ready = false; +} + +/* Upgrade or downgrade the objectModeType; we're assuming that objectMap has been allocated */ +void EditBuffer::setObjectMode(ObjectMode newType) { + switch (newType) { + case (OM_255): + if (objectMap2) { + objectMap2->unreference(); + } + objectMode = OM_255; + break; + case (OM_65535): + if (!objectMap2) { + objectMap2 = Cairo::ImageSurface::create(Cairo::FORMAT_A8, objectMap->get_width(), objectMap->get_height()); + } + objectMode = OM_65535; + break; + } +} + +EditUniqueID EditBuffer::getEditID() { + if (dataProvider && dataProvider->getCurrSubscriber()) { + return dataProvider->getCurrSubscriber()->getEditID(); + } + else return EUID_None; +} + +void EditBuffer::resize(int newWidth, int newHeight) { + resize(newWidth, newHeight, dataProvider ? dataProvider->getCurrSubscriber() : NULL); +} + +// Resize buffers if they already exist +void EditBuffer::resize(int newWidth, int newHeight, EditSubscriber* newSubscriber) { + if (newSubscriber) { + if (newSubscriber->getEditingType() == ET_OBJECTS) { + if (objectMap && (objectMap->get_width() != newWidth || objectMap->get_height() != newHeight)) + objectMap.clear(); + + if (!objectMap && newWidth && newHeight) { + objectMap = Cairo::ImageSurface::create(Cairo::FORMAT_A8, newWidth, newHeight); + } + if (objectMode==OM_65535) { + if (objectMap2) { + if (objectMap2->get_width() != newWidth || objectMap2->get_height() != newHeight) { + objectMap2.clear(); + } + } + if (!objectMap2 && newWidth && newHeight) { + objectMap2 = Cairo::ImageSurface::create(Cairo::FORMAT_A8, newWidth, newHeight); + } + } + // OM_255 -> deleting objectMap2, if any + else if (objectMap2) + objectMap2.clear(); + + // Should never happen! + if (imgFloatBuffer) { + delete imgFloatBuffer; + imgFloatBuffer = NULL; + } + if (LabBuffer) { + delete LabBuffer; + LabBuffer = NULL; + } + if (singlePlaneBuffer.data) { + singlePlaneBuffer.allocate(0,0); + } + } + + if (newSubscriber->getEditingType() == ET_PIPETTE) { + if (newSubscriber->getEditBufferType() == BT_IMAGEFLOAT) { + if (!imgFloatBuffer) + imgFloatBuffer = new Imagefloat(newWidth, newHeight); + else + imgFloatBuffer->allocate(newWidth, newHeight); + } + else if (imgFloatBuffer) { + delete imgFloatBuffer; + imgFloatBuffer = NULL; + } + + if (newSubscriber->getEditBufferType() == BT_LABIMAGE) { + if (LabBuffer && (LabBuffer->W != newWidth && LabBuffer->H != newHeight)) { + delete LabBuffer; + LabBuffer = NULL; + } + if (!LabBuffer) + LabBuffer = new LabImage(newWidth, newHeight); + } + else if (LabBuffer) { + delete LabBuffer; + LabBuffer = NULL; + } + + if (newSubscriber->getEditBufferType() == BT_SINGLEPLANE_FLOAT) { + singlePlaneBuffer.allocate(newWidth, newHeight); + } + else if (singlePlaneBuffer.data) + singlePlaneBuffer.allocate(0,0); + + // Should never happen! + if (objectMap ) objectMap.clear(); + if (objectMap2) objectMap2.clear(); + } + } + ready = false; +} + +bool EditBuffer::bufferCreated() { + EditSubscriber* subscriber; + if (dataProvider && (subscriber = dataProvider->getCurrSubscriber())) { + switch (subscriber->getEditingType()) { + case ET_PIPETTE: + switch (dataProvider->getCurrSubscriber()->getEditBufferType()) { + case (BT_IMAGEFLOAT): + return imgFloatBuffer != NULL; + case (BT_LABIMAGE): + return LabBuffer != NULL; + case (BT_SINGLEPLANE_FLOAT): + return singlePlaneBuffer.data != NULL; + } + break; + case (ET_OBJECTS): + return bool(objectMap); + } + } + return false; +} + +int EditBuffer::getObjectID(const Coord& location) { + int id = 0; + + if (objectMap && location.x>0 && location.y>0 && location.xget_width() && location.yget_height()) { + id = (unsigned short)(*( objectMap->get_data() + location.y * objectMap->get_stride() + location.x )); + if (objectMap2) + id |= (unsigned short)(*( objectMap->get_data() + location.y * objectMap->get_stride() + location.x )) << 8; + } + return id-1; +} + +void EditBuffer::getPipetteData(float* v, int x, int y, int squareSize) { + if (ready && dataProvider && dataProvider->getCurrSubscriber()) { + switch (dataProvider->getCurrSubscriber()->getEditBufferType()) { + case (BT_IMAGEFLOAT): + if (imgFloatBuffer) { + imgFloatBuffer->getPipetteData(v[0], v[1], v[2], x, y, squareSize, 0); + return; + } + break; + case (BT_LABIMAGE): + if (LabBuffer) { + LabBuffer->getPipetteData(v[0], v[1], v[2], x, y, squareSize); + return; + } + break; + case (BT_SINGLEPLANE_FLOAT): + if (singlePlaneBuffer.data != NULL) { + singlePlaneBuffer.getPipetteData(v[0], x, y, squareSize, 0); + v[1] = v[2] = -1.f; + return; + } + } + } + v[0] = v[1] = v[2] = -1.f; +} + +} diff --git a/rtengine/editbuffer.h b/rtengine/editbuffer.h new file mode 100644 index 000000000..f52373349 --- /dev/null +++ b/rtengine/editbuffer.h @@ -0,0 +1,89 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _EDITBUFFER_H_ +#define _EDITBUFFER_H_ + +#include "../rtgui/edit.h" +#include "array2D.h" +#include "iimage.h" + +namespace rtengine { + +/// @brief Structure that contains information about and pointers to the Edit buffer +class EditBuffer { +private: + + // Used to draw the objects where the color correspond to the object's ID, in order to find the correct object when hovering + Cairo::RefPtr objectMap; + // If more than 254 objects has to be handled, objectMap2 contains the "upper part" of the 16 bit int value. objectMap2 will be NULL otherwise. + Cairo::RefPtr objectMap2; + ObjectMode objectMode; + +protected: + + // To avoid duplicated information, we points to a EditDataProvider that contains the current EditSubscriber + // instead of pointing to the EditSubscriber directly + ::EditDataProvider* dataProvider; + + // TODO: Unfortunately, buffer can be of several type, each one representing a floating point image. Maybe we could unify everything one day!? + // Only one of the following pointers will be allocated at a time, if any; "one chunk" allocation + Imagefloat* imgFloatBuffer; + LabImage* LabBuffer; + PlanarWhateverData singlePlaneBuffer; + + bool ready; // flag that indicates if the _pipette_ buffer is ready + + void createBuffer(int width, int height); + void resize(int newWidth, int newHeight, EditSubscriber* newSubscriber); + void resize(int newWidth, int newHeight); + void flush(); + +public: + EditBuffer(::EditDataProvider *dataProvider); + ~EditBuffer(); + + /** @brief Getter to know if the pipette buffer is correctly filled */ + bool isReady() { return ready; } + + /** @brief Setter to tell that the pipette buffer is correctly filled + * You have to use this method once the pipette is filled, so it can be read. */ + void setReady() { ready = true; } + + void setObjectMode(ObjectMode newType); + ::EditDataProvider* getDataProvider() { return dataProvider; } + EditUniqueID getEditID(); + Imagefloat* getImgFloatBuffer() { return imgFloatBuffer; } + LabImage* getLabBuffer() { return LabBuffer; } + PlanarWhateverData* getSinglePlaneBuffer() { return &singlePlaneBuffer; } + ObjectMode getObjectMode() { return objectMode; } + + Cairo::RefPtr &getObjectMap () { return objectMap; } + Cairo::RefPtr &getObjectMap2() { return objectMap2; } + + // return true if the buffer has been allocated + bool bufferCreated(); + + int getObjectID(const Coord& location); + // get the pipette values + void getPipetteData(float* v, int x, int y, int squareSize); +}; + +} + +#endif diff --git a/rtengine/ex1simple.cc b/rtengine/ex1simple.cc new file mode 100644 index 000000000..97aecb2cd --- /dev/null +++ b/rtengine/ex1simple.cc @@ -0,0 +1,82 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "rtengine.h" +#include +//#include +#include + +class PListener : public rtengine::ProgressListener { + + public: + void setProgressStr (Glib::ustring str) { + std::cout << str << std::endl; + } + void setProgress (double p) { + std::cout << p << std::endl; + } +}; + +int main (int argc, char* argv[]) { + + if (argc<4) { + std::cout << "Usage: rtcmd " << std::endl; + exit(1); + } + + Glib::thread_init (); + + // create and fill settings + rtengine::Settings* s = rtengine::Settings::create (); + s->demosaicMethod = "hphd"; + s->colorCorrectionSteps = 2; + s->iccDirectory = ""; + s->colorimetricIntent = 1; + s->monitorProfile = ""; + // init rtengine + rtengine::init (s); + // the settings can be modified later through the "s" pointer without calling any api function + + // Create a listener object. Any class is appropriate that inherits from rtengine::ProgressListener + PListener pl; + + // Load the image given in the first command line parameter + rtengine::InitialImage* ii; + int errorCode; + ii = rtengine::InitialImage::load (argv[1], true, errorCode, &pl); + if (!ii) + ii = rtengine::InitialImage::load (argv[1], false, errorCode, &pl); + if (!ii) { + std::cout << "Input file not supported." << std::endl; + exit(2); + } + + // create an instance of ProcParams structure that holds the image processing settings. You find the memory map in a separate file and the non-basic types like strings and vectors can be manipulated through helper functions + rtengine::procparams::ProcParams params; + params.load (argv[2]); + +/* First, simplest scenario. Develope image and save it in a file */ + // create a processing job with the loaded image and the current processing parameters + rtengine::ProcessingJob* job = ProcessingJob::create (i, params); + // process image. The error is given back in errorcode. + rtengine::IImage16* res = rtengine::processImage (job, errorCode, &pl); + // save image to disk + res->saveToFile (argv[3]); + // through "res" you can access width/height and pixel data, too +} + diff --git a/rtengine/ex2simple.cc b/rtengine/ex2simple.cc new file mode 100644 index 000000000..f78c4a967 --- /dev/null +++ b/rtengine/ex2simple.cc @@ -0,0 +1,139 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "rtengine.h" +#include +//#include +#include + +class PListener : public rtengine::ProgressListener { + + public: + void setProgressStr (Glib::ustring str) { + std::cout << str << std::endl; + } + void setProgress (double p) { + std::cout << p << std::endl; + } +}; + +class MyPrevImgListener : public rtengine::PreviewImageListener { + + IImage8* i; + + public: + // this method is called when the staged image processor creates a new image to store the resulting preview image (this does not happen too often) + // usually you just have to store it + void setImage (IImage8* img, double scale, procparams::CropParams cp) { + i = img; + } + // if the staged image processor wants to delete the image that stores the preview image, it calls this method. You have to destroy the image. + void delImage (IImage8* img) { + if (img) { + // make sure we dont use this image in an other thread + IImage8* temp = i; + i->getMutex().lock (); + i = NULL; + temp->getMutex().unlock (); + // free it + img->free (); + } + } + // if the preview image changes, this method is called + void imageReady (procparams::CropParams cp) { + // initiate a redraw in the background and return as fast as possible + } + // a possible redraw function: + //void redraw () { + // if (i) { + // i->lock (); + // int w = i->getWidth (); + // int h = i->getHeigt (); + // const char* data = i->getData (); + // ... draw it ... + // i->unlock (); + // } + // } +}; + +int main (int argc, char* argv[]) { + + if (argc<4) { + std::cout << "Usage: rtcmd " << std::endl; + exit(1); + } + + Glib::thread_init (); + + // create and fill settings + rtengine::Settings* s = rtengine::Settings::create (); + s->demosaicMethod = "hphd"; + s->colorCorrectionSteps = 2; + s->iccDirectory = ""; + s->colorimetricIntent = 1; + s->monitorProfile = ""; + // init rtengine + rtengine::init (s); + // the settings can be modified later through the "s" pointer without calling any api function + + // Create a listener object. Any class is appropriate that inherits from rtengine::ProgressListener + PListener pl; + + // Load the image given in the first command line parameter + rtengine::InitialImage* ii; + int errorCode; + ii = rtengine::InitialImage::load (argv[1], true, errorCode, &pl); + if (!ii) + ii = rtengine::InitialImage::load (argv[1], false, errorCode, &pl); + if (!ii) { + std::cout << "Input file not supported." << std::endl; + exit(2); + } + +/* Second scenario. Create a stagedimageprocessor with a preview scale of 1:5 and change few things */ + MyPrevImgListener myPrevImgListener; + + StagedImageProcessor* ipc = StagedImageProcessor::create (ii); + ipc->setProgressListener (&pl); + ipc->setPreviewImageListener (&myPrevImgListener); + ipc->setPreviewScale (5); // preview scale = 1:5 + // you can add a histogram listener, too, that is notified when the histogram changes + // ipc->setHistogramListener (...); + // you can add autoexplistener that is notified about the exposure settings when the auto exp algorithm finishes + // ipc->setAutoExpListener (curve); + // you can add sizelistener if you want to be notified when the size of the final image changes (due to rotation/resize/etc) + // ipc->setSizeListener (crop); + + // if you want to change the settings you have to ask for the procparams structure of the staged image processor + // you have to tell it what has changed. At the first time tell it EvPhotoLoaded so a full processing will be performed + rtengine::procparams::ProcParams* params = ipc->beginUpdateParams (); + // change this and that... + params->toneCurve.brightness = 1.0; + // you can load it, too, from a file: params->load (argv[2]); + // finally you have to call this non-blocking method, and the image processing starts in the background. When finished, the preview image listener will be notified + ipc->endUpdateParams (rtengine::EvPhotoLoaded); + // you can go on with changing of the settings, following the gui actions + // now we know that only the brightness has changed compared to the previous settings, to only a part of the processing has to be repeated + params = ipc->beginUpdateParams (); + params->toneCurve.brightness = 1.2; + ipc->endUpdateParams (rtengine::EvBrightness); + + // ... and so on. If you dont need it any more, you can destroy it (make sure that no processing is happening when you destroy it!) + StagedImageProcessor::destroy (ipc); +} + diff --git a/rtengine/expo_before_b.cc b/rtengine/expo_before_b.cc new file mode 100644 index 000000000..07dfc2e93 --- /dev/null +++ b/rtengine/expo_before_b.cc @@ -0,0 +1,153 @@ + +//////////////////////////////////////////////////////////////// +// +// //exposure correction before interpolation +// +// code dated: December 27, 2010 +// +// Expo_before.cc is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +//////////////////////////////////////////////////////////////// + + + +// Jacques Desmis +// use fast-demo(provisional) from Emil Martinec +// inspired from work Guillermo Luijk and Manuel LLorens(Perfectraw) +// Ingo Weyrich (2014-07-07) +// optimized the highlight protection case +// needs 2*width*height*sizeof(float) byte less memory than before +// needs about 60% less processing time than before +// +// This function uses parameters: +// exposure (linear): 2^(-8..0..8): currently 0.5 +3 +// preserve (log) : 0..8 : currently 0.1 1 + +#include "rtengine.h" +#include "rawimagesource.h" +#include "mytime.h" +#include "rt_math.h" + +namespace rtengine { + +extern const Settings* settings; + +void RawImageSource::processRawWhitepoint(float expos, float preser) { + MyTime t1e,t2e; + if (settings->verbose) + t1e.set(); + + int width=W, height=H; + // exposure correction inspired from G.Luijk + + for (int c=0; c<4; c++) + chmax[c] *= expos; + + if (fabs(preser)<0.001f) { + // No highlight protection - simple mutiplication + + if (ri->getSensorType()==ST_BAYER || ri->getSensorType()==ST_FUJI_XTRANS) + #pragma omp parallel for + for (int row=0;rowgetSensorType()==ST_BAYER || ri->getSensorType()==ST_FUJI_XTRANS) { + // Demosaic to allow calculation of luminosity. + if(ri->getSensorType()==ST_BAYER) + fast_demosaic (0,0,W,H); + else + fast_xtrans_interpolate(); + } + + // Find maximum to adjust LUTs. New float engines clips only at the very end + float maxValFloat = 0.f; +#pragma omp parallel +{ + float maxValFloatThr = 0.f; + if (ri->getSensorType()==ST_BAYER || ri->getSensorType()==ST_FUJI_XTRANS) +#pragma omp for schedule(dynamic,16) nowait + for(int row=0;rowmaxValFloatThr) + maxValFloatThr = rawData[row][col]; + } + else +#pragma omp for schedule(dynamic,16) nowait + for(int row=0;rowmaxValFloatThr) + maxValFloatThr = rawData[row][col*3+c]; + } + +#pragma omp critical +{ + if(maxValFloatThr > maxValFloat) + maxValFloat = maxValFloatThr; +} +} + + // Exposure correction with highlight preservation + int maxVal = maxValFloat; + LUTf lut(maxVal+1); + float K; + if(expos>1){ + // Positive exposure + K = (float) maxVal / expos*exp(-preser*log(2.0)); + for (int j=max(1,(int)K);j<=maxVal;j++) + lut[(int)j]=(((float)maxVal-K*expos)/((float)maxVal-K)*(j-maxVal)+(float) maxVal) / j; + } else { + // Negative exposure + float EV=log(expos)/log(2.0); // Convert exp. linear to EV + K = (float)maxVal * exp(-preser * log(2.0)); + + for (int j=0;j<=maxVal;j++) + lut[(int)j] = exp(EV*((float)maxVal-j) / ((float)maxVal-K) * log(2.0)); + } + + if (ri->getSensorType()==ST_BAYER || ri->getSensorType()==ST_FUJI_XTRANS) + #pragma omp parallel for schedule(dynamic,16) + for(int row=0;rowverbose) { + t2e.set(); + printf("Exposure before %d usec\n", t2e.etime(t1e)); + } + +} + +} //namespace diff --git a/rtengine/fast_demo.cc b/rtengine/fast_demo.cc new file mode 100644 index 000000000..7654d3586 --- /dev/null +++ b/rtengine/fast_demo.cc @@ -0,0 +1,436 @@ +//////////////////////////////////////////////////////////////// +// +// Fast demosaicing algorythm +// +// copyright (c) 2008-2010 Emil Martinec +// +// +// code dated: August 26, 2010 +// +// fast_demo.cc is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +//////////////////////////////////////////////////////////////// + +#include +#include "rawimagesource.h" +#include "../rtgui/multilangmgr.h" +#include "procparams.h" +#include "opthelper.h" + +using namespace std; +using namespace rtengine; + +#define TS 224 +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +/* +LUTf RawImageSource::initInvGrad() +{ + LUTf invGrad (0x10000); + + //set up directional weight function + for (int i=0; i<0x10000; i++) + invGrad[i] = 1.0/SQR(1.0+i); + + return invGrad; +} +*/ +#define INVGRAD(i) (16.0f/SQR(4.0f+i)) +#ifdef __SSE2__ +#define INVGRADV(i) (c16v*_mm_rcp_ps(SQRV(fourv+i))) +#endif +//LUTf RawImageSource::invGrad = RawImageSource::initInvGrad(); + +SSEFUNCTION void RawImageSource::fast_demosaic(int winx, int winy, int winw, int winh) { + + double progress = 0.0; + const bool plistenerActive = plistener; + + //int winx=0, winy=0; + //int winw=W, winh=H; + + if (plistener) { + plistener->setProgressStr (Glib::ustring::compose(M("TP_RAW_DMETHOD_PROGRESSBAR"), RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::fast])); + plistener->setProgress (progress); + } + + + const int bord=5; + + float clip_pt = 4*65535*initialGain; + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +#ifdef _OPENMP +#pragma omp parallel +#endif + { + + char (*buffer); + float (*greentile); + float (*redtile); + float (*bluetile); +#define CLF 1 + // assign working space + buffer = (char *) calloc(3*sizeof(float)*TS*TS + 3*CLF*64 + 63,1); + char *data; + data = (char*)( ( uintptr_t(buffer) + uintptr_t(63)) / 64 * 64); + + greentile = (float (*)) data; //pointers to array + redtile = (float (*)) ((char*)greentile + sizeof(float)*TS*TS + CLF*64); + bluetile = (float (*)) ((char*)redtile + sizeof(float)*TS*TS + CLF*64); + +#ifdef _OPENMP +#pragma omp sections +#endif +{ +#ifdef _OPENMP +#pragma omp section +#endif +{ + + //first, interpolate borders using bilinear + for (int i=0; isetProgress(progress); + } +} + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + int progressCounter = 0; + const double progressInc = 16.0*(1.0-progress)/((H*W)/((TS-4)*(TS-4))); + +#ifdef _OPENMP +#pragma omp for nowait +#endif + for (int top=bord-2; top < H-bord+2; top += TS-(4)) + for (int left=bord-2; left < W-bord+2; left += TS-(4)) { + int bottom = min(top+TS, H-bord+2); + int right = min(left+TS, W-bord+2); + +#ifdef __SSE2__ + int j,cc; + __m128 wtuv, wtdv, wtlv, wtrv; + __m128 greenv,tempv,absv,abs2v; + __m128 onev = _mm_set1_ps( 1.0f ); + __m128 c16v = _mm_set1_ps( 16.0f ); + __m128 fourv = _mm_set1_ps( 4.0f ); + vmask selmask; + vmask andmask = _mm_set_epi32( 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff ); + if(FC(top,left) == 1) + selmask = _mm_set_epi32( 0, 0xffffffff, 0, 0xffffffff ); + else + selmask = _mm_set_epi32( 0xffffffff, 0, 0xffffffff, 0 ); +#endif + // interpolate G using gradient weights + for (int i=top,rr=0; i< bottom; i++,rr++) { + float wtu, wtd, wtl, wtr; +#ifdef __SSE2__ + selmask = (vmask)_mm_andnot_ps( (__m128)selmask, (__m128)andmask); + + for (j=left,cc=0; j < right-3; j+=4,cc+=4) { + tempv = LVFU(rawData[i][j]); + absv = vabsf(LVFU(rawData[i-1][j])-LVFU(rawData[i+1][j])); + wtuv = INVGRADV(absv+vabsf(tempv-LVFU(rawData[i-2][j]))+vabsf(LVFU(rawData[i-1][j])-LVFU(rawData[i-3][j]))); + wtdv = INVGRADV(absv+vabsf(tempv-LVFU(rawData[i+2][j]))+vabsf(LVFU(rawData[i+1][j])-LVFU(rawData[i+3][j]))); + abs2v = vabsf(LVFU(rawData[i][j-1])-LVFU(rawData[i][j+1])); + wtlv = INVGRADV(abs2v+vabsf(tempv-LVFU(rawData[i][j-2]))+vabsf(LVFU(rawData[i][j-1])-LVFU(rawData[i][j-3]))); + wtrv = INVGRADV(abs2v+vabsf(tempv-LVFU(rawData[i][j+2]))+vabsf(LVFU(rawData[i][j+1])-LVFU(rawData[i][j+3]))); + greenv = (wtuv*LVFU(rawData[i-1][j])+wtdv*LVFU(rawData[i+1][j])+wtlv*LVFU(rawData[i][j-1])+wtrv*LVFU(rawData[i][j+1])) / (wtuv+wtdv+wtlv+wtrv); + _mm_store_ps(&greentile[rr*TS+cc],vself(selmask, greenv, tempv)); + _mm_store_ps(&redtile[rr*TS+cc],tempv); + _mm_store_ps(&bluetile[rr*TS+cc],tempv); + } + for (; j < right; j++,cc++) { + + if (FC(i,j)==1) { + greentile[rr*TS+cc] = rawData[i][j]; + + } else { + //compute directional weights using image gradients + wtu=INVGRAD((abs(rawData[i+1][j]-rawData[i-1][j])+abs(rawData[i][j]-rawData[i-2][j])+abs(rawData[i-1][j]-rawData[i-3][j]))); + wtd=INVGRAD((abs(rawData[i-1][j]-rawData[i+1][j])+abs(rawData[i][j]-rawData[i+2][j])+abs(rawData[i+1][j]-rawData[i+3][j]))); + wtl=INVGRAD((abs(rawData[i][j+1]-rawData[i][j-1])+abs(rawData[i][j]-rawData[i][j-2])+abs(rawData[i][j-1]-rawData[i][j-3]))); + wtr=INVGRAD((abs(rawData[i][j-1]-rawData[i][j+1])+abs(rawData[i][j]-rawData[i][j+2])+abs(rawData[i][j+1]-rawData[i][j+3]))); + + //store in rgb array the interpolated G value at R/B grid points using directional weighted average + greentile[rr*TS+cc]=(wtu*rawData[i-1][j]+wtd*rawData[i+1][j]+wtl*rawData[i][j-1]+wtr*rawData[i][j+1]) / (wtu+wtd+wtl+wtr); + } + redtile[rr*TS+cc] = rawData[i][j]; + bluetile[rr*TS+cc] = rawData[i][j]; + } + +#else + for (int j=left,cc=0; j < right; j++,cc++) { + if (FC(i,j)==1) { + greentile[rr*TS+cc] = rawData[i][j]; + } else { + //compute directional weights using image gradients + wtu=INVGRAD((abs(rawData[i+1][j]-rawData[i-1][j])+abs(rawData[i][j]-rawData[i-2][j])+abs(rawData[i-1][j]-rawData[i-3][j]))); + wtd=INVGRAD((abs(rawData[i-1][j]-rawData[i+1][j])+abs(rawData[i][j]-rawData[i+2][j])+abs(rawData[i+1][j]-rawData[i+3][j]))); + wtl=INVGRAD((abs(rawData[i][j+1]-rawData[i][j-1])+abs(rawData[i][j]-rawData[i][j-2])+abs(rawData[i][j-1]-rawData[i][j-3]))); + wtr=INVGRAD((abs(rawData[i][j-1]-rawData[i][j+1])+abs(rawData[i][j]-rawData[i][j+2])+abs(rawData[i][j+1]-rawData[i][j+3]))); + + //store in rgb array the interpolated G value at R/B grid points using directional weighted average + greentile[rr*TS+cc]=(wtu*rawData[i-1][j]+wtd*rawData[i+1][j]+wtl*rawData[i][j-1]+wtr*rawData[i][j+1]) / (wtu+wtd+wtl+wtr); + } + redtile[rr*TS+cc] = rawData[i][j]; + bluetile[rr*TS+cc] = rawData[i][j]; + } +#endif + } + +#ifdef __SSE2__ + __m128 zd25v = _mm_set1_ps(0.25f); + __m128 clip_ptv = _mm_set1_ps( clip_pt ); +#endif + for (int i=top+1,rr=1; i< bottom-1; i++,rr++) { + if (FC(i,left+(FC(i,2)&1)+1)==0) +#ifdef __SSE2__ + for (int j=left+1,cc=1; j < right-1; j+=4,cc+=4) { + //interpolate B/R colors at R/B sites + _mm_storeu_ps(&bluetile[rr*TS+cc], LVFU(greentile[rr*TS+cc]) - zd25v*((LVFU(greentile[(rr-1)*TS+(cc-1)])+LVFU(greentile[(rr-1)*TS+(cc+1)])+LVFU(greentile[(rr+1)*TS+cc+1])+LVFU(greentile[(rr+1)*TS+cc-1])) - + _mm_min_ps(clip_ptv,LVFU(rawData[i-1][j-1])+LVFU(rawData[i-1][j+1])+LVFU(rawData[i+1][j+1])+LVFU(rawData[i+1][j-1])))); + } +#else + for (int cc=(FC(i,2)&1)+1, j=left+cc; j < right-1; j+=2, cc+=2) { + //interpolate B/R colors at R/B sites + bluetile[rr*TS+cc] = greentile[rr*TS+cc] - 0.25f*((greentile[(rr-1)*TS+(cc-1)]+greentile[(rr-1)*TS+(cc+1)]+greentile[(rr+1)*TS+cc+1]+greentile[(rr+1)*TS+cc-1]) - + min(clip_pt,rawData[i-1][j-1]+rawData[i-1][j+1]+rawData[i+1][j+1]+rawData[i+1][j-1])); + } +#endif + else +#ifdef __SSE2__ + for (int j=left+1,cc=1; j < right-1; j+=4,cc+=4) { + //interpolate B/R colors at R/B sites + _mm_storeu_ps(&redtile[rr*TS+cc], LVFU(greentile[rr*TS+cc]) - zd25v*((LVFU(greentile[(rr-1)*TS+cc-1])+LVFU(greentile[(rr-1)*TS+cc+1])+LVFU(greentile[(rr+1)*TS+cc+1])+LVFU(greentile[(rr+1)*TS+cc-1])) - + _mm_min_ps(clip_ptv,LVFU(rawData[i-1][j-1])+LVFU(rawData[i-1][j+1])+LVFU(rawData[i+1][j+1])+LVFU(rawData[i+1][j-1])))); + } +#else + for (int cc=(FC(i,2)&1)+1, j=left+cc; j < right-1; j+=2,cc+=2) { + //interpolate B/R colors at R/B sites + redtile[rr*TS+cc] = greentile[rr*TS+cc] - 0.25f*((greentile[(rr-1)*TS+cc-1]+greentile[(rr-1)*TS+cc+1]+greentile[(rr+1)*TS+cc+1]+greentile[(rr+1)*TS+cc-1]) - + min(clip_pt,rawData[i-1][j-1]+rawData[i-1][j+1]+rawData[i+1][j+1]+rawData[i+1][j-1])); + } +#endif + } + + +#ifdef __SSE2__ + __m128 temp1v,temp2v,greensumv; + selmask = _mm_set_epi32( 0xffffffff, 0, 0xffffffff, 0 ); +#endif + + // interpolate R/B using color differences + for (int i=top+2, rr=2; i< bottom-2; i++,rr++) { +#ifdef __SSE2__ + for (int cc=2+(FC(i,2)&1), j=left+cc; j < right-2; j+=4,cc+=4) { + // no need to take care about the borders of the tile. There's enough free space. + //interpolate R and B colors at G sites + greenv = LVFU(greentile[rr*TS+cc]); + greensumv = LVFU(greentile[(rr-1)*TS+cc]) + LVFU(greentile[(rr+1)*TS+cc]) + LVFU(greentile[rr*TS+cc-1]) + LVFU(greentile[rr*TS+cc+1]); + + temp1v = LVFU(redtile[rr*TS+cc]); + temp2v = greenv - zd25v*(greensumv - LVFU(redtile[(rr-1)*TS+cc]) - LVFU(redtile[(rr+1)*TS+cc]) - LVFU(redtile[rr*TS+cc-1]) - LVFU(redtile[rr*TS+cc+1])); + +// temp2v = greenv - zd25v*((LVFU(greentile[(rr-1)*TS+cc])-LVFU(redtile[(rr-1)*TS+cc]))+(LVFU(greentile[(rr+1)*TS+cc])-LVFU(redtile[(rr+1)*TS+cc]))+ +// (LVFU(greentile[rr*TS+cc-1])-LVFU(redtile[rr*TS+cc-1]))+(LVFU(greentile[rr*TS+cc+1])-LVFU(redtile[rr*TS+cc+1]))); + _mm_storeu_ps( &redtile[rr*TS+cc], vself(selmask, temp1v, temp2v)); + + temp1v = LVFU(bluetile[rr*TS+cc]); + + temp2v = greenv - zd25v*(greensumv - LVFU(bluetile[(rr-1)*TS+cc]) - LVFU(bluetile[(rr+1)*TS+cc]) - LVFU(bluetile[rr*TS+cc-1]) - LVFU(bluetile[rr*TS+cc+1])); + +// temp2v = greenv - zd25v*((LVFU(greentile[(rr-1)*TS+cc])-LVFU(bluetile[(rr-1)*TS+cc]))+(LVFU(greentile[(rr+1)*TS+cc])-LVFU(bluetile[(rr+1)*TS+cc]))+ +// (LVFU(greentile[rr*TS+cc-1])-LVFU(bluetile[rr*TS+cc-1]))+(LVFU(greentile[rr*TS+cc+1])-LVFU(bluetile[rr*TS+cc+1]))); + _mm_storeu_ps( &bluetile[rr*TS+cc], vself(selmask, temp1v, temp2v)); + } +#else + for (int cc=2+(FC(i,2)&1), j=left+cc; j < right-2; j+=2,cc+=2) { + //interpolate R and B colors at G sites + redtile[rr*TS+cc] = greentile[rr*TS+cc] - 0.25f*((greentile[(rr-1)*TS+cc]-redtile[(rr-1)*TS+cc])+(greentile[(rr+1)*TS+cc]-redtile[(rr+1)*TS+cc])+ + (greentile[rr*TS+cc-1]-redtile[rr*TS+cc-1])+(greentile[rr*TS+cc+1]-redtile[rr*TS+cc+1])); + bluetile[rr*TS+cc] = greentile[rr*TS+cc] - 0.25f*((greentile[(rr-1)*TS+cc]-bluetile[(rr-1)*TS+cc])+(greentile[(rr+1)*TS+cc]-bluetile[(rr+1)*TS+cc])+ + (greentile[rr*TS+cc-1]-bluetile[rr*TS+cc-1])+(greentile[rr*TS+cc+1]-bluetile[rr*TS+cc+1])); + } +#endif + } + + + for (int i=top+2, rr=2; i< bottom-2; i++,rr++) { +#ifdef __SSE2__ + for (j=left+2, cc=2; j< right-5; j+=4,cc+=4) { + _mm_storeu_ps(&red[i][j], LVFU(redtile[rr*TS+cc])); + _mm_storeu_ps(&green[i][j], LVFU(greentile[rr*TS+cc])); + _mm_storeu_ps(&blue[i][j], LVFU(bluetile[rr*TS+cc])); + } + for (; j< right-2; j++,cc++) { + red[i][j] = redtile[rr*TS+cc]; + green[i][j] = greentile[rr*TS+cc]; + blue[i][j] = bluetile[rr*TS+cc]; + } +#else + for (int j=left+2, cc=2; j< right-2; j++,cc++) { + red[i][j] = redtile[rr*TS+cc]; + green[i][j] = greentile[rr*TS+cc]; + blue[i][j] = bluetile[rr*TS+cc]; + } +#endif + + + } + if(plistenerActive && ((++progressCounter) % 16 == 0)) { +#ifdef _OPENMP +#pragma omp critical (updateprogress) +#endif +{ + progress += progressInc; + progress = min(1.0,progress); + plistener->setProgress (progress); +} + } + + } + free(buffer); +} // End of parallelization + if(plistenerActive) plistener->setProgress(1.00); + + + +} +#undef TS +#undef CLF diff --git a/rtengine/ffmanager.cc b/rtengine/ffmanager.cc new file mode 100644 index 000000000..abc7d64fe --- /dev/null +++ b/rtengine/ffmanager.cc @@ -0,0 +1,335 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "ffmanager.h" +#include "../rtgui/options.h" +#include +#include "safegtk.h" +#include "rawimage.h" +#include +#include +#include "imagedata.h" + +namespace rtengine{ + +extern const Settings* settings; + +// *********************** class ffInfo ************************************** + +inline ffInfo& ffInfo::operator =(const ffInfo &o){ + pathname = o.pathname; + maker = o.maker; + model = o.model; + lens = o.lens; + shutter = o.shutter; + focallength = o.focallength; + timestamp = o.timestamp; + if( ri ){ + delete ri; + ri = NULL; + } + return *this; +} + +bool ffInfo::operator <(const ffInfo &e2) const +{ + if( this->maker.compare( e2.maker) >=0 ) + return false; + if( this->model.compare( e2.model) >=0 ) + return false; + if( this->lens.compare( e2.lens) >=0 ) + return false; + if( this->focallength >= e2.focallength ) + return false; + if( this->timestamp >= e2.timestamp ) + return false; + return true; +} + +std::string ffInfo::key(const std::string &mak, const std::string &mod, const std::string &len, double focal, double apert ) +{ + std::ostringstream s; + s << mak << " " << mod << " "; + s.width(5); + s << len << " "; + s.precision( 2 ); + s.width(4); + s << focal << "mm F" << apert; + return s.str(); +} + +double ffInfo::distance(const std::string &mak, const std::string &mod, const std::string &len, double focallength, double aperture) const +{ + if( this->maker.compare( mak) != 0 ) + return INFINITY; + if( this->model.compare( mod) != 0 ) + return INFINITY; + if( this->lens.compare( len) != 0 ) + return INFINITY; + double dAperture = 2*(log(this->aperture) - log(aperture))/log(2);//more important for vignette + double dfocallength = (log(this->focallength/100.) - log(focallength/100.))/log(2);//more important for PRNU + + return sqrt( dfocallength*dfocallength + dAperture*dAperture); +} + +RawImage* ffInfo::getRawImage() +{ + if(ri) + return ri; + updateRawImage(); + + return ri; +} + +/* updateRawImage() load into ri the actual pixel data from pathname if there is a single shot + * otherwise load each file from the pathNames list and extract a template from the media; + * the first file is used also for reading all information other than pixels + */ +void ffInfo::updateRawImage() +{ + typedef unsigned int acc_t; + // averaging of flatfields if more than one is found matching the same key. + // this may not be necessary, as flatfield is further blurred before being applied to the processed image. + if( !pathNames.empty() ){ + std::list::iterator iName = pathNames.begin(); + ri = new RawImage(*iName); // First file used also for extra pixels informations (width,height, shutter, filters etc.. ) + if( ri->loadRaw(true)){ + delete ri; + ri=NULL; + }else{ + int H = ri->get_height(); + int W = ri->get_width(); + ri->compress_image(); + int rSize = W*((ri->getSensorType()==ST_BAYER || ri->getSensorType()==ST_FUJI_XTRANS)?1:3); + acc_t **acc = new acc_t*[H]; + for( int row=0; rowdata[row][col]; + int nFiles = 1; // First file data already loaded + + for( iName++; iName != pathNames.end(); iName++){ + RawImage* temp = new RawImage(*iName); + if( !temp->loadRaw(true)){ + temp->compress_image(); //\ TODO would be better working on original, because is temporary + nFiles++; + if( ri->getSensorType()==ST_BAYER || ri->getSensorType()==ST_FUJI_XTRANS ){ + for( int row=0; rowdata[row][col]; + } + }else{ + for( int row=0; rowdata[row][3*col+0]; + acc[row][3*col+1] += temp->data[row][3*col+1]; + acc[row][3*col+2] += temp->data[row][3*col+2]; + } + } + } + } + delete temp; + } + for (int row = 0; row < H; row++){ + for (int col = 0; col < rSize; col++) + ri->data[row][col] = acc[row][col] / nFiles; + delete [] acc[row]; + } + delete [] acc; + } + }else{ + ri = new RawImage(pathname); + if( ri->loadRaw(true)){ + delete ri; + ri=NULL; + }else { + ri->compress_image(); + } + } +} + + +// ************************* class FFManager ********************************* + +void FFManager::init( Glib::ustring pathname ) +{ + std::vector names; + Glib::RefPtr dir = Gio::File::create_for_path (pathname); + if( dir && !dir->query_exists()) + return; + safe_build_file_list (dir, names, pathname); + + ffList.clear(); + for (size_t i=0; isecond; + if( !i.pathNames.empty() && !i.pathname.empty() ){ + i.pathNames.push_back( i.pathname ); + i.pathname.clear(); + } + if( settings->verbose ){ + if( !i.pathname.empty() ) + printf( "%s: %s\n",i.key().c_str(),i.pathname.c_str()); + else{ + printf( "%s: MEAN of \n ",i.key().c_str()); + for( std::list::iterator iter = i.pathNames.begin(); iter != i.pathNames.end();iter++ ) + printf( "%s, ", iter->c_str() ); + printf("\n"); + } + } + } + currentPath = pathname; + return; +} + +ffInfo *FFManager::addFileInfo(const Glib::ustring &filename, bool pool ) +{ + Glib::RefPtr file = Gio::File::create_for_path(filename); + if (!file ) + return 0; + if( !file->query_exists()) + return 0; + Glib::RefPtr info = safe_query_file_info(file); + if (info && info->get_file_type() != Gio::FILE_TYPE_DIRECTORY && (!info->is_hidden() || !options.fbShowHidden)) { + size_t lastdot = info->get_name().find_last_of ('.'); + if (options.is_extention_enabled(lastdot!=Glib::ustring::npos ? info->get_name().substr (lastdot+1) : "")){ + RawImage ri(filename); + int res = ri.loadRaw(false); // Read informations about shot + if( !res ){ + ffList_t::iterator iter; + if(!pool){ + ffInfo n(filename,"","","",0,0,0); + iter = ffList.insert(std::pair< std::string,ffInfo>( "", 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); + /* 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 ); + 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 ) ); + }else{ + 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 ); + 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 ) ); + } + } + return &(iter->second); + } + } + } + return 0; +} + +void FFManager::getStat( int &totFiles, int &totTemplates) +{ + totFiles=0; + totTemplates=0; + for( ffList_t::iterator iter = ffList.begin(); iter != ffList.end();iter++ ){ + ffInfo &i = iter->second; + if( i.pathname.empty() ){ + totTemplates++; + totFiles += i.pathNames.size(); + }else + totFiles++; + } +} + +/* The search for the best match is twofold: + * if perfect matches for make and model are found, then the list is scanned for lesser distance in time + * otherwise if no match is found, the whole list is searched for lesser distance in lens and aperture + */ +ffInfo* FFManager::find( const std::string &mak, const std::string &mod, const std::string &len, double focal, double apert, time_t t ) +{ + if( ffList.empty() ) + return 0; + std::string key( ffInfo::key(mak,mod,len,focal,apert) ); + ffList_t::iterator iter = ffList.find( key ); + + if( iter != ffList.end() ){ + ffList_t::iterator bestMatch = iter; + time_t bestDeltaTime = ABS(iter->second.timestamp - t); + for(iter++; iter != ffList.end() && !key.compare( iter->second.key() ); iter++ ){ + time_t d = ABS(iter->second.timestamp - t ); + if( d< bestDeltaTime ){ + bestMatch = iter; + bestDeltaTime = d; + } + } + return &(bestMatch->second); + }else{ + iter = ffList.begin(); + ffList_t::iterator bestMatch = iter; + double bestD = iter->second.distance( mak, mod, len, focal, apert ); + for( iter++; iter != ffList.end();iter++ ){ + double d = iter->second.distance( mak, mod, len, focal, apert ); + if( d < bestD ){ + bestD = d; + bestMatch = iter; + } + } + return bestD != INFINITY ? &(bestMatch->second) : 0 ; + } +} + +RawImage* FFManager::searchFlatField( const std::string &mak, const std::string &mod, const std::string &len, double focal, double apert, time_t t ) +{ + ffInfo *ff = find( mak, mod, len, focal, apert, t ); + if( ff ) + return ff->getRawImage(); + else + return 0; +} + +RawImage* FFManager::searchFlatField( const Glib::ustring filename ) +{ + for ( ffList_t::iterator iter = ffList.begin(); iter != ffList.end();iter++ ){ + if( iter->second.pathname.compare( filename )==0 ) + return iter->second.getRawImage(); + } + ffInfo *ff = addFileInfo( filename , false); + if(ff) + return ff->getRawImage(); + return 0; +} + + +// Global variable +FFManager ffm; + + +} + diff --git a/rtengine/ffmanager.h b/rtengine/ffmanager.h new file mode 100644 index 000000000..415eaff9b --- /dev/null +++ b/rtengine/ffmanager.h @@ -0,0 +1,89 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 +#include +#include "rawimage.h" + +namespace rtengine{ + +class ffInfo +{ +public: + + Glib::ustring pathname; // filename of flat field + std::list pathNames; // other similar dark frames, used for average + std::string maker; ///< manufacturer + std::string model; ///< model + std::string lens; ///< lens + int iso; ///< ISO (gain) + double shutter; ///< shutter or exposure time in sec + double aperture; ///< aperture in stops + double focallength; ///< focal length in mm + time_t timestamp; ///< seconds since 1 Jan 1970 + + + ffInfo(const Glib::ustring &name, const std::string &mak, const std::string &mod,const std::string & len,double focal,double apert,time_t t) + :pathname(name),maker(mak),model(mod),lens(len),aperture(apert),focallength(focal),timestamp(t),ri(NULL){} + + ffInfo( const ffInfo &o) + :pathname(o.pathname),maker(o.maker),model(o.model),lens(o.lens),aperture(o.aperture),focallength(o.focallength),timestamp(o.timestamp),ri(NULL){} + ~ffInfo() { if( ri ) delete ri; } + + + ffInfo &operator =(const ffInfo &o); + bool operator <(const ffInfo &e2) const; + + // Calculate virtual distance between two shots; different model return infinite + double distance(const std::string &mak, const std::string &mod, const std::string &lens, double focallength, double aperture) const; + + static std::string key(const std::string &mak, const std::string &mod, const std::string &len, double focal, double apert ); + std::string key(){ return key( maker,model,lens,focallength,aperture); } + + RawImage *getRawImage(); + +protected: + RawImage *ri; ///< Flat Field raw data + + void updateRawImage(); +}; + +class FFManager +{ +public: + void init( Glib::ustring pathname ); + Glib::ustring getPathname(){ return currentPath; }; + void getStat( int &totFiles, int &totTemplate); + RawImage *searchFlatField( const std::string &mak, const std::string &mod, const std::string &len, double focallength, double apert, time_t t ); + RawImage *searchFlatField( const Glib::ustring filename ); + +protected: + typedef std::multimap ffList_t; + typedef std::map > bpList_t; + ffList_t ffList; + bool initialized; + Glib::ustring currentPath; + ffInfo *addFileInfo(const Glib::ustring &filename, bool pool=true ); + ffInfo *find( const std::string &mak, const std::string &mod, const std::string &len, double focal, double apert, time_t t ); +}; + +extern FFManager ffm; + +} diff --git a/rtengine/flatcurves.cc b/rtengine/flatcurves.cc new file mode 100644 index 000000000..179bbe9b0 --- /dev/null +++ b/rtengine/flatcurves.cc @@ -0,0 +1,379 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "curves.h" +#include +#include +#include "mytime.h" +#include + +#include +#include + +namespace rtengine { + +FlatCurve::FlatCurve (const std::vector& p, bool isPeriodic, int poly_pn) : kind(FCT_Empty), leftTangent(NULL), rightTangent(NULL), identityValue(0.5), periodic(isPeriodic) { + + ppn = poly_pn > 65500 ? 65500 : poly_pn; + poly_x.clear(); + poly_y.clear(); + + bool identity = true; + + if (p.size()>4) { + kind = (FlatCurveType)p[0]; + if (kind==FCT_MinMaxCPoints) { + int oneMorePoint = periodic ? 1:0; + N = (p.size()-1)/4; + x = new double[N+oneMorePoint]; + y = new double[N+oneMorePoint]; + leftTangent = new double[N+oneMorePoint]; + rightTangent = new double[N+oneMorePoint]; + int ix = 1; + for (int i=0; i= identityValue+1.e-7 || y[i] <= identityValue-1.e-7) + identity = false; + } + // The first point is copied to the end of the point list, to handle the curve periodicity + if (periodic) { + x[N] = p[1]+1.0; + y[N] = p[2]; + leftTangent[N] = p[3]; + rightTangent[N] = p[4]; + } + if (!identity && N > (periodic?1:0) ) { + CtrlPoints_set (); + fillHash(); + } + } + /*else if (kind==FCT_Parametric) { + }*/ + if (identity) + kind = FCT_Empty; + } +} + +FlatCurve::~FlatCurve () { + + delete [] x; + delete [] y; + delete [] leftTangent; + delete [] rightTangent; + delete [] ypp; + poly_x.clear(); + poly_y.clear(); +} + +/* + * The nominal (identity) curve may not be 0.5, use this method to set it to whatever value in the 0.-1. range you want + * Return true if the curve is nominal + */ +bool FlatCurve::setIdentityValue (double iVal) { + + if (identityValue == iVal) + return kind==FCT_Empty; + + identityValue = iVal; + bool identity = true; + for (int i=0; i= identityValue+1.e-7 || y[i] <= identityValue-1.e-7) { + identity = false; + break; + } + } + + if (!identity && N > (periodic?1:0) ) { + CtrlPoints_set (); + fillHash(); + kind = FCT_MinMaxCPoints; + } + else { + poly_x.clear(); + poly_y.clear(); + hash.clear(); + kind = FCT_Empty; + } + + return kind==FCT_Empty; +} + +void FlatCurve::CtrlPoints_set () { + + int N_ = periodic ? N : N-1; + int nbSubCurvesPoints = N_*6; + + std::vector sc_x(nbSubCurvesPoints); // X sub-curve points ( XP0,XP1,XP2, XP2,XP3,XP4, ...) + std::vector sc_y(nbSubCurvesPoints); // Y sub-curve points ( YP0,YP1,YP2, YP2,YP3,YP4, ...) + std::vector sc_length(N_*2); // Length of the subcurves + std::vector sc_isLinear(N_*2); // true if the subcurve is linear + double total_length=0.; + + // Create the list of Bezier sub-curves + // CtrlPoints_set is called if N > 1 + + unsigned int j = 0; + unsigned int k = 0; + + for (int i = 0; i < N_;) { + double length; + double dx; + double dy; + double xp1, xp2, yp2, xp3; + bool startLinear, endLinear; + + startLinear = (rightTangent[i] == 0.) || (y[i] == y[i+1]); + endLinear = (leftTangent [i+1] == 0.) || (y[i] == y[i+1]); + + if (startLinear && endLinear) { + // line shape + sc_x[j] = x[i]; + sc_y[j++] = y[i]; + sc_x[j] = x[i+1]; + sc_y[j] = y[i+1]; + sc_isLinear[k] = true; + i++; + + dx = sc_x[j] - sc_x[j-1]; + dy = sc_y[j] - sc_y[j-1]; + length = sqrt(dx*dx + dy*dy); + j++; + + // Storing the length of all sub-curves and the total length (to have a better distribution + // of the points along the curve) + sc_length[k++] = length; + total_length += length; + } + else { + if (startLinear) { + xp1 = x[i]; + } + else { + //xp1 = (xp4 - xp0) * rightTangent0 + xp0; + xp1 = (x[i+1] - x[i]) * rightTangent[i] + x[i]; + } + if (endLinear) { + xp3 = x[i+1]; + } + else { + //xp3 = (xp0 - xp4]) * leftTangent4 + xp4; + xp3 = (x[i] - x[i+1]) * leftTangent[i+1] + x[i+1]; + } + + xp2 = (xp1 + xp3) / 2.0; + yp2 = (y[i] + y[i+1]) / 2.0; + + if (rightTangent[i]+leftTangent[i+1] > 1.0) { // also means that start and end are not linear + xp1 = xp3 = xp2; + } + + if (startLinear) { + // Point 0, 2 + sc_x[j] = x[i]; + sc_y[j++] = y[i]; + sc_x[j] = xp2; + sc_y[j] = yp2; + sc_isLinear[k] = true; + + dx = sc_x[j] - sc_x[j-1]; + dy = sc_y[j] - sc_y[j-1]; + length = sqrt(dx*dx + dy*dy); + j++; + + // Storing the length of all sub-curves and the total length (to have a better distribution + // of the points along the curve) + sc_length[k++] = length; + total_length += length; + } + else { + // Point 0, 1, 2 + sc_x[j] = x[i]; + sc_y[j++] = y[i]; + sc_x[j] = xp1; + sc_y[j] = y[i]; + + dx = sc_x[j] - sc_x[j-1]; + dy = sc_y[j] - sc_y[j-1]; + length = sqrt(dx*dx + dy*dy); + j++; + + sc_x[j] = xp2; + sc_y[j] = yp2; + sc_isLinear[k] = false; + + dx = sc_x[j] - sc_x[j-1]; + dy = sc_y[j] - sc_y[j-1]; + length += sqrt(dx*dx + dy*dy); + j++; + + // Storing the length of all sub-curves and the total length (to have a better distribution + // of the points along the curve) + sc_length[k++] = length; + total_length += length; + } + if (endLinear) { + // Point 2, 4 + sc_x[j] = xp2; + sc_y[j++] = yp2; + sc_x[j] = x[i+1]; + sc_y[j] = y[i+1]; + sc_isLinear[k] = true; + + dx = sc_x[j] - sc_x[j-1]; + dy = sc_y[j] - sc_y[j-1]; + length = sqrt(dx*dx + dy*dy); + j++; + + // Storing the length of all sub-curves and the total length (to have a better distribution + // of the points along the curve) + sc_length[k++] = length; + total_length += length; + } + else { + // Point 2, 3, 4 + sc_x[j] = xp2; + sc_y[j++] = yp2; + sc_x[j] = xp3; + sc_y[j] = y[i+1]; + + dx = sc_x[j] - sc_x[j-1]; + dy = sc_y[j] - sc_y[j-1]; + length = sqrt(dx*dx + dy*dy); + j++; + + sc_x[j] = x[i+1]; + sc_y[j] = y[i+1]; + sc_isLinear[k] = false; + + dx = sc_x[j] - sc_x[j-1]; + dy = sc_y[j] - sc_y[j-1]; + length += sqrt(dx*dx + dy*dy); + j++; + + // Storing the length of all sub-curves and the total length (to have a better distribution + // of the points along the curve) + sc_length[k++] = length; + total_length += length; + } + i++; + } + } + + poly_x.clear(); + poly_y.clear(); + j = 0; + + // adding an initial horizontal line if necessary + if (!periodic && sc_x[j] != 0.) { + poly_x.push_back(0.); + poly_y.push_back(sc_y[j]); + } + + // the first point of the curves + poly_x.push_back(sc_x[j]); + poly_y.push_back(sc_y[j]); + + firstPointIncluded = false; + + // create the polyline with the number of points adapted to the X range of the sub-curve + for (unsigned int i=0; i < k; i++) { + if (sc_isLinear[i]) { + j++; // skip the first point + poly_x.push_back(sc_x[j]); + poly_y.push_back(sc_y[j++]); + } + else { + nbr_points = (int)(((double)(ppn) * sc_length[i] )/ total_length); + if (nbr_points<0){ + for(size_t it=0;it < sc_x.size(); it+=3) printf("sc_length[%zd/3]=%f \n",it,sc_length[it/3]); + printf("Flat curve: error detected!\n i=%d k=%d periodic=%d nbr_points=%d ppn=%d N=%d sc_length[i/3]=%f total_length=%f\n",i,k,periodic,nbr_points,ppn,N,sc_length[i/3],total_length); + exit(0); + } + // increment along the curve, not along the X axis + increment = 1.0 / (double)(nbr_points-1); + x1 = sc_x[j]; y1 = sc_y[j++]; + x2 = sc_x[j]; y2 = sc_y[j++]; + x3 = sc_x[j]; y3 = sc_y[j++]; + AddPolygons (); + } + } + + // adding the final horizontal segment, always (see under) + poly_x.push_back(3.0); // 3.0 is a hack for optimization purpose of the getVal method (the last value has to be beyond the normal range) + poly_y.push_back(sc_y[j-1]); + + /* + // Checking the values + Glib::ustring fname = "Curve.xyz"; // TopSolid'Design "plot" file format + std::ofstream f (fname.c_str()); + f << "$" << std::endl;; + for (unsigned int iter = 0; iter < poly_x.size(); iter++) { + f << poly_x[iter] << ", " << poly_y[iter] << ", 0." << std::endl;; + } + f << "$" << std::endl;; + f.close (); + */ +} + +double FlatCurve::getVal (double t) const { + + switch (kind) { + + case FCT_MinMaxCPoints : { + + // magic to handle curve periodicity : we look above the 1.0 bound for the value + if (t < poly_x[0]) t += 1.0; + + // do a binary search for the right interval: + int k_lo = 0, k_hi = poly_x.size() - 1; + while (k_hi - k_lo > 1){ + int k = (k_hi + k_lo) / 2; + if (poly_x[k] > t) + k_hi = k; + else + k_lo = k; + } + + double dx = poly_x[k_hi] - poly_x[k_lo]; + double dy = poly_y[k_hi] - poly_y[k_lo]; + return poly_y[k_lo] + (t - poly_x[k_lo]) * dy / dx; + break; + } + /*case Parametric : { + break; + }*/ + case FCT_Empty : + case FCT_Linear : // Linear doesn't exist yet and is then considered as identity + default: + return identityValue; + } +} + +void FlatCurve::getVal (const std::vector& t, std::vector& res) const { + + res.resize (t.size()); + for (unsigned int i=0; i + * + * 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 _GAUSS_H_ +#define _GAUSS_H_ + +#include +#include +#include +#include "alignedbuffer.h" +#ifdef _OPENMP +#include +#endif +#ifdef __SSE__ +#if defined( WIN32 ) && defined(__x86_64__) + #include +#else + #include +#endif +#endif + +// classical filtering if the support window is small: + +template void gaussHorizontal3 (T** src, T** dst, AlignedBufferMP &buffer, int W, int H, const float c0, const float c1) { + +#ifdef _OPENMP +#pragma omp for +#endif + for (int i=0; i* pBuf = buffer.acquire(); + T* temp=(T*)pBuf->data; + + for (int j=1; j void gaussVertical3 (T** src, T** dst, AlignedBufferMP &buffer, int W, int H, const float c0, const float c1) { + +#ifdef _OPENMP +#pragma omp for +#endif + for (int i=0; i* pBuf = buffer.acquire(); + T* temp = (T*)pBuf->data; + + for (int j = 1; j __attribute__((force_align_arg_pointer)) void gaussVertical3Sse (T** src, T** dst, int W, int H, const float c0, const float c1) { +#else +template void gaussVertical3Sse (T** src, T** dst, int W, int H, const float c0, const float c1) { +#endif + __m128 Tv,Tm1v,Tp1v; + __m128 c0v,c1v; + c0v = _mm_set1_ps(c0); + c1v = _mm_set1_ps(c1); +#ifdef _OPENMP +#pragma omp for +#endif + for (int i=0; i1) + Tv = _mm_loadu_ps( &src[1][i]); + for (int j=1; j __attribute__((force_align_arg_pointer)) void gaussHorizontal3Sse (T** src, T** dst, int W, int H, const float c0, const float c1) { +#else +template void gaussHorizontal3Sse (T** src, T** dst, int W, int H, const float c0, const float c1) { +#endif + float tmp[W][4] __attribute__ ((aligned (16))); + + __m128 Tv,Tm1v,Tp1v; + __m128 c0v,c1v; + c0v = _mm_set1_ps(c0); + c1v = _mm_set1_ps(c1); +#ifdef _OPENMP +#pragma omp for +#endif + for (int i=0; i1) + Tv = _mm_set_ps( src[i][1], src[i+1][1], src[i+2][1], src[i+3][1] ); + for (int j=1; j __attribute__((force_align_arg_pointer)) void gaussHorizontalSse (T** src, T** dst, int W, int H, float sigma) { +#else +template void gaussHorizontalSse (T** src, T** dst, int W, int H, float sigma) { +#endif + if (sigma<0.25) { + // dont perform filtering + if (src!=dst) +#pragma omp for + for (int i = 0; i (src, dst, W, H, c0, c1); + return; + } + + // coefficient calculation + float q = 0.98711 * sigma - 0.96330; + if (sigma<2.5) + q = 3.97156 - 4.14554 * sqrt (1.0 - 0.26891 * sigma); + float b0 = 1.57825 + 2.44413*q + 1.4281*q*q + 0.422205*q*q*q; + float b1 = 2.44413*q + 2.85619*q*q + 1.26661*q*q*q; + float b2 = -1.4281*q*q - 1.26661*q*q*q; + float b3 = 0.422205*q*q*q; + float B = 1.0 - (b1+b2+b3) / b0; + + b1 /= b0; + b2 /= b0; + b3 /= b0; + + // From: Bill Triggs, Michael Sdika: Boundary Conditions for Young-van Vliet Recursive Filtering + float M[3][3]; + M[0][0] = -b3*b1+1.0-b3*b3-b2; + M[0][1] = (b3+b1)*(b2+b3*b1); + M[0][2] = b3*(b1+b3*b2); + M[1][0] = b1+b3*b2; + M[1][1] = -(b2-1.0)*(b2+b3*b1); + M[1][2] = -(b3*b1+b3*b3+b2-1.0)*b3; + M[2][0] = b3*b1+b2+b1*b1-b2*b2; + M[2][1] = b1*b2+b3*b2*b2-b1*b3*b3-b3*b3*b3-b3*b2+b3; + M[2][2] = b3*(b1+b3*b2); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) { + M[i][j] *= (1.0+b2+(b1-b3)*b3); + M[i][j] /= (1.0+b1-b2+b3)*(1.0-b1-b2-b3); + } + float tmp[W][4] __attribute__ ((aligned (16))); + float tmpV[4] __attribute__ ((aligned (16))); + __m128 Rv; + __m128 Tv,Tm2v,Tm3v; + __m128 Bv,b1v,b2v,b3v; + __m128 temp2W,temp2Wp1; + Bv = _mm_set1_ps(B); + b1v = _mm_set1_ps(b1); + b2v = _mm_set1_ps(b2); + b3v = _mm_set1_ps(b3); +#pragma omp for + for (int i=0; i=0; j--) { + Tv = Rv; + Rv = _mm_load_ps(&tmp[j][0]) * Bv + Tv * b1v + Tm2v * b2v + Tm3v * b3v; + _mm_store_ps( &tmp[j][0], Rv ); + Tm3v = Tm2v; + Tm2v = Tv; + } + + for (int j=0; j=0; j--) + tmp[j][0] = B * tmp[j][0] + b1*tmp[j+1][0] + b2*tmp[j+2][0] + b3*tmp[j+3][0]; + + for (int j=0; j void gaussHorizontal (T** src, T** dst, AlignedBufferMP &buffer, int W, int H, double sigma) { + +#ifdef __SSE__ + if(sigma < 70) { // bigger sigma only with double precision + gaussHorizontalSse (src, dst, W, H, sigma); + return; + } +#endif + if (sigma<0.25) { + // dont perform filtering + if (src!=dst) +#pragma omp for + for (int i = 0; i (src, dst, buffer, W, H, c0, c1); + return; + } + + // coefficient calculation + double q = 0.98711 * sigma - 0.96330; + if (sigma<2.5) + q = 3.97156 - 4.14554 * sqrt (1.0 - 0.26891 * sigma); + double b0 = 1.57825 + 2.44413*q + 1.4281*q*q + 0.422205*q*q*q; + double b1 = 2.44413*q + 2.85619*q*q + 1.26661*q*q*q; + double b2 = -1.4281*q*q - 1.26661*q*q*q; + double b3 = 0.422205*q*q*q; + double B = 1.0 - (b1+b2+b3) / b0; + + b1 /= b0; + b2 /= b0; + b3 /= b0; + + // From: Bill Triggs, Michael Sdika: Boundary Conditions for Young-van Vliet Recursive Filtering + double M[3][3]; + M[0][0] = -b3*b1+1.0-b3*b3-b2; + M[0][1] = (b3+b1)*(b2+b3*b1); + M[0][2] = b3*(b1+b3*b2); + M[1][0] = b1+b3*b2; + M[1][1] = -(b2-1.0)*(b2+b3*b1); + M[1][2] = -(b3*b1+b3*b3+b2-1.0)*b3; + M[2][0] = b3*b1+b2+b1*b1-b2*b2; + M[2][1] = b1*b2+b3*b2*b2-b1*b3*b3-b3*b3*b3-b3*b2+b3; + M[2][2] = b3*(b1+b3*b2); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + M[i][j] /= (1.0+b1-b2+b3)*(1.0+b2+(b1-b3)*b3); + + #pragma omp for + for (int i=0; i* pBuf = buffer.acquire(); + double* temp2 = pBuf->data; + + temp2[0] = B * src[i][0] + b1*src[i][0] + b2*src[i][0] + b3*src[i][0]; + temp2[1] = B * src[i][1] + b1*temp2[0] + b2*src[i][0] + b3*src[i][0]; + temp2[2] = B * src[i][2] + b1*temp2[1] + b2*temp2[0] + b3*src[i][0]; + + for (int j=3; j=0; j--) + temp2[j] = B * temp2[j] + b1*temp2[j+1] + b2*temp2[j+2] + b3*temp2[j+3]; + for (int j=0; j __attribute__((force_align_arg_pointer)) void gaussVerticalSse (T** src, T** dst, int W, int H, float sigma) { +#else +template void gaussVerticalSse (T** src, T** dst, int W, int H, float sigma) { +#endif + if (sigma<0.25) { + // dont perform filtering + if (src!=dst) +#pragma omp for + for (int i = 0; i (src, dst, W, H, c0, c1); + return; + } + + // coefficient calculation + double q = 0.98711 * sigma - 0.96330; + if (sigma<2.5) + q = 3.97156 - 4.14554 * sqrt (1.0 - 0.26891 * sigma); + double b0 = 1.57825 + 2.44413*q + 1.4281*q*q + 0.422205*q*q*q; + double b1 = 2.44413*q + 2.85619*q*q + 1.26661*q*q*q; + double b2 = -1.4281*q*q - 1.26661*q*q*q; + double b3 = 0.422205*q*q*q; + double B = 1.0 - (b1+b2+b3) / b0; + + b1 /= b0; + b2 /= b0; + b3 /= b0; + + // From: Bill Triggs, Michael Sdika: Boundary Conditions for Young-van Vliet Recursive Filtering + double M[3][3]; + M[0][0] = -b3*b1+1.0-b3*b3-b2; + M[0][1] = (b3+b1)*(b2+b3*b1); + M[0][2] = b3*(b1+b3*b2); + M[1][0] = b1+b3*b2; + M[1][1] = -(b2-1.0)*(b2+b3*b1); + M[1][2] = -(b3*b1+b3*b3+b2-1.0)*b3; + M[2][0] = b3*b1+b2+b1*b1-b2*b2; + M[2][1] = b1*b2+b3*b2*b2-b1*b3*b3-b3*b3*b3-b3*b2+b3; + M[2][2] = b3*(b1+b3*b2); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) { + M[i][j] *= (1.0+b2+(b1-b3)*b3); + M[i][j] /= (1.0+b1-b2+b3)*(1.0-b1-b2-b3); + } + float tmp[H][4] __attribute__ ((aligned (16))); + __m128 Rv; + __m128 Tv,Tm2v,Tm3v; + __m128 Bv,b1v,b2v,b3v; + __m128 temp2W,temp2Wp1; + Bv = _mm_set1_ps(B); + b1v = _mm_set1_ps(b1); + b2v = _mm_set1_ps(b2); + b3v = _mm_set1_ps(b3); + + +#ifdef _OPENMP +#pragma omp for +#endif + for (int i=0; i=0; j--) { + Tv = Rv; + Rv = _mm_load_ps(&tmp[j][0]) * Bv + Tv * b1v + Tm2v * b2v + Tm3v * b3v; + _mm_storeu_ps( &dst[j][i], Rv ); + Tm3v = Tm2v; + Tm2v = Tv; + } + } +// Borders are done without SSE +#pragma omp for + for(int i=W-(W%4);i=0; j--) + tmp[j][0] = B * tmp[j][0] + b1*tmp[j+1][0] + b2*tmp[j+2][0] + b3*tmp[j+3][0]; + + for (int j=0; j void gaussVertical (T** src, T** dst, AlignedBufferMP &buffer, int W, int H, double sigma) { + +#ifdef __SSE__ + if(sigma < 70) { // bigger sigma only with double precision + gaussVerticalSse (src, dst, W, H, sigma); + return; + } +#endif + + if (sigma<0.25) { + // dont perform filtering + if (src!=dst) +#pragma omp for + for (int i = 0; i (src, dst, buffer, W, H, c0, c1); + return; + } + + // coefficient calculation + double q = 0.98711 * sigma - 0.96330; + if (sigma<2.5) + q = 3.97156 - 4.14554 * sqrt (1.0 - 0.26891 * sigma); + double b0 = 1.57825 + 2.44413*q + 1.4281*q*q + 0.422205*q*q*q; + double b1 = 2.44413*q + 2.85619*q*q + 1.26661*q*q*q; + double b2 = -1.4281*q*q - 1.26661*q*q*q; + double b3 = 0.422205*q*q*q; + double B = 1.0 - (b1+b2+b3) / b0; + + b1 /= b0; + b2 /= b0; + b3 /= b0; + + // From: Bill Triggs, Michael Sdika: Boundary Conditions for Young-van Vliet Recursive Filtering + double M[3][3]; + M[0][0] = -b3*b1+1.0-b3*b3-b2; + M[0][1] = (b3+b1)*(b2+b3*b1); + M[0][2] = b3*(b1+b3*b2); + M[1][0] = b1+b3*b2; + M[1][1] = -(b2-1.0)*(b2+b3*b1); + M[1][2] = -(b3*b1+b3*b3+b2-1.0)*b3; + M[2][0] = b3*b1+b2+b1*b1-b2*b2; + M[2][1] = b1*b2+b3*b2*b2-b1*b3*b3-b3*b3*b3-b3*b2+b3; + M[2][2] = b3*(b1+b3*b2); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + M[i][j] /= (1.0+b1-b2+b3)*(1.0+b2+(b1-b3)*b3); +#ifdef _OPENMP +#pragma omp for +#endif + for (int i=0; i* pBuf = buffer.acquire(); + double* temp2 = pBuf->data; + temp2[0] = B * src[0][i] + b1*src[0][i] + b2*src[0][i] + b3*src[0][i]; + temp2[1] = B * src[1][i] + b1*temp2[0] + b2*src[0][i] + b3*src[0][i]; + temp2[2] = B * src[2][i] + b1*temp2[1] + b2*temp2[0] + b3*src[0][i]; + + for (int j=3; j=0; j--) + temp2[j] = B * temp2[j] + b1*temp2[j+1] + b2*temp2[j+2] + b3*temp2[j+3]; + + for (int j=0; j void gaussDerivH (T** src, T** dst, AlignedBufferMP &buffer, int W, int H, double sigma) { + + + if (sigma<0.6) { + // apply symmetric derivative +#ifdef _OPENMP +#pragma omp for +#endif + for (int i=0; i* pBuf = buffer.acquire(); + T* temp = (T*)pBuf->data; + // double* temp = buffer->data;// replaced by 2 lines above + for (int j=1; j* pBuf = buffer.acquire(); + T* temp2 = (T*)pBuf->data; + // double* temp2 = buffer->data;// replaced by 2 lines above + + double src0 = (src[i][1]-src[i][0]); + + temp2[0] = B * src0 + b1*src0 + b2*src0 + b3*src0; + temp2[1] = B * 0.5*(src[i][2]-src[i][0]) + b1*temp2[0] + b2*src0 + b3*src0; + temp2[2] = B * 0.5*(src[i][3]-src[i][1]) + b1*temp2[1] + b2*temp2[0] + b3*src0; + + for (int j=3; j=0; j--) + temp2[j] = B * temp2[j] + b1*temp2[j+1] + b2*temp2[j+2] + b3*temp2[j+3]; + for (int j=0; j void gaussDerivV (T** src, T** dst, AlignedBufferMP &buffer, int W, int H, double sigma) { + + if (sigma<0.6) { + // apply symmetric derivative +#ifdef _OPENMP +#pragma omp for +#endif + for (int j=0; j* pBuf = buffer.acquire(); + T* temp = (T*)pBuf->data; + // double* temp = buffer->data;// replaced by 2 lines above + for (int i = 1; i* pBuf = buffer.acquire(); + T* temp2 = (T*)pBuf->data; + // double* temp2 = buffer->data;// replaced by 2 lines above + + double src0 = 0.5*(src[1][i]-src[0][i]); + + temp2[0] = B * src0 + b1*src0 + b2*src0 + b3*src0; + temp2[1] = B * 0.5*(src[2][i]-src[0][i]) + b1*temp2[0] + b2*src0 + b3*src0; + temp2[2] = B * 0.5*(src[3][i]-src[1][i]) + b1*temp2[1] + b2*temp2[0] + b3*src0; + + for (int j=3; j=0; j--) + temp2[j] = B * temp2[j] + b1*temp2[j+1] + b2*temp2[j+2] + b3*temp2[j+3]; + + for (int j=0; j +// +// +// code dated: February 12, 2011 +// +// green_equil_RT.cc is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +//////////////////////////////////////////////////////////////// +#define TS 256 // Tile size + +#include +#include +#include + + +#include "rt_math.h" +#include "rawimagesource.h" + +namespace rtengine { + +//void green_equilibrate()//for dcraw implementation +void RawImageSource::green_equilibrate(float thresh) +{ + // thresh = threshold for performing green equilibration; max percentage difference of G1 vs G2 + // G1-G2 differences larger than this will be assumed to be Nyquist texture, and left untouched + + int height=H, width=W; + + // local variables + float** rawptr = rawData; + array2D cfa (width,height,rawptr); + //array2D checker (width,height,ARRAY2D_CLEAR_DATA); + + + //int verbose=1; + + static const float eps=1.0; //tolerance to avoid dividing by zero + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + // Fill G interpolated values with border interpolation and input values + + //int vote1, vote2; + //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 +#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]; + + float d1=(o1_1+o1_2+o1_3+o1_4)*0.25f; + float d2=(o2_1+o2_2+o2_3+o2_4)*0.25f; + + 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.0; + 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.0; + //%%%%%%%%%%%%%%%%%%%%%% + + //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]; + + float gse=(cfa[rr+1][cc+1])+0.5*(cfa[rr][cc]-cfa[rr+2][cc+2]); + float gnw=(cfa[rr-1][cc-1])+0.5*(cfa[rr][cc]-cfa[rr-2][cc-2]); + float gne=(cfa[rr-1][cc+1])+0.5*(cfa[rr][cc]-cfa[rr-2][cc+2]); + float gsw=(cfa[rr+1][cc-1])+0.5*(cfa[rr][cc]-cfa[rr+2][cc-2]); + + + + 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])); + + 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); + //counter++; + } + + } + // } + } + //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/helperavx.h b/rtengine/helperavx.h new file mode 100644 index 000000000..e1b3dadee --- /dev/null +++ b/rtengine/helperavx.h @@ -0,0 +1,271 @@ +#ifndef __AVX__ +#error Please specify -mavx. +#endif + +#ifdef __GNUC__ +#define INLINE __attribute__((always_inline)) +#else +#define INLINE inline +#endif + +#include +#include + +typedef __m256d vdouble; +typedef __m128i vint; +typedef __m256i vmask; + +typedef __m256 vfloat; +typedef struct { + vint x, y; +} vint2; + +// + +static INLINE vint vrint_vi_vd(vdouble vd) { return _mm256_cvtpd_epi32(vd); } +static INLINE vint vtruncate_vi_vd(vdouble vd) { return _mm256_cvttpd_epi32(vd); } +static INLINE vdouble vcast_vd_vi(vint vi) { return _mm256_cvtepi32_pd(vi); } +static INLINE vdouble vcast_vd_d(double d) { return _mm256_set_pd(d, d, d, d); } +static INLINE vint vcast_vi_i(int i) { return _mm_set_epi32(i, i, i, i); } + +static INLINE vmask vreinterpret_vm_vd(vdouble vd) { return (__m256i)vd; } +static INLINE vdouble vreinterpret_vd_vm(vmask vm) { return (__m256d)vm; } + +static INLINE vmask vreinterpret_vm_vf(vfloat vf) { return (__m256i)vf; } +static INLINE vfloat vreinterpret_vf_vm(vmask vm) { return (__m256)vm; } + +// + +static INLINE vfloat vcast_vf_f(float f) { return _mm256_set_ps(f, f, f, f, f, f, f, f); } + +static INLINE vfloat vaddf(vfloat x, vfloat y) { return _mm256_add_ps(x, y); } +static INLINE vfloat vsubf(vfloat x, vfloat y) { return _mm256_sub_ps(x, y); } +static INLINE vfloat vmulf(vfloat x, vfloat y) { return _mm256_mul_ps(x, y); } +static INLINE vfloat vdivf(vfloat x, vfloat y) { return _mm256_div_ps(x, y); } +static INLINE vfloat vrecf(vfloat x) { return vdivf(vcast_vf_f(1.0f), x); } +static INLINE vfloat vsqrtf(vfloat x) { return _mm256_sqrt_ps(x); } +static INLINE vfloat vmaxf(vfloat x, vfloat y) { return _mm256_max_ps(x, y); } +static INLINE vfloat vminf(vfloat x, vfloat y) { return _mm256_min_ps(x, y); } + +// + +static INLINE vdouble vadd(vdouble x, vdouble y) { return _mm256_add_pd(x, y); } +static INLINE vdouble vsub(vdouble x, vdouble y) { return _mm256_sub_pd(x, y); } +static INLINE vdouble vmul(vdouble x, vdouble y) { return _mm256_mul_pd(x, y); } +static INLINE vdouble vdiv(vdouble x, vdouble y) { return _mm256_div_pd(x, y); } +static INLINE vdouble vrec(vdouble x) { return _mm256_div_pd(_mm256_set_pd(1, 1, 1, 1), x); } +static INLINE vdouble vsqrt(vdouble x) { return _mm256_sqrt_pd(x); } +static INLINE vdouble vmla(vdouble x, vdouble y, vdouble z) { return vadd(vmul(x, y), z); } + +static INLINE vdouble vmax(vdouble x, vdouble y) { return _mm256_max_pd(x, y); } +static INLINE vdouble vmin(vdouble x, vdouble y) { return _mm256_min_pd(x, y); } + +static INLINE vdouble vabs(vdouble d) { return (__m256d)_mm256_andnot_pd(_mm256_set_pd(-0.0,-0.0,-0.0,-0.0), d); } +static INLINE vdouble vneg(vdouble d) { return (__m256d)_mm256_xor_pd(_mm256_set_pd(-0.0,-0.0,-0.0,-0.0), d); } + +// + +static INLINE vint vaddi(vint x, vint y) { return _mm_add_epi32(x, y); } +static INLINE vint vsubi(vint x, vint y) { return _mm_sub_epi32(x, y); } + +static INLINE vint vandi(vint x, vint y) { return _mm_and_si128(x, y); } +static INLINE vint vandnoti(vint x, vint y) { return _mm_andnot_si128(x, y); } +static INLINE vint vori(vint x, vint y) { return _mm_or_si128(x, y); } +static INLINE vint vxori(vint x, vint y) { return _mm_xor_si128(x, y); } + +static INLINE vint vslli(vint x, int c) { return _mm_slli_epi32 (x, c); } +static INLINE vint vsrli(vint x, int c) { return _mm_srli_epi32 (x, c); } +static INLINE vint vsrai(vint x, int c) { return _mm_srai_epi32 (x, c); } + +// + +static INLINE vmask vandm(vmask x, vmask y) { return (vmask)_mm256_and_pd((__m256d)x, (__m256d)y); } +static INLINE vmask vandnotm(vmask x, vmask y) { return (vmask)_mm256_andnot_pd((__m256d)x, (__m256d)y); } +static INLINE vmask vorm(vmask x, vmask y) { return (vmask)_mm256_or_pd((__m256d)x, (__m256d)y); } +static INLINE vmask vxorm(vmask x, vmask y) { return (vmask)_mm256_xor_pd((__m256d)x, (__m256d)y); } + +static INLINE vmask vmask_eq(vdouble x, vdouble y) { return (__m256i)_mm256_cmp_pd(x, y, _CMP_EQ_OQ); } +static INLINE vmask vmask_neq(vdouble x, vdouble y) { return (__m256i)_mm256_cmp_pd(x, y, _CMP_NEQ_OQ); } +static INLINE vmask vmask_lt(vdouble x, vdouble y) { return (__m256i)_mm256_cmp_pd(x, y, _CMP_LT_OQ); } +static INLINE vmask vmask_le(vdouble x, vdouble y) { return (__m256i)_mm256_cmp_pd(x, y, _CMP_LE_OQ); } +static INLINE vmask vmask_gt(vdouble x, vdouble y) { return (__m256i)_mm256_cmp_pd(x, y, _CMP_GT_OQ); } +static INLINE vmask vmask_ge(vdouble x, vdouble y) { return (__m256i)_mm256_cmp_pd(x, y, _CMP_GE_OQ); } + +static INLINE vmask vmaskf_eq(vfloat x, vfloat y) { return (__m256i)_mm256_cmp_ps(x, y, _CMP_EQ_OQ); } +static INLINE vmask vmaskf_neq(vfloat x, vfloat y) { return (__m256i)_mm256_cmp_ps(x, y, _CMP_NEQ_OQ); } +static INLINE vmask vmaskf_lt(vfloat x, vfloat y) { return (__m256i)_mm256_cmp_ps(x, y, _CMP_LT_OQ); } +static INLINE vmask vmaskf_le(vfloat x, vfloat y) { return (__m256i)_mm256_cmp_ps(x, y, _CMP_LE_OQ); } +static INLINE vmask vmaskf_gt(vfloat x, vfloat y) { return (__m256i)_mm256_cmp_ps(x, y, _CMP_GT_OQ); } +static INLINE vmask vmaskf_ge(vfloat x, vfloat y) { return (__m256i)_mm256_cmp_ps(x, y, _CMP_GE_OQ); } + +static INLINE vmask vmaski_eq(vint x, vint y) { + __m256d r = _mm256_cvtepi32_pd(_mm_and_si128(_mm_cmpeq_epi32(x, y), _mm_set_epi32(1, 1, 1, 1))); + return vmask_eq(r, _mm256_set_pd(1, 1, 1, 1)); +} + +static INLINE vdouble vsel(vmask mask, vdouble x, vdouble y) { + return (__m256d)vorm(vandm(mask, (__m256i)x), vandnotm(mask, (__m256i)y)); +} + +static INLINE vint vseli_lt(vdouble d0, vdouble d1, vint x, vint y) { + __m128i mask = _mm256_cvtpd_epi32(_mm256_and_pd(_mm256_cmp_pd(d0, d1, _CMP_LT_OQ), _mm256_set_pd(1.0, 1.0, 1.0, 1.0))); + mask = _mm_cmpeq_epi32(mask, _mm_set_epi32(1, 1, 1, 1)); + return vori(vandi(mask, x), vandnoti(mask, y)); +} + +// + +static INLINE vint2 vcast_vi2_vm(vmask vm) { + vint2 r; + r.x = _mm256_castsi256_si128(vm); + r.y = _mm256_extractf128_si256(vm, 1); + return r; +} + +static INLINE vmask vcast_vm_vi2(vint2 vi) { + vmask m = _mm256_castsi128_si256(vi.x); + m = _mm256_insertf128_si256(m, vi.y, 1); + return m; +} + +static INLINE vint2 vrint_vi2_vf(vfloat vf) { return vcast_vi2_vm((vmask)_mm256_cvtps_epi32(vf)); } +static INLINE vint2 vtruncate_vi2_vf(vfloat vf) { return vcast_vi2_vm((vmask)_mm256_cvttps_epi32(vf)); } +static INLINE vfloat vcast_vf_vi2(vint2 vi) { return _mm256_cvtepi32_ps((vmask)vcast_vm_vi2(vi)); } +static INLINE vint2 vcast_vi2_i(int i) { vint2 r; r.x = r.y = vcast_vi_i(i); return r; } + +static INLINE vint2 vaddi2(vint2 x, vint2 y) { vint2 r; r.x = vaddi(x.x, y.x); r.y = vaddi(x.y, y.y); return r; } +static INLINE vint2 vsubi2(vint2 x, vint2 y) { vint2 r; r.x = vsubi(x.x, y.x); r.y = vsubi(x.y, y.y); return r; } + +static INLINE vint2 vandi2(vint2 x, vint2 y) { vint2 r; r.x = vandi(x.x, y.x); r.y = vandi(x.y, y.y); return r; } +static INLINE vint2 vandnoti2(vint2 x, vint2 y) { vint2 r; r.x = vandnoti(x.x, y.x); r.y = vandnoti(x.y, y.y); return r; } +static INLINE vint2 vori2(vint2 x, vint2 y) { vint2 r; r.x = vori(x.x, y.x); r.y = vori(x.y, y.y); return r; } +static INLINE vint2 vxori2(vint2 x, vint2 y) { vint2 r; r.x = vxori(x.x, y.x); r.y = vxori(x.y, y.y); return r; } + +static INLINE vint2 vslli2(vint2 x, int c) { vint2 r; r.x = vslli(x.x, c); r.y = vslli(x.y, c); return r; } +static INLINE vint2 vsrli2(vint2 x, int c) { vint2 r; r.x = vsrli(x.x, c); r.y = vsrli(x.y, c); return r; } +static INLINE vint2 vsrai2(vint2 x, int c) { vint2 r; r.x = vsrai(x.x, c); r.y = vsrai(x.y, c); return r; } + +static INLINE vmask vmaski2_eq(vint2 x, vint2 y) { + vint2 r; + r.x = _mm_cmpeq_epi32(x.x, y.x); + r.y = _mm_cmpeq_epi32(x.y, y.y); + return vcast_vm_vi2(r); +} + +static INLINE vint2 vseli2(vmask m, vint2 x, vint2 y) { + vint2 r, m2 = vcast_vi2_vm(m); + r.x = vori(vandi(m2.x, x.x), vandnoti(m2.x, y.x)); + r.y = vori(vandi(m2.y, x.y), vandnoti(m2.y, y.y)); + return r; +} + +// + +static INLINE double vcast_d_vd(vdouble v) { + double s[4]; + _mm256_storeu_pd(s, v); + return s[0]; +} + +static INLINE float vcast_f_vf(vfloat v) { + float s[8]; + _mm256_storeu_ps(s, v); + return s[0]; +} + +static INLINE vmask vsignbit(vdouble d) { + return (vmask)_mm256_and_pd(d, _mm256_set_pd(-0.0,-0.0,-0.0,-0.0)); +} + +static INLINE vdouble vsign(vdouble d) { + return _mm256_or_pd(_mm256_set_pd(1.0, 1.0, 1.0, 1.0), (vdouble)vsignbit(d)); +} + +static INLINE vdouble vmulsign(vdouble x, vdouble y) { + return (__m256d)vxorm((__m256i)x, vsignbit(y)); +} + +static INLINE vmask vmask_isinf(vdouble d) { + return (vmask)_mm256_cmp_pd(vabs(d), _mm256_set_pd(INFINITY, INFINITY, INFINITY, INFINITY), _CMP_EQ_OQ); +} + +static INLINE vmask vmask_ispinf(vdouble d) { + return (vmask)_mm256_cmp_pd(d, _mm256_set_pd(INFINITY, INFINITY, INFINITY, INFINITY), _CMP_EQ_OQ); +} + +static INLINE vmask vmask_isminf(vdouble d) { + return (vmask)_mm256_cmp_pd(d, _mm256_set_pd(-INFINITY, -INFINITY, -INFINITY, -INFINITY), _CMP_EQ_OQ); +} + +static INLINE vmask vmask_isnan(vdouble d) { + return (vmask)_mm256_cmp_pd(d, d, _CMP_NEQ_UQ); +} + +static INLINE vdouble visinf(vdouble d) { + return _mm256_and_pd((vdouble)vmask_isinf(d), vsign(d)); +} + +static INLINE vdouble visinf2(vdouble d, vdouble m) { + return _mm256_and_pd((vdouble)vmask_isinf(d), _mm256_or_pd((vdouble)vsignbit(d), m)); +} + +static INLINE vdouble vpow2i(vint q) { + vint r; + vdouble y; + q = _mm_add_epi32(_mm_set_epi32(0x3ff, 0x3ff, 0x3ff, 0x3ff), q); + q = _mm_slli_epi32(q, 20); + r = (__m128i)_mm_shuffle_ps((__m128)q, (__m128)q, _MM_SHUFFLE(1,0,0,0)); + y = _mm256_castpd128_pd256((__m128d)r); + r = (__m128i)_mm_shuffle_ps((__m128)q, (__m128)q, _MM_SHUFFLE(3,2,2,2)); + y = _mm256_insertf128_pd(y, (__m128d)r, 1); + y = _mm256_and_pd(y, (__m256d)_mm256_set_epi32(0xfff00000, 0, 0xfff00000, 0, 0xfff00000, 0, 0xfff00000, 0)); + return y; +} + +static INLINE vdouble vldexp(vdouble x, vint q) { + vint m = _mm_srai_epi32(q, 31); + m = _mm_slli_epi32(_mm_sub_epi32(_mm_srai_epi32(_mm_add_epi32(m, q), 9), m), 7); + q = _mm_sub_epi32(q, _mm_slli_epi32(m, 2)); + vdouble y = vpow2i(m); + return vmul(vmul(vmul(vmul(vmul(x, y), y), y), y), vpow2i(q)); +} + +static INLINE vint vilogbp1(vdouble d) { + vint q, r, c; + vmask m = vmask_lt(d, vcast_vd_d(4.9090934652977266E-91)); + d = vsel(m, vmul(vcast_vd_d(2.037035976334486E90), d), d); + c = _mm256_cvtpd_epi32(vsel(m, vcast_vd_d(300+0x3fe), vcast_vd_d(0x3fe))); + q = (__m128i)_mm256_castpd256_pd128(d); + q = (__m128i)_mm_shuffle_ps((__m128)q, _mm_set_ps(0, 0, 0, 0), _MM_SHUFFLE(0,0,3,1)); + r = (__m128i)_mm256_extractf128_pd(d, 1); + r = (__m128i)_mm_shuffle_ps(_mm_set_ps(0, 0, 0, 0), (__m128)r, _MM_SHUFFLE(3,1,0,0)); + q = _mm_or_si128(q, r); + q = _mm_srli_epi32(q, 20); + q = _mm_sub_epi32(q, c); + return q; +} + +static INLINE vdouble vupper(vdouble d) { + return (__m256d)_mm256_and_pd(d, (vdouble)_mm256_set_epi32(0xffffffff, 0xf8000000, 0xffffffff, 0xf8000000, 0xffffffff, 0xf8000000, 0xffffffff, 0xf8000000)); +} + +// + +typedef struct { + vdouble x, y; +} vdouble2; + +static INLINE vdouble2 dd(vdouble h, vdouble l) { + vdouble2 ret = {h, l}; + return ret; +} + +static INLINE vdouble2 vsel2(vmask mask, vdouble2 x, vdouble2 y) { + return dd((__m256d)vorm(vandm(mask, (__m256i)x.x), vandnotm(mask, (__m256i)y.x)), + (__m256d)vorm(vandm(mask, (__m256i)x.y), vandnotm(mask, (__m256i)y.y))); +} + +static INLINE vdouble2 abs_d(vdouble2 x) { + return dd((__m256d)_mm256_xor_pd(_mm256_and_pd(_mm256_set_pd(-0.0,-0.0,-0.0,-0.0), x.x), x.x), + (__m256d)_mm256_xor_pd(_mm256_and_pd(_mm256_set_pd(-0.0,-0.0,-0.0,-0.0), x.x), x.y)); +} diff --git a/rtengine/helpersse2.h b/rtengine/helpersse2.h new file mode 100644 index 000000000..2d90fcec3 --- /dev/null +++ b/rtengine/helpersse2.h @@ -0,0 +1,286 @@ +#ifndef __SSE2__ +#error Please specify -msse2. +#endif + +#ifdef __GNUC__ +#define INLINE __inline +//#define INLINE __attribute__((always_inline)) +#else +#define INLINE inline +#endif + +#include + +#include + +typedef __m128d vdouble; +typedef __m128i vint; +typedef __m128i vmask; + +typedef __m128 vfloat; +typedef __m128i vint2; + +// +#ifdef __GNUC__ + #if __GNUC__ == 4 && __GNUC_MINOR__ >= 8 + #define LVF(x) _mm_load_ps(&x) + #define LVFU(x) _mm_loadu_ps(&x) + #define STVF(x,y) _mm_store_ps(&x,y) + #else // there is a bug in gcc 4.7.x when using openmp and aligned memory and -O3 + #define LVF(x) _mm_loadu_ps(&x) + #define LVFU(x) _mm_loadu_ps(&x) + #define STVF(x,y) _mm_storeu_ps(&x,y) + #endif +#else + #define LVF(x) _mm_load_ps(&x) + #define LVFU(x) _mm_loadu_ps(&x) + #define STVF(x,y) _mm_store_ps(&x,y) +#endif + +// Load 8 floats from a and combine a[0],a[2],a[4] and a[6] into a vector of 4 floats +#define LC2VFU(a) _mm_shuffle_ps( LVFU(a), _mm_loadu_ps( (&a) + 4 ), _MM_SHUFFLE( 2,0,2,0 ) ) + +// Store a vector of 4 floats in a[0],a[2],a[4] and a[6] +#if defined(__x86_64__) && defined(__SSE4_1__) +// SSE4.1 => use _mm_blend_ps instead of _mm_set_epi32 and vself + #define STC2VFU(a,v) {\ + __m128 TST1V = _mm_loadu_ps(&a);\ + __m128 TST2V = _mm_shuffle_ps(v,v,_MM_SHUFFLE( 1,1,0,0 ));\ + _mm_storeu_ps(&a, _mm_blend_ps(TST1V,TST2V,5));\ + TST1V = _mm_loadu_ps((&a)+4);\ + TST2V = _mm_shuffle_ps(v,v,_MM_SHUFFLE( 3,3,2,2 ));\ + _mm_storeu_ps((&a)+4, _mm_blend_ps(TST1V,TST2V,5));\ + } +#else + #define STC2VFU(a,v) {\ + __m128 TST1V = _mm_loadu_ps(&a);\ + __m128 TST2V = _mm_shuffle_ps(v,v,_MM_SHUFFLE( 1,1,0,0 ));\ + vmask cmask = _mm_set_epi32(0xffffffff,0,0xffffffff,0);\ + _mm_storeu_ps(&a, vself(cmask,TST1V,TST2V));\ + TST1V = _mm_loadu_ps((&a)+4);\ + TST2V = _mm_shuffle_ps(v,v,_MM_SHUFFLE( 3,3,2,2 ));\ + _mm_storeu_ps((&a)+4, vself(cmask,TST1V,TST2V));\ + } +#endif + +#define ZEROV _mm_setzero_ps() +#define F2V(a) _mm_set1_ps((a)) + +static INLINE vint vrint_vi_vd(vdouble vd) { return _mm_cvtpd_epi32(vd); } +static INLINE vint vtruncate_vi_vd(vdouble vd) { return _mm_cvttpd_epi32(vd); } +static INLINE vdouble vcast_vd_vi(vint vi) { return _mm_cvtepi32_pd(vi); } +static INLINE vdouble vcast_vd_d(double d) { return _mm_set_pd(d, d); } +static INLINE vint vcast_vi_i(int i) { return _mm_set_epi32(0, 0, i, i); } + +static INLINE vmask vreinterpret_vm_vd(vdouble vd) { return (__m128i)vd; } +static INLINE vdouble vreinterpret_vd_vm(vint vm) { return (__m128d)vm; } + +static INLINE vmask vreinterpret_vm_vf(vfloat vf) { return (__m128i)vf; } +static INLINE vfloat vreinterpret_vf_vm(vmask vm) { return (__m128)vm; } + +// + +static INLINE vfloat vcast_vf_f(float f) { return _mm_set_ps(f, f, f, f); } + +static INLINE vfloat vaddf(vfloat x, vfloat y) { return _mm_add_ps(x, y); } +static INLINE vfloat vsubf(vfloat x, vfloat y) { return _mm_sub_ps(x, y); } +static INLINE vfloat vmulf(vfloat x, vfloat y) { return _mm_mul_ps(x, y); } +static INLINE vfloat vdivf(vfloat x, vfloat y) { return _mm_div_ps(x, y); } +static INLINE vfloat vrecf(vfloat x) { return vdivf(vcast_vf_f(1.0f), x); } +static INLINE vfloat vsqrtf(vfloat x) { return _mm_sqrt_ps(x); } +static INLINE vfloat vmaxf(vfloat x, vfloat y) { return _mm_max_ps(x, y); } +static INLINE vfloat vminf(vfloat x, vfloat y) { return _mm_min_ps(x, y); } + +// + +static INLINE vdouble vadd(vdouble x, vdouble y) { return _mm_add_pd(x, y); } +static INLINE vdouble vsub(vdouble x, vdouble y) { return _mm_sub_pd(x, y); } +static INLINE vdouble vmul(vdouble x, vdouble y) { return _mm_mul_pd(x, y); } +static INLINE vdouble vdiv(vdouble x, vdouble y) { return _mm_div_pd(x, y); } +static INLINE vdouble vrec(vdouble x) { return _mm_div_pd(_mm_set_pd(1, 1), x); } +static INLINE vdouble vsqrt(vdouble x) { return _mm_sqrt_pd(x); } +static INLINE vdouble vmla(vdouble x, vdouble y, vdouble z) { return vadd(vmul(x, y), z); } + +static INLINE vdouble vmax(vdouble x, vdouble y) { return _mm_max_pd(x, y); } +static INLINE vdouble vmin(vdouble x, vdouble y) { return _mm_min_pd(x, y); } + +static INLINE vdouble vabs(vdouble d) { return (__m128d)_mm_andnot_pd(_mm_set_pd(-0.0,-0.0), d); } +static INLINE vdouble vneg(vdouble d) { return (__m128d)_mm_xor_pd(_mm_set_pd(-0.0,-0.0), d); } + +// + +static INLINE vint vaddi(vint x, vint y) { return _mm_add_epi32(x, y); } +static INLINE vint vsubi(vint x, vint y) { return _mm_sub_epi32(x, y); } + +static INLINE vint vandi(vint x, vint y) { return _mm_and_si128(x, y); } +static INLINE vint vandnoti(vint x, vint y) { return _mm_andnot_si128(x, y); } +static INLINE vint vori(vint x, vint y) { return _mm_or_si128(x, y); } +static INLINE vint vxori(vint x, vint y) { return _mm_xor_si128(x, y); } + +static INLINE vint vslli(vint x, int c) { return _mm_slli_epi32(x, c); } +static INLINE vint vsrli(vint x, int c) { return _mm_srli_epi32(x, c); } +static INLINE vint vsrai(vint x, int c) { return _mm_srai_epi32(x, c); } + +// + +static INLINE vmask vandm(vmask x, vmask y) { return _mm_and_si128(x, y); } +static INLINE vmask vandnotm(vmask x, vmask y) { return _mm_andnot_si128(x, y); } +static INLINE vmask vorm(vmask x, vmask y) { return _mm_or_si128(x, y); } +static INLINE vmask vxorm(vmask x, vmask y) { return _mm_xor_si128(x, y); } +static INLINE vmask vnotm(vmask x) { return _mm_xor_si128(x, _mm_cmpeq_epi32(_mm_setzero_si128(), _mm_setzero_si128())); } + +static INLINE vmask vmask_eq(vdouble x, vdouble y) { return (__m128i)_mm_cmpeq_pd(x, y); } +static INLINE vmask vmask_neq(vdouble x, vdouble y) { return (__m128i)_mm_cmpneq_pd(x, y); } +static INLINE vmask vmask_lt(vdouble x, vdouble y) { return (__m128i)_mm_cmplt_pd(x, y); } +static INLINE vmask vmask_le(vdouble x, vdouble y) { return (__m128i)_mm_cmple_pd(x, y); } +static INLINE vmask vmask_gt(vdouble x, vdouble y) { return (__m128i)_mm_cmpgt_pd(x, y); } +static INLINE vmask vmask_ge(vdouble x, vdouble y) { return (__m128i)_mm_cmpge_pd(x, y); } + +static INLINE vmask vmaskf_eq(vfloat x, vfloat y) { return (__m128i)_mm_cmpeq_ps(x, y); } +static INLINE vmask vmaskf_neq(vfloat x, vfloat y) { return (__m128i)_mm_cmpneq_ps(x, y); } +static INLINE vmask vmaskf_lt(vfloat x, vfloat y) { return (__m128i)_mm_cmplt_ps(x, y); } +static INLINE vmask vmaskf_le(vfloat x, vfloat y) { return (__m128i)_mm_cmple_ps(x, y); } +static INLINE vmask vmaskf_gt(vfloat x, vfloat y) { return (__m128i)_mm_cmpgt_ps(x, y); } +static INLINE vmask vmaskf_ge(vfloat x, vfloat y) { return (__m128i)_mm_cmpge_ps(x, y); } + + +static INLINE vmask vmaski_eq(vint x, vint y) { + __m128 s = (__m128)_mm_cmpeq_epi32(x, y); + return (__m128i)_mm_shuffle_ps(s, s, _MM_SHUFFLE(1, 1, 0, 0)); +} + +static INLINE vdouble vsel(vmask mask, vdouble x, vdouble y) { + return (__m128d)vorm(vandm(mask, (__m128i)x), vandnotm(mask, (__m128i)y)); +} + +static INLINE vint vseli_lt(vdouble d0, vdouble d1, vint x, vint y) { + vmask mask = (vmask)_mm_cmpeq_ps(_mm_cvtpd_ps((vdouble)vmask_lt(d0, d1)), _mm_set_ps(0, 0, 0, 0)); + return vori(vandnoti(mask, x), vandi(mask, y)); +} + +// + +static INLINE vint2 vcast_vi2_vm(vmask vm) { return (vint2)vm; } +static INLINE vmask vcast_vm_vi2(vint2 vi) { return (vmask)vi; } + +static INLINE vint2 vrint_vi2_vf(vfloat vf) { return _mm_cvtps_epi32(vf); } +static INLINE vint2 vtruncate_vi2_vf(vfloat vf) { return _mm_cvttps_epi32(vf); } +static INLINE vfloat vcast_vf_vi2(vint2 vi) { return _mm_cvtepi32_ps(vcast_vm_vi2(vi)); } +static INLINE vint2 vcast_vi2_i(int i) { return _mm_set_epi32(i, i, i, i); } + +static INLINE vint2 vaddi2(vint2 x, vint2 y) { return vaddi(x, y); } +static INLINE vint2 vsubi2(vint2 x, vint2 y) { return vsubi(x, y); } + +static INLINE vint2 vandi2(vint2 x, vint2 y) { return vandi(x, y); } +static INLINE vint2 vandnoti2(vint2 x, vint2 y) { return vandnoti(x, y); } +static INLINE vint2 vori2(vint2 x, vint2 y) { return vori(x, y); } +static INLINE vint2 vxori2(vint2 x, vint2 y) { return vxori(x, y); } + +static INLINE vint2 vslli2(vint2 x, int c) { return vslli(x, c); } +static INLINE vint2 vsrli2(vint2 x, int c) { return vsrli(x, c); } +static INLINE vint2 vsrai2(vint2 x, int c) { return vsrai(x, c); } + +static INLINE vmask vmaski2_eq(vint2 x, vint2 y) { return _mm_cmpeq_epi32(x, y); } +static INLINE vint2 vseli2(vmask m, vint2 x, vint2 y) { return vorm(vandm(m, x), vandnotm(m, y)); } + +// + +static INLINE double vcast_d_vd(vdouble v) { + double s[2]; + _mm_storeu_pd(s, v); + return s[0]; +} + +static INLINE float vcast_f_vf(vfloat v) { + float s[4]; + _mm_storeu_ps(s, v); + return s[0]; +} + +static INLINE vmask vsignbit(vdouble d) { + return _mm_and_si128((__m128i)d, _mm_set_epi32(0x80000000, 0x0, 0x80000000, 0x0)); +} + +static INLINE vdouble vsign(vdouble d) { + return (__m128d)_mm_or_si128((__m128i)_mm_set_pd(1, 1), _mm_and_si128((__m128i)d, _mm_set_epi32(0x80000000, 0x0, 0x80000000, 0x0))); +} + +static INLINE vdouble vmulsign(vdouble x, vdouble y) { + return (__m128d)vxori((__m128i)x, vsignbit(y)); +} + +static INLINE vmask vmask_isinf(vdouble d) { + return (vmask)_mm_cmpeq_pd(vabs(d), _mm_set_pd(INFINITY, INFINITY)); +} + +static INLINE vmask vmask_ispinf(vdouble d) { + return (vmask)_mm_cmpeq_pd(d, _mm_set_pd(INFINITY, INFINITY)); +} + +static INLINE vmask vmask_isminf(vdouble d) { + return (vmask)_mm_cmpeq_pd(d, _mm_set_pd(-INFINITY, -INFINITY)); +} + +static INLINE vmask vmask_isnan(vdouble d) { + return (vmask)_mm_cmpneq_pd(d, d); +} + +static INLINE vdouble visinf(vdouble d) { + return (__m128d)_mm_and_si128(vmask_isinf(d), _mm_or_si128(vsignbit(d), (__m128i)_mm_set_pd(1, 1))); +} + +static INLINE vdouble visinf2(vdouble d, vdouble m) { + return (__m128d)_mm_and_si128(vmask_isinf(d), _mm_or_si128(vsignbit(d), (__m128i)m)); +} + +// + +static INLINE vdouble vpow2i(vint q) { + q = _mm_add_epi32(_mm_set_epi32(0x0, 0x0, 0x3ff, 0x3ff), q); + q = (__m128i)_mm_shuffle_ps((__m128)q, (__m128)q, _MM_SHUFFLE(1,3,0,3)); + return (__m128d)_mm_slli_epi32(q, 20); +} + +static INLINE vdouble vldexp(vdouble x, vint q) { + vint m = _mm_srai_epi32(q, 31); + m = _mm_slli_epi32(_mm_sub_epi32(_mm_srai_epi32(_mm_add_epi32(m, q), 9), m), 7); + q = _mm_sub_epi32(q, _mm_slli_epi32(m, 2)); + vdouble y = vpow2i(m); + return vmul(vmul(vmul(vmul(vmul(x, y), y), y), y), vpow2i(q)); +} + +static INLINE vint vilogbp1(vdouble d) { + vint m = vmask_lt(d, vcast_vd_d(4.9090934652977266E-91)); + d = vsel(m, vmul(vcast_vd_d(2.037035976334486E90), d), d); + __m128i q = _mm_and_si128((__m128i)d, _mm_set_epi32(((1 << 12)-1) << 20, 0, ((1 << 12)-1) << 20, 0)); + q = _mm_srli_epi32(q, 20); + q = vorm(vandm (m, _mm_sub_epi32(q, _mm_set_epi32(300 + 0x3fe, 0, 300 + 0x3fe, 0))), + vandnotm(m, _mm_sub_epi32(q, _mm_set_epi32( 0x3fe, 0, 0x3fe, 0)))); + q = (__m128i)_mm_shuffle_ps((__m128)q, (__m128)q, _MM_SHUFFLE(0,0,3,1)); + return q; +} + +static INLINE vdouble vupper(vdouble d) { + return (__m128d)_mm_and_si128((__m128i)d, _mm_set_epi32(0xffffffff, 0xf8000000, 0xffffffff, 0xf8000000)); +} + +// + +typedef struct { + vdouble x, y; +} vdouble2; + +static INLINE vdouble2 dd(vdouble h, vdouble l) { + vdouble2 ret = {h, l}; + return ret; +} + +static INLINE vdouble2 vsel2(vmask mask, vdouble2 x, vdouble2 y) { + return dd((__m128d)vorm(vandm(mask, (__m128i)x.x), vandnotm(mask, (__m128i)y.x)), + (__m128d)vorm(vandm(mask, (__m128i)x.y), vandnotm(mask, (__m128i)y.y))); +} + +static INLINE vdouble2 abs_d(vdouble2 x) { + return dd((__m128d)_mm_xor_pd(_mm_and_pd(_mm_set_pd(-0.0,-0.0), x.x), x.x), + (__m128d)_mm_xor_pd(_mm_and_pd(_mm_set_pd(-0.0,-0.0), x.x), x.y)); +} diff --git a/rtengine/hilite_recon.cc b/rtengine/hilite_recon.cc new file mode 100644 index 000000000..3ce6c83cb --- /dev/null +++ b/rtengine/hilite_recon.cc @@ -0,0 +1,855 @@ +//////////////////////////////////////////////////////////////// +// +// Highlight reconstruction +// +// copyright (c) 2008-2011 Emil Martinec +// +// +// code dated: June 16, 2011 +// +// hilite_recon.cc is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +//////////////////////////////////////////////////////////////// + +#include +#include +#include "array2D.h" +#include "rawimagesource.h" +#include "rt_math.h" +#include "opthelper.h" + +#ifdef _OPENMP +#include +#endif + + +#define FOREACHCOLOR for (int c=0; c < ColorCount; c++) + +//#include "RGBdefringe.cc" + +namespace rtengine { + + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +SSEFUNCTION void RawImageSource::boxblur2(float** src, float** dst, int H, int W, int box ) +{ + array2D temp(W,H); + + //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 = box + 1; + temp[row][0] = src[row][0]/len; + for (int j=1; j<=box; j++) { + temp[row][0] += src[row][j]/len; + } + for (int col=1; col<=box; col++) { + temp[row][col] = (temp[row][col-1]*len + src[row][col+box])/(len+1); + len ++; + } + for (int col = box+1; col < W-box; col++) { + temp[row][col] = temp[row][col-1] + (src[row][col+box] - src[row][col-box-1])/len; + } + for (int col=W-box; col temp((W/samp)+ ((W%samp)==0 ? 0 : 1),H); + +#ifdef _OPENMP +#pragma omp parallel +#endif +{ + float tempval; +#ifdef _OPENMP +#pragma omp for +#endif + //box blur image channel; box size = 2*box+1 + //horizontal blur + for (int row = 0; row < H; row++) { + int len = box + 1; + tempval = src[row][0]/len; + for (int j=1; j<=box; j++) { + tempval += src[row][j]/len; + } + temp[row][0] = tempval; + for (int col=1; col<=box; col++) { + tempval = (tempval*len + src[row][col+box])/(len+1); + if(col%samp == 0) + temp[row][col/samp] = tempval; + len ++; + } + for (int col = box+1; col < W-box; col++) { + tempval = tempval + (src[row][col+box] - src[row][col-box-1])/len; + if(col%samp == 0) + temp[row][col/samp] = tempval; + } + for (int col=W-box; colsetProgressStr ("HL reconstruction..."); + plistener->setProgress (progress); + } + + int height = H; + int width = W; + + const int range = 2; + const int pitch = 4; + + + int hfh = (height-(height%pitch))/pitch; + int hfw = (width-(width%pitch))/pitch; + + static const int numdirs = 4; + + static const float threshpct = 0.25; + static const float fixthreshpct = 0.7; + static const float maxpct = 0.95; + + //%%%%%%%%%%%%%%%%%%%% + //for blend algorithm: + static const float blendthresh=1.0; + const int ColorCount=3; + // Transform matrixes rgb>lab and back + static const float trans[2][ColorCount][ColorCount] = + { { { 1,1,1 }, { 1.7320508,-1.7320508,0 }, { -1,-1,2 } }, + { { 1,1,1 }, { 1,-1,1 }, { 1,1,-1 } } }; + static const float itrans[2][ColorCount][ColorCount] = + { { { 1,0.8660254,-0.5 }, { 1,-0.8660254,-0.5 }, { 1,0,1 } }, + { { 1,1,1 }, { 1,-1,1 }, { 1,1,-1 } } }; + //%%%%%%%%%%%%%%%%%%%% + + + float max_f[3], thresh[3], fixthresh[3], norm[3]; + + //float red1, green1, blue1;//diagnostic +// float chmaxalt[4]={0,0,0,0};//diagnostic + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + //halfsize demosaic + +/* + multi_array2D hfsize (hfw+1,hfh+1,ARRAY2D_CLEAR_DATA); + + boxblur_resamp(red,hfsize[0],chmaxalt[0],height,width,range,pitch); + if(plistener){ + progress += 0.05; + plistener->setProgress(progress); + } + boxblur_resamp(green,hfsize[1],chmaxalt[1],height,width,range,pitch); + if(plistener){ + progress += 0.05; + plistener->setProgress(progress); + } + boxblur_resamp(blue,hfsize[2],chmaxalt[2],height,width,range,pitch); + if(plistener){ + progress += 0.05; + plistener->setProgress(progress); + } + + //blur image + //for (int m=0; m<3; m++) + // boxblur2(hfsize[m],hfsizeblur[m],hfh,hfw,3); + +*/ + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + for (int c=0; c<3; c++) { + thresh[c] = chmax[c]*threshpct; + fixthresh[c] = chmax[c]*fixthreshpct; + max_f[c] = chmax[c]*maxpct;//min(chmax[0],chmax[1],chmax[2])*maxpct; + norm[c] = 1.0/(max_f[c]-fixthresh[c]); + } + float whitept = max(max_f[0],max_f[1],max_f[2]); + float clippt = min(max_f[0],max_f[1],max_f[2]); + float medpt = max_f[0]+max_f[1]+max_f[2]-whitept-clippt; + float blendpt = blendthresh*clippt; + + float camwb[4]; + for (int c=0; c<4; c++) camwb[c]=ri->get_cam_mul(c); + + multi_array2D channelblur(width,height,ARRAY2D_CLEAR_DATA); + multi_array2D hilite_full(width,height,ARRAY2D_CLEAR_DATA); + if(plistener){ + progress += 0.05; + plistener->setProgress(progress); + } + + // blur RGB channels + boxblur2(red ,channelblur[0],height,width,4); + if(plistener){ + progress += 0.05; + plistener->setProgress(progress); + } + boxblur2(green,channelblur[1],height,width,4); + if(plistener){ + progress += 0.05; + plistener->setProgress(progress); + } + boxblur2(blue ,channelblur[2],height,width,4); + if(plistener){ + progress += 0.05; + plistener->setProgress(progress); + } + + float hipass_sum=0, hipass_norm=0.00; + + // set up which pixels are clipped or near clipping +#ifdef _OPENMP +#pragma omp parallel for reduction(+:hipass_sum,hipass_norm) schedule(dynamic,16) +#endif + for (int i=0; ithresh[0] || green[i][j]>thresh[1] || blue[i][j]>thresh[2]) && + (red[i][j]setProgress(progress); + } + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + //blur highlight data + boxblur2(hilite_full[4],hilite_full[4],height,width,1); + if(plistener){ + progress += 0.05; + plistener->setProgress(progress); + } + +#ifdef _OPENMP +#pragma omp parallel for schedule(dynamic,16) +#endif + for (int i=0; i 2*hipass_ave) { + //too much variation + hilite_full[0][i][j] = hilite_full[1][i][j] = hilite_full[2][i][j] = hilite_full[3][i][j] = 0; + continue; + } + + if (hilite_full[4][i][j]>0.00001 && hilite_full[4][i][j]<0.95) { + //too near an edge, could risk using CA affected pixels, therefore omit + hilite_full[0][i][j] = hilite_full[1][i][j] = hilite_full[2][i][j] = hilite_full[3][i][j] = 0; + } + } + } + + for (int c=0; c<3; c++) channelblur[c](1,1);//free up some memory + + multi_array2D hilite(hfw+1,hfh+1,ARRAY2D_CLEAR_DATA); + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // blur and resample highlight data; range=size of blur, pitch=sample spacing + for (int m=0; m<4; m++) { + boxblur_resamp(hilite_full[m],hilite[m],height,width,range,pitch); + if(plistener){ + progress += 0.05; + plistener->setProgress(progress); + } + } + for (int c=0; c<5; c++) hilite_full[c](1,1);//free up some memory + + multi_array2D hilite_dir(hfw,hfh,ARRAY2D_CLEAR_DATA); + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + //blur highlights + //for (int m=0; m<4; m++) + // boxblur2(hilite[m],hilite[m],hfh,hfw,4); + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + if(plistener){ + progress += 0.05; + plistener->setProgress(progress); + } + + LUTf invfn(0x10000); + + for (int i=0; i<0x10000; i++) + invfn[i] = 1.0/(1.0+i); + + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + //fill gaps in highlight map by directional extension + //raster scan from four corners + for (int j=1; j0.01) { + for (int c=0; c<4; c++) { + hilite_dir[c][i][j] = hilite[c][i][j]/hilite[3][i][j]; + } + } else { + for (int c=0; c<4; c++) { + hilite_dir[c][i][j] = 0.1*((hilite_dir[0+c][i-2][j-1]+hilite_dir[0+c][i-1][j-1]+hilite_dir[0+c][i][j-1]+hilite_dir[0+c][i+1][j-1]+hilite_dir[0+c][i+2][j-1])/ + (hilite_dir[0+3][i-2][j-1]+hilite_dir[0+3][i-1][j-1]+hilite_dir[0+3][i][j-1]+hilite_dir[0+3][i+1][j-1]+hilite_dir[0+3][i+2][j-1]+0.00001)); + hilite_dir[4+c][i][j+1] += hilite_dir[c][i][j]; + hilite_dir[8+c][i-2][j] += hilite_dir[c][i][j]; + hilite_dir[12+c][i+2][j] += hilite_dir[c][i][j]; + } + } + } + if(plistener){ + progress += 0.05; + plistener->setProgress(progress); + } + + for (int j=hfw-2; j>0; j--) + for (int i=2; i0.01) { + for (int c=0; c<4; c++) { + hilite_dir[4+c][i][j] = hilite[c][i][j]/hilite[3][i][j]; + } + } else { + for (int c=0; c<4; c++) { + hilite_dir[4+c][i][j] = 0.1*((hilite_dir[4+c][(i-2)][(j+1)]+hilite_dir[4+c][(i-1)][(j+1)]+hilite_dir[4+c][(i)][(j+1)]+hilite_dir[4+c][(i+1)][(j+1)]+hilite_dir[4+c][(i+2)][(j+1)])/ + (hilite_dir[4+3][(i-2)][(j+1)]+hilite_dir[4+3][(i-1)][(j+1)]+hilite_dir[4+3][(i)][(j+1)]+hilite_dir[4+3][(i+1)][(j+1)]+hilite_dir[4+3][(i+2)][(j+1)]+0.00001)); + hilite_dir[8+c][i-2][j] += hilite_dir[4+c][i][j]; + hilite_dir[12+c][i+2][j] += hilite_dir[4+c][i][j]; + } + } + } + + if(plistener){ + progress += 0.05; + plistener->setProgress(progress); + } + + for (int i=1; i0.01) { + for (int c=0; c<4; c++) { + hilite_dir[8+c][i][j] = hilite[c][i][j]/hilite[3][i][j]; + } + } else { + for (int c=0; c<4; c++) { + hilite_dir[8+c][i][j] = 0.1*((hilite_dir[8+c][i-1][j-2]+hilite_dir[8+c][i-1][j-1]+hilite_dir[8+c][i-1][j]+hilite_dir[8+c][i-1][j+1]+hilite_dir[8+c][i-1][j+2])/ + (hilite_dir[8+3][i-1][j-2]+hilite_dir[8+3][i-1][j-1]+hilite_dir[8+3][i-1][j]+hilite_dir[8+3][i-1][j+1]+hilite_dir[8+3][i-1][j+2]+0.00001)); + hilite_dir[12+c][i+1][j] += hilite_dir[8+c][i][j]; + } + } + } + + if(plistener){ + progress += 0.05; + plistener->setProgress(progress); + } + + for (int i=hfh-2; i>0; i--) + for (int j=2; j0.01) { + for (int c=0; c<4; c++) { + hilite_dir[12+c][i][j] = hilite[c][i][j]/hilite[3][i][j]; + } + } else { + for (int c=0; c<4; c++) { + hilite_dir[12+c][i][j] = 0.1*((hilite_dir[12+c][(i+1)][(j-2)]+hilite_dir[12+c][(i+1)][(j-1)]+hilite_dir[12+c][(i+1)][(j)]+hilite_dir[12+c][(i+1)][(j+1)]+hilite_dir[12+c][(i+1)][(j+2)])/ + (hilite_dir[12+3][(i+1)][(j-2)]+hilite_dir[12+3][(i+1)][(j-1)]+hilite_dir[12+3][(i+1)][(j)]+hilite_dir[12+3][(i+1)][(j+1)]+hilite_dir[12+3][(i+1)][(j+2)]+0.00001)); + } + } + + } + + if(plistener){ + progress += 0.05; + plistener->setProgress(progress); + } + + //fill in edges + for (int dir=0; dirsetProgress(progress); + } + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + /*for (int m=0; m<4*numdirs; m++) { + boxblur2(hilite_dir[m],hilite_dir[m],hfh,hfw,4); + }*/ + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + //now we have highlight data extended in various directions + //next step is to build back local data by averaging + + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // now reconstruct clipped channels using color ratios + + //const float Yclip = 0.3333*(max[0] + max[1] + max[2]); + //float sumwt=0, counts=0; + +#ifdef _OPENMP +#pragma omp parallel for schedule(dynamic,16) +#endif + for (int i=0; i blendpt) rgb_blend[0]= rfrac*rgb[0]+(1-rfrac)*pixel[0]; + if (pixel[1] > blendpt) rgb_blend[1]= gfrac*rgb[1]+(1-gfrac)*pixel[1]; + if (pixel[2] > blendpt) rgb_blend[2]= bfrac*rgb[2]+(1-bfrac)*pixel[2]; + + //end of HLRecovery_blend estimation + //%%%%%%%%%%%%%%%%%%%%%%% + + //float pixref[3]={min(Yclip,hfsize[0][i1][j1]),min(Yclip,hfsize[1][i1][j1]),min(Yclip,hfsize[2][i1][j1])}; + + //there are clipped highlights + //first, determine weighted average of unclipped extensions (weighting is by 'hue' proximity) + float dirwt, factor, Y; + float totwt=0;//0.0003; + float clipfix[3]={0,0,0};//={totwt*rgb_blend[0],totwt*rgb_blend[1],totwt*rgb_blend[2]}; + for (int dir=0; dir0.5) { + dirwt = invfn[65535*(SQR(rgb_blend[0]/Y-hilite_dir[dir*4+0][i1][j1]/Yhi) + + SQR(rgb_blend[1]/Y-hilite_dir[dir*4+1][i1][j1]/Yhi) + + SQR(rgb_blend[2]/Y-hilite_dir[dir*4+2][i1][j1]/Yhi))]; + totwt += dirwt; + clipfix[0] += dirwt*hilite_dir[dir*4+0][i1][j1]/(hilite_dir[dir*4+3][i1][j1]+0.00001); + clipfix[1] += dirwt*hilite_dir[dir*4+1][i1][j1]/(hilite_dir[dir*4+3][i1][j1]+0.00001); + clipfix[2] += dirwt*hilite_dir[dir*4+2][i1][j1]/(hilite_dir[dir*4+3][i1][j1]+0.00001); + } + } + + if(totwt == 0.f) + continue; + + clipfix[0] /= totwt; + clipfix[1] /= totwt; + clipfix[2] /= totwt; + //sumwt += totwt; + //counts ++; + + //now correct clipped channels + if (pixel[0]>max_f[0] && pixel[1]>max_f[1] && pixel[2]>max_f[2]) { + //all channels clipped + float Y = (0.299*clipfix[0] + 0.587*clipfix[1] + 0.114*clipfix[2]); + //float Y = (clipfix[0] + clipfix[1] + clipfix[2]); + factor = whitept/Y; + red[i][j] = clipfix[0]*factor; + green[i][j] = clipfix[1]*factor; + blue[i][j] = clipfix[2]*factor; + } else {//some channels clipped + int notclipped[3] = {pixel[0]0.01) { + red[i][j] = (red[i][j] + hilite[0][i1][j1])/(1+hilite[3][i1][j1]); + green[i][j] = (green[i][j]+ hilite[1][i1][j1])/(1+hilite[3][i1][j1]); + blue[i][j] = (blue[i][j] + hilite[2][i1][j1])/(1+hilite[3][i1][j1]); + }*/ + + Y = (0.299 * red[i][j] + 0.587 * green[i][j] + 0.114 * blue[i][j]); + + if (Y>whitept) { + factor = whitept/Y; + + /*I = (0.596 * red[i][j] - 0.275 * green[i][j] - 0.321 * blue[i][j]); + Q = (0.212 * red[i][j] - 0.523 * green[i][j] + 0.311 * blue[i][j]); + + Y *= factor; + I *= factor;//max(0,min(1,(whitept-Y)/(whitept-clippt))); + Q *= factor;//max(0,min(1,(whitept-Y)/(whitept-clippt))); + + red[i][j] = Y + 0.956*I + 0.621*Q; + green[i][j] = Y - 0.272*I - 0.647*Q; + blue[i][j] = Y - 1.105*I + 1.702*Q;*/ + + red[i][j] *= factor; + green[i][j] *= factor; + blue[i][j] *= factor; + } + } + } + + if(plistener) plistener->setProgress(1.00); + //printf("ave wt=%f\n",sumwt/counts); + + + // diagnostic output + /*for (int i=0; i + * + * 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 "rawimagesource.h" +#include "rawimagesource_i.h" +#include "../rtgui/options.h" + +namespace rtengine { + +// computes highlight recovery multipliers. Needs a possibly downscaled image where +// the highlights are indicated by INT_MAX +void hlmultipliers (int** rec[3], int max_3[3], int dh, int dw) { + + // STEP I. recover color with two-color information + int phase = -1; + int k=0; + for (k=0; k<1000; k++) { + int changed = 0; + for (int i=1; i0)// && phase!=4) +// continue; + if (phase==-1 || phase==0 || phase==2) { + if (rec[0][i][j] == INT_MAX && rec[1][i][j] != INT_MAX && rec[1][i][j] >=0 && rec[2][i][j] != INT_MAX && rec[2][i][j] >=0) { + co = 0; + c1 = 1; + c2 = 2; + } + else if (rec[1][i][j] == INT_MAX && rec[0][i][j] != INT_MAX && rec[0][i][j] >=0 && rec[2][i][j] != INT_MAX && rec[2][i][j] >=0) { + co = 1; + c1 = 0; + c2 = 2; + } + else if (rec[2][i][j] == INT_MAX && rec[1][i][j] != INT_MAX && rec[1][i][j] >=0 && rec[0][i][j] != INT_MAX && rec[0][i][j] >=0) { + co = 2; + c1 = 1; + c2 = 0; + } + else + continue; + + double ratio[2] = {0.0, 0.0}; + int count = 0; + double rato = (double)rec[c1][i][j] / rec[c2][i][j]; + double arato = 0.0; + if (phase==2) { + for (int x=-1; x<=1; x++) + for (int y=-1; y<=1; y++) { + // average m/c color ratios in the surrounding pixels + if (rec[co][i+x][j+y]>=0 && rec[co][i+x][j+y]!=INT_MAX && rec[c1][i+x][j+y]>=0 && rec[c1][i+x][j+y]!=INT_MAX && rec[c2][i+x][j+y]>0 && rec[c2][i+x][j+y]!=INT_MAX) { + double ratt = (double)rec[c1][i+x][j+y] / rec[c2][i+x][j+y]; + if (ratt > rato*1.2 || ratt < rato / 1.2 || rec[co][i+x][j+y]=0 && rec[co][i+x][j+y]!=INT_MAX && rec[c1][i+x][j+y]>=0 && rec[c1][i+x][j+y]!=INT_MAX && rec[c2][i+x][j+y]>0 && rec[c2][i+x][j+y]!=INT_MAX) { + double ratt = (double)rec[c1][i+x][j+y] / rec[c2][i+x][j+y]; + if (ratt > rato*1.05 || ratt < rato / 1.05 || rec[co][i+x][j+y]=0 && rec[co][i+x][j+y]!=INT_MAX && rec[c1][i+x][j+y]>=0 && rec[c1][i+x][j+y]!=INT_MAX && rec[c2][i+x][j+y]>0 && rec[c2][i+x][j+y]!=INT_MAX) { + double ratt = (double)rec[c1][i+x][j+y] / rec[c2][i+x][j+y]; + if (ratt > rato*1.1 || ratt < rato / 1.1 || rec[co][i+x][j+y]1) { //(phase==0 && count>1) || (phase==2 && count>1)) { + rec[co][i][j] = -(int)((rec[c1][i][j] / ratio[0] * count + rec[c2][i][j] / ratio[1] * count) / 2); + changed++; + } + } + else if (phase==1 || phase==3) { + if (rec[0][i][j] == INT_MAX && rec[1][i][j] == INT_MAX && rec[2][i][j] != INT_MAX && rec[2][i][j] >=0) { + co = 2; + c1 = 0; + c2 = 1; + } + else if (rec[0][i][j] == INT_MAX && rec[2][i][j] == INT_MAX && rec[1][i][j] != INT_MAX && rec[1][i][j] >=0) { + co = 1; + c1 = 0; + c2 = 2; + } + else if (rec[1][i][j] == INT_MAX && rec[2][i][j] == INT_MAX && rec[0][i][j] != INT_MAX && rec[0][i][j] >=0) { + co = 0; + c1 = 1; + c2 = 2; + } + else + continue; + + double ratio[2] = {0.0, 0.0}; + int count[2] = {0, 0}; + for (int x=-1; x<=1; x++) + for (int y=-1; y<=1; y++) { + // average m/c color ratios in the surrounding pixels + if (rec[co][i+x][j+y]>=0 && rec[co][i+x][j+y]!=INT_MAX && rec[c1][i+x][j+y]>0 && rec[c1][i+x][j+y]!=INT_MAX) { + if ((phase==1 && rec[c1][i+x][j+y]=0 && rec[co][i+x][j+y]!=INT_MAX && rec[c2][i+x][j+y]>0 && rec[c2][i+x][j+y]!=INT_MAX) { + if ((phase==1 && rec[c2][i+x][j+y]2) || (phase==3 && count[0]>1)) { + rec[c1][i][j] = - (int) ((double)rec[co][i][j] / ratio[0] * count[0]); + changed++; + } + if ((phase==1 && count[1]>2) || (phase==3 && count[1]>1)) { + rec[c2][i][j] = - (int) ((double)rec[co][i][j] / ratio[1] * count[1]); + changed++; + } + } + else { + int val = 0; + int num = 0; + for (int c=0; c<3; c++) + if (rec[c][i][j]!=INT_MAX) { + val += rec[c][i][j]; + num++; + } + if (num<3 && num>0) { + for (int c=0; c<3; c++) + rec[c][i][j] = val / num; + } + } + } + + + bool change = false; + for (int i=1; i=H/HR_SCALE-2) + return; + double mr1 = 1.0 - ((double)((i+HR_SCALE/2) % HR_SCALE) / HR_SCALE + 0.5 / HR_SCALE); + int maxcol = W/HR_SCALE-2; + for (int j=sx1, jx=0; jx=maxcol) + continue; + double mc1 = 1.0 - ((double)((j+HR_SCALE/2) % HR_SCALE) / HR_SCALE + 0.5 / HR_SCALE); + double mulr = mr1*mc1 * hrmap[0][blr][blc] + mr1*(1.0-mc1) * hrmap[0][blr][blc+1] + (1.0-mr1)*mc1 * hrmap[0][blr+1][blc] + (1.0-mr1)*(1.0-mc1) * hrmap[0][blr+1][blc+1]; + double mulg = mr1*mc1 * hrmap[1][blr][blc] + mr1*(1.0-mc1) * hrmap[1][blr][blc+1] + (1.0-mr1)*mc1 * hrmap[1][blr+1][blc] + (1.0-mr1)*(1.0-mc1) * hrmap[1][blr+1][blc+1]; + double mulb = mr1*mc1 * hrmap[2][blr][blc] + mr1*(1.0-mc1) * hrmap[2][blr][blc+1] + (1.0-mr1)*mc1 * hrmap[2][blr+1][blc] + (1.0-mr1)*(1.0-mc1) * hrmap[2][blr+1][blc+1]; + red[jx] = (red[jx] * mulr); + green[jx] = (green[jx] * mulg); + blue[jx] = (blue[jx] * mulb); + } else { + red[jx] = (red[jx]); + green[jx] = (green[jx]); + blue[jx] = (blue[jx]); + } + } +} + +void RawImageSource::updateHLRecoveryMap_ColorPropagation () { + + // detect maximal pixel values + float* red = new float[W]; + float* blue = new float[W]; + int maxr = 0, maxg = 0, maxb = 0; + for (int i=32; iISRED(i,j) || ri->getSensorType()!=ST_BAYER) && red[j] > maxr) maxr = red[j]; + if ((ri->ISGREEN(i,j) || ri->getSensorType()!=ST_BAYER) && green[i][j] > maxg) maxg = green[i][j]; + if ((ri->ISBLUE(i,j) || ri->getSensorType()!=ST_BAYER) && blue[j] > maxb) maxb = blue[j]; + } + } + delete [] red; + delete [] blue; + + maxr = maxr * 19 / 20; + maxg = maxg * 19 / 20; + maxb = maxb * 19 / 20; + max_3[0] = maxr; + max_3[1] = maxg; + max_3[2] = maxb; + + // downscale image + int dw = W/HR_SCALE; + int dh = H/HR_SCALE; + Image16* ds = new Image16 (dw, dh); + + // overburnt areas + int** rec[3]; + for (int i=0; i<3; i++) + rec[i] = allocArray (dw, dh); + + float* reds[HR_SCALE]; + float* blues[HR_SCALE]; + for (int i=0; i(needhr, H); + needhr = allocArray (W, H); + + for (int i=0; i=max_3[0] || green[HR_SCALE*i+j][k]>=max_3[1] || blues[j][k]>=max_3[2]) + needhr[HR_SCALE*i+j][k] = 1; + else + needhr[HR_SCALE*i+j][k] = 0; + } + for (int j=0; jr(i,j) = sumr / HR_SCALE/HR_SCALE; + ds->g(i,j) = sumg / HR_SCALE/HR_SCALE; + ds->b(i,j) = sumb / HR_SCALE/HR_SCALE; + } + } + for (int i=0; i (hrmap[0], dh); + freeArray (hrmap[1], dh); + freeArray (hrmap[2], dh); + } + + hrmap[0] = allocArray (dw, dh); + hrmap[1] = allocArray (dw, dh); + hrmap[2] = allocArray (dw, dh); + + for (int i=0; ir(i,j)>0 ? (double)rec[0][i][j] / ds->r(i,j) : 1.0; + hrmap[1][i][j] = ds->g(i,j)>0 ? (double)rec[1][i][j] / ds->g(i,j) : 1.0; + hrmap[2][i][j] = ds->b(i,j)>0 ? (double)rec[2][i][j] / ds->b(i,j) : 1.0; + } + + delete ds; + + freeArray (rec[0], dh); + freeArray (rec[1], dh); + freeArray (rec[2], dh); +} + +} + diff --git a/rtengine/hlrecovery.cc b/rtengine/hlrecovery.cc new file mode 100644 index 000000000..430466e53 --- /dev/null +++ b/rtengine/hlrecovery.cc @@ -0,0 +1,287 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ + +namespace rtengine { + +template T** allocArray (int W, int H) { + + T** t = new T*[H]; + for (int i=0; i maxr) maxr = red[j]; + if (green[i][j] > maxg) maxg = green[i][j]; + if (blue[j] > maxb) maxb = blue[j]; + } + } + delete [] red; + delete [] blue; + + maxr = maxr * 19 / 20; + maxg = maxg * 19 / 20; + maxb = maxb * 19 / 20; + int max[3]; + max[0] = maxr; + max[1] = maxg; + max[2] = maxb; + if( options.rtSettings.verbose ) + printf ("HLRecoveryMap Maximum: R: %d, G: %d, B: %d\n", maxr, maxg, maxb); + + // downscale image + int dw = W/SCALE; + int dh = H/SCALE; + Image16* ds = new Image16 (dw, dh); + + // overburnt areas + int** rec[3]; + for (int i=0; i<3; i++) + rec[i] = allocArray (dw, dh); + + unsigned short* reds[SCALE]; + unsigned short* blues[SCALE]; + for (int i=0; ir(i,j) = sumr / SCALE/SCALE; + ds->g(i,j) = sumg / SCALE/SCALE; + ds->b(i,j) = sumb / SCALE/SCALE; + } + } + for (int i=0; i200) + phase2 = true; + for (int i=1; i=0) { + for (int x=-1; x<=1; x++) + for (int y=-1; y<=1; y++) + // average m/c color ratios in the surrounding pixels + if (rec[m][i+x][j+y]>=0 && rec[m][i+x][j+y]!=INT_MAX && rec[c][i+x][j+y]>0 && rec[c][i+x][j+y]!=INT_MAX) { + double ww = 1.0; + if (!phase2 && (/*(double)(rec[m][i+x][j+y] - rec[m][i][j])/max[m]*(rec[m][i+x][j+y] - rec[m][i][j])/max[m] > 1.0/2 || */rec[c][i+x][j+y]200) + phase2 = true; + for (int i=1; i0 && rec[0][i+x][j+y]!=INT_MAX && rec[1][i+x][j+y]>0 && rec[1][i+x][j+y]!=INT_MAX && rec[2][i+x][j+y]>0 && rec[2][i+x][j+y]!=INT_MAX) { + // convert to yiq + double Y = 0.299 * rec[0][i+x][j+y] + 0.587 * rec[1][i+x][j+y] + 0.114 * rec[2][i+x][j+y]; + double I = 0.596 * rec[0][i+x][j+y] - 0.275 * rec[1][i+x][j+y] - 0.321 * rec[2][i+x][j+y]; + double Q = 0.212 * rec[0][i+x][j+y] - 0.523 * rec[1][i+x][j+y] + 0.311 * rec[2][i+x][j+y]; + if (Y > maxY*7/10) { + double w = 1.0;// / (I*I+Q*Q); + yavg += Y*w; + iavg += I*w; + qavg += Q*w; + weight += w; + count++; + } + } + if ((!phase2 && count>5) || (phase2 && count>3)) { + double Y = yavg / weight; + double I = iavg / weight; + double Q = qavg / weight; + rec[0][i][j] = - (Y + 0.956*I + 0.621*Q); + rec[1][i][j] = - (Y - 0.272*I - 0.647*Q); + rec[2][i][j] = - (Y - 1.105*I + 1.702*Q); + } + } + + } + bool change = false; + for (int i=0; imaxval) + maxval = rec[c][i][j]; + + for (int i=0; i (hrmap[0], dh); + freeArray (hrmap[1], dh); + freeArray (hrmap[2], dh); + } + hrmap[0] = allocArray (dw, dh); + hrmap[1] = allocArray (dw, dh); + hrmap[2] = allocArray (dw, dh); + + this->full = full; + + for (int i=0; ir(i,j); + hrmap[1][i][j] = (double)rec[1][i][j] / ds->g(i,j); + hrmap[2][i][j] = (double)rec[2][i][j] / ds->b(i,j); + } + +/* for (int i=0; ir(i,j) = CLIP (rec[0][i][j]); + ds->g(i,j) = CLIP (rec[1][i][j]); + ds->b(i,j) = CLIP (rec[2][i][j]); + } + ds->save ("test.png"); +*/ + delete ds; + freeArray (rec[0], dh); + freeArray (rec[1], dh); + freeArray (rec[2], dh); + + printf ("HLMap vege\n"); +} + +void RawImageSource::hlRecovery (unsigned short* red, unsigned short* green, unsigned short* blue, int i, int sx1, int sx2, int skip) { + + int blr = (i+SCALE/2) / SCALE - 1; + if (blr<0 || blr>=H/SCALE-1) + return; + double mr1 = 1.0 - ((double)((i+SCALE/2) % SCALE) / SCALE + 0.5 / SCALE); + int jx = 0; + int maxcol = W/SCALE; + for (int j=sx1, jx=0; j=maxcol-1) + continue; + double mc1 = 1.0 - ((double)((j+SCALE/2) % SCALE) / SCALE + 0.5 / SCALE); + double mulr = mr1*mc1 * hrmap[0][blr][blc] + mr1*(1.0-mc1) * hrmap[0][blr][blc+1] + (1.0-mr1)*mc1 * hrmap[0][blr+1][blc] + (1.0-mr1)*(1.0-mc1) * hrmap[0][blr+1][blc+1]; + double mulg = mr1*mc1 * hrmap[1][blr][blc] + mr1*(1.0-mc1) * hrmap[1][blr][blc+1] + (1.0-mr1)*mc1 * hrmap[1][blr+1][blc] + (1.0-mr1)*(1.0-mc1) * hrmap[1][blr+1][blc+1]; + double mulb = mr1*mc1 * hrmap[2][blr][blc] + mr1*(1.0-mc1) * hrmap[2][blr][blc+1] + (1.0-mr1)*mc1 * hrmap[2][blr+1][blc] + (1.0-mr1)*(1.0-mc1) * hrmap[2][blr+1][blc+1]; + red[jx] = CLIP(red[jx] * mulr); + green[jx] = CLIP(green[jx] * mulg); + blue[jx] = CLIP(blue[jx] * mulb); + } +} +} + diff --git a/rtengine/iccjpeg.cc b/rtengine/iccjpeg.cc new file mode 100644 index 000000000..7500d27ec --- /dev/null +++ b/rtengine/iccjpeg.cc @@ -0,0 +1,244 @@ +/* + * iccprofile.c + * + * This file provides code to read and write International Color Consortium + * (ICC) device profiles embedded in JFIF JPEG image files. The ICC has + * defined a standard format for including such data in JPEG "APP2" markers. + * The code given here does not know anything about the internal structure + * of the ICC profile data; it just knows how to put the profile data into + * a JPEG file being written, or get it back out when reading. + * + * This code depends on new features added to the IJG JPEG library as of + * IJG release 6b; it will not compile or work with older IJG versions. + * + * NOTE: this code would need surgery to work on 16-bit-int machines + * with ICC profiles exceeding 64K bytes in size. If you need to do that, + * change all the "unsigned int" variables to "INT32". You'll also need + * to find a malloc() replacement that can allocate more than 64K. + */ + +#include "iccjpeg.h" +#include /* define malloc() */ + + +/* + * Since an ICC profile can be larger than the maximum size of a JPEG marker + * (64K), we need provisions to split it into multiple markers. The format + * defined by the ICC specifies one or more APP2 markers containing the + * following data: + * Identifying string ASCII "ICC_PROFILE\0" (12 bytes) + * Marker sequence number 1 for first APP2, 2 for next, etc (1 byte) + * Number of markers Total number of APP2's used (1 byte) + * Profile data (remainder of APP2 data) + * Decoders should use the marker sequence numbers to reassemble the profile, + * rather than assuming that the APP2 markers appear in the correct sequence. + */ + +#define ICC_MARKER (JPEG_APP0 + 2) /* JPEG marker code for ICC */ +#define ICC_OVERHEAD_LEN 14 /* size of non-profile data in APP2 */ +#define MAX_BYTES_IN_MARKER 65533 /* maximum data len of a JPEG marker */ +#define MAX_DATA_BYTES_IN_MARKER (MAX_BYTES_IN_MARKER - ICC_OVERHEAD_LEN) + + +/* + * This routine writes the given ICC profile data into a JPEG file. + * It *must* be called AFTER calling jpeg_start_compress() and BEFORE + * the first call to jpeg_write_scanlines(). + * (This ordering ensures that the APP2 marker(s) will appear after the + * SOI and JFIF or Adobe markers, but before all else.) + */ + +void +write_icc_profile (j_compress_ptr cinfo, + const JOCTET *icc_data_ptr, + unsigned int icc_data_len) +{ + unsigned int num_markers; /* total number of markers we'll write */ + int cur_marker = 1; /* per spec, counting starts at 1 */ + unsigned int length; /* number of bytes to write in this marker */ + + /* Calculate the number of markers we'll need, rounding up of course */ + num_markers = icc_data_len / MAX_DATA_BYTES_IN_MARKER; + if (num_markers * MAX_DATA_BYTES_IN_MARKER != icc_data_len) + num_markers++; + + while (icc_data_len > 0) { + /* length of profile to put in this marker */ + length = icc_data_len; + if (length > MAX_DATA_BYTES_IN_MARKER) + length = MAX_DATA_BYTES_IN_MARKER; + icc_data_len -= length; + + /* Write the JPEG marker header (APP2 code and marker length) */ + jpeg_write_m_header(cinfo, ICC_MARKER, (unsigned int) (length + ICC_OVERHEAD_LEN)); + + /* Write the marker identifying string "ICC_PROFILE" (null-terminated). + * We code it in this less-than-transparent way so that the code works + * even if the local character set is not ASCII. + */ + jpeg_write_m_byte(cinfo, 0x49); + jpeg_write_m_byte(cinfo, 0x43); + jpeg_write_m_byte(cinfo, 0x43); + jpeg_write_m_byte(cinfo, 0x5F); + jpeg_write_m_byte(cinfo, 0x50); + jpeg_write_m_byte(cinfo, 0x52); + jpeg_write_m_byte(cinfo, 0x4F); + jpeg_write_m_byte(cinfo, 0x46); + jpeg_write_m_byte(cinfo, 0x49); + jpeg_write_m_byte(cinfo, 0x4C); + jpeg_write_m_byte(cinfo, 0x45); + jpeg_write_m_byte(cinfo, 0x0); + + /* Add the sequencing info */ + jpeg_write_m_byte(cinfo, cur_marker); + jpeg_write_m_byte(cinfo, (int) num_markers); + + /* Add the profile data */ + while (length--) { + jpeg_write_m_byte(cinfo, *icc_data_ptr); + icc_data_ptr++; + } + cur_marker++; + } +} + + +/* + * Prepare for reading an ICC profile + */ + +void +setup_read_icc_profile (j_decompress_ptr cinfo) +{ + /* Tell the library to keep any APP2 data it may find */ + jpeg_save_markers(cinfo, ICC_MARKER, 0xFFFF); +} + + +/* + * Handy subroutine to test whether a saved marker is an ICC profile marker. + */ +static boolean +marker_is_icc (jpeg_saved_marker_ptr marker) +{ + return + marker->marker == ICC_MARKER && + marker->data_length >= ICC_OVERHEAD_LEN && + /* verify the identifying string */ + GETJOCTET(marker->data[0]) == 0x49 && + GETJOCTET(marker->data[1]) == 0x43 && + GETJOCTET(marker->data[2]) == 0x43 && + GETJOCTET(marker->data[3]) == 0x5F && + GETJOCTET(marker->data[4]) == 0x50 && + GETJOCTET(marker->data[5]) == 0x52 && + GETJOCTET(marker->data[6]) == 0x4F && + GETJOCTET(marker->data[7]) == 0x46 && + GETJOCTET(marker->data[8]) == 0x49 && + GETJOCTET(marker->data[9]) == 0x4C && + GETJOCTET(marker->data[10]) == 0x45 && + GETJOCTET(marker->data[11]) == 0x0; +} + + +/* + * See if there was an ICC profile in the JPEG file being read; + * if so, reassemble and return the profile data. + * + * TRUE is returned if an ICC profile was found, FALSE if not. + * If TRUE is returned, *icc_data_ptr is set to point to the + * returned data, and *icc_data_len is set to its length. + * + * IMPORTANT: the data at **icc_data_ptr has been allocated with malloc() + * and must be freed by the caller with free() when the caller no longer + * needs it. (Alternatively, we could write this routine to use the + * IJG library's memory allocator, so that the data would be freed implicitly + * at jpeg_finish_decompress() time. But it seems likely that many apps + * will prefer to have the data stick around after decompression finishes.) + * + * NOTE: if the file contains invalid ICC APP2 markers, we just silently + * return FALSE. You might want to issue an error message instead. + */ + +boolean +read_icc_profile (j_decompress_ptr cinfo, + JOCTET **icc_data_ptr, + unsigned int *icc_data_len) +{ + jpeg_saved_marker_ptr marker; + int num_markers = 0; + int seq_no; + JOCTET *icc_data; + unsigned int total_length; +#define MAX_SEQ_NO 255 /* sufficient since marker numbers are bytes */ + char marker_present[MAX_SEQ_NO+1]; /* 1 if marker found */ + unsigned int data_length[MAX_SEQ_NO+1]; /* size of profile data in marker */ + unsigned int data_offset[MAX_SEQ_NO+1]; /* offset for data in marker */ + + *icc_data_ptr = NULL; /* avoid confusion if FALSE return */ + *icc_data_len = 0; + + /* This first pass over the saved markers discovers whether there are + * any ICC markers and verifies the consistency of the marker numbering. + */ + + for (seq_no = 1; seq_no <= MAX_SEQ_NO; seq_no++) + marker_present[seq_no] = 0; + + for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) { + if (marker_is_icc(marker)) { + if (num_markers == 0) + num_markers = GETJOCTET(marker->data[13]); + else if (num_markers != GETJOCTET(marker->data[13])) + return FALSE; /* inconsistent num_markers fields */ + seq_no = GETJOCTET(marker->data[12]); + if (seq_no <= 0 || seq_no > num_markers) + return FALSE; /* bogus sequence number */ + if (marker_present[seq_no]) + return FALSE; /* duplicate sequence numbers */ + marker_present[seq_no] = 1; + data_length[seq_no] = marker->data_length - ICC_OVERHEAD_LEN; + } + } + + if (num_markers == 0) + return FALSE; + + /* Check for missing markers, count total space needed, + * compute offset of each marker's part of the data. + */ + + total_length = 0; + for (seq_no = 1; seq_no <= num_markers; seq_no++) { + if (marker_present[seq_no] == 0) + return FALSE; /* missing sequence number */ + data_offset[seq_no] = total_length; + total_length += data_length[seq_no]; + } + + /* Allocate space for assembled data */ + icc_data = (JOCTET *) malloc(total_length * sizeof(JOCTET)); + if (icc_data == NULL) + return FALSE; /* oops, out of memory */ + + /* and fill it in */ + for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) { + if (marker_is_icc(marker)) { + JOCTET FAR *src_ptr; + JOCTET *dst_ptr; + unsigned int length; + seq_no = GETJOCTET(marker->data[12]); + dst_ptr = icc_data + data_offset[seq_no]; + src_ptr = marker->data + ICC_OVERHEAD_LEN; + length = data_length[seq_no]; + while (length--) { + *dst_ptr++ = *src_ptr++; + } + } + } + + *icc_data_ptr = icc_data; + *icc_data_len = total_length; + + return TRUE; +} + diff --git a/rtengine/iccjpeg.h b/rtengine/iccjpeg.h new file mode 100644 index 000000000..d7cae7b5d --- /dev/null +++ b/rtengine/iccjpeg.h @@ -0,0 +1,74 @@ +/* + * iccprofile.h + * + * This file provides code to read and write International Color Consortium + * (ICC) device profiles embedded in JFIF JPEG image files. The ICC has + * defined a standard format for including such data in JPEG "APP2" markers. + * The code given here does not know anything about the internal structure + * of the ICC profile data; it just knows how to put the profile data into + * a JPEG file being written, or get it back out when reading. + * + * This code depends on new features added to the IJG JPEG library as of + * IJG release 6b; it will not compile or work with older IJG versions. + * + * NOTE: this code would need surgery to work on 16-bit-int machines + * with ICC profiles exceeding 64K bytes in size. See iccprofile.c + * for details. + */ + +#include /* needed to define "FILE", "NULL" */ +#include "jpeglib.h" + + +/* + * This routine writes the given ICC profile data into a JPEG file. + * It *must* be called AFTER calling jpeg_start_compress() and BEFORE + * the first call to jpeg_write_scanlines(). + * (This ordering ensures that the APP2 marker(s) will appear after the + * SOI and JFIF or Adobe markers, but before all else.) + */ + +extern void write_icc_profile JPP((j_compress_ptr cinfo, + const JOCTET *icc_data_ptr, + unsigned int icc_data_len)); + + +/* + * Reading a JPEG file that may contain an ICC profile requires two steps: + * + * 1. After jpeg_create_decompress() but before jpeg_read_header(), + * call setup_read_icc_profile(). This routine tells the IJG library + * to save in memory any APP2 markers it may find in the file. + * + * 2. After jpeg_read_header(), call read_icc_profile() to find out + * whether there was a profile and obtain it if so. + */ + + +/* + * Prepare for reading an ICC profile + */ + +extern void setup_read_icc_profile JPP((j_decompress_ptr cinfo)); + + +/* + * See if there was an ICC profile in the JPEG file being read; + * if so, reassemble and return the profile data. + * + * TRUE is returned if an ICC profile was found, FALSE if not. + * If TRUE is returned, *icc_data_ptr is set to point to the + * returned data, and *icc_data_len is set to its length. + * + * IMPORTANT: the data at **icc_data_ptr has been allocated with malloc() + * and must be freed by the caller with free() when the caller no longer + * needs it. (Alternatively, we could write this routine to use the + * IJG library's memory allocator, so that the data would be freed implicitly + * at jpeg_finish_decompress() time. But it seems likely that many apps + * will prefer to have the data stick around after decompression finishes.) + */ + +extern boolean read_icc_profile JPP((j_decompress_ptr cinfo, + JOCTET **icc_data_ptr, + unsigned int *icc_data_len)); + diff --git a/rtengine/iccmatrices.h b/rtengine/iccmatrices.h new file mode 100644 index 000000000..e5a91c4e0 --- /dev/null +++ b/rtengine/iccmatrices.h @@ -0,0 +1,165 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _ICCMATRICES_ +#define _ICCMATRICES_ + +// Bradford transform between illuminants +const double d65_d50[3][3] = {{0.9555766, -0.0230393, 0.0631636}, + {-0.0282895, 1.0099416, 0.0210077}, + {0.0122982, -0.0204830, 1.3299098}}; + +const double d50_d65[3][3] = {{ 1.0478112, 0.0228866, -0.0501270}, + {0.0295424, 0.9904844, -0.0170491}, + {-0.0092345, 0.0150436, 0.7521316}}; + +// Color space conversion to/from XYZ; color spaces adapted to D65 +const double xyz_sRGBd65[3][3] = {{0.4124564, 0.3575761, 0.1804375}, + {0.2126729, 0.7151522, 0.0721750}, // WARNING: the summ of this line is > 1.0 + {0.0193339, 0.1191920, 0.9503041}}; + +const double sRGBd65_xyz[3][3] = {{ 3.2404542, -1.5371385, -0.4985314}, + {-0.9692660, 1.8760108, 0.0415560}, + {0.0556434, -0.2040259, 1.0572252}}; + +//%%%%%%%%%%%%%%%%%%%%%%%% +// TEST using Gabor's matrices +/*const double xyz_sRGB[3][3] = {{0.435859, 0.385336, 0.143023}, + {0.222385, 0.717021, 0.0605936 }, + {0.0139162, 0.0971389, 0.713817}}; + +const double sRGB_xyz[3][3] = {{3.13593293538656, -1.61878246026431, -0.490913888760734}, + {-0.978702373022194, 1.91609508555177, 0.0334453372795315}, + {0.0720490013929888, -0.22919049060526, 1.40593851447263}};*/ +//%%%%%%%%%%%%%%%%%%%%%%%% + + +// Color space conversion to/from XYZ; color spaces adapted to D50 using Bradford transform +const double xyz_sRGB[3][3] = {{0.4360747, 0.3850649, 0.1430804}, + {0.2225045, 0.7168786, 0.0606169}, + {0.0139322, 0.0971045, 0.7141733}}; + +const double sRGB_xyz[3][3] = {{3.1338561, -1.6168667, -0.4906146}, + {-0.9787684, 1.9161415, 0.0334540}, + {0.0719453, -0.2289914, 1.4052427}}; + +const double xyz_adobe[3][3] = {{0.6097559, 0.2052401, 0.1492240}, + {0.3111242, 0.6256560, 0.0632197}, + {0.0194811, 0.0608902, 0.7448387}}; + +const double adobe_xyz[3][3] = {{1.9624274, -0.6105343, -0.3413404}, + {-0.9787684, 1.9161415, 0.0334540}, + {0.0286869, -0.1406752, 1.3487655}}; + +const double xyz_prophoto[3][3] = {{0.7976749, 0.1351917, 0.0313534}, + {0.2880402, 0.7118741, 0.0000857}, + {0.0000000, 0.0000000, 0.8252100}}; + +const double prophoto_xyz[3][3] = {{1.3459433, -0.2556075, -0.0511118}, + {-0.5445989, 1.5081673, 0.0205351}, + {0.0000000, 0.0000000, 1.2118128}}; + +const double xyz_widegamut[3][3] = {{0.7161046, 0.1009296, 0.1471858}, + {0.2581874, 0.7249378, 0.0168748}, + {0.0000000, 0.0517813, 0.7734287}}; + +const double widegamut_xyz[3][3] = {{ 1.4628067, -0.1840623, -0.2743606}, + {-0.5217933, 1.4472381, 0.0677227}, + {0.0349342, -0.0968930, 1.2884099}}; + +const double xyz_bruce[3][3] = {{0.4941816, 0.3204834, 0.1495550}, + {0.2521531, 0.6844869, 0.0633600}, + {0.0157886, 0.0629304, 0.7464909}}; + +const double bruce_xyz[3][3] = {{2.6502856, -1.2014485, -0.4289936}, + {-0.9787684, 1.9161415, 0.0334540}, + {0.0264570, -0.1361227, 1.3458542}}; + +const double xyz_beta[3][3] = {{0.6712537, 0.1745834, 0.1183829}, + {0.3032726, 0.6637861, 0.0329413}, + {0.0000000, 0.0407010, 0.7845090}}; + +const double beta_xyz[3][3] = {{1.6832270, -0.4282363, -0.2360185}, + {-0.7710229, 1.7065571, 0.0446900}, + {0.0400013, -0.0885376, 1.2723640}}; + +const double xyz_best[3][3] = {{0.6326696, 0.2045558, 0.1269946}, + {0.2284569, 0.7373523, 0.0341908}, + {0.0000000, 0.0095142, 0.8156958}}; + +const double best_xyz[3][3] = {{1.7552599, -0.4836786, -0.2530000}, + {-0.5441336, 1.5068789, 0.0215528}, + {0.0063467, -0.0175761, 1.2256959}}; + + +/*const double sRGB_d50[3][3] = {{0.4360520246092, 0.2224915978656, 0.0139291219896}, + {0.38508159282, 0.716886060114, 0.09709700166}, + {0.1430874138552, 0.0606214863936, 0.714185469944}}; + +const double d50_sRGB[3][3] = {{3.13405134405167,-0.978762729953942, 0.0719425766617001}, + {-1.61702771153574,1.91614222810656, -0.228971178679309}, + {-0.49065220876631,0.0334496273068589, 1.40521830559074}};*/ + +/* +// Gabor's matrices +const double sRGB_d50[3][3] = {{0.435859, 0.222385, 0.0139162}, + {0.385336, 0.717021, 0.0971389}, + {0.143023, 0.0605936, 0.713817}}; + +const double d50_sRGB[3][3] = {{3.13593293538656, -0.978702373022194, 0.0720490013929888}, + {-1.61878246026431, 1.91609508555177, -0.22919049060526}, + {-0.490913888760734, 0.0334453372795315, 1.40593851447263}}; + +const double adobe_d50[3][3] = {{0.6097395054954, 0.3111142944042, 0.0194773131652}, + {0.2052518325737, 0.6256618480686, 0.0608872306106}, + {0.1492308013399, 0.0632241329247, 0.744846530711}}; +const double d50_adobe[3][3] = {{1.9624959949628, -0.978762712052774, 0.0286904764959749}, + {-0.610587687828765,1.91614073756734, -0.140667763143042}, + {-0.34136021627766, 0.0334501217627688, 1.34875045144924}}; +const double prophoto_d50[3][3] = {{0.797675, 0.288040, 0.000000}, + {0.135192, 0.711874, 0.000000}, + {0.0313534,0.000086, 0.825210}}; +const double d50_prophoto[3][3] = {{1.34594335079331, -0.544598514291158, 0}, + {-0.255608118122657, 1.50816768465213, 0}, + {-0.0511117387775285, 0.0205345459181255, 1.21181275069376}}; +const double widegamut_d50[3][3] = {{0.716105, 0.258187, 0.000000}, + {0.100930, 0.724938, 0.0517813}, + {0.147186, 0.0168748, 0.773429}}; +const double d50_widegamut[3][3] = {{1.46280597103052, -0.521792197260068, 0.0349341417298585}, + {-0.184062984909417, 1.44723786022891, -0.0968930022172314}, + {-0.27436071519732, 0.0677226440980744,1.28840945122198}}; +const double bruce_d50[3][3] = {{0.4941607255908, 0.2521412970174, 0.0157852934504}, + {0.3204990468435, 0.684494580042, 0.062927176507}, + {0.1495612990809, 0.0633643619597, 0.746498914581}}; +const double d50_bruce[3][3] = {{2.65042308164152, -0.978762745761462, 0.0264609493245811}, + {-1.20155941925411, 1.9161402914007, -0.136115844662896}, + {-0.42902228923717, 0.0334495071197919, 1.34583900936772}}; +const double beta_d50[3][3] = {{0.671254, 0.303273, 0.000000}, + {0.174583, 0.663786, 0.040701}, + {0.118383, 0.0329413, 0.784509}}; +const double d50_beta[3][3] = {{1.68322591962771, -0.771023599950842, 0.0400013658754702}, + {-0.428235060337656, 1.70655704781303, -0.0885376438040078}, + {-0.236018598193503, 0.0446902191738489,1.27236406897742}}; +const double best_d50[3][3] = {{0.632670, 0.228457, 0.000000}, + {0.204556, 0.737352, 0.00951424}, + {0.126995, 0.0341908, 0.815696}}; +const double d50_best[3][3] = {{1.75525923340349, -0.544133953997468, 0.00634675299435191}, + {-0.483679025800866, 1.50687975713407, -0.017576175021718}, + {-0.253000840399762, 0.0215532098817316,1.22569552576991}}; + */ +#endif diff --git a/rtengine/iccstore.cc b/rtengine/iccstore.cc new file mode 100644 index 000000000..a2f2b533f --- /dev/null +++ b/rtengine/iccstore.cc @@ -0,0 +1,557 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifdef WIN32 +#include +#else +#include +#endif +#include "iccstore.h" +#include "iccmatrices.h" +#include +#include "safegtk.h" +#include "../rtgui/options.h" + +#include + +namespace rtengine { + +const double (*wprofiles[])[3] = {xyz_sRGB, xyz_adobe, xyz_prophoto, xyz_widegamut, xyz_bruce, xyz_beta, xyz_best}; +const double (*iwprofiles[])[3] = {sRGB_xyz, adobe_xyz, prophoto_xyz, widegamut_xyz, bruce_xyz, beta_xyz, best_xyz}; +const char* wpnames[] = {"sRGB", "Adobe RGB", "ProPhoto", "WideGamut", "BruceRGB", "Beta RGB", "BestRGB"}; +const char* wpgamma[] = {"default","BT709_g2.2_s4.5", "sRGB_g2.4_s12.92", "linear_g1.0", "standard_g2.2", "standard_g1.8", "High_g1.3_s3.35","Low_g2.6_s6.9"}; //gamma free +//default = gamma inside profile +//BT709 g=2.22 s=4.5 sRGB g=2.4 s=12.92 +//linear g=1.0 +//std22 g=2.2 std18 g=1.8 +// high g=1.3 s=3.35 for high dynamic images +//low g=2.6 s=6.9 for low contrast images + + +std::vector getGamma () {//return gamma + + std::vector res; + for (unsigned int i=0; i getWorkingProfiles () { + + std::vector res; + for (unsigned int i=0; i ICCStore::getOutputProfiles () { + + MyMutex::MyLock lock(mutex_); + + std::vector res; + for (std::map::iterator i=fileProfiles.begin(); i!=fileProfiles.end(); i++){ + Glib::ustring name(i->first); + std::string::size_type i2 = name.find_last_of('/'); + if( i2 == std::string::npos ) + i2 = name.find_last_of('\\'); + if( i2 == std::string::npos ) + res.push_back ( name ); // list only profiles inside selected profiles directory + } + return res; +} + + +cmsHPROFILE +ICCStore::makeStdGammaProfile(cmsHPROFILE iprof) +{ + // forgive me for the messy code, quick hack to change gamma of an ICC profile to the RT standard gamma + if (!iprof) { + return NULL; + } + cmsUInt32Number bytesNeeded = 0; + cmsSaveProfileToMem(iprof, 0, &bytesNeeded); + if (bytesNeeded == 0) { + return NULL; + } + uint8_t *data = new uint8_t[bytesNeeded+1]; + cmsSaveProfileToMem(iprof, data, &bytesNeeded); + const uint8_t *p = &data[128]; // skip 128 byte header + uint32_t tag_count; + memcpy(&tag_count, p, 4); + p += 4; + tag_count = ntohl(tag_count); + + struct icctag { + uint32_t sig; + uint32_t offset; + uint32_t size; + } tags[tag_count]; + + const uint32_t gamma = 0x239; + int gamma_size = (gamma == 0 || gamma == 256) ? 12 : 14; + int data_size = (gamma_size + 3) & ~3; + for (uint32_t i = 0; i < tag_count; i++) { + memcpy(&tags[i], p, 12); + tags[i].sig = ntohl(tags[i].sig); + tags[i].offset = ntohl(tags[i].offset); + tags[i].size = ntohl(tags[i].size); + p += 12; + if (tags[i].sig != 0x62545243 && // bTRC + tags[i].sig != 0x67545243 && // gTRC + tags[i].sig != 0x72545243 && // rTRC + tags[i].sig != 0x6B545243) // kTRC + { + data_size += (tags[i].size + 3) & ~3; + } + } + uint32_t sz = 128 + 4 + tag_count * 12 + data_size; + uint8_t *nd = new uint8_t[sz]; + memset(nd, 0, sz); + memcpy(nd, data, 128 + 4); + sz = htonl(sz); + memcpy(nd, &sz, 4); + uint32_t offset = 128 + 4 + tag_count * 12; + uint32_t gamma_offset = 0; + for (uint32_t i = 0; i < tag_count; i++) { + struct icctag tag; + tag.sig = htonl(tags[i].sig); + if (tags[i].sig == 0x62545243 || // bTRC + tags[i].sig == 0x67545243 || // gTRC + tags[i].sig == 0x72545243 || // rTRC + tags[i].sig == 0x6B545243) // kTRC + { + if (gamma_offset == 0) { + gamma_offset = offset; + uint32_t pcurve[] = { htonl(0x63757276), htonl(0), htonl(gamma_size == 12 ? 0 : 1) }; + memcpy(&nd[offset], pcurve, 12); + if (gamma_size == 14) { + uint16_t gm = htons(gamma); + memcpy(&nd[offset+12], &gm, 2); + } + offset += (gamma_size + 3) & ~3; + } + tag.offset = htonl(gamma_offset); + tag.size = htonl(gamma_size); + } else { + tag.offset = htonl(offset); + tag.size = htonl(tags[i].size); + memcpy(&nd[offset], &data[tags[i].offset], tags[i].size); + offset += (tags[i].size + 3) & ~3; + } + memcpy(&nd[128 + 4 + i * 12], &tag, 12); + } + + cmsHPROFILE oprof = cmsOpenProfileFromMem (nd, ntohl(sz)); + delete [] nd; + delete [] data; + return oprof; +} + +ICCStore* +ICCStore::getInstance(void) +{ + static ICCStore* instance_ = 0; + if ( instance_ == 0 ) + { + static MyMutex smutex_; + MyMutex::MyLock lock(smutex_); + if ( instance_ == 0 ) + { + instance_ = new ICCStore(); + } + } + return instance_; +} + +ICCStore::ICCStore () +{ + //cmsErrorAction (LCMS_ERROR_SHOW); + + int N = sizeof(wpnames)/sizeof(wpnames[0]); + for (int i=0; i::iterator r = wMatrices.find (name); + if (r!=wMatrices.end()) + return r->second; + else + return wMatrices["sRGB"]; +} + +TMatrix ICCStore::workingSpaceInverseMatrix (Glib::ustring name) { + + std::map::iterator r = iwMatrices.find (name); + if (r!=iwMatrices.end()) + return r->second; + else + return iwMatrices["sRGB"]; +} + +cmsHPROFILE ICCStore::workingSpace (Glib::ustring name) { + + std::map::iterator r = wProfiles.find (name); + if (r!=wProfiles.end()) + return r->second; + else + return wProfiles["sRGB"]; +} + +cmsHPROFILE ICCStore::workingSpaceGamma (Glib::ustring name) { + + std::map::iterator r = wProfilesGamma.find (name); + if (r!=wProfilesGamma.end()) + return r->second; + else + return wProfilesGamma["sRGB"]; +} + +cmsHPROFILE ICCStore::getProfile (Glib::ustring name) { + + MyMutex::MyLock lock(mutex_); + + std::map::iterator r = fileProfiles.find (name); + if (r!=fileProfiles.end()) + return r->second; + else { + if (!name.compare (0, 5, "file:") && safe_file_test (name.substr(5), Glib::FILE_TEST_EXISTS) && !safe_file_test (name.substr(5), Glib::FILE_TEST_IS_DIR)) { + ProfileContent pc (name.substr(5)); + if (pc.data) { + cmsHPROFILE profile = pc.toProfile (); + if (profile) { + fileProfiles[name] = profile; + fileProfileContents[name] = pc; + return profile; + } + } + } + } + return NULL; +} + +cmsHPROFILE ICCStore::getStdProfile (Glib::ustring name) { + + MyMutex::MyLock lock(mutex_); + + std::map::iterator r = fileStdProfiles.find (name.uppercase()); + if (r==fileStdProfiles.end()) { + // profile is not yet in store + std::map::iterator f = fileStdProfilesFileNames.find (name.uppercase()); + if(f!=fileStdProfilesFileNames.end()) { + // but there exists one => load it + ProfileContent pc (f->second); + if (pc.data) { + cmsHPROFILE profile = pc.toProfile (); + if (profile) { + fileStdProfiles[name.uppercase()] = profile; + } + // profile is not valid or it is now stored => remove entry from fileStdProfilesFileNames + fileStdProfilesFileNames.erase(f); + return profile; + } else { + // profile not valid => remove entry from fileStdProfilesFileNames + fileStdProfilesFileNames.erase(f); + return NULL; + } + } else { + // profile does not exist + return NULL; + } + } else { + // return profile from store + return r->second; + } +} + +ProfileContent ICCStore::getContent (Glib::ustring name) { + + MyMutex::MyLock lock(mutex_); + + return fileProfileContents[name]; +} + +// Reads all profiles from the given profiles dir +void ICCStore::init (Glib::ustring usrICCDir, Glib::ustring rtICCDir) { + + MyMutex::MyLock lock(mutex_); + + // + fileProfiles.clear(); + fileProfileContents.clear(); + // RawTherapee's profiles take precedence if a user's profile of the same name exists + loadICCs(Glib::build_filename(rtICCDir, "output"), false, fileProfiles, &fileProfileContents, true, true); + loadICCs(usrICCDir, false, fileProfiles, &fileProfileContents, true, true); + + // Input profiles + // Load these to different areas, since the short name (e.g. "NIKON D700" may overlap between system/user and RT dir) + fileStdProfiles.clear(); + fileStdProfilesFileNames.clear(); + loadICCs(Glib::build_filename(rtICCDir, "input"), true, fileStdProfiles, NULL); +} + +void ICCStore::loadICCs(Glib::ustring rootDirName, bool nameUpper, std::map& resultProfiles, std::map *resultProfileContents, bool prefetch, bool onlyRgb) { + if (rootDirName!="") { + std::deque qDirs; + + qDirs.push_front(rootDirName); + + while (!qDirs.empty()) { + // process directory + Glib::ustring dirname = qDirs.back(); + qDirs.pop_back(); + + Glib::Dir* dir = NULL; + try { + if (!safe_file_test (dirname, Glib::FILE_TEST_IS_DIR)) return; + dir = new Glib::Dir (dirname); + } + catch (Glib::Exception& fe) { + return; + } + dirname = dirname + "/"; + for (Glib::DirIterator i = dir->begin(); i!=dir->end(); ++i) { + Glib::ustring fname = dirname + *i; + Glib::ustring sname = *i; + // ignore directories + if (!safe_file_test (fname, Glib::FILE_TEST_IS_DIR)) { + size_t lastdot = sname.find_last_of ('.'); + if (lastdot!=Glib::ustring::npos && lastdot<=sname.size()-4 && (!sname.casefold().compare (lastdot, 4, ".icm") || !sname.casefold().compare (lastdot, 4, ".icc"))) { + Glib::ustring name = nameUpper ? sname.substr(0,lastdot).uppercase() : sname.substr(0,lastdot); + if(!prefetch) { + fileStdProfilesFileNames[name] = fname; + } else { + ProfileContent pc (fname); + if (pc.data) { + cmsHPROFILE profile = pc.toProfile (); + if (profile && (!onlyRgb || cmsGetColorSpace(profile) == cmsSigRgbData)) { + resultProfiles[name] = profile; + if(resultProfileContents) + (*resultProfileContents)[name] = pc; + } + } + } + } + } + // Removed recursive scanning, see issue #1730. + // To revert to the recursive method, just uncomment the next line. + + //else qDirs.push_front(fname); // for later scanning + } + delete dir; + } + } +} + +// Determine the first monitor default profile of operating system, if selected +void ICCStore::findDefaultMonitorProfile() { + defaultMonitorProfile=""; + +#ifdef WIN32 + // Get current main monitor. Could be fine tuned to get the current windows monitor (multi monitor setup), + // but problem is that we live in RTEngine with no GUI window to query around + HDC hDC=GetDC(NULL); + + if (hDC!=NULL) { + if (SetICMMode(hDC, ICM_ON)) { + char profileName[MAX_PATH+1]; DWORD profileLength=MAX_PATH; + if (GetICMProfileA(hDC,&profileLength,profileName)) defaultMonitorProfile=Glib::ustring(profileName); + // might fail if e.g. the monitor has no profile + } + + ReleaseDC(NULL,hDC); + } +#else +// TODO: Add other OS specific code here +#endif + + if (options.rtSettings.verbose) printf("Default monitor profile is: %s\n", defaultMonitorProfile.c_str()); +} + +ProfileContent::ProfileContent (Glib::ustring fileName) : data(NULL), length(0) { + + FILE* f = safe_g_fopen (fileName, "rb"); + if (!f) + return; + fseek (f, 0, SEEK_END); + length = ftell (f); + fseek (f, 0, SEEK_SET); + data = new char[length+1]; + fread (data, length, 1, f); + data[length] = 0; + fclose (f); +} + +ProfileContent::ProfileContent (const ProfileContent& other) { + + length = other.length; + if (other.data) { + data = new char[length+1]; + memcpy (data, other.data, length+1); + } + else + data = NULL; +} + +ProfileContent::ProfileContent (cmsHPROFILE hProfile) : data(NULL), length(0) { + + if (hProfile != NULL) { + cmsUInt32Number bytesNeeded = 0; + cmsSaveProfileToMem(hProfile, 0, &bytesNeeded); + if (bytesNeeded > 0) + { + data = new char[bytesNeeded+1]; + cmsSaveProfileToMem(hProfile, data, &bytesNeeded); + length = (int)bytesNeeded; + } + } +} + + +ProfileContent& ProfileContent::operator= (const ProfileContent& other) { + + length = other.length; + if (data) + delete [] data; + if (other.data) { + data = new char[length+1]; + memcpy (data, other.data, length+1); + } + else + data = NULL; + return *this; +} + +ProfileContent::~ProfileContent () { + + if (data) + delete [] data; +} + +cmsHPROFILE ProfileContent::toProfile () { + + if (data) + return cmsOpenProfileFromMem (data, length); + else + return NULL; +} + +cmsHPROFILE ICCStore::createFromMatrix (const double matrix[3][3], bool gamma, Glib::ustring name) { + + static const unsigned phead[] = + { 1024, 0, 0x2100000, 0x6d6e7472, 0x52474220, 0x58595a20, 0, 0, 0, + 0x61637370, 0, 0, 0, 0, 0, 0, 0, 0xf6d6, 0x10000, 0xd32d }; + unsigned pbody[] = + { 10, 0x63707274, 0, 36, /* cprt */ + 0x64657363, 0, 40, /* desc */ + 0x77747074, 0, 20, /* wtpt */ + 0x626b7074, 0, 20, /* bkpt */ + 0x72545243, 0, 14, /* rTRC */ + 0x67545243, 0, 14, /* gTRC */ + 0x62545243, 0, 14, /* bTRC */ + 0x7258595a, 0, 20, /* rXYZ */ + 0x6758595a, 0, 20, /* gXYZ */ + 0x6258595a, 0, 20 }; /* bXYZ */ + static const unsigned pwhite[] = { 0xf351, 0x10000, 0x116cc };//D65 + //static const unsigned pwhite[] = { 0xf6d6, 0x10000, 0xd340 };//D50 + + // 0x63757276 : curveType, 0 : reserved, 1 : entries (1=gamma, 0=identity), 0x1000000=1.0 + unsigned pcurve[] = { 0x63757276, 0, 0, 0x1000000 }; +// unsigned pcurve[] = { 0x63757276, 0, 1, 0x1000000 }; + + if (gamma) { + pcurve[2] = 1; + // pcurve[3] = 0x1f00000;// pcurve for gamma BT709 : g=2.22 s=4.5 + // normalize gamma in RT, default (Emil's choice = sRGB) + pcurve[3] = 0x2390000;//pcurve for gamma sRGB : g:2.4 s=12.92 + + } else { + // lcms2 up to 2.4 has a bug with linear gamma causing precision loss (banding) + // of floating point data when a normal icc encoding of linear gamma is used + // (i e 0 table entries), but by encoding a gamma curve which is 1.0 the + // floating point path is taken within lcms2 so no precision loss occurs and + // gamma is still 1.0. + pcurve[2] = 1; + pcurve[3] = 0x1000000; //pcurve for gamma 1 + } + + // constructing profile header + unsigned* oprof = new unsigned [phead[0]/sizeof(unsigned)]; + memset (oprof, 0, phead[0]); + memcpy (oprof, phead, sizeof(phead)); + + oprof[0] = 132 + 12*pbody[0]; + + // constructing tag directory (pointers inside the file), and types + // 0x74657874 : text + // 0x64657363 : description tag + for (unsigned int i=0; i < pbody[0]; i++) { + oprof[oprof[0]/4] = i ? (i > 1 ? 0x58595a20 : 0x64657363) : 0x74657874; + pbody[i*3+2] = oprof[0]; + oprof[0] += (pbody[i*3+3] + 3) & -4; + } + memcpy (oprof+32, pbody, sizeof(pbody)); + + // wtpt + memcpy ((char *)oprof+pbody[8]+8, pwhite, sizeof(pwhite)); + + // r/g/b TRC + for (int i=4; i < 7; i++) + memcpy ((char *)oprof+pbody[i*3+2], pcurve, sizeof(pcurve)); + + // r/g/b XYZ +// pseudoinverse ((double (*)[3]) out_rgb[output_color-1], inverse, 3); + for (int i=0; i < 3; i++) + for (int j=0; j < 3; j++) { + oprof[pbody[j*3+23]/4+i+2] = matrix[i][j] * 0x10000 + 0.5; +// for (num = k=0; k < 3; k++) +// num += xyzd50_srgb[i][k] * inverse[j][k]; + } + + // convert to network byte order + for (unsigned int i=0; i < phead[0]/4; i++) + oprof[i] = htonl(oprof[i]); + + // cprt + strcpy ((char *)oprof+pbody[2]+8, "--rawtherapee profile--"); + + // desc + oprof[pbody[5]/4+2] = name.size() + 1; + strcpy ((char *)oprof+pbody[5]+12, name.c_str()); + + + cmsHPROFILE p = cmsOpenProfileFromMem (oprof, ntohl(oprof[0])); + delete [] oprof; + return p; +} +} diff --git a/rtengine/iccstore.h b/rtengine/iccstore.h new file mode 100644 index 000000000..3662d099b --- /dev/null +++ b/rtengine/iccstore.h @@ -0,0 +1,101 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef __ICCSTORE__ +#define __ICCSTORE__ + +#include +#include +#include +#include +#include "../rtgui/threadutils.h" + +namespace rtengine { + +typedef const double (*TMatrix)[3]; + +class ProfileContent { + + public: + char* data; + int length; + + ProfileContent (): data(NULL), length(0) {} + ProfileContent (Glib::ustring fileName); + ProfileContent (const ProfileContent& other); + ProfileContent (cmsHPROFILE hProfile); + ~ProfileContent (); + ProfileContent& operator= (const rtengine::ProfileContent& other); + cmsHPROFILE toProfile (); +}; + +class ICCStore { + + std::map wProfiles; + std::map wProfilesGamma; + std::map wMatrices; + std::map iwMatrices; + + // these contain profiles from user/system directory (supplied on init) + std::map fileProfiles; + std::map fileProfileContents; + + // these contain standard profiles from RT. keys are all in uppercase + std::map fileStdProfilesFileNames; + std::map fileStdProfiles; + + cmsHPROFILE xyz; + cmsHPROFILE srgb; + + MyMutex mutex_; + + ICCStore (); + void loadICCs(Glib::ustring rootDirName, bool nameUpper, std::map& resultProfiles, std::map *resultProfileContents, bool prefetch = false, bool onlyRgb = false); + + public: + + static ICCStore* getInstance(void); + static cmsHPROFILE makeStdGammaProfile(cmsHPROFILE iprof); + + Glib::ustring defaultMonitorProfile; // Main monitors standard profile name, from OS + void findDefaultMonitorProfile(); + + int numOfWProfiles (); + cmsHPROFILE createFromMatrix (const double matrix[3][3], bool gamma=false, Glib::ustring name=""); + cmsHPROFILE workingSpace (Glib::ustring name); + cmsHPROFILE workingSpaceGamma (Glib::ustring name); + TMatrix workingSpaceMatrix (Glib::ustring name); + TMatrix workingSpaceInverseMatrix (Glib::ustring name); + + cmsHPROFILE getProfile (Glib::ustring name); + cmsHPROFILE getStdProfile(Glib::ustring name); + + void init (Glib::ustring usrICCDir, Glib::ustring stdICCDir); + ProfileContent getContent (Glib::ustring name); + + cmsHPROFILE getXYZProfile () { return xyz; } + cmsHPROFILE getsRGBProfile () { return srgb; } + std::vector getOutputProfiles (); +}; + +#define iccStore ICCStore::getInstance() + +//extern const char* wpnames[]; +} +#endif + diff --git a/rtengine/iimage.cc b/rtengine/iimage.cc new file mode 100644 index 000000000..9296fd837 --- /dev/null +++ b/rtengine/iimage.cc @@ -0,0 +1,43 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "rtengine.h" + +const char rtengine::sImage8[] = "Image8"; +const char rtengine::sImage16[] = "Image16"; +const char rtengine::sImagefloat[] = "Imagefloat"; +int rtengine::getCoarseBitMask( const procparams::CoarseTransformParams &coarse) +{ + int tr = TR_NONE; + if (coarse.rotate == 90) { + tr |= TR_R90; + } else if (coarse.rotate == 180) { + tr |= TR_R180; + } else if (coarse.rotate == 270) { + tr |= TR_R270; + } + + if (coarse.hflip) { + tr |= TR_HFLIP; + } + if (coarse.vflip) { + tr |= TR_VFLIP; + } + return tr; +} diff --git a/rtengine/iimage.h b/rtengine/iimage.h new file mode 100644 index 000000000..64a30f771 --- /dev/null +++ b/rtengine/iimage.h @@ -0,0 +1,1569 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _IIMAGE_ +#define _IIMAGE_ + +#include +#include +#include "rt_math.h" +#include "alignedbuffer.h" +#include "imagedimensions.h" +#include "LUT.h" +#include "coord2d.h" +#include "procparams.h" +#include "color.h" + +#define TR_NONE 0 +#define TR_R90 1 +#define TR_R180 2 +#define TR_R270 3 +#define TR_VFLIP 4 +#define TR_HFLIP 8 +#define TR_ROT 3 + +#define CHECK_BOUNDS 0 + +namespace rtengine { + + extern const char sImage8[]; + extern const char sImage16[]; + extern const char sImagefloat[]; + int getCoarseBitMask( const procparams::CoarseTransformParams &coarse); + class ProgressListener; + class Color; + + enum TypeInterpolation { TI_Nearest, TI_Bilinear }; + + // -------------------------------------------------------------------- + // Generic classes + // -------------------------------------------------------------------- + + class ImageDatas : virtual public ImageDimensions { + public: + template + void convertTo (S srcValue, D &dstValue) { + dstValue = static_cast(srcValue); + } + + // parameters that will never be used, replaced by the subclasses r, g and b parameters! + // they are still necessary to implement operator() in this parent class + virtual ~ImageDatas() {} + virtual void allocate (int W, int H) {} + virtual void rotate (int deg) {} + // free the memory allocated for the image data without deleting the object. + virtual void flushData () { allocate(0,0); } + + virtual void hflip () {} + virtual void vflip () {} + + // Read the raw dump of the data + void readData (FILE *fh) {} + // Write a raw dump of the data + void writeData (FILE *fh) {} + + virtual void normalizeInt (int srcMinVal, int srcMaxVal) {}; + virtual void normalizeFloat (float srcMinVal, float srcMaxVal) {}; + virtual void computeHistogramAutoWB (double &avg_r, double &avg_g, double &avg_b, int &n, LUTu &histogram, int compression) {} + virtual void getSpotWBData (double &reds, double &greens, double &blues, int &rn, int &gn, int &bn, + std::vector &red, std::vector &green, std::vector &blue, + int tran) {} + virtual void getAutoWBMultipliers (double &rm, double &gm, double &bm) { rm=gm=bm=1.0; } + virtual const char* getType () const { return "unknown"; } + + }; + + template <> + inline void ImageDatas::convertTo (const unsigned short srcValue, unsigned char &dstValue) { + dstValue = (unsigned char)(srcValue >> 8); + } + template <> + inline void ImageDatas::convertTo (const unsigned char srcValue, int &dstValue) { + dstValue = (int)(srcValue) << 8; + } + template <> + inline void ImageDatas::convertTo (const unsigned char srcValue, unsigned short &dstValue) { + dstValue = (unsigned short)(srcValue) << 8; + } + template <> + inline void ImageDatas::convertTo (const float srcValue, unsigned char &dstValue) { + dstValue = (unsigned char)( (unsigned short)(srcValue) >> 8 ); + } + template <> + inline void ImageDatas::convertTo (const unsigned char srcValue, float &dstValue) { + dstValue = float( (unsigned short)(srcValue) << 8 ); + } + + // -------------------------------------------------------------------- + // Planar order classes + // -------------------------------------------------------------------- + + template + class PlanarPtr { + protected: + AlignedBuffer ab; + public: + #if CHECK_BOUNDS + int width_, height_; + #endif + T** ptrs; + + #if CHECK_BOUNDS + PlanarPtr() : width_(0), height_(0), ptrs (NULL) {} + #else + PlanarPtr() : ptrs (NULL){} + #endif + + bool resize(int newSize) { + if (ab.resize(newSize)) { + ptrs=ab.data; + return true; + } + else { + ptrs=NULL; + return false; + } + } + void swap (PlanarPtr &other) { + ab.swap(other.ab); + T** tmpsPtrs = other.ptrs; + other.ptrs = ptrs; + ptrs = tmpsPtrs; + + #if CHECK_BOUNDS + int tmp = other.width_; + other.width_ = width_; + width_ = tmp; + tmp = other.height_; + other.height_ = height_; + height_ = tmp; + #endif + } + + T*& operator() (unsigned row) { + #if CHECK_BOUNDS + assert (row < height_); + #endif + return ptrs[row]; + } + // Will send back the start of a row, starting with a red, green or blue value + T* operator() (unsigned row) const { + #if CHECK_BOUNDS + assert (row < height_); + #endif + return ptrs[row]; + } + // Will send back a value at a given row, col position + T& operator() (unsigned row, unsigned col) { + #if CHECK_BOUNDS + assert (row < height_ && col < width_); + #endif + return ptrs[row][col]; + } + const T operator() (unsigned row, unsigned col) const { + #if CHECK_BOUNDS + assert (row < height_ && col < width_); + #endif + return ptrs[row][col]; + } + }; + + template + class PlanarWhateverData : virtual public ImageDatas { + + private: + AlignedBuffer abData; + + int rowstride; // Plan size, in bytes (all padding bytes included) + + public: + T* data; + PlanarPtr v; // v stands for "value", whatever it represent + + PlanarWhateverData() : rowstride(0), data (NULL) {} + PlanarWhateverData(int w, int h) : rowstride(0), data (NULL) { + allocate(w, h); + } + + // Send back the row stride. WARNING: unit = byte, not element! + int getRowStride () { return rowstride; } + + void swap(PlanarWhateverData &other) { + abData.swap(other.abData); + v.swap(other.v); + T* tmpData = other.data; + other.data = data; + data = tmpData; + int tmpWidth = other.width; + other.width = width; + width = tmpWidth; + int tmpHeight = other.height; + other.height = height; + height = tmpHeight; + #if CHECK_BOUNDS + v.width_ = width; + v.height_ = height; + #endif + } + + // use as pointer to data + //operator void*() { return data; }; + + /* If any of the required allocation fails, "width" and "height" are set to -1, and all remaining buffer are freed + * Can be safely used to reallocate an existing image */ + void allocate (int W, int H) { + + if (W==width && H==height) + return; + + width=W; + height=H; + #if CHECK_BOUNDS + v.width_ = width; + v.height_ = height; + #endif + + if (sizeof(T) > 1) { + // 128 bits memory alignment for >8bits data + rowstride = ( width*sizeof(T)+15 )/16*16; + } + else { + // No memory alignment for 8bits data + rowstride = width*sizeof(T); + } + + // find the padding length to ensure a 128 bits alignment for each row + size_t size = rowstride * height; + if (!width) { + size = 0; + rowstride = 0; + } + + if (size && abData.resize(size, 1) + && v.resize(height) ) + { + data = abData.data; + } + else { + // asking for a new size of 0 is safe and will free memory, if any! + abData.resize(0); + data = NULL; + v.resize(0); + width = height = -1; + #if CHECK_BOUNDS + v.width_ = v.height_ = -1; + #endif + + return; + } + + char *start = (char*)(data); + + for (int i=0; i *dest) { + assert (dest!=NULL); + // Make sure that the size is the same, reallocate if necessary + dest->allocate(width, height); + if (dest->width == -1) { + return; + } + for (int i=0; iv(i), v(i), width*sizeof(T)); + } + } + + void rotate (int deg) { + + if (deg==90) { + PlanarWhateverData rotatedImg(height, width); // New image, rotated + + for (int ny=0; ny rotatedImg(height, width); // New image, rotated + + for (int nx=0; nx32 && height>50; + #pragma omp parallel for schedule(static) if(bigImage) + #endif + for (int i=0; i + void resizeImgTo (int nw, int nh, TypeInterpolation interp, PlanarWhateverData *imgPtr) { + //printf("resizeImgTo: resizing %s image data (%d x %d) to %s (%d x %d)\n", getType(), width, height, imgPtr->getType(), imgPtr->width, imgPtr->height); + if (width==nw && height==nh) { + // special case where no resizing is necessary, just type conversion.... + for (int i=0; iv(i,j)); + } + } + } + else if (interp == TI_Nearest) { + for (int i=0; iv(i,j)); + } + } + } + else if (interp == TI_Bilinear) { + for (int i=0; i=height) sy = height-1; + float dy = float(i)*float(height)/float(nh) - float(sy); + int ny = sy+1; + if (ny>=height) ny = sy; + for (int j=0; j=width) sx = width; + float dx = float(j)*float(width)/float(nw) - float(sx); + int nx = sx+1; + if (nx>=width) nx = sx; + convertTo(v(sy,sx)*(1.f-dx)*(1.f-dy) + v(sy,nx)*dx*(1.f-dy) + v(ny,sx)*(1.f-dx)*dy + v(ny,nx)*dx*dy, imgPtr->v(i,j)); + } + } + } + else { + // This case should never occur! + for (int i=0; i32 && height>50; + #pragma omp parallel for schedule(static) if(bigImage) + #endif + for (int i=0; i32 && height>50; + #pragma omp parallel for schedule(static) if(bigImage) + #endif + for (int i=0; i please creates specialization if necessary + unsigned long int n = 0; + int halfSquare = squareSize/2; + transformPixel (posX, posY, tran, x, y); + for (int iy=y-halfSquare; iy=0 && iy>=0 && ixv(iy, ix)); + ++n; + } + } + } + value = n ? T(accumulator/float(n)) : T(0); + } + + void readData (FILE *f) { + for (int i=0; i + class PlanarRGBData : virtual public ImageDatas { + + private: + AlignedBuffer abData; + + int rowstride; // Plan size, in bytes (all padding bytes included) + int planestride; // Row length, in bytes (padding bytes included) + protected: + T* data; + + public: + PlanarPtr r; + PlanarPtr g; + PlanarPtr b; + + PlanarRGBData() : rowstride(0), planestride(0), data (NULL) {} + PlanarRGBData(int w, int h) : rowstride(0), planestride(0), data (NULL) { + allocate(w, h); + } + + // Send back the row stride. WARNING: unit = byte, not element! + int getRowStride () { return rowstride; } + // Send back the plane stride. WARNING: unit = byte, not element! + int getPlaneStride () { return planestride; } + + void swap(PlanarRGBData &other) { + abData.swap(other.abData); + r.swap(other.r); + g.swap(other.g); + b.swap(other.b); + T* tmpData = other.data; + other.data = data; + data = tmpData; + int tmpWidth = other.width; + other.width = width; + width = tmpWidth; + int tmpHeight = other.height; + other.height = height; + height = tmpHeight; + #if CHECK_BOUNDS + r.width_ = width; r.height_ = height; + g.width_ = width; g.height_ = height; + b.width_ = width; b.height_ = height; + #endif + } + + // use as pointer to data + //operator void*() { return data; }; + + /* If any of the required allocation fails, "width" and "height" are set to -1, and all remaining buffer are freed + * Can be safely used to reallocate an existing image */ + void allocate (int W, int H) { + + if (W==width && H==height) + return; + + width=W; + height=H; + #if CHECK_BOUNDS + r.width_ = width; r.height_ = height; + g.width_ = width; g.height_ = height; + b.width_ = width; b.height_ = height; + #endif + + if (sizeof(T) > 1) { + // 128 bits memory alignment for >8bits data + rowstride = ( width*sizeof(T)+15 )/16*16; + planestride = rowstride * height; + } + else { + // No memory alignment for 8bits data + rowstride = width*sizeof(T); + planestride = rowstride * height; + } + + // find the padding length to ensure a 128 bits alignment for each row + size_t size = (size_t)rowstride*3*(size_t)height; + if (!width) { + size = 0; + rowstride = 0; + } + + if (size && abData.resize(size, 1) + && r.resize(height) + && g.resize(height) + && b.resize(height) ) + { + data = abData.data; + } + else { + // asking for a new size of 0 is safe and will free memory, if any! + abData.resize(0); + data = NULL; + r.resize(0); + g.resize(0); + b.resize(0); + width = height = -1; + #if CHECK_BOUNDS + r.width_ = r.height_ = -1; + g.width_ = g.height_ = -1; + b.width_ = b.height_ = -1; + #endif + return; + } + + char *redstart = (char*)(data); + char *greenstart = (char*)(data) + planestride; + char *bluestart = (char*)(data) + 2*planestride; + + for (int i=0; i *dest) { + assert (dest!=NULL); + // Make sure that the size is the same, reallocate if necessary + dest->allocate(width, height); + if (dest->width == -1) { + printf("ERROR: PlanarRGBData::copyData >>> allocation failed!\n"); + return; + } + for (int i=0; ir(i), r(i), width*sizeof(T)); + memcpy (dest->g(i), g(i), width*sizeof(T)); + memcpy (dest->b(i), b(i), width*sizeof(T)); + } + } + + void rotate (int deg) { + + if (deg==90) { + PlanarRGBData rotatedImg(height, width); // New image, rotated + + for (int ny=0; ny rotatedImg(height, width); // New image, rotated + + for (int nx=0; nx32 && height>50; + #pragma omp parallel for schedule(static) if(bigImage) + #endif + for (int i=0; i + void resizeImgTo (int nw, int nh, TypeInterpolation interp, IC *imgPtr) { + //printf("resizeImgTo: resizing %s image data (%d x %d) to %s (%d x %d)\n", getType(), width, height, imgPtr->getType(), imgPtr->width, imgPtr->height); + if (width==nw && height==nh) { + // special case where no resizing is necessary, just type conversion.... + for (int i=0; ir(i,j)); + convertTo(g(i,j), imgPtr->g(i,j)); + convertTo(b(i,j), imgPtr->b(i,j)); + } + } + } + else if (interp == TI_Nearest) { + for (int i=0; ir(i,j)); + convertTo(g(ri,ci), imgPtr->g(i,j)); + convertTo(b(ri,ci), imgPtr->b(i,j)); + } + } + } + else if (interp == TI_Bilinear) { + for (int i=0; i=height) sy = height-1; + float dy = float(i)*float(height)/float(nh) - float(sy); + int ny = sy+1; + if (ny>=height) ny = sy; + for (int j=0; j=width) sx = width; + float dx = float(j)*float(width)/float(nw) - float(sx); + int nx = sx+1; + if (nx>=width) nx = sx; + convertTo(r(sy,sx)*(1.f-dx)*(1.f-dy) + r(sy,nx)*dx*(1.f-dy) + r(ny,sx)*(1.f-dx)*dy + r(ny,nx)*dx*dy, imgPtr->r(i,j)); + convertTo(g(sy,sx)*(1.f-dx)*(1.f-dy) + g(sy,nx)*dx*(1.f-dy) + g(ny,sx)*(1.f-dx)*dy + g(ny,nx)*dx*dy, imgPtr->g(i,j)); + convertTo(b(sy,sx)*(1.f-dx)*(1.f-dy) + b(sy,nx)*dx*(1.f-dy) + b(ny,sx)*(1.f-dx)*dy + b(ny,nx)*dx*dy, imgPtr->b(i,j)); + } + } + } + else { + // This case should never occur! + for (int i=0; i32 && height>50; + #pragma omp parallel for schedule(static) if(bigImage) + #endif + for (int i=0; i32 && height>50; + #pragma omp parallel for schedule(static) if(bigImage) + #endif + for (int i=0; i>histcompr); + histogram.clear(); + + for (int i=0; i(r(i,j), r_); + convertTo(g(i,j), g_); + convertTo(b(i,j), b_); + histogram[(int)Color::igamma_srgb (r_)>>histcompr]++; + histogram[(int)Color::igamma_srgb (g_)>>histcompr]++; + histogram[(int)Color::igamma_srgb (b_)>>histcompr]++; + } + } + + void computeHistogramAutoWB (double &avg_r, double &avg_g, double &avg_b, int &n, LUTu &histogram, const int compression) { + histogram.clear(); + avg_r = avg_g = avg_b = 0.; + n=0; + for (unsigned int i=0; i<(unsigned int)(height); i++) + for (unsigned int j=0; j<(unsigned int)(width); j++) { + float r_, g_, b_; + convertTo(r(i,j), r_); + convertTo(g(i,j), g_); + convertTo(b(i,j), b_); + int rtemp = Color::igamma_srgb (r_); + int gtemp = Color::igamma_srgb (g_); + int btemp = Color::igamma_srgb (b_); + + histogram[rtemp>>compression]++; + histogram[gtemp>>compression]+=2; + histogram[btemp>>compression]++; + + // autowb computation + if (r_>64000.f || g_>64000.f || b_>64000.f) continue; + avg_r += double(r_); + avg_g += double(g_); + avg_b += double(b_); + n++; + } + } + + void getAutoWBMultipliers (double &rm, double &gm, double &bm) { + + double avg_r = 0.; + double avg_g = 0.; + double avg_b = 0.; + int n = 0; + //int p = 6; + + for (unsigned int i=0; i<(unsigned int)(height); i++) + for (unsigned int j=0; j<(unsigned int)(width); j++) { + float r_, g_, b_; + convertTo(r(i,j), r_); + convertTo(g(i,j), g_); + convertTo(b(i,j), b_); + + if (r_>64000.f || g_>64000.f || b_>64000.f) continue; + avg_r += double(r_); + avg_g += double(g_); + avg_b += double(b_); + /*avg_r += intpow( (double)r(i, j), p); + avg_g += intpow( (double)g(i, j), p); + avg_b += intpow( (double)b(i, j), p);*/ + n++; + } + rm = avg_r/double(n); + gm = avg_g/double(n); + bm = avg_b/double(n); + } + + void transformPixel (int x, int y, int tran, int& tx, int& ty) { + + if (!tran) { + tx = x; + ty = y; + return; + } + int W = width; + int H = height; + int sw = W, sh = H; + if ((tran & TR_ROT) == TR_R90 || (tran & TR_ROT) == TR_R270) { + sw = H; + sh = W; + } + + int ppx = x, ppy = y; + if (tran & TR_HFLIP) + ppx = sw - 1 - x; + if (tran & TR_VFLIP) + ppy = sh - 1 - y; + + tx = ppx; + ty = ppy; + + if ((tran & TR_ROT) == TR_R180) { + tx = W - 1 - ppx; + ty = H - 1 - ppy; + } + else if ((tran & TR_ROT) == TR_R90) { + tx = ppy; + ty = H - 1 - ppx; + } + else if ((tran & TR_ROT) == TR_R270) { + tx = W - 1 - ppy; + ty = ppx; + } + } + + virtual void getSpotWBData (double &reds, double &greens, double &blues, int &rn, int &gn, int &bn, + std::vector &red, std::vector &green, std::vector &blue, + int tran) + { + int x; int y; + reds = 0, greens = 0, blues = 0; + rn = 0, gn = 0, bn = 0; + for (size_t i=0; i=0 && y>=0 && x(this->r(y, x), v); + reds += double(v); + rn++; + } + transformPixel (green[i].x, green[i].y, tran, x, y); + if (x>=0 && y>=0 && x(this->g(y, x), v); + greens += double(v); + gn++; + } + transformPixel (blue[i].x, blue[i].y, tran, x, y); + if (x>=0 && y>=0 && x(this->b(y, x), v); + blues += double(v); + bn++; + } + } + } + + void getPipetteData (T &valueR, T &valueG, T &valueB, int posX, int posY, int squareSize, int tran) + { + int x; int y; + float accumulatorR = 0.f; // using float to avoid range overflow; -> please creates specialization if necessary + float accumulatorG = 0.f; // " + float accumulatorB = 0.f; // " + unsigned long int n = 0; + int halfSquare = squareSize/2; + transformPixel (posX, posY, tran, x, y); + for (int iy=y-halfSquare; iy=0 && iy>=0 && ixr(iy, ix)); + accumulatorG += float(this->g(iy, ix)); + accumulatorB += float(this->b(iy, ix)); + ++n; + } + } + } + valueR = n ? T(accumulatorR/float(n)) : T(0); + valueG = n ? T(accumulatorG/float(n)) : T(0); + valueB = n ? T(accumulatorB/float(n)) : T(0); + } + + void readData (FILE *f) { + for (int i=0; i + class ChunkyPtr { + private: + T* ptr; + int width; + public: + #if CHECK_BOUNDS + int width_, height_; + #endif + +#if CHECK_BOUNDS + ChunkyPtr() : ptr (NULL), width(-1), width_(0), height_(0) {} +#else + ChunkyPtr() : ptr (NULL), width(-1) {} +#endif + void init(T* base, int w=-1) { ptr = base; width=w; } + void swap (ChunkyPtr &other) { + T* tmpsPtr = other.ptr; + other.ptr = ptr; + ptr = tmpsPtr; + + int tmpWidth = other.width; + other.width = width; + width = tmpWidth; + + #if CHECK_BOUNDS + int tmp = other.width_; + other.width_ = width_; + width_ = tmp; + tmp = other.height_; + other.height_ = height_; + height_ = tmp; + #endif + + } + + // Will send back the start of a row, starting with a red, green or blue value + T* operator() (unsigned row) const { + #if CHECK_BOUNDS + assert (row < height_); + #endif + return &ptr[3*(row*width)]; + } + // Will send back a value at a given row, col position + T& operator() (unsigned row, unsigned col) { + #if CHECK_BOUNDS + assert (row < height_ && col < width_); + #endif + return ptr[3*(row*width+col)]; + } + const T operator() (unsigned row, unsigned col) const { + #if CHECK_BOUNDS + assert (row < height_ && col < width_); + #endif + return ptr[3*(row*width+col)]; + } + }; + + template + class ChunkyRGBData : virtual public ImageDatas { + + private: + AlignedBuffer abData; + + public: + T* data; + ChunkyPtr r; + ChunkyPtr g; + ChunkyPtr b; + + ChunkyRGBData() : data (NULL) {} + ChunkyRGBData(int w, int h) : data (NULL) { + allocate(w, h); + } + + /** Returns the pixel data, in r/g/b order from top left to bottom right continuously. + * @return a pointer to the pixel data */ + const T* getData () { return data; } + + void swap(ChunkyRGBData &other) { + abData.swap(other.abData); + r.swap(other.r); + g.swap(other.g); + b.swap(other.b); + T* tmpData = other.data; + other.data = data; + data = tmpData; + int tmpWidth = other.width; + other.width = width; + width = tmpWidth; + int tmpHeight = other.height; + other.height = height; + height = tmpHeight; + #if CHECK_BOUNDS + r.width_ = width; r.height_ = height; + g.width_ = width; g.height_ = height; + b.width_ = width; b.height_ = height; + #endif + } + + /* + * If any of the required allocation fails, "width" and "height" are set to -1, and all remaining buffer are freed + * Can be safely used to reallocate an existing image or to free up it's memory with "allocate (0,0);" + */ + void allocate (int W, int H) { + + if (W==width && H==height) + return; + + width=W; + height=H; + #if CHECK_BOUNDS + r.width_ = width; r.height_ = height; + g.width_ = width; g.height_ = height; + b.width_ = width; b.height_ = height; + #endif + + abData.resize(width*height*3); + if (!abData.isEmpty()) { + data = abData.data; + r.init(data, width); + g.init(data+1, width); + b.init(data+2, width); + } + else { + data = NULL; + r.init(NULL); + g.init(NULL); + b.init(NULL); + width = height = -1; + #if CHECK_BOUNDS + r.width_ = r.height_ = -1; + g.width_ = g.height_ = -1; + b.width_ = b.height_ = -1; + #endif + } + } + + /** Copy the data to another ChunkyRGBData */ + void copyData(ChunkyRGBData *dest) { + assert (dest!=NULL); + // Make sure that the size is the same, reallocate if necessary + dest->allocate(width, height); + if (dest->width == -1) { + printf("ERROR: ChunkyRGBData::copyData >>> allocation failed!\n"); + return; + } + memcpy (dest->data, data, 3*width*height*sizeof(T)); + } + + void rotate (int deg) { + + if (deg==90) { + ChunkyRGBData rotatedImg(height, width); // New image, rotated + + for (int ny=0; ny rotatedImg(height, width); // New image, rotated + + for (int nx=0; nx + void resizeImgTo (int nw, int nh, TypeInterpolation interp, IC *imgPtr) { + //printf("resizeImgTo: resizing %s image data (%d x %d) to %s (%d x %d)\n", getType(), width, height, imgPtr->getType(), imgPtr->width, imgPtr->height); + if (width==nw && height==nh) { + // special case where no resizing is necessary, just type conversion.... + for (int i=0; ir(i,j)); + convertTo(g(i,j), imgPtr->g(i,j)); + convertTo(b(i,j), imgPtr->b(i,j)); + } + } + } + else if (interp == TI_Nearest) { + for (int i=0; ir(i,j)); + convertTo(g(ri,ci), imgPtr->g(i,j)); + convertTo(b(ri,ci), imgPtr->b(i,j)); + } + } + } + else if (interp == TI_Bilinear) { + for (int i=0; i=height) sy = height-1; + float dy = float(i)*float(height)/float(nh) - float(sy); + int ny = sy+1; + if (ny>=height) ny = sy; + for (int j=0; j=width) sx = width; + float dx = float(j)*float(width)/float(nw) - float(sx); + int nx = sx+1; + if (nx>=width) nx = sx; + T valR = r(sy,sx)*(1.f-dx)*(1.f-dy) + r(sy,nx)*dx*(1.f-dy) + r(ny,sx)*(1.f-dx)*dy + r(ny,nx)*dx*dy; + T valG = g(sy,sx)*(1.f-dx)*(1.f-dy) + g(sy,nx)*dx*(1.f-dy) + g(ny,sx)*(1.f-dx)*dy + g(ny,nx)*dx*dy; + T valB = b(sy,sx)*(1.f-dx)*(1.f-dy) + b(sy,nx)*dx*(1.f-dy) + b(ny,sx)*(1.f-dx)*dy + b(ny,nx)*dx*dy; + convertTo(valR, imgPtr->r(i,j)); + convertTo(valG, imgPtr->g(i,j)); + convertTo(valB, imgPtr->b(i,j)); + } + } + } + else { + // This case should never occur! + for (int i=0; i lBuffer(3*width); + T* lineBuffer = lBuffer.data; + size_t size = 3*width*sizeof(T); + for (int i=0; i>histcompr); + histogram.clear(); + + for (int i=0; i(r(i,j), r_); + convertTo(g(i,j), g_); + convertTo(b(i,j), b_); + histogram[(int)Color::igamma_srgb (r_)>>histcompr]++; + histogram[(int)Color::igamma_srgb (g_)>>histcompr]++; + histogram[(int)Color::igamma_srgb (b_)>>histcompr]++; + } + } + + void computeHistogramAutoWB (double &avg_r, double &avg_g, double &avg_b, int &n, LUTu &histogram, const int compression) { + histogram.clear(); + avg_r = avg_g = avg_b = 0.; + n=0; + for (unsigned int i=0; i<(unsigned int)(height); i++) + for (unsigned int j=0; j<(unsigned int)(width); j++) { + float r_, g_, b_; + convertTo(r(i,j), r_); + convertTo(g(i,j), g_); + convertTo(b(i,j), b_); + int rtemp = Color::igamma_srgb (r_); + int gtemp = Color::igamma_srgb (g_); + int btemp = Color::igamma_srgb (b_); + + histogram[rtemp>>compression]++; + histogram[gtemp>>compression]+=2; + histogram[btemp>>compression]++; + + // autowb computation + if (r_>64000.f || g_>64000.f || b_>64000.f) continue; + avg_r += double(r_); + avg_g += double(g_); + avg_b += double(b_); + n++; + } + } + + void getAutoWBMultipliers (double &rm, double &gm, double &bm) { + + double avg_r = 0.; + double avg_g = 0.; + double avg_b = 0.; + int n = 0; + //int p = 6; + + for (unsigned int i=0; i<(unsigned int)(height); i++) + for (unsigned int j=0; j<(unsigned int)(width); j++) { + float r_, g_, b_; + convertTo(r(i,j), r_); + convertTo(g(i,j), g_); + convertTo(b(i,j), b_); + + if (r_>64000.f || g_>64000.f || b_>64000.f) continue; + avg_r += double(r_); + avg_g += double(g_); + avg_b += double(b_); + /*avg_r += intpow( (double)r(i, j), p); + avg_g += intpow( (double)g(i, j), p); + avg_b += intpow( (double)b(i, j), p);*/ + n++; + } + rm = avg_r/double(n); + gm = avg_g/double(n); + bm = avg_b/double(n); + } + + void transformPixel (int x, int y, int tran, int& tx, int& ty) { + + if (!tran) { + tx = x; + ty = y; + return; + } + int W = width; + int H = height; + int sw = W, sh = H; + if ((tran & TR_ROT) == TR_R90 || (tran & TR_ROT) == TR_R270) { + sw = H; + sh = W; + } + + int ppx = x, ppy = y; + if (tran & TR_HFLIP) + ppx = sw - 1 - x; + if (tran & TR_VFLIP) + ppy = sh - 1 - y; + + tx = ppx; + ty = ppy; + + if ((tran & TR_ROT) == TR_R180) { + tx = W - 1 - ppx; + ty = H - 1 - ppy; + } + else if ((tran & TR_ROT) == TR_R90) { + tx = ppy; + ty = H - 1 - ppx; + } + else if ((tran & TR_ROT) == TR_R270) { + tx = W - 1 - ppy; + ty = ppx; + } + } + + virtual void getSpotWBData (double &reds, double &greens, double &blues, int &rn, int &gn, int &bn, + std::vector &red, std::vector &green, std::vector &blue, + int tran) + { + int x; int y; + reds = 0, greens = 0, blues = 0; + rn = 0, gn = 0, bn = 0; + for (size_t i=0; i=0 && y>=0 && x(this->r(y, x), v); + reds += double(v); + rn++; + } + transformPixel (green[i].x, green[i].y, tran, x, y); + if (x>=0 && y>=0 && x(this->g(y, x), v); + greens += double(v); + gn++; + } + transformPixel (blue[i].x, blue[i].y, tran, x, y); + if (x>=0 && y>=0 && x(this->b(y, x), v); + blues += double(v); + bn++; + } + } + } + + void readData (FILE *f) { + for (int i=0; i { + public: + virtual ~IImagefloat() {} + }; + + /** @brief This class represents an image having a classical 8 bits/pixel representation */ + class IImage8 : public IImage, public ChunkyRGBData { + public: + virtual ~IImage8() {} + }; + + /** @brief This class represents an image having a 16 bits/pixel planar representation. + The planes are stored as two dimensional arrays. All the rows have a 128 bits alignment. */ + class IImage16 : public IImage, public PlanarRGBData { + public: + virtual ~IImage16() {} + }; + +} + +#endif diff --git a/rtengine/image16.cc b/rtengine/image16.cc new file mode 100644 index 000000000..b62ad1d91 --- /dev/null +++ b/rtengine/image16.cc @@ -0,0 +1,327 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "image16.h" +#include "imagefloat.h" +#include "image8.h" +#include +#include +#include "rtengine.h" + +using namespace rtengine; + +Image16::Image16 () { +} + +Image16::Image16 (int w, int h) { + allocate (w, h); +} + +Image16::~Image16 () { +} + +void Image16::getScanline (int row, unsigned char* buffer, int bps) { + + if (data==NULL) + return; + + if (bps==16) { + int ix = 0; + unsigned short* sbuffer = (unsigned short*) buffer; + for (int i=0; i> 8; + buffer[ix++] = g(row,i) >> 8; + buffer[ix++] = b(row,i) >> 8; + } + } +} + +/* + * void Image16::setScanline (int row, unsigned char* buffer, int bps, int minValue[3], int maxValue[3]); + * has not been implemented yet, because as of now, this method is called for IIOSF_FLOAT sample format only + */ +void Image16::setScanline (int row, unsigned char* buffer, int bps, float *minValue, float *maxValue) { + + if (data==NULL) + return; + + // For optimization purpose, we're assuming that this class never have to provide min/max bound + assert(!minValue); + + switch (sampleFormat) { + case (IIOSF_UNSIGNED_CHAR): + { + int ix = 0; + for (int i=0; iwidth; // Destination image + int imheight=image->height; // Destination image + if (((tran & TR_ROT) == TR_R90)||((tran & TR_ROT) == TR_R270)) { + int swap = imwidth; + imwidth=imheight; + imheight=swap; + } + int maxx=width; // Source image + int maxy=height; // Source image + int mtran = tran & TR_ROT; + int skip = pp.skip; + + //if ((sx1 + skip*imwidth)>maxx) imwidth -- ; // we have a boundary condition that can cause errors + + // improve speed by integrating the area division into the multipliers + // switched to using ints for the red/green/blue channel buffer. + // Incidentally this improves accuracy too. + float area=skip*skip; + float rm2=rm; + float gm2=gm; + float bm2=bm; + rm/=area; + gm/=area; + bm/=area; + + #define GCLIP( x ) Color::gamma_srgb(CLIP(x)) + +#ifdef _OPENMP +#pragma omp parallel + { +#endif + AlignedBuffer abR(imwidth); + AlignedBuffer abG(imwidth); + AlignedBuffer abB(imwidth); + float *lineR = abR.data; + float *lineG = abG.data; + float *lineB = abB.data; + +#ifdef _OPENMP +#pragma omp for +#endif + // Iterating all the rows of the destination image + for (int iy=0; iy=maxy) + continue; + + for (int dst_x=0,src_x=sx1; dst_x=maxx) + continue; + + lineR[dst_x] = CLIP(rm2*r(src_y, src_x)); + lineG[dst_x] = CLIP(gm2*g(src_y, src_x)); + lineB[dst_x] = CLIP(bm2*b(src_y, src_x)); + } + } + else { + // source image, first line of the current destination row + int src_y=sy1+skip*iy; + if (src_y>=maxy) + continue; + + for (int dst_x=0,src_x=sx1; dst_x=maxx) + continue; + + int src_sub_width = MIN(maxx-src_x, skip); + int src_sub_height = MIN(maxy-src_y, skip); + + float rtot,gtot,btot; // RGB accumulators + rtot=gtot=btot=0.; + + for (int src_sub_y=0; src_sub_yr(iy, dst_x) = lineR[dst_x]; + image->g(iy, dst_x) = lineG[dst_x]; + image->b(iy, dst_x) = lineB[dst_x]; + } + else if (mtran == TR_R180) + for (int dst_x=0; dst_xr(imheight-1-iy, imwidth-1-dst_x) = lineR[dst_x]; + image->g(imheight-1-iy, imwidth-1-dst_x) = lineG[dst_x]; + image->b(imheight-1-iy, imwidth-1-dst_x) = lineB[dst_x]; + } + else if (mtran == TR_R90) + for (int dst_x=0,src_x=sx1; dst_xr(dst_x, imheight-1-iy) = lineR[dst_x]; + image->g(dst_x, imheight-1-iy) = lineG[dst_x]; + image->b(dst_x, imheight-1-iy) = lineB[dst_x]; + } + else if (mtran == TR_R270) + for (int dst_x=0,src_x=sx1; dst_xr(imwidth-1-dst_x, iy) = lineR[dst_x]; + image->g(imwidth-1-dst_x, iy) = lineG[dst_x]; + image->b(imwidth-1-dst_x, iy) = lineB[dst_x]; + } + } +#ifdef _OPENMP +} +#endif + #undef GCLIP +} + +Image8* +Image16::to8() +{ + Image8* img8 = new Image8(width,height); + for ( int h = 0; h < height; ++h ) + { + for ( int w = 0; w < width; ++w ) + { + img8->r(h, w) = (unsigned char)( r(h,w) >> 8); + img8->g(h, w) = (unsigned char)( g(h,w) >> 8); + img8->b(h, w) = (unsigned char)( b(h,w) >> 8); + } + } + return img8; +} + +Imagefloat* +Image16::tofloat() +{ + Imagefloat* imgfloat = new Imagefloat(width,height); + for ( int h = 0; h < height; ++h ) + { + for ( int w = 0; w < width; ++w ) + { + imgfloat->r(h,w) = (float)r(h,w); + imgfloat->g(h,w) = (float)g(h,w); + imgfloat->b(h,w) = (float)b(h,w); + } + } + return imgfloat; +} + +// Parallized transformation; create transform with cmsFLAGS_NOCACHE! +void Image16::ExecCMSTransform(cmsHTRANSFORM hTransform) { + //cmsDoTransform(hTransform, data, data, planestride); + + // LittleCMS cannot parallelize planar setups -- Hombre: LCMS2.4 can! But it we use this new feature, memory allocation have to be modified too + // so build temporary buffers to allow multi processor execution +#ifdef _OPENMP +#pragma omp parallel +#endif +{ + AlignedBuffer buffer(width*3); + +#ifdef _OPENMP +#pragma omp for schedule(static) +#endif + for (int y=0; y + * + * 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 . + */ +// +// A class representing a 16 bit rgb image with separate planes and 16 byte aligned data +// +#ifndef _IMAGE16_ +#define _IMAGE16_ + +#include "imageio.h" +#include "rtengine.h" +#include "imagefloat.h" + +namespace rtengine { + +class Image8; + +class Image16 : public IImage16, public ImageIO { + + public: + + Image16 (); + Image16 (int width, int height); + ~Image16 (); + + Image16* copy (); + + Image8* to8(); + Imagefloat* tofloat(); + + virtual void getStdImage (ColorTemp ctemp, int tran, Imagefloat* image, PreviewProps pp, bool first, procparams::ToneCurveParams hrp); + + virtual const char* getType () const { return sImage16; } + virtual int getBPS () { return 8*sizeof(unsigned short); } + virtual void getScanline (int row, unsigned char* buffer, int bps); + virtual void setScanline (int row, unsigned char* buffer, int bps, float *minValue=NULL, float *maxValue=NULL); + + // functions inherited from IImage16: + virtual MyMutex& getMutex () { return mutex (); } + virtual cmsHPROFILE getProfile () { return getEmbeddedProfile (); } + virtual int getBitsPerPixel () { return 8*sizeof(unsigned short); } + virtual int saveToFile (Glib::ustring fname) { return save (fname); } + virtual int saveAsPNG (Glib::ustring fname, int compression = -1, int bps = -1) { return savePNG (fname, compression, bps); } + virtual int saveAsJPEG (Glib::ustring fname, int quality = 100, int subSamp = 3) { return saveJPEG (fname, quality, subSamp); } + virtual int saveAsTIFF (Glib::ustring fname, int bps = -1, bool uncompressed = false) { return saveTIFF (fname, bps, uncompressed); } + virtual void setSaveProgressListener (ProgressListener* pl) { setProgressListener (pl); } + virtual void free () { delete this; } + + void ExecCMSTransform(cmsHTRANSFORM hTransform); +}; + +} +#endif diff --git a/rtengine/image8.cc b/rtengine/image8.cc new file mode 100644 index 000000000..5fe91f217 --- /dev/null +++ b/rtengine/image8.cc @@ -0,0 +1,241 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "image8.h" +#include "rtengine.h" + +using namespace rtengine; + + +Image8::Image8 () { +} + +Image8::Image8 (int w, int h) { + allocate (w, h); +} + +Image8::~Image8 () { +} + +void Image8::getScanline (int row, unsigned char* buffer, int bps) { + + if (data==NULL) + return; + + if (bps==8) + memcpy (buffer, data + row*width*3, width*3); + else if (bps==16) { + unsigned short* sbuffer = (unsigned short*) buffer; + for (int i=0, ix = row*width*3; i> 8; + break; + } + default: + // Other type are ignored, but could be implemented if necessary + break; + } +} + +Image8* Image8::copy () { + + Image8* cp = new Image8 (width, height); + copyData(cp); + return cp; +} + +void Image8::getStdImage (ColorTemp ctemp, int tran, Imagefloat* image, PreviewProps pp, bool first, procparams::ToneCurveParams hrp) +{ + // compute channel multipliers + double drm, dgm, dbm; + ctemp.getMultipliers (drm, dgm, dbm); + float rm=drm,gm=dgm,bm=dbm; + + rm = 1.0 / rm; + gm = 1.0 / gm; + bm = 1.0 / bm; + float mul_lum = 0.299*rm + 0.587*gm + 0.114*bm; + rm /= mul_lum; + gm /= mul_lum; + bm /= mul_lum; + + int sx1, sy1, sx2, sy2; + + transform (pp, tran, sx1, sy1, sx2, sy2); + + int imwidth=image->width; // Destination image + int imheight=image->height; // Destination image + if (((tran & TR_ROT) == TR_R90)||((tran & TR_ROT) == TR_R270)) { + int swap = imwidth; + imwidth=imheight; + imheight=swap; + } + int maxx=width; // Source image + int maxy=height; // Source image + int mtran = tran & TR_ROT; + int skip = pp.skip; + + //if ((sx1 + skip*imwidth)>maxx) imwidth -- ; // we have a boundary condition that can cause errors + + // improve speed by integrating the area division into the multipliers + // switched to using ints for the red/green/blue channel buffer. + // Incidentally this improves accuracy too. + float area=skip*skip; + float rm2=rm; + float gm2=gm; + float bm2=bm; + rm/=area; + gm/=area; + bm/=area; + + #define GCLIP( x ) Color::gamma_srgb(CLIP(x)) + +#ifdef _OPENMP +#pragma omp parallel + { +#endif + AlignedBuffer abR(imwidth); + AlignedBuffer abG(imwidth); + AlignedBuffer abB(imwidth); + float *lineR = abR.data; + float *lineG = abG.data; + float *lineB = abB.data; + +#ifdef _OPENMP +#pragma omp for +#endif + // Iterating all the rows of the destination image + for (int iy=0; iy=maxy) + continue; + + for (int dst_x=0,src_x=sx1; dst_x=maxx) + continue; + + convertTo(r(src_y, src_x), r_); + convertTo(g(src_y, src_x), g_); + convertTo(b(src_y, src_x), b_); + lineR[dst_x] = CLIP(rm2*r_); + lineG[dst_x] = CLIP(gm2*g_); + lineB[dst_x] = CLIP(bm2*b_); + } + } + else { + // source image, first line of the current destination row + int src_y=sy1+skip*iy; + if (src_y>=maxy) + continue; + + for (int dst_x=0,src_x=sx1; dst_x=maxx) + continue; + + int src_sub_width = MIN(maxx-src_x, skip); + int src_sub_height = MIN(maxy-src_y, skip); + + float rtot,gtot,btot; // RGB accumulators + rtot=gtot=btot=0.; + + for (int src_sub_y=0; src_sub_yr(iy, dst_x) = lineR[dst_x]; + image->g(iy, dst_x) = lineG[dst_x]; + image->b(iy, dst_x) = lineB[dst_x]; + } + else if (mtran == TR_R180) + for (int dst_x=0; dst_xr(imheight-1-iy, imwidth-1-dst_x) = lineR[dst_x]; + image->g(imheight-1-iy, imwidth-1-dst_x) = lineG[dst_x]; + image->b(imheight-1-iy, imwidth-1-dst_x) = lineB[dst_x]; + } + else if (mtran == TR_R90) + for (int dst_x=0,src_x=sx1; dst_xr(dst_x, imheight-1-iy) = lineR[dst_x]; + image->g(dst_x, imheight-1-iy) = lineG[dst_x]; + image->b(dst_x, imheight-1-iy) = lineB[dst_x]; + } + else if (mtran == TR_R270) + for (int dst_x=0,src_x=sx1; dst_xr(imwidth-1-dst_x, iy) = lineR[dst_x]; + image->g(imwidth-1-dst_x, iy) = lineG[dst_x]; + image->b(imwidth-1-dst_x, iy) = lineB[dst_x]; + } + } +#ifdef _OPENMP +} +#endif + #undef GCLIP +} diff --git a/rtengine/image8.h b/rtengine/image8.h new file mode 100644 index 000000000..9394d2f3f --- /dev/null +++ b/rtengine/image8.h @@ -0,0 +1,62 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +// +// A class representing a 8 bit rgb image without alpha channel +// +#ifndef _IMAGE8_ +#define _IMAGE8_ + +#include "imageio.h" +#include "rtengine.h" +#include "imagefloat.h" + +namespace rtengine { + +class Image8 : public IImage8, public ImageIO { + + public: + + Image8 (); + Image8 (int width, int height); + ~Image8 (); + + Image8* copy (); + + virtual void getStdImage (ColorTemp ctemp, int tran, Imagefloat* image, PreviewProps pp, bool first, procparams::ToneCurveParams hrp); + + virtual const char* getType () const { return sImage8; } + virtual int getBPS () { return 8*sizeof(unsigned char); } + virtual void getScanline (int row, unsigned char* buffer, int bps); + virtual void setScanline (int row, unsigned char* buffer, int bps, float *minValue=NULL, float *maxValue=NULL); + + // functions inherited from IImage*: + virtual MyMutex& getMutex () { return mutex (); } + virtual cmsHPROFILE getProfile () { return getEmbeddedProfile (); } + virtual int getBitsPerPixel () { return 8*sizeof(unsigned char); } + virtual int saveToFile (Glib::ustring fname) { return save (fname); } + virtual int saveAsPNG (Glib::ustring fname, int compression = -1, int bps = -1) { return savePNG (fname, compression, bps); } + virtual int saveAsJPEG (Glib::ustring fname, int quality = 100, int subSamp = 3) { return saveJPEG (fname, quality, subSamp); } + virtual int saveAsTIFF (Glib::ustring fname, int bps = -1, bool uncompressed = false) { return saveTIFF (fname, bps, uncompressed); } + virtual void setSaveProgressListener (ProgressListener* pl) { setProgressListener (pl); } + virtual void free () { delete this; } + +}; + +} +#endif diff --git a/rtengine/imagedata.cc b/rtengine/imagedata.cc new file mode 100644 index 000000000..1b6a770a0 --- /dev/null +++ b/rtengine/imagedata.cc @@ -0,0 +1,504 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "imagedata.h" +#include "iptcpairs.h" +#include +#include "safegtk.h" + +#ifndef GLIBMM_EXCEPTIONS_ENABLED +#include +#endif + +using namespace rtengine; + +extern "C" IptcData *iptc_data_new_from_jpeg_file (FILE* infile); + +ImageMetaData* ImageMetaData::fromFile (const Glib::ustring& fname, RawMetaDataLocation* rml) { + + return new ImageData (fname, rml); +} + +ImageData::ImageData (Glib::ustring fname, RawMetaDataLocation* ri) { + + size_t dotpos = fname.find_last_of ('.'); + root = NULL; + iptc = NULL; + + if (ri && (ri->exifBase>=0 || ri->ciffBase>=0)) { + FILE* f = safe_g_fopen (fname, "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 ((dotposgetTag (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; + memset (&time, 0, sizeof(time)); + } +} + +void ImageData::extractInfo () { + + if (!root) + return; + + make = ""; + model = ""; + serial = ""; + orientation = ""; + expcomp = 0; + shutter = 0; + aperture = 0; + focal_len = focal_len35mm = 0; + focus_dist = 0; + iso_speed = 0; + memset (&time, 0, sizeof(time)); + timeStamp = 0; + + if (root->getTag ("Make")){ + make = root->getTag ("Make")->valueToString (); + // same dcraw treatment + static const char *corp[] = + { "Canon", "NIKON", "EPSON", "KODAK", "Kodak", "OLYMPUS", "PENTAX", "RICOH", + "MINOLTA", "Minolta", "Konica", "CASIO", "Sinar", "Phase One", + "SAMSUNG", "Mamiya", "MOTOROLA", "Leaf" }; + for (size_t i=0; i < (sizeof(corp)/sizeof(*corp)); i++) + if ( make.find( corp[i] ) != std::string::npos ){ /* Simplify company names */ + make = corp[i]; + break; + } + make.erase( make.find_last_not_of(' ')+1 ); + } + + if (root->getTag ("Model")) + model = root->getTag ("Model")->valueToString (); + if (!(model.size()==0)) { + std::size_t i=0; + if ( make.find("KODAK") != std::string::npos ){ + if( (i = model.find(" DIGITAL CAMERA")) != std::string::npos || + (i = model.find(" Digital Camera")) != std::string::npos || + (i = model.find("FILE VERSION")) ) + model.resize( i ); + } + + model.erase( model.find_last_not_of(' ')+1 ); + + //if( (i=model.find( make )) != std::string::npos ) + if( !strncasecmp (model.c_str(), make.c_str(), make.size()) ) + if( model.at( make.size() )==' ') + model.erase(0,make.size()+1); + if( model.find( "Digital Camera ") != std::string::npos ) + model.erase(0,15); + } + else { + model = "Unknown"; + } + if (root->getTag ("Orientation")){ + orientation = root->getTag ("Orientation")->valueToString (); + } + + rtexif::TagDirectory* exif = NULL; + if (root->getTag ("Exif")) + exif = root->getTag ("Exif")->getDirectory (); + + if (exif) { + + // standard exif tags + if (exif->getTag ("ShutterSpeedValue")) + shutter = exif->getTag ("ShutterSpeedValue")->toDouble (); + if (exif->getTag ("ExposureTime")) + shutter = exif->getTag ("ExposureTime")->toDouble (); + if (exif->getTag ("ApertureValue")) + aperture = exif->getTag ("ApertureValue")->toDouble (); + if (exif->getTag ("FNumber")) + aperture = exif->getTag ("FNumber")->toDouble (); + if (exif->getTag ("ExposureBiasValue")) + expcomp = exif->getTag ("ExposureBiasValue")->toDouble (); + if (exif->getTag ("FocalLength")) + focal_len = exif->getTag ("FocalLength")->toDouble (); + if (exif->getTag ("FocalLengthIn35mmFilm")) + focal_len35mm = exif->getTag ("FocalLengthIn35mmFilm")->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"); + if (pDst) { + int num, denom; + pDst->toRational(num,denom); + } else { + // Second try, XMP data + char sXMPVal[64]; + if (root->getXMPTagValue("aux:ApproximateFocusDistance",sXMPVal)) { sscanf(sXMPVal,"%d/%d",&num,&denom); } + } + + if (num!=-3) { + if ((denom==1 && num>=10000) || num<0 || denom<0) + focus_dist=10000; // infinity + else if (denom>0) { + focus_dist=(float)num/denom; + } + } + + if (exif->getTag ("ISOSpeedRatings")) + iso_speed = exif->getTag ("ISOSpeedRatings")->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) { + time.tm_year -= 1900; + time.tm_mon -= 1; + time.tm_isdst = -1; + timeStamp = mktime(&time); + } + } + rtexif::Tag *snTag = exif->findTag ("SerialNumber"); + if(!snTag) + snTag = exif->findTag ("InternalSerialNumber"); + if ( snTag ) + serial = snTag->valueToString(); + // guess lens... + lens = "Unknown"; + + // Sometimes (e.g. DNG) EXIF already contains lens data + + if(!make.compare (0, 8, "FUJIFILM")) { + if(exif->getTag ("LensModel")) { + lens = exif->getTag ("LensModel")->valueToString (); + } + } else if (root->findTag("MakerNote")) { + rtexif::TagDirectory* mnote = root->findTag("MakerNote")->getDirectory(); + if (mnote && !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"); + if (isoTag) + iso_speed = isoTag->toInt(); + } + bool lensOk = false; + if (mnote->getTag ("LensData")) { + std::string ldata = mnote->getTag ("LensData")->valueToString (); + int pos; + if (ldata.size()>10 && (pos=ldata.find ("Lens = "))!=Glib::ustring::npos) { + lens = ldata.substr (pos + 7); + if (lens.compare (0, 7, "Unknown")) + lensOk = true; + else { + int pos = lens.find("$FL$"); // is there a placeholder for focallength? + if(pos != Glib::ustring::npos) { // then fill in focallength + lens = lens.replace(pos,4,exif->getTag ("FocalLength")->valueToString ()); + if(mnote->getTag ("LensType")) { + std::string ltype = mnote->getTag ("LensType")->valueToString (); + if(ltype.find("MF = Yes")!=Glib::ustring::npos) // check, whether it's a MF lens, should be always + lens = lens.replace(0,7,"MF"); + lensOk = true; + } + } + } + } + } + if (!lensOk && mnote->getTag ("Lens")) { + std::string ldata = mnote->getTag ("Lens")->valueToString (); + size_t i=0, j=0; + double n[4]; + for (int m=0; m<4; m++) { + while (igetTag ("LensType")) { + std::string ltype = mnote->getTag ("LensType")->valueToString (); + if(ltype.find("MF = Yes")!=Glib::ustring::npos) // check, whether it's a MF lens + lens = lens.replace(0,7,"MF"); // replace 'Unknwon' with 'MF' + else + lens = lens.replace(0,7,"AF"); // replace 'Unknwon' with 'AF' + } + } + } + else if (mnote && !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"); + if (baseIsoTag) + iso_speed = baseIsoTag->toInt(); + } + int found=false; + // canon EXIF have a string for lens model + rtexif::Tag *lt = mnote->getTag("LensType"); + if ( lt ) { + std::string ldata = lt->valueToString (); + if (ldata.size()>1) { + found=true; + lens = "Canon " + ldata; + } + } + if( !found || lens.substr(lens.find(' ')).length() < 7 ){ + lt = mnote->findTag("LensID"); + if ( lt ) { + std::string ldata = lt->valueToString (); + if (ldata.size()>1) { + lens = ldata; + } + } + } + } + else if (mnote && (!make.compare (0, 6, "PENTAX") || (!make.compare (0, 5, "RICOH") && !model.compare (0, 6, "PENTAX")))) { + if (mnote->getTag ("LensType")) + lens = mnote->getTag ("LensType")->valueToString (); + + // Try to get the FocalLength from the LensInfo structure, where length below 10mm will be correctly set + rtexif::Tag* flt=mnote->getTagP ("LensInfo/FocalLength"); + if (flt) + focal_len = flt->toDouble (); + else if ((flt = mnote->getTagP ("FocalLength"))) { + rtexif::Tag* flt = mnote->getTag ("FocalLength"); + focal_len = flt->toDouble (); + } + + if (mnote->getTag ("FocalLengthIn35mmFilm")) + focal_len35mm = mnote->getTag ("FocalLengthIn35mmFilm")->toDouble (); + } + else if (mnote && (!make.compare (0, 4, "SONY") || !make.compare (0, 6, "KONICA"))) { + if (mnote->getTag ("LensID")) + lens = mnote->getTag ("LensID")->valueToString (); + } + else if (mnote && !make.compare (0, 7, "OLYMPUS")) { + if (mnote->getTag ("Equipment")) { + rtexif::TagDirectory* eq = mnote->getTag ("Equipment")->getDirectory (); + if (eq->getTag ("LensType")) + lens = eq->getTag ("LensType")->valueToString (); + } + } + } else if (exif->getTag ("DNGLensInfo")) { + lens = exif->getTag ("DNGLensInfo")->valueToString (); + } else if (exif->getTag ("LensModel")) { + lens = exif->getTag ("LensModel")->valueToString (); + } else if (exif->getTag ("LensInfo")) { + lens = exif->getTag ("LensInfo")->valueToString (); + } + } +} + +ImageData::~ImageData () { + + delete root; + if (iptc) + iptc_data_free (iptc); +} + +const procparams::IPTCPairs ImageData::getIPTCData () const { + + procparams::IPTCPairs iptcc; + if (!iptc) + return iptcc; + + unsigned char buffer[2100]; + for (int i=0; i<16; i++) { + IptcDataSet* ds = iptc_data_get_next_dataset (iptc, NULL, IPTC_RECORD_APP_2, strTags[i].tag); + if (ds) { + iptc_dataset_get_data (ds, buffer, 2100); + std::vector icValues; + icValues.push_back (safe_locale_to_utf8((char*)buffer)); + + iptcc[strTags[i].field] = icValues; + iptc_dataset_unref (ds); + } + } + IptcDataSet* ds = NULL; + std::vector 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 (safe_locale_to_utf8((char*)buffer)); + } + iptcc["Keywords"] = keywords; + ds = NULL; + std::vector suppCategories; + 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 (safe_locale_to_utf8((char*)buffer)); + iptc_dataset_unref (ds); + } + iptcc["SupplementalCategories"] = suppCategories; + return iptcc; +} + +//------inherited functions--------------// + + +std::string ImageMetaData::apertureToString (double aperture) { + + char buffer[256]; + sprintf (buffer, "%0.1f", aperture); + return buffer; +} + +std::string ImageMetaData::shutterToString (double shutter) { + + char buffer[256]; + if (shutter > 0.0 && shutter < 0.9) + sprintf (buffer, "1/%0.0f", 1.0 / shutter); + else + sprintf (buffer, "%0.1f", shutter); + return buffer; +} + +std::string ImageMetaData::expcompToString (double expcomp, bool maskZeroexpcomp) { + + char buffer[256]; + if (maskZeroexpcomp==true){ + if (expcomp!=0.0){ + sprintf (buffer, "%0.2f", expcomp); + return buffer; + } + else + return ""; + } + else{ + sprintf (buffer, "%0.2f", expcomp); + return buffer; + } +} + +double ImageMetaData::shutterFromString (std::string s) { + + size_t i = s.find_first_of ('/'); + if (i==std::string::npos) + return atof (s.c_str()); + else + return atof (s.substr(0,i).c_str()) / atof (s.substr(i+1).c_str()); +} + +double ImageMetaData::apertureFromString (std::string s) { + + return atof (s.c_str()); +} + +extern "C" { + +#include +#include + +struct _IptcDataPrivate +{ + unsigned int ref_count; + + IptcLog *log; + IptcMem *mem; +}; + +IptcData * +iptc_data_new_from_jpeg_file (FILE *infile) +{ + IptcData *d; + unsigned char * buf; + int buf_len = 256*256; + int len, offset; + unsigned int iptc_len; + + if (!infile) + return NULL; + + d = iptc_data_new (); + if (!d) + return NULL; + + buf = (unsigned char*)iptc_mem_alloc (d->priv->mem, buf_len); + if (!buf) { + iptc_data_unref (d); + return NULL; + } + + len = iptc_jpeg_read_ps3 (infile, buf, buf_len); + + if (len <= 0) { + goto failure; + } + + offset = iptc_jpeg_ps3_find_iptc (buf, len, &iptc_len); + if (offset <= 0) { + goto failure; + } + + iptc_data_load (d, buf + offset, iptc_len); + + iptc_mem_free (d->priv->mem, buf); + return d; + +failure: + iptc_mem_free (d->priv->mem, buf); + iptc_data_unref (d); + return NULL; +} + +} diff --git a/rtengine/imagedata.h b/rtengine/imagedata.h new file mode 100644 index 000000000..3074c91b2 --- /dev/null +++ b/rtengine/imagedata.h @@ -0,0 +1,80 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef __IMAGEDATA_H__ +#define __IMAGEDATA_H__ + +#include +#include "rawimage.h" +#include +#include +#include "../rtexif/rtexif.h" +#include "procparams.h" +#include +#include "rtengine.h" + +namespace rtengine { + +class ImageData : public ImageMetaData { + + protected: + rtexif::TagDirectory* root; + IptcData* iptc; + + struct tm time; + time_t timeStamp; + int iso_speed; + double aperture; + double focal_len, focal_len35mm; + float focus_dist; // dist: 0=unknown, 10000=infinity + double shutter; + double expcomp; + std::string make, model, serial; + std::string orientation; + std::string lens; + + void extractInfo (); + + public: + + ImageData (Glib::ustring fname, RawMetaDataLocation* rml=NULL); + virtual ~ImageData (); + + 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; } +}; +} +#endif diff --git a/rtengine/imagedimensions.cc b/rtengine/imagedimensions.cc new file mode 100644 index 000000000..f1126e155 --- /dev/null +++ b/rtengine/imagedimensions.cc @@ -0,0 +1,63 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "imagedimensions.h" +#include "rtengine.h" + +void ImageDimensions::transform (PreviewProps pp, int tran, int &sx1, int &sy1, int &sx2, int &sy2) { + + int sw = width, sh = height; + if ((tran & TR_ROT) == TR_R90 || (tran & TR_ROT) == TR_R270) { + sw = height; + sh = width; + } + int ppx = pp.x, ppy = pp.y; + if (tran & TR_HFLIP) + ppx = sw - pp.x - pp.w; + if (tran & TR_VFLIP) + ppy = sh - pp.y - pp.h; + + sx1 = ppx; + sy1 = ppy; + sx2 = ppx + pp.w; + sy2 = ppy + pp.h; + + if ((tran & TR_ROT) == TR_R180) { + sx1 = width - ppx - pp.w; + sy1 = height - ppy - pp.h; + sx2 = sx1 + pp.w; + sy2 = sy1 + pp.h; + } + else if ((tran & TR_ROT) == TR_R90) { + sx1 = ppy; + sy1 = height - ppx - pp.w; + sx2 = sx1 + pp.h; + sy2 = sy1 + pp.w; + } + else if ((tran & TR_ROT) == TR_R270) { + sx1 = width - ppy - pp.h; + sy1 = ppx; + sx2 = sx1 + pp.h; + sy2 = sy1 + pp.w; + } + //printf ("ppx %d ppy %d ppw %d pph %d s: %d %d %d %d\n",pp.x, pp.y,pp.w,pp.h,sx1,sy1,sx2,sy2); + if (sx1<0)sx1=0; + if (sy1<0)sy1=0; +} + diff --git a/rtengine/imagedimensions.h b/rtengine/imagedimensions.h new file mode 100644 index 000000000..9126d500d --- /dev/null +++ b/rtengine/imagedimensions.h @@ -0,0 +1,49 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ + +#ifndef _IMAGEDIMENSIONS_ +#define _IMAGEDIMENSIONS_ + +class PreviewProps { + public: + int x, y, w, h, skip; + PreviewProps (int _x, int _y, int _w, int _h, int _skip) + : x(_x), y(_y), w(_w), h(_h), skip(_skip) {} +}; + +/* + * Description of an image dimension, with getter and setter + */ +class ImageDimensions { + + public: + int width; + int height; + + public: + ImageDimensions() : width(-1), height(-1) {} + int getW () { return width; } + int getH () { return height; } + int getWidth () { return width; } + int getHeight () { return height; } + void transform (PreviewProps pp, int tran, int &sx1, int &sy1, int &sx2, int &sy2); +}; + + +#endif diff --git a/rtengine/imagefloat.cc b/rtengine/imagefloat.cc new file mode 100644 index 000000000..fd71a7108 --- /dev/null +++ b/rtengine/imagefloat.cc @@ -0,0 +1,417 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "imagefloat.h" +#include "image16.h" +#include "image8.h" +#include +#include "rtengine.h" +#include "mytime.h" +#include "iccstore.h" +#include "alignedbuffer.h" +#include "rt_math.h" +#include "color.h" + +using namespace rtengine; + +Imagefloat::Imagefloat () { +} + +Imagefloat::Imagefloat (int w, int h) { + allocate (w, h); +} + +Imagefloat::~Imagefloat () { +} + +// Call this method to handle floating points input values of different size +void Imagefloat::setScanline (int row, unsigned char* buffer, int bps, float *minValue, float *maxValue) { + + if (data==NULL) + return; + + switch (sampleFormat) { + case (IIOSF_FLOAT): + { + int ix = 0; + float* sbuffer = (float*) buffer; + for (int i=0; imaxValue[0]) maxValue[0] = sbuffer[ix]; ++ix; } + g(row,i) = sbuffer[ix]; if (minValue) { if (sbuffer[ix]maxValue[1]) maxValue[1] = sbuffer[ix]; ++ix; } + b(row,i) = sbuffer[ix]; if (minValue) { if (sbuffer[ix]maxValue[2]) maxValue[2] = sbuffer[ix]; ++ix; } + } + break; + } + case (IIOSF_LOGLUV24): + case (IIOSF_LOGLUV32): + { + int ix = 0; + float* sbuffer = (float*) buffer; + float xyzvalues[3], rgbvalues[3]; + for (int i=0; imaxValue[0]) maxValue[0] = rgbvalues[0]; } + g(row,i) = rgbvalues[1]; if (minValue) { if (rgbvalues[1]maxValue[1]) maxValue[1] = rgbvalues[1]; } + b(row,i) = rgbvalues[2]; if (minValue) { if (rgbvalues[2]maxValue[2]) maxValue[2] = rgbvalues[2]; } + } + break; + } + default: + // Other type are ignored, but could be implemented if necessary + break; + } +} + +void Imagefloat::getScanline (int row, unsigned char* buffer, int bps) { + + if (data==NULL) + return; + + if (bps==32) { + int ix = 0; + float* sbuffer = (float*) buffer; + for (int i=0; iwidth; // Destination image + int imheight=image->height; // Destination image + if (((tran & TR_ROT) == TR_R90)||((tran & TR_ROT) == TR_R270)) { + int swap = imwidth; + imwidth=imheight; + imheight=swap; + } + int maxx=width; // Source image + int maxy=height; // Source image + int mtran = tran & TR_ROT; + int skip = pp.skip; + + // improve speed by integrating the area division into the multipliers + // switched to using ints for the red/green/blue channel buffer. + // Incidentally this improves accuracy too. + float area=skip*skip; + float rm2=rm; + float gm2=gm; + float bm2=bm; + rm/=area; + gm/=area; + bm/=area; + +#ifdef _OPENMP +#pragma omp parallel + { +#endif + AlignedBuffer abR(imwidth); + AlignedBuffer abG(imwidth); + AlignedBuffer abB(imwidth); + float *lineR = abR.data; + float *lineG = abG.data; + float *lineB = abB.data; + +#ifdef _OPENMP +#pragma omp for +#endif + for (int iy=0; iy=maxy) + continue; + + for (int dst_x=0,src_x=sx1; dst_x=maxx) + continue; + + lineR[dst_x] = CLIP(rm2*r(src_y, src_x)); + lineG[dst_x] = CLIP(gm2*g(src_y, src_x)); + lineB[dst_x] = CLIP(bm2*b(src_y, src_x)); + } + } + else { + // source image, first line of the current destination row + int src_y=sy1+skip*iy; + if (src_y>=maxy) + continue; + + for (int dst_x=0,src_x=sx1; dst_x=maxx) + continue; + + int src_sub_width = MIN(maxx-src_x, skip); + int src_sub_height = MIN(maxy-src_y, skip); + + float rtot,gtot,btot; // RGB accumulators + rtot=gtot=btot=0.; + + for (int src_sub_y=0; src_sub_yr(iy, dst_x) = lineR[dst_x]; + image->g(iy, dst_x) = lineG[dst_x]; + image->b(iy, dst_x) = lineB[dst_x]; + } + else if (mtran == TR_R180) + for (int dst_x=0; dst_xr(imheight-1-iy, imwidth-1-dst_x) = lineR[dst_x]; + image->g(imheight-1-iy, imwidth-1-dst_x) = lineG[dst_x]; + image->b(imheight-1-iy, imwidth-1-dst_x) = lineB[dst_x]; + } + else if (mtran == TR_R90) + for (int dst_x=0,src_x=sx1; dst_xr(dst_x, imheight-1-iy) = lineR[dst_x]; + image->g(dst_x, imheight-1-iy) = lineG[dst_x]; + image->b(dst_x, imheight-1-iy) = lineB[dst_x]; + } + else if (mtran == TR_R270) + for (int dst_x=0,src_x=sx1; dst_xr(imwidth-1-dst_x, iy) = lineR[dst_x]; + image->g(imwidth-1-dst_x, iy) = lineG[dst_x]; + image->b(imwidth-1-dst_x, iy) = lineB[dst_x]; + } + } +#ifdef _OPENMP +} +#endif +} + +Image8* +Imagefloat::to8() +{ + Image8* img8 = new Image8(width,height); +#ifdef _OPENMP +#pragma omp parallel for schedule(static) +#endif + for ( int h=0; h < height; ++h ) + { + for ( int w=0; w < width; ++w ) + { + img8->r(h, w) = (unsigned char)( (unsigned short)(r(h,w)) >> 8); + img8->g(h, w) = (unsigned char)( (unsigned short)(g(h,w)) >> 8); + img8->b(h, w) = (unsigned char)( (unsigned short)(b(h,w)) >> 8); + } + } + return img8; +} + +Image16* +Imagefloat::to16() +{ + Image16* img16 = new Image16(width,height); +#ifdef _OPENMP +#pragma omp parallel for schedule(static) +#endif + for ( int h=0; h < height; ++h ) + { + for ( int w=0; w < width; ++w ) + { + img16->r( h,w) = (unsigned short)(r(h,w)); + img16->g( h,w) = (unsigned short)(g(h,w)); + img16->b( h,w) = (unsigned short)(b(h,w)); + } + } + return img16; +} + +void Imagefloat::normalizeFloat(float srcMinVal, float srcMaxVal) { + + float scale = MAXVALD / (srcMaxVal-srcMinVal); + int w = width; + int h = height; + +#ifdef _OPENMP +#pragma omp parallel for firstprivate(w, h, srcMinVal, scale) schedule(dynamic, 5) +#endif + for (int y=0; yworkingSpaceMatrix (params.icm.working); + + float facRed = wprof[1][0]; + float facGreen = wprof[1][1]; + float facBlue = wprof[1][2]; + + + // calc pixel size + int x1, x2, y1, y2; + params.crop.mapToResized(width, height, scale, x1, x2, y1, y2); + +#pragma omp parallel +{ + LUTu histThr(65536); + histThr.clear(); +#pragma omp for nowait + for (int y=y1; y65535) + i=65535; + histThr[i]++; + } + } +#pragma omp critical +{ + for(int i=0;i<=0xffff;i++) + hist[i] += histThr[i]; +} +} + +} + +// Parallelized transformation; create transform with cmsFLAGS_NOCACHE! +void Imagefloat::ExecCMSTransform(cmsHTRANSFORM hTransform) { + + // LittleCMS cannot parallelize planar setups -- Hombre: LCMS2.4 can! But it we use this new feature, memory allocation + // have to be modified too to build temporary buffers that allow multi processor execution +#ifdef _OPENMP +#pragma omp parallel +#endif +{ + AlignedBuffer pBuf(width*3); + +#ifdef _OPENMP +#pragma omp for schedule(static) +#endif + for (int y=0; y + * + * 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 . + */ +// +// A class representing a 16 bit rgb image with separate planes and 16 byte aligned data +// +#ifndef _IMAGEFLOAT_ +#define _IMAGEFLOAT_ + +#include "imageio.h" +#include "rtengine.h" + +namespace rtengine { + using namespace procparams; + +class Image8; +class Image16; + +/* + * Image type used by most tools; expected range: [0.0 ; 65535.0] + */ +class Imagefloat : public IImagefloat, public ImageIO { + + public: + + Imagefloat (); + Imagefloat (int width, int height); + ~Imagefloat (); + + Imagefloat* copy (); + + Image8* to8(); + Image16* to16(); + + virtual void getStdImage (ColorTemp ctemp, int tran, Imagefloat* image, PreviewProps pp, bool first, procparams::ToneCurveParams hrp); + + virtual const char* getType () const { return sImagefloat; } + virtual int getBPS () { return 8*sizeof(float); } + virtual void getScanline (int row, unsigned char* buffer, int bps); + virtual void setScanline (int row, unsigned char* buffer, int bps, float *minValue=NULL, float *maxValue=NULL); + + // functions inherited from IImagefloat: + virtual MyMutex& getMutex () { return mutex (); } + virtual cmsHPROFILE getProfile () { return getEmbeddedProfile (); } + virtual int getBitsPerPixel () { return 8*sizeof(float); } + virtual int saveToFile (Glib::ustring fname) { return save (fname); } + virtual int saveAsPNG (Glib::ustring fname, int compression = -1, int bps = -1) { return savePNG (fname, compression, bps); } + virtual int saveAsJPEG (Glib::ustring fname, int quality = 100, int subSamp = 3) { return saveJPEG (fname, quality, subSamp); } + virtual int saveAsTIFF (Glib::ustring fname, int bps = -1, bool uncompressed = false) { return saveTIFF (fname, bps, uncompressed); } + virtual void setSaveProgressListener (ProgressListener* pl) { setProgressListener (pl); } + virtual void free () { delete this; } + + virtual void normalizeFloat(float srcMinVal, float srcMaxVal); + void normalizeFloatTo1(); + void normalizeFloatTo65535(); + void calcCroppedHistogram(const ProcParams ¶ms, float scale, LUTu & hist); + + void ExecCMSTransform(cmsHTRANSFORM hTransform); +}; + +} +#endif diff --git a/rtengine/imageio.cc b/rtengine/imageio.cc new file mode 100644 index 000000000..5c0d87f52 --- /dev/null +++ b/rtengine/imageio.cc @@ -0,0 +1,1269 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * Copyright (c) 2010 Oliver Duis + * + * 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 +#include +#include +#include +#include +#include +#include "rt_math.h" +#include "../rtgui/options.h" +#include "../rtgui/version.h" + +#ifdef WIN32 +#include +#else +#include +#endif + +#include "imageio.h" +#include "safegtk.h" +#include "iptcpairs.h" +#include "iccjpeg.h" +#include "color.h" + +#include "jpeg.h" + +using namespace std; +using namespace rtengine; +using namespace rtengine::procparams; + +Glib::ustring safe_locale_to_utf8 (const std::string& src); +Glib::ustring ImageIO::errorMsg[6] = {"Success", "Cannot read file.", "Invalid header.","Error while reading header.","File reading error", "Image format not supported."}; + + +// For only copying the raw input data +void ImageIO::setMetadata (const rtexif::TagDirectory* eroot) { + if (exifRoot!=NULL) { delete exifRoot; exifRoot = NULL; } + + if (eroot) { + rtexif::TagDirectory* td = ((rtexif::TagDirectory*)eroot)->clone (NULL); + + // make IPTC and XMP pass through + td->keepTag(0x83bb); // IPTC + td->keepTag(0x02bc); // XMP + + exifRoot=td; + } +} + +// For merging with RT specific data +void ImageIO::setMetadata (const rtexif::TagDirectory* eroot, const rtengine::procparams::ExifPairs& exif, const rtengine::procparams::IPTCPairs& iptcc) { + + // store exif info + exifChange.clear(); + exifChange = exif; + /*unsigned int j=0; + for (rtengine::procparams::ExifPairs::const_iterator i=exif.begin(); i!=exif.end(); i++) { + exifChange.at(j).first = i->first; + exifChange.at(j).second = i->second; + j++; + }*/ + + if (exifRoot!=NULL) { delete exifRoot; exifRoot = NULL; } + + if (eroot) + exifRoot = ((rtexif::TagDirectory*)eroot)->clone (NULL); + + if (iptc!=NULL) { iptc_data_free (iptc); iptc = NULL; } + + // build iptc structures for libiptcdata + if (iptcc.empty()) + return; + + iptc = iptc_data_new (); + for (rtengine::procparams::IPTCPairs::const_iterator i=iptcc.begin(); i!=iptcc.end(); i++) { + if (i->first == "Keywords" && !(i->second.empty())) { + for (unsigned int j=0; jsecond.size(); j++) { + IptcDataSet * ds = iptc_dataset_new (); + iptc_dataset_set_tag (ds, IPTC_RECORD_APP_2, IPTC_TAG_KEYWORDS); + std::string loc = safe_locale_to_utf8(i->second.at(j)); + iptc_dataset_set_data (ds, (unsigned char*)loc.c_str(), min(static_cast(64), loc.size()), IPTC_DONT_VALIDATE); + iptc_data_add_dataset (iptc, ds); + iptc_dataset_unref (ds); + } + continue; + } + else if (i->first == "SupplementalCategories" && !(i->second.empty())) { + for (unsigned int j=0; jsecond.size(); j++) { + IptcDataSet * ds = iptc_dataset_new (); + iptc_dataset_set_tag (ds, IPTC_RECORD_APP_2, IPTC_TAG_SUPPL_CATEGORY); + std::string loc = safe_locale_to_utf8(i->second.at(j)); + iptc_dataset_set_data (ds, (unsigned char*)loc.c_str(), min(static_cast(32), loc.size()), IPTC_DONT_VALIDATE); + iptc_data_add_dataset (iptc, ds); + iptc_dataset_unref (ds); + } + continue; + } + for (int j=0; j<16; j++) + if (i->first == strTags[j].field && !(i->second.empty())) { + IptcDataSet * ds = iptc_dataset_new (); + iptc_dataset_set_tag (ds, IPTC_RECORD_APP_2, strTags[j].tag); + std::string loc = safe_locale_to_utf8(i->second.at(0)); + iptc_dataset_set_data (ds, (unsigned char*)loc.c_str(), min(strTags[j].size, loc.size()), IPTC_DONT_VALIDATE); + iptc_data_add_dataset (iptc, ds); + iptc_dataset_unref (ds); + } + } + iptc_data_sort (iptc); +} + +void ImageIO::setOutputProfile (char* pdata, int plen) { + + delete [] profileData; + if (pdata) { + profileData = new char [plen]; + memcpy (profileData, pdata, plen); + } + else + profileData = NULL; + profileLength = plen; +} + +ImageIO::~ImageIO () { + + if (embProfile) + cmsCloseProfile(embProfile); + deleteLoadedProfileData(); + delete exifRoot; + delete [] profileData; +} + +void png_read_data(png_struct_def *png_ptr, unsigned char *data, size_t length); +void png_write_data(png_struct_def *png_ptr, unsigned char *data, size_t length); +void png_flush(png_struct_def *png_ptr); + +int ImageIO::getPNGSampleFormat (Glib::ustring fname, IIOSampleFormat &sFormat, IIOSampleArrangement &sArrangement) { + FILE *file = safe_g_fopen (fname,"rb"); + if (!file) + return IMIO_CANNOTREADFILE; + + //reading PNG header + unsigned char header[8]; + fread (header, 1, 8, file); + if (png_sig_cmp (header, 0, 8)) { + fclose(file); + return IMIO_HEADERERROR; + } + //initializing main structures + png_structp png = png_create_read_struct (PNG_LIBPNG_VER_STRING, 0, 0, 0); + if (!png) { + fclose (file); + return IMIO_HEADERERROR; + } + png_infop info = png_create_info_struct (png); + png_infop end_info = png_create_info_struct (png); + if (!end_info || !info) { + png_destroy_read_struct (&png, &info, &end_info); + fclose (file); + return IMIO_HEADERERROR; + } + + if (setjmp (png_jmpbuf(png))) { + png_destroy_read_struct (&png, &info, &end_info); + fclose (file); + return IMIO_READERROR; + } + + //set up png read + png_set_read_fn (png, file, png_read_data); + png_set_sig_bytes (png,8); + + png_read_info(png,info); + + //retrieving image information + png_uint_32 width,height; + int bit_depth,color_type,interlace_type,compression_type,filter_method; + png_get_IHDR(png,info,&width,&height,&bit_depth,&color_type,&interlace_type,&compression_type, &filter_method); + + png_destroy_read_struct (&png, &info, &end_info); + fclose (file); + + if (interlace_type!=PNG_INTERLACE_NONE) + return IMIO_VARIANTNOTSUPPORTED; + + if (bit_depth == 8) { + sArrangement = IIOSA_CHUNKY; + sFormat = IIOSF_UNSIGNED_CHAR; + return IMIO_SUCCESS; + } + else if (bit_depth == 16) { + sArrangement = IIOSA_CHUNKY; + sFormat = IIOSF_UNSIGNED_SHORT; + return IMIO_SUCCESS; + } + else { + sArrangement = IIOSA_UNKNOWN; + sFormat = IIOSF_UNKNOWN; + return IMIO_VARIANTNOTSUPPORTED; + } +} + +int ImageIO::loadPNG (Glib::ustring fname) { + + FILE *file = safe_g_fopen (fname,"rb"); + if (!file) + return IMIO_CANNOTREADFILE; + + if (pl) { + pl->setProgressStr ("PROGRESSBAR_LOADPNG"); + pl->setProgress (0.0); + } + + //reading PNG header + unsigned char header[8]; + fread (header, 1, 8, file); + if (png_sig_cmp (header, 0, 8)) { + fclose(file); + return IMIO_HEADERERROR; + } + //initializing main structures + png_structp png = png_create_read_struct (PNG_LIBPNG_VER_STRING, 0, 0, 0); + if (!png) { + fclose (file); + return IMIO_HEADERERROR; + } + png_infop info = png_create_info_struct (png); + png_infop end_info = png_create_info_struct (png); + if (!end_info || !info) { + png_destroy_read_struct (&png, &info, &end_info); + fclose (file); + return IMIO_HEADERERROR; + } + + if (setjmp (png_jmpbuf(png))) { + png_destroy_read_struct (&png, &info, &end_info); + fclose (file); + return IMIO_READERROR; + } + + //set up png read + png_set_read_fn (png, file, png_read_data); + png_set_sig_bytes (png,8); + + png_read_info(png,info); + + embProfile = NULL; + + //retrieving image information + png_uint_32 width,height; + int bit_depth,color_type,interlace_type,compression_type,filter_method; + png_get_IHDR(png, info, &width, &height, &bit_depth, &color_type, &interlace_type, &compression_type, &filter_method); + + if (color_type==PNG_COLOR_TYPE_PALETTE || interlace_type!=PNG_INTERLACE_NONE ) { + // we don't support interlaced png or png with palette + png_destroy_read_struct (&png, &info, &end_info); + fclose (file); + printf("%s uses an unsupported feature: . Skipping.\n",fname.data()); + return IMIO_VARIANTNOTSUPPORTED; + } + + if (color_type==PNG_COLOR_TYPE_GRAY || color_type==PNG_COLOR_TYPE_GRAY_ALPHA) + png_set_gray_to_rgb(png); + + if (png_get_valid(png,info,PNG_INFO_tRNS)) + png_set_tRNS_to_alpha(png); + + if (color_type & PNG_COLOR_MASK_ALPHA) + png_set_strip_alpha(png); + + //setting gamma + double gamma; + if (png_get_gAMA(png,info,&gamma)) + png_set_gamma(png, 1.0/gamma, gamma); // use gamma from metadata + else + png_set_gamma(png, 2.2, 1.0/2.2); // no gamma in metadata, suppose gamma 2.2 + +// if (bps==8 && bit_depth==16) png_set_strip_16(png); + + //updating png info struct + png_read_update_info(png,info); + png_get_IHDR(png,info,&width,&height,&bit_depth,&color_type,&interlace_type,&compression_type, &filter_method); + + allocate (width, height); + + int rowlen = width*3*bit_depth/8; + unsigned char *row = new unsigned char [rowlen]; + + // set a new jump point to avoid memory leak + if (setjmp (png_jmpbuf(png))) { + png_destroy_read_struct (&png, &info, &end_info); + fclose (file); + delete [] row; + return IMIO_READERROR; + } + + for (unsigned int i=0;isetProgress ((double)(i+1)/height); + } + + png_read_end (png, 0); + png_destroy_read_struct (&png, &info, &end_info); + + delete [] row; + fclose(file); + if (pl) { + pl->setProgressStr ("PROGRESSBAR_READY"); + pl->setProgress (1.0); + } + return IMIO_SUCCESS; +} + +typedef struct { + struct jpeg_error_mgr pub; /* "public" fields */ + jmp_buf setjmp_buffer; /* for return to caller */ +} my_error_mgr; + +void my_error_exit (j_common_ptr cinfo) { + /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */ + my_error_mgr *myerr = (my_error_mgr*) cinfo->err; + /* Always display the message. */ + /* We could postpone this until after returning, if we chose. */ + (*cinfo->err->output_message) (cinfo); + + /* Return control to the setjmp point */ +#if defined( WIN32 ) && defined( __x86_64__ ) + __builtin_longjmp(myerr->setjmp_buffer, 1); +#else + longjmp(myerr->setjmp_buffer, 1); +#endif +} + + +int ImageIO::loadJPEGFromMemory (const char* buffer, int bufsize) +{ + jpeg_decompress_struct cinfo; + jpeg_create_decompress(&cinfo); + jpeg_memory_src (&cinfo,(const JOCTET*)buffer,bufsize); + + /* We use our private extension JPEG error handler. + Note that this struct must live as long as the main JPEG parameter + struct, to avoid dangling-pointer problems. + */ + my_error_mgr jerr; + /* We set up the normal JPEG error routines, then override error_exit. */ + cinfo.err = jpeg_std_error(&jerr.pub); + jerr.pub.error_exit = my_error_exit; + + /* Establish the setjmp return context for my_error_exit to use. */ +#if defined( WIN32 ) && defined( __x86_64__ ) + if (__builtin_setjmp(jerr.setjmp_buffer)) { +#else + if (setjmp(jerr.setjmp_buffer)) { +#endif + /* If we get here, the JPEG code has signaled an error. + We need to clean up the JPEG object and return. + */ + jpeg_destroy_decompress(&cinfo); + return IMIO_READERROR; + } + + + if (pl) { + pl->setProgressStr ("PROGRESSBAR_LOADJPEG"); + pl->setProgress (0.0); + + } + + setup_read_icc_profile (&cinfo); + + jpeg_read_header(&cinfo, TRUE); + + deleteLoadedProfileData(); + loadedProfileDataJpg = true; + bool hasprofile = read_icc_profile (&cinfo, (JOCTET**)&loadedProfileData, (unsigned int*)&loadedProfileLength); + if (hasprofile) + embProfile = cmsOpenProfileFromMem (loadedProfileData, loadedProfileLength); + else + embProfile = NULL; + + jpeg_start_decompress(&cinfo); + + unsigned int width = cinfo.output_width; + unsigned int height = cinfo.output_height; + + allocate (width, height); + + unsigned char *row=new unsigned char[width*3]; + while (cinfo.output_scanline < height) { + if (jpeg_read_scanlines(&cinfo,&row,1) < 1) { + jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + delete [] row; + return IMIO_READERROR; + } + setScanline (cinfo.output_scanline-1, row, 8); + + if (pl && !(cinfo.output_scanline%100)) + pl->setProgress ((double)(cinfo.output_scanline)/cinfo.output_height); + } + delete [] row; + + jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + if (pl) { + pl->setProgressStr ("PROGRESSBAR_READY"); + pl->setProgress (1.0); + } + return IMIO_SUCCESS; +} + +int ImageIO::loadJPEG (Glib::ustring fname) { + FILE *file=safe_g_fopen(fname,"rb"); + if (!file) + return IMIO_CANNOTREADFILE; + + jpeg_decompress_struct cinfo; + jpeg_error_mgr jerr; + cinfo.err = my_jpeg_std_error(&jerr); + jpeg_create_decompress(&cinfo); + + my_jpeg_stdio_src (&cinfo,file); + if ( setjmp((reinterpret_cast(cinfo.src))->error_jmp_buf) == 0 ) + { + if (pl) { + pl->setProgressStr ("PROGRESSBAR_LOADJPEG"); + pl->setProgress (0.0); + } + + setup_read_icc_profile (&cinfo); + + //jpeg_stdio_src(&cinfo,file); + jpeg_read_header(&cinfo, TRUE); + + //if JPEG is CMYK, then abort reading + if (cinfo.jpeg_color_space == JCS_CMYK || cinfo.jpeg_color_space == JCS_YCCK || cinfo.jpeg_color_space == JCS_GRAYSCALE) { + jpeg_destroy_decompress(&cinfo); + return IMIO_READERROR; + } + + deleteLoadedProfileData(); + loadedProfileDataJpg = true; + bool hasprofile = read_icc_profile (&cinfo, (JOCTET**)&loadedProfileData, (unsigned int*)&loadedProfileLength); + if (hasprofile) + embProfile = cmsOpenProfileFromMem (loadedProfileData, loadedProfileLength); + else + embProfile = NULL; + + jpeg_start_decompress(&cinfo); + + unsigned int width = cinfo.output_width; + unsigned int height = cinfo.output_height; + + allocate (width, height); + + unsigned char *row=new unsigned char[width*3]; + while (cinfo.output_scanline < height) { + if (jpeg_read_scanlines(&cinfo,&row,1) < 1) { + jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + delete [] row; + return IMIO_READERROR; + } + setScanline (cinfo.output_scanline-1, row, 8); + + if (pl && !(cinfo.output_scanline%100)) + pl->setProgress ((double)(cinfo.output_scanline)/cinfo.output_height); + } + delete [] row; + + jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + fclose(file); + if (pl) { + pl->setProgressStr ("PROGRESSBAR_READY"); + pl->setProgress (1.0); + } + return IMIO_SUCCESS; + } + else { + jpeg_destroy_decompress(&cinfo); + return IMIO_READERROR; + } +} + +int ImageIO::getTIFFSampleFormat (Glib::ustring fname, IIOSampleFormat &sFormat, IIOSampleArrangement &sArrangement) { +#ifdef WIN32 + wchar_t *wfilename = (wchar_t*)g_utf8_to_utf16 (fname.c_str(), -1, NULL, NULL, NULL); + TIFF* in = TIFFOpenW (wfilename, "r"); + g_free (wfilename); +#else + TIFF* in = TIFFOpen(fname.c_str(), "r"); +#endif + if (in == NULL) + return IMIO_CANNOTREADFILE; + + uint16 bitspersample=0, samplesperpixel=0, sampleformat=0; + int hasTag = TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bitspersample); + hasTag &= TIFFGetField(in, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel); + if (!hasTag) { + // These are needed + TIFFClose(in); + sFormat = IIOSF_UNKNOWN; + return IMIO_VARIANTNOTSUPPORTED; + } + if (!TIFFGetField(in, TIFFTAG_SAMPLEFORMAT, &sampleformat)) + /* + * 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; + + uint16 config; + TIFFGetField(in, TIFFTAG_PLANARCONFIG, &config); + if (config == PLANARCONFIG_CONTIG) { + sArrangement = IIOSA_CHUNKY; + } + else { + sFormat = IIOSF_UNKNOWN; + sArrangement = IIOSA_UNKNOWN; + TIFFClose(in); + return IMIO_VARIANTNOTSUPPORTED; + } + + uint16 photometric; + if (!TIFFGetField(in, TIFFTAG_PHOTOMETRIC, &photometric)) { + TIFFClose(in); + return IMIO_VARIANTNOTSUPPORTED; + } + + uint16 compression; + if (photometric == PHOTOMETRIC_LOGLUV) + if (!TIFFGetField(in, TIFFTAG_COMPRESSION, &compression)) + compression = COMPRESSION_NONE; + + TIFFClose(in); + + if (photometric == PHOTOMETRIC_RGB) { + if ((samplesperpixel==3 || samplesperpixel==4) && sampleformat==SAMPLEFORMAT_UINT) { + if (bitspersample==8) { + sFormat = IIOSF_UNSIGNED_CHAR; + return IMIO_SUCCESS; + } + if (bitspersample==16) { + sFormat = IIOSF_UNSIGNED_SHORT; + return IMIO_SUCCESS; + } + } + else if (samplesperpixel==3 && sampleformat==SAMPLEFORMAT_IEEEFP) { + /* + * Not yet supported + * + if (bitspersample==16) { + sFormat = IIOSF_HALF; + return IMIO_SUCCESS; + }*/ + if ((samplesperpixel==3 || samplesperpixel==4) && bitspersample==32) { + sFormat = IIOSF_FLOAT; + return IMIO_SUCCESS; + } + } + } + else if (samplesperpixel==3 && photometric == PHOTOMETRIC_LOGLUV) { + if (compression==COMPRESSION_SGILOG24) { + sFormat = IIOSF_LOGLUV24; + return IMIO_SUCCESS; + } + else if (compression==COMPRESSION_SGILOG) { + sFormat = IIOSF_LOGLUV32; + return IMIO_SUCCESS; + } + } + return IMIO_VARIANTNOTSUPPORTED; +} + +int ImageIO::loadTIFF (Glib::ustring fname) { + + static MyMutex thumbMutex; + MyMutex::MyLock lock(thumbMutex); + if(!options.serializeTiffRead) + lock.release(); + +#ifdef WIN32 + wchar_t *wfilename = (wchar_t*)g_utf8_to_utf16 (fname.c_str(), -1, NULL, NULL, NULL); + TIFF* in = TIFFOpenW (wfilename, "r"); + g_free (wfilename); +#else + TIFF* in = TIFFOpen(fname.c_str(), "r"); +#endif + if (in == NULL) + return IMIO_CANNOTREADFILE; + + if (pl) { + pl->setProgressStr ("PROGRESSBAR_LOADTIFF"); + pl->setProgress (0.0); + } + + int width, height; + TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &width); + TIFFGetField(in, TIFFTAG_IMAGELENGTH, &height); + + uint16 bitspersample, samplesperpixel; + int hasTag = TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bitspersample); + hasTag &= TIFFGetField(in, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel); + if (!hasTag) { + // These are needed + TIFFClose(in); + return IMIO_VARIANTNOTSUPPORTED; + } + + uint16 config; + TIFFGetField(in, TIFFTAG_PLANARCONFIG, &config); + if (config != PLANARCONFIG_CONTIG) { + TIFFClose(in); + return IMIO_VARIANTNOTSUPPORTED; + } + + if (sampleFormat & (IIOSF_LOGLUV24|IIOSF_LOGLUV32)) + TIFFSetField(in, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_FLOAT); + + /* + * We could use the min/max values set in TIFFTAG_SMINSAMPLEVALUE and + * TIFFTAG_SMAXSAMPLEVALUE, but for now, we normalize the image to the + * effective minimum and maximum values + * + printf("Informations de \"%s\":\n", fname.c_str()); + uint16 tiffDefaultScale, tiffBaselineExposure, tiffLinearResponseLimit; + if (TIFFGetField(in, TIFFTAG_DEFAULTSCALE, &tiffDefaultScale)) { + printf(" DefaultScale: %d\n", tiffDefaultScale); + } + else + printf(" No DefaultScale value!\n"); + if (TIFFGetField(in, TIFFTAG_BASELINEEXPOSURE, &tiffBaselineExposure)) { + printf(" BaselineExposure: %d\n", tiffBaselineExposure); + } + else + printf(" No BaselineExposure value!\n"); + if (TIFFGetField(in, TIFFTAG_LINEARRESPONSELIMIT, &tiffLinearResponseLimit)) { + printf(" LinearResponseLimit: %d\n", tiffLinearResponseLimit); + } + else + printf(" No LinearResponseLimit value!\n"); + + uint16 tiffMinValue, tiffMaxValue; + if (TIFFGetField(in, TIFFTAG_SMINSAMPLEVALUE, &tiffMinValue)) { + printf(" MinValue: %d\n", tiffMinValue); + } + else + printf(" No minimum value!\n"); + if (TIFFGetField(in, TIFFTAG_SMAXSAMPLEVALUE, &tiffMaxValue)) { + printf(" MaxValue: %d\n\n", tiffMaxValue); + } + else + printf(" No maximum value!\n\n"); + printf("\n"); + */ + + + char* profdata; + deleteLoadedProfileData(); + loadedProfileDataJpg = false; + if (TIFFGetField(in, TIFFTAG_ICCPROFILE, &loadedProfileLength, &profdata)) { + embProfile = cmsOpenProfileFromMem (profdata, loadedProfileLength); + + // For 32 bits floating point images, gamma is forced to linear in embedded ICC profiles + if ( sampleFormat&(IIOSF_LOGLUV24|IIOSF_LOGLUV32|IIOSF_FLOAT) ) { + // Modifying the gammaTRG tags + cmsWriteTag(embProfile, cmsSigGreenTRCTag, (void*)Color::linearGammaTRC ); + cmsWriteTag(embProfile, cmsSigRedTRCTag, (void*)Color::linearGammaTRC ); + cmsWriteTag(embProfile, cmsSigBlueTRCTag, (void*)Color::linearGammaTRC ); + + // Saving the profile in the memory + cmsUInt32Number bytesNeeded = 0; + cmsSaveProfileToMem(embProfile, 0, &bytesNeeded); + if (bytesNeeded > 0) { + loadedProfileData = new char[bytesNeeded+1]; + cmsSaveProfileToMem(embProfile, loadedProfileData, &bytesNeeded); + } + loadedProfileLength = (int)bytesNeeded; + } + else { + // Saving the profile in the memory as is + loadedProfileData = new char [loadedProfileLength]; + memcpy (loadedProfileData, profdata, loadedProfileLength); + } + + } + else + embProfile = NULL; + + allocate (width, height); + + float minValue[3]={0.f, 0.f, 0.f}, maxValue[3]={0.f, 0.f, 0.f}; + unsigned char* linebuffer = new unsigned char[TIFFScanlineSize(in)]; + for (int row = 0; row < height; row++) { + if (TIFFReadScanline(in, linebuffer, row, 0) <0) { + TIFFClose(in); + delete [] linebuffer; + return IMIO_READERROR; + } + if (samplesperpixel>3) + for (int i=0; isetProgress ((double)(row+1)/height); + } + if (sampleFormat & (IIOSF_FLOAT|IIOSF_LOGLUV24|IIOSF_LOGLUV32)) { +#ifdef _DEBUG + if (options.rtSettings.verbose) + printf("Normalizing \"%s\" image \"%s\" whose mini/maxi values are:\n Red: minimum value=%0.5f / maximum value=%0.5f\n Green: minimum value=%0.5f / maximum value=%0.5f\n Blue: minimum value=%0.5f / maximum value=%0.5f\n", + getType(), fname.c_str(), + minValue[0], maxValue[0], minValue[1], + maxValue[1], minValue[2], maxValue[2] + ); +#endif + float minVal = min( min( minValue[0],minValue[1] ),minValue[2] ); + float maxVal = max( max( maxValue[0],maxValue[1] ),maxValue[2] ); + normalizeFloat(minVal, maxVal); + } + TIFFClose(in); + delete [] linebuffer; + + if (pl) { + pl->setProgressStr ("PROGRESSBAR_READY"); + pl->setProgress (1.0); + } + + return IMIO_SUCCESS; +} + +int ImageIO::loadPPMFromMemory(const char* buffer, int width, int height, bool swap, int bps) +{ + allocate (width, height); + + int line_length(width * 3 * (bps/8)); + + if ( swap && bps > 8 ) + { + char swapped[line_length]; + for ( int row = 0; row < height; ++row ) + { + ::swab(((char*)buffer) + (row * line_length),swapped,line_length); + setScanline(row,(unsigned char*)&swapped[0],bps); + } + } + else + { + for ( int row = 0; row < height; ++row ) + { + setScanline(row,((unsigned char*)buffer) + (row * line_length),bps); + } + } + + return IMIO_SUCCESS; +} + +int ImageIO::savePNG (Glib::ustring fname, int compression, volatile int bps) { + + FILE *file = safe_g_fopen_WriteBinLock (fname); + + if (!file) + return IMIO_CANNOTWRITEFILE; + + if (pl) { + pl->setProgressStr ("PROGRESSBAR_SAVEPNG"); + pl->setProgress (0.0); + } + + png_structp png = png_create_write_struct (PNG_LIBPNG_VER_STRING,0,0,0); + if (!png) { + fclose (file); + return IMIO_HEADERERROR; + } + png_infop info = png_create_info_struct(png); + if (!info) { + png_destroy_write_struct (&png,0); + fclose (file); + return IMIO_HEADERERROR; + } + + if (setjmp(png_jmpbuf(png))) { + png_destroy_write_struct (&png,&info); + fclose(file); + return IMIO_CANNOTWRITEFILE; + } + + png_set_write_fn (png, file, png_write_data, png_flush); + + png_set_compression_level(png,compression); + + int width = getW (); + int height = getH (); + if (bps<0) + bps = getBPS (); + + png_set_IHDR(png, info, width, height, bps, PNG_COLOR_TYPE_RGB, + PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,PNG_FILTER_TYPE_BASE); + + + int rowlen = width*3*bps/8; + unsigned char *row = new unsigned char [rowlen]; + + png_write_info(png,info); + for (int i=0;isetProgress ((double)(i+1)/height); + } + + png_write_end(png,info); + png_destroy_write_struct(&png,&info); + + delete [] row; + fclose (file); + + if (pl) { + pl->setProgressStr ("PROGRESSBAR_READY"); + pl->setProgress (1.0); + } + + return IMIO_SUCCESS; +} + + + +// Quality 0..100, subsampling: 1=low quality, 2=medium, 3=high +int ImageIO::saveJPEG (Glib::ustring fname, int quality, int subSamp) { + + FILE *file = safe_g_fopen_WriteBinLock (fname); + if (!file) + return IMIO_CANNOTWRITEFILE; + + jpeg_compress_struct cinfo; + /* We use our private extension JPEG error handler. + Note that this struct must live as long as the main JPEG parameter + struct, to avoid dangling-pointer problems. + */ + my_error_mgr jerr; + /* We set up the normal JPEG error routines, then override error_exit. */ + cinfo.err = jpeg_std_error(&jerr.pub); + jerr.pub.error_exit = my_error_exit; + + /* Establish the setjmp return context for my_error_exit to use. */ +#if defined( WIN32 ) && defined( __x86_64__ ) + if (__builtin_setjmp(jerr.setjmp_buffer)) { +#else + if (setjmp(jerr.setjmp_buffer)) { +#endif + /* If we get here, the JPEG code has signaled an error. + We need to clean up the JPEG object, close the file, remove the already saved part of the file and return. + */ + jpeg_destroy_compress(&cinfo); + fclose(file); + safe_g_remove(fname); + return IMIO_CANNOTWRITEFILE; + } + + jpeg_create_compress (&cinfo); + + + + if (pl) { + pl->setProgressStr ("PROGRESSBAR_SAVEJPEG"); + pl->setProgress (0.0); + } + + jpeg_stdio_dest (&cinfo, file); + + int width = getW (); + int height = getH (); + + cinfo.image_width = width; + cinfo.image_height = height; + cinfo.in_color_space = JCS_RGB; + cinfo.input_components = 3; + jpeg_set_defaults (&cinfo); + cinfo.write_JFIF_header = FALSE; + + // compute optimal Huffman coding tables for the image. Bit slower to generate, but size of result image is a bit less (default was FALSE) + cinfo.optimize_coding = TRUE; + + // Since math coprocessors are common these days, FLOAT should be a bit more accurate AND fast (default is ISLOW) + // (machine dependency is not really an issue, since we all run on x86 and having exactly the same file is not a requirement) + cinfo.dct_method = JDCT_FLOAT; + + if (quality>=0 && quality<=100) + jpeg_set_quality (&cinfo, quality, true); + + cinfo.comp_info[1].h_samp_factor=cinfo.comp_info[1].v_samp_factor = 1; + cinfo.comp_info[2].h_samp_factor=cinfo.comp_info[2].v_samp_factor = 1; + + if (subSamp==1) { + // Best compression, default of the JPEG library: 2x2, 1x1, 1x1 (4:1:1) + cinfo.comp_info[0].h_samp_factor=cinfo.comp_info[0].v_samp_factor = 2; + } else if (subSamp==2) { + // Widely used normal ratio 2x1, 1x1, 1x1 (4:2:2) + cinfo.comp_info[0].h_samp_factor = 2; cinfo.comp_info[0].v_samp_factor = 1; + } else if (subSamp==3) { + // Best quality 1x1 1x1 1x1 (4:4:4) + cinfo.comp_info[0].h_samp_factor=cinfo.comp_info[0].v_samp_factor = 1; + } + + jpeg_start_compress(&cinfo, TRUE); + + // buffer for exif and iptc markers + unsigned char* buffer = new unsigned char[165535]; //FIXME: no buffer size check so it can be overflowed in createJPEGMarker() for large tags, and then software will crash + unsigned int size; + // assemble and write exif marker + if (exifRoot) { + int size = rtexif::ExifManager::createJPEGMarker (exifRoot, exifChange, cinfo.image_width, cinfo.image_height, buffer); + if (size>0 && size<65530) + jpeg_write_marker(&cinfo, JPEG_APP0+1, buffer, size); + } + // assemble and write iptc marker + if (iptc) { + unsigned char* iptcdata; + bool error = false; + if (iptc_data_save (iptc, &iptcdata, &size)) { + if (iptcdata) + iptc_data_free_buf (iptc, iptcdata); + error = true; + } + int bytes = 0; + if (!error && (bytes = iptc_jpeg_ps3_save_iptc (NULL, 0, iptcdata, size, buffer, 65532)) < 0) { + if (iptcdata) + iptc_data_free_buf (iptc, iptcdata); + error = true; + } + if (!error) + jpeg_write_marker(&cinfo, JPEG_APP0+13, buffer, bytes); + } + delete [] buffer; + + // write icc profile to the output + if (profileData) + write_icc_profile (&cinfo, (JOCTET*)profileData, profileLength); + + // write image data + int rowlen = width*3; + unsigned char *row = new unsigned char [rowlen]; + + /* To avoid memory leaks we establish a new setjmp return context for my_error_exit to use. */ +#if defined( WIN32 ) && defined( __x86_64__ ) + if (__builtin_setjmp(jerr.setjmp_buffer)) { +#else + if (setjmp(jerr.setjmp_buffer)) { +#endif + /* If we get here, the JPEG code has signaled an error. + We need to clean up the JPEG object, close the file, remove the already saved part of the file and return. + */ + delete [] row; + jpeg_destroy_compress(&cinfo); + fclose(file); + safe_g_remove(fname); + return IMIO_CANNOTWRITEFILE; + } + + while (cinfo.next_scanline < cinfo.image_height) { + + getScanline (cinfo.next_scanline, row, 8); + if (jpeg_write_scanlines (&cinfo, &row, 1) < 1) { + jpeg_destroy_compress (&cinfo); + delete [] row; + fclose (file); + safe_g_remove(fname); + return IMIO_CANNOTWRITEFILE; + } + + if (pl && !(cinfo.next_scanline%100)) + pl->setProgress ((double)(cinfo.next_scanline)/cinfo.image_height); + } + + jpeg_finish_compress (&cinfo); + jpeg_destroy_compress (&cinfo); + + delete [] row; + + fclose (file); + if (pl) { + pl->setProgressStr ("PROGRESSBAR_READY"); + pl->setProgress (1.0); + } + + return IMIO_SUCCESS; +} + +int ImageIO::saveTIFF (Glib::ustring fname, int bps, bool uncompressed) { + + //TODO: Handling 32 bits floating point output images! + bool writeOk = true; + int width = getW (); + int height = getH (); + + if (bps<0) + bps = getBPS (); + + int lineWidth = width*3*bps/8; + unsigned char* linebuffer = new unsigned char[lineWidth]; +// TODO the following needs to be looked into - do we really need two ways to write a Tiff file ? + if (exifRoot && uncompressed) { + FILE *file = safe_g_fopen_WriteBinLock (fname); + + if (!file) { + delete [] linebuffer; + return IMIO_CANNOTWRITEFILE; + } + + if (pl) { + pl->setProgressStr ("PROGRESSBAR_SAVETIFF"); + pl->setProgress (0.0); + } + + // buffer for the exif and iptc + unsigned char* buffer = new unsigned char[165535]; //TODO: Is it really 165535... or 65535 ? + unsigned char* iptcdata = NULL; + unsigned int iptclen = 0; + if (iptc && iptc_data_save (iptc, &iptcdata, &iptclen) && iptcdata) { + iptc_data_free_buf (iptc, iptcdata); + iptcdata = NULL; + } + int size = rtexif::ExifManager::createTIFFHeader (exifRoot, exifChange, width, height, bps, profileData, profileLength, (char*)iptcdata, iptclen, buffer); + if (iptcdata) + iptc_data_free_buf (iptc, iptcdata); + + // The maximum lenght is strangely not the same than for the JPEG file... + // Which maximum length is the good one ? + if (size>0 && size<165530) + fwrite (buffer, size, 1, file); + +#if __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__ + bool needsReverse = bps==16 && exifRoot->getOrder()==rtexif::MOTOROLA; +#else + bool needsReverse = bps==16 && exifRoot->getOrder()==rtexif::INTEL; +#endif + + for (int i=0; isetProgress ((double)(i+1)/height); + } + delete [] buffer; + if (ferror(file)) + writeOk = false; + + fclose (file); + } + else { + // little hack to get libTiff to use proper byte order (see TIFFClienOpen()): + const char *mode = !exifRoot ? "w" : (exifRoot->getOrder()==rtexif::INTEL ? "wl":"wb"); + #ifdef WIN32 + wchar_t *wfilename = (wchar_t*)g_utf8_to_utf16 (fname.c_str(), -1, NULL, NULL, NULL); + TIFF* out = TIFFOpenW (wfilename, mode); + g_free (wfilename); + #else + TIFF* out = TIFFOpen(fname.c_str(), mode); + #endif + if (!out) { + delete [] linebuffer; + return IMIO_CANNOTWRITEFILE; + } + + if (pl) { + pl->setProgressStr ("PROGRESSBAR_SAVETIFF"); + pl->setProgress (0.0); + } + + if (exifRoot){ + rtexif::Tag *tag = exifRoot->getTag (TIFFTAG_EXIFIFD); + if (tag && tag->isDirectory()){ + rtexif::TagDirectory *exif = tag->getDirectory(); + if (exif) { + int exif_size = exif->calculateSize(); + unsigned char *buffer = new unsigned char[exif_size+8]; + // TIFFOpen writes out the header and sets file pointer at position 8 + + exif->write (8, buffer); + write (TIFFFileno (out), buffer+8, exif_size); + delete [] buffer; + // let libtiff know that scanlines or any other following stuff should go + // at a different offset: + TIFFSetWriteOffset (out, exif_size+8); + TIFFSetField (out, TIFFTAG_EXIFIFD, 8); + } + } + +//TODO Even though we are saving EXIF IFD - MakerNote still comes out screwed. + + if ((tag = exifRoot->getTag (TIFFTAG_MODEL)) != NULL) + TIFFSetField (out, TIFFTAG_MODEL, tag->getValue()); + if ((tag = exifRoot->getTag (TIFFTAG_MAKE)) != NULL) + TIFFSetField (out, TIFFTAG_MAKE, tag->getValue()); + if ((tag = exifRoot->getTag (TIFFTAG_DATETIME)) != NULL) + TIFFSetField (out, TIFFTAG_DATETIME, tag->getValue()); + if ((tag = exifRoot->getTag (TIFFTAG_ARTIST)) != NULL) + TIFFSetField (out, TIFFTAG_ARTIST, tag->getValue()); + if ((tag = exifRoot->getTag (TIFFTAG_COPYRIGHT)) != NULL) + TIFFSetField (out, TIFFTAG_COPYRIGHT, tag->getValue()); + + } + + Glib::ustring rtVersion("RawTherapee "); + rtVersion += VERSION; + TIFFSetField (out, TIFFTAG_SOFTWARE, rtVersion.c_str()); + TIFFSetField (out, TIFFTAG_IMAGEWIDTH, width); + TIFFSetField (out, TIFFTAG_IMAGELENGTH, height); + TIFFSetField (out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); + TIFFSetField (out, TIFFTAG_SAMPLESPERPIXEL, 3); + TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, height); + TIFFSetField (out, TIFFTAG_BITSPERSAMPLE, bps); + TIFFSetField (out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); + TIFFSetField (out, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT); + TIFFSetField (out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); + TIFFSetField (out, TIFFTAG_COMPRESSION, uncompressed ? COMPRESSION_NONE : COMPRESSION_DEFLATE); + if (!uncompressed) + TIFFSetField (out, TIFFTAG_PREDICTOR, PREDICTOR_NONE); + + if (profileData) + TIFFSetField (out, TIFFTAG_ICCPROFILE, profileLength, profileData); + + for (int row = 0; row < height; row++) { + getScanline (row, linebuffer, bps); + + if (TIFFWriteScanline (out, linebuffer, row, 0) < 0) { + TIFFClose (out); + delete [] linebuffer; + return IMIO_CANNOTWRITEFILE; + } + if (pl && !(row%100)) + pl->setProgress ((double)(row+1)/height); + } + if (TIFFFlush(out)!=1) + writeOk = false; + + TIFFClose (out); + } + + delete [] linebuffer; + if (pl) { + pl->setProgressStr ("PROGRESSBAR_READY"); + pl->setProgress (1.0); + } + + if(writeOk) + return IMIO_SUCCESS; + else { + safe_g_remove(fname); + return IMIO_CANNOTWRITEFILE; + } +} + +// PNG read and write routines: + +void png_read_data(png_structp png_ptr, png_bytep data, png_size_t length) { + png_size_t check; + + /* fread() returns 0 on error, so it is OK to store this in a png_size_t + * instead of an int, which is what fread() actually returns. + */ + check = (png_size_t)fread(data, (png_size_t)1, length, (FILE *)png_get_io_ptr(png_ptr)); + + if (check != length) + { + png_error(png_ptr, "Read Error"); + } +} + +void png_write_data(png_structp png_ptr, png_bytep data, png_size_t length) { + png_uint_32 check; + + check = fwrite(data, 1, length, (FILE *)png_get_io_ptr(png_ptr)); + if (check != length) + { + png_error(png_ptr, "Write Error"); + } +} + +void png_flush(png_structp png_ptr) { + FILE *io_ptr; + io_ptr = (FILE *)(png_get_io_ptr(png_ptr)); + if (io_ptr != NULL) + fflush(io_ptr); +} + +int ImageIO::load (Glib::ustring fname) { + + size_t lastdot = fname.find_last_of ('.'); + if( Glib::ustring::npos == lastdot ) + return IMIO_FILETYPENOTSUPPORTED; + if (!fname.casefold().compare (lastdot, 4, ".png")) + return loadPNG (fname); + else if (!fname.casefold().compare (lastdot, 4, ".jpg") || + !fname.casefold().compare (lastdot, 5, ".jpeg")) + return loadJPEG (fname); + else if (!fname.casefold().compare (lastdot, 4, ".tif") || + !fname.casefold().compare (lastdot, 5, ".tiff")) + return loadTIFF (fname); + else return IMIO_FILETYPENOTSUPPORTED; +} + +int ImageIO::save (Glib::ustring fname) { + + size_t lastdot = fname.find_last_of ('.'); + if( Glib::ustring::npos == lastdot ) + return IMIO_FILETYPENOTSUPPORTED; + if (!fname.casefold().compare (lastdot, 4, ".png")) + return savePNG (fname); + else if (!fname.casefold().compare (lastdot, 4, ".jpg") || + !fname.casefold().compare (lastdot, 5, ".jpeg")) + return saveJPEG (fname); + else if (!fname.casefold().compare (lastdot, 4, ".tif") || + !fname.casefold().compare (lastdot, 5, ".tiff")) + return saveTIFF (fname); + else return IMIO_FILETYPENOTSUPPORTED; +} diff --git a/rtengine/imageio.h b/rtengine/imageio.h new file mode 100644 index 000000000..980d86f92 --- /dev/null +++ b/rtengine/imageio.h @@ -0,0 +1,142 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _IMAGEIO_ +#define _IMAGEIO_ + +#define IMIO_SUCCESS 0 +#define IMIO_CANNOTREADFILE 1 +#define IMIO_INVALIDHEADER 2 +#define IMIO_HEADERERROR 3 +#define IMIO_READERROR 4 +#define IMIO_VARIANTNOTSUPPORTED 5 +#define IMIO_FILETYPENOTSUPPORTED 6 +#define IMIO_CANNOTWRITEFILE 7 + +#include "rtengine.h" +#include +#include "procparams.h" +#include +#include "../rtexif/rtexif.h" +#include "imagedimensions.h" +#include "iimage.h" +#include "colortemp.h" + +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 { + + protected: + ProgressListener* pl; + cmsHPROFILE embProfile; + char* profileData; + int profileLength; + char* loadedProfileData; + bool loadedProfileDataJpg; + int loadedProfileLength; + procparams::ExifPairs exifChange; + IptcData* iptc; + const rtexif::TagDirectory* exifRoot; + MyMutex imutex; + IIOSampleFormat sampleFormat; + IIOSampleArrangement sampleArrangement; + + private: + void deleteLoadedProfileData( ) { if(loadedProfileData) {if(loadedProfileDataJpg) free(loadedProfileData); else delete[] loadedProfileData;} loadedProfileData = NULL; } + public: + static Glib::ustring errorMsg[6]; + + ImageIO () : pl (NULL), embProfile(NULL), profileData(NULL), profileLength(0), loadedProfileData(NULL),loadedProfileDataJpg(false), + loadedProfileLength(0), iptc(NULL), exifRoot (NULL), sampleFormat(IIOSF_UNKNOWN), + sampleArrangement(IIOSA_UNKNOWN) {} + + virtual ~ImageIO (); + + void setProgressListener (ProgressListener* l) { pl = l; } + + void setSampleFormat(IIOSampleFormat sFormat) { sampleFormat = sFormat; } + IIOSampleFormat getSampleFormat() { return sampleFormat; } + void setSampleArrangement(IIOSampleArrangement sArrangement) { sampleArrangement = sArrangement; } + IIOSampleArrangement getSampleArrangement() { return sampleArrangement; } + + virtual void getStdImage (ColorTemp ctemp, int tran, Imagefloat* image, PreviewProps pp, bool first, procparams::ToneCurveParams hrp) { + printf("getStdImage NULL!\n"); + } + + virtual int getBPS () =0; + virtual void getScanline (int row, unsigned char* buffer, int bps) {} + virtual void setScanline (int row, unsigned char* buffer, int bps, float minValue[3]=NULL, float maxValue[3]=NULL) {} + + virtual bool readImage (Glib::ustring &fname, FILE *fh) { return false; }; + virtual bool writeImage (Glib::ustring &fname, FILE *fh) { return false; }; + + int load (Glib::ustring fname); + int save (Glib::ustring fname); + + int loadPNG (Glib::ustring fname); + int loadJPEG (Glib::ustring fname); + int loadTIFF (Glib::ustring fname); + static int getPNGSampleFormat (Glib::ustring fname, IIOSampleFormat &sFormat, IIOSampleArrangement &sArrangement); + static int getTIFFSampleFormat (Glib::ustring fname, IIOSampleFormat &sFormat, IIOSampleArrangement &sArrangement); + + 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 saveJPEG (Glib::ustring fname, int quality = 100, int subSamp=3); + int saveTIFF (Glib::ustring fname, int bps = -1, bool uncompressed = false); + + cmsHPROFILE getEmbeddedProfile () { return embProfile; } + void getEmbeddedProfileData (int& length, unsigned char*& pdata) { length = loadedProfileLength; pdata = (unsigned char*)loadedProfileData; } + + void setMetadata (const rtexif::TagDirectory* eroot); + void setMetadata (const rtexif::TagDirectory* eroot, const rtengine::procparams::ExifPairs& exif, const rtengine::procparams::IPTCPairs& iptcc); + void setOutputProfile (char* pdata, int plen); + MyMutex& mutex () { return imutex; } +}; + +} +#endif diff --git a/rtengine/imagesource.h b/rtengine/imagesource.h new file mode 100644 index 000000000..2aa1faa9f --- /dev/null +++ b/rtengine/imagesource.h @@ -0,0 +1,117 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _IMAGESOURCE_ +#define _IMAGESOURCE_ + +#include +#include +#include "rtengine.h" +#include "colortemp.h" +#include "procparams.h" +#include "coord2d.h" +#include "dcp.h" +#include "LUT.h" +#include "imagedata.h" +#include "image8.h" +#include "image16.h" +#include "imagefloat.h" + +namespace rtengine { + +using namespace procparams; + +class ImageMatrices { + +public: + double rgb_cam[3][3]; + double cam_rgb[3][3]; + double xyz_cam[3][3]; + double cam_xyz[3][3]; +}; + +class ImageSource : public InitialImage { + + private: + int references; + + protected: + double redAWBMul, greenAWBMul, blueAWBMul; // local copy of the multipliers, to avoid recomputing the values + cmsHPROFILE embProfile; + Glib::ustring fileName; + ImageData* idata; + ImageMatrices imatrices; + double dirpyrdenoiseExpComp; + + public: + ImageSource () : references (1), redAWBMul(-1.), greenAWBMul(-1.), blueAWBMul(-1.), + embProfile(NULL), idata(NULL), dirpyrdenoiseExpComp(INFINITY) {} + + virtual ~ImageSource () {} + virtual int load (Glib::ustring fname, bool batch = false) =0; + virtual void preprocess (const RAWParams &raw, const LensProfParams &lensProf, const CoarseTransformParams& coarse){}; + virtual void demosaic (const RAWParams &raw){}; + virtual void flushRawData (){}; + virtual void flushRGB (){}; + virtual void HLRecovery_Global (ToneCurveParams hrp){}; + virtual void HLRecovery_inpaint (float** red, float** green, float** blue){}; + + virtual bool IsrgbSourceModified() =0; // tracks whether cached rgb output of demosaic has been modified + + // use right after demosaicing image, add coarse transformation and put the result in the provided Imagefloat* + virtual void getImage (ColorTemp ctemp, int tran, Imagefloat* image, PreviewProps pp, ToneCurveParams hlp, ColorManagementParams cmp, RAWParams raw) {} + virtual eSensorType getSensorType () { return ST_NONE; } + // true is ready to provide the AutoWB, i.e. when the image has been demosaiced for RawImageSource + virtual bool isWBProviderReady () =0; + + virtual void convertColorSpace (Imagefloat* image, ColorManagementParams cmp, ColorTemp &wb) =0;// DIRTY HACK: this method is derived in rawimagesource and strimagesource, but (...,RAWParams raw) will be used ONLY for raw images + virtual void getAutoWBMultipliers (double &rm, double &gm, double &bm) =0; + virtual ColorTemp getWB () =0; + virtual ColorTemp getSpotWB (std::vector &red, std::vector &green, std::vector &blue, int tran, double equal) =0; + + virtual double getDefGain () { return 1.0; } + + virtual double getGamma () { return 0.0; } + + virtual void getFullSize (int& w, int& h, int tr = TR_NONE) {} + virtual void getSize (int tran, PreviewProps pp, int& w, int& h) {} + virtual int getRotateDegree() const { return 0; } + + virtual ImageData* getImageData () =0; + virtual ImageMatrices* getImageMatrices () =0; + virtual bool isRAW() const =0; + virtual DCPProfile* getDCP(ColorManagementParams cmp, ColorTemp &wb) { return NULL; }; + + virtual void setProgressListener (ProgressListener* pl) {} + + void increaseRef () { references++; } + void decreaseRef () { references--; if (!references) delete this; } + + virtual void getAutoExpHistogram (LUTu & histogram, int& histcompr)=0; + virtual void getRAWHistogram (LUTu & histRedRaw, LUTu & histGreenRaw, LUTu & histBlueRaw) { + histRedRaw.clear(); histGreenRaw.clear(); histBlueRaw.clear(); // only some sources will supply this + } + double getDirPyrDenoiseExpComp ( ) { return dirpyrdenoiseExpComp; } + // functions inherited from the InitialImage interface + virtual Glib::ustring getFileName () { return fileName; } + virtual cmsHPROFILE getEmbeddedProfile () { return embProfile; } + virtual const ImageMetaData* getMetaData () { return idata; } + virtual ImageSource* getImageSource () { return this; } +}; +} +#endif diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc new file mode 100644 index 000000000..8deffe19e --- /dev/null +++ b/rtengine/improccoordinator.cc @@ -0,0 +1,1105 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "improccoordinator.h" +#include "curves.h" +#include "mytime.h" +#include "refreshmap.h" +#include "../rtgui/ppversion.h" +#include "colortemp.h" +#include "improcfun.h" + +namespace rtengine { + +extern const Settings* settings; + +ImProcCoordinator::ImProcCoordinator () + : orig_prev(NULL), oprevi(NULL), oprevl(NULL), nprevl(NULL), previmg(NULL), workimg(NULL), + ncie(NULL), imgsrc(NULL), shmap(NULL), lastAwbEqual(0.), ipf(¶ms, true), scale(10), + highDetailPreprocessComputed(false), highDetailRawComputed(false), allocated(false), + bwAutoR(-9000.f), bwAutoG(-9000.f), bwAutoB(-9000.f), CAMMean(0.), + + hltonecurve(65536), + shtonecurve(65536), + tonecurve(65536,0),//,1); + chaut(0.f), redaut(0.f), blueaut(0.f), maxredaut(0.f), maxblueaut(0.f),minredaut(0.f), minblueaut(0.f),nresi(0.f), + chromina(0.f), sigma(0.f), lumema(0.f), + lumacurve(65536,0), + chroma_acurve(65536,0), + chroma_bcurve(65536,0), + satcurve(65536,0), + lhskcurve(65536,0), + clcurve(65536,0), + wavclCurve(65536,0), + clToningcurve(65536,0), + cl2Toningcurve(65536,0), + Noisecurve(65536,0), + NoiseCCcurve(65536,0), + vhist16(65536),vhist16bw(65536), + lhist16(65536), lhist16Cropped(65536), + lhist16CAM(65536), lhist16CroppedCAM(65536), + lhist16CCAM(65536), + histCropped(65536), + lhist16Clad(65536),lhist16CLlad(65536), + lhist16LClad(65536), lhist16LLClad(65536), + histRed(256), histRedRaw(256), + histGreen(256), histGreenRaw(256), + histBlue(256), histBlueRaw(256), + histLuma(256), + histToneCurve(256), + histToneCurveBW(256), + histLCurve(256), + histCCurve(256), + histCLurve(256), + histLLCurve(256), + + histLCAM(256), + histCCAM(256), + histClad(256), + bcabhist(256), + histChroma(256), + + CAMBrightCurveJ(), CAMBrightCurveQ(), + + rCurve(), + gCurve(), + bCurve(), + rcurvehist(256), rcurvehistCropped(256), rbeforehist(256), + gcurvehist(256), gcurvehistCropped(256), gbeforehist(256), + bcurvehist(256), bcurvehistCropped(256), bbeforehist(256), + fullw(1),fullh(1), + pW(-1), pH(-1), + plistener(NULL), imageListener(NULL), aeListener(NULL), acListener(NULL),abwListener(NULL),actListener(NULL),adnListener(NULL), awavListener(NULL), hListener(NULL), + resultValid(false), changeSinceLast(0), updaterRunning(false), destroying(false),utili(false),autili(false),wavcontlutili(false), + butili(false),ccutili(false),cclutili(false),clcutili(false),opautili(false) + + {} + +void ImProcCoordinator::assign (ImageSource* imgsrc) { + this->imgsrc = imgsrc; +} + +ImProcCoordinator::~ImProcCoordinator () { + + destroying = true; + updaterThreadStart.lock (); + if (updaterRunning && thread) + thread->join (); + mProcessing.lock(); + mProcessing.unlock(); + freeAll (); + + std::vector toDel = crops; + for (size_t i=0; idecreaseRef (); + updaterThreadStart.unlock (); +} + +DetailedCrop* ImProcCoordinator::createCrop (::EditDataProvider *editDataProvider, bool isDetailWindow) { + + return new Crop (this, editDataProvider, isDetailWindow); +} + + +// todo: bitmask containing desired actions, taken from changesSinceLast +// cropCall: calling crop, used to prevent self-updates ...doesn't seem to be used +void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) { + + MyMutex::MyLock processingLock(mProcessing); + int numofphases = 14; + int readyphase = 0; + + bwAutoR = bwAutoG = bwAutoB = -9000.f; + chaut=redaut=blueaut=maxredaut=maxblueaut=nresi=highresi=0.f; + chromina=sigma=lumema=0.f; + minredaut=minblueaut=10000.f; + if (todo==CROP && ipf.needsPCVignetting()) + todo |= TRANSFORM; // Change about Crop does affect TRANSFORM + + bool highDetailNeeded = false; + + if (options.prevdemo==PD_Sidecar) highDetailNeeded = true; //i#2664 + else highDetailNeeded = (todo & M_HIGHQUAL); + + // Check if any detail crops need high detail. If not, take a fast path short cut + if (!highDetailNeeded) { + for (size_t i=0; iget_skip() == 1 ) { // skip=1 -> full resolution + highDetailNeeded=true; + break; + } + } + + RAWParams rp = params.raw; + if( !highDetailNeeded ){ + // if below 100% magnification, take a fast path + if(rp.bayersensor.method != RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::none] && rp.bayersensor.method != RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::mono]) + rp.bayersensor.method = RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::fast]; + //bayerrp.all_enhance = false; + + if(rp.xtranssensor.method != RAWParams::XTransSensor::methodstring[RAWParams::XTransSensor::none] && rp.xtranssensor.method != RAWParams::XTransSensor::methodstring[RAWParams::XTransSensor::mono]) + rp.xtranssensor.method = RAWParams::XTransSensor::methodstring[RAWParams::XTransSensor::fast]; + + rp.bayersensor.ccSteps = 0; + rp.xtranssensor.ccSteps = 0; + //rp.deadPixelFilter = rp.hotPixelFilter = false; + } + + progress ("Applying white balance, color correction & sRGB conversion...",100*readyphase/numofphases); + // raw auto CA is bypassed if no high detail is needed, so we have to compute it when high detail is needed + if ( (todo & M_PREPROC) || (!highDetailPreprocessComputed && highDetailNeeded)) { + imgsrc->preprocess( rp, params.lensProf, params.coarse ); + imgsrc->getRAWHistogram( histRedRaw, histGreenRaw, histBlueRaw ); + if (highDetailNeeded) + highDetailPreprocessComputed = true; + else + highDetailPreprocessComputed = false; + } + + /* + Demosaic is kicked off only when + Detail considerations: + accurate detail is not displayed yet needed based on preview specifics (driven via highDetailNeeded flag) + OR + HLR considerations: + Color HLR alters rgb output of demosaic, so re-demosaic is needed when Color HLR is being turned off; + if HLR is enabled and changing method *from* Color to any other method + OR HLR gets disabled when Color method was selected + */ + // If high detail (=100%) is newly selected, do a demosaic update, since the last was just with FAST + if ( (todo & M_RAW) + || (!highDetailRawComputed && highDetailNeeded) + || ( 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) + printf("Demosaic Bayer image using method: %s\n",rp.bayersensor.method.c_str()); + else if (imgsrc->getSensorType() == ST_FUJI_XTRANS) + printf("Demosaic X-Trans image with using method: %s\n",rp.xtranssensor.method.c_str()); + } + + imgsrc->demosaic( rp ); + + if (highDetailNeeded) { + highDetailRawComputed = true; + if (params.toneCurve.hrenabled && params.toneCurve.method=="Color") { + todo |= M_INIT; + } + } + else + highDetailRawComputed = false; + } + + // Updating toneCurve.hrenabled if necessary + // It has to be done there, because the next 'if' statement will use the value computed here + if (todo & M_AUTOEXP) { + if (params.toneCurve.autoexp) {// this enabled HLRecovery + if (ToneCurveParams::HLReconstructionNecessary(histRedRaw, histGreenRaw, histBlueRaw) && !params.toneCurve.hrenabled) { + // switching params.toneCurve.hrenabled to true -> shouting in listener's ears! + params.toneCurve.hrenabled=true; + + // forcing INIT to be done, to reconstruct HL again + todo |= M_INIT; + } + } + } + + if (todo & (M_INIT|M_LINDENOISE)) { + MyMutex::MyLock initLock(minit); // Also used in crop window + + imgsrc->HLRecovery_Global( params.toneCurve ); // this handles Color HLRecovery + if (settings->verbose) printf ("Applying white balance, color correction & sRBG conversion...\n"); + currWB = ColorTemp (params.wb.temperature, params.wb.green, params.wb.equal, params.wb.method); + if (params.wb.method=="Camera") + currWB = imgsrc->getWB (); + else if (params.wb.method=="Auto") { + if (lastAwbEqual != params.wb.equal) { + double rm, gm, bm; + imgsrc->getAutoWBMultipliers(rm, gm, bm); + if (rm != -1.) { + autoWB.update(rm, gm, bm, params.wb.equal); + lastAwbEqual = params.wb.equal; + } + else { + lastAwbEqual = -1.; + autoWB.useDefaults(params.wb.equal); + } + //double rr,gg,bb; + //autoWB.getMultipliers(rr,gg,bb); + } + currWB = autoWB; + } + params.wb.temperature = currWB.getTemp (); + params.wb.green = currWB.getGreen (); + + int tr = getCoarseBitMask(params.coarse); + + imgsrc->getFullSize (fw, fh, tr); + + // Will (re)allocate the preview's buffers + setScale (scale); + PreviewProps pp (0, 0, fw, fh, scale); + // 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, pp, params.toneCurve, params.icm, params.raw); + //ColorTemp::CAT02 (orig_prev, ¶ms) ; + +/* Issue 2785, disabled some 1:1 tools + if (todo & M_LINDENOISE) { + DirPyrDenoiseParams denoiseParams = params.dirpyrDenoise; + if (denoiseParams.enabled && (scale==1)) { + Imagefloat *calclum = NULL ; + + denoiseParams.getCurves(noiseLCurve,noiseCCurve); + int nbw=6;//nb tile W + int nbh=4;// + + float ch_M[nbw*nbh]; + float max_r[nbw*nbh]; + float max_b[nbw*nbh]; + + if(denoiseParams.Lmethod == "CUR") { + if(noiseLCurve) + denoiseParams.luma = 0.5f; + else + denoiseParams.luma = 0.0f; + } else if(denoiseParams.Lmethod == "SLI") + noiseLCurve.Reset(); + + + if(noiseLCurve || noiseCCurve){//only allocate memory if enabled and scale=1 + // we only need image reduced to 1/4 here + calclum = new Imagefloat ((pW+1)/2, (pH+1)/2);//for luminance denoise curve + for(int ii=0;iir(ii>>1,jj>>1) = orig_prev->r(ii,jj); + calclum->g(ii>>1,jj>>1) = orig_prev->g(ii,jj); + calclum->b(ii>>1,jj>>1) = orig_prev->b(ii,jj); + } + } + imgsrc->convertColorSpace(calclum, params.icm, currWB);//claculate values after colorspace conversion + } + + int kall=1; + ipf.RGB_denoise(kall, orig_prev, orig_prev, calclum, ch_M, max_r, max_b, imgsrc->isRAW(), denoiseParams, imgsrc->getDirPyrDenoiseExpComp(), noiseLCurve, noiseCCurve, chaut, redaut, blueaut, maxredaut, maxblueaut, nresi, highresi); + } + } +*/ + imgsrc->convertColorSpace(orig_prev, params.icm, currWB); + + ipf.firstAnalysis (orig_prev, ¶ms, vhist16); + } + readyphase++; + + progress ("Rotate / Distortion...",100*readyphase/numofphases); + // Remove transformation if unneeded + bool needstransform = ipf.needsTransform(); + if (!needstransform && orig_prev!=oprevi) { + delete oprevi; + oprevi = orig_prev; + } + if (needstransform && orig_prev==oprevi) + oprevi = new Imagefloat (pW, pH); + if ((todo & M_TRANSFORM) && needstransform) + ipf.transform (orig_prev, oprevi, 0, 0, 0, 0, pW, pH, fw, fh, imgsrc->getMetaData()->getFocalLen(), + imgsrc->getMetaData()->getFocalLen35mm(), imgsrc->getMetaData()->getFocusDist(), imgsrc->getRotateDegree(), false); + + 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); + } + } + + progress ("Exposure curve & CIELAB conversion...",100*readyphase/numofphases); + if ((todo & M_RGBCURVE) || (todo & M_CROP)) { +// if (hListener) oprevi->calcCroppedHistogram(params, scale, histCropped); + + //complexCurve also calculated pre-curves histogram depending on crop + ipf.g = imgsrc->getGamma(); + ipf.iGamma = true; + CurveFactory::complexCurve (/*params.toneCurve.expcomp*/ 0.0, params.toneCurve.black/65535.0, + params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh, + params.toneCurve.shcompr, params.toneCurve.brightness, params.toneCurve.contrast, + ipf.g, !ipf.iGamma, params.toneCurve.curveMode, params.toneCurve.curve, params.toneCurve.curveMode2, params.toneCurve.curve2, + vhist16, histCropped, hltonecurve, shtonecurve, tonecurve, histToneCurve, customToneCurve1, customToneCurve2, scale==1 ? 1 : 1); + + CurveFactory::RGBCurve (params.rgbCurves.rcurve, rCurve, scale==1 ? 1 : 1); + CurveFactory::RGBCurve (params.rgbCurves.gcurve, gCurve, scale==1 ? 1 : 1); + CurveFactory::RGBCurve (params.rgbCurves.bcurve, bCurve, scale==1 ? 1 : 1); + + TMatrix wprof = iccStore->workingSpaceMatrix (params.icm.working); + double wp[3][3] = { + {wprof[0][0],wprof[0][1],wprof[0][2]}, + {wprof[1][0],wprof[1][1],wprof[1][2]}, + {wprof[2][0],wprof[2][1],wprof[2][2]}}; + TMatrix wiprof = iccStore->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]} + }; + opautili=false; + params.colorToning.getCurves(ctColorCurve, ctOpacityCurve, wp, wip, opautili); + + bool clctoningutili=false; + bool llctoningutili=false; + CurveFactory::curveToningCL(clctoningutili, params.colorToning.clcurve, clToningcurve,scale==1 ? 1 : 16); + // clToningcurve.dump("CLToning3"); + CurveFactory::curveToningLL(llctoningutili, params.colorToning.cl2curve, cl2Toningcurve,scale==1 ? 1 : 16); + + CurveFactory::curveBW (params.blackwhite.beforeCurve,params.blackwhite.afterCurve, vhist16bw, histToneCurveBW, beforeToneCurveBW, afterToneCurveBW,scale==1 ? 1 : 1); + + + float satLimit = float(params.colorToning.satProtectionThreshold)/100.f*0.7f+0.3f; + float satLimitOpacity = 1.f-(float(params.colorToning.saturatedOpacity)/100.f); + + int satTH=80; + int satPR=30; + int indi=0; + if(params.colorToning.enabled && params.colorToning.autosat){//for colortoning evaluation of saturation settings + float moyS=0.f; + float eqty=0.f; + ipf.moyeqt (oprevi, moyS, eqty);//return image : mean saturation and standard dev of saturation + //printf("moy=%f ET=%f\n", moyS,eqty); + float satp=((moyS+1.5f*eqty)-0.3f)/0.7f;//1.5 sigma ==> 93% pixels with high saturation -0.3 / 0.7 convert to Hombre scale + if(satp >= 0.92f) satp=0.92f;//avoid values too high (out of gamut) + if(satp <= 0.15f) satp=0.15f;//avoid too low values + + //satTH=(int) 100.f*satp; + //satPR=(int) 100.f*(moyS-0.85f*eqty);//-0.85 sigma==>20% pixels with low saturation + satLimit= 100.f*satp; + satTH = (int) 100.f*satp; + + satLimitOpacity= 100.f*(moyS-0.85f*eqty);//-0.85 sigma==>20% pixels with low saturation + satPR= (int) 100.f*(moyS-0.85f*eqty); + } + if(actListener) { + //if(params.blackwhite.enabled) {actListener->autoColorTonChanged(0, satTH, satPR);} + if(params.blackwhite.enabled && params.colorToning.autosat) {actListener->autoColorTonChanged(0, satTH, satPR);indi=0;}//hide sliders only if autosat + else { + if(params.colorToning.autosat){ + if (params.colorToning.method=="Lab") indi=1; + else if(params.colorToning.method=="RGBCurves") indi=1; + else if(params.colorToning.method=="RGBSliders") indi=1; + else if(params.colorToning.method=="Splico") indi=2; + else if(params.colorToning.method=="Splitlr") indi=2; + + //actListener->autoColorTonChanged(indi, satTH, satPR); + } + } + } + // if it's just crop we just need the histogram, no image updates + if ( todo & M_RGBCURVE ) { + //initialize rrm bbm ggm different from zero to avoid black screen in some cases + double rrm=33.; + double ggm=33.; + double bbm=33.; + + DCPProfile *dcpProf = imgsrc->getDCP(params.icm, currWB); + ipf.rgbProc (oprevi, oprevl, NULL, hltonecurve, shtonecurve, tonecurve, shmap, params.toneCurve.saturation, + rCurve, gCurve, bCurve, satLimit ,satLimitOpacity, 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); + if(params.blackwhite.enabled && params.blackwhite.autoc && abwListener) { + if (settings->verbose) + printf("ImProcCoordinator / Auto B&W coefs: R=%.2f G=%.2f B=%.2f\n", bwAutoR, bwAutoG, bwAutoB); + abwListener->BWChanged((float) rrm, (float) ggm, (float) bbm); + } + if(params.colorToning.autosat && actListener) { + if (settings->verbose) + printf("ImProcCoordinator / Auto CT: indi=%d satH=%d satPR=%d\n", indi,(int)satLimit , (int) satLimitOpacity); + actListener->autoColorTonChanged(indi, (int) satLimit, (int)satLimitOpacity);//change sliders autosat + } + // correct GUI black and white with value + } + // compute L channel histogram + int x1, y1, x2, y2, pos; + params.crop.mapToResized(pW, pH, scale, x1, x2, y1, y2); + lhist16.clear(); lhist16Cropped.clear(); + lhist16Clad.clear(); lhist16CLlad.clear();lhist16LLClad.clear(); + for (int x=0; xL[x][y])); + lhist16[pos]++; + if (y>=y1 && y=x1 && x170.. + else if (params.icm.working=="Adobe RGB") {adjustr = 1.8f; adjustbg = 1.4f;} + else if (params.icm.working=="sRGB") {adjustr = 2.0f; adjustbg = 1.7f;} + else if (params.icm.working=="WideGamut") {adjustr = adjustbg = 1.2f;} + else if (params.icm.working=="Beta RGB") {adjustr = adjustbg = 1.4f;} + else if (params.icm.working=="BestRGB") {adjustr = adjustbg = 1.4f;} + else if (params.icm.working=="BruceRGB") {adjustr = 1.8f; adjustbg = 1.5f;} +*/ + CurveFactory::complexsgnCurve (adjustr, autili, butili,ccutili,cclutili, params.labCurve.chromaticity, params.labCurve.rstprotection, + params.labCurve.acurve, params.labCurve.bcurve,params.labCurve.cccurve,params.labCurve.lccurve,chroma_acurve, chroma_bcurve, satcurve,lhskcurve, + lhist16Clad, lhist16LLClad, histCCurve, histLLCurve, scale==1 ? 1 : 16); + } + if (todo & (M_LUMINANCE+M_COLOR) ) { + nprevl->CopyFrom(oprevl); + + progress ("Applying Color Boost...",100*readyphase/numofphases); + + ipf.chromiLuminanceCurve (NULL, pW,nprevl, nprevl, chroma_acurve, chroma_bcurve, satcurve, lhskcurve, clcurve, lumacurve, utili, autili, butili, ccutili,cclutili,clcutili, histCCurve, histCLurve, histLLCurve, histLCurve); + ipf.vibrance(nprevl); + if((params.colorappearance.enabled && !params.colorappearance.tonecie) || (!params.colorappearance.enabled)) ipf.EPDToneMap(nprevl,5,1); + // for all treatments Defringe, Sharpening, Contrast detail , Microcontrast they are activated if "CIECAM" function are disabled + readyphase++; + +/* Issue 2785, disabled some 1:1 tools + if (scale==1) { + if((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)){ + progress ("Denoising luminance impulse...",100*readyphase/numofphases); + ipf.impulsedenoise (nprevl); + readyphase++; + } + if((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)){ + progress ("Defringing...",100*readyphase/numofphases); + ipf.defringe (nprevl); + readyphase++; + } + if (params.sharpenEdge.enabled) { + progress ("Edge sharpening...",100*readyphase/numofphases); + ipf.MLsharpen (nprevl); + readyphase++; + } + if (params.sharpenMicro.enabled) { + if(( params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)){ + progress ("Microcontrast...",100*readyphase/numofphases); + ipf.MLmicrocontrast (nprevl); + readyphase++; + } + } + if(((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) && params.sharpening.enabled) { + progress ("Sharpening...",100*readyphase/numofphases); + + float **buffer = new float*[pH]; + for (int i=0; iautocielab) || (!params.colorappearance.enabled)){ + progress ("Pyramid wavelet...",100*readyphase/numofphases); + ipf.dirpyrequalizer (nprevl, scale); + //ipf.Lanczoslab (ip_wavelet(LabImage * lab, LabImage * dst, const procparams::EqualizerParams & eqparams), nprevl, 1.f/scale); + readyphase++; + } + //} + + wavcontlutili = false; + //CurveFactory::curveWavContL ( wavcontlutili,params.wavelet.lcurve, wavclCurve, LUTu & histogramwavcl, LUTu & outBeforeWavCLurveHistogram,int skip); + CurveFactory::curveWavContL(wavcontlutili, params.wavelet.wavclCurve, wavclCurve , /*lhist16CLlad, histCLurve,*/ scale==1 ? 1 : 16); + + + if((params.wavelet.enabled)) { + WaveletParams WaveParams = params.wavelet; + // WaveParams.getCurves(wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY); + WaveParams.getCurves(wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL); + + 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); + + } + + + if(params.colorappearance.enabled){ + //L histo and Chroma histo for ciecam + // histogram well be for Lab (Lch) values, because very difficult to do with J,Q, M, s, C + int x1, y1, x2, y2, pos, posc; + params.crop.mapToResized(pW, pH, scale, x1, x2, y1, y2); + lhist16CAM.clear(); lhist16CroppedCAM.clear(); + lhist16CCAM.clear(); + for (int x=0; xL[x][y])); + if(!params.colorappearance.datacie) { + posc=CLIP((int)sqrt(nprevl->a[x][y]*nprevl->a[x][y] + nprevl->b[x][y]*nprevl->b[x][y])); + lhist16CAM[pos]++; + lhist16CCAM[posc]++; + } + if (y>=y1 && y=x1 && xgetMetaData()->getFNumber (); // F number + float fiso = imgsrc->getMetaData()->getISOSpeed () ; // ISO + float fspeed = imgsrc->getMetaData()->getShutterSpeed () ; // Speed + double fcomp = imgsrc->getMetaData()->getExpComp (); // Compensation +/- + double adap; + if(fnum < 0.3f || fiso < 5.f || fspeed < 0.00001f) { //if no exif data or wrong + adap=2000.; + } + else { + double E_V = fcomp + log2 (double((fnum*fnum) / fspeed / (fiso/100.f))); + E_V += params.toneCurve.expcomp;// exposure compensation in tonecurve ==> direct EV + E_V += log2(params.raw.expos);// exposure raw white point ; log2 ==> linear to EV + adap= powf(2.f, E_V-3.f);// cd / m2 + // end calculation adaptation scene luminosity + } + int begh=0; + int endh=pH; + float d; + bool execsharp=false; + + if(!ncie) + ncie = new CieImage (pW, pH); + + if (!CAMBrightCurveJ && (params.colorappearance.algo=="JC" || params.colorappearance.algo=="JS" || params.colorappearance.algo=="ALL")) + CAMBrightCurveJ(32768,0); + if (!CAMBrightCurveQ && (params.colorappearance.algo=="QM" || params.colorappearance.algo=="ALL")) + CAMBrightCurveQ(32768,0); + // Issue 2785, only float version of ciecam02 for navigator and pan background + ipf.ciecam_02float (ncie, float(adap), begh, endh, pW, 2, nprevl, ¶ms, customColCurve1,customColCurve2,customColCurve3, histLCAM, histCCAM, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, execsharp, d, scale, 1); + if(params.colorappearance.autodegree && acListener && params.colorappearance.enabled) acListener->autoCamChanged(100.*(double)d); + if(params.colorappearance.autoadapscen && acListener && params.colorappearance.enabled) acListener->adapCamChanged(adap);//real value of adapt scene luminosity + + readyphase++; + } else { + // CIECAM is disabled, we free up its image buffer to save some space + if (ncie) + delete ncie; ncie=NULL; + + if (CAMBrightCurveJ) CAMBrightCurveJ.reset(); + if (CAMBrightCurveQ) CAMBrightCurveQ.reset(); + } + } + // process crop, if needed + for (size_t i=0; ihasListener () && cropCall != crops[i] ) + crops[i]->update (todo); // may call ourselves + + // Flagging some LUT as dirty now, whether they have been freed up or not + CAMBrightCurveJ.dirty = true; + CAMBrightCurveQ.dirty = true; + + + progress ("Conversion to RGB...",100*readyphase/numofphases); + if (todo!=CROP && todo!=MINUPDATE) { + MyMutex::MyLock prevImgLock(previmg->getMutex()); + try + { + ipf.lab2monitorRgb (nprevl, previmg); + delete workimg; + Glib::ustring outProfile = params.icm.output; + + if(settings->HistogramWorking) { + Glib::ustring workProfile = params.icm.working; + workimg = ipf.lab2rgb (nprevl, 0,0,pW,pH, workProfile, true); + } else { + if (params.icm.output=="" || params.icm.output==ColorManagementParams::NoICMString) + outProfile="sRGB"; + workimg = ipf.lab2rgb (nprevl, 0,0,pW,pH, outProfile, false); + } + } + catch(char * str) + { + progress ("Error converting file...",0); + return; + } + } + if (!resultValid) { + resultValid = true; + if (imageListener) + imageListener->setImage (previmg, scale, params.crop); + } + if (imageListener) + // TODO: The WB tool should be advertised too in order to get the AutoWB's temp and green values + imageListener->imageReady (params.crop); + + readyphase++; + + if (hListener) { + updateLRGBHistograms (); + hListener->histogramChanged (histRed, histGreen, histBlue, histLuma, histToneCurve, histLCurve,histCCurve, /*histCLurve, histLLCurve,*/ histLCAM, histCCAM, histRedRaw, histGreenRaw, histBlueRaw, histChroma); + } +} + + +void ImProcCoordinator::freeAll () { + + if (settings->verbose) printf ("freeall starts %d\n", (int)allocated); + + if (allocated) { + if (orig_prev!=oprevi) + delete oprevi; oprevi = NULL; + delete orig_prev; orig_prev = NULL; + delete oprevl; oprevl = NULL; + delete nprevl; nprevl = NULL; + if (ncie) + delete ncie; ncie = NULL; + + if (imageListener) { + imageListener->delImage (previmg); + } + else + delete previmg; + + delete workimg; + if(shmap) + delete shmap; shmap = NULL; + + } + allocated = false; +} + +/** @brief Handles image buffer (re)allocation and trigger sizeChanged of SizeListener[s] + * If the scale change, this method will free all buffers and reallocate ones of the new size. + * It will then tell to the SizeListener that size has changed (sizeChanged) + * + * @param prevscale New Preview's scale. + */ +void ImProcCoordinator::setScale (int prevscale) { + + if (settings->verbose) + printf ("setscale before lock\n"); + + tr = getCoarseBitMask(params.coarse); + + int nW, nH; + imgsrc->getFullSize (fw, fh, tr); + + prevscale++; + do { + prevscale--; + PreviewProps pp (0, 0, fw, fh, prevscale); + imgsrc->getSize (tr, pp, nW, nH); + } while(nH<400 && prevscale>1 && (nW*nH < 1000000) ); // sctually hardcoded values, perhaps a better choice is possible + + if (settings->verbose) printf ("setscale starts (%d, %d)\n", nW, nH); + + if (nW!=pW || nH!=pH) { + + freeAll (); + + pW = nW; + pH = nH; + + orig_prev = new Imagefloat (pW, pH); + oprevi = orig_prev; + oprevl = new LabImage (pW, pH); + nprevl = new LabImage (pW, pH); + //ncie is only used in ImProcCoordinator::updatePreviewImage, it will be allocated on first use and deleted if not used anymore + previmg = new Image8 (pW, pH); + workimg = new Image8 (pW, pH); + if(params.sh.enabled) { + shmap = new SHMap (pW, pH, true); + } + + allocated = true; + } + + scale = prevscale; + resultValid = false; + fullw = fw; + fullh = fh; + if (settings->verbose) printf ("setscale ends\n"); + if (!sizeListeners.empty()) + for (size_t i=0; isizeChanged (fullw, fullh, fw, fh); + if (settings->verbose) printf ("setscale ends2\n"); + +} + + +void ImProcCoordinator::updateLRGBHistograms () { + + int x1, y1, x2, y2; + params.crop.mapToResized(pW, pH, scale, x1, x2, y1, y2); + +#pragma omp parallel sections +{ +#pragma omp section +{ + histChroma.clear(); + for (int i=y1; ia[i][j]) + SQR(nprevl->b[i][j]))/188.f)]++;//188 = 48000/256 + } +} +#pragma omp section +{ + histLuma.clear(); + for (int i=y1; iL[i][j]/128.f)]++; + } +} +#pragma omp section +{ + histRed.clear(); + histGreen.clear(); + histBlue.clear(); + + for (int i=y1; idata[ofs++]; + int g=workimg->data[ofs++]; + int b=workimg->data[ofs++]; + + histRed[r]++; + histGreen[g]++; + histBlue[b]++; + } + } +} +} + +} + +void ImProcCoordinator::progress (Glib::ustring str, int pr) { + +/* if (plistener) { + plistener->setProgressStr (str); + plistener->setProgress ((double)pr / 100.0); + }*/ +} + +bool ImProcCoordinator::getAutoWB (double& temp, double& green, double equal) { + + if (imgsrc) { + if (lastAwbEqual != equal) { +// Issue 2500 MyMutex::MyLock lock(minit); // Also used in crop window + double rm, gm, bm; + imgsrc->getAutoWBMultipliers(rm, gm, bm); + if (rm != -1) { + autoWB.update(rm, gm, bm, equal); + lastAwbEqual = equal; + } + else { + lastAwbEqual = -1.; + autoWB.useDefaults(equal); + } + } + temp = autoWB.getTemp (); + green = autoWB.getGreen (); + return true; + } + else { + //temp = autoWB.getTemp(); + temp = -1.0; + green = -1.0; + return false; + } +} + +void ImProcCoordinator::getCamWB (double& temp, double& green) { + + if (imgsrc) { + temp = imgsrc->getWB().getTemp (); + green = imgsrc->getWB().getGreen (); + } +} + +void ImProcCoordinator::getSpotWB (int x, int y, int rect, double& temp, double& tgreen) { + + ColorTemp ret; + + { + MyMutex::MyLock lock(mProcessing); + std::vector points, red, green, blue; + for (int i=y-rect; i<=y+rect; i++) + for (int j=x-rect; j<=x+rect; j++) + points.push_back (Coord2D (j, i)); + + ipf.transCoord (fw, fh, points, red, green, blue); + + int tr = getCoarseBitMask(params.coarse); + + ret = imgsrc->getSpotWB (red, green, blue, tr, params.wb.equal); + currWB = ColorTemp (params.wb.temperature, params.wb.green,params.wb.equal, params.wb.method); + //double rr,gg,bb; + //currWB.getMultipliers(rr,gg,bb); + + } // end of mutex lockong + + if (ret.getTemp() > 0) { + temp = ret.getTemp (); + tgreen = ret.getGreen (); + } else { + temp = currWB.getTemp (); + tgreen = currWB.getGreen (); + } +} + +void ImProcCoordinator::getAutoCrop (double ratio, int &x, int &y, int &w, int &h) { + + MyMutex::MyLock lock(mProcessing); + + LCPMapper *pLCPMap=NULL; + if (params.lensProf.lcpFile.length() && imgsrc->getMetaData()->getFocalLen()>0) { + LCPProfile *pLCPProf=lcpStore->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()); + } + + double fillscale = ipf.getTransformAutoFill (fullw, fullh, pLCPMap); + if (ratio>0) { + w = fullw * fillscale; + h = w / ratio; + if (h > fullh * fillscale) { + h = fullh * fillscale; + w = h * ratio; + } + } + else { + w = fullw * fillscale; + h = fullh * fillscale; + } + x = (fullw - w) / 2; + y = (fullh - h) / 2; +} + + +void ImProcCoordinator::saveInputICCReference (const Glib::ustring& fname, bool apply_wb) { + + MyMutex::MyLock lock(mProcessing); + + int fW, fH; + + int tr = getCoarseBitMask(params.coarse); + + imgsrc->getFullSize (fW, fH, tr); + PreviewProps pp (0, 0, fW, fH, 1); + ProcParams ppar = params; + ppar.toneCurve.hrenabled = false; + ppar.icm.input = "(none)"; + Imagefloat* im = new Imagefloat (fW, fH); + imgsrc->preprocess( ppar.raw, ppar.lensProf, ppar.coarse ); + imgsrc->demosaic(ppar.raw ); + ColorTemp currWB = ColorTemp (params.wb.temperature, params.wb.green, params.wb.equal, params.wb.method); + if (params.wb.method=="Camera") + currWB = imgsrc->getWB (); + else if (params.wb.method=="Auto") { + if (lastAwbEqual != params.wb.equal) { + double rm, gm, bm; + imgsrc->getAutoWBMultipliers(rm, gm, bm); + if (rm != -1.) { + autoWB.update(rm, gm, bm, params.wb.equal); + lastAwbEqual = params.wb.equal; + } + else { + lastAwbEqual = -1.; + autoWB.useDefaults(params.wb.equal); + } + } + currWB = autoWB; + } + if (!apply_wb) { + currWB = ColorTemp(); // = no white balance + } + imgsrc->getImage (currWB, tr, im, pp, ppar.toneCurve, ppar.icm, 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->getRotateDegree(), true); + delete im; + im = trImg; + } + if (params.crop.enabled) { + Imagefloat *tmpim = new Imagefloat (params.crop.w, params.crop.h); + int cx = params.crop.x; + int cy = params.crop.y; + int cw = params.crop.w; + int ch = params.crop.h; +#pragma omp parallel for + for (int i=cy; ir(i-cy, j-cx) = im->r(i, j); + tmpim->g(i-cy, j-cx) = im->g(i, j); + tmpim->b(i-cy, j-cx) = im->b(i, j); + } + } + delete im; + im = tmpim; + } + + // image may contain out of range samples, clip them to avoid wrap-arounds +#pragma omp parallel for + for(int i=0;iheight;i++) { + for(int j=0;jwidth;j++) { + im->r(i,j) = CLIP(im->r(i,j)); + im->g(i,j) = CLIP(im->g(i,j)); + im->b(i,j) = CLIP(im->b(i,j)); + } + } + + Image16* im16 = im->to16(); + delete im; + + int imw, imh; + double tmpScale = ipf.resizeScale(¶ms, fW, fH, imw, imh); + if (tmpScale != 1.0) { + Image16* tempImage = new Image16 (imw, imh); + ipf.resize (im16, tempImage, tmpScale); + delete im16; + im16 = tempImage; + } + im16->saveTIFF (fname,16,true); + delete im16; + + if (plistener) + plistener->setProgressState (false); + //im->saveJPEG (fname, 85); +} + +void ImProcCoordinator::stopProcessing () { + + updaterThreadStart.lock (); + if (updaterRunning && thread) { + changeSinceLast = 0; + thread->join (); + } + updaterThreadStart.unlock (); +} + +void ImProcCoordinator::startProcessing () { + + #undef THREAD_PRIORITY_NORMAL + + if (!destroying) { + if (!updaterRunning) { + updaterThreadStart.lock (); + thread = NULL; + updaterRunning = true; + updaterThreadStart.unlock (); + + //batchThread->yield(); //the running batch should wait other threads to avoid conflict + + thread = Glib::Thread::create(sigc::mem_fun(*this, &ImProcCoordinator::process), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + + } + } +} + +void ImProcCoordinator::startProcessing(int changeCode) { + paramsUpdateMutex.lock(); + changeSinceLast |= changeCode; + paramsUpdateMutex.unlock(); + + startProcessing (); +} + +void ImProcCoordinator::process () { + + if (plistener) + plistener->setProgressState (true); + + paramsUpdateMutex.lock (); + while (changeSinceLast) { + params = nextParams; + int change = changeSinceLast; + changeSinceLast = 0; + paramsUpdateMutex.unlock (); + + // M_VOID means no update, and is a bit higher that the rest + if (change & (M_VOID-1)) updatePreviewImage (change); + paramsUpdateMutex.lock (); + } + paramsUpdateMutex.unlock (); + updaterRunning = false; + + if (plistener) + plistener->setProgressState (false); +} + +ProcParams* ImProcCoordinator::beginUpdateParams () { + paramsUpdateMutex.lock (); + + return &nextParams; +} + +void ImProcCoordinator::endUpdateParams (ProcEvent change) { + endUpdateParams( refreshmap[(int)change] ); +} + +void ImProcCoordinator::endUpdateParams (int changeFlags) { + changeSinceLast |= changeFlags; + + paramsUpdateMutex.unlock (); + startProcessing (); +} + + +} diff --git a/rtengine/improccoordinator.h b/rtengine/improccoordinator.h new file mode 100644 index 000000000..6040b9977 --- /dev/null +++ b/rtengine/improccoordinator.h @@ -0,0 +1,244 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _IMPROCCOORDINATOR_H_ +#define _IMPROCCOORDINATOR_H_ + +#include "rtengine.h" +#include "improcfun.h" +#include "image8.h" +#include "image16.h" +#include "imagesource.h" +#include "procevents.h" +#include "dcrop.h" +#include "LUT.h" +#include "../rtgui/threadutils.h" + +namespace rtengine { + +using namespace procparams; + +class Crop; + +/** @brief Manages the image processing, espc. of the preview windows + * + * There is one ImProcCoordinator per edit panel. + * + * The ImProcCoordinator handle an sized down image representation of the full image, that is used when paning + * and in the Navigator object. + * + * Each ImProcCoordinator handles an rtengine::Crop list, which process images too with their own pipeline, + * but using this class' LUT and other precomputed parameters. The main preview area is displaying a non framed Crop object, + * while detail windows are framed Crop objects. + */ +class ImProcCoordinator : public StagedImageProcessor { + + friend class Crop; + + protected: + Imagefloat *orig_prev; + Imagefloat *oprevi; + LabImage *oprevl; + LabImage *nprevl; + Image8 *previmg; + Image8 *workimg; + CieImage *ncie; + + ImageSource* imgsrc; + + SHMap* shmap; + + ColorTemp currWB; + ColorTemp autoWB; + + double lastAwbEqual; + + ImProcFunctions ipf; + + int scale; + bool highDetailPreprocessComputed; + bool highDetailRawComputed; + bool allocated; + + void freeAll (); + + // Precomputed values used by DetailedCrop ---------------------------------------------- + + float bwAutoR, bwAutoG, bwAutoB; + float CAMMean; + LUTf hltonecurve; + LUTf shtonecurve; + LUTf tonecurve; + float chaut, redaut, blueaut, maxredaut, maxblueaut, minredaut, minblueaut, nresi, highresi, chromina, sigma, lumema; + + LUTf lumacurve; + LUTf chroma_acurve; + LUTf chroma_bcurve; + LUTf satcurve; + LUTf lhskcurve; + LUTf clcurve; + LUTf wavclCurve; + LUTf clToningcurve; + LUTf cl2Toningcurve; + LUTf Noisecurve; + LUTf NoiseCCcurve; + + LUTu vhist16,vhist16bw; + LUTu lhist16,lhist16Cropped; + LUTu lhist16CAM,lhist16CroppedCAM; + LUTu lhist16CCAM; + LUTu histCropped; + LUTu lhist16Clad,lhist16CLlad,lhist16LClad,lhist16LLClad; + LUTu histRed, histRedRaw; + LUTu histGreen, histGreenRaw; + LUTu histBlue, histBlueRaw; + LUTu histLuma, histToneCurve, histToneCurveBW, histLCurve, histCCurve, histCLurve; + LUTu histLLCurve, histLCAM, histCCAM, histClad, bcabhist, histChroma; + + LUTf CAMBrightCurveJ, CAMBrightCurveQ; + + LUTf rCurve; + LUTf gCurve; + LUTf bCurve; + ToneCurve customToneCurve1; + ToneCurve customToneCurve2; + ColorGradientCurve ctColorCurve; + OpacityCurve ctOpacityCurve; + NoiseCurve noiseLCurve; + NoiseCurve noiseCCurve; + WavCurve wavCLVCurve; + WavOpacityCurveRG waOpacityCurveRG; + WavOpacityCurveBY waOpacityCurveBY; + WavOpacityCurveW waOpacityCurveW; + WavOpacityCurveWL waOpacityCurveWL; + + ColorAppearance customColCurve1; + ColorAppearance customColCurve2; + ColorAppearance customColCurve3; + ToneCurve beforeToneCurveBW; + ToneCurve afterToneCurveBW; + + LUTu rcurvehist, rcurvehistCropped, rbeforehist; + LUTu gcurvehist, gcurvehistCropped, gbeforehist; + LUTu bcurvehist, bcurvehistCropped, bbeforehist; + + // ------------------------------------------------------------------------------------ + + int fw, fh, tr, fullw, fullh; + int pW, pH; + + ProgressListener* plistener; + PreviewImageListener* imageListener; + AutoExpListener* aeListener; + AutoCamListener* acListener; + AutoBWListener* abwListener; + AutoColorTonListener* actListener; + AutoChromaListener* adnListener; + WaveletListener* awavListener; + + HistogramListener* hListener; + std::vector sizeListeners; + + std::vector crops; + + bool resultValid; + + MyMutex minit; // to gain mutually exclusive access to ... to what exactly? + + void progress (Glib::ustring str, int pr); + void reallocAll (); + void updateLRGBHistograms (); + void setScale (int prevscale); + void updatePreviewImage (int todo, Crop* cropCall= NULL); + + MyMutex mProcessing; + ProcParams params; + + // members of the updater: + Glib::Thread* thread; + MyMutex updaterThreadStart; + MyMutex paramsUpdateMutex; + int changeSinceLast; + bool updaterRunning; + ProcParams nextParams; + bool destroying; + bool utili; + bool autili; + bool butili; + bool ccutili; + bool cclutili; + bool clcutili; + bool opautili; + bool wavcontlutili; + void startProcessing (); + void process (); + + public: + + ImProcCoordinator (); + ~ImProcCoordinator (); + void assign (ImageSource* imgsrc); + + void getParams (procparams::ProcParams* dst) { *dst = params; } + + void startProcessing(int changeCode); + ProcParams* beginUpdateParams (); + void endUpdateParams (ProcEvent change); // must be called after beginUpdateParams, triggers update + void endUpdateParams (int changeFlags); + void stopProcessing (); + + + void setPreviewScale (int scale) { setScale (scale); } + int getPreviewScale () { return scale; } + + //void fullUpdatePreviewImage (); + + int getFullWidth () { return fullw; } + int getFullHeight () { return fullh; } + + int getPreviewWidth () { return pW; } + int getPreviewHeight () { return pH; } + + DetailedCrop* createCrop (::EditDataProvider *editDataProvider, bool isDetailWindow); + + bool getAutoWB (double& temp, double& green, double equal); + void getCamWB (double& temp, double& green); + void getSpotWB (int x, int y, int rectSize, double& temp, double& green); + void getAutoCrop (double ratio, int &x, int &y, int &w, int &h); + + bool updateTryLock () {return updaterThreadStart.trylock();} + void updateUnLock () {updaterThreadStart.unlock();} + + void setProgressListener (ProgressListener* pl) { plistener = pl; } + void setPreviewImageListener (PreviewImageListener* il) {imageListener = il; } + void setSizeListener (SizeListener* il) {sizeListeners.push_back (il); } + void delSizeListener (SizeListener* il) {std::vector::iterator it = std::find (sizeListeners.begin(), sizeListeners.end(), il); if (it!=sizeListeners.end()) sizeListeners.erase (it); } + void setAutoExpListener (AutoExpListener* ael) {aeListener = ael; } + void setHistogramListener(HistogramListener *h) {hListener = h; } + void setAutoCamListener (AutoCamListener* acl) {acListener = acl; } + void setAutoBWListener (AutoBWListener* abw) {abwListener = abw; } + void setAutoColorTonListener (AutoColorTonListener* bwct) {actListener = bwct; } + void setAutoChromaListener (AutoChromaListener* adn) {adnListener = adn; } + void setWaveletListener (WaveletListener* awa) {awavListener = awa; } + + void saveInputICCReference (const Glib::ustring& fname, bool apply_wb); + + InitialImage* getInitialImage () { return imgsrc; } +}; +} +#endif diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc new file mode 100644 index 000000000..c1ed06bea --- /dev/null +++ b/rtengine/improcfun.cc @@ -0,0 +1,5867 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 + +#include "rtengine.h" +#include "improcfun.h" +#include "curves.h" +#include "colorclip.h" +#include "gauss.h" +#include "bilateral2.h" +#include "mytime.h" +#include "iccstore.h" +#include "impulse_denoise.h" +#include "imagesource.h" +#include "rtthumbnail.h" +#include "utils.h" +#include "iccmatrices.h" +#include "color.h" +#include "calc_distort.h" +#include "rt_math.h" +#include "EdgePreservingDecomposition.h" +#include "improccoordinator.h" +#include "clutstore.h" +#include "ciecam02.h" + +#ifdef _OPENMP +#include +#endif +#undef CLIPD +#define CLIPD(a) ((a)>0.0f?((a)<1.0f?(a):1.0f):0.0f) + +namespace rtengine { + + using namespace procparams; + +#undef ABS +#undef CLIPS +#undef CLIPC + +#define ABS(a) ((a)<0?-(a):(a)) +#define CLIPS(a) ((a)>-32768?((a)<32767?(a):32767):-32768) +#define CLIPC(a) ((a)>-32000?((a)<32000?(a):32000):-32000) +#define CLIP2(a) ((a)0.0?((a)<65535.5?(a):65535.5):0.0) + + +extern const Settings* settings; +LUTf ImProcFunctions::cachef; +LUTf ImProcFunctions::gamma2curve; +void ImProcFunctions::initCache () { + + const int maxindex = 65536; + cachef(maxindex,0/*LUT_CLIP_BELOW*/); + + gamma2curve(maxindex,0); + + for (int i=0; iColor::eps_max) { + cachef[i] = 327.68*( exp(1.0/3.0 * log((double)i / MAXVALD) )); + } + else { + cachef[i] = 327.68*((Color::kappa*i/MAXVALD+16.0)/116.0); + } + } + + for (int i=0; iworkingSpaceMatrix (wprofile); + + lumimul[0] = wprof[1][0]; + lumimul[1] = wprof[1][1]; + lumimul[2] = wprof[1][2]; + + int W = original->width; + for (int i=row_from; ir(i,j); + int g = original->g(i,j); + int b = original->b(i,j); + + int y = CLIP((int)(lumimul[0] * r + lumimul[1] * g + lumimul[2] * b)) ; + + if (histogram) { + histogram[y]++; + } + } + } +} +/* +void ImProcFunctions::CAT02 (Imagefloat* baseImg, const ProcParams* params) +{ + const double toxyz[3][3] = {{0.7976749, 0.1351917, 0.0313534}, + {0.2880402, 0.7118741, 0.0000857}, + {0.0000000, 0.0000000, 0.8252100}}; + + const double xyzto[3][3] = {{1.3459433, -0.2556075, -0.0511118}, + {-0.5445989, 1.5081673, 0.0205351}, + {0.0000000, 0.0000000, 1.2118128}}; + int fw = baseImg->width; + int fh = baseImg->height; + + double CAM02BB00,CAM02BB01,CAM02BB02,CAM02BB10,CAM02BB11,CAM02BB12,CAM02BB20,CAM02BB21,CAM02BB22; + double Xxx,Yyy,Zzz; + // Xxx=1.09844; + // Yyy=1.0; + // Zzz=0.355961; + //params.wb.temperature, params.wb.green, params.wb.method + double Xxyz, Zxyz; +// ColorTemp::temp2mulxyz (params->wb.temperature, params->wb.green, params->wb.method, Xxyz, Zxyz); + ColorTemp::temp2mulxyz (5000.0, 1.0, "Camera", Xxyz, Zxyz); + + ColorTemp::cieCAT02(Xxx, Yyy, Zzz, CAM02BB00,CAM02BB01,CAM02BB02,CAM02BB10,CAM02BB11,CAM02BB12,CAM02BB20,CAM02BB21,CAM02BB22); + printf("00=%f 01=%f 11=%f 20=%f 22=%f\n", CAM02BB00,CAM02BB01,CAM02BB11,CAM02BB20,CAM02BB22); + + + for (int i=0; ir(i,j); + float g = baseImg->g(i,j); + float b = baseImg->b(i,j); + + float x = toxyz[0][0] * r + toxyz[0][1] * g + toxyz[0][2] * b; + float y = toxyz[1][0] * r + toxyz[1][1] * g + toxyz[1][2] * b; + float z = toxyz[2][0] * r + toxyz[2][1] * g + toxyz[2][2] * b; + float Xcam=CAM02BB00* x +CAM02BB01* y + CAM02BB02* z ; + float Ycam=CAM02BB10* x +CAM02BB11* y + CAM02BB12* z ; + float Zcam=CAM02BB20* x +CAM02BB21* y + CAM02BB22* z ; + baseImg->r(i,j) = xyzto[0][0] * Xcam + xyzto[0][1] * Ycam + xyzto[0][2] * Zcam; + baseImg->g(i,j) = xyzto[1][0] * Xcam + xyzto[1][1] * Ycam + xyzto[1][2] * Zcam; + baseImg->b(i,j) = xyzto[2][0] * Xcam + xyzto[2][1] * Ycam + xyzto[2][2] * Zcam; + } + } +} +*/ +void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* params, LUTu & histogram) { + + // set up monitor transform + Glib::ustring wprofile = params->icm.working; + if (monitorTransform) + cmsDeleteTransform (monitorTransform); + monitorTransform = NULL; + +#if !defined(__APPLE__) // No support for monitor profiles on OS X, all data is sRGB + Glib::ustring monitorProfile=settings->monitorProfile; +#if defined(WIN32) + if (settings->autoMonitorProfile) monitorProfile=iccStore->defaultMonitorProfile; +#endif + + cmsHPROFILE monitor = iccStore->getProfile ("file:"+monitorProfile); + if (monitor) { + lcmsMutex->lock (); + cmsHPROFILE iprof = cmsCreateLab4Profile(NULL); + monitorTransform = cmsCreateTransform (iprof, TYPE_Lab_DBL, monitor, TYPE_RGB_8, settings->colorimetricIntent, + cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is for thread safety, NOOPTIMIZE for precision + cmsCloseProfile(iprof); + + lcmsMutex->unlock (); + } +#endif + // calculate histogram of the y channel needed for contrast curve calculation in exposure adjustments + + int T = 1; +#ifdef _OPENMP + if(multiThread) + T = omp_get_max_threads(); +#endif + + unsigned int** hist = new unsigned int* [T]; + for (int i=0; iheight; + int tid = omp_get_thread_num(); + int nthreads = omp_get_num_threads(); + int blk = H/nthreads; + + if (tidheight); +#endif + + histogram.clear(); + for (int j=0; j +void ImProcFunctions::ciecam_02 (CieImage* ncie, double adap, int begh, int endh, 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, int scalecd, int rtt) +{ +if(params->colorappearance.enabled) { +//int lastskip; +//if(rtt==1) {lastskip=scalecd;} //not for Rtthumbnail + +#ifdef _DEBUG + MyTime t1e,t2e; + t1e.set(); +#endif + LUTf dLcurve; + LUTu hist16JCAM; + bool jp=false; + float val; + //preparate for histograms CIECAM + if(pW!=1){//only with improccoordinator + dLcurve(65536,0); + dLcurve.clear(); + hist16JCAM(65536,0); + hist16JCAM.clear(); + for (int i=0; i<32768; i++) { //# 32768*1.414 approximation maxi for chroma + val = (double)i / 32767.0; + dLcurve[i] = CLIPD(val); + } + } + LUTf dCcurve; + LUTu hist16_CCAM; + bool chropC=false; + float valc; + + if(pW!=1){//only with improccoordinator + dCcurve(65536,0); + hist16_CCAM(65536); + hist16_CCAM.clear(); + for (int i=0; i<48000; i++) { //# 32768*1.414 approximation maxi for chroma + valc = (double)i / 47999.0; + dCcurve[i] = CLIPD(valc); + } + } + //end preparate histogram + int width = lab->W, height = lab->H; + float minQ=10000.f; + float minM=10000.f; + float maxQ= -1000.f; + float maxM= -1000.f; + float w_h; + float a_w; + float c_; + float f_l; + double Yw; + Yw=1.0; + double Xw, Zw; + double f,c,nc,yb,la,xw,yw,zw,f2,c2,nc2,yb2,la2; + double fl,n,nbb,ncb,aw; + double xwd,ywd,zwd; + int alg=0; + bool algepd=false; + float sum=0.f; + + 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 + //viewing condition for surround + if(params->colorappearance.surround=="Average") { f = 1.00; c = 0.69; nc = 1.00;f2=1.0,c2=0.69,nc2=1.0;} + else if(params->colorappearance.surround=="Dim"){ f2 = 0.9; c2 = 0.59; nc2 = 0.9;f=1.0,c=0.69,nc=1.0;} + else if(params->colorappearance.surround=="Dark"){f2 = 0.8; c2 = 0.525;nc2 = 0.8;f=1.0,c=0.69,nc=1.0;} + else if(params->colorappearance.surround=="ExtremelyDark"){f2 = 0.8; c2 = 0.41;nc2 = 0.8;f=1.0,c=0.69,nc=1.0;} + + //scene condition for surround + if(params->colorappearance.surrsource==true) {f = 0.85; c = 0.55; nc = 0.85;}// if user => source image has surround very dark + //with which algorithme + if (params->colorappearance.algo=="JC") alg=0; + else if(params->colorappearance.algo=="JS") alg=1; + else if(params->colorappearance.algo=="QM") {alg=2;algepd=true;} + else if(params->colorappearance.algo=="ALL") {alg=3;algepd=true;} + + bool needJ = (alg==0 || alg==1 || alg==3); + bool needQ = (alg==2 || alg==3); + //settings white point of output device - or illuminant viewing + if(settings->viewingdevice==0) {xwd=96.42;ywd=100.0;zwd=82.52;}//5000K + else if(settings->viewingdevice==1) {xwd=95.68;ywd=100.0;zwd=92.15;}//5500 + else if(settings->viewingdevice==2) {xwd=95.24;ywd=100.0;zwd=100.81;}//6000 + else if(settings->viewingdevice==3) {xwd=95.04;ywd=100.0;zwd=108.88;}//6500 + else if(settings->viewingdevice==4) {xwd=109.85;ywd=100.0;zwd=35.58;}//tungsten + else if(settings->viewingdevice==5) {xwd=99.18;ywd=100.0;zwd=67.39;}//fluo F2 + else if(settings->viewingdevice==6) {xwd=95.04;ywd=100.0;zwd=108.75;}//fluo F7 + else if(settings->viewingdevice==7) {xwd=100.96;ywd=100.0;zwd=64.35;}//fluo F11 + + + //settings mean Luminance Y of output device or viewing + if(settings->viewingdevicegrey==0) {yb2=5.0;} + else if(settings->viewingdevicegrey==1) {yb2=10.0;} + else if(settings->viewingdevicegrey==2) {yb2=15.0;} + else if(settings->viewingdevicegrey==3) {yb2=18.0;} + else if(settings->viewingdevicegrey==4) {yb2=23.0;} + else if(settings->viewingdevicegrey==5) {yb2=30.0;} + else if(settings->viewingdevicegrey==6) {yb2=40.0;} + + //La and la2 = ambiant luminosity scene and viewing + la=double(params->colorappearance.adapscen); + if(pwb==2){ + if(params->colorappearance.autoadapscen) la=adap; + } + + la2=double(params->colorappearance.adaplum); + + // level of adaptation + double deg=(params->colorappearance.degree)/100.0; + double pilot=params->colorappearance.autodegree ? 2.0 : deg; + + //algoritm's params + float jli=params->colorappearance.jlight; + float chr=params->colorappearance.chroma; + float contra=params->colorappearance.contrast; + float qbri=params->colorappearance.qbright; + float schr=params->colorappearance.schroma; + float mchr=params->colorappearance.mchroma; + float qcontra=params->colorappearance.qcontrast; + float hue=params->colorappearance.colorh; + double rstprotection = 100.-params->colorappearance.rstprotection; + if(schr>0.0) schr=schr/2.0f;//divide sensibility for saturation + + // extracting datas from 'params' to avoid cache flush (to be confirmed) + ColorAppearanceParams::eTCModeId curveMode = params->colorappearance.curveMode; + ColorAppearanceParams::eTCModeId curveMode2 = params->colorappearance.curveMode2; + bool hasColCurve1 = bool(customColCurve1); + bool hasColCurve2 = bool(customColCurve2); + ColorAppearanceParams::eCTCModeId curveMode3 = params->colorappearance.curveMode3; + bool hasColCurve3 = bool(customColCurve3); + + + if(CAMBrightCurveJ.dirty || CAMBrightCurveQ.dirty){ + LUTu hist16J; + LUTu hist16Q; + if (needJ) { + hist16J (65536); + hist16J.clear(); + } + if (needQ) { + hist16Q (65536); + hist16Q.clear(); + } + float koef=1.0f;//rough correspondence between L and J + for (int i=0; iL[i][j]/327.68f; + if (currL>95.) koef=1.f; + else if(currL>85.) koef=0.97f; + else if(currL>80.) koef=0.93f; + else if(currL>70.) koef=0.87f; + else if(currL>60.) koef=0.85f; + else if(currL>50.) koef=0.8f; + else if(currL>40.) koef=0.75f; + else if(currL>30.) koef=0.7f; + else if(currL>20.) koef=0.7f; + else if(currL>10.) koef=0.9f; + else if(currL>0.) koef=1.0f; + + if (needJ) + hist16J[CLIP((int)((koef*lab->L[i][j])))]++;//evaluate histogram luminance L # J + if (needQ) + hist16Q[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 + sum+=koef*lab->L[i][j];//evaluate mean J to calcualte Yb + } + //mean=(sum/((endh-begh)*width))/327.68f;//for Yb for all image...if one day "pipette" we can adapt Yb for each zone + mean=(sum/((height)*width))/327.68f;//for Yb for all image...if one day "pipette" we can adapt Yb for each zone + + //evaluate lightness, contrast + if (needJ) { + if (!CAMBrightCurveJ) { + CAMBrightCurveJ(65536,0); + CAMBrightCurveJ.dirty = false; + } + Ciecam02::curveJ (jli, contra, 1, CAMBrightCurveJ, hist16J);//lightness and contrast J + } + if (needQ) { + if (!CAMBrightCurveQ) { + CAMBrightCurveQ(65536,0); + CAMBrightCurveQ.dirty = false; + } + Ciecam02::curveJ (qbri, qcontra, 1, CAMBrightCurveQ, hist16Q);//brightness and contrast Q + } + } +if(settings->viewinggreySc==0){//auto + if (mean<15.f) yb=3.0; + else if(mean<30.f) yb=5.0; + else if(mean<40.f) yb=10.0; + else if(mean<45.f) yb=15.0; + else if(mean<50.f) yb=18.0; + else if(mean<55.f) yb=23.0; + else if(mean<60.f) yb=30.0; + else if(mean<70.f) yb=40.0; + else if(mean<80.f) yb=60.0; + else if(mean<90.f) yb=80.0; + else yb=90.0; +} +if(settings->viewinggreySc==1) yb=18.0; + + int gamu=0; + bool highlight = params->toneCurve.hrenabled; //Get the value if "highlight reconstruction" is activated + + if(params->colorappearance.gamut==true) gamu=1;//enabled gamut control + xw=100.0*Xw; + yw=100.0*Yw; + zw=100.0*Zw; + double xw1,yw1,zw1,xw2,yw2,zw2; + // settings of WB: scene and viewing + if(params->colorappearance.wbmodel=="RawT") {xw1=96.46;yw1=100.0;zw1=82.445;xw2=xwd;yw2=ywd;zw2=zwd;} //use RT WB; CAT 02 is used for output device (see prefreneces) + else if(params->colorappearance.wbmodel=="RawTCAT02") {xw1=xw;yw1=yw;zw1=zw;xw2=xwd;yw2=ywd;zw2=zwd;} // Settings RT WB are used for CAT02 => mix , CAT02 is use for output device (screen: D50 D65, projector: lamp, LED) see preferences + double cz,wh, pfl; + Ciecam02::initcam1(gamu, yb, pilot, f, la,xw, yw, zw, n, d, nbb, ncb,cz, aw, wh, pfl, fl, c); + double nj,dj,nbbj,ncbj,czj,awj,flj; + Ciecam02::initcam2(gamu,yb2, f2, la2, xw2, yw2, zw2, nj, dj, nbbj, ncbj,czj, awj, flj); + + + + +#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, scalecd) +#endif +{ //matrix for current working space + TMatrix wiprof = iccStore->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]} + }; + +#ifndef _DEBUG +#pragma omp for schedule(dynamic, 10) +#endif + for (int i=0; iL[i][j]; + float a=lab->a[i][j]; + float b=lab->b[i][j]; + float x1,y1,z1; + double x,y,z; + double epsil=0.0001; + //convert Lab => XYZ + Color::Lab2XYZ(L, a, b, x1, y1, z1); + // double J, C, h, Q, M, s, aw, fl, wh; + double J, C, h, Q, M, s; + + double Jpro,Cpro, hpro, Qpro, Mpro, spro; + bool t1L=false; + bool t1B=false; + bool t2B=false; + int c1s=0; + int c1co=0; + //double n,nbb,ncb,pfl,cz,d; + x=(double)x1/655.35; + y=(double)y1/655.35; + z=(double)z1/655.35; + //process source==> normal + Ciecam02::xyz2jchqms_ciecam02( J, C, h, + 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 ); + Jpro=J; + Cpro=C; + hpro=h; + Qpro=Q; + Mpro=M; + spro=s; + w_h=wh+epsil; + a_w=aw; + c_=c; + f_l=fl; + // we cannot have all algoritms with all chroma curves + if(alg==1) { + // Lightness saturation + if(Jpro > 99.9f) + Jpro = 99.9f; + Jpro=(CAMBrightCurveJ[(float)(Jpro*327.68)])/327.68;//ligthness CIECAM02 + contrast + double sres; + double Sp=spro/100.0; + double parsat=1.5; + parsat=1.5;//parsat=1.5 =>saturation ; 1.8 => chroma ; 2.5 => colorfullness (personal evaluation) + if(schr==-100.0) schr=-99.8; + Ciecam02::curvecolor(schr, Sp , sres, parsat); + double coe=pow(fl,0.25); + float dred=100.f;// in C mode + float protect_red=80.0f; // in C mode + dred = 100.0 * sqrt((dred*coe)/Qpro); + protect_red=100.0 * sqrt((protect_red*coe)/Qpro); + int sk=0; + float ko=100.f; + Color::skinred(Jpro, hpro, sres, Sp, dred, protect_red,sk,rstprotection,ko, spro); + Qpro= ( 4.0 / c ) * sqrt( Jpro / 100.0 ) * ( aw + 4.0 ) ; + Cpro=(spro*spro*Qpro)/(10000.0); + } + else if(alg==3 || alg==0 || alg==2) { + double coef=32760./wh; + if(alg==3 || alg==2) { + if(Qpro*coef > 32767.0f) + Qpro=(CAMBrightCurveQ[(float)32767.0f])/coef;//brightness and contrast + else + Qpro=(CAMBrightCurveQ[(float)(Qpro*coef)])/coef;//brightness and contrast + } + double Mp, sres; + double coe=pow(fl,0.25); + Mp=Mpro/100.0; + double parsat=2.5; + if(mchr==-100.0) mchr=-99.8 ; + if(mchr==100.0) mchr=99.9; + if(alg==3 || alg==2) Ciecam02::curvecolor(mchr, Mp , sres, parsat); else Ciecam02::curvecolor(0.0, Mp , sres, parsat);//colorfullness + float dred=100.f;//in C mode + float protect_red=80.0f;// in C mode + dred *=coe;//in M mode + protect_red *=coe;//M mode + int sk=0; + float ko=100.f; + Color::skinred(Jpro, hpro, sres, Mp, dred, protect_red,sk,rstprotection,ko, Mpro); + Jpro=(100.0* Qpro*Qpro) /(wh*wh); + Cpro= Mpro/coe; + spro = 100.0 * sqrt( Mpro / Qpro ); + if(alg!=2) { + if(Jpro > 99.9f) + Jpro = 99.9f; + Jpro=(CAMBrightCurveJ[(float)(Jpro*327.68f)])/327.68f;//ligthness CIECAM02 + contrast + } + double Cp; + double Sp=spro/100.0; + parsat=1.5; + if(schr==-100.0) schr=-99.; + if(schr==100.0) schr=98.; + if(alg==3) Ciecam02::curvecolor(schr, Sp , sres, parsat); else Ciecam02::curvecolor(0.0, Sp , sres, parsat); //saturation + dred=100.f;// in C mode + protect_red=80.0f; // in C mode + dred = 100.0 * sqrt((dred*coe)/Q); + protect_red=100.0 * sqrt((protect_red*coe)/Q); + sk=0; + Color::skinred(Jpro, hpro, sres, Sp, dred, protect_red,sk,rstprotection,ko, spro); + //double Q1; + Qpro= ( 4.0 / c ) * sqrt( Jpro / 100.0 ) * ( aw + 4.0 ) ; + Cpro=(spro*spro*Qpro)/(10000.0); + Cp=Cpro/100.0; + parsat=1.8;//parsat=1.5 =>saturation ; 1.8 => chroma ; 2.5 => colorfullness (personal evaluation : for not) + if(chr==-100.0) chr=-99.8; + if(alg!=2) Ciecam02::curvecolor(chr, Cp , sres, parsat);else Ciecam02::curvecolor(0.0, Cp , sres, parsat); //chroma + dred=55.f; + protect_red=30.0f; + sk=1; + Color::skinred(Jpro, hpro, sres, Cp, dred, protect_red,sk,rstprotection, ko, Cpro); + if(Jpro < 1. && Cpro > 12.) Cpro=12.;//reduce artifacts by "pseudo gamut control CIECAM" + else if(Jpro < 2. && Cpro > 15.) Cpro=15.; + else if(Jpro < 4. && Cpro > 30.) Cpro=30.; + else if(Jpro < 7. && Cpro > 50.) Cpro=50.; + + hpro=hpro+hue;if( hpro < 0.0 ) hpro += 360.0;//hue + } + + if (hasColCurve1) {//curve 1 with Lightness and Brightness + if (curveMode==ColorAppearanceParams::TC_MODE_LIGHT){ + /* float Jj=(float) Jpro*327.68; + float Jold=Jj; + const Lightcurve& userColCurve = static_cast(customColCurve1); + userColCurve.Apply(Jj); + Jj=0.7f*(Jj-Jold)+Jold;//divide sensibility + */ + float Jj=(float) Jpro*327.68f; + float Jold=Jj; + float Jold100=(float) Jpro; + float redu=25.f; + float reduc=1.f; + const Lightcurve& userColCurveJ1 = static_cast(customColCurve1); + userColCurveJ1.Apply(Jj); + if(Jj>Jold) { + if(Jj<65535.f) { + if(Jold < 327.68f*redu) Jj=0.3f*(Jj-Jold)+Jold;//divide sensibility + else { + reduc=LIM((100.f-Jold100)/(100.f-redu),0.f,1.f); + Jj=0.3f*reduc*(Jj-Jold)+Jold;//reduct sensibility in highlights + } + } + } + else if(Jj>10.f) Jj=0.8f*(Jj-Jold)+Jold; + else if (Jj>=0.f) Jj=0.90f*(Jj-Jold)+Jold;// not zero ==>artifacts + + + Jpro=(double)(Jj/327.68f); + if(Jpro < 1.) Jpro=1.; + t1L=true; + } + 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 Qq=(float) Qpro*327.68f*(1.f/coef); + float Qold100=(float) Qpro/coef; + + float Qold=Qq; + float redu=20.f; + float reduc=1.f; + + const Brightcurve& userColCurveB1 = static_cast(customColCurve1); + userColCurveB1.Apply(Qq); + if(Qq>Qold) { + if(Qq<65535.f) { + if(Qold < 327.68f*redu) Qq=0.25f*(Qq-Qold)+Qold;//divide sensibility + else { + reduc=LIM((100.f-Qold100)/(100.f-redu),0.f,1.f); + Qq=0.25f*reduc*(Qq-Qold)+Qold;//reduct sensibility in highlights + } + } + } + else if(Qq>10.f) Qq=0.5f*(Qq-Qold)+Qold; + else if (Qq>=0.f) 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)); + t1B=true; + if(Jpro < 1.) Jpro=1.; + + } + } + + if (hasColCurve2) {//curve 2 with Lightness and Brightness + if (curveMode2==ColorAppearanceParams::TC_MODE_LIGHT){ + float Jj=(float) Jpro*327.68; + float Jold=Jj; + /* + const Lightcurve& userColCurve = static_cast(customColCurve2); + userColCurve.Apply(Jj); + Jj=0.7f*(Jj-Jold)+Jold;//divide sensibility + */ + float Jold100=(float) Jpro; + float redu=25.f; + float reduc=1.f; + const Lightcurve& userColCurveJ2 = static_cast(customColCurve2); + userColCurveJ2.Apply(Jj); + if(Jj>Jold) { + if(Jj<65535.f) { + if(Jold < 327.68f*redu) Jj=0.3f*(Jj-Jold)+Jold;//divide sensibility + else { + reduc=LIM((100.f-Jold100)/(100.f-redu),0.f,1.f); + Jj=0.3f*reduc*(Jj-Jold)+Jold;//reduct sensibility in highlights + } + } + } + else if(Jj>10.f) {if(!t1L)Jj=0.8f*(Jj-Jold)+Jold;else Jj=0.4f*(Jj-Jold)+Jold;} + else if (Jj>=0.f){if(!t1L)Jj=0.90f*(Jj-Jold)+Jold;else Jj=0.5f*(Jj-Jold)+Jold;}// not zero ==>artifacts + + Jpro=(double)(Jj/327.68f); + if(Jpro < 1.) Jpro=1.; + + } + else if (curveMode2==ColorAppearanceParams::TC_MODE_BRIGHT){ // + float coef=((aw+4.f)*(4.f/c))/100.f; + float Qq=(float) Qpro*327.68f*(1.f/coef); + float Qold100=(float) Qpro/coef; + + float Qold=Qq; + float redu=20.f; + float reduc=1.f; + + const Brightcurve& userColCurveB2 = static_cast(customColCurve2); + userColCurveB2.Apply(Qq); + if(Qq>Qold) { + if(Qq<65535.f) { + if(Qold < 327.68f*redu) Qq=0.25f*(Qq-Qold)+Qold;//divide sensibility + else { + reduc=LIM((100.f-Qold100)/(100.f-redu),0.f,1.f); + Qq=0.25f*reduc*(Qq-Qold)+Qold;//reduct sensibility in highlights + } + } + } + else if(Qq>10.f) Qq=0.5f*(Qq-Qold)+Qold; + else if (Qq>=0.f) 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)); + 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 + coef=2.f;//adapt Q to J approximation + Qq=(float) Qpro*coef; + Qold=Qq; + const Lightcurve& userColCurveJ1 = static_cast(customColCurve1); + userColCurveJ1.Apply(Qq); + Qq=0.1f*(Qq-Qold)+Qold;//approximative adaptation + Qpro=(double)(Qq/coef); + Jpro=100.*(Qpro*Qpro)/((4.0/c)*(4.0/c)*(aw+4.0)*(aw+4.0)); + } + if(Jpro < 1.) Jpro=1.; + } + } + + if (hasColCurve3) {//curve 3 with chroma saturation colorfullness + if (curveMode3==ColorAppearanceParams::TC_MODE_CHROMA){ + double parsat=0.8;//0.68; + double coef=327.68/parsat; + float Cc=(float) Cpro*coef; + float Ccold=Cc; + const Chromacurve& userColCurve = static_cast(customColCurve3); + userColCurve.Apply(Cc); + float dred=55.f; + float protect_red=30.0f; + float sk=1; + float ko=1.f/coef; + Color::skinred(Jpro, hpro, Cc, Ccold, dred, protect_red,sk,rstprotection,ko, Cpro); + if(Jpro < 1. && Cpro > 12.) Cpro=12.;//reduce artifacts by "pseudo gamut control CIECAM" + else if(Jpro < 2. && Cpro > 15.) Cpro=15.; + else if(Jpro < 4. && Cpro > 30.) Cpro=30.; + else if(Jpro < 7. && Cpro > 50.) Cpro=50.; + + // Cpro=Cc/coef; + } + else if (curveMode3==ColorAppearanceParams::TC_MODE_SATUR){ // + double parsat=0.8;//0.6 + double coef=327.68/parsat; + float Ss=(float) spro*coef; + float Sold=Ss; + const Saturcurve& userColCurve = static_cast(customColCurve3); + userColCurve.Apply(Ss); + Ss=0.6f*(Ss-Sold)+Sold;//divide sensibility saturation + double coe=pow(fl,0.25); + float dred=100.f;// in C mode + float protect_red=80.0f; // in C mode + dred = 100.0 * sqrt((dred*coe)/Qpro); + protect_red=100.0 * sqrt((protect_red*coe)/Qpro); + int sk=0; + float ko=1.f/coef; + Color::skinred(Jpro, hpro, Ss, Sold, dred, protect_red,sk,rstprotection,ko, spro); + Qpro= ( 4.0 / c ) * sqrt( Jpro / 100.0 ) * ( aw + 4.0 ) ; + Cpro=(spro*spro*Qpro)/(10000.0); + c1s=1; + + } + else if (curveMode3==ColorAppearanceParams::TC_MODE_COLORF){ // + double parsat=0.8;//0.68; + double coef=327.68/parsat; + float Mm=(float) Mpro*coef; + float Mold=Mm; + const Colorfcurve& userColCurve = static_cast(customColCurve3); + userColCurve.Apply(Mm); + double coe=pow(fl,0.25); + float dred=100.f;//in C mode + float protect_red=80.0f;// in C mode + dred *=coe;//in M mode + protect_red *=coe; + int sk=0; + float ko=1.f/coef; + Color::skinred(Jpro, hpro, Mm, Mold, dred, protect_red,sk,rstprotection,ko, Mpro); + Cpro= Mpro/coe; + if(Jpro < 1. && Mpro > 12.*coe) Mpro=12.*coe;//reduce artifacts by "pseudo gamut control CIECAM" + else if(Jpro < 2. && Mpro > 15.*coe) Mpro=15.*coe; + else if(Jpro < 4. && Mpro > 30.*coe) Mpro=30.*coe; + else if(Jpro < 7. && Mpro > 50.*coe) Mpro=50.*coe; + + + c1co=1; + } + } + //to retrieve the correct values of variables + if(t2B && t1B) Jpro=(100.0* Qpro*Qpro) /(wh*wh);// for brightness curve + if(c1s==1) { + Qpro= ( 4.0 / c ) * sqrt( Jpro / 100.0 ) * ( aw + 4.0 ) ;//for saturation curve + Cpro=(spro*spro*Qpro)/(10000.0); + } + if(c1co==1) { double coe=pow(fl,0.25);Cpro= Mpro/coe;} // for colorfullness curve + //retrieve values C,J...s + C=Cpro; + J=Jpro; + Q=Qpro; + M=Mpro; + h=hpro; + s=spro; + + if(params->colorappearance.tonecie || settings->autocielab){//use pointer for tonemapping with CIECAM and also sharpening , defringe, contrast detail + // if(params->colorappearance.tonecie || params->colorappearance.sharpcie){//use pointer for tonemapping with CIECAM and also sharpening , defringe, contrast detail + float Qred= ( 4.0 / c) * ( aw + 4.0 );//estimate Q max if J=100.0 + ncie->Q_p[i][j]=(float)Q+epsil;//epsil to avoid Q=0 + ncie->M_p[i][j]=(float)M+epsil; + ncie->J_p[i][j]=(float)J+epsil; + ncie->h_p[i][j]=(float)h; + ncie->C_p[i][j]=(float)C+epsil; + // ncie->s_p[i][j]=(float)s; + ncie->sh_p[i][j]=(float) 32768.*(( 4.0 / c )*sqrt( J / 100.0 ) * ( aw + 4.0 ))/Qred ; + // ncie->ch_p[i][j]=(float) 327.68*C; + if(ncie->Q_p[i][j]Q_p[i][j];//minima + if(ncie->Q_p[i][j]>maxQ) maxQ=ncie->Q_p[i][j];//maxima + } + if(!params->colorappearance.tonecie || !settings->autocielab || !params->epd.enabled ){ + +// if(!params->epd.enabled || !params->colorappearance.tonecie || !settings->autocielab){ + // if(!params->epd.enabled || !params->colorappearance.tonecie || !params->colorappearance.sharpcie){ + int posl, posc; + double brli=327.; + double chsacol=327.; + int libr=0; + int colch=0; + if(curveMode==ColorAppearanceParams::TC_MODE_BRIGHT) {brli=70.0; libr=1;} + else if(curveMode==ColorAppearanceParams::TC_MODE_LIGHT) {brli=327.;libr=0;} + if (curveMode3==ColorAppearanceParams::TC_MODE_CHROMA) {chsacol=327.;colch=0;} + else if(curveMode3==ColorAppearanceParams::TC_MODE_SATUR) {chsacol=450.0;colch=1;} + else if(curveMode3==ColorAppearanceParams::TC_MODE_COLORF) {chsacol=327.0;colch=2;} + if(ciedata) { + // Data for J Q M s and C histograms + //update histogram + jp=true; + if(pW!=1){//only with improccoordinator + if(libr==1) posl=CLIP((int)(Q*brli));//40.0 to 100.0 approximative factor for Q - 327 for J + else if(libr==0) posl=CLIP((int)(J*brli));//327 for J + hist16JCAM[posl]++; + } + chropC=true; + if(pW!=1){//only with improccoordinator + if(colch==0) posc=CLIP((int)(C*chsacol));//450.0 approximative factor for s 320 for M + else if(colch==1) posc=CLIP((int)(s*chsacol)); + else if(colch==2) posc=CLIP((int)(M*chsacol)); + hist16_CCAM[posc]++; + } + } + double xx,yy,zz; + //double nj, nbbj, ncbj, flj, czj, dj, awj; + //process normal==> viewing + 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); + x=(float)xx*655.35; + y=(float)yy*655.35; + z=(float)zz*655.35; + float Ll,aa,bb; + //convert xyz=>lab + Color::XYZ2Lab(x, y, z, Ll, aa, bb); + lab->L[i][j]=Ll; + lab->a[i][j]=aa; + lab->b[i][j]=bb; + // gamut control in Lab mode; I must study how to do with cIECAM only + if(gamu==1) { + float R,G,B; + float HH, Lprov1, Chprov1; + Lprov1=lab->L[i][j]/327.68f; + Chprov1=sqrt(SQR(lab->a[i][j]/327.68f) + SQR(lab->b[i][j]/327.68f)); + HH=atan2(lab->b[i][j],lab->a[i][j]); + +#ifdef _DEBUG + bool neg=false; + bool more_rgb=false; + //gamut control : Lab values are in gamut + Color::gamutLchonly(HH,Lprov1,Chprov1, R, G, B, wip, highlight, 0.15f, 0.96f, neg, more_rgb); +#else + //gamut control : Lab values are in gamut + Color::gamutLchonly(HH,Lprov1,Chprov1, R, G, B, wip, highlight, 0.15f, 0.96f); +#endif + + lab->L[i][j]=Lprov1*327.68f; + lab->a[i][j]=327.68f*Chprov1*cos(HH); + lab->b[i][j]=327.68f*Chprov1*sin(HH); + + } + } + } + } + // End of parallelization +if(!params->epd.enabled || !params->colorappearance.tonecie || !settings->autocielab){//normal +//if(!params->epd.enabled || !params->colorappearance.tonecie || !params->colorappearance.sharpcie){//normal + + if(ciedata) { + //update histogram J + if(pW!=1){//only with improccoordinator + for (int i=0; i<32768; i++) {// + if (jp) { + float hval = dLcurve[i]; + int hi = (int)(255.0*CLIPD(hval)); // + histLCAM[hi] += hist16JCAM[i] ; + } + } + } + if(pW!=1){//only with improccoordinator + for (int i=0; i<48000; i++) {// + if (chropC) { + float hvalc = dCcurve[i]; + int hic = (int)(255.0*CLIPD(hvalc)); // + histCCAM[hic] += hist16_CCAM[i] ; + } + } + } + } +} +#ifdef _DEBUG + if (settings->verbose) { + t2e.set(); + printf("CIECAM02 performed in %d usec:\n", t2e.etime(t1e)); + // printf("minc=%f maxc=%f minj=%f maxj=%f\n",minc,maxc,minj,maxj); + } +#endif + +if(settings->autocielab) { +//if(params->colorappearance.sharpcie) { + +//all this treatments reduce artifacts, but can lead to slightly different results +if(params->defringe.enabled) if(execsharp) ImProcFunctions::defringecam (ncie);// + +//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; + int choice=0; + + bool alread=false; + float artifact=(float) settings->artifact_cbdl; + if(artifact>6.f) artifact=6.f; + if(artifact <0.f) artifact=1.f; + int hotbad=0; + float chrom=50.f; + {ImProcFunctions::badpixcam (ncie, artifact, 5, 2 , b_l, t_l, t_r, b_r,params->dirpyrequalizer.skinprotect , chrom, hotbad); alread=true; }//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 +} + +if (params->sharpenMicro.enabled)if(execsharp) ImProcFunctions::MLmicrocontrastcam(ncie); + +if(params->sharpening.enabled) + if(execsharp) { + float **buffer = lab->L; // We can use the L-buffer from lab as buffer to save some memory + ImProcFunctions::sharpeningcam (ncie, buffer); // sharpening adapted to CIECAM + } + +//if(params->dirpyrequalizer.enabled) if(execsharp) { +if(params->dirpyrequalizer.enabled /*&& (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; + int choice=0;//not disabled in case of ! always 0 +// if (params->dirpyrequalizer.algo=="FI") choice=0; +// else if(params->dirpyrequalizer.algo=="LA") choice=1; + if(rtt==1) 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, scalecd);//contrast by detail adapted to CIECAM +} + float Qredi= ( 4.0 / c_) * ( a_w + 4.0 ); + float co_e=(pow(f_l,0.25f)); + +#ifndef _DEBUG +#pragma omp parallel default(shared) firstprivate(height,width, Qredi,a_w,c_) +#endif +{ +#ifndef _DEBUG + #pragma omp for schedule(dynamic, 10) +#endif + for (int i=0; ish_p[i][j]/(32768.f); + ncie->J_p[i][j]=100.0* interm*interm/((a_w+4.)*(a_w+4.)*(4./c_)*(4./c_)); + ncie->Q_p[i][j]=( 4.0 / c_) * ( a_w + 4.0 ) * sqrt(ncie->J_p[i][j]/100.f); + ncie->M_p[i][j]=ncie->C_p[i][j]*co_e; + } + } +} + +if((params->colorappearance.tonecie || (params->colorappearance.tonecie && params->epd.enabled)) || (params->sharpening.enabled && settings->autocielab) + || (params->dirpyrequalizer.enabled && settings->autocielab) ||(params->defringe.enabled && settings->autocielab) || (params->sharpenMicro.enabled && settings->autocielab) + || (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 ); + //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) +#endif +{ + TMatrix wiprofa = iccStore->workingSpaceInverseMatrix (params->icm.working); + double wipa[3][3] = { + {wiprofa[0][0],wiprofa[0][1],wiprofa[0][2]}, + {wiprofa[1][0],wiprofa[1][1],wiprofa[1][2]}, + {wiprofa[2][0],wiprofa[2][1],wiprofa[2][2]} + }; + + +#ifndef _DEBUG + #pragma omp for schedule(dynamic, 10) +#endif + for (int i=0; iepd.enabled) ncie->J_p[i][j]=(100.0* ncie->Q_p[i][j]*ncie->Q_p[i][j])/(w_h*w_h); + if(params->epd.enabled) ncie->J_p[i][j]=(100.0* ncie->Q_p[i][j]*ncie->Q_p[i][j])/SQR((4./c)*(aw+4.)); + + ncie->C_p[i][j] =(ncie->M_p[i][j])/co_e; + //show histogram in CIECAM mode (Q,J, M,s,C) + int posl, posc; + double brli=327.; + double chsacol=327.; + int libr=0; + int colch=0; + float sa_t; + if(curveMode==ColorAppearanceParams::TC_MODE_BRIGHT) {brli=70.0; libr=1;} + else if(curveMode==ColorAppearanceParams::TC_MODE_LIGHT) {brli=327.;libr=0;} + if (curveMode3==ColorAppearanceParams::TC_MODE_CHROMA) {chsacol=327.;colch=0;} + else if(curveMode3==ColorAppearanceParams::TC_MODE_SATUR) {chsacol=450.0;colch=1;} + else if(curveMode3==ColorAppearanceParams::TC_MODE_COLORF) {chsacol=327.0;colch=2;} + if(ciedata) { + // Data for J Q M s and C histograms + //update histogram + jp=true; + if(pW!=1){//only with improccoordinator + if(libr==1) posl=CLIP((int)(ncie->Q_p[i][j]*brli));//40.0 to 100.0 approximative factor for Q - 327 for J + else if(libr==0) posl=CLIP((int)(ncie->J_p[i][j]*brli));//327 for J + hist16JCAM[posl]++; + } + chropC=true; + if(pW!=1){//only with improccoordinator + if(colch==0) posc=CLIP((int)(ncie->C_p[i][j]*chsacol));//450.0 approximative factor for s 320 for M + else if(colch==1) {sa_t=100.f*sqrt(ncie->C_p[i][j]/ncie->Q_p[i][j]); posc=CLIP((int)(sa_t*chsacol));}//Q_p always > 0 + else if(colch==2) posc=CLIP((int)(ncie->M_p[i][j]*chsacol)); + hist16_CCAM[posc]++; + } + } + //end histograms + // double nd, nbbd, ncbd, fld, czd, dd, awd; + 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); + x=(float)xx*655.35; + y=(float)yy*655.35; + z=(float)zz*655.35; + float Ll,aa,bb; + //convert xyz=>lab + Color::XYZ2Lab(x, y, z, Ll, aa, bb); + lab->L[i][j]=Ll; + lab->a[i][j]=aa; + lab->b[i][j]=bb; + if(gamu==1) { + float R,G,B; + float HH, Lprov1, Chprov1; + Lprov1=lab->L[i][j]/327.68f; + Chprov1=sqrt(SQR(lab->a[i][j]/327.68f) + SQR(lab->b[i][j]/327.68f)); + HH=atan2(lab->b[i][j],lab->a[i][j]); + +#ifdef _DEBUG + bool neg=false; + bool more_rgb=false; + //gamut control : Lab values are in gamut + Color::gamutLchonly(HH,Lprov1,Chprov1, R, G, B, wipa, highlight, 0.15f, 0.96f, neg, more_rgb); +#else + //gamut control : Lab values are in gamut + Color::gamutLchonly(HH,Lprov1,Chprov1, R, G, B, wipa, highlight, 0.15f, 0.96f); +#endif + + lab->L[i][j]=Lprov1*327.68f; + lab->a[i][j]=327.68f*Chprov1*cos(HH); + lab->b[i][j]=327.68f*Chprov1*sin(HH); + } + } + + + } + //end parallelization + //show CIECAM histograms + if(ciedata) { + //update histogram J and Q + if(pW!=1){//only with improccoordinator + for (int i=0; i<32768; i++) {// + if (jp) { + float hval = dLcurve[i]; + int hi = (int)(255.0*CLIPD(hval)); // + histLCAM[hi] += hist16JCAM[i] ; + } + } + } + //update color histogram M,s,C + if(pW!=1){//only with improccoordinator + for (int i=0; i<48000; i++) {// + if (chropC) { + float hvalc = dCcurve[i]; + int hic = (int)(255.0*CLIPD(hvalc)); // + histCCAM[hic] += hist16_CCAM[i] ; + } + } + } + } + + } + +} +} +//end CIECAM + + +// 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, + 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, int scalecd, int rtt) +{ +if(params->colorappearance.enabled) { +//int lastskip; +//if(rtt==1) {lastskip=scalecd;} //not for Rtthumbnail + +#ifdef _DEBUG + MyTime t1e,t2e; + t1e.set(); +#endif + LUTf dLcurve; + LUTu hist16JCAM; + float val; + //preparate for histograms CIECAM + if(pW!=1){//only with improccoordinator + dLcurve(65536, 0); + dLcurve.clear(); + hist16JCAM(65536); + hist16JCAM.clear(); + for (int i=0; i<32768; i++) { //# 32768*1.414 approximation maxi for chroma + val = (double)i / 32767.0; + dLcurve[i] = CLIPD(val); + } + } + LUTf dCcurve(65536,0); + LUTu hist16_CCAM(65536); + bool chropC=false; + float valc; + + if(pW!=1){//only with improccoordinator + for (int i=0; i<48000; i++) { //# 32768*1.414 approximation maxi for chroma + valc = (double)i / 47999.0; + dCcurve[i] = CLIPD(valc); + } + hist16_CCAM.clear(); + } + //end preparate histogram + int width = lab->W, height = lab->H; + float minQ = 10000.f; + float maxQ = -1000.f; + float Yw; + Yw=1.0; + double Xw, Zw; + float f,nc,yb,la,c,xw,yw,zw,f2,c2,nc2,yb2,la2; + float fl,n,nbb,ncb,aw;//d + float xwd,ywd,zwd; + int alg=0; + bool algepd=false; + float sum=0.f; + + const bool ciedata = (params->colorappearance.datacie && pW!=1); + bool jp=ciedata; + + ColorTemp::temp2mulxyz (params->wb.temperature, params->wb.green, params->wb.method, Xw, Zw); //compute white Xw Yw Zw : white current WB + //viewing condition for surround + if(params->colorappearance.surround=="Average") { f = 1.00f; c = 0.69f; nc = 1.00f;f2=1.0f,c2=0.69f,nc2=1.0f;} + else if(params->colorappearance.surround=="Dim"){ f2 = 0.9f; c2 = 0.59f; nc2 = 0.9f;f=1.0f,c=0.69f,nc=1.0f;} + else if(params->colorappearance.surround=="Dark"){f2 = 0.8f; c2 = 0.525f;nc2 = 0.8f;f=1.0f,c=0.69f,nc=1.0f;} + else if(params->colorappearance.surround=="ExtremelyDark"){f2 = 0.8f; c2 = 0.41f;nc2 = 0.8f;f=1.0f,c=0.69f,nc=1.0f;} + + //scene condition for surround + if(params->colorappearance.surrsource==true) {f = 0.85f; c = 0.55f; nc = 0.85f;}// if user => source image has surround very dark + //with which algorithm + if (params->colorappearance.algo=="JC") alg=0; + else if(params->colorappearance.algo=="JS") alg=1; + else if(params->colorappearance.algo=="QM") {alg=2;algepd=true;} + else if(params->colorappearance.algo=="ALL") {alg=3;algepd=true;} + + //settings white point of output device - or illuminant viewing + if(settings->viewingdevice==0) {xwd=96.42f;ywd=100.0f;zwd=82.52f;}//5000K + else if(settings->viewingdevice==1) {xwd=95.68f;ywd=100.0f;zwd=92.15f;}//5500 + else if(settings->viewingdevice==2) {xwd=95.24f;ywd=100.0f;zwd=100.81f;}//6000 + else if(settings->viewingdevice==3) {xwd=95.04f;ywd=100.0f;zwd=108.88f;}//6500 + else if(settings->viewingdevice==4) {xwd=109.85f;ywd=100.0f;zwd=35.58f;}//tungsten + else if(settings->viewingdevice==5) {xwd=99.18f;ywd=100.0f;zwd=67.39f;}//fluo F2 + else if(settings->viewingdevice==6) {xwd=95.04f;ywd=100.0f;zwd=108.75f;}//fluo F7 + else if(settings->viewingdevice==7) {xwd=100.96f;ywd=100.0f;zwd=64.35f;}//fluo F11 + + + //settings mean Luminance Y of output device or viewing + if(settings->viewingdevicegrey==0) {yb2=5.0f;} + else if(settings->viewingdevicegrey==1) {yb2=10.0f;} + else if(settings->viewingdevicegrey==2) {yb2=15.0f;} + else if(settings->viewingdevicegrey==3) {yb2=18.0f;} + else if(settings->viewingdevicegrey==4) {yb2=23.0f;} + else if(settings->viewingdevicegrey==5) {yb2=30.0f;} + else if(settings->viewingdevicegrey==6) {yb2=40.0f;} + + //La and la2 = ambiant luminosity scene and viewing + la=float(params->colorappearance.adapscen); + if(pwb==2){ + if(params->colorappearance.autoadapscen) la=adap; + } + + la2=float(params->colorappearance.adaplum); + + // level of adaptation + const float deg=(params->colorappearance.degree)/100.0f; + const float pilot=params->colorappearance.autodegree ? 2.0f : deg; + + //algoritm's params + float chr=0.f; + if(alg==0 || alg==3) { + chr=params->colorappearance.chroma; + if(chr==-100.0f) + chr=-99.8f; + } + + float schr=0.f; + if(alg==3 || alg==1) { + schr=params->colorappearance.schroma; + if(schr>0.0) schr=schr/2.0f;//divide sensibility for saturation + if(alg==3) { + if(schr==-100.0f) + schr=-99.f; + if(schr==100.0f) + schr=98.f; + } else { + if(schr==-100.0f) + schr=-99.8f; + } + } + float mchr=0.f; + if(alg==3 || alg == 2) { + mchr = params->colorappearance.mchroma; + if(mchr==-100.0f) + mchr=-99.8f ; + if(mchr==100.0f) + mchr=99.9f; + } + + const float hue=params->colorappearance.colorh; + const float rstprotection = 100.-params->colorappearance.rstprotection; + + // extracting datas from 'params' to avoid cache flush (to be confirmed) + const ColorAppearanceParams::eTCModeId curveMode = params->colorappearance.curveMode; + const bool hasColCurve1 = bool(customColCurve1); + bool t1L=false; + bool t1B=false; + if (hasColCurve1 && curveMode==ColorAppearanceParams::TC_MODE_LIGHT) + t1L = true; + if(hasColCurve1 && curveMode==ColorAppearanceParams::TC_MODE_BRIGHT) + t1B = true; + + const ColorAppearanceParams::eTCModeId curveMode2 = params->colorappearance.curveMode2; + const bool hasColCurve2 = bool(customColCurve2); + bool t2B=false; + if(hasColCurve2 && curveMode2==ColorAppearanceParams::TC_MODE_BRIGHT) + t2B = true; + + const ColorAppearanceParams::eCTCModeId curveMode3 = params->colorappearance.curveMode3; + const bool hasColCurve3 = bool(customColCurve3); + bool c1s = false; + bool c1co = false; + if( hasColCurve3 && curveMode3==ColorAppearanceParams::TC_MODE_SATUR) + c1s = true; + if(hasColCurve3 && curveMode3==ColorAppearanceParams::TC_MODE_COLORF) + c1co = true; + + if(CAMBrightCurveJ.dirty || CAMBrightCurveQ.dirty){ + bool needJ = (alg==0 || alg==1 || alg==3); + bool needQ = (alg==2 || alg==3); + LUTu hist16J; + LUTu hist16Q; + if (needJ) { + hist16J (65536); + hist16J.clear(); + } + if (needQ) { + hist16Q (65536); + hist16Q.clear(); + } +#pragma omp parallel +{ + LUTu hist16Jthr; + LUTu hist16Qthr; + if (needJ) { + hist16Jthr (65536); + hist16Jthr.clear(); + } + if (needQ) { + hist16Qthr(65536); + hist16Qthr.clear(); + } + +#pragma omp for reduction(+:sum) + for (int i=0; iL[i][j]/327.68f; + float koef=1.0f;//rough correspondence between L and J +// if (currL>95.f) koef=1.f; + if(currL>85.f) koef=0.97f; + else if(currL>80.f) koef=0.93f; + else if(currL>70.f) koef=0.87f; + else if(currL>60.f) koef=0.85f; + else if(currL>50.f) koef=0.8f; + else if(currL>40.f) koef=0.75f; +// else if(currL>30.f) koef=0.7f; + else if(currL>20.f) koef=0.7f; + else if(currL>10.f) koef=0.9f; +// else if(currL>0.f) koef=1.0f; + + if (needJ) + hist16Jthr[CLIP((int)((koef*lab->L[i][j])))]++;//evaluate histogram luminance L # J + if (needQ) + hist16Qthr[CLIP((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 + } +#pragma omp critical +{ + if(needJ) + for(int i=0;i<65536;i++) + hist16J[i] += hist16Jthr[i]; + if(needQ) + for(int i=0;i<65536;i++) + hist16Q[i] += hist16Qthr[i]; + +} +} + + + //mean=(sum/((endh-begh)*width))/327.68f;//for Yb for all image...if one day "pipette" we can adapt Yb for each zone + mean=(sum/((height)*width))/327.68f;//for Yb for all image...if one day "pipette" we can adapt Yb for each zone + + //evaluate lightness, contrast + if (needJ) { + if (!CAMBrightCurveJ) { + CAMBrightCurveJ(32768,LUT_CLIP_ABOVE); + CAMBrightCurveJ.dirty = false; + } + float jli=params->colorappearance.jlight; + float contra=params->colorappearance.contrast; + Ciecam02::curveJfloat (jli, contra, 1, CAMBrightCurveJ, hist16J);//lightness and contrast J + } + if (needQ) { + if (!CAMBrightCurveQ) { + CAMBrightCurveQ(32768,LUT_CLIP_ABOVE); + CAMBrightCurveQ.clear(); + CAMBrightCurveQ.dirty = false; + } + float qbri=params->colorappearance.qbright; + float qcontra=params->colorappearance.qcontrast; + Ciecam02::curveJfloat (qbri, qcontra, 1, CAMBrightCurveQ, hist16Q);//brightness and contrast Q + } + } + +if(settings->viewinggreySc==0){//auto + if (mean<15.f) yb=3.0f; + else if(mean<30.f) yb=5.0f; + else if(mean<40.f) yb=10.0f; + else if(mean<45.f) yb=15.0f; + else if(mean<50.f) yb=18.0f; + else if(mean<55.f) yb=23.0f; + else if(mean<60.f) yb=30.0f; + else if(mean<70.f) yb=40.0f; + else if(mean<80.f) yb=60.0f; + else if(mean<90.f) yb=80.0f; + else yb=90.0f; +} +if(settings->viewinggreySc==1) yb=18.0f;//fixed + + + const bool highlight = params->toneCurve.hrenabled; //Get the value if "highlight reconstruction" is activated + + const int gamu = (params->colorappearance.gamut==true) ? 1 : 0; + xw=100.0f*Xw; + yw=100.0f*Yw; + zw=100.0f*Zw; + float xw1,yw1,zw1,xw2,yw2,zw2; + // settings of WB: scene and viewing + if(params->colorappearance.wbmodel=="RawT") {xw1=96.46f;yw1=100.0f;zw1=82.445f;xw2=xwd;yw2=ywd;zw2=zwd;} //use RT WB; CAT 02 is used for output device (see prefreneces) + else if(params->colorappearance.wbmodel=="RawTCAT02") {xw1=xw;yw1=yw;zw1=zw;xw2=xwd;yw2=ywd;zw2=zwd;} // Settings RT WB are used for CAT02 => mix , CAT02 is use for output device (screen: D50 D65, projector: lamp, LED) see preferences + float cz,wh, pfl; + Ciecam02::initcam1float(gamu, yb, pilot, f, la,xw, yw, zw, n, d, nbb, ncb,cz, aw, wh, pfl, fl, c); + const float pow1 = pow_F( 1.64f - pow_F( 0.29f, n ), 0.73f ); + float nj,dj,nbbj,ncbj,czj,awj,flj; + Ciecam02::initcam2float(gamu,yb2, f2, la2, xw2, yw2, zw2, nj, dj, nbbj, ncbj,czj, awj, flj); + const float reccmcz = 1.f / (c2*czj); + 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 a_w=aw; + const float c_=c; + const float f_l=fl; + const float coe=pow_F(fl,0.25f); + const float QproFactor = ( 0.4f / c ) * ( aw + 4.0f ) ; + const bool epdEnabled = params->epd.enabled; + 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)); + + //matrix for current working space + TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params->icm.working); + const float 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]} + }; + +#ifdef __SSE2__ + int bufferLength = ((width+3)/4) * 4; // bufferLength has to be a multiple of 4 +#endif +#ifndef _DEBUG +#pragma omp parallel +#endif +{ + float minQThr = 10000.f; + float maxQThr = -1000.f; +#ifdef __SSE2__ + // one line buffer per channel and thread + float Jbuffer[bufferLength] ALIGNED16; + float Cbuffer[bufferLength] ALIGNED16; + float hbuffer[bufferLength] ALIGNED16; + float Qbuffer[bufferLength] ALIGNED16; + float Mbuffer[bufferLength] ALIGNED16; + float sbuffer[bufferLength] ALIGNED16; +#endif +#ifndef _DEBUG +#pragma omp for schedule(dynamic, 16) +#endif + for (int i=0; iL[i][k]),LVFU(lab->a[i][k]),LVFU(lab->b[i][k]),x,y,z); + x = x/c655d35; + y = y/c655d35; + z = z/c655d35; + Ciecam02::xyz2jchqms_ciecam02float( J, C, h, + Q, M, s, F2V(aw), F2V(fl), F2V(wh), + x, y, z, + F2V(xw1), F2V(yw1), F2V(zw1), + F2V(yb), F2V(la), + F2V(f), F2V(c), F2V(nc), F2V(pow1), F2V(nbb), F2V(ncb), F2V(pfl), F2V(cz), F2V(d)); + STVF(Jbuffer[k],J); + STVF(Cbuffer[k],C); + STVF(hbuffer[k],h); + STVF(Qbuffer[k],Q); + STVF(Mbuffer[k],M); + STVF(sbuffer[k],s); + } + for(;kL[i][k]; + float a=lab->a[i][k]; + float b=lab->b[i][k]; + float x,y,z; + //convert Lab => XYZ + Color::Lab2XYZ(L, a, b, x, y, z); + x = x/655.35f; + y = y/655.35f; + z = z/655.35f; + float J, C, h, Q, M, s; + Ciecam02::xyz2jchqms_ciecam02float( J, C, h, + Q, M, s, aw, fl, wh, + x, y, z, + xw1, yw1, zw1, + yb, la, + f, c, nc, pilot, gamu, pow1, nbb, ncb, pfl, cz, d); + Jbuffer[k] = J; + Cbuffer[k] = C; + hbuffer[k] = h; + Qbuffer[k] = Q; + Mbuffer[k] = M; + sbuffer[k] = s; + } +#endif // __SSE2__ + for (int j=0; jL[i][j]; + float a=lab->a[i][j]; + float b=lab->b[i][j]; + float x1,y1,z1; + //convert Lab => XYZ + Color::Lab2XYZ(L, a, b, x1, y1, z1); + x=(float)x1/655.35f; + y=(float)y1/655.35f; + z=(float)z1/655.35f; + //process source==> normal + Ciecam02::xyz2jchqms_ciecam02float( J, C, h, + Q, M, s, aw, fl, wh, + x, y, z, + xw1, yw1, zw1, + yb, la, + f, c, nc, pilot, gamu, pow1, nbb, ncb, pfl, cz, d); +#endif + float Jpro,Cpro, hpro, Qpro, Mpro, spro; + Jpro=J; + Cpro=C; + hpro=h; + Qpro=Q; + Mpro=M; + spro=s; + // we cannot have all algorithms with all chroma curves + if(alg==0) { + Jpro = CAMBrightCurveJ[Jpro*327.68f]/327.68f; //lightness CIECAM02 + contrast + Qpro = QproFactor * sqrtf(Jpro); + float Cp = (spro*spro*Qpro)/(1000000.f); + Cpro = Cp * 100.f; + float sres; + Ciecam02::curvecolorfloat(chr, Cp , sres, 1.8f); + Color::skinredfloat(Jpro, hpro, sres, Cp, 55.f, 30.f,1,rstprotection, 100.f, Cpro); + } + if(alg==1) { + // Lightness saturation + Jpro = CAMBrightCurveJ[Jpro*327.68f]/327.68f;//lightness CIECAM02 + contrast + float sres; + float Sp=spro/100.0f; + float parsat=1.5f; //parsat=1.5 =>saturation ; 1.8 => chroma ; 2.5 => colorfullness (personal evaluation) + Ciecam02::curvecolorfloat(schr, Sp , sres, parsat); + float dred=100.f;// in C mode + float protect_red=80.0f; // in C mode + dred = 100.0f * sqrtf((dred*coe)/Qpro); + protect_red=100.0f * sqrtf((protect_red*coe)/Qpro); + Color::skinredfloat(Jpro, hpro, sres, Sp, dred, protect_red,0,rstprotection,100.f, spro); + Qpro = QproFactor * sqrtf(Jpro); + Cpro=(spro*spro*Qpro)/(10000.0f); + } + else if(alg==2) { + float coef=32767.f/wh; + Qpro=(CAMBrightCurveQ[(float)(Qpro*coef)])/coef;//brightness and contrast + float Mp, sres; + Mp=Mpro/100.0f; + Ciecam02::curvecolorfloat(mchr, Mp , sres, 2.5f); + float dred=100.f;//in C mode + float protect_red=80.0f;// in C mode + dred *=coe;//in M mode + protect_red *=coe;//M mode + Color::skinredfloat(Jpro, hpro, sres, Mp, dred, protect_red,0,rstprotection,100.f, Mpro); + Jpro = SQR((10.f*Qpro)/wh); + Cpro= Mpro/coe; + Qpro = (Qpro == 0.f ? epsil : Qpro); // avoid division by zero + spro = 100.0f * sqrtf( Mpro / Qpro ); + } + else if(alg==3) { + float coef=32760.f/wh; + if(Qpro*coef >= 32767.0f) + Qpro=(CAMBrightCurveQ[32767])/coef;//brightness and contrast + else + Qpro=(CAMBrightCurveQ[(float)(Qpro*coef)])/coef;//brightness and contrast + float Mp, sres; + Mp=Mpro/100.0f; + Ciecam02::curvecolorfloat(mchr, Mp , sres, 2.5f); + float dred=100.f;//in C mode + float protect_red=80.0f;// in C mode + dred *=coe;//in M mode + protect_red *=coe;//M mode + Color::skinredfloat(Jpro, hpro, sres, Mp, dred, protect_red,0,rstprotection,100.f, Mpro); + Jpro = SQR((10.f*Qpro)/wh); + Cpro= Mpro/coe; + Qpro = (Qpro == 0.f ? epsil : Qpro); // avoid division by zero + spro = 100.0f * sqrtf( Mpro / Qpro ); + if(Jpro > 99.9f) + Jpro = 99.9f; + Jpro=(CAMBrightCurveJ[(float)(Jpro*327.68f)])/327.68f;//lightness CIECAM02 + contrast + float Sp=spro/100.0f; + Ciecam02::curvecolorfloat(schr, Sp , sres, 1.5f); + dred=100.f;// in C mode + protect_red=80.0f; // in C mode + dred = 100.0f * sqrtf((dred*coe)/Q); + protect_red=100.0f * sqrtf((protect_red*coe)/Q); + Color::skinredfloat(Jpro, hpro, sres, Sp, dred, protect_red,0,rstprotection,100.f, spro); + Qpro = QproFactor * sqrtf(Jpro); + float Cp=(spro*spro*Qpro)/(1000000.f); + Cpro = Cp*100.f; + Ciecam02::curvecolorfloat(chr, Cp , sres, 1.8f); + Color::skinredfloat(Jpro, hpro, sres, Cp, 55.f, 30.f,1,rstprotection, 100.f, Cpro); +// disabled this code, Issue 2690 +// if(Jpro < 1.f && Cpro > 12.f) Cpro=12.f;//reduce artifacts by "pseudo gamut control CIECAM" +// else if(Jpro < 2.f && Cpro > 15.f) Cpro=15.f; +// else if(Jpro < 4.f && Cpro > 30.f) Cpro=30.f; +// else if(Jpro < 7.f && Cpro > 50.f) Cpro=50.f; + hpro=hpro+hue; + if( hpro < 0.0f ) + hpro += 360.0f;//hue + } + + if (hasColCurve1) {//curve 1 with Lightness and Brightness + if (curveMode==ColorAppearanceParams::TC_MODE_LIGHT){ + float Jj=(float) Jpro*327.68f; + float Jold=Jj; + float Jold100=(float) Jpro; + float redu=25.f; + float reduc=1.f; + const Lightcurve& userColCurveJ1 = static_cast(customColCurve1); + userColCurveJ1.Apply(Jj); + if(Jj>Jold) { + if(Jj<65535.f) { + if(Jold < 327.68f*redu) Jj=0.3f*(Jj-Jold)+Jold;//divide sensibility + else { + reduc=LIM((100.f-Jold100)/(100.f-redu),0.f,1.f); + Jj=0.3f*reduc*(Jj-Jold)+Jold;//reduct sensibility in highlights + } + } + } + else if(Jj>10.f) Jj=0.8f*(Jj-Jold)+Jold; + else if (Jj>=0.f) Jj=0.90f*(Jj-Jold)+Jold;// not zero ==>artifacts + Jpro=(float)(Jj/327.68f); + if(Jpro<1.f) Jpro=1.f; + } + 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 Qq=(float) Qpro*327.68f*(1.f/coef); + float Qold100=(float) Qpro/coef; + + float Qold=Qq; + float redu=20.f; + float reduc=1.f; + + const Brightcurve& userColCurveB1 = static_cast(customColCurve1); + userColCurveB1.Apply(Qq); + if(Qq>Qold) { + if(Qq<65535.f) { + if(Qold < 327.68f*redu) Qq=0.25f*(Qq-Qold)+Qold;//divide sensibility + else { + reduc=LIM((100.f-Qold100)/(100.f-redu),0.f,1.f); + Qq=0.25f*reduc*(Qq-Qold)+Qold;//reduct sensibility in highlights + } + } + } + else if(Qq>10.f) Qq=0.5f*(Qq-Qold)+Qold; + else if (Qq>=0.f) 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(Jpro< 1.f) Jpro=1.f; + } + } + + if (hasColCurve2) {//curve 2 with Lightness and Brightness + if (curveMode2==ColorAppearanceParams::TC_MODE_LIGHT){ + float Jj=(float) Jpro*327.68f; + float Jold=Jj; + float Jold100=(float) Jpro; + float redu=25.f; + float reduc=1.f; + const Lightcurve& userColCurveJ2 = static_cast(customColCurve2); + userColCurveJ2.Apply(Jj); + if(Jj>Jold) { + if(Jj<65535.f) { + if(Jold < 327.68f*redu) Jj=0.3f*(Jj-Jold)+Jold;//divide sensibility + else { + reduc=LIM((100.f-Jold100)/(100.f-redu),0.f,1.f); + Jj=0.3f*reduc*(Jj-Jold)+Jold;//reduct sensibility in highlights + } + } + } + else if(Jj>10.f) {if(!t1L)Jj=0.8f*(Jj-Jold)+Jold;else Jj=0.4f*(Jj-Jold)+Jold;} + else if (Jj>=0.f){if(!t1L)Jj=0.90f*(Jj-Jold)+Jold;else Jj=0.5f*(Jj-Jold)+Jold;}// not zero ==>artifacts + Jpro=(float)(Jj/327.68f); + if(Jpro< 1.f) Jpro=1.f; + + } + else if (curveMode2==ColorAppearanceParams::TC_MODE_BRIGHT){ // + float coef=((aw+4.f)*(4.f/c))/100.f; + float Qq=(float) Qpro*327.68f*(1.f/coef); + float Qold100=(float) Qpro/coef; + + float Qold=Qq; + float redu=20.f; + float reduc=1.f; + + const Brightcurve& userColCurveB2 = static_cast(customColCurve2); + userColCurveB2.Apply(Qq); + if(Qq>Qold) { + if(Qq<65535.f) { + if(Qold < 327.68f*redu) Qq=0.25f*(Qq-Qold)+Qold;//divide sensibility + else { + reduc=LIM((100.f-Qold100)/(100.f-redu),0.f,1.f); + Qq=0.25f*reduc*(Qq-Qold)+Qold;//reduct sensibility in highlights + } + } + } + else if(Qq>10.f) Qq=0.5f*(Qq-Qold)+Qold; + else if (Qq>=0.f) 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(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 + Qq=(float) Qpro*coef; + Qold=Qq; + const Lightcurve& userColCurveJ1 = static_cast(customColCurve1); + userColCurveJ1.Apply(Qq); + Qq=0.05f*(Qq-Qold)+Qold;//approximative adaptation + Qpro=(float)(Qq/coef); + Jpro=100.f*(Qpro*Qpro)/((4.0f/c)*(4.0f/c)*(aw+4.0f)*(aw+4.0f)); + } + if(Jpro < 1.f) Jpro=1.f; + } + } + + if (hasColCurve3) {//curve 3 with chroma saturation colorfullness + if (curveMode3==ColorAppearanceParams::TC_MODE_CHROMA){ + float parsat=0.8f;//0.68; + float coef=327.68f/parsat; + float Cc=(float) Cpro*coef; + float Ccold=Cc; + const Chromacurve& userColCurve = static_cast(customColCurve3); + userColCurve.Apply(Cc); + float dred=55.f; + float protect_red=30.0f; + int sk=1; + float ko=1.f/coef; + Color::skinredfloat(Jpro, hpro, Cc, Ccold, dred, protect_red,sk,rstprotection,ko, Cpro); + if(Jpro < 1.f && Cpro > 12.f) Cpro=12.f;//reduce artifacts by "pseudo gamut control CIECAM" + else if(Jpro < 2.f && Cpro > 15.f) Cpro=15.f; + else if(Jpro < 4.f && Cpro > 30.f) Cpro=30.f; + else if(Jpro < 7.f && Cpro > 50.f) Cpro=50.f; + + } + else if (curveMode3==ColorAppearanceParams::TC_MODE_SATUR){ // + float parsat=0.8f;//0.6 + float coef=327.68f/parsat; + float Ss=(float) spro*coef; + float Sold=Ss; + const Saturcurve& userColCurve = static_cast(customColCurve3); + userColCurve.Apply(Ss); + Ss=0.6f*(Ss-Sold)+Sold;//divide sensibility saturation + float dred=100.f;// in C mode + float protect_red=80.0f; // in C mode + dred = 100.0f * sqrtf((dred*coe)/Qpro); + protect_red=100.0f * sqrtf((protect_red*coe)/Qpro); + int sk=0; + float ko=1.f/coef; + Color::skinredfloat(Jpro, hpro, Ss, Sold, dred, protect_red,sk,rstprotection,ko, spro); + Qpro= ( 4.0f / c ) * sqrtf( Jpro / 100.0f ) * ( aw + 4.0f ) ; + Cpro=(spro*spro*Qpro)/(10000.0f); + + } + else if (curveMode3==ColorAppearanceParams::TC_MODE_COLORF){ // + float parsat=0.8f;//0.68; + float coef=327.68f/parsat; + float Mm=(float) Mpro*coef; + float Mold=Mm; + const Colorfcurve& userColCurve = static_cast(customColCurve3); + userColCurve.Apply(Mm); + float dred=100.f;//in C mode + float protect_red=80.0f;// in C mode + dred *=coe;//in M mode + protect_red *=coe; + int sk=0; + float ko=1.f/coef; + Color::skinredfloat(Jpro, hpro, Mm, Mold, dred, protect_red,sk,rstprotection,ko, Mpro); + Cpro= Mpro/coe; + if(Jpro < 1.f && Mpro > 12.f*coe) Mpro=12.f*coe;//reduce artifacts by "pseudo gamut control CIECAM" + else if(Jpro < 2.f && Mpro > 15.f*coe) Mpro=15.f*coe; + else if(Jpro < 4.f && Mpro > 30.f*coe) Mpro=30.f*coe; + else if(Jpro < 7.f && Mpro > 50.f*coe) Mpro=50.f*coe; + } + } + //to retrieve the correct values of variables + + if(c1s) { + Qpro= ( 4.0f / c ) * sqrtf( Jpro / 100.0f ) * ( aw + 4.0f ) ;//for saturation curve + Cpro=(spro*spro*Qpro)/(10000.0f); + } + if(c1co) { + float coe=pow_F(fl,0.25f);Cpro= Mpro/coe;} // for colorfullness curve + //retrieve values C,J...s + C=Cpro; + J=Jpro; + Q=Qpro; + M=Mpro; + h=hpro; + s=spro; + + if(params->colorappearance.tonecie || settings->autocielab){//use pointer for tonemapping with CIECAM and also sharpening , defringe, contrast detail + ncie->Q_p[i][j]=(float)Q+epsil;//epsil to avoid Q=0 + ncie->M_p[i][j]=(float)M+epsil; + ncie->J_p[i][j]=(float)J+epsil; + ncie->h_p[i][j]=(float)h; + ncie->C_p[i][j]=(float)C+epsil; + ncie->sh_p[i][j]=(float) 3276.8f*(sqrtf( J ) ) ; + if(epdEnabled) { + if(ncie->Q_p[i][j]Q_p[i][j];//minima + if(ncie->Q_p[i][j]>maxQThr) + maxQThr = ncie->Q_p[i][j];//maxima + } + } + if(!params->colorappearance.tonecie || !settings->autocielab || !epdEnabled){ + + if(ciedata) { + // Data for J Q M s and C histograms + int posl, posc; + float brli=327.f; + float chsacol=327.f; + int libr=0; + int colch=0; + if(curveMode==ColorAppearanceParams::TC_MODE_BRIGHT) {brli=70.0f; libr=1;} + else if(curveMode==ColorAppearanceParams::TC_MODE_LIGHT) {brli=327.f;libr=0;} + if (curveMode3==ColorAppearanceParams::TC_MODE_CHROMA) {chsacol=327.f;colch=0;} + else if(curveMode3==ColorAppearanceParams::TC_MODE_SATUR) {chsacol=450.0f;colch=1;} + else if(curveMode3==ColorAppearanceParams::TC_MODE_COLORF) {chsacol=327.0f;colch=2;} + //update histogram + if(pW!=1){//only with improccoordinator + if(libr==1) posl=CLIP((int)(Q*brli));//40.0 to 100.0 approximative factor for Q - 327 for J + else if(libr==0) posl=CLIP((int)(J*brli));//327 for J + hist16JCAM[posl]++; + } + chropC=true; + if(pW!=1){//only with improccoordinator + if(colch==0) posc=CLIP((int)(C*chsacol));//450.0 approximative factor for s 320 for M + else if(colch==1) posc=CLIP((int)(s*chsacol)); + else if(colch==2) posc=CLIP((int)(M*chsacol)); + hist16_CCAM[posc]++; + } + } +if(LabPassOne){ +#ifdef __SSE2__ + // write to line buffers + Jbuffer[j] = J; + Cbuffer[j] = C; + hbuffer[j] = h; +#else + float xx,yy,zz; + //process normal==> viewing + + Ciecam02::jch2xyz_ciecam02float( xx, yy, zz, + J, C, h, + xw2, yw2, zw2, + yb2, la2, + f2, c2, nc2, gamu, pow1n, nbbj, ncbj, flj, czj, dj, awj); + float x,y,z; + x=(float)xx*655.35f; + y=(float)yy*655.35f; + z=(float)zz*655.35f; + float Ll,aa,bb; + //convert xyz=>lab + Color::XYZ2Lab(x, y, z, Ll, aa, bb); + + // gamut control in Lab mode; I must study how to do with cIECAM only + if(gamu==1) { + float HH, Lprov1, Chprov1; + Lprov1=Ll/327.68f; + Chprov1=sqrtf(SQR(aa) + SQR(bb))/327.68f; + HH=xatan2f(bb,aa); + float2 sincosval; + if(Chprov1==0.0f) { + sincosval.y = 1.f; + sincosval.x = 0.0f; + } else { + sincosval.y = aa/(Chprov1*327.68f); + sincosval.x = bb/(Chprov1*327.68f); + } + + +#ifdef _DEBUG + bool neg=false; + bool more_rgb=false; + //gamut control : Lab values are in gamut + Color::gamutLchonly(sincosval,Lprov1,Chprov1, wip, highlight, 0.15f, 0.96f, neg, more_rgb); +#else + //gamut control : Lab values are in gamut + Color::gamutLchonly(sincosval,Lprov1,Chprov1, wip, highlight, 0.15f, 0.96f); +#endif + + lab->L[i][j]=Lprov1*327.68f; + lab->a[i][j]=327.68f*Chprov1*sincosval.y; + lab->b[i][j]=327.68f*Chprov1*sincosval.x; + + } else { + lab->L[i][j]=Ll; + lab->a[i][j]=aa; + lab->b[i][j]=bb; + } +#endif + } + } + } +#ifdef __SSE2__ + // process line buffers + float *xbuffer = Qbuffer; + float *ybuffer = Mbuffer; + float *zbuffer = sbuffer; + for(k=0;klab + Color::XYZ2Lab(xbuffer[j], ybuffer[j], zbuffer[j], Ll, aa, bb); + + // gamut control in Lab mode; I must study how to do with cIECAM only + if(gamu==1) { + float HH, Lprov1, Chprov1; + Lprov1=Ll/327.68f; + Chprov1=sqrtf(SQR(aa) + SQR(bb))/327.68f; + HH=xatan2f(bb,aa); + float2 sincosval; + if(Chprov1==0.0f) { + sincosval.y = 1.f; + sincosval.x = 0.0f; + } else { + sincosval.y = aa/(Chprov1*327.68f); + sincosval.x = bb/(Chprov1*327.68f); + } +#ifdef _DEBUG + bool neg=false; + bool more_rgb=false; + //gamut control : Lab values are in gamut + Color::gamutLchonly(sincosval,Lprov1,Chprov1, wip, highlight, 0.15f, 0.96f, neg, more_rgb); +#else + //gamut control : Lab values are in gamut + Color::gamutLchonly(sincosval,Lprov1,Chprov1, wip, highlight, 0.15f, 0.96f); +#endif + lab->L[i][j]=Lprov1*327.68f; + lab->a[i][j]=327.68f*Chprov1*sincosval.y; + lab->b[i][j]=327.68f*Chprov1*sincosval.x; + } else { + lab->L[i][j]=Ll; + lab->a[i][j]=aa; + lab->b[i][j]=bb; + } + } +#endif + } +#pragma omp critical +{ + if(minQThr < minQ) + minQ = minQThr; + if(maxQThr > maxQ) + maxQ = maxQThr; +} + } + // End of parallelization +if(!params->colorappearance.tonecie || !settings->autocielab){//normal + + if(ciedata) { + //update histogram J + for (int i=0; i<32768; i++) {// + if (jp) { + float hval = dLcurve[i]; + int hi = (int)(255.0f*CLIPD(hval)); // + histLCAM[hi] += hist16JCAM[i] ; + } + } + for (int i=0; i<48000; i++) {// + if (chropC) { + float hvalc = dCcurve[i]; + int hic = (int)(255.0f*CLIPD(hvalc)); // + histCCAM[hic] += hist16_CCAM[i] ; + } + } + } +} +#ifdef _DEBUG + if (settings->verbose) { + t2e.set(); + printf("CIECAM02 performed in %d usec:\n", t2e.etime(t1e)); + // printf("minc=%f maxc=%f minj=%f maxj=%f\n",minc,maxc,minj,maxj); + } +#endif + +if(settings->autocielab) { +if((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)){ + + + +//all this treatments reduce artefacts, but can leed to slighty different results + +if(params->defringe.enabled) + if(execsharp) { + lab->deleteLab(); + ImProcFunctions::defringecam (ncie);//defringe adapted to CIECAM + lab->reallocLab(); + } +//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) artifact=6.f; + if(artifact <0.f) artifact=1.f; + + 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 + lab->reallocLab(); + } +} + +//if(params->colorappearance.badpixsl > 0) { int mode=params->colorappearance.badpixsl; +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 + lab->reallocLab(); +} + +if(params->impulseDenoise.enabled) if(execsharp) { + float **buffers[3]; + buffers[0] = lab->L; + buffers[1] = lab->a; + buffers[2] = lab->b; + ImProcFunctions::impulsedenoisecam (ncie,buffers);//impulse adapted to CIECAM +} + +if (params->sharpenMicro.enabled)if(execsharp) ImProcFunctions::MLmicrocontrastcam(ncie); + +if(params->sharpening.enabled) + if(execsharp) { + float **buffer = lab->L; // We can use the L-buffer from lab as buffer to save some memory + ImProcFunctions::sharpeningcam (ncie, buffer); // sharpening adapted to CIECAM + } + +//if(params->dirpyrequalizer.enabled) if(execsharp) { +if(params->dirpyrequalizer.enabled /*&& 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; + int choice=0;// I have not suppress this statement in case of !! always to 0 +// if(params->dirpyrequalizer.algo=="FI") choice=0; +// else if(params->dirpyrequalizer.algo=="LA") choice=1; + + if(rtt==1) { + 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, scalecd);//contrast by detail adapted to CIECAM + lab->reallocLab(); + } +/* +if(params->colorappearance.badpixsl > 0) if(execsharp){ int mode=params->colorappearance.badpixsl; +printf("BADPIX"); + ImProcFunctions::badpixcam (ncie, 8.0, 10, mode);//for bad pixels + } + */ +} + const float Qredi= ( 4.0f / c_) * ( a_w + 4.0f ); + const float co_e=(pow_F(f_l,0.25f)); + + +#ifndef _DEBUG +#pragma omp parallel +#endif +{ +#ifndef _DEBUG + #pragma omp for schedule(dynamic, 10) +#endif + for (int i=0; ish_p[i][j]/(32768.f)); + ncie->J_p[i][j]=100.0f* SQR(interm); + ncie->Q_p[i][j]=interm*Qredi; + ncie->M_p[i][j]=ncie->C_p[i][j]*co_e; + } + } +} +} +if((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)){ + + if(epdEnabled && params->colorappearance.tonecie && algepd) { + lab->deleteLab(); + ImProcFunctions::EPDToneMapCIE(ncie, a_w, c_, w_h, width, height, begh, endh, minQ, maxQ, Iterates, scale ); + lab->reallocLab(); + } + //EPDToneMapCIE adated to CIECAM + + + const float eps=0.0001f; + const float co_e=(pow_F(f_l,0.25f))+eps; + TMatrix wiprofa = iccStore->workingSpaceInverseMatrix (params->icm.working); + const float wipa[3][3] = { + {float(wiprofa[0][0]),float(wiprofa[0][1]),float(wiprofa[0][2])}, + {float(wiprofa[1][0]),float(wiprofa[1][1]),float(wiprofa[1][2])}, + {float(wiprofa[2][0]),float(wiprofa[2][1]),float(wiprofa[2][2])} + }; + +#ifndef _DEBUG +#pragma omp parallel +#endif +{ +#ifdef __SSE2__ + // one line buffer per channel + float Jbuffer[bufferLength] ALIGNED16; + float Cbuffer[bufferLength] ALIGNED16; + float hbuffer[bufferLength] ALIGNED16; + float *xbuffer = Jbuffer; // we can use one of the above buffers + float *ybuffer = Cbuffer; // " + float *zbuffer = hbuffer; // " +#endif + +#ifndef _DEBUG + #pragma omp for schedule(dynamic, 10) +#endif + for (int i=0; iJ_p[i][j]=(100.0f* ncie->Q_p[i][j]*ncie->Q_p[i][j])/(w_h*w_h); + if(epdEnabled) ncie->J_p[i][j]=(100.0f* ncie->Q_p[i][j]*ncie->Q_p[i][j])/SQR((4.f/c)*(aw+4.f)); + + const float ncie_C_p = (ncie->M_p[i][j])/co_e; + //show histogram in CIECAM mode (Q,J, M,s,C) + if(ciedata) { + // Data for J Q M s and C histograms + int posl, posc; + float brli=327.f; + float chsacol=327.f; + int libr=0; + int colch=0; + float sa_t; + if(curveMode==ColorAppearanceParams::TC_MODE_BRIGHT) {brli=70.0f; libr=1;} + else if(curveMode==ColorAppearanceParams::TC_MODE_LIGHT) {brli=327.f;libr=0;} + if (curveMode3==ColorAppearanceParams::TC_MODE_CHROMA) {chsacol=327.f;colch=0;} + else if(curveMode3==ColorAppearanceParams::TC_MODE_SATUR) {chsacol=450.0f;colch=1;} + else if(curveMode3==ColorAppearanceParams::TC_MODE_COLORF) {chsacol=327.0f;colch=2;} + //update histogram + if(pW!=1){//only with improccoordinator + if(libr==1) posl=CLIP((int)(ncie->Q_p[i][j]*brli));//40.0 to 100.0 approximative factor for Q - 327 for J + else if(libr==0) posl=CLIP((int)(ncie->J_p[i][j]*brli));//327 for J + hist16JCAM[posl]++; + } + chropC=true; + if(pW!=1){//only with improccoordinator + if(colch==0) posc=CLIP((int)(ncie_C_p*chsacol));//450.0 approximative factor for s 320 for M + else if(colch==1) {sa_t=100.f*sqrtf(ncie_C_p/ncie->Q_p[i][j]); posc=CLIP((int)(sa_t*chsacol));}//Q_p always > 0 + else if(colch==2) posc=CLIP((int)(ncie->M_p[i][j]*chsacol)); + hist16_CCAM[posc]++; + } + } + //end histograms + +#ifdef __SSE2__ + Jbuffer[j] = ncie->J_p[i][j]; + Cbuffer[j] = ncie_C_p; + hbuffer[j] = ncie->h_p[i][j]; +#else + Ciecam02::jch2xyz_ciecam02float( xx, yy, zz, + ncie->J_p[i][j], ncie_C_p, ncie->h_p[i][j], + xw2, yw2, zw2, + yb2, la2, + f2, c2, nc2, gamu, pow1n, nbbj, ncbj, flj, czj, dj, awj); + x=(float)xx*655.35f; + y=(float)yy*655.35f; + z=(float)zz*655.35f; + float Ll,aa,bb; + //convert xyz=>lab + Color::XYZ2Lab(x, y, z, Ll, aa, bb); + if(gamu==1) { + float Lprov1, Chprov1; + Lprov1=Ll/327.68f; + Chprov1=sqrtf(SQR(aa) + SQR(bb))/327.68f; + float2 sincosval; + if(Chprov1==0.0f) { + sincosval.y = 1.f; + sincosval.x = 0.0f; + } else { + sincosval.y = aa/(Chprov1*327.68f); + sincosval.x = bb/(Chprov1*327.68f); + } + + +#ifdef _DEBUG + bool neg=false; + bool more_rgb=false; + //gamut control : Lab values are in gamut + Color::gamutLchonly(sincosval,Lprov1,Chprov1, wipa, highlight, 0.15f, 0.96f, neg, more_rgb); +#else + //gamut control : Lab values are in gamut + Color::gamutLchonly(sincosval,Lprov1,Chprov1, wipa, highlight, 0.15f, 0.96f); +#endif + + lab->L[i][j]=Lprov1*327.68f; + lab->a[i][j]=327.68f*Chprov1*sincosval.y; + lab->b[i][j]=327.68f*Chprov1*sincosval.x; + } else { + lab->L[i][j]=Ll; + lab->a[i][j]=aa; + lab->b[i][j]=bb; + } +#endif + } +#ifdef __SSE2__ + // process line buffers + int k; + vfloat x,y,z; + vfloat c655d35 = F2V(655.35f); + for(k=0;klab + Color::XYZ2Lab(xbuffer[j], ybuffer[j], zbuffer[j], Ll, aa, bb); + if(gamu==1) { + float Lprov1, Chprov1; + Lprov1=Ll/327.68f; + Chprov1=sqrtf(SQR(aa) + SQR(bb))/327.68f; + float2 sincosval; + if(Chprov1==0.0f) { + sincosval.y = 1.f; + sincosval.x = 0.0f; + } else { + sincosval.y = aa/(Chprov1*327.68f); + sincosval.x = bb/(Chprov1*327.68f); + } +#ifdef _DEBUG + bool neg=false; + bool more_rgb=false; + //gamut control : Lab values are in gamut + Color::gamutLchonly(sincosval,Lprov1,Chprov1, wipa, highlight, 0.15f, 0.96f, neg, more_rgb); +#else + //gamut control : Lab values are in gamut + Color::gamutLchonly(sincosval,Lprov1,Chprov1, wipa, highlight, 0.15f, 0.96f); +#endif + lab->L[i][j]=Lprov1*327.68f; + lab->a[i][j]=327.68f*Chprov1*sincosval.y; + lab->b[i][j]=327.68f*Chprov1*sincosval.x; + } else { + lab->L[i][j]=Ll; + lab->a[i][j]=aa; + lab->b[i][j]=bb; + } + + } +#endif // __SSE2__ + } + +} //end parallelization + + //show CIECAM histograms + if(ciedata) { + //update histogram J and Q + for (int i=0; i<32768; i++) {// + if (jp) { + float hval = dLcurve[i]; + int hi = (int)(255.0f*CLIPD(hval)); // + histLCAM[hi] += hist16JCAM[i] ; + } + } + //update color histogram M,s,C + for (int i=0; i<48000; i++) {// + if (chropC) { + float hvalc = dCcurve[i]; + int hic = (int)(255.0f*CLIPD(hvalc)); // + histCCAM[hic] += hist16_CCAM[i] ; + } + } + } + + } +} +} +//end CIECAM + +void ImProcFunctions::moyeqt (Imagefloat* working, float &moyS, float &eqty) { +// MyTime t1e,t2e; +// t1e.set(); + + int tHh=working->height; + int tWw=working->width; + float moy=0.f; + float eqt=0.f; +#pragma omp parallel +{ +float mo=0.f; +#ifndef _DEBUG + #pragma omp for reduction(+:moy) +#endif + for (int i=0; ir(i,j)); + float g = CLIP(working->g(i,j)); + float b = CLIP(working->b(i,j)); + float h, s, v; + Color::rgb2hsv(r, g, b, h, s, v); + moy+=s; + } + } + mo=moy/(tHh*tWw); + moyS=mo; +#ifndef _DEBUG + #pragma omp for reduction(+:eqt) +#endif + for (int i=0; ir(i,j)); + float g = CLIP(working->g(i,j)); + float b = CLIP(working->b(i,j)); + float h, s, v; + Color::rgb2hsv(r, g, b, h, s, v); + eqt+=SQR(s-mo); + } + } +} + eqt=eqt/(tHh*tWw); + eqty=(sqrt(eqt)); + + // t2e.set(); + // printf("Moyeqt:%d\n", t2e.etime(t1e)); + +} + +static inline void +filmlike_clip_rgb_tone(float *r, float *g, float *b, const float L) +{ + float r_ = *r > L ? L : *r; + float b_ = *b > L ? L : *b; + float g_ = b_ + ((r_ - b_) * (*g - *b) / (*r - *b)); + *r = r_; + *g = g_; + *b = b_; +} + +static void +filmlike_clip(float *r, float *g, float *b) +{ + // This is Adobe's hue-stable film-like curve with a diagonal, ie only used for clipping. Can probably be further optimized. + const float L = 65535.0; + if (*r >= *g) { + if (*g > *b) { // Case 1: r >= g > b + filmlike_clip_rgb_tone(r, g, b, L); + } else if (*b > *r) { // Case 2: b > r >= g + filmlike_clip_rgb_tone(b, r, g, L); + } else if (*b > *g) { // Case 3: r >= b > g + filmlike_clip_rgb_tone(r, b, g, L); + } else { // Case 4: r >= g == b + *r = *r > L ? L : *r; + *g = *g > L ? L : *g; + *b = *g; + } + } else { + if (*r >= *b) { // Case 5: g > r >= b + filmlike_clip_rgb_tone(g, r, b, L); + } else if (*b > *g) { // Case 6: b > g > r + filmlike_clip_rgb_tone(b, g, r, L); + } else { // Case 7: g >= b > r + filmlike_clip_rgb_tone(g, b, r, L); + } + } +} + +void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, EditBuffer *editBuffer, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, + SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, float satLimit ,float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, bool opautili, LUTf & clToningcurve,LUTf & cl2Toningcurve, + const ToneCurve & customToneCurve1,const ToneCurve & customToneCurve2, const ToneCurve & customToneCurvebw1,const ToneCurve & customToneCurvebw2, double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, DCPProfile *dcpProf ) { + rgbProc (working, lab, editBuffer, hltonecurve, shtonecurve, tonecurve, shmap, sat, rCurve, gCurve, bCurve, satLimit ,satLimitOpacity, ctColorCurve, ctOpacityCurve, opautili, clToningcurve, cl2Toningcurve,customToneCurve1, customToneCurve2, customToneCurvebw1, customToneCurvebw2,rrm, ggm, bbm, autor, autog, autob, params->toneCurve.expcomp, params->toneCurve.hlcompr, params->toneCurve.hlcomprthresh, dcpProf); +} + +// Process RGB image and convert to LAB space +void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, EditBuffer *editBuffer, LUTf & hltonecurve, LUTf & shtonecurve, LUTf & tonecurve, + SHMap* shmap, int sat, LUTf & rCurve, LUTf & gCurve, LUTf & bCurve, float satLimit ,float satLimitOpacity, const ColorGradientCurve & ctColorCurve, const OpacityCurve & ctOpacityCurve, bool opautili, LUTf & clToningcurve,LUTf & cl2Toningcurve, + const ToneCurve & customToneCurve1, const ToneCurve & customToneCurve2, const ToneCurve & customToneCurvebw1,const ToneCurve & customToneCurvebw2,double &rrm, double &ggm, double &bbm, float &autor, float &autog, float &autob, double expcomp, int hlcompr, int hlcomprthresh, DCPProfile *dcpProf) { + + LUTf iGammaLUTf; + Imagefloat *tmpImage=NULL; + + // NOTE: We're getting all 3 pointers here, but this function may not need them all, so one could optimize this + Imagefloat* editImgFloat = NULL; + LabImage* editLab = NULL; + PlanarWhateverData* editWhatever = NULL; + EditUniqueID editID = editBuffer ? editBuffer->getEditID() : EUID_None; + if (editID != EUID_None) { + switch (editBuffer->getDataProvider()->getCurrSubscriber()->getEditBufferType()) { + case (BT_IMAGEFLOAT): + editImgFloat = editBuffer->getImgFloatBuffer(); + break; + case (BT_LABIMAGE): + editLab = editBuffer->getLabBuffer(); + break; + case (BT_SINGLEPLANE_FLOAT): + editWhatever = editBuffer->getSinglePlaneBuffer(); + break; + } + } + + int h_th, s_th; + if (shmap) { + h_th = shmap->max_f - params->sh.htonalwidth * (shmap->max_f - shmap->avg) / 100; + s_th = params->sh.stonalwidth * (shmap->avg - shmap->min_f) / 100; + } + + bool processSH = params->sh.enabled && shmap!=NULL && (params->sh.highlights>0 || params->sh.shadows>0); + bool processLCE = params->sh.enabled && shmap!=NULL && params->sh.localcontrast>0; + double lceamount = params->sh.localcontrast / 200.0; + + TMatrix wprof = iccStore->workingSpaceMatrix (params->icm.working); + TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params->icm.working); + + double toxyz[3][3] = { + { + ( wprof[0][0] / Color::D50x), + ( wprof[0][1] / Color::D50x), + ( wprof[0][2] / Color::D50x) + },{ + ( wprof[1][0]), + ( wprof[1][1]), + ( wprof[1][2]) + },{ + ( wprof[2][0] / Color::D50z), + ( wprof[2][1] / Color::D50z), + ( wprof[2][2] / Color::D50z) + } + }; + + //inverse matrix user select + 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]} + }; + + double wp[3][3] = { + {wprof[0][0],wprof[0][1],wprof[0][2]}, + {wprof[1][0],wprof[1][1],wprof[1][2]}, + {wprof[2][0],wprof[2][1],wprof[2][2]}}; + + + bool mixchannels = (params->chmixer.red[0]!=100 || params->chmixer.red[1]!=0 || params->chmixer.red[2]!=0 || + params->chmixer.green[0]!=0 || params->chmixer.green[1]!=100 || params->chmixer.green[2]!=0 || + params->chmixer.blue[0]!=0 || params->chmixer.blue[1]!=0 || params->chmixer.blue[2]!=100); + + FlatCurve* hCurve; + FlatCurve* sCurve; + FlatCurve* vCurve; + FlatCurve* bwlCurve; + + FlatCurveType hCurveType = (FlatCurveType)params->hsvequalizer.hcurve.at(0); + FlatCurveType sCurveType = (FlatCurveType)params->hsvequalizer.scurve.at(0); + FlatCurveType vCurveType = (FlatCurveType)params->hsvequalizer.vcurve.at(0); + FlatCurveType bwlCurveType = (FlatCurveType)params->blackwhite.luminanceCurve.at(0); + bool hCurveEnabled = hCurveType > FCT_Linear; + bool sCurveEnabled = sCurveType > FCT_Linear; + bool vCurveEnabled = vCurveType > FCT_Linear; + bool bwlCurveEnabled = bwlCurveType > FCT_Linear; + + // TODO: We should create a 'skip' value like for CurveFactory::complexsgnCurve (rtengine/curves.cc) + if (hCurveEnabled) { + hCurve = new FlatCurve(params->hsvequalizer.hcurve); + if (hCurve->isIdentity()) { + delete hCurve; + hCurve = NULL; + hCurveEnabled = false; + } + } + if (sCurveEnabled) { + sCurve = new FlatCurve(params->hsvequalizer.scurve); + if (sCurve->isIdentity()) { + delete sCurve; + sCurve = NULL; + sCurveEnabled = false; + } + } + if (vCurveEnabled) { + vCurve = new FlatCurve(params->hsvequalizer.vcurve); + if (vCurve->isIdentity()) { + delete vCurve; + vCurve = NULL; + vCurveEnabled = false; + } + } + if (bwlCurveEnabled) { + bwlCurve = new FlatCurve(params->blackwhite.luminanceCurve); + if (bwlCurve->isIdentity()) { + delete bwlCurve; + bwlCurve = NULL; + bwlCurveEnabled = false; + } + } + + ClutPtr colorLUT; + bool clutAndWorkingProfilesAreSame = false; + TMatrix work2xyz, xyz2clut, clut2xyz, xyz2work; + if ( params->filmSimulation.enabled && !params->filmSimulation.clutFilename.empty() ) + { + colorLUT.set( clutStore.getClut( params->filmSimulation.clutFilename ) ); + if ( colorLUT ) + { + clutAndWorkingProfilesAreSame = colorLUT->profile() == params->icm.working; + if ( !clutAndWorkingProfilesAreSame ) + { + work2xyz = iccStore->workingSpaceMatrix( params->icm.working ); + xyz2clut = iccStore->workingSpaceInverseMatrix( colorLUT->profile() ); + xyz2work = iccStore->workingSpaceInverseMatrix( params->icm.working ); + clut2xyz = iccStore->workingSpaceMatrix( colorLUT->profile() ); + } + } + } + + double filmSimCorrectedStrength = double(params->filmSimulation.strength)/100.; + double filmSimSourceStrength = double(100-params->filmSimulation.strength)/100.; + + const float exp_scale = pow (2.0, expcomp); + const float comp = (max(0.0, expcomp) + 1.0)*hlcompr/100.0; + const float shoulder = ((65536.0/max(1.0f,exp_scale))*(hlcomprthresh/200.0))+0.1; + const float hlrange = 65536.0-shoulder; + const bool isProPhoto = (params->icm.working == "ProPhoto"); + // extracting datas from 'params' to avoid cache flush (to be confirmed) + ToneCurveParams::eTCModeId curveMode = params->toneCurve.curveMode; + ToneCurveParams::eTCModeId curveMode2 = params->toneCurve.curveMode2; + bool highlight = params->toneCurve.hrenabled;//Get the value if "highlight reconstruction" is activated + bool hasToneCurve1 = bool(customToneCurve1); + bool hasToneCurve2 = bool(customToneCurve2); + BlackWhiteParams::eTCModeId beforeCurveMode = params->blackwhite.beforeCurveMode; + BlackWhiteParams::eTCModeId afterCurveMode = params->blackwhite.afterCurveMode; + + bool hasToneCurvebw1 = bool(customToneCurvebw1); + bool hasToneCurvebw2 = bool(customToneCurvebw2); + + bool hasColorToning = params->colorToning.enabled && bool(ctOpacityCurve) && bool(ctColorCurve); + // float satLimit = float(params->colorToning.satProtectionThreshold)/100.f*0.7f+0.3f; + // float satLimitOpacity = 1.f-(float(params->colorToning.saturatedOpacity)/100.f); + float strProtect = (float(params->colorToning.strength)/100.f); + + /* + // Debug output - Color LUTf points + if (ctColorCurve) { + printf("\nColor curve:"); + for (size_t i=0; i<501; i++) { + if (i==0 || i==250 || i==500) + printf("\n(%.1f)[", float(i)/500.f); + printf("%.3f ", ctColorCurve.lutHueCurve[float(i)]); + if (i==0 || i==250 || i==500) + printf("]\n"); + } + printf("\n"); + } + */ + + /* + // Debug output - Opacity LUTf points + if (ctOpacityCurve) { + printf("\nOpacity curve:"); + for (size_t i=0; i<501; i++) { + if (i==0 || i==250 || i==500) + printf("\n(%.1f)[", float(i)/500.f); + printf("%.3f ", ctOpacityCurve.lutOpacityCurve[float(i)]); + if (i==0 || i==250 || i==500) + printf("]\n"); + } + printf("\n"); + } + */ + + float RedLow = (100.f + float(params->colorToning.redlow))/100.f;//printf("Rel=%f\n",RedLow); + float GreenLow = (100.f + float(params->colorToning.greenlow))/100.f;//printf("Gre=%f\n",GreenLow); + float BlueLow = (100.f + float(params->colorToning.bluelow))/100.f;//printf("Blu=%f\n",BlueLow); + float RedMed = (100.f + float(params->colorToning.redmed))/100.f; + float GreenMed = (100.f + float(params->colorToning.greenmed))/100.f; + float BlueMed = (100.f + float(params->colorToning.bluemed))/100.f; + float RedHigh = (100.f + float(params->colorToning.redhigh))/100.f;//printf("RedH=%f\n",RedHigh); + float GreenHigh = (100.f + float(params->colorToning.greenhigh))/100.f; + float BlueHigh = (100.f + float(params->colorToning.bluehigh))/100.f; + float SatLow = float(params->colorToning.shadowsColSat.value[0])/100.f; + float SatHigh = float(params->colorToning.hlColSat.value[0])/100.f; + + float Balan = float(params->colorToning.balance); + + float chMixRR = float(params->chmixer.red[0]); + float chMixRG = float(params->chmixer.red[1]); + float chMixRB = float(params->chmixer.red[2]); + float chMixGR = float(params->chmixer.green[0]); + float chMixGG = float(params->chmixer.green[1]); + float chMixGB = float(params->chmixer.green[2]); + float chMixBR = float(params->chmixer.blue[0]); + float chMixBG = float(params->chmixer.blue[1]); + float chMixBB = float(params->chmixer.blue[2]); + + int shHighlights = params->sh.highlights; + int shShadows = params->sh.shadows; + bool blackwhite = params->blackwhite.enabled; + bool complem = params->blackwhite.enabledcc; + float bwr = float(params->blackwhite.mixerRed); + float bwg = float(params->blackwhite.mixerGreen); + float bwb = float(params->blackwhite.mixerBlue); + float bwrgam = float(params->blackwhite.gammaRed); + float bwggam = float(params->blackwhite.gammaGreen); + float bwbgam = float(params->blackwhite.gammaBlue); + float mixerOrange = float(params->blackwhite.mixerOrange); + float mixerYellow = float(params->blackwhite.mixerYellow); + float mixerCyan = float(params->blackwhite.mixerCyan); + float mixerMagenta = float(params->blackwhite.mixerMagenta); + float mixerPurple = float(params->blackwhite.mixerPurple); + int algm=0; + if (params->blackwhite.method=="Desaturation") algm=0; + else if(params->blackwhite.method=="LumEqualizer") algm=1; + else if(params->blackwhite.method=="ChannelMixer") algm=2; + float kcorec=1.f; + //gamma correction of each channel + float gamvalr=125.f; + float gamvalg=125.f; + float gamvalb=125.f; + double nr=0; + double ng=0; + double nb=0; + bool computeMixerAuto = params->blackwhite.autoc && (autor < -5000.f); + if(bwrgam < 0) gamvalr=100.f; + if(bwggam < 0) gamvalg=100.f; + if(bwbgam < 0) gamvalb=100.f; + float gammabwr=1.f; + float gammabwg=1.f; + float gammabwb=1.f; + //if (params->blackwhite.setting=="Ma" || params->blackwhite.setting=="Mr" || params->blackwhite.setting=="Fr" || params->blackwhite.setting=="Fa") { + { + gammabwr=1.f -bwrgam/gamvalr; + gammabwg=1.f -bwggam/gamvalg; + gammabwb=1.f -bwbgam/gamvalb; + } + bool hasgammabw = gammabwr!=1.f || gammabwg!=1.f || gammabwb!=1.f; + + //normalize gamma to sRGB + double start = exp(g*log( -0.055 / ((1.0/g-1.0)*1.055 ))); + double slope = 1.055 * pow (start, 1.0/g-1) - 0.055/start; + double mul = 1.055; + double add = 0.055; + + if (iGamma && g > 1.) { + iGammaLUTf(65535); +#pragma omp parallel for + for (int i=0; i<65536; i++) { + iGammaLUTf[i] = float(CurveFactory::igamma (double(i)/65535., g, start, slope, mul, add)*65535.); + } + } + + if (hasColorToning || blackwhite) + tmpImage = new Imagefloat(working->width,working->height); + +#define TS 112 + +#ifdef _OPENMP +#pragma omp parallel if (multiThread) +#endif +{ + char *buffer; + char *editIFloatBuffer = NULL; + char *editWhateverBuffer = NULL; + + buffer = (char *) malloc(3*sizeof(float)*TS*TS + 20*64 + 63); + char *data; + data = (char*)( ( uintptr_t(buffer) + uintptr_t(63)) / 64 * 64); + + float *rtemp = (float(*))data; + float *gtemp = (float (*)) ((char*)rtemp + sizeof(float)*TS*TS + 4*64); + float *btemp = (float (*)) ((char*)gtemp + sizeof(float)*TS*TS + 8*64); + int istart; + int jstart; + int tW; + int tH; + + // Allocating buffer for the EditBuffer + float *editIFloatTmpR, *editIFloatTmpG, *editIFloatTmpB, *editWhateverTmp; + if (editImgFloat) { + editIFloatBuffer = (char *) malloc(3*sizeof(float)*TS*TS + 20*64 + 63); + data = (char*)( ( uintptr_t(editIFloatBuffer) + uintptr_t(63)) / 64 * 64); + + editIFloatTmpR = (float(*))data; + editIFloatTmpG = (float (*)) ((char*)editIFloatTmpR + sizeof(float)*TS*TS + 4*64); + editIFloatTmpB = (float (*)) ((char*)editIFloatTmpG + sizeof(float)*TS*TS + 8*64); + } + if (editWhatever) { + editWhateverBuffer = (char *) malloc(sizeof(float)*TS*TS + 20*64 + 63); + data = (char*)( ( uintptr_t(editWhateverBuffer) + uintptr_t(63)) / 64 * 64); + + editWhateverTmp = (float(*))data; + } + + +#ifdef _OPENMP +#pragma omp for schedule(dynamic) collapse(2) +#endif + for(int ii=0;iiheight;ii+=TS) + for(int jj=0;jjwidth;jj+=TS) { + istart = ii; + jstart = jj; + tH = min(ii+TS,working->height); + tW = min(jj+TS,working->width); + + + for (int i=istart,ti=0; ir(i,j); + gtemp[ti*TS+tj] = working->g(i,j); + btemp[ti*TS+tj] = working->b(i,j); + } + } + + if (mixchannels) { + for (int i=istart,ti=0; imap[i][j]; + double factor = 1.0; + + if (processSH) { + if (mapval > h_th) + factor = (h_th + (100.0 - shHighlights) * (mapval - h_th) / 100.0) / mapval; + else if (mapval < s_th) + factor = (s_th - (100.0 - shShadows) * (s_th - mapval) / 100.0) / mapval; + } + if (processLCE) { + double sub = lceamount*(mapval-factor*(r*lumimul[0] + g*lumimul[1] + b*lumimul[2])); + rtemp[ti*TS+tj] = factor*r-sub; + gtemp[ti*TS+tj] = factor*g-sub; + btemp[ti*TS+tj] = factor*b-sub; + } + else { + rtemp[ti*TS+tj] = factor*r; + gtemp[ti*TS+tj] = factor*g; + btemp[ti*TS+tj] = factor*b; + } + } + } + } + + for (int i=istart,ti=0; istep2ApplyTile(rtemp, gtemp, btemp, tW-jstart, tH-istart, TS, exp_scale); + } + for (int i=istart,ti=0; i 65535 || g > 65535 || b > 65535) { + filmlike_clip(&r, &g, &b); + } + + rtemp[ti*TS+tj] = r; + gtemp[ti*TS+tj] = g; + btemp[ti*TS+tj] = b; + } + } + + for (int i=istart,ti=0; i(customToneCurve1); + userToneCurve.Apply(rtemp[ti*TS+tj], gtemp[ti*TS+tj], btemp[ti*TS+tj]); + } + } + } + else if (curveMode==ToneCurveParams::TC_MODE_FILMLIKE){ // Adobe like + for (int i=istart,ti=0; i(customToneCurve1); + userToneCurve.Apply(rtemp[ti*TS+tj], gtemp[ti*TS+tj], btemp[ti*TS+tj]); + } + } + } + else if (curveMode==ToneCurveParams::TC_MODE_SATANDVALBLENDING){ // apply the curve on the saturation and value channels + for (int i=istart,ti=0; i(customToneCurve1); + 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]); + userToneCurve.Apply(rtemp[ti*TS+tj], gtemp[ti*TS+tj], btemp[ti*TS+tj]); + } + } + } + else if (curveMode==ToneCurveParams::TC_MODE_WEIGHTEDSTD){ // apply the curve to the rgb channels, weighted + const WeightedStdToneCurve& userToneCurve = static_cast(customToneCurve1); + for (int i=istart,ti=0; i(rtemp[ti*TS+tj]); + gtemp[ti*TS+tj] = CLIP(gtemp[ti*TS+tj]); + btemp[ti*TS+tj] = CLIP(btemp[ti*TS+tj]); + userToneCurve.Apply(rtemp[ti*TS+tj], gtemp[ti*TS+tj], btemp[ti*TS+tj]); + } + } + } + else if (curveMode==ToneCurveParams::TC_MODE_LUMINANCE){ // apply the curve to the luminance channel + const LuminanceToneCurve& userToneCurve = static_cast(customToneCurve1); + for (int i=istart,ti=0; i(rtemp[ti*TS+tj]); + gtemp[ti*TS+tj] = CLIP(gtemp[ti*TS+tj]); + btemp[ti*TS+tj] = CLIP(btemp[ti*TS+tj]); + userToneCurve.Apply(rtemp[ti*TS+tj], gtemp[ti*TS+tj], btemp[ti*TS+tj]); + } + } + } + } + + if (editID == EUID_ToneCurve2) { // filling the pipette buffer + for (int i=istart,ti=0; i(customToneCurve2); + userToneCurve.Apply(rtemp[ti*TS+tj], gtemp[ti*TS+tj], btemp[ti*TS+tj]); + } + } + } + else if (curveMode2==ToneCurveParams::TC_MODE_FILMLIKE){ // Adobe like + for (int i=istart,ti=0; i(customToneCurve2); + userToneCurve.Apply(rtemp[ti*TS+tj], gtemp[ti*TS+tj], btemp[ti*TS+tj]); + } + } + } + else if (curveMode2==ToneCurveParams::TC_MODE_SATANDVALBLENDING){ // apply the curve on the saturation and value channels + for (int i=istart,ti=0; i(customToneCurve2); + userToneCurve.Apply(rtemp[ti*TS+tj], gtemp[ti*TS+tj], btemp[ti*TS+tj]); + } + } + } + else if (curveMode2==ToneCurveParams::TC_MODE_WEIGHTEDSTD){ // apply the curve to the rgb channels, weighted + const WeightedStdToneCurve& userToneCurve = static_cast(customToneCurve2); + for (int i=istart,ti=0; i(customToneCurve2); + for (int i=istart,ti=0; irgbCurves.lumamode){ // normal RGB mode + + for (int i=istart,ti=0; irgbCurves.lumamode==true (Luminosity mode) + // rCurve.dump("r_curve");//debug + + for (int i=istart,ti=0; irgbcurveslumamode_gamut) { + float RR,GG,BB; + float HH, Lpro, Chpro; + Lpro=L_2/327.68f; + Chpro=sqrt(SQR(a_1) + SQR(b_1))/327.68f; + HH=xatan2f(b_1,a_1); + // According to mathematical laws we can get the sin and cos of HH by simple operations + float2 sincosval; + if(Chpro==0.0f) { + sincosval.y = 1.0f; + sincosval.x = 0.0f; + } else { + sincosval.y = a_1/(Chpro*327.68f); + sincosval.x = b_1/(Chpro*327.68f); + } + +#ifdef _DEBUG + bool neg=false; + bool more_rgb=false; + //gamut control : Lab values are in gamut + Color::gamutLchonly(HH,Lpro,Chpro, RR, GG, BB, wip, highlight, 0.15f, 0.96f, neg, more_rgb); +#else + //gamut control : Lab values are in gamut + Color::gamutLchonly(HH,Lpro,Chpro, RR, GG, BB, wip, highlight, 0.15f, 0.96f); +#endif + + //Color::gamutLchonly(HH,Lpro,Chpro, RR, GG, BB, wip, highlight, 0.15f, 0.96f); + + + +// float2 sincosval = xsincosf(HH); + + L_2=Lpro*327.68f; + a_1=327.68f*Chpro*sincosval.y; + b_1=327.68f*Chpro*sincosval.x; + } //end of gamut control + + //calculate RGB with L_2 and old value of a and b + Color::Lab2XYZ(L_2, a_1, b_1, x_, y_, z_) ; + Color::xyz2rgb(x_,y_,z_,R,G,B,wip); + + rtemp[ti*TS+tj] =R; + gtemp[ti*TS+tj] =G; + btemp[ti*TS+tj] =B; + } + } + } + } + + if (editID == EUID_HSV_H || editID == EUID_HSV_S || editID == EUID_HSV_V) { + for (int i=istart,ti=0; i 0) { + s = (1.f-satby100)*s+satby100*(1.f-SQR(SQR(1.f-min(s,1.0f)))); + if (s<0.f) s=0.f; + } else /*if (sat < 0)*/ + s *= 1.f+satby100; + + //HSV equalizer + if (hCurveEnabled) { + h = (hCurve->getVal(double(h)) - 0.5) * 2.f + h; + if (h > 1.0f) + h -= 1.0f; + else if (h < 0.0f) + h += 1.0f; + } + if (sCurveEnabled) { + //shift saturation + float satparam = (sCurve->getVal(double(h))-0.5) * 2; + if (satparam > 0.00001f) { + s = (1.f-satparam)*s+satparam*(1.f-SQR(1.f-min(s,1.0f))); + if (s<0.f) s=0.f; + } else if (satparam < -0.00001f) + s *= 1.f+satparam; + + } + if (vCurveEnabled) { + if (v<0) v=0; // important + + //shift value + float valparam = vCurve->getVal((double)h)-0.5f; + valparam *= (1.f-SQR(SQR(1.f-min(s,1.0f)))); + if (valparam > 0.00001f) { + v = (1.f-valparam)*v+ valparam*(1.f-SQR(1.f-min(v,1.0f)));// SQR (SQR to increase action and avoid artefacts + if (v<0) v=0; + } else { + if (valparam < -0.00001f) + v *= (1.f+ valparam);//1.99 to increase action + } + + } + Color::hsv2rgb(h, s, v, rtemp[ti*TS+tj], gtemp[ti*TS+tj], btemp[ti*TS+tj]); + } + } + } + + if (isProPhoto) { // this is a hack to avoid the blue=>black bug (Issue 2141) + for (int i=istart,ti=0; icolorToning.method=="Splitlr") { + float balanS, balanH; + float reducac= 0.4f; + int preser=0; + if(params->colorToning.lumamode == true) preser=1; + + balanS = 1.f + Balan/100.f;//balan between 0 and 2 + balanH = 1.f - Balan/100.f; + float rh, gh, bh; + float rl, gl, bl; + float xh, yh, zh; + float xl, yl, zl; + float iplow,iphigh; + iplow=(float)ctColorCurve.low; + iphigh=(float)ctColorCurve.high; + //2 colours + ctColorCurve.getVal(iphigh, xh, yh, zh); + ctColorCurve.getVal(iplow, xl, yl, zl); + + Color::xyz2rgb(xh, yh, zh, rh, gh, bh, wip); + Color::xyz2rgb(xl, yl, zl, rl, gl, bl, wip); + //reteave rgb value with s and l =1 + retreavergb(rl,gl,bl); + retreavergb(rh,gh,bh); + //printf("rl=%f gl=%f bl=%f\n",rl,gl,bl); + + for (int i=istart,ti=0; icolorToning.method=="Splitco") { +/* +#if 1 + for (int i=istart,ti=0; i crash + gtemp[ti*TS+tj] = CLIP(go); + btemp[ti*TS+tj] = CLIP(bo); + } + } +#else +*/ + float reducac = 0.3f; + int preser = 0; + //bool execbal = params->colorToning.method=="Splitbal"; + if(params->colorToning.lumamode == true) preser = 1; + + for (int i=istart,ti=0; icolorToning.method=="Lab" && opautili) { + int algm=0; + bool twocol = true;//true=500 color false=2 color + int metchrom; + if (params->colorToning.twocolor=="Std" ) metchrom=0; + else if (params->colorToning.twocolor=="All" ) metchrom=1; + else if (params->colorToning.twocolor=="Separ") metchrom=2; + else if (params->colorToning.twocolor=="Two" ) metchrom=3; + + if(metchrom==3) twocol=false; + + float iplow,iphigh; + if(twocol==false){ + iplow=(float)ctColorCurve.low; + iphigh=(float)ctColorCurve.high; + } + + int twoc=0;//integer instead of bool to let more possible choice...other than 2 and 500. + if (twocol==false) twoc=0; // 2 colours + else twoc=1; // 500 colours + if (params->colorToning.method=="Lab") algm=1; + else if (params->colorToning.method=="Lch") algm=2;//in case of + if (algm <=2) { + for (int i=istart,ti=0; i crash + gtemp[ti*TS+tj] = CLIP(go); + btemp[ti*TS+tj] = CLIP(bo); + } + } + } + } + else if (params->colorToning.method.substr(0,3)=="RGB" && opautili) { + // color toning + for (int i=istart,ti=0; i(s/satLimit, 1.f)*(1.f-satLimitOpacity)) * ctOpacityCurve.lutOpacityCurve[l_*500.f]; + if(!ctOpacityCurve) opacity=0.f; + float r2, g2, b2; + ctColorCurve.getVal(l_, r2, g2, b2); // get the color from the color curve + + float h2, s2, l2; + Color::rgb2hsl(r2,g2,b2,h2,s2,l2); // transform this new color to hsl + + Color::hsl2rgb(h2, s+((1.f-s)*(1.f-l)*0.7f), l, r2, g2, b2); + + rtemp[ti*TS+tj] = r+(r2-r)*opacity; // merge the color to the old color, depending on the opacity + gtemp[ti*TS+tj] = g+(g2-g)*opacity; + btemp[ti*TS+tj] = b+(b2-b)*opacity; + } + } + } + } + + // filling the pipette buffer + if (editID == EUID_BlackWhiteBeforeCurve) { + for (int i=istart,ti=0; ilab + Color::rgbxyz(rtemp[ti*TS+tj], gtemp[ti*TS+tj], btemp[ti*TS+tj], X, Y, Z, wp); + //convert Lab + Color::XYZ2Lab(X, Y, Z, L, aa, bb); + //end rgb=>lab + float HH=xatan2f(bb,aa);// HH hue in -3.141 +3.141 + + editWhateverTmp[ti*TS+tj] = float(Color::huelab_to_huehsv2(HH)); + } + } + } + + //Film Simulations + if ( colorLUT ) + { + for (int i=istart,ti=0; i( Color::gamma_srgb( sourceR ) ); + sourceG = CLIP( Color::gamma_srgb( sourceG ) ); + sourceB = CLIP( Color::gamma_srgb( sourceB ) ); + + float r, g, b; + colorLUT->getRGB( sourceR, sourceG, sourceB, r, g, b ); + // apply strength + sourceR = r * filmSimCorrectedStrength + sourceR * filmSimSourceStrength; + sourceG = g * filmSimCorrectedStrength + sourceG * filmSimSourceStrength; + sourceB = b * filmSimCorrectedStrength + sourceB * filmSimSourceStrength; + // apply inverse gamma sRGB + sourceR = Color::igamma_srgb( sourceR ); + sourceG = Color::igamma_srgb( sourceG ); + sourceB = Color::igamma_srgb( sourceB ); + + if (!clutAndWorkingProfilesAreSame) { + //convert from clut to working profile + float x, y, z; + Color::rgbxyz( sourceR, sourceG, sourceB, x, y, z, clut2xyz ); + Color::xyz2rgb( x, y, z, sourceR, sourceG, sourceB, xyz2work ); + } + + } + } + } + + //black and white + if(blackwhite){ + if (hasToneCurvebw1) { + if (beforeCurveMode==BlackWhiteParams::TC_MODE_STD_BW){ // Standard + for (int i=istart,ti=0; i(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(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(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]); + userToneCurvebw.Apply(rtemp[ti*TS+tj], gtemp[ti*TS+tj], btemp[ti*TS+tj]); + } + } + } + else if (beforeCurveMode==BlackWhiteParams::TC_MODE_WEIGHTEDSTD_BW){ // apply the curve to the rgb channels, weighted + for (int i=istart,ti=0; i(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]); + + userToneCurvebw.Apply(rtemp[ti*TS+tj], gtemp[ti*TS+tj], btemp[ti*TS+tj]); + } + } + } + } + + if (algm==0){//lightness + for (int i=istart,ti=0; ilab + float r = rtemp[ti*TS+tj]; + float g = gtemp[ti*TS+tj]; + float b = btemp[ti*TS+tj]; + float X,Y,Z; + float L,aa,bb; + Color::rgbxyz(r,g,b,X,Y,Z,wp); + //convert Lab + Color::XYZ2Lab(X, Y, Z, L, aa, bb); + //end rgb=>lab + //lab ==> Ch + float CC=sqrt(SQR(aa/327.68f) + SQR(bb/327.68f));//CC chromaticity in 0..180 or more + float HH=xatan2f(bb,aa);// HH hue in -3.141 +3.141 + float l_r;//Luminance Lab in 0..1 + l_r = L/32768.f; + + if (bwlCurveEnabled) { + double hr = Color::huelab_to_huehsv2(HH); + float valparam = float((bwlCurve->getVal(hr)-0.5f) * 2.0f);//get l_r=f(H) + float kcc=(CC/70.f);//take Chroma into account...70 "middle" of chromaticity (arbitrary and simple), one can imagine other algorithme + //reduct action for low chroma and increase action for high chroma + valparam *= kcc; + if(valparam > 0.f) { l_r = (1.f-valparam)*l_r+ valparam*(1.f-SQR(SQR(SQR(SQR(1.f-min(l_r,1.0f))))));}// SQR (SQR((SQR) to increase action in low light + else l_r *= (1.f + valparam);//for negative + } + L=l_r*32768.f; + float RR,GG,BB; + float Lr; + Lr=L/327.68f;//for gamutlch +#ifdef _DEBUG + bool neg=false; + bool more_rgb=false; + //gamut control : Lab values are in gamut + Color::gamutLchonly(HH,Lr,CC, RR, GG, BB, wip, highlight, 0.15f, 0.96f, neg, more_rgb); +#else + //gamut control : Lab values are in gamut + Color::gamutLchonly(HH,Lr,CC, RR, GG, BB, wip, highlight, 0.15f, 0.96f); +#endif + //convert CH ==> ab + L=Lr*327.68f; + // float a_,b_; + // a_=0.f;//grey + // b_=0.f;//grey + //convert lab=>rgb + Color::Lab2XYZ(L, 0.f, 0.f, X, Y, Z); + float rr_,gg_,bb_; + Color::xyz2rgb(X,Y,Z,rr_,gg_,bb_,wip); + rtemp[ti*TS+tj] = gtemp[ti*TS+tj]= btemp[ti*TS+tj] = rr_; + // tmpImage->r(i,j) = tmpImage->g(i,j) = tmpImage->b(i,j) = CLIP(val[0]*kcorec); + + if (hasgammabw) + Color::trcGammaBW (rtemp[ti*TS+tj], gtemp[ti*TS+tj], btemp[ti*TS+tj], gammabwr, gammabwg, gammabwb); + + //gamma correction: pseudo TRC curve + // if (hasgammabw) + // Color::trcGammaBW (rr_, gg_, bb_, gammabwr, gammabwg, gammabwb); + // rtemp[ti*TS+tj] = rr_; + // gtemp[ti*TS+tj] = gg_; + // btemp[ti*TS+tj] = bb_; + } + } + } + } + if(!blackwhite) { + // ready, fill lab + for (int i=istart,ti=0; ir(i,j) = editIFloatTmpR[ti*TS+tj]; + editImgFloat->g(i,j) = editIFloatTmpG[ti*TS+tj]; + editImgFloat->b(i,j) = editIFloatTmpB[ti*TS+tj]; + } + else if (editWhatever) { + editWhatever->v(i,j) = editWhateverTmp[ti*TS+tj]; + } + + float r = rtemp[ti*TS+tj]; + float g = gtemp[ti*TS+tj]; + float b = btemp[ti*TS+tj]; + + float x = toxyz[0][0] * r + toxyz[0][1] * g + toxyz[0][2] * b; + float y = toxyz[1][0] * r + toxyz[1][1] * g + toxyz[1][2] * b; + float z = toxyz[2][0] * r + toxyz[2][1] * g + toxyz[2][2] * b; + + float fx,fy,fz; + + fx = (x<65535.0f ? cachef[std::max(x,0.f)] : (327.68f*float(exp(log(x/MAXVALF)/3.0f )))); + fy = (y<65535.0f ? cachef[std::max(y,0.f)] : (327.68f*float(exp(log(y/MAXVALF)/3.0f )))); + fz = (z<65535.0f ? cachef[std::max(z,0.f)] : (327.68f*float(exp(log(z/MAXVALF)/3.0f )))); + + lab->L[i][j] = (116.0f * fy - 5242.88f); //5242.88=16.0*327.68; + lab->a[i][j] = (500.0f * (fx - fy) ); + lab->b[i][j] = (200.0f * (fy - fz) ); + + //test for color accuracy + /* + float fy = (0.00862069 * lab->L[i][j])/327.68 + 0.137932; // (L+16)/116 + float fx = (0.002 * lab->a[i][j])/327.68 + fy; + float fz = fy - (0.005 * lab->b[i][j])/327.68; + + float x_ = 65535*Lab2xyz(fx)*Color::D50x; + float y_ = 65535*Lab2xyz(fy); + float z_ = 65535*Lab2xyz(fz)*Color::D50z; + + int R,G,B; + xyz2srgb(x_,y_,z_,R,G,B); + r=(float)R; g=(float)G; b=(float)B; + float xxx=1; + */ + } + } + } else { // black & white + // Auto channel mixer needs whole image, so we now copy to tmpImage and close the tiled processing + for (int i=istart,ti=0; ir(i,j) = editIFloatTmpR[ti*TS+tj]; + editImgFloat->g(i,j) = editIFloatTmpG[ti*TS+tj]; + editImgFloat->b(i,j) = editIFloatTmpB[ti*TS+tj]; + } + else if (editWhatever) { + editWhatever->v(i,j) = editWhateverTmp[ti*TS+tj]; + } + + tmpImage->r(i,j) = rtemp[ti*TS+tj]; + tmpImage->g(i,j) = gtemp[ti*TS+tj]; + tmpImage->b(i,j) = btemp[ti*TS+tj]; + } + } + } + } + free(buffer); + if (editIFloatBuffer) free (editIFloatBuffer); + if (editWhateverBuffer) free (editWhateverBuffer); + +} + // starting a new tile processing with a 'reduction' clause for the auto mixer computing + if (blackwhite) {//channel-mixer + int tW = working->width; + int tH = working->height; + if (algm==2) {//channel-mixer + //end auto chmix + float mix[3][3]; + + if (computeMixerAuto) { + // auto channel-mixer + +#ifdef _OPENMP +#pragma omp parallel for schedule(dynamic, 5) reduction(+:nr,ng,nb) +#endif + for (int i=0; ir(i,j); + ng += tmpImage->g(i,j); + nb += tmpImage->b(i,j); + } + } + + double srgb = nr+ng+nb; + double knr = srgb/nr; + double kng = srgb/ng; + double knb = srgb/nb; + double sk = knr+kng+knb; + autor=(float)(100.0*knr/sk); + autog=(float)(100.0*kng/sk); + autob=(float)(100.0*knb/sk); + + } + + if (params->blackwhite.autoc) { + // auto channel-mixer + bwr = autor; + bwg = autog; + bwb = autob; + mixerOrange = 33.f; + mixerYellow = 33.f; + mixerMagenta = 33.f; + mixerPurple = 33.f; + mixerCyan = 33.f; + } + float filcor; + Color::computeBWMixerConstants(params->blackwhite.setting, params->blackwhite.filter,params->blackwhite.algo,filcor, + bwr, bwg, bwb, mixerOrange, mixerYellow, mixerCyan, mixerPurple, mixerMagenta, + params->blackwhite.autoc, complem, kcorec, rrm, ggm, bbm); + + mix[0][0] = bwr; + mix[1][0] = bwr; + mix[2][0] = bwr; + mix[0][1] = bwg; + mix[1][1] = bwg; + mix[2][1] = bwg; + mix[0][2] = bwb; + mix[1][2] = bwb; + mix[2][2] = bwb; + +#ifdef _OPENMP +#pragma omp parallel for schedule(dynamic, 5) +#endif + for (int i=0; ir(i,j); + in[1] = tmpImage->g(i,j); + in[2] = tmpImage->b(i,j); + //mix channel + for (int end=0; end < 3 ; end++){ + val[end]=0.f; + for (int beg=0; beg < 3 ; beg++) { + val[end] += mix[end][beg] *in[beg]; + } + } + tmpImage->r(i,j) = tmpImage->g(i,j) = tmpImage->b(i,j) = CLIP(val[0]*kcorec); + + //gamma correction: pseudo TRC curve + if (hasgammabw) Color::trcGammaBW (tmpImage->r(i,j), tmpImage->g(i,j), tmpImage->b(i,j), gammabwr, gammabwg, gammabwb); + } + } + } + if (editID == EUID_BlackWhiteAfterCurve) { +#ifdef _OPENMP +#pragma omp parallel for schedule(dynamic, 5) +#endif + for (int i=0; iv(i,j) = CLIP(tmpImage->r(i,j)/65535.f); // assuming that r=g=b + } + } + } + + if (hasToneCurvebw2) { + + if (afterCurveMode==BlackWhiteParams::TC_MODE_STD_BW){ // Standard +#ifdef _OPENMP +#pragma omp parallel for schedule(dynamic, 5) +#endif + for (int i=0; i(customToneCurvebw2); + userToneCurve.Apply(tmpImage->r(i,j), tmpImage->g(i,j), tmpImage->b(i,j)); + } + } + } + else if (afterCurveMode==BlackWhiteParams::TC_MODE_WEIGHTEDSTD_BW){ // apply the curve to the rgb channels, weighted +#ifdef _OPENMP +#pragma omp parallel for schedule(dynamic, 5) +#endif + for (int i=0; i(customToneCurvebw2); + + tmpImage->r(i,j) = CLIP(tmpImage->r(i,j)); + tmpImage->g(i,j) = CLIP(tmpImage->g(i,j)); + tmpImage->b(i,j) = CLIP(tmpImage->b(i,j)); + + userToneCurve.Apply(tmpImage->r(i,j), tmpImage->g(i,j), tmpImage->b(i,j)); + } + } + } + } + + //colortoning with black and white + if (hasColorToning) { + if(params->colorToning.method=="Splitco") { +/* + #if 1 + for (int i=istart,ti=0; i crash + gtemp[ti*TS+tj] = CLIP(go); + btemp[ti*TS+tj] = CLIP(bo); + } + } +#else +*/ + int preser=0; + if(params->colorToning.lumamode == true) preser=1; + + float reducac= 0.3f; +#ifdef _OPENMP +#pragma omp parallel for schedule(dynamic, 5) +#endif + + for (int i=0; ir(i,j); + float g = tmpImage->g(i,j); + float b = tmpImage->b(i,j); + + float lumbefore=0.299f*r + 0.587f*g + 0.114f*b; + 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); + float lumafter=0.299f*ro + 0.587f*go + 0.114f*bo; + float preserv=1.f; + if(preser==1) preserv=lumbefore/lumafter; + ro*=preserv; + go*=preserv; + bo*=preserv; + ro=CLIP(ro); + go=CLIP(go); + bo=CLIP(bo); + tmpImage->r(i,j)=ro; + tmpImage->g(i,j)=go; + tmpImage->b(i,j)=bo; + } + } + } +//#endif + } + + else if (params->colorToning.method=="Splitlr") { + float balanS, balanH; + float reducac= 0.4f; + int preser=0; + if(params->colorToning.lumamode == true) preser=1; + + balanS = 1.f + Balan/100.f;//balan between 0 and 2 + balanH = 1.f - Balan/100.f; + float rh, gh, bh; + float rl, gl, bl; + float xh, yh, zh; + float xl, yl, zl; + float iplow,iphigh; + iplow=(float)ctColorCurve.low; + iphigh=(float)ctColorCurve.high; + + //2 colours + ctColorCurve.getVal(iphigh, xh, yh, zh); + ctColorCurve.getVal(iplow, xl, yl, zl); + + Color::xyz2rgb(xh, yh, zh, rh, gh, bh, wip); + Color::xyz2rgb(xl, yl, zl, rl, gl, bl, wip); + + //retrieve rgb value with s and l =1 + retreavergb(rl,gl,bl); + retreavergb(rh,gh,bh); +#ifdef _OPENMP +#pragma omp parallel for schedule(dynamic, 5) +#endif + for (int i=0; ir(i,j); + float g = tmpImage->g(i,j); + float b = tmpImage->b(i,j); + + float ro,go,bo; + int mode=1; + toning2col (r, g, b, ro, go, bo, iplow, iphigh, rl, gl, bl, rh, gh, bh, SatLow, SatHigh, balanS, balanH, reducac, mode, preser, strProtect); + tmpImage->r(i,j)=ro; + tmpImage->g(i,j)=go; + tmpImage->b(i,j)=bo; + } + } + } + + //colortoning with shift color Lab + else if (params->colorToning.method=="Lab" && opautili) { + int algm=0; + bool twocol = true; + int metchrom; + if (params->colorToning.twocolor=="Std" ) metchrom=0; + else if (params->colorToning.twocolor=="All" ) metchrom=1; + else if (params->colorToning.twocolor=="Separ") metchrom=2; + else if (params->colorToning.twocolor=="Two" ) metchrom=3; + + if(metchrom==3) twocol=false; + + float iplow,iphigh; + if(twocol==false) { + iplow=(float)ctColorCurve.low; + iphigh=(float)ctColorCurve.high; + + } + int twoc=0;//integer instead of bool to let more possible choice...other than 2 and 500. + if(twocol==false) twoc=0; // 2 colours + else twoc=1; // 500 colours + if (params->colorToning.method=="Lab") algm=1; + else if(params->colorToning.method=="Lch") algm=2; //in case of + if(algm <=2) { +#ifdef _OPENMP +#pragma omp parallel for schedule(dynamic, 5) +#endif + for (int i=0; ir(i,j); + float g = tmpImage->g(i,j); + float b = tmpImage->b(i,j); + float ro,bo,go; + labtoning (r, g, b, ro, go, bo, algm, metchrom, twoc, satLimit, satLimitOpacity, ctColorCurve, ctOpacityCurve, clToningcurve,cl2Toningcurve, iplow, iphigh, wp, wip); + tmpImage->r(i,j)=CLIP(ro); + tmpImage->g(i,j)=CLIP(go); + tmpImage->b(i,j)=CLIP(bo); + + } + } + } + } + + else if (params->colorToning.method.substr(0,3)=="RGB" && opautili) { + // color toning +#ifdef _OPENMP +#pragma omp parallel for schedule(dynamic, 5) +#endif + for (int i=0; ir(i,j); + float g = tmpImage->g(i,j); + float b = tmpImage->b(i,j); + + // Luminance = (0.299f*r + 0.587f*g + 0.114f*b) + + float h,s,l; + Color::rgb2hsl(r,g,b,h,s,l); + + float l_ = Color::gamma_srgb(l*65535.f)/65535.f; + + // get the opacity and tweak it to preserve saturated colors + float opacity = ctOpacityCurve.lutOpacityCurve[l_*500.f]/4.f; + + float r2, g2, b2; + ctColorCurve.getVal(l_, r2, g2, b2); // get the color from the color curve + + float h2, s2, l2; + Color::rgb2hsl(r2,g2,b2,h2,s2,l2); // transform this new color to hsl + + Color::hsl2rgb(h2, s2, l, r2, g2, b2); + + tmpImage->r(i,j)= r+(r2-r)*opacity; + tmpImage->g(i,j) = g+(g2-g)*opacity; + tmpImage->b(i,j)= b+(b2-b)*opacity; + } + } + } + } + // filling the pipette buffer by the content of the temp pipette buffers + // due to optimization, we have to test now if the pipette has been filled in the second tile loop, by + // testing editID + /*if (editImgFloat) { + for (int i=istart,ti=0; ir(i,j) = editIFloatTmpR[ti*TS+tj]; + editImgFloat->g(i,j) = editIFloatTmpG[ti*TS+tj]; + editImgFloat->b(i,j) = editIFloatTmpB[ti*TS+tj]; + } + } + else*/ + /* + if (editWhatever && (editID==EUID_BlackWhiteAfterCurve)) { + for (int i=istart,ti=0; iv(i,j) = editWhateverTmp[ti*TS+tj]; + } + } +*/ + + // ready, fill lab (has to be the same code than the "fill lab" above!) + +#ifdef _OPENMP +#pragma omp parallel for schedule(dynamic, 5) +#endif + for (int i=0; ir(i,j); + float g = tmpImage->g(i,j); + float b = tmpImage->b(i,j); + + float x = toxyz[0][0] * r + toxyz[0][1] * g + toxyz[0][2] * b; + float y = toxyz[1][0] * r + toxyz[1][1] * g + toxyz[1][2] * b; + float z = toxyz[2][0] * r + toxyz[2][1] * g + toxyz[2][2] * b; + + float fx,fy,fz; + + fx = (x<65535.0f ? cachef[std::max(x,0.f)] : (327.68f*float(exp(log(x/MAXVALF)/3.0f )))); + fy = (y<65535.0f ? cachef[std::max(y,0.f)] : (327.68f*float(exp(log(y/MAXVALF)/3.0f )))); + fz = (z<65535.0f ? cachef[std::max(z,0.f)] : (327.68f*float(exp(log(z/MAXVALF)/3.0f )))); + + lab->L[i][j] = (116.0f * fy - 5242.88f); //5242.88=16.0*327.68; + lab->a[i][j] = (500.0f * (fx - fy) ); + lab->b[i][j] = (200.0f * (fy - fz) ); + + + //test for color accuracy + /*float fy = (0.00862069 * lab->L[i][j])/327.68 + 0.137932; // (L+16)/116 + float fx = (0.002 * lab->a[i][j])/327.68 + fy; + float fz = fy - (0.005 * lab->b[i][j])/327.68; + + float x_ = 65535*Lab2xyz(fx)*Color::D50x; + float y_ = 65535*Lab2xyz(fy); + float z_ = 65535*Lab2xyz(fz)*Color::D50z; + + int R,G,B; + xyz2srgb(x_,y_,z_,R,G,B); + r=(float)R; g=(float)G; b=(float)B; + float xxx=1;*/ + + } + } + + + if(tmpImage) + delete tmpImage; + } + if (hCurveEnabled) delete hCurve; + if (sCurveEnabled) delete sCurve; + if (vCurveEnabled) delete vCurve; +} + +/** +* @brief retreave RGB value with maximum saturation +* @param r red input and in exit new r +* @param g green input and in exit new g +* @param b blue input and in exit new b +**/ +void ImProcFunctions::retreavergb (float &r, float &g, float &b) { + float mini = min(r,g,b); + float maxi = max(r,g,b); + float kkm=65535.f/maxi; + if(b==mini && r==maxi) {r=65535.f;g=kkm*(g-b);b=0.f;} + else if(b==mini && g==maxi) {g=65535.f;r=kkm*(r-b);b=0.f;} + else if(g==mini && r==maxi) {r=65535.f;b=kkm*(b-g);g=0.f;} + else if(g==mini && b==maxi) {b=65535.f;r=kkm*(r-g);g=0.f;} + else if(r==mini && b==maxi) {b=65535.f;g=kkm*(g-r);r=0.f;} + else if(r==mini && g==maxi) {g=65535.f;b=kkm*(b-r);r=0.f;} +} + +/** +* @brief Interpolate by decreasing with a parabol k = aa*v*v + bb*v +c v[0..1] +* @param reducac val ue of the reduction in the middle of the range +* @param vinf value [0..1] for beginning decrease +* @param aa second degree parameter +* @param bb first degree parameter +* @param cc third parameter +**/ +void ImProcFunctions::secondeg_end (float reducac, float vinf, float &aa, float &bb, float &cc) { + float zrd=reducac;//value at me linear =0.5 + float v0=vinf;//max shadows + float me=(1.f + v0)/2.f;//"median" value = (v0 + 1.=/2) + //float a1=1.f-v0; + float a2=me-v0; + float a3=1.f-v0*v0; + float a4=me*me-v0*v0; + aa = (1.f + (zrd-1.f)*(1-v0)/a2)/(a4*(1.f-v0)/a2 - a3); + bb = -(1.f + a3*aa)/(1.f-v0); + cc = - (aa +bb); +} + +/** +* @brief Interpolate by increasing with a parabol k = aa*v*v + bb*v v[0..1] +* @param reducac val ue of the reduction in the middle of the range +* @param vend value [0..1] for beginning increase +* @param aa second degree parameter +* @param bb first degree parameter +**/ +void ImProcFunctions::secondeg_begin (float reducac, float vend, float &aam, float &bbm) { + float zrmd=reducac;//linear = 0.5 + float v0m=vend; + float mem=vend/2.f;//(0. + 0.8)/2.f + aam=(1.f-zrmd*v0m/mem)/(v0m*v0m-mem*v0m);// + bbm=(1.f-aam*v0m*v0m)/v0m; +} + + +/** +* @brief color toning with 9 sliders shadows middletones highlight +* @param r red input values [0..65535] +* @param g green input values [0..65535] +* @param b blue input values [0..65535] +* @param ro red output values [0..65535] +* @param go green output values [0..65535] +* @param bo blue output values [0..65535] +* @param RedLow [0..1] value after transformations of sliders [-100..100] for shadows +* @param GreenLow [0..1] value after transformations of sliders [-100..100] for shadows +* @param BlueLow [0..1] value after transformations of sliders [-100..100] for shadows +* @param RedMed [0..1] value after transformations of sliders [-100..100] for midtones +* @param GreenMed [0..1] value after transformations of sliders [-100..100] for midtones +* @param BlueMed [0..1] value after transformations of sliders [-100..100] for midtones +* @param RedHigh [0..1] value after transformations of sliders [-100..100] for highlights +* @param GreenHigh [0..1] value after transformations of sliders [-100..100] for highlights +* @param BlueHigh [0..1] value after transformations of sliders [-100..100] for highlights +* @param reducac value of the reduction in the middle of the range for second degree increse or decrease action +* @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) { + float bmu = mode==1 ? 0.5f : 0.4f; + float RedL = 1.f + (RedLow -1.f)*0.4f; + float GreenL = 1.f + (GreenLow-1.f)*0.4f; + float BlueL = 1.f + (BlueLow -1.f)*bmu; + float h,s,v; + Color::rgb2hsv(r, g, b, h, s, v); + float ksat=1.f; + float ksatlow=1.f; +// float s_0=0.55f; +// float s_1=0.85f; + /* + if(mode==0) {//color + if(s < s_0) ksat=SQR((1.f/s_0)*s); + if(s > s_1) ksat=SQR((1.f/(s_1-1.f))*s - (1.f/(s_1-1.f))); + } + */ + ksat=1.f; + float kl=1.f; + float rlo=1.f;//0.4 0.5 + float rlm=1.5f;//1.1 + float rlh=2.2f;//1.1 + float rlob=bmu;//for BW old mode + + if(mode==0){//color + rlo*=pow_F(strProtect,0.4f);//0.5 ==> 0.75 + rlh*=pow_F(strProtect,0.4f); + rlm*=pow_F(strProtect,0.4f); + } + else {//bw coefficient to preserve same results as before for satlimtopacity = 0.5 (default) + rlo=strProtect*0.8f;//0.4 + rlob=strProtect;//0.5 + rlm=strProtect*2.2f;//1.1 + rlh=strProtect*2.4f;//1.2 + } + if(mode==0) rlob=rlo; + + //second degree + float aa,bb,cc; + float v0=0.15f; + //fixed value of reducac=0.3 + //secondeg_end (reducac, v0, aa, bb, cc); + if(mode==1) { + reducac=0.5f;//black and white mode + if(v > 0.15f) + kl =(-1.f/0.85f)*v + (1.f)/0.85f;//Low light ==> decrease action after v=0.15 + } + else { //color + secondeg_end (reducac, v0, aa, bb, cc); + float aab,bbb; + secondeg_begin (0.7f, v0, aab, bbb); + + if(v > v0) kl=aa*v*v+bb*v+cc;//verified ==> exact + else if (mode==0) kl=aab*v*v+bbb*v;//ksatlow=ksat; + } + + if(RedLow !=1.f) { + RedL = 1.f + (RedLow-1.f) * kl * ksat * rlo; //0.4 + if(RedLow >= 1.f) { + g -= 20000.f*(RedL-1.f) * ksatlow; + b -= 20000.f*(RedL-1.f) * ksatlow; + } + else { + r += 20000.f*(RedL-1.f) * ksatlow; + } + r=CLIP(r); + g=CLIP(g); + b=CLIP(b); + } + + if(GreenLow !=1.f) { + GreenL = 1.f + (GreenLow-1.f) * kl * ksat * rlo; //0.4 + if(GreenLow >= 1.f) { + r -= 20000.f*(GreenL-1.f) * ksatlow; + b -= 20000.f*(GreenL-1.f) * ksatlow; + } + else { + g += 20000.f*(GreenL-1.f) * ksatlow; + } + + r=CLIP(r); + b=CLIP(b); + g=CLIP(g); + } + + if(BlueLow !=1.f) { + BlueL = 1.f + (BlueLow-1.f) * kl * ksat * rlob; + if(BlueLow >= 1.f) { + r -= 20000.f*(BlueL-1.f) * ksatlow; + g -= 20000.f*(BlueL-1.f) * ksatlow; + } + else { + b += 20000.f*(BlueL-1.f)* ksatlow; + } + + r=CLIP(r); + g=CLIP(g); + b=CLIP(b); + } + // mid tones + float km; + float v0m=0.5f;//max action + float v0mm=0.5f;//max + + if(v= 1.f) { + r += 20000.f*(RedM-1.f); + g -= 10000.f*(RedM-1.f); + b -= 10000.f*(RedM-1.f); + r=CLIP(r); + g=CLIP(g); + b=CLIP(b); + } + else { + r += 10000.f*(RedM-1.f); + g -= 20000.f*(RedM-1.f); + b -= 20000.f*(RedM-1.f); + r=CLIP(r); + g=CLIP(g); + b=CLIP(b); + } + } + + float GreenM = 1.f + (GreenMed-1.f)*rlm; + if(GreenMed !=1.f) { + GreenM = 1.f + (GreenMed-1.f) * km * rlm; + if(GreenMed >= 1.f) { + r -= 10000.f*(GreenM-1.f); + g += 20000.f*(GreenM-1.f); + b -= 10000.f*(GreenM-1.f); + r=CLIP(r); + g=CLIP(g); + b=CLIP(b); + } + else { + r -= 20000.f*(GreenM-1.f); + g += 10000.f*(GreenM-1.f); + b -= 20000.f*(GreenM-1.f); + r=CLIP(r); + g=CLIP(g); + b=CLIP(b); + } + } + + float BlueM = 1.f + (BlueMed-1.f)*rlm; + if(BlueMed !=1.f) { + BlueM = 1.f + (BlueMed-1.f) * km * rlm; + if(BlueMed >= 1.f) { + r -= 10000.f*(BlueM-1.f); + g -= 10000.f*(BlueM-1.f); + b += 20000.f*(BlueM-1.f); + r=CLIP(r); + g=CLIP(g); + b=CLIP(b); + } + else { + r -= 20000.f*(BlueM-1.f); + g -= 20000.f*(BlueM-1.f); + b += 10000.f*(BlueM-1.f); + r=CLIP(r); + g=CLIP(g); + b=CLIP(b); + } + } + + //high tones + float kh; + kh=1.f; + float v00=0.8f;//max action + float aa0, bb0; + secondeg_begin (reducac, v00, aa0, bb0); +// float hmu=1.5f; +// if(mode==1) hmu=1.2f;//for BW old mode + + if(v > v00) { kh =(-1.f/(1.f-v00))*v + (1.f)/(1.f-v00); }//High tones + else kh=aa0*v*v+bb0*v;//verification = good + + float RedH=1.f + (RedHigh-1.f)*rlh; + float GreenH=1.f + (GreenHigh-1.f)*rlh; + float BlueH=1.f + (BlueHigh-1.f)*rlh;//1.2 + if(RedHigh !=1.f) { + RedH = 1.f + (RedHigh-1.f) * kh * rlh; //1.2 + if(RedHigh >= 1.f) { + r += 20000.f*(RedH-1.f); + r=CLIP(r); + } + else { + g -= 20000.f*(RedH-1.f); + b -= 20000.f*(RedH-1.f); + } + g=CLIP(g); + b=CLIP(b); + } + if(GreenHigh !=1.f) { + GreenH = 1.f + (GreenHigh-1.f) * kh * rlh; //1.2 + if(GreenHigh >= 1.f) { + g += 20000.f*(GreenH-1.f); + g=CLIP(g); + } + else { + r -= 20000.f*(GreenH-1.f); + b -= 20000.f*(GreenH-1.f); + } + r=CLIP(r); + b=CLIP(b); + } + if(BlueHigh !=1.f) { + BlueH = 1.f + (BlueHigh-1.f) * kh * rlh; //1.2 + if(BlueHigh >= 1.f) { + b += 20000.f*(BlueH-1.f); + b=CLIP(b); + } + else { + r -= 20000.f*(BlueH-1.f); + g -= 20000.f*(BlueH-1.f); + } + r=CLIP(r); + g=CLIP(g); + } + + ro=r; + go=g; + bo=b; +} + +/** +* @brief color toning with 2 colors - 2 sliders saturation shadows and highlight and one balance +* @param r g b input values [0..65535] +* @param ro go bo output values [0..65535] +* @param iplow iphigh [0..1] from curve color - value of luminance shadows and highlights +* @param rl gl bl [0..65535] - color of reference shadow +* @param rh gh bh [0..65535] - color of reference highlight +* @param SatLow SatHigh [0..1] from sliders saturation shadows and highlight +* @param balanS [0..1] balance for shadows (one slider) +* @param balanH [0..1] balance for highlights (same slider than for balanS) +* @param reducac value of the reduction in the middle of the range for second degree, increase or decrease action +**/ +void ImProcFunctions::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) { + float lumbefore=0.299f*r + 0.587f*g + 0.114f*b; + float h,s,l; + Color::rgb2hsl(r,g,b,h,s,l); + float v; + Color::rgb2hsv(r, g, b, h, s, v); + float ksat=1.f; + float ksatlow=1.f; + float s_0=0.55f; + float s_1=0.85f; +/* + if(mode==0) {//color + if(s < s_0) ksat=SQR((1.f/s_0)*s); + if(s > s_1) ksat=SQR((1.f/(s_1-1.f))*s - (1.f/(s_1-1.f))); + } + */ + ksat=1.f; + float kl=1.f; + float rlo=1.f; + float rlh=2.2f; + rlo*=pow_F(strProtect,0.4f);//0.5 ==> 0.75 transfered value for more action + rlh*=pow_F(strProtect,0.4f); + //low tones + //second degree + float aa, bb, cc; + //fixed value of reducac =0.4; + secondeg_end (reducac, iplow, aa, bb, cc); + float aab, bbb, ccb; + + secondeg_begin (0.7f, iplow, aab, bbb); + + if(v > iplow) kl=aa*v*v+bb*v+cc; + else if (mode==0) kl=aab*v*v+bbb*v; + + //rl gl bl + float RedL, GreenL, BlueL; + float krl=rl/(rl+gl+bl); + float kgl=gl/(rl+gl+bl); + float kbl=bl/(rl+gl+bl); + + if(SatLow > 0.f) { + float kmgb; + if(g<20000.f || b < 20000.f || r < 20000.f) { kmgb=min(r,g,b);kl *= pow((kmgb/20000.f),0.85f); } //I have tested ...0.85 compromise... + RedL = 1.f + (SatLow*krl) * kl * ksat * rlo * balanS; //0.4 + if(krl > 0.f) { + g -= 20000.f*(RedL-1.f) * ksatlow; + b -= 20000.f*(RedL-1.f) * ksatlow; + } + g=CLIP(g); + b=CLIP(b); + + GreenL = 1.f + (SatLow*kgl) * kl * ksat * rlo * balanS; //0.4 + if(kgl > 0.f) { + r -= 20000.f*(GreenL-1.f) * ksatlow; + b -= 20000.f*(GreenL-1.f) * ksatlow; + } + r=CLIP(r); + b=CLIP(b); + + BlueL = 1.f + (SatLow*kbl) * kl * ksat * rlo * balanS; //0.4 + if(kbl > 0.f) { + r -= 20000.f*(BlueL-1.f) * ksatlow; + g -= 20000.f*(BlueL-1.f) * ksatlow; + } + r=CLIP(r); + g=CLIP(g); + } + + //high tones + float kh=1.f; + kh=1.f; + float aa0, bb0; + //fixed value of reducac ==0.4; + secondeg_begin (reducac, iphigh, aa0, bb0); + + if(v > iphigh) { kh =(-1.f/(1.f-iphigh))*v + (1.f)/(1.f-iphigh); } //Low light ==> decrease action after iplow + else kh=aa0*v*v+bb0*v; + float kmgb; + if(g>45535.f || b > 45535.f || r > 45535.f) { + kmgb=max(r,g,b); + float cora=1.f/(45535.f-65535.f); + float corb=1.f-cora*45535.f; + float cor=kmgb*cora+corb; + kh *= cor; + /* best algo if necessary with non linear response...little differences and more time! + float aa=1.f /(pow(45535.f,0.65f) - pow(65535.f,0.65f)); + float bb=1.f-aa*pow(45535.f,0.65f); + float cor=aa*pow(kmbg,0.65f)+bb; + kh*=cor;*/ + } + + float RedH, GreenH, BlueH; + float krh=rh/(rh+gh+bh); + float kgh=gh/(rh+gh+bh); + float kbh=bh/(rh+gh+bh); + if(SatHigh > 0.f) { + RedH = 1.f + (SatHigh*krh) * kh * rlh * balanH; //1.2 + if(krh > 0.f) { + r += 20000.f*(RedH-1.f); + r=CLIP(r); + } + g=CLIP(g); + b=CLIP(b); + + GreenH = 1.f + (SatHigh*kgh) * kh * rlh * balanH; //1.2 + if(kgh> 0.f) { + g += 20000.f*(GreenH-1.f); + g=CLIP(g); + } + r=CLIP(r); + b=CLIP(b); + BlueH = 1.f + (SatHigh*kbh) * kh * rlh * balanH; //1.2 + if(kbh > 0.f) { + b += 20000.f*(BlueH-1.f); + b=CLIP(b); + } + r=CLIP(r); + g=CLIP(g); + } + float lumafter=0.299f*r + 0.587f*g + 0.114f*b; + float preserv=1.f; + if(preser==1) preserv=lumbefore/lumafter; + + //float preserv=lumbefore/lumafter; + ro=r; + go=g; + bo=b; + ro*=preserv; + go*=preserv; + bo*=preserv; + ro=CLIP(ro); + go=CLIP(go); + bo=CLIP(bo); +} + +/** +* @brief color toning with interpolation in mode Lab +* @param r g b input values [0..65535] +* @param ro go bo output values [0..65535] +* @param algm metchrom twoc - methods +* @param ctColorCurve curve 500 colors +* @param ctOpacityCurve curve standard 'ab' +* @param clToningcurve curve special 'ab' and 'a' +* @param cl2Toningcurve curve special 'b' +* @param iplow iphigh [0..1] luminance +* @param wp wip 3x3 matrix and inverse conversion rgb XYZ +**/ +void ImProcFunctions::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] ) { + float realL; + float h,s,l; + Color::rgb2hsl(r,g,b,h,s,l); + float x2, y2, z2; + float xl, yl, zl; + + if(twoc!=1) { + l = (Color::gammatab_13_2[ l*65535.f])/65535.f;//to compensate L from Lab + iphigh = (Color::gammatab_13_2[iphigh*65535.f])/65535.f; + iplow = (Color::gammatab_13_2[ iplow*65535.f])/65535.f; + } + + if(twoc==1) { + ctColorCurve.getVal(l, x2, y2, z2); + } + else { + ctColorCurve.getVal(iphigh, x2, y2, z2); + ctColorCurve.getVal(iplow, xl, yl, zl); + } + realL=l; + + + //float opacity = ctOpacityCurve.lutOpacityCurve[l*500.f]; + //if(params->blackwhite.enabled){satLimit=80.f;satLimitOpacity=30.f;}//force BW + + // get the opacity and tweak it to preserve saturated colors + //float l_ = Color::gamma_srgb(l*65535.f)/65535.f; + float opacity; + opacity = (1.f-min(s/satLimit, 1.f)*(1.f-satLimitOpacity)) * ctOpacityCurve.lutOpacityCurve[l*500.f]; + 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; + if (clToningcurve[lm*65535.f]/(lm*65535.f) < 1.f) + {chromat = (clToningcurve[(lm)*65535.f]/(lm*65535.f))-1.f;} //special effect + else + {chromat = 1.f-SQR(SQR((lm*65535.f)/clToningcurve[(lm)*65535.f]));} //apply C=f(L) acts on 'a' and 'b' + + if (cl2Toningcurve[lm*65535.f]/(lm*65535.f) < 1.f) + {luma = (cl2Toningcurve[(lm)*65535.f]/(lm*65535.f))-1.f;} //special effect + else + {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); + 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); +} + + +void ImProcFunctions::luminanceCurve (LabImage* lold, LabImage* lnew, LUTf & curve) { + + int W = lold->W; + int H = lold->H; + +#pragma omp parallel for if (multiThread) + for (int i=0; iL[i][j]; + //if (Lin>0 && Lin<65535) + lnew->L[i][j] = curve[Lin]; + } +} + + + +SSEFUNCTION void ImProcFunctions::chromiLuminanceCurve (EditBuffer *editBuffer, int pW, LabImage* lold, LabImage* lnew, LUTf & acurve, LUTf & bcurve, LUTf & satcurve,LUTf & lhskcurve, LUTf & clcurve, LUTf & curve, bool utili, bool autili, bool butili, bool ccutili, bool cclutili, bool clcutili, LUTu &histCCurve, LUTu &histCLurve, LUTu &histLLCurve, LUTu &histLCurve) { + int W = lold->W; + int H = lold->H; + // lhskcurve.dump("lh_curve"); + //init Flatcurve for C=f(H) + + // NOTE: We're getting all 3 pointers here, but this function may not need them all, so one could optimize this + Imagefloat* editImgFloat = NULL; + LabImage* editLab = NULL; + PlanarWhateverData* editWhatever = NULL; + EditUniqueID editID = EUID_None; + bool editPipette = false; + if (editBuffer) { + editID = editBuffer->getEditID(); + if (editID != EUID_None) { + editPipette = true; + switch (editBuffer->getDataProvider()->getCurrSubscriber()->getEditBufferType()) { + case (BT_IMAGEFLOAT): + editImgFloat = editBuffer->getImgFloatBuffer(); + break; + case (BT_LABIMAGE): + editLab = editBuffer->getLabBuffer(); + break; + case (BT_SINGLEPLANE_FLOAT): + editWhatever = editBuffer->getSinglePlaneBuffer(); + break; + } + } + } + + FlatCurve* chCurve = NULL;// curve C=f(H) + bool chutili = false; + if (params->labCurve.chromaticity > -100) { + chCurve = new FlatCurve(params->labCurve.chcurve); + if (!chCurve || chCurve->isIdentity()) { + if (chCurve) { + delete chCurve; + chCurve = NULL; + } + }//do not use "Munsell" if Chcurve not used + else + chutili=true; + } + FlatCurve* lhCurve = NULL;//curve L=f(H) + bool lhutili = false; + if (params->labCurve.chromaticity > -100) { + lhCurve = new FlatCurve(params->labCurve.lhcurve); + if (!lhCurve || lhCurve->isIdentity()) { + if (lhCurve) { + delete lhCurve; + lhCurve = NULL; + } + }//do not use "Munsell" if Chcurve not used + else + lhutili=true; + } + + FlatCurve* hhCurve = NULL;//curve H=f(H) + bool hhutili = false; + if (params->labCurve.chromaticity > -100) { + hhCurve = new FlatCurve(params->labCurve.hhcurve); + if (!hhCurve || hhCurve->isIdentity()) { + if (hhCurve) { + delete hhCurve; + hhCurve = NULL; + } + }//do not use "Munsell" if Chcurve not used + else + hhutili = true; + } + + LUTf dCcurve; + LUTf dLcurve; + + LUTu hist16Clad; + LUTu hist16Llad; + + //preparate for histograms CIECAM + if(pW!=1){//only with improccoordinator + dCcurve(48000,0); + dLcurve(65536,0); + hist16Clad(65536); + hist16Llad(65536); + float val; + for (int i=0; i<48000; i++) { //# 32768*1.414 approximation maxi for chroma + val = (double)i / 47999.0; + dCcurve[i] = CLIPD(val); + } + for (int i=0; i<65535; i++) { // a + val = (double)i / 65534.0; + dLcurve[i] = CLIPD(val); + } + + hist16Clad.clear(); + hist16Llad.clear(); + + } +#ifdef _DEBUG + MyTime t1e,t2e; + t1e.set(); + // init variables to display Munsell corrections + MunsellDebugInfo* MunsDebugInfo = new MunsellDebugInfo(); +#endif + + float adjustr=1.0f; + +// if(params->labCurve.avoidclip ){ + // parameter to adapt curve C=f(C) to gamut + + if (params->icm.working=="ProPhoto") {adjustr = 1.2f;}// 1.2 instead 1.0 because it's very rare to have C>170.. + else if (params->icm.working=="Adobe RGB") {adjustr = 1.8f;} + else if (params->icm.working=="sRGB") {adjustr = 2.0f;} + else if (params->icm.working=="WideGamut") {adjustr = 1.2f;} + else if (params->icm.working=="Beta RGB") {adjustr = 1.4f;} + else if (params->icm.working=="BestRGB") {adjustr = 1.4f;} + else if (params->icm.working=="BruceRGB") {adjustr = 1.8f;} + + // reference to the params structure has to be done outside of the parallelization to avoid CPU cache problem + const bool highlight = params->toneCurve.hrenabled; //Get the value if "highlight reconstruction" is activated + const int chromaticity = params->labCurve.chromaticity; + const float chromapro = (chromaticity + 100.0f)/100.0f; + const bool bwonly = params->blackwhite.enabled && !params->colorToning.enabled; + const bool bwToning = params->labCurve.chromaticity ==- 100 /*|| params->blackwhite.method=="Ch" || params->blackwhite.enabled */ || bwonly; + //if(chromaticity==-100) chromaticity==-99; + const bool LCredsk = params->labCurve.lcredsk; + const bool ccut = ccutili; + const bool clut = clcutili; + const double rstprotection = 100.-params->labCurve.rstprotection; // Red and Skin Tones Protection + // avoid color shift is disabled when bwToning is activated and enabled if gamut is true in colorappearanace + const bool avoidColorShift = (params->labCurve.avoidcolorshift || (params->colorappearance.gamut && params->colorappearance.enabled)) && !bwToning ; + const float protectRed = (float)settings->protectred; + const double protectRedH = settings->protectredh; + float protect_red,protect_redh; + protect_red = protectRed;//default=60 chroma: one can put more or less if necessary...in 'option' 40...160 + if(protect_red < 20.0f) protect_red=20.0; // avoid too low value + if(protect_red > 180.0f) protect_red=180.0; // avoid too high value + protect_redh=float(protectRedH);//default=0.4 rad : one can put more or less if necessary...in 'option' 0.2 ..1.0 + if(protect_redh<0.1f) protect_redh=0.1f;//avoid divide by 0 and negatives values + if(protect_redh>1.0f) protect_redh=1.0f;//avoid too big values + float protect_redhcur = protectRedH;//default=0.4 rad : one can put more or less if necessary...in 'option' 0.2 ..1 + if(protect_redhcur<0.1f) protect_redhcur=0.1f;//avoid divide by 0 and negatives values:minimal protection for transition + if(protect_redhcur>3.5f) protect_redhcur=3.5f;//avoid too big values + + //increase saturation after denoise : ...approximation + float factnoise=1.f; + if(params->dirpyrDenoise.enabled) { + factnoise=(1.f+params->dirpyrDenoise.chroma/500.f);//levels=5 +// if(yyyy) factnoise=(1.f+params->dirpyrDenoise.chroma/100.f);//levels=7 + } + const float scaleConst = 100.0f/100.1f; + + + const bool gamutLch = settings->gamutLch; + const float amountchroma = (float) settings->amchroma; + + TMatrix wiprof = iccStore->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]} + }; + + TMatrix wprof = iccStore->workingSpaceMatrix (params->icm.working); + double wp[3][3] = { + {wprof[0][0],wprof[0][1],wprof[0][2]}, + {wprof[1][0],wprof[1][1],wprof[1][2]}, + {wprof[2][0],wprof[2][1],wprof[2][2]}}; + +#ifdef _DEBUG +#pragma omp parallel default(shared) firstprivate(highlight, ccut, clut, chromaticity, bwToning, rstprotection, avoidColorShift, LCredsk, protectRed, protectRedH, gamutLch, lold, lnew, MunsDebugInfo, pW) if (multiThread) +#else +#pragma omp parallel if (multiThread) +#endif +{ +#ifdef __SSE2__ + float HHBuffer[W] ALIGNED16; + float CCBuffer[W] ALIGNED16; +#endif +#pragma omp for schedule(dynamic, 16) + for (int i=0; iL[i],lold->a[i], lold->b[i], W, /*corMunsell*/true, /*lumaMuns*/false, params->toneCurve.hrenabled, /*gamut*/true, wip, multiThread); + } +#ifdef __SSE2__ + // precalculate some values using SSE + if(bwToning || (!autili && !butili)) { + __m128 c327d68v = _mm_set1_ps(327.68f); + __m128 av,bv; + int k; + for (k=0; ka[i][k]); + bv = LVFU(lold->b[i][k]); + STVF(HHBuffer[k],xatan2f(bv,av)); + STVF(CCBuffer[k],_mm_sqrt_ps(SQRV(av)+SQRV(bv))/c327d68v); + } + for(;kb[i][k],lold->a[i][k]); + CCBuffer[k] = sqrt(SQR(lold->a[i][k]) + SQR(lold->b[i][k]))/327.68f; + } + } +#endif // __SSE2__ + for (int j=0; jL[i][j]; + float LL=Lin/327.68f; + float CC; + float HH; + float Chprov; + float Chprov1; + float memChprov; + float2 sincosval; + if(bwToning) { // this values will be also set when bwToning is false some lines down +#ifdef __SSE2__ + // use precalculated values from above + HH = HHBuffer[j]; + CC = CCBuffer[j]; +#else + HH=xatan2f(lold->b[i][j],lold->a[i][j]); + CC=sqrt(SQR(lold->a[i][j]) + SQR(lold->b[i][j]))/327.68f; +#endif + // According to mathematical laws we can get the sin and cos of HH by simple operations + if(CC==0.0f) { + sincosval.y = 1.0f; + sincosval.x = 0.0f; + } else { + sincosval.y = lold->a[i][j]/(CC*327.68f); + sincosval.x = lold->b[i][j]/(CC*327.68f); + } + + Chprov=CC; + Chprov1=CC; + memChprov=Chprov; + } + + if (editPipette && editID == EUID_Lab_LCurve) + editWhatever->v(i,j) = LIM01(Lin/32768.0f);// Lab L pipette + + lnew->L[i][j] = curve[Lin]; + + float Lprov1=(lnew->L[i][j])/327.68f; + + if(editPipette) { + if (editID == EUID_Lab_aCurve) { // Lab a pipette + float chromapipa =lold->a[i][j]+(32768.f*1.28f); + editWhatever->v(i,j) = LIM01((chromapipa)/(65536.f*1.28f)); + } else if (editID == EUID_Lab_bCurve) { //Lab b pipette + float chromapipb =lold->b[i][j]+(32768.f*1.28f); + editWhatever->v(i,j) = LIM01((chromapipb)/(65536.f*1.28f)); + } + } + + float atmp, btmp; + + atmp = lold->a[i][j]; + if(autili) + atmp = acurve[atmp+32768.0f]-32768.0f;// curves Lab a + + btmp = lold->b[i][j]; + if(butili) + btmp = bcurve[btmp+32768.0f]-32768.0f;// curves Lab b + + if(!bwToning) { //take into account modification of 'a' and 'b' +#ifdef __SSE2__ + if(!autili && !butili) { + // use precalculated values from above + HH = HHBuffer[j]; + CC = CCBuffer[j]; + } else { + CC = sqrt(SQR(atmp) + SQR(btmp))/327.68f; + HH = xatan2f(btmp,atmp); + } +#else + CC=sqrt(SQR(atmp) + SQR(btmp))/327.68f; + HH=xatan2f(btmp,atmp); +#endif + // According to mathematical laws we can get the sin and cos of HH by simple operations + //float2 sincosval; + if(CC == 0.f) { + sincosval.y = 1.f; + sincosval.x = 0.f; + } else { + sincosval.y = atmp/(CC*327.68f); + sincosval.x = btmp/(CC*327.68f); + } + Chprov=CC; + Chprov1=CC; + memChprov=Chprov; + } // now new values of lold with 'a' and 'b' + + if(editPipette) + if (editID == EUID_Lab_LHCurve || editID == EUID_Lab_CHCurve || editID == EUID_Lab_HHCurve) {//H pipette + float valpar =Color::huelab_to_huehsv2(HH); + editWhatever->v(i,j) = valpar; + } + + if (lhutili) { // L=f(H) + const float ClipLevel = 65535.f; + float l_r;//Luminance Lab in 0..1 + l_r = Lprov1/100.f; + { + float khue=1.9f;//in reserve in case of! + float valparam = float((lhCurve->getVal(Color::huelab_to_huehsv2(HH))-0.5f));//get l_r=f(H) + float valparamneg; + valparamneg=valparam; + float kcc=(CC/amountchroma);//take Chroma into account...40 "middle low" of chromaticity (arbitrary and simple), one can imagine other algorithme + //reduce action for low chroma and increase action for high chroma + valparam *= 2.f*kcc; + valparamneg*= kcc;//slightly different for negative + if(valparam > 0.f) + l_r = (1.f-valparam)*l_r+ valparam*(1.f-SQR(((SQR(1.f-min(l_r,1.0f)))))); + else + //for negative + l_r *= (1.f+khue*valparamneg); + } + + Lprov1=l_r*100.f; + + float Chprov2 = sqrt(SQR(atmp)+SQR(btmp))/327.68f; + //Gamut control especialy fot negative values slightly different of gamutlchonly + bool inRGB; + do { + inRGB=true; + float aprov1=Chprov2*sincosval.y; + float bprov1=Chprov2*sincosval.x; + + float fy = (0.00862069f *Lprov1 )+ 0.137932f; + float fx = (0.002f * aprov1) + fy; + float fz = fy - (0.005f * bprov1); + + float x_ = 65535.0f * Color::f2xyz(fx)*Color::D50x; + float z_ = 65535.0f * Color::f2xyz(fz)*Color::D50z; + float y_=(Lprov1>Color::epskap) ? 65535.0*fy*fy*fy : 65535.0*Lprov1/Color::kappa; + float R,G,B; + Color::xyz2rgb(x_,y_,z_,R,G,B,wip); + if (R<0.0f || G<0.0f || B<0.0f) { + if(Lprov1 < 0.1f) Lprov1=0.1f; + Chprov2*=0.95f; + inRGB=false; + } + else if (!highlight && (R>ClipLevel || G>ClipLevel || B>ClipLevel)) { + if (Lprov1 > 99.98f) Lprov1 = 99.98f; + Chprov2 *= 0.95f; + inRGB = false; + } + } + while (!inRGB); + + atmp=327.68f*Chprov2*sincosval.y; + btmp=327.68f*Chprov2*sincosval.x; + } + +// calculate C=f(H) + if (chutili) { + double hr = Color::huelab_to_huehsv2(HH); + float chparam = float((chCurve->getVal(hr)-0.5f) * 2.0f);//get C=f(H) + float chromaChfactor=1.0f+chparam; + atmp *= chromaChfactor;//apply C=f(H) + btmp *= chromaChfactor; + } + + if (hhutili) { // H=f(H) + //hue Lab in -PI +PI + float valparam = float((hhCurve->getVal(Color::huelab_to_huehsv2(HH))-0.5f) * 1.7f) +HH;//get H=f(H) 1.7 optimisation ! + HH = valparam; + sincosval = xsincosf(HH); + } + + if(!bwToning){ + float factorskin, factorsat, factorskinext; + if(chromapro > 1.f) { + float scale = scaleConst;//reduction in normal zone + float scaleext = 1.f;//reduction in transition zone + Color::scalered ( rstprotection, chromapro, 0.0, HH, protect_redh, scale, scaleext);//1.0 + float interm = (chromapro - 1.f); + factorskin = 1.f + (interm*scale); + factorskinext = 1.f+ (interm*scaleext); + } else { + factorskin = chromapro ; // +(chromapro)*scale; + factorskinext = chromapro ;// +(chromapro)*scaleext; + } + factorsat = chromapro * factnoise; + + //simulate very approximative gamut f(L) : with pyramid transition + float dred /*=55.f*/;//C red value limit + if (Lprov1<25.f) dred = 40.f; + else if(Lprov1<30.f) dred = 3.f * Lprov1 -35.f; + else if(Lprov1<70.f) dred = 55.f; + else if(Lprov1<75.f) dred = -3.f * Lprov1 + 265.f; + else dred = 40.f; + // end pyramid + + // Test if chroma is in the normal range first + Color::transitred ( HH, Chprov1, dred, factorskin, protect_red, factorskinext, protect_redh, factorsat, factorsat); + atmp *= factorsat; + btmp *= factorsat; + + if (editPipette && editID == EUID_Lab_CLCurve) + editWhatever->v(i,j) = LIM01(LL/100.f);// Lab C=f(L) pipette + + if (clut) { // begin C=f(L) + float factorskin,factorsat,factor,factorskinext,interm; + float chromaCfactor=(clcurve[LL*655.35f])/(LL*655.35f);//apply C=f(L) + float curf=0.7f;//empirical coeff because curve is more progressive + float scale = 100.0f/100.1f;//reduction in normal zone for curve C + float scaleext=1.0f;//reduction in transition zone for curve C + float protect_redcur,protect_redhcur;//perhaps the same value than protect_red and protect_redh + float deltaHH;//HH value transition for C curve + protect_redcur=curf*protectRed;//default=60 chroma: one can put more or less if necessary...in 'option' 40...160==> curf =because curve is more progressive + if(protect_redcur < 20.0f) protect_redcur=20.0; // avoid too low value + if(protect_redcur > 180.0f) protect_redcur=180.0; // avoid too high value + protect_redhcur=curf*float(protectRedH);//default=0.4 rad : one can put more or less if necessary...in 'option' 0.2 ..1.0 ==> curf =because curve is more progressive + if(protect_redhcur<0.1f) protect_redhcur=0.1f;//avoid divide by 0 and negatives values + if(protect_redhcur>1.0f) protect_redhcur=1.0f;//avoid too big values + + deltaHH=protect_redhcur;//transition hue + if(chromaCfactor>0.0) Color::scalered ( rstprotection, chromaCfactor, 0.0, HH, deltaHH, scale, scaleext);//1.0 + if(chromaCfactor>1.0) { + interm=(chromaCfactor-1.0f)*100.0f; + factorskin= 1.0f+(interm*scale)/100.0f; + factorskinext=1.0f+(interm*scaleext)/100.0f; + } + else { + factorskin= chromaCfactor; // +(1.0f-chromaCfactor)*scale; + factorskinext= chromaCfactor ; //+(1.0f-chromaCfactor)*scaleext; + } + + factorsat=chromaCfactor; + factor=factorsat; + Color::transitred ( HH, Chprov1, dred, factorskin, protect_redcur, factorskinext, deltaHH, factorsat, factor); + atmp *= factor; + btmp *= factor; + } + // end C=f(L) + // if (editID == EUID_Lab_CLCurve) + // editWhatever->v(i,j) = LIM01(Lprov2/100.f);// Lab C=f(L) pipette + + // I have placed C=f(C) after all C treatments to assure maximum amplitude of "C" + if (editPipette && editID == EUID_Lab_CCurve){ + float chromapip = sqrt(SQR(atmp)+SQR(btmp)+0.001f); + editWhatever->v(i,j) = LIM01((chromapip)/(48000.f));}//Lab C=f(C) pipette + + if (ccut) { + float factorskin,factorsat,factor,factorskinext,interm; + float chroma = sqrt(SQR(atmp)+SQR(btmp)+0.001f); + float chromaCfactor=(satcurve[chroma*adjustr])/(chroma*adjustr);//apply C=f(C) + float curf=0.7f;//empirical coeff because curve is more progressive + float scale = 100.0f/100.1f;//reduction in normal zone for curve CC + float scaleext=1.0f;//reduction in transition zone for curve CC + float protect_redcur,protect_redhcur;//perhaps the same value than protect_red and protect_redh + float deltaHH;//HH value transition for CC curve + protect_redcur=curf*protectRed;//default=60 chroma: one can put more or less if necessary...in 'option' 40...160==> curf =because curve is more progressive + if(protect_redcur < 20.0f) protect_redcur=20.0; // avoid too low value + if(protect_redcur > 180.0f) protect_redcur=180.0; // avoid too high value + protect_redhcur=curf*float(protectRedH);//default=0.4 rad : one can put more or less if necessary...in 'option' 0.2 ..1.0 ==> curf =because curve is more progressive + if(protect_redhcur<0.1f) protect_redhcur=0.1f;//avoid divide by 0 and negatives values + if(protect_redhcur>1.0f) protect_redhcur=1.0f;//avoid too big values + + deltaHH=protect_redhcur;//transition hue + if(chromaCfactor>0.0) Color::scalered ( rstprotection, chromaCfactor, 0.0, HH, deltaHH, scale, scaleext);//1.0 + if(chromaCfactor>1.0) { + interm=(chromaCfactor-1.0f)*100.0f; + factorskin= 1.0f+(interm*scale)/100.0f; + factorskinext=1.0f+(interm*scaleext)/100.0f; + } + else { + //factorskin= chromaCfactor*scale; + //factorskinext=chromaCfactor*scaleext; + factorskin= chromaCfactor; // +(1.0f-chromaCfactor)*scale; + factorskinext= chromaCfactor ; //+(1.0f-chromaCfactor)*scaleext; + + } + + factorsat=chromaCfactor; + factor=factorsat; + Color::transitred ( HH, Chprov1, dred, factorskin, protect_redcur, factorskinext, deltaHH, factorsat, factor); + atmp *= factor; + btmp *= factor; + } + } + // end chroma C=f(C) + + //update histogram C + if(pW!=1){//only with improccoordinator + int posp=CLIP((int)sqrt((atmp*atmp + btmp*btmp))); + hist16Clad[posp]++; + } + + if (editPipette && editID == EUID_Lab_LCCurve){ + float chromapiplc = sqrt(SQR(atmp)+SQR(btmp)+0.001f); + editWhatever->v(i,j) = LIM01((chromapiplc)/(48000.f)); + }//Lab L=f(C) pipette + + + if (cclutili && !bwToning) { //apply curve L=f(C) for skin and rd...but also for extended color ==> near green and blue (see 'curf') + + const float xx=0.25f;//soft : between 0.2 and 0.4 + float skdeltaHH; + + skdeltaHH=protect_redhcur;//transition hue + + float skbeg=-0.05f;//begin hue skin + float skend=1.60f;//end hue skin + const float chrmin=50.0f;//to avoid artifact, because L curve is not a real curve for luminance + float aa,bb; + float zz=0.0f; + float yy=0.0f; + if(Chprov1 < chrmin) + yy=SQR(Chprov1/chrmin)*xx; + else + yy=xx;//avoid artifact for low C + if(!LCredsk) { + skbeg=-3.1415; + skend=3.14159; + skdeltaHH=0.001f; + } + if(HH>skbeg && HH < skend ) { + zz=yy; + } else if(HH>skbeg-skdeltaHH && HH<=skbeg) { //transition + aa=yy/skdeltaHH; + bb=-aa*(skbeg-skdeltaHH); + zz=aa*HH+bb; + } else if(HH>=skend && HH < skend+skdeltaHH) { //transition + aa=-yy/skdeltaHH; + bb=-aa*(skend+skdeltaHH); + zz=aa*HH+bb; + } + + float chroma=sqrt(SQR(atmp)+SQR(btmp)+0.001f); + float Lc = (lhskcurve[chroma*adjustr])/(chroma*adjustr);//apply L=f(C) + Lc=(Lc-1.0f)*zz+1.0f;//reduct action + Lprov1*=Lc;//adjust luminance + } + //update histo LC + if(pW!=1){//only with improccoordinator + int posl=CLIP((int(Lprov1*327.68f))); + hist16Llad[posl]++; + } + + Chprov1 = sqrt(SQR(atmp)+SQR(btmp))/327.68f; + + // labCurve.bwtoning option allows to decouple modulation of a & b curves by saturation + // with bwtoning enabled the net effect of a & b curves is visible + if (bwToning) { + atmp -= lold->a[i][j]; + btmp -= lold->b[i][j]; + } + + if (avoidColorShift) { + //gamutmap Lch ==> preserve Hue,but a little slower than gamutbdy for high values...and little faster for low values + if(gamutLch) { + float R,G,B; + +#ifdef _DEBUG + bool neg=false; + bool more_rgb=false; + //gamut control : Lab values are in gamut + Color::gamutLchonly(HH, sincosval, Lprov1,Chprov1, R, G, B, wip, highlight, 0.15f, 0.96f, neg, more_rgb); +#else + //gamut control : Lab values are in gamut + Color::gamutLchonly(HH, sincosval,Lprov1,Chprov1, R, G, B, wip, highlight, 0.15f, 0.96f); +#endif + lnew->L[i][j]=Lprov1*327.68f; +// float2 sincosval = xsincosf(HH); + lnew->a[i][j]=327.68f*Chprov1*sincosval.y; + lnew->b[i][j]=327.68f*Chprov1*sincosval.x; + } else { + //use gamutbdy + //Luv limiter + float Y,u,v; + Color::Lab2Yuv(lnew->L[i][j],atmp,btmp,Y,u,v); + //Yuv2Lab includes gamut restriction map + Color::Yuv2Lab(Y,u,v,lnew->L[i][j],lnew->a[i][j],lnew->b[i][j], wp); + } + + if (utili || autili || butili || ccut || clut || cclutili || chutili || lhutili || hhutili || clcutili || chromaticity) { + float correctionHue=0.f; // Munsell's correction + float correctlum=0.f; + + Lprov1=lnew->L[i][j]/327.68f; + Chprov=sqrt(SQR(lnew->a[i][j])+ SQR(lnew->b[i][j]))/327.68f; + +#ifdef _DEBUG + Color::AllMunsellLch(/*lumaMuns*/true, Lprov1,LL,HH,Chprov,memChprov,correctionHue,correctlum, MunsDebugInfo); +#else + Color::AllMunsellLch(/*lumaMuns*/true, Lprov1,LL,HH,Chprov,memChprov,correctionHue,correctlum); +#endif + if(correctionHue != 0.f || correctlum != 0.f) { + if(fabs(correctionHue) < 0.015f) + HH+=correctlum; // correct only if correct Munsell chroma very little. + /* if((HH>0.0f && HH < 1.6f) && memChprov < 70.0f) HH+=correctlum;//skin correct + else if(fabs(correctionHue) < 0.3f) HH+=0.08f*correctlum; + else if(fabs(correctionHue) < 0.2f) HH+=0.25f*correctlum; + else if(fabs(correctionHue) < 0.1f) HH+=0.35f*correctlum; + else if(fabs(correctionHue) < 0.015f) HH+=correctlum; // correct only if correct Munsell chroma very little. + */ + sincosval = xsincosf(HH+correctionHue); + } + lnew->a[i][j]=327.68f*Chprov*sincosval.y;// apply Munsell + lnew->b[i][j]=327.68f*Chprov*sincosval.x; + } + } else { +// if(Lprov1 > maxlp) maxlp=Lprov1; +// if(Lprov1 < minlp) minlp=Lprov1; + if(!bwToning){ + lnew->L[i][j]=Lprov1*327.68f; +// float2 sincosval = xsincosf(HH); + lnew->a[i][j]=327.68f*Chprov1*sincosval.y; + lnew->b[i][j]=327.68f*Chprov1*sincosval.x; + } + else { + //Luv limiter only + lnew->a[i][j] = atmp; + lnew->b[i][j] = btmp; + } + } + } + } +} // end of parallelization + + //update histogram C with data chromaticity and not with CC curve + if(pW!=1){//only with improccoordinator + for (int i=0; i<48000; i++) {//32768*1.414 + ... + float hval = dCcurve[i]; + int hi = (int)(255.0*CLIPD(hval)); // + histCCurve[hi] += hist16Clad[i] ; + } + //update histogram L with data luminance + for (int i=0; i<65535; i++) { + float hlval = dLcurve[i]; + int hli = (int)(255.0*CLIPD(hlval)); + histLCurve[hli] += hist16Llad[i] ; + } + } + +#ifdef _DEBUG + if (settings->verbose) { + t2e.set(); + printf("Color::AllMunsellLch (correction performed in %d usec):\n", t2e.etime(t1e)); + printf(" Munsell chrominance: MaxBP=%1.2frad MaxRY=%1.2frad MaxGY=%1.2frad MaxRP=%1.2frad dep=%i\n", MunsDebugInfo->maxdhue[0], MunsDebugInfo->maxdhue[1], MunsDebugInfo->maxdhue[2], MunsDebugInfo->maxdhue[3], MunsDebugInfo->depass); + printf(" Munsell luminance : MaxBP=%1.2frad MaxRY=%1.2frad MaxGY=%1.2frad MaxRP=%1.2frad dep=%i\n", MunsDebugInfo->maxdhuelum[0], MunsDebugInfo->maxdhuelum[1], MunsDebugInfo->maxdhuelum[2], MunsDebugInfo->maxdhuelum[3], MunsDebugInfo->depassLum); + } + delete MunsDebugInfo; +#endif + + if (chCurve) delete chCurve; + if (lhCurve) delete lhCurve; + if (hhCurve) delete hhCurve; + + // t2e.set(); + // printf("Chromil took %d �sec\n",t2e.etime(t1e)); +} + + +//#include "cubic.cc" + +void ImProcFunctions::colorCurve (LabImage* lold, LabImage* lnew) { + +/* LUT cmultiplier(181021); + + double boost_a = ((float)params->colorBoost.amount + 100.0) / 100.0; + double boost_b = ((float)params->colorBoost.amount + 100.0) / 100.0; + + double c, amul = 1.0, bmul = 1.0; + if (boost_a > boost_b) { + c = boost_a; + if (boost_a > 0) + bmul = boost_b / boost_a; + } + else { + c = boost_b; + if (boost_b > 0) + amul = boost_a / boost_b; + } + + if (params->colorBoost.enable_saturationlimiter && c>1.0) { + // re-generate color multiplier lookup table + double d = params->colorBoost.saturationlimit / 3.0; + double alpha = 0.5; + double threshold1 = alpha * d; + double threshold2 = c*d*(alpha+1.0) - d; + for (int i=0; i<=181020; i++) { // lookup table stores multipliers with a 0.25 chrominance resolution + double chrominance = (double)i/4.0; + if (chrominance < threshold1) + cmultiplier[i] = c; + else if (chrominance < d) + cmultiplier[i] = (c / (2.0*d*(alpha-1.0)) * (chrominance-d)*(chrominance-d) + c*d/2.0 * (alpha+1.0) ) / chrominance; + else if (chrominance < threshold2) + cmultiplier[i] = (1.0 / (2.0*d*(c*(alpha+1.0)-2.0)) * (chrominance-d)*(chrominance-d) + c*d/2.0 * (alpha+1.0) ) / chrominance; + else + cmultiplier[i] = 1.0; + } + } + + float eps = 0.001; + double shift_a = params->colorShift.a + eps, shift_b = params->colorShift.b + eps; + + float** oa = lold->a; + float** ob = lold->b; + + #pragma omp parallel for if (multiThread) + for (int i=0; iH; i++) + for (int j=0; jW; j++) { + + double wanted_c = c; + if (params->colorBoost.enable_saturationlimiter && c>1) { + float chroma = (float)(4.0 * sqrt((oa[i][j]+shift_a)*(oa[i][j]+shift_a) + (ob[i][j]+shift_b)*(ob[i][j]+shift_b))); + wanted_c = cmultiplier [chroma]; + } + + double real_c = wanted_c; + if (wanted_c >= 1.0 && params->colorBoost.avoidclip) { + double cclip = 100000.0; + double cr = tightestroot ((double)lnew->L[i][j]/655.35, (double)(oa[i][j]+shift_a)*amul, (double)(ob[i][j]+shift_b)*bmul, 3.079935, -1.5371515, -0.54278342); + double cg = tightestroot ((double)lnew->L[i][j]/655.35, (double)(oa[i][j]+shift_a)*amul, (double)(ob[i][j]+shift_b)*bmul, -0.92123418, 1.87599, 0.04524418); + double cb = tightestroot ((double)lnew->L[i][j]/655.35, (double)(oa[i][j]+shift_a)*amul, (double)(ob[i][j]+shift_b)*bmul, 0.052889682, -0.20404134, 1.15115166); + if (cr>1.0 && cr1.0 && cg1.0 && cba[i][j] = LIM(nna,-32000.0f,32000.0f); + lnew->b[i][j] = LIM(nnb,-32000.0f,32000.0f); + } +*/ + //delete [] cmultiplier; +} + + void ImProcFunctions::impulsedenoise (LabImage* lab) { + + if (params->impulseDenoise.enabled && lab->W>=8 && lab->H>=8) + + impulse_nr (lab, (float)params->impulseDenoise.thresh/20.0 ); + } + + void ImProcFunctions::impulsedenoisecam (CieImage* ncie, float **buffers[3]) { + + if (params->impulseDenoise.enabled && ncie->W>=8 && ncie->H>=8) + + impulse_nrcam (ncie, (float)params->impulseDenoise.thresh/20.0, buffers ); + } + + void ImProcFunctions::defringe (LabImage* lab) { + + if (params->defringe.enabled && lab->W>=8 && lab->H>=8) + + PF_correct_RT(lab, lab, params->defringe.radius, params->defringe.threshold); + } + + void ImProcFunctions::defringecam (CieImage* ncie) { + if (params->defringe.enabled && ncie->W>=8 && ncie->H>=8) + PF_correct_RTcam(ncie, ncie, params->defringe.radius, params->defringe.threshold); + } + + 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){ + if(ncie->W>=8 && ncie->H>=8) Badpixelscam(ncie, ncie, rad, thr, mode, b_l, t_l, t_r,b_r, 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){ + if(lab->W>=8 && lab->H>=8) BadpixelsLab(lab, lab, rad, thr, mode, b_l, t_l, t_r,b_r, skinprot, chrom); + } + + 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; + if(artifact > 6.f) artifact =6.f; + if(artifact <0.f) artifact=1.f; + + 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 + + //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); + } + } +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){ + +if(!params->epd.enabled) return; +if(params->wavelet.enabled && params->wavelet.tmrs!=0) return; + + float stren=params->epd.strength; + float edgest=params->epd.edgeStopping; + float sca=params->epd.scale; + float gamm=params->epd.gamma; + float rew=params->epd.reweightingIterates; + unsigned int i, N = Wid*Hei; + float Qpro= ( 4.0 / c_) * ( a_w + 4.0 ) ;//estimate Q max if J=100.0 + float *Qpr=ncie->Q_p[0]; + if (settings->verbose) + printf("minQ=%f maxQ=%f Qpro=%f\n",minQ,maxQ, Qpro); + if(maxQ>Qpro) + Qpro=maxQ; + + EdgePreservingDecomposition epd = EdgePreservingDecomposition(Wid, Hei); + + #pragma omp parallel for + for (int i=0; iQ_p[i][j] = gamm*ncie->Q_p[i][j]/(Qpro); + + float Compression = expf(-stren); //This modification turns numbers symmetric around 0 into exponents. + float DetailBoost = stren; + if(stren < 0.0f) DetailBoost = 0.0f; //Go with effect of exponent only if uncompressing. + + //Auto select number of iterates. Note that p->EdgeStopping = 0 makes a Gaussian blur. + if(Iterates == 0) Iterates = (unsigned int)(edgest*15.0); + //Jacques Desmis : always Iterates=5 for compatibility images between preview and output + + epd.CompressDynamicRange(Qpr, (float)sca/skip, (float)edgest, Compression, DetailBoost, Iterates, rew, Qpr); + + //Restore past range, also desaturate a bit per Mantiuk's Color correction for tone mapping. + float s = (1.0f + 38.7889f)*powf(Compression, 1.5856f)/(1.0f + 38.7889f*powf(Compression, 1.5856f)); + #ifndef _DEBUG + #pragma omp parallel for schedule(dynamic,10) + #endif + for (int i=0; iQ_p[i][j]=(ncie->Q_p[i][j]*Qpro)/gamm; + ncie->M_p[i][j]*=s; + } +/* + float *Qpr2 = new float[Wid*((heir)+1)]; + + for (int i=heir; iQ_p[i][j];} + if(minQ>0.0) minQ=0.0;//normaly minQ always > 0... +// EdgePreservingDecomposition epd = EdgePreservingDecomposition(Wid, Hei); +//EdgePreservingDecomposition epd = EdgePreservingDecomposition(Wid, Hei/2); + for(i = N2; i != N; i++) +// for(i = begh*Wid; i != N; i++) + //Qpr[i] = (Qpr[i]-minQ)/(maxQ+1.0); + Qpr2[i-N2] = (Qpr2[i-N2]-minQ)/(Qpro+1.0); + + float Compression2 = expf(-stren); //This modification turns numbers symmetric around 0 into exponents. + float DetailBoost2 = stren; + if(stren < 0.0f) DetailBoost2 = 0.0f; //Go with effect of exponent only if uncompressing. + + //Auto select number of iterates. Note that p->EdgeStopping = 0 makes a Gaussian blur. + if(Iterates == 0) Iterates = (unsigned int)(edgest*15.0); + + + epd.CompressDynamicRange(Qpr2, (float)sca/skip, (float)edgest, Compression2, DetailBoost2, Iterates, rew, Qpr2); + + //Restore past range, also desaturate a bit per Mantiuk's Color correction for tone mapping. + float s2 = (1.0f + 38.7889f)*powf(Compression, 1.5856f)/(1.0f + 38.7889f*powf(Compression, 1.5856f)); + for (int i=heir; iQ_p[i][j]=Qpr2[(i-heir)*Wid+j]*Qpro + minQ; + // Qpr[i*Wid+j]=Qpr[i*Wid+j]*maxQ + minQ; + // ncie->J_p[i][j]=(100.0* Qpr[i*Wid+j]*Qpr[i*Wid+j]) /(w_h*w_h); + + ncie->M_p[i][j]*=s2; + } + delete [] Qpr2; + +*/ +} + + +//Map tones by way of edge preserving decomposition. Is this the right way to include source? +//#include "EdgePreservingDecomposition.cc" +void ImProcFunctions::EPDToneMap(LabImage *lab, unsigned int Iterates, int skip){ + //Hasten access to the parameters. +// EPDParams *p = (EPDParams *)(¶ms->epd); + + //Enabled? Leave now if not. +// if(!p->enabled) return; +if(!params->epd.enabled) return; +if(params->wavelet.enabled && params->wavelet.tmrs!=0) return; + +float stren=params->epd.strength; +float edgest=params->epd.edgeStopping; +float sca=params->epd.scale; +float gamm=params->epd.gamma; +float rew=params->epd.reweightingIterates; + //Pointers to whole data and size of it. + float *L = lab->L[0]; + float *a = lab->a[0]; + float *b = lab->b[0]; + unsigned int i, N = lab->W*lab->H; + EdgePreservingDecomposition epd = EdgePreservingDecomposition(lab->W, lab->H); + + //Due to the taking of logarithms, L must be nonnegative. Further, scale to 0 to 1 using nominal range of L, 0 to 15 bit. + float minL = FLT_MAX; + float maxL = 0.f; +#pragma omp parallel +{ + float lminL = FLT_MAX; + float lmaxL = 0.f; +#pragma omp for + for(i = 0; i < N; i++) { + if(L[i] < lminL) lminL = L[i]; + if(L[i] > lmaxL) lmaxL = L[i]; + } +#pragma omp critical + if(lminL < minL) minL = lminL; + if(lmaxL > maxL) maxL = lmaxL; + +} + if(minL > 0.0f) minL = 0.0f; //Disable the shift if there are no negative numbers. I wish there were just no negative numbers to begin with. +#pragma omp parallel for + for(i = 0; i < N; i++) + //{L[i] = (L[i] - minL)/32767.0f; + {L[i] = (L[i] - minL)/maxL; + L[i]*=gamm; + } + //Some interpretations. + float Compression = expf(-stren); //This modification turns numbers symmetric around 0 into exponents. + float DetailBoost = stren; + if(stren < 0.0f) DetailBoost = 0.0f; //Go with effect of exponent only if uncompressing. + + //Auto select number of iterates. Note that p->EdgeStopping = 0 makes a Gaussian blur. + if(Iterates == 0) Iterates = (unsigned int)(edgest*15.0f); + +/* Debuggery. Saves L for toying with outside of RT. +char nm[64]; +sprintf(nm, "%ux%ufloat.bin", lab->W, lab->H); +FILE *f = fopen(nm, "wb"); +fwrite(L, N, sizeof(float), f); +fclose(f);*/ + + epd.CompressDynamicRange(L, sca/float(skip), edgest, Compression, DetailBoost, Iterates, rew, L); + + //Restore past range, also desaturate a bit per Mantiuk's Color correction for tone mapping. + float s = (1.0f + 38.7889f)*powf(Compression, 1.5856f)/(1.0f + 38.7889f*powf(Compression, 1.5856f)); + #ifdef _OPENMP + #pragma omp parallel for // removed schedule(dynamic,10) + #endif + for(int ii = 0; ii < N; ii++) + a[ii] *= s, + b[ii] *= s, + //L[ii] = L[ii]*32767.0f*(1.f/gamm) + minL; + L[ii] = L[ii]*maxL*(1.f/gamm) + minL; +} + + + void ImProcFunctions::getAutoExp (LUTu & histogram, int histcompr, double defgain, double clip, + double& expcomp, int& bright, int& contr, int& black, int& hlcompr, int& hlcomprthresh) { + + float scale = 65536.0f; + float midgray=0.1842f;//middle gray in linear gamma =1 50% luminance + + int imax=65536>>histcompr; + int overex=0; + float sum = 0.f, hisum=0.f, losum=0.f; + float ave = 0.f, hidev=0.f, lodev=0.f; + //find average luminance + for (int i=0; isum/8.f || (count==7 && octile[count]>sum/16.f)) { + octile[count]=log(1.+(float)i)/log(2.f); + count++;// = min(count+1,7); + } + } + if (ilog((float)imax+1.f)/log2(2.f)) {//if very overxposed image + octile[6]=1.5f*octile[5]-0.5f*octile[4]; + overex=2; + } + + if (octile[7]>log((float)imax+1.f)/log2(2.f)) {//if overexposed + octile[7]=1.5f*octile[6]-0.5f*octile[5]; + overex=1; + } + + // store values of octile[6] and octile[7] for calculation of exposure compensation + // if we don't do this and the pixture is underexposed, calculation of exposure compensation assumes + // that it's overexposed and calculates the wrong direction + float oct6,oct7; + oct6 = octile[6]; + oct7 = octile[7]; + + + for(int i=1; i<8; i++) { + if (octile[i] == 0.0f) + octile[i] = octile[i-1]; + } + // compute weighted average separation of octiles + // for future use in contrast setting + for (int i=1; i<6; i++) { + ospread += (octile[i+1]-octile[i])/max(0.5f,(i>2 ? (octile[i+1]-octile[3]) : (octile[3]-octile[i]))); + } + ospread /= 5.f; + if (ospread<=0.f) {//probably the image is a blackframe + expcomp=0.; + black=0; + bright=0; + contr=0; + hlcompr=0; + hlcomprthresh=0; + return; + } + + + // compute clipping points based on the original histograms (linear, without exp comp.) + int clipped = 0; + int rawmax = (imax) - 1; + while (rawmax>1 && histogram[rawmax]+clipped <= 0) { + clipped += histogram[rawmax]; + rawmax--; + } + + //compute clipped white point + int clippable = (int)(sum * clip/100.f ); + int somm=sum; + clipped = 0; + int whiteclip = (imax) - 1; + while (whiteclip>1 && histogram[whiteclip]+clipped <= clippable) { + clipped += histogram[whiteclip]; + whiteclip--; + } + int clipwh=clipped; + //compute clipped black point + clipped = 0; + int shc = 0; + + while (shc 1.f) {//for great expcomp + expcomp = (expcomp1*fabs(expcomp2)+expcomp2*fabs(expcomp1))/(fabs(expcomp1)+fabs(expcomp2)); + } + else { + expcomp = 0.5 * (double)expcomp1 + 0.5 *(double) expcomp2;//for small expcomp + } + float gain = exp((float)expcomp*log(2.f)); + + float corr = sqrt(gain*scale/rawmax); + black = (int) shc*corr; + + + //now tune hlcompr to bring back rawmax to 65535 + hlcomprthresh = 33; + //this is a series approximation of the actual formula for comp, + //which is a transcendental equation + float comp = (gain*((float)whiteclip)/scale - 1.f)*2.3f;// 2.3 instead of 2 to increase slightly comp + hlcompr=(int)(100.*comp/(max(0.0,expcomp) + 1.0)); + hlcompr = max(0,min(100,hlcompr)); + + //now find brightness if gain didn't bring ave to midgray using + //the envelope of the actual 'control cage' brightness curve for simplicity + float midtmp = gain*sqrt(median*ave)/scale; + if (midtmp<0.1f) { + bright = (midgray-midtmp)*15.0/(midtmp); + } else { + bright = (midgray-midtmp)*15.0/(0.10833-0.0833*midtmp); + } + + bright = 0.25*/*(median/ave)*(hidev/lodev)*/max(0,bright); + + //compute contrast that spreads the average spacing of octiles + contr = (int) 50.0f*(1.1f-ospread); + contr = max(0,min(100,contr)); + //take gamma into account + double whiteclipg = (int)(CurveFactory::gamma2 (whiteclip * corr / 65536.0) * 65536.0); + + double gavg = 0.; + for (int i=0; i<65536>>histcompr; i++) + gavg += histogram[i] * CurveFactory::gamma2((int)(corr*(i<verbose) { + printf("sum=%i clip=%f clippable=%i clipWh=%i clipBl=%i\n",somm, clip, clippable,clipwh, clipbl); + printf ("expcomp1= %f expcomp2= %f gain= %f expcomp=%f\n",expcomp1,expcomp2,gain,expcomp); + printf ("expo=%f\n",expo); + printf ("median: %i average: %f median/average: %f\n",median,ave, median/ave); + printf ("average: %f\n",ave); + printf("comp=%f hlcomp: %i\n",comp, hlcompr); + printf ("median/average: %f\n",median/ave); + printf ("lodev: %f hidev: %f hidev/lodev: %f\n",lodev,hidev,hidev/lodev); + printf ("lodev: %f\n",lodev); + printf ("hidev: %f\n",hidev); + printf ("imax=%d rawmax= %d whiteclip= %d gain= %f\n",imax,rawmax,whiteclip,gain); + printf ("octiles: %f %f %f %f %f %f %f %f\n",octile[0],octile[1],octile[2],octile[3],octile[4],octile[5],octile[6],octile[7]); + printf ("ospread= %f\n",ospread); + printf ("overexp= %i\n",overex); + } + */ + /* + // %%%%%%%%%% LEGACY AUTOEXPOSURE CODE %%%%%%%%%%%%% + // black point selection is based on the linear result (yielding better visual results) + black = (int)(shc * corr); + // compute the white point of the exp. compensated gamma corrected image + double whiteclipg = (int)(CurveFactory::gamma2 (whiteclip * corr / 65536.0) * 65536.0); + + // compute average intensity of the exp compensated, gamma corrected image + double gavg = 0; + for (int i=0; i<65536>>histcompr; i++) + gavg += histogram[i] * CurveFactory::gamma2((int)(corr*(i<12.0) expcomp = 12.0; + bright = max(-100,min(bright,100)); + } + + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + double ImProcFunctions::getAutoDistor (const Glib::ustring &fname, int thumb_size) { + if (fname != "") { + rtengine::RawMetaDataLocation ri; + 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); + if (thumb == NULL) + return 0.0; + + Thumbnail* raw = rtengine::Thumbnail::loadFromRaw (fname, ri, w_raw, h_raw, 1, 1.0, FALSE); + if (raw == NULL) { + delete thumb; + return 0.0; + } + + if (h_thumb != h_raw) { + delete thumb; + delete raw; + return 0.0; + } + + int width; + + if (w_thumb > w_raw) + width = w_raw; + else + width = w_thumb; + + unsigned char* thumbGray; + unsigned char* rawGray; + thumbGray = thumb->getGrayscaleHistEQ (width); + rawGray = raw->getGrayscaleHistEQ (width); + + if (thumbGray == NULL || rawGray == NULL) { + if (thumbGray) delete thumbGray; + if (rawGray) delete rawGray; + delete thumb; + delete raw; + return 0.0; + } + + double dist_amount; + int dist_result = calcDistortion (thumbGray, rawGray, width, h_thumb, 1, dist_amount); + if(dist_result == -1) // not enough features found, try increasing max. number of features by factor 4 + dist_result = calcDistortion (thumbGray, rawGray, width, h_thumb, 4, dist_amount); + delete thumbGray; + delete rawGray; + delete thumb; + delete raw; + return dist_amount; + } + else + return 0.0; + } + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +} +#undef PIX_SORT +#undef med3x3 diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h new file mode 100644 index 000000000..226e42c8a --- /dev/null +++ b/rtengine/improcfun.h @@ -0,0 +1,379 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _IMPROCFUN_H_ +#define _IMPROCFUN_H_ + +#include "imagefloat.h" +#include "image16.h" +#include "image8.h" +#include "procparams.h" +#include "shmap.h" +#include "coord2d.h" +#include "color.h" +#include "labimage.h" +#include "cieimage.h" +#include "LUT.h" +#include "lcp.h" +#include "dcp.h" +#include "curves.h" +#include "cplx_wavelet_dec.h" +#include "editbuffer.h" + +#define PIX_SORT(a,b) { if ((a)>(b)) {temp=(a);(a)=(b);(b)=temp;} } + +#define med3(a0,a1,a2,a3,a4,a5,a6,a7,a8,median) { \ +pp[0]=a0; pp[1]=a1; pp[2]=a2; pp[3]=a3; pp[4]=a4; pp[5]=a5; pp[6]=a6; pp[7]=a7; pp[8]=a8; \ +PIX_SORT(pp[1],pp[2]); PIX_SORT(pp[4],pp[5]); PIX_SORT(pp[7],pp[8]); \ +PIX_SORT(pp[0],pp[1]); PIX_SORT(pp[3],pp[4]); PIX_SORT(pp[6],pp[7]); \ +PIX_SORT(pp[1],pp[2]); PIX_SORT(pp[4],pp[5]); PIX_SORT(pp[7],pp[8]); \ +PIX_SORT(pp[0],pp[3]); PIX_SORT(pp[5],pp[8]); PIX_SORT(pp[4],pp[7]); \ +PIX_SORT(pp[3],pp[6]); PIX_SORT(pp[1],pp[4]); PIX_SORT(pp[2],pp[5]); \ +PIX_SORT(pp[4],pp[7]); PIX_SORT(pp[4],pp[2]); PIX_SORT(pp[6],pp[4]); \ +PIX_SORT(pp[4],pp[2]); median=pp[4];} //pp4 = median + + + +namespace rtengine { + +using namespace procparams; + +class ImProcFunctions { + + static LUTf gamma2curve; + + cmsHTRANSFORM monitorTransform; + + const ProcParams* params; + double scale; + bool multiThread; + + 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 sharpenHaloCtrl (LabImage* lab, float** blurmap, float** base, int W, int H, SharpeningParams &sharpenParam); + void sharpenHaloCtrlcam (CieImage* ncie, float** blurmap, float** base, int W, int H); + void firstAnalysisThread(Imagefloat* original, Glib::ustring wprofile, unsigned int* histogram, int row_from, int row_to); + void dcdamping (float** aI, float** aO, float damping, int W, int H); + + bool needsCA (); + bool needsDistortion (); + bool needsRotation (); + bool needsPerspective (); + bool needsGradient (); + bool needsVignetting (); + bool needsLCP (); + // 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) { + const double A=-0.85; + + double w[4]; + + { + double t1, t2; + t1 = -A*(Dx-1.0)*Dx; + t2 = (3.0-2.0*Dx)*Dx*Dx; + w[3] = t1*Dx; + w[2] = t1*(Dx-1.0) + t2; + w[1] = -t1*Dx + 1.0 - t2; + w[0] = -t1*(Dx-1.0); + } + + double rd, gd, bd; + double yr[4], yg[4], yb[4]; + + for (int k=ys, kx=0; kr(k,i) * w[ix]; + gd += src->g(k,i) * w[ix]; + bd += src->b(k,i) * w[ix]; + } + yr[kx] = rd; yg[kx] = gd; yb[kx] = bd; + } + + + { + double t1, t2; + + t1 = -A*(Dy-1.0)*Dy; + t2 = (3.0-2.0*Dy)*Dy*Dy; + w[3] = t1*Dy; + w[2] = t1*(Dy-1.0) + t2; + w[1] = -t1*Dy + 1.0 - t2; + w[0] = -t1*(Dy-1.0); + } + + rd = gd = bd = 0.0; + for (int i=0; i<4; i++) { + rd += yr[i] * w[i]; + gd += yg[i] * w[i]; + bd += yb[i] * w[i]; + } + + *r = rd * mul; + *g = gd * mul; + *b = bd * mul; + + // if (xs==100 && ys==100) + // printf ("r=%g, g=%g\n", *r, *g); + } + + inline void interpolateTransformChannelsCubic (float** src, int xs, int ys, double Dx, double Dy, float *r, double mul) { + const double A=-0.85; + + double w[4]; + + { + double t1, t2; + t1 = -A*(Dx-1.0)*Dx; + t2 = (3.0-2.0*Dx)*Dx*Dx; + w[3] = t1*Dx; + w[2] = t1*(Dx-1.0) + t2; + w[1] = -t1*Dx + 1.0 - t2; + w[0] = -t1*(Dx-1.0); + } + + double rd; + double yr[4]; + + for (int k=ys, kx=0; kdefault + // 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=NULL); + 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=NULL); + static void getAutoExp (LUTu & histogram, int histcompr, double defgain, 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=NULL); +}; +} +#endif diff --git a/rtengine/impulse_denoise.h b/rtengine/impulse_denoise.h new file mode 100644 index 000000000..3151e8ec0 --- /dev/null +++ b/rtengine/impulse_denoise.h @@ -0,0 +1,510 @@ +/* + * This file is part of RawTherapee. + * + * 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 widthITheightOUT ANY widthARRANTY; without even the implied warranty of + * MERCheightANTABILITY 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 . + * + * 2010 Emil Martinec + * + */ +#include +#include "rt_math.h" +#include "labimage.h" +#include "improcfun.h" +#include "cieimage.h" +#include "sleef.c" +#include "opthelper.h" + +using namespace std; + +namespace rtengine { + +SSEFUNCTION void ImProcFunctions::impulse_nr (LabImage* lab, double thresh) +{ + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // impulse noise removal + // local variables + + int width = lab->W; + int height = lab->H; + + // buffer for the lowpass image + float ** lpf = new float *[height]; + // buffer for the highpass image + float ** impish = new float *[height]; + for (int i=0; i (lab->L, lpf, impish /*used as buffer here*/, width, height, thresh, false); +#ifdef _OPENMP +#pragma omp parallel +#endif + { + AlignedBufferMP buffer(max(width,height)); + + gaussHorizontal (lab->L, lpf, buffer, width, height, max(2.0,thresh-1.0)); + gaussVertical (lpf, lpf, buffer, width, height, max(2.0,thresh-1.0)); + } + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + float impthr = max(1.0,5.5-thresh); + float impthrDiv24 = impthr / 24.0f; //Issue 1671: moved the Division outside the loop, impthr can be optimized out too, but I let in the code at the moment + + +#ifdef _OPENMP +#pragma omp parallel +#endif +{ + int i1,j1,j; + float hpfabs, hfnbrave; +#ifdef __SSE2__ + __m128 hfnbravev,hpfabsv; + __m128 impthrDiv24v = _mm_set1_ps( impthrDiv24 ); + __m128 onev = _mm_set1_ps( 1.0f ); +#endif +#ifdef _OPENMP +#pragma omp for +#endif + for (int i=0; i < height; i++) { + for (j=0; j < 2; j++) { + hpfabs = fabs(lab->L[i][j]-lpf[i][j]); + //block average of high pass data + for (i1=max(0,i-2), hfnbrave=0; i1<=min(i+2,height-1); i1++ ) + for (j1=0; j1<=j+2; j1++) { + hfnbrave += fabs(lab->L[i1][j1]-lpf[i1][j1]); + } + impish[i][j] = (hpfabs>((hfnbrave-hpfabs)*impthrDiv24)); + } +#ifdef __SSE2__ + for (; j < width-5; j+=4) { + hfnbravev = _mm_setzero_ps( ); + hpfabsv = vabsf(LVFU(lab->L[i][j])-LVFU(lpf[i][j])); + //block average of high pass data + for (i1=max(0,i-2); i1<=min(i+2,height-1); i1++ ) + for (j1=j-2; j1<=j+2; j1++) { + hfnbravev += vabsf(LVFU(lab->L[i1][j1])-LVFU(lpf[i1][j1])); + } + _mm_storeu_ps(&impish[i][j], vself(vmaskf_gt(hpfabsv, (hfnbravev-hpfabsv)*impthrDiv24v), onev, _mm_setzero_ps())); + } + for (; j < width-2; j++) { + hpfabs = fabs(lab->L[i][j]-lpf[i][j]); + //block average of high pass data + for (i1=max(0,i-2), hfnbrave=0; i1<=min(i+2,height-1); i1++ ) + for (j1=j-2; j1<=j+2; j1++) { + hfnbrave += fabs(lab->L[i1][j1]-lpf[i1][j1]); + } + impish[i][j] = (hpfabs>((hfnbrave-hpfabs)*impthrDiv24)); + } +#else + for (; j < width-2; j++) { + hpfabs = fabs(lab->L[i][j]-lpf[i][j]); + //block average of high pass data + for (i1=max(0,i-2), hfnbrave=0; i1<=min(i+2,height-1); i1++ ) + for (j1=j-2; j1<=j+2; j1++) { + hfnbrave += fabs(lab->L[i1][j1]-lpf[i1][j1]); + } + impish[i][j] = (hpfabs>((hfnbrave-hpfabs)*impthrDiv24)); + } +#endif + for (; j < width; j++) { + hpfabs = fabs(lab->L[i][j]-lpf[i][j]); + //block average of high pass data + for (i1=max(0,i-2), hfnbrave=0; i1<=min(i+2,height-1); i1++ ) + for (j1=j-2; j1L[i1][j1]-lpf[i1][j1]); + } + impish[i][j] = (hpfabs>((hfnbrave-hpfabs)*impthrDiv24)); + } + } +} + +//now impulsive values have been identified + +// Issue 1671: +// often, noise isn't evenly distributed, e.g. only a few noisy pixels in the bright sky, but many in the dark foreground, +// so it's better to schedule dynamic and let every thread only process 16 rows, to avoid running big threads out of work +// Measured it and in fact gives better performance than without schedule(dynamic,16). Of course, there could be a better +// choice for the chunk_size than 16 +// race conditions are avoided by the array impish +#ifdef _OPENMP +#pragma omp parallel +#endif +{ + int i1,j1,j; + float wtdsum[3], dirwt, norm; +#ifdef _OPENMP +#pragma omp for schedule(dynamic,16) +#endif + for (int i=0; i < height; i++) { + for (j=0; j < 2; j++) { + if (!impish[i][j]) continue; + norm=0.0; + wtdsum[0]=wtdsum[1]=wtdsum[2]=0.0; + for (i1=max(0,i-2); i1<=min(i+2,height-1); i1++ ) + for (j1=0; j1<=j+2; j1++ ) { + if (i1==i && j1==j) continue; + if (impish[i1][j1]) continue; + dirwt = 1/(SQR(lab->L[i1][j1]-lab->L[i][j])+eps);//use more sophisticated rangefn??? + wtdsum[0] += dirwt*lab->L[i1][j1]; + wtdsum[1] += dirwt*lab->a[i1][j1]; + wtdsum[2] += dirwt*lab->b[i1][j1]; + norm += dirwt; + } + if (norm) { + lab->L[i][j]=wtdsum[0]/norm;//low pass filter + lab->a[i][j]=wtdsum[1]/norm;//low pass filter + lab->b[i][j]=wtdsum[2]/norm;//low pass filter + } + } + for (; j < width-2; j++) { + if (!impish[i][j]) continue; + norm=0.0; + wtdsum[0]=wtdsum[1]=wtdsum[2]=0.0; + for (i1=max(0,i-2); i1<=min(i+2,height-1); i1++ ) + for (j1=j-2; j1<=j+2; j1++ ) { + if (i1==i && j1==j) continue; + if (impish[i1][j1]) continue; + dirwt = 1/(SQR(lab->L[i1][j1]-lab->L[i][j])+eps);//use more sophisticated rangefn??? + wtdsum[0] += dirwt*lab->L[i1][j1]; + wtdsum[1] += dirwt*lab->a[i1][j1]; + wtdsum[2] += dirwt*lab->b[i1][j1]; + norm += dirwt; + } + if (norm) { + lab->L[i][j]=wtdsum[0]/norm;//low pass filter + lab->a[i][j]=wtdsum[1]/norm;//low pass filter + lab->b[i][j]=wtdsum[2]/norm;//low pass filter + } + } + for (; j < width; j++) { + if (!impish[i][j]) continue; + norm=0.0; + wtdsum[0]=wtdsum[1]=wtdsum[2]=0.0; + for (i1=max(0,i-2); i1<=min(i+2,height-1); i1++ ) + for (j1=j-2; j1L[i1][j1]-lab->L[i][j])+eps);//use more sophisticated rangefn??? + wtdsum[0] += dirwt*lab->L[i1][j1]; + wtdsum[1] += dirwt*lab->a[i1][j1]; + wtdsum[2] += dirwt*lab->b[i1][j1]; + norm += dirwt; + } + if (norm) { + lab->L[i][j]=wtdsum[0]/norm;//low pass filter + lab->a[i][j]=wtdsum[1]/norm;//low pass filter + lab->b[i][j]=wtdsum[2]/norm;//low pass filter + } + } + } +} +//now impulsive values have been corrected + + for (int i=0; iW; + int height = ncie->H; + + + float piid=3.14159265f/180.f; + + // buffer for the lowpass image + float ** lpf = buffers[0]; + // buffer for the highpass image + float ** impish = buffers[1]; + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // modified bilateral filter for lowpass image, omitting input pixel; or Gaussian blur + + + + //The cleaning algorithm starts here + + //rangeblur (lab->L, lpf, impish /*used as buffer here*/, width, height, thresh, false); +#ifdef _OPENMP +#pragma omp parallel +#endif + { + AlignedBufferMP buffer(max(width,height)); + gaussHorizontal (ncie->sh_p, lpf, buffer, width, height, max(2.0,thresh-1.0)); + gaussVertical (lpf, lpf, buffer, width, height, max(2.0,thresh-1.0)); + } + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + float impthr = max(1.0f,5.0f-(float)thresh); + float impthrDiv24 = impthr / 24.0f; //Issue 1671: moved the Division outside the loop, impthr can be optimized out too, but I let in the code at the moment + +#ifdef _OPENMP +#pragma omp parallel +#endif +{ + int i1,j1,j; + float hpfabs, hfnbrave; +#ifdef __SSE2__ + __m128 hfnbravev,hpfabsv; + __m128 impthrDiv24v = _mm_set1_ps( impthrDiv24 ); + __m128 onev = _mm_set1_ps( 1.0f ); +#endif +#ifdef _OPENMP +#pragma omp for +#endif + for (int i=0; i < height; i++) { + for (j=0; j < 2; j++) { + hpfabs = fabs(ncie->sh_p[i][j]-lpf[i][j]); + //block average of high pass data + for (i1=max(0,i-2), hfnbrave=0; i1<=min(i+2,height-1); i1++ ) + for (j1=0; j1<=j+2; j1++) { + hfnbrave += fabs(ncie->sh_p[i1][j1]-lpf[i1][j1]); + } + impish[i][j] = (hpfabs>((hfnbrave-hpfabs)*impthrDiv24)); + } +#ifdef __SSE2__ + for (; j < width-5; j+=4) { + hpfabsv = vabsf(LVFU(ncie->sh_p[i][j])-LVFU(lpf[i][j])); + hfnbravev = _mm_setzero_ps(); + //block average of high pass data + for (i1=max(0,i-2); i1<=min(i+2,height-1); i1++ ) { + for (j1=j-2; j1<=j+2; j1++ ) { + hfnbravev += vabsf(LVFU(ncie->sh_p[i1][j1])-LVFU(lpf[i1][j1])); + } + _mm_storeu_ps(&impish[i][j], vself(vmaskf_gt(hpfabsv, (hfnbravev-hpfabsv)*impthrDiv24v), onev, _mm_setzero_ps())); + } + } + for (; j < width-2; j++) { + hpfabs = fabs(ncie->sh_p[i][j]-lpf[i][j]); + //block average of high pass data + for (i1=max(0,i-2), hfnbrave=0; i1<=min(i+2,height-1); i1++ ) + for (j1=j-2; j1<=j+2; j1++ ) { + hfnbrave += fabs(ncie->sh_p[i1][j1]-lpf[i1][j1]); + } + impish[i][j] = (hpfabs>((hfnbrave-hpfabs)*impthrDiv24)); + } +#else + for (; j < width-2; j++) { + hpfabs = fabs(ncie->sh_p[i][j]-lpf[i][j]); + //block average of high pass data + for (i1=max(0,i-2), hfnbrave=0; i1<=min(i+2,height-1); i1++ ) + for (j1=j-2; j1<=j+2; j1++ ) { + hfnbrave += fabs(ncie->sh_p[i1][j1]-lpf[i1][j1]); + } + impish[i][j] = (hpfabs>((hfnbrave-hpfabs)*impthrDiv24)); + } +#endif + for (; j < width; j++) { + hpfabs = fabs(ncie->sh_p[i][j]-lpf[i][j]); + //block average of high pass data + for (i1=max(0,i-2), hfnbrave=0; i1<=min(i+2,height-1); i1++ ) + for (j1=j-2; j1sh_p[i1][j1]-lpf[i1][j1]); + } + impish[i][j] = (hpfabs>((hfnbrave-hpfabs)*impthrDiv24)); + } + } +} + +//now impulsive values have been identified + + const float eps = 1.0f; + + float** sraa = buffers[0]; // we can reuse buffers[0] because lpf is not needed anymore at this point + float** srbb = buffers[2]; + +#ifdef _OPENMP +#pragma omp parallel +#endif +{ + int j; + float2 sincosval; +#ifdef __SSE2__ + vfloat2 sincosvalv; + __m128 piidv = _mm_set1_ps( piid ); + __m128 tempv; +#endif +#ifdef _OPENMP +#pragma omp for +#endif + for (int i=0; ih_p[i][j])); + tempv = LVFU(ncie->C_p[i][j]); + _mm_storeu_ps(&sraa[i][j], tempv * sincosvalv.y); + _mm_storeu_ps(&srbb[i][j], tempv * sincosvalv.x); + } + for (; jh_p[i][j]); + sraa[i][j]=ncie->C_p[i][j]*sincosval.y; + srbb[i][j]=ncie->C_p[i][j]*sincosval.x; + } +#else + for (j=0; jh_p[i][j]); + sraa[i][j]=ncie->C_p[i][j]*sincosval.y; + srbb[i][j]=ncie->C_p[i][j]*sincosval.x; + } +#endif + } +} + +// Issue 1671: +// often, noise isn't evenly distributed, e.g. only a few noisy pixels in the bright sky, but many in the dark foreground, +// so it's better to schedule dynamic and let every thread only process 16 rows, to avoid running big threads out of work +// Measured it and in fact gives better performance than without schedule(dynamic,16). Of course, there could be a better +// choice for the chunk_size than 16 +// race conditions are avoided by the array impish +#ifdef _OPENMP +#pragma omp parallel +#endif +{ + int i1,j1,j; + float wtdsum[3], dirwt, norm; +#ifdef _OPENMP +#pragma omp for schedule(dynamic,16) +#endif + for (int i=0; i < height; i++) { + for (j=0; j < 2; j++) { + if (!impish[i][j]) continue; + norm=0.0f; + wtdsum[0]=wtdsum[1]=wtdsum[2]=0.0f; + for (i1=max(0,i-2); i1<=min(i+2,height-1); i1++ ) + for (j1=0; j1<=j+2; j1++ ) { + if (i1==i && j1==j) continue; + if (impish[i1][j1]) continue; + dirwt = 1.f/(SQR(ncie->sh_p[i1][j1]-ncie->sh_p[i][j])+eps);//use more sophisticated rangefn??? + wtdsum[0] += dirwt*ncie->sh_p[i1][j1]; + wtdsum[1] += dirwt*sraa[i1][j1]; + wtdsum[2] += dirwt*srbb[i1][j1]; + norm += dirwt; + } + if (norm) { + ncie->sh_p[i][j]=wtdsum[0]/norm;//low pass filter + sraa[i][j]=wtdsum[1]/norm;//low pass filter + srbb[i][j]=wtdsum[2]/norm;//low pass filter + } + } + for (; j < width-2; j++) { + if (!impish[i][j]) continue; + norm=0.0f; + wtdsum[0]=wtdsum[1]=wtdsum[2]=0.0f; + for (i1=max(0,i-2); i1<=min(i+2,height-1); i1++ ) + for (j1=j-2; j1<=j+2; j1++ ) { + if (i1==i && j1==j) continue; + if (impish[i1][j1]) continue; + dirwt = 1.f/(SQR(ncie->sh_p[i1][j1]-ncie->sh_p[i][j])+eps);//use more sophisticated rangefn??? + wtdsum[0] += dirwt*ncie->sh_p[i1][j1]; + wtdsum[1] += dirwt*sraa[i1][j1]; + wtdsum[2] += dirwt*srbb[i1][j1]; + norm += dirwt; + } + if (norm) { + ncie->sh_p[i][j]=wtdsum[0]/norm;//low pass filter + sraa[i][j]=wtdsum[1]/norm;//low pass filter + srbb[i][j]=wtdsum[2]/norm;//low pass filter + } + } + for (; j < width; j++) { + if (!impish[i][j]) continue; + norm=0.0f; + wtdsum[0]=wtdsum[1]=wtdsum[2]=0.0f; + for (i1=max(0,i-2); i1<=min(i+2,height-1); i1++ ) + for (j1=j-2; j1sh_p[i1][j1]-ncie->sh_p[i][j])+eps);//use more sophisticated rangefn??? + wtdsum[0] += dirwt*ncie->sh_p[i1][j1]; + wtdsum[1] += dirwt*sraa[i1][j1]; + wtdsum[2] += dirwt*srbb[i1][j1]; + norm += dirwt; + } + if (norm) { + ncie->sh_p[i][j]=wtdsum[0]/norm;//low pass filter + sraa[i][j]=wtdsum[1]/norm;//low pass filter + srbb[i][j]=wtdsum[2]/norm;//low pass filter + } + } + } +} + +//now impulsive values have been corrected + +#ifdef _OPENMP +#pragma omp parallel +#endif +{ +#ifdef __SSE2__ + __m128 interav,interbv; + __m128 piidv = _mm_set1_ps(piid); +#endif // __SSE2__ + int j; +#ifdef _OPENMP +#pragma omp for +#endif + for(int i = 0; i < height; i++ ) { +#ifdef __SSE2__ + for(j = 0; j < width-3; j+=4) { + interav = LVFU(sraa[i][j]); + interbv = LVFU(srbb[i][j]); + _mm_storeu_ps(&ncie->h_p[i][j],(xatan2f(interbv,interav))/piidv); + _mm_storeu_ps(&ncie->C_p[i][j], _mm_sqrt_ps(SQRV(interbv)+SQRV(interav))); + } + for(; j < width; j++) { + float intera = sraa[i][j]; + float interb = srbb[i][j]; + ncie->h_p[i][j]=(xatan2f(interb,intera))/piid; + ncie->C_p[i][j]=sqrt(SQR(interb)+SQR(intera)); + } + +#else + for(j = 0; j < width; j++) { + float intera = sraa[i][j]; + float interb = srbb[i][j]; + ncie->h_p[i][j]=(xatan2f(interb,intera))/piid; + ncie->C_p[i][j]=sqrt(SQR(interb)+SQR(intera)); + } +#endif + } +} + +} + + +} diff --git a/rtengine/init.cc b/rtengine/init.cc new file mode 100644 index 000000000..4c3024746 --- /dev/null +++ b/rtengine/init.cc @@ -0,0 +1,93 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "rtengine.h" +#include "iccstore.h" +#include "dcp.h" +#include "camconst.h" +#include "rawimagesource.h" +#include "improcfun.h" +#include "improccoordinator.h" +#include "dfmanager.h" +#include "ffmanager.h" +#include "rtthumbnail.h" +#include "../rtgui/profilestore.h" +#include "../rtgui/threadutils.h" + +namespace rtengine { + +const Settings* settings; + +MyMutex* lcmsMutex = NULL; + +int init (const Settings* s, Glib::ustring baseDir, Glib::ustring userSettingsDir) { + + settings = s; + iccStore->init (s->iccDirectory, baseDir + "/iccprofiles"); + iccStore->findDefaultMonitorProfile(); + + dcpStore->init (baseDir + "/dcpprofiles"); + + CameraConstantsStore::initCameraConstants (baseDir, userSettingsDir); + profileStore.init (); + ProcParams::init (); + Color::init (); + RawImageSource::init (); + ImProcFunctions::initCache (); + Thumbnail::initGamma (); + delete lcmsMutex; + lcmsMutex = new MyMutex; + dfm.init( s->darkFramesPath ); + ffm.init( s->flatFieldsPath ); + return 0; +} + +void cleanup () { + + ProcParams::cleanup (); + Color::cleanup (); + ImProcFunctions::cleanupCache (); + Thumbnail::cleanupGamma (); + RawImageSource::cleanup (); +} + +StagedImageProcessor* StagedImageProcessor::create (InitialImage* initialImage) { + + ImProcCoordinator* ipc = new ImProcCoordinator (); + ipc->assign (initialImage->getImageSource ()); + return ipc; +} + +void StagedImageProcessor::destroy (StagedImageProcessor* sip) { + + delete sip; +} + +Settings* Settings::create () { + + return new Settings; +} + +void Settings::destroy (Settings* s) { + + delete s; +} + + +} + diff --git a/rtengine/iplab2rgb.cc b/rtengine/iplab2rgb.cc new file mode 100644 index 000000000..44783afe6 --- /dev/null +++ b/rtengine/iplab2rgb.cc @@ -0,0 +1,465 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "rtengine.h" +#include "improcfun.h" +#include +#include "iccstore.h" +#include "iccmatrices.h" +#include "../rtgui/options.h" +#include "settings.h" +#include "curves.h" +#include "alignedbuffer.h" +#include "color.h" + +namespace rtengine { + +#define CLIP01(a) ((a)>0?((a)<1?(a):1):0) + +extern const Settings* settings; + +const double (*wprof[])[3] = {xyz_sRGB, xyz_adobe, xyz_prophoto, xyz_widegamut, xyz_bruce, xyz_beta, xyz_best}; +const double (*iwprof[])[3] = {sRGB_xyz, adobe_xyz, prophoto_xyz, widegamut_xyz, bruce_xyz, beta_xyz, best_xyz}; +const char* wprofnames[] = {"sRGB", "Adobe RGB", "ProPhoto", "WideGamut", "BruceRGB", "Beta RGB", "BestRGB"}; +const int numprof = 7; + +void ImProcFunctions::lab2monitorRgb (LabImage* lab, Image8* image) { + //gamutmap(lab); + + if (monitorTransform) { + + int W = lab->W; + int H = lab->H; + unsigned char * data = image->data; + + // cmsDoTransform is relatively expensive +#ifdef _OPENMP +#pragma omp parallel firstprivate(lab, data, W, H) +#endif +{ + AlignedBuffer pBuf(3*lab->W); + double *buffer=pBuf.data; + +#ifdef _OPENMP +#pragma omp for schedule(dynamic,16) +#endif + for (int i=0; iL[i]; + float* ra = lab->a[i]; + float* rb = lab->b[i]; + + float fy,fx,fz,x_,y_,z_,LL; + + for (int j=0; jW; + int H = lab->H; + unsigned char * data = image->data; + +#ifdef _OPENMP +#pragma omp parallel for schedule(dynamic,16) if (multiThread) +#endif + for (int i=0; iL[i]; + float* ra = lab->a[i]; + float* rb = lab->b[i]; + int ix = i * 3 * W; + + float R,G,B; + float fy,fx,fz,x_,y_,z_,LL; + + for (int j=0; jColor::epskap) ? 65535.0*fy*fy*fy : 65535.0*LL/Color::kappa; + + Color::xyz2srgb(x_,y_,z_,R,G,B); + + /* copy RGB */ + //int R1=((int)gamma2curve[(R)]) + data[ix++] = ((int)gamma2curve[CLIP(R)]) >> 8; + data[ix++] = ((int)gamma2curve[CLIP(G)]) >> 8; + data[ix++] = ((int)gamma2curve[CLIP(B)]) >> 8; + } + } + } +} + +Image8* ImProcFunctions::lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, bool standard_gamma) { + //gamutmap(lab); + + if (cx<0) cx = 0; + if (cy<0) cy = 0; + if (cx+cw>lab->W) cw = lab->W-cx; + if (cy+ch>lab->H) ch = lab->H-cy; + + Image8* image = new Image8 (cw, ch); + + cmsHPROFILE oprof = iccStore->getProfile (profile); + + if (oprof) { + cmsHPROFILE oprofG = oprof; + if (standard_gamma) { + oprofG = ICCStore::makeStdGammaProfile(oprof); + } + lcmsMutex->lock (); + cmsHPROFILE hLab = cmsCreateLab4Profile(NULL); + cmsHTRANSFORM hTransform = cmsCreateTransform (hLab, TYPE_Lab_DBL, oprofG, TYPE_RGB_8, settings->colorimetricIntent, + cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is important for thread safety + cmsCloseProfile(hLab); + lcmsMutex->unlock (); + + unsigned char *data = image->data; + + // cmsDoTransform is relatively expensive +#ifdef _OPENMP +#pragma omp parallel +#endif +{ + AlignedBuffer pBuf(3*cw); + double *buffer=pBuf.data; + int condition = cy+ch; + +#ifdef _OPENMP +#pragma omp for firstprivate(lab) schedule(dynamic,16) +#endif + for (int i=cy; iL[i]; + float* ra = lab->a[i]; + float* rb = lab->b[i]; + + for (int j=cx; jL[i]; + float* ra = lab->a[i]; + float* rb = lab->b[i]; + int ix = 3*i*cw; + for (int j=cx; jColor::epskap) ? 65535.0*fy*fy*fy : 65535.0*LL/Color::kappa; + + Color::xyz2rgb(x_,y_,z_,R,G,B,rgb_xyz); + + image->data[ix++] = (int)gamma2curve[CLIP(R)] >> 8; + image->data[ix++] = (int)gamma2curve[CLIP(G)] >> 8; + image->data[ix++] = (int)gamma2curve[CLIP(B)] >> 8; + } + } + } + return image; +} +// for default (not gamma) +Image16* ImProcFunctions::lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, bool bw) { + + //gamutmap(lab); + + if (cx<0) cx = 0; + if (cy<0) cy = 0; + if (cx+cw>lab->W) cw = lab->W-cx; + if (cy+ch>lab->H) ch = lab->H-cy; + + Image16* image = new Image16 (cw, ch); + cmsHPROFILE oprof = iccStore->getProfile (profile); + + + + if (oprof) { + #pragma omp parallel for if (multiThread) + for (int i=cy; iL[i]; + float* ra = lab->a[i]; + float* rb = lab->b[i]; + short* xa = (short*)image->r(i-cy); + short* ya = (short*)image->g(i-cy); + short* za = (short*)image->b(i-cy); + for (int j=cx; jColor::epskap) ? 65535.0f*fy*fy*fy : 65535.0f*LL/Color::kappa; + + xa[j-cx] = CLIP((int) round(x_)); + ya[j-cx] = CLIP((int) round(y_)); + za[j-cx] = CLIP((int) round(z_)); + if(bw && y_ < 65535.f ){//force Bw value and take highlight into account + xa[j-cx] =(int) round(y_* Color::D50x ); + za[j-cx] =(int) round(y_* Color::D50z); + } + + } + } + + cmsHPROFILE iprof = iccStore->getXYZProfile (); + lcmsMutex->lock (); + cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprof, TYPE_RGB_16, settings->colorimetricIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); + lcmsMutex->unlock (); + + image->ExecCMSTransform(hTransform); + + cmsDeleteTransform(hTransform); + } else { + #pragma omp parallel for if (multiThread) + for (int i=cy; iL[i]; + float* ra = lab->a[i]; + float* rb = lab->b[i]; + for (int j=cx; jColor::epskap) ? (float) 65535.0f*fy*fy*fy : 65535.0f*LL/Color::kappa; + + Color::xyz2srgb(x_,y_,z_,R,G,B); + + image->r(i-cy,j-cx) = (int)gamma2curve[CLIP(R)]; + image->g(i-cy,j-cx) = (int)gamma2curve[CLIP(G)]; + image->b(i-cy,j-cx) = (int)gamma2curve[CLIP(B)]; + } + } + } + return image; +} + + +// for gamma options (BT709...sRGB linear...) +Image16* ImProcFunctions::lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, Glib::ustring profi, Glib::ustring gam, bool freegamma, double gampos, double slpos, double &ga0, double &ga1, double &ga2, double &ga3, double &ga4, double &ga5, double &ga6, bool bw) { + + //gamutmap(lab); + + if (cx<0) cx = 0; + if (cy<0) cy = 0; + if (cx+cw>lab->W) cw = lab->W-cx; + if (cy+ch>lab->H) ch = lab->H-cy; + + Image16* image = new Image16 (cw, ch); + float p1,p2,p3,p4,p5,p6;//primaries + //double ga0,ga1,ga2,ga3,ga4,ga5=0.0,ga6=0.0;//gamma parameters + double g_a0,g_a1,g_a2,g_a3,g_a4,g_a5;//gamma parameters + double pwr; + double ts; + ga6=0.0; + pwr=1.0/gampos; + ts=slpos; + int mode=0, imax=0; + + int t50; + int select_temp =1;//5003K + const double eps=0.000000001;// not divide by zero + //primaries for 7 working profiles ==> output profiles + // eventually to adapt primaries if RT used special profiles ! + if(profi=="ProPhoto") {p1=0.7347; p2=0.2653; p3=0.1596; p4=0.8404; p5=0.0366; p6=0.0001;select_temp=1;}//Prophoto primaries + else if (profi=="WideGamut") {p1=0.7350; p2=0.2650; p3=0.1150; p4=0.8260; p5=0.1570; p6=0.0180;select_temp=1;}//Widegamut primaries + else if (profi=="Adobe RGB") {p1=0.6400; p2=0.3300; p3=0.2100; p4=0.7100; p5=0.1500; p6=0.0600;select_temp=2;}//Adobe primaries + else if (profi=="sRGB") {p1=0.6400; p2=0.3300; p3=0.3000; p4=0.6000; p5=0.1500; p6=0.0600;select_temp=2;} // sRGB primaries + else if (profi=="BruceRGB") {p1=0.6400; p2=0.3300; p3=0.2800; p4=0.6500; p5=0.1500; p6=0.0600;select_temp=2;} // Bruce primaries + else if (profi=="Beta RGB") {p1=0.6888; p2=0.3112; p3=0.1986; p4=0.7551; p5=0.1265; p6=0.0352;select_temp=1;} // Beta primaries + else if (profi=="BestRGB") {p1=0.7347; p2=0.2653; p3=0.2150; p4=0.7750; p5=0.1300; p6=0.0350;select_temp=1;} // Best primaries + if (!freegamma) {//if Free gamma not selected + // gamma : ga0,ga1,ga2,ga3,ga4,ga5 by calcul + if(gam=="BT709_g2.2_s4.5") {ga0=2.22;ga1=0.909995;ga2=0.090005;ga3=0.222222; ga4=0.081071;ga5=0.0;}//BT709 2.2 4.5 - my prefered as D.Coffin + else if (gam=="sRGB_g2.4_s12.92") {ga0=2.40; ga1=0.947858; ga2=0.052142;ga3=0.077399;ga4=0.039293;ga5=0.0;}//sRGB 2.4 12.92 - RT default as Lightroom + else if (gam=="High_g1.3_s3.35") {ga0=1.3 ; ga1=0.998279; ga2=0.001721;ga3=0.298507;ga4=0.005746;ga5=0.0;}//for high dynamic images + else if (gam== "Low_g2.6_s6.9") {ga0=2.6 ; ga1=0.891161; ga2=0.108839;ga3=0.144928;ga4=0.076332;ga5=0.0;} //gamma 2.6 variable : for low contrast images + else if (gam=="linear_g1.0") {ga0=1.0; ga1=1.;ga2=0.;ga3=1./eps;ga4=0.;ga5=0.0;}//gamma=1 linear : for high dynamic images (cf : D.Coffin...) + else if (gam=="standard_g2.2") {ga0=2.2; ga1=1.;ga2=0.;ga3=1./eps;ga4=0.;ga5=0.0;}//gamma=2.2 (as gamma of Adobe, Widegamut...) + else if (gam=="standard_g1.8") {ga0=1.8; ga1=1.;ga2=0.;ga3=1./eps;ga4=0.;ga5=0.0;}//gamma=1.8 (as gamma of Prophoto) + } + else //free gamma selected + { + if(slpos==0) slpos=eps; + Color::calcGamma(pwr, ts, mode, imax,g_a0,g_a1,g_a2,g_a3,g_a4,g_a5);// call to calcGamma with selected gamma and slope : return parameters for LCMS2 + ga4=g_a3*ts; + //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); + ga0=gampos;ga1=1./(1.0+g_a4);ga2=g_a4/(1.0 + g_a4);ga3=1./slpos;ga5=0.0; + //printf("ga0=%f ga1=%f ga2=%f ga3=%f ga4=%f\n", ga0,ga1,ga2,ga3,ga4); + + } + if(select_temp==1) t50=5003;// for Widegamut, Prophoto Best, Beta D50 + else if (select_temp==2) t50=6504;// for sRGB, AdobeRGB, Bruce D65 + + cmsCIExyY xyD; + cmsCIExyYTRIPLE Primaries = {{p1, p2, 1.0},//red primaries + {p3, p4, 1.0}, // green + {p5, p6, 1.0} //blue + }; + cmsToneCurve* GammaTRC[3]; + cmsFloat64Number Parameters[7]; + Parameters[0] = ga0; + Parameters[1] = ga1; + Parameters[2] = ga2; + Parameters[3] = ga3; + Parameters[4] = ga4; + Parameters[5] = ga5; + Parameters[6] = ga6; +// 7 parameters for smoother curves + cmsWhitePointFromTemp(&xyD, t50); + GammaTRC[0] = GammaTRC[1] = GammaTRC[2] = cmsBuildParametricToneCurve(NULL, 5, Parameters);//5 = more smoother than 4 + cmsHPROFILE oprofdef = cmsCreateRGBProfileTHR(NULL, &xyD, &Primaries, GammaTRC); //oprofdef become Outputprofile + + cmsFreeToneCurve(GammaTRC[0]); + + + if (oprofdef) { + #pragma omp parallel for if (multiThread) + for (int i=cy; iL[i]; + float* ra = lab->a[i]; + float* rb = lab->b[i]; + short* xa = (short*)image->r(i-cy); + short* ya = (short*)image->g(i-cy); + short* za = (short*)image->b(i-cy); + for (int j=cx; jColor::epskap) ? (float) 65535.0*fy*fy*fy : 65535.0f*LL/Color::kappa; + + xa[j-cx] = CLIP((int) round(x_)) ; + ya[j-cx] = CLIP((int) round(y_)); + za[j-cx] = CLIP((int) round(z_)); + if(bw && y_ < 65535.f){//force Bw value and take highlight into account + xa[j-cx] =(int) round(y_ * Color::D50x); + za[j-cx] =(int) round(y_ * Color::D50z); + } + + } + } + + cmsHPROFILE iprof = iccStore->getXYZProfile (); + lcmsMutex->lock (); + cmsHTRANSFORM hTransform = cmsCreateTransform (iprof, TYPE_RGB_16, oprofdef, TYPE_RGB_16, settings->colorimetricIntent, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); + lcmsMutex->unlock (); + + image->ExecCMSTransform(hTransform); + cmsDeleteTransform(hTransform); + } else { + // + #pragma omp parallel for if (multiThread) + for (int i=cy; iL[i]; + float* ra = lab->a[i]; + float* rb = lab->b[i]; + for (int j=cx; jColor::epskap) ? (float) 65535.0*fy*fy*fy : 65535.0f*LL/Color::kappa; + + Color::xyz2srgb(x_,y_,z_,R,G,B); + + image->r(i-cy,j-cx) = (int)gamma2curve[CLIP(R)]; + image->g(i-cy,j-cx) = (int)gamma2curve[CLIP(G)]; + image->b(i-cy,j-cx) = (int)gamma2curve[CLIP(B)]; + } + } + } + return image; +} + +//#include "sRGBgamutbdy.cc" + +} diff --git a/rtengine/ipresize.cc b/rtengine/ipresize.cc new file mode 100644 index 000000000..29e25107d --- /dev/null +++ b/rtengine/ipresize.cc @@ -0,0 +1,410 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "improcfun.h" +#include "rt_math.h" +#include "sleef.c" +#include "opthelper.h" +//#define PROFILE + +#ifdef PROFILE +# include +#endif + +namespace rtengine { + +static inline float Lanc(float x, float a) +{ + if (x * x < 1e-6f) + return 1.0f; + else if (x * x > a * a) + return 0.0f; + else { + x = static_cast(M_PI) * x; + return a * xsinf(x) * xsinf(x / a) / (x * x); + } +} + +void ImProcFunctions::Lanczos(const Image16* src, Image16* dst, float scale) +{ + + const float delta = 1.0f / scale; + const float a = 3.0f; + const float sc = min(scale, 1.0f); + const int support = static_cast(2.0f * a / sc) + 1; + +#pragma omp parallel +{ + // storage for precomputed parameters for horisontal interpolation + float * wwh = new float[support * dst->width]; + int * jj0 = new int[dst->width]; + int * jj1 = new int[dst->width]; + + // temporal storage for vertically-interpolated row of pixels + float * lr = new float[src->width]; + float * lg = new float[src->width]; + float * lb = new float[src->width]; + + // Phase 1: precompute coefficients for horisontal interpolation + + for (int j = 0; j < dst->width; j++) { + + // x coord of the center of pixel on src image + float x0 = (static_cast(j) + 0.5f) * delta - 0.5f; + + // weights for interpolation in horisontal direction + float * w = wwh + j * support; + + // sum of weights used for normalization + float ws = 0.0f; + + jj0[j] = max(0, static_cast(floorf(x0 - a / sc)) + 1); + jj1[j] = min(src->width, static_cast(floorf(x0 + a / sc)) + 1); + + // calculate weights + for (int jj = jj0[j]; jj < jj1[j]; jj++) { + int k = jj - jj0[j]; + float z = sc * (x0 - static_cast(jj)); + w[k] = Lanc(z, a); + ws += w[k]; + } + + // normalize weights + for (int k = 0; k < support; k++) { + w[k] /= ws; + } + } + // Phase 2: do actual interpolation +#pragma omp for + for (int i = 0; i < dst->height; i++) { + + // y coord of the center of pixel on src image + float y0 = (static_cast(i) + 0.5f) * delta - 0.5f; + + // weights for interpolation in y direction + float w[support]; + + // sum of weights used for normalization + float ws= 0.0f; + + int ii0 = max(0, static_cast(floorf(y0 - a / sc)) + 1); + int ii1 = min(src->height, static_cast(floorf(y0 + a / sc)) + 1); + + // calculate weights for vertical interpolation + for (int ii = ii0; ii < ii1; ii++) { + int k = ii - ii0; + float z = sc * (y0 - static_cast(ii)); + w[k] = Lanc(z, a); + ws += w[k]; + } + + // normalize weights + for (int k = 0; k < support; k++) { + w[k] /= ws; + } + + // Do vertical interpolation. Store results. + for (int j = 0; j < src->width; j++) { + + float r = 0.0f, g = 0.0f, b = 0.0f; + + for (int ii = ii0; ii < ii1; ii++) { + int k = ii - ii0; + + r += w[k] * src->r(ii,j); + g += w[k] * src->g(ii,j); + b += w[k] * src->b(ii,j); + } + + lr[j] = r; + lg[j] = g; + lb[j] = b; + } + + // Do horizontal interpolation + for(int j = 0; j < dst->width; j++) { + + float * wh = wwh + support * j; + + float r = 0.0f, g = 0.0f, b = 0.0f; + + for (int jj = jj0[j]; jj < jj1[j]; jj++) { + int k = jj - jj0[j]; + + r += wh[k] * lr[jj]; + g += wh[k] * lg[jj]; + b += wh[k] * lb[jj]; + } + + dst->r(i,j) = CLIP(static_cast(r)); + dst->g(i,j) = CLIP(static_cast(g)); + dst->b(i,j) = CLIP(static_cast(b)); + } + } + + delete[] wwh; + delete[] jj0; + delete[] jj1; + delete[] lr; + delete[] lg; + delete[] lb; +} +} + + +SSEFUNCTION void ImProcFunctions::Lanczos(const LabImage* src, LabImage* dst, float scale) +{ + const float delta = 1.0f / scale; + const float a = 3.0f; + const float sc = min(scale, 1.0f); + const int support = static_cast(2.0f * a / sc) + 1; + + // storage for precomputed parameters for horizontal interpolation + float * wwh = new float[support * dst->W]; + int * jj0 = new int[dst->W]; + int * jj1 = new int[dst->W]; + + // Phase 1: precompute coefficients for horizontal interpolation + for (int j = 0; j < dst->W; j++) { + + // x coord of the center of pixel on src image + float x0 = (static_cast(j) + 0.5f) * delta - 0.5f; + + // weights for interpolation in horizontal direction + float * w = wwh + j * support; + + // sum of weights used for normalization + float ws = 0.0f; + + jj0[j] = max(0, static_cast(floorf(x0 - a / sc)) + 1); + jj1[j] = min(src->W, static_cast(floorf(x0 + a / sc)) + 1); + + // calculate weights + for (int jj = jj0[j]; jj < jj1[j]; jj++) { + int k = jj - jj0[j]; + float z = sc * (x0 - static_cast(jj)); + w[k] = Lanc(z, a); + ws += w[k]; + } + + // normalize weights + for (int k = 0; k < support; k++) { + w[k] /= ws; + } + } + +#ifdef _OPENMP +#pragma omp parallel +#endif +{ + // temporal storage for vertically-interpolated row of pixels + float * lL = new float[src->W]; + float * la = new float[src->W]; + float * lb = new float[src->W]; + // weights for interpolation in y direction + float w[support] ALIGNED64; + + // Phase 2: do actual interpolation +#ifdef _OPENMP +#pragma omp for +#endif + for (int i = 0; i < dst->H; i++) { + // y coord of the center of pixel on src image + float y0 = (static_cast(i) + 0.5f) * delta - 0.5f; + + // sum of weights used for normalization + float ws = 0.0f; + + int ii0 = max(0, static_cast(floorf(y0 - a / sc)) + 1); + int ii1 = min(src->H, static_cast(floorf(y0 + a / sc)) + 1); + + // calculate weights for vertical interpolation + for (int ii = ii0; ii < ii1; ii++) { + int k = ii - ii0; + float z = sc * (y0 - static_cast(ii)); + w[k] = Lanc(z, a); + ws += w[k]; + } + + // normalize weights + for (int k = 0; k < support; k++) { + w[k] /= ws; + } + + // Do vertical interpolation. Store results. +#ifdef __SSE2__ + int j; + __m128 Lv,av,bv,wkv; + for (j = 0; j < src->W-3; j+=4) { + Lv = _mm_setzero_ps(); + av = _mm_setzero_ps(); + bv = _mm_setzero_ps(); + + for (int ii = ii0; ii < ii1; ii++) { + int k = ii - ii0; + wkv = _mm_set1_ps(w[k]); + Lv += wkv * LVFU(src->L[ii][j]); + av += wkv * LVFU(src->a[ii][j]); + bv += wkv * LVFU(src->b[ii][j]); + } + + STVF(lL[j],Lv); + STVF(la[j],av); + STVF(lb[j],bv); + } +#else + int j=0; +#endif + for (; j < src->W; j++) { + float L = 0.0f, a = 0.0f, b = 0.0f; + + for (int ii = ii0; ii < ii1; ii++) { + int k = ii - ii0; + + L += w[k] * src->L[ii][j]; + a += w[k] * src->a[ii][j]; + b += w[k] * src->b[ii][j]; + } + + lL[j] = L; + la[j] = a; + lb[j] = b; + } + + // Do horizontal interpolation + for(int j = 0; j < dst->W; j++) { + + float * wh = wwh + support * j; + + float L = 0.0f, a = 0.0f, b = 0.0f; + + for (int jj = jj0[j]; jj < jj1[j]; jj++) { + int k = jj - jj0[j]; + + L += wh[k] * lL[jj]; + a += wh[k] * la[jj]; + b += wh[k] * lb[jj]; + } + + dst->L[i][j] = L; + dst->a[i][j] = a; + dst->b[i][j] = b; + } + } + delete[] lL; + delete[] la; + delete[] lb; +} + delete[] jj0; + delete[] jj1; + delete[] wwh; +} + +float ImProcFunctions::resizeScale (const ProcParams* params, int fw, int fh, int &imw, int &imh) { + imw = fw; + imh = fh; + if (!params || !params->resize.enabled) { + return 1.0; + } + + // get the resize parameters + int refw, refh; + double dScale; + if (params->crop.enabled && params->resize.appliesTo == "Cropped area") { + // the resize values applies to the crop dimensions + refw = params->crop.w; + refh = params->crop.h; + } + else { + // the resize values applies to the image dimensions + // if a crop exists, it will be resized to the calculated scale + refw = fw; + refh = fh; + } + + switch(params->resize.dataspec) { + case (1): + // Width + dScale = (double)params->resize.width/(double)refw; + break; + case (2): + // Height + dScale = (double)params->resize.height/(double)refh; + break; + case (3): + // FitBox + if ((double)refw/(double)refh > (double)params->resize.width/(double)params->resize.height) + dScale = (double)params->resize.width/(double)refw; + else + dScale = (double)params->resize.height/(double)refh; + break; + default: + // Scale + dScale = params->resize.scale; + break; + } + + if (fabs(dScale-1.0)<=1e-5) { + return 1.0; + } + if (params->crop.enabled && params->resize.appliesTo == "Full image") { + imw = params->crop.w; + imh = params->crop.h; + } + else { + imw = refw; + imh = refh; + } + imw = (int)( (double)imw * dScale + 0.5 ); + imh = (int)( (double)imh * dScale + 0.5 ); + return (float)dScale; +} + +void ImProcFunctions::resize (Image16* src, Image16* dst, float dScale) { +#ifdef PROFILE + time_t t1 = clock(); +#endif + if(params->resize.method != "Nearest" ) { + Lanczos(src, dst, dScale); + } else { + // Nearest neighbour algorithm +#ifdef _OPENMP +#pragma omp parallel for if (multiThread) +#endif + for (int i=0; iheight; i++) { + int sy = i/dScale; + sy = LIM(sy, 0, src->height-1); + for (int j=0; jwidth; j++) { + int sx = j/dScale; + sx = LIM(sx, 0, src->width-1); + dst->r(i,j) = src->r(sy,sx); + dst->g(i,j) = src->g(sy,sx); + dst->b(i,j) = src->b(sy,sx); + } + } + } + +#ifdef PROFILE + time_t t2 = clock(); + std::cout << "Resize: " << params->resize.method << ": " + << (float)(t2 - t1) / CLOCKS_PER_SEC << std::endl; +#endif +} + +} diff --git a/rtengine/ipsharpen.cc b/rtengine/ipsharpen.cc new file mode 100644 index 000000000..ba369333a --- /dev/null +++ b/rtengine/ipsharpen.cc @@ -0,0 +1,1134 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "rtengine.h" +#include "improcfun.h" +#include "gauss.h" +#include "bilateral2.h" +#include "rt_math.h" +#include "sleef.c" +#include "opthelper.h" + +using namespace std; + +namespace rtengine { + +#undef ABS + +#define ABS(a) ((a)<0?-(a):(a)) +#define CLIREF(x) LIM(x,-200000.0f,200000.0f) // avoid overflow : do not act directly on image[] or pix[] + + +extern const Settings* settings; +SSEFUNCTION void ImProcFunctions::dcdamping (float** aI, float** aO, float damping, int W, int H) { + + const float dampingFac=-2.0/(damping*damping); + +#ifdef __SSE2__ + __m128 Iv,Ov,Uv,zerov,onev,fourv,fivev,dampingFacv,Tv; + zerov = _mm_setzero_ps( ); + onev = _mm_set1_ps( 1.0f ); + fourv = _mm_set1_ps( 4.0f ); + fivev = _mm_set1_ps( 5.0f ); + dampingFacv = _mm_set1_ps( dampingFac ); +#ifdef _OPENMP +#pragma omp for +#endif + for (int i=0; iW, H = lab->H; + + float** tmpI = new float*[H]; + for (int i=0; iL[i][j]; + } + + float** tmp = (float**)b2; + +#ifdef _OPENMP +#pragma omp parallel +#endif + { + AlignedBufferMP buffer(max(W,H)); + + float damping = sharpenParam.deconvdamping / 5.0; + bool needdamp = sharpenParam.deconvdamping > 0; + for (int k=0; k (tmpI, tmp, buffer, W, H, sharpenParam.deconvradius / scale); + gaussVertical (tmp, tmp, buffer, W, H, sharpenParam.deconvradius / scale); + + if (!needdamp) { +#ifdef _OPENMP +#pragma omp for +#endif + for (int i=0; i0) + tmp[i][j] = (float)lab->L[i][j] / tmp[i][j]; + } + else + dcdamping (tmp, lab->L, damping, W, H); + + gaussHorizontal (tmp, tmp, buffer, W, H, sharpenParam.deconvradius / scale); + gaussVertical (tmp, tmp, buffer, W, H, sharpenParam.deconvradius / scale); + +#ifdef _OPENMP +#pragma omp for +#endif + for (int i=0; iL[i][j] = lab->L[i][j]*p1 + max(tmpI[i][j],0.0f)*p2; + + } // end parallel + + for (int i=0; iW<8 || lab->H<8) + return; + + int W = lab->W, H = lab->H; + float** b3 = NULL; + float** labCopy = NULL; + + if (sharpenParam.edgesonly) { + b3 = new float*[H]; + for (int i=0; i buffer(max(W,H)); + if (sharpenParam.edgesonly==false) { + + gaussHorizontal (lab->L, b2, buffer, W, H, sharpenParam.radius / scale); + gaussVertical (b2, b2, buffer, W, H, sharpenParam.radius / scale); + } + else { + bilateral (lab->L, (float**)b3, b2, W, H, sharpenParam.edges_radius / scale, sharpenParam.edges_tolerance, multiThread); + gaussHorizontal (b3, b2, buffer, W, H, sharpenParam.radius / scale); + gaussVertical (b2, b2, buffer, W, H, sharpenParam.radius / scale); + } + + float** base = lab->L; + if (sharpenParam.edgesonly) + base = b3; + + if (sharpenParam.halocontrol==false) { +#ifdef _OPENMP +#pragma omp for +#endif + for (int i=0; i( + min(ABS(diff), upperBound), // X axis value = absolute value of the difference, truncated to the max value of this field + sharpenParam.amount * diff * 0.01f // Y axis max value + ); + lab->L[i][j] = lab->L[i][j] + delta; + } + } + else { + if (!sharpenParam.edgesonly) { + // make a deep copy of lab->L +#ifdef _OPENMP +#pragma omp for +#endif + for( int i=0; iL[i][j]; + base = labCopy; + } + sharpenHaloCtrl (lab, b2, base, W, H, sharpenParam); + } + + } // end parallel + + if (sharpenParam.halocontrol && !sharpenParam.edgesonly) { + // delete the deep copy + for( int i=0; iL[i][j]; + if (max_ < labL) max_ = labL; + if (min_ > labL) min_ = labL; + + // deviation from the environment as measurement + float diff = nL[i][j] - blurmap[i][j]; + + const float upperBound = 2000.f; // WARNING: Duplicated value, it's baaaaaad ! + float delta = sharpenParam.threshold.multiply( + min(ABS(diff), upperBound), // X axis value = absolute value of the difference + sharpFac * diff // Y axis max value = sharpening.amount * signed difference + ); + float newL = labL + delta; + // applying halo control + if (newL > max_) + newL = max_ + (newL-max_) * scale; + else if (newL < min_) + newL = min_ - (min_-newL) * scale; + + lab->L[i][j] = newL; + } + } +} + +// To the extent possible under law, Manuel Llorens +// has waived all copyright and related or neighboring rights to this work. +// This work is published from: Spain. + +// Thanks to Manuel for this excellent job (Jacques Desmis JDC or frej83) +void ImProcFunctions::MLsharpen (LabImage* lab) { + // JD: this algorithm maximize clarity of images; it does not play on accutance. It can remove (partialy) the effects of the AA filter) + // I think we can use this algorithm alone in most cases, or first to clarify image and if you want a very little USM (unsharp mask sharpening) after... + if (params->sharpenEdge.enabled==false) + return; + MyTime t1e,t2e; + t1e.set(); + + int offset,c,i,j,p,width2; + int width = lab->W, height = lab->H; + float *L,lumH,lumV,lumD1,lumD2,v,contrast,s; + float difL,difR,difT,difB,difLT,difRB,difLB,difRT,wH,wV,wD1,wD2,chmax[3]; + float f1,f2,f3,f4; + float templab; + int iii,kkk; + width2 = 2*width; + const float epsil=0.01f;//prevent divide by zero + const float eps2=0.001f;//prevent divide by zero + float amount; + amount = params->sharpenEdge.amount / 100.0f; + if (amount < 0.00001f) + return; + + if (settings->verbose) + printf ("SharpenEdge amount %f\n", amount); + + L = new float[width*height]; + + chmax[0] = 8.0f; + chmax[1] = 3.0f; + chmax[2] = 3.0f; + + int channels; + if (params->sharpenEdge.threechannels) channels=0; else channels=2; + if (settings->verbose) + printf ("SharpenEdge channels %d\n", channels); + + int passes=params->sharpenEdge.passes; + if (settings->verbose) + printf ("SharpenEdge passes %d\n", passes); + + for (p=0; pL[ii][kk]/327.68f; // adjust to RT and to 0..100 + else if (c==1) L[offset] = lab->a[ii][kk]/327.68f; + else /*if (c==2) */ L[offset] = lab->b[ii][kk]/327.68f; + } +#ifdef _OPENMP +#pragma omp parallel for private(j,i,iii,kkk, templab,offset,wH,wV,wD1,wD2,s,lumH,lumV,lumD1,lumD2,v,contrast,f1,f2,f3,f4,difT,difB,difL,difR,difLT,difLB,difRT,difRB) shared(lab,L,amount) +#endif + for(j=2; jL[ii][kk]/327.68f; + else if (c==1) lumH=lumV=lumD1=lumD2=v=lab->a[ii][kk]/327.68f; + else /* if (c==2) */ lumH=lumV=lumD1=lumD2=v=lab->b[ii][kk]/327.68f; + + + // contrast detection + contrast = sqrt(fabs(L[offset+1]-L[offset-1])*fabs(L[offset+1]-L[offset-1])+fabs(L[offset+width]-L[offset-width])*fabs(L[offset+width]-L[offset-width]))/chmax[c]; + if (contrast>1.0f) + contrast=1.0f; + + // new possible values + if (((L[offset]L[offset+1])) || ((L[offset]>L[offset-1])&&(L[offset]epsil)&&(difL>epsil)){ + lumH = (L[offset-1]*difR+L[offset+1]*difL)/(difL+difR); + lumH = v*(1.f-contrast)+lumH*contrast; + } + } + + if (((L[offset]L[offset+width])) || ((L[offset]>L[offset-width])&&(L[offset]epsil)&&(difT>epsil)){ + lumV = (L[offset-width]*difB+L[offset+width]*difT)/(difT+difB); + lumV = v*(1.f-contrast)+lumV*contrast; + } + } + + if (((L[offset]L[offset+1+width])) || ((L[offset]>L[offset-1-width])&&(L[offset]epsil)&&(difRB>epsil)) { + lumD1 = (L[offset-1-width]*difRB+L[offset+1+width]*difLT)/(difLT+difRB); + lumD1 = v*(1.f-contrast)+lumD1*contrast; + } + } + + if (((L[offset]L[offset-1+width])) || ((L[offset]>L[offset+1-width])&&(L[offset]epsil)&&(difRT>epsil)) { + lumD2 = (L[offset+1-width]*difLB+L[offset-1+width]*difRT)/(difLB+difRT); + lumD2 = v*(1.f-contrast)+lumD2*contrast; + } + } + + s = amount; + + // avoid sharpening diagonals too much + if (((fabs(wH/wV)<0.45f)&&(fabs(wH/wV)>0.05f))||((fabs(wV/wH)<0.45f)&&(fabs(wV/wH)>0.05f))) + s = amount/3.0f; + + // final mix + if ((wH!=0.0f)&&(wV!=0.0f)&&(wD1!=0.0f)&&(wD2!=0.0f)) { + iii = offset/width; + kkk = offset-iii*width; + float provL=lab->L[iii][kkk]/327.68f; + if(c==0){ if(provL < 92.f) templab = v*(1.f-s)+(lumH*wH+lumV*wV+lumD1*wD1+lumD2*wD2)/(wH+wV+wD1+wD2)*s; else templab=provL;} + else templab = v*(1.f-s)+(lumH*wH+lumV*wV+lumD1*wD1+lumD2*wD2)/(wH+wV+wD1+wD2)*s; + if (c==0) lab->L[iii][kkk] = fabs(327.68f*templab); // fabs because lab->L always >0 + else if (c==1) lab->a[iii][kkk] = 327.68f*templab ; + else if (c==2) lab->b[iii][kkk] = 327.68f*templab ; + } + + } + } + + delete [] L; + + t2e.set(); + if (settings->verbose) + printf("SharpenEdge gradient %d usec\n", t2e.etime(t1e)); +} + +// To the extent possible under law, Manuel Llorens +// has waived all copyright and related or neighboring rights to this work. +// This code is licensed under CC0 v1.0, see license information at +// http://creativecommons.org/publicdomain/zero/1.0/ + +//! MicroContrast is a sharpening method developed by Manuel Llorens and documented here: http://www.rawness.es/sharpening/?lang=en +//!
The purpose is maximize clarity of the image without creating halo's. +//!
Addition from JD : pyramid + pondered contrast with matrix 5x5 +//! \param lab LabImage Image in the CIELab colour space +void ImProcFunctions::MLmicrocontrast(LabImage* lab) { + if (params->sharpenMicro.enabled==false) + return; + MyTime t1e,t2e; + t1e.set(); + int k; + if (params->sharpenMicro.matrix == false) k=2; else k=1; + // k=2 matrix 5x5 k=1 matrix 3x3 + int offset,offset2,i,j,col,row,n; + float temp,temp2,temp3,temp4,tempL; + float *LM,v,s,contrast; + int signs[25]; + int width = lab->W, height = lab->H; + float uniform = params->sharpenMicro.uniformity;//between 0 to 100 + int unif; + unif = (int)(uniform/10.0f); //put unif between 0 to 10 + float amount = params->sharpenMicro.amount/1500.0f; //amount 2000.0 quasi no artefacts ==> 1500 = maximum, after artefacts + if (amount < 0.000001f) + return; + if (k==1) + amount *= 2.7f; //25/9 if 3x3 + if (settings->verbose) + printf ("Micro-contrast amount %f\n", amount); + if (settings->verbose) + printf ("Micro-contrast uniformity %i\n",unif); + //modulation uniformity in function of luminance + float L98[11] = {0.001f,0.0015f,0.002f,0.004f,0.006f,0.008f,0.01f,0.03f,0.05f,0.1f,0.1f}; + float L95[11] = {0.0012f,0.002f,0.005f,0.01f,0.02f,0.05f,0.1f,0.12f,0.15f,0.2f,0.25f}; + float L92[11] = {0.01f,0.015f,0.02f,0.06f,0.10f,0.13f,0.17f,0.25f,0.3f,0.32f,0.35f}; + float L90[11] = {0.015f,0.02f,0.04f,0.08f,0.12f,0.15f,0.2f,0.3f,0.4f,0.5f,0.6f}; + float L87[11] = {0.025f,0.03f,0.05f,0.1f,0.15f,0.25f,0.3f,0.4f,0.5f,0.63f,0.75f}; + float L83[11] = {0.055f,0.08f,0.1f,0.15f,0.2f,0.3f,0.4f,0.5f,0.6f,0.75f,0.85f}; + float L80[11] = {0.15f,0.2f,0.25f,0.3f,0.35f,0.4f,0.5f,0.6f,0.7f,0.8f,0.9f}; + float L75[11] = {0.22f,0.25f,0.3f,0.4f,0.5f,0.6f,0.7f,0.8f,0.85f,0.9f,0.95f}; + float L70[11] = {0.35f,0.4f,0.5f,0.6f,0.7f,0.8f,0.97f,1.0f,1.0f,1.0f,1.0f}; + float L63[11] = {0.55f,0.6f,0.7f,0.8f,0.85f,0.9f,1.0f,1.0f,1.0f,1.0f,1.0f}; + float L58[11] = {0.75f,0.77f,0.8f,0.9f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f}; + //default 5 + //modulation contrast + float Cont0[11] = {0.05f,0.1f,0.2f,0.25f,0.3f,0.4f,0.5f,0.6f,0.7f,0.8f,0.9f}; + float Cont1[11] = {0.1f,0.2f,0.3f,0.4f,0.5f,0.6f,0.7f,0.8f,0.9f,0.95f,1.0f}; + float Cont2[11] = {0.2f,0.40f,0.6f,0.7f,0.8f,0.85f,0.90f,0.95f,1.0f,1.05f,1.10f}; + float Cont3[11] = {0.5f,0.6f,0.7f,0.8f,0.85f,0.9f,1.0f,1.0f,1.05f,1.10f,1.20f}; + float Cont4[11] = {0.8f,0.85f,0.9f,0.95f,1.0f,1.05f,1.10f,1.150f,1.2f,1.25f,1.40f}; + float Cont5[11] = {1.0f,1.1f,1.2f,1.25f,1.3f,1.4f,1.45f,1.50f,1.6f,1.65f,1.80f}; + + float chmax=8.0f; + LM = new float[width*height];//allocation for Luminance +#ifdef _OPENMP +#pragma omp parallel for private(offset, i,j) shared(LM) +#endif + for(j=0; jL[j][i]/327.68f;// adjust to 0.100 and to RT variables + } + +#ifdef _OPENMP +#pragma omp parallel for private(j,i,offset,s,signs,v,n,row,col,offset2,contrast,temp,temp2,temp3,tempL,temp4) shared(lab,LM,amount,chmax,unif,k,L98,L95,L92,L90,L87,L83,L80,L75,L70,L63,L58,Cont0,Cont1,Cont2,Cont3,Cont4,Cont5) +#endif + for(j=k; jLM[offset2]) signs[n]=1; + n++; + } + if (k==1) contrast = sqrt(fabs(LM[offset+1]-LM[offset-1])*fabs(LM[offset+1]-LM[offset-1])+fabs(LM[offset+width]-LM[offset-width])*fabs(LM[offset+width]-LM[offset-width]))/chmax; //for 3x3 + else /* if (k==2) */ contrast = sqrt(fabs(LM[offset+1]-LM[offset-1])*fabs(LM[offset+1]-LM[offset-1])+fabs(LM[offset+width]-LM[offset-width])*fabs(LM[offset+width]-LM[offset-width]) + +fabs(LM[offset+2]-LM[offset-2])*fabs(LM[offset+2]-LM[offset-2])+fabs(LM[offset+2*width]-LM[offset-2*width])*fabs(LM[offset+2*width]-LM[offset-2*width]))/(2*chmax); //for 5x5 + + if (contrast>1.0f) + contrast=1.0f; + //matrix 5x5 + temp=lab->L[j][i]/327.68f; //begin 3x3 + temp += CLIREF(v-LM[offset-width-1])*sqrtf(2.0f)*s; + temp += CLIREF(v-LM[offset-width])*s; + temp += CLIREF(v-LM[offset-width+1])*sqrtf(2.0f)*s; + temp += CLIREF(v-LM[offset-1])*s; + temp += CLIREF(v-LM[offset+1])*s; + temp += CLIREF(v-LM[offset+width-1])*sqrtf(2.0f)*s; + temp += CLIREF(v-LM[offset+width])*s; + temp += CLIREF(v-LM[offset+width+1])*sqrtf(2.0f)*s;//end 3x3 + + // add JD continue 5x5 + if (k==2) { + temp += 2.0f*CLIREF(v-LM[offset+2*width])*s; + temp += 2.0f*CLIREF(v-LM[offset-2*width])*s; + temp += 2.0f*CLIREF(v-LM[offset-2 ])*s; + temp += 2.0f*CLIREF(v-LM[offset+2 ])*s; + + temp += 2.0f*CLIREF(v-LM[offset+2*width-1])*s*sqrtf(1.25f);// 1.25 = 1*1 + 0.5*0.5 + temp += 2.0f*CLIREF(v-LM[offset+2*width-2])*s*sqrtf(2.00f); + temp += 2.0f*CLIREF(v-LM[offset+2*width+1])*s*sqrtf(1.25f); + temp += 2.0f*CLIREF(v-LM[offset+2*width+2])*s*sqrtf(2.00f); + temp += 2.0f*CLIREF(v-LM[offset+ width+2])*s*sqrtf(1.25f); + temp += 2.0f*CLIREF(v-LM[offset+ width-2])*s*sqrtf(1.25f); + temp += 2.0f*CLIREF(v-LM[offset-2*width-1])*s*sqrtf(1.25f); + temp += 2.0f*CLIREF(v-LM[offset-2*width-2])*s*sqrtf(2.00f); + temp += 2.0f*CLIREF(v-LM[offset-2*width+1])*s*sqrtf(1.25f); + temp += 2.0f*CLIREF(v-LM[offset-2*width+2])*s*sqrtf(2.00f); + temp += 2.0f*CLIREF(v-LM[offset- width+2])*s*sqrtf(1.25f); + temp += 2.0f*CLIREF(v-LM[offset- width-2])*s*sqrtf(1.25f); + } + if (temp <0.0f) temp = 0.0f; + v=temp; + + n=0; + + for(row=j-k; row<=j+k; row++){ + for(col=i-k,offset2=row*width+col; col<=i+k; col++,offset2++){ + if (((v0))||((v>LM[offset2])&&(signs[n]<0))) { + temp = v*0.75f+LM[offset2]*0.25f;// 0.75 0.25 + } + n++; + } + } + if (LM[offset]>95.0f || LM[offset]<5.0f) + contrast *= Cont0[unif]; //+ JD : luminance pyramid to adjust contrast by evaluation of LM[offset] + else if (LM[offset]>90.0f || LM[offset]<10.0f) + contrast *= Cont1[unif]; + else if (LM[offset]>80.0f || LM[offset]<20.0f) + contrast *= Cont2[unif]; + else if (LM[offset]>70.0f || LM[offset]<30.0f) + contrast *= Cont3[unif]; + else if (LM[offset]>60.0f || LM[offset]<40.0f) + contrast *= Cont4[unif]; + else + contrast *= Cont5[unif];//(2.0f/k)*Cont5[unif]; + + if (contrast>1.0f) + contrast=1.0f; + tempL = 327.68f*(temp*(1.0f-contrast)+LM[offset]*contrast); + // JD: modulation of microcontrast in function of original Luminance and modulation of luminance + temp2 = tempL/(327.68f*LM[offset]);//for highlights + if (temp2>1.0f) { + if (temp2>1.70f) temp2=1.70f;//limit action + if (LM[offset]>98.0f) { lab->L[j][i]=LM[offset]*327.68f; } + else if (LM[offset]>95.0f) { temp3=temp2-1.0f; temp=(L95[unif]*temp3)+1.0f; lab->L[j][i]=temp*LM[offset]*327.68f; } + else if (LM[offset]>92.0f) { temp3=temp2-1.0f; temp=(L92[unif]*temp3)+1.0f; lab->L[j][i]=temp*LM[offset]*327.68f; } + else if (LM[offset]>90.0f) { temp3=temp2-1.0f; temp=(L90[unif]*temp3)+1.0f; lab->L[j][i]=temp*LM[offset]*327.68f; } + else if (LM[offset]>87.0f) { temp3=temp2-1.0f; temp=(L87[unif]*temp3)+1.0f; lab->L[j][i]=temp*LM[offset]*327.68f; } + else if (LM[offset]>83.0f) { temp3=temp2-1.0f; temp=(L83[unif]*temp3)+1.0f; lab->L[j][i]=temp*LM[offset]*327.68f; } + else if (LM[offset]>80.0f) { temp3=temp2-1.0f; temp=(L80[unif]*temp3)+1.0f; lab->L[j][i]=temp*LM[offset]*327.68f; } + else if (LM[offset]>75.0f) { temp3=temp2-1.0f; temp=(L75[unif]*temp3)+1.0f; lab->L[j][i]=temp*LM[offset]*327.68f; } + else if (LM[offset]>70.0f) { temp3=temp2-1.0f; temp=(L70[unif]*temp3)+1.0f; lab->L[j][i]=temp*LM[offset]*327.68f; } + else if (LM[offset]>63.0f) { temp3=temp2-1.0f; temp=(L63[unif]*temp3)+1.0f; lab->L[j][i]=temp*LM[offset]*327.68f; } + else if (LM[offset]>58.0f) { temp3=temp2-1.0f; temp=(L58[unif]*temp3)+1.0f; lab->L[j][i]=temp*LM[offset]*327.68f; } + else if (LM[offset]>42.0f) { temp3=temp2-1.0f; temp=(L58[unif]*temp3)+1.0f; lab->L[j][i]=temp*LM[offset]*327.68f; } + else if (LM[offset]>37.0f) { temp3=temp2-1.0f; temp=(L63[unif]*temp3)+1.0f; lab->L[j][i]=temp*LM[offset]*327.68f; } + else if (LM[offset]>30.0f) { temp3=temp2-1.0f; temp=(L70[unif]*temp3)+1.0f; lab->L[j][i]=temp*LM[offset]*327.68f; } + else if (LM[offset]>25.0f) { temp3=temp2-1.0f; temp=(L75[unif]*temp3)+1.0f; lab->L[j][i]=temp*LM[offset]*327.68f; } + else if (LM[offset]>20.0f) { temp3=temp2-1.0f; temp=(L80[unif]*temp3)+1.0f; lab->L[j][i]=temp*LM[offset]*327.68f; } + else if (LM[offset]>17.0f) { temp3=temp2-1.0f; temp=(L83[unif]*temp3)+1.0f; lab->L[j][i]=temp*LM[offset]*327.68f; } + else if (LM[offset]>13.0f) { temp3=temp2-1.0f; temp=(L87[unif]*temp3)+1.0f; lab->L[j][i]=temp*LM[offset]*327.68f; } + else if (LM[offset]>10.0f) { temp3=temp2-1.0f; temp=(L90[unif]*temp3)+1.0f; lab->L[j][i]=temp*LM[offset]*327.68f; } + else if (LM[offset]> 5.0f) { temp3=temp2-1.0f; temp=(L95[unif]*temp3)+1.0f; lab->L[j][i]=temp*LM[offset]*327.68f; } + else if (LM[offset]> 0.0f) { lab->L[j][i]=LM[offset]*327.68f;} + } + temp4 = (327.68f*LM[offset])/tempL;// + if (temp4>1.0f) { + if (temp4>1.7f) + temp4 = 1.7f;//limit action + if (LM[offset]< 2.0f) { temp3=temp4-1.0f; temp=(L98[unif]*temp3)+1.0f; lab->L[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]< 5.0f) { temp3=temp4-1.0f; temp=(L95[unif]*temp3)+1.0f; lab->L[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]< 8.0f) { temp3=temp4-1.0f; temp=(L92[unif]*temp3)+1.0f; lab->L[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]<10.0f) { temp3=temp4-1.0f; temp=(L90[unif]*temp3)+1.0f; lab->L[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]<13.0f) { temp3=temp4-1.0f; temp=(L87[unif]*temp3)+1.0f; lab->L[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]<17.0f) { temp3=temp4-1.0f; temp=(L83[unif]*temp3)+1.0f; lab->L[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]<20.0f) { temp3=temp4-1.0f; temp=(L80[unif]*temp3)+1.0f; lab->L[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]<25.0f) { temp3=temp4-1.0f; temp=(L75[unif]*temp3)+1.0f; lab->L[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]<30.0f) { temp3=temp4-1.0f; temp=(L70[unif]*temp3)+1.0f; lab->L[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]<37.0f) { temp3=temp4-1.0f; temp=(L63[unif]*temp3)+1.0f; lab->L[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]<42.0f) { temp3=temp4-1.0f; temp=(L58[unif]*temp3)+1.0f; lab->L[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]<58.0f) { temp3=temp4-1.0f; temp=(L58[unif]*temp3)+1.0f; lab->L[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]<63.0f) { temp3=temp4-1.0f; temp=(L63[unif]*temp3)+1.0f; lab->L[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]<70.0f) { temp3=temp4-1.0f; temp=(L70[unif]*temp3)+1.0f; lab->L[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]<75.0f) { temp3=temp4-1.0f; temp=(L75[unif]*temp3)+1.0f; lab->L[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]<80.0f) { temp3=temp4-1.0f; temp=(L80[unif]*temp3)+1.0f; lab->L[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]<83.0f) { temp3=temp4-1.0f; temp=(L83[unif]*temp3)+1.0f; lab->L[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]<87.0f) { temp3=temp4-1.0f; temp=(L87[unif]*temp3)+1.0f; lab->L[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]<90.0f) { temp3=temp4-1.0f; temp=(L90[unif]*temp3)+1.0f; lab->L[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]<95.0f) { temp3=temp4-1.0f; temp=(L95[unif]*temp3)+1.0f; lab->L[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]<100.0f) { lab->L[j][i]=LM[offset]*327.68f; } + } + + } + delete [] LM; + t2e.set(); + if (settings->verbose) + printf("Micro-contrast %d usec\n", t2e.etime(t1e)); + +} + +//! MicroContrast is a sharpening method developed by Manuel Llorens and documented here: http://www.rawness.es/sharpening/?lang=en +//!
The purpose is maximize clarity of the image without creating halo's. +//!
Addition from JD : pyramid + pondered contrast with matrix 5x5 +//! \param ncie CieImage Image in the CIECAM02 colour space +void ImProcFunctions::MLmicrocontrastcam(CieImage* ncie) { + if (params->sharpenMicro.enabled==false) + return; + MyTime t1e,t2e; + t1e.set(); + int k; + if (params->sharpenMicro.matrix == false) k=2; else k=1; + // k=2 matrix 5x5 k=1 matrix 3x3 + int offset,offset2,i,j,col,row,n; + float temp,temp2,temp3,temp4,tempL; + float *LM,v,s,contrast; + int signs[25]; + int width = ncie->W, height = ncie->H; + float uniform = params->sharpenMicro.uniformity;//between 0 to 100 + int unif; + unif = (int)(uniform/10.0f); //put unif between 0 to 10 + float amount = params->sharpenMicro.amount/1500.0f; //amount 2000.0 quasi no artefacts ==> 1500 = maximum, after artefacts + if (amount < 0.000001f) + return; + if (k==1) + amount *= 2.7f; //25/9 if 3x3 + if (settings->verbose) + printf ("Micro-contrast amount %f\n", amount); + if (settings->verbose) + printf ("Micro-contrast uniformity %i\n",unif); + //modulation uniformity in function of luminance + float L98[11] = {0.001f,0.0015f,0.002f,0.004f,0.006f,0.008f,0.01f,0.03f,0.05f,0.1f,0.1f}; + float L95[11] = {0.0012f,0.002f,0.005f,0.01f,0.02f,0.05f,0.1f,0.12f,0.15f,0.2f,0.25f}; + float L92[11] = {0.01f,0.015f,0.02f,0.06f,0.10f,0.13f,0.17f,0.25f,0.3f,0.32f,0.35f}; + float L90[11] = {0.015f,0.02f,0.04f,0.08f,0.12f,0.15f,0.2f,0.3f,0.4f,0.5f,0.6f}; + float L87[11] = {0.025f,0.03f,0.05f,0.1f,0.15f,0.25f,0.3f,0.4f,0.5f,0.63f,0.75f}; + float L83[11] = {0.055f,0.08f,0.1f,0.15f,0.2f,0.3f,0.4f,0.5f,0.6f,0.75f,0.85f}; + float L80[11] = {0.15f,0.2f,0.25f,0.3f,0.35f,0.4f,0.5f,0.6f,0.7f,0.8f,0.9f}; + float L75[11] = {0.22f,0.25f,0.3f,0.4f,0.5f,0.6f,0.7f,0.8f,0.85f,0.9f,0.95f}; + float L70[11] = {0.35f,0.4f,0.5f,0.6f,0.7f,0.8f,0.97f,1.0f,1.0f,1.0f,1.0f}; + float L63[11] = {0.55f,0.6f,0.7f,0.8f,0.85f,0.9f,1.0f,1.0f,1.0f,1.0f,1.0f}; + float L58[11] = {0.75f,0.77f,0.8f,0.9f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f}; + //default 5 + //modulation contrast + float Cont0[11] = {0.05f,0.1f,0.2f,0.25f,0.3f,0.4f,0.5f,0.6f,0.7f,0.8f,0.9f}; + float Cont1[11] = {0.1f,0.2f,0.3f,0.4f,0.5f,0.6f,0.7f,0.8f,0.9f,0.95f,1.0f}; + float Cont2[11] = {0.2f,0.40f,0.6f,0.7f,0.8f,0.85f,0.90f,0.95f,1.0f,1.05f,1.10f}; + float Cont3[11] = {0.5f,0.6f,0.7f,0.8f,0.85f,0.9f,1.0f,1.0f,1.05f,1.10f,1.20f}; + float Cont4[11] = {0.8f,0.85f,0.9f,0.95f,1.0f,1.05f,1.10f,1.150f,1.2f,1.25f,1.40f}; + float Cont5[11] = {1.0f,1.1f,1.2f,1.25f,1.3f,1.4f,1.45f,1.50f,1.6f,1.65f,1.80f}; + + float chmax=8.0f; + LM = new float[width*height];//allocation for Luminance +#ifdef _OPENMP +#pragma omp parallel for private(offset, i,j) shared(LM) +#endif + for(j=0; jsh_p[j][i]/327.68f;// adjust to 0.100 and to RT variables + } + +#ifdef _OPENMP +#pragma omp parallel for private(j,i,offset,s,signs,v,n,row,col,offset2,contrast,temp,temp2,temp3,tempL,temp4) shared(ncie,LM,amount,chmax,unif,k,L98,L95,L92,L90,L87,L83,L80,L75,L70,L63,L58,Cont0,Cont1,Cont2,Cont3,Cont4,Cont5) +#endif + for(j=k; jLM[offset2]) signs[n]=1; + n++; + } + if (k==1) contrast = sqrt(fabs(LM[offset+1]-LM[offset-1])*fabs(LM[offset+1]-LM[offset-1])+fabs(LM[offset+width]-LM[offset-width])*fabs(LM[offset+width]-LM[offset-width]))/chmax; //for 3x3 + else /* if (k==2) */ contrast = sqrt(fabs(LM[offset+1]-LM[offset-1])*fabs(LM[offset+1]-LM[offset-1])+fabs(LM[offset+width]-LM[offset-width])*fabs(LM[offset+width]-LM[offset-width]) + +fabs(LM[offset+2]-LM[offset-2])*fabs(LM[offset+2]-LM[offset-2])+fabs(LM[offset+2*width]-LM[offset-2*width])*fabs(LM[offset+2*width]-LM[offset-2*width]))/(2*chmax); //for 5x5 + + if (contrast>1.0f) + contrast=1.0f; + //matrix 5x5 + temp=ncie->sh_p[j][i]/327.68f; //begin 3x3 + temp += CLIREF(v-LM[offset-width-1])*sqrtf(2.0f)*s; + temp += CLIREF(v-LM[offset-width])*s; + temp += CLIREF(v-LM[offset-width+1])*sqrtf(2.0f)*s; + temp += CLIREF(v-LM[offset-1])*s; + temp += CLIREF(v-LM[offset+1])*s; + temp += CLIREF(v-LM[offset+width-1])*sqrtf(2.0f)*s; + temp += CLIREF(v-LM[offset+width])*s; + temp += CLIREF(v-LM[offset+width+1])*sqrtf(2.0f)*s;//end 3x3 + + // add JD continue 5x5 + if (k==2) { + temp += 2.0f*CLIREF(v-LM[offset+2*width])*s; + temp += 2.0f*CLIREF(v-LM[offset-2*width])*s; + temp += 2.0f*CLIREF(v-LM[offset-2 ])*s; + temp += 2.0f*CLIREF(v-LM[offset+2 ])*s; + + temp += 2.0f*CLIREF(v-LM[offset+2*width-1])*s*sqrtf(1.25f);// 1.25 = 1*1 + 0.5*0.5 + temp += 2.0f*CLIREF(v-LM[offset+2*width-2])*s*sqrtf(2.00f); + temp += 2.0f*CLIREF(v-LM[offset+2*width+1])*s*sqrtf(1.25f); + temp += 2.0f*CLIREF(v-LM[offset+2*width+2])*s*sqrtf(2.00f); + temp += 2.0f*CLIREF(v-LM[offset+ width+2])*s*sqrtf(1.25f); + temp += 2.0f*CLIREF(v-LM[offset+ width-2])*s*sqrtf(1.25f); + temp += 2.0f*CLIREF(v-LM[offset-2*width-1])*s*sqrtf(1.25f); + temp += 2.0f*CLIREF(v-LM[offset-2*width-2])*s*sqrtf(2.00f); + temp += 2.0f*CLIREF(v-LM[offset-2*width+1])*s*sqrtf(1.25f); + temp += 2.0f*CLIREF(v-LM[offset-2*width+2])*s*sqrtf(2.00f); + temp += 2.0f*CLIREF(v-LM[offset- width+2])*s*sqrtf(1.25f); + temp += 2.0f*CLIREF(v-LM[offset- width-2])*s*sqrtf(1.25f); + } + if (temp <0.0f) temp = 0.0f; + v=temp; + + n=0; + + for(row=j-k; row<=j+k; row++){ + for(col=i-k,offset2=row*width+col; col<=i+k; col++,offset2++){ + if (((v0))||((v>LM[offset2])&&(signs[n]<0))) { + temp = v*0.75f+LM[offset2]*0.25f;// 0.75 0.25 + } + n++; + } + } + if (LM[offset]>95.0f || LM[offset]<5.0f) + contrast *= Cont0[unif]; //+ JD : luminance pyramid to adjust contrast by evaluation of LM[offset] + else if (LM[offset]>90.0f || LM[offset]<10.0f) + contrast *= Cont1[unif]; + else if (LM[offset]>80.0f || LM[offset]<20.0f) + contrast *= Cont2[unif]; + else if (LM[offset]>70.0f || LM[offset]<30.0f) + contrast *= Cont3[unif]; + else if (LM[offset]>60.0f || LM[offset]<40.0f) + contrast *= Cont4[unif]; + else + contrast *= Cont5[unif];//(2.0f/k)*Cont5[unif]; + + if (contrast>1.0f) + contrast=1.0f; + tempL = 327.68f*(temp*(1.0f-contrast)+LM[offset]*contrast); + // JD: modulation of microcontrast in function of original Luminance and modulation of luminance + temp2 = tempL/(327.68f*LM[offset]);//for highlights + if (temp2>1.0f) { + if (temp2>1.70f) temp2=1.70f;//limit action + if (LM[offset]>98.0f) { ncie->sh_p[j][i]=LM[offset]*327.68f; } + else if (LM[offset]>95.0f) { temp3=temp2-1.0f; temp=(L95[unif]*temp3)+1.0f; ncie->sh_p[j][i]=temp*LM[offset]*327.68f; } + else if (LM[offset]>92.0f) { temp3=temp2-1.0f; temp=(L92[unif]*temp3)+1.0f; ncie->sh_p[j][i]=temp*LM[offset]*327.68f; } + else if (LM[offset]>90.0f) { temp3=temp2-1.0f; temp=(L90[unif]*temp3)+1.0f; ncie->sh_p[j][i]=temp*LM[offset]*327.68f; } + else if (LM[offset]>87.0f) { temp3=temp2-1.0f; temp=(L87[unif]*temp3)+1.0f; ncie->sh_p[j][i]=temp*LM[offset]*327.68f; } + else if (LM[offset]>83.0f) { temp3=temp2-1.0f; temp=(L83[unif]*temp3)+1.0f; ncie->sh_p[j][i]=temp*LM[offset]*327.68f; } + else if (LM[offset]>80.0f) { temp3=temp2-1.0f; temp=(L80[unif]*temp3)+1.0f; ncie->sh_p[j][i]=temp*LM[offset]*327.68f; } + else if (LM[offset]>75.0f) { temp3=temp2-1.0f; temp=(L75[unif]*temp3)+1.0f; ncie->sh_p[j][i]=temp*LM[offset]*327.68f; } + else if (LM[offset]>70.0f) { temp3=temp2-1.0f; temp=(L70[unif]*temp3)+1.0f; ncie->sh_p[j][i]=temp*LM[offset]*327.68f; } + else if (LM[offset]>63.0f) { temp3=temp2-1.0f; temp=(L63[unif]*temp3)+1.0f; ncie->sh_p[j][i]=temp*LM[offset]*327.68f; } + else if (LM[offset]>58.0f) { temp3=temp2-1.0f; temp=(L58[unif]*temp3)+1.0f; ncie->sh_p[j][i]=temp*LM[offset]*327.68f; } + else if (LM[offset]>42.0f) { temp3=temp2-1.0f; temp=(L58[unif]*temp3)+1.0f; ncie->sh_p[j][i]=temp*LM[offset]*327.68f; } + else if (LM[offset]>37.0f) { temp3=temp2-1.0f; temp=(L63[unif]*temp3)+1.0f; ncie->sh_p[j][i]=temp*LM[offset]*327.68f; } + else if (LM[offset]>30.0f) { temp3=temp2-1.0f; temp=(L70[unif]*temp3)+1.0f; ncie->sh_p[j][i]=temp*LM[offset]*327.68f; } + else if (LM[offset]>25.0f) { temp3=temp2-1.0f; temp=(L75[unif]*temp3)+1.0f; ncie->sh_p[j][i]=temp*LM[offset]*327.68f; } + else if (LM[offset]>20.0f) { temp3=temp2-1.0f; temp=(L80[unif]*temp3)+1.0f; ncie->sh_p[j][i]=temp*LM[offset]*327.68f; } + else if (LM[offset]>17.0f) { temp3=temp2-1.0f; temp=(L83[unif]*temp3)+1.0f; ncie->sh_p[j][i]=temp*LM[offset]*327.68f; } + else if (LM[offset]>13.0f) { temp3=temp2-1.0f; temp=(L87[unif]*temp3)+1.0f; ncie->sh_p[j][i]=temp*LM[offset]*327.68f; } + else if (LM[offset]>10.0f) { temp3=temp2-1.0f; temp=(L90[unif]*temp3)+1.0f; ncie->sh_p[j][i]=temp*LM[offset]*327.68f; } + else if (LM[offset]> 5.0f) { temp3=temp2-1.0f; temp=(L95[unif]*temp3)+1.0f; ncie->sh_p[j][i]=temp*LM[offset]*327.68f; } + else if (LM[offset]> 0.0f) { ncie->sh_p[j][i]=LM[offset]*327.68f;} + } + temp4 = (327.68f*LM[offset])/tempL;// + if (temp4>1.0f) { + if (temp4>1.7f) + temp4 = 1.7f;//limit action + if (LM[offset]< 2.0f) { temp3=temp4-1.0f; temp=(L98[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]< 5.0f) { temp3=temp4-1.0f; temp=(L95[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]< 8.0f) { temp3=temp4-1.0f; temp=(L92[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]<10.0f) { temp3=temp4-1.0f; temp=(L90[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]<13.0f) { temp3=temp4-1.0f; temp=(L87[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]<17.0f) { temp3=temp4-1.0f; temp=(L83[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]<20.0f) { temp3=temp4-1.0f; temp=(L80[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]<25.0f) { temp3=temp4-1.0f; temp=(L75[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]<30.0f) { temp3=temp4-1.0f; temp=(L70[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]<37.0f) { temp3=temp4-1.0f; temp=(L63[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]<42.0f) { temp3=temp4-1.0f; temp=(L58[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]<58.0f) { temp3=temp4-1.0f; temp=(L58[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]<63.0f) { temp3=temp4-1.0f; temp=(L63[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]<70.0f) { temp3=temp4-1.0f; temp=(L70[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]<75.0f) { temp3=temp4-1.0f; temp=(L75[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]<80.0f) { temp3=temp4-1.0f; temp=(L80[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]<83.0f) { temp3=temp4-1.0f; temp=(L83[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]<87.0f) { temp3=temp4-1.0f; temp=(L87[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]<90.0f) { temp3=temp4-1.0f; temp=(L90[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]<95.0f) { temp3=temp4-1.0f; temp=(L95[unif]*temp3)+1.0f; ncie->sh_p[j][i]=(LM[offset]*327.68f)/temp; } + else if (LM[offset]<100.0f) { ncie->sh_p[j][i]=LM[offset]*327.68f; } + } + + } + delete [] LM; + t2e.set(); + if (settings->verbose) + printf("Micro-contrast %d usec\n", t2e.etime(t1e)); + +} + +void ImProcFunctions::deconvsharpeningcam (CieImage* ncie, float** b2) { + + if (params->sharpening.enabled==false || params->sharpening.deconvamount<1) + return; + + int W = ncie->W, H = ncie->H; + + float** tmpI = new float*[H]; + for (int i=0; ish_p[i][j]; + } + + float** tmp = (float**)b2; + +#ifdef _OPENMP +#pragma omp parallel +#endif + { + AlignedBufferMP buffer(max(W,H)); + + + float damping = params->sharpening.deconvdamping / 5.0; + bool needdamp = params->sharpening.deconvdamping > 0; + for (int k=0; ksharpening.deconviter; k++) { + + // apply blur function (gaussian blur) + gaussHorizontal (tmpI, tmp, buffer, W, H, params->sharpening.deconvradius / scale); + gaussVertical (tmp, tmp, buffer, W, H, params->sharpening.deconvradius / scale); + + if (!needdamp) { +#ifdef _OPENMP +#pragma omp for +#endif + for (int i=0; i0) + tmp[i][j] = (float)ncie->sh_p[i][j] / tmp[i][j]; + } + else + dcdamping (tmp, ncie->sh_p, damping, W, H); + + gaussHorizontal (tmp, tmp, buffer, W, H, params->sharpening.deconvradius / scale); + gaussVertical (tmp, tmp, buffer, W, H, params->sharpening.deconvradius / scale); + + +#ifdef _OPENMP +#pragma omp for +#endif + for (int i=0; isharpening.deconvamount / 100.0; + float p2 = params->sharpening.deconvamount / 100.0; + float p1 = 1.0 - p2; + +#ifdef _OPENMP +#pragma omp for +#endif + for (int i=0; iJ_p[i][j] > 8.0f && ncie->J_p[i][j] < 92.0f) ncie->sh_p[i][j] = ncie->sh_p[i][j]*p1 + max(tmpI[i][j],0.0f)*p2; + + } // end parallel + + for (int i=0; isharpening.method=="rld") { + deconvsharpeningcam (ncie, b2); + return; + } + + // Rest is UNSHARP MASK + if (params->sharpening.enabled==false || params->sharpening.amount<1 || ncie->W<8 || ncie->H<8) + return; + + int W = ncie->W, H = ncie->H; + float** b3; + float** ncieCopy; + + if (params->sharpening.edgesonly) { + b3 = new float*[H]; + for (int i=0; isharpening.halocontrol && !params->sharpening.edgesonly) { + // We only need the lab parameter copy in this special case + ncieCopy = new float*[H]; + for( int i=0; i buffer(max(W,H)); + + if (params->sharpening.edgesonly==false) { + + gaussHorizontal (ncie->sh_p, b2, buffer, W, H, params->sharpening.radius / scale); + gaussVertical (b2, b2, buffer, W, H, params->sharpening.radius / scale); + } + else { + bilateral (ncie->sh_p, (float**)b3, b2, W, H, params->sharpening.edges_radius / scale, params->sharpening.edges_tolerance, multiThread); + gaussHorizontal (b3, b2, buffer, W, H, params->sharpening.radius / scale); + gaussVertical (b2, b2, buffer, W, H, params->sharpening.radius / scale); + } + + float** base = ncie->sh_p; + if (params->sharpening.edgesonly) + base = b3; + + if (params->sharpening.halocontrol==false) { +#ifdef _OPENMP +#pragma omp for +#endif + for (int i=0; isharpening.threshold.multiply( + min(ABS(diff), upperBound), // X axis value = absolute value of the difference, truncated to the max value of this field + params->sharpening.amount * diff * 0.01f // Y axis max value + ); + if(ncie->J_p[i][j] > 8.0f && ncie->J_p[i][j] < 92.0f) ncie->sh_p[i][j] = ncie->sh_p[i][j] + delta; + } + } + else { + if (!params->sharpening.edgesonly) { + // make a deep copy of lab->L +#ifdef _OPENMP +#pragma omp for +#endif + for( int i=0; ish_p[i][j]; + base = ncieCopy; + } + sharpenHaloCtrlcam (ncie, b2, base, W, H); + } + + } // end parallel + + if (params->sharpening.halocontrol && !params->sharpening.edgesonly) { + // delete the deep copy + for( int i=0; isharpening.edgesonly) { + for (int i=0; isharpening.halocontrol_amount) * 0.01f; + float sharpFac = params->sharpening.amount * 0.01f; + float** nL = base; + +#ifdef _OPENMP +#pragma omp for +#endif + for (int i=2; ish_p[i][j]; + if (max_ < labL) max_ = labL; + if (min_ > labL) min_ = labL; + + // deviation from the environment as measurement + float diff = nL[i][j] - blurmap[i][j]; + + const float upperBound = 2000.f; // WARNING: Duplicated value, it's baaaaaad ! + float delta = params->sharpening.threshold.multiply( + min(ABS(diff), upperBound), // X axis value = absolute value of the difference + sharpFac * diff // Y axis max value = sharpening.amount * signed difference + ); + float newL = labL + delta; + // applying halo control + if (newL > max_) + newL = max_ + (newL-max_) * scale; + else if (newL < min_) + newL = min_ - (min_-newL) * scale; + + ncie->sh_p[i][j] = newL; + } + } +} + +} diff --git a/rtengine/iptcpairs.h b/rtengine/iptcpairs.h new file mode 100644 index 000000000..018e7f1bf --- /dev/null +++ b/rtengine/iptcpairs.h @@ -0,0 +1,49 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _IPTCPAIRS_ +#define _IPTCPAIRS_ + + +struct IptcPair { + IptcTag tag; + size_t size; + Glib::ustring field; +}; + +const IptcPair strTags[] = { + {IPTC_TAG_CAPTION, 2000, "Caption"}, + {IPTC_TAG_WRITER_EDITOR, 32, "CaptionWriter"}, + {IPTC_TAG_HEADLINE, 256, "Headline"}, + {IPTC_TAG_SPECIAL_INSTRUCTIONS, 256, "Instructions"}, + {IPTC_TAG_CATEGORY, 3, "Category"}, + {IPTC_TAG_BYLINE, 32, "Author"}, + {IPTC_TAG_BYLINE_TITLE, 32, "AuthorsPosition"}, + {IPTC_TAG_CREDIT, 32, "Credit"}, + {IPTC_TAG_SOURCE, 32, "Source"}, + {IPTC_TAG_COPYRIGHT_NOTICE, 128, "Copyright"}, + {IPTC_TAG_CITY, 32, "City"}, + {IPTC_TAG_STATE, 32, "Province"}, + {IPTC_TAG_COUNTRY_NAME, 64, "Country"}, + {IPTC_TAG_OBJECT_NAME, 64, "Title"}, + {IPTC_TAG_ORIG_TRANS_REF, 32, "TransReference"}, + {IPTC_TAG_DATE_CREATED, 8, "DateCreated"} +}; + +#endif + diff --git a/rtengine/iptransform.cc b/rtengine/iptransform.cc new file mode 100644 index 000000000..9d07565ee --- /dev/null +++ b/rtengine/iptransform.cc @@ -0,0 +1,924 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "rtengine.h" +#include "improcfun.h" +#ifdef _OPENMP +#include +#endif +#include "mytime.h" +#include "rt_math.h" +#include "sleef.c" +using namespace std; + +namespace rtengine { +#undef CLIPTOC + +#define CLIPTOC(a,b,c,d) ((a)>=(b)?((a)<=(c)?(a):(d=true,(c))):(d=true,(b))) +#define RT_PI 3.141592653589 + +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) { + + bool clipped = false; + + red.clear (); green.clear (); blue.clear (); + + if (!needsCA() && !needsDistortion() && !needsRotation() && !needsPerspective() && (!params->lensProf.useDist || pLCPMap==NULL)) { + for (size_t i=0; idistortion.amount; + + // auxiliary variables for rotation + double cost = cos(params->rotate.degree * RT_PI/180.0); + double sint = sin(params->rotate.degree * RT_PI/180.0); + + // auxiliary variables for vertical perspective correction + double vpdeg = params->perspective.vertical / 100.0 * 45.0; + double vpalpha = (90.0 - vpdeg) / 180.0 * RT_PI; + double vpteta = fabs(vpalpha-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.0 - hpdeg) / 180.0 * RT_PI; + double hpteta = fabs(hpalpha-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 = ascaleDef>0 ? ascaleDef : (params->commonTrans.autofill ? getTransformAutoFill (oW, oH, pLCPMap) : 1.0); + + for (size_t i=0; ilensProf.useDist) pLCPMap->correctDistortion(x_d,y_d); // must be first transform + + y_d = ascale * (y_d - h2); + x_d = ascale * (x_d - w2); + + 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 ; + } + + // LCP CA is not reflected in preview (and very small), so don't add it here + + red.push_back (Coord2D(Dx*(s+params->cacorrection.red)+w2, Dy*(s+params->cacorrection.red)+h2)); + green.push_back (Coord2D(Dx*s+w2, Dy*s+h2)); + blue.push_back (Coord2D(Dx*(s+params->cacorrection.blue)+w2, Dy*(s+params->cacorrection.blue)+h2)); + } + + // Clip all points and track if they were any corrections + for (size_t i=0; i corners (8); + corners[0].set (x1, y1); + corners[1].set (x1, y2); + corners[2].set (x2, y2); + corners[3].set (x2, y1); + corners[4].set ((x1+x2)/2, y1); + corners[5].set ((x1+x2)/2, y2); + corners[6].set (x1, (y1+y2)/2); + corners[7].set (x2, (y1+y2)/2); + + // Add several steps inbetween + int xstep = (x2-x1)/DivisionsPerBorder; + if (xstep<1) xstep = 1; + for (int i=x1+xstep; i<=x2-xstep; i+=xstep) { + corners.push_back (Coord2D (i, y1)); + corners.push_back (Coord2D (i, y2)); + } + int ystep = (y2-y1)/DivisionsPerBorder; + if (ystep<1) ystep = 1; + for (int i=y1+ystep; i<=y2-ystep; i+=ystep) { + corners.push_back (Coord2D (x1, i)); + corners.push_back (Coord2D (x2, i)); + } + + std::vector r, g, b; + + bool clipped = transCoord (W, H, corners, r, g, b, ascaleDef, pLCPMap); + + // Merge all R G Bs into one X/Y pool + std::vector transCorners; + transCorners.insert (transCorners.end(), r.begin(), r.end()); + transCorners.insert (transCorners.end(), g.begin(), g.end()); + transCorners.insert (transCorners.end(), b.begin(), b.end()); + + // find the min/max of all coordinates, so the borders + double x1d = transCorners[0].x; + for (size_t i=1; ix2d) + x2d = transCorners[i].x; + int x2v = (int)ceil(x2d); + + double y2d = transCorners[0].y; + for (size_t i=1; iy2d) + y2d = transCorners[i].y; + int y2v = (int)ceil(y2d); + + xv = x1v; + yv = y1v; + wv = x2v - x1v + 1; + hv = y2v - y1v + 1; + + return clipped; +} + +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, int rawRotationDeg, bool fullImage) { + + LCPMapper *pLCPMap=NULL; + if (needsLCP() && focalLen>0) { + LCPProfile *pLCPProf=lcpStore->getProfile(params->lensProf.lcpFile); + if (pLCPProf) pLCPMap=new LCPMapper(pLCPProf, focalLen, focalLen35mm, focusDist, 0, false, params->lensProf.useDist, + original->width, original->height, params->coarse, rawRotationDeg); + } + + if (!(needsCA() || needsDistortion() || needsRotation() || needsPerspective() || needsLCP()) && (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; +} + +// helper function +void ImProcFunctions::calcVignettingParams(int oW, int oH, const VignettingParams& vignetting, double &w2, double &h2, double& maxRadius, double &v, double &b, double &mul) +{ + // vignette center is a point with coordinates between -1 and +1 + double x = vignetting.centerX / 100.0; + double y = vignetting.centerY / 100.0; + + // calculate vignette center in pixels + w2 = (double) oW / 2.0 - 0.5 + x * oW; + h2 = (double) oH / 2.0 - 0.5 + y * oH; + + // max vignette radius in pixels + maxRadius = sqrt( (double)( oW*oW + oH*oH ) ) / 2.; + + // vignette variables with applied strength + v = 1.0 + vignetting.strength * fabs(vignetting.amount) * 3.0 / 400.0; + b = 1.0 + vignetting.radius * 7.0 / 100.0; + mul = (1.0-v) / tanh(b); +} + +struct grad_params { + bool angle_is_zero, transpose, bright_top; + float ta, yc, xc; + float ys, ys_inv; + float scale, botmul, topmul; + float top_edge_0; + int h; +}; +static void calcGradientParams(int oW, int oH, const GradientParams& gradient, struct grad_params& gp) +{ + int w = oW; + int h = oH; + double gradient_stops = gradient.strength; + double gradient_span = gradient.feather / 100.0; + double gradient_center_x = gradient.centerX / 200.0 + 0.5; + double gradient_center_y = gradient.centerY / 200.0 + 0.5; + double gradient_angle = gradient.degree / 180.0 * M_PI; + //fprintf(stderr, "%f %f %f %f %f %d %d\n", gradient_stops, gradient_span, gradient_center_x, gradient_center_y, gradient_angle, w, h); + + // make 0.0 <= gradient_angle < 2 * M_PI + gradient_angle = fmod(gradient_angle, 2 * M_PI); + if (gradient_angle < 0.0) { + gradient_angle += 2.0 * M_PI; + } + + gp.bright_top = false; + gp.transpose = false; + gp.angle_is_zero = false; + gp.h = h; + double cosgrad = cos(gradient_angle); + if (fabs(cosgrad) < 0.707) { + // we transpose to avoid division by zero at 90 degrees + // (actually we could transpose only for 90 degrees, but this way we avoid + // division with extremely small numbers + gp.transpose = true; + gradient_angle += 0.5 * M_PI; + cosgrad = cos(gradient_angle); + double gxc = gradient_center_x; + gradient_center_x = 1.0 - gradient_center_y; + gradient_center_y = gxc; + } + gradient_angle = fmod(gradient_angle, 2 * M_PI); + if (gradient_angle > 0.5 * M_PI && gradient_angle < M_PI) { + gradient_angle += M_PI; + gp.bright_top = true; + } else if (gradient_angle >= M_PI && gradient_angle < 1.5 * M_PI) { + gradient_angle -= M_PI; + gp.bright_top = true; + } + if (fabs(gradient_angle) < 0.001 || fabs(gradient_angle - 2 * M_PI) < 0.001) { + gradient_angle = 0; + gp.angle_is_zero = true; + } + if (gp.transpose) { + gp.bright_top = !gp.bright_top; + } + if (gp.transpose) { + int tmp = w; + w = h; + h = tmp; + } + gp.scale = 1.0 / pow(2, gradient_stops); + if (gp.bright_top) { + gp.topmul = 1.0; + gp.botmul = gp.scale; + } else { + gp.topmul = gp.scale; + gp.botmul = 1.0; + } + gp.ta = tan(gradient_angle); + gp.xc = w * gradient_center_x; + gp.yc = h * gradient_center_y; + gp.ys = sqrt((float)h * h + (float)w * w) * (gradient_span / cos(gradient_angle)); + gp.ys_inv = 1.0 / gp.ys; + gp.top_edge_0 = gp.yc - gp.ys/2.0; + if (gp.ys < 1.0 / h) { + gp.ys_inv = 0; + gp.ys = 0; + } +} + +static float calcGradientFactor(const struct grad_params& gp, int x, int y) { + if (gp.angle_is_zero) { + int gy = gp.transpose ? x : y; + int gx = gp.transpose ? y : x; + if (gy < gp.top_edge_0) { + return gp.topmul; + } else if (gy >= gp.top_edge_0 + gp.ys) { + return gp.botmul; + } else { + float val = ((float)(gy - gp.top_edge_0) * gp.ys_inv); + if (gp.bright_top) { + val = 1.0 - val; + } + if (gp.scale < 1.0) { + val = pow(xsinf(val*M_PI/2), 3); + } else { + val = 1.0 - pow(xcosf(val*M_PI/2), 3); + } + return gp.scale + val * (1.0 - gp.scale); + } + } else { + int gy = gp.transpose ? x : y; + int gx = gp.transpose ? gp.h - y - 1 : x; + float top_edge = gp.yc - gp.ys/2.0 - gp.ta * (gx - gp.xc); + if (gy < top_edge) { + return gp.topmul; + } else if (gy >= top_edge + gp.ys) { + return gp.botmul; + } else { + float val = ((float)(gy - top_edge) * gp.ys_inv); + + if (gp.bright_top) { + val = 1.0 - val; + } + if (gp.scale < 1.0) { + val = pow(xsinf(val*M_PI/2), 3); + } else { + val = 1.0 - pow(xcosf(val*M_PI/2), 3); + } + return gp.scale + val * (1.0 - gp.scale); + } + } +} + +struct pcv_params { + float oe_a, oe_b, oe1_a, oe1_b, oe2_a, oe2_b; + float ie_mul, ie1_mul, ie2_mul; + float sepmix, feather; + int w, h, x1, x2, y1, y2; + int sep; + bool is_super_ellipse_mode, is_portrait; + float scale; + float fadeout_mul; +}; +static void calcPCVignetteParams(int fW, int fH, int oW, int oH, const PCVignetteParams& pcvignette, const CropParams &crop, struct pcv_params& pcv) { + + // ellipse formula: (x/a)^2 + (y/b)^2 = 1 + double roundness = pcvignette.roundness / 100.0; + pcv.feather = pcvignette.feather / 100.0; + if (crop.enabled) { + pcv.w = (crop.w * oW) / fW; + pcv.h = (crop.h * oH) / fH; + pcv.x1 = (crop.x * oW) / fW; + pcv.y1 = (crop.y * oH) / fH; + pcv.x2 = pcv.x1+pcv.w; + pcv.y2 = pcv.y1+pcv.h; + } else { + pcv.x1 = 0, pcv.y1 = 0; + pcv.x2 = oW, pcv.y2 = oH; + pcv.w = oW; + pcv.h = oH; + } + pcv.fadeout_mul = 1.0 / (0.05 * sqrtf(oW*oW+oH*oH)); + float short_side = (pcv.w < pcv.h) ? pcv.w : pcv.h; + float long_side = (pcv.w > pcv.h) ? pcv.w : pcv.h; + + pcv.sep = 2; + pcv.sepmix = 0; + pcv.oe_a = sqrt(2.0)*long_side*0.5; + pcv.oe_b = pcv.oe_a * short_side / long_side; + pcv.ie_mul = 1.0 / sqrt(2.0); + pcv.is_super_ellipse_mode = false; + pcv.is_portrait = (pcv.w < pcv.h); + if (roundness < 0.5) { + // make super-ellipse of higher and higher degree + pcv.is_super_ellipse_mode = true; + float sepf = 2 + 4*powf(1.0 - 2*roundness, 1.3); // gamma 1.3 used to balance the effect in the 0.0...0.5 roundness range + pcv.sep = ((int)sepf) & ~0x1; + pcv.sepmix = (sepf - pcv.sep) * 0.5; // 0.0 to 1.0 + pcv.oe1_a = powf(2.0, 1.0/pcv.sep)*long_side*0.5; + pcv.oe1_b = pcv.oe1_a * short_side / long_side; + pcv.ie1_mul = 1.0 / powf(2.0, 1.0/pcv.sep); + pcv.oe2_a = powf(2.0, 1.0/(pcv.sep+2))*long_side*0.5; + pcv.oe2_b = pcv.oe2_a * short_side / long_side; + pcv.ie2_mul = 1.0 / powf(2.0, 1.0/(pcv.sep+2)); + } + if (roundness > 0.5) { + // scale from fitted ellipse towards circle + float rad = sqrtf(pcv.w*pcv.w+pcv.h*pcv.h) / 2.0; + float diff_a = rad - pcv.oe_a; + float diff_b = rad - pcv.oe_b; + pcv.oe_a = pcv.oe_a + diff_a * 2*(roundness - 0.5); + pcv.oe_b = pcv.oe_b + diff_b * 2*(roundness - 0.5); + } + pcv.scale = powf(2, -pcvignette.strength); + if (pcvignette.strength >= 6.0) { + pcv.scale = 0.0; + } +} + +static float calcPCVignetteFactor(const struct pcv_params& pcv, int x, int y) { + + float fo = 1.0; + if (x < pcv.x1 || x > pcv.x2 || y < pcv.y1 || y > pcv.y2) { + /* + The initial plan was to have 1.0 directly outside the crop box (ie no fading), but due to + rounding/trunction here and there I didn't succeed matching up exactly on the pixel with + the crop box. To hide that mismatch I made a fade. + */ + int dist_x = (x < pcv.x1) ? pcv.x1 - x : x - pcv.x2; + int dist_y = (y < pcv.y1) ? pcv.y1 - y : y - pcv.y2; + if (dist_x < 0) dist_x = 0; + if (dist_y < 0) dist_y = 0; + fo = sqrtf(dist_x*dist_x+dist_y*dist_y) * pcv.fadeout_mul; + if (fo >= 1.0) { + return 1.0; + } + } + float val, a, b; + if (pcv.is_portrait) { + a = fabs((y-pcv.y1)-pcv.h*0.5); + b = fabs((x-pcv.x1)-pcv.w*0.5); + } else { + a = fabs((x-pcv.x1)-pcv.w*0.5); + b = fabs((y-pcv.y1)-pcv.h*0.5); + } + float angle = xatan2f(b, a); + float dist = sqrtf(a*a+b*b); + float dist_oe, dist_ie; + float2 sincosval; + if(dist==0.0f) { + sincosval.y = 1.0f; // cos + sincosval.x = 0.0f; // sin + } else { + sincosval.y = a / dist; // cos + sincosval.x = b / dist; // sin + } + if (pcv.is_super_ellipse_mode) { + float dist_oe1 = pcv.oe1_a*pcv.oe1_b / pow_F(pow(pcv.oe1_b*sincosval.y, pcv.sep) + pow(pcv.oe1_a*sincosval.x, pcv.sep), 1.0/pcv.sep); + float dist_oe2 = pcv.oe2_a*pcv.oe2_b / pow_F(pow(pcv.oe2_b*sincosval.y, pcv.sep+2) + pow(pcv.oe2_a*sincosval.x, pcv.sep+2), 1.0/(pcv.sep+2)); + float dist_ie1 = pcv.ie1_mul * dist_oe1 * (1.0 - pcv.feather); + float dist_ie2 = pcv.ie2_mul * dist_oe2 * (1.0 - pcv.feather); + dist_oe = dist_oe1 * (1.0 - pcv.sepmix) + dist_oe2 * pcv.sepmix; + dist_ie = dist_ie1 * (1.0 - pcv.sepmix) + dist_ie2 * pcv.sepmix; + } else { + dist_oe = pcv.oe_a*pcv.oe_b / sqrtf(SQR(pcv.oe_b*sincosval.y) + SQR(pcv.oe_a*sincosval.x)); + dist_ie = pcv.ie_mul * dist_oe * (1.0 - pcv.feather); + } + if (dist <= dist_ie) { + return 1.0; + } + + if (dist >= dist_oe) { + val = pcv.scale; + } else { + val = (dist - dist_ie) / (dist_oe - dist_ie); + if (pcv.scale < 1.0) { + val = pow(xcosf(val*M_PI/2), 4); + } else { + val = 1 - pow(xsinf(val*M_PI/2), 4); + } + val = pcv.scale + val * (1.0 - pcv.scale); + } + if (fo < 1.0) { + val = 1.0 * fo + val * (1.0 - fo); + } + return val; +} + +void ImProcFunctions::transformLuminanceOnly (Imagefloat* original, Imagefloat* transformed, int cx, int cy, int oW, int oH, int fW, int fH) { + const bool applyVignetting = needsVignetting(); + const bool applyGradient = needsGradient(); + const bool applyPCVignetting = needsPCVignetting(); + + double vig_w2, vig_h2, maxRadius, v, b, mul; + if (applyVignetting) { + calcVignettingParams(oW, oH, params->vignetting, vig_w2, vig_h2, maxRadius, v, b, mul); + } + + struct grad_params gp; + if (applyGradient) { + calcGradientParams(oW, oH, params->gradient, gp); + } + + struct pcv_params pcv; + if (applyPCVignetting) { + //fprintf(stderr, "%d %d | %d %d | %d %d | %d %d [%d %d]\n", fW, fH, oW, oH, transformed->width, transformed->height, cx, cy, params->crop.w, params->crop.h); + calcPCVignetteParams(fW, fH, oW, oH, params->pcvignette, params->crop, pcv); + } + bool darkening = (params->vignetting.amount <= 0.0); + #pragma omp parallel for schedule(dynamic,16) if (multiThread) + for (int y=0; yheight; y++) { + double vig_y_d = (double) (y + cy) - vig_h2 ; + for (int x=0; xwidth; x++) { + double factor = 1.0; + if (applyVignetting) { + double vig_x_d = (double) (x + cx) - vig_w2 ; + double r = sqrt(vig_x_d*vig_x_d + vig_y_d*vig_y_d); + if(darkening) + factor /= std::max(v + mul * tanh (b*(maxRadius-r) / maxRadius), 0.001); + else + factor = v + mul * tanh (b*(maxRadius-r) / maxRadius); + } + if (applyGradient) { + factor *= calcGradientFactor(gp, cx+x, cy+y); + } + if (applyPCVignetting) { + factor *= calcPCVignetteFactor(pcv, cx+x, cy+y); + } + transformed->r(y,x) = original->r(y,x) * factor; + transformed->g(y,x) = original->g(y,x) * factor; + transformed->b(y,x) = original->b(y,x) * factor; + } + } +} + +// 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) { + + double w2 = (double) oW / 2.0 - 0.5; + double h2 = (double) oH / 2.0 - 0.5; + + double vig_w2,vig_h2,maxRadius,v,b,mul; + calcVignettingParams(oW, oH, params->vignetting, vig_w2, vig_h2, maxRadius, v, b, mul); + + 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); + } + + float** chOrig[3]; + chOrig[0] = original->r.ptrs; + chOrig[1] = original->g.ptrs; + chOrig[2] = original->b.ptrs; + + float** chTrans[3]; + chTrans[0] = transformed->r.ptrs; + chTrans[1] = transformed->g.ptrs; + chTrans[2] = transformed->b.ptrs; + + // auxiliary variables for c/a correction + double chDist[3]; + chDist[0] = params->cacorrection.red; + chDist[1] = 0.0; + chDist[2] = params->cacorrection.blue; + + // 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 * RT_PI/180.0); + double sint = sin(params->rotate.degree * RT_PI/180.0); + + // auxiliary variables for vertical perspective correction + double vpdeg = params->perspective.vertical / 100.0 * 45.0; + double vpalpha = (90.0 - vpdeg) / 180.0 * RT_PI; + double vpteta = fabs(vpalpha-RT_PI/2)<3e-4 ? 0.0 : acos ((vpdeg>0 ? 1.0 : -1.0) * sqrt((-SQR(oW*tan(vpalpha)) + (vpdeg>0 ? 1.0 : -1.0) * + oW*tan(vpalpha)*sqrt(SQR(4*maxRadius)+SQR(oW*tan(vpalpha))))/(SQR(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.0 - hpdeg) / 180.0 * RT_PI; + double hpteta = fabs(hpalpha-RT_PI/2)<3e-4 ? 0.0 : acos ((hpdeg>0 ? 1.0 : -1.0) * sqrt((-SQR(oH*tan(hpalpha)) + (hpdeg>0 ? 1.0 : -1.0) * + 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, fullImage ? pLCPMap : NULL) : 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(); + + // main cycle + bool darkening = (params->vignetting.amount <= 0.0); + #pragma omp parallel for if (multiThread) + for (int y=0; yheight; y++) { + for (int x=0; xwidth; x++) { + double x_d=x,y_d=y; + if (enableLCPDist) pLCPMap->correctDistortion(x_d,y_d); // must be first transform + + x_d = ascale * (x_d + cx - w2); // centering x coord & scale + y_d = ascale * (y_d + cy - h2); // centering y coord & scale + + double vig_x_d, vig_y_d; + 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 Dxc = x_d * cost - y_d * sint; + double Dyc = x_d * sint + y_d * cost; + + // distortion correction + double s = 1; + if (needsDist) { + double r = sqrt(Dxc*Dxc + Dyc*Dyc) / maxRadius; // sqrt is slow + s = 1.0 - distAmount + distAmount * r ; + } + + double r2; + 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); + } + + for (int c=0; c < (enableCA ? 3 : 1); c++) { + double Dx = Dxc * (s + chDist[c]); + double Dy = Dyc * (s + chDist[c]); + + // de-center + 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; xc -= sx; + int yc = (int)Dy; Dy -= (double)yc; yc -= sy; + + // Convert only valid pixels + if (yc>=0 && ycheight && xc>=0 && xcwidth) { + + // 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); + else + vignmul *= (v + mul * tanh (b*(maxRadius-s*r2) / maxRadius)); + if (needsGradient()) { + vignmul *= calcGradientFactor(gp, cx+x, cy+y); + } + if (needsPCVignetting()) { + vignmul *= calcPCVignetteFactor(pcv, cx+x, cy+y); + } + + if (yc > 0 && yc < original->height-2 && xc > 0 && xc < original->width-2) { + // all interpolation pixels inside image + if (enableCA) + interpolateTransformChannelsCubic (chOrig[c], xc-1, yc-1, Dx, Dy, &(chTrans[c][y][x]), vignmul); + else + interpolateTransformCubic (original, xc-1, yc-1, Dx, Dy, &(transformed->r(y,x)), &(transformed->g(y,x)), &(transformed->b(y,x)), vignmul); + } else { + // edge pixels + int y1 = LIM(yc, 0, original->height-1); + int y2 = LIM(yc+1, 0, original->height-1); + int x1 = LIM(xc, 0, original->width-1); + int x2 = LIM(xc+1, 0, original->width-1); + + if (enableCA) { + chTrans[c][y][x] = vignmul * (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); + } else { + 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); + } + } + } + else { + if (enableCA) { + // not valid (source pixel x,y not inside source image, etc.) + chTrans[c][y][x] = 0; + } else { + transformed->r(y,x) = 0; + transformed->g(y,x) = 0; + transformed->b(y,x) = 0; + } + } + } + } + } +} + +// 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) { + + double w2 = (double) oW / 2.0 - 0.5; + double h2 = (double) oH / 2.0 - 0.5; + + double vig_w2, vig_h2, maxRadius, v, b, mul; + calcVignettingParams(oW, oH, params->vignetting, vig_w2, vig_h2, maxRadius, v, b, mul); + + 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 * RT_PI/180.0); + double sint = sin(params->rotate.degree * 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 * RT_PI; + double vpteta = fabs(vpalpha-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 * RT_PI; + double hpteta = fabs(hpalpha-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; yheight; y++) { + for (int x=0; xwidth; x++) { + double x_d=x,y_d=y; + if (pLCPMap && params->lensProf.useDist) pLCPMap->correctDistortion(x_d,y_d); // must be first transform + + y_d = ascale * (y_d + cy - h2); // centering y coord & scale + x_d = ascale * (x_d + cx - w2); // centering x coord & scale + + double vig_x_d, vig_y_d; + 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; + 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 && ycheight && xc>=0 && xcwidth) { + + // 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); + else + vignmul = v + mul * tanh (b*(maxRadius-s*r2) / maxRadius); + if (needsGradient()) + vignmul *= calcGradientFactor(gp, cx+x, cy+y); + if (needsPCVignetting()) + vignmul *= calcPCVignetteFactor(pcv, cx+x, cy+y); + + if (yc < original->height-1 && xc < original->width-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->height-1); + int y2 = LIM(yc+1, 0, original->height-1); + int x1 = LIM(xc, 0, original->width-1); + int x2 = LIM(xc+1, 0, original->width-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); + } + } + 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) { + if (!needsCA() && !needsDistortion() && !needsRotation() && !needsPerspective() && (!params->lensProf.useDist || pLCPMap==NULL)) + return 1; + + double scaleU = 2, scaleL = 0.001; // upper and lower border, iterate inbetween + + do { + double scale = (scaleU + scaleL) * 0.5; + + int orx, ory, orw, orh; + bool clipped = transCoord (oW, oH, 0, 0, oW, oH, orx, ory, orw, orh, scale, pLCPMap); + + if (clipped) + scaleU = scale; + else + scaleL = scale; + } while (scaleU - scaleL > 0.001); + + return scaleL; +} + +bool ImProcFunctions::needsCA () { + return fabs (params->cacorrection.red) > 1e-15 || fabs (params->cacorrection.blue) > 1e-15; +} + +bool ImProcFunctions::needsDistortion () { + return fabs (params->distortion.amount) > 1e-15; +} + +bool ImProcFunctions::needsRotation () { + return fabs (params->rotate.degree) > 1e-15; +} + +bool ImProcFunctions::needsPerspective () { + return params->perspective.horizontal || params->perspective.vertical; +} + +bool ImProcFunctions::needsGradient () { + return params->gradient.enabled && fabs(params->gradient.strength) > 1e-15; +} + +bool ImProcFunctions::needsPCVignetting () { + return params->pcvignette.enabled && fabs(params->pcvignette.strength) > 1e-15; +} + +bool ImProcFunctions::needsVignetting () { + return params->vignetting.amount; +} + +bool ImProcFunctions::needsLCP () { + return params->lensProf.lcpFile.length()>0; +} + +bool ImProcFunctions::needsTransform () { + return needsCA () || needsDistortion () || needsRotation () || needsPerspective () || needsGradient () || needsPCVignetting () || needsVignetting () || needsLCP(); +} + + +} + diff --git a/rtengine/ipvibrance.cc b/rtengine/ipvibrance.cc new file mode 100644 index 000000000..2582209d0 --- /dev/null +++ b/rtengine/ipvibrance.cc @@ -0,0 +1,471 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * Copyright (c) 2011 Jacques Desmis + * + * 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 "rt_math.h" +//#include + +#include "rtengine.h" +#include "improcfun.h" +#include "iccstore.h" +#include "mytime.h" +#include "../rtgui/thresholdselector.h" +#include "curves.h" +#include "color.h" + +#ifdef _OPENMP +#include +#endif + +using namespace std; + +namespace rtengine { + +using namespace procparams; + +#define SAT(a,b,c) ((float)max(a,b,c)-(float)min(a,b,c))/(float)max(a,b,c) + +extern const Settings* settings; + +void fillCurveArrayVib(DiagonalCurve* diagCurve, LUTf &outCurve) { + + if (diagCurve) { +#ifdef _OPENMP +#pragma omp parallel for +#endif + for (int i=0; i<=0xffff; i++ ) { + // change to [0,1] range + // apply custom/parametric/NURBS curve, if any + // and store result in a temporary array + outCurve[i] = 65535.f*diagCurve->getVal( double(i)/65535.0 ); + } + } + else { + for (int i=0; i<=0xffff; i++) { + outCurve[i] = float(i); + } + } +} + + +/* + * Vibrance correction + * copyright (c)2011 Jacques Desmis and Jean-Christophe Frisch + * + */ +void ImProcFunctions::vibrance (LabImage* lab) { + if (!params->vibrance.enabled) + return; + +// int skip=1; //scale==1 ? 1 : 16; + bool skinCurveIsSet=false; + DiagonalCurve* dcurve = NULL; + dcurve = new DiagonalCurve (params->vibrance.skintonescurve, CURVES_MIN_POLY_POINTS); + if (dcurve) { + if (!dcurve->isIdentity()) { + skinCurveIsSet = true; + } + else { + delete dcurve; + dcurve = NULL; + } + } + + if (!skinCurveIsSet && !params->vibrance.pastels && !params->vibrance.saturated) { + if (dcurve) { + delete dcurve; + dcurve = NULL; + } + return; + } + + const int width = lab->W; + const int height = lab->H; + +#ifdef _DEBUG + MyTime t1e,t2e; + t1e.set(); + int negat=0, moreRGB=0, negsat=0, moresat=0; +#endif + + // skin hue curve + // I use diagonal because I think it's better + LUTf skin_curve (65536,0); + if(skinCurveIsSet) + fillCurveArrayVib(dcurve, skin_curve); + if (dcurve) { + delete dcurve; + dcurve = NULL; + } + + +// skin_curve.dump("skin_curve"); + + const float chromaPastel = float(params->vibrance.pastels) / 100.0f; + const float chromaSatur = float(params->vibrance.saturated) / 100.0f; + const float p00=0.07f; + const float limitpastelsatur = (static_cast(params->vibrance.psthreshold.value[ThresholdSelector::TS_TOPLEFT]) / 100.0f)*(1.0f-p00) + p00; + const float maxdp=(limitpastelsatur-p00)/4.0f; + const float maxds=(1.0-limitpastelsatur)/4.0f; + const float p0 = p00+maxdp; + const float p1 = p00+2.0f*maxdp; + const float p2 = p00+3.0f*maxdp; + const float s0 = limitpastelsatur + maxds; + const float s1 = limitpastelsatur + 2.0f*maxds; + const float s2 = limitpastelsatur + 3.0f*maxds; + const float transitionweighting = static_cast(params->vibrance.psthreshold.value[ThresholdSelector::TS_BOTTOMLEFT]) / 100.0f; + float chromamean=0.0f; + if(chromaPastel != chromaSatur){ + //if sliders pastels and saturated are different: transition with a double linear interpolation: between p2 and limitpastelsatur, and between limitpastelsatur and s0 + //modify the "mean" point in function of double threshold => differential transition + chromamean = maxdp * (chromaSatur-chromaPastel) / (s0-p2) + chromaPastel; + // move chromaMean up or down depending on transitionCtrl + if (transitionweighting > 0.0f) { + chromamean = (chromaSatur-chromamean) * transitionweighting + chromamean; + } + else if (transitionweighting < 0.0f) { + chromamean = (chromamean-chromaPastel) * transitionweighting + chromamean; + } + } + const float chromaPastel_a = (chromaPastel-chromamean)/(p2-limitpastelsatur); + const float chromaPastel_b = chromaPastel-chromaPastel_a*p2; + + const float chromaSatur_a=(chromaSatur-chromamean)/(s0-limitpastelsatur); + const float chromaSatur_b=chromaSatur-chromaSatur_a*s0; + + const float dhue=0.15f;//hue transition + const float dchr=20.0f;//chroma transition + const float skbeg=-0.05f;//begin hue skin + const float skend=1.60f;//end hue skin + const float xx=0.5f;//soft : between 0.3 and 1.0 + const float ask=65535.0f/(skend-skbeg); + const float bsk=-skbeg*ask; + + + const bool highlight = params->toneCurve.hrenabled;//Get the value if "highlight reconstruction" is activated + const bool protectskins = params->vibrance.protectskins; + const bool avoidcolorshift = params->vibrance.avoidcolorshift; + + TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params->icm.working); + //inverse matrix user select + const double wip[3][3] = { + {wiprof[0][0],wiprof[0][1],wiprof[0][2]}, + {wiprof[1][0],wiprof[1][1],wiprof[1][2]}, + {wiprof[2][0],wiprof[2][1],wiprof[2][2]} + }; + + +#ifdef _DEBUG + MunsellDebugInfo* MunsDebugInfo = NULL; + if (avoidcolorshift) + MunsDebugInfo = new MunsellDebugInfo(); + +#pragma omp parallel default(shared) firstprivate(lab, width, height, chromaPastel, chromaSatur, highlight, limitpastelsatur, \ + transitionweighting, protectskins, avoidcolorshift, MunsDebugInfo) reduction(+: negat, moreRGB, negsat, moresat) if (multiThread) +#else +#pragma omp parallel default(shared) if (multiThread)// firstprivate(lab, width, height, chromaPastel, chromaSatur, highlight, limitpastelsatur, \ + transitionweighting, protectskins, avoidcolorshift) if (multiThread) +#endif +{ + + float sathue[5],sathue2[4];// adjust sat in function of hue + +/* + // Fitting limitpastelsatur into the real 0.07->1.0 range +// limitpastelsatur = limitpastelsatur*(1.0f-p00) + p00; + float p0,p1,p2;//adapt limit of pyramid to psThreshold + float s0,s1,s2; +*/ + +#ifdef _OPENMP + if (settings->verbose && omp_get_thread_num()==0) { +#else + if (settings->verbose) { +#endif + printf("vibrance: p0=%1.2f p1=%1.2f p2=%1.2f s0=%1.2f s1=%1.2f s2=%1.2f\n", p0,p1,p2,s0,s1,s2); + printf(" pastel=%f satur=%f limit= %1.2f chromamean=%0.5f\n",1.0f+chromaPastel,1.0f+chromaSatur, limitpastelsatur, chromamean); + } + +#pragma omp for schedule(dynamic, 16) + for (int i=0; iL[i][j]/327.68f; + float CC=sqrt(SQR(lab->a[i][j])+ SQR(lab->b[i][j]))/327.68f; + float HH=xatan2f(lab->b[i][j],lab->a[i][j]); + + float satredu=1.0f; //reduct sat in function of skin + if(protectskins) { + Color::SkinSat (LL, HH, CC, satredu);// for skin colors + } + // here we work on Chromaticity and Hue + // variation of Chromaticity ==> saturation via RGB + // Munsell correction, then conversion to Lab + float Lprov=LL; + float Chprov=CC; + float R, G, B; + float2 sincosval; + if(CC==0.0f) { + sincosval.y = 1.f; + sincosval.x = 0.0f; + } else { + sincosval.y = lab->a[i][j]/(CC*327.68f); + sincosval.x = lab->b[i][j]/(CC*327.68f); + } + +#ifdef _DEBUG + bool neg=false; + bool more_rgb=false; + //gamut control : Lab values are in gamut + Color::gamutLchonly(HH, sincosval, Lprov, Chprov, R, G, B, wip, highlight, 0.15f, 0.98f, neg, more_rgb); + if(neg) negat++; + if(more_rgb) moreRGB++; +#else + //gamut control : Lab values are in gamut + Color::gamutLchonly(HH, sincosval, Lprov, Chprov, R, G, B, wip, highlight, 0.15f, 0.98f); +#endif + if(Chprov > 6.0f) { + const float saturation=SAT(R,G,B); + if(saturation>0.0f) { + if(satredu!=1.0f) { + // for skin, no differentiation + sathue [0]=sathue [1]=sathue [2]=sathue [3]=sathue[4]=1.0f; + sathue2[0]=sathue2[1]=sathue2[2]=sathue2[3] =1.0f; + } else { + //double pyramid: LL and HH + //I try to take into account: Munsell response (human vision) and Gamut..(less response for red): preferably using Prophoto or WideGamut + //blue: -1.80 -3.14 green = 2.1 3.14 green-yellow=1.4 2.1 red:0 1.4 blue-purple:-0.7 -1.4 purple: 0 -0.7 + //these values allow a better and differential response + if(LL < 20.0f) {//more for blue-purple, blue and red modulate + if (/*HH> -3.1415f &&*/ HH< -1.5f ) {sathue[0]=1.3f;sathue[1]=1.2f;sathue[2]=1.1f;sathue[3]=1.05f;sathue[4]=0.4f;sathue2[0]=1.05f;sathue2[1]=1.1f ;sathue2[2]=1.05f;sathue2[3]=1.0f;}//blue + else if(/*HH>=-1.5f &&*/ HH< -0.7f ) {sathue[0]=1.6f;sathue[1]=1.4f;sathue[2]=1.3f;sathue[3]=1.2f ;sathue[4]=0.4f;sathue2[0]=1.2f ;sathue2[1]=1.15f;sathue2[2]=1.1f ;sathue2[3]=1.0f;}//blue purple 1.2 1.1 + else if(/*HH>=-0.7f &&*/ HH< 0.0f ) {sathue[0]=1.2f;sathue[1]=1.0f;sathue[2]=1.0f;sathue[3]=1.0f ;sathue[4]=0.4f;sathue2[0]=1.0f ;sathue2[1]=1.0f ;sathue2[2]=1.0f ;sathue2[3]=1.0f;}//purple + // else if( HH>= 0.0f && HH<= 1.4f ) {sathue[0]=1.1f;sathue[1]=1.1f;sathue[2]=1.1f;sathue[3]=1.0f ;sathue[4]=0.4f;sathue2[0]=1.0f ;sathue2[1]=1.0f ;sathue2[2]=1.0f ;sathue2[3]=1.0f;}//red 0.8 0.7 + else if(/*HH>= 0.0f &&*/ HH<= 1.4f ) {sathue[0]=1.3f;sathue[1]=1.2f;sathue[2]=1.1f;sathue[3]=1.0f ;sathue[4]=0.4f;sathue2[0]=1.0f ;sathue2[1]=1.0f ;sathue2[2]=1.0f ;sathue2[3]=1.0f;}//red 0.8 0.7 + else if(/*HH> 1.4f &&*/ HH<= 2.1f ) {sathue[0]=1.0f;sathue[1]=1.0f;sathue[2]=1.0f;sathue[3]=1.0f ;sathue[4]=0.4f;sathue2[0]=1.0f ;sathue2[1]=1.0f ;sathue2[2]=1.0f ;sathue2[3]=1.0f;}//green yellow 1.2 1.1 + else /*if(HH> 2.1f && HH<= 3.1415f)*/ {sathue[0]=1.4f;sathue[1]=1.3f;sathue[2]=1.2f;sathue[3]=1.15f;sathue[4]=0.4f;sathue2[0]=1.15f;sathue2[1]=1.1f ;sathue2[2]=1.05f;sathue2[3]=1.0f;}//green + } + else if (LL< 50.0f) {//more for blue and green, less for red and green-yellow + if (/*HH> -3.1415f &&*/ HH< -1.5f ) {sathue[0]=1.5f;sathue[1]=1.4f;sathue[2]=1.3f;sathue[3]=1.2f ;sathue[4]=0.4f;sathue2[0]=1.2f ;sathue2[1]=1.1f ;sathue2[2]=1.05f;sathue2[3]=1.0f;}//blue + else if(/*HH>=-1.5f &&*/ HH< -0.7f ) {sathue[0]=1.3f;sathue[1]=1.2f;sathue[2]=1.1f;sathue[3]=1.05f;sathue[4]=0.4f;sathue2[0]=1.05f;sathue2[1]=1.05f;sathue2[2]=1.0f ;sathue2[3]=1.0f;}//blue purple 1.2 1.1 + else if(/*HH>=-0.7f &&*/ HH< 0.0f ) {sathue[0]=1.2f;sathue[1]=1.0f;sathue[2]=1.0f;sathue[3]=1.0f ;sathue[4]=0.4f;sathue2[0]=1.0f ;sathue2[1]=1.0f ;sathue2[2]=1.0f ;sathue2[3]=1.0f;}//purple + // else if( HH>= 0.0f && HH<= 1.4f ) {sathue[0]=0.8f;sathue[1]=0.8f;sathue[2]=0.8f;sathue[3]=0.8f ;sathue[4]=0.4f;sathue2[0]=0.8f ;sathue2[1]=0.8f ;sathue2[2]=0.8f ;sathue2[3]=0.8f;}//red 0.8 0.7 + else if(/*HH>= 0.0f &&*/ HH<= 1.4f ) {sathue[0]=1.1f;sathue[1]=1.0f;sathue[2]=0.9f;sathue[3]=0.8f ;sathue[4]=0.4f;sathue2[0]=0.8f ;sathue2[1]=0.8f ;sathue2[2]=0.8f ;sathue2[3]=0.8f;}//red 0.8 0.7 + else if(/*HH> 1.4f &&*/ HH<= 2.1f ) {sathue[0]=1.1f;sathue[1]=1.1f;sathue[2]=1.1f;sathue[3]=1.05f;sathue[4]=0.4f;sathue2[0]=0.9f ;sathue2[1]=0.8f ;sathue2[2]=0.7f ;sathue2[3]=0.6f;}//green yellow 1.2 1.1 + else /*if(HH> 2.1f && HH<= 3.1415f)*/ {sathue[0]=1.5f;sathue[1]=1.4f;sathue[2]=1.3f;sathue[3]=1.2f ;sathue[4]=0.4f;sathue2[0]=1.2f ;sathue2[1]=1.1f ;sathue2[2]=1.05f;sathue2[3]=1.0f;}//green + + } + else if (LL< 80.0f) {//more for green, less for red and green-yellow + if (/*HH> -3.1415f &&*/ HH< -1.5f ) {sathue[0]=1.3f;sathue[1]=1.2f;sathue[2]=1.15f;sathue[3]=1.1f ;sathue[4]=0.3f;sathue2[0]=1.1f ;sathue2[1]=1.1f ;sathue2[2]=1.05f;sathue2[3]=1.0f;}//blue + else if(/*HH>=-1.5f &&*/ HH< -0.7f ) {sathue[0]=1.3f;sathue[1]=1.2f;sathue[2]=1.15f;sathue[3]=1.1f ;sathue[4]=0.3f;sathue2[0]=1.1f ;sathue2[1]=1.05f;sathue2[2]=1.0f ;sathue2[3]=1.0f;}//blue purple 1.2 1.1 + else if(/*HH>=-0.7f &&*/ HH< 0.0f ) {sathue[0]=1.2f;sathue[1]=1.0f;sathue[2]=1.0f ;sathue[3]=1.0f ;sathue[4]=0.3f;sathue2[0]=1.0f ;sathue2[1]=1.0f ;sathue2[2]=1.0f ;sathue2[3]=1.0f;}//purple + // else if( HH>= 0.0f && HH<= 1.4f ) {sathue[0]=0.8f;sathue[1]=0.8f;sathue[2]=0.8f ;sathue[3]=0.8f ;sathue[4]=0.3f;sathue2[0]=0.8f ;sathue2[1]=0.8f ;sathue2[2]=0.8f ;sathue2[3]=0.8f;}//red 0.8 0.7 + else if(/*HH>= 0.0f &&*/ HH<= 1.4f ) {sathue[0]=1.1f;sathue[1]=1.0f;sathue[2]=0.9f ;sathue[3]=0.8f ;sathue[4]=0.3f;sathue2[0]=0.8f ;sathue2[1]=0.8f ;sathue2[2]=0.8f ;sathue2[3]=0.8f;}//red 0.8 0.7 + else if(/*HH> 1.4f &&*/ HH<= 2.1f ) {sathue[0]=1.3f;sathue[1]=1.2f;sathue[2]=1.1f ;sathue[3]=1.05f;sathue[4]=0.3f;sathue2[0]=1.0f ;sathue2[1]=0.9f ;sathue2[2]=0.8f ;sathue2[3]=0.7f;}//green yellow 1.2 1.1 + else /*if(HH> 2.1f && HH<= 3.1415f)*/ {sathue[0]=1.6f;sathue[1]=1.4f;sathue[2]=1.3f ;sathue[3]=1.25f;sathue[4]=0.3f;sathue2[0]=1.25f;sathue2[1]=1.2f ;sathue2[2]=1.15f;sathue2[3]=1.05f;}//green - even with Prophoto green are too "little" 1.5 1.3 + } + else /*if (LL>=80.0f)*/ {//more for green-yellow, less for red and purple + if (/*HH> -3.1415f &&*/ HH< -1.5f ) {sathue[0]=1.0f;sathue[1]=1.0f;sathue[2]=0.9f;sathue[3]=0.8f;sathue[4]=0.2f;sathue2[0]=0.8f;sathue2[1]=0.8f ;sathue2[2]=0.8f ;sathue2[3]=0.8f;}//blue + else if(/*HH>=-1.5f &&*/ HH< -0.7f ) {sathue[0]=1.0f;sathue[1]=1.0f;sathue[2]=0.9f;sathue[3]=0.8f;sathue[4]=0.2f;sathue2[0]=0.8f;sathue2[1]=0.8f ;sathue2[2]=0.8f ;sathue2[3]=0.8f;}//blue purple 1.2 1.1 + else if(/*HH>=-0.7f &&*/ HH< 0.0f ) {sathue[0]=1.2f;sathue[1]=1.0f;sathue[2]=1.0f;sathue[3]=0.9f;sathue[4]=0.2f;sathue2[0]=0.9f;sathue2[1]=0.9f ;sathue2[2]=0.8f ;sathue2[3]=0.8f;}//purple + // else if( HH>= 0.0f && HH<= 1.4f ) {sathue[0]=0.8f;sathue[1]=0.8f;sathue[2]=0.8f;sathue[3]=0.8f;sathue[4]=0.2f;sathue2[0]=0.8f;sathue2[1]=0.8f ;sathue2[2]=0.8f ;sathue2[3]=0.8f;}//red 0.8 0.7 + else if(/*HH>= 0.0f &&*/ HH<= 1.4f ) {sathue[0]=1.1f;sathue[1]=1.0f;sathue[2]=0.9f;sathue[3]=0.8f;sathue[4]=0.2f;sathue2[0]=0.8f;sathue2[1]=0.8f ;sathue2[2]=0.8f ;sathue2[3]=0.8f;}//red 0.8 0.7 + else if(/*HH> 1.4f &&*/ HH<= 2.1f ) {sathue[0]=1.6f;sathue[1]=1.5f;sathue[2]=1.4f;sathue[3]=1.2f;sathue[4]=0.2f;sathue2[0]=1.1f;sathue2[1]=1.05f;sathue2[2]=1.0f ;sathue2[3]=1.0f;}//green yellow 1.2 1.1 + else /*if(HH> 2.1f && HH<= 3.1415f)*/ {sathue[0]=1.4f;sathue[1]=1.3f;sathue[2]=1.2f;sathue[3]=1.1f;sathue[4]=0.2f;sathue2[0]=1.1f;sathue2[1]=1.05f;sathue2[2]=1.05f;sathue2[3]=1.0f;}//green + } + } + float chmodpastel,chmodsat; + // variables to improve transitions + float pa, pb;// transition = pa*saturation + pb + float chl00 = chromaPastel*satredu*sathue[4]; + float chl0 = chromaPastel*satredu*sathue[0]; + float chl1 = chromaPastel*satredu*sathue[1]; + float chl2 = chromaPastel*satredu*sathue[2]; + float chl3 = chromaPastel*satredu*sathue[3]; + float chs0 = chromaSatur*satredu*sathue2[0]; + float chs1 = chromaSatur*satredu*sathue2[1]; + float chs2 = chromaSatur*satredu*sathue2[2]; + float chs3 = chromaSatur*satredu*sathue2[3]; + float s3 = 1.0f; + // We handle only positive values here ; improve transitions + if (saturation < p00) chmodpastel = chl00 ; //neutral tones + else if (saturation < p0 ) { pa=(chl00-chl0)/(p00-p0); pb=chl00-pa*p00; chmodpastel = pa*saturation + pb; } + else if (saturation < p1) { pa=(chl0-chl1)/(p0-p1); pb=chl0-pa*p0; chmodpastel = pa*saturation + pb; } + else if (saturation < p2) { pa=(chl1-chl2)/(p1-p2); pb=chl1-pa*p1; chmodpastel = pa*saturation + pb; } + else if (saturation < limitpastelsatur) { pa=(chl2- chl3)/(p2-limitpastelsatur); pb=chl2-pa*p2; chmodpastel = pa*saturation + pb; } + else if (saturation < s0) { pa=(chl3-chs0)/(limitpastelsatur-s0) ; pb=chl3-pa*limitpastelsatur; chmodsat = pa*saturation + pb; } + else if (saturation < s1) { pa=(chs0-chs1)/(s0-s1); pb=chs0-pa*s0; chmodsat = pa*saturation + pb; } + else if (saturation < s2) { pa=(chs1-chs2)/(s1-s2); pb=chs1-pa*s1; chmodsat = pa*saturation + pb; } + else { pa=(chs2-chs3)/(s2-s3); pb=chs2-pa*s2; chmodsat = pa*saturation + pb; } + + if(chromaPastel != chromaSatur){ + + // Pastels + if(saturation > p2 && saturation < limitpastelsatur) { + float newchromaPastel = chromaPastel_a*saturation + chromaPastel_b; + chmodpastel = newchromaPastel*satredu*sathue[3]; + } + + // Saturated + if(saturation < s0 && saturation >=limitpastelsatur) { + float newchromaSatur=chromaSatur_a*saturation + chromaSatur_b; + chmodsat = newchromaSatur*satredu*sathue2[0]; + } + }// end transition + + if (saturation <= limitpastelsatur) { + if (chmodpastel > 2.0f ) + chmodpastel = 2.0f; //avoid too big values + else if(chmodpastel < -0.93f) + chmodpastel =-0.93f; //avoid negative values + + Chprov *=(1.0f+chmodpastel); + if(Chprov<6.0f) + Chprov=6.0f; + } + else { //if (saturation > limitpastelsatur) + if (chmodsat > 1.8f ) + chmodsat = 1.8f; //saturated + else if(chmodsat < -0.93f) + chmodsat =-0.93f; + + Chprov *= 1.0f+chmodsat; + if(Chprov < 6.0f) + Chprov=6.0f; + } + } + } + + bool hhModified = false; + // Vibrance's Skin curve + if(skinCurveIsSet) { + if (HH>skbeg && HH transition + float HHsk=ask*HH+bsk; + float Hn=(skin_curve[HHsk]-bsk)/ask; + float Hc=(Hn*xx+HH*(1.0f-xx)); + HH=Hc; + hhModified = true; + } + else if(Chprov < (60.0f+dchr)) {//transition chroma + float HHsk=ask*HH+bsk; + float Hn=(skin_curve[HHsk]-bsk)/ask; + float Hc=(Hn*xx+HH*(1.0f-xx)); + float aa= (HH-Hc)/dchr ; float bb= HH-(60.0f+dchr)*aa; + HH=aa*Chprov+bb; + hhModified = true; + } + } + //transition hue + else if(HH>(skbeg-dhue) && HH<=skbeg && Chprov < (60.0f+dchr*0.5f)) { + float HHsk=ask*skbeg+bsk; + float Hn=(skin_curve[HHsk]-bsk)/ask; + float Hcc=(Hn*xx+skbeg*(1.0f-xx)); + float adh=(Hcc-(skbeg-dhue))/(dhue); + float bdh=Hcc-adh*skbeg; + HH=adh*HH+bdh; + hhModified = true; + } + else if(HH>=skend && HH<(skend+dhue) && Chprov < (60.0f+dchr*0.5f)) { + float HHsk=ask*skend+bsk; + float Hn=(skin_curve[HHsk]-bsk)/ask; + float Hcc=(Hn*xx+skend*(1.0f-xx)); + float adh=(skend+dhue-Hcc)/(dhue); + float bdh=Hcc-adh*skend; + HH=adh*HH+bdh; + hhModified = true; + } + } // end skin hue + + //Munsell correction +// float2 sincosval; + if(!avoidcolorshift && hhModified) + sincosval = xsincosf(HH); + float aprovn,bprovn; + bool inGamut; + do { + inGamut=true; + if(avoidcolorshift) { + float correctionHue=0.0f; + float correctlum=0.0f; + +#ifdef _DEBUG + Color::AllMunsellLch(/*lumaMuns*/false, Lprov,Lprov,HH,Chprov,CC,correctionHue,correctlum, MunsDebugInfo); +#else + Color::AllMunsellLch(/*lumaMuns*/false, Lprov,Lprov,HH,Chprov,CC,correctionHue,correctlum); +#endif + if(correctionHue != 0.f || hhModified) { + sincosval = xsincosf(HH+correctionHue); + hhModified = false; + } + } + aprovn=Chprov*sincosval.y; + bprovn=Chprov*sincosval.x; + + float fyy = (0.00862069f *Lprov )+ 0.137932f; + float fxx = (0.002f * aprovn) + fyy; + float fzz = fyy - (0.005f * bprovn); + float xx_ = 65535.f * Color::f2xyz(fxx)*Color::D50x; + // float yy_ = 65535.0f * Color::f2xyz(fyy); + float zz_ = 65535.f * Color::f2xyz(fzz)*Color::D50z; + float yy_ = 65535.f * ((Lprov>Color::epskap) ? fyy*fyy*fyy : Lprov/Color::kappa); + + Color::xyz2rgb(xx_,yy_,zz_,R,G,B,wip); + + if(R<0.0f || G<0.0f || B<0.0f) { +#ifdef _DEBUG + negsat++; +#endif + Chprov *= 0.98f; + inGamut = false; + } + + // if "highlight reconstruction" enabled don't control Gamut for highlights + if((!highlight) && (R>65535.0f || G>65535.0f || B>65535.0f)) { +#ifdef _DEBUG + moresat++; +#endif + Chprov *= 0.98f; + inGamut = false; + } + } while (!inGamut); + + //put new values in Lab + lab->L[i][j]=Lprov*327.68f; + lab->a[i][j]=aprovn*327.68f; + lab->b[i][j]=bprovn*327.68f; + } + +} // end of parallelization + +#ifdef _DEBUG + t2e.set(); + if (settings->verbose) { + printf("Vibrance (performed in %d usec):\n", t2e.etime(t1e)); + printf(" Gamut: G1negat=%iiter G165535=%iiter G2negsat=%iiter G265535=%iiter\n",negat,moreRGB,negsat,moresat); + if (MunsDebugInfo) + printf(" Munsell chrominance: MaxBP=%1.2frad MaxRY=%1.2frad MaxGY=%1.2frad MaxRP=%1.2frad depass=%i\n", MunsDebugInfo->maxdhue[0], MunsDebugInfo->maxdhue[1], MunsDebugInfo->maxdhue[2], MunsDebugInfo->maxdhue[3], MunsDebugInfo->depass); + } + if (MunsDebugInfo) + delete MunsDebugInfo; +#endif + +} + + +} diff --git a/rtengine/ipwavelet.cc b/rtengine/ipwavelet.cc new file mode 100644 index 000000000..eb87c0924 --- /dev/null +++ b/rtengine/ipwavelet.cc @@ -0,0 +1,2881 @@ +//////////////////////////////////////////////////////////////// +// +// +// +// +// code dated: December , 2014 +// +// Ipwaveletcc is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// * 2014 Jacques Desmis +// * 2014 Ingo Weyrich + +// +//////////////////////////////////////////////////////////////// + + + +#include +#include "../rtgui/threadutils.h" + +#include "rtengine.h" +#include "improcfun.h" +#include "LUT.h" +#include "array2D.h" +#include "boxblur.h" +#include "rt_math.h" +#include "mytime.h" +#include "sleef.c" +#include "opthelper.h" +#include "StopWatch.h" +#include "EdgePreservingDecomposition.h" + +#ifdef _OPENMP +#include +#endif + +#include "cplx_wavelet_dec.h" + +#define TS 64 // Tile size +#define offset 25 // shift between tiles +#define fTS ((TS/2+1)) // second dimension of Fourier tiles +#define blkrad 1 // radius of block averaging + +#define PIX_SORT(a,b) { if ((a)>(b)) {temp=(a);(a)=(b);(b)=temp;} } + +#define med3(a0,a1,a2,a3,a4,a5,a6,a7,a8,median) { \ +pp[0]=a0; pp[1]=a1; pp[2]=a2; pp[3]=a3; pp[4]=a4; pp[5]=a5; pp[6]=a6; pp[7]=a7; pp[8]=a8; \ +PIX_SORT(pp[1],pp[2]); PIX_SORT(pp[4],pp[5]); PIX_SORT(pp[7],pp[8]); \ +PIX_SORT(pp[0],pp[1]); PIX_SORT(pp[3],pp[4]); PIX_SORT(pp[6],pp[7]); \ +PIX_SORT(pp[1],pp[2]); PIX_SORT(pp[4],pp[5]); PIX_SORT(pp[7],pp[8]); \ +PIX_SORT(pp[0],pp[3]); PIX_SORT(pp[5],pp[8]); PIX_SORT(pp[4],pp[7]); \ +PIX_SORT(pp[3],pp[6]); PIX_SORT(pp[1],pp[4]); PIX_SORT(pp[2],pp[5]); \ +PIX_SORT(pp[4],pp[7]); PIX_SORT(pp[4],pp[2]); PIX_SORT(pp[6],pp[4]); \ +PIX_SORT(pp[4],pp[2]); median=pp[4];} //pp4 = median + + +#define med2(a0,a1,a2,a3,a4,median) { \ +pp[0]=a0; pp[1]=a1; pp[2]=a2; pp[3]=a3; pp[4]=a4; \ +PIX_SORT(pp[0],pp[1]) ; PIX_SORT(pp[3],pp[4]) ; PIX_SORT(pp[0],pp[3]) ;\ +PIX_SORT(pp[1],pp[4]) ; PIX_SORT(pp[1],pp[2]) ; PIX_SORT(pp[2],pp[3]) ;\ +PIX_SORT(pp[1],pp[2]) ; median=pp[2] ;} + + +#define epsilon 0.001f/(TS*TS) //tolerance + + +namespace rtengine { + +extern const Settings* settings; + +struct cont_params { + float mul[10]; + int chrom; + int chro; + int contrast; + float th; + float thH; + float conres; + float conresH; + float chrores; + float hueres; + float sky; + float b_l,t_l,b_r,t_r; + float b_ly,t_ly,b_ry,t_ry; + float b_lsl,t_lsl,b_rsl,t_rsl; + float b_lhl,t_lhl,b_rhl,t_rhl; + float edg_low, edg_mean, edg_sd, edg_max; + float lev0s, lev0n, lev1s, lev1n, lev2s, lev2n; + float b_lpast,t_lpast,b_rpast,t_rpast; + float b_lsat,t_lsat,b_rsat,t_rsat; + int rad; + int val; + int til; + int numlevH, numlevS; + float mulC[9]; + float mulopaRG[9]; + float mulopaBY[9]; + bool curv; + bool opaBY; + bool opaRG; + bool edgcurv; + bool diagcurv; + int CHmet; + int CHSLmet; + int EDmet; + bool HSmet; + bool avoi; + float strength; + int reinforce; + bool detectedge; + int backm; + float eddet; + float eddetthr; + bool lips; + float eddetthrHi; + bool link; + bool lip3; + bool tonemap; + bool diag; + int TMmeth; + float tmstrength; + float balan; + int ite; + int contmet; + bool opaW; + int BAmet; + bool bam; + float blhigh; + float grhigh; + float blmed; + float grmed; + float bllow; + float grlow; + bool cbena; + +}; + +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) + + +{ + MyTime t1e,t2e ; + t1e.set(); + +#ifdef _DEBUG + // init variables to display Munsell corrections + MunsellDebugInfo* MunsDebugInfo = new MunsellDebugInfo(); +#endif + TMatrix wiprof = iccStore->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]} + }; + const short int imheight=lab->H, imwidth=lab->W; + struct cont_params cp; + cp.avoi = params->wavelet.avoid; + if(params->wavelet.Medgreinf=="more") cp.reinforce = 1; + if(params->wavelet.Medgreinf=="none") cp.reinforce = 2; + if(params->wavelet.Medgreinf=="less") cp.reinforce = 3; + cp.lip3 = params->wavelet.lipst; + cp.diag = params->wavelet.tmr; + cp.balan = (float)params->wavelet.balance; + cp.ite = params->wavelet.iter; + cp.tonemap=false; + cp.bam=false; + if(params->wavelet.tmrs==0) cp.tonemap=false; + else cp.tonemap=true; + /*else if(params->wavelet.TMmethod=="std") {cp.TMmeth=1;cp.tonemap=true;} + else if(params->wavelet.TMmethod=="high") {cp.TMmeth=2;cp.tonemap=true;} + else if(params->wavelet.TMmethod=="lowhigh") {cp.TMmeth=3;cp.tonemap=true;} + */ + if(params->wavelet.TMmethod=="cont") cp.contmet=1; + else if(params->wavelet.TMmethod=="tm") cp.contmet=2; + + if(params->wavelet.BAmethod!="none") cp.bam=true; + if(params->wavelet.BAmethod=="sli") cp.BAmet=1; + if(params->wavelet.BAmethod=="cur") cp.BAmet=2; + + cp.tmstrength=params->wavelet.tmrs; + //cp.tonemap = params->wavelet.tmr; + + if(params->wavelet.Backmethod=="black") cp.backm= 0; + if(params->wavelet.Backmethod=="grey") cp.backm = 1; + if(params->wavelet.Backmethod=="resid") cp.backm = 2; + cp.link=params->wavelet.linkedg; + cp.eddet=(float) params->wavelet.edgedetect; + cp.eddetthr=(float) params->wavelet.edgedetectthr; + cp.eddetthrHi=(float) params->wavelet.edgedetectthr2; + int N=imheight*imwidth; + int maxmul=params->wavelet.thres; + static const float scales[10] = {1.f,2.f,4.f,8.f,16.f,32.f,64.f,128.f,256.f,512.f}; + float scaleskip[10]; + for(int sc=0;sc<10;sc++) + scaleskip[sc]=scales[sc]/skip; + float atten0 = 0.40f; + float atten123=0.90f; + + //int DaubLen = settings->daubech ? 8 : 6; + int DaubLen; + if(params->wavelet.daubcoeffmethod=="2_") DaubLen=4; + if(params->wavelet.daubcoeffmethod=="4_") DaubLen=6; + if(params->wavelet.daubcoeffmethod=="6_") DaubLen=8; + if(params->wavelet.daubcoeffmethod=="10_") DaubLen=12; + if(params->wavelet.daubcoeffmethod=="14_") DaubLen=16; + + cp.CHSLmet=1; +// if(params->wavelet.CHSLmethod=="SL") cp.CHSLmet=1; +// if(params->wavelet.CHSLmethod=="CU") cp.CHSLmet=2; + cp.EDmet=1; + if(params->wavelet.EDmethod=="SL") cp.EDmet=1; + if(params->wavelet.EDmethod=="CU") cp.EDmet=2; + + cp.cbena= params->wavelet.cbenab; + cp.blhigh=(float)params->wavelet.bluehigh; + cp.grhigh=(float)params->wavelet.greenhigh; + cp.blmed=(float)params->wavelet.bluemed; + cp.grmed=(float)params->wavelet.greenmed; + cp.bllow=(float)params->wavelet.bluelow; + cp.grlow=(float)params->wavelet.greenlow; + cp.curv=false; + cp.edgcurv=false; + cp.diagcurv=false; + cp.opaRG=false; + cp.opaBY=false; + cp.opaW=false; + cp.CHmet=0; + cp.HSmet=false; + if(params->wavelet.CHmethod=="with") cp.CHmet=1; + if(params->wavelet.CHmethod=="link") cp.CHmet=2; + if(params->wavelet.HSmethod=="with") cp.HSmet=true; + + cp.strength = min(1.f,max(0.f,((float)params->wavelet.strength / 100.f))); + + for(int m=0;mverbose) printf("Wav mul 0=%f 1=%f 2=%f 3=%f 4=%f 5=%f 6=%f 7=%f 8=%f 9=%f\n",cp.mul[0],cp.mul[1],cp.mul[2],cp.mul[3],cp.mul[4],cp.mul[5],cp.mul[6],cp.mul[7],cp.mul[8],cp.mul[9]); + for(int sc=0;sc<9;sc++) {//reduce strength if zoom < 100% for chroma and tuning + if(sc==0) {if(scaleskip[sc] < 1.f) {cp.mulC[sc]*=(atten0*scaleskip[sc]);cp.mulopaRG[sc]*=(atten0*scaleskip[sc]);cp.mulopaBY[sc]*=(atten0*scaleskip[sc]);}} + else {if(scaleskip[sc] < 1.f) {cp.mulC[sc]*=(atten123*scaleskip[sc]);cp.mulopaRG[sc]*=(atten123*scaleskip[sc]);cp.mulopaBY[sc]*=(atten123*scaleskip[sc]);}} + } + + cp.chro=waparams.chro; + cp.chrom=waparams.chroma; + cp.contrast=waparams.contrast; + cp.rad=waparams.edgrad; + cp.val=waparams.edgval; + cp.til=waparams.edgthresh; + + cp.conres=waparams.rescon; + cp.conresH=waparams.resconH; + cp.chrores=waparams.reschro; + //cp.hueres=waparams.reshue; + cp.hueres=2.f; + cp.th=float(waparams.thr); + cp.thH=float(waparams.thrH); + cp.sky=waparams.sky; + //skin + cp.b_l = static_cast(params->wavelet.hueskin.value[0]) / 100.0f; + cp.t_l = static_cast(params->wavelet.hueskin.value[1]) / 100.0f; + cp.b_r = static_cast(params->wavelet.hueskin.value[2]) / 100.0f; + cp.t_r = static_cast(params->wavelet.hueskin.value[3]) / 100.0f; + + cp.b_ly = static_cast(params->wavelet.hueskin2.value[0]) / 100.0f; + cp.t_ly = static_cast(params->wavelet.hueskin2.value[1]) / 100.0f; + cp.b_ry = static_cast(params->wavelet.hueskin2.value[2]) / 100.0f; + cp.t_ry = static_cast(params->wavelet.hueskin2.value[3]) / 100.0f; + cp.numlevH=params->wavelet.threshold; + + //shadows + cp.b_lsl = static_cast(params->wavelet.bllev.value[0]); + cp.t_lsl = static_cast(params->wavelet.bllev.value[1]); + cp.b_rsl = static_cast(params->wavelet.bllev.value[2]); + cp.t_rsl = static_cast(params->wavelet.bllev.value[3]); + cp.numlevS=params->wavelet.threshold2; + int maxlevS=9-cp.numlevH; + cp.numlevS = MIN(cp.numlevS,maxlevS); + //printf("levHigh=%d levShad=%d\n",cp.numlevH,cp.numlevS); + //highlight + cp.b_lhl = static_cast(params->wavelet.hllev.value[0]); + cp.t_lhl = static_cast(params->wavelet.hllev.value[1]); + cp.b_rhl = static_cast(params->wavelet.hllev.value[2]); + cp.t_rhl = static_cast(params->wavelet.hllev.value[3]); + //printf("BL=%f TL=%f BR=%f TR=%f\n",cp.b_lhl,cp.t_lhl,cp.b_rhl,cp.t_rhl); + //pastel + cp.b_lpast = static_cast(params->wavelet.pastlev.value[0]); + cp.t_lpast = static_cast(params->wavelet.pastlev.value[1]); + cp.b_rpast = static_cast(params->wavelet.pastlev.value[2]); + cp.t_rpast = static_cast(params->wavelet.pastlev.value[3]); + //saturated + cp.b_lsat = static_cast(params->wavelet.satlev.value[0]); + cp.t_lsat = static_cast(params->wavelet.satlev.value[1]); + cp.b_rsat = static_cast(params->wavelet.satlev.value[2]); + cp.t_rsat = static_cast(params->wavelet.satlev.value[3]); + //edge local contrast + cp.edg_low = static_cast(params->wavelet.edgcont.value[0]); + cp.edg_mean = static_cast(params->wavelet.edgcont.value[1]); + cp.edg_max = static_cast(params->wavelet.edgcont.value[2]); + cp.edg_sd = static_cast(params->wavelet.edgcont.value[3]); + //level noise + cp.lev0s =static_cast(params->wavelet.level0noise.value[0]); + cp.lev0n =static_cast(params->wavelet.level0noise.value[1]); + cp.lev1s =static_cast(params->wavelet.level1noise.value[0]); + cp.lev1n =static_cast(params->wavelet.level1noise.value[1]); + cp.lev2s =static_cast(params->wavelet.level2noise.value[0]); + cp.lev2n =static_cast(params->wavelet.level2noise.value[1]); + + cp.detectedge = false; + cp.detectedge = params->wavelet.medianlev; + //printf("low=%f mean=%f sd=%f max=%f\n",cp.edg_low,cp.edg_mean,cp.edg_sd,cp.edg_max); + int minwin=min(imwidth,imheight); + int maxlevelcrop=9; + if(cp.mul[9]!=0) + maxlevelcrop=10; + // adap maximum level wavelet to size of crop + if(minwin*skip < 1024) maxlevelcrop = 9;//sampling wavelet 512 + if(minwin*skip < 512) maxlevelcrop = 8;//sampling wavelet 256 + if(minwin*skip < 256) maxlevelcrop = 7;//sampling 128 + if(minwin*skip < 128) maxlevelcrop = 6; + if(minwin < 64) maxlevelcrop = 5; + // printf("minwin=%d maxcrop=%d\n",minwin, maxlevelcrop); + + int levwav=params->wavelet.thres; + if(levwav==9 && cp.mul[9]!=0) levwav=10; + levwav=min(maxlevelcrop,levwav); + // determine number of levels to process. + // for(levwav=min(maxlevelcrop,levwav);levwav>0;levwav--) + // if(cp.mul[levwav-1]!=0.f || cp.curv) + // if(cp.mul[levwav-1]!=0.f) + // break; + // I suppress this fonctionality ==> crash for level < 3 + if(levwav<1) + return; // nothing to do + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // begin tile processing of image + + //output buffer + int realtile; + if(params->wavelet.Tilesmethod=="big") realtile=22; + if(params->wavelet.Tilesmethod=="lit") realtile=12; + + int tilesize; + int overlap; + tilesize = 1024; + overlap = 128; + //tilesize=128*params->wavelet.tiles; + tilesize=128*realtile; + //overlap=(int) tilesize*params->wavelet.overl; + overlap=(int) tilesize*0.125f; + // printf("overl=%d\n",overlap); + int numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip; + if(params->wavelet.Tilesmethod=="full") kall=0; + Tile_calc (tilesize, overlap, kall, imwidth, imheight, numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip); + + const int numtiles = numtiles_W*numtiles_H; + LabImage * dsttmp; + if(numtiles == 1) { + dsttmp = dst; + } else { + dsttmp = new LabImage(imwidth,imheight); + for (int n=0; n<3*imwidth*imheight; n++) dsttmp->data[n] = 0; + } + //now we have tile dimensions, overlaps + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + int minsizetile=min(tilewidth, tileheight); + int maxlev2=10; + if(minsizetile < 1024 && levwav==10) maxlev2 = 9; + if(minsizetile < 512) maxlev2 = 8; + if(minsizetile < 256) maxlev2 = 7; + if(minsizetile < 128) maxlev2 = 6; + levwav=min(maxlev2,levwav); + + //printf("levwav = %d\n",levwav); + + int numthreads = 1; + int maxnumberofthreadsforwavelet =0; + //reduce memory for big tile size + if(kall!=0) { + if(realtile <= 22) maxnumberofthreadsforwavelet=2; + if(realtile <= 20) maxnumberofthreadsforwavelet=3; + if(realtile <= 18) maxnumberofthreadsforwavelet=4; + if(realtile <= 16) maxnumberofthreadsforwavelet=6; + if(realtile <= 14) maxnumberofthreadsforwavelet=8; + //printf("maxNRT=%d\n",maxnumberofthreadsforwavelet); + if((maxnumberofthreadsforwavelet==6 || maxnumberofthreadsforwavelet==8) && levwav==10) maxnumberofthreadsforwavelet-=2; + if(levwav <=7 && maxnumberofthreadsforwavelet ==8) maxnumberofthreadsforwavelet=0; + } + //printf("maxthre=%d\n",maxnumberofthreadsforwavelet); + +#ifdef _OPENMP + // Calculate number of tiles. If less than omp_get_max_threads(), then limit num_threads to number of tiles + if( options.rgbDenoiseThreadLimit>0) + maxnumberofthreadsforwavelet = min(max(options.rgbDenoiseThreadLimit / 2, 1), maxnumberofthreadsforwavelet); + + numthreads = MIN(numtiles,omp_get_max_threads()); + if(maxnumberofthreadsforwavelet > 0) + numthreads = MIN(numthreads,maxnumberofthreadsforwavelet); +#ifdef _RT_NESTED_OPENMP + wavNestedLevels = omp_get_max_threads() / numthreads; + bool oldNested = omp_get_nested(); + if(wavNestedLevels < 2) + wavNestedLevels = 1; + else + omp_set_nested(true); + if(maxnumberofthreadsforwavelet > 0) + while(wavNestedLevels*numthreads > maxnumberofthreadsforwavelet) + wavNestedLevels--; +#endif + if(settings->verbose) + printf("Ip Wavelet uses %d main thread(s) and up to %d nested thread(s) for each main thread\n",numthreads,wavNestedLevels); + + +#endif + +#ifdef _OPENMP +#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** varhue = new float*[tileheight]; + for (int i=0; i we can use output buffer for labco + labco = dst; + if(cp.avoi) { // we need a buffer to hold a copy of the L channel + Lold = new float*[tileheight]; + LoldBuffer = new float[tilewidth*tileheight]; + memcpy(LoldBuffer, lab->L[0], tilewidth*tileheight*sizeof(float)); + for (int i=0; iL; + } + +#ifdef _RT_NESTED_OPENMP +#pragma omp parallel for num_threads(wavNestedLevels) if(wavNestedLevels>1) +#endif + + for (int i=tiletop; ia[i][j]); + bv = LVFU(lab->b[i][j]); + huev = xatan2f(bv,av); + chrov = _mm_sqrt_ps(SQRV(av)+SQRV(bv)) / c327d68v; + _mm_storeu_ps(&varhue[i1][j1],huev); + _mm_storeu_ps(&varchro[i1][j1], chrov); + if(labco != lab) { + _mm_storeu_ps(&(labco->L[i1][j1]),LVFU(lab->L[i][j])); + _mm_storeu_ps(&(labco->a[i1][j1]),av); + _mm_storeu_ps(&(labco->b[i1][j1]),bv); + } + } +#else + j=tileleft; +#endif + for (; ja[i][j]; + float b=lab->b[i][j]; + varhue[i1][j1]=xatan2f(b,a); + varchro[i1][j1]=(sqrtf(a*a+b*b))/327.68f; + if(labco != lab) { + labco->L[i1][j1] = lab->L[i][j]; + labco->a[i1][j1] = a; + labco->b[i1][j1] = b; + } + } + } + //to avoid artifacts in blue sky + if(params->wavelet.median) { + float** tmL; + int wid=labco->W; + int hei=labco->H; + int borderL = 1; + tmL = new float*[hei]; + for (int i=0; iL[i][j]; + } + } + +#ifdef _RT_NESTED_OPENMP +#pragma omp parallel for num_threads(wavNestedLevels) if(wavNestedLevels>1) +#endif + for (int i=1; i - 2.5f) && (varchro[i][j] > 15.f && varchro[i][j] < 55.f) && labco->L[i][j] > 6000.f) //blue sky + med3x3 ==> after for more effect use denoise + med3(labco->L[i][j] ,labco->L[i-1][j], labco->L[i+1][j] ,labco->L[i][j+1],labco->L[i][j-1], labco->L[i-1][j-1],labco->L[i-1][j+1],labco->L[i+1][j-1],labco->L[i+1][j+1],tmL[i][j]);//3x3 + } + } + for(int i = borderL; i < hei-borderL; i++ ) { + for(int j = borderL; j < wid-borderL; j++) { + labco->L[i][j] = tmL[i][j]; + } + } + + for (int i=0; iW * labco->H; + + int levwavL = levwav; + bool ref0=false; + if(cp.lev0s > 0.f || cp.lev1s > 0.f || cp.lev2s > 0.f) ref0=true; + + // printf("LevwavL before: %d\n",levwavL); + if(cp.contrast == 0.f && cp.tonemap==false && cp.conres == 0.f && cp.conresH == 0.f && cp.val ==0 && !ref0 && params->wavelet.CLmethod=="all") { // no processing of residual L or edge=> we probably can reduce the number of levels + while(levwavL > 0 && cp.mul[levwavL-1] == 0.f) // cp.mul[level] == 0.f means no changes to level + levwavL--; + } + // printf("LevwavL after: %d\n",levwavL); + if(levwavL < 3) levwavL=3;//to allow edge => I always allocate 3 levels..because if user select wavelet it is to do something !! + if(levwavL > 0) { + wavelet_decomposition* Ldecomp = new wavelet_decomposition (labco->data, labco->W, labco->H, levwavL, 1, skip, max(1,wavNestedLevels), DaubLen ); + if(!Ldecomp->memoryAllocationFailed) { + + float madL[8][3]; + bool memoryAllocationFailed = false; +#ifdef _RT_NESTED_OPENMP +#pragma omp parallel for schedule(dynamic) collapse(2) num_threads(wavNestedLevels) if(wavNestedLevels>1) +#endif + for (int lvl=0; lvl<3; lvl++) { + for (int dir=1; dir<4; dir++) { + int Wlvl_L = Ldecomp->level_W(lvl); + int Hlvl_L = Ldecomp->level_H(lvl); + + float ** WavCoeffs_L = Ldecomp->level_coeffs(lvl); + + madL[lvl][dir-1] = SQR(Mad(WavCoeffs_L[dir], Wlvl_L*Hlvl_L)); + } + } + int ind=0; + bool ref=false; + if(cp.lev0s > 0.f || cp.lev1s > 0.f || cp.lev2s > 0.f) ref=true; + bool contr=false; + for(int f=0;f 0 || ref || contr) {//edge + Evaluate2(*Ldecomp, cp, ind, mean, meanN, sigma, sigmaN, MaxP, MaxN, madL); + } + //init for edge and denoise + float vari[3]; + + vari[0]=8.f*SQR((cp.lev0n/125.0)*(1.0+ cp.lev0n/25.0)); + vari[1]=8.f*SQR((cp.lev1n/125.0)*(1.0+ cp.lev1n/25.0)); + vari[2]=8.f*SQR((cp.lev2n/125.0)*(1.0+ cp.lev2n/25.0)); + int edge=1; + if(cp.lev0n > 0.1f || cp.lev1n > 0.1f || cp.lev2n > 0.1f) { + vari[0] = max(0.0001f,vari[0]); + vari[1] = max(0.0001f,vari[1]); + vari[2] = max(0.0001f,vari[2]); + float* noisevarlum = NULL; // we need a dummy to pass it to WaveletDenoiseAllL + if(!WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL, vari, edge))// + memoryAllocationFailed = true; + } + ind=1; + //Flat curve for Contrast=f(H) in levels + FlatCurve* ChCurve = NULL;//curve C=f(H) + bool Chutili = false; + ChCurve = new FlatCurve(params->wavelet.Chcurve); + if (!ChCurve || ChCurve->isIdentity()) { + if (ChCurve) { + delete ChCurve; + ChCurve = NULL; + } + } else + Chutili = true; + + + WaveletcontAllL(labco, varhue, varchro, *Ldecomp, cp, skip, mean, meanN, sigma, sigmaN, MaxP, MaxN, wavCLVCcurve, waOpacityCurveW, waOpacityCurveWL, ChCurve, Chutili); + if(cp.val > 0 || ref || contr || cp.diagcurv) {//edge + Evaluate2(*Ldecomp, cp, ind, mean, meanN, sigma, sigmaN, MaxP, MaxN, madL); + } + WaveletcontAllLfinal(labco, varhue, varchro, *Ldecomp, cp, skip, mean, meanN, sigma, sigmaN, MaxP, MaxN, wavCLVCcurve, waOpacityCurveWL, ChCurve, Chutili); + //Evaluate2(*Ldecomp, cp, ind, mean, meanN, sigma, sigmaN, MaxP, MaxN, madL); + + Ldecomp->reconstruct(labco->data, cp.strength); + } + delete Ldecomp; + } + //Flat curve for H=f(H) in residual image + FlatCurve* hhCurve = NULL;//curve H=f(H) + bool hhutili = false; + hhCurve = new FlatCurve(params->wavelet.hhcurve); + if (!hhCurve || hhCurve->isIdentity()) { + if (hhCurve) { + delete hhCurve; + hhCurve = NULL; + } + } else + hhutili = true; + + + if(!hhutili) {//always a or b + int levwava = levwav; + // printf("Levwava before: %d\n",levwava); + if(cp.chrores == 0.f && params->wavelet.CLmethod=="all" && !cp.cbena) { // no processing of residual ab => we probably can reduce the number of levels + while(levwava > 0 && !cp.diag &&(((cp.CHmet==2 && (cp.chro == 0.f || cp.mul[levwava-1] == 0.f )) || (cp.CHmet!=2 && (levwava == 10 || (!cp.curv || (cp.curv && cp.mulC[levwava-1] == 0.f)))))) && (!cp.opaRG || levwava == 10 || (cp.opaRG && cp.mulopaRG[levwava-1] == 0.f)) && ((levwava == 10 ||(cp.CHSLmet==1 && cp.mulC[levwava-1] == 0.f)))) { + levwava--; + } + } + //printf("Levwava after: %d\n",levwava); + if(levwava > 0) { + wavelet_decomposition* adecomp = new wavelet_decomposition (labco->data+datalen, labco->W, labco->H,levwava, 1, skip, max(1,wavNestedLevels), DaubLen ); + if(!adecomp->memoryAllocationFailed) { + WaveletcontAllAB(labco, varhue, varchro, *adecomp, waOpacityCurveW, cp, true); + adecomp->reconstruct(labco->data+datalen, cp.strength); + } + delete adecomp; + } + int levwavb = levwav; + //printf("Levwavb before: %d\n",levwavb); + if(cp.chrores == 0.f && params->wavelet.CLmethod=="all" && !cp.cbena) { // no processing of residual ab => we probably can reduce the number of levels + while(levwavb > 0 && !cp.diag && (((cp.CHmet==2 && (cp.chro == 0.f || cp.mul[levwavb-1] == 0.f )) || (cp.CHmet!=2 && (levwavb == 10 || (!cp.curv || (cp.curv && cp.mulC[levwavb-1] == 0.f)))))) && (!cp.opaBY || levwavb == 10 || (cp.opaBY && cp.mulopaBY[levwavb-1] == 0.f)) && ((levwavb == 10 ||(cp.CHSLmet==1 && cp.mulC[levwavb-1] == 0.f)))) { + levwavb--; + } + } + // printf("Levwavb after: %d\n",levwavb); + if(levwavb > 0) { + wavelet_decomposition* bdecomp = new wavelet_decomposition (labco->data+2*datalen, labco->W, labco->H, levwavb, 1, skip, max(1,wavNestedLevels), DaubLen ); + if(!bdecomp->memoryAllocationFailed) { + WaveletcontAllAB(labco, varhue, varchro, *bdecomp, waOpacityCurveW, cp, false); + bdecomp->reconstruct(labco->data+2*datalen, cp.strength); + } + delete bdecomp; + } + } else {// a and b + int levwavab = levwav; + // printf("Levwavab before: %d\n",levwavab); + if(cp.chrores == 0.f && !hhutili && params->wavelet.CLmethod=="all") { // no processing of residual ab => we probably can reduce the number of levels + while(levwavab > 0 && (((cp.CHmet==2 && (cp.chro == 0.f || cp.mul[levwavab-1] == 0.f )) || (cp.CHmet!=2 && (levwavab == 10 || (!cp.curv || (cp.curv && cp.mulC[levwavab-1] == 0.f)))))) && (!cp.opaRG || levwavab == 10 || (cp.opaRG && cp.mulopaRG[levwavab-1] == 0.f)) && ((levwavab == 10 ||(cp.CHSLmet==1 && cp.mulC[levwavab-1] == 0.f)))) { + levwavab--; + } + } + // printf("Levwavab after: %d\n",levwavab); + if(levwavab > 0) { + wavelet_decomposition* adecomp = new wavelet_decomposition (labco->data+datalen, labco->W, labco->H,levwavab, 1, skip, max(1,wavNestedLevels), DaubLen ); + wavelet_decomposition* bdecomp = new wavelet_decomposition (labco->data+2*datalen, labco->W, labco->H, levwavab, 1, skip, max(1,wavNestedLevels), DaubLen ); + if(!adecomp->memoryAllocationFailed && !bdecomp->memoryAllocationFailed) { + WaveletcontAllAB(labco, varhue, varchro, *adecomp, waOpacityCurveW, cp, true); + WaveletcontAllAB(labco, varhue, varchro, *bdecomp, waOpacityCurveW, cp, false); + WaveletAandBAllAB(labco, varhue, varchro, *adecomp, *bdecomp, cp, waOpacityCurveW, hhCurve, hhutili ); + + adecomp->reconstruct(labco->data+datalen, cp.strength); + bdecomp->reconstruct(labco->data+2*datalen, cp.strength); + + } + delete adecomp; + delete bdecomp; + } + } + if (hhCurve) + delete hhCurve; + + if(numtiles > 1 || (numtiles == 1 /*&& cp.avoi*/)) {//in all case since I add contrast curve + //calculate mask for feathering output tile overlaps + float Vmask[height+overlap] ALIGNED16; + float Hmask[width+overlap] ALIGNED16; + + if(numtiles > 1) { + for (int i=0; i0) Vmask[i] = mask; + if (tilebottom0) Hmask[i] = mask; + if (tilerighttoneCurve.hrenabled; + +#ifdef _RT_NESTED_OPENMP +#pragma omp parallel for schedule(dynamic,16) num_threads(wavNestedLevels) if(wavNestedLevels>1) +#endif + for (int i=tiletop; ia[i1][col]); + bv = LVFU(labco->b[i1][col]); + _mm_store_ps(&atan2Buffer[col],xatan2f(bv,av)); + + cv = _mm_sqrt_ps(SQRV(av)+SQRV(bv)); + yv = av / cv; + xv = bv / cv; + xyMask = vmaskf_eq(zerov, cv); + yv = vself(xyMask, onev, yv); + xv = vself(xyMask, zerov, xv); + _mm_store_ps(&yBuffer[col],yv); + _mm_store_ps(&xBuffer[col],xv); + _mm_store_ps(&chprovBuffer[col], cv / c327d68v); + + } + for(;cola[i1][col]; + float b = labco->b[i1][col]; + atan2Buffer[col] = xatan2f(b,a); + float Chprov1=sqrtf(SQR(a) + SQR(b)); + yBuffer[col] = (Chprov1 == 0.f) ? 1.f : a/Chprov1; + xBuffer[col] = (Chprov1 == 0.f) ? 0.f : b/Chprov1; + chprovBuffer[col] = Chprov1/327.68; + } + } +#endif + + for (int j=tileleft; ja[i1][j1]; + b = labco->b[i1][j1]; + float HH=xatan2f(b,a); + float Chprov1=sqrtf(SQR(a) + SQR(b)); + float2 sincosv; + sincosv.y = (Chprov1==0.0f) ? 1.f : a/(Chprov1); + sincosv.x = (Chprov1==0.0f) ? 0.f : b/(Chprov1); + Chprov1 /= 327.68f; +#endif + L = labco->L[i1][j1]; + const float Lin=labco->L[i1][j1]; + + if(wavclCurve) {labco->L[i1][j1] =(0.5f*Lin + 1.5f*wavclCurve[Lin])/2.f;}//apply contrast curve + L = labco->L[i1][j1]; + + float Lprov1=L/327.68f; + float Lprov2 = Lold[i][j]/327.68f; + float memChprov=varchro[i1][j1]; + float R,G,B; +#ifdef _DEBUG + bool neg=false; + bool more_rgb=false; + Color::gamutLchonly(HH,sincosv, Lprov1,Chprov1, R, G, B, wip, highlight, 0.15f, 0.96f, neg, more_rgb); +#else + Color::gamutLchonly(HH,sincosv, Lprov1,Chprov1, R, G, B, wip, highlight, 0.15f, 0.96f); +#endif + L=Lprov1*327.68f; + + a=327.68f*Chprov1*sincosv.y;//gamut + b=327.68f*Chprov1*sincosv.x;//gamut + float correctionHue=0.0f; // Munsell's correction + float correctlum=0.0f; + Lprov1=L/327.68f; + float Chprov=sqrtf(SQR(a)+ SQR(b))/327.68f; +#ifdef _DEBUG + Color::AllMunsellLch(true, Lprov1,Lprov2,HH,Chprov,memChprov,correctionHue,correctlum, MunsDebugInfo); +#else + Color::AllMunsellLch(true, Lprov1,Lprov2,HH,Chprov,memChprov,correctionHue,correctlum); +#endif + + if(correctionHue!=0.f || correctlum!=0.f) { // only calculate sin and cos if HH changed + if(fabs(correctionHue) < 0.015f) + HH+=correctlum; // correct only if correct Munsell chroma very little. + sincosv = xsincosf(HH+correctionHue); + } + + a=327.68f*Chprov*sincosv.y;// apply Munsell + b=327.68f*Chprov*sincosv.x;//aply Munsell + } else {//general case + L = labco->L[i1][j1]; + const float Lin=labco->L[i1][j1]; + + if(wavclCurve) {labco->L[i1][j1] = (0.5f*Lin + 1.5f*wavclCurve[Lin])/2.f;}//apply contrast curve + L = labco->L[i1][j1]; + a = labco->a[i1][j1]; + b = labco->b[i1][j1]; + } + if(numtiles > 1) { + float factor = Vmask[i1]*Hmask[j1]; + dsttmp->L[i][j]+= factor*L; + dsttmp->a[i][j]+= factor*a; + dsttmp->b[i][j]+= factor*b; + } else { + dsttmp->L[i][j] = L; + dsttmp->a[i][j] = a; + dsttmp->b[i][j] = b; + + } + } + } + } + if(LoldBuffer != NULL) { + delete [] LoldBuffer; + delete [] Lold; + } + if(numtiles>1) + delete labco; + } + } + for (int i=0; i 1) { + dst->CopyFrom(dsttmp); + delete dsttmp; + } + + if (settings->verbose) { + t2e.set(); + printf("Wavelet performed in %d usec:\n", t2e.etime(t1e)); + } + +}//end o + + + + +#undef TS +#undef fTS +#undef offset +#undef epsilon + + void ImProcFunctions::Aver( float * RESTRICT DataList, int datalen, float &averagePlus, float &averageNeg, float &max, float &min) { + + //find absolute mean + int countP = 0, countN = 0; + float averaP = 0.f, averaN = 0.f; + + float thres = 5.f;//different fom zero to take into account only data large enough + max=0.f; + min=0.f; +#ifdef _RT_NESTED_OPENMP +#pragma omp parallel num_threads(wavNestedLevels) if(wavNestedLevels>1) +#endif +{ + float lmax = 0.f, lmin = 0.f; +#ifdef _RT_NESTED_OPENMP +#pragma omp for reduction(+:averaP,averaN,countP,countN) nowait +#endif + for(int i=0;i= thres) { + averaP += DataList[i]; + if(DataList[i]> lmax) + lmax = DataList[i]; + countP++; + } + else if(DataList[i] < -thres) { + averaN += DataList[i]; + if(DataList[i] < lmin) + lmin = DataList[i]; + countN++; + } + } +#ifdef _RT_NESTED_OPENMP +#pragma omp critical +#endif +{ + max = max > lmax ? max : lmax; + min = min < lmin ? min : lmin; +} +} + + averagePlus=averaP/countP; + averageNeg=averaN/countN; + + } + + + void ImProcFunctions::Sigma( float * RESTRICT DataList, int datalen, float averagePlus, float averageNeg, float &sigmaPlus, float &sigmaNeg) { + int countP = 0, countN = 0; + float variP = 0.f, variN = 0.f; + float thres = 5.f;//different fom zero to take into account only data large enough + +#ifdef _RT_NESTED_OPENMP +#pragma omp parallel for reduction(+:variP,variN,countP,countN) num_threads(wavNestedLevels) if(wavNestedLevels>1) +#endif + for(int i=0;i= thres) { + variP += SQR(DataList[i] - averagePlus); + countP++; + } + else if(DataList[i] <= -thres) { + variN += SQR(DataList[i] - averageNeg); + countN++; + } + } + + sigmaPlus=sqrt(variP/countP); + sigmaNeg=sqrt(variN/countN); + + } + + void ImProcFunctions::Evaluate2(wavelet_decomposition &WaveletCoeffs_L, + struct cont_params cp, int ind, float *mean, float *meanN, float *sigma, float *sigmaN, float *MaxP, float *MaxN, float madL[8][3]){ +//StopWatch Stop1("Evaluate2"); + int maxlvl = WaveletCoeffs_L.maxlevel(); + for (int lvl=0; lvlwavelet.thres; + for (int dir=1; dir<4; dir++) { + Aver(WavCoeffs_L[dir], W_L*H_L, avLP[dir], avLN[dir], maxL[dir], minL[dir]); + Sigma(WavCoeffs_L[dir], W_L*H_L, avLP[dir], avLN[dir], sigP[dir], sigN[dir]); + // printf("dir=%d level=%d avLP=%f max=%f avLN=%f min=%f sigP=%f sigN=%f\n",dir,level,avLP[dir] ,maxL[dir], avLN[dir] ,minL[dir], sigP[dir], sigN[dir]); + } + AvL=0.f;AvN=0.f;SL=0.f;SN=0.f;maxLP=0.f;maxLN=0.f;MADL=0.f; + for (int dir=1; dir<4; dir++) { + AvL +=avLP[dir]; + AvN +=avLN[dir]; + SL +=sigP[dir]; + SN +=sigN[dir]; + maxLP += maxL[dir]; + maxLN += minL[dir]; + MADL += madL[dir]; + } + AvL/=3; + AvN/=3; + SL/=3; + SN/=3; + maxLP/=3; + maxLN/=3; + MADL/=3; + if(level < 3) MADL=sqrt(MADL);else MADL=0.f; + mean[level]=AvL; + meanN[level]=AvN; + sigma[level]=SL; + sigmaN[level]=SN; + MaxP[level]=maxLP; + MaxN[level]=maxLN; + // if(params->wavelet.CLmethod!="all") {//display only if user choose different from all + // printf("Ind=%d Level=%d MadL=%f AvL=%f AvN=%f SL=%f SN=%f maxP=%f maxN=%f\n",ind, level,MADL,mean[level],meanN[level],sigma[level],sigmaN[level],MaxP[level],MaxN[level]); + // } + } + +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){ + int n=W_L*H_L; + if(Contrast == NULL) Contrast = new float[n]; + memcpy(Contrast, Source, n*sizeof(float)); +#ifdef _RT_NESTED_OPENMP +#pragma omp parallel for +#endif + for (int i=0; i ave) { + float kh = ah*(Source[i]*100.f)+bh; + prov=32768.f*Source[i]; + Contrast[i]=ave+kh*(Source[i]*32768.f-ave); + } else { + float kl = al*(Source[i]*100.f)+bl; + prov=32768.f*Source[i]; + Contrast[i]=ave-kl*(ave-Source[i]*32768.f); + } + float diflc=Contrast[i]-prov; + diflc*=factorx; + Contrast[i] = (prov + diflc)/32768.f; + //contrast between 0 and 1 + } +*/ + Contrast[i] = Source[i] ; + + } + 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){ + + const float eps = 0.000001f; + int n=W_L*H_L; + +#ifdef __SSE2__ +#ifdef _RT_NESTED_OPENMP +#pragma omp parallel +#endif +{ + __m128 epsv = _mm_set1_ps( eps ); +#ifdef _RT_NESTED_OPENMP +#pragma omp for +#endif + for(int ii = 0; ii < n-3; ii+=4) + _mm_storeu_ps( &Source[ii], xlogf(LVFU(Source[ii]) + epsv)); +} + for(int ii = n-(n%4); ii < n; ii++) + Source[ii] = xlogf(Source[ii] + eps); + +#else +#ifdef _RT_NESTED_OPENMP +#pragma omp parallel for +#endif + for(int ii = 0; ii < n; ii++) + Source[ii] = xlogf(Source[ii] + eps); +#endif + + float *ucr =ContrastDR(Source, skip, cp, W_L, H_L, Compression,DetailBoost,max0, min0, ave, ah, bh, al, bl, factorx); + if(Compressed == NULL) Compressed = ucr; + float temp; + if(DetailBoost>0.f && DetailBoost < 0.05f ) { + float betemp=expf(-(2.f-DetailBoost+0.694f))-1.f;//0.694 = log(2) + temp = 1.2f*xlogf( -betemp); + temp /= 20.f; + } + else if(DetailBoost>=0.05f && DetailBoost < 0.25f ) { + float betemp=expf(-(2.f-DetailBoost+0.694f))-1.f;//0.694 = log(2) + temp = 1.2f*xlogf( -betemp); + temp /= (-75.f*DetailBoost+23.75f); + } + else if(DetailBoost>=0.25f) { + float betemp=expf(-(2.f-DetailBoost+0.694f))-1.f;//0.694 = log(2) + temp = 1.2f*xlogf( -betemp); + temp /= (-2.f*DetailBoost + 5.5f); + } + + else temp= (Compression - 1.0f)/20.f; +// printf("temp=%f \n", temp); + + +#ifdef __SSE2__ +#ifdef _RT_NESTED_OPENMP +#pragma omp parallel +#endif +{ + __m128 cev, uev, sourcev; + __m128 epsv = _mm_set1_ps( eps ); + __m128 DetailBoostv = _mm_set1_ps( DetailBoost ); + __m128 tempv = _mm_set1_ps( temp ); +#ifdef _RT_NESTED_OPENMP +#pragma omp for +#endif + for(int i = 0; i < n-3; i+=4){ + cev = xexpf(LVFU(Source[i]) + LVFU(ucr[i])*(tempv)) - epsv; + uev = xexpf(LVFU(ucr[i])) - epsv; + sourcev = xexpf(LVFU(Source[i])) - epsv; + _mm_storeu_ps( &Source[i], sourcev); + _mm_storeu_ps( &Compressed[i], cev + DetailBoostv * (sourcev - uev) ); + } +} + for(int i=n-(n%4); i < n; i++){ + float ce = xexpf(Source[i] + ucr[i]*(temp)) - eps; + float ue = xexpf(ucr[i]) - eps; + Source[i] = xexpf(Source[i]) - eps; + Compressed[i] = ce + DetailBoost*(Source[i] - ue); + } + +#else +#ifdef _RT_NESTED_OPENMP +#pragma omp parallel for +#endif + for(int i = 0; i < n; i++){ + float ce = xexpf(Source[i] + ucr[i]*(temp)) - eps; + float ue = xexpf(ucr[i]) - eps; + Source[i] = xexpf(Source[i]) - eps; + Compressed[i] = ce + DetailBoost*(Source[i] - ue); + } +#endif + + if(Compressed != ucr) delete[] ucr; + return Compressed; + + +} + +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) { + float stren=cp.tmstrength; + float gamm=params->wavelet.gamma; + cp.TMmeth=2;//default after testing + if(cp.TMmeth ==1) {min0 = 0.0f;max0=32768.f;} + else if (cp.TMmeth ==2) {min0 = 0.0f;} +#ifdef _RT_NESTED_OPENMP +#pragma omp parallel for +#endif + for(int i = 0; i < W_L*H_L; i++) + { WavCoeffs_L0[i]= (WavCoeffs_L0[i] - min0)/max0; + WavCoeffs_L0[i]*=gamm; + } + + float Compression = expf(-stren); //This modification turns numbers symmetric around 0 into exponents. + float DetailBoost = stren; + if(stren < 0.0f) DetailBoost = 0.0f; //Go with effect of exponent only if uncompressing. + + + CompressDR(WavCoeffs_L0, skip, cp, W_L, H_L, Compression,DetailBoost,max0, min0, ave, ah, bh, al, bl, factorx, WavCoeffs_L0); + + +#ifdef _RT_NESTED_OPENMP +#pragma omp parallel for // removed schedule(dynamic,10) +#endif + for(int ii = 0; ii < W_L*H_L; ii++) + WavCoeffs_L0[ii] = WavCoeffs_L0[ii]*max0*(1.f/gamm) + min0; + } + + + + + void ImProcFunctions::EPDToneMapResid(float * WavCoeffs_L0, unsigned int Iterates, int skip, struct cont_params cp, int W_L, int H_L, float max0, float min0) { + + + float stren=cp.tmstrength; + float edgest=params->epd.edgeStopping; + float sca=params->epd.scale; + float gamm=params->wavelet.gamma; + float rew=params->epd.reweightingIterates; + EdgePreservingDecomposition epd = EdgePreservingDecomposition(W_L, H_L); + cp.TMmeth=2;//default after testing + if(cp.TMmeth ==1) {min0 = 0.0f;max0=32768.f;} + else if (cp.TMmeth ==2) {min0 = 0.0f;} + // max0=32768.f; +#ifdef _RT_NESTED_OPENMP +#pragma omp parallel for +#endif + for(int i = 0; i < W_L*H_L; i++) + { WavCoeffs_L0[i]= (WavCoeffs_L0[i] - min0)/max0; + WavCoeffs_L0[i]*=gamm; + } + + float Compression = expf(-stren); //This modification turns numbers symmetric around 0 into exponents. + float DetailBoost = stren; + if(stren < 0.0f) DetailBoost = 0.0f; //Go with effect of exponent only if uncompressing. + + //Auto select number of iterates. Note that p->EdgeStopping = 0 makes a Gaussian blur. + if(Iterates == 0) Iterates = (unsigned int)(edgest*15.0f); + + + epd.CompressDynamicRange(WavCoeffs_L0, sca/float(skip), edgest, Compression, DetailBoost, Iterates, rew, WavCoeffs_L0); + + //Restore past range, also desaturate a bit per Mantiuk's Color correction for tone mapping. +#ifdef _RT_NESTED_OPENMP +#pragma omp parallel for // removed schedule(dynamic,10) +#endif + for(int ii = 0; ii < W_L*H_L; ii++) + WavCoeffs_L0[ii] = WavCoeffs_L0[ii]*max0*(1.f/gamm) + min0; + } + +void ImProcFunctions::WaveletcontAllLfinal(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 WavOpacityCurveWL & waOpacityCurveWL, FlatCurve* ChCurve, bool Chutili){ + + int maxlvl = WaveletCoeffs_L.maxlevel(); + int W_L = WaveletCoeffs_L.level_W(0); + int H_L = WaveletCoeffs_L.level_H(0); + float * WavCoeffs_L0 = WaveletCoeffs_L.coeff0; + + +#ifdef _RT_NESTED_OPENMP +#pragma omp for schedule(dynamic) collapse(2) +#endif + for (int dir=1; dir<4; dir++) { + for (int lvl=0; lvl1) +#endif + for (int i=0; i1) +#endif +{ + float lminL = FLT_MAX; + float lmaxL = 0.f; + +#ifdef _RT_NESTED_OPENMP +#pragma omp for +#endif + for(int i = 0; i < W_L*H_L; i++) { + if(WavCoeffs_L0[i] < lminL) lminL = WavCoeffs_L0[i]; + if(WavCoeffs_L0[i] > lmaxL) lmaxL = WavCoeffs_L0[i]; + + } +#ifdef _RT_NESTED_OPENMP +#pragma omp critical +#endif + { if(lminL < min0) min0 = lminL; + if(lmaxL > max0) max0 = lmaxL; + } + +} + + } + + // printf("MAXmax0=%f MINmin0=%f\n",max0,min0); + +//tone mapping +if(cp.tonemap && cp.contmet==2) { + //iterate = 5 + EPDToneMapResid(WavCoeffs_L0, 5, skip, cp, W_L, H_L, max0, min0); + +} +//end tonemapping + + + max0/=327.68f; + min0/=327.68f; + float ave = avedbl / (double)(W_L*H_L); + float av=ave/327.68f; + float ah=(multH-1.f)/(av-max0);// + float bh=1.f-max0*ah; + float al=(multL-1.f)/(av-min0); + float bl=1.f-min0*al; + float factorx=1.f; + float *koeLi[9]; + float maxkoeLi[9]; + float *koeLibuffer = NULL; + bool lipschitz =false; + lipschitz=true; + + if(lipschitz==true) { + for(int y=0;y<9;y++) maxkoeLi[y]=0.f; + koeLibuffer = new float[9*H_L*W_L]; + for (int i=0; i<9; i++) { + koeLi[i] = &koeLibuffer[i*W_L*H_L]; + } + + for(int j=0;j<9;j++) + for (int i=0; i1) +#endif +{ + if(contrast != 0.f) { // contrast = 0.f means that all will be multiplied by 1.f, so we can skip this step + { +#ifdef _RT_NESTED_OPENMP +#pragma omp for +#endif + for (int i=0; i ave) { + float kh = ah*(WavCoeffs_L0[i]/327.68f)+bh; + prov=WavCoeffs_L0[i]; + WavCoeffs_L0[i]=ave+kh*(WavCoeffs_L0[i]-ave); + } else { + float kl = al*(WavCoeffs_L0[i]/327.68f)+bl; + prov=WavCoeffs_L0[i]; + WavCoeffs_L0[i]=ave-kl*(ave-WavCoeffs_L0[i]); + } + float diflc=WavCoeffs_L0[i]-prov; + diflc*=factorx; + WavCoeffs_L0[i] = prov + diflc; + } + } + } + } + +if(cp.tonemap && cp.contmet==1) { + float maxp=max0*256.f; + float minp=min0*256.f; +#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 ); +} +#ifdef _RT_NESTED_OPENMP +#pragma omp barrier +#endif + + if(cp.conres != 0.f || cp.conresH != 0.f) { // cp.conres = 0.f and cp.comresH = 0.f means that all will be multiplied by 1.f, so we can skip this step +#ifdef _RT_NESTED_OPENMP +#pragma omp for nowait +#endif + for (int i=0; i (100.f-tran)) + tran=100.f-cp.th; + if(LL100 < cp.th){ + float aalp=(1.f-alp)/cp.th;//no changes for LL100 = cp.th + float kk=aalp*LL100+alp; + WavCoeffs_L0[i] *= (1.f+kk*cp.conres/200.f); + } + else if(LL100 < cp.th + tran) { + float ath = -cp.conres/tran; + float bth = cp.conres-ath*cp.th; + WavCoeffs_L0[i] *= (1.f+(LL100*ath+bth)/200.f); + } + //highlight + tran=5.f; + if(cp.thH < (tran)) + tran = cp.thH; + if(LL100 > cp.thH) + WavCoeffs_L0[i] *= (1.f+cp.conresH/200.f); + else if(LL100 > (cp.thH - tran)) { + float athH = cp.conresH/tran; + float bthH = cp.conresH-athH*cp.thH; + WavCoeffs_L0[i] *= (1.f+(LL100*athH+bthH)/200.f); + } + } + } + //enabled Lipschitz..replace simple by complex edge detection + // I found this concept on the web (doctoral thesis on medical Imaging) + // I was inspired by the principle of Canny and Lipschitz (continuity and derivability) + // I adapted the principle but have profoundly changed the algorithm + // One can 1) change all parameters and found good parameters; + //one can also chnage in calckoe + float edd=settings->ed_detec; + float eddlow=settings->ed_low; + float eddlipinfl=settings->ed_lipinfl; + float eddlipampl=settings->ed_lipampl; + + + +if(cp.detectedge && lipschitz==true) { //enabled Lipschitz control...more memory..more time... + float *tmCBuffer = new float[H_L*W_L]; + float *tmC[H_L]; + for (int i=0; i 1 for alp >eddlipinfl and alph < 1 + //Liamp < 1 for alp < eddlipinfl and alph > 0 + if(alph > 1.f) {alph = 1.f/ alph;} + if(beta > 1.f) {beta=1.f/beta;} + //take into account diagonal + //if in same value OK + //if not no edge or reduction + float bet=1.f; + //if(cp.lip3) {//enhance algorithm + if(alph > eddlipinfl && beta < 0.85f*eddlipinfl) {//0.85 arbitrary value ==> eliminate from edge if H V D too different + bet=beta; + } + //} + float AmpLip=1.f; + + if(alph > eddlipinfl) {AmpLip=alipinfl*alph+blipinfl;kampli=SQR(bet)*AmpLip*aamp;}//If beta low reduce kampli + else {AmpLip=(1.f/eddlipinfl)*SQR(SQR(alph*bet));kampli=AmpLip/aamp;}//Strong Reduce if beta low + // comparaison betwwen pixel and neighbours to do ==> I think 3 dir above is better + + //koeLi[lvl*3][i*W_L + j] koeLi[lvl*3][(i-1)*W_L + j] koeLi[lvl*3][(i+1)*W_L + j] + // koeLi[lvl*3][i*W_L + j+1] koeLi[lvl*3][i*W_L + j-1]) koeLi[lvl*3][(i-1)*W_L + j-1] + // koeLi[lvl*3][(i-1)*W_L + j+1] koeLi[lvl*3][(i+1)*W_L + j-1] koeLi[lvl*3][(i+1)*W_L + j+1]) + + // apply to each direction Wavelet level : horizontal / vertiacle / diagonal + + interm*=kampli; + if(interm < cp.eddetthr/eddlow) interm = 0.01f;//eliminate too low values + //we can change this part of algo==> not equal but ponderate + koeLi[lvl*3][i*W_L + j]=koeLi[lvl*3 + 1][i*W_L + j]=koeLi[lvl*3 + 2][i*W_L + j]=interm;//new value + //here KoeLi contains values where gradient is high and coef high, and eliminate low values... + } + } + } + // end +} + +#ifdef _RT_NESTED_OPENMP +#pragma omp for schedule(dynamic) collapse(2) +#endif + for (int dir=1; dir<4; dir++) { + for (int lvl=0; lvl1) +#endif +{ +#ifdef __SSE2__ + float huebuffer[W_L] ALIGNED64; + float chrbuffer[W_L] ALIGNED64; +#endif // __SSE2__ +#ifdef _RT_NESTED_OPENMP +#pragma omp for schedule(dynamic,16) +#endif + for (int i=0; iv(i,j) = valpar; + } + */ + float valparam = float((hhCurve->getVal(Color::huelab_to_huehsv2(hueR))-0.5f) * 1.7f) +hueR;//get H=f(H) 1.7 optimisation ! + float2 sincosval = xsincosf(valparam); + WavCoeffs_a0[i*W_L+j]=chR*sincosval.y; + WavCoeffs_b0[i*W_L+j]=chR*sincosval.x; + } + } +} + } + +} + + void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float **varchrom, wavelet_decomposition &WaveletCoeffs_ab,const WavOpacityCurveW & waOpacityCurveW, + struct cont_params cp, const bool useChannelA){ + + int maxlvl = WaveletCoeffs_ab.maxlevel(); + int W_L = WaveletCoeffs_ab.level_W(0); + int H_L = WaveletCoeffs_ab.level_H(0); + + float * WavCoeffs_ab0 = WaveletCoeffs_ab.coeff0; + +#ifdef _RT_NESTED_OPENMP +#pragma omp parallel num_threads(wavNestedLevels) if(wavNestedLevels>1) +#endif +{ + if(cp.chrores != 0.f) { // cp.chrores == 0.f means all will be multiplied by 1.f, so we can skip the processing of residual + +#ifdef _RT_NESTED_OPENMP +#pragma omp for nowait +#endif + for (int i=0; i 0.f){ + if((modhue < cp.t_ry && modhue > cp.t_ly)) { + scale=(100.f-cp.sky)/100.1f; + } else if((modhue >= cp.t_ry && modhue < cp.b_ry)) { + scale=(100.f-cp.sky)/100.1f; + float ar=(scale-1.f)/(cp.t_ry- cp.b_ry); + float br=scale-cp.t_ry*ar; + scale=ar*modhue+br; + } else if((modhue > cp.b_ly && modhue < cp.t_ly)) { + scale=(100.f-cp.sky)/100.1f; + float al=(scale-1.f)/(-cp.b_ly + cp.t_ly); + float bl=scale-cp.t_ly*al; + scale=al*modhue+bl; + } + } else if(skyprot < 0.f){ + if((modhue > cp.t_ry || modhue < cp.t_ly)){ + scale=(100.f+cp.sky)/100.1f; + } + /* else if((modhue >= cp.t_ry && modhue < cp.b_ry)) { + scale=(100.f+cp.sky)/100.1f; + float ar=(scale-1.f)/(cp.t_ry- cp.b_ry); + float br=scale-cp.t_ry*ar; + scale=ar*modhue+br; + } + else if((modhue > cp.b_ly && modhue < cp.t_ly)) { + scale=(100.f+cp.sky)/100.1f; + float al=(scale-1.f)/(-cp.b_ly + cp.t_ly); + float bl=scale-cp.t_ly*al; + scale=al*modhue+bl; + } + */ + } + WavCoeffs_ab0[i]*=(1.f+cp.chrores*(scale)/100.f); + + } + } + + if(cp.cbena) {//if user select Toning and color balance + +#ifdef _RT_NESTED_OPENMP +#pragma omp for nowait +#endif + for (int i=0; iL[ii*2][jj*2])/327.68f;//I use labco but I can use also WavCoeffs_L0 (more exact but more memory) + + float sca=1.f;//amplifer - reducter...about 1, but perhaps 0.6 or 1.3 + if(useChannelA) {//green red (little magenta) + //transition to avoid artifacts with 6 between 30 to 36 and 63 to 69 + float aa=(cp.grmed-cp.grlow)/6.f; + float bb= cp.grlow-30.f*aa; + float aaa=(cp.grhigh-cp.grmed)/6.f; + float bbb= cp.grmed-63.f*aaa; + + if(LL < 30.f)//shadows + WavCoeffs_ab0[i]+=cp.grlow*(sca)*300.f; + else if(LL >= 30.f && LL < 36.f) {//transition + float tr=aa*LL+bb; + WavCoeffs_ab0[i]+= tr*(sca)*300.f; + } + else if(LL >= 36.f && LL < 63.f)//midtones + WavCoeffs_ab0[i]+=cp.grmed*(sca)*300.f; + else if(LL >= 63.f && LL < 69.f) {//transition + float trh=aaa*LL+bbb; + WavCoeffs_ab0[i]+=trh*(sca)*300.f; + } + else if(LL >= 69.f)//highlights + WavCoeffs_ab0[i]+=cp.grhigh*(sca)*300.f; + } + else {//blue yellow + //transition with 6 between 30 to 36 and 63 to 69 + float aa1=(cp.blmed-cp.bllow)/6.f; + float bb1= cp.bllow-30.f*aa1; + float aaa1=(cp.blhigh-cp.blmed)/6.f; + float bbb1= cp.blmed-63.f*aaa1; + + if(LL < 30.f) + WavCoeffs_ab0[i]+=cp.bllow*(sca)*300.f; + else if(LL >= 30.f && LL < 36.f) { + float tr1=aa1*LL+bb1; + WavCoeffs_ab0[i]+=tr1*(sca)*300.f; + } + else if(LL >= 36.f && LL < 63.f) + WavCoeffs_ab0[i]+=cp.blmed*(sca)*300.f; + else if(LL >= 63.f && LL < 69.f) { + float trh1=aaa1*LL+bbb1; + WavCoeffs_ab0[i]+=trh1*(sca)*300.f; + } + else if(LL >= 69.f) + WavCoeffs_ab0[i]+=cp.blhigh*(sca)*300.f; + } + } + } + +#ifdef _RT_NESTED_OPENMP +#pragma omp for schedule(dynamic) collapse(2) +#endif + for (int dir=1; dir<4; dir++) { + for (int lvl=0; lvl= 30.f && cp.eddetthr < 50.f) { + borderL = 1; + + for (int i=1; i= 50.f && cp.eddetthr < 75.f) { + borderL = 1; + for (int i=1; i= 75.f) { + borderL = 2; + + for (int i=2; i lees good results==> probably because structure data different and also I compare to original value which have + and - + for(int i = borderL; i < H_L-borderL; i++ ) {//[-1 0 1] x==>j + for(int j = borderL; j < W_L-borderL; j++) { + tmC[i][j]=- WavCoeffs_LL[dir][(i)*W_L + j-1] + WavCoeffs_LL[dir][(i)*W_L + j+1]; + } + } + for(int i = borderL; i < H_L-borderL; i++ ) {//[1 0 -1] y==>i + for(int j = borderL; j < W_L-borderL; j++) { + tmC[i][j]= - WavCoeffs_LL[dir][(i-1)*W_L + j] + WavCoeffs_LL[dir][(i+1)*W_L + j]; + } + } + */ + + float thr=40.f;//avoid artifact eg. noise...to test + float thr2=1.5f*edd;//edd can be modified in option ed_detect + thr2+=cp.eddet/30.f;//to test + float diffFactor = (cp.eddet/100.f); + for(int i = 0; i < H_L; i++ ) { + for(int j = 0; j < W_L; j++) { + koeLi[level*3 + dir-1][i*W_L + j]=1.f; + } + } + for(int i = borderL; i < H_L-borderL; i++ ) { + for(int j = borderL; j < W_L-borderL; j++) { + // my own algo : probably a little false, but simpler as Lipschitz ! + // Thr2 = maximum of the function ==> Lipsitch says = probably edge +// float temp = WavCoeffs_LL[dir][i*W_L + j]; +// if(temp>=0.f && temp < thr) temp = thr; +// if(temp < 0.f && temp > -thr) temp = -thr; + float temp = max(fabsf(WavCoeffs_LL[dir][i*W_L + j]), thr ); + koeLi[level*3 + dir-1][i*W_L + j]= min(thr2,fabs(tmC[i][j]/temp));// limit maxi + //it will be more complicated to calculate both Wh and Wv, but we have also Wd==> pseudo Lipschitz + if(koeLi[level*3+ dir-1][i*W_L + j] > maxkoeLi[level*3+ dir-1]) + maxkoeLi[level*3+ dir-1] = koeLi[level*3 + dir-1][i*W_L + j]; + float diff = maxkoeLi[level*3+ dir-1] - koeLi[level*3 + dir-1][i*W_L + j]; + diff *= diffFactor; + koeLi[level*3 + dir-1][i*W_L + j] = maxkoeLi[level*3 + dir-1] - diff; + } + } + +} + + void ImProcFunctions::finalContAllL (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 WavOpacityCurveWL & waOpacityCurveWL, FlatCurve* ChCurve, bool Chutili) + { + bool lipschitz=true; + float edge=1.f; + bool curvdiag=true; + if(curvdiag) {//curve + float insigma=0.666f;//SD + float logmax=log(MaxP[level]);//log Max + float rapX=(mean[level]+sigma[level])/MaxP[level];//rapport between sD / max + float inx=log(insigma); + float iny=log(rapX); + float rap=inx/iny;//koef + float asig=0.166f/sigma[level]; + float bsig=0.5f-asig*mean[level]; + float amean=0.5f/mean[level]; + float absciss; + float kinterm; + float kmul; + for (int i=0; i= (mean[level]+sigma[level])){//for max + float valcour=log(fabs(WavCoeffs_L[dir][i])); + float valc=valcour-logmax; + float vald=valc*rap; + absciss=exp(vald); + + } + else if(fabs(WavCoeffs_L[dir][i])>=mean[level] && fabs(WavCoeffs_L[dir][i]) < (mean[level]+sigma[level])){ + absciss=asig*fabs(WavCoeffs_L[dir][i])+bsig; + } + else if(fabs(WavCoeffs_L[dir][i]) < mean[level]){ + absciss=amean*fabs(WavCoeffs_L[dir][i]); + } + kinterm=1.f; + kmul=1.f; + + float kc = kmul*(waOpacityCurveWL[absciss*500.f]-0.5f); + float reduceeffect=1.5f; + if(kc <=0.f) reduceeffect=1.f; + kinterm = 1.f + reduceeffect*kmul*(waOpacityCurveWL[absciss*500.f]-0.5f); + + if(kinterm<0.f) kinterm=0.01f; + } + + WavCoeffs_L[dir][i] *= kinterm; + } + } + int choicelevel = atoi(params->wavelet.Lmethod.data())-1; + choicelevel = choicelevel == -1 ? 4 : choicelevel; + + int choiceClevel=0; + if(params->wavelet.CLmethod=="one") choiceClevel=0; + else if(params->wavelet.CLmethod=="inf") choiceClevel=1; + else if(params->wavelet.CLmethod=="sup") choiceClevel=2; + else if(params->wavelet.CLmethod=="all") choiceClevel=3; + int choiceDir=0; + if(params->wavelet.Dirmethod=="one") choiceDir=1; + else if(params->wavelet.Dirmethod=="two") choiceDir=2; + else if(params->wavelet.Dirmethod=="thr") choiceDir=3; + else if(params->wavelet.Dirmethod=="all") choiceDir=0; + + int dir1 = (choiceDir == 2) ? 1 : 2; + int dir2 = (choiceDir == 3) ? 1 : 3; + if(choiceClevel<3) { // not all levels visible, paint residual + if(level == 0) { + if(cp.backm!=2) { // nothing to change when residual is used as background + float backGroundColor = (cp.backm==1) ? 12000.f : 0.f; + for (int i=0; i= choicelevel) { + for (int dir=1; dir<4; dir++) { + for (int i=0; i= choicelevel + if(level >= choicelevel) { + for (int i=0; i= choicelevel + if(level <= choicelevel) { + for (int i=0; itop_right; + float t_l=settings->top_left; + float b_r=settings->bot_right; + float b_l=settings->bot_left; + float edd=settings->ed_detec; + float eddlow=settings->ed_low; + float eddstrength=settings->ed_detecStr; + float aedstr=(eddstrength-1.f)/90.f; + float bedstr=1.f-10.f*aedstr; + + bool refi=false; + // if(cp.lev0s > 0.f || cp.lev1s > 0.f || cp.lev2s > 0.f) refi=true; + // if(cp.val > 0 || refi) {//edge + if(cp.val > 0) {//edge + float * koe; + float maxkoe=0.f; + if(lipschitz==false) { + koe = new float [H_L*W_L]; + for (int i=0; i=0.f && temp < thr) temp= thr; + if(temp < 0.f && temp > -thr) temp= -thr; + koe[i*W_L + j]= min(thr2,fabs(tmC[i][j]/temp)); + + if(koe[i*W_L + j] > maxkoe) maxkoe=koe[i*W_L + j]; + float diff=maxkoe-koe[i*W_L + j]; + diff *=(cp.eddet/100.f); + float interm=maxkoe-diff; + if(interm < cp.eddetthr/30.f) interm = 0.01f; + + koe[i*W_L + j]=interm; + + } + } + //printf("maxkoe=%f \n",maxkoe); + + for (int i=0; i not too high value to avoid artifacts + float value = ((float)cp.val)/8.f;//strength + if (scaleskip[1] < 1.f) value *= (atten01234*scaleskip[1]);//for zoom < 100% reduce strength...I choose level 1...but!! + float edge=1.f; + float lim0=20.f;//arbitrary limit for low radius and level between 2 or 3 to 30 maxi + float lev = float (level); + float repart=(float)cp.til; + float brepart; + if(cp.reinforce==1) brepart=3.f; + if(cp.reinforce==3) brepart=0.5f; //arbitrary value to increase / decrease repart, between 1 and 0 + float arepart=-(brepart-1.f)/(lim0/60.f); + if (cp.reinforce !=2) {if(rad < lim0/60.f) repart *= (arepart*rad + brepart);}//linear repartition of repart + + float al0 = 1.f + (repart)/50.f; + float al10 =1.0f;//arbitrary value ==> less = take into account high levels + // float ak =-(al0-al10)/10.f;//10 = maximum levels + float ak =-(al0-al10)/10.f;//10 = maximum levels + float bk =al0; + float koef = ak*level+bk;//modulate for levels : more levels high, more koef low ==> concentrated action on low levels, without or near for high levels + float expkoef= -pow(fabs(rad - lev),koef);//reduce effect for high levels + if (cp.reinforce==3) {if(rad < lim0/60.f && level==0) expkoef *= repart;}//reduce effect for low values of rad and level=0==> quasi only level 1 is effective + if (cp.reinforce==1) {if(rad < lim0/60.f && level==1) expkoef /= repart;}//increase effect for low values of rad and level=1==> quasi only level 0 is effective + float coefsd=0.85f;//arbitray value to reduce effect after sigma in all case + float coefmean=0.85f;//arbitray value to reduce effect after sigma in all case +// edge = 1.f + value * exp (expkoef);//estimate edge "pseudo variance" + //take into account local contrast + float refin= value * exp (expkoef); + if(cp.link==true){//combi + { + if(level==0) refin *= (1.f + cp.lev0s/50.f);// we can change this sensibility! + if(level==1) refin *= (1.f + cp.lev1s/50.f); + if(level==2) refin *= (1.f + cp.lev2s/50.f); + } + } + float edgePrecalc = 1.f + refin; //estimate edge "pseudo variance" + //bool exa=false; + if(cp.EDmet==2) {//curve + // if(exa) {//curve + float insigma=0.666f;//SD + float logmax=log(MaxP[level]);//log Max + float rapX=(mean[level]+sigma[level])/MaxP[level];//rapport between sD / max + float inx=log(insigma); + float iny=log(rapX); + float rap=inx/iny;//koef + float asig=0.166f/sigma[level]; + float bsig=0.5f-asig*mean[level]; + float amean=0.5f/mean[level]; + float absciss; + float kinterm; + float kmul; + for (int i=0; i 10.f) edge=(aedstr*cp.eddet+bedstr)*(edgePrecalc*(1.f+koe[i]))/(1.f+0.9f*maxkoe); + else edge=(edgePrecalc*(1.f+koe[i]))/(1.f+0.9f*maxkoe); + } + if(lipschitz==true) { + if(level < 3) edge = 1.f +(edgePrecalc-1.f)*(koeLi[level*3][i])/(1.f+0.9f*maxkoeLi[level*3+ dir-1]); + else edge = edgePrecalc; + } + } + else edge = edgePrecalc; + + if(cp.edgcurv) { + if(fabs(WavCoeffs_L[dir][i])>= (mean[level]+sigma[level])){//for max + float valcour=log(fabs(WavCoeffs_L[dir][i])); + float valc=valcour-logmax; + float vald=valc*rap; + absciss=exp(vald); + + } + else if(fabs(WavCoeffs_L[dir][i])>=mean[level] && fabs(WavCoeffs_L[dir][i]) < (mean[level]+sigma[level])){ + absciss=asig*fabs(WavCoeffs_L[dir][i])+bsig; + } + else if(fabs(WavCoeffs_L[dir][i]) < mean[level]){ + absciss=amean*fabs(WavCoeffs_L[dir][i]); + } + // Threshold adjuster settings==> approximative for curve + //kmul about average cbrt(3--40 / 10)==>1.5 to 2.5 + //kmul about SD 10--60 / 35 ==> 2 + // kmul about low cbrt((5.f+cp.edg_low)/5.f);==> 1.5 + // kmul about max ==> 9 + // we can change these values + // result is different not best or bad than threshold slider...but similar + float abssd=4.f;//amplification reference + float bbssd=2.f;//mini ampli + float maxamp=2.5f;//maxi ampli at end + float maxampd=10.f;//maxi ampli at end + float a_abssd=(maxamp - abssd)/0.333f; + float b_abssd=maxamp-a_abssd; + float da_abssd=(maxampd - abssd)/0.333f; + float db_abssd=maxampd-da_abssd; + float am=(abssd-bbssd)/0.666f; + float kmuld=0.f; + if(absciss>0.666f && absciss < 1.f) {kmul=a_abssd*absciss + b_abssd;kmuld=da_abssd*absciss + db_abssd;}//about max ==> kinterm + else kmul = kmuld = absciss*am+bbssd; + kinterm=1.f; + float kc= kmul*(wavCLVCcurve[absciss*500.f]-0.5f); + float kcd= kmuld*(wavCLVCcurve[absciss*500.f]-0.5f); + float reduceeffect=0.6f; + if(kc >=0.f) + kinterm = 1.f + reduceeffect*kmul*(wavCLVCcurve[absciss*500.f]-0.5f);//about 1 to 3 general and big amplification for max (under 0) + else + kinterm = 1.f - (SQR(kcd))/10.f; + + if(kinterm<0.f) kinterm=0.01f; + edge *= kinterm; + if(edge < 1.f) + edge=1.f; + } + WavCoeffs_L[dir][i] *= edge; + } + } + else if(cp.EDmet==1) {//threshold adjuster + float MaxPCompare = MaxP[level]*SQR(cp.edg_max/100.f);//100 instead of b_r...case if b_r < 100 + float MaxNCompare = MaxN[level]*SQR(cp.edg_max/100.f);//always rduce a little edge for near max values + float edgeSdCompare = (mean[level]+1.5f*sigma[level])*SQR(cp.edg_sd/t_r);// 1.5 standard deviation #80% range between mean 50% and 80% + float edgeMeanCompare = mean[level]*SQR(cp.edg_mean/t_l); + float edgeLowCompare = (5.f+SQR(cp.edg_low)); + float edgeMeanFactor = cbrt(cp.edg_mean/t_l); + float interm; + if(cp.edg_low < 10.f) interm= cbrt((5.f+cp.edg_low)/5.f); + else interm=1.437f;//cbrt(3); + float edgeLowFactor = interm; + float edgeSdFactor = cp.edg_sd/t_r; + float edgeMaxFactor = SQR(cp.edg_max/b_r); + float edgMaxFsup=(cp.edg_max/b_r);//reduce increase of effect for high values contrast..if slider > b_r + + for (int i=0; i 10.f) edge=(aedstr*cp.eddet+bedstr)*(edgePrecalc*(1.f+koe[i]))/(1.f+0.9f*maxkoe); + else edge=(edgePrecalc*(1.f+koe[i]))/(1.f+0.9f*maxkoe); + } + if(lipschitz==true) { + if(level < 3) edge = 1.f +(edgePrecalc-1.f)*(koeLi[level*3][i])/(1.f+0.9f*maxkoeLi[level*3+ dir-1]); + else edge = edgePrecalc; + } + } + else edge = edgePrecalc; + + //algorithm that take into account local contrast + // I use a thresholdadjuster with + // Bottom left ==> minimal low value for local contrast (not 0, but 5...we can change) + // 0 10*10 35*35 100*100 substantially correspond to the true distribution of low value, mean, standard-deviation and max (ed 5, 50, 400, 4000 + // Top left ==> mean reference value (for each level), we can change cbrt(cp.edg_mean/10.f) + // Top Right==> standard deviation (for each level) we can change (cp.edg_sd/35.f) + // bottom right ==> Max for positif and negatif contrast we can change cp.edg_max/100.f + // If we move sliders to the left, local contrast is reduced + // if we move sliders to the right local contrast is increased + // MaxP, MaxN, mean, sigma are calculated if necessary (val > 0) by evaluate2(), eval2(), aver() , sigma() + if(b_r < 100.f && cp.edg_max/b_r > 1.f) {//in case of b_r < 100 and slider move to right + if (WavCoeffs_L[dir][i] > MaxPCompare*cp.edg_max/b_r) { + edge *= edgMaxFsup; + if(edge < 1.f) + edge=1.f; + } + else if (WavCoeffs_L[dir][i] < MaxNCompare*cp.edg_max/b_r) { + edge *= edgMaxFsup; + if(edge < 1.f) + edge=1.f; + } + } + + if (WavCoeffs_L[dir][i] > MaxPCompare) { + edge *= edgeMaxFactor; + if(edge < 1.f) + edge=1.f; + }//reduce edge if > new max + else if (WavCoeffs_L[dir][i] < MaxNCompare) { + edge *= edgeMaxFactor; + if(edge < 1.f) + edge=1.f; + } + + if (fabs(WavCoeffs_L[dir][i]) >= edgeMeanCompare && fabs(WavCoeffs_L[dir][i]) < edgeSdCompare) { + //if (fabs(WavCoeffs_L[dir][i]) > edgeSdCompare) { + edge *= edgeSdFactor; + if(edge < 1.f) + edge=1.f; + }//mofify effect if sd change + if (fabs(WavCoeffs_L[dir][i]) < edgeMeanCompare) { + edge *= edgeMeanFactor; + if(edge < 1.f) + edge=1.f; + } // modify effect if mean change + if (fabs(WavCoeffs_L[dir][i]) < edgeLowCompare) { + edge *= edgeLowFactor; + if(edge < 1.f) + edge=1.f; + } + WavCoeffs_L[dir][i] *= edge; + } + } + if(lipschitz==false) { + delete [] koe; + } + } + + + if(cp.link==false) { //used both with denoise 1 2 3 + float refine=0.f; + for (int i=0; iwavelet.skinprotect; + const float skinprotneg = -skinprot; + const float factorHard = (1.f - skinprotneg/100.f); + + //to adjust increase contrast with local contrast + + //for each pixel and each level + float beta; + float mea[9]; + mea[0]=mean[level]/6.f; + mea[1]=mean[level]/2.f; + mea[2]=mean[level];// 50% data + mea[3]=mean[level] + sigma[level]/2.f; + mea[4]=mean[level] + sigma[level];//66% + mea[5]=mean[level] + 1.2f*sigma[level]; + mea[6]=mean[level] + 1.5f*sigma[level];// + mea[7]=mean[level] + 2.f*sigma[level];//95% + mea[8]=mean[level] + 2.5f*sigma[level];//99% + + bool skinControl = (skinprot != 0.f); + bool useChromAndHue = (skinprot != 0.f || cp.HSmet); + float modchro, kLlev; + + for (int i=0; iL[ii*2][jj*2]; + LL100=LL100init=LL/327.68f; + LL100res=WavCoeffs_L0[i]/327.68f; + float delta=fabs(LL100init-LL100res)/(maxlvl/2); + for(int ml=0;ml 0.f){ + Color::SkinSatCbdl2 (LL100, modhue, modchro, skinprot, scale, true, cp.b_l, cp.t_l, cp.t_r, cp.b_r, 0); //0 for skin and extand + } else if(skinprot < 0.f){ + Color::SkinSatCbdl2 (LL100, modhue, modchro, skinprotneg, scale, false, cp.b_l, cp.t_l, cp.t_r, cp.b_r, 0); + if (scale == 1.f) + scale=factorHard; + else + scale=1.f; + } + + } + if(Chutili){ + int i_i=i/W_L; + int j_j=i-i_i*W_L; + double lr; + float modhue2 = varhue[i_i][j_j]; + float valparam = float((ChCurve->getVal(lr=Color::huelab_to_huehsv2(modhue2))-0.5f));//get valparam=f(H) + + if(valparam > 0.f) scale2=1.f + 3.f* valparam;//arbitrary value + else scale2 = 1.f + 1.9f*valparam;//near 0 but not zero if curve # 0 + + //curve Contrast / hue + + } + // + //linear transition HL + float diagacc=1.f; + /* + if(cp.diag) { + if(dir <=2) diagacc=0.75f; + if(dir ==3) diagacc=1.5f; + } + */ + float alpha = (1024.f + 15.f *(float) cpMul*scale*scale2*beta*diagacc)/1024.f ; + if(cp.HSmet){ + float aaal=(1.f-alpha)/((cp.b_lhl-cp.t_lhl)*kH[level]); + float bbal=1.f-aaal*cp.b_lhl*kH[level]; + float aaar=(alpha-1.f)/(cp.t_rhl-cp.b_rhl)*kH[level]; + float bbbr=1.f-cp.b_rhl*aaar*kH[level]; + //linear transition Shadows + float aaalS=(1.f-alpha)/(cp.b_lsl-cp.t_lsl); + float bbalS=1.f-aaalS*cp.b_lsl; + float aaarS=(alpha-1.f)/(cp.t_rsl-cp.b_rsl); + float bbbrS=1.f-cp.b_rsl*aaarS; + if(level <=cp.numlevH) {//in function of levels + if((LL100 > cp.t_lhl*kH[level] && LL100 < cp.t_rhl*kH[level])) {kLlev=alpha;} + else if((LL100 > cp.b_lhl*kH[level] && LL100 <= cp.t_lhl*kH[level])) kLlev=aaal*LL100+bbal; + else if((LL100 > cp.t_rhl*kH[level] && LL100 <= cp.b_rhl*kH[level])) kLlev=aaar*LL100+bbbr; + else kLlev=1.f; + } + if(level >=(9-cp.numlevS)) { + if((LL100 > cp.t_lsl && LL100 < cp.t_rsl)) kLlev=alpha; + else if((LL100 > cp.b_lsl && LL100 <= cp.t_lsl)) kLlev=aaalS*LL100+bbalS; + else if((LL100 > cp.t_rsl && LL100 <= cp.b_rsl)) kLlev=aaarS*LL100+bbbrS; + else kLlev=1.f; + } + + } + else kLlev=alpha; + + WavCoeffs_L[dir][i]*=(kLlev); + } + } +if(waOpacityCurveW) cp.opaW=true; + +if(cp.bam) { +if(cp.opaW && cp.BAmet==2){ + int iteration = cp.ite; + int itplus=7+iteration; + int itmoins= 7-iteration; + int med = maxlvl/2; + int it; + if(level < med) {it=itmoins; } + else if(level == med) it=7; + else if(level > med) it=itplus; + + for(int j=0; j < it; j++) { + //float bal = cp.balan;//-100 +100 + float kba=1.f; + float k1; + float k2; + // if(dir <3) kba= 1.f + bal/600.f; + // if(dir==3) kba = 1.f - bal/300.f; + for (int i=0; iL[ii*2][jj*2]/327.68f; + k1=600.f; + k2=300.f; + k1=0.3f*(waOpacityCurveW[6.f*LL100]-0.5f);//k1 between 0 and 0.5 0.5==> 1/6=0.16 + k2=k1*2.f; + if(dir <3) kba= 1.f + k1; + if(dir==3) kba = 1.f - k2; + + WavCoeffs_L[dir][i] *=(kba); + } + } +} +if(cp.BAmet==1){ + int iteration = cp.ite; + int itplus=7+iteration; + int itmoins= 7-iteration; + int med = maxlvl/2; + int it; + if(level < med) {it=itmoins; } + else if(level == med) it=7; + else if(level > med) it=itplus; + + for(int j=0; j < it; j++) { + float bal = cp.balan;//-100 +100 + float kba=1.f; + float k1; + float k2; + // if(dir <3) kba= 1.f + bal/600.f; + // if(dir==3) kba = 1.f - bal/300.f; + for (int i=0; iL[ii*2][jj*2]/327.68f; + float aa=4970.f; + float bb=-397000.f; + float b0=100000.f; + float a0=-4970.f; + if(LL100> 80.f) {k1=aa*LL100 + bb;k2=0.5f*k1;} + if(LL100< 20.f) {k1=a0*LL100 + b0;k2=0.5f*k1;} + //k1=600.f; + //k2=300.f; + //k1=0.3f*(waOpacityCurveW[6.f*LL100]-0.5f);//k1 between 0 and 0.5 0.5==> 1/6=0.16 + //k2=k1*2.f; + if(dir <3) kba= 1.f + bal/k1; + if(dir==3) kba = 1.f - bal/k2; + + WavCoeffs_L[dir][i] *=(kba); + } + } +} + +} + + // to see each level of wavelet ...level from 0 to 8 + int choicelevel = atoi(params->wavelet.Lmethod.data())-1; + choicelevel = choicelevel == -1 ? 4 : choicelevel; + } + + void ImProcFunctions::ContAllAB (LabImage * labco, int maxlvl, float ** varhue, float **varchrom, float ** WavCoeffs_ab, float * WavCoeffs_ab0, int level, int dir, const WavOpacityCurveW & waOpacityCurveW, struct cont_params cp, + int W_ab, int H_ab, const bool useChannelA) + { + float cpMul = cp.mul[level]; + if(cpMul != 0.f && cp.CHmet==2 && cp.chro != 0.f) { // cpMul == 0.f or cp.chro = 0.f means all will be multiplied by 1.f, so we can skip this + const float skinprot = params->wavelet.skinprotect; + const float skinprotneg = -skinprot; + const float factorHard = (1.f - skinprotneg/100.f); + const float cpChrom = cp.chro; + + //to adjust increase contrast with local contrast + bool useSkinControl = (skinprot != 0.f); + float alphaC =(1024.f + 15.f *cpMul*cpChrom/50.f)/1024.f ; + for (int i=0; iL[ii*2][jj*2]/327.68f; + float modhue = varhue[ii][jj]; + float modchro = varchrom[ii*2][jj*2]; + // hue chroma skin with initial lab datas + float scale=1.f; + if(skinprot > 0.f){ + Color::SkinSatCbdl2 (LL100, modhue, modchro, skinprot, scale, true, cp.b_l, cp.t_l, cp.t_r, cp.b_r, 0); //0 for skin and extand + } else if(skinprot < 0.f){ + Color::SkinSatCbdl2 (LL100, modhue, modchro, skinprotneg, scale, false, cp.b_l, cp.t_l, cp.t_r, cp.b_r, 0); + scale = (scale == 1.f) ? factorHard : 1.f; + } + alphaC =(1024.f + 15.f *cpMul*cpChrom*scale/50.f)/1024.f ; + } + WavCoeffs_ab[dir][i] *= alphaC; + } + } + //Curve chro + + float cpMulC = cp.mulC[level]; + // if( (cp.curv || cp.CHSLmet==1) && cp.CHmet!=2 && level < 9 && cpMulC != 0.f) { // cpMulC == 0.f means all will be multiplied by 1.f, so we can skip + if( cp.CHmet!=2 && level < 9 && cpMulC != 0.f) { // cpMulC == 0.f means all will be multiplied by 1.f, so we can skip + float modchro, modhue, kClev; + const float skinprot = params->wavelet.skinprotect; + const float skinprotneg = -skinprot; + const float factorHard = (1.f - skinprotneg/100.f); + bool useSkinControl = (skinprot != 0.f); + + for (int i=0; iL[ii*2][jj*2]; + float LL100=LL/327.68f; + float scale=1.f; + modchro = varchrom[ii*2][jj*2]; + + if(useSkinControl) { + // hue chroma skin with initial lab datas + modhue = varhue[ii][jj]; + scale=1.f; + if(skinprot > 0.f){ + Color::SkinSatCbdl2 (LL100, modhue, modchro, skinprot, scale, true, cp.b_l, cp.t_l, cp.t_r, cp.b_r, 1); //1 for curve + } + else if(skinprot < 0.f){ + Color::SkinSatCbdl2 (LL100, modhue, modchro, skinprotneg, scale, false, cp.b_l, cp.t_l, cp.t_r, cp.b_r, 1); + scale = (scale == 1.f) ? factorHard : 1.f; + } + } + float beta = (1024.f + 20.f * cpMulC * scale)/1024.f ; + if(beta < 0.02f) + beta=0.02f; + kClev = beta; + if(cp.CHmet==1){ + if(level < cp.chrom) { + //linear for saturated + if((modchro > cp.t_lsat && modchro < cp.t_rsat)) + kClev=beta; + else if((modchro > cp.b_lsat && modchro <= cp.t_lsat)) { + float aaal=(1.f-beta)/(cp.b_lsat-cp.t_lsat); + float bbal=1.f-aaal*cp.b_lsat; + kClev=aaal*modchro+bbal; + } else if((modchro > cp.t_rsat && modchro <= cp.b_rsat)) { + float aaar=(beta-1.f)/(cp.t_rsat-cp.b_rsat); + float bbbr=1.f-cp.b_rsat*aaar; + kClev=aaar*modchro+bbbr; + } else + kClev=1.f; + } else { + //linear for pastel + if((modchro > cp.t_lpast && modchro < cp.t_rpast)) + kClev=beta; + else if((modchro > cp.b_lpast && modchro <= cp.t_lpast)) { + float aaalS=(1.f-beta)/(cp.b_lpast-cp.t_lpast); + float bbalS=1.f-aaalS*cp.b_lpast; + kClev=aaalS*modchro+bbalS; + } else if((modchro > cp.t_rpast && modchro <= cp.b_rpast)) { + float aaarS=(beta-1.f)/(cp.t_rpast-cp.b_rpast); + float bbbrS=1.f-cp.b_rpast*aaarS; + kClev=aaarS*modchro+bbbrS; + } else + kClev=1.f; + } + } + else if(cp.CHmet==0) + kClev=beta; + WavCoeffs_ab[dir][i] *= kClev; + } + } + + bool useOpacity; + float mulOpacity; + if(useChannelA) { + useOpacity = cp.opaRG; + mulOpacity = cp.mulopaRG[level]; + } + else { + useOpacity = cp.opaBY; + mulOpacity = cp.mulopaBY[level]; + } + + if(useOpacity && level < 9 && mulOpacity != 0.f) { //toning + + float beta = (1024.f + 20.f * mulOpacity)/1024.f ; + //float beta = (1000.f * mulOpacity); + for (int i=0; i med) it=itplus; + + for(int j=0; j < it; j++) { + //float bal = cp.balan;//-100 +100 + float kba=1.f; + float k1; + float k2; + // if(dir <3) kba= 1.f + bal/600.f; + // if(dir==3) kba = 1.f - bal/300.f; + for (int i=0; iL[ii*2][jj*2]/327.68f; + k1=600.f; + k2=300.f; + k1=0.3f*(waOpacityCurveW[6.f*LL100]-0.5f);//k1 between 0 and 0.5 0.5==> 1/6=0.16 + k2=k1*2.f; + if(dir <3) kba= 1.f + k1; + if(dir==3) kba = 1.f - k2; + + WavCoeffs_ab[dir][i] *=(kba); + } + } +} +if(cp.BAmet==1){ + int iteration = cp.ite; + int itplus=7+iteration; + int itmoins= 7-iteration; + int med = maxlvl/2; + int it; + if(level < med) {it=itmoins; } + else if(level == med) it=7; + else if(level > med) it=itplus; + + for(int j=0; j < it; j++) { + float bal = cp.balan;//-100 +100 + float kba=1.f; + float k1; + float k2; + // if(dir <3) kba= 1.f + bal/600.f; + // if(dir==3) kba = 1.f - bal/300.f; + for (int i=0; iL[ii*2][jj*2]/327.68f; + float aa=4970.f; + float bb=-397000.f; + float b0=100000.f; + float a0=-4970.f; + if(LL100> 80.f) {k1=aa*LL100 + bb;k2=0.5f*k1;} + if(LL100< 20.f) {k1=a0*LL100 + b0;k2=0.5f*k1;} + //k1=600.f; + //k2=300.f; + //k1=0.3f*(waOpacityCurveW[6.f*LL100]-0.5f);//k1 between 0 and 0.5 0.5==> 1/6=0.16 + //k2=k1*2.f; + if(dir <3) kba= 1.f + bal/k1; + if(dir==3) kba = 1.f - bal/k2; + + WavCoeffs_ab[dir][i] *=(kba); + } + } +} + +} + + // to see each level of wavelet ...level from 0 to 8 + int choicelevel = atoi(params->wavelet.Lmethod.data())-1; + choicelevel = choicelevel == -1 ? 4 : choicelevel; + int choiceClevel=0; + if(params->wavelet.CLmethod=="one") choiceClevel=0; + else if(params->wavelet.CLmethod=="inf") choiceClevel=1; + else if(params->wavelet.CLmethod=="sup") choiceClevel=2; + else if(params->wavelet.CLmethod=="all") choiceClevel=3; + int choiceDir=0; + if(params->wavelet.Dirmethod=="one") choiceDir=1; + else if(params->wavelet.Dirmethod=="two") choiceDir=2; + else if(params->wavelet.Dirmethod=="thr") choiceDir=3; + else if(params->wavelet.Dirmethod=="all") choiceDir=0; + + int dir1 = (choiceDir == 2) ? 1 : 2; + int dir2 = (choiceDir == 3) ? 1 : 3; + if(choiceClevel<3) { // not all levels visible, paint residual + if(level == 0) { + if(cp.backm!=2) { // nothing to change when residual is used as background + float backGroundChroma = (cp.backm==1) ? 0.f : 0.f;//we can change first to colorized... + for (int i=0; i= choicelevel) { + for (int dir=1; dir<4; dir++) { + for (int i=0; i= choicelevel + if(level >= choicelevel) { + for (int i=0; i= choicelevel + if(level <= choicelevel) { + for (int i=0; i +#include +#include +#include "jpeg.h" + +/* + * jdatasrc.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * Modified 2009-2010 by Guido Vollbeding. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains decompression data source routines for the case of + * reading JPEG data from a file (or any stdio stream). While these routines + * are sufficient for most applications, some will want to use a different + * source manager. + * IMPORTANT: we assume that fread() will correctly transcribe an array of + * JOCTETs from 8-bit-wide elements on external storage. If char is wider + * than 8 bits on your machine, you may need to do some tweaking. + */ + +/* this is not a core library module, so it doesn't define JPEG_INTERNALS */ +//#include "jinclude.h" + +#define JFREAD(file,buf,sizeofbuf) \ + ((size_t) fread((void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) +#define JFWRITE(file,buf,sizeofbuf) \ + ((size_t) fwrite((const void *) (buf), (size_t) 1, (size_t) (sizeofbuf), (file))) + + + + +/* Expanded data source object for stdio input */ + +typedef struct { + struct jpeg_source_mgr pub; /* public fields */ + jmp_buf error_jmp_buf; /* error handler for this instance */ + + FILE * infile; /* source stream */ + JOCTET * buffer; /* start of buffer */ + boolean start_of_file; /* have we gotten any data yet? */ +} my_source_mgr; + +typedef my_source_mgr * my_src_ptr; + +#define INPUT_BUF_SIZE 4096 /* choose an efficiently fread'able size */ + + +/* + * Initialize source --- called by jpeg_read_header + * before any data is actually read. + */ + +METHODDEF(void) +my_init_source (j_decompress_ptr cinfo) +{ + my_src_ptr src = (my_src_ptr) cinfo->src; + + /* We reset the empty-input-file flag for each image, + * but we don't clear the input buffer. + * This is correct behavior for reading a series of images from one source. + */ + src->start_of_file = TRUE; +} + + +/* + * Fill the input buffer --- called whenever buffer is emptied. + * + * In typical applications, this should read fresh data into the buffer + * (ignoring the current state of next_input_byte & bytes_in_buffer), + * reset the pointer & count to the start of the buffer, and return TRUE + * indicating that the buffer has been reloaded. It is not necessary to + * fill the buffer entirely, only to obtain at least one more byte. + * + * There is no such thing as an EOF return. If the end of the file has been + * reached, the routine has a choice of ERREXIT() or inserting fake data into + * the buffer. In most cases, generating a warning message and inserting a + * fake EOI marker is the best course of action --- this will allow the + * decompressor to output however much of the image is there. However, + * the resulting error message is misleading if the real problem is an empty + * input file, so we handle that case specially. + * + * In applications that need to be able to suspend compression due to input + * not being available yet, a FALSE return indicates that no more data can be + * obtained right now, but more may be forthcoming later. In this situation, + * the decompressor will return to its caller (with an indication of the + * number of scanlines it has read, if any). The application should resume + * decompression after it has loaded more data into the input buffer. Note + * that there are substantial restrictions on the use of suspension --- see + * the documentation. + * + * When suspending, the decompressor will back up to a convenient restart point + * (typically the start of the current MCU). next_input_byte & bytes_in_buffer + * indicate where the restart point will be if the current call returns FALSE. + * Data beyond this point must be rescanned after resumption, so move it to + * the front of the buffer rather than discarding it. + */ + +METHODDEF(boolean) +my_fill_input_buffer (j_decompress_ptr cinfo) +{ + my_src_ptr src = (my_src_ptr) cinfo->src; + size_t nbytes; + + nbytes = JFREAD(src->infile, src->buffer, INPUT_BUF_SIZE); + + if (nbytes == 0) { + if (src->start_of_file) /* Treat empty input file as fatal error */ + ERREXIT(cinfo, JERR_INPUT_EMPTY); + WARNMS(cinfo, JWRN_JPEG_EOF); + /* Insert a fake EOI marker */ + src->buffer[0] = (JOCTET) 0xFF; + src->buffer[1] = (JOCTET) JPEG_EOI; + nbytes = 2; + } + + if (src->start_of_file) + src->buffer[0] = (JOCTET) 0xFF; + + src->pub.next_input_byte = src->buffer; + src->pub.bytes_in_buffer = nbytes; + src->start_of_file = FALSE; + + return TRUE; +} + + +/* + * Skip data --- used to skip over a potentially large amount of + * uninteresting data (such as an APPn marker). + * + * Writers of suspendable-input applications must note that skip_input_data + * is not granted the right to give a suspension return. If the skip extends + * beyond the data currently in the buffer, the buffer can be marked empty so + * that the next read will cause a fill_input_buffer call that can suspend. + * Arranging for additional bytes to be discarded before reloading the input + * buffer is the application writer's problem. + */ + +METHODDEF(void) +my_skip_input_data (j_decompress_ptr cinfo, long num_bytes) +{ + my_src_ptr src = (my_src_ptr) cinfo->src; + + /* Just a dumb implementation for now. Could use fseek() except + * it doesn't work on pipes. Not clear that being smart is worth + * any trouble anyway --- large skips are infrequent. + */ + if (num_bytes > 0) { + while (num_bytes > (long) src->pub.bytes_in_buffer) { + num_bytes -= (long) src->pub.bytes_in_buffer; + (void) my_fill_input_buffer(cinfo); + /* note we assume that fill_input_buffer will never return FALSE, + * so suspension need not be handled. + */ + } + src->pub.next_input_byte += (size_t) num_bytes; + src->pub.bytes_in_buffer -= (size_t) num_bytes; + } +} + + +/* + * An additional method that can be provided by data source modules is the + * resync_to_restart method for error recovery in the presence of RST markers. + * For the moment, this source module just uses the default resync method + * provided by the JPEG library. That method assumes that no backtracking + * is possible. + */ + + +/* + * Terminate source --- called by jpeg_finish_decompress + * after all data has been read. Often a no-op. + * + * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding + * application must deal with any cleanup that should happen even + * for error exit. + */ + +METHODDEF(void) +my_term_source (j_decompress_ptr cinfo) +{ + /* no work necessary here */ +} + + +/* + * Prepare for input from a stdio stream. + * The caller must have already opened the stream, and is responsible + * for closing it after finishing decompression. + */ + +GLOBAL(void) +my_jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile) +{ + my_src_ptr src; + + /* The source object and input buffer are made permanent so that a series + * of JPEG images can be read from the same file by calling jpeg_stdio_src + * only before the first one. (If we discarded the buffer at the end of + * one image, we'd likely lose the start of the next one.) + * This makes it unsafe to use this manager and a different source + * manager serially with the same JPEG object. Caveat programmer. + */ + if (cinfo->src == NULL) { /* first time for this JPEG object? */ + cinfo->src = (struct jpeg_source_mgr *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + sizeof(my_source_mgr)); + src = (my_src_ptr) cinfo->src; + src->buffer = (JOCTET *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + INPUT_BUF_SIZE * sizeof(JOCTET)); + } + + src = (my_src_ptr) cinfo->src; + src->pub.init_source = my_init_source; + src->pub.fill_input_buffer = my_fill_input_buffer; + src->pub.skip_input_data = my_skip_input_data; + src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */ + src->pub.term_source = my_term_source; + src->infile = infile; + src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ + src->pub.next_input_byte = NULL; /* until buffer loaded */ +} + +METHODDEF(void) +my_error_exit (j_common_ptr cinfo) +{ + /* Always display the message */ + (*cinfo->err->output_message) (cinfo); + + /* Let the memory manager delete any temp files before we die */ + //jpeg_destroy(cinfo); + + j_decompress_ptr dinfo = (j_decompress_ptr)cinfo; +// longjmp (((rt_jpeg_error_mgr*)(dinfo->src))->error_jmp_buf, 1); + longjmp ((reinterpret_cast(dinfo->src)) ->error_jmp_buf, 1); +} + + +//const char * const jpeg_std_message_table[] = { +//#include "jerror.h" +// NULL +//}; +extern const char * const jpeg_std_message_table[]; + + +/* + * Actual output of an error or trace message. + * Applications may override this method to send JPEG messages somewhere + * other than stderr. + * + * On Windows, printing to stderr is generally completely useless, + * so we provide optional code to produce an error-dialog popup. + * Most Windows applications will still prefer to override this routine, + * but if they don't, it'll do something at least marginally useful. + * + * NOTE: to use the library in an environment that doesn't support the + * C stdio library, you may have to delete the call to fprintf() entirely, + * not just not use this routine. + */ + +METHODDEF(void) +output_message (j_common_ptr cinfo) +{ + char buffer[JMSG_LENGTH_MAX]; + + /* Create the message */ + (*cinfo->err->format_message) (cinfo, buffer); + +#ifdef USE_WINDOWS_MESSAGEBOX + /* Display it in a message dialog box */ + MessageBox(GetActiveWindow(), buffer, "JPEG Library Error", + MB_OK | MB_ICONERROR); +#else + /* Send it to stderr, adding a newline */ + fprintf(stderr, "%s\n", buffer); +#endif +} + + +/* + * Decide whether to emit a trace or warning message. + * msg_level is one of: + * -1: recoverable corrupt-data warning, may want to abort. + * 0: important advisory messages (always display to user). + * 1: first level of tracing detail. + * 2,3,...: successively more detailed tracing messages. + * An application might override this method if it wanted to abort on warnings + * or change the policy about which messages to display. + */ + +METHODDEF(void) +emit_message (j_common_ptr cinfo, int msg_level) +{ + struct jpeg_error_mgr * err = cinfo->err; + + if (msg_level < 0) { + /* It's a warning message. Since corrupt files may generate many warnings, + * the policy implemented here is to show only the first warning, + * unless trace_level >= 3. + */ + if (err->num_warnings == 0 || err->trace_level >= 3) + (*err->output_message) (cinfo); + /* Always count warnings in num_warnings. */ + err->num_warnings++; + } else { + /* It's a trace message. Show it if trace_level >= msg_level. */ + if (err->trace_level >= msg_level) + (*err->output_message) (cinfo); + } +} + + +/* + * Format a message string for the most recent JPEG error or message. + * The message is stored into buffer, which should be at least JMSG_LENGTH_MAX + * characters. Note that no '\n' character is added to the string. + * Few applications should need to override this method. + */ + +METHODDEF(void) +format_message (j_common_ptr cinfo, char * buffer) +{ + struct jpeg_error_mgr * err = cinfo->err; + int msg_code = err->msg_code; + const char * msgtext = NULL; + const char * msgptr; + char ch; + boolean isstring; + + /* Look up message string in proper table */ + if (msg_code > 0 && msg_code <= err->last_jpeg_message) { + msgtext = err->jpeg_message_table[msg_code]; + } else if (err->addon_message_table != NULL && + msg_code >= err->first_addon_message && + msg_code <= err->last_addon_message) { + msgtext = err->addon_message_table[msg_code - err->first_addon_message]; + } + + /* Defend against bogus message number */ + if (msgtext == NULL) { + err->msg_parm.i[0] = msg_code; + msgtext = err->jpeg_message_table[0]; + } + + /* Check for string parameter, as indicated by %s in the message text */ + isstring = FALSE; + msgptr = msgtext; + while ((ch = *msgptr++) != '\0') { + if (ch == '%') { + if (*msgptr == 's') isstring = TRUE; + break; + } + } + + /* Format the message into the passed buffer */ + if (isstring) + sprintf(buffer, msgtext, err->msg_parm.s); + else + sprintf(buffer, msgtext, + err->msg_parm.i[0], err->msg_parm.i[1], + err->msg_parm.i[2], err->msg_parm.i[3], + err->msg_parm.i[4], err->msg_parm.i[5], + err->msg_parm.i[6], err->msg_parm.i[7]); +} + + +/* + * Reset error state variables at start of a new image. + * This is called during compression startup to reset trace/error + * processing to default state, without losing any application-specific + * method pointers. An application might possibly want to override + * this method if it has additional error processing state. + */ + +METHODDEF(void) +reset_error_mgr (j_common_ptr cinfo) +{ + cinfo->err->num_warnings = 0; + /* trace_level is not reset since it is an application-supplied parameter */ + cinfo->err->msg_code = 0; /* may be useful as a flag for "no error" */ +} + + +GLOBAL(struct jpeg_error_mgr *) +my_jpeg_std_error (struct jpeg_error_mgr * err) +{ + + err->error_exit = my_error_exit; + err->emit_message = emit_message; + err->output_message = output_message; + err->format_message = format_message; + err->reset_error_mgr = reset_error_mgr; + + err->trace_level = 0; /* default = no tracing */ + err->num_warnings = 0; /* no warnings emitted yet */ + err->msg_code = 0; /* may be useful as a flag for "no error" */ + + /* Initialize message table pointers */ + err->jpeg_message_table = jpeg_std_message_table; + err->last_jpeg_message = (int) JMSG_LASTMSGCODE - 1; + + err->addon_message_table = NULL; + err->first_addon_message = 0; /* for safety */ + err->last_addon_message = 0; + + return err; +} diff --git a/rtengine/jpeg.h b/rtengine/jpeg.h new file mode 100644 index 000000000..7e3dded10 --- /dev/null +++ b/rtengine/jpeg.h @@ -0,0 +1,35 @@ +#ifndef _RT_JPEG_H +#define _RT_JPEG_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +extern GLOBAL(struct jpeg_error_mgr *) +my_jpeg_std_error (struct jpeg_error_mgr * err); + +extern GLOBAL(void) +my_jpeg_stdio_src (j_decompress_ptr cinfo, FILE * infile); + +GLOBAL(void) +jpeg_memory_src (j_decompress_ptr cinfo, const JOCTET * buffer, size_t bufsize); + +/** + * @brief jpeg from file and memory use this as base to managers + */ +typedef struct +{ + struct jpeg_source_mgr pub; /* public fields */ + jmp_buf error_jmp_buf; /* error handler for this instance */ +} rt_jpeg_error_mgr; + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/rtengine/jpeg_memsrc.cc b/rtengine/jpeg_memsrc.cc new file mode 100644 index 000000000..7d5970fb3 --- /dev/null +++ b/rtengine/jpeg_memsrc.cc @@ -0,0 +1,169 @@ +/* + * memsrc.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains decompression data source routines for the case of + * reading JPEG data from a memory buffer that is preloaded with the entire + * JPEG file. This would not seem especially useful at first sight, but + * a number of people have asked for it. + * This is really just a stripped-down version of jdatasrc.c. Comparison + * of this code with jdatasrc.c may be helpful in seeing how to make + * custom source managers for other purposes. + */ + +/* this is not a core library module, so it doesn't define JPEG_INTERNALS */ +//#include "jinclude.h" +//#include "jmorecfg.h" +//#include "jpeglib.h" +//#include "jerror.h" +#include +#include +#include +#include "jpeg.h" + + +/* Expanded data source object for memory input */ + +typedef struct { + struct jpeg_source_mgr pub; /* public fields */ + jmp_buf error_jmp_buf; /* error handler for this instance */ + + JOCTET eoi_buffer[2]; /* a place to put a dummy EOI */ +} my_source_mgr; + +typedef my_source_mgr * my_src_ptr; + + +/* + * Initialize source --- called by jpeg_read_header + * before any data is actually read. + */ + +static void +init_source (j_decompress_ptr cinfo) +{ + /* No work, since jpeg_memory_src set up the buffer pointer and count. + * Indeed, if we want to read multiple JPEG images from one buffer, + * this *must* not do anything to the pointer. + */ +} + + +/* + * Fill the input buffer --- called whenever buffer is emptied. + * + * In this application, this routine should never be called; if it is called, + * the decompressor has overrun the end of the input buffer, implying we + * supplied an incomplete or corrupt JPEG datastream. A simple error exit + * might be the most appropriate response. + * + * But what we choose to do in this code is to supply dummy EOI markers + * in order to force the decompressor to finish processing and supply + * some sort of output image, no matter how corrupted. + */ + +static boolean +fill_input_buffer(j_decompress_ptr cinfo) +{ + my_src_ptr src = (my_src_ptr) cinfo->src; + + WARNMS(cinfo, JWRN_JPEG_EOF); + + /* Create a fake EOI marker */ + src->eoi_buffer[0] = (JOCTET) 0xFF; + src->eoi_buffer[1] = (JOCTET) JPEG_EOI; + src->pub.next_input_byte = src->eoi_buffer; + src->pub.bytes_in_buffer = 2; + + return TRUE; +} + + +/* + * Skip data --- used to skip over a potentially large amount of + * uninteresting data (such as an APPn marker). + * + * If we overrun the end of the buffer, we let fill_input_buffer deal with + * it. An extremely large skip could cause some time-wasting here, but + * it really isn't supposed to happen ... and the decompressor will never + * skip more than 64K anyway. + */ + +static void +skip_input_data (j_decompress_ptr cinfo, long num_bytes) +{ + my_src_ptr src = (my_src_ptr) cinfo->src; + + if (num_bytes > 0) { + while (num_bytes > (long) src->pub.bytes_in_buffer) { + num_bytes -= (long) src->pub.bytes_in_buffer; + (void) fill_input_buffer(cinfo); + /* note we assume that fill_input_buffer will never return FALSE, + * so suspension need not be handled. + */ + } + src->pub.next_input_byte += (size_t) num_bytes; + src->pub.bytes_in_buffer -= (size_t) num_bytes; + } +} + + +/* + * An additional method that can be provided by data source modules is the + * resync_to_restart method for error recovery in the presence of RST markers. + * For the moment, this source module just uses the default resync method + * provided by the JPEG library. That method assumes that no backtracking + * is possible. + */ + + +/* + * Terminate source --- called by jpeg_finish_decompress + * after all data has been read. Often a no-op. + * + * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding + * application must deal with any cleanup that should happen even + * for error exit. + */ + +static void +term_source (j_decompress_ptr cinfo) +{ + /* no work necessary here */ +} + + +/* + * Prepare for input from a memory buffer. + */ + +GLOBAL(void) +jpeg_memory_src (j_decompress_ptr cinfo, const JOCTET * buffer, size_t bufsize) +{ + my_src_ptr src; + + /* The source object is made permanent so that a series of JPEG images + * can be read from a single buffer by calling jpeg_memory_src + * only before the first one. + * This makes it unsafe to use this manager and a different source + * manager serially with the same JPEG object. Caveat programmer. + */ + if (cinfo->src == NULL) { /* first time for this JPEG object? */ + cinfo->src = (struct jpeg_source_mgr *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + sizeof(my_source_mgr)); + } + + src = (my_src_ptr) cinfo->src; + src->pub.init_source = init_source; + src->pub.fill_input_buffer = fill_input_buffer; + src->pub.skip_input_data = skip_input_data; + src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */ + src->pub.term_source = term_source; + + src->pub.next_input_byte = buffer; + src->pub.bytes_in_buffer = bufsize; +} diff --git a/rtengine/klt/README.txt b/rtengine/klt/README.txt new file mode 100644 index 000000000..59ebb44c2 --- /dev/null +++ b/rtengine/klt/README.txt @@ -0,0 +1,35 @@ +********************************************************************** +NOTICE: + +This code is now in the public domain. The Stanford Office of +Technology Licensing has removed all licensing restrictions. + +********************************************************************** + +KLT +An implementation of the Kanade-Lucas-Tomasi feature tracker + +Version 1.3.4 + +Authors: Stan Birchfield + stb@clemson.edu + + Thorsten Thormaehlen + thormae@tnt.uni-hannover.de + (implemented affine code) + + Thanks to many others for various bug fixes. + +Date: August 30, A.D. 2007 + May 10, A.D. 2007 + March 28, A.D. 2006 + November 21, A.D. 2005 + August 17, A.D. 2005 + June 16, A.D. 2004 + October 7, A.D. 1998 + +The code can be obtained from http://www.ces.clemson.edu/~stb/klt +(alternatively http://www.vision.stanford.edu/~birch/klt), +where the official manuals reside. For your convenience, unofficial +manuals have been placed in the current subdirectory 'doc'. + diff --git a/rtengine/klt/base.h b/rtengine/klt/base.h new file mode 100644 index 000000000..453aa7623 --- /dev/null +++ b/rtengine/klt/base.h @@ -0,0 +1,27 @@ +/********************************************************************* + * base.h + *********************************************************************/ + +#ifndef _BASE_H_ +#define _BASE_H_ + +#ifndef uchar +#define uchar unsigned char +#endif + +#ifndef schar +#define schar signed char +#endif + +#ifndef uint +#define uint unsigned int +#endif + +#ifndef ushort +#define ushort unsigned short +#endif + +#ifndef ulong +#define ulong unsigned long +#endif +#endif diff --git a/rtengine/klt/convolve.cc b/rtengine/klt/convolve.cc new file mode 100644 index 000000000..b6041a7a6 --- /dev/null +++ b/rtengine/klt/convolve.cc @@ -0,0 +1,319 @@ +/********************************************************************* + * convolve.c + *********************************************************************/ + +/* Standard includes */ +#include +#include +#include /* malloc(), realloc() */ + +/* Our includes */ +#include "base.h" +#include "error.h" +#include "convolve.h" +#include "klt_util.h" /* printing */ + +#define MAX_KERNEL_WIDTH 71 + + +typedef struct { + int width; + float data[MAX_KERNEL_WIDTH]; +} ConvolutionKernel; + +/* Kernels */ +static ConvolutionKernel gauss_kernel; +static ConvolutionKernel gaussderiv_kernel; +static float sigma_last = -10.0; + + +/********************************************************************* + * _KLTToFloatImage + * + * Given a pointer to image data (probably unsigned chars), copy + * data to a float image. + */ + +void _KLTToFloatImage( + KLT_PixelType *img, + int ncols, int nrows, + _KLT_FloatImage floatimg) +{ + KLT_PixelType *ptrend = img + ncols*nrows; + float *ptrout = floatimg->data; + + /* Output image must be large enough to hold result */ + assert(floatimg->ncols >= ncols); + assert(floatimg->nrows >= nrows); + + floatimg->ncols = ncols; + floatimg->nrows = nrows; + + while (img < ptrend) *ptrout++ = (float) *img++; +} + + +/********************************************************************* + * _computeKernels + */ + +static void _computeKernels( + float sigma, + ConvolutionKernel *gauss, + ConvolutionKernel *gaussderiv) +{ + const float factor = 0.01f; /* for truncating tail */ + int i; + + assert(MAX_KERNEL_WIDTH % 2 == 1); + assert(sigma >= 0.0); + + /* Compute kernels, and automatically determine widths */ + { + const int hw = MAX_KERNEL_WIDTH / 2; + float max_gauss = 1.0f, max_gaussderiv = (float) (sigma*exp(-0.5f)); + + /* Compute gauss and deriv */ + for (i = -hw ; i <= hw ; i++) { + gauss->data[i+hw] = (float) exp(-i*i / (2*sigma*sigma)); + gaussderiv->data[i+hw] = -i * gauss->data[i+hw]; + } + + /* Compute widths */ + gauss->width = MAX_KERNEL_WIDTH; + for (i = -hw ; fabs(gauss->data[i+hw] / max_gauss) < factor ; + i++, gauss->width -= 2); + gaussderiv->width = MAX_KERNEL_WIDTH; + for (i = -hw ; fabs(gaussderiv->data[i+hw] / max_gaussderiv) < factor ; + i++, gaussderiv->width -= 2); + if (gauss->width == MAX_KERNEL_WIDTH || + gaussderiv->width == MAX_KERNEL_WIDTH) { + KLTError("(_computeKernels) MAX_KERNEL_WIDTH %d is too small for " + "a sigma of %f", MAX_KERNEL_WIDTH, sigma); + exit(1); + } + } + + /* Shift if width less than MAX_KERNEL_WIDTH */ + for (i = 0 ; i < gauss->width ; i++) + gauss->data[i] = gauss->data[i+(MAX_KERNEL_WIDTH-gauss->width)/2]; + for (i = 0 ; i < gaussderiv->width ; i++) + gaussderiv->data[i] = gaussderiv->data[i+(MAX_KERNEL_WIDTH-gaussderiv->width)/2]; + /* Normalize gauss and deriv */ + { + const int hw = gaussderiv->width / 2; + float den; + + den = 0.0; + for (i = 0 ; i < gauss->width ; i++) den += gauss->data[i]; + for (i = 0 ; i < gauss->width ; i++) gauss->data[i] /= den; + den = 0.0; + for (i = -hw ; i <= hw ; i++) den -= i*gaussderiv->data[i+hw]; + for (i = -hw ; i <= hw ; i++) gaussderiv->data[i+hw] /= den; + } + + sigma_last = sigma; +} + + +/********************************************************************* + * _KLTGetKernelWidths + * + */ + +void _KLTGetKernelWidths( + float sigma, + int *gauss_width, + int *gaussderiv_width) +{ + _computeKernels(sigma, &gauss_kernel, &gaussderiv_kernel); + *gauss_width = gauss_kernel.width; + *gaussderiv_width = gaussderiv_kernel.width; +} + + +/********************************************************************* + * _convolveImageHoriz + */ + +static void _convolveImageHoriz( + _KLT_FloatImage imgin, + ConvolutionKernel kernel, + _KLT_FloatImage imgout) +{ + float *ptrrow = imgin->data; /* Points to row's first pixel */ + float *ptrout = imgout->data, /* Points to next output pixel */ + *ppp; + float sum; + int radius = kernel.width / 2; + int ncols = imgin->ncols, nrows = imgin->nrows; + int i, j, k; + + /* Kernel width must be odd */ + assert(kernel.width % 2 == 1); + + /* Must read from and write to different images */ + assert(imgin != imgout); + + /* Output image must be large enough to hold result */ + assert(imgout->ncols >= imgin->ncols); + assert(imgout->nrows >= imgin->nrows); + + /* For each row, do ... */ + for (j = 0 ; j < nrows ; j++) { + + /* Zero leftmost columns */ + for (i = 0 ; i < radius ; i++) + *ptrout++ = 0.0; + + /* Convolve middle columns with kernel */ + for ( ; i < ncols - radius ; i++) { + ppp = ptrrow + i - radius; + sum = 0.0; + for (k = kernel.width-1 ; k >= 0 ; k--) + sum += *ppp++ * kernel.data[k]; + *ptrout++ = sum; + } + + /* Zero rightmost columns */ + for ( ; i < ncols ; i++) + *ptrout++ = 0.0; + + ptrrow += ncols; + } +} + + +/********************************************************************* + * _convolveImageVert + */ + +static void _convolveImageVert( + _KLT_FloatImage imgin, + ConvolutionKernel kernel, + _KLT_FloatImage imgout) +{ + float *ptrcol = imgin->data; /* Points to row's first pixel */ + float *ptrout = imgout->data, /* Points to next output pixel */ + *ppp; + float sum; + int radius = kernel.width / 2; + int ncols = imgin->ncols, nrows = imgin->nrows; + int i, j, k; + + /* Kernel width must be odd */ + assert(kernel.width % 2 == 1); + + /* Must read from and write to different images */ + assert(imgin != imgout); + + /* Output image must be large enough to hold result */ + assert(imgout->ncols >= imgin->ncols); + assert(imgout->nrows >= imgin->nrows); + + /* For each column, do ... */ + for (i = 0 ; i < ncols ; i++) { + + /* Zero topmost rows */ + for (j = 0 ; j < radius ; j++) { + *ptrout = 0.0; + ptrout += ncols; + } + + /* Convolve middle rows with kernel */ + for ( ; j < nrows - radius ; j++) { + ppp = ptrcol + ncols * (j - radius); + sum = 0.0; + for (k = kernel.width-1 ; k >= 0 ; k--) { + sum += *ppp * kernel.data[k]; + ppp += ncols; + } + *ptrout = sum; + ptrout += ncols; + } + + /* Zero bottommost rows */ + for ( ; j < nrows ; j++) { + *ptrout = 0.0; + ptrout += ncols; + } + + ptrcol++; + ptrout -= nrows * ncols - 1; + } +} + + +/********************************************************************* + * _convolveSeparate + */ + +static void _convolveSeparate( + _KLT_FloatImage imgin, + ConvolutionKernel horiz_kernel, + ConvolutionKernel vert_kernel, + _KLT_FloatImage imgout) +{ + /* Create temporary image */ + _KLT_FloatImage tmpimg; + tmpimg = _KLTCreateFloatImage(imgin->ncols, imgin->nrows); + + /* Do convolution */ + _convolveImageHoriz(imgin, horiz_kernel, tmpimg); + + _convolveImageVert(tmpimg, vert_kernel, imgout); + + /* Free memory */ + _KLTFreeFloatImage(tmpimg); +} + + +/********************************************************************* + * _KLTComputeGradients + */ + +void _KLTComputeGradients( + _KLT_FloatImage img, + float sigma, + _KLT_FloatImage gradx, + _KLT_FloatImage grady) +{ + + /* Output images must be large enough to hold result */ + assert(gradx->ncols >= img->ncols); + assert(gradx->nrows >= img->nrows); + assert(grady->ncols >= img->ncols); + assert(grady->nrows >= img->nrows); + + /* Compute kernels, if necessary */ + if (fabs(sigma - sigma_last) > 0.05) + _computeKernels(sigma, &gauss_kernel, &gaussderiv_kernel); + + _convolveSeparate(img, gaussderiv_kernel, gauss_kernel, gradx); + _convolveSeparate(img, gauss_kernel, gaussderiv_kernel, grady); + +} + + +/********************************************************************* + * _KLTComputeSmoothedImage + */ + +void _KLTComputeSmoothedImage( + _KLT_FloatImage img, + float sigma, + _KLT_FloatImage smooth) +{ + /* Output image must be large enough to hold result */ + assert(smooth->ncols >= img->ncols); + assert(smooth->nrows >= img->nrows); + + /* Compute kernel, if necessary; gauss_deriv is not used */ + if (fabs(sigma - sigma_last) > 0.05) + _computeKernels(sigma, &gauss_kernel, &gaussderiv_kernel); + + _convolveSeparate(img, gauss_kernel, gauss_kernel, smooth); +} + + + diff --git a/rtengine/klt/convolve.h b/rtengine/klt/convolve.h new file mode 100644 index 000000000..6043a7e25 --- /dev/null +++ b/rtengine/klt/convolve.h @@ -0,0 +1,32 @@ +/********************************************************************* + * convolve.h + *********************************************************************/ + +#ifndef _CONVOLVE_H_ +#define _CONVOLVE_H_ + +#include "klt.h" +#include "klt_util.h" + +void _KLTToFloatImage( + KLT_PixelType *img, + int ncols, int nrows, + _KLT_FloatImage floatimg); + +void _KLTComputeGradients( + _KLT_FloatImage img, + float sigma, + _KLT_FloatImage gradx, + _KLT_FloatImage grady); + +void _KLTGetKernelWidths( + float sigma, + int *gauss_width, + int *gaussderiv_width); + +void _KLTComputeSmoothedImage( + _KLT_FloatImage img, + float sigma, + _KLT_FloatImage smooth); + +#endif diff --git a/rtengine/klt/error.cc b/rtengine/klt/error.cc new file mode 100644 index 000000000..c23640d50 --- /dev/null +++ b/rtengine/klt/error.cc @@ -0,0 +1,56 @@ +/********************************************************************* + * error.c + * + * Error and warning messages, and system commands. + *********************************************************************/ + + +/* Standard includes */ +#include +#include +#include + + +/********************************************************************* + * KLTError + * + * Prints an error message and dies. + * + * INPUTS + * exactly like printf + */ + +void KLTError(const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + fprintf(stderr, "KLT Error: "); + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n"); + va_end(args); + exit(1); +} + + +/********************************************************************* + * KLTWarning + * + * Prints a warning message. + * + * INPUTS + * exactly like printf + */ + +void KLTWarning(const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + fprintf(stderr, "KLT Warning: "); + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n"); + fflush(stderr); + va_end(args); +} + diff --git a/rtengine/klt/error.h b/rtengine/klt/error.h new file mode 100644 index 000000000..3905f99ac --- /dev/null +++ b/rtengine/klt/error.h @@ -0,0 +1,15 @@ +/********************************************************************* + * error.h + *********************************************************************/ + +#ifndef _ERROR_H_ +#define _ERROR_H_ + +#include +#include + +void KLTError(const char *fmt, ...); +void KLTWarning(const char *fmt, ...); + +#endif + diff --git a/rtengine/klt/klt.cc b/rtengine/klt/klt.cc new file mode 100644 index 000000000..831914754 --- /dev/null +++ b/rtengine/klt/klt.cc @@ -0,0 +1,535 @@ +/********************************************************************* + * klt.c + * + * Kanade-Lucas-Tomasi tracker + *********************************************************************/ + +/* Standard includes */ +#include +#include /* logf() */ +#include /* malloc() */ +#include "../rt_math.h" + +/* Our includes */ +#include "base.h" +#include "convolve.h" +#include "error.h" +#include "klt.h" +#include "pyramid.h" + +using namespace std; + +static const int mindist = 10; +static const int window_size = 7; +static const int min_eigenvalue = 1; +static const float min_determinant = 0.01f; +static const float min_displacement = 0.1f; +static const int max_iterations = 10; +static const float max_residue = 10.0f; +static const float grad_sigma = 1.0f; +static const float smooth_sigma_fact = 0.1f; +static const float pyramid_sigma_fact = 0.9f; +static const float step_factor = 1.0f; +static const KLT_BOOL sequentialMode = FALSE; +static const KLT_BOOL lighting_insensitive = FALSE; +/* for affine mapping*/ +static const int affineConsistencyCheck = -1; +static const int affine_window_size = 15; +static const int affine_max_iterations = 10; +static const float affine_max_residue = 10.0; +static const float affine_min_displacement = 0.02f; +static const float affine_max_displacement_differ = 1.5f; + +static const KLT_BOOL smoothBeforeSelecting = TRUE; +static const KLT_BOOL writeInternalImages = FALSE; +static const int search_range = 15; +static const int nSkippedPixels = 0; + +extern int KLT_verbose; + + +/********************************************************************* + * _createArray2D + * + * Creates a two-dimensional array. + * + * INPUTS + * ncols: no. of columns + * nrows: no. of rows + * nbytes: no. of bytes per entry + * + * RETURNS + * Pointer to an array. Must be coerced. + * + * EXAMPLE + * char **ar; + * ar = (char **) createArray2D(8, 5, sizeof(char)); + */ + +static void** _createArray2D(int ncols, int nrows, int nbytes) +{ + char **tt; + int i; + + tt = (char **) malloc(nrows * sizeof(void *) + + ncols * nrows * nbytes); + if (tt == NULL) { + KLTError("(createArray2D) Out of memory"); + exit(1); + } + for (i = 0 ; i < nrows ; i++) + tt[i] = ((char *) tt) + (nrows * sizeof(void *) + + i * ncols * nbytes); + + return((void **) tt); +} + + +/********************************************************************* + * KLTCreateTrackingContext + * + */ + +KLT_TrackingContext KLTCreateTrackingContext() +{ + KLT_TrackingContext tc; + + /* Allocate memory */ + tc = (KLT_TrackingContext) malloc(sizeof(KLT_TrackingContextRec)); + + /* Set values to default values */ + tc->mindist = mindist; + tc->window_width = window_size; + tc->window_height = window_size; + tc->sequentialMode = sequentialMode; + tc->smoothBeforeSelecting = smoothBeforeSelecting; + tc->writeInternalImages = writeInternalImages; + tc->lighting_insensitive = lighting_insensitive; + tc->min_eigenvalue = min_eigenvalue; + tc->min_determinant = min_determinant; + tc->max_iterations = max_iterations; + tc->min_displacement = min_displacement; + tc->max_residue = max_residue; + tc->grad_sigma = grad_sigma; + tc->smooth_sigma_fact = smooth_sigma_fact; + tc->pyramid_sigma_fact = pyramid_sigma_fact; + tc->step_factor = step_factor; + tc->nSkippedPixels = nSkippedPixels; + tc->pyramid_last = NULL; + tc->pyramid_last_gradx = NULL; + tc->pyramid_last_grady = NULL; + /* for affine mapping */ + tc->affineConsistencyCheck = affineConsistencyCheck; + tc->affine_window_width = affine_window_size; + tc->affine_window_height = affine_window_size; + tc->affine_max_iterations = affine_max_iterations; + tc->affine_max_residue = affine_max_residue; + tc->affine_min_displacement = affine_min_displacement; + tc->affine_max_displacement_differ = affine_max_displacement_differ; + + /* Change nPyramidLevels and subsampling */ + KLTChangeTCPyramid(tc, search_range); + + /* Update border, which is dependent upon */ + /* smooth_sigma_fact, pyramid_sigma_fact, window_size, and subsampling */ + KLTUpdateTCBorder(tc); + + return(tc); +} + + +/********************************************************************* + * KLTCreateFeatureList + * + */ + +KLT_FeatureList KLTCreateFeatureList( + int nFeatures) +{ + KLT_FeatureList fl; + KLT_Feature first; + int nbytes = sizeof(KLT_FeatureListRec) + + nFeatures * sizeof(KLT_Feature) + + nFeatures * sizeof(KLT_FeatureRec); + int i; + + /* Allocate memory for feature list */ + fl = (KLT_FeatureList) malloc(nbytes); + + /* Set parameters */ + fl->nFeatures = nFeatures; + + /* Set pointers */ + fl->feature = (KLT_Feature *) (fl + 1); + first = (KLT_Feature) (fl->feature + nFeatures); + for (i = 0 ; i < nFeatures ; i++) { + fl->feature[i] = first + i; + fl->feature[i]->aff_img = NULL; /* initialization fixed by Sinisa Segvic */ + fl->feature[i]->aff_img_gradx = NULL; + fl->feature[i]->aff_img_grady = NULL; + } + /* Return feature list */ + return(fl); +} + + +/********************************************************************* + * KLTCreateFeatureHistory + * + */ + +KLT_FeatureHistory KLTCreateFeatureHistory( + int nFrames) +{ + KLT_FeatureHistory fh; + KLT_Feature first; + int nbytes = sizeof(KLT_FeatureHistoryRec) + + nFrames * sizeof(KLT_Feature) + + nFrames * sizeof(KLT_FeatureRec); + int i; + + /* Allocate memory for feature history */ + fh = (KLT_FeatureHistory) malloc(nbytes); + + /* Set parameters */ + fh->nFrames = nFrames; + + /* Set pointers */ + fh->feature = (KLT_Feature *) (fh + 1); + first = (KLT_Feature) (fh->feature + nFrames); + for (i = 0 ; i < nFrames ; i++) + fh->feature[i] = first + i; + + /* Return feature history */ + return(fh); +} + + +/********************************************************************* + * KLTCreateFeatureTable + * + */ + +KLT_FeatureTable KLTCreateFeatureTable( + int nFrames, + int nFeatures) +{ + KLT_FeatureTable ft; + KLT_Feature first; + int nbytes = sizeof(KLT_FeatureTableRec); + int i, j; + + /* Allocate memory for feature history */ + ft = (KLT_FeatureTable) malloc(nbytes); + + /* Set parameters */ + ft->nFrames = nFrames; + ft->nFeatures = nFeatures; + + /* Set pointers */ + ft->feature = (KLT_Feature **) + _createArray2D(nFrames, nFeatures, sizeof(KLT_Feature)); + first = (KLT_Feature) malloc(nFrames * nFeatures * sizeof(KLT_FeatureRec)); + for (j = 0 ; j < nFeatures ; j++) + for (i = 0 ; i < nFrames ; i++) + ft->feature[j][i] = first + j*nFrames + i; + + //free(first); + /* Return feature table */ + return(ft); +} + + +/********************************************************************* + * KLTPrintTrackingContext + */ + +void KLTPrintTrackingContext( + KLT_TrackingContext tc) +{ + fprintf(stderr, "\n\nTracking context:\n\n"); + fprintf(stderr, "\tmindist = %d\n", tc->mindist); + fprintf(stderr, "\twindow_width = %d\n", tc->window_width); + fprintf(stderr, "\twindow_height = %d\n", tc->window_height); + fprintf(stderr, "\tsequentialMode = %s\n", + tc->sequentialMode ? "TRUE" : "FALSE"); + fprintf(stderr, "\tsmoothBeforeSelecting = %s\n", + tc->smoothBeforeSelecting ? "TRUE" : "FALSE"); + fprintf(stderr, "\twriteInternalImages = %s\n", + tc->writeInternalImages ? "TRUE" : "FALSE"); + + fprintf(stderr, "\tmin_eigenvalue = %d\n", tc->min_eigenvalue); + fprintf(stderr, "\tmin_determinant = %f\n", tc->min_determinant); + fprintf(stderr, "\tmin_displacement = %f\n", tc->min_displacement); + fprintf(stderr, "\tmax_iterations = %d\n", tc->max_iterations); + fprintf(stderr, "\tmax_residue = %f\n", tc->max_residue); + fprintf(stderr, "\tgrad_sigma = %f\n", tc->grad_sigma); + fprintf(stderr, "\tsmooth_sigma_fact = %f\n", tc->smooth_sigma_fact); + fprintf(stderr, "\tpyramid_sigma_fact = %f\n", tc->pyramid_sigma_fact); + fprintf(stderr, "\tnSkippedPixels = %d\n", tc->nSkippedPixels); + fprintf(stderr, "\tborderx = %d\n", tc->borderx); + fprintf(stderr, "\tbordery = %d\n", tc->bordery); + fprintf(stderr, "\tnPyramidLevels = %d\n", tc->nPyramidLevels); + fprintf(stderr, "\tsubsampling = %d\n", tc->subsampling); + + fprintf(stderr, "\n\tpyramid_last = %s\n", (tc->pyramid_last!=NULL) ? + "points to old image" : "NULL"); + fprintf(stderr, "\tpyramid_last_gradx = %s\n", + (tc->pyramid_last_gradx!=NULL) ? + "points to old image" : "NULL"); + fprintf(stderr, "\tpyramid_last_grady = %s\n", + (tc->pyramid_last_grady!=NULL) ? + "points to old image" : "NULL"); + fprintf(stderr, "\n\n"); +} + + +/********************************************************************* + * KLTChangeTCPyramid + * + */ + +void KLTChangeTCPyramid( + KLT_TrackingContext tc, + int search_range) +{ + float window_halfwidth; + float subsampling; + + /* Check window size (and correct if necessary) */ + if (tc->window_width % 2 != 1) { + tc->window_width = tc->window_width+1; + KLTWarning("(KLTChangeTCPyramid) Window width must be odd. " + "Changing to %d.\n", tc->window_width); + } + if (tc->window_height % 2 != 1) { + tc->window_height = tc->window_height+1; + KLTWarning("(KLTChangeTCPyramid) Window height must be odd. " + "Changing to %d.\n", tc->window_height); + } + if (tc->window_width < 3) { + tc->window_width = 3; + KLTWarning("(KLTChangeTCPyramid) Window width must be at least three. \n" + "Changing to %d.\n", tc->window_width); + } + if (tc->window_height < 3) { + tc->window_height = 3; + KLTWarning("(KLTChangeTCPyramid) Window height must be at least three. \n" + "Changing to %d.\n", tc->window_height); + } + window_halfwidth = min(tc->window_width,tc->window_height)/2.0f; + + subsampling = ((float) search_range) / window_halfwidth; + + if (subsampling < 1.0) { /* 1.0 = 0+1 */ + tc->nPyramidLevels = 1; + } else if (subsampling <= 3.0) { /* 3.0 = 2+1 */ + tc->nPyramidLevels = 2; + tc->subsampling = 2; + } else if (subsampling <= 5.0) { /* 5.0 = 4+1 */ + tc->nPyramidLevels = 2; + tc->subsampling = 4; + } else if (subsampling <= 9.0) { /* 9.0 = 8+1 */ + tc->nPyramidLevels = 2; + tc->subsampling = 8; + } else { + /* The following lines are derived from the formula: + search_range = + window_halfwidth * \sum_{i=0}^{nPyramidLevels-1} 8^i, + which is the same as: + search_range = + window_halfwidth * (8^nPyramidLevels - 1)/(8 - 1). + Then, the value is rounded up to the nearest integer. */ + float val = (float) (log(7.0*subsampling+1.0)/log(8.0)); + tc->nPyramidLevels = (int) (val + 0.99); + tc->subsampling = 8; + } +} + + +/********************************************************************* + * NOTE: Manually must ensure consistency with _KLTComputePyramid() + */ + +static float _pyramidSigma( + KLT_TrackingContext tc) +{ + return (tc->pyramid_sigma_fact * tc->subsampling); +} + + +/********************************************************************* + * Updates border, which is dependent upon + * smooth_sigma_fact, pyramid_sigma_fact, window_size, and subsampling + */ + +void KLTUpdateTCBorder( + KLT_TrackingContext tc) +{ + float val; + int pyramid_gauss_hw; + int smooth_gauss_hw; + int gauss_width, gaussderiv_width; + int num_levels = tc->nPyramidLevels; + int n_invalid_pixels; + int window_hw; + int ss = tc->subsampling; + int ss_power; + int border; + int i; + + /* Check window size (and correct if necessary) */ + if (tc->window_width % 2 != 1) { + tc->window_width = tc->window_width+1; + KLTWarning("(KLTUpdateTCBorder) Window width must be odd. " + "Changing to %d.\n", tc->window_width); + } + if (tc->window_height % 2 != 1) { + tc->window_height = tc->window_height+1; + KLTWarning("(KLTUpdateTCBorder) Window height must be odd. " + "Changing to %d.\n", tc->window_height); + } + if (tc->window_width < 3) { + tc->window_width = 3; + KLTWarning("(KLTUpdateTCBorder) Window width must be at least three. \n" + "Changing to %d.\n", tc->window_width); + } + if (tc->window_height < 3) { + tc->window_height = 3; + KLTWarning("(KLTUpdateTCBorder) Window height must be at least three. \n" + "Changing to %d.\n", tc->window_height); + } + window_hw = max(tc->window_width, tc->window_height)/2; + + /* Find widths of convolution windows */ + _KLTGetKernelWidths(_KLTComputeSmoothSigma(tc), + &gauss_width, &gaussderiv_width); + smooth_gauss_hw = gauss_width/2; + _KLTGetKernelWidths(_pyramidSigma(tc), + &gauss_width, &gaussderiv_width); + pyramid_gauss_hw = gauss_width/2; + + /* Compute the # of invalid pixels at each level of the pyramid. + n_invalid_pixels is computed with respect to the ith level + of the pyramid. So, e.g., if n_invalid_pixels = 5 after + the first iteration, then there are 5 invalid pixels in + level 1, which translated means 5*subsampling invalid pixels + in the original level 0. */ + n_invalid_pixels = smooth_gauss_hw; + for (i = 1 ; i < num_levels ; i++) { + val = ((float) n_invalid_pixels + pyramid_gauss_hw) / ss; + n_invalid_pixels = (int) (val + 0.99); /* Round up */ + } + + /* ss_power = ss^(num_levels-1) */ + ss_power = 1; + for (i = 1 ; i < num_levels ; i++) + ss_power *= ss; + + /* Compute border by translating invalid pixels back into */ + /* original image */ + border = (n_invalid_pixels + window_hw) * ss_power; + + tc->borderx = border; + tc->bordery = border; +} + + +/********************************************************************* + * KLTFreeTrackingContext + * KLTFreeFeatureList + * KLTFreeFeatureHistory + * KLTFreeFeatureTable + */ + +void KLTFreeTrackingContext( + KLT_TrackingContext tc) +{ + if (tc->pyramid_last) + _KLTFreePyramid((_KLT_Pyramid) tc->pyramid_last); + if (tc->pyramid_last_gradx) + _KLTFreePyramid((_KLT_Pyramid) tc->pyramid_last_gradx); + if (tc->pyramid_last_grady) + _KLTFreePyramid((_KLT_Pyramid) tc->pyramid_last_grady); + free(tc); +} + +void KLTFreeFeatureList( + KLT_FeatureList fl) +{ + /* for affine mapping */ + int indx; + for (indx = 0 ; indx < fl->nFeatures ; indx++) { + /* free image and gradient */ + _KLTFreeFloatImage(fl->feature[indx]->aff_img); + _KLTFreeFloatImage(fl->feature[indx]->aff_img_gradx); + _KLTFreeFloatImage(fl->feature[indx]->aff_img_grady); + fl->feature[indx]->aff_img = NULL; + fl->feature[indx]->aff_img_gradx = NULL; + fl->feature[indx]->aff_img_grady = NULL; + } + + free(fl); +} + +void KLTFreeFeatureHistory( + KLT_FeatureHistory fh) +{ + free(fh); +} + +void KLTFreeFeatureTable( + KLT_FeatureTable ft) +{ + free(ft->feature[0][0]); /* this plugs a memory leak found by Stefan Wachter */ + free(ft->feature); + free(ft); +} + + +/********************************************************************* + * KLTStopSequentialMode + */ + +void KLTStopSequentialMode( + KLT_TrackingContext tc) +{ + tc->sequentialMode = FALSE; + _KLTFreePyramid((_KLT_Pyramid) tc->pyramid_last); + _KLTFreePyramid((_KLT_Pyramid) tc->pyramid_last_gradx); + _KLTFreePyramid((_KLT_Pyramid) tc->pyramid_last_grady); + tc->pyramid_last = NULL; + tc->pyramid_last_gradx = NULL; + tc->pyramid_last_grady = NULL; +} + + +/********************************************************************* + * KLTCountRemainingFeatures + */ + +int KLTCountRemainingFeatures( + KLT_FeatureList fl) +{ + int count = 0; + int i; + + for (i = 0 ; i < fl->nFeatures ; i++) + if (fl->feature[i]->val >= 0) + count++; + + return count; +} + +/********************************************************************* + * KLTSetVerbosity + */ + +void KLTSetVerbosity( + int verbosity) +{ + KLT_verbose = verbosity; +} + + + diff --git a/rtengine/klt/klt.h b/rtengine/klt/klt.h new file mode 100644 index 000000000..7b174b69b --- /dev/null +++ b/rtengine/klt/klt.h @@ -0,0 +1,244 @@ +/********************************************************************* + * klt.h + * + * Kanade-Lucas-Tomasi tracker + *********************************************************************/ + +#ifndef _KLT_H_ +#define _KLT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef float KLT_locType; +typedef unsigned char KLT_PixelType; + +#define KLT_BOOL int + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + +#ifndef NULL +#define NULL 0 +#endif + +#define KLT_TRACKED 0 +#define KLT_NOT_FOUND -1 +#define KLT_SMALL_DET -2 +#define KLT_MAX_ITERATIONS -3 +#define KLT_OOB -4 +#define KLT_LARGE_RESIDUE -5 + +#include "klt_util.h" /* for affine mapping */ + +/******************* + * Structures + */ + +typedef struct { + /* Available to user */ + int mindist; /* min distance b/w features */ + int window_width, window_height; + KLT_BOOL sequentialMode; /* whether to save most recent image to save time */ + /* can set to TRUE manually, but don't set to */ + /* FALSE manually */ + KLT_BOOL smoothBeforeSelecting; /* whether to smooth image before */ + /* selecting features */ + KLT_BOOL writeInternalImages; /* whether to write internal images */ + /* tracking features */ + KLT_BOOL lighting_insensitive; /* whether to normalize for gain and bias (not in original algorithm) */ + + /* Available, but hopefully can ignore */ + int min_eigenvalue; /* smallest eigenvalue allowed for selecting */ + float min_determinant; /* th for determining lost */ + float min_displacement; /* th for stopping tracking when pixel changes little */ + int max_iterations; /* th for stopping tracking when too many iterations */ + float max_residue; /* th for stopping tracking when residue is large */ + float grad_sigma; + float smooth_sigma_fact; + float pyramid_sigma_fact; + float step_factor; /* size of Newton steps; 2.0 comes from equations, 1.0 seems to avoid overshooting */ + int nSkippedPixels; /* # of pixels skipped when finding features */ + int borderx; /* border in which features will not be found */ + int bordery; + int nPyramidLevels; /* computed from search_ranges */ + int subsampling; /* " */ + + + /* for affine mapping */ + int affine_window_width, affine_window_height; + int affineConsistencyCheck; /* whether to evaluates the consistency of features with affine mapping + -1 = don't evaluates the consistency + 0 = evaluates the consistency of features with translation mapping + 1 = evaluates the consistency of features with similarity mapping + 2 = evaluates the consistency of features with affine mapping + */ + int affine_max_iterations; + float affine_max_residue; + float affine_min_displacement; + float affine_max_displacement_differ; /* th for the difference between the displacement calculated + by the affine tracker and the frame to frame tracker in pel*/ + + /* User must not touch these */ + void *pyramid_last; + void *pyramid_last_gradx; + void *pyramid_last_grady; +} KLT_TrackingContextRec, *KLT_TrackingContext; + + +typedef struct { + KLT_locType x; + KLT_locType y; + int val; + /* for affine mapping */ + _KLT_FloatImage aff_img; + _KLT_FloatImage aff_img_gradx; + _KLT_FloatImage aff_img_grady; + KLT_locType aff_x; + KLT_locType aff_y; + KLT_locType aff_Axx; + KLT_locType aff_Ayx; + KLT_locType aff_Axy; + KLT_locType aff_Ayy; +} KLT_FeatureRec, *KLT_Feature; + +typedef struct { + int nFeatures; + KLT_Feature *feature; +} KLT_FeatureListRec, *KLT_FeatureList; + +typedef struct { + int nFrames; + KLT_Feature *feature; +} KLT_FeatureHistoryRec, *KLT_FeatureHistory; + +typedef struct { + int nFrames; + int nFeatures; + KLT_Feature **feature; +} KLT_FeatureTableRec, *KLT_FeatureTable; + + + +/******************* + * Functions + */ + +/* Create */ +KLT_TrackingContext KLTCreateTrackingContext(void); +KLT_FeatureList KLTCreateFeatureList( + int nFeatures); +KLT_FeatureHistory KLTCreateFeatureHistory( + int nFrames); +KLT_FeatureTable KLTCreateFeatureTable( + int nFrames, + int nFeatures); + +/* Free */ +void KLTFreeTrackingContext( + KLT_TrackingContext tc); +void KLTFreeFeatureList( + KLT_FeatureList fl); +void KLTFreeFeatureHistory( + KLT_FeatureHistory fh); +void KLTFreeFeatureTable( + KLT_FeatureTable ft); + +/* Processing */ +void KLTSelectGoodFeatures( + KLT_TrackingContext tc, + KLT_PixelType *img, + int ncols, + int nrows, + KLT_FeatureList fl); +void KLTTrackFeatures( + KLT_TrackingContext tc, + KLT_PixelType *img1, + KLT_PixelType *img2, + int ncols, + int nrows, + KLT_FeatureList fl); +void KLTReplaceLostFeatures( + KLT_TrackingContext tc, + KLT_PixelType *img, + int ncols, + int nrows, + KLT_FeatureList fl); + +/* Utilities */ +int KLTCountRemainingFeatures( + KLT_FeatureList fl); +void KLTPrintTrackingContext( + KLT_TrackingContext tc); +void KLTChangeTCPyramid( + KLT_TrackingContext tc, + int search_range); +void KLTUpdateTCBorder( + KLT_TrackingContext tc); +void KLTStopSequentialMode( + KLT_TrackingContext tc); +void KLTSetVerbosity( + int verbosity); +float _KLTComputeSmoothSigma( + KLT_TrackingContext tc); + +/* Storing/Extracting Features */ +void KLTStoreFeatureList( + KLT_FeatureList fl, + KLT_FeatureTable ft, + int frame); +void KLTExtractFeatureList( + KLT_FeatureList fl, + KLT_FeatureTable ft, + int frame); +void KLTStoreFeatureHistory( + KLT_FeatureHistory fh, + KLT_FeatureTable ft, + int feat); +void KLTExtractFeatureHistory( + KLT_FeatureHistory fh, + KLT_FeatureTable ft, + int feat); + +/* Writing/Reading */ +void KLTWriteFeatureListToPPM( + KLT_FeatureList fl, + KLT_PixelType *greyimg, + int ncols, + int nrows, + const char *filename); +void KLTWriteFeatureList( + KLT_FeatureList fl, + const char *filename, + const char *fmt); +void KLTWriteFeatureHistory( + KLT_FeatureHistory fh, + const char *filename, + const char *fmt); +void KLTWriteFeatureTable( + KLT_FeatureTable ft, + const char *filename, + const char *fmt); +KLT_FeatureList KLTReadFeatureList( + KLT_FeatureList fl, + const char *filename); +KLT_FeatureHistory KLTReadFeatureHistory( + KLT_FeatureHistory fh, + const char *filename); +KLT_FeatureTable KLTReadFeatureTable( + KLT_FeatureTable ft, + const char *filename); +#ifdef __cplusplus +} +#endif + +#endif + + + + + + diff --git a/rtengine/klt/klt_util.cc b/rtengine/klt/klt_util.cc new file mode 100644 index 000000000..e1fc342f3 --- /dev/null +++ b/rtengine/klt/klt_util.cc @@ -0,0 +1,170 @@ +/********************************************************************* + * klt_util.c + *********************************************************************/ + +/* Standard includes */ +#include +#include /* malloc() */ +#include /* fabs() */ + +#include "../rt_math.h" + +/* Our includes */ +#include "base.h" +#include "error.h" +#include "pnmio.h" +#include "klt.h" +#include "klt_util.h" + +using namespace std; + +/*********************************************************************/ + +float _KLTComputeSmoothSigma( + KLT_TrackingContext tc) +{ + return (tc->smooth_sigma_fact * max(tc->window_width, tc->window_height)); +} + + +/********************************************************************* + * _KLTCreateFloatImage + */ + +_KLT_FloatImage _KLTCreateFloatImage( + int ncols, + int nrows) +{ + _KLT_FloatImage floatimg; + int nbytes = sizeof(_KLT_FloatImageRec) + + ncols * nrows * sizeof(float); + + floatimg = (_KLT_FloatImage) malloc(nbytes); + if (floatimg == NULL) { + KLTError("(_KLTCreateFloatImage) Out of memory"); + exit(1); + } + floatimg->ncols = ncols; + floatimg->nrows = nrows; + floatimg->data = (float *) (floatimg + 1); + + return(floatimg); +} + + +/********************************************************************* + * _KLTFreeFloatImage + */ + +void _KLTFreeFloatImage( + _KLT_FloatImage floatimg) +{ + free(floatimg); +} + + +/********************************************************************* + * _KLTPrintSubFloatImage + */ + +void _KLTPrintSubFloatImage( + _KLT_FloatImage floatimg, + int x0, int y0, + int width, int height) +{ + int ncols = floatimg->ncols; + int offset; + int i, j; + + assert(x0 >= 0); + assert(y0 >= 0); + assert(x0 + width <= ncols); + assert(y0 + height <= floatimg->nrows); + + fprintf(stderr, "\n"); + for (j = 0 ; j < height ; j++) { + for (i = 0 ; i < width ; i++) { + offset = (j+y0)*ncols + (i+x0); + fprintf(stderr, "%6.2f ", *(floatimg->data + offset)); + } + fprintf(stderr, "\n"); + } + fprintf(stderr, "\n"); +} + + +/********************************************************************* + * _KLTWriteFloatImageToPGM + */ + +void _KLTWriteFloatImageToPGM( + _KLT_FloatImage img, + const char *filename) +{ + int npixs = img->ncols * img->nrows; + float mmax = -999999.9f, mmin = 999999.9f; + float fact; + float *ptr; + uchar *byteimg, *ptrout; + int i; + + /* Calculate minimum and maximum values of float image */ + ptr = img->data; + for (i = 0 ; i < npixs ; i++) { + mmax = max(mmax, *ptr); + mmin = min(mmin, *ptr); + ptr++; + } + + /* Allocate memory to hold converted image */ + byteimg = (uchar *) malloc(npixs * sizeof(uchar)); + + /* Convert image from float to uchar */ + fact = 255.0f / (mmax-mmin); + ptr = img->data; + ptrout = byteimg; + for (i = 0 ; i < npixs ; i++) { + *ptrout++ = (uchar) ((*ptr++ - mmin) * fact); + } + + /* Write uchar image to PGM */ + pgmWriteFile(filename, byteimg, img->ncols, img->nrows); + + /* Free memory */ + free(byteimg); +} + +/********************************************************************* + * _KLTWriteFloatImageToPGM + */ + +void _KLTWriteAbsFloatImageToPGM( + _KLT_FloatImage img, + const char *filename,float scale) +{ + int npixs = img->ncols * img->nrows; + float fact; + float *ptr; + uchar *byteimg, *ptrout; + int i; + float tmp; + + /* Allocate memory to hold converted image */ + byteimg = (uchar *) malloc(npixs * sizeof(uchar)); + + /* Convert image from float to uchar */ + fact = 255.0f / scale; + ptr = img->data; + ptrout = byteimg; + for (i = 0 ; i < npixs ; i++) { + tmp = (float) (fabs(*ptr++) * fact); + if(tmp > 255.0) tmp = 255.0; + *ptrout++ = (uchar) tmp; + } + + /* Write uchar image to PGM */ + pgmWriteFile(filename, byteimg, img->ncols, img->nrows); + + /* Free memory */ + free(byteimg); +} diff --git a/rtengine/klt/klt_util.h b/rtengine/klt/klt_util.h new file mode 100644 index 000000000..4ddd2e74b --- /dev/null +++ b/rtengine/klt/klt_util.h @@ -0,0 +1,37 @@ +/********************************************************************* + * klt_util.h + *********************************************************************/ + +#ifndef _KLT_UTIL_H_ +#define _KLT_UTIL_H_ + +typedef struct { + int ncols; + int nrows; + float *data; +} _KLT_FloatImageRec, *_KLT_FloatImage; + +_KLT_FloatImage _KLTCreateFloatImage( + int ncols, + int nrows); + +void _KLTFreeFloatImage( + _KLT_FloatImage); + +void _KLTPrintSubFloatImage( + _KLT_FloatImage floatimg, + int x0, int y0, + int width, int height); + +void _KLTWriteFloatImageToPGM( + _KLT_FloatImage img, + const char *filename); + +/* for affine mapping */ +void _KLTWriteAbsFloatImageToPGM( + _KLT_FloatImage img, + const char *filename,float scale); + +#endif + + diff --git a/rtengine/klt/main.cpp b/rtengine/klt/main.cpp new file mode 100644 index 000000000..7ce9b378d --- /dev/null +++ b/rtengine/klt/main.cpp @@ -0,0 +1,30 @@ +// main.cpp : Defines the entry point for the console application. +// + +#include // printf + +extern "C" { + void RunExample1(); + void RunExample2(); + void RunExample3(); + void RunExample4(); + void RunExample5(); +} + +int main(int argc, char* argv[]) +{ + // select which example to run here + const int which = 1; + + // run the appropriate example + switch (which) { + case 1: RunExample1(); break; + case 2: RunExample2(); break; + case 3: RunExample3(); break; + case 4: RunExample4(); break; // Note: example4 reads output from example 3 + case 5: RunExample5(); break; + default: printf("There is no example number %d\n", which); + } + return 0; +} + diff --git a/rtengine/klt/pnmio.cc b/rtengine/klt/pnmio.cc new file mode 100644 index 000000000..de8a1b0d9 --- /dev/null +++ b/rtengine/klt/pnmio.cc @@ -0,0 +1,353 @@ +/********************************************************************* + * pnmio.c + * + * Various routines to manipulate PNM files. + *********************************************************************/ + + +/* Standard includes */ +#include /* FILE */ +#include /* malloc(), atoi() */ + +/* Our includes */ +#include "error.h" + +#define LENGTH 80 + + +/*********************************************************************/ + +static void _getNextString( + FILE *fp, + char *line) +{ + int i; + + line[0] = '\0'; + + while (line[0] == '\0') { + fscanf(fp, "%s", line); + i = -1; + do { + i++; + if (line[i] == '#') { + line[i] = '\0'; + while (fgetc(fp) != '\n') ; + } + } while (line[i] != '\0'); + } +} + + +/********************************************************************* + * pnmReadHeader + */ + +void pnmReadHeader( + FILE *fp, + int *magic, + int *ncols, int *nrows, + int *maxval) +{ + char line[LENGTH]; + + /* Read magic number */ + _getNextString(fp, line); + if (line[0] != 'P') { + KLTError("(pnmReadHeader) Magic number does not begin with 'P', " + "but with a '%c'", line[0]); + exit(1); + } + sscanf(line, "P%d", magic); + + /* Read size, skipping comments */ + _getNextString(fp, line); + *ncols = atoi(line); + _getNextString(fp, line); + *nrows = atoi(line); + if (*ncols < 0 || *nrows < 0 || *ncols > 10000 || *nrows > 10000) { + KLTError("(pnmReadHeader) The dimensions %d x %d are unacceptable", + *ncols, *nrows); + exit(1); + } + + /* Read maxval, skipping comments */ + _getNextString(fp, line); + *maxval = atoi(line); + fread(line, 1, 1, fp); /* Read newline which follows maxval */ + + if (*maxval != 255) + KLTWarning("(pnmReadHeader) Maxval is not 255, but %d", *maxval); +} + + +/********************************************************************* + * pgmReadHeader + */ + +void pgmReadHeader( + FILE *fp, + int *magic, + int *ncols, int *nrows, + int *maxval) +{ + pnmReadHeader(fp, magic, ncols, nrows, maxval); + if (*magic != 5) { + KLTError("(pgmReadHeader) Magic number is not 'P5', but 'P%d'", *magic); + exit(1); + } +} + + +/********************************************************************* + * ppmReadHeader + */ + +void ppmReadHeader( + FILE *fp, + int *magic, + int *ncols, int *nrows, + int *maxval) +{ + pnmReadHeader(fp, magic, ncols, nrows, maxval); + if (*magic != 6) { + KLTError("(ppmReadHeader) Magic number is not 'P6', but 'P%d'", *magic); + exit(1); + } +} + + +/********************************************************************* + * pgmReadHeaderFile + */ + +void pgmReadHeaderFile( + const char *fname, + int *magic, + int *ncols, int *nrows, + int *maxval) +{ + FILE *fp; + + /* Open file */ + if ( (fp = fopen(fname, "rb")) == NULL) { + KLTError("(pgmReadHeaderFile) Can't open file named '%s' for reading\n", fname); + exit(1); + } + + /* Read header */ + pgmReadHeader(fp, magic, ncols, nrows, maxval); + + /* Close file */ + fclose(fp); +} + + +/********************************************************************* + * ppmReadHeaderFile + */ + +void ppmReadHeaderFile( + const char *fname, + int *magic, + int *ncols, int *nrows, + int *maxval) +{ + FILE *fp; + + /* Open file */ + if ( (fp = fopen(fname, "rb")) == NULL) { + KLTError("(ppmReadHeaderFile) Can't open file named '%s' for reading\n", fname); + exit(1); + } + + /* Read header */ + ppmReadHeader(fp, magic, ncols, nrows, maxval); + + /* Close file */ + fclose(fp); +} + + +/********************************************************************* + * pgmRead + * + * NOTE: If img is NULL, memory is allocated. + */ + +unsigned char* pgmRead( + FILE *fp, + unsigned char *img, + int *ncols, int *nrows) +{ + unsigned char *ptr; + int magic, maxval; + int i; + + /* Read header */ + pgmReadHeader(fp, &magic, ncols, nrows, &maxval); + + /* Allocate memory, if necessary, and set pointer */ + if (img == NULL) { + ptr = (unsigned char *) malloc(*ncols * *nrows * sizeof(char)); + if (ptr == NULL) { + KLTError("(pgmRead) Memory not allocated"); + exit(1); + } + } + else + ptr = img; + + /* Read binary image data */ + { + unsigned char *tmpptr = ptr; + for (i = 0 ; i < *nrows ; i++) { + fread(tmpptr, *ncols, 1, fp); + tmpptr += *ncols; + } + } + + return ptr; +} + + +/********************************************************************* + * pgmReadFile + * + * NOTE: If img is NULL, memory is allocated. + */ + +unsigned char* pgmReadFile( + const char *fname, + unsigned char *img, + int *ncols, int *nrows) +{ + unsigned char *ptr; + FILE *fp; + + /* Open file */ + if ( (fp = fopen(fname, "rb")) == NULL) { + KLTError("(pgmReadFile) Can't open file named '%s' for reading\n", fname); + exit(1); + } + + /* Read file */ + ptr = pgmRead(fp, img, ncols, nrows); + + /* Close file */ + fclose(fp); + + return ptr; +} + + +/********************************************************************* + * pgmWrite + */ + +void pgmWrite( + FILE *fp, + const unsigned char *img, + int ncols, + int nrows) +{ + int i; + + /* Write header */ + fprintf(fp, "P5\n"); + fprintf(fp, "%d %d\n", ncols, nrows); + fprintf(fp, "255\n"); + + /* Write binary data */ + for (i = 0 ; i < nrows ; i++) { + fwrite(img, ncols, 1, fp); + img += ncols; + } +} + + +/********************************************************************* + * pgmWriteFile + */ + +void pgmWriteFile( + const char *fname, + const unsigned char *img, + int ncols, + int nrows) +{ + FILE *fp; + + /* Open file */ + if ( (fp = fopen(fname, "wb")) == NULL) { + KLTError("(pgmWriteFile) Can't open file named '%s' for writing\n", fname); + exit(1); + } + + /* Write to file */ + pgmWrite(fp, img, ncols, nrows); + + /* Close file */ + fclose(fp); +} + + +/********************************************************************* + * ppmWrite + */ + +void ppmWrite( + FILE *fp, + const unsigned char *redimg, + const unsigned char *greenimg, + const unsigned char *blueimg, + int ncols, + int nrows) +{ + int i, j; + + /* Write header */ + fprintf(fp, "P6\n"); + fprintf(fp, "%d %d\n", ncols, nrows); + fprintf(fp, "255\n"); + + /* Write binary data */ + for (j = 0 ; j < nrows ; j++) { + for (i = 0 ; i < ncols ; i++) { + fwrite(redimg, 1, 1, fp); + fwrite(greenimg, 1, 1, fp); + fwrite(blueimg, 1, 1, fp); + redimg++; greenimg++; blueimg++; + } + } +} + + +/********************************************************************* + * ppmWriteFileRGB + */ + +void ppmWriteFileRGB( + const char *fname, + const unsigned char *redimg, + const unsigned char *greenimg, + const unsigned char *blueimg, + int ncols, + int nrows) +{ + FILE *fp; + + /* Open file */ + if ( (fp = fopen(fname, "wb")) == NULL) { + KLTError("(ppmWriteFileRGB) Can't open file named '%s' for writing\n", fname); + exit(1); + } + + /* Write to file */ + ppmWrite(fp, redimg, greenimg, blueimg, ncols, nrows); + + /* Close file */ + fclose(fp); +} + + diff --git a/rtengine/klt/pnmio.h b/rtengine/klt/pnmio.h new file mode 100644 index 000000000..9cf8ded95 --- /dev/null +++ b/rtengine/klt/pnmio.h @@ -0,0 +1,56 @@ +/********************************************************************* + * pnmio.h + *********************************************************************/ + +#ifndef _PNMIO_H_ +#define _PNMIO_H_ + +#include + +/********** + * With pgmReadFile and pgmRead, setting img to NULL causes memory + * to be allocated + */ + +/********** + * used for reading from/writing to files + */ +unsigned char* pgmReadFile( + const char *fname, + unsigned char *img, + int *ncols, + int *nrows); +void pgmWriteFile( + const char *fname, + const unsigned char *img, + int ncols, + int nrows); +void ppmWriteFileRGB( + const char *fname, + const unsigned char *redimg, + const unsigned char *greenimg, + const unsigned char *blueimg, + int ncols, + int nrows); + +/********** + * used for communicating with stdin and stdout + */ +unsigned char* pgmRead( + FILE *fp, + unsigned char *img, + int *ncols, int *nrows); +void pgmWrite( + FILE *fp, + const unsigned char *img, + int ncols, + int nrows); +void ppmWrite( + FILE *fp, + const unsigned char *redimg, + const unsigned char *greenimg, + const unsigned char *blueimg, + int ncols, + int nrows); + +#endif diff --git a/rtengine/klt/pyramid.cc b/rtengine/klt/pyramid.cc new file mode 100644 index 000000000..e8b9f47ec --- /dev/null +++ b/rtengine/klt/pyramid.cc @@ -0,0 +1,149 @@ +/********************************************************************* + * pyramid.c + * + *********************************************************************/ + +/* Standard includes */ +#include +#include /* malloc() ? */ +#include /* memset() ? */ +#include /* */ + +/* Our includes */ +#include "base.h" +#include "error.h" +#include "convolve.h" /* for computing pyramid */ +#include "pyramid.h" + + +/********************************************************************* + * + */ + +_KLT_Pyramid _KLTCreatePyramid( + int ncols, + int nrows, + int subsampling, + int nlevels) +{ + _KLT_Pyramid pyramid; + int nbytes = sizeof(_KLT_PyramidRec) + + nlevels * sizeof(_KLT_FloatImage *) + + nlevels * sizeof(int) + + nlevels * sizeof(int); + int i; + + if (subsampling != 2 && subsampling != 4 && + subsampling != 8 && subsampling != 16 && subsampling != 32) { + KLTError("(_KLTCreatePyramid) Pyramid's subsampling must " + "be either 2, 4, 8, 16, or 32"); + exit(1); + } + + + /* Allocate memory for structure and set parameters */ + pyramid = (_KLT_Pyramid) malloc(nbytes); + if (pyramid == NULL) { + KLTError("(_KLTCreatePyramid) Out of memory"); + exit(1); + } + + /* Set parameters */ + pyramid->subsampling = subsampling; + pyramid->nLevels = nlevels; + pyramid->img = (_KLT_FloatImage *) (pyramid + 1); + pyramid->ncols = (int *) (pyramid->img + nlevels); + pyramid->nrows = (int *) (pyramid->ncols + nlevels); + + /* Allocate memory for each level of pyramid and assign pointers */ + for (i = 0 ; i < nlevels ; i++) { + pyramid->img[i] = _KLTCreateFloatImage(ncols, nrows); + pyramid->ncols[i] = ncols; pyramid->nrows[i] = nrows; + ncols /= subsampling; nrows /= subsampling; + } + + return pyramid; +} + + +/********************************************************************* + * + */ + +void _KLTFreePyramid( + _KLT_Pyramid pyramid) +{ + int i; + + /* Free images */ + for (i = 0 ; i < pyramid->nLevels ; i++) + _KLTFreeFloatImage(pyramid->img[i]); + + /* Free structure */ + free(pyramid); +} + + +/********************************************************************* + * + */ + +void _KLTComputePyramid( + _KLT_FloatImage img, + _KLT_Pyramid pyramid, + float sigma_fact) +{ + _KLT_FloatImage currimg, tmpimg; + int ncols = img->ncols, nrows = img->nrows; + int subsampling = pyramid->subsampling; + int subhalf = subsampling / 2; + float sigma = subsampling * sigma_fact; /* empirically determined */ + int oldncols; + int i, x, y; + + if (subsampling != 2 && subsampling != 4 && + subsampling != 8 && subsampling != 16 && subsampling != 32) { + KLTError("(_KLTComputePyramid) Pyramid's subsampling must " + "be either 2, 4, 8, 16, or 32"); + exit(1); + } + + assert(pyramid->ncols[0] == img->ncols); + assert(pyramid->nrows[0] == img->nrows); + + /* Copy original image to level 0 of pyramid */ + memcpy(pyramid->img[0]->data, img->data, ncols*nrows*sizeof(float)); + + currimg = img; + for (i = 1 ; i < pyramid->nLevels ; i++) { + tmpimg = _KLTCreateFloatImage(ncols, nrows); + _KLTComputeSmoothedImage(currimg, sigma, tmpimg); + + + /* Subsample */ + oldncols = ncols; + ncols /= subsampling; nrows /= subsampling; + for (y = 0 ; y < nrows ; y++) + for (x = 0 ; x < ncols ; x++) + pyramid->img[i]->data[y*ncols+x] = + tmpimg->data[(subsampling*y+subhalf)*oldncols + + (subsampling*x+subhalf)]; + + /* Reassign current image */ + currimg = pyramid->img[i]; + + _KLTFreeFloatImage(tmpimg); + } +} + + + + + + + + + + + + diff --git a/rtengine/klt/pyramid.h b/rtengine/klt/pyramid.h new file mode 100644 index 000000000..eca9e6692 --- /dev/null +++ b/rtengine/klt/pyramid.h @@ -0,0 +1,32 @@ +/********************************************************************* + * pyramid.h + *********************************************************************/ + +#ifndef _PYRAMID_H_ +#define _PYRAMID_H_ + +#include "klt_util.h" + +typedef struct { + int subsampling; + int nLevels; + _KLT_FloatImage *img; + int *ncols, *nrows; +} _KLT_PyramidRec, *_KLT_Pyramid; + + +_KLT_Pyramid _KLTCreatePyramid( + int ncols, + int nrows, + int subsampling, + int nlevels); + +void _KLTComputePyramid( + _KLT_FloatImage floatimg, + _KLT_Pyramid pyramid, + float sigma_fact); + +void _KLTFreePyramid( + _KLT_Pyramid pyramid); + +#endif diff --git a/rtengine/klt/selectGoodFeatures.cc b/rtengine/klt/selectGoodFeatures.cc new file mode 100644 index 000000000..176057f39 --- /dev/null +++ b/rtengine/klt/selectGoodFeatures.cc @@ -0,0 +1,542 @@ +/********************************************************************* + * selectGoodFeatures.c + * + *********************************************************************/ + +/* Standard includes */ +#include +#include /* malloc(), qsort() */ +#include /* fflush() */ +#include /* memset() */ +#include /* fsqrt() */ +#define fsqrt(X) sqrt(X) + +/* Our includes */ +#include "base.h" +#include "error.h" +#include "convolve.h" +#include "klt.h" +#include "klt_util.h" +#include "pyramid.h" + +int KLT_verbose = 1; + +typedef enum {SELECTING_ALL, REPLACING_SOME} selectionMode; + + +/********************************************************************* + * _quicksort + * Replacement for qsort(). Computing time is decreased by taking + * advantage of specific knowledge of our array (that there are + * three ints associated with each point). + * + * This routine generously provided by + * Manolis Lourakis + * + * NOTE: The results of this function may be slightly different from + * those of qsort(). This is due to the fact that different sort + * algorithms have different behaviours when sorting numbers with the + * same value: Some leave them in the same relative positions in the + * array, while others change their relative positions. For example, + * if you have the array [c d b1 a b2] with b1=b2, it may be sorted as + * [a b1 b2 c d] or [a b2 b1 c d]. + */ + +#define SWAP3(list, i, j) \ +{ int *pi, *pj, tmp; \ + pi=list+3*(i); pj=list+3*(j); \ + \ + tmp=*pi; \ + *pi++=*pj; \ + *pj++=tmp; \ + \ + tmp=*pi; \ + *pi++=*pj; \ + *pj++=tmp; \ + \ + tmp=*pi; \ + *pi=*pj; \ + *pj=tmp; \ +} + +void _quicksort(int *pointlist, int n) +{ + unsigned int i, j, ln, rn; + + while (n > 1) + { + SWAP3(pointlist, 0, n/2); + for (i = 0, j = n; ; ) + { + do + --j; + while (pointlist[3*j+2] < pointlist[2]); + do + ++i; + while (i < j && pointlist[3*i+2] > pointlist[2]); + if (i >= j) + break; + SWAP3(pointlist, i, j); + } + SWAP3(pointlist, j, 0); + ln = j; + rn = n - ++j; + if (ln < rn) + { + _quicksort(pointlist, ln); + pointlist += 3*j; + n = rn; + } + else + { + _quicksort(pointlist + 3*j, rn); + n = ln; + } + } +} +#undef SWAP3 + + +/*********************************************************************/ + +static void _fillFeaturemap( + int x, int y, + uchar *featuremap, + int mindist, + int ncols, + int nrows) +{ + int ix, iy; + + for (iy = y - mindist ; iy <= y + mindist ; iy++) + for (ix = x - mindist ; ix <= x + mindist ; ix++) + if (ix >= 0 && ix < ncols && iy >= 0 && iy < nrows) + featuremap[iy*ncols+ix] = 1; +} + + +/********************************************************************* + * _enforceMinimumDistance + * + * Removes features that are within close proximity to better features. + * + * INPUTS + * featurelist: A list of features. The nFeatures property + * is used. + * + * OUTPUTS + * featurelist: Is overwritten. Nearby "redundant" features are removed. + * Writes -1's into the remaining elements. + * + * RETURNS + * The number of remaining features. + */ + +static void _enforceMinimumDistance( + int *pointlist, /* featurepoints */ + int npoints, /* number of featurepoints */ + KLT_FeatureList featurelist, /* features */ + int ncols, int nrows, /* size of images */ + int mindist, /* min. dist b/w features */ + int min_eigenvalue, /* min. eigenvalue */ + KLT_BOOL overwriteAllFeatures) +{ + int indx; /* Index into features */ + int x, y, val; /* Location and trackability of pixel under consideration */ + uchar *featuremap; /* Boolean array recording proximity of features */ + int *ptr; + + /* Cannot add features with an eigenvalue less than one */ + if (min_eigenvalue < 1) min_eigenvalue = 1; + + /* Allocate memory for feature map and clear it */ + featuremap = (uchar *) malloc(ncols * nrows * sizeof(uchar)); + memset(featuremap, 0, ncols*nrows); + + /* Necessary because code below works with (mindist-1) */ + mindist--; + + /* If we are keeping all old good features, then add them to the featuremap */ + if (!overwriteAllFeatures) + for (indx = 0 ; indx < featurelist->nFeatures ; indx++) + if (featurelist->feature[indx]->val >= 0) { + x = (int) featurelist->feature[indx]->x; + y = (int) featurelist->feature[indx]->y; + _fillFeaturemap(x, y, featuremap, mindist, ncols, nrows); + } + + /* For each feature point, in descending order of importance, do ... */ + ptr = pointlist; + indx = 0; + while (1) { + + /* If we can't add all the points, then fill in the rest + of the featurelist with -1's */ + if (ptr >= pointlist + 3*npoints) { + while (indx < featurelist->nFeatures) { + if (overwriteAllFeatures || + featurelist->feature[indx]->val < 0) { + featurelist->feature[indx]->x = -1; + featurelist->feature[indx]->y = -1; + featurelist->feature[indx]->val = KLT_NOT_FOUND; + featurelist->feature[indx]->aff_img = NULL; + featurelist->feature[indx]->aff_img_gradx = NULL; + featurelist->feature[indx]->aff_img_grady = NULL; + featurelist->feature[indx]->aff_x = -1.0; + featurelist->feature[indx]->aff_y = -1.0; + featurelist->feature[indx]->aff_Axx = 1.0; + featurelist->feature[indx]->aff_Ayx = 0.0; + featurelist->feature[indx]->aff_Axy = 0.0; + featurelist->feature[indx]->aff_Ayy = 1.0; + } + indx++; + } + break; + } + + x = *ptr++; + y = *ptr++; + val = *ptr++; + + /* Ensure that feature is in-bounds */ + assert(x >= 0); + assert(x < ncols); + assert(y >= 0); + assert(y < nrows); + + while (!overwriteAllFeatures && + indx < featurelist->nFeatures && + featurelist->feature[indx]->val >= 0) + indx++; + + if (indx >= featurelist->nFeatures) break; + + /* If no neighbor has been selected, and if the minimum + eigenvalue is large enough, then add feature to the current list */ + if (!featuremap[y*ncols+x] && val >= min_eigenvalue) { + featurelist->feature[indx]->x = (KLT_locType) x; + featurelist->feature[indx]->y = (KLT_locType) y; + featurelist->feature[indx]->val = (int) val; + featurelist->feature[indx]->aff_img = NULL; + featurelist->feature[indx]->aff_img_gradx = NULL; + featurelist->feature[indx]->aff_img_grady = NULL; + featurelist->feature[indx]->aff_x = -1.0; + featurelist->feature[indx]->aff_y = -1.0; + featurelist->feature[indx]->aff_Axx = 1.0; + featurelist->feature[indx]->aff_Ayx = 0.0; + featurelist->feature[indx]->aff_Axy = 0.0; + featurelist->feature[indx]->aff_Ayy = 1.0; + indx++; + + /* Fill in surrounding region of feature map, but + make sure that pixels are in-bounds */ + _fillFeaturemap(x, y, featuremap, mindist, ncols, nrows); + } + } + + /* Free feature map */ + free(featuremap); +} + + +/********************************************************************* + * _comparePoints + * + * Used by qsort (in _KLTSelectGoodFeatures) to determine + * which feature is better. + * By switching the '>' with the '<', qsort is fooled into sorting + * in descending order. + */ + +#ifdef KLT_USE_QSORT +static int _comparePoints(const void *a, const void *b) +{ + int v1 = *(((int *) a) + 2); + int v2 = *(((int *) b) + 2); + + if (v1 > v2) return(-1); + else if (v1 < v2) return(1); + else return(0); +} +#endif + + +/********************************************************************* + * _sortPointList + */ + +static void _sortPointList( + int *pointlist, + int npoints) +{ +#ifdef KLT_USE_QSORT + qsort(pointlist, npoints, 3*sizeof(int), _comparePoints); +#else + _quicksort(pointlist, npoints); +#endif +} + + +/********************************************************************* + * _minEigenvalue + * + * Given the three distinct elements of the symmetric 2x2 matrix + * [gxx gxy] + * [gxy gyy], + * Returns the minimum eigenvalue of the matrix. + */ + +static float _minEigenvalue(float gxx, float gxy, float gyy) +{ + return (float) ((gxx + gyy - sqrt((gxx - gyy)*(gxx - gyy) + 4*gxy*gxy))/2.0f); +} + + +/*********************************************************************/ + +void _KLTSelectGoodFeatures( + KLT_TrackingContext tc, + KLT_PixelType *img, + int ncols, + int nrows, + KLT_FeatureList featurelist, + selectionMode mode) +{ + _KLT_FloatImage floatimg, gradx, grady; + int window_hw, window_hh; + int *pointlist; + int npoints = 0; + KLT_BOOL overwriteAllFeatures = (mode == SELECTING_ALL) ? + TRUE : FALSE; + KLT_BOOL floatimages_created = FALSE; + + /* Check window size (and correct if necessary) */ + if (tc->window_width % 2 != 1) { + tc->window_width = tc->window_width+1; + KLTWarning("Tracking context's window width must be odd. " + "Changing to %d.\n", tc->window_width); + } + if (tc->window_height % 2 != 1) { + tc->window_height = tc->window_height+1; + KLTWarning("Tracking context's window height must be odd. " + "Changing to %d.\n", tc->window_height); + } + if (tc->window_width < 3) { + tc->window_width = 3; + KLTWarning("Tracking context's window width must be at least three. \n" + "Changing to %d.\n", tc->window_width); + } + if (tc->window_height < 3) { + tc->window_height = 3; + KLTWarning("Tracking context's window height must be at least three. \n" + "Changing to %d.\n", tc->window_height); + } + window_hw = tc->window_width/2; + window_hh = tc->window_height/2; + + /* Create pointlist, which is a simplified version of a featurelist, */ + /* for speed. Contains only integer locations and values. */ + pointlist = (int *) malloc(ncols * nrows * 3 * sizeof(int)); + + /* Create temporary images, etc. */ + if (mode == REPLACING_SOME && + tc->sequentialMode && tc->pyramid_last != NULL) { + floatimg = ((_KLT_Pyramid) tc->pyramid_last)->img[0]; + gradx = ((_KLT_Pyramid) tc->pyramid_last_gradx)->img[0]; + grady = ((_KLT_Pyramid) tc->pyramid_last_grady)->img[0]; + assert(gradx != NULL); + assert(grady != NULL); + } else { + floatimages_created = TRUE; + floatimg = _KLTCreateFloatImage(ncols, nrows); + gradx = _KLTCreateFloatImage(ncols, nrows); + grady = _KLTCreateFloatImage(ncols, nrows); + if (tc->smoothBeforeSelecting) { + _KLT_FloatImage tmpimg; + tmpimg = _KLTCreateFloatImage(ncols, nrows); + _KLTToFloatImage(img, ncols, nrows, tmpimg); + _KLTComputeSmoothedImage(tmpimg, _KLTComputeSmoothSigma(tc), floatimg); + _KLTFreeFloatImage(tmpimg); + } else _KLTToFloatImage(img, ncols, nrows, floatimg); + + /* Compute gradient of image in x and y direction */ + _KLTComputeGradients(floatimg, tc->grad_sigma, gradx, grady); + } + + /* Write internal images */ + if (tc->writeInternalImages) { + _KLTWriteFloatImageToPGM(floatimg, "kltimg_sgfrlf.pgm"); + _KLTWriteFloatImageToPGM(gradx, "kltimg_sgfrlf_gx.pgm"); + _KLTWriteFloatImageToPGM(grady, "kltimg_sgfrlf_gy.pgm"); + } + + /* Compute trackability of each image pixel as the minimum + of the two eigenvalues of the Z matrix */ + { + float gx, gy; + float gxx, gxy, gyy; + int xx, yy; + int *ptr; + float val; + unsigned int limit = 1; + int borderx = tc->borderx; /* Must not touch cols */ + int bordery = tc->bordery; /* lost by convolution */ + int x, y; + + if (borderx < window_hw) borderx = window_hw; + if (bordery < window_hh) bordery = window_hh; + + /* Find largest value of an int */ + for (size_t i = 0 ; i < sizeof(int) ; i++) limit *= 256; + limit = limit/2 - 1; + + /* For most of the pixels in the image, do ... */ + ptr = pointlist; + for (y = bordery ; y < nrows - bordery ; y += tc->nSkippedPixels + 1) + for (x = borderx ; x < ncols - borderx ; x += tc->nSkippedPixels + 1) { + + /* Sum the gradients in the surrounding window */ + gxx = 0; gxy = 0; gyy = 0; + for (yy = y-window_hh ; yy <= y+window_hh ; yy++) + for (xx = x-window_hw ; xx <= x+window_hw ; xx++) { + gx = *(gradx->data + ncols*yy+xx); + gy = *(grady->data + ncols*yy+xx); + gxx += gx * gx; + gxy += gx * gy; + gyy += gy * gy; + } + + /* Store the trackability of the pixel as the minimum + of the two eigenvalues */ + *ptr++ = x; + *ptr++ = y; + val = _minEigenvalue(gxx, gxy, gyy); + if (val > limit) { + KLTWarning("(_KLTSelectGoodFeatures) minimum eigenvalue %f is " + "greater than the capacity of an int; setting " + "to maximum value", val); + val = (float) limit; + } + *ptr++ = (int) val; + npoints++; + } + } + + /* Sort the features */ + _sortPointList(pointlist, npoints); + + /* Check tc->mindist */ + if (tc->mindist < 0) { + KLTWarning("(_KLTSelectGoodFeatures) Tracking context field tc->mindist " + "is negative (%d); setting to zero", tc->mindist); + tc->mindist = 0; + } + + /* Enforce minimum distance between features */ + _enforceMinimumDistance( + pointlist, + npoints, + featurelist, + ncols, nrows, + tc->mindist, + tc->min_eigenvalue, + overwriteAllFeatures); + + /* Free memory */ + free(pointlist); + if (floatimages_created) { + _KLTFreeFloatImage(floatimg); + _KLTFreeFloatImage(gradx); + _KLTFreeFloatImage(grady); + } +} + + +/********************************************************************* + * KLTSelectGoodFeatures + * + * Main routine, visible to the outside. Finds the good features in + * an image. + * + * INPUTS + * tc: Contains parameters used in computation (size of image, + * size of window, min distance b/w features, sigma to compute + * image gradients, # of features desired). + * img: Pointer to the data of an image (probably unsigned chars). + * + * OUTPUTS + * features: List of features. The member nFeatures is computed. + */ + +void KLTSelectGoodFeatures( + KLT_TrackingContext tc, + KLT_PixelType *img, + int ncols, + int nrows, + KLT_FeatureList fl) +{ + if (KLT_verbose >= 1) { + fprintf(stderr, "(KLT) Selecting the %d best features " + "from a %d by %d image... ", fl->nFeatures, ncols, nrows); + fflush(stderr); + } + + _KLTSelectGoodFeatures(tc, img, ncols, nrows, + fl, SELECTING_ALL); + + if (KLT_verbose >= 1) { + fprintf(stderr, "\n\t%d features found.\n", + KLTCountRemainingFeatures(fl)); + if (tc->writeInternalImages) + fprintf(stderr, "\tWrote images to 'kltimg_sgfrlf*.pgm'.\n"); + fflush(stderr); + } +} + + +/********************************************************************* + * KLTReplaceLostFeatures + * + * Main routine, visible to the outside. Replaces the lost features + * in an image. + * + * INPUTS + * tc: Contains parameters used in computation (size of image, + * size of window, min distance b/w features, sigma to compute + * image gradients, # of features desired). + * img: Pointer to the data of an image (probably unsigned chars). + * + * OUTPUTS + * features: List of features. The member nFeatures is computed. + */ + +void KLTReplaceLostFeatures( + KLT_TrackingContext tc, + KLT_PixelType *img, + int ncols, + int nrows, + KLT_FeatureList fl) +{ + int nLostFeatures = fl->nFeatures - KLTCountRemainingFeatures(fl); + + if (KLT_verbose >= 1) { + fprintf(stderr, "(KLT) Attempting to replace %d features " + "in a %d by %d image... ", nLostFeatures, ncols, nrows); + fflush(stderr); + } + + /* If there are any lost features, replace them */ + if (nLostFeatures > 0) + _KLTSelectGoodFeatures(tc, img, ncols, nrows, + fl, REPLACING_SOME); + + if (KLT_verbose >= 1) { + fprintf(stderr, "\n\t%d features replaced.\n", + nLostFeatures - fl->nFeatures + KLTCountRemainingFeatures(fl)); + if (tc->writeInternalImages) + fprintf(stderr, "\tWrote images to 'kltimg_sgfrlf*.pgm'.\n"); + fflush(stderr); + } +} + + diff --git a/rtengine/klt/speed.txt b/rtengine/klt/speed.txt new file mode 100644 index 000000000..08e20e59e --- /dev/null +++ b/rtengine/klt/speed.txt @@ -0,0 +1,12 @@ +======================================================================= +speed of KLT versus OpenCV feature tracker on a 2.8 GHz P4 computer: + + KLT OpenCV +--------------------------------------------- +track (100) 54 ms 47 ms +track/replace (100) 95 ms 82 ms +track (1000) 79 ms 59 ms +track/replace (1000) 139 ms 103 ms + +The number of features is given in parentheses. These times were computed by running the code on the same image multiple times in succession, then averaging. As a result, they may not reflect the overhead of loading the image and cache misses that would occur in a real scenario. +======================================================================= diff --git a/rtengine/klt/storeFeatures.cc b/rtengine/klt/storeFeatures.cc new file mode 100644 index 000000000..149cc90d4 --- /dev/null +++ b/rtengine/klt/storeFeatures.cc @@ -0,0 +1,135 @@ +/********************************************************************* + * storeFeatures.c + * + *********************************************************************/ + +#include + +/* Our includes */ +#include "error.h" +#include "klt.h" + + +/********************************************************************* + * + */ + +void KLTStoreFeatureList( + KLT_FeatureList fl, + KLT_FeatureTable ft, + int frame) +{ + int feat; + + if (frame < 0 || frame >= ft->nFrames) { + KLTError("(KLTStoreFeatures) Frame number %d is not between 0 and %d", + frame, ft->nFrames - 1); + exit(1); + } + + if (fl->nFeatures != ft->nFeatures) { + KLTError("(KLTStoreFeatures) FeatureList and FeatureTable must " + "have the same number of features"); + exit(1); + } + + for (feat = 0 ; feat < fl->nFeatures ; feat++) { + ft->feature[feat][frame]->x = fl->feature[feat]->x; + ft->feature[feat][frame]->y = fl->feature[feat]->y; + ft->feature[feat][frame]->val = fl->feature[feat]->val; + } +} + + +/********************************************************************* + * + */ + +void KLTExtractFeatureList( + KLT_FeatureList fl, + KLT_FeatureTable ft, + int frame) +{ + int feat; + + if (frame < 0 || frame >= ft->nFrames) { + KLTError("(KLTExtractFeatures) Frame number %d is not between 0 and %d", + frame, ft->nFrames - 1); + exit(1); + } + + if (fl->nFeatures != ft->nFeatures) { + KLTError("(KLTExtractFeatures) FeatureList and FeatureTable must " + "have the same number of features"); + exit(1); + } + + for (feat = 0 ; feat < fl->nFeatures ; feat++) { + fl->feature[feat]->x = ft->feature[feat][frame]->x; + fl->feature[feat]->y = ft->feature[feat][frame]->y; + fl->feature[feat]->val = ft->feature[feat][frame]->val; + } +} + + +/********************************************************************* + * + */ + +void KLTStoreFeatureHistory( + KLT_FeatureHistory fh, + KLT_FeatureTable ft, + int feat) +{ + int frame; + + if (feat < 0 || feat >= ft->nFeatures) { + KLTError("(KLTStoreFeatureHistory) Feature number %d is not between 0 and %d", + feat, ft->nFeatures - 1); + exit(1); + } + + if (fh->nFrames != ft->nFrames) { + KLTError("(KLTStoreFeatureHistory) FeatureHistory and FeatureTable must " + "have the same number of frames"); + exit(1); + } + + for (frame = 0 ; frame < fh->nFrames ; frame++) { + ft->feature[feat][frame]->x = fh->feature[frame]->x; + ft->feature[feat][frame]->y = fh->feature[frame]->y; + ft->feature[feat][frame]->val = fh->feature[frame]->val; + } +} + + +/********************************************************************* + * + */ + +void KLTExtractFeatureHistory( + KLT_FeatureHistory fh, + KLT_FeatureTable ft, + int feat) +{ + int frame; + + if (feat < 0 || feat >= ft->nFeatures) { + KLTError("(KLTExtractFeatureHistory) Feature number %d is not between 0 and %d", + feat, ft->nFeatures - 1); + exit(1); + } + + if (fh->nFrames != ft->nFrames) { + KLTError("(KLTExtractFeatureHistory) FeatureHistory and FeatureTable must " + "have the same number of frames"); + exit(1); + } + + for (frame = 0 ; frame < fh->nFrames ; frame++) { + fh->feature[frame]->x = ft->feature[feat][frame]->x; + fh->feature[frame]->y = ft->feature[feat][frame]->y; + fh->feature[frame]->val = ft->feature[feat][frame]->val; + } +} + diff --git a/rtengine/klt/trackFeatures.cc b/rtengine/klt/trackFeatures.cc new file mode 100644 index 000000000..2b6b81f5f --- /dev/null +++ b/rtengine/klt/trackFeatures.cc @@ -0,0 +1,1542 @@ +/********************************************************************* + * trackFeatures.c + * + *********************************************************************/ + +/* Standard includes */ +#include +#include /* fabs() */ +#include /* malloc() */ +#include /* fflush() */ + +/* Our includes */ +#include "base.h" +#include "error.h" +#include "convolve.h" /* for computing pyramid */ +#include "klt.h" +#include "klt_util.h" /* _KLT_FloatImage */ +#include "pyramid.h" /* _KLT_Pyramid */ + +extern int KLT_verbose; + +typedef float *_FloatWindow; + +/********************************************************************* + * _interpolate + * + * Given a point (x,y) in an image, computes the bilinear interpolated + * gray-level value of the point in the image. + */ + +static float _interpolate( + float x, + float y, + _KLT_FloatImage img) +{ + int xt = (int) x; /* coordinates of top-left corner */ + int yt = (int) y; + float ax = x - xt; + float ay = y - yt; + float *ptr = img->data + (img->ncols*yt) + xt; + +#ifndef _DNDEBUG + if (xt<0 || yt<0 || xt>=img->ncols-1 || yt>=img->nrows-1) { + fprintf(stderr, "(xt,yt)=(%d,%d) imgsize=(%d,%d)\n" + "(x,y)=(%f,%f) (ax,ay)=(%f,%f)\n", + xt, yt, img->ncols, img->nrows, x, y, ax, ay); + fflush(stderr); + } +#endif + + assert (xt >= 0 && yt >= 0 && xt <= img->ncols - 2 && yt <= img->nrows - 2); + + return ( (1-ax) * (1-ay) * *ptr + + ax * (1-ay) * *(ptr+1) + + (1-ax) * ay * *(ptr+(img->ncols)) + + ax * ay * *(ptr+(img->ncols)+1) ); +} + + +/********************************************************************* + * _computeIntensityDifference + * + * Given two images and the window center in both images, + * aligns the images wrt the window and computes the difference + * between the two overlaid images. + */ + +static void _computeIntensityDifference( + _KLT_FloatImage img1, /* images */ + _KLT_FloatImage img2, + float x1, float y1, /* center of window in 1st img */ + float x2, float y2, /* center of window in 2nd img */ + int width, int height, /* size of window */ + _FloatWindow imgdiff) /* output */ +{ + int hw = width/2, hh = height/2; + float g1, g2; + int i, j; + + /* Compute values */ + for (j = -hh ; j <= hh ; j++) + for (i = -hw ; i <= hw ; i++) { + g1 = _interpolate(x1+i, y1+j, img1); + g2 = _interpolate(x2+i, y2+j, img2); + *imgdiff++ = g1 - g2; + } +} + + +/********************************************************************* + * _computeGradientSum + * + * Given two gradients and the window center in both images, + * aligns the gradients wrt the window and computes the sum of the two + * overlaid gradients. + */ + +static void _computeGradientSum( + _KLT_FloatImage gradx1, /* gradient images */ + _KLT_FloatImage grady1, + _KLT_FloatImage gradx2, + _KLT_FloatImage grady2, + float x1, float y1, /* center of window in 1st img */ + float x2, float y2, /* center of window in 2nd img */ + int width, int height, /* size of window */ + _FloatWindow gradx, /* output */ + _FloatWindow grady) /* " */ +{ + int hw = width/2, hh = height/2; + float g1, g2; + int i, j; + + /* Compute values */ + for (j = -hh ; j <= hh ; j++) + for (i = -hw ; i <= hw ; i++) { + g1 = _interpolate(x1+i, y1+j, gradx1); + g2 = _interpolate(x2+i, y2+j, gradx2); + *gradx++ = g1 + g2; + g1 = _interpolate(x1+i, y1+j, grady1); + g2 = _interpolate(x2+i, y2+j, grady2); + *grady++ = g1 + g2; + } +} + +/********************************************************************* + * _computeIntensityDifferenceLightingInsensitive + * + * Given two images and the window center in both images, + * aligns the images wrt the window and computes the difference + * between the two overlaid images; normalizes for overall gain and bias. + */ + +static void _computeIntensityDifferenceLightingInsensitive( + _KLT_FloatImage img1, /* images */ + _KLT_FloatImage img2, + float x1, float y1, /* center of window in 1st img */ + float x2, float y2, /* center of window in 2nd img */ + int width, int height, /* size of window */ + _FloatWindow imgdiff) /* output */ +{ + int hw = width/2, hh = height/2; + float g1, g2, sum1_squared = 0, sum2_squared = 0; + int i, j; + + float sum1 = 0, sum2 = 0; + float mean1, mean2,alpha,belta; + /* Compute values */ + for (j = -hh ; j <= hh ; j++) + for (i = -hw ; i <= hw ; i++) { + g1 = _interpolate(x1+i, y1+j, img1); + g2 = _interpolate(x2+i, y2+j, img2); + sum1 += g1; sum2 += g2; + sum1_squared += g1*g1; + sum2_squared += g2*g2; + } + mean1=sum1_squared/(width*height); + mean2=sum2_squared/(width*height); + alpha = (float) sqrt(mean1/mean2); + mean1=sum1/(width*height); + mean2=sum2/(width*height); + belta = mean1-alpha*mean2; + + for (j = -hh ; j <= hh ; j++) + for (i = -hw ; i <= hw ; i++) { + g1 = _interpolate(x1+i, y1+j, img1); + g2 = _interpolate(x2+i, y2+j, img2); + *imgdiff++ = g1- g2*alpha-belta; + } +} + + +/********************************************************************* + * _computeGradientSumLightingInsensitive + * + * Given two gradients and the window center in both images, + * aligns the gradients wrt the window and computes the sum of the two + * overlaid gradients; normalizes for overall gain and bias. + */ + +static void _computeGradientSumLightingInsensitive( + _KLT_FloatImage gradx1, /* gradient images */ + _KLT_FloatImage grady1, + _KLT_FloatImage gradx2, + _KLT_FloatImage grady2, + _KLT_FloatImage img1, /* images */ + _KLT_FloatImage img2, + + float x1, float y1, /* center of window in 1st img */ + float x2, float y2, /* center of window in 2nd img */ + int width, int height, /* size of window */ + _FloatWindow gradx, /* output */ + _FloatWindow grady) /* " */ +{ + int hw = width/2, hh = height/2; + float g1, g2, sum1_squared = 0, sum2_squared = 0; + int i, j; + + float mean1, mean2, alpha; + for (j = -hh ; j <= hh ; j++) + for (i = -hw ; i <= hw ; i++) { + g1 = _interpolate(x1+i, y1+j, img1); + g2 = _interpolate(x2+i, y2+j, img2); + sum1_squared += g1; sum2_squared += g2; + } + mean1 = sum1_squared/(width*height); + mean2 = sum2_squared/(width*height); + alpha = (float) sqrt(mean1/mean2); + + /* Compute values */ + for (j = -hh ; j <= hh ; j++) + for (i = -hw ; i <= hw ; i++) { + g1 = _interpolate(x1+i, y1+j, gradx1); + g2 = _interpolate(x2+i, y2+j, gradx2); + *gradx++ = g1 + g2*alpha; + g1 = _interpolate(x1+i, y1+j, grady1); + g2 = _interpolate(x2+i, y2+j, grady2); + *grady++ = g1+ g2*alpha; + } +} + +/********************************************************************* + * _compute2by2GradientMatrix + * + */ + +static void _compute2by2GradientMatrix( + _FloatWindow gradx, + _FloatWindow grady, + int width, /* size of window */ + int height, + float *gxx, /* return values */ + float *gxy, + float *gyy) + +{ + float gx, gy; + int i; + + /* Compute values */ + *gxx = 0.0; *gxy = 0.0; *gyy = 0.0; + for (i = 0 ; i < width * height ; i++) { + gx = *gradx++; + gy = *grady++; + *gxx += gx*gx; + *gxy += gx*gy; + *gyy += gy*gy; + } +} + + +/********************************************************************* + * _compute2by1ErrorVector + * + */ + +static void _compute2by1ErrorVector( + _FloatWindow imgdiff, + _FloatWindow gradx, + _FloatWindow grady, + int width, /* size of window */ + int height, + float step_factor, /* 2.0 comes from equations, 1.0 seems to avoid overshooting */ + float *ex, /* return values */ + float *ey) +{ + float diff; + int i; + + /* Compute values */ + *ex = 0; *ey = 0; + for (i = 0 ; i < width * height ; i++) { + diff = *imgdiff++; + *ex += diff * (*gradx++); + *ey += diff * (*grady++); + } + *ex *= step_factor; + *ey *= step_factor; +} + + +/********************************************************************* + * _solveEquation + * + * Solves the 2x2 matrix equation + * [gxx gxy] [dx] = [ex] + * [gxy gyy] [dy] = [ey] + * for dx and dy. + * + * Returns KLT_TRACKED on success and KLT_SMALL_DET on failure + */ + +static int _solveEquation( + float gxx, float gxy, float gyy, + float ex, float ey, + float small, + float *dx, float *dy) +{ + float det = gxx*gyy - gxy*gxy; + + + if (det < small) return KLT_SMALL_DET; + + *dx = (gyy*ex - gxy*ey)/det; + *dy = (gxx*ey - gxy*ex)/det; + return KLT_TRACKED; +} + + +/********************************************************************* + * _allocateFloatWindow + */ + +static _FloatWindow _allocateFloatWindow( + int width, + int height) +{ + _FloatWindow fw; + + fw = (_FloatWindow) malloc(width*height*sizeof(float)); + if (fw == NULL) { + KLTError("(_allocateFloatWindow) Out of memory."); + exit(1); + } + return fw; +} + + +/********************************************************************* + * _printFloatWindow + * (for debugging purposes) + */ + +/* +static void _printFloatWindow( + _FloatWindow fw, + int width, + int height) +{ + int i, j; + + fprintf(stderr, "\n"); + for (i = 0 ; i < width ; i++) { + for (j = 0 ; j < height ; j++) { + fprintf(stderr, "%6.1f ", *fw++); + } + fprintf(stderr, "\n"); + } +} +*/ + + +/********************************************************************* + * _sumAbsFloatWindow + */ + +static float _sumAbsFloatWindow( + _FloatWindow fw, + int width, + int height) +{ + float sum = 0.0; + int w; + + for ( ; height > 0 ; height--) + for (w=0 ; w < width ; w++) + sum += (float) fabs(*fw++); + + return sum; +} + + +/********************************************************************* + * _trackFeature + * + * Tracks a feature point from one image to the next. + * + * RETURNS + * KLT_SMALL_DET if feature is lost, + * KLT_MAX_ITERATIONS if tracking stopped because iterations timed out, + * KLT_TRACKED otherwise. + */ + +static int _trackFeature( + float x1, /* location of window in first image */ + float y1, + float *x2, /* starting location of search in second image */ + float *y2, + _KLT_FloatImage img1, + _KLT_FloatImage gradx1, + _KLT_FloatImage grady1, + _KLT_FloatImage img2, + _KLT_FloatImage gradx2, + _KLT_FloatImage grady2, + int width, /* size of window */ + int height, + float step_factor, /* 2.0 comes from equations, 1.0 seems to avoid overshooting */ + int max_iterations, + float small, /* determinant threshold for declaring KLT_SMALL_DET */ + float th, /* displacement threshold for stopping */ + float max_residue, /* residue threshold for declaring KLT_LARGE_RESIDUE */ + int lighting_insensitive) /* whether to normalize for gain and bias */ +{ + _FloatWindow imgdiff, gradx, grady; + float gxx, gxy, gyy, ex, ey, dx, dy; + int iteration = 0; + int status; + int hw = width/2; + int hh = height/2; + int nc = img1->ncols; + int nr = img1->nrows; + float one_plus_eps = 1.001f; /* To prevent rounding errors */ + + + /* Allocate memory for windows */ + imgdiff = _allocateFloatWindow(width, height); + gradx = _allocateFloatWindow(width, height); + grady = _allocateFloatWindow(width, height); + + /* Iteratively update the window position */ + do { + + /* If out of bounds, exit loop */ + if ( x1-hw < 0.0f || nc-( x1+hw) < one_plus_eps || + *x2-hw < 0.0f || nc-(*x2+hw) < one_plus_eps || + y1-hh < 0.0f || nr-( y1+hh) < one_plus_eps || + *y2-hh < 0.0f || nr-(*y2+hh) < one_plus_eps) { + status = KLT_OOB; + break; + } + + /* Compute gradient and difference windows */ + if (lighting_insensitive) { + _computeIntensityDifferenceLightingInsensitive(img1, img2, x1, y1, *x2, *y2, + width, height, imgdiff); + _computeGradientSumLightingInsensitive(gradx1, grady1, gradx2, grady2, + img1, img2, x1, y1, *x2, *y2, width, height, gradx, grady); + } else { + _computeIntensityDifference(img1, img2, x1, y1, *x2, *y2, + width, height, imgdiff); + _computeGradientSum(gradx1, grady1, gradx2, grady2, + x1, y1, *x2, *y2, width, height, gradx, grady); + } + + + /* Use these windows to construct matrices */ + _compute2by2GradientMatrix(gradx, grady, width, height, + &gxx, &gxy, &gyy); + _compute2by1ErrorVector(imgdiff, gradx, grady, width, height, step_factor, + &ex, &ey); + + /* Using matrices, solve equation for new displacement */ + status = _solveEquation(gxx, gxy, gyy, ex, ey, small, &dx, &dy); + if (status == KLT_SMALL_DET) break; + + *x2 += dx; + *y2 += dy; + iteration++; + + } while ((fabs(dx)>=th || fabs(dy)>=th) && iteration < max_iterations); + + /* Check whether window is out of bounds */ + if (*x2-hw < 0.0f || nc-(*x2+hw) < one_plus_eps || + *y2-hh < 0.0f || nr-(*y2+hh) < one_plus_eps) + status = KLT_OOB; + + /* Check whether residue is too large */ + if (status == KLT_TRACKED) { + if (lighting_insensitive) + _computeIntensityDifferenceLightingInsensitive(img1, img2, x1, y1, *x2, *y2, + width, height, imgdiff); + else + _computeIntensityDifference(img1, img2, x1, y1, *x2, *y2, + width, height, imgdiff); + if (_sumAbsFloatWindow(imgdiff, width, height)/(width*height) > max_residue) + status = KLT_LARGE_RESIDUE; + } + + /* Free memory */ + free(imgdiff); free(gradx); free(grady); + + /* Return appropriate value */ + if (status == KLT_SMALL_DET) return KLT_SMALL_DET; + else if (status == KLT_OOB) return KLT_OOB; + else if (status == KLT_LARGE_RESIDUE) return KLT_LARGE_RESIDUE; + else if (iteration >= max_iterations) return KLT_MAX_ITERATIONS; + else return KLT_TRACKED; + +} + + +/*********************************************************************/ + +static KLT_BOOL _outOfBounds( + float x, + float y, + int ncols, + int nrows, + int borderx, + int bordery) +{ + return (x < borderx || x > ncols-1-borderx || + y < bordery || y > nrows-1-bordery ); +} + + + + +/********************************************************************** +* CONSISTENCY CHECK OF FEATURES BY AFFINE MAPPING (BEGIN) +* +* Created by: Thorsten Thormaehlen (University of Hannover) June 2004 +* thormae@tnt.uni-hannover.de +* +* Permission is granted to any individual or institution to use, copy, modify, +* and distribute this part of the software, provided that this complete authorship +* and permission notice is maintained, intact, in all copies. +* +* This software is provided "as is" without express or implied warranty. +* +* +* The following static functions are helpers for the affine mapping. +* They all start with "_am". +* There are also small changes in other files for the +* affine mapping these are all marked by "for affine mapping" +* +* Thanks to Kevin Koeser (koeser@mip.informatik.uni-kiel.de) for fixing a bug +*/ + +#define SWAP_ME(X,Y) {temp=(X);(X)=(Y);(Y)=temp;} + +static float **_am_matrix(long nr, long nc) +{ + float **m; + int a; + m = (float **) malloc((size_t)(nr*sizeof(float*))); + m[0] = (float *) malloc((size_t)((nr*nc)*sizeof(float))); + for(a = 1; a < nr; a++) m[a] = m[a-1]+nc; + return m; +} + +static void _am_free_matrix(float **m) +{ + free(m[0]); + free(m); +} + + +static int _am_gauss_jordan_elimination(float **a, int n, float **b, int m) +{ + /* re-implemented from Numerical Recipes in C */ + int *indxc,*indxr,*ipiv; + int i,j,k,l,ll; + float big,dum,pivinv,temp; + int col = 0; + int row = 0; + + indxc=(int *)malloc((size_t) (n*sizeof(int))); + indxr=(int *)malloc((size_t) (n*sizeof(int))); + ipiv=(int *)malloc((size_t) (n*sizeof(int))); + for (j=0;j= big) { + big= (float) fabs(a[j][k]); + row=j; + col=k; + } + } else if (ipiv[k] > 1) { + free(ipiv); free(indxr); free(indxc); return KLT_SMALL_DET; + } + } + ++(ipiv[col]); + if (row != col) { + for (l=0;l=0;l--) { + if (indxr[l] != indxc[l]) + for (k=0;kncols/2, hh = window->nrows/2; + int x0 = (int) x; + int y0 = (int) y; + float * windata = window->data; + int offset; + int i, j; + + assert(x0 - hw >= 0); + assert(y0 - hh >= 0); + assert(x0 + hw <= img->ncols); + assert(y0 + hh <= img->nrows); + + /* copy values */ + for (j = -hh ; j <= hh ; j++) + for (i = -hw ; i <= hw ; i++) { + offset = (j+y0)*img->ncols + (i+x0); + *windata++ = *(img->data+offset); + } +} + +/********************************************************************* + * _am_computeIntensityDifferenceAffine + * + * Given two images and the window center in both images, + * aligns the images with the window and computes the difference + * between the two overlaid images using the affine mapping. + * A = [ Axx Axy] + * [ Ayx Ayy] +*/ + +static void _am_computeIntensityDifferenceAffine( + _KLT_FloatImage img1, /* images */ + _KLT_FloatImage img2, + float x1, float y1, /* center of window in 1st img */ + float x2, float y2, /* center of window in 2nd img */ + float Axx, float Ayx , float Axy, float Ayy, /* affine mapping */ + int width, int height, /* size of window */ + _FloatWindow imgdiff) /* output */ +{ + int hw = width/2, hh = height/2; + float g1, g2; + int i, j; + float mi, mj; + + /* Compute values */ + for (j = -hh ; j <= hh ; j++) + for (i = -hw ; i <= hw ; i++) { + g1 = _interpolate(x1+i, y1+j, img1); + mi = Axx * i + Axy * j; + mj = Ayx * i + Ayy * j; + g2 = _interpolate(x2+mi, y2+mj, img2); + *imgdiff++ = g1 - g2; + } +} + +/********************************************************************* + * _am_compute6by6GradientMatrix + * + */ + +static void _am_compute6by6GradientMatrix( + _FloatWindow gradx, + _FloatWindow grady, + int width, /* size of window */ + int height, + float **T) /* return values */ +{ + int hw = width/2, hh = height/2; + int i, j; + float gx, gy, gxx, gxy, gyy, x, y, xx, xy, yy; + + + /* Set values to zero */ + for (j = 0 ; j < 6 ; j++) { + for (i = j ; i < 6 ; i++) { + T[j][i] = 0.0; + } + } + + for (j = -hh ; j <= hh ; j++) { + for (i = -hw ; i <= hw ; i++) { + gx = *gradx++; + gy = *grady++; + gxx = gx * gx; + gxy = gx * gy; + gyy = gy * gy; + x = (float) i; + y = (float) j; + xx = x * x; + xy = x * y; + yy = y * y; + + T[0][0] += xx * gxx; + T[0][1] += xx * gxy; + T[0][2] += xy * gxx; + T[0][3] += xy * gxy; + T[0][4] += x * gxx; + T[0][5] += x * gxy; + + T[1][1] += xx * gyy; + T[1][2] += xy * gxy; + T[1][3] += xy * gyy; + T[1][4] += x * gxy; + T[1][5] += x * gyy; + + T[2][2] += yy * gxx; + T[2][3] += yy * gxy; + T[2][4] += y * gxx; + T[2][5] += y * gxy; + + T[3][3] += yy * gyy; + T[3][4] += y * gxy; + T[3][5] += y * gyy; + + T[4][4] += gxx; + T[4][5] += gxy; + + T[5][5] += gyy; + } + } + + for (j = 0 ; j < 5 ; j++) { + for (i = j+1 ; i < 6 ; i++) { + T[i][j] = T[j][i]; + } + } + +} + + + +/********************************************************************* + * _am_compute6by1ErrorVector + * + */ + +static void _am_compute6by1ErrorVector( + _FloatWindow imgdiff, + _FloatWindow gradx, + _FloatWindow grady, + int width, /* size of window */ + int height, + float **e) /* return values */ +{ + int hw = width/2, hh = height/2; + int i, j; + float diff, diffgradx, diffgrady; + + /* Set values to zero */ + for(i = 0; i < 6; i++) e[i][0] = 0.0; + + /* Compute values */ + for (j = -hh ; j <= hh ; j++) { + for (i = -hw ; i <= hw ; i++) { + diff = *imgdiff++; + diffgradx = diff * (*gradx++); + diffgrady = diff * (*grady++); + e[0][0] += diffgradx * i; + e[1][0] += diffgrady * i; + e[2][0] += diffgradx * j; + e[3][0] += diffgrady * j; + e[4][0] += diffgradx; + e[5][0] += diffgrady; + } + } + + for(i = 0; i < 6; i++) e[i][0] *= 0.5; + +} + + +/********************************************************************* + * _am_compute4by4GradientMatrix + * + */ + +static void _am_compute4by4GradientMatrix( + _FloatWindow gradx, + _FloatWindow grady, + int width, /* size of window */ + int height, + float **T) /* return values */ +{ + int hw = width/2, hh = height/2; + int i, j; + float gx, gy, x, y; + + + /* Set values to zero */ + for (j = 0 ; j < 4 ; j++) { + for (i = 0 ; i < 4 ; i++) { + T[j][i] = 0.0; + } + } + + for (j = -hh ; j <= hh ; j++) { + for (i = -hw ; i <= hw ; i++) { + gx = *gradx++; + gy = *grady++; + x = (float) i; + y = (float) j; + T[0][0] += (x*gx+y*gy) * (x*gx+y*gy); + T[0][1] += (x*gx+y*gy)*(x*gy-y*gx); + T[0][2] += (x*gx+y*gy)*gx; + T[0][3] += (x*gx+y*gy)*gy; + + T[1][1] += (x*gy-y*gx) * (x*gy-y*gx); + T[1][2] += (x*gy-y*gx)*gx; + T[1][3] += (x*gy-y*gx)*gy; + + T[2][2] += gx*gx; + T[2][3] += gx*gy; + + T[3][3] += gy*gy; + } + } + + for (j = 0 ; j < 3 ; j++) { + for (i = j+1 ; i < 4 ; i++) { + T[i][j] = T[j][i]; + } + } + +} + +/********************************************************************* + * _am_compute4by1ErrorVector + * + */ + +static void _am_compute4by1ErrorVector( + _FloatWindow imgdiff, + _FloatWindow gradx, + _FloatWindow grady, + int width, /* size of window */ + int height, + float **e) /* return values */ +{ + int hw = width/2, hh = height/2; + int i, j; + float diff, diffgradx, diffgrady; + + /* Set values to zero */ + for(i = 0; i < 4; i++) e[i][0] = 0.0; + + /* Compute values */ + for (j = -hh ; j <= hh ; j++) { + for (i = -hw ; i <= hw ; i++) { + diff = *imgdiff++; + diffgradx = diff * (*gradx++); + diffgrady = diff * (*grady++); + e[0][0] += diffgradx * i + diffgrady * j; + e[1][0] += diffgrady * i - diffgradx * j; + e[2][0] += diffgradx; + e[3][0] += diffgrady; + } + } + + for(i = 0; i < 4; i++) e[i][0] *= 0.5; + +} + + + +/********************************************************************* + * _am_trackFeatureAffine + * + * Tracks a feature point from the image of first occurrence to the actual image. + * + * RETURNS + * KLT_SMALL_DET or KLT_LARGE_RESIDUE or KLT_OOB if feature is lost, + * KLT_TRACKED otherwise. + */ + +/* if you enalbe the DEBUG_AFFINE_MAPPING make sure you have created a directory "./debug" */ +/* #define DEBUG_AFFINE_MAPPING */ + +#ifdef DEBUG_AFFINE_MAPPING +static int counter = 0; +static int glob_index = 0; +#endif + +static int _am_trackFeatureAffine( + float x1, /* location of window in first image */ + float y1, + float *x2, /* starting location of search in second image */ + float *y2, + _KLT_FloatImage img1, + _KLT_FloatImage gradx1, + _KLT_FloatImage grady1, + _KLT_FloatImage img2, + _KLT_FloatImage gradx2, + _KLT_FloatImage grady2, + int width, /* size of window */ + int height, + float step_factor, /* 2.0 comes from equations, 1.0 seems to avoid overshooting */ + int max_iterations, + float small, /* determinant threshold for declaring KLT_SMALL_DET */ + float th, /* displacement threshold for stopping */ + float th_aff, + float max_residue, /* residue threshold for declaring KLT_LARGE_RESIDUE */ + int lighting_insensitive, /* whether to normalize for gain and bias */ + int affine_map, /* whether to evaluates the consistency of features with affine mapping */ + float mdd, /* difference between the displacements */ + float *Axx, float *Ayx, + float *Axy, float *Ayy) /* used affine mapping */ +{ + + + _FloatWindow imgdiff, gradx, grady; + float gxx, gxy, gyy, ex, ey, dx, dy; + int iteration = 0; + int status = 0; + int hw = width/2; + int hh = height/2; + int nc1 = img1->ncols; + int nr1 = img1->nrows; + int nc2 = img2->ncols; + int nr2 = img2->nrows; + float **a; + float **T; + float one_plus_eps = 1.001f; /* To prevent rounding errors */ + float old_x2 = *x2; + float old_y2 = *y2; + KLT_BOOL convergence = FALSE; + +#ifdef DEBUG_AFFINE_MAPPING + char fname[80]; + _KLT_FloatImage aff_diff_win = _KLTCreateFloatImage(width,height); + printf("starting location x2=%f y2=%f\n", *x2, *y2); +#endif + + /* Allocate memory for windows */ + imgdiff = _allocateFloatWindow(width, height); + gradx = _allocateFloatWindow(width, height); + grady = _allocateFloatWindow(width, height); + T = _am_matrix(6,6); + a = _am_matrix(6,1); + + /* Iteratively update the window position */ + do { + if(!affine_map) { + /* pure translation tracker */ + + /* If out of bounds, exit loop */ + if ( x1-hw < 0.0f || nc1-( x1+hw) < one_plus_eps || + *x2-hw < 0.0f || nc2-(*x2+hw) < one_plus_eps || + y1-hh < 0.0f || nr1-( y1+hh) < one_plus_eps || + *y2-hh < 0.0f || nr2-(*y2+hh) < one_plus_eps) { + status = KLT_OOB; + break; + } + + /* Compute gradient and difference windows */ + if (lighting_insensitive) { + _computeIntensityDifferenceLightingInsensitive(img1, img2, x1, y1, *x2, *y2, + width, height, imgdiff); + _computeGradientSumLightingInsensitive(gradx1, grady1, gradx2, grady2, + img1, img2, x1, y1, *x2, *y2, width, height, gradx, grady); + } else { + _computeIntensityDifference(img1, img2, x1, y1, *x2, *y2, + width, height, imgdiff); + _computeGradientSum(gradx1, grady1, gradx2, grady2, + x1, y1, *x2, *y2, width, height, gradx, grady); + } + +#ifdef DEBUG_AFFINE_MAPPING + aff_diff_win->data = imgdiff; + sprintf(fname, "./debug/kltimg_trans_diff_win%03d.%03d.pgm", glob_index, counter); + printf("%s\n", fname); + _KLTWriteAbsFloatImageToPGM(aff_diff_win, fname,256.0); + printf("iter = %d translation tracker res: %f\n", iteration, _sumAbsFloatWindow(imgdiff, width, height)/(width*height)); +#endif + + /* Use these windows to construct matrices */ + _compute2by2GradientMatrix(gradx, grady, width, height, + &gxx, &gxy, &gyy); + _compute2by1ErrorVector(imgdiff, gradx, grady, width, height, step_factor, + &ex, &ey); + + /* Using matrices, solve equation for new displacement */ + status = _solveEquation(gxx, gxy, gyy, ex, ey, small, &dx, &dy); + + convergence = (fabs(dx) < th && fabs(dy) < th); + + *x2 += dx; + *y2 += dy; + + }else{ + /* affine tracker */ + + float ul_x = *Axx * (-hw) + *Axy * hh + *x2; /* upper left corner */ + float ul_y = *Ayx * (-hw) + *Ayy * hh + *y2; + float ll_x = *Axx * (-hw) + *Axy * (-hh) + *x2; /* lower left corner */ + float ll_y = *Ayx * (-hw) + *Ayy * (-hh) + *y2; + float ur_x = *Axx * hw + *Axy * hh + *x2; /* upper right corner */ + float ur_y = *Ayx * hw + *Ayy * hh + *y2; + float lr_x = *Axx * hw + *Axy * (-hh) + *x2; /* lower right corner */ + float lr_y = *Ayx * hw + *Ayy * (-hh) + *y2; + + /* If out of bounds, exit loop */ + if ( x1-hw < 0.0f || nc1-(x1+hw) < one_plus_eps || + y1-hh < 0.0f || nr1-(y1+hh) < one_plus_eps || + ul_x < 0.0f || nc2-(ul_x ) < one_plus_eps || + ll_x < 0.0f || nc2-(ll_x ) < one_plus_eps || + ur_x < 0.0f || nc2-(ur_x ) < one_plus_eps || + lr_x < 0.0f || nc2-(lr_x ) < one_plus_eps || + ul_y < 0.0f || nr2-(ul_y ) < one_plus_eps || + ll_y < 0.0f || nr2-(ll_y ) < one_plus_eps || + ur_y < 0.0f || nr2-(ur_y ) < one_plus_eps || + lr_y < 0.0f || nr2-(lr_y ) < one_plus_eps) { + status = KLT_OOB; + break; + } + +#ifdef DEBUG_AFFINE_MAPPING + counter++; + _am_computeAffineMappedImage(img1, x1, y1, 1.0, 0.0 , 0.0, 1.0, width, height, imgdiff); + aff_diff_win->data = imgdiff; + sprintf(fname, "./debug/kltimg_aff_diff_win%03d.%03d_1.pgm", glob_index, counter); + printf("%s\n", fname); + _KLTWriteAbsFloatImageToPGM(aff_diff_win, fname,256.0); + + _am_computeAffineMappedImage(img2, *x2, *y2, *Axx, *Ayx , *Axy, *Ayy, width, height, imgdiff); + aff_diff_win->data = imgdiff; + sprintf(fname, "./debug/kltimg_aff_diff_win%03d.%03d_2.pgm", glob_index, counter); + printf("%s\n", fname); + _KLTWriteAbsFloatImageToPGM(aff_diff_win, fname,256.0); +#endif + + _am_computeIntensityDifferenceAffine(img1, img2, x1, y1, *x2, *y2, *Axx, *Ayx , *Axy, *Ayy, + width, height, imgdiff); +#ifdef DEBUG_AFFINE_MAPPING + aff_diff_win->data = imgdiff; + sprintf(fname, "./debug/kltimg_aff_diff_win%03d.%03d_3.pgm", glob_index,counter); + printf("%s\n", fname); + _KLTWriteAbsFloatImageToPGM(aff_diff_win, fname,256.0); + + printf("iter = %d affine tracker res: %f\n", iteration, _sumAbsFloatWindow(imgdiff, width, height)/(width*height)); +#endif + + _am_getGradientWinAffine(gradx2, grady2, *x2, *y2, *Axx, *Ayx , *Axy, *Ayy, + width, height, gradx, grady); + + switch(affine_map){ + case 1: + _am_compute4by1ErrorVector(imgdiff, gradx, grady, width, height, a); + _am_compute4by4GradientMatrix(gradx, grady, width, height, T); + + status = _am_gauss_jordan_elimination(T,4,a,1); + + *Axx += a[0][0]; + *Ayx += a[1][0]; + *Ayy = *Axx; + *Axy = -(*Ayx); + + dx = a[2][0]; + dy = a[3][0]; + + break; + case 2: + _am_compute6by1ErrorVector(imgdiff, gradx, grady, width, height, a); + _am_compute6by6GradientMatrix(gradx, grady, width, height, T); + + status = _am_gauss_jordan_elimination(T,6,a,1); + + *Axx += a[0][0]; + *Ayx += a[1][0]; + *Axy += a[2][0]; + *Ayy += a[3][0]; + + dx = a[4][0]; + dy = a[5][0]; + + break; + } + + *x2 += dx; + *y2 += dy; + + /* old upper left corner - new upper left corner */ + ul_x -= *Axx * (-hw) + *Axy * hh + *x2; + ul_y -= *Ayx * (-hw) + *Ayy * hh + *y2; + /* old lower left corner - new lower left corner */ + ll_x -= *Axx * (-hw) + *Axy * (-hh) + *x2; + ll_y -= *Ayx * (-hw) + *Ayy * (-hh) + *y2; + /* old upper right corner - new upper right corner */ + ur_x -= *Axx * hw + *Axy * hh + *x2; + ur_y -= *Ayx * hw + *Ayy * hh + *y2; + /* old lower right corner - new lower right corner */ + lr_x -= *Axx * hw + *Axy * (-hh) + *x2; + lr_y -= *Ayx * hw + *Ayy * (-hh) + *y2; + +#ifdef DEBUG_AFFINE_MAPPING + printf ("iter = %d, ul_x=%f ul_y=%f ll_x=%f ll_y=%f ur_x=%f ur_y=%f lr_x=%f lr_y=%f \n", + iteration, ul_x, ul_y, ll_x, ll_y, ur_x, ur_y, lr_x, lr_y); +#endif + + convergence = (fabs(dx) < th && fabs(dy) < th && + fabs(ul_x) < th_aff && fabs(ul_y) < th_aff && + fabs(ll_x) < th_aff && fabs(ll_y) < th_aff && + fabs(ur_x) < th_aff && fabs(ur_y) < th_aff && + fabs(lr_x) < th_aff && fabs(lr_y) < th_aff); + } + + if (status == KLT_SMALL_DET) break; + iteration++; +#ifdef DEBUG_AFFINE_MAPPING + printf ("iter = %d, x1=%f, y1=%f, x2=%f, y2=%f, Axx=%f, Ayx=%f , Axy=%f, Ayy=%f \n",iteration, x1, y1, *x2, *y2, *Axx, *Ayx , *Axy, *Ayy); +#endif + } while ( !convergence && iteration < max_iterations); + /*} while ( (fabs(dx)>=th || fabs(dy)>=th || (affine_map && iteration < 8) ) && iteration < max_iterations); */ + _am_free_matrix(T); + _am_free_matrix(a); + + /* Check whether window is out of bounds */ + if (*x2-hw < 0.0f || nc2-(*x2+hw) < one_plus_eps || + *y2-hh < 0.0f || nr2-(*y2+hh) < one_plus_eps) + status = KLT_OOB; + + /* Check whether feature point has moved to much during iteration*/ + if ( (*x2-old_x2) > mdd || (*y2-old_y2) > mdd ) + status = KLT_OOB; + + /* Check whether residue is too large */ + if (status == KLT_TRACKED) { + if(!affine_map){ + _computeIntensityDifference(img1, img2, x1, y1, *x2, *y2, + width, height, imgdiff); + }else{ + _am_computeIntensityDifferenceAffine(img1, img2, x1, y1, *x2, *y2, *Axx, *Ayx , *Axy, *Ayy, + width, height, imgdiff); + } +#ifdef DEBUG_AFFINE_MAPPING + printf("iter = %d final_res = %f\n", iteration, _sumAbsFloatWindow(imgdiff, width, height)/(width*height)); +#endif + if (_sumAbsFloatWindow(imgdiff, width, height)/(width*height) > max_residue) + status = KLT_LARGE_RESIDUE; + } + + /* Free memory */ + free(imgdiff); free(gradx); free(grady); + +#ifdef DEBUG_AFFINE_MAPPING + printf("iter = %d status=%d\n", iteration, status); + _KLTFreeFloatImage( aff_diff_win ); +#endif + + /* Return appropriate value */ + return status; +} + +/* + * CONSISTENCY CHECK OF FEATURES BY AFFINE MAPPING (END) + **********************************************************************/ + + + +/********************************************************************* + * KLTTrackFeatures + * + * Tracks feature points from one image to the next. + */ + +void KLTTrackFeatures( + KLT_TrackingContext tc, + KLT_PixelType *img1, + KLT_PixelType *img2, + int ncols, + int nrows, + KLT_FeatureList featurelist) +{ + _KLT_FloatImage tmpimg, floatimg1, floatimg2; + _KLT_Pyramid pyramid1, pyramid1_gradx, pyramid1_grady, + pyramid2, pyramid2_gradx, pyramid2_grady; + float subsampling = (float) tc->subsampling; + float xloc, yloc, xlocout, ylocout; + int val; + int indx, r; + KLT_BOOL floatimg1_created = FALSE; + int i; + + if (KLT_verbose >= 1) { + fprintf(stderr, "(KLT) Tracking %d features in a %d by %d image... ", + KLTCountRemainingFeatures(featurelist), ncols, nrows); + fflush(stderr); + } + + /* Check window size (and correct if necessary) */ + if (tc->window_width % 2 != 1) { + tc->window_width = tc->window_width+1; + KLTWarning("Tracking context's window width must be odd. " + "Changing to %d.\n", tc->window_width); + } + if (tc->window_height % 2 != 1) { + tc->window_height = tc->window_height+1; + KLTWarning("Tracking context's window height must be odd. " + "Changing to %d.\n", tc->window_height); + } + if (tc->window_width < 3) { + tc->window_width = 3; + KLTWarning("Tracking context's window width must be at least three. \n" + "Changing to %d.\n", tc->window_width); + } + if (tc->window_height < 3) { + tc->window_height = 3; + KLTWarning("Tracking context's window height must be at least three. \n" + "Changing to %d.\n", tc->window_height); + } + + /* Create temporary image */ + tmpimg = _KLTCreateFloatImage(ncols, nrows); + + /* Process first image by converting to float, smoothing, computing */ + /* pyramid, and computing gradient pyramids */ + if (tc->sequentialMode && tc->pyramid_last != NULL) { + pyramid1 = (_KLT_Pyramid) tc->pyramid_last; + pyramid1_gradx = (_KLT_Pyramid) tc->pyramid_last_gradx; + pyramid1_grady = (_KLT_Pyramid) tc->pyramid_last_grady; + if (pyramid1->ncols[0] != ncols || pyramid1->nrows[0] != nrows) { + KLTError("(KLTTrackFeatures) Size of incoming image (%d by %d) " + "is different from size of previous image (%d by %d)\n", + ncols, nrows, pyramid1->ncols[0], pyramid1->nrows[0]); + exit(1); + } + assert(pyramid1_gradx != NULL); + assert(pyramid1_grady != NULL); + } else { + floatimg1_created = TRUE; + floatimg1 = _KLTCreateFloatImage(ncols, nrows); + _KLTToFloatImage(img1, ncols, nrows, tmpimg); + _KLTComputeSmoothedImage(tmpimg, _KLTComputeSmoothSigma(tc), floatimg1); + pyramid1 = _KLTCreatePyramid(ncols, nrows, (int) subsampling, tc->nPyramidLevels); + _KLTComputePyramid(floatimg1, pyramid1, tc->pyramid_sigma_fact); + pyramid1_gradx = _KLTCreatePyramid(ncols, nrows, (int) subsampling, tc->nPyramidLevels); + pyramid1_grady = _KLTCreatePyramid(ncols, nrows, (int) subsampling, tc->nPyramidLevels); + for (i = 0 ; i < tc->nPyramidLevels ; i++) + _KLTComputeGradients(pyramid1->img[i], tc->grad_sigma, + pyramid1_gradx->img[i], + pyramid1_grady->img[i]); + } + + /* Do the same thing with second image */ + floatimg2 = _KLTCreateFloatImage(ncols, nrows); + _KLTToFloatImage(img2, ncols, nrows, tmpimg); + _KLTComputeSmoothedImage(tmpimg, _KLTComputeSmoothSigma(tc), floatimg2); + pyramid2 = _KLTCreatePyramid(ncols, nrows, (int) subsampling, tc->nPyramidLevels); + _KLTComputePyramid(floatimg2, pyramid2, tc->pyramid_sigma_fact); + pyramid2_gradx = _KLTCreatePyramid(ncols, nrows, (int) subsampling, tc->nPyramidLevels); + pyramid2_grady = _KLTCreatePyramid(ncols, nrows, (int) subsampling, tc->nPyramidLevels); + for (i = 0 ; i < tc->nPyramidLevels ; i++) + _KLTComputeGradients(pyramid2->img[i], tc->grad_sigma, + pyramid2_gradx->img[i], + pyramid2_grady->img[i]); + + /* Write internal images */ + if (tc->writeInternalImages) { + char fname[80]; + for (i = 0 ; i < tc->nPyramidLevels ; i++) { + sprintf(fname, "kltimg_tf_i%d.pgm", i); + _KLTWriteFloatImageToPGM(pyramid1->img[i], fname); + sprintf(fname, "kltimg_tf_i%d_gx.pgm", i); + _KLTWriteFloatImageToPGM(pyramid1_gradx->img[i], fname); + sprintf(fname, "kltimg_tf_i%d_gy.pgm", i); + _KLTWriteFloatImageToPGM(pyramid1_grady->img[i], fname); + sprintf(fname, "kltimg_tf_j%d.pgm", i); + _KLTWriteFloatImageToPGM(pyramid2->img[i], fname); + sprintf(fname, "kltimg_tf_j%d_gx.pgm", i); + _KLTWriteFloatImageToPGM(pyramid2_gradx->img[i], fname); + sprintf(fname, "kltimg_tf_j%d_gy.pgm", i); + _KLTWriteFloatImageToPGM(pyramid2_grady->img[i], fname); + } + } + + /* For each feature, do ... */ + for (indx = 0 ; indx < featurelist->nFeatures ; indx++) { + + /* Only track features that are not lost */ + if (featurelist->feature[indx]->val >= 0) { + + xloc = featurelist->feature[indx]->x; + yloc = featurelist->feature[indx]->y; + + /* Transform location to coarsest resolution */ + for (r = tc->nPyramidLevels - 1 ; r >= 0 ; r--) { + xloc /= subsampling; yloc /= subsampling; + } + xlocout = xloc; ylocout = yloc; + + /* Beginning with coarsest resolution, do ... */ + for (r = tc->nPyramidLevels - 1 ; r >= 0 ; r--) { + + /* Track feature at current resolution */ + xloc *= subsampling; yloc *= subsampling; + xlocout *= subsampling; ylocout *= subsampling; + + val = _trackFeature(xloc, yloc, + &xlocout, &ylocout, + pyramid1->img[r], + pyramid1_gradx->img[r], pyramid1_grady->img[r], + pyramid2->img[r], + pyramid2_gradx->img[r], pyramid2_grady->img[r], + tc->window_width, tc->window_height, + tc->step_factor, + tc->max_iterations, + tc->min_determinant, + tc->min_displacement, + tc->max_residue, + tc->lighting_insensitive); + + if (val==KLT_SMALL_DET || val==KLT_OOB) + break; + } + + /* Record feature */ + if (val == KLT_OOB) { + featurelist->feature[indx]->x = -1.0; + featurelist->feature[indx]->y = -1.0; + featurelist->feature[indx]->val = KLT_OOB; + if( featurelist->feature[indx]->aff_img ) _KLTFreeFloatImage(featurelist->feature[indx]->aff_img); + if( featurelist->feature[indx]->aff_img_gradx ) _KLTFreeFloatImage(featurelist->feature[indx]->aff_img_gradx); + if( featurelist->feature[indx]->aff_img_grady ) _KLTFreeFloatImage(featurelist->feature[indx]->aff_img_grady); + featurelist->feature[indx]->aff_img = NULL; + featurelist->feature[indx]->aff_img_gradx = NULL; + featurelist->feature[indx]->aff_img_grady = NULL; + + } else if (_outOfBounds(xlocout, ylocout, ncols, nrows, tc->borderx, tc->bordery)) { + featurelist->feature[indx]->x = -1.0; + featurelist->feature[indx]->y = -1.0; + featurelist->feature[indx]->val = KLT_OOB; + if( featurelist->feature[indx]->aff_img ) _KLTFreeFloatImage(featurelist->feature[indx]->aff_img); + if( featurelist->feature[indx]->aff_img_gradx ) _KLTFreeFloatImage(featurelist->feature[indx]->aff_img_gradx); + if( featurelist->feature[indx]->aff_img_grady ) _KLTFreeFloatImage(featurelist->feature[indx]->aff_img_grady); + featurelist->feature[indx]->aff_img = NULL; + featurelist->feature[indx]->aff_img_gradx = NULL; + featurelist->feature[indx]->aff_img_grady = NULL; + } else if (val == KLT_SMALL_DET) { + featurelist->feature[indx]->x = -1.0; + featurelist->feature[indx]->y = -1.0; + featurelist->feature[indx]->val = KLT_SMALL_DET; + if( featurelist->feature[indx]->aff_img ) _KLTFreeFloatImage(featurelist->feature[indx]->aff_img); + if( featurelist->feature[indx]->aff_img_gradx ) _KLTFreeFloatImage(featurelist->feature[indx]->aff_img_gradx); + if( featurelist->feature[indx]->aff_img_grady ) _KLTFreeFloatImage(featurelist->feature[indx]->aff_img_grady); + featurelist->feature[indx]->aff_img = NULL; + featurelist->feature[indx]->aff_img_gradx = NULL; + featurelist->feature[indx]->aff_img_grady = NULL; + } else if (val == KLT_LARGE_RESIDUE) { + featurelist->feature[indx]->x = -1.0; + featurelist->feature[indx]->y = -1.0; + featurelist->feature[indx]->val = KLT_LARGE_RESIDUE; + if( featurelist->feature[indx]->aff_img ) _KLTFreeFloatImage(featurelist->feature[indx]->aff_img); + if( featurelist->feature[indx]->aff_img_gradx ) _KLTFreeFloatImage(featurelist->feature[indx]->aff_img_gradx); + if( featurelist->feature[indx]->aff_img_grady ) _KLTFreeFloatImage(featurelist->feature[indx]->aff_img_grady); + featurelist->feature[indx]->aff_img = NULL; + featurelist->feature[indx]->aff_img_gradx = NULL; + featurelist->feature[indx]->aff_img_grady = NULL; + } else if (val == KLT_MAX_ITERATIONS) { + featurelist->feature[indx]->x = -1.0; + featurelist->feature[indx]->y = -1.0; + featurelist->feature[indx]->val = KLT_MAX_ITERATIONS; + if( featurelist->feature[indx]->aff_img ) _KLTFreeFloatImage(featurelist->feature[indx]->aff_img); + if( featurelist->feature[indx]->aff_img_gradx ) _KLTFreeFloatImage(featurelist->feature[indx]->aff_img_gradx); + if( featurelist->feature[indx]->aff_img_grady ) _KLTFreeFloatImage(featurelist->feature[indx]->aff_img_grady); + featurelist->feature[indx]->aff_img = NULL; + featurelist->feature[indx]->aff_img_gradx = NULL; + featurelist->feature[indx]->aff_img_grady = NULL; + } else { + featurelist->feature[indx]->x = xlocout; + featurelist->feature[indx]->y = ylocout; + featurelist->feature[indx]->val = KLT_TRACKED; + if (tc->affineConsistencyCheck >= 0 && val == KLT_TRACKED) { /*for affine mapping*/ + int border = 2; /* add border for interpolation */ + +#ifdef DEBUG_AFFINE_MAPPING + glob_index = indx; +#endif + + if(!featurelist->feature[indx]->aff_img){ + /* save image and gradient for each feature at finest resolution after first successful track */ + featurelist->feature[indx]->aff_img = _KLTCreateFloatImage((tc->affine_window_width+border), (tc->affine_window_height+border)); + featurelist->feature[indx]->aff_img_gradx = _KLTCreateFloatImage((tc->affine_window_width+border), (tc->affine_window_height+border)); + featurelist->feature[indx]->aff_img_grady = _KLTCreateFloatImage((tc->affine_window_width+border), (tc->affine_window_height+border)); + _am_getSubFloatImage(pyramid1->img[0],xloc,yloc,featurelist->feature[indx]->aff_img); + _am_getSubFloatImage(pyramid1_gradx->img[0],xloc,yloc,featurelist->feature[indx]->aff_img_gradx); + _am_getSubFloatImage(pyramid1_grady->img[0],xloc,yloc,featurelist->feature[indx]->aff_img_grady); + featurelist->feature[indx]->aff_x = xloc - (int) xloc + (tc->affine_window_width+border)/2; + featurelist->feature[indx]->aff_y = yloc - (int) yloc + (tc->affine_window_height+border)/2;; + }else{ + /* affine tracking */ + val = _am_trackFeatureAffine(featurelist->feature[indx]->aff_x, featurelist->feature[indx]->aff_y, + &xlocout, &ylocout, + featurelist->feature[indx]->aff_img, + featurelist->feature[indx]->aff_img_gradx, + featurelist->feature[indx]->aff_img_grady, + pyramid2->img[0], + pyramid2_gradx->img[0], pyramid2_grady->img[0], + tc->affine_window_width, tc->affine_window_height, + tc->step_factor, + tc->affine_max_iterations, + tc->min_determinant, + tc->min_displacement, + tc->affine_min_displacement, + tc->affine_max_residue, + tc->lighting_insensitive, + tc->affineConsistencyCheck, + tc->affine_max_displacement_differ, + &featurelist->feature[indx]->aff_Axx, + &featurelist->feature[indx]->aff_Ayx, + &featurelist->feature[indx]->aff_Axy, + &featurelist->feature[indx]->aff_Ayy + ); + featurelist->feature[indx]->val = val; + if(val != KLT_TRACKED){ + featurelist->feature[indx]->x = -1.0; + featurelist->feature[indx]->y = -1.0; + featurelist->feature[indx]->aff_x = -1.0; + featurelist->feature[indx]->aff_y = -1.0; + /* free image and gradient for lost feature */ + _KLTFreeFloatImage(featurelist->feature[indx]->aff_img); + _KLTFreeFloatImage(featurelist->feature[indx]->aff_img_gradx); + _KLTFreeFloatImage(featurelist->feature[indx]->aff_img_grady); + featurelist->feature[indx]->aff_img = NULL; + featurelist->feature[indx]->aff_img_gradx = NULL; + featurelist->feature[indx]->aff_img_grady = NULL; + }else{ + /*featurelist->feature[indx]->x = xlocout;*/ + /*featurelist->feature[indx]->y = ylocout;*/ + } + } + } + + } + } + } + + if (tc->sequentialMode) { + tc->pyramid_last = pyramid2; + tc->pyramid_last_gradx = pyramid2_gradx; + tc->pyramid_last_grady = pyramid2_grady; + } else { + _KLTFreePyramid(pyramid2); + _KLTFreePyramid(pyramid2_gradx); + _KLTFreePyramid(pyramid2_grady); + } + + /* Free memory */ + _KLTFreeFloatImage(tmpimg); + if (floatimg1_created) _KLTFreeFloatImage(floatimg1); + _KLTFreeFloatImage(floatimg2); + _KLTFreePyramid(pyramid1); + _KLTFreePyramid(pyramid1_gradx); + _KLTFreePyramid(pyramid1_grady); + + if (KLT_verbose >= 1) { + fprintf(stderr, "\n\t%d features successfully tracked.\n", + KLTCountRemainingFeatures(featurelist)); + if (tc->writeInternalImages) + fprintf(stderr, "\tWrote images to 'kltimg_tf*.pgm'.\n"); + fflush(stderr); + } + +} + + diff --git a/rtengine/klt/writeFeatures.cc b/rtengine/klt/writeFeatures.cc new file mode 100644 index 000000000..d902778de --- /dev/null +++ b/rtengine/klt/writeFeatures.cc @@ -0,0 +1,807 @@ +/********************************************************************* + * writeFeatures.c + * + ********************************************************************* + */ + +/* Standard includes */ +#include +#include /* isdigit() */ +#include /* sprintf(), fprintf(), sscanf(), fscanf() */ +#include /* malloc() */ +#include /* memcpy(), strcmp() */ + +/* Our includes */ +#include "base.h" +#include "error.h" +#include "pnmio.h" /* ppmWriteFileRGB() */ +#include "klt.h" + +using namespace std; + +#define BINHEADERLENGTH 6 + +extern int KLT_verbose; + +typedef enum {FEATURE_LIST, FEATURE_HISTORY, FEATURE_TABLE} structureType; + +static char warning_line[] = "!!! Warning: This is a KLT data file. " + "Do not modify below this line !!!\n"; +static char binheader_fl[BINHEADERLENGTH+1] = "KLTFL1"; +static char binheader_fh[BINHEADERLENGTH+1] = "KLTFH1"; +static char binheader_ft[BINHEADERLENGTH+1] = "KLTFT1"; + +/********************************************************************* + * KLTWriteFeatureListToPPM + */ + +void KLTWriteFeatureListToPPM( + KLT_FeatureList featurelist, + KLT_PixelType *greyimg, + int ncols, + int nrows, + const char *filename) +{ + int nbytes = ncols * nrows * sizeof(char); + uchar *redimg, *grnimg, *bluimg; + int offset; + int x, y, xx, yy; + int i; + + if (KLT_verbose >= 1) + fprintf(stderr, "(KLT) Writing %d features to PPM file: '%s'\n", + KLTCountRemainingFeatures(featurelist), filename); + + /* Allocate memory for component images */ + redimg = (uchar *) malloc(nbytes); + grnimg = (uchar *) malloc(nbytes); + bluimg = (uchar *) malloc(nbytes); + if (redimg == NULL || grnimg == NULL || bluimg == NULL) { + KLTError("(KLTWriteFeaturesToPPM) Out of memory\n"); + exit(1); + } + + /* Copy grey image to component images */ + if (sizeof(KLT_PixelType) != 1) + KLTWarning("(KLTWriteFeaturesToPPM) KLT_PixelType is not uchar"); + memcpy(redimg, greyimg, nbytes); + memcpy(grnimg, greyimg, nbytes); + memcpy(bluimg, greyimg, nbytes); + + /* Overlay features in red */ + for (i = 0 ; i < featurelist->nFeatures ; i++) + if (featurelist->feature[i]->val >= 0) { + x = (int) (featurelist->feature[i]->x + 0.5); + y = (int) (featurelist->feature[i]->y + 0.5); + for (yy = y - 1 ; yy <= y + 1 ; yy++) + for (xx = x - 1 ; xx <= x + 1 ; xx++) + if (xx >= 0 && yy >= 0 && xx < ncols && yy < nrows) { + offset = yy * ncols + xx; + *(redimg + offset) = 255; + *(grnimg + offset) = 0; + *(bluimg + offset) = 0; + } + } + + /* Write to PPM file */ + ppmWriteFileRGB(filename, redimg, grnimg, bluimg, ncols, nrows); + + /* Free memory */ + free(redimg); + free(grnimg); + free(bluimg); +} + + +static FILE* _printSetupTxt( + const char *fname, /* Input: filename, or NULL for stderr */ + const char *fmt, /* Input: format (e.g., %5.1f or %3d) */ + char *format, /* Output: format (e.g., (%5.1f,%5.1f)=%3d) */ + char *type) /* Output: either 'f' or 'd', based on input format */ +{ + FILE *fp; + const int val_width = 5; + int i; + + /* Either open file or use stderr */ + if (fname == NULL) fp = stderr; + else fp = fopen(fname, "wb"); + if (fp == NULL) { + KLTError("(KLTWriteFeatures) " + "Can't open file '%s' for writing\n", fname); + exit(1); + } + + /* Parse format */ + if (fmt[0] != '%') { + KLTError("(KLTWriteFeatures) Bad Format: %s\n", fmt); + exit(1); + } + i = 0; while (fmt[i] != '\0') i++; *type = fmt[i-1]; + if (*type != 'f' && *type != 'd') { + KLTError("(KLTWriteFeatures) Format must end in 'f' or 'd'."); + exit(1); + } + + /* Construct feature format */ + sprintf(format, "(%s,%s)=%%%dd ", fmt, fmt, val_width); + + return fp; +} + + +static FILE* _printSetupBin( + const char *fname) /* Input: filename */ +{ + FILE *fp; + if (fname == NULL) { + KLTError("(KLTWriteFeatures) Can't write binary data to stderr"); + exit(1); + } + fp = fopen(fname, "wb"); + if (fp == NULL) { + KLTError("(KLTWriteFeatures) " + "Can't open file '%s' for writing", fname); + exit(1); + } + return fp; +} + + +static void _printNhyphens( + FILE *fp, + int n) +{ + int i; + for (i = 0 ; i < n ; i++) + fprintf(fp, "-"); +} + +static void _printInteger( + FILE *fp, + int integer, + int width) +{ + char fmt[80]; + sprintf(fmt, "%%%dd", width); + fprintf(fp, fmt, integer); +} + + +static KLT_BOOL _isCharInString( + const char c, + const char *str) +{ + int width = strlen(str); + int i; + + for (i = 0 ; i < width ; i++) + if (c == str[i]) return TRUE; + + return FALSE; +} + + +/********************************************************************* + * _findStringWidth + * + * Calculates the length of a string after expansion. E.g., the + * length of "(%6.1f)" is eight -- six for the floating-point number, + * and two for the parentheses. + */ + +static int _findStringWidth( + const char *str) +{ + int width = 0; + int add; + int maxi = strlen(str) - 1; + int i = 0; + + + while (str[i] != '\0') { + if (str[i] == '%') { + if (isdigit(str[i+1])) { + sscanf(str+i+1, "%d", &add); + width += add; + i += 2; + while (!_isCharInString(str[i], "diouxefgn")) { + i++; + if (i > maxi) { + KLTError("(_findStringWidth) Can't determine length " + "of string '%s'", str); + exit(1); + } + } + i++; + } else if (str[i+1] == 'c') { + width++; + i += 2; + } else { + KLTError("(_findStringWidth) Can't determine length " + "of string '%s'", str); + exit(1); + } + } else { + i++; + width++; + } + } + + return width; +} + + +static void _printHeader( + FILE *fp, + const char *format, + structureType id, + int nFrames, + int nFeatures) +{ + int width = _findStringWidth(format); + int i; + + assert(id == FEATURE_LIST || id == FEATURE_HISTORY || id == FEATURE_TABLE); + + if (fp != stderr) { + fprintf(fp, "Feel free to place comments here.\n\n\n"); + fprintf(fp, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); + fprintf(fp, "%s", warning_line); + fprintf(fp, "\n"); + } + fprintf(fp, "------------------------------\n"); + switch (id) { + case FEATURE_LIST: fprintf(fp, "KLT Feature List\n"); break; + case FEATURE_HISTORY: fprintf(fp, "KLT Feature History\n"); break; + case FEATURE_TABLE: fprintf(fp, "KLT Feature Table\n"); break; + } + + fprintf(fp, "------------------------------\n\n"); + switch (id) { + case FEATURE_LIST: fprintf(fp, "nFeatures = %d\n\n", nFeatures); break; + case FEATURE_HISTORY: fprintf(fp, "nFrames = %d\n\n", nFrames); break; + case FEATURE_TABLE: fprintf(fp, "nFrames = %d, nFeatures = %d\n\n", + nFrames, nFeatures); break; + } + + switch (id) { + case FEATURE_LIST: fprintf(fp, "feature | (x,y)=val\n"); + fprintf(fp, "--------+-"); + _printNhyphens(fp, width); + fprintf(fp, "\n"); + break; + case FEATURE_HISTORY: fprintf(fp, "frame | (x,y)=val\n"); + fprintf(fp, "------+-"); + _printNhyphens(fp, width); + fprintf(fp, "\n"); + break; + case FEATURE_TABLE: fprintf(fp, "feature | frame\n"); + fprintf(fp, " |"); + for (i = 0 ; i < nFrames ; i++) _printInteger(fp, i, width); + fprintf(fp, "\n--------+-"); + for (i = 0 ; i < nFrames ; i++) _printNhyphens(fp, width); + fprintf(fp, "\n"); + break; + } +} + + +static void _printFeatureTxt( + FILE *fp, + KLT_Feature feat, + const char *format, + const char type) +{ + assert(type == 'f' || type == 'd'); + + if (type == 'f') + fprintf(fp, format, (float) feat->x, (float) feat->y, feat->val); + else if (type == 'd') { + /* Round x & y to nearest integer, unless negative */ + float x = feat->x; + float y = feat->y; + if (x >= 0.0) x += 0.5; + if (y >= 0.0) y += 0.5; + fprintf(fp, format, + (int) x, (int) y, feat->val); + } +} + + +static void _printFeatureBin( + FILE *fp, + KLT_Feature feat) +{ + fwrite(&(feat->x), sizeof(KLT_locType), 1, fp); + fwrite(&(feat->y), sizeof(KLT_locType), 1, fp); + fwrite(&(feat->val), sizeof(int), 1, fp); +} + + +static void _printShutdown( + FILE *fp) +{ + /* Close file, if necessary */ + if (fp != stderr) + fclose(fp); +} + + +/********************************************************************* + * KLTWriteFeatureList() + * KLTWriteFeatureHistory() + * KLTWriteFeatureTable() + * + * Writes features to file or to screen. + * + * INPUTS + * fname: name of file to write data; if NULL, then print to stderr + * fmt: format for printing (e.g., "%5.1f" or "%3d"); + * if NULL, and if fname is not NULL, then write to binary file. + */ + +void KLTWriteFeatureList( + KLT_FeatureList fl, + const char *fname, + const char *fmt) +{ + FILE *fp; + char format[100]; + char type; + int i; + + if (KLT_verbose >= 1 && fname != NULL) { + fprintf(stderr, + "(KLT) Writing feature list to %s file: '%s'\n", + (fmt == NULL ? "binary" : "text"), fname); + } + + if (fmt != NULL) { /* text file or stderr */ + fp = _printSetupTxt(fname, fmt, format, &type); + _printHeader(fp, format, FEATURE_LIST, 0, fl->nFeatures); + + for (i = 0 ; i < fl->nFeatures ; i++) { + fprintf(fp, "%7d | ", i); + _printFeatureTxt(fp, fl->feature[i], format, type); + fprintf(fp, "\n"); + } + _printShutdown(fp); + } else { /* binary file */ + fp = _printSetupBin(fname); + fwrite(binheader_fl, sizeof(char), BINHEADERLENGTH, fp); + fwrite(&(fl->nFeatures), sizeof(int), 1, fp); + for (i = 0 ; i < fl->nFeatures ; i++) { + _printFeatureBin(fp, fl->feature[i]); + } + fclose(fp); + } +} + + +void KLTWriteFeatureHistory( + KLT_FeatureHistory fh, + const char *fname, + const char *fmt) +{ + FILE *fp; + char format[100]; + char type; + int i; + + if (KLT_verbose >= 1 && fname != NULL) { + fprintf(stderr, + "(KLT) Writing feature history to %s file: '%s'\n", + (fmt == NULL ? "binary" : "text"), fname); + } + + if (fmt != NULL) { /* text file or stderr */ + fp = _printSetupTxt(fname, fmt, format, &type); + _printHeader(fp, format, FEATURE_HISTORY, fh->nFrames, 0); + + for (i = 0 ; i < fh->nFrames ; i++) { + fprintf(fp, "%5d | ", i); + _printFeatureTxt(fp, fh->feature[i], format, type); + fprintf(fp, "\n"); + } + _printShutdown(fp); + } else { /* binary file */ + fp = _printSetupBin(fname); + fwrite(binheader_fh, sizeof(char), BINHEADERLENGTH, fp); + fwrite(&(fh->nFrames), sizeof(int), 1, fp); + for (i = 0 ; i < fh->nFrames ; i++) { + _printFeatureBin(fp, fh->feature[i]); + } + fclose(fp); + } +} + + + +void KLTWriteFeatureTable( + KLT_FeatureTable ft, + const char *fname, + const char *fmt) +{ + FILE *fp; + char format[100]; + char type; + int i, j; + + if (KLT_verbose >= 1 && fname != NULL) { + fprintf(stderr, + "(KLT) Writing feature table to %s file: '%s'\n", + (fmt == NULL ? "binary" : "text"), fname); + } + + if (fmt != NULL) { /* text file or stderr */ + fp = _printSetupTxt(fname, fmt, format, &type); + _printHeader(fp, format, FEATURE_TABLE, ft->nFrames, ft->nFeatures); + + for (j = 0 ; j < ft->nFeatures ; j++) { + fprintf(fp, "%7d | ", j); + for (i = 0 ; i < ft->nFrames ; i++) + _printFeatureTxt(fp, ft->feature[j][i], format, type); + fprintf(fp, "\n"); + } + _printShutdown(fp); + } else { /* binary file */ + fp = _printSetupBin(fname); + fwrite(binheader_ft, sizeof(char), BINHEADERLENGTH, fp); + fwrite(&(ft->nFrames), sizeof(int), 1, fp); + fwrite(&(ft->nFeatures), sizeof(int), 1, fp); + for (j = 0 ; j < ft->nFeatures ; j++) { + for (i = 0 ; i < ft->nFrames ; i++) { + _printFeatureBin(fp, ft->feature[j][i]); + } + } + fclose(fp); + } +} + + + +static structureType _readHeader( + FILE *fp, + int *nFrames, + int *nFeatures, + KLT_BOOL *binary) +{ +#define LINELENGTH 100 + char line[LINELENGTH]; + structureType id; + + /* If file is binary, then read data and return */ + fread(line, sizeof(char), BINHEADERLENGTH, fp); + line[BINHEADERLENGTH] = 0; + if (strcmp(line, binheader_fl) == 0) { + assert(nFeatures != NULL); + fread(nFeatures, sizeof(int), 1, fp); + *binary = TRUE; + return FEATURE_LIST; + } else if (strcmp(line, binheader_fh) == 0) { + assert(nFrames != NULL); + fread(nFrames, sizeof(int), 1, fp); + *binary = TRUE; + return FEATURE_HISTORY; + } else if (strcmp(line, binheader_ft) == 0) { + assert(nFrames != NULL); + assert(nFeatures != NULL); + fread(nFrames, sizeof(int), 1, fp); + fread(nFeatures, sizeof(int), 1, fp); + *binary = TRUE; + return FEATURE_TABLE; + + /* If file is NOT binary, then continue.*/ + } else { + rewind(fp); + *binary = FALSE; + } + + /* Skip comments until warning line */ + while (strcmp(line, warning_line) != 0) { + fgets(line, LINELENGTH, fp); + if (feof(fp)) { + KLTError("(_readFeatures) File is corrupted -- Couldn't find line:\n" + "\t%s\n", warning_line); + exit(1); + } + } + + /* Read 'Feature List', 'Feature History', or 'Feature Table' */ + while (fgetc(fp) != '-'); + while (fgetc(fp) != '\n'); + fgets(line, LINELENGTH, fp); + if (strcmp(line, "KLT Feature List\n") == 0) id = FEATURE_LIST; + else if (strcmp(line, "KLT Feature History\n") == 0) id = FEATURE_HISTORY; + else if (strcmp(line, "KLT Feature Table\n") == 0) id = FEATURE_TABLE; + else { + KLTError("(_readFeatures) File is corrupted -- (Not 'KLT Feature List', " + "'KLT Feature History', or 'KLT Feature Table')"); + exit(1); + } + + /* If there's an incompatibility between the type of file */ + /* and the parameters passed, exit now before we attempt */ + /* to write to non-allocated memory. Higher routine should */ + /* detect and handle this error. */ + if ((id == FEATURE_LIST && nFeatures == NULL) || + (id == FEATURE_HISTORY && nFrames == NULL) || + (id == FEATURE_TABLE && (nFeatures == NULL || nFrames == NULL))) + return id; + + /* Read nFeatures and nFrames */ + while (fgetc(fp) != '-'); + while (fgetc(fp) != '\n'); + fscanf(fp, "%s", line); + if (id == FEATURE_LIST) { + if (strcmp(line, "nFeatures") != 0) { + KLTError("(_readFeatures) File is corrupted -- " + "(Expected 'nFeatures', found '%s' instead)", line); + exit(1); + } + } else if (strcmp(line, "nFrames") != 0) { + KLTError("(_readFeatures) File is corrupted -- " + "(Expected 'nFrames', found '%s' instead)", line); + exit(1); + } + fscanf(fp, "%s", line); + if (strcmp(line, "=") != 0) { + KLTError("(_readFeatures) File is corrupted -- " + "(Expected '=', found '%s' instead)", line); + exit(1); + } + if (id == FEATURE_LIST) fscanf(fp, "%d", nFeatures); + else fscanf(fp, "%d", nFrames); + + /* If 'Feature Table', then also get nFeatures */ + if (id == FEATURE_TABLE) { + fscanf(fp, "%s", line); + if (strcmp(line, ",") != 0) { + KLTError("(_readFeatures) File '%s' is corrupted -- " + "(Expected 'comma', found '%s' instead)", line); + exit(1); + } + fscanf(fp, "%s", line); + if (strcmp(line, "nFeatures") != 0) { + KLTError("(_readFeatures) File '%s' is corrupted -- " + "(2 Expected 'nFeatures ', found '%s' instead)", line); + exit(1); + } + fscanf(fp, "%s", line); + if (strcmp(line, "=") != 0) { + KLTError("(_readFeatures) File '%s' is corrupted -- " + "(2 Expected '= ', found '%s' instead)", line); + exit(1); + } + fscanf(fp, "%d", nFeatures); + } + + /* Skip junk before data */ + while (fgetc(fp) != '-'); + while (fgetc(fp) != '\n'); + + return id; +#undef LINELENGTH +} + + +static void _readFeatureTxt( + FILE *fp, + KLT_Feature feat) +{ + while (fgetc(fp) != '('); + fscanf(fp, "%f,%f)=%d", &(feat->x), &(feat->y), &(feat->val)); +} + + +static void _readFeatureBin( + FILE *fp, + KLT_Feature feat) +{ + fread(&(feat->x), sizeof(KLT_locType), 1, fp); + fread(&(feat->y), sizeof(KLT_locType), 1, fp); + fread(&(feat->val), sizeof(int), 1, fp); +} + + +/********************************************************************* + * KLTReadFeatureList + * KLTReadFeatureHistory + * KLTReadFeatureTable + * + * If the first parameter (fl, fh, or ft) is NULL, then the + * corresponding structure is created. + */ + +KLT_FeatureList KLTReadFeatureList( + KLT_FeatureList fl_in, + const char *fname) +{ + FILE *fp; + KLT_FeatureList fl; + int nFeatures; + structureType id; + int indx; + KLT_BOOL binary; /* whether file is binary or text */ + int i; + + fp = fopen(fname, "rb"); + if (fp == NULL) { + KLTError("(KLTReadFeatureList) Can't open file '%s' " + "for reading", fname); + exit(1); + } + if (KLT_verbose >= 1) + fprintf(stderr, "(KLT) Reading feature list from '%s'\n", fname); + id = _readHeader(fp, NULL, &nFeatures, &binary); + if (id != FEATURE_LIST) { + KLTError("(KLTReadFeatureList) File '%s' does not contain " + "a FeatureList", fname); + exit(1); + } + + if (fl_in == NULL) { + fl = KLTCreateFeatureList(nFeatures); + fl->nFeatures = nFeatures; + } + else { + fl = fl_in; + if (fl->nFeatures != nFeatures) { + KLTError("(KLTReadFeatureList) The feature list passed " + "does not contain the same number of features as " + "the feature list in file '%s' ", fname); + exit(1); + } + } + + if (!binary) { /* text file */ + for (i = 0 ; i < fl->nFeatures ; i++) { + fscanf(fp, "%d |", &indx); + if (indx != i) { + KLTError("(KLTReadFeatureList) Bad index at i = %d" + "-- %d", i, indx); + exit(1); + } + _readFeatureTxt(fp, fl->feature[i]); + } + } else { /* binary file */ + for (i = 0 ; i < fl->nFeatures ; i++) { + _readFeatureBin(fp, fl->feature[i]); + } + } + + fclose(fp); + + return fl; +} + + +KLT_FeatureHistory KLTReadFeatureHistory( + KLT_FeatureHistory fh_in, + const char *fname) +{ + FILE *fp; + KLT_FeatureHistory fh; + int nFrames; + structureType id; + int indx; + KLT_BOOL binary; /* whether file is binary or text */ + int i; + + fp = fopen(fname, "rb"); + if (fp == NULL) { + KLTError("(KLTReadFeatureHistory) Can't open file '%s' " + "for reading", fname); + exit(1); + } + if (KLT_verbose >= 1) fprintf(stderr, "(KLT) Reading feature history from '%s'\n", fname); + id = _readHeader(fp, &nFrames, NULL, &binary); + if (id != FEATURE_HISTORY) { + KLTError("(KLTReadFeatureHistory) File '%s' does not contain " + "a FeatureHistory", fname); + exit(1); + } + + if (fh_in == NULL) { + fh = KLTCreateFeatureHistory(nFrames); + fh->nFrames = nFrames; + } + else { + fh = fh_in; + if (fh->nFrames != nFrames) { + KLTError("(KLTReadFeatureHistory) The feature history passed " + "does not contain the same number of frames as " + "the feature history in file '%s' ", fname); + exit(1); + } + } + + if (!binary) { /* text file */ + for (i = 0 ; i < fh->nFrames ; i++) { + fscanf(fp, "%d |", &indx); + if (indx != i) { + KLTError("(KLTReadFeatureHistory) Bad index at i = %d" + "-- %d", i, indx); + exit(1); + } + _readFeatureTxt(fp, fh->feature[i]); + } + } else { /* binary file */ + for (i = 0 ; i < fh->nFrames ; i++) { + _readFeatureBin(fp, fh->feature[i]); + } + } + + fclose(fp); + + return fh; +} + + +KLT_FeatureTable KLTReadFeatureTable( + KLT_FeatureTable ft_in, + const char *fname) +{ + FILE *fp; + KLT_FeatureTable ft; + int nFrames; + int nFeatures; + structureType id; + int indx; + KLT_BOOL binary; /* whether file is binary or text */ + int i, j; + + fp = fopen(fname, "rb"); + if (fp == NULL) { + KLTError("(KLTReadFeatureTable) Can't open file '%s' " + "for reading", fname); + exit(1); + } + if (KLT_verbose >= 1) fprintf(stderr, "(KLT) Reading feature table from '%s'\n", fname); + id = _readHeader(fp, &nFrames, &nFeatures, &binary); + if (id != FEATURE_TABLE) { + KLTError("(KLTReadFeatureTable) File '%s' does not contain " + "a FeatureTable", fname); + exit(1); + } + + if (ft_in == NULL) { + ft = KLTCreateFeatureTable(nFrames, nFeatures); + ft->nFrames = nFrames; + ft->nFeatures = nFeatures; + } + else { + ft = ft_in; + + if (ft->nFrames != nFrames || ft->nFeatures != nFeatures) { + KLTError("(KLTReadFeatureTable) The feature table passed " + "does not contain the same number of frames and " + "features as the feature table in file '%s' ", fname); + exit(1); + } + } + + if (!binary) { /* text file */ + for (j = 0 ; j < ft->nFeatures ; j++) { + fscanf(fp, "%d |", &indx); + if (indx != j) { + KLTError("(KLTReadFeatureTable) Bad index at j = %d" + "-- %d", j, indx); + exit(1); + } + for (i = 0 ; i < ft->nFrames ; i++) + _readFeatureTxt(fp, ft->feature[j][i]); + } + } else { /* binary file */ + for (j = 0 ; j < ft->nFeatures ; j++) { + for (i = 0 ; i < ft->nFrames ; i++) + _readFeatureBin(fp, ft->feature[j][i]); + } + } + + fclose(fp); + + return ft; +} + diff --git a/rtengine/labimage.cc b/rtengine/labimage.cc new file mode 100644 index 000000000..e3511afaf --- /dev/null +++ b/rtengine/labimage.cc @@ -0,0 +1,38 @@ +#include "labimage.h" +#include +namespace rtengine { + +LabImage::LabImage (int w, int h) : fromImage(false), W(w), H(h) { + allocLab(w,h); +} + +LabImage::~LabImage () { + deleteLab(); +} + +void LabImage::CopyFrom(LabImage *Img){ + memcpy(data, Img->data, W*H*3*sizeof(float)); +} + +void LabImage::getPipetteData (float &v1, float &v2, float &v3, int posX, int posY, int squareSize) { + float accumulator_L = 0.f; + float accumulator_a = 0.f; + float accumulator_b = 0.f; + unsigned long int n = 0; + int halfSquare = squareSize/2; + for (int iy=posY-halfSquare; iy=0 && iy>=0 && ix + * + * 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 _LABIMAGE_H_ +#define _LABIMAGE_H_ + +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]; + + data = new float [W*H*3]; + float * index = data; + for (int i=0; i +* +* 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 "lcp.h" +#include "safegtk.h" +#include "iccmatrices.h" +#include "iccstore.h" +#include "rawimagesource.h" +#include "improcfun.h" +#include "rt_math.h" + +#ifdef WIN32 +#include +// for GCC32 +#ifndef _WIN32_IE +#define _WIN32_IE 0x0600 +#endif +#include +#endif + + +using namespace std; +using namespace rtengine; +using namespace rtexif; + + +LCPModelCommon::LCPModelCommon() { + focLenX=focLenY=-1; imgXCenter=imgYCenter=0.5; + x0=y0=fx=fy=meanErr=0; badErr=false; + for (int i=0;i<5;i++) param[i]=0; + scaleFac=1; +} + +bool LCPModelCommon::empty() const { + return param[0]==0 && param[1]==0 && param[2]==0; +} + +void LCPModelCommon::print() const { + printf("focLen %g/%g; imgCenter %g/%g; scale %g; err %g\n",focLenX,focLenY,imgXCenter,imgYCenter,scaleFac,meanErr); + 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]); +} + +// weightened merge two parameters +void LCPModelCommon::merge(const LCPModelCommon& a, const LCPModelCommon& b, float facA) { + float facB=1-facA; + + focLenX = facA * a.focLenX + facB * b.focLenX; + focLenY = facA * a.focLenY + facB * b.focLenY; + imgXCenter = facA * a.imgXCenter + facB * b.imgXCenter; + imgYCenter = facA * a.imgYCenter + facB * b.imgYCenter; + scaleFac = facA * a.scaleFac + facB * b.scaleFac; + meanErr = facA * a.meanErr + facB * b.meanErr; + + for (int i=0;i<5;i++) param[i]= facA * a.param[i] + facB * b.param[i]; +} + +void 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 + int Dmax=fullWidth; if (fullHeight>fullWidth) Dmax=fullHeight; + + // correct focLens + if (focLenX<0) { // they may not be given + // and 35mm may not be given either + if (focalLength35mm<1) focalLength35mm = focalLength*sensorFormatFactor; + + focLenX=focLenY=focalLength / ( 35*focalLength/focalLength35mm); // focLen must be calculated in pixels + } + + if (swapXY) { + x0 = (mirrorX ? 1.-imgYCenter : imgYCenter) * fullWidth; + y0 = (mirrorY ? 1.-imgXCenter : imgXCenter) * fullHeight; + fx = focLenY * Dmax; + fy = focLenX * Dmax; + } else { + x0 = (mirrorX ? 1.-imgXCenter : imgXCenter) * fullWidth; + y0 = (mirrorY ? 1.-imgYCenter : imgYCenter) * fullHeight; + fx = focLenX * Dmax; + fy = focLenY * Dmax; + } + //printf("FW %i /X0 %g FH %i /Y0 %g %g\n",fullWidth,x0,fullHeight,y0, imgYCenter); +} + +LCPPersModel::LCPPersModel() { + focLen=focDist=aperture=0; +} + +// mode: 0=distortion, 1=vignette, 2=CA +bool LCPPersModel::hasModeData(int mode) const { + return (mode==0 && !vignette.empty() && !vignette.badErr) || (mode==1 && !base.empty() && !base.badErr) + || (mode==2 && !chromRG.empty() && !chromG.empty() && !chromBG.empty() && + !chromRG.badErr && !chromG.badErr && !chromBG.badErr); +} + +void LCPPersModel::print() const { + printf("--- PersModel focLen %g; focDist %g; aperture %g\n", focLen, focDist, aperture); + printf("Base:\n"); base.print(); + if (!chromRG.empty()) { printf("ChromRG:\n"); chromRG.print(); } + if (!chromG.empty()) { printf("ChromG:\n"); chromG.print(); } + if (!chromBG.empty()) { printf("ChromBG:\n"); chromBG.print(); } + if (!vignette.empty()) { printf("Vignette:\n"); vignette.print(); } + 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) +{ + if (pProf==NULL) return; + + useCADist=useCADistP; + + // determine in what the image with the RAW landscape in comparison (calibration target) + // in vignetting, the rotation has not taken place yet + int rot = 0; + if (rawRotationDeg>=0) rot=(coarse.rotate+rawRotationDeg) % 360; + + swapXY = (rot==90 || rot==270); + bool mirrorX = (rot==90 || rot==180); + bool mirrorY = (rot==180 || rot==270); + //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, NULL, NULL); + 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]); + for (int i=0;i<3;i++) chrom[i].prepareParams(fullWidth, fullHeight, focalLength, focalLength35mm, pProf->sensorFormatFactor, swapXY, mirrorX, mirrorY); + } + + enableCA = !vignette && focusDist>0; +} + +void LCPMapper::correctDistortion(double& x, double& y) const { + double xd=(x-mc.x0)/mc.fx, yd=(y-mc.y0)/mc.fy; + + const float* aDist = mc.param; + double rsqr = xd*xd+yd*yd; + double xfac=aDist[swapXY?3:4], yfac=aDist[swapXY?4:3]; + + 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; + + x = xnew * mc.fx + mc.x0; + y = ynew * mc.fy + mc.y0; +} + +void LCPMapper::correctCA(double& x, double& y, int channel) const { + if (!enableCA) return; + + double rsqr, 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; + + // Green contains main distortion, just like base + if (useCADist) { + const float* aDist = chrom[1].param; + double rsqr = xd*xd+yd*yd; + double xfac=aDist[swapXY?3:4], yfac=aDist[swapXY?4:3]; + + double commonFac = (((aDist[2]*rsqr + aDist[1])*rsqr + aDist[0])*rsqr + 1.) + + 2. * (yfac * yd + xfac * xd); + + xgreen = xd * commonFac + aDist[4] * rsqr; + ygreen = yd * commonFac + aDist[3] * rsqr; + } else { + xgreen=xd; ygreen=yd; + } + + if (channel==1) { + // green goes directly + x = xgreen * chrom[1].fx + chrom[1].x0; + y = ygreen * chrom[1].fy + chrom[1].y0; + } else { + // others are diffs from green + xd=xgreen; yd=ygreen; + rsqr=xd*xd+yd*yd; + + const float* 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); + + x = (chrom[channel].scaleFac * ( xd * commonSum + xfac*rsqr )) * chrom[channel].fx + chrom[channel].x0; + y = (chrom[channel].scaleFac * ( yd * commonSum + yfac*rsqr )) * chrom[channel].fy + chrom[channel].y0; + } +} + +float LCPMapper::calcVignetteFac(int x, int y) const { + // No need for swapXY, since vignette is in RAW and always before rotation + double xd=((double)x-mc.x0)/mc.fx, yd=((double)y-mc.y0)/mc.fy; + + const float* aVig= mc.param; + double rsqr = xd*xd+yd*yd; + double param0Sqr = aVig[0]*aVig[0]; + + return 1. + rsqr * (-aVig[0] + rsqr * ((param0Sqr - aVig[1]) + - (param0Sqr*aVig[0] - 2.*aVig[0]*aVig[1] + aVig[2]) *rsqr + + (param0Sqr*param0Sqr + aVig[1]*aVig[1] + + 2.*aVig[0]*aVig[2] - 3.*param0Sqr*aVig[1]) *rsqr*rsqr)); +} + +LCPProfile::LCPProfile(Glib::ustring fname) { + const int BufferSize=8192; + char buf[BufferSize]; + + XML_Parser parser = XML_ParserCreate(NULL); + 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; + for (int i=0;ihasModeData(0)) { + errVignette+=aPersModel[pm]->vignette.meanErr; + vignetteCount++; + } + + if (aPersModel[pm]->hasModeData(1)) { + errBase+=aPersModel[pm]->base.meanErr; + baseCount++; + } + + if (aPersModel[pm]->hasModeData(2)) { + errChrom+=std::max(std::max(aPersModel[pm]->chromRG.meanErr,aPersModel[pm]->chromG.meanErr),aPersModel[pm]->chromBG.meanErr); + 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;pmhasModeData(0) && aPersModel[pm]->vignette.meanErr > maxAvgDevFac * errVignette) { + aPersModel[pm]->vignette.badErr=true; + filtered++; + } + + if (aPersModel[pm]->hasModeData(1) && aPersModel[pm]->base.meanErr > maxAvgDevFac * errBase) { + aPersModel[pm]->base.badErr=true; + filtered++; + } + + if (aPersModel[pm]->hasModeData(2) && + (aPersModel[pm]->chromRG.meanErr > maxAvgDevFac * errChrom || aPersModel[pm]->chromG.meanErr > maxAvgDevFac * errChrom + || aPersModel[pm]->chromBG.meanErr > maxAvgDevFac * errChrom)) { + aPersModel[pm]->chromRG.badErr=aPersModel[pm]->chromG.badErr=aPersModel[pm]->chromBG.badErr=true; + filtered++; + } + } + + //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=NULL, *pHigh=NULL; + + 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;pmfocLen; + + if (aPersModel[pm]->hasModeData(mode)) { + if (f <= focalLength && (pLow==NULL || f > pLow->focLen || (focusDist==0 && f==pLow->focLen && pLow->focDist>aPersModel[pm]->focDist))) { + pLow=aPersModel[pm]; + } + if (f >= focalLength && (pHigh==NULL || f < pHigh->focLen || (focusDist==0 && f==pHigh->focLen && pHigh->focDistfocDist))) { + 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;pmaperture; // float aperLog=log(aper); + float focDist=aPersModel[pm]->focDist; float focDistLog=log(focDist)+euler; + double meanErr; + + if (aPersModel[pm]->hasModeData(mode)) { + if (mode==0) { + meanErr=aPersModel[pm]->vignette.meanErr; + + // by aperture (vignette), and max out focus distance + // tests showed doing this by log(aperture) is not as advisable + if (aPersModel[pm]->focLen==bestFocLenLow && ( + (aper==aperture && pLow->vignette.meanErr>meanErr) + || (aper>=aperture && aperaperture && pLow->aperture > aperture) + || (aper<=aperture && (pLow->aperture>aperture || fabs(aperture-aper)aperture))))) { + pLow=aPersModel[pm]; + } + if (aPersModel[pm]->focLen==bestFocLenHigh && ( + (aper==aperture && pHigh->vignette.meanErr>meanErr) + || (aper<=aperture && aper>pHigh->aperture && pHigh->aperture < aperture) + || (aper>=aperture && (pHigh->apertureaperture))))) { + pHigh=aPersModel[pm]; + } + } else { + meanErr = (mode==1 ? aPersModel[pm]->base.meanErr : aPersModel[pm]->chromG.meanErr); + + if (focusDist>0) { + // by focus distance + if (aPersModel[pm]->focLen==bestFocLenLow && ( + (focDist==focusDist && (mode==1 ? pLow->base.meanErr : pLow->chromG.meanErr)>meanErr) + || (focDist>=focusDist && focDistfocDist && pLow->focDist > focusDist) + || (focDist<=focusDist && (pLow->focDist>focusDist || fabs(focusDistLog-focDistLog)focDist)+euler)))))) { + pLow=aPersModel[pm]; + } + if (aPersModel[pm]->focLen==bestFocLenHigh && ( + (focDist==focusDist && (mode==1 ? pHigh->base.meanErr : pHigh->chromG.meanErr)>meanErr) + || (focDist<=focusDist && focDist>pHigh->focDist && pHigh->focDist < focusDist) + || (focDist>=focusDist && (pHigh->focDistfocDist)+euler)))))) { + pHigh=aPersModel[pm]; + } + } else { + // no focus distance available, just error + if (aPersModel[pm]->focLen==bestFocLenLow && (mode==1 ? pLow->base.meanErr : pLow->chromG.meanErr)>meanErr) { + pLow=aPersModel[pm]; + } + if (aPersModel[pm]->focLen==bestFocLenHigh && (mode==1 ? pHigh->base.meanErr : pHigh->chromG.meanErr)>meanErr) { + pHigh=aPersModel[pm]; + } + } + } + } + } + } + + if (pLow!=NULL && pHigh!=NULL) { + // 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; + } + + //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 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;pmprint(); +} + +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==NULL) 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!=NULL) { + for (int i = 0; attr[i]; i += 2) { + const char* nameStart=strrchr(attr[i],':'); + if (nameStart==NULL) nameStart=const_cast(attr[i]); else nameStart++; + + strcpy(pProf->lastTag, nameStart); + 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; + + // Check if it contains non-whitespaces (there are several calls to this for one tag unfortunately) + bool onlyWhiteSpace=true; + int i=0; + while (ilastTag; + + // 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) { + char* p=raw; + while (*p) { + if (*p=='.') *p=','; + p++; + } + } + + 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->focLenX=atof(raw); + else if (!strcmp("FocalLengthY",tag)) + pProf->pCurCommon->focLenY=atof(raw); + else if (!strcmp("ImageXCenter",tag)) + pProf->pCurCommon->imgXCenter=atof(raw); + else if (!strcmp("ImageYCenter",tag)) + pProf->pCurCommon->imgYCenter=atof(raw); + else if (!strcmp("ScaleFactor",tag)) + pProf->pCurCommon->scaleFac=atof(raw); + else if (!strcmp("ResidualMeanError",tag)) + pProf->pCurCommon->meanErr=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); + + // 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=NULL; + pProf->persModelCount++; + } +} + +// Generates as singleton +LCPStore* LCPStore::getInstance() +{ + static LCPStore* instance_ = 0; + if ( instance_ == 0 ) + { + static MyMutex smutex_; + MyMutex::MyLock lock(smutex_); + if ( instance_ == 0 ) + { + instance_ = new LCPStore(); + } + } + return instance_; +} + +LCPProfile* LCPStore::getProfile (Glib::ustring filename) { + if (filename.length()==0 || !isValidLCPFileName(filename)) return NULL; + + 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); + //profileCache[filename]->print(); + return profileCache[filename]; +} + +bool LCPStore::isValidLCPFileName(Glib::ustring filename) const { + if (!safe_file_test (filename, Glib::FILE_TEST_EXISTS) || safe_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}; char pathA[MAX_PATH]; + + 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 (safe_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 new file mode 100644 index 000000000..6d3707f74 --- /dev/null +++ b/rtengine/lcp.h @@ -0,0 +1,132 @@ +/* +* This file is part of RawTherapee. +* +* Copyright (c) 2012 Oliver Duis +* +* 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 _LCP_ +#define _LCP_ + +#include "imagefloat.h" +#include "../rtgui/threadutils.h" +#include +#include +#include +#include +#include + +namespace rtengine { + // Perspective model common data, also used for Vignette and Fisheye + class LCPModelCommon { + public: + float focLenX, focLenY, imgXCenter, imgYCenter; + float param[5]; // k1..k5, resp. alpha1..5 + float scaleFac; // alpha0 + double meanErr; + bool badErr; + + double x0,y0,fx,fy; // prepared params + + 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); + }; + + 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); + + public: + // Common data + Glib::ustring profileName, lensPrettyName, cameraPrettyName, lens, camera; // lens/camera(=model) can be auto-matched with DNG + bool isRaw,isFisheye; + float sensorFormatFactor; + int persModelCount; + + // The correction frames + static const int MaxPersModelCount=3000; + LCPPersModel* aPersModel[MaxPersModelCount]; // Do NOT use std::list or something, it's buggy in GCC! + + LCPProfile(Glib::ustring fname); + + 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; + + // Maps file name to profile as cache + std::map profileCache; + + public: + Glib::ustring getDefaultCommonDirectory() const; + bool isValidLCPFileName(Glib::ustring filename) const; + LCPProfile* getProfile(Glib::ustring filename); + + static LCPStore* getInstance(); + }; + +#define lcpStore LCPStore::getInstance() + + + // Once precalculated class to correct a point + class LCPMapper { + + bool useCADist; // should the distortion in the CA info be used? + bool swapXY; + LCPModelCommon mc; + LCPModelCommon chrom[3]; // in order RedGreen/Green/BlueGreen + + 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) const; // MUST be the first stage + void correctCA(double& x, double& y, int channel) const; + float calcVignetteFac (int x, int y) const; // MUST be in RAW + }; +} +#endif diff --git a/rtengine/loadinitial.cc b/rtengine/loadinitial.cc new file mode 100644 index 000000000..382ff4e09 --- /dev/null +++ b/rtengine/loadinitial.cc @@ -0,0 +1,47 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "rtengine.h" +#include "stdimagesource.h" +#include "rawimagesource.h" + +namespace rtengine { + +InitialImage* InitialImage::load (const Glib::ustring& fname, bool isRaw, int* errorCode, ProgressListener* pl) { + + ImageSource* isrc; + + if (!isRaw) + isrc = new StdImageSource (); + else + isrc = new RawImageSource (); + + isrc->setProgressListener (pl); + + if(isRaw && pl == NULL) + *errorCode = isrc->load (fname, true); + else + *errorCode = isrc->load (fname); + if (*errorCode) { + delete isrc; + return NULL; + } + return isrc; +} +} + diff --git a/rtengine/median.h b/rtengine/median.h new file mode 100644 index 000000000..185a7e409 --- /dev/null +++ b/rtengine/median.h @@ -0,0 +1,222 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#define SORT3(a1,a2,a3,b1,b2,b3) \ + { \ + if ((a1)<(a2)) { \ + if ((a2)<(a3)) { \ + (b1) = (a1); (b2) = (a2); (b3) = (a3); \ + } \ + else if ((a1)<(a3)) { \ + (b1) = (a1); (b2) = (a3); (b3) = (a2); \ + } \ + else { \ + (b1) = (a3); (b2) = (a1); (b3) = (a2); \ + } \ + } \ + else { \ + if ((a3)<(a2)) { \ + (b1) = (a3); (b2) = (a2); (b3) = (a1); \ + } \ + else if ((a3)<(a1)) { \ + (b1) = (a2); (b2) = (a3); (b3) = (a1); \ + } \ + else { \ + (b1) = (a2); (b2) = (a1); (b3) = (a3); \ + } \ + } \ + } + +#define MERGESORT(a1,a2,a3,b1,b2,b3,c1,c2,c3,c4,c5,c6) \ + {\ + if (a1 + * + * 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 . + */ +#define MINMAX3(a,b,c,min,max) \ +{ \ +if ((a)<(b)) { \ + if ((b)<(c)) { \ + (min) = (a); \ + (max) = (c); \ + } \ + else { \ + (max) = (b); \ + if ((a)<(c)) \ + (min) = (a); \ + else \ + (min) = (c); \ + } \ +} else { \ + if ((b)>(c)) { \ + (min) = (c); \ + (max) = (a); \ + } \ + else { \ + (min) = (b); \ + if ((a)>(c)) \ + (max) = (a); \ + else \ + (max) = (c); \ + } \ +} \ +} + +#define MIN3(a,b,c,min) \ +{ \ +if ((a)<(b)) { \ + if ((a)<(c)) \ + (min) = (a); \ + else \ + (min) = (c); \ +} else { \ + if ((b)>(c)) \ + (min) = (c); \ + else \ + (min) = (b); \ +} \ +} + +#define MAX3(a,b,c,min) \ +{ \ +if ((a)>(b)) { \ + if ((a)>(c)) \ + (max) = (a); \ + else \ + (max) = (c); \ +} else { \ + if ((b)<(c)) \ + (max) = (c); \ + else \ + (max) = (b); \ +} \ +} diff --git a/rtengine/myfile.cc b/rtengine/myfile.cc new file mode 100755 index 000000000..49372942d --- /dev/null +++ b/rtengine/myfile.cc @@ -0,0 +1,382 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "myfile.h" +#include +#include +#include "safegtk.h" +#ifdef BZIP_SUPPORT +#include +#endif + +// get mmap() sorted out +#ifdef MYFILE_MMAP + +#ifdef WIN32 + +#include +#include + +// dummy values +#define MAP_PRIVATE 1 +#define PROT_READ 1 +#define MAP_FAILED (void *)-1 + +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); + + if (handle != NULL) { + start = MapViewOfFile(handle, FILE_MAP_COPY, 0, offset, length); + CloseHandle(handle); + return start; + } + + return MAP_FAILED; +} + +int munmap(void *start, size_t length) +{ + UnmapViewOfFile(start); + return 0; +} + +#else // WIN32 + +#include +#include + +#endif // WIN32 +#endif // MYFILE_MMAP + +#ifdef MYFILE_MMAP + +IMFILE* fopen (const char* fname) +{ + int fd = safe_open_ReadOnly(fname); + if ( fd < 0 ) + return 0; + + struct stat stat_buffer; + if ( fstat(fd,&stat_buffer) < 0 ) + { + printf("no stat\n"); + close(fd); + return 0; + } + + void* data = mmap(0,stat_buffer.st_size,PROT_READ,MAP_PRIVATE,fd,0); + if ( data == MAP_FAILED ) + { + printf("no mmap\n"); + close(fd); + return 0; + } + + IMFILE* mf = new IMFILE; + + memset(mf, 0, sizeof(*mf)); + mf->fd = fd; + mf->pos = 0; + mf->size = stat_buffer.st_size; + mf->data = (char*)data; + mf->eof = false; + +#ifdef BZIP_SUPPORT + { + bool bzip = false; + Glib::ustring bname = Glib::path_get_basename(fname); + size_t lastdot = bname.find_last_of ('.'); + if (lastdot!=bname.npos) + bzip = bname.substr (lastdot).casefold() == Glib::ustring(".bz2").casefold(); + + if (bzip) { + int ret; + + // initialize bzip stream structure + bz_stream stream; + stream.bzalloc = 0; + stream.bzfree = 0; + stream.opaque = 0; + ret = BZ2_bzDecompressInit(&stream, 0, 0); + + if (ret != BZ_OK) { + printf("bzip initialization failed with error %d\n", ret); + } + else { + // allocate initial buffer for decompressed data + unsigned int buffer_out_count = 0; // bytes of decompressed data + unsigned int buffer_size = 10*1024*1024; // 10 MB, extended dynamically if needed + char* buffer = 0; + + stream.next_in = mf->data; // input data address + stream.avail_in = mf->size; + + while (ret == BZ_OK) { + buffer = static_cast( realloc(buffer, buffer_size)); // allocate/resize buffer + if (!buffer) free(buffer); + + stream.next_out = buffer + buffer_out_count; // output data adress + stream.avail_out = buffer_size - buffer_out_count; + + ret = BZ2_bzDecompress(&stream); + + buffer_size *= 2; // increase buffer size for next iteration + buffer_out_count = stream.total_out_lo32; + if (stream.total_out_hi32 > 0) + printf("bzip decompressed data byte count high byte is nonzero: %d\n", stream.total_out_hi32); + } + + if (ret == BZ_STREAM_END) { + //delete [] mf->data; + // close memory mapping, setting fd -1 will ensure deletion of mf->data upon fclose() + mf->fd = -1; + munmap((void*)mf->data,mf->size); + close(mf->fd); + + char* realData = new char [buffer_out_count]; + memcpy(realData, buffer, buffer_out_count); + + mf->data = realData; + mf->size = buffer_out_count; + } + else + printf("bzip decompression failed with error %d\n", ret); + + // cleanup + free(buffer); + ret = BZ2_bzDecompressEnd(&stream); + if (ret != BZ_OK) + printf("bzip cleanup failed with error %d\n", ret); + } + } + } +#endif // BZIP_SUPPORT + + return mf; +} + +IMFILE* gfopen (const char* fname) +{ + return fopen(fname); +} +#else + +IMFILE* fopen (const char* fname) { + + FILE* f = g_fopen (fname, "rb"); + if (!f) + return NULL; + IMFILE* mf = new IMFILE; + memset(mf, 0, sizeof(*mf)); + fseek (f, 0, SEEK_END); + mf->size = ftell (f); + mf->data = new char [mf->size]; + fseek (f, 0, SEEK_SET); + fread (mf->data, 1, mf->size, f); + fclose (f); + mf->pos = 0; + mf->eof = false; + + return mf; +} + +IMFILE* gfopen (const char* fname) { + + FILE* f = g_fopen (fname, "rb"); + if (!f) + return NULL; + IMFILE* mf = new IMFILE; + memset(mf, 0, sizeof(*mf)); + fseek (f, 0, SEEK_END); + mf->size = ftell (f); + mf->data = new char [mf->size]; + fseek (f, 0, SEEK_SET); + fread (mf->data, 1, mf->size, f); + fclose (f); + mf->pos = 0; + mf->eof = false; + +#ifdef BZIP_SUPPORT + { + bool bzip = false; + Glib::ustring bname = Glib::path_get_basename(fname); + size_t lastdot = bname.find_last_of ('.'); + if (lastdot!=bname.npos) + bzip = bname.substr (lastdot).casefold() == Glib::ustring(".bz2").casefold(); + + if (bzip) { + int ret; + + // initialize bzip stream structure + bz_stream stream; + stream.bzalloc = 0; + stream.bzfree = 0; + stream.opaque = 0; + ret = BZ2_bzDecompressInit(&stream, 0, 0); + + if (ret != BZ_OK) { + printf("bzip initialization failed with error %d\n", ret); + } + else { + // allocate initial buffer for decompressed data + unsigned int buffer_out_count = 0; // bytes of decompressed data + unsigned int buffer_size = 10*1024*1024; // 10 MB, extended dynamically if needed + char* buffer = 0; + + stream.next_in = mf->data; // input data address + stream.avail_in = mf->size; + + while (ret == BZ_OK) { + buffer = static_cast( realloc(buffer, buffer_size)); // allocate/resize buffer + if (!buffer) free(buffer); + + stream.next_out = buffer + buffer_out_count; // output data adress + stream.avail_out = buffer_size - buffer_out_count; + + ret = BZ2_bzDecompress(&stream); + + buffer_size *= 2; // increase buffer size for next iteration + buffer_out_count = stream.total_out_lo32; + if (stream.total_out_hi32 > 0) + printf("bzip decompressed data byte count high byte is nonzero: %d\n", stream.total_out_hi32); + } + + if (ret == BZ_STREAM_END) { + delete [] mf->data; + char* realData = new char [buffer_out_count]; + memcpy(realData, buffer, buffer_out_count); + + mf->data = realData; + mf->size = buffer_out_count; + } + else + printf("bzip decompression failed with error %d\n", ret); + + // cleanup + free(buffer); + ret = BZ2_bzDecompressEnd(&stream); + if (ret != BZ_OK) + printf("bzip cleanup failed with error %d\n", ret); + } + } + } +#endif // BZIP_SUPPORT + return mf; +} +#endif //MYFILE_MMAP + +IMFILE* fopen (unsigned* buf, int size) { + + IMFILE* mf = new IMFILE; + memset(mf, 0, sizeof(*mf)); + mf->fd = -1; + mf->size = size; + mf->data = new char [mf->size]; + memcpy ((void*)mf->data, buf, size); + mf->pos = 0; + mf->eof = false; + return mf; +} + +void fclose (IMFILE* f) { +#ifdef MYFILE_MMAP + if ( f->fd == -1 ) + { + delete [] f->data; + } + else + { + munmap((void*)f->data,f->size); + close(f->fd); + } +#else + delete [] f->data; +#endif + delete f; +} + +int fscanf (IMFILE* f, const char* s ...) { + // fscanf not easily wrapped since we have no terminating \0 at end + // of file data and vsscanf() won't tell us how many characters that + // were parsed. However, only dcraw.cc code use it and only for "%f" and + // "%d", so we make a dummy fscanf here just to support dcraw case. + char buf[50], *endptr; + int copy_sz = f->size - f->pos; + if (copy_sz > sizeof(buf)) { + copy_sz = sizeof(buf) - 1; + } + memcpy(buf, &f->data[f->pos], copy_sz); + buf[copy_sz] = '\0'; + va_list ap; + va_start (ap, s); + if (strcmp(s, "%d") == 0) { + int i = strtol(buf, &endptr, 10); + if (endptr == buf) { + return 0; + } + int *pi = va_arg(ap, int*); + *pi = i; + } else if (strcmp(s, "%f") == 0) { + float f = strtof(buf, &endptr); + if (endptr == buf) { + return 0; + } + float *pf = va_arg(ap, float*); + *pf = f; + } + va_end (ap); + f->pos += endptr - buf; + return 1; +} + + +char* fgets (char* s, int n, IMFILE* f) { + + if (f->pos>=f->size) { + f->eof = true; + return NULL; + } + int i = 0; + do s[i++] = f->data[f->pos++]; + while (ipossize); + return s; +} + +void imfile_set_plistener(IMFILE *f, rtengine::ProgressListener *plistener, double progress_range) { + f->plistener = plistener; + f->progress_range = progress_range; + f->progress_next = f->size / 10 + 1; + f->progress_current = 0; +} + +void imfile_update_progress(IMFILE *f) { + if (!f->plistener || f->progress_current < f->progress_next) { + return; + } + do { + f->progress_next += f->size / 10 + 1; + } while (f->progress_next < f->progress_current); + double p = (double)f->progress_current / f->size; + if (p > 1.0) { + /* this can happen if same bytes are read over and over again. Progress bar is not intended + to be exact, just give some progress indication for normal raw file access patterns */ + p = 1.0; + } + f->plistener->setProgress(p * f->progress_range); +} diff --git a/rtengine/myfile.h b/rtengine/myfile.h new file mode 100755 index 000000000..8870c66a8 --- /dev/null +++ b/rtengine/myfile.h @@ -0,0 +1,121 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _MYFILE_ +#define _MYFILE_ + +#include +#include +#include +#include "rtengine.h" +struct IMFILE { + int fd; + ssize_t pos; + ssize_t size; + char* data; + bool eof; + rtengine::ProgressListener *plistener; + double progress_range; + ssize_t progress_next; + ssize_t progress_current; +}; + +/* + Functions for progress bar updates + Note: progress bar is not intended to be exact, eg if you read same data over and over again progress + will potentially reach 100% before you're finished. + */ +void imfile_set_plistener(IMFILE *f, rtengine::ProgressListener *plistener, double progress_range); +void imfile_update_progress(IMFILE *f); + +IMFILE* fopen (const char* fname); +IMFILE* gfopen (const char* fname);IMFILE* fopen (unsigned* buf, int size); +void fclose (IMFILE* f); +inline int ftell (IMFILE* f) { + + return f->pos; +} + +inline int feof (IMFILE* f) { + + return f->eof; +} + +inline void fseek (IMFILE* f, int p, int how) { + int fpos = f->pos; + + if (how==SEEK_SET) + f->pos = p; + else if (how==SEEK_CUR) + f->pos += p; + else if (how==SEEK_END) + f->pos = f->size+p; + + if (f->pos < 0 || f->pos> f->size) + f->pos = fpos; +} + +inline int fgetc (IMFILE* f) { + + if (f->possize) { + if (f->plistener && ++f->progress_current >= f->progress_next) { + imfile_update_progress(f); + } + return (unsigned char)f->data[f->pos++]; + } + f->eof = true; + return EOF; +} + +inline int getc (IMFILE* f) { + + return fgetc(f); +} + +inline int fread (void* dst, int es, int count, IMFILE* f) { + + int s = es*count; + int avail = f->size - f->pos; + if (s<=avail) { + memcpy (dst, f->data+f->pos, s); + f->pos += s; + if (f->plistener) { + f->progress_current += s; + if (f->progress_current >= f->progress_next) { + imfile_update_progress(f); + } + } + return count; + } + else { + memcpy (dst, f->data+f->pos, avail); + f->pos += avail; + f->eof = true; + return avail/es; + } +} + +inline unsigned char* fdata(int offset, IMFILE* f) { + return (unsigned char*)f->data + offset; +} + +int fscanf (IMFILE* f, const char* s ...); +char* fgets (char* s, int n, IMFILE* f); + +#endif + diff --git a/rtengine/mytime.h b/rtengine/mytime.h new file mode 100644 index 000000000..19b963ca8 --- /dev/null +++ b/rtengine/mytime.h @@ -0,0 +1,72 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _MYTIME_ +#define _MYTIME_ + +#ifdef WIN32 +#include +#elif defined __APPLE__ +#include +#else +#include +#endif + +class MyTime { + + public: +#ifndef WIN32 + timespec t; +#else + LONGLONG t; + LONGLONG baseFrequency; + MyTime(){ + LARGE_INTEGER ulf; + QueryPerformanceFrequency(&ulf); + baseFrequency = ulf.QuadPart; + QueryPerformanceCounter(&ulf); + t = ulf.QuadPart; + } +#endif + + void set () { +#ifdef WIN32 + LARGE_INTEGER ulf; + QueryPerformanceCounter(&ulf); + t = ulf.QuadPart; +#elif defined __APPLE__ + struct timeval tv; + gettimeofday(&tv, NULL); + t.tv_sec = tv.tv_sec; + t.tv_nsec = tv.tv_usec*1000; +#else + clock_gettime (CLOCK_REALTIME, &t); +#endif +} + + int etime (MyTime a) { +#ifndef WIN32 + return (t.tv_sec-a.t.tv_sec)*1000000 + (t.tv_nsec-a.t.tv_nsec)/1000; +#else + return (t - a.t)*1000/(baseFrequency/1000); +#endif + } +}; + + +#endif diff --git a/rtengine/opthelper.h b/rtengine/opthelper.h new file mode 100644 index 000000000..c6d8a63b0 --- /dev/null +++ b/rtengine/opthelper.h @@ -0,0 +1,75 @@ +//////////////////////////////////////////////////////////////// +// +// opthelper.h includes some #defines which help to make optimizations easier and better readable +// +// copyright (c) 2013 Ingo Weyrich +// +// this is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +//////////////////////////////////////////////////////////////// + +#ifndef OPTHELPER_H + #define OPTHELPER_H + + #ifdef __SSE2__ + #include "sleefsseavx.c" + #ifdef __GNUC__ + #if defined(WIN32) && !defined( __x86_64__ ) + // needed for actual versions of GCC with 32-Bit Windows + #define SSEFUNCTION __attribute__((force_align_arg_pointer)) + #else + #define SSEFUNCTION + #endif + #else + #define SSEFUNCTION + #endif + #else + #ifdef __SSE__ + #ifdef __GNUC__ + #if defined(WIN32) && !defined( __x86_64__ ) + // needed for actual versions of GCC with 32-Bit Windows + #define SSEFUNCTION __attribute__((force_align_arg_pointer)) + #else + #define SSEFUNCTION + #endif + #else + #define SSEFUNCTION + #endif + #else + #define SSEFUNCTION + #endif + #endif + + #ifdef __GNUC__ + #define RESTRICT __restrict__ + #define LIKELY(x) __builtin_expect (!!(x), 1) + #define UNLIKELY(x) __builtin_expect (!!(x), 0) + #if __GNUC__ == 4 && __GNUC_MINOR__ >= 8 + #define ALIGNED64 __attribute__ ((aligned (64))) + #define ALIGNED16 __attribute__ ((aligned (16))) + #else // there is a bug in gcc 4.7.x when using openmp and aligned memory and -O3 + #define ALIGNED64 + #define ALIGNED16 + #endif + #else + #define RESTRICT + #define LIKELY(x) (x) + #define UNLIKELY(x) (x) + #define ALIGNED64 + #define ALIGNED16 + #endif + #ifndef __clang__ + #define _RT_NESTED_OPENMP _OPENMP + #endif +#endif diff --git a/rtengine/previewimage.cc b/rtengine/previewimage.cc new file mode 100644 index 000000000..3024a05a4 --- /dev/null +++ b/rtengine/previewimage.cc @@ -0,0 +1,193 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "previewimage.h" +#include "iimage.h" +#include "utils.h" +#include "iimage.h" +#include "rtthumbnail.h" +#include "rawimagesource.h" +#include "StopWatch.h" + +using namespace rtengine; +using namespace procparams; + +PreviewImage::PreviewImage (const Glib::ustring &fname, const Glib::ustring &ext, const PreviewImageMode mode) { + rtengine::Thumbnail* tpp=NULL; + + if (mode==PIM_EmbeddedPreviewOnly || mode==PIM_EmbeddedOrRaw) { + + const unsigned char *data = NULL; + + int width=-1, height=-1; + if (ext.lowercase()=="jpg" || ext.lowercase()=="jpeg") { + // int deg = infoFromImage (fname); + tpp = rtengine::Thumbnail::loadFromImage (fname, width, height, 1, 1., true); + if (tpp) + data = tpp->getImage8Data(); + } + else if (ext.lowercase()=="png") { + tpp = rtengine::Thumbnail::loadFromImage (fname, width, height, 1, 1., true); + if (tpp) + data = tpp->getImage8Data(); + } + else if (ext.lowercase()=="tif" || ext.lowercase()=="tiff") { + // int deg = infoFromImage (fname); + tpp = rtengine::Thumbnail::loadFromImage (fname, width, height, 1, 1., true); + if (tpp) + data = tpp->getImage8Data(); + } + else { + rtengine::RawMetaDataLocation ri; + tpp = rtengine::Thumbnail::loadQuickFromRaw (fname, ri, width, height, 1, true, true); + if (tpp) + data = tpp->getImage8Data(); + } + + if (tpp) { + if (data) { + int w, h; + double scale = 1.; + if (tpp) + tpp->getDimensions(w, h, scale); + previewImage = Cairo::ImageSurface::create(Cairo::FORMAT_RGB24, w, h); + previewImage->flush(); + +#pragma omp parallel +{ + const unsigned char *src; + unsigned char *dst; +#pragma omp for schedule(static,10) + for (unsigned int i=0; i<(unsigned int)(h); i++) { + src = data + i*w*3; + dst = previewImage->get_data() + i*w*4; + for (unsigned int j=0; j<(unsigned int)(w); j++) { + unsigned char r = *(src++); + unsigned char g = *(src++); + unsigned char b = *(src++); + +#if __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__ + *(dst++) = b; + *(dst++) = g; + *(dst++) = r; + *(dst++) = 0; +#else + *(dst++) = 0; + *(dst++) = r; + *(dst++) = g; + *(dst++) = b; +#endif + } + } +} + previewImage->mark_dirty(); + } + } + } + + if ((mode==PIM_EmbeddedOrRaw && !tpp) || mode==PIM_ForceRaw) { + RawImageSource rawImage; + int error = rawImage.load(fname, true); + if (!error) { + rtengine::Image8 *output = NULL; + const unsigned char *data = NULL; + int fw, fh; + procparams::ProcParams params; + /*rtengine::RAWParams raw; + rtengine::LensProfParams lensProf; + rtengine::procparams::ToneCurveParams toneCurve; + rtengine::procparams::ColorManagementParams icm; + rtengine::CoarseTransformParams coarse;*/ + ColorTemp wb = rawImage.getWB (); + rawImage.getFullSize (fw, fh, TR_NONE); + PreviewProps pp (0, 0, fw, fh, 1); + params.icm.input = Glib::ustring("(embedded)"); + params.raw.bayersensor.method = RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::fast]; + params.raw.deadPixelFilter = false; + params.raw.ca_autocorrect = false; + params.raw.xtranssensor.method = RAWParams::XTransSensor::methodstring[RAWParams::XTransSensor::fast]; + rawImage.preprocess(params.raw, params.lensProf, params.coarse); + rawImage.demosaic(params.raw); + Imagefloat* image = new rtengine::Imagefloat (fw, fh); + rawImage.getImage (wb, TR_NONE, image, pp, params.toneCurve, params.icm, params.raw); + output = new Image8(fw, fh); + rawImage.convertColorSpace(image, params.icm, wb); + StopWatch Stop1("inspector loop"); +#pragma omp parallel for schedule(dynamic, 10) + for (int i=0; ir(i,j) = Color::gamma2curve[image->r(i,j)]; + image->g(i,j) = Color::gamma2curve[image->g(i,j)]; + image->b(i,j) = Color::gamma2curve[image->b(i,j)]; + } + Stop1.stop(); + + image->resizeImgTo(fw, fh, TI_Nearest, output); + data = output->getData(); + + + if (data) { + int w, h; + double scale = 1.; + w = output->getWidth(); + h = output->getHeight(); + previewImage = Cairo::ImageSurface::create(Cairo::FORMAT_RGB24, w, h); + previewImage->flush(); + +#pragma omp parallel +{ + const unsigned char *src; + unsigned char *dst; +#pragma omp for schedule(static,10) + for (unsigned int i=0; i<(unsigned int)(h); i++) { + src = data + i*w*3; + dst = previewImage->get_data() + i*w*4; + for (unsigned int j=0; j<(unsigned int)(w); j++) { + unsigned char r = *(src++); + unsigned char g = *(src++); + unsigned char b = *(src++); +#if __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__ + *(dst++) = b; + *(dst++) = g; + *(dst++) = r; + *(dst++) = 0; +#else + *(dst++) = 0; + *(dst++) = r; + *(dst++) = g; + *(dst++) = b; +#endif + } + } +} + if (output) + delete output; + previewImage->mark_dirty(); + } + } + } + + if (tpp) + delete tpp; + +} + +Cairo::RefPtr PreviewImage::getImage() { + return previewImage; +} diff --git a/rtengine/previewimage.h b/rtengine/previewimage.h new file mode 100644 index 000000000..6f78dc960 --- /dev/null +++ b/rtengine/previewimage.h @@ -0,0 +1,54 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _PREVIEWIMAGE_ +#define _PREVIEWIMAGE_ + +#include +#include "cairomm/cairomm.h" + +namespace rtengine { + +/** @brief Get a quick preview image out of a raw or standard file + * + * This class reads the full size preview image (at least the biggest one available) from the raw file, + * or the fast demosaiced version if no suitable embedded preview is found. + * + * For standard image, it simply read it with fast conversion for 32 bits images + */ +class PreviewImage { + +private: + Cairo::RefPtr previewImage; + +public: + typedef enum mode { + PIM_EmbeddedPreviewOnly, /// Get the embedded image only, fail if doesn't exist + PIM_EmbeddedOrRaw, /// Get the embedded image if it exist, or use the raw file otherwise + PIM_ForceRaw /// Get a preview of the raw file, even if an embedded image exist + } PreviewImageMode; + + PreviewImage (const Glib::ustring &fname, const Glib::ustring &ext, const PreviewImageMode mode); + + Cairo::RefPtr getImage(); + +}; + +} + +#endif diff --git a/rtengine/processingjob.cc b/rtengine/processingjob.cc new file mode 100644 index 000000000..6b1c30d28 --- /dev/null +++ b/rtengine/processingjob.cc @@ -0,0 +1,39 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "processingjob.h" + +namespace rtengine { + +ProcessingJob* ProcessingJob::create (const Glib::ustring& fname, bool isRaw, const procparams::ProcParams& pparams) { + + return new ProcessingJobImpl (fname, isRaw, pparams); +} + +ProcessingJob* ProcessingJob::create (InitialImage* initialImage, const procparams::ProcParams& pparams) { + + return new ProcessingJobImpl (initialImage, pparams); +} + +void ProcessingJob::destroy (ProcessingJob* job) { + + delete static_cast(job); +} + +} + diff --git a/rtengine/processingjob.h b/rtengine/processingjob.h new file mode 100644 index 000000000..800b58820 --- /dev/null +++ b/rtengine/processingjob.h @@ -0,0 +1,45 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _PROCESSINGJOB_ +#define _PROCESSINGJOB_ + +#include "rtengine.h" + +namespace rtengine { + +class ProcessingJobImpl : public ProcessingJob { + + public: + Glib::ustring fname; + bool isRaw; + InitialImage* initialImage; + procparams::ProcParams pparams; + + ProcessingJobImpl (const Glib::ustring& fn, bool iR, const procparams::ProcParams& pp) + : fname(fn), isRaw(iR), initialImage(NULL) { pparams = pp; } + + ProcessingJobImpl (InitialImage* iImage, const procparams::ProcParams& pp) + : fname(""), initialImage(iImage) { pparams = pp; iImage->increaseRef(); } + + ~ProcessingJobImpl () { if (initialImage) initialImage->decreaseRef(); } +}; + +} + +#endif diff --git a/rtengine/procevents.h b/rtengine/procevents.h new file mode 100644 index 000000000..2f926e545 --- /dev/null +++ b/rtengine/procevents.h @@ -0,0 +1,429 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef __PROCEVENT__ +#define __PROCEVENT__ + +namespace rtengine { + +enum ProcEvent { + EvPhotoLoaded=0, + EvProfileLoaded=1, + EvProfileChanged=2, + EvHistoryBrowsed=3, + EvBrightness=4, + EvContrast=5, + EvBlack=6, + EvExpComp=7, + EvHLCompr=8, + EvSHCompr=9, + EvToneCurve1=10, + EvAutoExp=11, + EvClip=12, + EvLBrightness=13, + EvLContrast=14, + EvLBlack=15, + EvLHLCompr=16, + EvLSHCompr=17, + EvLLCurve=18, + EvShrEnabled=19, + EvShrRadius=20, + EvShrAmount=21, + EvShrThresh=22, + EvShrEdgeOnly=23, + EvShrEdgeRadius=24, + EvShrEdgeTolerance=25, + EvShrHaloControl=26, + EvShrHaloAmount=27, + EvShrMethod=28, + EvShrDRadius=29, + EvShrDAmount=30, + EvShrDDamping=31, + EvShrDIterations=32, + EvLCPUseDist=33, + EvLCPUseVign=34, + EvLCPUseCA=35, + EvFixedExp=36, + EvWBMethod=37, + EvWBTemp=38, + EvWBGreen=39, + EvToneCurveMode1=40, + EvToneCurve2=41, + EvToneCurveMode2=42, + EvLDNRadius=43, // obsolete + EvLDNEdgeTolerance=44, // obsolete + EvCDNEnabled=45, // obsolete + EvBlendCMSMatrix=46, + EvDCPToneCurve=47, + EvDCPIlluminant=48, + EvSHEnabled=49, + EvSHHighlights=50, + EvSHShadows=51, + EvSHHLTonalW=52, + EvSHSHTonalW=53, + EvSHLContrast=54, + EvSHRadius=55, + EvCTRotate=56, + EvCTHFlip=57, + EvCTVFlip=58, + EvROTDegree=59, + EvTransAutoFill=60, + EvDISTAmount=61, + EvBookmarkSelected=62, + EvCrop=63, + EvCACorr=64, + EvHREnabled=65, + EvHRAmount=66, //obsolete + EvHRMethod=67, + EvWProfile=68, + EvOProfile=69, + EvIProfile=70, + EvVignettingAmount=71, + EvChMixer=72, + EvResizeScale=73, + EvResizeMethod=74, + EvExif=75, + EvIPTC=76, + EvResizeSpec=77, + EvResizeWidth=78, + EvResizeHeight=79, + EvResizeEnabled=80, + EvProfileChangeNotification=81, + EvSHHighQuality=82, + EvPerspCorr=83, + EvLCPFile=84, + EvRGBrCurveLumamode=85, + EvIDNEnabled=86, + EvIDNThresh=87, + EvDPDNEnabled=88, + EvDPDNLuma=89, + EvDPDNChroma=90, + EvDPDNGamma=91, + EvDirPyrEqualizer=92, + EvDirPyrEqlEnabled=93, + EvLSaturation=94, + EvLaCurve=95, + EvLbCurve=96, + EvDemosaicMethod=97, + EvPreProcessHotPixel=98, + EvSaturation=99, + EvHSVEqualizerH=100, + EvHSVEqualizerS=101, + EvHSVEqualizerV=102, + EvHSVEqEnabled=103, + EvDefringeEnabled=104, + EvDefringeRadius=105, + EvDefringeThreshold=106, + EvHLComprThreshold=107, + EvResizeBoundingBox=108, + EvResizeAppliesTo=109, + EvLAvoidColorShift=110, + EvLSatLimiter=111, // obsolete + EvLRSTProtection=112, + EvDemosaicDCBIter=113, + EvDemosaicFalseColorIter=114, + EvDemosaicDCBEnhanced=115, + EvPreProcessCARed=116, + EvPreProcessCABlue=117, + EvPreProcessLineDenoise=118, + EvPreProcessGEquilThresh=119, + EvPreProcessAutoCA=120, + EvPreProcessAutoDF=121, + EvPreProcessDFFile=122, + EvPreProcessExpCorrLinear=123, + EvPreProcessExpCorrPH=124, + EvFlatFieldFile=125, + EvFlatFieldAutoSelect=126, + EvFlatFieldBlurRadius=127, + EvFlatFieldBlurType=128, + EvAutoDIST=129, + EvDPDNLumCurve=130, + EvDPDNChromCurve=131, + EvGAMMA=132, + EvGAMPOS=133, + EvGAMFREE=134, + EvSLPOS=135, + EvPreProcessExpBlackzero=136, + EvPreProcessExpBlackone=137, + EvPreProcessExpBlacktwo=138, + EvPreProcessExpBlackthree=139, + EvPreProcessExptwoGreen=140, + EvSharpenEdgePasses=141, + EvSharpenEdgeAmount=142, + EvSharpenMicroAmount=143, + EvSharpenMicroUniformity=144, + EvSharpenEdgeEnabled=145, + EvSharpenEdgeThreechannels=146, + EvSharpenMicroEnabled=147, + EvSharpenMicroMatrix=148, + EvDemosaicALLEnhanced=149, // Disabled but not removed for now, may be reintroduced some day + EvVibranceEnabled=150, + EvVibrancePastels=151, + EvVibranceSaturated=152, + EvVibranceProtectSkins=153, + EvVibranceAvoidColorShift=154, + EvVibrancePastSatTog=155, + EvVibrancePastSatThreshold=156, + EvEPDStrength=157, + EvEPDEdgeStopping=158, + EvEPDScale=159, + EvEPDReweightingIterates=160, + EvEPDEnabled=161, + EvRGBrCurve=162, + EvRGBgCurve=163, + EvRGBbCurve=164, + EvNeutralExp=165, + EvDemosaicMethodPreProc=166, + EvLCCCurve=167, + EvLCHCurve=168, + EvVibranceSkinTonesCurve=169, + EvLLCCurve=170, + EvLLCredsk=171, + EvDPDNLdetail=172, + EvCATEnabled=173, + EvCATDegree=174, + EvCATMethodsur=175, + EvCATAdapscen=176, + EvCATAdapLum=177, + EvCATMethodWB=178, + EvCATJLight=179, + EvCATChroma=180, + EvCATAutoDegree=181, + EvCATContrast=182, + EvCATsurr=183, + EvCATgamut=184, + EvCATMethodalg=185, + EvCATRstpro=186, + EvCATQbright=187, + EvCATQContrast=188, + EvCATSChroma=189, + EvCATMChroma=190, + EvCAThue=191, + EvCATCurve1=192, + EvCATCurve2=193, + EvCATCurveMode1=194, + EvCATCurveMode2=195, + EvCATCurve3=196, + EvCATCurveMode3=197, + EvCATdatacie=198, + EvCATtonecie=199, + EvDPDNredchro=200, + EvDPDNbluechro=201, + EvDPDNmet=202, +// EvDPDNperform=201, + EvDemosaicLMMSEIter=203, + EvCATbadpix=204, + EvCATAutoAdap=205, + EvPFCurve=206, + EvWBequal=207, + EvWBequalbo=208, + EvGradientDegree=209, + EvGradientEnabled=210, + EvPCVignetteStrength=211, + EvPCVignetteEnabled=212, + EvBWChmixEnabled=213, + EvBWred=214, + EvBWgreen=215, + EvBWblue=216, + EvBWredgam=217, + EvBWgreengam=218, + EvBWbluegam=219, + EvBWfilter=220, + EvBWsetting=221, + EvBWoran=222, + EvBWyell=223, + EvBWcyan=224, + EvBWmag=225, + EvBWpur=226, + EvBWLuminanceEqual=227, + EvBWChmixEnabledLm=228, + EvBWmethod=229, + EvBWBeforeCurve=230, + EvBWBeforeCurveMode=231, + EvBWAfterCurve=232, + EvBWAfterCurveMode=233, + EvAutoch=234, +// EvFixedch=235, -- can be reused -- + EvNeutralBW=236, + EvGradientFeather=237, + EvGradientStrength=238, + EvGradientCenter=239, + EvPCVignetteFeather=240, + EvPCVignetteRoundness=241, + EvVignettingRadius=242, + EvVignettingStrenght=243, + EvVignettingCenter=244, + EvLCLCurve=245, + EvLLHCurve=246, + EvLHHCurve=247, + EvDirPyrEqualizerThreshold=248, + EvDPDNenhance=249, + EvBWMethodalg=250, + EvDirPyrEqualizerSkin=251, + EvDirPyrEqlgamutlab=252, + EvDirPyrEqualizerHueskin=253, +// EvDirPyrEqualizeralg=254, + EvDPDNmedian=254, + EvDPDNmedmet=255, + EvColorToningEnabled=256, + EvColorToningColor =257, + EvColorToningOpacity=258, + EvColorToningCLCurve=259, + EvColorToningMethod=260, +// EvColorToningTwocolor=259, + EvColorToningLLCurve=261, + EvColorToningredlow=262, + EvColorToninggreenlow=263, + EvColorToningbluelow=264, + EvColorToningredmed=265, + EvColorToninggreenmed=266, + EvColorToningbluemed=267, + EvColorToningredhigh=268, + EvColorToninggreenhigh=269, + EvColorToningbluehigh=270, + EvColorToningbalance=271, + EvColorToningNeutral=272, + EvColorToningsatlow=273, + EvColorToningsathigh=274, + EvColorToningTwocolor=275, + EvColorToningNeutralcur=276, + EvColorToningLumamode=277, + EvColorToningShadows=278, + EvColorToningHighights=279, + EvColorToningSatProtection=280, + EvColorToningSatThreshold=281, + EvColorToningStrength=282, + EvColorToningautosat=283, + EvDPDNmetmed=284, + EvDPDNrgbmet=285, + EvDPDNpasses=286, + EvFlatFieldClipControl=287, + EvFlatFieldAutoClipControl=288, + EvPreProcessExpBlackRed=289, + EvPreProcessExpBlackGreen=290, + EvPreProcessExpBlackBlue=291, + EvFilmSimulationEnabled=292, + EvFilmSimulationStrength=293, + EvFilmSimulationFilename=294, + EvDPDNLCurve=295, + EvDPDNsmet=296, + EvPreProcessDeadPixel=297, + EvDPDNCCCurve=298, + EvDPDNautochroma=299, + EvDPDNLmet=300, + EvDPDNCmet=301, + EvDPDNC2met=302, + EvWavelet=303, + EvWavEnabled=304, + EvWavLmet=305, + EvWavCLmet=306, + EvWavDirmeto=307, + EvWavtiles=308, + EvWavsky=309, + EvWavthres=310, + EvWavthr=311, + EvWavchroma=312, + EvWavmedian=313, + EvWavunif=314, + EvWavSkin=315, + EvWavHueskin=316, + EvWavThreshold=317, + EvWavlhl=318, + EvWavlbl=319, + EvWavThreshold2=320, + EvWavavoid=321, + EvWavCCCurve=322, + EvWavpast=323, + EvWavsat=324, + EvWavCHmet=325, + EvWavHSmet=326, + EvWavchro=327, + EvWavColor=328, + EvWavOpac=329, + EvWavsup=330, + EvWavTilesmet=331, + EvWavrescon=332, + EvWavreschro=333, + EvWavresconH=334, + EvWavthrH=335, + EvWavHueskin2=336, + EvWavedgrad=337, + EvWavedgval=338, + EvWavStrength=339, + EvWavdaubcoeffmet=340, + EvWavedgreinf=341, + EvWaveletch=342, + EvWavCHSLmet=343, + EvWavedgcont=344, + EvWavEDmet=345, + EvWavlev0nois=346, + EvWavlev1nois=347, + EvWavlev2nois=348, + EvWavmedianlev=349, + EvWavHHCurve=350, + EvWavBackmet=351, + EvWavedgedetect=352, + EvWavlipst=353, + EvWavedgedetectthr=354, + EvWavedgedetectthr2=355, + EvWavlinkedg=356, + EvWavCHCurve=357, + EvPreProcessHotDeadThresh=358, + EvEPDgamma=359, + EvWavtmr=360, + EvWavTMmet=361, + EvWavtmrs=362, + EvWavbalance=363, + EvWaviter=364, + EvWavgamma=365, + EvWavCLCurve=366, + EvWavopacity=367, + EvWavBAmet=368, + EvWavopacityWL=369, + EvPrShrEnabled=370, + EvPrShrRadius=371, + EvPrShrAmount=372, + EvPrShrThresh=373, + EvPrShrEdgeOnly=374, + EvPrShrEdgeRadius=375, + EvPrShrEdgeTolerance=376, + EvPrShrHaloControl=377, + EvPrShrHaloAmount=378, + EvPrShrMethod=379, + EvPrShrDRadius=380, + EvPrShrDAmount=381, + EvPrShrDDamping=382, + EvPrShrDIterations=383, + EvWavcbenab=384, + EvWavgreenhigh=385, + EvWavbluehigh=386, + EvWavgreenmed=387, + EvWavbluemed=388, + EvWavgreenlow=389, + EvWavbluelow=390, + EvWavNeutral=391, + EvDCPApplyLookTable=392, + EvDCPApplyBaselineExposureOffset=393, + EvDCPApplyHueSatMap=394, + + NUMOFEVENTS +}; +} +#endif + + diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc new file mode 100644 index 000000000..b6fdad148 --- /dev/null +++ b/rtengine/procparams.cc @@ -0,0 +1,3393 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "procparams.h" +#include "rt_math.h" +#include "safegtk.h" +#include "safekeyfile.h" +#include "dcp.h" +#include "../rtgui/multilangmgr.h" +#include "../rtgui/version.h" +#include "../rtgui/ppversion.h" +#include "../rtgui/paramsedited.h" +#include "../rtgui/options.h" +#include +#define APPVERSION VERSION + +using namespace std; +extern Options options; + +namespace rtengine { +namespace procparams { + const int tr=(int) options.rtSettings.top_right; + 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 *RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::numMethods]={"amaze","igv","lmmse","eahd", "hphd", "vng4", "dcb", "ahd", "fast", "mono", "none" }; + const char *RAWParams::XTransSensor::methodstring[RAWParams::XTransSensor::numMethods]={"3-pass (best)", "1-pass (medium)", "fast", "mono", "none" }; + +const char *RAWParams::ff_BlurTypestring[RAWParams::numFlatFileBlurTypes]={/*"Parametric",*/ "Area Flatfield", "Vertical Flatfield", "Horizontal Flatfield", "V+H Flatfield"}; +std::vector WBParams::wbEntries; + +bool ToneCurveParams::HLReconstructionNecessary(LUTu &histRedRaw, LUTu &histGreenRaw, LUTu &histBlueRaw) { + if (options.rtSettings.verbose) + printf("histRedRaw[ 0]=%07d, histGreenRaw[ 0]=%07d, histBlueRaw[ 0]=%07d\nhistRedRaw[255]=%07d, histGreenRaw[255]=%07d, histBlueRaw[255]=%07d\n", + histRedRaw[0], histGreenRaw[0], histBlueRaw[0], histRedRaw[255], histGreenRaw[255], histBlueRaw[255]); + + return histRedRaw[255]>50 || histGreenRaw[255]>50 || histBlueRaw[255]>50 || histRedRaw[0]>50 || histGreenRaw[0]>50 || histBlueRaw[0]>50; +} + +void WBParams::init() { + // Creation of the different methods and its associated temperature value + wbEntries.push_back(new WBEntry("Camera" ,WBT_CAMERA, M("TP_WBALANCE_CAMERA"), 0, 1.f, 1.f)); + wbEntries.push_back(new WBEntry("Auto" ,WBT_AUTO, M("TP_WBALANCE_AUTO"), 0, 1.f, 1.f)); + wbEntries.push_back(new WBEntry("Daylight" ,WBT_DAYLIGHT, M("TP_WBALANCE_DAYLIGHT"), 5300, 1.f, 1.f)); + wbEntries.push_back(new WBEntry("Cloudy" ,WBT_CLOUDY, M("TP_WBALANCE_CLOUDY"), 6200, 1.f, 1.f)); + wbEntries.push_back(new WBEntry("Shade" ,WBT_SHADE, M("TP_WBALANCE_SHADE"), 7600, 1.f, 1.f)); + wbEntries.push_back(new WBEntry("Water 1" ,WBT_WATER, M("TP_WBALANCE_WATER1"), 35000, 0.3f, 1.1f)); + wbEntries.push_back(new WBEntry("Water 2" ,WBT_WATER, M("TP_WBALANCE_WATER2"), 48000, 0.63f, 1.38f)); + wbEntries.push_back(new WBEntry("Tungsten" ,WBT_TUNGSTEN, M("TP_WBALANCE_TUNGSTEN"), 2856, 1.f, 1.f)); + wbEntries.push_back(new WBEntry("Fluo F1" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO1"), 6430, 1.f, 1.f)); + wbEntries.push_back(new WBEntry("Fluo F2" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO2"), 4230, 1.f, 1.f)); + wbEntries.push_back(new WBEntry("Fluo F3" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO3"), 3450, 1.f, 1.f)); + wbEntries.push_back(new WBEntry("Fluo F4" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO4"), 2940, 1.f, 1.f)); + wbEntries.push_back(new WBEntry("Fluo F5" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO5"), 6350, 1.f, 1.f)); + wbEntries.push_back(new WBEntry("Fluo F6" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO6"), 4150, 1.f, 1.f)); + wbEntries.push_back(new WBEntry("Fluo F7" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO7"), 6500, 1.f, 1.f)); + wbEntries.push_back(new WBEntry("Fluo F8" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO8"), 5020, 1.f, 1.f)); + wbEntries.push_back(new WBEntry("Fluo F9" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO9"), 4330, 1.f, 1.f)); + wbEntries.push_back(new WBEntry("Fluo F10" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO10"), 5300, 1.f, 1.f)); + wbEntries.push_back(new WBEntry("Fluo F11" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO11"), 4000, 1.f, 1.f)); + wbEntries.push_back(new WBEntry("Fluo F12" ,WBT_FLUORESCENT, M("TP_WBALANCE_FLUO12"), 3000, 1.f, 1.f)); + wbEntries.push_back(new WBEntry("HMI Lamp" ,WBT_LAMP, M("TP_WBALANCE_HMI"), 4800, 1.f, 1.f)); + wbEntries.push_back(new WBEntry("GTI Lamp" ,WBT_LAMP, M("TP_WBALANCE_GTI"), 5000, 1.f, 1.f)); + wbEntries.push_back(new WBEntry("JudgeIII Lamp" ,WBT_LAMP, M("TP_WBALANCE_JUDGEIII"), 5100, 1.f, 1.f)); + wbEntries.push_back(new WBEntry("Solux Lamp 3500K" ,WBT_LAMP, M("TP_WBALANCE_SOLUX35"), 3480, 1.f, 1.f)); + wbEntries.push_back(new WBEntry("Solux Lamp 4100K" ,WBT_LAMP, M("TP_WBALANCE_SOLUX41"), 3930, 1.f, 1.f)); + wbEntries.push_back(new WBEntry("Solux Lamp 4700K" ,WBT_LAMP, M("TP_WBALANCE_SOLUX47"), 4700, 1.f, 1.f)); + wbEntries.push_back(new WBEntry("NG Solux Lamp 4700K" ,WBT_LAMP, M("TP_WBALANCE_SOLUX47_NG"), 4480, 1.f, 1.f)); + wbEntries.push_back(new WBEntry("LED LSI Lumelex 2040",WBT_LED, M("TP_WBALANCE_LED_LSI"), 2970, 1.f, 1.f)); + wbEntries.push_back(new WBEntry("LED CRS SP12 WWMR16" ,WBT_LED, M("TP_WBALANCE_LED_CRS"), 3050, 1.f, 1.f)); + wbEntries.push_back(new WBEntry("Flash 5500K" ,WBT_FLASH, M("TP_WBALANCE_FLASH55"), 5500, 1.f, 1.f)); + wbEntries.push_back(new WBEntry("Flash 6000K" ,WBT_FLASH, M("TP_WBALANCE_FLASH60"), 6000, 1.f, 1.f)); + wbEntries.push_back(new WBEntry("Flash 6500K" ,WBT_FLASH, M("TP_WBALANCE_FLASH65"), 6500, 1.f, 1.f)); + // Should remain the last one + wbEntries.push_back(new WBEntry("Custom" ,WBT_CUSTOM, M("TP_WBALANCE_CUSTOM"), 0, 1.f, 1.f)); +} + +void WBParams::cleanup() { + for (unsigned int i=0; i &curve) { + double v[8]= { 0.050, 0.62, 0.25, 0.25, + 0.585, 0.11, 0.25, 0.25 }; + + curve.resize(9); + curve.at(0) = double(FCT_MinMaxCPoints); + for (size_t i=1; i &curve) { + double v[16]={ 0.00, 0.3, 0.35, 0.00, + 0.25, 0.8, 0.35, 0.35, + 0.70, 0.8, 0.35, 0.35, + 1.00, 0.3, 0.00, 0.00 }; + curve.resize(17); + curve.at(0 ) = double(FCT_MinMaxCPoints); + for (size_t i=1; i &curve) { + double v[6]= { 0.00, 0.00, + 0.35, 0.65, + 1.00, 1.00 }; + + curve.resize(7); + curve.at(0) = double(DCT_NURBS); + for (size_t i=1; i &curve) { + double v[6]= { 0.00, 0.00, + 0.35, 0.65, + 1.00, 1.00 }; + + curve.resize(7); + curve.at(0) = double(DCT_NURBS); + for (size_t i=1; i &colorCurve, std::vector &opacityCurve) const { + // check if non null first + if (!redlow && !greenlow && !bluelow && !redmed && !greenmed && !bluemed && !redhigh && !greenhigh && !bluehigh) { + colorCurve.resize(1); + colorCurve.at(0) = FCT_Linear; + opacityCurve.resize(1); + opacityCurve.at(0) = FCT_Linear; + return; + } + + float low[3]; // RGB color for shadows + float med[3]; // RGB color for mid-tones + float high[3]; // RGB color for highlights + float lowSat = 0.f; + float medSat = 0.f; + float highSat = 0.f; + float minTmp, maxTmp; + + // Fill the shadow mixer values of the Color TOning tool + low[0] = float(redlow )/100.f; // [-1. ; +1.] + low[1] = float(greenlow)/100.f; // [-1. ; +1.] + low[2] = float(bluelow )/100.f; // [-1. ; +1.] + minTmp = min(low[0], low[1], low[2]); + maxTmp = max(low[0], low[1], low[2]); + if (maxTmp-minTmp > 0.005f) { + float v[3]; + lowSat = (maxTmp-minTmp)/2.f; + if (low[0] == minTmp) v[0] = 0.f; + else if (low[1] == minTmp) v[1] = 0.f; + else if (low[2] == minTmp) v[2] = 0.f; + if (low[0] == maxTmp) v[0] = 1.f; + else if (low[1] == maxTmp) v[1] = 1.f; + else if (low[2] == maxTmp) v[2] = 1.f; + if (low[0] != minTmp && low[0] != maxTmp) v[0] = (low[0]-minTmp)/(maxTmp-minTmp); + else if (low[1] != minTmp && low[1] != maxTmp) v[1] = (low[1]-minTmp)/(maxTmp-minTmp); + else if (low[2] != minTmp && low[2] != maxTmp) v[2] = (low[2]-minTmp)/(maxTmp-minTmp); + low[0] = v[0]; + low[1] = v[1]; + low[2] = v[2]; + } + else { + low[0] = low[1] = low[2] = 1.f; + } + + // Fill the mid-tones mixer values of the Color TOning tool + med[0] = float(redmed )/100.f; // [-1. ; +1.] + med[1] = float(greenmed)/100.f; // [-1. ; +1.] + med[2] = float(bluemed )/100.f; // [-1. ; +1.] + minTmp = min(med[0], med[1], med[2]); + maxTmp = max(med[0], med[1], med[2]); + if (maxTmp-minTmp > 0.005f) { + float v[3]; + medSat = (maxTmp-minTmp)/2.f; + if (med[0] == minTmp) v[0] = 0.f; + else if (med[1] == minTmp) v[1] = 0.f; + else if (med[2] == minTmp) v[2] = 0.f; + if (med[0] == maxTmp) v[0] = 1.f; + else if (med[1] == maxTmp) v[1] = 1.f; + else if (med[2] == maxTmp) v[2] = 1.f; + if (med[0] != minTmp && med[0] != maxTmp) v[0] = (med[0]-minTmp)/(maxTmp-minTmp); + else if (med[1] != minTmp && med[1] != maxTmp) v[1] = (med[1]-minTmp)/(maxTmp-minTmp); + else if (med[2] != minTmp && med[2] != maxTmp) v[2] = (med[2]-minTmp)/(maxTmp-minTmp); + med[0] = v[0]; + med[1] = v[1]; + med[2] = v[2]; + } + else { + med[0] = med[1] = med[2] = 1.f; + } + + // Fill the highlight mixer values of the Color TOning tool + high[0] = float(redhigh )/100.f; // [-1. ; +1.] + high[1] = float(greenhigh)/100.f; // [-1. ; +1.] + high[2] = float(bluehigh )/100.f; // [-1. ; +1.] + minTmp = min(high[0], high[1], high[2]); + maxTmp = max(high[0], high[1], high[2]); + if (maxTmp-minTmp > 0.005f) { + float v[3]; + highSat = (maxTmp-minTmp)/2.f; + if (high[0] == minTmp) v[0] = 0.f; + else if (high[1] == minTmp) v[1] = 0.f; + else if (high[2] == minTmp) v[2] = 0.f; + if (high[0] == maxTmp) v[0] = 1.f; + else if (high[1] == maxTmp) v[1] = 1.f; + else if (high[2] == maxTmp) v[2] = 1.f; + if (high[0] != minTmp && high[0] != maxTmp) v[0] = (high[0]-minTmp)/(maxTmp-minTmp); + else if (high[1] != minTmp && high[1] != maxTmp) v[1] = (high[1]-minTmp)/(maxTmp-minTmp); + else if (high[2] != minTmp && high[2] != maxTmp) v[2] = (high[2]-minTmp)/(maxTmp-minTmp); + high[0] = v[0]; + high[1] = v[1]; + high[2] = v[2]; + } + else { + high[0] = high[1] = high[2] = 1.f; + } + + + + + const double xPosLow = 0.1; + const double xPosMed = 0.4; + const double xPosHigh = 0.7; + + + + colorCurve.resize( medSat!=0.f ? 13 : 9 ); + colorCurve.at(0) = FCT_MinMaxCPoints; + opacityCurve.resize(13); + opacityCurve.at(0) = FCT_MinMaxCPoints; + + float h, s, l; + int idx = 1; + + if (lowSat == 0.f) { + if (medSat != 0.f) + Color::rgb2hsl(med[0], med[1], med[2], h, s, l); + else// highSat can't be null if the 2 other ones are! + Color::rgb2hsl(high[0], high[1], high[2], h, s, l); + } + else + Color::rgb2hsl(low[0], low[1], low[2], h, s, l); + colorCurve.at(idx++) = xPosLow; + colorCurve.at(idx++) = h; + colorCurve.at(idx++) = 0.35; + colorCurve.at(idx++) = 0.35; + + if (medSat != 0.f) { + Color::rgb2hsl(med[0], med[1], med[2], h, s, l); + colorCurve.at(idx++) = xPosMed; + colorCurve.at(idx++) = h; + colorCurve.at(idx++) = 0.35; + colorCurve.at(idx++) = 0.35; + } + + if (highSat == 0.f) { + if (medSat != 0.f) + Color::rgb2hsl(med[0], med[1], med[2], h, s, l); + else// lowSat can't be null if the 2 other ones are! + Color::rgb2hsl(low[0], low[1], low[2], h, s, l); + } + else + Color::rgb2hsl(high[0], high[1], high[2], h, s, l); + colorCurve.at(idx++) = xPosHigh; + colorCurve.at(idx++) = h; + colorCurve.at(idx++) = 0.35; + colorCurve.at(idx) = 0.35; + + opacityCurve.at(1) = xPosLow; + opacityCurve.at(2) = double(lowSat); + opacityCurve.at(3) = 0.35; + opacityCurve.at(4) = 0.35; + opacityCurve.at(5) = xPosMed; + opacityCurve.at(6) = double(medSat); + opacityCurve.at(7) = 0.35; + opacityCurve.at(8) = 0.35; + opacityCurve.at(9) = xPosHigh; + opacityCurve.at(10) = double(highSat); + opacityCurve.at(11) = 0.35; + opacityCurve.at(12) = 0.35; +} + +void ColorToningParams::slidersToCurve(std::vector &colorCurve, std::vector &opacityCurve) const { + if (hlColSat.value[0]==0 && shadowsColSat.value[0]==0) { // if both opacity are null, set both curves to Linear + colorCurve.resize(1); + colorCurve.at(0) = FCT_Linear; + opacityCurve.resize(1); + opacityCurve.at(0) = FCT_Linear; + return; + } + + colorCurve.resize(9); + colorCurve.at(0) = FCT_MinMaxCPoints; + colorCurve.at(1) = 0.26 + 0.12*double(balance)/100.; + colorCurve.at(2) = double(shadowsColSat.value[1])/360.; + colorCurve.at(3) = 0.35; + colorCurve.at(4) = 0.35; + colorCurve.at(5) = 0.64 + 0.12*double(balance)/100.; + colorCurve.at(6) = double(hlColSat.value[1])/360.; + colorCurve.at(7) = 0.35; + colorCurve.at(8) = 0.35; + + opacityCurve.resize(9); + opacityCurve.at(0) = FCT_MinMaxCPoints; + opacityCurve.at(1) = colorCurve.at(1); + opacityCurve.at(2) = double(shadowsColSat.value[0])/100.; + opacityCurve.at(3) = 0.35; + opacityCurve.at(4) = 0.35; + opacityCurve.at(5) = colorCurve.at(5); + opacityCurve.at(6) = double(hlColSat.value[0])/100.; + opacityCurve.at(7) = 0.35; + 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 { + 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 + + // Transform slider values to control points + std::vector cCurve, oCurve; + if (method=="RGBSliders" || method=="Splitlr") + slidersToCurve(cCurve, oCurve); + else if (method=="Splitco") + mixerToCurve(cCurve, oCurve); + else { + cCurve = this->colorCurve; + oCurve = this->opacityCurve; + } + + if(method=="Lab") { + if(twocolor=="Separ") satur=0.9f; + if(twocolor=="All" || twocolor=="Two") satur=0.9f; + colorCurveLUT.SetXYZ(cCurve, xyz_rgb, rgb_xyz, satur, lumin); + opacityCurveLUT.Set(oCurve, opautili); + } + else if(method=="Splitlr" || method=="Splitco") { + colorCurveLUT.SetXYZ(cCurve, xyz_rgb, rgb_xyz, satur, lumin); + opacityCurveLUT.Set(oCurve, opautili); + } + else if(method.substr(0,3)=="RGB") { + colorCurveLUT.SetRGB(cCurve, xyz_rgb, rgb_xyz); + opacityCurveLUT.Set(oCurve, opautili); + } +} +//WaveletParams::WaveletParams (): hueskin(-5, 25, 170, 120, false), hueskin2(-260, -250, -130, -140, false), hllev(50, 75, 100, 98, false), bllev(0, 2, 50, 25, false), pastlev(0, 2, 30, 20, false), satlev(30, 45, 130, 100, false), edgcont(0, 20, 100, 75, false){ + +WaveletParams::WaveletParams (): hueskin(-5, 25, 170, 120, false), hueskin2(-260, -250, -130, -140, false), hllev(50, 75, 100, 98, false), bllev(0, 2, 50, 25, false), + pastlev(0, 2, 30, 20, false), satlev(30, 45, 130, 100, false), edgcont(bl, tl, br, tr, false), /* edgcont(0, 10, 75, 40, false),*/level0noise(0, 0, false),level1noise(0, 0, false), level2noise(0, 0, false){ + setDefaults (); +} + +void WaveletParams::getDefaultOpacityCurveRG(std::vector &curve) { + double v[8]= { 0.0, 0.50,0.35,0.35, + 1.00, 0.50,0.35,0.35}; + + curve.resize(9); + curve.at(0) = double(FCT_MinMaxCPoints); + for (size_t i=1; i &curve) { + double v[8]= { 0.0, 0.50,0.35,0.35, + 1.00, 0.50,0.35,0.35}; + + curve.resize(9); + curve.at(0 ) = double(FCT_MinMaxCPoints); + for (size_t i=1; i &curve) { + double v[16]={ 0.00, 0.35, 0.35, 0.00, + 0.35, 0.75, 0.35, 0.35, + 0.60, 0.75, 0.35, 0.35, + 1.00, 0.35, 0.00, 0.00 }; + curve.resize(17); + curve.at(0) = double(FCT_MinMaxCPoints); + for (size_t i=1; i &curve) { + double v[8]= { 0.0, 0.50,0.35,0.35, + 1.00, 0.50,0.35,0.35}; + + /*double v[12]={ 0.00, 0.53, 0.35, 0.00, + 0.42, 0.53, 0.35, 0.35, + 1.00, 0.15, 0.00, 0.00 }; + */ + curve.resize(9); + curve.at(0) = double(FCT_MinMaxCPoints); + for (size_t i=1; i &curve) { + double v[12]= { 0.0, 0.25, 0.35, 0.35, + 0.50, 0.75, 0.35, 0.35, 0.90, 0.0, 0.35, 0.35}; + + curve.resize(13); + curve.at(0 ) = double(FCT_MinMaxCPoints); + for (size_t i=1; iccwcurve); + opacityCurveLUTRG.Set(this->opacityCurveRG); + opacityCurveLUTBY.Set(this->opacityCurveBY); + opacityCurveLUTW.Set(this->opacityCurveW); + opacityCurveLUTWL.Set(this->opacityCurveWL); + +} + +void WaveletParams::setDefaults() { + getDefaultCCWCurve(ccwcurve); + getDefaultOpacityCurveRG(opacityCurveRG); + getDefaultOpacityCurveBY(opacityCurveBY); + getDefaultOpacityCurveW(opacityCurveW); + getDefaultOpacityCurveWL(opacityCurveWL); + enabled = false; + median = false; + medianlev = false; + linkedg = true; + cbenab = false; + lipst = false; + Medgreinf = "less"; //"none"; + avoid = false; + tmr = false; + strength = 100; + balance = 0; + iter = 0; + wavclCurve.clear (); + wavclCurve.push_back(DCT_Linear); + + Lmethod = "4_"; + CHmethod = "without"; + CHSLmethod = "SL"; + EDmethod = "CU"; + BAmethod = "none"; + TMmethod = "none"; + HSmethod = "with"; + CLmethod = "all"; + Backmethod = "grey"; + Dirmethod = "all"; + Tilesmethod = "full"; + daubcoeffmethod = "4_"; + rescon = 0; + resconH = 0; + reschro = 0; + tmrs = 0; + gamma = 1; + sky = 0.; + sup = 0; + thres = 7; + chroma = 5; + chro = 0; + contrast = 0; + edgrad =15; + edgval = 0; + edgthresh = 10; + thr = 35; + thrH = 65; + skinprotect = 0.; + hueskin.setValues(-5, 25, 170, 120); + hueskin2.setValues(-260, -250, -130, -140); + threshold=5; + threshold2=4; + edgedetect=80; + edgedetectthr=20; + edgedetectthr2=0; + hllev.setValues(50, 75, 100, 98); + bllev.setValues(0, 2, 50, 25); + pastlev.setValues(0, 2, 30, 20); + satlev.setValues(30, 45, 130, 100); +// edgcont.setValues(bl, tl, br, tr); + edgcont.setValues(0, 10, 75, 40); + level0noise.setValues(0, 0); + level1noise.setValues(0, 0); + level2noise.setValues(0, 0); + hhcurve.clear (); + hhcurve.push_back(FCT_Linear); + Chcurve.clear (); + Chcurve.push_back(FCT_Linear); + + for(int i = 0; i < 9; i ++) + { + c[i] = 0; + } + for(int i = 0; i < 9; i ++) + { + ch[i] = 0; + } + +} + + +DirPyrDenoiseParams::DirPyrDenoiseParams () { + setDefaults (); +} + +void DirPyrDenoiseParams::getDefaultNoisCurve(std::vector &curve) { + double v[8]={ 0.05, 0.15, 0.35, 0.35, + 0.55, 0.04, 0.35, 0.35}; + curve.resize(9); + curve.at(0 ) = double(FCT_MinMaxCPoints); + for (size_t i=1; i &curve) { + // double v[8]= { 0.15, 0.00,0.35,0.35, + // 0.60, 0.05,0.35,0.35}; + double v[8]= { 0.05, 0.50,0.35,0.35, + 0.35, 0.05,0.35,0.35}; + + curve.resize(9); + curve.at(0 ) = double(FCT_MinMaxCPoints); + for (size_t i=1; ilcurve); + cCurve.Set(this->cccurve); +} + +void ToneCurveParams::setDefaults() { + autoexp = false; + clip = 0.02; + expcomp = 0; + brightness = 0; + contrast = 0; + saturation = 0; + black = 0; + hlcompr = 0; + hlcomprthresh = 33; + shcompr = 50; + curve.clear (); + curve.push_back(DCT_Linear); + curve2.clear (); + curve2.push_back(DCT_Linear); + curveMode = ToneCurveParams::TC_MODE_STD; + curveMode2 = ToneCurveParams::TC_MODE_STD; + hrenabled = false; + method = "Blend"; +} + +void LensProfParams::setDefaults() { + lcpFile=""; + useDist=useVign=true; + useCA=false; +} + +void CoarseTransformParams::setDefaults() { + rotate = 0; + hflip = false; + vflip = false; +} + +void RAWParams::setDefaults() { + bayersensor.method = RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::amaze]; + bayersensor.ccSteps = 0; + bayersensor.dcb_iterations = 2; + bayersensor.dcb_enhance = true; + //bayersensor.all_enhance = false; + bayersensor.lmmse_iterations = 2; + bayersensor.black0 = 0.0; + bayersensor.black1 = 0.0; + bayersensor.black2 = 0.0; + bayersensor.black3 = 0.0; + bayersensor.twogreen = true; + bayersensor.linenoise = 0; + bayersensor.greenthresh = 0; + + xtranssensor.method = RAWParams::XTransSensor::methodstring[RAWParams::XTransSensor::threePass]; + xtranssensor.ccSteps = 0; + xtranssensor.blackred = 0.0; + xtranssensor.blackgreen = 0.0; + xtranssensor.blackblue = 0.0; + + expos=1.0; + preser=0.0; + df_autoselect = false; + ff_AutoSelect = false; + ff_BlurRadius = 32; + ff_BlurType = RAWParams::ff_BlurTypestring[RAWParams::area_ff]; + ff_AutoClipControl = false; + ff_clipControl = 0; + cared = 0; + cablue = 0; + ca_autocorrect = false; + hotPixelFilter = false; + deadPixelFilter = false; + hotdeadpix_thresh = 100; +} + +void ColorManagementParams::setDefaults() { + input = "(cameraICC)"; + blendCMSMatrix = false; + toneCurve = true; + applyLookTable = true; + applyBaselineExposureOffset = true; + applyHueSatMap = true; + dcpIlluminant = 0; + working = "ProPhoto"; + output = "RT_sRGB"; + gamma = "default"; + gampos =2.22; + slpos=4.5; + freegamma = false; +} + +ProcParams::ProcParams () { + + setDefaults (); +} + +void ProcParams::init () { + + WBParams::init(); +} + +void ProcParams::cleanup () { + + WBParams::cleanup(); +} + +ProcParams* ProcParams::create () { + + return new ProcParams(); +} + +void ProcParams::destroy (ProcParams* pp) { + + delete pp; +} + +void ProcParams::setDefaults () { + + toneCurve.setDefaults(); + + labCurve.brightness = 0; + labCurve.contrast = 0; + labCurve.chromaticity = 0; + labCurve.avoidcolorshift = false; + labCurve.lcredsk = true; + labCurve.rstprotection = 0; + labCurve.lcurve.clear (); + labCurve.lcurve.push_back(DCT_Linear); + labCurve.acurve.clear (); + labCurve.acurve.push_back(DCT_Linear); + labCurve.bcurve.clear (); + labCurve.bcurve.push_back(DCT_Linear); + labCurve.cccurve.clear (); + labCurve.cccurve.push_back(DCT_Linear); + labCurve.chcurve.clear (); + labCurve.chcurve.push_back(FCT_Linear); + labCurve.lhcurve.clear (); + labCurve.lhcurve.push_back(FCT_Linear); + labCurve.hhcurve.clear (); + labCurve.hhcurve.push_back(FCT_Linear); + + labCurve.lccurve.clear (); + labCurve.lccurve.push_back(DCT_Linear); + labCurve.clcurve.clear (); + labCurve.clcurve.push_back(DCT_Linear); + + rgbCurves.lumamode = false; + rgbCurves.rcurve.clear (); + rgbCurves.rcurve.push_back(DCT_Linear); + rgbCurves.gcurve.clear (); + rgbCurves.gcurve.push_back(DCT_Linear); + rgbCurves.bcurve.clear (); + rgbCurves.bcurve.push_back(DCT_Linear); + + colorToning.setDefaults(); + + sharpenEdge.enabled = false; + sharpenEdge.passes = 2; + sharpenEdge.amount = 50.0; + sharpenEdge.threechannels = false; + + sharpenMicro.enabled = false; + sharpenMicro.amount = 20.0; + sharpenMicro.uniformity = 50.0; + sharpenMicro.matrix = false; + + sharpening.enabled = false; + sharpening.radius = 0.5; + sharpening.amount = 200; + sharpening.threshold.setValues(20, 80, 2000, 1200); + sharpening.edgesonly = false; + sharpening.edges_radius = 1.9; + sharpening.edges_tolerance = 1800; + sharpening.halocontrol = false; + sharpening.halocontrol_amount = 85; + sharpening.method = "usm"; + sharpening.deconvradius = 0.75; + sharpening.deconviter = 30; + sharpening.deconvdamping = 20; + sharpening.deconvamount = 75; + + prsharpening.enabled = false; + prsharpening.radius = 0.5; + prsharpening.amount = 200; + prsharpening.threshold.setValues(20, 80, 2000, 1200); + prsharpening.edgesonly = false; + prsharpening.edges_radius = 1.9; + prsharpening.edges_tolerance = 1800; + prsharpening.halocontrol = false; + prsharpening.halocontrol_amount = 85; + prsharpening.method = "usm"; + prsharpening.deconvradius = 0.5; + prsharpening.deconviter = 100; + prsharpening.deconvdamping = 0; + prsharpening.deconvamount = 100; + + vibrance.enabled = false; + vibrance.pastels = 0; + vibrance.saturated = 0; + vibrance.psthreshold.setValues(0, 75); + vibrance.protectskins = false; + vibrance.avoidcolorshift = true; + vibrance.pastsattog = true; + vibrance.skintonescurve.clear (); + vibrance.skintonescurve.push_back(DCT_Linear); + + wb.method = "Camera"; + wb.temperature = 6504; + wb.green = 1.0; + wb.equal = 1.0; + colorappearance.enabled = false; + colorappearance.degree = 90; + colorappearance.autodegree = true; + colorappearance.surround = "Average"; + colorappearance.adaplum = 16; + colorappearance.badpixsl = 0; + colorappearance.adapscen = 2000.0; + colorappearance.autoadapscen = true; + colorappearance.algo = "No"; + colorappearance.wbmodel = "RawT"; + colorappearance.jlight = 0.0; + colorappearance.qbright = 0.0; + colorappearance.chroma = 0.0; + colorappearance.schroma = 0.0; + colorappearance.mchroma = 0.0; + colorappearance.rstprotection = 0.0; + colorappearance.contrast = 0.0; + colorappearance.qcontrast = 0.0; + colorappearance.colorh = 0.0; + colorappearance.surrsource = false; + colorappearance.gamut = true; +// colorappearance.badpix = false; + colorappearance.datacie = false; + colorappearance.tonecie = false; + // colorappearance.sharpcie = false; + colorappearance.curve.clear (); + colorappearance.curve.push_back(DCT_Linear); + colorappearance.curve2.clear (); + colorappearance.curve2.push_back(DCT_Linear); + colorappearance.curveMode =ColorAppearanceParams::TC_MODE_LIGHT; + colorappearance.curveMode2 = ColorAppearanceParams::TC_MODE_LIGHT; + colorappearance.curve3.clear (); + colorappearance.curve3.push_back(DCT_Linear); + colorappearance.curveMode3 = ColorAppearanceParams::TC_MODE_CHROMA; + + impulseDenoise.enabled = false; + impulseDenoise.thresh = 50; + + defringe.enabled = false; + defringe.radius = 2.0; + defringe.threshold = 13; + defringe.huecurve.resize (25); + defringe.huecurve.at(0) = FCT_MinMaxCPoints; + defringe.huecurve.at(1) = 0.166666667; + defringe.huecurve.at(2) = 0.; + defringe.huecurve.at(3) = 0.35; + defringe.huecurve.at(4) = 0.35; + defringe.huecurve.at(5) = 0.347; + defringe.huecurve.at(6) = 0.; + defringe.huecurve.at(7) = 0.35; + defringe.huecurve.at(8) = 0.35; + defringe.huecurve.at(9) = 0.513667426; + defringe.huecurve.at(10) = 0; + defringe.huecurve.at(11) = 0.35; + defringe.huecurve.at(12) = 0.35; + defringe.huecurve.at(13) = 0.668944571; + defringe.huecurve.at(14) = 0.; + defringe.huecurve.at(15) = 0.35; + defringe.huecurve.at(16) = 0.35; + defringe.huecurve.at(17) = 0.8287775246; + defringe.huecurve.at(18) = 0.97835991; + defringe.huecurve.at(19) = 0.35; + defringe.huecurve.at(20) = 0.35; + defringe.huecurve.at(21) = 0.9908883827; + defringe.huecurve.at(22) = 0.; + defringe.huecurve.at(23) = 0.35; + defringe.huecurve.at(24) = 0.35; + + dirpyrDenoise.setDefaults(); + + epd.enabled = false; + epd.strength = 0.5; + epd.gamma = 1.0; + epd.edgeStopping = 1.4; + epd.scale = 0.3; + epd.reweightingIterates = 0; + + sh.enabled = false; + sh.hq = false; + sh.highlights = 0; + sh.htonalwidth = 80; + sh.shadows = 0; + sh.stonalwidth = 80; + sh.localcontrast = 0; + sh.radius = 40; + + crop.enabled = false; + crop.x = -1; + crop.y = -1; + crop.w = 15000; + crop.h = 15000; + crop.fixratio = false; + crop.ratio = "3:2"; + crop.orientation= "As Image"; + crop.guide = "Rule of thirds"; + + coarse.setDefaults(); + + commonTrans.autofill = true; + + rotate.degree = 0; + + distortion.amount = 0; + + perspective.horizontal = 0; + perspective.vertical = 0; + + gradient.enabled = false; + gradient.degree = 0; + gradient.feather = 25; + gradient.strength = 0.60; + gradient.centerX = 0; + gradient.centerY = 0; + + pcvignette.enabled = false; + pcvignette.strength = 0.60; + pcvignette.feather = 50; + pcvignette.roundness = 50; + + cacorrection.red = 0; + cacorrection.blue = 0; + + + vignetting.amount = 0; + vignetting.radius = 50; + vignetting.strength = 1; + vignetting.centerX = 0; + vignetting.centerY = 0; + + lensProf.setDefaults(); + + chmixer.red[0] = 100; + chmixer.red[1] = 0; + chmixer.red[2] = 0; + chmixer.green[0] = 0; + chmixer.green[1] = 100; + chmixer.green[2] = 0; + chmixer.blue[0] = 0; + chmixer.blue[1] = 0; + chmixer.blue[2] = 100; + + blackwhite.autoc = false; + blackwhite.enabledcc = true; + blackwhite.enabled = false; + blackwhite.mixerRed = 33; + blackwhite.mixerGreen = 33; + blackwhite.mixerBlue = 33; + blackwhite.mixerOrange = 33; + blackwhite.mixerYellow = 33; + blackwhite.mixerCyan = 33; + blackwhite.mixerMagenta = 33; + blackwhite.mixerPurple = 33; + blackwhite.gammaRed = 0; + blackwhite.gammaGreen = 0; + blackwhite.gammaBlue = 0; + blackwhite.luminanceCurve.clear (); + blackwhite.luminanceCurve.push_back (FCT_Linear); + blackwhite.method = "Desaturation"; + blackwhite.filter = "None"; + blackwhite.setting = "NormalContrast"; + blackwhite.beforeCurve.clear (); + blackwhite.beforeCurve.push_back(DCT_Linear); + blackwhite.beforeCurveMode = BlackWhiteParams::TC_MODE_STD_BW; + blackwhite.afterCurve.clear (); + blackwhite.afterCurve.push_back(DCT_Linear); + blackwhite.afterCurveMode = BlackWhiteParams::TC_MODE_STD_BW; + blackwhite.algo = "SP"; + + resize.enabled = false; + resize.scale = 1.0; + resize.appliesTo = "Cropped area"; + resize.method = "Lanczos"; + resize.dataspec = 3; + resize.width = 900; + resize.height = 900; + + icm.setDefaults(); + + dirpyrequalizer.enabled = false; + dirpyrequalizer.gamutlab = false; + for(int i = 0; i < 6; i ++) + { + dirpyrequalizer.mult[i] = 1.0; + } + dirpyrequalizer.threshold = 0.2; + dirpyrequalizer.skinprotect = 0.; + dirpyrequalizer.hueskin.setValues(-5, 25, 170, 120); //default (b_l 0, t_l 30, b_r 170, t_r 120); + // dirpyrequalizer.algo = "FI"; + + hsvequalizer.hcurve.clear (); + hsvequalizer.hcurve.push_back (FCT_Linear); + hsvequalizer.scurve.clear (); + hsvequalizer.scurve.push_back (FCT_Linear); + hsvequalizer.vcurve.clear (); + hsvequalizer.vcurve.push_back (FCT_Linear); + + filmSimulation.setDefaults(); + + raw.setDefaults(); + + exif.clear (); + iptc.clear (); + + rank = 0; + colorlabel = 0; + inTrash = false; + + ppVersion = PPVERSION; +} + +static Glib::ustring expandRelativePath(Glib::ustring procparams_fname, Glib::ustring prefix, Glib::ustring embedded_fname) { + if (embedded_fname == "" || !Glib::path_is_absolute(procparams_fname)) { + return embedded_fname; + } + if (prefix != "") { + if (embedded_fname.length() < prefix.length() || embedded_fname.substr(0, prefix.length()) != prefix) { + return embedded_fname; + } + embedded_fname = embedded_fname.substr(prefix.length()); + } + if (Glib::path_is_absolute(embedded_fname)) { + return prefix + embedded_fname; + } + Glib::ustring absPath = prefix + Glib::path_get_dirname(procparams_fname) + G_DIR_SEPARATOR_S + embedded_fname; + return absPath; +} + +static Glib::ustring relativePathIfInside(Glib::ustring procparams_fname, bool fnameAbsolute, Glib::ustring embedded_fname) { + if (fnameAbsolute || embedded_fname == "" || !Glib::path_is_absolute(procparams_fname)) { + return embedded_fname; + } + Glib::ustring prefix = ""; + if (embedded_fname.length() > 5 && embedded_fname.substr(0, 5) == "file:") { + embedded_fname = embedded_fname.substr(5); + prefix = "file:"; + } + if (!Glib::path_is_absolute(embedded_fname)) { + return prefix + embedded_fname; + } + Glib::ustring dir1 = Glib::path_get_dirname(procparams_fname) + G_DIR_SEPARATOR_S; + Glib::ustring dir2 = Glib::path_get_dirname(embedded_fname) + G_DIR_SEPARATOR_S; + if (dir2.substr(0, dir1.length()) != dir1) { + // it's in a different directory, ie not inside + return prefix + embedded_fname; + } + return prefix + embedded_fname.substr(dir1.length()); +} + +int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsolute, ParamsEdited* pedited) { + + if (!fname.length() && !fname2.length()) + return 0; + + SafeKeyFile keyFile; + + keyFile.set_string ("Version", "AppVersion", APPVERSION); + keyFile.set_integer ("Version", "Version", PPVERSION); + + if (!pedited || pedited->general.rank) keyFile.set_integer ("General", "Rank", rank); + if (!pedited || pedited->general.colorlabel) keyFile.set_integer ("General", "ColorLabel", colorlabel); + if (!pedited || pedited->general.intrash) keyFile.set_boolean ("General", "InTrash", inTrash); + + // save tone curve + if (!pedited || pedited->toneCurve.autoexp) keyFile.set_boolean ("Exposure", "Auto", toneCurve.autoexp); + if (!pedited || pedited->toneCurve.clip) keyFile.set_double ("Exposure", "Clip", toneCurve.clip); + if (!pedited || pedited->toneCurve.expcomp) keyFile.set_double ("Exposure", "Compensation", toneCurve.expcomp); + if (!pedited || pedited->toneCurve.brightness) keyFile.set_integer ("Exposure", "Brightness", toneCurve.brightness); + if (!pedited || pedited->toneCurve.contrast) keyFile.set_integer ("Exposure", "Contrast", toneCurve.contrast); + if (!pedited || pedited->toneCurve.saturation) keyFile.set_integer ("Exposure", "Saturation", toneCurve.saturation); + if (!pedited || pedited->toneCurve.black) keyFile.set_integer ("Exposure", "Black", toneCurve.black); + if (!pedited || pedited->toneCurve.hlcompr) keyFile.set_integer ("Exposure", "HighlightCompr", toneCurve.hlcompr); + if (!pedited || pedited->toneCurve.hlcomprthresh) keyFile.set_integer ("Exposure", "HighlightComprThreshold", toneCurve.hlcomprthresh); + if (!pedited || pedited->toneCurve.shcompr) keyFile.set_integer ("Exposure", "ShadowCompr", toneCurve.shcompr); + // save highlight recovery settings + if (!pedited || pedited->toneCurve.hrenabled) keyFile.set_boolean ("HLRecovery", "Enabled", toneCurve.hrenabled); + if (!pedited || pedited->toneCurve.method) keyFile.set_string ("HLRecovery", "Method", toneCurve.method); + if (!pedited || pedited->toneCurve.curveMode) { + Glib::ustring method; + switch (toneCurve.curveMode) { + case (ToneCurveParams::TC_MODE_STD): + method = "Standard"; + break; + case (ToneCurveParams::TC_MODE_FILMLIKE): + method = "FilmLike"; + break; + case (ToneCurveParams::TC_MODE_SATANDVALBLENDING): + method = "SatAndValueBlending"; + break; + case (ToneCurveParams::TC_MODE_WEIGHTEDSTD): + method = "WeightedStd"; + break; + case (ToneCurveParams::TC_MODE_LUMINANCE): + method = "Luminance"; + break; + } + keyFile.set_string ("Exposure", "CurveMode", method); + } + if (!pedited || pedited->toneCurve.curveMode2) { + Glib::ustring method; + switch (toneCurve.curveMode2) { + case (ToneCurveParams::TC_MODE_STD): + method = "Standard"; + break; + case (ToneCurveParams::TC_MODE_FILMLIKE): + method = "FilmLike"; + break; + case (ToneCurveParams::TC_MODE_SATANDVALBLENDING): + method = "SatAndValueBlending"; + break; + case (ToneCurveParams::TC_MODE_WEIGHTEDSTD): + method = "WeightedStd"; + break; + case (ToneCurveParams::TC_MODE_LUMINANCE): + method = "Luminance"; + break; + } + keyFile.set_string ("Exposure", "CurveMode2", method); + } + if (!pedited || pedited->toneCurve.curve) { + Glib::ArrayHandle tcurve = toneCurve.curve; + keyFile.set_double_list("Exposure", "Curve", tcurve); + } + if (!pedited || pedited->toneCurve.curve2) { + Glib::ArrayHandle tcurve = toneCurve.curve2; + keyFile.set_double_list("Exposure", "Curve2", tcurve); + } + + // save channel mixer + if (!pedited || pedited->chmixer.red[0] || pedited->chmixer.red[1] || pedited->chmixer.red[2]) { + Glib::ArrayHandle rmix (chmixer.red, 3, Glib::OWNERSHIP_NONE); + keyFile.set_integer_list("Channel Mixer", "Red", rmix); + } + if (!pedited || pedited->chmixer.green[0] || pedited->chmixer.green[1] || pedited->chmixer.green[2]) { + Glib::ArrayHandle gmix (chmixer.green, 3, Glib::OWNERSHIP_NONE); + keyFile.set_integer_list("Channel Mixer", "Green", gmix); + } + if (!pedited || pedited->chmixer.blue[0] || pedited->chmixer.blue[1] || pedited->chmixer.blue[2]) { + Glib::ArrayHandle bmix (chmixer.blue, 3, Glib::OWNERSHIP_NONE); + keyFile.set_integer_list("Channel Mixer", "Blue", bmix); + } + + //save Black & White + if (!pedited || pedited->blackwhite.enabled) keyFile.set_boolean ("Black & White", "Enabled", blackwhite.enabled); + if (!pedited || pedited->blackwhite.method) keyFile.set_string ("Black & White", "Method", blackwhite.method ); + if (!pedited || pedited->blackwhite.autoc) keyFile.set_boolean ("Black & White", "Auto", blackwhite.autoc); + if (!pedited || pedited->blackwhite.enabledcc) keyFile.set_boolean ("Black & White", "ComplementaryColors", blackwhite.enabledcc); + if (!pedited || pedited->blackwhite.setting) keyFile.set_string ("Black & White", "Setting", blackwhite.setting ); + if (!pedited || pedited->blackwhite.filter) keyFile.set_string ("Black & White", "Filter", blackwhite.filter ); + if (!pedited || pedited->blackwhite.mixerRed) keyFile.set_integer ("Black & White", "MixerRed", blackwhite.mixerRed); + if (!pedited || pedited->blackwhite.mixerOrange) keyFile.set_integer ("Black & White", "MixerOrange", blackwhite.mixerOrange); + if (!pedited || pedited->blackwhite.mixerYellow) keyFile.set_integer ("Black & White", "MixerYellow", blackwhite.mixerYellow); + if (!pedited || pedited->blackwhite.mixerGreen) keyFile.set_integer ("Black & White", "MixerGreen", blackwhite.mixerGreen); + if (!pedited || pedited->blackwhite.mixerCyan) keyFile.set_integer ("Black & White", "MixerCyan", blackwhite.mixerCyan); + if (!pedited || pedited->blackwhite.mixerBlue) keyFile.set_integer ("Black & White", "MixerBlue", blackwhite.mixerBlue); + if (!pedited || pedited->blackwhite.mixerMagenta) keyFile.set_integer ("Black & White", "MixerMagenta", blackwhite.mixerMagenta); + if (!pedited || pedited->blackwhite.mixerPurple) keyFile.set_integer ("Black & White", "MixerPurple", blackwhite.mixerPurple); + if (!pedited || pedited->blackwhite.gammaRed) keyFile.set_integer ("Black & White", "GammaRed", blackwhite.gammaRed); + if (!pedited || pedited->blackwhite.gammaGreen) keyFile.set_integer ("Black & White", "GammaGreen", blackwhite.gammaGreen); + if (!pedited || pedited->blackwhite.gammaBlue) keyFile.set_integer ("Black & White", "GammaBlue", blackwhite.gammaBlue); + if (!pedited || pedited->blackwhite.algo) keyFile.set_string ("Black & White", "Algorithm", blackwhite.algo); + + if (!pedited || pedited->blackwhite.luminanceCurve) { + Glib::ArrayHandle luminanceCurve = blackwhite.luminanceCurve; + keyFile.set_double_list("Black & White", "LuminanceCurve", luminanceCurve); + } + if (!pedited || pedited->blackwhite.beforeCurveMode) { + Glib::ustring mode; + switch (blackwhite.beforeCurveMode) { + case (BlackWhiteParams::TC_MODE_STD_BW): + mode = "Standard"; + break; + case (BlackWhiteParams::TC_MODE_FILMLIKE_BW): + mode = "FilmLike"; + break; + case (BlackWhiteParams::TC_MODE_SATANDVALBLENDING_BW): + mode = "SatAndValueBlending"; + break; + case (BlackWhiteParams::TC_MODE_WEIGHTEDSTD_BW): + mode = "WeightedStd"; + break; + } + keyFile.set_string ("Black & White", "BeforeCurveMode", mode); + } + + if (!pedited || pedited->blackwhite.afterCurveMode) { + Glib::ustring mode; + switch (blackwhite.afterCurveMode) { + case (BlackWhiteParams::TC_MODE_STD_BW): + mode = "Standard"; + break; + case (BlackWhiteParams::TC_MODE_WEIGHTEDSTD_BW): + mode = "WeightedStd"; + break; + default: + break; + } + keyFile.set_string ("Black & White", "AfterCurveMode", mode); + } + + if (!pedited || pedited->blackwhite.beforeCurve) { + Glib::ArrayHandle tcurvebw = blackwhite.beforeCurve; + keyFile.set_double_list("Black & White", "BeforeCurve", tcurvebw); + } + if (!pedited || pedited->blackwhite.afterCurve) { + Glib::ArrayHandle tcurvebw = blackwhite.afterCurve; + keyFile.set_double_list("Black & White", "AfterCurve", tcurvebw); + } + + // save luma curve + if (!pedited || pedited->labCurve.brightness) keyFile.set_integer ("Luminance Curve", "Brightness", labCurve.brightness); + if (!pedited || pedited->labCurve.contrast) keyFile.set_integer ("Luminance Curve", "Contrast", labCurve.contrast); + if (!pedited || pedited->labCurve.chromaticity) keyFile.set_integer ("Luminance Curve", "Chromaticity", labCurve.chromaticity); + if (!pedited || pedited->labCurve.avoidcolorshift) keyFile.set_boolean ("Luminance Curve", "AvoidColorShift", labCurve.avoidcolorshift); + if (!pedited || pedited->labCurve.rstprotection) keyFile.set_double ("Luminance Curve", "RedAndSkinTonesProtection", labCurve.rstprotection); + if (!pedited || pedited->labCurve.lcredsk) keyFile.set_boolean ("Luminance Curve", "LCredsk", labCurve.lcredsk); + + if (!pedited || pedited->labCurve.lcurve) { + Glib::ArrayHandle lcurve = labCurve.lcurve; + keyFile.set_double_list("Luminance Curve", "LCurve", lcurve); + } + if (!pedited || pedited->labCurve.acurve) { + Glib::ArrayHandle acurve = labCurve.acurve; + keyFile.set_double_list("Luminance Curve", "aCurve", acurve); + } + if (!pedited || pedited->labCurve.bcurve) { + Glib::ArrayHandle bcurve = labCurve.bcurve; + keyFile.set_double_list("Luminance Curve", "bCurve", bcurve); + } + if (!pedited || pedited->labCurve.cccurve) { + Glib::ArrayHandle cccurve = labCurve.cccurve; + keyFile.set_double_list("Luminance Curve", "ccCurve", cccurve); + } + if (!pedited || pedited->labCurve.chcurve) { + Glib::ArrayHandle chcurve = labCurve.chcurve; + keyFile.set_double_list("Luminance Curve", "chCurve", chcurve); + } + if (!pedited || pedited->labCurve.lhcurve) { + Glib::ArrayHandle lhcurve = labCurve.lhcurve; + keyFile.set_double_list("Luminance Curve", "lhCurve", lhcurve); + } + if (!pedited || pedited->labCurve.hhcurve) { + Glib::ArrayHandle hhcurve = labCurve.hhcurve; + keyFile.set_double_list("Luminance Curve", "hhCurve", hhcurve); + } + + if (!pedited || pedited->labCurve.lccurve) { + Glib::ArrayHandle lccurve = labCurve.lccurve; + keyFile.set_double_list("Luminance Curve", "LcCurve", lccurve); + } + if (!pedited || pedited->labCurve.clcurve) { + Glib::ArrayHandle clcurve = labCurve.clcurve; + keyFile.set_double_list("Luminance Curve", "ClCurve", clcurve); + } + + // save sharpening + if (!pedited || pedited->sharpening.enabled) keyFile.set_boolean ("Sharpening", "Enabled", sharpening.enabled); + if (!pedited || pedited->sharpening.method) keyFile.set_string ("Sharpening", "Method", sharpening.method); + if (!pedited || pedited->sharpening.radius) keyFile.set_double ("Sharpening", "Radius", sharpening.radius); + if (!pedited || pedited->sharpening.amount) keyFile.set_integer ("Sharpening", "Amount", sharpening.amount); + if (!pedited || pedited->sharpening.threshold) { + Glib::ArrayHandle thresh (sharpening.threshold.value, 4, Glib::OWNERSHIP_NONE); + keyFile.set_integer_list("Sharpening", "Threshold", thresh); + } + if (!pedited || pedited->sharpening.edgesonly) keyFile.set_boolean ("Sharpening", "OnlyEdges", sharpening.edgesonly); + if (!pedited || pedited->sharpening.edges_radius) keyFile.set_double ("Sharpening", "EdgedetectionRadius", sharpening.edges_radius); + if (!pedited || pedited->sharpening.edges_tolerance) keyFile.set_integer ("Sharpening", "EdgeTolerance", sharpening.edges_tolerance); + if (!pedited || pedited->sharpening.halocontrol) keyFile.set_boolean ("Sharpening", "HalocontrolEnabled", sharpening.halocontrol); + if (!pedited || pedited->sharpening.halocontrol_amount) keyFile.set_integer ("Sharpening", "HalocontrolAmount", sharpening.halocontrol_amount); + if (!pedited || pedited->sharpening.deconvradius) keyFile.set_double ("Sharpening", "DeconvRadius", sharpening.deconvradius); + if (!pedited || pedited->sharpening.deconvamount) keyFile.set_integer ("Sharpening", "DeconvAmount", sharpening.deconvamount); + if (!pedited || pedited->sharpening.deconvdamping) keyFile.set_integer ("Sharpening", "DeconvDamping", sharpening.deconvdamping); + if (!pedited || pedited->sharpening.deconviter) keyFile.set_integer ("Sharpening", "DeconvIterations", sharpening.deconviter); + + // save vibrance + if (!pedited || pedited->vibrance.enabled) keyFile.set_boolean ("Vibrance", "Enabled", vibrance.enabled); + if (!pedited || pedited->vibrance.pastels) keyFile.set_integer ("Vibrance", "Pastels", vibrance.pastels); + if (!pedited || pedited->vibrance.saturated) keyFile.set_integer ("Vibrance", "Saturated", vibrance.saturated); + if (!pedited || pedited->vibrance.psthreshold) { + Glib::ArrayHandle thresh (vibrance.psthreshold.value, 2, Glib::OWNERSHIP_NONE); + keyFile.set_integer_list("Vibrance", "PSThreshold", thresh); + } + if (!pedited || pedited->vibrance.protectskins) keyFile.set_boolean ("Vibrance", "ProtectSkins", vibrance.protectskins); + if (!pedited || pedited->vibrance.avoidcolorshift) keyFile.set_boolean ("Vibrance", "AvoidColorShift", vibrance.avoidcolorshift); + if (!pedited || pedited->vibrance.pastsattog) keyFile.set_boolean ("Vibrance", "PastSatTog", vibrance.pastsattog); + if (!pedited || pedited->vibrance.skintonescurve) { + Glib::ArrayHandle skintonescurve = vibrance.skintonescurve; + keyFile.set_double_list("Vibrance", "SkinTonesCurve", skintonescurve); + } + + //save edge sharpening + if (!pedited || pedited->sharpenEdge.enabled) keyFile.set_boolean ("SharpenEdge", "Enabled", sharpenEdge.enabled); + if (!pedited || pedited->sharpenEdge.passes) keyFile.set_integer ("SharpenEdge", "Passes", sharpenEdge.passes); + if (!pedited || pedited->sharpenEdge.amount) keyFile.set_double ("SharpenEdge", "Strength", sharpenEdge.amount); + if (!pedited || pedited->sharpenEdge.threechannels) keyFile.set_boolean ("SharpenEdge", "ThreeChannels", sharpenEdge.threechannels); + + //save micro-contrast sharpening + if (!pedited || pedited->sharpenMicro.enabled) keyFile.set_boolean ("SharpenMicro", "Enabled", sharpenMicro.enabled); + if (!pedited || pedited->sharpenMicro.matrix) keyFile.set_boolean ("SharpenMicro", "Matrix", sharpenMicro.matrix); + if (!pedited || pedited->sharpenMicro.amount) keyFile.set_double ("SharpenMicro", "Strength", sharpenMicro.amount); + if (!pedited || pedited->sharpenMicro.uniformity) keyFile.set_double ("SharpenMicro", "Uniformity", sharpenMicro.uniformity); + +/* + // save colorBoost + if (!pedited || pedited->colorBoost.amount) keyFile.set_integer ("Color Boost", "Amount", colorBoost.amount); + if (!pedited || pedited->colorBoost.avoidclip) keyFile.set_boolean ("Color Boost", "AvoidColorClipping", colorBoost.avoidclip); + if (!pedited || pedited->colorBoost.enable_saturationlimiter) keyFile.set_boolean ("Color Boost", "SaturationLimiter", colorBoost.enable_saturationlimiter); + if (!pedited || pedited->colorBoost.saturationlimit) keyFile.set_double ("Color Boost", "SaturationLimit", colorBoost.saturationlimit); +*/ + + // save wb + if (!pedited || pedited->wb.method) keyFile.set_string ("White Balance", "Setting", wb.method); + if (!pedited || pedited->wb.temperature) keyFile.set_integer ("White Balance", "Temperature", wb.temperature); + if (!pedited || pedited->wb.green) keyFile.set_double ("White Balance", "Green", wb.green); + if (!pedited || pedited->wb.equal) keyFile.set_double ("White Balance", "Equal", wb.equal); + +/* + // save colorShift + if (!pedited || pedited->colorShift.a) keyFile.set_double ("Color Shift", "ChannelA", colorShift.a); + if (!pedited || pedited->colorShift.b) keyFile.set_double ("Color Shift", "ChannelB", colorShift.b); +*/ + // save colorappearance + if (!pedited || pedited->colorappearance.enabled) keyFile.set_boolean ("Color appearance", "Enabled", colorappearance.enabled); + if (!pedited || pedited->colorappearance.degree) keyFile.set_integer ("Color appearance", "Degree", colorappearance.degree); + if (!pedited || pedited->colorappearance.autodegree) keyFile.set_boolean ("Color appearance", "AutoDegree", colorappearance.autodegree); + if (!pedited || pedited->colorappearance.surround) keyFile.set_string ("Color appearance", "Surround", colorappearance.surround); + // if (!pedited || pedited->colorappearance.backgrd) keyFile.set_integer ("Color appearance", "Background", colorappearance.backgrd); + if (!pedited || pedited->colorappearance.adaplum) keyFile.set_double ("Color appearance", "AdaptLum", colorappearance.adaplum); + if (!pedited || pedited->colorappearance.badpixsl) keyFile.set_integer ("Color appearance", "Badpixsl", colorappearance.badpixsl); + if (!pedited || pedited->colorappearance.wbmodel) keyFile.set_string ("Color appearance", "Model", colorappearance.wbmodel); + if (!pedited || pedited->colorappearance.algo) keyFile.set_string ("Color appearance", "Algorithm", colorappearance.algo); + + if (!pedited || pedited->colorappearance.jlight) keyFile.set_double ("Color appearance", "J-Light", colorappearance.jlight); + if (!pedited || pedited->colorappearance.qbright) keyFile.set_double ("Color appearance", "Q-Bright", colorappearance.qbright); + if (!pedited || pedited->colorappearance.chroma) keyFile.set_double ("Color appearance", "C-Chroma", colorappearance.chroma); + if (!pedited || pedited->colorappearance.schroma) keyFile.set_double ("Color appearance", "S-Chroma", colorappearance.schroma); + if (!pedited || pedited->colorappearance.mchroma) keyFile.set_double ("Color appearance", "M-Chroma", colorappearance.mchroma); + if (!pedited || pedited->colorappearance.contrast) keyFile.set_double ("Color appearance", "J-Contrast", colorappearance.contrast); + if (!pedited || pedited->colorappearance.qcontrast) keyFile.set_double ("Color appearance", "Q-Contrast", colorappearance.qcontrast); + if (!pedited || pedited->colorappearance.colorh) keyFile.set_double ("Color appearance", "H-Hue", colorappearance.colorh); + if (!pedited || pedited->colorappearance.rstprotection) keyFile.set_double ("Color appearance", "RSTProtection", colorappearance.rstprotection); + + if (!pedited || pedited->colorappearance.adapscen) keyFile.set_double ("Color appearance", "AdaptScene", colorappearance.adapscen); + if (!pedited || pedited->colorappearance.autoadapscen) keyFile.set_boolean ("Color appearance", "AutoAdapscen", colorappearance.autoadapscen); + if (!pedited || pedited->colorappearance.surrsource) keyFile.set_boolean ("Color appearance", "SurrSource", colorappearance.surrsource); + if (!pedited || pedited->colorappearance.gamut) keyFile.set_boolean ("Color appearance", "Gamut", colorappearance.gamut); +// if (!pedited || pedited->colorappearance.badpix) keyFile.set_boolean ("Color appearance", "Badpix", colorappearance.badpix); + if (!pedited || pedited->colorappearance.datacie) keyFile.set_boolean ("Color appearance", "Datacie", colorappearance.datacie); + if (!pedited || pedited->colorappearance.tonecie) keyFile.set_boolean ("Color appearance", "Tonecie", colorappearance.tonecie); +// if (!pedited || pedited->colorappearance.sharpcie) keyFile.set_boolean ("Color appearance", "Sharpcie", colorappearance.sharpcie); + if (!pedited || pedited->colorappearance.curveMode) { + Glib::ustring method; + switch (colorappearance.curveMode) { + case (ColorAppearanceParams::TC_MODE_LIGHT): + method = "Lightness"; + break; + case (ColorAppearanceParams::TC_MODE_BRIGHT): + method = "Brightness"; + break; + } + keyFile.set_string ("Color appearance", "CurveMode", method); + } + if (!pedited || pedited->colorappearance.curveMode2) { + Glib::ustring method; + switch (colorappearance.curveMode2) { + case (ColorAppearanceParams::TC_MODE_LIGHT): + method = "Lightness"; + break; + case (ColorAppearanceParams::TC_MODE_BRIGHT): + method = "Brightness"; + break; + } + keyFile.set_string ("Color appearance", "CurveMode2", method); + } + if (!pedited || pedited->colorappearance.curveMode3) { + Glib::ustring method; + switch (colorappearance.curveMode3) { + case (ColorAppearanceParams::TC_MODE_CHROMA): + method = "Chroma"; + break; + case (ColorAppearanceParams::TC_MODE_SATUR): + method = "Saturation"; + break; + case (ColorAppearanceParams::TC_MODE_COLORF): + method = "Colorfullness"; + break; + + } + keyFile.set_string ("Color appearance", "CurveMode3", method); + } + + if (!pedited || pedited->colorappearance.curve) { + Glib::ArrayHandle tcurve = colorappearance.curve; + keyFile.set_double_list("Color appearance", "Curve", tcurve); + } + if (!pedited || pedited->colorappearance.curve2) { + Glib::ArrayHandle tcurve = colorappearance.curve2; + keyFile.set_double_list("Color appearance", "Curve2", tcurve); + } + if (!pedited || pedited->colorappearance.curve3) { + Glib::ArrayHandle tcurve = colorappearance.curve3; + keyFile.set_double_list("Color appearance", "Curve3", tcurve); + } + + + + // save impulseDenoise + if (!pedited || pedited->impulseDenoise.enabled) keyFile.set_boolean ("Impulse Denoising", "Enabled", impulseDenoise.enabled); + if (!pedited || pedited->impulseDenoise.thresh) keyFile.set_integer ("Impulse Denoising", "Threshold", impulseDenoise.thresh); + + // save defringe + if (!pedited || pedited->defringe.enabled) keyFile.set_boolean ("Defringing", "Enabled", defringe.enabled); + if (!pedited || pedited->defringe.radius) keyFile.set_double ("Defringing", "Radius", defringe.radius); + if (!pedited || pedited->defringe.threshold) keyFile.set_integer ("Defringing", "Threshold", defringe.threshold); + if (!pedited || pedited->defringe.huecurve) { + Glib::ArrayHandle huecurve = defringe.huecurve; + keyFile.set_double_list("Defringing", "HueCurve", huecurve); + } + + // save dirpyrDenoise + if (!pedited || pedited->dirpyrDenoise.enabled) keyFile.set_boolean ("Directional Pyramid Denoising", "Enabled", dirpyrDenoise.enabled); + if (!pedited || pedited->dirpyrDenoise.enhance) keyFile.set_boolean ("Directional Pyramid Denoising", "Enhance", dirpyrDenoise.enhance); + if (!pedited || pedited->dirpyrDenoise.median) keyFile.set_boolean ("Directional Pyramid Denoising", "Median", dirpyrDenoise.median); + if (!pedited || pedited->dirpyrDenoise.autochroma) keyFile.set_boolean ("Directional Pyramid Denoising", "Auto", dirpyrDenoise.autochroma); + // if (!pedited || pedited->dirpyrDenoise.perform) keyFile.set_boolean ("Directional Pyramid Denoising", "Perform", dirpyrDenoise.perform); + if (!pedited || pedited->dirpyrDenoise.luma) keyFile.set_double ("Directional Pyramid Denoising", "Luma", dirpyrDenoise.luma); + if (!pedited || pedited->dirpyrDenoise.Ldetail) keyFile.set_double ("Directional Pyramid Denoising", "Ldetail", dirpyrDenoise.Ldetail); + if (!pedited || pedited->dirpyrDenoise.chroma) keyFile.set_double ("Directional Pyramid Denoising", "Chroma", dirpyrDenoise.chroma); + if (!pedited || pedited->dirpyrDenoise.dmethod) keyFile.set_string ("Directional Pyramid Denoising", "Method", dirpyrDenoise.dmethod); + if (!pedited || pedited->dirpyrDenoise.Lmethod) keyFile.set_string ("Directional Pyramid Denoising", "LMethod", dirpyrDenoise.Lmethod); + // never save 'auto chroma preview mode' to pp3 + if (!pedited || pedited->dirpyrDenoise.Cmethod) { + if(dirpyrDenoise.Cmethod=="PRE") + dirpyrDenoise.Cmethod = "MAN"; + keyFile.set_string ("Directional Pyramid Denoising", "CMethod", dirpyrDenoise.Cmethod); + } + if (!pedited || pedited->dirpyrDenoise.C2method) { + if(dirpyrDenoise.C2method=="PREV") + dirpyrDenoise.C2method = "MANU"; + keyFile.set_string ("Directional Pyramid Denoising", "C2Method", dirpyrDenoise.C2method); + } + if (!pedited || pedited->dirpyrDenoise.smethod) keyFile.set_string ("Directional Pyramid Denoising", "SMethod", dirpyrDenoise.smethod); + if (!pedited || pedited->dirpyrDenoise.medmethod) keyFile.set_string ("Directional Pyramid Denoising", "MedMethod", dirpyrDenoise.medmethod); + if (!pedited || pedited->dirpyrDenoise.rgbmethod) keyFile.set_string ("Directional Pyramid Denoising", "RGBMethod", dirpyrDenoise.rgbmethod); + if (!pedited || pedited->dirpyrDenoise.methodmed) keyFile.set_string ("Directional Pyramid Denoising", "MethodMed", dirpyrDenoise.methodmed); + if (!pedited || pedited->dirpyrDenoise.redchro) keyFile.set_double ("Directional Pyramid Denoising", "Redchro", dirpyrDenoise.redchro); + if (!pedited || pedited->dirpyrDenoise.bluechro)keyFile.set_double ("Directional Pyramid Denoising", "Bluechro", dirpyrDenoise.bluechro); + if (!pedited || pedited->dirpyrDenoise.gamma) keyFile.set_double ("Directional Pyramid Denoising", "Gamma", dirpyrDenoise.gamma); + if (!pedited || pedited->dirpyrDenoise.passes) keyFile.set_integer ("Directional Pyramid Denoising", "Passes", dirpyrDenoise.passes); + if (!pedited || pedited->dirpyrDenoise.lcurve) { + Glib::ArrayHandle lcurve = dirpyrDenoise.lcurve; + keyFile.set_double_list("Directional Pyramid Denoising", "LCurve", lcurve); + } + if (!pedited || pedited->dirpyrDenoise.cccurve) { + Glib::ArrayHandle cccurve = dirpyrDenoise.cccurve; + keyFile.set_double_list("Directional Pyramid Denoising", "CCCurve", cccurve); + } + + //Save epd. + if (!pedited || pedited->epd.enabled) keyFile.set_boolean ("EPD", "Enabled", epd.enabled); + if (!pedited || pedited->epd.strength) keyFile.set_double ("EPD", "Strength", epd.strength); + if (!pedited || pedited->epd.gamma) keyFile.set_double ("EPD", "Gamma", epd.gamma); + if (!pedited || pedited->epd.edgeStopping) keyFile.set_double ("EPD", "EdgeStopping", epd.edgeStopping); + if (!pedited || pedited->epd.scale) keyFile.set_double ("EPD", "Scale", epd.scale); + if (!pedited || pedited->epd.reweightingIterates) keyFile.set_integer ("EPD", "ReweightingIterates", epd.reweightingIterates); + +/* + // save lumaDenoise + if (!pedited || pedited->lumaDenoise.enabled) keyFile.set_boolean ("Luminance Denoising", "Enabled", lumaDenoise.enabled); + if (!pedited || pedited->lumaDenoise.radius) keyFile.set_double ("Luminance Denoising", "Radius", lumaDenoise.radius); + if (!pedited || pedited->lumaDenoise.edgetolerance) keyFile.set_integer ("Luminance Denoising", "EdgeTolerance", lumaDenoise.edgetolerance); +*/ + +/* + // save colorDenoise + //if (!pedited || pedited->colorDenoise.enabled) keyFile.set_boolean ("Chrominance Denoising", "Enabled", colorDenoise.enabled); + if (!pedited || pedited->colorDenoise.amount) keyFile.set_integer ("Chrominance Denoising", "Amount", colorDenoise.amount); +*/ + + // save sh + if (!pedited || pedited->sh.enabled) keyFile.set_boolean ("Shadows & Highlights", "Enabled", sh.enabled); + if (!pedited || pedited->sh.hq) keyFile.set_boolean ("Shadows & Highlights", "HighQuality", sh.hq); + if (!pedited || pedited->sh.highlights) keyFile.set_integer ("Shadows & Highlights", "Highlights", sh.highlights); + if (!pedited || pedited->sh.htonalwidth) keyFile.set_integer ("Shadows & Highlights", "HighlightTonalWidth", sh.htonalwidth); + if (!pedited || pedited->sh.shadows) keyFile.set_integer ("Shadows & Highlights", "Shadows", sh.shadows); + if (!pedited || pedited->sh.stonalwidth) keyFile.set_integer ("Shadows & Highlights", "ShadowTonalWidth", sh.stonalwidth); + if (!pedited || pedited->sh.localcontrast) keyFile.set_integer ("Shadows & Highlights", "LocalContrast", sh.localcontrast); + if (!pedited || pedited->sh.radius) keyFile.set_integer ("Shadows & Highlights", "Radius", sh.radius); + + // save crop + if (!pedited || pedited->crop.enabled) keyFile.set_boolean ("Crop", "Enabled", crop.enabled); + if (!pedited || pedited->crop.x) keyFile.set_integer ("Crop", "X", crop.x); + if (!pedited || pedited->crop.y) keyFile.set_integer ("Crop", "Y", crop.y); + if (!pedited || pedited->crop.w) keyFile.set_integer ("Crop", "W", crop.w); + if (!pedited || pedited->crop.h) keyFile.set_integer ("Crop", "H", crop.h); + if (!pedited || pedited->crop.fixratio) keyFile.set_boolean ("Crop", "FixedRatio", crop.fixratio); + if (!pedited || pedited->crop.ratio) keyFile.set_string ("Crop", "Ratio", crop.ratio); + if (!pedited || pedited->crop.orientation) keyFile.set_string ("Crop", "Orientation", crop.orientation); + if (!pedited || pedited->crop.guide) keyFile.set_string ("Crop", "Guide", crop.guide); + + // save coarse + if (!pedited || pedited->coarse.rotate) keyFile.set_integer ("Coarse Transformation", "Rotate", coarse.rotate); + if (!pedited || pedited->coarse.hflip) keyFile.set_boolean ("Coarse Transformation", "HorizontalFlip", coarse.hflip); + if (!pedited || pedited->coarse.vflip) keyFile.set_boolean ("Coarse Transformation", "VerticalFlip", coarse.vflip); + + // save commonTrans + if (!pedited || pedited->commonTrans.autofill) keyFile.set_boolean ("Common Properties for Transformations", "AutoFill", commonTrans.autofill); + + // save rotate + if (!pedited || pedited->rotate.degree) keyFile.set_double ("Rotation", "Degree", rotate.degree); + + // save distortion + if (!pedited || pedited->distortion.amount) keyFile.set_double ("Distortion", "Amount", distortion.amount); + + // lens profile + if (!pedited || pedited->lensProf.lcpFile) keyFile.set_string ("LensProfile", "LCPFile", relativePathIfInside(fname, fnameAbsolute, lensProf.lcpFile)); + if (!pedited || pedited->lensProf.useDist) keyFile.set_boolean ("LensProfile", "UseDistortion", lensProf.useDist); + if (!pedited || pedited->lensProf.useVign) keyFile.set_boolean ("LensProfile", "UseVignette", lensProf.useVign); + if (!pedited || pedited->lensProf.useCA) keyFile.set_boolean ("LensProfile", "UseCA", lensProf.useCA); + + // save perspective correction + if (!pedited || pedited->perspective.horizontal) keyFile.set_double ("Perspective", "Horizontal", perspective.horizontal); + if (!pedited || pedited->perspective.vertical) keyFile.set_double ("Perspective", "Vertical", perspective.vertical); + + // save gradient + if (!pedited || pedited->gradient.enabled) keyFile.set_boolean ("Gradient", "Enabled", gradient.enabled); + if (!pedited || pedited->gradient.degree) keyFile.set_double ("Gradient", "Degree", gradient.degree); + if (!pedited || pedited->gradient.feather) keyFile.set_integer ("Gradient", "Feather", gradient.feather); + if (!pedited || pedited->gradient.strength) keyFile.set_double ("Gradient", "Strength", gradient.strength); + if (!pedited || pedited->gradient.centerX) keyFile.set_integer ("Gradient", "CenterX", gradient.centerX); + if (!pedited || pedited->gradient.centerY) keyFile.set_integer ("Gradient", "CenterY", gradient.centerY); + + // save post-crop vignette + if (!pedited || pedited->pcvignette.enabled) keyFile.set_boolean ("PCVignette", "Enabled", pcvignette.enabled); + if (!pedited || pedited->pcvignette.strength) keyFile.set_double ("PCVignette", "Strength", pcvignette.strength); + if (!pedited || pedited->pcvignette.feather) keyFile.set_integer ("PCVignette", "Feather", pcvignette.feather); + if (!pedited || pedited->pcvignette.roundness) keyFile.set_integer ("PCVignette", "Roundness", pcvignette.roundness); + + // save C/A correction + if (!pedited || pedited->cacorrection.red) keyFile.set_double ("CACorrection", "Red", cacorrection.red); + if (!pedited || pedited->cacorrection.blue) keyFile.set_double ("CACorrection", "Blue", cacorrection.blue); + + // save vignetting correction + if (!pedited || pedited->vignetting.amount) keyFile.set_integer ("Vignetting Correction", "Amount", vignetting.amount); + if (!pedited || pedited->vignetting.radius) keyFile.set_integer ("Vignetting Correction", "Radius", vignetting.radius); + if (!pedited || pedited->vignetting.strength) keyFile.set_integer ("Vignetting Correction", "Strength", vignetting.strength); + if (!pedited || pedited->vignetting.centerX) keyFile.set_integer ("Vignetting Correction", "CenterX", vignetting.centerX); + if (!pedited || pedited->vignetting.centerY) keyFile.set_integer ("Vignetting Correction", "CenterY", vignetting.centerY); + + + if (!pedited || pedited->resize.enabled) keyFile.set_boolean ("Resize", "Enabled",resize.enabled); + if (!pedited || pedited->resize.scale) keyFile.set_double ("Resize", "Scale", resize.scale); + if (!pedited || pedited->resize.appliesTo) keyFile.set_string ("Resize", "AppliesTo", resize.appliesTo); + if (!pedited || pedited->resize.method) keyFile.set_string ("Resize", "Method", resize.method); + if (!pedited || pedited->resize.dataspec) keyFile.set_integer ("Resize", "DataSpecified", resize.dataspec); + if (!pedited || pedited->resize.width) keyFile.set_integer ("Resize", "Width", resize.width); + if (!pedited || pedited->resize.height) keyFile.set_integer ("Resize", "Height", resize.height); + + if (!pedited || pedited->prsharpening.enabled) keyFile.set_boolean ("PostResizeSharpening", "Enabled", prsharpening.enabled); + if (!pedited || pedited->prsharpening.method) keyFile.set_string ("PostResizeSharpening", "Method", prsharpening.method); + if (!pedited || pedited->prsharpening.radius) keyFile.set_double ("PostResizeSharpening", "Radius", prsharpening.radius); + if (!pedited || pedited->prsharpening.amount) keyFile.set_integer ("PostResizeSharpening", "Amount", prsharpening.amount); + if (!pedited || pedited->prsharpening.threshold) { + Glib::ArrayHandle thresh (prsharpening.threshold.value, 4, Glib::OWNERSHIP_NONE); + keyFile.set_integer_list("PostResizeSharpening", "Threshold", thresh); + } + if (!pedited || pedited->prsharpening.edgesonly) keyFile.set_boolean ("PostResizeSharpening", "OnlyEdges", prsharpening.edgesonly); + if (!pedited || pedited->prsharpening.edges_radius) keyFile.set_double ("PostResizeSharpening", "EdgedetectionRadius", prsharpening.edges_radius); + if (!pedited || pedited->prsharpening.edges_tolerance) keyFile.set_integer ("PostResizeSharpening", "EdgeTolerance", prsharpening.edges_tolerance); + if (!pedited || pedited->prsharpening.halocontrol) keyFile.set_boolean ("PostResizeSharpening", "HalocontrolEnabled", prsharpening.halocontrol); + if (!pedited || pedited->prsharpening.halocontrol_amount) keyFile.set_integer ("PostResizeSharpening", "HalocontrolAmount", prsharpening.halocontrol_amount); + if (!pedited || pedited->prsharpening.deconvradius) keyFile.set_double ("PostResizeSharpening", "DeconvRadius", prsharpening.deconvradius); + if (!pedited || pedited->prsharpening.deconvamount) keyFile.set_integer ("PostResizeSharpening", "DeconvAmount", prsharpening.deconvamount); + if (!pedited || pedited->prsharpening.deconvdamping) keyFile.set_integer ("PostResizeSharpening", "DeconvDamping", prsharpening.deconvdamping); + if (!pedited || pedited->prsharpening.deconviter) keyFile.set_integer ("PostResizeSharpening", "DeconvIterations", prsharpening.deconviter); + + + // save color management settings + if (!pedited || pedited->icm.input) keyFile.set_string ("Color Management", "InputProfile", relativePathIfInside(fname, fnameAbsolute, icm.input)); + if (!pedited || pedited->icm.toneCurve) keyFile.set_boolean ("Color Management", "ToneCurve", icm.toneCurve); + if (!pedited || pedited->icm.applyLookTable) keyFile.set_boolean ("Color Management", "ApplyLookTable", icm.applyLookTable); + if (!pedited || pedited->icm.applyBaselineExposureOffset) keyFile.set_boolean ("Color Management", "ApplyBaselineExposureOffset", icm.applyBaselineExposureOffset); + if (!pedited || pedited->icm.applyHueSatMap) keyFile.set_boolean ("Color Management", "ApplyHueSatMap", icm.applyHueSatMap); + if (!pedited || pedited->icm.blendCMSMatrix) keyFile.set_boolean ("Color Management", "BlendCMSMatrix", icm.blendCMSMatrix); + if (!pedited || pedited->icm.dcpIlluminant) keyFile.set_integer ("Color Management", "DCPIlluminant", icm.dcpIlluminant); + if (!pedited || pedited->icm.working) keyFile.set_string ("Color Management", "WorkingProfile", icm.working); + if (!pedited || pedited->icm.output) keyFile.set_string ("Color Management", "OutputProfile", icm.output); + if (!pedited || pedited->icm.gamma) keyFile.set_string ("Color Management", "Gammafree", icm.gamma); + if (!pedited || pedited->icm.freegamma) keyFile.set_boolean ("Color Management", "Freegamma", icm.freegamma); + if (!pedited || pedited->icm.gampos) keyFile.set_double ("Color Management", "GammaValue", icm.gampos); + if (!pedited || pedited->icm.slpos) keyFile.set_double ("Color Management", "GammaSlope", icm.slpos); + + + + // save wavelet parameters + if (!pedited || pedited->wavelet.enabled) keyFile.set_boolean ("Wavelet", "Enabled", wavelet.enabled); + if (!pedited || pedited->wavelet.strength) keyFile.set_integer ("Wavelet", "Strength", wavelet.strength); + if (!pedited || pedited->wavelet.balance) keyFile.set_integer ("Wavelet", "Balance", wavelet.balance); + if (!pedited || pedited->wavelet.iter) keyFile.set_integer ("Wavelet", "Iter", wavelet.iter); + if (!pedited || pedited->wavelet.thres) keyFile.set_integer ("Wavelet", "MaxLev", wavelet.thres); + if (!pedited || pedited->wavelet.Tilesmethod) keyFile.set_string ("Wavelet", "TilesMethod", wavelet.Tilesmethod); + if (!pedited || pedited->wavelet.daubcoeffmethod) keyFile.set_string ("Wavelet", "DaubMethod", wavelet.daubcoeffmethod); + if (!pedited || pedited->wavelet.CLmethod) keyFile.set_string ("Wavelet", "ChoiceLevMethod", wavelet.CLmethod); + if (!pedited || pedited->wavelet.Backmethod) keyFile.set_string ("Wavelet", "BackMethod", wavelet.Backmethod); + if (!pedited || pedited->wavelet.Lmethod) keyFile.set_string ("Wavelet", "LevMethod", wavelet.Lmethod); + if (!pedited || pedited->wavelet.Dirmethod) keyFile.set_string ("Wavelet", "DirMethod", wavelet.Dirmethod); + if (!pedited || pedited->wavelet.greenhigh) keyFile.set_integer ("Wavelet", "CBgreenhigh", wavelet.greenhigh); + if (!pedited || pedited->wavelet.greenmed) keyFile.set_integer ("Wavelet", "CBgreenmed", wavelet.greenmed); + if (!pedited || pedited->wavelet.greenlow) keyFile.set_integer ("Wavelet", "CBgreenlow", wavelet.greenlow); + if (!pedited || pedited->wavelet.bluehigh) keyFile.set_integer ("Wavelet", "CBbluehigh", wavelet.bluehigh); + if (!pedited || pedited->wavelet.bluemed) keyFile.set_integer ("Wavelet", "CBbluemed", wavelet.bluemed); + if (!pedited || pedited->wavelet.bluelow) keyFile.set_integer ("Wavelet", "CBbluelow", wavelet.bluelow); + + for(int i = 0; i < 9; i++) + { + std::stringstream ss; + ss << "Contrast" << (i+1); + if (!pedited || pedited->wavelet.c[i]) keyFile.set_integer("Wavelet", ss.str(), wavelet.c[i]); + } + for(int i = 0; i < 9; i++) + { + std::stringstream ss; + ss << "Chroma" << (i+1); + if (!pedited || pedited->wavelet.ch[i]) keyFile.set_integer("Wavelet", ss.str(), wavelet.ch[i]); + } + + if (!pedited || pedited->wavelet.sup) keyFile.set_integer ("Wavelet", "ContExtra", wavelet.sup); + if (!pedited || pedited->wavelet.HSmethod) keyFile.set_string ("Wavelet", "HSMethod", wavelet.HSmethod); + if (!pedited || pedited->wavelet.hllev) { + Glib::ArrayHandle thresh (wavelet.hllev.value, 4, Glib::OWNERSHIP_NONE); + keyFile.set_integer_list("Wavelet", "HLRange", thresh); + } + if (!pedited || pedited->wavelet.bllev) { + Glib::ArrayHandle thresh (wavelet.bllev.value, 4, Glib::OWNERSHIP_NONE); + keyFile.set_integer_list("Wavelet", "SHRange", thresh); + } + if (!pedited || pedited->wavelet.edgcont) { + Glib::ArrayHandle thresh (wavelet.edgcont.value, 4, Glib::OWNERSHIP_NONE); + keyFile.set_integer_list("Wavelet", "Edgcont", thresh); + } + if (!pedited || pedited->wavelet.level0noise) { + Glib::ArrayHandle thresh (wavelet.level0noise.value, 2, Glib::OWNERSHIP_NONE); + keyFile.set_double_list("Wavelet", "Level0noise", thresh); + } + if (!pedited || pedited->wavelet.level1noise) { + Glib::ArrayHandle thresh (wavelet.level1noise.value, 2, Glib::OWNERSHIP_NONE); + keyFile.set_double_list("Wavelet", "Level1noise", thresh); + } + if (!pedited || pedited->wavelet.level2noise) { + Glib::ArrayHandle thresh (wavelet.level2noise.value, 2, Glib::OWNERSHIP_NONE); + keyFile.set_double_list("Wavelet", "Level2noise", thresh); + } + + if (!pedited || pedited->wavelet.threshold) keyFile.set_integer ("Wavelet", "ThresholdHighlight", wavelet.threshold); + if (!pedited || pedited->wavelet.threshold2) keyFile.set_integer ("Wavelet", "ThresholdShadow", wavelet.threshold2); + if (!pedited || pedited->wavelet.edgedetect) keyFile.set_integer ("Wavelet", "Edgedetect", wavelet.edgedetect); + if (!pedited || pedited->wavelet.edgedetectthr) keyFile.set_integer ("Wavelet", "Edgedetectthr", wavelet.edgedetectthr); + if (!pedited || pedited->wavelet.edgedetectthr2) keyFile.set_integer ("Wavelet", "EdgedetectthrHi", wavelet.edgedetectthr2); + if (!pedited || pedited->wavelet.chroma) keyFile.set_integer ("Wavelet", "ThresholdChroma", wavelet.chroma); + if (!pedited || pedited->wavelet.CHmethod) keyFile.set_string ("Wavelet", "CHromaMethod", wavelet.CHmethod); + if (!pedited || pedited->wavelet.Medgreinf) keyFile.set_string ("Wavelet", "Medgreinf", wavelet.Medgreinf); + if (!pedited || pedited->wavelet.CHSLmethod) keyFile.set_string ("Wavelet", "CHSLromaMethod", wavelet.CHSLmethod); + if (!pedited || pedited->wavelet.EDmethod) keyFile.set_string ("Wavelet", "EDMethod", wavelet.EDmethod); + if (!pedited || pedited->wavelet.BAmethod) keyFile.set_string ("Wavelet", "BAMethod", wavelet.BAmethod); + if (!pedited || pedited->wavelet.TMmethod) keyFile.set_string ("Wavelet", "TMMethod", wavelet.TMmethod); + if (!pedited || pedited->wavelet.chro) keyFile.set_integer ("Wavelet", "ChromaLink", wavelet.chro); + if (!pedited || pedited->wavelet.ccwcurve) { + Glib::ArrayHandle ccwcurve = wavelet.ccwcurve; + keyFile.set_double_list("Wavelet", "ContrastCurve", ccwcurve); + } + if (!pedited || pedited->wavelet.pastlev) { + Glib::ArrayHandle thresh (wavelet.pastlev.value, 4, Glib::OWNERSHIP_NONE); + keyFile.set_integer_list("Wavelet", "Pastlev", thresh); + } + if (!pedited || pedited->wavelet.satlev) { + Glib::ArrayHandle thresh (wavelet.satlev.value, 4, Glib::OWNERSHIP_NONE); + keyFile.set_integer_list("Wavelet", "Satlev", thresh); + } + + if (!pedited || pedited->wavelet.opacityCurveRG) { + Glib::ArrayHandle curve = wavelet.opacityCurveRG; + keyFile.set_double_list("Wavelet", "OpacityCurveRG", curve); + } + if (!pedited || pedited->wavelet.opacityCurveBY) { + Glib::ArrayHandle curve = wavelet.opacityCurveBY; + keyFile.set_double_list("Wavelet", "OpacityCurveBY", curve); + } + if (!pedited || pedited->wavelet.opacityCurveW) { + Glib::ArrayHandle curve = wavelet.opacityCurveW; + keyFile.set_double_list("Wavelet", "OpacityCurveW", curve); + } + if (!pedited || pedited->wavelet.opacityCurveWL) { + Glib::ArrayHandle curve = wavelet.opacityCurveWL; + keyFile.set_double_list("Wavelet", "OpacityCurveWL", curve); + } + + if (!pedited || pedited->wavelet.hhcurve) { + Glib::ArrayHandle curve = wavelet.hhcurve; + keyFile.set_double_list("Wavelet", "HHcurve", curve); + } + if (!pedited || pedited->wavelet.Chcurve) { + Glib::ArrayHandle curve = wavelet.Chcurve; + keyFile.set_double_list("Wavelet", "CHcurve", curve); + } + if (!pedited || pedited->wavelet.wavclCurve) { + Glib::ArrayHandle wavclCurve = wavelet.wavclCurve; + keyFile.set_double_list("Wavelet", "WavclCurve", wavclCurve); + } + + + if (!pedited || pedited->wavelet.median) keyFile.set_boolean ("Wavelet", "Median", wavelet.median); + if (!pedited || pedited->wavelet.medianlev) keyFile.set_boolean ("Wavelet", "Medianlev", wavelet.medianlev); + if (!pedited || pedited->wavelet.linkedg) keyFile.set_boolean ("Wavelet", "Linkedg", wavelet.linkedg); + if (!pedited || pedited->wavelet.cbenab) keyFile.set_boolean ("Wavelet", "CBenab", wavelet.cbenab); + if (!pedited || pedited->wavelet.lipst) keyFile.set_boolean ("Wavelet", "Lipst", wavelet.lipst); + // if (!pedited || pedited->wavelet.edgreinf) keyFile.set_boolean ("Wavelet", "Edgreinf", wavelet.edgreinf); + if (!pedited || pedited->wavelet.skinprotect) keyFile.set_double ("Wavelet", "Skinprotect", wavelet.skinprotect); + if (!pedited || pedited->wavelet.hueskin) { + Glib::ArrayHandle thresh (wavelet.hueskin.value, 4, Glib::OWNERSHIP_NONE); + keyFile.set_integer_list("Wavelet", "Hueskin", thresh); + } + + if (!pedited || pedited->wavelet.edgrad) keyFile.set_integer ("Wavelet", "Edgrad", wavelet.edgrad); + if (!pedited || pedited->wavelet.edgval) keyFile.set_integer ("Wavelet", "Edgval", wavelet.edgval); + if (!pedited || pedited->wavelet.edgthresh) keyFile.set_integer ("Wavelet", "ThrEdg", wavelet.edgthresh); + // if (!pedited || pedited->wavelet.strength) keyFile.set_integer ("Wavelet", "Strength", wavelet.strength); + // if (!pedited || pedited->wavelet.balance) keyFile.set_integer ("Wavelet", "Balance", wavelet.balance); + + if (!pedited || pedited->wavelet.avoid) keyFile.set_boolean ("Wavelet", "AvoidColorShift", wavelet.avoid); + if (!pedited || pedited->wavelet.tmr) keyFile.set_boolean ("Wavelet", "TMr", wavelet.tmr); + if (!pedited || pedited->wavelet.rescon) keyFile.set_integer ("Wavelet", "ResidualcontShadow", wavelet.rescon); + if (!pedited || pedited->wavelet.resconH) keyFile.set_integer ("Wavelet", "ResidualcontHighlight", wavelet.resconH); + if (!pedited || pedited->wavelet.thr) keyFile.set_integer ("Wavelet", "ThresholdResidShadow", wavelet.thr); + if (!pedited || pedited->wavelet.thrH) keyFile.set_integer ("Wavelet", "ThresholdResidHighLight", wavelet.thrH); + if (!pedited || pedited->wavelet.reschro) keyFile.set_integer ("Wavelet", "Residualchroma", wavelet.reschro); + if (!pedited || pedited->wavelet.tmrs) keyFile.set_double ("Wavelet", "ResidualTM", wavelet.tmrs); + if (!pedited || pedited->wavelet.gamma) keyFile.set_double ("Wavelet", "Residualgamma", wavelet.gamma); + if (!pedited || pedited->wavelet.sky) keyFile.set_double ("Wavelet", "HueRangeResidual", wavelet.sky); + if (!pedited || pedited->wavelet.hueskin2) { + Glib::ArrayHandle thresh (wavelet.hueskin2.value, 4, Glib::OWNERSHIP_NONE); + keyFile.set_integer_list("Wavelet", "HueRange", thresh); + } + if (!pedited || pedited->wavelet.contrast) keyFile.set_integer ("Wavelet", "Contrast", wavelet.contrast); + + + // save directional pyramid wavelet parameters + if (!pedited || pedited->dirpyrequalizer.enabled) keyFile.set_boolean ("Directional Pyramid Equalizer", "Enabled", dirpyrequalizer.enabled); + if (!pedited || pedited->dirpyrequalizer.gamutlab) keyFile.set_boolean ("Directional Pyramid Equalizer", "Gamutlab", dirpyrequalizer.gamutlab); + for(int i = 0; i < 6; i++) + { + std::stringstream ss; + ss << "Mult" << i; + if (!pedited || pedited->dirpyrequalizer.mult[i]) keyFile.set_double("Directional Pyramid Equalizer", ss.str(), dirpyrequalizer.mult[i]); + } + if (!pedited || pedited->dirpyrequalizer.threshold) keyFile.set_double ("Directional Pyramid Equalizer", "Threshold", dirpyrequalizer.threshold); + if (!pedited || pedited->dirpyrequalizer.skinprotect) keyFile.set_double ("Directional Pyramid Equalizer", "Skinprotect", dirpyrequalizer.skinprotect); + // if (!pedited || pedited->dirpyrequalizer.algo) keyFile.set_string ("Directional Pyramid Equalizer", "Algorithm", dirpyrequalizer.algo); + if (!pedited || pedited->dirpyrequalizer.hueskin) { + Glib::ArrayHandle thresh (dirpyrequalizer.hueskin.value, 4, Glib::OWNERSHIP_NONE); + keyFile.set_integer_list("Directional Pyramid Equalizer", "Hueskin", thresh); + } + + // save hsv wavelet parameters + if (!pedited || pedited->hsvequalizer.hcurve) { + Glib::ArrayHandle hcurve = hsvequalizer.hcurve; + keyFile.set_double_list("HSV Equalizer", "HCurve", hcurve); + } + if (!pedited || pedited->hsvequalizer.scurve) { + Glib::ArrayHandle scurve = hsvequalizer.scurve; + keyFile.set_double_list("HSV Equalizer", "SCurve", scurve); + } + if (!pedited || pedited->hsvequalizer.vcurve) { + Glib::ArrayHandle vcurve = hsvequalizer.vcurve; + keyFile.set_double_list("HSV Equalizer", "VCurve", vcurve); + } + + //save film simulation parameters + if ( !pedited || pedited->filmSimulation.enabled ) keyFile.set_boolean( "Film Simulation", "Enabled", filmSimulation.enabled ); + if ( !pedited || pedited->filmSimulation.clutFilename ) keyFile.set_string ( "Film Simulation", "ClutFilename", filmSimulation.clutFilename ); + if ( !pedited || pedited->filmSimulation.strength ) keyFile.set_integer( "Film Simulation", "Strength", filmSimulation.strength ); + + + if (!pedited || pedited->rgbCurves.lumamode) keyFile.set_boolean ("RGB Curves", "LumaMode", rgbCurves.lumamode); + + if (!pedited || pedited->rgbCurves.rcurve) { + Glib::ArrayHandle RGBrcurve = rgbCurves.rcurve; + keyFile.set_double_list("RGB Curves", "rCurve", RGBrcurve); + } + if (!pedited || pedited->rgbCurves.gcurve) { + Glib::ArrayHandle RGBgcurve = rgbCurves.gcurve; + keyFile.set_double_list("RGB Curves", "gCurve", RGBgcurve); + } + if (!pedited || pedited->rgbCurves.bcurve) { + Glib::ArrayHandle RGBbcurve = rgbCurves.bcurve; + keyFile.set_double_list("RGB Curves", "bCurve", RGBbcurve); + } + + // save Color Toning + if (!pedited || pedited->colorToning.enabled) keyFile.set_boolean ("ColorToning", "Enabled", colorToning.enabled); + if (!pedited || pedited->colorToning.method) keyFile.set_string ("ColorToning", "Method", colorToning.method); + if (!pedited || pedited->colorToning.lumamode) keyFile.set_boolean ("ColorToning", "Lumamode", colorToning.lumamode); + if (!pedited || pedited->colorToning.twocolor) keyFile.set_string ("ColorToning", "Twocolor", colorToning.twocolor); + if (!pedited || pedited->colorToning.redlow) keyFile.set_double ("ColorToning", "Redlow", colorToning.redlow); + if (!pedited || pedited->colorToning.greenlow) keyFile.set_double ("ColorToning", "Greenlow", colorToning.greenlow); + if (!pedited || pedited->colorToning.bluelow) keyFile.set_double ("ColorToning", "Bluelow", colorToning.bluelow); + if (!pedited || pedited->colorToning.satlow) keyFile.set_double ("ColorToning", "Satlow", colorToning.satlow); + if (!pedited || pedited->colorToning.balance) keyFile.set_integer ("ColorToning", "Balance", colorToning.balance); + if (!pedited || pedited->colorToning.sathigh) keyFile.set_double ("ColorToning", "Sathigh", colorToning.sathigh); + if (!pedited || pedited->colorToning.redmed) keyFile.set_double ("ColorToning", "Redmed", colorToning.redmed); + if (!pedited || pedited->colorToning.greenmed) keyFile.set_double ("ColorToning", "Greenmed", colorToning.greenmed); + if (!pedited || pedited->colorToning.bluemed) keyFile.set_double ("ColorToning", "Bluemed", colorToning.bluemed); + if (!pedited || pedited->colorToning.redhigh) keyFile.set_double ("ColorToning", "Redhigh", colorToning.redhigh); + if (!pedited || pedited->colorToning.greenhigh) keyFile.set_double ("ColorToning", "Greenhigh", colorToning.greenhigh); + if (!pedited || pedited->colorToning.bluehigh) keyFile.set_double ("ColorToning", "Bluehigh", colorToning.bluehigh); + if (!pedited || pedited->colorToning.autosat) keyFile.set_boolean ("ColorToning", "Autosat", colorToning.autosat); + + if (!pedited || pedited->colorToning.opacityCurve) { + Glib::ArrayHandle curve = colorToning.opacityCurve; + keyFile.set_double_list("ColorToning", "OpacityCurve", curve); + } + if (!pedited || pedited->colorToning.colorCurve) { + Glib::ArrayHandle curve = colorToning.colorCurve; + keyFile.set_double_list("ColorToning", "ColorCurve", curve); + } + if (!pedited || pedited->colorToning.satprotectionthreshold) keyFile.set_integer ("ColorToning", "SatProtectionThreshold", colorToning.satProtectionThreshold ); + if (!pedited || pedited->colorToning.saturatedopacity) keyFile.set_integer ("ColorToning", "SaturatedOpacity", colorToning.saturatedOpacity ); + if (!pedited || pedited->colorToning.strength) keyFile.set_integer ("ColorToning", "Strength", colorToning.strength ); + + if (!pedited || pedited->colorToning.hlColSat) { + Glib::ArrayHandle thresh (colorToning.hlColSat.value, 2, Glib::OWNERSHIP_NONE); + keyFile.set_integer_list("ColorToning", "HighlightsColorSaturation", thresh); + } + if (!pedited || pedited->colorToning.shadowsColSat) { + Glib::ArrayHandle thresh (colorToning.shadowsColSat.value, 2, Glib::OWNERSHIP_NONE); + keyFile.set_integer_list("ColorToning", "ShadowsColorSaturation", thresh); + } + if (!pedited || pedited->colorToning.clcurve) { + Glib::ArrayHandle clcurve = colorToning.clcurve; + keyFile.set_double_list("ColorToning", "ClCurve", clcurve); + } + if (!pedited || pedited->colorToning.cl2curve) { + Glib::ArrayHandle cl2curve = colorToning.cl2curve; + keyFile.set_double_list("ColorToning", "Cl2Curve", cl2curve); + } + + // save raw parameters + if (!pedited || pedited->raw.darkFrame) keyFile.set_string ("RAW", "DarkFrame", relativePathIfInside(fname, fnameAbsolute, raw.dark_frame) ); + if (!pedited || pedited->raw.dfAuto) keyFile.set_boolean ("RAW", "DarkFrameAuto", raw.df_autoselect ); + if (!pedited || pedited->raw.ff_file) keyFile.set_string ("RAW", "FlatFieldFile", relativePathIfInside(fname, fnameAbsolute, raw.ff_file) ); + if (!pedited || pedited->raw.ff_AutoSelect) keyFile.set_boolean ("RAW", "FlatFieldAutoSelect", raw.ff_AutoSelect ); + if (!pedited || pedited->raw.ff_BlurRadius) keyFile.set_integer ("RAW", "FlatFieldBlurRadius", raw.ff_BlurRadius ); + if (!pedited || pedited->raw.ff_BlurType) keyFile.set_string ("RAW", "FlatFieldBlurType", raw.ff_BlurType ); + if (!pedited || pedited->raw.ff_AutoClipControl) keyFile.set_boolean ("RAW", "FlatFieldAutoClipControl", raw.ff_AutoClipControl ); + if (!pedited || pedited->raw.ff_clipControl) keyFile.set_boolean ("RAW", "FlatFieldClipControl", raw.ff_clipControl ); + if (!pedited || pedited->raw.caCorrection) keyFile.set_boolean ("RAW", "CA", raw.ca_autocorrect ); + if (!pedited || pedited->raw.caRed) keyFile.set_double ("RAW", "CARed", raw.cared ); + if (!pedited || pedited->raw.caBlue) keyFile.set_double ("RAW", "CABlue", raw.cablue ); + if (!pedited || pedited->raw.hotPixelFilter) keyFile.set_boolean ("RAW", "HotPixelFilter", raw.hotPixelFilter ); + if (!pedited || pedited->raw.deadPixelFilter) keyFile.set_boolean ("RAW", "DeadPixelFilter", raw.deadPixelFilter ); + if (!pedited || pedited->raw.hotDeadPixelThresh) keyFile.set_integer ("RAW", "HotDeadPixelThresh", raw.hotdeadpix_thresh ); + + if (!pedited || pedited->raw.bayersensor.method) keyFile.set_string ("RAW Bayer", "Method", raw.bayersensor.method ); + if (!pedited || pedited->raw.bayersensor.ccSteps) keyFile.set_integer ("RAW Bayer", "CcSteps", raw.bayersensor.ccSteps); + if (!pedited || pedited->raw.bayersensor.exBlack0) keyFile.set_double ("RAW Bayer", "PreBlack0", raw.bayersensor.black0 ); + if (!pedited || pedited->raw.bayersensor.exBlack1) keyFile.set_double ("RAW Bayer", "PreBlack1", raw.bayersensor.black1 ); + if (!pedited || pedited->raw.bayersensor.exBlack2) keyFile.set_double ("RAW Bayer", "PreBlack2", raw.bayersensor.black2 ); + if (!pedited || pedited->raw.bayersensor.exBlack3) keyFile.set_double ("RAW Bayer", "PreBlack3", raw.bayersensor.black3 ); + if (!pedited || pedited->raw.bayersensor.exTwoGreen) keyFile.set_boolean ("RAW Bayer", "PreTwoGreen", raw.bayersensor.twogreen ); + if (!pedited || pedited->raw.bayersensor.linenoise) keyFile.set_integer ("RAW Bayer", "LineDenoise", raw.bayersensor.linenoise); + if (!pedited || pedited->raw.bayersensor.greenEq) keyFile.set_integer ("RAW Bayer", "GreenEqThreshold", raw.bayersensor.greenthresh); + if (!pedited || pedited->raw.bayersensor.dcbIterations) keyFile.set_integer ("RAW Bayer", "DCBIterations", raw.bayersensor.dcb_iterations ); + if (!pedited || pedited->raw.bayersensor.dcbEnhance) keyFile.set_boolean ("RAW Bayer", "DCBEnhance", raw.bayersensor.dcb_enhance ); + if (!pedited || pedited->raw.bayersensor.lmmseIterations) keyFile.set_integer ("RAW Bayer", "LMMSEIterations", raw.bayersensor.lmmse_iterations ); + //if (!pedited || pedited->raw.bayersensor.allEnhance) keyFile.set_boolean ("RAW Bayer", "ALLEnhance", raw.bayersensor.all_enhance ); + + if (!pedited || pedited->raw.xtranssensor.method) keyFile.set_string ("RAW X-Trans", "Method", raw.xtranssensor.method ); + if (!pedited || pedited->raw.xtranssensor.ccSteps) keyFile.set_integer ("RAW X-Trans", "CcSteps", raw.xtranssensor.ccSteps); + if (!pedited || pedited->raw.xtranssensor.exBlackRed) keyFile.set_double ("RAW X-Trans", "PreBlackRed", raw.xtranssensor.blackred ); + if (!pedited || pedited->raw.xtranssensor.exBlackGreen) keyFile.set_double ("RAW X-Trans", "PreBlackGreen", raw.xtranssensor.blackgreen ); + if (!pedited || pedited->raw.xtranssensor.exBlackBlue) keyFile.set_double ("RAW X-Trans", "PreBlackBlue", raw.xtranssensor.blackblue ); + + + // save raw exposition + if (!pedited || pedited->raw.exPos) keyFile.set_double ("RAW", "PreExposure", raw.expos ); + if (!pedited || pedited->raw.exPreser) keyFile.set_double ("RAW", "PrePreserv", raw.preser ); + + // save exif change list + if (!pedited || pedited->exif) { + for (ExifPairs::const_iterator i=exif.begin(); i!=exif.end(); i++) + keyFile.set_string ("Exif", i->first, i->second); + } + + // save iptc change list + if (!pedited || pedited->iptc) { + for (IPTCPairs::const_iterator i=iptc.begin(); i!=iptc.end(); i++) { + Glib::ArrayHandle values = i->second; + keyFile.set_string_list ("IPTC", i->first, values); + } + } + + Glib::ustring sPParams = keyFile.to_data(); + + int error1, error2; + error1 = write (fname , sPParams); + if (fname2.length()) { + + error2 = write (fname2, sPParams); + // If at least one file has been saved, it's a success + return error1 & error2; + } + else + return error1; +} + +int ProcParams::write (Glib::ustring &fname, Glib::ustring &content) const { + + int error = 0; + if (fname.length()) { + FILE *f; + f = safe_g_fopen (fname, "wt"); + + if (f==NULL) + error = 1; + else { + fprintf (f, "%s", content.c_str()); + fclose (f); + } + } + return error; +} + +int ProcParams::load (Glib::ustring fname, ParamsEdited* pedited) { + setlocale(LC_NUMERIC, "C"); // to set decimal point to "." + if (fname.empty()) + return 1; + + SafeKeyFile keyFile; + try { + //setDefaults (); + if (pedited) + pedited->set(false); + + FILE* f = safe_g_fopen (fname, "rt"); + if (!f) + return 1; + char* buffer = new char[1024]; + std::ostringstream ostr; + while (fgets (buffer, 1024, f)) + ostr << buffer << "\n"; + delete [] buffer; + if (!keyFile.load_from_data (ostr.str())) + return 1; + fclose (f); + + // load tonecurve: + +ppVersion = PPVERSION; +appVersion = APPVERSION; +if (keyFile.has_group ("Version")) { + if (keyFile.has_key ("Version", "AppVersion")) appVersion = keyFile.get_string ("Version", "AppVersion"); + if (keyFile.has_key ("Version", "Version")) ppVersion = keyFile.get_integer ("Version", "Version"); +} +//printf("ProcParams::load called ppVersion=%i\n",ppVersion); + +if (keyFile.has_group ("General")) { + if (keyFile.has_key ("General", "Rank")) { rank = keyFile.get_integer ("General", "Rank"); if (pedited) pedited->general.rank = true; } + if (keyFile.has_key ("General", "ColorLabel")) { colorlabel = keyFile.get_integer ("General", "ColorLabel"); if (pedited) pedited->general.colorlabel = true; } + if (keyFile.has_key ("General", "InTrash")) { inTrash = keyFile.get_boolean ("General", "InTrash"); if (pedited) pedited->general.intrash = true; } +} + +if (keyFile.has_group ("Exposure")) { + if (ppVersiontoneCurve.autoexp = true; } + + if (keyFile.has_key ("Exposure", "Clip")) { toneCurve.clip = keyFile.get_double ("Exposure", "Clip"); if (pedited) pedited->toneCurve.clip = true; } + if (keyFile.has_key ("Exposure", "Compensation")) { toneCurve.expcomp = keyFile.get_double ("Exposure", "Compensation"); if (pedited) pedited->toneCurve.expcomp = true; } + if (keyFile.has_key ("Exposure", "Brightness")) { toneCurve.brightness = keyFile.get_integer ("Exposure", "Brightness"); if (pedited) pedited->toneCurve.brightness = true; } + if (keyFile.has_key ("Exposure", "Contrast")) { toneCurve.contrast = keyFile.get_integer ("Exposure", "Contrast"); if (pedited) pedited->toneCurve.contrast = true; } + if (keyFile.has_key ("Exposure", "Saturation")) { toneCurve.saturation = keyFile.get_integer ("Exposure", "Saturation"); if (pedited) pedited->toneCurve.saturation = true; } + if (keyFile.has_key ("Exposure", "Black")) { toneCurve.black = keyFile.get_integer ("Exposure", "Black"); if (pedited) pedited->toneCurve.black = true; } + if (keyFile.has_key ("Exposure", "HighlightCompr")) { toneCurve.hlcompr = keyFile.get_integer ("Exposure", "HighlightCompr"); if (pedited) pedited->toneCurve.hlcompr = true; } + if (keyFile.has_key ("Exposure", "HighlightComprThreshold")) { toneCurve.hlcomprthresh = keyFile.get_integer ("Exposure", "HighlightComprThreshold"); if (pedited) pedited->toneCurve.hlcomprthresh = true; } + if (keyFile.has_key ("Exposure", "ShadowCompr")) { toneCurve.shcompr = keyFile.get_integer ("Exposure", "ShadowCompr"); if (pedited) pedited->toneCurve.shcompr = true; } + // load highlight recovery settings + if (toneCurve.shcompr > 100) toneCurve.shcompr = 100; // older pp3 files can have values above 100. + if (keyFile.has_key ("Exposure", "CurveMode")) { + Glib::ustring sMode = keyFile.get_string ("Exposure", "CurveMode"); + if (sMode == "Standard") toneCurve.curveMode = ToneCurveParams::TC_MODE_STD; + else if (sMode == "FilmLike") toneCurve.curveMode = ToneCurveParams::TC_MODE_FILMLIKE; + else if (sMode == "SatAndValueBlending") toneCurve.curveMode = ToneCurveParams::TC_MODE_SATANDVALBLENDING; + else if (sMode == "WeightedStd") toneCurve.curveMode = ToneCurveParams::TC_MODE_WEIGHTEDSTD; + else if (sMode == "Luminance") toneCurve.curveMode = ToneCurveParams::TC_MODE_LUMINANCE; + if (pedited) pedited->toneCurve.curveMode = true; + } + if (keyFile.has_key ("Exposure", "CurveMode2")) { + Glib::ustring sMode = keyFile.get_string ("Exposure", "CurveMode2"); + if (sMode == "Standard") toneCurve.curveMode2 = ToneCurveParams::TC_MODE_STD; + else if (sMode == "FilmLike") toneCurve.curveMode2 = ToneCurveParams::TC_MODE_FILMLIKE; + else if (sMode == "SatAndValueBlending") toneCurve.curveMode2 = ToneCurveParams::TC_MODE_SATANDVALBLENDING; + else if (sMode == "WeightedStd") toneCurve.curveMode2 = ToneCurveParams::TC_MODE_WEIGHTEDSTD; + else if (sMode == "Luminance") toneCurve.curveMode2 = ToneCurveParams::TC_MODE_LUMINANCE; + if (pedited) pedited->toneCurve.curveMode2 = true; + } + if (ppVersion>200) { + if (keyFile.has_key ("Exposure", "Curve")) { toneCurve.curve = keyFile.get_double_list ("Exposure", "Curve"); if (pedited) pedited->toneCurve.curve = true; } + if (keyFile.has_key ("Exposure", "Curve2")) { toneCurve.curve2 = keyFile.get_double_list ("Exposure", "Curve2"); if (pedited) pedited->toneCurve.curve2 = true; } + } +} +if (keyFile.has_group ("HLRecovery")) { + if (keyFile.has_key ("HLRecovery", "Enabled")) { toneCurve.hrenabled = keyFile.get_boolean ("HLRecovery", "Enabled"); if (pedited) pedited->toneCurve.hrenabled = true; } + if (keyFile.has_key ("HLRecovery", "Method")) { toneCurve.method = keyFile.get_string ("HLRecovery", "Method"); if (pedited) pedited->toneCurve.method = true; } +} + + // load channel mixer curve +if (keyFile.has_group ("Channel Mixer")) { + if (keyFile.has_key ("Channel Mixer", "Red") && keyFile.has_key ("Channel Mixer", "Green") && keyFile.has_key ("Channel Mixer", "Blue")) { + if (pedited) { + pedited->chmixer.red[0] = pedited->chmixer.red[1] = pedited->chmixer.red[2] = true; + pedited->chmixer.green[0] = pedited->chmixer.green[1] = pedited->chmixer.green[2] = true; + pedited->chmixer.blue[0] = pedited->chmixer.blue[1] = pedited->chmixer.blue[2] = true; + } + + Glib::ArrayHandle rmix = keyFile.get_integer_list ("Channel Mixer", "Red"); + Glib::ArrayHandle gmix = keyFile.get_integer_list ("Channel Mixer", "Green"); + Glib::ArrayHandle bmix = keyFile.get_integer_list ("Channel Mixer", "Blue"); + memcpy (chmixer.red, rmix.data(), 3*sizeof(int)); + memcpy (chmixer.green, gmix.data(), 3*sizeof(int)); + memcpy (chmixer.blue, bmix.data(), 3*sizeof(int)); + } +} + + // load black & white +if (keyFile.has_group ("Black & White")) { + if (keyFile.has_key ("Black & White", "Enabled")) { blackwhite.enabled = keyFile.get_boolean ("Black & White", "Enabled"); if (pedited) pedited->blackwhite.enabled = true; } + if (keyFile.has_key ("Black & White", "Method")) { blackwhite.method = keyFile.get_string ("Black & White", "Method"); if (pedited) pedited->blackwhite.method = true; } + + if (keyFile.has_key ("Black & White", "Auto")) { blackwhite.autoc = keyFile.get_boolean ("Black & White", "Auto"); if (pedited) pedited->blackwhite.autoc = true; } + if (keyFile.has_key ("Black & White", "ComplementaryColors")) { blackwhite.enabledcc = keyFile.get_boolean ("Black & White", "ComplementaryColors"); if (pedited) pedited->blackwhite.enabledcc = true; } + if (keyFile.has_key ("Black & White", "MixerRed")) { blackwhite.mixerRed = keyFile.get_integer ("Black & White", "MixerRed"); if (pedited) pedited->blackwhite.mixerRed = true; } + if (keyFile.has_key ("Black & White", "MixerOrange")) { blackwhite.mixerOrange = keyFile.get_integer ("Black & White", "MixerOrange"); if (pedited) pedited->blackwhite.mixerOrange = true; } + if (keyFile.has_key ("Black & White", "MixerYellow")) { blackwhite.mixerYellow = keyFile.get_integer ("Black & White", "MixerYellow"); if (pedited) pedited->blackwhite.mixerYellow = true; } + if (keyFile.has_key ("Black & White", "MixerGreen")) { blackwhite.mixerGreen = keyFile.get_integer ("Black & White", "MixerGreen"); if (pedited) pedited->blackwhite.mixerGreen = true; } + if (keyFile.has_key ("Black & White", "MixerCyan")) { blackwhite.mixerCyan = keyFile.get_integer ("Black & White", "MixerCyan"); if (pedited) pedited->blackwhite.mixerCyan = true; } + if (keyFile.has_key ("Black & White", "MixerBlue")) { blackwhite.mixerBlue = keyFile.get_integer ("Black & White", "MixerBlue"); if (pedited) pedited->blackwhite.mixerBlue = true; } + if (keyFile.has_key ("Black & White", "MixerMagenta")) { blackwhite.mixerMagenta = keyFile.get_integer ("Black & White", "MixerMagenta"); if (pedited) pedited->blackwhite.mixerMagenta = true; } + if (keyFile.has_key ("Black & White", "MixerPurple")) { blackwhite.mixerPurple = keyFile.get_integer ("Black & White", "MixerPurple"); if (pedited) pedited->blackwhite.mixerPurple = true; } + if (keyFile.has_key ("Black & White", "GammaRed")) { blackwhite.gammaRed = keyFile.get_integer ("Black & White", "GammaRed"); if (pedited) pedited->blackwhite.gammaRed = true; } + if (keyFile.has_key ("Black & White", "GammaGreen")) { blackwhite.gammaGreen = keyFile.get_integer ("Black & White", "GammaGreen"); if (pedited) pedited->blackwhite.gammaGreen = true; } + if (keyFile.has_key ("Black & White", "GammaBlue")) { blackwhite.gammaBlue = keyFile.get_integer ("Black & White", "GammaBlue"); if (pedited) pedited->blackwhite.gammaBlue = true; } + if (keyFile.has_key ("Black & White", "Filter")) { blackwhite.filter = keyFile.get_string ("Black & White", "Filter"); if (pedited) pedited->blackwhite.filter = true; } + if (keyFile.has_key ("Black & White", "Setting")) { blackwhite.setting = keyFile.get_string ("Black & White", "Setting"); if (pedited) pedited->blackwhite.setting = true; } + if (keyFile.has_key ("Black & White", "LuminanceCurve")) { blackwhite.luminanceCurve = keyFile.get_double_list ("Black & White", "LuminanceCurve"); if (pedited) pedited->blackwhite.luminanceCurve = true; } + if (keyFile.has_key ("Black & White", "BeforeCurve")) { blackwhite.beforeCurve = keyFile.get_double_list ("Black & White", "BeforeCurve"); if (pedited) pedited->blackwhite.beforeCurve = true; } + if (keyFile.has_key ("Black & White", "Algorithm")) { blackwhite.algo = keyFile.get_string ("Black & White", "Algorithm"); if (pedited) pedited->blackwhite.algo = true; } + if (keyFile.has_key ("Black & White", "BeforeCurveMode")) { + Glib::ustring sMode = keyFile.get_string ("Black & White", "BeforeCurveMode"); + if (sMode == "Standard") blackwhite.beforeCurveMode = BlackWhiteParams::TC_MODE_STD_BW; + else if (sMode == "FilmLike") blackwhite.beforeCurveMode = BlackWhiteParams::TC_MODE_FILMLIKE_BW; + else if (sMode == "SatAndValueBlending") blackwhite.beforeCurveMode = BlackWhiteParams::TC_MODE_SATANDVALBLENDING_BW; + else if (sMode == "WeightedStd") blackwhite.beforeCurveMode = BlackWhiteParams::TC_MODE_WEIGHTEDSTD_BW; + if (pedited) pedited->blackwhite.beforeCurveMode = true; + } + if (keyFile.has_key ("Black & White", "AfterCurve")) { blackwhite.afterCurve = keyFile.get_double_list ("Black & White", "AfterCurve"); if (pedited) pedited->blackwhite.afterCurve = true; } + if (keyFile.has_key ("Black & White", "AfterCurveMode")) { + Glib::ustring sMode2 = keyFile.get_string ("Black & White", "AfterCurveMode"); + if (sMode2 == "Standard") blackwhite.afterCurveMode = BlackWhiteParams::TC_MODE_STD_BW; + else if (sMode2 == "WeightedStd") blackwhite.afterCurveMode = BlackWhiteParams::TC_MODE_WEIGHTEDSTD_BW; + if (pedited) pedited->blackwhite.afterCurveMode = true; + } +} + + // load luma curve +if (keyFile.has_group ("Luminance Curve")) { + if (keyFile.has_key ("Luminance Curve", "Brightness")) { labCurve.brightness = keyFile.get_integer ("Luminance Curve", "Brightness"); if (pedited) pedited->labCurve.brightness = true; } + if (keyFile.has_key ("Luminance Curve", "Contrast")) { labCurve.contrast = keyFile.get_integer ("Luminance Curve", "Contrast"); if (pedited) pedited->labCurve.contrast = true; } + + if (ppVersion < 303) { + // transform Saturation into Chromaticity + // if Saturation == 0, should we set BWToning on? + if (keyFile.has_key ("Luminance Curve", "Saturation")) { labCurve.chromaticity = keyFile.get_integer ("Luminance Curve", "Saturation"); if (pedited) pedited->labCurve.chromaticity = true; } + // transform AvoidColorClipping into AvoidColorShift + if (keyFile.has_key ("Luminance Curve", "AvoidColorClipping")) { labCurve.avoidcolorshift = keyFile.get_boolean ("Luminance Curve", "AvoidColorClipping"); if (pedited) pedited->labCurve.avoidcolorshift = true; } + } + else { + if (keyFile.has_key ("Luminance Curve", "Chromaticity")) { labCurve.chromaticity = keyFile.get_integer ("Luminance Curve", "Chromaticity"); if (pedited) pedited->labCurve.chromaticity = true; } + if (keyFile.has_key ("Luminance Curve", "AvoidColorShift")) { labCurve.avoidcolorshift = keyFile.get_boolean ("Luminance Curve", "AvoidColorShift"); if (pedited) pedited->labCurve.avoidcolorshift = true; } + if (keyFile.has_key ("Luminance Curve", "RedAndSkinTonesProtection")) { labCurve.rstprotection = keyFile.get_double ("Luminance Curve", "RedAndSkinTonesProtection"); if (pedited) pedited->labCurve.rstprotection = true; } + } + if (keyFile.has_key ("Luminance Curve", "LCredsk")) { labCurve.lcredsk = keyFile.get_boolean ("Luminance Curve", "LCredsk"); if (pedited) pedited->labCurve.lcredsk = true; } + if (ppVersion < 314) + // Backward compatibility: If BWtoning is true, Chromaticity has to be set to -100, which will produce the same effect + // and will enable the b&w toning mode ('a' & 'b' curves) + if (keyFile.has_key ("Luminance Curve", "BWtoning")) { + if ( keyFile.get_boolean ("Luminance Curve", "BWtoning")) { + labCurve.chromaticity = -100; + if (pedited) pedited->labCurve.chromaticity = true; + } + } + if (keyFile.has_key ("Luminance Curve", "LCurve")) { labCurve.lcurve = keyFile.get_double_list ("Luminance Curve", "LCurve"); if (pedited) pedited->labCurve.lcurve = true; } + if (keyFile.has_key ("Luminance Curve", "aCurve")) { labCurve.acurve = keyFile.get_double_list ("Luminance Curve", "aCurve"); if (pedited) pedited->labCurve.acurve = true; } + if (keyFile.has_key ("Luminance Curve", "bCurve")) { labCurve.bcurve = keyFile.get_double_list ("Luminance Curve", "bCurve"); if (pedited) pedited->labCurve.bcurve = true; } + if (keyFile.has_key ("Luminance Curve", "ccCurve")) { labCurve.cccurve = keyFile.get_double_list ("Luminance Curve", "ccCurve"); if (pedited) pedited->labCurve.cccurve = true; } + if (keyFile.has_key ("Luminance Curve", "chCurve")) { labCurve.chcurve = keyFile.get_double_list ("Luminance Curve", "chCurve"); if (pedited) pedited->labCurve.chcurve = true; } + if (keyFile.has_key ("Luminance Curve", "lhCurve")) { labCurve.lhcurve = keyFile.get_double_list ("Luminance Curve", "lhCurve"); if (pedited) pedited->labCurve.lhcurve = true; } + if (keyFile.has_key ("Luminance Curve", "hhCurve")) { labCurve.hhcurve = keyFile.get_double_list ("Luminance Curve", "hhCurve"); if (pedited) pedited->labCurve.hhcurve = true; } + if (keyFile.has_key ("Luminance Curve", "LcCurve")) { labCurve.lccurve = keyFile.get_double_list ("Luminance Curve", "LcCurve"); if (pedited) pedited->labCurve.lccurve = true; } + if (keyFile.has_key ("Luminance Curve", "ClCurve")) { labCurve.clcurve = keyFile.get_double_list ("Luminance Curve", "ClCurve"); if (pedited) pedited->labCurve.clcurve = true; } + + } + + // load sharpening +if (keyFile.has_group ("Sharpening")) { + if (keyFile.has_key ("Sharpening", "Enabled")) { sharpening.enabled = keyFile.get_boolean ("Sharpening", "Enabled"); if (pedited) pedited->sharpening.enabled = true; } + if (keyFile.has_key ("Sharpening", "Radius")) { sharpening.radius = keyFile.get_double ("Sharpening", "Radius"); if (pedited) pedited->sharpening.radius = true; } + if (keyFile.has_key ("Sharpening", "Amount")) { sharpening.amount = keyFile.get_integer ("Sharpening", "Amount"); if (pedited) pedited->sharpening.amount = true; } + if (keyFile.has_key ("Sharpening", "Threshold")) { + if (ppVersion < 302) { + int thresh = min(keyFile.get_integer ("Sharpening", "Threshold"), 2000); + sharpening.threshold.setValues(thresh, thresh, 2000, 2000); // TODO: 2000 is the maximum value and is taken of rtgui/sharpening.cc ; should be changed by the tool modularization + } + else { + Glib::ArrayHandle thresh = keyFile.get_integer_list ("Sharpening", "Threshold"); + sharpening.threshold.setValues(thresh.data()[0], thresh.data()[1], min(thresh.data()[2], 2000), min(thresh.data()[3], 2000)); + } + if (pedited) pedited->sharpening.threshold = true; + } + if (keyFile.has_key ("Sharpening", "OnlyEdges")) { sharpening.edgesonly = keyFile.get_boolean ("Sharpening", "OnlyEdges"); if (pedited) pedited->sharpening.edgesonly = true; } + if (keyFile.has_key ("Sharpening", "EdgedetectionRadius")) { sharpening.edges_radius = keyFile.get_double ("Sharpening", "EdgedetectionRadius"); if (pedited) pedited->sharpening.edges_radius = true; } + if (keyFile.has_key ("Sharpening", "EdgeTolerance")) { sharpening.edges_tolerance = keyFile.get_integer ("Sharpening", "EdgeTolerance"); if (pedited) pedited->sharpening.edges_tolerance = true; } + if (keyFile.has_key ("Sharpening", "HalocontrolEnabled")) { sharpening.halocontrol = keyFile.get_boolean ("Sharpening", "HalocontrolEnabled"); if (pedited) pedited->sharpening.halocontrol = true; } + if (keyFile.has_key ("Sharpening", "HalocontrolAmount")) { sharpening.halocontrol_amount = keyFile.get_integer ("Sharpening", "HalocontrolAmount"); if (pedited) pedited->sharpening.halocontrol_amount = true; } + if (keyFile.has_key ("Sharpening", "Method")) { sharpening.method = keyFile.get_string ("Sharpening", "Method"); if (pedited) pedited->sharpening.method = true; } + if (keyFile.has_key ("Sharpening", "DeconvRadius")) { sharpening.deconvradius = keyFile.get_double ("Sharpening", "DeconvRadius"); if (pedited) pedited->sharpening.deconvradius = true; } + if (keyFile.has_key ("Sharpening", "DeconvAmount")) { sharpening.deconvamount = keyFile.get_integer ("Sharpening", "DeconvAmount"); if (pedited) pedited->sharpening.deconvamount = true; } + if (keyFile.has_key ("Sharpening", "DeconvDamping")) { sharpening.deconvdamping = keyFile.get_integer ("Sharpening", "DeconvDamping"); if (pedited) pedited->sharpening.deconvdamping = true; } + if (keyFile.has_key ("Sharpening", "DeconvIterations")) { sharpening.deconviter = keyFile.get_integer ("Sharpening", "DeconvIterations"); if (pedited) pedited->sharpening.deconviter = true; } +} + + // load edge sharpening +if (keyFile.has_group ("SharpenEdge")) { + if (keyFile.has_key ("SharpenEdge", "Enabled")) { sharpenEdge.enabled = keyFile.get_boolean ("SharpenEdge", "Enabled"); if (pedited) pedited->sharpenEdge.enabled = true; } + if (keyFile.has_key ("SharpenEdge", "Passes")) { sharpenEdge.passes = keyFile.get_integer ("SharpenEdge", "Passes"); if (pedited) pedited->sharpenEdge.passes = true; } + if (keyFile.has_key ("SharpenEdge", "Strength")) { sharpenEdge.amount = keyFile.get_double ("SharpenEdge", "Strength"); if (pedited) pedited->sharpenEdge.amount = true; } + if (keyFile.has_key ("SharpenEdge", "ThreeChannels")) { sharpenEdge.threechannels = keyFile.get_boolean ("SharpenEdge", "ThreeChannels"); if (pedited) pedited->sharpenEdge.threechannels = true; } +} + + // load micro-contrast sharpening +if (keyFile.has_group ("SharpenMicro")) { + if (keyFile.has_key ("SharpenMicro", "Enabled")) { sharpenMicro.enabled = keyFile.get_boolean ("SharpenMicro", "Enabled"); if (pedited) pedited->sharpenMicro.enabled = true; } + if (keyFile.has_key ("SharpenMicro", "Matrix")) { sharpenMicro.matrix = keyFile.get_boolean ("SharpenMicro", "Matrix"); if (pedited) pedited->sharpenMicro.matrix = true; } + if (keyFile.has_key ("SharpenMicro", "Strength")) { sharpenMicro.amount = keyFile.get_double ("SharpenMicro", "Strength"); if (pedited) pedited->sharpenMicro.amount = true; } + if (keyFile.has_key ("SharpenMicro", "Uniformity")) { sharpenMicro.uniformity = keyFile.get_double ("SharpenMicro", "Uniformity"); if (pedited) pedited->sharpenMicro.uniformity = true; } +} + + // load vibrance +if (keyFile.has_group ("Vibrance")) { + if (keyFile.has_key ("Vibrance", "Enabled")) { vibrance.enabled = keyFile.get_boolean ("Vibrance", "Enabled"); if (pedited) pedited->vibrance.enabled = true; } + if (keyFile.has_key ("Vibrance", "Pastels")) { vibrance.pastels = keyFile.get_integer ("Vibrance", "Pastels"); if (pedited) pedited->vibrance.pastels = true; } + if (keyFile.has_key ("Vibrance", "Saturated")) { vibrance.saturated = keyFile.get_integer ("Vibrance", "Saturated"); if (pedited) pedited->vibrance.saturated = true; } + if (keyFile.has_key ("Vibrance", "PSThreshold")) { + if (ppVersion < 302) { + int thresh = keyFile.get_integer ("Vibrance", "PSThreshold"); + vibrance.psthreshold.setValues(thresh, thresh); + } + else { + Glib::ArrayHandle thresh = keyFile.get_integer_list ("Vibrance", "PSThreshold"); + vibrance.psthreshold.setValues(thresh.data()[0], thresh.data()[1]); + } + if (pedited) pedited->vibrance.psthreshold = true; + } + if (keyFile.has_key ("Vibrance", "ProtectSkins")) { vibrance.protectskins = keyFile.get_boolean ("Vibrance", "ProtectSkins"); if (pedited) pedited->vibrance.protectskins = true; } + if (keyFile.has_key ("Vibrance", "AvoidColorShift")) { vibrance.avoidcolorshift = keyFile.get_boolean ("Vibrance", "AvoidColorShift"); if (pedited) pedited->vibrance.avoidcolorshift = true; } + if (keyFile.has_key ("Vibrance", "PastSatTog")) { vibrance.pastsattog = keyFile.get_boolean ("Vibrance", "PastSatTog"); if (pedited) pedited->vibrance.pastsattog = true; } + if (keyFile.has_key ("Vibrance", "SkinTonesCurve")) { vibrance.skintonescurve = keyFile.get_double_list ("Vibrance", "SkinTonesCurve"); if (pedited) pedited->vibrance.skintonescurve = true; } +} + + // load colorBoost +/*if (keyFile.has_group ("Color Boost")) { + if (keyFile.has_key ("Color Boost", "Amount")) { colorBoost.amount = keyFile.get_integer ("Color Boost", "Amount"); if (pedited) pedited->colorBoost.amount = true; } + else { + int a=0, b=0; + if (keyFile.has_key ("Color Boost", "ChannelA")) { a = keyFile.get_integer ("Color Boost", "ChannelA"); } + if (keyFile.has_key ("Color Boost", "ChannelB")) { b = keyFile.get_integer ("Color Boost", "ChannelB"); } + colorBoost.amount = (a+b) / 2; + if (pedited) pedited->colorBoost.amount = true; + } + if (keyFile.has_key ("Color Boost", "AvoidColorClipping")) { colorBoost.avoidclip = keyFile.get_boolean ("Color Boost", "AvoidColorClipping"); if (pedited) pedited->colorBoost.avoidclip = true; } + if (keyFile.has_key ("Color Boost", "SaturationLimiter")) { colorBoost.enable_saturationlimiter= keyFile.get_boolean ("Color Boost", "SaturationLimiter"); if (pedited) pedited->colorBoost.enable_saturationlimiter = true; } + if (keyFile.has_key ("Color Boost", "SaturationLimit")) { colorBoost.saturationlimit = keyFile.get_double ("Color Boost", "SaturationLimit"); if (pedited) pedited->colorBoost.saturationlimit = true; } +}*/ + + // load wb +if (keyFile.has_group ("White Balance")) { + if (keyFile.has_key ("White Balance", "Setting")) { wb.method = keyFile.get_string ("White Balance", "Setting"); if (pedited) pedited->wb.method = true; } + if (keyFile.has_key ("White Balance", "Temperature")) { wb.temperature = keyFile.get_integer ("White Balance", "Temperature"); if (pedited) pedited->wb.temperature = true; } + if (keyFile.has_key ("White Balance", "Green")) { wb.green = keyFile.get_double ("White Balance", "Green"); if (pedited) pedited->wb.green = true; } + if (keyFile.has_key ("White Balance", "Equal")) { wb.equal = keyFile.get_double ("White Balance", "Equal"); if (pedited) pedited->wb.equal = true; } +} + + // load colorShift +/*if (keyFile.has_group ("Color Shift")) { + if (keyFile.has_key ("Color Shift", "ChannelA")) { colorShift.a = keyFile.get_double ("Color Shift", "ChannelA"); if (pedited) pedited->colorShift.a = true; } + if (keyFile.has_key ("Color Shift", "ChannelB")) { colorShift.b = keyFile.get_double ("Color Shift", "ChannelB"); if (pedited) pedited->colorShift.b = true; } +}*/ + + // load defringe +if (keyFile.has_group ("Defringing")) { + if (keyFile.has_key ("Defringing", "Enabled")) { defringe.enabled = keyFile.get_boolean ("Defringing", "Enabled"); if (pedited) pedited->defringe.enabled = true; } + if (keyFile.has_key ("Defringing", "Radius")) { defringe.radius = keyFile.get_double ("Defringing", "Radius"); if (pedited) pedited->defringe.radius = true; } + if (keyFile.has_key ("Defringing", "Threshold")) { defringe.threshold = (float)keyFile.get_integer ("Defringing", "Threshold"); if (pedited) pedited->defringe.threshold = true; } + if (ppVersion < 310) { + defringe.threshold = sqrt(defringe.threshold * 33.f/5.f); + } + if (keyFile.has_key ("Defringing", "HueCurve")) { defringe.huecurve = keyFile.get_double_list ("Defringing", "HueCurve"); if (pedited) pedited->defringe.huecurve = true; } +} + // load colorappearance +if (keyFile.has_group ("Color appearance")) { + if (keyFile.has_key ("Color appearance", "Enabled")) {colorappearance.enabled = keyFile.get_boolean ("Color appearance", "Enabled"); if (pedited) pedited->colorappearance.enabled = true; } + if (keyFile.has_key ("Color appearance", "Degree")) {colorappearance.degree = keyFile.get_integer ("Color appearance", "Degree"); if (pedited) pedited->colorappearance.degree = true; } + if (keyFile.has_key ("Color appearance", "AutoDegree")) {colorappearance.autodegree = keyFile.get_boolean ("Color appearance", "AutoDegree"); if (pedited) pedited->colorappearance.autodegree = true; } + if (keyFile.has_key ("Color appearance", "Surround")) {colorappearance.surround = keyFile.get_string ("Color appearance", "Surround"); if (pedited) pedited->colorappearance.surround = true; } +// if (keyFile.has_key ("Color appearance", "Background")) {colorappearance.backgrd = keyFile.get_integer ("Color appearance", "Background"); if (pedited) pedited->colorappearance.backgrd = true; } + if (keyFile.has_key ("Color appearance", "AdaptLum")) {colorappearance.adaplum = keyFile.get_double ("Color appearance", "AdaptLum"); if (pedited) pedited->colorappearance.adaplum = true; } + if (keyFile.has_key ("Color appearance", "Badpixsl")) {colorappearance.badpixsl = keyFile.get_integer ("Color appearance", "Badpixsl"); if (pedited) pedited->colorappearance.badpixsl = true; } + if (keyFile.has_key ("Color appearance", "Model")) {colorappearance.wbmodel = keyFile.get_string ("Color appearance", "Model"); if (pedited) pedited->colorappearance.wbmodel = true; } + if (keyFile.has_key ("Color appearance", "Algorithm")) {colorappearance.algo = keyFile.get_string ("Color appearance", "Algorithm"); if (pedited) pedited->colorappearance.algo = true; } + if (keyFile.has_key ("Color appearance", "J-Light")) {colorappearance.jlight = keyFile.get_double ("Color appearance", "J-Light"); if (pedited) pedited->colorappearance.jlight = true; } + if (keyFile.has_key ("Color appearance", "Q-Bright")) {colorappearance.qbright = keyFile.get_double ("Color appearance", "Q-Bright"); if (pedited) pedited->colorappearance.qbright = true; } + if (keyFile.has_key ("Color appearance", "C-Chroma")) {colorappearance.chroma = keyFile.get_double ("Color appearance", "C-Chroma"); if (pedited) pedited->colorappearance.chroma = true; } + if (keyFile.has_key ("Color appearance", "S-Chroma")) {colorappearance.schroma = keyFile.get_double ("Color appearance", "S-Chroma"); if (pedited) pedited->colorappearance.schroma = true; } + if (keyFile.has_key ("Color appearance", "M-Chroma")) {colorappearance.mchroma = keyFile.get_double ("Color appearance", "M-Chroma"); if (pedited) pedited->colorappearance.mchroma = true; } + if (keyFile.has_key ("Color appearance", "RSTProtection")) {colorappearance.rstprotection = keyFile.get_double ("Color appearance", "RSTProtection"); if (pedited) pedited->colorappearance.rstprotection = true; } + if (keyFile.has_key ("Color appearance", "J-Contrast")) {colorappearance.contrast = keyFile.get_double ("Color appearance", "J-Contrast"); if (pedited) pedited->colorappearance.contrast = true; } + if (keyFile.has_key ("Color appearance", "Q-Contrast")) {colorappearance.qcontrast = keyFile.get_double ("Color appearance", "Q-Contrast"); if (pedited) pedited->colorappearance.qcontrast = true; } + if (keyFile.has_key ("Color appearance", "H-Hue")) {colorappearance.colorh = keyFile.get_double ("Color appearance", "H-Hue"); if (pedited) pedited->colorappearance.colorh = true; } + if (keyFile.has_key ("Color appearance", "AdaptScene")) {colorappearance.adapscen = keyFile.get_double ("Color appearance", "AdaptScene"); if (pedited) pedited->colorappearance.adapscen = true; } + if (keyFile.has_key ("Color appearance", "AutoAdapscen")) {colorappearance.autoadapscen = keyFile.get_boolean ("Color appearance", "AutoAdapscen"); if (pedited) pedited->colorappearance.autoadapscen = true; } + if (keyFile.has_key ("Color appearance", "SurrSource")) {colorappearance.surrsource = keyFile.get_boolean ("Color appearance", "SurrSource"); if (pedited) pedited->colorappearance.surrsource = true; } + if (keyFile.has_key ("Color appearance", "Gamut")) {colorappearance.gamut = keyFile.get_boolean ("Color appearance", "Gamut"); if (pedited) pedited->colorappearance.gamut = true; } +// if (keyFile.has_key ("Color appearance", "Badpix")) {colorappearance.badpix = keyFile.get_boolean ("Color appearance", "Badpix"); if (pedited) pedited->colorappearance.badpix = true; } + if (keyFile.has_key ("Color appearance", "Datacie")) {colorappearance.datacie = keyFile.get_boolean ("Color appearance", "Datacie"); if (pedited) pedited->colorappearance.datacie = true; } + if (keyFile.has_key ("Color appearance", "Tonecie")) {colorappearance.tonecie = keyFile.get_boolean ("Color appearance", "Tonecie"); if (pedited) pedited->colorappearance.tonecie = true; } +// if (keyFile.has_key ("Color appearance", "Sharpcie")) {colorappearance.sharpcie = keyFile.get_boolean ("Color appearance", "Sharpcie"); if (pedited) pedited->colorappearance.sharpcie = true; } + if (keyFile.has_key ("Color appearance", "CurveMode")) { + Glib::ustring sMode = keyFile.get_string ("Color appearance", "CurveMode"); + if (sMode == "Lightness") colorappearance.curveMode = ColorAppearanceParams::TC_MODE_LIGHT; + else if (sMode == "Brightness") colorappearance.curveMode = ColorAppearanceParams::TC_MODE_BRIGHT; + if (pedited) pedited->colorappearance.curveMode = true; + } + if (keyFile.has_key ("Color appearance", "CurveMode2")) { + Glib::ustring sMode = keyFile.get_string ("Color appearance", "CurveMode2"); + if (sMode == "Lightness") colorappearance.curveMode2 = ColorAppearanceParams::TC_MODE_LIGHT; + else if (sMode == "Brightness") colorappearance.curveMode2 = ColorAppearanceParams::TC_MODE_BRIGHT; + if (pedited) pedited->colorappearance.curveMode2 = true; + } + if (keyFile.has_key ("Color appearance", "CurveMode3")) { + Glib::ustring sMode = keyFile.get_string ("Color appearance", "CurveMode3"); + if (sMode == "Chroma") colorappearance.curveMode3 = ColorAppearanceParams::TC_MODE_CHROMA; + else if (sMode == "Saturation") colorappearance.curveMode3 = ColorAppearanceParams::TC_MODE_SATUR; + else if (sMode == "Colorfullness") colorappearance.curveMode3 = ColorAppearanceParams::TC_MODE_COLORF; + + if (pedited) pedited->colorappearance.curveMode3 = true; + } + + if (ppVersion>200) { + if (keyFile.has_key ("Color appearance", "Curve")) { colorappearance.curve = keyFile.get_double_list ("Color appearance", "Curve"); if (pedited) pedited->colorappearance.curve = true; } + if (keyFile.has_key ("Color appearance", "Curve2")) { colorappearance.curve2 = keyFile.get_double_list ("Color appearance", "Curve2"); if (pedited) pedited->colorappearance.curve2 = true; } + if (keyFile.has_key ("Color appearance", "Curve3")) { colorappearance.curve3 = keyFile.get_double_list ("Color appearance", "Curve3"); if (pedited) pedited->colorappearance.curve3 = true; } + } + + } + + // load impulseDenoise +if (keyFile.has_group ("Impulse Denoising")) { + if (keyFile.has_key ("Impulse Denoising", "Enabled")) { impulseDenoise.enabled = keyFile.get_boolean ("Impulse Denoising", "Enabled"); if (pedited) pedited->impulseDenoise.enabled = true; } + if (keyFile.has_key ("Impulse Denoising", "Threshold")) { impulseDenoise.thresh = keyFile.get_integer ("Impulse Denoising", "Threshold"); if (pedited) pedited->impulseDenoise.thresh = true; } +} + + // load dirpyrDenoise +if (keyFile.has_group ("Directional Pyramid Denoising")) {//TODO: No longer an accurate description for FT denoise + if (keyFile.has_key ("Directional Pyramid Denoising", "Enabled")) { dirpyrDenoise.enabled = keyFile.get_boolean ("Directional Pyramid Denoising", "Enabled"); if (pedited) pedited->dirpyrDenoise.enabled = true; } + if (keyFile.has_key ("Directional Pyramid Denoising", "Enhance")) { dirpyrDenoise.enhance = keyFile.get_boolean ("Directional Pyramid Denoising", "Enhance"); if (pedited) pedited->dirpyrDenoise.enhance = true; } + if (keyFile.has_key ("Directional Pyramid Denoising", "Median")) { dirpyrDenoise.median = keyFile.get_boolean ("Directional Pyramid Denoising", "Median"); if (pedited) pedited->dirpyrDenoise.median = true; } + if (keyFile.has_key ("Directional Pyramid Denoising", "Auto")) { dirpyrDenoise.autochroma = keyFile.get_boolean ("Directional Pyramid Denoising", "Auto"); if (pedited) pedited->dirpyrDenoise.autochroma = true; } + // if (keyFile.has_key ("Directional Pyramid Denoising", "Perform")) { dirpyrDenoise.perform = keyFile.get_boolean ("Directional Pyramid Denoising", "Perform"); if (pedited) pedited->dirpyrDenoise.perform = true; } + if (keyFile.has_key ("Directional Pyramid Denoising", "Luma")) { dirpyrDenoise.luma = keyFile.get_double ("Directional Pyramid Denoising", "Luma"); if (pedited) pedited->dirpyrDenoise.luma = true; } + if (keyFile.has_key ("Directional Pyramid Denoising", "Ldetail")) { dirpyrDenoise.Ldetail = keyFile.get_double ("Directional Pyramid Denoising", "Ldetail"); if (pedited) pedited->dirpyrDenoise.Ldetail = true; } + if (keyFile.has_key ("Directional Pyramid Denoising", "Chroma")) { dirpyrDenoise.chroma = keyFile.get_double ("Directional Pyramid Denoising", "Chroma"); if (pedited) pedited->dirpyrDenoise.chroma = true; } + if (keyFile.has_key ("Directional Pyramid Denoising", "Method")) {dirpyrDenoise.dmethod = keyFile.get_string ("Directional Pyramid Denoising", "Method"); if (pedited) pedited->dirpyrDenoise.dmethod = true; } + if (keyFile.has_key ("Directional Pyramid Denoising", "LMethod")) {dirpyrDenoise.Lmethod = keyFile.get_string ("Directional Pyramid Denoising", "LMethod"); if (pedited) pedited->dirpyrDenoise.Lmethod = true; } + if (keyFile.has_key ("Directional Pyramid Denoising", "CMethod")) {dirpyrDenoise.Cmethod = keyFile.get_string ("Directional Pyramid Denoising", "CMethod"); if (pedited) pedited->dirpyrDenoise.Cmethod = true; } + // never load 'auto chroma preview mode' from pp3 + if(dirpyrDenoise.Cmethod=="PRE") + dirpyrDenoise.Cmethod = "MAN"; + if (keyFile.has_key ("Directional Pyramid Denoising", "C2Method")) {dirpyrDenoise.C2method = keyFile.get_string ("Directional Pyramid Denoising", "C2Method"); if (pedited) pedited->dirpyrDenoise.C2method = true; } + if(dirpyrDenoise.C2method=="PREV") + dirpyrDenoise.C2method = "MANU"; + if (keyFile.has_key ("Directional Pyramid Denoising", "SMethod")) {dirpyrDenoise.smethod = keyFile.get_string ("Directional Pyramid Denoising", "SMethod"); if (pedited) pedited->dirpyrDenoise.smethod = true; } + if (keyFile.has_key ("Directional Pyramid Denoising", "MedMethod")) {dirpyrDenoise.medmethod = keyFile.get_string ("Directional Pyramid Denoising", "MedMethod"); if (pedited) pedited->dirpyrDenoise.medmethod = true; } + if (keyFile.has_key ("Directional Pyramid Denoising", "MethodMed")) {dirpyrDenoise.methodmed = keyFile.get_string ("Directional Pyramid Denoising", "MethodMed"); if (pedited) pedited->dirpyrDenoise.methodmed = true; } + if (keyFile.has_key ("Directional Pyramid Denoising", "RGBMethod")) {dirpyrDenoise.rgbmethod = keyFile.get_string ("Directional Pyramid Denoising", "RGBMethod"); if (pedited) pedited->dirpyrDenoise.rgbmethod = true; } + if (keyFile.has_key ("Directional Pyramid Denoising", "LCurve")) {dirpyrDenoise.lcurve = keyFile.get_double_list ("Directional Pyramid Denoising", "LCurve"); if (pedited) pedited->dirpyrDenoise.lcurve = true; } + if (keyFile.has_key ("Directional Pyramid Denoising", "CCCurve")) {dirpyrDenoise.cccurve = keyFile.get_double_list ("Directional Pyramid Denoising", "CCCurve"); if (pedited) pedited->dirpyrDenoise.cccurve = true; } + + if (keyFile.has_key ("Directional Pyramid Denoising", "Redchro")) { dirpyrDenoise.redchro = keyFile.get_double ("Directional Pyramid Denoising", "Redchro"); if (pedited) pedited->dirpyrDenoise.redchro = true; } + if (keyFile.has_key ("Directional Pyramid Denoising", "Bluechro")) { dirpyrDenoise.bluechro = keyFile.get_double ("Directional Pyramid Denoising", "Bluechro"); if (pedited) pedited->dirpyrDenoise.bluechro = true; } + if (keyFile.has_key ("Directional Pyramid Denoising", "Gamma")) { dirpyrDenoise.gamma = keyFile.get_double ("Directional Pyramid Denoising", "Gamma"); if (pedited) pedited->dirpyrDenoise.gamma = true; } + if (keyFile.has_key ("Directional Pyramid Denoising", "Passes")) { dirpyrDenoise.passes = keyFile.get_integer ("Directional Pyramid Denoising", "Passes"); if (pedited) pedited->dirpyrDenoise.passes = true; } +} + + //Load EPD. +if (keyFile.has_group ("EPD")) { + if(keyFile.has_key("EPD", "Enabled")) { epd.enabled = keyFile.get_boolean ("EPD", "Enabled"); if (pedited) pedited->epd.enabled = true; } + if(keyFile.has_key("EPD", "Strength")) { epd.strength = keyFile.get_double ("EPD", "Strength"); if (pedited) pedited->epd.strength = true; } + if(keyFile.has_key("EPD", "Gamma")) { epd.gamma = keyFile.get_double ("EPD", "Gamma"); if (pedited) pedited->epd.gamma = true; } + if(keyFile.has_key("EPD", "EdgeStopping")) { epd.edgeStopping = keyFile.get_double ("EPD", "EdgeStopping"); if (pedited) pedited->epd.edgeStopping = true; } + if(keyFile.has_key("EPD", "Scale")) { epd.scale = keyFile.get_double ("EPD", "Scale"); if (pedited) pedited->epd.scale = true; } + if(keyFile.has_key("EPD", "ReweightingIterates")) { epd.reweightingIterates = keyFile.get_integer ("EPD", "ReweightingIterates"); if (pedited) pedited->epd.reweightingIterates = 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; } + if (keyFile.has_key ("Luminance Denoising", "Radius")) { lumaDenoise.radius = keyFile.get_double ("Luminance Denoising", "Radius"); if (pedited) pedited->lumaDenoise.radius = true; } + if (keyFile.has_key ("Luminance Denoising", "EdgeTolerance")) { lumaDenoise.edgetolerance = keyFile.get_integer ("Luminance Denoising", "EdgeTolerance"); if (pedited) pedited->lumaDenoise.edgetolerance = true; } +}*/ + + // load colorDenoise +/*if (keyFile.has_group ("Chrominance Denoising")) { + if (keyFile.has_key ("Chrominance Denoising", "Enabled")) { colorDenoise.enabled = keyFile.get_boolean ("Chrominance Denoising", "Enabled"); if (pedited) pedited->colorDenoise.enabled = true; } + // WARNING: radius doesn't exist anymore; is there any compatibility issue that require to keep the following line? + if (keyFile.has_key ("Chrominance Denoising", "Radius")) { colorDenoise.amount = 10*keyFile.get_double ("Chrominance Denoising", "Radius"); } + if (keyFile.has_key ("Chrominance Denoising", "Amount")) { colorDenoise.amount = keyFile.get_integer ("Chrominance Denoising", "Amount"); if (pedited) pedited->colorDenoise.amount = true; } +}*/ + + // load sh +if (keyFile.has_group ("Shadows & Highlights")) { + if (keyFile.has_key ("Shadows & Highlights", "Enabled")) { sh.enabled = keyFile.get_boolean ("Shadows & Highlights", "Enabled"); if (pedited) pedited->sh.enabled = true; } + if (keyFile.has_key ("Shadows & Highlights", "HighQuality")) { sh.hq = keyFile.get_boolean ("Shadows & Highlights", "HighQuality"); if (pedited) pedited->sh.hq = true; } + if (keyFile.has_key ("Shadows & Highlights", "Highlights")) { sh.highlights = keyFile.get_integer ("Shadows & Highlights", "Highlights"); if (pedited) pedited->sh.highlights = true; } + if (keyFile.has_key ("Shadows & Highlights", "HighlightTonalWidth")) { sh.htonalwidth = keyFile.get_integer ("Shadows & Highlights", "HighlightTonalWidth"); if (pedited) pedited->sh.htonalwidth = true; } + if (keyFile.has_key ("Shadows & Highlights", "Shadows")) { sh.shadows = keyFile.get_integer ("Shadows & Highlights", "Shadows"); if (pedited) pedited->sh.shadows = true; } + if (keyFile.has_key ("Shadows & Highlights", "ShadowTonalWidth")) { sh.stonalwidth = keyFile.get_integer ("Shadows & Highlights", "ShadowTonalWidth"); if (pedited) pedited->sh.stonalwidth = true; } + if (keyFile.has_key ("Shadows & Highlights", "LocalContrast")) { sh.localcontrast = keyFile.get_integer ("Shadows & Highlights", "LocalContrast"); if (pedited) pedited->sh.localcontrast = true; } + if (keyFile.has_key ("Shadows & Highlights", "Radius")) { sh.radius = keyFile.get_integer ("Shadows & Highlights", "Radius"); if (pedited) pedited->sh.radius = true; } +} + + // load crop +if (keyFile.has_group ("Crop")) { + if (keyFile.has_key ("Crop", "Enabled")) { crop.enabled = keyFile.get_boolean ("Crop", "Enabled"); if (pedited) pedited->crop.enabled = true; } + if (keyFile.has_key ("Crop", "X")) { crop.x = keyFile.get_integer ("Crop", "X"); if (pedited) pedited->crop.x = true; } + if (keyFile.has_key ("Crop", "Y")) { crop.y = keyFile.get_integer ("Crop", "Y"); if (pedited) pedited->crop.y = true; } + if (keyFile.has_key ("Crop", "W")) { crop.w = keyFile.get_integer ("Crop", "W"); if (pedited) pedited->crop.w = true; } + if (keyFile.has_key ("Crop", "H")) { crop.h = keyFile.get_integer ("Crop", "H"); if (pedited) pedited->crop.h = true; } + if (keyFile.has_key ("Crop", "FixedRatio")) { crop.fixratio = keyFile.get_boolean ("Crop", "FixedRatio"); if (pedited) pedited->crop.fixratio = true; } + if (keyFile.has_key ("Crop", "Ratio")) { + crop.ratio = keyFile.get_string ("Crop", "Ratio"); + if (pedited) pedited->crop.ratio = true; + //backwards compatibility for crop.ratio + if (crop.ratio=="DIN") crop.ratio = "1.414 - DIN EN ISO 216"; + if (crop.ratio=="8.5:11") crop.ratio = "8.5:11 - US Letter"; + if (crop.ratio=="11:17") crop.ratio = "11:17 - Tabloid"; + } + if (keyFile.has_key ("Crop", "Orientation")) { crop.orientation= keyFile.get_string ("Crop", "Orientation"); if (pedited) pedited->crop.orientation = true; } + if (keyFile.has_key ("Crop", "Guide")) { crop.guide = keyFile.get_string ("Crop", "Guide"); if (pedited) pedited->crop.guide = true; } +} + + // load coarse +if (keyFile.has_group ("Coarse Transformation")) { + if (keyFile.has_key ("Coarse Transformation", "Rotate")) { coarse.rotate = keyFile.get_integer ("Coarse Transformation", "Rotate"); if (pedited) pedited->coarse.rotate = true; } + if (keyFile.has_key ("Coarse Transformation", "HorizontalFlip")) { coarse.hflip = keyFile.get_boolean ("Coarse Transformation", "HorizontalFlip"); if (pedited) pedited->coarse.hflip = true; } + if (keyFile.has_key ("Coarse Transformation", "VerticalFlip")) { coarse.vflip = keyFile.get_boolean ("Coarse Transformation", "VerticalFlip"); if (pedited) pedited->coarse.vflip = true; } +} + + // load rotate +if (keyFile.has_group ("Rotation")) { + if (keyFile.has_key ("Rotation", "Degree")) { rotate.degree = keyFile.get_double ("Rotation", "Degree"); if (pedited) pedited->rotate.degree = true; } +} + // load commonTrans +if (keyFile.has_group ("Common Properties for Transformations")) { + if (keyFile.has_key ("Common Properties for Transformations", "AutoFill")) { commonTrans.autofill = keyFile.get_boolean ("Common Properties for Transformations", "AutoFill"); if (pedited) pedited->commonTrans.autofill = true; } +} + + // load distortion +if (keyFile.has_group ("Distortion")) { + if (keyFile.has_key ("Distortion", "Amount")) { distortion.amount = keyFile.get_double ("Distortion", "Amount"); if (pedited) pedited->distortion.amount = true; } +} + + // lens profile +if (keyFile.has_group ("LensProfile")) { + if (keyFile.has_key ("LensProfile", "LCPFile")) { lensProf.lcpFile = expandRelativePath(fname, "", keyFile.get_string ("LensProfile", "LCPFile")); if (pedited) pedited->lensProf.lcpFile = true; } + if (keyFile.has_key ("LensProfile", "UseDistortion")) { lensProf.useDist = keyFile.get_boolean ("LensProfile", "UseDistortion"); if (pedited) pedited->lensProf.useDist = true; } + if (keyFile.has_key ("LensProfile", "UseVignette")) { lensProf.useVign = keyFile.get_boolean ("LensProfile", "UseVignette"); if (pedited) pedited->lensProf.useVign = true; } + if (keyFile.has_key ("LensProfile", "UseCA")) { lensProf.useCA = keyFile.get_boolean ("LensProfile", "UseCA"); if (pedited) pedited->lensProf.useCA = true; } +} + + // load perspective correction +if (keyFile.has_group ("Perspective")) { + if (keyFile.has_key ("Perspective", "Horizontal")) { perspective.horizontal = keyFile.get_double ("Perspective", "Horizontal"); if (pedited) pedited->perspective.horizontal = true; } + if (keyFile.has_key ("Perspective", "Vertical")) { perspective.vertical = keyFile.get_double ("Perspective", "Vertical"); if (pedited) pedited->perspective.vertical = true; } +} + + // load gradient +if (keyFile.has_group ("Gradient")) { + if (keyFile.has_key ("Gradient", "Enabled")) { gradient.enabled = keyFile.get_boolean ("Gradient", "Enabled"); if (pedited) pedited->gradient.enabled = true; } + if (keyFile.has_key ("Gradient", "Degree")) { gradient.degree = keyFile.get_double ("Gradient", "Degree"); if (pedited) pedited->gradient.degree = true; } + if (keyFile.has_key ("Gradient", "Feather")) { gradient.feather = keyFile.get_integer ("Gradient", "Feather"); if (pedited) pedited->gradient.feather = true; } + if (keyFile.has_key ("Gradient", "Strength")) { gradient.strength = keyFile.get_double ("Gradient", "Strength");if (pedited) pedited->gradient.strength = true; } + if (keyFile.has_key ("Gradient", "CenterX")) { gradient.centerX = keyFile.get_integer ("Gradient", "CenterX"); if (pedited) pedited->gradient.centerX = true; } + if (keyFile.has_key ("Gradient", "CenterY")) { gradient.centerY = keyFile.get_integer ("Gradient", "CenterY"); if (pedited) pedited->gradient.centerY = true; } +} + +if (keyFile.has_group ("PCVignette")) { + if (keyFile.has_key ("PCVignette", "Enabled")) { pcvignette.enabled = keyFile.get_boolean ("PCVignette", "Enabled"); if (pedited) pedited->pcvignette.enabled = true; } + if (keyFile.has_key ("PCVignette", "Strength")) { pcvignette.strength = keyFile.get_double ("PCVignette", "Strength");if (pedited) pedited->pcvignette.strength = true; } + if (keyFile.has_key ("PCVignette", "Feather")) { pcvignette.feather = keyFile.get_integer ("PCVignette", "Feather"); if (pedited) pedited->pcvignette.feather = true; } + if (keyFile.has_key ("PCVignette", "Roundness")) { pcvignette.roundness = keyFile.get_integer ("PCVignette", "Roundness"); if (pedited) pedited->pcvignette.roundness = true; } +} + +// load c/a correction +if (keyFile.has_group ("CACorrection")) { + if (keyFile.has_key ("CACorrection", "Red")) { cacorrection.red = keyFile.get_double ("CACorrection", "Red"); if (pedited) pedited->cacorrection.red = true; } + if (keyFile.has_key ("CACorrection", "Blue")) { cacorrection.blue = keyFile.get_double ("CACorrection", "Blue"); if (pedited) pedited->cacorrection.blue = true; } +} + + // load vignetting correction +if (keyFile.has_group ("Vignetting Correction")) { + if (keyFile.has_key ("Vignetting Correction", "Amount")) { vignetting.amount = keyFile.get_integer ("Vignetting Correction", "Amount"); if (pedited) pedited->vignetting.amount = true; } + if (keyFile.has_key ("Vignetting Correction", "Radius")) { vignetting.radius = keyFile.get_integer ("Vignetting Correction", "Radius"); if (pedited) pedited->vignetting.radius = true; } + if (keyFile.has_key ("Vignetting Correction", "Strength")) { vignetting.strength = keyFile.get_integer ("Vignetting Correction", "Strength"); if (pedited) pedited->vignetting.strength = true; } + if (keyFile.has_key ("Vignetting Correction", "CenterX")) { vignetting.centerX = keyFile.get_integer ("Vignetting Correction", "CenterX"); if (pedited) pedited->vignetting.centerX = true; } + if (keyFile.has_key ("Vignetting Correction", "CenterY")) { vignetting.centerY = keyFile.get_integer ("Vignetting Correction", "CenterY"); if (pedited) pedited->vignetting.centerY = true; } +} + + // load resize settings +if (keyFile.has_group ("Resize")) { + if (keyFile.has_key ("Resize", "Enabled")) { resize.enabled = keyFile.get_boolean ("Resize", "Enabled"); if (pedited) pedited->resize.enabled = true; } + if (keyFile.has_key ("Resize", "Scale")) { resize.scale = keyFile.get_double ("Resize", "Scale"); if (pedited) pedited->resize.scale = true; } + if (keyFile.has_key ("Resize", "AppliesTo")) { resize.appliesTo = keyFile.get_string ("Resize", "AppliesTo"); if (pedited) pedited->resize.appliesTo = true; } + if (keyFile.has_key ("Resize", "Method")) { resize.method = keyFile.get_string ("Resize", "Method"); if (pedited) pedited->resize.method = true; } + if (keyFile.has_key ("Resize", "DataSpecified")) { resize.dataspec = keyFile.get_integer ("Resize", "DataSpecified"); if (pedited) pedited->resize.dataspec = true; } + if (keyFile.has_key ("Resize", "Width")) { resize.width = keyFile.get_integer ("Resize", "Width"); if (pedited) pedited->resize.width = true; } + if (keyFile.has_key ("Resize", "Height")) { resize.height = keyFile.get_integer ("Resize", "Height"); if (pedited) pedited->resize.height = true; } +} + + // load post resize sharpening +if (keyFile.has_group ("PostResizeSharpening")) { + if (keyFile.has_key ("PostResizeSharpening", "Enabled")) { prsharpening.enabled = keyFile.get_boolean ("PostResizeSharpening", "Enabled"); if (pedited) pedited->prsharpening.enabled = true; } + if (keyFile.has_key ("PostResizeSharpening", "Radius")) { prsharpening.radius = keyFile.get_double ("PostResizeSharpening", "Radius"); if (pedited) pedited->prsharpening.radius = true; } + if (keyFile.has_key ("PostResizeSharpening", "Amount")) { prsharpening.amount = keyFile.get_integer ("PostResizeSharpening", "Amount"); if (pedited) pedited->prsharpening.amount = true; } + if (keyFile.has_key ("PostResizeSharpening", "Threshold")) { + if (ppVersion < 302) { + int thresh = min(keyFile.get_integer ("PostResizeSharpening", "Threshold"), 2000); + prsharpening.threshold.setValues(thresh, thresh, 2000, 2000); // TODO: 2000 is the maximum value and is taken of rtgui/sharpening.cc ; should be changed by the tool modularization + } + else { + Glib::ArrayHandle thresh = keyFile.get_integer_list ("PostResizeSharpening", "Threshold"); + prsharpening.threshold.setValues(thresh.data()[0], thresh.data()[1], min(thresh.data()[2], 2000), min(thresh.data()[3], 2000)); + } + if (pedited) pedited->prsharpening.threshold = true; + } + if (keyFile.has_key ("PostResizeSharpening", "OnlyEdges")) { prsharpening.edgesonly = keyFile.get_boolean ("PostResizeSharpening", "OnlyEdges"); if (pedited) pedited->prsharpening.edgesonly = true; } + if (keyFile.has_key ("PostResizeSharpening", "EdgedetectionRadius")) { prsharpening.edges_radius = keyFile.get_double ("PostResizeSharpening", "EdgedetectionRadius"); if (pedited) pedited->prsharpening.edges_radius = true; } + if (keyFile.has_key ("PostResizeSharpening", "EdgeTolerance")) { prsharpening.edges_tolerance = keyFile.get_integer ("PostResizeSharpening", "EdgeTolerance"); if (pedited) pedited->prsharpening.edges_tolerance = true; } + if (keyFile.has_key ("PostResizeSharpening", "HalocontrolEnabled")) { prsharpening.halocontrol = keyFile.get_boolean ("PostResizeSharpening", "HalocontrolEnabled"); if (pedited) pedited->prsharpening.halocontrol = true; } + if (keyFile.has_key ("PostResizeSharpening", "HalocontrolAmount")) { prsharpening.halocontrol_amount = keyFile.get_integer ("PostResizeSharpening", "HalocontrolAmount"); if (pedited) pedited->prsharpening.halocontrol_amount = true; } + if (keyFile.has_key ("PostResizeSharpening", "Method")) { prsharpening.method = keyFile.get_string ("PostResizeSharpening", "Method"); if (pedited) pedited->prsharpening.method = true; } + if (keyFile.has_key ("PostResizeSharpening", "DeconvRadius")) { prsharpening.deconvradius = keyFile.get_double ("PostResizeSharpening", "DeconvRadius"); if (pedited) pedited->prsharpening.deconvradius = true; } + if (keyFile.has_key ("PostResizeSharpening", "DeconvAmount")) { prsharpening.deconvamount = keyFile.get_integer ("PostResizeSharpening", "DeconvAmount"); if (pedited) pedited->prsharpening.deconvamount = true; } + if (keyFile.has_key ("PostResizeSharpening", "DeconvDamping")) { prsharpening.deconvdamping = keyFile.get_integer ("PostResizeSharpening", "DeconvDamping"); if (pedited) pedited->prsharpening.deconvdamping = true; } + if (keyFile.has_key ("PostResizeSharpening", "DeconvIterations")) { prsharpening.deconviter = keyFile.get_integer ("PostResizeSharpening", "DeconvIterations"); if (pedited) pedited->prsharpening.deconviter = true; } +} + + // load color management settings +if (keyFile.has_group ("Color Management")) { + if (keyFile.has_key ("Color Management", "InputProfile")) { icm.input = expandRelativePath(fname, "file:", keyFile.get_string ("Color Management", "InputProfile")); if (pedited) pedited->icm.input = true; } + if (keyFile.has_key ("Color Management", "ToneCurve")) { icm.toneCurve = keyFile.get_boolean ("Color Management", "ToneCurve"); if (pedited) pedited->icm.toneCurve = true; } + if (keyFile.has_key ("Color Management", "ApplyLookTable")) { icm.applyLookTable = keyFile.get_boolean ("Color Management", "ApplyLookTable"); if (pedited) pedited->icm.applyLookTable = true; } + if (keyFile.has_key ("Color Management", "ApplyBaselineExposureOffset")) { icm.applyBaselineExposureOffset = keyFile.get_boolean ("Color Management", "ApplyBaselineExposureOffset"); if (pedited) pedited->icm.applyBaselineExposureOffset = true; } + if (keyFile.has_key ("Color Management", "ApplyHueSatMap")) { icm.applyHueSatMap = keyFile.get_boolean ("Color Management", "ApplyHueSatMap"); if (pedited) pedited->icm.applyHueSatMap = true; } + if (keyFile.has_key ("Color Management", "BlendCMSMatrix")) { icm.blendCMSMatrix = keyFile.get_boolean ("Color Management", "BlendCMSMatrix"); if (pedited) pedited->icm.blendCMSMatrix = true; } + if (keyFile.has_key ("Color Management", "DCPIlluminant")) { icm.dcpIlluminant = keyFile.get_integer ("Color Management", "DCPIlluminant"); if (pedited) pedited->icm.dcpIlluminant = true; } + if (keyFile.has_key ("Color Management", "WorkingProfile")) { icm.working = keyFile.get_string ("Color Management", "WorkingProfile"); if (pedited) pedited->icm.working = true; } + if (keyFile.has_key ("Color Management", "OutputProfile")) { icm.output = keyFile.get_string ("Color Management", "OutputProfile"); if (pedited) pedited->icm.output = true; } + if (keyFile.has_key ("Color Management", "Gammafree")) { icm.gamma = keyFile.get_string ("Color Management", "Gammafree"); if (pedited) pedited->icm.gamfree = true; } + if (keyFile.has_key ("Color Management", "Freegamma")) { icm.freegamma = keyFile.get_boolean ("Color Management", "Freegamma"); if (pedited) pedited->icm.freegamma = true; } + if (keyFile.has_key ("Color Management", "GammaValue")) { icm.gampos = keyFile.get_double ("Color Management", "GammaValue"); if (pedited) pedited->icm.gampos = true; } + if (keyFile.has_key ("Color Management", "GammaSlope")) { icm.slpos = keyFile.get_double ("Color Management", "GammaSlope"); if (pedited) pedited->icm.slpos = true; } + +} + // load wavelet wavelet parameters +if (keyFile.has_group ("Wavelet")) { + if (keyFile.has_key ("Wavelet", "Enabled")) { wavelet.enabled = keyFile.get_boolean ("Wavelet", "Enabled"); if (pedited) pedited->wavelet.enabled = true; } + if (keyFile.has_key ("Wavelet", "Strength")) { wavelet.strength = keyFile.get_integer ("Wavelet", "Strength"); if (pedited) pedited->wavelet.strength = true; } + if (keyFile.has_key ("Wavelet", "Balance")) { wavelet.balance = keyFile.get_integer ("Wavelet", "Balance"); if (pedited) pedited->wavelet.balance = true; } + if (keyFile.has_key ("Wavelet", "Iter")) { wavelet.iter = keyFile.get_integer ("Wavelet", "Iter"); if (pedited) pedited->wavelet.iter = true; } + if (keyFile.has_key ("Wavelet", "Median")) {wavelet.median = keyFile.get_boolean ("Wavelet", "Median");if (pedited) pedited->wavelet.median = true;} + if (keyFile.has_key ("Wavelet", "Medianlev")) {wavelet.medianlev = keyFile.get_boolean ("Wavelet", "Medianlev");if (pedited) pedited->wavelet.medianlev = true;} + if (keyFile.has_key ("Wavelet", "Linkedg")) {wavelet.linkedg = keyFile.get_boolean ("Wavelet", "Linkedg");if (pedited) pedited->wavelet.linkedg = true;} + if (keyFile.has_key ("Wavelet", "CBenab")) {wavelet.cbenab = keyFile.get_boolean ("Wavelet", "CBenab");if (pedited) pedited->wavelet.cbenab = true;} + if (keyFile.has_key ("Wavelet", "CBgreenhigh")) { wavelet.greenhigh = keyFile.get_integer ("Wavelet", "CBgreenhigh"); if (pedited) pedited->wavelet.greenhigh = true; } + if (keyFile.has_key ("Wavelet", "CBgreenmed")) { wavelet.greenmed = keyFile.get_integer ("Wavelet", "CBgreenmed"); if (pedited) pedited->wavelet.greenmed = true; } + if (keyFile.has_key ("Wavelet", "CBgreenlow")) { wavelet.greenlow = keyFile.get_integer ("Wavelet", "CBgreenlow"); if (pedited) pedited->wavelet.greenlow = true; } + if (keyFile.has_key ("Wavelet", "CBbluehigh")) { wavelet.bluehigh = keyFile.get_integer ("Wavelet", "CBbluehigh"); if (pedited) pedited->wavelet.bluehigh = true; } + if (keyFile.has_key ("Wavelet", "CBbluemed")) { wavelet.bluemed = keyFile.get_integer ("Wavelet", "CBbluemed"); if (pedited) pedited->wavelet.bluemed = true; } + if (keyFile.has_key ("Wavelet", "CBbluelow")) { wavelet.bluelow = keyFile.get_integer ("Wavelet", "CBbluelow"); if (pedited) pedited->wavelet.bluelow = true; } + // if (keyFile.has_key ("Wavelet", "Edgreinf")) {wavelet.edgreinf = keyFile.get_boolean ("Wavelet", "Edgreinf");if (pedited) pedited->wavelet.edgreinf = true;} + if (keyFile.has_key ("Wavelet", "Lipst")) {wavelet.lipst = keyFile.get_boolean ("Wavelet", "Lipst");if (pedited) pedited->wavelet.lipst = true;} + if (keyFile.has_key ("Wavelet", "AvoidColorShift")) {wavelet.avoid = keyFile.get_boolean ("Wavelet", "AvoidColorShift");if (pedited) pedited->wavelet.avoid = true;} + if (keyFile.has_key ("Wavelet", "TMr")) {wavelet.tmr = keyFile.get_boolean ("Wavelet", "TMr");if (pedited) pedited->wavelet.tmr = true;} + if (keyFile.has_key ("Wavelet", "LevMethod")) {wavelet.Lmethod = keyFile.get_string ("Wavelet", "LevMethod"); if (pedited) pedited->wavelet.Lmethod = true; } + if (keyFile.has_key ("Wavelet", "ChoiceLevMethod")) {wavelet.CLmethod = keyFile.get_string ("Wavelet", "ChoiceLevMethod"); if (pedited) pedited->wavelet.CLmethod = true; } + if (keyFile.has_key ("Wavelet", "BackMethod")) {wavelet.Backmethod = keyFile.get_string ("Wavelet", "BackMethod"); if (pedited) pedited->wavelet.Backmethod = true; } + if (keyFile.has_key ("Wavelet", "TilesMethod")) {wavelet.Tilesmethod = keyFile.get_string ("Wavelet", "TilesMethod"); if (pedited) pedited->wavelet.Tilesmethod = true; } + if (keyFile.has_key ("Wavelet", "DaubMethod")) {wavelet.daubcoeffmethod = keyFile.get_string ("Wavelet", "DaubMethod"); if (pedited) pedited->wavelet.daubcoeffmethod = true; } + if (keyFile.has_key ("Wavelet", "CHromaMethod")) {wavelet.CHmethod = keyFile.get_string ("Wavelet", "CHromaMethod"); if (pedited) pedited->wavelet.CHmethod = true; } + if (keyFile.has_key ("Wavelet", "Medgreinf")) {wavelet.Medgreinf = keyFile.get_string ("Wavelet", "Medgreinf"); if (pedited) pedited->wavelet.Medgreinf = true; } + if (keyFile.has_key ("Wavelet", "CHSLromaMethod")) {wavelet.CHSLmethod = keyFile.get_string ("Wavelet", "CHSLromaMethod"); if (pedited) pedited->wavelet.CHSLmethod = true; } + if (keyFile.has_key ("Wavelet", "EDMethod")) {wavelet.EDmethod = keyFile.get_string ("Wavelet", "EDMethod"); if (pedited) pedited->wavelet.EDmethod = true; } + if (keyFile.has_key ("Wavelet", "BAMethod")) {wavelet.BAmethod = keyFile.get_string ("Wavelet", "BAMethod"); if (pedited) pedited->wavelet.BAmethod = true; } + if (keyFile.has_key ("Wavelet", "TMMethod")) {wavelet.TMmethod = keyFile.get_string ("Wavelet", "TMMethod"); if (pedited) pedited->wavelet.TMmethod = true; } + if (keyFile.has_key ("Wavelet", "HSMethod")) {wavelet.HSmethod = keyFile.get_string ("Wavelet", "HSMethod"); if (pedited) pedited->wavelet.HSmethod = true; } + if (keyFile.has_key ("Wavelet", "DirMethod")) {wavelet.Dirmethod = keyFile.get_string ("Wavelet", "DirMethod"); if (pedited) pedited->wavelet.Dirmethod = true; } + if (keyFile.has_key ("Wavelet", "ResidualcontShadow")) {wavelet.rescon = keyFile.get_integer ("Wavelet", "ResidualcontShadow"); if (pedited) pedited->wavelet.rescon = true; } + if (keyFile.has_key ("Wavelet", "ResidualcontHighlight")) {wavelet.resconH = keyFile.get_integer ("Wavelet", "ResidualcontHighlight"); if (pedited) pedited->wavelet.resconH = true; } + if (keyFile.has_key ("Wavelet", "Residualchroma")) {wavelet.reschro = keyFile.get_integer ("Wavelet", "Residualchroma"); if (pedited) pedited->wavelet.reschro = true; } + if (keyFile.has_key ("Wavelet", "ResidualTM")) {wavelet.tmrs = keyFile.get_double ("Wavelet", "ResidualTM"); if (pedited) pedited->wavelet.tmrs = true; } + if (keyFile.has_key ("Wavelet", "Residualgamma")) {wavelet.gamma = keyFile.get_double ("Wavelet", "Residualgamma"); if (pedited) pedited->wavelet.gamma = true; } + if (keyFile.has_key ("Wavelet", "ContExtra")) {wavelet.sup = keyFile.get_integer ("Wavelet", "ContExtra"); if (pedited) pedited->wavelet.sup = true; } + if (keyFile.has_key ("Wavelet", "HueRangeResidual")) {wavelet.sky = keyFile.get_double ("Wavelet", "HueRangeResidual"); if (pedited) pedited->wavelet.sky = true; } + if (keyFile.has_key ("Wavelet", "MaxLev")) {wavelet.thres = keyFile.get_integer ("Wavelet", "MaxLev"); if (pedited) pedited->wavelet.thres = true; } + if (keyFile.has_key ("Wavelet", "ThresholdHighLight")) {wavelet.threshold = keyFile.get_integer ("Wavelet", "ThresholdHighLight"); if (pedited) pedited->wavelet.threshold = true; } + if (keyFile.has_key ("Wavelet", "ThresholdShadow")) {wavelet.threshold2 = keyFile.get_integer ("Wavelet", "ThresholdShadow"); if (pedited) pedited->wavelet.threshold2 = true; } + if (keyFile.has_key ("Wavelet", "Edgedetect")) {wavelet.edgedetect = keyFile.get_integer ("Wavelet", "Edgedetect"); if (pedited) pedited->wavelet.edgedetect = true; } + if (keyFile.has_key ("Wavelet", "Edgedetectthr")) {wavelet.edgedetectthr = keyFile.get_integer ("Wavelet", "Edgedetectthr"); if (pedited) pedited->wavelet.edgedetectthr = true; } + if (keyFile.has_key ("Wavelet", "EdgedetectthrHi")) {wavelet.edgedetectthr2 = keyFile.get_integer ("Wavelet", "EdgedetectthrHi"); if (pedited) pedited->wavelet.edgedetectthr2 = true; } + if (keyFile.has_key ("Wavelet", "ThresholdChroma")) {wavelet.chroma = keyFile.get_integer ("Wavelet", "ThresholdChroma"); if (pedited) pedited->wavelet.chroma = true; } + if (keyFile.has_key ("Wavelet", "ChromaLink")) {wavelet.chro = keyFile.get_integer ("Wavelet", "ChromaLink"); if (pedited) pedited->wavelet.chro = true; } + if (keyFile.has_key ("Wavelet", "Contrast")) {wavelet.contrast = keyFile.get_integer ("Wavelet", "Contrast"); if (pedited) pedited->wavelet.contrast = true; } + if (keyFile.has_key ("Wavelet", "Edgrad")) {wavelet.edgrad = keyFile.get_integer ("Wavelet", "Edgrad"); if (pedited) pedited->wavelet.edgrad = true; } + if (keyFile.has_key ("Wavelet", "Edgval")) {wavelet.edgval = keyFile.get_integer ("Wavelet", "Edgval"); if (pedited) pedited->wavelet.edgval = true; } + if (keyFile.has_key ("Wavelet", "ThrEdg")) {wavelet.edgthresh = keyFile.get_integer ("Wavelet", "ThrEdg"); if (pedited) pedited->wavelet.edgthresh = true; } + if (keyFile.has_key ("Wavelet", "ThresholdResidShadow")) {wavelet.thr = keyFile.get_integer ("Wavelet", "ThresholdResidShadow"); if (pedited) pedited->wavelet.thr = true; } + if (keyFile.has_key ("Wavelet", "ThresholdResidHighLight")) {wavelet.thrH = keyFile.get_integer ("Wavelet", "ThresholdResidHighLight"); if (pedited) pedited->wavelet.thrH = true; } + if (keyFile.has_key ("Wavelet", "ContrastCurve")) {wavelet.ccwcurve = keyFile.get_double_list ("Wavelet", "ContrastCurve"); if (pedited) pedited->wavelet.ccwcurve = true; } + if (keyFile.has_key ("Wavelet", "OpacityCurveRG")) { wavelet.opacityCurveRG = keyFile.get_double_list ("Wavelet", "OpacityCurveRG"); if (pedited) pedited->wavelet.opacityCurveRG = true; } + if (keyFile.has_key ("Wavelet", "OpacityCurveBY")) { wavelet.opacityCurveBY = keyFile.get_double_list ("Wavelet", "OpacityCurveBY"); if (pedited) pedited->wavelet.opacityCurveBY = true; } + if (keyFile.has_key ("Wavelet", "OpacityCurveW")) { wavelet.opacityCurveW = keyFile.get_double_list ("Wavelet", "OpacityCurveW"); if (pedited) pedited->wavelet.opacityCurveW = true; } + if (keyFile.has_key ("Wavelet", "OpacityCurveWL")) { wavelet.opacityCurveWL = keyFile.get_double_list ("Wavelet", "OpacityCurveWL"); if (pedited) pedited->wavelet.opacityCurveWL = true; } + if (keyFile.has_key ("Wavelet", "HHcurve")) { wavelet.hhcurve = keyFile.get_double_list ("Wavelet", "HHcurve"); if (pedited) pedited->wavelet.hhcurve = true; } + if (keyFile.has_key ("Wavelet", "CHcurve")) { wavelet.Chcurve = keyFile.get_double_list ("Wavelet", "CHcurve"); if (pedited) pedited->wavelet.Chcurve = true; } + if (keyFile.has_key ("Wavelet", "WavclCurve")) { wavelet.wavclCurve = keyFile.get_double_list ("Wavelet", "WavclCurve"); if (pedited) pedited->wavelet.wavclCurve = true; } + if (keyFile.has_key ("Wavelet", "Hueskin")) { + Glib::ArrayHandle thresh = keyFile.get_integer_list ("Wavelet", "Hueskin"); + wavelet.hueskin.setValues(thresh.data()[0], thresh.data()[1], min(thresh.data()[2], 300), min(thresh.data()[3], 300)); + if (pedited) pedited->wavelet.hueskin = true; + } + if (keyFile.has_key ("Wavelet", "HueRange")) { + Glib::ArrayHandle thresh = keyFile.get_integer_list ("Wavelet", "HueRange"); + wavelet.hueskin2.setValues(thresh.data()[0], thresh.data()[1], min(thresh.data()[2], 300), min(thresh.data()[3], 300)); + if (pedited) pedited->wavelet.hueskin2 = true; + } + + if (keyFile.has_key ("Wavelet", "HLRange")) { + Glib::ArrayHandle thresh = keyFile.get_integer_list ("Wavelet", "HLRange"); + wavelet.hllev.setValues(thresh.data()[0], thresh.data()[1], min(thresh.data()[2], 300), min(thresh.data()[3], 300)); + if (pedited) pedited->wavelet.hllev = true; + } + if (keyFile.has_key ("Wavelet", "SHRange")) { + Glib::ArrayHandle thresh = keyFile.get_integer_list ("Wavelet", "SHRange"); + wavelet.bllev.setValues(thresh.data()[0], thresh.data()[1], min(thresh.data()[2], 300), min(thresh.data()[3], 300)); + if (pedited) pedited->wavelet.bllev = true; + } + if (keyFile.has_key ("Wavelet", "Edgcont")) { + Glib::ArrayHandle thresh = keyFile.get_integer_list ("Wavelet", "Edgcont"); + wavelet.edgcont.setValues(thresh.data()[0], thresh.data()[1], min(thresh.data()[2], 300), min(thresh.data()[3], 300)); + if (pedited) pedited->wavelet.edgcont = true; + } + if (keyFile.has_key ("Wavelet", "Level0noise")) { + Glib::ArrayHandle thresh = keyFile.get_double_list ("Wavelet", "Level0noise"); + wavelet.level0noise.setValues(thresh.data()[0], thresh.data()[1]); + if (pedited) pedited->wavelet.level0noise = true; + } + if (keyFile.has_key ("Wavelet", "Level1noise")) { + Glib::ArrayHandle thresh = keyFile.get_double_list ("Wavelet", "Level1noise"); + wavelet.level1noise.setValues(thresh.data()[0], thresh.data()[1]); + if (pedited) pedited->wavelet.level1noise = true; + } + if (keyFile.has_key ("Wavelet", "Level2noise")) { + Glib::ArrayHandle thresh = keyFile.get_double_list ("Wavelet", "Level2noise"); + wavelet.level2noise.setValues(thresh.data()[0], thresh.data()[1]); + if (pedited) pedited->wavelet.level2noise = true; + } + + if (keyFile.has_key ("Wavelet", "Pastlev")) { + Glib::ArrayHandle thresh = keyFile.get_integer_list ("Wavelet", "Pastlev"); + wavelet.pastlev.setValues(thresh.data()[0], thresh.data()[1], min(thresh.data()[2], 300), min(thresh.data()[3], 300)); + if (pedited) pedited->wavelet.pastlev = true; + } + if (keyFile.has_key ("Wavelet", "Satlev")) { + Glib::ArrayHandle thresh = keyFile.get_integer_list ("Wavelet", "Satlev"); + wavelet.satlev.setValues(thresh.data()[0], thresh.data()[1], min(thresh.data()[2], 300), min(thresh.data()[3], 300)); + if (pedited) pedited->wavelet.satlev = true; + } + + + if(keyFile.has_key ("Wavelet", "Skinprotect")) { wavelet.skinprotect = keyFile.get_double ("Wavelet", "Skinprotect"); if (pedited) pedited->wavelet.skinprotect = true; } + for(int i = 0; i < 9; i ++) + { + std::stringstream ss; + ss << "Contrast" << (i+1); + if(keyFile.has_key ("Wavelet", ss.str())) {wavelet.c[i] = keyFile.get_integer ("Wavelet", ss.str()); if (pedited) pedited->wavelet.c[i] = true;} + } + for(int i = 0; i < 9; i ++) + { + std::stringstream ss; + ss << "Chroma" << (i+1); + if(keyFile.has_key ("Wavelet", ss.str())) {wavelet.ch[i] = keyFile.get_integer ("Wavelet", ss.str()); if (pedited) pedited->wavelet.ch[i] = true;} + } + +} + + // load directional pyramid equalizer parameters +if (keyFile.has_group ("Directional Pyramid Equalizer")) { + if (keyFile.has_key ("Directional Pyramid Equalizer", "Enabled")) { dirpyrequalizer.enabled = keyFile.get_boolean ("Directional Pyramid Equalizer", "Enabled"); if (pedited) pedited->dirpyrequalizer.enabled = true; } + if (keyFile.has_key ("Directional Pyramid Equalizer", "Gamutlab")) { dirpyrequalizer.gamutlab = keyFile.get_boolean ("Directional Pyramid Equalizer", "Gamutlab"); if (pedited) pedited->dirpyrequalizer.gamutlab = true; } + // if (keyFile.has_key ("Directional Pyramid Equalizer", "Algorithm")) { dirpyrequalizer.algo = keyFile.get_string ("Directional Pyramid Equalizer", "Algorithm"); if (pedited) pedited->dirpyrequalizer.algo = true; } + if (keyFile.has_key ("Directional Pyramid Equalizer", "Hueskin")) { + Glib::ArrayHandle thresh = keyFile.get_integer_list ("Directional Pyramid Equalizer", "Hueskin"); + dirpyrequalizer.hueskin.setValues(thresh.data()[0], thresh.data()[1], min(thresh.data()[2], 300), min(thresh.data()[3], 300)); + if (pedited) pedited->dirpyrequalizer.hueskin = true; + } + + if (ppVersion < 316) { + for(int i = 0; i < 5; i ++) { + std::stringstream ss; + ss << "Mult" << i; + if(keyFile.has_key ("Directional Pyramid Equalizer", ss.str())) { + if(i==4) { dirpyrequalizer.threshold = keyFile.get_double ("Directional Pyramid Equalizer", ss.str()); if (pedited) pedited->dirpyrequalizer.threshold = true; } + else { dirpyrequalizer.mult[i] = keyFile.get_double ("Directional Pyramid Equalizer", ss.str()); if (pedited) pedited->dirpyrequalizer.mult[i] = true; } + } + } + dirpyrequalizer.mult[4] = 1.0; + } + else { + // 5 level wavelet + dedicated threshold parameter + for(int i = 0; i < 6; i ++) { + std::stringstream ss; + ss << "Mult" << i; + if(keyFile.has_key ("Directional Pyramid Equalizer", ss.str())) { dirpyrequalizer.mult[i] = keyFile.get_double ("Directional Pyramid Equalizer", ss.str()); if (pedited) pedited->dirpyrequalizer.mult[i] = true; } + } + if(keyFile.has_key ("Directional Pyramid Equalizer", "Threshold")) { dirpyrequalizer.threshold = keyFile.get_double ("Directional Pyramid Equalizer", "Threshold"); if (pedited) pedited->dirpyrequalizer.threshold = true; } + if(keyFile.has_key ("Directional Pyramid Equalizer", "Skinprotect")) { dirpyrequalizer.skinprotect = keyFile.get_double ("Directional Pyramid Equalizer", "Skinprotect"); if (pedited) pedited->dirpyrequalizer.skinprotect = true; } + } +} + + // load CLUT parameters +if ( keyFile.has_group( "Film Simulation" ) ) +{ + if ( keyFile.has_key( "Film Simulation", "Enabled" ) ) { filmSimulation.enabled = keyFile.get_boolean( "Film Simulation", "Enabled" ); if ( pedited ) pedited->filmSimulation.enabled = true; } + if ( keyFile.has_key( "Film Simulation", "ClutFilename" ) ) { filmSimulation.clutFilename = keyFile.get_string( "Film Simulation", "ClutFilename" ); if ( pedited ) pedited->filmSimulation.clutFilename = true; } + if ( keyFile.has_key( "Film Simulation", "Strength" ) ) { + if (ppVersion < 321) + filmSimulation.strength = int(keyFile.get_double( "Film Simulation", "Strength" )*100 + 0.1); + else + filmSimulation.strength = keyFile.get_integer( "Film Simulation", "Strength" ); + if ( pedited ) pedited->filmSimulation.strength = true; + } +} + + // load HSV wavelet parameters +if (keyFile.has_group ("HSV Equalizer")) { + if (ppVersion>=300) { + if (keyFile.has_key ("HSV Equalizer", "HCurve")) { hsvequalizer.hcurve = keyFile.get_double_list ("HSV Equalizer", "HCurve"); if (pedited) pedited->hsvequalizer.hcurve = true; } + if (keyFile.has_key ("HSV Equalizer", "SCurve")) { hsvequalizer.scurve = keyFile.get_double_list ("HSV Equalizer", "SCurve"); if (pedited) pedited->hsvequalizer.scurve = true; } + if (keyFile.has_key ("HSV Equalizer", "VCurve")) { hsvequalizer.vcurve = keyFile.get_double_list ("HSV Equalizer", "VCurve"); if (pedited) pedited->hsvequalizer.vcurve = true; } + } +} + + // load RGB curves +if (keyFile.has_group ("RGB Curves")) { + if (keyFile.has_key ("RGB Curves", "LumaMode")) { rgbCurves.lumamode = keyFile.get_boolean ("RGB Curves", "LumaMode"); if (pedited) pedited->rgbCurves.lumamode = true; } + if (keyFile.has_key ("RGB Curves", "rCurve")) { rgbCurves.rcurve = keyFile.get_double_list ("RGB Curves", "rCurve"); if (pedited) pedited->rgbCurves.rcurve = true; } + if (keyFile.has_key ("RGB Curves", "gCurve")) { rgbCurves.gcurve = keyFile.get_double_list ("RGB Curves", "gCurve"); if (pedited) pedited->rgbCurves.gcurve = true; } + if (keyFile.has_key ("RGB Curves", "bCurve")) { rgbCurves.bcurve = keyFile.get_double_list ("RGB Curves", "bCurve"); if (pedited) pedited->rgbCurves.bcurve = true; } +} + + // load Color Toning +if (keyFile.has_group ("ColorToning")) { + if (keyFile.has_key ("ColorToning", "Enabled")) { colorToning.enabled = keyFile.get_boolean ("ColorToning", "Enabled"); if (pedited) pedited->colorToning.enabled = true; } + if (keyFile.has_key ("ColorToning", "Method")) { colorToning.method = keyFile.get_string ("ColorToning", "Method"); if (pedited) pedited->colorToning.method = true; } + if (keyFile.has_key ("ColorToning", "Lumamode")) { colorToning.lumamode = keyFile.get_boolean ("ColorToning", "Lumamode"); if (pedited) pedited->colorToning.lumamode = true; } + if (keyFile.has_key ("ColorToning", "Twocolor")) { colorToning.twocolor = keyFile.get_string ("ColorToning", "Twocolor"); if (pedited) pedited->colorToning.twocolor = true; } + if (keyFile.has_key ("ColorToning", "OpacityCurve")) { colorToning.opacityCurve = keyFile.get_double_list ("ColorToning", "OpacityCurve"); if (pedited) pedited->colorToning.opacityCurve = true; } + if (keyFile.has_key ("ColorToning", "ColorCurve")) { colorToning.colorCurve = keyFile.get_double_list ("ColorToning", "ColorCurve"); if (pedited) pedited->colorToning.colorCurve = true; } + if (keyFile.has_key ("ColorToning", "Autosat")) { colorToning.autosat = keyFile.get_boolean ("ColorToning", "Autosat"); if (pedited) pedited->colorToning.autosat = true; } + if (keyFile.has_key ("ColorToning", "SatProtectionThreshold")) { colorToning.satProtectionThreshold = keyFile.get_integer ("ColorToning", "SatProtectionThreshold"); if (pedited) pedited->colorToning.satprotectionthreshold = true; } + if (keyFile.has_key ("ColorToning", "SaturatedOpacity")) { colorToning.saturatedOpacity = keyFile.get_integer ("ColorToning", "SaturatedOpacity"); if (pedited) pedited->colorToning.saturatedopacity = true; } + if (keyFile.has_key ("ColorToning", "Strength")) { colorToning.strength = keyFile.get_integer ("ColorToning", "Strength"); if (pedited) pedited->colorToning.strength = true; } + if (keyFile.has_key ("ColorToning", "HighlightsColorSaturation")) { + Glib::ArrayHandle thresh = keyFile.get_integer_list ("ColorToning", "HighlightsColorSaturation"); + colorToning.hlColSat.setValues(thresh.data()[0], thresh.data()[1]); + if (pedited) pedited->colorToning.hlColSat = true; + } + if (keyFile.has_key ("ColorToning", "ShadowsColorSaturation")) { + Glib::ArrayHandle thresh = keyFile.get_integer_list ("ColorToning", "ShadowsColorSaturation"); + colorToning.shadowsColSat.setValues(thresh.data()[0], thresh.data()[1]); + if (pedited) pedited->colorToning.shadowsColSat = true; + } + if (keyFile.has_key ("ColorToning", "ClCurve")) { colorToning.clcurve = keyFile.get_double_list ("ColorToning", "ClCurve"); if (pedited) pedited->colorToning.clcurve = true; } + if (keyFile.has_key ("ColorToning", "Cl2Curve")) { colorToning.cl2curve = keyFile.get_double_list ("ColorToning", "Cl2Curve"); if (pedited) pedited->colorToning.cl2curve = true; } + if (keyFile.has_key ("ColorToning", "Redlow")) { colorToning.redlow = keyFile.get_double ("ColorToning", "Redlow"); if (pedited) pedited->colorToning.redlow = true; } + if (keyFile.has_key ("ColorToning", "Greenlow")) { colorToning.greenlow = keyFile.get_double ("ColorToning", "Greenlow"); if (pedited) pedited->colorToning.greenlow = true; } + if (keyFile.has_key ("ColorToning", "Bluelow")) { colorToning.bluelow = keyFile.get_double ("ColorToning", "Bluelow"); if (pedited) pedited->colorToning.bluelow = true; } + if (keyFile.has_key ("ColorToning", "Satlow")) { colorToning.satlow = keyFile.get_double ("ColorToning", "Satlow"); if (pedited) pedited->colorToning.satlow = true; } + if (keyFile.has_key ("ColorToning", "Balance")) { colorToning.balance = keyFile.get_integer ("ColorToning", "Balance"); if (pedited) pedited->colorToning.balance = true; } + if (keyFile.has_key ("ColorToning", "Sathigh")) { colorToning.sathigh = keyFile.get_double ("ColorToning", "Sathigh"); if (pedited) pedited->colorToning.sathigh = true; } + if (keyFile.has_key ("ColorToning", "Redmed")) { colorToning.redmed = keyFile.get_double ("ColorToning", "Redmed"); if (pedited) pedited->colorToning.redmed = true; } + if (keyFile.has_key ("ColorToning", "Greenmed")) { colorToning.greenmed = keyFile.get_double ("ColorToning", "Greenmed"); if (pedited) pedited->colorToning.greenmed = true; } + if (keyFile.has_key ("ColorToning", "Bluemed")) { colorToning.bluemed = keyFile.get_double ("ColorToning", "Bluemed"); if (pedited) pedited->colorToning.bluemed = true; } + if (keyFile.has_key ("ColorToning", "Redhigh")) { colorToning.redhigh = keyFile.get_double ("ColorToning", "Redhigh"); if (pedited) pedited->colorToning.redhigh = true; } + if (keyFile.has_key ("ColorToning", "Greenhigh")) { colorToning.greenhigh = keyFile.get_double ("ColorToning", "Greenhigh"); if (pedited) pedited->colorToning.greenhigh = true; } + if (keyFile.has_key ("ColorToning", "Bluehigh")) { colorToning.bluehigh = keyFile.get_double ("ColorToning", "Bluehigh"); if (pedited) pedited->colorToning.bluehigh = true; } +} + + // load raw settings +if (keyFile.has_group ("RAW")) { + if (keyFile.has_key ("RAW", "DarkFrame")) { raw.dark_frame = expandRelativePath(fname, "", keyFile.get_string ("RAW", "DarkFrame" )); if (pedited) pedited->raw.darkFrame = true; } + if (keyFile.has_key ("RAW", "DarkFrameAuto")) { raw.df_autoselect = keyFile.get_boolean ("RAW", "DarkFrameAuto" ); if (pedited) pedited->raw.dfAuto = true; } + if (keyFile.has_key ("RAW", "FlatFieldFile")) { raw.ff_file = expandRelativePath(fname, "", keyFile.get_string ("RAW", "FlatFieldFile" )); if (pedited) pedited->raw.ff_file = true; } + if (keyFile.has_key ("RAW", "FlatFieldAutoSelect")) { raw.ff_AutoSelect = keyFile.get_boolean ("RAW", "FlatFieldAutoSelect" ); if (pedited) pedited->raw.ff_AutoSelect = true; } + if (keyFile.has_key ("RAW", "FlatFieldBlurRadius")) { raw.ff_BlurRadius = keyFile.get_integer ("RAW", "FlatFieldBlurRadius" ); if (pedited) pedited->raw.ff_BlurRadius = true; } + if (keyFile.has_key ("RAW", "FlatFieldBlurType")) { raw.ff_BlurType = keyFile.get_string ("RAW", "FlatFieldBlurType" ); if (pedited) pedited->raw.ff_BlurType = true; } + if (keyFile.has_key ("RAW", "FlatFieldAutoClipControl")) { raw.ff_AutoClipControl = keyFile.get_boolean ("RAW", "FlatFieldAutoClipControl" ); if (pedited) pedited->raw.ff_AutoClipControl = true; } + if (keyFile.has_key ("RAW", "FlatFieldClipControl")) { raw.ff_clipControl = keyFile.get_boolean ("RAW", "FlatFieldClipControl" ); if (pedited) pedited->raw.ff_clipControl = true; } + if (keyFile.has_key ("RAW", "CA")) { raw.ca_autocorrect = keyFile.get_boolean ("RAW", "CA" ); if (pedited) pedited->raw.caCorrection = true; } + if (keyFile.has_key ("RAW", "CARed")) { raw.cared = keyFile.get_double ("RAW", "CARed" ); if (pedited) pedited->raw.caRed = true; } + if (keyFile.has_key ("RAW", "CABlue")) { raw.cablue = keyFile.get_double ("RAW", "CABlue" ); if (pedited) pedited->raw.caBlue = true; } + // for compatibility to elder pp3 versions + if (keyFile.has_key ("RAW", "HotDeadPixels")) { raw.deadPixelFilter = raw.hotPixelFilter = keyFile.get_boolean ("RAW", "HotDeadPixels" ); if (pedited) pedited->raw.hotPixelFilter = pedited->raw.deadPixelFilter = true; } + if (keyFile.has_key ("RAW", "HotPixelFilter")) { raw.hotPixelFilter = keyFile.get_boolean ("RAW", "HotPixelFilter" ); if (pedited) pedited->raw.hotPixelFilter = true; } + if (keyFile.has_key ("RAW", "DeadPixelFilter")) { raw.deadPixelFilter = keyFile.get_boolean ("RAW", "DeadPixelFilter" ); if (pedited) pedited->raw.deadPixelFilter = true; } + + if (keyFile.has_key ("RAW", "HotDeadPixelThresh")) { raw.hotdeadpix_thresh = keyFile.get_integer ("RAW", "HotDeadPixelThresh" ); if (pedited) pedited->raw.hotDeadPixelThresh = true; } + if (keyFile.has_key ("RAW", "PreExposure")) { raw.expos =keyFile.get_double("RAW", "PreExposure"); if (pedited) pedited->raw.exPos = true; } + if (keyFile.has_key ("RAW", "PrePreserv")) { raw.preser =keyFile.get_double("RAW", "PrePreserv"); if (pedited) pedited->raw.exPreser = true; } + + if (ppVersion < 320) { + if (keyFile.has_key ("RAW", "Method")) { raw.bayersensor.method = keyFile.get_string ("RAW", "Method"); if (pedited) pedited->raw.bayersensor.method = true; } + if (keyFile.has_key ("RAW", "CcSteps")) { raw.bayersensor.ccSteps = keyFile.get_integer ("RAW", "CcSteps"); if (pedited) pedited->raw.bayersensor.ccSteps = true; } + if (keyFile.has_key ("RAW", "LineDenoise")) { raw.bayersensor.linenoise = keyFile.get_integer ("RAW", "LineDenoise" ); if (pedited) pedited->raw.bayersensor.linenoise = true; } + if (keyFile.has_key ("RAW", "GreenEqThreshold")) { raw.bayersensor.greenthresh= keyFile.get_integer ("RAW", "GreenEqThreshold"); if (pedited) pedited->raw.bayersensor.greenEq = true; } + if (keyFile.has_key ("RAW", "DCBIterations")) { raw.bayersensor.dcb_iterations = keyFile.get_integer("RAW", "DCBIterations"); if (pedited) pedited->raw.bayersensor.dcbIterations = true; } + if (keyFile.has_key ("RAW", "DCBEnhance")) { raw.bayersensor.dcb_enhance = keyFile.get_boolean("RAW", "DCBEnhance"); if (pedited) pedited->raw.bayersensor.dcbEnhance = true; } + if (keyFile.has_key ("RAW", "LMMSEIterations")) { raw.bayersensor.lmmse_iterations = keyFile.get_integer("RAW", "LMMSEIterations"); if (pedited) pedited->raw.bayersensor.lmmseIterations = true; } + if (keyFile.has_key ("RAW", "PreBlackzero")) { raw.bayersensor.black0 = keyFile.get_double("RAW", "PreBlackzero"); if (pedited) pedited->raw.bayersensor.exBlack0 = true; } + if (keyFile.has_key ("RAW", "PreBlackone")) { raw.bayersensor.black1 = keyFile.get_double("RAW", "PreBlackone"); if (pedited) pedited->raw.bayersensor.exBlack1 = true; } + if (keyFile.has_key ("RAW", "PreBlacktwo")) { raw.bayersensor.black2 = keyFile.get_double("RAW", "PreBlacktwo"); if (pedited) pedited->raw.bayersensor.exBlack2 = true; } + if (keyFile.has_key ("RAW", "PreBlackthree")) { raw.bayersensor.black3 = keyFile.get_double("RAW", "PreBlackthree"); if (pedited) pedited->raw.bayersensor.exBlack3 = true; } + if (keyFile.has_key ("RAW", "PreTwoGreen")) { raw.bayersensor.twogreen = keyFile.get_boolean("RAW", "PreTwoGreen"); if (pedited) pedited->raw.bayersensor.exTwoGreen = true; } + //if (keyFile.has_key ("RAW", "ALLEnhance")) { raw.bayersensor.all_enhance = keyFile.get_boolean("RAW", "ALLEnhance"); if (pedited) pedited->raw.bayersensor.allEnhance = true; } + } +} + +// load Bayer sensors' raw settings +if (keyFile.has_group ("RAW Bayer")) { + if (keyFile.has_key ("RAW Bayer", "Method")) { raw.bayersensor.method = keyFile.get_string ("RAW Bayer", "Method"); if (pedited) pedited->raw.bayersensor.method = true; } + if (keyFile.has_key ("RAW Bayer", "CcSteps")) { raw.bayersensor.ccSteps = keyFile.get_integer ("RAW Bayer", "CcSteps"); if (pedited) pedited->raw.bayersensor.ccSteps = true; } + if (keyFile.has_key ("RAW Bayer", "PreBlack0")) { raw.bayersensor.black0 = keyFile.get_double("RAW Bayer", "PreBlack0"); if (pedited) pedited->raw.bayersensor.exBlack0 = true; } + if (keyFile.has_key ("RAW Bayer", "PreBlack1")) { raw.bayersensor.black1 = keyFile.get_double("RAW Bayer", "PreBlack1"); if (pedited) pedited->raw.bayersensor.exBlack1 = true; } + if (keyFile.has_key ("RAW Bayer", "PreBlack2")) { raw.bayersensor.black2 = keyFile.get_double("RAW Bayer", "PreBlack2"); if (pedited) pedited->raw.bayersensor.exBlack2 = true; } + if (keyFile.has_key ("RAW Bayer", "PreBlack3")) { raw.bayersensor.black3 = keyFile.get_double("RAW Bayer", "PreBlack3"); if (pedited) pedited->raw.bayersensor.exBlack3 = true; } + if (keyFile.has_key ("RAW Bayer", "PreTwoGreen")) { raw.bayersensor.twogreen = keyFile.get_boolean("RAW Bayer", "PreTwoGreen"); if (pedited) pedited->raw.bayersensor.exTwoGreen = true; } + if (keyFile.has_key ("RAW Bayer", "LineDenoise")) { raw.bayersensor.linenoise = keyFile.get_integer ("RAW Bayer", "LineDenoise" ); if (pedited) pedited->raw.bayersensor.linenoise = true; } + if (keyFile.has_key ("RAW Bayer", "GreenEqThreshold")) { raw.bayersensor.greenthresh= keyFile.get_integer ("RAW Bayer", "GreenEqThreshold"); if (pedited) pedited->raw.bayersensor.greenEq = true; } + if (keyFile.has_key ("RAW Bayer", "DCBIterations")) { raw.bayersensor.dcb_iterations = keyFile.get_integer("RAW Bayer", "DCBIterations"); if (pedited) pedited->raw.bayersensor.dcbIterations = true; } + if (keyFile.has_key ("RAW Bayer", "DCBEnhance")) { raw.bayersensor.dcb_enhance = keyFile.get_boolean("RAW Bayer", "DCBEnhance"); if (pedited) pedited->raw.bayersensor.dcbEnhance = true; } + if (keyFile.has_key ("RAW Bayer", "LMMSEIterations")) { raw.bayersensor.lmmse_iterations = keyFile.get_integer("RAW Bayer", "LMMSEIterations"); if (pedited) pedited->raw.bayersensor.lmmseIterations = true; } + //if (keyFile.has_key ("RAW Bayer", "ALLEnhance")) { raw.bayersensor.all_enhance = keyFile.get_boolean("RAW Bayer", "ALLEnhance"); if (pedited) pedited->raw.bayersensor.allEnhance = true; } +} + +// load X-Trans sensors' raw settings +if (keyFile.has_group ("RAW X-Trans")) { + if (keyFile.has_key ("RAW X-Trans", "Method")) { raw.xtranssensor.method = keyFile.get_string ("RAW X-Trans", "Method"); if (pedited) pedited->raw.xtranssensor.method = true; } + if (keyFile.has_key ("RAW X-Trans", "CcSteps")) { raw.xtranssensor.ccSteps = keyFile.get_integer ("RAW X-Trans", "CcSteps"); if (pedited) pedited->raw.xtranssensor.ccSteps = true; } + if (keyFile.has_key ("RAW X-Trans", "PreBlackRed")) { raw.xtranssensor.blackred = keyFile.get_double("RAW X-Trans", "PreBlackRed"); if (pedited) pedited->raw.xtranssensor.exBlackRed = true; } + if (keyFile.has_key ("RAW X-Trans", "PreBlackGreen")) { raw.xtranssensor.blackgreen = keyFile.get_double("RAW X-Trans", "PreBlackGreen"); if (pedited) pedited->raw.xtranssensor.exBlackGreen = true; } + if (keyFile.has_key ("RAW X-Trans", "PreBlackBlue")) { raw.xtranssensor.blackblue = keyFile.get_double("RAW X-Trans", "PreBlackBlue"); if (pedited) pedited->raw.xtranssensor.exBlackBlue = true; } +} + + // load exif change settings +if (keyFile.has_group ("Exif")) { + std::vector keys = keyFile.get_keys ("Exif"); + for (int i=0; i<(int)keys.size(); i++) { + Glib::ustring tmpStr = keyFile.get_string ("Exif", keys[i]); + exif[keys[i]] = keyFile.get_string ("Exif", keys[i]); + if (pedited) pedited->exif = true; + } +} + + /* + * Load iptc change settings + * + * Existing values are preserved, and the stored values + * are added to the list. To reset a field, the user has to + * save the profile with the field leaved empty, but still + * terminated by a semi-column ";" + * + * Please note that the old Keywords and SupplementalCategories + * tag content is fully replaced by the new one, + * i.e. they don't merge + */ +if (keyFile.has_group ("IPTC")) { + std::vector keys = keyFile.get_keys ("IPTC"); + IPTCPairs::iterator element; + for (unsigned int i=0; isecond.clear(); + } + + // TODO: look out if merging Keywords and SupplementalCategories from the procparams chain would be interesting + std::vector currIptc = keyFile.get_string_list ("IPTC", keys[i]); + for ( + std::vector::iterator currLoadedTagValue=currIptc.begin(); + currLoadedTagValue!=currIptc.end(); + currLoadedTagValue++) + { + iptc[keys[i]].push_back(currLoadedTagValue->data()); + } + if (pedited) pedited->iptc = true; + } +} + + + return 0; + } + catch (const Glib::Error& e) { + printf ("-->%s\n", e.what().c_str()); + return 1; + } + catch (...) { + printf ("-->unknown exception!\n"); + return 1; + } + return 0; +} + +const Glib::ustring ColorManagementParams::NoICMString = Glib::ustring("No ICM: sRGB output"); + +bool operator==(const WaveletParams & a, const WaveletParams & b) { + if(a.enabled != b.enabled) + return false; + + for(int i = 0; i < 9; i++) { + if(a.c[i] != b.c[i]) + return false; + } + for(int i = 0; i < 9; i++) { + if(a.ch[i] != b.ch[i]) + return false; + } + + return true; +} + + + +bool operator==(const DirPyrEqualizerParams & a, const DirPyrEqualizerParams & b) { + if(a.enabled != b.enabled) + return false; + + for(int i = 0; i < 6; i++) { + if(a.mult[i] != b.mult[i]) + return false; + } + if (a.threshold != b.threshold) + return false; + + return true; +} + +/*bool operator==(const ExifPairs& a, const ExifPairs& b) { + + return a.field == b.field && a.value == b.value; +} + +bool operator==(const IPTCPairs& a, const IPTCPairs& b) { + + return a.field == b.field && a.values == b.values; +}*/ +bool ProcParams::operator== (const ProcParams& other) { + + return + toneCurve.curve == other.toneCurve.curve + && toneCurve.curve2 == other.toneCurve.curve2 + && toneCurve.brightness == other.toneCurve.brightness + && toneCurve.black == other.toneCurve.black + && toneCurve.contrast == other.toneCurve.contrast + && toneCurve.saturation == other.toneCurve.saturation + && toneCurve.shcompr == other.toneCurve.shcompr + && toneCurve.hlcompr == other.toneCurve.hlcompr + && toneCurve.hlcomprthresh == other.toneCurve.hlcomprthresh + && toneCurve.autoexp == other.toneCurve.autoexp + && toneCurve.clip == other.toneCurve.clip + && toneCurve.expcomp == other.toneCurve.expcomp + && toneCurve.curveMode == other.toneCurve.curveMode + && toneCurve.curveMode2 == other.toneCurve.curveMode2 + && toneCurve.hrenabled == other.toneCurve.hrenabled + && toneCurve.method == other.toneCurve.method + && labCurve.lcurve == other.labCurve.lcurve + && labCurve.acurve == other.labCurve.acurve + && labCurve.bcurve == other.labCurve.bcurve + && labCurve.cccurve == other.labCurve.cccurve + && labCurve.chcurve == other.labCurve.chcurve + && labCurve.lhcurve == other.labCurve.lhcurve + && labCurve.hhcurve == other.labCurve.hhcurve + && labCurve.lccurve == other.labCurve.lccurve + && labCurve.clcurve == other.labCurve.clcurve + && labCurve.brightness == other.labCurve.brightness + && labCurve.contrast == other.labCurve.contrast + && labCurve.chromaticity == other.labCurve.chromaticity + && labCurve.avoidcolorshift == other.labCurve.avoidcolorshift + && labCurve.rstprotection == other.labCurve.rstprotection + && labCurve.lcredsk == other.labCurve.lcredsk + && sharpenEdge.enabled == other.sharpenEdge.enabled + && sharpenEdge.passes == other.sharpenEdge.passes + && sharpenEdge.amount == other.sharpenEdge.amount + && sharpenEdge.threechannels == other.sharpenEdge.threechannels + && sharpenMicro.enabled == other.sharpenMicro.enabled + && sharpenMicro.matrix == other.sharpenMicro.matrix + && sharpenMicro.amount == other.sharpenMicro.amount + && sharpenMicro.uniformity == other.sharpenMicro.uniformity + && sharpening.enabled == other.sharpening.enabled + && sharpening.radius == other.sharpening.radius + && sharpening.amount == other.sharpening.amount + && sharpening.threshold == other.sharpening.threshold + && sharpening.edgesonly == other.sharpening.edgesonly + && sharpening.edges_radius == other.sharpening.edges_radius + && sharpening.edges_tolerance == other.sharpening.edges_tolerance + && sharpening.halocontrol == other.sharpening.halocontrol + && sharpening.halocontrol_amount== other.sharpening.halocontrol_amount + && sharpening.method == other.sharpening.method + && sharpening.deconvamount == other.sharpening.deconvamount + && sharpening.deconvradius == other.sharpening.deconvradius + && sharpening.deconviter == other.sharpening.deconviter + && sharpening.deconvdamping == other.sharpening.deconvdamping + && prsharpening.enabled == other.prsharpening.enabled + && prsharpening.radius == other.prsharpening.radius + && prsharpening.amount == other.prsharpening.amount + && prsharpening.threshold == other.prsharpening.threshold + && prsharpening.edgesonly == other.prsharpening.edgesonly + && prsharpening.edges_radius == other.prsharpening.edges_radius + && prsharpening.edges_tolerance == other.prsharpening.edges_tolerance + && prsharpening.halocontrol == other.prsharpening.halocontrol + && prsharpening.halocontrol_amount== other.prsharpening.halocontrol_amount + && prsharpening.method == other.prsharpening.method + && prsharpening.deconvamount == other.prsharpening.deconvamount + && prsharpening.deconvradius == other.prsharpening.deconvradius + && prsharpening.deconviter == other.prsharpening.deconviter + && prsharpening.deconvdamping == other.prsharpening.deconvdamping + && vibrance.enabled == other.vibrance.enabled + && vibrance.pastels == other.vibrance.pastels + && vibrance.saturated == other.vibrance.saturated + && vibrance.psthreshold == other.vibrance.psthreshold + && vibrance.protectskins == other.vibrance.protectskins + && vibrance.avoidcolorshift == other.vibrance.avoidcolorshift + && vibrance.pastsattog == other.vibrance.pastsattog + && vibrance.skintonescurve == other.vibrance.skintonescurve + //&& colorBoost.amount == other.colorBoost.amount + //&& colorBoost.avoidclip == other.colorBoost.avoidclip + //&& colorBoost.enable_saturationlimiter == other.colorBoost.enable_saturationlimiter + //&& colorBoost.saturationlimit == other.colorBoost.saturationlimit + && wb.method == other.wb.method + && wb.green == other.wb.green + && wb.temperature == other.wb.temperature + && wb.equal == other.wb.equal + //&& colorShift.a == other.colorShift.a + //&& colorShift.b == other.colorShift.b + && colorappearance.enabled == other.colorappearance.enabled + && colorappearance.degree == other.colorappearance.degree + && colorappearance.autodegree == other.colorappearance.autodegree + && colorappearance.surround == other.colorappearance.surround + && colorappearance.adapscen == other.colorappearance.adapscen + && colorappearance.autoadapscen == other.colorappearance.autoadapscen + && colorappearance.adaplum == other.colorappearance.adaplum + && colorappearance.badpixsl == other.colorappearance.badpixsl + && colorappearance.wbmodel == other.colorappearance.wbmodel + && colorappearance.algo == other.colorappearance.algo + && colorappearance.curveMode == other.colorappearance.curveMode + && colorappearance.curveMode2 == other.colorappearance.curveMode2 + && colorappearance.curveMode3 == other.colorappearance.curveMode3 + && colorappearance.jlight == other.colorappearance.jlight + && colorappearance.qbright == other.colorappearance.qbright + && colorappearance.chroma == other.colorappearance.chroma + && colorappearance.schroma == other.colorappearance.schroma + && colorappearance.mchroma == other.colorappearance.mchroma + && colorappearance.rstprotection == other.colorappearance.rstprotection + && colorappearance.contrast == other.colorappearance.contrast + && colorappearance.qcontrast == other.colorappearance.qcontrast + && colorappearance.colorh == other.colorappearance.colorh + && impulseDenoise.enabled == other.impulseDenoise.enabled + && impulseDenoise.thresh == other.impulseDenoise.thresh + && dirpyrDenoise.enabled == other.dirpyrDenoise.enabled + && dirpyrDenoise.enhance == other.dirpyrDenoise.enhance + && dirpyrDenoise.median == other.dirpyrDenoise.median + && dirpyrDenoise.autochroma == other.dirpyrDenoise.autochroma +// && dirpyrDenoise.perform == other.dirpyrDenoise.perform + && dirpyrDenoise.luma == other.dirpyrDenoise.luma + && dirpyrDenoise.lcurve == other.dirpyrDenoise.lcurve + && dirpyrDenoise.cccurve == other.dirpyrDenoise.cccurve + && dirpyrDenoise.Ldetail == other.dirpyrDenoise.Ldetail + && dirpyrDenoise.chroma == other.dirpyrDenoise.chroma + && dirpyrDenoise.dmethod == other.dirpyrDenoise.dmethod + && dirpyrDenoise.Lmethod == other.dirpyrDenoise.Lmethod + && dirpyrDenoise.Cmethod == other.dirpyrDenoise.Cmethod + && dirpyrDenoise.C2method == other.dirpyrDenoise.C2method + && dirpyrDenoise.smethod == other.dirpyrDenoise.smethod + && dirpyrDenoise.medmethod == other.dirpyrDenoise.medmethod + && dirpyrDenoise.methodmed == other.dirpyrDenoise.methodmed + && dirpyrDenoise.rgbmethod == other.dirpyrDenoise.rgbmethod + && dirpyrDenoise.redchro == other.dirpyrDenoise.redchro + && dirpyrDenoise.bluechro == other.dirpyrDenoise.bluechro + && dirpyrDenoise.gamma == other.dirpyrDenoise.gamma + && dirpyrDenoise.passes == other.dirpyrDenoise.passes + && epd.enabled == other.epd.enabled + && epd.strength == other.epd.strength + && epd.gamma == other.epd.gamma + && epd.edgeStopping == other.epd.edgeStopping + && epd.scale == other.epd.scale + && epd.reweightingIterates == other.epd.reweightingIterates + && defringe.enabled == other.defringe.enabled + && defringe.radius == other.defringe.radius + && defringe.threshold == other.defringe.threshold + && defringe.huecurve == other.defringe.huecurve + + //&& lumaDenoise.enabled == other.lumaDenoise.enabled + //&& lumaDenoise.radius == other.lumaDenoise.radius + //&& lumaDenoise.edgetolerance == other.lumaDenoise.edgetolerance + //&& colorDenoise.enabled == other.colorDenoise.enabled + //&& colorDenoise.edgetolerance == other.colorDenoise.edgetolerance + //&& colorDenoise.edgesensitive == other.colorDenoise.edgesensitive + && sh.enabled == other.sh.enabled + && sh.hq == other.sh.hq + && sh.highlights == other.sh.highlights + && sh.htonalwidth == other.sh.htonalwidth + && sh.shadows == other.sh.shadows + && sh.stonalwidth == other.sh.stonalwidth + && sh.localcontrast == other.sh.localcontrast + && sh.radius == other.sh.radius + && crop.enabled == other.crop.enabled + && crop.x == other.crop.x + && crop.y == other.crop.y + && crop.w == other.crop.w + && crop.h == other.crop.h + && crop.fixratio == other.crop.fixratio + && crop.ratio == other.crop.ratio + && crop.orientation == other.crop.orientation + && crop.guide == other.crop.guide + && coarse.rotate == other.coarse.rotate + && coarse.hflip == other.coarse.hflip + && coarse.vflip == other.coarse.vflip + && rotate.degree == other.rotate.degree + && commonTrans.autofill == other.commonTrans.autofill + && distortion.amount == other.distortion.amount + && lensProf.lcpFile == other.lensProf.lcpFile + && lensProf.useDist == other.lensProf.useDist + && lensProf.useVign == other.lensProf.useVign + && lensProf.useCA == other.lensProf.useCA + && perspective.horizontal == other.perspective.horizontal + && perspective.vertical == other.perspective.vertical + && gradient.enabled == other.gradient.enabled + && gradient.degree == other.gradient.degree + && gradient.feather == other.gradient.feather + && gradient.strength == other.gradient.strength + && gradient.centerX == other.gradient.centerX + && gradient.centerY == other.gradient.centerY + && pcvignette.enabled == other.pcvignette.enabled + && pcvignette.strength == other.pcvignette.strength + && pcvignette.feather == other.pcvignette.feather + && pcvignette.roundness == other.pcvignette.roundness + && cacorrection.red == other.cacorrection.red + && cacorrection.blue == other.cacorrection.blue + && vignetting.amount == other.vignetting.amount + && vignetting.radius == other.vignetting.radius + && vignetting.strength == other.vignetting.strength + && vignetting.centerX == other.vignetting.centerX + && vignetting.centerY == other.vignetting.centerY + && !memcmp (&chmixer.red, &other.chmixer.red, 3*sizeof(int)) + && !memcmp (&chmixer.green, &other.chmixer.green, 3*sizeof(int)) + && !memcmp (&chmixer.blue, &other.chmixer.blue, 3*sizeof(int)) + && blackwhite.mixerRed == other.blackwhite.mixerRed + && blackwhite.mixerOrange == other.blackwhite.mixerOrange + && blackwhite.mixerYellow == other.blackwhite.mixerYellow + && blackwhite.mixerGreen == other.blackwhite.mixerGreen + && blackwhite.mixerCyan == other.blackwhite.mixerCyan + && blackwhite.mixerBlue == other.blackwhite.mixerBlue + && blackwhite.mixerMagenta == other.blackwhite.mixerMagenta + && blackwhite.mixerPurple == other.blackwhite.mixerPurple + && blackwhite.gammaRed == other.blackwhite.gammaRed + && blackwhite.gammaGreen == other.blackwhite.gammaGreen + && blackwhite.gammaBlue == other.blackwhite.gammaBlue + && blackwhite.filter == other.blackwhite.filter + && blackwhite.setting == other.blackwhite.setting + && blackwhite.method == other.blackwhite.method + && blackwhite.luminanceCurve == other.blackwhite.luminanceCurve + && blackwhite.beforeCurve == other.blackwhite.beforeCurve + && blackwhite.afterCurve == other.blackwhite.afterCurve + && blackwhite.beforeCurveMode == other.blackwhite.beforeCurveMode + && blackwhite.afterCurveMode == other.blackwhite.afterCurveMode + && blackwhite.autoc == other.blackwhite.autoc + && blackwhite.algo == other.blackwhite.algo + && resize.scale == other.resize.scale + && resize.appliesTo == other.resize.appliesTo + && resize.method == other.resize.method + && resize.dataspec == other.resize.dataspec + && resize.width == other.resize.width + && resize.height == other.resize.height + && raw.bayersensor.method == other.raw.bayersensor.method + && raw.bayersensor.ccSteps == other.raw.bayersensor.ccSteps + && raw.bayersensor.black0==other.raw.bayersensor.black0 + && raw.bayersensor.black1==other.raw.bayersensor.black1 + && raw.bayersensor.black2==other.raw.bayersensor.black2 + && raw.bayersensor.black3==other.raw.bayersensor.black3 + && raw.bayersensor.twogreen==other.raw.bayersensor.twogreen + && raw.bayersensor.greenthresh == other.raw.bayersensor.greenthresh + && raw.bayersensor.linenoise == other.raw.bayersensor.linenoise + && raw.bayersensor.dcb_enhance == other.raw.bayersensor.dcb_enhance + && raw.bayersensor.dcb_iterations == other.raw.bayersensor.dcb_iterations + && raw.xtranssensor.method == other.raw.xtranssensor.method + && raw.xtranssensor.ccSteps == other.raw.xtranssensor.ccSteps + && raw.xtranssensor.blackred==other.raw.xtranssensor.blackred + && raw.xtranssensor.blackgreen==other.raw.xtranssensor.blackgreen + && raw.xtranssensor.blackblue==other.raw.xtranssensor.blackblue + && raw.dark_frame == other.raw.dark_frame + && raw.df_autoselect == other.raw.df_autoselect + && raw.ff_file == other.raw.ff_file + && raw.ff_AutoSelect == other.raw.ff_AutoSelect + && raw.ff_BlurRadius == other.raw.ff_BlurRadius + && raw.ff_BlurType == other.raw.ff_BlurType + && raw.ff_AutoClipControl == other.raw.ff_AutoClipControl + && raw.ff_clipControl == other.raw.ff_clipControl + && raw.expos==other.raw.expos + && raw.preser==other.raw.preser + && raw.ca_autocorrect == other.raw.ca_autocorrect + && raw.cared == other.raw.cared + && raw.cablue == other.raw.cablue + && raw.hotPixelFilter == other.raw.hotPixelFilter + && raw.deadPixelFilter == other.raw.deadPixelFilter + && raw.hotdeadpix_thresh == other.raw.hotdeadpix_thresh + && icm.input == other.icm.input + && icm.toneCurve == other.icm.toneCurve + && icm.applyLookTable == other.icm.applyLookTable + && icm.applyBaselineExposureOffset == other.icm.applyBaselineExposureOffset + && icm.applyHueSatMap == other.icm.applyHueSatMap + && icm.blendCMSMatrix == other.icm.blendCMSMatrix + && icm.dcpIlluminant == other.icm.dcpIlluminant + && icm.working == other.icm.working + && icm.output == other.icm.output + && icm.gamma == other.icm.gamma + && icm.freegamma == other.icm.freegamma + && icm.gampos == other.icm.gampos + && icm.slpos == other.icm.slpos + && wavelet == other.wavelet + && wavelet.Lmethod == other.wavelet.Lmethod + && wavelet.CLmethod == other.wavelet.CLmethod + && wavelet.Backmethod == other.wavelet.Backmethod + && wavelet.Tilesmethod == other.wavelet.Tilesmethod + && wavelet.daubcoeffmethod == other.wavelet.daubcoeffmethod + && wavelet.CHmethod == other.wavelet.CHmethod + && wavelet.CHSLmethod == other.wavelet.CHSLmethod + && wavelet.EDmethod == other.wavelet.EDmethod + && wavelet.BAmethod == other.wavelet.BAmethod + && wavelet.TMmethod == other.wavelet.TMmethod + && wavelet.HSmethod == other.wavelet.HSmethod + && wavelet.Dirmethod == other.wavelet.Dirmethod + && wavelet.rescon == other.wavelet.rescon + && wavelet.resconH == other.wavelet.resconH + && wavelet.reschro == other.wavelet.reschro + && wavelet.tmrs == other.wavelet.tmrs + && wavelet.gamma == other.wavelet.gamma + && wavelet.sup == other.wavelet.sup + && wavelet.sky == other.wavelet.sky + && wavelet.thres == other.wavelet.thres + && wavelet.threshold == other.wavelet.threshold + && wavelet.chroma == other.wavelet.chroma + && wavelet.chro == other.wavelet.chro + && wavelet.tmr == other.wavelet.tmr + && wavelet.contrast == other.wavelet.contrast + && wavelet.median == other.wavelet.median + && wavelet.medianlev == other.wavelet.medianlev + && wavelet.linkedg == other.wavelet.linkedg + && wavelet.cbenab == other.wavelet.cbenab + && wavelet.lipst == other.wavelet.lipst + && wavelet.Medgreinf == other.wavelet.Medgreinf + && wavelet.edgrad == other.wavelet.edgrad + && wavelet.edgval == other.wavelet.edgval + && wavelet.edgthresh == other.wavelet.edgthresh + && wavelet.thr == other.wavelet.thr + && wavelet.thrH == other.wavelet.thrH + && wavelet.threshold == other.wavelet.threshold + && wavelet.threshold2 == other.wavelet.threshold2 + && wavelet.edgedetect == other.wavelet.edgedetect + && wavelet.edgedetectthr == other.wavelet.edgedetectthr + && wavelet.edgedetectthr2 == other.wavelet.edgedetectthr2 + && wavelet.hueskin == other.wavelet.hueskin + && wavelet.hueskin2 == other.wavelet.hueskin2 + && wavelet.hllev == other.wavelet.hllev + && wavelet.bllev == other.wavelet.bllev + && wavelet.edgcont == other.wavelet.edgcont + && wavelet.level0noise == other.wavelet.level0noise + && wavelet.level1noise == other.wavelet.level1noise + && wavelet.level2noise == other.wavelet.level2noise + && wavelet.pastlev == other.wavelet.pastlev + && wavelet.satlev == other.wavelet.satlev + && wavelet.opacityCurveRG == other.wavelet.opacityCurveRG + && wavelet.opacityCurveBY == other.wavelet.opacityCurveBY + && wavelet.opacityCurveW == other.wavelet.opacityCurveW + && wavelet.opacityCurveWL == other.wavelet.opacityCurveWL + && wavelet.hhcurve == other.wavelet.hhcurve + && wavelet.Chcurve == other.wavelet.Chcurve + && wavelet.ccwcurve == other.wavelet.ccwcurve + && wavelet.wavclCurve == other.wavelet.wavclCurve + && wavelet.skinprotect == other.wavelet.skinprotect + && wavelet.strength == other.wavelet.strength + && wavelet.balance == other.wavelet.balance + && wavelet.greenhigh == other.wavelet.greenhigh + && wavelet.greenmed == other.wavelet.greenmed + && wavelet.greenlow == other.wavelet.greenlow + && wavelet.bluehigh == other.wavelet.bluehigh + && wavelet.bluemed == other.wavelet.bluemed + && wavelet.bluelow == other.wavelet.bluelow + && wavelet.iter == other.wavelet.iter + && dirpyrequalizer == other.dirpyrequalizer + // && dirpyrequalizer.algo == other.dirpyrequalizer.algo + && dirpyrequalizer.hueskin == other.dirpyrequalizer.hueskin + && dirpyrequalizer.threshold == other.dirpyrequalizer.threshold + && dirpyrequalizer.skinprotect == other.dirpyrequalizer.skinprotect + && hsvequalizer.hcurve == other.hsvequalizer.hcurve + && hsvequalizer.scurve == other.hsvequalizer.scurve + && hsvequalizer.vcurve == other.hsvequalizer.vcurve + && filmSimulation.enabled == other.filmSimulation.enabled + && filmSimulation.clutFilename == other.filmSimulation.clutFilename + && filmSimulation.strength == other.filmSimulation.strength + && rgbCurves.rcurve == other.rgbCurves.rcurve + && rgbCurves.gcurve == other.rgbCurves.gcurve + && rgbCurves.bcurve == other.rgbCurves.bcurve + && colorToning.enabled == other.colorToning.enabled + && colorToning.twocolor == other.colorToning.twocolor + && colorToning.method == other.colorToning.method + && colorToning.colorCurve == other.colorToning.colorCurve + && colorToning.opacityCurve == other.colorToning.opacityCurve + && colorToning.autosat == other.colorToning.autosat + && colorToning.satProtectionThreshold == other.colorToning.satProtectionThreshold + && colorToning.saturatedOpacity == other.colorToning.saturatedOpacity + && colorToning.strength == other.colorToning.strength + && colorToning.hlColSat == other.colorToning.hlColSat + && colorToning.shadowsColSat == other.colorToning.shadowsColSat + && colorToning.balance == other.colorToning.balance + && colorToning.clcurve == other.colorToning.clcurve + && colorToning.cl2curve == other.colorToning.cl2curve + && colorToning.redlow == other.colorToning.redlow + && colorToning.greenlow == other.colorToning.greenlow + && colorToning.bluelow == other.colorToning.bluelow + && colorToning.satlow == other.colorToning.satlow + && colorToning.sathigh == other.colorToning.sathigh + && colorToning.redmed == other.colorToning.redmed + && colorToning.greenmed == other.colorToning.greenmed + && colorToning.bluemed == other.colorToning.bluemed + && colorToning.redhigh == other.colorToning.redhigh + && colorToning.greenhigh == other.colorToning.greenhigh + && colorToning.bluehigh == other.colorToning.bluehigh + && exif==other.exif + && iptc==other.iptc; +} + +bool ProcParams::operator!= (const ProcParams& other) { + + return !(*this==other); +} + +PartialProfile::PartialProfile(bool createInstance, bool paramsEditedValue) { + if (createInstance) { + pparams = new ProcParams(); + pedited = new ParamsEdited(paramsEditedValue); + } + else { + pparams = NULL; + pedited = NULL; + } +} + +PartialProfile::PartialProfile(ProcParams* pp, ParamsEdited* pe, bool fullCopy) { + if (fullCopy && pp) { + pparams = new ProcParams(*pp); + } + else + pparams = pp; + + if (fullCopy && pe) { + pedited = new ParamsEdited(*pe); + } + else + pedited = pe; +} + +PartialProfile::PartialProfile(const ProcParams* pp, const ParamsEdited* pe) { + if (pp) { + pparams = new ProcParams(*pp); + } + else + pparams = NULL; + + if (pe) { + pedited = new ParamsEdited(*pe); + } + else + pedited = NULL; +} + +int PartialProfile::load (Glib::ustring fName) { + if (!pparams) pparams = new ProcParams(); + if (!pedited) pedited = new ParamsEdited(); + if (fName == DEFPROFILE_INTERNAL) + return 0; + else + return pparams->load(fName, pedited); +} + +void PartialProfile::deleteInstance () { + if (pparams) { delete pparams; pparams = NULL; } + if (pedited) { delete pedited; pedited = NULL; } +} + +/* + * Set the all values of the General section to false + * in order to preserve them in applyTo + */ +void PartialProfile::clearGeneral () { + if (pedited) { + pedited->general.colorlabel = false; + pedited->general.intrash = false; + pedited->general.rank = false; + } +} + +const void PartialProfile::applyTo(ProcParams *destParams) const { + if (destParams && pparams && pedited) { + pedited->combine(*destParams, *pparams, true); + } +} + +void PartialProfile::set(bool v) { + if (pedited) pedited->set(v); +} + +} +} + diff --git a/rtengine/procparams.h b/rtengine/procparams.h new file mode 100644 index 000000000..d15f39f14 --- /dev/null +++ b/rtengine/procparams.h @@ -0,0 +1,1231 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _PROCPARAMS_H_ +#define _PROCPARAMS_H_ + +#include +#include +#include +#include +#include "LUT.h" + +class ParamsEdited; + +namespace rtengine { + +class ColorGradientCurve; +class OpacityCurve; +class NoiseCurve; +class WavCurve; +class WavOpacityCurveRG; +class WavOpacityCurveBY; +class WavOpacityCurveW; +class WavOpacityCurveWL; + +namespace procparams { + +template +class Threshold { + public: + T value[4]; + + protected: + bool initEq1; + bool _isDouble; +#ifndef NDEBUG + unsigned int part[5]; +#endif + public: + Threshold (T bottom, T top, bool startAtOne) { + initEq1 = startAtOne; + value[0] = bottom; + value[1] = top; + value[2] = T(0); + value[3] = T(0); + _isDouble = false; + } + + Threshold (T bottomLeft, T topLeft, T bottomRight, T topRight, bool startAtOne) { + initEq1 = startAtOne; + value[0] = bottomLeft; + value[1] = topLeft; + value[2] = bottomRight; + value[3] = topRight; + _isDouble = true; + } + + // for convenience, since 'values' is public + void setValues(T bottom, T top) { + value[0] = bottom; + value[1] = top; + } + + // for convenience, since 'values' is public + void setValues(T bottomLeft, T topLeft, T bottomRight, T topRight) { + value[0] = bottomLeft; + value[1] = topLeft; + value[2] = bottomRight; + value[3] = topRight; + } + + bool isDouble() const { return _isDouble; } + + // RT: Type of the returned value + // RV: Type of the value on the X axis + // RV2: Type of the maximum value on the Y axis + template + RT multiply(RV x, RV2 yMax) const { + double val = double(x); + if (initEq1) { + if (_isDouble) { + if (val == double(value[2]) && double(value[2]) == double(value[3])) + // this handle the special case where the 2 right values are the same, then bottom one is sent back, + // useful if one wants to keep the bottom value even beyond the x max bound + return RT(0.); + if (val >= double(value[3])) + return RT(yMax); + if (val > double(value[2])) + return RT(double(yMax)*(val-double(value[2]))/(double(value[3])-double(value[2]))); + } + if (val >= double(value[0])) + return RT(0); + if (val > double(value[1])) + return RT(double(yMax)*(1.-(val-double(value[0]))/(double(value[1])-double(value[0])))); + return RT(yMax); + } + else { + if (_isDouble) { + if (val == double(value[2]) && double(value[2]) == double(value[3])) + // this handle the special case where the 2 right values are the same, then top one is sent back, + // useful if one wants to keep the top value even beyond the x max bound + return RT(yMax); + if (val >= double(value[2])) + return RT(0); + if (val > double(value[3])) + return RT(double(yMax)*(1.-(val-double(value[3]))/(double(value[2])-double(value[3])))); + } + if (val >= double(value[1])) + return RT(yMax); + if (val > double(value[0])) + return RT(double(yMax)*(val-double(value[0]))/(double(value[1])-double(value[0]))); + return RT(0); + } + } + + // RT: Type of the returned value + // RV: Type of the value on the X axis + /*template + RT getRatio(RV val) const { + double val = double(val); + if (initEq1) { + if (_isDouble) { // assuming that simple thresholds will be more frequent + if (val >= double(value[3])) + return RT(1); + if (val > double(value[2])) + return (val-double(value[2]))/(double(value[3])-double(value[2])); + } + if (val >= double(value[1])) + return RT(0); + if (val > double(value[0])) + return 1.-(val-double(value[0]))/(double(value[1])-double(value[0])); + return RT(1); + } + else { + if (_isDouble) { // assuming that simple thresholds will be more frequent + if (val >= double(value[3])) + return RT(0); + if (val > double(value[2])) + return 1.-(val-double(value[2]))/(double(value[3])-double(value[2])); + } + if (val >= double(value[1])) + return RT(1); + if (val > double(value[0])) + return (val-double(value[0]))/(double(value[1])-double(value[0])); + return RT(0); + } + }*/ + + Threshold & operator= (const Threshold &rhs) { + value[0] = rhs.value[0]; + value[1] = rhs.value[1]; + value[2] = rhs.value[2]; + value[3] = rhs.value[3]; + initEq1 = rhs.initEq1; + _isDouble = rhs._isDouble; + return *this; + } + + bool operator== (const Threshold &rhs) const { + if (_isDouble) + return fabs(value[0]-rhs.value[0])<1e-10 + && fabs(value[1]-rhs.value[1])<1e-10 + && fabs(value[2]-rhs.value[2])<1e-10 + && fabs(value[3]-rhs.value[3])<1e-10; + else + return fabs(value[0]-rhs.value[0])<1e-10 + && fabs(value[1]-rhs.value[1])<1e-10; + } +}; + +/** + * Parameters of the tone curve + */ +class ToneCurveParams { + + public: + + enum eTCModeId { + TC_MODE_STD, // Standard modes, the curve is applied on all component individually + TC_MODE_WEIGHTEDSTD, // Weighted standard mode + TC_MODE_FILMLIKE, // Film-like mode, as defined in Adobe's reference code + TC_MODE_SATANDVALBLENDING, // Modify the Saturation and Value channel + TC_MODE_LUMINANCE // Modify the Luminance channel with coefficients from Rec 709's + }; + + bool autoexp; + double clip; + bool hrenabled; // Highlight Reconstruction enabled + Glib::ustring method; // Highlight Reconstruction's method + double expcomp; + std::vector curve; + std::vector curve2; + eTCModeId curveMode; + eTCModeId curveMode2; + int brightness; + int black; + int contrast; + int saturation; + int shcompr; + int hlcompr; // Highlight Recovery's compression + int hlcomprthresh; // Highlight Recovery's threshold + + ToneCurveParams () { + setDefaults(); + } + void setDefaults(); + static bool HLReconstructionNecessary(LUTu &histRedRaw, LUTu &histGreenRaw, LUTu &histBlueRaw); +}; + + +/** + * Parameters of the luminance curve + */ +class LCurveParams { + + public: + std::vector lcurve; + std::vector acurve; + std::vector bcurve; + std::vector cccurve; + std::vector chcurve; + std::vector lhcurve; + std::vector hhcurve; + std::vector lccurve; + std::vector clcurve; + int brightness; + int contrast; + int chromaticity; + bool avoidcolorshift; + double rstprotection; + bool lcredsk; +}; + +/** + * Parameters of the RGB curves + */ +class RGBCurvesParams { + + public: + bool lumamode; + std::vector rcurve; + std::vector gcurve; + std::vector bcurve; +}; + +/** + * Parameters of the Color Toning + */ + +class ColorToningParams { + + public: + bool enabled; + bool autosat; + std::vector opacityCurve; + std::vector colorCurve; + int satProtectionThreshold; + int saturatedOpacity; + int strength; + int balance; + Threshold hlColSat; + Threshold shadowsColSat; + std::vector clcurve; + std::vector cl2curve; + + /* Can be either: + * Splitlr : + * Splitco : + * Splitbal : + * Lab : + * Lch : + * RGBSliders : + * RGBCurves : + */ + Glib::ustring method; + + /* Can be either: + * Std : + * All : + * Separ : + * Two : + */ + Glib::ustring twocolor; + double redlow; + double greenlow; + double bluelow; + double redmed; + double greenmed; + double bluemed; + double redhigh; + double greenhigh; + double bluehigh; + double satlow; + double sathigh; + bool lumamode; + + ColorToningParams (); + void setDefaults(); // SHOULD BE GENERALIZED TO ALL CLASSES! + /// @brief Transform the mixer values to their curve equivalences + void mixerToCurve(std::vector &colorCurve, std::vector &opacityCurve) const; + /// @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; + + static void getDefaultColorCurve(std::vector &curve); + static void getDefaultOpacityCurve(std::vector &curve); + static void getDefaultCLCurve(std::vector &curve); + static void getDefaultCL2Curve(std::vector &curve); +}; + +/** + * Parameters of the sharpening + */ +class SharpeningParams { + + public: + bool enabled; + double radius; + int amount; + Threshold threshold; + bool edgesonly; + double edges_radius; + int edges_tolerance; + bool halocontrol; + int halocontrol_amount; + Glib::ustring method; + int deconvamount; + double deconvradius; + int deconviter; + int deconvdamping; + + SharpeningParams() : threshold(20, 80, 2000, 1200, false) {}; +}; +class SharpenEdgeParams { + public: + bool enabled; + int passes; + double amount; + bool threechannels; +}; +class SharpenMicroParams { + public: + bool enabled; + bool matrix; + double amount; + double uniformity; +}; + +/** + * Parameters of the vibrance + */ +class VibranceParams { + + public: + bool enabled; + int pastels; + int saturated; + Threshold psthreshold; + bool protectskins; + bool avoidcolorshift; + bool pastsattog; + std::vector skintonescurve; + + VibranceParams() : psthreshold(0, 75, false) {}; +}; + +/** + * Parameters of the color boost + */ +/*class ColorBoostParams { + + public: + int amount; + bool avoidclip; + bool enable_saturationlimiter; + double saturationlimit; +};*/ + +/** + * Parameters of the white balance adjustments + */ + +enum WBTypes { + WBT_CAMERA, + WBT_AUTO, + WBT_DAYLIGHT, + WBT_CLOUDY, + WBT_SHADE, + WBT_WATER, + WBT_TUNGSTEN, + WBT_FLUORESCENT, + WBT_LAMP, + WBT_FLASH, + WBT_LED, + // WBT_CUSTOM one must remain the last one! + WBT_CUSTOM +}; + +class WBEntry { +public: + Glib::ustring ppLabel; + enum WBTypes type; + Glib::ustring GUILabel; + int temperature; + double green; + double equal; + + WBEntry(Glib::ustring p, enum WBTypes t, Glib::ustring l, int temp, double green, double equal) : ppLabel(p), type(t), GUILabel(l), temperature(temp), green(green), equal(equal) {}; +}; + +class WBParams { + + public: + static std::vector wbEntries; + Glib::ustring method; + int temperature; + double green; + double equal; + + static void init(); + static void cleanup(); +}; + +/** + * Parameters of colorappearance + */ +class ColorAppearanceParams { + + public: + enum eTCModeId { + TC_MODE_LIGHT, // Lightness mode + TC_MODE_BRIGHT, // Brightness mode + }; + + enum eCTCModeId { + TC_MODE_CHROMA, // chroma mode + TC_MODE_SATUR, // saturation mode + TC_MODE_COLORF, // colorfullness mode + }; + + bool enabled; + int degree; + bool autodegree; + std::vector curve; + std::vector curve2; + std::vector curve3; + eTCModeId curveMode; + eTCModeId curveMode2; + eCTCModeId curveMode3; + + Glib::ustring surround; + double adapscen; + bool autoadapscen; + + double adaplum; + int badpixsl; + Glib::ustring wbmodel; + Glib::ustring algo; + double contrast; + double qcontrast; + double jlight; + double qbright; + double chroma; + double schroma; + double mchroma; + double colorh; + double rstprotection; + bool surrsource; + bool gamut; + // bool badpix; + bool datacie; + bool tonecie; + // bool sharpcie; + }; + +/** + * Parameters of the color shift + */ +/*class ColorShiftParams { + + public: + double a; + double b; +};*/ + +/** + * Parameters of the luminance denoising + */ +/*class LumaDenoiseParams { + + public: + bool enabled; + double radius; + int edgetolerance; +};*/ + +/** + * Parameters of the color denoising + */ +/*class ColorDenoiseParams { + + public: + bool enabled; + int edgetolerance; + bool edgesensitive; + int amount; +};*/ + +/** + * Parameters of defringing + */ +class DefringeParams { + + public: + bool enabled; + double radius; + float threshold; + std::vector huecurve; +}; + +/** + * Parameters of impulse denoising + */ +class ImpulseDenoiseParams { + + public: + bool enabled; + int thresh; + +}; + +/** + * Parameters of the directional pyramid denoising + */ +class DirPyrDenoiseParams { + + public: + std::vector lcurve; + std::vector cccurve; + + bool enabled; + bool enhance; + bool median; + bool autochroma; + + bool perform; + double luma; + double Ldetail; + double chroma; + double redchro; + double bluechro; + double gamma; + Glib::ustring dmethod; + Glib::ustring Lmethod; + Glib::ustring Cmethod; + Glib::ustring C2method; + Glib::ustring smethod; + Glib::ustring medmethod; + Glib::ustring methodmed; + Glib::ustring rgbmethod; + int passes; + + DirPyrDenoiseParams (); + void setDefaults(); // SHOULD BE GENERALIZED TO ALL CLASSES! + void getCurves(NoiseCurve &lCurve, NoiseCurve &cCurve) const; + + static void getDefaultNoisCurve(std::vector &curve); + static void getDefaultCCCurve(std::vector &curve); + +}; + +//EPD related parameters. +class EPDParams{ + public: + bool enabled; + double strength; + double gamma; + double edgeStopping; + double scale; + int reweightingIterates; +}; + +/** + * Parameters of the shadow/highlight enhancement + */ +class SHParams { + + public: + bool enabled; + bool hq; + int highlights; + int htonalwidth; + int shadows; + int stonalwidth; + int localcontrast; + int radius; +}; + +/** + * Parameters of the cropping + */ +class CropParams { + + public: + bool enabled; + int x; + int y; + int w; + int h; + bool fixratio; + Glib::ustring ratio; + Glib::ustring orientation; + Glib::ustring guide; + + CropParams() :enabled(false), x(0),y(0),w(0),h(0),fixratio(false) {}; + void mapToResized(int resizedWidth, int resizedHeight, int scale, int &x1, int &x2, int &y1, int &y2) const; +}; + +/** + * Parameters of the coarse transformations like 90 deg rotations and h/v flipping + */ +class CoarseTransformParams { + + public: + int rotate; + bool hflip; + bool vflip; + + CoarseTransformParams() { + setDefaults(); + } + void setDefaults(); +}; + +/** + * Common transformation parameters + */ +class CommonTransformParams { + + public: + bool autofill; +}; + +/** + * Parameters of the rotation + */ +class RotateParams { + + public: + double degree; +}; + +/** + * Parameters of the distortion correction + */ +class DistortionParams { + + public: + double amount; +}; + +// Lens profile correction parameters +class LensProfParams { + +public: + Glib::ustring lcpFile; + bool useDist, useVign, useCA; + + LensProfParams() { + setDefaults(); + } + void setDefaults(); +}; + +/** + * Parameters of the perspective correction + */ +class PerspectiveParams { + + public: + double horizontal; + double vertical; +}; + +/** + * Parameters of the gradient filter + */ +class GradientParams { + + public: + bool enabled; + double degree; + int feather; + double strength; + int centerX; + int centerY; +}; + +/** + * Parameters of the post-crop vignette filter + */ +class PCVignetteParams { + + public: + bool enabled; + double strength; + int feather; + int roundness; +}; + +/** + * Parameters of the vignetting correction + */ +class VignettingParams { + + public: + int amount; + int radius; + int strength; + int centerX; + int centerY; +}; + +/** + * Parameters of the color mixer + */ +class ChannelMixerParams { + + public: + int red[3]; + int green[3]; + int blue[3]; +}; + +class BlackWhiteParams { + + public: + enum eTCModeId { + TC_MODE_STD_BW, // Standard modes, the curve is applied on all component individually + TC_MODE_WEIGHTEDSTD_BW, // Weighted standard mode + TC_MODE_FILMLIKE_BW, // Film-like mode, as defined in Adobe's reference code + TC_MODE_SATANDVALBLENDING_BW // Modify the Saturation and Value channel + }; + + std::vector beforeCurve; + eTCModeId beforeCurveMode; + std::vector afterCurve; + eTCModeId afterCurveMode; + Glib::ustring algo; + + std::vector luminanceCurve; + bool autoc; + bool enabledcc; + bool enabled; + Glib::ustring filter; + Glib::ustring setting; + Glib::ustring method; + int mixerRed; + int mixerOrange; + int mixerYellow; + int mixerGreen; + int mixerCyan; + int mixerBlue; + int mixerMagenta; + int mixerPurple; + int gammaRed; + int gammaGreen; + int gammaBlue; +}; + +/** + * Parameters of the c/a correction + */ +class CACorrParams { + + public: + double red; + double blue; +}; + +/** + * Parameters of the highlight recovery + */ + /* +class HRecParams { + + public: + bool enabled; + Glib::ustring method; +}; +*/ +/** + * Parameters of the resizing + */ +class ResizeParams { + + public: + bool enabled; + double scale; + Glib::ustring appliesTo; + Glib::ustring method; + int dataspec; + int width; + int height; +}; + +/** + * Parameters of the color spaces used during the processing + */ +class ColorManagementParams { + + public: + Glib::ustring input; + bool toneCurve; + bool applyLookTable; + bool applyBaselineExposureOffset; + bool applyHueSatMap; + bool blendCMSMatrix; // setting no longer used + int dcpIlluminant; + Glib::ustring working; + Glib::ustring output; + static const Glib::ustring NoICMString; + + Glib::ustring gamma; + double gampos; + double slpos; + bool freegamma; + + ColorManagementParams() { + setDefaults(); + } + void setDefaults(); +}; + +/** + * Typedef for representing a key/value for the exif metadata information + */ +typedef std::map ExifPairs; + +/** + * The IPTC key/value pairs + */ +typedef std::map > IPTCPairs; + + +class WaveletParams { + + public: + std::vector ccwcurve; + std::vector opacityCurveRG; + std::vector opacityCurveBY; + std::vector opacityCurveW; + std::vector opacityCurveWL; + std::vector hhcurve; + std::vector Chcurve; + std::vector wavclCurve; + bool enabled; + bool median; + bool medianlev; + bool linkedg; + bool cbenab; + double greenlow; + double bluelow; + double greenmed; + double bluemed; + double greenhigh; + double bluehigh; + + bool lipst; + // bool edgreinf; + bool avoid; + bool tmr; + int strength; + int balance; + int iter; + int c[9]; + int ch[9]; + + Glib::ustring Lmethod; + Glib::ustring CLmethod; + Glib::ustring Backmethod; + Glib::ustring Tilesmethod; + Glib::ustring daubcoeffmethod; + Glib::ustring CHmethod; + Glib::ustring Medgreinf; + Glib::ustring CHSLmethod; + Glib::ustring EDmethod; + Glib::ustring BAmethod; + Glib::ustring TMmethod; + Glib::ustring Dirmethod; + Glib::ustring HSmethod; + int rescon; + int resconH; + int reschro; + double tmrs; + double gamma; + int sup; + double sky; + int thres; + int chroma; + int chro; + int threshold; + int threshold2; + int edgedetect; + int edgedetectthr; + int edgedetectthr2; + int contrast; + int edgrad; + int edgval; + int edgthresh; + int thr; + int thrH; + double skinprotect; + Threshold hueskin; + Threshold hueskin2; + Threshold hllev; + Threshold bllev; + Threshold pastlev; + Threshold satlev; + Threshold edgcont; + Threshold level0noise; + Threshold level1noise; + Threshold level2noise; + + + WaveletParams (); + void setDefaults(); + void getCurves(WavCurve &cCurve,WavOpacityCurveRG &opacityCurveLUTRG , WavOpacityCurveBY &opacityCurveLUTBY, WavOpacityCurveW &opacityCurveLUTW, WavOpacityCurveWL &opacityCurveLUTWL) const; + static void getDefaultCCWCurve(std::vector &curve); + static void getDefaultOpacityCurveRG(std::vector &curve); + static void getDefaultOpacityCurveBY(std::vector &curve); + static void getDefaultOpacityCurveW(std::vector &curve); + static void getDefaultOpacityCurveWL(std::vector &curve); + +}; + + +/** +* Directional pyramid equalizer params +*/ +class DirPyrEqualizerParams { + + public: + bool enabled; + bool gamutlab; + double mult[6]; + double threshold; + double skinprotect; + Threshold hueskin; + //Glib::ustring algo; + + DirPyrEqualizerParams() : hueskin(20, 80, 2000, 1200, false) {}; +}; + +/** + * HSV equalizer params + */ +class HSVEqualizerParams { + + public: + std::vector hcurve; + std::vector scurve; + std::vector vcurve; +}; + + +/** + * Film simualtion params + */ +struct FilmSimulationParams { + bool enabled; + Glib::ustring clutFilename; + int strength; + + FilmSimulationParams() { + setDefaults(); + } + + void setDefaults() { + enabled = false; + clutFilename = Glib::ustring(); + strength = 100; + } +}; + + +/** + * Parameters for RAW demosaicing, common to all sensor type + */ +class RAWParams { + + public: + /** + * Parameters for RAW demosaicing specific to Bayer sensors + */ + class BayerSensor { + public: + //enum eMethod{ eahd,hphd,vng4,dcb,amaze,ahd,IGV_noise,fast, + //numMethods }; // This MUST be the last enum + enum eMethod{ amaze, igv, lmmse, eahd, hphd, vng4, dcb, ahd, fast, mono, none, + numMethods }; // This MUST be the last enum + static const char *methodstring[numMethods]; + + Glib::ustring method; + int ccSteps; + double black0; + double black1; + double black2; + double black3; + bool twogreen; + int linenoise; + int greenthresh; + int dcb_iterations; + int lmmse_iterations; + bool dcb_enhance; + //bool all_enhance; + }; + + /** + * Parameters for RAW demosaicing specific to X-Trans sensors + */ + class XTransSensor { + public: + enum eMethod{ threePass, onePass, fast, mono, none, + numMethods }; // This MUST be the last enum + static const char *methodstring[numMethods]; + + Glib::ustring method; + int ccSteps; + double blackred; + double blackgreen; + double blackblue; + }; + + BayerSensor bayersensor; ///< RAW parameters for Bayer sensors + XTransSensor xtranssensor; ///< RAW parameters for X-Trans sensors + + enum eFlatFileBlurType{ /*parametric,*/area_ff,v_ff,h_ff,vh_ff, + numFlatFileBlurTypes }; // This MUST be the last enum + + static const char *ff_BlurTypestring[numFlatFileBlurTypes]; + + Glib::ustring dark_frame; + bool df_autoselect; + + Glib::ustring ff_file; + bool ff_AutoSelect; + int ff_BlurRadius; + Glib::ustring ff_BlurType; + bool ff_AutoClipControl; + int ff_clipControl; + + bool ca_autocorrect; + double cared; + double cablue; + + // exposure before interpolation + double expos; + double preser; + + bool hotPixelFilter; + bool deadPixelFilter; + int hotdeadpix_thresh; + + RAWParams() { + setDefaults(); + } + void setDefaults(); +}; + +/** + * This class holds all the processing parameters applied on the images + */ +class ProcParams { + + public: + ToneCurveParams toneCurve; ///< Tone curve parameters + LCurveParams labCurve; ///< CIELAB luminance curve parameters + RGBCurvesParams rgbCurves; ///< RGB curves parameters + ColorToningParams colorToning; ///< Color Toning parameters + SharpeningParams sharpening; ///< Sharpening parameters + SharpeningParams prsharpening; ///< Sharpening parameters for post resize sharpening + SharpenEdgeParams sharpenEdge; ///< Sharpen edge parameters + SharpenMicroParams sharpenMicro; ///< Sharpen microcontrast parameters + VibranceParams vibrance; ///< Vibrance parameters + //ColorBoostParams colorBoost; ///< Color boost parameters + WBParams wb; ///< White balance parameters + ColorAppearanceParams colorappearance; + //ColorShiftParams colorShift; ///< Color shift parameters + //LumaDenoiseParams lumaDenoise; ///< Luminance denoising parameters + //ColorDenoiseParams colorDenoise; ///< Color denoising parameters + DefringeParams defringe; ///< Defringing parameters + ImpulseDenoiseParams impulseDenoise; ///< Impulse denoising parameters + DirPyrDenoiseParams dirpyrDenoise; ///< Directional Pyramid denoising parameters + EPDParams epd; ///< Edge Preserving Decomposition parameters + SHParams sh; ///< Shadow/highlight enhancement parameters + CropParams crop; ///< Crop parameters + CoarseTransformParams coarse; ///< Coarse transformation (90, 180, 270 deg rotation, h/v flipping) parameters + CommonTransformParams commonTrans; ///< Common transformation parameters (autofill) + RotateParams rotate; ///< Rotation parameters + DistortionParams distortion; ///< Lens distortion correction parameters + LensProfParams lensProf; ///< Lens correction profile parameters + PerspectiveParams perspective; ///< Perspective correction parameters + GradientParams gradient; ///< Gradient filter parameters + PCVignetteParams pcvignette; ///< Post-crop vignette filter parameters + CACorrParams cacorrection; ///< Lens c/a correction parameters + VignettingParams vignetting; ///< Lens vignetting correction parameters + ChannelMixerParams chmixer; ///< Channel mixer parameters + BlackWhiteParams blackwhite; ///< Black & White parameters + ResizeParams resize; ///< Resize parameters + ColorManagementParams icm; ///< profiles/color spaces used during the image processing + RAWParams raw; ///< RAW parameters before demosaicing + WaveletParams wavelet; ///< wavelet wavelet parameters + DirPyrEqualizerParams dirpyrequalizer; ///< directional pyramid wavelet parameters + HSVEqualizerParams hsvequalizer; ///< hsv wavelet parameters + FilmSimulationParams filmSimulation; ///< film simulation parameters + char rank; ///< Custom image quality ranking + char colorlabel; ///< Custom color label + bool inTrash; ///< Marks deleted image + Glib::ustring appVersion; ///< Version of the application that generated the parameters + int ppVersion; ///< Version of the PP file from which the parameters have been read + + ExifPairs exif; ///< List of modifications appplied on the exif tags of the input image + IPTCPairs iptc; ///< The IPTC tags and values to be saved to the output image + + /** + * The constructor only sets the hand-wired defaults. + */ + ProcParams (); + /** + * Sets the hand-wired defaults parameters. + */ + void setDefaults (); + /** + * Saves the parameters to possibly two files. This is a performance improvement if a function has to + * save the same file in two different location, i.e. the cache and the image's directory + * @param fname the name of the first file (can be an empty string) + * @param fname2 the name of the second file (can be an empty string) (optional) + * @param fnameAbsolute set to false if embedded filenames (if any, darkframe/flatfield) should be stored as relative + * filenames if they are inside the same directory or in a sub-directory to fname's directory. + * @param pedited pointer to a ParamsEdited object (optional) to store which values has to be saved + * @return Error code (=0 if all supplied filenames where created correctly) + */ + int save (Glib::ustring fname, Glib::ustring fname2 = "", bool fnameAbsolute = true, ParamsEdited* pedited=NULL); + /** + * Loads the parameters from a file. + * @param fname the name of the file + * @params pedited pointer to a ParamsEdited object (optional) to store which values has been loaded + * @return Error code (=0 if no error) + */ + int load (Glib::ustring fname, ParamsEdited* pedited=NULL); + + /** Creates a new instance of ProcParams. + * @return a pointer to the new ProcParams instance. */ + static ProcParams* create (); + + /** Destroys an instance of ProcParams. + * @param pp a pointer to the ProcParams instance to destroy. */ + static void destroy (ProcParams* pp); + + static void init (); + static void cleanup (); + + bool operator== (const ProcParams& other); + bool operator!= (const ProcParams& other); + + private: + /** Write the ProcParams's text in the file of the given name. + * @param fname the name of the file + * @param content the text to write + * @return Error code (=0 if no error) + * */ + int write (Glib::ustring &fname, Glib::ustring &content) const; + +}; + +/** + * This class associate a ProcParams object and a ParamEdited object through a pointer + * to instance of each type in order to handle partial pp3 file loading (and later maybe + * saving too) + * + * PartialProfile is not responsible of ProcParams and ParamsEdited object creation + * and hence is not responsible of their destructions. The function that instanciate + * PartialProfile object has to handle all this itself. + */ +class PartialProfile { + public: + rtengine::procparams::ProcParams* pparams; + ParamsEdited* pedited; + PartialProfile& operator=(PartialProfile& rhs) { pparams=rhs.pparams; pedited=rhs.pedited; return *this; }; + + PartialProfile (bool createInstance=false, bool paramsEditedValue=false); + PartialProfile (ProcParams* pp, ParamsEdited* pe=NULL, bool fullCopy=false); + PartialProfile (const ProcParams* pp, const ParamsEdited* pe=NULL); + void deleteInstance (); + void clearGeneral (); + int load (Glib::ustring fName); + void set (bool v); + const void applyTo (ProcParams *destParams) const ; +}; + +/** + * This class automatically create the pparams and pedited instance in the constructor, + * and automatically delete them in the destructor. This class has been mostly created + * to be used with vectors, which use the default constructor/destructor + */ +class AutoPartialProfile : public PartialProfile { + public: + AutoPartialProfile() : PartialProfile(true) {} + ~AutoPartialProfile() { deleteInstance(); } +}; + +} +} +#endif diff --git a/rtengine/rawimage.cc b/rtengine/rawimage.cc new file mode 100755 index 000000000..563a0c980 --- /dev/null +++ b/rtengine/rawimage.cc @@ -0,0 +1,777 @@ +/* + * This file is part of RawTherapee. + * + * Created on: 20/nov/2010 + */ + +#include "rawimage.h" +#include "settings.h" +#include "camconst.h" +#include "utils.h" +#ifdef WIN32 +#include +#else +#include +#endif +#include "safegtk.h" + +namespace rtengine{ + +extern const Settings* settings; + +RawImage::RawImage( const Glib::ustring name ) +:data(NULL) +,prefilters(0) +,filename(name) +,profile_data(NULL) +,allocation(NULL) +{ + memset(maximum_c4, 0, sizeof(maximum_c4)); + RT_matrix_from_constant = 0; + RT_blacklevel_from_constant = 0; + RT_whitelevel_from_constant = 0; +} + +RawImage::~RawImage() +{ + if(ifp) + fclose(ifp); + if( image ) + free(image); + if(allocation){ delete [] allocation; allocation=NULL;} + if(float_raw_image) { delete [] float_raw_image; float_raw_image = NULL; } + if(data){ delete [] data; data=NULL;} + if(profile_data){ delete [] profile_data; profile_data=NULL;} +} + +eSensorType RawImage::getSensorType() { + if (isBayer()) + return ST_BAYER; + else if (isXtrans()) + return ST_FUJI_XTRANS; + else if (isFoveon()) + return ST_FOVEON; + + return ST_NONE; +} + +/* Similar to dcraw scale_colors for coeff. calculation, but without actual pixels scaling. + * need pixels in data[][] available + */ +void RawImage::get_colorsCoeff( float *pre_mul_, float *scale_mul_, float *cblack_, bool forceAutoWB) { + unsigned row, col, x, y, c, sum[8]; + unsigned W = this->get_width(); + unsigned H = this->get_height(); + float val; + double dsum[8], dmin, dmax; + + if ((this->get_cblack(4)+1)/2 == 1 && (this->get_cblack(5)+1)/2 == 1) { + for (int c = 0; c < 4; c++){ + cblack_[FC(c/2,c%2)] = this->get_cblack(6 + c/2 % this->get_cblack(4) * this->get_cblack(5) + c%2 % this->get_cblack(5)); + pre_mul_[c] = this->get_pre_mul(c); + } + } else if(isXtrans()) { + // for xtrans files dcraw stores black levels in cblack[6] .. cblack[41], but all are equal, so we just use cblack[6] + for (int c = 0; c < 4; c++){ + cblack_[c] = (float) this->get_cblack(6); + pre_mul_[c] = this->get_pre_mul(c); + } + } else { + for (int c = 0; c < 4; c++){ + cblack_[c] = (float) this->get_cblack(c); + pre_mul_[c] = this->get_pre_mul(c); + } + } + if ( this->get_cam_mul(0) == -1 || forceAutoWB) { + memset(dsum, 0, sizeof dsum); + if (this->isBayer()) { + // calculate number of pixels per color + dsum[FC(0,0)+4] += (int)(((W+1)/2) * ((H+1)/2)); + dsum[FC(0,1)+4] += (int)(((W/2) * ((H+1)/2))); + dsum[FC(1,0)+4] += (int)(((W+1)/2) * (H/2)); + dsum[FC(1,1)+4] += (int)((W/2) * (H/2)); + +#pragma omp parallel private(val,row,col,x,y) +{ + double dsumthr[8]; + memset(dsumthr, 0, sizeof dsumthr); + float sum[4]; + // make local copies of the black and white values to avoid calculations and conversions + float cblackfloat[4]; + float whitefloat[4]; + for (int c = 0; c < 4; c++) { + cblackfloat[c] = cblack_[c]; + whitefloat[c] = this->get_white(c) - 25; + } + float *tempdata = data[0]; +#pragma omp for nowait + for (row = 0; row < H; row += 8) { + int ymax = row + 8 < H ? row + 8 : H; + for (col = 0; col < W ; col += 8) { + int xmax = col + 8 < W ? col + 8 : W; + memset(sum, 0, sizeof sum); + for (y = row; y < ymax; y++) + for (x = col; x < xmax; x++) { + int c = FC(y, x); + val = tempdata[y*W+x]; + if (val > whitefloat[c]) { // calculate number of pixels to be substracted from sum and skip the block + dsumthr[FC(row,col)+4] += (int)(((xmax - col + 1)/2) * ((ymax - row + 1)/2)); + dsumthr[FC(row,col+1)+4] += (int)(((xmax - col)/2) * ((ymax - row + 1)/2)); + dsumthr[FC(row+1,col)+4] += (int)(((xmax - col + 1)/2) * ((ymax - row)/2)); + dsumthr[FC(row+1,col+1)+4] += (int)(((xmax - col)/2) * ((ymax - row)/2)); + goto skip_block2; + } + if (val < cblackfloat[c]) + val = cblackfloat[c]; + sum[c] += val; + } + for (int c = 0; c < 4; c++) + dsumthr[c] += sum[c]; +skip_block2: ; + } + } +#pragma omp critical +{ + for (int c = 0; c < 4; c++) + dsum[c] += dsumthr[c]; + for (int c = 4; c < 8; c++) + dsum[c] -= dsumthr[c]; + +} +} + for(int c=0;c<4;c++) + dsum[c] -= cblack_[c] * dsum[c+4]; + + } else if(isXtrans()) { +#pragma omp parallel +{ + double dsumthr[8]; + memset(dsumthr, 0, sizeof dsumthr); + float sum[8]; + // make local copies of the black and white values to avoid calculations and conversions + float whitefloat[4]; + for (int c = 0; c < 4; c++) { + whitefloat[c] = this->get_white(c) - 25; + } + +#pragma omp for nowait + for (int row = 0; row < H; row += 8) + for (int col = 0; col < W ; col += 8) { + memset(sum, 0, sizeof sum); + for (int y = row; y < row + 8 && y < H; y++) + for (int x = col; x < col + 8 && x < W; x++) { + int c = XTRANSFC(y, x); + float val = data[y][x]; + if (val > whitefloat[c]) + goto skip_block3; + if ((val -= cblack_[c]) < 0) + val = 0; + sum[c] += val; + sum[c + 4]++; + } + for (int c = 0; c < 8; c++) + dsumthr[c] += sum[c]; +skip_block3: ; + } +#pragma omp critical +{ + for (int c = 0; c < 8; c++) + dsum[c] += dsumthr[c]; + +} +} + } else if (colors == 1) { + for (int c = 0; c < 4; c++) + pre_mul_[c] = 1; + } else { + for (row = 0; row < H; row += 8) + for (col = 0; col < W ; col += 8) { + memset(sum, 0, sizeof sum); + for (y = row; y < row + 8 && y < H; y++) + for (x = col; x < col + 8 && x < W; x++) + for (int c = 0; c < 3; c++) { + if (this->isBayer()) { + c = FC(y, x); + val = data[y][x]; + } else + val = data[y][3*x+c]; + if (val > this->get_white(c) - 25) + goto skip_block; + if ((val -= cblack_[c]) < 0) + val = 0; + sum[c] += val; + sum[c + 4]++; + if ( this->isBayer()) + break; + } + for (c = 0; c < 8; c++) + dsum[c] += sum[c]; +skip_block: ; + } + } + for (int c = 0; c < 4; c++) + if (dsum[c]) + pre_mul_[c] = dsum[c + 4] / dsum[c]; + }else{ + memset(sum, 0, sizeof sum); + for (row = 0; row < 8; row++) + for (col = 0; col < 8; col++) { + int c = FC(row, col); + if ((val = white[row][col] - cblack_[c]) > 0) + sum[c] += val; + sum[c + 4]++; + } + if (sum[0] && sum[1] && sum[2] && sum[3]) + for (int c = 0; c < 4; c++) + pre_mul_[c] = (float) sum[c + 4] / sum[c]; + else if (this->get_cam_mul(0) && this->get_cam_mul(2)){ + pre_mul_[0] = this->get_cam_mul(0); + pre_mul_[1] = this->get_cam_mul(1); + pre_mul_[2] = this->get_cam_mul(2); + pre_mul_[3] = this->get_cam_mul(3); + }else + fprintf(stderr, "Cannot use camera white balance.\n"); + } + if (pre_mul_[3] == 0) + pre_mul_[3] = this->get_colors() < 4 ? pre_mul_[1] : 1; + else if (this->get_colors() < 4) + pre_mul_[3] = pre_mul_[1] = (pre_mul_[3] + pre_mul_[1]) / 2; + + if (colors == 1) + for (c = 1; c < 4; c++) + cblack_[c] = cblack_[0]; + + bool multiple_whites = false; + int largest_white = this->get_white(0); + for (c = 1; c < 4; c++) { + if (this->get_white(c) != this->get_white(0)) { + multiple_whites = true; + if (this->get_white(c) > largest_white) { + largest_white = this->get_white(c); + } + } + } + if (multiple_whites) { + // dcraw's pre_mul/cam_mul expects a single white, so if we have provided multiple whites we need + // to adapt scaling to avoid color shifts. + for (c = 0; c < 4; c++) { + // we don't really need to do the largest_white division but do so just to keep pre_mul in similar + // range as before adjustment so they don't look strangely large if someone would print them + pre_mul_[c] *= (float)this->get_white(c) / largest_white; + } + } + + for (dmin = DBL_MAX, dmax = c = 0; c < 4; c++) { + if (dmin > pre_mul_[c]) + dmin = pre_mul_[c]; + if (dmax < pre_mul_[c]) + dmax = pre_mul_[c]; + } + + for (c = 0; c < 4; c++) { + int sat = this->get_white(c) - cblack_[c]; + scale_mul_[c] = (pre_mul_[c] /= dmax) * 65535.0 / sat; + } + if (settings->verbose) { + float asn[4] = { 1/cam_mul[0], 1/cam_mul[1], 1/cam_mul[2], 1/cam_mul[3] }; + for (dmax = c = 0; c < 4; c++) { + if (cam_mul[c] == 0) asn[c] = 0; + if (asn[c] > dmax) dmax = asn[c]; + } + for (c = 0; c < 4; c++) asn[c] /= dmax; + printf("cam_mul:[%f %f %f %f], AsShotNeutral:[%f %f %f %f]\n", + cam_mul[0], cam_mul[1], cam_mul[2], cam_mul[3], asn[0], asn[1], asn[2], asn[3]); + printf("pre_mul:[%f %f %f %f], scale_mul:[%f %f %f %f], cblack:[%f %f %f %f]\n", + pre_mul_[0], pre_mul_[1], pre_mul_[2], pre_mul_[3], + scale_mul_[0], scale_mul_[1], scale_mul_[2], scale_mul_[3], + cblack_[0], cblack_[1], cblack_[2], cblack_[3]); + printf("rgb_cam:[ [ %f %f %f], [%f %f %f], [%f %f %f] ]%s\n", + rgb_cam[0][0], rgb_cam[1][0], rgb_cam[2][0], + rgb_cam[0][1], rgb_cam[1][1], rgb_cam[2][1], + rgb_cam[0][2], rgb_cam[1][2], rgb_cam[2][2], + (!this->isBayer()) ? " (not bayer)" : ""); + + } +} + +int RawImage::loadRaw (bool loadData, bool closeFile, ProgressListener *plistener, double progressRange) +{ + ifname = filename.c_str(); + image = NULL; + verbose = settings->verbose; + oprof = NULL; + + ifp = gfopen (ifname); // Maps to either file map or direct fopen + if (!ifp) return 3; + imfile_set_plistener(ifp, plistener, 0.9 * progressRange); + + thumb_length = 0; + thumb_offset = 0; + thumb_load_raw = 0; + use_camera_wb = 0; + highlight = 1; + half_size = 0; + raw_image = 0; + + //***************** Read ALL raw file info + identify (); + if (!is_raw) { + fclose(ifp); + ifp=NULL; + if (plistener) { + plistener->setProgress(1.0 * progressRange); + } + return 2; + } + + if (flip==5) + this->rotate_deg = 270; + else if (flip==3) + this->rotate_deg = 180; + else if (flip==6) + this->rotate_deg = 90; + else if (flip % 90 == 0 && flip < 360) + this->rotate_deg = flip; + else + this->rotate_deg = 0; + + if( loadData ){ + + use_camera_wb = 1; + shrink = 0; + if (settings->verbose) printf ("Loading %s %s image from %s...\n", make, model, filename.c_str()); + iheight = height; + iwidth = width; + + if (filters || colors == 1) { + raw_image = (ushort *) calloc ((raw_height+7)*raw_width, 2); + merror (raw_image, "main()"); + } + + // dcraw needs this global variable to hold pixel data + image = (dcrawImage_t)calloc (height*width*sizeof *image + meta_length, 1); + meta_data = (char *) (image + height*width); + if(!image) + return 200; +/* Issue 2467 + if (setjmp (failure)) { + if (image) { free (image); image=NULL; } + if (raw_image) { free(raw_image); raw_image=NULL; } + fclose(ifp); ifp=NULL; + return 100; + } +*/ + // Load raw pixels data + fseek (ifp, data_offset, SEEK_SET); + (this->*load_raw)(); + if (plistener) { + plistener->setProgress(0.9 * progressRange); + } + + CameraConstantsStore* ccs = CameraConstantsStore::getInstance(); + CameraConst *cc = ccs->get(make, model); + + if (raw_image) { + if (cc && cc->has_rawCrop()) { + int lm, tm, w, h; + cc->get_rawCrop(lm, tm, w, h); + if(((int)top_margin - tm) & 1) // we have an odd border difference + filters = (filters << 4) | (filters >> 28); // left rotate filters by 4 bits + left_margin = lm; + top_margin = tm; + if (w < 0) { + iwidth += w; + iwidth -= left_margin; + width += w; + width -= left_margin; + } else if (w > 0) { + iwidth = width = min((int)width,w); + } + if (h < 0) { + iheight += h; + iheight -= top_margin; + height += h; + height -= top_margin; + } else if (h > 0) { + iheight = height = min((int)height,h); + } + } + if (cc && cc->has_rawMask(0)) { + for (int i = 0; i < 8 && cc->has_rawMask(i); i++) { + cc->get_rawMask(i, mask[i][0], mask[i][1], mask[i][2], mask[i][3]); + } + } + crop_masked_pixels(); + free (raw_image); + raw_image=NULL; + } else { + if (cc && cc->has_rawCrop()) { // foveon images + int lm, tm, w, h; + cc->get_rawCrop(lm, tm, w, h); + left_margin = lm; + top_margin = tm; + if (w < 0) { + width += w; + width -= left_margin; + } else if (w > 0) { + width = min((int)width,w); + } + if (h < 0) { + height += h; + height -= top_margin; + } else if (h > 0) { + height = min((int)height,h); + } + } + } + + // Load embedded profile + if (profile_length) { + profile_data = new char[profile_length]; + fseek ( ifp, profile_offset, SEEK_SET); + fread ( profile_data, 1, profile_length, ifp); + } + + /* + Setting the black level, there are three sources: + dcraw single value 'black' or multi-value 'cblack', can be calculated or come + from a hard-coded table or come from a stored value in the raw file, and + finally there's 'black_c4' which are table values provided by RT camera constants. + Any of these may or may not be set. + + We reduce these sources to one four channel black level, and do this by picking + the highest found. + */ + int black_c4[4] = { -1, -1, -1, -1 }; + + bool white_from_cc = false; + bool black_from_cc = false; + if (cc) { + for (int i = 0; i < 4; i++) { + if (RT_blacklevel_from_constant) { + black_c4[i] = cblack[i] + cc->get_BlackLevel(i, iso_speed); + } + // load 4 channel white level here, will be used if available + if (RT_whitelevel_from_constant) { + maximum_c4[i] = cc->get_WhiteLevel(i, iso_speed, aperture); + if(tiff_bps > 0 && maximum_c4[i] > 0 && !isFoveon()) { + unsigned compare = ((uint64_t)1 << tiff_bps) - 1; // use uint64_t to avoid overflow if tiff_bps == 32 + while(maximum_c4[i] > compare) + maximum_c4[i] >>= 1; + } + } + } + } + if (black_c4[0] == -1) { + if(isXtrans()) + for (int c=0; c < 4; c++) black_c4[c] = cblack[6]; + else + // RT constants not set, bring in the DCRAW single channel black constant + for (int c=0; c < 4; c++) black_c4[c] = black + cblack[c]; + } else { + black_from_cc = true; + } + if (maximum_c4[0] > 0) { + white_from_cc = true; + } + for (int c=0; c < 4; c++) { + if (cblack[c] < black_c4[c]) { + cblack[c] = black_c4[c]; + } + } + if (settings->verbose) { + if (cc) { + printf("constants exists for \"%s %s\" in camconst.json\n", make, model); + } else { + printf("no constants in camconst.json exists for \"%s %s\" (relying only on dcraw defaults)\n", make, model); + } + printf("black levels: R:%d G1:%d B:%d G2:%d (%s)\n", get_cblack(0), get_cblack(1), get_cblack(2), get_cblack(3), + black_from_cc ? "provided by camconst.json" : "provided by dcraw"); + printf("white levels: R:%d G1:%d B:%d G2:%d (%s)\n", get_white(0), get_white(1), get_white(2), get_white(3), + white_from_cc ? "provided by camconst.json" : "provided by dcraw"); + printf("raw crop: %d %d %d %d (provided by %s)\n", left_margin, top_margin, iwidth, iheight, (cc && cc->has_rawCrop()) ? "camconst.json" : "dcraw"); + printf("color matrix provided by %s\n", (cc && cc->has_dcrawMatrix()) ? "camconst.json" : "dcraw"); + } + } + + if ( closeFile ) { + fclose(ifp); ifp=NULL; + } + if (plistener) { + plistener->setProgress(1.0 * progressRange); + } + + return 0; +} + +float** RawImage::compress_image() +{ + if( !image ) + return NULL; + if (isBayer() || isXtrans()) { + if (!allocation) { + allocation = new float[height * width]; + data = new float*[height]; + for (int i = 0; i < height; i++) + data[i] = allocation + i * width; + } + } else if (colors == 1) { + // Monochrome + if (!allocation) { + allocation = new float[height * width]; + data = new float*[height]; + for (int i = 0; i < height; i++) + data[i] = allocation + i * width; + } + } else { + if (!allocation) { + allocation = new float[3 * height * width]; + data = new float*[height]; + for (int i = 0; i < height; i++) + data[i] = allocation + 3 * i * width; + } + } + + // copy pixel raw data: the compressed format earns space + if( float_raw_image ) { + #pragma omp parallel for + for (int row = 0; row < height; row++) + for (int col = 0; col < width; col++) + this->data[row][col] = float_raw_image[(row + top_margin) * raw_width + col + left_margin]; + delete [] float_raw_image; + float_raw_image = NULL; + } else if (filters != 0 && !isXtrans()) { + #pragma omp parallel for + for (int row = 0; row < height; row++) + for (int col = 0; col < width; col++) + this->data[row][col] = image[row * width + col][FC(row, col)]; + } else if (isXtrans()) { + #pragma omp parallel for + for (int row = 0; row < height; row++) + for (int col = 0; col < width; col++) + this->data[row][col] = image[row * width + col][XTRANSFC(row, col)]; + } else if (colors == 1) { + #pragma omp parallel for + for (int row = 0; row < height; row++) + for (int col = 0; col < width; col++) + this->data[row][col] = image[row * width + col][0]; + } else { + #pragma omp parallel for + for (int row = 0; row < height; row++) + for (int col = 0; col < width; col++) { + this->data[row][3 * col + 0] = image[(row+top_margin) * iwidth + col+left_margin][0]; + this->data[row][3 * col + 1] = image[(row+top_margin) * iwidth + col+left_margin][1]; + this->data[row][3 * col + 2] = image[(row+top_margin) * iwidth + col+left_margin][2]; + } + } + free(image); // we don't need this anymore + image=NULL; + return data; +} + +bool +RawImage::is_supportedThumb() const +{ + return ( (thumb_width * thumb_height) > 0 && + ( write_thumb == &rtengine::RawImage::jpeg_thumb || + write_thumb == &rtengine::RawImage::ppm_thumb) && + !thumb_load_raw ); +} + +void RawImage::getXtransMatrix( char XtransMatrix[6][6]) +{ + for(int row=0;row<6;row++) + for(int col=0;col<6;col++) + XtransMatrix[row][col] = xtrans[row][col]; +} + +void RawImage::getRgbCam (float rgbcam[3][4]) +{ + for(int row=0;row<3;row++) + for(int col=0;col<4;col++) + rgbcam[row][col] = rgb_cam[row][col]; + +} + +bool +RawImage::get_thumbSwap() const +{ + return ((order == 0x4949) == (ntohs(0x1234) == 0x1234)) ? true : false; +} + +} //namespace rtengine + +bool +DCraw::dcraw_coeff_overrides(const char make[], const char model[], const int iso_speed, short trans[12], int *black_level, int *white_level) +{ + static const int dcraw_arw2_scaling_bugfix_shift = 2; + static const struct { + const char *prefix; + int black_level, white_level; // set to -1 for no change + short trans[12]; // set first value to 0 for no change + } table[] = { + + { "Canon EOS 5D Mark III", -1, 0x3a98, /* RT */ + { 6722,-635,-963,-4287,12460,2028,-908,2162,5668 } }, + { "Canon EOS 5D", -1, 0xe6c, /* RT */ + { 6319,-793,-614,-5809,13342,2738,-1132,1559,7971 } }, + { "Canon EOS 6D", -1, 0x3c82, + { 7034,-804,-1014,-4420,12564,2058,-851,1994,5758 } }, + { "Canon EOS 7D", -1, 0x3510, /* RT - Colin Walker */ + { 5962,-171,-732,-4189,12307,2099,-911,1981,6304 } }, + { "Canon EOS 20D", -1, 0xfff, /* RT */ + { 7590,-1646,-673,-4697,12411,2568,-627,1118,7295 } }, + { "Canon EOS 40D", -1, 0x3f60, /* RT */ + { 6070,-531,-883,-5763,13647,2315,-1533,2582,6801 } }, + { "Canon EOS 60D", -1, 0x2ff7, /* RT - Colin Walker */ + { 5678,-179,-718,-4389,12381,2243,-869,1819,6380 } }, + { "Canon EOS 450D", -1, 0x390d, /* RT */ + { 6246,-1272,-523,-5075,12357,3075,-1035,1825,7333 } }, + { "Canon EOS 550D", -1, 0x3dd7, /* RT - Lebedev*/ + { 6519,-772,-703,-4994,12737,2519,-1387,2492,6175 } }, + { "Canon EOS-1D Mark III", 0, 0x3bb0, /* RT */ + { 7406,-1592,-646,-4856,12457,2698,-432,726,7921 } }, + { "Canon PowerShot G10", -1, -1, /* RT */ + { 12535,-5030,-796,-2711,10134,3006,-413,1605,5264 } }, + { "Canon PowerShot G12", -1, -1, /* RT */ + { 12222,-4097,-1380,-2876,11016,2130,-888,1630,4434 } }, + + + { "Fujifilm X100", -1, -1, /* RT - Colin Walker */ + { 10841,-3288,-807,-4652,12552,2344,-642,1355,7206 } }, + + + { "Nikon D200", -1, 0xfbc, /* RT */ + { 8498,-2633,-295,-5423,12869,2860,-777,1077,8124 } }, + { "Nikon D3000", -1, -1, /* RT */ + { 9211,-2521,-104,-6487,14280,2394,-754,1122,8033 } }, + { "Nikon D3100", -1, -1, /* RT */ + { 7729,-2212,-481,-5709,13148,2858,-1295,1908,8936 } }, + { "Nikon D3S", -1, -1, /* RT */ + { 8792,-2663,-344,-5221,12764,2752,-1491,2165,8121 } }, + { "Nikon D5200", -1, -1, // color matrix copied from D5200 DNG D65 matrix + { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } }, + { "Nikon D7000", -1, -1, /* RT - Tanveer(tsk1979) */ + { 7530,-1942,-255,-4318,11390,3362,-926,1694,7649 } }, + { "Nikon D7100", -1, -1, // color matrix and WP copied from D7100 DNG D65 matrix + { 8322,-3112,-1047,-6367,14342,2179,-988,1638,6394 } }, + { "Nikon D700", -1, -1, /* RT */ + { 8364,-2503,-352,-6307,14026,2492,-1134,1512,8156 } }, + { "Nikon COOLPIX A", -1, 0x3e00, // color matrix and WP copied from "COOLPIX A" DNG D65 matrix + { 8198,-2239,-724,-4871,12389,2798,-1043,205,7181 } }, + + + { "Olympus E-30", -1, 0xfbc, /* RT - Colin Walker */ + { 8510,-2355,-693,-4819,12520,2578,-1029,2067,7752 } }, + { "Olympus E-5", -1, 0xeec, /* RT - Colin Walker */ + { 9732,-2629,-999,-4899,12931,2173,-1243,2353,7457 } }, + { "Olympus E-P1", -1, 0xffd, /* RT - Colin Walker */ + { 8834,-2344,-804,-4691,12503,2448,-978,1919,7603 } }, + { "Olympus E-P2", -1, 0xffd, /* RT - Colin Walker */ + { 7758,-1619,-800,-5002,12886,2349,-985,1964,8305 } }, + { "Olympus E-P3", -1, -1, /* RT - Colin Walker */ + { 7041,-1794,-336,-3790,11192,2984,-1364,2625,6217 } }, + { "Olympus E-PL1s", -1, -1, /* RT - Colin Walker */ + { 9010,-2271,-838,-4792,12753,2263,-1059,2058,7589 } }, + { "Olympus E-PL1", -1, -1, /* RT - Colin Walker */ + { 9010,-2271,-838,-4792,12753,2263,-1059,2058,7589 } }, + { "Olympus E-PL2", -1, -1, /* RT - Colin Walker */ + { 11975,-3351,-1184,-4500,12639,2061,-1230,2353,7009 } }, + { "Olympus E-PL3", -1, -1, /* RT - Colin Walker */ + { 7041,-1794,-336,-3790,11192,2984,-1364,2625,6217 } }, + { "Olympus XZ-1", -1, -1, /* RT - Colin Walker */ + { 8665,-2247,-762,-2424,10372,2382,-1011,2286,5189 } }, + + + /* since Dcraw_v9.21 Panasonic BlackLevel is read from exif (tags 0x001c BlackLevelRed, 0x001d BlackLevelGreen, 0x001e BlackLevelBlue + and we define here the needed offset of around 15. The total BL is BL + BLoffset (cblack + black) */ + + { "Panasonic DMC-FZ150", 15, 0xfd2, /* RT */ + { 10435,-3208,-72,-2293,10506,2067,-486,1725,4682 } }, + { "Panasonic DMC-G10", 15, 0xf50, /* RT - Colin Walker - variable WL 3920 - 4080 */ + { 8310,-1811,-960,-4941,12990,2151,-1378,2468,6860 } }, + { "Panasonic DMC-G1", 15, 0xf50, /* RT - Colin Walker - variable WL 3920 - 4080 */ + { 7477,-1615,-651,-5016,12769,2506,-1380,2475,7240 } }, + { "Panasonic DMC-G2", 15, 0xf50, /* RT - Colin Walker - variable WL 3920 - 4080 */ + { 8310,-1811,-960,-4941,12990,2151,-1378,2468,6860 } }, + { "Panasonic DMC-G3", 15, 0xfdc, /* RT - Colin Walker - WL 4060 */ + { 6051,-1406,-671,-4015,11505,2868,-1654,2667,6219 } }, + { "Panasonic DMC-G5", 15, 0xfdc, /* RT - WL 4060 */ + { 7122,-2092,-419,-4643,11769,3283,-1363,2413,5944 } }, + { "Panasonic DMC-GF1", 15, 0xf50, /* RT - Colin Walker - Variable WL 3920 - 4080 */ + { 7863,-2080,-668,-4623,12331,2578,-1020,2066,7266 } }, + { "Panasonic DMC-GF2", 15, 0xfd2, /* RT - Colin Walker - WL 4050 */ + { 7694,-1791,-745,-4917,12818,2332,-1221,2322,7197 } }, + { "Panasonic DMC-GF3", 15, 0xfd2, /* RT - Colin Walker - WL 4050 */ + { 8074,-1846,-861,-5026,12999,2239,-1320,2375,7422 } }, + { "Panasonic DMC-GH1", 15, 0xf5a, /* RT - Colin Walker - variable WL 3930 - 4080 */ + { 6360,-1557,-375,-4201,11504,3086,-1378,2518,5843 } }, + { "Panasonic DMC-GH2", 15, 0xf5a, /* RT - Colin Walker - variable WL 3930 - 4080 */ +// { 6855,-1765,-456,-4223,11600,2996,-1450,2602,5761 } }, disabled due to problems with underwater WB + { 7780,-2410,-806,-3913,11724,2484,-1018,2390,5298 } }, // dcraw original + + { "Pentax K200D", -1, -1, /* RT */ + { 10962,-4428,-542,-5486,13023,2748,-569,842,8390 } }, + + + { "Leica Camera AG M9 Digital Camera", -1, -1, /* RT */ + { 7181,-1706,-55,-3557,11409,2450,-621,2072,7533 } }, + + + { "SONY NEX-3", 128 << dcraw_arw2_scaling_bugfix_shift, -1, /* RT - Colin Walker */ + { 5145,-741,-123,-4915,12310,2945,-794,1489,6906 } }, + { "SONY NEX-5", 128 << dcraw_arw2_scaling_bugfix_shift, -1, /* RT - Colin Walker */ + { 5154,-716,-115,-5065,12506,2882,-988,1715,6800 } }, + { "Sony NEX-5N", 128 << dcraw_arw2_scaling_bugfix_shift, -1, /* RT - Colin Walker */ + { 5130,-1055,-269,-4473,11797,3050,-701,1310,7121 } }, + { "Sony NEX-5R", 128 << dcraw_arw2_scaling_bugfix_shift, -1, + { 6129,-1545,-418,-4930,12490,2743,-977,1693,6615 } }, + { "SONY NEX-C3", 128 << dcraw_arw2_scaling_bugfix_shift, -1, /* RT - Colin Walker */ + { 5130,-1055,-269,-4473,11797,3050,-701,1310,7121 } }, + { "Sony SLT-A77", 128 << dcraw_arw2_scaling_bugfix_shift, -1, /* RT - Colin Walker */ + { 5126,-830,-261,-4788,12196,2934,-948,1602,7068 } }, + }; + + *black_level = -1; + *white_level = -1; + memset(trans, 0, sizeof(*trans)*12); + + // indicate that DCRAW wants these from constants (rather than having loaded these from RAW file + // note: this is simplified so far, in some cases dcraw calls this when it has say the black level + // from file, but then we will not provide any black level in the tables. This case is mainly just + // to avoid loading table values if we have loaded a DNG conversion of a raw file (which already + // have constants stored in the file). + RT_whitelevel_from_constant = 1; + RT_blacklevel_from_constant = 1; + RT_matrix_from_constant = 1; + + { // test if we have any information in the camera constants store, if so we take that. + rtengine::CameraConstantsStore* ccs = rtengine::CameraConstantsStore::getInstance(); + rtengine::CameraConst *cc = ccs->get(make, model); + if (cc) { + *black_level = cc->get_BlackLevel(0, iso_speed); + *white_level = cc->get_WhiteLevel(0, iso_speed, aperture); + if (cc->has_dcrawMatrix()) { + const short *mx = cc->get_dcrawMatrix(); + for (int j = 0; j < 12; j++) { + trans[j] = mx[j]; + } + } + return true; + } + } + + char name[strlen(make) + strlen(model) + 32]; + sprintf(name, "%s %s", make, model); + for (int i = 0; i < sizeof table / sizeof(table[0]); i++) { + if (strcasecmp(name, table[i].prefix) == 0) { + *black_level = table[i].black_level; + *white_level = table[i].white_level; + for (int j = 0; j < 12; j++) { + trans[j] = table[i].trans[j]; + } + return true; + } + } + return false; +} diff --git a/rtengine/rawimage.h b/rtengine/rawimage.h new file mode 100755 index 000000000..4f7dae634 --- /dev/null +++ b/rtengine/rawimage.h @@ -0,0 +1,184 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef __RAWIMAGE_H +#define __RAWIMAGE_H + +#include +#include "dcraw.h" +#include "imageio.h" + +namespace rtengine { + +struct badPix +{ + uint16_t x; + uint16_t y; + badPix( uint16_t xc, uint16_t yc ):x(xc),y(yc){} +}; + +class PixelsMap{ + int w; // line width in base_t units + int h; // height + typedef unsigned long base_t; + static const size_t base_t_size=sizeof(base_t); + base_t *pm; + +public: + PixelsMap(int width, int height ) + :h(height){ + w = (width+base_t_size-1) /base_t_size; + pm = new base_t [h * w ]; + memset(pm,0,h * w *base_t_size ); + } + ~PixelsMap(){ + delete [] pm; + } + int width() const { return w; } + int height() const { return h; } + + // if a pixel is set returns true + bool get(int x, int y) + { + return (pm[y*w+ x/(base_t_size*8) ] & (base_t)1<<(x%(base_t_size*8)) )!=0; + } + + // set a pixel + void set(int x, int y) + { + pm[y*w+ x/(base_t_size*8) ] |= (base_t)1<<(x%(base_t_size*8)) ; + } + + // set pixels from a list + int set( std::vector &bp) + { + for(std::vector::iterator iter = bp.begin(); iter != bp.end(); ++iter) + set( iter->x,iter->y); + + return bp.size(); + } + + void clear(){ + memset(pm,0,h * w *base_t_size ); + } + // return 0 if at least one pixel in the word(base_t) is set, otherwise return the number of pixels to skip to the next word base_t + int skipIfZero(int x, int y){ + return pm[y*w+ x/(base_t_size*8) ]==0 ? base_t_size*8 -x%(base_t_size*8):0; + } +}; + + +class RawImage: public DCraw +{ +public: + + RawImage( const Glib::ustring name ); + ~RawImage(); + + int loadRaw (bool loadData=true, bool closeFile=true, ProgressListener *plistener=0, double progressRange=1.0); + void get_colorsCoeff( float* pre_mul_, float* scale_mul_, float* cblack_, bool forceAutoWB ); + void set_prefilters(){ + if (isBayer() && get_colors() == 3) { + prefilters = filters; + filters &= ~((filters & 0x55555555) << 1); + } + } + dcrawImage_t get_image() { return image; } + float** compress_image(); // 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 ) +protected: + Glib::ustring filename; // complete filename + int rotate_deg; // 0,90,180,270 degree of rotation: info taken by dcraw from exif + char* profile_data; // Embedded ICC color profile + float* allocation; // pointer to allocated memory + int maximum_c4[4]; + bool isBayer() const { return (filters!=0 && filters!=9); } + bool isXtrans() const { return filters==9; } + bool isFoveon() const { return is_foveon; } + +public: + + static void initCameraConstants(Glib::ustring baseDir); + std::string get_filename() const { return filename;} + int get_width() const { return width; } + int get_height() const { return height; } + int get_iwidth() const { return iwidth; } + int get_iheight() const { return iheight; } + int get_leftmargin() const { return left_margin; } + int get_topmargin() const { return top_margin; } + int get_FujiWidth() const { return fuji_width; } + eSensorType getSensorType(); + + void getRgbCam (float rgbcam[3][4]); + void getXtransMatrix ( char xtransMatrix[6][6]); + void clearXtransCblack( ) { for(int c=0;c<4;c++) cblack[c] = 0;} + unsigned get_filters() const { return filters; } + int get_colors() const { return colors;} + int get_cblack(int i) const {return cblack[i];} + int get_white(int i) const { if (maximum_c4[0] > 0) return maximum_c4[i]; else return maximum;} + unsigned short get_whiteSample( int r, int c ) const { return white[r][c];} + + double get_ISOspeed() const {return iso_speed;} + double get_shutter() const {return shutter; } + double get_aperture() const {return aperture; } + time_t get_timestamp() const { return timestamp;} + int get_rotateDegree() const { return rotate_deg;} + const std::string get_maker() const { return std::string(make); } + const std::string get_model() const { return std::string(model); } + + float get_cam_mul(int c )const {return cam_mul[c];} + float get_pre_mul(int c )const {return pre_mul[c];} + float get_rgb_cam( int r, int c) const { return rgb_cam[r][c];} + + int get_exifBase() const {return exif_base; } + int get_ciffBase() const {return ciff_base; } + int get_ciffLen() const {return ciff_len; } + + int get_profileLen() const {return profile_length;} + char* get_profile() const { return profile_data;} + IMFILE *get_file() { return ifp; } + bool is_supportedThumb() const ; + int get_thumbOffset(){ return int(thumb_offset);} + int get_thumbWidth(){ return int(thumb_width);} + int get_thumbHeight(){ return int(thumb_height);} + int get_thumbBPS(){ return thumb_load_raw ? 16 : 8; } + bool get_thumbSwap() const; + unsigned get_thumbLength(){ return thumb_length;} + bool zeroIsBad() {return zero_is_bad == 1 ? true : false;} + +public: + // dcraw functions + void scale_colors(){ if(isXtrans()) clearXtransCblack( ); DCraw::scale_colors(); } + void pre_interpolate() { DCraw::pre_interpolate(); } + +public: + bool ISRED (unsigned row, unsigned col) const { return ((filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)==0);} + bool ISGREEN(unsigned row, unsigned col) const { return ((filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)==1);} + bool ISBLUE (unsigned row, unsigned col) const { return ((filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)==2);} + unsigned FC (unsigned row, unsigned col) const { return (filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3); } + bool ISXTRANSRED (unsigned row, unsigned col) const { return ((xtrans[(row)%6][(col)%6])==0);} + bool ISXTRANSGREEN(unsigned row, unsigned col) const { return ((xtrans[(row)%6][(col)%6])==1);} + bool ISXTRANSBLUE (unsigned row, unsigned col) const { return ((xtrans[(row)%6][(col)%6])==2);} + unsigned XTRANSFC (unsigned row, unsigned col) const { return (xtrans[(row)%6][(col)%6]);} + +}; + +} + +#endif // __RAWIMAGE_H diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc new file mode 100644 index 000000000..d0a800d01 --- /dev/null +++ b/rtengine/rawimagesource.cc @@ -0,0 +1,3713 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "rtengine.h" +#include "rawimagesource.h" +#include "rawimagesource_i.h" +#include "median.h" +#include "rawimage.h" +#include "mytime.h" +#include "iccmatrices.h" +#include "iccstore.h" +#include "image8.h" +#include "curves.h" +#include "dfmanager.h" +#include "ffmanager.h" +#include "slicer.h" +#include "../rtgui/options.h" +#include "dcp.h" +#include "rt_math.h" +#include "improcfun.h" +#ifdef _OPENMP +#include +#endif +#include "opthelper.h" + +namespace rtengine { + +extern const Settings* settings; +#undef ABS +#undef DIST + +#define ABS(a) ((a)<0?-(a):(a)) +#define DIST(a,b) (ABS(a-b)) + +#define PIX_SORT(a,b) { if ((a)>(b)) {temp=(a);(a)=(b);(b)=temp;} } + +#define med3x3(a0,a1,a2,a3,a4,a5,a6,a7,a8,median) { \ +p[0]=a0; p[1]=a1; p[2]=a2; p[3]=a3; p[4]=a4; p[5]=a5; p[6]=a6; p[7]=a7; p[8]=a8; \ +PIX_SORT(p[1],p[2]); PIX_SORT(p[4],p[5]); PIX_SORT(p[7],p[8]); \ +PIX_SORT(p[0],p[1]); PIX_SORT(p[3],p[4]); PIX_SORT(p[6],p[7]); \ +PIX_SORT(p[1],p[2]); PIX_SORT(p[4],p[5]); PIX_SORT(p[7],p[8]); \ +PIX_SORT(p[0],p[3]); PIX_SORT(p[5],p[8]); PIX_SORT(p[4],p[7]); \ +PIX_SORT(p[3],p[6]); PIX_SORT(p[1],p[4]); PIX_SORT(p[2],p[5]); \ +PIX_SORT(p[4],p[7]); PIX_SORT(p[4],p[2]); PIX_SORT(p[6],p[4]); \ +PIX_SORT(p[4],p[2]); median=p[4];} //a4 is the median + +#define med5(a0,a1,a2,a3,a4,median) { \ +p[0]=a0; p[1]=a1; p[2]=a2; p[3]=a3; p[4]=a4; \ +PIX_SORT(p[0],p[1]) ; PIX_SORT(p[3],p[4]) ; PIX_SORT(p[0],p[3]) ; \ +PIX_SORT(p[1],p[4]) ; PIX_SORT(p[1],p[2]) ; PIX_SORT(p[2],p[3]) ; \ +PIX_SORT(p[1],p[2]) ; median=p[2] ;} + + +RawImageSource::RawImageSource () +:ImageSource() +,plistener(NULL) +,border(4) +,ri(NULL) +,cache(NULL) +,rawData(0,0) +,green(0,0) +,red(0,0) +,blue(0,0) +{ + hrmap[0] = NULL; + hrmap[1] = NULL; + hrmap[2] = NULL; + //needhr = NULL; + //hpmap = NULL; + camProfile = NULL; + embProfile = NULL; + rgbSourceModified = false; + hlmax[0] = hlmax[1] = hlmax[2] = hlmax[3] = 0.f; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +RawImageSource::~RawImageSource () { + + delete idata; + if (ri) { + delete ri; + } + + flushRGB(); + flushRawData(); + + if( cache ) + delete [] cache; + if (hrmap[0]!=NULL) { + int dh = H/HR_SCALE; + freeArray(hrmap[0], dh); + freeArray(hrmap[1], dh); + freeArray(hrmap[2], dh); + } + //if (needhr) + // freeArray(needhr, H); + //if (hpmap) + // freeArray(hpmap, H); + if (camProfile) + cmsCloseProfile (camProfile); + if (embProfile) + cmsCloseProfile (embProfile); +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void RawImageSource::transformRect (PreviewProps pp, int tran, int &ssx1, int &ssy1, int &width, int &height, int &fw) { + + pp.x += border; + pp.y += border; + + if (d1x) { + if ((tran & TR_ROT) == TR_R90 || (tran & TR_ROT) == TR_R270) { + pp.x /= 2; + pp.w = pp.w/2+1; + } + else { + pp.y /= 2; + pp.h = pp.h/2+1; + } + } + + int w = W, h = H; + if (fuji) { + w = ri->get_FujiWidth() * 2 + 1; + h = (H - ri->get_FujiWidth())*2 + 1; + } + + int sw = w, sh = h; + if ((tran & TR_ROT) == TR_R90 || (tran & TR_ROT) == TR_R270) { + sw = h; + sh = w; + } + if( pp.w > sw-2*border) pp.w = sw-2*border; + if( pp.h > sh-2*border) pp.h = sh-2*border; + + int ppx = pp.x, ppy = pp.y; + if (tran & TR_HFLIP) + ppx = sw - pp.x - pp.w; + if (tran & TR_VFLIP) + ppy = sh - pp.y - pp.h; + + int sx1 = ppx; // assuming it's >=0 + int sy1 = ppy; // assuming it's >=0 + int sx2 = max(ppx + pp.w, w-1); + int sy2 = max(ppy + pp.h, h-1); + + if ((tran & TR_ROT) == TR_R180) { + sx1 = max(w - ppx - pp.w, 0); + sy1 = max(h - ppy - pp.h, 0); + sx2 = min(sx1 + pp.w, w-1); + sy2 = min(sy1 + pp.h, h-1); + } + else if ((tran & TR_ROT) == TR_R90) { + sx1 = ppy; + sy1 = max(h - ppx - pp.w, 0); + sx2 = min(sx1 + pp.h, w-1); + sy2 = min(sy1 + pp.w, h-1); + } + else if ((tran & TR_ROT) == TR_R270) { + sx1 = max(w - ppy - pp.h, 0); + sy1 = ppx; + sx2 = min(sx1 + pp.h, w-1); + sy2 = min(sy1 + pp.w, h-1); + } + + if (fuji) { + // atszamoljuk a koordinatakat fuji-ra: + // recalculate the coordinates fuji-ra: + ssx1 = (sx1+sy1) / 2; + ssy1 = (sy1 - sx2 ) / 2 + ri->get_FujiWidth(); + int ssx2 = (sx2+sy2) / 2 + 1; + int ssy2 = (sy2 - sx1) / 2 + ri->get_FujiWidth(); + fw = (sx2 - sx1) / 2 / pp.skip; + width = (ssx2 - ssx1) / pp.skip + ((ssx2 - ssx1) % pp.skip > 0); + height = (ssy2 - ssy1) / pp.skip + ((ssy2 - ssy1) % pp.skip > 0); + } + else { + ssx1 = sx1; + ssy1 = sy1; + width = (sx2 - sx1) / pp.skip + ((sx2 - sx1) % pp.skip > 0); + height = (sy2 - sy1) / pp.skip + ((sy2 - sy1) % pp.skip > 0); + } +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +static float +calculate_scale_mul(float scale_mul[4], const float pre_mul_[4], const float c_white[4], const float c_black[4], bool isMono, int colors) +{ + if (isMono || colors == 1) { + for (int c = 0; c < 4; c++) { + scale_mul[c] = 65535.0 / (c_white[c] - c_black[c]); + } + } else { + float pre_mul[4]; + for (int c = 0; c < 4; c++) { + pre_mul[c] = pre_mul_[c]; + } + if (pre_mul[3] == 0) { + pre_mul[3] = pre_mul[1]; // G2 == G1 + } + float maxpremul = max(pre_mul[0], pre_mul[1], pre_mul[2], pre_mul[3]); + for (int c = 0; c < 4; c++) { + scale_mul[c] = (pre_mul[c] / maxpremul) * 65535.0 / (c_white[c] - c_black[c]); + } + } + float gain = max(scale_mul[0], scale_mul[1], scale_mul[2], scale_mul[3]) / min(scale_mul[0], scale_mul[1], scale_mul[2], scale_mul[3]); + return gain; +} + +void RawImageSource::getImage (ColorTemp ctemp, int tran, Imagefloat* image, PreviewProps pp, ToneCurveParams hrp, ColorManagementParams cmp, RAWParams raw ) +{ + MyMutex::MyLock lock(getImageMutex); + + tran = defTransform (tran); + + // compute channel multipliers + double r, g, b; + float rm, gm, bm; + if (ctemp.getTemp() < 0) { + // no white balance, ie revert the pre-process white balance to restore original unbalanced raw camera color + rm = ri->get_pre_mul(0); + gm = ri->get_pre_mul(1); + bm = ri->get_pre_mul(2); + } else { + ctemp.getMultipliers (r, g, b); + rm = imatrices.cam_rgb[0][0]*r + imatrices.cam_rgb[0][1]*g + imatrices.cam_rgb[0][2]*b; + gm = imatrices.cam_rgb[1][0]*r + imatrices.cam_rgb[1][1]*g + imatrices.cam_rgb[1][2]*b; + bm = imatrices.cam_rgb[2][0]*r + imatrices.cam_rgb[2][1]*g + imatrices.cam_rgb[2][2]*b; + } + + if (true) { + // adjust gain so the maximum raw value of the least scaled channel just hits max + const float new_pre_mul[4] = { ri->get_pre_mul(0) / rm, ri->get_pre_mul(1) / gm, ri->get_pre_mul(2) / bm, ri->get_pre_mul(3) / gm }; + float new_scale_mul[4]; + + bool isMono = (ri->getSensorType()==ST_FUJI_XTRANS && raw.xtranssensor.method == RAWParams::XTransSensor::methodstring[RAWParams::XTransSensor::mono]) + || (ri->getSensorType()==ST_BAYER && raw.bayersensor.method == RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::mono]); + float gain = calculate_scale_mul(new_scale_mul, new_pre_mul, c_white, cblacksom, isMono, ri->get_colors()); + rm = new_scale_mul[0] / scale_mul[0] * gain; + gm = new_scale_mul[1] / scale_mul[1] * gain; + bm = new_scale_mul[2] / scale_mul[2] * gain; + //fprintf(stderr, "camera gain: %f, current wb gain: %f, diff in stops %f\n", camInitialGain, gain, log2(camInitialGain) - log2(gain)); + } else { + // old scaling: used a fixed reference gain based on camera (as-shot) white balance + + // how much we need to scale each channel to get our new white balance + rm = refwb_red / rm; + gm = refwb_green / gm; + bm = refwb_blue / bm; + // normalize so larger multiplier becomes 1.0 + float minval = min(rm, gm, bm); + rm /= minval; + gm /= minval; + bm /= minval; + // multiply with reference gain, ie as-shot WB + rm *= camInitialGain; + gm *= camInitialGain; + bm *= camInitialGain; + } + + defGain=0.0; + // compute image area to render in order to provide the requested part of the image + int sx1, sy1, imwidth, imheight, fw; + transformRect (pp, tran, sx1, sy1, imwidth, imheight, fw); + + // check possible overflows + int maximwidth, maximheight; + if ((tran & TR_ROT) == TR_R90 || (tran & TR_ROT) == TR_R270) { + maximwidth = image->height; + maximheight = image->width; + } + else { + maximwidth = image->width; + maximheight = image->height; + } + if (d1x) + maximheight /= 2; + + // correct if overflow (very rare), but not fuji because it is corrected in transline + if (!fuji && imwidth>maximwidth) + imwidth = maximwidth; + if (!fuji && imheight>maximheight) + imheight = maximheight; + + int maxx=this->W,maxy=this->H,skip=pp.skip; + + //if (sx1+skip*imwidth>maxx) imwidth --; // very hard to fix this situation without an 'if' in the loop. + float area=skip*skip; + rm/=area; + gm/=area; + bm/=area; + + // raw clip levels after white balance + hlmax[0]=65535 * rm / min(rm, gm, bm); + hlmax[1]=65535 * gm / min(rm, gm, bm); + hlmax[2]=65535 * bm / min(rm, gm, bm); + + +#ifdef _OPENMP +#pragma omp parallel if(!d1x) // omp disabled for D1x to avoid race conditions (see Issue 1088 http://code.google.com/p/rawtherapee/issues/detail?id=1088) + { +#endif + // render the requested image part + float* line_red = new float[imwidth]; + float* line_grn = new float[imwidth]; + float* line_blue = new float[imwidth]; + //printf("clip[0]=%f clip[1]=%f clip[2]=%f\n",hlmax[0],hlmax[1],hlmax[2]); + + +#ifdef _OPENMP +#pragma omp for +#endif + for (int ix=0; ix=maxy-skip) i=maxy-skip-1; // avoid trouble + if (ri->getSensorType()==ST_BAYER || ri->getSensorType()==ST_FUJI_XTRANS || ri->get_colors() == 1) { + for (int j=0,jx=sx1; j=maxx-skip) jx=maxx-skip-1; // avoid trouble + float rtot,gtot,btot; + rtot=gtot=btot=0; + for (int m=0; m hlmax[0] || gtot > hlmax[1] || btot > hlmax[2])) + { + // make a sort of luminance recovery. Note that as we don't desaturate + // surrounding unclipped highlights the transition into clipping may not + // be smooth, meaning that stuff like RGB-HSV desaturation will look bad. + // We accept this drawback though, those that really need highlight reconstruction + // should enable that. + float L = rtot*0.2126729f + gtot*0.7151521f + btot*0.0721750f; + rtot = gtot = btot = L; + //rtot=CLIP(rtot); + //gtot=CLIP(gtot); + //btot=CLIP(btot); + } + line_red[j] = rtot; + line_grn[j] = gtot; + line_blue[j] = btot; + } + } else { + for (int j=0,jx=sx1; jmaxx-skip) jx=maxx-skip-1; + float rtot,gtot,btot; + rtot=gtot=btot=0; + for (int m=0; m hlmax[0] || gtot > hlmax[1] || btot > hlmax[2])) + { + float L = rtot*0.2126729f + gtot*0.7151521f + btot*0.0721750f; + rtot = gtot = btot = L; + //rtot=CLIP(rtot); + //gtot=CLIP(gtot); + //btot=CLIP(btot); + } + line_red[j] = rtot; + line_grn[j] = gtot; + line_blue[j] = btot; + + } + } + + //process all highlight recovery other than "Color" + if (hrp.hrenabled && hrp.method!="Color") + hlRecovery (hrp.method, line_red, line_grn, line_blue, i, sx1, imwidth, skip, raw, hlmax); + + transLine (line_red, line_grn, line_blue, ix, image, tran, imwidth, imheight, fw); + + } + + delete [] line_red; + delete [] line_grn; + delete [] line_blue; +#ifdef _OPENMP + } +#endif + if (fuji) { + int a = ((tran & TR_ROT) == TR_R90 && image->width%2==0) || ((tran & TR_ROT) == TR_R180 && image->height%2+image->width%2==1) || ((tran & TR_ROT) == TR_R270 && image->height%2==0); + // first row + for (int j=1+a; jwidth-1; j+=2) { + image->r(0,j) = (image->r(1,j) + image->r(0,j+1) + image->r(0,j-1)) / 3; + image->g(0,j) = (image->g(1,j) + image->g(0,j+1) + image->g(0,j-1)) / 3; + image->b(0,j) = (image->b(1,j) + image->b(0,j+1) + image->b(0,j-1)) / 3; + } + // other rows + for (int i=1; iheight-1; i++) { + for (int j=2-(a+i+1)%2; jwidth-1; j+=2) { + // edge-adaptive interpolation + double dh = (ABS(image->r(i,j+1) - image->r(i,j-1)) + ABS(image->g(i,j+1) - image->g(i,j-1)) + ABS(image->b(i,j+1) - image->b(i,j-1))) / 1.0; + double dv = (ABS(image->r(i+1,j) - image->r(i-1,j)) + ABS(image->g(i+1,j) - image->g(i-1,j)) + ABS(image->b(i+1,j) - image->b(i-1,j))) / 1.0; + double eh = 1.0 / (1.0 + dh); + double ev = 1.0 / (1.0 + dv); + image->r(i,j) = (eh * (image->r(i,j+1) + image->r(i,j-1)) + ev * (image->r(i+1,j) + image->r(i-1,j))) / (2.0 * (eh + ev)); + image->g(i,j) = (eh * (image->g(i,j+1) + image->g(i,j-1)) + ev * (image->g(i+1,j) + image->g(i-1,j))) / (2.0 * (eh + ev)); + image->b(i,j) = (eh * (image->b(i,j+1) + image->b(i,j-1)) + ev * (image->b(i+1,j) + image->b(i-1,j))) / (2.0 * (eh + ev)); + } + // first pixel + if (2-(a+i+1)%2==2) { + image->r(i,0) = (image->r(i+1,0) + image->r(i-1,0) + image->r(i,1)) / 3; + image->g(i,0) = (image->g(i+1,0) + image->g(i-1,0) + image->g(i,1)) / 3; + image->b(i,0) = (image->b(i+1,0) + image->b(i-1,0) + image->b(i,1)) / 3; + } + // last pixel + if (2-(a+i+image->width)%2==2) { + image->r(i,image->width-1) = (image->r(i+1,image->width-1) + image->r(i-1,image->width-1) + image->r(i,image->width-2)) / 3; + image->g(i,image->width-1) = (image->g(i+1,image->width-1) + image->g(i-1,image->width-1) + image->g(i,image->width-2)) / 3; + image->b(i,image->width-1) = (image->b(i+1,image->width-1) + image->b(i-1,image->width-1) + image->b(i,image->width-2)) / 3; + } + } + // last row + int b = (a==1 && image->height%2) || (a==0 && image->height%2==0); + for (int j=1+b; jwidth-1; j+=2) { + image->r(image->height-1,j) = (image->r(image->height-2,j) + image->r(image->height-1,j+1) + image->r(image->height-1,j-1)) / 3; + image->g(image->height-1,j) = (image->g(image->height-2,j) + image->g(image->height-1,j+1) + image->g(image->height-1,j-1)) / 3; + image->b(image->height-1,j) = (image->b(image->height-2,j) + image->b(image->height-1,j+1) + image->b(image->height-1,j-1)) / 3; + } + } + + + + // Flip if needed + if (tran & TR_HFLIP) + hflip (image); + if (tran & TR_VFLIP) + vflip (image); + + // Color correction (only when running on full resolution) + if (ri->getSensorType()!=ST_NONE && pp.skip==1) { + if (ri->getSensorType()==ST_BAYER) + processFalseColorCorrection (image, raw.bayersensor.ccSteps); + else if (ri->getSensorType()==ST_FUJI_XTRANS) + processFalseColorCorrection (image, raw.xtranssensor.ccSteps); + } +} + +DCPProfile *RawImageSource::getDCP(ColorManagementParams cmp, ColorTemp &wb) { + DCPProfile *dcpProf = NULL; + cmsHPROFILE dummy; + findInputProfile(cmp.input, NULL, (static_cast(getMetaData()))->getCamera(), &dcpProf, dummy); + if (dcpProf == NULL) { + return NULL; + } + dcpProf->setStep2ApplyState(cmp.working, cmp.toneCurve, cmp.applyLookTable, cmp.applyBaselineExposureOffset); + return dcpProf; +} + +void RawImageSource::convertColorSpace(Imagefloat* image, ColorManagementParams cmp, 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()); +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +/* interpolateBadPixelsBayer: correct raw pixels looking at the bitmap + * takes into consideration if there are multiple bad pixels in the neighborhood + */ +int RawImageSource::interpolateBadPixelsBayer( PixelsMap &bitmapBads ) +{ + static const float eps=1.f; + int counter=0; +#pragma omp parallel for reduction(+:counter) schedule(dynamic,16) + for( int row = 2; row < H-2; row++ ){ + for(int col = 2; col weighting is 0.70710678 + // For green channel following pixels will be used for interpolation. Pixel to be interpolated is in center. + // 1 means that pixel is used in this step, if itself and his counterpart are not marked bad + // 0 0 0 0 0 + // 0 1 0 1 0 + // 0 0 0 0 0 + // 0 1 0 1 0 + // 0 0 0 0 0 + for( int dx=-1;dx<=1;dx+=2){ + if( bitmapBads.get(col+dx,row-1) || bitmapBads.get(col-dx,row+1)) + continue; + float dirwt = 0.70710678f/( fabsf( rawData[row-1][col+dx]- rawData[row+1][col-dx])+eps); + wtdsum += dirwt * (rawData[row-1][col+dx] + rawData[row+1][col-dx]); + norm += dirwt; + } + } else { + // red and blue channel. Distance to center pixel is sqrt(8) => weighting is 0.35355339 + // For red and blue channel following pixels will be used for interpolation. Pixel to be interpolated is in center. + // 1 means that pixel is used in this step, if itself and his counterpart are not marked bad + // 1 0 0 0 1 + // 0 0 0 0 0 + // 0 0 0 0 0 + // 0 0 0 0 0 + // 1 0 0 0 1 + for( int dx=-2;dx<=2;dx+=4){ + if( bitmapBads.get(col+dx,row-2) || bitmapBads.get(col-dx,row+2)) + continue; + float dirwt = 0.35355339f/( fabsf( rawData[row-2][col+dx]- rawData[row+2][col-dx])+eps); + wtdsum += dirwt * (rawData[row-2][col+dx] + rawData[row+2][col-dx]); + norm += dirwt; + } + } + // channel independent. Distance to center pixel is 2 => weighting is 0.5 + // Additionally for all channel following pixels will be used for interpolation. Pixel to be interpolated is in center. + // 1 means that pixel is used in this step, if itself and his counterpart are not marked bad + // 0 0 1 0 0 + // 0 0 0 0 0 + // 1 0 0 0 1 + // 0 0 0 0 0 + // 0 0 1 0 0 + + // horizontal interpolation + if(!(bitmapBads.get(col-2,row) || bitmapBads.get(col+2,row))) { + float dirwt = 0.5f/( fabsf( rawData[row][col-2]- rawData[row][col+2])+eps); + wtdsum += dirwt * (rawData[row][col-2] + rawData[row][col+2]); + norm += dirwt; + } + + // vertical interpolation + if(!(bitmapBads.get(col,row-2) || bitmapBads.get(col,row+2))) { + float dirwt = 0.5f/( fabsf( rawData[row-2][col]- rawData[row+2][col])+eps); + wtdsum += dirwt * (rawData[row-2][col] + rawData[row+2][col]); + norm += dirwt; + } + + if (LIKELY(norm > 0.f)){ // This means, we found at least one pair of valid pixels in the steps above, likelyhood of this case is about 99.999% + rawData[row][col]= wtdsum / (2.f * norm);//gradient weighted average, Factor of 2.f is an optimization to avoid multiplications in former steps + counter++; + } else { //backup plan -- simple average. Same method for all channels. We could improve this, but it's really unlikely that this case happens + int tot = 0; + float sum = 0; + for( int dy=-2;dy<=2;dy+=2){ + for( int dx=-2;dx<=2;dx+=2){ + if(bitmapBads.get(col+dx,row+dy)) + continue; + sum += rawData[row+dy][col+dx]; + tot++; + } + } + if (tot > 0) { + rawData[row][col] = sum/tot; + counter ++; + } + } + } + } + return counter; // Number of interpolated pixels. +} + +/* interpolateBadPixels3Colours: correct raw pixels looking at the bitmap + * takes into consideration if there are multiple bad pixels in the neighborhood + */ +int RawImageSource::interpolateBadPixelsNColours( PixelsMap &bitmapBads, const int colours ) +{ + static const float eps=1.f; + int counter=0; +#pragma omp parallel for reduction(+:counter) schedule(dynamic,16) + for( int row = 2; row < H-2; row++ ){ + for(int col = 2; col 0.f)){ // This means, we found at least one pair of valid pixels in the steps above, likelyhood of this case is about 99.999% + for(int c=0;c 0) { + for(int c=0;cXTRANSFC(row,col); + float oldval = rawData[row][col]; + if(pixelColor==1) { + // green channel. A green pixel can either be a solitary green pixel or a member of a 2x2 square of green pixels + if(ri->XTRANSFC(row,col-1)==ri->XTRANSFC(row,col+1)) { + // If left and right neighbour have same color, then this is a solitary green pixel + // For these the following pixels will be used for interpolation. Pixel to be interpolated is in center and marked with a P. + // Pairs of pixels used in this step are numbered. A pair will be used if none of the pixels of the pair is marked bad + // 0 means, the pixel has a different color and will not be used + // 0 1 0 2 0 + // 3 5 0 6 4 + // 0 0 P 0 0 + // 4 6 0 5 3 + // 0 2 0 1 0 + for( int dx=-1;dx<=1;dx+=2){ // pixels marked 5 or 6 in above example. Distance to P is sqrt(2) => weighting is 0.70710678f + if( bitmapBads.get(col+dx,row-1) || bitmapBads.get(col-dx,row+1)) + continue; + float dirwt = 0.70710678f/( fabsf( rawData[row-1][col+dx]- rawData[row+1][col-dx])+eps); + wtdsum += dirwt * (rawData[row-1][col+dx] + rawData[row+1][col-dx]); + norm += dirwt; + } + for( int dx=-1;dx<=1;dx+=2){ // pixels marked 1 or 2 on above example. Distance to P is sqrt(5) => weighting is 0.44721359f + if( bitmapBads.get(col+dx,row-2) || bitmapBads.get(col-dx,row+2)) + continue; + float dirwt = 0.44721359f/( fabsf( rawData[row-2][col+dx]- rawData[row+2][col-dx])+eps); + wtdsum += dirwt * (rawData[row-2][col+dx] + rawData[row+2][col-dx]); + norm += dirwt; + } + for( int dx=-2;dx<=2;dx+=4){ // pixels marked 3 or 4 on above example. Distance to P is sqrt(5) => weighting is 0.44721359f + if( bitmapBads.get(col+dx,row-1) || bitmapBads.get(col-dx,row+1)) + continue; + float dirwt = 0.44721359f/( fabsf( rawData[row-1][col+dx]- rawData[row+1][col-dx])+eps); + wtdsum += dirwt * (rawData[row-1][col+dx] + rawData[row+1][col-dx]); + norm += dirwt; + } + } else { + // this is a member of a 2x2 square of green pixels + // For these the following pixels will be used for interpolation. Pixel to be interpolated is at position P in the example. + // Pairs of pixels used in this step are numbered. A pair will be used if none of the pixels of the pair is marked bad + // 0 means, the pixel has a different color and will not be used + // 1 0 0 3 + // 0 P 2 0 + // 0 2 1 0 + // 3 0 0 0 + int offset1 = ri->XTRANSFC(row-1,col-1) == ri->XTRANSFC(row+1,col+1) ? 1 : -1; // pixels marked 1 in above example. Distance to P is sqrt(2) => weighting is 0.70710678f + if( !(bitmapBads.get(col-offset1,row-1) || bitmapBads.get(col+offset1,row+1))) { + float dirwt = 0.70710678f/( fabsf( rawData[row-1][col-offset1]- rawData[row+1][col+offset1])+eps); + wtdsum += dirwt * (rawData[row-1][col-offset1] + rawData[row+1][col+offset1]); + norm += dirwt; + } + int offsety = (ri->XTRANSFC(row-1,col) != 1 ? 1 : -1); + int offsetx = offset1 * offsety; + if( !(bitmapBads.get(col+offsetx,row) || bitmapBads.get(col,row+offsety))) { + float dirwt = 1.f/( fabsf( rawData[row][col+offsetx]- rawData[row+offsety][col])+eps); + wtdsum += dirwt * (rawData[row][col+offsetx] + rawData[row+offsety][col]); + norm += dirwt; + } + int offsety2 = -offsety; + int offsetx2 = -offsetx; + offsetx *=2; + offsety *=2; + // pixels marked 3 in above example. Distance to P is sqrt(5) => weighting is 0.44721359f + if( !(bitmapBads.get(col+offsetx,row+offsety2) || bitmapBads.get(col+offsetx2,row+offsety))) { + float dirwt = 0.44721359f/( fabsf( rawData[row+offsety2][col+offsetx]- rawData[row+offsety][col+offsetx2])+eps); + wtdsum += dirwt * (rawData[row+offsety2][col+offsetx] + rawData[row+offsety][col+offsetx2]); + norm += dirwt; + } + } + } else { + // red and blue channel. + // Each red or blue pixel has exactly one neigbour of same color in distance 2 and four neighbours of same color which can be reached by a move of a knight in chess. + // For the distance 2 pixel (marked with an X) we generate a virtual counterpart (marked with a V) + // For red and blue channel following pixels will be used for interpolation. Pixel to be interpolated is in center and marked with a P. + // Pairs of pixels used in this step are numbered except for distance 2 pixels which are marked X and V. A pair will be used if none of the pixels of the pair is marked bad + // 0 1 0 0 0 0 0 X 0 0 remaining cases are symmetric + // 0 0 0 0 2 1 0 0 0 2 + // X 0 P 0 V 0 0 P 0 0 + // 0 0 0 0 1 0 0 0 0 0 + // 0 2 0 0 0 0 2 V 1 0 + + // Find two knight moves landing on a pixel of same color as the pixel to be interpolated. + // If we look at first and last row of 5x5 square, we will find exactly two knight pixels. + // Additionally we know that the column of this pixel has 1 or -1 horizontal distance to the center pixel + // When we find a knight pixel, we get its counterpart, which has distance (+-3,+-3), where the signs of distance depend on the corner of the found knight pixel. + // These pixels are marked 1 or 2 in above examples. Distance to P is sqrt(5) => weighting is 0.44721359f + // The following loop simply scans the four possible places. To keep things simple, it doesn't stop after finding two knight pixels, because it will not find more than two + for(int d1=-2,offsety=3;d1<=2;d1+=4,offsety-=6) { + for(int d2=-1,offsetx=3;d2<1;d2+=2,offsetx-=6) { + if(ri->XTRANSFC(row+d1,col+d2) == pixelColor) { + if( !(bitmapBads.get(col+d2,row+d1) || bitmapBads.get(col+d2+offsetx,row+d1+offsety))) { + float dirwt = 0.44721359f/( fabsf( rawData[row+d1][col+d2]- rawData[row+d1+offsety][col+d2+offsetx])+eps); + wtdsum += dirwt * (rawData[row+d1][col+d2] + rawData[row+d1+offsety][col+d2+offsetx]); + norm += dirwt; + } + } + } + } + + // now scan for the pixel of same colour in distance 2 in each direction (marked with an X in above examples). + bool distance2PixelFound = false; + int dx,dy; + // check horizontal + for(dx=-2,dy=0;dx<=2 && !distance2PixelFound;dx+=4) + if(ri->XTRANSFC(row,col+dx) == pixelColor) + distance2PixelFound = true; + + if(!distance2PixelFound) + // no distance 2 pixel on horizontal, check vertical + for(dx=0,dy=-2;dy<=2 && !distance2PixelFound;dy+=4) + if(ri->XTRANSFC(row+dy,col) == pixelColor) + distance2PixelFound = true; + + // calculate the value of its virtual counterpart (marked with a V in above examples) + float virtualPixel; + if(dy==0) { + virtualPixel = 0.5f*(rawData[row-1][col-dx] + rawData[row+1][col-dx]); + } + else { + virtualPixel = 0.5f*(rawData[row-dy][col-1] + rawData[row-dy][col+1]); + } + // and weight as usual. Distance to P is 2 => weighting is 0.5f + float dirwt = 0.5f/( fabsf( virtualPixel- rawData[row+dy][col+dx])+eps); + wtdsum += dirwt * (virtualPixel + rawData[row+dy][col+dx]); + norm += dirwt; + } + + if (LIKELY(norm > 0.f)){ // This means, we found at least one pair of valid pixels in the steps above, likelyhood of this case is about 99.999% + rawData[row][col]= wtdsum / (2.f * norm);//gradient weighted average, Factor of 2.f is an optimization to avoid multiplications in former steps +//#pragma omp critical +// printf("%s Pixel at (col/row) : (%4d/%4d) : Original : %f, interpolated: %f\n",pixelColor == 0 ? "Red " : pixelColor==1 ? "Green" : "Blue ", col-7,row-7,oldval, rawData[row][col]); + counter++; + } + } + } + return counter; // Number of interpolated pixels. +} +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +/* Search for hot or dead pixels in the image and update the map + * For each pixel compare its value to the average of similar color surrounding + * (Taken from Emil Martinec idea) + * (Optimized by Ingo Weyrich 2013) + */ +int RawImageSource::findHotDeadPixels( PixelsMap &bpMap, float thresh, bool findHotPixels, bool findDeadPixels ) +{ + float varthresh = (20.0*(thresh/100.0) + 1.0 ); + + // counter for dead or hot pixels + int counter=0; + + // allocate temporary buffer + float (*cfablur); + cfablur = (float (*)) malloc (H*W * sizeof *cfablur); + +#pragma omp parallel +{ +#pragma omp for + for (int i=0; iH-3) {inext=i-2;} else {inext=i+2;} + for (int j=0; jW-3) {jnext=j-2;} else {jnext=j+2;} + med3x3(rawData[iprev][jprev],rawData[iprev][j],rawData[iprev][jnext], + rawData[i][jprev],rawData[i][j],rawData[i][jnext], + rawData[inext][jprev],rawData[inext][j],rawData[inext][jnext],temp); + cfablur[i*W+j] = rawData[i][j]-temp; + } + } +#pragma omp for reduction(+:counter) schedule (dynamic,16) + //cfa pixel heat/death evaluation + for (int rr=0; rr < H; rr++) { + int top=max(0,rr-2); + int bottom=min(H-1,rr+2); + int rrmWpcc = rr*W; + for (int cc=0; cc < W; cc++,rrmWpcc++) { + //evaluate pixel for heat/death + float pixdev = cfablur[rrmWpcc]; + if((!findDeadPixels) && pixdev <= 0) + continue; + if((!findHotPixels) && pixdev >= 0) + continue; + pixdev = fabsf(pixdev); + float hfnbrave = -pixdev; + int left=max(0,cc-2); + int right=min(W-1,cc+2); + for (int mm=top; mm<=bottom; mm++) { + int mmmWpnn = mm*W+left; + for (int nn=left; nn<=right; nn++,mmmWpnn++) { + hfnbrave += fabsf(cfablur[mmmWpnn]); + } + } + if (pixdev * ((bottom-top+1)*(right-left+1)-1) > varthresh*hfnbrave) { + // mark the pixel as "bad" + bpMap.set(cc,rr); + counter++; + } + }//end of pixel evaluation + } +}//end of parallel processing + free (cfablur); + return counter; +} + +void RawImageSource::rotateLine (float* line, PlanarPtr &channel, int tran, int i, int w, int h) { + + if ((tran & TR_ROT) == TR_R180) + for (int j=0; j=0 && yheight && y>=0 && xwidth) { + image->r(image->height-1-y,image->width-1-x) = red[j]; + image->g(image->height-1-y,image->width-1-x) = green[j]; + image->b(image->height-1-y,image->width-1-x) = blue[j]; + } + } + } + else if ((tran & TR_ROT) == TR_R270) { + int end = min(h+fw-i, w-fw+i); + for (int j=start; j=0 && xheight && y>=0 && ywidth) { + image->r(image->height-1-x,y) = red[j]; + image->g(image->height-1-x,y) = green[j]; + image->b(image->height-1-x,y) = blue[j]; + } + } + } + else if ((tran & TR_ROT) == TR_R90) { + int end = min(h+fw-i, w-fw+i); + for (int j=start; j=0 && ywidth && y>=0 && xheight) { + image->r(x,image->width-1-y) = red[j]; + image->g(x,image->width-1-y) = green[j]; + image->b(x,image->width-1-y) = blue[j]; + } + } + } + else { + int end = min(h+fw-i, w-fw+i); + for (int j=start; j=0 && yheight && y>=0 && xwidth) { + image->r(y,x) = red[j]; + image->g(y,x) = green[j]; + image->b(y,x) = blue[j]; + } + } + } + } + // Nikon D1X vertical interpolation + coarse rotation + else if (d1x) { + // copy new pixels + if ((tran & TR_ROT) == TR_R180) { + for (int j=0; jr(2*imheight-2-2*i,imwidth-1-j) = red[j]; + image->g(2*imheight-2-2*i,imwidth-1-j) = green[j]; + image->b(2*imheight-2-2*i,imwidth-1-j) = blue[j]; + } + + if (i==1 || i==2) { // linear interpolation + int row = 2*imheight-1-2*i; + for (int j=0; jr(row,col) = (red[j] + image->r(row+1,col)) /2; + image->g(row,col) = (green[j] + image->g(row+1,col)) /2; + image->b(row,col) = (blue[j] + image->b(row+1,col)) /2; + } + } + else if (i==imheight-1) { + int row = 2*imheight-1-2*i; + for (int j=0; jr(row,col) = (red[j] + image->r(row+1,col)) /2; + image->g(row,col) = (green[j] + image->g(row+1,col)) /2; + image->b(row,col) = (blue[j] + image->b(row+1,col)) /2; + } + row = 2*imheight-1-2*i+2; + for (int j=0; jr(row,col) = (red[j] + image->r(row+1,col)) /2; + image->g(row,col) = (green[j] + image->g(row+1,col)) /2; + image->b(row,col) = (blue[j] + image->b(row+1,col)) /2; + } + } + else if (i>2 && ir(row,col) = CLIP((int)(-0.0625*red[j] + 0.5625*image->r(row-1,col) + 0.5625*image->r(row+1,col) - 0.0625*image->r(row+3,col))); + image->g(row,col) = CLIP((int)(-0.0625*green[j] + 0.5625*image->g(row-1,col) + 0.5625*image->g(row+1,col) - 0.0625*image->g(row+3,col))); + image->b(row,col) = CLIP((int)(-0.0625*blue[j] + 0.5625*image->b(row-1,col) + 0.5625*image->b(row+1,col) - 0.0625*image->b(row+3,col))); + } + } + } + else if ((tran & TR_ROT) == TR_R90) { + for (int j=0; jr(j,2*imheight-2-2*i) = red[j]; + image->g(j,2*imheight-2-2*i) = green[j]; + image->b(j,2*imheight-2-2*i) = blue[j]; + } + if (i==1 || i==2) { // linear interpolation + int col = 2*imheight-1-2*i; + for (int j=0; jr(j,col) = (red[j] + image->r(j,col+1)) /2; + image->g(j,col) = (green[j] + image->g(j,col+1)) /2; + image->b(j,col) = (blue[j] + image->b(j,col+1)) /2; + } + } + else if (i==imheight-1) { + int col = 2*imheight-1-2*i; + for (int j=0; jr(j,col) = (red[j] + image->r(j,col+1)) /2; + image->g(j,col) = (green[j] + image->g(j,col+1)) /2; + image->b(j,col) = (blue[j] + image->b(j,col+1)) /2; + } + col = 2*imheight-1-2*i+2; + for (int j=0; jr(j,col) = (red[j] + image->r(j,col+1)) /2; + image->g(j,col) = (green[j] + image->g(j,col+1)) /2; + image->b(j,col) = (blue[j] + image->b(j,col+1)) /2; + } + } + else if (i>2 && ir(j,col) = CLIP((int)(-0.0625*red[j] + 0.5625*image->r(j,col-1) + 0.5625*image->r(j,col+1) - 0.0625*image->r(j,col+3))); + image->g(j,col) = CLIP((int)(-0.0625*green[j] + 0.5625*image->g(j,col-1) + 0.5625*image->g(j,col+1) - 0.0625*image->g(j,col+3))); + image->b(j,col) = CLIP((int)(-0.0625*blue[j] + 0.5625*image->b(j,col-1) + 0.5625*image->b(j,col+1) - 0.0625*image->b(j,col+3))); + } + } + } + else if ((tran & TR_ROT) == TR_R270) { + for (int j=0; jr(imwidth-1-j,2*i) = red[j]; + image->g(imwidth-1-j,2*i) = green[j]; + image->b(imwidth-1-j,2*i) = blue[j]; + } + if (i==1 || i==2) { // linear interpolation + for (int j=0; jr(row,2*i-1) = (red[j] + image->r(row,2*i-2)) * 0.5f; + image->g(row,2*i-1) = (green[j] + image->g(row,2*i-2)) * 0.5f; + image->b(row,2*i-1) = (blue[j] + image->b(row,2*i-2)) * 0.5f; + } + } + else if (i==imheight-1) { + for (int j=0; jr(row,2*i-1) = (red[j] + image->r(row,2*i-2)) * 0.5f; + image->g(row,2*i-1) = (green[j] + image->g(row,2*i-2)) * 0.5f; + image->b(row,2*i-1) = (blue[j] + image->b(row,2*i-2)) * 0.5f; + image->r(row,2*i-3) = (image->r(row,2*i-2) + image->r(row,2*i-4)) * 0.5f; + image->g(row,2*i-3) = (image->g(row,2*i-2) + image->g(row,2*i-4)) * 0.5f; + image->b(row,2*i-3) = (image->b(row,2*i-2) + image->b(row,2*i-4)) * 0.5f; + } + } + else if (i>0 && ir(row,2*i-3) = CLIP((int)(-0.0625*red[j] + 0.5625*image->r(row,2*i-2) + 0.5625*image->r(row,2*i-4) - 0.0625*image->r(row,2*i-6))); + image->g(row,2*i-3) = CLIP((int)(-0.0625*green[j] + 0.5625*image->g(row,2*i-2) + 0.5625*image->g(row,2*i-4) - 0.0625*image->g(row,2*i-6))); + image->b(row,2*i-3) = CLIP((int)(-0.0625*blue[j] + 0.5625*image->b(row,2*i-2) + 0.5625*image->b(row,2*i-4) - 0.0625*image->b(row,2*i-6))); + } + } + } + else { + rotateLine (red, image->r, tran, 2*i, imwidth, imheight); + rotateLine (green, image->g, tran, 2*i, imwidth, imheight); + rotateLine (blue, image->b, tran, 2*i, imwidth, imheight); + + if (i==1 || i==2) { // linear interpolation + for (int j=0; jr(2*i-1,j) = (red[j] + image->r(2*i-2,j)) /2; + image->g(2*i-1,j) = (green[j] + image->g(2*i-2,j)) /2; + image->b(2*i-1,j) = (blue[j] + image->b(2*i-2,j)) /2; + } + } + else if (i==imheight-1) { + for (int j=0; jr(2*i-3,j) = (image->r(2*i-4,j) + image->r(2*i-2,j)) /2; + image->g(2*i-3,j) = (image->g(2*i-4,j) + image->g(2*i-2,j)) /2; + image->b(2*i-3,j) = (image->b(2*i-4,j) + image->b(2*i-2,j)) /2; + image->r(2*i-1,j) = (red[j] + image->r(2*i-2,j)) /2; + image->g(2*i-1,j) = (green[j] + image->g(2*i-2,j)) /2; + image->b(2*i-1,j) = (blue[j] + image->b(2*i-2,j)) /2; + } + } + else if (i>2 && ir(2*i-3,j) = CLIP((int)(-0.0625*red[j] + 0.5625*image->r(2*i-2,j) + 0.5625*image->r(2*i-4,j) - 0.0625*image->r(2*i-6,j))); + image->g(2*i-3,j) = CLIP((int)(-0.0625*green[j] + 0.5625*image->g(2*i-2,j) + 0.5625*image->g(2*i-4,j) - 0.0625*image->g(2*i-6,j))); + image->b(2*i-3,j) = CLIP((int)(-0.0625*blue[j] + 0.5625*image->b(2*i-2,j) + 0.5625*image->b(2*i-4,j) - 0.0625*image->b(2*i-6,j))); + } + } + } + } // if nikon dx1 + // other (conventional) CCD coarse rotation + else { + rotateLine (red, image->r, tran, i, imwidth, imheight); + rotateLine (green, image->g, tran, i, imwidth, imheight); + rotateLine (blue, image->b, tran, i, imwidth, imheight); + } +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void RawImageSource::getFullSize (int& w, int& h, int tr) { + + tr = defTransform (tr); + + if (fuji) { + w = ri->get_FujiWidth() * 2 + 1; + h = (H - ri->get_FujiWidth())*2 + 1; + } + else if (d1x) { + w = W; + h = 2*H-1; + } + else { + w = W; + h = H; + } + + if ((tr & TR_ROT) == TR_R90 || (tr & TR_ROT) == TR_R270) { + int tmp = w; + w = h; + h = tmp; + } + w -= 2 * border; + h -= 2 * border; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void RawImageSource::getSize (int tran, PreviewProps pp, int& w, int& h) { + + tran = defTransform (tran); + +// if (fuji) { +// return; +// } +// else if (d1x) { +// return; +// } +// else { + w = pp.w / pp.skip + (pp.w % pp.skip > 0); + h = pp.h / pp.skip + (pp.h % pp.skip > 0); +// } +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void RawImageSource::hflip (Imagefloat* image) { + image->hflip(); +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void RawImageSource::vflip (Imagefloat* image) { + image->vflip(); +} + + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +int RawImageSource::load (Glib::ustring fname, bool batch) { + + MyTime t1,t2; + t1.set(); + fileName = fname; + + if (plistener) { + plistener->setProgressStr ("Decoding..."); + plistener->setProgress (0.0); + } + + ri = new RawImage(fname); + int errCode = ri->loadRaw (true, true, plistener, 0.8); + if (errCode) return errCode; + + ri->compress_image(); + if (plistener) { + plistener->setProgress (0.9); + } +/***** Copy once constant data extracted from raw *******/ + W = ri->get_width(); + H = ri->get_height(); + fuji = ri->get_FujiWidth()!=0; + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + imatrices.rgb_cam[i][j] = ri->get_rgb_cam(i,j); + // compute inverse of the color transformation matrix + // first arg is matrix, second arg is inverse + inverse33 (imatrices.rgb_cam, imatrices.cam_rgb); + + d1x = ! ri->get_model().compare("D1X"); + if (d1x) + border = 8; + + if(ri->getSensorType()==ST_FUJI_XTRANS) + border = 7; + else if(ri->getSensorType()==ST_FOVEON) + border = 0; + + if ( ri->get_profile() ) + embProfile = cmsOpenProfileFromMem (ri->get_profile(), ri->get_profileLen()); + + // create profile + memset (imatrices.xyz_cam, 0, sizeof(imatrices.xyz_cam)); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + imatrices.xyz_cam[i][j] += xyz_sRGB[i][k] * imatrices.rgb_cam[k][j]; + camProfile = iccStore->createFromMatrix (imatrices.xyz_cam, false, "Camera"); + inverse33 (imatrices.xyz_cam, imatrices.cam_xyz); + + for (int c = 0; c < 4; c++) { + c_white[c] = ri->get_white(c); + } + // First we get the "as shot" ("Camera") white balance and store it + float pre_mul[4]; + // FIXME: get_colorsCoeff not so much used nowadays, when we have calculate_scale_mul() function here + ri->get_colorsCoeff( pre_mul, scale_mul, c_black, false);//modify for black level + camInitialGain = max(scale_mul[0], scale_mul[1], scale_mul[2], scale_mul[3]) / min(scale_mul[0], scale_mul[1], scale_mul[2], scale_mul[3]); + + double camwb_red = ri->get_pre_mul(0) / pre_mul[0]; + double camwb_green = ri->get_pre_mul(1) / pre_mul[1]; + double camwb_blue = ri->get_pre_mul(2) / pre_mul[2]; + double cam_r = imatrices.rgb_cam[0][0]*camwb_red + imatrices.rgb_cam[0][1]*camwb_green + imatrices.rgb_cam[0][2]*camwb_blue; + double cam_g = imatrices.rgb_cam[1][0]*camwb_red + imatrices.rgb_cam[1][1]*camwb_green + imatrices.rgb_cam[1][2]*camwb_blue; + double cam_b = imatrices.rgb_cam[2][0]*camwb_red + imatrices.rgb_cam[2][1]*camwb_green + imatrices.rgb_cam[2][2]*camwb_blue; + camera_wb = ColorTemp (cam_r, cam_g, cam_b, 1.); // as shot WB + + ColorTemp ReferenceWB; + double ref_r, ref_g, ref_b; + { + // ...then we re-get the constants but now with auto which gives us better demosaicing and CA auto-correct + // performance for strange white balance settings (such as UniWB) + ri->get_colorsCoeff( ref_pre_mul, scale_mul, c_black, true); + refwb_red = ri->get_pre_mul(0) / ref_pre_mul[0]; + refwb_green = ri->get_pre_mul(1) / ref_pre_mul[1]; + refwb_blue = ri->get_pre_mul(2) / ref_pre_mul[2]; + initialGain = max(scale_mul[0], scale_mul[1], scale_mul[2], scale_mul[3]) / min(scale_mul[0], scale_mul[1], scale_mul[2], scale_mul[3]); + ref_r = imatrices.rgb_cam[0][0]*refwb_red + imatrices.rgb_cam[0][1]*refwb_green + imatrices.rgb_cam[0][2]*refwb_blue; + ref_g = imatrices.rgb_cam[1][0]*refwb_red + imatrices.rgb_cam[1][1]*refwb_green + imatrices.rgb_cam[1][2]*refwb_blue; + ref_b = imatrices.rgb_cam[2][0]*refwb_red + imatrices.rgb_cam[2][1]*refwb_green + imatrices.rgb_cam[2][2]*refwb_blue; + ReferenceWB = ColorTemp (ref_r, ref_g, ref_b, 1.); + } + if (settings->verbose) { + printf("Raw As Shot White balance: temp %f, tint %f\n", camera_wb.getTemp(), camera_wb.getGreen()); + printf("Raw Reference (auto) white balance: temp %f, tint %f, multipliers [%f %f %f | %f %f %f]\n", ReferenceWB.getTemp(), ReferenceWB.getGreen(), ref_r, ref_g, ref_b, refwb_red, refwb_blue, refwb_green); + } + + /*{ + // Test code: if you want to test a specific white balance + ColorTemp d50wb = ColorTemp(5000.0, 1.0, 1.0, "Custom"); + double rm,gm,bm,r,g,b; + d50wb.getMultipliers(r, g, b); + camwb_red = imatrices.cam_rgb[0][0]*r + imatrices.cam_rgb[0][1]*g + imatrices.cam_rgb[0][2]*b; + camwb_green = imatrices.cam_rgb[1][0]*r + imatrices.cam_rgb[1][1]*g + imatrices.cam_rgb[1][2]*b; + camwb_blue = imatrices.cam_rgb[2][0]*r + imatrices.cam_rgb[2][1]*g + imatrices.cam_rgb[2][2]*b; + double pre_mul[3], dmax = 0; + pre_mul[0] = ri->get_pre_mul(0) / camwb_red; + pre_mul[1] = ri->get_pre_mul(1) / camwb_green; + pre_mul[2] = ri->get_pre_mul(2) / camwb_blue; + for (int c = 0; c < 3; c++) { + if (dmax < pre_mul[c]) + dmax = pre_mul[c]; + } + for (int c = 0; c < 3; c++) { + pre_mul[c] /= dmax; + } + camwb_red *= dmax; + camwb_green *= dmax; + camwb_blue *= dmax; + for (int c = 0; c < 3; c++) { + int sat = ri->get_white(c) - ri->get_cblack(c); + scale_mul[c] = pre_mul[c] * 65535.0 / sat; + } + scale_mul[3] = pre_mul[1] * 65535.0 / (ri->get_white(3) - ri->get_cblack(3)); + initialGain = 1.0 / min(pre_mul[0], pre_mul[1], pre_mul[2]); + }*/ + + + ri->set_prefilters(); + + //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); + + green(W,H); + red(W,H); + blue(W,H); + //hpmap = allocArray(W, H); + + if (plistener) { + plistener->setProgress (1.0); + } + plistener=NULL; // This must be reset, because only load() is called through progressConnector + t2.set(); + if( settings->verbose ) + printf("Load %s: %d usec\n",fname.c_str(), t2.etime(t1)); + + return 0; // OK! +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &lensProf, const CoarseTransformParams& coarse) +{ + MyTime t1,t2; + t1.set(); + + Glib::ustring newDF = raw.dark_frame; + RawImage *rid=NULL; + if (!raw.df_autoselect) { + if( !raw.dark_frame.empty()) + rid = dfm.searchDarkFrame( raw.dark_frame ); + } else { + rid = dfm.searchDarkFrame( ri->get_maker(), ri->get_model(), ri->get_ISOspeed(), ri->get_shutter(), ri->get_timestamp()); + } + if( rid && settings->verbose){ + printf( "Subtracting Darkframe:%s\n",rid->get_filename().c_str()); + } + + PixelsMap bitmapBads(W,H); + int totBP=0; // Hold count of bad pixels to correct + + if(ri->zeroIsBad()) { // mark all pixels with value zero as bad, has to be called before FF and DF. dcraw sets this flag only for some cameras (mainly Panasonic and Leica) +#pragma omp parallel for reduction(+:totBP) + for(int i=0;idata[i][j] == 0.f) { + bitmapBads.set(j,i); + totBP++; + } + } + if( settings->verbose) { + printf( "%d pixels with value zero marked as bad pixels\n",totBP); + } + } + + //FLATFIELD start + Glib::ustring newFF = raw.ff_file; + RawImage *rif=NULL; + if (!raw.ff_AutoSelect) { + if( !raw.ff_file.empty()) + rif = ffm.searchFlatField( raw.ff_file ); + } else { + rif = ffm.searchFlatField( idata->getMake(), idata->getModel(),idata->getLens(),idata->getFocalLen(), idata->getFNumber(), idata->getDateTimeAsTS()); + } + + + bool hasFlatField = (rif!=NULL); + if( hasFlatField && settings->verbose) { + printf( "Flat Field Correction:%s\n",rif->get_filename().c_str()); + } + + copyOriginalPixels(raw, ri, rid, rif); + //FLATFIELD end + + + // Always correct camera badpixels from .badpixels file + std::vector *bp = dfm.getBadPixels( ri->get_maker(), ri->get_model(), idata->getSerialNumber() ); + if( bp ){ + totBP+=bitmapBads.set( *bp ); + if( settings->verbose ){ + std::cout << "Correcting " << bp->size() << " pixels from .badpixels" << std::endl; + } + } + + // If darkframe selected, correct hotpixels found on darkframe + bp = 0; + if( raw.df_autoselect ){ + bp = dfm.getHotPixels( ri->get_maker(), ri->get_model(), ri->get_ISOspeed(), ri->get_shutter(), ri->get_timestamp()); + }else if( !raw.dark_frame.empty() ) + bp = dfm.getHotPixels( raw.dark_frame ); + if(bp){ + totBP+=bitmapBads.set( *bp ); + if( settings->verbose && !bp->empty()){ + std::cout << "Correcting " << bp->size() << " hotpixels from darkframe" << std::endl; + } + } + + + scaleColors( 0,0, W, H, raw);//+ + raw parameters for black level(raw.blackxx) + + // Correct vignetting of lens profile + if (!hasFlatField && lensProf.useVign) { + LCPProfile *pLCPProf=lcpStore->getProfile(lensProf.lcpFile); + if (pLCPProf && idata->getFocalLen() > 0.f) { + LCPMapper map(pLCPProf, idata->getFocalLen(), idata->getFocalLen35mm(), idata->getFocusDist(), idata->getFNumber(), true, false, W, H, coarse, -1); + + #pragma omp parallel for + for (int y=0; y0) rawData[y][x] *= map.calcVignetteFac(x,y); + } + } + } + } + + defGain = 0.0;//log(initialGain) / log(2.0); + + if ( ri->getSensorType()==ST_BAYER && (raw.hotPixelFilter>0 || raw.deadPixelFilter>0)) { + if (plistener) { + plistener->setProgressStr ("Hot/Dead Pixel Filter..."); + plistener->setProgress (0.0); + } + int nFound = findHotDeadPixels( bitmapBads, raw.hotdeadpix_thresh, raw.hotPixelFilter, raw.deadPixelFilter ); + totBP += nFound; + if( settings->verbose && nFound>0){ + printf( "Correcting %d hot/dead pixels found inside image\n",nFound ); + } + } + + // check if it is an olympus E camera, 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.; + +#pragma omp parallel for default(shared) private(i) reduction(+: ng1, ng2, avgg1, avgg2) + for (i=border; iISGREEN(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); + +#pragma omp parallel for default(shared) + for (int i=border; iISGREEN(i,j)) { + float currData; + currData = (float)(rawData[i][j] * ((i&1) ? corrg2 : corrg1)); + rawData[i][j] = (currData); + } + } + + if ( ri->getSensorType()==ST_BAYER && raw.bayersensor.greenthresh >0) { + if (plistener) { + plistener->setProgressStr ("Green equilibrate..."); + plistener->setProgress (0.0); + } + green_equilibrate(0.01*(raw.bayersensor.greenthresh)); + } + + + if( totBP ) + if ( ri->getSensorType()==ST_BAYER ) + interpolateBadPixelsBayer( bitmapBads ); + else if ( ri->getSensorType()==ST_FUJI_XTRANS ) + interpolateBadPixelsXtrans( bitmapBads ); + else + interpolateBadPixelsNColours( bitmapBads, ri->get_colors() ); + + if ( ri->getSensorType()==ST_BAYER && raw.bayersensor.linenoise >0 ) { + if (plistener) { + plistener->setProgressStr ("Line Denoise..."); + plistener->setProgress (0.0); + } + + cfa_linedn(0.00002*(raw.bayersensor.linenoise)); + } + + if ( (raw.ca_autocorrect || fabs(raw.cared)>0.001 || fabs(raw.cablue)>0.001) && ri->getSensorType() == ST_BAYER ) { // Auto CA correction disabled for X-Trans, for now... + if (plistener) { + plistener->setProgressStr ("CA Auto Correction..."); + plistener->setProgress (0.0); + } + + CA_correct_RT(raw.cared, raw.cablue); + } + + if ( raw.expos !=1 ) processRawWhitepoint(raw.expos, raw.preser); + + if(dirpyrdenoiseExpComp == INFINITY) { + LUTu aehist; int aehistcompr; + double clip=0; + int brightness, contrast, black, hlcompr, hlcomprthresh; + getAutoExpHistogram (aehist, aehistcompr); + ImProcFunctions::getAutoExp (aehist, aehistcompr, getDefGain(), clip, dirpyrdenoiseExpComp, brightness, contrast, black, hlcompr, hlcomprthresh); + } + + t2.set(); + if( settings->verbose ) + printf("Preprocessing: %d usec\n", t2.etime(t1)); + return; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void RawImageSource::demosaic(const RAWParams &raw) +{ + MyTime t1,t2; + t1.set(); + + if (ri->getSensorType()==ST_BAYER) { + if ( raw.bayersensor.method == RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::hphd] ) + hphd_demosaic (); + 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); + else if (raw.bayersensor.method == RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::amaze] ) + amaze_demosaic_RT (0,0,W,H); + else if (raw.bayersensor.method == RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::dcb] ) + dcb_demosaic(raw.bayersensor.dcb_iterations, raw.bayersensor.dcb_enhance); + else if (raw.bayersensor.method == RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::eahd]) + eahd_demosaic (); + else if (raw.bayersensor.method == RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::igv]) + igv_interpolate(W,H); + else if (raw.bayersensor.method == RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::lmmse]) + lmmse_interpolate_omp(W,H,raw.bayersensor.lmmse_iterations); + else if (raw.bayersensor.method == RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::fast] ) + fast_demosaic (0,0,W,H); + else if (raw.bayersensor.method == RAWParams::BayerSensor::methodstring[RAWParams::BayerSensor::mono] ) + nodemosaic(true); + else + nodemosaic(false); + + //if (raw.all_enhance) refinement_lassus(); + + } else if (ri->getSensorType()==ST_FUJI_XTRANS) { + if (raw.xtranssensor.method == RAWParams::XTransSensor::methodstring[RAWParams::XTransSensor::fast] ) + fast_xtrans_interpolate(); + else if (raw.xtranssensor.method == RAWParams::XTransSensor::methodstring[RAWParams::XTransSensor::onePass]) + xtrans_interpolate(1,false); + else if (raw.xtranssensor.method == RAWParams::XTransSensor::methodstring[RAWParams::XTransSensor::threePass] ) + xtrans_interpolate(3,true); + else if(raw.xtranssensor.method == RAWParams::XTransSensor::methodstring[RAWParams::XTransSensor::mono] ) + nodemosaic(true); + else + nodemosaic(false); + } else if (ri->get_colors() == 1) { + // Monochrome + nodemosaic(true); + } + t2.set(); + + rgbSourceModified = false; + if( settings->verbose ) { + if (getSensorType() == ST_BAYER) + printf("Demosaicing Bayer data: %s - %d usec\n",raw.bayersensor.method.c_str(), t2.etime(t1)); + else if (getSensorType() == ST_FUJI_XTRANS) + printf("Demosaicing X-Trans data: %s - %d usec\n",raw.xtranssensor.method.c_str(), t2.etime(t1)); + } + +} + +void RawImageSource::flushRawData() { + if(cache) { + delete [] cache; + cache = 0; + } + if (rawData) { + rawData(0,0); + } +} + +void RawImageSource::flushRGB() { + if (green) { + green(0,0); + } + if (red) { + red(0,0); + } + if (blue) { + blue(0,0); + } +} + +void RawImageSource::HLRecovery_Global(ToneCurveParams hrp ) +{ + if (hrp.hrenabled && hrp.method=="Color"){ + if(!rgbSourceModified) { + if (settings->verbose) printf ("Applying Highlight Recovery: Color propagation...\n"); + HLRecovery_inpaint (red,green,blue); + rgbSourceModified = true; + } + } +} + + +void RawImageSource::processFlatField(const RAWParams &raw, RawImage *riFlatFile, unsigned short black[4]) +{ + float (*cfablur); + cfablur = (float (*)) calloc (H*W, sizeof *cfablur); + int BS = raw.ff_BlurRadius; + BS += BS&1; + + //function call to cfabloxblur + if (raw.ff_BlurType == RAWParams::ff_BlurTypestring[RAWParams::v_ff]) + cfaboxblur(riFlatFile, cfablur, 2*BS, 0); + else if (raw.ff_BlurType == RAWParams::ff_BlurTypestring[RAWParams::h_ff]) + cfaboxblur(riFlatFile, cfablur, 0, 2*BS); + else if (raw.ff_BlurType == RAWParams::ff_BlurTypestring[RAWParams::vh_ff]) + //slightly more complicated blur if trying to correct both vertical and horizontal anomalies + cfaboxblur(riFlatFile, cfablur, BS, BS);//first do area blur to correct vignette + else //(raw.ff_BlurType == RAWParams::ff_BlurTypestring[RAWParams::area_ff]) + cfaboxblur(riFlatFile, cfablur, BS, BS); + + if(ri->getSensorType()==ST_BAYER) { + float refcolor[2][2]; + //find center ave values by channel + for (int m=0; m<2; m++) + for (int n=0; n<2; n++) { + int row = 2*(H>>2)+m; + int col = 2*(W>>2)+n; + int c = FC(row, col); + int c4 = ( c == 1 && !(row&1) ) ? 3 : c; + refcolor[m][n] = max(0.0f,cfablur[row*W+col] - black[c4]); + } + + float limitFactor = 1.f; + if(raw.ff_AutoClipControl) { + int clipControlGui = 0; + for (int m=0; m<2; m++) + for (int n=0; n<2; n++) { + float maxval = 0.f; + int c = FC(m, n); + int c4 = ( c == 1 && !(m&1) ) ? 3 : c; +#pragma omp parallel +{ + float maxvalthr = 0.f; +#pragma omp for + for (int row = 0; row< H-m; row+=2) { + for (int col = 0; col < W-n; col+=2) { + float tempval = (rawData[row+m][col+n]-black[c4]) * ( refcolor[m][n]/max(1e-5f,cfablur[(row+m)*W+col+n]-black[c4]) ); + if(tempval > maxvalthr) + maxvalthr = tempval; + } + } +#pragma omp critical +{ + + if(maxvalthr>maxval) + maxval = maxvalthr; + +} +} + // now we have the max value for the channel + // if it clips, calculate factor to avoid clipping + if(maxval + black[c4] >= ri->get_white(c4)) + limitFactor = min(limitFactor,ri->get_white(c4) / (maxval + black[c4])); + } + clipControlGui = (1.f - limitFactor) * 100.f; // this value can be used to set the clip control slider in gui + } else { + limitFactor = max((float)(100 - raw.ff_clipControl)/100.f,0.01f); + } + for (int m=0; m<2; m++) + for (int n=0; n<2; n++) + refcolor[m][n] *= limitFactor; + + + for (int m=0; m<2; m++) + for (int n=0; n<2; n++) { +#pragma omp parallel +{ + int c = FC(m, n); + int c4 = ( c == 1 && !(m&1) ) ? 3 : c; +#pragma omp for + for (int row = 0; row< H-m; row+=2) { + for (int col = 0; col < W-n; col+=2) { + float vignettecorr = ( refcolor[m][n]/max(1e-5f,cfablur[(row+m)*W+col+n]-black[c4]) ); + rawData[row+m][col+n] = (rawData[row+m][col+n]-black[c4]) * vignettecorr + black[c4]; + } + } +} + } + } else if(ri->getSensorType()==ST_FUJI_XTRANS) { + float refcolor[3] = {0.f}; + int cCount[3] = {0}; + //find center ave values by channel + for (int m=-3; m<3; m++) + for (int n=-3; n<3; n++) { + int row = 2*(H>>2)+m; + int col = 2*(W>>2)+n; + int c = riFlatFile->XTRANSFC(row, col); + refcolor[c] += max(0.0f,cfablur[row*W+col] - black[c]); + cCount[c] ++; + } + for(int c=0;c<3;c++) + refcolor[c] = refcolor[c] / cCount[c]; + + float limitFactor = 1.f; + + if(raw.ff_AutoClipControl) { + // determine maximum calculated value to avoid clipping + int clipControlGui = 0; + float maxval = 0.f; + // xtrans files have only one black level actually, so we can simplify the code a bit +#pragma omp parallel +{ + float maxvalthr = 0.f; +#pragma omp for schedule(dynamic,16) nowait + for (int row = 0; row< H; row++) { + for (int col = 0; col < W; col++) { + float tempval = (rawData[row][col]-black[0]) * ( refcolor[ri->XTRANSFC(row, col)]/max(1e-5f,cfablur[(row)*W+col]-black[0]) ); + if(tempval > maxvalthr) + maxvalthr = tempval; + } + } +#pragma omp critical +{ + if(maxvalthr>maxval) + maxval = maxvalthr; +} +} + // there's only one white level for xtrans + if(maxval + black[0] > ri->get_white(0)) { + limitFactor = ri->get_white(0) / (maxval + black[0]); + clipControlGui = (1.f - limitFactor) * 100.f; // this value can be used to set the clip control slider in gui + } + } else { + limitFactor = max((float)(100 - raw.ff_clipControl)/100.f,0.01f); + } + + + for(int c=0;c<3;c++) + refcolor[c] *= limitFactor; + +#pragma omp parallel for + for (int row = 0; row< H; row++) { + for (int col = 0; col < W; col++) { + int c = ri->XTRANSFC(row, col); + float vignettecorr = ( refcolor[c]/max(1e-5f,cfablur[(row)*W+col]-black[c]) ); + rawData[row][col] = (rawData[row][col]-black[c]) * vignettecorr + black[c]; + } + } + } + if (raw.ff_BlurType == RAWParams::ff_BlurTypestring[RAWParams::vh_ff]) { + float (*cfablur1); + cfablur1 = (float (*)) calloc (H*W, sizeof *cfablur1); + float (*cfablur2); + cfablur2 = (float (*)) calloc (H*W, sizeof *cfablur2); + //slightly more complicated blur if trying to correct both vertical and horizontal anomalies + cfaboxblur(riFlatFile, cfablur1, 0, 2*BS);//now do horizontal blur + cfaboxblur(riFlatFile, cfablur2, 2*BS, 0);//now do vertical blur + + if(ri->getSensorType()==ST_BAYER) { + for (int m=0; m<2; m++) + for (int n=0; n<2; n++) { +#pragma omp parallel for + for (int row = 0; row< H-m; row+=2) { + int c = FC(row, 0); + int c4 = ( c == 1 && !(row&1) ) ? 3 : c; + for (int col = 0; col < W-n; col+=2) { + float hlinecorr = (max(1e-5f,cfablur[(row+m)*W+col+n]-black[c4])/max(1e-5f,cfablur1[(row+m)*W+col+n]-black[c4]) ); + float vlinecorr = (max(1e-5f,cfablur[(row+m)*W+col+n]-black[c4])/max(1e-5f,cfablur2[(row+m)*W+col+n]-black[c4]) ); + rawData[row+m][col+n] = ((rawData[row+m][col+n]-black[c4]) * hlinecorr * vlinecorr + black[c4]); + } + } + } + } else if(ri->getSensorType()==ST_FUJI_XTRANS) { +#pragma omp parallel for + for (int row = 0; row< H; row++) { + for (int col = 0; col < W; col++) { + int c = ri->XTRANSFC(row, col); + float hlinecorr = (max(1e-5f,cfablur[(row)*W+col]-black[c])/max(1e-5f,cfablur1[(row)*W+col]-black[c]) ); + float vlinecorr = (max(1e-5f,cfablur[(row)*W+col]-black[c])/max(1e-5f,cfablur2[(row)*W+col]-black[c]) ); + rawData[row][col] = ((rawData[row][col]-black[c]) * hlinecorr * vlinecorr + black[c]); + } + } + + } + free (cfablur1); + free (cfablur2); + } + + free (cfablur); +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +/* Copy original pixel data and + * subtract dark frame (if present) from current image and apply flat field correction (if present) + */ +void RawImageSource::copyOriginalPixels(const RAWParams &raw, RawImage *src, RawImage *riDark, RawImage *riFlatFile ) +{ + unsigned short black[4]={ri->get_cblack(0),ri->get_cblack(1),ri->get_cblack(2),ri->get_cblack(3)}; + + if (ri->getSensorType()==ST_BAYER || ri->getSensorType()==ST_FUJI_XTRANS) { + if (!rawData) + rawData(W,H); + if (riDark && W == riDark->get_width() && H == riDark->get_height()) { // This works also for xtrans-sensors, because black[0] to black[4] are equal for these + for (int row = 0; row < H; row++) { + for (int col = 0; col < W; col++) { + int c = FC(row, col); + int c4 = ( c == 1 && !(row&1) ) ? 3 : c; + rawData[row][col] = max(src->data[row][col]+black[c4] - riDark->data[row][col], 0.0f); + } + } + }else{ + for (int row = 0; row < H; row++) { + for (int col = 0; col < W; col++) { + rawData[row][col] = src->data[row][col]; + } + } + } + + + if (riFlatFile && W == riFlatFile->get_width() && H == riFlatFile->get_height()) { + processFlatField(raw, riFlatFile, black); + } // flatfield + } else if (ri->get_colors() == 1) { + // Monochrome + if (!rawData) rawData(W,H); + + if (riDark && W == riDark->get_width() && H == riDark->get_height()) { + for (int row = 0; row < H; row++) { + for (int col = 0; col < W; col++) { + rawData[row][col] = max(src->data[row][col]+black[0] - riDark->data[row][col], 0.0f); + } + } + } else { + for (int row = 0; row < H; row++) { + for (int col = 0; col < W; col++) { + rawData[row][col] = src->data[row][col]; + } + } + } + } else { + // No bayer pattern + // TODO: Is there a flat field correction possible? + if (!rawData) rawData(3*W,H); + + if (riDark && W == riDark->get_width() && H == riDark->get_height()) { + for (int row = 0; row < H; row++) { + for (int col = 0; col < W; col++) { + int c = FC(row, col); + int c4 = ( c == 1 && !(row&1) ) ? 3 : c; + rawData[row][3*col+0] = max(src->data[row][3*col+0]+black[c4] - riDark->data[row][3*col+0], 0.0f); + rawData[row][3*col+1] = max(src->data[row][3*col+1]+black[c4] - riDark->data[row][3*col+1], 0.0f); + rawData[row][3*col+2] = max(src->data[row][3*col+2]+black[c4] - riDark->data[row][3*col+2], 0.0f); + } + } + } else { + for (int row = 0; row < H; row++) { + for (int col = 0; col < W; col++) { + rawData[row][3*col+0] = src->data[row][3*col+0]; + rawData[row][3*col+1] = src->data[row][3*col+1]; + rawData[row][3*col+2] = src->data[row][3*col+2]; + } + } + } + } +} + +SSEFUNCTION void RawImageSource::cfaboxblur(RawImage *riFlatFile, float* cfablur, const int boxH, const int boxW ) { + + float (*cfatmp); + cfatmp = (float (*)) calloc (H*W, sizeof *cfatmp); +// const float hotdeadthresh = 0.5; + +#pragma omp parallel +{ +#pragma omp for + for (int i=0; iH-3) {inext=i-2;} else {inext=i+2;} + for (int j=0; jW-3) {jnext=j-2;} else {jnext=j+2;} + //med3x3(riFlatFile->data[iprev][jprev], riFlatFile->data[iprev][j], riFlatFile->data[iprev][jnext], + // riFlatFile->data[i][jprev], riFlatFile->data[i][j], riFlatFile->data[i][jnext], + // riFlatFile->data[inext][jprev], riFlatFile->data[inext][j], riFlatFile->data[inext][jnext], cfatmp[i*W+j]); + med5(riFlatFile->data[iprev][j], riFlatFile->data[i][jprev],riFlatFile->data[i][j], + riFlatFile->data[i][jnext], riFlatFile->data[inext][j],median); + +// if (riFlatFile->data[i][j]>hotdeadthresh*median || median>hotdeadthresh*riFlatFile->data[i][j]) { + if (((int)riFlatFile->data[i][j]<<1)>median || (median<<1) > riFlatFile->data[i][j]) { + cfatmp[i*W+j] = median; + } else { + cfatmp[i*W+j] = riFlatFile->data[i][j]; + } + + } + } + + //box blur cfa image; box size = BS + //horizontal blur +#pragma omp for + for (int row = 0; row < H; row++) { + int len = boxW/2 + 1; + cfatmp[row*W+0] = cfatmp[row*W+0]/len; + cfatmp[row*W+1] = cfatmp[row*W+1]/len; + for (int j=2; j<=boxW; j+=2) { + cfatmp[row*W+0] += cfatmp[row*W+j]/len; + cfatmp[row*W+1] += cfatmp[row*W+j+1]/len; + } + for (int col=2; col<=boxW; col+=2) { + cfatmp[row*W+col] = (cfatmp[row*W+col-2]*len + cfatmp[row*W+boxW+col])/(len+1); + cfatmp[row*W+col+1] = (cfatmp[row*W+col-1]*len + cfatmp[row*W+boxW+col+1])/(len+1); + len ++; + } + for (int col = boxW+2; col < W-boxW; col++) { + cfatmp[row*W+col] = cfatmp[row*W+col-2] + (cfatmp[row*W+boxW+col]-cfatmp[row*W+col-boxW-2])/len; + } + for (int col=W-boxW; colget_colors()); // recalculate scale colors with adjusted levels + //fprintf(stderr, "recalc: %f [%f %f %f %f]\n", initialGain, scale_mul[0], scale_mul[1], scale_mul[2], scale_mul[3]); + + // this seems strange, but it works + + // scale image colors + + if( ri->getSensorType()==ST_BAYER){ +#pragma omp parallel +{ + float tmpchmax[3]; + tmpchmax[0] = tmpchmax[1] = tmpchmax[2] = 0.0f; + +#pragma omp for nowait + for (int row = winy; row < winy+winh; row ++){ + for (int col = winx; col < winx+winw; col++) { + float val = rawData[row][col]; + int c = FC(row, col); // three colors, 0=R, 1=G, 2=B + int c4 = ( c == 1 && !(row&1) ) ? 3 : c; // four colors, 0=R, 1=G1, 2=B, 3=G2 + val-=cblacksom[c4]; + val*=scale_mul[c4]; + + rawData[row][col] = (val); + tmpchmax[c] = max(tmpchmax[c],val); + } + } +#pragma omp critical +{ + chmax[0] = max(tmpchmax[0],chmax[0]); + chmax[1] = max(tmpchmax[1],chmax[1]); + chmax[2] = max(tmpchmax[2],chmax[2]); +} +} + } else if ( ri->get_colors() == 1 ) { +#pragma omp parallel +{ + float tmpchmax = 0.0f; + +#pragma omp for nowait + for (int row = winy; row < winy+winh; row ++){ + for (int col = winx; col < winx+winw; col++) { + float val = rawData[row][col]; + val -= cblacksom[0]; + val *= scale_mul[0]; + rawData[row][col] = (val); + tmpchmax = max(tmpchmax,val); + } + } +#pragma omp critical +{ + chmax[0] = chmax[1] = chmax[2] = chmax[3] = max(tmpchmax,chmax[0]); +} +} + } else if(ri->getSensorType()==ST_FUJI_XTRANS) { +#pragma omp parallel +{ + float tmpchmax[3]; + tmpchmax[0] = tmpchmax[1] = tmpchmax[2] = 0.0f; + +#pragma omp for nowait + for (int row = winy; row < winy+winh; row ++){ + for (int col = winx; col < winx+winw; col++) { + float val = rawData[row][col]; + int c = ri->XTRANSFC(row, col); + val-=cblacksom[c]; + val*=scale_mul[c]; + + rawData[row][col] = (val); + tmpchmax[c] = max(tmpchmax[c],val); + } + } +#pragma omp critical +{ + chmax[0] = max(tmpchmax[0],chmax[0]); + chmax[1] = max(tmpchmax[1],chmax[1]); + chmax[2] = max(tmpchmax[2],chmax[2]); +} +} + } else { +#pragma omp parallel +{ + float tmpchmax[3]; + tmpchmax[0] = tmpchmax[1] = tmpchmax[2] = 0.0f; + +#pragma omp for nowait + for (int row = winy; row < winy+winh; row ++){ + for (int col = winx; col < winx+winw; col++) { + for (int c=0; c<3; c++) { // three colors, 0=R, 1=G, 2=B + float val = rawData[row][3*col+c]; + val -= cblacksom[c]; + val *= scale_mul[c]; + rawData[row][3*col+c] = (val); + tmpchmax[c] = max(tmpchmax[c],val); + } + } + } +#pragma omp critical +{ + chmax[0] = max(tmpchmax[0],chmax[0]); + chmax[1] = max(tmpchmax[1],chmax[1]); + chmax[2] = max(tmpchmax[2],chmax[2]); +} +} + chmax[3]=chmax[1]; + } + +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +int RawImageSource::defTransform (int tran) { + + int deg = ri->get_rotateDegree(); + if ((tran & TR_ROT) == TR_R180) + deg += 180; + else if ((tran & TR_ROT) == TR_R90) + deg += 90; + else if ((tran & TR_ROT) == TR_R270) + deg += 270; + deg %= 360; + + int ret = 0; + if (deg==90) + ret |= TR_R90; + else if (deg==180) + ret |= TR_R180; + else if (deg==270) + ret |= TR_R270; + if (tran & TR_HFLIP) + ret |= TR_HFLIP; + if (tran & TR_VFLIP) + ret |= TR_VFLIP; + return ret; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +// Thread called part +void RawImageSource::processFalseColorCorrectionThread (Imagefloat* im, int row_from, int row_to) { + + int W = im->width; + + array2D rbconv_Y (W,3); + array2D rbconv_I (W,3); + array2D rbconv_Q (W,3); + array2D rbout_I (W,3); + array2D rbout_Q (W,3); + + float* row_I = new float[W]; + float* row_Q = new float[W]; + + float* pre1_I = new float[3]; + float* pre2_I = new float[3]; + float* post1_I = new float[3]; + float* post2_I = new float[3]; + float middle_I[6]; + float* pre1_Q = new float[3]; + float* pre2_Q = new float[3]; + float* post1_Q = new float[3]; + float* post2_Q = new float[3]; + float middle_Q[6]; + float* tmp; + + int px=(row_from-1)%3, cx=row_from%3, nx=0; + + convert_row_to_YIQ (im->r(row_from-1), im->g(row_from-1), im->b(row_from-1), rbconv_Y[px], rbconv_I[px], rbconv_Q[px], W); + convert_row_to_YIQ (im->r(row_from), im->g(row_from), im->b(row_from), rbconv_Y[cx], rbconv_I[cx], rbconv_Q[cx], W); + + for (int j=0; jr(i+1), im->g(i+1), im->b(i+1), rbconv_Y[nx], rbconv_I[nx], rbconv_Q[nx], W); + + SORT3(rbconv_I[px][0],rbconv_I[cx][0],rbconv_I[nx][0],pre1_I[0],pre1_I[1],pre1_I[2]); + SORT3(rbconv_I[px][1],rbconv_I[cx][1],rbconv_I[nx][1],pre2_I[0],pre2_I[1],pre2_I[2]); + SORT3(rbconv_Q[px][0],rbconv_Q[cx][0],rbconv_Q[nx][0],pre1_Q[0],pre1_Q[1],pre1_Q[2]); + SORT3(rbconv_Q[px][1],rbconv_Q[cx][1],rbconv_Q[nx][1],pre2_Q[0],pre2_Q[1],pre2_Q[2]); + + // median I channel + for (int j=1; jrow_from) { + for (int j=1; jr(i-1), im->g(i-1), im->b(i-1), rbconv_Y[px], row_I, row_Q, W); + } + } + // blur last 3 row and finalize H-1th row + for (int j=1; jr(row_to-1), im->g(row_to-1), im->b(row_to-1), rbconv_Y[cx], row_I, row_Q, W); + + delete [] row_I; + delete [] row_Q; + delete [] pre1_I; + delete [] pre2_I; + delete [] post1_I; + delete [] post2_I; + delete [] pre1_Q; + delete [] pre2_Q; + delete [] post1_Q; + delete [] post2_Q; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +// correction_YIQ_LQ +void RawImageSource::processFalseColorCorrection (Imagefloat* im, int steps) { + + if (im->height<4) + return; + + for (int t=0; theight-2)/nthreads; + + if (tidheight - 1); + } +#else + processFalseColorCorrectionThread (im, 1 , im->height - 1); +#endif + } +} + +// Some camera input profiles need gamma preprocessing +// gamma is applied before the CMS, correct line fac=lineFac*rawPixel+LineSum after the CMS +void RawImageSource::getProfilePreprocParams(cmsHPROFILE in, float& gammaFac, float& lineFac, float& lineSum) { + gammaFac=0; lineFac=1; lineSum=0; + + char copyright[256]; + copyright[0]=0; + + if (cmsGetProfileInfoASCII(in, cmsInfoCopyright, cmsNoLanguage, cmsNoCountry, copyright, 256)>0) { + if (strstr(copyright,"Phase One")!=NULL) + gammaFac=0.55556; // 1.8 + else if (strstr(copyright,"Nikon Corporation")!=NULL) { + gammaFac=0.5; lineFac=-0.4; lineSum=1.35; // determined in reverse by measuring NX an RT developed colorchecker PNGs + } + } +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +static void +lab2ProphotoRgbD50(float L, float A, float B, float& r, float& g, float& b) +{ + float X; + float Y; + float Z; +#define CLIP01(a) ((a)>0?((a)<1?(a):1):0) + { // convert from Lab to XYZ + float x, y, z, fx, fy, fz; + + fy = (L + 16.0f)/116.0f; + fx = A/500.0f + fy; + fz = fy - B/200.0f; + + if (fy > 24.0f/116.0f) { + y = fy*fy*fy; + } else { + y = (fy - 16.0f/116.0f)/7.787036979f; + } + if (fx > 24.0f/116.0f) { + x = fx*fx*fx; + } else { + x = (fx - 16.0/116.0)/7.787036979f; + } + if (fz > 24.0f/116.0f) { + z = fz*fz*fz; + } else { + z = (fz - 16.0f/116.0f)/7.787036979f; + } + //0.9642, 1.0000, 0.8249 D50 + X = x * 0.9642; + Y = y; + Z = z * 0.8249; + } + r = prophoto_xyz[0][0]*X + prophoto_xyz[0][1]*Y + prophoto_xyz[0][2]*Z; + g = prophoto_xyz[1][0]*X + prophoto_xyz[1][1]*Y + prophoto_xyz[1][2]*Z; + b = prophoto_xyz[2][0]*X + prophoto_xyz[2][1]*Y + prophoto_xyz[2][2]*Z; + r = CLIP01(r); + g = CLIP01(g); + b = CLIP01(b); +} + +// Converts raw image including ICC input profile to working space - floating point version +void RawImageSource::colorSpaceConversion_ (Imagefloat* im, ColorManagementParams &cmp, ColorTemp &wb, double pre_mul[3], cmsHPROFILE embedded, cmsHPROFILE camprofile, double camMatrix[3][3], const std::string &camName) { + +// MyTime t1, t2, t3; +// t1.set (); + cmsHPROFILE in; + DCPProfile *dcpProf; + + if (!findInputProfile(cmp.input, embedded, camName, &dcpProf, in)) { + return; + } + + if (dcpProf!=NULL) { + // DCP processing + dcpProf->Apply(im, cmp.dcpIlluminant, cmp.working, wb, pre_mul, camMatrix, false, cmp.applyHueSatMap, false); + return; + } + + if (in==NULL) { + // use default camprofile, supplied by dcraw + // in this case we avoid using the slllllooooooowwww lcms + + // Calculate matrix for direct conversion raw>working space + TMatrix work = iccStore->workingSpaceInverseMatrix (cmp.working); + double mat[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + mat[i][j] += work[i][k] * camMatrix[k][j]; // rgb_xyz * imatrices.xyz_cam + + + #pragma omp parallel for + for (int i=0; iheight; i++) + for (int j=0; jwidth; j++) { + + float newr = mat[0][0]*im->r(i,j) + mat[0][1]*im->g(i,j) + mat[0][2]*im->b(i,j); + float newg = mat[1][0]*im->r(i,j) + mat[1][1]*im->g(i,j) + mat[1][2]*im->b(i,j); + float newb = mat[2][0]*im->r(i,j) + mat[2][1]*im->g(i,j) + mat[2][2]*im->b(i,j); + + im->r(i,j) = newr; + im->g(i,j) = newg; + im->b(i,j) = newb; + + } + } else { + const bool working_space_is_prophoto = (cmp.working == "ProPhoto"); + + // use supplied input profile + + /* + The goal here is to in addition to user-made custom ICC profiles also support profiles + supplied with other popular raw converters. As curves affect color rendering and + different raw converters deal with them differently (and few if any is as flexible + as RawTherapee) we cannot really expect to get the *exact* same color rendering here. + However we try hard to make the best out of it. + + Third-party input profiles that contain a LUT (usually A2B0 tag) often needs some preprocessing, + as ICC LUTs are not really designed for dealing with linear camera data. Generally one + must apply some sort of curve to get efficient use of the LUTs. Unfortunately how you + should preprocess is not standardized so there are almost as many ways as there are + software makers, and for each one we have to reverse engineer to find out how it has + been done. (The ICC files made for RT has linear LUTs) + + ICC profiles which only contain the XYZ tags (ie only a color matrix) should + (hopefully) not require any pre-processing. + + Some LUT ICC profiles apply a contrast curve and desaturate highlights (to give a "film-like" + behavior. These will generally work with RawTherapee, but will not produce good results when + you enable highlight recovery/reconstruction, as that data is added linearly on top of the + original range. RawTherapee works best with linear ICC profiles. + */ + + enum camera_icc_type { + CAMERA_ICC_TYPE_GENERIC, // Generic, no special pre-processing required, RTs own is this way + CAMERA_ICC_TYPE_PHASE_ONE, // Capture One profiles + CAMERA_ICC_TYPE_LEAF, // Leaf profiles, former Leaf Capture now in Capture One, made for Leaf digital backs + CAMERA_ICC_TYPE_NIKON // Nikon NX profiles + } camera_icc_type = CAMERA_ICC_TYPE_GENERIC; + + float leaf_prophoto_mat[3][3]; + { // identify ICC type + char copyright[256] = ""; + char description[256] = ""; + + cmsGetProfileInfoASCII(in, cmsInfoCopyright, cmsNoLanguage, cmsNoCountry, copyright, 256); + cmsGetProfileInfoASCII(in, cmsInfoDescription, cmsNoLanguage, cmsNoCountry, description, 256); + camera_icc_type = CAMERA_ICC_TYPE_GENERIC; + // Note: order the identification with the most detailed matching first since the more general ones may also match the more detailed + if ((strstr(copyright, "Leaf") != NULL || + strstr(copyright, "Phase One A/S") != NULL || + strstr(copyright, "Kodak") != NULL || + strstr(copyright, "Creo") != NULL) && + (strstr(description,"LF2 ") == description || + strstr(description,"LF3 ") == description || + strstr(description,"LeafLF2") == description || + strstr(description,"LeafLF3") == description || + strstr(description,"LeafLF4") == description || + strstr(description,"MamiyaLF2") == description || + strstr(description,"MamiyaLF3") == description)) + { + camera_icc_type = CAMERA_ICC_TYPE_LEAF; + } else if (strstr(copyright, "Phase One A/S") != NULL) { + camera_icc_type = CAMERA_ICC_TYPE_PHASE_ONE; + } else if (strstr(copyright,"Nikon Corporation")!=NULL) { + camera_icc_type = CAMERA_ICC_TYPE_NIKON; + } + } + + // Initialize transform + cmsHTRANSFORM hTransform; + cmsHPROFILE prophoto = iccStore->workingSpace("ProPhoto"); // We always use Prophoto to apply the ICC profile to minimize problems with clipping in LUT conversion. + bool transform_via_pcs_lab = false; + bool separate_pcs_lab_highlights = false; + lcmsMutex->lock (); + switch (camera_icc_type) { + case CAMERA_ICC_TYPE_PHASE_ONE: + case CAMERA_ICC_TYPE_LEAF: { + // These profiles have a RGB to Lab cLUT, gives gamma 1.8 output, and expects a "film-like" curve on input + transform_via_pcs_lab = true; + separate_pcs_lab_highlights = true; + // We transform to Lab because we can and that we avoid getting an unnecessary unmatched gamma conversion which we would need to revert. + hTransform = cmsCreateTransform (in, TYPE_RGB_FLT, NULL, TYPE_Lab_FLT, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); + for (int i=0; i<3; i++) { + for (int j=0; j<3; j++) { + leaf_prophoto_mat[i][j] = 0; + for (int k=0; k<3; k++) + leaf_prophoto_mat[i][j] += prophoto_xyz[i][k] * camMatrix[k][j]; + } + } + break; + } + case CAMERA_ICC_TYPE_NIKON: + case CAMERA_ICC_TYPE_GENERIC: + default: + hTransform = cmsCreateTransform (in, TYPE_RGB_FLT, prophoto, TYPE_RGB_FLT, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); // NOCACHE is important for thread safety + break; + } + + lcmsMutex->unlock (); + if (hTransform == NULL) { + // Fallback: create transform from camera profile. Should not happen normally. + lcmsMutex->lock (); + hTransform = cmsCreateTransform (camprofile, TYPE_RGB_FLT, prophoto, TYPE_RGB_FLT, INTENT_RELATIVE_COLORIMETRIC, cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE ); + lcmsMutex->unlock (); + } + TMatrix toxyz, torgb; + if (!working_space_is_prophoto) { + toxyz = iccStore->workingSpaceMatrix ("ProPhoto"); + torgb = iccStore->workingSpaceInverseMatrix (cmp.working); //sRGB .. Adobe...Wide... + } + + #ifdef _OPENMP + #pragma omp parallel + #endif + { + AlignedBuffer buffer(im->width*3); + AlignedBuffer hl_buffer(im->width*3); + AlignedBuffer hl_scale(im->width); + #ifdef _OPENMP + #pragma omp for schedule(static) + #endif + for ( int h = 0; h < im->height; ++h ) { + float *p=buffer.data, *pR=im->r(h), *pG=im->g(h), *pB=im->b(h); + + // Apply pre-processing + for ( int w = 0; w < im->width; ++w ) { + float r = *(pR++); + float g = *(pG++); + float b = *(pB++); + + // convert to 0-1 range as LCMS expects that + r /= 65535.0f; + g /= 65535.0f; + b /= 65535.0f; + + float maxc = max(r,g,b); + if (maxc <= 1.0) { + hl_scale.data[w] = 1.0; + } else { + // highlight recovery extend the range past the clip point, which means we can get values larger than 1.0 here. + // LUT ICC profiles only work in the 0-1 range so we scale down to fit and restore after conversion. + hl_scale.data[w] = 1.0 / maxc; + r *= hl_scale.data[w]; + g *= hl_scale.data[w]; + b *= hl_scale.data[w]; + } + + switch (camera_icc_type) { + case CAMERA_ICC_TYPE_PHASE_ONE: + // Here we apply a curve similar to Capture One's "Film Standard" + gamma, the reason is that the LUTs embedded in the + // ICCs are designed to work on such input, and if you provide it with a different curve you don't get as good result. + // We will revert this curve after we've made the color transform. However when we revert the curve, we'll notice that + // highlight rendering suffers due to that the LUT transform don't expand well, therefore we do a less compressed + // conversion too and mix them, this gives us the highest quality and most flexible result. + hl_buffer.data[3*w+0] = pow_F(r, 1.0/1.8); + hl_buffer.data[3*w+1] = pow_F(g, 1.0/1.8); + hl_buffer.data[3*w+2] = pow_F(b, 1.0/1.8); + r = phaseOneIccCurveInv->getVal(r); + g = phaseOneIccCurveInv->getVal(g); + b = phaseOneIccCurveInv->getVal(b); + break; + case CAMERA_ICC_TYPE_LEAF: { + // Leaf profiles expect that the camera native RGB has been converted to Prophoto RGB + float newr = leaf_prophoto_mat[0][0]*r + leaf_prophoto_mat[0][1]*g + leaf_prophoto_mat[0][2]*b; + float newg = leaf_prophoto_mat[1][0]*r + leaf_prophoto_mat[1][1]*g + leaf_prophoto_mat[1][2]*b; + float newb = leaf_prophoto_mat[2][0]*r + leaf_prophoto_mat[2][1]*g + leaf_prophoto_mat[2][2]*b; + hl_buffer.data[3*w+0] = pow_F(newr, 1.0/1.8); + hl_buffer.data[3*w+1] = pow_F(newg, 1.0/1.8); + hl_buffer.data[3*w+2] = pow_F(newb, 1.0/1.8); + r = phaseOneIccCurveInv->getVal(newr); + g = phaseOneIccCurveInv->getVal(newg); + b = phaseOneIccCurveInv->getVal(newb); + break; + } + case CAMERA_ICC_TYPE_NIKON: + // gamma 0.5 + r = sqrtf(r); + g = sqrtf(g); + b = sqrtf(b); + break; + case CAMERA_ICC_TYPE_GENERIC: + default: + // do nothing + break; + } + + *(p++) = r; *(p++) = g; *(p++) = b; + } + + // Run icc transform + cmsDoTransform (hTransform, buffer.data, buffer.data, im->width); + if (separate_pcs_lab_highlights) { + cmsDoTransform (hTransform, hl_buffer.data, hl_buffer.data, im->width); + } + + // Apply post-processing + p=buffer.data; pR=im->r(h); pG=im->g(h); pB=im->b(h); + for ( int w = 0; w < im->width; ++w ) { + + float r, g, b, hr, hg, hb; + + if (transform_via_pcs_lab) { + float L = *(p++); + float A = *(p++); + float B = *(p++); + // profile connection space CIELAB should have D50 illuminant + lab2ProphotoRgbD50(L, A, B, r, g, b); + if (separate_pcs_lab_highlights) { + lab2ProphotoRgbD50(hl_buffer.data[3*w+0], hl_buffer.data[3*w+1], hl_buffer.data[3*w+2], hr, hg, hb); + } + } else { + r = *(p++); + g = *(p++); + b = *(p++); + } + + // restore pre-processing and/or add post-processing for the various ICC types + switch (camera_icc_type) { + default: + break; + case CAMERA_ICC_TYPE_PHASE_ONE: + case CAMERA_ICC_TYPE_LEAF: { + // note the 1/1.8 gamma, it's the gamma that the profile has applied, which we must revert before we can revert the curve + r = phaseOneIccCurve->getVal(pow_F(r, 1.0/1.8)); + g = phaseOneIccCurve->getVal(pow_F(g, 1.0/1.8)); + b = phaseOneIccCurve->getVal(pow_F(b, 1.0/1.8)); + const float mix = 0.25; // may seem a low number, but remember this is linear space, mixing starts 2 stops from clipping + const float maxc = max(r, g, b); + if (maxc > mix) { + float fac = (maxc - mix) / (1.0 - mix); + fac = sqrtf(sqrtf(fac)); // gamma 0.25 to mix in highlight render relatively quick + r = (1.0-fac) * r + fac * hr; + g = (1.0-fac) * g + fac * hg; + b = (1.0-fac) * b + fac * hb; + } + break; + } + case CAMERA_ICC_TYPE_NIKON: { + const float lineFac = -0.4; + const float lineSum = 1.35; + r *= r * lineFac + lineSum; + g *= g * lineFac + lineSum; + b *= b * lineFac + lineSum; + break; + } + } + + // restore highlight scaling if any + if (hl_scale.data[w] != 1.0) { + float fac = 1.0 / hl_scale.data[w]; + r *= fac; + g *= fac; + b *= fac; + } + + // If we don't have ProPhoto as chosen working profile, convert. This conversion is clipless, ie if we convert + // to a small space such as sRGB we may end up with negative values and values larger than max. + if (!working_space_is_prophoto) { + //convert from Prophoto to XYZ + float x = (toxyz[0][0] * r + toxyz[0][1] * g + toxyz[0][2] * b ) ; + float y = (toxyz[1][0] * r + toxyz[1][1] * g + toxyz[1][2] * b ) ; + float z = (toxyz[2][0] * r + toxyz[2][1] * g + toxyz[2][2] * b ) ; + //convert from XYZ to cmp.working (sRGB...Adobe...Wide..) + r = ((torgb[0][0]*x + torgb[0][1]*y + torgb[0][2]*z)) ; + g = ((torgb[1][0]*x + torgb[1][1]*y + torgb[1][2]*z)) ; + b = ((torgb[2][0]*x + torgb[2][1]*y + torgb[2][2]*z)) ; + } + + // return to the 0.0 - 65535.0 range (with possible negative and > max values present) + r *= 65535.0; + g *= 65535.0; + b *= 65535.0; + + *(pR++) = r; *(pG++) = g; *(pB++) = b; + } + } + } // End of parallelization + cmsDeleteTransform(hTransform); + } + +//t3.set (); +// printf ("ICM TIME: %d usec\n", t3.etime(t1)); +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +// Converts raw image including ICC input profile to working space - 16bit int version +/*void RawImageSource::colorSpaceConversion16 (Image16* im, ColorManagementParams cmp, cmsHPROFILE embedded, cmsHPROFILE camprofile, double camMatrix[3][3], std::string camName) { + cmsHPROFILE in; + DCPProfile *dcpProf; + + if (!findInputProfile(cmp.input, embedded, camName, &dcpProf, in)) return; + + if (dcpProf!=NULL) { + dcpProf->Apply(im, (DCPLightType)cmp.preferredProfile, cmp.working, cmp.toneCurve); + } else { + if (in==NULL) { + // Take camprofile from DCRAW + // in this case we avoid using the slllllooooooowwww lcms + TMatrix work = iccStore->workingSpaceInverseMatrix (cmp.working); + double mat[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}}; + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + mat[i][j] += work[i][k] * camMatrix[k][j]; // rgb_xyz * imatrices.xyz_cam + +#pragma omp parallel for + for (int i=0; iheight; i++) + for (int j=0; jwidth; j++) { + + float newr = mat[0][0]*im->r(i,j) + mat[0][1]*im->g(i,j) + mat[0][2]*im->b(i,j); + float newg = mat[1][0]*im->r(i,j) + mat[1][1]*im->g(i,j) + mat[1][2]*im->b(i,j); + float newb = mat[2][0]*im->r(i,j) + mat[2][1]*im->g(i,j) + mat[2][2]*im->b(i,j); + + im->r(i,j) = CLIP((int)newr); + im->g(i,j) = CLIP((int)newg); + im->b(i,j) = CLIP((int)newb); + } + } else { + // Gamma preprocessing + float gammaFac, lineFac, lineSum; + getProfilePreprocParams(in, gammaFac, lineFac, lineSum); + + if (gammaFac>0) { +#pragma omp parallel for + for ( int h = 0; h < im->height; ++h ) + for ( int w = 0; w < im->width; ++w ) { + im->r(h,w)= (int) (pow ((double)(im->r(h,w) / 65535.0), (double)gammaFac) * 65535.0); + im->g(h,w)= (int) (pow ((double)(im->g(h,w) / 65535.0), (double)gammaFac) * 65535.0); + im->b(h,w)= (int) (pow ((double)(im->b(h,w) / 65535.0), (double)gammaFac) * 65535.0); + } + } + + cmsHPROFILE out = iccStore->workingSpace (cmp.working); + //out = iccStore->workingSpaceGamma (wProfile); + lcmsMutex->lock (); + cmsHTRANSFORM hTransform = cmsCreateTransform (in, TYPE_RGB_16, out, TYPE_RGB_16, settings->colorimetricIntent, + cmsFLAGS_NOCACHE); // NOCACHE is important for thread safety + lcmsMutex->unlock (); + + if (hTransform) { + im->ExecCMSTransform(hTransform); + + // There might be Nikon postprocessings + if (lineSum>0) { +#pragma omp parallel for + for ( int h = 0; h < im->height; ++h ) + for ( int w = 0; w < im->width; ++w ) { + im->r(h,w) *= im->r(h,w) * lineFac / 65535.0 + lineSum; + im->g(h,w) *= im->g(h,w) * lineFac / 65535.0 + lineSum; + im->b(h,w) *= im->b(h,w) * lineFac / 65535.0 + lineSum; + } + } + } + else { + lcmsMutex->lock (); + hTransform = cmsCreateTransform (camprofile, TYPE_RGB_16, out, TYPE_RGB_16, + settings->colorimetricIntent, cmsFLAGS_NOCACHE); + lcmsMutex->unlock (); + + im->ExecCMSTransform(hTransform); + } + + cmsDeleteTransform(hTransform); + } + } + //t3.set (); + //printf ("ICM TIME: %d\n", t3.etime(t1)); +}*/ + +// Determine RAW input and output profiles. Returns TRUE on success +bool RawImageSource::findInputProfile(Glib::ustring inProfile, cmsHPROFILE embedded, std::string camName, DCPProfile **dcpProf, cmsHPROFILE& in) { + in=NULL; // cam will be taken on NULL + *dcpProf=NULL; + + if (inProfile == "(none)") return false; + + if (inProfile == "(embedded)" && embedded) { + in = embedded; + } else if (inProfile=="(cameraICC)") { + // DCPs have higher quality, so use them first + *dcpProf=dcpStore->getStdProfile(camName); + if (*dcpProf==NULL) in = iccStore->getStdProfile(camName); + } else if (inProfile!="(camera)" && inProfile!="") { + Glib::ustring normalName=inProfile; + if (!inProfile.compare (0, 5, "file:")) normalName=inProfile.substr(5); + + if (dcpStore->isValidDCPFileName(normalName)) *dcpProf=dcpStore->getProfile(normalName); + if (*dcpProf==NULL) in = iccStore->getProfile (inProfile); + } + + // "in" might be NULL because of "not found". That's ok, we take the cam profile then + + return true; +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +// derived from Dcraw "blend_highlights()" +// very effective to reduce (or remove) the magenta, but with levels of grey ! +void RawImageSource::HLRecovery_blend(float* rin, float* gin, float* bin, int width, float maxval, float* hlmax) + { + const int ColorCount=3; + + // Transform matrixes rgb>lab and back + static const float trans[2][ColorCount][ColorCount] = + { { { 1,1,1 }, { 1.7320508,-1.7320508,0 }, { -1,-1,2 } }, + { { 1,1,1 }, { 1,-1,1 }, { 1,1,-1 } } }; + static const float itrans[2][ColorCount][ColorCount] = + { { { 1,0.8660254,-0.5 }, { 1,-0.8660254,-0.5 }, { 1,0,1 } }, + { { 1,1,1 }, { 1,-1,1 }, { 1,1,-1 } } }; + +#define FOREACHCOLOR for (int c=0; c < ColorCount; c++) + + float minpt=min(hlmax[0],hlmax[1],hlmax[2]);//min of the raw clip points + //float maxpt=max(hlmax[0],hlmax[1],hlmax[2]);//max of the raw clip points + //float medpt=hlmax[0]+hlmax[1]+hlmax[2]-minpt-maxpt;//median of the raw clip points + float maxave=(hlmax[0]+hlmax[1]+hlmax[2])/3;//ave of the raw clip points + //some thresholds: + const float clipthresh = 0.95; + const float fixthresh = 0.5; + const float satthresh = 0.5; + + float clip[3]; + FOREACHCOLOR clip[c]=min(maxave,hlmax[c]); + + // Determine the maximum level (clip) of all channels + const float clippt = clipthresh*maxval; + const float fixpt = fixthresh*minpt; + const float desatpt = satthresh*maxave+(1-satthresh)*maxval; + + for (int col=0; col clippt) break; } + if (c == ColorCount) continue; + + // Initialize cam with raw input [0] and potentially clipped input [1] + FOREACHCOLOR { + lratio += min(rgb[c],clip[c]); + cam[0][c] = rgb[c]; + cam[1][c] = min(cam[0][c],maxval); + } + + // Calculate the lightness correction ratio (chratio) + for (int i=0; i<2; i++) { + FOREACHCOLOR { + lab[i][c]=0; + for (int j=0; j < ColorCount; j++) + lab[i][c] += trans[ColorCount-3][c][j] * cam[i][j]; + } + + sum[i]=0; + for (int c=1; c < ColorCount; c++) + sum[i] += SQR(lab[i][c]); + } + chratio = (sqrt(sum[1]/sum[0])); + + // Apply ratio to lightness in LCH space + for (int c=1; c < ColorCount; c++) + lab[0][c] *= chratio; + + // Transform back from LCH to RGB + FOREACHCOLOR { + cam[0][c]=0; + for (int j=0; j < ColorCount; j++) { + cam[0][c] += itrans[ColorCount-3][c][j] * lab[0][j]; + } + } + FOREACHCOLOR rgb[c] = cam[0][c] / ColorCount; + + // Copy converted pixel back + if (rin[col] > fixpt) { + float rfrac = SQR((min(clip[0],rin[col])-fixpt)/(clip[0]-fixpt)); + rin[col]= min(maxave,rfrac*rgb[0]+(1-rfrac)*rin[col]); + } + if (gin[col] > fixpt) { + float gfrac = SQR((min(clip[1],gin[col])-fixpt)/(clip[1]-fixpt)); + gin[col]= min(maxave,gfrac*rgb[1]+(1-gfrac)*gin[col]); + } + if (bin[col] > fixpt) { + float bfrac = SQR((min(clip[2],bin[col])-fixpt)/(clip[2]-fixpt)); + bin[col]= min(maxave,bfrac*rgb[2]+(1-bfrac)*bin[col]); + } + + lratio /= (rin[col]+gin[col]+bin[col]); + L = (rin[col]+gin[col]+bin[col])/3; + C = lratio * 1.732050808 * (rin[col] - gin[col]); + H = lratio * (2 * bin[col] - rin[col] - gin[col]); + rin[col] = L - H / 6.0 + C / 3.464101615; + gin[col] = L - H / 6.0 - C / 3.464101615; + bin[col] = L + H / 3.0; + + if ((L=(rin[col]+gin[col]+bin[col])/3) > desatpt) { + Lfrac = max(0.0f,(maxave-L)/(maxave-desatpt)); + C = Lfrac * 1.732050808 * (rin[col] - gin[col]); + H = Lfrac * (2 * bin[col] - rin[col] - gin[col]); + rin[col] = L - H / 6.0 + C / 3.464101615; + gin[col] = L - H / 6.0 - C / 3.464101615; + bin[col] = L + H / 3.0; + } + } + } + +void RawImageSource::HLRecovery_Luminance (float* rin, float* gin, float* bin, float* rout, float* gout, float* bout, int width, float maxval) { + + for (int i=0; imaxval || g>maxval || b>maxval) { + float ro = min(r, maxval); + float go = min(g, maxval); + float bo = min(b, maxval); + double L = r + g + b; + double C = 1.732050808 * (r - g); + double H = 2 * b - r - g; + double Co = 1.732050808 * (ro - go); + double Ho = 2 * bo - ro - go; + if (r!=g && g!=b) { + double ratio = sqrt ((Co*Co+Ho*Ho) / (C*C+H*H)); + C *= ratio; + H *= ratio; + } + float rr = L / 3.0 - H / 6.0 + C / 3.464101615; + float gr = L / 3.0 - H / 6.0 - C / 3.464101615; + float br = L / 3.0 + H / 3.0; + rout[i] = rr; + gout[i] = gr; + bout[i] = br; + } + else { + rout[i] = rin[i]; + gout[i] = gin[i]; + bout[i] = bin[i]; + } + } +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void RawImageSource::HLRecovery_CIELab (float* rin, float* gin, float* bin, float* rout, float* gout, float* bout, + int width, float maxval, double xyz_cam[3][3], double cam_xyz[3][3]) { + + //static bool crTableReady = false; + + // lookup table for Lab conversion + // perhaps should be centralized, universally defined so we don't keep remaking it??? + /*for (int ix=0; ix < 0x10000; ix++) { + float rx = ix / 65535.0; + fv[ix] = rx > 0.008856 ? exp(1.0/3 * log(rx)) : 7.787*rx + 16/116.0; + }*/ + //crTableReady = true; + + + for (int i=0; imaxval || g>maxval || b>maxval) { + float ro = min(r, maxval); + float go = min(g, maxval); + float bo = min(b, maxval); + float yy = xyz_cam[1][0]*r + xyz_cam[1][1]*g + xyz_cam[1][2]*b; + float fy = (yy<65535.0 ? ImProcFunctions::cachef[yy]/327.68 : (exp(log(yy/MAXVALD)/3.0 ))); + // compute LCH decompostion of the clipped pixel (only color information, thus C and H will be used) + float x = xyz_cam[0][0]*ro + xyz_cam[0][1]*go + xyz_cam[0][2]*bo; + float y = xyz_cam[1][0]*ro + xyz_cam[1][1]*go + xyz_cam[1][2]*bo; + float z = xyz_cam[2][0]*ro + xyz_cam[2][1]*go + xyz_cam[2][2]*bo; + x = (x<65535.0 ? ImProcFunctions::cachef[x]/327.68 : (exp(log(x/MAXVALD)/3.0 ))); + y = (y<65535.0 ? ImProcFunctions::cachef[y]/327.68 : (exp(log(y/MAXVALD)/3.0 ))); + z = (z<65535.0 ? ImProcFunctions::cachef[z]/327.68 : (exp(log(z/MAXVALD)/3.0 ))); + // convert back to rgb + double fz = fy - y + z; + double fx = fy + x - y; + + double zr = Color::f2xyz(fz); + double xr = Color::f2xyz(fx); + + x = xr*65535.0 ; + y = yy; + z = zr*65535.0 ; + float rr = cam_xyz[0][0]*x + cam_xyz[0][1]*y + cam_xyz[0][2]*z; + float gr = cam_xyz[1][0]*x + cam_xyz[1][1]*y + cam_xyz[1][2]*z; + float br = cam_xyz[2][0]*x + cam_xyz[2][1]*y + cam_xyz[2][2]*z; + rout[i] = (rr); + gout[i] = (gr); + bout[i] = (br); + } + else { + rout[i] = (rin[i]); + gout[i] = (gin[i]); + bout[i] = (bin[i]); + } + } +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void RawImageSource::hlRecovery (std::string method, float* red, float* green, float* blue, int i, int sx1, int width, int skip,const RAWParams &raw, float* hlmax ) { + + if (method=="Luminance") + HLRecovery_Luminance (red, green, blue, red, green, blue, width, 65535.0); + else if (method=="CIELab blending") + HLRecovery_CIELab (red, green, blue, red, green, blue, width, 65535.0, imatrices.xyz_cam, imatrices.cam_xyz); + /*else if (method=="Color") + HLRecovery_ColorPropagation (red, green, blue, i, sx1, width, skip);*/ + else if (method=="Blend") // derived from Dcraw + HLRecovery_blend(red, green, blue, width, 65535.0, hlmax); + +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void RawImageSource::getAutoExpHistogram (LUTu & histogram, int& histcompr) { + + histcompr = 3; + + histogram(65536>>histcompr); + histogram.clear(); + +#pragma omp parallel +{ + LUTu tmphistogram(65536>>histcompr); + tmphistogram.clear(); +#pragma omp for nowait + for (int i=border; igetSensorType()==ST_BAYER) { + for (int j=start; jISGREEN(i,j)) tmphistogram[CLIP((int)(refwb_green*rawData[i][j]))>>histcompr]+=4; + else if (ri->ISRED(i,j)) tmphistogram[CLIP((int)(refwb_red* rawData[i][j]))>>histcompr]+=4; + else if (ri->ISBLUE(i,j)) tmphistogram[CLIP((int)(refwb_blue* rawData[i][j]))>>histcompr]+=4; + } + } else if (ri->getSensorType()==ST_FUJI_XTRANS) { + for (int j=start; jISXTRANSGREEN(i,j)) tmphistogram[CLIP((int)(refwb_green*rawData[i][j]))>>histcompr]+=4; + else if (ri->ISXTRANSRED(i,j)) tmphistogram[CLIP((int)(refwb_red* rawData[i][j]))>>histcompr]+=4; + else if (ri->ISXTRANSBLUE(i,j)) tmphistogram[CLIP((int)(refwb_blue* rawData[i][j]))>>histcompr]+=4; + } + } else if (ri->get_colors() == 1) { + for (int j=start; j>histcompr]++; + } + } else { + for (int j=start; j>histcompr]++; + tmphistogram[CLIP((int)(refwb_green*rawData[i][3*j+1]))>>histcompr]+=2; + tmphistogram[CLIP((int)(refwb_blue* rawData[i][3*j+2]))>>histcompr]++; + } + } + } +#pragma omp critical +{ + for(int i=0; i<(65536>>histcompr);i++) + histogram[i] += tmphistogram[i]; +} +} +} + +// Histogram MUST be 256 in size; gamma is applied, blackpoint and gain also +void RawImageSource::getRAWHistogram (LUTu & histRedRaw, LUTu & histGreenRaw, LUTu & histBlueRaw) { + + histRedRaw.clear(); histGreenRaw.clear(); histBlueRaw.clear(); + const float mult[4] = { 65535.0 / ri->get_white(0), 65535.0 / ri->get_white(1), 65535.0 / ri->get_white(2), 65535.0 / ri->get_white(3) }; + +#ifdef _OPENMP + int numThreads; + // reduce the number of threads under certain conditions to avoid overhaed of too many critical regions + numThreads = sqrt((((H-2*border)*(W-2*border))/262144.f)); + numThreads = std::min(std::max(numThreads,1), omp_get_max_threads()); + +#pragma omp parallel num_threads(numThreads) +#endif +{ + // we need one LUT per color and thread, which corresponds to 1 MB per thread + LUTu tmphist[4]; + tmphist[0](65536);tmphist[0].clear(); + tmphist[1](65536);tmphist[1].clear(); + tmphist[2](65536);tmphist[2].clear(); + tmphist[3](65536);tmphist[3].clear(); + +#ifdef _OPENMP +#pragma omp for nowait +#endif + for (int i=border; igetSensorType()==ST_BAYER) { + int j; + int c1 = FC(i,start); + c1 = ( c1 == 1 && !(i&1) ) ? 3 : c1; + int c2 = FC(i,start+1); + c2 = ( c2 == 1 && !(i&1) ) ? 3 : c2; + for (j=start; jdata[i][j]]++; + tmphist[c2][(int)ri->data[i][j+1]]++; + } + if(jdata[i][j]]++; + } + } else if (ri->get_colors() == 1) { + for (int j=start; jdata[i][j]]++; + } + } + } else if(ri->getSensorType()==ST_FUJI_XTRANS) { + for (int j=start; jXTRANSFC(i,j); + tmphist[c][(int)ri->data[i][j]]++; + } + } else { + for (int j=start; jdata[i][3*j+c]]++; + } + } + } + } +#ifdef _OPENMP +#pragma omp critical +#endif +{ + for(int i=0;i<65536;i++){ + int idx; + idx = CLIP((int)Color::gamma(mult[0]*(i-(cblacksom[0]/*+black_lev[0]*/)))); + histRedRaw[idx>>8] += tmphist[0][i]; + idx = CLIP((int)Color::gamma(mult[1]*(i-(cblacksom[1]/*+black_lev[1]*/)))); + histGreenRaw[idx>>8] += tmphist[1][i]; + idx = CLIP((int)Color::gamma(mult[3]*(i-(cblacksom[3]/*+black_lev[3]*/)))); + histGreenRaw[idx>>8] += tmphist[3][i]; + idx = CLIP((int)Color::gamma(mult[2]*(i-(cblacksom[2]/*+black_lev[2]*/)))); + histBlueRaw[idx>>8] += tmphist[2][i]; + } +} // end of critical region +} // end of parallel region + + + if (ri->getSensorType()==ST_BAYER) // since there are twice as many greens, correct for it + for (int i=0;i<256;i++) + histGreenRaw[i]>>=1; + else if(ri->getSensorType()==ST_FUJI_XTRANS) // since Xtrans has 2.5 as many greens, correct for it + for (int i=0;i<256;i++) + histGreenRaw[i] = (histGreenRaw[i]*2)/5; + + +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void RawImageSource::getRowStartEnd (int x, int &start, int &end) { + if (fuji) { + int fw = ri->get_FujiWidth(); + start = ABS(fw-x) + border; + end = min(H+ W-fw-x, fw+x) - border; + } + else { + start = border; + end = W-border; + } +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + void RawImageSource::getAutoWBMultipliers (double &rm, double &gm, double &bm) { + + if (ri->get_colors() == 1) { + rm = gm = bm = 1; + return; + } + if (redAWBMul != -1.) { + rm = redAWBMul; + gm = greenAWBMul; + bm = blueAWBMul; + return; + } + + if (!isWBProviderReady()) { + rm = -1.0; + gm = -1.0; + bm = -1.0; + return; + } + + double avg_r = 0; + double avg_g = 0; + double avg_b = 0; + int rn = 0, gn = 0, bn = 0; + + if (fuji) { + for (int i=32; iget_FujiWidth(); + int start = ABS(fw-i) + 32; + int end = min(H+W-fw-i, fw+i) - 32; + for (int j=start; jgetSensorType()!=ST_BAYER) { + double dr = CLIP(initialGain*(rawData[i][3*j] )); + double dg = CLIP(initialGain*(rawData[i][3*j+1])); + double db = CLIP(initialGain*(rawData[i][3*j+2])); + if (dr>64000. || dg>64000. || db>64000.) continue; + avg_r += dr; + avg_g += dg; + avg_b += db; + rn = gn = ++bn; + } + else { + int c = FC( i, j); + double d = CLIP(initialGain*(rawData[i][j])); + if (d>64000.) + continue; + // Let's test green first, because they are more numerous + if (c==1) { + avg_g += d; + gn++; + } + else if (c==0) { + avg_r += d; + rn++; + } + else /*if (c==2)*/ { + avg_b += d; + bn++; + } + } + } + } + } + else { + if (ri->getSensorType()!=ST_BAYER) { + if(ri->getSensorType()==ST_FUJI_XTRANS) { + for (int i=32; iISXTRANSRED(i,j)) { + float dr = CLIP(initialGain*(rawData[i][j])); + if (dr>64000.f) + continue; + avg_r += dr; + rn ++; + } + if(ri->ISXTRANSGREEN(i,j)) { + float dg = CLIP(initialGain*(rawData[i][j])); + if (dg>64000.f) + continue; + avg_g += dg; + gn ++; + } + if(ri->ISXTRANSBLUE(i,j)) { + float db = CLIP(initialGain*(rawData[i][j])); + if (db>64000.f) + continue; + avg_b += db; + bn ++; + } + } + } else { + for (int i=32; i64000. || dg>64000. || db>64000.) continue; + avg_r += dr; rn++; + avg_g += dg; + avg_b += db; + } + gn = rn; bn=rn; + } + } else { + //determine GRBG coset; (ey,ex) is the offset of the R subarray + int ey, ex; + if (ri->ISGREEN(0,0)) {//first pixel is G + if (ri->ISRED(0,1)) {ey=0; ex=1;} else {ey=1; ex=0;} + } else {//first pixel is R or B + if (ri->ISRED(0,0)) {ey=0; ex=0;} else {ey=1; ex=1;} + } + double d[2][2]; + for (int i=32; iverbose ) + printf ("AVG: %g %g %g\n", avg_r/rn, avg_g/gn, avg_b/bn); + + // return ColorTemp (pow(avg_r/rn, 1.0/6.0)*img_r, pow(avg_g/gn, 1.0/6.0)*img_g, pow(avg_b/bn, 1.0/6.0)*img_b); + + double reds = avg_r/rn * refwb_red; + double greens = avg_g/gn * refwb_green; + double blues = avg_b/bn * refwb_blue; + + redAWBMul = rm = imatrices.rgb_cam[0][0]*reds + imatrices.rgb_cam[0][1]*greens + imatrices.rgb_cam[0][2]*blues; + greenAWBMul = gm = imatrices.rgb_cam[1][0]*reds + imatrices.rgb_cam[1][1]*greens + imatrices.rgb_cam[1][2]*blues; + blueAWBMul = bm = imatrices.rgb_cam[2][0]*reds + imatrices.rgb_cam[2][1]*greens + imatrices.rgb_cam[2][2]*blues; + } + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + ColorTemp RawImageSource::getSpotWB (std::vector &red, std::vector &green, std::vector &blue, int tran, double equal) { + + int x; int y; + double reds = 0, greens = 0, blues = 0; + int rn = 0; + + if (ri->getSensorType()!=ST_BAYER) { + if(ri->getSensorType()==ST_FUJI_XTRANS) { + int d[9][2] = {{0,0}, {-1,-1}, {-1,0}, {-1,1}, {0,-1}, {0,1}, {1,-1}, {1,0}, {1,1}}; + double rloc, gloc, bloc; + int rnbrs, gnbrs, bnbrs; + for (size_t i=0; i=0 && yv>=0 && xvISXTRANSRED(yv,xv)) { //RED + rloc += (rawData[yv][xv]); + rnbrs++; + continue; + } else if (ri->ISXTRANSBLUE(yv,xv)) { //BLUE + bloc += (rawData[yv][xv]); + bnbrs++; + continue; + } else { // GREEN + gloc += (rawData[yv][xv]); + gnbrs++; + continue; + } + } + } + rloc /= rnbrs; gloc /= gnbrs; bloc /= bnbrs; + if (rloc*initialGain<64000. && gloc*initialGain<64000. && bloc*initialGain<64000.) { + reds += rloc; greens += gloc; blues += bloc; rn++; + } + } + + } else { + int xmin, xmax, ymin, ymax; + int xr, xg, xb, yr, yg, yb; + for (size_t i=0; i52500 || + initialGain*(rawData[yg][3*xg+1])>52500 || + initialGain*(rawData[yb][3*xb+2])>52500) continue; + xmin = min(xr,xg,xb); + xmax = max(xr,xg,xb); + ymin = min(yr,yg,yb); + ymax = max(yr,yg,yb); + if (xmin>=0 && ymin>=0 && xmax=0 && yv>=0 && xv=0 && yv>=0 && xv=0 && yv>=0 && xvget_FujiWidth() * 2 + 1; + h = (H - ri->get_FujiWidth())*2 + 1; + } + int sw = w, sh = h; + if ((tran & TR_ROT) == TR_R90 || (tran & TR_ROT) == TR_R270) { + sw = h; + sh = w; + } + + int ppx = x, ppy = y; + if (tran & TR_HFLIP) + ppx = sw - 1 - x ; + if (tran & TR_VFLIP) + ppy = sh - 1 - y; + + int tx = ppx; + int ty = ppy; + + if ((tran & TR_ROT) == TR_R180) { + tx = w - 1 - ppx; + ty = h - 1 - ppy; + } + else if ((tran & TR_ROT) == TR_R90) { + tx = ppy; + ty = h - 1 - ppx; + } + else if ((tran & TR_ROT) == TR_R270) { + tx = w - 1 - ppy; + ty = ppx; + } + + if (fuji) { + ttx = (tx+ty) / 2; + tty = (ty-tx) / 2 + ri->get_FujiWidth(); + } + else { + ttx = tx; + tty = ty; + } +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +void RawImageSource::inverse33 (const double (*rgb_cam)[3], double (*cam_rgb)[3]) { + double nom = (rgb_cam[0][2]*rgb_cam[1][1]*rgb_cam[2][0] - rgb_cam[0][1]*rgb_cam[1][2]*rgb_cam[2][0] - + rgb_cam[0][2]*rgb_cam[1][0]*rgb_cam[2][1] + rgb_cam[0][0]*rgb_cam[1][2]*rgb_cam[2][1] + + rgb_cam[0][1]*rgb_cam[1][0]*rgb_cam[2][2] - rgb_cam[0][0]*rgb_cam[1][1]*rgb_cam[2][2] ); + cam_rgb[0][0] = (rgb_cam[1][2]*rgb_cam[2][1]-rgb_cam[1][1]*rgb_cam[2][2]) / nom; + cam_rgb[0][1] = -(rgb_cam[0][2]*rgb_cam[2][1]-rgb_cam[0][1]*rgb_cam[2][2]) / nom; + cam_rgb[0][2] = (rgb_cam[0][2]*rgb_cam[1][1]-rgb_cam[0][1]*rgb_cam[1][2]) / nom; + cam_rgb[1][0] = -(rgb_cam[1][2]*rgb_cam[2][0]-rgb_cam[1][0]*rgb_cam[2][2]) / nom; + cam_rgb[1][1] = (rgb_cam[0][2]*rgb_cam[2][0]-rgb_cam[0][0]*rgb_cam[2][2]) / nom; + cam_rgb[1][2] = -(rgb_cam[0][2]*rgb_cam[1][0]-rgb_cam[0][0]*rgb_cam[1][2]) / nom; + cam_rgb[2][0] = (rgb_cam[1][1]*rgb_cam[2][0]-rgb_cam[1][0]*rgb_cam[2][1]) / nom; + cam_rgb[2][1] = -(rgb_cam[0][1]*rgb_cam[2][0]-rgb_cam[0][0]*rgb_cam[2][1]) / nom; + cam_rgb[2][2] = (rgb_cam[0][1]*rgb_cam[1][0]-rgb_cam[0][0]*rgb_cam[1][1]) / nom; +} + +DiagonalCurve* RawImageSource::phaseOneIccCurve; +DiagonalCurve* RawImageSource::phaseOneIccCurveInv; + +void RawImageSource::init () { + + { // Initialize Phase One ICC curves + + /* This curve is derived from TIFFTAG_TRANSFERFUNCTION of a Capture One P25+ image with applied film curve, + exported to TIFF with embedded camera ICC. It's assumed to be similar to most standard curves in + Capture One. It's not necessary to be exactly the same, it's just to be close to a typical curve to + give the Phase One ICC files a good working space. */ + const double phase_one_forward[] = { + 0.0000000000, 0.0000000000, 0.0152590219, 0.0029602502, 0.0305180438, 0.0058899825, 0.0457770657, 0.0087739376, 0.0610360876, 0.0115968566, + 0.0762951095, 0.0143587396, 0.0915541314, 0.0171969177, 0.1068131533, 0.0201876860, 0.1220721752, 0.0232852674, 0.1373311971, 0.0264744030, + 0.1525902190, 0.0297245747, 0.1678492409, 0.0330205234, 0.1831082628, 0.0363775082, 0.1983672847, 0.0397802701, 0.2136263066, 0.0432593271, + 0.2288853285, 0.0467841611, 0.2441443503, 0.0503700313, 0.2594033722, 0.0540474556, 0.2746623941, 0.0577859159, 0.2899214160, 0.0616159304, + 0.3051804379, 0.0655222400, 0.3204394598, 0.0695353628, 0.3356984817, 0.0736552987, 0.3509575036, 0.0778973068, 0.3662165255, 0.0822461280, + 0.3814755474, 0.0867170214, 0.3967345693, 0.0913252461, 0.4119935912, 0.0960860609, 0.4272526131, 0.1009994659, 0.4425116350, 0.1060654612, + 0.4577706569, 0.1113298238, 0.4730296788, 0.1167925536, 0.4882887007, 0.1224841688, 0.5035477226, 0.1284046693, 0.5188067445, 0.1345540551, + 0.5340657664, 0.1409781033, 0.5493247883, 0.1476615549, 0.5645838102, 0.1546501869, 0.5798428321, 0.1619287404, 0.5951018540, 0.1695277333, + 0.6103608759, 0.1774776837, 0.6256198978, 0.1858091096, 0.6408789197, 0.1945525292, 0.6561379416, 0.2037384604, 0.6713969635, 0.2134279393, + 0.6866559854, 0.2236667430, 0.7019150072, 0.2345159075, 0.7171740291, 0.2460517281, 0.7324330510, 0.2583047227, 0.7476920729, 0.2714122225, + 0.7629510948, 0.2854352636, 0.7782101167, 0.3004959182, 0.7934691386, 0.3167620356, 0.8087281605, 0.3343862058, 0.8239871824, 0.3535820554, + 0.8392462043, 0.3745937285, 0.8545052262, 0.3977111467, 0.8697642481, 0.4232547494, 0.8850232700, 0.4515754940, 0.9002822919, 0.4830701152, + 0.9155413138, 0.5190966659, 0.9308003357, 0.5615320058, 0.9460593576, 0.6136263066, 0.9613183795, 0.6807965209, 0.9765774014, 0.7717402914, + 0.9918364233, 0.9052109560, 1.0000000000, 1.0000000000 + }; + std::vector cForwardPoints; + cForwardPoints.push_back(double(DCT_Spline)); // The first value is the curve type + std::vector cInversePoints; + cInversePoints.push_back(double(DCT_Spline)); // The first value is the curve type + for (int i = 0; i < sizeof(phase_one_forward)/sizeof(phase_one_forward[0]); i += 2) { + cForwardPoints.push_back(phase_one_forward[i+0]); + cForwardPoints.push_back(phase_one_forward[i+1]); + cInversePoints.push_back(phase_one_forward[i+1]); + cInversePoints.push_back(phase_one_forward[i+0]); + } + phaseOneIccCurve = new DiagonalCurve(cForwardPoints, CURVES_MIN_POLY_POINTS); + phaseOneIccCurveInv = new DiagonalCurve(cInversePoints, CURVES_MIN_POLY_POINTS); + } +} + +void RawImageSource::cleanup () { + delete phaseOneIccCurve; + delete phaseOneIccCurveInv; +} + + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +//#include "demosaic_algos.cc" + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +//Emil's code +/* + * Now compiled separately + * +#include "fast_demo.cc"//fast demosaic +#include "amaze_demosaic_RT.cc"//AMaZE demosaic +#include "CA_correct_RT.cc"//Emil's CA auto correction +#include "cfa_linedn_RT.cc"//Emil's line denoise +#include "green_equil_RT.cc"//Emil's green channel equilibration +#include "hilite_recon.cc"//Emil's highlight reconstruction + +#include "expo_before_b.cc"//Jacques's exposure before interpolation +*/ +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +#undef PIX_SORT +#undef med3x3 + +} /* namespace */ + +#undef PIX_SORT +#undef med3x3 + diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h new file mode 100644 index 000000000..835a734f4 --- /dev/null +++ b/rtengine/rawimagesource.h @@ -0,0 +1,265 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _RAWIMAGESOURCE_ +#define _RAWIMAGESOURCE_ + +#include "imagesource.h" +#include "dcp.h" +#include "array2D.h" +#include "curves.h" +#include "color.h" +#include "iimage.h" + +#define HR_SCALE 2 + +namespace rtengine { + +// these two functions "simulate" and jagged array, but just use two allocs +template T** allocArray (int W, int H, bool initZero=false) { + + T** t = new T*[H]; + t[0] = new T[H*W]; + + if (initZero) memset(t[0],0,sizeof(T)*W*H); + + for (int i=1; i void freeArray (T** a, int H) { + + delete [] a[0]; + delete [] a; +} + + +template void freeArray2 (T** a, int H) { + //for (int i=0; i rawData; // holds preprocessed pixel values, rowData[i][j] corresponds to the ith row and jth column + + // the interpolated green plane: + array2D green; + // the interpolated red plane: + array2D red; + // the interpolated blue plane: + array2D blue; + + + void hphd_vertical (float** hpmap, int col_from, int col_to); + void hphd_horizontal (float** hpmap, int row_from, int row_to); + void hphd_green (float** hpmap); + void processFalseColorCorrectionThread (Imagefloat* im, int row_from, int row_to); + void hlRecovery (std::string method, float* red, float* green, float* blue, int i, int sx1, int width, int skip, const RAWParams &raw, float* hlmax); + int defTransform (int tran); + void rotateLine (float* line, PlanarPtr &channel, int tran, int i, int w, int h); + void transformRect (PreviewProps pp, int tran, int &sx1, int &sy1, int &width, int &height, int &fw); + void transformPosition (int x, int y, int tran, int& tx, int& ty); + + void updateHLRecoveryMap_ColorPropagation (); + void HLRecovery_ColorPropagation (float* red, float* green, float* blue, int i, int sx1, int width, int skip); + unsigned FC(int row, int col){ return ri->FC(row,col); } + inline void getRowStartEnd (int x, int &start, int &end); + static void getProfilePreprocParams(cmsHPROFILE in, float& gammafac, float& lineFac, float& lineSum); + + + public: + RawImageSource (); + ~RawImageSource (); + + int load (Glib::ustring fname, bool batch = false); + void preprocess (const RAWParams &raw, const LensProfParams &lensProf, const CoarseTransformParams& coarse); + void demosaic (const RAWParams &raw); + void flushRawData (); + void flushRGB (); + void HLRecovery_Global (ToneCurveParams hrp); + void refinement_lassus (int PassCount); + void refinement(int PassCount); + + bool IsrgbSourceModified() {return rgbSourceModified;} // tracks whether cached rgb output of demosaic has been modified + + void processFlatField(const RAWParams &raw, RawImage *riFlatFile, unsigned short black[4]); + void copyOriginalPixels(const RAWParams &raw, RawImage *ri, RawImage *riDark, RawImage *riFlatFile ); + void cfaboxblur (RawImage *riFlatFile, float* cfablur, int boxH, int boxW ); + void scaleColors (int winx,int winy,int winw,int winh, const RAWParams &raw);// raw for cblack + + void getImage (ColorTemp ctemp, int tran, Imagefloat* image, PreviewProps pp, ToneCurveParams hrp, ColorManagementParams cmp, RAWParams raw); + eSensorType getSensorType () { return ri!=NULL ? ri->getSensorType() : ST_NONE; } + ColorTemp getWB () { return camera_wb; } + void getAutoWBMultipliers (double &rm, double &gm, double &bm); + ColorTemp getSpotWB (std::vector &red, std::vector &green, std::vector &blue, int tran, double equal); + bool isWBProviderReady () { return rawData; } + + double getDefGain () { return defGain; } + + double getGamma () { return Color::sRGBGamma; } + + void getFullSize (int& w, int& h, int tr = TR_NONE); + void getSize (int tran, PreviewProps pp, int& w, int& h); + int getRotateDegree() const { return ri->get_rotateDegree(); } + + ImageData* getImageData () { return idata; } + ImageMatrices* getImageMatrices () { return &imatrices; } + bool isRAW() const { return true; } + + void setProgressListener (ProgressListener* pl) { plistener = pl; } + void getAutoExpHistogram (LUTu & histogram, int& histcompr); + void getRAWHistogram (LUTu & histRedRaw, LUTu & histGreenRaw, LUTu & histBlueRaw); + DCPProfile *getDCP(ColorManagementParams cmp, ColorTemp &wb); + + void convertColorSpace(Imagefloat* image, ColorManagementParams cmp, ColorTemp &wb); + static bool findInputProfile(Glib::ustring inProfile, cmsHPROFILE embedded, std::string camName, DCPProfile **dcpProf, cmsHPROFILE& in); + static void colorSpaceConversion (Imagefloat* im, ColorManagementParams cmp, ColorTemp &wb, double pre_mul[3], cmsHPROFILE embedded, cmsHPROFILE camprofile, double cam[3][3], std::string camName) { + colorSpaceConversion_ (im, cmp, wb, pre_mul, embedded, camprofile, cam, camName); + } + static void inverse33 (const double (*coeff)[3], double (*icoeff)[3]); + + void boxblur2(float** src, float** dst, int H, int W, int box ); + void boxblur_resamp(float **src, float **dst, int H, int W, int box, int samp ); + + //void boxblur_resamp(float **red, float **green, float **blue, int H, int W, float thresh[3], float max[3], + // multi_array2D & hfsize, multi_array2D & hilite, int box ); + void HLRecovery_inpaint (float** red, float** green, float** blue); + //void HLRecovery_inpaint (); + + static void HLRecovery_Luminance (float* rin, float* gin, float* bin, float* rout, float* gout, float* bout, int width, float maxval); + static void HLRecovery_CIELab (float* rin, float* gin, float* bin, float* rout, float* gout, float* bout, int width, float maxval, double cam[3][3], double icam[3][3]); + static void HLRecovery_blend (float* rin, float* gin, float* bin, int width, float maxval, float* hlmax); + static void init (); + static void cleanup (); + + protected: + typedef unsigned short ushort; + void processFalseColorCorrection (Imagefloat* i, int steps); + inline void convert_row_to_YIQ (float* r, float* g, float* b, float* Y, float* I, float* Q, int W); + inline void convert_row_to_RGB (float* r, float* g, float* b, float* Y, float* I, float* Q, int W); + + inline void convert_to_cielab_row (float* ar, float* ag, float* ab, float* oL, float* oa, float* ob); + inline void interpolate_row_g (float* agh, float* agv, int i); + inline void interpolate_row_rb (float* ar, float* ab, float* pg, float* cg, float* ng, int i); + inline void interpolate_row_rb_mul_pp (float* ar, float* ab, float* pg, float* cg, float* ng, int i, float r_mul, float g_mul, float b_mul, int x1, int width, int skip); + + int LinEqSolve( int nDim, double* pfMatr, double* pfVect, double* pfSolution);//Emil's CA auto correction + void CA_correct_RT (double cared, double cablue); + void ddct8x8s(int isgn, float a[8][8]); + void processRawWhitepoint (float expos, float preser); // exposure before interpolation + + int interpolateBadPixelsBayer( PixelsMap &bitmapBads ); + int interpolateBadPixelsNColours( PixelsMap &bitmapBads, const int colours ); + int interpolateBadPixelsXtrans( PixelsMap &bitmapBads ); + int findHotDeadPixels( PixelsMap &bpMap, float thresh, bool findHotPixels, bool findDeadPixels ); + + void cfa_linedn (float linenoiselevel);//Emil's line denoise + + void green_equilibrate (float greenthresh);//Emil's green equilibration + + void nodemosaic(bool bw); + void eahd_demosaic(); + void hphd_demosaic(); + void vng4_demosaic(); + void ppg_demosaic(); + void jdl_interpolate_omp(); + void igv_interpolate(int winw, int winh); + void lmmse_interpolate_omp(int winw, int winh, int iterations); + + void amaze_demosaic_RT(int winx, int winy, int winw, int winh);//Emil's code for AMaZE + void fast_demosaic(int winx, int winy, int winw, int winh );//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 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); + void fill_raw( float (*cache )[4], int x0, int y0, float** rawData); + void fill_border( float (*cache )[4], int border, int x0, int y0); + void copy_to_buffer(float (*image2)[3], float (*image)[4]); + void dcb_hid(float (*image)[4], float (*bufferH)[3], float (*bufferV)[3], int x0, int y0); + void dcb_color(float (*image)[4], int x0, int y0); + void dcb_hid2(float (*image)[4], int x0, int y0); + void dcb_map(float (*image)[4], int x0, int y0); + void dcb_correction(float (*image)[4], int x0, int y0); + void dcb_pp(float (*image)[4], int x0, int y0); + void dcb_correction2(float (*image)[4], int x0, int y0); + void restore_from_buffer(float (*image)[4], float (*image2)[3]); + void dcb_refinement(float (*image)[4], int x0, int y0); + void dcb_color_full(float (*image)[4], int x0, int y0, float (*chroma)[2]); + void cielab (const float (*rgb)[3], float* l, float* a, float *b, const int width, const int height, const int labWidth, const float xyz_cam[3][3]); + void xtransborder_interpolate (int border); + void xtrans_interpolate (int passes, bool useCieLab); + void fast_xtrans_interpolate (); + void transLine (float* red, float* green, float* blue, int i, Imagefloat* image, int tran, int imw, int imh, int fw); + void hflip (Imagefloat* im); + void vflip (Imagefloat* im); + +}; +} +#endif diff --git a/rtengine/rawimagesource_i.h b/rtengine/rawimagesource_i.h new file mode 100644 index 000000000..5115a9ec1 --- /dev/null +++ b/rtengine/rawimagesource_i.h @@ -0,0 +1,329 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ + +#ifndef RAWIMAGESOURCE_I_H_INCLUDED +#define RAWIMAGESOURCE_I_H_INCLUDED + +#include "rawimagesource.h" + +#include "curves.h" + +namespace rtengine { + +inline void RawImageSource::convert_row_to_YIQ (float* r, float* g, float* b, float* Y, float* I, float* Q, int W) { + for (int j=0; jthreshold) + oL[j] = cache[(int)y]; + else + oL[j] = float(903.3 * y / MAXVALD); + + oa[j] = float(500.0 * ((x>threshold ? cache[(int)x] : 7.787*x/MAXVALD+16.0/116.0) - (y>threshold ? cache[(int)y] : 7.787*y/MAXVALD+16.0/116.0))); + ob[j] = float(200.0 * ((y>threshold ? cache[(int)y] : 7.787*y/MAXVALD+16.0/116.0) - (z>threshold ? cache[(int)z] : 7.787*z/MAXVALD+16.0/116.0))); + } +} + +inline void RawImageSource::interpolate_row_g (float* agh, float* agv, int i) { + + for (int j=0; jISGREEN(i,j)) { + agh[j] = rawData[i][j]; + agv[j] = rawData[i][j]; + } + else { + int gh=0; + int gv=0; + if (j>1 && jmaxgh) + gh = maxgh; + else if (gh1 && imaxgv) + gv = maxgv; + else if (gvISRED(i,0) || ri->ISRED(i,1)) { + // RGRGR or GRGRGR line + for (int j=0; jISRED(i,j)) { + // red is simple + ar[j] = rawData[i][j]; + // blue: cross interpolation + int b = 0; + int n = 0; + if (i>0 && j>0) { + b += rawData[i-1][j-1] - pg[j-1]; + n++; + } + if (i>0 && j0) { + b += rawData[i+1][j-1] - ng[j-1]; + n++; + } + if (iISBLUE(i,j)) { + // red is simple + ab[j] = rawData[i][j]; + // blue: cross interpolation + int r = 0; + int n = 0; + if (i>0 && j>0) { + r += rawData[i-1][j-1] - pg[j-1]; + n++; + } + if (i>0 && j0) { + r += rawData[i+1][j-1] - ng[j-1]; + n++; + } + if (iISRED(i,0) || ri->ISRED(i,1)) { + // RGRGR or GRGRGR line + for (int j=x1, jx=0; jxISRED(i,j)) { + // red is simple + ar[jx] = r_mul * rawData[i][j]; + // blue: cross interpolation + float b = 0; + int n = 0; + if (i>0 && j>0) { + b += b_mul*rawData[i-1][j-1] - g_mul*pg[j-1]; + n++; + } + if (i>0 && j0) { + b += b_mul*rawData[i+1][j-1] - g_mul*ng[j-1]; + n++; + } + if (iISBLUE(i,j)) { + // red is simple + ab[jx] = b_mul*rawData[i][j]; + // blue: cross interpolation + float r = 0; + int n = 0; + if (i>0 && j>0) { + r += r_mul*rawData[i-1][j-1] - g_mul*pg[j-1]; + n++; + } + if (i>0 && j0) { + r += r_mul*rawData[i+1][j-1] - g_mul*ng[j-1]; + n++; + } + if (i + * + * 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 _RAWMETADATALOCATION_ +#define _RAWMETADATALOCATION_ + +namespace rtengine { + + struct RawMetaDataLocation { + int exifBase; + int ciffBase; + int ciffLength; + }; +} + +#endif + diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc new file mode 100644 index 000000000..d2cf58687 --- /dev/null +++ b/rtengine/refreshmap.cc @@ -0,0 +1,422 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "refreshmap.h" +#include "procevents.h" + +int refreshmap[rtengine::NUMOFEVENTS] = { +ALL, // EvPhotoLoaded, +ALL, // EvProfileLoaded, +ALL, // EvProfileChanged, +ALL, // EvHistoryBrowsed, +RGBCURVE, // EvBrightness, +RGBCURVE, // EvContrast, +RGBCURVE, // EvBlack, +RGBCURVE, // EvExpComp, +RGBCURVE, // EvHLCompr, +RGBCURVE, // EvSHCompr, +RGBCURVE, // EvToneCurve1, +AUTOEXP, // EvAutoExp, +AUTOEXP, // EvClip, +LUMINANCECURVE, // EvLBrightness, +LUMINANCECURVE, // EvLContrast, +LUMINANCECURVE, // EvLBlack, +LUMINANCECURVE, // EvLHLCompr, +LUMINANCECURVE, // EvLSHCompr, +LUMINANCECURVE, // EvLLCurve, +SHARPENING, // EvShrEnabled, +SHARPENING, // EvShrRadius, +SHARPENING, // EvShrAmount, +SHARPENING, // EvShrThresh, +SHARPENING, // EvShrEdgeOnly, +SHARPENING, // EvShrEdgeRadius, +SHARPENING, // EvShrEdgeTolerance, +SHARPENING, // EvShrHaloControl, +SHARPENING, // EvShrHaloAmount, +SHARPENING, // EvShrMethod, +SHARPENING, // EvShrDRadius, +SHARPENING, // EvShrDAmount, +SHARPENING, // EvShrDDamping, +SHARPENING, // EvShrDIterations, +TRANSFORM, // EvLCPUseDist, +DARKFRAME, // EvLCPUseVign, +TRANSFORM, // EvLCPUseCA, +M_VOID, // EvFixedExp +WHITEBALANCE, // EvWBMethod, +WHITEBALANCE, // EvWBTemp, +WHITEBALANCE, // EvWBGreen, +RGBCURVE, // EvToneCurveMode1, +RGBCURVE, // EvToneCurve2, +RGBCURVE, // EvToneCurveMode2, +0, // EvLDNRadius: obsolete, +0, // EvLDNEdgeTolerance: obsolete, +0, // EvCDNEnabled:obsolete, +ALL, // EvBlendCMSMatrix, +RGBCURVE, // EvDCPToneCurve, +ALL, // EvDCPIlluminant, +RETINEX, // EvSHEnabled, +RGBCURVE, // EvSHHighlights, +RGBCURVE, // EvSHShadows, +RGBCURVE, // EvSHHLTonalW, +RGBCURVE, // EvSHSHTonalW, +RGBCURVE, // EvSHLContrast, +RETINEX, // EvSHRadius, +ALL, // EvCTRotate, +ALL, // EvCTHFlip, +ALL, // EvCTVFlip, +TRANSFORM, // EvROTDegree, +TRANSFORM, // EvTransAutoFill, +TRANSFORM, // EvDISTAmount, +ALL, // EvBookmarkSelected, +CROP, // EvCrop, +TRANSFORM, // EvCACorr, +ALLNORAW, // EvHREnabled, +ALLNORAW, // EvHRAmount, +ALLNORAW, // EvHRMethod, +ALL, // EvWProfile, +OUTPUTPROFIL, // EvOProfile, +ALL, // EvIProfile, +TRANSFORM, // EvVignettingAmount, +RGBCURVE, // EvChMixer, +RESIZE, // EvResizeScale, +RESIZE, // EvResizeMethod, +EXIF, // EvExif, +IPTC, // EvIPTC +RESIZE, // EvResizeSpec, +RESIZE, // EvResizeWidth +RESIZE, // EvResizeHeight +RESIZE, // EvResizeEnabled +ALL, // EvProfileChangeNotification +RETINEX, // EvShrHighQuality +TRANSFORM, // EvPerspCorr +DARKFRAME, // EvLCPFile +RGBCURVE, // EvRGBrCurveLumamode +IMPULSEDENOISE, // EvIDNEnabled, +IMPULSEDENOISE, // EvIDNThresh, +ALLNORAW, // EvDPDNEnabled, +ALLNORAW, // EvDPDNLuma, +ALLNORAW, // EvDPDNChroma, +ALLNORAW, // EvDPDNGamma, +DIRPYREQUALIZER, // EvDirPyrEqualizer, +DIRPYREQUALIZER, // EvDirPyrEqlEnabled, +LUMINANCECURVE, // EvLSaturation, +LUMINANCECURVE, // EvLaCurve, +LUMINANCECURVE, // EvLbCurve, +DEMOSAIC, // EvDemosaicMethod +DARKFRAME, // EvPreProcessHotPixel +RGBCURVE, // EvSaturation, +RGBCURVE, // EvHSVEqualizerH, +RGBCURVE, // EvHSVEqualizerS, +RGBCURVE, // EvHSVEqualizerV, +RGBCURVE, // EvHSVEqEnabled, +DEFRINGE, // EvDefringeEnabled, +DEFRINGE, // EvDefringeRadius, +DEFRINGE, // EvDefringeThreshold, +RGBCURVE, // EvHLComprThreshold, +RESIZE, // EvResizeBoundingBox +RESIZE, // EvResizeAppliesTo +LUMINANCECURVE, // EvCBAvoidClip, +LUMINANCECURVE, // EvCBSatLimiter, +LUMINANCECURVE, // EvCBSatLimit, +DEMOSAIC, // EvDemosaicDCBIter +DEMOSAIC, // EvDemosaicFalseColorIter +DEMOSAIC, // EvDemosaicDCBEnhanced +DARKFRAME, // EvPreProcessCARed +DARKFRAME, // EvPreProcessCABlue +DARKFRAME, // EvPreProcessLineDenoise +DARKFRAME, // EvPreProcessGEquilThresh +DARKFRAME, // EvPreProcessAutoCA +DARKFRAME, // EvPreProcessAutoDF +DARKFRAME, // EvPreProcessDFFile +DARKFRAME, // EvPreProcessExpCorrLinear +DARKFRAME, // EvPreProcessExpCorrPH +FLATFIELD, // EvFlatFieldFile, +FLATFIELD, // EvFlatFieldAutoSelect, +FLATFIELD, // EvFlatFieldBlurRadius, +FLATFIELD, // EvFlatFieldBlurType, +TRANSFORM, // EvAutoDIST, +ALLNORAW, // EvDPDNLumCurve, +ALLNORAW, // EvDPDNChromCurve, +GAMMA, // EvGAMMA +GAMMA, // EvGAMPOS +GAMMA, // EvGAMFREE +GAMMA, // EvSLPOS +DARKFRAME, // EvPreProcessExpBlackzero +DARKFRAME, // EvPreProcessExpBlackone +DARKFRAME, // EvPreProcessExpBlacktwo +DARKFRAME, // EvPreProcessExpBlackthree +DARKFRAME, // EvPreProcessExptwoGreen +SHARPENING, // EvSharpenEdgePasses +SHARPENING, // EvSharpenEdgeStrength +SHARPENING, // EvSharpenMicroStrength +SHARPENING, // EvSharpenMicroUniformity +SHARPENING, // EvSharpenEdgeEnabled +SHARPENING, // EvSharpenEdgeThreechannels +SHARPENING, // EvSharpenMicroEnabled +SHARPENING, // EvSharpenMicroMatrix +DEMOSAIC, // EvDemosaicALLEnhanced // Disabled but not removed for now, may be reintroduced some day +RGBCURVE, // EvVibranceEnabled +RGBCURVE, // EvVibrancePastels +RGBCURVE, // EvVibranceSaturated +RGBCURVE, // EvVibranceProtectSkins +RGBCURVE, // EvVibranceAvoidColorShift +RGBCURVE, // EvVibrancePastSatTog +RGBCURVE, // EvVibrancePastSatThreshold +SHARPENING, // EvEPDStrength +SHARPENING, // EvEPDEdgeStopping +SHARPENING, // EvEPDScale +SHARPENING, // EvEPDReweightingIterates +SHARPENING, // EvEPDEnabled +RGBCURVE, // EvRGBrCurve +RGBCURVE, // EvRGBgCurve +RGBCURVE, // EvRGBbCurve +RGBCURVE, // EvNeutralExp +DEMOSAIC|M_PREPROC, // EvDemosaicMethodPreProc +LUMINANCECURVE, // EvLCCurve +LUMINANCECURVE, // EvLCHCurve +RGBCURVE, // EvVibranceSkinTonesCurve +LUMINANCECURVE, // EvLLCCurve +LUMINANCECURVE, // EvLLCredsk +ALLNORAW, // EvDPDNLdetail +LUMINANCECURVE, // EvCATEnabled +LUMINANCECURVE, // EvCATDegree +LUMINANCECURVE, // EvCATMethodsur +LUMINANCECURVE, // EvCATAdapscen +LUMINANCECURVE, // EvCATAdapLum +LUMINANCECURVE, // EvCATMethodWB +LUMINANCECURVE, // EvCATJLight +LUMINANCECURVE, // EvCATChroma +LUMINANCECURVE, // EvCATAutoDegree +LUMINANCECURVE, // EvCATContrast +LUMINANCECURVE, // EvCATSurr +LUMINANCECURVE, // EvCATgamut +LUMINANCECURVE, // EvCATmethodalg +LUMINANCECURVE, // EvCATRstpro +LUMINANCECURVE, // EvCATQbright +LUMINANCECURVE, // EvCATQContrast +LUMINANCECURVE, // EvCATSChroma +LUMINANCECURVE, // EvCATMchroma +LUMINANCECURVE, // EvCAThue +LUMINANCECURVE, // EvCATcurve1 +LUMINANCECURVE, // EvCATcurve2 +LUMINANCECURVE, // EvCATcurvemode1 +LUMINANCECURVE, // EvCATcurvemode2 +LUMINANCECURVE, // EvCATcurve3 +LUMINANCECURVE, // EvCATcurvemode3 +LUMINANCECURVE, // EvCATdatacie +LUMINANCECURVE, // EvCATtonecie +ALLNORAW, // EvDPDNbluechro +ALLNORAW, // EvDPDNperform +ALLNORAW, // EvDPDNmet +DEMOSAIC, // EvDemosaicLMMSEIter +LUMINANCECURVE, // EvCATbadpix +LUMINANCECURVE, // EvCATAutoadap +DEFRINGE, // EvPFCurve +WHITEBALANCE, // EvWBequal +WHITEBALANCE, // EvWBequalbo +TRANSFORM, // EvGradientDegree +TRANSFORM, // EvGradientEnabled +TRANSFORM, // EvPCVignetteStrength +TRANSFORM, // EvPCVignetteEnabled +RGBCURVE, // EvBWChmixEnabled +RGBCURVE, // EvBWred +RGBCURVE, // EvBWgreen +RGBCURVE, // EvBWblue +RGBCURVE, // EvBWredgam +RGBCURVE, // EvBWgreengam +RGBCURVE, // EvBWbluegam +RGBCURVE, // EvBWfilter +RGBCURVE, // EvBWsetting +RGBCURVE, // EvBWoran +RGBCURVE, // EvBWyell +RGBCURVE, // EvBWcyan +RGBCURVE, // EvBWmag +RGBCURVE, // EvBpur +RGBCURVE, // EvBWLuminanceEqual +RGBCURVE, // EvBWChmixEnabledLm +RGBCURVE, // EvBWmethod +RGBCURVE, // EvBWBeforeCurve +RGBCURVE, // EvBWBeforeCurveMode +RGBCURVE, // EvBWAfterCurve +RGBCURVE, // EvBWAfterCurveMode +RGBCURVE, // EvAutoch +NONE, // --unused-- +RGBCURVE, // EvNeutralBW +TRANSFORM, // EvGradientFeather +TRANSFORM, // EvGradientStrength +TRANSFORM, // EvGradientCenter +TRANSFORM, // EvPCVignetteFeather +TRANSFORM, // EvPCVignetteRoundness +TRANSFORM, // EvVignettingRadius, +TRANSFORM, // EvVignettingStrength +TRANSFORM, // EvVignettingCenter +LUMINANCECURVE, // EvLCLCurve +LUMINANCECURVE, // EvLLHCurve +LUMINANCECURVE, // EvLHHCurve +DIRPYREQUALIZER, // EvDirPyrEqualizerThreshold +ALLNORAW, // EvDPDNenhance +RGBCURVE, // EvBWMethodalg +DIRPYREQUALIZER, // EvDirPyrEqualizerSkin +DIRPYREQUALIZER, // EvDirPyrEqlgamutlab +DIRPYREQUALIZER, // EvDirPyrEqualizerHueskin +ALLNORAW, // EvDPDNmedian +ALLNORAW, //EvDPDNmedmet +//DIRPYREQUALIZER // EvDirPyrEqualizeralg +RGBCURVE, // EvColorToningEnabled +RGBCURVE, // EvColorToningColor +RGBCURVE, // EvColorToningOpacity +RGBCURVE, // EvColorToningCLCurve +RGBCURVE, // EvColorToningMethod +//RGBCURVE, // EvColorToningTwocolor +RGBCURVE, // EvColorToningLLCurve +RGBCURVE, // EvColorToningredlow +RGBCURVE, // EvColorToninggreenlow +RGBCURVE, // EvColorToningbluelow +RGBCURVE, // EvColorToningredmed +RGBCURVE, // EvColorToninggreenmed +RGBCURVE, // EvColorToningbluemed +RGBCURVE, // EvColorToningredhigh +RGBCURVE, // EvColorToninggreenhigh +RGBCURVE, // EvColorToningbluehigh +RGBCURVE, // EvColorToningbalance +RGBCURVE, // EvColorToningNeutral +RGBCURVE, // EvColorToningsatlow +RGBCURVE, // EvColorToningsathigh +RGBCURVE, // EvColorToningTwocolor +RGBCURVE, // EvColorToningNeutralcur +RGBCURVE, // EvColorToningLumamode +RGBCURVE, // EvColorToningShadows +RGBCURVE, // EvColorToningHighights +RGBCURVE, // EvColorToningSatProtection +RGBCURVE, // EvColorToningSatThreshold +RGBCURVE, //EvColorToningStrength +RGBCURVE, //EvColorToningautosat +ALLNORAW, //EvDPDNmetmed +ALLNORAW, //EvDPDNrgbmet +ALLNORAW, //EvDPDNpasses +FLATFIELD, // EvFlatFieldClipControl +FLATFIELD, // EvFlatFieldAutoClipControl +DARKFRAME, // EvPreProcessExpBlackRed +DARKFRAME, // EvPreProcessExpBlackGreen +DARKFRAME, // EvPreProcessExpBlackBlue +RGBCURVE, //EvFilmSimulationEnabled +RGBCURVE, //EvFilmSimulationStrength +RGBCURVE, //EvFilmSimulationFilename +ALLNORAW, // EvDPDNLCurve +ALLNORAW, // EvDPDNsmet +DARKFRAME, // EvPreProcessDeadPixel +ALLNORAW, //EvDPDNCCCurve +ALLNORAW, //EvDPDNautochroma +ALLNORAW, // EvDPDNLmet +ALLNORAW, // EvDPDNCmet +ALLNORAW, // EvDPDNC2met +DIRPYREQUALIZER, // EvWavelet +DIRPYREQUALIZER, // EvEnabled +DIRPYREQUALIZER, // EvWavLmethod +DIRPYREQUALIZER, // EvWavCLmethod +DIRPYREQUALIZER, // EvWavDirmethod +DIRPYREQUALIZER, // EvWavtiles +DIRPYREQUALIZER, // EvWavsky +DIRPYREQUALIZER, // EvWavthres +DIRPYREQUALIZER, // EvWavthr +DIRPYREQUALIZER, // EvWavchroma +DIRPYREQUALIZER, // EvWavmedian +DIRPYREQUALIZER, // EvWavunif +DIRPYREQUALIZER, // EvWavSkin +DIRPYREQUALIZER, // EvWavHueSkin +DIRPYREQUALIZER, // EvWavThreshold +DIRPYREQUALIZER, // EvWavlhl +DIRPYREQUALIZER, // EvWavbhl +DIRPYREQUALIZER, // EvWavThresHold2 +DIRPYREQUALIZER, // EvWavavoid +DIRPYREQUALIZER, // EvWavCCCurve +DIRPYREQUALIZER, // EvWavpast +DIRPYREQUALIZER, // EvWavsat +DIRPYREQUALIZER, // EvWavCHmet +DIRPYREQUALIZER, // EvWavHSmet +DIRPYREQUALIZER, // EvWavchro +DIRPYREQUALIZER, // EvWavColor +DIRPYREQUALIZER, // EvWavOpac +DIRPYREQUALIZER, // EvWavsup +DIRPYREQUALIZER, // EvWavTilesmet +DIRPYREQUALIZER, // EvWavrescon +DIRPYREQUALIZER, // EvWavreschro +DIRPYREQUALIZER, // EvWavresconH +DIRPYREQUALIZER, // EvWavthrH +DIRPYREQUALIZER, // EvWavHueskin2 +DIRPYREQUALIZER, // EvWavedgrad +DIRPYREQUALIZER, // EvWavedgval +DIRPYREQUALIZER, // EvWavStrngth +DIRPYREQUALIZER, // EvWavdaubcoeffmet +DIRPYREQUALIZER, // EvWavedgreinf +DIRPYREQUALIZER, // EvWaveletch +DIRPYREQUALIZER, //EvWavCHSLmet +DIRPYREQUALIZER, //EvWavedgcont +DIRPYREQUALIZER, //EvWavEDmet +DIRPYREQUALIZER, //EvWavlev0nois +DIRPYREQUALIZER, //EvWavlev1nois +DIRPYREQUALIZER, //EvWavlev2nois +DIRPYREQUALIZER, //EvWavmedianlev +DIRPYREQUALIZER, //EvWavHHCurve +DIRPYREQUALIZER, //EvWavBackmet +DIRPYREQUALIZER, //EvWavedgedetect +DIRPYREQUALIZER, //EvWavlipst +DIRPYREQUALIZER, //EvWavedgedetectthr +DIRPYREQUALIZER, //EvWavedgedetectthr2 +DIRPYREQUALIZER, //EvWavlinkedg +DIRPYREQUALIZER, //EvWavCHCurve +DARKFRAME, //EvPreProcessHotDeadThresh +SHARPENING, //EvEPDgamma +DIRPYREQUALIZER, //EvWavtmr +DIRPYREQUALIZER, //EvWavTMmet +DIRPYREQUALIZER, //EvWavtmrs +DIRPYREQUALIZER, //EvWavbalance +DIRPYREQUALIZER, //EvWaviter +DIRPYREQUALIZER, //EvWavgamma +DIRPYREQUALIZER, //EvWavCLCurve +DIRPYREQUALIZER, //EvWavopacity +DIRPYREQUALIZER, //EvWavBAmet +DIRPYREQUALIZER, //EvWavopacityWL +RESIZE, // EvPrShrEnabled +RESIZE, // EvPrShrRadius +RESIZE, // EvPrShrAmount +RESIZE, // EvPrShrThresh +RESIZE, // EvPrShrEdgeOnly +RESIZE, // EvPrShrEdgeRadius=375, +RESIZE, // EvPrShrEdgeTolerance=376, +RESIZE, // EvPrShrHaloControl=377, +RESIZE, // EvPrShrHaloAmount=378, +RESIZE, // EvPrShrMethod=379, +RESIZE, // EvPrShrDRadius=380, +RESIZE, // EvPrShrDAmount=381, +RESIZE, // EvPrShrDDamping=382, +RESIZE, // EvPrShrDIterations=383, +DIRPYREQUALIZER, // EvWavcbenab +DIRPYREQUALIZER, // EvWavgreenhigh +DIRPYREQUALIZER, // EvWavbluehigh +DIRPYREQUALIZER, // EvWavgreenmed +DIRPYREQUALIZER, // EvWavbluemed +DIRPYREQUALIZER, // EvWavgreenlow +DIRPYREQUALIZER, // EvWavbluelow +DIRPYREQUALIZER, // EvWavNeutral +RGBCURVE, // EvDCPApplyLookTable, +RGBCURVE, // EvDCPApplyBaselineExposureOffset, +ALL // EvDCPApplyHueSatMap + +}; + diff --git a/rtengine/refreshmap.h b/rtengine/refreshmap.h new file mode 100644 index 000000000..17b96302c --- /dev/null +++ b/rtengine/refreshmap.h @@ -0,0 +1,74 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef __REFRESHMAP__ +#define __REFRESHMAP__ + +// Use M_VOID if you wish to update the proc params without updating the preview at all ! +#define M_VOID (1<<15) +// 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<<14) +// Force high quality +#define M_HIGHQUAL (1<<13) + +// Elementary functions that can be done to +// the preview image when an event occurs +#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_TRANSFORM (1<<6) +#define M_BLURMAP (1<<5) +#define M_AUTOEXP (1<<4) +#define M_RGBCURVE (1<<3) +#define M_LUMACURVE (1<<2) +#define M_LUMINANCE (1<<1) +#define M_COLOR (1<<0) + +// 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_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) // without HIGHQUAL +#define ALL (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) // without HIGHQUAL +#define TRANSFORM (M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define RETINEX (M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define AUTOEXP (M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define RGBCURVE (M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define LUMINANCECURVE (M_LUMACURVE|M_LUMINANCE) +#define SHARPENING M_LUMINANCE +#define IMPULSEDENOISE M_LUMINANCE +#define DEFRINGE M_LUMINANCE +#define WHITEBALANCE (M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define DEMOSAIC (M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define DARKFRAME (M_PREPROC|M_RAW|M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|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_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define DIRPYRDENOISE (M_COLOR|M_LUMINANCE) +#define CROP M_CROP +#define RESIZE M_VOID +#define EXIF M_VOID +#define IPTC M_VOID +#define DIRPYREQUALIZER (M_COLOR|M_LUMINANCE) +#define OUTPUTPROFIL (M_COLOR|M_LUMINANCE) +#define GAMMA (M_COLOR|M_LUMINANCE) +#define MINUPDATE M_MINUPDATE +#define NONE 0 +#define ALLNORAW (M_INIT|M_LINDENOISE|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) + +extern int refreshmap[]; +#endif diff --git a/rtengine/rt_math.h b/rtengine/rt_math.h new file mode 100644 index 000000000..9cdb6828c --- /dev/null +++ b/rtengine/rt_math.h @@ -0,0 +1,70 @@ +#ifndef _MYMATH_ +#define _MYMATH_ +#include +#include + + +namespace rtengine { + static const int MAXVAL = 0xffff; + static const float MAXVALF = float(MAXVAL); // float version of MAXVAL + static const double MAXVALD = double(MAXVAL); // double version of MAXVAL + + template + inline const _Tp SQR (_Tp x) { +// return std::pow(x,2); Slower than: + return (x*x); + } + + template + inline const _Tp& min(const _Tp& a, const _Tp& b) { + return std::min(a,b); + } + + template + inline const _Tp& max(const _Tp& a, const _Tp& b) { + return std::max(a,b); + } + + + template + inline const _Tp LIM(const _Tp& a, const _Tp& b, const _Tp& c) { + return std::max(b,std::min(a,c)); + } + + template + inline const _Tp LIM01(const _Tp& a) { + return std::max(_Tp(0),std::min(a,_Tp(1))); + } + + template + inline const _Tp ULIM(const _Tp& a, const _Tp& b, const _Tp& c) { + return ((b < c) ? LIM(a,b,c) : LIM(a,c,b)); + } + + template + inline const _Tp CLIP(const _Tp& a) { + return LIM(a, static_cast<_Tp>(0), static_cast<_Tp>(MAXVAL)); + } + + + template + inline const _Tp& min(const _Tp& a, const _Tp& b, const _Tp& c) { + return std::min(c,std::min(a,b)); + } + + template + inline const _Tp& max(const _Tp& a, const _Tp& b, const _Tp& c) { + return std::max(c,std::max(a,b)); + } + + template + inline const _Tp& min(const _Tp& a, const _Tp& b, const _Tp& c, const _Tp& d) { + return std::min(d,std::min(c,std::min(a,b))); + } + + template + inline const _Tp& max(const _Tp& a, const _Tp& b, const _Tp& c, const _Tp& d) { + return std::max(d,std::max(c,std::max(a,b))); + } +} +#endif diff --git a/rtengine/rtengine.h b/rtengine/rtengine.h new file mode 100644 index 000000000..46a8a0d6b --- /dev/null +++ b/rtengine/rtengine.h @@ -0,0 +1,474 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _RTENGINE_ +#define _RTENGINE_ + +#include "rt_math.h" +#include "procparams.h" +#include "procevents.h" +#include +#include +#include +#include +#include "../rtexif/rtexif.h" +#include "rawmetadatalocation.h" +#include "iimage.h" +#include "utils.h" +#include "../rtgui/threadutils.h" +#include "settings.h" +#include "LUT.h" +/** + * @file + * This file contains the main functionality of the raw therapee engine. + * + */ + + class EditDataProvider; + +namespace rtengine { + + class IImage8; + class IImage16; + class IImagefloat; + + /** + * This class represents provides functions to obtain exif and IPTC metadata information + * from the image file + */ + class ImageMetaData { + + public: + /** Checks the availability of exif metadata tags. + * @return Returns true if image contains exif metadata tags */ + virtual bool hasExif () const =0; + /** Returns the directory of exif metadata tags. + * @return The directory of exif metadata tags */ + virtual const rtexif::TagDirectory* getExifData () const =0; + /** Checks the availability of IPTC tags. + * @return Returns true if image contains IPTC tags */ + virtual bool hasIPTC () const =0; + /** Returns the directory of IPTC tags. + * @return The directory of IPTC tags */ + virtual const procparams::IPTCPairs getIPTCData () const =0; + /** @return a struct containing the date and time of the image */ + virtual struct tm getDateTime () const =0; + /** @return a timestamp containing the date and time of the image */ + virtual time_t getDateTimeAsTS() const =0; + /** @return the ISO of the image */ + virtual int getISOSpeed () const =0; + /** @return the F number of the image */ + virtual double getFNumber () const =0; + /** @return the focal length used at the exposure */ + virtual double getFocalLen () const =0; + /** @return the focal length in 35mm used at the exposure */ + virtual double getFocalLen35mm () const =0; + /** @return the focus distance in meters, 0=unknown, 10000=infinity */ + virtual float getFocusDist () const =0; + /** @return the shutter speed */ + virtual double getShutterSpeed () const =0; + /** @return the exposure compensation */ + virtual double getExpComp () const =0; + /** @return the maker of the camera */ + virtual std::string getMake () const =0; + /** @return the model of the camera */ + virtual std::string getModel () const =0; + + std::string getCamera () const { return getMake() + " " + getModel(); } + + /** @return the lens on the camera */ + virtual std::string getLens () const =0; + /** @return the orientation of the image */ + virtual std::string getOrientation () 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 */ + static std::string shutterToString (double shutter); + /** Functions to convert between floating point and string representation of shutter and aperture */ + static double apertureFromString (std::string shutter); + /** Functions to convert between floating point and string representation of shutter and aperture */ + static double shutterFromString (std::string shutter); + /** Functions to convert between floating point and string representation of exposure compensation */ + static std::string expcompToString (double expcomp, bool maskZeroexpcomp); + + virtual ~ImageMetaData () {} + + /** 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. + * @return The metadata */ + static ImageMetaData* fromFile (const Glib::ustring& fname, RawMetaDataLocation* rml); + }; + + /** This listener interface is used to indicate the progress of time consuming operations */ + class ProgressListener { + + public: + virtual ~ProgressListener() {} + /** This member function is called when the percentage of the progress has been changed. + * @param p is a number between 0 and 1 */ + virtual void setProgress (double p) {} + /** This member function is called when a textual information corresponding to the progress has been changed. + * @param str is the textual information corresponding to the progress */ + virtual void setProgressStr (Glib::ustring str) {} + /** This member function is called when the state of the processing has been changed. + * @param inProcessing =true if the processing has been started, =false if it has been stopped */ + virtual void setProgressState (bool inProcessing) {} + /** This member function is called when an error occurs during the operation. + * @param descr is the error message */ + virtual void error (Glib::ustring descr) {} + }; + + class ImageSource; + + /** + * This class represents an image loaded into the memory. It is the basis of further processing. + * The embedded icc profile and metadata information can be obtained through this class, too. + */ + class InitialImage { + + public: + /** Returns the file name of the image. + * @return The file name of the image */ + virtual Glib::ustring getFileName () =0; + /** 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; + /** 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. */ + virtual void increaseRef () {} + /** This class has manual reference counting. You have to call this function each time to remove a reference + * (the last one deletes the instance automatically). */ + virtual void decreaseRef () {} + + virtual ~InitialImage () {} + + /** Loads an image into the memory. + * @param fname the name of the file + * @param isRaw shall be true if it is a raw file + * @param errorCode is a pointer to a variable that is set to nonzero if an error happened (output) + * @param pl is a pointer pointing to an object implementing a progress listener. It can be NULL, in this case progress is not reported. + * @return an object representing the loaded and pre-processed image */ + static InitialImage* load (const Glib::ustring& fname, bool isRaw, int* errorCode, ProgressListener* pl = NULL); + }; + + /** When the preview image is ready for display during staged processing (thus the changes have been updated), + * the staged processor notifies the listener class implementing a PreviewImageListener. + * It is important to note that the file passed to the listener can be used in a shared manner (copying it is not + * needed) as long as the mutex corresponding to the image is used every time the image is accessed. + * If the scale of the preview image is >1, no sharpening, no denoising and no cropping is applied, and + * the transform operations (rotate, c/a, vignetting correction) are performed using a faster less quality algorithm. + * The image you get with this listener is created to display on the monitor (monitor profile has been already applied). */ + class PreviewImageListener { + public: + virtual ~PreviewImageListener() {} + /** With this member function the staged processor notifies the listener that it allocated a new + * image to store the end result of the processing. It can be used in a shared manner. + * @param img is a pointer to the image + * @param scale describes the current scaling applied compared to the 100% size (preview scale) + * @param cp holds the coordinates of the current crop rectangle */ + virtual void setImage (IImage8* img, double scale, procparams::CropParams cp) {} + /** With this member function the staged processor notifies the listener that the image passed as parameter + * will be deleted, and no longer used to store the preview image. + * @param img the pointer to the image to be destroyed. The listener has to free the image! */ + virtual void delImage (IImage8* img) {} + /** With this member function the staged processor notifies the listener that the preview image has been updated. + * @param cp holds the coordinates of the current crop rectangle */ + virtual void imageReady (procparams::CropParams cp) {} + }; + + /** When the detailed crop image is ready for display during staged processing (thus the changes have been updated), + * the staged processor notifies the listener class implementing a DetailedCropListener. + * It is important to note that the file passed to the listener can not be used in a shared manner, the class + * implementing this interface has to store a copy of it. */ + class DetailedCropListener { + public: + virtual ~DetailedCropListener() {} + /** With this member function the staged processor notifies the listener that the detailed crop image has been updated. + * @param img is a pointer to the detailed crop image */ + virtual void setDetailedCrop (IImage8* img, IImage8* imgtrue, procparams::ColorManagementParams cmp, + procparams::CropParams cp, int cx, int cy, int cw, int ch, int skip) {} + virtual bool getWindow (int& cx, int& cy, int& cw, int& ch, int& skip) { return false; } + // virtual void setPosition (int x, int y, bool update=true) {} + + }; + + /** This listener is used when the full size of the final image has been changed (e.g. rotated by 90 deg.) */ + class SizeListener { + public: + virtual ~SizeListener() {} + /** This member function is called when the size of the final image has been changed + * @param w is the width of the final image (without cropping) + * @param h is the height of the final image (without cropping) + * @param ow is the width of the final image (without resizing and cropping) + * @param oh is the height of the final image (without resizing and cropping) */ + virtual void sizeChanged (int w, int h, int ow, int oh) {} + }; + + /** This listener is used when the histogram of the final image has changed. */ + class HistogramListener { + public: + virtual ~HistogramListener() {} + /** This member function is called when the histogram of the final image has changed. + * @param histRed is the array of size 256 containing the histogram of the red channel + * @param histGreen is the array of size 256 containing the histogram of the green channel + * @param histBlue is the array of size 256 containing the histogram of the blue channel + * @param histLuma is the array of size 256 containing the histogram of the luminance channel + * other for curves backgrounds, histRAW is RAW without colors */ + virtual void 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) {} + }; + + /** This listener is used when the auto exposure has been recomputed (e.g. when the clipping ratio changed). */ + class AutoExpListener { + public: + virtual ~AutoExpListener() {} + /** This member function is called when the auto exposure has been recomputed. + * @param brightness is the new brightness value (in logarithmic scale) + * @param bright is the new ... + * @param black is the new black level (measured in absolute pixel data) + * @param contrast is the new contrast values + * @param hlcompr is the new highlight recovery amount + * @param hlcomprthresh is the new threshold for hlcompr + * @param hlrecons set to true if HighLight Reconstruction is enabled */ + virtual void autoExpChanged (double brightness, int bright, int contrast, int black, int hlcompr, int hlcomprthresh, bool hlrecons) {} + }; + + class AutoCamListener { + public : + virtual ~AutoCamListener() {} + virtual void autoCamChanged (double ccam) {} + virtual void adapCamChanged (double cadap) {} + }; + + class AutoChromaListener { + public : + virtual ~AutoChromaListener() {} + virtual void chromaChanged (double autchroma, double autred, double autblue) {} + virtual void noiseChanged (double nresid, double highresid) {} + virtual void noiseTilePrev (int tileX, int tileY, int prevX, int prevY, int sizeT, int sizeP) {} + + }; + + class AutoColorTonListener { + public : + virtual ~AutoColorTonListener() {} + virtual void autoColorTonChanged (int bwct, int satthres, int satprot) {} + }; + + class AutoBWListener { + public : + virtual ~AutoBWListener() {} + virtual void BWChanged (double redbw, double greenbw, double bluebw) {} + + }; + + class WaveletListener { + public : + virtual ~WaveletListener() {} + virtual void wavChanged (double nlevel) {} + + }; + + + /** This class represents a detailed part of the image (looking through a kind of window). + * It can be created and destroyed with the appropriate members of StagedImageProcessor. + * Several crops can be assigned to the same image. */ + class DetailedCrop { + public: + virtual ~DetailedCrop() {} + /** Sets the window defining the crop. */ + virtual void setWindow (int cx, int cy, int cw, int ch, int skip) {} + + /** First try to update (threadless update). If it returns false, make a full update */ + virtual bool tryUpdate () { return false; } + /** Perform a full recalculation of the part of the image corresponding to the crop. */ + virtual void fullUpdate () {} + /** Sets the listener of the crop. */ + virtual void setListener (DetailedCropListener* il) {} + /** Destroys the crop. */ + virtual void destroy () {} + }; + + /** This is a staged, cached image processing manager with partial image update support. */ + class StagedImageProcessor { + + public: + /** Returns the inital image corresponding to the image processor. + * @return the inital image corresponding to the image processor */ + virtual InitialImage* getInitialImage () =0; + /** Returns the current processing parameters. + * @param dst is the location where the image processing parameters are copied (it is assumed that the memory is allocated by the caller) */ + virtual void getParams (procparams::ProcParams* dst) =0; + /** An essential member function. Call this when a setting has been changed. This function returns a pointer to the + * processing parameters, that you have to update to reflect the changed situation. When ready, call the paramsUpdateReady + * function to start the image update. + * @param change is the ID of the changed setting */ + virtual procparams::ProcParams* beginUpdateParams () =0; + /** An essential member function. This indicates that you are ready with the update of the processing parameters you got + * with the beginUpdateParams call, so the image can be updated. This function returns immediately. + * The image update starts immediately in the background. If it is ready, the result is passed to a PreviewImageListener + * and to a DetailedCropListener (if enabled). */ + virtual void endUpdateParams (ProcEvent change) =0; + virtual void endUpdateParams (int changeFlags) =0; + // Starts a minimal update + virtual void startProcessing(int changeCode) =0; + /** Stops image processing. When it returns, the image processing is already stopped. */ + virtual void stopProcessing () =0; + /** Sets the scale of the preview image. The larger the number is, the faster the image updates are (typical values are 4-5). + * @param scale is the scale of the preview image */ + virtual void setPreviewScale (int scale) =0; + /** Returns the scale of the preview image. + * @return the current scale of the preview image */ + virtual int getPreviewScale () =0; + /** Returns the full width of the resulting image (in 1:1 scale). + * @return the width of the final image */ + virtual int getFullWidth () =0; + /** Returns the full height of the resulting image (in 1:1 scale). + * @return the height of the final image */ + virtual int getFullHeight () =0; + /** Returns the width of the preview image. + * @return the width of the preview image */ + virtual int getPreviewWidth () =0; + /** Returns the height of the preview image. + * @return the height of the preview image */ + virtual int getPreviewHeight () =0; + + virtual bool updateTryLock() = 0; + + virtual void updateUnLock() = 0; + + /** Creates and returns a Crop instance that acts as a window on the image + * @param editDataProvider pointer to the EditDataProvider that communicates with the EditSubscriber + * @return a pointer to the Crop object that handles the image data trough its own pipeline */ + virtual DetailedCrop* createCrop (::EditDataProvider *editDataProvider, bool isDetailWindow) =0; + + virtual bool getAutoWB (double& temp, double& green, double equal) =0; + virtual void getCamWB (double& temp, double& green) =0; + virtual void getSpotWB (int x, int y, int rectSize, double& temp, double& green) =0; + virtual void getAutoCrop (double ratio, int &x, int &y, int &w, int &h) =0; + + virtual void saveInputICCReference (const Glib::ustring& fname, bool apply_wb) =0; + + virtual void setProgressListener (ProgressListener* l) =0; + virtual void setSizeListener (SizeListener* l) =0; + virtual void delSizeListener (SizeListener* l) =0; + virtual void setAutoExpListener (AutoExpListener* l) =0; + virtual void setHistogramListener (HistogramListener *l) =0; + virtual void setPreviewImageListener (PreviewImageListener* l) =0; + virtual void setAutoCamListener (AutoCamListener* l) =0; + virtual void setAutoBWListener (AutoBWListener* l) =0; + virtual void setAutoColorTonListener (AutoColorTonListener* l) =0; + virtual void setAutoChromaListener (AutoChromaListener* l) =0; + virtual void setWaveletListener (WaveletListener* l) =0; + + virtual ~StagedImageProcessor () {} + + /** Returns a staged, cached image processing manager supporting partial updates + * @param initialImage is a loaded and pre-processed initial image + * @return the staged image processing manager */ + static StagedImageProcessor* create (InitialImage* initialImage); + static void destroy (StagedImageProcessor* sip); + }; + + +/** + * @brief Initializes the RT engine + * @param s is a struct of basic settings + * @param baseDir base directory of RT's installation dir + * @param userSettingsDir RT's base directory in the user's settings dir */ + int init (const Settings* s, Glib::ustring baseDir, Glib::ustring userSettingsDir); + +/** Cleanup the RT engine (static variables) */ + void cleanup (); + +/** Returns the available working profile names + * @return a vector of the available working profile names */ + std::vector getWorkingProfiles (); +/** Returns the available output gammas + * @return a vector of the available gamma names */ + std::vector getGamma (); + + /** This class holds all the necessary informations to accomplish the full processing of the image */ + class ProcessingJob { + + public: + + /** Creates a processing job from a file name. This function always succeeds. It only stores the data into the ProcessingJob class, it does not load + * the image thus it returns immediately. + * @param fname the name of the file + * @param isRaw shall be true if it is a raw file + * @param pparams is a struct containing the processing parameters + * @return an object containing the data above. It can be passed to the functions that do the actual image processing. */ + static ProcessingJob* create (const Glib::ustring& fname, bool isRaw, const procparams::ProcParams& pparams); + + /** Creates a processing job from a file name. This function always succeeds. It only stores the data into the ProcessingJob class, it does not load + * the image thus it returns immediately. This function increases the reference count of the initialImage. If you decide not the process the image you + * have to cancel it by calling the member function void cancel(). If the image is processed the reference count of initialImage is decreased automatically, thus the ProcessingJob + * instance gets invalid. You can not use a ProcessingJob instance to process an image twice. + * @param initialImage is a loaded and pre-processed initial image + * @param pparams is a struct containing the processing parameters + * @return an object containing the data above. It can be passed to the functions that do the actual image processing. */ + static ProcessingJob* create (InitialImage* initialImage, const procparams::ProcParams& pparams); + + /** Cancels and destroys a processing job. The reference count of the corresponding initialImage (if any) is decreased. After the call of this function the ProcessingJob instance + * gets invalid, you must not use it any more. Dont call this function while the job is being processed. + * @param job is the job to destroy */ + static void destroy (ProcessingJob* job); + }; + +/** This function performs all the image processinf steps corresponding to the given ProcessingJob. It returns when it is ready, so it can be slow. + * The ProcessingJob passed becomes invalid, you can not use it any more. + * @param job the ProcessingJob to cancel. + * @param errorCode is the error code if an error occured (e.g. the input image could not be loaded etc.) + * @param pl is an optional ProgressListener if you want to keep track of the progress + * @param tunnelMetaData tunnels IPTC and XMP to output without change + * @return the resulting image, with the output profile applied, exif and iptc data set. You have to save it or you can access the pixel data directly. */ + IImage16* processImage (ProcessingJob* job, int& errorCode, ProgressListener* pl = NULL, bool tunnelMetaData=false, bool flush = false); + +/** This class is used to control the batch processing. The class implementing this interface will be called when the full processing of an + * image is ready and the next job to process is needed. */ + class BatchProcessingListener : public ProgressListener { + public: + /** This function is called when an image gets ready during the batch processing. It has to return with the next job, or with NULL if + * there is no jobs left. + * @param img is the result of the last ProcessingJob + * @return the next ProcessingJob to process */ + virtual ProcessingJob* imageReady (IImage16* img) =0; + virtual void error(Glib::ustring message) =0; + }; +/** This function performs all the image processinf steps corresponding to the given ProcessingJob. It runs in the background, thus it returns immediately, + * When it finishes, it calls the BatchProcessingListener with the resulting image and asks for the next job. It the listener gives a new job, it goes on + * with processing. If no new job is given, it finishes. + * The ProcessingJob passed becomes invalid, you can not use it any more. + * @param job the ProcessingJob to cancel. + * @param bpl is the BatchProcessingListener that is called when the image is ready or the next job is needed. It also acts as a ProgressListener. + * @param tunnelMetaData tunnels IPTC and XMP to output without change */ + void startBatchProcessing (ProcessingJob* job, BatchProcessingListener* bpl, bool tunnelMetaData); + + + extern MyMutex* lcmsMutex; +} + +#endif + diff --git a/rtengine/rtetest.cc b/rtengine/rtetest.cc new file mode 100644 index 000000000..4c3046685 --- /dev/null +++ b/rtengine/rtetest.cc @@ -0,0 +1,70 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "rtengine.h" +#include +//#include +#include + +class PListener : public rtengine::ProgressListener { + + public: + void setProgressStr (Glib::ustring str) { + std::cout << str << std::endl; + } + void setProgress (double p) { + std::cout << p << std::endl; + } +}; + +int main (int argc, char* argv[]) { + + if (argc<4) { + std::cout << "Usage: rtcmd " << std::endl; + exit(1); + } + + rtengine::Settings s; + s.demosaicMethod = "hphd"; + s.colorCorrectionSteps = 2; + s.iccDirectory = ""; + s.colorimetricIntent = 1; + s.monitorProfile = ""; + + Glib::thread_init (); + rtengine::init (s,""); + PListener pl; + + rtengine::InitialImage* ii; + int errorCode; + ii = rtengine::InitialImage::load (argv[1], true, errorCode, &pl); + if (!ii) + ii = rtengine::InitialImage::load (argv[1], false, errorCode, &pl); + if (!ii) { + std::cout << "Input file not supported." << std::endl; + exit(2); + } + + rtengine::procparams::ProcParams params; + params.load (argv[2]); + + rtengine::ProcessingJob* job = ProcessingJob::create (ii, params); + rtengine::IImage16* res = rtengine::processImage (job, errorCode, &pl); + res->saveToFile (argv[3]); +} + diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc new file mode 100644 index 000000000..e76a020c4 --- /dev/null +++ b/rtengine/rtthumbnail.cc @@ -0,0 +1,1696 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "rtengine.h" +#include "rtthumbnail.h" +#include "../rtgui/options.h" +#include "image8.h" +#include +#include "curves.h" +#include +#include "improcfun.h" +#include "colortemp.h" +#include "mytime.h" +#include "utils.h" +#include "iccstore.h" +#include "iccmatrices.h" +#include "rawimagesource.h" +#include "stdimagesource.h" +#include +#include +#include "safekeyfile.h" +#include "safegtk.h" +#include "rawimage.h" +#include "jpeg.h" +#include "../rtgui/ppversion.h" +#include "improccoordinator.h" +#include + + +extern Options options; + +namespace rtengine { +using namespace procparams; + +Thumbnail* Thumbnail::loadFromImage (const Glib::ustring& fname, int &w, int &h, int fixwh, double wbEq, bool inspectorMode) { + + StdImageSource imgSrc; + if (imgSrc.load(fname)) { + return NULL; + } + + ImageIO* img = imgSrc.getImageIO(); + + Thumbnail* tpp = new Thumbnail (); + + unsigned char* data; + img->getEmbeddedProfileData (tpp->embProfileLength, data); + if (data && tpp->embProfileLength) { + tpp->embProfileData = new unsigned char [tpp->embProfileLength]; + memcpy (tpp->embProfileData, data, tpp->embProfileLength); + } + + tpp->scaleForSave = 8192; + tpp->defGain = 1.0; + tpp->gammaCorrected = false; + tpp->isRaw = 0; + memset (tpp->colorMatrix, 0, sizeof(tpp->colorMatrix)); + tpp->colorMatrix[0][0] = 1.0; + tpp->colorMatrix[1][1] = 1.0; + tpp->colorMatrix[2][2] = 1.0; + + if (inspectorMode) { + // Special case, meaning that we want a full sized thumbnail image (e.g. for the Inspector feature) + w = img->width; + h = img->height; + tpp->scale = 1.; + } + else { + if (fixwh==1) { + w = h * img->width / img->height; + tpp->scale = (double)img->height / h; + } + else { + h = w * img->height / img->width; + tpp->scale = (double)img->width / w; + } + } + // bilinear interpolation + if (tpp->thumbImg) { + delete tpp->thumbImg; + tpp->thumbImg = NULL; + } + if (inspectorMode) { + // we want an Image8 + if (img->getType() == rtengine::sImage8) { + // copy the image + Image8 *srcImg = static_cast(img); + Image8 *thImg = new Image8 (w, h); + srcImg->copyData(thImg); + tpp->thumbImg = thImg; + } + else { + // copy the image with a conversion + tpp->thumbImg = resizeTo(w, h, TI_Bilinear, img); + } + } + else { + // we want the same image type than the source file + tpp->thumbImg = resizeToSameType(w, h, TI_Bilinear, img); + + // histogram computation + tpp->aeHistCompression = 3; + tpp->aeHistogram(65536>>tpp->aeHistCompression); + + double avg_r = 0; + double avg_g = 0; + double avg_b = 0; + int n = 0; + + if (img->getType() == rtengine::sImage8) { + Image8 *image = static_cast(img); + image->computeHistogramAutoWB(avg_r, avg_g, avg_b, n, tpp->aeHistogram, tpp->aeHistCompression); + } + else if (img->getType() == sImage16) { + Image16 *image = static_cast(img); + image->computeHistogramAutoWB(avg_r, avg_g, avg_b, n, tpp->aeHistogram, tpp->aeHistCompression); + } + else if (img->getType() == sImagefloat) { + Imagefloat *image = static_cast(img); + image->computeHistogramAutoWB(avg_r, avg_g, avg_b, n, tpp->aeHistogram, tpp->aeHistCompression); + } + else { + printf("loadFromImage: Unsupported image type \"%s\"!\n", img->getType()); + } + + if (n>0) { + ColorTemp cTemp; + + tpp->redAWBMul = avg_r/double(n); + tpp->greenAWBMul = avg_g/double(n); + tpp->blueAWBMul = avg_b/double(n); + tpp->wbEqual = wbEq; + + cTemp.mul2temp (tpp->redAWBMul, tpp->greenAWBMul, tpp->blueAWBMul, tpp->wbEqual, tpp->autoWBTemp, tpp->autoWBGreen); + } + + tpp->init (); + } + + return tpp; +} + +Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, RawMetaDataLocation& rml, int &w, int &h, int fixwh, bool rotate, bool inspectorMode) +{ + RawImage *ri= new RawImage(fname); + int r = ri->loadRaw(false,false); + if( r ) + { + delete ri; + return NULL; + } + + rml.exifBase = ri->get_exifBase(); + rml.ciffBase = ri->get_ciffBase(); + rml.ciffLength = ri->get_ciffLen(); + + Image8* img = new Image8 (); + // No sample format detection occurred earlier, so we set them here, + // as they are mandatory for the setScanline method + img->setSampleFormat(IIOSF_UNSIGNED_CHAR); + img->setSampleArrangement(IIOSA_CHUNKY); + + int err = 1; + + // see if it is something we support + if ( ri->is_supportedThumb() ) + { + const char* data((const char*)fdata(ri->get_thumbOffset(),ri->get_file())); + if ( (unsigned char)data[1] == 0xd8 ) + { + err = img->loadJPEGFromMemory(data,ri->get_thumbLength()); + } + else + { + err = img->loadPPMFromMemory(data,ri->get_thumbWidth(),ri->get_thumbHeight(),ri->get_thumbSwap(),ri->get_thumbBPS()); + } + } + + // did we succeed? + if ( err ) + { + printf("Could not extract thumb from %s\n",fname.data()); + delete img; + delete ri; + return NULL; + } + + Thumbnail* tpp = new Thumbnail (); + + tpp->isRaw = 1; + memset (tpp->colorMatrix, 0, sizeof(tpp->colorMatrix)); + tpp->colorMatrix[0][0] = 1.0; + tpp->colorMatrix[1][1] = 1.0; + tpp->colorMatrix[2][2] = 1.0; + + if (inspectorMode) { + // Special case, meaning that we want a full sized thumbnail image (e.g. for the Inspector feature) + w = img->width; + h = img->height; + tpp->scale = 1.; + } + else { + if (fixwh==1) { + w = h * img->width / img->height; + tpp->scale = (double)img->height / h; + } + else { + h = w * img->height / img->width; + tpp->scale = (double)img->width / w; + } + } + + if (tpp->thumbImg) { + delete tpp->thumbImg; + tpp->thumbImg = NULL; + } + if (inspectorMode) { + tpp->thumbImg = img; + } + else { + tpp->thumbImg = resizeTo(w, h, TI_Nearest, img); + delete img; + } + + if (rotate && ri->get_rotateDegree() > 0) { + std::string fname = ri->get_filename(); + std::string suffix = fname.length() > 4 ? fname.substr(fname.length()-3) : ""; + for (int i = 0; i < suffix.length(); i++) suffix[i] = std::tolower(suffix[i]); + // Leaf .mos, Mamiya .mef and Phase One .iiq files have thumbnails already rotated. + if (suffix != "mos" && suffix != "mef" && suffix != "iiq") { + tpp->thumbImg->rotate(ri->get_rotateDegree()); + // width/height may have changed after rotating + w = tpp->thumbImg->width; + h = tpp->thumbImg->height; + } + } + + if (!inspectorMode) + tpp->init (); + + delete ri; + + return tpp; +} + +#define FISRED(filter,row,col) \ + ((filter >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)==0 || !filter) +#define FISGREEN(filter,row,col) \ + ((filter >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)==1 || !filter) +#define FISBLUE(filter,row,col) \ + ((filter >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)==2 || !filter) + +RawMetaDataLocation Thumbnail::loadMetaDataFromRaw (const Glib::ustring& fname) +{ + RawMetaDataLocation rml; + rml.exifBase = -1; + rml.ciffBase = -1; + rml.ciffLength = -1; + + RawImage ri(fname); + int r = ri.loadRaw(false); + if( !r ){ + rml.exifBase = ri.get_exifBase(); + rml.ciffBase = ri.get_ciffBase(); + rml.ciffLength = ri.get_ciffLen(); + } + return rml; +} + +Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocation& rml, int &w, int &h, int fixwh, double wbEq, bool rotate) +{ + RawImage *ri= new RawImage (fname); + int r = ri->loadRaw(1,0); + if( r ){ + delete ri; + return NULL; + } + int width = ri->get_width(); + int height = ri->get_height(); + rtengine::Thumbnail* tpp = new rtengine::Thumbnail; + + tpp->isRaw = true; + tpp->embProfile = NULL; + tpp->embProfileData = NULL; + tpp->embProfileLength = ri->get_profileLen(); + if (ri->get_profileLen()) + tpp->embProfile = cmsOpenProfileFromMem(ri->get_profile(), + ri->get_profileLen()); //\ TODO check if mutex is needed + + tpp->redMultiplier = ri->get_pre_mul(0); + tpp->greenMultiplier = ri->get_pre_mul(1); + tpp->blueMultiplier = ri->get_pre_mul(2); + + ri->scale_colors(); + ri->pre_interpolate(); + + rml.exifBase = ri->get_exifBase(); + rml.ciffBase = ri->get_ciffBase(); + rml.ciffLength = ri->get_ciffLen(); + + tpp->camwbRed = tpp->redMultiplier / ri->get_pre_mul(0); + tpp->camwbGreen = tpp->greenMultiplier / ri->get_pre_mul(1); + tpp->camwbBlue = tpp->blueMultiplier / ri->get_pre_mul(2); + tpp->defGain= 1.0/ min(ri->get_pre_mul(0), ri->get_pre_mul(1), ri->get_pre_mul(2)); + tpp->gammaCorrected = true; + + unsigned filter = ri->get_filters(); + int firstgreen = 1; + // locate first green location in the first row + if(ri->getSensorType()==ST_BAYER) + while (!FISGREEN(filter,1,firstgreen)) + firstgreen++; + + int skip = 1; + if (ri->get_FujiWidth() != 0){ + if (fixwh == 1) // fix height, scale width + skip = ((ri->get_height() - ri->get_FujiWidth()) / sqrt(0.5) - firstgreen - 1) / h; + else + skip = (ri->get_FujiWidth()/sqrt(0.5) - firstgreen - 1) / w; + }else{ + if (fixwh == 1) // fix height, scale width + skip = (ri->get_height() - firstgreen - 1) / h; + else + skip = (ri->get_width() - firstgreen - 1) / w; + } + if (skip % 2) + skip--; + if (skip < 1) + skip = 1; + + int hskip = skip, vskip = skip; + if (!ri->get_model().compare("D1X")) + hskip *= 2; + + int rofs = 0; + int tmpw = (width - 2) / hskip; + int tmph = (height - 2) / vskip; + + DCraw::dcrawImage_t image = ri->get_image(); + + Imagefloat* tmpImg = new Imagefloat(tmpw, tmph); + if (ri->getSensorType()==ST_BAYER) { + // demosaicing! (sort of) + for (int row = 1, y = 0; row < height - 1 && y < tmph; row += vskip, y++) { + rofs = row * width; + for (int col = firstgreen, x = 0; col < width - 1 && x < tmpw; col+= hskip, x++) { + int ofs = rofs + col; + int g = image[ofs][1]; + int r, b; + if (FISRED(filter,row,col+1)) { + r = (image[ofs + 1 ][0] + image[ofs - 1 ][0]) >> 1; + b = (image[ofs + width][2] + image[ofs - width][2]) >> 1; + } else { + b = (image[ofs + 1 ][2] + image[ofs - 1 ][2]) >> 1; + r = (image[ofs + width][0] + image[ofs - width][0]) >> 1; + } + tmpImg->r(y,x) = r; + tmpImg->g(y,x) = g; + tmpImg->b(y,x) = b; + } + } + } else if (ri->get_colors() == 1) { + for (int row = 1, y = 0; row < height - 1 && y < tmph; row += vskip, y++) { + rofs = row * width; + for (int col = firstgreen, x = 0; col < width - 1 && x < tmpw; col + += hskip, x++) { + int ofs = rofs + col; + tmpImg->r(y,x) = tmpImg->g(y,x) = tmpImg->b(y,x) = image[ofs][0]; + } + } + } else { + if(ri->getSensorType()==ST_FUJI_XTRANS) { + for( int row=1, y = 0; row < height-1 && y < tmph; row+=vskip, y++) { + rofs = row * width; + for( int col=1, x = 0; col < width-1 && x < tmpw; col+=hskip, x++ ) { + int ofs = rofs + col; + float sum[3] = {}; + int c; + for(int v=-1;v<=1;v++) { + for(int h=-1;h<=1;h++) { + c = ri->XTRANSFC(row+v,col+h); + sum[c] += image[ofs + v*width + h][c]; + } + } + c = ri->XTRANSFC(row,col); + + switch (c) { + case 0: tmpImg->r(y,x) = image[ofs][0]; tmpImg->g(y,x) = sum[1] / 5.f; tmpImg->b(y,x) = sum[2] / 3.f; break; + case 1: tmpImg->r(y,x) = sum[0] / 2.f; tmpImg->g(y,x) = image[ofs][1]; tmpImg->b(y,x) = sum[2] / 2.f; break; + case 2: tmpImg->r(y,x) = sum[0] / 3.f; tmpImg->g(y,x) = sum[1] / 5.f; tmpImg->b(y,x) = image[ofs][2]; break; + } + } + } + } else { + int iwidth = ri->get_iwidth(); + int iheight = ri->get_iheight(); + int left_margin = ri->get_leftmargin(); + firstgreen += left_margin; + int top_margin = ri->get_topmargin(); + for (int row = 1 + top_margin, y = 0; row < iheight + top_margin - 1 && y < tmph; row += vskip, y++) { + rofs = row * iwidth; + for (int col = firstgreen, x = 0; col < iwidth + left_margin - 1 && x < tmpw; col += hskip, x++) { + int ofs = rofs + col; + tmpImg->r(y,x) = image[ofs][0]; + tmpImg->g(y,x) = image[ofs][1]; + tmpImg->b(y,x) = image[ofs][2]; + } + } + } + } + + if (ri->get_FujiWidth() != 0) { + int fw = ri->get_FujiWidth() / hskip; + double step = sqrt(0.5); + int wide = fw / step; + int high = (tmph - fw) / step; + Imagefloat* fImg = new Imagefloat(wide, high); + float r, c; + + for (int row = 0; row < high; row++) + for (int col = 0; col < wide; col++) { + unsigned ur = r = fw + (row - col) * step; + unsigned uc = c = (row + col) * step; + if (ur > tmph - 2 || uc > tmpw - 2) + continue; + double fr = r - ur; + double fc = c - uc; + fImg->r(row,col) = (tmpImg->r(ur,uc)*(1-fc) + tmpImg->r(ur,uc + 1)*fc) * (1-fr) + (tmpImg->r(ur + 1,uc)*(1-fc) + tmpImg->r(ur + 1,uc + 1)*fc) * fr; + fImg->g(row,col) = (tmpImg->g(ur,uc)*(1-fc) + tmpImg->g(ur,uc + 1)*fc) * (1-fr) + (tmpImg->g(ur + 1,uc)*(1-fc) + tmpImg->g(ur + 1,uc + 1)*fc) * fr; + fImg->b(row,col) = (tmpImg->b(ur,uc)*(1-fc) + tmpImg->b(ur,uc + 1)*fc) * (1-fr) + (tmpImg->b(ur + 1,uc)*(1-fc) + tmpImg->b(ur + 1,uc + 1)*fc) * fr; + } + delete tmpImg; + tmpImg = fImg; + tmpw = wide; + tmph = high; + } + + if (fixwh == 1) // fix height, scale width + w = tmpw * h / tmph; + else + h = tmph * w / tmpw; + + if (tpp->thumbImg) delete tpp->thumbImg; tpp->thumbImg = NULL; + tpp->thumbImg = resizeTo(w, h, TI_Bilinear, tmpImg); + delete tmpImg; + + + if (ri->get_FujiWidth() != 0) + tpp->scale = (double) (height - ri->get_FujiWidth()) / sqrt(0.5) / h; + else + tpp->scale = (double) height / h; + + // generate histogram for auto exposure + tpp->aeHistCompression = 3; + tpp->aeHistogram(65536 >> tpp->aeHistCompression); + tpp->aeHistogram.clear(); + int radd = 4; + int gadd = 4; + int badd = 4; + if (!filter) + radd = gadd = badd = 1; + 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; + + for (int i = 32; i < height - 32; i++) { + int start, end; + if (ri->get_FujiWidth() != 0) { + int fw = ri->get_FujiWidth(); + start = ABS(fw-i) + 32; + end = min(height + width-fw-i, fw+i) - 32; + } else { + start = 32; + end = width - 32; + } + if(ri->getSensorType()==ST_BAYER) { + 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++; + } + } + } else if(ri->getSensorType()==ST_FUJI_XTRANS) { + for (int j = start; j < end; j++) { + if (ri->ISXTRANSGREEN(i,j)) { + double d = tpp->defGain * image[i * width + j][1]; + if (d > 64000.) + continue; + avg_g += d; + gn++; + } + else if (ri->ISXTRANSRED(i,j)) { + double d = tpp->defGain * image[i * width + j][0]; + if (d > 64000.) + continue; + avg_r += d; + rn++; + } + else if (ri->ISXTRANSBLUE(i,j)) { + double d = tpp->defGain * image[i * width + j][2]; + if (d > 64000.) + continue; + 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++; + } + d = tpp->defGain * image[i * width + j][1]; + if (d <= 64000.) { + avg_g += d; + gn++; + } + d = tpp->defGain * image[i * width + j][2]; + if (d <= 64000.) { + avg_b += d; + bn++; + } + } + } + } + + double reds = avg_r / rn * tpp->camwbRed; + double greens = avg_g / gn * tpp->camwbGreen; + double blues = avg_b / bn * 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; + tpp->blueAWBMul = ri->get_rgb_cam(2, 0) * reds + ri->get_rgb_cam(2, 1) * greens + ri->get_rgb_cam(2, 2) * blues; + tpp->wbEqual = wbEq; + + ColorTemp cTemp; + cTemp.mul2temp(tpp->redAWBMul, tpp->greenAWBMul, tpp->blueAWBMul, tpp->wbEqual, tpp->autoWBTemp, tpp->autoWBGreen); + + if (rotate && ri->get_rotateDegree() > 0) { + tpp->thumbImg->rotate(ri->get_rotateDegree()); + } + + for (int a = 0; a < 3; a++) + for (int b = 0; b < 3; b++) + tpp->colorMatrix[a][b] = ri->get_rgb_cam(a, b); + + tpp->init(); + delete ri; + return tpp; +} +#undef FISRED +#undef FISGREEN +#undef FISBLUE + + +unsigned short *Thumbnail::igammatab = 0; +unsigned char *Thumbnail::gammatab = 0; + +void Thumbnail::initGamma () { + igammatab = new unsigned short[256]; + gammatab = new unsigned char[65536]; + for (int i=0; i<256; i++) + igammatab[i] = (unsigned short)(255.0*pow((double)i/255.0,Color::sRGBGamma)); + for (int i=0; i<65536; i++) + gammatab[i] = (unsigned char)(255.0*pow((double)i/65535.0,1.f/Color::sRGBGamma)); +} + +void Thumbnail::cleanupGamma () { + delete [] igammatab; + delete [] gammatab; +} + +void Thumbnail::init () { + + RawImageSource::inverse33 (colorMatrix, iColorMatrix); + //colorMatrix is rgb_cam + memset (cam2xyz, 0, sizeof(cam2xyz)); + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + cam2xyz[i][j] += xyz_sRGB[i][k] * colorMatrix[k][j]; + camProfile = iccStore->createFromMatrix (cam2xyz, false, "Camera"); +} + +Thumbnail::Thumbnail () : + camProfile(NULL), thumbImg(NULL), + camwbRed(1.0), camwbGreen(1.0), camwbBlue(1.0), + redAWBMul(-1.0), greenAWBMul(-1.0), blueAWBMul(-1.0), + autoWBTemp(2700), autoWBGreen(1.0), wbEqual(-1.0), + embProfileLength(0), embProfileData(NULL), embProfile(NULL), + redMultiplier(1.0), greenMultiplier(1.0), blueMultiplier(1.0), + defGain(1.0), + scaleForSave(8192), + gammaCorrected(false), + aeHistCompression(3) { +} + +Thumbnail::~Thumbnail () { + + delete thumbImg; + //delete [] aeHistogram; + delete [] embProfileData; + if (embProfile) + cmsCloseProfile(embProfile); + if (camProfile) + cmsCloseProfile(camProfile); +} + +// Simple processing of RAW internal JPGs +IImage8* Thumbnail::quickProcessImage (const procparams::ProcParams& params, int rheight, rtengine::TypeInterpolation interp, double& myscale) { + + int rwidth; + if (params.coarse.rotate==90 || params.coarse.rotate==270) { + rwidth = rheight; + rheight = thumbImg->height * rwidth / thumbImg->width; + } + else + rwidth = thumbImg->width * rheight / thumbImg->height; + + Image8* baseImg = resizeTo(rwidth, rheight, interp, thumbImg); + + if (params.coarse.rotate) + baseImg->rotate (params.coarse.rotate); + + if (params.coarse.hflip) + baseImg->hflip (); + + if (params.coarse.vflip) + baseImg->vflip (); + return baseImg; +} + +// 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) { + // check if the WB's equalizer value has changed + if (wbEqual < (params.wb.equal-5e-4) || wbEqual > (params.wb.equal+5e-4)) { + wbEqual = params.wb.equal; + // recompute the autoWB + ColorTemp cTemp; + cTemp.mul2temp (redAWBMul, greenAWBMul, blueAWBMul, wbEqual, autoWBTemp, autoWBGreen); + } + // compute WB multipliers + ColorTemp currWB = ColorTemp (params.wb.temperature, params.wb.green, params.wb.equal,params.wb.method); + if (params.wb.method=="Camera") { + //recall colorMatrix is rgb_cam + double cam_r = colorMatrix[0][0]*camwbRed + colorMatrix[0][1]*camwbGreen + colorMatrix[0][2]*camwbBlue; + double cam_g = colorMatrix[1][0]*camwbRed + colorMatrix[1][1]*camwbGreen + colorMatrix[1][2]*camwbBlue; + double cam_b = colorMatrix[2][0]*camwbRed + colorMatrix[2][1]*camwbGreen + colorMatrix[2][2]*camwbBlue; + currWB = ColorTemp (cam_r, cam_g, cam_b, params.wb.equal); + } + else if (params.wb.method=="Auto") + currWB = ColorTemp (autoWBTemp, autoWBGreen, wbEqual, "Custom"); + double r, g, b; + currWB.getMultipliers (r, g, b); + //iColorMatrix is cam_rgb + double rm = iColorMatrix[0][0]*r + iColorMatrix[0][1]*g + iColorMatrix[0][2]*b; + double gm = iColorMatrix[1][0]*r + iColorMatrix[1][1]*g + iColorMatrix[1][2]*b; + double bm = iColorMatrix[2][0]*r + iColorMatrix[2][1]*g + iColorMatrix[2][2]*b; + rm = camwbRed / rm; + gm = camwbGreen / gm; + bm = camwbBlue / bm; + double mul_lum = 0.299*rm + 0.587*gm + 0.114*bm; + double logDefGain = log(defGain) / log(2.0); + int rmi, gmi, bmi; + // Since HL recovery is not rendered in thumbs +// if (!isRaw || !params.toneCurve.hrenabled) { + logDefGain = 0.0; + rmi = 1024.0 * rm * defGain / mul_lum; + gmi = 1024.0 * gm * defGain / mul_lum; + bmi = 1024.0 * bm * defGain / mul_lum; +/* } + else { + rmi = 1024.0 * rm / mul_lum; + gmi = 1024.0 * gm / mul_lum; + bmi = 1024.0 * bm / mul_lum; + }*/ + + // The RAW exposure is not reflected since it's done in preprocessing. If we only have e.g. the chached thumb, + // that is already preprocessed. So we simulate the effect here roughly my modifying the exposure accordingly + if (isRaw && fabs(1.0-params.raw.expos)>0.001) { + rmi*=params.raw.expos; + gmi*=params.raw.expos; + bmi*=params.raw.expos; + } + + // resize to requested width and perform coarse transformation + int rwidth; + if (params.coarse.rotate==90 || params.coarse.rotate==270) { + rwidth = rheight; + rheight = int(size_t(thumbImg->height) * size_t(rwidth) / size_t(thumbImg->width)); + } + else + rwidth = int(size_t(thumbImg->width) * size_t(rheight) / size_t(thumbImg->height)); + + Imagefloat* baseImg = resizeTo(rwidth, rheight, interp, thumbImg); + + if (params.coarse.rotate) { + baseImg->rotate (params.coarse.rotate); + rwidth = baseImg->width; + rheight = baseImg->height; + } + + if (params.coarse.hflip) + baseImg->hflip (); + + if (params.coarse.vflip) + baseImg->vflip (); + + // apply white balance and raw white point (simulated) + int val; + unsigned short val_; + for (int i=0; iconvertTo(baseImg->r(i,j), val_); + val = static_cast(val_)*rmi>>10; + baseImg->r(i,j) = CLIP(val); + + baseImg->convertTo(baseImg->g(i,j), val_); + val = static_cast(val_)*gmi>>10; + baseImg->g(i,j) = CLIP(val); + + baseImg->convertTo(baseImg->b(i,j), val_); + val = static_cast(val_)*bmi>>10; + baseImg->b(i,j) = CLIP(val); + } + +/* + // apply highlight recovery, if needed -- CURRENTLY BROKEN DUE TO INCOMPATIBLE DATA TYPES, BUT HL RECOVERY AREN'T COMPUTED FOR THUMBNAILS ANYWAY... + if (isRaw && params.toneCurve.hrenabled) { + int maxval = 65535 / defGain; + if (params.toneCurve.method=="Luminance" || params.toneCurve.method=="Color") + for (int i=0; ir[i], baseImg->g[i], baseImg->b[i], baseImg->r[i], baseImg->g[i], baseImg->b[i], rwidth, maxval); + else if (params.toneCurve.method=="CIELab blending") { + double icamToD50[3][3]; + RawImageSource::inverse33 (cam2xyz, icamToD50); + for (int i=0; ir[i], baseImg->g[i], baseImg->b[i], baseImg->r[i], baseImg->g[i], baseImg->b[i], rwidth, maxval, cam2xyz, icamToD50); + } + } +*/ + + // if luma denoise has to be done for thumbnails, it should be right here + + // perform color space transformation + if (isRaw) { + double pre_mul[3] = { redMultiplier, greenMultiplier, blueMultiplier }; + RawImageSource::colorSpaceConversion (baseImg, params.icm, currWB, pre_mul, embProfile, camProfile, cam2xyz, camName ); + } else { + StdImageSource::colorSpaceConversion (baseImg, params.icm, embProfile, thumbImg->getSampleFormat()); + } + + int fw = baseImg->width; + int fh = baseImg->height; + //ColorTemp::CAT02 (baseImg, ¶ms) ;//perhaps not good! + + ImProcFunctions ipf (¶ms, false); + ipf.setScale (sqrt(double(fw*fw+fh*fh))/sqrt(double(thumbImg->width*thumbImg->width+thumbImg->height*thumbImg->height))*scale); + + LUTu hist16 (65536); + LUTu hist16C (65536); + + double gamma = isRaw ? Color::sRGBGamma : 0; // usually in ImageSource, but we don't have that here + ipf.firstAnalysis (baseImg, ¶ms, hist16); + + // perform transform + if (ipf.needsTransform()) { + Imagefloat* trImg = new Imagefloat (fw, fh); + int origFW; + int origFH; + double tscale; + 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, 0, true); // Raw rotate degree not detectable here + delete baseImg; + baseImg = trImg; + } + + // update blurmap + SHMap* shmap = NULL; + if (params.sh.enabled) { + shmap = new SHMap (fw, fh, false); + double radius = sqrt (double(fw*fw+fh*fh)) / 2.0; + double shradius = params.sh.radius; + if (!params.sh.hq) shradius *= radius / 1800.0; + shmap->update (baseImg, shradius, ipf.lumimul, params.sh.hq, 16); + } + + // RGB processing + double expcomp = params.toneCurve.expcomp; + int bright = params.toneCurve.brightness; + int contr = params.toneCurve.contrast; + int black = params.toneCurve.black; + int hlcompr = params.toneCurve.hlcompr; + int hlcomprthresh = params.toneCurve.hlcomprthresh; + + if (params.toneCurve.autoexp && aeHistogram) { + ipf.getAutoExp (aeHistogram, aeHistCompression, logDefGain, params.toneCurve.clip, expcomp, bright, contr, black, hlcompr, hlcomprthresh); + //ipf.getAutoExp (aeHistogram, aeHistCompression, logDefGain, params.toneCurve.clip, params.toneCurve.expcomp, params.toneCurve.brightness, params.toneCurve.contrast, params.toneCurve.black, params.toneCurve.hlcompr); + } + + LUTf curve1 (65536); + LUTf curve2 (65536); + LUTf curve (65536); + LUTf satcurve (65536); + LUTf lhskcurve (65536); + LUTf clcurve (65536); + LUTf clToningcurve (65536); + LUTf cl2Toningcurve (65536); + + LUTf rCurve (65536); + LUTf gCurve (65536); + LUTf bCurve (65536); + + LUTu dummy; + + ToneCurve customToneCurve1, customToneCurve2; + ColorGradientCurve ctColorCurve; + OpacityCurve ctOpacityCurve; + // NoisCurve dnNoisCurve; + + ColorAppearance customColCurve1; + ColorAppearance customColCurve2; + ColorAppearance customColCurve3; + ToneCurve customToneCurvebw1; + ToneCurve customToneCurvebw2; + + ipf.g = gamma; + ipf.iGamma = true; + CurveFactory::complexCurve (0.0, black/65535.0, hlcompr, hlcomprthresh, + params.toneCurve.shcompr, bright, contr, ipf.g, !ipf.iGamma, + params.toneCurve.curveMode, params.toneCurve.curve, + params.toneCurve.curveMode2, params.toneCurve.curve2, + hist16, dummy, curve1, curve2, curve, dummy, customToneCurve1, customToneCurve2, 16); + + CurveFactory::RGBCurve (params.rgbCurves.rcurve, rCurve, 16); + CurveFactory::RGBCurve (params.rgbCurves.gcurve, gCurve, 16); + CurveFactory::RGBCurve (params.rgbCurves.bcurve, bCurve, 16); + + TMatrix wprof = iccStore->workingSpaceMatrix (params.icm.working); + double wp[3][3] = { + {wprof[0][0],wprof[0][1],wprof[0][2]}, + {wprof[1][0],wprof[1][1],wprof[1][2]}, + {wprof[2][0],wprof[2][1],wprof[2][2]}}; + TMatrix wiprof = iccStore->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]} + }; + bool opautili=false; + params.colorToning.getCurves(ctColorCurve, ctOpacityCurve, wp, wip, opautili); + //params.dirpyrDenoise.getCurves(dnNoisCurve, lldenoisutili); + + bool clctoningutili=false; + bool llctoningutili=false; + CurveFactory::curveToningCL(clctoningutili, params.colorToning.clcurve, clToningcurve,scale==1 ? 1 : 16); + CurveFactory::curveToningLL(llctoningutili, params.colorToning.cl2curve, cl2Toningcurve, scale==1 ? 1 : 16); + + CurveFactory::curveBW (params.blackwhite.beforeCurve, params.blackwhite.afterCurve, hist16, dummy, customToneCurvebw1, customToneCurvebw2, 16); + + double rrm, ggm, bbm; + float autor, autog, autob; + float satLimit = float(params.colorToning.satProtectionThreshold)/100.f*0.7f+0.3f; + float satLimitOpacity = 1.f-(float(params.colorToning.saturatedOpacity)/100.f); + + if(params.colorToning.enabled && params.colorToning.autosat){//for colortoning evaluation of saturation settings + float moyS=0.f; + float eqty=0.f; + ipf.moyeqt (baseImg, moyS, eqty);//return image : mean saturation and standard dev of saturation + //printf("moy=%f ET=%f\n", moyS,eqty); + float satp=((moyS+1.5f*eqty)-0.3f)/0.7f;//1.5 sigma ==> 93% pixels with high saturation -0.3 / 0.7 convert to Hombre scale + if(satp >= 0.92f) satp=0.92f;//avoid values too high (out of gamut) + if(satp <= 0.15f) satp=0.15f;//avoid too low values + + satLimit= 100.f*satp; + + satLimitOpacity= 100.f*(moyS-0.85f*eqty);//-0.85 sigma==>20% pixels with low saturation + } + + autor = autog = autob = -9000.f; // This will ask to compute the "auto" values for the B&W tool + + LabImage* labView = new LabImage (fw,fh); + DCPProfile *dcpProf = NULL; + if (isRaw) { + cmsHPROFILE dummy; + RawImageSource::findInputProfile(params.icm.input, NULL, camName, &dcpProf, dummy); + if (dcpProf != NULL) { + dcpProf->setStep2ApplyState(params.icm.working, params.icm.toneCurve, params.icm.applyLookTable, params.icm.applyBaselineExposureOffset); + } + } + ipf.rgbProc (baseImg, labView, NULL, curve1, curve2, curve, shmap, params.toneCurve.saturation, rCurve, gCurve, bCurve, satLimit ,satLimitOpacity, ctColorCurve, ctOpacityCurve, opautili, clToningcurve, cl2Toningcurve, customToneCurve1, customToneCurve2, customToneCurvebw1, customToneCurvebw2,rrm, ggm, bbm, autor, autog, autob, expcomp, hlcompr, hlcomprthresh, dcpProf); + + // freeing up some memory + customToneCurve1.Reset(); + customToneCurve2.Reset(); + ctColorCurve.Reset(); + ctOpacityCurve.Reset(); + // dnNoisCurve.Reset(); + customToneCurvebw1.Reset(); + customToneCurvebw2.Reset(); + + if (shmap) + delete shmap; + + // luminance histogram update + hist16.clear();hist16C.clear(); + for (int i=0; iL[i][j])))]++; + hist16C[CLIP((int)sqrt(labView->a[i][j]*labView->a[i][j] + labView->b[i][j]*labView->b[i][j]))]++; + } + // luminance processing +// ipf.EPDToneMap(labView,0,6); + + bool utili=false; + bool autili=false; + bool butili=false; + bool ccutili=false; + bool cclutili=false; + bool clcutili=false; + + CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve, + hist16, hist16, curve, dummy, 16, utili); + + CurveFactory::curveCL(clcutili, params.labCurve.clcurve, clcurve, hist16C, dummy, 16); + + CurveFactory::complexsgnCurve (1.f, autili, butili, ccutili, cclutili,params.labCurve.chromaticity, params.labCurve.rstprotection, + params.labCurve.acurve, params.labCurve.bcurve,params.labCurve.cccurve,params.labCurve.lccurve, curve1, curve2, satcurve,lhskcurve, + hist16C, hist16C, dummy, dummy, + 16); + //ipf.luminanceCurve (labView, labView, curve); + + + ipf.chromiLuminanceCurve (NULL, 1,labView, labView, curve1, curve2, satcurve,lhskcurve, clcurve, curve, utili, autili, butili, ccutili,cclutili, clcutili, dummy, dummy, dummy, dummy); + + ipf.vibrance(labView); + + if((params.colorappearance.enabled && !params.colorappearance.tonecie) || !params.colorappearance.enabled) ipf.EPDToneMap(labView,5,6); + + //if(!params.colorappearance.enabled){ipf.EPDToneMap(labView,5,6);} + + CurveFactory::curveLightBrightColor ( + params.colorappearance.curveMode, params.colorappearance.curve, + params.colorappearance.curveMode2, params.colorappearance.curve2, + params.colorappearance.curveMode3, params.colorappearance.curve3, + hist16, hist16, dummy, + hist16C, dummy, + customColCurve1, + customColCurve2, + customColCurve3, + 16); + + if(params.colorappearance.enabled){ + int begh = 0, endh = labView->H; + bool execsharp=false; + float d; + 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) + //if no exif data or wrong + adap=2000.f; + else { + float E_V = fcomp + log2 ((fnum*fnum) / fspeed / (fiso/100.f)); + float expo2= params.toneCurve.expcomp;// exposure compensation in tonecurve ==> direct EV + E_V += expo2; + float expo1;//exposure raw white point + expo1=log2(params.raw.expos);//log2 ==>linear to EV + E_V += expo1; + adap= powf(2.f, E_V-3.f);//cd / m2 + //end calculation adaptation scene luminosity + } + + LUTf CAMBrightCurveJ; + LUTf CAMBrightCurveQ; + float CAMMean; + int sk; + int scale; + sk=16; + int rtt=0; + CieImage* cieView = new CieImage (fw,fh); + ipf.ciecam_02float (cieView, adap, begh, endh, 1, 2, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 6, execsharp, d, sk, rtt); + delete cieView; + } + // color processing + //ipf.colorCurve (labView, labView); + + // obtain final image + Image8* readyImg = new Image8 (fw, fh); + ipf.lab2monitorRgb (labView, readyImg); + delete labView; + delete baseImg; + // calculate scale + if (params.coarse.rotate==90 || params.coarse.rotate==270) + myscale = scale * thumbImg->width / fh; + else + myscale = scale * thumbImg->height / fh; + + myscale = 1.0 / myscale; +/* // apply crop + if (params.crop.enabled) { + int ix = 0; + for (int i=0; i(params.crop.y+params.crop.h)/myscale || j(params.crop.x+params.crop.w)/myscale) { + readyImg->data[ix++] /= 3; + readyImg->data[ix++] /= 3; + readyImg->data[ix++] /= 3; + } + else + ix += 3; + }*/ + + return readyImg; +} + +int Thumbnail::getImageWidth (const procparams::ProcParams& params, int rheight, float &ratio) { + if (thumbImg==NULL) return 0; // Can happen if thumb is just building and GUI comes in with resize wishes + + int rwidth; + if (params.coarse.rotate==90 || params.coarse.rotate==270) { + ratio = (float)(thumbImg->height) / (float)(thumbImg->width); + } + else { + ratio = (float)(thumbImg->width) / (float)(thumbImg->height); + } + rwidth = (int)(ratio * (float)rheight); + + return rwidth; +} + +void Thumbnail::getDimensions (int& w, int& h, double& scaleFac) { + if (thumbImg) { + w=thumbImg->width; h=thumbImg->height; scaleFac=scale; + } else { + w=0; h=0; scale=1; + } +} + +void Thumbnail::getCamWB (double& temp, double& green) { + + double cam_r = colorMatrix[0][0]*camwbRed + colorMatrix[0][1]*camwbGreen + colorMatrix[0][2]*camwbBlue; + double cam_g = colorMatrix[1][0]*camwbRed + colorMatrix[1][1]*camwbGreen + colorMatrix[1][2]*camwbBlue; + double cam_b = colorMatrix[2][0]*camwbRed + colorMatrix[2][1]*camwbGreen + colorMatrix[2][2]*camwbBlue; + ColorTemp currWB = ColorTemp (cam_r, cam_g, cam_b, 1.0); // we do not take the equalizer into account here, because we want camera's WB + temp = currWB.getTemp (); + green = currWB.getGreen (); +} + +void Thumbnail::getAutoWB (double& temp, double& green, double equal) { + + if (equal != wbEqual) { + // compute the values depending on equal + ColorTemp cTemp; + wbEqual = equal; + // compute autoWBTemp and autoWBGreen + cTemp.mul2temp(redAWBMul, greenAWBMul, blueAWBMul, wbEqual, autoWBTemp, autoWBGreen); + } + temp = autoWBTemp; + green = autoWBGreen; +} + +void Thumbnail::getAutoWBMultipliers (double& rm, double& gm, double& bm) { + rm = redAWBMul; + gm = greenAWBMul; + bm = blueAWBMul; +} + +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, + params.toneCurve.brightness, params.toneCurve.contrast, params.toneCurve.black, params.toneCurve.hlcompr, params.toneCurve.hlcomprthresh); + } +} + +void Thumbnail::getSpotWB (const procparams::ProcParams& params, int xp, int yp, int rect, double& rtemp, double& rgreen) { + + std::vector points, red, green, blue; + for (int i=yp-rect; i<=yp+rect; i++) + for (int j=xp-rect; j<=xp+rect; j++) + points.push_back (Coord2D (j, i)); + + int fw = thumbImg->width, fh = thumbImg->height; + if (params.coarse.rotate==90 || params.coarse.rotate==270) { + fw = thumbImg->height; + fh = thumbImg->width; + } + ImProcFunctions ipf (¶ms, false); + ipf.transCoord (fw, fh, points, red, green, blue); + int tr = getCoarseBitMask(params.coarse); + // calculate spot wb (copy & pasted from stdimagesource) + double reds = 0, greens = 0, blues = 0; + int rn = 0, gn = 0, bn = 0; + thumbImg->getSpotWBData(reds, greens, blues, rn, gn, bn, red, green, blue, tr); + reds = reds/rn * camwbRed; + greens = greens/gn * camwbGreen; + blues = blues/bn * camwbBlue; + + double rm = colorMatrix[0][0]*reds + colorMatrix[0][1]*greens + colorMatrix[0][2]*blues; + double gm = colorMatrix[1][0]*reds + colorMatrix[1][1]*greens + colorMatrix[1][2]*blues; + double bm = colorMatrix[2][0]*reds + colorMatrix[2][1]*greens + colorMatrix[2][2]*blues; + + ColorTemp ct (rm, gm, bm, params.wb.equal); + rtemp = ct.getTemp (); + rgreen = ct.getGreen (); +} +void Thumbnail::transformPixel (int x, int y, int tran, int& tx, int& ty) { + + int W = thumbImg->width; + int H = thumbImg->height; + int sw = W, sh = H; + if ((tran & TR_ROT) == TR_R90 || (tran & TR_ROT) == TR_R270) { + sw = H; + sh = W; + } + + int ppx = x, ppy = y; + if (tran & TR_HFLIP) + ppx = sw - 1 - x ; + if (tran & TR_VFLIP) + ppy = sh - 1 - y; + + tx = ppx; + ty = ppy; + + if ((tran & TR_ROT) == TR_R180) { + tx = W - 1 - ppx; + ty = H - 1 - ppy; + } + else if ((tran & TR_ROT) == TR_R90) { + tx = ppy; + ty = H - 1 - ppx; + } + else if ((tran & TR_ROT) == TR_R270) { + tx = W - 1 - ppy; + ty = ppx; + } + tx/=scale; + ty/=scale; +} + +unsigned char* Thumbnail::getGrayscaleHistEQ (int trim_width) { + if (!thumbImg) + return NULL; + + if (thumbImg->widthheight*trim_width]; + int ix = 0,max; + + if (gammaCorrected) { + // if it's gamma correct (usually a RAW), we have the problem that there is a lot noise etc. that makes the maximum way too high. + // Strategy is limit a certain percent of pixels so the overall picture quality when scaling to 8 bit is way better + const double BurnOffPct=0.03; // *100 = percent pixels that may be clipped + + // Calc the histogram + unsigned int* hist16 = new unsigned int [65536]; + memset(hist16,0,sizeof(int)*65536); + + if (thumbImg->getType() == sImage8) { + Image8 *image = static_cast(thumbImg); + image->calcGrayscaleHist(hist16); + } + else if (thumbImg->getType() == sImage16) { + Image16 *image = static_cast(thumbImg); + image->calcGrayscaleHist(hist16); + } + else if (thumbImg->getType() == sImagefloat) { + Imagefloat *image = static_cast(thumbImg); + image->calcGrayscaleHist(hist16); + } + else { + printf("getGrayscaleHistEQ #1: Unsupported image type \"%s\"!\n", thumbImg->getType()); + } + + // Go down till we cut off that many pixels + unsigned long cutoff = thumbImg->height * thumbImg->height * 4 * BurnOffPct; + + int max_; + unsigned long sum=0; + for (max_=65535; max_>16384 && sumgetType() == sImage8) { + Image8 *image = static_cast(thumbImg); + for (int i=0; iheight; i++) + for (int j=(thumbImg->width-trim_width)/2; jwidth-trim_width)/2; j++) { + unsigned short r_, g_, b_; + image->convertTo(image->r(i,j), r_); + image->convertTo(image->g(i,j), g_); + image->convertTo(image->b(i,j), b_); + int r= gammatab[min(r_,static_cast(max_)) * scaleForSave >> 13]; + int g= gammatab[min(g_,static_cast(max_)) * scaleForSave >> 13]; + int b= gammatab[min(b_,static_cast(max_)) * scaleForSave >> 13]; + tmpdata[ix++] = (r*19595+g*38469+b*7472) >> 16; + } + } + else if (thumbImg->getType() == sImage16) { + Image16 *image = static_cast(thumbImg); + for (int i=0; iheight; i++) + for (int j=(thumbImg->width-trim_width)/2; jwidth-trim_width)/2; j++) { + unsigned short r_, g_, b_; + image->convertTo(image->r(i,j), r_); + image->convertTo(image->g(i,j), g_); + image->convertTo(image->b(i,j), b_); + int r= gammatab[min(r_,static_cast(max_)) * scaleForSave >> 13]; + int g= gammatab[min(g_,static_cast(max_)) * scaleForSave >> 13]; + int b= gammatab[min(b_,static_cast(max_)) * scaleForSave >> 13]; + tmpdata[ix++] = (r*19595+g*38469+b*7472) >> 16; + } + } + else if (thumbImg->getType() == sImagefloat) { + Imagefloat *image = static_cast(thumbImg); + for (int i=0; iheight; i++) + for (int j=(thumbImg->width-trim_width)/2; jwidth-trim_width)/2; j++) { + unsigned short r_, g_, b_; + image->convertTo(image->r(i,j), r_); + image->convertTo(image->g(i,j), g_); + image->convertTo(image->b(i,j), b_); + int r= gammatab[min(r_,static_cast(max_)) * scaleForSave >> 13]; + int g= gammatab[min(g_,static_cast(max_)) * scaleForSave >> 13]; + int b= gammatab[min(b_,static_cast(max_)) * scaleForSave >> 13]; + tmpdata[ix++] = (r*19595+g*38469+b*7472) >> 16; + } + } + } + else { + // If it's not gamma corrected (usually a JPG) we take the normal maximum + max=0; + + if (thumbImg->getType() == sImage8) { + Image8 *image = static_cast(thumbImg); + unsigned char max_=0; + + for (int row=0; rowheight; row++) + for (int col=0; colwidth; col++) { + if (image->r(row,col)>max_) max_ = image->r(row,col); + if (image->g(row,col)>max_) max_ = image->g(row,col); + if (image->b(row,col)>max_) max_ = image->b(row,col); + } + image->convertTo(max_, max); + + if (max < 16384) max = 16384; + scaleForSave = 65535*8192 / max; + + // Correction and gamma to 8 Bit + for (int i=0; iheight; i++) + for (int j=(image->width-trim_width)/2; jwidth-trim_width)/2; j++) { + unsigned short rtmp, gtmp, btmp; + image->convertTo(image->r(i,j), rtmp); + image->convertTo(image->g(i,j), gtmp); + image->convertTo(image->b(i,j), btmp); + int r = rtmp * scaleForSave >> 21; + int g = gtmp * scaleForSave >> 21; + int b = btmp * scaleForSave >> 21; + tmpdata[ix++] = (r*19595+g*38469+b*7472)>>16; + } + } + else if (thumbImg->getType() == sImage16) { + Image16 *image = static_cast(thumbImg); + unsigned short max_=0; + + for (int row=0; rowheight; row++) + for (int col=0; colwidth; col++) { + if (image->r(row,col)>max_) max_ = image->r(row,col); + if (image->g(row,col)>max_) max_ = image->g(row,col); + if (image->b(row,col)>max_) max_ = image->b(row,col); + } + image->convertTo(max_, max); + + if (max < 16384) max = 16384; + scaleForSave = 65535*8192 / max; + + // Correction and gamma to 8 Bit + for (int i=0; iheight; i++) + for (int j=(image->width-trim_width)/2; jwidth-trim_width)/2; j++) { + unsigned short rtmp, gtmp, btmp; + image->convertTo(image->r(i,j), rtmp); + image->convertTo(image->g(i,j), gtmp); + image->convertTo(image->b(i,j), btmp); + int r = rtmp * scaleForSave >> 21; + int g = gtmp * scaleForSave >> 21; + int b = btmp * scaleForSave >> 21; + tmpdata[ix++] = (r*19595+g*38469+b*7472)>>16; + } + } + else if (thumbImg->getType() == sImagefloat) { + Imagefloat *image = static_cast(thumbImg); + float max_=0.f; + + for (int row=0; rowheight; row++) + for (int col=0; colwidth; col++) { + if (image->r(row,col)>max_) max_ = image->r(row,col); + if (image->g(row,col)>max_) max_ = image->g(row,col); + if (image->b(row,col)>max_) max_ = image->b(row,col); + } + image->convertTo(max_, max); + + if (max < 16384) max = 16384; + scaleForSave = 65535*8192 / max; + + // Correction and gamma to 8 Bit + for (int i=0; iheight; i++) + for (int j=(image->width-trim_width)/2; jwidth-trim_width)/2; j++) { + unsigned short rtmp, gtmp, btmp; + image->convertTo(image->r(i,j), rtmp); + image->convertTo(image->g(i,j), gtmp); + image->convertTo(image->b(i,j), btmp); + int r = rtmp * scaleForSave >> 21; + int g = gtmp * scaleForSave >> 21; + int b = btmp * scaleForSave >> 21; + tmpdata[ix++] = (r*19595+g*38469+b*7472)>>16; + } + } + else { + printf("getGrayscaleHistEQ #2: Unsupported image type \"%s\"!\n", thumbImg->getType()); + } + } + + // histogram equalization + unsigned int hist[256] = {0}; + + for (int i=0; i0 && cdf_min==-1) { + cdf_min=cdf; + } + if (cdf_min!=-1) { + hist[i] = (cdf-cdf_min)*255/((thumbImg->height*trim_width)-cdf_min); + } + } + + for (int i=0; igetType(), sizeof (char), strlen(thumbImg->getType()), f); + fputc ('\n', f); + guint32 w = guint32(thumbImg->width); + guint32 h = guint32(thumbImg->height); + fwrite (&w, sizeof (guint32), 1, f); + fwrite (&h, sizeof (guint32), 1, f); + + if (thumbImg->getType() == sImage8) { + Image8 *image = static_cast(thumbImg); + image->writeData(f); + } + else if (thumbImg->getType() == sImage16) { + Image16 *image = static_cast(thumbImg); + image->writeData(f); + } + else if (thumbImg->getType() == sImagefloat) { + Imagefloat *image = static_cast(thumbImg); + image->writeData(f); + } + + //thumbImg->writeData(f); + fclose (f); + return true; +} + +bool Thumbnail::readImage (const Glib::ustring& fname) { + + if (thumbImg) { + delete thumbImg; + thumbImg = NULL; + } + + Glib::ustring fullFName = fname+".rtti"; + + if (!safe_file_test (fullFName, Glib::FILE_TEST_EXISTS)) + return false; + + FILE* f = safe_g_fopen (fullFName, "rb"); + if (!f) + return false; + + char imgType[31]; // 30 -> arbitrary size, but should be enough for all image type's name + fgets(imgType, 30, f); + imgType[strlen(imgType)-1] = '\0'; // imgType has a \n trailing character, so we overwrite it by the \0 char + + guint32 width, height; + fread (&width, 1, sizeof (guint32), f); + fread (&height, 1, sizeof (guint32), f); + + bool success = false; + if (!strcmp(imgType, sImage8)) { + Image8 *image = new Image8(width, height); + image->readData(f); + thumbImg = image; + success = true; + } + else if (!strcmp(imgType, sImage16)) { + Image16 *image = new Image16(width, height); + image->readData(f); + thumbImg = image; + success = true; + } + else if (!strcmp(imgType, sImagefloat)) { + Imagefloat *image = new Imagefloat(width, height); + image->readData(f); + thumbImg = image; + success = true; + } + else { + printf("readImage: Unsupported image type \"%s\"!\n", imgType); + } + fclose(f); + return success; +} + +bool Thumbnail::readData (const Glib::ustring& fname) { + setlocale(LC_NUMERIC, "C"); // to set decimal point to "." + SafeKeyFile keyFile; + + try { + MyMutex::MyLock thmbLock(thumbMutex); + if (!keyFile.load_from_file (fname)) + return false; + + if (keyFile.has_group ("LiveThumbData")) { + if (keyFile.has_key ("LiveThumbData", "CamWBRed")) camwbRed = keyFile.get_double ("LiveThumbData", "CamWBRed"); + if (keyFile.has_key ("LiveThumbData", "CamWBGreen")) camwbGreen = keyFile.get_double ("LiveThumbData", "CamWBGreen"); + if (keyFile.has_key ("LiveThumbData", "CamWBBlue")) camwbBlue = keyFile.get_double ("LiveThumbData", "CamWBBlue"); + if (keyFile.has_key ("LiveThumbData", "RedAWBMul")) redAWBMul = keyFile.get_double ("LiveThumbData", "RedAWBMul"); + if (keyFile.has_key ("LiveThumbData", "GreenAWBMul")) greenAWBMul = keyFile.get_double ("LiveThumbData", "GreenAWBMul"); + if (keyFile.has_key ("LiveThumbData", "BlueAWBMul")) blueAWBMul = keyFile.get_double ("LiveThumbData", "BlueAWBMul"); + if (keyFile.has_key ("LiveThumbData", "AEHistCompression")) aeHistCompression = keyFile.get_integer ("LiveThumbData", "AEHistCompression"); + if (keyFile.has_key ("LiveThumbData", "RedMultiplier")) redMultiplier = keyFile.get_double ("LiveThumbData", "RedMultiplier"); + if (keyFile.has_key ("LiveThumbData", "GreenMultiplier")) greenMultiplier = keyFile.get_double ("LiveThumbData", "GreenMultiplier"); + if (keyFile.has_key ("LiveThumbData", "BlueMultiplier")) blueMultiplier = keyFile.get_double ("LiveThumbData", "BlueMultiplier"); + if (keyFile.has_key ("LiveThumbData", "Scale")) scale = keyFile.get_double ("LiveThumbData", "Scale"); + if (keyFile.has_key ("LiveThumbData", "DefaultGain")) defGain = keyFile.get_double ("LiveThumbData", "DefaultGain"); + if (keyFile.has_key ("LiveThumbData", "ScaleForSave")) scaleForSave = keyFile.get_integer ("LiveThumbData", "ScaleForSave"); + if (keyFile.has_key ("LiveThumbData", "GammaCorrected")) gammaCorrected = keyFile.get_boolean ("LiveThumbData", "GammaCorrected"); + if (keyFile.has_key ("LiveThumbData", "ColorMatrix")) { + std::vector cm = keyFile.get_double_list ("LiveThumbData", "ColorMatrix"); + int ix = 0; + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) + colorMatrix[i][j] = cm[ix++]; + } + } + return true; + } + catch (Glib::Error &err) { + if (options.rtSettings.verbose) + printf("Thumbnail::readData / Error code %d while reading values from \"%s\":\n%s\n", err.code(), fname.c_str(), err.what().c_str()); + } + catch (...) { + if (options.rtSettings.verbose) + printf("Thumbnail::readData / Unknown exception while trying to load \"%s\"!\n", fname.c_str()); + } + + return false; +} + +bool Thumbnail::writeData (const Glib::ustring& fname) { + + SafeKeyFile keyFile; + + MyMutex::MyLock thmbLock(thumbMutex); + + try { + if( safe_file_test(fname,Glib::FILE_TEST_EXISTS) ) + keyFile.load_from_file (fname); + } + catch (Glib::Error &err) { + if (options.rtSettings.verbose) + printf("Thumbnail::writeData / Error code %d while reading values from \"%s\":\n%s\n", err.code(), fname.c_str(), err.what().c_str()); + } + catch (...) { + if (options.rtSettings.verbose) + printf("Thumbnail::writeData / Unknown exception while trying to save \"%s\"!\n", fname.c_str()); + } + + keyFile.set_double ("LiveThumbData", "CamWBRed", camwbRed); + keyFile.set_double ("LiveThumbData", "CamWBGreen", camwbGreen); + keyFile.set_double ("LiveThumbData", "CamWBBlue", camwbBlue); + keyFile.set_double ("LiveThumbData", "RedAWBMul", redAWBMul); + keyFile.set_double ("LiveThumbData", "GreenAWBMul", greenAWBMul); + keyFile.set_double ("LiveThumbData", "BlueAWBMul", blueAWBMul); + keyFile.set_integer ("LiveThumbData", "AEHistCompression", aeHistCompression); + keyFile.set_double ("LiveThumbData", "RedMultiplier", redMultiplier); + keyFile.set_double ("LiveThumbData", "GreenMultiplier", greenMultiplier); + keyFile.set_double ("LiveThumbData", "BlueMultiplier", blueMultiplier); + keyFile.set_double ("LiveThumbData", "Scale", scale); + keyFile.set_double ("LiveThumbData", "DefaultGain", defGain); + keyFile.set_integer ("LiveThumbData", "ScaleForSave", scaleForSave); + keyFile.set_boolean ("LiveThumbData", "GammaCorrected", gammaCorrected); + Glib::ArrayHandle cm ((double*)colorMatrix, 9, Glib::OWNERSHIP_NONE); + keyFile.set_double_list ("LiveThumbData", "ColorMatrix", cm); + + FILE *f = safe_g_fopen (fname, "wt"); + if (!f) { + if (options.rtSettings.verbose) + printf("Thumbnail::writeData / Error: unable to open file \"%s\" with write access!\n", fname.c_str()); + return false; + } + else { + fprintf (f, "%s", keyFile.to_data().c_str()); + fclose (f); + } + return true; +} + +bool Thumbnail::readEmbProfile (const Glib::ustring& fname) { + + FILE* f = safe_g_fopen (fname, "rb"); + if (!f) { + embProfileData = NULL; + embProfile = NULL; + embProfileLength = 0; + } + else { + fseek (f, 0, SEEK_END); + embProfileLength = ftell (f); + fseek (f, 0, SEEK_SET); + embProfileData = new unsigned char[embProfileLength]; + fread (embProfileData, 1, embProfileLength, f); + fclose (f); + embProfile = cmsOpenProfileFromMem (embProfileData, embProfileLength); + return true; + } + return false; +} + +bool Thumbnail::writeEmbProfile (const Glib::ustring& fname) { + + if (embProfileData) { + FILE* f = safe_g_fopen(fname, "wb"); + if (f) { + fwrite (embProfileData, 1, embProfileLength, f); + fclose (f); + return true; + } + } + return false; +} + +bool Thumbnail::readAEHistogram (const Glib::ustring& fname) { + + FILE* f = safe_g_fopen (fname, "rb"); + if (!f) + aeHistogram(0); + else { + aeHistogram(65536>>aeHistCompression); + fread (&aeHistogram[0], 1, (65536>>aeHistCompression)*sizeof(aeHistogram[0]), f); + fclose (f); + return true; + } + return false; +} + +bool Thumbnail::writeAEHistogram (const Glib::ustring& fname) { + + if (aeHistogram) { + FILE* f = safe_g_fopen (fname, "wb"); + if (f) { + fwrite (&aeHistogram[0], 1, (65536>>aeHistCompression)*sizeof(aeHistogram[0]), f); + fclose (f); + return true; + } + } + return false; +} + +unsigned char* Thumbnail::getImage8Data() { + if (thumbImg && thumbImg->getType()==rtengine::sImage8) { + Image8* img8 = static_cast(thumbImg); + return img8->data; + } + return NULL; +} + + + +} diff --git a/rtengine/rtthumbnail.h b/rtengine/rtthumbnail.h new file mode 100644 index 000000000..393241eb7 --- /dev/null +++ b/rtengine/rtthumbnail.h @@ -0,0 +1,159 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _THUMBPROCESSINGPARAMETERS_ +#define _THUMBPROCESSINGPARAMETERS_ + +#include "rawmetadatalocation.h" +#include "procparams.h" +#include +#include +#include "image8.h" +#include "image16.h" +#include "imagefloat.h" +#include "../rtgui/threadutils.h" + +namespace rtengine { + + class Thumbnail { + + MyMutex thumbMutex; + + cmsHPROFILE camProfile; + double iColorMatrix[3][3]; + double cam2xyz[3][3]; + + void transformPixel (int x, int y, int tran, int& tx, int& ty); + + static unsigned short *igammatab; + static unsigned char *gammatab; + + ImageIO* thumbImg; + double camwbRed; + double camwbGreen; + double camwbBlue; + double redAWBMul, greenAWBMul, blueAWBMul; // multipliers for auto WB + double autoWBTemp, autoWBGreen, wbEqual; // autoWBTemp and autoWBGreen are updated each time autoWB is requested and if wbEqual has been modified + LUTu aeHistogram; + int aeHistCompression; + int embProfileLength; + unsigned char* embProfileData; + cmsHPROFILE embProfile; + double redMultiplier; + double greenMultiplier; + double blueMultiplier; + double scale; + double defGain; + int scaleForSave; + bool gammaCorrected; + double colorMatrix[3][3]; + + public: + + bool isRaw; + + ~Thumbnail (); + Thumbnail (); + + static void initGamma (); + static void cleanupGamma (); + 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); + 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); + 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); + + void getCamWB (double& temp, double& green); + void getAutoWB (double& temp, double& green, double equal); + void getAutoWBMultipliers (double& rm, double& gm, double& bm); + void getSpotWB (const procparams::ProcParams& params, int x, int y, int rect, double& temp, double& green); + void applyAutoExp (procparams::ProcParams& pparams); + + unsigned char* getGrayscaleHistEQ (int trim_width); + bool writeImage (const Glib::ustring& fname, int format); + bool readImage (const Glib::ustring& fname); + + bool readData (const Glib::ustring& fname); + bool writeData (const Glib::ustring& fname); + + bool readEmbProfile (const Glib::ustring& fname); + bool writeEmbProfile (const Glib::ustring& fname); + + bool readAEHistogram (const Glib::ustring& fname); + bool writeAEHistogram (const Glib::ustring& fname); + + unsigned char* getImage8Data(); // accessor to the 8bit image if it is one, which should be the case for the "Inspector" mode. + + // Hombre: ... let's hope that proper template can make this cleaner + + static ImageIO* resizeToSameType(int nw, int nh, TypeInterpolation interp, ImageIO* srcImg) { + ImageIO* imgPtr; + if (srcImg->getType() == sImage8) { + Image8* castedSrcImg = static_cast(srcImg); + Image8* img8 = new Image8 (nw, nh); + castedSrcImg->resizeImgTo(nw, nh, interp, img8); + imgPtr = img8; + } + else if (srcImg->getType() == sImage16) { + Image16* castedSrcImg = static_cast(srcImg); + Image16* img16 = new Image16 (nw, nh); + castedSrcImg->resizeImgTo(nw, nh, interp, img16); + imgPtr = img16; + } + else if (srcImg->getType() == sImagefloat) { + Imagefloat* castedSrcImg = static_cast(srcImg); + Imagefloat* imgfloat = new Imagefloat (nw, nh); + castedSrcImg->resizeImgTo(nw, nh, interp, imgfloat); + imgPtr = imgfloat; + } + return imgPtr; + } + + template + static IC* resizeTo(int nw, int nh, TypeInterpolation interp, ImageIO* srcImg) { + + IC* imgPtr = new IC (nw, nh); + + // Hombre: ... let's hope that proper template can make this cleaner + + if (srcImg->getType() == sImage8) { + Image8* castedSrcImg = static_cast(srcImg); + castedSrcImg->resizeImgTo<>(nw, nh, interp, imgPtr); + } + else if (srcImg->getType() == sImage16) { + Image16* castedSrcImg = static_cast(srcImg); + castedSrcImg->resizeImgTo<>(nw, nh, interp, imgPtr); + } + else if (srcImg->getType() == sImagefloat) { + Imagefloat* castedSrcImg = static_cast(srcImg); + castedSrcImg->resizeImgTo<>(nw, nh, interp, imgPtr); + } + return imgPtr; + }; +}; +} + +#endif + diff --git a/rtengine/safegtk.cc b/rtengine/safegtk.cc new file mode 100755 index 000000000..71105b6af --- /dev/null +++ b/rtengine/safegtk.cc @@ -0,0 +1,507 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * Copyright (c) 2010 Sasha Vasko + * Copyright (c) 2010 Oliver Duis + * + * 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 "safegtk.h" +#include "../rtgui/guiutils.h" +#include +#include +#ifdef WIN32 +#include +// for GCC32 +#ifndef _WIN32_IE +#define _WIN32_IE 0x0600 +#endif +#include +#include +#else +#include +#endif +#include "../rtgui/rtimage.h" +#include + + +Glib::RefPtr safe_create_from_file(const Glib::ustring& filename) +{ + Glib::RefPtr res; + Glib::ustring path = RTImage::findIconAbsolutePath(filename); + if (path.length()) { + try { + res = Gdk::Pixbuf::create_from_file (path); + } + catch (Glib::Exception& ex) { + printf ("ERROR: (ustring) File \"%s\" not found.\n", ex.what().c_str()); + } + } + return res; +} + +Cairo::RefPtr safe_create_from_png(const Glib::ustring& filename) +{ + Cairo::RefPtr res; + Glib::ustring path = RTImage::findIconAbsolutePath(filename); + if (path.length()) { + // files_test need a std::string which (as stated in its proto) but will only work if + // we use the Glib::ustring filename !? + try { + // create_from_png need a std::string converted from UTF8 with safe_locale_from_utf8 + res = Cairo::ImageSurface::create_from_png (safe_locale_from_utf8(path)); + } catch (...) { + printf("ERROR: (ustring) File \"%s\" not found.\n", path.c_str()); + } + } + return res; +} + +Glib::RefPtr safe_query_file_info (Glib::RefPtr &file) +{ + Glib::RefPtr info; +#ifdef GLIBMM_EXCEPTIONS_ENABLED + try { info = file->query_info(); }catch (...) { } +#else + std::auto_ptr error; + info = file->query_info("*", Gio::FILE_QUERY_INFO_NONE, error); +#endif + return info; +} + +Glib::RefPtr safe_next_file (Glib::RefPtr &dirList) +{ + Glib::RefPtr info; +#ifdef GLIBMM_EXCEPTIONS_ENABLED + bool retry; + Glib::ustring last_error = ""; + do { + retry = false; + try { + info = dirList->next_file(); + } catch (Glib::Exception& ex) { + printf ("%s\n", ex.what().c_str()); + // API problem: not possible to differ between error looking at particular entry or + // general error scanning the directory. We do a hack by retrying and see if the + // error changes, if it does we can assume it's about the current filename and we + // should look at the next. More likely if a single file error is that the next + // retry is okay of course. + retry = (ex.what() != last_error); + last_error = ex.what(); + } + } while (retry); +#else + bool retry; + Glib::ustring last_error = ""; + do { + retry = false; + std::auto_ptr error; + Glib::RefPtr cancellable; + info = dirList->next_file(cancellable, error); + if (!info && error.get()) { + printf ("%s\n", error.what().c_str()); + retry = (error.what() != last_error); + last_error = error.what(); + } + } while (retry); +#endif + return info; +} + +#ifdef GLIBMM_EXCEPTIONS_ENABLED +# define SAFE_ENUMERATOR_CODE_START \ + do{try { if ((dirList = dir->enumerate_children ())) \ + for (Glib::RefPtr info = safe_next_file(dirList); info; info = safe_next_file(dirList)) { + +# define SAFE_ENUMERATOR_CODE_END \ + }} catch (Glib::Exception& ex) { printf ("%s\n", ex.what().c_str()); }}while(0) +#else +# define SAFE_ENUMERATOR_CODE_START \ + do{std::auto_ptr error; Glib::RefPtr cancellable; \ + if ((dirList = dir->enumerate_children (cancellable, "*", Gio::FILE_QUERY_INFO_NONE, error))) \ + for (Glib::RefPtr info = safe_next_file(dirList); info; info = safe_next_file(dirList)) { + +# define SAFE_ENUMERATOR_CODE_END } if (error.get()) printf ("%s\n", error->what().c_str());}while (0) +#endif + +#ifdef WIN32 + +// High speed Windows version +void safe_build_file_list (Glib::RefPtr &dir, std::vector &flist) +{ + Glib::ustring fullPath=dir->get_path() + Glib::ustring("\\*"); + + DWORD dwVersion=GetVersion(); + bool win7Plus=(LOBYTE(LOWORD(dwVersion))>6) || ((LOBYTE(LOWORD(dwVersion))==6) && HIBYTE(LOWORD(dwVersion))>=1); // 6.1 or better + + wchar_t *wDirName = (wchar_t*)g_utf8_to_utf16 (fullPath.c_str(), -1, NULL, NULL, NULL); + WIN32_FIND_DATAW fi; + + HANDLE hFF=FindFirstFileExW(wDirName, + //win7Plus ? FindExInfoBasic : // TODO: Add if MinGW is updated, makes it even faster + FindExInfoStandard,&fi, + FindExSearchNameMatch,NULL, + win7Plus ? 2 : 0); // Win7 large fetch + + if (hFF != INVALID_HANDLE_VALUE) { + do { + SYSTEMTIME stUTC; + FileTimeToSystemTime(&fi.ftLastWriteTime, &stUTC); + char time[64]; + sprintf(time,"%d-%02d-%02dT%02d:%02d:%02dZ",stUTC.wYear,stUTC.wMonth,stUTC.wDay,stUTC.wHour,stUTC.wMinute,stUTC.wSecond); + Glib::TimeVal timeVal; + timeVal.assign_from_iso8601(Glib::ustring(time)); + + char pathA[MAX_PATH]; + WideCharToMultiByte(CP_UTF8,0,(WCHAR*)fi.cFileName,-1,pathA,MAX_PATH,0,0); + flist.push_back (FileMTimeInfo (removeExtension(Glib::ustring(pathA)), timeVal)); + + } while (FindNextFileW(hFF, &fi)); + + FindClose(hFF); + } + + g_free(wDirName); +} +#else + +// Generic file list build +void safe_build_file_list (Glib::RefPtr &dir, std::vector &flist) +{ + Glib::RefPtr dirList; + if (dir) { + SAFE_ENUMERATOR_CODE_START + flist.push_back (FileMTimeInfo (removeExtension(info->get_name()), info->modification_time())); + SAFE_ENUMERATOR_CODE_END; + } +} +#endif +/* + * safe_build_file_list can now filter out at the source all files that doesn't have the extensions specified (if provided) + */ +void safe_build_file_list (Glib::RefPtr &dir, std::vector &names, const Glib::ustring &directory, const std::vector *extensions) +{ + Glib::RefPtr dirList; + + if (dir) { + if (!extensions) { + SAFE_ENUMERATOR_CODE_START + names.push_back (Glib::build_filename (directory, info->get_name())); + SAFE_ENUMERATOR_CODE_END; + } + else { + // convert extensions to lowercase in a new vector list + std::vector lcExtensions; + for (unsigned int i=0; isize(); i++) + lcExtensions.push_back ((*extensions)[i].lowercase()); + + SAFE_ENUMERATOR_CODE_START + // convert the current filename to lowercase in a new ustring + Glib::ustring fname = Glib::ustring(info->get_name()).lowercase(); + + size_t pos = fname.find_last_of('.'); + if (pos < (fname.length()-1)) { + // there is an extension to the filename + + Glib::ustring lcFileExt = fname.substr(pos+1).lowercase(); + + // look out if it has one of the retained extensions + for (size_t i=0; iget_name())); + break; + } + } + } + SAFE_ENUMERATOR_CODE_END; + } + } +} + + +void safe_build_subdir_list (Glib::RefPtr &dir, std::vector &subDirs, bool add_hidden) +{ + Glib::RefPtr dirList; + if (dir) + { + // CD-ROMs with no drive inserted are reported, but do not exist, causing RT to crash + if (!safe_file_test(dir->get_path(),Glib::FILE_TEST_EXISTS)) return; + + SAFE_ENUMERATOR_CODE_START + if (info->get_file_type() == Gio::FILE_TYPE_DIRECTORY && (!info->is_hidden() || add_hidden)) + subDirs.push_back (info->get_name()); + SAFE_ENUMERATOR_CODE_END; + } +} + +/* + * For an unknown reason, Glib::filename_to_utf8 doesn't work on Windows, so we're using + * Glib::filename_to_utf8 for Linux/Apple and Glib::locale_to_utf8 for Windows + */ +Glib::ustring safe_filename_to_utf8 (const std::string& src) +{ + Glib::ustring utf8_str; +#ifdef WIN32 +#ifdef GLIBMM_EXCEPTIONS_ENABLED + try { + utf8_str = Glib::locale_to_utf8(src); + } + catch (const Glib::Error& e) { + utf8_str = Glib::convert_with_fallback(src, "UTF-8", "ISO-8859-1","?"); + } +#else + { + std::auto_ptr error; + utf8_str = locale_to_utf8(src, error); + if (error.get()) + utf8_str = Glib::convert_with_fallback(src, "UTF-8", "ISO-8859-1","?", error); + } +#endif //GLIBMM_EXCEPTIONS_ENABLED +#else + utf8_str = Glib::filename_to_utf8(src); +#endif + return utf8_str; +} + +Glib::ustring safe_locale_to_utf8 (const std::string& src) +{ + Glib::ustring utf8_str; +#ifdef GLIBMM_EXCEPTIONS_ENABLED + try { + utf8_str = Glib::locale_to_utf8(src); + } + catch (const Glib::Error& e) { + utf8_str = Glib::convert_with_fallback(src, "UTF-8", "ISO-8859-1","?"); + } +#else + { + std::auto_ptr error; + utf8_str = locale_to_utf8(src, error); + if (error.get()) + utf8_str = Glib::convert_with_fallback(src, "UTF-8", "ISO-8859-1","?", error); + } +#endif //GLIBMM_EXCEPTIONS_ENABLED + return utf8_str; +} + +std::string safe_locale_from_utf8 (const Glib::ustring& utf8_str) +{ + std::string str; +#ifdef GLIBMM_EXCEPTIONS_ENABLED + try { + str = Glib::locale_from_utf8(utf8_str); + } + catch (const Glib::Error& e) { + //str = Glib::convert_with_fallback(utf8_str, "ISO-8859-1", "UTF-8", "?"); + } +#else + { + std::auto_ptr error; + str = Glib::locale_from_utf8(utf8_str, error); + /*if (error.get()) + {str = Glib::convert_with_fallback(utf8_str, "ISO-8859-1", "UTF-8", "?", error);}*/ + } +#endif //GLIBMM_EXCEPTIONS_ENABLED + return str; +} + +bool safe_spawn_command_line_async (const Glib::ustring& cmd_utf8) +{ + std::string cmd; + bool success = false; +#ifdef GLIBMM_EXCEPTIONS_ENABLED + try { + cmd = Glib::filename_from_utf8(cmd_utf8); + printf ("command line: %s\n", cmd.c_str()); + Glib::spawn_command_line_async (cmd.c_str()); + success = true; + } catch (Glib::Exception& ex) { + printf ("%s\n", ex.what().c_str()); + } +#else + std::auto_ptr error; + cmd = Glib::filename_from_utf8(cmd_utf8, error); + if (!error.get()) { + printf ("command line: %s\n", cmd.c_str()); + Glib::spawn_command_line_async (cmd, error); + } + if (error.get()) + printf ("%s\n", error->what().c_str()); + else + success = true; +#endif + return success; +} + +bool safe_spawn_command_line_sync (const Glib::ustring& cmd_utf8) +{ + int exitStatus=-1; + try { + //cmd = Glib::filename_from_utf8(cmd_utf8); + printf ("command line: %s\n", cmd_utf8.c_str()); + + // if it crashes here on windows, make sure you have the GTK runtime files gspawn-win32-helper*.exe files in RT directory + Glib::spawn_command_line_sync (cmd_utf8, NULL, NULL, &exitStatus); + } catch (Glib::Exception& ex) { + printf ("%s\n", ex.what().c_str()); + } + return (exitStatus==0); +} + +// Opens a file for binary writing and request exclusive lock (cases were you need "wb" mode plus locking) +// (Important on Windows to prevent Explorer to crash RT when parallel scanning e.g. a currently written image file) +FILE * safe_g_fopen_WriteBinLock(const Glib::ustring& fname) { + FILE* f=NULL; + +#ifdef WIN32 + // g_fopen just uses _wfopen internally on Windows, does not lock access and has no options to set this + // so use a native function to work around this problem + wchar_t *wFname = (wchar_t*)g_utf8_to_utf16 (fname.c_str(), -1, NULL, NULL, NULL); + HANDLE hFile = CreateFileW(wFname, GENERIC_READ | GENERIC_WRITE, 0 /* no sharing allowed */, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + g_free(wFname); + + if (hFile==INVALID_HANDLE_VALUE) + f=NULL; + else + f=_fdopen( _open_osfhandle((intptr_t)hFile, 0) , "wb"); +#else + f = safe_g_fopen(fname, "wb"); +#endif + + return f; +} + +// Covers old UNIX ::open, which expects ANSI instead of UTF8 on Windows +int safe_open_ReadOnly(const char *fname) { + int fd=-1; + +#ifdef WIN32 + // First convert UTF8 to UTF16, then use Windows function to open + wchar_t *wFname = (wchar_t*)g_utf8_to_utf16 (fname, -1, NULL, NULL, NULL); + HANDLE hFile = CreateFileW(wFname, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + g_free(wFname); + + // convert back to old file descriptor format + if (hFile!=INVALID_HANDLE_VALUE) fd = _open_osfhandle((intptr_t)hFile, 0); +#else + fd = ::open(fname, O_RDONLY); +#endif + + return fd; +} + + +FILE * safe_g_fopen(const Glib::ustring& src,const gchar *mode) +{ + return g_fopen(src.c_str(),mode); +} + +bool safe_file_test (const Glib::ustring& filename, Glib::FileTest test) +{ + return Glib::file_test (filename, test); +} + +int safe_g_remove(const Glib::ustring& filename) +{ + return ::g_remove(filename.c_str()); +} + +int safe_g_rename(const Glib::ustring& oldFilename, const Glib::ustring& newFilename) +{ + return ::g_rename(oldFilename.c_str(), newFilename.c_str()); +} + +int safe_g_mkdir_with_parents(const Glib::ustring& dirName, int mode) +{ + return ::g_mkdir_with_parents(dirName.c_str(), mode); +} + +Glib::ustring safe_get_user_picture_dir() { + #ifdef WIN32 + // get_user_special_dir/pictures crashes on some Windows configurations. + // so we use the safe native functions here + WCHAR pathW[MAX_PATH]={0}; + if (SHGetSpecialFolderPathW(NULL,pathW,CSIDL_MYPICTURES,false)) { + char pathA[MAX_PATH]; + WideCharToMultiByte(CP_UTF8,0,pathW,-1,pathA,MAX_PATH,0,0); + return Glib::ustring(pathA); + } else return Glib::ustring("C:\\"); + + #else + + return Glib::get_user_special_dir (G_USER_DIRECTORY_PICTURES); + + #endif +} + +Glib::ustring safe_get_user_home_dir() { + #ifdef WIN32 + // get_user_special_dir/pictures crashes on some Windows configurations. + // so we use the safe native functions here + WCHAR pathW[MAX_PATH]={0}; + if (SHGetSpecialFolderPathW(NULL,pathW,CSIDL_PERSONAL,false)) { + char pathA[MAX_PATH]; + WideCharToMultiByte(CP_UTF8,0,pathW,-1,pathA,MAX_PATH,0,0); + return Glib::ustring(pathA); + } else return Glib::ustring("C:\\"); + + #else + + return Glib::get_home_dir(); + + #endif +} + +#ifdef WIN32 +Glib::ustring safe_get_user_profile_dir() { + WCHAR pathW[MAX_PATH]={0}; + if (SHGetSpecialFolderPathW(NULL,pathW,CSIDL_PROFILE,false)) { + char pathA[MAX_PATH]; + WideCharToMultiByte(CP_UTF8,0,pathW,-1,pathA,MAX_PATH,0,0); + return Glib::ustring(pathA); + } else return Glib::ustring("C:\\"); +} +#endif + + +Glib::ustring safe_get_user_desktop_dir() { + #ifdef WIN32 + // get_user_special_dir/pictures crashes on some Windows configurations. + // so we use the safe native functions here + WCHAR pathW[MAX_PATH]={0}; + if (SHGetSpecialFolderPathW(NULL,pathW,CSIDL_DESKTOP,false)) { + char pathA[MAX_PATH]; + WideCharToMultiByte(CP_UTF8,0,pathW,-1,pathA,MAX_PATH,0,0); + return Glib::ustring(pathA); + } else return Glib::ustring("C:\\"); + + #else + + return Glib::get_user_special_dir (G_USER_DIRECTORY_DESKTOP); + + #endif +} + +#ifdef WIN32 +/* + * Test if the path is a root path based on the content of the string + * + * Warning: this function is a workaround for Windows platform, and not necessarily bullet proof + */ +bool safe_is_shortcut_dir (const Glib::ustring& path) { + return PathIsRootA(path.c_str()) || safe_get_user_home_dir() == path || safe_get_user_desktop_dir() == path || safe_get_user_profile_dir() == path; // || safe_get_user_picture_dir() == path; +} +#endif diff --git a/rtengine/safegtk.h b/rtengine/safegtk.h new file mode 100644 index 000000000..eb10b7c5b --- /dev/null +++ b/rtengine/safegtk.h @@ -0,0 +1,52 @@ +#ifndef SAFE_GTK_H_INCLUDED +#define SAFE_GTK_H_INCLUDED + +#include +#include +#include + +Glib::RefPtr safe_create_from_file(const Glib::ustring& filename); +Cairo::RefPtr safe_create_from_png(const Glib::ustring& filename); + +class FileMTimeInfo { + + public: + Glib::ustring fname; + Glib::TimeVal mtime; + + FileMTimeInfo (Glib::ustring name, Glib::TimeVal mtime) : fname(name), mtime(mtime) {} + bool operator<(const FileMTimeInfo& other) const { return mtime safe_query_file_info (Glib::RefPtr &file); +void safe_build_file_list (Glib::RefPtr &dir, std::vector &flist); +void safe_build_file_list (Glib::RefPtr &dir, std::vector &names, const Glib::ustring &directory = "", const std::vector *extensions=NULL); +void safe_build_subdir_list (Glib::RefPtr &dir, std::vector &subDirs, bool add_hidden); + +bool safe_spawn_command_line_async (const Glib::ustring& cmd_utf8); +bool safe_spawn_command_line_sync (const Glib::ustring& cmd_utf8); + +Glib::ustring safe_filename_to_utf8 (const std::string& src); +Glib::ustring safe_locale_to_utf8 (const std::string& src); // from rtengine +std::string safe_locale_from_utf8 (const Glib::ustring& utf8_str); +std::string safe_filename_from_utf8 (const Glib::ustring& utf8_str); + +FILE * safe_g_fopen(const Glib::ustring& src,const gchar *mode); +FILE * safe_g_fopen_WriteBinLock(const Glib::ustring& fname); +int safe_open_ReadOnly(const char *fname); + +bool safe_file_test (const Glib::ustring& filename, Glib::FileTest test); +int safe_g_remove(const Glib::ustring& filename); +int safe_g_rename(const Glib::ustring& oldFilename, const Glib::ustring& newFilename); +int safe_g_mkdir_with_parents(const Glib::ustring& dirName, int mode); + +Glib::ustring safe_get_user_picture_dir(); +Glib::ustring safe_get_user_home_dir(); +Glib::ustring safe_get_user_desktop_dir(); + +#ifdef WIN32 +Glib::ustring safe_get_user_profile_dir(); +bool safe_is_shortcut_dir (const Glib::ustring& filename); +#endif + +#endif diff --git a/rtengine/safekeyfile.h b/rtengine/safekeyfile.h new file mode 100644 index 000000000..8e2148ed7 --- /dev/null +++ b/rtengine/safekeyfile.h @@ -0,0 +1,116 @@ +#ifndef SAFE_KEY_FILE_H_INCLUDED +#define SAFE_KEY_FILE_H_INCLUDED + +#include +namespace rtengine { + +class SafeKeyFile : public Glib::KeyFile +{ + public : + +#ifdef GLIBMM_EXCEPTIONS_ENABLED +#define SAFE_KEY_FILE_METHOD_CODE(method,method_err) \ + do { try { res = Glib::KeyFile::method; }catch (const Glib::KeyFileError& e) { } ; \ + return res; }while(0) +#else +#define SAFE_KEY_FILE_METHOD_CODE(method,method_err) \ + do { std::auto_ptr error; \ + res = Glib::KeyFile::method_err; \ + if (error.get()){/* TODO */}; \ + return res;} while(0) +#endif //GLIBMM_EXCEPTIONS_ENABLED +#define SAFE_KEY_FILE_METHOD(method,method_err,ret_type) \ + { ret_type res = (ret_type)0; SAFE_KEY_FILE_METHOD_CODE(method,method_err);} + +#define SAFE_KEY_FILE_METHOD_NOINIT(method,method_err,ret_type) \ + { ret_type res; SAFE_KEY_FILE_METHOD_CODE(method,method_err);} + + Glib::ustring to_data() + SAFE_KEY_FILE_METHOD_NOINIT(to_data(), to_data(error), Glib::ustring); + + bool load_from_data(const Glib::ustring& data, Glib::KeyFileFlags flags = Glib::KEY_FILE_NONE) + SAFE_KEY_FILE_METHOD(load_from_data(data,flags), load_from_data(data,flags,error), bool); + + bool load_from_file(const std::string& filename, Glib::KeyFileFlags flags = Glib::KEY_FILE_NONE) + SAFE_KEY_FILE_METHOD(load_from_file(filename,flags), load_from_file(filename,flags,error), bool); + + bool has_key(const Glib::ustring& group_name, const Glib::ustring& key) const + SAFE_KEY_FILE_METHOD(has_key(group_name,key), has_key(group_name,key,error), bool); + + bool get_boolean(const Glib::ustring& group_name, const Glib::ustring& key) const + SAFE_KEY_FILE_METHOD(get_boolean(group_name,key), get_boolean(group_name,key,error), bool); + + int get_integer(const Glib::ustring& group_name, const Glib::ustring& key) const + SAFE_KEY_FILE_METHOD(get_integer(group_name,key), get_integer(group_name,key,error), int); + + + + double get_double(const Glib::ustring& group_name, const Glib::ustring& key) const + SAFE_KEY_FILE_METHOD(get_double(group_name,key), get_double(group_name,key,error), double); + + typedef std::vector DoubleArrayType; + + DoubleArrayType get_double_list(const Glib::ustring& group_name, const Glib::ustring& key) const + SAFE_KEY_FILE_METHOD_NOINIT(get_double_list(group_name,key), get_double_list(group_name,key,error), DoubleArrayType); + + typedef std::vector IntArrayType; + + IntArrayType get_integer_list(const Glib::ustring& group_name, const Glib::ustring& key) const + SAFE_KEY_FILE_METHOD_NOINIT(get_integer_list(group_name,key), get_integer_list(group_name,key,error), IntArrayType); + + Glib::ustring get_string(const Glib::ustring& group_name, const Glib::ustring& key) const + SAFE_KEY_FILE_METHOD_NOINIT(get_string(group_name,key), get_string(group_name,key,error), Glib::ustring); +/* + double get_double(const Glib::ustring& group_name, const Glib::ustring& key) const { + Glib::ustring temp = get_string( group_name, key); + if(!temp.empty()) { + double tmpdbl; + if(sscanf(temp.c_str(), "%lf", &tmpdbl)) + return tmpdbl; + else + return 0.0; + } + return 0.0; + } +*/ + typedef std::vector StringArrayType; + + StringArrayType get_string_list(const Glib::ustring& group_name, const Glib::ustring& key) const + SAFE_KEY_FILE_METHOD_NOINIT(get_string_list(group_name,key), get_string_list(group_name,key,error), StringArrayType); +/* + typedef std::vector DoubleArrayType; + + DoubleArrayType get_double_list(const Glib::ustring& group_name, const Glib::ustring& key) const { + StringArrayType temp = get_string_list(group_name, key); + DoubleArrayType tempdouble; + unsigned int n = temp.size(); + if(n) { + tempdouble.reserve(n); + for (unsigned int i=0; i + * + * 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 _RTSETTINGS_ +#define _RTSETTINGS_ + +namespace rtengine { + + /** This structure holds the global parameters used by the RT engine. */ + class Settings { + public: + Glib::ustring iccDirectory; ///< The directory containing the possible output icc profiles + int colorimetricIntent; ///< Colorimetric intent used at color space conversions + int viewingdevice; // white of output device (D50...D65..) + int viewingdevicegrey; // level of grey output device + int viewinggreySc; // level of grey Scene + int leveldnv; // level of crop denoise + int leveldnti; // size of tiles denoise + int leveldnaut; // level of auto denoise + int leveldnliss; // level of auto multi zone + int leveldnautsimpl; // STD or EXPERT + + Glib::ustring monitorProfile; ///< ICC profile of the monitor (full path recommended) + bool autoMonitorProfile; ///< Try to auto-determine the correct monitor color profile + bool autocielab; + bool rgbcurveslumamode_gamut;// controls gamut enforcement for RGB curves in lumamode + bool verbose; + Glib::ustring darkFramesPath; ///< The default directory for dark frames + Glib::ustring flatFieldsPath; ///< The default directory for flat fields + Glib::ustring adobe; // default name of AdobeRGB1998 + Glib::ustring prophoto; // default name of Prophoto + Glib::ustring prophoto10; // default name of Prophoto + + Glib::ustring widegamut; //default name of WidegamutRGB + Glib::ustring beta; // default name of BetaRGB + Glib::ustring best; // default name of BestRGB + Glib::ustring bruce; // default name of Bruce + Glib::ustring srgb; // default name of SRGB space profile + Glib::ustring srgb10; // default name of SRGB space profile + + bool gamutICC; // no longer used + bool gamutLch; + bool ciecamfloat; + bool HistogramWorking; + int amchroma; + int protectred; + double protectredh; + double nrauto; + double nrautomax; + double nrhigh; + int nrwavlevel; + bool daubech; + bool ciebadpixgauss; + int CRI_color; // N� for display Lab value ; 0 disabled + int denoiselabgamma; // 0=gamma 26 11 1=gamma 40 5 2 =gamma 55 10 + // double colortoningab; // + // double decaction; + // bool bw_complementary; + double artifact_cbdl; + double level0_cbdl; + double level123_cbdl; + double bot_left; + double top_left; + double top_right; + double bot_right; + double ed_detec; + double ed_detecStr; + double ed_low; + double ed_lipinfl; + double ed_lipampl; + /** Creates a new instance of Settings. + * @return a pointer to the new Settings instance. */ + static Settings* create (); + /** Destroys an instance of Settings. + * @param s a pointer to the Settings instance to destroy. */ + static void destroy (Settings* s); + }; +} + +#endif + diff --git a/rtengine/shmap.cc b/rtengine/shmap.cc new file mode 100644 index 000000000..951abaca9 --- /dev/null +++ b/rtengine/shmap.cc @@ -0,0 +1,389 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "shmap.h" +#include "gauss.h" +#include "rtengine.h" +#include "rt_math.h" +#include "rawimagesource.h" +#undef THREAD_PRIORITY_NORMAL +#include "opthelper.h" + +namespace rtengine { + +extern const Settings* settings; + +SHMap::SHMap (int w, int h, bool multiThread) : W(w), H(h), multiThread(multiThread) { + + map = new float*[H]; + for (int i=0; ir(i,j),0.f) + lumi[1]*std::max(img->g(i,j),0.f) + lumi[2]*std::max(img->b(i,j),0.f); + } + +} + +void SHMap::update (Imagefloat* img, double radius, double lumi[3], bool hq, int skip) { + + if (!hq) { + fillLuminance( img, map, lumi); + +#ifdef _OPENMP +#pragma omp parallel +#endif +{ + AlignedBufferMP* pBuffer = new AlignedBufferMP (max(W,H)); + gaussHorizontal (map, map, *pBuffer, W, H, radius); + gaussVertical (map, map, *pBuffer, W, H, radius); + delete pBuffer; +} + } + + else { + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + //experimental dirpyr shmap + + float thresh = (100.f*radius);//1000; + + // set up range function + // calculate size of Lookup table. That's possible because from a value k for all i>=k rangefn[i] will be exp(-10) + // So we use this fact and the automatic clip of lut to reduce the size of lut and the number of calculations to fill the lut + // In past this lut had only integer precision with rangefn[i] = 0 for all i>=k + // We set the last element to a small epsilon 1e-15 instead of zero to avoid divisions by zero + const int lutSize = thresh * sqrtf(10.f) + 1; + thresh *= thresh; + LUTf rangefn(lutSize); + for (int i=0; i(i)*i) / thresh ));//*intfactor; + } + rangefn[lutSize-1] = 1e-15f; + + // We need one temporary buffer + float ** buffer = allocArray (W, H); + + // the final result has to be in map + // for an even number of levels that means: map => buffer, buffer => map + // for an odd number of levels that means: buffer => map, map => buffer, buffer => map + // so let's calculate the number of levels first + // There are at least two levels + int numLevels=2; + int scale=2; + while (skip*scale<16) { + scale *= 2; + numLevels++; + } + + float ** dirpyrlo[2]; + if(numLevels&1) { // odd number of levels, start with buffer + dirpyrlo[0] = buffer; + dirpyrlo[1] = map; + } else { // even number of levels, start with map + dirpyrlo[0] = map; + dirpyrlo[1] = buffer; + } + + fillLuminance( img, dirpyrlo[0], lumi); + + scale = 1; + int level=0; + int indx=0; + dirpyr_shmap(dirpyrlo[indx], dirpyrlo[1-indx], W, H, rangefn, level, scale ); + scale *= 2; + level ++; + indx = 1-indx; + while (skip*scale<16) { + dirpyr_shmap(dirpyrlo[indx], dirpyrlo[1-indx], W, H, rangefn, level, scale ); + scale *= 2; + level ++; + indx = 1-indx; + } + + dirpyr_shmap(dirpyrlo[indx], dirpyrlo[1-indx], W, H, rangefn, level, scale ); + + freeArray(buffer, H); + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +/* + // anti-alias filtering the result +#ifdef _OPENMP +#pragma omp for +#endif + for (int i=0; i0 && j>0 && i _max_f) + _max_f = _val; + _avg += _val; + } +#ifdef _OPENMP +#pragma omp critical +#endif +{ + if(_min_f < min_f ) + min_f = _min_f; + if(_max_f > max_f ) + max_f = _max_f; +} +} + _avg /= ((H)*(W)); + avg = _avg; + +} + +void SHMap::forceStat (float max_, float min_, float avg_) { + + max_f = max_; + min_f = min_; + avg = avg_; +} + +SSEFUNCTION void SHMap::dirpyr_shmap(float ** data_fine, float ** data_coarse, int width, int height, LUTf & rangefn, int level, int scale) +{ + //scale is spacing of directional averaging weights + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // calculate weights, compute directionally weighted average + + int scalewin, halfwin; + + if(level < 2) { + halfwin = 1; + scalewin = halfwin*scale; + +#ifdef _OPENMP +#pragma omp parallel +#endif +{ +#if defined( __SSE2__ ) && defined( __x86_64__ ) + __m128 dirwtv, valv, normv, dftemp1v, dftemp2v; +#endif // __SSE2__ + int j; +#ifdef _OPENMP +#pragma omp for +#endif + for(int i = 0; i < height; i++) { + float dirwt; + for(j = 0; j < scalewin; j++) { + float val=0.f; + float norm=0.f; + for(int inbr=max(i-scalewin,i%scale); inbr<=min(i+scalewin, height-1); inbr+=scale) { + for (int jnbr=j%scale; jnbr<=j+scalewin; jnbr+=scale) { + dirwt = ( rangefn[abs(data_fine[inbr][jnbr]-data_fine[i][j])] ); + val += dirwt*data_fine[inbr][jnbr]; + norm += dirwt; + } + } + data_coarse[i][j] = val/norm; // low pass filter + } +#if defined( __SSE2__ ) && defined( __x86_64__ ) + int inbrMin = max(i-scalewin,i%scale); + for(; j < (width-scalewin)-3; j+=4) { + valv= _mm_setzero_ps(); + normv= _mm_setzero_ps(); + dftemp1v = LVFU(data_fine[i][j]); + for(int inbr=inbrMin; inbr<=min(i+scalewin, height-1); inbr+=scale) { + for (int jnbr=j-scalewin; jnbr<=j+scalewin; jnbr+=scale) { + dftemp2v = LVFU(data_fine[inbr][jnbr]); + dirwtv = ( rangefn[_mm_cvttps_epi32(vabsf(dftemp2v-dftemp1v))] ); + valv += dirwtv*dftemp2v; + normv += dirwtv; + } + } + _mm_storeu_ps( &data_coarse[i][j], valv/normv); + } + for(; j < width-scalewin; j++) { + float val=0.f; + float norm=0.f; + for(int inbr=inbrMin; inbr<=min(i+scalewin, height-1); inbr+=scale) { + for (int jnbr=j-scalewin; jnbr<=j+scalewin; jnbr+=scale) { + dirwt = ( rangefn[abs(data_fine[inbr][jnbr]-data_fine[i][j])] ); + val += dirwt*data_fine[inbr][jnbr]; + norm += dirwt; + } + } + data_coarse[i][j] = val/norm; // low pass filter + } + +#else + for(; j < width-scalewin; j++) { + float val=0.f; + float norm=0.f; + for(int inbr=max(i-scalewin,i%scale); inbr<=min(i+scalewin, height-1); inbr+=scale) { + for (int jnbr=j-scalewin; jnbr<=j+scalewin; jnbr+=scale) { + dirwt = ( rangefn[abs(data_fine[inbr][jnbr]-data_fine[i][j])] ); + val += dirwt*data_fine[inbr][jnbr]; + norm += dirwt; + } + } + data_coarse[i][j] = val/norm; // low pass filter + } +#endif + for(; j < width; j++) { + float val=0.f; + float norm=0.f; + for(int inbr=max(i-scalewin,i%scale); inbr<=min(i+scalewin, height-1); inbr+=scale) { + for (int jnbr=j-scalewin; jnbr + * + * 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 __SHMAP__ +#define __SHMAP__ + +#include "imagefloat.h" +#include "image16.h" + +namespace rtengine { + +class SHMap { + + public: + float** map; + float max_f, min_f, avg; + + SHMap (int w, int h, bool multiThread); + ~SHMap (); + + void update (Imagefloat* img, double radius, double lumi[3], bool hq, int skip); + void forceStat (float max_, float min_, float avg_); + + private: + int W, H; + bool multiThread; + + void fillLuminance( Imagefloat * img, float **luminance, double lumi[3] ); + void dirpyr_shmap(float ** data_fine, float ** data_coarse, int width, int height, LUTf & rangefn, int level, int scale); + +}; +} +#endif diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc new file mode 100644 index 000000000..7b0d2a6be --- /dev/null +++ b/rtengine/simpleprocess.cc @@ -0,0 +1,1190 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "rtengine.h" +#include "colortemp.h" +#include "imagesource.h" +#include "improcfun.h" +#include "curves.h" +#include "iccstore.h" +#include "clutstore.h" +#include "processingjob.h" +#include +#include "../rtgui/options.h" +#include "rawimagesource.h" +#include "../rtgui/multilangmgr.h" +#include "mytime.h" +#undef THREAD_PRIORITY_NORMAL + +namespace rtengine { +extern const Settings* settings; + +IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* pl, bool tunnelMetaData, bool flush) { + + errorCode = 0; + + ProcessingJobImpl* job = static_cast(pjob); + + if (pl) { + pl->setProgressStr ("PROGRESSBAR_PROCESSING"); + pl->setProgress (0.0); + } + + InitialImage* ii = job->initialImage; + if (!ii) { + ii = InitialImage::load (job->fname, job->isRaw, &errorCode); + if (errorCode) { + delete job; + return NULL; + } + } + procparams::ProcParams& params = job->pparams; + + // acquire image from imagesource + ImageSource* imgsrc = ii->getImageSource (); + + int tr = getCoarseBitMask(params.coarse); + int fw, fh; + imgsrc->getFullSize (fw, fh, tr); + + // check the crop params + if (params.crop.x > fw || params.crop.y > fh) { + // the crop is completely out of the image, so we disable the crop + params.crop.enabled = false; + // and we set the values to the defaults + params.crop.x = 0; + params.crop.y = 0; + params.crop.w = fw; + params.crop.h = fh; + } + else { + if ((params.crop.x + params.crop.w) > fw) { + // crop overflow in the width dimension ; we trim it + params.crop.w = fw-params.crop.x; + } + if ((params.crop.y + params.crop.h) > fh) { + // crop overflow in the height dimension ; we trim it + params.crop.h = fh-params.crop.y; + } + } +// MyTime t1,t2; +// t1.set(); + + ImProcFunctions ipf (¶ms, true); + + PreviewProps pp (0, 0, fw, fh, 1); + imgsrc->preprocess( params.raw, params.lensProf, params.coarse); + + if (params.toneCurve.autoexp) {// this enabled HLRecovery + LUTu histRedRaw(256), histGreenRaw(256), histBlueRaw(256); + imgsrc->getRAWHistogram(histRedRaw, histGreenRaw, histBlueRaw); + if (ToneCurveParams::HLReconstructionNecessary(histRedRaw, histGreenRaw, histBlueRaw) && !params.toneCurve.hrenabled) { + params.toneCurve.hrenabled=true; + // WARNING: Highlight Reconstruction is being forced 'on', should we force a method here too? + } + } + + if (pl) pl->setProgress (0.20); + imgsrc->demosaic( params.raw); + if (pl) pl->setProgress (0.30); + imgsrc->HLRecovery_Global( params.toneCurve ); + if (pl) pl->setProgress (0.40); + // set the color temperature + ColorTemp currWB = ColorTemp (params.wb.temperature, params.wb.green, params.wb.equal, params.wb.method); + if (params.wb.method=="Camera") + currWB = imgsrc->getWB (); + else if (params.wb.method=="Auto") { + double rm, gm, bm; + imgsrc->getAutoWBMultipliers(rm, gm, bm); + currWB.update(rm, gm, bm, params.wb.equal); + } + + NoiseCurve noiseLCurve; + NoiseCurve noiseCCurve; + Imagefloat *calclum = NULL ; + params.dirpyrDenoise.getCurves(noiseLCurve, noiseCCurve); + float autoNR = (float) settings->nrauto;// + float autoNRmax = (float) settings->nrautomax;// + int tilesize; + int overlap; + if(settings->leveldnti ==0) { + tilesize = 1024; + overlap = 128; + } + if(settings->leveldnti ==1) { + tilesize = 768; + overlap = 96; + } + + // const int tilesize = 768; + // const int overlap = 96; + int numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip; + ipf.Tile_calc (tilesize, overlap, 2, fw, fh, numtiles_W, numtiles_H, tilewidth, tileheight, tileWskip, tileHskip); + int nbtl=numtiles_W*numtiles_H; + if((settings->leveldnautsimpl==1 && params.dirpyrDenoise.Cmethod=="AUT") || (settings->leveldnautsimpl==0 && params.dirpyrDenoise.C2method=="AUTO")) nbtl=9; + float *ch_M = new float [nbtl];//allocate memory + float *max_r = new float [nbtl]; + float *max_b = new float [nbtl]; + float *min_b = new float [9]; + float *min_r = new float [9]; + float *lumL = new float [nbtl]; + float *chromC = new float [nbtl]; + float *ry = new float [nbtl]; + float *sk = new float [nbtl]; + float *pcsk = new float [nbtl]; + float *Max_R_ =new float [nbtl]; + float *Max_B_ = new float [nbtl]; + // printf("expert=%d\n",settings->leveldnautsimpl); + if(settings->leveldnautsimpl==1 && params.dirpyrDenoise.Cmethod=="PON") { + MyTime t1pone,t2pone; + t1pone.set(); + int crW,crH; + if(settings->leveldnv ==0) {crW=100;crH=100;} + if(settings->leveldnv ==1) {crW=250;crH=250;} + if(settings->leveldnv ==2) {crW=int(tileWskip/2);crH=int(tileHskip/2);} + // if(settings->leveldnv ==2) {crW=int(tileWskip/2);crH=int(1.15f*(tileWskip/2));}//adapted to scale of preview + if(settings->leveldnv ==3) {crW=tileWskip-10;crH=tileHskip-10;} + + float lowdenoise=1.f; + int levaut=settings->leveldnaut; + if(levaut==1) //Standard + lowdenoise=0.7f; + + // int crW=tileWskip-10;//crop noise width + // int crH=tileHskip-10;//crop noise height +// Imagefloat *origCropPart;//init auto noise +// origCropPart = new Imagefloat (crW, crH);//allocate memory + if (params.dirpyrDenoise.enabled) {//evaluate Noise + LUTf gamcurve(65536,0); + float gam, gamthresh, gamslope; + ipf.RGB_denoise_infoGamCurve(params.dirpyrDenoise, imgsrc->isRAW(), gamcurve, gam, gamthresh, gamslope); + #pragma omp parallel + { + Imagefloat *origCropPart;//init auto noise + origCropPart = new Imagefloat (crW, crH);//allocate memory + Imagefloat *provicalc = new Imagefloat ((crW+1)/2, (crH+1)/2);//for denoise curves + int skipP=1; + #pragma omp for schedule(dynamic) collapse(2) nowait + for(int wcr=0;wcrgetImage (currWB, tr, origCropPart, ppP, params.toneCurve, params.icm, params.raw ); + + // we only need image reduced to 1/4 here + for(int ii=0;iir(ii>>1,jj>>1) = origCropPart->r(ii,jj); + provicalc->g(ii>>1,jj>>1) = origCropPart->g(ii,jj); + provicalc->b(ii>>1,jj>>1) = origCropPart->b(ii,jj); + } + } + imgsrc->convertColorSpace(provicalc, params.icm, currWB);//for denoise luminance curve + float maxr=0.f; + float maxb=0.f; + float pondcorrec=1.0f; + float chaut, redaut, blueaut, maxredaut, maxblueaut, minredaut, minblueaut, nresi, highresi, chromina, sigma, lumema, sigma_L, redyel, skinc, nsknc; + int Nb; + chaut=0.f;redaut=0.f; blueaut=0.f; maxredaut=0.f; maxblueaut=0.f;chromina=0.f; sigma=0.f; + ipf.RGB_denoise_info(origCropPart, provicalc, imgsrc->isRAW(), gamcurve, gam, gamthresh, gamslope, params.dirpyrDenoise, imgsrc->getDirPyrDenoiseExpComp(), chaut, Nb, redaut, blueaut, maxredaut, maxblueaut, minredaut, minblueaut, nresi, highresi, chromina, sigma, lumema, sigma_L, redyel, skinc, nsknc); + float multip=1.f; + float adjustr=1.f; + if (params.icm.working=="ProPhoto") {adjustr =1.f;}// + else if (params.icm.working=="Adobe RGB") {adjustr = 1.f/1.3f;} + else if (params.icm.working=="sRGB") {adjustr = 1.f/1.3f;} + else if (params.icm.working=="WideGamut") {adjustr =1.f/1.1f;} + else if (params.icm.working=="Beta RGB") {adjustr =1.f/1.2f;} + else if (params.icm.working=="BestRGB") {adjustr =1.f/1.2f;} + else if (params.icm.working=="BruceRGB") {adjustr =1.f/1.2f;} + + if(!imgsrc->isRAW()) multip=2.f;//take into account gamma for TIF / JPG approximate value...not good fot gamma=1 + float maxmax=max(maxredaut,maxblueaut); + float delta; + int mode=2; + int lissage=settings->leveldnliss; + ipf.calcautodn_info (chaut, delta, Nb, levaut, maxmax, lumema, chromina, mode, lissage, redyel, skinc, nsknc); + + // printf("PROCESS cha=%f red=%f bl=%f redM=%f bluM=%f chrom=%f sigm=%f lum=%f sigL=%f\n",chaut,redaut,blueaut, maxredaut, maxblueaut, chromina, sigma, lumema, sigma_L); + if(maxredaut > maxblueaut) { + maxr=(delta)/((autoNRmax*multip*adjustr*lowdenoise)/2.f); + if(minblueaut <= minredaut && minblueaut < chaut) maxb=(-chaut+minblueaut)/(autoNRmax*multip*adjustr*lowdenoise); + } + else { + maxb=(delta)/((autoNRmax*multip*adjustr*lowdenoise)/2.f); + if(minredaut <= minblueaut && minredaut < chaut) maxr=(-chaut+minredaut)/(autoNRmax*multip*adjustr*lowdenoise); + }//maxb mxr - empirical evaluation red / blue + + ch_M[hcr*numtiles_W + wcr]=pondcorrec*chaut/(autoNR*multip*adjustr*lowdenoise); + max_r[hcr*numtiles_W + wcr]=pondcorrec*maxr; + max_b[hcr*numtiles_W + wcr]=pondcorrec*maxb; + lumL[hcr*numtiles_W + wcr]=lumema; + chromC[hcr*numtiles_W + wcr]=chromina; + ry[hcr*numtiles_W + wcr]=redyel; + sk[hcr*numtiles_W + wcr]=skinc; + pcsk[hcr*numtiles_W + wcr]=nsknc; + + } + } + + delete provicalc; + delete origCropPart; + } + + int liss=settings->leveldnliss;//smooth result around mean + + if(liss==2 || liss==3){ + // I smooth only mean and not delta (max) + float nchm=0.f; + float koef=0.4f;//between 0.1 to 0.9 + if(liss==3) koef=0.0f;//quasi auto for mean Ch + for(int wcr=0;wcrMaxR) MaxR=Max_R_[k]; + if(max_b[k]>MaxB) MaxB=Max_B_[k]; + + } + MaxBMoy/=nbtl; + MaxRMoy/=nbtl; + + for(int k=0;k MaxB) { + max_r[k]=MaxRMoy + (MaxR-MaxRMoy)*0.66f;//#std Dev + //max_b[k]=MinB; + max_b[k]=MaxBMoy + (MaxB-MaxBMoy)*0.66f; + + } + else { + max_b[k]=MaxBMoy + (MaxB-MaxBMoy)*0.66f; + //max_r[k]=MinR; + max_r[k]=MaxRMoy + (MaxR-MaxRMoy)*0.66f; + + } + } + } + + if (settings->verbose) { + t2pone.set(); + printf("Info denoise ponderated performed in %d usec:\n", t2pone.etime(t1pone)); + } + + } + } + + + if((settings->leveldnautsimpl==1 && params.dirpyrDenoise.Cmethod=="AUT") || (settings->leveldnautsimpl==0 && params.dirpyrDenoise.C2method=="AUTO")) { + MyTime t1aue,t2aue; + t1aue.set(); + int crW,crH; + if(settings->leveldnv ==0) {crW=100;crH=100;} + if(settings->leveldnv ==1) {crW=250;crH=250;} + if(settings->leveldnv ==2) {crW=int(tileWskip/2);crH=int(tileHskip/2);} + // if(settings->leveldnv ==2) {crW=int(tileWskip/2);crH=int(1.15f*(tileWskip/2));}//adapted to scale of preview + if(settings->leveldnv ==3) {crW=tileWskip-10;crH=tileHskip-10;} + + float lowdenoise=1.f; + int levaut=settings->leveldnaut; + if(levaut==1) //Standard + lowdenoise=0.7f; + + if (params.dirpyrDenoise.enabled) {//evaluate Noise + LUTf gamcurve(65536,0); + float gam, gamthresh, gamslope; + ipf.RGB_denoise_infoGamCurve(params.dirpyrDenoise, imgsrc->isRAW(), gamcurve, gam, gamthresh, gamslope); + int Nb[9]; + int coordW[3];//coordonate of part of image to mesure noise + int coordH[3]; + int begW=50; + int begH=50; + coordW[0]=begW;coordW[1]=fw/2-crW/2;coordW[2]=fw-crW-begW; + coordH[0]=begH;coordH[1]=fh/2-crH/2;coordH[2]=fh-crH-begH; + #pragma omp parallel + { + Imagefloat *origCropPart;//init auto noise + origCropPart = new Imagefloat (crW, crH);//allocate memory + Imagefloat *provicalc = new Imagefloat ((crW+1)/2, (crH+1)/2);//for denoise curves + + #pragma omp for schedule(dynamic) collapse(2) nowait + 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); + // we only need image reduced to 1/4 here + for(int ii=0;iir(ii>>1,jj>>1) = origCropPart->r(ii,jj); + provicalc->g(ii>>1,jj>>1) = origCropPart->g(ii,jj); + provicalc->b(ii>>1,jj>>1) = origCropPart->b(ii,jj); + } + } + imgsrc->convertColorSpace(provicalc, params.icm, currWB);//for denoise luminance curve + int nb = 0; + float chaut=0.f, redaut=0.f, blueaut=0.f, maxredaut=0.f, maxblueaut=0.f, minredaut=0.f, minblueaut=0.f, nresi=0.f, highresi=0.f, chromina=0.f, sigma=0.f, lumema=0.f, sigma_L=0.f, redyel=0.f, skinc=0.f, nsknc=0.f; + ipf.RGB_denoise_info(origCropPart, provicalc, imgsrc->isRAW(), gamcurve, gam, gamthresh, gamslope, params.dirpyrDenoise, imgsrc->getDirPyrDenoiseExpComp(), chaut, nb, redaut, blueaut, maxredaut, maxblueaut, minredaut, minblueaut, nresi, highresi, chromina, sigma, lumema, sigma_L, redyel, skinc, nsknc); + Nb[hcr*3 + wcr] = nb; + ch_M[hcr*3 + wcr] = chaut; + max_r[hcr*3 + wcr] = maxredaut; + max_b[hcr*3 + wcr] = maxblueaut; + min_r[hcr*3 + wcr] = minredaut; + min_b[hcr*3 + wcr] = minblueaut; + lumL[hcr*3 + wcr] = lumema; + chromC[hcr*3 + wcr] = chromina; + ry[hcr*3 + wcr] = redyel; + sk[hcr*3 + wcr] = skinc; + pcsk[hcr*3 + wcr] = nsknc; + } + } + delete provicalc; + delete origCropPart; + } + float chM=0.f; + float MaxR=0.f; + float MaxB=0.f; + float MinR=100000000.f; + float MinB=100000000.f; + float maxr=0.f; + float maxb=0.f; + float multip=1.f; + float adjustr=1.f; + float Max_R[9]={0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f}; + float Max_B[9]={0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f,0.f}; + float Min_R[9]; + float Min_B[9]; + float MaxRMoy=0.f; + float MaxBMoy=0.f; + float MinRMoy=0.f; + float MinBMoy=0.f; + + if (params.icm.working=="ProPhoto") {adjustr =1.f;} + else if (params.icm.working=="Adobe RGB") {adjustr = 1.f/1.3f;} + else if (params.icm.working=="sRGB") {adjustr = 1.f/1.3f;} + else if (params.icm.working=="WideGamut") {adjustr =1.f/1.1f;} + else if (params.icm.working=="Beta RGB") {adjustr =1.f/1.2f;} + else if (params.icm.working=="BestRGB") {adjustr =1.f/1.2f;} + else if (params.icm.working=="BruceRGB") {adjustr =1.f/1.2f;} + + if(!imgsrc->isRAW()) multip=2.f;//take into account gamma for TIF / JPG approximate value...not good fot gamma=1 + + float delta[9]; + int mode=1; + int lissage=settings->leveldnliss; + for(int k=0;k<9;k++) { + float maxmax = max(max_r[k],max_b[k]); + ipf.calcautodn_info (ch_M[k], delta[k], Nb[k], levaut, maxmax, lumL[k], chromC[k], mode, lissage, ry[k], sk[k], pcsk[k] ); + // printf("ch_M=%f delta=%f\n",ch_M[k], delta[k]); + } + for(int k=0;k<9;k++) { + if(max_r[k] > max_b[k]) { + //printf("R delta=%f koef=%f\n",delta[k],autoNRmax*multip*adjustr*lowdenoise); + Max_R[k]=(delta[k])/((autoNRmax*multip*adjustr*lowdenoise)/2.f); + Min_B[k]= -(ch_M[k]-min_b[k])/(autoNRmax*multip*adjustr*lowdenoise); + Max_B[k]=0.f; + Min_R[k]=0.f; + } + else { + //printf("B delta=%f koef=%f\n",delta[k],autoNRmax*multip*adjustr*lowdenoise); + Max_B[k]=(delta[k])/((autoNRmax*multip*adjustr*lowdenoise)/2.f); + Min_R[k]=- (ch_M[k]-min_r[k]) / (autoNRmax*multip*adjustr*lowdenoise); + Min_B[k]=0.f; + Max_R[k]=0.f; + } + } + + for(int k=0;k<9;k++) { + // printf("ch_M= %f Max_R=%f Max_B=%f min_r=%f min_b=%f\n",ch_M[k],Max_R[k], Max_B[k],Min_R[k], Min_B[k]); + chM+=ch_M[k]; + MaxBMoy+=Max_B[k]; + MaxRMoy+=Max_R[k]; + MinRMoy+=Min_R[k]; + MinBMoy+=Min_B[k]; + if(Max_R[k]>MaxR) MaxR=Max_R[k]; + if(Max_B[k]>MaxB) MaxB=Max_B[k]; + if(Min_R[k] MaxB) { + maxr=MaxRMoy + (MaxR-MaxRMoy)*0.66f;//#std Dev + // maxb=MinB; + maxb=MinBMoy + (MinB-MinBMoy)*0.66f; + + } + else { + maxb=MaxBMoy + (MaxB-MaxBMoy)*0.66f; + // maxr=MinR; + maxr=MinRMoy + (MinR-MinRMoy)*0.66f; + + } + +// printf("SIMPL cha=%f red=%f bl=%f \n",chM,maxr,maxb); + + params.dirpyrDenoise.chroma=chM/(autoNR*multip*adjustr); + params.dirpyrDenoise.redchro=maxr; + params.dirpyrDenoise.bluechro=maxb; + } + if (settings->verbose) { + t2aue.set(); + printf("Info denoise auto performed in %d usec:\n", t2aue.etime(t1aue)); + } + + //end evaluate noise + } + + + + + + Imagefloat* baseImg = new Imagefloat (fw, fh); + imgsrc->getImage (currWB, tr, baseImg, pp, params.toneCurve, params.icm, params.raw); + if (pl) pl->setProgress (0.45); + +// LUTf Noisecurve (65536,0); +//!!!// auto exposure!!! + double expcomp = params.toneCurve.expcomp; + int bright = params.toneCurve.brightness; + int contr = params.toneCurve.contrast; + int black = params.toneCurve.black; + int hlcompr = params.toneCurve.hlcompr; + int hlcomprthresh = params.toneCurve.hlcomprthresh; + + if (params.toneCurve.autoexp) { + LUTu aehist; int aehistcompr; + imgsrc->getAutoExpHistogram (aehist, aehistcompr); + ipf.getAutoExp (aehist, aehistcompr, imgsrc->getDefGain(), 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 + // commented out because it makes the application crash when batch processing... + // TODO: find a better place to flush rawData and rawRGB + if(flush) { + imgsrc->flushRawData(); + imgsrc->flushRGB(); + } + + // perform luma/chroma denoise +// CieImage *cieView; +// NoisCurve noiseLCurve; +// bool lldenoiseutili=false; +// Imagefloat *calclum ; +// params.dirpyrDenoise.getCurves(noiseLCurve, lldenoiseutili); +// if (params.dirpyrDenoise.enabled && lldenoiseutili) { + + DirPyrDenoiseParams denoiseParams = params.dirpyrDenoise; // make a copy because we cheat here + + if(denoiseParams.Lmethod == "CUR") { + if(noiseLCurve) + denoiseParams.luma = 0.5f; + else + denoiseParams.luma = 0.0f; + } else if(denoiseParams.Lmethod=="SLI") + noiseLCurve.Reset(); + if (denoiseParams.enabled && (noiseLCurve || noiseCCurve )) { + // we only need image reduced to 1/4 here + calclum = new Imagefloat ((fw+1)/2, (fh+1)/2);//for luminance denoise curve +#pragma omp parallel for + for(int ii=0;iir(ii>>1,jj>>1) = baseImg->r(ii,jj); + calclum->g(ii>>1,jj>>1) = baseImg->g(ii,jj); + calclum->b(ii>>1,jj>>1) = baseImg->b(ii,jj); + } + } + imgsrc->convertColorSpace(calclum, params.icm, currWB); + } + if (denoiseParams.enabled) { + // 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; + 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); + + } + // delete calclum; + delete [] ch_M; + delete [] max_r; + delete [] max_b; + delete [] min_r; + delete [] min_b; + delete [] lumL; + delete [] chromC; + delete [] ry; + delete [] sk; + delete [] pcsk; + delete [] Max_R_; + delete [] Max_B_; + + imgsrc->convertColorSpace(baseImg, params.icm, currWB); + + // perform first analysis + LUTu hist16 (65536); + LUTu hist16C (65536); + + ipf.firstAnalysis (baseImg, ¶ms, hist16); + + // 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->getRotateDegree(), true); + delete baseImg; + baseImg = trImg; + } + + // update blurmap + SHMap* shmap = NULL; + if (params.sh.enabled) { + shmap = new SHMap (fw, fh, true); + double radius = sqrt (double(fw*fw+fh*fh)) / 2.0; + double shradius = params.sh.radius; + if (!params.sh.hq) shradius *= radius / 1800.0; + shmap->update (baseImg, shradius, ipf.lumimul, params.sh.hq, 1); + } + // RGB processing + + LUTf curve1 (65536); + LUTf curve2 (65536); + LUTf curve (65536,0); + LUTf satcurve (65536,0); + LUTf lhskcurve (65536,0); + LUTf lumacurve(65536,0); + LUTf clcurve (65536,0); + LUTf clToningcurve (65536,0); + LUTf cl2Toningcurve (65536,0); + LUTf wavclCurve (65536,0); + + LUTf rCurve (65536,0); + LUTf gCurve (65536,0); + LUTf bCurve (65536,0); + LUTu dummy; + + ToneCurve customToneCurve1, customToneCurve2; + ColorGradientCurve ctColorCurve; + OpacityCurve ctOpacityCurve; + ColorAppearance customColCurve1, customColCurve2,customColCurve3 ; + ToneCurve customToneCurvebw1; + ToneCurve customToneCurvebw2; + //if(params.blackwhite.enabled) params.toneCurve.hrenabled=false; + + ipf.g = imgsrc->getGamma(); + ipf.iGamma = true; + CurveFactory::complexCurve (0.0, black/65535.0, hlcompr, hlcomprthresh, params.toneCurve.shcompr, bright, contr, ipf.g, !ipf.iGamma, + params.toneCurve.curveMode, params.toneCurve.curve, params.toneCurve.curveMode2, params.toneCurve.curve2, + hist16, dummy, curve1, curve2, curve, dummy, customToneCurve1, customToneCurve2 ); + + CurveFactory::RGBCurve (params.rgbCurves.rcurve, rCurve, 1); + CurveFactory::RGBCurve (params.rgbCurves.gcurve, gCurve, 1); + CurveFactory::RGBCurve (params.rgbCurves.bcurve, bCurve, 1); + + TMatrix wprof = iccStore->workingSpaceMatrix (params.icm.working); + TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params.icm.working); + + double wp[3][3] = { + {wprof[0][0],wprof[0][1],wprof[0][2]}, + {wprof[1][0],wprof[1][1],wprof[1][2]}, + {wprof[2][0],wprof[2][1],wprof[2][2]}}; + 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]} + }; + bool opautili=false; + params.colorToning.getCurves(ctColorCurve, ctOpacityCurve, wp, wip, opautili); + + bool clctoningutili=false; + CurveFactory::curveToningCL(clctoningutili, params.colorToning.clcurve, clToningcurve, 1); + bool llctoningutili=false; + CurveFactory::curveToningLL(llctoningutili, params.colorToning.cl2curve, cl2Toningcurve, 1); + + LabImage* labView = new LabImage (fw,fh); + + + CurveFactory::curveBW (params.blackwhite.beforeCurve, params.blackwhite.afterCurve, hist16, dummy, customToneCurvebw1, customToneCurvebw2, 1); + double rrm, ggm, bbm; + float autor, autog, autob; + float satLimit = float(params.colorToning.satProtectionThreshold)/100.f*0.7f+0.3f; + float satLimitOpacity = 1.f-(float(params.colorToning.saturatedOpacity)/100.f); + + if(params.colorToning.enabled && params.colorToning.autosat){//for colortoning evaluation of saturation settings + float moyS=0.f; + float eqty=0.f; + ipf.moyeqt (baseImg, moyS, eqty);//return image : mean saturation and standard dev of saturation + //printf("moy=%f ET=%f\n", moyS,eqty); + float satp=((moyS+1.5f*eqty)-0.3f)/0.7f;//1.5 sigma ==> 93% pixels with high saturation -0.3 / 0.7 convert to Hombre scale + if(satp >= 0.92f) satp=0.92f;//avoid values too high (out of gamut) + if(satp <= 0.15f) satp=0.15f;//avoid too low values + + satLimit= 100.f*satp; + + satLimitOpacity= 100.f*(moyS-0.85f*eqty);//-0.85 sigma==>20% pixels with low saturation + } + + autor = -9000.f; // This will ask to compute the "auto" values for the B&W tool (have to be inferior to -5000) + DCPProfile *dcpProf = imgsrc->getDCP(params.icm, currWB); + ipf.rgbProc (baseImg, labView, NULL, curve1, curve2, curve, shmap, params.toneCurve.saturation, rCurve, gCurve, bCurve, satLimit ,satLimitOpacity, ctColorCurve, ctOpacityCurve, opautili, clToningcurve, cl2Toningcurve,customToneCurve1, customToneCurve2,customToneCurvebw1, customToneCurvebw2, rrm, ggm, bbm, autor, autog, autob, expcomp, hlcompr, hlcomprthresh, dcpProf); + if (settings->verbose) + printf("Output image / Auto B&W coefs: R=%.2f G=%.2f B=%.2f\n", autor, autog, autob); + + // if clut was used and size of clut cache == 1 we free the memory used by the clutstore (default clut cache size = 1 for 32 bit OS) + if ( params.filmSimulation.enabled && !params.filmSimulation.clutFilename.empty() && options.clutCacheSize == 1) + clutStore.clearCache(); + + // freeing up some memory + customToneCurve1.Reset(); + customToneCurve2.Reset(); + ctColorCurve.Reset(); + ctOpacityCurve.Reset(); + noiseLCurve.Reset(); + noiseCCurve.Reset(); + customToneCurvebw1.Reset(); + customToneCurvebw2.Reset(); + + // Freeing baseImg because not used anymore + delete baseImg; + baseImg = NULL; + + if (shmap) + delete shmap; + shmap = NULL; + + if (pl) + pl->setProgress (0.5); + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + // start tile processing...??? + + hist16.clear(); hist16C.clear(); + if(params.labCurve.contrast !=0) {//only use hist16 for contrast + +#ifdef _OPENMP +#pragma omp parallel shared(hist16,labView, fh, fw) +#endif +{ + LUTu hist16thr (65536); // one temporary lookup table per thread + hist16thr.clear(); +#ifdef _OPENMP +#pragma omp for schedule(static) nowait +#endif + for (int i=0; iL[i][j])))]++; + } + +#pragma omp critical +{ + for(int i=0;i<65536;i++) + hist16[i] += hist16thr[i]; +} +} + + + } + bool utili=false; + bool autili=false; + bool butili=false; + bool ccutili=false; + bool cclutili=false; + bool clcutili=false; + + CurveFactory::complexLCurve (params.labCurve.brightness, params.labCurve.contrast, params.labCurve.lcurve,hist16, hist16, lumacurve, dummy, 1, utili); + CurveFactory::curveCL(clcutili, params.labCurve.clcurve, clcurve, hist16C, dummy, 1); + + CurveFactory::complexsgnCurve (1.f, autili, butili, ccutili, cclutili, params.labCurve.chromaticity, params.labCurve.rstprotection, + params.labCurve.acurve, params.labCurve.bcurve, params.labCurve.cccurve,params.labCurve.lccurve,curve1, curve2, satcurve,lhskcurve, + hist16C, hist16C, dummy,dummy, + 1); + + ipf.chromiLuminanceCurve (NULL, 1,labView, labView, curve1, curve2, satcurve,lhskcurve,clcurve, lumacurve, utili, autili, butili, ccutili,cclutili, clcutili, dummy, dummy, dummy, dummy); + + if((params.colorappearance.enabled && !params.colorappearance.tonecie) || (!params.colorappearance.enabled))ipf.EPDToneMap(labView,5,1); + + + ipf.vibrance(labView); + + if((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) ipf.impulsedenoise (labView); + // for all treatments Defringe, Sharpening, Contrast detail ,Microcontrast they are activated if "CIECAM" function are disabled + + if((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) ipf.defringe (labView); + + if (params.sharpenEdge.enabled) { + ipf.MLsharpen(labView); + } + if (params.sharpenMicro.enabled) { + if((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) ipf.MLmicrocontrast (labView);//!params.colorappearance.sharpcie + } + + if(((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) && params.sharpening.enabled) { + + float **buffer = new float*[fh]; + for (int i=0; iautocielab) || !params.colorappearance.enabled) ipf.dirpyrequalizer (labView, 1);//TODO: this is the luminance tonecurve, not the RGB one + int kall=2; + bool wavcontlutili=false; + + CurveFactory::curveWavContL(wavcontlutili, params.wavelet.wavclCurve, wavclCurve,/* hist16C, dummy,*/ 1); + + if((params.wavelet.enabled)) ipf.ip_wavelet(labView, labView, kall, WaveParams, wavCLVCurve, waOpacityCurveRG, waOpacityCurveBY, waOpacityCurveW, waOpacityCurveWL, wavclCurve, wavcontlutili, 1); + wavCLVCurve.Reset(); + + //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;f_h=fh;} + CieImage *cieView = new CieImage (f_w,(f_h)); + begh=0; + endh=fh; + CurveFactory::curveLightBrightColor ( + params.colorappearance.curveMode, params.colorappearance.curve, + params.colorappearance.curveMode2, params.colorappearance.curve2, + params.colorappearance.curveMode3, params.colorappearance.curve3, + hist16, hist16,dummy, + hist16C, dummy, + customColCurve1, + customColCurve2, + customColCurve3, + 1); + 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 + - + if(fnum < 0.3f || fiso < 5.f || fspeed < 0.00001f) { + adap=2000.; + }//if no exif data or wrong + else { + float E_V = fcomp + log2 ((fnum*fnum) / fspeed / (fiso/100.f)); + E_V += params.toneCurve.expcomp;// exposure compensation in tonecurve ==> direct EV + E_V += log2(params.raw.expos);// exposure raw white point ; log2 ==> linear to EV + adap = powf(2.f, E_V-3.f);//cd / m2 + } + LUTf CAMBrightCurveJ; + LUTf CAMBrightCurveQ; + float CAMMean; + if (params.sharpening.enabled) { + float d; + double dd; + + int sk=1; + if(settings->ciecamfloat) ipf.ciecam_02float (cieView, float(adap), begh, endh,1,2, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, true, d, sk, 1); + else ipf.ciecam_02 (cieView, adap, begh, endh,1,2, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, true, dd, 1, 1); + } + else { + float d; + + double dd; + int sk=1; + if(settings->ciecamfloat) ipf.ciecam_02float (cieView, float(adap), begh, endh,1,2, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, true, d, sk, 1); + else ipf.ciecam_02 (cieView, adap, begh, endh,1, 2, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, true, dd, 1, 1); + } + } + delete cieView; + cieView = NULL; + + + + + // end tile processing...??? + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + if (pl) pl->setProgress (0.60); + + int imw, imh; + double tmpScale = ipf.resizeScale(¶ms, fw, fh, imw, imh); + bool labResize = params.resize.enabled && params.resize.method != "Nearest" && tmpScale != 1.0; + LabImage *tmplab; + + // crop and convert to rgb16 + int cx = 0, cy = 0, cw = labView->W, ch = labView->H; + if (params.crop.enabled) { + cx = params.crop.x; + cy = params.crop.y; + cw = params.crop.w; + ch = params.crop.h; + if(labResize) { // crop lab data + tmplab = new LabImage(cw,ch); + for(int row = 0;rowL[row][col] = labView->L[row+cy][col+cx]; + tmplab->a[row][col] = labView->a[row+cy][col+cx]; + tmplab->b[row][col] = labView->b[row+cy][col+cx]; + } + } + delete labView; + labView = tmplab; + cx = 0; + cy = 0; + } + } + + if (labResize) { // resize lab data + // resize image + tmplab = new LabImage(imw,imh); + ipf.Lanczos (labView, tmplab, tmpScale); + delete labView; + labView = tmplab; + cw = labView->W; + ch = labView->H; + if(params.prsharpening.enabled) { + float **buffer = new float*[ch]; + for (int i=0; i opnames = iccStore->getOutputProfiles (); + //test if files are in system + for (int j=0; j<9; j++) { + // one can modify "option" [Color Management] to adapt the profile's name if they are different for windows, MacOS, Linux ?? + // some of them are actually provided by RT, thanks to Jacques Desmis + if (j==0) chpro=options.rtSettings.prophoto; + else if(j==1) chpro=options.rtSettings.adobe; + else if(j==2) chpro=options.rtSettings.widegamut; + else if(j==3) chpro=options.rtSettings.beta; + else if(j==4) chpro=options.rtSettings.best; + else if(j==5) chpro=options.rtSettings.bruce; + else if(j==6) chpro=options.rtSettings.srgb; + else if(j==7) chpro=options.rtSettings.srgb10;//gamma 1.0 + else if(j==8) chpro=options.rtSettings.prophoto10;//gamma 1.0 + + for (unsigned int i=0; iverbose) printf("Missing file: %s\n", chpro.c_str()); + } + if (params.icm.freegamma && params.icm.gampos < 1.35) pro=true; //select profil with gammaTRC modified : + else if (params.icm.gamma=="linear_g1.0" || (params.icm.gamma=="High_g1.3_s3.35")) pro=true;//pro=0 RT_sRGB || Prophoto + + // Check that output profiles exist, otherwise use LCMS2 + // Use the icc/icm profiles associated to possible working profiles, set in "options" + if (params.icm.working=="ProPhoto" && present_space[0] && !pro) outProfile=options.rtSettings.prophoto; + else if (params.icm.working=="Adobe RGB" && present_space[1] ) outProfile=options.rtSettings.adobe; + else if (params.icm.working=="WideGamut" && present_space[2] ) outProfile=options.rtSettings.widegamut; + else if (params.icm.working=="Beta RGB" && present_space[3] ) outProfile=options.rtSettings.beta; + else if (params.icm.working=="BestRGB" && present_space[4] ) outProfile=options.rtSettings.best; + else if (params.icm.working=="BruceRGB" && present_space[5] ) outProfile=options.rtSettings.bruce; + else if (params.icm.working=="sRGB" && present_space[6] && !pro) outProfile=options.rtSettings.srgb; + else if (params.icm.working=="sRGB" && present_space[7] && pro) outProfile=options.rtSettings.srgb10; + else if (params.icm.working=="ProPhoto" && present_space[8] && pro) outProfile=options.rtSettings.prophoto10; + else { + // Should not occurs + if (settings->verbose) printf("\"%s\": unknown working profile! - use LCMS2 substitution\n", params.icm.working.c_str() ); + useLCMS=true; + } + + //begin adaptation rTRC gTRC bTRC + //"jprof" profile has the same characteristics than RGB values, but TRC are adapted... for applying profile + if (!useLCMS) { + if (settings->verbose) printf("Output Gamma - profile: \"%s\"\n", outProfile.c_str() ); //c_str() + jprof = iccStore->getProfile(outProfile); //get output profile + if (jprof == NULL) { + useLCMS = true; + if (settings->verbose) printf("\"%s\" ICC output profile not found!\n", outProfile.c_str()); + } + else { + Parameters[0] = ga0; + Parameters[1] = ga1; + Parameters[2] = ga2; + Parameters[3] = ga3; + Parameters[4] = ga4; + Parameters[5] = ga5; + Parameters[6] = ga6; + // 7 parameters for smoother curves + //change desc Tag , to "free gamma", or "BT709", etc. + cmsContext ContextID = cmsGetProfileContextID(jprof);//modification TAG + DescriptionMLU = cmsMLUalloc(ContextID, 1); + CopyrightMLU = cmsMLUalloc(ContextID, 1);//for ICC + DmndMLU=cmsMLUalloc(ContextID, 1);//for ICC + DmddMLU=cmsMLUalloc(ContextID, 1);// for ICC + + + // instruction with //ICC are used for generate icc profile + if (DescriptionMLU == NULL) printf("Description error\n"); + cmsMLUsetWide(CopyrightMLU, "en", "US", L"General Public License - AdobeRGB compatible") ;//adapt to profil + cmsMLUsetWide(DmndMLU, "en", "US", L"RawTherapee") ; + cmsMLUsetWide(DmddMLU, "en", "US", L"RTMedium") ; //adapt to profil + //display Tag desc with : selection of gamma and Primaries + if (!params.icm.freegamma) { + std::wstring gammaStr; + if(params.icm.gamma=="High_g1.3_s3.35") { + gammaStr = std::wstring(L"GammaTRC: High g=1.3 s=3.35"); + } + else if (params.icm.gamma=="Low_g2.6_s6.9") { + gammaStr = std::wstring(L"GammaTRC: Low g=2.6 s=6.9"); + } + else if (params.icm.gamma=="sRGB_g2.4_s12.92") { + gammaStr = std::wstring(L"GammaTRC: sRGB g=2.4 s=12.92"); + } + else if (params.icm.gamma== "BT709_g2.2_s4.5") { + gammaStr = std::wstring(L"GammaTRC: BT709 g=2.2 s=4.5"); + } + else if (params.icm.gamma== "linear_g1.0") { + gammaStr = std::wstring(L"GammaTRC: Linear g=1.0"); + } + else if (params.icm.gamma== "standard_g2.2") { + gammaStr = std::wstring(L"GammaTRC: g=2.2"); + } + else if (params.icm.gamma== "standard_g1.8") { + gammaStr = std::wstring(L"GammaTRC: g=1.8"); + } + cmsMLUsetWide(DescriptionMLU, "en", "US", gammaStr.c_str()); + + //for elaboration ICC profiles + // else if (params.icm.gamma== "sRGB_g2.4_s12.92" && !params.icm.freegamma) cmsMLUsetWide(DescriptionMLU, "en", "US", L"RT_Medium gamma sRGB(AdobeRGB compatible)"); + // else if (params.icm.gamma== "BT709_g2.2_s4.5" && !params.icm.freegamma) cmsMLUsetWide(DescriptionMLU, "en", "US", L"RT_sRGB gamma BT709(IEC61966 equivalent)"); + // else if (params.icm.gamma== "sRGB_g2.4_s12.92" && !params.icm.freegamma) cmsMLUsetWide(DescriptionMLU, "en", "US", L"RT_sRGB gamma sRGB(IEC61966 equivalent)"); + // else if (params.icm.gamma== "linear_g1.0" && !params.icm.freegamma) cmsMLUsetWide(DescriptionMLU, "en", "US", L"RT_sRGB gamma Linear1.0(IEC61966 equivalent)"); + //else if (params.icm.gamma== "BT709_g2.2_s4.5" && !params.icm.freegamma) cmsMLUsetWide(DescriptionMLU, "en", "US", L"RT_Large gamma BT709(Prophoto compatible)"); + // else if (params.icm.gamma== "sRGB_g2.4_s12.92" && !params.icm.freegamma) cmsMLUsetWide(DescriptionMLU, "en", "US", L"RT_Large gamma sRGB(Prophoto compatible)"); + // else if (params.icm.gamma== "linear_g1.0" && !params.icm.freegamma) cmsMLUsetWide(DescriptionMLU, "en", "US", L"RT_Large gamma Linear1.0(Prophoto compatible)"); + } + else { + // create description with gamma + slope + primaries + std::wostringstream gammaWs; + gammaWs.precision(2); + gammaWs<<"Manual GammaTRC: g="<<(float)params.icm.gampos<<" s="<<(float)params.icm.slpos; + cmsMLUsetWide(DescriptionMLU, "en", "US", gammaWs.str().c_str()); + } + + cmsWriteTag(jprof, cmsSigProfileDescriptionTag, DescriptionMLU);//desc changed + // cmsWriteTag(jprof, cmsSigCopyrightTag, CopyrightMLU); + // cmsWriteTag(jprof, cmsSigDeviceMfgDescTag, DmndMLU); + // cmsWriteTag(jprof, cmsSigDeviceModelDescTag, DmddMLU); + + // Calculate output profile's rTRC bTRC gTRC + GammaTRC[0] = GammaTRC[1] = GammaTRC[2] = cmsBuildParametricToneCurve(NULL, 5, Parameters); + cmsWriteTag(jprof, cmsSigGreenTRCTag, (void*)GammaTRC[1] ); + cmsWriteTag(jprof, cmsSigRedTRCTag, (void*)GammaTRC[0] ); + cmsWriteTag(jprof, cmsSigBlueTRCTag, (void*)GammaTRC[2] ); + //for generation ICC profiles : here Prophoto ==> Large + // if(params.icm.gamma== "BT709_g2.2_s4.5") cmsSaveProfileToFile(jprof, "RT_sRGB_gBT709.icm"); + // else if (params.icm.gamma== "sRGB_g2.4_s12.92") cmsSaveProfileToFile(jprof, "RT_Medium_gsRGB.icc"); + // else if (params.icm.gamma== "linear_g1.0") cmsSaveProfileToFile(jprof, "RT_Large_g10.icc"); + + + } + } + if (GammaTRC[0]) cmsFreeToneCurve(GammaTRC[0]); + } + else { + // 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.output, params.blackwhite.enabled); + bool bwonly = params.blackwhite.enabled && !params.colorToning.enabled ; + if(autili || butili ) bwonly = false; + readyImg = ipf.lab2rgb16 (labView, cx, cy, cw, ch, params.icm.output, bwonly); + if (settings->verbose) printf("Output profile_: \"%s\"\n", params.icm.output.c_str()); + } + + delete labView; + labView = NULL; + + + + if(!autili && !butili ) { + if(params.blackwhite.enabled && !params.colorToning.enabled ) {//force BW r=g=b + if (settings->verbose) printf("Force BW\n"); + for (int ccw=0;ccwr(cch,ccw)=readyImg->g(cch,ccw); + readyImg->b(cch,ccw)=readyImg->g(cch,ccw); + } + } + } + } + if (pl) pl->setProgress (0.70); + + if (tmpScale != 1.0 && params.resize.method == "Nearest") { // resize rgb data (gamma applied) + Image16* tempImage = new Image16 (imw, imh); + ipf.resize (readyImg, tempImage, tmpScale); + delete readyImg; + readyImg = tempImage; + } + + if (tunnelMetaData) + readyImg->setMetadata (ii->getMetaData()->getExifData ()); + else + readyImg->setMetadata (ii->getMetaData()->getExifData (), params.exif, params.iptc); + + + // Setting the output curve to readyImg + if (customGamma) { + if (!useLCMS) { + // use corrected sRGB profile in order to apply a good TRC if present, otherwise use LCMS2 profile generated by lab2rgb16b + ProfileContent pc(jprof); + readyImg->setOutputProfile (pc.data, pc.length); + } + } + else { + // use RT_sRGB.icm profile if present, otherwise use LCMS2 profile generate by lab2rgb16b + Glib::ustring outputProfile; + if (params.icm.output!="" && params.icm.output!=ColorManagementParams::NoICMString) { + outputProfile = params.icm.output; + + /* if we'd wanted the RT_sRGB profile we would have selected it + else { + // use RT_sRGB.icm profile if present, otherwise use LCMS2 profile generate by lab2rgb16b + if (settings->verbose) printf("No output profiles set ; looking for the default sRGB profile (\"%s\")...\n", options.rtSettings.srgb.c_str()); + outputProfile = options.rtSettings.srgb; + }*/ + + // if iccStore->getProfile send back an object, then iccStore->getContent will do too + cmsHPROFILE jprof = iccStore->getProfile(outputProfile); //get outProfile + if (jprof == NULL) { + if (settings->verbose) printf("\"%s\" ICC output profile not found!\n - use LCMS2 substitution\n", outputProfile.c_str()); + } + else { + if (settings->verbose) printf("Using \"%s\" output profile\n", outputProfile.c_str()); + ProfileContent pc = iccStore->getContent (outputProfile); + readyImg->setOutputProfile (pc.data, pc.length); + } + } else { + // No ICM + readyImg->setOutputProfile (NULL,0); + } + } +// t2.set(); +// if( settings->verbose ) +// printf("Total:- %d usec\n", t2.etime(t1)); + + if (!job->initialImage) + ii->decreaseRef (); + + delete job; + if (pl) + pl->setProgress (0.75); +/* curve1.reset();curve2.reset(); + curve.reset(); + satcurve.reset(); + lhskcurve.reset(); + + rCurve.reset(); + gCurve.reset(); + bCurve.reset(); + hist16.reset(); + hist16C.reset(); +*/ + return readyImg; +} + +void batchProcessingThread (ProcessingJob* job, BatchProcessingListener* bpl, bool tunnelMetaData) { + + ProcessingJob* currentJob = job; + + while (currentJob) { + int errorCode; + IImage16* img = processImage (currentJob, errorCode, bpl, tunnelMetaData, true); + if (errorCode) { + bpl->error (M("MAIN_MSG_CANNOTLOAD")); + currentJob = NULL; + } else { + try { + currentJob = bpl->imageReady (img); + } catch (Glib::Exception& ex) { + bpl->error (ex.what()); + currentJob = NULL; + } + } + } +} + +void startBatchProcessing (ProcessingJob* job, BatchProcessingListener* bpl, bool tunnelMetaData) { + + if (bpl) +#if __GNUC__ == 4 && __GNUC_MINOR__ == 8 && defined( WIN32 ) && defined(__x86_64__) + // See Issue 2384 "Very bad response time on win7/64 using gcc 4.8 when queue is running" + Glib::Thread::create(sigc::bind(sigc::ptr_fun(batchProcessingThread), job, bpl, tunnelMetaData), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); +#else + Glib::Thread::create(sigc::bind(sigc::ptr_fun(batchProcessingThread), job, bpl, tunnelMetaData), 0, true, true, Glib::THREAD_PRIORITY_LOW); +#endif + +} + +} diff --git a/rtengine/simpleprocess.h b/rtengine/simpleprocess.h new file mode 100644 index 000000000..fb5a24ff6 --- /dev/null +++ b/rtengine/simpleprocess.h @@ -0,0 +1,26 @@ +/* + * File: simpleprocess.h + * Author: askv + * + * Created on September 18, 2010, 8:31 PM + */ + +#ifndef SIMPLEPROCESS_H +#define SIMPLEPROCESS_H + +#ifdef __cplusplus +extern "C" { +#endif + + + + +#ifdef __cplusplus +} +#endif +namespace rtengine { + +extern Glib::Thread *batchThread; +} +#endif /* SIMPLEPROCESS_H */ + diff --git a/rtengine/sleef.c b/rtengine/sleef.c new file mode 100755 index 000000000..c7b3fb486 --- /dev/null +++ b/rtengine/sleef.c @@ -0,0 +1,1253 @@ +#ifndef _SLEEFC_ +#define _SLEEFC_ + +#include +#include +#include +//#include +//#include + +#define PI4_A .7853981554508209228515625 +#define PI4_B .794662735614792836713604629039764404296875e-8 +#define PI4_C .306161699786838294306516483068750264552437361480769e-16 +#define M_4_PI 1.273239544735162542821171882678754627704620361328125 + +#define L2U .69314718055966295651160180568695068359375 +#define L2L .28235290563031577122588448175013436025525412068e-12 +#define R_LN2 1.442695040888963407359924681001892137426645954152985934135449406931 + +__inline int64_t doubleToRawLongBits(double d) { + union { + double f; + int64_t i; + } tmp; + tmp.f = d; + return tmp.i; +} + +__inline double longBitsToDouble(int64_t i) { + union { + double f; + int64_t i; + } tmp; + tmp.i = i; + return tmp.f; +} + +__inline double xfabs(double x) { + return longBitsToDouble(0x7fffffffffffffffLL & doubleToRawLongBits(x)); +} + +__inline double mulsign(double x, double y) { + return longBitsToDouble(doubleToRawLongBits(x) ^ (doubleToRawLongBits(y) & (1LL << 63))); +} + +__inline double sign(double d) { return mulsign(1, d); } +__inline double mla(double x, double y, double z) { return x * y + z; } +__inline double xrint(double x) { return x < 0 ? (int)(x - 0.5) : (int)(x + 0.5); } + +__inline int xisnan(double x) { return x != x; } +__inline int xisinf(double x) { return x == INFINITY || x == -INFINITY; } +__inline int xisminf(double x) { return x == -INFINITY; } +__inline int xispinf(double x) { return x == INFINITY; } + +__inline double ldexpk(double x, int q) { + double u; + int m; + m = q >> 31; + m = (((m + q) >> 9) - m) << 7; + q = q - (m << 2); + u = longBitsToDouble(((int64_t)(m + 0x3ff)) << 52); + x = x * u * u * u * u; + u = longBitsToDouble(((int64_t)(q + 0x3ff)) << 52); + return x * u; +} + +__inline double xldexp(double x, int q) { return ldexpk(x, q); } + +__inline int ilogbp1(double d) { + int m = d < 4.9090934652977266E-91; + d = m ? 2.037035976334486E90 * d : d; + int q = (doubleToRawLongBits(d) >> 52) & 0x7ff; + q = m ? q - (300 + 0x03fe) : q - 0x03fe; + return q; +} + +__inline int xilogb(double d) { + int e = ilogbp1(xfabs(d)) - 1; + e = d == 0 ? (-2147483647 - 1) : e; + e = d == INFINITY || d == -INFINITY ? 2147483647 : e; + return e; +} + +__inline double upper(double d) { + return longBitsToDouble(doubleToRawLongBits(d) & 0xfffffffff8000000LL); +} + +typedef struct { + double x, y; +} double2; + +typedef struct { + float x, y; +} float2; + +__inline double2 dd(double h, double l) { + double2 ret; + ret.x = h; ret.y = l; + return ret; +} + +__inline double2 normalize_d(double2 t) { + double2 s; + + s.x = t.x + t.y; + s.y = t.x - s.x + t.y; + + return s; +} + +__inline double2 scale_d(double2 d, double s) { + double2 r; + + r.x = d.x * s; + r.y = d.y * s; + + return r; +} + +__inline double2 add2_ss(double x, double y) { + double2 r; + + r.x = x + y; + double v = r.x - x; + r.y = (x - (r.x - v)) + (y - v); + + return r; +} + +__inline double2 add_ds(double2 x, double y) { + // |x| >= |y| + + double2 r; + + assert(xisnan(x.x) || xisnan(y) || xfabs(x.x) >= xfabs(y)); + + r.x = x.x + y; + r.y = x.x - r.x + y + x.y; + + return r; +} + +__inline double2 add2_ds(double2 x, double y) { + // |x| >= |y| + + double2 r; + + r.x = x.x + y; + double v = r.x - x.x; + r.y = (x.x - (r.x - v)) + (y - v); + r.y += x.y; + + return r; +} + +__inline double2 add_sd(double x, double2 y) { + // |x| >= |y| + + double2 r; + + assert(xisnan(x) || xisnan(y.x) || xfabs(x) >= xfabs(y.x)); + + r.x = x + y.x; + r.y = x - r.x + y.x + y.y; + + return r; +} + +__inline double2 add_dd(double2 x, double2 y) { + // |x| >= |y| + + double2 r; + + assert(xisnan(x.x) || xisnan(y.x) || xfabs(x.x) >= xfabs(y.x)); + + r.x = x.x + y.x; + r.y = x.x - r.x + y.x + x.y + y.y; + + return r; +} + +__inline double2 add2_dd(double2 x, double2 y) { + double2 r; + + r.x = x.x + y.x; + double v = r.x - x.x; + r.y = (x.x - (r.x - v)) + (y.x - v); + r.y += x.y + y.y; + + return r; +} + +__inline double2 div_dd(double2 n, double2 d) { + double t = 1.0 / d.x; + double dh = upper(d.x), dl = d.x - dh; + double th = upper(t ), tl = t - th; + double nhh = upper(n.x), nhl = n.x - nhh; + + double2 q; + + q.x = n.x * t; + + double u = -q.x + nhh * th + nhh * tl + nhl * th + nhl * tl + + q.x * (1 - dh * th - dh * tl - dl * th - dl * tl); + + q.y = t * (n.y - q.x * d.y) + u; + + return q; +} + +__inline double2 mul_ss(double x, double y) { + double xh = upper(x), xl = x - xh; + double yh = upper(y), yl = y - yh; + double2 r; + + r.x = x * y; + r.y = xh * yh - r.x + xl * yh + xh * yl + xl * yl; + + return r; +} + +__inline double2 mul_ds(double2 x, double y) { + double xh = upper(x.x), xl = x.x - xh; + double yh = upper(y ), yl = y - yh; + double2 r; + + r.x = x.x * y; + r.y = xh * yh - r.x + xl * yh + xh * yl + xl * yl + x.y * y; + + return r; +} + +__inline double2 mul_dd(double2 x, double2 y) { + double xh = upper(x.x), xl = x.x - xh; + double yh = upper(y.x), yl = y.x - yh; + double2 r; + + r.x = x.x * y.x; + r.y = xh * yh - r.x + xl * yh + xh * yl + xl * yl + x.x * y.y + x.y * y.x; + + return r; +} + +__inline double2 squ_d(double2 x) { + double xh = upper(x.x), xl = x.x - xh; + double2 r; + + r.x = x.x * x.x; + r.y = xh * xh - r.x + (xh + xh) * xl + xl * xl + x.x * (x.y + x.y); + + return r; +} + +__inline double2 rec_s(double d) { + double t = 1.0 / d; + double dh = upper(d), dl = d - dh; + double th = upper(t), tl = t - th; + double2 q; + + q.x = t; + q.y = t * (1 - dh * th - dh * tl - dl * th - dl * tl); + + return q; +} + +__inline double2 sqrt_d(double2 d) { + double t = sqrt(d.x + d.y); + return scale_d(mul_dd(add2_dd(d, mul_ss(t, t)), rec_s(t)), 0.5); +} + +__inline double atan2k(double y, double x) { + double s, t, u; + int q = 0; + + if (x < 0) { x = -x; q = -2; } + if (y > x) { t = x; x = y; y = -t; q += 1; } + + s = y / x; + t = s * s; + + u = -1.88796008463073496563746e-05; + u = u * t + (0.000209850076645816976906797); + u = u * t + (-0.00110611831486672482563471); + u = u * t + (0.00370026744188713119232403); + u = u * t + (-0.00889896195887655491740809); + u = u * t + (0.016599329773529201970117); + u = u * t + (-0.0254517624932312641616861); + u = u * t + (0.0337852580001353069993897); + u = u * t + (-0.0407629191276836500001934); + u = u * t + (0.0466667150077840625632675); + u = u * t + (-0.0523674852303482457616113); + u = u * t + (0.0587666392926673580854313); + u = u * t + (-0.0666573579361080525984562); + u = u * t + (0.0769219538311769618355029); + u = u * t + (-0.090908995008245008229153); + u = u * t + (0.111111105648261418443745); + u = u * t + (-0.14285714266771329383765); + u = u * t + (0.199999999996591265594148); + u = u * t + (-0.333333333333311110369124); + + t = u * t * s + s; + t = q * (M_PI/2) + t; + + return t; +} + +__inline double xatan2(double y, double x) { + double r = atan2k(xfabs(y), x); + + r = mulsign(r, x); + if (xisinf(x) || x == 0) r = M_PI/2 - (xisinf(x) ? (sign(x) * (M_PI /2)) : 0); + if (xisinf(y) ) r = M_PI/2 - (xisinf(x) ? (sign(x) * (M_PI*1/4)) : 0); + if ( y == 0) r = (sign(x) == -1 ? M_PI : 0); + + return xisnan(x) || xisnan(y) ? NAN : mulsign(r, y); +} + +__inline double xasin(double d) { + return mulsign(atan2k(xfabs(d), sqrt((1+d)*(1-d))), d); +} + +__inline double xacos(double d) { + return mulsign(atan2k(sqrt((1+d)*(1-d)), xfabs(d)), d) + (d < 0 ? M_PI : 0); +} + +__inline double xatan(double s) { + double t, u; + int q = 0; + + if (s < 0) { s = -s; q = 2; } + if (s > 1) { s = 1.0 / s; q |= 1; } + + t = s * s; + + u = -1.88796008463073496563746e-05; + u = u * t + (0.000209850076645816976906797); + u = u * t + (-0.00110611831486672482563471); + u = u * t + (0.00370026744188713119232403); + u = u * t + (-0.00889896195887655491740809); + u = u * t + (0.016599329773529201970117); + u = u * t + (-0.0254517624932312641616861); + u = u * t + (0.0337852580001353069993897); + u = u * t + (-0.0407629191276836500001934); + u = u * t + (0.0466667150077840625632675); + u = u * t + (-0.0523674852303482457616113); + u = u * t + (0.0587666392926673580854313); + u = u * t + (-0.0666573579361080525984562); + u = u * t + (0.0769219538311769618355029); + u = u * t + (-0.090908995008245008229153); + u = u * t + (0.111111105648261418443745); + u = u * t + (-0.14285714266771329383765); + u = u * t + (0.199999999996591265594148); + u = u * t + (-0.333333333333311110369124); + + t = s + s * (t * u); + + if ((q & 1) != 0) t = 1.570796326794896557998982 - t; + if ((q & 2) != 0) t = -t; + + return t; +} + +__inline double xsin(double d) { + int q; + double u, s; + + q = (int)xrint(d * M_1_PI); + + d = mla(q, -PI4_A*4, d); + d = mla(q, -PI4_B*4, d); + d = mla(q, -PI4_C*4, d); + + s = d * d; + + if ((q & 1) != 0) d = -d; + + u = -7.97255955009037868891952e-18; + u = mla(u, s, 2.81009972710863200091251e-15); + u = mla(u, s, -7.64712219118158833288484e-13); + u = mla(u, s, 1.60590430605664501629054e-10); + u = mla(u, s, -2.50521083763502045810755e-08); + u = mla(u, s, 2.75573192239198747630416e-06); + u = mla(u, s, -0.000198412698412696162806809); + u = mla(u, s, 0.00833333333333332974823815); + u = mla(u, s, -0.166666666666666657414808); + + u = mla(s, u * d, d); + + return u; +} + +__inline double xcos(double d) { + int q; + double u, s; + + q = 1 + 2*(int)xrint(d * M_1_PI - 0.5); + + d = mla(q, -PI4_A*2, d); + d = mla(q, -PI4_B*2, d); + d = mla(q, -PI4_C*2, d); + + s = d * d; + + if ((q & 2) == 0) d = -d; + + u = -7.97255955009037868891952e-18; + u = mla(u, s, 2.81009972710863200091251e-15); + u = mla(u, s, -7.64712219118158833288484e-13); + u = mla(u, s, 1.60590430605664501629054e-10); + u = mla(u, s, -2.50521083763502045810755e-08); + u = mla(u, s, 2.75573192239198747630416e-06); + u = mla(u, s, -0.000198412698412696162806809); + u = mla(u, s, 0.00833333333333332974823815); + u = mla(u, s, -0.166666666666666657414808); + + u = mla(s, u * d, d); + + return u; +} + +__inline double2 xsincos(double d) { + int q; + double u, s, t; + double2 r; + + q = (int)xrint(d * (2 * M_1_PI)); + + s = d; + + s = mla(-q, PI4_A*2, s); + s = mla(-q, PI4_B*2, s); + s = mla(-q, PI4_C*2, s); + + t = s; + + s = s * s; + + u = 1.58938307283228937328511e-10; + u = mla(u, s, -2.50506943502539773349318e-08); + u = mla(u, s, 2.75573131776846360512547e-06); + u = mla(u, s, -0.000198412698278911770864914); + u = mla(u, s, 0.0083333333333191845961746); + u = mla(u, s, -0.166666666666666130709393); + u = u * s * t; + + r.x = t + u; + + u = -1.13615350239097429531523e-11; + u = mla(u, s, 2.08757471207040055479366e-09); + u = mla(u, s, -2.75573144028847567498567e-07); + u = mla(u, s, 2.48015872890001867311915e-05); + u = mla(u, s, -0.00138888888888714019282329); + u = mla(u, s, 0.0416666666666665519592062); + u = mla(u, s, -0.5); + + r.y = u * s + 1; + + if ((q & 1) != 0) { s = r.y; r.y = r.x; r.x = s; } + if ((q & 2) != 0) { r.x = -r.x; } + if (((q+1) & 2) != 0) { r.y = -r.y; } + + if (xisinf(d)) { r.x = r.y = NAN; } + + return r; +} + +__inline double xtan(double d) { + int q; + double u, s, x; + + q = (int)xrint(d * (2 * M_1_PI)); + + x = mla(q, -PI4_A*2, d); + x = mla(q, -PI4_B*2, x); + x = mla(q, -PI4_C*2, x); + + s = x * x; + + if ((q & 1) != 0) x = -x; + + u = 1.01419718511083373224408e-05; + u = mla(u, s, -2.59519791585924697698614e-05); + u = mla(u, s, 5.23388081915899855325186e-05); + u = mla(u, s, -3.05033014433946488225616e-05); + u = mla(u, s, 7.14707504084242744267497e-05); + u = mla(u, s, 8.09674518280159187045078e-05); + u = mla(u, s, 0.000244884931879331847054404); + u = mla(u, s, 0.000588505168743587154904506); + u = mla(u, s, 0.00145612788922812427978848); + u = mla(u, s, 0.00359208743836906619142924); + u = mla(u, s, 0.00886323944362401618113356); + u = mla(u, s, 0.0218694882853846389592078); + u = mla(u, s, 0.0539682539781298417636002); + u = mla(u, s, 0.133333333333125941821962); + u = mla(u, s, 0.333333333333334980164153); + + u = mla(s, u * x, x); + + if ((q & 1) != 0) u = 1.0 / u; + + if (xisinf(d)) u = NAN; + + return u; +} + +__inline double xlog(double d) { + double x, x2, t, m; + int e; + + e = ilogbp1(d * 0.7071); + m = ldexpk(d, -e); + + x = (m-1) / (m+1); + x2 = x * x; + + t = 0.148197055177935105296783; + t = mla(t, x2, 0.153108178020442575739679); + t = mla(t, x2, 0.181837339521549679055568); + t = mla(t, x2, 0.22222194152736701733275); + t = mla(t, x2, 0.285714288030134544449368); + t = mla(t, x2, 0.399999999989941956712869); + t = mla(t, x2, 0.666666666666685503450651); + t = mla(t, x2, 2); + + x = x * t + 0.693147180559945286226764 * e; + + if (xisinf(d)) x = INFINITY; + if (d < 0) x = NAN; + if (d == 0) x = -INFINITY; + + return x; +} + +__inline double xexp(double d) { + int q = (int)xrint(d * R_LN2); + double s, u; + + s = mla(q, -L2U, d); + s = mla(q, -L2L, s); + + u = 2.08860621107283687536341e-09; + u = mla(u, s, 2.51112930892876518610661e-08); + u = mla(u, s, 2.75573911234900471893338e-07); + u = mla(u, s, 2.75572362911928827629423e-06); + u = mla(u, s, 2.4801587159235472998791e-05); + u = mla(u, s, 0.000198412698960509205564975); + u = mla(u, s, 0.00138888888889774492207962); + u = mla(u, s, 0.00833333333331652721664984); + u = mla(u, s, 0.0416666666666665047591422); + u = mla(u, s, 0.166666666666666851703837); + u = mla(u, s, 0.5); + + u = s * s * u + s + 1; + u = ldexpk(u, q); + + if (xisminf(d)) u = 0; + + return u; +} + +__inline double2 logk(double d) { + double2 x, x2; + double m, t; + int e; + + e = ilogbp1(d * 0.7071); + m = ldexpk(d, -e); + + x = div_dd(add2_ss(-1, m), add2_ss(1, m)); + x2 = squ_d(x); + + t = 0.134601987501262130076155; + t = mla(t, x2.x, 0.132248509032032670243288); + t = mla(t, x2.x, 0.153883458318096079652524); + t = mla(t, x2.x, 0.181817427573705403298686); + t = mla(t, x2.x, 0.222222231326187414840781); + t = mla(t, x2.x, 0.285714285651261412873718); + t = mla(t, x2.x, 0.400000000000222439910458); + t = mla(t, x2.x, 0.666666666666666371239645); + + return add2_dd(mul_ds(dd(0.693147180559945286226764, 2.319046813846299558417771e-17), e), + add2_dd(scale_d(x, 2), mul_ds(mul_dd(x2, x), t))); +} + +__inline double expk(double2 d) { + int q = (int)rint((d.x + d.y) * R_LN2); + double2 s, t; + double u; + + s = add2_ds(d, q * -L2U); + s = add2_ds(s, q * -L2L); + + s = normalize_d(s); + + u = 2.51069683420950419527139e-08; + u = mla(u, s.x, 2.76286166770270649116855e-07); + u = mla(u, s.x, 2.75572496725023574143864e-06); + u = mla(u, s.x, 2.48014973989819794114153e-05); + u = mla(u, s.x, 0.000198412698809069797676111); + u = mla(u, s.x, 0.0013888888939977128960529); + u = mla(u, s.x, 0.00833333333332371417601081); + u = mla(u, s.x, 0.0416666666665409524128449); + u = mla(u, s.x, 0.166666666666666740681535); + u = mla(u, s.x, 0.500000000000000999200722); + + t = add_dd(s, mul_ds(squ_d(s), u)); + + t = add_sd(1, t); + return ldexpk(t.x + t.y, q); +} + +__inline double xpow(double x, double y) { + int yisint = (int)y == y; + int yisodd = (1 & (int)y) != 0 && yisint; + + double result = expk(mul_ds(logk(xfabs(x)), y)); + + result = xisnan(result) ? INFINITY : result; + result *= (x >= 0 ? 1 : (!yisint ? NAN : (yisodd ? -1 : 1))); + + double efx = mulsign(xfabs(x) - 1, y); + if (xisinf(y)) result = efx < 0 ? 0.0 : (efx == 0 ? 1.0 : INFINITY); + if (xisinf(x) || x == 0) result = (yisodd ? sign(x) : 1) * ((x == 0 ? -y : y) < 0 ? 0 : INFINITY); + if (xisnan(x) || xisnan(y)) result = NAN; + if (y == 0 || x == 1) result = 1; + + return result; +} + +__inline double2 expk2(double2 d) { + int q = (int)rint((d.x + d.y) * R_LN2); + double2 s, t; + double u; + + s = add2_ds(d, q * -L2U); + s = add2_ds(s, q * -L2L); + + s = normalize_d(s); + + u = 2.51069683420950419527139e-08; + u = mla(u, s.x, 2.76286166770270649116855e-07); + u = mla(u, s.x, 2.75572496725023574143864e-06); + u = mla(u, s.x, 2.48014973989819794114153e-05); + u = mla(u, s.x, 0.000198412698809069797676111); + u = mla(u, s.x, 0.0013888888939977128960529); + u = mla(u, s.x, 0.00833333333332371417601081); + u = mla(u, s.x, 0.0416666666665409524128449); + u = mla(u, s.x, 0.166666666666666740681535); + u = mla(u, s.x, 0.500000000000000999200722); + + t = add_dd(s, mul_ds(squ_d(s), u)); + + t = add_sd(1, t); + return dd(ldexpk(t.x, q), ldexpk(t.y, q)); +} + +__inline double xsinh(double x) { + double y = xfabs(x); + double2 d = expk2(dd(y, 0)); + d = add2_dd(d, div_dd(dd(-1, 0), d)); + y = (d.x + d.y) * 0.5; + + y = xisinf(x) || xisnan(y) ? INFINITY : y; + y = mulsign(y, x); + y = xisnan(x) ? NAN : y; + + return y; +} + +__inline double xcosh(double x) { + double2 d = expk2(dd(x, 0)); + d = add2_dd(d, div_dd(dd(1, 0), d)); + double y = (d.x + d.y) * 0.5; + + y = xisinf(x) || xisnan(y) ? INFINITY : y; + y = xisnan(x) ? NAN : y; + + return y; +} + +__inline double xtanh(double x) { + double y = xfabs(x); + double2 d = expk2(dd(y, 0)); + double2 e = div_dd(dd(1, 0), d); + d = div_dd(add2_dd(d, scale_d(e, -1)), add2_dd(d, e)); + y = d.x + d.y; + + y = xisinf(x) || xisnan(y) ? 1.0 : y; + y = mulsign(y, x); + y = xisnan(x) ? NAN : y; + + return y; +} + +__inline double2 logk2(double2 d) { + double2 x, x2, m; + double t; + int e; + + d = normalize_d(d); + e = ilogbp1(d.x * 0.7071); + m = scale_d(d, ldexpk(1, -e)); + + x = div_dd(add2_ds(m, -1), add2_ds(m, 1)); + x2 = squ_d(x); + + t = 0.134601987501262130076155; + t = mla(t, x2.x, 0.132248509032032670243288); + t = mla(t, x2.x, 0.153883458318096079652524); + t = mla(t, x2.x, 0.181817427573705403298686); + t = mla(t, x2.x, 0.222222231326187414840781); + t = mla(t, x2.x, 0.285714285651261412873718); + t = mla(t, x2.x, 0.400000000000222439910458); + t = mla(t, x2.x, 0.666666666666666371239645); + + return add2_dd(mul_ds(dd(0.693147180559945286226764, 2.319046813846299558417771e-17), e), + add2_dd(scale_d(x, 2), mul_ds(mul_dd(x2, x), t))); +} + +__inline double xasinh(double x) { + double y = xfabs(x); + double2 d = logk2(add2_ds(sqrt_d(add2_ds(mul_ss(y, y), 1)), y)); + y = d.x + d.y; + + y = xisinf(x) || xisnan(y) ? INFINITY : y; + y = mulsign(y, x); + y = xisnan(x) ? NAN : y; + + return y; +} + +__inline double xacosh(double x) { + double2 d = logk2(add2_ds(sqrt_d(add2_ds(mul_ss(x, x), -1)), x)); + double y = d.x + d.y; + + y = xisinf(x) || xisnan(y) ? INFINITY : y; + y = x == 1.0 ? 0.0 : y; + y = x < 1.0 ? NAN : y; + y = xisnan(x) ? NAN : y; + + return y; +} + +__inline double xatanh(double x) { + double y = xfabs(x); + double2 d = logk2(div_dd(add2_ss(1, y), add2_ss(1, -y))); + y = y > 1.0 ? NAN : (y == 1.0 ? INFINITY : (d.x + d.y) * 0.5); + + y = xisinf(x) || xisnan(y) ? NAN : y; + y = mulsign(y, x); + y = xisnan(x) ? NAN : y; + + return y; +} + +// + +__inline double xfma(double x, double y, double z) { + union { + double f; + long long int i; + } tmp; + + tmp.f = x; + tmp.i = (tmp.i + 0x4000000) & 0xfffffffff8000000LL; + double xh = tmp.f, xl = x - xh; + + tmp.f = y; + tmp.i = (tmp.i + 0x4000000) & 0xfffffffff8000000LL; + double yh = tmp.f, yl = y - yh; + + double h = x * y; + double l = xh * yh - h + xl * yh + xh * yl + xl * yl; + + double h2, l2, v; + + h2 = h + z; + v = h2 - h; + l2 = (h - (h2 - v)) + (z - v) + l; + + return h2 + l2; +} + +__inline double xsqrt(double d) { // max error : 0.5 ulp + double q = 1; + + if (d < 8.636168555094445E-78) { + d *= 1.157920892373162E77; + q = 2.9387358770557188E-39; + } + + // http://en.wikipedia.org/wiki/Fast_inverse_square_root + double x = longBitsToDouble(0x5fe6ec85e7de30da - (doubleToRawLongBits(d + 1e-320) >> 1)); + + x = x * (1.5 - 0.5 * d * x * x); + x = x * (1.5 - 0.5 * d * x * x); + x = x * (1.5 - 0.5 * d * x * x); + + // You can change xfma to fma if fma is correctly implemented + x = xfma(d * x, d * x, -d) * (x * -0.5) + d * x; + + return d == INFINITY ? INFINITY : x * q; +} + +__inline double xcbrt(double d) { // max error : 2 ulps + double x, y, q = 1.0; + int e, r; + + e = ilogbp1(d); + d = ldexpk(d, -e); + r = (e + 6144) % 3; + q = (r == 1) ? 1.2599210498948731647672106 : q; + q = (r == 2) ? 1.5874010519681994747517056 : q; + q = ldexpk(q, (e + 6144) / 3 - 2048); + + q = mulsign(q, d); + d = xfabs(d); + + x = -0.640245898480692909870982; + x = x * d + 2.96155103020039511818595; + x = x * d + -5.73353060922947843636166; + x = x * d + 6.03990368989458747961407; + x = x * d + -3.85841935510444988821632; + x = x * d + 2.2307275302496609725722; + + y = x * x; y = y * y; x -= (d * y - x) * (1.0 / 3.0); + y = d * x * x; + y = (y - (2.0 / 3.0) * y * (y * x - 1)) * q; + + return y; +} + +__inline double xexp2(double a) { + double u = expk(mul_ds(dd(0.69314718055994528623, 2.3190468138462995584e-17), a)); + if (xispinf(a)) u = INFINITY; + if (xisminf(a)) u = 0; + return u; +} + +__inline double xexp10(double a) { + double u = expk(mul_ds(dd(2.3025850929940459011, -2.1707562233822493508e-16), a)); + if (xispinf(a)) u = INFINITY; + if (xisminf(a)) u = 0; + return u; +} + +__inline double xexpm1(double a) { + double2 d = add2_ds(expk2(dd(a, 0)), -1.0); + double x = d.x + d.y; + if (xispinf(a)) x = INFINITY; + if (xisminf(a)) x = -1; + return x; +} + +__inline double xlog10(double a) { + double2 d = mul_dd(logk(a), dd(0.43429448190325176116, 6.6494347733425473126e-17)); + double x = d.x + d.y; + + if (xisinf(a)) x = INFINITY; + if (a < 0) x = NAN; + if (a == 0) x = -INFINITY; + + return x; +} + +__inline double xlog1p(double a) { + double2 d = logk2(add2_ss(a, 1)); + double x = d.x + d.y; + + if (xisinf(a)) x = INFINITY; + if (a < -1) x = NAN; + if (a == -1) x = -INFINITY; + + return x; +} + +/////////////////////////////////////////// + +#define PI4_Af 0.78515625f +#define PI4_Bf 0.00024127960205078125f +#define PI4_Cf 6.3329935073852539062e-07f +#define PI4_Df 4.9604681473525147339e-10f + +#define L2Uf 0.693145751953125f +#define L2Lf 1.428606765330187045e-06f + +#define R_LN2f 1.442695040888963407359924681001892137426645954152985934135449406931f +#define M_PIf ((float)M_PI) +#define M_PIf_2 ((float)M_PI_2) + +#define INFINITYf ((float)INFINITY) +#define NANf ((float)NAN) + +__inline int32_t floatToRawIntBits(float d) { + union { + float f; + int32_t i; + } tmp; + tmp.f = d; + return tmp.i; +} + +__inline float intBitsToFloat(int32_t i) { + union { + float f; + int32_t i; + } tmp; + tmp.i = i; + return tmp.f; +} + +__inline float xfabsf(float x) { + return intBitsToFloat(0x7fffffffL & floatToRawIntBits(x)); +} + +__inline float mulsignf(float x, float y) { + return intBitsToFloat(floatToRawIntBits(x) ^ (floatToRawIntBits(y) & (1 << 31))); +} + +__inline float signf(float d) { return mulsignf(1, d); } +__inline float mlaf(float x, float y, float z) { return x * y + z; } +__inline float xrintf(float x) { return x < 0 ? (int)(x - 0.5f) : (int)(x + 0.5f); } + +__inline int xisnanf(float x) { return x != x; } +__inline int xisinff(float x) { return x == INFINITYf || x == -INFINITYf; } +__inline int xisminff(float x) { return x == -INFINITYf; } +__inline int xispinff(float x) { return x == INFINITYf; } + +__inline int ilogbp1f(float d) { + int m = d < 5.421010862427522E-20f; + d = m ? 1.8446744073709552E19f * d : d; + int q = (floatToRawIntBits(d) >> 23) & 0xff; + q = m ? q - (64 + 0x7e) : q - 0x7e; + return q; +} + +__inline float ldexpkf(float x, int q) { + float u; + int m; + m = q >> 31; + m = (((m + q) >> 6) - m) << 4; + q = q - (m << 2); + u = intBitsToFloat(((int32_t)(m + 0x7f)) << 23); + u = u * u; + x = x * u * u; + u = intBitsToFloat(((int32_t)(q + 0x7f)) << 23); + return x * u; +} + +__inline float xcbrtf(float d) { // max error : 2 ulps + float x, y, q = 1.0f; + int e, r; + + e = ilogbp1f(d); + d = ldexpkf(d, -e); + r = (e + 6144) % 3; + q = (r == 1) ? 1.2599210498948731647672106f : q; + q = (r == 2) ? 1.5874010519681994747517056f : q; + q = ldexpkf(q, (e + 6144) / 3 - 2048); + + q = mulsignf(q, d); + d = xfabsf(d); + + x = -0.601564466953277587890625f; + x = mlaf(x, d, 2.8208892345428466796875f); + x = mlaf(x, d, -5.532182216644287109375f); + x = mlaf(x, d, 5.898262500762939453125f); + x = mlaf(x, d, -3.8095417022705078125f); + x = mlaf(x, d, 2.2241256237030029296875f); + + y = d * x * x; + y = (y - (2.0f / 3.0f) * y * (y * x - 1.0f)) * q; + + return y; +} + +__inline float xsinf(float d) { + int q; + float u, s; + + q = (int)xrintf(d * (float)M_1_PI); + + d = mlaf(q, -PI4_Af*4, d); + d = mlaf(q, -PI4_Bf*4, d); + d = mlaf(q, -PI4_Cf*4, d); + d = mlaf(q, -PI4_Df*4, d); + + s = d * d; + + if ((q & 1) != 0) d = -d; + + u = 2.6083159809786593541503e-06f; + u = mlaf(u, s, -0.0001981069071916863322258f); + u = mlaf(u, s, 0.00833307858556509017944336f); + u = mlaf(u, s, -0.166666597127914428710938f); + + u = mlaf(s, u * d, d); + + return u; +} + +__inline float xcosf(float d) { + int q; + float u, s; + + q = 1 + 2*(int)xrintf(d * (float)M_1_PI - 0.5f); + + d = mlaf(q, -PI4_Af*2, d); + d = mlaf(q, -PI4_Bf*2, d); + d = mlaf(q, -PI4_Cf*2, d); + d = mlaf(q, -PI4_Df*2, d); + + s = d * d; + + if ((q & 2) == 0) d = -d; + + u = 2.6083159809786593541503e-06f; + u = mlaf(u, s, -0.0001981069071916863322258f); + u = mlaf(u, s, 0.00833307858556509017944336f); + u = mlaf(u, s, -0.166666597127914428710938f); + + u = mlaf(s, u * d, d); + + return u; +} + +__inline float2 xsincosf(float d) { + int q; + float u, s, t; + float2 r; + + q = (int)rint(d * ((float)(2 * M_1_PI))); + + s = d; + + s = mlaf(q, -PI4_Af*2, s); + s = mlaf(q, -PI4_Bf*2, s); + s = mlaf(q, -PI4_Cf*2, s); + s = mlaf(q, -PI4_Df*2, s); + + t = s; + + s = s * s; + + u = -0.000195169282960705459117889f; + u = mlaf(u, s, 0.00833215750753879547119141f); + u = mlaf(u, s, -0.166666537523269653320312f); + u = u * s * t; + + r.x = t + u; + + u = -2.71811842367242206819355e-07f; + u = mlaf(u, s, 2.47990446951007470488548e-05f); + u = mlaf(u, s, -0.00138888787478208541870117f); + u = mlaf(u, s, 0.0416666641831398010253906f); + u = mlaf(u, s, -0.5f); + + r.y = u * s + 1; + + if ((q & 1) != 0) { s = r.y; r.y = r.x; r.x = s; } + if ((q & 2) != 0) { r.x = -r.x; } + if (((q+1) & 2) != 0) { r.y = -r.y; } + + if (xisinff(d)) { r.x = r.y = NANf; } + + return r; +} + +__inline float xtanf(float d) { + int q; + float u, s, x; + + q = (int)xrintf(d * (float)(2 * M_1_PI)); + + x = d; + + x = mlaf(q, -PI4_Af*2, x); + x = mlaf(q, -PI4_Bf*2, x); + x = mlaf(q, -PI4_Cf*2, x); + x = mlaf(q, -PI4_Df*2, x); + + s = x * x; + + if ((q & 1) != 0) x = -x; + + u = 0.00927245803177356719970703f; + u = mlaf(u, s, 0.00331984995864331722259521f); + u = mlaf(u, s, 0.0242998078465461730957031f); + u = mlaf(u, s, 0.0534495301544666290283203f); + u = mlaf(u, s, 0.133383005857467651367188f); + u = mlaf(u, s, 0.333331853151321411132812f); + + u = mlaf(s, u * x, x); + + if ((q & 1) != 0) u = 1.0f / u; + + if (xisinff(d)) u = NANf; + + return u; +} + +__inline float xatanf(float s) { + float t, u; + int q = 0; + + if (s < 0) { s = -s; q = 2; } + if (s > 1) { s = 1.0f / s; q |= 1; } + + t = s * s; + + u = 0.00282363896258175373077393f; + u = mlaf(u, t, -0.0159569028764963150024414f); + u = mlaf(u, t, 0.0425049886107444763183594f); + u = mlaf(u, t, -0.0748900920152664184570312f); + u = mlaf(u, t, 0.106347933411598205566406f); + u = mlaf(u, t, -0.142027363181114196777344f); + u = mlaf(u, t, 0.199926957488059997558594f); + u = mlaf(u, t, -0.333331018686294555664062f); + + t = s + s * (t * u); + + if ((q & 1) != 0) t = 1.570796326794896557998982f - t; + if ((q & 2) != 0) t = -t; + + return t; +} + +__inline float atan2kf(float y, float x) { + float s, t, u; + float q = 0.f; + + if (x < 0) { x = -x; q = -2.f; } + if (y > x) { t = x; x = y; y = -t; q += 1.f; } + + s = y / x; + t = s * s; + + u = 0.00282363896258175373077393f; + u = mlaf(u, t, -0.0159569028764963150024414f); + u = mlaf(u, t, 0.0425049886107444763183594f); + u = mlaf(u, t, -0.0748900920152664184570312f); + u = mlaf(u, t, 0.106347933411598205566406f); + u = mlaf(u, t, -0.142027363181114196777344f); + u = mlaf(u, t, 0.199926957488059997558594f); + u = mlaf(u, t, -0.333331018686294555664062f); + + t = u * t; + t = mlaf(t,s,s); + return mlaf(q,(float)(M_PIf_2),t); +} + +__inline float xatan2f(float y, float x) { + float r = atan2kf(xfabsf(y), x); + + r = mulsignf(r, x); + if (xisinff(x) || x == 0) r = M_PIf/2 - (xisinff(x) ? (signf(x) * (float)(M_PIf*.5f)) : 0); + if (xisinff(y) ) r = M_PIf/2 - (xisinff(x) ? (signf(x) * (float)(M_PIf*.25f)) : 0); + if ( y == 0) r = (signf(x) == -1 ? M_PIf : 0); + + return xisnanf(x) || xisnanf(y) ? NANf : mulsignf(r, y); +} + +__inline float xasinf(float d) { + return mulsignf(atan2kf(fabsf(d), sqrtf((1.0f+d)*(1.0f-d))), d); +} + +__inline float xacosf(float d) { + return mulsignf(atan2kf(sqrtf((1.0f+d)*(1.0f-d)), fabsf(d)), d) + (d < 0 ? (float)M_PI : 0.0f); +} + +__inline float xlogf(float d) { + float x, x2, t, m; + int e; + + e = ilogbp1f(d * 0.7071f); + m = ldexpkf(d, -e); + + x = (m-1.0f) / (m+1.0f); + x2 = x * x; + + t = 0.2371599674224853515625f; + t = mlaf(t, x2, 0.285279005765914916992188f); + t = mlaf(t, x2, 0.400005519390106201171875f); + t = mlaf(t, x2, 0.666666567325592041015625f); + t = mlaf(t, x2, 2.0f); + + x = x * t + 0.693147180559945286226764f * e; + + if (xisinff(d)) x = INFINITYf; + if (d < 0) x = NANf; + if (d == 0) x = -INFINITYf; + + return x; +} + +__inline float xexpf(float d) { + if(d<=-104.0f) return 0.0f; + + int q = (int)xrintf(d * R_LN2f); + float s, u; + + s = mlaf(q, -L2Uf, d); + s = mlaf(q, -L2Lf, s); + + u = 0.00136324646882712841033936f; + u = mlaf(u, s, 0.00836596917361021041870117f); + u = mlaf(u, s, 0.0416710823774337768554688f); + u = mlaf(u, s, 0.166665524244308471679688f); + u = mlaf(u, s, 0.499999850988388061523438f); + + u = mlaf( s, mlaf(s,u,1.f),1.f); + return ldexpkf(u, q); + +} + +__inline float xmul2f(float d) { + union { + float floatval; + int intval; + } uflint; + uflint.floatval = d; + if (uflint.intval & 0x7FFFFFFF) { // if f==0 do nothing + uflint.intval += 1 << 23; // add 1 to the exponent + } + return uflint.floatval; +} + +__inline float xdiv2f(float d) { + union { + float floatval; + int intval; + } uflint; + uflint.floatval = d; + if (uflint.intval & 0x7FFFFFFF) { // if f==0 do nothing + uflint.intval -= 1 << 23; // sub 1 from the exponent + } + return uflint.floatval; +} + +__inline float xdivf( float d, int n){ + union { + float floatval; + int intval; + } uflint; + uflint.floatval = d; + if (uflint.intval & 0x7FFFFFFF) { // if f==0 do nothing + uflint.intval -= n << 23; // add n to the exponent + } + return uflint.floatval; +} + + + +#endif diff --git a/rtengine/sleef.h b/rtengine/sleef.h new file mode 100644 index 000000000..ab42eda40 --- /dev/null +++ b/rtengine/sleef.h @@ -0,0 +1,51 @@ +typedef struct { + double x, y; +} double2; + +typedef struct { + float x, y; +} float2; + +double xsin(double d); +double xcos(double d); +double2 xsincos(double d); +double xtan(double d); +double xasin(double s); +double xacos(double s); +double xatan(double s); +double xatan2(double y, double x); +double xlog(double d); +double xexp(double d); +double xpow(double x, double y); + +double xsinh(double x); +double xcosh(double x); +double xtanh(double x); +double xasinh(double x); +double xacosh(double x); +double xatanh(double x); +double xldexp(double x, int q); +int xilogb(double d); + +double xfma(double x, double y, double z); +double xsqrt(double d); +double xcbrt(double d); + +double xexp2(double a); +double xexp10(double a); +double xexpm1(double a); +double xlog10(double a); +double xlog1p(double a); + +float xsinf(float d); +float xcosf(float d); +float2 xsincosf(float d); +float xtanf(float d); +float xasinf(float s); +float xacosf(float s); +float xatanf(float s); +float xatan2f(float y, float x); +float xlogf(float d); +float xexpf(float d); +float xpowf(float x, float y); +float xcbrtf(float d); diff --git a/rtengine/sleefsseavx.c b/rtengine/sleefsseavx.c new file mode 100644 index 000000000..543cf5abc --- /dev/null +++ b/rtengine/sleefsseavx.c @@ -0,0 +1,1326 @@ +#ifndef SLEEFSSEAVX +#define SLEEFSSEAVX + +#include +#include +//#include +//#include +//#include "sleefsseavx.h" +#ifdef __SSE2__ +#include "helpersse2.h" + +#ifdef ENABLE_AVX +#include "helperavx.h" +#endif + +#ifdef __GNUC__ +#define INLINE __inline +#else +#define INLINE inline +#endif + +// + +#define PI4_A .7853981554508209228515625 +#define PI4_B .794662735614792836713604629039764404296875e-8 +#define PI4_C .306161699786838294306516483068750264552437361480769e-16 +#define M_4_PI 1.273239544735162542821171882678754627704620361328125 + +#define L2U .69314718055966295651160180568695068359375 +#define L2L .28235290563031577122588448175013436025525412068e-12 +#define R_LN2 1.442695040888963407359924681001892137426645954152985934135449406931 + +// + +#define PI4_Af 0.78515625f +#define PI4_Bf 0.00024127960205078125f +#define PI4_Cf 6.3329935073852539062e-07f +#define PI4_Df 4.9604681473525147339e-10f + +#define L2Uf 0.693145751953125f +#define L2Lf 1.428606765330187045e-06f +#define R_LN2f 1.442695040888963407359924681001892137426645954152985934135449406931f + +#define INFINITYf ((float)INFINITY) +#define NANf ((float)NAN) + +// + +static INLINE vdouble vadd3(vdouble v0, vdouble v1, vdouble v2) { + return vadd(vadd(v0, v1), v2); +} + +static INLINE vdouble vadd4(vdouble v0, vdouble v1, vdouble v2, vdouble v3) { + return vadd3(vadd(v0, v1), v2, v3); +} + +static INLINE vdouble vadd5(vdouble v0, vdouble v1, vdouble v2, vdouble v3, vdouble v4) { + return vadd4(vadd(v0, v1), v2, v3, v4); +} + +static INLINE vdouble vadd6(vdouble v0, vdouble v1, vdouble v2, vdouble v3, vdouble v4, vdouble v5) { + return vadd5(vadd(v0, v1), v2, v3, v4, v5); +} + +static INLINE vdouble vadd7(vdouble v0, vdouble v1, vdouble v2, vdouble v3, vdouble v4, vdouble v5, vdouble v6) { + return vadd6(vadd(v0, v1), v2, v3, v4, v5, v6); +} + +static INLINE vdouble vsub3(vdouble v0, vdouble v1, vdouble v2) { + return vsub(vsub(v0, v1), v2); +} + +static INLINE vdouble vsub4(vdouble v0, vdouble v1, vdouble v2, vdouble v3) { + return vsub3(vsub(v0, v1), v2, v3); +} + +static INLINE vdouble vsub5(vdouble v0, vdouble v1, vdouble v2, vdouble v3, vdouble v4) { + return vsub4(vsub(v0, v1), v2, v3, v4); +} + +// + +static INLINE vdouble2 normalize_d(vdouble2 t) { + vdouble2 s; + + s.x = vadd(t.x, t.y); + s.y = vadd(vsub(t.x, s.x), t.y); + + return s; +} + +static INLINE vdouble2 scale_d(vdouble2 d, vdouble s) { + vdouble2 r = {vmul(d.x, s), vmul(d.y, s)}; + return r; +} + +static INLINE vdouble2 add_ss(vdouble x, vdouble y) { + vdouble2 r; + + r.x = vadd(x, y); + r.y = vadd(vsub(x, r.x), y); + + return r; +} + +static INLINE vdouble2 add2_ss(vdouble x, vdouble y) { + vdouble2 r; + + r.x = vadd(x, y); + vdouble v = vsub(r.x, x); + r.y = vadd(vsub(x, vsub(r.x, v)), vsub(y, v)); + + return r; +} + +static INLINE vdouble2 add_ds(vdouble2 x, vdouble y) { + vdouble2 r; + + r.x = vadd(x.x, y); + r.y = vadd3(vsub(x.x, r.x), y, x.y); + + return r; +} + +static INLINE vdouble2 add2_ds(vdouble2 x, vdouble y) { + vdouble2 r; + + r.x = vadd(x.x, y); + vdouble v = vsub(r.x, x.x); + r.y = vadd(vsub(x.x, vsub(r.x, v)), vsub(y, v)); + r.y = vadd(r.y, x.y); + + return r; +} + +static INLINE vdouble2 add_sd(vdouble x, vdouble2 y) { + vdouble2 r; + + r.x = vadd(x, y.x); + r.y = vadd3(vsub(x, r.x), y.x, y.y); + + return r; +} + +static INLINE vdouble2 add_dd(vdouble2 x, vdouble2 y) { + // |x| >= |y| + + vdouble2 r; + + r.x = vadd(x.x, y.x); + r.y = vadd4(vsub(x.x, r.x), y.x, x.y, y.y); + + return r; +} + +static INLINE vdouble2 add2_dd(vdouble2 x, vdouble2 y) { + vdouble2 r; + + r.x = vadd(x.x, y.x); + vdouble v = vsub(r.x, x.x); + r.y = vadd(vsub(x.x, vsub(r.x, v)), vsub(y.x, v)); + r.y = vadd(r.y, vadd(x.y, y.y)); + + return r; +} + +static INLINE vdouble2 div_dd(vdouble2 n, vdouble2 d) { + vdouble t = vrec(d.x); + vdouble dh = vupper(d.x), dl = vsub(d.x, dh); + vdouble th = vupper(t ), tl = vsub(t , th); + vdouble nhh = vupper(n.x), nhl = vsub(n.x, nhh); + + vdouble2 q; + + q.x = vmul(n.x, t); + + vdouble u = vadd5(vsub(vmul(nhh, th), q.x), vmul(nhh, tl), vmul(nhl, th), vmul(nhl, tl), + vmul(q.x, vsub5(vcast_vd_d(1), vmul(dh, th), vmul(dh, tl), vmul(dl, th), vmul(dl, tl)))); + + q.y = vadd(vmul(t, vsub(n.y, vmul(q.x, d.y))), u); + + return q; +} + +static INLINE vdouble2 mul_ss(vdouble x, vdouble y) { + vdouble xh = vupper(x), xl = vsub(x, xh); + vdouble yh = vupper(y), yl = vsub(y, yh); + vdouble2 r; + + r.x = vmul(x, y); + r.y = vadd5(vmul(xh, yh), vneg(r.x), vmul(xl, yh), vmul(xh, yl), vmul(xl, yl)); + + return r; +} + +static INLINE vdouble2 mul_ds(vdouble2 x, vdouble y) { + vdouble xh = vupper(x.x), xl = vsub(x.x, xh); + vdouble yh = vupper(y ), yl = vsub(y , yh); + vdouble2 r; + + r.x = vmul(x.x, y); + r.y = vadd6(vmul(xh, yh), vneg(r.x), vmul(xl, yh), vmul(xh, yl), vmul(xl, yl), vmul(x.y, y)); + + return r; +} + +static INLINE vdouble2 mul_dd(vdouble2 x, vdouble2 y) { + vdouble xh = vupper(x.x), xl = vsub(x.x, xh); + vdouble yh = vupper(y.x), yl = vsub(y.x, yh); + vdouble2 r; + + r.x = vmul(x.x, y.x); + r.y = vadd7(vmul(xh, yh), vneg(r.x), vmul(xl, yh), vmul(xh, yl), vmul(xl, yl), vmul(x.x, y.y), vmul(x.y, y.x)); + + return r; +} + +static INLINE vdouble2 squ_d(vdouble2 x) { + vdouble xh = vupper(x.x), xl = vsub(x.x, xh); + vdouble2 r; + + r.x = vmul(x.x, x.x); + r.y = vadd5(vmul(xh, xh), vneg(r.x), vmul(vadd(xh, xh), xl), vmul(xl, xl), vmul(x.x, vadd(x.y, x.y))); + + return r; +} + +static INLINE vdouble2 rec_s(vdouble d) { + vdouble t = vrec(d); + vdouble dh = vupper(d), dl = vsub(d, dh); + vdouble th = vupper(t), tl = vsub(t, th); + vdouble2 q; + + q.x = t; + q.y = vmul(t, vsub5(vcast_vd_d(1), vmul(dh, th), vmul(dh, tl), vmul(dl, th), vmul(dl, tl))); + + return q; +} + +static INLINE vdouble2 sqrt_d(vdouble2 d) { + vdouble t = vsqrt(vadd(d.x, d.y)); + return scale_d(mul_dd(add2_dd(d, mul_ss(t, t)), rec_s(t)), vcast_vd_d(0.5)); +} + +// + +static INLINE vdouble xldexp(vdouble x, vint q) { return vldexp(x, q); } + +static INLINE vint xilogb(vdouble d) { + vdouble e = vcast_vd_vi(vsubi(vilogbp1(vabs(d)), vcast_vi_i(1))); + e = vsel(vmask_eq(d, vcast_vd_d(0)), vcast_vd_d(-2147483648.0), e); + e = vsel(vmask_eq(vabs(d), vcast_vd_d(INFINITY)), vcast_vd_d(2147483647), e); + return vrint_vi_vd(e); +} + +static INLINE vdouble xsin(vdouble d) { + vint q; + vdouble u, s; + + q = vrint_vi_vd(vmul(d, vcast_vd_d(M_1_PI))); + + u = vcast_vd_vi(q); + d = vadd(d, vmul(u, vcast_vd_d(-PI4_A*4))); + d = vadd(d, vmul(u, vcast_vd_d(-PI4_B*4))); + d = vadd(d, vmul(u, vcast_vd_d(-PI4_C*4))); + + s = vmul(d, d); + + d = vsel(vmaski_eq(vandi(q, vcast_vi_i(1)), vcast_vi_i(1)), vneg(d), d); + + u = vcast_vd_d(-7.97255955009037868891952e-18); + u = vmla(u, s, vcast_vd_d(2.81009972710863200091251e-15)); + u = vmla(u, s, vcast_vd_d(-7.64712219118158833288484e-13)); + u = vmla(u, s, vcast_vd_d(1.60590430605664501629054e-10)); + u = vmla(u, s, vcast_vd_d(-2.50521083763502045810755e-08)); + u = vmla(u, s, vcast_vd_d(2.75573192239198747630416e-06)); + u = vmla(u, s, vcast_vd_d(-0.000198412698412696162806809)); + u = vmla(u, s, vcast_vd_d(0.00833333333333332974823815)); + u = vmla(u, s, vcast_vd_d(-0.166666666666666657414808)); + + u = vmla(s, vmul(u, d), d); + + return u; +} + +static INLINE vdouble xcos(vdouble d) { + vint q; + vdouble u, s; + + q = vrint_vi_vd(vsub(vmul(d, vcast_vd_d(M_1_PI)), vcast_vd_d(0.5))); + q = vaddi(vaddi(q, q), vcast_vi_i(1)); + + u = vcast_vd_vi(q); + d = vadd(d, vmul(u, vcast_vd_d(-PI4_A*2))); + d = vadd(d, vmul(u, vcast_vd_d(-PI4_B*2))); + d = vadd(d, vmul(u, vcast_vd_d(-PI4_C*2))); + + s = vmul(d, d); + + d = vsel(vmaski_eq(vandi(q, vcast_vi_i(2)), vcast_vi_i(0)), vneg(d), d); + + u = vcast_vd_d(-7.97255955009037868891952e-18); + u = vmla(u, s, vcast_vd_d(2.81009972710863200091251e-15)); + u = vmla(u, s, vcast_vd_d(-7.64712219118158833288484e-13)); + u = vmla(u, s, vcast_vd_d(1.60590430605664501629054e-10)); + u = vmla(u, s, vcast_vd_d(-2.50521083763502045810755e-08)); + u = vmla(u, s, vcast_vd_d(2.75573192239198747630416e-06)); + u = vmla(u, s, vcast_vd_d(-0.000198412698412696162806809)); + u = vmla(u, s, vcast_vd_d(0.00833333333333332974823815)); + u = vmla(u, s, vcast_vd_d(-0.166666666666666657414808)); + + u = vmla(s, vmul(u, d), d); + + return u; +} + +static INLINE vdouble2 xsincos(vdouble d) { + vint q; + vmask m; + vdouble u, s, t, rx, ry; + vdouble2 r; + + q = vrint_vi_vd(vmul(d, vcast_vd_d(M_2_PI))); + + s = d; + + u = vcast_vd_vi(q); + s = vmla(u, vcast_vd_d(-PI4_A*2), s); + s = vmla(u, vcast_vd_d(-PI4_B*2), s); + s = vmla(u, vcast_vd_d(-PI4_C*2), s); + + t = s; + + s = vmul(s, s); + + u = vcast_vd_d(1.58938307283228937328511e-10); + u = vmla(u, s, vcast_vd_d(-2.50506943502539773349318e-08)); + u = vmla(u, s, vcast_vd_d(2.75573131776846360512547e-06)); + u = vmla(u, s, vcast_vd_d(-0.000198412698278911770864914)); + u = vmla(u, s, vcast_vd_d(0.0083333333333191845961746)); + u = vmla(u, s, vcast_vd_d(-0.166666666666666130709393)); + u = vmul(vmul(u, s), t); + + rx = vadd(t, u); + + u = vcast_vd_d(-1.13615350239097429531523e-11); + u = vmla(u, s, vcast_vd_d(2.08757471207040055479366e-09)); + u = vmla(u, s, vcast_vd_d(-2.75573144028847567498567e-07)); + u = vmla(u, s, vcast_vd_d(2.48015872890001867311915e-05)); + u = vmla(u, s, vcast_vd_d(-0.00138888888888714019282329)); + u = vmla(u, s, vcast_vd_d(0.0416666666666665519592062)); + u = vmla(u, s, vcast_vd_d(-0.5)); + + ry = vadd(vcast_vd_d(1), vmul(s, u)); + + m = vmaski_eq(vandi(q, vcast_vi_i(1)), vcast_vi_i(0)); + r.x = vsel(m, rx, ry); + r.y = vsel(m, ry, rx); + + m = vmaski_eq(vandi(q, vcast_vi_i(2)), vcast_vi_i(2)); + r.x = vreinterpret_vd_vm(vxorm(vandm(m, vreinterpret_vm_vd(vcast_vd_d(-0.0))), vreinterpret_vm_vd(r.x))); + + m = vmaski_eq(vandi(vaddi(q, vcast_vi_i(1)), vcast_vi_i(2)), vcast_vi_i(2)); + r.y = vreinterpret_vd_vm(vxorm(vandm(m, vreinterpret_vm_vd(vcast_vd_d(-0.0))), vreinterpret_vm_vd(r.y))); + + m = vmask_isinf(d); + r.x = vsel(m, vcast_vd_d(NAN), r.x); + r.y = vsel(m, vcast_vd_d(NAN), r.y); + + return r; +} + +static INLINE vdouble xtan(vdouble d) { + vint q; + vdouble u, s, x; + vmask m; + + q = vrint_vi_vd(vmul(d, vcast_vd_d(M_2_PI))); + + u = vcast_vd_vi(q); + x = vadd(d, vmul(u, vcast_vd_d(-PI4_A*2))); + x = vadd(x, vmul(u, vcast_vd_d(-PI4_B*2))); + x = vadd(x, vmul(u, vcast_vd_d(-PI4_C*2))); + + s = vmul(x, x); + + m = vmaski_eq(vandi(q, vcast_vi_i(1)), vcast_vi_i(1)); + x = vsel(m, vneg(x), x); + + u = vcast_vd_d(1.01419718511083373224408e-05); + u = vmla(u, s, vcast_vd_d(-2.59519791585924697698614e-05)); + u = vmla(u, s, vcast_vd_d(5.23388081915899855325186e-05)); + u = vmla(u, s, vcast_vd_d(-3.05033014433946488225616e-05)); + u = vmla(u, s, vcast_vd_d(7.14707504084242744267497e-05)); + u = vmla(u, s, vcast_vd_d(8.09674518280159187045078e-05)); + u = vmla(u, s, vcast_vd_d(0.000244884931879331847054404)); + u = vmla(u, s, vcast_vd_d(0.000588505168743587154904506)); + u = vmla(u, s, vcast_vd_d(0.00145612788922812427978848)); + u = vmla(u, s, vcast_vd_d(0.00359208743836906619142924)); + u = vmla(u, s, vcast_vd_d(0.00886323944362401618113356)); + u = vmla(u, s, vcast_vd_d(0.0218694882853846389592078)); + u = vmla(u, s, vcast_vd_d(0.0539682539781298417636002)); + u = vmla(u, s, vcast_vd_d(0.133333333333125941821962)); + u = vmla(u, s, vcast_vd_d(0.333333333333334980164153)); + + u = vmla(s, vmul(u, x), x); + + u = vsel(m, vrec(u), u); + + u = vsel(vmask_isinf(d), vcast_vd_d(NAN), u); + + return u; +} + +static INLINE vdouble atan2k(vdouble y, vdouble x) { + vdouble s, t, u; + vint q; + vmask p; + + q = vseli_lt(x, vcast_vd_d(0), vcast_vi_i(-2), vcast_vi_i(0)); + x = vabs(x); + + q = vseli_lt(x, y, vaddi(q, vcast_vi_i(1)), q); + p = vmask_lt(x, y); + s = vsel (p, vneg(x), y); + t = vmax (x, y); + + s = vdiv(s, t); + t = vmul(s, s); + + u = vcast_vd_d(-1.88796008463073496563746e-05); + u = vmla(u, t, vcast_vd_d(0.000209850076645816976906797)); + u = vmla(u, t, vcast_vd_d(-0.00110611831486672482563471)); + u = vmla(u, t, vcast_vd_d(0.00370026744188713119232403)); + u = vmla(u, t, vcast_vd_d(-0.00889896195887655491740809)); + u = vmla(u, t, vcast_vd_d(0.016599329773529201970117)); + u = vmla(u, t, vcast_vd_d(-0.0254517624932312641616861)); + u = vmla(u, t, vcast_vd_d(0.0337852580001353069993897)); + u = vmla(u, t, vcast_vd_d(-0.0407629191276836500001934)); + u = vmla(u, t, vcast_vd_d(0.0466667150077840625632675)); + u = vmla(u, t, vcast_vd_d(-0.0523674852303482457616113)); + u = vmla(u, t, vcast_vd_d(0.0587666392926673580854313)); + u = vmla(u, t, vcast_vd_d(-0.0666573579361080525984562)); + u = vmla(u, t, vcast_vd_d(0.0769219538311769618355029)); + u = vmla(u, t, vcast_vd_d(-0.090908995008245008229153)); + u = vmla(u, t, vcast_vd_d(0.111111105648261418443745)); + u = vmla(u, t, vcast_vd_d(-0.14285714266771329383765)); + u = vmla(u, t, vcast_vd_d(0.199999999996591265594148)); + u = vmla(u, t, vcast_vd_d(-0.333333333333311110369124)); + + t = vadd(s, vmul(s, vmul(t, u))); + t = vadd(t, vmul(vcast_vd_vi(q), vcast_vd_d(M_PI/2))); + + return t; +} + +static INLINE vdouble xatan2(vdouble y, vdouble x) { + vdouble r = atan2k(vabs(y), x); + + r = vmulsign(r, x); + r = vsel(vorm(vmask_isinf(x), vmask_eq(x, vcast_vd_d(0))), vsub(vcast_vd_d(M_PI/2), visinf2(x, vmulsign(vcast_vd_d(M_PI/2), x))), r); + r = vsel(vmask_isinf(y), vsub(vcast_vd_d(M_PI/2), visinf2(x, vmulsign(vcast_vd_d(M_PI/4), x))), r); + r = vsel(vmask_eq(y, vcast_vd_d(0)), vsel(vmask_eq(vsign(x), vcast_vd_d(-1.0)), vcast_vd_d(M_PI), vcast_vd_d(0)), r); + + return vsel(vorm(vmask_isnan(x), vmask_isnan(y)), vcast_vd_d(NAN), vmulsign(r, y)); +} + +static INLINE vdouble xasin(vdouble d) { + vdouble x, y; + x = vadd(vcast_vd_d(1), d); + y = vsub(vcast_vd_d(1), d); + x = vmul(x, y); + x = vsqrt(x); + x = vsel(vmask_isnan(x), vcast_vd_d(NAN), atan2k(vabs(d), x)); + return vmulsign(x, d); +} + +static INLINE vdouble xacos(vdouble d) { + vdouble x, y; + x = vadd(vcast_vd_d(1), d); + y = vsub(vcast_vd_d(1), d); + x = vmul(x, y); + x = vsqrt(x); + x = vmulsign(atan2k(x, vabs(d)), d); + y = (vdouble)vandm(vmask_lt(d, vcast_vd_d(0)), (vmask)vcast_vd_d(M_PI)); + x = vadd(x, y); + return x; +} + +static INLINE vdouble xatan(vdouble s) { + vdouble t, u; + vint q; + + q = vseli_lt(s, vcast_vd_d(0), vcast_vi_i(2), vcast_vi_i(0)); + s = vabs(s); + + q = vseli_lt(vcast_vd_d(1), s, vaddi(q, vcast_vi_i(1)), q); + s = vsel(vmask_lt(vcast_vd_d(1), s), vdiv(vcast_vd_d(1), s), s); + + t = vmul(s, s); + + u = vcast_vd_d(-1.88796008463073496563746e-05); + u = vmla(u, t, vcast_vd_d(0.000209850076645816976906797)); + u = vmla(u, t, vcast_vd_d(-0.00110611831486672482563471)); + u = vmla(u, t, vcast_vd_d(0.00370026744188713119232403)); + u = vmla(u, t, vcast_vd_d(-0.00889896195887655491740809)); + u = vmla(u, t, vcast_vd_d(0.016599329773529201970117)); + u = vmla(u, t, vcast_vd_d(-0.0254517624932312641616861)); + u = vmla(u, t, vcast_vd_d(0.0337852580001353069993897)); + u = vmla(u, t, vcast_vd_d(-0.0407629191276836500001934)); + u = vmla(u, t, vcast_vd_d(0.0466667150077840625632675)); + u = vmla(u, t, vcast_vd_d(-0.0523674852303482457616113)); + u = vmla(u, t, vcast_vd_d(0.0587666392926673580854313)); + u = vmla(u, t, vcast_vd_d(-0.0666573579361080525984562)); + u = vmla(u, t, vcast_vd_d(0.0769219538311769618355029)); + u = vmla(u, t, vcast_vd_d(-0.090908995008245008229153)); + u = vmla(u, t, vcast_vd_d(0.111111105648261418443745)); + u = vmla(u, t, vcast_vd_d(-0.14285714266771329383765)); + u = vmla(u, t, vcast_vd_d(0.199999999996591265594148)); + u = vmla(u, t, vcast_vd_d(-0.333333333333311110369124)); + + t = vadd(s, vmul(s, vmul(t, u))); + + t = vsel(vmaski_eq(vandi(q, vcast_vi_i(1)), vcast_vi_i(1)), vsub(vcast_vd_d(M_PI/2), t), t); + t = vsel(vmaski_eq(vandi(q, vcast_vi_i(2)), vcast_vi_i(2)), vneg(t), t); + + return t; +} + +static INLINE vdouble xlog(vdouble d) { + vdouble x, x2; + vdouble t, m; + vint e; + + e = vilogbp1(vmul(d, vcast_vd_d(0.7071))); + m = vldexp(d, vsubi(vcast_vi_i(0), e)); + + x = vdiv(vadd(vcast_vd_d(-1), m), vadd(vcast_vd_d(1), m)); + x2 = vmul(x, x); + + t = vcast_vd_d(0.148197055177935105296783); + t = vmla(t, x2, vcast_vd_d(0.153108178020442575739679)); + t = vmla(t, x2, vcast_vd_d(0.181837339521549679055568)); + t = vmla(t, x2, vcast_vd_d(0.22222194152736701733275)); + t = vmla(t, x2, vcast_vd_d(0.285714288030134544449368)); + t = vmla(t, x2, vcast_vd_d(0.399999999989941956712869)); + t = vmla(t, x2, vcast_vd_d(0.666666666666685503450651)); + t = vmla(t, x2, vcast_vd_d(2)); + + x = vadd(vmul(x, t), vmul(vcast_vd_d(0.693147180559945286226764), vcast_vd_vi(e))); + + x = vsel(vmask_ispinf(d), vcast_vd_d(INFINITY), x); + x = vsel(vmask_gt(vcast_vd_d(0), d), vcast_vd_d(NAN), x); + x = vsel(vmask_eq(d, vcast_vd_d(0)), vcast_vd_d(-INFINITY), x); + + return x; +} + +static INLINE vdouble xexp(vdouble d) { + vint q = vrint_vi_vd(vmul(d, vcast_vd_d(R_LN2))); + vdouble s, u; + + s = vadd(d, vmul(vcast_vd_vi(q), vcast_vd_d(-L2U))); + s = vadd(s, vmul(vcast_vd_vi(q), vcast_vd_d(-L2L))); + + u = vcast_vd_d(2.08860621107283687536341e-09); + u = vmla(u, s, vcast_vd_d(2.51112930892876518610661e-08)); + u = vmla(u, s, vcast_vd_d(2.75573911234900471893338e-07)); + u = vmla(u, s, vcast_vd_d(2.75572362911928827629423e-06)); + u = vmla(u, s, vcast_vd_d(2.4801587159235472998791e-05)); + u = vmla(u, s, vcast_vd_d(0.000198412698960509205564975)); + u = vmla(u, s, vcast_vd_d(0.00138888888889774492207962)); + u = vmla(u, s, vcast_vd_d(0.00833333333331652721664984)); + u = vmla(u, s, vcast_vd_d(0.0416666666666665047591422)); + u = vmla(u, s, vcast_vd_d(0.166666666666666851703837)); + u = vmla(u, s, vcast_vd_d(0.5)); + + u = vadd(vcast_vd_d(1), vadd(s, vmul(vmul(s, s), u))); + + u = vldexp(u, q); + + u = vsel(vmask_isminf(d), vcast_vd_d(0), u); + + return u; +} + +static INLINE vdouble2 logk(vdouble d) { + vdouble2 x, x2; + vdouble t, m; + vint e; + + e = vilogbp1(vmul(d, vcast_vd_d(0.7071))); + m = vldexp(d, vsubi(vcast_vi_i(0), e)); + + x = div_dd(add2_ss(vcast_vd_d(-1), m), add2_ss(vcast_vd_d(1), m)); + x2 = squ_d(x); + x2 = normalize_d(x2); + + t = vcast_vd_d(0.134601987501262130076155); + t = vmla(t, x2.x, vcast_vd_d(0.132248509032032670243288)); + t = vmla(t, x2.x, vcast_vd_d(0.153883458318096079652524)); + t = vmla(t, x2.x, vcast_vd_d(0.181817427573705403298686)); + t = vmla(t, x2.x, vcast_vd_d(0.222222231326187414840781)); + t = vmla(t, x2.x, vcast_vd_d(0.285714285651261412873718)); + t = vmla(t, x2.x, vcast_vd_d(0.400000000000222439910458)); + t = vmla(t, x2.x, vcast_vd_d(0.666666666666666371239645)); + + return add2_dd(mul_ds(dd(vcast_vd_d(0.693147180559945286226764), vcast_vd_d(2.319046813846299558417771e-17)), + vcast_vd_vi(e)), + add2_dd(scale_d(x, vcast_vd_d(2)), mul_ds(mul_dd(x2, x), t))); +} + +static INLINE vdouble expk(vdouble2 d) { + vdouble u = vmul(vadd(d.x, d.y), vcast_vd_d(R_LN2)); + vint q = vrint_vi_vd(u); + vdouble2 s, t; + + s = add2_ds(d, vmul(vcast_vd_vi(q), vcast_vd_d(-L2U))); + s = add2_ds(s, vmul(vcast_vd_vi(q), vcast_vd_d(-L2L))); + + q = vrint_vi_vd(vmin(vmax(vcast_vd_d(-2047.49), u), vcast_vd_d(2047.49))); + + s = normalize_d(s); + + u = vcast_vd_d(2.51069683420950419527139e-08); + u = vmla(u, s.x, vcast_vd_d(2.76286166770270649116855e-07)); + u = vmla(u, s.x, vcast_vd_d(2.75572496725023574143864e-06)); + u = vmla(u, s.x, vcast_vd_d(2.48014973989819794114153e-05)); + u = vmla(u, s.x, vcast_vd_d(0.000198412698809069797676111)); + u = vmla(u, s.x, vcast_vd_d(0.0013888888939977128960529)); + u = vmla(u, s.x, vcast_vd_d(0.00833333333332371417601081)); + u = vmla(u, s.x, vcast_vd_d(0.0416666666665409524128449)); + u = vmla(u, s.x, vcast_vd_d(0.166666666666666740681535)); + u = vmla(u, s.x, vcast_vd_d(0.500000000000000999200722)); + + t = add_dd(s, mul_ds(squ_d(s), u)); + + t = add_sd(vcast_vd_d(1), t); + u = vadd(t.x, t.y); + u = vldexp(u, q); + + return u; +} + +static INLINE vdouble xpow(vdouble x, vdouble y) { +#if 1 + vmask yisint = vmask_eq(vcast_vd_vi(vrint_vi_vd(y)), y); + vmask yisodd = vandm(vmaski_eq(vandi(vrint_vi_vd(y), vcast_vi_i(1)), vcast_vi_i(1)), yisint); + + vdouble result = expk(mul_ds(logk(vabs(x)), y)); + + //result = vsel(vmask_isnan(result), vcast_vd_d(INFINITY), result); + + result = vmul(result, + vsel(vmask_gt(x, vcast_vd_d(0)), + vcast_vd_d(1), + vsel(yisint, + vsel(yisodd, + vcast_vd_d(-1), + vcast_vd_d(1)), + vcast_vd_d(NAN)))); + + vdouble efx = vreinterpret_vd_vm(vxorm(vreinterpret_vm_vd(vsub(vabs(x), vcast_vd_d(1))), vsignbit(y))); + + result = vsel(vmask_isinf(y), + vsel(vmask_lt(efx, vcast_vd_d(0)), + vcast_vd_d(0), + vsel(vmask_eq(efx, vcast_vd_d(0)), + vcast_vd_d(1.0), + vcast_vd_d(INFINITY))), + result); + + result = vsel(vorm(vmask_isinf(x), vmask_eq(x, vcast_vd_d(0))), + vmul(vsel(yisodd, vsign(x), vcast_vd_d(1)), + vsel(vmask_lt(vsel(vmask_eq(x, vcast_vd_d(0)), vneg(y), y), vcast_vd_d(0)), + vcast_vd_d(0), + vcast_vd_d(INFINITY))), + result); + + result = vsel(vorm(vmask_isnan(x), vmask_isnan(y)), vcast_vd_d(NAN), result); + + result = vsel(vorm(vmask_eq(y, vcast_vd_d(0)), vmask_eq(x, vcast_vd_d(1))), vcast_vd_d(1), result); + + return result; +#else + return expk(mul_ds(logk(x), y)); +#endif +} + +static INLINE vdouble2 expk2(vdouble2 d) { + vdouble u = vmul(vadd(d.x, d.y), vcast_vd_d(R_LN2)); + vint q = vrint_vi_vd(u); + vdouble2 s, t; + + s = add2_ds(d, vmul(vcast_vd_vi(q), vcast_vd_d(-L2U))); + s = add2_ds(s, vmul(vcast_vd_vi(q), vcast_vd_d(-L2L))); + + q = vrint_vi_vd(vmin(vmax(vcast_vd_d(-2047.49), u), vcast_vd_d(2047.49))); + + s = normalize_d(s); + + u = vcast_vd_d(2.51069683420950419527139e-08); + u = vmla(u, s.x, vcast_vd_d(2.76286166770270649116855e-07)); + u = vmla(u, s.x, vcast_vd_d(2.75572496725023574143864e-06)); + u = vmla(u, s.x, vcast_vd_d(2.48014973989819794114153e-05)); + u = vmla(u, s.x, vcast_vd_d(0.000198412698809069797676111)); + u = vmla(u, s.x, vcast_vd_d(0.0013888888939977128960529)); + u = vmla(u, s.x, vcast_vd_d(0.00833333333332371417601081)); + u = vmla(u, s.x, vcast_vd_d(0.0416666666665409524128449)); + u = vmla(u, s.x, vcast_vd_d(0.166666666666666740681535)); + u = vmla(u, s.x, vcast_vd_d(0.500000000000000999200722)); + + t = add_dd(s, mul_ds(squ_d(s), u)); + + t = add_sd(vcast_vd_d(1), t); + + return dd(vldexp(t.x, q), vldexp(t.y, q)); +} + +static INLINE vdouble xsinh(vdouble x) { + vdouble y = vabs(x); + vdouble2 d = expk2(dd(y, vcast_vd_d(0))); + d = add2_dd(d, div_dd(dd(vcast_vd_d(-1), vcast_vd_d(0)), d)); + y = vmul(vadd(d.x, d.y), vcast_vd_d(0.5)); + + y = vsel(vorm(vmask_isinf(x), vmask_isnan(y)), vcast_vd_d(INFINITY), y); + y = vmulsign(y, x); + y = vsel(vmask_isnan(x), vcast_vd_d(NAN), y); + + return y; +} + +static INLINE vdouble xcosh(vdouble x) { + vdouble2 d = expk2(dd(x, vcast_vd_d(0))); + d = add2_dd(d, div_dd(dd(vcast_vd_d(1), vcast_vd_d(0)), d)); + vdouble y = vmul(vadd(d.x, d.y), vcast_vd_d(0.5)); + + y = vsel(vorm(vmask_isinf(x), vmask_isnan(y)), vcast_vd_d(INFINITY), y); + y = vsel(vmask_isnan(x), vcast_vd_d(NAN), y); + + return y; +} + +static INLINE vdouble xtanh(vdouble x) { + vdouble y = vabs(x); + vdouble2 d = expk2(dd(y, vcast_vd_d(0))); + vdouble2 e = div_dd(dd(vcast_vd_d(1), vcast_vd_d(0)), d); + d = div_dd(add2_dd(d, scale_d(e, vcast_vd_d(-1))), add2_dd(d, e)); + y = d.x + d.y; + + y = vsel(vorm(vmask_isinf(x), vmask_isnan(y)), vcast_vd_d(1.0), y); + y = vmulsign(y, x); + y = vsel(vmask_isnan(x), vcast_vd_d(NAN), y); + + return y; +} + +static INLINE vdouble2 logk2(vdouble2 d) { + vdouble2 x, x2, m; + vdouble t; + vint e; + + d = normalize_d(d); + e = vilogbp1(vmul(d.x, vcast_vd_d(0.7071))); + m = scale_d(d, vldexp(vcast_vd_d(1), vsubi(vcast_vi_i(0), e))); + + x = div_dd(add2_ds(m, vcast_vd_d(-1)), add2_ds(m, vcast_vd_d(1))); + x2 = squ_d(x); + x2 = normalize_d(x2); + + t = vcast_vd_d(0.134601987501262130076155); + t = vmla(t, x2.x, vcast_vd_d(0.132248509032032670243288)); + t = vmla(t, x2.x, vcast_vd_d(0.153883458318096079652524)); + t = vmla(t, x2.x, vcast_vd_d(0.181817427573705403298686)); + t = vmla(t, x2.x, vcast_vd_d(0.222222231326187414840781)); + t = vmla(t, x2.x, vcast_vd_d(0.285714285651261412873718)); + t = vmla(t, x2.x, vcast_vd_d(0.400000000000222439910458)); + t = vmla(t, x2.x, vcast_vd_d(0.666666666666666371239645)); + + return add2_dd(mul_ds(dd(vcast_vd_d(0.693147180559945286226764), vcast_vd_d(2.319046813846299558417771e-17)), + vcast_vd_vi(e)), + add2_dd(scale_d(x, vcast_vd_d(2)), mul_ds(mul_dd(x2, x), t))); +} + +static INLINE vdouble xasinh(vdouble x) { + vdouble y = vabs(x); + vdouble2 d = logk2(add2_ds(sqrt_d(add2_ds(mul_ss(y, y), vcast_vd_d(1))), y)); + y = vadd(d.x, d.y); + + y = vsel(vorm(vmask_isinf(x), vmask_isnan(y)), vcast_vd_d(INFINITY), y); + y = vmulsign(y, x); + y = vsel(vmask_isnan(x), vcast_vd_d(NAN), y); + + return y; +} + +static INLINE vdouble xacosh(vdouble x) { + vdouble2 d = logk2(add2_ds(sqrt_d(add2_ds(mul_ss(x, x), vcast_vd_d(-1))), x)); + vdouble y = vadd(d.x, d.y); + + y = vsel(vorm(vmask_isinf(x), vmask_isnan(y)), vcast_vd_d(INFINITY), y); + y = vsel(vmask_eq(x, vcast_vd_d(1.0)), vcast_vd_d(0.0), y); + y = vsel(vmask_lt(x, vcast_vd_d(1.0)), vcast_vd_d(NAN), y); + y = vsel(vmask_isnan(x), vcast_vd_d(NAN), y); + + return y; +} + +static INLINE vdouble xatanh(vdouble x) { + vdouble y = vabs(x); + vdouble2 d = logk2(div_dd(add2_ss(vcast_vd_d(1), y), add2_ss(vcast_vd_d(1), -y))); + y = vsel(vmask_gt(y, vcast_vd_d(1.0)), vcast_vd_d(NAN), vsel(vmask_eq(y, vcast_vd_d(1.0)), vcast_vd_d(INFINITY), vmul(vadd(d.x, d.y), vcast_vd_d(0.5)))); + + y = vsel(vorm(vmask_isinf(x), vmask_isnan(y)), vcast_vd_d(NAN), y); + y = vmulsign(y, x); + y = vsel(vmask_isnan(x), vcast_vd_d(NAN), y); + + return y; +} + +static INLINE vdouble xcbrt(vdouble d) { + vdouble x, y, q = vcast_vd_d(1.0); + vint e, qu, re; + vdouble t; + + e = vilogbp1(vabs(d)); + d = vldexp(d, vsubi(vcast_vi_i(0), e)); + + t = vadd(vcast_vd_vi(e), vcast_vd_d(6144)); + qu = vtruncate_vi_vd(vdiv(t, vcast_vd_d(3))); + re = vtruncate_vi_vd(vsub(t, vmul(vcast_vd_vi(qu), vcast_vd_d(3)))); + + q = vsel(vmaski_eq(re, vcast_vi_i(1)), vcast_vd_d(1.2599210498948731647672106), q); + q = vsel(vmaski_eq(re, vcast_vi_i(2)), vcast_vd_d(1.5874010519681994747517056), q); + q = vldexp(q, vsubi(qu, vcast_vi_i(2048))); + + q = vmulsign(q, d); + + d = vabs(d); + + x = vcast_vd_d(-0.640245898480692909870982); + x = vmla(x, d, vcast_vd_d(2.96155103020039511818595)); + x = vmla(x, d, vcast_vd_d(-5.73353060922947843636166)); + x = vmla(x, d, vcast_vd_d(6.03990368989458747961407)); + x = vmla(x, d, vcast_vd_d(-3.85841935510444988821632)); + x = vmla(x, d, vcast_vd_d(2.2307275302496609725722)); + + y = vmul(x, x); y = vmul(y, y); x = vsub(x, vmul(vmla(d, y, vneg(x)), vcast_vd_d(1.0 / 3.0))); + y = vmul(vmul(d, x), x); + y = vmul(vsub(y, vmul(vmul(vcast_vd_d(2.0 / 3.0), y), vmla(y, x, vcast_vd_d(-1.0)))), q); + + return y; +} + +static INLINE vdouble xexp2(vdouble a) { + vdouble u = expk(mul_ds(dd(vcast_vd_d(0.69314718055994528623), vcast_vd_d(2.3190468138462995584e-17)), a)); + u = vsel(vmask_ispinf(a), vcast_vd_d(INFINITY), u); + u = vsel(vmask_isminf(a), vcast_vd_d(0), u); + return u; +} + +static INLINE vdouble xexp10(vdouble a) { + vdouble u = expk(mul_ds(dd(vcast_vd_d(2.3025850929940459011), vcast_vd_d(-2.1707562233822493508e-16)), a)); + u = vsel(vmask_ispinf(a), vcast_vd_d(INFINITY), u); + u = vsel(vmask_isminf(a), vcast_vd_d(0), u); + return u; +} + +static INLINE vdouble xexpm1(vdouble a) { + vdouble2 d = add2_ds(expk2(dd(a, vcast_vd_d(0))), vcast_vd_d(-1.0)); + vdouble x = d.x + d.y; + x = vsel(vmask_ispinf(a), vcast_vd_d(INFINITY), x); + x = vsel(vmask_isminf(a), vcast_vd_d(-1), x); + return x; +} + +static INLINE vdouble xlog10(vdouble a) { + vdouble2 d = mul_dd(logk(a), dd(vcast_vd_d(0.43429448190325176116), vcast_vd_d(6.6494347733425473126e-17))); + vdouble x = d.x + d.y; + + x = vsel(vmask_ispinf(a), vcast_vd_d(INFINITY), x); + x = vsel(vmask_gt(vcast_vd_d(0), a), vcast_vd_d(NAN), x); + x = vsel(vmask_eq(a, vcast_vd_d(0)), vcast_vd_d(-INFINITY), x); + + return x; +} + +static INLINE vdouble xlog1p(vdouble a) { + vdouble2 d = logk2(add2_ss(a, vcast_vd_d(1))); + vdouble x = d.x + d.y; + + x = vsel(vmask_ispinf(a), vcast_vd_d(INFINITY), x); + x = vsel(vmask_gt(vcast_vd_d(-1), a), vcast_vd_d(NAN), x); + x = vsel(vmask_eq(a, vcast_vd_d(-1)), vcast_vd_d(-INFINITY), x); + + return x; +} + +// + +typedef struct { + vfloat x, y; +} vfloat2; +#if defined( __FMA__ ) && defined( __x86_64__ ) + static INLINE vfloat vmlaf(vfloat x, vfloat y, vfloat z) { return _mm_fmadd_ps(x,y,z); } +#else + static INLINE vfloat vmlaf(vfloat x, vfloat y, vfloat z) { return vaddf(vmulf(x, y), z); } +#endif +static INLINE vfloat vabsf(vfloat f) { return (vfloat)vandnotm((vmask)vcast_vf_f(-0.0f), (vmask)f); } +static INLINE vfloat vnegf(vfloat f) { return (vfloat)vxorm((vmask)f, (vmask)vcast_vf_f(-0.0f)); } + +#if defined( __SSE4_1__ ) && defined( __x86_64__ ) + // only one instruction when using SSE4.1 + static INLINE vfloat vself(vmask mask, vfloat x, vfloat y) { + return _mm_blendv_ps(y,x,(vfloat)mask); + } +#else + // three instructions when using SSE2 + static INLINE vfloat vself(vmask mask, vfloat x, vfloat y) { + return (vfloat)vorm(vandm(mask, (vmask)x), vandnotm(mask, (vmask)y)); + } +#endif + +static INLINE vint2 vseli2_lt(vfloat f0, vfloat f1, vint2 x, vint2 y) { + vint2 m2 = vcast_vi2_vm(vmaskf_lt(f0, f1)); + return vori2(vandi2(m2, x), vandnoti2(m2, y)); +} + +static INLINE vmask vsignbitf(vfloat f) { + return vandm((vmask)f, (vmask)vcast_vf_f(-0.0f)); +} + +static INLINE vfloat vmulsignf(vfloat x, vfloat y) { + return (vfloat)vxorm((vmask)x, vsignbitf(y)); +} + +static INLINE vfloat vsignf(vfloat f) { + return (vfloat)vorm((vmask)vcast_vf_f(1.0f), vandm((vmask)vcast_vf_f(-0.0f), (vmask)f)); +} + +static INLINE vmask vmaskf_isinf(vfloat d) { return vmaskf_eq(vabsf(d), vcast_vf_f(INFINITYf)); } +static INLINE vmask vmaskf_ispinf(vfloat d) { return vmaskf_eq(d, vcast_vf_f(INFINITYf)); } +static INLINE vmask vmaskf_isminf(vfloat d) { return vmaskf_eq(d, vcast_vf_f(-INFINITYf)); } +static INLINE vmask vmaskf_isnan(vfloat d) { return vmaskf_neq(d, d); } +static INLINE vfloat visinf2f(vfloat d, vfloat m) { return (vfloat)vandm(vmaskf_isinf(d), vorm(vsignbitf(d), (vmask)m)); } +static INLINE vfloat visinff(vfloat d) { return visinf2f(d, vcast_vf_f(1.0f)); } + +static INLINE vint2 vilogbp1f(vfloat d) { + vmask m = vmaskf_lt(d, vcast_vf_f(5.421010862427522E-20f)); + d = vself(m, vmulf(vcast_vf_f(1.8446744073709552E19f), d), d); + vint2 q = vandi2(vsrli2(vcast_vi2_vm(vreinterpret_vm_vf(d)), 23), vcast_vi2_i(0xff)); + q = vsubi2(q, vseli2(m, vcast_vi2_i(64 + 0x7e), vcast_vi2_i(0x7e))); + return q; +} + +static INLINE vfloat vldexpf(vfloat x, vint2 q) { + vfloat u; + vint2 m = vsrai2(q, 31); + m = vslli2(vsubi2(vsrai2(vaddi2(m, q), 6), m), 4); + q = vsubi2(q, vslli2(m, 2)); + u = vreinterpret_vf_vm(vcast_vm_vi2(vslli2(vaddi2(m, vcast_vi2_i(0x7f)), 23))); + x = vmulf(vmulf(vmulf(vmulf(x, u), u), u), u); + u = vreinterpret_vf_vm(vcast_vm_vi2(vslli2(vaddi2(q, vcast_vi2_i(0x7f)), 23))); + return vmulf(x, u); +} + +static INLINE vfloat xsinf(vfloat d) { + vint2 q; + vfloat u, s; + + q = vrint_vi2_vf(vmulf(d, vcast_vf_f((float)M_1_PI))); + + u = vcast_vf_vi2(q); + d = vmlaf(u, vcast_vf_f(-PI4_Af*4), d); + d = vmlaf(u, vcast_vf_f(-PI4_Bf*4), d); + d = vmlaf(u, vcast_vf_f(-PI4_Cf*4), d); + d = vmlaf(u, vcast_vf_f(-PI4_Df*4), d); + + s = vmulf(d, d); + + d = vself(vmaski2_eq(vandi2(q, vcast_vi2_i(1)), vcast_vi2_i(1)), vnegf(d), d); + + u = vcast_vf_f(2.6083159809786593541503e-06f); + u = vmlaf(u, s, vcast_vf_f(-0.0001981069071916863322258f)); + u = vmlaf(u, s, vcast_vf_f(0.00833307858556509017944336f)); + u = vmlaf(u, s, vcast_vf_f(-0.166666597127914428710938f)); + + u = vmlaf(s, vmulf(u, d), d); + + return u; +} + +static INLINE vfloat xcosf(vfloat d) { + vint2 q; + vfloat u, s; + + q = vrint_vi2_vf(vsubf(vmulf(d, vcast_vf_f((float)M_1_PI)), vcast_vf_f(0.5f))); + q = vaddi2(vaddi2(q, q), vcast_vi2_i(1)); + + u = vcast_vf_vi2(q); + d = vmlaf(u, vcast_vf_f(-PI4_Af*2), d); + d = vmlaf(u, vcast_vf_f(-PI4_Bf*2), d); + d = vmlaf(u, vcast_vf_f(-PI4_Cf*2), d); + d = vmlaf(u, vcast_vf_f(-PI4_Df*2), d); + + s = vmulf(d, d); + + d = vself(vmaski2_eq(vandi2(q, vcast_vi2_i(2)), vcast_vi2_i(2)), d, vnegf(d)); + + u = vcast_vf_f(2.6083159809786593541503e-06f); + u = vmlaf(u, s, vcast_vf_f(-0.0001981069071916863322258f)); + u = vmlaf(u, s, vcast_vf_f(0.00833307858556509017944336f)); + u = vmlaf(u, s, vcast_vf_f(-0.166666597127914428710938f)); + + u = vmlaf(s, vmulf(u, d), d); + + return u; +} + +static INLINE vfloat2 xsincosf(vfloat d) { + vint2 q; + vmask m; + vfloat u, s, t, rx, ry; + vfloat2 r; + + q = vrint_vi2_vf(vmulf(d, vcast_vf_f((float)M_2_PI))); + + s = d; + + u = vcast_vf_vi2(q); + s = vmlaf(u, vcast_vf_f(-PI4_Af*2), s); + s = vmlaf(u, vcast_vf_f(-PI4_Bf*2), s); + s = vmlaf(u, vcast_vf_f(-PI4_Cf*2), s); + s = vmlaf(u, vcast_vf_f(-PI4_Df*2), s); + + t = s; + + s = vmulf(s, s); + + u = vcast_vf_f(-0.000195169282960705459117889f); + u = vmlaf(u, s, vcast_vf_f(0.00833215750753879547119141f)); + u = vmlaf(u, s, vcast_vf_f(-0.166666537523269653320312f)); + u = vmulf(vmulf(u, s), t); + + rx = vaddf(t, u); + + u = vcast_vf_f(-2.71811842367242206819355e-07f); + u = vmlaf(u, s, vcast_vf_f(2.47990446951007470488548e-05f)); + u = vmlaf(u, s, vcast_vf_f(-0.00138888787478208541870117f)); + u = vmlaf(u, s, vcast_vf_f(0.0416666641831398010253906f)); + u = vmlaf(u, s, vcast_vf_f(-0.5)); + + ry = vaddf(vcast_vf_f(1), vmulf(s, u)); + + m = vmaski2_eq(vandi2(q, vcast_vi2_i(1)), vcast_vi2_i(0)); + r.x = vself(m, rx, ry); + r.y = vself(m, ry, rx); + + m = vmaski2_eq(vandi2(q, vcast_vi2_i(2)), vcast_vi2_i(2)); + r.x = vreinterpret_vf_vm(vxorm(vandm(m, vreinterpret_vm_vf(vcast_vf_f(-0.0))), vreinterpret_vm_vf(r.x))); + + m = vmaski2_eq(vandi2(vaddi2(q, vcast_vi2_i(1)), vcast_vi2_i(2)), vcast_vi2_i(2)); + r.y = vreinterpret_vf_vm(vxorm(vandm(m, vreinterpret_vm_vf(vcast_vf_f(-0.0))), vreinterpret_vm_vf(r.y))); + + m = vmaskf_isinf(d); + r.x = vself(m, vcast_vf_f(NAN), r.x); + r.y = vself(m, vcast_vf_f(NAN), r.y); + + return r; +} + +static INLINE vfloat xtanf(vfloat d) { + vint2 q; + vmask m; + vfloat u, s, x; + + q = vrint_vi2_vf(vmulf(d, vcast_vf_f((float)(2 * M_1_PI)))); + + x = d; + + u = vcast_vf_vi2(q); + x = vmlaf(u, vcast_vf_f(-PI4_Af*2), x); + x = vmlaf(u, vcast_vf_f(-PI4_Bf*2), x); + x = vmlaf(u, vcast_vf_f(-PI4_Cf*2), x); + x = vmlaf(u, vcast_vf_f(-PI4_Df*2), x); + + s = vmulf(x, x); + + m = vmaski2_eq(vandi2(q, vcast_vi2_i(1)), vcast_vi2_i(1)); + x = vself(m, vnegf(x), x); + + u = vcast_vf_f(0.00927245803177356719970703f); + u = vmlaf(u, s, vcast_vf_f(0.00331984995864331722259521f)); + u = vmlaf(u, s, vcast_vf_f(0.0242998078465461730957031f)); + u = vmlaf(u, s, vcast_vf_f(0.0534495301544666290283203f)); + u = vmlaf(u, s, vcast_vf_f(0.133383005857467651367188f)); + u = vmlaf(u, s, vcast_vf_f(0.333331853151321411132812f)); + + u = vmlaf(s, vmulf(u, x), x); + + u = vself(m, vrecf(u), u); + + u = vself(vmaskf_isinf(d), vcast_vf_f(NANf), u); + + return u; +} + +static INLINE vfloat xatanf(vfloat s) { + vfloat t, u; + vint2 q; + + q = vseli2_lt(s, vcast_vf_f(0.0f), vcast_vi2_i(2), vcast_vi2_i(0)); + s = vabsf(s); + + q = vseli2_lt(vcast_vf_f(1.0f), s, vaddi2(q, vcast_vi2_i(1)), q); + s = vself(vmaskf_lt(vcast_vf_f(1.0f), s), vdivf(vcast_vf_f(1.0f), s), s); + + t = vmulf(s, s); + + u = vcast_vf_f(0.00282363896258175373077393f); + u = vmlaf(u, t, vcast_vf_f(-0.0159569028764963150024414f)); + u = vmlaf(u, t, vcast_vf_f(0.0425049886107444763183594f)); + u = vmlaf(u, t, vcast_vf_f(-0.0748900920152664184570312f)); + u = vmlaf(u, t, vcast_vf_f(0.106347933411598205566406f)); + u = vmlaf(u, t, vcast_vf_f(-0.142027363181114196777344f)); + u = vmlaf(u, t, vcast_vf_f(0.199926957488059997558594f)); + u = vmlaf(u, t, vcast_vf_f(-0.333331018686294555664062f)); + + t = vaddf(s, vmulf(s, vmulf(t, u))); + + t = vself(vmaski2_eq(vandi2(q, vcast_vi2_i(1)), vcast_vi2_i(1)), vsubf(vcast_vf_f((float)(M_PI/2)), t), t); + t = vself(vmaski2_eq(vandi2(q, vcast_vi2_i(2)), vcast_vi2_i(2)), vnegf(t), t); + + return t; +} + +static INLINE vfloat atan2kf(vfloat y, vfloat x) { + vfloat s, t, u; + vint2 q; + vmask p; + + q = vseli2_lt(x, vcast_vf_f(0.0f), vcast_vi2_i(-2), vcast_vi2_i(0)); + x = vabsf(x); + + q = vseli2_lt(x, y, vaddi2(q, vcast_vi2_i(1)), q); + p = vmaskf_lt(x, y); + s = vself(p, vnegf(x), y); + t = vmaxf(x, y); + + s = vdivf(s, t); + t = vmulf(s, s); + + u = vcast_vf_f(0.00282363896258175373077393f); + u = vmlaf(u, t, vcast_vf_f(-0.0159569028764963150024414f)); + u = vmlaf(u, t, vcast_vf_f(0.0425049886107444763183594f)); + u = vmlaf(u, t, vcast_vf_f(-0.0748900920152664184570312f)); + u = vmlaf(u, t, vcast_vf_f(0.106347933411598205566406f)); + u = vmlaf(u, t, vcast_vf_f(-0.142027363181114196777344f)); + u = vmlaf(u, t, vcast_vf_f(0.199926957488059997558594f)); + u = vmlaf(u, t, vcast_vf_f(-0.333331018686294555664062f)); + + t = vaddf(s, vmulf(s, vmulf(t, u))); + t = vaddf(t, vmulf(vcast_vf_vi2(q), vcast_vf_f((float)(M_PI/2)))); + + return t; +} + +static INLINE vfloat xatan2f(vfloat y, vfloat x) { + vfloat r = atan2kf(vabsf(y), x); + + r = vmulsignf(r, x); + r = vself(vorm(vmaskf_isinf(x), vmaskf_eq(x, vcast_vf_f(0.0f))), vsubf(vcast_vf_f((float)(M_PI/2)), visinf2f(x, vmulsignf(vcast_vf_f((float)(M_PI/2)), x))), r); + r = vself(vmaskf_isinf(y), vsubf(vcast_vf_f((float)(M_PI/2)), visinf2f(x, vmulsignf(vcast_vf_f((float)(M_PI/4)), x))), r); + r = vself(vmaskf_eq(y, vcast_vf_f(0.0f)), vself(vmaskf_eq(vsignf(x), vcast_vf_f(-1.0f)), vcast_vf_f((float)M_PI), vcast_vf_f(0.0f)), r); + + return vself(vorm(vmaskf_isnan(x), vmaskf_isnan(y)), vcast_vf_f(NANf), vmulsignf(r, y)); +} + +static INLINE vfloat xasinf(vfloat d) { + vfloat x, y; + x = vaddf(vcast_vf_f(1.0f), d); + y = vsubf(vcast_vf_f(1.0f), d); + x = vmulf(x, y); + x = vsqrtf(x); + x = vself(vmaskf_isnan(x), vcast_vf_f(NANf), atan2kf(vabsf(d), x)); + return vmulsignf(x, d); +} + +static INLINE vfloat xacosf(vfloat d) { + vfloat x, y; + x = vaddf(vcast_vf_f(1.0f), d); + y = vsubf(vcast_vf_f(1.0f), d); + x = vmulf(x, y); + x = vsqrtf(x); + x = vmulsignf(atan2kf(x, vabsf(d)), d); + y = (vfloat)vandm(vmaskf_lt(d, vcast_vf_f(0.0f)), (vmask)vcast_vf_f((float)M_PI)); + x = vaddf(x, y); + return x; +} + +static INLINE vfloat xlogf(vfloat d) { + vfloat x, x2, t, m; + vint2 e; + + e = vilogbp1f(vmulf(d, vcast_vf_f(0.7071f))); + m = vldexpf(d, vsubi2(vcast_vi2_i(0), e)); + + x = vdivf(vaddf(vcast_vf_f(-1.0f), m), vaddf(vcast_vf_f(1.0f), m)); + x2 = vmulf(x, x); + + t = vcast_vf_f(0.2371599674224853515625f); + t = vmlaf(t, x2, vcast_vf_f(0.285279005765914916992188f)); + t = vmlaf(t, x2, vcast_vf_f(0.400005519390106201171875f)); + t = vmlaf(t, x2, vcast_vf_f(0.666666567325592041015625f)); + t = vmlaf(t, x2, vcast_vf_f(2.0f)); + + x = vaddf(vmulf(x, t), vmulf(vcast_vf_f(0.693147180559945286226764f), vcast_vf_vi2(e))); + + x = vself(vmaskf_ispinf(d), vcast_vf_f(INFINITYf), x); + x = vself(vmaskf_gt(vcast_vf_f(0), d), vcast_vf_f(NANf), x); + x = vself(vmaskf_eq(d, vcast_vf_f(0)), vcast_vf_f(-INFINITYf), x); + + return x; +} + +static INLINE vfloat xlogf0(vfloat d) { + vfloat x, x2, t, m; + vint2 e; + + e = vilogbp1f(vmulf(d, vcast_vf_f(0.7071f))); + m = vldexpf(d, vsubi2(vcast_vi2_i(0), e)); + + x = vdivf(vaddf(vcast_vf_f(-1.0f), m), vaddf(vcast_vf_f(1.0f), m)); + x2 = vmulf(x, x); + + t = vcast_vf_f(0.2371599674224853515625f); + t = vmlaf(t, x2, vcast_vf_f(0.285279005765914916992188f)); + t = vmlaf(t, x2, vcast_vf_f(0.400005519390106201171875f)); + t = vmlaf(t, x2, vcast_vf_f(0.666666567325592041015625f)); + t = vmlaf(t, x2, vcast_vf_f(2.0f)); + + x = vaddf(vmulf(x, t), vmulf(vcast_vf_f(0.693147180559945286226764f), vcast_vf_vi2(e))); + + x = vself(vmaskf_ispinf(d), vcast_vf_f(0), x); + x = vself(vmaskf_gt(vcast_vf_f(0), d), vcast_vf_f(0), x); + x = vself(vmaskf_eq(d, vcast_vf_f(0)), vcast_vf_f(0), x); + + return x; +} + + +static INLINE vfloat xexpf(vfloat d) { + vint2 q = vrint_vi2_vf(vmulf(d, vcast_vf_f(R_LN2f))); + vfloat s, u; + + s = vmlaf(vcast_vf_vi2(q), vcast_vf_f(-L2Uf),d); + s = vmlaf(vcast_vf_vi2(q), vcast_vf_f(-L2Lf),s); + + u = vcast_vf_f(0.00136324646882712841033936f); + u = vmlaf(u, s, vcast_vf_f(0.00836596917361021041870117f)); + u = vmlaf(u, s, vcast_vf_f(0.0416710823774337768554688f)); + u = vmlaf(u, s, vcast_vf_f(0.166665524244308471679688f)); + u = vmlaf(u, s, vcast_vf_f(0.499999850988388061523438f)); + + u = vaddf(vcast_vf_f(1.0f), vmlaf(vmulf(s, s), u, s)); + + u = vldexpf(u, q); + + u = vself(vmaskf_isminf(d), vcast_vf_f(0.0f), u); +// -104.0 + u = vself(vmaskf_gt(vcast_vf_f(-104), d), vcast_vf_f(0), u); + return u; +} + +static INLINE vfloat xcbrtf(vfloat d) { + vfloat x, y, q = vcast_vf_f(1.0), t; + vint2 e, qu, re; + + e = vilogbp1f(vabsf(d)); + d = vldexpf(d, vsubi2(vcast_vi2_i(0), e)); + + t = vaddf(vcast_vf_vi2(e), vcast_vf_f(6144)); + qu = vtruncate_vi2_vf(vdivf(t, vcast_vf_f(3))); + re = vtruncate_vi2_vf(vsubf(t, vmulf(vcast_vf_vi2(qu), vcast_vf_f(3)))); + + q = vself(vmaski2_eq(re, vcast_vi2_i(1)), vcast_vf_f(1.2599210498948731647672106f), q); + q = vself(vmaski2_eq(re, vcast_vi2_i(2)), vcast_vf_f(1.5874010519681994747517056f), q); + q = vldexpf(q, vsubi2(qu, vcast_vi2_i(2048))); + + q = vmulsignf(q, d); + d = vabsf(d); + + x = vcast_vf_f(-0.601564466953277587890625f); + x = vmlaf(x, d, vcast_vf_f(2.8208892345428466796875f)); + x = vmlaf(x, d, vcast_vf_f(-5.532182216644287109375f)); + x = vmlaf(x, d, vcast_vf_f(5.898262500762939453125f)); + x = vmlaf(x, d, vcast_vf_f(-3.8095417022705078125f)); + x = vmlaf(x, d, vcast_vf_f(2.2241256237030029296875f)); + + y = vmulf(vmulf(d, x), x); + y = vmulf(vsubf(y, vmulf(vmulf(vcast_vf_f(2.0f / 3.0f), y), vmlaf(y, x, vcast_vf_f(-1.0f)))), q); + + return y; +} + +static INLINE vfloat LIMV( vfloat a, vfloat b, vfloat c ) { +return _mm_max_ps( b, _mm_min_ps(a,c)); +} + +static INLINE vfloat ULIMV( vfloat a, vfloat b, vfloat c ){ + return vself( vmaskf_lt(b,c), LIMV(a,b,c), LIMV(a,c,b)); +} + +static INLINE vfloat SQRV(vfloat a){ + return _mm_mul_ps( a,a ); +} + +static inline void vswap( vmask condition, vfloat &a, vfloat &b) { + vfloat temp = vself(condition, a, b); // the larger of the two + condition = vnotm(condition); // invert the mask + a = vself(condition, a, b); // the smaller of the two + b = temp; +} + +#endif // __SSE2__ +#endif // SLEEFSSEAVX diff --git a/rtengine/sleefsseavx.h b/rtengine/sleefsseavx.h new file mode 100644 index 000000000..b2b179dd3 --- /dev/null +++ b/rtengine/sleefsseavx.h @@ -0,0 +1,108 @@ +#include +#include + +#ifdef __SSE2__ +#define VECTLENDP 2 +#define VECTLENSP 4 + +typedef __m128d vdouble; +typedef __m128i vint; + +typedef __m128 vfloat; +typedef __m128i vint2; +typedef __m128i vmask; + +static vdouble vloadu(double *p) { return _mm_loadu_pd(p); } +static void vstoreu(double *p, vdouble v) { _mm_storeu_pd(p, v); } + +static vfloat vloaduf(float *p) { return _mm_loadu_ps(p); } +static void vstoreuf(float *p, vfloat v) { _mm_storeu_ps(p, v); } + +static vint2 vloadui2(int32_t *p) { return (vint2)_mm_loadu_si128((__m128i *)p); } +static void vstoreui2(int32_t *p, vint2 v) { _mm_storeu_si128((__m128i *)p, (__m128i)v); } +#endif + +#ifdef ENABLE_AVX +#define VECTLENDP 4 +#define VECTLENSP 8 + +typedef __m256d vdouble; +typedef __m128i vint; + + +typedef __m256 vfloat; +typedef struct { + vint x, y; +} vint2; + +static vdouble vloadu(double *p) { return _mm256_loadu_pd(p); } +static void vstoreu(double *p, vdouble v) { return _mm256_storeu_pd(p, v); } + +static vfloat vloaduf(float *p) { return _mm256_loadu_ps(p); } +static void vstoreuf(float *p, vfloat v) { return _mm256_storeu_ps(p, v); } + +static vint2 vloadui2(int32_t *p) { + vint2 r; + r.x = _mm_loadu_si128((__m128i *) p ); + r.y = _mm_loadu_si128((__m128i *)(p + 4)); + return r; +} + +static void vstoreui2(int32_t *p, vint2 v) { + _mm_storeu_si128((__m128i *) p , v.x); + _mm_storeu_si128((__m128i *)(p + 4), v.y); +} +#endif + +typedef struct { + vdouble x, y; +} vdouble2; + +vdouble xldexp(vdouble x, vint q); +vint xilogb(vdouble d); + +vdouble xsin(vdouble d); +vdouble xcos(vdouble d); +vdouble2 xsincos(vdouble d); +vdouble xtan(vdouble d); +vdouble xasin(vdouble s); +vdouble xacos(vdouble s); +vdouble xatan(vdouble s); +vdouble xatan2(vdouble y, vdouble x); +vdouble xlog(vdouble d); +vdouble xexp(vdouble d); +vdouble xpow(vdouble x, vdouble y); + +vdouble xsinh(vdouble d); +vdouble xcosh(vdouble d); +vdouble xtanh(vdouble d); +vdouble xasinh(vdouble s); +vdouble xacosh(vdouble s); +vdouble xatanh(vdouble s); + +vdouble xcbrt(vdouble d); + +vdouble xexp2(vdouble a); +vdouble xexp10(vdouble a); +vdouble xexpm1(vdouble a); +vdouble xlog10(vdouble a); +vdouble xlog1p(vdouble a); + +// + +typedef struct { + vfloat x, y; +} vfloat2; + +vfloat xsinf(vfloat d); +vfloat xcosf(vfloat d); +vfloat2 xsincosf(vfloat d); +vfloat xtanf(vfloat d); +vfloat xasinf(vfloat s); +vfloat xacosf(vfloat s); +vfloat xatanf(vfloat s); +vfloat xatan2f(vfloat y, vfloat x); +vfloat xlogf(vfloat d); +vfloat xlogf0(vfloat d); +vfloat xexpf(vfloat d); +vfloat xcbrtf(vfloat s); diff --git a/rtengine/slicer.cc b/rtengine/slicer.cc new file mode 100644 index 000000000..5008ee1f1 --- /dev/null +++ b/rtengine/slicer.cc @@ -0,0 +1,138 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "rt_math.h" + +#include "slicer.h" + +#ifdef _OPENMP +#include +#endif + +using namespace std; + +// If no parameter set, everything = 0 -> process all the image +Block::Block() { + posX = 0; + posY = 0; + width = 0; + height = 0; +} + +Block::Block(unsigned int x, unsigned int y, unsigned int w, unsigned int h) { + posX = x; + posY = y; + width = w; + height = h; +} + +/* + * Slice a sub-region to process in blocks who's size is given by the number of processor + * and the number of pixel per block (and hence the memory footprint) + */ +Slicer::Slicer(unsigned int imageWidth, unsigned int imageHeight, Block *subRegion, unsigned int pixels ) { + // If the sub-region has a portrait shape, X and Y coordinates are swapped for better result + // It will be swapped back when sending back the block coordinates + region.width = !(subRegion->width) ? imageWidth : subRegion->width; + region.height = !(subRegion->height) ? imageHeight : subRegion->height; // Assuming that the sub-region is under posY + if (region.width < region.height) { + region.width = !(subRegion->height) ? imageHeight : subRegion->height; + region.height = !(subRegion->width) ? imageWidth : subRegion->width; // Assuming that the sub-region is under posY + portrait = true; + imWidth = imageHeight; + imHeight = imageWidth; + region.posX = subRegion->posY; + region.posY = subRegion->posX; + } + else { + portrait = false; + imWidth = imageWidth; + imHeight = imageHeight; + region.posX = subRegion->posX; + region.posY = subRegion->posY; + } + double subRegionRatio = (double)(region.width) / (double)(region.height); + + //total number of core/processor +#ifdef _OPENMP + unsigned int procNumber = omp_get_num_procs(); +#else + unsigned int procNumber = 1; +#endif + + //calculate the number of block + blockNumber = (double(region.width*region.height) / (double)pixels); + blockNumber = int((rtengine::max(blockNumber, 1U) + (double)procNumber/2.)/procNumber)*procNumber; + vBlockNumber = (unsigned int)(sqrt((double)blockNumber / subRegionRatio)+0.5); + vBlockNumber = CLAMP(vBlockNumber, 1, blockNumber); + hBlockNumber = (double)blockNumber / (double)vBlockNumber; + blockWidth = 1.0 / hBlockNumber; + + double maxPixelNumberX = (double)region.height / (double)vBlockNumber; + double maxPixelNumberY = (double)region.width / (double)((unsigned int)hBlockNumber); + if (maxPixelNumberX - (double)((unsigned int)maxPixelNumberX) != 0.) maxPixelNumberX += 1.; + if (maxPixelNumberY - (double)((unsigned int)maxPixelNumberY) != 0.) maxPixelNumberY += 1.; + maxPixelNumber = (unsigned int)maxPixelNumberX * (unsigned int)maxPixelNumberY; + +} + +// return the absolute position and size of the requested block +void Slicer::get_block(unsigned int numBlock, Block *block) { + double roundingTradeOff = (hBlockNumber - (double)((int)hBlockNumber)) == 0.5 ? 2.1 : 2.0; + unsigned int alreadyCompletedLineNbr = (unsigned int)((double)(numBlock) * blockWidth + (blockWidth/roundingTradeOff)); + + unsigned int prevLineEnd = (unsigned int)((double)alreadyCompletedLineNbr * hBlockNumber + 0.5); + unsigned int myLineEnd = (unsigned int)((double)(alreadyCompletedLineNbr+1) * hBlockNumber + 0.5); + + unsigned int nbrCellsOnMyLine = myLineEnd - prevLineEnd; + unsigned int cellOnMyLine = numBlock - prevLineEnd; + + unsigned int blockStart = (unsigned int)(((double)region.width / (double)nbrCellsOnMyLine)*(double)(cellOnMyLine)); + unsigned int blockEnd = (unsigned int)(((double)region.width / (double)nbrCellsOnMyLine)*(double)(cellOnMyLine+1)); + block->width = blockEnd - blockStart; + block->posX = region.posX + blockStart; + if (cellOnMyLine == (nbrCellsOnMyLine-1)) { + // We make sure that the last block of the row take the rest of the remaining X space + block->width = region.posX + region.width - block->posX; + } + + blockStart = (unsigned int)(((double)region.height / (double)vBlockNumber)*(double)(alreadyCompletedLineNbr)); + blockEnd = (unsigned int)(((double)region.height / (double)vBlockNumber)*(double)(alreadyCompletedLineNbr+1)); + block->height = blockEnd - blockStart; + block->posY = region.posY + blockStart; + if (alreadyCompletedLineNbr == (vBlockNumber-1)) { + block->height = region.posY + region.height - block->posY; + } + + if (portrait) { + // we swap back the X/Y coordinates + unsigned int temp; + + temp = block->posX; + block->posX = block->posY; + block->posY = temp; + + temp = block->width; + block->width = block->height; + block->height = temp; + + } +} diff --git a/rtengine/slicer.h b/rtengine/slicer.h new file mode 100644 index 000000000..ac27bca82 --- /dev/null +++ b/rtengine/slicer.h @@ -0,0 +1,61 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _SLICER_ +#define _SLICER_ + +//The image is divided in blocks even on single processor machine, mainly to decrease memory consumption +//maximum number of pixel per block +#define PIXELS_PER_BLOCK 250000 + +/* + * Used to specify a subregion of an image and to specify a cell in this subregion + */ +class Block { + public: + unsigned int posX; + unsigned int posY; + unsigned int width; // If 0, use the full width of the image + unsigned int height; // If 0, use the full height of the image + Block(); + Block(unsigned int x, unsigned int y, unsigned int w, unsigned int h); +}; + +/* + * This class handle the best slicing of the image with a given number of pixels per block and the number of + * processor, and tries to create blocks as square as possible. There can be a different number of block on + * each line, and the pixel per block requested may be oversized by very few percents. + */ +class Slicer { + protected: + bool portrait; // Orientation of the sub-region + unsigned int imWidth; // Image width + unsigned int imHeight; // Image height + Block region; // Sub-region to process + double hBlockNumber; // Horizontal number of block for the sub-region + unsigned int vBlockNumber; // Vertical number of block for the sub-region + double blockWidth; + + public: + unsigned int blockNumber; // number of block for the sub-region + unsigned int maxPixelNumber; // number of pixel of the biggest block (for memory allocation purpose) + Slicer(unsigned int imageWidth, unsigned int imageHeight, Block *subRegion, unsigned int pixels); + void get_block(unsigned int blockId, Block *block); +}; + +#endif diff --git a/rtengine/stdimagesource.cc b/rtengine/stdimagesource.cc new file mode 100755 index 000000000..fe326a8e8 --- /dev/null +++ b/rtengine/stdimagesource.cc @@ -0,0 +1,329 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "stdimagesource.h" +#include "mytime.h" +#include "iccstore.h" +#include "imageio.h" +#include "curves.h" +#include "color.h" + +#undef THREAD_PRIORITY_NORMAL + +namespace rtengine { + +extern const Settings* settings; + +template void freeArray (T** a, int H) { + for (int i=0; i T** allocArray (int W, int H) { + + T** t = new T*[H]; + for (int i=0; igetH()/HR_SCALE; + freeArray(hrmap[0], dh); + freeArray(hrmap[1], dh); + freeArray(hrmap[2], dh); + } + + if (needhr) + freeArray(needhr, img->getH()); + + if (img) delete img; +} + +void StdImageSource::getSampleFormat (Glib::ustring &fname, IIOSampleFormat &sFormat, IIOSampleArrangement &sArrangement) { + + sFormat = IIOSF_UNKNOWN; + sArrangement = IIOSA_UNKNOWN; + + size_t lastdot = fname.find_last_of ('.'); + if( Glib::ustring::npos == lastdot ) { + return; + } + if (!fname.casefold().compare (lastdot, 4, ".jpg") || + !fname.casefold().compare (lastdot, 5, ".jpeg")) + { + // For now, png and jpeg files are converted to unsigned short by the loader itself, + // but there should be functions that read the sample format first, like the TIFF case below + sFormat = IIOSF_UNSIGNED_CHAR; + sArrangement = IIOSA_CHUNKY; + return; + } + else if (!fname.casefold().compare (lastdot, 4, ".png")) { + int result = ImageIO::getPNGSampleFormat (fname, sFormat, sArrangement); + if (result == IMIO_SUCCESS) + return; + } + else if (!fname.casefold().compare (lastdot, 4, ".tif") || + !fname.casefold().compare (lastdot, 5, ".tiff")) + { + int result = ImageIO::getTIFFSampleFormat (fname, sFormat, sArrangement); + if (result == IMIO_SUCCESS) + return; + } + return; +} + +/* + * This method make define the correspondence between the input image type + * and RT's image data type (Image8, Image16 and Imagefloat), then it will + * load the image into it + */ +int StdImageSource::load (Glib::ustring fname, bool batch) { + + fileName = fname; + + // First let's find out the input image's type + + IIOSampleFormat sFormat; + IIOSampleArrangement sArrangement; + getSampleFormat(fname, sFormat, sArrangement); + + // Then create the appropriate object + + switch (sFormat) { + case (IIOSF_UNSIGNED_CHAR): + { + Image8 *img_8 = new Image8 (); + img = img_8; + break; + } + case (IIOSF_UNSIGNED_SHORT): + { + Image16 *img_16 = new Image16 (); + img = img_16; + break; + } + case (IIOSF_LOGLUV24): + case (IIOSF_LOGLUV32): + case (IIOSF_FLOAT): + { + Imagefloat *img_float = new Imagefloat (); + img = img_float; + break; + } + default: + return IMIO_FILETYPENOTSUPPORTED; + } + + img->setSampleFormat(sFormat); + img->setSampleArrangement(sArrangement); + + if (plistener) { + plistener->setProgressStr ("PROGRESSBAR_LOADING"); + plistener->setProgress (0.0); + img->setProgressListener (plistener); + } + + // And load the image! + + int error = img->load (fname); + if (error) { + delete img; + img = NULL; + return error; + } + + embProfile = img->getEmbeddedProfile (); + + idata = new ImageData (fname); + if (idata->hasExif()) { + int deg = 0; + if (idata->getOrientation()=="Rotate 90 CW") { + deg = 90; + } + else if (idata->getOrientation()=="Rotate 180") { + deg = 180; + } + else if (idata->getOrientation()=="Rotate 270 CW") { + deg = 270; + } + if (deg) { + img->rotate(deg); + } + } + + if (plistener) { + plistener->setProgressStr ("PROGRESSBAR_READY"); + plistener->setProgress (1.0); + } + + wb = ColorTemp (1.0,1.0,1.0,1.0); + //this is probably a mistake if embedded profile is not D65 + + return 0; +} + +void StdImageSource::getImage (ColorTemp ctemp, int tran, Imagefloat* image, PreviewProps pp,ToneCurveParams hrp, ColorManagementParams cmp, RAWParams raw) { + + // the code will use OpenMP as of now. + + img->getStdImage(ctemp, tran, image, pp, true, hrp); + + // Hombre: we could have rotated the image here too, with just few line of code, but: + // 1. it would require other modifications in the engine, so "do not touch that little plonker!" + // 2. it's more optimized like this + + // Flip if needed + if (tran & TR_HFLIP) + image->hflip(); + if (tran & TR_VFLIP) + image->vflip(); +} + +void StdImageSource::convertColorSpace(Imagefloat* image, ColorManagementParams cmp, ColorTemp &wb) { + colorSpaceConversion (image, cmp, embProfile, img->getSampleFormat()); +} + +void StdImageSource::colorSpaceConversion (Imagefloat* im, ColorManagementParams cmp, cmsHPROFILE embedded, IIOSampleFormat sampleFormat) { + + bool skipTransform = false; + cmsHPROFILE in = NULL; + cmsHPROFILE out = iccStore->workingSpace (cmp.working); + if (cmp.input=="(embedded)" || cmp.input=="" || cmp.input=="(camera)" || cmp.input=="(cameraICC)") { + if (embedded) + in = embedded; + else { + if (sampleFormat & (IIOSF_LOGLUV24|IIOSF_LOGLUV32|IIOSF_FLOAT)) + skipTransform = true; + else + in = iccStore->getsRGBProfile (); + } + } else { + if (cmp.input!="(none)") { + in = iccStore->getProfile (cmp.input); + if (in==NULL && embedded) + in = embedded; + else if (in==NULL) { + if (sampleFormat & (IIOSF_LOGLUV24|IIOSF_LOGLUV32|IIOSF_FLOAT)) + skipTransform = true; + else + in = iccStore->getsRGBProfile (); + } + } + } + + if (!skipTransform && in) { + if(in == embedded && cmsGetColorSpace(in) != cmsSigRgbData) { // if embedded profile is not an RGB profile, use sRGB + printf("embedded profile is not an RGB profile, using sRGB as input profile\n"); + in = iccStore->getsRGBProfile (); + } + lcmsMutex->lock (); + cmsHTRANSFORM hTransform = cmsCreateTransform (in, TYPE_RGB_FLT, out, TYPE_RGB_FLT, settings->colorimetricIntent, + cmsFLAGS_NOOPTIMIZE | cmsFLAGS_NOCACHE); + lcmsMutex->unlock (); + if(hTransform) { + // Convert to the [0.0 ; 1.0] range + im->normalizeFloatTo1(); + + im->ExecCMSTransform(hTransform); + + // Converting back to the [0.0 ; 65535.0] range + im->normalizeFloatTo65535(); + + cmsDeleteTransform(hTransform); + } else { + printf("Could not convert from %s to %s\n",in == embedded ? "embedded profile" : cmp.input.data(),cmp.working.data()); + } + } +} + +void StdImageSource::getFullSize (int& w, int& h, int tr) { + + w = img->width; + h = img->height; + if ((tr & TR_ROT) == TR_R90 || (tr & TR_ROT) == TR_R270) { + w = img->height; + h = img->width; + } +} + +void StdImageSource::getSize (int tran, PreviewProps pp, int& w, int& h) { + + w = pp.w / pp.skip + (pp.w % pp.skip > 0); + h = pp.h / pp.skip + (pp.h % pp.skip > 0); +} + +void StdImageSource::getAutoExpHistogram (LUTu & histogram, int& histcompr) { + if (img->getType() == sImage8) { + Image8 *img_ = static_cast(img); + img_->computeAutoHistogram(histogram, histcompr); + } + else if (img->getType() == sImage16) { + Image16 *img_ = static_cast(img); + img_->computeAutoHistogram(histogram, histcompr); + } + else if (img->getType() == sImagefloat) { + Imagefloat *img_ = static_cast(img); + img_->computeAutoHistogram(histogram, histcompr); + } +} + +void StdImageSource::getAutoWBMultipliers (double &rm, double &gm, double &bm) { + if (redAWBMul != -1.) { + rm = redAWBMul; + gm = greenAWBMul; + bm = blueAWBMul; + return; + } + + img->getAutoWBMultipliers(rm, gm, bm); + + redAWBMul = rm; + greenAWBMul = gm; + blueAWBMul = bm; +} + +ColorTemp StdImageSource::getSpotWB (std::vector &red, std::vector &green, std::vector& blue, int tran, double equal) { + int rn, gn, bn; + double reds, greens, blues; + img->getSpotWBData(reds, greens, blues, rn, gn, bn, red, green, blue, tran); + double img_r, img_g, img_b; + wb.getMultipliers (img_r, img_g, img_b); + if( settings->verbose ) + printf ("AVG: %g %g %g\n", reds/rn, greens/gn, blues/bn); + + return ColorTemp (reds/rn*img_r, greens/gn*img_g, blues/bn*img_b, equal); +} + +} + diff --git a/rtengine/stdimagesource.h b/rtengine/stdimagesource.h new file mode 100644 index 000000000..d8ab7275d --- /dev/null +++ b/rtengine/stdimagesource.h @@ -0,0 +1,76 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _STDIMAGESOURCE_ +#define _STDIMAGESOURCE_ + +#include "imagesource.h" + +namespace rtengine { + +class StdImageSource : public ImageSource { + + protected: + ImageIO* img; + ColorTemp wb; + ProgressListener* plistener; + bool full; + float** hrmap[3]; + char** needhr; + int max[3]; + bool rgbSourceModified; + + //void transformPixel (int x, int y, int tran, int& tx, int& ty); + void getSampleFormat (Glib::ustring &fname, IIOSampleFormat &sFormat, IIOSampleArrangement &sArrangement); + + public: + StdImageSource (); + ~StdImageSource (); + + int load (Glib::ustring fname, bool batch = false); + void getImage (ColorTemp ctemp, int tran, Imagefloat* image, PreviewProps pp, ToneCurveParams hrp, ColorManagementParams cmp, RAWParams raw); + ColorTemp getWB () { return wb; } + void getAutoWBMultipliers (double &rm, double &gm, double &bm); + ColorTemp getSpotWB (std::vector &red, std::vector &green, std::vector &blue, int tran, double equal); + + bool isWBProviderReady () { return true; }; + + void getAutoExpHistogram (LUTu &histogram, int& histcompr); + + double getDefGain () { return 0.0; } + double getGamma () { return 0.0; } + + void getFullSize (int& w, int& h, int tr = TR_NONE); + void getSize (int tran, PreviewProps pp, int& w, int& h); + + ImageData* getImageData () { return idata; } + ImageIO* getImageIO () { return img; } + ImageMatrices* getImageMatrices () { return (ImageMatrices*)NULL; } + bool isRAW() const { return false; } + + void setProgressListener (ProgressListener* pl) { plistener = pl; } + + void convertColorSpace(Imagefloat* image, ColorManagementParams cmp, ColorTemp &wb);// RAWParams raw will not be used for non-raw files (see imagesource.h) + static void colorSpaceConversion (Imagefloat* im, ColorManagementParams cmp, cmsHPROFILE embedded, IIOSampleFormat sampleFormat); + //static void colorSpaceConversion16 (Image16* im, ColorManagementParams cmp, cmsHPROFILE embedded); + + static inline double intpow (double a, int b) { double r = 1.0; for (int i=0; i + * + * 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 +#include "rt_math.h" + +#include "utils.h" +#include "rt_math.h" + +using namespace std; + +namespace rtengine { + +void bilinearInterp (const unsigned char* src, int sw, int sh, unsigned char* dst, int dw, int dh) { + + int ix = 0; + for (int i=0; i=sh) sy = sh-1; + double dy = (double)i*sh/dh - sy; + int ny = sy+1; + if (ny>=sh) ny = sy; + int or1 = 3*sw*sy; + int or2 = 3*sw*ny; + for (int j=0; j=sw) sx = sw; + double dx = (double)j*sw/dw - sx; + int nx = sx+1; + if (nx>=sw) nx = sx; + int ofs11 = or1 + 3*sx; + int ofs12 = or1 + 3*nx; + int ofs21 = or2 + 3*sx; + int ofs22 = or2 + 3*nx; + unsigned int val = src[ofs11]*(1-dx)*(1-dy) + src[ofs12]*dx*(1-dy) + src[ofs21]*(1-dx)*dy + src[ofs22]*dx*dy; + dst[ix++] = val; + ofs11++; ofs12++; ofs21++; ofs22++; + val = src[ofs11]*(1-dx)*(1-dy) + src[ofs12]*dx*(1-dy) + src[ofs21]*(1-dx)*dy + src[ofs22]*dx*dy; + dst[ix++] = val; + ofs11++; ofs12++; ofs21++; ofs22++; + val = src[ofs11]*(1-dx)*(1-dy) + src[ofs12]*dx*(1-dy) + src[ofs21]*(1-dx)*dy + src[ofs22]*dx*dy; + dst[ix++] = val; + } + } +} + +void nearestInterp (const unsigned char* src, int sw, int sh, unsigned char* dst, int dw, int dh) { + + int ix = 0; + for (int i=0; i + * + * 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 _SIMPLEUTILS_ +#define _SIMPLEUTILS_ + +namespace rtengine { + +void bilinearInterp (const unsigned char* src, int sw, int sh, unsigned char* dst, int dw, int dh); +void nearestInterp (const unsigned char* src, int sw, int sh, unsigned char* dst, int dw, int dh); +void rotate (unsigned char* img, int& w, int& h, int deg); +void hflip (unsigned char* img, int w, int h); +void vflip (unsigned char* img, int w, int h); + +} +#endif diff --git a/rtexif/CMakeLists.txt b/rtexif/CMakeLists.txt new file mode 100644 index 000000000..a2e713ed7 --- /dev/null +++ b/rtexif/CMakeLists.txt @@ -0,0 +1,23 @@ +add_library (rtexif rtexif.cc stdattribs.cc nikonattribs.cc canonattribs.cc pentaxattribs.cc fujiattribs.cc sonyminoltaattribs.cc olympusattribs.cc kodakattribs.cc) +add_dependencies (rtexif AboutFile) + +IF (WIN32) + set_target_properties (rtexif PROPERTIES COMPILE_FLAGS " -ffast-math -fexpensive-optimizations") + 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}) + #set_target_properties (rth PROPERTIES LINK_FLAGS "-mwindows") +ELSE (WIN32) + set_target_properties (rtexif PROPERTIES COMPILE_FLAGS " -ffast-math -fexpensive-optimizations -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}) +ENDIF (WIN32) + +include_directories (BEFORE "${CMAKE_CURRENT_BINARY_DIR}") + +IF (BUILD_SHARED_LIBS) + INSTALL(TARGETS rtexif DESTINATION ${LIBDIR}) +ENDIF (BUILD_SHARED_LIBS) diff --git a/rtexif/canonattribs.cc b/rtexif/canonattribs.cc new file mode 100644 index 000000000..d85b0379e --- /dev/null +++ b/rtexif/canonattribs.cc @@ -0,0 +1,1534 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _CANONATTRIBS_ +#define _CANONATTRIBS_ + +#include +#include + +#include "rtexif.h" + +using namespace std; + +namespace rtexif { + +class CAOnOffInterpreter : public Interpreter { +public: + virtual std::string toString (Tag* t) + { + int n = t->toInt(); + if( n==0 ) return "OFF"; + else if( n == 1) return "ON"; + else return "undef"; + } +}; +CAOnOffInterpreter caOnOffInterpreter; + +class CAIntSerNumInterpreter : public Interpreter { + public: + CAIntSerNumInterpreter () {} + virtual std::string toString (Tag* t) { return ""; } +}; + +CAIntSerNumInterpreter caIntSerNumInterpreter; + +class CAApertureInterpreter : public Interpreter { + public: + CAApertureInterpreter () {} + virtual std::string toString (Tag* t) { + char buffer[32]; + double v = pow(2.0, t->toDouble()/64.0); + if( v<0. || v> 1000.) return "undef"; + sprintf (buffer, "%.1f",v ); + return buffer; + } +}; +CAApertureInterpreter caApertureInterpreter; + +class CAMacroModeInterpreter : public ChoiceInterpreter { +public: + CAMacroModeInterpreter(){ + choices[1] = "Macro"; + choices[2] = "Normal"; + } +}; +CAMacroModeInterpreter caMacroModeInterpreter; + +class CASelfTimerInterpreter : public Interpreter { +public: + virtual std::string toString (Tag* t) { + int sec = t->toInt(0,SHORT); + if( !sec ) return "OFF"; + char buffer[32]; + sprintf (buffer, "%.1fs %s", sec/10., sec&0x4000?",Custom":""); + return buffer; + } +}; +CASelfTimerInterpreter caSelfTimerInterpreter; + +class CAQualityInterpreter : public ChoiceInterpreter { +public: + CAQualityInterpreter(){ + choices[1] = "Economy"; + choices[2] = "Normal"; + choices[3] = "Fine"; + choices[4] = "RAW"; + choices[5] = "Superfine"; + } +}; +CAQualityInterpreter caQualityInterpreter; + +class CAFlashModeInterpreter : public ChoiceInterpreter { +public: + CAFlashModeInterpreter(){ + choices[0] = "Off"; + choices[1] = "Auto"; + choices[2] = "On"; + choices[3] = "Red-eye reduction"; + choices[4] = "Slow-sync"; + choices[5] = "Red-eye reduction (Auto)"; + choices[6] = "Red-eye reduction (On)"; + choices[16]= "External flash"; + } +}; +CAFlashModeInterpreter caFlashModeInterpreter; + +class CAContinuousDriveInterpreter : public ChoiceInterpreter { +public: + CAContinuousDriveInterpreter(){ + choices[0] = "Single"; + choices[1] = "Continuous"; + choices[2] = "Movie"; + choices[3] = "Continuous, Speed Priority"; + choices[4] = "Continuous, Low"; + choices[5] = "Continuous, High"; + } +}; +CAContinuousDriveInterpreter caContinuousDriveInterpreter; + +class CAFocusModeInterpreter : public ChoiceInterpreter { +public: + CAFocusModeInterpreter(){ + choices[0] = "One-shot AF"; + choices[1] = "AI Servo AF"; + choices[2] = "AI Focus AF"; + choices[3] = "Manual Focus"; + choices[4] = "Single"; + choices[5] = "Continuous"; + choices[6] = "Manual Focus"; + choices[16] = "Pan Focus"; + } +}; +CAFocusModeInterpreter caFocusModeInterpreter; + +class CARecordModeInterpreter : public ChoiceInterpreter { +public: + CARecordModeInterpreter(){ + choices[1] = "JPEG"; + choices[2] = "CRW+THM"; + choices[3] = "AVI+THM"; + choices[4] = "TIF"; + choices[5] = "TIF+JPEG"; + choices[6] = "CR2"; + choices[7] = "CR2+JPEG"; + choices[9] = "Video"; + } +}; +CARecordModeInterpreter caRecordModeInterpreter; + +class CAImageSizeInterpreter : public ChoiceInterpreter { +public: + CAImageSizeInterpreter (){ + choices[0] = "Large"; + choices[1] = "Medium"; + choices[2] = "Small"; + choices[5] = "Medium 1"; + choices[6] = "Medium 2"; + choices[7] = "Medium 3"; + choices[8] = "Postcard"; + choices[9] = "Widescreen"; + choices[10] = "Medium Widescreen"; + choices[128] = "640x480 Movie"; + choices[129] = "Medium Movie"; + choices[130] = "Small Movie"; + choices[137] = "1280x720 Movie"; + choices[142] = "1920x1080 Movie"; + } +}; +CAImageSizeInterpreter caImageSizeInterpreter; + +class CAEasyModeInterpreter : public ChoiceInterpreter { +public: + CAEasyModeInterpreter (){ + choices[0] = "Full auto "; + choices[1] = "Manual "; + choices[2] = "Landscape "; + choices[3] = "Fast shutter "; + choices[4] = "Slow shutter "; + choices[5] = "Night "; + choices[6] = "Gray Scale "; + choices[7] = "Sepia "; + choices[8] = "Portrait "; + choices[9] = "Sports "; + choices[10] = "Macro "; + choices[11] = "Black & White"; + choices[12] = "Pan focus"; + choices[13] = "Vivid"; + choices[14] = "Neutral"; + choices[15] = "Flash Off"; + choices[16] = "Long Shutter"; + choices[17] = "Super Macro"; + choices[18] = "Foliage"; + choices[19] = "Indoor"; + choices[20] = "Fireworks"; + choices[21] = "Beach"; + choices[22] = "Underwater"; + choices[23] = "Snow"; + choices[24] = "Kids & Pets"; + choices[25] = "Night Snapshot"; + choices[26] = "Digital Macro"; + choices[27] = "My Colors"; + choices[28] = "Still Image"; + choices[30] = "Color Accent"; + choices[31] = "Color Swap"; + choices[32] = "Aquarium"; + choices[33] = "ISO 3200"; + choices[38] = "Creative Auto"; + choices[42] = "Super Vivid"; + choices[43] = "Poster"; + choices[47] = "Fisheye"; + choices[48] = "Miniature"; + choices[261]= "Sunset"; + } +}; +CAEasyModeInterpreter caEasyModeInterpreter; + +class CADigitalZoomInterpreter : public ChoiceInterpreter { +public: + CADigitalZoomInterpreter(){ + choices[0] = "None"; + choices[1] = "2x"; + choices[2] = "4x"; + choices[3] = "Other"; + } +}; +CADigitalZoomInterpreter caDigitalZoomInterpreter; + +class CAMeteringModeInterpreter : public ChoiceInterpreter { +public: + CAMeteringModeInterpreter(){ + choices[0] = "Default"; + choices[1] = "Spot"; + choices[2] = "Average"; + choices[3] = "Evaluative"; + choices[4] = "Partial"; + choices[5] = "Center-weighted averaging"; + } +}; +CAMeteringModeInterpreter caMeteringModeInterpreter; + +class CAFocusRangeInterpreter : public ChoiceInterpreter { +public: + CAFocusRangeInterpreter(){ + choices[0] = "Manual"; + choices[1] = "Auto"; + choices[2] = "Not Known"; + choices[3] = "Macro"; + choices[4] = "Very Close"; + choices[5] = "Close"; + choices[6] = "Middle Range"; + choices[7] = "Far Range"; + choices[8] = "Pan Focus"; + choices[9] = "Super Macro"; + choices[10] = "Infinity"; + } +}; +CAFocusRangeInterpreter caFocusRangeInterpreter; + +class CAAFPointInterpreter : public ChoiceInterpreter { +public: + CAAFPointInterpreter(){ + choices[0x2005] = "Manual AF point selection "; + choices[0x3000] = "None (MF)"; + choices[0x3001] = "Auto AF point selection "; + choices[0x3002] = "Right "; + choices[0x3003] = "Center "; + choices[0x3004] = "Left "; + choices[0x4001] = "Auto AF point selection "; + choices[0x4006] = "Face Detect"; + } +}; +CAAFPointInterpreter caAFPointInterpreter; + +class CAExposureModeInterpreter : public ChoiceInterpreter { +public: + CAExposureModeInterpreter(){ + choices[0] = "Easy"; + choices[1] = "Program AE"; + choices[2] = "Shutter speed priority AE"; + choices[3] = "Aperture-priority AE"; + choices[4] = "Manual"; + choices[5] = "Depth-of-field AE"; + choices[6] = "M-Dep"; + choices[7] = "Bulb"; + } +}; +CAExposureModeInterpreter caExposureModeInterpreter; + +class CAFlashBitsInterpreter : public Interpreter { +public: + virtual std::string toString (Tag* t) { + std::ostringstream s; + unsigned bits = t->toInt(0,SHORT); + if( bits & 0x0001 ) s << "Manual "; + if( bits & 0x0002 ) s << "TTL "; + if( bits & 0x0004 ) s << "A-TTL "; + if( bits & 0x0008 ) s << "E-TTL "; + if( bits & 0x0010 ) s << "FP sync enabled "; + if( bits & 0x0080 ) s << "2nd curtain "; + if( bits & 0x0800 ) s << "FP sync used "; + if( bits & 0x2000 ) s << "Built-in "; + if( bits & 0x4000 ) s << "External "; + return s.str(); + } +}; +CAFlashBitsInterpreter caFlashBitsInterpreter; + +class CAFocusContinuousInterpreter : public ChoiceInterpreter { +public: + CAFocusContinuousInterpreter(){ + choices[0] = "Single"; + choices[1] = "Continuous"; + choices[8] = "Manual"; + } +}; +CAFocusContinuousInterpreter caFocusContinuousInterpreter; + +class CAAESettingsInterpreter : public ChoiceInterpreter { +public: + CAAESettingsInterpreter(){ + choices[0] = "Normal AE"; + choices[1] = "Exposure Compensation"; + choices[2] = "AE Lock"; + choices[3] = "AE Lock + Exposure Comp."; + choices[4] = "No AE"; + } +}; +CAAESettingsInterpreter caAESettingsInterpreter; + +class CAStabilizationInterpreter : public ChoiceInterpreter { +public: + CAStabilizationInterpreter(){ + choices[0] = "Off"; + choices[1] = "On"; + choices[2] = "On, Shot Only"; + choices[3] = "On, Panning"; + choices[4] = "On, Video"; + } +}; +CAStabilizationInterpreter caStabilizationInterpreter; + +class CASpotMeteringInterpreter : public ChoiceInterpreter { +public: + CASpotMeteringInterpreter(){ + choices[0] = "Center"; + choices[1] = "AF Point"; + } +}; +CASpotMeteringInterpreter caSpotMeteringInterpreter; + +class CAPhotoEffectInterpreter : public ChoiceInterpreter { +public: + CAPhotoEffectInterpreter(){ + choices[0] = "Off"; + choices[1] = "Vivid"; + choices[2] = "Neutral"; + choices[3] = "Smooth"; + choices[4] = "Sepia"; + choices[5] = "B&W"; + choices[6] = "Custom"; + choices[100] = "My Color Data"; + } +}; +CAPhotoEffectInterpreter caPhotoEffectInterpreter; + +class CAManualFlashInterpreter : public ChoiceInterpreter { +public: + CAManualFlashInterpreter(){ + choices[0] = "N/A"; + choices[0x500] = "Full"; + choices[0x502] = "Medium"; + choices[0x504] = "Low"; + choices[0x7fff] = "N/A"; + } +}; +CAManualFlashInterpreter caManualFlashInterpreter; + +class CARAWQualityInterpreter : public ChoiceInterpreter { +public: + CARAWQualityInterpreter(){ + choices[0] = "N/A"; + choices[1] = "sRAW1 (mRAW)"; + choices[2] = "sRAW2 (sRAW)"; + } +}; +CARAWQualityInterpreter caRAWQualityInterpreter; + +class CAFocalInterpreter : public Interpreter { +public: + virtual std::string toString (Tag* t) { + Tag *unitTag = t->getParent()->getRoot()->findTag("FocalUnits"); + double v = unitTag?unitTag->toDouble():1.; + v = (v>0. ? t->toDouble()/v : t->toDouble()); + if( v <0. || v>1000000.) return "undef"; + char buffer[32]; + sprintf (buffer, "%.1f", v ); + return buffer; + } +}; +CAFocalInterpreter caFocalInterpreter; + +class CALensInterpreter : public IntLensInterpreter< int > { + public: + CALensInterpreter () { // From EXIFTOOL database 'Canon.pm' V3.19 + choices.insert(p_t(1, "Canon EF 50mm f/1.8")); + choices.insert(p_t(2, "Canon EF 28mm f/2.8")); + choices.insert(p_t(3, "Canon EF 135mm f/2.8 Soft")); + choices.insert(p_t(4, "Canon EF 35-105mm f/3.5-4.5")); + choices.insert(p_t(4, "Sigma UC Zoom 35-135mm f/4-5.6")); + choices.insert(p_t(5, "Canon EF 35-70mm f/3.5-4.5")); + choices.insert(p_t(6, "Canon EF 28-70mm f/3.5-4.5")); + choices.insert(p_t(6, "Sigma 18-50mm f/3.5-5.6 DC")); + choices.insert(p_t(6, "Sigma 18-125mm f/3.5-5.6 DC IF ASP")); + choices.insert(p_t(6, "Tokina AF 193-2 19-35mm f/3.5-4.5")); + choices.insert(p_t(6, "Sigma 28-80mm f/3.5-5.6 II Macro")); + choices.insert(p_t(7, "Canon EF 100-300mm f/5.6L")); + choices.insert(p_t(8, "Canon EF 100-300mm f/5.6")); + choices.insert(p_t(8, "Sigma 70-300mm f/4-5.6 [APO] DG Macro")); + choices.insert(p_t(8, "Tokina AT-X 242 AF 24-200mm f/3.5-5.6")); + choices.insert(p_t(9, "Canon EF 70-210mm f/4")); + choices.insert(p_t(9, "Sigma 55-200mm f/4-5.6 DC")); + choices.insert(p_t(10, "Canon EF 50mm f/2.5 Macro")); + choices.insert(p_t(10, "Sigma 50mm f/2.8 EX")); + choices.insert(p_t(10, "Sigma 28mm f/1.8")); + choices.insert(p_t(10, "Sigma 105mm f/2.8 Macro EX")); + choices.insert(p_t(10, "Sigma 70mm f/2.8 EX DG Macro EF")); + choices.insert(p_t(11, "Canon EF 35mm f/2")); + choices.insert(p_t(13, "Canon EF 15mm f/2.8 Fisheye")); + choices.insert(p_t(14, "Canon EF 50-200mm f/3.5-4.5L")); + choices.insert(p_t(15, "Canon EF 50-200mm f/3.5-4.5")); + choices.insert(p_t(16, "Canon EF 35-135mm f/3.5-4.5")); + choices.insert(p_t(17, "Canon EF 35-70mm f/3.5-4.5A")); + choices.insert(p_t(18, "Canon EF 28-70mm f/3.5-4.5")); + choices.insert(p_t(20, "Canon EF 100-200mm f/4.5A")); + choices.insert(p_t(21, "Canon EF 80-200mm f/2.8L")); + choices.insert(p_t(22, "Canon EF 20-35mm f/2.8L")); + choices.insert(p_t(22, "Tokina AT-X 280 AF Pro 28-80mm f/2.8 Aspherical")); + choices.insert(p_t(23, "Canon EF 35-105mm f/3.5-4.5")); + choices.insert(p_t(24, "Canon EF 35-80mm f/4-5.6 Power Zoom")); + choices.insert(p_t(25, "Canon EF 35-80mm f/4-5.6 Power Zoom")); + choices.insert(p_t(26, "Canon EF 100mm f/2.8 Macro")); + choices.insert(p_t(26, "Cosina 100mm f/3.5 Macro AF")); + choices.insert(p_t(26, "Tamron SP AF 90mm f/2.8 Di Macro")); + choices.insert(p_t(26, "Tamron SP AF 180mm f/3.5 Di Macro")); + choices.insert(p_t(26, "Carl Zeiss Planar T* 50mm f/1.4")); + choices.insert(p_t(27, "Canon EF 35-80mm f/4-5.6")); + choices.insert(p_t(28, "Canon EF 80-200mm f/4.5-5.6")); + choices.insert(p_t(28, "Tamron SP AF 28-75mm f/2.8 XR Di LD Aspherical IF Macro")); + choices.insert(p_t(28, "Tamron SP AF 28-105mm f/2.8 LD Aspherical IF")); + choices.insert(p_t(28, "Tamron AF 28-200mm f/3.8-5.6 Aspherical")); + choices.insert(p_t(28, "Tamron AF 70-300mm f/4.5-5.6 Di LD 1:2 Macro Zoom")); + choices.insert(p_t(29, "Canon EF 50mm f/1.8 II")); + choices.insert(p_t(30, "Canon EF 35-105mm f/4.5-5.6")); + choices.insert(p_t(31, "Canon EF 75-300mm f/4-5.6")); + choices.insert(p_t(31, "Tamron SP AF 300mm f/2.8 LD IF")); + choices.insert(p_t(32, "Canon EF 24mm f/2.8")); + choices.insert(p_t(32, "Sigma 15mm f/2.8 EX Fisheye")); + choices.insert(p_t(33, "Voigtlander or Carl Zeiss Lens")); + choices.insert(p_t(33, "Voigtlander Ultron 40mm f/2 SLII Aspherical")); + choices.insert(p_t(33, "Carl Zeiss Distagon T* 15mm f/2.8 ZE")); + choices.insert(p_t(33, "Carl Zeiss Distagon T* 18mm f/3.5 ZE")); + choices.insert(p_t(33, "Carl Zeiss Distagon T* 21mm f/2.8 ZE")); + choices.insert(p_t(33, "Carl Zeiss Distagon T* 28mm f/2 ZE")); + choices.insert(p_t(33, "Carl Zeiss Distagon T* 35mm f/2 ZE")); + choices.insert(p_t(35, "Canon EF 35-80mm f/4-5.6")); + choices.insert(p_t(36, "Canon EF 38-76mm f/4.5-5.6")); + choices.insert(p_t(37, "Canon EF 35-80mm f/4-5.6")); + choices.insert(p_t(37, "Tamron 70-200mm f/2.8 Di LD IF Macro")); + choices.insert(p_t(37, "Tamron AF 28-300mm f/3.5-6.3 XR Di VC LD Aspherical IF Macro (A20)")); + choices.insert(p_t(37, "Tamron SP AF 17-50mm f/2.8 XR Di II VC LD Aspherical IF")); + choices.insert(p_t(37, "Tamron AF 18-270mm f/3.5-6.3 Di II VC LD Aspherical IF Macro")); + choices.insert(p_t(38, "Canon EF 80-200mm f/4.5-5.6")); + choices.insert(p_t(39, "Canon EF 75-300mm f/4-5.6")); + choices.insert(p_t(40, "Canon EF 28-80mm f/3.5-5.6")); + choices.insert(p_t(41, "Canon EF 28-90mm f/4-5.6")); + choices.insert(p_t(42, "Canon EF 28-200mm f/3.5-5.6")); + choices.insert(p_t(42, "Tamron AF 28-300mm f/3.5-6.3 XR Di VC LD Aspherical IF Macro (A20)")); + choices.insert(p_t(43, "Canon EF 28-105mm f/4-5.6")); + choices.insert(p_t(44, "Canon EF 90-300mm f/4.5-5.6")); + choices.insert(p_t(45, "Canon EF-S 18-55mm f/3.5-5.6 II")); + choices.insert(p_t(46, "Canon EF 28-90mm f/4-5.6")); + choices.insert(p_t(48, "Canon EF-S 18-55mm f/3.5-5.6 IS")); + choices.insert(p_t(49, "Canon EF-S 55-250mm f/4-5.6 IS")); + choices.insert(p_t(50, "Canon EF-S 18-200mm f/3.5-5.6 IS")); + choices.insert(p_t(51, "Canon EF-S 18-135mm f/3.5-5.6 IS")); + choices.insert(p_t(52, "Canon EF-S 18-55mm f/3.5-5.6 IS II")); + 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(94, "Canon TS-E 17mm f/4L")); + choices.insert(p_t(95, "Canon TS-E 24mm f/3.5 L 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")); + choices.insert(p_t(127, "Canon TS-E 90mm f/2.8")); + choices.insert(p_t(129, "Canon EF 300mm f/2.8L")); + choices.insert(p_t(130, "Canon EF 50mm f/1.0L")); + choices.insert(p_t(131, "Canon EF 28-80mm f/2.8-4L")); + choices.insert(p_t(131, "Sigma 8mm f/3.5 EX DG Circular Fisheye")); + choices.insert(p_t(131, "Sigma 17-35mm f/2.8-4 EX DG Aspherical HSM")); + choices.insert(p_t(131, "Sigma 17-70mm f/2.8-4.5 DC Macro")); + choices.insert(p_t(131, "Sigma APO 50-150mm f/2.8 EX DC HSM II")); + choices.insert(p_t(131, "Sigma APO 120-300mm f/2.8 EX DG HSM")); + choices.insert(p_t(131, "Sigma 4.5mm f/2.8 EX DC HSM Circular Fisheye")); + choices.insert(p_t(131, "Sigma 70-200mm f/2.8 APO EX HSM")); + choices.insert(p_t(132, "Canon EF 1200mm f/5.6L")); + choices.insert(p_t(134, "Canon EF 600mm f/4L IS")); + choices.insert(p_t(135, "Canon EF 200mm f/1.8L")); + choices.insert(p_t(136, "Canon EF 300mm f/2.8L")); + choices.insert(p_t(137, "Canon EF 85mm f/1.2L")); + choices.insert(p_t(137, "Sigma 18-50mm f/2.8-4.5 DC OS HSM")); + choices.insert(p_t(137, "Sigma 50-200mm f/4-5.6 DC OS HSM")); + choices.insert(p_t(137, "Sigma 18-250mm f/3.5-6.3 DC OS HSM")); + choices.insert(p_t(137, "Sigma 24-70mm f/2.8 IF EX DG HSM")); + choices.insert(p_t(137, "Sigma 18-125mm f/3.8-5.6 DC OS HSM")); + choices.insert(p_t(137, "Sigma 17-70mm f/2.8-4 DC Macro OS HSM")); + choices.insert(p_t(137, "Sigma 17-50mm f/2.8 OS HSM")); + choices.insert(p_t(137, "Sigma 18-200mm f/3.5-6.3 II DC OS HSM")); + choices.insert(p_t(137, "Tamron AF 18-270mm f/3.5-6.3 Di II VC PZD")); + choices.insert(p_t(137, "Sigma 8-16mm f/4.5-5.6 DC HSM")); + choices.insert(p_t(137, "Tamron SP 17-50mm f/2.8 XR Di II VC")); + choices.insert(p_t(137, "Tamron SP 60mm f/2 Macro Di II")); + choices.insert(p_t(137, "Sigma 10-20mm f/3.5 EX DC HSM")); + choices.insert(p_t(137, "Tamron SP 24-70mm f/2.8 Di VC USD")); + choices.insert(p_t(138, "Canon EF 28-80mm f/2.8-4L")); + choices.insert(p_t(139, "Canon EF 400mm f/2.8L")); + choices.insert(p_t(140, "Canon EF 500mm f/4.5L")); + choices.insert(p_t(141, "Canon EF 500mm f/4.5L")); + choices.insert(p_t(142, "Canon EF 300mm f/2.8L IS")); + choices.insert(p_t(143, "Canon EF 500mm f/4L IS")); + choices.insert(p_t(144, "Canon EF 35-135mm f/4-5.6 USM")); + choices.insert(p_t(145, "Canon EF 100-300mm f/4.5-5.6 USM")); + choices.insert(p_t(146, "Canon EF 70-210mm f/3.5-4.5 USM")); + choices.insert(p_t(147, "Canon EF 35-135mm f/4-5.6 USM")); + choices.insert(p_t(148, "Canon EF 28-80mm f/3.5-5.6 USM")); + choices.insert(p_t(149, "Canon EF 100mm f/2 USM")); + choices.insert(p_t(150, "Canon EF 14mm f/2.8L")); + choices.insert(p_t(150, "Sigma 20mm f/1.8 EX")); + choices.insert(p_t(150, "Sigma 24mm f/1.8 DG Macro EX")); + choices.insert(p_t(150, "Sigma 30mm f/1.4 DC HSM")); + choices.insert(p_t(151, "Canon EF 200mm f/2.8L")); + choices.insert(p_t(152, "Canon EF 300mm f/4L IS")); + choices.insert(p_t(152, "Sigma 12-24mm f/4.5-5.6 EX DG Aspherical HSM")); + choices.insert(p_t(152, "Sigma 14mm f/2.8 EX Aspherical HSM")); + choices.insert(p_t(152, "Sigma 10-20mm f/4-5.6")); + choices.insert(p_t(152, "Sigma 100-300mm f/4")); + choices.insert(p_t(153, "Canon EF 35-350mm f/3.5-5.6L")); + choices.insert(p_t(153, "Sigma 50-500mm f/4-6.3 APO HSM EX")); + choices.insert(p_t(153, "Tamron AF 28-300mm f/3.5-6.3 XR LD Aspherical IF Macro")); + choices.insert(p_t(153, "Tamron AF 18-200mm f/3.5-6.3 XR Di II LD Aspherical IF Macro (A14)")); + choices.insert(p_t(153, "Tamron 18-250mm f/3.5-6.3 Di II LD Aspherical IF Macro")); + choices.insert(p_t(154, "Canon EF 20mm f/2.8 USM")); + choices.insert(p_t(155, "Canon EF 85mm f/1.8 USM")); + choices.insert(p_t(156, "Canon EF 28-105mm f/3.5-4.5 USM")); + choices.insert(p_t(156, "Tamron SP 70-300mm f/4-5.6 Di VC USD")); + choices.insert(p_t(160, "Canon EF 20-35mm f/3.5-4.5 USM")); + choices.insert(p_t(160, "Tamron AF 19-35mm f/3.5-4.5")); + choices.insert(p_t(160, "Tokina AT-X 124 AF Pro DX 12-24mm f/4")); + choices.insert(p_t(160, "Tokina AT-X 107 AF DX 10-17mm f/3.5-4.5 Fisheye")); + choices.insert(p_t(160, "Tokina AT-X 116 AF Pro DX 11-16mm f/2.8")); + choices.insert(p_t(161, "Canon EF 28-70mm f/2.8L")); + choices.insert(p_t(161, "Sigma 24-70mm f/2.8 EX")); + choices.insert(p_t(161, "Sigma 28-70mm f/2.8 EX")); + choices.insert(p_t(161, "Tamron AF 17-50mm f/2.8 Di-II LD Aspherical")); + choices.insert(p_t(161, "Tamron 90mm f/2.8")); + choices.insert(p_t(161, "Sigma 24-60mm f/2.8 EX DG")); + choices.insert(p_t(162, "Canon EF 200mm f/2.8L")); + choices.insert(p_t(163, "Canon EF 300mm f/4L")); + choices.insert(p_t(164, "Canon EF 400mm f/5.6L")); + choices.insert(p_t(165, "Canon EF 70-200mm f/2.8 L")); + choices.insert(p_t(166, "Canon EF 70-200mm f/2.8 L + x1.4")); + choices.insert(p_t(167, "Canon EF 70-200mm f/2.8 L + x2")); + choices.insert(p_t(168, "Canon EF 28mm f/1.8 USM")); + choices.insert(p_t(169, "Canon EF 17-35mm f/2.8L")); + choices.insert(p_t(169, "Sigma 18-200mm f/3.5-6.3 DC OS")); + choices.insert(p_t(169, "Sigma 15-30mm f/3.5-4.5 EX DG Aspherical")); + choices.insert(p_t(169, "Sigma 18-50mm f/2.8 Macro")); + choices.insert(p_t(169, "Sigma 30mm f/1.4 EX DC HSM")); + choices.insert(p_t(169, "Sigma 50mm f/1.4 EX DG HSM")); + choices.insert(p_t(169, "Sigma 85mm f/1.4 EX DG HSM")); + choices.insert(p_t(169, "Sigma 35mm f/1.4 DG HSM")); + choices.insert(p_t(170, "Canon EF 200mm f/2.8L II")); + choices.insert(p_t(171, "Canon EF 300mm f/4L")); + choices.insert(p_t(172, "Canon EF 400mm f/5.6L")); + choices.insert(p_t(173, "Canon EF 180mm f/3.5L Macro")); + choices.insert(p_t(173, "Sigma 180mm f/3.5 EX HSM Macro")); + choices.insert(p_t(173, "Sigma APO 150mm f/2.8 EX DG HSM Macro")); + choices.insert(p_t(174, "Canon EF 135mm f/2L")); + choices.insert(p_t(174, "Sigma 70-200mm f/2.8 EX DG APO OS HSM")); + choices.insert(p_t(174, "Sigma 50-500mm f/4.5-6.3 APO DG OS HSM")); + choices.insert(p_t(175, "Canon EF 400mm f/2.8L")); + choices.insert(p_t(176, "Canon EF 24-85mm f/3.5-4.5 USM")); + choices.insert(p_t(177, "Canon EF 300mm f/4L IS")); + choices.insert(p_t(178, "Canon EF 28-135mm f/3.5-5.6 IS")); + choices.insert(p_t(179, "Canon EF 24mm f/1.4L")); + choices.insert(p_t(180, "Canon EF 35mm f/1.4L")); + choices.insert(p_t(181, "Canon EF 100-400mm f/4.5-5.6L IS + x1.4")); + choices.insert(p_t(182, "Canon EF 100-400mm f/4.5-5.6L IS + x2")); + choices.insert(p_t(183, "Canon EF 100-400mm f/4.5-5.6L IS")); + choices.insert(p_t(183, "Sigma 150mm f/2.8 EX DG OS HSM APO Macro")); + choices.insert(p_t(183, "Sigma 105mm f/2.8 EX DG OS HSM Macro")); + choices.insert(p_t(184, "Canon EF 400mm f/2.8L + x2")); + choices.insert(p_t(185, "Canon EF 600mm f/4L IS")); + choices.insert(p_t(186, "Canon EF 70-200mm f/4L")); + choices.insert(p_t(187, "Canon EF 70-200mm f/4L + 1.4x")); + choices.insert(p_t(188, "Canon EF 70-200mm f/4L + 2x")); + choices.insert(p_t(189, "Canon EF 70-200mm f/4L + 2.8x")); + choices.insert(p_t(190, "Canon EF 100mm f/2.8 Macro")); + choices.insert(p_t(191, "Canon EF 400mm f/4 DO IS")); + choices.insert(p_t(193, "Canon EF 35-80mm f/4-5.6 USM")); + 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(198, "Canon EF 50mm f/1.4 USM")); + choices.insert(p_t(199, "Canon EF 28-80mm f/3.5-5.6 USM")); + choices.insert(p_t(200, "Canon EF 75-300mm f/4-5.6 USM")); + choices.insert(p_t(201, "Canon EF 28-80mm f/3.5-5.6 USM")); + choices.insert(p_t(202, "Canon EF 28-80mm f/3.5-5.6 USM IV")); + choices.insert(p_t(208, "Canon EF 22-55mm f/4-5.6 USM")); + choices.insert(p_t(209, "Canon EF 55-200mm f/4.5-5.6")); + choices.insert(p_t(210, "Canon EF 28-90mm f/4-5.6 USM")); + choices.insert(p_t(211, "Canon EF 28-200mm f/3.5-5.6 USM")); + choices.insert(p_t(212, "Canon EF 28-105mm f/4-5.6 USM")); + choices.insert(p_t(213, "Canon EF 90-300mm f/4.5-5.6 USM")); + choices.insert(p_t(214, "Canon EF-S 18-55mm f/3.5-5.6 USM")); + choices.insert(p_t(215, "Canon EF 55-200mm f/4.5-5.6 II USM")); + choices.insert(p_t(224, "Canon EF 70-200mm f/2.8L IS")); + choices.insert(p_t(225, "Canon EF 70-200mm f/2.8L IS + x1.4")); + choices.insert(p_t(226, "Canon EF 70-200mm f/2.8L IS + x2")); + choices.insert(p_t(227, "Canon EF 70-200mm f/2.8L IS + x2.8")); + choices.insert(p_t(228, "Canon EF 28-105mm f/3.5-4.5 USM")); + choices.insert(p_t(229, "Canon EF 16-35mm f/2.8L")); + choices.insert(p_t(230, "Canon EF 24-70mm f/2.8L")); + choices.insert(p_t(231, "Canon EF 17-40mm f/4L")); + choices.insert(p_t(232, "Canon EF 70-300mm f/4.5-5.6 DO IS USM")); + choices.insert(p_t(233, "Canon EF 28-300mm f/3.5-5.6L IS")); + choices.insert(p_t(234, "Canon EF-S 17-85mm f4-5.6 IS USM")); + choices.insert(p_t(235, "Canon EF-S 10-22mm f/3.5-4.5 USM")); + choices.insert(p_t(236, "Canon EF-S 60mm f/2.8 Macro USM")); + choices.insert(p_t(237, "Canon EF 24-105mm f/4L IS")); + choices.insert(p_t(238, "Canon EF 70-300mm f/4-5.6 IS USM")); + choices.insert(p_t(239, "Canon EF 85mm f/1.2L II")); + choices.insert(p_t(240, "Canon EF-S 17-55mm f/2.8 IS USM")); + choices.insert(p_t(241, "Canon EF 50mm f/1.2L")); + choices.insert(p_t(242, "Canon EF 70-200mm f/4L IS")); + choices.insert(p_t(243, "Canon EF 70-200mm f/4L IS + 1.4x")); + choices.insert(p_t(244, "Canon EF 70-200mm f/4L IS + 2x")); + choices.insert(p_t(245, "Canon EF 70-200mm f/4L IS + 2.8x")); + choices.insert(p_t(246, "Canon EF 16-35mm f/2.8L II")); + choices.insert(p_t(247, "Canon EF 14mm f/2.8L II USM")); + choices.insert(p_t(248, "Canon EF 200mm f/2L IS")); + choices.insert(p_t(249, "Canon EF 800mm f/5.6L IS")); + choices.insert(p_t(250, "Canon EF 24mm f/1.4L II")); + choices.insert(p_t(251, "Canon EF 70-200mm f/2.8L IS II USM")); + choices.insert(p_t(252, "Canon EF 70-200mm f/2.8L IS II USM + x1.4")); + choices.insert(p_t(253, "Canon EF 70-200mm f/2.8L IS II USM + x2")); + choices.insert(p_t(254, "Canon EF 100mm f/2.8L Macro IS USM")); + choices.insert(p_t(488, "Canon EF-S 15-85mm f/3.5-5.6 IS USM")); + choices.insert(p_t(489, "Canon EF 70-300mm f/4-5.6L IS USM")); + choices.insert(p_t(490, "Canon EF 8-15mm f/4L USM")); + choices.insert(p_t(491, "Canon EF 300mm f/2.8L IS II USM")); + choices.insert(p_t(492, "Canon EF 400mm f/2.8L IS II 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(496, "Canon EF 200-400mm f/4L IS USM")); + choices.insert(p_t(502, "Canon EF 28mm f/2.8 IS USM")); + choices.insert(p_t(503, "Canon EF 24mm f/2.8 IS USM")); + choices.insert(p_t(504, "Canon EF 24-70mm f/4L IS USM")); + choices.insert(p_t(505, "Canon EF 35mm f/2 IS USM")); + choices.insert(p_t(4142, "Canon EF-S 18-135mm f/3.5-5.6 IS STM")); + choices.insert(p_t(4143, "Canon EF-M 18-55mm f/3.5-5.6 IS STM")); + choices.insert(p_t(4144, "Canon EF 40mm f/2.8 STM")); + choices.insert(p_t(4145, "Canon EF-M 22mm f/2 STM")); + choices.insert(p_t(4146, "Canon EF-S 18-55mm f/3.5-5.6 IS STM")); + choices.insert(p_t(4147, "Canon EF-M 11-22mm f/4-5.6 IS STM")); + } + + virtual std::string toString (Tag* t) + { + int lensID = t->toInt(); + + it_t r; + size_t nFound = choices.count( lensID ); + if(1 == nFound) { + r = choices.find ( lensID ); + return r->second; + } + + Tag *apertureTag = t->getParent()->getRoot()->findTag("MaxAperture"); + Tag *focalLengthTag = t->getParent()->getRoot()->findTag("FocalLength"); + Tag *focalLengthMaxTag = t->getParent()->getRoot()->findTag("LongFocal"); + Tag *focalLengthMinTag = t->getParent()->getRoot()->findTag("ShortFocal"); + Tag *unitTag = t->getParent()->getRoot()->findTag("FocalUnits"); + double maxApertureAtFocal = 0.; + double focalLength = 0.; + double focalLengthMin = 0.; + double focalLengthMax = 0.; + if( apertureTag ) + maxApertureAtFocal = pow(2.0, apertureTag->toDouble()/64.0); + if( unitTag ){ + double unit = unitTag->toDouble(); + if( unit==0. ) + unit=1; + if( focalLengthTag ) + focalLength = focalLengthTag->toDouble(); + if( focalLengthMinTag ) + focalLengthMin = focalLengthMinTag->toDouble()/unit; + if( focalLengthMaxTag ) + focalLengthMax = focalLengthMaxTag->toDouble()/unit; + } + + std::ostringstream s; + s << "Unknown "; + if (focalLengthMin > 0.) + s << focalLengthMin; + if (focalLengthMax > 0. && focalLengthMax != focalLengthMin) + s << "-" << focalLengthMax; + if (focalLengthMin > 0.) + s << "mm"; + + s << " (" << lensID << ")"; + if (0 == nFound) { + return s.str(); + } + double deltaMin = 1000.; + + std::string bestMatch(s.str()); + std::ostringstream candidates; + for (r = choices.lower_bound(lensID); r != choices.upper_bound(lensID); r++) { + double a1,a2,f1,f2,lensAperture,dif; + + if( !extractLensInfo( r->second ,f1,f2,a1,a2) ) + continue; + if( f1 == 0. || a1 == 0.) + continue; + + if( focalLength < f1 - .5 || focalLength > f2 + 0.5 ) + continue; + if( focalLengthMin>0. && fabs(f1-focalLengthMin) > 0.5 ) + continue; + if( focalLengthMax>0. && fabs(f2-focalLengthMax) > 0.5 ) + continue; + if( maxApertureAtFocal > 0.1){ + if( maxApertureAtFocal < a1 - 0.15 || maxApertureAtFocal > a2 +0.15) + continue; + + if( a1 == a2 || f1 == f2) + lensAperture = a1; + else + lensAperture = exp( log(a1)+(log(a2)-log(a1))/(log(f2)-log(f1))*(log(focalLength)-log(f1)) ); + + dif = abs(lensAperture - maxApertureAtFocal); + } else + dif = 0; + + if( dif < deltaMin ){ + deltaMin = dif; + bestMatch = r->second; + } + if( dif < 0.15){ + if( candidates.tellp() ) + candidates << "\n or " << r->second; + else + candidates << r->second; + } + + } + if( !candidates.tellp() ) + return bestMatch; + else + return candidates.str(); + } +}; +CALensInterpreter caLensInterpreter; + +class CAFocalTypeInterpreter : public ChoiceInterpreter { +public: + CAFocalTypeInterpreter(){ + choices[0] = "undef"; + choices[1] = "Fixed"; + choices[2] = "Zoom"; + } +}; +CAFocalTypeInterpreter caFocalTypeInterpreter; + +class CAFocalPlaneInterpreter : public Interpreter { +public: + virtual std::string toString (Tag* t) { + int val = t->toInt(); + if( val <40 ) return "undef"; + char buffer[1024]; + sprintf (buffer, "%.2fmm", val *25.4 / 1000); + return buffer; + } +}; +CAFocalPlaneInterpreter caFocalPlaneInterpreter; + +class CAExposureTimeInterpreter : public Interpreter { +public: + virtual std::string toString (Tag* t) { + char buffer[1024]; + double d = pow (2, - t->toInt()/32.0); + sprintf (buffer, "%.3f", d); + return buffer; + } +}; +CAExposureTimeInterpreter caExposureTimeInterpreter; + +class CAEVInterpreter : public Interpreter { + virtual std::string toString (Tag* t) { + char buffer[1024]; + sprintf (buffer, "%.1f", t->toDouble()/32.0 ); + return buffer; + } +}; +CAEVInterpreter caEVInterpreter; + +class CABaseISOInterpreter : public Interpreter { +public: + virtual std::string toString (Tag* t) { + char buffer[32]; + int a = t->toInt(); + sprintf (buffer, "%d", a); + return buffer; + } + virtual double toDouble (Tag* t, int ofs){ + int a = Interpreter::toInt(t, ofs); + if(a>1) { + double i = pow(2., double(a)/32. - 4.) * 50.; + return i; + } + else + return 0.; + } + virtual int toInt (Tag* t, int ofs, TagType astype){ + int a = Interpreter::toInt(t, ofs, astype); + if(a>1) { + int i = int(double(powf(2.f, float(a)/32.f - 4.f)) * 50.f +0.5f); + return i; + } + else + return 0; + } +}; +CABaseISOInterpreter caBaseISOInterpreter; + +class CAToneCurveInterpreter : public ChoiceInterpreter { +public: + CAToneCurveInterpreter(){ + choices[0] = "Standard"; + choices[1] = "Manual"; + choices[2] = "Custom"; + } +}; +CAToneCurveInterpreter caToneCurveInterpreter; + +class CASharpnessFrequencyInterpreter : public ChoiceInterpreter { +public: + CASharpnessFrequencyInterpreter(){ + choices[0] = "N/A"; + choices[1] = "Lowest"; + choices[2] = "Low"; + choices[3] = "Standard"; + choices[4] = "High"; + choices[5] = "Highest"; + } +}; +CASharpnessFrequencyInterpreter caSharpnessFrequencyInterpreter; + +class CAWhiteBalanceInterpreter : public ChoiceInterpreter { +public: + CAWhiteBalanceInterpreter(){ + choices[0] = "Auto"; + choices[1] = "Daylight"; + choices[2] = "Cloudy"; + choices[3] = "Tungsten"; + choices[4] = "Fluorescent"; + choices[5] = "Flash"; + choices[6] = "Custom"; + choices[7] = "Black & White"; + choices[8] = "Shade"; + choices[9] = "Manual Temperature (Kelvin)"; + choices[10] = "PC Set1"; + choices[11] = "PC Set2"; + choices[12] = "PC Set3"; + choices[14] = "Daylight Fluorescent"; + choices[15] = "Custom 1"; + choices[16] = "Custom 2"; + choices[17] = "Underwater"; + } +}; +CAWhiteBalanceInterpreter caWhiteBalanceInterpreter; + +class CAPictureStyleInterpreter : public ChoiceInterpreter { +public: + CAPictureStyleInterpreter(){ + choices[0] = "None"; + choices[1] = "Standard "; + choices[2] = "Set 1"; + choices[3] = "Set 2"; + choices[4] = "Set 3"; + choices[0x21] = "User Def. 1"; + choices[0x22] = "User Def. 2"; + choices[0x23] = "User Def. 3"; + choices[0x41] = "External 1"; + choices[0x42] = "External 2"; + choices[0x43] = "External 3"; + choices[0x81] = "Standard"; + choices[0x82] = "Portrait"; + choices[0x83] = "Landscape"; + choices[0x84] = "Neutral"; + choices[0x85] = "Faithful"; + choices[0x86] = "Monochrome"; + } +}; +CAPictureStyleInterpreter caPictureStyleInterpreter; + +class CASlowShutterInterpreter : public ChoiceInterpreter { +public: + CASlowShutterInterpreter(){ + choices[0] = "Off"; + choices[1] = "Night Scene"; + choices[2] = "On"; + choices[3] = "None"; + } +}; +CASlowShutterInterpreter caSlowShutterInterpreter; + +class CAFlashGuideNumberInterpreter : public Interpreter{ +public: + virtual std::string toString (Tag* t) { + int n= t->toInt(); + if( n==-1) return "undef"; + char buffer[32]; + sprintf (buffer, "%.0f", n/32. ); + return buffer; + } +}; +CAFlashGuideNumberInterpreter caFlashGuideNumberInterpreter; + +class CAAFPointsInFocusInterpreter : public ChoiceInterpreter { +public: + CAAFPointsInFocusInterpreter(){ + choices[0x3000] = "None (MF)"; + choices[0x3001] = "Right"; + choices[0x3002] = "Center"; + choices[0x3003] = "Center+Right"; + choices[0x3004] = "Left"; + choices[0x3005] = "Left+Right"; + choices[0x3006] = "Left+Center"; + choices[0x3007] = "All"; + } +}; +CAAFPointsInFocusInterpreter caAFPointsInFocusInterpreter; + +class CAAutoExposureBracketingInterpreter : public ChoiceInterpreter { +public: + CAAutoExposureBracketingInterpreter(){ + choices[-1] = "On "; + choices[0] = "Off "; + choices[1] = "On (shot 1)"; + choices[2] = "On (shot 2)"; + choices[3] = "On (shot 3)"; + } +}; +CAAutoExposureBracketingInterpreter caAutoExposureBracketingInterpreter; + +class CAControModeInterpreter : public ChoiceInterpreter { +public: + CAControModeInterpreter(){ + choices[0] = "n/a"; + choices[1] = "Camera Local Control"; + choices[3] = "Computer Remote Control"; + } +}; +CAControModeInterpreter caControModeInterpreter; + +class CAFocusDistanceInterpreter : public Interpreter { +public: + virtual std::string toString (Tag* t) { + char buffer[1024]; + sprintf (buffer, "%.2f", t->toDouble()/100 ); + return buffer; + } +}; +CAFocusDistanceInterpreter caFocusDistanceInterpreter; + +class CAMeasuredEVInterpreter : public Interpreter { +public: + virtual std::string toString (Tag* t) { + char buffer[1024]; + sprintf (buffer, "%.1f", t->toDouble()/8 - 6 ); + return buffer; + } +}; +CAMeasuredEVInterpreter caMeasuredEVInterpreter; + +class CACameraTypeInterpreter : public ChoiceInterpreter { +public: + CACameraTypeInterpreter(){ + choices[248] = "EOS High-end"; + choices[250] = "Compact"; + choices[252] = "EOS Mid-end"; + choices[255] = "DV Camera"; + } +}; +CACameraTypeInterpreter caCameraTypeInterpreter; + +class CAAutoRotateInterpreter : public ChoiceInterpreter { +public: + CAAutoRotateInterpreter(){ + choices[-1] = "Rotated by Software"; + choices[0] = "None"; + choices[1] = "Rotate 90 CW"; + choices[2] = "Rotate 180"; + choices[3] = "Rotate 270 CW"; + } +}; +CAAutoRotateInterpreter caAutoRotateInterpreter; + +class CABracketModeInterpreter : public ChoiceInterpreter { +public: + CABracketModeInterpreter(){ + choices[0] = "Off"; + choices[1] = "AEB"; + choices[2] = "FEB"; + choices[3] = "ISO"; + choices[4] = "WB"; + } +}; +CABracketModeInterpreter caBracketModeInterpreter; + +class CARAWJpegQualityInterpreter : public ChoiceInterpreter { +public: + CARAWJpegQualityInterpreter(){ + choices[1] = "Economy"; + choices[2] = "Normal"; + choices[3] = "Fine"; + choices[4] = "RAW"; + choices[5] = "Superfine"; + } +}; +CARAWJpegQualityInterpreter caRAWJpegQualityInterpreter; + +class CAJpegSizeInterpreter : public ChoiceInterpreter { +public: + CAJpegSizeInterpreter(){ + choices[0] = "Large"; + choices[1] = "Medium"; + choices[2] = "Small"; + choices[5] = "Medium 1"; + choices[6] = "Medium 2"; + choices[7] = "Medium 3"; + choices[8] = "Postcard"; + choices[9] = "Widescreen"; + } +}; +CAJpegSizeInterpreter caJpegSizeInterpreter; + +class CAWBBracketModeInterpreter : public ChoiceInterpreter { +public: + CAWBBracketModeInterpreter(){ + choices[0] = "Off"; + choices[1] = "Shift AB"; + choices[2] = "shift GM"; + } +}; +CAWBBracketModeInterpreter caWBBracketModeInterpreter; + +class CAFilterEffectInterpreter : public ChoiceInterpreter { +public: + CAFilterEffectInterpreter(){ + choices[0] = "None"; + choices[1] = "Yellow"; + choices[2] = "Orange"; + choices[3] = "Red"; + choices[4] = "Green"; + } +}; +CAFilterEffectInterpreter caFilterEffectInterpreter; + +class CAToningEffectInterpreter : public ChoiceInterpreter { +public: + CAToningEffectInterpreter(){ + choices[0] = "None"; + choices[1] = "Sepia"; + choices[2] = "Blue"; + choices[3] = "Purple"; + choices[4] = "Green"; + } +}; +CAToningEffectInterpreter caToningEffectInterpreter; + +class CAFileNumberInterpreter : public Interpreter { +public: + virtual std::string toString (Tag* t) { + unsigned long val = t->toInt(0,LONG); + char buffer[32]; + sprintf (buffer, "%ld", ((val&0xffc0)>>6)*10000+((val>>16)&0xff)+((val&0x3f)<<8) ); + return buffer; + } +}; +CAFileNumberInterpreter caFileNumberInterpreter; + +class CAModelIDInterpreter : public ChoiceInterpreter { + public: + CAModelIDInterpreter () { + choices[0x1010000] = "PowerShot A30"; + choices[0x1040000] = "PowerShot S300 / Digital IXUS 300 / IXY Digital 300"; + choices[0x1060000] = "PowerShot A20"; + choices[0x1080000] = "PowerShot A10"; + choices[0x1090000] = "PowerShot S110 / Digital IXUS v / IXY Digital 200"; + choices[0x1100000] = "PowerShot G2"; + choices[0x1110000] = "PowerShot S40"; + choices[0x1120000] = "PowerShot S30"; + choices[0x1130000] = "PowerShot A40"; + choices[0x1140000] = "EOS D30"; + choices[0x1150000] = "PowerShot A100"; + choices[0x1160000] = "PowerShot S200 / Digital IXUS v2 / IXY Digital 200a"; + choices[0x1170000] = "PowerShot A200"; + choices[0x1180000] = "PowerShot S330 / Digital IXUS 330 / IXY Digital 300a"; + choices[0x1190000] = "PowerShot G3"; + choices[0x1210000] = "PowerShot S45"; + choices[0x1230000] = "PowerShot SD100 / Digital IXUS II / IXY Digital 30"; + choices[0x1240000] = "PowerShot S230 / Digital IXUS v3 / IXY Digital 320"; + choices[0x1250000] = "PowerShot A70"; + choices[0x1260000] = "PowerShot A60"; + choices[0x1270000] = "PowerShot S400 / Digital IXUS 400 / IXY Digital 400"; + choices[0x1290000] = "PowerShot G5"; + choices[0x1300000] = "PowerShot A300"; + choices[0x1310000] = "PowerShot S50"; + choices[0x1340000] = "PowerShot A80"; + choices[0x1350000] = "PowerShot SD10 / Digital IXUS i / IXY Digital L"; + choices[0x1360000] = "PowerShot S1 IS"; + choices[0x1370000] = "PowerShot Pro1"; + choices[0x1380000] = "PowerShot S70"; + choices[0x1390000] = "PowerShot S60"; + choices[0x1400000] = "PowerShot G6"; + choices[0x1410000] = "PowerShot S500 / Digital IXUS 500 / IXY Digital 500"; + choices[0x1420000] = "PowerShot A75"; + choices[0x1440000] = "PowerShot SD110 / Digital IXUS IIs / IXY Digital 30a"; + choices[0x1450000] = "PowerShot A400"; + choices[0x1470000] = "PowerShot A310"; + choices[0x1490000] = "PowerShot A85"; + choices[0x1520000] = "PowerShot S410 / Digital IXUS 430 / IXY Digital 450"; + choices[0x1530000] = "PowerShot A95"; + choices[0x1540000] = "PowerShot SD300 / Digital IXUS 40 / IXY Digital 50"; + choices[0x1550000] = "PowerShot SD200 / Digital IXUS 30 / IXY Digital 40"; + choices[0x1560000] = "PowerShot A520"; + choices[0x1570000] = "PowerShot A510"; + choices[0x1590000] = "PowerShot SD20 / Digital IXUS i5 / IXY Digital L2"; + choices[0x1640000] = "PowerShot S2 IS"; + choices[0x1650000] = "PowerShot SD430 / IXUS Wireless / IXY Wireless"; + choices[0x1660000] = "PowerShot SD500 / Digital IXUS 700 / IXY Digital 600"; + choices[0x1668000] = "EOS D60"; + choices[0x1700000] = "PowerShot SD30 / Digital IXUS i zoom / IXY Digital L3"; + choices[0x1740000] = "PowerShot A430"; + choices[0x1750000] = "PowerShot A410"; + choices[0x1760000] = "PowerShot S80"; + choices[0x1780000] = "PowerShot A620"; + choices[0x1790000] = "PowerShot A610"; + choices[0x1800000] = "PowerShot SD630 / Digital IXUS 65 / IXY Digital 80"; + choices[0x1810000] = "PowerShot SD450 / Digital IXUS 55 / IXY Digital 60"; + choices[0x1820000] = "PowerShot TX1"; + choices[0x1870000] = "PowerShot SD400 / Digital IXUS 50 / IXY Digital 55"; + choices[0x1880000] = "PowerShot A420"; + choices[0x1890000] = "PowerShot SD900 / Digital IXUS 900 Ti / IXY Digital 1000"; + choices[0x1900000] = "PowerShot SD550 / Digital IXUS 750 / IXY Digital 700"; + choices[0x1920000] = "PowerShot A700"; + choices[0x1940000] = "PowerShot SD700 IS / Digital IXUS 800 IS / IXY Digital 800 IS"; + choices[0x1950000] = "PowerShot S3 IS"; + choices[0x1960000] = "PowerShot A540"; + choices[0x1970000] = "PowerShot SD600 / Digital IXUS 60 / IXY Digital 70"; + choices[0x1980000] = "PowerShot G7"; + choices[0x1990000] = "PowerShot A530"; + choices[0x2000000] = "PowerShot SD800 IS / Digital IXUS 850 IS / IXY Digital 900 IS"; + choices[0x2010000] = "PowerShot SD40 / Digital IXUS i7 / IXY Digital L4"; + choices[0x2020000] = "PowerShot A710 IS"; + choices[0x2030000] = "PowerShot A640"; + choices[0x2040000] = "PowerShot A630"; + choices[0x2090000] = "PowerShot S5 IS"; + choices[0x2100000] = "PowerShot A460"; + choices[0x2120000] = "PowerShot SD850 IS / Digital IXUS 950 IS / IXY Digital 810 IS"; + choices[0x2130000] = "PowerShot A570 IS"; + choices[0x2140000] = "PowerShot A560"; + choices[0x2150000] = "PowerShot SD750 / Digital IXUS 75 / IXY Digital 90"; + choices[0x2160000] = "PowerShot SD1000 / Digital IXUS 70 / IXY Digital 10"; + choices[0x2180000] = "PowerShot A550"; + choices[0x2190000] = "PowerShot A450"; + choices[0x2230000] = "PowerShot G9"; + choices[0x2240000] = "PowerShot A650 IS"; + choices[0x2260000] = "PowerShot A720 IS"; + choices[0x2290000] = "PowerShot SX100 IS"; + choices[0x2300000] = "PowerShot SD950 IS / Digital IXUS 960 IS / IXY Digital 2000 IS"; + choices[0x2310000] = "PowerShot SD870 IS / Digital IXUS 860 IS / IXY Digital 910 IS"; + choices[0x2320000] = "PowerShot SD890 IS / Digital IXUS 970 IS / IXY Digital 820 IS"; + choices[0x2360000] = "PowerShot SD790 IS / Digital IXUS 90 IS / IXY Digital 95 IS"; + choices[0x2370000] = "PowerShot SD770 IS / Digital IXUS 85 IS / IXY Digital 25 IS"; + choices[0x2380000] = "PowerShot A590 IS"; + choices[0x2390000] = "PowerShot A580"; + choices[0x2420000] = "PowerShot A470"; + choices[0x2430000] = "PowerShot SD1100 IS / Digital IXUS 80 IS / IXY Digital 20 IS"; + choices[0x2460000] = "PowerShot SX1 IS"; + choices[0x2470000] = "PowerShot SX10 IS"; + choices[0x2480000] = "PowerShot A1000 IS"; + choices[0x2490000] = "PowerShot G10"; + choices[0x2510000] = "PowerShot A2000 IS"; + choices[0x2520000] = "PowerShot SX110 IS"; + choices[0x2530000] = "PowerShot SD990 IS / Digital IXUS 980 IS / IXY Digital 3000 IS"; + choices[0x2540000] = "PowerShot SD880 IS / Digital IXUS 870 IS / IXY Digital 920 IS"; + choices[0x2550000] = "PowerShot E1"; + choices[0x2560000] = "PowerShot D10"; + choices[0x2570000] = "PowerShot SD960 IS / Digital IXUS 110 IS / IXY Digital 510 IS"; + choices[0x2580000] = "PowerShot A2100 IS"; + choices[0x2590000] = "PowerShot A480"; + choices[0x2600000] = "PowerShot SX200 IS"; + choices[0x2610000] = "PowerShot SD970 IS / Digital IXUS 990 IS / IXY Digital 830 IS"; + choices[0x2620000] = "PowerShot SD780 IS / Digital IXUS 100 IS / IXY Digital 210 IS"; + choices[0x2630000] = "PowerShot A1100 IS"; + choices[0x2640000] = "PowerShot SD1200 IS / Digital IXUS 95 IS / IXY Digital 110 IS"; + choices[0x2700000] = "PowerShot G11"; + choices[0x2710000] = "PowerShot SX120 IS"; + choices[0x2720000] = "PowerShot S90"; + choices[0x2750000] = "PowerShot SX20 IS"; + choices[0x2760000] = "PowerShot SD980 IS / Digital IXUS 200 IS / IXY Digital 930 IS"; + choices[0x2770000] = "PowerShot SD940 IS / Digital IXUS 120 IS / IXY Digital 220 IS"; + choices[0x2800000] = "PowerShot A495"; + choices[0x2810000] = "PowerShot A490"; + choices[0x2820000] = "PowerShot A3100 IS"; + choices[0x2830000] = "PowerShot A3000 IS"; + choices[0x2840000] = "PowerShot SD1400 IS / IXUS 130 / IXY 400F"; + choices[0x2850000] = "PowerShot SD1300 IS / IXUS 105 / IXY 200F"; + choices[0x2860000] = "PowerShot SD3500 IS / IXUS 210 / IXY 10S"; + choices[0x2870000] = "PowerShot SX210 IS"; + choices[0x2880000] = "PowerShot SD4000 IS / IXUS 300 HS / IXY 30S"; + choices[0x2890000] = "PowerShot SD4500 IS / IXUS 1000 HS / IXY 50S"; + choices[0x2920000] = "PowerShot G12"; + choices[0x2930000] = "PowerShot SX30 IS"; + choices[0x2940000] = "PowerShot SX130 IS"; + choices[0x2950000] = "PowerShot S95"; + choices[0x3010000] = "PowerShot Pro90 IS"; + choices[0x3340000] = "PowerShot SX50 HS"; + choices[0x3360000] = "PowerShot S110"; + choices[0x3540000] = "PowerShot G16"; + choices[0x3550000] = "PowerShot S120"; + choices[0x4040000] = "PowerShot G1"; + choices[0x6040000] = "PowerShot S100 / Digital IXUS / IXY Digital"; + choices[0x4007d673] = "DC19 / DC21 / DC22"; + choices[0x4007d674] = "XH A1"; + choices[0x4007d675] = "HV10"; + choices[0x4007d676] = "MD130 / MD140 / MD150 / MD160"; + choices[0x4007d777] = "iVIS DC50"; + choices[0x4007d778] = "iVIS HV20"; + choices[0x4007d779] = "DC211"; + choices[0x4007d77a] = "HG10"; + choices[0x4007d77b] = "iVIS HR10"; + choices[0x4007d878] = "HV30"; + choices[0x4007d87e] = "DC301 / DC310 / DC311 / DC320 / DC330"; + choices[0x4007d87f] = "FS100"; + choices[0x4007d880] = "iVIS HF10"; + choices[0x4007d882] = "HG20 / HG21 / VIXIA HG21"; + choices[0x4007d925] = "LEGRIA HF21"; + choices[0x4007d978] = "LEGRIA HV40"; + choices[0x4007d987] = "DC410 / DC420"; + choices[0x4007d988] = "LEGRIA FS19 / FS20 / FS21 / FS22 / FS200"; + choices[0x4007d989] = "LEGRIA HF20 / HF200"; + choices[0x4007d98a] = "VIXIA HF S10 / S100"; + choices[0x4007da8e] = "LEGRIA HF R16 / R17 / R106"; + choices[0x4007da90] = "LEGRIA HF S21 / VIXIA HF S200"; + choices[0x4007da92] = "LEGRIA FS36 / FS305 / FS306 / FS307"; + choices[0x80000001] = "EOS-1D"; + choices[0x80000167] = "EOS-1DS"; + choices[0x80000168] = "EOS 10D"; + choices[0x80000169] = "EOS-1D Mark III"; + choices[0x80000170] = "EOS Digital Rebel / 300D / Kiss Digital"; + choices[0x80000174] = "EOS-1D Mark II"; + choices[0x80000175] = "EOS 20D"; + choices[0x80000176] = "EOS Digital Rebel XSi / 450D / Kiss X2"; + choices[0x80000188] = "EOS-1Ds Mark II"; + choices[0x80000189] = "EOS Digital Rebel XT / 350D / Kiss Digital N"; + choices[0x80000190] = "EOS 40D"; + choices[0x80000213] = "EOS 5D"; + choices[0x80000215] = "EOS-1Ds Mark III"; + choices[0x80000218] = "EOS 5D Mark II"; + choices[0x80000232] = "EOS-1D Mark II N"; + choices[0x80000234] = "EOS 30D"; + choices[0x80000236] = "EOS Digital Rebel XTi / 400D / Kiss Digital X"; + choices[0x80000250] = "EOS 7D"; + choices[0x80000252] = "EOS Rebel T1i / 500D / Kiss X3"; + choices[0x80000254] = "EOS Rebel XS / 1000D / Kiss F"; + choices[0x80000261] = "EOS 50D"; + choices[0x80000270] = "EOS Rebel T2i / 550D / Kiss X4"; + choices[0x80000281] = "EOS-1D Mark IV"; + choices[0x80000285] = "EOS 5D Mark III"; + choices[0x80000286] = "EOS 600D"; + choices[0x80000287] = "EOS 60D"; + choices[0x80000325] = "EOS 70D"; + } +}; +CAModelIDInterpreter caModelIDInterpreter; + +class CAPanoramaDirectionInterpreter : public ChoiceInterpreter { +public: + CAPanoramaDirectionInterpreter(){ + choices[0] = "Left to Right"; + choices[1] = "Right to Left"; + choices[2] = "Bottom to Top"; + choices[3] = "Top to Bottom"; + choices[4] = "2x2 Matrix (Clockwise)"; + } +}; +CAPanoramaDirectionInterpreter caPanoramaDirectionInterpreter; + +class CAAspectRatioInterpreter : public ChoiceInterpreter { +public: + CAAspectRatioInterpreter(){ + choices[0] = "3:2"; + choices[1] = "1:1"; + choices[2] = "4:3"; + choices[7] = "16:9"; + } + +}; +CAAspectRatioInterpreter caAspectRatioInterpreter; + +const TagAttrib canonCameraSettingsAttribs[] = { + {0, AC_WRITE, 0, 0, 1, AUTO, "MacroMode", &caMacroModeInterpreter}, + {0, AC_WRITE, 0, 0, 2, AUTO, "SelfTimer", &caSelfTimerInterpreter}, + {0, AC_WRITE, 0, 0, 3, AUTO, "Quality", &caQualityInterpreter}, + {0, AC_WRITE, 0, 0, 4, AUTO, "CanonFlashMode", &caFlashModeInterpreter}, + {0, AC_WRITE, 0, 0, 5, AUTO, "ContinuousDrive", &caContinuousDriveInterpreter}, + {0, AC_WRITE, 0, 0, 7, AUTO, "FocusMode", &caFocusModeInterpreter}, + {0, AC_WRITE, 0, 0, 9, AUTO, "RecordMode", &caRecordModeInterpreter}, + {0, AC_WRITE, 0, 0, 10, AUTO, "CanonImageSize", &caImageSizeInterpreter}, + {0, AC_WRITE, 0, 0, 11, AUTO, "EasyMode", &caEasyModeInterpreter}, + {0, AC_WRITE, 0, 0, 12, AUTO, "DigitalZoom", &caDigitalZoomInterpreter}, + {0, AC_WRITE, 0, 0, 13, AUTO, "Contrast", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 14, AUTO, "Saturation", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 15, AUTO, "Sharpness", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 16, AUTO, "CameraISO", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 17, AUTO, "MeteringMode", &caMeteringModeInterpreter}, + {0, AC_WRITE, 0, 0, 18, AUTO, "FocusRange", &caFocusRangeInterpreter}, + {0, AC_WRITE, 0, 0, 19, AUTO, "AFPoint", &caAFPointInterpreter}, + {0, AC_WRITE, 0, 0, 20, AUTO, "CanonExposureMode", &caExposureModeInterpreter}, + {0, AC_WRITE, 0, 0, 22, AUTO, "LensID", &caLensInterpreter}, + {0, AC_WRITE, 0, 0, 23, AUTO, "LongFocal", &caFocalInterpreter}, + {0, AC_WRITE, 0, 0, 24, AUTO, "ShortFocal", &caFocalInterpreter}, + {0, AC_WRITE, 0, 0, 25, AUTO, "FocalUnits", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 26, AUTO, "MaxAperture", &caApertureInterpreter}, + {0, AC_WRITE, 0, 0, 27, AUTO, "MinAperture", &caApertureInterpreter}, + {0, AC_WRITE, 0, 0, 28, AUTO, "FlashActivity", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 29, AUTO, "FlashBits", &caFlashBitsInterpreter}, + {0, AC_WRITE, 0, 0, 32, AUTO, "FocusContinuous", &caFocusContinuousInterpreter}, + {0, AC_WRITE, 0, 0, 33, AUTO, "AESetting", &caAESettingsInterpreter}, + {0, AC_WRITE, 0, 0, 34, AUTO, "ImageStabilization", &caStabilizationInterpreter}, + {0, AC_WRITE, 0, 0, 35, AUTO, "DisplayAperture", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 36, AUTO, "ZoomSourceWidth", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 37, AUTO, "ZoomTargetWidth", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 39, AUTO, "SpotMeteringMode", &caSpotMeteringInterpreter}, + {0, AC_WRITE, 0, 0, 40, AUTO, "PhotoEffect", &caPhotoEffectInterpreter}, + {0, AC_WRITE, 0, 0, 41, AUTO, "ManualFlashOutput", &caManualFlashInterpreter}, + {0, AC_WRITE, 0, 0, 42, AUTO, "ColorTone", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 46, AUTO, "SRAWQuality", &caRAWQualityInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL} +}; + +const TagAttrib canonFocalLengthAttribs[] = { + {0, AC_WRITE, 0, 0, 0, AUTO, "FocalType", &caFocalTypeInterpreter}, + {0, AC_WRITE, 0, 0, 1, AUTO, "FocalLength", &caFocalInterpreter}, + {0, AC_WRITE, 0, 0, 2, AUTO, "FocalPlaneXSize", &caFocalPlaneInterpreter}, + {0, AC_WRITE, 0, 0, 3, AUTO, "FocalPlaneYSize", &caFocalPlaneInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL} +}; + +const TagAttrib canonShotInfoAttribs[] = { + {0, AC_WRITE, 0, 0, 1, AUTO, "AutoISO", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 2, AUTO, "BaseISO" ,&caBaseISOInterpreter}, + {0, AC_WRITE, 0, 0, 3, AUTO, "MeasuredEV", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 4, AUTO, "TargetAperture", &caApertureInterpreter}, + {0, AC_WRITE, 0, 0, 5, AUTO, "TargetExposureTime",&caExposureTimeInterpreter}, + {0, AC_WRITE, 0, 0, 6, AUTO, "ExposureCompensation",&caEVInterpreter}, + {0, AC_WRITE, 0, 0, 7, AUTO, "WhiteBalance",&caWhiteBalanceInterpreter}, + {0, AC_WRITE, 0, 0, 8, AUTO, "SlowShutter",&caSlowShutterInterpreter}, + {0, AC_WRITE, 0, 0, 9, AUTO, "SequenceNumber", &stdInterpreter}, + {0, AC_WRITE, 0, 0,10, AUTO, "OpticalZoomCode", &stdInterpreter}, + {0, AC_WRITE, 0, 0,13, AUTO, "FlashGuideNumber" , &caFlashGuideNumberInterpreter}, + {0, AC_WRITE, 0, 0,14, AUTO, "AFPointsInFocus", &caAFPointsInFocusInterpreter}, + {0, AC_WRITE, 0, 0,15, AUTO, "FlashExposureComp", &stdInterpreter}, + {0, AC_WRITE, 0, 0,16, AUTO, "AutoExposureBracketing",&caAutoExposureBracketingInterpreter}, + {0, AC_WRITE, 0, 0,17, AUTO, "AEBBracketValue", &stdInterpreter}, + {0, AC_WRITE, 0, 0,18, AUTO, "ControlMode", &caControModeInterpreter}, + {0, AC_WRITE, 0, 0,19, AUTO, "FocusDistanceUpper", &caFocusDistanceInterpreter}, + {0, AC_WRITE, 0, 0,20, AUTO, "FocusDistanceLower", &caFocusDistanceInterpreter}, + {0, AC_WRITE, 0, 0,21, AUTO, "FNumber" ,&caApertureInterpreter}, + {0, AC_WRITE, 0, 0,22, AUTO, "ExposureTime",&caExposureTimeInterpreter}, + {0, AC_WRITE, 0, 0,24, AUTO, "BulbDuration", &stdInterpreter}, + {0, AC_WRITE, 0, 0,24, AUTO, "MeasuredEV2", &caMeasuredEVInterpreter}, + {0, AC_WRITE, 0, 0,26, AUTO, "CameraType", &caCameraTypeInterpreter}, + {0, AC_WRITE, 0, 0,27, AUTO, "AutoRotate",&caAutoRotateInterpreter}, + {0, AC_WRITE, 0, 0,28, AUTO, "NDFilter",&caOnOffInterpreter}, + {0, AC_WRITE, 0, 0,29, AUTO, "Self-timer2", &stdInterpreter}, + {0, AC_WRITE, 0, 0,33, AUTO, "FlashOutput", &stdInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}, +}; + +const TagAttrib canonFileInfoAttribs[] = { + {0, AC_WRITE, 0, 0, 1, AUTO, "FileNumber", &caFileNumberInterpreter}, + {0, AC_WRITE, 0, 0, 3, AUTO, "BracketMode", &caBracketModeInterpreter}, + {0, AC_WRITE, 0, 0, 4, AUTO, "BracketValue", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 5, AUTO, "BracketShotNumber", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 6, AUTO, "RawJpgQuality",&caRAWJpegQualityInterpreter}, + {0, AC_WRITE, 0, 0, 7, AUTO, "RawJpgSize",&caJpegSizeInterpreter}, + {0, AC_WRITE, 0, 0, 8, AUTO, "NoiseReduction",&stdInterpreter}, + {0, AC_WRITE, 0, 0, 9, AUTO, "WBBracketMode" ,&caWBBracketModeInterpreter}, + {0, AC_WRITE, 0, 0,12, AUTO, "WBBracketValueAB", &stdInterpreter}, + {0, AC_WRITE, 0, 0,13, AUTO, "WBBracketValueGM", &stdInterpreter}, + {0, AC_WRITE, 0, 0,14, AUTO, "FilterEffect" ,&caFilterEffectInterpreter}, + {0, AC_WRITE, 0, 0,15, AUTO, "ToningEffect" ,&caToningEffectInterpreter}, + {0, AC_WRITE, 0, 0,19, AUTO, "LiveViewShooting" ,&caOnOffInterpreter}, + {0, AC_WRITE, 0, 0,25, AUTO, "FlashExposureLock" ,&caOnOffInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}, +}; + +const TagAttrib canonProcessingInfoAttribs[] = { + {0, AC_WRITE, 0, 0, 1, AUTO, "ToneCurve", &caToneCurveInterpreter}, + {0, AC_WRITE, 0, 0, 2, AUTO, "Sharpness", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 3, AUTO, "SharpnessFrequency", &caSharpnessFrequencyInterpreter}, + {0, AC_WRITE, 0, 0, 4, AUTO, "SensorRedLevel", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 5, AUTO, "SensorBlueLevel", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 6, AUTO, "WhiteBalanceRed", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 7, AUTO, "WhiteBalanceBlue", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 8, AUTO, "WhiteBalance", &caWhiteBalanceInterpreter}, + {0, AC_WRITE, 0, 0, 9, AUTO, "ColorTemperature", &stdInterpreter}, + {0, AC_WRITE, 0, 0,10, AUTO, "PictureStyle", &caPictureStyleInterpreter}, + {0, AC_WRITE, 0, 0,11, AUTO, "DigitalGain", &stdInterpreter}, + {0, AC_WRITE, 0, 0,12, AUTO, "WBShiftAB", &stdInterpreter}, + {0, AC_WRITE, 0, 0,13, AUTO, "WBShiftGM", &stdInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}, +}; + +const TagAttrib canonPanoramaInfoAttribs[] = { + {0, AC_WRITE, 0, 0, 2, AUTO, "PanoramaFrameNumber", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 5, AUTO, "PanoramaDirection", &caPanoramaDirectionInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}, +}; + +const TagAttrib canonCropInfoAttribs[] = { + {0, AC_WRITE, 0, 0, 0, AUTO, "CropLeftMargin", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 1, AUTO, "CropRightMargin", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 2, AUTO, "CropTopMargin", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 3, AUTO, "CropBottomMargin", &stdInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}, +}; + +const TagAttrib canonAspectInfoAttribs[] = { + {0, AC_WRITE, 0, 0, 0, AUTO, "AspectRatio", &caAspectRatioInterpreter}, + {0, AC_WRITE, 0, 0, 1, AUTO, "CroppedImageWidth", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 2, AUTO, "CroppedImageHeight", &stdInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}, +}; + +const TagAttrib canonMicroAdjustAttrib[] = { + {0, AC_WRITE, 0, 0, 1, AUTO, "AFMicroAdjActive", &caOnOffInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 2, AUTO, "", NULL}, +}; + +const TagAttrib canonAttribs[] = { + {0, AC_WRITE, 0, canonCameraSettingsAttribs, 0x0001, AUTO, "CanonCameraSettings", &stdInterpreter}, + {0, AC_WRITE, 0, canonFocalLengthAttribs, 0x0002, AUTO, "CanonFocalLength", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0003, AUTO, "CanonFlashInfo", &stdInterpreter}, + {0, AC_WRITE, 0, canonShotInfoAttribs, 0x0004, AUTO, "CanonShotInfo", &stdInterpreter}, + {0, AC_WRITE, 0, canonPanoramaInfoAttribs, 0x0005, AUTO, "CanonPanorama", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0006, AUTO, "CanonImageType", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0007, AUTO, "CanonFirmwareVersion", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0008, AUTO, "FileNumber", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0009, AUTO, "OwnerName", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x000a, AUTO, "ColorInfoD30", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x000c, AUTO, "SerialNumber", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x000d, AUTO, "CanonCameraInfo", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x000e, AUTO, "CanonFileLength", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x000f, AUTO, "CustomFunctions", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0010, AUTO, "CanonModelID", &caModelIDInterpreter}, + {0, AC_WRITE, 0, 0, 0x0012, AUTO, "CanonAFInfo", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0015, AUTO, "SerialNumberFormat", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x001c, AUTO, "DateStampMode", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x001d, AUTO, "MyColors", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x001e, AUTO, "FirmwareRevision", &stdInterpreter}, + {0, AC_NEW, 0, 0, 0x0024, AUTO, "FaceDetect1", &stdInterpreter}, + {0, AC_NEW, 0, 0, 0x0025, AUTO, "FaceDetect2", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0026, AUTO, "CanonAFInfo2", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0083, AUTO, "OriginalDecisionData", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0090, AUTO, "CustomFunctions1D", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0091, AUTO, "PersonalFunctions", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0092, AUTO, "PersonalFunctionValues", &stdInterpreter}, + {0, AC_WRITE, 0, canonFileInfoAttribs, 0x0093, AUTO, "CanonFileInfo", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0094, AUTO, "AFPointsInFocus1D", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0095, AUTO, "LensType", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0096, AUTO, "InternalSerialNumber", &caIntSerNumInterpreter}, + {0, AC_WRITE, 0, 0, 0x0097, AUTO, "DustRemovalData", &stdInterpreter}, + {0, AC_WRITE, 0, canonCropInfoAttribs, 0x0098, AUTO, "CropInfo", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0099, AUTO, "CustomFunctions2", &stdInterpreter}, + {0, AC_WRITE, 0, canonAspectInfoAttribs, 0x009a, AUTO, "AspectInfo", &stdInterpreter}, + {0, AC_WRITE, 0, canonProcessingInfoAttribs, 0x00a0, AUTO, "ProcessingInfo", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x00a1, AUTO, "ToneCurveTable", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x00a2, AUTO, "SharpnessTable", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x00a3, AUTO, "SharpnessFreqTable", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x00a4, AUTO, "WhiteBalanceTable", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x00a9, AUTO, "ColorBalance", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x00aa, AUTO, "MeasuredColor", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x00ae, AUTO, "ColorTemperature", &stdInterpreter}, + {0, AC_NEW , 0, 0, 0x00b0, AUTO, "CanonFlags", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x00b1, AUTO, "ModifiedInfo", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x00b2, AUTO, "ToneCurveMatching", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x00b3, AUTO, "WhiteBalanceMatching", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x00b4, AUTO, "ColorSpace", &stdInterpreter}, + {1, AC_WRITE, 0, 0, 0x00b6, AUTO, "PreviewImageInfo", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x00d0, AUTO, "VRDOffset", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x00e0, AUTO, "SensorInfo", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x4001, AUTO, "ColorBalance", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x4002, AUTO, "UnknownBlock1", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x4003, AUTO, "ColorInfo", &stdInterpreter}, + {1, AC_WRITE, 0, 0, 0x4005, AUTO, "UnknownBlock2", &stdInterpreter}, + {1, AC_WRITE, 0, 0, 0x4008, AUTO, "BlackLevel", &stdInterpreter}, + {1, AC_WRITE, 0, canonMicroAdjustAttrib, 0x4013, AUTO, "AFMicroAdj", &stdInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}}; +} +#endif + diff --git a/rtexif/fujiattribs.cc b/rtexif/fujiattribs.cc new file mode 100644 index 000000000..717c5018e --- /dev/null +++ b/rtexif/fujiattribs.cc @@ -0,0 +1,260 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _FUJIATTRIBS_ +#define _FUJIATTRIBS_ + +#include "rtexif.h" + +namespace rtexif { + +class FAOnOffInterpreter : public ChoiceInterpreter { + public: + FAOnOffInterpreter () { + choices[0] = "Off"; + choices[1] = "On"; + } +}; +FAOnOffInterpreter faOnOffInterpreter; + +class FASharpnessInterpreter : public ChoiceInterpreter { + public: + FASharpnessInterpreter () { + choices[1] = "Soft"; + choices[2] = "Soft2"; + choices[3] = "Normal"; + choices[4] = "Hard"; + choices[5] = "Hard2"; + choices[0x82] = "Medium Soft"; + choices[0x84] = "Medium Hard"; + choices[0x8000] = "Film Simulation"; + choices[0xffff] = "n/a"; + } +}; +FASharpnessInterpreter faSharpnessInterpreter; + +class FAWhiteBalanceInterpreter : public ChoiceInterpreter { + public: + FAWhiteBalanceInterpreter () { + choices[0] = "Auto"; + choices[0x100] = "Daylight"; + choices[0x200] = "Cloudy"; + choices[0x300] = "Daylight Fluorescent"; + choices[0x301] = "Day White Fluorescent"; + choices[0x302] = "White Fluorescent"; + choices[0x303] = "Warm White Fluorescent"; + choices[0x304] = "Living Room Warm White Fluorescent"; + choices[0x400] = "Incandescent"; + choices[0x500] = "Flash"; + choices[0xf00] = "Custom"; + choices[0xf01] = "Custom2"; + choices[0xf02] = "Custom3"; + choices[0xf03] = "Custom4"; + choices[0xf04] = "Custom5"; + choices[0xff0] = "Kelvin"; + } +}; +FAWhiteBalanceInterpreter faWhiteBalanceInterpreter; + +class FASaturationInterpreter : public ChoiceInterpreter { + public: + FASaturationInterpreter () { + choices[0] = "Normal"; + choices[0x80] = "Medium High"; + choices[0x100] = "High"; + choices[0x180] = "Medium Low"; + choices[0x200] = "Low"; + choices[0x300] = "None (B&W)"; + choices[0x8000] = "Film Simulation"; + } +}; +FASaturationInterpreter faSaturationInterpreter; + +class FAContrastInterpreter : public ChoiceInterpreter { + public: + FAContrastInterpreter () { + choices[0] = "Normal"; + choices[0x80] = "Medium High"; + choices[0x100] = "High"; + choices[0x180] = "Medium Low"; + choices[0x200] = "Low"; + choices[0x8000] = "Film Simulation"; + } +}; +FAContrastInterpreter faContrastInterpreter; + +class FAContrast2Interpreter : public ChoiceInterpreter { + public: + FAContrast2Interpreter () { + choices[0] = "Normal"; + choices[0x100] = "High"; + choices[0x300] = "Low"; + } +}; +FAContrast2Interpreter faContrast2Interpreter; + +class FANoiseReductionInterpreter : public ChoiceInterpreter { + public: + FANoiseReductionInterpreter () { + choices[0x40] = "Low"; + choices[0x80] = "Normal"; + } +}; +FANoiseReductionInterpreter faNoiseReductionInterpreter; + +class FAFlashInterpreter : public ChoiceInterpreter { + public: + FAFlashInterpreter () { + choices[0] = "Auto"; + choices[1] = "On"; + choices[2] = "Off"; + choices[3] = "Red-eye reduction"; + choices[4] = "External"; + } +}; +FAFlashInterpreter faFlashInterpreter; + +class FAFocusModeInterpreter : public ChoiceInterpreter { + public: + FAFocusModeInterpreter () { + choices[0] = "Auto"; + choices[1] = "Manual"; + } +}; +FAFocusModeInterpreter faFocusModeInterpreter; + +class FAColorModeInterpreter : public ChoiceInterpreter { + public: + FAColorModeInterpreter () { + choices[0] = "Standard"; + choices[0x10] = "Chrome"; + choices[0x30] = "B & W"; + } +}; +FAColorModeInterpreter faColorModeInterpreter; + +class FADynamicRangeInterpreter : public ChoiceInterpreter { + public: + FADynamicRangeInterpreter () { + choices[1] = "Standard"; + choices[3] = "Wide"; + } +}; +FADynamicRangeInterpreter faDynamicRangeInterpreter; + +class FAFilmModeInterpreter : public ChoiceInterpreter { + public: + FAFilmModeInterpreter () { + choices[0] = "F0/Standard"; + choices[0x100] = "F1/Studio Portrait"; + choices[0x110] = "F1a/Studio Portrait Enhanced Saturation"; + choices[0x120] = "F1b/Studio Portrait Smooth Skin Tone"; + choices[0x130] = "F1c/Studio Portrait Increased Sharpness "; + choices[0x200] = "F2/Fujichrome"; + choices[0x300] = "F3/Studio Portrait Ex"; + choices[0x400] = "F4/Velvia"; + } +}; +FAFilmModeInterpreter faFilmModeInterpreter; + +class FADRSettingInterpreter : public ChoiceInterpreter { + public: + FADRSettingInterpreter () { + choices[0] = "Auto (100-400%)"; + choices[0x1] = "RAW"; + choices[0x100] = "Standard (100%)"; + choices[0x200] = "Wide1 (230%)"; + choices[0x201] = "Wide2 (400%)"; + choices[0x8000] = "Film Simulation"; + } +}; +FADRSettingInterpreter faDRSettingInterpreter; + +class FAPictureModeInterpreter : public ChoiceInterpreter { + public: + FAPictureModeInterpreter () { + choices[0] = "Auto"; + choices[1] = "Portrait"; + choices[2] = "Landscape"; + choices[3] = "Macro"; + choices[4] = "Sports"; + choices[5] = "Night Scene"; + choices[6] = "Program AE"; + choices[7] = "Natural Light"; + choices[8] = "Anti-blur"; + choices[9] = "Beach & Snow"; + choices[10] = "Sunset"; + choices[11] = "Museum"; + choices[12] = "Party"; + choices[13] = "Flower"; + choices[14] = "Text"; + choices[15] = "Natural Light & Flash"; + choices[16] = "Beach"; + choices[17] = "Fireworks"; + choices[18] = "Underwater"; + choices[0x100] = "Aperture-priority AE"; + choices[0x200] = "Shutter speed priority AE"; + choices[0x300] = "Manual"; + } +}; +FAPictureModeInterpreter faPictureModeInterpreter; + + + +const TagAttrib fujiAttribs[] = { + {0, AC_WRITE, 0, 0, 0x0000, AUTO, "Version", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0010, AUTO, "InternalSerialNumber", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1000, AUTO, "Quality", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1001, AUTO, "Sharpness", &faSharpnessInterpreter}, + {0, AC_WRITE, 0, 0, 0x1002, AUTO, "WhiteBalance", &faWhiteBalanceInterpreter}, + {0, AC_WRITE, 0, 0, 0x1003, AUTO, "Saturation", &faSaturationInterpreter}, + {0, AC_WRITE, 0, 0, 0x1004, AUTO, "Contrast", &faContrastInterpreter}, + {0, AC_WRITE, 0, 0, 0x1005, AUTO, "ColorTemperature", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1006, AUTO, "Contrast2", &faContrast2Interpreter}, + {0, AC_WRITE, 0, 0, 0x100a, AUTO, "WhiteBalanceFineTune", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x100b, AUTO, "NoiseReduction", &faNoiseReductionInterpreter}, + {0, AC_WRITE, 0, 0, 0x1010, AUTO, "FujiFlashMode", &faFlashInterpreter}, + {0, AC_WRITE, 0, 0, 0x1011, AUTO, "FlashExposureComp", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1020, AUTO, "Macro", &faOnOffInterpreter}, + {0, AC_WRITE, 0, 0, 0x1021, AUTO, "FocusMode", &faFocusModeInterpreter}, + {0, AC_WRITE, 0, 0, 0x1023, AUTO, "FocusPixel", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1030, AUTO, "SlowSync", &faOnOffInterpreter}, + {0, AC_WRITE, 0, 0, 0x1031, AUTO, "PictureMode", &faPictureModeInterpreter}, + {0, AC_WRITE, 0, 0, 0x1100, AUTO, "AutoBracketing", &faOnOffInterpreter}, + {0, AC_WRITE, 0, 0, 0x1101, AUTO, "SequenceNumber", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1210, AUTO, "ColorMode", &faColorModeInterpreter}, + {0, AC_WRITE, 0, 0, 0x1300, AUTO, "BlurWarning", &faOnOffInterpreter}, + {0, AC_WRITE, 0, 0, 0x1301, AUTO, "FocusWarning", &faOnOffInterpreter}, + {0, AC_WRITE, 0, 0, 0x1302, AUTO, "ExposureWarning", &faOnOffInterpreter}, + {0, AC_WRITE, 0, 0, 0x1400, AUTO, "DynamicRange", &faDynamicRangeInterpreter}, + {0, AC_WRITE, 0, 0, 0x1401, AUTO, "FilmMode", &faFilmModeInterpreter}, + {0, AC_WRITE, 0, 0, 0x1402, AUTO, "DynamicRangeSetting", &faDRSettingInterpreter}, + {0, AC_WRITE, 0, 0, 0x1403, AUTO, "DevelopmentDynamicRange", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1404, AUTO, "MinFocalLength", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1405, AUTO, "MaxFocalLength", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1406, AUTO, "MaxApertureAtMinFocal", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1407, AUTO, "MaxApertureAtMaxFocal", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x140b, AUTO, "AutoDynamicRange", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x4100, AUTO, "FacesDetected", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x8000, AUTO, "FileSource", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x8002, AUTO, "OrderNumber", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x8003, AUTO, "FrameNumber", &stdInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}}; +} +#endif + diff --git a/rtexif/kodakattribs.cc b/rtexif/kodakattribs.cc new file mode 100644 index 000000000..d05f8c4bb --- /dev/null +++ b/rtexif/kodakattribs.cc @@ -0,0 +1,137 @@ +/* + * This file is part of RawTherapee. + */ +#ifndef _KODAKATTRIBS_ +#define _KODAKATTRIBS_ + +#include +#include "rtexif.h" + +namespace rtexif { + + +void parseKodakIfdTextualInfo(Tag *textualInfo, Tag* exif_) +{ + // parse TextualInfo and copy values into corresponding standard Exif + if (textualInfo->getType() != ASCII) { + return; + } + TagDirectory *exif = exif_->getDirectory(); + char *value = (char *)textualInfo->getValue(); + int valuesize = textualInfo->getValueSize(); + + char *p = value; + char *pc, *plf; + while ((pc = strchr(p, ':')) != NULL && (plf = strchr(pc, '\n')) != NULL) { + while (*p == ' ') p++; + size_t len = pc - p; + while (len > 1 && p[len-1] == ' ') len--; + std::string key = std::string(p, len); + ++pc; while (*pc == ' ') pc++; + len = plf - pc; + while (len > 1 && pc[len-1] == ' ') len--; + std::string val = std::string(pc, len); + p = ++plf; + + // we pick out a few select tags here + Tag *t; + if (key == "Lens") { + // Proback645 may have "Lens" but not "Focal Length" + float flen = atof(val.c_str()); + if (flen != 0.0) { + t = new Tag(exif, lookupAttrib(exifAttribs,"FocalLength")); + t->initRational(flen*32, 32); + exif->replaceTag(t); + } + } else if (key == "Focal Length") { + float flen = atof(val.c_str()); + if (flen != 0.0) { + t = new Tag(exif, lookupAttrib(exifAttribs,"FocalLength")); + t->initRational(flen*32, 32); + exif->replaceTag(t); + } + } else if (key == "Aperture") { + float aperture = atof(&val.c_str()[1]); + if (aperture != 0.0) { + t = new Tag(exif, lookupAttrib(exifAttribs,"FNumber")); + t->initRational((int)(aperture*10), 10); + exif->replaceTag(t); + } + } else if (key == "Exposure Bias" || key == "Compensation") { + float bias = 0.0; + if (val != "Off") { + bias = atof(val.c_str()); + } + t = new Tag (exif, lookupAttrib(exifAttribs,"ExposureBiasValue")); + t->initRational ((int)(bias*1000), 1000); + exif->replaceTag(t); + } else if (key == "ISO Speed") { + t = new Tag (exif, lookupAttrib(exifAttribs,"ISOSpeedRatings")); + t->initInt(atoi(val.c_str()), SHORT); + exif->replaceTag(t); + } else if (key == "Shutter") { + const char *p1 = strchr(val.c_str(), '/'); + int a, b; + if (p1 == NULL) { + a = atoi(val.c_str()); + b = 1; + } else { + a = atoi(val.c_str()); + b = atoi(&p1[1]); + } + t = new Tag (exif, lookupAttrib(exifAttribs,"ExposureTime")); + t->initRational(a, b); + exif->replaceTag(t); + + float ssv = -log2((float)a/(float)b); // convert to APEX value + t = new Tag (exif, lookupAttrib(exifAttribs,"ShutterSpeedValue")); + t->initRational(1000000 * ssv, 1000000); + exif->replaceTag(t); + } else if (key == "Flash Fired") { + t = new Tag (exif, lookupAttrib(exifAttribs,"Flash")); + if (val == "No") { + t->initInt(0, SHORT); + } else { + // not sure if "Flash Fired" is only yes/no, only seen "No" in test pictures + t->initInt(1, SHORT); + } + exif->replaceTag(t); + } else if (key == "White balance") { // yes should be small 'b' int 'balance'. + t = new Tag (exif, lookupAttrib(exifAttribs,"Flash")); + t->initInt((val == "Auto") ? 0 : 1, SHORT); + exif->replaceTag(t); + } + } +} + +// table not complete, not all proprietary Kodak tags are known +const TagAttrib kodakIfdAttribs[] = { + {0, AC_WRITE, 0, 0, 0x0001, AUTO, "UnknownEV?", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0003, AUTO, "ExposureValue", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x03e9, AUTO, "OriginalFileName", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x03eb, AUTO, "SensorLeftBorder", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x03ec, AUTO, "SensorTopBorder", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x03ed, AUTO, "SensorImageWidth", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x03ee, AUTO, "SensorImageHeight", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x03f1, AUTO, "TextualInfo", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x03fc, AUTO, "WhiteBalance", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x03fd, AUTO, "Processing", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0401, AUTO, "Time", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0414, AUTO, "NCDFileInfo", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0846, AUTO, "ColorTemperature", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0852, AUTO, "WB_RGBMul0", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0853, AUTO, "WB_RGBMul1", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0854, AUTO, "WB_RGBMul2", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0855, AUTO, "WB_RGBMul3", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x085c, AUTO, "WB_RGBCoeffs0", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x085d, AUTO, "WB_RGBCoeffs1", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x085e, AUTO, "WB_RGBCoeffs2", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x085f, AUTO, "WB_RGBCoeffs3", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0ce5, AUTO, "FirmwareVersion", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1391, AUTO, "ToneCurveFileName", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1784, AUTO, "ISO", &stdInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL }}; + +} +#endif + diff --git a/rtexif/nikonattribs.cc b/rtexif/nikonattribs.cc new file mode 100644 index 000000000..1c92587b4 --- /dev/null +++ b/rtexif/nikonattribs.cc @@ -0,0 +1,935 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _NIKONATTRIBS_ +#define _NIKONATTRIBS_ + +#include +#include +#include +#include + +#include "rtexif.h" + +using namespace std; + +namespace rtexif { + +class NAISOInterpreter : public Interpreter { + public: + NAISOInterpreter () {} + virtual std::string toString (Tag* t) { + char buffer[32]; + sprintf (buffer, "%d", t->toInt(2)); + return buffer; + } +}; +NAISOInterpreter naISOInterpreter; + +class NAISOInfoISOInterpreter : public Interpreter { + public: + NAISOInfoISOInterpreter () {} + virtual std::string toString (Tag* t) { + char buffer[32]; + int a = t->toInt(); + sprintf (buffer, "%d", a); + return buffer; + } + virtual double toDouble (Tag* t, int ofs){ + int a = t->getValue()[ofs]; + if(a>1) { + double i = pow(2., double(a)/12. - 5.) * 100.; + return i; + } + else + return 0.; + } + virtual int toInt (Tag* t, int ofs, TagType astype){ + int a = t->getValue()[ofs]; + if(a>1) { + int i = int(double(powf(2.f, float(a)/12.f - 5.f)) * 100.f +0.5f); + return i; + } + else + return 0; + } +}; +NAISOInfoISOInterpreter naISOInfoISOInterpreter; + +class NAISOExpansionInterpreter : public Interpreter { + public: + NAISOExpansionInterpreter () {} + virtual std::string toString (Tag* t) { + int a = t->toInt(); + // unclear if this interpretation is correct! + switch (a) { + case 0x0: return "Off"; + case 0x101: return "Hi 0.3"; + case 0x102: return "Hi 0.5"; + case 0x103: return "Hi 0.7"; + case 0x104: return "Hi 1.0"; + case 0x105: return "Hi 1.3"; + case 0x106: return "Hi 1.5"; + case 0x107: return "Hi 1.7"; + case 0x108: return "Hi 2.0"; + case 0x201: return "Lo 0.3"; + case 0x202: return "Lo 0.5"; + case 0x203: return "Lo 0.7"; + case 0x204: return "Lo 1.0"; + default: { char buffer[32]; sprintf(buffer, "0x%04X", a); return buffer; } + } + } +}; +NAISOExpansionInterpreter naISOExpansionInterpreter; + +class NALensTypeInterpreter : public Interpreter { + public: + NALensTypeInterpreter () {} + virtual std::string toString (Tag* t) { + int a = t->toInt(); + std::ostringstream str; + str << "MF = " << (a&1 ? "Yes" : "No") << std::endl; + str << "D = " << (a&2 ? "Yes" : "No") << std::endl; + str << "G = " << (a&4 ? "Yes" : "No") << std::endl; + str << "VR = " << (a&8 ? "Yes" : "No"); + return str.str(); + } +}; +NALensTypeInterpreter naLensTypeInterpreter; + +class NAFlashModeInterpreter : public ChoiceInterpreter { + public: + NAFlashModeInterpreter () { + choices[0] = "Did Not Fire"; + choices[1] = "Fired, Manual"; + choices[7] = "Fired, External"; + choices[8] = "Fired, Commander Mode"; + choices[9] = "Fired, TTL Mode"; + } +}; +NAFlashModeInterpreter naFlashModeInterpreter; + +class NAHiISONRInterpreter : public ChoiceInterpreter { + public: + NAHiISONRInterpreter () { + choices[0] = "Off"; + choices[1] = "Minimal"; + choices[2] = "Low"; + choices[4] = "Normal"; + choices[6] = "High"; + } +}; +NAHiISONRInterpreter naHiISONRInterpreter; + +class NAShootingModeInterpreter : public Interpreter { + public: + NAShootingModeInterpreter () {} + virtual std::string toString (Tag* t) { + int a = t->toInt(); + std::ostringstream str; + str << "Continuous = " << (a&1 ? "Yes" : "No") << std::endl; + str << "Delay = " << (a&2 ? "Yes" : "No") << std::endl; + str << "PC Control = " << (a&4 ? "Yes" : "No") << std::endl; + str << "White-Balance Bracketing = " << (a&8 ? "Yes" : "No") << std::endl; + str << "Exposure Bracketing = " << (a&16 ? "Yes" : "No") << std::endl; + str << "Auto ISO = " << (a&32 ? "Yes" : "No") << std::endl; + str << "IR Control = " << (a&64 ? "Yes" : "No"); + return str.str(); + } +}; +NAShootingModeInterpreter naShootingModeInterpreter; + +class NAAFInfoInterpreter : public Interpreter { + std::map amchoices; + std::map afpchoices; + public: + NAAFInfoInterpreter () { + amchoices[0] = "Single Area"; + amchoices[1] = "Dynamic Area"; + amchoices[2] = "Dynamic Area, Closest Subject"; + amchoices[3] = "Group Dynamic"; + amchoices[4] = "Single Area (wide)"; + amchoices[5] = "Dynamic Area (wide)"; + afpchoices[0] = "Center"; + afpchoices[1] = "Top"; + afpchoices[2] = "Bottom"; + afpchoices[3] = "Left"; + afpchoices[4] = "Right"; + afpchoices[5] = "Upper-left"; + afpchoices[6] = "Upper-right"; + afpchoices[7] = "Lower-left"; + afpchoices[8] = "Lower-right"; + afpchoices[9] = "Far Left"; + afpchoices[10] = "Far Right"; + } + virtual std::string toString (Tag* t) { + int am = t->toInt (0, BYTE); + int afp = t->toInt (1, BYTE); + int aff = t->toInt (2, SHORT); + std::ostringstream str; + str << "AFAreaMode = " << amchoices[am] << std::endl; + str << "AFAreaMode = " << afpchoices[afp] << std::endl; + + std::ostringstream af; + if (aff&1) + if (af.str()=="") af << "Center"; + else af << ", Center"; + else if (aff&2) + if (af.str()=="") af << "Top"; + else af << ", Top"; + else if (aff&4) + if (af.str()=="") af << "Bottom"; + else af << ", Bottom"; + else if (aff&8) + if (af.str()=="") af << "Left"; + else af << ", Left"; + else if (aff&16) + if (af.str()=="") af << "Right"; + else af << ", Right"; + else if (aff&32) + if (af.str()=="") af << "Upper-left"; + else af << ", Upper-left"; + else if (aff&64) + if (af.str()=="") af << "Upper-right"; + else af << ", Upper-right"; + else if (aff&128) + if (af.str()=="") af << " Lower-left"; + else af << ", Lower-left"; + else if (aff&256) + if (af.str()=="") af << "Lower-right"; + else af << ", Lower-right"; + else if (aff&512) + if (af.str()=="") af << "Far Left"; + else af << ", Far Left"; + else if (aff&1024) { + if (af.str()=="") af << "Far Right"; + else af << ", Far Right"; + } + + str << "AFPointsInFocus = " << af.str(); + return str.str(); + } +}; +NAAFInfoInterpreter naAFInfoInterpreter; + +class NALensDataInterpreter : public Interpreter { + std::map lenses; + public: + NALensDataInterpreter () { // From EXIFTOOL database 'Nikon.pm' V2.80 +/* The key is a composite string made of 8 HEX bytes + * LensIDNumber LensFStops MinFocalLength MaxFocalLength MaxApertureAtMinFocal MaxApertureAtMaxFocal MCUVersion and LensType */ + lenses["00 00 00 00 00 00 00 01"] = "Manual Lens No CPU"; + lenses["00 00 00 00 00 00 E1 12"] = "TC-17E II"; + lenses["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"; + lenses["00 00 00 00 00 00 F2 18"] = "TC-20E [II] or Sigma APO Tele Converter 2x EX DG or Kenko Teleplus PRO 300 DG 2.0x"; + lenses["00 00 48 48 53 53 00 01"] = "Loreo 40mm f/11-22 3D Lens in a Cap 9005"; + lenses["00 36 1C 2D 34 3C 00 06"] = "Tamron SP AF 11-18mm f/4.5-5.6 Di II LD Aspherical (IF)"; + lenses["00 3C 1F 37 30 30 00 06"] = "Tokina AT-X 124 PRO DX AF 12-24mm f/4"; + lenses["00 3E 80 A0 38 3F 00 02"] = "Tamron SP AF 200-500mm f/5-6.3 Di LD (IF)"; + lenses["00 3F 2D 80 2B 40 00 06"] = "Tamron AF 18-200mm f/3.5-6.3 XR Di II LD Aspherical (IF)"; + lenses["00 3F 2D 80 2C 40 00 06"] = "Tamron AF 18-200mm f/3.5-6.3 XR Di II LD Aspherical (IF) Macro"; + lenses["00 3F 80 A0 38 3F 00 02"] = "Tamron SP AF 200-500mm f/5-6.3 Di"; + lenses["00 40 11 11 2C 2C 00 00"] = "Samyang 8mm f/3.5 Fish-Eye"; + lenses["00 40 18 2B 2C 34 00 06"] = "Tokina AT-X 107 DX Fish-Eye AF 10-17mm f/3.5-4.5"; + lenses["00 40 2A 72 2C 3C 00 06"] = "Tokina AT-X 16.5-135 DX AF 16.5-135mm f/3.5-5.6"; + lenses["00 40 2B 2B 2C 2C 00 02"] = "Tokina AT-X 17 PRO AF 17mm f/3.5"; + lenses["00 40 2D 2D 2C 2C 00 00"] = "Carl Zeiss Distagon T* 18mm f/3.5 ZF.2"; + lenses["00 40 2D 80 2C 40 00 06"] = "Tamron AF 18-200mm f/3.5-6.3 XR Di II LD Aspherical (IF) Macro (A14NII)"; + lenses["00 40 2D 88 2C 40 00 06"] = "Tamron AF 18-250mm f/3.5-6.3 Di II LD Aspherical (IF) Macro (A18NII)"; + lenses["00 40 2D 88 2C 40 62 06"] = "Tamron AF 18-250mm f/3.5-6.3 Di II LD Aspherical (IF) Macro (A18)"; + lenses["00 40 31 31 2C 2C 00 00"] = "Voigtlander Color Skopar 20mm f/3.5 SLII Aspherical"; + lenses["00 40 37 80 2C 3C 00 02"] = "Tokina AT-X 242 AF 24-200mm f/3.5-5.6"; + lenses["00 40 64 64 2C 2C 00 00"] = "Voigtlander APO-Lanthar 90mm f/3.5 SLII Close Focus"; + lenses["00 44 60 98 34 3C 00 02"] = "Tokina AT-X 840D 80-400mm f/4.5-5.6"; + lenses["00 47 10 10 24 24 00 00"] = "Fisheye Nikkor 8mm f/2.8 AiS"; + lenses["00 47 25 25 24 24 00 02"] = "Tamron SP AF 14mm f/2.8 Aspherical (IF) (69E)"; + lenses["00 47 44 44 24 24 00 06"] = "Tokina AT-X M35 PRO DX (AF 35mm f/2.8 Macro)"; + lenses["00 47 53 80 30 3C 00 06"] = "Tamron AF 55-200mm f/4-5.6 Di II LD"; + lenses["00 48 1C 29 24 24 00 06"] = "Tokina AT-X 116 PRO DX AF 11-16mm f/2.8"; + lenses["00 48 29 3C 24 24 00 06"] = "Tokina AT-X 16-28 PRO FX AF 16-28mm f/2.8"; + lenses["00 48 29 50 24 24 00 06"] = "Tokina AT-X 165 PRO DX AF 16-50mm f/2.8"; + lenses["00 48 32 32 24 24 00 00"] = "Carl Zeiss Distagon T* 21mm f/2.8 ZF.2"; + lenses["00 48 3C 60 24 24 00 02"] = "Tokina AT-X 280 PRO AF 28-80mm f/2.8 Aspherical"; + lenses["00 48 3C 6A 24 24 00 02"] = "Tamron SP AF 28-105mm f/2.8"; + lenses["00 48 50 50 18 18 00 00"] = "Nikkor H 50mm f/2"; + lenses["00 48 50 72 24 24 00 06"] = "Tokina AT-X 535 PRO DX AF 50-135mm f/2.8"; + lenses["00 48 5C 8E 30 3C 00 06"] = "Tamron AF 70-300mm f/4-5.6 Di LD Macro 1:2 (A17)"; + lenses["00 48 68 68 24 24 00 00"] = "Series E 100mm f/2.8"; + lenses["00 48 80 80 30 30 00 00"] = "Nikkor 200mm f/4 AiS"; + lenses["00 49 30 48 22 2B 00 02"] = "Tamron SP AF 20-40mm f/2.7-3.5"; + lenses["00 4C 6A 6A 20 20 00 00"] = "Nikkor 105mm f/2.5 AiS"; + lenses["00 4C 7C 7C 2C 2C 00 02"] = "Tamron SP AF 180mm f/3.5 Di Model (B01)"; + lenses["00 53 2B 50 24 24 00 06"] = "Tamron SP AF 17-50mm f/2.8 (A16)"; + lenses["00 54 2B 50 24 24 00 06"] = "Tamron SP AF 17-50mm f/2.8 XR Di II LD Aspherical (IF) (A16NII)"; + lenses["00 54 3C 3C 18 18 00 00"] = "Carl Zeiss Distagon T* 28mm f/2 ZF.2"; + lenses["00 54 44 44 0C 0C 00 00"] = "Nikkor 35mm f/1.4 AiS"; + lenses["00 54 44 44 18 18 00 00"] = "Carl Zeiss Distagon T* 35mm f/2 ZF.2"; + lenses["00 54 48 48 18 18 00 00"] = "Voigtlander Ultron 40mm f/2 SLII Aspherical"; + lenses["00 54 50 50 0C 0C 00 00"] = "Carl Zeiss Planar T* 50mm f/1.4 ZF.2"; + lenses["00 54 50 50 18 18 00 00"] = "Carl Zeiss Makro-Planar T* 50mm f/2 ZF.2"; + lenses["00 54 55 55 0C 0C 00 00"] = "Voigtlander Nokton 58mm f/1.4 SLII"; + lenses["00 54 56 56 30 30 00 00"] = "Coastal Optical Systems 60mm f/4 UV-VIS-IR Macro Apo"; + lenses["00 54 62 62 0C 0C 00 00"] = "Carl Zeiss Planar T* 85mm f/1.4 ZF.2"; + lenses["00 54 68 68 18 18 00 00"] = "Carl Zeiss Makro-Planar T* 100mm f/2 ZF.2"; + lenses["00 54 68 68 24 24 00 02"] = "Tokina AT-X M100 PRO D 100mm f/2.8 Macro"; + lenses["00 54 8E 8E 24 24 00 02"] = "Tokina AT-X 300 PRO AF 300mm f/2.8"; + lenses["00 58 64 64 20 20 00 00"] = "Soligor C/D Macro MC 90mm f/2.5"; + lenses["01 00 00 00 00 00 02 00"] = "AF Teleconverter TC-16A 1.6x"; + lenses["01 00 00 00 00 00 08 00"] = "AF Teleconverter TC-16A 1.6x"; + lenses["01 58 50 50 14 14 02 00"] = "AF Nikkor 50mm f/1.8"; + lenses["02 2F 98 98 3D 3D 02 00"] = "Sigma APO 400mm f/5.6"; + lenses["02 34 A0 A0 44 44 02 00"] = "Sigma APO 500mm f/7.2"; + lenses["02 37 5E 8E 35 3D 02 00"] = "Sigma APO 75-300mm f/4.5-5.6"; + lenses["02 37 A0 A0 34 34 02 00"] = "Sigma APO 500mm f/4.5"; + lenses["02 3A 5E 8E 32 3D 02 00"] = "Sigma 75-300mm f/4-5.6"; + lenses["02 3B 44 61 30 3D 02 00"] = "Sigma 35-80mm f/4-5.6"; + lenses["02 3C B0 B0 3C 3C 02 00"] = "Sigma APO 800mm f/5.6"; + lenses["02 3F 24 24 2C 2C 02 00"] = "Sigma 14mm f/3.5"; + lenses["02 3F 3C 5C 2D 35 02 00"] = "Sigma 28-70mm f/3.5-4.5 UC"; + lenses["02 40 44 5C 2C 34 02 00"] = "Exakta AF 35-70mm f/3.5-4.5 MC"; + lenses["02 40 44 73 2B 36 02 00"] = "Sigma 35-135mm f/3.5-4.5 a"; + lenses["02 42 44 5C 2A 34 02 00"] = "AF Zoom-Nikkor 35-70mm f/3.3-4.5"; + lenses["02 42 44 5C 2A 34 08 00"] = "AF Zoom-Nikkor 35-70mm f/3.3-4.5"; + lenses["02 46 37 37 25 25 02 00"] = "Sigma 24mm f/2.8 Super Wide II Macro"; + lenses["02 46 3C 5C 25 25 02 00"] = "Sigma 28-70mm f/2.8"; + lenses["02 46 5C 82 25 25 02 00"] = "Sigma 70-210mm f/2.8 APO"; + lenses["02 48 50 50 24 24 02 00"] = "Sigma 50mm f/2.8 Macro"; + lenses["02 48 65 65 24 24 02 00"] = "Sigma 90mm f/2.8 Macro"; + lenses["03 43 5C 81 35 35 02 00"] = "Soligor AF C/D Zoom UMCS 70-210mm f/4.5"; + lenses["03 48 5C 81 30 30 02 00"] = "AF Zoom-Nikkor 70-210mm f/4"; + lenses["04 48 3C 3C 24 24 03 00"] = "AF Nikkor 28mm f/2.8"; + lenses["05 54 50 50 0C 0C 04 00"] = "AF Nikkor 50mm f/1.4"; + lenses["06 3F 68 68 2C 2C 06 00"] = "Cosina AF 100mm f/3.5 Macro"; + lenses["06 54 53 53 24 24 06 00"] = "AF Micro-Nikkor 55mm f/2.8"; + lenses["07 36 3D 5F 2C 3C 03 00"] = "Cosina AF Zoom 28-80mm f/3.5-5.6 MC Macro"; + lenses["07 3E 30 43 2D 35 03 00"] = "Soligor AF Zoom 19-35mm f/3.5-4.5 MC"; + lenses["07 40 2F 44 2C 34 03 02"] = "Tamron AF 19-35mm f/3.5-4.5 (A10)"; + lenses["07 40 30 45 2D 35 03 02"] = "Tamron AF 19-35mm f/3.5-4.5 (A10)"; + lenses["07 40 3C 5C 2C 35 03 00"] = "Tokina AF 270 II (AF 28-70mm f/3.5-4.5)"; + lenses["07 40 3C 62 2C 34 03 00"] = "AF Zoom-Nikkor 28-85mm f/3.5-4.5"; + lenses["07 46 2B 44 24 30 03 02"] = "Tamron SP AF 17-35mm f/2.8-4 Di LD Aspherical (IF) (A05)"; + lenses["07 46 3D 6A 25 2F 03 00"] = "Cosina AF Zoom 28-105mm f/2.8-3.8 MC"; + lenses["07 47 3C 5C 25 35 03 00"] = "Tokina AF 287 SD AF 28-70mm f/2.8-4.5"; + lenses["07 48 3C 5C 24 24 03 00"] = "Tokina AT-X 287 AF 28-70mm f/2.8"; + lenses["08 40 44 6A 2C 34 04 00"] = "AF Zoom-Nikkor 35-105mm f/3.5-4.5"; + lenses["09 48 37 37 24 24 04 00"] = "AF Nikkor 24mm f/2.8"; + lenses["0A 48 8E 8E 24 24 03 00"] = "AF Nikkor 300mm f/2.8 IF-ED"; + lenses["0A 48 8E 8E 24 24 05 00"] = "AF Nikkor 300mm f/2.8 IF-ED N"; + lenses["0B 3E 3D 7F 2F 3D 0E 00"] = "Tamron AF 28-200mm f/3.8-5.6 (71D)"; + lenses["0B 3E 3D 7F 2F 3D 0E 02"] = "Tamron AF 28-200mm f/3.8-5.6D (171D)"; + lenses["0B 48 7C 7C 24 24 05 00"] = "AF Nikkor 180mm f/2.8 IF-ED"; + lenses["0D 40 44 72 2C 34 07 00"] = "AF Zoom-Nikkor 35-135mm f/3.5-4.5"; + lenses["0E 48 5C 81 30 30 05 00"] = "AF Zoom-Nikkor 70-210mm f/4"; + lenses["0E 4A 31 48 23 2D 0E 02"] = "Tamron SP AF 20-40mm f/2.7-3.5 (166D)"; + lenses["0F 58 50 50 14 14 05 00"] = "AF Nikkor 50mm f/1.8 N"; + lenses["10 3D 3C 60 2C 3C D2 02"] = "Tamron AF 28-80mm f/3.5-5.6 Aspherical (177D)"; + lenses["10 48 8E 8E 30 30 08 00"] = "AF Nikkor 300mm f/4 IF-ED"; + lenses["11 48 44 5C 24 24 08 00"] = "AF Zoom-Nikkor 35-70mm f/2.8"; + lenses["12 36 5C 81 35 3D 09 00"] = "Cosina AF Zoom 70-210mm f/4.5-5.6 MC Macro"; + lenses["12 36 69 97 35 42 09 00"] = "Soligor AF Zoom 100-400mm f/4.5-6.7 MC"; + lenses["12 39 5C 8E 34 3D 08 02"] = "Cosina AF Zoom 70-300mm f/4.5-5.6 MC Macro"; + lenses["12 3B 68 8D 3D 43 09 02"] = "Cosina AF Zoom 100-300mm f/5.6-6.7 MC Macro"; + lenses["12 3B 98 98 3D 3D 09 00"] = "Tokina AT-X 400 SD AF 400mm f/5.6"; + lenses["12 3D 3C 80 2E 3C DF 02"] = "Tamron AF 28-200mm f/3.8-5.6 AF Aspherical LD (IF) (271D)"; + lenses["12 44 5E 8E 34 3C 09 00"] = "Tokina 730 AF 75-300mm f/4.5-5.6"; + lenses["12 48 5C 81 30 3C 09 00"] = "AF Nikkor 70-210mm f/4-5.6"; + lenses["12 4A 5C 81 31 3D 09 00"] = "Soligor AF C/D Auto Zoom+Macro 70-210mm f/4-5.6 UMCS"; + lenses["13 42 37 50 2A 34 0B 00"] = "AF Zoom-Nikkor 24-50mm f/3.3-4.5"; + lenses["14 48 60 80 24 24 0B 00"] = "AF Zoom-Nikkor 80-200mm f/2.8 ED"; + lenses["14 48 68 8E 30 30 0B 00"] = "Tokina AT-X 340 AF II 100-300mm f/4"; + lenses["14 54 60 80 24 24 0B 00"] = "Tokina AT-X 828 AF 80-200mm f/2.8"; + lenses["15 4C 62 62 14 14 0C 00"] = "AF Nikkor 85mm f/1.8"; + lenses["17 3C A0 A0 30 30 0F 00"] = "Nikkor 500mm f/4 P ED IF"; + lenses["17 3C A0 A0 30 30 11 00"] = "Nikkor 500mm f/4 P ED IF"; + lenses["18 40 44 72 2C 34 0E 00"] = "AF Zoom-Nikkor 35-135mm f/3.5-4.5 N"; + lenses["1A 54 44 44 18 18 11 00"] = "AF Nikkor 35mm f/2"; + lenses["1B 44 5E 8E 34 3C 10 00"] = "AF Zoom-Nikkor 75-300mm f/4.5-5.6"; + lenses["1C 48 30 30 24 24 12 00"] = "AF Nikkor 20mm f/2.8"; + lenses["1D 42 44 5C 2A 34 12 00"] = "AF Zoom-Nikkor 35-70mm f/3.3-4.5 N"; + lenses["1E 54 56 56 24 24 13 00"] = "AF Micro-Nikkor 60mm f/2.8"; + lenses["1E 5D 64 64 20 20 13 00"] = "Tamron SP AF 90mm f/2.5 (52E)"; + lenses["1F 54 6A 6A 24 24 14 00"] = "AF Micro-Nikkor 105mm f/2.8"; + lenses["20 3C 80 98 3D 3D 1E 02"] = "Tamron AF 200-400mm f/5.6 LD IF (75D)"; + lenses["20 48 60 80 24 24 15 00"] = "AF Zoom-Nikkor 80-200mm f/2.8 ED"; + lenses["20 5A 64 64 20 20 14 00"] = "Tamron SP AF 90mm f/2.5 Macro (152E)"; + lenses["21 40 3C 5C 2C 34 16 00"] = "AF Zoom-Nikkor 28-70mm f/3.5-4.5"; + lenses["21 56 8E 8E 24 24 14 00"] = "Tamron SP AF 300mm f/2.8 LD-IF (60E)"; + lenses["22 48 72 72 18 18 16 00"] = "AF DC-Nikkor 135mm f/2"; + lenses["22 53 64 64 24 24 E0 02"] = "Tamron SP AF 90mm f/2.8 Macro 1:1 (72E)"; + lenses["23 30 BE CA 3C 48 17 00"] = "Zoom-Nikkor 1200-1700mm f/5.6-8 P ED IF"; + lenses["24 44 60 98 34 3C 1A 02"] = "Tokina AT-X 840 AF II 80-400mm f/4.5-5.6"; + lenses["24 48 60 80 24 24 1A 02"] = "AF Zoom-Nikkor 80-200mm f/2.8D ED"; + lenses["24 54 60 80 24 24 1A 02"] = "Tokina AT-X 828 AF PRO 80-200mm f/2.8"; + lenses["25 44 44 8E 34 42 1B 02"] = "Tokina AF 353 (AF 35-300mm f/4.5-6.7)"; + lenses["25 48 3C 5C 24 24 1B 02"] = "Tokina AT-X 270 AF PRO II 28-70mm f/2.6-2.8"; + lenses["25 48 3C 5C 24 24 1B 02"] = "Tokina AT-X 287 AF PRO SV 28-70mm f/2.8"; + lenses["25 48 44 5C 24 24 1B 02"] = "AF Zoom-Nikkor 35-70mm f/2.8D"; + lenses["25 48 44 5C 24 24 52 02"] = "AF Zoom-Nikkor 35-70mm f/2.8D"; + lenses["26 3C 54 80 30 3C 1C 06"] = "Sigma 55-200mm f/4-5.6 DC"; + lenses["26 3C 5C 82 30 3C 1C 02"] = "Sigma 70-210mm f/4-5.6 UC-II"; + lenses["26 3C 5C 8E 30 3C 1C 02"] = "Sigma 70-300mm f/4-5.6 DG Macro"; + lenses["26 3C 98 98 3C 3C 1C 02"] = "Sigma APO Tele Macro 400mm f/5.6"; + lenses["26 3D 3C 80 2F 3D 1C 02"] = "Sigma 28-300mm f/3.8-5.6 Aspherical"; + lenses["26 3E 3C 6A 2E 3C 1C 02"] = "Sigma 28-105mm f/3.8-5.6 UC-III Aspherical IF"; + lenses["26 40 27 3F 2C 34 1C 02"] = "Sigma 15-30mm f/3.5-4.5 EX Aspherical DG DF"; + lenses["26 40 2D 44 2B 34 1C 02"] = "Sigma 18-35mm f/3.5-4.5 Aspherical"; + lenses["26 40 2D 50 2C 3C 1C 06"] = "Sigma 18-50mm f/3.5-5.6 DC"; + lenses["26 40 2D 70 2B 3C 1C 06"] = "Sigma 18-125mm f/3.5-5.6 DC"; + lenses["26 40 2D 80 2C 40 1C 06"] = "Sigma 18-200mm f/3.5-6.3 DC"; + lenses["26 40 37 5C 2C 3C 1C 02"] = "Sigma 24-70mm f/3.5-5.6 Aspherical HF"; + lenses["26 40 3C 5C 2C 34 1C 02"] = "AF Zoom-Nikkor 28-70mm f/3.5-4.5D"; + lenses["26 40 3C 60 2C 3C 1C 02"] = "Sigma 28-80mm f/3.5-5.6 Mini Zoom Macro II Aspherical"; + lenses["26 40 3C 65 2C 3C 1C 02"] = "Sigma 28-90mm f/3.5-5.6 Macro"; + lenses["26 40 3C 80 2B 3C 1C 02"] = "Sigma 28-200mm f/3.5-5.6 Compact Aspherical Hyperzoom Macro"; + lenses["26 40 3C 80 2C 3C 1C 02"] = "Sigma 28-200mm f/3.5-5.6 Compact Aspherical Hyperzoom Macro"; + lenses["26 40 3C 8E 2C 40 1C 02"] = "Sigma 28-300mm f/3.5-6.3 Macro"; + lenses["26 40 7B A0 34 40 1C 02"] = "Sigma APO 170-500mm f/5-6.3 Aspherical RF"; + lenses["26 41 3C 8E 2C 40 1C 02"] = "Sigma 28-300mm f/3.5-6.3 DG Macro"; + lenses["26 44 73 98 34 3C 1C 02"] = "Sigma 135-400mm f/4.5-5.6 APO Aspherical"; + lenses["26 48 11 11 30 30 1C 02"] = "Sigma 8mm f/4 EX Circular Fisheye"; + lenses["26 48 27 27 24 24 1C 02"] = "Sigma 15mm f/2.8 EX Diagonal Fish-Eye"; + lenses["26 48 2D 50 24 24 1C 06"] = "Sigma 18-50mm f/2.8 EX DC"; + lenses["26 48 31 49 24 24 1C 02"] = "Sigma 20-40mm f/2.8"; + lenses["26 48 37 56 24 24 1C 02"] = "Sigma 24-60mm f/2.8 EX DG"; + lenses["26 48 3C 5C 24 24 1C 06"] = "Sigma 28-70mm f/2.8 EX DG"; + lenses["26 48 3C 5C 24 30 1C 02"] = "Sigma 28-70mm f/2.8-4 DG High Speed Zoom"; + lenses["26 48 3C 6A 24 30 1C 02"] = "Sigma 28-105mm f/2.8-4 Aspherical"; + lenses["26 48 8E 8E 30 30 1C 02"] = "Sigma APO Tele Macro 300mm f/4"; + lenses["26 54 2B 44 24 30 1C 02"] = "Sigma 17-35mm f/2.8-4 EX Aspherical"; + lenses["26 54 37 5C 24 24 1C 02"] = "Sigma 24-70mm f/2.8 EX DG Macro"; + lenses["26 54 37 73 24 34 1C 02"] = "Sigma 24-135mm f/2.8-4.5"; + lenses["26 54 3C 5C 24 24 1C 02"] = "Sigma 28-70mm f/2.8 EX"; + lenses["26 58 31 31 14 14 1C 02"] = "Sigma 20mm f/1.8 EX Aspherical DG DF RF"; + lenses["26 58 37 37 14 14 1C 02"] = "Sigma 24mm f/1.8 EX Aspherical DG DF MACRO"; + lenses["26 58 3C 3C 14 14 1C 02"] = "Sigma 28mm f/1.8 EX DG DF"; + lenses["27 48 8E 8E 24 24 1D 02"] = "AF-I Nikkor 300mm f/2.8D IF-ED"; + lenses["27 48 8E 8E 24 24 E1 02"] = "AF-I Nikkor 300mm f/2.8D IF-ED + TC-17E"; + lenses["27 48 8E 8E 24 24 F1 02"] = "AF-I Nikkor 300mm f/2.8D IF-ED + TC-14E"; + lenses["27 48 8E 8E 24 24 F2 02"] = "AF-I Nikkor 300mm f/2.8D IF-ED + TC-20E"; + lenses["27 48 8E 8E 30 30 1D 02"] = "Tokina AT-X 304 AF 300mm f/4"; + lenses["27 54 8E 8E 24 24 1D 02"] = "Tamron SP AF 300mm f/2.8 LD-IF (360E)"; + lenses["28 3C A6 A6 30 30 1D 02"] = "AF-I Nikkor 600mm f/4D IF-ED"; + lenses["28 3C A6 A6 30 30 E1 02"] = "AF-I Nikkor 600mm f/4D IF-ED + TC-17E"; + lenses["28 3C A6 A6 30 30 F1 02"] = "AF-I Nikkor 600mm f/4D IF-ED + TC-14E"; + lenses["28 3C A6 A6 30 30 F2 02"] = "AF-I Nikkor 600mm f/4D IF-ED + TC-20E"; + lenses["2A 54 3C 3C 0C 0C 26 02"] = "AF Nikkor 28mm f/1.4D"; + lenses["2B 3C 44 60 30 3C 1F 02"] = "AF Zoom-Nikkor 35-80mm f/4-5.6D"; + lenses["2C 48 6A 6A 18 18 27 02"] = "AF DC-Nikkor 105mm f/2D"; + lenses["2D 48 80 80 30 30 21 02"] = "AF Micro-Nikkor 200mm f/4D IF-ED"; + lenses["2E 48 5C 82 30 3C 22 02"] = "AF Nikkor 70-210mm f/4-5.6D"; + lenses["2E 48 5C 82 30 3C 28 02"] = "AF Nikkor 70-210mm f/4-5.6D"; + lenses["2F 40 30 44 2C 34 29 02"] = "Tokina AF 235 II 20-35mm f/3.5-4.5"; + lenses["2F 40 30 44 2C 34 29 02"] = "Tokina AF 193 19-35mm f/3.5-4.5"; + lenses["2F 48 30 44 24 24 29 02"] = "AF Zoom-Nikkor 20-35mm f/2.8D IF"; + lenses["2F 48 30 44 24 24 29 02"] = "Tokina AT-X 235 AF PRO (AF 20-35mm f/2.8)"; + lenses["30 48 98 98 24 24 24 02"] = "AF-I Nikkor 400mm f/2.8D IF-ED"; + lenses["30 48 98 98 24 24 E1 02"] = "AF-I Nikkor 400mm f/2.8D IF-ED + TC-17E"; + lenses["30 48 98 98 24 24 F1 02"] = "AF-I Nikkor 400mm f/2.8D IF-ED + TC-14E"; + lenses["30 48 98 98 24 24 F2 02"] = "AF-I Nikkor 400mm f/2.8D IF-ED + TC-20E"; + lenses["31 54 56 56 24 24 25 02"] = "AF Micro-Nikkor 60mm f/2.8D"; + lenses["32 53 64 64 24 24 35 02"] = "Tamron SP AF 90mm f/2.8 Di Macro 1:1 (172E/272E)"; + lenses["32 54 50 50 24 24 35 02"] = "Sigma 50mm f/2.8 EX DG Macro"; + lenses["32 54 6A 6A 24 24 35 02"] = "AF Micro-Nikkor 105mm f/2.8D"; + lenses["32 54 6A 6A 24 24 35 02"] = "Sigma 105mm f/2.8 EX DG Macro"; + lenses["33 48 2D 2D 24 24 31 02"] = "AF Nikkor 18mm f/2.8D"; + lenses["33 54 3C 5E 24 24 62 02"] = "Tamron SP AF 28-75mm f/2.8 XR Di LD Aspherical (IF) Macro (A09)"; + lenses["34 48 29 29 24 24 32 02"] = "AF Fisheye Nikkor 16mm f/2.8D"; + lenses["35 3C A0 A0 30 30 33 02"] = "AF-I Nikkor 500mm f/4D IF-ED"; + lenses["35 3C A0 A0 30 30 E1 02"] = "AF-I Nikkor 500mm f/4D IF-ED + TC-17E"; + lenses["35 3C A0 A0 30 30 F1 02"] = "AF-I Nikkor 500mm f/4D IF-ED + TC-14E"; + lenses["35 3C A0 A0 30 30 F2 02"] = "AF-I Nikkor 500mm f/4D IF-ED + TC-20E"; + lenses["36 48 37 37 24 24 34 02"] = "AF Nikkor 24mm f/2.8D"; + lenses["37 48 30 30 24 24 36 02"] = "AF Nikkor 20mm f/2.8D"; + lenses["38 4C 62 62 14 14 37 02"] = "AF Nikkor 85mm f/1.8D"; + lenses["3A 40 3C 5C 2C 34 39 02"] = "AF Zoom-Nikkor 28-70mm f/3.5-4.5D"; + lenses["3B 48 44 5C 24 24 3A 02"] = "AF Zoom-Nikkor 35-70mm f/2.8D N"; + lenses["3C 48 60 80 24 24 3B 02"] = "AF Zoom-Nikkor 80-200mm f/2.8D ED"; + lenses["3D 3C 44 60 30 3C 3E 02"] = "AF Zoom-Nikkor 35-80mm f/4-5.6D"; + lenses["3E 48 3C 3C 24 24 3D 02"] = "AF Nikkor 28mm f/2.8D"; + lenses["3F 40 44 6A 2C 34 45 02"] = "AF Zoom-Nikkor 35-105mm f/3.5-4.5D"; + lenses["41 48 7C 7C 24 24 43 02"] = "AF Nikkor 180mm f/2.8D IF-ED"; + lenses["42 54 44 44 18 18 44 02"] = "AF Nikkor 35mm f/2D"; + lenses["43 54 50 50 0C 0C 46 02"] = "AF Nikkor 50mm f/1.4D"; + lenses["44 44 60 80 34 3C 47 02"] = "AF Zoom-Nikkor 80-200mm f/4.5-5.6D"; + lenses["45 3D 3C 60 2C 3C 48 02"] = "Tamron AF 28-80mm f/3.5-5.6 Aspherical (177D)"; + lenses["45 40 3C 60 2C 3C 48 02"] = "AF Zoom-Nikkor 28-80mm f/3.5-5.6D"; + lenses["45 41 37 72 2C 3C 48 02"] = "Tamron SP AF 24-135mm f/3.5-5.6 AD Aspherical (IF) Macro (190D)"; + lenses["46 3C 44 60 30 3C 49 02"] = "AF Zoom-Nikkor 35-80mm f/4-5.6D N"; + lenses["47 42 37 50 2A 34 4A 02"] = "AF Zoom-Nikkor 24-50mm f/3.3-4.5D"; + lenses["48 38 1F 37 34 3C 4B 06"] = "Sigma 12-24mm f/4.5-5.6 EX Aspherical DG HSM"; + lenses["48 3C 19 31 30 3C 4B 06"] = "Sigma 10-20mm f/4-5.6 EX DC HSM"; + lenses["48 3C 50 A0 30 40 4B 02"] = "Sigma 50-500mm f/4-6.3 EX APO RF HSM"; + lenses["48 3C 8E B0 3C 3C 4B 02"] = "Sigma APO 300-800mm f/5.6 EX DG HSM"; + lenses["48 3C B0 B0 3C 3C 4B 02"] = "Sigma APO 800mm f/5.6 EX HSM"; + lenses["48 44 A0 A0 34 34 4B 02"] = "Sigma APO 500mm f/4.5 EX HSM"; + lenses["48 48 24 24 24 24 4B 02"] = "Sigma 14mm f/2.8 EX Aspherical HSM"; + lenses["48 48 2B 44 24 30 4B 06"] = "Sigma 17-35mm f/2.8-4 EX DG Aspherical HSM"; + lenses["48 48 68 8E 30 30 4B 02"] = "Sigma 100-300mm f/4 EX IF HSM"; + lenses["48 48 76 76 24 24 4B 06"] = "Sigma 150mm f/2.8 EX DG APO Macro HSM"; + lenses["48 48 8E 8E 24 24 4B 02"] = "AF-S Nikkor 300mm f/2.8D IF-ED"; + lenses["48 48 8E 8E 24 24 E1 02"] = "AF-S Nikkor 300mm f/2.8D IF-ED + TC-17E"; + lenses["48 48 8E 8E 24 24 F1 02"] = "AF-S Nikkor 300mm f/2.8D IF-ED + TC-14E"; + lenses["48 48 8E 8E 24 24 F2 02"] = "AF-S Nikkor 300mm f/2.8D IF-ED + TC-20E"; + lenses["48 4C 7C 7C 2C 2C 4B 02"] = "Sigma 180mm f/3.5 EX DG Macro"; + lenses["48 4C 7D 7D 2C 2C 4B 02"] = "Sigma APO Macro 180mm f/3.5 EX DG HSM"; + lenses["48 54 3E 3E 0C 0C 4B 06"] = "Sigma 30mm f/1.4 EX DC HSM"; + lenses["48 54 5C 80 24 24 4B 02"] = "Sigma 70-200mm f/2.8 EX APO IF HSM"; + lenses["48 54 6F 8E 24 24 4B 02"] = "Sigma APO 120-300mm f/2.8 EX DG HSM"; + lenses["48 54 8E 8E 24 24 4B 02"] = "Sigma APO 300mm f/2.8 EX DG HSM"; + lenses["49 3C A6 A6 30 30 4C 02"] = "AF-S Nikkor 600mm f/4D IF-ED"; + lenses["49 3C A6 A6 30 30 E1 02"] = "AF-S Nikkor 600mm f/4D IF-ED + TC-17E"; + lenses["49 3C A6 A6 30 30 F1 02"] = "AF-S Nikkor 600mm f/4D IF-ED + TC-14E"; + lenses["49 3C A6 A6 30 30 F2 02"] = "AF-S Nikkor 600mm f/4D IF-ED + TC-20E"; + lenses["4A 40 11 11 2C 0C 4D 02"] = "Samyang 8mm f/3.5 Fish-Eye CS"; + lenses["4A 48 24 24 24 0C 4D 02"] = "Samyang AE 14mm f/2.8 ED AS IF UMC"; + lenses["4A 54 62 62 0C 0C 4D 02"] = "AF Nikkor 85mm f/1.4D IF"; + lenses["4A 60 44 44 0C 0C 4D 02"] = "Samyang 35mm f/1.4 AS UMC"; + lenses["4A 60 62 62 0C 0C 4D 02"] = "Samyang AE 85mm f/1.4 AS IF UMC"; + lenses["4B 3C A0 A0 30 30 4E 02"] = "AF-S Nikkor 500mm f/4D IF-ED"; + lenses["4B 3C A0 A0 30 30 E1 02"] = "AF-S Nikkor 500mm f/4D IF-ED + TC-17E"; + lenses["4B 3C A0 A0 30 30 F1 02"] = "AF-S Nikkor 500mm f/4D IF-ED + TC-14E"; + lenses["4B 3C A0 A0 30 30 F2 02"] = "AF-S Nikkor 500mm f/4D IF-ED + TC-20E"; + lenses["4C 40 37 6E 2C 3C 4F 02"] = "AF Zoom-Nikkor 24-120mm f/3.5-5.6D IF"; + lenses["4D 40 3C 80 2C 3C 62 02"] = "AF Zoom-Nikkor 28-200mm f/3.5-5.6D IF"; + lenses["4D 41 3C 8E 2B 40 62 02"] = "Tamron AF 28-300mm f/3.5-6.3 XR Di LD Aspherical (IF) (A061)"; + lenses["4D 41 3C 8E 2C 40 62 02"] = "Tamron AF 28-300mm f/3.5-6.3 XR LD Aspherical (IF) (185D)"; + lenses["4E 48 72 72 18 18 51 02"] = "AF DC-Nikkor 135mm f/2D"; + lenses["4F 40 37 5C 2C 3C 53 06"] = "IX-Nikkor 24-70mm f/3.5-5.6"; + lenses["50 48 56 7C 30 3C 54 06"] = "IX-Nikkor 60-180mm f/4-5.6"; + lenses["53 48 60 80 24 24 57 02"] = "AF Zoom-Nikkor 80-200mm f/2.8D ED"; + lenses["53 48 60 80 24 24 60 02"] = "AF Zoom-Nikkor 80-200mm f/2.8D ED"; + lenses["54 44 5C 7C 34 3C 58 02"] = "AF Zoom-Micro Nikkor 70-180mm f/4.5-5.6D ED"; + lenses["54 44 5C 7C 34 3C 61 02"] = "AF Zoom-Micro Nikkor 70-180mm f/4.5-5.6D ED"; + lenses["56 3C 5C 8E 30 3C 1C 02"] = "Sigma 70-300mm f/4-5.6 APO Macro Super II"; + lenses["56 48 5C 8E 30 3C 5A 02"] = "AF Zoom-Nikkor 70-300mm f/4-5.6D ED"; + lenses["59 48 98 98 24 24 5D 02"] = "AF-S Nikkor 400mm f/2.8D IF-ED"; + lenses["59 48 98 98 24 24 E1 02"] = "AF-S Nikkor 400mm f/2.8D IF-ED + TC-17E"; + lenses["59 48 98 98 24 24 F1 02"] = "AF-S Nikkor 400mm f/2.8D IF-ED + TC-14E"; + lenses["59 48 98 98 24 24 F2 02"] = "AF-S Nikkor 400mm f/2.8D IF-ED + TC-20E"; + lenses["5A 3C 3E 56 30 3C 5E 06"] = "IX-Nikkor 30-60mm f/4-5.6"; + lenses["5B 44 56 7C 34 3C 5F 06"] = "IX-Nikkor 60-180mm f/4.5-5.6"; + lenses["5D 48 3C 5C 24 24 63 02"] = "AF-S Zoom-Nikkor 28-70mm f/2.8D IF-ED"; + lenses["5E 48 60 80 24 24 64 02"] = "AF-S Zoom-Nikkor 80-200mm f/2.8D IF-ED"; + lenses["5F 40 3C 6A 2C 34 65 02"] = "AF Zoom-Nikkor 28-105mm f/3.5-4.5D IF"; + lenses["60 40 3C 60 2C 3C 66 02"] = "AF Zoom-Nikkor 28-80mm f/3.5-5.6D"; + lenses["61 44 5E 86 34 3C 67 02"] = "AF Zoom-Nikkor 75-240mm f/4.5-5.6D"; + lenses["63 48 2B 44 24 24 68 02"] = "AF-S Nikkor 17-35mm f/2.8D IF-ED"; + lenses["64 00 62 62 24 24 6A 02"] = "PC Micro-Nikkor 85mm f/2.8D"; + lenses["65 44 60 98 34 3C 6B 0A"] = "AF VR Zoom-Nikkor 80-400mm f/4.5-5.6D ED"; + lenses["66 40 2D 44 2C 34 6C 02"] = "AF Zoom-Nikkor 18-35mm f/3.5-4.5D IF-ED"; + lenses["67 48 37 62 24 30 6D 02"] = "AF Zoom-Nikkor 24-85mm f/2.8-4D IF"; + lenses["67 54 37 5C 24 24 1C 02"] = "Sigma 24-70mm f/2.8 EX DG Macro"; + lenses["68 42 3C 60 2A 3C 6E 06"] = "AF Zoom-Nikkor 28-80mm f/3.3-5.6G"; + lenses["69 47 5C 8E 30 3C 00 02"] = "Tamron AF 70-300mm f/4-5.6 Di LD Macro 1:2 (A17N)"; + lenses["69 48 5C 8E 30 3C 6F 02"] = "Tamron AF 70-300mm f/4-5.6 LD Macro 1:2 (772D)"; + lenses["69 48 5C 8E 30 3C 6F 06"] = "AF Zoom-Nikkor 70-300mm f/4-5.6G"; + lenses["6A 48 8E 8E 30 30 70 02"] = "AF-S Nikkor 300mm f/4D IF-ED"; + lenses["6B 48 24 24 24 24 71 02"] = "AF Nikkor ED 14mm f/2.8D"; + lenses["6D 48 8E 8E 24 24 73 02"] = "AF-S Nikkor 300mm f/2.8D IF-ED II"; + lenses["6E 48 98 98 24 24 74 02"] = "AF-S Nikkor 400mm f/2.8D IF-ED II"; + lenses["6F 3C A0 A0 30 30 75 02"] = "AF-S Nikkor 500mm f/4D IF-ED II"; + lenses["70 3C A6 A6 30 30 76 02"] = "AF-S Nikkor 600mm f/4D IF-ED II"; + lenses["72 48 4C 4C 24 24 77 00"] = "Nikkor 45mm f/2.8 P"; + lenses["74 40 37 62 2C 34 78 06"] = "AF-S Zoom-Nikkor 24-85mm f/3.5-4.5G IF-ED"; + lenses["75 40 3C 68 2C 3C 79 06"] = "AF Zoom-Nikkor 28-100mm f/3.5-5.6G"; + lenses["76 58 50 50 14 14 7A 02"] = "AF Nikkor 50mm f/1.8D"; + lenses["77 44 61 98 34 3C 7B 0E"] = "Sigma 80-400mm f/4.5-5.6 EX OS"; + lenses["77 48 5C 80 24 24 7B 0E"] = "AF-S VR Zoom-Nikkor 70-200mm f/2.8G IF-ED"; + lenses["78 40 37 6E 2C 3C 7C 0E"] = "AF-S VR Zoom-Nikkor 24-120mm f/3.5-5.6G IF-ED"; + lenses["79 40 11 11 2C 2C 1C 06"] = "Sigma 8mm f/3.5 EX Circular Fisheye"; + lenses["79 40 3C 80 2C 3C 7F 06"] = "AF Zoom-Nikkor 28-200mm f/3.5-5.6G IF-ED"; + lenses["79 48 5C 5C 24 24 1C 06"] = "Sigma 70mm f/2.8 EX DG Macro"; + lenses["7A 3B 53 80 30 3C 4B 06"] = "Sigma 55-200mm f/4-5.6 DC HSM"; + lenses["7A 3C 1F 37 30 30 7E 06"] = "AF-S DX Zoom-Nikkor 12-24mm f/4G IF-ED"; + lenses["7A 3C 1F 37 30 30 7E 06"] = "Tokina AT-X 124 AF PRO DX II (AF 12-24mm f/4)"; + lenses["7A 40 2D 50 2C 3C 4B 06"] = "Sigma 18-50mm f/3.5-5.6 DC HSM"; + lenses["7A 40 2D 80 2C 40 4B 0E"] = "Sigma 18-200mm f/3.5-6.3 DC OS HSM"; + lenses["7A 47 2B 5C 24 34 4B 06"] = "Sigma 17-70mm f/2.8-4.5 DC Macro Asp. IF HSM"; + lenses["7A 47 50 76 24 24 4B 06"] = "Sigma 50-150mm f/2.8 EX APO DC HSM"; + lenses["7A 48 2B 5C 24 34 4B 06"] = "Sigma 17-70mm f/2.8-4.5 DC Macro Asp. IF HSM"; + lenses["7A 48 2D 50 24 24 4B 06"] = "Sigma 18-50mm f/2.8 EX DC Macro"; + lenses["7A 48 5C 80 24 24 4B 06"] = "Sigma 70-200mm f/2.8 EX APO DG Macro HSM II"; + lenses["7A 54 6E 8E 24 24 4B 02"] = "Sigma APO 120-300mm f/2.8 EX DG HSM"; + lenses["7B 48 80 98 30 30 80 0E"] = "AF-S VR Zoom-Nikkor 200-400mm f/4G IF-ED"; + lenses["7D 48 2B 53 24 24 82 06"] = "AF-S DX Zoom-Nikkor 17-55mm f/2.8G IF-ED"; + lenses["7F 40 2D 5C 2C 34 84 06"] = "AF-S DX Zoom-Nikkor 18-70mm f/3.5-4.5G IF-ED"; + lenses["7F 48 2B 5C 24 34 1C 06"] = "Sigma 17-70mm f/2.8-4.5 DC Macro Asp. IF"; + lenses["7F 48 2D 50 24 24 1C 06"] = "Sigma 18-50mm f/2.8 EX DC Macro"; + lenses["80 48 1A 1A 24 24 85 06"] = "AF DX Fisheye-Nikkor 10.5mm f/2.8G ED"; + lenses["81 54 80 80 18 18 86 0E"] = "AF-S VR Nikkor 200mm f/2G IF-ED"; + lenses["82 48 8E 8E 24 24 87 0E"] = "AF-S VR Nikkor 300mm f/2.8G IF-ED"; + lenses["83 00 B0 B0 5A 5A 88 04"] = "FSA-L2 EDG 65 800mm f/13 G"; + lenses["89 3C 53 80 30 3C 8B 06"] = "AF-S DX Zoom-Nikkor 55-200mm f/4-5.6G ED"; + lenses["8A 54 6A 6A 24 24 8C 0E"] = "AF-S VR Micro-Nikkor 105mm f/2.8G IF-ED"; + lenses["8B 40 2D 80 2C 3C 8D 0E"] = "AF-S DX VR Zoom-Nikkor 18-200mm f/3.5-5.6G IF-ED"; + lenses["8B 40 2D 80 2C 3C FD 0E"] = "AF-S DX VR Zoom-Nikkor 18-200mm f/3.5-5.6G IF-ED [II]"; + lenses["8C 40 2D 53 2C 3C 8E 06"] = "AF-S DX Zoom-Nikkor 18-55mm f/3.5-5.6G ED"; + lenses["8D 44 5C 8E 34 3C 8F 0E"] = "AF-S VR Zoom-Nikkor 70-300mm f/4.5-5.6G IF-ED"; + lenses["8E 3C 2B 5C 24 30 4B 0E"] = "Sigma 17-70mm f/2.8-4 DC Macro OS HSM Contemporary"; + lenses["8F 40 2D 72 2C 3C 91 06"] = "AF-S DX Zoom-Nikkor 18-135mm f/3.5-5.6G IF-ED"; + lenses["90 3B 53 80 30 3C 92 0E"] = "AF-S DX VR Zoom-Nikkor 55-200mm f/4-5.6G IF-ED"; + lenses["91 54 44 44 0C 0C 4B 06"] = "Sigma 35mm f/1.4 DG HSM | A"; + lenses["92 2C 2D 88 2C 40 4B 0E"] = "Sigma 18-250mm f/3.5-6.3 DC Macro OS HSM"; + lenses["92 48 24 37 24 24 94 06"] = "AF-S Zoom-Nikkor 14-24mm f/2.8G ED"; + lenses["93 48 37 5C 24 24 95 06"] = "AF-S Zoom-Nikkor 24-70mm f/2.8G ED"; + lenses["94 40 2D 53 2C 3C 96 06"] = "AF-S DX Zoom-Nikkor 18-55mm f/3.5-5.6G ED II"; + lenses["95 00 37 37 2C 2C 97 06"] = "PC-E Nikkor 24mm f/3.5D ED"; + lenses["95 4C 37 37 2C 2C 97 02"] = "PC-E Nikkor 24mm f/3.5D ED"; + lenses["96 38 1F 37 34 3C 4B 06"] = "Sigma 12-24mm f/4.5-5.6 II DG HSM"; + lenses["96 48 98 98 24 24 98 0E"] = "AF-S VR Nikkor 400mm f/2.8G ED"; + lenses["97 3C A0 A0 30 30 99 0E"] = "AF-S VR Nikkor 500mm f/4G ED"; + lenses["98 3C A6 A6 30 30 9A 0E"] = "AF-S VR Nikkor 600mm f/4G ED"; + lenses["99 40 29 62 2C 3C 9B 0E"] = "AF-S DX VR Zoom-Nikkor 16-85mm f/3.5-5.6G ED"; + lenses["9A 40 2D 53 2C 3C 9C 0E"] = "AF-S DX VR Zoom-Nikkor 18-55mm f/3.5-5.6G"; + lenses["9B 00 4C 4C 24 24 9D 06"] = "PC-E Micro Nikkor 45mm f/2.8D ED"; + lenses["9B 54 4C 4C 24 24 9D 02"] = "PC-E Micro Nikkor 45mm f/2.8D ED"; + lenses["9B 54 62 62 0C 0C 4B 06"] = "Sigma 85mm f/1.4 EX DG HSM"; + lenses["9C 48 5C 80 24 24 4B 0E"] = "Sigma 70-200mm f/2.8 EX DG OS HSM"; + lenses["9C 54 56 56 24 24 9E 06"] = "AF-S Micro Nikkor 60mm f/2.8G ED"; + lenses["9D 00 62 62 24 24 9F 06"] = "PC-E Micro Nikkor 85mm f/2.8D"; + lenses["9D 48 2B 50 24 24 4B 0E"] = "Sigma 17-50mm f/2.8 EX DC OS HSM"; + lenses["9D 54 62 62 24 24 9F 02"] = "PC-E Micro Nikkor 85mm f/2.8D"; + lenses["9E 38 11 29 34 3C 4B 06"] = "Sigma 8-16mm f/4.5-5.6 DC HSM"; + lenses["9E 40 2D 6A 2C 3C A0 0E"] = "AF-S DX VR Zoom-Nikkor 18-105mm f/3.5-5.6G ED"; + lenses["9F 37 50 A0 34 40 4B 0E"] = "Sigma 50-500mm f/4.5-6.3 DG OS HSM"; + lenses["9F 58 44 44 14 14 A1 06"] = "AF-S DX Nikkor 35mm f/1.8G"; + lenses["A0 48 2A 5C 24 30 4B 0E"] = "Sigma 17-70mm f/2.8-4 DC Macro OS HSM"; + lenses["26 40 2D 44 2B 34 1C 02"] = "Sigma 18-35mm f/3.5-4.5 Aspherical"; + lenses["8B 4C 2D 44 14 14 4B 06"] = "Sigma 18-35mm f/1.8 DC HSM"; + lenses["A0 54 50 50 0C 0C A2 06"] = "AF-S Nikkor 50mm f/1.4G"; + lenses["A1 40 18 37 2C 34 A3 06"] = "AF-S DX Nikkor 10-24mm f/3.5-4.5G ED"; + lenses["A1 41 19 31 2C 2C 4B 06"] = "Sigma 10-20mm f/3.5 EX DC HSM"; + lenses["A2 48 5C 80 24 24 A4 0E"] = "AF-S Nikkor 70-200mm f/2.8G ED VR II"; + lenses["A3 3C 29 44 30 30 A5 0E"] = "AF-S Nikkor 16-35mm f/4G ED VR"; + lenses["A3 3C 5C 8E 30 3C 4B 0E"] = "Sigma 70-300mm f/4-5.6 DG OS"; + lenses["A4 47 2D 50 24 34 4B 0E"] = "Sigma 18-50mm f/2.8-4.5 DC OS HSM"; + lenses["A4 54 37 37 0C 0C A6 06"] = "AF-S Nikkor 24mm f/1.4G ED"; + lenses["A5 40 2D 88 2C 40 4B 0E"] = "Sigma 18-250mm f/3.5-6.3 DC OS HSM"; + lenses["A5 40 3C 8E 2C 3C A7 0E"] = "AF-S Nikkor 28-300mm f/3.5-5.6G ED VR"; + lenses["A6 48 37 5C 24 24 4B 06"] = "Sigma 24-70mm f/2.8 IF EX DG HSM"; + lenses["A6 48 8E 8E 24 24 A8 0E"] = "AF-S VR Nikkor 300mm f/2.8G IF-ED II"; + lenses["A7 49 80 A0 24 24 4B 06"] = "Sigma APO 200-500mm f/2.8 EX DG"; + lenses["A7 4B 62 62 2C 2C A9 0E"] = "AF-S DX Micro Nikkor 85mm f/3.5G ED VR"; + lenses["A8 48 80 98 30 30 AA 0E"] = "AF-S VR Zoom-Nikkor 200-400mm f/4G IF-ED II"; + lenses["A9 54 80 80 18 18 AB 0E"] = "AF-S Nikkor 200mm f/2G ED VR II"; + lenses["AA 3C 37 6E 30 30 AC 0E"] = "AF-S Nikkor 24-120mm f/4G ED VR"; + lenses["AC 38 53 8E 34 3C AE 0E"] = "AF-S DX VR Nikkor 55-300mm f/4.5-5.6G ED"; + lenses["AD 3C 2D 8E 2C 3C AF 0E"] = "AF-S DX Nikkor 18-300mm 3.5-5.6G ED VR"; + lenses["AE 54 62 62 0C 0C B0 06"] = "AF-S Nikkor 85mm f/1.4G"; + lenses["AF 54 44 44 0C 0C B1 06"] = "AF-S Nikkor 35mm f/1.4G"; + lenses["B0 4C 50 50 14 14 B2 06"] = "AF-S Nikkor 50mm f/1.8G"; + lenses["B1 48 48 48 24 24 B3 06"] = "AF-S DX Micro Nikkor 40mm f/2.8G"; + lenses["B2 48 5C 80 30 30 B4 0E"] = "AF-S Nikkor 70-200mm f/4G ED VR"; + lenses["B3 4C 62 62 14 14 B5 06"] = "AF-S Nikkor 85mm f/1.8G"; + lenses["B4 40 37 62 2C 34 B6 0E"] = "AF-S VR Zoom-Nikkor 24-85mm f/3.5-4.5G IF-ED"; + lenses["B5 4C 3C 3C 14 14 B7 06"] = "AF-S Nikkor 28mm f/1.8G"; + lenses["B6 48 37 56 24 24 1C 02"] = "Sigma 24-60mm f/2.8 EX DG"; + lenses["B7 44 60 98 34 3C B9 0E"] = "AF-S Nikkor 80-400mm f/4.5-5.6G ED VR"; + lenses["B8 40 2D 44 2C 34 BA 06"] = "AF-S Nikkor 18-35mm f/3.5-4.5G ED"; + lenses["CD 3D 2D 70 2E 3C 4B 0E"] = "Sigma 18-125mm f/3.8-5.6 DC OS HSM"; + lenses["CE 34 76 A0 38 40 4B 0E"] = "Sigma 150-500mm f/5-6.3 DG OS APO HSM"; + lenses["CF 38 6E 98 34 3C 4B 0E"] = "Sigma APO 120-400mm f/4.5-5.6 DG OS HSM"; + lenses["DC 48 19 19 24 24 4B 06"] = "Sigma 10mm f/2.8 EX DC HSM Fisheye"; + lenses["DE 54 50 50 0C 0C 4B 06"] = "Sigma 50mm f/1.4 EX DG HSM"; + lenses["D8 48 5C 5C 24 24 1C 06"] = "Sigma 70mm f/2.8 EX DG Macro"; + lenses["E0 3C 5C 8E 30 3C 4B 06"] = "Sigma 70-300mm f/4-5.6 APO DG Macro HSM"; + lenses["E1 58 37 37 14 14 1C 02"] = "Sigma 24mm f/1.8 EX DG Aspherical Macro"; + lenses["E3 54 50 50 24 24 35 02"] = "Sigma 50mm f/2.8 EX DG Macro"; + lenses["E5 54 6A 6A 24 24 35 02"] = "Sigma 105mm f/2.8 EX DG Macro"; + lenses["E6 41 3C 8E 2C 40 1C 02"] = "Sigma 28-300mm f/3.5-6.3 DG Macro"; + lenses["E9 54 37 5C 24 24 1C 02"] = "Sigma 24-70mm f/2.8 EX DG Macro"; + lenses["ED 40 2D 80 2C 40 4B 0E"] = "Sigma 18-200mm f/3.5-6.3 DC OS HSM"; + lenses["EE 48 5C 80 24 24 4B 06"] = "Sigma 70-200mm f/2.8 EX APO DG Macro HSM II"; + lenses["F0 38 1F 37 34 3C 4B 06"] = "Sigma 12-24mm f/4.5-5.6 EX DG Aspherical HSM"; + lenses["F0 3F 2D 8A 2C 40 DF 0E"] = "Tamron AF 18-270mm f/3.5-6.3 Di II VC PZD (B008)"; + lenses["F1 44 A0 A0 34 34 4B 02"] = "Sigma APO 500mm f/4.5 EX DG HSM"; + lenses["F1 47 5C 8E 30 3C DF 0E"] = "Tamron SP 70-300mm f/4-5.6 Di VC USD (A005)"; + lenses["F3 48 68 8E 30 30 4B 02"] = "Sigma APO 100-300mm f/4 EX IF HSM"; + lenses["F3 54 2B 50 24 24 84 0E"] = "Tamron SP AF 17-50mm f/2.8 XR Di II VC LD Aspherical (IF) (B005)"; + lenses["F4 54 56 56 18 18 84 06"] = "Tamron SP AF 60mm f/2.0 Di II Macro 1:1 (G005)"; + lenses["F5 40 2C 8A 2C 40 40 0E"] = "Tamron AF 18-270mm f/3.5-6.3 Di II VC LD Aspherical (IF) Macro (B003)"; + lenses["F5 48 76 76 24 24 4B 06"] = "Sigma 150mm f/2.8 EX DG APO Macro HSM"; + lenses["F6 3F 18 37 2C 34 84 06"] = "Tamron SP AF 10-24mm f/3.5-4.5 Di II LD Aspherical (IF) (B001)"; + lenses["F6 48 2D 50 24 24 4B 06"] = "Sigma 18-50mm f/2.8 EX DC Macro"; + lenses["F7 53 5C 80 24 24 40 06"] = "Tamron SP AF 70-200mm f/2.8 Di LD (IF) Macro (A001)"; + lenses["F7 53 5C 80 24 24 84 06"] = "Tamron SP AF 70-200mm f/2.8 Di LD (IF) Macro (A001)"; + lenses["F8 54 3E 3E 0C 0C 4B 06"] = "Sigma 30mm f/1.4 EX DC HSM"; + lenses["F8 54 64 64 24 24 DF 06"] = "Tamron SP AF 90mm f/2.8 Di Macro 1:1 (272NII)"; + lenses["F8 55 64 64 24 24 84 06"] = "Tamron SP AF 90mm f/2.8 Di Macro 1:1 (272NII)"; + lenses["F9 3C 19 31 30 3C 4B 06"] = "Sigma 10-20mm f/4-5.6 EX DC HSM"; + lenses["F9 40 3C 8E 2C 40 40 0E"] = "Tamron AF 28-300mm f/3.5-6.3 XR Di VC LD Aspherical (IF) Macro (A20)"; + lenses["FA 54 3C 5E 24 24 84 06"] = "Tamron SP AF 28-75mm f/2.8 XR Di LD Aspherical (IF) Macro (A09NII)"; + lenses["FA 54 3C 5E 24 24 DF 06"] = "Tamron SP AF 28-75mm f//2.8 XR Di LD Aspherical (IF) Macro (A09NII)"; + lenses["FA 54 6E 8E 24 24 4B 02"] = "Sigma APO 120-300mm f/2.8 EX DG HSM"; + lenses["FB 54 2B 50 24 24 84 06"] = "Tamron SP AF 17-50mm f/2.8 XR Di II LD Aspherical (IF) (A16NII)"; + lenses["FB 54 8E 8E 24 24 4B 02"] = "Sigma APO 300mm f/2.8 EX DG HSM"; + lenses["FC 40 2D 80 2C 40 DF 06"] = "Tamron AF 18-200mm f/3.5-6.3 XR Di II LD Aspherical (IF) Macro (A14NII)"; + lenses["FD 47 50 76 24 24 4B 06"] = "Sigma 50-150mm f/2.8 EX APO DC HSM II"; + lenses["FE 47 00 00 24 24 4B 06"] = "Sigma 4.5mm f/2.8 EX DC HSM Circular Fisheye"; + lenses["FE 48 37 5C 24 24 DF 0E"] = "Tamron SP 24-70mm f/2.8 Di VC USD"; + lenses["FE 53 5C 80 24 24 84 06"] = "Tamron SP AF 70-200mm f/2.8 Di LD (IF) Macro (A001)"; + lenses["FE 54 5C 80 24 24 DF 0E"] = "Tamron SP AF 70-200mm f//2.8 Di VC USD (A009)"; + lenses["FE 54 64 64 24 24 DF 0E"] = "Tamron SP 90mm f/2.8 Di VC USD Macro 1:1"; + } + virtual std::string toString (Tag* t) { + + static const unsigned char xlat[2][256] = { + { 0xc1,0xbf,0x6d,0x0d,0x59,0xc5,0x13,0x9d,0x83,0x61,0x6b,0x4f,0xc7,0x7f,0x3d,0x3d, + 0x53,0x59,0xe3,0xc7,0xe9,0x2f,0x95,0xa7,0x95,0x1f,0xdf,0x7f,0x2b,0x29,0xc7,0x0d, + 0xdf,0x07,0xef,0x71,0x89,0x3d,0x13,0x3d,0x3b,0x13,0xfb,0x0d,0x89,0xc1,0x65,0x1f, + 0xb3,0x0d,0x6b,0x29,0xe3,0xfb,0xef,0xa3,0x6b,0x47,0x7f,0x95,0x35,0xa7,0x47,0x4f, + 0xc7,0xf1,0x59,0x95,0x35,0x11,0x29,0x61,0xf1,0x3d,0xb3,0x2b,0x0d,0x43,0x89,0xc1, + 0x9d,0x9d,0x89,0x65,0xf1,0xe9,0xdf,0xbf,0x3d,0x7f,0x53,0x97,0xe5,0xe9,0x95,0x17, + 0x1d,0x3d,0x8b,0xfb,0xc7,0xe3,0x67,0xa7,0x07,0xf1,0x71,0xa7,0x53,0xb5,0x29,0x89, + 0xe5,0x2b,0xa7,0x17,0x29,0xe9,0x4f,0xc5,0x65,0x6d,0x6b,0xef,0x0d,0x89,0x49,0x2f, + 0xb3,0x43,0x53,0x65,0x1d,0x49,0xa3,0x13,0x89,0x59,0xef,0x6b,0xef,0x65,0x1d,0x0b, + 0x59,0x13,0xe3,0x4f,0x9d,0xb3,0x29,0x43,0x2b,0x07,0x1d,0x95,0x59,0x59,0x47,0xfb, + 0xe5,0xe9,0x61,0x47,0x2f,0x35,0x7f,0x17,0x7f,0xef,0x7f,0x95,0x95,0x71,0xd3,0xa3, + 0x0b,0x71,0xa3,0xad,0x0b,0x3b,0xb5,0xfb,0xa3,0xbf,0x4f,0x83,0x1d,0xad,0xe9,0x2f, + 0x71,0x65,0xa3,0xe5,0x07,0x35,0x3d,0x0d,0xb5,0xe9,0xe5,0x47,0x3b,0x9d,0xef,0x35, + 0xa3,0xbf,0xb3,0xdf,0x53,0xd3,0x97,0x53,0x49,0x71,0x07,0x35,0x61,0x71,0x2f,0x43, + 0x2f,0x11,0xdf,0x17,0x97,0xfb,0x95,0x3b,0x7f,0x6b,0xd3,0x25,0xbf,0xad,0xc7,0xc5, + 0xc5,0xb5,0x8b,0xef,0x2f,0xd3,0x07,0x6b,0x25,0x49,0x95,0x25,0x49,0x6d,0x71,0xc7 }, + { 0xa7,0xbc,0xc9,0xad,0x91,0xdf,0x85,0xe5,0xd4,0x78,0xd5,0x17,0x46,0x7c,0x29,0x4c, + 0x4d,0x03,0xe9,0x25,0x68,0x11,0x86,0xb3,0xbd,0xf7,0x6f,0x61,0x22,0xa2,0x26,0x34, + 0x2a,0xbe,0x1e,0x46,0x14,0x68,0x9d,0x44,0x18,0xc2,0x40,0xf4,0x7e,0x5f,0x1b,0xad, + 0x0b,0x94,0xb6,0x67,0xb4,0x0b,0xe1,0xea,0x95,0x9c,0x66,0xdc,0xe7,0x5d,0x6c,0x05, + 0xda,0xd5,0xdf,0x7a,0xef,0xf6,0xdb,0x1f,0x82,0x4c,0xc0,0x68,0x47,0xa1,0xbd,0xee, + 0x39,0x50,0x56,0x4a,0xdd,0xdf,0xa5,0xf8,0xc6,0xda,0xca,0x90,0xca,0x01,0x42,0x9d, + 0x8b,0x0c,0x73,0x43,0x75,0x05,0x94,0xde,0x24,0xb3,0x80,0x34,0xe5,0x2c,0xdc,0x9b, + 0x3f,0xca,0x33,0x45,0xd0,0xdb,0x5f,0xf5,0x52,0xc3,0x21,0xda,0xe2,0x22,0x72,0x6b, + 0x3e,0xd0,0x5b,0xa8,0x87,0x8c,0x06,0x5d,0x0f,0xdd,0x09,0x19,0x93,0xd0,0xb9,0xfc, + 0x8b,0x0f,0x84,0x60,0x33,0x1c,0x9b,0x45,0xf1,0xf0,0xa3,0x94,0x3a,0x12,0x77,0x33, + 0x4d,0x44,0x78,0x28,0x3c,0x9e,0xfd,0x65,0x57,0x16,0x94,0x6b,0xfb,0x59,0xd0,0xc8, + 0x22,0x36,0xdb,0xd2,0x63,0x98,0x43,0xa1,0x04,0x87,0x86,0xf7,0xa6,0x26,0xbb,0xd6, + 0x59,0x4d,0xbf,0x6a,0x2e,0xaa,0x2b,0xef,0xe6,0x78,0xb6,0x4e,0xe0,0x2f,0xdc,0x7c, + 0xbe,0x57,0x19,0x32,0x7e,0x2a,0xd0,0xb8,0xba,0x29,0x00,0x3c,0x52,0x7d,0xa8,0x49, + 0x3b,0x2d,0xeb,0x25,0x49,0xfa,0xa3,0xaa,0x39,0xa7,0xc5,0xa7,0x50,0x11,0x36,0xfb, + 0xc6,0x67,0x4a,0xf5,0xa5,0x12,0x65,0x7e,0xb0,0xdf,0xaf,0x4e,0xb3,0x61,0x7f,0x2f } }; + + int ver = (t->toInt (0, BYTE) - '0') * 1000 + (t->toInt (1, BYTE) - '0') * 100 + (t->toInt (2, BYTE) - '0') * 10 + (t->toInt (3, BYTE) - '0'); + + std::ostringstream ld; + ld << "Version = " << ver << std::endl; + + int lenstype = t->getParent()->getTag(0x0083)->toInt(0,BYTE); + + std::ostringstream lid; + lid.setf (std::ios_base::hex, std::ios_base::basefield); + lid.setf (std::ios_base::uppercase); + + Tag *modelTag = t->getParent()->getRoot()->findTag("Model"); + std::string model( modelTag? modelTag->valueToString():""); + int lidoffs = 7; + bool d100 = false; + if (model.substr(0,10)=="NIKON D100" || model.substr(0,9)=="NIKON D1X") { + lidoffs = 0; + d100 = true; + }else if( ver<204){ + lidoffs = 7; + d100 = false; + }else{ + lidoffs = 8; + d100 = false; + } + + unsigned char buffer[16]; + if (d100) + memcpy (buffer, t->getValue()+6, 7); + else + memcpy (buffer, t->getValue()+4, 16); + + if (ver>=201) { + const unsigned char* serval = t->getParent()->getTag(0x001d)->getValue (); + int serial = 0; + for (int i=0; serval[i]; i++) + serial = serial*10 + (isdigit(serval[i]) ? serval[i] - '0' : serval[i] % 10); + const unsigned char* scval = t->getParent()->getTag(0x00a7)->getValue (); + int key = 0; + for (int i=0; i<4; i++) + key ^= scval[i]; + + unsigned char ci = xlat[0][serial & 0xff]; + unsigned char cj = xlat[1][key]; + unsigned char ck = 0x60; + for (int i=0; i < 16; i++) + buffer[i] ^= (cj += ci * ck++); + } + + std::string EffectiveMaxApertureString = ""; + if (!d100) { + int EffectiveMaxApertureValue; + if( ver<204 ){ + ld << "ExitPupilPosition = " << (int) buffer[0] << std::endl; + ld << "AFAperture = " << (int) buffer[1] << std::endl; + ld << "FocusPosition = " << (int) buffer[4] << std::endl; + ld << "FocusDistance = " << (int) buffer[5] << std::endl; + ld << "FocalLength = " << (int) buffer[6] << std::endl; + EffectiveMaxApertureValue = (int) buffer[14]; + }else{ + ld << "ExitPupilPosition = " << (int) buffer[0] << std::endl; + ld << "AFAperture = " << (int) buffer[1] << std::endl; + ld << "FocusPosition = " << (int) buffer[4] << std::endl; + ld << "FocusDistance = " << (int) buffer[6] << std::endl; + ld << "FocalLength = " << (int) buffer[7] << std::endl; + EffectiveMaxApertureValue = (int) buffer[15]; + } + switch (EffectiveMaxApertureValue) { + case 0x8: EffectiveMaxApertureString = "1.2";break; + case 0xc: EffectiveMaxApertureString = "1.4";break; + case 0x14: EffectiveMaxApertureString = "1.8";break; + case 0x18: EffectiveMaxApertureString = "2.0";break; + case 0x20: EffectiveMaxApertureString = "2.5";break; + case 0x24: EffectiveMaxApertureString = "2.8";break; + case 0x2a: EffectiveMaxApertureString = "3.3";break; + case 0x2c: EffectiveMaxApertureString = "3.5";break; + case 0x30: EffectiveMaxApertureString = "4.0";break; + case 0x34: EffectiveMaxApertureString = "4.5";break; + case 0x38: EffectiveMaxApertureString = "5.0";break; + case 0x3c: EffectiveMaxApertureString = "5.6";break; + case 0x40: EffectiveMaxApertureString = "6.3";break; + case 0x44: EffectiveMaxApertureString = "7.1";break; + case 0x48: EffectiveMaxApertureString = "8.0";break; + case 0x4e: EffectiveMaxApertureString = "9.5";break; + case 0x54: EffectiveMaxApertureString = "11.0";break; + case 0x5a: EffectiveMaxApertureString = "13.0";break; + case 0x5e: EffectiveMaxApertureString = "15.0";break; + case 0x60: EffectiveMaxApertureString = "16.0";break; + case 0x66: EffectiveMaxApertureString = "19.0";break; + case 0x6c: EffectiveMaxApertureString = "22.0";break; + default : EffectiveMaxApertureString = ""; + } + ld << "EffectiveMaxAperture = " << EffectiveMaxApertureString << std::endl; + } + + for (int i=0; i<7; i++) + lid << std::setw(2) << std::setfill('0') << (int)buffer[lidoffs+i] << ' '; + lid << std::setw(2) << std::setfill('0') << lenstype; + + std::map::iterator r = lenses.find (lid.str()); + if (r!=lenses.end()){ + if(r==lenses.begin() && EffectiveMaxApertureString != "") // first entry is for unchipped lenses + ld << "Lens = Unknown $FL$mm f/" << EffectiveMaxApertureString; + else + ld << "Lens = " << r->second; + } + else + ld << "Lens = Unknown, ID=" << lid.str(); + + return ld.str(); + } + +}; +NALensDataInterpreter naLensDataInterpreter; + +const TagAttrib nikonISOInfoAttribs[] = { + {0, AC_WRITE, 0, 0, 0x0000, AUTO, "ISO", &naISOInfoISOInterpreter}, + {0, AC_WRITE, 0, 0, 0x0004, SHORT, "ISOExpansion", &naISOExpansionInterpreter}, + {0, AC_WRITE, 0, 0, 0x0006, AUTO, "ISO2", &naISOInfoISOInterpreter}, + {0, AC_WRITE, 0, 0, 0x000a, SHORT, "ISOExpansion2", &naISOExpansionInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}}; + +const TagAttrib nikon2Attribs[] = { + {0, AC_WRITE, 0, 0, 0x0002, AUTO, "Unknown", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0003, AUTO, "Quality", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0004, AUTO, "ColorMode", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0005, AUTO, "ImageAdjustment", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0006, AUTO, "ISOSpeed", &naISOInterpreter}, + {0, AC_WRITE, 0, 0, 0x0007, AUTO, "WhiteBalance", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0008, AUTO, "Focus", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0009, AUTO, "Unknown", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x000a, AUTO, "DigitalZoom", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x000b, AUTO, "AuxiliaryLens", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0f00, AUTO, "Unknown", &stdInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}}; + +const TagAttrib nikon3Attribs[] = { + {0, AC_WRITE, 0, 0, 0x0001, AUTO, "MakerNoteVersion", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0002, AUTO, "ISOSpeed", &naISOInterpreter}, + {0, AC_WRITE, 0, 0, 0x0003, AUTO, "ColorMode", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0004, AUTO, "Quality", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0005, AUTO, "WhiteBalance", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0006, AUTO, "Sharpness", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0007, AUTO, "FocusMode", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0008, AUTO, "FlashSetting", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0009, AUTO, "FlashType", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x000b, AUTO, "WhiteBalanceFineTune", &stdInterpreter}, + {0, AC_NEW, 0, 0, 0x000c, AUTO, "ColorBalance1", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x000d, AUTO, "ProgramShift", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x000e, AUTO, "ExposureDifference", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x000f, AUTO, "ISOSelection", &naISOInterpreter}, + {0, AC_WRITE, 0, 0, 0x0010, AUTO, "DataDump", &stdInterpreter}, + {1, AC_WRITE, 0, 0, 0x0011, AUTO, "NikonPreview", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0012, AUTO, "FlashExposureComp", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0013, AUTO, "ISOSetting", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0016, AUTO, "ImageBoundary", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0018, AUTO, "FlashExposureBracketValue", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0019, AUTO, "ExposureBracketValue", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x001a, AUTO, "ImageProcessing", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x001b, AUTO, "CropHiSpeed", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x001d, AUTO, "SerialNumber", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x001e, AUTO, "ColorSpace", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0020, AUTO, "ImageAuthentication", &stdInterpreter}, + {0, AC_WRITE, 0, nikonISOInfoAttribs, 0x0025, AUTO, "ISOInfo", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0080, AUTO, "ImageAdjustment", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0081, AUTO, "ToneComp", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0082, AUTO, "AuxiliaryLens", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0083, AUTO, "LensType", &naLensTypeInterpreter}, + {0, AC_WRITE, 0, 0, 0x0084, AUTO, "Lens", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0085, AUTO, "ManualFocusDistance", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0086, AUTO, "DigitalZoom", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0087, AUTO, "FlashMode", &naFlashModeInterpreter}, + {0, AC_WRITE, 0, 0, 0x0088, AUTO, "AFInfo", &naAFInfoInterpreter}, + {0, AC_WRITE, 0, 0, 0x0089, AUTO, "ShootingMode", &naShootingModeInterpreter}, + {0, AC_WRITE, 0, 0, 0x008a, AUTO, "AutoBracketRelease", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x008b, AUTO, "LensFStops", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x008c, AUTO, "NEFCurve1", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x008d, AUTO, "ColorHue", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x008f, AUTO, "SceneMode", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0090, AUTO, "LightSource", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0091, AUTO, "ShotInfo", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0092, AUTO, "HueAdjustment", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0094, AUTO, "Saturation", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0095, AUTO, "NoiseReduction", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0096, AUTO, "NEFCurve2", &stdInterpreter}, + {0, AC_NEW, 0, 0, 0x0097, AUTO, "ColorBalance", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0098, AUTO, "LensData", &naLensDataInterpreter}, + {0, AC_WRITE, 0, 0, 0x0099, AUTO, "RawImageCenter", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x009a, AUTO, "SensorPixelSize", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x00a0, AUTO, "SerialNumber", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x00a2, AUTO, "ImageDataSize", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x00a5, AUTO, "ImageCount", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x00a6, AUTO, "DeletedImageCount", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x00a7, AUTO, "ShutterCount", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x00a9, AUTO, "ImageOptimization", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x00aa, AUTO, "Saturation", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x00ab, AUTO, "VariProgram", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x00ac, AUTO, "ImageStabilization", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x00ad, AUTO, "AFResponse", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x00b0, AUTO, "MultiExposure", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x00b1, AUTO, "HighISONoiseReduction", &naHiISONRInterpreter}, + {0, AC_WRITE, 0, 0, 0x0e00, AUTO, "PrintIM", &stdInterpreter}, + {0, AC_DONTWRITE, 0, 0, 0x0e01, AUTO, "NikonCaptureData", &stdInterpreter}, + {0, AC_DONTWRITE, 0, 0, 0x0e09, AUTO, "NikonCaptureVersion", &stdInterpreter}, + {0, AC_DONTWRITE, 0, 0, 0x0e0e, AUTO, "NikonCaptureOffsets", &stdInterpreter}, + {0, AC_DONTWRITE, 0, 0, 0x0e10, AUTO, "NikonScanIFD", &stdInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}}; + +} +#endif + diff --git a/rtexif/olympusattribs.cc b/rtexif/olympusattribs.cc new file mode 100644 index 000000000..d858b64f0 --- /dev/null +++ b/rtexif/olympusattribs.cc @@ -0,0 +1,736 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _OLYMPUSATTRIBS_ +#define _OLYMPUSATTRIBS_ + +#include +#include +#include +#include + +#include "rtexif.h" + +namespace rtexif { + +class OLOnOffInterpreter : public Interpreter { + public: + OLOnOffInterpreter () {} + virtual std::string toString (Tag* t) { + if (t->toInt()==0) + return "Off"; + else + return "On"; + } +}; +OLOnOffInterpreter olOnOffInterpreter; + +class OLYesNoInterpreter : public Interpreter { + public: + OLYesNoInterpreter () {} + virtual std::string toString (Tag* t) { + if (t->toInt()==0) + return "No"; + else + return "Yes"; + } +}; +OLYesNoInterpreter olYesNoInterpreter; + +class OLApertureInterpreter : public Interpreter { + public: + OLApertureInterpreter () {} + virtual std::string toString (Tag* t) { + std::ostringstream str; + str.precision(2); + str << pow(2, t->toInt() / 512.0); + return str.str(); + } +}; +OLApertureInterpreter olApertureInterpreter; + +class OLLensTypeInterpreter : public Interpreter { + std::map lenses; + public: + OLLensTypeInterpreter () { // From EXIFTOOL database 'Olympus.pm' V2.09 + // exadecimal bytes + lenses["00 01 00"] = "Zuiko Digital ED 50mm f/2 Macro"; + lenses["00 01 01"] = "Zuiko Digital 40-150mm f/3.5-4.5"; + lenses["00 01 10"] = "Zuiko Digital ED 14-42mm f/3.5-5.6"; + lenses["00 02 00"] = "Zuiko Digital ED 150mm f/2"; + lenses["00 02 10"] = "Zuiko Digital 17mm f/2.8 Pancake"; + lenses["00 03 00"] = "Zuiko Digital ED 300mm f/2.8"; + lenses["00 03 10"] = "Zuiko Digital ED 14-150mm f/4-5.6"; + lenses["00 04 10"] = "Zuiko Digital ED 9-18mm f/4-5.6"; + lenses["00 05 00"] = "Zuiko Digital 14-54mm f/2.8-3.5"; + lenses["00 05 01"] = "Zuiko Digital Pro ED 90-250mm f/2.8"; + lenses["00 05 10"] = "Zuiko Digital ED 14-42mm f/3.5-5.6 L"; + lenses["00 06 00"] = "Zuiko Digital ED 50-200mm f/2.8-3.5"; + lenses["00 06 01"] = "Zuiko Digital ED 8mm f/3.5 Fisheye"; + lenses["00 06 10"] = "Zuiko Digital ED 40-150mm f/4-5.6"; + lenses["00 07 00"] = "Zuiko Digital 11-22mm f/2.8-3.5"; + lenses["00 07 01"] = "Zuiko Digital 18-180mm f/3.5-6.3"; + lenses["00 07 10"] = "Zuiko Digital ED 12mm f/2"; + lenses["00 08 01"] = "Zuiko Digital 70-300mm f/4-5.6"; + lenses["00 08 10"] = "Zuiko Digital ED 75-300mm f/4.8-6.7"; + lenses["00 09 10"] = "Zuiko Digital 14-42mm f/3.5-5.6 II"; + lenses["00 10 01"] = "Kenko Tokina Reflex 300mm f/6.3 MF Macro"; + lenses["00 10 10"] = "Zuiko Digital ED 12-50mm f/3.5-6.3 EZ"; + lenses["00 11 10"] = "Zuiko Digital 45mm f/1.8"; + lenses["00 12 10"] = "Zuiko Digital ED 60mm f/2.8 Macro"; + lenses["00 13 10"] = "Zuiko Digital ED 14-42mm f/3.5-5.6 II R"; + lenses["00 14 10"] = "Zuiko Digital ED 40-150mm f/4-5.6 R"; + lenses["00 15 00"] = "Zuiko Digital ED 7-14mm f/4"; + lenses["00 15 10"] = "Zuiko Digital ED 75mm f/1.8"; + lenses["00 16 10"] = "Zuiko Digital 17mm f/1.8"; + lenses["00 17 00"] = "Zuiko Digital Pro ED 35-100mm f/2"; + lenses["00 18 00"] = "Zuiko Digital 14-45mm f/3.5-5.6"; + lenses["00 18 10"] = "Zuiko Digital ED 75-300mm f/4.8-6.7 II"; + lenses["00 19 10"] = "Zuiko Digital ED 12-40mm f/2.8 Pro"; + lenses["00 20 00"] = "Zuiko Digital 35mm f/3.5 Macro"; + lenses["00 22 00"] = "Zuiko Digital 17.5-45mm f/3.5-5.6"; + lenses["00 23 00"] = "Zuiko Digital ED 14-42mm f/3.5-5.6"; + lenses["00 24 00"] = "Zuiko Digital ED 40-150mm f/4-5.6"; + lenses["00 30 00"] = "Zuiko Digital ED 50-200mm f/2.8-3.5 SWD"; + lenses["00 31 00"] = "Zuiko Digital ED 12-60mm f/2.8-4 SWD"; + lenses["00 32 00"] = "Zuiko Digital ED 14-35mm f/2 SWD"; + lenses["00 33 00"] = "Zuiko Digital 25mm f/2.8"; + lenses["00 34 00"] = "Zuiko Digital ED 9-18mm f/4-5.6"; + lenses["00 35 00"] = "Zuiko Digital 14-54mm f/2.8-3.5 II"; + lenses["01 01 00"] = "Sigma 18-50mm f/3.5-5.6 DC"; + lenses["01 01 10"] = "Sigma 30mm f/2.8 EX DN"; + lenses["01 02 00"] = "Sigma 55-200mm f/4-5.6 DC"; + lenses["01 02 10"] = "Sigma 19mm f/2.8 EX DN"; + lenses["01 03 00"] = "Sigma 18-125mm f/3.5-5.6 DC"; + lenses["01 03 10"] = "Sigma 30mm f/2.8 DN | A"; + lenses["01 04 00"] = "Sigma 18-125mm f/3.5-5.6 DC"; + lenses["01 04 10"] = "Sigma 19mm f/2.8 DN | A"; + lenses["01 05 00"] = "Sigma 30mm f/1.4 EX DC HSM"; + lenses["01 05 10"] = "Sigma 60mm f/2.8 DN | A"; + lenses["01 06 00"] = "Sigma 50-500mm f/4-6.3 EX DG APO HSM RF"; + lenses["01 07 00"] = "Sigma 105mm f/2.8 EX DG Macro"; + lenses["01 08 00"] = "Sigma 150mm f/2.8 EX DG APO HSM Macro"; + lenses["01 09 00"] = "Sigma 18-50mm f/2.8 EX DC Macro"; + lenses["01 10 00"] = "Sigma 24mm f/1.8 EX DG Aspherical Macro"; + lenses["01 11 00"] = "Sigma 135-400mm f/4.5-5.6 DG APO"; + lenses["01 12 00"] = "Sigma 300-800mm f/5.6 EX DG APO HSM"; + lenses["01 13 00"] = "Sigma 30mm f/1.4 EX DC HSM"; + lenses["01 14 00"] = "Sigma 50-500mm f/4-6.3 EX DG APO HSM"; + lenses["01 15 00"] = "Sigma 10-20mm f/4-5.6 EX DC HSM"; + lenses["01 16 00"] = "Sigma 70-200mm f/2.8 II EX DG APO HSM Macro"; + lenses["01 17 00"] = "Sigma 50mm f/1.4 EX DG HSM"; + lenses["02 01 00"] = "Leica D Vario Elmarit 14-50mm f/2.8-3.5 Asph."; + lenses["02 01 10"] = "Lumix G Vario 14-45mm f/3.5-5.6 Asph. Mega OIS"; + lenses["02 02 00"] = "Leica D Summilux 25mm f/1.4 Asph."; + lenses["02 02 10"] = "Lumix G Vario 45-200mm f/4-5.6 Mega OIS"; + lenses["02 03 00"] = "Leica D Vario Elmar 14-50mm f/3.8-5.6 Asph. Mega OIS"; + lenses["02 03 01"] = "Leica D Vario Elmar 14-50mm f/3.8-5.6 Asph."; + lenses["02 03 10"] = "Lumix G Vario HD 14-140mm f/4-5.8 Asph. Mega OIS"; + lenses["02 04 00"] = "Leica D Vario Elmar 14-150mm f/3.5-5.6"; + lenses["02 04 10"] = "Lumix G Vario 7-14mm f/4 Asph."; + lenses["02 05 10"] = "Lumix G 20mm f/1.7 Asph."; + lenses["02 06 10"] = "Leica DG Macro-Elmarit 45mm f/2.8 Asph. Mega OIS"; + lenses["02 07 10"] = "Lumix G Vario 14-42mm f/3.5-5.6 Asph. Mega OIS"; + lenses["02 08 10"] = "Lumix G Fisheye 8mm f/3.5"; + lenses["02 09 10"] = "Lumix G Vario 100-300mm f/4-5.6 Mega OIS"; + lenses["02 10 10"] = "Lumix G 14mm f/2.5 Asph."; + lenses["02 11 10"] = "Lumix G 12.5mm f/12 3D"; + lenses["02 12 10"] = "Leica DG Summilux 25mm f/1.4 Asph."; + lenses["02 13 10"] = "Lumix G X Vario PZ 45-175mm f/4-5.6 Asph. Power OIS"; + lenses["02 14 10"] = "Lumix G X Vario PZ 14-42mm f/3.5-5.6 Asph. Power OIS"; + lenses["02 15 10"] = "Lumix G X Vario 12-35mm f/2.8 Asph. Power OIS"; + lenses["02 16 10"] = "Lumix G Vario 45-150mm f/4-5.6 Asph. Mega OIS"; + lenses["02 17 10"] = "Lumix G X Vario 35-100mm f/2.8 Power OIS"; + lenses["02 18 10"] = "Lumix G Vario 14-42mm f/3.5-5.6 II Asph. Mega OIS"; + lenses["02 19 10"] = "Lumix G Vario 14-140mm f/3.5-5.6 Asph. Power OIS"; + lenses["03 01 00"] = "Leica D Vario Elmarit 14-50mm f/2.8-3.5 Asph."; + lenses["03 02 00"] = "Leica D Summilux 25mm f/1.4 Asph."; + } + virtual std::string toString (Tag* t) { + std::ostringstream lid; + lid.setf (std::ios_base::hex, std::ios_base::basefield); + lid.setf (std::ios_base::uppercase); + lid << std::setw(2) << std::setfill('0') << t->toInt(0)<< ' '; //maker + lid << std::setw(2) << std::setfill('0') << t->toInt(2)<< ' '; //model + lid << std::setw(2) << std::setfill('0') << t->toInt(3); // submodel + + std::map::iterator r = lenses.find (lid.str()); + if (r!=lenses.end()) + return r->second; + else + return "Unknown"; + } +}; +OLLensTypeInterpreter olLensTypeInterpreter; + +class OLFlashTypeInterpreter : public ChoiceInterpreter { + public: + OLFlashTypeInterpreter () { + choices[0] = "None"; + choices[2] = "Simple E-System"; + choices[3] = "E-System"; + } +}; +OLFlashTypeInterpreter olFlashTypeInterpreter; + +class OLExposureModeInterpreter : public ChoiceInterpreter { + public: + OLExposureModeInterpreter () { + choices[1] = "Manual"; + choices[2] = "Program"; + choices[3] = "Aperture-priority AE"; + choices[4] = "Shutter speed priority AE"; + choices[5] = "Program-shift"; + } +}; +OLExposureModeInterpreter olExposureModeInterpreter; + +class OLMeteringModeInterpreter : public ChoiceInterpreter { + public: + OLMeteringModeInterpreter () { + choices[2] = "Center-weighted average"; + choices[3] = "Spot"; + choices[5] = "ESP"; + choices[261] = "Pattern+AF"; + choices[515] = "Spot+Highlight control"; + choices[1027] = "Spot+Shadow control"; + } +}; +OLMeteringModeInterpreter olMeteringModeInterpreter; + +class OLFocusModeInterpreter : public ChoiceInterpreter { + public: + OLFocusModeInterpreter () { + choices[0] = "Single AF"; + choices[1] = "Sequential shooting AF"; + choices[2] = "Continuous AF"; + choices[3] = "Multi AF"; + choices[10] = "MF"; + } +}; +OLFocusModeInterpreter olFocusModeInterpreter; + +class OLWhitebalance2Interpreter : public ChoiceInterpreter { + public: + OLWhitebalance2Interpreter () { + choices[0] = "Auto"; + choices[16] = "7500K (Fine Weather with Shade)"; + choices[17] = "6000K (Cloudy)"; + choices[18] = "5300K (Fine Weather)"; + choices[20] = "3000K (Tungsten light)"; + choices[21] = "3600K (Tungsten light-like)"; + choices[33] = "6600K (Daylight fluorescent)"; + choices[34] = "4500K (Neutral white fluorescent)"; + choices[35] = "4000K (Cool white fluorescent)"; + choices[48] = "3600K (Tungsten light-like)"; + choices[256] = "Custom WB 1"; + choices[257] = "Custom WB 2"; + choices[258] = "Custom WB 3"; + choices[259] = "Custom WB 4"; + choices[512] = "Custom WB 5400K"; + choices[513] = "Custom WB 2900K"; + choices[514] = "Custom WB 8000K"; + } +}; +OLWhitebalance2Interpreter olWhitebalance2Interpreter; + +class OLSceneModeInterpreter : public ChoiceInterpreter { + public: + OLSceneModeInterpreter () { + choices[0] = "Standard"; + choices[6] = "Auto"; + choices[7] = "Sport"; + choices[8] = "Portrait"; + choices[9] = "Landscape+Portrait"; + choices[10] = "Landscape"; + choices[11] = "Night Scene"; + choices[12] = "Self Portrait"; + choices[13] = "Panorama"; + choices[14] = "2 in 1"; + choices[15] = "Movie"; + choices[16] = "Landscape+Portrait"; + choices[17] = "Night+Portrait"; + choices[18] = "Indoor"; + choices[19] = "Fireworks"; + choices[20] = "Sunset"; + choices[22] = "Macro"; + choices[23] = "Super Macro"; + choices[24] = "Food"; + choices[25] = "Documents"; + choices[26] = "Museum"; + choices[27] = "Shoot & Select"; + choices[28] = "Beach & Snow"; + choices[29] = "Self Protrait+Timer"; + choices[30] = "Candle"; + choices[31] = "Available Light"; + choices[32] = "Behind Glass"; + choices[33] = "My Mode"; + choices[34] = "Pet"; + choices[35] = "Underwater Wide1"; + choices[36] = "Underwater Macro"; + choices[37] = "Shoot & Select1"; + choices[38] = "Shoot & Select2"; + choices[39] = "High Key"; + choices[40] = "Digital Image Stabilization"; + choices[41] = "Auction"; + choices[42] = "Beach"; + choices[43] = "Snow"; + choices[44] = "Underwater Wide2"; + choices[45] = "Low Key"; + choices[46] = "Children"; + choices[47] = "Vivid"; + choices[48] = "Nature Macro"; + choices[49] = "Underwater Snapshot"; + choices[50] = "Shooting Guide"; + } +}; +OLSceneModeInterpreter olSceneModeInterpreter; + +class OLPictureModeBWFilterInterpreter : public ChoiceInterpreter { + public: + OLPictureModeBWFilterInterpreter () { + choices[0] = "n/a"; + choices[1] = "Neutral"; + choices[2] = "Yellow"; + choices[3] = "Orange"; + choices[4] = "Red"; + choices[5] = "Green"; + } +}; +OLPictureModeBWFilterInterpreter olPictureModeBWFilterInterpreter; + +class OLPictureModeToneInterpreter : public ChoiceInterpreter { + public: + OLPictureModeToneInterpreter () { + choices[0] = "n/a"; + choices[1] = "Neutral"; + choices[2] = "Sepia"; + choices[3] = "Blue"; + choices[4] = "Purple"; + choices[5] = "Green"; + } +}; +OLPictureModeToneInterpreter olPictureModeToneInterpreter; + +class OLImageQuality2Interpreter : public ChoiceInterpreter { + public: + OLImageQuality2Interpreter () { + choices[1] = "SQ"; + choices[2] = "HQ"; + choices[3] = "SHQ"; + choices[4] = "RAW"; + } +}; +OLImageQuality2Interpreter olImageQuality2Interpreter; + +class OLDevEngineInterpreter : public ChoiceInterpreter { + public: + OLDevEngineInterpreter () { + choices[0] = "High Speed"; + choices[1] = "High Function"; + choices[2] = "Advanced High Speed"; + choices[3] = "Advanced High Function"; + } +}; +OLDevEngineInterpreter olDevEngineInterpreter; + +class OLPictureModeInterpreter : public ChoiceInterpreter { + public: + OLPictureModeInterpreter () { + choices[1] = "Vivid"; + choices[2] = "Natural"; + choices[3] = "Muted"; + choices[4] = "Portrait"; + choices[256] = "Monotone"; + choices[512] = "Sepia"; + } +}; +OLPictureModeInterpreter olPictureModeInterpreter; + +class OLColorSpaceInterpreter : public ChoiceInterpreter { + public: + OLColorSpaceInterpreter () { + choices[0] = "sRGB"; + choices[1] = "Adobe RGB"; + choices[2] = "Pro Photo RGB"; + } +}; +OLColorSpaceInterpreter olColorSpaceInterpreter; + +class OLNoiseFilterInterpreter : public Interpreter { + public: + OLNoiseFilterInterpreter () {} + virtual std::string toString (Tag* t) { + int a = t->toInt (0); + int b = t->toInt (2); + int c = t->toInt (4); + if (a==-1 && b==-2 && c==1) + return "Low"; + else if (a==-2 && b==-2 && c==1) + return "Off"; + else if (a==0 && b==-2 && c==1) + return "Standard"; + else if (a==1 && b==-2 && c==1) + return "High"; + else return "Unknown"; + } +}; +OLNoiseFilterInterpreter olNoiseFilterInterpreter; + +class OLFlashModeInterpreter : public Interpreter { + public: + OLFlashModeInterpreter () {} + virtual std::string toString (Tag* t) { + std::ostringstream str; + int a = t->toInt (); + str << "Flash Used = " << ((a&1) ? "Yes" : "No") << std::endl; + str << "Fill-in = " << ((a&2) ? "On" : "Off") << std::endl; + str << "Red-eye = " << ((a&4) ? "On" : "Off") << std::endl; + str << "Slow-sync = " << ((a&8) ? "On" : "Off") << std::endl; + str << "Forced On = " << ((a&16) ? "On" : "Off") << std::endl; + str << "2nd Curtain = " << ((a&32) ? "On" : "Off"); + return str.str(); + } +}; +OLFlashModeInterpreter olFlashModeInterpreter; + +class OLNoiseReductionInterpreter : public Interpreter { + public: + OLNoiseReductionInterpreter () {} + virtual std::string toString (Tag* t) { + std::ostringstream str; + int a = t->toInt (); + str << "Noise Reduction = " << ((a&1) ? "On" : "Off") << std::endl; + str << "Noise Filter = " << ((a&2) ? "On" : "Off") << std::endl; + str << "Noise Filter (ISO Boost) = " << ((a&4) ? "On" : "Off"); + return str.str(); + } +}; +OLNoiseReductionInterpreter olNoiseReductionInterpreter; + +class OLFlashModelInterpreter : public ChoiceInterpreter { + public: + OLFlashModelInterpreter () { + choices[0] = "None"; + choices[1] = "FL-20"; + choices[2] = "FL-50"; + choices[3] = "RF-11"; + choices[4] = "TF-22"; + choices[5] = "FL-36"; + choices[6] = "FL-50R"; + choices[7] = "FL-36R"; + } +}; +OLFlashModelInterpreter olFlashModelInterpreter; + +const TagAttrib olyFocusInfoAttribs[] = { + {0, AC_WRITE, 0, 0, 0x0000, AUTO, "FocusInfoVersion", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0209, AUTO, "AutoFocus", &olOnOffInterpreter}, + {0, AC_WRITE, 0, 0, 0x0210, AUTO, "SceneDetect", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0211, AUTO, "SceneArea", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0212, AUTO, "SceneDetectData", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0300, AUTO, "ZoomStepCount", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0301, AUTO, "FocusStepCount", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0303, AUTO, "FocusStepInfinity", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0304, AUTO, "FocusStepNear", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0305, AUTO, "FocusDistance", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0308, AUTO, "AFPoint", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1201, AUTO, "ExternalFlash", &olOnOffInterpreter}, + {0, AC_WRITE, 0, 0, 0x1203, AUTO, "ExternalFlashGuideNumber", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1204, AUTO, "ExternalFlashBounce", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1205, AUTO, "ExternalFlashZoom", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1208, AUTO, "InternalFlash", &olOnOffInterpreter}, + {0, AC_WRITE, 0, 0, 0x1209, AUTO, "ManualFlash", &olOnOffInterpreter}, + {0, AC_WRITE, 0, 0, 0x1500, AUTO, "SensorTemperature", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1600, AUTO, "ImageStabilization", &stdInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}}; + +const TagAttrib olyImageProcessingAttribs[] = { + {0, AC_WRITE, 0, 0, 0x0000, AUTO, "ImageProcessingVersion", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0100, AUTO, "WB_RBLevels", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0102, AUTO, "WB_RBLevels3000K", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0103, AUTO, "WB_RBLevels3300K", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0104, AUTO, "WB_RBLevels3600K", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0105, AUTO, "WB_RBLevels3900K", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0106, AUTO, "WB_RBLevels4000K", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0107, AUTO, "WB_RBLevels4300K", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0108, AUTO, "WB_RBLevels4500K", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0109, AUTO, "WB_RBLevels4800K", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x010a, AUTO, "WB_RBLevels5300K", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x010b, AUTO, "WB_RBLevels6000K", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x010c, AUTO, "WB_RBLevels6600K", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x010d, AUTO, "WB_RBLevels7500K", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x010e, AUTO, "WB_RBLevelsCWB1", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x010f, AUTO, "WB_RBLevelsCWB2", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0110, AUTO, "WB_RBLevelsCWB3", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0111, AUTO, "WB_RBLevelsCWB4", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0113, AUTO, "WB_GLevel3000K", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0114, AUTO, "WB_GLevel3300K", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0115, AUTO, "WB_GLevel3600K", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0116, AUTO, "WB_GLevel3900K", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0117, AUTO, "WB_GLevel4000K", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0118, AUTO, "WB_GLevel4300K", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0119, AUTO, "WB_GLevel4500K", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x011a, AUTO, "WB_GLevel4800K", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x011b, AUTO, "WB_GLevel5300K", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x011c, AUTO, "WB_GLevel6000K", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x011d, AUTO, "WB_GLevel6600K", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x011e, AUTO, "WB_GLevel7500K", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x011f, AUTO, "WB_GLevel", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0200, AUTO, "ColorMatrix", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0300, AUTO, "Enhancer", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0301, AUTO, "EnhancerValues", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0310, AUTO, "CoringFilter", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0311, AUTO, "CoringValues", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0600, AUTO, "BlackLevel2", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0610, AUTO, "GainBase", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0611, AUTO, "ValidBits", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0612, AUTO, "CropLeft", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0613, AUTO, "CropTop", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0614, AUTO, "CropWidth", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0615, AUTO, "CropHeight", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1010, AUTO, "NoiseReduction2", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1011, AUTO, "DistortionCorrection2", &olOnOffInterpreter}, + {0, AC_WRITE, 0, 0, 0x1012, AUTO, "ShadingCompensation2", &olOnOffInterpreter}, + {1, AC_WRITE, 0, 0, 0x1103, AUTO, "UnknownBlock", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1200, AUTO, "FaceDetect", &olOnOffInterpreter}, + {0, AC_WRITE, 0, 0, 0x1201, AUTO, "FaceDetectArea", &stdInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}}; + +const TagAttrib olyRawDevelopmentAttribs[] = { + {0, AC_WRITE, 0, 0, 0x0000, AUTO, "RawDevVersion", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0100, AUTO, "RawDevExposureBiasValue", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0101, AUTO, "RawDevWhiteBalanceValue", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0102, AUTO, "RawDevWBFineAdjustment", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0103, AUTO, "RawDevGrayPoint", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0104, AUTO, "RawDevSaturationEmphasis", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0105, AUTO, "RawDevMemoryColorEmphasis", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0106, AUTO, "RawDevContrastValue", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0107, AUTO, "RawDevSharpnessValue", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0108, AUTO, "RawDevColorSpace", &olColorSpaceInterpreter}, + {0, AC_WRITE, 0, 0, 0x0109, AUTO, "RawDevEngine", &olDevEngineInterpreter}, + {0, AC_WRITE, 0, 0, 0x010a, AUTO, "RawDevNoiseReduction", &olNoiseReductionInterpreter}, + {0, AC_WRITE, 0, 0, 0x010b, AUTO, "RawDevEditStatus", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x010c, AUTO, "RawDevSettings", &stdInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}}; + +const TagAttrib olyRawDevelopment2Attribs[] = { + {0, AC_WRITE, 0, 0, 0x0000, AUTO, "RawDevVersion", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0100, AUTO, "RawDevExposureBiasValue", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0101, AUTO, "RawDevWhiteBalance", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0102, AUTO, "RawDevWhiteBalanceValue", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0103, AUTO, "RawDevWBFineAdjustment", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0104, AUTO, "RawDevGrayPoint", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0105, AUTO, "RawDevContrastValue", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0106, AUTO, "RawDevSharpnessValue", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0107, AUTO, "RawDevSaturationEmphasis", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0108, AUTO, "RawDevMemoryColorEmphasis", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0109, AUTO, "RawDevColorSpace", &olColorSpaceInterpreter}, + {0, AC_WRITE, 0, 0, 0x010a, AUTO, "RawDevNoiseReduction", &olNoiseReductionInterpreter}, + {0, AC_WRITE, 0, 0, 0x010b, AUTO, "RawDevEngine", &olDevEngineInterpreter}, + {0, AC_WRITE, 0, 0, 0x010c, AUTO, "RawDevPictureMode", &olPictureModeInterpreter}, + {0, AC_WRITE, 0, 0, 0x010d, AUTO, "RawDevPMSaturation", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x010e, AUTO, "RawDevPMContrast", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x010f, AUTO, "RawDevPMSharpness", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0110, AUTO, "RawDevPM_BWFilter", &olPictureModeBWFilterInterpreter}, + {0, AC_WRITE, 0, 0, 0x0111, AUTO, "RawDevPMPictureTone", &olPictureModeToneInterpreter}, + {0, AC_WRITE, 0, 0, 0x0112, AUTO, "RawDevGradation", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0113, AUTO, "RawDevSaturation3", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0119, AUTO, "RawDevAutoGradation", &olOnOffInterpreter}, + {0, AC_WRITE, 0, 0, 0x0120, AUTO, "RawDevPMNoiseFilter", &stdInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}}; + +const TagAttrib olyCameraSettingsAttribs[] = { + {0, AC_WRITE, 0, 0, 0x0000, AUTO, "CameraSettingsVersion", &stdInterpreter}, + {1, AC_WRITE, 0, 0, 0x0100, AUTO, "PreviewImageValid", &olYesNoInterpreter}, + {1, AC_WRITE, 0, 0, 0x0101, AUTO, "PreviewImageStart", &stdInterpreter}, + {1, AC_WRITE, 0, 0, 0x0102, AUTO, "PreviewImageLength", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0200, AUTO, "ExposureMode", &olExposureModeInterpreter}, + {0, AC_WRITE, 0, 0, 0x0201, AUTO, "AELock", &olOnOffInterpreter}, + {0, AC_WRITE, 0, 0, 0x0202, AUTO, "MeteringMode", &olMeteringModeInterpreter}, + {0, AC_WRITE, 0, 0, 0x0300, AUTO, "MacroMode", &olOnOffInterpreter}, + {0, AC_WRITE, 0, 0, 0x0301, AUTO, "FocusMode", &olFocusModeInterpreter}, + {0, AC_WRITE, 0, 0, 0x0302, AUTO, "FocusProcess", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0303, AUTO, "AFSearch", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0304, AUTO, "AFAreas", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0400, AUTO, "FlashMode", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0401, AUTO, "FlashExposureComp", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0500, AUTO, "WhiteBalance2", &olWhitebalance2Interpreter}, + {0, AC_WRITE, 0, 0, 0x0501, AUTO, "WhiteBalanceTemperature", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0502, AUTO, "WhiteBalanceBracket", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0503, AUTO, "CustomSaturation", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0504, AUTO, "ModifiedSaturation", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0505, AUTO, "ContrastSetting", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0506, AUTO, "SharpnessSetting", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0507, AUTO, "ColorSpace", &olColorSpaceInterpreter}, + {0, AC_WRITE, 0, 0, 0x0509, AUTO, "SceneMode", &olSceneModeInterpreter}, + {0, AC_WRITE, 0, 0, 0x050a, AUTO, "NoiseReduction", &olNoiseReductionInterpreter}, + {0, AC_WRITE, 0, 0, 0x050b, AUTO, "DistortionCorrection", &olOnOffInterpreter}, + {0, AC_WRITE, 0, 0, 0x050c, AUTO, "ShadingCompensation", &olOnOffInterpreter}, + {0, AC_WRITE, 0, 0, 0x050d, AUTO, "CompressionFactor", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x050f, AUTO, "Gradation", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0520, AUTO, "PictureMode", &olPictureModeInterpreter}, + {0, AC_WRITE, 0, 0, 0x0521, AUTO, "PictureModeSaturation", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0522, AUTO, "PictureModeHue", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0523, AUTO, "PictureModeContrast", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0524, AUTO, "PictureModeSharpness", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0525, AUTO, "PictureModeBWFilter", &olPictureModeBWFilterInterpreter}, + {0, AC_WRITE, 0, 0, 0x0526, AUTO, "PictureModeTone", &olPictureModeToneInterpreter}, + {0, AC_WRITE, 0, 0, 0x0527, AUTO, "NoiseFilter", &olNoiseFilterInterpreter}, + {0, AC_WRITE, 0, 0, 0x0600, AUTO, "DriveMode", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0601, AUTO, "PanoramaMode", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0603, AUTO, "ImageQuality2", &olImageQuality2Interpreter}, + {0, AC_WRITE, 0, 0, 0x0900, AUTO, "ManometerPressure", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0901, AUTO, "ManometerReading", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0902, AUTO, "ExtendedWBDetect", &olOnOffInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}}; + +const TagAttrib olyEquipmentAttribs[] = { + {0, AC_WRITE, 0, 0, 0x0000, AUTO, "EquipmentVersion", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0100, AUTO, "CameraType2", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0101, AUTO, "SerialNumber", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0102, AUTO, "InternalSerialNumber", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0103, AUTO, "FocalPlaneDiagonal", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0104, AUTO, "BodyFirmwareVersion", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0201, AUTO, "LensType", &olLensTypeInterpreter}, + {0, AC_WRITE, 0, 0, 0x0202, AUTO, "LensSerialNumber", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0204, AUTO, "LensFirmwareVersion", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0205, AUTO, "MaxApertureAtMinFocal", &olApertureInterpreter}, + {0, AC_WRITE, 0, 0, 0x0206, AUTO, "MaxApertureAtMaxFocal", &olApertureInterpreter}, + {0, AC_WRITE, 0, 0, 0x0207, AUTO, "MinFocalLength", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0208, AUTO, "MaxFocalLength", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x020a, AUTO, "MaxApertureAtCurrentFocal", &olApertureInterpreter}, + {0, AC_WRITE, 0, 0, 0x020b, AUTO, "LensProperties", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0301, AUTO, "Extender", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0302, AUTO, "ExtenderSerialNumber", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0303, AUTO, "ExtenderModel", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0304, AUTO, "ExtenderFirmwareVersion", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1000, AUTO, "FlashType", &olFlashTypeInterpreter}, + {0, AC_WRITE, 0, 0, 0x1001, AUTO, "FlashModel", &olFlashModelInterpreter}, + {0, AC_WRITE, 0, 0, 0x1002, AUTO, "FlashFirmwareVersion", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1003, AUTO, "FlashSerialNumber", &stdInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}}; + +const TagAttrib olympusAttribs[] = { + {0, AC_WRITE, 0, 0, 0x0104, AUTO, "BodyFirmwareVersion", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0200, AUTO, "SpecialMode", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0201, AUTO, "Quality", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0202, AUTO, "Macro", &olOnOffInterpreter}, + {0, AC_WRITE, 0, 0, 0x0203, AUTO, "BWMode", &olOnOffInterpreter}, + {0, AC_WRITE, 0, 0, 0x0204, AUTO, "DigitalZoom", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0205, AUTO, "FocalPlaneDiagonal", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0206, AUTO, "LensDistortionParams", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0207, AUTO, "CameraType", &stdInterpreter}, + {1, AC_WRITE, 0, 0, 0x0208, AUTO, "TextInfo", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0209, AUTO, "CameraID", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x020b, AUTO, "EpsonImageWidth", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x020c, AUTO, "EpsonImageHeight", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x020d, AUTO, "EpsonSoftware", &stdInterpreter}, + {0, AC_SYSTEM, 0, 0, 0x0280, AUTO, "PreviewImage", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0300, AUTO, "PreCaptureFrames", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0301, AUTO, "WhiteBoard", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0302, AUTO, "OneTouchWB", &olOnOffInterpreter}, + {0, AC_WRITE, 0, 0, 0x0303, AUTO, "WhiteBalanceBracket", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0304, AUTO, "WhiteBalanceBias", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0403, AUTO, "SceneMode", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0404, AUTO, "SerialNumber", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0405, AUTO, "Firmware", &stdInterpreter}, + {1, AC_WRITE, 0, 0, 0x0e00, AUTO, "PrintIM", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0f00, AUTO, "DataDump", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0f01, AUTO, "DataDump2", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1000, AUTO, "ShutterSpeedValue", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1001, AUTO, "ISOValue", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1002, AUTO, "ApertureValue", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1003, AUTO, "BrightnessValue", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1004, AUTO, "FlashMode", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1005, AUTO, "FlashDevice", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1006, AUTO, "ExposureCompensation", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1007, AUTO, "SensorTemperature", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1008, AUTO, "LensTemperature", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1009, AUTO, "LightCondition", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x100a, AUTO, "FocusRange", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x100b, AUTO, "FocusMode", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x100c, AUTO, "ManualFocusDistance", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x100d, AUTO, "ZoomStepCount", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x100e, AUTO, "FocusStepCount", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x100f, AUTO, "Sharpness", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1010, AUTO, "FlashChargeLevel", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1011, AUTO, "ColorMatrix", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1012, AUTO, "BlackLevel", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1013, AUTO, "ColorTemperatureBG", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1014, AUTO, "ColorTemperatureRG", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1015, AUTO, "WBMode", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1017, AUTO, "RedBalance", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1018, AUTO, "BlueBalance", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1019, AUTO, "ColorMatrixNumber", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x101a, AUTO, "SerialNumber", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x101b, AUTO, "ExternalFlashAE1_0", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x101c, AUTO, "ExternalFlashAE2_0", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x101d, AUTO, "InternalFlashAE1_0", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x101e, AUTO, "InternalFlashAE2_0", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x101f, AUTO, "ExternalFlashAE1", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1020, AUTO, "ExternalFlashAE2", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1021, AUTO, "InternalFlashAE1", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1022, AUTO, "InternalFlashAE2", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1023, AUTO, "FlashExposureComp", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1024, AUTO, "InternalFlashTable", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1025, AUTO, "ExternalFlashGValue", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1026, AUTO, "ExternalFlashBounce", &olYesNoInterpreter}, + {0, AC_WRITE, 0, 0, 0x1027, AUTO, "ExternalFlashZoom", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1028, AUTO, "ExternalFlashMode", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1029, AUTO, "Contrast", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x102a, AUTO, "SharpnessFactor", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x102b, AUTO, "ColorControl", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x102c, AUTO, "ValidBits", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x102d, AUTO, "CoringFilter", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x102e, AUTO, "OlympusImageWidth", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x102f, AUTO, "OlympusImageHeight", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1030, AUTO, "SceneDetect", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1031, AUTO, "SceneArea", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1033, AUTO, "SceneDetectData", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1034, AUTO, "CompressionRatio", &stdInterpreter}, + {1, AC_WRITE, 0, 0, 0x1035, AUTO, "PreviewImageValid", &olYesNoInterpreter}, + {1, AC_WRITE, 0, 0, 0x1036, AUTO, "PreviewImageStart", &stdInterpreter}, + {1, AC_WRITE, 0, 0, 0x1037, AUTO, "PreviewImageLength", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1038, AUTO, "AFResult", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x1039, AUTO, "CCDScanMode", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x103a, AUTO, "NoiseReduction", &olOnOffInterpreter}, + {0, AC_WRITE, 0, 0, 0x103b, AUTO, "InfinityLensStep", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x103c, AUTO, "NearLensStep", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x103d, AUTO, "LightValueCenter", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x103e, AUTO, "LightValuePeriphery", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x103f, AUTO, "FieldCount", &stdInterpreter}, + {0, AC_WRITE, 0, olyEquipmentAttribs, 0x2010, AUTO, "Equipment", &stdInterpreter}, + {0, AC_WRITE, 0, olyCameraSettingsAttribs, 0x2020, AUTO, "CameraSettings", &stdInterpreter}, + {0, AC_WRITE, 0, olyRawDevelopmentAttribs, 0x2030, AUTO, "RawDevelopment", &stdInterpreter}, + {0, AC_WRITE, 0, olyRawDevelopment2Attribs, 0x2031, AUTO, "RawDev2", &stdInterpreter}, + {0, AC_WRITE, 0, olyImageProcessingAttribs, 0x2040, AUTO, "ImageProcessing", &stdInterpreter}, + {0, AC_WRITE, 0, olyFocusInfoAttribs, 0x2050, AUTO, "FocusInfo", &stdInterpreter}, + {1, AC_WRITE, 0, 0, 0x2100, AUTO, "Olympus2100", &stdInterpreter}, + {1, AC_WRITE, 0, 0, 0x2300, AUTO, "Olympus2300", &stdInterpreter}, + {1, AC_WRITE, 0, 0, 0x2400, AUTO, "Olympus2400", &stdInterpreter}, + {1, AC_WRITE, 0, 0, 0x2500, AUTO, "Olympus2500", &stdInterpreter}, + {1, AC_WRITE, 0, 0, 0x2600, AUTO, "Olympus2600", &stdInterpreter}, + {1, AC_WRITE, 0, 0, 0x2700, AUTO, "Olympus2700", &stdInterpreter}, + {1, AC_WRITE, 0, 0, 0x2800, AUTO, "Olympus2800", &stdInterpreter}, + {1, AC_WRITE, 0, 0, 0x2900, AUTO, "Olympus2900", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x3000, AUTO, "RawInfo", &stdInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}}; +} +#endif + diff --git a/rtexif/pentaxattribs.cc b/rtexif/pentaxattribs.cc new file mode 100644 index 000000000..810d2634f --- /dev/null +++ b/rtexif/pentaxattribs.cc @@ -0,0 +1,1861 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _PENTAXATTRIBS_ +#define _PENTAXATTRIBS_ + +#include +#include +#include /* memcpy() */ +#include +#include + +#include "rtexif.h" + +namespace rtexif { + + +class PAQualityInterpreter : public ChoiceInterpreter { + public: + PAQualityInterpreter () { + choices[0] = "Good"; + choices[1] = "Better"; + choices[2] = "Best"; + choices[3] = "TIFF"; + choices[4] = "RAW"; + choices[5] = "Premium"; + } +}; +PAQualityInterpreter paQualityInterpreter; + +class PAOnOffInterpreter : public ChoiceInterpreter { + public: + PAOnOffInterpreter () { + choices[0] = "Off"; + choices[1] = "On"; + } +}; +PAOnOffInterpreter paOnOffInterpreter; + +class PAShakeReductionInterpreter : public ChoiceInterpreter { + public: + PAShakeReductionInterpreter () { + choices[ 0] = "Off"; + choices[ 1] = "On"; + choices[ 4] = "On (4)"; + choices[ 5] = "On but Disabled"; + choices[ 6] = "On (Video)"; + choices[ 7] = "On (7)"; + choices[ 15] = "On (15)"; + choices[ 39] = "On (mode 2)"; + choices[135] = "On (135)"; + choices[167] = "On (mode 1)"; + } +}; +PAShakeReductionInterpreter paShakeReductionInterpreter; + +class PAShakeReduction2Interpreter : public ChoiceInterpreter { + public: + PAShakeReduction2Interpreter () { + choices[ 0] = "Off"; + choices[ 1] = "On"; + choices[ 4] = "Off (AA simulation off)"; + choices[ 5] = "On but Disabled"; + choices[ 6] = "On (Video)"; + choices[ 7] = "On (AA simulation off)"; + choices[12] = "Off (AA simulation type 1)"; + choices[15] = "On (AA simulation type 1)"; + choices[20] = "Off (AA simulation type 2)"; + choices[23] = "On (AA simulation type 2)"; + } +}; +PAShakeReduction2Interpreter paShakeReduction2Interpreter; + +class PAPictureModeInterpreter : public ChoiceInterpreter { + public: + PAPictureModeInterpreter () { + choices[0] = "Program"; + choices[1] = "Shutter Speed Priority"; + choices[2] = "Program AE"; + choices[3] = "Manual"; + choices[5] = "Portrait"; + choices[6] = "Landscape"; + choices[8] = "Sport"; + choices[9] = "Night Scene"; + choices[11] = "Soft"; + choices[12] = "Surf & Snow"; + choices[13] = "Candlelight"; + choices[14] = "Autumn"; + choices[15] = "Macro"; + choices[17] = "Fireworks"; + choices[18] = "Text"; + choices[19] = "Panorama"; + choices[20] = "3-D"; + choices[21] = "Black & White"; + choices[22] = "Sepia"; + choices[23] = "Red"; + choices[24] = "Pink"; + choices[25] = "Purple"; + choices[26] = "Blue"; + choices[27] = "Green"; + choices[28] = "Yellow"; + choices[30] = "Self Portrait"; + choices[31] = "Illustrations"; + choices[33] = "Digital Filter"; + choices[35] = "Night Scene Portrait"; + choices[37] = "Museum"; + choices[38] = "Food"; + choices[39] = "Underwater"; + choices[40] = "Green Mode"; + choices[49] = "Light Pet"; + choices[50] = "Dark Pet"; + choices[51] = "Medium Pet"; + choices[53] = "Underwater"; + choices[54] = "Candlelight"; + choices[55] = "Natural Skin Tone"; + choices[56] = "Synchro Sound Record"; + choices[58] = "Frame Composite"; + choices[59] = "Report"; + choices[60] = "Kids"; + choices[61] = "Blur Reduction"; + choices[65] = "Half-length Portrait"; + choices[221] = "P"; + choices[255] = "PICT"; + } +}; +PAPictureModeInterpreter paPictureModeInterpreter; + +class PASceneModeInterpreter : public ChoiceInterpreter { + public: + PASceneModeInterpreter () { + choices[ 0] = "Off"; + choices[ 1] = "HDR"; + choices[ 4] = "Auto PICT"; + choices[ 5] = "Portrait"; + choices[ 6] = "Landscape"; + choices[ 7] = "Macro"; + choices[ 8] = "Sport"; + choices[ 9] = "Night Scene Portrait"; + choices[10] = "No Flash"; + choices[11] = "Night Scene"; + choices[12] = "Surf & Snow"; + choices[14] = "Sunset"; + choices[15] = "Kids"; + choices[16] = "Pet"; + choices[17] = "Candlelight"; + choices[18] = "Museum"; + choices[20] = "Food"; + choices[21] = "Stage Lighting"; + choices[22] = "Night Snap"; + choices[25] = "Night Scene HDR"; + choices[26] = "Blue Sky"; + choices[27] = "Forest"; + choices[29] = "Backlight Silhouette"; + } +}; +PASceneModeInterpreter paSceneModeInterpreter; + +class PAAEProgramModeInterpreter : public ChoiceInterpreter { + public: + PAAEProgramModeInterpreter () { + choices[ 0] = "M, P or TAv"; + choices[ 1] = "Av, B or X"; + choices[ 2] = "Tv"; + choices[ 3] = "Sv or Green Mode"; + choices[ 8] = "Hi-speed Program"; + choices[ 11] = "Hi-speed Program (P-Shift)"; + choices[ 16] = "DOF Program"; + choices[ 19] = "DOF Program (P-Shift)"; + choices[ 24] = "MTF Program"; + choices[ 27] = "MTF Program (P-Shift)"; + choices[ 35] = "Standard"; + choices[ 43] = "Portrait"; + choices[ 51] = "Landscape"; + choices[ 59] = "Macro"; + choices[ 67] = "Sport"; + choices[ 75] = "Night Scene Portrait"; + choices[ 83] = "No Flash"; + choices[ 91] = "Night Scene"; + choices[ 99] = "Surf & Snow"; + choices[104] = "Night Snap"; + choices[107] = "Text"; + choices[115] = "Sunset"; + choices[123] = "Kids"; + choices[131] = "Pet"; + choices[139] = "Candlelight"; + choices[144] = "SCN"; + choices[147] = "Museum"; + choices[160] = "Program"; + choices[184] = "Shallow DOF Program"; + choices[216] = "HDR"; + } +}; +PAAEProgramModeInterpreter paAEProgramModeInterpreter; + +class PAFlashModeInterpreter : public ChoiceInterpreter { + public: + PAFlashModeInterpreter () { + choices[0x0] = "Auto, Did not fire"; + choices[0x1] = "Off"; + choices[0x2] = "On, Did not fire"; + choices[0x3] = "Auto, Did not fire, Red-eye reduction"; + choices[0x100] = "Auto, Fired"; + choices[0x102] = "On"; + choices[0x103] = "Auto, Fired, Red-eye reduction"; + choices[0x104] = "On, Red-eye reduction"; + choices[0x105] = "On, Wireless (Master)"; + choices[0x106] = "On, Wireless (Control)"; + choices[0x108] = "On, Soft"; + choices[0x109] = "On, Slow-sync"; + choices[0x10a] = "On, Slow-sync, Red-eye reduction"; + choices[0x10b] = "On, Trailing-curtain Sync"; + } +}; +PAFlashModeInterpreter paFlashModeInterpreter; + +class PAFocusModeInterpreter : public ChoiceInterpreter { + public: + PAFocusModeInterpreter () { + choices[0] = "Normal"; + choices[1] = "Macro"; + choices[2] = "Infinity"; + choices[3] = "Manual"; + choices[4] = "Super Macro"; + choices[5] = "Pan Focus"; + choices[16] = "AF-S"; + choices[17] = "AF-C"; + choices[18] = "AF-A"; + } +}; +PAFocusModeInterpreter paFocusModeInterpreter; + +class PAAFPointInterpreter : public ChoiceInterpreter { + public: + PAAFPointInterpreter () { + choices[1] = "Upper-left"; + choices[2] = "Top"; + choices[3] = "Upper-right"; + choices[4] = "Left"; + choices[5] = "Mid-left"; + choices[6] = "Center"; + choices[7] = "Mid-right"; + choices[8] = "Right"; + choices[9] = "Lower-left"; + choices[10] = "Bottom"; + choices[11] = "Lower-right"; + choices[65532] = "Face Recognition AF"; + choices[65533] = "Automatic Tracking AF"; + choices[65534] = "Fixed Center"; + choices[65535] = "Auto"; + } +}; +PAAFPointInterpreter paAFPointInterpreter; + +class PAAFFocusInterpreter : public ChoiceInterpreter { + public: + PAAFFocusInterpreter () { + choices[0x0] = "Fixed Center or Multiple"; + choices[0x1] = "Top-left"; + choices[0x2] = "Top-center"; + choices[0x3] = "Top-right"; + choices[0x4] = "Left"; + choices[0x5] = "Center"; + choices[0x6] = "Right"; + choices[0x7] = "Bottom-left"; + choices[0x8] = "Bottom-center"; + choices[0x9] = "Bottom-right"; + choices[0xffff] = "None"; + } +}; +PAAFFocusInterpreter paAFFocusInterpreter; + +class PAISOInterpreter : public ChoiceInterpreter { + public: + PAISOInterpreter () { + choices[3] = "50"; + choices[4] = "64"; + choices[5] = "80"; + choices[6] = "100"; + choices[7] = "125"; + choices[8] = "160"; + choices[9] = "200"; + choices[10] = "250"; + choices[11] = "320"; + choices[12] = "400"; + choices[13] = "500"; + choices[14] = "640"; + choices[15] = "800"; + choices[16] = "1000"; + choices[17] = "1250"; + choices[18] = "1600"; + choices[19] = "2000"; + choices[20] = "2500"; + choices[21] = "3200"; + choices[22] = "4000"; + choices[23] = "5000"; + choices[24] = "6400"; + choices[25] = "8000"; + choices[26] = "10000"; + choices[27] = "12800"; + choices[28] = "16000"; + choices[29] = "20000"; + choices[30] = "25600"; + choices[31] = "32000"; + choices[32] = "40000"; + choices[33] = "51200"; + + choices[50] = "50"; + choices[100] = "100"; + choices[200] = "200"; + /*choices[400] = "400"; + choices[800] = "800"; + choices[1600] = "1600"; + choices[3200] = "3200"; Moved to tail for sorting reasons */ + + choices[258] = "50"; + choices[259] = "70"; + choices[260] = "100"; + choices[261] = "140"; + choices[262] = "200"; + choices[263] = "280"; + choices[264] = "400"; + choices[265] = "560"; + choices[266] = "800"; + choices[267] = "1100"; + choices[268] = "1600"; + choices[269] = "2200"; + choices[270] = "3200"; + choices[271] = "4500"; + choices[272] = "6400"; + choices[273] = "9000"; + choices[274] = "12800"; + choices[275] = "18000"; + choices[276] = "25600"; + choices[277] = "36000"; + choices[278] = "51200"; + + choices[400] = "400"; + choices[800] = "800"; + choices[1600] = "1600"; + choices[3200] = "3200"; + + //choices[65534] = "Auto"; ?? + //choices[65535] = "Auto"; ?? + } +}; +PAISOInterpreter paISOInterpreter; + +class PAFNumberInterpreter: public Interpreter { +public: + PAFNumberInterpreter () {} + virtual std::string toString (Tag* t) { + char buffer[32]; + double v = t->toDouble()/10; + if( v < 0. || v > 1000. ) return "undef"; + sprintf (buffer, "%.1f", v ); + return buffer; + } +}; +PAFNumberInterpreter paFNumberInterpreter; + +class PAMeteringModeInterpreter : public ChoiceInterpreter { + public: + PAMeteringModeInterpreter () { + choices[0] = "Multi-segment"; + choices[1] = "Center-weighted average"; + choices[2] = "Spot"; + } +}; +PAMeteringModeInterpreter paMeteringModeInterpreter; + +class PAWhiteBalanceInterpreter : public ChoiceInterpreter { + public: + PAWhiteBalanceInterpreter () { + choices[0] = "Auto"; + choices[1] = "Daylight"; + choices[2] = "Shade"; + choices[3] = "Fluorescent"; + choices[4] = "Tungsten"; + choices[5] = "Manual"; + choices[6] = "Daylight Fluorescent"; + choices[7] = "Day White Fluorescent"; + choices[8] = "White Fluorescent"; + choices[9] = "Flash"; + choices[10] = "Cloudy"; + choices[11] = "Warm White Fluorescent"; + choices[14] = "Multi Auto"; + choices[15] = "Color Temperature Enhancement"; + choices[17] = "Kelvin"; + choices[65534] = "Unknown"; + choices[65535] = "User Selected"; + } +}; +PAWhiteBalanceInterpreter paWhiteBalanceInterpreter; + +class PAWhiteBalanceModeInterpreter : public ChoiceInterpreter { + public: + PAWhiteBalanceModeInterpreter () { + choices[1] = "Auto (Daylight)"; + choices[2] = "Auto (Shade)"; + choices[3] = "Auto (Flash)"; + choices[4] = "Auto (Tungsten)"; + choices[6] = "Auto (DaylightFluorescent)"; + choices[7] = "Auto (DaywhiteFluorescent)"; + choices[8] = "Auto (WhiteFluorescent)"; + choices[10] = "Auto (Cloudy)"; + choices[65534] = "Preset (Fireworks?)"; + choices[65535] = "User-Selected"; + } +}; +PAWhiteBalanceModeInterpreter paWhiteBalanceModeInterpreter; + +class PASaturationInterpreter : public ChoiceInterpreter { + public: + PASaturationInterpreter () { + choices[0] = "Low"; + choices[1] = "Normal"; + choices[2] = "High"; + choices[3] = "Med Low"; + choices[4] = "Med High"; + choices[5] = "Very Low"; + choices[6] = "Very High"; + } +}; +PASaturationInterpreter paSaturationInterpreter; + +class PAContrastInterpreter : public ChoiceInterpreter { + public: + PAContrastInterpreter () { + choices[0] = "Low"; + choices[1] = "Normal"; + choices[2] = "High"; + choices[3] = "Med Low"; + choices[4] = "Med High"; + choices[5] = "Very Low"; + choices[6] = "Very High"; + } +}; +PAContrastInterpreter paContrastInterpreter; + +class PASharpnessInterpreter : public ChoiceInterpreter { + public: + PASharpnessInterpreter () { + choices[0] = "Soft"; + choices[1] = "Normal"; + choices[2] = "Hard"; + choices[3] = "Med Soft"; + choices[4] = "Med Hard"; + choices[5] = "Very Soft"; + choices[6] = "Very Hard"; + } +}; +PASharpnessInterpreter paSharpnessInterpreter; + +class PAPictureModeInterpreter2: public ChoiceInterpreter { +public: + PAPictureModeInterpreter2(){ + choices[ 0] = "Program"; + choices[ 1] = "Hi-speed Program"; + choices[ 2] = "DOF Program"; + choices[ 3] = "MTF Program"; + choices[ 4] = "Standard"; + choices[ 5] = "Portrait"; + choices[ 6] = "Landscape"; + choices[ 7] = "Macro"; + choices[ 8] = "Sport "; + choices[ 9] = "Night Scene Portrait "; + choices[10] = "No Flash"; + choices[11] = "Night Scene"; + choices[12] = "Surf & Snow"; + choices[13] = "Text"; + choices[14] = "Sunset"; + choices[15] = "Kids"; + choices[16] = "Pet"; + choices[17] = "Candlelight"; + choices[18] = "Museum"; + choices[19] = "Food "; + choices[20] = "Stage Lighting"; + choices[21] = "Night Snap"; + choices[256+4] = "Auto PICT"; + choices[256+5] = "Auto PICT (Portrait)"; + choices[256+6] = "Auto PICT (Landscape)"; + choices[256+7] = "Auto PICT (Macro)"; + choices[256+8] = "Auto PICT (Sport)"; + choices[256+8] = "Auto PICT (Sport)"; + choices[512+0] = "Program (HyP)"; + choices[512+1] = "Hi-speed Program (HyP)"; + choices[512+2] = "DOF Program (HyP)"; + choices[512+3] = "MTF Program (HyP)"; + choices[3*256] = "Green Mode"; + choices[4*256] = "Shutter Speed Priority"; + choices[5*256] = "Aperture Priority"; + choices[6*256] = "Program Tv Shift"; + choices[7*256] = "Program Av Shift"; + choices[8*256] = "Manual"; + choices[9*256] = "Bulb"; + choices[10*256] = "Aperture Priority, Off-Auto-Aperture"; + choices[11*256] = "Manual, Off-Auto-Aperture"; + choices[12*256] = "Bulb, Off-Auto-Aperture"; + choices[13*256] = "Shutter & Aperture Priority AE"; + choices[15*256] = "Sensitivity Priority AE"; + choices[16*256] = "Flash X-Sync Speed AE"; + } + virtual std::string toString (Tag* t) { + int c = 256*t->toInt(0,BYTE) + t->toInt(1,BYTE); + std::map::iterator r = choices.find (c); + if (r!=choices.end()){ + std::ostringstream s; + s << r->second; + if( t->toInt(1,BYTE)==0 ) + s << "\n1/2 EV steps"; + else + s << "\n1/3 EV steps"; + return s.str(); + }else { + char buffer[1024]; + t->toString (buffer); + return std::string (buffer); + } + } +}; +PAPictureModeInterpreter2 paPictureModeInterpreter2; + +class PADriveModeInterpreter : public ChoiceInterpreter{ + std::map choices1; + std::map choices2; + std::map choices3; +public: + PADriveModeInterpreter(){ + choices[0] = "Single-frame"; + choices[1] = "Continuous"; + choices[2] = "Continuous (Lo)"; + choices[3] = "Burst"; + choices[4] = "Continuous (Medium)"; + choices[255] = "Video"; + choices1[0] = "No Timer"; + choices1[1] = "Self-timer (12 s)"; + choices1[2] = "Self-timer (2 s)"; + choices1[15] = "Video"; + choices1[16] = "Mirror Lock-up"; + choices1[255] = "n/a"; + choices2[0] = "Shutter Button"; + choices2[1] = "Remote Control (3 s delay)"; + choices2[2] = "Remote Control"; + choices2[4] = "Remote Continuous Shooting"; + choices3[0] = "Single Exposure"; + choices3[1] = "Multiple Exposure"; + choices3[15] = "Interval Movie"; + choices3[16] = "HDR"; + choices3[32] = "HDR Strong 1"; + choices3[48] = "HDR Strong 2"; + choices3[64] = "HDR Strong 3"; + choices3[224] = "HDR Auto"; + choices3[255] = "Video"; + } + virtual std::string toString (Tag* t) { + std::map::iterator r = choices.find (t->toInt(0,BYTE)); + std::map::iterator r1 = choices1.find (t->toInt(1,BYTE)); + std::map::iterator r2 = choices2.find (t->toInt(2,BYTE)); + std::map::iterator r3 = choices3.find (t->toInt(3,BYTE)); + std::ostringstream s; + s << ((r !=choices.end())? r->second : ""); + s << ((r1!=choices1.end())? r1->second : "")<<" "; + s << ((r2!=choices2.end())? r2->second : "")<<" "; + s << ((r3!=choices3.end())? r3->second : "")<<" "; + return s.str(); + } +}; +PADriveModeInterpreter paDriveModeInterpreter; + +class PAColorSpaceInterpreter: public ChoiceInterpreter{ +public: + PAColorSpaceInterpreter(){ + choices[0] = "sRGB"; + choices[1] = "Adobe RGB"; + } +}; +PAColorSpaceInterpreter paColorSpaceInterpreter; + +class PALensTypeInterpreter : public IntLensInterpreter< int > { + public: + PALensTypeInterpreter () { // From EXIFTOOL database 'Pentax.pm' V2.65 + choices.insert(p_t( 0+ 0, "M-42 or No Lens")); + choices.insert(p_t(256*1+ 0, "K,M Lens")); + choices.insert(p_t(256*2+ 0, "A Series Lens")); + choices.insert(p_t(256*3+ 0, "Sigma Lens")); + choices.insert(p_t(256*3+ 17, "smc PENTAX-FA SOFT 85mm f/2.8")); + choices.insert(p_t(256*3+ 18, "smc PENTAX-F 1.7X AF ADAPTER")); + choices.insert(p_t(256*3+ 19, "smc PENTAX-F 24-50mm f/4")); + choices.insert(p_t(256*3+ 20, "smc PENTAX-F 35-80mm f/4-5.6")); + choices.insert(p_t(256*3+ 21, "smc PENTAX-F 80-200mm f/4.7-5.6")); + choices.insert(p_t(256*3+ 22, "smc PENTAX-F FISH-EYE 17-28mm f/3.5-4.5")); + choices.insert(p_t(256*3+ 23, "smc PENTAX-F 100-300mm f/4.5-5.6")); + choices.insert(p_t(256*3+ 23, "Sigma AF 28-300mm f/3.5-5.6 DL IF")); + choices.insert(p_t(256*3+ 23, "Sigma AF 28-300mm f/3.5-6.3 DG IF Macro")); + choices.insert(p_t(256*3+ 24, "smc PENTAX-F 35-135mm f/3.5-4.5")); + choices.insert(p_t(256*3+ 25, "smc PENTAX-F 35-105mm f/4-5.6")); + choices.insert(p_t(256*3+ 25, "Sigma AF 28-300mm f/3.5-5.6 DL IF")); + choices.insert(p_t(256*3+ 25, "Sigma 55-200mm f/4-5.6 DC")); + choices.insert(p_t(256*3+ 25, "Sigma AF 28-300mm f/3.5-6.3 DG IF Macro")); + choices.insert(p_t(256*3+ 25, "Tokina 80-200mm f/2.8 ATX-Pro")); + choices.insert(p_t(256*3+ 26, "smc PENTAX-F* 250-600mm f/5.6 ED[IF]")); + choices.insert(p_t(256*3+ 27, "smc PENTAX-F 28-80mm f/3.5-4.5")); + choices.insert(p_t(256*3+ 27, "Tokina AT-X Pro AF 28-70mm f/2.6-2.8")); + choices.insert(p_t(256*3+ 28, "smc PENTAX-F 35-70mm f/3.5-4.5")); + choices.insert(p_t(256*3+ 28, "Tokina 19-35mm f/3.5-4.5 AF")); + choices.insert(p_t(256*3+ 28, "Tokina AT-X AF 400mm f/5.6")); + choices.insert(p_t(256*3+ 29, "PENTAX-F 28-80mm f/3.5-4.5")); + choices.insert(p_t(256*3+ 29, "Sigma AF 18-125mm f/3.5-5.6 DC")); + choices.insert(p_t(256*3+ 29, "Tokina AT-X PRO 28-70mm f/2.6-2.8")); + choices.insert(p_t(256*3+ 30, "PENTAX-F 70-200mm f/4-5.6")); + choices.insert(p_t(256*3+ 31, "smc PENTAX-F 70-210mm f/4-5.6")); + choices.insert(p_t(256*3+ 31, "Tokina AF 730 75-300mm f/4.5-5.6")); + choices.insert(p_t(256*3+ 31, "Takumar-F 70-210mm f/4-5.6")); + choices.insert(p_t(256*3+ 32, "smc PENTAX-F 50mm f/1.4")); + choices.insert(p_t(256*3+ 33, "smc PENTAX-F 50mm f/1.7")); + choices.insert(p_t(256*3+ 34, "smc PENTAX-F 135mm f/2.8 [IF]")); + choices.insert(p_t(256*3+ 35, "smc PENTAX-F 28mm f/2.8")); + choices.insert(p_t(256*3+ 36, "Sigma 20mm f/1.8 EX DG Aspherical RF")); + choices.insert(p_t(256*3+ 38, "smc PENTAX-F* 300mm f/4.5 ED[IF]")); + choices.insert(p_t(256*3+ 39, "smc PENTAX-F* 600mm f/4 ED[IF]")); + choices.insert(p_t(256*3+ 40, "smc PENTAX-F Macro 100mm f/2.8")); + choices.insert(p_t(256*3+ 41, "smc PENTAX-F Macro 50mm f/2.8")); + choices.insert(p_t(256*3+ 41, "Sigma 50mm f/2.8 Macro")); + choices.insert(p_t(256*3+ 44, "Sigma AF 10-20mm f/4-5.6 EX DC")); + choices.insert(p_t(256*3+ 44, "Sigma 12-24mm f/4.5-5.6 EX DG")); + choices.insert(p_t(256*3+ 44, "Sigma 17-70mm f/2.8-4.5 DC Macro")); + choices.insert(p_t(256*3+ 44, "Sigma 18-50mm f/3.5-5.6 DC")); + choices.insert(p_t(256*3+ 44, "Tamron 35-90mm f/4 AF")); + choices.insert(p_t(256*3+ 46, "Sigma APO 70-200mm f/2.8 EX")); + choices.insert(p_t(256*3+ 46, "Sigma EX APO 100-300mm f/4 IF")); + choices.insert(p_t(256*3+ 46, "Samsung/Schneider D-XENON 50-200mm f/4-5.6 ED")); + choices.insert(p_t(256*3+ 50, "smc PENTAX-FA 28-70mm f/4 AL")); + choices.insert(p_t(256*3+ 51, "Sigma 28mm f/1.8 EX DG Aspherical Macro")); + choices.insert(p_t(256*3+ 52, "smc PENTAX-FA 28-200mm f/3.8-5.6 AL[IF]")); + choices.insert(p_t(256*3+ 52, "Tamron AF LD 28-200mm f/3.8-5.6 [IF] Aspherical (171D)")); + choices.insert(p_t(256*3+ 53, "smc PENTAX-FA 28-80mm f/3.5-5.6 AL")); + choices.insert(p_t(256*3+ 247,"smc PENTAX-DA FISH-EYE 10-17mm f/3.5-4.5 ED[IF]")); + choices.insert(p_t(256*3+ 248,"smc PENTAX-DA 12-24mm f/4 ED AL[IF]")); + choices.insert(p_t(256*3+ 250,"smc PENTAX-DA 50-200mm f/4-5.6 ED")); + choices.insert(p_t(256*3+ 251,"smc PENTAX-DA 40mm f/2.8 Limited")); + choices.insert(p_t(256*3+ 252,"smc PENTAX-DA 18-55mm f/3.5-5.6 AL")); + choices.insert(p_t(256*3+ 253,"smc PENTAX-DA 14mm f/2.8 ED[IF]")); + choices.insert(p_t(256*3+ 254,"smc PENTAX-DA 16-45mm f/4 ED AL")); + choices.insert(p_t(256*3+ 255,"Sigma 18-200mm f/3.5-6.3 DC")); + choices.insert(p_t(256*3+ 255,"Sigma DL-II 35-80mm f/4-5.6")); + choices.insert(p_t(256*3+ 255,"Sigma DL Zoom 75-300mm f/4-5.6")); + choices.insert(p_t(256*3+ 255,"Sigma DF EX Aspherical 28-70mm f/2.8")); + choices.insert(p_t(256*3+ 255,"Sigma AF Tele 400mm f/5.6 Multi-coated")); + choices.insert(p_t(256*3+ 255,"Sigma 24-60mm f/2.8 EX DG")); + choices.insert(p_t(256*3+ 255,"Sigma 70-300mm f/4-5.6 Macro")); + choices.insert(p_t(256*3+ 255,"Sigma 55-200mm f/4-5.6 DC")); + choices.insert(p_t(256*3+ 255,"Sigma 18-50mm f/2.8 EX DC")); + choices.insert(p_t(256*4+ 1, "smc PENTAX-FA SOFT 28mm f/2.8")); + choices.insert(p_t(256*4+ 2, "smc PENTAX-FA 80-320mm f/4.5-5.6")); + choices.insert(p_t(256*4+ 3, "smc PENTAX-FA 43mm f/1.9 Limited")); + choices.insert(p_t(256*4+ 6, "smc PENTAX-FA 35-80mm f/4-5.6")); + choices.insert(p_t(256*4+ 12, "smc PENTAX-FA 50mm f/1.4")); + choices.insert(p_t(256*4+ 15, "smc PENTAX-FA 28-105mm f/4-5.6 [IF]")); + choices.insert(p_t(256*4+ 16, "Tamron AF 80-210mm f/4-5.6 (178D)")); + choices.insert(p_t(256*4+ 19, "Tamron SP AF 90mm f/2.8 (172E)")); + choices.insert(p_t(256*4+ 20, "smc PENTAX-FA 28-80mm f/3.5-5.6")); + choices.insert(p_t(256*4+ 21, "Cosina AF 100-300mm f/5.6-6.7")); + choices.insert(p_t(256*4+ 22, "Tokina 28-80mm f/3.5-5.6")); + choices.insert(p_t(256*4+ 23, "smc PENTAX-FA 20-35mm f/4 AL")); + choices.insert(p_t(256*4+ 24, "smc PENTAX-FA 77mm f/1.8 Limited")); + choices.insert(p_t(256*4+ 25, "Tamron SP AF 14mm f/2.8")); + choices.insert(p_t(256*4+ 26, "smc PENTAX-FA Macro 100mm f/3.5")); + choices.insert(p_t(256*4+ 26, "Cosina 100mm f/3.5 Macro")); + choices.insert(p_t(256*4+ 27, "Tamron AF 28-300mm f/3.5-6.3 LD Aspherical[IF] Macro (185D/285D)")); + choices.insert(p_t(256*4+ 28, "smc PENTAX-FA 35mm f/2 AL")); + choices.insert(p_t(256*4+ 29, "Tamron AF 28-200mm f/3.8-5.6 LD Super II Macro (371D)")); + choices.insert(p_t(256*4+ 34, "smc PENTAX-FA 24-90mm f/3.5-4.5 AL[IF]")); + choices.insert(p_t(256*4+ 35, "smc PENTAX-FA 100-300mm f/4.7-5.8")); + choices.insert(p_t(256*4+ 36, "Tamron AF70-300mm f/4-5.6 LD Macro")); + choices.insert(p_t(256*4+ 37, "Tamron SP AF 24-135mm f/3.5-5.6 AD AL (190D)")); + choices.insert(p_t(256*4+ 38, "smc PENTAX-FA 28-105mm f/3.2-4.5 AL[IF]")); + choices.insert(p_t(256*4+ 39, "smc PENTAX-FA 31mm f/1.8 AL Limited")); + choices.insert(p_t(256*4+ 41, "Tamron AF 28-200mm Super Zoom f/3.8-5.6 Aspherical XR [IF] Macro (A03)")); + choices.insert(p_t(256*4+ 43, "smc PENTAX-FA 28-90mm f/3.5-5.6")); + choices.insert(p_t(256*4+ 44, "smc PENTAX-FA J 75-300mm f/4.5-5.8 AL")); + choices.insert(p_t(256*4+ 45, "Tamron 28-300mm f/3.5-6.3 Ultra zoom XR")); + choices.insert(p_t(256*4+ 45, "Tamron AF 28-300mm f/3.5-6.3 XR Di LD Aspherical [IF] Macro")); + choices.insert(p_t(256*4+ 46, "smc PENTAX-FA J 28-80mm f/3.5-5.6 AL")); + choices.insert(p_t(256*4+ 47, "smc PENTAX-FA J 18-35mm f/4-5.6 AL")); + choices.insert(p_t(256*4+ 49, "Tamron SP AF 28-75mm f/2.8 XR Di (A09)")); + choices.insert(p_t(256*4+ 51, "smc PENTAX-D FA 50mm f/2.8 Macro")); + choices.insert(p_t(256*4+ 52, "smc PENTAX-D FA 100mm f/2.8 Macro")); + choices.insert(p_t(256*4+ 55, "Samsung/Schneider D-XENOGON 35mm f/2")); + choices.insert(p_t(256*4+ 56, "Samsung/Schneider D-XENON 100mm f/2.8 Macro")); + choices.insert(p_t(256*4+ 75, "Tamron SP AF 70-200mm f/2.8 Di LD [IF] Macro (A001)")); + choices.insert(p_t(256*4+ 214, "smc PENTAX-DA 35mm f/2.4 AL")); + choices.insert(p_t(256*4+ 229, "smc PENTAX-DA 18-55mm f/3.5-5.6 AL II")); + choices.insert(p_t(256*4+ 230, "Tamron SP AF 17-50mm f/2.8 XR Di II")); + choices.insert(p_t(256*4+ 231, "smc PENTAX-DA 18-250mm f/3.5-6.3 ED AL [IF]")); + choices.insert(p_t(256*4+ 237, "Samsung/Schneider D-XENOGON 10-17mm f/3.5-4.5")); + choices.insert(p_t(256*4+ 239, "Samsung/Schneider D-XENON 12-24mm f/4 ED AL [IF]")); + choices.insert(p_t(256*4+ 242, "smc PENTAX-DA* 16-50mm f/2.8 ED AL [IF] SDM (SDM unused)")); + choices.insert(p_t(256*4+ 243, "smc PENTAX-DA 70mm f/2.4 Limited")); + choices.insert(p_t(256*4+ 244, "smc PENTAX-DA 21mm f/3.2 AL Limited")); + choices.insert(p_t(256*4+ 245, "Samsung/Schneider D-XENON 50-200mm f/4-5.6")); + choices.insert(p_t(256*4+ 246, "Samsung/Schneider D-XENON 18-55mm f/3.5-5.6")); + choices.insert(p_t(256*4+ 247, "smc PENTAX-DA 10-17mm f/3.5-4.5 ED [IF] Fisheye zoom")); + choices.insert(p_t(256*4+ 248, "smc PENTAX-DA 12-24mm f/4 ED AL [IF]")); + choices.insert(p_t(256*4+ 249, "Tamron 18-200mm f/3.5-6.3 XR DiII (A14)")); + choices.insert(p_t(256*4+ 250, "smc PENTAX-DA 50-200mm f/4-5.6 ED")); + choices.insert(p_t(256*4+ 251, "smc PENTAX-DA 40mm f/2.8 Limited")); + choices.insert(p_t(256*4+ 252, "smc PENTAX-DA 18-55mm f/3.5-5.6 AL")); + choices.insert(p_t(256*4+ 253, "smc PENTAX-DA 14mm f/2.8 ED[IF]")); + choices.insert(p_t(256*4+ 254, "smc PENTAX-DA 16-45mm f/4 ED AL")); + choices.insert(p_t(256*5+ 1, "smc PENTAX-FA* 24mm f/2 AL[IF]")); + choices.insert(p_t(256*5+ 2, "smc PENTAX-FA 28mm f/2.8 AL")); + choices.insert(p_t(256*5+ 3, "smc PENTAX-FA 50mm f/1.7")); + choices.insert(p_t(256*5+ 4, "smc PENTAX-FA 50mm f/1.4")); + choices.insert(p_t(256*5+ 5, "smc PENTAX-FA* 600mm f/4 ED[IF]")); + choices.insert(p_t(256*5+ 6, "smc PENTAX-FA* 300mm f/4.5 ED[IF]")); + choices.insert(p_t(256*5+ 7, "smc PENTAX-FA 135mm f/2.8 [IF]")); + choices.insert(p_t(256*5+ 8, "smc PENTAX-FA Macro 50mm f/2.8")); + choices.insert(p_t(256*5+ 9, "smc PENTAX-FA Macro 100mm f/2.8")); + choices.insert(p_t(256*5+ 10, "smc PENTAX-FA* 85mm f/1.4 [IF]")); + choices.insert(p_t(256*5+ 11, "smc PENTAX-FA* 200mm f/2.8 ED[IF]")); + choices.insert(p_t(256*5+ 12, "smc PENTAX-FA 28-80mm f/3.5-4.7")); + choices.insert(p_t(256*5+ 13, "smc PENTAX-FA 70-200mm f/4-5.6")); + choices.insert(p_t(256*5+ 14, "smc PENTAX-FA* 250-600mm f/5.6 ED[IF]")); + choices.insert(p_t(256*5+ 15, "smc PENTAX-FA 28-105mm f/4-5.6")); + choices.insert(p_t(256*5+ 16, "smc PENTAX-FA 100-300mm f/4.5-5.6")); + choices.insert(p_t(256*5+ 98, "smc PENTAX-FA 100-300mm f/4.5-5.6")); + choices.insert(p_t(256*6+ 1, "smc PENTAX-FA* 85mm f/1.4 [IF]")); + choices.insert(p_t(256*6+ 2, "smc PENTAX-FA* 200mm f/2.8 ED[IF]")); + choices.insert(p_t(256*6+ 3, "smc PENTAX-FA* 300mm f/2.8 ED[IF]")); + choices.insert(p_t(256*6+ 4, "smc PENTAX-FA* 28-70mm f/2.8 AL")); + choices.insert(p_t(256*6+ 5, "smc PENTAX-FA* 80-200mm f/2.8 ED[IF]")); + choices.insert(p_t(256*6+ 6, "smc PENTAX-FA* 28-70mm f/2.8 AL")); + choices.insert(p_t(256*6+ 7, "smc PENTAX-FA* 80-200mm f/2.8 ED[IF]")); + choices.insert(p_t(256*6+ 8, "smc PENTAX-FA 28-70mm f/4 AL")); + choices.insert(p_t(256*6+ 9, "smc PENTAX-FA 20mm f/2.8")); + choices.insert(p_t(256*6+ 10, "smc PENTAX-FA* 400mm f/5.6 ED[IF]")); + choices.insert(p_t(256*6+ 13, "smc PENTAX-FA* 400mm f/5.6 ED[IF]")); + choices.insert(p_t(256*6+ 14, "smc PENTAX-FA* Macro 200mm f/4 ED[IF]")); + choices.insert(p_t(256*7+ 0, "smc PENTAX-DA 21mm f/3.2 AL Limited")); + choices.insert(p_t(256*7+ 58, "smc PENTAX-D FA Macro 100mm f/2.8 WR")); + choices.insert(p_t(256*7+ 75, "Tamron SP AF 70-200mm f/2.8 Di LD [IF] Macro (A001)")); + choices.insert(p_t(256*7+ 202, "smc PENTAX-DA L 18-55mm f/3.5-5.6 AL WR")); + choices.insert(p_t(256*7+ 204, "HD PENTAX-DA 15mm f/4 ED AL Limited")); + choices.insert(p_t(256*7+ 205, "HD PENTAX-DA 35mm f/2.8 Macro Limited")); + choices.insert(p_t(256*7+ 206, "HD PENTAX-DA 70mm f/2.4 Limited")); + choices.insert(p_t(256*7+ 207, "HD PENTAX-DA 21mm f/3.2 ED AL Limited")); + choices.insert(p_t(256*7+ 208, "HD PENTAX-DA 40mm f/2.8 Limited")); + choices.insert(p_t(256*7+ 212, "smc PENTAX-DA 50mm f/1.8")); + choices.insert(p_t(256*7+ 213, "smc PENTAX-DA 40mm f/2.8 XS")); + choices.insert(p_t(256*7+ 214, "smc PENTAX-DA 35mm f/2.4 AL")); + choices.insert(p_t(256*7+ 216, "smc PENTAX-DA L 55-300mm f/4-5.8 ED")); + choices.insert(p_t(256*7+ 217, "smc PENTAX-DA 50-200mm f/4-5.6 ED WR")); + choices.insert(p_t(256*7+ 218, "smc PENTAX-DA 18-55mm f/3.5-5.6 AL WR")); + choices.insert(p_t(256*7+ 220, "Tamron SP AF 10-24mm f/3.5-4.5 Di II LD Aspherical [IF]")); + choices.insert(p_t(256*7+ 221, "smc PENTAX-DA L 50-200mm f/4-5.6 ED")); + choices.insert(p_t(256*7+ 222, "smc PENTAX-DA L 18-55mm f/3.5-5.6")); + choices.insert(p_t(256*7+ 223, "Samsung/Schneider D-XENON 18-55mm f/3.5-5.6 II")); + choices.insert(p_t(256*7+ 224, "smc PENTAX-DA 15mm f/4 ED AL Limited")); + choices.insert(p_t(256*7+ 225, "Samsung/Schneider D-XENON 18-250mm f/3.5-6.3")); + choices.insert(p_t(256*7+ 226, "smc PENTAX-DA* 55mm f/1.4 SDM (SDM unused)")); + choices.insert(p_t(256*7+ 227, "smc PENTAX-DA* 60-250mm f/4 [IF] SDM (SDM unused)")); + choices.insert(p_t(256*7+ 228, "Samsung 16-45mm f/4 ED")); + choices.insert(p_t(256*7+ 229, "smc PENTAX-DA 18-55mm f/3.5-5.6 AL II")); + choices.insert(p_t(256*7+ 230, "Tamron AF 17-50mm f/2.8 XR Di-II LD (Model A16)")); + choices.insert(p_t(256*7+ 231, "smc PENTAX-DA 18-250mm f/3.5-6.3 ED AL [IF]")); + choices.insert(p_t(256*7+ 233, "smc PENTAX-DA 35mm f/2.8 Macro Limited")); + choices.insert(p_t(256*7+ 234, "smc PENTAX-DA* 300mm f/4 ED [IF] SDM (SDM unused)")); + choices.insert(p_t(256*7+ 235, "smc PENTAX-DA* 200mm f/2.8 ED [IF] SDM (SDM unused)")); + choices.insert(p_t(256*7+ 236, "smc PENTAX-DA 55-300mm f/4-5.8 ED")); + choices.insert(p_t(256*7+ 238, "Tamron AF 18-250mm f/3.5-6.3 Di II LD Aspherical [IF] Macro")); + choices.insert(p_t(256*7+ 241, "smc PENTAX-DA* 50-135mm f/2.8 ED [IF] SDM (SDM unused)")); + choices.insert(p_t(256*7+ 242, "smc PENTAX-DA* 16-50mm f/2.8 ED AL [IF] SDM (SDM unused)")); + choices.insert(p_t(256*7+ 243, "smc PENTAX-DA 70mm f/2.4 Limited")); + choices.insert(p_t(256*7+ 244, "smc PENTAX-DA 21mm f/3.2 AL Limited")); + choices.insert(p_t(256*8+ 3, "Sigma AF 18-125mm f/3.5-5.6 DC")); + choices.insert(p_t(256*8+ 4, "Sigma 50mm f/1.4 EX DG HSM")); + choices.insert(p_t(256*8+ 8, "Sigma 18-250mm f/3.5-6.3 DC OS HSM")); + choices.insert(p_t(256*8+ 11, "Sigma 10-20mm f/3.5 EX DC HSM")); + choices.insert(p_t(256*8+ 12, "Sigma 70-300mm f/4-5.6 DG OS")); + choices.insert(p_t(256*8+ 13, "Sigma 120-400mm f/4.5-5.6 APO DG OS HSM")); + choices.insert(p_t(256*8+ 14, "Sigma 17-70mm f/2.8-4.0 DC Macro OS HSM")); + choices.insert(p_t(256*8+ 15, "Sigma 150-500mm f/5-6.3 APO DG OS HSM")); + choices.insert(p_t(256*8+ 16, "Sigma 70-200mm f/2.8 EX DG Macro HSM II")); + choices.insert(p_t(256*8+ 17, "Sigma 50-500mm f/4.5-6.3 DG OS HSM")); + choices.insert(p_t(256*8+ 18, "Sigma 8-16mm f/4.5-5.6 DC HSM")); + choices.insert(p_t(256*8+ 21, "Sigma 17-50mm f/2.8 EX DC OS HSM")); + choices.insert(p_t(256*8+ 22, "Sigma 85mm f/1.4 EX DG HSM")); + choices.insert(p_t(256*8+ 23, "Sigma 70-200mm f/2.8 APO EX DG OS HSM")); + choices.insert(p_t(256*8+ 27, "Sigma 18-200mm f/3.5-6.3 II DC HSM")); + choices.insert(p_t(256*8+ 28, "Sigma 18-250mm f/3.5-6.3 DC Macro HSM")); + choices.insert(p_t(256*8+ 30, "Sigma 17-70mm f/2.8-4 DC Macro HSM | C")); // "| C" stands for "Contemporary" product line + choices.insert(p_t(256*8+ 210, "smc PENTAX-DA 18-270mm f/3.5-6.3 ED SDM")); + choices.insert(p_t(256*8+ 211, "HD PENTAX-DA 560mm f/5.6 ED AW")); + choices.insert(p_t(256*8+ 215, "smc PENTAX-DA 18-135mm f/3.5-5.6 ED AL [IF] DC WR")); + choices.insert(p_t(256*8+ 226, "smc PENTAX-DA* 55mm f/1.4 SDM")); + choices.insert(p_t(256*8+ 227, "smc PENTAX-DA* 60-250mm f/4 [IF] SDM")); + choices.insert(p_t(256*8+ 232, "smc PENTAX-DA 17-70mm f/4 AL [IF] SDM")); + choices.insert(p_t(256*8+ 234, "smc PENTAX-DA* 300mm f/4 ED [IF] SDM")); + choices.insert(p_t(256*8+ 235, "smc PENTAX-DA* 200mm f/2.8 ED [IF] SDM")); + choices.insert(p_t(256*8+ 241, "smc PENTAX-DA* 50-135mm f/2.8 ED [IF] SDM")); + choices.insert(p_t(256*8+ 242, "smc PENTAX-DA* 16-50mm f/2.8 ED AL [IF] SDM")); + choices.insert(p_t(256*8+ 255, "Sigma 70-200mm f/2.8 EX DG Macro HSM II")); + choices.insert(p_t(256*8+ 255, "Sigma 150-500mm f/5-6.3 DG APO [OS] HSM")); + choices.insert(p_t(256*8+ 255, "Sigma 50-150mm f/2.8 II APO EX DC HSM")); + choices.insert(p_t(256*8+ 255, "Sigma 4.5mm f/2.8 EX DC HSM Circular Fisheye")); + choices.insert(p_t(256*8+ 255, "Sigma 50-200mm f/4-5.6 DC OS")); + choices.insert(p_t(256*8+ 255, "Sigma 24-70mm f/2.8 EX DG HSM")); + choices.insert(p_t(256*9+ 0, "645 Manual Lens")); + choices.insert(p_t(256*10+ 0, "645 A Series Lens")); + choices.insert(p_t(256*11+ 1, "smc PENTAX-FA 645 75mm f/2.8")); + choices.insert(p_t(256*11+ 2, "smc PENTAX-FA 645 45mm f/2.8")); + choices.insert(p_t(256*11+ 3, "smc PENTAX-FA* 645 300mm f/4 ED [IF]")); + choices.insert(p_t(256*11+ 4, "smc PENTAX-FA 645 45-85mm f/4.5")); + choices.insert(p_t(256*11+ 5, "smc PENTAX-FA 645 400mm f/5.6 ED [IF]")); + choices.insert(p_t(256*11+ 7, "smc PENTAX-FA 645 Macro 120mm f/4")); + choices.insert(p_t(256*11+ 8, "smc PENTAX-FA 645 80-160mm f/4.5")); + choices.insert(p_t(256*11+ 9, "smc PENTAX-FA 645 200mm f/4 [IF]")); + choices.insert(p_t(256*11+ 10, "smc PENTAX-FA 645 150mm f/2.8 [IF]")); + choices.insert(p_t(256*11+ 11, "smc PENTAX-FA 645 35mm f/3.5 AL [IF]")); + choices.insert(p_t(256*11+ 12, "smc PENTAX-FA 645 300mm f/5.6 ED [IF]")); + choices.insert(p_t(256*11+ 14, "smc PENTAX-FA 645 55-110mm f/5.6")); + choices.insert(p_t(256*11+ 16, "smc PENTAX-FA 645 33-55mm f/4.5 AL")); + choices.insert(p_t(256*11+ 17, "smc PENTAX-FA 645 150-300mm f/5.6 ED [IF]")); + choices.insert(p_t(256*13+ 18, "smc PENTAX-D FA 645 55mm f/2.8 AL [IF] SDM AW")); + 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*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")); + choices.insert(p_t(256*21+ 6, "06 Telephoto Zoom 15-45mm f/2.8")); + choices.insert(p_t(256*21+ 7, "07 Mount Shield 11.5mm f/9")); + choices.insert(p_t(256*22+ 3, "03 Fish-eye 3.2mm f/5.6")); + choices.insert(p_t(256*22+ 4, "04 Toy Lens Wide 6.3mm f/7.1")); + choices.insert(p_t(256*22+ 5, "05 Toy Lens Telephoto 18mm f/8")); + } + virtual std::string toString (Tag* t) { + double *liArray = NULL; + double maxApertureAtFocal = 0.; + double focalLength = 0.; + int lensID = 256*t->toInt(0,BYTE) + t->toInt(1,BYTE); + TagDirectory *root=t->getParent()->getRoot(); + if (root){ + + Tag *t1; + t1 = root->findTag("FocalLength"); // Should get tag 0x920A (rational64u) from the standard Exif tag list + if( t1) + focalLength = t1->toDouble(); // Focal Length + + t1 = root->findTag("MaxAperture"); + if(t1){ + double maxAperture = t1->toDouble(); // MaxApertureValue at focal Length + if (maxAperture != 0.) + maxApertureAtFocal = maxAperture; + else { + t1 = root->findTag("NominalMaxAperture"); + if(t1) + maxApertureAtFocal = t1->toDouble(); + } + } + + t1 = root->getTagP("LensInfo"); + if(t1) + liArray = t1->toDoubleArray(); + + // Focal length below 10mm are set to 0 by the camera in the standard Exif tag, so we'll look into the makernotes + // This value will have decimals, which reflects more precision... or imprecision, due to the packed form of this value, who knows? + if (focalLength == 0.) { + rtexif::TagDirectory* mnote = root->findTag("MakerNote")->getDirectory(); + rtexif::Tag* flt=mnote->getTagP("LensInfo/FocalLength"); + if (flt) + focalLength = flt->toDouble (); + else if ((flt = mnote->getTagP ("FocalLength"))) + focalLength = flt->toDouble(); + } + } + std::string retval = guess( lensID, focalLength, maxApertureAtFocal, liArray); + if(liArray) + delete [] liArray; + return retval; + } +}; +PALensTypeInterpreter paLensTypeInterpreter; + +class PASRResultInterpreter: public Interpreter { +public: + PASRResultInterpreter(){ } + virtual std::string toString (Tag* t) { + std::ostringstream str; + int b = t->toInt(0,BYTE); + if (!b) + str << "Not stabilized"; + else if (b & 1) + str << "Stabilized"; + else if (b & 64) + str << "Not Ready"; + return str.str(); + } +}; +PASRResultInterpreter paSRResultInterpreter; + +class PAHighISONoiseInterpreter: public ChoiceInterpreter { +public: + PAHighISONoiseInterpreter(){ + choices[0] = "Off"; + choices[1] = "Weakest"; + choices[2] = "Weak"; + choices[3] = "Strong"; + } +}; +PAHighISONoiseInterpreter paHighISONoiseInterpreter; + +class PAMonochromeFilterEffectInterpreter: public ChoiceInterpreter { +public: + PAMonochromeFilterEffectInterpreter(){ + choices[1] = "Green"; + choices[2] = "Yellow"; + choices[3] = "Orange"; + choices[4] = "Red"; + choices[5] = "Magenta"; + choices[6] = "Blue"; + choices[7] = "Cyan"; + choices[8] = "Infrared"; + choices[65535] = "None"; + } +}; +PAMonochromeFilterEffectInterpreter paMonochromeFilterEffectInterpreter; + +class PAMonochromeToningInterpreter: public ChoiceInterpreter { +public: + PAMonochromeToningInterpreter(){ + choices[0] = "-4"; + choices[1] = "-3"; + choices[2] = "-2"; + choices[3] = "-1"; + choices[4] = "0"; + choices[5] = "1"; + choices[6] = "2"; + choices[7] = "3"; + choices[8] = "4"; + choices[65535] = "None"; + } +}; +PAMonochromeToningInterpreter paMonochromeToningInterpreter; + +class PAShadowCorrectionInterpreter: public ChoiceInterpreter { +public: + PAShadowCorrectionInterpreter(){ + choices[ 0 ] = "Off"; + choices[ 1 ] = "On"; + choices[ 2 ] = "Auto 2"; + choices[ 1<<8 | 1 ] = "Weak"; + choices[ 1<<8 | 2 ] = "Normal"; + choices[ 1<<8 | 3 ] = "Strong"; + choices[ 2<<8 | 4 ] = "Auto"; + } + + virtual std::string toString (Tag* t) { + int idx = 0; + if (t->getCount() == 1) + idx = t->toInt(0,BYTE); + else if (t->getCount() == 2) + idx = t->toInt(0,BYTE) << 8 | t->toInt(1,BYTE); + + std::map::iterator r = choices.find (idx); + std::ostringstream s; + s << ((r !=choices.end())? r->second : "n/a"); + return s.str(); + } +}; +PAShadowCorrectionInterpreter paShadowCorrectionInterpreter; + +class PAISOAutoParametersInterpreter: public ChoiceInterpreter { +public: + PAISOAutoParametersInterpreter(){ + choices[1] = "Slow"; + choices[2] = "Standard"; + choices[3] = "Fast"; + } + virtual std::string toString (Tag* t) { + std::map::iterator r = choices.find (t->toInt(0,BYTE)); + std::ostringstream s; + s << ((r !=choices.end())? r->second : "n/a"); + return s.str(); + } +}; +PAISOAutoParametersInterpreter paISOAutoParametersInterpreter; + +class PABleachBypassToningInterpreter: public ChoiceInterpreter { +public: + PABleachBypassToningInterpreter(){ + choices[1] = "Green"; + choices[2] = "Yellow"; + choices[3] = "Orange"; + choices[4] = "Red"; + choices[5] = "Magenta"; + choices[6] = "Purple"; + choices[7] = "Blue"; + choices[8] = "Cyan"; + choices[65535] = "Off"; + } +}; +PABleachBypassToningInterpreter paBleachBypassToningInterpreter; + +class PABlurControlInterpreter: public ChoiceInterpreter { +public: + PABlurControlInterpreter(){ + choices[0] = "Off"; + choices[1] = "Low"; + choices[2] = "Medium"; + choices[3] = "High"; + } + virtual std::string toString (Tag* t) { + std::map::iterator r = choices.find (t->toInt(0,BYTE)); + std::ostringstream s; + s << ((r !=choices.end())? r->second : "n/a"); + return s.str(); + } +}; +PABlurControlInterpreter paBlurControlInterpreter; + +class PAHDRInterpreter: public ChoiceInterpreter { + std::map choices1; + std::map choices2; +public: + PAHDRInterpreter(){ + choices[0] = "Off"; + choices[1] = "HDR Auto"; + choices[2] = "HDR 1"; + choices[3] = "HDR 2"; + choices[4] = "HDR 3"; + + choices1[0] = "Auto-align Off"; + choices1[1] = "Auto-align On"; + + choices2[0] = "n/a"; + choices2[1] = "1 EV"; + choices2[2] = "2 EV"; + choices2[4] = "3 EV"; + } + virtual std::string toString (Tag* t) { + std::map::iterator r = choices.find (t->toInt(0,BYTE)); + std::map::iterator r1 = choices1.find (t->toInt(1,BYTE)); + std::map::iterator r2 = choices2.find (t->toInt(2,BYTE)); + std::ostringstream s; + s << ((r !=choices.end() )? r->second : "") << std::endl; + s << ((r1!=choices1.end())? r1->second : "") << std::endl; + s << ((r2!=choices2.end())? r2->second : ""); + return s.str(); + } +}; +PAHDRInterpreter paHDRInterpreter; + +class PACrossProcessInterpreter: public ChoiceInterpreter { +public: + PACrossProcessInterpreter(){ + choices[ 0] = "Off"; + choices[ 1] = "Randow"; + choices[ 2] = "Preset 1"; + choices[ 3] = "Preset 2"; + choices[ 4] = "Preset 3"; + choices[33] = "Favorite 1"; + choices[34] = "Favorite 2"; + choices[35] = "Favorite 3"; + } +}; +PACrossProcessInterpreter paCrossProcessInterpreter; + +class PAPowerSourceInterpreter: public ChoiceInterpreter { +public: + PAPowerSourceInterpreter(){ + choices[2] = "Body Battery"; + choices[3] = "Grip Battery "; + choices[4] = "External Power Supply"; + } +}; +PAPowerSourceInterpreter paPowerSourceInterpreter; + +class PALensModelQInterpreter: public Interpreter { +public: + PALensModelQInterpreter(){} + virtual std::string toString (Tag* t){ + char buffer[31]; + buffer[0] = 0; // + return buffer; // TODO: how to get the string content!? + + // normal path below (copy the content of the string), but has to be bug fixed + memcpy(buffer, t->getValue(), 30); + buffer[30] = 0; + return buffer; + } +}; +PALensModelQInterpreter paLensModelQInterpreter; + +class PALensInfoQInterpreter: public Interpreter { +public: + PALensInfoQInterpreter(){} + virtual std::string toString (Tag* t){ + char buffer[21]; + buffer[0] = 0; + return buffer; // TODO: how to get the string content!? + + // normal path below (copy the content of the string), but has to be bug fixed + memcpy(buffer, t->getValue(), 20); + buffer[20] = 0; + return buffer; + } +}; +PALensInfoQInterpreter paLensInfoQInterpreter; + +class PAFlashExposureCompInterpreter: public Interpreter { +public: + PAFlashExposureCompInterpreter(){} + virtual std::string toString (Tag* t){ + int a; + if (t->getCount() == 1) a = t->toInt(0, SLONG) / 256; // int32u + else a = t->toInt(0, SBYTE) / 6; // int8u[2] + char buffer[10]; + sprintf (buffer, "%d", a ); + return buffer; + } + virtual double toDouble (Tag* t, int ofs){ + int a; + if (t->getCount() == 1) a = t->toInt(0, SLONG) / 256; // int32u + else a = t->toInt(0, SBYTE) / 6; // int8u[2] + return double(a); + } +}; +PAFlashExposureCompInterpreter paFlashExposureCompInterpreter; + +class PAFocalLengthInterpreter: public Interpreter { +public: + PAFocalLengthInterpreter(){} + virtual std::string toString (Tag* t){ + double a = double(t->toInt(0,LONG)); + if(a>1.){ + char buffer[10]; + sprintf (buffer, "%.2f", a/100. ); + return buffer; + }else + return "n/a"; + } + virtual double toDouble (Tag* t, int ofs){ + double a = double(t->toInt(0,LONG)); + if(a>1.) + return a/100.; + else + return 0.; + } +}; +PAFocalLengthInterpreter paFocalLengthInterpreter; + +class PALensDataFocalLengthInterpreter: public Interpreter { +public: + PALensDataFocalLengthInterpreter(){} + virtual std::string toString (Tag* t){ + int a = t->toInt(0,BYTE); + float b = float(10*int(a>>2)) * pow(4.f, float(int(a&0x03)-2)); + if(b>1.f){ + char buffer[10]; + sprintf (buffer, "%.2f", b ); + return buffer; + }else + return "n/a"; + } + virtual double toDouble (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)); + if(b>1.f) + return b; + else + return 0.; + } +}; +PALensDataFocalLengthInterpreter paLensDataFocalLengthInterpreter; + +class PAISOfInterpreter: public Interpreter { + public: + PAISOfInterpreter(){} + virtual std::string toString (Tag* t){ + int a = t->toInt(0,BYTE); + char buffer[32]; + double v = 100.*exp(double(a-32)*log(2.)/8.); + sprintf (buffer, "%.1f", v ); + return buffer; + } + virtual double toDouble (Tag* t, int ofs){ + int a = t->toInt(0,BYTE); + return 100.*exp(double(a-32)*log(2.)/8.); + } +}; +PAISOfInterpreter paISOfInterpreter; + +class PAMaxApertureInterpreter: public Interpreter { + public: + PAMaxApertureInterpreter(){} + virtual std::string toString (Tag* t){ + int a = t->toInt(0,BYTE); + a &= 0x7F; + if(a>1){ + char buffer[32]; + double v = pow(2.0, (a-1)/32.0); + if( v < 0. || v > 1000. ) return "undef"; + sprintf (buffer, "%.1f", v ); + return buffer; + }else + return "n/a"; + } + virtual double toDouble (Tag* t, int ofs){ + int a = t->toInt(0,BYTE); + a &= 0x7F; + if(a>1) + return pow(2.0, double(a-1)/32.0); + else + return 0.; + } +}; +PAMaxApertureInterpreter paMaxApertureInterpreter; + +class PAAEXvInterpreter: public Interpreter { + public: + PAAEXvInterpreter(){} + virtual std::string toString (Tag* t){ + int a = t->toInt(0,BYTE); + char buffer[32]; + double v = double(a-64)/8.; + sprintf (buffer, "%.1f", v ); + return buffer; + } + virtual double toDouble (Tag* t, int ofs){ + int a = t->toInt(0,BYTE); + return double(a-64)/8.; + } +}; +PAAEXvInterpreter paAEXvInterpreter; + +class PAAEBXvInterpreter: public Interpreter { + public: + PAAEBXvInterpreter(){} + virtual std::string toString (Tag* t){ + int a = t->toInt(0,SBYTE); + char buffer[32]; + double v = double(a)/8.; + sprintf (buffer, "%.1f", v ); + return buffer; + } + virtual double toDouble (Tag* t, int ofs){ + int a = t->toInt(0,SBYTE); + return double(a)/8.; + } +}; +PAAEBXvInterpreter paAEBXvInterpreter; + +class PAApertureInterpreter: public Interpreter { + public: + PAApertureInterpreter(){} + virtual std::string toString (Tag* t){ + int a = t->toInt(0,BYTE); + char buffer[32]; + double v = exp((double(a)-68.)*log(2.)/16.); + sprintf (buffer, "%.1f", v ); + return buffer; + } + virtual double toDouble (Tag* t, int ofs){ + int a = t->toInt(0,BYTE); + return exp((double(a)-68.)*log(2.)/16.); + } +}; +PAApertureInterpreter paApertureInterpreter; + +class PAExposureTimeInterpreter: public Interpreter { + public: + PAExposureTimeInterpreter(){} + virtual std::string toString (Tag* t){ + int a = t->toInt(0,BYTE); + char buffer[32]; + double v = 24.*exp(-(double(a)-32.)*log(2.)/8.); + sprintf (buffer, "%.6f", v ); + return buffer; + } + virtual double toDouble (Tag* t, int ofs){ + int a = t->toInt(0,BYTE); + return 24.*exp(-(double(a)-32.)*log(2.)/8.); + } +}; +PAExposureTimeInterpreter paExposureTimeInterpreter; + +class PANominalMinApertureInterpreter: public Interpreter { +public: + PANominalMinApertureInterpreter(){} + virtual std::string toString (Tag* t){ + char buffer[32]; + int a = t->toInt(0,BYTE); + int mina = a & 0x0F; + sprintf (buffer, "%.1f", double(int(pow(2.0, double(mina+10)/4.0)+0.2))); + return buffer; + } + virtual double toDouble (Tag* t, int ofs){ + int a = t->toInt(0,BYTE) & 0x0F; + return double(int(pow(2.0, double(a+10)/4.0)+0.2)); + } +}; +PANominalMinApertureInterpreter paNominalMinApertureInterpreter; + +class PANominalMaxApertureInterpreter: public Interpreter { +public: + PANominalMaxApertureInterpreter(){} + virtual std::string toString (Tag* t){ + char buffer[32]; + int a = t->toInt(0,BYTE); + int maxa = (a & 0xF0)>>4; + sprintf (buffer, "%.1f", double(int(pow(2.0, double(maxa)/4.0)+0.2)) ); + return buffer; + } + virtual double toDouble (Tag* t, int ofs){ + int a = ( t->toInt(0,BYTE) & 0xF0)>>4; + return double(int(pow(2.0, double(a)/4.0)+0.2)); + } +}; +PANominalMaxApertureInterpreter paNominalMaxApertureInterpreter; + +class PAFlashStatusInterpreter: public ChoiceInterpreter { +public: + PAFlashStatusInterpreter(){ + choices[0x0] = "Off"; + choices[0x2] = "External, Did not fire"; + choices[0x6] = "External, Fired"; + choices[0x9] = "Internal, Did not fire"; + choices[0xd] = "Internal, Fired"; + } +}; +PAFlashStatusInterpreter paFlashStatusInterpreter; + +class PAInternalFlashModeInterpreter: public ChoiceInterpreter { +public: + PAInternalFlashModeInterpreter(){ + choices[0x0] = "n/a - Off-Auto-Aperture"; + choices[0x86] = "On, Wireless (Control)"; + choices[0x95] = "On, Wireless (Master)"; + choices[0xc0] = "On"; + choices[0xc1] = "On, Red-eye reduction"; + choices[0xc2] = "On, Auto"; + choices[0xc3] = "On, Auto, Red-eye reduction"; + choices[0xc8] = "On, Slow-sync"; + choices[0xc9] = "On, Slow-sync, Red-eye reduction"; + choices[0xca] = "On, Trailing-curtain Sync"; + choices[0xf0] = "Off, Normal"; + choices[0xf1] = "Off, Red-eye reduction"; + choices[0xf2] = "Off, Auto"; + choices[0xf3] = "Off, Auto, Red-eye reduction"; + choices[0xf4] = "Off, (Unknown 0xf4)"; + choices[0xf5] = "Off, Wireless (Master)"; + choices[0xf6] = "Off, Wireless (Control)"; + choices[0xf8] = "Off, Slow-sync"; + choices[0xf9] = "Off, Slow-sync, Red-eye reduction"; + choices[0xfa] = "Off, Trailing-curtain Sync"; + } +}; +PAInternalFlashModeInterpreter paInternalFlashModeInterpreter; + +class PAExternalFlashModeInterpreter: public ChoiceInterpreter { + public: + PAExternalFlashModeInterpreter(){ + choices[0x0 ]= "n/a - Off-Auto-Aperture"; + choices[0x3f] = "Off"; + choices[0x40] = "On, Auto"; + choices[0xbf] = "On, Flash Problem"; + choices[0xc0] = "On, Manual"; + choices[0xc4] = "On, P-TTL Auto"; + choices[0xc5] = "On, Contrast-control Sync"; + choices[0xc6] = "On, High-speed Sync"; + choices[0xcc] = "On, Wireless"; + choices[0xcd] = "On, Wireless, High-speed Sync"; + } +}; +PAExternalFlashModeInterpreter paExternalFlashModeInterpreter; + +class PAExternalFlashExposureCompInterpreter: public ChoiceInterpreter { + public: + PAExternalFlashExposureCompInterpreter(){ + choices[0] = "n/a"; + choices[144] = "n/a (Manual Mode)"; + choices[164] = "-3.0"; + choices[167] = "-2.5"; + choices[168] = "-2.0"; + choices[171] = "-1.5"; + choices[172] = "-1.0"; + choices[175] = "-0.5"; + choices[176] = "0"; + choices[179] = "+0.5"; + choices[180] = "+1.0"; + } +}; +PAExternalFlashExposureCompInterpreter paExternalFlashExposureCompInterpreter; + +class PAExternalFlashBounceInterpreter: public ChoiceInterpreter { + public: + PAExternalFlashBounceInterpreter(){ + choices[0] = "n/a"; + choices[16] = "Direct"; + choices[48] = "Bonce"; + } +}; +PAExternalFlashBounceInterpreter paExternalFlashBounceInterpreter; + +class PAExternalFlashGNInterpreter: public Interpreter { + public: + PAExternalFlashGNInterpreter(){} + virtual std::string toString (Tag* t) { + char buffer[1024]; + int b = t->toInt(0,BYTE) & 0x1F; + sprintf (buffer, "%.0f", pow(2.,b/16.+4) ); + return buffer; + } +}; +PAExternalFlashGNInterpreter paExternalFlashGNInterpreter; + +class PAEVStepsInterpreter:public Interpreter { +public: + PAEVStepsInterpreter(){} + virtual std::string toString (Tag* t) { + std::ostringstream str; + if( t->toInt(0,BYTE) & 0x20 ) + str << "1/3 EV steps"; + else + str << "1/2 EV steps"; + return str.str(); + } +}; +PAEVStepsInterpreter paEVStepsInterpreter; + +class PAEDialinInterpreter:public Interpreter { +public: + PAEDialinInterpreter(){} + virtual std::string toString (Tag* t) { + std::ostringstream str; + if( t->toInt(0,BYTE) & 0x40 ) + str << "P Shift"; + else + str << "Tv or Av"; + return str.str(); + } +}; +PAEDialinInterpreter paEDialinInterpreter; + +class PAApertureRingUseInterpreter: public Interpreter { +public: + PAApertureRingUseInterpreter(){} + virtual std::string toString (Tag* t) { + std::ostringstream str; + if( t->toInt(0,BYTE) & 0x80 ) + str << "Permitted"; + else + str << "Prohibited"; + return str.str(); + } +}; +PAApertureRingUseInterpreter paApertureRingUseInterpreter; + +class PAFlashOptionInterpreter: public ChoiceInterpreter { +public: + PAFlashOptionInterpreter(){ + choices[0x0] = "Normal"; + choices[0x1] = "Red-eye reduction"; + choices[0x2] = "Auto"; + choices[0x3] = "Auto, Red-eye reduction"; + choices[0x5] = "Wireless (Master)"; + choices[0x6] = "Wireless (Control)"; + choices[0x8] = "Slow-sync"; + choices[0x9] = "Slow-sync, Red-eye reduction"; + choices[0xa] = "Trailing-curtain Sync"; + } + virtual std::string toString (Tag* t) { + std::map::iterator r = choices.find (t->toInt(0,BYTE) >>4); + if (r!=choices.end()) + return r->second; + else { + char buffer[1024]; + t->toString (buffer); + return std::string (buffer); + } + } +}; +PAFlashOptionInterpreter paFlashOptionInterpreter; + +class PAMeteringMode2Interpreter: public Interpreter { +public: + PAMeteringMode2Interpreter(){} + virtual std::string toString (Tag* t) { + std::ostringstream str; + int v = (t->toInt(0,BYTE) & 0xF); + if(!v) + str << "Multi-segment"; + else if(v&1) + str << "Center-weighted average"; + else if(v&2) + str << "Spot"; + return str.str(); + } +}; +PAMeteringMode2Interpreter paMeteringMode2Interpreter; + +class PAExposureBracketStepSizeInterpreter: public ChoiceInterpreter { +public: + PAExposureBracketStepSizeInterpreter(){ + choices[3] = "0.3"; + choices[4] = "0.5"; + choices[5] = "0.7"; + choices[8] = "1.0"; + choices[11] = "1.3"; + choices[12] = "1.5"; + choices[13] = "1.7"; + choices[16] = "2.0"; + } +}; +PAExposureBracketStepSizeInterpreter paExposureBracketStepSizeInterpreter; + +class PAPictureMode2Interpreter: public ChoiceInterpreter { +public: + PAPictureMode2Interpreter(){ + choices[0] = "Scene Mode"; + choices[1] = "Auto PICT"; + choices[2] = "Program AE"; + choices[3] = "Green Mode"; + choices[4] = "Shutter Speed Priority"; + choices[5] = "Aperture Priority"; + choices[6] = "Program Tv Shift"; + choices[7] = "Program Av Shift"; + choices[8] = "Manual"; + choices[9] = "Bulb"; + choices[10] = "Aperture Priority, Off-Auto-Aperture"; + choices[11] = "Manual, Off-Auto-Aperture"; + choices[12] = "Bulb, Off-Auto-Aperture"; + choices[13] = "Shutter & Aperture Priority AE"; + choices[15] = "Sensitivity Priority AE"; + choices[16] = "Flash X-Sync Speed AE"; + } +}; +PAPictureMode2Interpreter paPictureMode2Interpreter; + +class PAProgramLineInterpreter: public Interpreter { +public: + PAProgramLineInterpreter(){} + virtual std::string toString (Tag* t) { + std::ostringstream str; + int c = t->toInt(0,BYTE); + switch(c & 0xf){ + case 0: str << "Manual";break; + case 1: str << "AF-S";break; + case 2: str << "AF-C";break; + case 3: str << "AF-A";break; + } + if( (c & 0xF0) == 0) str << ", Point Selection Auto"; + else if( c & 0x20 ) str << ", Fixed Center Point Selected"; + else if( c & 0x10 ) str << ", Point Selected"; + return str.str(); + } +}; +PAProgramLineInterpreter paProgramLineInterpreter; + +class PAAFModeInterpreter: public Interpreter { +public: + PAAFModeInterpreter(){} + virtual std::string toString (Tag* t) { + switch(t->toInt(0,BYTE) & 0x3){ + case 0: return "Normal"; + case 1: return "Hi Speed"; + case 2: return "Depth"; + case 3: return "MTF"; + } + return"Normal"; + } + +}; +PAAFModeInterpreter paAFModeInterpreter; + +class PAAFPointSelectedInterpreter: public Interpreter { +public: + PAAFPointSelectedInterpreter(){} + virtual std::string toString (Tag* t) { + const char *ps[]={"Upper-left","Top","Upper-right","Left","Mid-left","Center","Mid-right","Right","Lower-left","Bottom","Lower-right"}; + int c = t->toInt(0,SHORT); + if( !c ) + return "Auto"; + else{ + for( int iBit=0; iBit<11; iBit++) + if( c & (1<toInt(0,BYTE); + if( !c ) + return "Single-frame"; + else if( c & 0x01) + return "Continuous"; + else if( c & 0x04) + return "Self-timer (12 s)"; + else if( c & 0x08) + return "Self-timer (2 s)"; + else if( c & 0x10 ) + return "Remote Control (3 s delay)"; + else if( c & 0x20) + return "Remote Control"; + else if( c & 0x40) + return "Exposure Bracket"; + else if( c & 0x80) + return "Multiple Exposure"; + else + return "Unknown"; + } +}; +PADriveMode2Interpreter paDriveMode2Interpreter; + +const TagAttrib pentaxAttribs[] = { + {0, AC_WRITE, 0, 0, 0x0000, AUTO, "PentaxVersion", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0001, AUTO, "PentaxModelType", &stdInterpreter}, + {0, AC_SYSTEM, 0, 0, 0x0002, AUTO, "PreviewImageSize", &stdInterpreter}, + {0, AC_SYSTEM, 0, 0, 0x0003, AUTO, "PreviewImageLength", &stdInterpreter}, + {0, AC_SYSTEM, 0, 0, 0x0004, AUTO, "PreviewImageStart", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0005, AUTO, "PentaxModelID", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0006, AUTO, "Date", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0007, AUTO, "Time", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0008, AUTO, "Quality", &paQualityInterpreter}, + {0, AC_WRITE, 0, 0, 0x0009, AUTO, "PentaxImageSize", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x000b, AUTO, "PictureMode", &paPictureModeInterpreter}, + {0, AC_WRITE, 0, 0, 0x000c, AUTO, "FlashMode", &paFlashModeInterpreter}, + {0, AC_WRITE, 0, 0, 0x000d, AUTO, "FocusMode", &paFocusModeInterpreter}, + {0, AC_WRITE, 0, 0, 0x000e, AUTO, "AFPointSelected", &paAFPointInterpreter}, + {0, AC_WRITE, 0, 0, 0x000f, AUTO, "AFPointsInFocus", &paAFFocusInterpreter}, + {0, AC_WRITE, 0, 0, 0x0010, AUTO, "FocusPosition", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0012, AUTO, "ExposureTime", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0013, AUTO, "FNumber", &paFNumberInterpreter}, + {0, AC_WRITE, 0, 0, 0x0014, AUTO, "ISO", &paISOInterpreter}, + {0, AC_WRITE, 0, 0, 0x0015, AUTO, "LightReading", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0016, AUTO, "ExposureCompensation", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0017, AUTO, "MeteringMode", &paMeteringModeInterpreter}, + {0, AC_WRITE, 0, 0, 0x0018, AUTO, "AutoBracketing", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0019, AUTO, "WhiteBalance", &paWhiteBalanceInterpreter}, + {0, AC_WRITE, 0, 0, 0x001a, AUTO, "WhiteBalanceMode", &paWhiteBalanceModeInterpreter}, + {0, AC_WRITE, 0, 0, 0x001b, AUTO, "BlueBalance", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x001c, AUTO, "RedBalance", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x001d, AUTO, "FocalLength", &paFocalLengthInterpreter}, + {0, AC_WRITE, 0, 0, 0x001e, AUTO, "DigitalZoom", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x001f, AUTO, "Saturation", &paSaturationInterpreter}, + {0, AC_WRITE, 0, 0, 0x0020, AUTO, "Contrast", &paContrastInterpreter}, + {0, AC_WRITE, 0, 0, 0x0021, AUTO, "Sharpness", &paSharpnessInterpreter}, + {0, AC_WRITE, 0, 0, 0x0022, AUTO, "WorldTimeLocation", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0023, AUTO, "HometownCity", &stdInterpreter}, + {0, AC_NEW, 0, 0, 0x0024, AUTO, "DestinationCity", &stdInterpreter}, + {0, AC_NEW, 0, 0, 0x0025, AUTO, "HometownDST", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0026, AUTO, "DestinationDST", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0027, AUTO, "DSPFirmwareVersion", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0028, AUTO, "CPUFirmwareVersion", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0029, AUTO, "FrameNumber", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x002d, AUTO, "EffectiveLV", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0032, AUTO, "ImageProcessing", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0033, AUTO, "PictureMode", &paPictureModeInterpreter2}, + {0, AC_WRITE, 0, 0, 0x0034, AUTO, "DriveMode", &paDriveModeInterpreter}, + {0, AC_WRITE, 0, 0, 0x0037, AUTO, "ColorSpace", &paColorSpaceInterpreter}, + {0, AC_WRITE, 0, 0, 0x0038, AUTO, "ImageAreaOffset", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0039, AUTO, "RawImageSize", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x003c, AUTO, "AFPointsInFocus", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x003e, AUTO, "PreviewImageBorders", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x003f, AUTO, "LensType", &paLensTypeInterpreter}, + {0, AC_WRITE, 0, 0, 0x0040, AUTO, "SensitivityAdjust", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0041, AUTO, "ImageProcessingCount", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0047, AUTO, "CameraTemperature", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0048, AUTO, "AELock", &paOnOffInterpreter}, + {0, AC_WRITE, 0, 0, 0x0049, AUTO, "NoiseReduction", &paOnOffInterpreter}, + {0, AC_WRITE, 0, 0, 0x004d, AUTO, "FlashExposureComp", &paFlashExposureCompInterpreter}, + {0, AC_WRITE, 0, 0, 0x004f, AUTO, "ImageTone", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0050, AUTO, "ColorTemperature", &stdInterpreter}, + {0, AC_WRITE, 0, pentaxSRInfoAttribs, 0x005c, AUTO, "ShakeReductionInfo", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x005d, AUTO, "ShutterCount", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0069, AUTO, "DynamicRangeExpansion", &paOnOffInterpreter}, + {0, AC_WRITE, 0, 0, 0x0071, AUTO, "HighISONoiseReduction", &paHighISONoiseInterpreter}, + {0, AC_WRITE, 0, 0, 0x0072, AUTO, "AFAdjustment", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0073, AUTO, "MonochromeFilterEffect", &paMonochromeFilterEffectInterpreter}, + {0, AC_WRITE, 0, 0, 0x0074, AUTO, "MonochromeToning", &paMonochromeToningInterpreter}, + {0, AC_WRITE, 0, 0, 0x0076, AUTO, "FaceDetect", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0077, AUTO, "FaceDetectFrameSize", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0079, AUTO, "ShadowCorrection", &paShadowCorrectionInterpreter}, + {0, AC_WRITE, 0, 0, 0x007a, AUTO, "ISOAutoParameters", &paISOAutoParametersInterpreter}, + {0, AC_WRITE, 0, 0, 0x007b, AUTO, "CrossProcess", &paCrossProcessInterpreter}, + {0, AC_WRITE, 0, pentaxLensCorrAttribs, 0x007d, AUTO, "LensCorr", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x007f, AUTO, "BleachBypassToning", &paBleachBypassToningInterpreter}, + {0, AC_WRITE, 0, 0, 0x0082, AUTO, "BlurControl", &paBlurControlInterpreter}, + {0, AC_WRITE, 0, 0, 0x0085, AUTO, "HDR", &paHDRInterpreter}, + {0, AC_WRITE, 0, 0, 0x0088, AUTO, "NeutralDensityFilter", &paOnOffInterpreter}, + {0, AC_WRITE, 0, 0, 0x008b, AUTO, "ISO", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0200, AUTO, "BlackPoint", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0201, AUTO, "WhitePoint", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0203, AUTO, "ColorMatrixA", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0204, AUTO, "ColorMatrixB", &stdInterpreter}, + {0, AC_WRITE, 0, pentaxCameraSettingsAttribs, 0x0205, AUTO, "CameraSettings", &stdInterpreter}, + {0, AC_WRITE, 0, pentaxAEInfoAttribs, 0x0206, AUTO, "AEInfo", &stdInterpreter}, + {0, AC_WRITE, 0, pentaxLensDataAttribs, 0x0207, AUTO, "LensInfo", &stdInterpreter}, + {0, AC_WRITE, 0, pentaxFlashInfoAttribs, 0x0208, AUTO, "FlashInfo", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0209, AUTO, "AEMeteringSegments", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x020a, AUTO, "FlashADump", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x020b, AUTO, "FlashBDump", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x020d, AUTO, "WB_RGGBLevelsDaylight", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x020e, AUTO, "WB_RGGBLevelsShade", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x020f, AUTO, "WB_RGGBLevelsCloudy", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0210, AUTO, "WB_RGGBLevelsTungsten", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0211, AUTO, "WB_RGGBLevelsFluorescentD", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0212, AUTO, "WB_RGGBLevelsFluorescentN", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0213, AUTO, "WB_RGGBLevelsFluorescentW", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0214, AUTO, "WB_RGGBLevelsFlash", &stdInterpreter}, + {0, AC_WRITE, 0, pentaxCameraInfoAttribs, 0x0215, AUTO, "CameraInfo", &stdInterpreter}, + {0, AC_WRITE, 0, pentaxBatteryInfoAttribs, 0x0216, AUTO, "BatteryInfo", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x021f, AUTO, "AFInfo", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0222, AUTO, "ColorInfo", &stdInterpreter}, + {0, AC_WRITE, 0, pentaxLensInfoQAttribs, 0x0239, AUTO, "LensInfoQ", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x03fe, AUTO, "DataDump", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x03ff, AUTO, "UnknownInfo", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0402, AUTO, "ToneCurve", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0403, AUTO, "ToneCurves", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0e00, AUTO, "PrintIM", &stdInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}}; + +const TagAttrib pentaxSRInfoAttribs[] = { + {0, AC_WRITE, 0, 0, 0, AUTO, "SRResult", &paSRResultInterpreter}, + {0, AC_WRITE, 0, 0, 1, AUTO, "ShakeReduction", &paShakeReductionInterpreter}, + {0, AC_WRITE, 0, 0, 2, AUTO, "SRHalfPressTime", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 3, AUTO, "SRFocalLength", &stdInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}}; + +const TagAttrib pentaxSRInfo2Attribs[] = { + {0, AC_WRITE, 0, 0, 0, AUTO, "SRResult", &paSRResultInterpreter}, // assuming it's the same interpreter, but that's not sure + {0, AC_WRITE, 0, 0, 1, AUTO, "ShakeReduction", &paShakeReduction2Interpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}}; + +const TagAttrib pentaxLensDataAttribs[] = { + {0, AC_WRITE, 0, 0, 9, AUTO, "FocalLength", &paLensDataFocalLengthInterpreter}, + {0, AC_WRITE, 0, 0, 10, AUTO, "NominalMaxAperture", &paNominalMaxApertureInterpreter}, + {0, AC_WRITE, 0, 0, 10, AUTO, "NominalMinAperture", &paNominalMinApertureInterpreter}, + {0, AC_WRITE, 0, 0, 14, AUTO, "MaxAperture", &paMaxApertureInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}}; + +const TagAttrib pentaxLensInfoQAttribs[] = { + {0, AC_WRITE, 0, 0, 12, AUTO, "LensModel", &paLensModelQInterpreter}, + {0, AC_WRITE, 0, 0, 42, AUTO, "LensInfo", &paLensInfoQInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}}; + +const TagAttrib pentaxLensCorrAttribs[] = { + {0, AC_WRITE, 0, 0, 0, AUTO, "DistortionCorrection", &paOnOffInterpreter}, + {0, AC_WRITE, 0, 0, 1, AUTO, "ChromaticAberrationCorrection", &paOnOffInterpreter}, + {0, AC_WRITE, 0, 0, 2, AUTO, "VignettingCorrection", &paOnOffInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}}; + +const TagAttrib pentaxCameraSettingsAttribs[] = { + {0, AC_WRITE, 0, 0, 0, AUTO, "PictureMode2", &paPictureMode2Interpreter}, + {0, AC_WRITE, 0, 0, 1, AUTO, "ProgramLine", &paProgramLineInterpreter}, + {0, AC_WRITE, 0, 0, 1, AUTO, "EVSteps", &paEVStepsInterpreter}, + {0, AC_WRITE, 0, 0, 1, AUTO, "E-DialinProgram", &paEDialinInterpreter}, + {0, AC_WRITE, 0, 0, 1, AUTO, "ApertureRing", &paApertureRingUseInterpreter}, + {0, AC_WRITE, 0, 0, 2, AUTO, "FlashOptions", &paFlashOptionInterpreter}, + {0, AC_WRITE, 0, 0, 2, AUTO, "MeteringMode2", &paMeteringMode2Interpreter}, + {0, AC_WRITE, 0, 0, 3, AUTO, "AFMode", &paAFModeInterpreter}, + {0, AC_WRITE, 0, 0, 4, AUTO, "AFPointSelected2", &paAFPointSelectedInterpreter}, + {0, AC_WRITE, 0, 0, 7, AUTO, "DriveMode2", &paDriveMode2Interpreter}, + {0, AC_WRITE, 0, 0, 8, AUTO, "ExposureBracketStepSize", &paExposureBracketStepSizeInterpreter}, + {0, AC_WRITE, 0, 0, 9, AUTO, "BracketShotNumber", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 10, AUTO, "WhiteBalanceSet", &stdInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}}; + +const TagAttrib pentaxAEInfoAttribs[] = { + {0, AC_WRITE, 0, 0, 0, AUTO, "AEExposureTime", &paExposureTimeInterpreter}, + {0, AC_WRITE, 0, 0, 1, AUTO, "AEAperture", &paApertureInterpreter}, + {0, AC_WRITE, 0, 0, 2, AUTO, "AE_ISO", &paISOfInterpreter}, + {0, AC_WRITE, 0, 0, 3, AUTO, "AEXv", &paAEXvInterpreter}, + {0, AC_WRITE, 0, 0, 4,SBYTE, "AEBXv", &paAEBXvInterpreter}, + {0, AC_WRITE, 0, 0, 5, AUTO, "AEMinExposureTime", &paExposureTimeInterpreter}, + {0, AC_WRITE, 0, 0, 6, AUTO, "AEProgramMode", &paAEProgramModeInterpreter}, + {0, AC_WRITE, 0, 0, 9, AUTO, "AEMaxAperture", &paApertureInterpreter}, + {0, AC_WRITE, 0, 0, 10, AUTO, "AEMaxAperture2", &paApertureInterpreter}, + {0, AC_WRITE, 0, 0, 11, AUTO, "AEMinAperture", &paApertureInterpreter}, + {0, AC_WRITE, 0, 0, 12, AUTO, "AEMeteringMode", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 14,SBYTE, "FlashExposureCompSet", &stdInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}}; + +const TagAttrib pentaxAEInfo2Attribs[] = { + {0, AC_WRITE, 0, 0, 2, AUTO, "AEExposureTime", &paExposureTimeInterpreter}, + {0, AC_WRITE, 0, 0, 3, AUTO, "AEAperture", &paApertureInterpreter}, + {0, AC_WRITE, 0, 0, 4, AUTO, "AE_ISO", &paISOfInterpreter}, + {0, AC_WRITE, 0, 0, 5, AUTO, "AEXv", &paAEXvInterpreter}, + {0, AC_WRITE, 0, 0, 6,SBYTE, "AEBXv", &paAEBXvInterpreter}, + {0, AC_WRITE, 0, 0, 8,SBYTE, "AEError", &stdInterpreter}, + //{0, AC_WRITE, 0, 0, 11, AUTO, "AEApertureSteps", &}, + {0, AC_WRITE, 0, 0, 15, AUTO, "SceneMode", &paSceneModeInterpreter}, + {0, AC_WRITE, 0, 0, 16, AUTO, "AEMaxAperture", &paApertureInterpreter}, + {0, AC_WRITE, 0, 0, 17, AUTO, "AEMaxAperture2", &paApertureInterpreter}, + {0, AC_WRITE, 0, 0, 18, AUTO, "AEMinAperture", &paApertureInterpreter}, + {0, AC_WRITE, 0, 0, 19, AUTO, "AEMinExposureTime", &paExposureTimeInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}}; + +const TagAttrib pentaxAEInfo3Attribs[] = { + {0, AC_WRITE, 0, 0, 16, AUTO, "AEExposureTime", &paExposureTimeInterpreter}, + {0, AC_WRITE, 0, 0, 17, AUTO, "AEAperture", &paApertureInterpreter}, + {0, AC_WRITE, 0, 0, 18, AUTO, "AE_ISO", &paISOfInterpreter}, + {0, AC_WRITE, 0, 0, 28, AUTO, "AEMaxAperture", &paApertureInterpreter}, + {0, AC_WRITE, 0, 0, 29, AUTO, "AEMaxAperture2", &paApertureInterpreter}, + {0, AC_WRITE, 0, 0, 30, AUTO, "AEMinAperture", &paApertureInterpreter}, + {0, AC_WRITE, 0, 0, 31, AUTO, "AEMinExposureTime", &paExposureTimeInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}}; + +const TagAttrib pentaxFlashInfoAttribs[] = { + {0, AC_WRITE, 0, 0, 0, AUTO, "FlashStatus", &paFlashStatusInterpreter}, + {0, AC_WRITE, 0, 0, 1, AUTO, "InternalFlashMode", &paInternalFlashModeInterpreter}, + {0, AC_WRITE, 0, 0, 2, AUTO, "ExternalFlashMode", &paExternalFlashModeInterpreter}, + {0, AC_WRITE, 0, 0, 3, AUTO, "InternalFlashStrength", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 24, AUTO, "ExternalFlashGuideNumber", &paExternalFlashGNInterpreter}, + {0, AC_WRITE, 0, 0, 25, AUTO, "ExternalFlashExposureComp", &paExternalFlashExposureCompInterpreter}, + {0, AC_WRITE, 0, 0, 26, AUTO, "ExternalFlashBounce", &paExternalFlashBounceInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}}; + +const TagAttrib pentaxBatteryInfoAttribs[] = { + {0, AC_WRITE, 0, 0, 0, AUTO, "PowerSource", &paPowerSourceInterpreter}, + {0, AC_WRITE, 0, 0, 1, AUTO, "BatteryStates", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 2, AUTO, "BatteryADBodyNoLoad", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 3, AUTO, "BatteryADBodyLoad", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 4, AUTO, "BatteryADGripNoLoad", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 5, AUTO, "BatteryADGripLoad", &stdInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}}; + +const TagAttrib pentaxCameraInfoAttribs[] = { + {0, AC_WRITE, 0, 0, 0, AUTO, "PentaxModelID", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 1, AUTO, "ManufactureDate", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 2, AUTO, "ProductionCode", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 4, AUTO, "InternalSerialNumber", &stdInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}}; + +} +#endif + + + + diff --git a/rtexif/rtexif.cc b/rtexif/rtexif.cc new file mode 100644 index 000000000..9701b9022 --- /dev/null +++ b/rtexif/rtexif.cc @@ -0,0 +1,2424 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * Some parts of the source code (e.g. ciff support) are taken from dcraw + * that is copyrighted by Dave Coffin + * + * 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 +#include +#include +#include + +#include "../rtgui/cacheimagedata.h" +#include "rtexif.h" +#include "../rtengine/safegtk.h" +#include "../rtgui/version.h" +#include "../rtgui/ppversion.h" + +using namespace std; + +namespace rtexif { + +Interpreter stdInterpreter; + +//--------------- class TagDirectory ------------------------------------------ +// this class is a collection (an array) of tags +//----------------------------------------------------------------------------- + +#define TAG_SUBFILETYPE 0x00fe + +TagDirectory::TagDirectory () + : attribs(ifdAttribs), order(HOSTORDER), parent(NULL) {} + +TagDirectory::TagDirectory (TagDirectory* p, const TagAttrib* ta, ByteOrder border) + : attribs(ta), order(border), parent(p) {} + +TagDirectory::TagDirectory (TagDirectory* p, FILE* f, int base, const TagAttrib* ta, ByteOrder border, bool skipIgnored) + : attribs(ta), order(border), parent(p) +{ + + int numOfTags = get2 (f, order); + if (numOfTags<=0 || numOfTags>1000) // KodakIfd has lots of tags, thus 1000 as the limit + return; + + bool thumbdescr = false; + for (int i=0; igetType()==0) { + delete newTag; + continue; + } + + if (skipIgnored) { + 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) + thumbdescr = true; + + const TagAttrib* attrib = getAttrib (id); + + if (!attrib || attrib->ignore==1 || (thumbdescr && attrib->ignore==2)) + delete newTag; + else + addTag (newTag); + } else addTag (newTag); + } +} + +TagDirectory::~TagDirectory () { + + for (size_t i=0; igetID() < b->getID(); + } +}; + +void TagDirectory::sort () { + + std::sort (tags.begin(), tags.end(), CompareTags()); + for (size_t i=0; iisDirectory()) + for (int j=0; tags[i]->getDirectory(j); j++) + tags[i]->getDirectory(j)->sort (); +} +TagDirectory* TagDirectory::getRoot() +{ + if(parent) return parent->getRoot(); + else return this; +} + +const TagAttrib* TagDirectory::getAttrib (int id) { + + if (attribs) + for (int i=0; attribs[i].ignore!=-1; i++) + if (attribs[i].ID==id) + return &attribs[i]; + + return NULL; +} + +const TagAttrib* TagDirectory::getAttrib (const char* name) { + + if (attribs) + for (int i=0; attribs[i].ignore!=-1; i++) + if (!strcmp (attribs[i].name, name)) + return &attribs[i]; + + return NULL; +} + +const TagAttrib* TagDirectory::getAttribP (const char* name) { + + if (attribs) + for (int i=0; attribs[i].ignore!=-1; i++) { + // Yeah, self made comparison! + const char *n = name; + const char *a = attribs[i].name; + while (*n && *a && *n==*a) { n++; a++; }; + if (!*a && (!*n || *n=='/')) { + // we reached the end of the subpart of name and the end of attribs->name, so they match + if (*n=='/') { + Tag* tag = getTag (attribs[i].ID); + TagDirectory *tagDir; + if (attribs[i].subdirAttribs && tag && (tagDir=tag->getDirectory())) + return tagDir->getAttribP(n+1); + else + return NULL; + } + else + return &attribs[i]; + } + } + return NULL; +} + +void TagDirectory::printAll (unsigned int level) const { + + // set the spacer prefix string + char prefixStr[level*4+1]; + unsigned int i; + for (i=0; inameToString (); + if (tags[i]->isDirectory()) + for (int j=0; tags[i]->getDirectory(j); j++) { + printf ("%s+-- DIRECTORY %s[%d]:\n", prefixStr, name.c_str(), j); + tags[i]->getDirectory(j)->printAll (level+1); + } + else + std::string value = tags[i]->valueToString (); + } +} + +/** @brief Dump the TagDirectory and its sub-directories to the file 'fname' + * + * This method has been created to dump the metadata for the Custom Profile Builders. + * It contains an [RT General] section to communicate some parameters, then the TagDirectory follows. + * + * The key is composed as follow: "010F_Make", i.e. "tag number or ID _ tag name" + * Entries like: + * + * 927C_MakerNotesSony=$subdir + * + * indicates that this tag refer to a sub-directory. RT's Keywords begins with $, where & is the first char of the value. + * $subdir is the only keyword so far. + * + * You'll have then to check for the [EXIF/927C_MakerNotesSony] section, given that the root section + * is named [EXIF]. + * + * WARNING: Some string will be sanitized, i.e. the new line char will be replaced by "\n". You'll + * have to check for this escape string if you want a correct display of the value, but your KeyFile module + * will most likely handle that automatically for you. + * + * @param commFNname Absolute path of the temporary communication file's name + * @param commFNname Absolute path of the image's file name + * @param commFNname Absolute path of the output profiles's file name + * @param defaultPParams absolute or relative path (to the application's folder) of the default ProcParams to use + * @param cfs pointer to a CacheImageData object that will contain common values + * @param flagMode will tell whether the Custom Profile Builder is called for on flagging event or for real development + * @param keyfile The KeyFile object to dump to. Has to be NULL (default value) on first call! + * @param tagDirName Name of the current TagDirectory (full path, i.e. "EXIF/MakerNotes/LensInfo"). Can be empty on first call, "EXIF" will then be used + * + * @return True if everything went fine, false otherwise + */ +bool TagDirectory::CPBDump (const Glib::ustring &commFName, const Glib::ustring &imageFName, const Glib::ustring &profileFName, const Glib::ustring &defaultPParams, const CacheImageData* cfs, const bool flagMode, + rtengine::SafeKeyFile *keyFile, Glib::ustring tagDirName) const +{ + + rtengine::SafeKeyFile *kf; + if (!keyFile) + kf = new rtengine::SafeKeyFile(); + else + kf = keyFile; + + if (!kf) + return false; + + if (!keyFile || tagDirName.empty()) + tagDirName = "EXIF"; + + std::vector tagDirList; + std::vector tagDirPaths; + + FILE *f = NULL; + if (!keyFile) { + // open the file in write mode + f = safe_g_fopen (commFName, "wt"); + if (f==NULL) { + printf("TagDirectory::keyFileDump(\"%s\") >>> Error: unable to open file with write access!\n", commFName.c_str()); + delete kf; + return false; + } + + kf->set_string ("RT General", "CachePath", options.cacheBaseDir); + kf->set_string ("RT General", "AppVersion", VERSION); + kf->set_integer("RT General", "ProcParamsVersion", PPVERSION); + kf->set_string ("RT General", "ImageFileName", imageFName); + kf->set_string ("RT General", "OutputProfileFileName", profileFName); + kf->set_string ("RT General", "DefaultProcParams", defaultPParams); + kf->set_boolean("RT General", "FlaggingMode", flagMode); + + kf->set_double ("Common Data", "FNumber", cfs->fnumber); + kf->set_double ("Common Data", "Shutter", cfs->shutter); + kf->set_double ("Common Data", "FocalLength", cfs->focalLen); + kf->set_integer("Common Data", "ISO", cfs->iso); + kf->set_string ("Common Data", "Lens", cfs->lens); + kf->set_string ("Common Data", "Make", cfs->camMake); + kf->set_string ("Common Data", "Model", cfs->camModel); + } + + // recursively iterate over the tag list + for (size_t i=0; inameToString (); + if (tags[i]->isDirectory()) + for (int j=0; tags[i]->getDirectory(j); j++) { + // Accumulating the TagDirectories to dump later + tagDirPaths.push_back( Glib::ustring( tagDirName + "/" + getDumpKey(tags[i]->getID(), tagName) ) ); + tagDirList.push_back(tags[i]->getDirectory(j)); + kf->set_string (tagDirName, getDumpKey(tags[i]->getID(), tagName), "$subdir"); + } + else { + kf->set_string (tagDirName, getDumpKey(tags[i]->getID(), tagName), tags[i]->valueToString()); + } + } + + // dumping the sub-directories + for (size_t i=0; i< tagDirList.size(); i++) + tagDirList.at(i)->CPBDump(commFName, imageFName, profileFName, defaultPParams, cfs, flagMode, kf, tagDirPaths.at(i)); + + if (!keyFile) { + fprintf (f, "%s", kf->to_data().c_str()); + fclose (f); + delete kf; + } + + return true; +} + +Glib::ustring TagDirectory::getDumpKey (int tagID, const Glib::ustring tagName) { + Glib::ustring key; + if (options.CPBKeys == CPBKT_TID || options.CPBKeys == CPBKT_TID_NAME) + key = Glib::ustring(Glib::ustring::format(std::fixed, std::hex, std::setfill(L'0'), std::setw(4), tagID)); + if (options.CPBKeys == CPBKT_TID_NAME) + key += Glib::ustring("_"); + if (options.CPBKeys == CPBKT_TID_NAME || options.CPBKeys == CPBKT_NAME) + key += Glib::ustring(tagName); + return key; +} +void TagDirectory::addTag (Tag* tag) { + + // look up if it already exists: + if (getTag (tag->getID())) + delete tag; + else + tags.push_back (tag); +} + +void TagDirectory::addTagFront (Tag* tag) { + + // look up if it already exists: + if (getTag (tag->getID())) + delete tag; + else + tags.insert (tags.begin(), tag); +} + +void TagDirectory::replaceTag (Tag* tag) { + + // look up if it already exists: + for (size_t i=0; igetID()==tag->getID()) { + delete tags[i]; + tags[i] = tag; + return; + } + tags.push_back (tag); +} + +Tag* TagDirectory::getTag (int ID) const { + + for (size_t i=0; igetID()==ID) + return tags[i]; + return NULL; +} + +Tag* TagDirectory::getTag (const char* name) const { + + if (attribs) { + for (int i=0; attribs[i].ignore!=-1; i++) + if (!strcmp (attribs[i].name, name)) + return getTag (attribs[i].ID); + } + return NULL; +} + +Tag* TagDirectory::getTagP (const char* name) const { + + if (attribs) + for (int i=0; attribs[i].ignore!=-1; i++) { + // Yeah, self made comparison! + const char *n = name; + const char *a = attribs[i].name; + while (*n && *a && *n==*a) { n++; a++; }; + if (!*a && (!*n || *n=='/')) { + // we reached the end of the subpart of name and the end of attribs->name, so they match + if (*n=='/') { + Tag* tag = getTag (attribs[i].ID); + TagDirectory *tagDir; + if (attribs[i].subdirAttribs && tag && (tagDir=tag->getDirectory())) + return tagDir->getTagP(n+1); + else + return NULL; + } + else + return getTag (attribs[i].ID); + } + } + return NULL; +} + +Tag* TagDirectory::findTag (const char* name) const { + if (attribs) { + for (int i=0; attribs[i].ignore!=-1; i++) + if (!strcmp (attribs[i].name, name)){ + Tag* t= getTag (attribs[i].ID); + if(t) return t; + else break; + } + } + for (size_t i=0; iisDirectory()){ + TagDirectory *dir = tags[i]->getDirectory(); + Tag* t=dir->findTag(name); + if(t) return t; + } + return NULL; +} + +// 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 { + *value=0; + + if (!getTag("ApplicationNotes")) return false; + char *sXMP = (char*)getTag("ApplicationNotes")->getValue(); + + // Check for full word + char *pos=sXMP; + + bool found=false; + do { + pos=strstr(pos,name); + if (pos) { + char nextChar=*(pos+strlen(name)); + if (nextChar==' ' || nextChar=='>' || nextChar=='=') + found=true; + else + pos+=strlen(name); + } + } while (pos && !found); + if (!found) return false; + + char *posTag =strchr(pos,'>'); + char *posAttr=strchr(pos,'"'); + + if (!posTag && !posAttr) return false; + + if (posTag && (!posAttr || posTaggetID()==ID) tags[i]->setKeep(true); +} + +int TagDirectory::calculateSize () { + + int size = 2; // space to store the number of tags + for (size_t i=0; igetKeep()) + size += 12 + tags[i]->calculateSize (); + + size += 4; // next ifd pointer + return size; +} + +TagDirectory* TagDirectory::clone (TagDirectory* parent) { + + TagDirectory* td = new TagDirectory (parent, attribs, order); + for (size_t i=0; itags.push_back (tags[i]->clone (td)); + return td; +} + +int TagDirectory::write (int start, unsigned char* buffer) { + + int size = calculateSize (); + int tagnum = 0; + int nondirspace = 0; + for (size_t i=0; igetKeep()) { + tagnum++; + if (!tags[i]->isDirectory()) + nondirspace += tags[i]->calculateSize(); + } + int nextValOffs = start + 2 + tagnum * 12 + 4; + int nextDirOffs = nextValOffs + nondirspace; + int pos = start; + sset2 (tagnum, buffer+start, order); + pos += 2; + int maxPos = start + size; + for (size_t i=0; igetKeep()) { + if (!tags[i]->isDirectory()) + nextValOffs = tags[i]->write (pos, nextValOffs, buffer); // pos: where to put the tag, dataoffset: the place where the value can be put. return: next data offset + else + nextDirOffs = tags[i]->write (pos, nextDirOffs, buffer); // pos: where to put the tag, dataoffset: the place where the value can be put. return: next data offset + + pos += 12; + } + } + sset4 (0, buffer+pos, order); + return maxPos; +} + +void TagDirectory::applyChange (std::string name, std::string value) { + + std::string::size_type dp = name.find_first_of ('.'); + std::string fseg = name.substr (0,dp); + // this is a final segment: apply change + if (dp==std::string::npos) { + + Tag* t = NULL; + for (size_t i=0; inameToString()==fseg) { + t = tags[i]; + break; + } + + if (value=="#keep" && t) + t->setKeep (true); + else if (value=="#delete" && t) + t->setKeep (false); + else if (t && !t->isDirectory()) + t->valueFromString (value); + else { + const TagAttrib* attrib = NULL; + for (int i=0; attribs[i].ignore!=-1; i++) + if (!strcmp (attribs[i].name, fseg.c_str())) { + attrib = &attribs[i]; + break; + } + if (attrib) { + Tag* nt = new Tag (this, attrib); + nt->initString (value.c_str()); + addTag (nt); + } + } + } + // this is a subdirectory + else { + // try to find it + std::string::size_type dp1 = fseg.find_first_of ('['); + std::string basename = fseg.substr (0,dp1); + Tag* t = NULL; + int dirnum = -1; + for (size_t i=0; iisDirectory()) { + for (int j=0; tags[i]->getDirectory(j); j++) { + if (tags[i]->nameToString(j) == fseg) { + t = tags[i]; + dirnum = j; + break; + } + } + if (!t && tags[i]->nameToString() == basename) { // found it, but that directory index does not exist + t = tags[i]; + dirnum = -1; + } + } + if (!t && value!="#keep" && value!="#delete") { + const TagAttrib* attrib = NULL; + for (int i=0; attribs[i].ignore!=-1; i++) + if (!strcmp (attribs[i].name, fseg.c_str())) { + attrib = &attribs[i]; + break; + } + if (attrib && attrib->subdirAttribs) { + t = new Tag (this, attrib); + t->initSubDir (); + addTag (t); + } + dirnum = 0; + } + if (t && dirnum>=0) + t->getDirectory(dirnum)->applyChange (name.substr (dp+1, std::string::npos), value); + } +} + +TagDirectoryTable::TagDirectoryTable () +:zeroOffset(0),valuesSize(0) +{ +} + +TagDirectoryTable::TagDirectoryTable (TagDirectory* p, unsigned char *v,int memsize,int offs, TagType type, const TagAttrib* ta, ByteOrder border) +:TagDirectory(p,ta,border),zeroOffset(offs),valuesSize(memsize),defaultType( type ) +{ + values = new unsigned char[valuesSize]; + memcpy(values,v,valuesSize); + + // Security ; will avoid to read above the buffer limit if the RT's tagDirectoryTable is longer that what's in the file + int count = valuesSize/getTypeSize(type); + + for(const TagAttrib* tattr = ta; tattr->ignore != -1 && tattr->IDID*getTypeSize(type)), tattr->type == AUTO ? type : tattr->type); + tags.push_back(newTag); // Here we can insert more tag in the same offset because of bitfield meaning + } +} + +TagDirectoryTable::TagDirectoryTable (TagDirectory* p, FILE* f, int memsize,int offs, TagType type, const TagAttrib* ta, ByteOrder border) +:TagDirectory(p,ta,border),zeroOffset(offs),valuesSize(memsize),defaultType( type ) +{ + values = new unsigned char[valuesSize]; + fread (values, 1, valuesSize, f); + + // Security ; will avoid to read above the buffer limit if the RT's tagDirectoryTable is longer that what's in the file + int count = valuesSize/getTypeSize(type); + + for(const TagAttrib* tattr = ta; tattr->ignore != -1 && tattr->IDID*getTypeSize(type)), tattr->type == AUTO ? type : tattr->type); + tags.push_back(newTag); // Here we can insert more tag in the same offset because of bitfield meaning + } +} +TagDirectory* TagDirectoryTable::clone (TagDirectory* parent) { + + TagDirectory* td = new TagDirectoryTable (parent,values,valuesSize,zeroOffset,defaultType, attribs, order); + return td; +} + +TagDirectoryTable::~TagDirectoryTable() +{ + if(values) + delete [] values; +} +int TagDirectoryTable::calculateSize () +{ + return valuesSize; +} + +int TagDirectoryTable::write (int start, unsigned char* buffer) { + if( values && valuesSize){ + memcpy(buffer+start,values,valuesSize); + return start+valuesSize; + }else + return start; +} + +//--------------- class Tag --------------------------------------------------- +// this class represents a tag stored in the directory +//----------------------------------------------------------------------------- + +Tag::Tag (TagDirectory* p, FILE* f, int base) + : type(INVALID), count(0), value(NULL), allocOwnMemory(true), attrib(NULL), parent(p), directory(NULL) { + + ByteOrder order = getOrder(); + + tag = get2 (f, order); + type = (TagType)get2 (f, order); + count = get4 (f, order); + if (!count) count = 1; + + makerNoteKind = NOMK; + keep = false; + + // filter out invalid tags + // note the large count is to be able to pass LeafData ASCII tag which can be up to almost 10 megabytes, + // (only a small part of it will actually be parsed though) + if ((int)type<1 || (int)type>14 || count>10*1024*1024) { + type = INVALID; + return; + } + + // store next Tag's position in file + int save = ftell(f) + 4; + + // load value field (possibly seek before) + valuesize = count * getTypeSize(type); + + if (valuesize > 4) + fseek (f, get4(f, getOrder()) + base, SEEK_SET); + + attrib = parent->getAttrib (tag); + + if (attrib && (attrib->action==AC_WRITE || attrib->action==AC_NEW)) + keep = true; + + if( tag == 0xc634 ){ // DNGPrivateData + int currPos = ftell(f); + const int buffersize = 32; + char buffer[buffersize],*p=buffer; + while( fread (p, 1, 1, f ) && *p != 0 && p-buffergetRoot()->findTag("Make"); + std::string make( tmake ? tmake->valueToString():""); + int save = ftell(f); + int originalOffset = sget4( (unsigned char*)&buffer[10], ( make.find("SONY") != std::string::npos ) || ( make.find("Canon") != std::string::npos ) || ( make.find("OLYMPUS") != std::string::npos ) ?MOTOROLA:bom ); + + if( !parseMakerNote(f, save - originalOffset , bom )) + type = INVALID; + } + }else if( !strncmp(buffer,"PENTAX",6) ){ + makerNoteKind = HEADERIFD; + fread (buffer, 1, 2, f); + directory = new TagDirectory*[2]; + directory[0] = new TagDirectory (parent, f, currPos, pentaxAttribs, strncmp(buffer,"MM",2)? INTEL:MOTOROLA); + directory[1] = NULL; + }else + /* SONY uses this tag to write hidden info and pointer to private encrypted tags + { + unsigned offset =sget4((unsigned char*)buffer, order); + fseek(f,offset,SEEK_SET); + makerNoteKind = TABLESUBDIR; + directory = new TagDirectory*[2]; + directory[0] = new TagDirectory (parent, f, base, sonyDNGMakerNote, order); + directory[1] = NULL; + fseek (f, save, SEEK_SET); + return; + }*/ + type = INVALID; + } + // if this tag is the makernote, it needs special treatment (brand specific parsing) + if (tag==0x927C && attrib && !strcmp (attrib->name, "MakerNote") ) { + if( !parseMakerNote(f,base,order )){ + type = INVALID; + fseek (f, save, SEEK_SET); + return; + } + } + else if (attrib && attrib->subdirAttribs) { + // Some subdirs are specific of maker and model + char make[128], model[128]; + make[0]=0; + model[0]=0; + Tag* tmake = parent->getRoot()->getTag ("Make"); + if (tmake) tmake->toString (make); + Tag* tmodel = parent->getRoot()->getTag ("Model"); + if (tmodel) tmodel->toString (model); + if (!strncmp(make, "SONY", 4)) { + switch( tag ){ + case 0x0010: + directory = new TagDirectory*[2]; + directory[1] = NULL; + if (count == 15360) + directory[0] = new TagDirectoryTable (parent, f, valuesize,0,BYTE , sonyCameraInfoAttribs, order); + else + directory[0] = new TagDirectoryTable (parent, f, valuesize,0,BYTE , sonyCameraInfo2Attribs, order); + break; + case 0x0114: + directory = new TagDirectory*[2]; + directory[1] = NULL; + if (count == 280 || count == 364) + directory[0] = new TagDirectoryTable (parent, f, valuesize,0,SHORT , sonyCameraSettingsAttribs, MOTOROLA); + else if (count == 332) + directory[0] = new TagDirectoryTable (parent, f, valuesize,0,SHORT , sonyCameraSettingsAttribs2, MOTOROLA); + else if(count == 1536 || count == 2048) + directory[0] = new TagDirectoryTable (parent, f, valuesize,0,BYTE , sonyCameraSettingsAttribs3, INTEL); + else { + // Unknown CameraSettings + delete [] directory; + directory = NULL; + type = INVALID; + } + makerNoteKind = directory ? TABLESUBDIR : NOMK; + break; + case 0x9405: + directory = new TagDirectory*[2]; + directory[1] = NULL; + directory[0] = new TagDirectoryTable (parent, f, valuesize,0,SHORT , attrib->subdirAttribs, order); + makerNoteKind = TABLESUBDIR; + break; + default: + goto defsubdirs; + } + }else if ((!strncmp(make, "PENTAX", 6)) || (!strncmp(make, "RICOH", 5) && !strncmp(model, "PENTAX", 6))) { // Either the former Pentax brand or the RICOH brand + PENTAX model" + switch( tag ){ + case 0x007d: + case 0x0205: + case 0x0208: + case 0x0216: + directory = new TagDirectory*[2]; + directory[1] = NULL; + directory[0] = new TagDirectoryTable (parent, f, valuesize,0,BYTE , attrib->subdirAttribs, order); + makerNoteKind = TABLESUBDIR; + break; + case 0x0215: + directory = new TagDirectory*[2]; + directory[1] = NULL; + directory[0] = new TagDirectoryTable (parent, f, valuesize,0,LONG , attrib->subdirAttribs, order); + makerNoteKind = TABLESUBDIR; + break; + case 0x005c: + directory = new TagDirectory*[2]; + directory[1] = NULL; + if (count == 4) // SRInfo + directory[0] = new TagDirectoryTable (parent, f, valuesize,0,BYTE , pentaxSRInfoAttribs, order); + else if (count == 2) // SRInfo2 + directory[0] = new TagDirectoryTable (parent, f, valuesize,0,BYTE , pentaxSRInfo2Attribs, order); + else { + // Unknown SRInfo + delete [] directory; + directory = NULL; + type = INVALID; + } + makerNoteKind = directory ? TABLESUBDIR : NOMK; + break; + case 0x0206: + directory = new TagDirectory*[2]; + directory[1] = NULL; + if (count == 21) // AEInfo2 + directory[0] = new TagDirectoryTable (parent, f, valuesize,0,BYTE , pentaxAEInfo2Attribs, order); + else if (count == 48) // AEInfo3 + directory[0] = new TagDirectoryTable (parent, f, valuesize,0,BYTE , pentaxAEInfo3Attribs, order); + else if (count <= 25) // AEInfo + directory[0] = new TagDirectoryTable (parent, f, valuesize,0,BYTE , pentaxAEInfoAttribs, order); + else { + // Unknown AEInfo + delete [] directory; + directory = NULL; + type = INVALID; + } + makerNoteKind = directory ? TABLESUBDIR : NOMK; + break; + case 0x0207: + { // There are 2 format pentaxLensDataAttribs + int offsetFirst = 4; // LensInfo2 + if( strstr(model, "*ist") || strstr(model, "GX-1") || strstr(model, "K100D") || strstr(model, "K110D") ) + offsetFirst = 3; // LensInfo + else if( strstr(model, "645D") ) + offsetFirst = 13; // LensInfo3 + else if( strstr(model, "K-01") || strstr(model, "K-30") || strstr(model, "K-50")) + offsetFirst = 15; // LensInfo5 + else if( strstr(model, "K-5") || strstr(model, "K-r") ) + offsetFirst = 12; // LensInfo4 + else if(!strncmp(make, "RICOH", 5)) { // all PENTAX camera model produced under the RICOH era uses LensInfo5, for now... + offsetFirst = 15; // LensInfo5 too + } + directory = new TagDirectory*[2]; + directory[1] = NULL; + directory[0] = new TagDirectoryTable (parent, f, valuesize,offsetFirst,BYTE , attrib->subdirAttribs, order); + makerNoteKind = TABLESUBDIR; + } + break; + case 0x0239: + directory = new TagDirectory*[2]; + directory[1] = NULL; + directory[0] = new TagDirectoryTable (parent, f, valuesize,0,BYTE , attrib->subdirAttribs, order); + makerNoteKind = TABLESUBDIR; + break; + default: + goto defsubdirs; + } + }else if (!strncmp(make, "Canon", 5)) { + switch( tag ){ + case 0x0001: + case 0x0002: + case 0x0004: + case 0x0005: + case 0x0093: + case 0x0098: + case 0x00a0: + directory = new TagDirectory*[2]; + directory[1] = NULL; + directory[0] = new TagDirectoryTable (parent, f, valuesize,0,SSHORT , attrib->subdirAttribs, order); + makerNoteKind = TABLESUBDIR; + break; + case 0x009a: + case 0x4013: + directory = new TagDirectory*[2]; + directory[1] = NULL; + directory[0] = new TagDirectoryTable (parent, f, valuesize,0,LONG , attrib->subdirAttribs, order); + makerNoteKind = TABLESUBDIR; + break; + default: + goto defsubdirs; + } + }else if (!strncmp(make, "NIKON", 5)) { + switch (tag) { + case 0x0025: { + directory = new TagDirectory*[2]; + directory[1] = NULL; + directory[0] = new TagDirectoryTable (parent, f, valuesize,0,BYTE , attrib->subdirAttribs, order); + makerNoteKind = TABLESUBDIR; + break; + } + default: + goto defsubdirs; + } + }else if(type==UNDEFINED){ + count = 1; + type = LONG; + directory = new TagDirectory*[2]; + directory[0] = new TagDirectory (parent, f, base, attrib->subdirAttribs, order); + directory[1] = NULL; + }else + goto defsubdirs; + } + else { + // read value + value = new unsigned char [valuesize+1]; + fread (value, 1, valuesize, f); + value[valuesize] = '\0'; + } + // seek back to the saved position + fseek (f, save, SEEK_SET); + return; + +defsubdirs: + // read value + value = new unsigned char [valuesize]; + fread (value, 1, valuesize, f); + int pos = ftell (f); + // count the number of valid subdirs + int sdcount = count; + if (sdcount>0) { + if (parent->getAttribTable()==olympusAttribs) + sdcount = 1; + // allocate space + directory = new TagDirectory*[sdcount+1]; + // load directories + for (size_t j=0,i=0; jsubdirAttribs, order); + fseek (f, pos, SEEK_SET); + } + // set the terminating NULL + directory[sdcount] = NULL; + } + else + type = INVALID; + + // seek back to the saved position + fseek (f, save, SEEK_SET); + return; + +} + +bool Tag::parseMakerNote(FILE* f, int base, ByteOrder bom ) +{ + value = NULL; + Tag* tmake = parent->getRoot()->findTag("Make"); + std::string make( tmake ? tmake->valueToString():""); + + Tag* tmodel = parent->getRoot()->findTag ("Model"); + std::string model( tmodel ? tmodel->valueToString():""); + + if ( make.find( "NIKON" ) != std::string::npos ) { + if ( model.find("NIKON E700")!= std::string::npos || + model.find("NIKON E800")!= std::string::npos || + model.find("NIKON E900")!= std::string::npos || + model.find("NIKON E900S")!= std::string::npos || + model.find("NIKON E910")!= std::string::npos || + model.find("NIKON E950")!= std::string::npos ) { + makerNoteKind = HEADERIFD; + valuesize = 8; + value = new unsigned char[8]; + fread (value, 1, 8, f); + directory = new TagDirectory*[2]; + directory[0] = new TagDirectory (parent, f, base, nikon2Attribs, bom); + directory[1] = NULL; + } else if ( model.find("NIKON E990")!= std::string::npos || + (model.find("NIKON D1")!= std::string::npos && model.size()>8 && model.at(8)!='0')) { + makerNoteKind = IFD; + directory = new TagDirectory*[2]; + directory[0] = new TagDirectory (parent, f, base, nikon3Attribs, bom); + directory[1] = NULL; + } else { + // needs refinement! (embedded tiff header parsing) + makerNoteKind = NIKON3; + valuesize = 18; + value = new unsigned char[18]; + int basepos = ftell (f); + fread (value, 1, 18, f); + directory = new TagDirectory*[2]; + directory[0] = new TagDirectory (parent, f, basepos+10, nikon3Attribs, bom); + directory[1] = NULL; + } + } else if ( make.find( "Canon" ) != std::string::npos ) { + makerNoteKind = IFD; + directory = new TagDirectory*[2]; + directory[0] = new TagDirectory (parent, f, base, canonAttribs, bom); + directory[1] = NULL; + } else if ( make.find( "PENTAX" ) != std::string::npos ) { + makerNoteKind = HEADERIFD; + valuesize = 6; + value = new unsigned char[6]; + fread (value, 1, 6, f); + directory = new TagDirectory*[2]; + directory[0] = new TagDirectory (parent, f, base, pentaxAttribs, bom); + directory[1] = NULL; + } else if ( (make.find( "RICOH" ) != std::string::npos ) && (model.find("PENTAX") != std::string::npos) ) { + makerNoteKind = HEADERIFD; + valuesize = 10; + value = new unsigned char[10]; + fread (value, 1, 10, f); + directory = new TagDirectory*[2]; + directory[0] = new TagDirectory (parent, f, ftell (f)-10, pentaxAttribs, bom); + directory[1] = NULL; + } else if ( make.find( "FUJIFILM" ) != std::string::npos ) { + makerNoteKind = FUJI; + valuesize = 12; + value = new unsigned char[12]; + fread (value, 1, 12, f); + directory = new TagDirectory*[2]; + directory[0] = new TagDirectory (parent, f, ftell(f)-12, fujiAttribs, INTEL); + directory[1] = NULL; + } else if ( make.find( "KONICA MINOLTA" ) != std::string::npos || make.find( "Minolta" ) != std::string::npos ) { + makerNoteKind = IFD; + directory = new TagDirectory*[2]; + directory[0] = new TagDirectory (parent, f, base, minoltaAttribs, bom); + directory[1] = NULL; + } else if ( make.find( "SONY" ) != std::string::npos ) { + valuesize = 12; + value = new unsigned char[12]; + fread (value, 1, 12, f); + if (!strncmp((char*)value, "SONY DSC", 8)) + makerNoteKind = HEADERIFD; + else { + makerNoteKind = IFD; + fseek (f, -12, SEEK_CUR); + } + directory = new TagDirectory*[2]; + directory[0] = new TagDirectory (parent, f, base, sonyAttribs, bom ); + directory[1] = NULL; + } else if ( make.find( "OLYMPUS" ) != std::string::npos ) { + makerNoteKind = HEADERIFD; + valuesize = 8; + value = new unsigned char[12]; + fread (value, 1, 8, f); + directory = new TagDirectory*[2]; + directory[1] = NULL; + if (!strncmp((char*)value, "OLYMPUS", 7)) { + makerNoteKind = OLYMPUS2; + fread (value+8, 1, 4, f); + valuesize = 12; + directory[0] = new TagDirectory (parent, f, ftell(f)-12, olympusAttribs, value[8]=='I' ? INTEL : MOTOROLA); + } else + directory[0] = new TagDirectory (parent, f, base, olympusAttribs, bom); + } else + return false; + return true; +} + +Tag* Tag::clone (TagDirectory* parent) { + + Tag* t = new Tag (parent, attrib); + + t->tag = tag; + t->type = type; + t->count = count; + t->keep = keep; + t->valuesize = valuesize; + if (value) { + t->value = new unsigned char [valuesize]; + memcpy (t->value, value, valuesize); + } + else + value = NULL; + t->makerNoteKind = makerNoteKind; + if (directory) { + int ds = 0; + for (; directory[ds]; ds++); + t->directory = new TagDirectory*[ds+1]; + for (int i=0; idirectory[i] = directory[i]->clone (parent); + t->directory[ds] = NULL; + } + else + t->directory = NULL; + return t; +} + +Tag::~Tag () { + + // delete value + if (value && allocOwnMemory) + delete [] value; + + // if there are directories behind the tag, delete them + int i = 0; + if (directory) { + while (directory[i]) + delete directory[i++]; + delete [] directory; + } +} + +void Tag::setInt (int v, int ofs, TagType astype) { + + if (astype==SHORT) + sset2 (v, value+ofs, getOrder()); + else if (astype==RATIONAL) { + sset4 (v, value+ofs, getOrder()); + sset4 (1, value+ofs+4, getOrder()); + } + else + sset4 (v, value+ofs, getOrder()); +} + +void Tag::fromInt (int v) { + + if (type==SHORT) + sset2 (v, value, getOrder()); + else + sset4 (v, value, getOrder()); +} + +void Tag::fromString (const char* v, int size) { + + if( value && allocOwnMemory) + delete [] value; + if (size<0) + valuesize = strlen (v) + 1; + else + valuesize = size; + count = valuesize; + if( allocOwnMemory ) + value = new unsigned char [valuesize]; + memcpy ((char*)value, v, valuesize); +} + +int Tag::toInt (int ofs, TagType astype) { + if (attrib) + return attrib->interpreter->toInt(this, ofs, astype); + + int a; + if (astype == INVALID) + astype = type; + switch (astype) { + //case SBYTE: return (signed char)(value[ofs]); + case SBYTE: return int((reinterpret_cast(value))[ofs]); + case BYTE: return value[ofs]; + case ASCII: return 0; + case SSHORT:return (int)int2_to_signed(sget2 (value+ofs, getOrder())); + case SHORT: return (int)sget2 (value+ofs, getOrder()); + case SLONG: + case LONG: return (int)sget4 (value+ofs, getOrder()); + case SRATIONAL: + case RATIONAL: a = (int)sget4 (value+ofs+4, getOrder()); return a==0 ? 0 : (int)sget4 (value+ofs, getOrder()) / a; + case FLOAT: return (int)toDouble(ofs); + case UNDEFINED: return 0; + default: return 0; // Quick fix for missing cases (INVALID, DOUBLE, OLYUNDEF, SUBDIR) + } + return 0; +} + +double Tag::toDouble (int ofs) { + if (attrib) + return attrib->interpreter->toDouble(this, ofs); + + union IntFloat { uint32_t i; float f; } conv; + + double ud, dd; + switch (type) { + case SBYTE: return (double)(int((reinterpret_cast(value))[ofs])); + case BYTE: return (double)((int)value[ofs]); + case ASCII: return 0.0; + case SSHORT:return (double)int2_to_signed(sget2 (value+ofs, getOrder())); + case SHORT: return (double)((int)sget2 (value+ofs, getOrder())); + case SLONG: + case LONG: return (double)((int)sget4 (value+ofs, getOrder())); + case SRATIONAL: + case RATIONAL: ud = (int)sget4 (value+ofs, getOrder()); dd = (int)sget4 (value+ofs+4, getOrder()); return dd==0. ? 0. : (double)ud / (double)dd; + case FLOAT: + conv.i=sget4 (value+ofs, getOrder()); + return conv.f; // IEEE FLOATs are already C format, they just need a recast + + case UNDEFINED: return 0.; + default: return 0.; // Quick fix for missing cases (INVALID, DOUBLE, OLYUNDEF, SUBDIR) + } + return 0.; +} + +/** + * @brief Create an array of the elements + */ +double *Tag::toDoubleArray(int ofs) { + double *values = new double[count]; + for (unsigned int i=0; i126) + isstring = false; + if (isstring) { + int j = 0; + for (i=0; i+ofs') + buffer[j++] = '\\'; + buffer[j++] = value[i+ofs]; + } + buffer[j++] = 0; + return; + } + } + else if (type==ASCII) { + sprintf (buffer, "%.64s", value+ofs); + return; + } + + size_t maxcount = 4; + if (count<4) + maxcount = count; + + strcpy (buffer, ""); + for (size_t i=0; i0) + strcat (buffer, ", "); + char* b = buffer + strlen(buffer); + + switch (type) { + case UNDEFINED: + case BYTE: sprintf (b, "%d", value[i+ofs]); break; + case SSHORT: sprintf (b, "%d", toInt(2*i+ofs)); break; + case SHORT: sprintf (b, "%u", toInt(2*i+ofs)); break; + case SLONG: sprintf (b, "%ld", (long)toInt(4*i+ofs)); break; + case LONG: sprintf (b, "%lu", (unsigned long)toInt(4*i+ofs)); break; + case SRATIONAL: + case RATIONAL: sprintf (b, "%d/%d", (int)sget4 (value+8*i+ofs, getOrder()), (int)sget4 (value+8*i+ofs+4, getOrder())); break; + case FLOAT: sprintf (b, "%g", toDouble(8*i+ofs)); break; + default: break; + } + } + if (count > maxcount) + strcat (buffer, "..."); +} + +std::string Tag::nameToString (int i) { + + char buffer[1024]; + if (attrib) + strcpy (buffer, attrib->name); + else + sprintf (buffer, "0x%x", tag); + if (i>0) + sprintf (buffer+strlen(buffer)-1, "[%d]", i); + return buffer; +} + +std::string Tag::valueToString () { + + char buffer[1024]; + if (attrib && attrib->interpreter) + return attrib->interpreter->toString (this); + else { + toString (buffer); + return buffer; + } +} + +void Tag::valueFromString (const std::string& value) { + + if (attrib && attrib->interpreter) + attrib->interpreter->fromString (this, value); +} + +int Tag::calculateSize () { + int size = 0; + + if (directory) { + int j; + for (j=0; directory[j]; j++) + size += directory[j]->calculateSize (); + if (j>1) + size += 4*j; + } + else if (valuesize > 4) + size += valuesize + (valuesize%2); // we align tags to even byte positions + + if (makerNoteKind!=NOMK) + count = directory[0]->calculateSize () / getTypeSize(type); + + if (makerNoteKind==NIKON3 || makerNoteKind==OLYMPUS2 || makerNoteKind==FUJI) + size += valuesize; + else if (makerNoteKind==HEADERIFD) + size += valuesize; + return size; +} + +int Tag::write (int offs, int dataOffs, unsigned char* buffer) { + + if ((int)type==0 || offs>65500) + return dataOffs; + + sset2 (tag, buffer+offs, parent->getOrder()); + offs += 2; + unsigned short typ = type; + sset2 (typ, buffer+offs, parent->getOrder()); + offs += 2; + sset4 (count, buffer+offs, parent->getOrder()); + offs += 4; + if (!directory) { + if (valuesize>4) { + sset4 (dataOffs, buffer+offs, parent->getOrder()); + memcpy (buffer+dataOffs, value, valuesize); + if (valuesize%2) + buffer[dataOffs+valuesize] = 0; // zero padding required by the exif standard + return dataOffs + valuesize + (valuesize%2); + } + else { + memcpy (buffer+offs, value, valuesize); + return dataOffs; + } + } + else { + if (makerNoteKind==NIKON3) { + sset4 (dataOffs, buffer+offs, parent->getOrder()); + memcpy (buffer+dataOffs, value, 18); + dataOffs += 10; + dataOffs += directory[0]->write (8, buffer+dataOffs); + return dataOffs; + } + else if (makerNoteKind==OLYMPUS2 || makerNoteKind==FUJI) { + sset4 (dataOffs, buffer+offs, parent->getOrder()); + memcpy (buffer+dataOffs, value, valuesize); + dataOffs += valuesize + directory[0]->write (valuesize, buffer+dataOffs); + return dataOffs; + } + else if (makerNoteKind==HEADERIFD) { + sset4 (dataOffs, buffer+offs, parent->getOrder()); + memcpy (buffer+dataOffs, value, valuesize); + dataOffs += valuesize; + dataOffs += directory[0]->write (dataOffs, buffer); + return dataOffs; + } + else if( makerNoteKind==TABLESUBDIR){ + sset4 (dataOffs, buffer+offs, parent->getOrder()); + dataOffs = directory[0]->write (dataOffs, buffer); + return dataOffs; + } + else if (!directory[1]) { + sset4 (dataOffs, buffer+offs, parent->getOrder()); + return directory[0]->write (dataOffs, buffer); + } + else { + sset4 (dataOffs, buffer+offs, parent->getOrder()); + int linkOffs = dataOffs; + for (int i=0; directory[i]; i++) + dataOffs += 4; + for (int i=0; directory[i]; i++) { + sset4 (dataOffs, buffer+linkOffs, parent->getOrder()); + linkOffs += 4; + dataOffs = directory[i]->write (dataOffs, buffer); + } + return dataOffs; + } + } +} + +Tag::Tag (TagDirectory* p, const TagAttrib* attr) + : tag(attr ? attr->ID : -1), type(INVALID), count(0), value(NULL), valuesize(0), keep(true), allocOwnMemory(true), attrib(attr), parent(p), directory(NULL), makerNoteKind (NOMK) { +} + +Tag::Tag (TagDirectory* p, const TagAttrib* attr, int data, TagType t) + : tag(attr ? attr->ID : -1), type(t), count(1), value(NULL), valuesize(0), keep(true), allocOwnMemory(true), attrib(attr), parent(p), directory(NULL), makerNoteKind (NOMK) { + + initInt (data, t); +} + +Tag::Tag (TagDirectory* p, const TagAttrib* attr, unsigned char *data, TagType t) + : tag(attr ? attr->ID : -1), type(t), count(1), value(NULL), valuesize(0), keep(true), allocOwnMemory(false), attrib(attr), parent(p), directory(NULL), makerNoteKind (NOMK) { + + initType (data, t); +} + +Tag::Tag (TagDirectory* p, const TagAttrib* attr, const char* text) + : tag(attr ? attr->ID : -1), type(ASCII), count(1), value(NULL), valuesize(0), keep(true), allocOwnMemory(true), attrib(attr), parent(p), directory(NULL), makerNoteKind (NOMK) { + + initString (text); +} + +void Tag::initType (unsigned char *data, TagType type) +{ + valuesize = getTypeSize(type); + if( allocOwnMemory ){ + value = new unsigned char[valuesize]; + memcpy ((char*)value, data, valuesize); + }else + value = data; +} + +void Tag::initInt (int data, TagType t, int cnt) { + + type = t; + if (t==LONG) + valuesize = 4; + else if (t==SHORT) + valuesize = 2; + else if (t==BYTE) + valuesize = 1; + else if (t==RATIONAL) + valuesize = 8; + + count = cnt; + valuesize *= count; + value = new unsigned char[valuesize]; + setInt (data, 0, t); +} + +void Tag::initString (const char* text) { + + type = ASCII; + count = strlen(text)+1; + valuesize = count; + value = new unsigned char[valuesize]; + strcpy ((char*)value, text); +} + +void Tag::initSubDir () { + type = LONG; + valuesize = 4; + count = 1; + value = new unsigned char[4]; + setInt (0); + directory = new TagDirectory*[2]; + directory[0] = new TagDirectory (parent, attrib ? attrib->subdirAttribs : NULL, parent->getOrder()); + directory[1] = NULL; +} + +void Tag::initSubDir (TagDirectory* dir) { + type = LONG; + valuesize = 4; + count = 1; + value = new unsigned char[4]; + setInt (0); + directory = new TagDirectory*[2]; + directory[0] = dir; + directory[1] = NULL; +} + +void Tag::initMakerNote (MNKind mnk, const TagAttrib* ta) { + type = UNDEFINED; + valuesize = 4; + count = 1; + value = new unsigned char[4]; + setInt (0); + directory = new TagDirectory*[2]; + directory[0] = new TagDirectory (parent, ta, parent->getOrder()); + directory[1] = NULL; + makerNoteKind = mnk; +} + +void Tag::initUndefArray (const char* data, int len) { + type = UNDEFINED; + count = valuesize = len; + value = new unsigned char[valuesize]; + memcpy (value, data, len); +} + +void Tag::initLongArray (const char* data, int len) { + type = LONG; + count = (len+3)/4; + valuesize = count * 4; + value = new unsigned char[valuesize]; + memcpy (value, data, len); +} + +void Tag::initRational (int num, int den) { + count = 1; + valuesize = 8; + value = new unsigned char[8]; + type = RATIONAL; + setInt (num, 0); + setInt (den, 4); +} + +//--------------- class IFDParser --------------------------------------------- +// static functions to read tag directories from different kinds of files +//----------------------------------------------------------------------------- + + +const TagAttrib* lookupAttrib (const TagAttrib* dir, const char* field) { + + for (int i=0; dir[i].ignore!=-1; i++) + if (!strcmp (dir[i].name, field)) + return &dir[i]; + return 0; +} + + +TagDirectory* ExifManager::parseCIFF (FILE* f, int base, int length) { + + TagDirectory* root = new TagDirectory (NULL, ifdAttribs, INTEL); + Tag* exif = new Tag (root, lookupAttrib(ifdAttribs,"Exif")); + exif->initSubDir (); + Tag* mn = new Tag (exif->getDirectory(), lookupAttrib(exifAttribs,"MakerNote")); + mn->initMakerNote (IFD, canonAttribs); + root->addTag (exif); + exif->getDirectory()->addTag (mn); + parseCIFF (f, base, length, root); + root->sort (); + return root; +} + +Tag* ExifManager::saveCIFFMNTag (FILE* f, TagDirectory* root, int len, const char* name) { + int s = ftell (f); + char* data = new char [len]; + fread (data, len, 1, f); + TagDirectory* mn = root->getTag ("Exif")->getDirectory()->getTag("MakerNote")->getDirectory(); + Tag* cs = new Tag (mn, lookupAttrib(canonAttribs, name)); + cs->initUndefArray (data, len); + mn->addTag (cs); + fseek (f, s, SEEK_SET); + return cs; +} + +void ExifManager::parseCIFF (FILE* f, int base, int length, TagDirectory* root) { + + char buffer[1024]; + Tag* t; + + fseek (f, base+length-4, SEEK_SET); + + int dirStart = get4 (f, INTEL) + base; + fseek (f, dirStart, SEEK_SET); + + int numOfTags = get2 (f, INTEL); + + if (numOfTags > 100) return; + + float exptime, shutter, aperture, fnumber, ev; + exptime = fnumber = shutter = aperture = ev = -1000.f; + int focal_len, iso; + focal_len = iso = -1; + + TagDirectory* exif = root->getTag("Exif")->getDirectory(); + + time_t timestamp = time (NULL); + + for (int i=0; i> 8) + 8) | 8) == 0x38) + parseCIFF (f, ftell(f), len, root); // Parse a sub-table + + if (type == 0x0810) { + fread (buffer, 64, 1, f); + t = new Tag (root, lookupAttrib(ifdAttribs,"Artist")); + t->initString (buffer); + root->addTag (t); + } + if (type == 0x080a) { + fread (buffer, 64, 1, f); + t = new Tag (root, lookupAttrib(ifdAttribs,"Make")); + t->initString (buffer); + root->addTag (t); + fseek (f, strlen(buffer) - 63, SEEK_CUR); + fread (buffer, 64, 1, f); + t = new Tag (root, lookupAttrib(ifdAttribs,"Model")); + t->initString (buffer); + root->addTag (t); + } + if (type == 0x1818) { + ev = int_to_float(get4(f, INTEL)); + shutter = int_to_float(get4(f, INTEL)); + exptime = pow (2, -shutter); + aperture = int_to_float(get4(f, INTEL)); + fnumber = pow (2, aperture/2); + + } + if (type == 0x102d) { + Tag* t = saveCIFFMNTag (f, root, len, "CanonCameraSettings"); + int mm = t->toInt (34, SHORT); + Tag* nt = new Tag (exif, lookupAttrib(exifAttribs,"MeteringMode")); + switch (mm) { + case 0: nt->initInt (5, SHORT); break; + case 1: nt->initInt (3, SHORT); break; + case 2: nt->initInt (1, SHORT); break; + case 3: nt->initInt (5, SHORT); break; + case 4: nt->initInt (6, SHORT); break; + case 5: nt->initInt (2, SHORT); break; + } + exif->addTag (nt); + nt = new Tag (exif, lookupAttrib(exifAttribs,"MaxApertureValue")); + nt->initRational (t->toInt(52,SHORT), 32); + exif->addTag (nt); + int em = t->toInt(40,SHORT); + nt = new Tag (exif, lookupAttrib(exifAttribs,"ExposureProgram")); + switch (em) { + case 0: nt->initInt (2, SHORT); break; + case 1: nt->initInt (2, SHORT); break; + case 2: nt->initInt (4, SHORT); break; + case 3: nt->initInt (3, SHORT); break; + case 4: nt->initInt (1, SHORT); break; + default: nt->initInt (0, SHORT); break; + } + exif->addTag (nt); + nt = new Tag (exif, lookupAttrib(exifAttribs,"Flash")); + if (t->toInt(8,SHORT)==0) + nt->initInt (0, SHORT); + else + nt->initInt (1, SHORT); + exif->addTag (nt); + nt = new Tag (exif, lookupAttrib(exifAttribs,"MaxApertureValue")); + nt->initRational (t->toInt(52,SHORT), 32); + exif->addTag (nt); + } + if (type == 0x1029) + saveCIFFMNTag (f, root, len, "CanonFocalLength"); + if (type == 0x1031) + saveCIFFMNTag (f, root, len, "SensorInfo"); + if (type == 0x1033) + saveCIFFMNTag (f, root, len, "CustomFunctions"); + if (type == 0x1038) + saveCIFFMNTag (f, root, len, "CanonAFInfo"); + if (type == 0x1093) + saveCIFFMNTag (f, root, len, "CanonFileInfo"); + if (type == 0x10a9) + saveCIFFMNTag (f, root, len, "ColorBalance"); + if (type == 0x102a) { + saveCIFFMNTag (f, 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; + fnumber = pow (2, aperture/2); + shutter = ((short)get2(f, INTEL))/32.0f; + ev = ((short)get2(f, INTEL))/32.0f; + fseek (f, 34, SEEK_CUR); + if (shutter > 1e6) shutter = get2 (f, INTEL) / 10.0f; + exptime = pow (2,-shutter); + } + if (type == 0x5029) { + focal_len = len >> 16; + if ((len & 0xffff) == 2) focal_len /= 32; + } +// if (type == 0x5813) flash_used = int_to_float(len); + if (type == 0x580e) timestamp = len; + if (type == 0x180e) timestamp = get4 (f, INTEL); + if ((type | 0x4000) == 0x580e) + timestamp = mktime (gmtime (×tamp)); + fseek (f, nextPos, SEEK_SET); + } + if (shutter>-999) { + t = new Tag (exif, lookupAttrib(exifAttribs,"ShutterSpeedValue")); + t->initRational ((int)(shutter*10000), 10000); + exif->addTag (t); + } + if (exptime>-999) { + t = new Tag (exif, lookupAttrib(exifAttribs,"ExposureTime")); + t->initRational ((int)(exptime*10000), 10000); + exif->addTag (t); + } + if (aperture>-999) { + t = new Tag (exif, lookupAttrib(exifAttribs,"ApertureValue")); + t->initRational ((int)(aperture*10), 10); + exif->addTag (t); + } + if (fnumber>-999) { + t = new Tag (exif, lookupAttrib(exifAttribs,"FNumber")); + t->initRational ((int)(fnumber*10), 10); + exif->addTag (t); + } + if (ev>-999) { + t = new Tag (exif, lookupAttrib(exifAttribs,"ExposureBiasValue")); + t->initRational ((int)(ev*1000), 1000); + exif->addTag (t); + } + if (iso>0) { + t = new Tag (exif, lookupAttrib(exifAttribs,"ISOSpeedRatings")); + t->initInt (iso, LONG); + exif->addTag (t); + } + if (focal_len>0) { + t = new Tag (exif, lookupAttrib(exifAttribs,"FocalLength")); + t->initRational (focal_len*32, 32); + exif->addTag (t); + } + + if (timestamp!=time(NULL)) { + struct tm* tim = localtime (×tamp); + strftime (buffer, 20, "%Y:%m:%d %H:%M:%S", tim); + t = new Tag (exif, lookupAttrib(exifAttribs,"DateTimeOriginal")); + t->initString (buffer); + exif->addTag (t); + t = new Tag (exif, lookupAttrib(exifAttribs,"DateTimeDigitized")); + t->initString (buffer); + exif->addTag (t); + t = new Tag (root, lookupAttrib(ifdAttribs,"DateTime")); + t->initString (buffer); + root->addTag (t); + } +} + +static void +parse_leafdata(TagDirectory* root, ByteOrder order) { + + Tag *leafdata = root->getTag("LeafData"); + if (!leafdata) { + return; + } + unsigned char *value = leafdata->getValue(); + int valuesize = leafdata->getValueSize(); + + // parse LeafData tag, a tag specific to Leaf digital backs, and has a custom + // format with 52 byte tag headers starting with "PKTS" + const char *PKTS_tag = (order == MOTOROLA) ? "PKTS" : "STKP"; + char *hdr; + int pos = 0; + + // There are lots of sub-tags in here, but for now we only care about those directly + // useful to RT, which is ISO and rotation. Shutter speed and aperture is not + // available here. + int iso_speed = 0; + int rotation_angle = 0; + int found_count = 0; + while (pos + (int)sizeof(hdr) <= valuesize && found_count < 2) { + hdr = (char *)&value[pos]; + if (strncmp(hdr, PKTS_tag, 4) != 0) { + // in a few cases the header can be offset a few bytes, don't know why + // it does not seem to be some sort of alignment, it appears random, + // this check takes care of it, restart if we find an offset match. + int offset = 1; + for (; offset <= 3; offset++) { + if (strncmp(&hdr[offset], PKTS_tag, 4) == 0) { + pos += offset; + break; + } + } + if (offset <= 3) { + continue; + } + break; + } + int size = sget4((unsigned char *)&hdr[48], order); + if (pos + size > valuesize) { + break; + } + pos += 52; + char *val = (char *)&value[pos]; + if (strncmp(&hdr[8], "CameraObj_ISO_speed", 19) == 0) { + iso_speed = 25 * (1 << (atoi(val) - 1)); + found_count++; + } else if (strncmp(&hdr[8], "ImgProf_rotation_angle", 22) == 0) { + rotation_angle = atoi(val); + found_count++; + } else { + // check if this is a sub-directory, include test for that strange offset of next header + if (size >= 8 && + (strncmp(val, PKTS_tag, 4) == 0 || + strncmp(&val[1], PKTS_tag, 4) == 0 || + strncmp(&val[2], PKTS_tag, 4) == 0 || + strncmp(&val[3], PKTS_tag, 4) == 0)) + { + // start of next hdr, this is a sub-directory, we skip those for now. + size = 0; + } + } + pos += size; + } + + // create standard tags from the custom Leaf tags + Tag* exif = root->getTag ("Exif"); + if (!exif) { + exif = new Tag (root, root->getAttrib ("Exif")); + exif->initSubDir(); + root->addTagFront (exif); + } + if (!exif->getDirectory()->getTag("ISOSpeedRatings")) { + Tag *t = new Tag (exif->getDirectory(), exif->getDirectory()->getAttrib ("ISOSpeedRatings")); + t->initInt (iso_speed, LONG); + exif->getDirectory()->addTagFront (t); + } + if (!root->getTag("Orientation")) { + int orientation; + switch (rotation_angle) { + case 0: orientation = 1; break; + case 90: orientation = 6; break; + case 180: orientation = 3; break; + case 270: orientation = 8; break; + default: orientation = 1; break; + } + Tag *t = new Tag (root, root->getAttrib ("Orientation")); + t->initInt (orientation, SHORT); + root->addTagFront (t); + } + + // now look in ApplicationNotes tag for additional information + Tag *appnotes = root->getTag("ApplicationNotes"); + if (!appnotes) { + return; + } + char *xmp = (char *)appnotes->getValue(); + char *end, *p; + // Quick-and-dirty value extractor, no real xml parsing. + // We could make it more generic, but we just get most important + // values we know use to be in there. + if ((p = strstr(xmp, "xmlns:tiff")) != NULL && + (end = strstr(p, "")) != NULL) + { + *end = '\0'; + while ((p = strstr(p, "')) == NULL) { + break; + } + *tagend = '\0'; + char *val = &tagend[1]; + if ((p = strstr(val, "getAttrib (tag) && !root->getTag (tag)) { + Tag *t = new Tag (root, root->getAttrib (tag)); + if (strcmp(tag, "Make") == 0 || + strcmp(tag, "Model") == 0) + { + if (strcmp(tag, "Model") == 0) { + // Leaf adds back serial number and camera model to the 'Model' + // tag, we strip that away here so the back can be recognized + // and matched against DCP profile + char *p1 = strchr(val, '('); + if (p1 != NULL) { + *p1 = '\0'; + } + // Model name also contains a leading "Leaf " which we already + // have in the Make name, remove that. + if (strstr(val, "Leaf ") == val) { + t->initString (&val[5]); + } else { + t->initString (val); + } + if (p1 != NULL) { + *p1 = '('; + } + } else { + t->initString (val); + } + root->addTagFront (t); + } else { + delete t; + } + } + *p = '<'; + *tagend = '>'; + } + *end = '<'; + } + if ((p = strstr(xmp, "xmlns:exif")) != NULL && + (end = strstr(p, "")) != NULL) + { + *end = '\0'; + while ((p = strstr(p, "')) == NULL) { + break; + } + *tagend = '\0'; + char *val = &tagend[1]; + if ((p = strstr(val, "getDirectory()->getAttrib (tag) && !exif->getDirectory()->getTag (tag)) { + Tag *t = new Tag (exif->getDirectory(), exif->getDirectory()->getAttrib (tag)); + int num, denom; + struct tm tm; + if (strcmp(tag, "ApertureValue") == 0 && sscanf(val, "%d/%d", &num, &denom) == 2) { + t->initRational (num, denom); + exif->getDirectory()->addTagFront (t); + // we also make an "FNumber" tag since many tools don't interpret ApertureValue + // according to Exif standard + t = new Tag (exif->getDirectory(), lookupAttrib(exifAttribs,"FNumber")); + double f = pow(sqrt(2.0), ((double)num / denom)); + if (f > 10.0) { + t->initRational ((int)floor(f), 1); + } else { + t->initRational ((int)floor(f * 10.0), 10); + } + exif->getDirectory()->addTagFront (t); + } else if (strcmp(tag, "ShutterSpeedValue") == 0 && sscanf(val, "%d/%d", &num, &denom) == 2) { + t->initRational (num, denom); + exif->getDirectory()->addTagFront (t); + // we also make an "ExposureTime" tag since many tools don't interpret ShutterSpeedValue + // according to Exif standard + t = new Tag (exif->getDirectory(), lookupAttrib(exifAttribs,"ExposureTime")); + double f = 1.0 / pow(2.0, ((double)num / denom)); + if (f > 10.0) { + t->initRational ((int)floor(f), 1); + } else if (f > 1.0) { + t->initRational ((int)floor(f * 10.0), 10); + } else if (f == 1.0) { + t->initRational (1, 1); + } else { + f = 1.0 / f; + static const double etimes[] = { + 10000, 8000, 6400, 6000, 5000, + 4000, 3200, 3000, 2500, + 2000, 1600, 1500, 1250, + 1000, 800, 750, 640, + 500, 400, 350, 320, + 250, 200, 180, 160, + 125, 100, 90, 80, + 60, 50, 45, 40, + 30, 25, 22, 20, + 15, 13, 11, 10, + 8, 6, 5, + 4, 3, 2.5, + 2, 1.6, 1.5, 1.3, + 1, -1 }; + double diff = etimes[0]; + int idx = -1; + for (int i = 1; etimes[i] > 0; i++) { + if (abs(etimes[i] - f) < diff) { + idx = i; + diff = abs(etimes[i] - f); + } + } + if (idx != -1 && f < etimes[0]) { + f = etimes[idx]; + } + if (f < 2) { + t->initRational (10, (int)(10 * f)); + } else { + t->initRational (1, (int)f); + } + } + exif->getDirectory()->addTagFront (t); + } else if (strcmp(tag, "FocalLength") == 0 && sscanf(val, "%d/%d", &num, &denom) == 2) { + t->initRational (num, denom); + exif->getDirectory()->addTagFront (t); + } else if (strcmp(tag, "ISOSpeedRatings") == 0) { + char *p1 = val; + while (*p1 != '\0' && !isdigit(*p1)) p1++; + if (*p1 != '\0') { + t->initInt (atoi(p1), LONG); + exif->getDirectory()->addTagFront (t); + } + } else if (strcmp(tag, "DateTimeOriginal") == 0 && + sscanf(val, "%d-%d-%dT%d:%d:%dZ", + &tm.tm_year, &tm.tm_mon, + &tm.tm_mday, &tm.tm_hour, + &tm.tm_min, &tm.tm_sec) == 6) + { + char tstr[64]; + sprintf(tstr, "%04d:%02d:%02d %02d:%02d:%02d", tm.tm_year, tm.tm_mon, + tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); + t->initString (tstr); + exif->getDirectory()->addTagFront (t); + } else { + delete t; + } + } + *p = '<'; + *tagend = '>'; + } + *end = '<'; + } +} + +TagDirectory* ExifManager::parse (FILE* f, int base, bool skipIgnored) { + 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); + + // first read the IFD directory + TagDirectory* root = new TagDirectory (NULL, f, base, ifdAttribs, order, skipIgnored); + + // fix ISO issue with nikon and panasonic cameras + Tag* make = root->getTag ("Make"); + Tag* exif = root->getTag ("Exif"); + 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 (); + 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 (NULL, f, base, exifAttribs, order, true); + + 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); + } + } + Tag *kodakIFD = root->getTag("KodakIFD"); + if (kodakIFD && kodakIFD->getDirectory()->getTag("TextualInfo")) { + parseKodakIfdTextualInfo(kodakIFD->getDirectory()->getTag("TextualInfo"), exif); + } + } + + parse_leafdata(root, order); + + 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. + + 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. + + This code is supposed to handle all raw containers and end up with the same model + regardless of container. + + 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") : 0; + int sensorWidth = (iw) ? iw->toInt() : 0; + Tag* tmodel = root->getTag ("Model"); + const char *model = (tmodel) ? (const char *)tmodel->getValue() : ""; + 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() : ""; + 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 = (tmodel4) ? (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); + } + } + +// root->printAll (); + + return root; +} + +TagDirectory* ExifManager::parseJPEG (FILE* f) { + + fseek (f, 0, SEEK_SET); + unsigned char markerl = 0xff; + unsigned char c; + fread (&c, 1, 1, f); + const char exifid[] = "Exif\0\0"; + char idbuff[8]; + int tiffbase = -1; + while (fread (&c, 1, 1, f)) { + if (c!=markerl) continue; + if (fread (&c, 1, 1, f) && c==0xe1) { // APP1 marker found + if (fread (idbuff, 1, 8, f)<8) + return NULL; + if (!memcmp(idbuff+2, exifid, 6)) { // Exif info found + tiffbase = ftell (f); + return parse (f, tiffbase); + } + } + } + return NULL; +} + +TagDirectory* ExifManager::parseTIFF (FILE* f, bool skipIgnored) { + + return parse (f, 0, skipIgnored); +} + +std::vector ExifManager::defTags; + +// forthis: the byte order will be taken from directory "forthis" +const std::vector& ExifManager::getDefaultTIFFTags (TagDirectory* forthis) { + + for (size_t i=0; igetOrder (); + sset2 ((unsigned short)order, buffer+offs, order); offs += 2; + sset2 (42, buffer+offs, order); offs += 2; + sset4 (8, buffer+offs, order); offs += 4; + + TagDirectory* cl; + if (root) + cl = (const_cast(root))->clone (NULL); + else + cl = new TagDirectory (NULL, ifdAttribs, INTEL); + + for (rtengine::procparams::ExifPairs::const_iterator i=changeList.begin(); i!=changeList.end(); i++) + cl->applyChange (i->first, i->second); + + getDefaultTIFFTags (cl); + + defTags[0]->setInt (W, 0, LONG); + defTags[1]->setInt (H, 0, LONG); + defTags[8]->setInt (8, 0, SHORT); + + for (int i=defTags.size()-1; i>=0; i--) + cl->replaceTag (defTags[i]->clone (cl)); + cl->sort (); + int size = cl->write (8, buffer+6); + + delete cl; + + return size + 6; +} + +int ExifManager::createTIFFHeader (const TagDirectory* root, const rtengine::procparams::ExifPairs& changeList, int W, int H, int bps, const char* profiledata, int profilelen, const char* iptcdata, int iptclen, unsigned char* buffer) { + +// write tiff header + int offs = 0; + ByteOrder order = HOSTORDER; + if (root) + order = root->getOrder (); + sset2 ((unsigned short)order, buffer+offs, order); offs += 2; + sset2 (42, buffer+offs, order); offs += 2; + sset4 (8, buffer+offs, order); offs += 4; + + TagDirectory* cl; + if (root) + cl = (const_cast(root))->clone (NULL); + else + cl = new TagDirectory (NULL, ifdAttribs, HOSTORDER); + +// add tiff strip data + int rps = 8; + int strips = ceil((double)H/rps); + cl->replaceTag (new Tag (cl, lookupAttrib(ifdAttribs,"RowsPerStrip"), rps, LONG)); + Tag* stripBC = new Tag (cl, lookupAttrib(ifdAttribs,"StripByteCounts")); + stripBC->initInt (0, LONG, strips); + cl->replaceTag (stripBC); + Tag* stripOffs = new Tag (cl, lookupAttrib(ifdAttribs,"StripOffsets")); + stripOffs->initInt (0, LONG, strips); + cl->replaceTag (stripOffs); + for (int i=0; isetInt (rps*W*3*bps/8, i*4); + int remaining = (H-rps*floor((double)H/rps))*W*3*bps/8; + if (remaining) + stripBC->setInt (remaining, (strips-1)*4); + else + stripBC->setInt (rps*W*3*bps/8, (strips-1)*4); + if (profiledata) { + Tag* icc = new Tag (cl, lookupAttrib(ifdAttribs,"ICCProfile")); + icc->initUndefArray (profiledata, profilelen); + cl->replaceTag (icc); + } + if (iptcdata) { + Tag* iptc = new Tag (cl, lookupAttrib(ifdAttribs,"IPTCData")); + iptc->initLongArray (iptcdata, iptclen); + cl->replaceTag (iptc); + } + +// apply list of changes + for (rtengine::procparams::ExifPairs::const_iterator i=changeList.begin(); i!=changeList.end(); i++) + cl->applyChange (i->first, i->second); + + // append default properties + getDefaultTIFFTags (cl); + + defTags[0]->setInt (W, 0, LONG); + defTags[1]->setInt (H, 0, LONG); + defTags[8]->initInt(0, SHORT, 3); + for (int i=0;i<3;i++) defTags[8]->setInt(bps, i*2, SHORT); + + for (int i=defTags.size()-1; i>=0; i--) + cl->replaceTag (defTags[i]->clone (cl)); + +// calculate strip offsets + int size = cl->calculateSize (); + int byps = bps / 8; + for (int i=0; isetInt (size + 8 + i*rps*W*3*byps, i*4); + + cl->sort (); + int endOffs = cl->write (8, buffer); + +// cl->printAll(); + delete cl; + + return endOffs; +} + +//----------------------------------------------------------------------------- +// global functions to read byteorder dependent data +//----------------------------------------------------------------------------- +unsigned short sget2 (unsigned char *s, rtexif::ByteOrder order) { + + if (order == rtexif::INTEL) return s[0] | s[1] << 8; + else return s[0] << 8 | s[1]; +} + +int sget4 (unsigned char *s, rtexif::ByteOrder order) { + + if (order == rtexif::INTEL) return s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24; + else return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]; +} + +inline unsigned short get2 (FILE* f, rtexif::ByteOrder order) { + + unsigned char str[2] = { 0xff,0xff }; + fread (str, 1, 2, f); + return rtexif::sget2 (str, order); +} + +int get4 (FILE* f, rtexif::ByteOrder order) { + + unsigned char str[4] = { 0xff,0xff,0xff,0xff }; + fread (str, 1, 4, f); + return rtexif::sget4 (str, order); +} + +void sset2 (unsigned short v, unsigned char *s, rtexif::ByteOrder order) { + + if (order == rtexif::INTEL) { + s[0] = v & 0xff; v >>= 8; + s[1] = v; + } + else { + s[1] = v & 0xff; v >>= 8; + s[0] = v; + } +} + +void sset4 (int v, unsigned char *s, rtexif::ByteOrder order) { + + if (order == rtexif::INTEL) { + s[0] = v & 0xff; v >>= 8; + s[1] = v & 0xff; v >>= 8; + s[2] = v & 0xff; v >>= 8; + s[3] = v; + } + else { + s[3] = v & 0xff; v >>= 8; + s[2] = v & 0xff; v >>= 8; + s[1] = v & 0xff; v >>= 8; + s[0] = v; + } +} + +float int_to_float (int i) { + union { int i; float f; } u; + u.i = i; + return u.f; +} + +short int int2_to_signed (short unsigned int i) { + union { short unsigned int i; short int s; } u; + u.i = i; + return u.s; +} + +/* Function to parse and extract focal length and aperture information from description + * @fullname must conform to the following formats + * mm f/ + * -mm f/ + * -mm f/- + * NB: no space between separator '-'; no space between focal length and 'mm' + */ +bool extractLensInfo(std::string &fullname,double &minFocal, double &maxFocal, double &maxApertureAtMinFocal, double &maxApertureAtMaxFocal) +{ + minFocal=0.0; + maxFocal=0.0; + maxApertureAtMinFocal=0.0; + maxApertureAtMaxFocal=0.0; + char buffer[1024]; + strcpy(buffer,fullname.c_str()); + char *pF = strstr(buffer,"f/" ); + if( pF ){ + sscanf(pF+2,"%lf-%lf",&maxApertureAtMinFocal,&maxApertureAtMaxFocal); + if(maxApertureAtMinFocal >0. && maxApertureAtMaxFocal==0.) + maxApertureAtMaxFocal= maxApertureAtMinFocal; + + char *pMM = pF-3; + while( pMM[0]!= 'm' && pMM[1]!= 'm' && pMM>buffer) pMM--; + if( pMM[0]== 'm' && pMM[1]== 'm' ){ + char *sp=pMM; + while( *sp != ' ' && sp > buffer )sp--; + sscanf(sp+1,"%lf-%lf",&minFocal,&maxFocal); + if(maxFocal==0.) { + maxFocal = minFocal; + } + return true; + } + } + return false; +} + +} diff --git a/rtexif/rtexif.h b/rtexif/rtexif.h new file mode 100644 index 000000000..f5f238640 --- /dev/null +++ b/rtexif/rtexif.h @@ -0,0 +1,478 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _MEXIF3_ +#define _MEXIF3_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../rtengine/procparams.h" +#include "../rtengine/safekeyfile.h" + +class CacheImageData; + +namespace rtexif { + +enum TagType {INVALID=0, BYTE=1, ASCII=2, SHORT=3, LONG=4, RATIONAL=5, SBYTE=6, UNDEFINED=7, SSHORT=8, SLONG=9, SRATIONAL=10, FLOAT=11, DOUBLE=12, OLYUNDEF=13, AUTO=98, SUBDIR=99}; +enum ActionCode { + AC_DONTWRITE, // don't write it to the output + AC_WRITE, // write it to the output + AC_SYSTEM, // changed by RT (not editable/deletable) - don't write, don't show + AC_NEW, // new addition - write, don't show + + AC_INVALID=100, // invalid state +}; +enum ByteOrder {INTEL=0x4949, MOTOROLA=0x4D4D}; +#if __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__ +const enum ByteOrder HOSTORDER = INTEL; +#else +const enum ByteOrder HOSTORDER = MOTOROLA; +#endif +enum MNKind {NOMK, IFD, HEADERIFD, NIKON3, OLYMPUS2, FUJI,TABLESUBDIR}; + +bool extractLensInfo(std::string &fullname,double &minFocal, double &maxFocal, double &maxApertureAtMinFocal, double &maxApertureAtMaxFocal); + +unsigned short sget2 (unsigned char *s, ByteOrder order); +int sget4 (unsigned char *s, ByteOrder order); +inline unsigned short get2 (FILE* f, ByteOrder order); +inline int get4 (FILE* f, ByteOrder order); +inline void sset2 (unsigned short v, unsigned char *s, ByteOrder order); +inline void sset4 (int v, unsigned char *s, ByteOrder order); +inline float int_to_float (int i); +short int int2_to_signed (short unsigned int i); + +struct TIFFHeader { + + unsigned short byteOrder; + unsigned short fixed; + unsigned int ifdOffset; +}; + +class Tag; +class Interpreter; + +/// Structure of informations describing an Exif tag +struct TagAttrib { + int ignore; // =0: never ignore, =1: always ignore, =2: ignore if the subdir type is reduced image, =-1: end of table + ActionCode action; + int editable; + const TagAttrib* subdirAttribs; // !NULL if this tag points to a subdir + /** Numeric identifier of tag (or index inside DirectoryTable) + To avoid rewriting all the tables, and to address the problem of TagDirectoryTable with heterogeneous tag's type, + this parameter is now an unsigned int, where the leftmost 2 bytes represent the tag's type, which by default will be aqual + to 0 (INVALID). Only non null tag type will be used. See nikon attrib for an example + */ + unsigned short ID; + TagType type; + const char* name; + Interpreter* interpreter; // Call back hook +}; + +const TagAttrib* lookupAttrib (const TagAttrib* dir, const char* field); + +/// A directory of tags +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) + static Glib::ustring getDumpKey (int tagID, const Glib::ustring tagName); + + public: + TagDirectory (); + TagDirectory (TagDirectory* p, FILE* f, int base, const TagAttrib* ta, ByteOrder border, bool skipIgnored=true); + TagDirectory (TagDirectory* p, const TagAttrib* ta, ByteOrder border); + virtual ~TagDirectory (); + + inline ByteOrder getOrder () const { return order; } + TagDirectory* getParent () { return parent; } + TagDirectory* getRoot (); + inline int getCount () const { 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") + 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") + Tag* getTag (int ID) const; + virtual Tag* findTag (const char* name) const; + bool getXMPTagValue(const char* name, char* value) const; + + void keepTag (int ID); + virtual void addTag (Tag* a); + virtual void addTagFront (Tag* a); + virtual void replaceTag (Tag* a); + inline Tag* getTagByIndex (int ix) { return tags[ix]; } + inline void setOrder (ByteOrder bo) { order = bo; } + + 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 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, + const CacheImageData* cfs, const bool flagMode, rtengine::SafeKeyFile *keyFile=NULL, Glib::ustring tagDirName="") const; + virtual void sort (); +}; + +// a table of tags: id are offset from beginning and not identifiers +class TagDirectoryTable: public TagDirectory { + protected: + unsigned char *values; // Tags values are saved internally here + long zeroOffset; // Offset 0 (index 0) could be at an offset from values + long valuesSize; // Size of allocated memory + TagType defaultType; // Default type of all tags in this directory + public: + TagDirectoryTable(); + TagDirectoryTable (TagDirectory* p, unsigned char *v,int memsize,int offs, TagType type, const TagAttrib* ta, ByteOrder border); + TagDirectoryTable (TagDirectory* p, FILE* f, int memsize,int offset, TagType type, const TagAttrib* ta, ByteOrder border); + virtual ~TagDirectoryTable(); + virtual int calculateSize (); + virtual int write (int start, unsigned char* buffer); + virtual TagDirectory* clone (TagDirectory* parent); +}; + +// a class representing a single tag +class Tag { + + protected: + unsigned short tag; + TagType type; + unsigned int count; + unsigned char* value; + int valuesize; + bool keep; + bool allocOwnMemory; + + const TagAttrib* attrib; + TagDirectory* parent; + TagDirectory** directory; + MNKind makerNoteKind; + bool parseMakerNote(FILE* f, int base, ByteOrder bom ); + + public: + Tag (TagDirectory* parent, FILE* f, int base); // parse next tag from the file + Tag (TagDirectory* parent, const TagAttrib* attr); + Tag (TagDirectory* parent, const TagAttrib* attr, unsigned char *data, TagType t); + Tag (TagDirectory* parent, const TagAttrib* attr, int data, TagType t); // create a new tag from array (used + 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); + + // get basic tag properties + int getID () const { return tag; } + int getCount () const { return count; } + TagType getType () const { return (attrib && attrib->type > INVALID && attrib->type < AUTO) ? attrib->type : type; } + unsigned char* getValue () const { return value; } + signed char* getSignedValue () const { return reinterpret_cast(value); } + const TagAttrib* getAttrib () const { return attrib; } + inline ByteOrder getOrder () const { return parent ? parent->getOrder() : HOSTORDER; } + inline TagDirectory* getParent () const { return parent; } + int getValueSize () const { return valuesize; } + bool getOwnMemory () const { return allocOwnMemory; } + + // read/write value + int toInt (int ofs=0, TagType astype=INVALID); + void fromInt (int v); + double toDouble (int ofs=0); + double *toDoubleArray (int ofs=0); + void toRational (int& num, int& denom, int ofs=0); + void toString (char* buffer, int ofs=0); + void fromString (const char* v, int size=-1); + void setInt (int v, int ofs=0, TagType astype=LONG); + + + // additional getter/setter for more comfortable use + std::string valueToString (); + std::string nameToString (int i=0); + void valueFromString (const std::string& value); + + // functions for writing + int calculateSize (); + int write (int offs, int dataOffs, unsigned char* buffer); + Tag* clone (TagDirectory* parent); + + // to control if the tag shall be written + bool getKeep () { return keep; } + void setKeep (bool k) { keep = k; } + + // get subdirectory (there can be several, the last is NULL) + bool isDirectory () { return directory!=NULL; } + TagDirectory* getDirectory (int i=0) { return (directory) ? directory[i] : 0; } + + MNKind getMakerNoteFormat () { return makerNoteKind; } + }; + +class ExifManager { + + static std::vector defTags; + + static Tag* saveCIFFMNTag (FILE* f, TagDirectory* root, int len, const char* name); + public: + static TagDirectory* parse (FILE*f, int base, bool skipIgnored=true); + static TagDirectory* parseJPEG (FILE*f); + 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); + + static const std::vector& getDefaultTIFFTags (TagDirectory* forthis); + static int createJPEGMarker (const TagDirectory* root, const rtengine::procparams::ExifPairs& changeList, int W, int H, unsigned char* buffer); + static int createTIFFHeader (const TagDirectory* root, const rtengine::procparams::ExifPairs& changeList, int W, int H, int bps, const char* profiledata, int profilelen, const char* iptcdata, int iptclen, unsigned char* buffer); +}; + +class Interpreter { + public: + Interpreter () {} + virtual ~Interpreter() {}; + virtual std::string toString (Tag* t) { + char buffer[1024]; + t->toString (buffer); + std::string s(buffer); + std::string::size_type p1 = s.find_first_not_of(' '); + if( p1 == std::string::npos ) + return s; + else + return s.substr(p1, s.find_last_not_of(' ')-p1+1); + } + virtual void fromString (Tag* t, const std::string& value) { + if (t->getType()==SHORT || t->getType()==LONG) + t->fromInt (atoi(value.c_str())); + else + t->fromString (value.c_str()); + } + // Get the value as a double + virtual double toDouble(Tag* t, int ofs=0) { + double ud, dd; + switch (t->getType()) { + case SBYTE: return double(int(t->getSignedValue()[ofs])); + case BYTE: return (double)((int)t->getValue()[ofs]); + case ASCII: return 0.0; + case SSHORT:return (double)int2_to_signed(sget2 (t->getValue()+ofs, t->getOrder())); + case SHORT: return (double)((int)sget2 (t->getValue()+ofs, t->getOrder())); + case SLONG: + case LONG: return (double)((int)sget4 (t->getValue()+ofs, t->getOrder())); + case SRATIONAL: + case RATIONAL: ud = (int)sget4 (t->getValue()+ofs, t->getOrder()); dd = (int)sget4 (t->getValue()+ofs+4, t->getOrder()); return dd==0. ? 0. : (double)ud / (double)dd; + case FLOAT: return double(sget4 (t->getValue()+ofs, t->getOrder())); + case UNDEFINED: return 0.; + default: return 0.; // Quick fix for missing cases (INVALID, DOUBLE, OLYUNDEF, SUBDIR) + } + } + // Get the value as an int + virtual int toInt (Tag* t, int ofs=0, TagType astype=INVALID) { + int a; + if (astype == INVALID || astype==AUTO) + astype = t->getType(); + switch (astype) { + case SBYTE: return int(t->getSignedValue()[ofs]); + case BYTE: return t->getValue()[ofs]; + case ASCII: return 0; + case SSHORT:return (int)int2_to_signed(sget2 (t->getValue()+ofs, t->getOrder())); + case SHORT: return (int)sget2 (t->getValue()+ofs, t->getOrder()); + case SLONG: + case LONG: return (int)sget4 (t->getValue()+ofs, t->getOrder()); + case SRATIONAL: + case RATIONAL: a = (int)sget4 (t->getValue()+ofs+4, t->getOrder()); return a==0 ? 0 : (int)sget4 (t->getValue()+ofs, t->getOrder()) / a; + case FLOAT: return (int)toDouble(t, ofs); + case UNDEFINED: return 0; + default: return 0; // Quick fix for missing cases (INVALID, DOUBLE, OLYUNDEF, SUBDIR) + } + return 0; + } +}; + +extern Interpreter stdInterpreter; +class ChoiceInterpreter : public Interpreter { + protected: + std::map choices; + public: + ChoiceInterpreter () {}; + virtual std::string toString (Tag* t) { + std::map::iterator r = choices.find (t->toInt()); + if (r!=choices.end()) + return r->second; + else { + char buffer[1024]; + t->toString (buffer); + return std::string (buffer); + } + } +}; + +template< class T > +class IntLensInterpreter : public Interpreter { +protected: + typedef std::multimap< T, std::string> container_t; + typedef typename std::multimap< T, std::string>::iterator it_t; + typedef std::pair< T, std::string> p_t; + container_t choices; + + virtual std::string guess(const T lensID, double focalLength, double maxApertureAtFocal, double *lensInfoArray) { + it_t r; + size_t nFound = choices.count( lensID ); + + switch( nFound ) { + case 0: // lens Unknown + { + std::ostringstream s; + s << lensID; + return s.str(); + } + case 1: // lens found + r = choices.find ( lensID ); + return r->second; + default: + // More than one hit: we must guess + break; + } + + std::string bestMatch("Unknown"); + double a1,a2,f1,f2; + + /* FIRST TRY + * + * Get the lens info (min/man focal, min/max aperture) and compare them to the possible choice + */ + if (lensInfoArray) { + for ( r = choices.lower_bound( lensID ); r != choices.upper_bound(lensID); r++ ){ + if( !extractLensInfo( r->second ,f1,f2,a1,a2) ) + continue; + if (f1==lensInfoArray[0] && f2==lensInfoArray[1] && a1==lensInfoArray[2] && a2==lensInfoArray[3]) + // can't match better! we take this entry as being the one + return r->second; + } + // No lens found, we update the "unknown" string with the lens info values + if (lensInfoArray[0]==lensInfoArray[1]) + bestMatch += Glib::ustring::compose(" (%1mm", int(lensInfoArray[0])); + else + bestMatch += Glib::ustring::compose(" (%1-%2mm", int(lensInfoArray[0]), int(lensInfoArray[1])); + + if (lensInfoArray[2]==lensInfoArray[3]) + bestMatch += Glib::ustring::compose(" f/%1)", Glib::ustring::format(std::fixed, std::setprecision(1), lensInfoArray[2])); + else + bestMatch += Glib::ustring::compose(" f/%1-%2)", + Glib::ustring::format(std::fixed, std::setprecision(1), lensInfoArray[2]), + Glib::ustring::format(std::fixed, std::setprecision(1), lensInfoArray[3])); + } + + /* SECOND TRY + * + * Choose the best match: thanks to exiftool by Phil Harvey + * first throws for "out of focal range" and lower or upper aperture of the lens compared to MaxApertureAtFocal + * if the lens is not constant aperture, calculate aprox. aperture of the lens at focalLength + * and compare with actual aperture. + */ + std::ostringstream candidates; + double deltaMin = 1000.; + for ( r = choices.lower_bound( lensID ); r != choices.upper_bound(lensID); r++ ){ + double lensAperture,dif; + + if( !extractLensInfo( r->second ,f1,f2,a1,a2) ) + continue; + if( f1 == 0. || a1 == 0.) + continue; + + if( focalLength < f1 - .5 || focalLength > f2 + 0.5 ) + continue; + if( maxApertureAtFocal > 0.1){ + if( maxApertureAtFocal < a1 - 0.15 || maxApertureAtFocal > a2 +0.15) + continue; + + if( a1 == a2 || f1 == f2) + lensAperture = a1; + else + lensAperture = exp( log(a1)+(log(a2)-log(a1))/(log(f2)-log(f1))*(log(focalLength)-log(f1)) ); + + dif = abs(lensAperture - maxApertureAtFocal); + }else + dif = 0; + if( dif < deltaMin ){ + deltaMin = dif; + bestMatch = r->second; + } + if( dif < 0.15){ + if( candidates.tellp() ) + candidates << "\n or " << r->second; + else + candidates << r->second; + } + } + if( !candidates.tellp() ) + return bestMatch; + else + return candidates.str(); + } +}; + +inline static int getTypeSize( TagType type ) { + return ("11124811248484"[type<14?type:0]-'0'); +} + +extern const TagAttrib exifAttribs[]; +extern const TagAttrib gpsAttribs[]; +extern const TagAttrib iopAttribs[]; +extern const TagAttrib ifdAttribs[]; +extern const TagAttrib nikon2Attribs[]; +extern const TagAttrib nikon3Attribs[]; +extern const TagAttrib canonAttribs[]; +extern const TagAttrib pentaxAttribs[]; +extern const TagAttrib pentaxLensDataAttribs[]; +extern const TagAttrib pentaxLensInfoQAttribs[]; +extern const TagAttrib pentaxLensCorrAttribs[]; +extern const TagAttrib pentaxAEInfoAttribs[]; +extern const TagAttrib pentaxAEInfo2Attribs[]; +extern const TagAttrib pentaxAEInfo3Attribs[]; +extern const TagAttrib pentaxCameraSettingsAttribs[]; +extern const TagAttrib pentaxFlashInfoAttribs[]; +extern const TagAttrib pentaxSRInfoAttribs[]; +extern const TagAttrib pentaxSRInfo2Attribs[]; +extern const TagAttrib pentaxBatteryInfoAttribs[]; +extern const TagAttrib pentaxCameraInfoAttribs[]; +extern const TagAttrib fujiAttribs[]; +extern const TagAttrib minoltaAttribs[]; +extern const TagAttrib sonyAttribs[]; +extern const TagAttrib sonyTag9405Attribs[]; +extern const TagAttrib sonyCameraInfoAttribs[]; +extern const TagAttrib sonyCameraInfo2Attribs[]; +extern const TagAttrib sonyCameraSettingsAttribs[]; +extern const TagAttrib sonyCameraSettingsAttribs2[]; +extern const TagAttrib sonyCameraSettingsAttribs3[]; +//extern const TagAttrib sonyDNGMakerNote[]; +extern const TagAttrib olympusAttribs[]; +extern const TagAttrib kodakIfdAttribs[]; +void parseKodakIfdTextualInfo(Tag *textualInfo, Tag* exif); +} +#endif diff --git a/rtexif/sonyminoltaattribs.cc b/rtexif/sonyminoltaattribs.cc new file mode 100644 index 000000000..6e21f502e --- /dev/null +++ b/rtexif/sonyminoltaattribs.cc @@ -0,0 +1,2015 @@ +/* + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _SONYMINOLTAATTRIBS_ +#define _SONYMINOLTAATTRIBS_ + +#include + +#include "rtexif.h" + +namespace rtexif { + +class SANoYesInterpreter : public ChoiceInterpreter { + public: + SANoYesInterpreter () { + choices[1] = "No"; + choices[16] = "Yes"; + } +}; +SANoYesInterpreter saNoYesInterpreter; + +class SAOnOffInterpreter : public ChoiceInterpreter { + public: + SAOnOffInterpreter () { + choices[0] = "Off"; + choices[1] = "On"; + choices[5] = "On"; + } +}; +SAOnOffInterpreter saOnOffInterpreter; + +class SAOnOffInterpreter2 : public ChoiceInterpreter { + public: + SAOnOffInterpreter2 () { + choices[1] = "Off"; + choices[16] = "On"; + } +}; +SAOnOffInterpreter2 saOnOffInterpreter2; + +class SAOnOffInterpreter3 : public ChoiceInterpreter { + public: + SAOnOffInterpreter3 () { + choices[1] = "Off"; + choices[16] = "On (Auto)"; + choices[17] = "On (Manual)"; + } +}; +SAOnOffInterpreter3 saOnOffInterpreter3; + +class SAOnOffInterpreter4 : public ChoiceInterpreter { + public: + SAOnOffInterpreter4 () { + choices[0] = "n/a"; + choices[1] = "Off"; + choices[16] = "On"; + choices[255] = "None"; + } +}; +SAOnOffInterpreter4 saOnOffInterpreter4; + +class SAOnOffInterpreter5 : public ChoiceInterpreter { + public: + SAOnOffInterpreter5 () { + choices[1] = "On"; + choices[2] = "Off"; + } +}; +SAOnOffInterpreter5 saOnOffInterpreter5; + +class SAHighISONoiseReduction : public ChoiceInterpreter { + public: + SAHighISONoiseReduction () { + choices[0] = "Off"; + choices[1] = "Low"; + choices[2] = "Normal"; + choices[3] = "High"; + choices[256] = "Auto"; + choices[65535] = "n/a"; + } +}; +SAHighISONoiseReduction saHighISONoiseReduction; + +class SAHighISONoiseReduction2 : public ChoiceInterpreter { + public: + SAHighISONoiseReduction2 () { + choices[0] = "Normal"; + choices[1] = "High"; + choices[2] = "Low"; + choices[3] = "Off"; + choices[65535] = "n/a"; + } +}; +SAHighISONoiseReduction2 saHighISONoiseReduction2; + +class SAHighISONoiseReduction3 : public ChoiceInterpreter { + public: + SAHighISONoiseReduction3 () { + choices[0] = "Normal"; + choices[1] = "Low"; + choices[2] = "High"; + choices[3] = "Off"; + } +}; +SAHighISONoiseReduction3 saHighISONoiseReduction3; + +class SAHighISONoiseReduction4 : public ChoiceInterpreter { + public: + SAHighISONoiseReduction4 () { + choices[0] = "Off"; + choices[1] = "Low"; + choices[2] = "Normal"; + choices[3] = "High"; + } +}; +SAHighISONoiseReduction4 saHighISONoiseReduction4; + +class SAHighISONoiseReduction5 : public ChoiceInterpreter { + public: + SAHighISONoiseReduction5 () { + choices[16] = "Low"; + choices[19] = "Auto"; + } +}; +SAHighISONoiseReduction5 saHighISONoiseReduction5; + +class SASmileShutterMode : public ChoiceInterpreter { + public: + SASmileShutterMode () { + choices[17] = "Slight smile"; + choices[18] = "Normal smile"; + choices[19] = "Big smile"; + } +}; +SASmileShutterMode saSmileShutterMode; + +class SAHDRLevel : public ChoiceInterpreter { + public: + SAHDRLevel () { + choices[33] = "1 EV"; + choices[34] = "1.5 EV"; + choices[35] = "2 EV"; + choices[36] = "2.5 EV"; + choices[37] = "3 EV"; + choices[38] = "3.5 EV"; + choices[39] = "4 EV"; + choices[40] = "5 EV"; + choices[41] = "6 EV"; + } +}; +SAHDRLevel saHDRLevel; + +class SAViewingMode : public ChoiceInterpreter { + public: + SAViewingMode () { + choices[0] = "n/a"; + choices[16] = "ViewFinder"; + choices[33] = "Focus Check Live View"; + choices[34] = "Quick AF Live View"; + } +}; +SAViewingMode saViewingMode; + +class SAFlashAction : public ChoiceInterpreter { + public: + SAFlashAction () { + choices[1] = "Did not fire"; + choices[2] = "Fired"; + } +}; +SAFlashAction saFlashAction; + +class SALiveViewFocusMode : public ChoiceInterpreter { + public: + SALiveViewFocusMode () { + choices[0] = "n/a"; + choices[1] = "AF"; + choices[16] = "Manual"; + } +}; +SALiveViewFocusMode saLiveViewFocusMode; + +class SALensMount : public ChoiceInterpreter { + public: + SALensMount () { + choices[1] = "Unknown"; + choices[16] = "A-Mount"; + choices[17] = "E-Mount"; + } +}; +SALensMount saLensMount; + +class SASweepPanoramaSize : public ChoiceInterpreter { + public: + SASweepPanoramaSize () { + choices[1] = "Standard"; + choices[2] = "Wide"; + } +}; +SASweepPanoramaSize saSweepPanoramaSize; + +class SASweepPanoramaDirection : public ChoiceInterpreter { + public: + SASweepPanoramaDirection () { + choices[1] = "Right"; + choices[2] = "Left"; + choices[3] = "Up"; + choices[4] = "Down"; + } +}; +SASweepPanoramaDirection saSweepPanoramaDirection; + +class SALiveViewAFSetting : public ChoiceInterpreter { + public: + SALiveViewAFSetting () { + choices[0] = "n/a"; + choices[1] = "Phase-detect AF"; + choices[2] = "Contrast AF"; + } +}; +SALiveViewAFSetting saLiveViewAFSetting; + +class SAPanoramaSize3D : public ChoiceInterpreter { + public: + SAPanoramaSize3D () { + choices[0] = "n/a"; + choices[1] = "Standard"; + choices[2] = "Wide"; + choices[3] = "16:9"; + } +}; +SAPanoramaSize3D saPanoramaSize3D; + +class SALiveViewMetering : public ChoiceInterpreter { + public: + SALiveViewMetering () { + choices[0] = "n/a"; + choices[16] = "40 segment"; + choices[32] = "1200-zone Evaluative"; + } +}; +SALiveViewMetering saLiveViewMetering; + +class SAWhiteBalanceInterpreter: public ChoiceInterpreter { + public: + SAWhiteBalanceInterpreter(){ + choices[ 0x0] = "Auto"; + choices[ 0x1] = "Color Temperature/Color Filter"; + choices[0x10] = "Daylight"; + choices[0x20] = "Cloudy"; + choices[0x30] = "Shade"; + choices[0x40] = "Tungsten"; + choices[0x50] = "Flash"; + choices[0x60] = "Fluorescent"; + choices[0x70] = "Custom"; + } +}; +SAWhiteBalanceInterpreter saWhiteBalanceInterpreter; + +class SAWhiteBalanceSettingInterpreter: public ChoiceInterpreter { + public: + SAWhiteBalanceSettingInterpreter(){ + choices[0x10] = "Auto (-3)"; + choices[0x11] = "Auto (-2)"; + choices[0x12] = "Auto (-1)"; + choices[0x13] = "Auto (0)"; + choices[0x14] = "Auto (+1)"; + choices[0x15] = "Auto (+2)"; + choices[0x16] = "Auto (+3)"; + choices[0x20] = "Daylight (-3)"; + choices[0x21] = "Daylight (-2)"; + choices[0x22] = "Daylight (-1)"; + choices[0x23] = "Daylight (0)"; + choices[0x24] = "Daylight (+1)"; + choices[0x25] = "Daylight (+2)"; + choices[0x26] = "Daylight (+3)"; + choices[0x30] = "Shade (-3)"; + choices[0x31] = "Shade (-2)"; + choices[0x32] = "Shade (-1)"; + choices[0x33] = "Shade (0)"; + choices[0x34] = "Shade (+1)"; + choices[0x35] = "Shade (+2)"; + choices[0x36] = "Shade (+3)"; + choices[0x40] = "Cloudy (-3)"; + choices[0x41] = "Cloudy (-2)"; + choices[0x42] = "Cloudy (-1)"; + choices[0x43] = "Cloudy (0)"; + choices[0x44] = "Cloudy (+1)"; + choices[0x45] = "Cloudy (+2)"; + choices[0x46] = "Cloudy (+3)"; + choices[0x50] = "Tungsten (-3)"; + choices[0x51] = "Tungsten (-2)"; + choices[0x52] = "Tungsten (-1)"; + choices[0x53] = "Tungsten (0)"; + choices[0x54] = "Tungsten (+1)"; + choices[0x55] = "Tungsten (+2)"; + choices[0x56] = "Tungsten (+3)"; + choices[0x60] = "Fluorescent (-3)"; + choices[0x61] = "Fluorescent (-2)"; + choices[0x62] = "Fluorescent (-1)"; + choices[0x63] = "Fluorescent (0)"; + choices[0x64] = "Fluorescent (+1)"; + choices[0x65] = "Fluorescent (+2)"; + choices[0x66] = "Fluorescent (+3)"; + choices[0x70] = "Flash (-3)"; + choices[0x71] = "Flash (-2)"; + choices[0x72] = "Flash (-1)"; + choices[0x73] = "Flash (0)"; + choices[0x74] = "Flash (+1)"; + choices[0x75] = "Flash (+2)"; + choices[0x76] = "Flash (+3)"; + choices[0xa3] = "Custom"; + choices[0xf3] = "Color Temperature/Color Filter"; + } +}; +SAWhiteBalanceSettingInterpreter saWhiteBalanceSettingInterpreter; + +class SASceneModeInterpreter : public ChoiceInterpreter { + public: + SASceneModeInterpreter () { + choices[0] = "Normal (P,A,S or M)"; + choices[1] = "Portrait"; + choices[2] = "Text"; + choices[3] = "Night Scene"; + choices[4] = "Sunset"; + choices[5] = "Sports"; + choices[6] = "Landscape"; + choices[8] = "Macro"; + choices[9] = "Super Macro"; + choices[16] = "Auto"; + choices[17] = "Night Portrait"; + choices[18] = "Sweep Panorama"; + choices[19] = "Handheld Night Shot"; + choices[20] = "Anti Motion Blur"; + choices[21] = "Cont.Priority AE"; + choices[22] = "Auto+"; + choices[23] = "3D Sweep Panorama"; + } +}; +SASceneModeInterpreter saSceneModeInterpreter; + +class SAZoneMatchingInterpreter : public ChoiceInterpreter { + public: + SAZoneMatchingInterpreter () { + choices[0] = "ISO Setting Used"; + choices[1] = "High Key"; + choices[2] = "Low Key"; + } +}; +SAZoneMatchingInterpreter saZoneMatchingInterpreter; + +class SADynamicRangeOptimizerInterpreter : public ChoiceInterpreter { + public: + SADynamicRangeOptimizerInterpreter () { + choices[0] = "Off"; + choices[1] = "Standard"; + choices[2] = "Advanced"; + choices[3] = "Auto"; + choices[8] = "Advanced Lv1"; + choices[9] = "Advanced Lv2"; + choices[10] = "Advanced Lv3"; + choices[11] = "Advanced Lv4"; + choices[12] = "Advanced Lv5"; + choices[16] = "Lv1"; + choices[17] = "Lv2"; + choices[18] = "Lv3"; + choices[19] = "Lv4"; + choices[20] = "Lv5"; + } +}; +SADynamicRangeOptimizerInterpreter saDynamicRangeOptimizerInterpreter; + +class SAColorModeInterpreter : public ChoiceInterpreter { + public: + SAColorModeInterpreter () { + choices[0] = "Standard"; + choices[1] = "Vivid"; + choices[2] = "Portrait"; + choices[3] = "Landscape"; + choices[4] = "Sunset"; + choices[5] = "Night Scene"; + choices[6] = "B&W"; + choices[7] = "Adobe RGB"; + choices[12] = "Neutral"; + choices[13] = "Clear"; + choices[14] = "Deep"; + choices[15] = "Light"; + choices[16] = "Autumn"; + choices[17] = "Sepia"; + choices[100]= "Neutral"; + choices[101]= "Clear"; + choices[102]= "Deep"; + choices[103]= "Light"; + choices[104]= "Night View"; + choices[105]= "Autumn Leaves"; + } +}; +SAColorModeInterpreter saColorModeInterpreter; + +class SAExposureModeInterpreter : public ChoiceInterpreter { + public: + SAExposureModeInterpreter () { + choices[0] = "Auto"; + choices[1] = "Portrait"; + choices[2] = "Beach"; + choices[4] = "Snow"; + choices[5] = "Landscape"; + choices[6] = "Program"; + choices[7] = "Aperture Priority"; + choices[8] = "Shutter Priority"; + choices[9] = "Night Scene"; + choices[10] = "Hi-Speed Shutter"; + choices[11] = "Twilight Portrait"; + choices[12] = "Soft Snap"; + choices[13] = "Fireworks"; + choices[14] = "Smile Shutter"; + choices[15] = "Manual"; + choices[18] = "High Sensitivity"; + choices[19] = "Macro"; + choices[20] = "Advanced Sports Shooting"; + choices[29] = "Underwater"; + choices[33] = "Gourmet"; + choices[34] = "Panorama"; + choices[35] = "Handheld Twilight"; + choices[36] = "Anti Motion Blur"; + choices[37] = "Pet"; + choices[38] = "Backlight Correction HDR"; + choices[40] = "Background Defocus"; + } +}; +SAExposureModeInterpreter saExposureModeInterpreter; + +class SAQualityInterpreter : public ChoiceInterpreter { + public: + SAQualityInterpreter () { + choices[0] = "Normal"; + choices[1] = "Fine"; + } +}; +SAQualityInterpreter saQualityInterpreter; + +class SAAntiBlurInterpreter : public ChoiceInterpreter { + public: + SAAntiBlurInterpreter () { + choices[0] = "Off"; + choices[1] = "On (Continuous)"; + choices[2] = "On (Shooting)"; + choices[65535] = "n/a"; + } +}; +SAAntiBlurInterpreter saAntiBlurInterpreter; + +class SALensIDInterpreter : public IntLensInterpreter< int > { + public: + SALensIDInterpreter () { // From EXIFTOOL database 'Sony.pm' V1.94 and 'Minolta' 2.04; + // Please do not remove entries on database synchronization, and avoid transferring "categories' header" types + choices.insert(p_t(0, "Minolta AF 28-85mm f/3.5-4.5")); + choices.insert(p_t(1, "Minolta AF 80-200mm f/2.8 HS-APO G")); + choices.insert(p_t(2, "Minolta AF 28-70mm f/2.8 G")); + choices.insert(p_t(3, "Minolta AF 28-80mm f/4-5.6")); + choices.insert(p_t(4, "Minolta AF 85mm f/1.4G")); + choices.insert(p_t(5, "Minolta AF 35-70mm f/3.5-4.5")); + choices.insert(p_t(6, "Minolta AF 24-85mm f/3.5-4.5")); + choices.insert(p_t(7, "Minolta AF 100-300mm f/4.5-5.6 APO")); + choices.insert(p_t(7, "Minolta AF 100-400mm f/4.5-6.7 APO")); + choices.insert(p_t(7, "Sigma AF 100-300mm f/4 EX DG IF")); + choices.insert(p_t(8, "Minolta AF 70-210mm f/4.5-5.6")); + choices.insert(p_t(9, "Minolta AF 50mm f/3.5 Macro")); + choices.insert(p_t(10, "Minolta AF 28-105mm f/3.5-4.5 [New]")); + choices.insert(p_t(11, "Minolta AF 300mm f/4 HS-APO G")); + choices.insert(p_t(12, "Minolta AF 100mm f/2.8 Soft Focus")); + choices.insert(p_t(13, "Minolta AF 75-300mm f/4.5-5.6")); + choices.insert(p_t(14, "Minolta AF 100-400mm f/4.5-6.7 APO")); + choices.insert(p_t(15, "Minolta AF 400mm f/4.5 HS-APO G")); + choices.insert(p_t(16, "Minolta AF 17-35mm f/3.5 G")); + choices.insert(p_t(17, "Minolta AF 20-35mm f/3.5-4.5")); + choices.insert(p_t(18, "Minolta AF 28-80mm f/3.5-5.6 II")); + choices.insert(p_t(19, "Minolta AF 35mm f/1.4 G")); + choices.insert(p_t(20, "Minolta/Sony 135mm f/2.8 [T4.5] STF")); + choices.insert(p_t(22, "Minolta AF 35-80mm f/4-5.6 II")); + choices.insert(p_t(23, "Minolta AF 200mm f/4 Macro APO G")); + choices.insert(p_t(24, "Minolta/Sony AF 24-105mm f/3.5-4.5 (D)")); + choices.insert(p_t(24, "Sigma 18-50mm f/2.8 EX DC Macro")); + choices.insert(p_t(24, "Sigma 17-70mm f/2.8-4.5 DC Macro")); + choices.insert(p_t(24, "Sigma 20-40mm f/2.8 EX DG Aspherical IF")); + choices.insert(p_t(24, "Sigma 18-200mm f/3.5-6.3 DC")); + choices.insert(p_t(24, "Sigma 18-125mm f/4-5,6 DC")); + choices.insert(p_t(24, "Tamron SP AF 28-75mm f/2.8 XR Di (IF) Macro")); + choices.insert(p_t(25, "Minolta AF 100-300mm f/4.5-5.6 APO D")); + choices.insert(p_t(25, "Sigma 100-300mm f/4 EX DG APO")); + choices.insert(p_t(25, "Sigma 70mm f/2.8 EX DG Macro")); + choices.insert(p_t(25, "Sigma 20mm f/1.8 EX DG Aspherical RF")); + choices.insert(p_t(25, "Sigma 30mm f/1.4 EX DC")); + choices.insert(p_t(25, "Sigma 24mm f/1.8 EX DG ASP Macro")); + choices.insert(p_t(27, "Minolta AF 85mm f/1.4 G (D)")); + choices.insert(p_t(28, "Minolta/Sony AF 100mm f/2.8 Macro (D)")); + choices.insert(p_t(28, "Tamron SP AF 90mm f/2.8 Di Macro")); + choices.insert(p_t(28, "Tamron AF 180mm f/3.5 SP Di LD [IF] Macro")); + choices.insert(p_t(29, "Minolta/Sony AF 75-300mm f/4.5-5.6 (D)")); + choices.insert(p_t(30, "Minolta AF 28-80mm f/3.5-5.6 (D)")); + choices.insert(p_t(30, "Sigma AF 10-20mm f/4-5.6 EX DC")); + choices.insert(p_t(30, "Sigma AF 12-24mm f/4.5-5.6 EX DG")); + choices.insert(p_t(30, "Sigma 28-70mm EX DG F2.8")); + choices.insert(p_t(30, "Sigma 55-200mm f/4-5.6 DC")); + choices.insert(p_t(31, "Minolta/Sony AF 50mm f/2.8 Macro (D)")); + choices.insert(p_t(31, "Minolta/Sony AF 50mm f/3.5 Macro")); + choices.insert(p_t(32, "Minolta/Sony AF 300mm f/2.8 G or 1.5x Teleconverter")); + choices.insert(p_t(33, "Minolta/Sony AF 70-200mm f/2.8 G")); + choices.insert(p_t(35, "Minolta AF 85mm f/1.4 G (D) Limited")); + choices.insert(p_t(36, "Minolta AF 28-100mm f/3.5-5.6 (D)")); + choices.insert(p_t(38, "Minolta AF 17-35mm f/2.8-4 (D)")); + choices.insert(p_t(39, "Minolta AF 28-75mm f/2.8 (D)")); + choices.insert(p_t(40, "Minolta/Sony AF DT 18-70mm f/3.5-5.6 (D)")); + choices.insert(p_t(41, "Minolta/Sony AF DT 11-18mm f/4.5-5.6 (D)")); + choices.insert(p_t(41, "Tamron SP AF 11-18mm f/4.5-5.6 Di II LD Aspherical IF")); + choices.insert(p_t(42, "Minolta AF DT 18-200mm f/3.5-6.3 (D)")); + choices.insert(p_t(43, "Minolta AF 35mm f/1.4 G")); + choices.insert(p_t(44, "Sony AF 50mm f/1.4")); + choices.insert(p_t(45, "Carl Zeiss Planar T* 85mm f/1.4 ZA")); + choices.insert(p_t(46, "Carl Zeiss Vario-Sonnar T* DT 16-80mm f/3.5-4.5 ZA")); + choices.insert(p_t(47, "Carl Zeiss Sonnar T* 135mm F1.8 ZA")); + choices.insert(p_t(48, "Carl Zeiss Vario-Sonnar T* 24-70mm f/2.8 ZA SSM")); + choices.insert(p_t(49, "Sony AF DT 55-200mm f/4-5.6")); + choices.insert(p_t(50, "Sony AF DT 18-250mm f/3.5-6.3")); + choices.insert(p_t(51, "Sony AF DT 16-105mm f/3.5-5.6")); + choices.insert(p_t(52, "Sony AF 70-300mm f/4.5-5.6 G SSM")); + choices.insert(p_t(52, "Tamron SP 70-300mm f/4-5.6 Di VC USD")); + choices.insert(p_t(53, "Sony AF 70-400mm f/4.5-5.6 G SSM")); + choices.insert(p_t(54, "Carl Zeiss Vario-Sonnar T* 16-35mm f/2.8 ZA SSM")); + choices.insert(p_t(55, "Sony DT 18-55mm f/3.5-5.6 SAM")); + choices.insert(p_t(56, "Sony AF DT 55-200mm f/4-5.6 SAM")); + choices.insert(p_t(57, "Sony AF DT 50mm f/1.8 SAM")); + choices.insert(p_t(57, "Tamron SP AF 60mm f/2 Di II LD [IF] Macro 1:1")); + choices.insert(p_t(57, "Tamron 18-270mm f/3.5-6.3 Di II PZD")); + choices.insert(p_t(58, "Sony AF DT 30mm f/2.8 SAM Macro")); + choices.insert(p_t(59, "Sony AF 28-75mm f/2.8 SAM")); + choices.insert(p_t(60, "Carl Zeiss Distagon T* 24mm f/2 ZA SSM")); + choices.insert(p_t(61, "Sony AF 85mm f/2.8 SAM")); + choices.insert(p_t(62, "Sony DT 35mm f/1.8 SAM")); + choices.insert(p_t(63, "Sony DT 16-50mm f/2.8 SSM")); + choices.insert(p_t(64, "Sony 500mm f/4.0 G SSM")); + choices.insert(p_t(65, "Sony DT 18-135mm f/3.5-5.6 SAM")); + choices.insert(p_t(66, "Sony 300mm f/2.8 G SSM II")); + choices.insert(p_t(67, "Sony 70-20mm f/2.8 G SSM")); + choices.insert(p_t(68, "Sony DT 55-300mm f/4.5-5.6 SAM")); + choices.insert(p_t(69, "Sony 70-400mm f/4-5.6 G SSM II")); + choices.insert(p_t(70, "Carl Zeiss Planar T* 50mm f/1.4 ZA SSM")); + choices.insert(p_t(128, "Tamron AF 18-200mm f/3.5-6.3 XR Di II LD Aspherical (IF)")); + choices.insert(p_t(128, "Tamron AF 28-300mm f/3.5-6.3")); + choices.insert(p_t(128, "Tamron 80-300mm f/3.5-6.3")); + choices.insert(p_t(128, "Tamron AF 28-200mm f/3.8-5.6 XR Di Aspherical [IF] Macro")); + choices.insert(p_t(128, "Tamron SP AF 17-35mm f/2.8-4 Di LD Aspherical IF")); + choices.insert(p_t(128, "Sigma AF 50-150mm f/2.8 EX DC APO HSM II")); + choices.insert(p_t(128, "Sigma 10-20mm f/3.5 EX DC HSM")); + choices.insert(p_t(128, "Sigma 70-200mm f/2.8 II EX DG APO Macro HSM")); + choices.insert(p_t(128, "Sigma 10mm f/2.8 EX DC HSM Fisheye")); + choices.insert(p_t(128, "Sigma 35mm f/1.4 DG HSM")); + choices.insert(p_t(128, "Sigma 50mm f/1.4 EX DG HSM")); + choices.insert(p_t(128, "Sigma 85mm f/1.4 EX DG HSM")); + choices.insert(p_t(128, "Sigma 24-70mm f/2.8 IF EX DG HSM")); + choices.insert(p_t(128, "Sigma 18-250mm f/3.5-6.3 DC OS HSM")); + choices.insert(p_t(128, "Sigma 17-50mm f/2.8 EX DC HSM")); + choices.insert(p_t(128, "Sigma 17-70mm f/2.8-4 DC Macro HSM")); + choices.insert(p_t(129, "Tamron 200-400mm f/5.6 LD")); + choices.insert(p_t(129, "Tamron 70-300mm f/4-5.6 LD")); + choices.insert(p_t(131, "Tamron 20-40mm f/2.7-3.5 SP Aspherical IF")); + choices.insert(p_t(135, "Vivitar 28-210mm f/3.5-5.6")); + choices.insert(p_t(136, "Tokina EMZ M100 AF 100mm f/3.5")); + choices.insert(p_t(137, "Cosina 70-210mm f/2.8-4 AF")); + choices.insert(p_t(138, "Soligor 19-35mm f/3.5-4.5")); + choices.insert(p_t(142, "Voigtlander 70-300mm f/4.5-5.6")); + choices.insert(p_t(146, "Voigtlander Macro APO-Lanthar 125mm f/2.5 SL")); + choices.insert(p_t(255, "Tamron SP AF 17-50mm f/2.8 XR Di II LD Aspherical")); + choices.insert(p_t(255, "Tamron AF 18-250mm f/3.5-6.3 XR Di II LD")); + choices.insert(p_t(255, "Tamron AF 55-200mm f/4-5.6 Di II LD Macro")); + choices.insert(p_t(255, "Tamron AF 70-300mm f/4-5.6 Di LD Macro 1:2")); + choices.insert(p_t(255, "Tamron SP AF 200-500mm f/5.0-6.3 Di LD [IF]")); + choices.insert(p_t(255, "Tamron SP AF 10-24mm f/3.5-4.5 Di II LD Aspherical [IF]")); + choices.insert(p_t(255, "Tamron SP AF 70-200mm f/2.8 Di LD Macro [IF]")); + choices.insert(p_t(255, "Tamron SP AF 28-75mm f/2.8 XR Di LD Aspherical [IF]")); + choices.insert(p_t(2550, "Minolta AF 50mm f/1.7")); + choices.insert(p_t(2551, "Minolta AF 35-70mm f/4")); + choices.insert(p_t(2551, "Sigma UC AF 28-70mm f/3.5-4.5")); + choices.insert(p_t(2551, "Sigma AF 28-70mm f/2.8")); + choices.insert(p_t(2551, "Sigma M-AF 70-200mm f/2.8 EX Aspherical")); + choices.insert(p_t(2551, "Quantaray M-AF 35-80mm f/4-5.6")); + choices.insert(p_t(2552, "Minolta AF 28-85mm f/3.5-4.5 [New]")); + choices.insert(p_t(2552, "Tokina 19-35mm f/3.5-4.5")); + choices.insert(p_t(2552, "Tokina 28-70mm f/2.8 AT-X")); + choices.insert(p_t(2552, "Tokina 80-400mm f/4.5-5.6 AT-X AF II 840")); + choices.insert(p_t(2552, "Tokina AF PRO 28-80mm f/2.8 AT-X 280")); + choices.insert(p_t(2552, "Tokina AT-X PRO II AF 28-70mm f/2.6-2.8 270")); + choices.insert(p_t(2552, "Tamron AF 19-35mm f/3.5-4.5")); + choices.insert(p_t(2552, "Angenieux AF 28-70mm f/2.6")); + choices.insert(p_t(2553, "Minolta AF 28-135mm f/4-4.5")); + choices.insert(p_t(2553, "Sigma ZOOM-alpha 35-135mm f/3.5-4.5")); + choices.insert(p_t(2553, "Sigma 28-105mm f/2.8-4 Aspherical")); + choices.insert(p_t(2554, "Minolta AF 35-105mm f/3.5-4.5")); + choices.insert(p_t(2555, "Minolta AF 70-210mm f/4 Macro")); + choices.insert(p_t(2555, "Sigma 70-210mm f/4-5.6 APO")); + choices.insert(p_t(2555, "Sigma M-AF 70-200mm f/2.8 EX APO")); + choices.insert(p_t(2555, "Sigma 75-200mm f/2.8-3.5")); + choices.insert(p_t(2556, "Minolta AF 135mm f/2.8")); + choices.insert(p_t(2557, "Minolta AF 28mm f/2.8")); + choices.insert(p_t(2558, "Minolta AF 24-50mm f/4")); + choices.insert(p_t(2560, "Minolta AF 100-200mm f/4.5")); + choices.insert(p_t(2561, "Minolta AF 75-300mm f/4.5-5.6")); + choices.insert(p_t(2561, "Sigma 70-300mm f/4-5.6 DL Macro")); + choices.insert(p_t(2561, "Sigma 300mm f/4 APO Macro")); + choices.insert(p_t(2561, "Sigma AF 500mm f/4.5 APO")); + choices.insert(p_t(2561, "Sigma AF 170-500mm f/5-6.3 APO Aspherical")); + choices.insert(p_t(2561, "Tokina AT-X AF 300mm f/4")); + choices.insert(p_t(2561, "Tokina AT-X AF 400mm f/5.6 SD")); + choices.insert(p_t(2561, "Tokina AF 730 II 75-300mm f/4.5-5.6")); + choices.insert(p_t(2562, "Minolta/Sony AF 50mm f/1.4 [New]")); + choices.insert(p_t(2563, "Minolta AF 300mm f/2.8 G")); + choices.insert(p_t(2563, "Sigma AF 50-500mm f/4-6.3 EX DG APO")); + choices.insert(p_t(2563, "Sigma AF 170-500mm f/5-6.3 APO Aspherical")); + choices.insert(p_t(2563, "Sigma AF 500mm f/4.5 EX DG APO")); + choices.insert(p_t(2563, "Sigma 400mm f/5.6 APO")); + choices.insert(p_t(2564, "Minolta AF 50mm f/2.8 Macro")); + choices.insert(p_t(2564, "Sigma 50mm f/2.8 EX Macro")); + choices.insert(p_t(2565, "Minolta AF 600mm f/4")); + choices.insert(p_t(2566, "Minolta AF 24mm f/2.8")); + choices.insert(p_t(2572, "Minolta/Sony AF 500mm f/8 Reflex")); + choices.insert(p_t(2578, "Minolta AF 16mm f/2.8 Fisheye")); + choices.insert(p_t(2578, "Sigma 8mm f/4 EX DG Fisheye")); + choices.insert(p_t(2578, "Sigma 14mm f/3.5")); + choices.insert(p_t(2578, "Sigma 15mm f/2.8 Fisheye")); + choices.insert(p_t(2579, "Minolta AF 20mm f/2.8")); + choices.insert(p_t(2581, "Minolta/Sony AF 100mm f/2.8 Macro")); + choices.insert(p_t(2581, "Sigma AF 90mm f/2.8 Macro")); + choices.insert(p_t(2581, "Sigma AF 105mm f/2.8 EX DG Macro")); + choices.insert(p_t(2581, "Sigma 180mm f/5.6 Macro")); + choices.insert(p_t(2581, "Tamron AF 90mm f/2.8 Macro")); + choices.insert(p_t(2585, "Minolta AF 35-105mm f/3.5-4.5 New")); + choices.insert(p_t(2585, "Beroflex 35-135mm f/3.5-4.5")); + choices.insert(p_t(2585, "Tamron AF 24-135mm f/3.5-5.6")); + choices.insert(p_t(2588, "Minolta AF 70-210mm f/3.5-4.5")); + choices.insert(p_t(2589, "Minolta AF 80-200 f/2.8 APO")); + choices.insert(p_t(2589, "Tokina 80-200mm f/2.8")); + choices.insert(p_t(2591, "Minolta AF 35mm f/1.4")); + choices.insert(p_t(2592, "Minolta AF 85mm f/1.4 G (D)")); + choices.insert(p_t(2593, "Minolta AF 200mm f/2.8 G APO")); + choices.insert(p_t(2594, "Minolta AF 3x-1x f/1.7-2.8 Macro")); + choices.insert(p_t(2596, "Minolta AF 28mm f/2")); + choices.insert(p_t(2597, "Minolta AF 35mm f/2")); + choices.insert(p_t(2598, "Minolta AF 100mm f/2")); + choices.insert(p_t(2604, "Minolta AF 80-200mm f/4.5-5.6")); + choices.insert(p_t(2605, "Minolta AF 35-80mm f/4-5.6")); + choices.insert(p_t(2606, "Minolta AF 100-300mm f/4.5-5.6 (D)")); + choices.insert(p_t(2607, "Minolta AF 35-80mm f/4-5.6")); + choices.insert(p_t(2608, "Minolta AF 300mm f/2.8 G")); + choices.insert(p_t(2609, "Minolta AF 600mm f/4 HS-APO G")); + choices.insert(p_t(2612, "Minolta AF 200mm f/2.8 G HS-APO")); + choices.insert(p_t(2613, "Minolta AF 50mm f/1.7 New")); + choices.insert(p_t(2615, "Minolta AF 28-105mm f/3.5-4.5 Power Zoom")); + choices.insert(p_t(2616, "Minolta AF 35-200mm f/4.5-5.6 Power Zoom")); + choices.insert(p_t(2618, "Minolta AF 28-80mm f/4-5.6 Power Zoom")); + choices.insert(p_t(2619, "Minolta AF 80-200mm f/4.5-5.6 Power Zoom")); + choices.insert(p_t(2620, "Minolta AF 28-70mm f/2.8 G")); + choices.insert(p_t(2621, "Minolta AF 100-300mm f/4.5-5.6 Power Zoom")); + choices.insert(p_t(2624, "Minolta AF 35-80mm f/4-5.6 Power Zoom")); + choices.insert(p_t(2628, "Minolta AF 80-200mm f/2.8 G")); + choices.insert(p_t(2629, "Minolta AF 85mm f/1.4 New")); + choices.insert(p_t(2631, "Minolta/Sony AF 100-300mm f/4.5-5.6 APO")); + choices.insert(p_t(2632, "Minolta AF 24-50mm f/4 New")); + choices.insert(p_t(2638, "Minolta AF 50mm f/2.8 Macro New")); + choices.insert(p_t(2639, "Minolta AF 100mm f/2.8 Macro")); + choices.insert(p_t(2641, "Minolta AF 20mm f/2.8 New")); + choices.insert(p_t(2642, "Minolta AF 24mm f/2.8 New")); + choices.insert(p_t(2644, "Minolta AF 100-400mm f/4.5-6.7 APO")); + choices.insert(p_t(2662, "Minolta AF 50mm f/1.4 New")); + choices.insert(p_t(2667, "Minolta AF 35mm f/2 New")); + choices.insert(p_t(2668, "Minolta AF 28mm f/2 New")); + choices.insert(p_t(2672, "Minolta AF 24-105mm f/3.5-4.5 (D)")); + choices.insert(p_t(4574, "Minolta AF 200mm f/2.8 G x2")); + choices.insert(p_t(4575, "1.4 x Teleconverter")); + choices.insert(p_t(4585, "Tamron SP AF 300mm f/2.8 LD IF")); + choices.insert(p_t(6553, "Arax MC 35mm f/2.8 Tilt+Shift")); + choices.insert(p_t(6553, "Arax MC 80mm f/2.8 Tilt+Shift")); + choices.insert(p_t(6553, "Zenitar MF 16mm f/2.8 Fisheye M42")); + choices.insert(p_t(6553, "Samyang 500mm Mirror f/8")); + choices.insert(p_t(6553, "Pentacon Auto 135mm f/2.8")); + choices.insert(p_t(6553, "Pentacon Auto 29mm f/2.8")); + choices.insert(p_t(6553, "Helios 44-2 58mm f/2")); + choices.insert(p_t(25501, "Minolta AF 50mm f/1.7")); + choices.insert(p_t(25511, "Minolta AF 35-70mm f/4")); + choices.insert(p_t(25511, "Sigma UC AF 28-70mm f/3.5-4.5")); + choices.insert(p_t(25511, "Sigma AF 28-70mm f/2.8")); + choices.insert(p_t(25511, "Sigma M-AF 70-200mm f/2.8 EX Aspherical")); + choices.insert(p_t(25511, "Quantaray M-AF 35-80mm f/4-5.6")); + choices.insert(p_t(25521, "Minolta AF 28-85mm f/3.5-4.5")); + choices.insert(p_t(25521, "Tokina 19-35mm f/3.5-4.5")); + choices.insert(p_t(25521, "Tokina 28-70mm f/2.8 AT-X")); + choices.insert(p_t(25521, "Tokina 80-400mm f/4.5-5.6 AT-X AF II 840")); + choices.insert(p_t(25521, "Tokina AF PRO 28-80mm f/2.8 AT-X 280")); + choices.insert(p_t(25521, "Tokina AT-X PRO II AF 28-70mm f/2.6-2.8 270")); + choices.insert(p_t(25521, "Tamron AF 19-35mm f/3.5-4.5")); + choices.insert(p_t(25521, "Angenieux AF 28-70mm f/2.6")); + choices.insert(p_t(25521, "Tokina AT-X 17 AF 17mm f/3.5")); + choices.insert(p_t(25531, "Minolta AF 28-135mm f/4-4.5")); + choices.insert(p_t(25531, "Sigma ZOOM-alpha 35-135mm f/3.5-4.5")); + choices.insert(p_t(25531, "Sigma 28-105mm f/2.8-4 Aspherical")); + choices.insert(p_t(25531, "Sigma 28-105mm f/4-5.6 UC")); + choices.insert(p_t(25541, "Minolta AF 35-105mm f/3.5-4.5")); + choices.insert(p_t(25551, "Minolta AF 70-210mm f/4 Macro")); + choices.insert(p_t(25551, "Sigma 70-210mm f/4-5.6 APO")); + choices.insert(p_t(25551, "Sigma M-AF 70-200mm f/2.8 EX APO")); + choices.insert(p_t(25551, "Sigma 75-200mm f/2.8-3.5")); + choices.insert(p_t(25561, "Minolta AF 135mm f/2.8")); + choices.insert(p_t(25571, "Minolta/Sony AF 28mm f/2.8")); + choices.insert(p_t(25581, "Minolta AF 24-50mm f/4")); + choices.insert(p_t(25601, "Minolta AF 100-200mm f/4.5")); + choices.insert(p_t(25611, "Minolta AF 75-300mm f/4.5-5.6")); + choices.insert(p_t(25611, "Sigma 70-300mm f/4-5.6 DL Macro")); + choices.insert(p_t(25611, "Sigma 300mm f/4 APO Macro")); + choices.insert(p_t(25611, "Sigma AF 500mm f/4.5 APO")); + choices.insert(p_t(25611, "Sigma AF 170-500mm f/5-6.3 APO Aspherical")); + choices.insert(p_t(25611, "Tokina AT-X AF 300mm f/4")); + choices.insert(p_t(25611, "Tokina AT-X AF 400mm f/5.6 SD")); + choices.insert(p_t(25611, "Tokina AF 730 II 75-300mm f/4.5-5.6")); + choices.insert(p_t(25611, "Sigma 800mm f/5.6 APO")); + choices.insert(p_t(25611, "Sigma AF 400mm f/5.6 APO Macro")); + choices.insert(p_t(25621, "Minolta AF 50mm f/1.4")); + choices.insert(p_t(25631, "Minolta AF 300mm f/2.8 APO")); + choices.insert(p_t(25631, "Sigma AF 50-500mm f/4-6.3 EX DG APO")); + choices.insert(p_t(25631, "Sigma AF 170-500mm f/5-6.3 APO Aspherical")); + choices.insert(p_t(25631, "Sigma AF 500mm f/4.5 EX DG APO")); + choices.insert(p_t(25631, "Sigma 400mm f/5.6 APO")); + choices.insert(p_t(25641, "Minolta AF 50mm f/2.8 Macro")); + choices.insert(p_t(25641, "Sigma AF 50mm f/2.8 EX Macro")); + choices.insert(p_t(25651, "Minolta AF 600mm f/4")); + choices.insert(p_t(25661, "Minolta AF 24mm f/2.8")); + choices.insert(p_t(25661, "Sigma 17-35mm f/2.8-4 EX Aspherical")); + choices.insert(p_t(25721, "Minolta/Sony AF 500mm f/8 Reflex")); + choices.insert(p_t(25781, "Minolta/Sony AF 16mm f/2.8 Fisheye")); + choices.insert(p_t(25781, "Sigma 8mm f/4 EX DG Fisheye")); + choices.insert(p_t(25781, "Sigma 14mm f/3.5")); + choices.insert(p_t(25781, "Sigma 15mm f/2.8 Fisheye")); + choices.insert(p_t(25791, "Minolta/Sony AF 20mm f/2.8")); + choices.insert(p_t(25791, "Tokina AT-X Pro DX 11-16mm f/2.8")); + choices.insert(p_t(25811, "Minolta/Sony AF 100mm f/2.8 Macro")); + choices.insert(p_t(25811, "Sigma AF 90mm f/2.8 Macro")); + choices.insert(p_t(25811, "Sigma AF 105mm f/2.8 EX DG Macro")); + choices.insert(p_t(25811, "Sigma 180mm f/5.6 Macro")); + choices.insert(p_t(25811, "Sigma 180mm f/3.5 EX DG Macro")); + choices.insert(p_t(25811, "Tamron 90mm f/2.8 Macro")); + choices.insert(p_t(25851, "Beroflex 35-135mm f/3.5-4.5")); + choices.insert(p_t(25858, "Minolta AF 35-105mm f/3.5-4.5")); + choices.insert(p_t(25858, "Tamron 24-135mm f/3.5-5.6")); + choices.insert(p_t(25881, "Minolta AF 70-210mm f/3.5-4.5")); + choices.insert(p_t(25891, "Minolta AF 80-200mm f/2.8 APO")); + choices.insert(p_t(25891, "Tokina 80-200mm f/2.8")); + choices.insert(p_t(25901, "Minolta AF 200mm f/2.8 G APO + Minolta AF 1.4x APO")); + choices.insert(p_t(25901, "Minolta AF 600mm f/4 HS-APO G + Minolta AF 1.4x APO")); + choices.insert(p_t(25911, "Minolta AF 35mm f/1.4")); + choices.insert(p_t(25921, "Minolta AF 85mm f/1.4 G (D)")); + choices.insert(p_t(25931, "Minolta AF 200mm f/2.8 G APO")); + choices.insert(p_t(25941, "Minolta AF 3x-1x f/1.7-2.8 Macro")); + choices.insert(p_t(25961, "Minolta AF 28mm f/2")); + choices.insert(p_t(25971, "Minolta AF 35mm f/2")); + choices.insert(p_t(25981, "Minolta AF 100mm f/2")); + choices.insert(p_t(26011, "Minolta AF 200mm f/2.8 G APO + Minolta AF 2x APO")); + choices.insert(p_t(26011, "Minolta AF 600mm f/4 HS-APO G + Minolta AF 2x APO")); + choices.insert(p_t(26041, "Minolta AF 80-200mm f/4.5-5.6")); + choices.insert(p_t(26051, "Minolta AF 35-80mm f/4-5.6")); + choices.insert(p_t(26061, "Minolta AF 100-300mm f/4.5-5.6")); + choices.insert(p_t(26071, "Minolta AF 35-80mm f/4-5.6")); + choices.insert(p_t(26081, "Minolta AF 300mm f/2.8 HS-APO G")); + choices.insert(p_t(26091, "Minolta AF 600mm f/4 HS-APO G")); + choices.insert(p_t(26121, "Minolta AF 200mm f/2.8 HS-APO G")); + choices.insert(p_t(26131, "Minolta AF 50mm f/1.7 New")); + choices.insert(p_t(26151, "Minolta AF 28-105mm f/3.5-4.5 xi")); + choices.insert(p_t(26161, "Minolta AF 35-200mm f/4.5-5.6 xi")); + choices.insert(p_t(26181, "Minolta AF 28-80mm f/4-5.6 xi")); + choices.insert(p_t(26191, "Minolta AF 80-200mm f/4.5-5.6 xi")); + choices.insert(p_t(26201, "Minolta AF 28-70mm f/2.8 G")); + choices.insert(p_t(26211, "Minolta AF 100-300mm f/4.5-5.6 xi")); + choices.insert(p_t(26241, "Minolta AF 35-80mm f/4-5.6 Power Zoom")); + choices.insert(p_t(26281, "Minolta AF 80-200mm f/2.8 G")); + choices.insert(p_t(26291, "Minolta AF 85mm f/1.4 New")); + choices.insert(p_t(26311, "Minolta/Sony AF 100-300mm f/4.5-5.6 APO")); + choices.insert(p_t(26321, "Minolta AF 24-50mm f/4 New")); + choices.insert(p_t(26381, "Minolta AF 50mm f/2.8 Macro New")); + choices.insert(p_t(26391, "Minolta AF 100mm f/2.8 Macro")); + choices.insert(p_t(26411, "Minolta/Sony AF 20mm f/2.8 New")); + choices.insert(p_t(26421, "Minolta AF 24mm f/2.8 New")); + choices.insert(p_t(26441, "Minolta AF 100-400mm f/4.5-6.7 APO")); + choices.insert(p_t(26621, "Minolta AF 50mm f/1.4 New")); + choices.insert(p_t(26671, "Minolta AF 35mm f/2 New")); + choices.insert(p_t(26681, "Minolta AF 28mm f/2 New")); + choices.insert(p_t(26721, "Minolta AF 24-105mm f/3.5-4.5 (D)")); + choices.insert(p_t(45671, "Tokina 70-210mm f/4-5.6")); + choices.insert(p_t(45741, "Tamron SP AF 90mm f/2.5")); + choices.insert(p_t(45741, "Tokina RF 500mm f/8.0 x2")); + choices.insert(p_t(45741, "Tokina 300mm f/2.8 x2")); + choices.insert(p_t(45741, "Minolta AF 200mm f/2.8 G x2")); + choices.insert(p_t(45851, "Tamron SP AF 300mm f/2.8 LD IF")); + choices.insert(p_t(45871, "Tamron AF 70-210mm f/2.8 SP LD")); + choices.insert(p_t(65535, "Sony E 16mm f/2.8")); + choices.insert(p_t(65535, "Sony E 18-55mm f/3.5-5.6 OSS")); + choices.insert(p_t(65535, "Sony E 55-210mm f/4.5-6.3 OSS")); + choices.insert(p_t(65535, "Sony E 18-200mm f/3.5-6.3 OSS")); + choices.insert(p_t(65535, "Sony E 30mm f/3.5 Macro")); + choices.insert(p_t(65535, "Sony E 24mm f/1.8 ZA")); + choices.insert(p_t(65535, "Sony E 50mm f/1.8 OSS")); + choices.insert(p_t(65535, "Sony E 16-70mm f/4 ZA OSS")); + choices.insert(p_t(65535, "Sony E 10-18mm f/4 OSS")); + choices.insert(p_t(65535, "Sony E PZ 16-50mm f/3.5-5.6 OSS")); + choices.insert(p_t(65535, "Sony FE 35mm f/2.8 ZA")); + choices.insert(p_t(65535, "Sony FE 24-70mm f/4 ZA OSS")); + choices.insert(p_t(65535, "Sony E 18-200mm f/3.5-6.3 OSS LE")); + choices.insert(p_t(65535, "Sony E 20mm f/2.8")); + choices.insert(p_t(65535, "Sony E 35mm f/1.8 OSS")); + choices.insert(p_t(65535, "Sony E PZ 18-200mm f/3.5-6.3 OSS")); + choices.insert(p_t(65535, "Sony FE 55mm f/1.8 ZA")); + choices.insert(p_t(65535, "Sony FE 28-70mm f/3.5-5.6 OSS")); + choices.insert(p_t(65535, "Sony E PZ 18-105mm f/4 G OSS")); + choices.insert(p_t(65535, "Sony FE 70-200mm f/4 G OSS")); + choices.insert(p_t(65535, "Sigma 19mm f/2.8 [EX] DN")); + choices.insert(p_t(65535, "Sigma 30mm f/2.8 [EX] DN")); + choices.insert(p_t(65535, "Sigma 60mm f/2.8 DN")); + choices.insert(p_t(65535, "Tamron 18-200mm f/3.5-6.3 Di III VC")); + choices.insert(p_t(65535, "Zeiss Touit 12mm f/2.8")); + choices.insert(p_t(65535, "Zeiss Touit 32mm f/1.8")); + choices.insert(p_t(65535, "Arax MC 35mm f/2.8 Tilt+Shift")); + choices.insert(p_t(65535, "Arax MC 80mm f/2.8 Tilt+Shift")); + choices.insert(p_t(65535, "Zenitar MF 16mm f/2.8 Fisheye M42")); + choices.insert(p_t(65535, "Samyang 500mm f/8 Mirror")); + choices.insert(p_t(65535, "Pentacon Auto 135mm f/2.8")); + choices.insert(p_t(65535, "Pentacon Auto 29mm f/2.8")); + choices.insert(p_t(65535, "Helios 44-2 58mm f/2")); + } + + virtual std::string toString (Tag* t) + { + int lensID = t->toInt(); + Tag *lensInfoTag = t->getParent()->getRoot()->findTag("LensInfo"); + Tag *apertureTag = t->getParent()->getRoot()->findTag("MaxApertureValue"); + Tag *focalLengthTag = t->getParent()->getRoot()->findTag("FocalLength"); + double maxApertureAtFocal = 0.; + double focalLength = 0.; + if( apertureTag ) + maxApertureAtFocal = pow(2.0, apertureTag->toDouble()/2.0); + if( focalLengthTag ) + focalLength = focalLengthTag->toDouble(); + double *liArray = NULL; + if (lensInfoTag) + liArray = lensInfoTag->toDoubleArray(); + std::string retval = guess( lensID, focalLength, maxApertureAtFocal, liArray); + if(liArray) + delete [] liArray; + return retval; + } +}; +SALensIDInterpreter saLensIDInterpreter; + +class SALensID2Interpreter : public IntLensInterpreter< int > { + public: + SALensID2Interpreter () { // From EXIFTOOL database 'Sony.pm' V1.94 and 'Minolta' 2.04; + // Please do not remove entries on database synchronization, and avoid transferring "categories' header" types + choices.insert(p_t(00000, "Unknown E-Mount lens or other lens")); + choices.insert(p_t(00001, "Sony LA-EA1 Adapter")); + choices.insert(p_t(00002, "Sony LA-EA2 Adapter")); + choices.insert(p_t(00006, "Sony LA-EA4 Adapter")); + choices.insert(p_t(32784, "Sony E 16mm f/2.8")); + choices.insert(p_t(32785, "Sony E 18-55mm f/3.5-5.6 OSS")); + choices.insert(p_t(32786, "Sony E 55-210mm f/4.5-6.3 OSS")); + choices.insert(p_t(32787, "Sony E 18-200mm f/3.5-6.3 OSS")); + choices.insert(p_t(32788, "Sony E 30mm f/3.5 Macro")); + choices.insert(p_t(32789, "Sony E 24mm f/1.8 ZA")); + choices.insert(p_t(32790, "Sony E 50mm f/1.8 OSS")); + choices.insert(p_t(32791, "Sony E 16-70mm f/4 ZA OSS")); + choices.insert(p_t(32792, "Sony E 10-18mm f/4 OSS")); + choices.insert(p_t(32793, "Sony E PZ 16-50mm f/3.5-5.6 OSS")); + choices.insert(p_t(32794, "Sony FE 35mm f/2.8 ZA")); + choices.insert(p_t(32795, "Sony FE 24-70mm f/4 ZA OSS")); + choices.insert(p_t(32797, "Sony E 18-200mm f/3.5-6.3 OSS LE")); + 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(32807, "Sony E PZ 18-200mm f/3.5-6.3 OSS")); + choices.insert(p_t(32808, "Sony FE 55mm f/1.8 ZA")); + choices.insert(p_t(32813, "Sony FE 28-70mm f/3.5-5.6 OSS")); + } + + virtual std::string toString (Tag* t) + { + int lensID = t->toInt(); + Tag *lensInfoTag = t->getParent()->getRoot()->findTag("LensInfo"); + Tag *apertureTag = t->getParent()->getRoot()->findTag("MaxApertureValue"); + Tag *focalLengthTag = t->getParent()->getRoot()->findTag("FocalLength"); + double maxApertureAtFocal = 0.; + double focalLength = 0.; + if( apertureTag ) + maxApertureAtFocal = pow(2.0, apertureTag->toDouble()/2.0); + if( focalLengthTag ) + focalLength = focalLengthTag->toDouble(); + double *liArray = NULL; + if (lensInfoTag) + liArray = lensInfoTag->toDoubleArray(); + std::string retval = guess( lensID, focalLength, maxApertureAtFocal, liArray); + if(liArray) + delete [] liArray; + return retval; + } +}; +SALensID2Interpreter saLensID2Interpreter; + +class MATeleconverterInterpreter : public ChoiceInterpreter { + public: + MATeleconverterInterpreter () { + choices[0] = "None "; + choices[0x48] = "Minolta AF 2x APO (D)"; + choices[0x50] = "Minolta AF 2x APO II"; + choices[0x88] = "Minolta AF 1.4x APO (D)"; + choices[0x90] = "Minolta AF 1.4x APO II"; + } +}; +MATeleconverterInterpreter maTeleconverterInterpreter; + +class MAQualityInterpreter : public ChoiceInterpreter { + public: + MAQualityInterpreter () { + choices[0] = "Raw"; + choices[1] = "Super Fine"; + choices[2] = "Fine"; + choices[3] = "Standard"; + choices[4] = "Economy"; + choices[5] = "Extra fine"; + choices[6] = "RAW + JPEG"; + choices[7] = "cRAW"; + choices[8] = "cRAW + JPEG"; + } +}; +MAQualityInterpreter maQualityInterpreter; + +class MAImageSizeInterpreter : public ChoiceInterpreter { + public: + MAImageSizeInterpreter () { + choices[1] = "1600x1200"; + choices[2] = "1280x960"; + choices[3] = "640x480"; + choices[5] = "2560x1920"; + choices[6] = "2272x1704"; + choices[7] = "2048x1536"; + } +}; +MAImageSizeInterpreter maImageSizeInterpreter; + +class SAQualityInterpreter2 : public ChoiceInterpreter { + public: + SAQualityInterpreter2 () { + choices[0] = "Raw"; + choices[2] = "cRAW"; + choices[16] = "Extra fine"; + choices[32] = "Fine"; + choices[34] = "RAW + JPEG"; + choices[35] = "cRAW + JPEG"; + choices[48] = "Standard"; + } +}; +SAQualityInterpreter2 saQualityInterpreter2; + +class SAQualityInterpreter3 : public ChoiceInterpreter { + public: + SAQualityInterpreter3 () { + choices[2] = "RAW"; + choices[4] = "RAW + JPEG"; + choices[6] = "Fine"; + choices[7] = "Standard"; + } +}; +SAQualityInterpreter3 saQualityInterpreter3; + +class SADriveMode : public ChoiceInterpreter { + public: + SADriveMode () { + choices[0] = "Single Frame"; + choices[1] = "Continuous High"; + choices[4] = "Self-timer 10 sec"; + choices[5] = "Self-timer 2 sec"; + choices[7] = "Continuous Bracketing"; + choices[12] = "Continuous Low"; + choices[18] = "White Balance Bracketing Low"; + choices[19] = "D-Range Optimizer Bracketing Low"; + } +}; +SADriveMode saDriveMode; + +class SADriveMode2 : public ChoiceInterpreter { + public: + SADriveMode2 () { + choices[0] = "Single Frame"; + choices[2] = "Continuous High"; + choices[4] = "Self-timer 10 sec"; + choices[5] = "Self-timer 2 sec, Mirror Lock-up"; + choices[7] = "Continuous Bracketing"; + choices[10] = "Remote Commander"; + choices[11] = "Continuous Self-timer"; + } +}; +SADriveMode2 saDriveMode2; + +class SADriveMode3 : public ChoiceInterpreter { + public: + SADriveMode3 () { + choices[0x10] = "Single Frame"; + choices[0x21] = "Continuous High"; + choices[0x22] = "Continuous Low"; + choices[0x30] = "Speed Priority Continuous"; + choices[0x51] = "Self-timer 10 sec"; + choices[0x52] = "Self-timer 2 sec, Mirror Lock-up"; + choices[0x71] = "Continuous Bracketing 0.3 EV"; + choices[0x75] = "Continuous Bracketing 0.7 EV"; + choices[0x91] = "White Balance Bracketing Low"; + choices[0x92] = "White Balance Bracketing High"; + choices[0xC0] = "Remote Commander"; + choices[0xD1] = "Continuous - HDR"; + choices[0xD2] = "Continuous - Multi Frame NR"; + choices[0xD3] = "Continuous - Handheld Night Shot"; + choices[0xD4] = "Continuous - Anti Motion Blur"; + choices[0xD5] = "Continuous - Sweep Panorama"; + choices[0xD6] = "Continuous - 3D Sweep Panorama"; + } +}; +SADriveMode3 saDriveMode3; + +class SAFocusMode: public ChoiceInterpreter { + public: + SAFocusMode () { + choices[0] = "Manual"; + choices[1] = "AF-S"; + choices[2] = "AF-C"; + choices[3] = "AF-A"; + choices[4] = "Permanent-AF"; + choices[65535] = "n/a"; + } +}; +SAFocusMode saFocusMode; + +class SAFocusMode2: public ChoiceInterpreter { + public: + SAFocusMode2 () { + choices[0] = "Manual"; + choices[1] = "AF-S"; + choices[2] = "AF-C"; + choices[3] = "AF-A"; + choices[65535] = "n/a"; + } +}; +SAFocusMode2 saFocusMode2; + +class SAFocusModeSetting3: public ChoiceInterpreter { + public: + SAFocusModeSetting3 () { + choices[17] = "AF-S"; + choices[18] = "AF-C"; + choices[19] = "AF-A"; + choices[32] = "Manual"; + choices[48] = "DMF"; + choices[65535] = "n/a"; + } +}; +SAFocusModeSetting3 saFocusModeSetting3; + +class SAAFMode: public ChoiceInterpreter { + public: + SAAFMode(){ + choices[0] = "Default"; + choices[1] = "Multi AF"; + choices[2] = "Center AF"; + choices[3] = "Spot AF"; + choices[4] = "Flexible Spot AF"; + choices[6] = "Touch AF"; + choices[14] = "Manual Focus"; + choices[15] = "Face Detected"; + choices[65535] = "n/a"; + } +}; +SAAFMode saAFMode; + +class SAAFAreaMode: public ChoiceInterpreter { + public: + SAAFAreaMode () { + choices[0] = "Wide"; + choices[1] = "Local"; + choices[2] = "Spot"; + } +}; +SAAFAreaMode saAFAreaMode; + +class SAAFAreaMode2: public ChoiceInterpreter { + public: + SAAFAreaMode2 () { + choices[1] = "Wide"; + choices[2] = "Spot"; + choices[3] = "Local"; + choices[4] = "Flexible"; + } +}; +SAAFAreaMode2 saAFAreaMode2; + +class SAAFPointSelected: public ChoiceInterpreter { + public: + SAAFPointSelected () { + choices[1] = "Center"; + choices[2] = "Top"; + choices[3] = "Top-Right"; + choices[4] = "Right"; + choices[5] = "Bottom-Right"; + choices[6] = "Bottom"; + choices[7] = "Bottom-Left"; + choices[8] = "Left"; + choices[9] = "Top-Left"; + choices[10] = "Far Right"; + choices[11] = "Far Left"; + } +}; +SAAFPointSelected saAFPointSelected; + +class SACameraInfoAFPointSelected: public ChoiceInterpreter { + public: + SACameraInfoAFPointSelected () { + choices[0] = "Auto"; + choices[1] = "Center"; + choices[2] = "Top"; + choices[3] = "Upper-Right"; + choices[4] = "Right"; + choices[5] = "Lower-Right"; + choices[6] = "Bottom"; + choices[7] = "Lower-Left"; + choices[8] = "Left"; + choices[9] = "Upper-Left"; + choices[10] = "Far Right"; + choices[11] = "Far Left"; + choices[12] = "Upper-middle"; + choices[13] = "Near Right"; + choices[14] = "Lower-middle"; + choices[15] = "Near Left"; + } +}; +SACameraInfoAFPointSelected saCameraInfoAFPointSelected; + +class SACameraInfoAFPoint: public ChoiceInterpreter { + public: + SACameraInfoAFPoint () { + choices[0] = "Upper-Left"; + choices[1] = "Left"; + choices[2] = "Lower-Left"; + choices[3] = "Far Left"; + choices[4] = "Top (horizontal)"; + choices[5] = "Near Right"; + choices[6] = "Center (horizontal)"; + choices[7] = "Near Left"; + choices[8] = "Bottom (horizontal)"; + choices[9] = "Top (vertical)"; + choices[10] = "Center (vertical)"; + choices[11] = "Bottom (vertical)"; + choices[12] = "Far Right"; + choices[13] = "Upper-Right"; + choices[14] = "Right"; + choices[15] = "Lower-Right"; + choices[16] = "Upper-middle"; + choices[17] = "Lower-middle"; + choices[255] = "(none)"; + } +}; +SACameraInfoAFPoint saCameraInfoAFPoint; + +class SAAFPointSelected2: public ChoiceInterpreter { + public: + SAAFPointSelected2 () { + choices[1] = "Center"; + choices[2] = "Top"; + choices[3] = "Top-Right"; + choices[4] = "Right"; + choices[5] = "Bottom-Right"; + choices[6] = "Bottom"; + choices[7] = "Bottom-Left"; + choices[8] = "Left"; + choices[9] = "Top-Left"; + } +}; +SAAFPointSelected2 saAFPointSelected2; + +class SAMeteringMode0_3: public ChoiceInterpreter { + public: + SAMeteringMode0_3 () { + choices[0] = "Multi-segment"; + choices[2] = "Center-weighted Average"; + choices[3] = "Spot"; + } +}; +SAMeteringMode0_3 saMeteringMode0_3; + +class SAMeteringMode1_3: public ChoiceInterpreter { + public: + SAMeteringMode1_3 () { + choices[1] = "Multi-segment"; + choices[2] = "Center-weighted Average"; + choices[3] = "Spot"; + } +}; +SAMeteringMode1_3 saMeteringMode1_3; + +class SAMeteringMode1_4: public ChoiceInterpreter { + public: + SAMeteringMode1_4 () { + choices[1] = "Multi-segment"; + choices[2] = "Center-weighted Average"; + choices[4] = "Spot"; + } +}; +SAMeteringMode1_4 saMeteringMode1_4; + +class SADynamicRangeOptimizerMode: public ChoiceInterpreter { + public: + SADynamicRangeOptimizerMode () { + choices[0] = "Off"; + choices[1] = "Standard"; + choices[2] = "Advanced Auto"; + choices[3] = "Advanced Level"; + choices[4097] = "Auto"; + } +}; +SADynamicRangeOptimizerMode saDynamicRangeOptimizerMode; + +class SADynamicRangeOptimizerSetting: public ChoiceInterpreter { + public: + SADynamicRangeOptimizerSetting () { + choices[1] = "Off"; + choices[2] = "On (Auto)"; + choices[3] = "On (Manual)"; + } +}; +SADynamicRangeOptimizerSetting saDynamicRangeOptimizerSetting; + +class SACreativeStyle: public ChoiceInterpreter { + public: + SACreativeStyle () { + choices[1] = "Standard"; + choices[2] = "Vivid"; + choices[3] = "Portrait"; + choices[4] = "Landscape"; + choices[5] = "Sunset"; + choices[6] = "Night View/Portrait"; + choices[8] = "B&W"; + choices[9] = "Adobe RGB"; + choices[11] = "Neutral"; + choices[12] = "Clear"; + choices[13] = "Deep"; + choices[14] = "Light"; + choices[15] = "Autumn Leaves"; + choices[16] = "Sepia"; + } +}; +SACreativeStyle saCreativeStyle; + +class SACreativeStyle2: public ChoiceInterpreter { + public: + SACreativeStyle2 () { + choices[1] = "Standard"; + choices[2] = "Vivid"; + choices[3] = "Portrait"; + choices[4] = "Landscape"; + choices[5] = "Sunset"; + choices[6] = "Night View/Portrait"; + choices[8] = "B&W"; + } +}; +SACreativeStyle2 saCreativeStyle2; + +class SACreativeStyleSetting: public ChoiceInterpreter { + public: + SACreativeStyleSetting () { + choices[16] = "Standard"; + choices[32] = "Vivid"; + choices[64] = "Portrait"; + choices[80] = "Landscape"; + choices[96] = "B&W"; + choices[160] = "Sunset"; + } +}; +SACreativeStyleSetting saCreativeStyleSetting; + +class SAFlashControl: public ChoiceInterpreter { + public: + SAFlashControl () { + choices[1] = "ADI Flash"; + choices[2] = "Pre-flash TTL"; + } +}; +SAFlashControl saFlashControl; + +class SAFlashMode: public ChoiceInterpreter { + public: + SAFlashMode () { + choices[0] = "ADI"; + choices[1] = "TTL"; + } +}; +SAFlashMode saFlashMode; + +class SAFlashMode2: public ChoiceInterpreter { + public: + SAFlashMode2 () { + choices[1] = "Flash Off"; + choices[16] = "Autoflash"; + choices[17] = "Fill-flash"; + choices[18] = "Slow Sync"; + choices[19] = "Rear Sync"; + choices[20] = "Wireless"; + } +}; +SAFlashMode2 saFlashMode2; + +class SAExposureProgram: public ChoiceInterpreter { + public: + SAExposureProgram () { + choices[0] = "Auto"; + choices[1] = "Manual"; + choices[2] = "Program AE"; + choices[3] = "Aperture-priority AE"; + choices[4] = "Shutter speed priority AE"; + choices[8] = "Program Shift A"; + choices[9] = "Program Shift S"; + choices[16] = "Portrait"; + choices[17] = "Sports"; + choices[18] = "Sunset"; + choices[19] = "Night Portrait"; + choices[20] = "Landscape"; + choices[21] = "Macro"; + choices[35] = "Auto No Flash"; + } +}; +SAExposureProgram saExposureProgram; + +class SAExposureProgram2: public ChoiceInterpreter { + public: + SAExposureProgram2 () { + choices[1] = "Program AE"; + choices[2] = "Aperture-priority AE"; + choices[3] = "Shutter speed priority AE"; + choices[4] = "Manual"; + choices[5] = "Cont. Priority AE"; + choices[16] = "Auto"; + choices[17] = "Auto (no flash)"; + choices[18] = "Auto+"; + choices[49] = "Portrait"; + choices[50] = "Landscape"; + choices[51] = "Macro"; + choices[52] = "Sports"; + choices[53] = "Sunset"; + choices[54] = "Night view"; + choices[55] = "Night view/portrait"; + choices[56] = "Handheld Night Shot"; + choices[57] = "3D Sweep Panorama"; + choices[64] = "Auto 2"; + choices[65] = "Auto 2 (no flash)"; + choices[80] = "Sweep Panorama"; + choices[96] = "Anti Motion Blur"; + choices[128] = "Toy Camera"; + choices[129] = "Pop Color"; + choices[130] = "Posterization"; + choices[131] = "Posterization B/W"; + choices[132] = "Retro Photo"; + choices[133] = "High-key"; + choices[134] = "Partial Color Red"; + choices[135] = "Partial Color Green"; + choices[136] = "Partial Color Blue"; + choices[137] = "Partial Color Yellow"; + choices[138] = "High Contrast Monochrome"; + } +}; +SAExposureProgram2 saExposureProgram2; + +class SARotation: public ChoiceInterpreter { + public: + SARotation () { + choices[0] = "Horizontal"; + choices[1] = "Rotate 90 CW"; + choices[2] = "Rotate 270 CW"; + choices[3] = "None"; + } +}; +SARotation saRotation; + +class SASonyImageSize: public ChoiceInterpreter { + public: + SASonyImageSize () { + choices[1] = "Large"; + choices[2] = "Medium"; + choices[3] = "Small"; + } +}; +SASonyImageSize saSonyImageSize; + +class SASonyImageSize3: public ChoiceInterpreter { + public: + SASonyImageSize3 () { + choices[21] = "Large (3:2)"; + choices[22] = "Medium (3:2)"; + choices[23] = "Small (3:2)"; + choices[25] = "Large (16:9)"; + choices[26] = "Medium (16:9) "; + choices[27] = "Small (16:9)"; + } +}; +SASonyImageSize3 saSonyImageSize3; + +class SAAspectRatio: public ChoiceInterpreter { + public: + SAAspectRatio () { + choices[1] = "3:2"; + choices[2] = "16:9"; + } +}; +SAAspectRatio saAspectRatio; + +class SAAspectRatio2: public ChoiceInterpreter { + public: + SAAspectRatio2 () { + choices[4] = "3:2"; + choices[8] = "16:9"; + } +}; +SAAspectRatio2 saAspectRatio2; + +class SAExposureLevelIncrements: public ChoiceInterpreter { + public: + SAExposureLevelIncrements () { + choices[33] = "1/3 EV"; + choices[50] = "1/2 EV"; + } +}; +SAExposureLevelIncrements saExposureLevelIncrements; + +class SAAFIlluminator: public ChoiceInterpreter { + public: + SAAFIlluminator () { + choices[0] = "Off"; + choices[1] = "Auto"; + choices[65535]="n/a"; + } +}; +SAAFIlluminator saAFIlluminator; + +class SAColorSpace1_2: public ChoiceInterpreter { + public: + SAColorSpace1_2 () { + choices[1] = "sRGB"; + choices[2] = "AdobeRGB"; + } +}; +SAColorSpace1_2 saColorSpace1_2; + +class SAColorSpace0_5: public ChoiceInterpreter { + public: + SAColorSpace0_5 () { + choices[0] = "sRGB"; + choices[1] = "AdobeRGB"; + choices[5] = "AdobeRGB"; + } +}; +SAColorSpace0_5 saColorSpace0_5; + +class SAColorSpace5_6: public ChoiceInterpreter { + public: + SAColorSpace5_6 () { + choices[5] = "AdobeRGB"; + choices[6] = "sRGB"; + } +}; +SAColorSpace5_6 saColorSpace5_6; + +class SAReleaseModeInterpreter: public ChoiceInterpreter { + public: + SAReleaseModeInterpreter () { + choices[0] = "Normal"; + choices[2] = "Burst"; + choices[5] = "Exposure Bracketing"; + choices[6] = "White Balance Bracketing"; + choices[65535]="n/a"; + } +}; +SAReleaseModeInterpreter saReleaseModeInterpreter; + +class SAImageStyleInterpreter: public ChoiceInterpreter { + public: + SAImageStyleInterpreter () { + choices[1] = "Standard"; + choices[2] = "Vivid"; + choices[9] = "Adobe RGB"; + choices[11] = "Neutral"; + choices[129]="StyleBox1"; + choices[130]="StyleBox2"; + choices[131]="StyleBox3"; + } +}; +SAImageStyleInterpreter saImageStyleInterpreter; + +class SAPictureEffectInterpreter: public ChoiceInterpreter { + public: + SAPictureEffectInterpreter(){ + choices[0] = "Off"; + choices[1] = "Toy Camera"; + choices[2] = "Pop Color"; + choices[3] = "Posterization"; + choices[4] = "Posterization B/W"; + choices[5] = "Retro Photo"; + choices[6] = "Soft High Key"; + choices[7] = "Partial Color Red"; + choices[8] = "Partial Color Green"; + choices[9] = "Partial Color Blue"; + choices[10] = "Partial Color Yellow"; + choices[13] = "High Contrast Monochrome"; + choices[16] = "Toy Camera 2"; + choices[33] = "Soft Focus"; + choices[48] = "Miniature"; + choices[50] = "Miniature 2"; + choices[51] = "Miniature 3"; + choices[65] = "HDR Painting"; + choices[80] = "Rich-tone Monochrome"; + choices[98] = "Water Color"; + choices[114] = "Illustration"; + } +}; +SAPictureEffectInterpreter saPictureEffectInterpreter; + +class SACameraInfoFocusStatusInterpreter : public ChoiceInterpreter { + public: + SACameraInfoFocusStatusInterpreter() { + choices[0] = "Manual - Not confirmed (0)"; + choices[4] = "Manual - Not confirmed (4)"; + choices[16] = "AF-C - Confirmed"; + choices[24] = "AF-C - Not Confirmed"; + choices[64] = "AF-S - Confirmed"; + } +}; +SACameraInfoFocusStatusInterpreter saCameraInfoFocusStatusInterpreter; + +class SAExposureTimeInterpreter : public Interpreter { + public: + SAExposureTimeInterpreter () {} + virtual std::string toString (Tag* t){ + double a = t->toDouble(); + if(a>0){ + char buffer[10]; + sprintf (buffer, "%.4f", a); + return buffer; + }else + return "n/a"; + } + virtual double toDouble (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(); + int a; + if (astype==BYTE) + a = t->getValue()[ofs]; + else if (astype==SHORT) + a = (int)sget2 (t->getValue()+ofs, t->getOrder()); + + // Decode the value + if(a>0.) + return pow(2., 6.-(double(a)/8.)); + else + return 0.; + } + virtual int toInt (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; + if (astype==INVALID || astype==AUTO) + astype = t->getType(); + if (astype==BYTE) + a = t->getValue()[ofs]; + else if (astype==SHORT) + a = (int)sget2 (t->getValue()+ofs, t->getOrder()); + + // Decode the value + if(a) + return int(powf(2.f, 6.f-(float(a)/8.f))+0.5f); + else + return 0; + } +}; +SAExposureTimeInterpreter saExposureTimeInterpreter; + +class SAFNumberInterpreter : public Interpreter { + public: + SAFNumberInterpreter () {} + virtual std::string toString (Tag* t){ + double a = double(t->toDouble()); + if(a){ + char buffer[10]; + sprintf (buffer, "%.1f", a/100. ); + return buffer; + }else + return "n/a"; + } + virtual double toDouble (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(); + int a; + if (astype==BYTE) + a = t->getValue()[ofs]; + else if (astype==SHORT) + a = (int)sget2 (t->getValue()+ofs, t->getOrder()); + + // Decode the value + if(a>0.) + return pow(2., (double(a)/8. - 1.) / 2.); + else + return 0.; + } + virtual int toInt (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; + if (astype==INVALID || astype==AUTO) + astype = t->getType(); + if (astype==BYTE) + a = t->getValue()[ofs]; + else if (astype==SHORT) + a = (int)sget2 (t->getValue()+ofs, t->getOrder()); + + // Decode the value + if(a) + return int(powf(2.f, (float(a)/8.f - 1.f) / 2.f)+0.5f); + else + return 0; + } +}; +SAFNumberInterpreter saFNumberInterpreter; + +class SAISOSettingInterpreter : public Interpreter { + public: + SAISOSettingInterpreter () {} + virtual std::string toString (Tag* t){ + int a = t->toInt(); + if(a){ + char buffer[10]; + sprintf (buffer, "%d", a ); + return buffer; + }else + return "Auto"; + } + virtual int toInt (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; + if (astype==INVALID || astype==AUTO) + astype = t->getType(); + if (astype==BYTE) + a = t->getValue()[ofs]; + else if (astype==SHORT) + a = (int)sget2 (t->getValue()+ofs, t->getOrder()); + + // Decode the value + if(a && a!=254) // 254 = 'Auto' for CameraSettings3, but we might say the same for CameraSettings & CameraSettings2 (?) + return int(expf((double(a)/8.f-6.f)*logf(2.f))*100.f +0.5f); + else + return 0; + } +}; +SAISOSettingInterpreter saISOSettingInterpreter; + +class SAExposureCompSetInterpreter : public Interpreter { + public: + SAExposureCompSetInterpreter () {} + virtual std::string toString (Tag* t){ + double a = t->toDouble(); + char buffer[10]; + sprintf (buffer, "%.2f", a ); + return buffer; + } + virtual double toDouble (Tag* t, int ofs){ + // Get the value + int a = t->getValue()[ofs]; + // Decode the value + return (double(a) - 128.) / 24.; + } +}; +SAExposureCompSetInterpreter saExposureCompSetInterpreter; + +class SAAFMicroAdjValueInterpreter : public Interpreter { + public: + SAAFMicroAdjValueInterpreter() {} + virtual std::string toString (Tag* t){ + char buffer[10]; + sprintf (buffer, "%d", t->getValue()[0] - 20); + return buffer; + } + virtual int toInt (Tag* t, int ofs, TagType astype){ + return t->getValue()[0] - 20; + } +}; +SAAFMicroAdjValueInterpreter saAFMicroAdjValueInterpreter; + +class SAAFMicroAdjModeInterpreter : public Interpreter { + public: + SAAFMicroAdjModeInterpreter() {} + virtual std::string toString (Tag* t){ + int a = t->getValue()[0] & 0x80; + if (a==0x80) + return "On"; + return "Off"; + } + virtual int toInt (Tag* t, int ofs, TagType astype){ + return (t->getValue()[0] & 0x80) == 0x80 ? 1 : 0; + } +}; + +SAAFMicroAdjModeInterpreter saAFMicroAdjModeInterpreter; + +class SAAFMicroAdjRegisteredLensesInterpreter : public Interpreter { + public: + SAAFMicroAdjRegisteredLensesInterpreter() {} + virtual std::string toString (Tag* t){ + char buffer[10]; + sprintf (buffer, "%d", t->getValue()[0] & 0x7f); + return buffer; + } + virtual int toInt (Tag* t, int ofs, TagType astype){ + return t->getValue()[0] & 0x7f; + } +}; +SAAFMicroAdjRegisteredLensesInterpreter saAFMicroAdjRegisteredLensesInterpreter; + +class SAFocusStatusInterpreter : public Interpreter { + public: + SAFocusStatusInterpreter () {} + virtual std::string toString (Tag* t){ + std::string retval; + int a = t->toInt(); + if (a == 0) + retval = "Not confirmed"; + else if (a == 4) + retval = "Not confirmed, Tracking"; + else { + if (a & 1) + retval = "Confirmed"; + if (a & 2) { + if (!retval.empty()) + retval += ", "; + retval += "Failed"; + } + if (a & 4) + if (!retval.empty()) + retval += ", "; + retval += "Tracking"; + } + return retval; + } +}; +SAFocusStatusInterpreter saFocusStatusInterpreter; + +class SAColorTemperatureSettingInterpreter : public Interpreter { + public: + SAColorTemperatureSettingInterpreter () {} + virtual std::string toString (Tag* t){ + char buffer[10]; + sprintf (buffer, "%d", t->toInt()); + return buffer; + } + virtual int toInt (Tag* t, int ofs, TagType astype){ + int a; + if (astype==INVALID || astype==AUTO) + astype = t->getType(); + if (astype==BYTE) + a = t->getValue()[ofs]; + else if (astype==SHORT) + a = (int)sget2 (t->getValue()+ofs, t->getOrder()); + return a * 100; + } +}; +SAColorTemperatureSettingInterpreter saColorTemperatureSettingInterpreter; + +const TagAttrib minoltaAttribs[] = { + {0, AC_WRITE, 0, 0, 0x0000, AUTO, "MakerNoteVersion", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0001, AUTO, "MinoltaCameraSettingsOld", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0003, AUTO, "MinoltaCameraSettings", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0004, AUTO, "MinoltaCameraSettings7D", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0018, AUTO, "ImageStabilization", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0040, AUTO, "CompressedImageSize", &stdInterpreter}, + {1, AC_WRITE, 0, 0, 0x0081, AUTO, "PreviewImage", &stdInterpreter}, + {1, AC_WRITE, 0, 0, 0x0088, AUTO, "PreviewImageStart", &stdInterpreter}, + {1, AC_WRITE, 0, 0, 0x0089, AUTO, "PreviewImageLength", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0100, AUTO, "SceneMode", &saSceneModeInterpreter}, + {0, AC_WRITE, 0, 0, 0x0101, AUTO, "ColorMode", &saColorModeInterpreter}, + {0, AC_WRITE, 0, 0, 0x0102, AUTO, "MinoltaQuality", &maQualityInterpreter}, + {0, AC_WRITE, 0, 0, 0x0103, AUTO, "MinoltaImageSize", &maImageSizeInterpreter}, + {0, AC_WRITE, 0, 0, 0x0104, AUTO, "FlashExposureComp", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0105, AUTO, "Teleconverter", &maTeleconverterInterpreter}, + {0, AC_WRITE, 0, 0, 0x0107, AUTO, "ImageStabilization", &saOnOffInterpreter}, + {0, AC_WRITE, 0, 0, 0x010a, AUTO, "ZoneMatching", &saZoneMatchingInterpreter}, + {0, AC_WRITE, 0, 0, 0x010b, AUTO, "ColorTemperature", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x010c, AUTO, "LensID", &saLensIDInterpreter}, + {0, AC_WRITE, 0, 0, 0x0113, AUTO, "ImageStabilization", &saOnOffInterpreter}, + {0, AC_WRITE, 0, 0, 0x0114, AUTO, "MinoltaCameraSettings", &stdInterpreter}, + {1, AC_WRITE, 0, 0, 0x0e00, AUTO, "PrintIM", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0f00, AUTO, "MinoltaCameraSettings2", &stdInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}}; + +const TagAttrib sonyAttribs[] = { + {0, AC_WRITE, 0, sonyCameraInfoAttribs, 0x0010, AUTO, "CameraInfo", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0102, AUTO, "Quality", &maQualityInterpreter}, + {0, AC_WRITE, 0, 0, 0x0104, AUTO, "FlashExposureComp",&stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0106, AUTO, "TeleConverter", &maTeleconverterInterpreter}, + {0, AC_WRITE, 0, sonyCameraSettingsAttribs, 0x0114, AUTO, "SonyCameraSettings",&stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0115, AUTO, "WhiteBalance",&saWhiteBalanceInterpreter}, + {1, AC_WRITE, 0, 0, 0x0e00, AUTO, "PrintIM", &stdInterpreter}, + {1, AC_WRITE, 0, 0, 0x2001, AUTO, "PreviewImage", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x2009, AUTO, "HighISONoiseReduction", &saHighISONoiseReduction}, + {0, AC_WRITE, 0, 0, 0x200a, AUTO, "AutoHDR", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x200b, AUTO, "MultiFrameNoiseReduction", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x200e, AUTO, "PictureEffect", &saPictureEffectInterpreter}, + {0, AC_WRITE, 0, 0, 0x2011, AUTO, "VignettingCorrection", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x2012, AUTO, "LateralChromaticAberration", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x2013, AUTO, "DistortionCorrection", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xb020, AUTO, "ColorReproduction", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xb021, AUTO, "ColorTemperature", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xb022, AUTO, "ColorCompensationFilter", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xb023, AUTO, "SceneMode", &saSceneModeInterpreter}, + {0, AC_WRITE, 0, 0, 0xb024, AUTO, "ZoneMatching", &saZoneMatchingInterpreter}, + {0, AC_WRITE, 0, 0, 0xb025, AUTO, "DynamicRangeOptimizer", &saDynamicRangeOptimizerInterpreter}, + {0, AC_WRITE, 0, 0, 0xb026, AUTO, "ImageStabilization", &saOnOffInterpreter}, + {0, AC_WRITE, 0, 0, 0xb027, AUTO, "LensID", &saLensIDInterpreter}, + {0, AC_WRITE, 0, minoltaAttribs, 0xb028, AUTO, "MinoltaMakerNote", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xb029, AUTO, "ColorMode", &saColorModeInterpreter}, + {0, AC_WRITE, 0, 0, 0xb040, AUTO, "Macro", &saOnOffInterpreter}, + {0, AC_WRITE, 0, 0, 0xb041, AUTO, "ExposureMode", &saExposureModeInterpreter}, + {0, AC_WRITE, 0, 0, 0xb042, AUTO, "FocusMode", &saFocusMode}, + {0, AC_WRITE, 0, 0, 0xb043, AUTO, "AFMode", &saAFMode}, + {0, AC_WRITE, 0, 0, 0xb044, AUTO, "AFIlluminator", &saAFIlluminator}, + {0, AC_WRITE, 0, 0, 0xb047, AUTO, "Quality", &saQualityInterpreter}, + {0, AC_WRITE, 0, 0, 0xb048, AUTO, "FlashLevel", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xb049, AUTO, "ReleaseMode",&saReleaseModeInterpreter}, + {0, AC_WRITE, 0, 0, 0xb04a, AUTO, "SequenceNumber", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xb04b, AUTO, "AntiBlur", &saAntiBlurInterpreter}, + {0, AC_WRITE, 0, 0, 0xb04e, AUTO, "LongExposureNoiseReduction", &saOnOffInterpreter}, + {0, AC_WRITE, 0, 0, 0xb04f, AUTO, "DynamicRangeOptimizer", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xb050, AUTO, "HighISONoiseReduction2", &saHighISONoiseReduction2}, + {0, AC_WRITE, 0, 0, 0xb052, AUTO, "IntelligentAuto", &stdInterpreter}, + {0, AC_WRITE, 0, sonyTag9405Attribs, 0x9405, AUTO, "Tag9405", &stdInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}}; + +const TagAttrib sonyTag9405Attribs[] = { + {0, AC_WRITE, 0, 0, 0x005d, AUTO, "LensFormat", &stdInterpreter}, // 9405b start here + {0, AC_WRITE, 0, 0, 0x005e, AUTO, "LensMount", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0060, SHORT, "LensType2", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0062, SHORT, "LensType", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0603, AUTO, "LensFormat", &stdInterpreter}, // 9405a start here + {0, AC_WRITE, 0, 0, 0x0604, AUTO, "LensMount", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0605, SHORT, "LensType2", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0608, SHORT, "LensType", &stdInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}}; + +const TagAttrib sonyCameraInfoAttribs[] = { + {0, AC_WRITE, 0, 0, 14, SHORT, "FocalLength", &saExposureTimeInterpreter}, + {0, AC_WRITE, 0, 0, 16, SHORT, "FocalLengthTeleZoom", &saExposureTimeInterpreter}, + {0, AC_WRITE, 0, 0, 25, AUTO, "FocusStatus", &saCameraInfoFocusStatusInterpreter}, + {0, AC_WRITE, 0, 0, 28, AUTO, "AFPointSelected", &saCameraInfoAFPointSelected}, + {0, AC_WRITE, 0, 0, 29, AUTO, "FocusMode", &saFocusMode2}, + {0, AC_WRITE, 0, 0, 32, AUTO, "AFPoint", &saCameraInfoAFPoint}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}}; + +const TagAttrib sonyCameraInfo2Attribs[] = { + {0, AC_WRITE, 0, 0, 304, AUTO, "AFMicroAdjValue", &saAFMicroAdjValueInterpreter}, + {0, AC_WRITE, 0, 0, 305, AUTO, "AFMicroAdjMode", &saAFMicroAdjModeInterpreter}, + {0, AC_WRITE, 0, 0, 305, AUTO, "AFMicroAdjRegisteredLenses", &saAFMicroAdjRegisteredLensesInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}}; + +const TagAttrib sonyCameraSettingsAttribs[]={ + {0, AC_WRITE, 0, 0, 0, AUTO, "ExposureTime", &saExposureTimeInterpreter}, + {0, AC_WRITE, 0, 0, 1, AUTO, "FNumber", &saFNumberInterpreter}, + {0, AC_WRITE, 0, 0, 4, AUTO, "DriveMode", &saDriveMode}, + {0, AC_WRITE, 0, 0, 6, AUTO, "WhiteBalanceFineTune",&stdInterpreter}, + {0, AC_WRITE, 0, 0, 16, AUTO, "FocusModeSetting",&saFocusMode}, + {0, AC_WRITE, 0, 0, 17, AUTO, "AFAreaMode",&saAFAreaMode}, + {0, AC_WRITE, 0, 0, 18, AUTO, "AFPointSelected", &saAFPointSelected}, + {0, AC_WRITE, 0, 0, 21, AUTO, "MeteringMode",&saMeteringMode1_4}, + {0, AC_WRITE, 0, 0, 22, AUTO, "ISOSetting",&saISOSettingInterpreter}, + {0, AC_WRITE, 0, 0, 24, AUTO, "DynamicRangeOptimizerMode", &saDynamicRangeOptimizerMode}, + {0, AC_WRITE, 0, 0, 25, AUTO, "DynamicRangeOptimizerLevel",&stdInterpreter}, + {0, AC_WRITE, 0, 0, 26, AUTO, "CreativeStyle",&saCreativeStyle}, + {0, AC_WRITE, 0, 0, 28, AUTO, "Sharpness",&stdInterpreter}, + {0, AC_WRITE, 0, 0, 29, AUTO, "Contrast",&stdInterpreter}, + {0, AC_WRITE, 0, 0, 30, AUTO, "Saturation",&stdInterpreter}, + {0, AC_WRITE, 0, 0, 31, AUTO, "ZoneMatchingValue",&stdInterpreter}, + {0, AC_WRITE, 0, 0, 34, AUTO, "Brightness",&stdInterpreter}, + {0, AC_WRITE, 0, 0, 35, AUTO, "FlashMode",&saFlashMode}, + {0, AC_WRITE, 0, 0, 40, AUTO, "PrioritySetupShutterRelease",&stdInterpreter}, + {0, AC_WRITE, 0, 0, 41, AUTO, "AFIlluminator",&saAFIlluminator}, + {0, AC_WRITE, 0, 0, 42, AUTO, "AFWithShutter",&saOnOffInterpreter}, + {0, AC_WRITE, 0, 0, 43, AUTO, "LongExposureNoiseReduction",&saOnOffInterpreter}, + {0, AC_WRITE, 0, 0, 44, AUTO, "HighISONoiseReduction",&saHighISONoiseReduction3}, + {0, AC_WRITE, 0, 0, 45, AUTO, "ImageStyle",&saImageStyleInterpreter}, + {0, AC_WRITE, 0, 0, 60, AUTO, "ExposureProgram",&saExposureProgram}, + {0, AC_WRITE, 0, 0, 61, AUTO, "ImageStabilization",&saOnOffInterpreter}, + {0, AC_WRITE, 0, 0, 63, AUTO, "Rotation",&saRotation}, + {0, AC_WRITE, 0, 0, 77, AUTO, "FocusMode",&saFocusMode}, + {0, AC_WRITE, 0, 0, 83, AUTO, "FocusStatus",&saFocusStatusInterpreter}, + {0, AC_WRITE, 0, 0, 84, AUTO, "SonyImageSize",&saSonyImageSize}, + {0, AC_WRITE, 0, 0, 85, AUTO, "AspectRatio",&saAspectRatio}, + {0, AC_WRITE, 0, 0, 86, AUTO, "Quality",&saQualityInterpreter2}, + {0, AC_WRITE, 0, 0, 88, AUTO, "ExposureLevelIncrements",&saExposureLevelIncrements}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}}; + +const TagAttrib sonyCameraSettingsAttribs2[]={ + {0, AC_WRITE, 0, 0, 0, AUTO, "ExposureTime", &saExposureTimeInterpreter}, + {0, AC_WRITE, 0, 0, 1, AUTO, "FNumber", &saFNumberInterpreter}, + {0, AC_WRITE, 0, 0, 11, AUTO, "ColorTemperatureSetting", &saColorTemperatureSettingInterpreter}, + {0, AC_WRITE, 0, 0, 15, AUTO, "FocusMode",&saFocusMode2}, + {0, AC_WRITE, 0, 0, 16, AUTO, "AFAreaMode",&saAFAreaMode}, + {0, AC_WRITE, 0, 0, 17, AUTO, "AFPointSelected",&saAFPointSelected2}, + {0, AC_WRITE, 0, 0, 19, AUTO, "MeteringMode",&saMeteringMode1_4}, + {0, AC_WRITE, 0, 0, 20, AUTO, "ISOSetting",&saISOSettingInterpreter}, + {0, AC_WRITE, 0, 0, 22, AUTO, "DynamicRangeOptimizerMode",&saDynamicRangeOptimizerMode}, + {0, AC_WRITE, 0, 0, 23, AUTO, "DynamicRangeOptimizerLevel",&stdInterpreter}, + {0, AC_WRITE, 0, 0, 24, AUTO, "CreativeStyle",&saCreativeStyle2}, + {0, AC_WRITE, 0, 0, 25, AUTO, "Sharpness",&stdInterpreter}, + {0, AC_WRITE, 0, 0, 26, AUTO, "Contrast",&stdInterpreter}, + {0, AC_WRITE, 0, 0, 27, AUTO, "Saturation",&stdInterpreter}, + {0, AC_WRITE, 0, 0, 35, AUTO, "FlashMode",&saFlashMode}, + {0, AC_WRITE, 0, 0, 38, AUTO, "HighISONoiseReduction",&saHighISONoiseReduction4}, + {0, AC_WRITE, 0, 0, 60, AUTO, "ExposureProgram",&saExposureProgram}, + {0, AC_WRITE, 0, 0, 63, AUTO, "Rotation",&saRotation}, + {0, AC_WRITE, 0, 0, 83, AUTO, "FocusStatus",&saFocusStatusInterpreter}, + {0, AC_WRITE, 0, 0, 84, AUTO, "SonyImageSize",&saSonyImageSize}, + {0, AC_WRITE, 0, 0, 85, AUTO, "AspectRatio",&saAspectRatio}, + {0, AC_WRITE, 0, 0, 86, AUTO, "Quality",&saQualityInterpreter2}, + {0, AC_WRITE, 0, 0, 88, AUTO, "ExposureLevelIncrements",&saExposureLevelIncrements}, + {0, AC_WRITE, 0, 0,126, AUTO, "DriveMode", &saDriveMode2}, + {0, AC_WRITE, 0, 0,131, AUTO, "ColorSpace", &saColorSpace5_6}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}}; + +const TagAttrib sonyCameraSettingsAttribs3[]={ + {0, AC_WRITE, 0, 0, 0, AUTO, "ShutterSpeedSetting",&saExposureTimeInterpreter}, + {0, AC_WRITE, 0, 0, 1, AUTO, "ApertureSetting",&saFNumberInterpreter}, + {0, AC_WRITE, 0, 0, 2, AUTO, "ISOSetting",&saISOSettingInterpreter}, + {0, AC_WRITE, 0, 0, 3, AUTO, "ExposureCompensationSet",&saExposureCompSetInterpreter}, + {0, AC_WRITE, 0, 0, 3, AUTO, "DriveModeSetting",&saDriveMode3}, + {0, AC_WRITE, 0, 0, 5, AUTO, "ExposureProgram",&saExposureProgram2}, + {0, AC_WRITE, 0, 0, 6, AUTO, "FocusModeSetting",&saFocusModeSetting3}, + {0, AC_WRITE, 0, 0, 7, AUTO, "MeteringMode",&saMeteringMode1_3}, + {0, AC_WRITE, 0, 0, 9, AUTO, "SonyImageSize",&saSonyImageSize3}, + {0, AC_WRITE, 0, 0, 10, AUTO, "AspectRatio",&saAspectRatio2}, + {0, AC_WRITE, 0, 0, 11, AUTO, "Quality",&saQualityInterpreter3}, + {0, AC_WRITE, 0, 0, 12, AUTO, "DynamicRangeOptimizerSetting", &saDynamicRangeOptimizerSetting}, + {0, AC_WRITE, 0, 0, 14, AUTO, "ColorSpace", &saColorSpace1_2}, + {0, AC_WRITE, 0, 0, 15, AUTO, "CreativeStyleSetting",&saCreativeStyleSetting}, + {0, AC_WRITE, 0, 0, 16, AUTO, "Contrast",&stdInterpreter}, + {0, AC_WRITE, 0, 0, 17, AUTO, "Saturation",&stdInterpreter}, + {0, AC_WRITE, 0, 0, 18, AUTO, "Sharpness",&stdInterpreter}, + {0, AC_WRITE, 0, 0, 22, AUTO, "WhiteBalance",&saWhiteBalanceSettingInterpreter}, + {0, AC_WRITE, 0, 0, 23, AUTO, "ColorTemperatureSetting", &saColorTemperatureSettingInterpreter}, + {0, AC_WRITE, 0, 0, 23, AUTO, "ColorCompensationFilterSet", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 32, AUTO, "FlashMode",&saFlashMode2}, + {0, AC_WRITE, 0, 0, 33, AUTO, "FlashControl",&saFlashControl}, + {0, AC_WRITE, 0, 0, 35, AUTO, "FlashExposureCompSet", &saExposureCompSetInterpreter}, + {0, AC_WRITE, 0, 0, 36, AUTO, "AFAreaMode",&saAFAreaMode2}, + {0, AC_WRITE, 0, 0, 37, AUTO, "LongExposureNoiseReduction",&saOnOffInterpreter2}, + {0, AC_WRITE, 0, 0, 38, AUTO, "HighISONoiseReduction",&saHighISONoiseReduction5}, + {0, AC_WRITE, 0, 0, 39, AUTO, "SmileShutterMode",&saSmileShutterMode}, + {0, AC_WRITE, 0, 0, 40, AUTO, "RedEyeReduction",&saOnOffInterpreter2}, + {0, AC_WRITE, 0, 0, 45, AUTO, "HDRSetting",&saOnOffInterpreter3}, + {0, AC_WRITE, 0, 0, 46, AUTO, "HDRLevel",&saHDRLevel}, + {0, AC_WRITE, 0, 0, 47, AUTO, "ViewingMode",&saViewingMode}, + {0, AC_WRITE, 0, 0, 48, AUTO, "FaceDetection",&saOnOffInterpreter2}, + {0, AC_WRITE, 0, 0, 49, AUTO, "SmileShutter",&saOnOffInterpreter2}, + {0, AC_WRITE, 0, 0, 50, AUTO, "SweepPanoramaSize",&saSweepPanoramaSize}, + {0, AC_WRITE, 0, 0, 51, AUTO, "SweepPanoramaDirection",&saSweepPanoramaDirection}, + {0, AC_WRITE, 0, 0, 52, AUTO, "DriveMode",&saDriveMode3}, + {0, AC_WRITE, 0, 0, 53, AUTO, "MultiFrameNoiseReduction",&saOnOffInterpreter4}, + {0, AC_WRITE, 0, 0, 54, AUTO, "LiveViewAFSetting",&saLiveViewAFSetting}, + {0, AC_WRITE, 0, 0, 56, AUTO, "PanoramaSize3D",&saPanoramaSize3D}, + {0, AC_WRITE, 0, 0, 131, AUTO, "AFButtonPressed",&saNoYesInterpreter}, + {0, AC_WRITE, 0, 0, 132, AUTO, "LiveViewMetering",&saLiveViewMetering}, + {0, AC_WRITE, 0, 0, 133, AUTO, "ViewingMode2",&saViewingMode}, + {0, AC_WRITE, 0, 0, 134, AUTO, "AELock",&saOnOffInterpreter5}, + {0, AC_WRITE, 0, 0, 135, AUTO, "FlashAction",&saFlashAction}, + {0, AC_WRITE, 0, 0, 139, AUTO, "LiveViewFocusMode",&saLiveViewFocusMode}, + {0, AC_WRITE, 0, 0, 153, AUTO, "LensMount",&saLensMount}, + {0, AC_WRITE, 0, 0, 643, AUTO, "AFButtonPressed",&saNoYesInterpreter}, + {0, AC_WRITE, 0, 0, 644, AUTO, "LiveViewMetering",&saLiveViewMetering}, + {0, AC_WRITE, 0, 0, 645, AUTO, "ViewingMode2",&saViewingMode}, + {0, AC_WRITE, 0, 0, 646, AUTO, "AELock",&saOnOffInterpreter5}, + {0, AC_WRITE, 0, 0, 647, AUTO, "FlashAction",&saFlashAction}, + {0, AC_WRITE, 0, 0, 651, AUTO, "LiveViewFocusMode",&saLiveViewFocusMode}, + {0, AC_WRITE, 0, 0, 1015, SHORT, "LensType2",&saLensID2Interpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}}; + +/*const TagAttrib sonyDNGMakerNote[]={ + {0, AC_WRITE, 0, 0, 0x7200, AUTO, "SonyOffset", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x7201, AUTO, "SonyLength", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x7221, AUTO, "SonyKey", &stdInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}};*/ + +} +#endif + + diff --git a/rtexif/stdattribs.cc b/rtexif/stdattribs.cc new file mode 100644 index 000000000..0990d3a4c --- /dev/null +++ b/rtexif/stdattribs.cc @@ -0,0 +1,718 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * Copyright (c) 2010 Oliver Duis + * + * 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 _STDATTRIBS_ +#define _STDATTRIBS_ + +#include +#include + +#include "rtexif.h" + +namespace rtexif { + +class ColorSpaceInterpreter : public ChoiceInterpreter { + + public: + ColorSpaceInterpreter () { + choices[1] = "sRGB"; + choices[2] = "Adobe RGB"; + choices[0xffff] = "Uncalibrated"; + } +}; +ColorSpaceInterpreter colorSpaceInterpreter; + +class PreviewColorSpaceInterpreter : public ChoiceInterpreter { + + public: + PreviewColorSpaceInterpreter () { + choices[0] = "Unknown"; + choices[1] = "Gray Gamma 2.2"; + choices[2] = "sRGB"; + choices[3] = "Adobe RGB"; + choices[4] = "ProPhoto RGB"; + } +}; +PreviewColorSpaceInterpreter previewColorSpaceInterpreter; + +class LinearSRGBInterpreter : public ChoiceInterpreter { + + public: + LinearSRGBInterpreter () { + choices[0] = "Linear"; + choices[1] = "sRGB"; + } +}; +LinearSRGBInterpreter linearSRGBInterpreter; + +class DefaultBlackRenderInterpreter : public ChoiceInterpreter { + + public: + DefaultBlackRenderInterpreter () { + choices[0] = "Auto"; + choices[1] = "None"; + } +}; +DefaultBlackRenderInterpreter defaultBlackRenderInterpreter; + +class ExposureProgramInterpreter : public ChoiceInterpreter { + + public: + ExposureProgramInterpreter () { + choices[0] = "Not defined"; + choices[1] = "Manual"; + choices[2] = "Normal program"; + choices[3] = "Aperture priority"; + choices[4] = "Shutter priority"; + choices[5] = "Creative program"; + choices[6] = "Action program"; + choices[7] = "Portrait mode"; + choices[8] = "Landscape mode"; + } +}; +ExposureProgramInterpreter exposureProgramInterpreter; + +class MeteringModeInterpreter : public ChoiceInterpreter { + + public: + MeteringModeInterpreter () { + choices[0] = "Unknown"; + choices[1] = "Average"; + choices[2] = "Center weighted"; + choices[3] = "Spot"; + choices[4] = "Multispot"; + choices[5] = "Pattern"; + choices[6] = "Partial"; + choices[255] = "Other"; + } +}; +MeteringModeInterpreter meteringModeInterpreter; + +class ExposureModeInterpreter : public ChoiceInterpreter { + + public: + ExposureModeInterpreter () { + choices[0] = "Auto exposure"; + choices[1] = "Manual exposure"; + choices[2] = "Auto bracket"; + } +}; +ExposureModeInterpreter exposureModeInterpreter; + +class WhiteBalanceInterpreter : public ChoiceInterpreter { + + public: + WhiteBalanceInterpreter () { + choices[0] = "Auto white balance"; + choices[1] = "Manual white balance"; + } +}; +WhiteBalanceInterpreter whiteBalanceInterpreter; + +class SceneCaptureInterpreter : public ChoiceInterpreter { + + public: + SceneCaptureInterpreter () { + choices[0] = "Standard"; + choices[1] = "Landscape"; + choices[2] = "Portrait"; + choices[3] = "Night scene"; + } +}; +SceneCaptureInterpreter sceneCaptureInterpreter; + +class GainControlInterpreter : public ChoiceInterpreter { + + public: + GainControlInterpreter () { + choices[0] = "None"; + choices[1] = "Low gain up"; + choices[2] = "High gain up"; + choices[3] = "Low gain down"; + choices[4] = "High gain down"; + } +}; +GainControlInterpreter gainControlInterpreter; + +class ContrastInterpreter : public ChoiceInterpreter { + + public: + ContrastInterpreter () { + choices[0] = "Normal"; + choices[1] = "Soft"; + choices[2] = "Hard"; + } +}; +ContrastInterpreter contrastInterpreter; + +class SharpnessInterpreter : public ChoiceInterpreter { + + public: + SharpnessInterpreter () { + choices[0] = "Normal"; + choices[1] = "Soft"; + choices[2] = "Hard"; + } +}; +SharpnessInterpreter sharpnessInterpreter; + +class SaturationInterpreter : public ChoiceInterpreter { + + public: + SaturationInterpreter () { + choices[0] = "Normal"; + choices[1] = "Low saturation"; + choices[2] = "High saturation"; + } +}; +SaturationInterpreter saturationInterpreter; + +class FlashInterpreter : public ChoiceInterpreter { + + public: + FlashInterpreter () { + choices[0x0000] = "Flash did not fire"; + choices[0x0001] = "Flash fired"; + choices[0x0005] = "Strobe return light not detected"; + choices[0x0007] = "Strobe return light detected"; + choices[0x0009] = "Flash fired, compulsory flash mode"; + choices[0x000D] = "Flash fired, compulsory flash mode, return light not detected"; + choices[0x000F] = "Flash fired, compulsory flash mode, return light detected"; + choices[0x0010] = "Flash did not fire, compulsory flash mode"; + choices[0x0018] = "Flash did not fire, auto mode"; + choices[0x0019] = "Flash fired, auto mode"; + choices[0x001D] = "Flash fired, auto mode, return light not detected"; + choices[0x001F] = "Flash fired, auto mode, return light detected"; + choices[0x0020] = "No flash function"; + choices[0x0041] = "Flash fired, red-eye reduction mode"; + choices[0x0045] = "Flash fired, red-eye reduction mode, return light not detected"; + choices[0x0047] = "Flash fired, red-eye reduction mode, return light detected"; + choices[0x0049] = "Flash fired, compulsory flash mode, red-eye reduction mode"; + choices[0x004D] = "Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected"; + choices[0x004F] = "Flash fired, compulsory flash mode, red-eye reduction mode, return light detected"; + choices[0x0059] = "Flash fired, auto mode, red-eye reduction mode"; + choices[0x005D] = "Flash fired, auto mode, return light not detected, red-eye reduction mode"; + choices[0x005F] = "Flash fired, auto mode, return light detected, red-eye reduction mode"; + } +}; +FlashInterpreter flashInterpreter; + +class LightSourceInterpreter : public ChoiceInterpreter { + + public: + LightSourceInterpreter () { + choices[0] = "Unknown"; + choices[1] = "Daylight"; + choices[2] = "Fluorescent"; + choices[3] = "Tungsten"; + choices[4] = "Flash"; + choices[9] = "Fine weather"; + choices[10] = "Cloudy weather"; + choices[11] = "Shade"; + choices[12] = "Daylight fluorescent"; + choices[13] = "Day white fluorescent"; + choices[14] = "Cool white fluorescent"; + choices[15] = "White fluorescent"; + choices[17] = "Standard light A"; + choices[18] = "Standard light B"; + choices[19] = "Standard light C"; + choices[20] = "D55"; + choices[21] = "D65"; + choices[22] = "D75"; + choices[23] = "D50"; + choices[24] = "ISO studio tungsten"; + choices[255] = "Other light source"; + } +}; +LightSourceInterpreter lightSourceInterpreter; + +class CompressionInterpreter : public ChoiceInterpreter { + + public: + CompressionInterpreter () { + choices[1] = "Uncompressed"; + choices[6] = "JPEG Compression"; + } +}; +CompressionInterpreter compressionInterpreter; + +class PhotometricInterpreter : public ChoiceInterpreter { + + public: + PhotometricInterpreter () { + choices[2] = "RGB"; + choices[6] = "YCbCr"; + } +}; +PhotometricInterpreter photometricInterpreter; + +class ProfileEmbedPolicyInterpreter : public ChoiceInterpreter { + + public: + ProfileEmbedPolicyInterpreter () { + choices[0] = "Allow Copying"; + choices[1] = "Embed if Used"; + choices[2] = "Never Embed"; + choices[3] = "No Restrictions"; + } +}; +ProfileEmbedPolicyInterpreter profileEmbedPolicyInterpreter; + +class PlanarConfigInterpreter : public ChoiceInterpreter { + + public: + PlanarConfigInterpreter () { + choices[1] = "Chunky format"; + choices[2] = "Planar format"; + } +}; +PlanarConfigInterpreter planarConfigInterpreter; + +class FNumberInterpreter : public Interpreter { + public: + FNumberInterpreter () {} + virtual std::string toString (Tag* t) { + char buffer[32]; + double v = t->toDouble(); + if( v < 0. || v > 1000. ) return "undef"; + sprintf (buffer, "%0.1f", v); + return buffer; + } +}; +FNumberInterpreter fNumberInterpreter; + +class ApertureInterpreter : public Interpreter { + public: + ApertureInterpreter () {} + virtual std::string toString (Tag* t) { + char buffer[32]; + double v = pow(2.0, t->toDouble()/2.0); + if( v < 0. || v > 1000. ) return "undef"; + sprintf (buffer, "%.1f", v ); + return buffer; + } +}; +ApertureInterpreter apertureInterpreter; + +class ExposureBiasInterpreter : public Interpreter { + public: + ExposureBiasInterpreter () {} + virtual std::string toString (Tag* t) { + char buffer[32]; + double v = t->toDouble(); + if( v < -1000. || v > 1000. ) return "undef"; + sprintf (buffer, "%+0.2f", v ); + return buffer; + } +}; +ExposureBiasInterpreter exposureBiasInterpreter; + +class ShutterSpeedInterpreter : public Interpreter { + public: + ShutterSpeedInterpreter () {} + virtual std::string toString (Tag* t) { + char buffer[1024]; + double d = pow (2.0, -t->toDouble()); + if (d > 0.0 && d < 0.9) + sprintf (buffer, "1/%.0f", 1.0 / d); + else + sprintf (buffer, "%.1f", d); + return buffer; + } +}; +ShutterSpeedInterpreter shutterSpeedInterpreter; + +class ExposureTimeInterpreter : public Interpreter { + public: + ExposureTimeInterpreter () {} + virtual std::string toString (Tag* t) { + char buffer[1024]; + double d = t->toDouble(); + if (d > 0.0 && d < 0.9) + sprintf (buffer, "1/%.0f", 1.0 / d); + else + sprintf (buffer, "%.1f", d); + return buffer; + } +}; +ExposureTimeInterpreter exposureTimeInterpreter; + +class FocalLengthInterpreter : public Interpreter { + public: + FocalLengthInterpreter () {} + virtual std::string toString (Tag* t) { + char buffer[32]; + double v = t->toDouble(); + if( v>1000000. || v<0 ) return "undef"; + sprintf (buffer, "%.1f", v ); + return buffer; + } +}; +FocalLengthInterpreter focalLengthInterpreter; + +class UserCommentInterpreter : public Interpreter { + public: + UserCommentInterpreter () {} + virtual std::string toString (Tag* t) { + char *buffer = new char[t->getCount()]; + if (!strncmp((char*)t->getValue(), "ASCII\0\0\0",8)) { + strncpy (buffer, (char*)t->getValue()+8, t->getCount()-8); + buffer[t->getCount()-8] = '\0'; + } + else + buffer[0]=0; + std::string retVal(buffer); + delete [] buffer; + return retVal; + } + virtual void fromString (Tag* t, const std::string& value) { + char *buffer = new char[t->getCount()]; + memcpy (buffer, "ASCII\0\0\0", 8); + strcpy (buffer+8, value.c_str()); + t->fromString (buffer, value.size() + 9); + delete [] buffer; + } +}; +UserCommentInterpreter userCommentInterpreter; + +class CFAInterpreter : public Interpreter { +public: + CFAInterpreter(){} + virtual std::string toString (Tag* t) { + char colors[]="RGB"; + char buffer[1024]; + for( int i=0; i< t->getCount();i++){ + unsigned char c = t->toInt(i,BYTE); + buffer[i]= c<3 ?colors[c]:' '; + } + buffer[t->getCount()]=0; + return buffer; + } +}; +CFAInterpreter cfaInterpreter; + +class OrientationInterpreter : public ChoiceInterpreter { +public: + OrientationInterpreter (){ + choices[1] = "Horizontal (normal)"; + choices[2] = "Mirror horizontal "; + choices[3] = "Rotate 180"; + choices[4] = "Mirror vertical"; + choices[5] = "Mirror horizontal and rotate 270 CW"; + choices[6] = "Rotate 90 CW"; + choices[7] = "Mirror horizontal and rotate 90 CW"; + choices[8] = "Rotate 270 CW"; + // '9' is an "unofficial" value for Orientation but used by some older cameras that lacks orientation sensor, such as Kodak DCS + choices[9] = "Unknown"; + } +}; +OrientationInterpreter orientationInterpreter; + +class UnitsInterpreter : public ChoiceInterpreter { +public: + UnitsInterpreter(){ + choices[0] = "Unknown"; + choices[1] = "inches"; + choices[2] = "cm"; + } +}; +UnitsInterpreter unitsInterpreter; + +class UTF8BinInterpreter : public Interpreter { + public: + UTF8BinInterpreter () {} +}; +UTF8BinInterpreter utf8BinInterpreter; + +const TagAttrib exifAttribs[] = { + {0, AC_SYSTEM, 0, 0, 0x0100, AUTO, "ImageWidth", &stdInterpreter}, + {0, AC_SYSTEM, 0, 0, 0x0101, AUTO, "ImageHeight", &stdInterpreter}, + {0, AC_SYSTEM, 0, 0, 0x0102, AUTO, "BitsPerSample", &stdInterpreter}, + {0, AC_SYSTEM, 0, 0, 0x0103, AUTO, "Compression", &compressionInterpreter}, + {0, AC_WRITE, 0, 0, 0x828d, AUTO, "CFAPatternDim", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x828e, AUTO, "CFAPattern", &cfaInterpreter}, + {0, AC_WRITE, 0, 0, 0x829A, AUTO, "ExposureTime", &exposureTimeInterpreter}, + {0, AC_WRITE, 0, 0, 0x829D, AUTO, "FNumber", &fNumberInterpreter}, + {0, AC_WRITE, 0, 0, 0x8822, AUTO, "ExposureProgram", &exposureProgramInterpreter}, + {0, AC_WRITE, 0, 0, 0x8824, AUTO, "SpectralSensitivity", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x8827, AUTO, "ISOSpeedRatings", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x8828, AUTO, "OECF", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x9000, AUTO, "ExifVersion", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x9003, AUTO, "DateTimeOriginal", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x9004, AUTO, "DateTimeDigitized", &stdInterpreter}, + {0, AC_SYSTEM, 0, 0, 0x9101, AUTO, "ComponentsConfiguration", &stdInterpreter}, + {0, AC_SYSTEM, 0, 0, 0x9102, AUTO, "CompressedBitsPerPixel", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x9201, AUTO, "ShutterSpeedValue", &shutterSpeedInterpreter}, + {0, AC_WRITE, 0, 0, 0x9202, AUTO, "ApertureValue", &apertureInterpreter}, + {0, AC_WRITE, 0, 0, 0x9203, AUTO, "BrightnessValue", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x9204, AUTO, "ExposureBiasValue", &exposureBiasInterpreter}, + {0, AC_WRITE, 0, 0, 0x9205, AUTO, "MaxApertureValue", &apertureInterpreter}, + {0, AC_WRITE, 0, 0, 0x9206, AUTO, "SubjectDistance", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x9207, AUTO, "MeteringMode", &meteringModeInterpreter}, + {0, AC_WRITE, 0, 0, 0x9208, AUTO, "LightSource", &lightSourceInterpreter}, + {0, AC_WRITE, 0, 0, 0x9209, AUTO, "Flash", &flashInterpreter}, + {0, AC_WRITE, 0, 0, 0x920A, AUTO, "FocalLength", &focalLengthInterpreter}, + {0, AC_WRITE, 0, 0, 0x9214, AUTO, "SubjectArea", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x9215, AUTO, "ExposureIndex", &stdInterpreter}, // Note: exists as 0xA215 too, it should be that way + {0, AC_DONTWRITE, 0, 0, 0x9216, AUTO, "TIFFEPSStandardID", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x9217, AUTO, "SensingMethod", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x927C, AUTO, "MakerNote", &stdInterpreter}, + {0, AC_WRITE, 1, 0, 0x9286, AUTO, "UserComment", &userCommentInterpreter}, + {0, AC_WRITE, 0, 0, 0x9290, AUTO, "SubSecTime", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x9291, AUTO, "SubSecTimeOriginal", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x9292, AUTO, "SubSecTimeDigitized", &stdInterpreter}, + {0, AC_SYSTEM, 0, 0, 0xA000, AUTO, "FlashpixVersion", &stdInterpreter}, + {0, AC_DONTWRITE, 0, 0, 0xA001, AUTO, "ColorSpace", &colorSpaceInterpreter}, + {0, AC_SYSTEM, 0, 0, 0xA002, AUTO, "PixelXDimension", &stdInterpreter}, + {0, AC_SYSTEM, 0, 0, 0xA003, AUTO, "PixelYDimension", &stdInterpreter}, + {1, AC_DONTWRITE, 0, 0, 0xA004, AUTO, "RelatedSoundFile", &stdInterpreter}, + {0, AC_SYSTEM, 0, iopAttribs, 0xA005, AUTO, "Interoperability", &stdInterpreter}, // do not enable, as it causes trouble with FUJI files + {0, AC_WRITE, 0, 0, 0xA20B, AUTO, "FlashEnergy", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xA20C, AUTO, "SpatialFrequencyResponse", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xA20E, AUTO, "FocalPlaneXResolution", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xA20F, AUTO, "FocalPlaneYResolution", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xA210, AUTO, "FocalPlaneResolutionUnit", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xA214, AUTO, "SubjectLocation", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xA215, AUTO, "ExposureIndex", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xA217, AUTO, "SensingMethod", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xA300, AUTO, "FileSource", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xA301, AUTO, "SceneType", &stdInterpreter}, + {0, AC_DONTWRITE, 0, 0, 0xA302, AUTO, "CFAPattern", &cfaInterpreter}, + {0, AC_WRITE, 0, 0, 0xA401, AUTO, "CustomRendered", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xA402, AUTO, "ExposureMode", &exposureModeInterpreter}, + {0, AC_WRITE, 0, 0, 0xA403, AUTO, "WhiteBalance", &whiteBalanceInterpreter}, + {0, AC_WRITE, 0, 0, 0xA404, AUTO, "DigitalZoomRatio", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xA405, AUTO, "FocalLengthIn35mmFilm", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xA406, AUTO, "SceneCaptureType", &sceneCaptureInterpreter}, + {0, AC_WRITE, 0, 0, 0xA407, AUTO, "GainControl", &gainControlInterpreter}, + {0, AC_WRITE, 0, 0, 0xA408, AUTO, "Contrast", &contrastInterpreter}, + {0, AC_WRITE, 0, 0, 0xA409, AUTO, "Saturation", &saturationInterpreter}, + {0, AC_WRITE, 0, 0, 0xA40A, AUTO, "Sharpness", &sharpnessInterpreter}, + {0, AC_WRITE, 0, 0, 0xA40B, AUTO, "DeviceSettingDescription", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xA40C, AUTO, "SubjectDistanceRange", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xA420, AUTO, "ImageUniqueID", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xA431, AUTO, "SerialNumber", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xA432, AUTO, "LensInfo", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xA433, AUTO, "LensMake", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xA434, AUTO, "LensModel", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xA435, AUTO, "LensSerialNumber", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xA500, AUTO, "Gamma", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC618, AUTO, "LinearizationTable", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC619, AUTO, "BlackLevelRepeatDim", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC61A, AUTO, "BlackLevel", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC61B, AUTO, "BlackLevelDeltaH", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC61C, AUTO, "BlackLevelDeltaV", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC61D, AUTO, "WhiteLevel", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC61E, AUTO, "DefaultScale", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC61F, AUTO, "DefaultCropOrigin", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC620, AUTO, "DefaultCropSize", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC621, AUTO, "ColorMatrix1", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC622, AUTO, "ColorMatrix2", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC623, AUTO, "CameraCalibration1", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC624, AUTO, "CameraCalibration2", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC625, AUTO, "ReductionMatrix1", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC626, AUTO, "ReductionMatrix2", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC627, AUTO, "AnalogBalance", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC628, AUTO, "AsShotNeutral", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC629, AUTO, "AsShotWhiteXY", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC62A, AUTO, "BaselineExposure", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC62B, AUTO, "BaselineNoise", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC62C, AUTO, "BaselineSharpness", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC62D, AUTO, "BayerGreenSplit", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC62E, AUTO, "LinearResponseLimit", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC62F, AUTO, "CameraSerialNumber", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC630, AUTO, "DNGLensInfo", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC631, AUTO, "ChromaBlurRadius", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC632, AUTO, "AntiAliasStrength", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC633, AUTO, "ShadowScale", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC65A, AUTO, "CalibrationIlluminant1", &lightSourceInterpreter}, + {0, AC_WRITE, 0, 0, 0xC65B, AUTO, "CalibrationIlluminant2", &lightSourceInterpreter}, + {0, AC_WRITE, 0, 0, 0xC65C, AUTO, "BestQualityScale", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC65D, AUTO, "RawDataUniqueID", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC68B, AUTO, "OriginalRawFileName", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC68D, AUTO, "ActiveArea", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC68E, AUTO, "MaskedAreas", &stdInterpreter}, +// {0, AC_WRITE, 0, 0, 0xC68F, AUTO, "AsShotICCProfile", & ???}, + {0, AC_WRITE, 0, 0, 0xC690, AUTO, "AsShotPreProfileMatrix", &stdInterpreter}, +// {0, AC_WRITE, 0, 0, 0xC691, AUTO, "CurrentICCProfile", & ???}, + {0, AC_WRITE, 0, 0, 0xC692, AUTO, "CurrentPreProfileMatrix", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC6BF, AUTO, "ColorimetricReference", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC6F3, AUTO, "CameraCalibrationSig", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC6F4, AUTO, "ProfileCalibrationSig", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC6F5, AUTO, "ProfileIFD", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC6F6, AUTO, "AsShotProfileName", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC6F7, AUTO, "NoiseReductionApplied", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC6F8, AUTO, "ProfileName", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC6F9, AUTO, "ProfileHueSatMapDims", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC6FA, AUTO, "ProfileHueSatMapData1", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC6FB, AUTO, "ProfileHueSatMapData2", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC6FC, AUTO, "ProfileToneCurve", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC6FD, AUTO, "ProfileEmbedPolicy", &profileEmbedPolicyInterpreter}, + {0, AC_WRITE, 0, 0, 0xC6FE, AUTO, "ProfileCopyright", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC714, AUTO, "ForwardMatrix1", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC715, AUTO, "ForwardMatrix2", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC716, AUTO, "PreviewApplicationName", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC717, AUTO, "PreviewApplicationVersion", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC718, AUTO, "PreviewSettingsName", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC719, AUTO, "PreviewSettingsDigest", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC71A, AUTO, "PreviewColorSpace", &previewColorSpaceInterpreter}, + {0, AC_WRITE, 0, 0, 0xC71B, AUTO, "PreviewDateTime", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC71C, AUTO, "RawImageDigest", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC71D, AUTO, "OriginalRawFileDigest", &stdInterpreter}, +// {0, AC_WRITE, 0, 0, 0xC71E, AUTO, "SubTileBlockSize", & ???}, +// {0, AC_WRITE, 0, 0, 0xC71F, AUTO, "RowInterleaveFactor", & ???}, + {0, AC_WRITE, 0, 0, 0xC725, AUTO, "ProfileLookTableDims", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 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, 0, 0xC761, AUTO, "NoiseProfile", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC763, AUTO, "TimeCodes", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC764, AUTO, "FrameRate", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC772, AUTO, "TStop", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC789, AUTO, "ReelName", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC791, AUTO, "OriginalDefaultFinalSize", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC792, AUTO, "OriginalBestQualitySize", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC793, AUTO, "OriginalDefaultCropSize", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC7A1, AUTO, "CameraLabel", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC7A3, AUTO, "ProfileHueSatMapEncoding", &linearSRGBInterpreter}, + {0, AC_WRITE, 0, 0, 0xC7A4, AUTO, "ProfileLookTableEncoding", &linearSRGBInterpreter}, + {0, AC_WRITE, 0, 0, 0xC7A5, AUTO, "BaselineExposureOffset", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC7A6, AUTO, "DefaultBlackRender", &defaultBlackRenderInterpreter}, + {0, AC_WRITE, 0, 0, 0xC7A7, AUTO, "NewRawImageDigest", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC7A8, AUTO, "RawToPreviewGain", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC7B5, AUTO, "DefaultUserCrop", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xFDE9, AUTO, "SerialNumber", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xFDEA, AUTO, "Lens", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xFE4C, AUTO, "RawFile", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xFE4D, AUTO, "Converter", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xFE4E, AUTO, "WhiteBalance", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xFE51, AUTO, "Exposure", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xFE52, AUTO, "Shadows", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xFE53, AUTO, "Brightness", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xFE54, AUTO, "Contrast", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xFE55, AUTO, "Saturation", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xFE56, AUTO, "Sharpness", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xFE57, AUTO, "Smoothness", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xFE58, AUTO, "MoireFilter", &stdInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL }}; + + +const TagAttrib gpsAttribs[] = { + {0, AC_WRITE, 0, 0, 0x0000, AUTO, "GPSVersionID", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0001, AUTO, "GPSLatitudeRef", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0002, AUTO, "GPSLatitude", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0003, AUTO, "GPSLongitudeRef", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0004, AUTO, "GPSLongitude", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0005, AUTO, "GPSAltitudeRef", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0006, AUTO, "GPSAltitude", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0007, AUTO, "GPSTimeStamp", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0008, AUTO, "GPSSatelites", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0009, AUTO, "GPSStatus", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x000a, AUTO, "GPSMeasureMode", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x000b, AUTO, "GPSDOP", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x000c, AUTO, "GPSSpeedRef", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x000d, AUTO, "GPSSpeed", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x000e, AUTO, "GPSTrackRef", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x000f, AUTO, "GPSTrack", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0010, AUTO, "GPSImgDirectionRef", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0011, AUTO, "GPSImgDirection", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0012, AUTO, "GPSMapDatum", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0013, AUTO, "GPSDestLatitudeRef", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0014, AUTO, "GPSDestLatitude", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0015, AUTO, "GPSDestLongitudeRef", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0016, AUTO, "GPSDestLongitude", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0017, AUTO, "GPSDestBearingRef", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0018, AUTO, "GPSDestBearing", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0019, AUTO, "GPSDestDistanceRef", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x001a, AUTO, "GPSDestDistance", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x001b, AUTO, "GPSProcessingMethod", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x001c, AUTO, "GPSAreaInformation", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x001d, AUTO, "GPSDateStamp", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x001e, AUTO, "GPSDifferential", &stdInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL }}; + +const TagAttrib iopAttribs[] = { + {0, AC_WRITE, 0, 0, 0x0001, AUTO, "InteroperabilityIndex", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0002, AUTO, "InteroperabilityVersion", &stdInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL }}; + + const TagAttrib ifdAttribs[] = { + {0, AC_SYSTEM, 0, 0, 0x0017, AUTO, "PanaISO", &stdInterpreter}, + {0, AC_SYSTEM, 0, 0, 0x0100, AUTO, "ImageWidth", &stdInterpreter}, + {0, AC_SYSTEM, 0, 0, 0x0101, AUTO, "ImageHeight", &stdInterpreter}, + {0, AC_SYSTEM, 0, 0, 0x0102, AUTO, "BitsPerSample", &stdInterpreter}, + {0, AC_SYSTEM, 0, 0, 0x0103, AUTO, "Compression", &compressionInterpreter}, + {0, AC_SYSTEM, 0, 0, 0x0106, AUTO, "PhotometricInterpretation", &photometricInterpreter}, + {0, AC_WRITE, 1, 0, 0x010E, AUTO, "ImageDescription", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x010F, AUTO, "Make", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0110, AUTO, "Model", &stdInterpreter}, + {1, AC_DONTWRITE, 0, 0, 0x0111, AUTO, "StripOffsets", &stdInterpreter}, + {0, AC_SYSTEM, 0, 0, 0x0112, AUTO, "Orientation", &orientationInterpreter}, + {0, AC_SYSTEM, 0, 0, 0x0115, AUTO, "SamplesPerPixel", &stdInterpreter}, + {1, AC_DONTWRITE, 0, 0, 0x0116, AUTO, "RowsPerStrip", &stdInterpreter}, + {1, AC_DONTWRITE, 0, 0, 0x0117, AUTO, "StripByteCounts", &stdInterpreter}, + {0, AC_SYSTEM, 0, 0, 0x011A, AUTO, "XResolution", &stdInterpreter}, + {0, AC_SYSTEM, 0, 0, 0x011B, AUTO, "YResolution", &stdInterpreter}, + {0, AC_SYSTEM, 0, 0, 0x011C, AUTO, "PlanarConfiguration", &planarConfigInterpreter}, + {0, AC_SYSTEM, 0, 0, 0x0128, AUTO, "ResolutionUnit", &unitsInterpreter}, + {0, AC_SYSTEM, 0, 0, 0x012D, AUTO, "TransferFunction", &stdInterpreter}, + {0, AC_SYSTEM, 0, 0, 0x0131, AUTO, "Software", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x0132, AUTO, "DateTime", &stdInterpreter}, + {0, AC_WRITE, 1, 0, 0x013B, AUTO, "Artist", &stdInterpreter}, + {0, AC_SYSTEM, 0, 0, 0x013E, AUTO, "WhitePoint", &stdInterpreter}, + {0, AC_SYSTEM, 0, 0, 0x013F, AUTO, "PriomaryChromaticities", &stdInterpreter}, + {0, AC_WRITE, 0, ifdAttribs, 0x014A, AUTO, "SubIFD", &stdInterpreter}, + {0, AC_SYSTEM, 0, 0, 0x0201, AUTO, "JPEGInterchangeFormat", &stdInterpreter}, + {0, AC_SYSTEM, 0, 0, 0x0202, AUTO, "JPEGInterchangeFormatLength", &stdInterpreter}, + {0, AC_SYSTEM, 0, 0, 0x0211, AUTO, "YCbCrCoefficients", &stdInterpreter}, + {0, AC_SYSTEM, 0, 0, 0x0212, AUTO, "YCbCrSubSampling", &stdInterpreter}, + {0, AC_SYSTEM, 0, 0, 0x0213, AUTO, "YCbCrPositioning", &stdInterpreter}, + {0, AC_SYSTEM, 0, 0, 0x0214, AUTO, "ReferenceBlackWhite", &stdInterpreter}, + {0, AC_SYSTEM, 0, 0, 0x02bc, AUTO, "ApplicationNotes", &utf8BinInterpreter}, // XMP + {0, AC_WRITE, 0, 0, 0x4746, AUTO, "Rating",&stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x4749, AUTO, "RatingPercent",&stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x828d, AUTO, "CFAPatternDim", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x828e, AUTO, "CFAPattern", &cfaInterpreter}, + {0, AC_WRITE, 0, kodakIfdAttribs, 0x8290, AUTO, "KodakIFD", &stdInterpreter}, + {0, AC_WRITE, 1, 0, 0x8298, AUTO, "Copyright", &stdInterpreter}, + {0, AC_DONTWRITE, 0, 0, 0x8606, AUTO, "LeafData", &stdInterpreter}, // is actually a subdir, but a proprietary format + {0, AC_WRITE, 0, exifAttribs, 0x8769, AUTO, "Exif", &stdInterpreter}, + {0, AC_SYSTEM, 0, 0, 0x8773, AUTO, "ICCProfile", &stdInterpreter}, + {0, AC_SYSTEM, 0, 0, 0x83BB, AUTO, "IPTCData", &stdInterpreter}, + {0, AC_WRITE, 0, gpsAttribs, 0x8825, AUTO, "GPSInfo", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x9003, AUTO, "DateTimeOriginal", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x9004, AUTO, "DateTimeDigitized", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0x9211, AUTO, "ImageNumber", &stdInterpreter}, + {0, AC_WRITE, 0, iopAttribs, 0xA005, AUTO, "Interoperability", &stdInterpreter}, + {0, AC_DONTWRITE, 0, 0, 0xC4A5, AUTO, "PrintIMInformation", &stdInterpreter}, + {0, AC_DONTWRITE, 0, 0, 0xC612, AUTO, "DNGVersion", &stdInterpreter}, + {0, AC_DONTWRITE, 0, 0, 0xC613, AUTO, "DNGBackwardVersion", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC614, AUTO, "UniqueCameraModel", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xC615, AUTO, "LocalizedCameraModel", &stdInterpreter}, + {0, AC_WRITE, 0, 0, 0xc62f, AUTO, "CameraSerialNumber", &stdInterpreter}, + {0, AC_SYSTEM, 0, 0, 0xc630, AUTO, "DNGLensInfo", &stdInterpreter}, + {0, AC_DONTWRITE, 0, 0, 0xC634, AUTO, "MakerNote", &stdInterpreter}, //DNGPrivateData + {0, AC_WRITE, 0, 0, 0xc65d, AUTO, "RawDataUniqueID", &stdInterpreter}, + {0, AC_DONTWRITE, 0, 0, 0xc761, AUTO, "NoiseProfile", &stdInterpreter}, + {0, AC_SYSTEM, 0, 0, 0x00fe, AUTO, "NewSubFileType", &stdInterpreter}, + {-1, AC_DONTWRITE, 0, 0, 0, AUTO, "", NULL}}; +} + +#endif diff --git a/rtgui/CMakeLists.txt b/rtgui/CMakeLists.txt new file mode 100644 index 000000000..c21dd6c55 --- /dev/null +++ b/rtgui/CMakeLists.txt @@ -0,0 +1,74 @@ + +set (BASESOURCEFILES + editwindow.cc batchtoolpanelcoord.cc paramsedited.cc cropwindow.cc previewhandler.cc previewwindow.cc navigator.cc indclippedpanel.cc previewmodepanel.cc filterpanel.cc + exportpanel.cc cursormanager.cc rtwindow.cc renamedlg.cc recentbrowser.cc placesbrowser.cc filepanel.cc editorpanel.cc batchqueuepanel.cc + ilabel.cc thumbbrowserbase.cc adjuster.cc filebrowserentry.cc filebrowser.cc filethumbnailbuttonset.cc + cachemanager.cc cacheimagedata.cc shcselector.cc perspective.cc thresholdselector.cc thresholdadjuster.cc + clipboard.cc thumbimageupdater.cc bqentryupdater.cc lensgeom.cc coloredbar.cc edit.cc coordinateadjuster.cc + coarsepanel.cc cacorrection.cc chmixer.cc blackwhite.cc + resize.cc icmpanel.cc crop.cc shadowshighlights.cc + impulsedenoise.cc dirpyrdenoise.cc epd.cc + exifpanel.cc toolpanel.cc lensprofile.cc + sharpening.cc vibrance.cc rgbcurves.cc colortoning.cc + whitebalance.cc vignetting.cc gradient.cc pcvignette.cc rotate.cc distortion.cc + crophandler.cc dirbrowser.cc + curveeditor.cc curveeditorgroup.cc diagonalcurveeditorsubgroup.cc flatcurveeditorsubgroup.cc + filecatalog.cc extprog.cc + previewloader.cc rtimage.cc inspector.cc + histogrampanel.cc history.cc imagearea.cc + imageareapanel.cc iptcpanel.cc labcurve.cc main.cc + multilangmgr.cc mycurve.cc myflatcurve.cc mydiagonalcurve.cc options.cc + preferences.cc profilepanel.cc saveasdlg.cc + saveformatpanel.cc soundman.cc splash.cc + thumbnail.cc tonecurve.cc toolbar.cc + guiutils.cc zoompanel.cc toolpanelcoord.cc + thumbbrowserentrybase.cc batchqueueentry.cc + batchqueue.cc lwbutton.cc lwbuttonset.cc + batchqueuebuttonset.cc browserfilter.cc exiffiltersettings.cc + profilestore.cc partialpastedlg.cc + sensorbayer.cc sensorxtrans.cc preprocess.cc bayerpreprocess.cc bayerprocess.cc bayerrawexposure.cc xtransprocess.cc xtransrawexposure.cc + darkframe.cc flatfield.cc rawcacorrection.cc rawexposure.cc wavelet.cc + dirpyrequalizer.cc hsvequalizer.cc defringe.cc + popupcommon.cc popupbutton.cc popuptogglebutton.cc sharpenedge.cc sharpenmicro.cc colorappearance.cc + filmsimulation.cc prsharpening.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 (APPLE) +if (WIN32) + set (EXTRA_SRC windirmonitor.cc myicon.rc) + set (EXTRA_LIB_RTGUI winmm) + include_directories (${EXTRA_INCDIR} ${GLIB2_INCLUDE_DIRS} ${GLIBMM_INCLUDE_DIRS} + ${GTK_INCLUDE_DIRS} ${GTKMM_INCLUDE_DIRS} ${GIO_INCLUDE_DIRS} ${GIOMM_INCLUDE_DIRS}) + link_directories (. "${PROJECT_SOURCE_DIR}/rtexif" ${EXTRA_LIBDIR} ${GLIB2_LIBRARY_DIRS} ${GLIBMM_LIBRARY_DIRS} + ${GTK_LIBRARY_DIRS} ${GTKMM_LIBRARY_DIRS} ${GIO_LIBRARY_DIRS} ${GIOMM_LIBRARY_DIRS}) + #set_target_properties (rth PROPERTIES LINK_FLAGS "-mwindows") +else (WIN32) + include_directories (${EXTRA_INCDIR} ${GLIB2_INCLUDE_DIRS} ${GLIBMM_INCLUDE_DIRS} + ${GTK_INCLUDE_DIRS} ${GTKMM_INCLUDE_DIRS} ${GIO_INCLUDE_DIRS} ${GIOMM_INCLUDE_DIRS} ${IPTCDATA_INCLUDE_DIRS} + ${LCMS_INCLUDE_DIRS} ${EXPAT_INCLUDE_DIRS} ${FFTW3F_LIBRARY_DIRS} ${GTHREAD_INCLUDE_DIRS} ${GOBJECT_INCLUDE_DIRS} + ${CANBERRA-GTK_INCLUDE_DIRS}) + link_directories (${EXTRA_LIBDIR} ${GLIB2_LIBRARY_DIRS} ${GLIBMM_LIBRARY_DIRS} + ${GTK_LIBRARY_DIRS} ${GTKMM_LIBRARY_DIRS} ${GIO_LIBRARY_DIRS} ${GIOMM_LIBRARY_DIRS} ${IPTCDATA_LIBRARY_DIRS} + ${LCMS_LIBRARY_DIRS} ${EXPAT_LIBRARY_DIRS} ${FFTW3F_LIBRARY_DIRS} ${GTHREAD_LIBRARY_DIRS} ${GOBJECT_LIBRARY_DIRS} + ${CANBERRA-GTK_LIBRARY_DIRS}) +endif (WIN32) +# create config.h which defines where data are stored +configure_file ("${CMAKE_CURRENT_SOURCE_DIR}/config.h.in" "${CMAKE_CURRENT_BINARY_DIR}/config.h") + +add_executable (rth ${EXTRA_SRC} ${BASESOURCEFILES}) +add_dependencies (rth AboutFile) + +set_target_properties (rth PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS}" OUTPUT_NAME rawtherapee) +#target_link_libraries (rth rtengine ${JPEG_LIBRARIES} ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} ${TIFF_LIBRARIES} ${EXTRA_LIB} ${GOBJECT_LIBRARIES} ${GTHREAD_LIBRARIES} +# ${GLIB2_LIBRARIES} ${GLIBMM_LIBRARIES} ${GTK_LIBRARIES} ${GTKMM_LIBRARIES} ${GIO_LIBRARIES} ${GIOMM_LIBRARIES} ${LCMS_LIBRARIES} ${IPTCDATA_LIBRARIES}) +target_link_libraries (rth rtengine ${JPEG_LIBRARIES} ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} ${TIFF_LIBRARIES} ${GOBJECT_LIBRARIES} ${GTHREAD_LIBRARIES} + ${GLIB2_LIBRARIES} ${GLIBMM_LIBRARIES} ${GTK_LIBRARIES} ${GTKMM_LIBRARIES} ${GIO_LIBRARIES} ${GIOMM_LIBRARIES} ${LCMS_LIBRARIES} ${EXPAT_LIBRARIES} + ${FFTW3F_LIBRARIES} ${IPTCDATA_LIBRARIES} ${CANBERRA-GTK_LIBRARIES} ${EXTRA_LIB_RTGUI}) +install (TARGETS rth DESTINATION ${BINDIR}) + diff --git a/rtgui/RT.ico b/rtgui/RT.ico new file mode 100644 index 000000000..d7befa1a7 Binary files /dev/null and b/rtgui/RT.ico differ diff --git a/rtgui/addsetids.h b/rtgui/addsetids.h new file mode 100644 index 000000000..f9d6b6ef1 --- /dev/null +++ b/rtgui/addsetids.h @@ -0,0 +1,114 @@ +#ifndef _ADDSETIDS_ +#define _ADDSETIDS_ + + +// UPDATE THE DEFAULT VALUE IN OPTIONS.CC int babehav[] TOO !!! + + +#define ADDSET_TC_EXPCOMP 0 +#define ADDSET_TC_BRIGHTNESS 1 +#define ADDSET_TC_BLACKLEVEL 2 +#define ADDSET_TC_CONTRAST 3 +#define ADDSET_SH_HIGHLIGHTS 4 +#define ADDSET_SH_SHADOWS 5 +#define ADDSET_SH_LOCALCONTRAST 6 +#define ADDSET_LC_BRIGHTNESS 7 +#define ADDSET_LC_CONTRAST 8 +#define ADDSET_SHARP_AMOUNT 9 +#define ADDSET_WB_TEMPERATURE 10 +#define ADDSET_WB_GREEN 11 +#define ADDSET_ROTATE_DEGREE 12 +#define ADDSET_DIST_AMOUNT 13 +#define ADDSET_PERSPECTIVE 14 +#define ADDSET_CA 15 +#define ADDSET_VIGN_AMOUNT 16 +#define ADDSET_VIGN_RADIUS 17 +#define ADDSET_VIGN_STRENGTH 18 +#define ADDSET_VIGN_CENTER 19 +#define ADDSET_LC_CHROMATICITY 20 +#define ADDSET_TC_SATURATION 21 +#define ADDSET_TC_HLCOMPAMOUNT 22 +#define ADDSET_TC_HLCOMPTHRESH 23 +#define ADDSET_TC_SHCOMP 24 +#define ADDSET_DIRPYREQ 25 +#define ADDSET_DIRPYRDN_LUMA 26 +#define ADDSET_DIRPYRDN_LUMDET 27 +#define ADDSET_DIRPYRDN_CHROMA 28 +#define ADDSET_DIRPYRDN_CHROMARED 29 +#define ADDSET_DIRPYRDN_CHROMABLUE 30 +#define ADDSET_DIRPYRDN_GAMMA 31 +#define ADDSET_CHMIXER 32 +#define ADDSET_PREPROCESS_GREENEQUIL 33 +#define ADDSET_PREPROCESS_LINEDENOISE 34 +#define ADDSET_RAWCACORR 35 +#define ADDSET_RAWEXPOS_LINEAR 36 +#define ADDSET_RAWEXPOS_PRESER 37 +#define ADDSET_RAWEXPOS_BLACKS 38 +#define ADDSET_SHARPENEDGE_AMOUNT 39 +#define ADDSET_SHARPENMICRO_AMOUNT 40 +#define ADDSET_SHARPENEDGE_PASS 41 +#define ADDSET_SHARPENMICRO_UNIFORMITY 42 +#define ADDSET_VIBRANCE_PASTELS 43 +#define ADDSET_VIBRANCE_SATURATED 44 +#define ADDSET_FREE_OUPUT_GAMMA 45 +#define ADDSET_FREE_OUTPUT_SLOPE 46 +#define ADDSET_CAT_DEGREE 47 +#define ADDSET_CAT_ADAPTSCENE 48 +#define ADDSET_CAT_ADAPTVIEWING 49 +#define ADDSET_CAT_LIGHT 50 +#define ADDSET_CAT_CHROMA 51 +#define ADDSET_CAT_CONTRAST 52 +#define ADDSET_CAT_RSTPRO 53 +#define ADDSET_CAT_BRIGHT 54 +#define ADDSET_CAT_CONTRAST_Q 55 +#define ADDSET_CAT_CHROMA_S 56 +#define ADDSET_CAT_CHROMA_M 57 +#define ADDSET_CAT_HUE 58 +#define ADDSET_CAT_BADPIX 59 +#define ADDSET_WB_EQUAL 60 +#define ADDSET_GRADIENT_DEGREE 61 +#define ADDSET_GRADIENT_FEATHER 62 +#define ADDSET_GRADIENT_STRENGTH 63 +#define ADDSET_GRADIENT_CENTER 64 +#define ADDSET_PCVIGNETTE_STRENGTH 65 +#define ADDSET_PCVIGNETTE_FEATHER 66 +#define ADDSET_PCVIGNETTE_ROUNDNESS 67 +#define ADDSET_BLACKWHITE_HUES 68 +#define ADDSET_BLACKWHITE_GAMMA 69 +#define ADDSET_DIRPYREQ_THRESHOLD 70 +#define ADDSET_DIRPYREQ_SKINPROTECT 71 +#define ADDSET_COLORTONING_SPLIT 72 +#define ADDSET_COLORTONING_SATTHRESHOLD 73 +#define ADDSET_COLORTONING_SATOPACITY 74 +#define ADDSET_COLORTONING_BALANCE 75 +#define ADDSET_COLORTONING_STRENGTH 76 +#define ADDSET_DIRPYRDN_PASSES 77 +#define ADDSET_RAWFFCLIPCONTROL 78 +#define ADDSET_FILMSIMULATION_STRENGTH 79 +#define ADDSET_WA 80 +#define ADDSET_WA_SKINPROTECT 81 +#define ADDSET_WA_THRR 82 +#define ADDSET_WA_THRRH 83 +#define ADDSET_WA_THRES 84 +#define ADDSET_WA_THRESHOLD 85 +#define ADDSET_WA_THRESHOLD2 86 +#define ADDSET_WA_CHRO 87 +#define ADDSET_WA_CHROMA 88 +#define ADDSET_WA_CONTRAST 89 +#define ADDSET_WA_RESCON 90 +#define ADDSET_WA_RESCONH 91 +#define ADDSET_WA_RESCHRO 92 +#define ADDSET_WA_SKYPROTECT 93 +#define ADDSET_WA_EDGRAD 94 +#define ADDSET_WA_EDGVAL 95 +#define ADDSET_WA_STRENGTH 96 +#define ADDSET_WA_EDGEDETECT 97 +#define ADDSET_WA_EDGEDETECTTHR 98 +#define ADDSET_WA_EDGEDETECTTHR2 99 +#define ADDSET_WA_TMRS 100 +#define ADDSET_WA_GAMMA 101 + +// When adding items, make sure to update ADDSET_PARAM_NUM +#define ADDSET_PARAM_NUM 102 // THIS IS USED AS A DELIMITER!! + +#endif diff --git a/rtgui/adjuster.cc b/rtgui/adjuster.cc new file mode 100644 index 000000000..c09c4af2e --- /dev/null +++ b/rtgui/adjuster.cc @@ -0,0 +1,495 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "adjuster.h" +#include +#include +#include "multilangmgr.h" +#include "../rtengine/rtengine.h" +#include "options.h" +#include "guiutils.h" +#include "rtimage.h" + +#define MIN_RESET_BUTTON_HEIGHT 17 + +static double one2one(double val) { return val; } + +Adjuster::Adjuster (Glib::ustring vlabel, double vmin, double vmax, double vstep, double vdefault, Gtk::Image *imgIcon1, Gtk::Image *imgIcon2, double2double_fun slider2value_, double2double_fun value2slider_) { + + Gtk::HBox *hbox2=NULL; + label = NULL; + adjusterListener = NULL; + afterReset = false; + blocked = false; + automatic = NULL; + eventPending = false; + + slider2value = slider2value_ ? slider2value_ : one2one; + value2slider = value2slider_ ? value2slider_ : one2one; + vMin = vmin; + vMax = vmax; + vStep = vstep; + addMode = false; + + // TODO: let the user chose the default value of Adjuster::delay, for slow machines + delay = options.adjusterDelay; // delay is no more static, so we can set the delay individually (useful for the RAW editor tab) + + set_border_width (0); + set_spacing (0); + + hbox = Gtk::manage (new Gtk::HBox ()); + hbox->set_border_width(0); + hbox->set_spacing(2); + + editedCheckBox = NULL; + + if (!vlabel.empty()) { + adjustmentName = vlabel; + label = Gtk::manage (new Gtk::Label (adjustmentName, Gtk::ALIGN_LEFT)); + } + + reset = Gtk::manage (new Gtk::Button ()); + reset->add (*Gtk::manage (new RTImage ("gtk-undo-ltr-small.png", "gtk-undo-rtl-small.png"))); + reset->set_relief (Gtk::RELIEF_NONE); + reset->set_border_width (0); + reset->set_tooltip_text (M("ADJUSTER_RESET_TO_DEFAULT")); + reset->set_can_focus(false); + + spin = Gtk::manage (new MySpinButton ()); + spin->set_has_frame(false); + spin->set_name("FramelessSpinButton"); + + reset->set_size_request (-1, spin->get_height() > MIN_RESET_BUTTON_HEIGHT ? spin->get_height(): MIN_RESET_BUTTON_HEIGHT); + + slider = Gtk::manage (new MyHScale ()); + slider->set_draw_value (false); + + pack_start (*hbox, true, true); + + if (vlabel.empty()) { + // No label, everything goes in hbox + if (imgIcon1) hbox->pack_start (*imgIcon1, Gtk::PACK_SHRINK, 0); + hbox->pack_start (*slider, Gtk::PACK_EXPAND_WIDGET, 0); + if (imgIcon2) hbox->pack_start (*imgIcon2, Gtk::PACK_SHRINK, 0); + hbox->pack_end (*reset, Gtk::PACK_SHRINK, 0); + hbox->pack_end (*spin, Gtk::PACK_SHRINK, 0); + } + else { + // A label is provided, spreading the widgets in 2 rows + hbox->pack_start (*label); + hbox->pack_end (*reset, Gtk::PACK_SHRINK, 0); + hbox->pack_end (*spin, Gtk::PACK_SHRINK, 0); + if (!imgIcon1 || !imgIcon2) { + pack_start (*slider, true, true); + } + else { + // A second HBox is necessary + hbox2 = Gtk::manage (new Gtk::HBox()); + if (imgIcon1) hbox2->pack_start (*imgIcon1, Gtk::PACK_SHRINK, 0); + hbox2->pack_start (*slider, true, true); + if (imgIcon2) hbox2->pack_start (*imgIcon2, Gtk::PACK_SHRINK, 0); + pack_start (*hbox2, true, true); + } + } + + setLimits (vmin, vmax, vstep, vdefault); + + defaultVal = shapeValue (vdefault); + ctorDefaultVal = shapeValue (vdefault); + editedState = defEditedState = Irrelevant; + autoState = Irrelevant; + + sliderChange = slider->signal_value_changed().connect( sigc::mem_fun(*this, &Adjuster::sliderChanged) ); + spinChange = spin->signal_value_changed().connect ( sigc::mem_fun(*this, &Adjuster::spinChanged), true); + reset->signal_button_release_event().connect_notify( sigc::mem_fun(*this, &Adjuster::resetPressed) ); + slider->set_update_policy (Gtk::UPDATE_CONTINUOUS); + + show_all (); +} + +Adjuster::~Adjuster () { + + sliderChange.block (true); + spinChange.block (true); + delayConnection.block (true); + adjusterListener = NULL; + if (automatic) delete automatic; +} + +void Adjuster::addAutoButton (Glib::ustring tooltip) { + if (!automatic) { + automatic = new Gtk::CheckButton (); + //automatic->add (*Gtk::manage (new RTImage ("processing.png"))); + automatic->set_border_width (0); + automatic->set_tooltip_markup(tooltip.length() ? Glib::ustring::compose("%1\n\n%2", M("GENERAL_AUTO"), tooltip) : M("GENERAL_AUTO")); + autoChange = automatic->signal_toggled().connect( sigc::mem_fun(*this, &Adjuster::autoToggled) ); + + hbox->pack_end (*automatic, Gtk::PACK_SHRINK, 0); + hbox->reorder_child (*automatic, 0); + } +} + +void Adjuster::delAutoButton () { + if (automatic) { + removeIfThere(hbox, automatic); + delete automatic; + automatic = NULL; + } +} + +void Adjuster::throwOnButtonRelease(bool throwOnBRelease) { + + if (throwOnBRelease) { + if (!buttonReleaseSlider.connected()) + buttonReleaseSlider = slider->signal_button_release_event().connect_notify( sigc::mem_fun(*this, &Adjuster::sliderReleased) ); + if (!buttonReleaseSpin.connected()) + buttonReleaseSpin = spin->signal_button_release_event().connect_notify( sigc::mem_fun(*this, &Adjuster::spinReleased) ); // Use the same callback hook + } + else { + if (buttonReleaseSlider.connected()) + buttonReleaseSlider.disconnect(); + if (buttonReleaseSpin.connected()) + buttonReleaseSpin.disconnect(); + } + eventPending = false; +} + +void Adjuster::setDefault (double def) { + + defaultVal = shapeValue (def); +} + +void Adjuster::setDefaultEditedState (EditedState eState) { + + defEditedState = eState; +} + +void Adjuster::autoToggled () { + + if (!editedCheckBox) { + // If not used in the BatchEditor panel + if (automatic->get_active()) { + // Disable the slider and spin button + spin->set_sensitive(false); + slider->set_sensitive(false); + } + else { + // Enable the slider and spin button + spin->set_sensitive(true); + slider->set_sensitive(true); + } + } + + if (adjusterListener!=NULL && !blocked) { + adjusterListener->adjusterAutoToggled(this, automatic->get_active()); + } +} + +void Adjuster::sliderReleased (GdkEventButton* event) { + + if ((event != NULL) && (event->button == 1)) { + if (delayConnection.connected()) + delayConnection.disconnect (); + notifyListener(); + } +} + +void Adjuster::spinReleased (GdkEventButton* event) { + + if ((event != NULL) && delay==0) { + if (delayConnection.connected()) + delayConnection.disconnect (); + notifyListener(); + } +} + +void Adjuster::resetValue (bool toInitial) { + if (editedState!=Irrelevant) { + editedState = defEditedState; + if (editedCheckBox) { + editedChange.block (true); + editedCheckBox->set_active (defEditedState==Edited); + editedChange.block (false); + } + refreshLabelStyle (); + } + afterReset = true; + if (toInitial) { + // resetting to the initial editing value, when the image has been loaded + slider->set_value (addMode ? defaultVal : value2slider(defaultVal)); + } + else { + // resetting to the slider default value + if (addMode) + slider->set_value (0.); + else + slider->set_value (value2slider(ctorDefaultVal)); + } +} + +// Please note that it won't change the "Auto" CheckBox's state, if there +void Adjuster::resetPressed (GdkEventButton* event) { + + if ((event != NULL) && (event->state & GDK_CONTROL_MASK) && (event->button == 1)) + resetValue(true); + else + resetValue(false); +} + +double Adjuster::shapeValue (double a) { + + return round(a*pow(double(10), digits)) / pow(double(10), digits); +} + +void Adjuster::setLimits (double vmin, double vmax, double vstep, double vdefault) { + + sliderChange.block (true); + spinChange.block (true); + for (digits=0; fabs(vstep*pow(double(10),digits)-floor(vstep*pow(double(10),digits)))>0.000000000001; digits++); + spin->set_digits (digits); + spin->set_increments (vstep, 2.0*vstep); + spin->set_range (vmin, vmax); + spin->updateSize(); + spin->set_value (shapeValue(vdefault)); + slider->set_digits (digits); + slider->set_increments (vstep, 2.0*vstep); + slider->set_range (addMode ? vmin : value2slider(vmin), addMode ? vmax : value2slider(vmax)); + slider->set_value (addMode ? shapeValue(vdefault) : value2slider(shapeValue(vdefault))); + //defaultVal = shapeValue (vdefault); + sliderChange.block (false); + spinChange.block (false); +} + +void Adjuster::setAddMode(bool addM) { + if (addM != addMode) { + // Switching the Adjuster to the new mode + addMode = addM; + if (addM) { + // Switching to the relative mode + double range = -vMin + vMax; + if (range < 0.) range = -range; + setLimits(-range, range, vStep, 0); + } + else { + // Switching to the absolute mode + setLimits(vMin, vMax, vStep, defaultVal); + } + } +} + +void Adjuster::spinChanged () { + + if (delayConnection.connected()) + delayConnection.disconnect (); + + sliderChange.block (true); + slider->set_value (addMode ? spin->get_value () : value2slider(spin->get_value ())); + sliderChange.block (false); + + if (delay==0) { + if (adjusterListener && !blocked) { + if (!buttonReleaseSlider.connected() || afterReset) { + eventPending = false; + adjusterListener->adjusterChanged (this, spin->get_value ()); + } + else eventPending = true; + } + } + else { + eventPending = true; + delayConnection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &Adjuster::notifyListener), delay); + } + + if (editedState==UnEdited) { + editedState = Edited; + if (editedCheckBox) { + editedChange.block (true); + editedCheckBox->set_active (true); + editedChange.block (false); + } + refreshLabelStyle (); + } + afterReset = false; +} + +void Adjuster::sliderChanged () { + + if (delayConnection.connected()) + delayConnection.disconnect (); + + spinChange.block (true); + spin->set_value (addMode ? slider->get_value () : slider2value(slider->get_value ())); + spinChange.block (false); + + if (delay==0 || afterReset) { + if (adjusterListener && !blocked) { + if (!buttonReleaseSlider.connected() || afterReset) { + eventPending = false; + adjusterListener->adjusterChanged (this, spin->get_value ()); + } + else eventPending = true; + } + } + else { + eventPending = true; + delayConnection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &Adjuster::notifyListener), delay); + } + + if (!afterReset && editedState==UnEdited) { + editedState = Edited; + if (editedCheckBox) { + editedChange.block (true); + editedCheckBox->set_active (true); + editedChange.block (false); + } + refreshLabelStyle (); + } + afterReset = false; +} + +void Adjuster::setValue (double a) { + + spinChange.block (true); + sliderChange.block (true); + spin->set_value (shapeValue (a)); + slider->set_value (addMode ? shapeValue(a) : value2slider(shapeValue (a))); + sliderChange.block (false); + spinChange.block (false); + afterReset = false; +} + +void Adjuster::setAutoValue (bool a) { + if (automatic) { + bool oldVal = autoChange.block(true); + automatic->set_active(a); + autoChange.block(oldVal); + if (!editedCheckBox) { + // If not used in the BatchEditor panel + if (a) { + // Disable the slider and spin button + spin->set_sensitive(false); + slider->set_sensitive(false); + } + else { + // Enable the slider and spin button + spin->set_sensitive(true); + slider->set_sensitive(true); + } + } + } +} + +bool Adjuster::notifyListener () { + + if (eventPending && adjusterListener!=NULL && !blocked) { + adjusterListener->adjusterChanged (this, spin->get_value ()); + } + eventPending = false; + + return false; +} + +bool Adjuster::notifyListenerAutoToggled () { + + if (adjusterListener!=NULL && !blocked) { + adjusterListener->adjusterAutoToggled(this, automatic->get_active()); + } + return false; +} + +void Adjuster::setEnabled (bool enabled) { + + bool autoVal = automatic && !editedCheckBox ? automatic->get_active() : true; + spin->set_sensitive (enabled && autoVal); + slider->set_sensitive (enabled && autoVal); + if (automatic) + automatic->set_sensitive (enabled); +} + +void Adjuster::setEditedState (EditedState eState) { + + if (editedState!=eState) { + if (editedCheckBox) { + editedChange.block (true); + editedCheckBox->set_active (eState==Edited); + editedChange.block (false); + } + editedState = eState; + refreshLabelStyle (); + } +} + +EditedState Adjuster::getEditedState () { + + if (editedState!=Irrelevant && editedCheckBox) + editedState = editedCheckBox->get_active () ? Edited : UnEdited; + return editedState; +} + +void Adjuster::showEditedCB () { + + if (label) + removeIfThere(hbox, label, false); + + if (!editedCheckBox) { + editedCheckBox = Gtk::manage(new Gtk::CheckButton (adjustmentName)); + hbox->pack_start (*editedCheckBox, Gtk::PACK_SHRINK, 2); + hbox->reorder_child (*editedCheckBox, 0); + editedChange = editedCheckBox->signal_toggled().connect( sigc::mem_fun(*this, &Adjuster::editedToggled) ); + editedCheckBox->show(); + } +} + +void Adjuster::refreshLabelStyle () { + +/* Glib::RefPtr style = label->get_style (); + Pango::FontDescription fd = style->get_font (); + fd.set_weight (editedState==Edited ? Pango::WEIGHT_BOLD : Pango::WEIGHT_NORMAL); + style->set_font (fd); + label->set_style (style); + label->queue_draw ();*/ +} + +void Adjuster::editedToggled () { + + if (adjusterListener && !blocked) { + adjusterListener->adjusterChanged (this, spin->get_value ()); + } + eventPending = false; +} + +double Adjuster::trimValue (double val) { + + if (val > vMax) val = vMax; // shapeValue(vMax) ? + else if (val < vMin) val = vMin; // shapeValue(vMin) ? + return val; +} + +int Adjuster::trimValue (int val) { + + if (val > (int)vMax) val = (int)vMax; // shapeValue(vMax) ? + else if (val < (int)vMin) val = (int)vMin; // shapeValue(vMin) ? + return val; +} + +float Adjuster::trimValue (float val) { + + if (val > (float)vMax) val = (float)vMax; // shapeValue(vMax) ? + else if (val < (float)vMin) val = (float)vMin; // shapeValue(vMin) ? + return val; +} diff --git a/rtgui/adjuster.h b/rtgui/adjuster.h new file mode 100644 index 000000000..773829df3 --- /dev/null +++ b/rtgui/adjuster.h @@ -0,0 +1,134 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _ADJUSTER_H_ +#define _ADJUSTER_H_ + +#include +#include "editedstate.h" +#include "guiutils.h" + +class Adjuster; +class AdjusterListener { + + public: + virtual ~AdjusterListener() {}; + virtual void adjusterChanged (Adjuster* a, double newval) {} + virtual void adjusterAutoToggled (Adjuster* a, bool newval) {} +}; + +typedef double(*double2double_fun)(double val); + +class Adjuster : public Gtk::VBox { + + protected: + Glib::ustring adjustmentName; + Gtk::HBox* hbox; + Gtk::Label* label; + MyHScale* slider; + MySpinButton* spin; + Gtk::Button* reset; + Gtk::CheckButton* automatic; + AdjusterListener* adjusterListener; + sigc::connection delayConnection; + sigc::connection spinChange; + sigc::connection sliderChange; + sigc::connection editedChange; + sigc::connection autoChange; + sigc::connection buttonReleaseSlider; + sigc::connection buttonReleaseSpin; + bool listenerReady; + double defaultVal; // current default value (it can change when switching from ADD or SET mode) + double ctorDefaultVal; // default value at construction time + EditedState editedState; + EditedState defEditedState; + EditedState autoState; + EditedState defAutoState; + int digits; + Gtk::CheckButton* editedCheckBox; + bool afterReset; + bool blocked; + bool addMode; + bool eventPending; + double vMin; + double vMax; + double vStep; + + double shapeValue (double a); + void refreshLabelStyle (); + double2double_fun value2slider, slider2value; + + public: + + int delay; + + Adjuster (Glib::ustring vlabel, double vmin, double vmax, double vstep, double vdefault, Gtk::Image *imgIcon1=NULL, Gtk::Image *imgIcon2=NULL, double2double_fun slider2value=NULL, double2double_fun value2slider=NULL); + virtual ~Adjuster (); + + // Add an "Automatic" checkbox next to the reset button. + void addAutoButton(Glib::ustring tooltip=""); + // Remove the "Automatic" checkbox next to the reset button. + void delAutoButton(); + // Send back the value of og the Auto checkbox + bool getAutoValue () { return automatic!=NULL ? automatic->get_active () : false; } + void setAutoValue (bool a); + bool notifyListenerAutoToggled (); + void autoToggled (); + void setAutoInconsistent (bool i) { if (automatic) automatic->set_inconsistent(i); } + bool getAutoInconsistent () { return automatic ? automatic->get_inconsistent() : true /* we have to return something */; } + + void setAdjusterListener (AdjusterListener* alistener) { adjusterListener = alistener; } + + // return the value trimmed to the limits at construction time + double getValue () { return shapeValue(spin->get_value ()); } + // return the value trimmed to the limits at construction time + int getIntValue () { return spin->get_value_as_int (); } + // return the value trimmed to the limits at construction time, + // method only used by the history manager, so decoration is added if addMode=true + Glib::ustring getTextValue () { if (addMode) return Glib::ustring::compose("%1", spin->get_text ()); else return spin->get_text (); } + + void setLabel (Glib::ustring lbl) { label->set_label(lbl); } + void setValue (double a); + void setLimits (double vmin, double vmax, double vstep, double vdefault); + void setEnabled (bool enabled); + void setDefault (double def); + // will let the adjuster throw it's "changed" signal when the mouse button is released. Can work altogether with the delay value. + void throwOnButtonRelease(bool throwOnBRelease=true); + void setNbDisplayedChars (int nbr) { spin->set_width_chars(nbr); } + void setEditedState (EditedState eState); + EditedState getEditedState (); + void setDefaultEditedState (EditedState eState); + void showEditedCB (); + bool block(bool isBlocked) { bool oldValue = blocked; blocked = isBlocked; return oldValue; } + + void setAddMode(bool addM); + bool getAddMode() { return addMode; }; + void spinChanged (); + void sliderChanged (); + bool notifyListener (); + void sliderReleased (GdkEventButton* event); + void spinReleased (GdkEventButton* event); + void resetValue (bool toInitial); + void resetPressed (GdkEventButton* event); + void editedToggled (); + double trimValue (double val); + float trimValue (float val); + int trimValue (int val); +}; + +#endif diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc new file mode 100644 index 000000000..b2ba1a831 --- /dev/null +++ b/rtgui/batchqueue.cc @@ -0,0 +1,961 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 +#include "../rtengine/rt_math.h" + +#include +#include +#include + +#include "thumbnail.h" +#include "batchqueue.h" +#include "multilangmgr.h" +#include "filecatalog.h" +#include "batchqueuebuttonset.h" +#include "guiutils.h" +#include "../rtengine/safegtk.h" +#include "rtimage.h" + +using namespace std; +using namespace rtengine; + +BatchQueue::BatchQueue (FileCatalog* aFileCatalog) : processing(NULL), fileCatalog(aFileCatalog), sequence(0), listener(NULL) { + + location = THLOC_BATCHQUEUE; + + int p = 0; + pmenu = new Gtk::Menu (); + + pmenu->attach (*Gtk::manage(open = new Gtk::MenuItem (M("FILEBROWSER_POPUPOPENINEDITOR"))), 0, 1, p, p+1); p++; + pmenu->attach (*Gtk::manage(selall = new Gtk::MenuItem (M("FILEBROWSER_POPUPSELECTALL"))), 0, 1, p, p+1); p++; + pmenu->attach (*Gtk::manage(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++; + + pmenu->attach (*Gtk::manage(head = new Gtk::ImageMenuItem (M("FILEBROWSER_POPUPMOVEHEAD"))), 0, 1, p, p+1); p++; + head->set_image(*Gtk::manage(new RTImage ("toleftend.png"))); + + pmenu->attach (*Gtk::manage(tail = new Gtk::ImageMenuItem (M("FILEBROWSER_POPUPMOVEEND"))), 0, 1, p, p+1); p++; + tail->set_image(*Gtk::manage(new RTImage ("torightend.png"))); + + pmenu->attach (*Gtk::manage(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++; + + pmenu->attach (*Gtk::manage(cancel = new Gtk::ImageMenuItem (M("FILEBROWSER_POPUPCANCELJOB"))), 0, 1, p, p+1); p++; + cancel->set_image(*Gtk::manage(new RTImage ("gtk-close.png"))); + + pmenu->show_all (); + + // Accelerators + pmaccelgroup = Gtk::AccelGroup::create (); + pmenu->set_accel_group (pmaccelgroup); + open->add_accelerator ("activate", pmenu->get_accel_group(), GDK_e, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE); + selall->add_accelerator ("activate", pmenu->get_accel_group(), GDK_a, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE); + head->add_accelerator ("activate", pmenu->get_accel_group(), GDK_Home, (Gdk::ModifierType)0, Gtk::ACCEL_VISIBLE); + tail->add_accelerator ("activate", pmenu->get_accel_group(), GDK_End, (Gdk::ModifierType)0, Gtk::ACCEL_VISIBLE); + cancel->add_accelerator ("activate", pmenu->get_accel_group(), GDK_Delete, (Gdk::ModifierType)0, Gtk::ACCEL_VISIBLE); + + open->signal_activate().connect(sigc::mem_fun(*this, &BatchQueue::openLastSelectedItemInEditor)); + cancel->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &BatchQueue::cancelItems), &selected)); + head->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &BatchQueue::headItems), &selected)); + tail->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &BatchQueue::tailItems), &selected)); + selall->signal_activate().connect (sigc::mem_fun(*this, &BatchQueue::selectAll)); + + setArrangement (ThumbBrowserBase::TB_Vertical); +} + +BatchQueue::~BatchQueue () +{ + #if PROTECT_VECTORS + MYWRITERLOCK(l, entryRW); + #endif + + // The listener merges parameters with old values, so delete afterwards + for (size_t i=0; iresize(getThumbnailHeight()); + } +} + +// Reduce the max size of a thumb, since thumb is processed synchronously on adding to queue +// leading to very long waiting when adding more images +int BatchQueue::calcMaxThumbnailHeight() { + return std::min(options.maxThumbnailHeight, 200); +} + +// Function for virtual override in thumbbrowser base +int BatchQueue::getMaxThumbnailHeight() const { + return calcMaxThumbnailHeight(); +} + +void BatchQueue::saveThumbnailHeight (int height) { + options.thumbSizeQueue = height; +} + +int BatchQueue::getThumbnailHeight () { + // The user could have manually forced the option to a too big value + return std::max(std::min(options.thumbSizeQueue, 200), 10); +} + +void BatchQueue::rightClicked (ThumbBrowserEntryBase* entry) { + + pmenu->popup (3, this->eventTime); +} + +void BatchQueue::doubleClicked(ThumbBrowserEntryBase* entry) { + openItemInEditor(entry); +} + +bool BatchQueue::keyPressed (GdkEventKey* event) { + bool ctrl = event->state & GDK_CONTROL_MASK; + + if ((event->keyval==GDK_A || event->keyval==GDK_a) && ctrl) { + selectAll (); + return true; + } + else if ((event->keyval==GDK_E || event->keyval== GDK_e) && ctrl) { + openLastSelectedItemInEditor(); + return true; + } + else if (event->keyval==GDK_Home) { + headItems (&selected); + return true; + } + else if (event->keyval==GDK_End) { + tailItems (&selected); + return true; + } + else if (event->keyval==GDK_Delete) { + cancelItems (&selected); + return true; + } + + return false; +} + +void BatchQueue::addEntries ( std::vector &entries, bool head, bool save) +{ + { + // TODO: Check for Linux + #if PROTECT_VECTORS + MYWRITERLOCK(l, entryRW); + #endif + + for( std::vector::iterator entry = entries.begin(); entry != entries.end();entry++ ){ + (*entry)->setParent (this); + + // BatchQueueButtonSet HAVE TO be added before resizing to take them into account + BatchQueueButtonSet* bqbs = new BatchQueueButtonSet (*entry); + bqbs->setButtonListener (this); + (*entry)->addButtonSet (bqbs); + + (*entry)->resize (getThumbnailHeight()); // batch queue might have smaller, restricted size + Glib::ustring tempFile = getTempFilenameForParams( (*entry)->filename ); + + // recovery save + if( !(*entry)->params.save( tempFile ) ) + (*entry)->savedParamsFile = tempFile; + + (*entry)->selected = false; + if (!head) + fd.push_back (*entry); + else { + std::vector::iterator pos; + for (pos=fd.begin(); pos!=fd.end(); pos++) + if (!(*pos)->processing) { + fd.insert (pos, *entry); + break; + } + if (pos==fd.end()) + fd.push_back (*entry); + } + if ((*entry)->thumbnail) + (*entry)->thumbnail->imageEnqueued (); + } + } + + if (save) + saveBatchQueue( ); + + redraw(); + notifyListener (false); +} + +bool BatchQueue::saveBatchQueue( ) +{ + Glib::ustring savedQueueFile; + savedQueueFile = options.rtdir+"/batch/queue.csv"; + FILE *f = safe_g_fopen (savedQueueFile, "wt"); + + if (f==NULL) + return false; + + { + // TODO: Check for Linux + #if PROTECT_VECTORS + MYREADERLOCK(l, entryRW); + #endif + + if (fd.size()) + // The column's header is mandatory (the first line will be skipped when loaded) + fprintf(f,"input image full path|param file full path|output image full path|file format|jpeg quality|jpeg subsampling|" + "png bit depth|png compression|tiff bit depth|uncompressed tiff|save output params|force format options|\n"); + + // method is already running with entryLock, so no need to lock again + for (std::vector::iterator pos=fd.begin(); pos!=fd.end(); pos++){ + BatchQueueEntry* bqe = reinterpret_cast(*pos); + // Warning: for code's simplicity in loadBatchQueue, each field must end by the '|' character, safer than ';' or ',' since it can't be used in paths + fprintf(f,"%s|%s|%s|%s|%d|%d|%d|%d|%d|%d|%d|%d|\n", + bqe->filename.c_str(),bqe->savedParamsFile.c_str(), bqe->outFileName.c_str(), bqe->saveFormat.format.c_str(), + bqe->saveFormat.jpegQuality, bqe->saveFormat.jpegSubSamp, + bqe->saveFormat.pngBits, bqe->saveFormat.pngCompression, + bqe->saveFormat.tiffBits, bqe->saveFormat.tiffUncompressed, + bqe->saveFormat.saveParams, bqe->forceFormatOpts + ); + } + } + fclose (f); + return true; +} + +bool BatchQueue::loadBatchQueue( ) +{ + Glib::ustring savedQueueFile; + savedQueueFile = options.rtdir+"/batch/queue.csv"; + FILE *f = safe_g_fopen (savedQueueFile, "rt"); + + if (f!=NULL) { + char *buffer = new char[1024]; + unsigned numLoaded=0; + // skipping the first line + bool firstLine=true; + + // Yes, it's better to get the lock for the whole file reading, + // to update the list in one shot without any other concurrent access! + + // TODO: Check for Linux + #if PROTECT_VECTORS + MYWRITERLOCK(l, entryRW); + #endif + + while (fgets (buffer, 1024, f)){ + + if (firstLine) { + // skipping the column's title line + firstLine=false; + continue; + } + + size_t pos; + Glib::ustring source; + Glib::ustring paramsFile; + Glib::ustring outputFile; + Glib::ustring saveFmt(options.saveFormat.format); + int jpegQuality=options.saveFormat.jpegQuality, jpegSubSamp =options.saveFormat.jpegSubSamp; + int pngBits =options.saveFormat.pngBits, pngCompression =options.saveFormat.pngCompression; + int tiffBits =options.saveFormat.tiffBits, tiffUncompressed=options.saveFormat.tiffUncompressed; + int saveParams =options.saveFormat.saveParams; + int forceFormatOpts =options.forceFormatOpts; + + Glib::ustring currLine(buffer); + int a = 0; + if (currLine.rfind('\n') != Glib::ustring::npos) a++; + if (currLine.rfind('\r') != Glib::ustring::npos) a++; + if (a) + currLine = currLine.substr(0, currLine.length()-a); + + // Looking for the image's full path + pos = currLine.find('|'); + if (pos != Glib::ustring::npos) { + source = currLine.substr(0, pos); + currLine = currLine.substr(pos+1); + + // Looking for the procparams' full path + pos = currLine.find('|'); + if (pos != Glib::ustring::npos) { + paramsFile = currLine.substr(0, pos); + currLine = currLine.substr(pos+1); + + // Looking for the full output path; if empty, it'll use the template string + pos = currLine.find('|'); + if (pos != Glib::ustring::npos) { + outputFile = currLine.substr(0, pos); + currLine = currLine.substr(pos+1); + + // No need to bother reading the last options, they will be ignored if outputFile is empty! + if (!outputFile.empty()) { + + // Looking for the saving format + pos = currLine.find('|'); + if (pos != Glib::ustring::npos) { + saveFmt = currLine.substr(0, pos); + currLine = currLine.substr(pos+1); + + // Looking for the jpeg quality + pos = currLine.find('|'); + if (pos != Glib::ustring::npos) { + jpegQuality = atoi(currLine.substr(0, pos).c_str()); + currLine = currLine.substr(pos+1); + + // Looking for the jpeg subsampling + pos = currLine.find('|'); + if (pos != Glib::ustring::npos) { + jpegSubSamp = atoi(currLine.substr(0, pos).c_str()); + currLine = currLine.substr(pos+1); + + // Looking for the png bit depth + pos = currLine.find('|'); + if (pos != Glib::ustring::npos) { + pngBits = atoi(currLine.substr(0, pos).c_str()); + currLine = currLine.substr(pos+1); + + // Looking for the png compression + pos = currLine.find('|'); + if (pos != Glib::ustring::npos) { + pngCompression = atoi(currLine.substr(0, pos).c_str()); + currLine = currLine.substr(pos+1); + + // Looking for the tiff bit depth + pos = currLine.find('|'); + if (pos != Glib::ustring::npos) { + tiffBits = atoi(currLine.substr(0, pos).c_str()); + currLine = currLine.substr(pos+1); + + // Looking for the tiff uncompression + pos = currLine.find('|'); + if (pos != Glib::ustring::npos) { + tiffUncompressed = atoi(currLine.substr(0, pos).c_str()); + currLine = currLine.substr(pos+1); + + // Looking out if we have to save the procparams + pos = currLine.find('|'); + if (pos != Glib::ustring::npos) { + saveParams = atoi(currLine.substr(0, pos).c_str()); + currLine = currLine.substr(pos+1); + + // Looking out if we have to to use the format options + pos = currLine.find('|'); + if (pos != Glib::ustring::npos) { + forceFormatOpts = atoi(currLine.substr(0, pos).c_str()); + // currLine = currLine.substr(pos+1); + + }}}}}}}}}}}}} + + if( !source.empty() && !paramsFile.empty() ){ + rtengine::procparams::ProcParams pparams; + if( pparams.load( paramsFile ) ) + continue; + + ::Thumbnail *thumb = cacheMgr->getEntry( source ); + if( thumb ){ + rtengine::ProcessingJob* job = rtengine::ProcessingJob::create(source, thumb->getType() == FT_Raw, pparams); + + int prevh = getMaxThumbnailHeight(); + int prevw = prevh; + thumb->getThumbnailSize (prevw, prevh, &pparams); + + BatchQueueEntry *entry = new BatchQueueEntry(job, pparams,source, prevw, prevh, thumb); + thumb->decreaseRef(); // Removing the refCount acquired by cacheMgr->getEntry + entry->setParent(this); + + // BatchQueueButtonSet HAVE TO be added before resizing to take them into account + BatchQueueButtonSet* bqbs = new BatchQueueButtonSet(entry); + bqbs->setButtonListener(this); + entry->addButtonSet(bqbs); + + //entry->resize(getThumbnailHeight()); + entry->savedParamsFile = paramsFile; + entry->selected = false; + entry->outFileName = outputFile; + if (!outputFile.empty()) { + entry->saveFormat.format = saveFmt; + entry->saveFormat.jpegQuality = jpegQuality; + entry->saveFormat.jpegSubSamp = jpegSubSamp; + entry->saveFormat.pngBits = pngBits; + entry->saveFormat.pngCompression = pngCompression; + entry->saveFormat.tiffBits = tiffBits; + entry->saveFormat.tiffUncompressed = tiffUncompressed!=0; + entry->saveFormat.saveParams = saveParams!=0; + entry->forceFormatOpts = forceFormatOpts!=0; + } + else + entry->forceFormatOpts = false; + fd.push_back(entry); + + numLoaded++; + } + } + } + delete [] buffer; + fclose(f); + } + + redraw(); + notifyListener(false); + + return !fd.empty(); +} + +Glib::ustring BatchQueue::getTempFilenameForParams( const Glib::ustring filename ) +{ + time_t rawtime; + struct tm *timeinfo; + char stringTimestamp [80]; + time ( &rawtime ); + timeinfo = localtime ( &rawtime ); + strftime (stringTimestamp,sizeof(stringTimestamp),"_%Y%m%d%H%M%S_",timeinfo); + Glib::ustring savedParamPath; + savedParamPath = options.rtdir+"/batch/"; + safe_g_mkdir_with_parents (savedParamPath, 0755); + savedParamPath += Glib::path_get_basename (filename); + savedParamPath += stringTimestamp; + savedParamPath += paramFileExtension; + return savedParamPath; +} + +int cancelItemUI (void* data) +{ + safe_g_remove( (static_cast(data))->savedParamsFile ); + delete static_cast(data); + return 0; +} + +void BatchQueue::cancelItems (std::vector* items) { + { + // TODO: Check for Linux + #if PROTECT_VECTORS + MYWRITERLOCK(l, entryRW); + #endif + + for (size_t i=0; isize(); i++) { + BatchQueueEntry* entry = (BatchQueueEntry*)(*items)[i]; + if (entry->processing) + continue; + std::vector::iterator pos = std::find (fd.begin(), fd.end(), entry); + if (pos!=fd.end()) { + fd.erase (pos); + rtengine::ProcessingJob::destroy (entry->job); + if (entry->thumbnail) + entry->thumbnail->imageRemovedFromQueue (); + g_idle_add (cancelItemUI, entry); + } + } + for (size_t i=0; iselected = false; + lastClicked = NULL; + selected.clear (); + } + + saveBatchQueue( ); + + redraw (); + notifyListener (false); +} + +void BatchQueue::headItems (std::vector* items) { + { + // TODO: Check for Linux + #if PROTECT_VECTORS + MYWRITERLOCK(l, entryRW); + #endif + + for (int i=items->size()-1; i>=0; i--) { + BatchQueueEntry* entry = (BatchQueueEntry*)(*items)[i]; + if (entry->processing) + continue; + std::vector::iterator pos = std::find (fd.begin(), fd.end(), entry); + if (pos!=fd.end() && pos!=fd.begin()) { + fd.erase (pos); + // find the first item that is not under processing + for (pos=fd.begin(); pos!=fd.end(); pos++) + if (!(*pos)->processing) { + fd.insert (pos, entry); + break; + } + } + } + } + saveBatchQueue( ); + + redraw (); +} + +void BatchQueue::tailItems (std::vector* items) { + { + // TODO: Check for Linux + #if PROTECT_VECTORS + MYWRITERLOCK(l, entryRW); + #endif + + for (size_t i=0; isize(); i++) { + BatchQueueEntry* entry = (BatchQueueEntry*)(*items)[i]; + if (entry->processing) + continue; + std::vector::iterator pos = std::find (fd.begin(), fd.end(), entry); + if (pos!=fd.end()) { + fd.erase (pos); + fd.push_back (entry); + } + } + } + saveBatchQueue( ); + + redraw (); +} + +void BatchQueue::selectAll () { + { + // TODO: Check for Linux + #if PROTECT_VECTORS + MYWRITERLOCK(l, entryRW); + #endif + + lastClicked = NULL; + selected.clear (); + for (size_t i=0; iprocessing) + continue; + fd[i]->selected = true; + selected.push_back (fd[i]); + } + } + queue_draw (); +} + +void BatchQueue::openLastSelectedItemInEditor() { + { + // TODO: Check for Linux + #if PROTECT_VECTORS + MYREADERLOCK(l, entryRW); + #endif + + if (selected.size() > 0) { + openItemInEditor(selected.back()); + } + } +} + +void BatchQueue::openItemInEditor(ThumbBrowserEntryBase* item) { + if (item) { + std::vector< ::Thumbnail*> requestedItem; + requestedItem.push_back(item->thumbnail); + fileCatalog->openRequested(requestedItem); + } +} + + +void BatchQueue::startProcessing () { + + if (!processing) { + // TODO: Check for Linux + #if PROTECT_VECTORS + MYWRITERLOCK(l, entryRW); + #endif + + if (!fd.empty()) { + BatchQueueEntry* next; + + next = static_cast(fd[0]); + // tag it as processing and set sequence + next->processing = true; + next->sequence = sequence = 1; + processing = next; + // remove from selection + if (processing->selected) { + std::vector::iterator pos = std::find (selected.begin(), selected.end(), processing); + if (pos!=selected.end()) + selected.erase (pos); + processing->selected = false; + } + + #if PROTECT_VECTORS + MYWRITERLOCK_RELEASE(l); + #endif + + // remove button set + next->removeButtonSet (); + + // start batch processing + rtengine::startBatchProcessing (next->job, this, options.tunnelMetaData); + queue_draw (); + } + } +} + +rtengine::ProcessingJob* BatchQueue::imageReady (rtengine::IImage16* img) { + + // save image img + Glib::ustring fname; + SaveFormat saveFormat; + if (processing->outFileName=="") { // auto file name + Glib::ustring s = calcAutoFileNameBase (processing->filename, processing->sequence); + saveFormat = options.saveFormatBatch; + fname = autoCompleteFileName (s, saveFormat.format); + } + else { // use the save-as filename with automatic completion for uniqueness + if (processing->forceFormatOpts) + saveFormat = processing->saveFormat; + else + saveFormat = options.saveFormatBatch; + // The output filename's extension is forced to the current or selected output format, + // despite what the user have set in the fielneame's field of the "Save as" dialgo box + fname = autoCompleteFileName (removeExtension(processing->outFileName), saveFormat.format); + //fname = autoCompleteFileName (removeExtension(processing->outFileName), getExtension(processing->outFileName)); + } + //printf ("fname=%s, %s\n", fname.c_str(), removeExtension(fname).c_str()); + + if (img && fname!="") { + int err = 0; + 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); + else if (saveFormat.format=="jpg") + err = img->saveAsJPEG (fname, saveFormat.jpegQuality, saveFormat.jpegSubSamp); + img->free (); + + if (err) + throw Glib::FileError(Glib::FileError::FAILED, M("MAIN_MSG_CANNOTSAVE")+"\n"+fname); + + if (saveFormat.saveParams) { + // We keep the extension to avoid overwriting the profile when we have + // the same output filename with different extension + //processing->params.save (removeExtension(fname) + paramFileExtension); + processing->params.save (fname + ".out" + paramFileExtension); + } + + if (processing->thumbnail) { + processing->thumbnail->imageDeveloped (); + processing->thumbnail->imageRemovedFromQueue (); + } + } + // save temporary params file name: delete as last thing + Glib::ustring processedParams = processing->savedParamsFile; + + // delete from the queue + bool queueEmptied=false; + bool remove_button_set = false; + + { + // TODO: Check for Linux + #if PROTECT_VECTORS + MYWRITERLOCK(l, entryRW); + #endif + + delete processing; + processing = NULL; + + fd.erase (fd.begin()); + + // return next job + if (fd.empty()) { + queueEmptied=true; + } + else if (listener && listener->canStartNext ()) { + BatchQueueEntry* next = static_cast(fd[0]); + // tag it as selected and set sequence + next->processing = true; + next->sequence = ++sequence; + processing = next; + // remove from selection + if (processing->selected) { + std::vector::iterator pos = std::find (selected.begin(), selected.end(), processing); + if (pos!=selected.end()) + selected.erase (pos); + processing->selected = false; + } + // remove button set + remove_button_set = true; + } + } + if (remove_button_set) { + // ButtonSet have Cairo::Surface which might be rendered while we're trying to delete them + GThreadLock lock; + processing->removeButtonSet (); + } + if (saveBatchQueue( )) { + safe_g_remove( processedParams ); + // Delete all files in directory \batch when finished, just to be sure to remove zombies + + // Not sure that locking is necessary, but it should be safer + // TODO: Check for Linux + #if PROTECT_VECTORS + MYREADERLOCK(l, entryRW); + #endif + if( fd.empty() ){ + #if PROTECT_VECTORS + MYREADERLOCK_RELEASE(l); + #endif + std::vector names; + Glib::ustring batchdir = Glib::build_filename(options.rtdir, "batch"); + Glib::RefPtr dir = Gio::File::create_for_path (batchdir); + safe_build_file_list (dir, names, batchdir); + for(std::vector::iterator iter=names.begin(); iter != names.end();iter++ ) + safe_g_remove( *iter ); + } + } + + redraw (); + notifyListener (queueEmptied); + + return processing ? processing->job : NULL; +} + +// Calculates automatic filename of processed batch entry, but just the base name +// example output: "c:\out\converted\dsc0121" +Glib::ustring BatchQueue::calcAutoFileNameBase (const Glib::ustring& origFileName, int sequence) { + + std::vector pa; + std::vector da; + + for (size_t i=0; i=origFileName.size()) + break; + Glib::ustring tok = ""; + while ((i=0 && origFileName[extpos]!='.'; extpos--); + for (int k=extpos-1; k>=0 && origFileName[k]!='/' && origFileName[k]!='\\'; k--) + filename = origFileName[k] + filename; + +// printf ("%d, |%s|\n", extpos, filename.c_str()); + + // constructing full output path +// printf ("path=|%s|\n", options.savePath.c_str()); + + Glib::ustring path=""; + if (options.saveUsePathTemplate) { + int ix=0; + while (options.savePathTemplate[ix]!=0) { + if (options.savePathTemplate[ix]=='%') { + ix++; + if (options.savePathTemplate[ix]=='p') { + ix++; + int i = options.savePathTemplate[ix]-'0'; + if (i=1 && w<=9) { + ix++; + seqstr << std::setw (w) << std::setfill ('0'); + } + + seqstr << sequence; + path += seqstr.str (); + } + } + + else + path = path + options.savePathTemplate[ix]; + ix++; + } + } + else + path = Glib::build_filename (options.savePathFolder, filename); + + return path; +} + +Glib::ustring BatchQueue::autoCompleteFileName (const Glib::ustring& fileName, const Glib::ustring& format) { + + // separate filename and the path to the destination directory + Glib::ustring dstdir = Glib::path_get_dirname (fileName); + Glib::ustring dstfname = Glib::path_get_basename (fileName); + Glib::ustring fname; + + // create directory, if does not exist + if (safe_g_mkdir_with_parents (dstdir, 0755) ) + return ""; + + // In overwrite mode we TRY to delete the old file first. + // if that's not possible (e.g. locked by viewer, R/O), we revert to the standard naming scheme + bool inOverwriteMode=options.overwriteOutputFile; + + for (int tries=0; tries<100; tries++) { + if (tries==0) + fname = Glib::ustring::compose ("%1.%2", Glib::build_filename (dstdir, dstfname), format); + else + fname = Glib::ustring::compose ("%1-%2.%3", Glib::build_filename (dstdir, dstfname), tries, format); + + int fileExists=safe_file_test (fname, Glib::FILE_TEST_EXISTS); + + if (inOverwriteMode && fileExists) { + if (safe_g_remove(fname) == -1) + inOverwriteMode = false; // failed to delete- revert to old naming scheme + else + fileExists = false; // deleted now + } + + if (!fileExists) { + return fname; + } + } + return ""; +} + +int setProgressUI (void* p) { + (static_cast(p))->redraw(); + return 0; +} + +void BatchQueue::setProgress (double p) { + + if (processing) + processing->progress = p; + + // No need to acquire the GUI, setProgressUI will do it + g_idle_add (setProgressUI, this); +} + +void BatchQueue::buttonPressed (LWButton* button, int actionCode, void* actionData) { + + std::vector bqe; + bqe.push_back (static_cast(actionData)); + + if (actionCode==10) // cancel + cancelItems (&bqe); + else if (actionCode==8) // to head + headItems (&bqe); + else if (actionCode==9) // to tail + tailItems (&bqe); +} + +struct NLParams { + BatchQueueListener* listener; + int qsize; + bool queueEmptied; + bool queueError; + Glib::ustring queueErrorMessage; +}; + +int bqnotifylistenerUI (void* data) { + GThreadLock lock; // All GUI acces from idle_add callbacks or separate thread HAVE to be protected + NLParams* params = static_cast(data); + params->listener->queueSizeChanged (params->qsize, params->queueEmptied, params->queueError, params->queueErrorMessage); + delete params; + return 0; +} + +void BatchQueue::notifyListener (bool queueEmptied) { + + if (listener) { + NLParams* params = new NLParams; + params->listener = listener; + { + // TODO: Check for Linux + #if PROTECT_VECTORS + MYREADERLOCK(l, entryRW); + #endif + params->qsize = fd.size(); + } + params->queueEmptied = queueEmptied; + params->queueError = false; + g_idle_add (bqnotifylistenerUI, params); + } +} + +void BatchQueue::redrawNeeded (LWButton* button) { + GThreadLock lock; + queue_draw (); +} + +void BatchQueue::error (Glib::ustring msg) { + + if (processing && processing->processing) { + // restore failed thumb + BatchQueueButtonSet* bqbs = new BatchQueueButtonSet (processing); + bqbs->setButtonListener (this); + processing->addButtonSet (bqbs); + processing->processing = false; + processing->job = rtengine::ProcessingJob::create(processing->filename, processing->thumbnail->getType() == FT_Raw, processing->params); + processing = NULL; + redraw (); + } + if (listener) { + NLParams* params = new NLParams; + params->listener = listener; + params->queueEmptied = false; + params->queueError = true; + params->queueErrorMessage = msg; + g_idle_add (bqnotifylistenerUI, params); + } +} diff --git a/rtgui/batchqueue.h b/rtgui/batchqueue.h new file mode 100755 index 000000000..f515bed29 --- /dev/null +++ b/rtgui/batchqueue.h @@ -0,0 +1,110 @@ +/* + * This file is part of RawTherapee. + * + * + * 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 _BATCHQUEUE_ +#define _BATCHQUEUE_ + +#include +#include "threadutils.h" +#include "batchqueueentry.h" +#include "../rtengine/rtengine.h" +#include "options.h" +#include "lwbuttonset.h" +#include "thumbbrowserbase.h" + +class BatchQueueListener { + + public: + virtual ~BatchQueueListener () {} + virtual void queueSizeChanged (int qsize, bool queueEmptied, bool queueError, Glib::ustring queueErrorMessage) =0; + virtual bool canStartNext () =0; +}; + +class FileCatalog; +class BatchQueue : public ThumbBrowserBase, + public rtengine::BatchProcessingListener, + public LWButtonListener { + + protected: + int getMaxThumbnailHeight() const; + void saveThumbnailHeight (int height); + int getThumbnailHeight (); + + BatchQueueEntry* processing; // holds the currently processed image + FileCatalog* fileCatalog; + int sequence; // holds the current sequence index + + Glib::ustring nameTemplate; + + Gtk::ImageMenuItem* cancel; + Gtk::ImageMenuItem* head; + Gtk::ImageMenuItem* tail; + Gtk::MenuItem* selall; + Gtk::MenuItem* open; + Gtk::Menu* pmenu; + + Glib::RefPtr pmaccelgroup; + + BatchQueueListener* listener; + + Glib::ustring autoCompleteFileName (const Glib::ustring& fileName, const Glib::ustring& format); + Glib::ustring getTempFilenameForParams( const Glib::ustring filename ); + bool saveBatchQueue( ); + void notifyListener (bool queueEmptied); + + public: + BatchQueue (FileCatalog* aFileCatalog); + ~BatchQueue (); + + void addEntries (std::vector &entries, bool head=false, bool save=true); + void cancelItems (std::vector* items); + void headItems (std::vector* items); + void tailItems (std::vector* items); + void selectAll (); + void openItemInEditor(ThumbBrowserEntryBase* item); + void openLastSelectedItemInEditor(); + + void startProcessing (); + + bool hasJobs () { + // not sure that this lock is necessary, but it's safer to keep it... + // TODO: Check for Linux + #if PROTECT_VECTORS + MYREADERLOCK(l, entryRW); + #endif + return (!fd.empty()); + } + + rtengine::ProcessingJob* imageReady (rtengine::IImage16* img); + void error (Glib::ustring msg); + void setProgress (double p); + void rightClicked (ThumbBrowserEntryBase* entry); + void doubleClicked (ThumbBrowserEntryBase* entry); + bool keyPressed (GdkEventKey* event); + void buttonPressed (LWButton* button, int actionCode, void* actionData); + void redrawNeeded (LWButton* button); + + void setBatchQueueListener (BatchQueueListener* l) { listener = l; } + + bool loadBatchQueue (); + void resizeLoadedQueue(); + + static Glib::ustring calcAutoFileNameBase (const Glib::ustring& origFileName, int sequence = 0); + static int calcMaxThumbnailHeight(); +}; + +#endif diff --git a/rtgui/batchqueuebuttonset.cc b/rtgui/batchqueuebuttonset.cc new file mode 100644 index 000000000..f3079a62b --- /dev/null +++ b/rtgui/batchqueuebuttonset.cc @@ -0,0 +1,43 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "batchqueuebuttonset.h" +#include "multilangmgr.h" +#include "../rtengine/safegtk.h" + +extern Glib::ustring argv0; + +bool BatchQueueButtonSet::iconsLoaded = false; + +Cairo::RefPtr BatchQueueButtonSet::cancelIcon; +Cairo::RefPtr BatchQueueButtonSet::headIcon; +Cairo::RefPtr BatchQueueButtonSet::tailIcon; + +BatchQueueButtonSet::BatchQueueButtonSet (BatchQueueEntry* myEntry) { + + if (!iconsLoaded) { + cancelIcon = safe_create_from_png ("gtk-close.png"); + headIcon = safe_create_from_png ("toleftend.png"); + tailIcon = safe_create_from_png ("torightend.png"); + iconsLoaded = true; + } + + add (new LWButton (headIcon, 8, myEntry, LWButton::Left, LWButton::Center, M("FILEBROWSER_POPUPMOVEHEAD"))); + add (new LWButton (tailIcon, 9, myEntry, LWButton::Left, LWButton::Center, M("FILEBROWSER_POPUPMOVEEND"))); + add (new LWButton (cancelIcon, 10, myEntry, LWButton::Right, LWButton::Center, M("FILEBROWSER_POPUPCANCELJOB"))); +} diff --git a/rtgui/batchqueuebuttonset.h b/rtgui/batchqueuebuttonset.h new file mode 100644 index 000000000..bd43b5657 --- /dev/null +++ b/rtgui/batchqueuebuttonset.h @@ -0,0 +1,38 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _BATCHQUEUEBUTTONSET_ +#define _BATCHQUEUEBUTTONSET_ + +#include "lwbuttonset.h" +#include + +class BatchQueueEntry; +class BatchQueueButtonSet : public LWButtonSet { + + static bool iconsLoaded; + + public: + static Cairo::RefPtr cancelIcon; + static Cairo::RefPtr headIcon; + static Cairo::RefPtr tailIcon; + + BatchQueueButtonSet (BatchQueueEntry* myEntry); +}; + +#endif diff --git a/rtgui/batchqueueentry.cc b/rtgui/batchqueueentry.cc new file mode 100644 index 000000000..3728b3bd3 --- /dev/null +++ b/rtgui/batchqueueentry.cc @@ -0,0 +1,236 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "batchqueueentry.h" +#include "thumbbrowserbase.h" + +#include +#include "guiutils.h" +#include "threadutils.h" +#include "../rtengine/safegtk.h" +#include "multilangmgr.h" + +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(NULL), origpw(prevw), origph(prevh), opreviewDone(false), + job(pjob), progress(0), outFileName(""), sequence(0), forceFormatOpts(false) { + + thumbnail=thm; + params = pparams; + + #if 1 //ndef WIN32 + // The BatchQueueEntryIdleHelper tracks if an entry has been deleted while it was sitting waiting for "idle" + bqih = new BatchQueueEntryIdleHelper; + bqih->bqentry = this; + bqih->destroyed = false; + bqih->pending = 0; + #endif + + if (!iconsLoaded) { + savedAsIcon = safe_create_from_file ("gtk-save.png"); + iconsLoaded = true; + } + + if (thumbnail) + thumbnail->increaseRef (); +} + +BatchQueueEntry::~BatchQueueEntry () { + + batchQueueEntryUpdater.removeJobs (this); + if (opreview) delete [] opreview; opreview=NULL; + if (thumbnail) + thumbnail->decreaseRef (); + + if (bqih->pending) + bqih->destroyed = true; + else + delete bqih; +} + +void BatchQueueEntry::refreshThumbnailImage () { + + if (!opreviewDone) { + // creating the image buffer first + //if (!opreview) opreview = new guint8[(origpw+1) * origph * 3]; + // this will asynchronously compute the original preview and land at this.updateImage + batchQueueEntryUpdater.process (NULL, origpw, origph, preh, this, ¶ms, thumbnail); + } + else { + // this will asynchronously land at this.updateImage + batchQueueEntryUpdater.process (opreview, origpw, origph, preh, this); + } +} + +void BatchQueueEntry::calcThumbnailSize () { + + prew = preh * origpw / origph; +} + + +void BatchQueueEntry::drawProgressBar (Glib::RefPtr win, Glib::RefPtr gc, const Gdk::Color& foregr, const Gdk::Color& backgr, int x, int w, int y, int h) { + + if (processing) { + Cairo::RefPtr cr = win->create_cairo_context(); + cr->set_antialias (Cairo::ANTIALIAS_SUBPIXEL); + double px = x + w/6.0; + double pw = w*2.0/3.0; + double py = y + h/4.0; + double ph = h/2.0; + cr->move_to (px, py); + cr->line_to (px+pw, py); + cr->set_line_width (ph); + cr->set_line_cap (Cairo::LINE_CAP_ROUND); + cr->set_source_rgb (foregr.get_red_p(), foregr.get_green_p(), foregr.get_blue_p()); + cr->stroke (); + + cr->move_to (px, py); + cr->line_to (px+pw, py); + cr->set_line_width (ph*3.0/4.0); + cr->set_source_rgb (backgr.get_red_p(), backgr.get_green_p(), backgr.get_blue_p()); + cr->stroke (); + + cr->move_to (px, py); + cr->line_to (px+pw*progress, py); + cr->set_line_width (ph/2.0); + cr->set_source_rgb (foregr.get_red_p(), foregr.get_green_p(), foregr.get_blue_p()); + cr->stroke (); + } +} + +void BatchQueueEntry::removeButtonSet () { + + delete buttonSet; + buttonSet = NULL; +} + +std::vector > BatchQueueEntry::getIconsOnImageArea () { + + std::vector > ret; + + if (!outFileName.empty()) + ret.push_back (savedAsIcon); + + return ret; +} + +void BatchQueueEntry::getIconSize (int& w, int& h) { + + w = savedAsIcon->get_width (); + h = savedAsIcon->get_height (); +} + + +Glib::ustring BatchQueueEntry::getToolTip (int x, int y) { + // get the parent class' tooltip first + Glib::ustring tooltip = ThumbBrowserEntryBase::getToolTip(x, y); + + // add the saving param options + if (!outFileName.empty()) { + tooltip += Glib::ustring::compose("\n\n%1: %2", M("BATCHQUEUE_DESTFILENAME"), outFileName); + if (forceFormatOpts) { + tooltip += Glib::ustring::compose("\n\n%1: %2 (%3 bits)", M("SAVEDLG_FILEFORMAT"), saveFormat.format, + saveFormat.format == "png" ? saveFormat.pngBits : + saveFormat.format == "tif" ? saveFormat.tiffBits : 8); + if (saveFormat.format == "jpg") { + tooltip += Glib::ustring::compose("\n%1: %2\n%3: %4", + M("SAVEDLG_JPEGQUAL"), saveFormat.jpegQuality, + M("SAVEDLG_SUBSAMP"), + 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")); + } + } + } + + return tooltip; + +} + +struct BQUpdateParam { + BatchQueueEntryIdleHelper* bqih; + guint8* img; + int w,h; +}; + +int updateImageUIThread (void* data) { + + BQUpdateParam* params = static_cast(data); + + BatchQueueEntryIdleHelper* bqih = params->bqih; + + GThreadLock tLock; // Acquire the GUI + + // If the BQEntry was destroyed meanwhile, remove all the IdleHelper if all entries came through + if (bqih->destroyed) { + if (bqih->pending == 1) + delete bqih; + else + bqih->pending--; + delete [] params->img; + delete params; + + return 0; + } + + bqih->bqentry->_updateImage (params->img, params->w, params->h); + bqih->pending--; + + delete params; + return 0; +} + +// Starts a copy of img->preview via GTK thread +void BatchQueueEntry::updateImage (guint8* img, int w, int h, int origw, int origh, guint8* newOPreview) { + + // since the update itself is already called in an async thread and there are problem with accessing opreview in thumbbrowserbase, + // it's safer to do this synchronously + { + GThreadLock lock; + + _updateImage(img,w,h); + } +} + +void BatchQueueEntry::_updateImage (guint8* img, int w, int h) { + + if (preh == h) { + + #if PROTECT_VECTORS + MYWRITERLOCK(l, lockRW); + #endif + + prew = w; + assert (preview == NULL); + preview = new guint8 [prew*preh*3]; + memcpy (preview, img, prew*preh*3); + if (parent) + parent->redrawNeeded (this); + } + delete [] img; +} + diff --git a/rtgui/batchqueueentry.h b/rtgui/batchqueueentry.h new file mode 100644 index 000000000..7c2b360ce --- /dev/null +++ b/rtgui/batchqueueentry.h @@ -0,0 +1,77 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _BATCHQUEUEENTRY_ +#define _BATCHQUEUEENTRY_ + +#include +#include "../rtengine/rtengine.h" +#include "thumbbrowserentrybase.h" +#include "thumbnail.h" +#include "bqentryupdater.h" + +class BatchQueueEntry; +struct BatchQueueEntryIdleHelper { + BatchQueueEntry* bqentry; + bool destroyed; + int pending; +}; + +class BatchQueueEntry : public ThumbBrowserEntryBase, public BQEntryUpdateListener { + + guint8* opreview; + int origpw, origph; + BatchQueueEntryIdleHelper* bqih; + bool opreviewDone; + static bool iconsLoaded; + +public: + + static Glib::RefPtr savedAsIcon; + + rtengine::ProcessingJob* job; + rtengine::procparams::ProcParams params; + Glib::ustring savedParamsFile; + double progress; + Glib::ustring outFileName; + int sequence; + SaveFormat saveFormat; + bool forceFormatOpts; + + BatchQueueEntry (rtengine::ProcessingJob* job, const rtengine::procparams::ProcParams& pparams, Glib::ustring fname, int prevw, int prevh, Thumbnail* thm=NULL); + ~BatchQueueEntry (); + + void refreshThumbnailImage (); + void calcThumbnailSize (); + + void drawProgressBar (Glib::RefPtr win, Glib::RefPtr gc, const Gdk::Color& foregr, const Gdk::Color& backgr, int x, int w, int y, int h); + + void removeButtonSet (); + + virtual std::vector > getIconsOnImageArea (); + virtual void getIconSize (int& w, int& h); + virtual Glib::ustring getToolTip (int x, int y); + + // bqentryupdatelistener interface + void updateImage (guint8* img, int w, int h, int origw, int origh, guint8* newOPreview); + void _updateImage (guint8* img, int w, int h); // inside gtk thread +}; + + + +#endif diff --git a/rtgui/batchqueuepanel.cc b/rtgui/batchqueuepanel.cc new file mode 100644 index 000000000..216309c89 --- /dev/null +++ b/rtgui/batchqueuepanel.cc @@ -0,0 +1,347 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "batchqueuepanel.h" +#include "options.h" +#include "preferences.h" +#include "multilangmgr.h" +#include "rtwindow.h" +#include "soundman.h" +#include "../rtengine/safegtk.h" +#include "rtimage.h" + +struct BQProcessLoaded { + BatchQueue* bq; +}; + +int processLoadedBatchQueueUIThread (void* data) { + + BatchQueue* bq = static_cast(data); + bq->resizeLoadedQueue(); + return 0; +} + +static Glib::ustring makeFolderLabel(Glib::ustring path) +{ + if (!safe_file_test (path, Glib::FILE_TEST_IS_DIR)) + return "(" + M("GENERAL_NONE") + ")"; + if (path.size() > 40) { + size_t last_ds = path.find_last_of (G_DIR_SEPARATOR); + if (last_ds != Glib::ustring::npos && last_ds > 10) { + path = "..." + path.substr(last_ds); + } + } + return path; +} + +BatchQueuePanel::BatchQueuePanel (FileCatalog* aFileCatalog) { + + batchQueue = Gtk::manage( new BatchQueue(aFileCatalog) ); + + // construct batch queue panel with the extra "start" and "stop" button + Gtk::VBox* batchQueueButtonBox = Gtk::manage (new Gtk::VBox); + start = Gtk::manage (new Gtk::ToggleButton (M("FILEBROWSER_STARTPROCESSING"))); + stop = Gtk::manage (new Gtk::ToggleButton (M("FILEBROWSER_STOPPROCESSING"))); + autoStart = Gtk::manage (new Gtk::CheckButton (M("BATCHQUEUE_AUTOSTART"))); + start->set_tooltip_markup (M("FILEBROWSER_STARTPROCESSINGHINT")); + stop->set_tooltip_markup (M("FILEBROWSER_STOPPROCESSINGHINT")); + autoStart->set_tooltip_text (M("FILEBROWSER_TOOLTIP_STOPPROCESSING")); + start->set_active (false); + stop->set_active (true); + autoStart->set_active (options.procQueueEnabled); + + start->set_image (*Gtk::manage (new RTImage ("gtk-media-play.png"))); + startConnection = start->signal_toggled().connect (sigc::mem_fun(*this, &BatchQueuePanel::startBatchProc)); + stop->set_image (*Gtk::manage (new RTImage ("gtk-media-stop.png"))); + stopConnection = stop->signal_toggled().connect (sigc::mem_fun(*this, &BatchQueuePanel::stopBatchProc)); + batchQueueButtonBox->pack_start (*start, Gtk::PACK_SHRINK, 4); + batchQueueButtonBox->pack_start (*stop, Gtk::PACK_SHRINK, 4); + batchQueueButtonBox->pack_start (*autoStart, Gtk::PACK_SHRINK, 4); + + // Output directory selection + fdir = Gtk::manage (new Gtk::Frame (M("PREFERENCES_OUTDIR"))); + Gtk::VBox* odvb = Gtk::manage (new Gtk::VBox ()); + odvb->set_border_width (4); + Gtk::HBox* hb2 = Gtk::manage (new Gtk::HBox ()); + useTemplate = Gtk::manage (new Gtk::RadioButton (M("PREFERENCES_OUTDIRTEMPLATE")+":")); + hb2->pack_start (*useTemplate, Gtk::PACK_SHRINK,4); + outdirTemplate = Gtk::manage (new Gtk::Entry ()); + hb2->pack_start (*outdirTemplate); + odvb->pack_start (*hb2, Gtk::PACK_SHRINK, 4); + outdirTemplate->set_tooltip_markup (M("PREFERENCES_OUTDIRTEMPLATEHINT")); + useTemplate->set_tooltip_markup (M("PREFERENCES_OUTDIRTEMPLATEHINT")); + Gtk::HBox* hb3 = Gtk::manage (new Gtk::HBox ()); + useFolder = Gtk::manage (new Gtk::RadioButton (M("PREFERENCES_OUTDIRFOLDER")+":")); + hb3->pack_start (*useFolder, Gtk::PACK_SHRINK,4); + +#if defined(__APPLE__) || defined(__linux__) + // At the time of writing (2013-11-11) the gtkmm FileChooserButton with ACTION_SELECT_FOLDER + // is so buggy on these platforms (OS X and Linux) that we rather employ this ugly button hack. + // When/if GTKMM gets fixed we can go back to use the FileChooserButton, like we do on Windows. + outdirFolderButton = Gtk::manage (new Gtk::Button("(" + M("GENERAL_NONE") + ")")); + outdirFolderButton->set_alignment(0.0, 0.0); + hb3->pack_start (*outdirFolderButton); + outdirFolderButton->signal_pressed().connect( sigc::mem_fun(*this, &BatchQueuePanel::pathFolderButtonPressed) ); + outdirFolderButton->set_tooltip_markup (M("PREFERENCES_OUTDIRFOLDERHINT")); + outdirFolderButton->set_label(makeFolderLabel(options.savePathFolder)); + Gtk::Image* folderImg = Gtk::manage (new Gtk::Image (Gtk::Stock::DIRECTORY, Gtk::ICON_SIZE_MENU)); + folderImg->show (); + outdirFolderButton->set_image (*folderImg); + outdirFolder = 0; +#else + outdirFolder = Gtk::manage (new MyFileChooserButton (M("PREFERENCES_OUTDIRFOLDER"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); + hb3->pack_start (*outdirFolder); + outdirFolder->signal_current_folder_changed().connect (sigc::mem_fun(*this, &BatchQueuePanel::pathFolderChanged)); + outdirFolder->set_tooltip_markup (M("PREFERENCES_OUTDIRFOLDERHINT")); + if (safe_file_test (options.savePathFolder, Glib::FILE_TEST_IS_DIR)) + outdirFolder->set_current_folder (options.savePathFolder); + outdirFolderButton = 0; +#endif + + odvb->pack_start (*hb3, Gtk::PACK_SHRINK, 4); + useFolder->set_tooltip_markup (M("PREFERENCES_OUTDIRFOLDERHINT")); + Gtk::RadioButton::Group g = useTemplate->get_group(); + useFolder->set_group (g); + fdir->add (*odvb); + + // Output file format selection + fformat = Gtk::manage (new Gtk::Frame (M("PREFERENCES_FILEFORMAT"))); + saveFormatPanel = Gtk::manage (new SaveFormatPanel ()); + fformat->add (*saveFormatPanel); + + saveFormatPanel->init (options.saveFormatBatch); + outdirTemplate->set_text (options.savePathTemplate); + useTemplate->set_active (options.saveUsePathTemplate); + useFolder->set_active (!options.saveUsePathTemplate); + + // setup signal handlers + outdirTemplate->signal_changed().connect (sigc::mem_fun(*this, &BatchQueuePanel::saveOptions)); + useTemplate->signal_toggled().connect (sigc::mem_fun(*this, &BatchQueuePanel::saveOptions)); + useFolder->signal_toggled().connect (sigc::mem_fun(*this, &BatchQueuePanel::saveOptions)); + saveFormatPanel->setListener (this); + + // setup button bar + topBox = Gtk::manage (new Gtk::HBox ()); + pack_start (*topBox, Gtk::PACK_SHRINK); + + topBox->pack_start (*batchQueueButtonBox, Gtk::PACK_SHRINK, 4); + topBox->pack_start (*fdir); + topBox->pack_start (*fformat, Gtk::PACK_SHRINK, 4); + + // add middle browser area + pack_start (*batchQueue); + + // lower box with thumbnail zoom + bottomBox = Gtk::manage (new Gtk::HBox ()); + pack_start (*bottomBox, Gtk::PACK_SHRINK); + + // thumbnail zoom + Gtk::HBox* zoomBox = Gtk::manage (new Gtk::HBox ()); + zoomBox->pack_start (*Gtk::manage (new Gtk::VSeparator), Gtk::PACK_SHRINK, 4); + Gtk::Label* zoomLabel = Gtk::manage (new Gtk::Label (Glib::ustring("")+M("FILEBROWSER_THUMBSIZE")+":")); + zoomLabel->set_use_markup (true); + zoomBox->pack_start (*zoomLabel, Gtk::PACK_SHRINK, 4); + zoomInButton = Gtk::manage (new Gtk::Button ()); + zoomInButton->set_image (*Gtk::manage (new RTImage ("gtk-zoom-in.png"))); + zoomInButton->signal_pressed().connect (sigc::mem_fun(*batchQueue, &BatchQueue::zoomIn)); + zoomInButton->set_relief (Gtk::RELIEF_NONE); + zoomInButton->set_tooltip_markup (M("FILEBROWSER_ZOOMINHINT")); + zoomBox->pack_end (*zoomInButton, Gtk::PACK_SHRINK); + zoomOutButton = Gtk::manage (new Gtk::Button ()); + zoomOutButton->set_image (*Gtk::manage (new RTImage ("gtk-zoom-out.png"))); + zoomOutButton->signal_pressed().connect (sigc::mem_fun(*batchQueue, &BatchQueue::zoomOut)); + zoomOutButton->set_relief (Gtk::RELIEF_NONE); + zoomOutButton->set_tooltip_markup (M("FILEBROWSER_ZOOMOUTHINT")); + zoomBox->pack_end (*zoomOutButton, Gtk::PACK_SHRINK); + bottomBox->pack_end (*zoomBox, Gtk::PACK_SHRINK); + + + batchQueue->setBatchQueueListener (this); + + show_all (); + if (batchQueue->loadBatchQueue ()) { + g_idle_add_full (G_PRIORITY_LOW, processLoadedBatchQueueUIThread, batchQueue, NULL); + } +} + +// it is expected to have a non null forceOrientation value on Preferences update only. In this case, qsize is ingored and computed automatically +void BatchQueuePanel::updateTab (int qsize, int forceOrientation) +{ + Gtk::Notebook *nb =(Gtk::Notebook *)(this->get_parent()); + + if (forceOrientation > 0) + qsize = batchQueue->getEntries().size(); + + if ((forceOrientation==0 && options.mainNBVertical) || (forceOrientation==2)) { + Gtk::VBox* vbb = Gtk::manage (new Gtk::VBox ()); + Gtk::Label* l; + + if(!qsize ){ + vbb->pack_start (*Gtk::manage (new RTImage ("processing.png"))); + l=Gtk::manage (new Gtk::Label (Glib::ustring(" ") + M("MAIN_FRAME_BATCHQUEUE")) ); + } else if( start->get_active () ){ + vbb->pack_start (*Gtk::manage (new RTImage ("processing-play.png"))); + l=Gtk::manage (new Gtk::Label (Glib::ustring(" ") + M("MAIN_FRAME_BATCHQUEUE")+" [" +Glib::ustring::format( qsize )+"]")); + } else { + vbb->pack_start (*Gtk::manage (new RTImage ("processing-pause.png"))); + l=Gtk::manage (new Gtk::Label (Glib::ustring(" ") + M("MAIN_FRAME_BATCHQUEUE")+" [" +Glib::ustring::format( qsize )+"]" )); + } + l->set_angle (90); + vbb->pack_start (*l); + vbb->set_spacing (2); + vbb->set_tooltip_markup (M("MAIN_FRAME_BATCHQUEUE_TOOLTIP")); + vbb->show_all (); + nb->set_tab_label(*this,*vbb); + } else { + Gtk::HBox* hbb = Gtk::manage (new Gtk::HBox ()); + if (!qsize ) { + hbb->pack_start (*Gtk::manage (new RTImage ("processing.png"))); + hbb->pack_start (*Gtk::manage (new Gtk::Label (M("MAIN_FRAME_BATCHQUEUE") ))); + } else if ( start->get_active () ){ + hbb->pack_start (*Gtk::manage (new RTImage ("processing-play.png"))); + hbb->pack_start (*Gtk::manage (new Gtk::Label (M("MAIN_FRAME_BATCHQUEUE")+" [" +Glib::ustring::format( qsize )+"]" ))); + } else { + hbb->pack_start (*Gtk::manage (new RTImage ("processing-pause.png"))); + hbb->pack_start (*Gtk::manage (new Gtk::Label (M("MAIN_FRAME_BATCHQUEUE")+" [" +Glib::ustring::format( qsize )+"]" ))); + } + hbb->set_spacing (2); + hbb->set_tooltip_markup (M("MAIN_FRAME_BATCHQUEUE_TOOLTIP")); + hbb->show_all (); + nb->set_tab_label(*this,*hbb); + } +} + +void BatchQueuePanel::queueSizeChanged (int qsize, bool queueEmptied, bool queueError, Glib::ustring queueErrorMessage) +{ + updateTab ( qsize); + + if (queueEmptied || queueError) { + stopBatchProc (); + fdir->set_sensitive (true); + fformat->set_sensitive (true); + + SoundManager::playSoundAsync(options.sndBatchQueueDone); + } + if (queueError) { + Gtk::MessageDialog msgd (queueErrorMessage, true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); + msgd.run (); + } +} + +void BatchQueuePanel::startBatchProc () { + + stopConnection.block (true); + startConnection.block (true); + stop->set_active (false); + start->set_active (true); + stopConnection.block (false); + startConnection.block (false); + + if (batchQueue->hasJobs()) { + fdir->set_sensitive (false); + fformat->set_sensitive (false); + saveOptions(); + batchQueue->startProcessing (); + } + else + stopBatchProc (); + + updateTab (batchQueue->getEntries().size()); +} + +void BatchQueuePanel::stopBatchProc () { + + stopConnection.block (true); + startConnection.block (true); + stop->set_active (true); + start->set_active (false); + stopConnection.block (false); + startConnection.block (false); + updateTab (batchQueue->getEntries().size()); +} + +void BatchQueuePanel::addBatchQueueJobs ( std::vector &entries, bool head) { + + batchQueue->addEntries (entries, head); + + if (stop->get_active () && autoStart->get_active ()) + startBatchProc (); +} + +bool BatchQueuePanel::canStartNext () { + + if (start->get_active ()) + return true; + else { + fdir->set_sensitive (true); + fformat->set_sensitive (true); + return false; + } +} + +void BatchQueuePanel::saveOptions () { + + options.savePathTemplate = outdirTemplate->get_text(); + options.saveUsePathTemplate = useTemplate->get_active(); + options.procQueueEnabled = autoStart->get_active (); +} + +void BatchQueuePanel::pathFolderButtonPressed () { + + Gtk::FileChooserDialog fc(M("PREFERENCES_OUTDIRFOLDER"),Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER ); + fc.add_button( Gtk::StockID("gtk-cancel"), Gtk::RESPONSE_CANCEL); + fc.add_button( Gtk::StockID("gtk-ok"), Gtk::RESPONSE_OK); + fc.set_filename(options.savePathFolder); + fc.set_transient_for(*parent); + int result = fc.run(); + if (result == Gtk::RESPONSE_OK) { + if (safe_file_test(fc.get_current_folder(), Glib::FILE_TEST_IS_DIR)) { + options.savePathFolder = fc.get_current_folder(); + outdirFolderButton->set_label(makeFolderLabel(options.savePathFolder)); + } + } +} + +// We only want to save the following when it changes, +// since these settings are shared with editorpanel : +void BatchQueuePanel::pathFolderChanged () { + + options.savePathFolder = outdirFolder->get_current_folder(); +} + +void BatchQueuePanel::formatChanged (Glib::ustring f) { + + options.saveFormatBatch = saveFormatPanel->getFormat (); + +} + +bool BatchQueuePanel::handleShortcutKey (GdkEventKey* event) { + bool ctrl = event->state & GDK_CONTROL_MASK; + if (ctrl){ + switch(event->keyval) { + case GDK_s: + if (start->get_active()) { + stopBatchProc(); + } else { + startBatchProc(); + } + return true; + } + } + return batchQueue->keyPressed (event); +} diff --git a/rtgui/batchqueuepanel.h b/rtgui/batchqueuepanel.h new file mode 100644 index 000000000..55aad806a --- /dev/null +++ b/rtgui/batchqueuepanel.h @@ -0,0 +1,79 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _BATCHQUEUEPANEL_ +#define _BATCHQUEUEPANEL_ + +#include +#include "batchqueue.h" +#include "saveformatpanel.h" +#include "guiutils.h" + +class RTWindow; +class FileCatalog; +class Thumbnail; +class BatchQueuePanel : public Gtk::VBox, + public BatchQueueListener, + public FormatChangeListener { + + Gtk::Button* zoomInButton; + Gtk::Button* zoomOutButton; + Gtk::ToggleButton* start; + Gtk::ToggleButton* stop; + Gtk::CheckButton* autoStart; + sigc::connection startConnection; + sigc::connection stopConnection; + + Gtk::Entry* outdirTemplate; + MyFileChooserButton* outdirFolder; + Gtk::Button* outdirFolderButton; + Gtk::RadioButton* useTemplate; + Gtk::RadioButton* useFolder; + SaveFormatPanel* saveFormatPanel; + Gtk::Frame *fdir, *fformat; + + RTWindow* parent; + BatchQueue* batchQueue; + Gtk::HBox* bottomBox; + Gtk::HBox* topBox; + + public: + + BatchQueuePanel (FileCatalog* aFileCatalog); + + void setParent (RTWindow* p) { parent = p; } + + void addBatchQueueJobs (std::vector &entries , bool head=false); + + // batchqueuelistener interface + void queueSizeChanged (int qsize, bool queueEmptied, bool queueError, Glib::ustring queueErrorMessage); + bool canStartNext (); + + void startBatchProc (); + void stopBatchProc (); + + void saveOptions (); + void pathFolderChanged (); + void pathFolderButtonPressed (); + void formatChanged (Glib::ustring f); + void updateTab (int qsize, int forceOrientation=0); // forceOrientation=0: base on options / 1: horizontal / 2: vertical + + bool handleShortcutKey (GdkEventKey* event); +}; +#endif + diff --git a/rtgui/batchtoolpanelcoord.cc b/rtgui/batchtoolpanelcoord.cc new file mode 100644 index 000000000..da07baff2 --- /dev/null +++ b/rtgui/batchtoolpanelcoord.cc @@ -0,0 +1,634 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "multilangmgr.h" +#include "batchtoolpanelcoord.h" +#include "options.h" +#include "filepanel.h" +#include "procparamchangers.h" +#include "addsetids.h" + +using namespace rtengine::procparams; + +BatchToolPanelCoordinator::BatchToolPanelCoordinator (FilePanel* parent) : ToolPanelCoordinator(), 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); + toolPanelNotebook->remove_page (*metadataPanel); + metadataPanel = 0; + toiM = 0; + + for (size_t i=0; isetBatchMode (true); +} + +void BatchToolPanelCoordinator::selectionChanged (const std::vector& selected) { + + if (selected!=this->selected) { + closeSession (); + this->selected = selected; + selFileNames.clear (); + for (size_t i=0; igetFileName ()); + initSession (); + } +} + +void BatchToolPanelCoordinator::closeSession (bool save) { + + pparamsEdited.set (false); + + for (size_t i=0; iremoveThumbnailListener (this); + + if (somethingChanged && save) { + + // read new values from the gui + for (size_t i=0; iwrite (&pparams, &pparamsEdited); + + // combine with initial parameters and set + ProcParams newParams; + for (size_t i=0; itrimValues (&newParams); + + selected[i]->setProcParams (newParams, NULL, BATCHEDITOR, true); + } + } + for (size_t i=0; iclearParamChanges (); +} + +void BatchToolPanelCoordinator::initSession () { + + somethingChanged = false; + + initialPP.resize (selected.size()); + for (size_t i=0; igetProcParams (); + selected[i]->applyAutoExp (initialPP[i]); + selected[i]->addThumbnailListener (this); + } + + // compare all the ProcParams and describe which parameters has different (i.e. inconsistent) values in pparamsEdited + pparamsEdited.initFrom (initialPP); + + crop->setDimensions (100000, 100000); + +/* if (!selected.empty()) { + pparams = selected[0]->getProcParams (); + for (int i=0; isetDefaults (&pparams, &pparamsEdited); + toolPanels[i]->read (&pparams, &pparamsEdited); + } + for (int i=0; iprocParamsChanged (&pparams, rtengine::EvPhotoLoaded, "batch processing", &pparamsEdited); + } +*/ + + if (!selected.empty()) { + + // The first selected image (in the thumbnail list, not the click list) is used to populate the EditorPanel and set the default values + pparams = selected[0]->getProcParams (); + + coarse->initBatchBehavior (); + + if (selected.size()==1) { + + for (size_t i=0; isetMultiImage(false); + + toneCurve->setAdjusterBehavior (false, false, false, false, false, false, false, false); + lcurve->setAdjusterBehavior (false, false, false); + whitebalance->setAdjusterBehavior (false, false, false); + vibrance->setAdjusterBehavior (false, false); + vignetting->setAdjusterBehavior (false, false, false, false); + colorappearance->setAdjusterBehavior (false, false, false, false, false, false, false, false, false, false, false, false, false); + rotate->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); + sharpenEdge->setAdjusterBehavior (false, false); + sharpenMicro->setAdjusterBehavior (false, false); + icm->setAdjusterBehavior (false, false); + + chmixer->setAdjusterBehavior (false); + blackwhite->setAdjusterBehavior (false,false); + colortoning->setAdjusterBehavior (false, false, false, false, false); + filmSimulation->setAdjusterBehavior(false); + + shadowshighlights->setAdjusterBehavior (false, false, false); + dirpyrequalizer->setAdjusterBehavior (false, false, false); + wavelet->setAdjusterBehavior (false, false, false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false, false, false); + dirpyrdenoise->setAdjusterBehavior (false, false,false,false,false,false, false); + bayerpreprocess->setAdjusterBehavior (false, false); + rawcacorrection->setAdjusterBehavior (false); + flatfield->setAdjusterBehavior(false); + rawexposure->setAdjusterBehavior (false, false); + bayerrawexposure->setAdjusterBehavior (false); + xtransrawexposure->setAdjusterBehavior (false); + } + else { + + for (size_t i=0; isetMultiImage(true); + + toneCurve->setAdjusterBehavior (options.baBehav[ADDSET_TC_EXPCOMP], options.baBehav[ADDSET_TC_HLCOMPAMOUNT],options.baBehav[ADDSET_TC_HLCOMPTHRESH], options.baBehav[ADDSET_TC_BRIGHTNESS], options.baBehav[ADDSET_TC_BLACKLEVEL],options.baBehav[ADDSET_TC_SHCOMP], options.baBehav[ADDSET_TC_CONTRAST], options.baBehav[ADDSET_TC_SATURATION]); + lcurve->setAdjusterBehavior (options.baBehav[ADDSET_LC_BRIGHTNESS], options.baBehav[ADDSET_LC_CONTRAST], options.baBehav[ADDSET_LC_CHROMATICITY]); + whitebalance->setAdjusterBehavior (options.baBehav[ADDSET_WB_TEMPERATURE], options.baBehav[ADDSET_WB_GREEN], options.baBehav[ADDSET_WB_EQUAL]); + vibrance->setAdjusterBehavior (options.baBehav[ADDSET_VIBRANCE_PASTELS], options.baBehav[ADDSET_VIBRANCE_SATURATED]); + 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]); + 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]); + 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]); +// colortoning->setAdjusterBehavior (options.baBehav[ADDSET_COLORTONING_SPLIT], options.baBehav[ADDSET_COLORTONING_SATTHRESHOLD], options.baBehav[ADDSET_COLORTONING_SATOPACITY], options.baBehav[ADDSET_COLORTONING_STRPROTECT], options.baBehav[ADDSET_COLORTONING_BALANCE]); + colortoning->setAdjusterBehavior (options.baBehav[ADDSET_COLORTONING_SPLIT], options.baBehav[ADDSET_COLORTONING_SATTHRESHOLD], options.baBehav[ADDSET_COLORTONING_SATOPACITY], options.baBehav[ADDSET_COLORTONING_STRENGTH], options.baBehav[ADDSET_COLORTONING_BALANCE]); + filmSimulation->setAdjusterBehavior(options.baBehav[ADDSET_FILMSIMULATION_STRENGTH]); + + chmixer->setAdjusterBehavior (options.baBehav[ADDSET_CHMIXER] ); + blackwhite->setAdjusterBehavior (options.baBehav[ADDSET_BLACKWHITE_HUES],options.baBehav[ADDSET_BLACKWHITE_GAMMA]); + shadowshighlights->setAdjusterBehavior (options.baBehav[ADDSET_SH_HIGHLIGHTS], options.baBehav[ADDSET_SH_SHADOWS], options.baBehav[ADDSET_SH_LOCALCONTRAST]); + dirpyrequalizer->setAdjusterBehavior (options.baBehav[ADDSET_DIRPYREQ], options.baBehav[ADDSET_DIRPYREQ_THRESHOLD], options.baBehav[ADDSET_DIRPYREQ_SKINPROTECT]); + wavelet->setAdjusterBehavior (options.baBehav[ADDSET_WA], options.baBehav[ADDSET_WA_THRESHOLD], options.baBehav[ADDSET_WA_THRESHOLD2],options.baBehav[ADDSET_WA_THRES],options.baBehav[ADDSET_WA_CHRO],options.baBehav[ADDSET_WA_CHROMA],options.baBehav[ADDSET_WA_CONTRAST],options.baBehav[ADDSET_WA_SKINPROTECT],options.baBehav[ADDSET_WA_RESCHRO],options.baBehav[ADDSET_WA_TMRS],options.baBehav[ADDSET_WA_RESCON],options.baBehav[ADDSET_WA_RESCONH],options.baBehav[ADDSET_WA_THRR],options.baBehav[ADDSET_WA_THRRH],options.baBehav[ADDSET_WA_SKYPROTECT], options.baBehav[ADDSET_WA_EDGRAD],options.baBehav[ADDSET_WA_EDGVAL],options.baBehav[ADDSET_WA_STRENGTH],options.baBehav[ADDSET_WA_GAMMA],options.baBehav[ADDSET_WA_EDGEDETECT], options.baBehav[ADDSET_WA_EDGEDETECTTHR], options.baBehav[ADDSET_WA_EDGEDETECTTHR2]); + dirpyrdenoise->setAdjusterBehavior (options.baBehav[ADDSET_DIRPYRDN_LUMA],options.baBehav[ADDSET_DIRPYRDN_LUMDET],options.baBehav[ADDSET_DIRPYRDN_CHROMA],options.baBehav[ADDSET_DIRPYRDN_CHROMARED],options.baBehav[ADDSET_DIRPYRDN_CHROMABLUE], options.baBehav[ADDSET_DIRPYRDN_GAMMA], options.baBehav[ADDSET_DIRPYRDN_PASSES]); + bayerpreprocess->setAdjusterBehavior (options.baBehav[ADDSET_PREPROCESS_LINEDENOISE], options.baBehav[ADDSET_PREPROCESS_GREENEQUIL]); + rawcacorrection->setAdjusterBehavior (options.baBehav[ADDSET_RAWCACORR]); + flatfield->setAdjusterBehavior(options.baBehav[ADDSET_RAWFFCLIPCONTROL]); + rawexposure->setAdjusterBehavior (options.baBehav[ADDSET_RAWEXPOS_LINEAR], options.baBehav[ADDSET_RAWEXPOS_PRESER]); + bayerrawexposure->setAdjusterBehavior (options.baBehav[ADDSET_RAWEXPOS_BLACKS]); + xtransrawexposure->setAdjusterBehavior (options.baBehav[ADDSET_RAWEXPOS_BLACKS]); + + 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_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; + 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_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_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_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_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.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; + } + + for (size_t i=0; isetDefaults (&pparams, &pparamsEdited); + toolPanels[i]->read (&pparams, &pparamsEdited); + // TODO: autoOpenCurve has been disabled because initSession is called on each parameter change from the editor panel, + // if the thumbnail remains selected in the DirectoryBrowser (i.e. always, unless the user think about deselecting it) + //toolPanels[i]->autoOpenCurve(); + } + for (size_t i=0; iprocParamsChanged (&pparams, rtengine::EvPhotoLoaded, M("BATCH_PROCESSING"), &pparamsEdited); + } +} + +void BatchToolPanelCoordinator::panelChanged (rtengine::ProcEvent event, const Glib::ustring& descr) { + + if (selected.empty()) + return; + + somethingChanged = true; + + pparamsEdited.set (false); + // read new values from the gui + for (size_t i=0; iwrite (&pparams, &pparamsEdited); + + // If only a single item is selected, we emulate the behaviour of the editor tool panel coordinator, + // otherwise we adjust the inital parameters on a per-image basis. + if (selected.size()==1) { + // Compensate rotation on flip + if (event==rtengine::EvCTHFlip || event==rtengine::EvCTVFlip) { + if (fabs(pparams.rotate.degree)>0.001) { + pparams.rotate.degree *= -1; + rotate->read (&pparams); + } + } + + int w, h; + selected[0]->getFinalSize (selected[0]->getProcParams (), w, h); + crop->setDimensions(w, h); + + // Some transformations change the crop and resize parameter for convenience. + if (event==rtengine::EvCTHFlip) { + crop->hFlipCrop (); + crop->write (&pparams, &pparamsEdited); + } + else if (event==rtengine::EvCTVFlip) { + crop->vFlipCrop (); + crop->write (&pparams, &pparamsEdited); + } + else if (event==rtengine::EvCTRotate) { + crop->rotateCrop (pparams.coarse.rotate, pparams.coarse.hflip, pparams.coarse.vflip); + crop->write (&pparams, &pparamsEdited); + resize->update (pparams.crop.enabled, pparams.crop.w, pparams.crop.h, w, h); + resize->write (&pparams, &pparamsEdited); + } + else if (event==rtengine::EvCrop) { + resize->update (pparams.crop.enabled, pparams.crop.w, pparams.crop.h); + resize->write (&pparams, &pparamsEdited); + } + } + else { + // Compensate rotation on flip + if (event==rtengine::EvCTHFlip || event==rtengine::EvCTVFlip) { + for (size_t i=0; i 0.001) { + initialPP[i].rotate.degree *= -1.0; + + pparamsEdited.rotate.degree = false; + } + } + } + + // some transformations make the crop change for convenience + if (event==rtengine::EvCTHFlip) { + for (size_t i=0; igetFinalSize (selected[i]->getProcParams (), w, h); + + rtengine::procparams::CropParams& crop = initialPP[i].crop; + crop.x = w - crop.x - crop.w; + + pparamsEdited.crop.x = false; + } + } + else if (event==rtengine::EvCTVFlip) { + for (size_t i=0; igetFinalSize (selected[i]->getProcParams (), w, h); + + rtengine::procparams::CropParams& crop = initialPP[i].crop; + crop.y = h - crop.y - crop.h; + + pparamsEdited.crop.y = false; + } + } + else if (event==rtengine::EvCTRotate) { + int newDeg = pparams.coarse.rotate; + for (size_t i=0; igetFinalSize (selected[i]->getProcParams (), w, h); + + int oldDeg = initialPP[i].coarse.rotate; + + rtengine::procparams::CropParams& crop = initialPP[i].crop; + int rotation = (360 + newDeg - oldDeg) % 360; + ProcParams pptemp = selected[i]->getProcParams(); // Get actual procparams + if((pptemp.coarse.hflip != pptemp.coarse.vflip) && ((rotation%180)==90)) + rotation = (rotation + 180)%360; + + + switch (rotation) { + case 90: + std::swap(crop.x, crop.y); + std::swap(crop.w, crop.h); + + crop.x = h - crop.x - crop.w; + break; + case 270: + std::swap(crop.x, crop.y); + std::swap(crop.w, crop.h); + + crop.y = w - crop.y - crop.h; + break; + case 180: + crop.x = w - crop.x - crop.w; + crop.y = h - crop.y - crop.h; + break; + } + + initialPP[i].coarse.rotate = newDeg; + + } + pparamsEdited.crop.x = false; + pparamsEdited.crop.y = false; + pparamsEdited.crop.w = false; + pparamsEdited.crop.h = false; + pparamsEdited.coarse.rotate = false; + } + } + + if (event==rtengine::EvAutoExp || event==rtengine::EvClip) + for (size_t i=0; iapplyAutoExp (initialPP[i]); + } + + if (event==rtengine::EvAutoDIST) { + for (size_t i=0; itrimValues (&newParams); + + selected[i]->setProcParams (newParams, NULL, BATCHEDITOR, false); + } + + for (size_t i=0; iprocParamsChanged (&pparams, event, descr, &pparamsEdited); +} + +void BatchToolPanelCoordinator::getAutoWB (double& temp, double& green, double equal) { + + if (!selected.empty()) + selected[0]->getAutoWB (temp, green, equal); +} + +void BatchToolPanelCoordinator::getCamWB (double& temp, double& green) { + + if (!selected.empty()) + selected[0]->getCamWB (temp, green); +} + +void BatchToolPanelCoordinator::optionsChanged () { + + closeSession (); + initSession (); +} + +void BatchToolPanelCoordinator::procParamsChanged (Thumbnail* thm, int whoChangedIt) { + + if (whoChangedIt!=BATCHEDITOR && !blockedUpdate) { + closeSession (false); + initSession (); + } +} + +void BatchToolPanelCoordinator::beginBatchPParamsChange(int numberOfEntries) { + + blockedUpdate = true; + if (numberOfEntries > 50) // Arbitrary amount + parent->set_sensitive(false); +} + +// The end of a batch pparams change triggers a close/initsession +void BatchToolPanelCoordinator::endBatchPParamsChange() { + //printf("BatchToolPanelCoordinator::endBatchPParamsChange / Nouvelle session!\n"); + closeSession (false); + initSession (); + blockedUpdate = false; + parent->set_sensitive(true); +} + +/* + * WARNING: profileChange is actually called by the History only. + * Using a Profile panel in the batch tool panel editor is actually + * not supported by BatchToolPanelCoordinator::profileChange! + */ +void BatchToolPanelCoordinator::profileChange (const rtengine::procparams::PartialProfile* nparams, rtengine::ProcEvent event, const Glib::ustring& descr, const ParamsEdited* paramsEdited) { + + if (event==rtengine::EvProfileChanged) { + // a profile has been selected in a hypothetical Profile panel + // -> ACTUALLY NOT SUPPORTED + return; + } + + pparams = *(nparams->pparams); + if (paramsEdited) + pparamsEdited = *paramsEdited; + + + for (size_t i=0; iread (&pparams, &pparamsEdited); + // I guess we don't want to automatically unfold curve editors here... + + somethingChanged = true; + + // read new values from the gui + for (size_t i=0; iwrite (&pparams, &pparamsEdited); + + // combine with initial parameters of each image and set + ProcParams newParams; + for (size_t i=0; isetProcParams (newParams, NULL, BATCHEDITOR, false); + } + + for (size_t i=0; iprocParamsChanged (&pparams, event, descr, &pparamsEdited); +} + +void BatchToolPanelCoordinator::cropSelectionReady () { + + toolBar->setTool (TMHand); +} + +CropGUIListener* BatchToolPanelCoordinator::startCropEditing (Thumbnail* thm) { + + if (thm) { + int w, h; + thm->getFinalSize (thm->getProcParams (), w, h); + crop->setDimensions (w, h); + } + return crop; +} + +void BatchToolPanelCoordinator::rotateSelectionReady (double rotate_deg, Thumbnail* thm) { + + toolBar->setTool (TMHand); + if (rotate_deg!=0.0) + rotate->straighten (rotate_deg); +} + +void BatchToolPanelCoordinator::spotWBselected (int x, int y, Thumbnail* thm) { + +// toolBar->setTool (TOOL_HAND); + if (x>0 && y>0 && thm) { + for (size_t i=0; igetSpotWB (x, y, whitebalance->getSize(), temp, green); + double otemp = initialPP[i].wb.temperature; + double ogreen = initialPP[i].wb.green; + if (options.baBehav[12]) + temp = temp - otemp; + if (options.baBehav[13]) + green = green - ogreen; + whitebalance->setWB (temp, green); + } + } +} + diff --git a/rtgui/batchtoolpanelcoord.h b/rtgui/batchtoolpanelcoord.h new file mode 100644 index 000000000..8cdd12c64 --- /dev/null +++ b/rtgui/batchtoolpanelcoord.h @@ -0,0 +1,82 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef __BATCHTOOLPANELCCORD__ +#define __BATCHTOOLPANELCCORD__ + +#include "thumbnail.h" +#include "toolpanelcoord.h" +#include "fileselectionchangelistener.h" +#include "../rtengine/rtengine.h" +#include "paramsedited.h" +#include "thumbnaillistener.h" + +class FilePanel; +class BatchToolPanelCoordinator : + public ToolPanelCoordinator, + public FileSelectionChangeListener, + public BatchPParamsChangeListener, + public ThumbnailListener +{ + protected: + rtengine::procparams::ProcParams pparams; + ParamsEdited pparamsEdited; + std::vector selected; + std::vector selFileNames; + std::vector initialPP; + bool somethingChanged; + bool blockedUpdate; + FilePanel* parent; + + void closeSession (bool save=true); + void initSession (); + + public: + + BatchToolPanelCoordinator (FilePanel* parent); + + // FileSelectionChangeListener interface + void selectionChanged (const std::vector& selected); + + // toolpanellistener interface + void panelChanged (rtengine::ProcEvent event, const Glib::ustring& descr); + + // profilechangelistener interface + void profileChange (const rtengine::procparams::PartialProfile* nparams, rtengine::ProcEvent event, const Glib::ustring& descr, const ParamsEdited* paramsEdited=NULL); + + // wbprovider interface + void getAutoWB (double& temp, double& green, double equal); + void getCamWB (double& temp, double& green); + + // thumbnaillistener interface + void procParamsChanged (Thumbnail* thm, int whoChangedIt); + + // batchpparamschangelistener interface + void beginBatchPParamsChange(int numberOfEntries); + void endBatchPParamsChange(); + + // imageareatoollistener interface + void spotWBselected (int x, int y, Thumbnail* thm=NULL); + void cropSelectionReady (); + void rotateSelectionReady (double rotate_deg, Thumbnail* thm=NULL); + CropGUIListener* startCropEditing (Thumbnail* thm=NULL); + + void optionsChanged (); +}; + +#endif diff --git a/rtgui/bayerpreprocess.cc b/rtgui/bayerpreprocess.cc new file mode 100644 index 000000000..f157bf8ac --- /dev/null +++ b/rtgui/bayerpreprocess.cc @@ -0,0 +1,117 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "bayerpreprocess.h" +#include "guiutils.h" +#include "../rtengine/safegtk.h" +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +BayerPreProcess::BayerPreProcess () : FoldableToolPanel(this, "bayerpreprocess", M("TP_PREPROCESS_LABEL"), true) +{ + lineDenoise = Gtk::manage(new Adjuster (M("TP_PREPROCESS_LINEDENOISE"),0,1000,1,0)); + lineDenoise->setAdjusterListener (this); + if (lineDenoise->delay < 1000) lineDenoise->delay = 1000; + lineDenoise->show(); + + greenEqThreshold = Gtk::manage(new Adjuster (M("TP_PREPROCESS_GREENEQUIL"),0,100,1,0)); + greenEqThreshold->setAdjusterListener (this); + if (greenEqThreshold->delay < 1000) greenEqThreshold->delay = 1000; + greenEqThreshold->show(); + + pack_start( *lineDenoise, Gtk::PACK_SHRINK, 4); + + pack_start( *Gtk::manage (new Gtk::HSeparator())); + + pack_start( *greenEqThreshold, Gtk::PACK_SHRINK, 4); + +} + +void BayerPreProcess::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited) +{ + disableListener (); + + if(pedited ){ + lineDenoise->setEditedState( pedited->raw.bayersensor.linenoise ? Edited : UnEdited ); + greenEqThreshold->setEditedState( pedited->raw.bayersensor.greenEq ? Edited : UnEdited ); + } + + lineDenoise->setValue (pp->raw.bayersensor.linenoise); + greenEqThreshold->setValue (pp->raw.bayersensor.greenthresh); + + enableListener (); +} + +void BayerPreProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pedited) +{ + pp->raw.bayersensor.linenoise = lineDenoise->getIntValue(); + pp->raw.bayersensor.greenthresh = greenEqThreshold->getIntValue(); + + if (pedited) { + pedited->raw.bayersensor.linenoise = lineDenoise->getEditedState (); + pedited->raw.bayersensor.greenEq= greenEqThreshold->getEditedState (); + } +} + +void BayerPreProcess::adjusterChanged (Adjuster* a, double newval) +{ + if (listener) { + + Glib::ustring value = a->getTextValue(); + + if (a == greenEqThreshold) + listener->panelChanged (EvPreProcessGEquilThresh, value ); + else if (a == lineDenoise) + listener->panelChanged (EvPreProcessLineDenoise, value ); + } +} + +void BayerPreProcess::setBatchMode(bool batchMode) +{ + ToolPanel::setBatchMode (batchMode); + lineDenoise->showEditedCB (); + greenEqThreshold->showEditedCB (); +} + +void BayerPreProcess::setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited) +{ + lineDenoise->setDefault( defParams->raw.bayersensor.linenoise); + greenEqThreshold->setDefault (defParams->raw.bayersensor.greenthresh); + + if (pedited) { + lineDenoise->setDefaultEditedState( pedited->raw.bayersensor.linenoise ? Edited : UnEdited); + greenEqThreshold->setDefaultEditedState(pedited->raw.bayersensor.greenEq ? Edited : UnEdited); + } else { + lineDenoise->setDefaultEditedState( Irrelevant ); + greenEqThreshold->setDefaultEditedState(Irrelevant ); + } +} + +void BayerPreProcess::setAdjusterBehavior (bool linedenoiseadd, bool greenequiladd) { + + lineDenoise->setAddMode(linedenoiseadd); + greenEqThreshold->setAddMode(greenequiladd); +} + +void BayerPreProcess::trimValues (rtengine::procparams::ProcParams* pp) { + + lineDenoise->trimValue(pp->raw.bayersensor.linenoise); + greenEqThreshold->trimValue(pp->raw.bayersensor.greenthresh); +} diff --git a/rtgui/bayerpreprocess.h b/rtgui/bayerpreprocess.h new file mode 100644 index 000000000..5c2ec4cdb --- /dev/null +++ b/rtgui/bayerpreprocess.h @@ -0,0 +1,49 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _BAYERPREPROCESS_H_ +#define _BAYERPREPROCESS_H_ + +#include +#include "adjuster.h" +#include "toolpanel.h" +#include "../rtengine/rawimage.h" + +class BayerPreProcess : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel { + + protected: + + Adjuster* lineDenoise; + Adjuster* greenEqThreshold; + + public: + + BayerPreProcess (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + + void adjusterChanged (Adjuster* a, double newval); + void hotDeadPixelChanged(); + void setAdjusterBehavior (bool linedenoiseadd, bool greenequiladd); + void trimValues (rtengine::procparams::ProcParams* pp); +}; + +#endif diff --git a/rtgui/bayerprocess.cc b/rtgui/bayerprocess.cc new file mode 100644 index 000000000..9a8b49329 --- /dev/null +++ b/rtgui/bayerprocess.cc @@ -0,0 +1,270 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "bayerprocess.h" +#include "options.h" +#include "guiutils.h" +using namespace rtengine; +using namespace rtengine::procparams; + +BayerProcess::BayerProcess () : FoldableToolPanel(this, "bayerprocess", M("TP_RAW_LABEL"), true) +{ + Gtk::HBox* hb1 = Gtk::manage (new Gtk::HBox ()); + hb1->pack_start (*Gtk::manage (new Gtk::Label ( M("TP_RAW_DMETHOD") +": ")),Gtk::PACK_SHRINK, 4); + method = Gtk::manage (new MyComboBoxText ()); + for( size_t i=0; iappend_text(procparams::RAWParams::BayerSensor::methodstring[i]); + + method->set_active(0); + hb1->set_tooltip_markup (M("TP_RAW_DMETHOD_TOOLTIP")); + + hb1->pack_end (*method, Gtk::PACK_EXPAND_WIDGET, 4); + pack_start( *hb1, Gtk::PACK_SHRINK, 4); + + dcbOptions = Gtk::manage (new Gtk::VBox ()); + dcbOptions->set_border_width(4); + + dcbIterations = Gtk::manage (new Adjuster (M("TP_RAW_DCBITERATIONS"),0,5,1,2)); + dcbIterations->setAdjusterListener (this); + if (dcbIterations->delay < 1000) dcbIterations->delay = 1000; + dcbIterations->show(); + dcbEnhance = Gtk::manage (new Gtk::CheckButton(M("TP_RAW_DCBENHANCE"))); + dcbOptions->pack_start(*dcbIterations); + dcbOptions->pack_start(*dcbEnhance); + pack_start( *dcbOptions, Gtk::PACK_SHRINK, 4); + + lmmseOptions = Gtk::manage (new Gtk::VBox ()); + lmmseOptions->set_border_width(4); + + lmmseIterations = Gtk::manage (new Adjuster (M("TP_RAW_LMMSEITERATIONS"),0,6,1,2)); + lmmseIterations->setAdjusterListener (this); + lmmseIterations->set_tooltip_markup (M("TP_RAW_LMMSE_TOOLTIP")); + + if (lmmseIterations->delay < 1000) lmmseIterations->delay = 1000; + lmmseIterations->show(); + lmmseOptions->pack_start(*lmmseIterations); + pack_start( *lmmseOptions, Gtk::PACK_SHRINK, 4); + + pack_start( *Gtk::manage( new Gtk::HSeparator()), Gtk::PACK_SHRINK, 0 ); + ccSteps = Gtk::manage (new Adjuster (M("TP_RAW_FALSECOLOR"),0,5,1,0 )); + ccSteps->setAdjusterListener (this); + if (ccSteps->delay < 1000) ccSteps->delay = 1000; + ccSteps->show(); + pack_start( *ccSteps, Gtk::PACK_SHRINK, 4); + + //pack_start( *Gtk::manage( new Gtk::HSeparator()), Gtk::PACK_SHRINK, 0 ); + //allOptions = Gtk::manage (new Gtk::VBox ()); + //allOptions->set_border_width(2); + //allEnhance = Gtk::manage (new Gtk::CheckButton(M("TP_RAW_ALLENHANCE"))); + //allOptions->pack_start(*allEnhance); + //pack_start( *allOptions, Gtk::PACK_SHRINK, 4); + + methodconn = method->signal_changed().connect( sigc::mem_fun(*this, &BayerProcess::methodChanged) ); + dcbEnhconn = dcbEnhance->signal_toggled().connect ( sigc::mem_fun(*this, &BayerProcess::dcbEnhanceChanged), true); + //allEnhconn = allEnhance->signal_toggled().connect ( sigc::mem_fun(*this, &BayerProcess::allEnhanceChanged), true); +} + + +void BayerProcess::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited) +{ + disableListener (); + methodconn.block (true); + dcbEnhconn.block (true); + //allEnhconn.block (true); + + method->set_active(procparams::RAWParams::BayerSensor::numMethods); + for( size_t i=0; i< procparams::RAWParams::BayerSensor::numMethods; i++) + if( pp->raw.bayersensor.method == procparams::RAWParams::BayerSensor::methodstring[i]){ + method->set_active(i); + oldSelection = i; + break; + } + + if(pedited ){ + ccSteps->setEditedState (pedited->raw.bayersensor.ccSteps ? Edited : UnEdited); + dcbIterations->setEditedState ( pedited->raw.bayersensor.dcbIterations ? Edited : UnEdited); + dcbEnhance->set_inconsistent(!pedited->raw.bayersensor.dcbEnhance); + //allEnhance->set_inconsistent(!pedited->raw.bayersensor.allEnhance); + lmmseIterations->setEditedState ( pedited->raw.bayersensor.lmmseIterations ? Edited : UnEdited); + + if( !pedited->raw.bayersensor.method ) + method->set_active(procparams::RAWParams::BayerSensor::numMethods); // No name + } + + //allEnhance->set_active(pp->raw.bayersensor.all_enhance); + + dcbIterations->setValue (pp->raw.bayersensor.dcb_iterations); + dcbEnhance->set_active(pp->raw.bayersensor.dcb_enhance); + ccSteps->setValue (pp->raw.bayersensor.ccSteps); + if (pp->raw.bayersensor.method == procparams::RAWParams::BayerSensor::methodstring[procparams::RAWParams::BayerSensor::dcb] || + method->get_active_row_number() == procparams::RAWParams::BayerSensor::numMethods) + dcbOptions->show(); + else + dcbOptions->hide(); + + lmmseIterations->setValue (pp->raw.bayersensor.lmmse_iterations); + if (pp->raw.bayersensor.method == procparams::RAWParams::BayerSensor::methodstring[procparams::RAWParams::BayerSensor::lmmse] || + method->get_active_row_number() == procparams::RAWParams::BayerSensor::numMethods) + lmmseOptions->show(); + else + lmmseOptions->hide(); + + // Flase color suppression is applied to all demozaicing method, so don't hide anything + /*if (pp->raw.bayersensor.method == procparams::RAWParams::BayerSensor::methodstring[procparams::RAWParams::BayerSensor::eahd] || + pp->raw.bayersensor.method == procparams::RAWParams::BayerSensor::methodstring[procparams::RAWParams::BayerSensor::hphd] || + pp->raw.bayersensor.method == procparams::RAWParams::BayerSensor::methodstring[procparams::RAWParams::BayerSensor::vng4]) + ccSteps->show(); + else + ccSteps->hide();*/ + + lastDCBen = pp->raw.bayersensor.dcb_enhance; + //lastALLen = pp->raw.bayersensor.all_enhance; + + methodconn.block (false); + dcbEnhconn.block (false); + //allEnhconn.block (false); + + enableListener (); +} + +void BayerProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pedited) +{ + pp->raw.bayersensor.ccSteps = ccSteps->getIntValue(); + pp->raw.bayersensor.dcb_iterations = dcbIterations->getIntValue(); + pp->raw.bayersensor.dcb_enhance = dcbEnhance->get_active(); + //pp->raw.bayersensor.all_enhance = allEnhance->get_active(); + pp->raw.bayersensor.lmmse_iterations = lmmseIterations->getIntValue(); + + int currentRow = method->get_active_row_number(); + if( currentRow>=0 && currentRow < procparams::RAWParams::BayerSensor::numMethods) + pp->raw.bayersensor.method = procparams::RAWParams::BayerSensor::methodstring[currentRow]; + + if (pedited) { + pedited->raw.bayersensor.ccSteps = ccSteps->getEditedState (); + pedited->raw.bayersensor.method = method->get_active_row_number() != procparams::RAWParams::BayerSensor::numMethods; + pedited->raw.bayersensor.dcbIterations = dcbIterations->getEditedState (); + pedited->raw.bayersensor.dcbEnhance = !dcbEnhance->get_inconsistent(); + //pedited->raw.bayersensor.allEnhance = !allEnhance->get_inconsistent(); + pedited->raw.bayersensor.lmmseIterations = lmmseIterations->getEditedState (); + + } +} + +void BayerProcess::setBatchMode(bool batchMode) +{ + method->append_text (M("GENERAL_UNCHANGED")); + method->set_active(procparams::RAWParams::BayerSensor::numMethods); // No name + dcbOptions->hide(); + lmmseOptions->hide(); + ToolPanel::setBatchMode (batchMode); + ccSteps->showEditedCB (); + dcbIterations->showEditedCB (); + lmmseIterations->showEditedCB (); +} + +void BayerProcess::setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited) +{ + dcbIterations->setDefault( defParams->raw.bayersensor.dcb_iterations); + lmmseIterations->setDefault( defParams->raw.bayersensor.lmmse_iterations); + ccSteps->setDefault (defParams->raw.bayersensor.ccSteps); + if (pedited) { + dcbIterations->setDefaultEditedState( pedited->raw.bayersensor.dcbIterations ? Edited : UnEdited); + lmmseIterations->setDefaultEditedState( pedited->raw.bayersensor.lmmseIterations ? Edited : UnEdited); + ccSteps->setDefaultEditedState(pedited->raw.bayersensor.ccSteps ? Edited : UnEdited); + }else{ + dcbIterations->setDefaultEditedState( Irrelevant ); + lmmseIterations->setDefaultEditedState( Irrelevant ); + ccSteps->setDefaultEditedState(Irrelevant ); + } +} + +void BayerProcess::adjusterChanged (Adjuster* a, double newval) +{ + if (listener) { + if (a == dcbIterations) + listener->panelChanged (EvDemosaicDCBIter, a->getTextValue() ); + else if (a == ccSteps) + listener->panelChanged (EvDemosaicFalseColorIter, a->getTextValue() ); + else if (a == lmmseIterations) + listener->panelChanged (EvDemosaicLMMSEIter, a->getTextValue() ); + } +} + +void BayerProcess::methodChanged () +{ + int curSelection = method->get_active_row_number(); + if ( curSelection == procparams::RAWParams::BayerSensor::dcb){ + dcbOptions->show(); + }else{ + dcbOptions->hide(); + } + if ( curSelection == procparams::RAWParams::BayerSensor::lmmse){ + lmmseOptions->show(); + }else{ + lmmseOptions->hide(); + } + + Glib::ustring methodName=""; + bool ppreq = false; + if( curSelection>=0 && curSelection < procparams::RAWParams::BayerSensor::numMethods) { + methodName = procparams::RAWParams::BayerSensor::methodstring[curSelection]; + if (curSelection == procparams::RAWParams::BayerSensor::mono || oldSelection == procparams::RAWParams::BayerSensor::mono) { + ppreq = true; + } + } + oldSelection = curSelection; + + if (listener) + listener->panelChanged (ppreq ? EvDemosaicMethodPreProc : EvDemosaicMethod, methodName); +} + +void BayerProcess::dcbEnhanceChanged () +{ + if (batchMode) { + if (dcbEnhance->get_inconsistent()) { + dcbEnhance->set_inconsistent (false); + dcbEnhconn.block (true); + dcbEnhance->set_active (false); + dcbEnhconn.block (false); + } + else if (lastDCBen) + dcbEnhance->set_inconsistent (true); + + lastDCBen = dcbEnhance->get_active (); + } + if (listener) + listener->panelChanged (EvDemosaicDCBEnhanced, dcbEnhance->get_active()?M("GENERAL_ENABLED"):M("GENERAL_DISABLED")); +} + +/*void BayerProcess::allEnhanceChanged () +{ + if (batchMode) { + if (allEnhance->get_inconsistent()) { + allEnhance->set_inconsistent (false); + allEnhconn.block (true); + allEnhance->set_active (false); + allEnhconn.block (false); + } + else if (lastALLen) + allEnhance->set_inconsistent (true); + + lastALLen = allEnhance->get_active (); + } + if (listener) + listener->panelChanged (EvDemosaicALLEnhanced, allEnhance->get_active()?M("GENERAL_ENABLED"):M("GENERAL_DISABLED")); +}*/ diff --git a/rtgui/bayerprocess.h b/rtgui/bayerprocess.h new file mode 100644 index 000000000..cb281832b --- /dev/null +++ b/rtgui/bayerprocess.h @@ -0,0 +1,61 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _BAYERPROCESS_H_ +#define _BAYERPROCESS_H_ + +#include +#include "adjuster.h" +#include "guiutils.h" +#include "toolpanel.h" + + +class BayerProcess : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel{ + + protected: + + MyComboBoxText* method; + Adjuster* ccSteps; + Gtk::VBox *dcbOptions; + Adjuster* dcbIterations; + Gtk::CheckButton* dcbEnhance; + //Gtk::VBox *allOptions; + //Gtk::CheckButton* allEnhance; + Gtk::VBox *lmmseOptions; + Adjuster* lmmseIterations; + + bool lastDCBen; + int oldSelection; + //bool lastALLen; + sigc::connection methodconn,dcbEnhconn; //,allEnhconn; + public: + + BayerProcess (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + + void methodChanged (); + void adjusterChanged (Adjuster* a, double newval); + void dcbEnhanceChanged(); + //void allEnhanceChanged(); +}; + +#endif diff --git a/rtgui/bayerrawexposure.cc b/rtgui/bayerrawexposure.cc new file mode 100644 index 000000000..402c1063b --- /dev/null +++ b/rtgui/bayerrawexposure.cc @@ -0,0 +1,185 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "bayerrawexposure.h" +#include "guiutils.h" +#include "../rtengine/safegtk.h" +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +BayerRAWExposure::BayerRAWExposure () : FoldableToolPanel(this, "bayerrawexposure", M("TP_EXPOS_BLACKPOINT_LABEL"), true) +{ + PexBlack1 = Gtk::manage(new Adjuster (M("TP_RAWEXPOS_BLACK_1"),-2048,2048,0.1,0));//black level + PexBlack1->setAdjusterListener (this); + if (PexBlack1->delay < 1000) PexBlack1->delay = 1000; + PexBlack1->show(); + PexBlack2 = Gtk::manage(new Adjuster (M("TP_RAWEXPOS_BLACK_2"),-2048,2048,0.1,0));//black level + PexBlack2->setAdjusterListener (this); + if (PexBlack2->delay < 1000) PexBlack2->delay = 1000; + PexBlack2->show(); + PexBlack3 = Gtk::manage(new Adjuster (M("TP_RAWEXPOS_BLACK_3"),-2048,2048,0.1,0));//black level + PexBlack3->setAdjusterListener (this); + if (PexBlack3->delay < 1000) PexBlack3->delay = 1000; + PexBlack3->show(); + PexBlack0 = Gtk::manage(new Adjuster (M("TP_RAWEXPOS_BLACK_0"),-2048,2048,0.1,0));//black level + PexBlack0->setAdjusterListener (this); + if (PexBlack0->delay < 1000) PexBlack0->delay = 1000; + PexBlack0->show(); + PextwoGreen = Gtk::manage(new Gtk::CheckButton((M("TP_RAWEXPOS_TWOGREEN"))));// two green + PextwoGreen->set_active (true); + greenconn = PextwoGreen->signal_toggled().connect ( sigc::mem_fun(*this, &BayerRAWExposure::GreenChanged)); + + pack_start( *PexBlack1, Gtk::PACK_SHRINK, 0);//black R + pack_start( *PexBlack0, Gtk::PACK_SHRINK, 0);//black G1 + pack_start( *PexBlack3, Gtk::PACK_SHRINK, 0);//black G2 + pack_start( *PexBlack2, Gtk::PACK_SHRINK, 0);//black B + pack_start( *PextwoGreen, Gtk::PACK_SHRINK, 0);//black 2 green +} + +void BayerRAWExposure::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited) +{ + disableListener (); + + if(pedited ){ + PexBlack0->setEditedState( pedited->raw.bayersensor.exBlack0 ? Edited : UnEdited ); + PexBlack1->setEditedState( pedited->raw.bayersensor.exBlack1 ? Edited : UnEdited ); + PexBlack2->setEditedState( pedited->raw.bayersensor.exBlack2 ? Edited : UnEdited ); + PexBlack3->setEditedState( pedited->raw.bayersensor.exBlack3 ? Edited : UnEdited ); + } + greenconn.block (true); + PextwoGreen->set_active (pp->raw.bayersensor.twogreen); + greenconn.block (false); + lastPextwoGreen = pp->raw.bayersensor.twogreen; + + PexBlack0->setValue (pp->raw.bayersensor.black0);//black + PexBlack1->setValue (pp->raw.bayersensor.black1);//black + PexBlack2->setValue (pp->raw.bayersensor.black2);//black + + if(!PextwoGreen->get_active())PexBlack3->setValue (pp->raw.bayersensor.black3);else PexBlack3->setValue (PexBlack0->getValue()); + + enableListener (); +} + +void BayerRAWExposure::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pedited) +{ + pp->raw.bayersensor.black0 = PexBlack0->getValue();// black + pp->raw.bayersensor.black1 = PexBlack1->getValue();// black + pp->raw.bayersensor.black2 = PexBlack2->getValue();// black + pp->raw.bayersensor.twogreen=PextwoGreen->get_active(); + if(PextwoGreen->get_active()){pp->raw.bayersensor.black3=pp->raw.bayersensor.black0;} else {pp->raw.bayersensor.black3 = PexBlack3->getValue();}// active or desactive 2 green together + + if (pedited) { + pedited->raw.bayersensor.exBlack0 = PexBlack0->getEditedState ();//black + pedited->raw.bayersensor.exBlack1 = PexBlack1->getEditedState ();//black + pedited->raw.bayersensor.exBlack2 = PexBlack2->getEditedState ();//black + pedited->raw.bayersensor.exBlack3 = PexBlack3->getEditedState ();//black + pedited->raw.bayersensor.exTwoGreen =!PextwoGreen->get_inconsistent(); + } + +} + +void BayerRAWExposure::adjusterChanged (Adjuster* a, double newval) +{ + if (listener) { + Glib::ustring value = a->getTextValue(); + if (a == PexBlack0) {if(!PextwoGreen->get_active()) + listener->panelChanged (EvPreProcessExpBlackzero, value ); else {listener->panelChanged (EvPreProcessExpBlackzero, value );PexBlack3->setValue (PexBlack0->getValue());}} + else if (a == PexBlack1) + listener->panelChanged (EvPreProcessExpBlackone, value ); + else if (a == PexBlack2) + listener->panelChanged (EvPreProcessExpBlacktwo, value ); + else if (a == PexBlack3) {if(!PextwoGreen->get_active()) + listener->panelChanged (EvPreProcessExpBlackthree, value ); else {listener->panelChanged (EvPreProcessExpBlackthree, value );PexBlack0->setValue (PexBlack3->getValue());}} + } +} +void BayerRAWExposure::GreenChanged() { + if (batchMode) { + if (PextwoGreen->get_inconsistent()) { + PextwoGreen->set_inconsistent (false); + greenconn.block (true); + PextwoGreen->set_active (false); + greenconn.block (false); + } + else if (lastPextwoGreen) + PextwoGreen->set_inconsistent (true); + lastPextwoGreen = PextwoGreen->get_active (); + } + + if (listener) { + if (PextwoGreen->get_active()) + { listener->panelChanged (EvPreProcessExptwoGreen, M("GENERAL_ENABLED")); + PexBlack3->setValue (PexBlack0->getValue());//two green together + } + + else + { listener->panelChanged (EvPreProcessExptwoGreen, M("GENERAL_DISABLED")); + } + + } + +} + +void BayerRAWExposure::setBatchMode(bool batchMode) +{ + ToolPanel::setBatchMode (batchMode); + PexBlack0->showEditedCB ();//black + PexBlack1->showEditedCB ();//black + PexBlack2->showEditedCB ();//black + PexBlack3->showEditedCB ();//black + +} + +void BayerRAWExposure::setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited) +{ + PexBlack0->setDefault( defParams->raw.bayersensor.black0); + PexBlack1->setDefault( defParams->raw.bayersensor.black1); + PexBlack2->setDefault( defParams->raw.bayersensor.black2); + PexBlack3->setDefault( defParams->raw.bayersensor.black3); + + if (pedited) { + PexBlack0->setDefaultEditedState( pedited->raw.bayersensor.exBlack0 ? Edited : UnEdited); + PexBlack1->setDefaultEditedState( pedited->raw.bayersensor.exBlack1 ? Edited : UnEdited); + PexBlack2->setDefaultEditedState( pedited->raw.bayersensor.exBlack2 ? Edited : UnEdited); + PexBlack3->setDefaultEditedState( pedited->raw.bayersensor.exBlack3 ? Edited : UnEdited); + + } else { + PexBlack0->setDefaultEditedState( Irrelevant ); + PexBlack1->setDefaultEditedState( Irrelevant ); + PexBlack2->setDefaultEditedState( Irrelevant ); + PexBlack3->setDefaultEditedState( Irrelevant ); + + } +} + +void BayerRAWExposure::setAdjusterBehavior (bool pexblackadd) { + + PexBlack0->setAddMode(pexblackadd); + PexBlack1->setAddMode(pexblackadd); + PexBlack2->setAddMode(pexblackadd); + PexBlack3->setAddMode(pexblackadd); +} + +void BayerRAWExposure::trimValues (rtengine::procparams::ProcParams* pp) { + + PexBlack0->trimValue(pp->raw.bayersensor.black0); + PexBlack1->trimValue(pp->raw.bayersensor.black1); + PexBlack2->trimValue(pp->raw.bayersensor.black2); + PexBlack3->trimValue(pp->raw.bayersensor.black3); +} diff --git a/rtgui/bayerrawexposure.h b/rtgui/bayerrawexposure.h new file mode 100644 index 000000000..e485fb12b --- /dev/null +++ b/rtgui/bayerrawexposure.h @@ -0,0 +1,54 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _BAYERRAWEXPOSURE_H_ +#define _BAYERRAWEXPOSURE_H_ + +#include +#include "adjuster.h" +#include "toolpanel.h" +#include "../rtengine/rawimage.h" + +class BayerRAWExposure : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel { + +protected: + Adjuster* PexBlack0; + Adjuster* PexBlack1; + Adjuster* PexBlack2; + Adjuster* PexBlack3; + bool lastPextwoGreen; + sigc::connection greenconn; + Gtk::CheckButton* PextwoGreen; + +private: +// Gtk::CheckButton* PextwoGreen; +public: + + BayerRAWExposure (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void GreenChanged() ; + void adjusterChanged (Adjuster* a, double newval); + void setAdjusterBehavior (bool pexblackadd); + void trimValues (rtengine::procparams::ProcParams* pp); +}; + +#endif diff --git a/rtgui/blackwhite.cc b/rtgui/blackwhite.cc new file mode 100644 index 000000000..f631225bb --- /dev/null +++ b/rtgui/blackwhite.cc @@ -0,0 +1,1323 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "blackwhite.h" +#include "rtimage.h" +#include "../rtengine/color.h" +#include +#include +#include "guiutils.h" +#include "edit.h" + +using namespace rtengine; +using namespace rtengine::procparams; + + +BlackWhite::BlackWhite (): FoldableToolPanel(this, "blackwhite", M("TP_BWMIX_LABEL"), false, true) { + CurveListener::setMulti(true); + + nextredbw = 0.3333; + nextgreenbw = 0.3333; + nextbluebw = 0.3333; + + //----------- Method combobox ------------------------------ + + Gtk::HBox* metHBox = Gtk::manage (new Gtk::HBox ()); + metHBox->set_border_width (0); + metHBox->set_spacing (2); + Gtk::Label* metLabel = Gtk::manage (new Gtk::Label (M("TP_BWMIX_MET")+":")); + metHBox->pack_start (*metLabel, Gtk::PACK_SHRINK); + method = Gtk::manage (new MyComboBoxText ()); + method->append_text (M("TP_BWMIX_MET_DESAT")); + method->append_text (M("TP_BWMIX_MET_LUMEQUAL")); + method->append_text (M("TP_BWMIX_MET_CHANMIX")); + + method->set_active (0); + metHBox->pack_start (*method); + pack_start (*metHBox); + methodconn = method->signal_changed().connect ( sigc::mem_fun(*this, &BlackWhite::methodChanged) ); + + + //----------- Luminance equalizer ------------------------------ + + luminanceSep = Gtk::manage (new Gtk::HSeparator()); + pack_start (*luminanceSep); + + std::vector bottomMilestones; + float R, G, B; + // -0.1 rad < Hue < 1.6 rad + for (int i=0; i<7; i++) { + float x = float(i)*(1.0f/6.0); + Color::hsv2rgb01(x, 0.5f, 0.5f, R, G, B); + bottomMilestones.push_back( GradientMilestone(double(x), double(R), double(G), double(B)) ); + } + luminanceCEG = new CurveEditorGroup (options.lastBWCurvesDir, M("TP_BWMIX_CHANNEL")); + luminanceCEG->setCurveListener (this); + luminanceCurve = static_cast(luminanceCEG->addCurve(CT_Flat, M("TP_BWMIX_VAL"))); + luminanceCurve->setEditID(EUID_BlackWhiteLuminance, BT_SINGLEPLANE_FLOAT); + luminanceCurve->setBottomBarBgGradient(bottomMilestones); + luminanceCurve->setCurveColorProvider(this, 3); + luminanceCurve->setTooltip(M("TP_BWMIX_CURVEEDITOR_LH_TOOLTIP")); + + luminanceCEG->curveListComplete(); + pack_start (*luminanceCEG, Gtk::PACK_SHRINK, 4); + + //----------- Auto and Reset buttons ------------------------------ + + mixerFrame = Gtk::manage (new Gtk::Frame (M("TP_BWMIX_MET_CHANMIX"))); + pack_start (*mixerFrame, Gtk::PACK_SHRINK, 0); + + mixerVBox = Gtk::manage (new Gtk::VBox ()); + mixerVBox->set_border_width(4); + mixerVBox->set_spacing(4); + + autoHBox = Gtk::manage (new Gtk::HBox ()); + autoHBox->set_border_width (2); + + autoch = Gtk::manage (new Gtk::ToggleButton (M("TP_BWMIX_AUTOCH"))); + autoch->set_tooltip_markup (M("TP_BWMIX_AUTOCH_TIP")); + autoconn = autoch->signal_toggled().connect( sigc::mem_fun(*this, &BlackWhite::autoch_toggled) ); + + neutral = Gtk::manage (new Gtk::Button (M("TP_BWMIX_NEUTRAL"))); + RTImage *resetImg = Gtk::manage (new RTImage ("gtk-undo-ltr-small.png", "gtk-undo-rtl-small.png")); + neutral->set_image(*resetImg); + neutral->set_tooltip_text (M("TP_BWMIX_NEUTRAL_TIP")); + neutralconn = neutral->signal_pressed().connect( sigc::mem_fun(*this, &BlackWhite::neutral_pressed) ); + neutral->show(); + + autoHBox->pack_start (*autoch); + autoHBox->pack_end (*neutral); + autoHBox->pack_end (*Gtk::manage (new Gtk::Label (" "))); //spacer + mixerVBox->pack_start (*autoHBox); + + //----------- Presets combobox ------------------------------ + + mixerVBox->pack_start (*Gtk::manage (new Gtk::HSeparator())); + + settingHBox = Gtk::manage (new Gtk::HBox ()); + settingHBox->set_border_width (0); + settingHBox->set_spacing (2); + settingHBox->set_tooltip_markup (M("TP_BWMIX_SETTING_TOOLTIP")); + Gtk::Label *settingLabel = Gtk::manage (new Gtk::Label (M("TP_BWMIX_SETTING")+":")); + + settingHBox->pack_start (*settingLabel, Gtk::PACK_SHRINK); + setting = Gtk::manage (new MyComboBoxText ()); + setting->append_text (M("TP_BWMIX_SET_NORMCONTAST")); + setting->append_text (M("TP_BWMIX_SET_HIGHCONTAST")); + setting->append_text (M("TP_BWMIX_SET_LUMINANCE")); + setting->append_text (M("TP_BWMIX_SET_LANDSCAPE")); + setting->append_text (M("TP_BWMIX_SET_PORTRAIT")); + setting->append_text (M("TP_BWMIX_SET_LOWSENSIT")); + setting->append_text (M("TP_BWMIX_SET_HIGHSENSIT")); + setting->append_text (M("TP_BWMIX_SET_PANCHRO")); + setting->append_text (M("TP_BWMIX_SET_HYPERPANCHRO")); + setting->append_text (M("TP_BWMIX_SET_ORTHOCHRO")); + setting->append_text (M("TP_BWMIX_SET_RGBABS")); + setting->append_text (M("TP_BWMIX_SET_RGBREL")); + setting->append_text (M("TP_BWMIX_SET_ROYGCBPMABS")); + setting->append_text (M("TP_BWMIX_SET_ROYGCBPMREL")); + setting->append_text (M("TP_BWMIX_SET_INFRARED")); + + setting->set_active (0); + settingHBox->pack_start (*setting); + mixerVBox->pack_start (*settingHBox); + settingconn = setting->signal_changed().connect ( sigc::mem_fun(*this, &BlackWhite::settingChanged) ); + + RGBLabels = Gtk::manage(new Gtk::Label("---", Gtk::ALIGN_CENTER)); + RGBLabels->set_tooltip_text(M("TP_BWMIX_RGBLABEL_HINT")); + mixerVBox->pack_start (*RGBLabels); + + //----------- Complementary Color checkbox ------------------------------ + + enabledccSep= Gtk::manage (new Gtk::HSeparator()); + mixerVBox->pack_start (*enabledccSep); + + enabledcc = Gtk::manage (new Gtk::CheckButton (M("TP_BWMIX_CC_ENABLED"))); + + enabledcc->set_active (true); + enabledcc->set_tooltip_markup (M("TP_BWMIX_CC_TOOLTIP")); + + mixerVBox->pack_start(*enabledcc, Gtk::PACK_SHRINK, 0); + enabledcc->show (); + enaccconn = enabledcc->signal_toggled().connect( sigc::mem_fun(*this, &BlackWhite::enabledcc_toggled) ); + + //----------- Color Filters ------------------------------ + + filterSep = Gtk::manage (new Gtk::HSeparator()); + mixerVBox->pack_start (*filterSep); + + filterHBox = Gtk::manage (new Gtk::HBox ()); + filterHBox->set_border_width (0); + filterHBox->set_spacing (2); + filterHBox->set_tooltip_markup (M("TP_BWMIX_FILTER_TOOLTIP")); + Gtk::Label *filterLabel = Gtk::manage (new Gtk::Label (M("TP_BWMIX_FILTER")+":")); + filterHBox->pack_start (*filterLabel, Gtk::PACK_SHRINK); + filter = Gtk::manage (new MyComboBoxText ()); + filter->append_text (M("TP_BWMIX_FILTER_NONE")); + filter->append_text (M("TP_BWMIX_FILTER_RED")); + filter->append_text (M("TP_BWMIX_FILTER_REDYELLOW")); + filter->append_text (M("TP_BWMIX_FILTER_YELLOW")); + filter->append_text (M("TP_BWMIX_FILTER_GREENYELLOW")); + filter->append_text (M("TP_BWMIX_FILTER_GREEN")); + filter->append_text (M("TP_BWMIX_FILTER_BLUEGREEN")); + filter->append_text (M("TP_BWMIX_FILTER_BLUE")); + filter->append_text (M("TP_BWMIX_FILTER_PURPLE")); + + filter->set_active (0); + filterHBox->pack_start (*filter); + mixerVBox->pack_start (*filterHBox); + filterconn = filter->signal_changed().connect ( sigc::mem_fun(*this, &BlackWhite::filterChanged) ); + + //----------- RGB / ROYGCBPM Mixer ------------------------------ + + imgIcon[0] = Gtk::manage (new RTImage ("Chanmixer-R.png")); + imgIcon[1] = Gtk::manage (new RTImage ("Chanmixer-O.png")); + imgIcon[2] = Gtk::manage (new RTImage ("Chanmixer-Y.png")); + imgIcon[3] = Gtk::manage (new RTImage ("Chanmixer-G.png")); + imgIcon[4] = Gtk::manage (new RTImage ("Chanmixer-C.png")); + imgIcon[5] = Gtk::manage (new RTImage ("Chanmixer-B.png")); + imgIcon[6] = Gtk::manage (new RTImage ("Chanmixer-P.png")); + imgIcon[7] = Gtk::manage (new RTImage ("Chanmixer-M.png")); + + imgIcon[8] = Gtk::manage (new RTImage ("Chanmixer-Rgamma.png")); + imgIcon[9] = Gtk::manage (new RTImage ("Chanmixer-Ggamma.png")); + imgIcon[10] = Gtk::manage (new RTImage ("Chanmixer-Bgamma.png")); + + mixerVBox->pack_start (*Gtk::manage (new Gtk::HSeparator())); + + mixerRed= Gtk::manage(new Adjuster (/*M("TP_BWMIX_RED")*/"", -100, 200, 1, 33, imgIcon[0])); + if (mixerRed->delay < 50) mixerRed->delay = 50; + mixerRed->setAdjusterListener (this); + mixerRed->set_tooltip_markup (M("TP_BWMIX_RGB_TOOLTIP")); + mixerRed->show(); + mixerVBox->pack_start( *mixerRed, Gtk::PACK_SHRINK, 0); + + mixerGreen= Gtk::manage(new Adjuster (/*M("TP_BWMIX_GREEN")*/"", -100, 200, 1, 33, imgIcon[3])); + if (mixerGreen->delay < 50) mixerGreen->delay = 50; + mixerGreen->setAdjusterListener (this); + mixerGreen->set_tooltip_markup (M("TP_BWMIX_RGB_TOOLTIP")); + mixerGreen->show(); + mixerVBox->pack_start( *mixerGreen, Gtk::PACK_SHRINK, 0); + + mixerBlue= Gtk::manage(new Adjuster (/*M("TP_BWMIX_BLUE")*/"", -100, 200, 1, 33, imgIcon[5])); + if (mixerBlue->delay < 50) mixerBlue->delay = 50; + mixerBlue->setAdjusterListener (this); + mixerBlue->set_tooltip_markup (M("TP_BWMIX_RGB_TOOLTIP")); + mixerBlue->show(); + mixerVBox->pack_start( *mixerBlue, Gtk::PACK_SHRINK, 0); + + filterSep2 = Gtk::manage (new Gtk::HSeparator()); + mixerVBox->pack_start (*filterSep2); + + algoHBox = Gtk::manage (new Gtk::HBox ()); + algoHBox->set_border_width (0); + algoHBox->set_spacing (2); + algoHBox->set_tooltip_markup (M("TP_BWMIX_ALGO_TOOLTIP")); + + alLabel = Gtk::manage (new Gtk::Label (M("TP_BWMIX_ALGO")+":")); + algoHBox->pack_start (*alLabel, Gtk::PACK_SHRINK); + + algo = Gtk::manage (new MyComboBoxText ()); + algo->append_text (M("TP_BWMIX_ALGO_LI")); + algo->append_text (M("TP_BWMIX_ALGO_SP")); + algo->set_active (1); + algoHBox->pack_start (*algo); + mixerVBox->pack_start(*algoHBox); + algoconn = algo->signal_changed().connect ( sigc::mem_fun(*this, &BlackWhite::algoChanged) ); + + mixerOrange= Gtk::manage(new Adjuster (/*M("TP_BWMIX_ORANGE")*/"", -100, 200, 1, 33, imgIcon[1])); + if (mixerOrange->delay < 50) mixerOrange->delay = 50; + mixerOrange->setAdjusterListener (this); + mixerOrange->set_tooltip_markup (M("TP_BWMIX_RGB_TOOLTIP")); + mixerOrange->show(); + mixerVBox->pack_start( *mixerOrange, Gtk::PACK_SHRINK, 0); + + mixerYellow= Gtk::manage(new Adjuster (/*M("TP_BWMIX_YELLOW")*/"", -100, 200, 1, 33, imgIcon[2])); + if (mixerYellow->delay < 50) mixerYellow->delay = 50; + mixerYellow->setAdjusterListener (this); + mixerYellow->set_tooltip_markup (M("TP_BWMIX_RGB_TOOLTIP")); + mixerYellow->show(); + mixerVBox->pack_start( *mixerYellow, Gtk::PACK_SHRINK, 0); + + mixerCyan= Gtk::manage(new Adjuster (/*M("TP_BWMIX_CYAN")*/"", -100, 200, 1, 33, imgIcon[4])); + if (mixerCyan->delay < 50) mixerCyan->delay = 50; + mixerCyan->setAdjusterListener (this); + mixerCyan->set_tooltip_markup (M("TP_BWMIX_RGB_TOOLTIP")); + mixerCyan->show(); + mixerVBox->pack_start( *mixerCyan, Gtk::PACK_SHRINK, 0); + + mixerPurple= Gtk::manage(new Adjuster (/*M("TP_BWMIX_PURPLE")*/"", -100, 200, 1, 33, imgIcon[6])); + if (mixerPurple->delay < 50) mixerPurple->delay = 50; + mixerPurple->setAdjusterListener (this); + mixerPurple->set_tooltip_markup (M("TP_BWMIX_RGB_TOOLTIP")); + mixerPurple->show(); + mixerVBox->pack_start( *mixerPurple, Gtk::PACK_SHRINK, 0); + + mixerMagenta= Gtk::manage(new Adjuster (/*M("TP_BWMIX_MAGENTA")*/"", -100, 200, 1, 33, imgIcon[7])); + if (mixerMagenta->delay < 50) mixerMagenta->delay = 50; + mixerMagenta->setAdjusterListener (this); + mixerMagenta->set_tooltip_markup (M("TP_BWMIX_RGB_TOOLTIP")); + mixerMagenta->show(); + mixerVBox->pack_start( *mixerMagenta, Gtk::PACK_SHRINK, 0); + + mixerFrame->add(*mixerVBox); + + //----------- Gamma sliders ------------------------------ + + gammaFrame = Gtk::manage (new Gtk::Frame (M("TP_BWMIX_GAMMA"))); + pack_start (*gammaFrame, Gtk::PACK_SHRINK, 0); + + Gtk::VBox *gammaVBox = Gtk::manage (new Gtk::VBox()); + gammaVBox->set_spacing(4); + gammaVBox->set_border_width(4); + + + gammaRed= Gtk::manage(new Adjuster (/*M("TP_BWMIX_GAM_RED")*/"", -100, 100, 1, 0, imgIcon[8])); + if (gammaRed->delay < 50) gammaRed->delay = 50; + + gammaRed->setAdjusterListener (this); + gammaRed->set_tooltip_markup (M("TP_BWMIX_GAM_TOOLTIP")); + gammaRed->show(); + gammaVBox->pack_start( *gammaRed, Gtk::PACK_SHRINK, 0); + + gammaGreen= Gtk::manage(new Adjuster (/*M("TP_BWMIX_GAM_GREEN")*/"", -100, 100, 1, 0, imgIcon[9])); + if (gammaGreen->delay < 50) gammaGreen->delay = 50; + gammaGreen->setAdjusterListener (this); + gammaGreen->set_tooltip_markup (M("TP_BWMIX_GAM_TOOLTIP")); + gammaGreen->show(); + gammaVBox->pack_start( *gammaGreen, Gtk::PACK_SHRINK, 0); + + gammaBlue= Gtk::manage(new Adjuster (/*M("TP_BWMIX_GAM_BLUE")*/"", -100, 100, 1, 0, imgIcon[10])); + if (gammaBlue->delay < 50) gammaBlue->delay = 50; + gammaBlue->setAdjusterListener (this); + gammaBlue->set_tooltip_markup (M("TP_BWMIX_GAM_TOOLTIP")); + gammaBlue->show(); + gammaVBox->pack_start( *gammaBlue, Gtk::PACK_SHRINK, 0); + + gammaFrame->add(*gammaVBox); + + //----------- Curve 1 ------------------------------ + + std::vector bottomMilestonesbw; + bottomMilestonesbw.push_back( GradientMilestone(0., 0., 0., 0.) ); + bottomMilestonesbw.push_back( GradientMilestone(1., 1., 1., 1.) ); + + beforeCurveMode = Gtk::manage (new MyComboBoxText ()); + beforeCurveMode->append_text (M("TP_BWMIX_TCMODE_STANDARD")); + beforeCurveMode->append_text (M("TP_BWMIX_TCMODE_WEIGHTEDSTD")); + beforeCurveMode->append_text (M("TP_BWMIX_TCMODE_FILMLIKE")); + beforeCurveMode->append_text (M("TP_BWMIX_TCMODE_SATANDVALBLENDING")); + beforeCurveMode->set_active (0); + + beforeCurveCEG = new CurveEditorGroup (options.lastBWCurvesDir, M("TP_BWMIX_CURVEEDITOR1")); + beforeCurveCEG->setCurveListener (this); + + beforeCurve = static_cast(beforeCurveCEG->addCurve(CT_Diagonal, "", beforeCurveMode)); + beforeCurve->setEditID(EUID_BlackWhiteBeforeCurve, BT_IMAGEFLOAT); + beforeCurve->setBottomBarBgGradient(bottomMilestonesbw); + beforeCurve->setLeftBarBgGradient(bottomMilestonesbw); + beforeCurve->setTooltip(M("TP_BWMIX_CURVEEDITOR_BEFORE_TOOLTIP")); + + // This will add the reset button at the end of the curveType buttons + beforeCurveCEG->curveListComplete(); + + pack_start( *beforeCurveCEG, Gtk::PACK_SHRINK, 2); + + tcmodeconn = beforeCurveMode->signal_changed().connect( sigc::mem_fun(*this, &BlackWhite::curveMode1Changed), true ); + + //----------- Curve 2 ------------------------------ +/* + afterCurveMode = Gtk::manage (new MyComboBoxText ()); + afterCurveMode->append_text (M("TP_BWMIX_TCMODE_STANDARD")); + // afterCurveMode->append_text (M("TP_BWMIX_TCMODE_WEIGHTEDSTD")); + afterCurveMode->set_active (0); +*/ + afterCurveCEG = new CurveEditorGroup (options.lastBWCurvesDir, M("TP_BWMIX_CURVEEDITOR2")); + afterCurveCEG->setCurveListener (this); + +// afterCurve = static_cast(afterCurveCEG->addCurve(CT_Diagonal, "", afterCurveMode)); + afterCurve = static_cast(afterCurveCEG->addCurve(CT_Diagonal, "")); + afterCurve->setEditID(EUID_BlackWhiteAfterCurve, BT_SINGLEPLANE_FLOAT); + afterCurve->setBottomBarBgGradient(bottomMilestonesbw); + afterCurve->setLeftBarBgGradient(bottomMilestonesbw); + afterCurve->setTooltip(M("TP_BWMIX_CURVEEDITOR_AFTER_TOOLTIP")); + + afterCurveCEG->curveListComplete(); + + pack_start( *afterCurveCEG, Gtk::PACK_SHRINK, 2); + +// tcmodeconn2 = afterCurveMode->signal_changed().connect( sigc::mem_fun(*this, &BlackWhite::curveMode1Changed2), true ); + + show_all(); + + disableListener(); + methodChanged(); + enableListener(); +} +BlackWhite::~BlackWhite () { + delete luminanceCEG; + delete beforeCurveCEG; + delete afterCurveCEG; +} + +int BWChangedUI (void* data) { + GThreadLock lock; + (static_cast(data))->BWComputed_ (); + return 0; +} + +void BlackWhite::BWChanged (double redbw, double greenbw, double bluebw){ + nextredbw = redbw; + nextgreenbw = greenbw; + nextbluebw = bluebw; + g_idle_add (BWChangedUI, this); +} + +bool BlackWhite::BWComputed_ () { + + disableListener (); + mixerRed->setValue (nextredbw); + mixerGreen->setValue (nextgreenbw); + mixerBlue->setValue (nextbluebw); + enableListener (); + + updateRGBLabel(); + + return false; +} + +void BlackWhite::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + methodconn.block(true); + //autoconn.block (true); + filterconn.block(true); + settingconn.block(true); + enaccconn.block (true); + + if (pedited && !pedited->blackwhite.setting) + setting->set_active (15); // "Unchanged" + else if (pp->blackwhite.setting=="NormalContrast") + setting->set_active (0); + else if (pp->blackwhite.setting=="HighContrast") + setting->set_active (1); + else if (pp->blackwhite.setting=="Luminance") + setting->set_active (2); + else if (pp->blackwhite.setting=="Landscape") + setting->set_active (3); + else if (pp->blackwhite.setting=="Portrait") + setting->set_active (4); + else if (pp->blackwhite.setting=="LowSensitivity") + setting->set_active (5); + else if (pp->blackwhite.setting=="HighSensitivity") + setting->set_active (6); + else if (pp->blackwhite.setting=="Panchromatic") + setting->set_active (7); + else if (pp->blackwhite.setting=="HyperPanchromatic") + setting->set_active (8); + else if (pp->blackwhite.setting=="Orthochromatic") + setting->set_active (9); + else if (pp->blackwhite.setting=="RGB-Abs") + setting->set_active (10); + else if (pp->blackwhite.setting=="RGB-Rel") + setting->set_active (11); + else if (pp->blackwhite.setting=="ROYGCBPM-Abs") + setting->set_active (12); + else if (pp->blackwhite.setting=="ROYGCBPM-Rel") + setting->set_active (13); + else if (pp->blackwhite.setting=="InfraRed") + setting->set_active (14); + settingChanged(); + + + if (pedited && !pedited->blackwhite.method) + method->set_active (3); // "Unchanged" + else if (pp->blackwhite.method=="Desaturation") + method->set_active (0); + else if (pp->blackwhite.method=="LumEqualizer") + method->set_active (1); + else if (pp->blackwhite.method=="ChannelMixer") + method->set_active (2); + methodChanged(); + + + if (pedited && !pedited->blackwhite.filter) + filter->set_active (9); // "Unchanged" + else if (pp->blackwhite.filter=="None") + filter->set_active (0); + else if (pp->blackwhite.filter=="Red") + filter->set_active (1); + else if (pp->blackwhite.filter=="Orange") + filter->set_active (2); + else if (pp->blackwhite.filter=="Yellow") + filter->set_active (3); + else if (pp->blackwhite.filter=="YellowGreen") + filter->set_active (4); + else if (pp->blackwhite.filter=="Green") + filter->set_active (5); + else if (pp->blackwhite.filter=="Cyan") + filter->set_active (6); + else if (pp->blackwhite.filter=="Blue") + filter->set_active (7); + else if (pp->blackwhite.filter=="Purple") + filter->set_active (8); + filterChanged(); + + enabledcc->set_active (pp->blackwhite.enabledcc); + lastEnabledcc = pp->blackwhite.enabledcc; + setEnabled (pp->blackwhite.enabled); + + mixerRed->setValue (pp->blackwhite.mixerRed); + mixerGreen->setValue (pp->blackwhite.mixerGreen); + mixerBlue->setValue (pp->blackwhite.mixerBlue); + gammaRed->setValue (pp->blackwhite.gammaRed); + gammaGreen->setValue (pp->blackwhite.gammaGreen); + gammaBlue->setValue (pp->blackwhite.gammaBlue); + mixerOrange->setValue (pp->blackwhite.mixerOrange); + mixerYellow->setValue (pp->blackwhite.mixerYellow); + mixerCyan->setValue (pp->blackwhite.mixerCyan); + mixerMagenta->setValue (pp->blackwhite.mixerMagenta); + mixerPurple->setValue (pp->blackwhite.mixerPurple); + luminanceCurve->setCurve (pp->blackwhite.luminanceCurve); + beforeCurve->setCurve (pp->blackwhite.beforeCurve); + beforeCurveMode->set_active(pp->blackwhite.beforeCurveMode); + afterCurve->setCurve (pp->blackwhite.afterCurve); +// afterCurveMode->set_active(pp->blackwhite.afterCurveMode); + + autoch->set_active (pp->blackwhite.autoc); + lastAuto = pp->blackwhite.autoc; + + algoconn.block(true); + if (pedited && !pedited->blackwhite.algo) + algo->set_active (2); + else if (pp->blackwhite.algo=="LI") + algo->set_active (0); + else if (pp->blackwhite.algo=="SP") + algo->set_active (1); + algoconn.block(false); + algoChanged(); + + + if (pedited) { + luminanceCurve->setUnChanged (!pedited->blackwhite.luminanceCurve); + beforeCurve->setUnChanged (!pedited->blackwhite.beforeCurve); + afterCurve->setUnChanged (!pedited->blackwhite.afterCurve); + autoch->set_inconsistent (!pedited->blackwhite.autoc); + set_inconsistent (multiImage && !pedited->blackwhite.enabled); + enabledcc->set_inconsistent (!pedited->blackwhite.enabledcc); + mixerRed->setEditedState (pedited->blackwhite.mixerRed ? Edited : UnEdited); + mixerGreen->setEditedState (pedited->blackwhite.mixerGreen ? Edited : UnEdited); + mixerBlue->setEditedState (pedited->blackwhite.mixerBlue ? Edited : UnEdited); + gammaRed->setEditedState (pedited->blackwhite.gammaRed ? Edited : UnEdited); + gammaGreen->setEditedState (pedited->blackwhite.gammaGreen ? Edited : UnEdited); + gammaBlue->setEditedState (pedited->blackwhite.gammaBlue ? Edited : UnEdited); + mixerOrange->setEditedState (pedited->blackwhite.mixerOrange ? Edited : UnEdited); + mixerYellow->setEditedState (pedited->blackwhite.mixerYellow ? Edited : UnEdited); + mixerCyan->setEditedState (pedited->blackwhite.mixerCyan ? Edited : UnEdited); + mixerMagenta->setEditedState (pedited->blackwhite.mixerMagenta ? Edited : UnEdited); + mixerPurple->setEditedState (pedited->blackwhite.mixerPurple ? Edited : UnEdited); + if (!pedited->blackwhite.beforeCurveMode) { + beforeCurveMode->set_active(4); // "Unchanged" + } +// if (!pedited->blackwhite.afterCurveMode) { +// afterCurveMode->set_active(1); // "Unchanged" +// } + } + methodconn.block(false); + filterconn.block(false); + settingconn.block(false); + //autoconn.block (false); + enaccconn.block (false); + + updateRGBLabel(); + + enableListener (); +} + +void BlackWhite::write (ProcParams* pp, ParamsEdited* pedited) { + pp->blackwhite.enabled = getEnabled(); + pp->blackwhite.luminanceCurve = luminanceCurve->getCurve (); + pp->blackwhite.autoc = autoch->get_active(); + pp->blackwhite.enabledcc = enabledcc->get_active (); + pp->blackwhite.mixerRed = mixerRed->getValue (); + pp->blackwhite.mixerGreen = mixerGreen->getValue (); + pp->blackwhite.mixerBlue = mixerBlue->getValue (); + pp->blackwhite.gammaRed = gammaRed->getValue (); + pp->blackwhite.gammaGreen = gammaGreen->getValue (); + pp->blackwhite.gammaBlue = gammaBlue->getValue (); + pp->blackwhite.mixerOrange = mixerOrange->getValue (); + pp->blackwhite.mixerYellow = mixerYellow->getValue (); + pp->blackwhite.mixerCyan = mixerCyan->getValue (); + pp->blackwhite.mixerMagenta = mixerMagenta->getValue (); + pp->blackwhite.mixerPurple = mixerPurple->getValue (); + pp->blackwhite.beforeCurve = beforeCurve->getCurve (); + pp->blackwhite.afterCurve = afterCurve->getCurve (); + + int tcMode = beforeCurveMode->get_active_row_number(); + if (tcMode == 0) pp->blackwhite.beforeCurveMode = BlackWhiteParams::TC_MODE_STD_BW; + else if (tcMode == 1) pp->blackwhite.beforeCurveMode = BlackWhiteParams::TC_MODE_WEIGHTEDSTD_BW; + else if (tcMode == 2) pp->blackwhite.beforeCurveMode = BlackWhiteParams::TC_MODE_FILMLIKE_BW; + else if (tcMode == 3) pp->blackwhite.beforeCurveMode = BlackWhiteParams::TC_MODE_SATANDVALBLENDING_BW; + +// tcMode = afterCurveMode->get_active_row_number(); +// if (tcMode == 0) pp->blackwhite.afterCurveMode = BlackWhiteParams::TC_MODE_STD_BW; + // else if (tcMode == 1) pp->blackwhite.afterCurveMode = BlackWhiteParams::TC_MODE_WEIGHTEDSTD; + + if (pedited) { + pedited->blackwhite.enabled = !get_inconsistent(); + pedited->blackwhite.luminanceCurve = !luminanceCurve->isUnChanged (); + pedited->blackwhite.autoc = !autoch->get_inconsistent(); + pedited->blackwhite.enabledcc = !enabledcc->get_inconsistent(); + pedited->blackwhite.mixerRed = mixerRed->getEditedState (); + pedited->blackwhite.mixerGreen = mixerGreen->getEditedState (); + pedited->blackwhite.mixerBlue = mixerBlue->getEditedState (); + pedited->blackwhite.gammaRed = gammaRed->getEditedState (); + pedited->blackwhite.gammaGreen = gammaGreen->getEditedState (); + pedited->blackwhite.gammaBlue = gammaBlue->getEditedState (); + pedited->blackwhite.filter = filter->get_active_text()!=M("GENERAL_UNCHANGED"); + pedited->blackwhite.setting = setting->get_active_text()!=M("GENERAL_UNCHANGED"); + pedited->blackwhite.method = method->get_active_text()!=M("GENERAL_UNCHANGED"); + pedited->blackwhite.mixerOrange = mixerOrange->getEditedState (); + pedited->blackwhite.mixerYellow = mixerYellow->getEditedState (); + pedited->blackwhite.mixerCyan = mixerCyan->getEditedState (); + pedited->blackwhite.mixerMagenta = mixerMagenta->getEditedState (); + pedited->blackwhite.mixerPurple = mixerPurple->getEditedState (); + pedited->blackwhite.beforeCurve = !beforeCurve->isUnChanged (); + pedited->blackwhite.beforeCurveMode = beforeCurveMode->get_active_row_number() != 4; + pedited->blackwhite.afterCurve = !afterCurve->isUnChanged (); + pedited->blackwhite.algo = algo->get_active_text()!=M("GENERAL_UNCHANGED"); + +// pedited->blackwhite.afterCurveMode = afterCurveMode->get_active_row_number() != 1; + } + if (method->get_active_row_number()==0) + pp->blackwhite.method = "Desaturation"; + else if (method->get_active_row_number()==1) + pp->blackwhite.method = "LumEqualizer"; + else if (method->get_active_row_number()==2) + pp->blackwhite.method = "ChannelMixer"; + + if (algo->get_active_row_number()==0) + pp->blackwhite.algo = "LI"; + else if (algo->get_active_row_number()==1) + pp->blackwhite.algo = "SP"; + + pp->blackwhite.setting = getSettingString(); + pp->blackwhite.filter = getFilterString(); +} + +void BlackWhite::algoChanged () { + if (listener && (multiImage||getEnabled()) ) { + listener->panelChanged (EvBWMethodalg, algo->get_active_text ());} +} + +void BlackWhite::curveChanged (CurveEditor* ce) { + if (listener) { + if (ce == beforeCurve) + listener->panelChanged (EvBWBeforeCurve, M("HISTORY_CUSTOMCURVE")); + if (ce == afterCurve) + listener->panelChanged (EvBWAfterCurve, M("HISTORY_CUSTOMCURVE")); + if (ce == luminanceCurve) + listener->panelChanged (EvBWLuminanceEqual, M("HISTORY_CUSTOMCURVE")); + } +} + +void BlackWhite::curveMode1Changed () { + if (listener) Glib::signal_idle().connect (sigc::mem_fun(*this, &BlackWhite::curveMode1Changed_)); +} +bool BlackWhite::curveMode1Changed_ () { + if (listener) listener->panelChanged (EvBWBeforeCurveMode, escapeHtmlChars(beforeCurveMode->get_active_text())); + return false; +} +/* +void BlackWhite::curveMode1Changed2 () { + if (listener) Glib::signal_idle().connect (sigc::mem_fun(*this, &BlackWhite::curveMode1Changed2_)); +} +bool BlackWhite::curveMode1Changed2_ () { + if (listener) listener->panelChanged (EvBWAfterCurveMode, escapeHtmlChars(afterCurveMode->get_active_text())); + return false; +} +*/ +void BlackWhite::colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller* caller) { + + float r, g, b; + + if (elemType == ColorCaller::CCET_VERTICAL_BAR) + valY = 0.5f; + + if (callerId == 1) { // Hue = f(Hue) + + float h = float((valY - 0.5) * 2. + valX); + if (h > 1.0f) + h -= 1.0f; + else if (h < 0.0f) + h += 1.0f; + Color::hsv2rgb01(h, 0.5f, 0.5f, r, g, b); + caller->ccRed = double(r); + caller->ccGreen = double(g); + caller->ccBlue = double(b); + } + else if (callerId == 2) { // Saturation = f(Hue) + Color::hsv2rgb01(float(valX), float(valY), 0.5f, r, g, b); + caller->ccRed = double(r); + caller->ccGreen = double(g); + caller->ccBlue = double(b); + } + else if (callerId == 3) { // Value = f(Hue) + Color::hsv2rgb01(float(valX), 0.5f, float(valY), r, g, b); + caller->ccRed = double(r); + caller->ccGreen = double(g); + caller->ccBlue = double(b); + } + else { + printf("Error: no curve displayed!\n"); + } +} + + +void BlackWhite::settingChanged () { + + if ( setting->get_active_row_number()==10 || setting->get_active_row_number()==11 ) { + // RGB Channel Mixer + showMixer(3); + hideEnabledCC(); + showFilter(); + } + else if ( setting->get_active_row_number()==12 || setting->get_active_row_number()==13 ) { + // ROYGCBPM Channel Mixer + showMixer(7); + showEnabledCC(); + showFilter(); + } + else if ( setting->get_active_row_number()==14 ) { + // Infrared + filter->set_active (0); + showMixer(3, false); + hideEnabledCC(); + hideFilter(); + } + else { + // RGB Presets + showMixer(3, false); + hideEnabledCC(); + showFilter(); + } + + // Checking "listener" to avoid "autoch" getting toggled off because it has to change the sliders when toggling on + if (listener){ + if (multiImage && autoch->get_inconsistent()) + autoch->set_inconsistent (false); + autoconn.block(true); + autoch->set_active (false); + autoconn.block(false); + lastAuto = false; + } + + updateRGBLabel(); + + if (listener && (multiImage||getEnabled())) { + listener->panelChanged (EvBWsetting, setting->get_active_text ()); + } +} + + +void BlackWhite::filterChanged () { + // Checking "listener" to avoid "autoch" getting toggled off because it has to change the sliders when toggling on + if (listener){ + if (multiImage && autoch->get_inconsistent()) + autoch->set_inconsistent (false); + autoconn.block(true); + autoch->set_active (false); + autoconn.block(false); + lastAuto = false; + } + + updateRGBLabel(); + + if (listener && (multiImage||getEnabled())) { + listener->panelChanged (EvBWfilter, filter->get_active_text ()); + } +} + +void BlackWhite::methodChanged () { + if(method->get_active_row_number()==2) { + // Channel Mixer + hideLuminance(); + + if(setting->get_active_row_number()==10 || setting->get_active_row_number()==11){ + hideEnabledCC(); + showMixer(3); + } + else if(setting->get_active_row_number()==12 || setting->get_active_row_number()==13) { + showEnabledCC(); + showMixer(7); + } + else { + hideEnabledCC(); + showMixer(3, false); + } + beforeCurveCEG->show(); + afterCurveCEG->show(); + + bool wasEnabled = disableListener(); + settingChanged(); + if (wasEnabled) enableListener(); + } + else if(method->get_active_row_number()==1) { + // Luminance Equalizer + showLuminance(); + hideMixer(); + beforeCurveCEG->show(); + afterCurveCEG->show(); + } + else if(method->get_active_row_number()==0) { + // Desaturation + hideLuminance(); + hideMixer(); + beforeCurveCEG->show(); + afterCurveCEG->show(); + } + if (listener && (multiImage||getEnabled())) { + listener->panelChanged (EvBWmethod, method->get_active_text ()); + } +} + +void BlackWhite::enabledChanged () { + if (listener) { + if (get_inconsistent()) + listener->panelChanged (EvBWChmixEnabled, M("GENERAL_UNCHANGED")); + else if (getEnabled()) + listener->panelChanged (EvBWChmixEnabled, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvBWChmixEnabled, M("GENERAL_DISABLED")); + } +} + +void BlackWhite::neutral_pressed () { + // This method deselects auto chmixer and sets "neutral" values to params + disableListener(); + + if (multiImage && autoch->get_inconsistent()) + autoch->set_inconsistent (false); + autoconn.block(true); + autoch->set_active (false); + autoconn.block(false); + lastAuto = false; + + int activeSetting = setting->get_active_row_number(); + if (activeSetting < 10 || activeSetting > 13) + setting->set_active (11); + filter->set_active (0); + mixerRed->resetValue(false); + mixerGreen->resetValue(false); + mixerBlue->resetValue(false); + mixerOrange->resetValue(false); + mixerYellow->resetValue(false); + mixerMagenta->resetValue(false); + mixerPurple->resetValue(false); + mixerCyan->resetValue(false); + + enableListener(); + + updateRGBLabel(); + + listener->panelChanged (EvNeutralBW, M("ADJUSTER_RESET_TO_DEFAULT")); +} + +void BlackWhite::enabledcc_toggled () { + + // toggling off the Complementary Colors does switch off the Auto button + if (multiImage) { + // multiple image editing (batch) + if (enabledcc->get_inconsistent()) { + enabledcc->set_inconsistent (false); // set consistent + enaccconn.block (true); + enabledcc->set_active (false); // ... and deactivated + enaccconn.block (false); + } + else if (lastEnabledcc) + enabledcc->set_inconsistent (true); + + lastEnabledcc = enabledcc->get_active (); + } + + if (multiImage && autoch->get_inconsistent()) + autoch->set_inconsistent (false); + autoconn.block(true); + autoch->set_active (false); + autoconn.block(false); + lastAuto = false; + + updateRGBLabel(); + + if (listener) { + if (enabledcc->get_inconsistent()) + listener->panelChanged (EvBWChmixEnabledLm, M("GENERAL_UNCHANGED")); + else if (enabledcc->get_active ()) { + listener->panelChanged (EvBWChmixEnabledLm, M("GENERAL_ENABLED")); + } + else { + listener->panelChanged (EvBWChmixEnabledLm, M("GENERAL_DISABLED")); + } + } +} + + +void BlackWhite::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + mixerRed->setDefault (defParams->blackwhite.mixerRed); + mixerGreen->setDefault (defParams->blackwhite.mixerGreen); + mixerBlue->setDefault (defParams->blackwhite.mixerBlue); + gammaRed->setDefault (defParams->blackwhite.gammaRed); + gammaGreen->setDefault (defParams->blackwhite.gammaGreen); + gammaBlue->setDefault (defParams->blackwhite.gammaBlue); + mixerOrange->setDefault (defParams->blackwhite.mixerOrange); + mixerYellow->setDefault (defParams->blackwhite.mixerYellow); + mixerCyan->setDefault (defParams->blackwhite.mixerCyan); + mixerMagenta->setDefault (defParams->blackwhite.mixerMagenta); + mixerPurple->setDefault (defParams->blackwhite.mixerPurple); + + if (pedited) { + mixerRed->setDefaultEditedState (pedited->blackwhite.mixerRed ? Edited : UnEdited); + mixerGreen->setDefaultEditedState (pedited->blackwhite.mixerGreen ? Edited : UnEdited); + mixerBlue->setDefaultEditedState (pedited->blackwhite.mixerBlue ? Edited : UnEdited); + gammaRed->setDefaultEditedState (pedited->blackwhite.gammaRed ? Edited : UnEdited); + gammaGreen->setDefaultEditedState (pedited->blackwhite.gammaGreen ? Edited : UnEdited); + gammaBlue->setDefaultEditedState (pedited->blackwhite.gammaBlue ? Edited : UnEdited); + mixerOrange->setDefaultEditedState (pedited->blackwhite.mixerOrange ? Edited : UnEdited); + mixerYellow->setDefaultEditedState (pedited->blackwhite.mixerYellow ? Edited : UnEdited); + mixerCyan->setDefaultEditedState (pedited->blackwhite.mixerCyan ? Edited : UnEdited); + mixerMagenta->setDefaultEditedState (pedited->blackwhite.mixerMagenta ? Edited : UnEdited); + mixerPurple->setDefaultEditedState (pedited->blackwhite.mixerPurple ? Edited : UnEdited); + } + else { + mixerRed->setDefaultEditedState (Irrelevant); + mixerGreen->setDefaultEditedState (Irrelevant); + mixerBlue->setDefaultEditedState (Irrelevant); + gammaRed->setDefaultEditedState (Irrelevant); + gammaGreen->setDefaultEditedState (Irrelevant); + gammaBlue->setDefaultEditedState (Irrelevant); + mixerOrange->setDefaultEditedState (Irrelevant); + mixerYellow->setDefaultEditedState (Irrelevant); + mixerCyan->setDefaultEditedState (Irrelevant); + mixerMagenta->setDefaultEditedState (Irrelevant); + mixerPurple->setDefaultEditedState (Irrelevant); + } +} + +void BlackWhite::autoch_toggled () { + + if (batchMode) { + if (multiImage) { + if (autoch->get_inconsistent()) { + autoch->set_inconsistent (false); + autoconn.block (true); + autoch->set_active (false); + autoconn.block (false); + } + else if (lastAuto) + autoch->set_inconsistent (true); + } + + lastAuto = autoch->get_active (); + + mixerRed->setEditedState (UnEdited); + mixerGreen->setEditedState (UnEdited); + mixerBlue->setEditedState (UnEdited); + mixerOrange->setEditedState (UnEdited); + mixerYellow->setEditedState (UnEdited); + mixerPurple->setEditedState (UnEdited); + mixerMagenta->setEditedState (UnEdited); + mixerCyan->setEditedState (UnEdited); + + bool wasEnabled = disableListener(); + if (mixerRed->getAddMode()) + mixerRed->resetValue(false); + if (mixerGreen->getAddMode()) + mixerGreen->resetValue(true); + if (mixerBlue->getAddMode()) + mixerBlue->resetValue(true); + if (mixerOrange->getAddMode()) + mixerOrange->resetValue(true); + if (mixerYellow->getAddMode()) + mixerYellow->resetValue(true); + if (mixerMagenta->getAddMode()) + mixerMagenta->resetValue(true); + if (mixerPurple->getAddMode()) + mixerPurple->resetValue(true); + if (mixerCyan->getAddMode()) + mixerCyan->resetValue(true); + setting->set_active (11); + filter->set_active (0); + if (wasEnabled) enableListener(); + + if (listener) { + if (autoch->get_inconsistent()) + listener->panelChanged (EvAutoch, M("GENERAL_UNCHANGED")); + else if (autoch->get_active ()) + listener->panelChanged (EvAutoch, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvAutoch, M("GENERAL_DISABLED")); + } + } + else { + if (autoch->get_active()) { + bool wasEnabled = disableListener(); + mixerRed->setValue(33); + mixerGreen->setValue(33); + mixerBlue->setValue(33); + mixerOrange->setValue(33); + mixerYellow->setValue(33); + mixerMagenta->setValue(33); + mixerPurple->setValue(33); + mixerCyan->setValue(33); + setting->set_active (11); + filter->set_active (0); + if (wasEnabled) enableListener(); + + updateRGBLabel(); + + if (listener) + listener->panelChanged (EvAutoch, M("GENERAL_ENABLED")); + } + else { + if (listener) + listener->panelChanged (EvAutoch, M("GENERAL_DISABLED")); + } + } + +} + +void BlackWhite::adjusterChanged (Adjuster* a, double newval) { + + // Checking "listener" to avoid "autoch" getting toggled off because it has to change the sliders when toggling on + if (listener && (a==mixerRed || a==mixerGreen || a==mixerBlue || a==mixerOrange || a==mixerYellow || a==mixerMagenta || a==mixerPurple || a==mixerCyan) ) { + if (multiImage && autoch->get_inconsistent()) + autoch->set_inconsistent (false); + autoconn.block(true); + autoch->set_active (false); + autoconn.block(false); + lastAuto = false; + } + + if (a == mixerRed || a==mixerGreen || a== mixerBlue + || a == mixerOrange || a == mixerYellow ||a == mixerCyan + || a == mixerMagenta || a == mixerPurple) + + updateRGBLabel(); + + if (listener && (multiImage||getEnabled())) { + Glib::ustring value = a->getTextValue(); + if (a == mixerRed) + listener->panelChanged (EvBWred, value ); + else if (a == mixerGreen) + listener->panelChanged (EvBWgreen, value ); + else if (a == mixerBlue) + listener->panelChanged (EvBWblue, value ); + else if (a == gammaGreen) + listener->panelChanged (EvBWgreengam, value ); + else if (a == gammaBlue) + listener->panelChanged (EvBWbluegam, value ); + else if (a == gammaRed) + listener->panelChanged (EvBWredgam, value ); + else if (a == mixerOrange) + listener->panelChanged (EvBWoran, value ); + else if (a == mixerYellow) + listener->panelChanged (EvBWyell, value ); + else if (a == mixerCyan) + listener->panelChanged (EvBWcyan, value ); + else if (a == mixerMagenta) + listener->panelChanged (EvBWmag, value ); + else if (a == mixerPurple) + listener->panelChanged (EvBWpur, value ); + } +} + +void BlackWhite::updateRGBLabel () { + if (!batchMode) { + float kcorrec=1.f; + float r, g, b; + if (autoch->get_active()) { + r = nextredbw; + g = nextgreenbw; + b = nextbluebw; + } + else { + r = mixerRed->getValue(); + g = mixerGreen->getValue(); + b = mixerBlue->getValue(); + } + double mixR, mixG, mixB; + float filcor; + Glib::ustring sSetting = getSettingString(); + Color::computeBWMixerConstants(sSetting, getFilterString(),getalgoString(), filcor, r, g, b, + mixerOrange->getValue(), mixerYellow->getValue(), mixerCyan->getValue(), mixerPurple->getValue(), mixerMagenta->getValue(), + autoch->get_active(), enabledcc->get_active(), kcorrec, mixR, mixG, mixB); + if( filcor!=1.f){ + r=kcorrec*r/(r+g+b); + g=kcorrec*g/(r+g+b); + b=kcorrec*b/(r+g+b); + } + RGBLabels->set_text( + Glib::ustring::compose(M("TP_BWMIX_RGBLABEL"), + Glib::ustring::format(std::fixed, std::setprecision(1), r*100.), + Glib::ustring::format(std::fixed, std::setprecision(1), g*100.), + Glib::ustring::format(std::fixed, std::setprecision(1), b*100.), + Glib::ustring::format(std::fixed, std::setprecision(0), ceil(kcorrec*100./*(r+g+b)*100.)*/))) + ); + // We have to update the RGB sliders too if preset values has been chosen + if (sSetting != "RGB-Abs" && sSetting != "RGB-Rel" && sSetting != "ROYGCBPM-Abs" && sSetting != "ROYGCBPM-Rel") { + mixerRed->setValue(mixR); + mixerGreen->setValue(mixG); + mixerBlue->setValue(mixB); + } + } +} + +void BlackWhite::setBatchMode (bool batchMode) { + removeIfThere (autoHBox, autoch, false); + autoch = Gtk::manage (new Gtk::CheckButton (M("TP_BWMIX_AUTOCH"))); + autoch->set_tooltip_markup (M("TP_BWMIX_AUTOCH_TIP")); + autoconn = autoch->signal_toggled().connect( sigc::mem_fun(*this, &BlackWhite::autoch_toggled) ); + autoHBox->pack_start (*autoch); + + removeIfThere (mixerVBox, RGBLabels, false); + delete RGBLabels; + RGBLabels = NULL; + + ToolPanel::setBatchMode (batchMode); + mixerRed->showEditedCB (); + mixerOrange->showEditedCB (); + mixerYellow->showEditedCB (); + mixerGreen->showEditedCB (); + mixerCyan->showEditedCB (); + mixerBlue->showEditedCB (); + mixerMagenta->showEditedCB (); + mixerPurple->showEditedCB (); + gammaRed->showEditedCB (); + gammaGreen->showEditedCB (); + gammaBlue->showEditedCB (); + method->append_text (M("GENERAL_UNCHANGED")); + filter->append_text (M("GENERAL_UNCHANGED")); + setting->append_text (M("GENERAL_UNCHANGED")); + luminanceCEG->setBatchMode (batchMode); + beforeCurveCEG->setBatchMode (batchMode); + beforeCurveCEG->show(); + beforeCurveMode->append_text (M("GENERAL_UNCHANGED")); + afterCurveCEG->setBatchMode (batchMode); + afterCurveCEG->show(); +// afterCurveMode->append_text (M("GENERAL_UNCHANGED")); + algo->append_text (M("GENERAL_UNCHANGED")); + + showLuminance(); + showFilter(); + showEnabledCC(); + showGamma(); + showMixer(7); +} + +void BlackWhite::autoOpenCurve () { + luminanceCurve->openIfNonlinear(); + beforeCurve->openIfNonlinear(); + afterCurve->openIfNonlinear(); +} +void BlackWhite::setEditProvider (EditDataProvider *provider) { + luminanceCurve->setEditProvider(provider); + beforeCurve->setEditProvider(provider); + afterCurve->setEditProvider(provider); +} + +void BlackWhite::setAdjusterBehavior (bool bwadd, bool bwgadd) { + + mixerRed->setAddMode(bwadd); + mixerOrange->setAddMode(bwadd); + mixerYellow->setAddMode(bwadd); + mixerGreen->setAddMode(bwadd); + mixerCyan->setAddMode(bwadd); + mixerBlue->setAddMode(bwadd); + mixerMagenta->setAddMode(bwadd); + mixerPurple->setAddMode(bwadd); + + gammaRed->setAddMode(bwgadd); + gammaGreen->setAddMode(bwgadd); + gammaBlue->setAddMode(bwgadd); +} + +void BlackWhite::trimValues (rtengine::procparams::ProcParams* pp) { + + mixerRed->trimValue (pp->blackwhite.mixerRed); + mixerGreen->trimValue (pp->blackwhite.mixerGreen); + mixerBlue->trimValue (pp->blackwhite.mixerBlue); + gammaRed->trimValue (pp->blackwhite.gammaRed); + gammaGreen->trimValue (pp->blackwhite.gammaGreen); + gammaBlue->trimValue (pp->blackwhite.gammaBlue); + mixerOrange->trimValue (pp->blackwhite.mixerOrange); + mixerYellow->trimValue (pp->blackwhite.mixerYellow); + mixerCyan->trimValue (pp->blackwhite.mixerCyan); + mixerMagenta->trimValue (pp->blackwhite.mixerMagenta); + mixerPurple->trimValue (pp->blackwhite.mixerPurple); +} + +void BlackWhite::showLuminance() { + luminanceCEG->show(); + luminanceSep->show(); +} + +void BlackWhite::hideLuminance() { + if (!batchMode) { + luminanceCEG->hide(); + luminanceSep->hide(); + } +} + +void BlackWhite::showFilter() { + filterHBox->show(); + filterSep->show(); +} + +void BlackWhite::hideFilter() { + if (!batchMode) { + filterHBox->hide(); + filterSep->hide(); + } +} + +void BlackWhite::showEnabledCC() { + enabledcc->show(); + enabledccSep->show(); +} + +void BlackWhite::hideEnabledCC() { + if (!batchMode) { + enabledcc->hide(); + enabledccSep->hide(); + } +} + +void BlackWhite::showMixer(int nChannels, bool RGBIsSensitive) { + if (!batchMode) + RGBLabels->show(); + + if (!batchMode && nChannels == 3) { + mixerRed->show(); mixerRed->set_sensitive (RGBIsSensitive); + mixerGreen->show(); mixerGreen->set_sensitive (RGBIsSensitive); + mixerBlue->show(); mixerBlue->set_sensitive (RGBIsSensitive); + filterSep2->hide(); + algo->hide(); + alLabel->hide(); + mixerOrange->hide(); + mixerYellow->hide(); + mixerCyan->hide(); + mixerMagenta->hide(); + mixerPurple->hide(); + } + else { + mixerRed->show(); mixerRed->set_sensitive (true); + mixerGreen->show(); mixerGreen->set_sensitive (true); + mixerBlue->show(); mixerBlue->set_sensitive (true); + filterSep2->show(); + mixerOrange->show(); + algo->show(); + alLabel->show(); + mixerYellow->show(); + mixerCyan->show(); + mixerMagenta->show(); + mixerPurple->show(); + } + mixerFrame->show(); +} + +void BlackWhite::hideMixer() { + if (!batchMode) + mixerFrame->hide(); +} + +void BlackWhite::showGamma() { + gammaFrame->show(); +} + +void BlackWhite::hideGamma() { + if (!batchMode) + gammaFrame->hide(); +} + +Glib::ustring BlackWhite::getalgoString() { + Glib::ustring retVal; + if (algo->get_active_row_number()==0) + retVal = "LI"; + else if (algo->get_active_row_number()==1) + retVal = "SP"; + return retVal; +} + +Glib::ustring BlackWhite::getSettingString() { + Glib::ustring retVal; + if (setting->get_active_row_number()==0) + retVal = "NormalContrast"; + else if (setting->get_active_row_number()==1) + retVal = "HighContrast"; + else if (setting->get_active_row_number()==2) + retVal = "Luminance"; + else if (setting->get_active_row_number()==3) + retVal = "Landscape"; + else if (setting->get_active_row_number()==4) + retVal = "Portrait"; + else if (setting->get_active_row_number()==5) + retVal = "LowSensitivity"; + else if (setting->get_active_row_number()==6) + retVal = "HighSensitivity"; + else if (setting->get_active_row_number()==7) + retVal = "Panchromatic"; + else if (setting->get_active_row_number()==8) + retVal = "HyperPanchromatic"; + else if (setting->get_active_row_number()==9) + retVal = "Orthochromatic"; + else if (setting->get_active_row_number()==10) + retVal = "RGB-Abs"; + else if (setting->get_active_row_number()==11) + retVal = "RGB-Rel"; + else if (setting->get_active_row_number()==12) + retVal = "ROYGCBPM-Abs"; + else if (setting->get_active_row_number()==13) + retVal = "ROYGCBPM-Rel"; + else if (setting->get_active_row_number()==14) + retVal = "InfraRed"; + return retVal; +} + +Glib::ustring BlackWhite::getFilterString() { + Glib::ustring retVal; + if (filter->get_active_row_number()==0) + retVal = "None"; + else if (filter->get_active_row_number()==1) + retVal = "Red"; + else if (filter->get_active_row_number()==2) + retVal = "Orange"; + else if (filter->get_active_row_number()==3) + retVal = "Yellow"; + else if (filter->get_active_row_number()==4) + retVal = "YellowGreen"; + else if (filter->get_active_row_number()==5) + retVal = "Green"; + else if (filter->get_active_row_number()==6) + retVal = "Cyan"; + else if (filter->get_active_row_number()==7) + retVal = "Blue"; + else if (filter->get_active_row_number()==8) + retVal = "Purple"; + return retVal; +} diff --git a/rtgui/blackwhite.h b/rtgui/blackwhite.h new file mode 100644 index 000000000..22e032a65 --- /dev/null +++ b/rtgui/blackwhite.h @@ -0,0 +1,138 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _BLACKWHITE_H_ +#define _BLACKWHITE_H_ + +#include +#include "adjuster.h" +#include "toolpanel.h" +#include "guiutils.h" +#include "curveeditor.h" +#include "curveeditorgroup.h" +#include "mycurve.h" +#include "colorprovider.h" + +class BlackWhite : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public rtengine::AutoBWListener, public CurveListener, public ColorProvider{ + + protected: + FlatCurveEditor* luminanceCurve; + Gtk::HSeparator* luminanceSep; + CurveEditorGroup* luminanceCEG; + CurveEditorGroup* beforeCurveCEG; + DiagonalCurveEditor* beforeCurve; + MyComboBoxText* beforeCurveMode; + CurveEditorGroup* afterCurveCEG; + DiagonalCurveEditor* afterCurve; + MyComboBoxText* afterCurveMode; + Gtk::ToggleButton* autoch; + Gtk::HBox* autoHBox; + Gtk::Button* neutral; + Gtk::Label* RGBLabels; + MyComboBoxText* algo; + sigc::connection algoconn; + Gtk::Label* alLabel; + Gtk::HBox* algoHBox; + + Adjuster *mixerRed; + Adjuster *mixerGreen; + Adjuster *mixerBlue; + Adjuster *gammaRed; + Adjuster *gammaGreen; + Adjuster *gammaBlue; + Adjuster *mixerOrange; + Adjuster *mixerYellow; + Adjuster *mixerCyan; + Adjuster *mixerMagenta; + Adjuster *mixerPurple; + MyComboBoxText* method; + sigc::connection methodconn; + Gtk::HBox* filterHBox; + Gtk::HSeparator* filterSep, *filterSep2; + MyComboBoxText* filter; + sigc::connection filterconn; + Gtk::HBox* settingHBox; + MyComboBoxText* setting; + sigc::connection settingconn; + Gtk::Frame* mixerFrame; + Gtk::VBox * mixerVBox; + Gtk::Frame* gammaFrame; + + Gtk::Image *imgIcon[11]; + + Gtk::HSeparator* enabledccSep; + Gtk::CheckButton* enabledcc; + bool lastEnabledcc, lastAuto; + sigc::connection enaccconn,tcmodeconn,tcmodeconn2, autoconn, neutralconn; + + double nextredbw; + double nextgreenbw; + double nextbluebw; + + void showLuminance(); + void hideLuminance(); + void showFilter(); + void hideFilter(); + void showEnabledCC(); + void hideEnabledCC(); + void showMixer(int nChannels, bool RGBIsSensitive=true); + void hideMixer(); + void showGamma(); + void hideGamma(); + + public: + + BlackWhite (); + ~BlackWhite (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + void autoOpenCurve (); + void setEditProvider (EditDataProvider *provider); + + void autoch_toggled (); + void neutral_pressed (); + + void updateRGBLabel (); + void adjusterChanged (Adjuster* a, double newval); + void setAdjusterBehavior (bool bwadd, bool bwgadd); + void trimValues (rtengine::procparams::ProcParams* pp); + void enabledcc_toggled (); + void enabledChanged (); + void methodChanged (); + void filterChanged (); + void settingChanged (); + virtual void colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller* caller); + void BWChanged (double redbw, double greenbw, double bluebw); + bool BWComputed_ (); + void curveChanged (CurveEditor* ce); + void curveMode1Changed (); + bool curveMode1Changed_ (); + void curveMode1Changed2 (); + bool curveMode1Changed2_ (); + void algoChanged (); + + Glib::ustring getSettingString (); + Glib::ustring getFilterString (); + Glib::ustring getalgoString (); + +}; + +#endif diff --git a/rtgui/bqentryupdater.cc b/rtgui/bqentryupdater.cc new file mode 100644 index 000000000..44395c8ff --- /dev/null +++ b/rtgui/bqentryupdater.cc @@ -0,0 +1,176 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "bqentryupdater.h" +#include +#include "guiutils.h" + +BatchQueueEntryUpdater batchQueueEntryUpdater; + +BatchQueueEntryUpdater::BatchQueueEntryUpdater () + : tostop(false), stopped(true), thread(NULL), qMutex(NULL) { +} + +void BatchQueueEntryUpdater::process (guint8* oimg, int ow, int oh, int newh, BQEntryUpdateListener* listener, rtengine::ProcParams* pparams, Thumbnail* thumbnail) { + if (!oimg && (!pparams || !thumbnail)) { + //printf("WARNING! !oimg && (!pparams || !thumbnail)\n"); + return; + } + + if (!qMutex) + qMutex = new MyMutex (); + + qMutex->lock (); + // look up if an older version is in the queue + std::list::iterator i; + for (i=jqueue.begin(); i!=jqueue.end(); i++) + if (i->oimg==oimg && i->listener==listener) { + i->ow = ow; + i->oh = oh; + i->newh = newh; + i->listener = listener; + i->pparams = pparams; + i->thumbnail = thumbnail; + break; + } + + // not found, create and append new job + if (i==jqueue.end ()) { + Job j; + j.oimg = oimg; + j.ow = ow; + j.oh = oh; + j.newh = newh; + j.listener = listener; + j.pparams = pparams; + j.thumbnail = thumbnail; + jqueue.push_back (j); + } + qMutex->unlock (); + + // Start thread if not running yet + if (stopped) { + stopped = false; + tostop = false; + +#if __GNUC__ == 4 && __GNUC_MINOR__ == 8 && defined( WIN32 ) && defined(__x86_64__) + #undef THREAD_PRIORITY_NORMAL + // See Issue 2384 comment #3 + thread = Glib::Thread::create(sigc::mem_fun(*this, &BatchQueueEntryUpdater::processThread), (unsigned long int)0, true, true, Glib::THREAD_PRIORITY_NORMAL); +#else + #undef THREAD_PRIORITY_LOW + thread = Glib::Thread::create(sigc::mem_fun(*this, &BatchQueueEntryUpdater::processThread), (unsigned long int)0, true, true, Glib::THREAD_PRIORITY_LOW); +#endif + } +} + +void BatchQueueEntryUpdater::processThread () { + // TODO: process visible jobs first + bool isEmpty=false; + + while (!tostop && !isEmpty) { + + qMutex->lock (); + isEmpty=jqueue.empty (); // do NOT put into while() since it must be within mutex section + Job current; + if (!isEmpty) { + current = jqueue.front (); + jqueue.pop_front (); + } + qMutex->unlock (); + if(isEmpty) + break; + rtengine::IImage8* img = NULL; + bool newBuffer = false; + if (current.thumbnail && current.pparams) { + // the thumbnail and the pparams are provided, it means that we have to build the original preview image + double tmpscale; + img = current.thumbnail->processThumbImage (*current.pparams, current.oh, tmpscale); + //current.thumbnail->decreaseRef (); // WARNING: decreasing refcount (and maybe deleting) thumbnail, with or without processed image + if (img) { + int prevw = img->getWidth(); + int prevh = img->getHeight(); +#ifndef NDEBUG + if (current.ow != img->getW() || current.oh != img->getH()) + printf("WARNING! Expected image size: %dx%d ; image size is: %dx%d\n", current.ow, current.oh, img->getW(), img->getH()); + assert ((current.ow+1)*current.oh >= img->getW()*img->getH()); +#endif + current.ow = prevw; + current.oh = prevh; + if (!current.oimg) { + current.oimg = new guint8[prevw*prevh*3]; + newBuffer = true; + } + memcpy(current.oimg, img->getData(), prevw * prevh * 3); + img->free(); + } + } + + if (current.oimg && !isEmpty && current.listener) { + int neww = current.newh * current.ow / current.oh; + guint8* img = new guint8 [current.newh*neww*3]; + thumbInterp (current.oimg, current.ow, current.oh, img, neww, current.newh); + current.listener->updateImage (img, neww, current.newh, current.ow, current.oh, newBuffer?current.oimg:NULL); + } + if(current.oimg) { + delete[] current.oimg; + current.oimg = NULL; + } + } + + stopped = true; +} + + +void BatchQueueEntryUpdater::removeJobs (BQEntryUpdateListener* listener) { + if (!qMutex) return; + + qMutex->lock (); + bool ready = false; + while (!ready) { + ready = true; + std::list::iterator i; + for (i=jqueue.begin(); i!=jqueue.end(); i++) + if (i->listener == listener) { + jqueue.erase (i); + ready = false; + break; + } + } + qMutex->unlock (); +} + +void BatchQueueEntryUpdater::terminate () { + // never started or currently not running? + if (!qMutex || stopped) return; + + if (!stopped) { + // Yield to currently running thread and wait till it's finished + GThreadUnLock lock; + tostop = true; + Glib::Thread::self()->yield(); + if (!stopped) thread->join (); + } + + // Remove remaining jobs + qMutex->lock (); + while (!jqueue.empty()) jqueue.pop_front (); + qMutex->unlock (); +} + + diff --git a/rtgui/bqentryupdater.h b/rtgui/bqentryupdater.h new file mode 100644 index 000000000..f794e4cec --- /dev/null +++ b/rtgui/bqentryupdater.h @@ -0,0 +1,63 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _BQENTRYUPDATER_ +#define _BQENTRYUPDATER_ + +#include +#include "../rtengine/rtengine.h" +#include "threadutils.h" +#include "thumbnail.h" + +class BQEntryUpdateListener { + + public: + virtual ~BQEntryUpdateListener () {} + virtual void updateImage (guint8* img, int w, int h, int origw, int origh, guint8* newOPreview) {} +}; + +class BatchQueueEntryUpdater { + + struct Job { + guint8* oimg; + int ow, oh, newh; + BQEntryUpdateListener* listener; + rtengine::ProcParams* pparams; + Thumbnail* thumbnail; + }; + + protected: + bool tostop; + bool stopped; + std::list jqueue; + Glib::Thread* thread; + MyMutex* qMutex; + + public: + BatchQueueEntryUpdater (); + + void process (guint8* oimg, int ow, int oh, int newh, BQEntryUpdateListener* listener, rtengine::ProcParams* pparams=NULL, Thumbnail* thumbnail=NULL); + void removeJobs (BQEntryUpdateListener* listener); + void terminate (); + + void processThread (); +}; + +extern BatchQueueEntryUpdater batchQueueEntryUpdater; + +#endif diff --git a/rtgui/browserfilter.cc b/rtgui/browserfilter.cc new file mode 100644 index 000000000..4118fcf48 --- /dev/null +++ b/rtgui/browserfilter.cc @@ -0,0 +1,33 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "browserfilter.h" + +BrowserFilter::BrowserFilter () : exifFilterEnabled (false) { + + showTrash = true; + for (int i=0; i<6; i++){ + showRanked[i] = true; + showCLabeled[i] = true; + } + for (int i=0; i<2; i++){ + showEdited[i] = true; + showRecentlySaved[i] = true; + } +} + diff --git a/rtgui/browserfilter.h b/rtgui/browserfilter.h new file mode 100644 index 000000000..acde5c387 --- /dev/null +++ b/rtgui/browserfilter.h @@ -0,0 +1,45 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _BROWSERFILTER_ +#define _BROWSERFILTER_ + +#include "exiffiltersettings.h" +#include + +class BrowserFilter { + + public: + bool showRanked[6]; + bool showCLabeled[6]; + bool showTrash; + bool showNotTrash; + bool showEdited[2]; + bool showRecentlySaved[2]; + bool multiselect; + + Glib::ustring queryString; + Glib::ustring queryFileName; + + bool exifFilterEnabled; + ExifFilterSettings exifFilter; + + BrowserFilter (); +}; + +#endif diff --git a/rtgui/cacheimagedata.cc b/rtgui/cacheimagedata.cc new file mode 100644 index 000000000..ca210cf6d --- /dev/null +++ b/rtgui/cacheimagedata.cc @@ -0,0 +1,183 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "cacheimagedata.h" +#include +#include +#include "../rtengine/safekeyfile.h" +#include "../rtengine/safegtk.h" +#include "version.h" +#include + +CacheImageData::CacheImageData () + : md5(""), supported(false), format(FT_Invalid), rankOld(-1), inTrashOld(false), recentlySaved(false), + timeValid(false), exifValid(false), redAWBMul(-1.0), greenAWBMul(-1.0), blueAWBMul(-1.0), thumbImgType(0) { +} + +/* + * Load the General, DateTime, ExifInfo, File info and ExtraRawInfo sections of the image data file + */ +int CacheImageData::load (const Glib::ustring& fname) { + setlocale(LC_NUMERIC, "C"); // to set decimal point to "." + rtengine::SafeKeyFile keyFile; + + try { + if (keyFile.load_from_file (fname)) { + + if (keyFile.has_group ("General")) { + if (keyFile.has_key ("General", "MD5")) md5 = keyFile.get_string ("General", "MD5"); + if (keyFile.has_key ("General", "Version")) version = keyFile.get_string ("General", "Version"); + if (keyFile.has_key ("General", "Supported")) supported = keyFile.get_boolean ("General", "Supported"); + if (keyFile.has_key ("General", "Format")) format = (ThFileType)keyFile.get_integer ("General", "Format"); + if (keyFile.has_key ("General", "Rank")) rankOld = keyFile.get_integer ("General", "Rank"); + if (keyFile.has_key ("General", "InTrash")) inTrashOld = keyFile.get_boolean ("General", "InTrash"); + if (keyFile.has_key ("General", "RecentlySaved")) recentlySaved = keyFile.get_boolean ("General", "RecentlySaved"); + } + + timeValid = keyFile.has_group ("DateTime"); + + if (timeValid) { + if (keyFile.has_key ("DateTime", "Year")) year = keyFile.get_integer ("DateTime", "Year"); + if (keyFile.has_key ("DateTime", "Month")) month = keyFile.get_integer ("DateTime", "Month"); + if (keyFile.has_key ("DateTime", "Day")) day = keyFile.get_integer ("DateTime", "Day"); + if (keyFile.has_key ("DateTime", "Hour")) hour = keyFile.get_integer ("DateTime", "Hour"); + if (keyFile.has_key ("DateTime", "Min")) min = keyFile.get_integer ("DateTime", "Min"); + if (keyFile.has_key ("DateTime", "Sec")) sec = keyFile.get_integer ("DateTime", "Sec"); + } + + exifValid = false; + + if (keyFile.has_group ("ExifInfo")) { + exifValid = true; + if (keyFile.has_key ("ExifInfo", "Valid")) exifValid = keyFile.get_boolean ("ExifInfo", "Valid"); + + if (exifValid) { + if (keyFile.has_key ("ExifInfo", "FNumber")) fnumber = keyFile.get_double ("ExifInfo", "FNumber"); + if (keyFile.has_key ("ExifInfo", "Shutter")) shutter = keyFile.get_double ("ExifInfo", "Shutter"); + if (keyFile.has_key ("ExifInfo", "FocalLen")) focalLen = keyFile.get_double ("ExifInfo", "FocalLen"); + if (keyFile.has_key ("ExifInfo", "FocalLen35mm")) focalLen35mm = keyFile.get_double ("ExifInfo", "FocalLen35mm"); + else focalLen35mm=focalLen; // prevent crashes on old files + if (keyFile.has_key ("ExifInfo", "FocusDist")) focusDist = keyFile.get_double ("ExifInfo", "FocusDist"); + else focusDist=0; + if (keyFile.has_key ("ExifInfo", "ISO")) iso = keyFile.get_integer ("ExifInfo", "ISO"); + if (keyFile.has_key ("ExifInfo", "ExpComp")) expcomp = keyFile.get_string ("ExifInfo", "ExpComp"); + } + if (keyFile.has_key ("ExifInfo", "Lens")) lens = keyFile.get_string ("ExifInfo", "Lens"); + if (keyFile.has_key ("ExifInfo", "CameraMake")) camMake = keyFile.get_string ("ExifInfo", "CameraMake"); + if (keyFile.has_key ("ExifInfo", "CameraModel")) camModel = keyFile.get_string ("ExifInfo", "CameraModel"); + } + + if (keyFile.has_group ("FileInfo")) { + if (keyFile.has_key ("FileInfo", "Filetype")) filetype = keyFile.get_string ("FileInfo", "Filetype"); + } + + 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", "ThumbImageOffset")) thumbOffset = keyFile.get_integer ("ExtraRawInfo", "ThumbImageOffset"); + } + else { + rotate = 0; + thumbImgType = 0; + } + return 0; + } + } + catch (Glib::Error &err) { + if (options.rtSettings.verbose) + printf("CacheImageData::load / Error code %d while reading values from \"%s\":\n%s\n", err.code(), fname.c_str(), err.what().c_str()); + } + catch (...) { + if (options.rtSettings.verbose) + printf("CacheImageData::load / Unknown exception while trying to load \"%s\"!\n", fname.c_str()); + } + return 1; +} + +/* + * Save the General, DateTime, ExifInfo, File info and ExtraRawInfo sections of the image data file + */ +int CacheImageData::save (const Glib::ustring& fname) { + + rtengine::SafeKeyFile keyFile; + + if (safe_file_test(fname,Glib::FILE_TEST_EXISTS)) { + try { + keyFile.load_from_file (fname); + } + catch (Glib::Error &err) { + if (options.rtSettings.verbose) + printf("CacheImageData::save / Error code %d while reading values from \"%s\":\n%s\n", err.code(), fname.c_str(), err.what().c_str()); + } + catch (...) { + if (options.rtSettings.verbose) + printf("CacheImageData::save / Unknown exception while trying to save \"%s\"!\n", fname.c_str()); + } + } + + keyFile.set_string ("General", "MD5", md5); + keyFile.set_string ("General", "Version", VERSION); // Application's version + keyFile.set_boolean ("General", "Supported", supported); + keyFile.set_integer ("General", "Format", format); + keyFile.set_boolean ("General", "RecentlySaved", recentlySaved); + + // remove the old implementation of Rank and InTrash from cache + if (keyFile.has_key ("General", "Rank")) keyFile.remove_key("General", "Rank"); + if (keyFile.has_key ("General", "InTrash")) keyFile.remove_key("General", "InTrash"); + + if (timeValid) { + keyFile.set_integer ("DateTime", "Year", year); + keyFile.set_integer ("DateTime", "Month", month); + keyFile.set_integer ("DateTime", "Day", day); + keyFile.set_integer ("DateTime", "Hour", hour); + keyFile.set_integer ("DateTime", "Min", min); + keyFile.set_integer ("DateTime", "Sec", sec); + } + + keyFile.set_boolean ("ExifInfo", "Valid", exifValid); + if (exifValid) { + keyFile.set_double ("ExifInfo", "FNumber", fnumber); + keyFile.set_double ("ExifInfo", "Shutter", shutter); + keyFile.set_double ("ExifInfo", "FocalLen", focalLen); + keyFile.set_double ("ExifInfo", "FocalLen35mm", focalLen35mm); + keyFile.set_double ("ExifInfo", "FocusDist", focusDist); + keyFile.set_integer ("ExifInfo", "ISO", iso); + keyFile.set_string ("ExifInfo", "ExpComp", expcomp); + } + keyFile.set_string ("ExifInfo", "Lens", lens); + keyFile.set_string ("ExifInfo", "CameraMake", camMake); + keyFile.set_string ("ExifInfo", "CameraModel", camModel); + keyFile.set_string ("FileInfo", "Filetype", filetype); + + if (format==FT_Raw) { + keyFile.set_integer ("ExtraRawInfo", "ThumbImageType", thumbImgType); + keyFile.set_integer ("ExtraRawInfo", "ThumbImageOffset", thumbOffset); + } + + FILE *f = safe_g_fopen (fname, "wt"); + if (!f) { + if (options.rtSettings.verbose) + printf("CacheImageData::save / Error: unable to open file \"%s\" with write access!\n", fname.c_str()); + return 1; + } + else { + fprintf (f, "%s", keyFile.to_data().c_str()); + fclose (f); + return 0; + } +} + diff --git a/rtgui/cacheimagedata.h b/rtgui/cacheimagedata.h new file mode 100644 index 000000000..a04bd7300 --- /dev/null +++ b/rtgui/cacheimagedata.h @@ -0,0 +1,82 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _CACHEIMAGEDATA_ +#define _CACHEIMAGEDATA_ + +#include +#include "options.h" + +class CacheImageData { + + public: + + // basic informations + Glib::ustring md5; + Glib::ustring version; + bool supported; + ThFileType format; + char rankOld; // old implementation of rank + bool inTrashOld; // old implementation of inTrash + bool recentlySaved; + + // time/date info + bool timeValid; + short year; + char month; + char day; + char hour; + char min; + char sec; + // exif info + bool exifValid; + double fnumber; + double shutter; + double focalLen,focalLen35mm; + float focusDist; + unsigned iso; + Glib::ustring lens; + Glib::ustring camMake; + Glib::ustring camModel; + Glib::ustring filetype; + Glib::ustring expcomp; + + // store a copy of the autoWB's multipliers computed in Thumbnail::_generateThumbnailImage + // they are not stored in the cache file by this class, but by rtengine::Thumbnail + // -1 = Unknown + double redAWBMul, greenAWBMul, blueAWBMul; + + // additional info on raw images + int rotate; + int thumbImgType; + int thumbOffset; + + enum + { + FULL_THUMBNAIL = 0, // was the thumbnail generated from whole file + QUICK_THUMBNAIL = 1 // was the thumbnail generated from embedded jpeg + }; + + CacheImageData (); + + int load (const Glib::ustring& fname); + int save (const Glib::ustring& fname); + + Glib::ustring getCamera() const { return Glib::ustring(camMake+" "+camModel); } +}; +#endif diff --git a/rtgui/cachemanager.cc b/rtgui/cachemanager.cc new file mode 100644 index 000000000..6112585ec --- /dev/null +++ b/rtgui/cachemanager.cc @@ -0,0 +1,347 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "cachemanager.h" +#include "options.h" +#include +#include +#include "guiutils.h" +#include "procparamchangers.h" +#include "../rtengine/safegtk.h" +#ifdef WIN32 +#include +#endif + +CacheManager* +CacheManager::getInstance(void) +{ + static CacheManager* instance_ = 0; + if ( instance_ == 0 ) + { + static MyMutex smutex_; + MyMutex::MyLock lock(smutex_); + if ( instance_ == 0 ) + { + instance_ = new CacheManager(); + } + } + return instance_; +} + +void CacheManager::init () { + + MyMutex::MyLock lock(mutex_); + + openEntries.clear (); + baseDir = options.cacheBaseDir; + + if (!safe_file_test (baseDir, Glib::FILE_TEST_IS_DIR)) + safe_g_mkdir_with_parents (baseDir, 511); + if (!safe_file_test (Glib::build_filename (baseDir, "profiles"), Glib::FILE_TEST_IS_DIR)) + safe_g_mkdir_with_parents (Glib::ustring(Glib::build_filename (baseDir, "profiles")), 511); + if (!safe_file_test (Glib::build_filename (baseDir, "images"), Glib::FILE_TEST_IS_DIR)) + safe_g_mkdir_with_parents (Glib::ustring(Glib::build_filename (baseDir, "images")), 511); + if (!safe_file_test (Glib::build_filename (baseDir, "aehistograms"), Glib::FILE_TEST_IS_DIR)) + safe_g_mkdir_with_parents (Glib::ustring(Glib::build_filename (baseDir, "aehistograms")), 511); + if (!safe_file_test (Glib::build_filename (baseDir, "embprofiles"), Glib::FILE_TEST_IS_DIR)) + safe_g_mkdir_with_parents (Glib::ustring(Glib::build_filename (baseDir, "embprofiles")), 511); + if (!safe_file_test (Glib::build_filename (baseDir, "data"), Glib::FILE_TEST_IS_DIR)) + safe_g_mkdir_with_parents (Glib::ustring(Glib::build_filename (baseDir, "data")), 511); +} + +Thumbnail* CacheManager::getEntry (const Glib::ustring& fname) { + + Thumbnail* res = NULL; + + // take manager lock and search for entry, if found return it else release + // lock and create it + { + MyMutex::MyLock lock(mutex_); + + string_thumb_map::iterator r = openEntries.find (fname); + // if it is open, return it + if (r!=openEntries.end()) { + r->second->increaseRef (); + return r->second; + } + } + + // compute the md5 + std::string md5 = getMD5 (fname); + if (md5=="") + return NULL; + + // build path name + Glib::ustring cfname = getCacheFileName ("data", fname, md5) + ".txt"; + + // let's see if we have it in the cache + if (safe_file_test (cfname, Glib::FILE_TEST_EXISTS)) { + CacheImageData* cfs = new CacheImageData (); + int e = cfs->load (cfname); + if (!e && cfs->supported==true) + res = new Thumbnail (this, fname, cfs); + if (res && !res->isSupported ()) { + delete res; + res = NULL; + } + delete cfs; + } + + // if not, create a new one + if (!res) { + res = new Thumbnail (this, fname, md5); + if (!res->isSupported ()) { + delete res; + res = NULL; + } + } + + // retake the lock and see if it was added while we we're unlocked, if it + // was use it over our version. if not added we create the cache entry + if (res) + { + MyMutex::MyLock lock(mutex_); + + string_thumb_map::iterator r = openEntries.find (fname); + if (r!=openEntries.end()) { + delete res; + r->second->increaseRef (); + return r->second; + } + + // it wasn't, create a new entry + openEntries[fname] = res; + } + + return res; +} + + +void CacheManager::deleteEntry (const Glib::ustring& fname) { + + MyMutex::MyLock lock(mutex_); + + // check if it is opened + string_thumb_map::iterator r = openEntries.find (fname); + // if it is open, dont delete it + if (r!=openEntries.end()) { + std::string md5 = r->second->getMD5 (); + + // decrease reference count; this will call back into CacheManager so + // we release the lock for it. + { + lock.release(); + r->second->decreaseRef (); + lock.acquire(); + } + + // if in the editor, the thumbnail still exists. If not, delete it: + r = openEntries.find (fname); + if (r==openEntries.end() && md5!="") { + safe_g_remove (getCacheFileName ("data", fname, md5) + ".txt"); + safe_g_remove (getCacheFileName ("profiles", fname, md5) + paramFileExtension); + safe_g_remove (getCacheFileName ("images", fname, md5) + ".rtti"); + safe_g_remove (getCacheFileName ("images", fname, md5) + ".cust16"); + safe_g_remove (getCacheFileName ("images", fname, md5) + ".cust"); + safe_g_remove (getCacheFileName ("images", fname, md5) + ".jpg"); + safe_g_remove (getCacheFileName ("aehistograms", fname, md5)); + safe_g_remove (getCacheFileName ("embprofiles", fname, md5) + ".icc"); + } + } + else { + std::string md5 = getMD5 (fname); + if (md5!="") { + safe_g_remove (getCacheFileName ("data", fname, md5) + ".txt"); + safe_g_remove (getCacheFileName ("profiles", fname, md5) + paramFileExtension); + safe_g_remove (getCacheFileName ("images", fname, md5) + ".rtti"); + safe_g_remove (getCacheFileName ("images", fname, md5) + ".cust16"); + safe_g_remove (getCacheFileName ("images", fname, md5) + ".cust"); + safe_g_remove (getCacheFileName ("images", fname, md5) + ".jpg"); + safe_g_remove (getCacheFileName ("aehistograms", fname, md5)); + safe_g_remove (getCacheFileName ("embprofiles", fname, md5) + ".icc"); + } + } +} + +void CacheManager::clearFromCache (const Glib::ustring& fname, bool leavenotrace) { + std::string md5 = getMD5 (fname); + if (md5!="") { + if (leavenotrace){ + safe_g_remove (getCacheFileName ("data", fname, md5) + ".txt"); + safe_g_remove (getCacheFileName ("profiles", fname, md5) + paramFileExtension); + } + safe_g_remove (getCacheFileName ("images", fname, md5) + ".rtti"); + safe_g_remove (getCacheFileName ("images", fname, md5) + ".cust16"); + safe_g_remove (getCacheFileName ("images", fname, md5) + ".cust"); + safe_g_remove (getCacheFileName ("images", fname, md5) + ".jpg"); + safe_g_remove (getCacheFileName ("aehistograms", fname, md5)); + safe_g_remove (getCacheFileName ("embprofiles", fname, md5) + ".icc"); + } +} + +void CacheManager::renameEntry (const std::string& oldfilename, const std::string& oldmd5, const std::string& newfilename) { + + MyMutex::MyLock lock(mutex_); + + std::string newmd5 = getMD5 (newfilename); + + safe_g_rename (getCacheFileName ("profiles", oldfilename, oldmd5) + paramFileExtension, (getCacheFileName ("profiles", newfilename, newmd5) + paramFileExtension).c_str()); + safe_g_rename (getCacheFileName ("images", oldfilename, oldmd5) + ".rtti", getCacheFileName ("images", newfilename, newmd5) + ".rtti"); + safe_g_rename (getCacheFileName ("images", oldfilename, oldmd5) + ".cust16", getCacheFileName ("images", newfilename, newmd5) + ".cust16"); + safe_g_rename (getCacheFileName ("images", oldfilename, oldmd5) + ".cust", getCacheFileName ("images", newfilename, newmd5) + ".cust"); + safe_g_rename (getCacheFileName ("images", oldfilename, oldmd5) + ".jpg", getCacheFileName ("images", newfilename, newmd5) + ".jpg"); + safe_g_rename (getCacheFileName ("aehistograms", oldfilename, oldmd5), getCacheFileName ("aehistograms", newfilename, newmd5)); + safe_g_rename (getCacheFileName ("embprofiles", oldfilename, oldmd5) + ".icc", getCacheFileName ("embprofiles", newfilename, newmd5) + ".icc"); + safe_g_rename (getCacheFileName ("data", oldfilename, oldmd5) + ".txt", getCacheFileName ("data", newfilename, newmd5) + ".txt"); + + // check if it is opened + string_thumb_map::iterator r = openEntries.find (oldfilename); + // if it is open, update md5 + if (r!=openEntries.end()) { + Thumbnail* t = r->second; + openEntries.erase (r); + t->setFileName (newfilename); + openEntries[newfilename] = t; + t->updateCache (); + t->saveThumbnail (); + } +} + +void CacheManager::closeThumbnail (Thumbnail* t) { + + MyMutex::MyLock lock(mutex_); + +// t->updateCache (); + string_thumb_map::iterator r = openEntries.find (t->getFileName()); + if (r!=openEntries.end()) + openEntries.erase (r); + delete t; +} + +void CacheManager::closeCache () { + + MyMutex::MyLock lock(mutex_); + + applyCacheSizeLimitation (); +} + +void CacheManager::clearAll () { + + MyMutex::MyLock lock(mutex_); + + deleteDir ("images"); + deleteDir ("aehistograms"); + deleteDir ("embprofiles"); + deleteDir ("profiles"); + deleteDir ("data"); + + // re-generate thumbnail images and clear profiles of open thumbnails + //string_thumb_map::iterator i; + //for (i=openEntries.begin(); i!=openEntries.end(); i++) { + // i->second->clearProcParams (CACHEMGR); + // i->second->generateThumbnailImage (); + // i->second->updateCache (); + //} +} +void CacheManager::clearThumbImages () { + + MyMutex::MyLock lock(mutex_); + + deleteDir ("images"); + deleteDir ("aehistograms"); + deleteDir ("embprofiles"); +} + +void CacheManager::clearProfiles () { + MyMutex::MyLock lock(mutex_); + + deleteDir ("profiles"); +} + +void CacheManager::deleteDir (const Glib::ustring& dirName) { + + try { + Glib::Dir* dir = new Glib::Dir (Glib::build_filename (baseDir, dirName)); + for (Glib::DirIterator i = dir->begin(); i!=dir->end(); ++i) + safe_g_remove (Glib::build_filename (Glib::build_filename (baseDir, dirName), *i)); + delete dir; + } + catch (const Glib::Error& e) { + } +} + +std::string CacheManager::getMD5 (const Glib::ustring& fname) { + + Glib::RefPtr file = Gio::File::create_for_path (fname); + if (file && file->query_exists()) { + + #ifdef WIN32 + // Windows: file name + size + creation time + // Safer because e.g. your camera image counter turns over. Do NOT use modified date, since tagging programs will change that + wchar_t *wFname = (wchar_t*)g_utf8_to_utf16 (fname.c_str(), -1, NULL, NULL, NULL); + WIN32_FILE_ATTRIBUTE_DATA fileAttr; + bool success=GetFileAttributesExW(wFname, GetFileExInfoStandard, &fileAttr); + g_free(wFname); + + if (success) { + // Just need the low file size, since RAWs are never that large + Glib::ustring fileID= Glib::ustring::compose ("%1-%2-%3-%4", fileAttr.nFileSizeLow, fileAttr.ftCreationTime.dwHighDateTime, fileAttr.ftCreationTime.dwLowDateTime, fname ); + return Glib::Checksum::compute_checksum (Glib::Checksum::CHECKSUM_MD5, fileID); + } + #else + // Least common denominator: file name + size to identify a file + Glib::RefPtr info = safe_query_file_info (file); + if (info) + return Glib::Checksum::compute_checksum (Glib::Checksum::CHECKSUM_MD5, Glib::ustring::compose ("%1%2", fname, info->get_size())); + #endif + } + return ""; +} + +Glib::ustring CacheManager::getCacheFileName (const Glib::ustring& subdir, const Glib::ustring& fname, const Glib::ustring& md5) { + + Glib::ustring cfn = Glib::build_filename (baseDir, subdir); + Glib::ustring cname = Glib::path_get_basename (fname) + "." + md5; + return Glib::build_filename (cfn, cname); +} + +void CacheManager::applyCacheSizeLimitation () { + + // TODO: Improve this, it just blindly deletes image without looking at create time or something to keep the current ones + std::vector flist; + Glib::ustring dataDir = Glib::build_filename (baseDir, "data"); + Glib::RefPtr dir = Gio::File::create_for_path (dataDir); + + safe_build_file_list (dir, flist); + + if (flist.size() > options.maxCacheEntries) { + std::sort (flist.begin(), flist.end()); + while (flist.size() > options.maxCacheEntries) { + safe_g_remove (Glib::build_filename (Glib::build_filename (baseDir, "data"), flist.front().fname) + ".txt"); + safe_g_remove (Glib::build_filename (Glib::build_filename (baseDir, "images"), flist.front().fname) + ".rtti"); + safe_g_remove (Glib::build_filename (Glib::build_filename (baseDir, "images"), flist.front().fname) + ".cust16"); + safe_g_remove (Glib::build_filename (Glib::build_filename (baseDir, "images"), flist.front().fname) + ".cust"); + safe_g_remove (Glib::build_filename (Glib::build_filename (baseDir, "images"), flist.front().fname) + ".jpg"); + safe_g_remove (Glib::build_filename (Glib::build_filename (baseDir, "aehistograms"), flist.front().fname)); + safe_g_remove (Glib::build_filename (Glib::build_filename (baseDir, "embprofiles"), flist.front().fname) + ".icc"); + // safe_g_remove (Glib::build_filename (Glib::build_filename (baseDir, "profiles"), flist.front().fname) + paramFileExtension); + flist.erase (flist.begin()); + } + } +} + diff --git a/rtgui/cachemanager.h b/rtgui/cachemanager.h new file mode 100644 index 000000000..6173e1c80 --- /dev/null +++ b/rtgui/cachemanager.h @@ -0,0 +1,74 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _CACHEMANAGER_ +#define _CACHEMANAGER_ + +#include +#include +#include +#include "thumbnail.h" +#include +#include "../rtengine/procparams.h" +#include "threadutils.h" + +class Thumbnail; + +class CacheManager { + + typedef std::pair string_thumb_pair; + typedef std::map string_thumb_map; + + string_thumb_map openEntries; + Glib::ustring baseDir; + MyMutex mutex_; + + void deleteDir (const Glib::ustring& dirName); + + CacheManager () {} + + public: + + static CacheManager* getInstance(void); + + void init (); + Thumbnail* getEntry (const Glib::ustring& fname); + void deleteEntry (const Glib::ustring& fname); + void renameEntry (const std::string& oldfilename, const std::string& oldmd5, const std::string& newfilename); + + void closeThumbnail (Thumbnail* t); + + const Glib::ustring& getBaseDir () { MyMutex::MyLock lock(mutex_); return baseDir; } + void closeCache (); + + static std::string getMD5 (const Glib::ustring& fname); + + void clearAll (); + void clearThumbImages (); + void clearProfiles (); + void clearFromCache(const Glib::ustring& fname, bool leavenotrace); + + void applyCacheSizeLimitation (); + + Glib::ustring getCacheFileName (const Glib::ustring& subdir, const Glib::ustring& fname, const Glib::ustring& md5); +}; + +#define cacheMgr CacheManager::getInstance() + +#endif + diff --git a/rtgui/cacorrection.cc b/rtgui/cacorrection.cc new file mode 100644 index 000000000..1cf0429d1 --- /dev/null +++ b/rtgui/cacorrection.cc @@ -0,0 +1,109 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "cacorrection.h" +#include +#include "rtimage.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +CACorrection::CACorrection () : FoldableToolPanel(this, "cacorrection", M("TP_CACORRECTION_LABEL")) { + + Gtk::Image* icaredL = Gtk::manage (new RTImage ("ajd-ca-red1.png")); + Gtk::Image* icaredR = Gtk::manage (new RTImage ("ajd-ca-red2.png")); + Gtk::Image* icablueL = Gtk::manage (new RTImage ("ajd-ca-blue1.png")); + Gtk::Image* icablueR = Gtk::manage (new RTImage ("ajd-ca-blue2.png")); + + red = Gtk::manage (new Adjuster (M("TP_CACORRECTION_RED"), -0.005, 0.005, 0.0001, 0, icaredL, icaredR)); + red->setAdjusterListener (this); + + blue = Gtk::manage (new Adjuster (M("TP_CACORRECTION_BLUE"), -0.005, 0.005, 0.0001, 0, icablueL, icablueR)); + blue->setAdjusterListener (this); + + pack_start (*red); + pack_start (*blue); + + show_all(); +} + +void CACorrection::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + if (pedited) { + red->setEditedState (pedited->cacorrection.red ? Edited : UnEdited); + blue->setEditedState (pedited->cacorrection.blue ? Edited : UnEdited); + } + + red->setValue (pp->cacorrection.red); + blue->setValue (pp->cacorrection.blue); + + enableListener (); +} + +void CACorrection::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->cacorrection.red = red->getValue (); + pp->cacorrection.blue = blue->getValue (); + + if (pedited) { + pedited->cacorrection.red = red->getEditedState (); + pedited->cacorrection.blue = blue->getEditedState (); + } +} + +void CACorrection::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + red->setDefault (defParams->cacorrection.red); + blue->setDefault (defParams->cacorrection.blue); + + if (pedited) { + red->setDefaultEditedState (pedited->cacorrection.red ? Edited : UnEdited); + blue->setDefaultEditedState (pedited->cacorrection.blue ? Edited : UnEdited); + } + else { + red->setDefaultEditedState (Irrelevant); + blue->setDefaultEditedState (Irrelevant); + } +} + +void CACorrection::adjusterChanged (Adjuster* a, double newval) { + + if (listener) + listener->panelChanged (EvCACorr, Glib::ustring::compose ("%1=%3\n%2=%4", M("TP_CACORRECTION_RED"), M("TP_CACORRECTION_BLUE"), Glib::ustring::format (std::setw(5), std::fixed, std::setprecision(4), red->getValue()), Glib::ustring::format (std::setw(5), std::fixed, std::setprecision(4), blue->getValue()))); +} + +void CACorrection::setAdjusterBehavior (bool badd) { + + red->setAddMode(badd); + blue->setAddMode(badd); +} + +void CACorrection::trimValues (rtengine::procparams::ProcParams* pp) { + + red->trimValue(pp->cacorrection.red); + blue->trimValue(pp->cacorrection.blue); +} + +void CACorrection::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + red->showEditedCB (); + blue->showEditedCB (); +} diff --git a/rtgui/cacorrection.h b/rtgui/cacorrection.h new file mode 100644 index 000000000..f0d77d286 --- /dev/null +++ b/rtgui/cacorrection.h @@ -0,0 +1,46 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _CACORRECTION_H_ +#define _CACORRECTION_H_ + +#include +#include "adjuster.h" +#include "toolpanel.h" + +class CACorrection : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel { + + protected: + Adjuster* red; + Adjuster* blue; + + public: + + CACorrection (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + + void adjusterChanged (Adjuster* a, double newval); + void setAdjusterBehavior (bool badd); + void trimValues (rtengine::procparams::ProcParams* pp); +}; + +#endif diff --git a/rtgui/chmixer.cc b/rtgui/chmixer.cc new file mode 100644 index 000000000..e74fa6c80 --- /dev/null +++ b/rtgui/chmixer.cc @@ -0,0 +1,183 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "chmixer.h" +#include "rtimage.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +ChMixer::ChMixer (): FoldableToolPanel(this, "chmixer", M("TP_CHMIXER_LABEL")) { + + imgIcon[0] = Gtk::manage (new RTImage ("Chanmixer-RR.png")); + imgIcon[1] = Gtk::manage (new RTImage ("Chanmixer-RG.png")); + imgIcon[2] = Gtk::manage (new RTImage ("Chanmixer-RB.png")); + imgIcon[3] = Gtk::manage (new RTImage ("Chanmixer-GR.png")); + imgIcon[4] = Gtk::manage (new RTImage ("Chanmixer-GG.png")); + imgIcon[5] = Gtk::manage (new RTImage ("Chanmixer-GB.png")); + imgIcon[6] = Gtk::manage (new RTImage ("Chanmixer-BR.png")); + imgIcon[7] = Gtk::manage (new RTImage ("Chanmixer-BG.png")); + imgIcon[8] = Gtk::manage (new RTImage ("Chanmixer-BB.png")); + + Gtk::Label* rlabel = Gtk::manage (new Gtk::Label ()); + rlabel->set_markup (Glib::ustring("\t") + M("TP_CHMIXER_RED") + Glib::ustring(":")); + rlabel->set_alignment(Gtk::ALIGN_LEFT); + + red[0] = Gtk::manage (new Adjuster ("", -200, 200, 1, 100, imgIcon[0])); + red[1] = Gtk::manage (new Adjuster ("", -200, 200, 1, 0, imgIcon[1])); + red[2] = Gtk::manage (new Adjuster ("", -200, 200, 1, 0, imgIcon[2])); + + Gtk::HSeparator* rsep = Gtk::manage (new Gtk::HSeparator ()); + + pack_start (*rlabel); + for (int i=0; i<3; i++) + pack_start (*red[i]); + pack_start (*rsep, Gtk::PACK_EXPAND_WIDGET, 4); + + Gtk::Label* glabel = Gtk::manage (new Gtk::Label ()); + glabel->set_markup (Glib::ustring("\t") + M("TP_CHMIXER_GREEN") + Glib::ustring(":")); + glabel->set_alignment(Gtk::ALIGN_LEFT); + + + green[0] = Gtk::manage (new Adjuster ("", -200, 200, 1, 0, imgIcon[3])); + green[1] = Gtk::manage (new Adjuster ("", -200, 200, 1, 100, imgIcon[4])); + green[2] = Gtk::manage (new Adjuster ("", -200, 200, 1, 0, imgIcon[5])); + + Gtk::HSeparator* gsep = Gtk::manage (new Gtk::HSeparator ()); + + pack_start (*glabel); + for (int i=0; i<3; i++) + pack_start (*green[i]); + pack_start (*gsep, Gtk::PACK_EXPAND_WIDGET, 4); + + Gtk::Label* blabel = Gtk::manage (new Gtk::Label ()); + blabel->set_markup (Glib::ustring("\t") + M("TP_CHMIXER_BLUE") + Glib::ustring(":")); + blabel->set_alignment(Gtk::ALIGN_LEFT); + blue[0] = Gtk::manage (new Adjuster ("", -200, 200, 1, 0, imgIcon[6])); + blue[1] = Gtk::manage (new Adjuster ("", -200, 200, 1, 0, imgIcon[7])); + blue[2] = Gtk::manage (new Adjuster ("", -200, 200, 1, 100, imgIcon[8])); + + for (int i=0; i<3; i++) { + red[i]->setAdjusterListener (this); + green[i]->setAdjusterListener (this); + blue[i]->setAdjusterListener (this); + } + + pack_start (*blabel); + for (int i=0; i<3; i++) + pack_start (*blue[i]); + + show_all(); +} + +void ChMixer::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + if (pedited) + for (int i=0; i<3; i++) { + red[i]->setEditedState (pedited->chmixer.red[i] ? Edited : UnEdited); + green[i]->setEditedState (pedited->chmixer.green[i] ? Edited : UnEdited); + blue[i]->setEditedState (pedited->chmixer.blue[i] ? Edited : UnEdited); + } + + for (int i=0; i<3; i++) { + red[i]->setValue (pp->chmixer.red[i]); + green[i]->setValue (pp->chmixer.green[i]); + blue[i]->setValue (pp->chmixer.blue[i]); + } + + enableListener (); +} + +void ChMixer::write (ProcParams* pp, ParamsEdited* pedited) { + + for (int i=0; i<3; i++) { + pp->chmixer.red[i] = (int) red[i]->getValue (); + pp->chmixer.green[i] = (int) green[i]->getValue (); + pp->chmixer.blue[i] = (int) blue[i]->getValue (); + } + + if (pedited) + for (int i=0; i<3; i++) { + pedited->chmixer.red[i] = red[i]->getEditedState (); + pedited->chmixer.green[i] = green[i]->getEditedState (); + pedited->chmixer.blue[i] = blue[i]->getEditedState (); + } +} + +void ChMixer::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + for (int i=0; i<3; i++) { + red[i]->setDefault (defParams->chmixer.red[i]); + green[i]->setDefault (defParams->chmixer.green[i]); + blue[i]->setDefault (defParams->chmixer.blue[i]); + } + + if (pedited) + for (int i=0; i<3; i++) { + red[i]->setDefaultEditedState (pedited->chmixer.red[i] ? Edited : UnEdited); + green[i]->setDefaultEditedState (pedited->chmixer.green[i] ? Edited : UnEdited); + blue[i]->setDefaultEditedState (pedited->chmixer.blue[i] ? Edited : UnEdited); + } + else + for (int i=0; i<3; i++) { + red[i]->setDefaultEditedState (Irrelevant); + green[i]->setDefaultEditedState (Irrelevant); + blue[i]->setDefaultEditedState (Irrelevant); + } +} + +void ChMixer::adjusterChanged (Adjuster* a, double newval) { + + if (listener) { + Glib::ustring descr = Glib::ustring::compose ("R=%1,%2,%3\nG=%4,%5,%6\nB=%7,%8,%9", + (int)red[0]->getValue(), (int)red[1]->getValue(), (int)red[2]->getValue(), + (int)green[0]->getValue(), (int)green[1]->getValue(), (int)green[2]->getValue(), + (int)blue[0]->getValue(), (int)blue[1]->getValue(), (int)blue[2]->getValue()); + listener->panelChanged (EvChMixer, descr); + } +} + +void ChMixer::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + for (int i=0; i<3; i++) { + red[i]->showEditedCB (); + green[i]->showEditedCB (); + blue[i]->showEditedCB (); + } +} + +void ChMixer::setAdjusterBehavior (bool rgbadd) { + + for (int i=0; i<3; i++) { + red[i]->setAddMode(rgbadd); + green[i]->setAddMode(rgbadd); + blue[i]->setAddMode(rgbadd); + } +} + +void ChMixer::trimValues (rtengine::procparams::ProcParams* pp) { + + for (int i=0; i<3; i++) { + red[i]->trimValue(pp->chmixer.red[i]); + green[i]->trimValue(pp->chmixer.green[i]); + blue[i]->trimValue(pp->chmixer.blue[i]); + } +} diff --git a/rtgui/chmixer.h b/rtgui/chmixer.h new file mode 100644 index 000000000..73ee7a865 --- /dev/null +++ b/rtgui/chmixer.h @@ -0,0 +1,48 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _CHMIXER_H_ +#define _CHMIXER_H_ + +#include +#include "adjuster.h" +#include "toolpanel.h" + +class ChMixer : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel { + + protected: + Adjuster *red[3]; + Adjuster *green[3]; + Adjuster *blue[3]; + Gtk::Image *imgIcon[9]; + + public: + + ChMixer (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + + void adjusterChanged (Adjuster* a, double newval); + void setAdjusterBehavior (bool rgbadd); + void trimValues (rtengine::procparams::ProcParams* pp); +}; + +#endif diff --git a/rtgui/clipboard.cc b/rtgui/clipboard.cc new file mode 100644 index 000000000..175c64c92 --- /dev/null +++ b/rtgui/clipboard.cc @@ -0,0 +1,69 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "clipboard.h" + +Clipboard clipboard; + +Clipboard::Clipboard () : partProfile (false) {} + +Clipboard::~Clipboard () { + partProfile.deleteInstance(); +} + +/* + * set both the "pparams" and "pedited" field of the PartialProfile; each one can be NULL + */ +void Clipboard::setPartialProfile (const rtengine::procparams::PartialProfile& pprofile) { + if (pprofile.pparams) { + if (!partProfile.pparams) partProfile.pparams = new rtengine::procparams::ProcParams(); + *partProfile.pparams = *pprofile.pparams; + } + else { + if (partProfile.pparams) { + delete partProfile.pparams; + partProfile.pparams = NULL; + } + } + + if (pprofile.pedited) { + if (!partProfile.pedited) partProfile.pedited = new ParamsEdited(); + *partProfile.pedited = *pprofile.pedited; + } + else { + if (partProfile.pedited) { + delete partProfile.pedited; + partProfile.pedited = NULL; + } + } +} + +/* + * this method copy the procparams to "pparams" and delete "pedited" + */ +void Clipboard::setProcParams (const rtengine::procparams::ProcParams& pparams) { + // copy procparams + if (!partProfile.pparams) partProfile.pparams = new rtengine::procparams::ProcParams(); + *partProfile.pparams = pparams; + + // delete pedited + if (partProfile.pedited) { + delete partProfile.pedited; + partProfile.pedited = NULL; + } +} diff --git a/rtgui/clipboard.h b/rtgui/clipboard.h new file mode 100644 index 000000000..4934cdf81 --- /dev/null +++ b/rtgui/clipboard.h @@ -0,0 +1,68 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _CLIPBOARD_ +#define _CLIPBOARD_ + +#include +#include "../rtengine/rtengine.h" +#include "../rtengine/procparams.h" +#include "paramsedited.h" +#include "myflatcurve.h" +#include "mydiagonalcurve.h" + +class Clipboard { + + bool _hasIPTC; + rtengine::procparams::IPTCPairs iptc; + rtengine::procparams::PartialProfile partProfile; + DiagonalCurveType hasDiagonalCurveDataType; + FlatCurveType hasFlatCurveDataType; + std::vector diagonalCurve; + std::vector flatCurve; + + + public: + void setIPTC (const rtengine::procparams::IPTCPairs& iptcc) { iptc = iptcc; _hasIPTC = true;} + const rtengine::procparams::IPTCPairs& getIPTC () { return iptc; } + bool hasIPTC () { return _hasIPTC; } + + void setPartialProfile (const rtengine::procparams::PartialProfile& pprofile); + const rtengine::procparams::PartialProfile& getPartialProfile () { return partProfile; }; + void setProcParams (const rtengine::procparams::ProcParams& pparams); + const rtengine::procparams::ProcParams& getProcParams () { return *partProfile.pparams; } + const ParamsEdited& getParamsEdited () { return *partProfile.pedited; } + bool hasProcParams () { return partProfile.pparams; } + bool hasPEdited () { return partProfile.pedited; } + + void setDiagonalCurveData (std::vector& p, DiagonalCurveType type ) { diagonalCurve = p; hasDiagonalCurveDataType = type; return; } + const std::vector & getDiagonalCurveData () { return diagonalCurve; } + DiagonalCurveType hasDiagonalCurveData () { return hasDiagonalCurveDataType; } + + void setFlatCurveData (std::vector& p, FlatCurveType type ) { flatCurve = p; hasFlatCurveDataType = type; return; } + const std::vector & getFlatCurveData () { return flatCurve; } + FlatCurveType hasFlatCurveData () { return hasFlatCurveDataType; } + + Clipboard (); + ~Clipboard (); + +}; + +extern Clipboard clipboard; + +#endif diff --git a/rtgui/coarsepanel.cc b/rtgui/coarsepanel.cc new file mode 100644 index 000000000..44e19d870 --- /dev/null +++ b/rtgui/coarsepanel.cc @@ -0,0 +1,154 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "coarsepanel.h" +#include "rtimage.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +CoarsePanel::CoarsePanel () : ToolPanel () { + + degree = 0; + degreechanged = true; + + Gtk::Image* rotateli = Gtk::manage (new RTImage ("stock-rotate-270.png")); + rotate_left = Gtk::manage (new Gtk::Button ()); + rotate_left->add (*rotateli); + rotate_left->set_relief(Gtk::RELIEF_NONE); + pack_start (*rotate_left); + + Gtk::Image* rotateri = Gtk::manage (new RTImage ("stock-rotate-90.png")); + rotate_right = Gtk::manage (new Gtk::Button ()); + rotate_right->add (*rotateri); + rotate_right->set_relief(Gtk::RELIEF_NONE); + pack_start (*rotate_right); + + Gtk::Image* fliphi = Gtk::manage (new RTImage ("stock-flip-horizontal.png")); + hflip = Gtk::manage (new Gtk::ToggleButton ()); + hflip->add (*fliphi); + hflip->set_relief(Gtk::RELIEF_NONE); + pack_start (*hflip); + + Gtk::Image* flipvi = Gtk::manage (new RTImage ("stock-flip-vertical.png")); + vflip = Gtk::manage (new Gtk::ToggleButton ()); + vflip->add (*flipvi); + vflip->set_relief(Gtk::RELIEF_NONE); + pack_start (*vflip); + + rotate_left->set_tooltip_markup (M("TP_COARSETRAF_TOOLTIP_ROTLEFT")); + rotate_right->set_tooltip_markup (M("TP_COARSETRAF_TOOLTIP_ROTRIGHT")); + vflip->set_tooltip_text (M("TP_COARSETRAF_TOOLTIP_VFLIP")); + hflip->set_tooltip_text (M("TP_COARSETRAF_TOOLTIP_HFLIP")); + + rotate_left->signal_pressed().connect( sigc::mem_fun(*this, &CoarsePanel::rotateLeft) ); + rotate_right->signal_pressed().connect( sigc::mem_fun(*this, &CoarsePanel::rotateRight) ); + hflip->signal_toggled().connect( sigc::mem_fun(*this, &CoarsePanel::flipHorizontal) ); + vflip->signal_toggled().connect( sigc::mem_fun(*this, &CoarsePanel::flipVertical) ); + + show_all_children (); +} + +void CoarsePanel::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + degree = pp->coarse.rotate; + + if (pedited) { + hflip->set_active (pedited->coarse.hflip ? pp->coarse.hflip : false); + vflip->set_active (pedited->coarse.vflip ? pp->coarse.vflip : false); + degreechanged = false; + oldhflip = pp->coarse.hflip; + oldvflip = pp->coarse.vflip; + } + else { + hflip->set_active (pp->coarse.hflip); + vflip->set_active (pp->coarse.vflip); + } + enableListener (); +} + +void CoarsePanel::write (ProcParams* pp, ParamsEdited* pedited) { + + if (pedited) { + pedited->coarse.rotate = degreechanged; + pedited->coarse.hflip = oldhflip != hflip->get_active (); + pedited->coarse.vflip = oldvflip != vflip->get_active (); + } + pp->coarse.rotate = degree; + pp->coarse.hflip = hflip->get_active (); + pp->coarse.vflip = vflip->get_active (); +} + +void CoarsePanel::initBatchBehavior () { + + disableListener (); + + degree = 0; + hflip->set_active (false); + vflip->set_active (false); + + enableListener (); +} + +void CoarsePanel::rotateLeft () { + + //Rotate one way or the opposite depending if the image is already flipped or not + if ( (vflip->get_active()) == (hflip->get_active ()) ) + degree = (degree + 270) % 360; + else + degree = (degree + 90) % 360; + degreechanged = true; + if (listener) + listener->panelChanged (EvCTRotate, Glib::ustring::format (degree)); +} + +void CoarsePanel::rotateRight () { + + //Rotate one way or the opposite depending if the image is already flipped or not + if ( (vflip->get_active()) == (hflip->get_active ()) ) + degree = (degree + 90) % 360; + else + degree = (degree + 270) % 360; + degreechanged = true; + if (listener) + listener->panelChanged (EvCTRotate, Glib::ustring::format (degree)); +} + +void CoarsePanel::flipHorizontal () { + + if (listener) { + if (hflip->get_active ()) + listener->panelChanged (EvCTHFlip, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvCTHFlip, M("GENERAL_DISABLED")); + } +} + +void CoarsePanel::flipVertical () { + + if (listener) { + if (vflip->get_active ()) + listener->panelChanged (EvCTVFlip, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvCTVFlip, M("GENERAL_DISABLED")); + } +} + + diff --git a/rtgui/coarsepanel.h b/rtgui/coarsepanel.h new file mode 100644 index 000000000..1fb19db81 --- /dev/null +++ b/rtgui/coarsepanel.h @@ -0,0 +1,49 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef __COARSEPANEL__ +#define __COARSEPANEL__ + +#include +#include "toolpanel.h" + +class CoarsePanel : public Gtk::HBox, public ToolPanel { + + protected: + Gtk::Button* rotate_left; + Gtk::Button* rotate_right; + Gtk::ToggleButton* hflip; + Gtk::ToggleButton* vflip; + int degree; + bool oldhflip, oldvflip, degreechanged; + + public: + + CoarsePanel (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void initBatchBehavior (); + + void rotateLeft (); + void rotateRight (); + void flipHorizontal (); + void flipVertical (); +}; + +#endif diff --git a/rtgui/colorappearance.cc b/rtgui/colorappearance.cc new file mode 100644 index 000000000..e7ddfed21 --- /dev/null +++ b/rtgui/colorappearance.cc @@ -0,0 +1,1197 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "colorappearance.h" +#include +#include "guiutils.h" +#include "../rtengine/color.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +ColorAppearance::ColorAppearance () : FoldableToolPanel(this, "colorappearance", M("TP_COLORAPP_LABEL"), false, true) { + CurveListener::setMulti(true); + std::vector milestones; + milestones.push_back( GradientMilestone(0., 0., 0., 0.) ); + milestones.push_back( GradientMilestone(1., 1., 1., 1.) ); + + + // ------------------------ Process #1: Converting to CIECAM + + + // Process 1 frame + Gtk::Frame *p1Frame; + // Vertical box container for the content of the Process 1 frame + Gtk::VBox *p1VBox; + + p1Frame = Gtk::manage (new Gtk::Frame(M("TP_COLORAPP_LABEL_SCENE")) ); + p1Frame->set_border_width(0); + p1Frame->set_label_align(0.025, 0.5); + + p1VBox = Gtk::manage ( new Gtk::VBox()); + p1VBox->set_border_width(4); + p1VBox->set_spacing(2); + + degree = Gtk::manage (new Adjuster (M("TP_COLORAPP_CIECAT_DEGREE"), 0., 100., 1., 100.)); + if (degree->delay < 1000) degree->delay = 1000; + degree->throwOnButtonRelease(); + degree->addAutoButton(M("TP_COLORAPP_DEGREE_AUTO_TOOLTIP")); + degree->set_tooltip_markup (M("TP_COLORAPP_DEGREE_TOOLTIP")); + p1VBox->pack_start (*degree); + + surrsource = Gtk::manage (new Gtk::CheckButton (M("TP_COLORAPP_SURSOURCE"))); + surrsource->set_tooltip_markup (M("TP_COLORAPP_SURSOURCE_TOOLTIP")); + p1VBox->pack_start (*surrsource, Gtk::PACK_SHRINK); + + Gtk::HBox* wbmHBox = Gtk::manage (new Gtk::HBox ()); + wbmHBox->set_border_width (0); + wbmHBox->set_spacing (2); + wbmHBox->set_tooltip_markup (M("TP_COLORAPP_MODEL_TOOLTIP")); + Gtk::Label* wbmLab = Gtk::manage (new Gtk::Label (M("TP_COLORAPP_MODEL")+":")); + wbmHBox->pack_start (*wbmLab, Gtk::PACK_SHRINK); + wbmodel = Gtk::manage (new MyComboBoxText ()); + wbmodel->append_text (M("TP_COLORAPP_WBRT")); + wbmodel->append_text (M("TP_COLORAPP_WBCAM")); + wbmodel->set_active (0); + wbmHBox->pack_start (*wbmodel); + p1VBox->pack_start (*wbmHBox); + + adapscen = Gtk::manage (new Adjuster (M("TP_COLORAPP_ADAPTSCENE"), 0.001, 16384., 0.001, 2000.));// EV -7 ==> EV 17 + if (adapscen->delay < 1000) adapscen->delay = 1000; + adapscen->throwOnButtonRelease(); + adapscen->addAutoButton(M("TP_COLORAPP_ADAP_AUTO_TOOLTIP")); + adapscen->set_tooltip_markup (M("TP_COLORAPP_ADAPTSCENE_TOOLTIP")); + p1VBox->pack_start (*adapscen); + + p1Frame->add(*p1VBox); + pack_start (*p1Frame, Gtk::PACK_EXPAND_WIDGET, 4); + + + // ------------------------ Process #2: Modifying image inside CIECAM + + + // Process 1 frame + Gtk::Frame *p2Frame; + // Vertical box container for the content of the Process 1 frame + Gtk::VBox *p2VBox; + + p2Frame = Gtk::manage (new Gtk::Frame(M("TP_COLORAPP_LABEL_CAM02")) ); + p2Frame->set_border_width(0); + p2Frame->set_label_align(0.025, 0.5); + + p2VBox = Gtk::manage ( new Gtk::VBox()); + p2VBox->set_border_width(4); + p2VBox->set_spacing(2); + + Gtk::HBox* alHBox = Gtk::manage (new Gtk::HBox ()); + alHBox->set_border_width (0); + alHBox->set_spacing (2); + alHBox->set_tooltip_markup (M("TP_COLORAPP_ALGO_TOOLTIP")); + Gtk::Label* alLabel = Gtk::manage (new Gtk::Label (M("TP_COLORAPP_ALGO")+":")); + alHBox->pack_start (*alLabel, Gtk::PACK_SHRINK); + algo = Gtk::manage (new MyComboBoxText ()); + algo->append_text (M("TP_COLORAPP_ALGO_JC")); + algo->append_text (M("TP_COLORAPP_ALGO_JS")); + algo->append_text (M("TP_COLORAPP_ALGO_QM")); + algo->append_text (M("TP_COLORAPP_ALGO_ALL")); + algo->set_active (0); + alHBox->pack_start (*algo); + p2VBox->pack_start (*alHBox); + + p2VBox->pack_start (*Gtk::manage (new Gtk::HSeparator()), Gtk::PACK_EXPAND_WIDGET, 4); + + jlight = Gtk::manage (new Adjuster (M("TP_COLORAPP_LIGHT"), -100.0, 100.0, 0.1, 0.)); + if (jlight->delay < 1000) jlight->delay = 1000; + jlight->throwOnButtonRelease(); + jlight->set_tooltip_markup (M("TP_COLORAPP_LIGHT_TOOLTIP")); + p2VBox->pack_start (*jlight); + + qbright = Gtk::manage (new Adjuster (M("TP_COLORAPP_BRIGHT"), -100.0, 100.0, 0.1, 0.)); + if (qbright->delay < 1000) qbright->delay = 1000; + qbright->throwOnButtonRelease(); + qbright->set_tooltip_markup (M("TP_COLORAPP_BRIGHT_TOOLTIP")); + p2VBox->pack_start (*qbright); + + chroma = Gtk::manage (new Adjuster (M("TP_COLORAPP_CHROMA"), -100.0, 100.0, 0.1, 0.)); + if (chroma->delay < 1000) chroma->delay = 1000; + chroma->throwOnButtonRelease(); + chroma->set_tooltip_markup (M("TP_COLORAPP_CHROMA_TOOLTIP")); + p2VBox->pack_start (*chroma); + + + schroma = Gtk::manage (new Adjuster (M("TP_COLORAPP_CHROMA_S"), -100.0, 100.0, 0.1, 0.)); + if (schroma->delay < 1000) schroma->delay = 1000; + schroma->throwOnButtonRelease(); + schroma->set_tooltip_markup (M("TP_COLORAPP_CHROMA_S_TOOLTIP")); + p2VBox->pack_start (*schroma); + + mchroma = Gtk::manage (new Adjuster (M("TP_COLORAPP_CHROMA_M"), -100.0, 100.0, 0.1, 0.)); + if (mchroma->delay < 1000) mchroma->delay = 1000; + mchroma->throwOnButtonRelease(); + mchroma->set_tooltip_markup (M("TP_COLORAPP_CHROMA_M_TOOLTIP")); + p2VBox->pack_start (*mchroma); + + rstprotection = Gtk::manage ( new Adjuster (M("TP_COLORAPP_RSTPRO"), 0., 100., 0.1, 0.) ); + if (rstprotection->delay < 1000) rstprotection->delay = 1000; + rstprotection->throwOnButtonRelease(); + rstprotection->set_tooltip_markup (M("TP_COLORAPP_RSTPRO_TOOLTIP")); + p2VBox->pack_start (*rstprotection); + + contrast = Gtk::manage (new Adjuster (M("TP_COLORAPP_CONTRAST"), -100.0, 100.0, 0.1, 0.)); + if (contrast->delay < 1000) contrast->delay = 1000; + contrast->throwOnButtonRelease(); + contrast->set_tooltip_markup (M("TP_COLORAPP_CONTRAST_TOOLTIP")); + p2VBox->pack_start (*contrast); + + qcontrast = Gtk::manage (new Adjuster (M("TP_COLORAPP_CONTRAST_Q"), -100.0, 100.0, 0.1, 0.)); + if (qcontrast->delay < 1000) qcontrast->delay = 1000; + qcontrast->throwOnButtonRelease(); + qcontrast->set_tooltip_markup (M("TP_COLORAPP_CONTRAST_Q_TOOLTIP")); + p2VBox->pack_start (*qcontrast); + + + colorh = Gtk::manage (new Adjuster (M("TP_COLORAPP_HUE"), -100.0, 100.0, 0.1, 0.)); + if (colorh->delay < 1000) colorh->delay = 1000; + colorh->throwOnButtonRelease(); + colorh->set_tooltip_markup (M("TP_COLORAPP_HUE_TOOLTIP")); + p2VBox->pack_start (*colorh); + + tonecie = Gtk::manage (new Gtk::CheckButton (M("TP_COLORAPP_TONECIE"))); + tonecie->set_tooltip_markup (M("TP_COLORAPP_TONECIE_TOOLTIP")); + tonecieconn = tonecie->signal_toggled().connect( sigc::mem_fun(*this, &ColorAppearance::tonecie_toggled) ); + p2VBox->pack_start (*tonecie); +/* + sharpcie = Gtk::manage (new Gtk::CheckButton (M("TP_COLORAPP_SHARPCIE"))); + sharpcie->set_tooltip_markup (M("TP_COLORAPP_SHARPCIE_TOOLTIP")); + sharpcieconn = sharpcie->signal_toggled().connect( sigc::mem_fun(*this, &ColorAppearance::sharpcie_toggled) ); + p2VBox->pack_start (*sharpcie); +*/ + p2VBox->pack_start (*Gtk::manage (new Gtk::HSeparator()), Gtk::PACK_EXPAND_WIDGET, 4); + + toneCurveMode = Gtk::manage (new MyComboBoxText ()); + toneCurveMode->append_text (M("TP_COLORAPP_TCMODE_LIGHTNESS")); + toneCurveMode->append_text (M("TP_COLORAPP_TCMODE_BRIGHTNESS")); + toneCurveMode->set_active (0); + toneCurveMode->set_tooltip_text(M("TP_COLORAPP_TCMODE_LABEL1")); + + curveEditorG = new CurveEditorGroup (options.lastToneCurvesDir, M("TP_COLORAPP_CURVEEDITOR1")); + curveEditorG->setCurveListener (this); + curveEditorG->setTooltip(M("TP_COLORAPP_CURVEEDITOR1_TOOLTIP")); + + shape = static_cast(curveEditorG->addCurve(CT_Diagonal, "", toneCurveMode)); + + + + tcmodeconn = toneCurveMode->signal_changed().connect( sigc::mem_fun(*this, &ColorAppearance::curveMode1Changed), true ); + + toneCurveMode2 = Gtk::manage (new MyComboBoxText ()); + toneCurveMode2->append_text (M("TP_COLORAPP_TCMODE_LIGHTNESS")); + toneCurveMode2->append_text (M("TP_COLORAPP_TCMODE_BRIGHTNESS")); + toneCurveMode2->set_active (0); + toneCurveMode2->set_tooltip_text(M("TP_COLORAPP_TCMODE_LABEL2")); + + curveEditorG2 = new CurveEditorGroup (options.lastToneCurvesDir, M("TP_COLORAPP_CURVEEDITOR2")); + curveEditorG2->setCurveListener (this); + + shape2 = static_cast(curveEditorG2->addCurve(CT_Diagonal, "", toneCurveMode2)); + + tcmode2conn = toneCurveMode2->signal_changed().connect( sigc::mem_fun(*this, &ColorAppearance::curveMode2Changed), true ); + + toneCurveMode3 = Gtk::manage (new MyComboBoxText ()); + toneCurveMode3->append_text (M("TP_COLORAPP_TCMODE_CHROMA")); + toneCurveMode3->append_text (M("TP_COLORAPP_TCMODE_SATUR")); + toneCurveMode3->append_text (M("TP_COLORAPP_TCMODE_COLORF")); + toneCurveMode3->set_active (0); + toneCurveMode3->set_tooltip_text(M("TP_COLORAPP_TCMODE_LABEL3")); + + curveEditorG3 = new CurveEditorGroup (options.lastToneCurvesDir, M("TP_COLORAPP_CURVEEDITOR3")); + curveEditorG3->setCurveListener (this); + + shape3 = static_cast(curveEditorG3->addCurve(CT_Diagonal, "", toneCurveMode3)); + shape3->setRangeLabels( + M("TP_LABCURVE_CURVEEDITOR_CC_RANGE1"), M("TP_LABCURVE_CURVEEDITOR_CC_RANGE2"), + M("TP_LABCURVE_CURVEEDITOR_CC_RANGE3"), M("TP_LABCURVE_CURVEEDITOR_CC_RANGE4") + ); + shape3->setBottomBarColorProvider(this, 1); + shape3->setLeftBarColorProvider(this, 1); + shape3->setRangeDefaultMilestones(0.05, 0.2, 0.58); + + +// shape3->setBottomBarColorProvider(this, 2); +// shape3->setLeftBarColorProvider(this, 2); +// shape3->setRangeDefaultMilestones(0.05, 0.2, 0.58); + + // The milestones are still the same than those define above + //milestones.push_back( GradientMilestone(0., 0., 0., 0.) ); + //milestones.push_back( GradientMilestone(1., 1., 1., 1.) ); + shape->setBottomBarBgGradient(milestones); + shape->setLeftBarBgGradient(milestones); + shape2->setBottomBarBgGradient(milestones); + shape2->setLeftBarBgGradient(milestones); + + std::vector shape3Milestones; + float R, G, B; + for (int i=0; i<7; i++) { + float x = float(i)*(1.0f/6.0); + Color::hsv2rgb01(x, 0.5f, 0.5f, R, G, B); + shape3Milestones.push_back( GradientMilestone(double(x), double(R), double(G), double(B)) ); + } + shape3->setBottomBarBgGradient(shape3Milestones); + shape3->setLeftBarBgGradient(shape3Milestones); + + shape3->setRangeDefaultMilestones(0.05, 0.2, 0.58); + + curveEditorG->curveListComplete(); + + curveEditorG2->curveListComplete(); + curveEditorG2->setTooltip(M("TP_COLORAPP_CURVEEDITOR2_TOOLTIP")); + + curveEditorG3->curveListComplete(); + curveEditorG3->setTooltip(M("TP_COLORAPP_CURVEEDITOR3_TOOLTIP")); + tcmode3conn = toneCurveMode3->signal_changed().connect( sigc::mem_fun(*this, &ColorAppearance::curveMode3Changed), true ); + + p2VBox->pack_start( *curveEditorG, Gtk::PACK_SHRINK, 2); + p2VBox->pack_start( *curveEditorG2, Gtk::PACK_SHRINK, 2); + p2VBox->pack_start( *curveEditorG3, Gtk::PACK_SHRINK, 2); + + // ------------------------ Choice CIECAM data + + + datacie = Gtk::manage (new Gtk::CheckButton (M("TP_COLORAPP_DATACIE"))); + datacie->set_tooltip_markup (M("TP_COLORAPP_DATACIE_TOOLTIP")); + datacieconn = datacie->signal_toggled().connect( sigc::mem_fun(*this, &ColorAppearance::datacie_toggled) ); + p2VBox->pack_start (*datacie); + + //------------------------- + + + + p2Frame->add(*p2VBox); + + + pack_start (*p2Frame, Gtk::PACK_EXPAND_WIDGET, 4); + + + + // ------------------------ Process #3: Converting back to Lab/RGB + + + // Process 3 frame + Gtk::Frame *p3Frame; + // Vertical box container for the content of the Process 3 frame + Gtk::VBox *p3VBox; + + p3Frame = Gtk::manage (new Gtk::Frame(M("TP_COLORAPP_LABEL_VIEWING")) ); // "Editing viewing conditions" ??? + p3Frame->set_border_width(0); + p3Frame->set_label_align(0.025, 0.5); + + p3VBox = Gtk::manage ( new Gtk::VBox()); + p3VBox->set_border_width(4); + p3VBox->set_spacing(2); + + adaplum = Gtk::manage (new Adjuster (M("TP_COLORAPP_ADAPTVIEWING"), 0.1, 1000., 0.1, 16.)); + if (adaplum->delay < 1000) adaplum->delay = 1000; + adaplum->throwOnButtonRelease(); + adaplum->set_tooltip_markup (M("TP_COLORAPP_ADAPTVIEWING_TOOLTIP")); + p3VBox->pack_start (*adaplum); + + Gtk::HBox* surrHBox = Gtk::manage (new Gtk::HBox ()); + surrHBox->set_border_width (0); + surrHBox->set_spacing (2); + surrHBox->set_tooltip_markup(M("TP_COLORAPP_SURROUND_TOOLTIP")); + Gtk::Label* surrLabel = Gtk::manage (new Gtk::Label (M("TP_COLORAPP_SURROUND")+":")); + surrHBox->pack_start (*surrLabel, Gtk::PACK_SHRINK); + surround = Gtk::manage (new MyComboBoxText ()); + surround->append_text (M("TP_COLORAPP_SURROUND_AVER")); + surround->append_text (M("TP_COLORAPP_SURROUND_DIM")); + surround->append_text (M("TP_COLORAPP_SURROUND_DARK")); + surround->append_text (M("TP_COLORAPP_SURROUND_EXDARK")); + surround->set_active (1); + surrHBox->pack_start (*surround); + p3VBox->pack_start (*surrHBox); + + p3Frame->add(*p3VBox); + pack_start (*p3Frame, Gtk::PACK_EXPAND_WIDGET, 4); + + + // ------------------------ Lab Gamut control + + + gamut = Gtk::manage (new Gtk::CheckButton (M("TP_COLORAPP_GAMUT"))); + gamut->set_tooltip_markup (M("TP_COLORAPP_GAMUT_TOOLTIP")); + gamutconn = gamut->signal_toggled().connect( sigc::mem_fun(*this, &ColorAppearance::gamut_toggled) ); + pack_start (*gamut, Gtk::PACK_SHRINK); + + // ------------------------ Bad pixel control + +/* + badpix = Gtk::manage (new Gtk::CheckButton (M("TP_COLORAPP_BADPIX"))); + badpix->set_tooltip_markup (M("TP_COLORAPP_BADPIX_TOOLTIP")); + badpixconn = badpix->signal_toggled().connect( sigc::mem_fun(*this, &ColorAppearance::badpix_toggled) ); + pack_start (*badpix, Gtk::PACK_SHRINK); +*/ + badpixsl = Gtk::manage (new Adjuster (M("TP_COLORAPP_BADPIXSL"), 0, 2, 1, 0)); + if (badpixsl->delay < 1000) badpixsl->delay = 1000; + badpixsl->throwOnButtonRelease(); + badpixsl->set_tooltip_markup (M("TP_COLORAPP_BADPIXSL_TOOLTIP")); + pack_start (*badpixsl, Gtk::PACK_SHRINK); + + // ------------------------ Listening events + + + surrconn = surrsource->signal_toggled().connect( sigc::mem_fun(*this, &ColorAppearance::surrsource_toggled) ); + wbmodelconn = wbmodel->signal_changed().connect ( sigc::mem_fun(*this, &ColorAppearance::wbmodelChanged) ); + algoconn = algo->signal_changed().connect ( sigc::mem_fun(*this, &ColorAppearance::algoChanged) ); + surroundconn = surround->signal_changed().connect ( sigc::mem_fun(*this, &ColorAppearance::surroundChanged) ); + + degree->setAdjusterListener (this); + adapscen->setAdjusterListener (this); + adaplum->setAdjusterListener (this); + badpixsl->setAdjusterListener (this); + jlight->setAdjusterListener (this); + qbright->setAdjusterListener (this); + colorh->setAdjusterListener (this); + chroma->setAdjusterListener (this); + schroma->setAdjusterListener (this); + mchroma->setAdjusterListener (this); + contrast->setAdjusterListener (this); + qcontrast->setAdjusterListener (this); + rstprotection->setAdjusterListener (this); + + show_all(); +} + +ColorAppearance::~ColorAppearance () { + delete curveEditorG; + delete curveEditorG2; + delete curveEditorG3; +} + + + +bool ColorAppearance::bgTTipQuery(int x, int y, bool keyboard_tooltip, const Glib::RefPtr& tooltip) { + return true; +} + +bool ColorAppearance::srTTipQuery(int x, int y, bool keyboard_tooltip, const Glib::RefPtr& tooltip) { + return true; +} + +void ColorAppearance::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + tcmodeconn.block(true); + tcmode2conn.block(true); + tcmode3conn.block(true); + shape->setCurve (pp->colorappearance.curve); + shape2->setCurve (pp->colorappearance.curve2); + shape3->setCurve (pp->colorappearance.curve3); + toneCurveMode->set_active(pp->colorappearance.curveMode); + toneCurveMode2->set_active(pp->colorappearance.curveMode2); + toneCurveMode3->set_active(pp->colorappearance.curveMode3); + curveMode3Changed(); // This will set the correct sensitive state of depending Adjusters + if (pedited) { + degree->setEditedState (pedited->colorappearance.degree ? Edited : UnEdited); + adapscen->setEditedState (pedited->colorappearance.adapscen ? Edited : UnEdited); + adaplum->setEditedState (pedited->colorappearance.adaplum ? Edited : UnEdited); + badpixsl->setEditedState (pedited->colorappearance.badpixsl ? Edited : UnEdited); + jlight->setEditedState (pedited->colorappearance.jlight ? Edited : UnEdited); + qbright->setEditedState (pedited->colorappearance.qbright ? Edited : UnEdited); + chroma->setEditedState (pedited->colorappearance.chroma ? Edited : UnEdited); + schroma->setEditedState (pedited->colorappearance.schroma ? Edited : UnEdited); + mchroma->setEditedState (pedited->colorappearance.mchroma ? Edited : UnEdited); + rstprotection->setEditedState (pedited->colorappearance.rstprotection ? Edited : UnEdited); + contrast->setEditedState (pedited->colorappearance.contrast ? Edited : UnEdited); + qcontrast->setEditedState (pedited->colorappearance.qcontrast ? Edited : UnEdited); + colorh->setEditedState (pedited->colorappearance.colorh ? Edited : UnEdited); + surrsource->set_inconsistent (!pedited->colorappearance.surrsource); + gamut->set_inconsistent (!pedited->colorappearance.gamut); + // badpix->set_inconsistent (!pedited->colorappearance.badpix); + datacie->set_inconsistent (!pedited->colorappearance.datacie); + tonecie->set_inconsistent (!pedited->colorappearance.tonecie); + // sharpcie->set_inconsistent (!pedited->colorappearance.sharpcie); + + degree->setAutoInconsistent (multiImage && !pedited->colorappearance.autodegree); + adapscen->setAutoInconsistent (multiImage && !pedited->colorappearance.autoadapscen); + set_inconsistent (multiImage && !pedited->colorappearance.enabled); + + shape->setUnChanged (!pedited->colorappearance.curve); + shape2->setUnChanged (!pedited->colorappearance.curve2); + shape3->setUnChanged (!pedited->colorappearance.curve3); + if (!pedited->colorappearance.curveMode) { + toneCurveMode->set_active(2); + } + if (!pedited->colorappearance.curveMode2) { + toneCurveMode2->set_active(2); + } + if (!pedited->colorappearance.curveMode3) { + toneCurveMode3->set_active(3); + } + + + } + + setEnabled(pp->colorappearance.enabled); + + surroundconn.block(true); + if (pedited && !pedited->colorappearance.surround) + surround->set_active (4); + else if (pp->colorappearance.surround=="Average") + surround->set_active (0); + else if (pp->colorappearance.surround=="Dim") + surround->set_active (1); + else if (pp->colorappearance.surround=="Dark") + surround->set_active (2); + else if (pp->colorappearance.surround=="ExtremelyDark") + surround->set_active (3); + surroundconn.block(false); + // Have to be manually called to handle initial state update + surroundChanged(); + + wbmodelconn.block(true); + if (pedited && !pedited->colorappearance.wbmodel) + wbmodel->set_active (2); + else if (pp->colorappearance.wbmodel=="RawT") + wbmodel->set_active (0); + else if (pp->colorappearance.wbmodel=="RawTCAT02") + wbmodel->set_active (1); + wbmodelconn.block(false); + // Have to be manually called to handle initial state update + wbmodelChanged(); + + algoconn.block(true); + if (pedited && !pedited->colorappearance.algo) + algo->set_active (4); + else if (pp->colorappearance.algo=="JC") + algo->set_active (0); + else if (pp->colorappearance.algo=="JS") + algo->set_active (1); + else if (pp->colorappearance.algo=="QM") + algo->set_active (2); + else if (pp->colorappearance.algo=="ALL") + algo->set_active (3); + algoconn.block(false); + // Have to be manually called to handle initial state update + algoChanged(); + + surrconn.block (true); + surrsource->set_active (pp->colorappearance.surrsource); + surrconn.block (false); + gamutconn.block (true); + gamut->set_active (pp->colorappearance.gamut); + gamutconn.block (false); +// badpixconn.block (true); +// badpix->set_active (pp->colorappearance.badpix); +// badpixconn.block (false); + datacieconn.block (true); + datacie->set_active (pp->colorappearance.datacie); + datacieconn.block (false); + tonecieconn.block (true); + tonecie->set_active (pp->colorappearance.tonecie); + tonecieconn.block (false); +// sharpcieconn.block (true); +// sharpcie->set_active (pp->colorappearance.sharpcie); +// sharpcieconn.block (false); + + lastsurr=pp->colorappearance.surrsource; + lastgamut=pp->colorappearance.gamut; +// lastbadpix=pp->colorappearance.badpix; + lastdatacie=pp->colorappearance.datacie; + lasttonecie=pp->colorappearance.tonecie; +// lastsharpcie=pp->colorappearance.sharpcie; + + lastAutoDegree = pp->colorappearance.autodegree; + lastAutoAdapscen = pp->colorappearance.autoadapscen; + + degree->setValue (pp->colorappearance.degree); + degree->setAutoValue(pp->colorappearance.autodegree); + adapscen->setValue (pp->colorappearance.adapscen); + adapscen->setAutoValue (pp->colorappearance.autoadapscen); + + adaplum->setValue (pp->colorappearance.adaplum); + badpixsl->setValue (pp->colorappearance.badpixsl); + jlight->setValue (pp->colorappearance.jlight); + qbright->setValue (pp->colorappearance.qbright); + chroma->setValue (pp->colorappearance.chroma); + schroma->setValue (pp->colorappearance.schroma); + mchroma->setValue (pp->colorappearance.mchroma); + rstprotection->setValue (pp->colorappearance.rstprotection); + contrast->setValue (pp->colorappearance.contrast); + qcontrast->setValue (pp->colorappearance.qcontrast); + colorh->setValue (pp->colorappearance.colorh); + + tcmode3conn.block(false); + tcmode2conn.block(false); + tcmodeconn.block(false); + enableListener (); +} +void ColorAppearance::autoOpenCurve () { + shape->openIfNonlinear(); + shape2->openIfNonlinear(); + shape3->openIfNonlinear(); + +} + + +void ColorAppearance::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->colorappearance.degree = degree->getValue (); + pp->colorappearance.autodegree = degree->getAutoValue (); + pp->colorappearance.enabled = getEnabled(); + pp->colorappearance.adapscen = adapscen->getValue (); + pp->colorappearance.autoadapscen = adapscen->getAutoValue (); + pp->colorappearance.adaplum = adaplum->getValue (); + pp->colorappearance.badpixsl = badpixsl->getValue (); + pp->colorappearance.jlight = jlight->getValue (); + pp->colorappearance.qbright = qbright->getValue (); + pp->colorappearance.chroma = chroma->getValue (); + pp->colorappearance.schroma = schroma->getValue (); + pp->colorappearance.mchroma = mchroma->getValue (); + pp->colorappearance.contrast = contrast->getValue (); + pp->colorappearance.qcontrast = qcontrast->getValue (); + pp->colorappearance.colorh = colorh->getValue (); + pp->colorappearance.rstprotection = rstprotection->getValue (); + pp->colorappearance.surrsource = surrsource->get_active(); + pp->colorappearance.gamut = gamut->get_active(); +// pp->colorappearance.badpix = badpix->get_active(); + pp->colorappearance.datacie = datacie->get_active(); + pp->colorappearance.tonecie = tonecie->get_active(); +// pp->colorappearance.sharpcie = sharpcie->get_active(); + pp->colorappearance.curve = shape->getCurve (); + pp->colorappearance.curve2 = shape2->getCurve (); + pp->colorappearance.curve3 = shape3->getCurve (); + + int tcMode = toneCurveMode->get_active_row_number(); + if (tcMode == 0) pp->colorappearance.curveMode = ColorAppearanceParams::TC_MODE_LIGHT; + else if (tcMode == 1) pp->colorappearance.curveMode = ColorAppearanceParams::TC_MODE_BRIGHT; + + tcMode = toneCurveMode2->get_active_row_number(); + if (tcMode == 0) pp->colorappearance.curveMode2 = ColorAppearanceParams::TC_MODE_LIGHT; + else if (tcMode == 1) pp->colorappearance.curveMode2 = ColorAppearanceParams::TC_MODE_BRIGHT; + + int tcMode3 = toneCurveMode3->get_active_row_number(); + if (tcMode3 == 0) pp->colorappearance.curveMode3 = ColorAppearanceParams::TC_MODE_CHROMA; + else if (tcMode3 == 1) pp->colorappearance.curveMode3 = ColorAppearanceParams::TC_MODE_SATUR; + else if (tcMode3 == 2) pp->colorappearance.curveMode3 = ColorAppearanceParams::TC_MODE_COLORF; + + if (pedited) { + pedited->colorappearance.degree = degree->getEditedState (); + pedited->colorappearance.adapscen = adapscen->getEditedState (); + pedited->colorappearance.adaplum = adaplum->getEditedState (); + pedited->colorappearance.badpixsl = badpixsl->getEditedState (); + pedited->colorappearance.jlight = jlight->getEditedState (); + pedited->colorappearance.qbright = qbright->getEditedState (); + pedited->colorappearance.chroma = chroma->getEditedState (); + pedited->colorappearance.schroma = schroma->getEditedState (); + pedited->colorappearance.mchroma = mchroma->getEditedState (); + pedited->colorappearance.contrast = contrast->getEditedState (); + pedited->colorappearance.qcontrast = qcontrast->getEditedState (); + pedited->colorappearance.colorh = colorh->getEditedState (); + pedited->colorappearance.rstprotection = rstprotection->getEditedState (); + pedited->colorappearance.autodegree = !degree->getAutoInconsistent(); + pedited->colorappearance.autoadapscen = !adapscen->getAutoInconsistent(); + pedited->colorappearance.enabled = !get_inconsistent(); + pedited->colorappearance.surround = surround->get_active_text()!=M("GENERAL_UNCHANGED"); + pedited->colorappearance.wbmodel = wbmodel->get_active_text()!=M("GENERAL_UNCHANGED"); + pedited->colorappearance.algo = algo->get_active_text()!=M("GENERAL_UNCHANGED"); + pedited->colorappearance.surrsource = !surrsource->get_inconsistent(); + pedited->colorappearance.gamut = !gamut->get_inconsistent(); + // pedited->colorappearance.badpix = !badpix->get_inconsistent(); + pedited->colorappearance.datacie = !datacie->get_inconsistent(); + pedited->colorappearance.tonecie = !tonecie->get_inconsistent(); + // pedited->colorappearance.sharpcie = !sharpcie->get_inconsistent(); + pedited->colorappearance.curve = !shape->isUnChanged (); + pedited->colorappearance.curve2 = !shape2->isUnChanged (); + pedited->colorappearance.curve3 = !shape3->isUnChanged (); + pedited->colorappearance.curveMode = toneCurveMode->get_active_row_number() != 2; + pedited->colorappearance.curveMode2 = toneCurveMode2->get_active_row_number() != 2; + pedited->colorappearance.curveMode3 = toneCurveMode3->get_active_row_number() != 3; + } + if (surround->get_active_row_number()==0) + pp->colorappearance.surround = "Average"; + else if (surround->get_active_row_number()==1) + pp->colorappearance.surround = "Dim"; + else if (surround->get_active_row_number()==2) + pp->colorappearance.surround = "Dark"; + else if (surround->get_active_row_number()==3) + pp->colorappearance.surround = "ExtremelyDark"; + + if (wbmodel->get_active_row_number()==0) + pp->colorappearance.wbmodel = "RawT"; + else if (wbmodel->get_active_row_number()==1) + pp->colorappearance.wbmodel = "RawTCAT02"; + + if (algo->get_active_row_number()==0) + pp->colorappearance.algo = "JC"; + else if (algo->get_active_row_number()==1) + pp->colorappearance.algo = "JS"; + else if (algo->get_active_row_number()==2) + pp->colorappearance.algo = "QM"; + else if (algo->get_active_row_number()==3) + pp->colorappearance.algo = "ALL"; + +} +void ColorAppearance::curveChanged (CurveEditor* ce) { + + if (listener) { + if (ce == shape) + listener->panelChanged (EvCATCurve1, M("HISTORY_CUSTOMCURVE")); + else if (ce == shape2) + listener->panelChanged (EvCATCurve2, M("HISTORY_CUSTOMCURVE")); + else if (ce == shape3) + listener->panelChanged (EvCATCurve3, M("HISTORY_CUSTOMCURVE")); + } +} + +void ColorAppearance::curveMode1Changed () { + if (listener) Glib::signal_idle().connect (sigc::mem_fun(*this, &ColorAppearance::curveMode1Changed_)); +} + +bool ColorAppearance::curveMode1Changed_ () { + if (listener) listener->panelChanged (EvCATCurveMode1, toneCurveMode->get_active_text()); + return false; +} + +void ColorAppearance::curveMode2Changed () { + if (listener) Glib::signal_idle().connect (sigc::mem_fun(*this, &ColorAppearance::curveMode2Changed_)); +} + +bool ColorAppearance::curveMode2Changed_ () { + if (listener) listener->panelChanged (EvCATCurveMode2, toneCurveMode2->get_active_text()); + return false; +} + +void ColorAppearance::curveMode3Changed () { + int tcMode3 = toneCurveMode3->get_active_row_number(); + if (tcMode3 == 0) {chroma->set_sensitive(true); schroma->set_sensitive(true); } + else if (tcMode3 == 2) {chroma->set_sensitive(false); schroma->set_sensitive(false);} + else if (tcMode3 == 1) {chroma->set_sensitive(false); schroma->set_sensitive(true); } + + if (listener) Glib::signal_idle().connect (sigc::mem_fun(*this, &ColorAppearance::curveMode3Changed_)); +} + +bool ColorAppearance::curveMode3Changed_ () { + if (listener) { + listener->panelChanged (EvCATCurveMode3, toneCurveMode3->get_active_text()); + } + return false; +} + +void ColorAppearance::surrsource_toggled () { + + if (batchMode) { + if (surrsource->get_inconsistent()) { + surrsource->set_inconsistent (false); + surrconn.block (true); + surrsource->set_active (false); + surrconn.block (false); + } + else if (lastsurr) + surrsource->set_inconsistent (true); + + lastsurr = surrsource->get_active (); + } + + if (listener) { + if (surrsource->get_active ()) + listener->panelChanged (EvCATsurr, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvCATsurr, M("GENERAL_DISABLED")); + } +} + +void ColorAppearance::gamut_toggled () { + + if (batchMode) { + if (gamut->get_inconsistent()) { + gamut->set_inconsistent (false); + gamutconn.block (true); + gamut->set_active (false); + gamutconn.block (false); + } + else if (lastgamut) + gamut->set_inconsistent (true); + + lastgamut = gamut->get_active (); + } + if (listener) { + if (gamut->get_active ()) + listener->panelChanged (EvCATgamut, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvCATgamut, M("GENERAL_DISABLED")); + } + + +} +/* +void ColorAppearance::badpix_toggled () { + + if (batchMode) { + if (badpix->get_inconsistent()) { + badpix->set_inconsistent (false); + badpixconn.block (true); + badpix->set_active (false); + badpixconn.block (false); + } + else if (lastbadpix) + badpix->set_inconsistent (true); + + lastbadpix = badpix->get_active (); + } + if (listener) { + if (badpix->get_active ()) + listener->panelChanged (EvCATbadpix, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvCATbadpix, M("GENERAL_DISABLED")); + } + + +} +*/ +void ColorAppearance::datacie_toggled () { + + if (batchMode) { + if (datacie->get_inconsistent()) { + datacie->set_inconsistent (false); + datacieconn.block (true); + datacie->set_active (false); + datacieconn.block (false); + } + else if (lastdatacie) + datacie->set_inconsistent (true); + + lastdatacie = datacie->get_active (); + } + + if (listener) { + if (datacie->get_active ()) + listener->panelChanged (EvCATdatacie, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvCATdatacie, M("GENERAL_DISABLED")); + } +} +void ColorAppearance::tonecie_toggled () { + + if (batchMode) { + if (tonecie->get_inconsistent()) { + tonecie->set_inconsistent (false); + tonecieconn.block (true); + tonecie->set_active (false); + tonecieconn.block (false); + } + else if (lasttonecie) + tonecie->set_inconsistent (true); + + lasttonecie = tonecie->get_active (); + } + if (listener) { + if (tonecie->get_active ()) + listener->panelChanged (EvCATtonecie, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvCATtonecie, M("GENERAL_DISABLED")); + } + +} +/* +void ColorAppearance::sharpcie_toggled () { + + if (batchMode) { + if (sharpcie->get_inconsistent()) { + sharpcie->set_inconsistent (false); + sharpcieconn.block (true); + sharpcie->set_active (false); + sharpcieconn.block (false); + } + else if (lastsharpcie) + sharpcie->set_inconsistent (true); + + lastsharpcie = sharpcie->get_active (); + } + if (listener) { + if (sharpcie->get_active ()) + listener->panelChanged (EvCATsharpcie, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvCATsharpcie, M("GENERAL_DISABLED")); + } + +} +*/ + +void ColorAppearance::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + degree->setDefault (defParams->colorappearance.degree); + adapscen->setDefault (defParams->colorappearance.adapscen); + adaplum->setDefault (defParams->colorappearance.adaplum); + badpixsl->setDefault (defParams->colorappearance.badpixsl); + jlight->setDefault (defParams->colorappearance.jlight); + qbright->setDefault (defParams->colorappearance.qbright); + chroma->setDefault (defParams->colorappearance.chroma); + schroma->setDefault (defParams->colorappearance.schroma); + mchroma->setDefault (defParams->colorappearance.mchroma); + rstprotection->setDefault (defParams->colorappearance.rstprotection); + contrast->setDefault (defParams->colorappearance.contrast); + qcontrast->setDefault (defParams->colorappearance.qcontrast); + colorh->setDefault (defParams->colorappearance.colorh); + + if (pedited) { + degree->setDefaultEditedState (pedited->colorappearance.degree ? Edited : UnEdited); + adapscen->setDefaultEditedState (pedited->colorappearance.adapscen ? Edited : UnEdited); + adaplum->setDefaultEditedState (pedited->colorappearance.adaplum ? Edited : UnEdited); + badpixsl->setDefaultEditedState (pedited->colorappearance.badpixsl ? Edited : UnEdited); + jlight->setDefaultEditedState (pedited->colorappearance.jlight ? Edited : UnEdited); + qbright->setDefaultEditedState (pedited->colorappearance.qbright ? Edited : UnEdited); + chroma->setDefaultEditedState (pedited->colorappearance.chroma ? Edited : UnEdited); + schroma->setDefaultEditedState (pedited->colorappearance.schroma ? Edited : UnEdited); + mchroma->setDefaultEditedState (pedited->colorappearance.mchroma ? Edited : UnEdited); + rstprotection->setDefaultEditedState (pedited->colorappearance.rstprotection ? Edited : UnEdited); + contrast->setDefaultEditedState (pedited->colorappearance.contrast ? Edited : UnEdited); + qcontrast->setDefaultEditedState (pedited->colorappearance.qcontrast ? Edited : UnEdited); + colorh->setDefaultEditedState (pedited->colorappearance.colorh ? Edited : UnEdited); + + } + else { + degree->setDefaultEditedState (Irrelevant); + adapscen->setDefaultEditedState (Irrelevant); + adaplum->setDefaultEditedState (Irrelevant); + badpixsl->setDefaultEditedState (Irrelevant); + jlight->setDefaultEditedState (Irrelevant); + qbright->setDefaultEditedState (Irrelevant); + chroma->setDefaultEditedState (Irrelevant); + schroma->setDefaultEditedState (Irrelevant); + mchroma->setDefaultEditedState (Irrelevant); + contrast->setDefaultEditedState (Irrelevant); + qcontrast->setDefaultEditedState (Irrelevant); + rstprotection->setDefaultEditedState (Irrelevant); + colorh->setDefaultEditedState (Irrelevant); + + } +} +int autoCamChangedUI (void* data) { + GThreadLock lock; // All GUI acces from idle_add callbacks or separate thread HAVE to be protected + (static_cast(data))->autoCamComputed_ (); + return 0; +} +void ColorAppearance::autoCamChanged (double ccam) +{ + nextCcam = ccam; + g_idle_add (autoCamChangedUI, this); +} + +bool ColorAppearance::autoCamComputed_ () { + + disableListener (); +// degree->setEnabled (true); + degree->setValue (nextCcam); + enableListener (); + + return false; +} +int adapCamChangedUI (void* data) { + GThreadLock lock; // All GUI acces from idle_add callbacks or separate thread HAVE to be protected + (static_cast(data))->adapCamComputed_ (); + return 0; +} +void ColorAppearance::adapCamChanged (double cadap) +{ + nextCadap = cadap; + g_idle_add (adapCamChangedUI, this); +} + +bool ColorAppearance::adapCamComputed_ () { + + disableListener (); +// degree->setEnabled (true); + adapscen->setValue (nextCadap); + enableListener (); + + return false; +} + + +void ColorAppearance::colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller *caller) { + + float R, G, B; + + if (elemType==ColorCaller::CCET_VERTICAL_BAR) + valY = 0.5; + + if (callerId == 1) { // cc - bottom bar + + float value = (1.f - 0.7f) * float(valX) + 0.7f; + // whole hue range + // Y axis / from 0.15 up to 0.75 (arbitrary values; was 0.45 before) + Color::hsv2rgb01(float(valY), float(valX), value, R, G, B); + } + caller->ccRed = double(R); + caller->ccGreen = double(G); + caller->ccBlue = double(B); +} + +void ColorAppearance::adjusterChanged (Adjuster* a, double newval) { + + if (listener && (multiImage||getEnabled()) ) { + if(a==degree) + listener->panelChanged (EvCATDegree, a->getTextValue()); + else if(a==adapscen) + listener->panelChanged (EvCATAdapscen, a->getTextValue()); + else if(a==adaplum) + listener->panelChanged (EvCATAdapLum, a->getTextValue()); + else if(a==badpixsl) + listener->panelChanged (EvCATbadpix, a->getTextValue()); + else if(a==jlight) + listener->panelChanged (EvCATJLight, a->getTextValue()); + else if(a==qbright) + listener->panelChanged (EvCATQbright, a->getTextValue()); + else if(a==chroma) + listener->panelChanged (EvCATChroma, a->getTextValue()); + else if(a==schroma) + listener->panelChanged (EvCATSChroma, a->getTextValue()); + else if(a==mchroma) + listener->panelChanged (EvCATMChroma, a->getTextValue()); + else if(a==rstprotection) + listener->panelChanged (EvCATRstpro, a->getTextValue()); + else if(a==contrast) + listener->panelChanged (EvCATContrast, a->getTextValue()); + else if(a==colorh) + listener->panelChanged (EvCAThue, a->getTextValue()); + else if(a==qcontrast) + listener->panelChanged (EvCATQContrast, a->getTextValue()); + + } +} + +void ColorAppearance::adjusterAutoToggled (Adjuster* a, bool newval) { + + if (multiImage) { + if (degree->getAutoInconsistent()) { + degree->setAutoInconsistent(false); + degree->setAutoValue(false); + } + else if (lastAutoDegree) + degree->setAutoInconsistent(true); + + lastAutoDegree = degree->getAutoValue(); + + if (adapscen->getAutoInconsistent()) { + adapscen->setAutoInconsistent(false); + adapscen->setAutoValue(false); + } + else if (lastAutoAdapscen) + adapscen->setAutoInconsistent(true); + + lastAutoAdapscen = adapscen->getAutoValue(); + + } + + if (listener && (multiImage||getEnabled()) ) { + + if(a==degree) { + if (degree->getAutoInconsistent()) + listener->panelChanged (EvCATAutoDegree, M("GENERAL_UNCHANGED")); + else if (degree->getAutoValue()) + listener->panelChanged (EvCATAutoDegree, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvCATAutoDegree, M("GENERAL_DISABLED")); + } + if(a==adapscen) { + if (adapscen->getAutoInconsistent()) + listener->panelChanged (EvCATAutoAdap, M("GENERAL_UNCHANGED")); + else if (adapscen->getAutoValue()) + listener->panelChanged (EvCATAutoAdap, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvCATAutoAdap, M("GENERAL_DISABLED")); + } + + + } +} +void ColorAppearance::enabledChanged () { + + if (listener) { + if (get_inconsistent()) + listener->panelChanged (EvCATEnabled, M("GENERAL_UNCHANGED")); + else if (getEnabled()) { + listener->panelChanged (EvCATEnabled, M("GENERAL_ENABLED")); + curveEditorG->set_sensitive (true); + toneCurveMode->set_sensitive (true); + } + else + listener->panelChanged (EvCATEnabled, M("GENERAL_DISABLED")); + } +} + +void ColorAppearance::surroundChanged () { + + if (listener && (multiImage||getEnabled()) ) { + listener->panelChanged (EvCATMethodsur, surround->get_active_text ()); + } +} + +void ColorAppearance::wbmodelChanged () { + + if (listener && (multiImage||getEnabled()) ) { + listener->panelChanged (EvCATMethodWB, wbmodel->get_active_text ()); + } +} + + +void ColorAppearance::algoChanged () { + + if ( algo->get_active_row_number()==0 ) { + contrast->show(); + rstprotection->show(); + qcontrast->hide(); + jlight->show(); + mchroma->hide(); + chroma->show(); + schroma->hide(); + qbright->hide(); + colorh->hide(); + tonecie->hide(); + // sharpcie->hide(); + curveEditorG->show(); + curveEditorG2->show(); + curveEditorG3->show(); + } + else if ( algo->get_active_row_number()==1 ) { + rstprotection->show(); + contrast->show(); + qcontrast->hide(); + jlight->show(); + mchroma->hide(); + chroma->hide(); + schroma->show(); + qbright->hide(); + colorh->hide(); + tonecie->hide(); +// sharpcie->hide(); + curveEditorG->show(); + curveEditorG2->show(); + curveEditorG3->show(); + } + else if ( algo->get_active_row_number()==2 ) { + contrast->hide(); + rstprotection->show(); + qcontrast->show(); + jlight->hide(); + mchroma->show(); + chroma->hide(); + schroma->hide(); + qbright->show(); + colorh->hide(); + tonecie->show(); + // sharpcie->show(); + // sharpcie->hide(); + curveEditorG->show(); + curveEditorG2->show(); + curveEditorG3->show(); + } + else if ( algo->get_active_row_number()>=3 ) { // ">=3" because everything has to be visible with the "(unchanged)" option too + contrast->show(); + rstprotection->show(); + qcontrast->show(); + jlight->show(); + mchroma->show(); + chroma->show(); + schroma->show(); + qbright->show(); + colorh->show(); + tonecie->show(); +// sharpcie->show(); +// sharpcie->hide(); + curveEditorG->show(); + curveEditorG2->show(); + curveEditorG3->show(); + } + + if (listener && (multiImage||getEnabled()) ) { + listener->panelChanged (EvCATMethodalg, algo->get_active_text ()); + } +} + +void ColorAppearance::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + + degree->showEditedCB (); + adapscen->showEditedCB (); + adaplum->showEditedCB (); + badpixsl->showEditedCB (); + jlight->showEditedCB (); + qbright->showEditedCB (); + chroma->showEditedCB (); + schroma->showEditedCB (); + mchroma->showEditedCB (); + rstprotection->showEditedCB (); + contrast->showEditedCB (); + qcontrast->showEditedCB (); + colorh->showEditedCB (); + + surround->append_text (M("GENERAL_UNCHANGED")); + wbmodel->append_text (M("GENERAL_UNCHANGED")); + algo->append_text (M("GENERAL_UNCHANGED")); + toneCurveMode->append_text (M("GENERAL_UNCHANGED")); + toneCurveMode2->append_text (M("GENERAL_UNCHANGED")); + toneCurveMode3->append_text (M("GENERAL_UNCHANGED")); + + curveEditorG->setBatchMode (batchMode); + curveEditorG2->setBatchMode (batchMode); + curveEditorG3->setBatchMode (batchMode); +} + +void ColorAppearance::updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve, LUTu & histCCurve,/* LUTu & histCLurve, LUTu & histLLCurve,*/ LUTu & histLCAM, LUTu & histCCAM, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma){ + + shape->updateBackgroundHistogram (histLCAM); + shape3->updateBackgroundHistogram (histCCAM); +} + + + +void ColorAppearance::setAdjusterBehavior (bool degreeadd, bool adapscenadd, bool adaplumadd, bool badpixsladd, bool jlightadd, bool chromaadd, bool contrastadd, bool rstprotectionadd, bool qbrightadd, bool qcontrastadd, bool schromaadd, bool mchromaadd, bool colorhadd) { + + degree->setAddMode(degreeadd); + adapscen->setAddMode(adapscenadd); + adaplum->setAddMode(adaplumadd); + badpixsl->setAddMode(badpixsladd); + jlight->setAddMode(jlightadd); + qbright->setAddMode(qbrightadd); + chroma->setAddMode(chromaadd); + schroma->setAddMode(schromaadd); + mchroma->setAddMode(mchromaadd); + rstprotection->setAddMode(rstprotectionadd); + contrast->setAddMode(contrastadd); + qcontrast->setAddMode(qcontrastadd); + colorh->setAddMode(colorhadd); +} + +void ColorAppearance::trimValues (rtengine::procparams::ProcParams* pp) { + + degree->trimValue(pp->colorappearance.degree); + adapscen->trimValue(pp->colorappearance.adapscen); + adaplum->trimValue(pp->colorappearance.adaplum); + badpixsl->trimValue(pp->colorappearance.badpixsl); + jlight->trimValue(pp->colorappearance.jlight); + qbright->trimValue(pp->colorappearance.qbright); + chroma->trimValue(pp->colorappearance.chroma); + schroma->trimValue(pp->colorappearance.schroma); + mchroma->trimValue(pp->colorappearance.mchroma); + rstprotection->trimValue(pp->colorappearance.rstprotection); + contrast->trimValue(pp->colorappearance.contrast); + qcontrast->trimValue(pp->colorappearance.qcontrast); + colorh->trimValue(pp->colorappearance.colorh); +} diff --git a/rtgui/colorappearance.h b/rtgui/colorappearance.h new file mode 100644 index 000000000..5bb821965 --- /dev/null +++ b/rtgui/colorappearance.h @@ -0,0 +1,137 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _COLORAPPEARANCE_H_ +#define _COLORAPPEARANCE_H_ + +#include +#include "adjuster.h" +#include "toolpanel.h" +#include "curveeditor.h" +#include "curveeditorgroup.h" +#include "mycurve.h" +#include "guiutils.h" +#include "colorprovider.h" + +class ColorAppearance : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public rtengine::AutoCamListener, public CurveListener, public ColorProvider { + + protected: + Glib::RefPtr bgTTips; + Glib::RefPtr srTTips; + Glib::RefPtr bgPixbuf; + Glib::RefPtr srPixbuf; + + Adjuster* degree; + Adjuster* adapscen; + Adjuster* adaplum; + Adjuster* badpixsl; + Adjuster* jlight; + Adjuster* qbright; + Adjuster* chroma; + Adjuster* schroma; + Adjuster* mchroma; + Adjuster* rstprotection; + Adjuster* contrast; + Adjuster* qcontrast; + Adjuster* colorh; + MyComboBoxText* toneCurveMode; + MyComboBoxText* toneCurveMode2; + MyComboBoxText* toneCurveMode3; + + //Adjuster* edge; + Gtk::CheckButton* surrsource; + Gtk::CheckButton* gamut; + // Gtk::CheckButton* badpix; + Gtk::CheckButton* datacie; + Gtk::CheckButton* tonecie; + // Gtk::CheckButton* sharpcie; + + MyComboBoxText* surround; + sigc::connection surroundconn; + MyComboBoxText* wbmodel; + sigc::connection wbmodelconn; + MyComboBoxText* algo; + sigc::connection algoconn; + sigc::connection surrconn; + sigc::connection gamutconn, datacieconn, tonecieconn /*,badpixconn , sharpcieconn*/; + sigc::connection tcmodeconn, tcmode2conn, tcmode3conn; + CurveEditorGroup* curveEditorG; + CurveEditorGroup* curveEditorG2; + CurveEditorGroup* curveEditorG3; + + DiagonalCurveEditor* shape; + DiagonalCurveEditor* shape2; + DiagonalCurveEditor* shape3; + double nextCcam, nextCadap; + bool lastAutoDegree; + bool lastAutoAdapscen; + bool lastsurr; + bool lastgamut; +// bool lastbadpix; + bool lastdatacie; + bool lasttonecie; + // bool lastsharpcie; + bool bgTTipQuery(int x, int y, bool keyboard_tooltip, const Glib::RefPtr& tooltip); + bool srTTipQuery(int x, int y, bool keyboard_tooltip, const Glib::RefPtr& tooltip); + + public: + + ColorAppearance (); + ~ColorAppearance (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + void adjusterChanged (Adjuster* a, double newval); + void adjusterAutoToggled (Adjuster* a, bool newval); +// void adjusterAdapToggled (Adjuster* a, bool newval); + void enabledChanged (); + void surroundChanged (); + void wbmodelChanged (); + void algoChanged (); + void surrsource_toggled (); + void gamut_toggled (); + // void badpix_toggled (); + void datacie_toggled (); + void tonecie_toggled (); +// void sharpcie_toggled (); + void autoCamChanged (double ccam); + bool autoCamComputed_ (); + void adapCamChanged (double cadap); + bool adapCamComputed_ (); + + void curveChanged (CurveEditor* ce); + void curveMode1Changed (); + bool curveMode1Changed_ (); + void curveMode2Changed (); + bool curveMode2Changed_ (); + void curveMode3Changed (); + bool curveMode3Changed_ (); + + void expandCurve (bool isExpanded); + bool isCurveExpanded (); + void autoOpenCurve (); + + void setAdjusterBehavior (bool degreeadd, bool adapscenadd, bool adaplumadd, bool badpixsladd, bool jlightadd, bool chromaadd, bool contrastadd, bool rstprotectionadd, bool qbrightadd, bool qcontrastadd, bool schromaadd, bool mchromaadd, bool colorhadd); + void trimValues (rtengine::procparams::ProcParams* pp); + void updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve, LUTu & histCCurve,/* LUTu & histCLurve, LUTu & histLLCurve,*/ LUTu & histLCAM, LUTu & histCCAM, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma); + virtual void colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller *caller); +}; + +#endif diff --git a/rtgui/coloredbar.cc b/rtgui/coloredbar.cc new file mode 100644 index 000000000..de41b8312 --- /dev/null +++ b/rtgui/coloredbar.cc @@ -0,0 +1,177 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "coloredbar.h" + +ColoredBar::ColoredBar (eRTOrientation orient) { + orientation = orient; + dirty = true; + this->x = this->y = this->w = this->h = 0; +} + +/* + * Redraw the bar to a Cairo::ImageSurface + */ +void ColoredBar::expose(Cairo::RefPtr destSurface) { + // look out if the Surface has to be redrawn + if (!surfaceCreated() || !destSurface) + return; + draw(); + copySurface(destSurface); +} + +/* + * Redraw the bar to a Gdk::Window + */ +void ColoredBar::expose(Glib::RefPtr destWindow) { + // look out if the Surface has to be redrawn + if (!surfaceCreated() || !destWindow) + return; + draw(); + copySurface(destWindow); +} + +/* + * Redraw the bar to a Gdk::Window + */ +void ColoredBar::expose(BackBuffer *backBuffer) { + // look out if the Surface has to be redrawn + if (!surfaceCreated() || !backBuffer) + return; + draw(); + copySurface(backBuffer); +} + +void ColoredBar::draw() { + if (isDirty()) { + Cairo::RefPtr cr = getContext(); + // the bar has to be drawn to the Surface first + if (!bgGradient.empty()) { + // a gradient has been set, we use it + cr->set_line_width(0.); + + // gradient background + Cairo::RefPtr< Cairo::LinearGradient > bggradient; + switch (orientation) { + case (RTO_Left2Right): + bggradient = Cairo::LinearGradient::create (0., 0., double(w), 0.); + break; + case (RTO_Right2Left): + bggradient = Cairo::LinearGradient::create (double(w), 0., 0., 0.); + break; + case (RTO_Bottom2Top): + bggradient = Cairo::LinearGradient::create (0., double(h), 0., 0.); + break; + case (RTO_Top2Bottom): + default: + bggradient = Cairo::LinearGradient::create (0., 0., 0., double(h)); + break; + } + + for (std::vector::iterator i=bgGradient.begin(); i!=bgGradient.end(); i++) { + bggradient->add_color_stop_rgb (i->position, i->r, i->g, i->b); + } + cr->set_source (bggradient); + cr->rectangle(0, 0, w, h); + cr->fill(); + } + else { + // ask the ColorProvider to provide colors :) for each pixels + if (colorProvider) { + cr->set_antialias(Cairo::ANTIALIAS_NONE); + cr->set_line_width(1.); + switch (orientation) { + case (RTO_Left2Right): + for (int x=0; xcolorForValue (x01, y01, CCET_BACKGROUND, colorCallerId, this); + cr->set_source_rgb(ccRed, ccGreen, ccBlue); + cr->rectangle(x_, y_, 1., 1.); + cr->fill(); + } + } + break; + case (RTO_Right2Left): + for (int x=0; xcolorForValue (x01, y01, CCET_BACKGROUND, colorCallerId, this); + cr->set_source_rgb(ccRed, ccGreen, ccBlue); + cr->rectangle(x_, y_, 1., 1.); + cr->fill(); + } + } + break; + case (RTO_Bottom2Top): + for (int x=0; xcolorForValue (y01, x01, CCET_BACKGROUND, colorCallerId, this); + cr->set_source_rgb(ccRed, ccGreen, ccBlue); + cr->rectangle(x_, y_, 1., 1.); + cr->fill(); + } + } + break; + case (RTO_Top2Bottom): + default: + for (int x=0; xcolorForValue (y01, x01, CCET_BACKGROUND, colorCallerId, this); + cr->set_source_rgb(ccRed, ccGreen, ccBlue); + cr->rectangle(x_, y_, 1., 1.); + cr->fill(); + } + } + break; + } + } + } + // has it been updated or not, we assume that the Surface has been correctly set (we don't handle allocation error) + setDirty(false); + } +} + +void ColoredBar::setBgGradient (const std::vector &milestones) { + bgGradient = milestones; + setDirty(true); +} + +void ColoredBar::clearBgGradient () { + bgGradient.clear(); + setDirty(true); +} + +bool ColoredBar::canGetColors() { + return colorProvider!=NULL || bgGradient.size()>0; +} diff --git a/rtgui/coloredbar.h b/rtgui/coloredbar.h new file mode 100644 index 000000000..8e62e20ed --- /dev/null +++ b/rtgui/coloredbar.h @@ -0,0 +1,54 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _COLOREDBAR_ +#define _COLOREDBAR_ + +#include "colorprovider.h" +#include "guiutils.h" + +/* + * Parent class for all colored bar type; a ColorProvider has to be set + * thanks to "setColorProvider" to be able to display colors inside the bar + */ +class ColoredBar : public BackBuffer, public ColorCaller { + + private: + void draw(); + + protected: + eRTOrientation orientation; + std::vector bgGradient; + + public: + ColoredBar (eRTOrientation orient); + + void expose(Glib::RefPtr destWindow); + void expose(Cairo::RefPtr destSurface); + void expose(BackBuffer *backBuffer); + + bool canGetColors(); + + // Method for convenience; if no Gradient provided, the ColoredBar will ask colors on a per pixel basis + void setBgGradient (const std::vector &milestones); + // by clearing the gradient, the ColorProvider will have to provide colors on a per pixel basis if a ColorProvider + // has been set, through ColorProvider::colorForValue on next ColoredBar::expose + void clearBgGradient (); +}; + +#endif diff --git a/rtgui/colorprovider.h b/rtgui/colorprovider.h new file mode 100644 index 000000000..f2ad08205 --- /dev/null +++ b/rtgui/colorprovider.h @@ -0,0 +1,64 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _COLORPROVIDER_ +#define _COLORPROVIDER_ + +#include + +class ColorProvider; + +/* + * The ColorCaller is the class that will query the ColorProvider + */ +class ColorCaller { + protected: + // a class can handle several ColorCaller; + // colorCallerId will let the provider identify the caller + int colorCallerId; + ColorProvider* colorProvider; + + public: + enum ElemType { + CCET_POINT, + CCET_VERTICAL_BAR, + CCET_HORIZONTAL_BAR, + CCET_BACKGROUND + }; + double ccRed; + double ccGreen; + double ccBlue; + + ColorCaller() : colorCallerId(-1), colorProvider(NULL), ccRed(0.), ccGreen(0.), ccBlue(0.) {} + void setColorProvider (ColorProvider* p, int id) { colorProvider = p; colorCallerId = id; } +}; + +/* + * Use it to let your widget feed a colored bar or graph lines with the wanted colors + * If you doesn't need to dynamically feed a widget with colors (e.g. curve's graph), + * you don't need to declare the instanciator class as BEING a ColorProvider, you'll + * still be able to set gradients for e.g. ColoredBar(s) + */ +class ColorProvider { + + public: + virtual ~ColorProvider() {}; + virtual void colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller* caller) {}; +}; + +#endif diff --git a/rtgui/colortoning.cc b/rtgui/colortoning.cc new file mode 100644 index 000000000..32d232870 --- /dev/null +++ b/rtgui/colortoning.cc @@ -0,0 +1,1090 @@ +/* + * This file is part of RawTherapee. + */ +#include "colortoning.h" +#include "mycurve.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +ColorToning::ColorToning () : FoldableToolPanel(this, "colortoning", M("TP_COLORTONING_LABEL"), false, true) +{ + nextbw=0; + CurveListener::setMulti(true); + + //---------------method + + method = Gtk::manage (new MyComboBoxText ()); + method->append_text (M("TP_COLORTONING_LAB")); + method->append_text (M("TP_COLORTONING_RGBSLIDERS")); + method->append_text (M("TP_COLORTONING_RGBCURVES")); + method->append_text (M("TP_COLORTONING_SPLITCOCO")); + method->append_text (M("TP_COLORTONING_SPLITLR")); + method->set_active (0); + method->set_tooltip_text (M("TP_COLORTONING_METHOD_TOOLTIP")); + + ctbox = Gtk::manage (new Gtk::HBox ()); + Gtk::Label* lab = Gtk::manage (new Gtk::Label (M("TP_COLORTONING_METHOD"))); + ctbox->pack_start (*lab, Gtk::PACK_SHRINK, 4); + ctbox->pack_start (*method); + pack_start (*ctbox); + + methodconn = method->signal_changed().connect ( sigc::mem_fun(*this, &ColorToning::methodChanged) ); + + //----------- Color curve ------------------------------ + + colorSep = Gtk::manage (new Gtk::HSeparator()); + pack_start (*colorSep); + + colLabel = Gtk::manage (new Gtk::Label (M("TP_COLORTONING_LABCOL"))); + colLabel->set_tooltip_text (M("TP_COLORTONING_LABCOL_TOOLTIP")); + + interLabel = Gtk::manage (new Gtk::Label (M("TP_COLORTONING_LABINT"))); + interLabel->set_tooltip_text (M("TP_COLORTONING_LABINT_TOOLTIP")); + pack_start (*colLabel, Gtk::PACK_SHRINK, 4); + pack_start (*interLabel, Gtk::PACK_SHRINK, 4); + + colorCurveEditorG = new CurveEditorGroup (options.lastColorToningCurvesDir, M("TP_COLORTONING_COLOR")); + colorCurveEditorG->setCurveListener (this); + + colorShape = static_cast(colorCurveEditorG->addCurve(CT_Flat, "", NULL, false)); + colorShape->setCurveColorProvider(this, 1); + std::vector milestones; + // whole hue range + for (int i=0; i<7; i++) { + float R, G, B; + float x = float(i)*(1.0f/6.0); + Color::hsv2rgb01(x, 0.5f, 0.5f, R, G, B); + milestones.push_back( GradientMilestone(double(x), double(R), double(G), double(B)) ); + } + colorShape->setLeftBarBgGradient(milestones); + + // luminance gradient + milestones.clear(); + milestones.push_back( GradientMilestone(0., 0., 0., 0.) ); + milestones.push_back( GradientMilestone(1., 1., 1., 1.) ); + colorShape->setBottomBarBgGradient(milestones); + std::vector defaultCurve; + rtengine::ColorToningParams::getDefaultColorCurve(defaultCurve); + colorShape->setResetCurve(FCT_MinMaxCPoints, defaultCurve); + + // This will add the reset button at the end of the curveType buttons + colorCurveEditorG->curveListComplete(); + colorCurveEditorG->show(); + + pack_start( *colorCurveEditorG, Gtk::PACK_SHRINK, 2); + + //----------------------red green blue yellow colours + + twocolor = Gtk::manage (new MyComboBoxText ()); + twocolor->append_text (M("TP_COLORTONING_TWOSTD")); + twocolor->append_text (M("TP_COLORTONING_TWOALL")); + twocolor->append_text (M("TP_COLORTONING_TWOBY")); + twocolor->append_text (M("TP_COLORTONING_TWO2")); + twocolor->set_tooltip_text (M("TP_COLORTONING_TWOCOLOR_TOOLTIP")); + twocolor->set_active (0); + + twocconn = twocolor->signal_changed().connect( sigc::mem_fun(*this, &ColorToning::twoColorChangedByGui) ); + + pack_start (*twocolor, Gtk::PACK_SHRINK, 4); + + //----------- Opacity curve ------------------------------ + + opacityCurveEditorG = new CurveEditorGroup (options.lastColorToningCurvesDir, M("TP_COLORTONING_OPACITY")); + opacityCurveEditorG->setCurveListener (this); + + rtengine::ColorToningParams::getDefaultOpacityCurve(defaultCurve); + opacityShape = static_cast(opacityCurveEditorG->addCurve(CT_Flat, "", NULL, false)); + opacityShape->setIdentityValue(0.); + opacityShape->setResetCurve(FlatCurveType(defaultCurve.at(0)), defaultCurve); + opacityShape->setBottomBarBgGradient(milestones); + + // This will add the reset button at the end of the curveType buttons + opacityCurveEditorG->curveListComplete(); + opacityCurveEditorG->show(); + + pack_start( *opacityCurveEditorG, Gtk::PACK_SHRINK, 2); + + //---------Chroma curve 1 -------------------- + iby = Gtk::manage (new RTImage ("Chanmixer-BY.png")); + irg = Gtk::manage (new RTImage ("Chanmixer-RG.png")); + + clCurveEditorG = new CurveEditorGroup (options.lastColorToningCurvesDir, M("TP_COLORTONING_CHROMAC")); + clCurveEditorG->setCurveListener (this); + + rtengine::ColorToningParams::getDefaultCLCurve(defaultCurve); + clshape = static_cast(clCurveEditorG->addCurve(CT_Diagonal, M("TP_COLORTONING_AB"),irg)); + clshape->setResetCurve(DiagonalCurveType(defaultCurve.at(0)), defaultCurve); + clshape->setTooltip(M("TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP")); + + clshape->setLeftBarColorProvider(this, 1); + clshape->setRangeDefaultMilestones(0.25, 0.5, 0.75); + milestones.push_back( GradientMilestone(0., 0., 0., 0.) ); + milestones.push_back( GradientMilestone(1., 1., 1., 1.) ); + + clshape->setBottomBarBgGradient(milestones); + clCurveEditorG->curveListComplete(); + + pack_start( *clCurveEditorG, Gtk::PACK_SHRINK, 2); + + //---------Chroma curve 2 -------------------- + + cl2CurveEditorG = new CurveEditorGroup (options.lastColorToningCurvesDir, M("TP_COLORTONING_CHROMAC")); + cl2CurveEditorG->setCurveListener (this); + + rtengine::ColorToningParams::getDefaultCL2Curve(defaultCurve); + cl2shape = static_cast(cl2CurveEditorG->addCurve(CT_Diagonal, M("TP_COLORTONING_BY"),iby)); + cl2shape->setResetCurve(DiagonalCurveType(defaultCurve.at(0)), defaultCurve); + cl2shape->setTooltip(M("TP_COLORTONING_CURVEEDITOR_CL_TOOLTIP")); + + cl2shape->setLeftBarColorProvider(this, 1); + cl2shape->setRangeDefaultMilestones(0.25, 0.5, 0.75); + milestones.push_back( GradientMilestone(0., 0., 0., 0.) ); + milestones.push_back( GradientMilestone(1., 1., 1., 1.) ); + + cl2shape->setBottomBarBgGradient(milestones); + cl2CurveEditorG->curveListComplete(); + + pack_start( *cl2CurveEditorG, Gtk::PACK_SHRINK, 2); + + //--------------------- Reset curves ----------------------------- + /* Each curve can reset to a different curve, so this button only save one click now... so we remove it. + neutralCurves = Gtk::manage (new Gtk::Button (M("TP_COLORTONING_NEUTRALCUR"))); + RTImage *resetImgc = Gtk::manage (new RTImage ("gtk-undo-ltr-small.png", "gtk-undo-rtl-small.png")); + neutralCurves->set_image(*resetImgc); + neutralCurves->set_tooltip_text (M("TP_COLORTONING_NEUTRALCUR_TIP")); + neutralcurvesconn = neutralCurves->signal_pressed().connect( sigc::mem_fun(*this, &ColorToning::neutralCurves_pressed) ); + neutralCurves->show(); + + pack_start (*neutralCurves); + */ + + //----------- Sliders + balance ------------------------------ + + hlColSat = Gtk::manage (new ThresholdAdjuster (M("TP_COLORTONING_HIGHLIGHT"), 0., 100., 60., M("TP_COLORTONING_STRENGTH"), 1., 0., 360., 80., M("TP_COLORTONING_HUE"), 1., NULL, false)); + hlColSat->setAdjusterListener (this); + hlColSat->setBgColorProvider(this, 2); + hlColSat->setUpdatePolicy(RTUP_DYNAMIC); + + pack_start( *hlColSat, Gtk::PACK_SHRINK, 0); + + shadowsColSat = Gtk::manage (new ThresholdAdjuster (M("TP_COLORTONING_SHADOWS"), 0., 100., 80., M("TP_COLORTONING_STRENGTH"), 1., 0., 360., 208., M("TP_COLORTONING_HUE"), 1., NULL, false)); + shadowsColSat->setAdjusterListener (this); + shadowsColSat->setBgColorProvider(this, 3); + shadowsColSat->setUpdatePolicy(RTUP_DYNAMIC); + + pack_start( *shadowsColSat, Gtk::PACK_SHRINK, 0); + + + balance = Gtk::manage( new Adjuster(M("TP_COLORTONING_BALANCE"), -100., 100., 1., 0.) ); + balance->setAdjusterListener(this); + + pack_start (*balance, Gtk::PACK_SHRINK, 2); + + //----------- Saturation and strength ------------------------------ + +// satLimiterSep = Gtk::manage (new Gtk::HSeparator()); + + +// pack_start (*satLimiterSep, Gtk::PACK_SHRINK); + +// Gtk::Frame *p1Frame; + // Vertical box container for the content of the Process 1 frame + Gtk::VBox *p1VBox; + p1Frame = Gtk::manage (new Gtk::Frame(M("TP_COLORTONING_SA")) ); + p1Frame->set_border_width(0); + p1Frame->set_label_align(0.025, 0.5); + + p1VBox = Gtk::manage ( new Gtk::VBox()); + p1VBox->set_border_width(4); + p1VBox->set_spacing(2); + + autosat = Gtk::manage (new Gtk::CheckButton (M("TP_COLORTONING_AUTOSAT"))); + autosat->set_active (true); + autosatConn = autosat->signal_toggled().connect( sigc::mem_fun(*this, &ColorToning::autosatChanged) ); + //satFrame->set_label_widget(*autosat); + + p1VBox->pack_start (*autosat, Gtk::PACK_SHRINK, 2); + + satProtectionThreshold = Gtk::manage( new Adjuster(M("TP_COLORTONING_SATURATIONTHRESHOLD"), 0., 100., 1., 80.) ); + satProtectionThreshold->setAdjusterListener(this); + satProtectionThreshold->set_sensitive(false); + + p1VBox->pack_start( *satProtectionThreshold, Gtk::PACK_SHRINK, 2); + + saturatedOpacity = Gtk::manage( new Adjuster(M("TP_COLORTONING_SATURATEDOPACITY"), 0., 100., 1., 30.) );; + saturatedOpacity->setAdjusterListener(this); + saturatedOpacity->set_sensitive(false); + + p1VBox->pack_start( *saturatedOpacity, Gtk::PACK_SHRINK, 2); //I have moved after Chanmixer + p1Frame->add(*p1VBox); + pack_start (*p1Frame, Gtk::PACK_EXPAND_WIDGET, 4); + + strength = Gtk::manage( new Adjuster(M("TP_COLORTONING_STR"), 0., 100., 1., 50.) );; + strength->setAdjusterListener(this); + + + + // --------------------Sliders BW Colortoning ------------------- + + chanMixerBox = Gtk::manage (new Gtk::VBox()); + Gtk::VBox *chanMixerHLBox = Gtk::manage (new Gtk::VBox()); + Gtk::VBox *chanMixerMidBox = Gtk::manage (new Gtk::VBox()); + Gtk::VBox *chanMixerShadowsBox = Gtk::manage (new Gtk::VBox()); + + Gtk::Image* iblueR = Gtk::manage (new RTImage ("ajd-wb-temp1.png")); + Gtk::Image* iyelL = Gtk::manage (new RTImage ("ajd-wb-temp2.png")); + Gtk::Image* imagL = Gtk::manage (new RTImage ("ajd-wb-green1.png")); + Gtk::Image* igreenR = Gtk::manage (new RTImage ("ajd-wb-green2.png")); + Gtk::Image* icyanL = Gtk::manage (new RTImage ("ajd-wb-bluered1.png")); + Gtk::Image* iredR = Gtk::manage (new RTImage ("ajd-wb-bluered2.png")); + + Gtk::Image* iblueRm = Gtk::manage (new RTImage ("ajd-wb-temp1.png")); + Gtk::Image* iyelLm = Gtk::manage (new RTImage ("ajd-wb-temp2.png")); + Gtk::Image* imagLm = Gtk::manage (new RTImage ("ajd-wb-green1.png")); + Gtk::Image* igreenRm = Gtk::manage (new RTImage ("ajd-wb-green2.png")); + Gtk::Image* icyanLm = Gtk::manage (new RTImage ("ajd-wb-bluered1.png")); + Gtk::Image* iredRm = Gtk::manage (new RTImage ("ajd-wb-bluered2.png")); + + Gtk::Image* iblueRh = Gtk::manage (new RTImage ("ajd-wb-temp1.png")); + Gtk::Image* iyelLh = Gtk::manage (new RTImage ("ajd-wb-temp2.png")); + Gtk::Image* imagLh = Gtk::manage (new RTImage ("ajd-wb-green1.png")); + Gtk::Image* igreenRh = Gtk::manage (new RTImage ("ajd-wb-green2.png")); + Gtk::Image* icyanLh = Gtk::manage (new RTImage ("ajd-wb-bluered1.png")); + Gtk::Image* iredRh = Gtk::manage (new RTImage ("ajd-wb-bluered2.png")); + + redhigh = Gtk::manage (new Adjuster ("", -100., 100., 1., 0., icyanLh, iredRh )); + greenhigh = Gtk::manage (new Adjuster ("", -100., 100., 1., 0., imagLh , igreenRh)); + bluehigh = Gtk::manage (new Adjuster ("", -100., 100., 1., 0., iyelLh , iblueRh )); + + redmed = Gtk::manage (new Adjuster ("", -100., 100., 1., 0., icyanLm, iredRm )); + greenmed = Gtk::manage (new Adjuster ("", -100., 100., 1., 0., imagLm , igreenRm)); + bluemed = Gtk::manage (new Adjuster ("", -100., 100., 1., 0., iyelLm , iblueRm )); + + redlow = Gtk::manage (new Adjuster ("", -100., 100., 1., 0., icyanL, iredR )); + greenlow = Gtk::manage (new Adjuster ("", -100., 100., 1., 0., imagL , igreenR)); + bluelow = Gtk::manage (new Adjuster ("", -100., 100., 1., 0., iyelL , iblueR )); + + chanMixerHLBox->pack_start (*redhigh); + chanMixerHLBox->pack_start (*greenhigh); + chanMixerHLBox->pack_start (*bluehigh); + chanMixerMidBox->pack_start (*redmed); + chanMixerMidBox->pack_start (*greenmed); + chanMixerMidBox->pack_start (*bluemed); + chanMixerShadowsBox->pack_start (*redlow); + chanMixerShadowsBox->pack_start (*greenlow); + chanMixerShadowsBox->pack_start (*bluelow); + + Gtk::Frame *chanMixerHLFrame = Gtk::manage (new Gtk::Frame(M("TP_COLORTONING_HIGHLIGHT"))); + Gtk::Frame *chanMixerMidFrame = Gtk::manage (new Gtk::Frame(M("TP_COLORTONING_MIDTONES"))); + Gtk::Frame *chanMixerShadowsFrame = Gtk::manage (new Gtk::Frame(M("TP_COLORTONING_SHADOWS"))); + + chanMixerHLFrame->add(*chanMixerHLBox); + chanMixerMidFrame->add(*chanMixerMidBox); + chanMixerShadowsFrame->add(*chanMixerShadowsBox); + + chanMixerBox->pack_start(*chanMixerHLFrame, Gtk::PACK_SHRINK); + chanMixerBox->pack_start(*chanMixerMidFrame, Gtk::PACK_SHRINK); + chanMixerBox->pack_start(*chanMixerShadowsFrame, Gtk::PACK_SHRINK); + + pack_start(*chanMixerBox, Gtk::PACK_SHRINK); + pack_start( *strength, Gtk::PACK_SHRINK, 2); //I have moved after Chanmixer + + //--------------------- Reset sliders --------------------------- + neutrHBox = Gtk::manage (new Gtk::HBox ()); + neutrHBox->set_border_width (2); + + neutral = Gtk::manage (new Gtk::Button (M("TP_COLORTONING_NEUTRAL"))); + RTImage *resetImg = Gtk::manage (new RTImage ("gtk-undo-ltr-small.png", "gtk-undo-rtl-small.png")); + neutral->set_image(*resetImg); + neutral->set_tooltip_text (M("TP_COLORTONING_NEUTRAL_TIP")); + neutralconn = neutral->signal_pressed().connect( sigc::mem_fun(*this, &ColorToning::neutral_pressed) ); + neutral->show(); + neutrHBox->pack_start (*neutral); + + pack_start (*neutrHBox); + + //--------------------- Keep luminance checkbox ------------------- + lumamode = Gtk::manage (new Gtk::CheckButton (M("TP_COLORTONING_LUMAMODE"))); + lumamode->set_tooltip_markup (M("TP_COLORTONING_LUMAMODE_TOOLTIP")); + lumamode->set_active (false); + lumamode->show (); + lumamodeConn = lumamode->signal_toggled().connect( sigc::mem_fun(*this, &ColorToning::lumamodeChanged) ); + + pack_start (*lumamode); + + + redlow->setAdjusterListener (this); + greenlow->setAdjusterListener (this); + bluelow->setAdjusterListener (this); + balance->setAdjusterListener (this); + redmed->setAdjusterListener (this); + greenmed->setAdjusterListener (this); + bluemed->setAdjusterListener (this); + redhigh->setAdjusterListener (this); + greenhigh->setAdjusterListener (this); + bluehigh->setAdjusterListener (this); + + show_all(); + + disableListener(); + methodChanged(); + enableListener(); +} + +ColorToning::~ColorToning() { + delete colorCurveEditorG; + delete opacityCurveEditorG; + delete clCurveEditorG; + delete cl2CurveEditorG; +} + +/* +void ColorToning::neutralCurves_pressed () { + disableListener(); + + bool changed = false; + changed |= colorShape->reset(); + changed |= opacityShape->reset(); + changed |= clshape->reset(); + changed |= cl2shape->reset(); + + enableListener(); + + if (listener && enabled->get_active() && changed) + listener->panelChanged (EvColorToningNeutralcur, M("ADJUSTER_RESET_TO_DEFAULT")); +} +*/ + +// Will only reset the chanel mixer +void ColorToning::neutral_pressed () { + disableListener(); + redlow->resetValue(false); + greenlow->resetValue(false); + bluelow->resetValue(false); + redmed->resetValue(false); + greenmed->resetValue(false); + bluemed->resetValue(false); + redhigh->resetValue(false); + greenhigh->resetValue(false); + bluehigh->resetValue(false); + //balance->resetValue(false); + + enableListener(); + if (listener && getEnabled()) + listener->panelChanged (EvColorToningNeutral, M("ADJUSTER_RESET_TO_DEFAULT")); +} + +void ColorToning::read (const ProcParams* pp, const ParamsEdited* pedited) +{ + disableListener (); + methodconn.block(true); + twocconn.block(true); + colorShape->setCurve (pp->colorToning.colorCurve); + opacityShape->setCurve (pp->colorToning.opacityCurve); + clshape->setCurve (pp->colorToning.clcurve); + cl2shape->setCurve (pp->colorToning.cl2curve); + + if (pedited) { + redlow->setEditedState (pedited->colorToning.redlow ? Edited : UnEdited); + greenlow->setEditedState (pedited->colorToning.greenlow ? Edited : UnEdited); + bluelow->setEditedState (pedited->colorToning.bluelow ? Edited : UnEdited); + balance->setEditedState (pedited->colorToning.balance ? Edited : UnEdited); + redmed->setEditedState (pedited->colorToning.redmed ? Edited : UnEdited); + greenmed->setEditedState (pedited->colorToning.greenmed ? Edited : UnEdited); + bluemed->setEditedState (pedited->colorToning.bluemed ? Edited : UnEdited); + redhigh->setEditedState (pedited->colorToning.redhigh ? Edited : UnEdited); + greenhigh->setEditedState (pedited->colorToning.greenhigh ? Edited : UnEdited); + bluehigh->setEditedState (pedited->colorToning.bluehigh ? Edited : UnEdited); + + hlColSat->setEditedState (pedited->colorToning.hlColSat ? Edited : UnEdited); + shadowsColSat->setEditedState (pedited->colorToning.shadowsColSat ? Edited : UnEdited); + + set_inconsistent (multiImage && !pedited->colorToning.enabled); + colorShape->setUnChanged (!pedited->colorToning.colorCurve); + opacityShape->setUnChanged (!pedited->colorToning.opacityCurve); + autosat->set_inconsistent (!pedited->colorToning.autosat); + clshape->setUnChanged (!pedited->colorToning.clcurve); + cl2shape->setUnChanged (!pedited->colorToning.cl2curve); + lumamode->set_inconsistent (!pedited->colorToning.lumamode); + } + redlow->setValue (pp->colorToning.redlow); + greenlow->setValue (pp->colorToning.greenlow); + bluelow->setValue (pp->colorToning.bluelow); + balance->setValue (pp->colorToning.balance); + redmed->setValue (pp->colorToning.redmed); + greenmed->setValue (pp->colorToning.greenmed); + bluemed->setValue (pp->colorToning.bluemed); + redhigh->setValue (pp->colorToning.redhigh); + greenhigh->setValue (pp->colorToning.greenhigh); + bluehigh->setValue (pp->colorToning.bluehigh); + + setEnabled (pp->colorToning.enabled); + + autosatConn.block (true); + autosat->set_active (pp->colorToning.autosat); + autosatConn.block (false); + lastautosat = pp->colorToning.autosat; + + satProtectionThreshold->setValue (pp->colorToning.satProtectionThreshold); + saturatedOpacity->setValue (pp->colorToning.saturatedOpacity); + hlColSat->setValue (pp->colorToning.hlColSat); + shadowsColSat->setValue (pp->colorToning.shadowsColSat); + strength->setValue (pp->colorToning.strength); + lumamodeConn.block (true); + lumamode->set_active (pp->colorToning.lumamode); + lumamodeConn.block (false); + + lastLumamode = pp->colorToning.lumamode; + + if (pedited && !pedited->colorToning.method) + method->set_active (5); + else if (pp->colorToning.method=="Lab") + method->set_active (0); + else if (pp->colorToning.method=="RGBSliders") + method->set_active (1); + else if (pp->colorToning.method=="RGBCurves") + method->set_active (2); + else if (pp->colorToning.method=="Splitco") + method->set_active (3); + else if (pp->colorToning.method=="Splitlr") + method->set_active (4); + methodChanged(); + methodconn.block(false); + + + if (pedited && !pedited->colorToning.twocolor) + twocolor->set_active (4); + else if (pp->colorToning.twocolor=="Std") + twocolor->set_active (0); + else if (pp->colorToning.twocolor=="All") + twocolor->set_active (1); + else if (pp->colorToning.twocolor=="Separ") + twocolor->set_active (2); + else if (pp->colorToning.twocolor=="Two") + twocolor->set_active (3); + + twocolorChanged(true); + + twocconn.block(false); + + enableListener (); +} + +void ColorToning::write (ProcParams* pp, ParamsEdited* pedited) { + pp->colorToning.redlow = redlow->getValue (); + pp->colorToning.greenlow = greenlow->getValue (); + pp->colorToning.bluelow = bluelow->getValue (); + pp->colorToning.balance = balance->getIntValue (); + pp->colorToning.redmed = redmed->getValue (); + pp->colorToning.greenmed = greenmed->getValue (); + pp->colorToning.bluemed = bluemed->getValue (); + pp->colorToning.redhigh = redhigh->getValue (); + pp->colorToning.greenhigh = greenhigh->getValue (); + pp->colorToning.bluehigh = bluehigh->getValue (); + + pp->colorToning.enabled = getEnabled(); + pp->colorToning.colorCurve = colorShape->getCurve (); + pp->colorToning.opacityCurve = opacityShape->getCurve (); + pp->colorToning.clcurve = clshape->getCurve (); + pp->colorToning.cl2curve = cl2shape->getCurve (); + pp->colorToning.lumamode = lumamode->get_active(); + + pp->colorToning.hlColSat = hlColSat->getValue (); + pp->colorToning.shadowsColSat = shadowsColSat->getValue (); + pp->colorToning.autosat = autosat->get_active(); + pp->colorToning.satProtectionThreshold = satProtectionThreshold->getIntValue(); + pp->colorToning.saturatedOpacity = saturatedOpacity->getIntValue(); + pp->colorToning.strength = strength->getIntValue(); + + if (pedited) { + pedited->colorToning.redlow = redlow->getEditedState (); + pedited->colorToning.greenlow = greenlow->getEditedState (); + pedited->colorToning.bluelow = bluelow->getEditedState (); + pedited->colorToning.balance = balance->getEditedState (); + pedited->colorToning.redmed = redmed->getEditedState (); + pedited->colorToning.greenmed = greenmed->getEditedState (); + pedited->colorToning.bluemed = bluemed->getEditedState (); + pedited->colorToning.redhigh = redhigh->getEditedState (); + pedited->colorToning.greenhigh = greenhigh->getEditedState (); + pedited->colorToning.bluehigh = bluehigh->getEditedState (); + pedited->colorToning.method = method->get_active_text()!=M("GENERAL_UNCHANGED"); + pedited->colorToning.twocolor = twocolor->get_active_text()!=M("GENERAL_UNCHANGED"); + + pedited->colorToning.enabled = !get_inconsistent(); + pedited->colorToning.autosat = !autosat->get_inconsistent(); + pedited->colorToning.colorCurve = !colorShape->isUnChanged (); + pedited->colorToning.opacityCurve = !opacityShape->isUnChanged (); + pedited->colorToning.clcurve = !clshape->isUnChanged (); + pedited->colorToning.cl2curve = !cl2shape->isUnChanged (); + pedited->colorToning.lumamode = !lumamode->get_inconsistent(); + + pedited->colorToning.hlColSat = hlColSat->getEditedState (); + pedited->colorToning.shadowsColSat = shadowsColSat->getEditedState (); + } + + if (method->get_active_row_number()==0) + pp->colorToning.method = "Lab"; + else if (method->get_active_row_number()==1) + pp->colorToning.method = "RGBSliders"; + else if (method->get_active_row_number()==2) + pp->colorToning.method = "RGBCurves"; + else if (method->get_active_row_number()==3) + pp->colorToning.method = "Splitco"; + else if (method->get_active_row_number()==4) + pp->colorToning.method = "Splitlr"; + + if (twocolor->get_active_row_number()==0) + pp->colorToning.twocolor = "Std"; + else if (twocolor->get_active_row_number()==1) + pp->colorToning.twocolor = "All"; + else if (twocolor->get_active_row_number()==2) + pp->colorToning.twocolor = "Separ"; + else if (twocolor->get_active_row_number()==3) + pp->colorToning.twocolor = "Two"; +} + +void ColorToning::lumamodeChanged () { + + if (batchMode) { + if (lumamode->get_inconsistent()) { + lumamode->set_inconsistent (false); + lumamodeConn.block (true); + lumamode->set_active (false); + lumamodeConn.block (false); + } + else if (lastLumamode) + lumamode->set_inconsistent (true); + + lastLumamode = lumamode->get_active (); + } + + if (listener && getEnabled()) { + if (lumamode->get_active ()) + listener->panelChanged (EvColorToningLumamode, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvColorToningLumamode, M("GENERAL_DISABLED")); + } +} + +void ColorToning::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + redlow->setDefault (defParams->colorToning.redlow); + greenlow->setDefault (defParams->colorToning.greenlow); + bluelow->setDefault (defParams->colorToning.bluelow); + balance->setDefault (defParams->colorToning.balance); + redmed->setDefault (defParams->colorToning.redmed); + greenmed->setDefault (defParams->colorToning.greenmed); + bluemed->setDefault (defParams->colorToning.bluemed); + redhigh->setDefault (defParams->colorToning.redhigh); + greenhigh->setDefault (defParams->colorToning.greenhigh); + bluehigh->setDefault (defParams->colorToning.bluehigh); + satProtectionThreshold->setDefault (defParams->colorToning.satProtectionThreshold); + saturatedOpacity->setDefault (defParams->colorToning.saturatedOpacity); + hlColSat->setDefault (defParams->colorToning.hlColSat); + shadowsColSat->setDefault (defParams->colorToning.shadowsColSat); + strength->setDefault (defParams->colorToning.strength); + + if (pedited) { + redlow->setDefaultEditedState (pedited->colorToning.redlow ? Edited : UnEdited); + greenlow->setDefaultEditedState (pedited->colorToning.greenlow ? Edited : UnEdited); + bluelow->setDefaultEditedState (pedited->colorToning.bluelow ? Edited : UnEdited); + balance->setDefaultEditedState (pedited->colorToning.balance ? Edited : UnEdited); + redmed->setDefaultEditedState (pedited->colorToning.redmed ? Edited : UnEdited); + greenmed->setDefaultEditedState (pedited->colorToning.greenmed ? Edited : UnEdited); + bluemed->setDefaultEditedState (pedited->colorToning.bluemed ? Edited : UnEdited); + redhigh->setDefaultEditedState (pedited->colorToning.redhigh ? Edited : UnEdited); + greenhigh->setDefaultEditedState (pedited->colorToning.greenhigh ? Edited : UnEdited); + bluehigh->setDefaultEditedState (pedited->colorToning.bluehigh ? Edited : UnEdited); + satProtectionThreshold->setDefaultEditedState (pedited->colorToning.satprotectionthreshold ? Edited : UnEdited); + saturatedOpacity->setDefaultEditedState (pedited->colorToning.saturatedopacity ? Edited : UnEdited); + hlColSat->setDefaultEditedState (pedited->colorToning.hlColSat ? Edited : UnEdited); + shadowsColSat->setDefaultEditedState (pedited->colorToning.shadowsColSat ? Edited : UnEdited); + strength->setDefaultEditedState (pedited->colorToning.strength ? Edited : UnEdited); + } + else { + redlow->setDefaultEditedState (Irrelevant); + greenlow->setDefaultEditedState (Irrelevant); + bluelow->setDefaultEditedState (Irrelevant); + balance->setDefaultEditedState (Irrelevant); + redmed->setDefaultEditedState (Irrelevant); + greenmed->setDefaultEditedState (Irrelevant); + bluemed->setDefaultEditedState (Irrelevant); + redhigh->setDefaultEditedState (Irrelevant); + greenhigh->setDefaultEditedState (Irrelevant); + bluehigh->setDefaultEditedState (Irrelevant); + satProtectionThreshold->setDefaultEditedState (Irrelevant); + saturatedOpacity->setDefaultEditedState (Irrelevant); + hlColSat->setDefaultEditedState (Irrelevant); + shadowsColSat->setDefaultEditedState (Irrelevant); + strength->setDefaultEditedState (Irrelevant); + } +} + +void ColorToning::setAdjusterBehavior (bool splitAdd, bool satThresholdAdd, bool satOpacityAdd, bool strprotectAdd, bool balanceAdd) { + redlow->setAddMode(splitAdd); + greenlow->setAddMode(splitAdd); + bluelow->setAddMode(splitAdd); + balance->setAddMode(splitAdd); + redmed->setAddMode(splitAdd); + greenmed->setAddMode(splitAdd); + bluemed->setAddMode(splitAdd); + redhigh->setAddMode(splitAdd); + greenhigh->setAddMode(splitAdd); + bluehigh->setAddMode(splitAdd); + satProtectionThreshold->setAddMode(satThresholdAdd); + saturatedOpacity->setAddMode(satOpacityAdd); + balance->setAddMode(balanceAdd); + strength->setAddMode(strprotectAdd); + +} + +void ColorToning::adjusterChanged (ThresholdAdjuster* a, double newBottom, double newTop) { + if (listener && getEnabled()) + listener->panelChanged (a==hlColSat ? EvColorToningHighights : EvColorToningShadows, + Glib::ustring::compose(Glib::ustring(M("TP_COLORTONING_HUE")+": %1"+"\n"+M("TP_COLORTONING_STRENGTH")+": %2"), int(newTop), int(newBottom))); +} + +int CTChanged_UI (void* data) { + GThreadLock lock; + (static_cast(data))->CTComp_ (); + return 0; +} + + +void ColorToning::autoColorTonChanged(int bwct, int satthres, int satprot){ + nextbw = bwct; + nextsatth=satthres; + nextsatpr=satprot; + g_idle_add (CTChanged_UI, this); +} + +bool ColorToning::CTComp_ () { + + disableListener (); + saturatedOpacity->setValue (nextsatpr); + satProtectionThreshold->setValue (nextsatth); +/* if(nextbw==1) { + saturatedOpacity->show(); + satProtectionThreshold->show(); + autosat->show(); + } + else { + saturatedOpacity->hide(); + satProtectionThreshold->hide(); + autosat->hide(); + } +*/ + enableListener (); + + return false; +} + +void ColorToning::adjusterChanged (Adjuster* a, double newval) { + + if (!listener || !getEnabled()) + return; + + if (a==redlow) + listener->panelChanged (EvColorToningredlow, redlow->getTextValue()); + else if (a==greenlow) + listener->panelChanged (EvColorToninggreenlow, greenlow->getTextValue()); + else if (a==bluelow) + listener->panelChanged (EvColorToningbluelow, bluelow->getTextValue()); + else if (a==redmed) + listener->panelChanged (EvColorToningredmed, redmed->getTextValue()); + else if (a==greenmed) + listener->panelChanged (EvColorToninggreenmed, greenmed->getTextValue()); + else if (a==bluemed) + listener->panelChanged (EvColorToningbluemed, bluemed->getTextValue()); + else if (a==redhigh) + listener->panelChanged (EvColorToningredhigh, redhigh->getTextValue()); + else if (a==greenhigh) + listener->panelChanged (EvColorToninggreenhigh, greenhigh->getTextValue()); + else if (a==bluehigh) + listener->panelChanged (EvColorToningbluehigh, bluehigh->getTextValue()); + else if (a==balance) + listener->panelChanged (EvColorToningbalance, balance->getTextValue()); + else if (a==satProtectionThreshold) + listener->panelChanged (EvColorToningSatThreshold, a->getTextValue()); + else if (a==saturatedOpacity) + listener->panelChanged (EvColorToningSatProtection, a->getTextValue()); + else if (a==strength) + listener->panelChanged (EvColorToningStrength, a->getTextValue()); +} + +//Two Color changed +void ColorToning::twocolorChanged (bool changedbymethod) { + if (!batchMode) { + if(method->get_active_row_number()==0) { // Lab + if(twocolor->get_active_row_number()==0) { + colorCurveEditorG->show(); // visible + opacityCurveEditorG->show(); // visible + clCurveEditorG->hide(); + cl2CurveEditorG->hide(); + } + else if(twocolor->get_active_row_number()==1 || twocolor->get_active_row_number()==3) { + colorCurveEditorG->show(); // visible + opacityCurveEditorG->hide(); + clCurveEditorG->show(); // visible + cl2CurveEditorG->hide(); + irg->hide(); + + } + else if(twocolor->get_active_row_number()==2) { + colorCurveEditorG->show(); // visible + opacityCurveEditorG->hide(); + clCurveEditorG->show(); // visible + cl2CurveEditorG->show(); // visible + irg->show(); + } + } + else if(method->get_active_row_number()==1) { // RGB Sliders + colorCurveEditorG->hide(); + opacityCurveEditorG->hide(); + clCurveEditorG->hide(); + cl2CurveEditorG->hide(); + } + else if(method->get_active_row_number()==2) { // RGB Curves + colorCurveEditorG->show(); // visible + opacityCurveEditorG->show(); // visible + clCurveEditorG->hide(); + cl2CurveEditorG->hide(); + } + else if(method->get_active_row_number()==3) { // Split LR + colorCurveEditorG->hide(); + opacityCurveEditorG->hide(); + clCurveEditorG->hide(); + cl2CurveEditorG->hide(); + } + else if(method->get_active_row_number()==4) { // Split color + colorCurveEditorG->hide(); + opacityCurveEditorG->hide(); + clCurveEditorG->hide(); + cl2CurveEditorG->hide(); + } + } + + if (listener && getEnabled() && !changedbymethod) + listener->panelChanged (EvColorToningTwocolor, twocolor->get_active_text ()); +} + +void ColorToning::twoColorChangedByGui() { + twocolorChanged(false); +} + +void ColorToning::methodChanged () { + + if (!batchMode) { + if (method->get_active_row_number()==0) { // Lab + colorSep->show(); + colLabel->hide(); + interLabel->hide(); + colorCurveEditorG->show(); + twocolor->show(); + opacityCurveEditorG->hide(); + clCurveEditorG->hide(); + cl2CurveEditorG->hide(); + //neutralCurves->show(); + hlColSat->hide(); + shadowsColSat->hide(); + balance->hide(); +// satLimiterSep->show(); + if(autosat->get_active()) { + saturatedOpacity->set_sensitive(false); + satProtectionThreshold->set_sensitive(false); + satProtectionThreshold->show(); + saturatedOpacity->show(); + } + else { + satProtectionThreshold->show(); + saturatedOpacity->show(); + saturatedOpacity->set_sensitive(true); + satProtectionThreshold->set_sensitive(true); + } + autosat->show(); + p1Frame->show(); + + strength->hide(); + chanMixerBox->hide(); + neutrHBox->hide(); + lumamode->hide(); + //splitSep->hide(); + //satlow->hide(); + //sathigh->hide(); + + twocolorChanged(true); + } + else if (method->get_active_row_number()==1) { // RGB Sliders + colorSep->hide(); + colLabel->hide(); + interLabel->hide(); + colorCurveEditorG->hide(); + twocolor->hide(); + twocolor->set_active (false); + opacityCurveEditorG->hide(); + clCurveEditorG->hide(); + cl2CurveEditorG->hide(); + //neutralCurves->hide(); + hlColSat->show(); + shadowsColSat->show(); + balance->show(); +// satLimiterSep->show(); + autosat->show(); + p1Frame->show(); + if(autosat->get_active()) { + saturatedOpacity->set_sensitive(false); + satProtectionThreshold->set_sensitive(false); + satProtectionThreshold->show(); + saturatedOpacity->show(); + } + else { + satProtectionThreshold->show(); + saturatedOpacity->show(); + saturatedOpacity->set_sensitive(true); + satProtectionThreshold->set_sensitive(true); + } + + strength->hide(); + chanMixerBox->hide(); + neutrHBox->hide(); + lumamode->hide(); + + } + else if (method->get_active_row_number()==2) { // RGB Curves + colorSep->hide(); + colLabel->hide(); + interLabel->hide(); + colorCurveEditorG->show(); + twocolor->hide(); + twocolor->set_active (false); + opacityCurveEditorG->show(); + clCurveEditorG->hide(); + cl2CurveEditorG->hide(); + //neutralCurves->show(); + hlColSat->hide(); + shadowsColSat->hide(); + balance->hide(); +// satLimiterSep->show(); + p1Frame->show(); + + autosat->show(); + if(autosat->get_active()) { + saturatedOpacity->set_sensitive(false); + satProtectionThreshold->set_sensitive(false); + satProtectionThreshold->show(); + saturatedOpacity->show(); + } + else { + satProtectionThreshold->show(); + saturatedOpacity->show(); + saturatedOpacity->set_sensitive(true); + satProtectionThreshold->set_sensitive(true); + } + strength->hide(); + chanMixerBox->hide(); + neutrHBox->hide(); + lumamode->hide(); + } + else if (method->get_active_row_number()==3) { // Split LR + colorSep->hide(); + colLabel->hide(); + interLabel->hide(); + colorCurveEditorG->hide(); + twocolor->hide(); + twocolor->set_active (false); + opacityCurveEditorG->hide(); + clCurveEditorG->hide(); + cl2CurveEditorG->hide(); + //neutralCurves->hide(); + hlColSat->hide(); + shadowsColSat->hide(); + balance->hide(); + p1Frame->hide(); + +// satLimiterSep->hide(); + autosat->hide(); + satProtectionThreshold->hide(); + saturatedOpacity->hide(); + strength->show(); + chanMixerBox->show(); + neutrHBox->show(); + lumamode->show(); + } + else if (method->get_active_row_number()==4) { // Split Color + colorSep->show(); + colLabel->hide(); + interLabel->hide(); + colorCurveEditorG->hide(); + twocolor->hide(); + opacityCurveEditorG->hide(); + clCurveEditorG->hide(); + cl2CurveEditorG->hide(); + //neutralCurves->hide(); + hlColSat->show(); + shadowsColSat->show(); + balance->show(); +// satLimiterSep->hide(); + p1Frame->hide(); + + autosat->hide(); + satProtectionThreshold->hide(); + saturatedOpacity->hide(); + strength->show(); + + chanMixerBox->hide(); + neutrHBox->hide(); + lumamode->show(); + } + } + + if (listener && getEnabled()) + listener->panelChanged (EvColorToningMethod, method->get_active_text ()); +} + + +void ColorToning::autoOpenCurve () { + colorShape->openIfNonlinear(); + opacityShape->openIfNonlinear(); + clshape->openIfNonlinear(); + cl2shape->openIfNonlinear(); +} + +void ColorToning::colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller *caller) { + + float R, G, B; + if (callerId == 1) { // ch - main curve + Color::hsv2rgb01(float(valY), 1.0f, 0.5f, R, G, B); + } + else if (callerId == 2) { // Slider 1 background + if (valY > 0.5) + // the hue range + Color::hsv2rgb01(float(valX), 1.0f, 0.5f, R, G, B); + else { + // the strength applied to the current hue + double strength, hue; + float r_, g_, b_; + hlColSat->getValue(strength, hue); + Color::hsv2rgb01(valY*2.f, 1.f, 1.f, r_, g_, b_); + Color::hsv2rgb01(hue/360.f, 1.f, 1.f, R, G, B); + R = r_+(R-r_)*valX; + G = g_+(G-g_)*valX; + B = b_+(B-b_)*valX; + } + } + else if (callerId == 3) { // Slider 2 background + if (valY > 0.5) + // the hue range + Color::hsv2rgb01(float(valX), 1.0f, 0.5f, R, G, B); + else { + // the strength applied to the current hue + double strength, hue; + float r_, g_, b_; + shadowsColSat->getValue(strength, hue); + Color::hsv2rgb01(valY*2.f, 1.f, 1.f, r_, g_, b_); + Color::hsv2rgb01(hue/360.f, 1.f, 1.f, R, G, B); + R = r_+(R-r_)*valX; + G = g_+(G-g_)*valX; + B = b_+(B-b_)*valX; + } + } + caller->ccRed = double(R); + caller->ccGreen = double(G); + caller->ccBlue = double(B); +} + +void ColorToning::curveChanged (CurveEditor* ce) { + + if (listener && getEnabled()) { + if (ce == colorShape) + listener->panelChanged (EvColorToningColor, M("HISTORY_CUSTOMCURVE")); + else if (ce == opacityShape) + listener->panelChanged (EvColorToningOpacity, M("HISTORY_CUSTOMCURVE")); + else if (ce == clshape) + listener->panelChanged (EvColorToningCLCurve, M("HISTORY_CUSTOMCURVE")); + else if (ce == cl2shape) + listener->panelChanged (EvColorToningLLCurve, M("HISTORY_CUSTOMCURVE")); + } +} + +void ColorToning::enabledChanged () { + + if (listener) { + if (get_inconsistent()) + listener->panelChanged (EvColorToningEnabled, M("GENERAL_UNCHANGED")); + else if (getEnabled()) + listener->panelChanged (EvColorToningEnabled, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvColorToningEnabled, M("GENERAL_DISABLED")); + } +} + +void ColorToning::autosatChanged () { + + if (batchMode) { + if (autosat->get_inconsistent()) { + autosat->set_inconsistent (false); + autosatConn.block (true); + autosat->set_active (false); + autosatConn.block (false); + } + else if (lastautosat) + autosat->set_inconsistent (true); + + lastautosat = autosat->get_active (); + } + if (listener) { + if (autosat->get_active()) { + if (getEnabled()) + listener->panelChanged (EvColorToningautosat, M("GENERAL_ENABLED")); + saturatedOpacity->set_sensitive(false); + satProtectionThreshold->set_sensitive(false); + } + else { + if (getEnabled()) + listener->panelChanged (EvColorToningautosat, M("GENERAL_DISABLED")); + saturatedOpacity->set_sensitive(true); + satProtectionThreshold->set_sensitive(true); + } + + } +} + +void ColorToning::trimValues (rtengine::procparams::ProcParams* pp) { + + redlow->trimValue(pp->colorToning.redlow); + greenlow->trimValue(pp->colorToning.greenlow); + bluelow->trimValue(pp->colorToning.bluelow); + balance->trimValue(pp->colorToning.balance); + redmed->trimValue(pp->colorToning.redmed); + greenmed->trimValue(pp->colorToning.greenmed); + bluemed->trimValue(pp->colorToning.bluemed); + redhigh->trimValue(pp->colorToning.redhigh); + greenhigh->trimValue(pp->colorToning.greenhigh); + bluehigh->trimValue(pp->colorToning.bluehigh); +} + +void ColorToning::setBatchMode (bool batchMode) +{ + ToolPanel::setBatchMode (batchMode); + method->append_text (M("GENERAL_UNCHANGED")); + twocolor->append_text (M("GENERAL_UNCHANGED")); + hlColSat->showEditedCB (); + shadowsColSat->showEditedCB (); + redlow->showEditedCB (); + greenlow->showEditedCB (); + bluelow->showEditedCB (); + balance->showEditedCB (); + redmed->showEditedCB (); + greenmed->showEditedCB (); + bluemed->showEditedCB (); + redhigh->showEditedCB (); + greenhigh->showEditedCB (); + bluehigh->showEditedCB (); + + colorCurveEditorG->setBatchMode (batchMode); + opacityCurveEditorG->setBatchMode (batchMode); + clCurveEditorG->setBatchMode (batchMode); + cl2CurveEditorG->setBatchMode (batchMode); + +} diff --git a/rtgui/colortoning.h b/rtgui/colortoning.h new file mode 100644 index 000000000..b15597d06 --- /dev/null +++ b/rtgui/colortoning.h @@ -0,0 +1,107 @@ +/* + * This file is part of RawTherapee. + */ +#ifndef _COLORTONING_H_ +#define _COLORTONING_H_ + +#include +#include "adjuster.h" +#include "toolpanel.h" +#include "guiutils.h" +#include "curveeditor.h" +#include "curveeditorgroup.h" +#include "thresholdadjuster.h" +#include "colorprovider.h" + +class ColorToning : public ToolParamBlock, public FoldableToolPanel, public rtengine::AutoColorTonListener,public CurveListener, public ColorProvider, + public ThresholdAdjusterListener, public AdjusterListener { + + protected: + //Gtk::HSeparator* splitSep; + Gtk::HSeparator* satLimiterSep; + Gtk::HSeparator* colorSep; + CurveEditorGroup* colorCurveEditorG; + CurveEditorGroup* opacityCurveEditorG; + CurveEditorGroup* clCurveEditorG; + CurveEditorGroup* cl2CurveEditorG; + FlatCurveEditor* opacityShape; + FlatCurveEditor* colorShape; + DiagonalCurveEditor* clshape; + DiagonalCurveEditor* cl2shape; + Gtk::HBox* ctbox; + Gtk::Frame *p1Frame; + + Gtk::VBox* chanMixerBox; + MyComboBoxText* method; + sigc::connection methodconn; + MyComboBoxText* twocolor; + Adjuster* redlow; + Adjuster* greenlow; + Adjuster* bluelow; + Adjuster* redmed; + Adjuster* greenmed; + Adjuster* bluemed; + Adjuster* redhigh; + Adjuster* greenhigh; + Adjuster* bluehigh; + Adjuster* balance; + Gtk::CheckButton* autosat; + ThresholdAdjuster* shadowsColSat; + ThresholdAdjuster* hlColSat; + Adjuster* satProtectionThreshold; + Adjuster* saturatedOpacity; + Adjuster* strength; + Gtk::Image* itot; + Gtk::Image* iby; + Gtk::Image* irg; + + Gtk::Button* neutral; + //Gtk::Button* neutralCurves; + Gtk::HBox* neutrHBox; + Gtk::HBox* chromaHbox; + Gtk::Label* colLabel; + Gtk::Label* interLabel; + Gtk::Label* chroLabel; + int nextbw; + int nextsatth; + int nextsatpr; + Glib::ustring nextbalcolor; + Glib::ustring balcolor; + bool lasttwocolor; + sigc::connection neutralconn, twocconn; //, neutralcurvesconn; + bool lastautosat; + sigc::connection autosatConn; + + Gtk::CheckButton* lumamode; + bool lastLumamode; + sigc::connection lumamodeConn; + + public: + ColorToning (); + ~ColorToning(); + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void trimValues (rtengine::procparams::ProcParams* pp); + void adjusterChanged (Adjuster* a, double newval); + void adjusterChanged (ThresholdAdjuster* a, double newBottom, double newTop); + void setAdjusterBehavior (bool splitAdd, bool satThresholdAdd, bool satOpacityAdd, bool strprotectAdd, bool balanceAdd); + void neutral_pressed (); + //void neutralCurves_pressed (); + void autoColorTonChanged (int bwct, int satthres, int satprot); + bool CTComp_ (); + + void enabledChanged (); + void curveChanged (CurveEditor* ce); + void autosatChanged (); + void autoOpenCurve (); + void methodChanged (); + void twocolorChanged (bool changedbymethod); + void twoColorChangedByGui (); + void lumamodeChanged (); + + void colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller* caller); +}; + +#endif diff --git a/rtgui/config.h.in b/rtgui/config.h.in new file mode 100644 index 000000000..cab481278 --- /dev/null +++ b/rtgui/config.h.in @@ -0,0 +1,29 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2010 Lukas Jirkovsky + * + * 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 __CONFIG_H__ +#define __CONFIG_H__ + +#cmakedefine BUILD_BUNDLE +#define DATA_SEARCH_PATH "${DATADIR}" +#define DOC_SEARCH_PATH "${DOCDIR}" +#define CREDITS_SEARCH_PATH "${CREDITSDIR}" +#define LICENCE_SEARCH_PATH "${LICENCEDIR}" + +#endif diff --git a/rtgui/coord.h b/rtgui/coord.h new file mode 100644 index 000000000..91fc40562 --- /dev/null +++ b/rtgui/coord.h @@ -0,0 +1,163 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _COORD_H_ +#define _COORD_H_ + +class PolarCoord; + +// Do not confuse with rtengine::Coord2D, Coord is for the GUI +class Coord { +public: + int x; + int y; + + Coord() : x(-1), y(-1) {} + Coord(int x, int y) : x(x), y(y) {} + + void set (int x, int y) { + this->x = x; + this->y = y; + } + + void setFromPolar(PolarCoord polar); + + /// @brief Clip the coord to stay in the width x height bounds + /// @return true if the x or y coordinate has changed + bool clip(int width, int height) { + int trimmedX = rtengine::LIM(x, 0, width); + int trimmedY = rtengine::LIM(y, 0, height); + bool retval = trimmedX!=x || trimmedY!=y; + x = trimmedX; + y = trimmedY; + return retval; + } + + void operator+=(const Coord & rhs) { + x += rhs.x; + y += rhs.y; + } + void operator-=(const Coord & rhs) { + x -= rhs.x; + y -= rhs.y; + } + void operator*=(double scale) { + x *= scale; + y *= scale; + } + Coord operator+(Coord & rhs) { + Coord result(x+rhs.x, y+rhs.y); + return result; + } + Coord operator-(Coord & rhs) { + Coord result(x-rhs.x, y-rhs.y); + return result; + } + Coord operator*(double scale) { + Coord result(x*scale, y*scale); + return result; + } +}; + +class PolarCoord { +public: + double radius; + double angle; // degree + + PolarCoord() : radius(1.), angle(0.) {} + PolarCoord(double radius, double angle) : radius(radius), angle(angle) {} + + void set (double radius, double angle) { + this->radius = radius; + this->angle = angle; + } + + void setFromCartesian(Coord start, Coord end) { + Coord delta(end.x-start.x, end.y-start.y); + setFromCartesian(delta); + } + + void setFromCartesian(Coord delta) { + if (!delta.x && !delta.y) { + // null vector, we set to a default value + radius = 1.; + angle = 0.; + return; + } + double x_ = double(delta.x); + double y_ = double(delta.y); + radius = sqrt(x_*x_+y_*y_); + if (delta.x>0.) { + if (delta.y>=0.) + angle = atan(y_/x_)/(2*M_PI)*360.; + else if (delta.y<0.) + angle = (atan(y_/x_)+2*M_PI)/(2*M_PI)*360.; + } + else if (delta.x<0.) + angle = (atan(y_/x_)+M_PI)/(2*M_PI)*360.; + else if (delta.x==0.) { + if (delta.y>0.) + angle = 90.; + else + angle = 270.; + } + } + + void operator+=(const PolarCoord & rhs) { + Coord thisCoord, rhsCoord; + thisCoord.setFromPolar(*this); + rhsCoord.setFromPolar(rhs); + thisCoord += rhsCoord; + setFromCartesian(thisCoord); + } + void operator-=(const PolarCoord & rhs) { + Coord thisCoord, rhsCoord; + thisCoord.setFromPolar(*this); + rhsCoord.setFromPolar(rhs); + thisCoord -= rhsCoord; + setFromCartesian(thisCoord); + } + void operator*=(double scale) { + radius *= scale; + } + PolarCoord operator+(PolarCoord & rhs) { + Coord thisCoord, rhsCoord; + thisCoord.setFromPolar(*this); + rhsCoord.setFromPolar(rhs); + thisCoord += rhsCoord; + PolarCoord result; + result.setFromCartesian(thisCoord); + return result; + } + PolarCoord operator-(PolarCoord & rhs) { + Coord thisCoord, rhsCoord; + thisCoord.setFromPolar(*this); + rhsCoord.setFromPolar(rhs); + thisCoord -= rhsCoord; + PolarCoord result; + result.setFromCartesian(thisCoord); + return result; + } + Coord operator*(double scale) { + Coord result(radius*scale, angle); + return result; + } + +}; + +#endif diff --git a/rtgui/coordinateadjuster.cc b/rtgui/coordinateadjuster.cc new file mode 100644 index 000000000..35bbe51e0 --- /dev/null +++ b/rtgui/coordinateadjuster.cc @@ -0,0 +1,198 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "coordinateadjuster.h" +#include "multilangmgr.h" +#include +#include "curveeditorgroup.h" + +Axis::Axis() + : label(""), decimal(5), increment(0.001), pageIncrement(0.01), rangeLowerBound(0.), rangeUpperBound(1.) +{} + +Axis::Axis(Glib::ustring label, unsigned int decimal, double increment, double pageIncrement, double valMin=0.0, double valMax=1.0) + : label(label), decimal(decimal), increment(increment), pageIncrement(pageIncrement), rangeLowerBound(valMin), rangeUpperBound(valMax) +{} + +void Axis::setValues(Glib::ustring label, unsigned int decimal, double increment, double pageIncrement, double valMin, double valMax) { + this->label = label; + this->decimal = decimal; + this->increment = increment; + this->pageIncrement = pageIncrement; + this->rangeLowerBound = valMin; + this->rangeUpperBound = valMax; +} + +CoordinateAdjuster::AxisAdjuster::AxisAdjuster(CoordinateAdjuster *parent, const Axis *axis, char index) : idx(index), parent(parent) { + label = Gtk::manage( new Gtk::Label(axis->label) ); + spinButton = Gtk::manage( new Gtk::SpinButton() ); + + label = Gtk::manage (new Gtk::Label(axis->label)); + //label->set_alignment(Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); + + spinButton = Gtk::manage (new Gtk::SpinButton()); + spinButton->set_name("AxisAdjuster"); + spinButton->set_digits(axis->decimal); + spinButton->set_increments(axis->increment, axis->pageIncrement); + spinButton->set_range(axis->rangeLowerBound, axis->rangeUpperBound); + spinButton->set_sensitive(false); + spinButtonConn = spinButton->signal_value_changed().connect( sigc::mem_fun(*this, &CoordinateAdjuster::AxisAdjuster::valueChanged) ); + //spinButton->signal_key_press_event().connect( sigc::mem_fun(*this, &CoordinateAdjuster::AxisAdjuster::keyPressed) ); +} + +void CoordinateAdjuster::AxisAdjuster::updateGUI(const Axis &axis) { + label->set_text(axis.label); + spinButton->set_digits(axis.decimal); + spinButton->set_increments(axis.increment, axis.pageIncrement); + spinButton->set_range(axis.rangeLowerBound, axis.rangeUpperBound); + spinButton->set_sensitive(false); + rangeLowerBound = axis.rangeLowerBound; + rangeUpperBound = axis.rangeUpperBound; +} + +void CoordinateAdjuster::AxisAdjuster::setValue(double newValue) { + float range = rangeUpperBound-rangeLowerBound; + spinButtonConn.block(true); + spinButton->set_value(newValue*range+rangeLowerBound); + spinButtonConn.block(false); +} + +void CoordinateAdjuster::AxisAdjuster::valueChanged() { + float range = rangeUpperBound-rangeLowerBound; + parent->updatePos(idx, (spinButton->get_value()-rangeLowerBound)/range); +} + +CoordinateAdjuster::CoordinateAdjuster(CoordinateProvider *provider, CurveEditorSubGroup *parent, const std::vector &axis) + : status(CA_STATUS_IDLE), parent(parent), coordinateProvider(provider) +{ + provider->setListener(this); + createWidgets(axis); +} + +CoordinateAdjuster::CoordinateAdjuster(CoordinateProvider *provider, CurveEditorSubGroup *parent) + : status(CA_STATUS_IDLE), parent(parent), coordinateProvider(provider) +{ + std::vector defaultAxis; + Axis X(M("CURVEEDITOR_AXIS_IN"), 3, 0.1, 1., 0., 100.); + Axis Y(M("CURVEEDITOR_AXIS_OUT"), 3, 0.1, 1., 0., 100.); + defaultAxis.push_back(X); + defaultAxis.push_back(Y); + + provider->setListener(this); + createWidgets(defaultAxis); +} + +void CoordinateAdjuster::createWidgets(const std::vector &axis) { + unsigned int count = axis.size(); + if (!count) { + printf("CoordinateAdjuster - Error: the Axis list is empty!\n"); + return; + } + assert (count <= 4); + + axisAdjusters.resize(axis.size()); + + set_spacing(3); + + AxisAdjuster *currAdjuster = NULL; + + for (unsigned int i=0; irangeLowerBound = currAxis->rangeLowerBound; + currAdjuster->rangeUpperBound = currAxis->rangeUpperBound; + + pack_start(*(currAdjuster->label), Gtk::PACK_SHRINK, 0); + pack_start(*(currAdjuster->spinButton), Gtk::PACK_SHRINK, 0); + } +} + +void CoordinateAdjuster::updatePos(char index, double value) { + coordinateProvider->setPos(value, index); +} + +void CoordinateAdjuster::setAxis(const std::vector &axis) { + assert (axis.size() == axisAdjusters.size()); + for (size_t i = 0; iupdateGUI(axis.at(i)); + } +} + +void CoordinateAdjuster::setPos(std::vector &pos) { + if (is_visible()) { + for (size_t i=0; isetValue(pos.at(i)); + } + } +} + +void CoordinateAdjuster::startNumericalAdjustment(const std::vector &newBoundaries) { + for (size_t i=0; ispinButton; + currSpinButton->set_sensitive(true); + float range = axisAdjusters.at(i)->rangeUpperBound-axisAdjusters.at(i)->rangeLowerBound; + currSpinButton->set_range(newBoundaries.at(i).minVal*range+axisAdjusters.at(i)->rangeLowerBound, newBoundaries.at(i).maxVal*range+axisAdjusters.at(i)->rangeUpperBound); + } + axisAdjusters.at(0)->spinButton->grab_focus(); + status = CA_STATUS_EDITING; +} + +void CoordinateAdjuster::switchAdjustedPoint(std::vector &pos, const std::vector &newBoundaries) { + if (status != CA_STATUS_EDITING) + return; + + for (size_t i=0; ispinButtonConn.block(true); + + // To avoid trimmed values, we have to... + + // ...enlarge range to the maximum + currAxis->spinButton->set_range(axisAdjusters.at(i)->rangeLowerBound, axisAdjusters.at(i)->rangeUpperBound); + + // ...set the new value + currAxis->setValue(pos.at(i)); + + // ...narrow the range to the new interval + float range = axisAdjusters.at(i)->rangeUpperBound-axisAdjusters.at(i)->rangeLowerBound; + currAxis->spinButton->set_range(newBoundaries.at(i).minVal*range+axisAdjusters.at(i)->rangeLowerBound, newBoundaries.at(i).maxVal*range+axisAdjusters.at(i)->rangeUpperBound); + + // enable events + currAxis->spinButtonConn.block(false); + } + axisAdjusters.at(0)->spinButton->grab_focus(); + status = CA_STATUS_EDITING; +} + +void CoordinateAdjuster::showMe(CoordinateProvider *provider) { + parent->showCoordinateAdjuster(provider); +} + +void CoordinateAdjuster::stopNumericalAdjustment() { + for (size_t i=0; ispinButtonConn.block(true); + axisAdjusters.at(i)->spinButton->set_sensitive(false); + axisAdjusters.at(i)->spinButton->set_range(axisAdjusters.at(i)->rangeLowerBound, axisAdjusters.at(i)->rangeUpperBound); + axisAdjusters.at(i)->spinButtonConn.block(false); + } + status = CA_STATUS_IDLE; +} diff --git a/rtgui/coordinateadjuster.h b/rtgui/coordinateadjuster.h new file mode 100644 index 000000000..3c4dbc38f --- /dev/null +++ b/rtgui/coordinateadjuster.h @@ -0,0 +1,157 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _COORDINATEADJUSTER_ +#define _COORDINATEADJUSTER_ + +#include + +class CurveEditorSubGroup; + +class Axis { +public: + Glib::ustring label; + unsigned int decimal; + double increment; + double pageIncrement; + double rangeLowerBound; + double rangeUpperBound; + + Axis(); + Axis(Glib::ustring label, unsigned int decimal, double increment, double pageIncrement, double valMin, double valMax); + void setValues(Glib::ustring label, unsigned int decimal, double increment, double pageIncrement, double valMin, double valMax); +}; + +class CoordinateAdjuster; +/** + * @brief Object that will emit NewCoordinates events + */ +class CoordinateProvider { +protected: + CoordinateAdjuster *coordinateAdjuster; +public: + CoordinateProvider() : coordinateAdjuster(NULL) {} + virtual ~CoordinateProvider() {} + void setListener(CoordinateAdjuster *adjuster) { coordinateAdjuster = adjuster; } + + /** @brief Update the position of the edited point ; will trigger events + * + * @param pos New position + * @param chanIdx Chanel index as given in the std::vector upon instantiation + */ + virtual void setPos(double pos, int chanIdx)=0; + virtual void stopNumericalAdjustment()=0; +}; + +/** + * @brief Widget that displays spin buttons to adjust coordinates + * + * You can set up to 4 axis that will be displayed on a single line, so keep the labels short! + * + * The position of the Axis in the vector will be used in the communication between the Adjuster and the Provider to identify the Axis + */ +class CoordinateAdjuster : public Gtk::HBox { + +public: + //-------------------------------- AxisAdjuster ------------------- + class AxisAdjuster { + private: + char idx; + public: + CoordinateAdjuster *parent; + Gtk::Label *label; + Gtk::SpinButton *spinButton; + sigc::connection spinButtonConn; + float rangeLowerBound; + float rangeUpperBound; + + AxisAdjuster(CoordinateAdjuster *parent, const Axis *axis, char index); + + // used to update the AxisAdjuster's parameters + void updateGUI(const Axis &axis); + // useed to update the displayed value + void setValue(double newValue); + //bool keyPressed(GdkEventKey* event); + void valueChanged(); + }; + //---------------------------------------------------------------- + + //-------------------------------- Boundaries ------------------- + class Boundaries { + public: + double minVal; + double maxVal; + }; + //--------------------------------------------------------------- + +private: + typedef enum { + CA_STATUS_IDLE, + CA_STATUS_EDITING, + CA_STATUS_END_EDITING + } Status; + + std::vector axisAdjusters; + Status status; + CurveEditorSubGroup *parent; + + void createWidgets(const std::vector &axis); + +protected: + + friend class AxisAdjuster; + + CoordinateProvider *coordinateProvider; + + void updatePos(char index, double value); + + +public: + + /// Basic X/Y adjuster, in the [0-1] range + CoordinateAdjuster(CoordinateProvider *provider, CurveEditorSubGroup *parent); + /// For more complex adjuster + CoordinateAdjuster(CoordinateProvider *provider, CurveEditorSubGroup *parent, const std::vector &axis); + + virtual ~CoordinateAdjuster() {} + + // Update the Axis list, e.g. on Curve change, but MUST have the same axis count + void setAxis(const std::vector &axis); + + /** @brief Update the numbers in the spin buttons ; doesn't trigger any event + * + * @param pos Vector that gives the values of each channels + */ + void setPos(std::vector &pos); + + /// Start the adjustment session (enable the widget) + void startNumericalAdjustment(const std::vector &newBoundaries); + + /// Edit another point + void switchAdjustedPoint(std::vector &pos, const std::vector &newBoundaries); + + /// Trigger the event to show the CoordinateAdjuster + void showMe(CoordinateProvider *provider); + + /// Stop the adjustment session (disable the widget, i.e. you won't be able to edit the values) + void stopNumericalAdjustment(); + +}; + + +#endif diff --git a/rtgui/createicon.cc b/rtgui/createicon.cc new file mode 100644 index 000000000..485b33027 --- /dev/null +++ b/rtgui/createicon.cc @@ -0,0 +1,200 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 + +void png_read_data(png_structp png_ptr, png_bytep data, png_size_t length) { + png_size_t check; + + /* fread() returns 0 on error, so it is OK to store this in a png_size_t + * instead of an int, which is what fread() actually returns. + */ + check = (png_size_t)fread(data, (png_size_t)1, length, (FILE *)png_ptr->io_ptr); + + if (check != length) + { + png_error(png_ptr, "Read Error"); + } +} + +void png_write_data(png_structp png_ptr, png_bytep data, png_size_t length) { + png_uint_32 check; + + check = fwrite(data, 1, length, (FILE *)(png_ptr->io_ptr)); + if (check != length) + { + png_error(png_ptr, "Write Error"); + } +} + +void png_flush(png_structp png_ptr) { + FILE *io_ptr; + io_ptr = (FILE *)CVT_PTR((png_ptr->io_ptr)); + if (io_ptr != NULL) + fflush(io_ptr); +} + + +unsigned char* loadPNG (char* fname, int& w, int& h) { + + FILE *file = fopen (fname,"rb"); + + unsigned char header[8]; + fread (header, 1, 8, file); + + png_structp png = png_create_read_struct (PNG_LIBPNG_VER_STRING, 0, 0, 0); + png_infop info = png_create_info_struct (png); + png_infop end_info = png_create_info_struct (png); + if (setjmp (png_jmpbuf(png))) { + png_destroy_read_struct (&png, &info, &end_info); + fclose (file); + return NULL; + } + //set up png read + png_set_read_fn (png, file, png_read_data); + png_set_sig_bytes (png,8); + + png_read_info(png,info); + + unsigned long width,height; + int bit_depth,color_type,interlace_type,compression_type,filter_method; + png_get_IHDR(png,info,&width,&height,&bit_depth,&color_type,&interlace_type, + &compression_type, &filter_method); + + //converting to 32bpp format + if (color_type==PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png); + + if (color_type==PNG_COLOR_TYPE_GRAY || color_type==PNG_COLOR_TYPE_GRAY_ALPHA) + png_set_gray_to_rgb(png); + + if (png_get_valid(png,info,PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png); + + if (interlace_type!=PNG_INTERLACE_NONE) { + png_destroy_read_struct (&png, &info, &end_info); + fclose (file); + return NULL; + } + + if (color_type & PNG_COLOR_MASK_ALPHA) + png_set_strip_alpha(png); + + //setting gamma + double gamma; + if (png_get_gAMA(png,info,&gamma)) + png_set_gamma(png, 2.0, gamma); + else + png_set_gamma(png,2.0, 0.45455); + + int bps = 8; + + //updating png info struct + png_read_update_info(png,info); + png_get_IHDR(png,info,&width,&height,&bit_depth,&color_type,&interlace_type, + &compression_type, &filter_method); + + if (color_type & PNG_COLOR_MASK_ALPHA) + png_set_strip_alpha(png); + + png_read_update_info(png,info); + png_get_IHDR(png,info,&width,&height,&bit_depth,&color_type,&interlace_type, + &compression_type, &filter_method); + + + unsigned char* data = new unsigned char[width*height*3]; + int rowlen = width*3; + unsigned char *row = new unsigned char [rowlen]; + + for (unsigned int i=0;i + * + * 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 "crop.h" +#include "options.h" +#include "rtimage.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +extern Options options; + +class RefreshSpinHelper { + + public: + Crop* crop; + bool notify; + RefreshSpinHelper (Crop* _crop, bool _notify) + : crop(_crop), notify(_notify) {} +}; + +Crop::Crop (): FoldableToolPanel(this, "crop", M("TP_CROP_LABEL"), false, true) { + + clistener = NULL; + + maxw = 3000; + maxh = 2000; + + Gtk::HBox* hb1 = Gtk::manage (new Gtk::HBox ()); + + hb1->pack_start (*Gtk::manage (new Gtk::Label (Glib::ustring(" ") + M("TP_CROP_X") +": "))); + x = Gtk::manage (new MySpinButton ()); + x->set_size_request (60, -1); + hb1->pack_start (*x); + + hb1->pack_start (*Gtk::manage (new Gtk::Label (Glib::ustring(" ") + M("TP_CROP_Y") + ": "))); + y = Gtk::manage (new MySpinButton ()); + y->set_size_request (60, -1); + hb1->pack_start (*y); + + pack_start (*hb1, Gtk::PACK_SHRINK, 2); + + Gtk::HBox* hb2 = Gtk::manage (new Gtk::HBox ()); + + hb2->pack_start (*Gtk::manage (new Gtk::Label (M("TP_CROP_W") + ": "))); + w = Gtk::manage (new MySpinButton ()); + w->set_size_request (60, -1); + hb2->pack_start (*w); + + hb2->pack_start (*Gtk::manage (new Gtk::Label (M("TP_CROP_H") + ": "))); + h = Gtk::manage (new MySpinButton ()); + h->set_size_request (60, -1); + hb2->pack_start (*h); + + pack_start (*hb2, Gtk::PACK_SHRINK, 4); + + selectCrop = Gtk::manage (new Gtk::Button (M("TP_CROP_SELECTCROP"))); + selectCrop->set_image (*Gtk::manage (new RTImage ("crop.png"))); + + pack_start (*selectCrop, Gtk::PACK_SHRINK, 2); + + Gtk::HBox* hb3 = Gtk::manage (new Gtk::HBox ()); + + fixr = Gtk::manage (new Gtk::CheckButton (M("TP_CROP_FIXRATIO"))); + fixr->set_active (1); + + hb3->pack_start (*fixr, Gtk::PACK_SHRINK, 4); + + ratio = Gtk::manage (new MyComboBoxText ()); + hb3->pack_start (*ratio, Gtk::PACK_EXPAND_WIDGET, 4); + + orientation = Gtk::manage (new MyComboBoxText ()); + hb3->pack_start (*orientation); + + pack_start (*hb3, Gtk::PACK_SHRINK, 4); + + Gtk::HBox* hb31 = Gtk::manage (new Gtk::HBox ()); + + hb31->pack_start (*Gtk::manage (new Gtk::Label (M("TP_CROP_GUIDETYPE"))), Gtk::PACK_SHRINK, 4); + guide = Gtk::manage (new MyComboBoxText ()); + hb31->pack_start (*guide); + + pack_start (*hb31, Gtk::PACK_SHRINK, 4); + + // ppibox START + ppibox = Gtk::manage (new Gtk::VBox()); + ppibox->pack_start (*Gtk::manage (new Gtk::HSeparator()), Gtk::PACK_SHRINK, 2); + + Gtk::HBox* hb4 = Gtk::manage (new Gtk::HBox ()); + hb4->pack_start (*Gtk::manage (new Gtk::Label (M("TP_CROP_PPI")))); + ppi = Gtk::manage (new MySpinButton ()); + ppi->set_size_request (60, -1); + hb4->pack_start (*ppi); + + sizebox = Gtk::manage (new Gtk::VBox()); + + sizecm = Gtk::manage (new Gtk::Label (M("GENERAL_NA") + " cm x " + M("GENERAL_NA") + " cm")); + sizein = Gtk::manage (new Gtk::Label (M("GENERAL_NA") + " in x " + M("GENERAL_NA") + " in")); + + sizebox->pack_start (*sizecm, Gtk::PACK_SHRINK, 4); + sizebox->pack_start (*Gtk::manage (new Gtk::HSeparator()), Gtk::PACK_SHRINK, 6); + sizebox->pack_start (*sizein, Gtk::PACK_SHRINK, 4); + sizebox->pack_start (*Gtk::manage (new Gtk::HSeparator()), Gtk::PACK_SHRINK, 6); + sizebox->pack_start (*hb4, Gtk::PACK_SHRINK, 2); + + ppibox->pack_start (*sizebox, Gtk::PACK_SHRINK, 1); + pack_start (*ppibox, Gtk::PACK_SHRINK, 0); + + 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; iappend_text (cropratio[i].label); + } + + ratio->set_active (0); + + orientation->append_text (M("GENERAL_LANDSCAPE")); + orientation->append_text (M("GENERAL_PORTRAIT")); + orientation->append_text (M("GENERAL_ASIMAGE")); + orientation->set_active (2); + + guide->append_text (M("TP_CROP_GTNONE")); + guide->append_text (M("TP_CROP_GTFRAME")); + guide->append_text (M("TP_CROP_GTRULETHIRDS")); + guide->append_text (M("TP_CROP_GTDIAGONALS")); + guide->append_text (M("TP_CROP_GTHARMMEANS")); + guide->append_text (M("TP_CROP_GTGRID")); + guide->append_text (M("TP_CROP_GTTRIANGLE1")); + guide->append_text (M("TP_CROP_GTTRIANGLE2")); + guide->append_text (M("TP_CROP_GTEPASSPORT")); + guide->set_active (0); + + w->set_range (0, maxw); + h->set_range (0, maxh); + x->set_range (0, maxw); + y->set_range (0, maxh); + + x->set_digits (0); + x->set_increments (1,100); + x->set_value (0); + + y->set_digits (0); + y->set_increments (1,100); + y->set_value (0); + + w->set_digits (0); + w->set_increments (1,100); + w->set_value (200); + + h->set_digits (0); + h->set_increments (1,100); + h->set_value (200); + + ppi->set_digits (0); + ppi->set_increments (1,100); + ppi->set_range (50, 12000); + ppi->set_value (300); + + xconn = x->signal_value_changed().connect ( sigc::mem_fun(*this, &Crop::positionChanged), true); + yconn = y->signal_value_changed().connect ( sigc::mem_fun(*this, &Crop::positionChanged), true); + wconn = w->signal_value_changed().connect ( sigc::mem_fun(*this, &Crop::widthChanged), true); + hconn = h->signal_value_changed().connect ( sigc::mem_fun(*this, &Crop::heightChanged), true); + fconn = fixr->signal_toggled().connect( sigc::mem_fun(*this, &Crop::ratioFixedChanged) ); + rconn = ratio->signal_changed().connect( sigc::mem_fun(*this, &Crop::ratioChanged) ); + oconn = orientation->signal_changed().connect( sigc::mem_fun(*this, &Crop::ratioChanged) ); + gconn = guide->signal_changed().connect( sigc::mem_fun(*this, &Crop::notifyListener) ); + selectCrop->signal_pressed().connect( sigc::mem_fun(*this, &Crop::selectPressed) ); + ppi->signal_value_changed().connect( sigc::mem_fun(*this, &Crop::refreshSize) ); + + nx = ny = nw = nh = 0; + lastRotationDeg = 0; + show_all (); +} + +void Crop::writeOptions () { + + options.cropPPI = (int)ppi->get_value (); +} + +void Crop::readOptions () { + + disableListener (); + + ppi->set_value (options.cropPPI); + + enableListener (); +} + +void Crop::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + xconn.block (true); + yconn.block (true); + wconn.block (true); + hconn.block (true); + rconn.block (true); + fconn.block (true); + oconn.block (true); + gconn.block (true); + + setEnabled(pp->crop.enabled); + + // check if the new values are larger than the maximum + double tmp, maxw, maxh; + w->get_range (tmp, maxw); + h->get_range (tmp, maxh); + if (pp->crop.x + pp->crop.w > (int)maxw || pp->crop.y + pp->crop.h > (int)maxh) + setDimensions (pp->crop.x + pp->crop.w, pp->crop.y + pp->crop.h); + + 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; + if (pp->crop.orientation == "Landscape") + orientation->set_active (flip_orientation ? 1 : 0); + else if (pp->crop.orientation == "Portrait") + orientation->set_active (flip_orientation ? 0 : 1); + else + orientation->set_active (2); + + if (pp->crop.guide == "None") + guide->set_active (0); + else if (pp->crop.guide == "Frame") + guide->set_active (1); + else if (pp->crop.guide == "Rule of thirds") + guide->set_active (2); + else if (pp->crop.guide == "Rule of diagonals") + guide->set_active (3); + else if (!strncmp(pp->crop.guide.data(),"Harmonic means",14)) + guide->set_active (4); + else if (pp->crop.guide == "Grid") + guide->set_active (5); + else if (pp->crop.guide == "Golden Triangle 1") + guide->set_active (6); + else if (pp->crop.guide == "Golden Triangle 2") + guide->set_active (7); + else if (pp->crop.guide == "ePassport") + guide->set_active (8); + + x->set_value (pp->crop.x); + y->set_value (pp->crop.y); + w->set_value (pp->crop.w); + h->set_value (pp->crop.h); + + nx = pp->crop.x; + ny = pp->crop.y; + nw = pp->crop.w; + nh = pp->crop.h; + + lastRotationDeg = pp->coarse.rotate; + + wDirty = false; + hDirty = false; + xDirty = false; + yDirty = false; + + if (pedited) { + wDirty = pedited->crop.w; + hDirty = pedited->crop.h; + xDirty = pedited->crop.x; + yDirty = pedited->crop.y; + if (!pedited->crop.ratio) + ratio->set_active_text (M("GENERAL_UNCHANGED")); + if (!pedited->crop.orientation) + orientation->set_active_text (M("GENERAL_UNCHANGED")); + if (!pedited->crop.guide) + guide->set_active_text (M("GENERAL_UNCHANGED")); + set_inconsistent (multiImage && !pedited->crop.enabled); + fixr->set_inconsistent (!pedited->crop.fixratio); + } + + lastFixRatio = pp->crop.fixratio; + + xconn.block (false); + yconn.block (false); + wconn.block (false); + hconn.block (false); + rconn.block (false); + fconn.block (false); + oconn.block (false); + gconn.block (false); + + enableListener (); +} + +void Crop::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->crop.enabled = getEnabled (); + pp->crop.x = nx; + pp->crop.y = ny; + pp->crop.w = nw; + pp->crop.h = nh; + pp->crop.fixratio = fixr->get_active (); + 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; + if (orientation->get_active_row_number()==0) + pp->crop.orientation = flip_orientation ? "Portrait" : "Landscape"; + else if (orientation->get_active_row_number()==1) + pp->crop.orientation = flip_orientation ? "Landscape" : "Portrait"; + else + pp->crop.orientation = "As Image"; + if (guide->get_active_row_number()==0) + pp->crop.guide = "None"; + else if (guide->get_active_row_number()==1) + pp->crop.guide = "Frame"; + else if (guide->get_active_row_number()==2) + pp->crop.guide = "Rule of thirds"; + else if (guide->get_active_row_number()==3) + pp->crop.guide = "Rule of diagonals"; + else if (guide->get_active_row_number()==4) + pp->crop.guide = "Harmonic means"; + else if (guide->get_active_row_number()==5) + pp->crop.guide = "Grid"; + else if (guide->get_active_row_number()==6) + pp->crop.guide = "Golden Triangle 1"; + else if (guide->get_active_row_number()==7) + pp->crop.guide = "Golden Triangle 2"; + else if (guide->get_active_row_number()==8) + pp->crop.guide = "ePassport"; + + if (pedited) { + pedited->crop.enabled = !get_inconsistent(); + pedited->crop.ratio = ratio->get_active_text() != M("GENERAL_UNCHANGED"); + pedited->crop.orientation = orientation->get_active_text() != M("GENERAL_UNCHANGED"); + pedited->crop.guide = guide->get_active_text() != M("GENERAL_UNCHANGED"); + pedited->crop.fixratio = !fixr->get_inconsistent(); + pedited->crop.w = wDirty; + pedited->crop.h = hDirty; + pedited->crop.x = xDirty; + pedited->crop.y = yDirty; + } + +} + +void Crop::trim (ProcParams* pp, int ow, int oh) { + + int xmin = pp->crop.x; + int ymin = pp->crop.y; + + if (xmin > ow || ymin > oh) { + // the crop is completely out of the image, so we disable the crop + pp->crop.enabled = false; + // and we set the values to the defaults + pp->crop.x = 0; + pp->crop.y = 0; + pp->crop.w = ow; + pp->crop.h = oh; + // the ratio is now not guaranteed, so we set it off + pp->crop.fixratio = false; + } + else { + if ((xmin + pp->crop.w) > ow) { + // crop overflow in the width dimension ; we trim it + pp->crop.w = ow-xmin; + } + if ((ymin + pp->crop.h) > oh) { + // crop overflow in the height dimension ; we trim it + pp->crop.h = oh-ymin; + } + } +} + +bool Crop::inImageArea (int x, int y) { + return x>=0 && x=0 && ycropSelectRequested (); +} + +void Crop::notifyListener () { + + if (listener && getEnabled ()) { + if (nw == 1 && nh == 1) { + setEnabled(false); + nx = (int)x->get_value (); + ny = (int)y->get_value (); + nw = (int)w->get_value (); + nh = (int)h->get_value (); + listener->panelChanged (EvCrop, M("GENERAL_DISABLED")); + } + else + listener->panelChanged (EvCrop, Glib::ustring::compose ("%1=%2, %3=%4\n%5=%6, %7=%8", M("TP_CROP_X"), nx, M("TP_CROP_Y"), ny, M("TP_CROP_W"), nw, M("TP_CROP_H"), nh)); + } +} + +void Crop::enabledChanged () { + + if (listener) { + if (get_inconsistent()) + listener->panelChanged (EvCrop, M("GENERAL_UNCHANGED")); + else if (getEnabled()) + listener->panelChanged (EvCrop, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvCrop, M("GENERAL_DISABLED")); + } +} + +int notifyListenerUI (void* data) { + GThreadLock lock; // All GUI acces from idle_add callbacks or separate thread HAVE to be protected + (static_cast(data))->notifyListener (); + return 0; +} + +int refreshSpinsUI (void* data) { + GThreadLock lock; // All GUI acces from idle_add callbacks or separate thread HAVE to be protected + RefreshSpinHelper* rsh = static_cast(data); + rsh->crop->refreshSpins (rsh->notify); + delete rsh; + return 0; +} + +void Crop::hFlipCrop () { + + nx = maxw - nx - nw; + g_idle_add (refreshSpinsUI, new RefreshSpinHelper (this, false)); +} + +void Crop::vFlipCrop () { + + ny = maxh - ny - nh; + g_idle_add (refreshSpinsUI, new RefreshSpinHelper (this, false)); +} + +void Crop::rotateCrop (int deg, bool hflip, bool vflip) { + + int rotation = (360+deg-lastRotationDeg)%360; + if((hflip != vflip) && ((rotation%180)==90)) + rotation = (rotation + 180)%360; + int tmp; + switch (rotation) { + case 90: + tmp = nx; + nx = maxh - ny - nh; + ny = tmp; + tmp = nw; + nw = nh; + nh = tmp; + break; + case 270: + tmp = ny; + ny = maxw - nx - nw; + nx = tmp; + tmp = nw; + nw = nh; + nh = tmp; + break; + case 180: + nx = maxw - nx - nw; + ny = maxh - ny - nh; + break; + } + lastRotationDeg = deg; + g_idle_add (refreshSpinsUI, new RefreshSpinHelper (this, false)); +} + +void Crop::positionChanged () { + + xDirty = true; + yDirty = true; + + int X = (int)x->get_value (); + int Y = (int)y->get_value (); + int W = nw; + int H = nh; + cropMoved (X, Y, W, H); + g_idle_add (notifyListenerUI, this); +} + +void Crop::widthChanged () { + + wDirty = true; + + int X = nx; + int Y = ny; + int W = (int)w->get_value (); + int H = nh; + cropWidth2Resized (X, Y, W, H); + g_idle_add (notifyListenerUI, this); +} + +void Crop::heightChanged () { + + hDirty = true; + + int X = nx; + int Y = ny; + int W = nw; + int H = (int)h->get_value (); + cropHeight2Resized (X, Y, W, H); + g_idle_add (notifyListenerUI, this); +} + +// Fixed ratio toggle button +void Crop::ratioFixedChanged () { + // Batch mode handling when enabling/disabling fixed crop + if (batchMode && lastFixRatio != fixr->get_active ()) { + if (fixr->get_inconsistent()) { + fixr->set_inconsistent (false); + fconn.block (true); + fixr->set_active (false); + fconn.block (false); + } + else if (lastFixRatio) + fixr->set_inconsistent (true); + } + + lastFixRatio = fixr->get_active (); + adjustCropToRatio(); +} + +// change to orientation or ration +void Crop::ratioChanged () { + if (!fixr->get_active ()) + fixr->set_active(true); // will ajust ratio anyway + else + adjustCropToRatio(); +} + +// Correct current crop if it doesn't fit +void Crop::adjustCropToRatio() { + if (fixr->get_active() && !fixr->get_inconsistent()) { + +// int W = w->get_value (); +// int H = h->get_value (); + int W = nw; + int H = nh; + int X = nx; + int Y = ny; + if (W>=H) + cropWidth2Resized (X, Y, W, H); + else + cropHeight2Resized (X, Y, W, H); + } + + // This will save the options + g_idle_add (refreshSpinsUI, new RefreshSpinHelper (this, true)); +} + +void Crop::refreshSize () { + + if (!batchMode) { + + std::ostringstream ostrin; + ostrin.precision (3); + // ostrin << h->get_value()/ppi->get_value() << " in x " << w->get_value()/ppi->get_value() << " in";; + ostrin << nh/ppi->get_value() << " in x " << nw/ppi->get_value() << " in";; + + sizein->set_text (ostrin.str ()); + + std::ostringstream ostrcm; + ostrcm.precision (3); + // ostrcm << h->get_value()/ppi->get_value()*2.54 << " cm x " << w->get_value()/ppi->get_value()*2.54 << " cm";; + ostrcm << nh/ppi->get_value()*2.54 << " cm x " << nw/ppi->get_value()*2.54 << " cm";; + + sizecm->set_text (ostrcm.str ()); + } +} + +/* + * Set the maximum dimensions of the image. This method can be called with wrong values, then + * called with the good ones !? + */ +void Crop::setDimensions (int mw, int mh) { + + maxw = mw; + maxh = mh; + + bool xconnWasBlocked = xconn.block (true); + bool yconnWasBlocked = yconn.block (true); + bool wconnWasBlocked = wconn.block (true); + bool hconnWasBlocked = hconn.block (true); + + w->set_range (0, maxw); + h->set_range (0, maxh); + x->set_range (0, maxw); + y->set_range (0, maxh); + + if (!xconnWasBlocked) xconn.block (false); + if (!yconnWasBlocked) yconn.block (false); + if (!wconnWasBlocked) wconn.block (false); + if (!hconnWasBlocked) hconn.block (false); + + if (!getEnabled()) { + nx = 0; + ny = 0; + nw = mw; + nh = mh; + + refreshSpins (); + } + refreshSize (); +} + +struct setdimparams { + Crop* crop; + int x; + int y; +}; + +int sizeChangedUI (void* data) { + GThreadLock lock; // All GUI acces from idle_add callbacks or separate thread HAVE to be protected + setdimparams* params = static_cast(data); + params->crop->setDimensions (params->x, params->y); + delete params; + return 0; +} + +void Crop::sizeChanged (int x, int y, int ow, int oh) { + + setdimparams* params = new setdimparams; + params->x = x; + params->y = y; + params->crop = this; + g_idle_add (sizeChangedUI, params); +} + +bool Crop::refreshSpins (bool notify) { + + xconn.block (true); + yconn.block (true); + wconn.block (true); + hconn.block (true); + + x->set_value (nx); + y->set_value (ny); + w->set_value (nw); + h->set_value (nh); + + xDirty = true; + yDirty = true; + wDirty = true; + hDirty = true; + + xconn.block (false); + yconn.block (false); + wconn.block (false); + hconn.block (false); + + refreshSize (); + if (notify) + notifyListener (); + + return false; +} + +void Crop::cropMoved (int &X, int &Y, int &W, int &H) { + +// W = w->get_value (); +// H = h->get_value (); + W = nw; + H = nh; + + if (X+W>maxw) + X = maxw-W; + if (Y+H>maxh) + Y = maxh-H; + if (X<0) + X = 0; + if (Y<0) + Y = 0; + + nx = X; + ny = Y; + nw = W; + nh = H; + + g_idle_add (refreshSpinsUI, new RefreshSpinHelper (this, false)); +// Glib::signal_idle().connect (sigc::mem_fun(*this, &Crop::refreshSpins)); +} + +void Crop::cropWidth1Resized (int &X, int &Y, int &W, int &H) { + + int oldXR = nx + nw; + if (W < 0) W = 0; + if (W > oldXR) W = oldXR; + if (fixr->get_active()) { + double r = getRatio(); + H = (int)round(W / r); + int Hmax = min(ny + nh, maxh - ny); + if (H > Hmax) { + H = Hmax; + W = H * r; + } + ny = ny - (H - nh) / 2.0; + if (ny < 0) ny = 0; + if (ny + H > maxh) ny = maxh - H; + } + X = oldXR - W; + Y = ny; + nx = X; + nw = W; + nh = H; + + g_idle_add (refreshSpinsUI, new RefreshSpinHelper (this, false)); +} + +void Crop::cropWidth2Resized (int &X, int &Y, int &W, int &H) { + + if (W < 0) W = 0; + if (W > maxw - nx) W = maxw - nx; + if (fixr->get_active()) { + double r = getRatio(); + H = (int)round(W / r); + int Hmax = min(ny + nh, maxh - ny); + if (H > Hmax) { + H = Hmax; + W = H * r; + } + ny = ny - (H - nh) / 2.0; + if (ny < 0) ny = 0; + if (ny + H > maxh) ny = maxh - H; + } + X = nx; + Y = ny; + nw = W; + nh = H; + + g_idle_add (refreshSpinsUI, new RefreshSpinHelper (this, false)); +} + +void Crop::cropHeight1Resized (int &X, int &Y, int &W, int &H) { + + int oldYB = ny + nh; + if (H < 0) H = 0; + if (H > oldYB) H = oldYB; + if (fixr->get_active()) { + double r = getRatio(); + W = (int)round(H * r); + int Wmax = min(nx + nw, maxw - nx); + if (W > Wmax) { + W = Wmax; + H = W / r; + } + nx = nx - (W - nw) / 2.0; + if (nx < 0) nx = 0; + if (nx + W > maxw) nx = maxw - W; + } + X = nx; + Y = oldYB - H; + ny = Y; + nw = W; + nh = H; + + g_idle_add (refreshSpinsUI, new RefreshSpinHelper (this, false)); +} + +void Crop::cropHeight2Resized (int &X, int &Y, int &W, int &H) { + + if (H < 0) H = 0; + if (H > maxh - ny) H = maxh - ny; + if (fixr->get_active()) { + double r = getRatio(); + W = (int)round(H * r); + int Wmax = min(nx + nw, maxw - nx); + if (W > Wmax) { + W = Wmax; + H = W / r; + } + nx = nx - (W - nw) / 2.0; // nx must be floating point to avoid drifting + if (nx < 0) nx = 0; + if (nx + W > maxw) nx = maxw - W; + } + X = nx; + Y = ny; + nw = W; + nh = H; + + g_idle_add (refreshSpinsUI, new RefreshSpinHelper (this, false)); +} + +void Crop::cropTopLeftResized (int &X, int &Y, int &W, int &H) { + + int oldXR = nx + nw; // right side + int oldYB = ny + nh; // bottom side + if (W < 0) W = 0; + if (H < 0) H = 0; + if (W > oldXR) W = oldXR; + if (H > oldYB) H = oldYB; + if (fixr->get_active()) { + double r = getRatio(); + W = (int)round(H * r); + if (W > oldXR) { + W = oldXR; + H = (int)round(W / r); + } + } + X = oldXR - W; + Y = oldYB - H; + nx = X; + ny = Y; + nw = W; + nh = H; + + g_idle_add (refreshSpinsUI, new RefreshSpinHelper (this, false)); +} + +void Crop::cropTopRightResized (int &X, int &Y, int &W, int &H) { + + int oldYB = ny + nh; + if (W < 0) W = 0; + if (H < 0) H = 0; + if (W > maxw - nx) W = maxw - nx; + if (H > oldYB) H = oldYB; + if (fixr->get_active()) { + double r = getRatio(); + W = (int)round(H * r); + if (W > maxw - nx) { + W = maxw - nx; + H = (int)round(W / r); + } + } + X = nx; + Y = oldYB - H; + ny = Y; + nw = W; + nh = H; + + g_idle_add (refreshSpinsUI, new RefreshSpinHelper (this, false)); +} + +void Crop::cropBottomLeftResized (int &X, int &Y, int &W, int &H) { + + int oldXR = nx + nw; + if (W < 0) W = 0; + if (H < 0) H = 0; + if (W > oldXR) W = oldXR; + if (H > maxh - ny) H = maxh - ny; + if (fixr->get_active()) { + double r = getRatio(); + W = (int)round(H * r); + if (W > oldXR) { + W = oldXR; + H = (int)round(W / r); + } + } + X = oldXR - W; + Y = ny; + nx = X; + nw = W; + nh = H; + + g_idle_add (refreshSpinsUI, new RefreshSpinHelper (this, false)); +} + +void Crop::cropBottomRightResized (int &X, int &Y, int &W, int &H) { + + if (W < 0) W = 0; + if (H < 0) H = 0; + if (W > maxw - nx) W = maxw - nx; + if (H > maxh - ny) H = maxh - ny; + if (fixr->get_active()) { + double r = getRatio(); + W = (int)round(H * r); + if (W > maxw - nx) { + W = maxw - nx; + H = (int)round(W / r); + } + } + X = nx; + Y = ny; + nw = W; + nh = H; + + g_idle_add (refreshSpinsUI, new RefreshSpinHelper (this, false)); +} + +void Crop::cropInit (int &x, int &y, int &w, int &h) { + + nx = x; + ny = y; + nw = 1; + nh = 1; + + w = 1; h = 1; + + setEnabled(true); +} + +void Crop::cropResized (int &x, int &y, int& x2, int& y2) { + + if (x2<0) + x2 = 0; + if (y2<0) + y2 = 0; + if (x2>=maxw) + x2 = maxw-1; + if (y2>=maxh) + y2 = maxh-1; + + int X, Y; + int W; + if (xmaxw) + W = maxw; + if (H>maxh) + H = maxh; + + if (fixr->get_active()) { + double r = getRatio (); + if (y<=y2) { + int W2max = (int)round ((maxh-Y) * r); + if (W>W2max) + W = W2max; + } + else { + int W2max = (int)round (y * r); + if (W>W2max) + W = W2max; + } + H = (int)round(W / r); + if (xget_active()==false) + return r; + + r = cropratio[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) + + if (orientation->get_active_row_number()==0) + return r; + else if(orientation->get_active_row_number()==1) + return 1.0 / r; + else return maxh <= maxw ? r : 1.0 /r; + +} + +void Crop::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + + ratio->append_text (M("GENERAL_UNCHANGED")); + orientation->append_text (M("GENERAL_UNCHANGED")); + guide->append_text (M("GENERAL_UNCHANGED")); + removeIfThere (this, ppibox); +} diff --git a/rtgui/crop.h b/rtgui/crop.h new file mode 100644 index 000000000..40bb1877b --- /dev/null +++ b/rtgui/crop.h @@ -0,0 +1,116 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _CROP_H_ +#define _CROP_H_ + +#include +#include "cropguilistener.h" +#include "toolpanel.h" +#include "guiutils.h" +#include + +class CropPanelListener { + + public: + virtual void cropSelectRequested () {} +}; + +class CropRatio { + + public: + Glib::ustring label; + double value; +}; + +class Crop : public ToolParamBlock, public CropGUIListener, public FoldableToolPanel, public rtengine::SizeListener { + + protected: + Gtk::CheckButton* fixr; + MyComboBoxText* ratio; + MyComboBoxText* orientation; + MyComboBoxText* guide; + Gtk::Button* selectCrop; + CropPanelListener* clistener; + int opt; + MySpinButton* x; + MySpinButton* y; + MySpinButton* w; + MySpinButton* h; + MySpinButton* ppi; + Gtk::Label* sizecm; + Gtk::Label* sizein; + Gtk::VBox* ppibox; + Gtk::VBox* sizebox; + int maxw, maxh; + double nx, ny; + int nw, nh; + int lastRotationDeg; + sigc::connection xconn, yconn, wconn, hconn, fconn, rconn, oconn, gconn; + bool wDirty, hDirty, xDirty, yDirty, lastFixRatio; + void adjustCropToRatio(); + std::vector cropratio; + + public: + + Crop (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + + void ratioChanged (); + void ratioFixedChanged (); // The toggle button + void refreshSize (); + void selectPressed (); + void setDimensions (int mw, int mh); + void enabledChanged (); + void positionChanged (); + void widthChanged (); + void heightChanged (); + bool refreshSpins (bool notify=false); + void notifyListener (); + void sizeChanged (int w, int h, int ow, int oh); + void trim (rtengine::procparams::ProcParams* pp, int ow, int oh); + void readOptions (); + void writeOptions (); + + void cropMoved (int &x, int &y, int &w, int &h); + void cropWidth1Resized (int &x, int &y, int &w, int &h); + void cropWidth2Resized (int &x, int &y, int &w, int &h); + void cropHeight1Resized (int &x, int &y, int &w, int &h); + void cropHeight2Resized (int &x, int &y, int &w, int &h); + void cropTopLeftResized (int &x, int &y, int &w, int &h); + void cropTopRightResized (int &x, int &y, int &w, int &h); + void cropBottomLeftResized (int &x, int &y, int &w, int &h); + void cropBottomRightResized (int &x, int &y, int &w, int &h); + void cropInit (int &x, int &y, int &w, int &h); + void cropResized (int &x, int &y, int& x2, int& y2); + void cropManipReady (); + bool inImageArea (int x, int y); + double getRatio (); + + void setCropPanelListener (CropPanelListener* cl) { clistener = cl; } + + void resizeScaleChanged (double rsc); + void hFlipCrop (); + void vFlipCrop (); + void rotateCrop (int deg, bool hflip, bool vflip); +}; + +#endif diff --git a/rtgui/cropguilistener.h b/rtgui/cropguilistener.h new file mode 100644 index 000000000..64ecfa1a8 --- /dev/null +++ b/rtgui/cropguilistener.h @@ -0,0 +1,42 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef __CROPGUILISTENER__ +#define __CROPGUILISTENER__ + +class CropGUIListener { + + public: + virtual ~CropGUIListener() {} + virtual void cropMoved (int &x, int &y, int &w, int &h) =0; + virtual void cropWidth1Resized (int &x, int &y, int &w, int &h) =0; + virtual void cropWidth2Resized (int &x, int &y, int &w, int &h) =0; + virtual void cropHeight1Resized (int &x, int &y, int &w, int &h) =0; + virtual void cropHeight2Resized (int &x, int &y, int &w, int &h) =0; + virtual void cropTopLeftResized (int &x, int &y, int &w, int &h) =0; + virtual void cropTopRightResized (int &x, int &y, int &w, int &h) =0; + virtual void cropBottomLeftResized (int &x, int &y, int &w, int &h) =0; + virtual void cropBottomRightResized (int &x, int &y, int &w, int &h) =0; + virtual void cropInit (int &x, int &y, int &w, int &h) =0; + virtual void cropResized (int &x, int &y, int& x2, int& y2) =0; + virtual void cropManipReady () =0; + virtual bool inImageArea (int x, int y) =0; + virtual double getRatio () =0; +}; + +#endif diff --git a/rtgui/crophandler.cc b/rtgui/crophandler.cc new file mode 100644 index 000000000..9c25eea64 --- /dev/null +++ b/rtgui/crophandler.cc @@ -0,0 +1,390 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "crophandler.h" +#undef THREAD_PRIORITY_NORMAL + +#include +#include "guiutils.h" +#include "cropwindow.h" +#include "../rtengine/dcrop.h" +#include "../rtengine/refreshmap.h" + +using namespace rtengine; + +CropHandler::CropHandler () + : zoom(10), ww(0), wh(0), cx(0), cy(0), cw(0), ch(0), + cropX(0), cropY(0), cropW(0), cropH(0), enabled(false), + cropimg(NULL), cropimgtrue(NULL), ipc(NULL), crop(NULL), listener(NULL), isLowUpdatePriority(false) { + + chi = new CropHandlerIdleHelper; + chi->destroyed = false; + chi->pending = 0; + chi->cropHandler = this; +} + +CropHandler::~CropHandler () { + + if (ipc) + ipc->delSizeListener (this); + + setEnabled (false); + if (crop) { + //crop->destroy (); + delete crop; // will do the same than destroy, plus delete the object + crop = NULL; + } + cimg.lock (); + if (chi->pending) + chi->destroyed = true; + else + delete chi; + cimg.unlock (); +} + +void CropHandler::setEditSubscriber (EditSubscriber* newSubscriber) { + (static_cast(crop))->setEditSubscriber(newSubscriber); +} + +void CropHandler::newImage (StagedImageProcessor* ipc_, bool isDetailWindow) { + + ipc = ipc_; + cx = 0; + cy = 0; + + if (!ipc) + return; + + EditDataProvider *editDataProvider = NULL; + CropWindow *cropWin = listener ? static_cast(listener) : NULL; + if (cropWin) + editDataProvider = cropWin->getImageArea(); + crop = ipc->createCrop (editDataProvider, isDetailWindow); + ipc->setSizeListener (this); + crop->setListener (enabled ? this : NULL); + initial = true; +} + +void CropHandler::sizeChanged (int x, int y, int ow, int oh) { // the ipc notifies it to keep track size changes like rotation + + compDim (); + +// this should be put into an idle source!!! +/* if (listener) + listener->cropWindowChanged (); + */ +} + +double CropHandler::getFitCropZoom () { + double z1 = (double) wh / cropParams.h; + double z2 = (double) ww / cropParams.w; + return z1getFullHeight (); + double z2 = (double) ww / ipc->getFullWidth (); + return z1=0) + x = centerx; + if (centery>=0) + y = centery; + + // maybe demosaic etc. if we cross the border to >100% + bool needsFullRefresh = (z>=1000 && zoom<1000); + + zoom = z; + if (zoom>=1000) { + cw = ww * 1000 / zoom; + ch = wh * 1000 / zoom; + } + else { + cw = ww * zoom; + ch = wh * zoom; + } + cx = x - cw / 2; + cy = y - ch / 2; + + compDim (); + if (enabled) { + if (needsFullRefresh) + ipc->startProcessing(M_HIGHQUAL); + else + update (); +} +} + + +void CropHandler::setWSize (int w, int h) { + + ww = w; + wh = h; + if (zoom>=1000) { + cw = ww * 1000 / zoom; + ch = wh * 1000 / zoom; + } + else { + cw = ww * zoom; + ch = wh * zoom; + } + + compDim (); + if (enabled) + update (); +} + +void CropHandler::getWSize (int& w, int &h) { + + w = ww; + h = wh; +} + +void CropHandler::setPosition (int x, int y, bool update_) { + + cx = x; + cy = y; + + compDim (); + if (enabled && update_) + update (); +} + +void CropHandler::getPosition (int& x, int& y) { + + x = cropX; + y = cropY; +} + + +int createpixbufs (void* data) { + + GThreadLock lock; + + CropHandlerIdleHelper* chi = static_cast(data); + if (chi->destroyed) { + if (chi->pending == 1) + delete chi; + else + chi->pending--; + + return 0; + } + + CropHandler* ch = chi->cropHandler; + + ch->cimg.lock (); + ch->cropPixbuf.clear (); + + if (!ch->enabled) { + delete [] ch->cropimg; + ch->cropimg = NULL; + delete [] ch->cropimgtrue; + ch->cropimgtrue = NULL; + ch->cimg.unlock (); + return 0; + } + + if (ch->cropimg) { + if (ch->cix==ch->cropX && ch->ciy==ch->cropY && ch->ciw==ch->cropW && ch->cih==ch->cropH && ch->cis==(ch->zoom>=1000?1:ch->zoom)) { + // calculate final image size + int czoom = ch->zoom<1000 ? 1000 : ch->zoom; + int imw = ch->cropimg_width * czoom / 1000; + int imh = ch->cropimg_height * czoom / 1000; + if (imw>ch->ww) + imw = ch->ww; + if (imh>ch->wh) + imh = ch->wh; + + Glib::RefPtr tmpPixbuf = Gdk::Pixbuf::create_from_data (ch->cropimg, Gdk::COLORSPACE_RGB, false, 8, ch->cropimg_width, 2*ch->cropimg_height, 3*ch->cropimg_width); + ch->cropPixbuf = Gdk::Pixbuf::create (Gdk::COLORSPACE_RGB, false, 8, imw, imh); + tmpPixbuf->scale (ch->cropPixbuf, 0, 0, imw, imh, 0, 0, czoom/1000.0, czoom/1000.0, Gdk::INTERP_NEAREST); + tmpPixbuf.clear (); + + Glib::RefPtr tmpPixbuftrue = Gdk::Pixbuf::create_from_data (ch->cropimgtrue, Gdk::COLORSPACE_RGB, false, 8, ch->cropimg_width, 2*ch->cropimg_height, 3*ch->cropimg_width); + ch->cropPixbuftrue = Gdk::Pixbuf::create (Gdk::COLORSPACE_RGB, false, 8, imw, imh); + tmpPixbuftrue->scale (ch->cropPixbuftrue, 0, 0, imw, imh, 0, 0, czoom/1000.0, czoom/1000.0, Gdk::INTERP_NEAREST); + tmpPixbuftrue.clear (); + } + delete [] ch->cropimg; + ch->cropimg = NULL; + delete [] ch->cropimgtrue; + ch->cropimgtrue = NULL; + } + ch->cimg.unlock (); + if (ch->listener) { + ch->listener->cropImageUpdated (); + if (ch->initial) { + ch->listener->initialImageArrived (); + ch->initial = false; + } + } + + chi->pending--; + + return 0; +} + +void CropHandler::setDetailedCrop (IImage8* im, IImage8* imtrue, rtengine::procparams::ColorManagementParams cmp, + rtengine::procparams::CropParams cp, int ax, int ay, int aw, int ah, int askip) { + + if (!enabled) + return; + + cimg.lock (); + + cropParams = cp; + colorParams = cmp; + + cropPixbuf.clear (); + if (cropimg) + delete [] cropimg; + cropimg = NULL; + if (cropimgtrue) + delete [] cropimgtrue; + cropimgtrue = NULL; + + if (ax==cropX && ay==cropY && aw==cropW && ah==cropH && askip==(zoom>=1000?1:zoom)) { + cropimg_width = im->getWidth (); + cropimg_height = im->getHeight (); + cropimg = new unsigned char [3*cropimg_width*cropimg_height]; + cropimgtrue = new unsigned char [3*cropimg_width*cropimg_height]; + memcpy (cropimg, im->getData(), 3*cropimg_width*cropimg_height); + memcpy (cropimgtrue, imtrue->getData(), 3*cropimg_width*cropimg_height); + cix = ax; + ciy = ay; + ciw = aw; + cih = ah; + cis = askip; + chi->pending++; + g_idle_add (createpixbufs, chi); + } + cimg.unlock (); + } + +bool CropHandler::getWindow (int& cwx, int& cwy, int& cww, int& cwh, int& cskip) { + + cwx = cropX; + cwy = cropY; + cww = cropW; + cwh = cropH; + + // hack: if called before first size allocation the size will be 0 + if (cww<10) + cww = 10; + if (cwh<32) + cwh = 32; + + cskip = zoom>=1000 ? 1 : zoom; + + return true; +} + +void CropHandler::update () { + + if (crop) { +// crop->setWindow (cropX, cropY, cropW, cropH, zoom>=1000 ? 1 : zoom); --> we use the "getWindow" hook instead of setting the size before + crop->setListener (this); + cropPixbuf.clear (); + + // To save threads, try to mark "needUpdate" without a thread first + if (crop->tryUpdate()) { + if (isLowUpdatePriority) + Glib::Thread::create(sigc::mem_fun(*crop, &DetailedCrop::fullUpdate), 0, false, true, Glib::THREAD_PRIORITY_LOW); + else + Glib::Thread::create(sigc::mem_fun(*crop, &DetailedCrop::fullUpdate), false ); + } + } +} + +void CropHandler::setEnabled (bool e) { + + enabled = e; + if (!enabled) { + if (crop) + crop->setListener (NULL); + cimg.lock (); + delete [] cropimg; + cropimg = NULL; + delete [] cropimgtrue; + cropimgtrue = NULL; + cropPixbuf.clear (); + cimg.unlock (); + } + else + update (); +} + +bool CropHandler::getEnabled () { + + return enabled; +} + +void CropHandler::getSize (int& w, int& h) { + + w = cropW; + h = cropH; +} + +void CropHandler::getFullImageSize (int& w, int& h) { + if (ipc) { + w = ipc->getFullWidth (); + h = ipc->getFullHeight (); + } else { + w=h=0; + } +} + +void CropHandler::compDim () { + + cropX = cx; + cropY = cy; + cropW = cw; + cropH = ch; + + cutRectToImgBounds (cropX, cropY, cropW, cropH); +} + +void CropHandler::cutRectToImgBounds (int& x, int& y, int& w, int& h) { + + if (ipc) { + if (w > ipc->getFullWidth()) + w = ipc->getFullWidth(); + if (h > ipc->getFullHeight()) + h = ipc->getFullHeight(); + if (x < 0) + x = 0; + if (y < 0) + y = 0; + if (x + w >= ipc->getFullWidth()) + x = ipc->getFullWidth() - w; + if (y + h >= ipc->getFullHeight()) + y = ipc->getFullHeight() - h; + } +} diff --git a/rtgui/crophandler.h b/rtgui/crophandler.h new file mode 100644 index 000000000..a42f5085f --- /dev/null +++ b/rtgui/crophandler.h @@ -0,0 +1,111 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef __CROPHANDLER__ +#define __CROPHANDLER__ + +#include "../rtengine/rtengine.h" +#include "threadutils.h" +#include "edit.h" +#include + +class CropHandlerListener { + + public: + virtual ~CropHandlerListener() {} + virtual void cropImageUpdated () {} + virtual void cropWindowChanged () {} + virtual void initialImageArrived () {} +}; + +class CropHandler; +struct CropHandlerIdleHelper { + CropHandler* cropHandler; + bool destroyed; + int pending; +}; + +class CropHandler : public rtengine::DetailedCropListener, public rtengine::SizeListener { + + friend int createpixbufs (void* data); + + protected: + int zoom; + int ww, wh; // size of the crop view on the screen + int cx, cy, cw, ch; // position and size of the requested crop + int cropX, cropY, cropW, cropH; // position and size of the crop corresponding to cropPixbuf + bool enabled; + unsigned char* cropimg; + unsigned char* cropimgtrue; + int cropimg_width, cropimg_height, cix, ciy, ciw, cih, cis; + bool initial; + bool isLowUpdatePriority; + + rtengine::StagedImageProcessor* ipc; + rtengine::DetailedCrop* crop; + + CropHandlerListener* listener; + CropHandlerIdleHelper* chi; + + void compDim (); + + public: + + void update (); + + + rtengine::procparams::CropParams cropParams; + rtengine::procparams::ColorManagementParams colorParams; + Glib::RefPtr cropPixbuf; + Glib::RefPtr cropPixbuftrue; + + MyMutex cimg; + + CropHandler (); + ~CropHandler (); + + void setCropHandlerListener (CropHandlerListener* l) { listener = l; } + void setEditSubscriber (EditSubscriber* newSubscriber); + + void newImage (rtengine::StagedImageProcessor* ipc_, bool isDetailWindow); + void setZoom (int z, int centerx=-1, int centery=-1); + double getFitZoom (); + double getFitCropZoom(); + void setWSize (int w, int h); + void getWSize (int& w, int &h); + void setPosition (int x, int y, bool update=true); + void getPosition (int& x, int& y); + void getSize (int& w, int& h); + void getFullImageSize (int& w, int& h); + + void setEnabled (bool e); + bool getEnabled (); + + rtengine::DetailedCrop* getCrop() { return crop; } + + // DetailedCropListener interface + void setDetailedCrop (rtengine::IImage8* im, rtengine::IImage8* imworking,rtengine::procparams::ColorManagementParams cmp, + rtengine::procparams::CropParams cp, int cx, int cy, int cw, int ch, int skip); + bool getWindow (int& cwx, int& cwy, int& cww, int& cwh, int& cskip); + // SizeListener interface + void sizeChanged (int w, int h, int ow, int oh); + + void cutRectToImgBounds (int& x, int& y, int& w, int& h); +}; + +#endif diff --git a/rtgui/cropwindow.cc b/rtgui/cropwindow.cc new file mode 100755 index 000000000..6dd99228e --- /dev/null +++ b/rtgui/cropwindow.cc @@ -0,0 +1,1974 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "cropwindow.h" +#include "options.h" +#include "guiutils.h" +#include "threadutils.h" +#include "../rtengine/mytime.h" +#include "imagearea.h" +#include "cursormanager.h" +#include "../rtengine/safegtk.h" +#include "../rtengine/rt_math.h" +#include "../rtengine/dcrop.h" + +using namespace rtengine; + +struct ZoomStep { + Glib::ustring label; + double zoom; + int czoom; +}; + +ZoomStep zoomSteps[] = { + {" 1%", 0.01, 100}, + {" 2%", 0.02, 50}, + {" 5%", 0.05, 20}, + {"6.7%", 1.0/15.0,15}, + {" 8%", 1.0/12.0,12}, + {" 10%", 0.1, 10}, + {"12.5%", 0.125, 8}, + {" 14%", 1.0/7.0, 7}, + {"16.6%", 1.0/6.0, 6}, + {" 20%", 0.2, 5}, + {" 25%", 0.25, 4}, + {" 33%", 1.0/3.0, 3}, + {" 50%", 0.5, 2}, + {"100%", 1.0, 1000}, + {"200%", 2.0, 2000}, + {"300%", 3.0, 3000}, + {"400%", 4.0, 4000}, + {"500%", 5.0, 5000}, + {"600%", 6.0, 6000}, + {"700%", 7.0, 7000}, + {"800%", 8.0, 8000}}; +#define MAXZOOMSTEPS 20 +#define ZOOM11INDEX 13 + +CropWindow::CropWindow (ImageArea* parent, rtengine::StagedImageProcessor* ipc_, bool isLowUpdatePriority_, bool isDetailWindow) + : onResizeArea(false), deleted(false), fitZoomEnabled(true), fitZoom(false), isLowUpdatePriority(isLowUpdatePriority_), + backColor(options.bgcolor), decorated(true), titleHeight(30), + sideBorderWidth(3), lowerBorderWidth(3), upperBorderWidth(1), sepWidth(2), + xpos(30), ypos(30), imgX(0), imgY(0), imgW(1), imgH(1), iarea(parent), + cropZoom(0), cropgl(NULL), pmlistener(NULL), observedCropWin(NULL), ipc(ipc_), isFlawnOver(false) { + Glib::RefPtr context = parent->get_pango_context () ; + Pango::FontDescription fontd = context->get_font_description (); + fontd.set_weight (Pango::WEIGHT_BOLD); + fontd.set_size(8*Pango::SCALE); + context->set_font_description (fontd); + cropLabel = "100%"; + Glib::RefPtr cllayout = parent->create_pango_layout("1000%"); + exposeVersion = zoomVersion = 0; + + int iw, ih; + cllayout->get_pixel_size (iw, ih); + + titleHeight = ih; + + bZoomOut = new LWButton (safe_create_from_png ("gtk-zoom-out-small.png"), 0, NULL, LWButton::Left, LWButton::Center, "Zoom Out"); + bZoomIn = new LWButton (safe_create_from_png ("gtk-zoom-in-small.png"), 1, NULL, LWButton::Left, LWButton::Center, "Zoom In"); + bZoom100 = new LWButton (safe_create_from_png ("gtk-zoom-100-small.png"), 2, NULL, LWButton::Left, LWButton::Center, "Zoom 100/%"); + //bZoomFit = new LWButton (safe_create_from_png ("gtk-zoom-fit.png"), 3, NULL, LWButton::Left, LWButton::Center, "Zoom Fit"); + bClose = new LWButton (safe_create_from_png ("gtk-close-small.png"), 4, NULL, LWButton::Right, LWButton::Center, "Close"); + + buttonSet.add (bZoomOut); + buttonSet.add (bZoomIn); + buttonSet.add (bZoom100); + buttonSet.add (bClose); + + buttonSet.setColors (Gdk::Color("black"), Gdk::Color("white")); + buttonSet.setButtonListener (this); + + int bsw, bsh; + buttonSet.getMinimalDimensions (bsw, bsh); + + if (bsh>titleHeight) + titleHeight = bsh; + + minWidth = bsw + iw + 2*sideBorderWidth; + + cropHandler.setCropHandlerListener (this); + cropHandler.newImage (ipc_, isDetailWindow); + + state = SNormal; +} + +void CropWindow::enable() { + cropHandler.setEnabled (true); +} + +void CropWindow::setPosition (int x, int y) { + + if (y<0) + y = 0; + xpos = x; + ypos = y; + if (decorated) + buttonSet.arrangeButtons (xpos + sideBorderWidth, ypos + upperBorderWidth, width - 2*sideBorderWidth, titleHeight); +} + +void CropWindow::getPosition (int& x, int& y) { + + x = xpos; + y = ypos; +} + +void CropWindow::getCropPosition (int& x, int& y) { + + int cropX, cropY; + cropHandler.getPosition (cropX, cropY); + if (state!=SCropImgMove) { + x = cropX; + y = cropY; + } + else { + x = cropX + action_x; + y = cropY + action_y; + } +} + +void CropWindow::getCropRectangle (int& x, int& y, int& w, int& h) { + + int cropX, cropY, cropW, cropH; + cropHandler.getPosition (cropX, cropY); + cropHandler.getSize (cropW, cropH); + if (state!=SCropImgMove) { + x = cropX; + y = cropY; + } + else { + x = cropX + action_x; + y = cropY + action_y; + } + if (state!=SCropWinResize) { + w = cropW; + h = cropH; + } + else { + w = imgAreaW; + h = imgAreaH; + } + cropHandler.cutRectToImgBounds (x, y, w, h); +} + +void CropWindow::setCropPosition (int x, int y, bool update) { + + cropHandler.setPosition (x, y, update); + for (std::list::iterator i=listeners.begin(); i!=listeners.end(); i++) + (*i)->cropPositionChanged (this); +} + +void CropWindow::setSize (int w, int h, bool norefresh) { + + width = w; + height = h; + + fitZoom = false; + + if (widthredraw (); +} + +void CropWindow::getSize (int& w, int& h) { + + w = width; + h = height; +} + +void CropWindow::getCropSize (int& w, int& h) { + + w = imgAreaW; + h = imgAreaH; +} + +bool CropWindow::isInside (int x, int y) { + + return x>=xpos && x=ypos && ygetCurrSubscriber(); + if (state==SNormal && subscriber && subscriber->getEditingType()==ET_PIPETTE) { + iarea->pipetteVal[0] = iarea->pipetteVal[1] = iarea->pipetteVal[2] = -1.f; + if (subscriber->mouseOver(0)) { + iarea->redraw(); + } + } +} + +void CropWindow::flawnOver (bool isFlawnOver) { + this->isFlawnOver = isFlawnOver; +} + +void CropWindow::buttonPress (int button, int type, int bstate, int x, int y) { + + iarea->grabFocus (this); + if (button==1 && type==GDK_2BUTTON_PRESS && onArea (CropImage, x, y) && (state==SNormal || state==SCropImgMove)) { + if (fitZoomEnabled) { + if (fitZoom) { + state = SNormal; + zoomVersion = exposeVersion; + screenCoordToImage (x, y, action_x, action_y); + changeZoom (ZOOM11INDEX, true, action_x, action_y); + fitZoom = false; + } + else + zoomFit (); + } + else + zoom11 (); + state = SNormal; + } + //below code is no longer working/needed after adding buttons for each of the backColor values + /*else if (button==1 && type==GDK_2BUTTON_PRESS && onArea (CropBorder, x, y)) { + backColor = (backColor+1) % 3; + options.bgcolor = backColor; + }*/ + else if (button==1 && type==GDK_BUTTON_PRESS && state==SNormal && onArea (CropToolBar, x, y)) { + if (!decorated || !buttonSet.pressNotify (x, y)) { + state = SCropWinMove; + action_x = x; + action_y = y; + press_x = xpos; + press_y = ypos; + } + } + else if (button==1 && type==GDK_BUTTON_PRESS && state==SNormal && onArea (CropResize, x, y)) { + state = SCropWinResize; + action_x = x; + action_y = y; + press_x = width; + press_y = height; + } + else if (button==1 && type==GDK_BUTTON_PRESS && state==SNormal && onArea (CropImage, x, y)) { + if (onArea (CropTopLeft, x, y)) { + state = SResizeTL; + press_x = x; + action_x = cropHandler.cropParams.x; + press_y = y; + action_y = cropHandler.cropParams.y; + } + else if (onArea (CropTopRight, x, y)) { + state = SResizeTR; + press_x = x; + action_x = cropHandler.cropParams.w; + press_y = y; + action_y = cropHandler.cropParams.y; + } + else if (onArea (CropBottomLeft, x, y)) { + state = SResizeBL; + press_x = x; + action_x = cropHandler.cropParams.x; + press_y = y; + action_y = cropHandler.cropParams.h; + } + else if (onArea (CropBottomRight, x, y)) { + state = SResizeBR; + press_x = x; + action_x = cropHandler.cropParams.w; + press_y = y; + action_y = cropHandler.cropParams.h; + } + else if (onArea (CropTop, x, y)) { + state = SResizeH1; + press_y = y; + action_y = cropHandler.cropParams.y; + } + else if (onArea (CropBottom, x, y)) { + state = SResizeH2; + press_y = y; + action_y = cropHandler.cropParams.h; + } + else if (onArea (CropLeft, x, y)) { + state = SResizeW1; + press_x = x; + action_x = cropHandler.cropParams.x; + } + else if (onArea (CropRight, x, y)) { + state = SResizeW2; + press_x = x; + action_x = cropHandler.cropParams.w; + } + else if ((bstate & GDK_SHIFT_MASK) && onArea (CropInside, x, y)) { + state = SCropMove; + press_x = x; + press_y = y; + action_x = cropHandler.cropParams.x; + action_y = cropHandler.cropParams.y; + } + else if (iarea->getToolMode () == TMHand) { + EditSubscriber *editSubscriber = iarea->getCurrSubscriber(); + + if (button==1 && editSubscriber && cropgl && cropgl->inImageArea(iarea->posImage.x, iarea->posImage.y) && (editSubscriber->getEditingType()==ET_OBJECTS && iarea->object>-1) ) { + editSubscriber->button1Pressed(bstate); + state=SEditDrag; + press_x = x; + press_y = y; + action_x = 0; + action_y = 0; + } + else if (onArea (CropObserved, x, y)) { + state = SObservedMove; + press_x = x; + press_y = y; + action_x = 0; + action_y = 0; + } + else if (button==1 && editSubscriber && cropgl && cropgl->inImageArea(iarea->posImage.x, iarea->posImage.y) && (editSubscriber->getEditingType()==ET_PIPETTE && (bstate & GDK_CONTROL_MASK)) ) { + editSubscriber->button1Pressed(bstate); + state=SEditDrag; + press_x = x; + press_y = y; + action_x = 0; + action_y = 0; + } + else if(zoomSteps[cropZoom].zoom > cropHandler.getFitZoom()) { // only allow move when image is only partial visible + state = SCropImgMove; + press_x = x; + press_y = y; + action_x = 0; + action_y = 0; + } + } + else if (onArea (CropObserved, x, y)) { + state = SObservedMove; + press_x = x; + press_y = y; + } + else if (iarea->getToolMode () == TMStraighten) { + state = SRotateSelecting; + press_x = x; + press_y = y; + action_x = x; + action_y = y; + rot_deg = 0; + } + else if (iarea->getToolMode () == TMSpotWB) { + int spotx, spoty; + screenCoordToImage (x, y, spotx, spoty); + iarea->spotWBSelected (spotx, spoty); + } + else if (iarea->getToolMode () == TMCropSelect && cropgl) { + state = SCropSelecting; + screenCoordToImage (x, y, press_x, press_y); + cropHandler.cropParams.enabled = true; + cropHandler.cropParams.x = press_x; + cropHandler.cropParams.y = press_y; + cropHandler.cropParams.w = cropHandler.cropParams.h = 1; + cropgl->cropInit (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h); + } + } + if (button==3) { + iarea->pipetteVal[0] = iarea->pipetteVal[1] = iarea->pipetteVal[2] = -1.f; + EditSubscriber *editSubscriber = iarea->getCurrSubscriber(); + if (editSubscriber && editSubscriber->getEditingType()==ET_PIPETTE) + editSubscriber->mouseOver(0); + state = SNormal; + iarea->setToolHand (); + if (pmhlistener) { + pmhlistener->toggleFreeze(); + } + } + iarea->redraw (); + updateCursor (x, y); +} + +void CropWindow::buttonRelease (int button, int num, int bstate, int x, int y) { + + EditSubscriber *editSubscriber = iarea->getCurrSubscriber(); + + bool needRedraw = false; + if (state==SCropWinResize) { + int newWidth = press_x + x - action_x; + int newHeight = press_y + y - action_y; + setSize(newWidth, newHeight); + if (decorated) { + options.detailWindowWidth = newWidth; + options.detailWindowHeight = newHeight; + } + state = SNormal; + for (std::list::iterator i=listeners.begin(); i!=listeners.end(); i++) + (*i)->cropWindowSizeChanged (this); + needRedraw = true; + } + else if (state==SCropImgMove) { + int cropX, cropY; + cropHandler.getPosition (cropX, cropY); + cropHandler.setPosition (cropX + action_x, cropY + action_y); + cropHandler.getPosition (cropX, cropY); + state = SNormal; + for (std::list::iterator i=listeners.begin(); i!=listeners.end(); i++) + (*i)->cropPositionChanged (this); + needRedraw = true; + } + else if (state==SRotateSelecting) { + iarea->straightenReady (rot_deg); + iarea->setToolHand (); + needRedraw = true; + } + else if (state==SObservedMove) { + observedCropWin->remoteMoveReady (); + state = SNormal; + needRedraw = true; + } + else if (state==SEditDrag) { + editSubscriber->button1Released(); + if (editSubscriber) { + rtengine::Crop* crop = static_cast(cropHandler.getCrop()); + Coord imgPos; + action_x = x; + action_y = y; + screenCoordToImage (x, y, imgPos.x, imgPos.y); + + iarea->posImage.set(imgPos.x, imgPos.y); + iarea->posScreen.set(x, y); + + Coord cropPos; + screenCoordToCropBuffer(x, y, cropPos.x, cropPos.y); + if (editSubscriber->getEditingType()==ET_PIPETTE) { + iarea->object = onArea (CropImage, x, y) && !onArea (CropObserved, x, y) ? 1 : 0; + //iarea->object = cropgl && cropgl->inImageArea(iarea->posImage.x, iarea->posImage.y) ? 1 : 0; + if (iarea->object) { + crop->getPipetteData(iarea->pipetteVal, cropPos.x, cropPos.y, iarea->getPipetteRectSize()); + //printf("PipetteData: %.3f %.3f %.3f\n", iarea->pipetteVal[0], iarea->pipetteVal[1], iarea->pipetteVal[2]); + } + else { + iarea->pipetteVal[0] = iarea->pipetteVal[1] = iarea->pipetteVal[2] = -1.f; + } + } + else if (editSubscriber->getEditingType()==ET_OBJECTS) { + if (onArea (CropImage, x, y)) + iarea->object = crop->getObjectID(cropPos); + else + iarea->object = -1; + } + + if (editSubscriber->mouseOver(bstate)) + iarea->redraw (); + } + else + iarea->object = 0; + iarea->deltaImage.set(0, 0); + iarea->deltaScreen.set(0, 0); + iarea->deltaPrevImage.set(0, 0); + iarea->deltaPrevScreen.set(0, 0); + state = SNormal; + needRedraw = true; + } + if (cropgl && (state==SCropSelecting || state==SResizeH1 || state==SResizeH2 || state==SResizeW1 || state==SResizeW2 || state==SResizeTL || state==SResizeTR || state==SResizeBL || state==SResizeBR || state==SCropMove)) + { + cropgl->cropManipReady (); + iarea->setToolHand (); + needRedraw = true; + } + + if (decorated) + buttonSet.releaseNotify (x, y); + + if (deleted) { + iarea->flawnOverWindow = NULL; + delete this; + return; + } + + state = SNormal; + iarea->grabFocus (NULL); + if (needRedraw) + iarea->redraw (); + updateCursor (x, y); +} + +void CropWindow::pointerMoved (int bstate, int x, int y) { + + EditSubscriber *editSubscriber = iarea->getCurrSubscriber(); + + if (state==SCropWinMove) { + setPosition (press_x + x - action_x, press_y + y - action_y); + iarea->redraw (); + } + else if (state==SCropWinResize) { + setSize (press_x + x - action_x, press_y + y - action_y, true); + for (std::list::iterator i=listeners.begin(); i!=listeners.end(); i++) + (*i)->cropWindowSizeChanged (this); + iarea->redraw (); + } + else if (state==SCropImgMove) { + // multiplier is the amplification factor ; disabled if the user selected "1" (no amplification) + double factor = options.panAccelFactor == 1 ? 1.0 : options.panAccelFactor * zoomSteps[cropZoom].zoom; + // never move the preview slower than the cursor + if (factor < 1.0) + factor = 1.0; + action_x = (press_x - x) / zoomSteps[cropZoom].zoom * factor; + action_y = (press_y - y) / zoomSteps[cropZoom].zoom * factor; + for (std::list::iterator i=listeners.begin(); i!=listeners.end(); i++) + (*i)->cropPositionChanged (this); + iarea->redraw (); + } + else if (state==SRotateSelecting) { + action_x = x; + action_y = y; + iarea->redraw (); + } + else if (state==SNormal && iarea->getToolMode () == TMSpotWB) { + action_x = x; + action_y = y; + iarea->redraw (); + } + else if (state==SResizeH1 && cropgl) { + int oy = cropHandler.cropParams.y; + cropHandler.cropParams.y = action_y + (y-press_y) / zoomSteps[cropZoom].zoom; + cropHandler.cropParams.h += oy - cropHandler.cropParams.y; + cropgl->cropHeight1Resized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h); + iarea->redraw (); + } + else if (state==SResizeH2 && cropgl) { + cropHandler.cropParams.h = action_y + (y-press_y) / zoomSteps[cropZoom].zoom; + cropgl->cropHeight2Resized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h); + iarea->redraw (); + } + else if (state==SResizeW1 && cropgl) { + int ox = cropHandler.cropParams.x; + cropHandler.cropParams.x = action_x + (x-press_x) / zoomSteps[cropZoom].zoom; + cropHandler.cropParams.w += ox - cropHandler.cropParams.x; + cropgl->cropWidth1Resized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h); + iarea->redraw (); + } + else if (state==SResizeW2 && cropgl) { + cropHandler.cropParams.w = action_x + (x-press_x) / zoomSteps[cropZoom].zoom; + cropgl->cropWidth2Resized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h); + iarea->redraw (); + } + else if (state==SResizeTL && cropgl) { + int ox = cropHandler.cropParams.x; + cropHandler.cropParams.x = action_x + (x-press_x) / zoomSteps[cropZoom].zoom; + cropHandler.cropParams.w += ox - cropHandler.cropParams.x; + int oy = cropHandler.cropParams.y; + cropHandler.cropParams.y = action_y + (y-press_y) / zoomSteps[cropZoom].zoom; + cropHandler.cropParams.h += oy - cropHandler.cropParams.y; + cropgl->cropTopLeftResized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h); + iarea->redraw (); + } + else if (state==SResizeTR && cropgl) { + cropHandler.cropParams.w = action_x + (x-press_x) / zoomSteps[cropZoom].zoom; + int oy = cropHandler.cropParams.y; + cropHandler.cropParams.y = action_y + (y-press_y) / zoomSteps[cropZoom].zoom; + cropHandler.cropParams.h += oy - cropHandler.cropParams.y; + cropgl->cropTopRightResized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h); + iarea->redraw (); + } + else if (state==SResizeBL && cropgl) { + int ox = cropHandler.cropParams.x; + cropHandler.cropParams.x = action_x + (x-press_x) / zoomSteps[cropZoom].zoom; + cropHandler.cropParams.w += ox - cropHandler.cropParams.x; + cropHandler.cropParams.h = action_y + (y-press_y) / zoomSteps[cropZoom].zoom; + cropgl->cropBottomLeftResized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h); + iarea->redraw (); + } + else if (state==SResizeBR && cropgl) { + cropHandler.cropParams.w = action_x + (x-press_x) / zoomSteps[cropZoom].zoom; + cropHandler.cropParams.h = action_y + (y-press_y) / zoomSteps[cropZoom].zoom; + cropgl->cropBottomRightResized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h); + iarea->redraw (); + } + else if (state==SCropMove && cropgl) { + cropHandler.cropParams.x = action_x + (x-press_x) / zoomSteps[cropZoom].zoom; + cropHandler.cropParams.y = action_y + (y-press_y) / zoomSteps[cropZoom].zoom; + cropgl->cropMoved (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h); + iarea->redraw (); + } + else if (state==SCropSelecting && cropgl) { + screenCoordToImage (x, y, action_x, action_y); + int cx1 = press_x, cy1 = press_y; + int cx2 = action_x, cy2 = action_y; + cropgl->cropResized (cx1, cy1, cx2, cy2); + if (cx2 > cx1) { + cropHandler.cropParams.x = cx1; + cropHandler.cropParams.w = cx2 - cx1 + 1; + } + else { + cropHandler.cropParams.x = cx2; + cropHandler.cropParams.w = cx1 - cx2 + 1; + } + if (cy2 > cy1) { + cropHandler.cropParams.y = cy1; + cropHandler.cropParams.h = cy2 - cy1 + 1; + } + else { + cropHandler.cropParams.y = cy2; + cropHandler.cropParams.h = cy1 - cy2 + 1; + } + iarea->redraw (); + } + else if (state==SObservedMove) { + observedCropWin->remoteMove ((x - press_x)/zoomSteps[cropZoom].zoom, (y - press_y)/zoomSteps[cropZoom].zoom); + iarea->redraw (); + } + else if (editSubscriber) { + rtengine::Crop* crop = static_cast(cropHandler.getCrop()); + if (state==SNormal) { + Coord imgPos; + action_x = x; + action_y = y; + screenCoordToImage (x, y, imgPos.x, imgPos.y); + + iarea->posImage.set(imgPos.x, imgPos.y); + iarea->posScreen.set(x, y); + + Coord cropPos; + screenCoordToCropBuffer(x, y, cropPos.x, cropPos.y); + if (editSubscriber->getEditingType()==ET_PIPETTE) { + iarea->object = onArea (CropImage, x, y) && !onArea (CropObserved, x, y) ? 1 : 0; + //iarea->object = cropgl && cropgl->inImageArea(iarea->posImage.x, iarea->posImage.y) ? 1 : 0; + if (iarea->object) { + crop->getPipetteData(iarea->pipetteVal, cropPos.x, cropPos.y, iarea->getPipetteRectSize()); + //printf("PipetteData: %.3f %.3f %.3f\n", iarea->pipetteVal[0], iarea->pipetteVal[1], iarea->pipetteVal[2]); + } + else { + iarea->pipetteVal[0] = iarea->pipetteVal[1] = iarea->pipetteVal[2] = -1.f; + } + } + else if (editSubscriber->getEditingType()==ET_OBJECTS) { + if (onArea (CropImage, x, y)) + iarea->object = crop->getObjectID(cropPos); + else + iarea->object = -1; + } + + if (editSubscriber->mouseOver(bstate)) + iarea->redraw (); + } + else if (state==SEditDrag) { + Coord currPos; + action_x = x; + action_y = y; + Coord oldPosImage = iarea->posImage+iarea->deltaImage; + //printf(">>> IMG / ImgPrev(%d x %d) = (%d x %d) + (%d x %d)\n", oldPosImage.x, oldPosImage.y, iarea->posImage.x, iarea->posImage.y, iarea->deltaImage.x, iarea->deltaImage.y); + screenCoordToImage (x, y, currPos.x, currPos.y); + iarea->deltaImage = currPos - iarea->posImage; + iarea->deltaPrevImage = currPos - oldPosImage; + //printf(" action_ & xy (%d x %d) -> (%d x %d) = (%d x %d) + (%d x %d) / deltaPrev(%d x %d)\n", action_x, action_y, currPos.x, currPos.y, iarea->posImage.x, iarea->posImage.y, iarea->deltaImage.x, iarea->deltaImage.y, iarea->deltaPrevImage.x, iarea->deltaPrevImage.y); + + Coord oldPosScreen = iarea->posScreen+iarea->deltaScreen; + //printf(">>> SCR / ScrPrev(%d x %d) = (%d x %d) + (%d x %d)\n", oldPosScreen.x, oldPosScreen.y, iarea->posScreen.x, iarea->posScreen.y, iarea->deltaScreen.x, iarea->deltaScreen.y); + currPos.set(x, y); + iarea->deltaScreen = currPos - iarea->posScreen; + iarea->deltaPrevScreen = currPos - oldPosScreen; + //printf(" action_ & xy (%d x %d) -> (%d x %d) = (%d x %d) + (%d x %d) / deltaPrev(%d x %d)\n", action_x, action_y, currPos.x, currPos.y, iarea->posScreen.x, iarea->posScreen.y, iarea->deltaScreen.x, iarea->deltaScreen.y, iarea->deltaPrevScreen.x, iarea->deltaPrevScreen.y); + + if (editSubscriber->drag(bstate)) + iarea->redraw (); + } + } + updateCursor (x, y); + + bool oRA = onArea (CropResize, x, y); + if (oRA!=onResizeArea) { + onResizeArea = oRA; + iarea->redraw (); + } + + if (decorated) + buttonSet.motionNotify (x, y); + + if (pmlistener) { + int mx, my; + screenCoordToImage (x, y, mx, my); + if (!onArea (CropImage, x, y) || !cropHandler.cropPixbuf) { + cropHandler.getFullImageSize(mx,my); + // pmlistener->pointerMoved (false, cropHandler.colorParams.working, mx, my, -1, -1, -1); + // if (pmhlistener) pmhlistener->pointerMoved (false, cropHandler.colorParams.working, mx, my, -1, -1, -1); + /* Glib::ustring outputProfile; + outputProfile =cropHandler.colorParams.output ; + printf("Using \"%s\" output\n", outputProfile.c_str()); + if(outputProfile=="RT_sRGB") printf("OK SRGB2"); + */ + pmlistener->pointerMoved (false, cropHandler.colorParams.output,cropHandler.colorParams.working, mx, my, -1, -1, -1); + if (pmhlistener) pmhlistener->pointerMoved (false, cropHandler.colorParams.output,cropHandler.colorParams.working, mx, my, -1, -1, -1); + + } + else { + /*MyMutex::MyLock lock(cropHandler.cimg); + + int vx = x - xpos - imgX; + int vy = y - ypos - imgY; + guint8* pix = cropHandler.cropPixbuf->get_pixels() + vy*cropHandler.cropPixbuf->get_rowstride() + vx*3; + if (vx < cropHandler.cropPixbuf->get_width() && vy < cropHandler.cropPixbuf->get_height()) + pmlistener->pointerMoved (true, mx, my, pix[0], pix[1], pix[2]); + + */ + + cropHandler.cimg.lock (); + int vx = x - xpos - imgX; + int vy = y - ypos - imgY; +// guint8* pix = cropHandler.cropPixbuf->get_pixels() + vy*cropHandler.cropPixbuf->get_rowstride() + vx*3; +// if (vx < cropHandler.cropPixbuf->get_width() && vy < cropHandler.cropPixbuf->get_height()) +// pmlistener->pointerMoved (true, mx, my, pix[0], pix[1], pix[2]); + int imwidth = cropHandler.cropPixbuf->get_width(); + int imheight = cropHandler.cropPixbuf->get_height(); + guint8* pix = cropHandler.cropPixbuftrue->get_pixels() + vy*cropHandler.cropPixbuf->get_rowstride() + vx*3; + if (vx < imwidth && vy < imheight) { + // pmlistener->pointerMoved (true, cropHandler.colorParams.working, mx, my, pix[0], pix[1], pix[2]); + pmlistener->pointerMoved (true, cropHandler.colorParams.output, cropHandler.colorParams.working,mx, my, pix[0], pix[1], pix[2]); + if (pmhlistener) + // pmhlistener->pointerMoved (true, cropHandler.colorParams.working, mx, my, pix[0], pix[1], pix[2]); + pmhlistener->pointerMoved (true, cropHandler.colorParams.output, cropHandler.colorParams.working,mx, my, pix[0], pix[1], pix[2]); + } + cropHandler.cimg.unlock (); + } + } +} + +bool CropWindow::onArea (CursorArea a, int x, int y) { + + int CROPRESIZEBORDER = 6 / zoomSteps[cropZoom].zoom; + int x1, y1, w, h; + switch (a) { + case CropWinButtons: + return decorated && buttonSet.inside (x, y); + case CropToolBar: + return x>xpos && y>ypos && x=xpos+imgX && y>=ypos+imgY && x=xpos+imgAreaX && y>=ypos+imgAreaY && x=xpos+imgX && y>=ypos+imgY && x=cropHandler.cropParams.y-CROPRESIZEBORDER && + y1<=cropHandler.cropParams.y+CROPRESIZEBORDER && + y>=ypos+imgY && + x1>=cropHandler.cropParams.x-CROPRESIZEBORDER && + x1<=cropHandler.cropParams.x+CROPRESIZEBORDER && + x>=xpos+imgX; + case CropTopRight: + screenCoordToImage (x, y, x1, y1); + return cropHandler.cropParams.enabled && + y1>=cropHandler.cropParams.y-CROPRESIZEBORDER && + y1<=cropHandler.cropParams.y+CROPRESIZEBORDER && + y>=ypos+imgY && + x1>=cropHandler.cropParams.x+cropHandler.cropParams.w-1-CROPRESIZEBORDER && + x1<=cropHandler.cropParams.x+cropHandler.cropParams.w-1+CROPRESIZEBORDER && + x=cropHandler.cropParams.y+cropHandler.cropParams.h-1-CROPRESIZEBORDER && + y1<=cropHandler.cropParams.y+cropHandler.cropParams.h-1+CROPRESIZEBORDER && + y=cropHandler.cropParams.x-CROPRESIZEBORDER && + x1<=cropHandler.cropParams.x+CROPRESIZEBORDER && + x>=xpos+imgX; + case CropBottomRight: + screenCoordToImage (x, y, x1, y1); + return cropHandler.cropParams.enabled && + y1>=cropHandler.cropParams.y+cropHandler.cropParams.h-1-CROPRESIZEBORDER && + y1<=cropHandler.cropParams.y+cropHandler.cropParams.h-1+CROPRESIZEBORDER && + y=cropHandler.cropParams.x+cropHandler.cropParams.w-1-CROPRESIZEBORDER && + x1<=cropHandler.cropParams.x+cropHandler.cropParams.w-1+CROPRESIZEBORDER && + xcropHandler.cropParams.x+CROPRESIZEBORDER && + x1cropHandler.cropParams.y-CROPRESIZEBORDER && + y1=ypos+imgY; + case CropBottom: + screenCoordToImage (x, y, x1, y1); + return cropHandler.cropParams.enabled && + x1>cropHandler.cropParams.x+CROPRESIZEBORDER && + x1cropHandler.cropParams.y+cropHandler.cropParams.h-1-CROPRESIZEBORDER && + y1cropHandler.cropParams.y+CROPRESIZEBORDER && + y1cropHandler.cropParams.x-CROPRESIZEBORDER && + x1=xpos+imgX; + case CropRight: + screenCoordToImage (x, y, x1, y1); + return cropHandler.cropParams.enabled && + y1>cropHandler.cropParams.y+CROPRESIZEBORDER && + y1cropHandler.cropParams.x+cropHandler.cropParams.w-1-CROPRESIZEBORDER && + x1cropHandler.cropParams.y && + y1cropHandler.cropParams.x && + x1=xpos+width-16 && y>=ypos+height-16 && xx1-6 && y>y1-6 && xx1+2 && y>y1+2 && xgetCurrSubscriber(); + ToolMode tm = iarea->getToolMode (); + + if (state==SNormal) { + if (onArea (CropWinButtons, x, y)) + cursorManager.setCursor (iarea->get_window(), CSArrow); + else if (onArea (CropToolBar, x, y)) + cursorManager.setCursor (iarea->get_window(), CSMove); + else if (onArea (CropResize, x, y)) + cursorManager.setCursor (iarea->get_window(), CSResizeDiagonal); + else if (tm==TMHand && (onArea (CropTopLeft, x, y))) + cursorManager.setCursor (iarea->get_window(), CSResizeTopLeft); + else if (tm==TMHand && (onArea (CropTopRight, x, y))) + cursorManager.setCursor (iarea->get_window(), CSResizeTopRight); + else if (tm==TMHand && (onArea (CropBottomLeft, x, y))) + cursorManager.setCursor (iarea->get_window(), CSResizeBottomLeft); + else if (tm==TMHand && (onArea (CropBottomRight, x, y))) + cursorManager.setCursor (iarea->get_window(), CSResizeBottomRight); + else if (tm==TMHand && (onArea (CropTop, x, y) || onArea (CropBottom, x, y))) + cursorManager.setCursor (iarea->get_window(), CSResizeHeight); + else if (tm==TMHand && (onArea (CropLeft, x, y) || onArea (CropRight, x, y))) + cursorManager.setCursor (iarea->get_window(), CSResizeWidth); + else if (onArea (CropImage, x, y)) { + int objectID = -1; + if (editSubscriber) { + Coord cropPos; + screenCoordToCropBuffer(iarea->posScreen.x, iarea->posScreen.y, cropPos.x, cropPos.y); + objectID = static_cast(cropHandler.getCrop())->getObjectID(cropPos); + } + if (objectID > -1) { + cursorManager.setCursor (iarea->get_window(), editSubscriber->getCursor(objectID)); + } + else if (tm==TMHand) { + if (onArea (CropObserved, x, y)) + cursorManager.setCursor (iarea->get_window(), CSMove); + else + cursorManager.setCursor (iarea->get_window(), CSOpenHand); + } + else if (tm==TMSpotWB) + cursorManager.setCursor (iarea->get_window(), CSSpotWB); + else if (tm==TMCropSelect) + cursorManager.setCursor (iarea->get_window(), CSCropSelect); + else if (tm==TMStraighten) + cursorManager.setCursor (iarea->get_window(), CSStraighten); + } + else + cursorManager.setCursor (iarea->get_window(), CSArrow); + } + else if (state==SCropSelecting) + cursorManager.setCursor (iarea->get_window(), CSCropSelect); + else if (state==SRotateSelecting) + cursorManager.setCursor (iarea->get_window(), CSStraighten); + else if (state==SCropMove || state==SCropWinMove || state==SObservedMove) + cursorManager.setCursor (iarea->get_window(), CSMove); + else if (state==SHandMove || state==SCropImgMove) + cursorManager.setCursor (iarea->get_window(), CSClosedHand); + else if (state==SResizeW1 || state==SResizeW2) + cursorManager.setCursor (iarea->get_window(), CSResizeWidth); + else if (state==SResizeH1 || state==SResizeH2) + cursorManager.setCursor (iarea->get_window(), CSResizeHeight); + else if (state==SResizeTL) + cursorManager.setCursor (iarea->get_window(), CSResizeTopLeft); + else if (state==SResizeTR) + cursorManager.setCursor (iarea->get_window(), CSResizeTopRight); + else if (state==SResizeBL) + cursorManager.setCursor (iarea->get_window(), CSResizeBottomLeft); + else if (state==SResizeBR) + cursorManager.setCursor (iarea->get_window(), CSResizeBottomRight); + else if (state==SCropWinResize) + cursorManager.setCursor (iarea->get_window(), CSResizeDiagonal); +} + +void CropWindow::expose (Cairo::RefPtr cr) { + MyMutex::MyLock lock(cropHandler.cimg); + + if (decorated) + drawDecoration (cr); + + int x = xpos, y = ypos, h = height, w = width; + + // draw the background + backColor = iarea->previewModePanel->GetbackColor(); + options.bgcolor = backColor; + if (backColor==0) { + Gdk::Color cback = iarea->get_style()->get_bg(Gtk::STATE_NORMAL); + cr->set_source_rgb (cback.get_red_p(), cback.get_green_p(), cback.get_blue_p()); + } + else if (backColor==1) + cr->set_source_rgb (0,0,0); + else if (backColor==2) + cr->set_source_rgb (1,1,1); + + cr->set_line_width (0.); + cr->rectangle (x+imgAreaX, y+imgAreaY, imgAreaW, imgAreaH); + cr->stroke_preserve (); + cr->fill (); + + + // draw image + if (state==SCropImgMove || state==SCropWinResize) { + // draw a rough image + int cropX, cropY; + cropHandler.getPosition (cropX, cropY); + if (state==SCropImgMove) { + cropX += action_x; + cropY += action_y; + } + Glib::RefPtr rough = iarea->getPreviewHandler()->getRoughImage (cropX, cropY, imgAreaW, imgAreaH, zoomSteps[cropZoom].zoom); + if (rough) { + iarea->get_window()->draw_pixbuf (iarea->get_style()->get_base_gc(Gtk::STATE_NORMAL), rough, 0, 0, x+imgAreaX+(imgAreaW-rough->get_width())/2, y+imgAreaY+(imgAreaH-rough->get_height())/2, -1, -1, Gdk::RGB_DITHER_NORMAL, 0, 0); +// if (cropHandler.cropParams.enabled) +// drawCrop (cr, x+imgX, y+imgY, imgW, imgH, cropX, cropY, zoomSteps[cropZoom].zoom, cropHandler.cropParams); + } + if (observedCropWin) + drawObservedFrame (cr); + } + else { + if (cropHandler.cropPixbuf) { + imgW = cropHandler.cropPixbuf->get_width (); + imgH = cropHandler.cropPixbuf->get_height (); + imgX = imgAreaX + (imgAreaW-imgW)/2; + imgY = imgAreaY + (imgAreaH-imgH)/2; + 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(); + + // While the Right-side ALT is pressed, auto-enable highlight and shadow clipping indicators + // TODO: Add linux/MacOS specific functions for alternative + #ifdef WIN32 + if (GetKeyState(VK_RMENU)<0) { + showcs=true; showch=true; + } + #endif + + if (showcs || showch || showR || showG || showB || showL || showFocusMask) { + Glib::RefPtr tmp = cropHandler.cropPixbuf->copy (); + guint8* pix = tmp->get_pixels(); + guint8* pixWrkSpace = cropHandler.cropPixbuftrue->get_pixels(); + + const int pixRowStride = tmp->get_rowstride (); + const int pixWSRowStride = cropHandler.cropPixbuftrue->get_rowstride (); + + const int bHeight = tmp->get_height(); + const int bWidth = tmp->get_width(); + + if (showFocusMask) { // modulate preview to display focus mask + const int blur_radius2 = 1; // radius of small kernel. 1 => 3x3 kernel + const int blur_dim2 = 2*blur_radius2+1; // dimension of small kernel + const int blur_radius = (blur_dim2*blur_dim2)/2; // radius of big kernel + const float kernel_size = SQR(2.f*blur_radius+1.f); // count of pixels in the big blur kernel + const float rkernel_size = 1.0f/kernel_size; // reciprocal of kernel_size to avoid divisions + const float kernel_size2 = SQR(2.f*blur_radius2+1.f); // count of pixels in the small blur kernel + const float rkernel_size2 = 1.0f/kernel_size2; // reciprocal of kernel_size to avoid divisions + + // aloocate buffer for precalculated Luminance + float* tmpL = (float*)malloc(bHeight * bWidth * sizeof(float) ); + // aloocate buffers for sums and sums of squares of small kernel + float* tmpLsum = (float*)malloc((bHeight) * (bWidth) * sizeof(float) ); + float* tmpLsumSq = (float*)malloc((bHeight) * (bWidth) * sizeof(float) ); + float* tmpstdDev2 = (float*)malloc((bHeight) * (bWidth) * sizeof(float) ); + float maxstdDev_L2 = 0.f; + +#ifdef _OPENMP +#pragma omp parallel +#endif +{ +#ifdef _OPENMP +#pragma omp for +#endif + // precalculate Luminance + for(int i=0;i maxthrstdDev_L2) + maxthrstdDev_L2 = stdDev_L2; + tmpstdDev2[i*bWidth+j] = stdDev_L2; + } + } +#pragma omp critical +{ + if(maxthrstdDev_L2 > maxstdDev_L2) + maxstdDev_L2 = maxthrstdDev_L2; +} +} + + const float focus_thresh = 80.f; + maxstdDev_L2 = std::min(maxstdDev_L2,focus_thresh); + const float focus_threshby10 = focus_thresh / 10.f; + #ifdef _OPENMP + #pragma omp parallel for schedule(dynamic,16) + #endif + for (int i=blur_radius+1; ifocus_thresh2 + && (stdDev_L = stdDev_L2 //TODO: could vary this to bypass noise better + && stdDev_L2 > stdDev_L //this is the key to select fine detail within lower contrast on larger scale + && stdDev_L > focus_threshby10 //options.highlightThreshold + ){ + // transpareny depends on sdtDev_L2 and maxstdDev_L2 + float transparency = 1.f - std::min(stdDev_L2 / maxstdDev_L2, 1.0f) ; + // first row of circle + guint8* currtmp = &curr[0] + (-3*pixRowStride); + guint8* currtmpWS = &currWs[0] + (-3*pixWSRowStride); + for(int jj=-3;jj<=3;jj+=3) { + guint8* currtmpl=currtmp+jj; + guint8* currtmpWSl=currtmpWS+jj; + //transparent green + currtmpl[0] = transparency * currtmpWSl[0]; + currtmpl[1] = transparency * currtmpWSl[1] + (1.f-transparency)*255.f; + currtmpl[2] = transparency * currtmpWSl[2]; + } + // second row of circle + currtmp = &curr[0] + (-2*pixRowStride); + currtmpWS = &currWs[0] + (-2*pixWSRowStride); + for(int jj=-6;jj<=6;jj+=3) { + guint8* currtmpl=currtmp+jj; + guint8* currtmpWSl=currtmpWS+jj; + //transparent green + currtmpl[0] = transparency * currtmpWSl[0]; + currtmpl[1] = transparency * currtmpWSl[1] + (1.f-transparency)*255.f; + currtmpl[2] = transparency * currtmpWSl[2]; + } + // three middle row of circle + for(int ii=-1;ii<=1;ii++) { + currtmp = &curr[0] + (ii*pixRowStride); + currtmpWS = &currWs[0] + (ii*pixWSRowStride); + for(int jj=-9;jj<=9;jj+=3) { + guint8* currtmpl=currtmp+jj; + guint8* currtmpWSl=currtmpWS+jj; + //transparent green + currtmpl[0] = transparency * currtmpWSl[0]; + currtmpl[1] = transparency * currtmpWSl[1] + (1.f-transparency)*255.f; + currtmpl[2] = transparency * currtmpWSl[2]; + } + } + // second last row of circle + currtmp = &curr[0] + (2*pixRowStride); + currtmpWS = &currWs[0] + (2*pixWSRowStride); + for(int jj=-6;jj<=6;jj+=3) { + guint8* currtmpl=currtmp+jj; + guint8* currtmpWSl=currtmpWS+jj; + //transparent green + currtmpl[0] = transparency * currtmpWSl[0]; + currtmpl[1] = transparency * currtmpWSl[1] + (1.f-transparency)*255.f; + currtmpl[2] = transparency * currtmpWSl[2]; + } + // last row of circle + currtmp = &curr[0] + (3*pixRowStride); + currtmpWS = &currWs[0] + (3*pixWSRowStride); + for(int jj=-3;jj<=3;jj+=3) { + guint8* currtmpl=currtmp+jj; + guint8* currtmpWSl=currtmpWS+jj; + //transparent green + currtmpl[0] = transparency * currtmpWSl[0]; + currtmpl[1] = transparency * currtmpWSl[1] + (1.f-transparency)*255.f; + currtmpl[2] = transparency * currtmpWSl[2]; + } + } + curr+=3; currWs+=3; + } + } + free(tmpL); + free(tmpLsum); + free(tmpLsumSq); + free(tmpstdDev2); + + } else { // !showFocusMask + + const int hlThreshold = options.highlightThreshold; + const int shThreshold = options.shadowThreshold; + const float ShawdowFac = 64 / (options.shadowThreshold+1); + const float HighlightFac = 64 / (256-options.highlightThreshold); + const bool showclippedAny = (!showR && !showG && !showB && !showL); // will show clipping if any of RGB chanels is clipped + +#ifdef _OPENMP +#pragma omp parallel for schedule(dynamic,16) +#endif + for (int i=0; i=hlThreshold ) { delta += 255-currWS[0]; changedHL=true; } + if ((showclippedAny || showG) && currWS[1]>=hlThreshold ) { delta += 255-currWS[1]; changedHL=true; } + if ((showclippedAny || showB) && currWS[2]>=hlThreshold ) { delta += 255-currWS[2]; changedHL=true; } + if (showL && currWS_L>= hlThreshold ) { delta += 255-currWS_L ; changedHL=true; } + + if (changedHL) { + delta *= HighlightFac; + if (showclippedAny) curr[0]=curr[1]=curr[2]=delta; // indicate clipped highlights in gray + else {curr[0]=255; curr[1]=curr[2]=delta;} // indicate clipped highlights in red + } + } + if (showcs) { + if ((showclippedAny || showR) && currWS[0]<=shThreshold ) { delta += currWS[0]; changedSH=true; } + if ((showclippedAny || showG) && currWS[1]<=shThreshold ) { delta += currWS[1]; changedSH=true; } + if ((showclippedAny || showB) && currWS[2]<=shThreshold ) { delta += currWS[2]; changedSH=true; } + if (showL && currWS_L <=shThreshold ) { delta += currWS_L ; changedSH=true; } + + if (changedSH) { + if (showclippedAny) { + delta = 255 - (delta * ShawdowFac); + curr[0]=curr[1]=curr[2]=delta; // indicate clipped shadows in gray + } + else { + delta *= ShawdowFac; + curr[2]=255; curr[0]=curr[1]=delta; // indicate clipped shadows in blue + } + } + } //if (showcs) + + // modulate the preview of channels & L; + if (!changedHL && !changedSH && !showclippedAny){ //This condition allows clipping indicators for RGB channels to remain in color + if (showR) curr[1]=curr[2]=curr[0]; //Red channel in grayscale + if (showG) curr[0]=curr[2]=curr[1]; //Green channel in grayscale + if (showB) curr[0]=curr[1]=curr[2]; //Blue channel in grayscale + if (showL) { //Luminosity + // see http://en.wikipedia.org/wiki/HSL_and_HSV#Lightness for more info + //int L = (int)(0.212671*curr[0]+0.715160*curr[1]+0.072169*curr[2]); + int L = (int)(0.299*curr[0]+0.587*curr[1]+0.114*curr[2]); //Lightness - this matches Luminosity mode in Photoshop CS5 + curr[0]=curr[1]=curr[2]=L; + } + } + + /* + if (showch && (currWS[0]>=options.highlightThreshold || currWS[1]>=options.highlightThreshold || currWS[2]>=options.highlightThreshold)) + curr[0] = curr[1] = curr[2] = 0; + else if (showcs && (currWS[0]<=options.shadowThreshold || currWS[1]<=options.shadowThreshold || currWS[2]<=options.shadowThreshold)) + curr[0] = curr[1] = curr[2] = 255; + //if (showch && ((0.299*curr[0]+0.587*curr[1]+0.114*curr[2])>=options.highlightThreshold)) + // curr[0] = curr[1] = curr[2] = 0; + //else if (showcs && ((0.299*curr[0]+0.587*curr[1]+0.114*curr[2])<=options.shadowThreshold)) + // curr[0] = curr[1] = curr[2] = 255; + */ + + curr+=3; currWS+=3; + } + } + } +//printf("zoomSteps[cropZoom].zoom=%d\n",zoomSteps[cropZoom].zoom); + iarea->get_window()->draw_pixbuf (iarea->get_style()->get_base_gc(Gtk::STATE_NORMAL), tmp, 0, 0, x+imgX, y+imgY, -1, -1, Gdk::RGB_DITHER_NONE, 0, 0); + } + else + iarea->get_window()->draw_pixbuf (iarea->get_style()->get_base_gc(Gtk::STATE_NORMAL), cropHandler.cropPixbuf, 0, 0, x+imgX, y+imgY, -1, -1, Gdk::RGB_DITHER_NONE, 0, 0); + + if (cropHandler.cropParams.enabled) { + int cropX, cropY; + cropHandler.getPosition (cropX, cropY); + drawCrop (cr, x+imgX, y+imgY, imgW, imgH, cropX, cropY, zoomSteps[cropZoom].zoom, cropHandler.cropParams,(this == iarea->mainCropWindow), true, zoomSteps[cropZoom].zoom <= cropHandler.getFitZoom() ); + } + if (observedCropWin) + drawObservedFrame (cr); + + EditSubscriber *editSubscriber = iarea->getCurrSubscriber(); + rtengine::Crop* crop = static_cast(cropHandler.getCrop()); + if (editSubscriber && crop->bufferCreated()) { + + // clip the region + if (this != iarea->mainCropWindow) { + cr->set_line_width (0.); + cr->rectangle (x+imgX, y+imgY, imgW, imgH); + cr->clip(); + } + + // drawing Subscriber's visible geometry + const std::vector visibleGeom = editSubscriber->getVisibleGeometry(); + cr->set_antialias(Cairo::ANTIALIAS_DEFAULT); // ANTIALIAS_SUBPIXEL ? + cr->set_line_cap(Cairo::LINE_CAP_SQUARE); + cr->set_line_join(Cairo::LINE_JOIN_ROUND); + + // drawing outer lines + for (std::vector::const_iterator i = visibleGeom.begin(); i != visibleGeom.end(); ++i) + (*i)->drawOuterGeometry(cr, crop, *this); + + // drawing inner lines + for (std::vector::const_iterator i = visibleGeom.begin(); i != visibleGeom.end(); ++i) + (*i)->drawInnerGeometry(cr, crop, *this); + + if (this != iarea->mainCropWindow) + cr->reset_clip(); + + // drawing to the "mouse over" channel + if (editSubscriber->getEditingType() == ET_OBJECTS) { + const std::vector mouseOverGeom = editSubscriber->getMouseOverGeometry(); + if (mouseOverGeom.size()) { + //printf("ObjectMap (%d x %d)\n", crop->getObjectMap()->get_width(), crop->getObjectMap()->get_height()); + Cairo::RefPtr crMO = Cairo::Context::create(crop->getObjectMap()); + crMO->set_antialias(Cairo::ANTIALIAS_NONE); + crMO->set_line_cap(Cairo::LINE_CAP_SQUARE); + crMO->set_line_join(Cairo::LINE_JOIN_ROUND); + crMO->set_operator(Cairo::OPERATOR_SOURCE); + + // clear the bitmap + crMO->set_source_rgba(0., 0., 0., 0.); + crMO->rectangle(0., 0., crop->getObjectMap()->get_width(), crop->getObjectMap()->get_height()); + crMO->set_line_width(0.); + crMO->fill(); + + Cairo::RefPtr crMO2; + if (crop->getObjectMode() > OM_255) { + crMO2 = Cairo::Context::create(crop->getObjectMap2()); + crMO2->set_antialias(Cairo::ANTIALIAS_NONE); + crMO2->set_line_cap(Cairo::LINE_CAP_SQUARE); + crMO2->set_line_join(Cairo::LINE_JOIN_ROUND); + crMO2->set_operator(Cairo::OPERATOR_SOURCE); + + // clear the bitmap + crMO2->set_source_rgba(0., 0., 0., 0.); + crMO2->rectangle(0., 0., crop->getObjectMap2()->get_width(), crop->getObjectMap2()->get_height()); + crMO2->set_line_width(0.); + crMO2->fill(); + } + std::vector::const_iterator i; + int a; + for (a=0, i=mouseOverGeom.begin(); i != mouseOverGeom.end(); ++i, ++a) { + (*i)->drawToMOChannel(crMO, crMO2, a, crop, *this); + } + + // Debug code: save the "mouse over" image to a new file at each occurrence + #if 0 + { + static unsigned int count=0; + int w = crop->getObjectMap()->get_width(); + int h = crop->getObjectMap()->get_height(); + Glib::RefPtr img = Gdk::Pixbuf::create(Gdk::COLORSPACE_RGB, false, 8, w, h); + guint8 *dst = img->get_pixels(); + unsigned char *src1 = crop->getObjectMap()->get_data(); + unsigned char *src2 = crop->getObjectMode() > OM_255 ? crop->getObjectMap()->get_data() : NULL; + memcpy(dst, src1, w*h); + for (int n=0, n3=0; nsave(Glib::ustring::compose("mouseOverImage-%1.png", count++), "png"); + } + #endif + } + } + } + } + else { + // cropHandler.cropPixbuf is null + int cropX, cropY; + cropHandler.getPosition (cropX, cropY); + Glib::RefPtr rough = iarea->getPreviewHandler()->getRoughImage (cropX, cropY, imgAreaW, imgAreaH, zoomSteps[cropZoom].zoom); + if (rough) { + iarea->get_window()->draw_pixbuf (iarea->get_style()->get_base_gc(Gtk::STATE_NORMAL), rough, 0, 0, x+imgAreaX+(imgAreaW-rough->get_width())/2, y+imgAreaY+(imgAreaH-rough->get_height())/2, -1, -1, Gdk::RGB_DITHER_NORMAL, 0, 0); + if (cropHandler.cropParams.enabled) { + drawCrop (cr, x+imgAreaX+(imgAreaW-rough->get_width())/2, y+imgAreaY+(imgAreaH-rough->get_height())/2, rough->get_width(), rough->get_height(), cropX, cropY, zoomSteps[cropZoom].zoom, cropHandler.cropParams, (this == iarea->mainCropWindow), true, zoomSteps[cropZoom].zoom <= cropHandler.getFitZoom()); + } + if (observedCropWin) + drawObservedFrame (cr, rough->get_width(), rough->get_height()); + } + } + } + + if (state==SRotateSelecting) + drawStraightenGuide (cr); + if (state==SNormal && isFlawnOver) { + EditSubscriber *editSubscriber = iarea->getCurrSubscriber(); + if (iarea->getToolMode () == TMHand && editSubscriber && editSubscriber->getEditingType()==ET_PIPETTE && iarea->object) + drawUnscaledSpotRectangle (cr, iarea->getPipetteRectSize ()); + else if (iarea->getToolMode () == TMSpotWB) + drawScaledSpotRectangle (cr, iarea->getSpotWBRectSize ()); + } + + //t2.set (); +// printf ("etime --> %d, %d\n", t2.etime (t1), t4.etime (t3)); +} + +// calculate the center of the zoomed in/out preview given a cursor position +void CropWindow::findCenter (int deltaZoom, int& x, int& y) { + int cursorX, cursorY; + screenCoordToImage(x, y, cursorX, cursorY); + + int cropX, cropY, cropW, cropH, skip; + cropHandler.getWindow (cropX, cropY, cropW, cropH, skip); + + int currCenterX = cropX + cropW/2; + int currCenterY = cropY + cropH/2; + + int deltaX = currCenterX - cursorX; + int deltaY = currCenterY - cursorY; + + double factor = zoomSteps[cropZoom].zoom / zoomSteps[cropZoom+deltaZoom].zoom; + x = cursorX + (int)((double)(deltaX)*factor); + y = cursorY + (int)((double)(deltaY)*factor); +} + +// zoom* is called from the zoomPanel or the scroll wheel in the preview area +void CropWindow::zoomIn (bool toCursor, int cursorX, int cursorY) { + + int x = -1; + int y = -1; + + if (toCursor) { + x = cursorX; + y = cursorY; + } else { + if (zoomSteps[cropZoom].zoom <= cropHandler.getFitZoom()) { + if (cropHandler.cropParams.enabled) { + x = cropHandler.cropParams.x + cropHandler.cropParams.w / 2; + y = cropHandler.cropParams.y + cropHandler.cropParams.h / 2; + } else { + int fw, fh; + cropHandler.getFullImageSize(fw, fh); + x = fw / 2; + y = fh / 2; + } + zoomVersion = exposeVersion; + } else if (zoomVersion != exposeVersion) { + screenCoordToImage(xpos+imgX+imgW/2, ypos+imgY+imgH/2, x, y); + if (cropHandler.cropParams.enabled) { + // add some gravity towards crop center + int x1 = cropHandler.cropParams.x + cropHandler.cropParams.w / 2; + int y1 = cropHandler.cropParams.y + cropHandler.cropParams.h / 2; + double cropd = sqrt(cropHandler.cropParams.h*cropHandler.cropParams.h+cropHandler.cropParams.w*cropHandler.cropParams.w) * zoomSteps[cropZoom].zoom; + double imd = sqrt(imgW*imgW+imgH+imgH); + double d; + // the more we can see of the crop, the more gravity towards crop center + if (cropd > imd) { + d = 0.8; + } else if (cropd < imd * 0.5) { + d = 0.0; + } else { + d = 1.6 * (cropd - imd * 0.5) / imd; + } + x = d * x + (1.0 - d) * x1; + y = d * y + (1.0 - d) * y1; + } + zoomVersion = exposeVersion; + } + } + + changeZoom (cropZoom+1, true, x, y); + fitZoom = false; +} + +void CropWindow::zoomOut (bool toCursor, int cursorX, int cursorY) { + + int x = -1; + int y = -1; + + if (toCursor) { + x = cursorX; + y = cursorY; + } + + zoomVersion = exposeVersion; + changeZoom (cropZoom-1, true, x, y); + fitZoom = false; +} + +void CropWindow::zoom11 () { + + int x = -1; + int y = -1; + if (zoomSteps[cropZoom].zoom <= cropHandler.getFitZoom()) { + if (cropHandler.cropParams.enabled) { + x = cropHandler.cropParams.x + cropHandler.cropParams.w / 2; + y = cropHandler.cropParams.y + cropHandler.cropParams.h / 2; + } else { + int fw, fh; + cropHandler.getFullImageSize(fw, fh); + x = fw/2; + y = fh/2; + } + zoomVersion = exposeVersion; + } + changeZoom (ZOOM11INDEX, true, x, y); + fitZoom = false; +} + +double CropWindow::getZoom () { + + return zoomSteps[cropZoom].zoom; +} + +bool CropWindow::isMinZoom () { + return cropZoom <= 0; +} + +bool CropWindow::isMaxZoom () { + return cropZoom >= MAXZOOMSTEPS; +} + +void CropWindow::setZoom (double zoom) { + int cz = MAXZOOMSTEPS; + if (zoom < zoomSteps[0].zoom) + cz = 0; + else + for (int i=0; i zoom) { + cz = i; + break; + } + changeZoom (cz, false); +} + +double CropWindow::getZoomFitVal () { + double z = cropHandler.getFitZoom (); + int cz = MAXZOOMSTEPS; + if (z < zoomSteps[0].zoom) + cz = 0; + else + for (int i=0; i z) { + cz = i; + break; + } + return zoomSteps[cz].zoom; +} + + +void CropWindow::zoomFit (bool skipZoomIfUnchanged) { + + double z = cropHandler.getFitZoom (); + int cz = MAXZOOMSTEPS; + if (z < zoomSteps[0].zoom) + cz = 0; + else + for (int i=0; i z) { + cz = i; + break; + } + zoomVersion = exposeVersion; + changeZoom (cz, true, -1, -1, skipZoomIfUnchanged); + fitZoom = true; +} + +void CropWindow::zoomFitCrop () { + if(cropHandler.cropParams.enabled) { + double z = cropHandler.getFitCropZoom (); + int cz = MAXZOOMSTEPS; + if (z < zoomSteps[0].zoom) + cz = 0; + else + for (int i=0; i z) { + cz = i; + break; + } + zoomVersion = exposeVersion; + int centerX,centerY; + centerX = cropHandler.cropParams.x + cropHandler.cropParams.w / 2; + centerY = cropHandler.cropParams.y + cropHandler.cropParams.h / 2; + changeZoom (cz, true, centerX, centerY, false); + fitZoom = false; + } +} + +void CropWindow::buttonPressed (LWButton* button, int actionCode, void* actionData) { + + if (button==bZoomIn) // zoom in + zoomIn (); + else if (button==bZoomOut) // zoom out + zoomOut (); + else if (button==bZoom100) // zoom 100 + zoom11 (); + else if (button==bClose) {// close + if(ipc->updateTryLock()) { + deleted = true; + iarea->cropWindowClosed (this); + ipc->updateUnLock(); + } + } +} + +void CropWindow::redrawNeeded (LWButton* button) { + + iarea->redraw (); +} + +void CropWindow::changeZoom (int zoom, bool notify, int centerx, int centery, bool skipZoomIfUnchanged) { + + if (zoom<0) + zoom = 0; + else if (zoom>MAXZOOMSTEPS) + zoom = MAXZOOMSTEPS; + + if (cropZoom == zoom && skipZoomIfUnchanged) { + // We are already at the start/end of the zoom range, so we do nothing + return; + } + + cropZoom = zoom; + + cropLabel = zoomSteps[cropZoom].label; + cropHandler.setZoom (zoomSteps[cropZoom].czoom, centerx, centery); + if (notify) + for (std::list::iterator i=listeners.begin(); i!=listeners.end(); i++) + (*i)->cropZoomChanged (this); + iarea->redraw (); +} + +void CropWindow::screenCoordToCropBuffer (int phyx, int phyy, int& cropx, int& cropy) { + + rtengine::Crop* crop = static_cast(cropHandler.getCrop()); + cropx = phyx - xpos - imgX; + cropy = phyy - ypos - imgY; + if (zoomSteps[cropZoom].zoom > 1.) { + cropx = int(double(cropx)/zoomSteps[cropZoom].zoom); + cropy = int(double(cropy)/zoomSteps[cropZoom].zoom); + } + cropx += crop->getLeftBorder(); + cropy += crop->getUpperBorder(); +} + +void CropWindow::screenCoordToImage (int phyx, int phyy, int& imgx, int& imgy) { + + int cropX, cropY; + cropHandler.getPosition (cropX, cropY); + imgx = cropX + (phyx - xpos - imgX)/zoomSteps[cropZoom].zoom; + imgy = cropY + (phyy - ypos - imgY)/zoomSteps[cropZoom].zoom; +} + +void CropWindow::screenCoordToPreview (int phyx, int phyy, int& prevx, int& prevy) { + + prevx = phyx - xpos - imgX; + prevy = phyy - ypos - imgY; +} + +void CropWindow::imageCoordToScreen (int imgx, int imgy, int& phyx, int& phyy) { + + int cropX, cropY; + cropHandler.getPosition (cropX, cropY); + phyx = (imgx - cropX)*zoomSteps[cropZoom].zoom + xpos + imgX; + phyy = (imgy - cropY)*zoomSteps[cropZoom].zoom + ypos + imgY; + // printf("imgx:%d / imgy:%d / cropX:%d / cropY:%d / xpos:%d / ypos:%d / imgX:%d / imgY:%d / leftBorder: %d / upperBorder:%d / phyx:%d / phyy:%d\n", imgx, imgy, cropX, cropY, xpos, ypos, imgX, imgY, crop->getLeftBorder(), crop->getUpperBorder(), phyx, phyy); +} + +void CropWindow::imageCoordToCropBuffer (int imgx, int imgy, int& phyx, int& phyy) { + int cropX, cropY; + rtengine::Crop* crop = static_cast(cropHandler.getCrop()); + cropHandler.getPosition (cropX, cropY); + phyx = (imgx - cropX)*zoomSteps[cropZoom].zoom + /*xpos + imgX +*/ crop->getLeftBorder(); + phyy = (imgy - cropY)*zoomSteps[cropZoom].zoom + /*ypos + imgY +*/ crop->getUpperBorder(); + //printf("imgx:%d / imgy:%d / cropX:%d / cropY:%d / xpos:%d / ypos:%d / imgX:%d / imgY:%d / leftBorder: %d / upperBorder:%d / phyx:%d / phyy:%d\n", imgx, imgy, cropX, cropY, xpos, ypos, imgX, imgY, crop->getLeftBorder(), crop->getUpperBorder(), phyx, phyy); +} + +int CropWindow::scaleValueToImage (int value) { + return int(double(value)/zoomSteps[cropZoom].zoom); +} + +float CropWindow::scaleValueToImage (float value) { + return float(double(value)/zoomSteps[cropZoom].zoom); +} + +double CropWindow::scaleValueToImage (double value) { + return value/zoomSteps[cropZoom].zoom; +} + +int CropWindow::scaleValueToScreen (int value) { + return int(double(value)*zoomSteps[cropZoom].zoom); +} + +float CropWindow::scaleValueToScreen (float value) { + return float(double(value)*zoomSteps[cropZoom].zoom); +} + +double CropWindow::scaleValueToScreen (double value) { + return value*zoomSteps[cropZoom].zoom; +} + +void CropWindow::drawDecoration (Cairo::RefPtr cr) { + + int x = xpos, y = ypos; + // prepare label + Glib::RefPtr context = iarea->get_pango_context () ; + Pango::FontDescription fontd = context->get_font_description (); + fontd.set_weight (Pango::WEIGHT_BOLD); + fontd.set_size(8*Pango::SCALE); + context->set_font_description (fontd); + Glib::RefPtr cllayout = iarea->create_pango_layout(cropLabel); + int iw, ih; + cllayout->get_pixel_size (iw, ih); + + // draw decoration (border) + int h = height, w = width; + + cr->set_source_rgb (0.1,0.1,0.1); + cr->set_line_width (1.0); + cr->move_to (x+2.5, y+titleHeight+2.5 ); + cr->line_to (x+2.5, y+h-2.5); + cr->line_to (x+w-2.5, y+h-2.5); + cr->line_to (x+w-2.5, y+titleHeight+2.5 ); + + cr->set_source_rgba (0.0,0.0,0.0,0.5); + cr->rectangle (x+2.5, y+0.5, w-5, titleHeight+2); + cr->stroke_preserve (); + cr->fill (); + + // draw label + cr->set_source_rgba (1,1,1,0.5); + cr->move_to (x+10+sideBorderWidth+bZoomIn->getIcon()->get_width()+bZoomOut->getIcon()->get_width()+bZoom100->getIcon()->get_width(), y+1+upperBorderWidth+(titleHeight-ih)/2); + cllayout->add_to_cairo_context (cr); + cr->fill (); + + buttonSet.redraw (cr); +} + +void CropWindow::drawStraightenGuide (Cairo::RefPtr cr) { + + if (action_x!=press_x || action_y!=press_y) { + double arg = (press_x-action_x) / sqrt(double((press_x-action_x)*(press_x-action_x)+(press_y-action_y)*(press_y-action_y))); + double sol1, sol2; + double pi = M_PI; + if (press_y>action_y) { + sol1 = acos(arg)*180/pi; + sol2 = -acos(-arg)*180/pi; + } + else { + sol1 = acos(-arg)*180/pi; + sol2 = -acos(arg)*180/pi; + } + if (fabs(sol1)45) + rot_deg = - 90.0 + rot_deg; + } + else + rot_deg = 0; + + Glib::RefPtr context = iarea->get_pango_context () ; + Pango::FontDescription fontd = context->get_font_description (); + fontd.set_weight (Pango::WEIGHT_BOLD); + fontd.set_size (8*Pango::SCALE); + context->set_font_description (fontd); + Glib::RefPtr deglayout = iarea->create_pango_layout(Glib::ustring::compose ("%1 deg", Glib::ustring::format(std::setprecision(2), rot_deg))); + + int x1 = press_x; + int y1 = press_y; + int y2 = action_y; + int x2 = action_x; +/* if (x1<0) x1 = 0; + if (y1<0) y1 = 0; + if (x2<0) x2 = 0; + if (y2<0) y2 = 0; + if (x2>=image->getWidth()) x2 = image->getWidth()-1; + if (y2>=image->getHeight()) y2 = image->getHeight()-1; + if (x1>=image->getWidth()) x1 = image->getWidth()-1; + if (y1>=image->getHeight()) y1 = image->getHeight()-1; +*/ + + cr->set_line_width (1); + cr->set_source_rgba (1.0, 1.0, 1.0, 0.618); + cr->move_to (x1+0.5, y1+0.5); + cr->line_to (x2+0.5, y2+0.5); + cr->stroke (); + cr->set_source_rgba (0.0, 0.0, 0.0, 0.618); + std::valarray ds (1); + ds[0] = 4; + cr->set_dash (ds, 0); + cr->move_to (x1+0.5, y1+0.5); + cr->line_to (x2+0.5, y2+0.5); + cr->stroke (); + + if (press_x!=action_x && press_y!=action_y) { + cr->set_source_rgb (0.0, 0.0, 0.0); + cr->move_to ((x1+x2)/2+1, (y1+y2)/2+1); + deglayout->add_to_cairo_context (cr); + cr->move_to ((x1+x2)/2+1, (y1+y2)/2-1); + deglayout->add_to_cairo_context (cr); + cr->move_to ((x1+x2)/2-1, (y1+y2)/2+1); + deglayout->add_to_cairo_context (cr); + cr->move_to ((x1+x2)/2+1, (y1+y2)/2+1); + deglayout->add_to_cairo_context (cr); + cr->fill (); + cr->set_source_rgb (1.0, 1.0, 1.0); + cr->move_to ((x1+x2)/2, (y1+y2)/2); + deglayout->add_to_cairo_context (cr); + cr->fill (); + } +} + +void CropWindow::drawScaledSpotRectangle (Cairo::RefPtr cr, int rectSize) { + + int x1 = action_x/zoomSteps[cropZoom].zoom - rectSize; + int y1 = action_y/zoomSteps[cropZoom].zoom - rectSize; + int y2 = action_y/zoomSteps[cropZoom].zoom + rectSize; + int x2 = action_x/zoomSteps[cropZoom].zoom + rectSize; + + cr->set_line_width (1.0); + cr->rectangle (xpos+imgX-0.5, ypos+imgY-0.5, imgW, imgH); + cr->clip (); + + cr->set_source_rgb (1.0, 1.0, 1.0); + cr->rectangle (x1*zoomSteps[cropZoom].zoom-1.5, y1*zoomSteps[cropZoom].zoom-1.5, x2*zoomSteps[cropZoom].zoom-x1*zoomSteps[cropZoom].zoom+2, y2*zoomSteps[cropZoom].zoom-y1*zoomSteps[cropZoom].zoom+2); + cr->stroke (); + cr->set_source_rgb (0.0, 0.0, 0.0); + cr->rectangle (x1*zoomSteps[cropZoom].zoom-0.5, y1*zoomSteps[cropZoom].zoom-0.5, x2*zoomSteps[cropZoom].zoom-x1*zoomSteps[cropZoom].zoom, y2*zoomSteps[cropZoom].zoom-y1*zoomSteps[cropZoom].zoom); + cr->stroke (); + + cr->reset_clip (); +} + +void CropWindow::drawUnscaledSpotRectangle (Cairo::RefPtr cr, int rectSize) { + + int x1 = action_x - rectSize; + int y1 = action_y - rectSize; + int y2 = action_y + rectSize; + int x2 = action_x + rectSize; + + cr->set_line_width (1.0); + cr->rectangle (xpos+imgX-0.5, ypos+imgY-0.5, imgW, imgH); + cr->clip (); + + cr->set_source_rgb (1.0, 1.0, 1.0); + cr->rectangle (x1-1.5, y1-1.5, x2-x1+2, y2-y1+2); + cr->stroke (); + cr->set_source_rgb (0.0, 0.0, 0.0); + cr->rectangle (x1-0.5, y1-0.5, x2-x1, y2-y1); + cr->stroke (); + + cr->reset_clip (); +} + +void CropWindow::getObservedFrameArea (int& x, int& y, int& w, int& h, int rw, int rh) { + + int cropX, cropY, cropW, cropH; + observedCropWin->getCropRectangle (cropX, cropY, cropW, cropH); + int myCropX, myCropY, myCropW, myCropH; + getCropRectangle (myCropX, myCropY, myCropW, myCropH); + + // translate it to screen coordinates + if (rw) { + x = xpos + imgAreaX+(imgAreaW-rw)/2 + (cropX-myCropX)*zoomSteps[cropZoom].zoom; + y = ypos + imgAreaY+(imgAreaH-rh)/2 + (cropY-myCropY)*zoomSteps[cropZoom].zoom; + } + else { + x = xpos + imgX + (cropX-myCropX)*zoomSteps[cropZoom].zoom; + y = ypos + imgY + (cropY-myCropY)*zoomSteps[cropZoom].zoom; + } + w = cropW * zoomSteps[cropZoom].zoom; + h = cropH * zoomSteps[cropZoom].zoom; +} + +void CropWindow::drawObservedFrame (Cairo::RefPtr cr, int rw, int rh) { + + int x, y, w, h; + getObservedFrameArea (x, y, w, h, rw, rh); + + // draw a black "shadow" line + cr->set_source_rgba( 0, 0, 0, 0.65); + cr->set_line_width (1); + cr->rectangle (x-0.5, y-0.5, w+4, h+4); + cr->stroke (); + + // draw a "frame" line. Color of frame line can be set in preferences + cr->set_source_rgba(options.navGuideBrush[0], options.navGuideBrush[1], options.navGuideBrush[2], options.navGuideBrush[3]); //( 1, 1, 1, 1.0); + cr->rectangle (x-1.5, y-1.5, w+4, h+4); + cr->stroke (); +} + +void CropWindow::cropImageUpdated () { + + iarea->redraw (); +} + +void CropWindow::cropWindowChanged () { + + if (!decorated) + iarea->syncBeforeAfterViews (); + iarea->redraw (); +} + +void CropWindow::initialImageArrived () { + + for (std::list::iterator i=listeners.begin(); i!=listeners.end(); i++) + (*i)->initialImageArrived (this); +} + + +void CropWindow::remoteMove (int deltaX, int deltaY) { + + state = SCropImgMove; + action_x = deltaX; + action_y = deltaY; + for (std::list::iterator i=listeners.begin(); i!=listeners.end(); i++) + (*i)->cropPositionChanged (this); +} + +void CropWindow::remoteMoveReady () { + + int cropX, cropY; + cropHandler.getPosition (cropX, cropY); + cropHandler.setPosition (cropX + action_x, cropY + action_y); + cropHandler.getPosition (cropX, cropY); + state = SNormal; + for (std::list::iterator i=listeners.begin(); i!=listeners.end(); i++) + (*i)->cropPositionChanged (this); +} + +void CropWindow::delCropWindowListener (CropWindowListener* l) { + + std::list::iterator i=listeners.begin(); + while (i!=listeners.end()) + if (*i==l) + i = listeners.erase (i); + else + i++; +} + +EditDataProvider* CropWindow::getImageArea() { + return iarea; +} diff --git a/rtgui/cropwindow.h b/rtgui/cropwindow.h new file mode 100755 index 000000000..a6a55905f --- /dev/null +++ b/rtgui/cropwindow.h @@ -0,0 +1,179 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _CROPWINDOW_ +#define _CROPWINDOW_ + +#include "../rtengine/rtengine.h" +#include +#include "lwbutton.h" +#include "lwbuttonset.h" +#include "editenums.h" +#include "crophandler.h" +#include +#include "cropguilistener.h" +#include "pointermotionlistener.h" + +class CropWindow; +class CropWindowListener { + + public: + virtual ~CropWindowListener() {} + virtual void cropPositionChanged (CropWindow*) {} + virtual void cropWindowSizeChanged (CropWindow*) {} + virtual void cropZoomChanged (CropWindow*) {} + virtual void initialImageArrived (CropWindow*) {} +}; + +class ImageArea; +class CropWindow : public LWButtonListener, public CropHandlerListener, public EditCoordSystem { + + // state management + ImgEditState state; // current state of user (see enum State) + int action_x, action_y, press_x, press_y; + double rot_deg; + bool onResizeArea; + bool deleted; + bool fitZoomEnabled; + bool fitZoom; + bool isLowUpdatePriority; + + // decoration + LWButton *bZoomIn, *bZoomOut, *bZoom100, /**bZoomFit,*/ *bClose; + LWButtonSet buttonSet; + Glib::ustring cropLabel; + int backColor; + bool decorated; + bool isFlawnOver; + + // crop frame description + int titleHeight, sideBorderWidth, lowerBorderWidth, upperBorderWidth, sepWidth, minWidth; + // size & position of the crop relative to the top left corner + // of the main preview area + int xpos, ypos, width, height; + // size & pos of the drawable area relative to the top left corner of the crop + int imgAreaX, imgAreaY, imgAreaW, imgAreaH; + // size & pos of the piece of preview image relative to the top left corner of the crop + int imgX, imgY, imgW, imgH; + + // image handling + + ImageArea* iarea; + int cropZoom; // *1000 + unsigned int zoomVersion, exposeVersion; + + // crop gui listener + CropGUIListener* cropgl; + PointerMotionListener* pmlistener; + PointerMotionListener* pmhlistener; + std::list listeners; + + CropWindow* observedCropWin; + rtengine::StagedImageProcessor* ipc; + + bool onArea (CursorArea a, int x, int y); + void updateCursor (int x, int y); + void drawDecoration (Cairo::RefPtr cr); + void drawStraightenGuide (Cairo::RefPtr cr); + void drawScaledSpotRectangle (Cairo::RefPtr cr, int rectSize); + void drawUnscaledSpotRectangle (Cairo::RefPtr cr, int rectSize); + void drawObservedFrame (Cairo::RefPtr cr, int rw=0, int rh=0); + void changeZoom (int zoom, bool notify=true, int centerx=-1, int centery=-1, bool skipZoomIfUnchanged = true); + void getObservedFrameArea (int& x, int& y, int& w, int& h, int rw=0, int rh=0); + + public: + CropHandler cropHandler; + CropWindow (ImageArea* parent, rtengine::StagedImageProcessor* ipc_, bool isLowUpdatePriority_, bool isDetailWindow); + + void setDecorated (bool decorated) { this->decorated = decorated; } + void setFitZoomEnabled (bool fze) { fitZoomEnabled = fze; } + void setObservedCropWin (CropWindow* cw) { observedCropWin = cw; } + + void screenCoordToCropBuffer (int phyx, int phyy, int& cropx, int& cropy); + void screenCoordToImage (int phyx, int phyy, int& imgx, int& imgy); + void screenCoordToPreview (int phyx, int phyy, int& prevx, int& prevy); + void imageCoordToScreen (int imgx, int imgy, int& phyx, int& phyy); + void imageCoordToCropBuffer (int imgx, int imgy, int& phyx, int& phyy); + int scaleValueToImage (int value); + float scaleValueToImage (float value); + double scaleValueToImage (double value); + int scaleValueToScreen (int value); + float scaleValueToScreen (float value); + double scaleValueToScreen (double value); + double getZoomFitVal (); + void setPosition (int x, int y); + void getPosition (int& x, int& y); + void setSize (int w, int h, bool norefresh=false); + void getSize (int& w, int& h); + void enable (); + + void leaveNotify (GdkEventCrossing* event); + void flawnOver (bool isFlawnOver); + + // zoomlistener interface + void zoomIn (bool toCursor=false, int cursorX=-1, int cursorY=-1); + void zoomOut (bool toCursor=false, int cursorX=-1, int cursorY=-1); + void zoom11 (); + void zoomFit (bool skipZoomIfUnchanged=true); + void zoomFitCrop (); + double getZoom (); + bool isMinZoom (); + bool isMaxZoom (); + void setZoom (double zoom); + + void findCenter (int deltaZoom, int& x, int& y); + bool isInside (int x, int y); + + + void buttonPress (int button, int num, int state, int x, int y); + void buttonRelease (int button, int num, int state, int x, int y); + void pointerMoved (int bstate, int x, int y); + + void expose (Cairo::RefPtr cr); + + // interface lwbuttonlistener + void buttonPressed (LWButton* button, int actionCode, void* actionData); + void redrawNeeded (LWButton* button); + + // crop handling + void getCropRectangle (int& x, int& y, int& w, int& h); + void getCropPosition (int& x, int& y); + void setCropPosition (int x, int y, bool update = true); + void getCropSize (int& w, int& h); + + // listeners + void setCropGUIListener (CropGUIListener* cgl) { cropgl = cgl; } + void setPointerMotionListener (PointerMotionListener* pml) { pmlistener = pml; } + void setPointerMotionHListener (PointerMotionListener* pml) { pmhlistener = pml; } + + // crop window listeners + void addCropWindowListener (CropWindowListener* l) { listeners.push_back (l); } + void delCropWindowListener (CropWindowListener* l); + + // crophandlerlistener interface + void cropImageUpdated (); + void cropWindowChanged (); + void initialImageArrived (); + + void remoteMove (int deltaX, int deltaY); + void remoteMoveReady (); + + EditDataProvider* getImageArea(); +}; + +#endif diff --git a/rtgui/cursormanager.cc b/rtgui/cursormanager.cc new file mode 100644 index 000000000..a625c7adc --- /dev/null +++ b/rtgui/cursormanager.cc @@ -0,0 +1,120 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "cursormanager.h" +#include "options.h" +#include "../rtengine/safegtk.h" +#include "rtimage.h" + +CursorManager cursorManager; + +void CursorManager::init (Glib::RefPtr mainWin) { + + cResizeWidth = new Gdk::Cursor (Gdk::SB_H_DOUBLE_ARROW); + cResizeHeight = new Gdk::Cursor (Gdk::SB_V_DOUBLE_ARROW); + cResizeDiag = new Gdk::Cursor (Gdk::BOTTOM_RIGHT_CORNER); + cResizeTopLeft = new Gdk::Cursor (Gdk::TOP_LEFT_CORNER); + cResizeTopRight = new Gdk::Cursor (Gdk::TOP_RIGHT_CORNER); + cResizeBottomLeft = new Gdk::Cursor (Gdk::BOTTOM_LEFT_CORNER); + cResizeBottomRight = new Gdk::Cursor (Gdk::BOTTOM_RIGHT_CORNER); + cCropMove = new Gdk::Cursor (Gdk::FLEUR); + cCropMoving = new Gdk::Cursor (Gdk::HAND2); + cCropSelection = new Gdk::Cursor (Gdk::CROSSHAIR); + cLeftTanMove = new Gdk::Cursor (Gdk::SB_LEFT_ARROW); + cRightTanMove = new Gdk::Cursor (Gdk::SB_RIGHT_ARROW); + cAdd = new Gdk::Cursor (Gdk::PLUS); + cWait = new Gdk::Cursor (Gdk::CLOCK); + + Glib::RefPtr hand = safe_create_from_file("cross.png"); + Glib::RefPtr close_hand = safe_create_from_file("closedhand.png"); + Glib::RefPtr wbpick = safe_create_from_file("gtk-color-picker-small.png"); + Glib::RefPtr empty = safe_create_from_file("empty.png"); + Glib::RefPtr move2D = safe_create_from_file("move-2D.png"); + Glib::RefPtr move1DH = safe_create_from_file("move-1D-h.png"); + Glib::RefPtr move1DV = safe_create_from_file("move-1D-v.png"); + Glib::RefPtr moveRotate = safe_create_from_file("move-rotate.png"); + + cHand = hand ? new Gdk::Cursor (cAdd->get_display(), hand, 10, 10) : new Gdk::Cursor (Gdk::HAND2); + cClosedHand = close_hand ? new Gdk::Cursor (cAdd->get_display(), close_hand, 10, 10) : new Gdk::Cursor (Gdk::HAND2); + cWB = wbpick ? new Gdk::Cursor (cAdd->get_display(), wbpick, 1, 12) : new Gdk::Cursor (Gdk::ARROW); + cHidden = empty ? new Gdk::Cursor (cAdd->get_display(), empty, 12, 12) : new Gdk::Cursor (Gdk::FLEUR); + cMove2D = move2D ? new Gdk::Cursor (cAdd->get_display(), move2D, 11, 11) : new Gdk::Cursor (Gdk::FLEUR); + cMove1DH = move1DH ? new Gdk::Cursor (cAdd->get_display(), move1DH, 11, 11) : new Gdk::Cursor (Gdk::FLEUR); + cMove1DV = move1DV ? new Gdk::Cursor (cAdd->get_display(), move1DV, 11, 11) : new Gdk::Cursor (Gdk::FLEUR); + cMoveRotate = moveRotate ? new Gdk::Cursor (cAdd->get_display(), moveRotate, 11, 11) : new Gdk::Cursor (Gdk::CIRCLE); + + mainWindow = mainWin; +} + +/* Set the cursor of the given window */ +void CursorManager::setCursor (Glib::RefPtr window, CursorShape shape) { + + if (shape==CSArrow) + // set_cursor without any arguments to select system default + window->set_cursor (); + else if (shape==CSOpenHand) + window->set_cursor (*cHand); + else if (shape==CSClosedHand) + window->set_cursor (*cClosedHand); + else if (shape==CSMove) + window->set_cursor (*cCropMove); + else if (shape==CSResizeWidth) + window->set_cursor (*cResizeWidth); + else if (shape==CSResizeHeight) + window->set_cursor (*cResizeHeight); + else if (shape==CSResizeDiagonal) + window->set_cursor (*cResizeDiag); + else if (shape==CSResizeTopLeft) + window->set_cursor (*cResizeTopLeft); + else if (shape==CSResizeTopRight) + window->set_cursor (*cResizeTopRight); + else if (shape==CSResizeBottomLeft) + window->set_cursor (*cResizeBottomLeft); + else if (shape==CSResizeBottomRight) + window->set_cursor (*cResizeBottomRight); + else if (shape==CSMove2D) + window->set_cursor (*cMove2D); + else if (shape==CSMove1DH) + window->set_cursor (*cMove1DH); + else if (shape==CSMove1DV) + window->set_cursor (*cMove1DV); + else if (shape==CSMoveRotate) + window->set_cursor (*cMoveRotate); + else if (shape==CSSpotWB) + window->set_cursor (*cWB); + else if (shape==CSCropSelect) + window->set_cursor (*cCropSelection); + else if (shape==CSMoveLeft) + window->set_cursor (*cLeftTanMove); + else if (shape==CSMoveRight) + window->set_cursor (*cRightTanMove); + else if (shape==CSStraighten) + window->set_cursor (*cCropSelection); + else if (shape==CSWait) + window->set_cursor (*cWait); + else if (shape==CSPlus) + window->set_cursor (*cAdd); + else if (shape==CSEmpty) + window->set_cursor (*cHidden); +} + +/* Set the cursor of the main window */ +void CursorManager::setCursor (CursorShape shape) { + setCursor(mainWindow, shape); +} + diff --git a/rtgui/cursormanager.h b/rtgui/cursormanager.h new file mode 100644 index 000000000..1302708c7 --- /dev/null +++ b/rtgui/cursormanager.h @@ -0,0 +1,69 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _CURSORMANAGER_ +#define _CURSORMANAGER_ + +#include + +enum CursorShape { + CSArrow, CSOpenHand, CSClosedHand, CSMove, CSMoveLeft, + CSMoveRight, CSResizeWidth, CSResizeHeight, CSResizeDiagonal, + CSResizeTopLeft, CSResizeTopRight, CSResizeBottomLeft, CSResizeBottomRight, + CSMove2D, CSMove1DH, CSMove1DV, CSMoveRotate, + CSSpotWB, CSCropSelect, CSStraighten, CSPlus, CSWait, CSEmpty +}; + +class CursorManager { + + protected: + Gdk::Cursor* cResizeWidth; + Gdk::Cursor* cResizeHeight; + Gdk::Cursor* cResizeDiag; + Gdk::Cursor* cResizeTopLeft; + Gdk::Cursor* cResizeTopRight; + Gdk::Cursor* cResizeBottomLeft; + Gdk::Cursor* cResizeBottomRight; + Gdk::Cursor* cCropMove; + Gdk::Cursor* cCropMoving; + Gdk::Cursor* cLeftTanMove; + Gdk::Cursor* cRightTanMove; + Gdk::Cursor* cNormal; + Gdk::Cursor* cCropSelection; + Gdk::Cursor* cAdd; + Gdk::Cursor* cWait; + Gdk::Cursor* cHand; + Gdk::Cursor* cClosedHand; + Gdk::Cursor* cWB; + Gdk::Cursor* cHidden; + Gdk::Cursor* cMove2D; + Gdk::Cursor* cMove1DH; + Gdk::Cursor* cMove1DV; + Gdk::Cursor* cMoveRotate; + Glib::RefPtr mainWindow; + + public: + void init (Glib::RefPtr mainWin); + void setCursor (Glib::RefPtr window, CursorShape shape); + void setCursor (CursorShape shape); +}; + +extern CursorManager cursorManager; + +#endif + diff --git a/rtgui/curveeditor.cc b/rtgui/curveeditor.cc new file mode 100644 index 000000000..1cadad6a6 --- /dev/null +++ b/rtgui/curveeditor.cc @@ -0,0 +1,373 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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. + * + * 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 "curveeditor.h" +#include "curveeditorgroup.h" +#include +#include +#include "guiutils.h" +#include "multilangmgr.h" +#include "../rtengine/LUT.h" + +#include + +bool CurveEditor::reset() { + return subGroup->curveReset(this); +} + +DiagonalCurveEditor::DiagonalCurveEditor (Glib::ustring text, CurveEditorGroup* ceGroup, CurveEditorSubGroup* ceSubGroup) : CurveEditor::CurveEditor(text, static_cast(ceGroup), ceSubGroup) { + + // Order set in the same order than "enum DiagonalCurveType". Shouldn't change, for compatibility reason + curveType->addEntry("curveType-linear.png", M("CURVEEDITOR_LINEAR")); // 0 Linear + curveType->addEntry("curveType-spline.png", M("CURVEEDITOR_CUSTOM")); // 1 Spline + curveType->addEntry("curveType-parametric.png", M("CURVEEDITOR_PARAMETRIC")); // 2 Parametric + curveType->addEntry("curveType-NURBS.png", M("CURVEEDITOR_NURBS")); // 3 NURBS + curveType->setSelected(DCT_Linear); + curveType->show(); + + rangeLabels[0] = M("CURVEEDITOR_SHADOWS"); + rangeLabels[1] = M("CURVEEDITOR_DARKS"); + rangeLabels[2] = M("CURVEEDITOR_LIGHTS"); + rangeLabels[3] = M("CURVEEDITOR_HIGHLIGHTS"); + + rangeMilestones[0] = 0.25; + rangeMilestones[1] = 0.50; + rangeMilestones[2] = 0.75; +} + +std::vector DiagonalCurveEditor::getCurve () { + std::vector curve; + + switch (selected) { + case (DCT_Spline): + return curve = customCurveEd; + case (DCT_Parametric): + return curve = paramCurveEd; + case (DCT_NURBS): + return curve = NURBSCurveEd; + default: + // returning Linear or Unchanged + curve.push_back((double)(selected)); + return curve; + } +} + +void DiagonalCurveEditor::setResetCurve(DiagonalCurveType cType, const std::vector &resetCurve) { + switch (cType) { + case (DCT_NURBS): + if (resetCurve.size() && DiagonalCurveType(resetCurve.at(0)) == cType) + NURBSResetCurve = resetCurve; + break; + case (DCT_Parametric): + if (resetCurve.size() && DiagonalCurveType(resetCurve.at(0)) == cType) + paramResetCurve = resetCurve; + break; + case (DCT_Spline): + if (resetCurve.size() && DiagonalCurveType(resetCurve.at(0)) == cType) + customResetCurve = resetCurve; + break; + default: + break; + } +} + +void DiagonalCurveEditor::setRangeLabels(Glib::ustring r1, Glib::ustring r2, Glib::ustring r3, Glib::ustring r4) { + rangeLabels[0] = r1; + rangeLabels[1] = r2; + rangeLabels[2] = r3; + rangeLabels[3] = r4; +} + +void DiagonalCurveEditor::getRangeLabels(Glib::ustring &r1, Glib::ustring &r2, Glib::ustring &r3, Glib::ustring &r4) { + r1 = rangeLabels[0]; + r2 = rangeLabels[1]; + r3 = rangeLabels[2]; + r4 = rangeLabels[3]; +} + +/* + * Admittedly that this method is called just after the instantiation of this class, we set the shcselector's default values + */ +void DiagonalCurveEditor::setRangeDefaultMilestones(double m1, double m2, double m3) { + rangeMilestones[0] = m1; + rangeMilestones[1] = m2; + rangeMilestones[2] = m3; + + paramCurveEd.at(1) = m1; + paramCurveEd.at(2) = m2; + paramCurveEd.at(3) = m3; +} + +void DiagonalCurveEditor::getRangeDefaultMilestones(double &m1, double &m2, double &m3) { + m1 = rangeMilestones[0]; + m2 = rangeMilestones[1]; + m3 = rangeMilestones[2]; +} + +FlatCurveEditor::FlatCurveEditor (Glib::ustring text, CurveEditorGroup* ceGroup, CurveEditorSubGroup* ceSubGroup, bool isPeriodic) : CurveEditor::CurveEditor(text, static_cast(ceGroup), ceSubGroup) { + + periodic = isPeriodic; + identityValue = 0.5; + + // Order set in the same order than "enum FlatCurveType". Shouldn't change, for compatibility reason + curveType->addEntry("curveType-flatLinear.png", M("CURVEEDITOR_LINEAR")); // 0 Linear + curveType->addEntry("curveType-controlPoints.png", M("CURVEEDITOR_MINMAXCPOINTS")); // 1 Min/Max ControlPoints + curveType->setSelected(FCT_Linear); + curveType->show(); +} + +std::vector FlatCurveEditor::getCurve () { + std::vector curve; + + switch (selected) { + //case (Parametric): + // return curve = paramCurveEd; + case (FCT_MinMaxCPoints): + return curve = controlPointsCurveEd; + default: + // returning Linear or Unchanged + curve.push_back((double)(selected)); + return curve; + } +} + +void FlatCurveEditor::setResetCurve(FlatCurveType cType, const std::vector &resetCurve) { + switch (cType) { + case (FCT_MinMaxCPoints): + if (resetCurve.size() && FlatCurveType(resetCurve.at(0)) == cType) + controlPointsResetCurve = resetCurve; + break; + default: + break; + } +} + +/* + * CurveEditor (CurveEditorGroup* ceGroup, Glib::ustring text) + * + * parameters: + * ceGroup = NULL or the address of the Widget that will receive the CurveTypeToggleButton + * text = (optional) label of the curve, displayed in the CurveTypeToggleButton, next to the image + */ +CurveEditor::CurveEditor (Glib::ustring text, CurveEditorGroup* ceGroup, CurveEditorSubGroup* ceSubGroup) : EditSubscriber(ET_PIPETTE) { + + bgHistValid = false; + remoteDrag = false; + selected = DCT_Linear; + bottomBarCP = NULL; + leftBarCP = NULL; + curveCP = NULL; + relatedWidget = NULL; + + group = ceGroup; + subGroup = ceSubGroup; + + if (group && text.size()) + curveType = new PopUpToggleButton(text + ":"); + else + curveType = new PopUpToggleButton(); + + curveType->set_tooltip_text(M("CURVEEDITOR_TYPE")); + // TODO: Does this signal have to be blocked when on curve type change ? + curveType->signal_toggled().connect ( sigc::mem_fun(*this, &CurveEditor::curveTypeToggled) ); + typeconn = curveType->signal_changed().connect (sigc::mem_fun(*this, &CurveEditor::typeSelectionChanged) ); +} + +void CurveEditor::setCurve (const std::vector& p) { + tempCurve = p; + group->setCurveExternal(this, p); +} + +CurveEditor::~CurveEditor () { + delete curveType; +} + +void CurveEditor::typeSelectionChanged (int n) { + group->typeSelectionChanged(this, n); +} + +void CurveEditor::curveTypeToggled() { + group->curveTypeToggled(this); +} + +bool CurveEditor::isUnChanged () { + return curveType->getSelected()==subGroup->getValUnchanged(); +} + +void CurveEditor::setUnChanged (bool uc) { + group->setUnChanged(uc, this); +} + +/* + * Update the backgrounds histograms + */ +void CurveEditor::updateBackgroundHistogram (LUTu & hist) { + // Copy the histogram in the curve editor cache + if (hist) { + histogram=hist; + bgHistValid = true; + } + else + bgHistValid = false; + + // Then call the curve editor group to eventually update the histogram + subGroup->updateBackgroundHistogram (this); +} + +// Open up the curve if it has modifications and it's not already opened +// Returns: true if curve was non linear and opened +bool CurveEditor::openIfNonlinear() { + + bool nonLinear = tempCurve.size() && (tempCurve[0] > subGroup->getValLinear()) && (tempCurve[0] < subGroup->getValUnchanged()); + + if (nonLinear && !curveType->get_active()) { + // Will trigger the signal_clicked event doing the display + curveType->set_active( true ); + } + + return nonLinear; +} + +// Handles markup tooltips +void CurveEditor::setTooltip(Glib::ustring ttip) { + curveType->set_tooltip_text(ttip.empty() ? + Glib::ustring::compose("%1 ", M("CURVEEDITOR_TYPE")) : + Glib::ustring::compose("%1\n%2", ttip, M("CURVEEDITOR_TYPE"))); +} + +void CurveEditor::setLeftBarColorProvider(ColorProvider* cp, int callerId) { + leftBarCP = cp; + leftBarCId = callerId; +} + +void CurveEditor::setBottomBarColorProvider(ColorProvider* cp, int callerId) { + bottomBarCP = cp; + bottomBarCId = callerId; +} + +void CurveEditor::setLeftBarBgGradient (const std::vector &milestones) { + leftBarBgGradient = milestones; +} + +void CurveEditor::setBottomBarBgGradient (const std::vector &milestones) { + bottomBarBgGradient = milestones; +} + +void CurveEditor::refresh () { + subGroup->refresh(this); +} + +void CurveEditor::setCurveColorProvider(ColorProvider* cp, int callerId) { + curveCP = cp; + curveCId = callerId; +} + +ColorProvider* CurveEditor::getLeftBarColorProvider() { + return leftBarCP; +} + +ColorProvider* CurveEditor::getBottomBarColorProvider() { + return bottomBarCP; +} + +ColorProvider* CurveEditor::getCurveColorProvider() { + return curveCP; +} + +int CurveEditor::getLeftBarCallerId() { + return leftBarCId; +} + +int CurveEditor::getBottomBarCallerId() { + return bottomBarCId; +} + +int CurveEditor::getCurveCallerId() { + return curveCId; +} + +std::vector CurveEditor::getBottomBarBgGradient () const { + return bottomBarBgGradient; +} + +std::vector CurveEditor::getLeftBarBgGradient () const { + return leftBarBgGradient; +} + +sigc::signal CurveEditor::signal_curvegraph_enter() { + return sig_curvegraph_enter; +} + +sigc::signal CurveEditor::signal_curvegraph_leave() { + return sig_curvegraph_leave; +} + +sigc::signal CurveEditor::signal_curvepoint_click() { + return sig_curvepoint_click; +} + +sigc::signal CurveEditor::signal_curvepoint_release() { + return sig_curvepoint_release; +} + +void CurveEditor::switchOffEditMode () { + if (EditSubscriber::getEditID() != EUID_None) { + // switching off the toggle button + if (group->displayedCurve == this) { + subGroup->editModeSwitchedOff(); + } + } + EditSubscriber::switchOffEditMode(); // disconnect +} + +bool CurveEditor::mouseOver(int modifierKey) { + EditDataProvider* provider = getEditProvider(); + subGroup->pipetteMouseOver(provider, modifierKey); + subGroup->refresh(this); + return true; // return true will ask the preview to be redrawn, for the cursor +} + +bool CurveEditor::button1Pressed(int modifierKey) { + EditDataProvider* provider = getEditProvider(); + if (provider->object) { + subGroup->pipetteButton1Pressed(provider, modifierKey); + remoteDrag = true; + } + subGroup->refresh(this); + return true; +} + +bool CurveEditor::button1Released() { + EditDataProvider* provider = getEditProvider(); + subGroup->pipetteButton1Released(provider); + remoteDrag = false; + subGroup->refresh(this); + return true; +} + +bool CurveEditor::drag(int modifierKey) { + EditDataProvider* provider = getEditProvider(); + subGroup->pipetteDrag(provider, modifierKey); + subGroup->refresh(this); + return false; +} + +CursorShape CurveEditor::getCursor(int objectID) { + if (remoteDrag) + return CSResizeHeight; + return CSOpenHand; +} diff --git a/rtgui/curveeditor.h b/rtgui/curveeditor.h new file mode 100644 index 000000000..45ef69cc3 --- /dev/null +++ b/rtgui/curveeditor.h @@ -0,0 +1,196 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _CURVEEDITOR_ +#define _CURVEEDITOR_ + +#include "popuptogglebutton.h" +#include "../rtengine/LUT.h" +#include "coloredbar.h" +#include "edit.h" +#include "mydiagonalcurve.h" +#include "myflatcurve.h" + +class CurveEditorGroup; +class CurveEditorSubGroup; + + +/* + *********************** Curve Editor *********************** + */ + + +/* + * This class is an interface between RT and the curve editor group ; it handles the methods + * related to a specific curve. It is created by CurveEditorGroup::addCurve + */ +class CurveEditor : public EditSubscriber { + + friend class CurveEditorGroup; + friend class CurveEditorSubGroup; + friend class DiagonalCurveEditorSubGroup; + friend class FlatCurveEditorSubGroup; + friend class DiagonalCurveEditor; + friend class FlatCurveEditor; + + protected: + + /* + * The curve editor contains only one widget (the curve type button) to receive the signals + * but it's co-handled by the CurveEditorGroup too + */ + + PopUpToggleButton* curveType; + LUTu histogram; // histogram values + bool bgHistValid; + + bool remoteDrag; + + int selected; + + CurveEditorGroup* group; + CurveEditorSubGroup* subGroup; + Gtk::Widget* relatedWidget; + + std::vector tempCurve; + sigc::connection typeconn; + + ColorProvider* bottomBarCP; + ColorProvider* leftBarCP; + ColorProvider* curveCP; + int bottomBarCId; + int leftBarCId; + int curveCId; + std::vector bottomBarBgGradient; + std::vector leftBarBgGradient; + + sigc::signal sig_curvegraph_enter; + sigc::signal sig_curvegraph_leave; + sigc::signal sig_curvepoint_click; + sigc::signal sig_curvepoint_release; + + public: + + CurveEditor (Glib::ustring text, CurveEditorGroup* ceGroup, CurveEditorSubGroup* ceSubGroup); + virtual ~CurveEditor (); + void typeSelectionChanged (int n); + void curveTypeToggled(); + bool isUnChanged (); + void setUnChanged (bool uc); + void updateBackgroundHistogram (LUTu & hist); + + void setLeftBarColorProvider(ColorProvider* cp, int callerId); + void setBottomBarColorProvider(ColorProvider* cp, int callerId); + void setCurveColorProvider(ColorProvider* cp, int callerId); + void setBottomBarBgGradient (const std::vector &milestones); + void setLeftBarBgGradient (const std::vector &milestones); + ColorProvider* getLeftBarColorProvider(); + ColorProvider* getBottomBarColorProvider(); + ColorProvider* getCurveColorProvider(); + int getLeftBarCallerId(); + int getBottomBarCallerId(); + int getCurveCallerId(); + std::vector getBottomBarBgGradient () const; + std::vector getLeftBarBgGradient () const; + + void refresh (); // refresh the display of the CurveEditor (e.g. when a ColoredBar has been changed from the outside) + bool openIfNonlinear(); // Open up the curve if it has modifications and it's not already opened + + void setCurve (const std::vector& p); + virtual void setIdentityValue (const double iValue=0.5) {}; + virtual double getIdentityValue () { return 0.5; }; + virtual std::vector getCurve () = 0; + bool reset(); + void setTooltip(Glib::ustring ttip); + + sigc::signal signal_curvegraph_enter(); + sigc::signal signal_curvegraph_leave(); + sigc::signal signal_curvepoint_click(); + sigc::signal signal_curvepoint_release(); + + void switchOffEditMode (); + bool mouseOver(int modifierKey); + bool button1Pressed(int modifierKey); + bool button1Released(); + bool drag(int modifierKey); + CursorShape getCursor(int objectID); + + +}; + + +/* + ******************** Diagonal Curve Editor ******************** + */ + + +class DiagonalCurveEditor : public CurveEditor { + + friend class DiagonalCurveEditorSubGroup; + + protected: + // reflects the buttonType active selection ; used as a pre-'selectionChange' reminder value + std::vector customCurveEd; + std::vector customResetCurve; + std::vector paramCurveEd; + std::vector paramResetCurve; + std::vector NURBSCurveEd; + std::vector NURBSResetCurve; + Glib::ustring rangeLabels[4]; + double rangeMilestones[3]; + + public: + DiagonalCurveEditor (Glib::ustring text, CurveEditorGroup* ceGroup, CurveEditorSubGroup* ceSubGroup); + std::vector getCurve (); + void setRangeLabels(Glib::ustring r1, Glib::ustring r2, Glib::ustring r3, Glib::ustring r4); + void getRangeLabels(Glib::ustring &r1, Glib::ustring &r2, Glib::ustring &r3, Glib::ustring &r4); + void setRangeDefaultMilestones(double m1, double m2, double m3); + void getRangeDefaultMilestones(double &m1, double &m2, double &m3); + + // set the reset curve for a given curve type. This is optional; all curve type have a default reset curve + void setResetCurve(DiagonalCurveType cType, const std::vector &resetCurve); +}; + + +/* + ********************** Flat Curve Editor ********************** + */ + + +class FlatCurveEditor : public CurveEditor { + + friend class FlatCurveEditorSubGroup; + + protected: + // reflects the buttonType active selection ; used as a pre-'selectionChange' reminder value + std::vector controlPointsCurveEd; + std::vector controlPointsResetCurve; + bool periodic; + double identityValue; + + public: + FlatCurveEditor (Glib::ustring text, CurveEditorGroup* ceGroup, CurveEditorSubGroup* ceSubGroup, bool isPeriodic = true); + virtual void setIdentityValue (const double iValue=0.5) { identityValue = iValue; } + virtual double getIdentityValue () { return identityValue; }; + std::vector getCurve (); + + // set the reset curve for a given curve type. This is optional; all curve type have a default reset curve + void setResetCurve(FlatCurveType cType, const std::vector &resetCurve); +}; + +#endif diff --git a/rtgui/curveeditorgroup.cc b/rtgui/curveeditorgroup.cc new file mode 100644 index 000000000..ae3c7d141 --- /dev/null +++ b/rtgui/curveeditorgroup.cc @@ -0,0 +1,434 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + * + * Class created by Jean-Christophe FRISCH, aka 'Hombre' + */ + +#include "curveeditor.h" +#include "curveeditorgroup.h" +#include "diagonalcurveeditorsubgroup.h" +#include "flatcurveeditorsubgroup.h" +#include "multilangmgr.h" +#include "../rtengine/safegtk.h" +#include "rtimage.h" + +CurveEditorGroup::CurveEditorGroup (Glib::ustring& curveDir, Glib::ustring groupLabel) : curveDir(curveDir), curve_reset(NULL), + displayedCurve(0), flatSubGroup(0), diagonalSubGroup(0), cl(NULL), numberOfPackedCurve(0) +{ + + // We set the label to the one provided as parameter, even if it's an empty string + curveGroupLabel = Gtk::manage (new Gtk::Label (groupLabel+":", Gtk::ALIGN_LEFT)); +} + +CurveEditorGroup::~CurveEditorGroup() { + for (std::vector::iterator i = curveEditors.begin(); i != curveEditors.end(); ++i) + { + delete *i; + } + delete flatSubGroup; + delete diagonalSubGroup; +} + +void CurveEditorGroup::hideCurrentCurve() { + // Setting the curve type to 'Unchanged' hide the CurveEditor + if (diagonalSubGroup) + diagonalSubGroup->stopNumericalAdjustment(); + if (flatSubGroup) + flatSubGroup->stopNumericalAdjustment(); + if (displayedCurve) + displayedCurve->curveType->set_active(false); +} + +/* + * Add a new curve to the curves list + * + * Parameters: + * cType: enum saying which kind of curve type has to be created + * curveLabel: Name of the curve that will be inserted in the toggle button, before the image. + * If empty, no text will prepend the image + * relatedWidget: pointer to a widget (or NULL) that will be inserted next to the curve's toggle button. + * if a smart pointer created by Gtk::manage is passed in, the widget will be deleted by the destructor, + * otherwise it'll have to be delete it manually + * periodic: for FlatCurve only, ask the curve to be periodic (default: True) + * + */ +CurveEditor* CurveEditorGroup::addCurve(CurveType cType, Glib::ustring curveLabel, Gtk::Widget *relatedWidget, bool periodic) { + switch (cType) { + case (CT_Diagonal): + { + if (!diagonalSubGroup) { + diagonalSubGroup = new DiagonalCurveEditorSubGroup(this, curveDir); + } + // We add it to the curve editor list + DiagonalCurveEditor* newCE = diagonalSubGroup->addCurve(curveLabel); + newCE->relatedWidget = relatedWidget; + curveEditors.push_back(newCE); + return (newCE); + } + case (CT_Flat): + { + if (!flatSubGroup) { + flatSubGroup = new FlatCurveEditorSubGroup(this, curveDir); + } + // We add it to the curve editor list + FlatCurveEditor* newCE = flatSubGroup->addCurve(curveLabel, periodic); + newCE->relatedWidget = relatedWidget; + curveEditors.push_back(newCE); + return (newCE); + } + default: + return (static_cast(NULL)); + break; + } + return NULL; // to avoid complains from Gcc +} + +/* + * Use this method to start a new line of button + */ +void CurveEditorGroup::newLine() { + Gtk::HBox* headerBox; + + if (curveEditors.size() > numberOfPackedCurve) { + headerBox = Gtk::manage (new Gtk::HBox ()); + + if (!numberOfPackedCurve) { + headerBox->pack_start(*curveGroupLabel, Gtk::PACK_SHRINK, 2); + + curve_reset = Gtk::manage (new Gtk::Button ()); + curve_reset->add (*Gtk::manage (new RTImage ("gtk-undo-ltr-small.png", "gtk-undo-rtl-small.png"))); + curve_reset->set_relief (Gtk::RELIEF_NONE); + curve_reset->set_border_width (0); + curve_reset->set_tooltip_text (M("CURVEEDITOR_TOOLTIPLINEAR")); + curve_reset->signal_clicked().connect( sigc::mem_fun(*this, &CurveEditorGroup::curveResetPressed) ); + + headerBox->pack_end (*curve_reset, Gtk::PACK_SHRINK, 0); + } + + int j = numberOfPackedCurve; + bool hasRelatedWidget = false; + for (int i = (int)(curveEditors.size())-1; i >= j; i--) { + if (curveEditors[i]->relatedWidget != NULL) + hasRelatedWidget = true; + } + for (int i = (int)(curveEditors.size())-1; i >= j; i--) { + if (curveEditors[i]->relatedWidget != NULL) + headerBox->pack_end (*curveEditors[i]->relatedWidget, Gtk::PACK_EXPAND_WIDGET, 2); + headerBox->pack_end (*curveEditors[i]->curveType->buttonGroup, hasRelatedWidget ? Gtk::PACK_SHRINK : Gtk::PACK_EXPAND_WIDGET, 2); + numberOfPackedCurve++; + } + + pack_start (*headerBox, Gtk::PACK_SHRINK, 2); + } + + +} + +/* + * Create all the widgets now that the curve list is complete + * This method should handle all curve number correctly, i.e. eventually display the curve type buttons + * in a grid (or table) + */ +void CurveEditorGroup::curveListComplete() { + newLine(); + + // We check the length of the label ; if it contains only one char (':'), we set it to the right default string + if (curveGroupLabel->get_label().size()==1) + curveGroupLabel->set_label(M(curveEditors.size() > 1 ? "CURVEEDITOR_CURVES" : "CURVEEDITOR_CURVE") + ":"); + + if (curveEditors.size() > 1) + cl->setMulti(true); +} + +/* + * Callback method used when a curve type button has changed ; + * it will activate the button, and so emit 'signal_toggled' (-> curveTypeToggled here under) + */ +void CurveEditorGroup::typeSelectionChanged (CurveEditor* ce, int n) { + // Same type : do nothing + if (ce==displayedCurve && n==(int)ce->selected) + return; + + if (nsubGroup->valUnchanged) + ce->selected = n; + + // The user selected a new type from a toggled off button + if (ce!=displayedCurve) + // We toggle off the other curve: it will emit the toggle off signal + hideCurrentCurve(); + + // If the button was not pressed before + if (!ce->curveType->get_active()) { + ce->subGroup->storeDisplayedCurve(); + // We set it pressed : it will emit the toggle on signal and update the GUI + ce->curveType->set_active( n>ce->subGroup->valLinear && nsubGroup->valUnchanged ); + if (n==ce->subGroup->valLinear || n==ce->subGroup->valUnchanged) { + // Since we do not activate the curve when the user switch the toggled off button to 'Linear', we have to + // to call the curve listener manually, because 'curveChanged' uses displayedCurve... + if (cl) { + if (cl->isMulti()) + cl->curveChanged (ce); + else + cl->curveChanged (); + } + } + else + curveChanged (); + } + else { + // The button is already pressed so we switch the GUI ourselves + ce->subGroup->switchGUI(); + curveChanged (); + } +} + +/* + * Callback method used when a button has been toggled on/off + * It then hide any other displayed curve and display it's curve + */ +void CurveEditorGroup::curveTypeToggled(CurveEditor* ce) { + bool curveRestored = false; + + if (displayedCurve) { + EditDataProvider* editProvider = displayedCurve->getEditProvider(); + if (editProvider && editProvider->getCurrSubscriber() == displayedCurve) + displayedCurve->switchOffEditMode(); + } + + // Looking for the button state + if (ce->curveType->get_active()) { + // The button is now pressed, so we have to first hide all other CurveEditor + hideCurrentCurve(); + + displayedCurve = ce; + + if (ce->curveType->getSelected()==ce->subGroup->valUnchanged) { + curveRestored = true; + ce->curveType->setSelected(ce->selected); + } + + // then show this CurveEditor + int ct = ce->curveType->getSelected(); + if (ct < ce->subGroup->valUnchanged) + ce->subGroup->restoreDisplayedHistogram(); + } + else { + // The button is now released, so we have to hide this CurveEditor + displayedCurve = 0; + } + ce->subGroup->switchGUI(); + + if (curveRestored) + curveChanged (); + +} + +/* + * Update the GUI if the given curveEditor is currently displayed + */ +void CurveEditorGroup::updateGUI (CurveEditor* ce) { + if (!ce) { + return; + } + + // we update the curve type button to the corresponding curve type, only if it is not currently set to 'Unchanged' + if (ce->curveType->getSelected()subGroup->valUnchanged) + ce->curveType->setSelected(ce->selected); + + // if not displayed or "unchanged" is selected, do not change gui + if (ce==displayedCurve && ce->curveType->getSelected()subGroup->valUnchanged) { + ce->subGroup->switchGUI(); + } +} + +/* + * Called from the outside to set the curve type & values + */ +void CurveEditorGroup::setCurveExternal (CurveEditor* ce, const std::vector& c) { + if (!c.empty()) { + ce->subGroup->storeCurveValues(ce, c); // The new curve is saved in the CurveEditor + (ce)->selected = c[0]; // We set the selected curve type in the CurveEditor to the one of the specified curve + } + updateGUI(static_cast(ce)); // And we update the GUI if necessary +} + +/* + * Listener called when the user has modified the curve + */ +void CurveEditorGroup::curveChanged () { + + displayedCurve->subGroup->storeDisplayedCurve(); + if (cl) { + if (cl->isMulti()) + cl->curveChanged (displayedCurve); + else + cl->curveChanged (); + } +} + +/* + * Listener called when the user has modified the curve + */ +float CurveEditorGroup::blendPipetteValues (CurveEditor* ce, float chan1, float chan2, float chan3) { + + if (cl) + return cl->blendPipetteValues(ce, chan1, chan2, chan3); + + return -1.f; +} + +/* + * Call back method when the reset button is pressed : + * reset the currently toggled on curve editor + */ +void CurveEditorGroup::curveResetPressed () { + if (displayedCurve) { + if (displayedCurve->subGroup->curveReset(displayedCurve)) { + curveChanged(); + } + } +} + +/* + * Set the tooltip text of the label of the curve group + */ +void CurveEditorGroup::setTooltip( Glib::ustring ttip) { + curveGroupLabel->set_tooltip_text( ttip ); +} + +void CurveEditorGroup::setBatchMode (bool batchMode) { + for (std::vector::iterator i = curveEditors.begin(); i != curveEditors.end(); ++i) { + (*i)->curveType->addEntry("curveType-unchanged.png", M("GENERAL_UNCHANGED")); + (*i)->curveType->show(); + } +} + +void CurveEditorGroup::setUnChanged (bool uc, CurveEditor* ce) { + if (uc) { + // the user selected several thumbnails, so we hide the editors and set the curveEditor selection to 'Unchanged' + //ce->typeconn.block(true); + // we hide the editor widgets + hideCurrentCurve(); + // the curve type selected option is set to unchanged + ce->curveType->setSelected(ce->subGroup->valUnchanged); + //ce->typeconn.block(false); + } + else { + // we want it to use back the 'CurveEditor::setCurve' memorized in CurveEditor::tempCurve + //ce->typeconn.block(true); + // we switch back the curve type selected option to the one of the used curve + ce->curveType->setSelected(ce->selected); + updateGUI (ce); + //ce->typeconn.block(false); + } +} + +CurveEditorSubGroup::CurveEditorSubGroup(Glib::ustring& curveDir) : curveDir(curveDir), lastFilename("") { + leftBar = NULL; + bottomBar = NULL; +} + +CurveEditorSubGroup::~CurveEditorSubGroup() { + if (leftBar) delete leftBar; + if (bottomBar) delete bottomBar; +} + +void CurveEditorSubGroup::updateEditButton(CurveEditor* curve, Gtk::ToggleButton *button, sigc::connection &connection) { + if (!curve->getEditProvider() || curve->getEditID() == EUID_None) { + button->hide(); + } + else { + button->show(); + bool prevstate = connection.block(true); + if (curve->isCurrentSubscriber()) + button->set_active(true); + else + button->set_active(false); + if (!prevstate) connection.block(false); + } +} + +Glib::ustring CurveEditorSubGroup::outputFile () { + + Gtk::FileChooserDialog dialog(M("CURVEEDITOR_SAVEDLGLABEL"), Gtk::FILE_CHOOSER_ACTION_SAVE); + FileChooserLastFolderPersister persister(&dialog, curveDir); + dialog.set_current_name (lastFilename); + + dialog.add_button(Gtk::StockID("gtk-cancel"), Gtk::RESPONSE_CANCEL); + dialog.add_button(Gtk::StockID("gtk-save"), Gtk::RESPONSE_APPLY); + + Gtk::FileFilter filter_pp; + filter_pp.set_name(M("FILECHOOSER_FILTER_CURVE")); + filter_pp.add_pattern("*.rtc"); + dialog.add_filter(filter_pp); + + Gtk::FileFilter filter_any; + filter_any.set_name(M("FILECHOOSER_FILTER_ANY")); + filter_any.add_pattern("*"); + dialog.add_filter(filter_any); + + //dialog.set_do_overwrite_confirmation (true); + + Glib::ustring fname; + do { + if (dialog.run() == Gtk::RESPONSE_APPLY) { + fname = dialog.get_filename(); + if (getExtension (fname) != "rtc") + fname += ".rtc"; + if (confirmOverwrite (dialog, fname)) { + lastFilename = Glib::path_get_basename (fname); + break; + } + } else { + fname = ""; + break; + } + } while (1); + + return fname; +} + +Glib::ustring CurveEditorSubGroup::inputFile () { + + Gtk::FileChooserDialog dialog(M("CURVEEDITOR_LOADDLGLABEL"), Gtk::FILE_CHOOSER_ACTION_OPEN); + FileChooserLastFolderPersister persister(&dialog, curveDir); + + dialog.add_button(Gtk::StockID("gtk-cancel"), Gtk::RESPONSE_CANCEL); + dialog.add_button(Gtk::StockID("gtk-apply"), Gtk::RESPONSE_APPLY); + + Gtk::FileFilter filter_pp; + filter_pp.set_name(M("FILECHOOSER_FILTER_CURVE")); + filter_pp.add_pattern("*.rtc"); + dialog.add_filter(filter_pp); + + Gtk::FileFilter filter_any; + filter_any.set_name(M("FILECHOOSER_FILTER_ANY")); + filter_any.add_pattern("*"); + dialog.add_filter(filter_any); + + int result = dialog.run(); + + Glib::ustring fname; + if (result==Gtk::RESPONSE_APPLY) { + fname = dialog.get_filename(); + if (Glib::file_test (fname, Glib::FILE_TEST_EXISTS)) + return fname; + } + fname = ""; + return fname; +} diff --git a/rtgui/curveeditorgroup.h b/rtgui/curveeditorgroup.h new file mode 100644 index 000000000..8367d3b32 --- /dev/null +++ b/rtgui/curveeditorgroup.h @@ -0,0 +1,156 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _CURVEEDITORGROUP_ +#define _CURVEEDITORGROUP_ + +#include +#include +#include +#include "guiutils.h" +#include "mycurve.h" +#include "myflatcurve.h" +#include "mydiagonalcurve.h" +#include "shcselector.h" +#include "adjuster.h" + +class CurveEditor; +class DiagonalCurveEditorSubGroup; +class FlatCurveEditorSubGroup; + +/* + * This class handle the curve widgets, shared between any number curve + * - to add a curve to the list, use the 'addCurve' method + * - to start a new line of curve button, use the 'newLine' method + * - if you add more than one curve, you must add a "CurveEditor* ce" parameter to your listener + */ +class CurveEditorGroup : public Gtk::VBox, public CurveListener { + + friend class CurveEditor; + friend class CurveEditorSubGroup; + friend class DiagonalCurveEditorSubGroup; + friend class FlatCurveEditorSubGroup; + +private: + Glib::ustring& curveDir; + +protected: + Gtk::Label* curveGroupLabel; + Gtk::Button* curve_reset; + std::vector curveEditors; + CurveEditor* displayedCurve; + FlatCurveEditorSubGroup* flatSubGroup; + DiagonalCurveEditorSubGroup* diagonalSubGroup; + + CurveListener* cl; + + unsigned int numberOfPackedCurve; + +public: + /** + * @param curveDir The folder used by load and save dialogs for the curve. + * This variable will be updated with actions in the + * dialogs. + */ + + CurveEditorGroup(Glib::ustring& curveDir, Glib::ustring groupLabel = ""); + ~CurveEditorGroup(); + void newLine(); + void curveListComplete(); + void setBatchMode (bool batchMode); + void setCurveExternal (CurveEditor* ce, const std::vector& c); + void setCurveListener (CurveListener* l) { cl = l; } + void setTooltip (Glib::ustring ttip); + CurveEditor* getDisplayedCurve () { return displayedCurve; } + //void on_realize (); + CurveEditor* addCurve(CurveType cType, Glib::ustring curveLabel, Gtk::Widget *relatedWidget=NULL, bool periodic=true); + +protected: + //void curveTypeToggled (); + void curveTypeToggled (CurveEditor* ce); + //void typeSelectionChanged (int n); + void typeSelectionChanged (CurveEditor* ce, int n); + void hideCurrentCurve (); + void updateGUI (CurveEditor* ce); + void curveResetPressed (); + void curveChanged (); + float blendPipetteValues(CurveEditor* ce, float chan1, float chan2, float chan3); + void setUnChanged (bool uc, CurveEditor* ce); +}; + +class CoordinateProvider; + +class CurveEditorSubGroup { + + friend class CurveEditorGroup; + +private: + Glib::ustring& curveDir; + Glib::ustring lastFilename; + +protected: + int valLinear; + int valUnchanged; + CurveEditorGroup *parent; + int curveBBoxPos; // 0=above, 1=right, 2=below, 3=left + + ColoredBar* leftBar; + ColoredBar* bottomBar; + + +public: + virtual ~CurveEditorSubGroup(); + int getValUnchanged() { return valUnchanged; } + int getValLinear() { return valLinear; } + void updateEditButton(CurveEditor* curve, Gtk::ToggleButton *button, sigc::connection &connection); + virtual void updateBackgroundHistogram (CurveEditor* ce) {} + virtual void switchGUI() = 0; + virtual void refresh(CurveEditor *curveToRefresh) = 0; + virtual void editModeSwitchedOff() = 0; + + virtual void showCoordinateAdjuster(CoordinateProvider *provider) = 0; + virtual void stopNumericalAdjustment() = 0; + + virtual void pipetteMouseOver(EditDataProvider *provider, int modifierKey) =0; + virtual void pipetteButton1Pressed(EditDataProvider *provider, int modifierKey) =0; + virtual void pipetteButton1Released(EditDataProvider *provider) =0; + virtual void pipetteDrag(EditDataProvider *provider, int modifierKey) =0; + + virtual bool curveReset (CurveEditor *ce) = 0; // Reset a curve editor, return TRUE if successful (curve changed) + +protected: + + /** + * @param curveDir The folder used by load and save dialogs for the curve. + * This variable will be updated with actions in the + * dialogs. + */ + CurveEditorSubGroup(Glib::ustring& curveDir); + + Glib::ustring outputFile (); + Glib::ustring inputFile (); + + virtual void storeCurveValues (CurveEditor* ce, const std::vector& p) = 0; + virtual void storeDisplayedCurve () = 0; + virtual void restoreDisplayedHistogram() {}; + virtual void removeEditor () = 0; + virtual const std::vector getCurveFromGUI (int type) = 0; + +}; + +#endif diff --git a/rtgui/curvelistener.h b/rtgui/curvelistener.h new file mode 100644 index 000000000..682c98b29 --- /dev/null +++ b/rtgui/curvelistener.h @@ -0,0 +1,73 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _CURVELISTENER_ +#define _CURVELISTENER_ + +#include + +class CurveEditor; + +class CurveListener { + + private: + bool multi; + public: + CurveListener() : multi(false) {} + virtual ~CurveListener() {} + virtual void curveChanged () {} + virtual void curveChanged (CurveEditor* ce) {} + void setMulti(bool value) { multi = value; } + bool isMulti() { return multi; } + + /** @brief Ask the reset curve for a given curve type + * @param ce CurveEditor that we want to reset + * @param curve Actual curve for the return value. The actual curve type (given by the first value of the vector) + * should be kept the same. Change the curve type if REALLY necessary! */ + virtual bool getResetCurve(CurveEditor *ce, std::vector &curve) { return false; } + + /** @brief Blend pipette values from its different channels into a single value + If the buffer has more than one channel and one channel, this method will blend them together. + @param chan1 first channel's value + @param chan2 second channel's value + @param chan3 third channel's value + @return the blended value */ + virtual float blendPipetteValues(CurveEditor *ce, float chan1, float chan2, float chan3) { + float retVal = 0.f; + int n = 0; + if (chan1 != -1.f) { + retVal += chan1; + ++n; + } + if (chan2 != -1.f) { + retVal += chan2; + ++n; + } + if (chan3 != -1.f) { + retVal += chan3; + ++n; + } + if (n>1) + retVal /= n; + else if (!n) + retVal = -1.f; + return retVal; + } +}; + +#endif diff --git a/rtgui/darkframe.cc b/rtgui/darkframe.cc new file mode 100644 index 000000000..fb8f9787e --- /dev/null +++ b/rtgui/darkframe.cc @@ -0,0 +1,212 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "darkframe.h" +#include "options.h" +#include "guiutils.h" +#include "../rtengine/safegtk.h" +#include +#include "rtimage.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +DarkFrame::DarkFrame () : FoldableToolPanel(this, "darkframe", M("TP_DARKFRAME_LABEL")) +{ + hbdf = Gtk::manage(new Gtk::HBox()); + hbdf->set_spacing(4); + darkFrameFile = Gtk::manage(new MyFileChooserButton(M("TP_DARKFRAME_LABEL"), Gtk::FILE_CHOOSER_ACTION_OPEN)); + darkFrameFilePersister.reset(new FileChooserLastFolderPersister(darkFrameFile, options.lastDarkframeDir)); + dfLabel = Gtk::manage(new Gtk::Label(M("GENERAL_FILE"))); + btnReset = Gtk::manage(new Gtk::Button()); + btnReset->set_image (*Gtk::manage(new RTImage ("gtk-cancel.png"))); + hbdf->pack_start(*dfLabel, Gtk::PACK_SHRINK, 0); + hbdf->pack_start(*darkFrameFile); + hbdf->pack_start(*btnReset, Gtk::PACK_SHRINK, 0); + dfAuto = Gtk::manage(new Gtk::CheckButton((M("TP_DARKFRAME_AUTOSELECT")))); + dfInfo = Gtk::manage(new Gtk::Label("")); + dfInfo->set_alignment(0,0); //left align + + pack_start( *hbdf, Gtk::PACK_SHRINK, 0); + pack_start( *dfAuto, Gtk::PACK_SHRINK, 0); + 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); + btnReset->signal_clicked().connect( sigc::mem_fun(*this, &DarkFrame::darkFrameReset), true ); + + // Set filename filters + b_filter_asCurrent = false; + Gtk::FileFilter *filter_any = Gtk::manage(new Gtk::FileFilter); + filter_any->add_pattern("*"); + filter_any->set_name(M("FILECHOOSER_FILTER_ANY")); + darkFrameFile->add_filter (*filter_any); + + // filters for all supported non-raw extensions + for (size_t i=0; iadd_pattern("*." + options.parseExtensions[i]); + filter_df->add_pattern("*." + options.parseExtensions[i].uppercase()); + filter_df->set_name(options.parseExtensions[i].uppercase()); + darkFrameFile->add_filter (*filter_df); + //printf("adding filter %s \n",options.parseExtensions[i].uppercase().c_str()); + } + } +} + +void DarkFrame::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited) +{ + disableListener (); + dfautoconn.block(true); + + dfAuto->set_active( pp->raw.df_autoselect ); + + if(pedited ){ + dfAuto->set_inconsistent(!pedited->raw.dfAuto ); + } + if (safe_file_test (pp->raw.dark_frame, Glib::FILE_TEST_EXISTS)) + darkFrameFile->set_filename (pp->raw.dark_frame); + else + darkFrameReset(); + hbdf->set_sensitive( !pp->raw.df_autoselect ); + + lastDFauto = pp->raw.df_autoselect; + + if( pp->raw.df_autoselect && dfp && !multiImage){ + // retrieve the auto-selected df filename + rtengine::RawImage *img = dfp->getDF(); + if( img ){ + dfInfo->set_text( Glib::ustring::compose("%1: %2ISO %3s", Glib::path_get_basename(img->get_filename()), img->get_ISOspeed(), img->get_shutter()) ); + }else{ + dfInfo->set_text(Glib::ustring(M("TP_PREPROCESS_NO_FOUND"))); + } + } + else dfInfo->set_text(""); + + dfChanged = false; + + dfautoconn.block(false); + enableListener (); + + // Add filter with the current file extension if the current file is raw + if (dfp && !batchMode){ + + if (b_filter_asCurrent){ + //First, remove last filter_asCurrent if it was set for a raw file + std::vector filters = darkFrameFile->list_filters(); + darkFrameFile->remove_filter(**(filters.end()-1)); + b_filter_asCurrent = false; + } + + Glib::ustring fname = Glib::path_get_basename(dfp->GetCurrentImageFilePath()); + Glib::ustring filetype; + + if (fname!=""){ + // get image filetype, set filter to the same as current image's filetype + std::string::size_type idx; + idx = fname.rfind('.'); + if(idx != std::string::npos){ + filetype = fname.substr(idx+1); + israw = filetype.uppercase()!="JPG" && filetype.uppercase()!="JPEG" && filetype.uppercase()!="PNG" && filetype.uppercase()!="TIF" && filetype.uppercase()!="TIFF"; + + //exclude non-raw + if (israw) + { + b_filter_asCurrent = true; + Gtk::FileFilter *filter_asCurrent = Gtk::manage(new Gtk::FileFilter); + filter_asCurrent->add_pattern("*." + filetype); + filter_asCurrent->set_name(M("FILECHOOSER_FILTER_SAME") + " (" + filetype + ")"); + darkFrameFile->add_filter (*filter_asCurrent); + darkFrameFile->set_filter (*filter_asCurrent); + } + } + } + } + +} + +void DarkFrame::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pedited) +{ + pp->raw.dark_frame = darkFrameFile->get_filename(); + pp->raw.df_autoselect = dfAuto->get_active(); + + if (pedited) { + pedited->raw.darkFrame = dfChanged; + pedited->raw.dfAuto = !dfAuto->get_inconsistent(); + } + +} + +void DarkFrame::dfAutoChanged() +{ + if (batchMode) { + if (dfAuto->get_inconsistent()) { + dfAuto->set_inconsistent (false); + dfautoconn.block (true); + dfAuto->set_active (false); + dfautoconn.block (false); + } + else if (lastDFauto) + dfAuto->set_inconsistent (true); + + lastDFauto = dfAuto->get_active (); + } + + if(dfAuto->get_active() && dfp && !batchMode){ + // retrieve the auto-selected df filename + rtengine::RawImage *img = dfp->getDF(); + if( img ){ + dfInfo->set_text( Glib::ustring::compose("%1: %2ISO %3s", Glib::path_get_basename(img->get_filename()), img->get_ISOspeed(), img->get_shutter()) ); + }else{ + dfInfo->set_text(Glib::ustring(M("TP_PREPROCESS_NO_FOUND"))); + } + } + else{dfInfo->set_text("");} + + hbdf->set_sensitive( !dfAuto->get_active() ); + if (listener) + listener->panelChanged (EvPreProcessAutoDF, dfAuto->get_active()?M("GENERAL_ENABLED"):M("GENERAL_DISABLED")); +} + +void DarkFrame::darkFrameChanged() +{ + dfChanged=true; + if (listener) + listener->panelChanged (EvPreProcessDFFile, Glib::path_get_basename(darkFrameFile->get_filename())); +} + +void DarkFrame::darkFrameReset() +{ + dfChanged=true; + +// caution: I had to make this hack, because set_current_folder() doesn't work correctly! +// Because szeva doesn't exist since he was committed to happy hunting ground in Issue 316 +// we can use him now for this hack + darkFrameFile->set_filename (options.lastDarkframeDir + "/szeva"); +// end of the hack + + if (!options.lastDarkframeDir.empty()) + darkFrameFile->set_current_folder(options.lastDarkframeDir); + + dfInfo->set_text(""); + if (listener) + listener->panelChanged (EvPreProcessDFFile, M("GENERAL_NONE")); + +} diff --git a/rtgui/darkframe.h b/rtgui/darkframe.h new file mode 100755 index 000000000..92f475100 --- /dev/null +++ b/rtgui/darkframe.h @@ -0,0 +1,66 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _DARKFRAME_H_ +#define _DARKFRAME_H_ + +#include +#include +#include "toolpanel.h" +#include "../rtengine/rawimage.h" +#include "guiutils.h" + +class DFProvider { + public: + virtual rtengine::RawImage* getDF() = 0; + virtual Glib::ustring GetCurrentImageFilePath() = 0; + // add other info here +}; + +class DarkFrame : public ToolParamBlock, public FoldableToolPanel { + +protected: + + MyFileChooserButton *darkFrameFile; + std::auto_ptr darkFrameFilePersister; + Gtk::HBox *hbdf; + Gtk::Button *btnReset; + Gtk::Label *dfLabel; + Gtk::Label *dfInfo; + Gtk::CheckButton* dfAuto; + bool dfChanged; + bool lastDFauto; + DFProvider *dfp; + sigc::connection dfautoconn, dfFile; + bool b_filter_asCurrent; + bool israw; + +public: + + DarkFrame (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + + void darkFrameChanged (); + void darkFrameReset (); + void dfAutoChanged (); + void setDFProvider (DFProvider* p) { dfp = p; }; +}; + +#endif diff --git a/rtgui/defringe.cc b/rtgui/defringe.cc new file mode 100644 index 000000000..18c877249 --- /dev/null +++ b/rtgui/defringe.cc @@ -0,0 +1,171 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "defringe.h" +#include +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +Defringe::Defringe () : FoldableToolPanel(this, "defringe", M("TP_DEFRINGE_LABEL"), true, true) { + + std::vector bottomMilestones; + float R, G, B; + for (int i=0; i<7; i++) { + float x = float(i)*(1.0f/6.0); + Color::hsv2rgb01(x, 0.5f, 0.5f, R, G, B); + bottomMilestones.push_back( GradientMilestone(double(x), double(R), double(G), double(B)) ); + } + + setEnabledTooltipMarkup(M("TP_SHARPENING_TOOLTIP")); + + curveEditorPF = new CurveEditorGroup (options.lastPFCurvesDir); + curveEditorPF->setCurveListener (this); + chshape = static_cast(curveEditorPF->addCurve(CT_Flat, M("TP_PFCURVE_CURVEEDITOR_CH"))); + chshape->setTooltip(M("TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP")); + chshape->setIdentityValue(0.); + chshape->setBottomBarBgGradient(bottomMilestones); + chshape->setCurveColorProvider(this, 1); + + //edgConn = enabled->signal_toggled().connect( sigc::mem_fun(*this, &Defringe::edgeChanged) ); + + radius = Gtk::manage (new Adjuster (M("TP_DEFRINGE_RADIUS"), 0.5, 5.0, 0.1, 2.0)); + threshold = Gtk::manage (new Adjuster (M("TP_DEFRINGE_THRESHOLD"), 0, 100, 1, 13)); + radius->setAdjusterListener (this); + threshold->setAdjusterListener (this); + // radius->show(); + // threshold->show(); + + pack_start (*radius); + pack_start (*threshold); + curveEditorPF->curveListComplete(); + + pack_start (*curveEditorPF, Gtk::PACK_SHRINK, 4); + + show (); +} + +Defringe::~Defringe () { + delete curveEditorPF; +} + +void Defringe::colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller *caller) { + + float R, G, B; + + if (elemType==ColorCaller::CCET_VERTICAL_BAR) + valY = 0.5; + + if (callerId == 1) { // ch + Color::hsv2rgb01(float(valX), float(valY), 0.5f, R, G, B); + } + caller->ccRed = double(R); + caller->ccGreen = double(G); + caller->ccBlue = double(B); +} + +void Defringe::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + if (pedited) { + radius->setEditedState ( pedited->defringe.radius ? Edited : UnEdited); + threshold->setEditedState ( pedited->defringe.threshold ? Edited : UnEdited); + set_inconsistent (multiImage && !pedited->defringe.enabled); + chshape->setUnChanged (!pedited->defringe.huecurve); + } + + setEnabled(pp->defringe.enabled); + + radius->setValue (pp->defringe.radius); + threshold->setValue (pp->defringe.threshold); + chshape->setCurve (pp->defringe.huecurve); + + enableListener (); +} + + +void Defringe::autoOpenCurve () { + // WARNING: The following line won't work, since linear is a flat curve at 0. + // chshape->openIfNonlinear(); +} + +void Defringe::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->defringe.radius = radius->getValue (); + pp->defringe.threshold = (int)threshold->getValue (); + pp->defringe.enabled = getEnabled(); + pp->defringe.huecurve = chshape->getCurve (); + + if (pedited) { + pedited->defringe.radius = radius->getEditedState (); + pedited->defringe.threshold = threshold->getEditedState (); + pedited->defringe.enabled = !get_inconsistent(); + pedited->defringe.huecurve = !chshape->isUnChanged (); + } +} + +void Defringe::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + radius->setDefault (defParams->defringe.radius); + threshold->setDefault (defParams->defringe.threshold); + + if (pedited) { + radius->setDefaultEditedState (pedited->defringe.radius ? Edited : UnEdited); + threshold->setDefaultEditedState (pedited->defringe.threshold ? Edited : UnEdited); + } + else { + radius->setDefaultEditedState (Irrelevant); + threshold->setDefaultEditedState (Irrelevant); + } +} +void Defringe::curveChanged () { + + if (listener && getEnabled()) listener->panelChanged (EvPFCurve, M("HISTORY_CUSTOMCURVE")); +} + +void Defringe::adjusterChanged (Adjuster* a, double newval) { + + if (listener && getEnabled()) { + + if (a==radius) + listener->panelChanged (EvDefringeRadius, Glib::ustring::format (std::setw(2), std::fixed, std::setprecision(1), a->getValue())); + else if (a==threshold) + listener->panelChanged (EvDefringeThreshold, Glib::ustring::format ((int)a->getValue())); + } +} + +void Defringe::enabledChanged () { + + if (listener) { + if (get_inconsistent()) + listener->panelChanged (EvDefringeEnabled, M("GENERAL_UNCHANGED")); + else if (getEnabled()) + listener->panelChanged (EvDefringeEnabled, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvDefringeEnabled, M("GENERAL_DISABLED")); + } +} + +void Defringe::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + radius->showEditedCB (); + threshold->showEditedCB (); +} diff --git a/rtgui/defringe.h b/rtgui/defringe.h new file mode 100644 index 000000000..fb84e86c0 --- /dev/null +++ b/rtgui/defringe.h @@ -0,0 +1,57 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _DEFRINGE_H_ +#define _DEFRINGE_H_ + +#include +#include "adjuster.h" +#include "toolpanel.h" +#include "guiutils.h" +#include "curveeditor.h" +#include "curveeditorgroup.h" +#include "colorprovider.h" + +class Defringe : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public CurveListener, public ColorProvider{ + + protected: + CurveEditorGroup* curveEditorPF; + FlatCurveEditor* chshape; + + Adjuster* radius; + Adjuster* threshold; + bool edges; + + public: + + Defringe (); + ~Defringe (); + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + void autoOpenCurve (); + void curveChanged (); + + void adjusterChanged (Adjuster* a, double newval); + void enabledChanged (); + virtual void colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller* caller); + +}; + +#endif diff --git a/rtgui/diagonalcurveeditorsubgroup.cc b/rtgui/diagonalcurveeditorsubgroup.cc new file mode 100644 index 000000000..2091e5a9d --- /dev/null +++ b/rtgui/diagonalcurveeditorsubgroup.cc @@ -0,0 +1,1082 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "clipboard.h" +#include +#include +#include +#include "guiutils.h" +#include "multilangmgr.h" +#include "mycurve.h" +#include "shcselector.h" +#include "adjuster.h" +#include "mycurve.h" +#include "mydiagonalcurve.h" +#include "curveeditor.h" +#include "diagonalcurveeditorsubgroup.h" + +DiagonalCurveEditorSubGroup::DiagonalCurveEditorSubGroup (CurveEditorGroup* prt, Glib::ustring& curveDir) : CurveEditorSubGroup(curveDir) { + + editedAdjuster = NULL; + editedAdjusterValue = 0; + + curveBBoxPos = options.curvebboxpos; + + valLinear = (int)DCT_Linear; + valUnchanged = (int)DCT_Unchanged; + parent = prt; + + activeParamControl = -1; + + // custom curve + customCurveBox = new Gtk::VBox (); + customCurveBox->set_spacing(4); + Gtk::HBox* customCurveAndButtons = Gtk::manage (new Gtk::HBox ()); + customCurveAndButtons->set_spacing(4); + customCurve = Gtk::manage (new MyDiagonalCurve ()); + customCurve->set_size_request (GRAPH_SIZE+2*RADIUS, GRAPH_SIZE+2*RADIUS); + customCurve->setType (DCT_Spline); + + Gtk::Box* custombbox; // curvebboxpos 0=above, 1=right, 2=below, 3=left + if (options.curvebboxpos==1 || options.curvebboxpos==3) { + custombbox = Gtk::manage (new Gtk::VBox ()); + } else { + custombbox = Gtk::manage (new Gtk::HBox ()); + } + custombbox->set_spacing(4); + + pasteCustom = Gtk::manage (new Gtk::Button ()); + pasteCustom->add (*Gtk::manage (new RTImage ("edit-paste.png"))); + copyCustom = Gtk::manage (new Gtk::Button ()); + copyCustom->add (*Gtk::manage (new RTImage ("edit-copy.png"))); + saveCustom = Gtk::manage (new Gtk::Button ()); + saveCustom->add (*Gtk::manage (new RTImage ("gtk-save-large.png"))); + loadCustom = Gtk::manage (new Gtk::Button ()); + loadCustom->add (*Gtk::manage (new RTImage ("gtk-open.png"))); + editPointCustom = Gtk::manage (new Gtk::ToggleButton ()); + editPointCustom->add (*Gtk::manage (new RTImage ("gtk-edit.png"))); + editPointCustom->set_tooltip_text(M("CURVEEDITOR_EDITPOINT_HINT")); + editCustom = Gtk::manage (new Gtk::ToggleButton()); + editCustom->add (*Gtk::manage (new RTImage ("editmodehand.png"))); + editCustom->set_tooltip_text(M("EDIT_PIPETTE_TOOLTIP")); + editCustom->hide(); + + custombbox->pack_end (*pasteCustom, Gtk::PACK_SHRINK, 0); + custombbox->pack_end (*copyCustom, Gtk::PACK_SHRINK, 0); + custombbox->pack_end (*saveCustom, Gtk::PACK_SHRINK, 0); + custombbox->pack_end (*loadCustom, Gtk::PACK_SHRINK, 0); + custombbox->pack_start(*editPointCustom, Gtk::PACK_SHRINK, 0); + custombbox->pack_start(*editCustom, Gtk::PACK_SHRINK, 0); + + customCurveAndButtons->pack_start (*customCurve, Gtk::PACK_EXPAND_WIDGET, 0); + customCurveAndButtons->pack_start (*custombbox, Gtk::PACK_SHRINK, 0); + customCurveBox->pack_start (*customCurveAndButtons, Gtk::PACK_EXPAND_WIDGET); + if (options.curvebboxpos==0) { + removeIfThere (customCurveAndButtons, custombbox, false); + customCurveBox->pack_start (*custombbox); + customCurveBox->reorder_child(*custombbox, 0); + } else if (options.curvebboxpos==2) { + removeIfThere (customCurveAndButtons, custombbox, false); + customCurveBox->pack_start (*custombbox); + } else if (options.curvebboxpos==3) { + customCurveAndButtons->reorder_child(*custombbox, 0); + } + + customCoordAdjuster = Gtk::manage (new CoordinateAdjuster(customCurve, this)); + customCurveBox->pack_start(*customCoordAdjuster, Gtk::PACK_SHRINK, 0); + if (options.curvebboxpos == 2) + customCurveBox->reorder_child(*customCoordAdjuster, 2); + customCoordAdjuster->show_all(); + + customCurveBox->show_all (); + customCoordAdjuster->hide(); + + saveCustom->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::savePressed) ); + loadCustom->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::loadPressed) ); + copyCustom->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::copyPressed) ); + pasteCustom->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::pastePressed) ); + editPointCustomConn = editPointCustom->signal_toggled().connect( sigc::bind(sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::editPointToggled), editPointCustom) ); + editCustomConn = editCustom->signal_toggled().connect( sigc::bind(sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::editToggled), editCustom) ); + + saveCustom->set_tooltip_text (M("CURVEEDITOR_TOOLTIPSAVE")); + loadCustom->set_tooltip_text (M("CURVEEDITOR_TOOLTIPLOAD")); + copyCustom->set_tooltip_text (M("CURVEEDITOR_TOOLTIPCOPY")); + pasteCustom->set_tooltip_text (M("CURVEEDITOR_TOOLTIPPASTE")); + // Custom curve end + + + // NURBS curve + NURBSCurveBox = new Gtk::VBox (); + NURBSCurveBox->set_spacing(4); + Gtk::HBox* NURBSCurveAndButtons = Gtk::manage (new Gtk::HBox ()); + NURBSCurveAndButtons->set_spacing(4); + NURBSCurve = Gtk::manage (new MyDiagonalCurve ()); + NURBSCurve->set_size_request (GRAPH_SIZE+2*RADIUS, GRAPH_SIZE+2*RADIUS); + NURBSCurve->setType (DCT_NURBS); + + Gtk::Box* NURBSbbox; + if (options.curvebboxpos==1 || options.curvebboxpos==3) { + NURBSbbox = Gtk::manage (new Gtk::VBox ()); + } else { + NURBSbbox = Gtk::manage (new Gtk::HBox ()); + } + NURBSbbox->set_spacing(4); + + pasteNURBS = Gtk::manage (new Gtk::Button ()); + pasteNURBS->add (*Gtk::manage (new RTImage ("edit-paste.png"))); + copyNURBS = Gtk::manage (new Gtk::Button ()); + copyNURBS->add (*Gtk::manage (new RTImage ("edit-copy.png"))); + saveNURBS = Gtk::manage (new Gtk::Button ()); + saveNURBS->add (*Gtk::manage (new RTImage ("gtk-save-large.png"))); + loadNURBS = Gtk::manage (new Gtk::Button ()); + loadNURBS->add (*Gtk::manage (new RTImage ("gtk-open.png"))); + editPointNURBS = Gtk::manage (new Gtk::ToggleButton ()); + editPointNURBS->add (*Gtk::manage (new RTImage ("gtk-edit.png"))); + editPointNURBS->set_tooltip_text(M("CURVEEDITOR_EDITPOINT_HINT")); + editNURBS = Gtk::manage (new Gtk::ToggleButton()); + editNURBS->add (*Gtk::manage (new RTImage ("editmodehand.png"))); + editNURBS->set_tooltip_text(M("EDIT_PIPETTE_TOOLTIP")); + editNURBS->hide(); + NURBSbbox->pack_end (*pasteNURBS, Gtk::PACK_SHRINK, 0); + NURBSbbox->pack_end (*copyNURBS, Gtk::PACK_SHRINK, 0); + NURBSbbox->pack_end (*saveNURBS, Gtk::PACK_SHRINK, 0); + NURBSbbox->pack_end (*loadNURBS, Gtk::PACK_SHRINK, 0); + NURBSbbox->pack_start(*editPointNURBS, Gtk::PACK_SHRINK, 0); + NURBSbbox->pack_start(*editNURBS, Gtk::PACK_SHRINK, 0); + + NURBSCurveAndButtons->pack_start (*NURBSCurve, Gtk::PACK_EXPAND_WIDGET, 0); + NURBSCurveAndButtons->pack_start (*NURBSbbox, Gtk::PACK_SHRINK, 0); + NURBSCurveBox->pack_start (*NURBSCurveAndButtons, Gtk::PACK_EXPAND_WIDGET); + if (options.curvebboxpos==0) { + removeIfThere (NURBSCurveAndButtons, NURBSbbox, false); + NURBSCurveBox->pack_start (*NURBSbbox); + NURBSCurveBox->reorder_child(*NURBSbbox, 0); + } else if (options.curvebboxpos==2) { + removeIfThere (NURBSCurveAndButtons, NURBSbbox, false); + NURBSCurveBox->pack_start (*NURBSbbox); + } else if (options.curvebboxpos==3) { + NURBSCurveAndButtons->reorder_child(*NURBSbbox, 0); + } + + NURBSCoordAdjuster = Gtk::manage (new CoordinateAdjuster(NURBSCurve, this)); + NURBSCurveBox->pack_start(*NURBSCoordAdjuster, Gtk::PACK_SHRINK, 0); + if (options.curvebboxpos == 2) + NURBSCurveBox->reorder_child(*NURBSCoordAdjuster, 2); + NURBSCoordAdjuster->show_all(); + + NURBSCurveBox->show_all (); + NURBSCoordAdjuster->hide(); + + saveNURBS->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::savePressed) ); + loadNURBS->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::loadPressed) ); + pasteNURBS->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::pastePressed) ); + copyNURBS->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::copyPressed) ); + editPointNURBSConn = editPointNURBS->signal_toggled().connect( sigc::bind(sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::editPointToggled), editPointNURBS) ); + editNURBSConn = editNURBS->signal_toggled().connect( sigc::bind(sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::editToggled), editNURBS) ); + + saveNURBS->set_tooltip_text (M("CURVEEDITOR_TOOLTIPSAVE")); + loadNURBS->set_tooltip_text (M("CURVEEDITOR_TOOLTIPLOAD")); + pasteNURBS->set_tooltip_text (M("CURVEEDITOR_TOOLTIPPASTE")); + copyNURBS->set_tooltip_text (M("CURVEEDITOR_TOOLTIPCOPY")); + // NURBS curve end + + + // parametric curve + paramCurveBox = new Gtk::VBox (); + paramCurveBox->set_spacing(4); + Gtk::HBox* paramCurveAndButtons = Gtk::manage (new Gtk::HBox ()); + paramCurveAndButtons->set_spacing(4); + Gtk::VBox* paramCurveAndShcVBox = Gtk::manage (new Gtk::VBox ()); + paramCurve = Gtk::manage (new MyDiagonalCurve ()); + paramCurve->set_size_request (GRAPH_SIZE+2*RADIUS, GRAPH_SIZE+2*RADIUS); + paramCurve->setType (DCT_Parametric); + + Gtk::Box* parambbox; + if (options.curvebboxpos==1 || options.curvebboxpos==3) { + parambbox = Gtk::manage (new Gtk::VBox ()); + } else { + parambbox = Gtk::manage (new Gtk::HBox ()); + } + parambbox->set_spacing(4); + + shcSelector = Gtk::manage (new SHCSelector ()); + shcSelector->set_size_request (GRAPH_SIZE-100, 10); // width, height + //* shcSelector->set_size_request ((GRAPH_SIZE+2*RADIUS)-20, 20); + + pasteParam = Gtk::manage (new Gtk::Button ()); + pasteParam->add (*Gtk::manage (new RTImage ("edit-paste.png"))); + copyParam = Gtk::manage (new Gtk::Button ()); + copyParam->add (*Gtk::manage (new RTImage ("edit-copy.png"))); + saveParam = Gtk::manage (new Gtk::Button ()); + saveParam->add (*Gtk::manage (new RTImage ("gtk-save-large.png"))); + loadParam = Gtk::manage (new Gtk::Button ()); + loadParam->add (*Gtk::manage (new RTImage ("gtk-open.png"))); + editParam = Gtk::manage (new Gtk::ToggleButton()); + editParam->add (*Gtk::manage (new RTImage ("editmodehand.png"))); + editParam->set_tooltip_text(M("EDIT_PIPETTE_TOOLTIP")); + editParam->hide(); + parambbox->pack_end (*pasteParam, Gtk::PACK_SHRINK, 0); + parambbox->pack_end (*copyParam, Gtk::PACK_SHRINK, 0); + parambbox->pack_end (*saveParam, Gtk::PACK_SHRINK, 0); + parambbox->pack_end (*loadParam, Gtk::PACK_SHRINK, 0); + parambbox->pack_start(*editParam, Gtk::PACK_SHRINK, 0); + + saveParam->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::savePressed) ); + loadParam->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::loadPressed) ); + pasteParam->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::pastePressed) ); + copyParam->signal_clicked().connect( sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::copyPressed) ); + editParamConn = editParam->signal_toggled().connect( sigc::bind(sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::editToggled), editParam) ); + + saveParam->set_tooltip_text (M("CURVEEDITOR_TOOLTIPSAVE")); + loadParam->set_tooltip_text (M("CURVEEDITOR_TOOLTIPLOAD")); + pasteParam->set_tooltip_text (M("CURVEEDITOR_TOOLTIPPASTE")); + copyParam->set_tooltip_text (M("CURVEEDITOR_TOOLTIPCOPY")); + + highlights = Gtk::manage (new Adjuster (M("CURVEEDITOR_HIGHLIGHTS"), -100, 100, 1, 0)); + lights = Gtk::manage (new Adjuster (M("CURVEEDITOR_LIGHTS"), -100, 100, 1, 0)); + darks = Gtk::manage (new Adjuster (M("CURVEEDITOR_DARKS"), -100, 100, 1, 0)); + shadows = Gtk::manage (new Adjuster (M("CURVEEDITOR_SHADOWS"), -100, 100, 1, 0)); + + Gtk::EventBox* evhighlights = Gtk::manage (new Gtk::EventBox ()); + Gtk::EventBox* evlights = Gtk::manage (new Gtk::EventBox ()); + Gtk::EventBox* evdarks = Gtk::manage (new Gtk::EventBox ()); + Gtk::EventBox* evshadows = Gtk::manage (new Gtk::EventBox ()); + + evhighlights->add (*highlights); + evlights->add (*lights); + evdarks->add (*darks); + evshadows->add (*shadows); + + // paramCurveSliderBox needed to set vspacing(4) between curve+shc and sliders without vspacing between each slider + Gtk::VBox* paramCurveSliderBox = Gtk::manage (new Gtk::VBox ()); + paramCurveSliderBox->set_spacing(4); + + paramCurveSliderBox->pack_start (*evhighlights); + paramCurveSliderBox->pack_start (*evlights); + paramCurveSliderBox->pack_start (*evdarks); + paramCurveSliderBox->pack_start (*evshadows); + + paramCurveBox->show_all (); + + paramCurveAndShcVBox->pack_start (*paramCurve, Gtk::PACK_EXPAND_WIDGET); + paramCurveAndShcVBox->pack_start (*shcSelector, Gtk::PACK_EXPAND_WIDGET); + paramCurveAndButtons->pack_start (*paramCurveAndShcVBox); + paramCurveAndButtons->pack_start (*parambbox, Gtk::PACK_SHRINK); + paramCurveBox->pack_start (*paramCurveAndButtons); + paramCurveBox->pack_start (*paramCurveSliderBox); + if (options.curvebboxpos==0) { + removeIfThere (paramCurveAndButtons, parambbox, false); + paramCurveBox->pack_start (*parambbox); + paramCurveBox->reorder_child(*parambbox, 0); + } else if (options.curvebboxpos==2) { + removeIfThere (paramCurveAndButtons, parambbox, false); + paramCurveBox->pack_start (*parambbox); + //paramCurveBox->reorder_child(*parambbox, 1); + } else if (options.curvebboxpos==3) { + paramCurveAndButtons->reorder_child(*parambbox, 0); + } + paramCurveBox->show_all (); + // parametric curve end + + + customCurveBox->reference (); + paramCurveBox->reference (); + + customCurve->setCurveListener (parent); // Send the message directly to the parent + NURBSCurve->setCurveListener (parent); + paramCurve->setCurveListener (parent); + shcSelector->setSHCListener (this); + + highlights->setAdjusterListener (this); + lights->setAdjusterListener (this); + darks->setAdjusterListener (this); + shadows->setAdjusterListener (this); + + evhighlights->set_events(Gdk::ENTER_NOTIFY_MASK | Gdk::LEAVE_NOTIFY_MASK); + evlights->set_events(Gdk::ENTER_NOTIFY_MASK | Gdk::LEAVE_NOTIFY_MASK); + evdarks->set_events(Gdk::ENTER_NOTIFY_MASK | Gdk::LEAVE_NOTIFY_MASK); + evshadows->set_events(Gdk::ENTER_NOTIFY_MASK | Gdk::LEAVE_NOTIFY_MASK); + evhighlights->signal_enter_notify_event().connect (sigc::bind(sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::adjusterEntered), 4)); + evlights->signal_enter_notify_event().connect (sigc::bind(sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::adjusterEntered), 5)); + evdarks->signal_enter_notify_event().connect (sigc::bind(sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::adjusterEntered), 6)); + evshadows->signal_enter_notify_event().connect (sigc::bind(sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::adjusterEntered), 7)); + evhighlights->signal_leave_notify_event().connect (sigc::bind(sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::adjusterLeft), 4)); + evlights->signal_leave_notify_event().connect (sigc::bind(sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::adjusterLeft), 5)); + evdarks->signal_leave_notify_event().connect (sigc::bind(sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::adjusterLeft), 6)); + evshadows->signal_leave_notify_event().connect (sigc::bind(sigc::mem_fun(*this, &DiagonalCurveEditorSubGroup::adjusterLeft), 7)); +} + +DiagonalCurveEditorSubGroup::~DiagonalCurveEditorSubGroup() { + delete customCurveBox; + delete paramCurveBox; + delete NURBSCurveBox; +} + +/* + * Add a new curve to the curves list + */ +DiagonalCurveEditor* DiagonalCurveEditorSubGroup::addCurve(Glib::ustring curveLabel) { + DiagonalCurveEditor* newCE = new DiagonalCurveEditor(curveLabel, parent, this); + + // Initialization of the new curve + storeCurveValues(newCE, getCurveFromGUI(DCT_Spline)); + storeCurveValues(newCE, getCurveFromGUI(DCT_Parametric)); + storeCurveValues(newCE, getCurveFromGUI(DCT_NURBS)); + return newCE; +} + +/* + * Switch off the edit button + */ +void DiagonalCurveEditorSubGroup::editModeSwitchedOff () { + // toggling off all edit buttons, even if only one is toggle on + bool prevState; + prevState = editCustomConn.block(true); + editCustom->set_active(false); + customCurve->pipetteMouseOver(NULL, NULL, 0); + customCurve->setDirty(true); + if (!prevState) editCustomConn.block(false); + prevState = editNURBSConn.block(true); + editNURBS->set_active(false); + NURBSCurve->pipetteMouseOver(NULL, NULL, 0); + NURBSCurve->setDirty(true); + if (!prevState) editNURBSConn.block(false); + prevState = editParamConn.block(true); + editParam->set_active(false); + paramCurve->pipetteMouseOver(NULL, NULL, 0); + paramCurve->setDirty(true); + if (!prevState) editParamConn.block(false); +} + +void DiagonalCurveEditorSubGroup::pipetteMouseOver(EditDataProvider *provider, int modifierKey) { + CurveEditor *curveEditor = static_cast(parent->displayedCurve); + switch((DiagonalCurveType)(curveEditor->curveType->getSelected())) { + case (DCT_Spline): + customCurve->pipetteMouseOver(curveEditor, provider, modifierKey); + customCurve->setDirty(true); + break; + case (DCT_Parametric): + { + paramCurve->pipetteMouseOver(curveEditor, provider, modifierKey); + paramCurve->setDirty(true); + float pipetteVal = 0.f; + editedAdjuster = NULL; + int n = 0; + if (provider->pipetteVal[0] != -1.f) { + pipetteVal += provider->pipetteVal[0]; + ++n; + } + if (provider->pipetteVal[1] != -1.f) { + pipetteVal += provider->pipetteVal[1]; + ++n; + } + if (provider->pipetteVal[2] != -1.f) { + pipetteVal += provider->pipetteVal[2]; + ++n; + } + if (n>1) { + pipetteVal /= n; + } + else if (!n) + pipetteVal = -1.f; + + if (pipetteVal != -1.f) { + double pos[3]; + shcSelector->getPositions(pos[0], pos[1], pos[2]); + if (pipetteVal>=pos[2]) { + editedAdjuster = highlights; + paramCurve->setActiveParam(4); + } + else if(pipetteVal>=pos[1]) { + editedAdjuster = lights; + paramCurve->setActiveParam(5); + } + else if(pipetteVal>=pos[0]) { + editedAdjuster = darks; + paramCurve->setActiveParam(6); + } + else { + editedAdjuster = shadows; + paramCurve->setActiveParam(7); + } + } + else + paramCurve->setActiveParam(-1); + } + break; + case (DCT_NURBS): + NURBSCurve->pipetteMouseOver(curveEditor, provider, modifierKey); + NURBSCurve->setDirty(true); + break; + default: // (DCT_Linear, DCT_Unchanged) + // ... do nothing + break; + } +} + +void DiagonalCurveEditorSubGroup::pipetteButton1Pressed(EditDataProvider *provider, int modifierKey) { + CurveEditor *curveEditor = static_cast(parent->displayedCurve); + switch((DiagonalCurveType)(curveEditor->curveType->getSelected())) { + case (DCT_Spline): + customCurve->pipetteButton1Pressed(provider, modifierKey); + break; + case (DCT_Parametric): + if (editedAdjuster) + editedAdjusterValue = editedAdjuster->getIntValue(); + break; + case (DCT_NURBS): + NURBSCurve->pipetteButton1Pressed(provider, modifierKey); + break; + default: // (DCT_Linear, DCT_Unchanged) + // ... do nothing + break; + } +} + +void DiagonalCurveEditorSubGroup::pipetteButton1Released(EditDataProvider *provider) { + CurveEditor *curveEditor = static_cast(parent->displayedCurve); + switch((DiagonalCurveType)(curveEditor->curveType->getSelected())) { + case (DCT_Spline): + customCurve->pipetteButton1Released(provider); + break; + case (DCT_Parametric): + editedAdjuster = NULL; + break; + case (DCT_NURBS): + NURBSCurve->pipetteButton1Released(provider); + break; + default: // (DCT_Linear, DCT_Unchanged) + // ... do nothing + break; + } +} + +void DiagonalCurveEditorSubGroup::pipetteDrag(EditDataProvider *provider, int modifierKey) { + CurveEditor *curveEditor = static_cast(parent->displayedCurve); + switch((DiagonalCurveType)(curveEditor->curveType->getSelected())) { + case (DCT_Spline): + customCurve->pipetteDrag(provider, modifierKey); + break; + case (DCT_Parametric): + if (editedAdjuster) { + int trimmedValue = editedAdjuster->trimValue(editedAdjusterValue-(provider->deltaScreen.y/2)); + if (trimmedValue != editedAdjuster->getIntValue()) { + editedAdjuster->setValue(trimmedValue); + adjusterChanged(editedAdjuster, trimmedValue); + } + } + break; + case (DCT_NURBS): + NURBSCurve->pipetteDrag(provider, modifierKey); + break; + default: // (DCT_Linear, DCT_Unchanged) + // ... do nothing + break; + } +} + +void DiagonalCurveEditorSubGroup::showCoordinateAdjuster(CoordinateProvider *provider) { + if (provider == customCurve) { + if (!editPointCustom->get_active()) editPointCustom->set_active(true); + } + else if (provider == NURBSCurve) { + if (!editPointNURBS->get_active()) editPointNURBS->set_active(true); + } +} + +void DiagonalCurveEditorSubGroup::stopNumericalAdjustment() { + customCurve->stopNumericalAdjustment(); + NURBSCurve->stopNumericalAdjustment(); +} + +/* + * Force the resize of the curve editor, if the displayed one is the requested one + */ +void DiagonalCurveEditorSubGroup::refresh(CurveEditor *curveToRefresh) { + if (curveToRefresh != NULL && curveToRefresh == static_cast(parent->displayedCurve)) { + switch((DiagonalCurveType)(curveToRefresh->curveType->getSelected())) { + case (DCT_Spline): + customCurve->refresh(); + break; + case (DCT_Parametric): + paramCurve->refresh(); + shcSelector->refresh(); + break; + case (DCT_NURBS): + NURBSCurve->refresh(); + break; + default: // (DCT_Linear, DCT_Unchanged) + // ... do nothing + break; + } + } +} + +/* + * Switch the editor widgets to the currently edited curve + */ +void DiagonalCurveEditorSubGroup::switchGUI() { + + removeEditor(); + + DiagonalCurveEditor* dCurve = static_cast(parent->displayedCurve); + + if (dCurve) { + + // Initializing GUI values + repacking the appropriated widget + //dCurve->typeconn.block(true); + + // first we update the colored bar + + ColorProvider *barColorProvider = dCurve->getLeftBarColorProvider(); + std::vector bgGradient = dCurve->getLeftBarBgGradient(); + if (barColorProvider == NULL && bgGradient.size() == 0) { + // dCurve has no left colored bar, so we delete the object + if (leftBar) { + delete leftBar; + leftBar = NULL; + } + } + else { + // dCurve ave a ColorProvider or a background gradient defined, so we create/update the object + if (!leftBar) { + leftBar = new ColoredBar(RTO_Bottom2Top); + } + if (barColorProvider) { + bgGradient.clear(); + leftBar->setColorProvider(barColorProvider, dCurve->getLeftBarCallerId()); + leftBar->setBgGradient (bgGradient); + } + else { + leftBar->setColorProvider(NULL, -1); + leftBar->setBgGradient (bgGradient); + } + } + + barColorProvider = dCurve->getBottomBarColorProvider(); + bgGradient = dCurve->getBottomBarBgGradient(); + if (barColorProvider == NULL && bgGradient.size() == 0) { + // dCurve has no bottom colored bar, so we delete the object + if (bottomBar) { + delete bottomBar; + bottomBar = NULL; + } + } + else { + // dCurve has a ColorProvider or a background gradient defined, so we create/update the object + if (!bottomBar) { + bottomBar = new ColoredBar(RTO_Left2Right); + } + if (barColorProvider) { + bgGradient.clear(); + bottomBar->setColorProvider(barColorProvider, dCurve->getBottomBarCallerId()); + bottomBar->setBgGradient (bgGradient); + } + else { + bottomBar->setColorProvider(NULL, -1); + bottomBar->setBgGradient (bgGradient); + } + } + + switch((DiagonalCurveType)(dCurve->curveType->getSelected())) { + case (DCT_Spline): + customCurve->setPoints (dCurve->customCurveEd); + customCurve->setColorProvider(dCurve->getCurveColorProvider(), dCurve->getCurveCallerId()); + customCurve->setColoredBar(leftBar, bottomBar); + customCurve->forceResize(); + updateEditButton(dCurve, editCustom, editCustomConn); + parent->pack_start (*customCurveBox); + customCurveBox->check_resize(); + break; + case (DCT_Parametric): + { + Glib::ustring label[4]; + dCurve->getRangeLabels(label[0], label[1], label[2], label[3]); + double mileStone[3]; + dCurve->getRangeDefaultMilestones(mileStone[0], mileStone[1], mileStone[2]); + paramCurve->setPoints (dCurve->paramCurveEd); + shcSelector->setDefaults(mileStone[0], mileStone[1], mileStone[2]); + shcSelector->setPositions ( + dCurve->paramCurveEd.at(1), + dCurve->paramCurveEd.at(2), + dCurve->paramCurveEd.at(3) + ); + + highlights->setValue (dCurve->paramCurveEd.at(4)); + highlights->setLabel(label[3]); + lights->setValue (dCurve->paramCurveEd.at(5)); + lights->setLabel(label[2]); + darks->setValue (dCurve->paramCurveEd.at(6)); + darks->setLabel(label[1]); + shadows->setValue (dCurve->paramCurveEd.at(7)); + shadows->setLabel(label[0]); + shcSelector->setColorProvider(barColorProvider, dCurve->getBottomBarCallerId()); + shcSelector->setBgGradient(bgGradient); + shcSelector->setMargins( (leftBar ? MyCurve::getBarWidth()+CBAR_MARGIN : RADIUS), RADIUS ); + paramCurve->setColoredBar(leftBar, NULL); + paramCurve->forceResize(); + updateEditButton(dCurve, editParam, editParamConn); + parent->pack_start (*paramCurveBox); + break; + } + case (DCT_NURBS): + NURBSCurve->setPoints (dCurve->NURBSCurveEd); + NURBSCurve->setColorProvider(dCurve->getCurveColorProvider(), dCurve->getCurveCallerId()); + NURBSCurve->setColoredBar(leftBar, bottomBar); + NURBSCurve->forceResize(); + updateEditButton(dCurve, editNURBS, editNURBSConn); + parent->pack_start (*NURBSCurveBox); + NURBSCurveBox->check_resize(); + break; + default: // (DCT_Linear, DCT_Unchanged) + // ... do nothing + break; + } + + //dCurve->typeconn.block(false); + } +} + +void DiagonalCurveEditorSubGroup::savePressed () { + + Glib::ustring fname = outputFile(); + if (fname.size()) { + std::ofstream f (fname.c_str()); + std::vector p; + //std::vector p = customCurve->getPoints (); + + switch (parent->displayedCurve->selected) { + case DCT_Spline: // custom + p = customCurve->getPoints (); + break; + case DCT_NURBS: // NURBS + p = NURBSCurve->getPoints (); + break; + case DCT_Parametric: + p = paramCurve->getPoints (); + break; + default: + break; + } + + int ix = 0; + if (p[ix]==(double)(DCT_Linear)) + f << "Linear" << std::endl; + else if (p[ix]==(double)(DCT_Spline)) + f << "Spline" << std::endl; + else if (p[ix]==(double)(DCT_NURBS)) + f << "NURBS" << std::endl; + else if (p[ix]==(double)(DCT_Parametric)) + f << "Parametric" << std::endl; + if (p[ix]==(double)(DCT_Parametric)) { + ix++; + for (unsigned int i=0; i p; + std::string s; + f >> s; + if (s=="Linear") + p.push_back ((double)(DCT_Linear)); + else if (s=="Spline") + p.push_back ((double)(DCT_Spline)); + else if (s=="NURBS") + p.push_back ((double)(DCT_NURBS)); + else if (s=="Parametric") + p.push_back ((double)(DCT_Parametric)); + else return; + + double x; + while (f) { + f >> x; + if (f) + p.push_back (x); + } + if (p[0] == (double)(DCT_Spline)) { + customCurve->setPoints (p); + customCurve->queue_draw (); + customCurve->notifyListener (); + } + else if (p[0] == (double)(DCT_NURBS)) { + NURBSCurve->setPoints (p); + NURBSCurve->queue_draw (); + NURBSCurve->notifyListener (); + } + else if (p[0] == (double)(DCT_Parametric)) { + shcSelector->setPositions ( p[1], p[2], p[3] ); + highlights->setValue (p[4]); + lights->setValue (p[5]); + darks->setValue (p[6]); + shadows->setValue (p[7]); + paramCurve->setPoints (p); + paramCurve->queue_draw (); + paramCurve->notifyListener (); + } + } + } +} + +void DiagonalCurveEditorSubGroup::copyPressed () { +// For compatibility use enum DiagonalCurveType here + + std::vector curve; + + switch (parent->displayedCurve->selected) { + case DCT_Spline: // custom + curve = customCurve->getPoints (); + clipboard.setDiagonalCurveData (curve,DCT_Spline); + break; + case DCT_Parametric: // parametric + // ... do something, first add save/load functions + curve = paramCurve->getPoints (); + clipboard.setDiagonalCurveData (curve,DCT_Parametric); + break; + case DCT_NURBS: // NURBS + curve = NURBSCurve->getPoints (); + clipboard.setDiagonalCurveData (curve,DCT_NURBS); + break; + default: // (DCT_Linear, DCT_Unchanged) + // ... do nothing + break; + } +} + +void DiagonalCurveEditorSubGroup::pastePressed () { +// For compatibility use enum DiagonalCurveType here + + std::vector curve; + DiagonalCurveType type; + + type = clipboard.hasDiagonalCurveData(); + + if (type == (DiagonalCurveType)parent->displayedCurve->selected) { + curve = clipboard.getDiagonalCurveData (); + switch (type) { + case DCT_Spline: // custom + customCurve->setPoints (curve); + customCurve->queue_draw (); + customCurve->notifyListener (); + break; + case DCT_Parametric: // parametric + // ... do something, first add save/load functions + shcSelector->setPositions ( + curve[1], + curve[2], + curve[3] ); + highlights->setValue (curve[4]); + lights->setValue (curve[5]); + darks->setValue (curve[6]); + shadows->setValue (curve[7]); + paramCurve->setPoints (curve); + paramCurve->queue_draw (); + paramCurve->notifyListener (); + break; + case DCT_NURBS: // NURBS + NURBSCurve->setPoints (curve); + NURBSCurve->queue_draw (); + NURBSCurve->notifyListener (); + break; + default: // (DCT_Linear, DCT_Unchanged) + // ... do nothing + break; + } + } + return; +} + +void DiagonalCurveEditorSubGroup::editPointToggled(Gtk::ToggleButton *button) { + if (button->get_active()) { + customCoordAdjuster->show(); + NURBSCoordAdjuster->show(); + } + else { + if (customCoordAdjuster) { + customCurve->stopNumericalAdjustment(); + customCoordAdjuster->hide(); + NURBSCurve->stopNumericalAdjustment(); + NURBSCoordAdjuster->hide(); + } + } + if (button == editPointCustom) { + editPointNURBSConn.block(true); + editPointNURBS->set_active(!editPointNURBS->get_active()); + editPointNURBSConn.block(false); + } + else { + editPointCustomConn.block(true); + editPointCustom->set_active(!editPointCustom->get_active()); + editPointCustomConn.block(false); + } +} + +void DiagonalCurveEditorSubGroup::editToggled (Gtk::ToggleButton *button) { + DiagonalCurveEditor* dCurve = static_cast(parent->displayedCurve); + if (!dCurve) + // should never happen! + return; + + if (button->get_active()) { + dCurve->subscribe(); + if (button == editCustom) + customCurve->notifyListener (); + else if (button == editNURBS) + NURBSCurve->notifyListener (); + else if (button == editParam) + paramCurve->notifyListener (); + + /* + if (button != editCustom) { + editCustomConn.block(true); + editCustom->set_active(true); + editCustomConn.block(false); + } + else { + // will throw the event of curveChanged, which will now build the edit's buffer + customCurve->notifyListener (); + } + if (button != editNURBS) { + editNURBSConn.block(true); + editNURBS->set_active(true); + editNURBSConn.block(false); + } + else { + NURBSCurve->notifyListener (); + } + if (button != editParam) { + editParamConn.block(true); + editParam->set_active(true); + editParamConn.block(false); + } + else { + paramCurve->notifyListener (); + } + */ + } + else { + dCurve->unsubscribe(); + /* + if (button != editCustom ) { editCustomConn.block(true); editCustom->set_active(false); editCustomConn.block(false); } + if (button != editNURBS ) { editNURBSConn.block(true); editNURBS->set_active(false); editNURBSConn.block(false); } + if (button != editParam ) { editParamConn.block(true); editParam->set_active(false); editParamConn.block(false); } + */ + } +} + +/* + * Store the curves of the currently displayed type from the widgets to the CurveEditor object + */ +void DiagonalCurveEditorSubGroup::storeDisplayedCurve() { + if (parent->displayedCurve) { + switch (parent->displayedCurve->selected) { + case (DCT_Spline): + storeCurveValues(parent->displayedCurve, getCurveFromGUI(DCT_Spline)); + break; + case (DCT_Parametric): + storeCurveValues(parent->displayedCurve, getCurveFromGUI(DCT_Parametric)); + break; + case (DCT_NURBS): + storeCurveValues(parent->displayedCurve, getCurveFromGUI(DCT_NURBS)); + break; + default: + break; + } + } +} + +/* + * Restore the histogram to all types from the CurveEditor object to the widgets + */ +void DiagonalCurveEditorSubGroup::restoreDisplayedHistogram() { + if (parent->displayedCurve /*&& initslope==1*/) { + paramCurve->updateBackgroundHistogram (parent->displayedCurve->histogram); + customCurve->updateBackgroundHistogram (parent->displayedCurve->histogram); + NURBSCurve->updateBackgroundHistogram (parent->displayedCurve->histogram); + } + +} + +void DiagonalCurveEditorSubGroup::storeCurveValues (CurveEditor* ce, const std::vector& p) { + if (!p.empty()) { + DiagonalCurveType t = (DiagonalCurveType)p[0]; + + switch (t) { + case (DCT_Spline): + (static_cast(ce))->customCurveEd = p; + break; + case (DCT_Parametric): + (static_cast(ce))->paramCurveEd = p; + break; + case (DCT_NURBS): + (static_cast(ce))->NURBSCurveEd = p; + break; + default: + break; + } + } +} + +/* + * Called to update the parametric curve graph with new slider values + */ +const std::vector DiagonalCurveEditorSubGroup::getCurveFromGUI (int type) { + switch ((DiagonalCurveType)type) { + case (DCT_Parametric): { + std::vector lcurve (8); + lcurve[0] = (double)(DCT_Parametric); + shcSelector->getPositions (lcurve[1], lcurve[2], lcurve[3]); + lcurve[4] = highlights->getValue (); + lcurve[5] = lights->getValue (); + lcurve[6] = darks->getValue (); + lcurve[7] = shadows->getValue (); + return lcurve; + } + case (DCT_Spline): + return customCurve->getPoints (); + case (DCT_NURBS): + return NURBSCurve->getPoints (); + default: { + // linear and other solutions + std::vector lcurve (1); + lcurve[0] = (double)(DCT_Linear); + return lcurve; + } + } +} + +/* + * Unlink the tree editor widgets from their parent box to hide them + */ +void DiagonalCurveEditorSubGroup::removeEditor () { + removeIfThere (parent, customCurveBox, false); + removeIfThere (parent, paramCurveBox, false); + removeIfThere (parent, NURBSCurveBox, false); +} + +bool DiagonalCurveEditorSubGroup::curveReset(CurveEditor *ce) { + if (!ce) + return false; + + DiagonalCurveEditor *dce = static_cast(ce); + + switch (ce->selected) { + case (DCT_NURBS) : // = Control cage + NURBSCurve->reset (dce->NURBSResetCurve, dce->getIdentityValue()); + return true; + break; + case (DCT_Spline) : // = Custom + customCurve->reset (dce->customResetCurve, dce->getIdentityValue()); + return true; + break; + case (DCT_Parametric) : + { + DiagonalCurveEditor* dCurve = static_cast(parent->displayedCurve); + double mileStone[3]; + dCurve->getRangeDefaultMilestones(mileStone[0], mileStone[1], mileStone[2]); + + highlights->resetPressed(NULL); + lights->resetPressed(NULL); + darks->resetPressed(NULL); + shadows->resetPressed(NULL); + shcSelector->setDefaults(mileStone[0], mileStone[1], mileStone[2]); + shcSelector->reset(); + paramCurve->reset (dce->paramResetCurve, dce->getIdentityValue()); + return true; + break; + } + default: + return false; + break; + } + return true; +} + +/* + * Listener + */ +void DiagonalCurveEditorSubGroup::shcChanged () { + + paramCurve->setPoints (getCurveFromGUI(DCT_Parametric)); + storeDisplayedCurve(); + parent->curveChanged (); +} + +/* + * Listener + */ +void DiagonalCurveEditorSubGroup::adjusterChanged (Adjuster* a, double newval) { + + paramCurve->setPoints (getCurveFromGUI(DCT_Parametric)); + storeDisplayedCurve(); + parent->curveChanged (); +} + +/* + * Listener called when the mouse is over a parametric curve's slider + */ +bool DiagonalCurveEditorSubGroup::adjusterEntered (GdkEventCrossing* ev, int ac) { + + if (ev->detail != GDK_NOTIFY_INFERIOR) { + activeParamControl = ac; + paramCurve->setActiveParam (activeParamControl); + } + return true; +} + +/* + * Listener called when the mouse left the parametric curve's slider + */ +bool DiagonalCurveEditorSubGroup::adjusterLeft (GdkEventCrossing* ev, int ac) { + + if (ev->detail != GDK_NOTIFY_INFERIOR) { + activeParamControl = -1; + paramCurve->setActiveParam (activeParamControl); + } + return true; +} + +void DiagonalCurveEditorSubGroup::updateBackgroundHistogram (CurveEditor* ce) { + if (ce==parent->displayedCurve /*&& initslope==1*/) { + paramCurve->updateBackgroundHistogram (ce->histogram); + customCurve->updateBackgroundHistogram (ce->histogram); + NURBSCurve->updateBackgroundHistogram (ce->histogram); + } +} + +void DiagonalCurveEditorSubGroup::setSubGroupRangeLabels(Glib::ustring r1, Glib::ustring r2, Glib::ustring r3, Glib::ustring r4) { + shadows->setLabel(r1); + darks->setLabel(r2); + lights->setLabel(r3); + highlights->setLabel(r4); +} diff --git a/rtgui/diagonalcurveeditorsubgroup.h b/rtgui/diagonalcurveeditorsubgroup.h new file mode 100644 index 000000000..e10daf3ed --- /dev/null +++ b/rtgui/diagonalcurveeditorsubgroup.h @@ -0,0 +1,113 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _DIAGONALCURVEEDITORSUBGROUP_ +#define _DIAGONALCURVEEDITORSUBGROUP_ + +#include +#include "curveeditorgroup.h" + +class DiagonalCurveEditor; + +class DiagonalCurveEditorSubGroup : public CurveEditorSubGroup, public SHCListener, public AdjusterListener { + + friend class DiagonalCurveEditor; + +protected: + Gtk::VBox* customCurveBox; + Gtk::VBox* NURBSCurveBox; + Gtk::VBox* paramCurveBox; + + MyDiagonalCurve* customCurve; + MyDiagonalCurve* NURBSCurve; + MyDiagonalCurve* paramCurve; + + SHCSelector* shcSelector; + Adjuster* highlights; + Adjuster* lights; + Adjuster* darks; + Adjuster* shadows; + + Adjuster *editedAdjuster; + int editedAdjusterValue; + + CoordinateAdjuster *customCoordAdjuster; + CoordinateAdjuster *NURBSCoordAdjuster; + + Gtk::Button* saveCustom; + Gtk::Button* loadCustom; + Gtk::Button* copyCustom; + Gtk::Button* pasteCustom; + Gtk::ToggleButton* editPointCustom; + Gtk::ToggleButton* editCustom; + sigc::connection editCustomConn, editPointCustomConn; + Gtk::Button* saveNURBS; + Gtk::Button* loadNURBS; + Gtk::Button* copyNURBS; + Gtk::Button* pasteNURBS; + Gtk::ToggleButton* editPointNURBS; + Gtk::ToggleButton* editNURBS; + sigc::connection editNURBSConn, editPointNURBSConn; + Gtk::Button* saveParam; + Gtk::Button* loadParam; + Gtk::Button* copyParam; + Gtk::Button* pasteParam; + Gtk::ToggleButton* editParam; + sigc::connection editParamConn; + + int activeParamControl; + +public: + DiagonalCurveEditorSubGroup(CurveEditorGroup* prt, Glib::ustring& curveDir); + virtual ~DiagonalCurveEditorSubGroup(); + + DiagonalCurveEditor* addCurve(Glib::ustring curveLabel = ""); + virtual void updateBackgroundHistogram (CurveEditor* ce); + void switchGUI(); + void refresh(CurveEditor *curveToRefresh); + void editModeSwitchedOff (); + void pipetteMouseOver(EditDataProvider *provider, int modifierKey); + void pipetteButton1Pressed(EditDataProvider *provider, int modifierKey); + void pipetteButton1Released(EditDataProvider *provider); + void pipetteDrag(EditDataProvider *provider, int modifierKey); + void showCoordinateAdjuster(CoordinateProvider *provider); + void stopNumericalAdjustment(); + + bool curveReset (CurveEditor *ce); + +protected: + void storeCurveValues (CurveEditor* ce, const std::vector& p); + void storeDisplayedCurve (); + void restoreDisplayedHistogram (); + void savePressed (); + void loadPressed (); + void copyPressed (); + void pastePressed (); + void editPointToggled(Gtk::ToggleButton *button); + void editToggled (Gtk::ToggleButton *button); + void removeEditor (); + const std::vector getCurveFromGUI (int type); + void shcChanged (); + void adjusterChanged (Adjuster* a, double newval); + bool adjusterEntered (GdkEventCrossing* ev, int ac); + bool adjusterLeft (GdkEventCrossing* ev, int ac); + void setSubGroupRangeLabels(Glib::ustring r1, Glib::ustring r2, Glib::ustring r3, Glib::ustring r4); + void setSubGroupBottomBarBgGradient(); +}; + +#endif diff --git a/rtgui/dirbrowser.cc b/rtgui/dirbrowser.cc new file mode 100644 index 000000000..c08680c64 --- /dev/null +++ b/rtgui/dirbrowser.cc @@ -0,0 +1,415 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "dirbrowser.h" +#ifdef WIN32 +#define _WIN32_WINNT 0x0600 +#include +#endif +#include "options.h" +#include "multilangmgr.h" +#include "../rtengine/safegtk.h" + +#include +#include "guiutils.h" +#include "rtimage.h" + +#define CHECKTIME 5000 + +struct DirNameComparator { + template + bool operator()(T const &firstDir, T const &secondDir) const { + return options.dirBrowserSortType == Gtk::SORT_ASCENDING ? firstDir < secondDir : firstDir > secondDir; + } +}; + +DirBrowser::DirBrowser () : dirTreeModel(), + dtColumns(), + tvc(M("DIRBROWSER_FOLDERS")), + expandSuccess(false) + #ifdef WIN32 + , volumes(0) + #endif +{ + + dirtree = Gtk::manage ( new Gtk::TreeView() ); + scrolledwindow4 = Gtk::manage ( new Gtk::ScrolledWindow() ); + +// dirtree->set_flags(Gtk::CAN_FOCUS); + dirtree->set_headers_visible(); + dirtree->set_headers_clickable(); + dirtree->set_rules_hint(false); + dirtree->set_reorderable(false); + dirtree->set_enable_search(false); + scrolledwindow4->set_flags(Gtk::CAN_FOCUS); + scrolledwindow4->set_border_width(2); + scrolledwindow4->set_shadow_type(Gtk::SHADOW_NONE); + scrolledwindow4->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + scrolledwindow4->property_window_placement().set_value(Gtk::CORNER_TOP_LEFT); + scrolledwindow4->add(*dirtree); + + pack_start (*scrolledwindow4); + dirtree->show (); + scrolledwindow4->show (); +} + +void DirBrowser::fillDirTree () { + + openfolder = safe_create_from_file ("gtk-open.png"); + closedfolder = safe_create_from_file ("folder.png"); + icdrom = safe_create_from_file ("drive-optical.png"); + ifloppy = safe_create_from_file ("drive-removable-media.png"); + ihdd = safe_create_from_file ("drive-harddisk.png"); + iremovable = safe_create_from_file ("media-usb.png"); + inetwork = safe_create_from_file ("network.png"); + + //Create the Tree model: + dirTreeModel = Gtk::TreeStore::create(dtColumns); + dirtree->set_model (dirTreeModel); + + fillRoot (); + + Gtk::CellRendererPixbuf* render_pb = Gtk::manage ( new Gtk::CellRendererPixbuf () ); + tvc.pack_start (*render_pb, false); + tvc.add_attribute(*render_pb, "pixbuf-expander-closed", dtColumns.icon2); + tvc.add_attribute(*render_pb, "pixbuf", dtColumns.icon2); + tvc.add_attribute(*render_pb, "pixbuf-expander-open", dtColumns.icon1); + tvc.pack_start (crt); + tvc.add_attribute(crt, "text", dtColumns.filename); + + dirtree->append_column(tvc); + + tvc.set_sort_order(options.dirBrowserSortType); + tvc.set_sort_column(dtColumns.filename); + tvc.set_sort_indicator(true); + tvc.set_clickable(); + + dirTreeModel->set_sort_column(dtColumns.filename, options.dirBrowserSortType); + + crt.property_ypad() = 0; + render_pb->property_ypad() = 0; + + dirtree->signal_row_expanded().connect(sigc::mem_fun(*this, &DirBrowser::row_expanded)); + dirtree->signal_row_activated().connect(sigc::mem_fun(*this, &DirBrowser::row_activated)); + dirTreeModel->signal_sort_column_changed().connect(sigc::mem_fun(*this, &DirBrowser::on_sort_column_changed)); +} + +#ifdef WIN32 +void DirBrowser::addRoot (char letter) { + + char volume[4]; + volume[0] = letter; + strcpy (volume+1, ":\\"); + + Gtk::TreeModel::iterator root = dirTreeModel->append(); + root->set_value (dtColumns.filename, Glib::ustring(volume)); + root->set_value (dtColumns.dirname, Glib::ustring(volume)); + + int type = GetDriveType (volume); + if (type==DRIVE_CDROM) { + root->set_value (0, icdrom); + root->set_value (1, icdrom); + } + else if (type==DRIVE_REMOVABLE) { + if (letter-'A'<2) { + root->set_value (0, ifloppy); + root->set_value (1, ifloppy); + } + else { + root->set_value (0, iremovable); + root->set_value (1, iremovable); + } + } + else if (type==DRIVE_REMOTE) { + root->set_value (0, inetwork); + root->set_value (1, inetwork); + } + else if (type==DRIVE_FIXED) { + root->set_value (0, ihdd); + root->set_value (1, ihdd); + } + + Gtk::TreeModel::iterator child = dirTreeModel->append (root->children()); + child->set_value (dtColumns.filename, Glib::ustring("foo")); +} + +void DirBrowser::updateDirTreeRoot () { + + for (Gtk::TreeModel::iterator i=dirTreeModel->children().begin(); i!=dirTreeModel->children().end(); i++) + updateDirTree (i); +} + +void DirBrowser::updateDirTree (const Gtk::TreeModel::iterator& iter) { + + if (dirtree->row_expanded (dirTreeModel->get_path (iter))) { + updateDir (iter); + for (Gtk::TreeModel::iterator i=iter->children().begin(); i!=iter->children().end(); i++) + updateDirTree (i); + } +} + +void DirBrowser::updateVolumes () { + + int nvolumes = GetLogicalDrives (); + if (nvolumes!=volumes) { + GThreadLock lock; + + for (int i=0; i<32; i++) + if (((volumes >> i) & 1) && !((nvolumes >> i) & 1)) { // volume i has been deleted + for (Gtk::TreeModel::iterator iter = dirTreeModel->children().begin(); iter!=dirTreeModel->children().end(); iter++) + if (iter->get_value (dtColumns.filename).c_str()[0]-'A' == i) { + dirTreeModel->erase (iter); + break; + } + } + else if (!((volumes >> i) & 1) && ((nvolumes >> i) & 1)) + addRoot ('A'+i); // volume i has been added + volumes = nvolumes; + } +} + +int updateVolumesUI (void* br) { + (static_cast(br))->updateVolumes (); + return 1; +} +int updateDirTreeUI (void* br) { + (static_cast(br))->updateDirTreeRoot (); + return 0; +} + +void DirBrowser::winDirChanged () { + + g_idle_add (updateDirTreeUI, this); +} +#endif + +void DirBrowser::fillRoot () { + +#ifdef WIN32 + volumes = GetLogicalDrives (); + for (int i=0; i<32; i++) + if ((volumes >> i) & 1) + addRoot ('A'+i); + // since sigc++ is not thread safe, we have to use the glib function + g_timeout_add (CHECKTIME, updateVolumesUI, this); +#else + Gtk::TreeModel::Row rootRow = *(dirTreeModel->append()); + rootRow[dtColumns.filename] = "/"; + rootRow[dtColumns.dirname] = "/"; + Gtk::TreeModel::Row childRow = *(dirTreeModel->append(rootRow.children())); + childRow[dtColumns.filename] = "foo"; +#endif +} + +void DirBrowser::on_sort_column_changed() const { + options.dirBrowserSortType = tvc.get_sort_order(); +} + +void DirBrowser::row_expanded (const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& path) { + + expandSuccess = false; + + // We will disable model's sorting because it decreases speed of inserting new items + // in list tree dramatically. Therefore will do: + // 1) Disable sorting in model + // 2) Manually sort data by DirNameComparator + // 3) Enable sorting in model again for UI (sorting by click on header) + int prevSortColumn; + Gtk::SortType prevSortType; + dirTreeModel->get_sort_column_id(prevSortColumn, prevSortType); + dirTreeModel->set_sort_column(Gtk::TreeSortable::DEFAULT_UNSORTED_COLUMN_ID, Gtk::SORT_ASCENDING); + + typedef std::vector DirPathType; + + DirPathType subDirs; + Glib::RefPtr dir = Gio::File::create_for_path (iter->get_value (dtColumns.dirname)); + + safe_build_subdir_list (dir, subDirs, options.fbShowHidden); + + if (subDirs.empty()) { + dirtree->collapse_row(path); + } + else { + Gtk::TreeNodeChildren children = iter->children(); + std::list forErase(children.begin(), children.end()); + + DirNameComparator comparator; + sort(subDirs.begin(), subDirs.end(), comparator); + + for (DirPathType::const_iterator it = subDirs.begin(), end = subDirs.end(); it != end; ++it) { + addDir(iter, *it); + } + + for (std::list::const_iterator it = forErase.begin(), end = forErase.end(); it != end; ++it) { + dirTreeModel->erase(*it); + } + dirTreeModel->set_sort_column(prevSortColumn, prevSortType); + + expandSuccess = true; + } +#ifdef WIN32 + Glib::RefPtr monitor = Glib::RefPtr(new WinDirMonitor (iter->get_value (dtColumns.dirname), this)); + iter->set_value (dtColumns.monitor, monitor); +#else + Glib::RefPtr monitor = dir->monitor_directory (); + iter->set_value (dtColumns.monitor, monitor); + monitor->signal_changed().connect (sigc::bind(sigc::mem_fun(*this, &DirBrowser::file_changed), iter, dir->get_parse_name())); +#endif +} + +void DirBrowser::updateDir (const Gtk::TreeModel::iterator& iter) { + + // first test if some files are deleted + bool change = true; + while (change) { + change = false; + for (Gtk::TreeModel::iterator it=iter->children().begin(); it!=iter->children().end(); it++) + if (!safe_file_test (it->get_value (dtColumns.dirname), Glib::FILE_TEST_EXISTS) + || !safe_file_test (it->get_value (dtColumns.dirname), Glib::FILE_TEST_IS_DIR)) { + GThreadLock lock; + dirTreeModel->erase (it); + change = true; + break; + } + } + // test if new files are created + std::vector subDirs; + Glib::RefPtr dir = Gio::File::create_for_path (iter->get_value (dtColumns.dirname)); + safe_build_subdir_list (dir, subDirs, options.fbShowHidden); + + for (int i=0; ichildren().begin(); it!=iter->children().end() && !found ; it++) + found = (it->get_value (dtColumns.filename)==subDirs[i]); + + if (!found) { + GThreadLock lock; + addDir (iter, subDirs[i]); + } + } +} + +void DirBrowser::addDir (const Gtk::TreeModel::iterator& iter, const Glib::ustring& dirname) { + + Gtk::TreeModel::iterator child = dirTreeModel->append(iter->children()); + child->set_value (dtColumns.filename, dirname); + child->set_value (dtColumns.icon1, openfolder); + child->set_value (dtColumns.icon2, closedfolder); + Glib::ustring fullname = Glib::build_filename (iter->get_value (dtColumns.dirname), dirname); + child->set_value (dtColumns.dirname, fullname); + Gtk::TreeModel::iterator fooRow = dirTreeModel->append(child->children()); + fooRow->set_value (dtColumns.filename, Glib::ustring("foo")); +} + +void DirBrowser::row_activated (const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* column) { + + Glib::ustring dname = dirTreeModel->get_iter (path)->get_value (dtColumns.dirname); + if (safe_file_test (dname, Glib::FILE_TEST_IS_DIR)) + for (size_t i=0; idirSelected (dname); +} + +Gtk::TreePath DirBrowser::expandToDir (const Glib::ustring& absDirPath) { + + Gtk::TreeModel::Path path; + path.append_index(0); + + char* dcpy = strdup (absDirPath.c_str()); + char* dir = strtok (dcpy, "/\\"); + int count = 0; + expandSuccess = true; + +#ifndef WIN32 + Gtk::TreeModel::iterator j = dirTreeModel->get_iter (path); + path.up (); + path.append_index (0); + row_expanded(j, path); + path.append_index (0); +#endif + + while (dir) { + Glib::ustring dirstr = dir; +#ifdef WIN32 + if (count==0) + dirstr = dirstr + "\\"; +#endif + Gtk::TreeModel::iterator i = dirTreeModel->get_iter (path); + int ix = 0; + while (i && expandSuccess) { + Gtk::TreeModel::Row crow = *i; + Glib::ustring str =crow[dtColumns.filename]; +#ifdef WIN32 + if (str.casefold()==dirstr.casefold()) { +#else + if (str==dirstr) { +#endif + path.up (); + path.append_index (ix); + row_expanded(i, path); + path.append_index (0); + break; + } + ix++; + i++; + } + count++; + dir = strtok(NULL, "/\\"); + } + + free(dcpy); + + path.up (); + dirtree->expand_to_path (path); + + return path; +} + +void DirBrowser::open (const Glib::ustring& dirname, const Glib::ustring& fileName) { + + dirtree->collapse_all (); + + // WARNING & TODO: One should test here if the directory/file has R/W access permission to avoid crash + + Glib::RefPtr dir = Gio::File::create_for_path(dirname); + if( !dir->query_exists()) + return; + Glib::ustring absDirPath = dir->get_parse_name (); + Gtk::TreePath path = expandToDir (absDirPath); + dirtree->scroll_to_row (path); + dirtree->get_selection()->select (path); + Glib::ustring absFilePath; + if (!fileName.empty()) + absFilePath = Glib::build_filename (absDirPath, fileName); + for (size_t i=0; idirSelected (absDirPath, absFilePath); + } +} + +void DirBrowser::file_changed (const Glib::RefPtr& file, const Glib::RefPtr& other_file, Gio::FileMonitorEvent event_type, const Gtk::TreeModel::iterator& iter, const Glib::ustring& dirName) { + + if (!file || !safe_file_test (dirName, Glib::FILE_TEST_IS_DIR) || event_type==Gio::FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED) + return; + + updateDir (iter); +} + +void DirBrowser::selectDir (Glib::ustring dir) { + + open (dir, ""); +} + diff --git a/rtgui/dirbrowser.h b/rtgui/dirbrowser.h new file mode 100644 index 000000000..dc9c21522 --- /dev/null +++ b/rtgui/dirbrowser.h @@ -0,0 +1,105 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _DIRBROWSER_ +#define _DIRBROWSER_ + +#include +#include +#ifdef WIN32 +#include "windirmonitor.h" +#endif +#include "dirselectionlistener.h" +#include "dirbrowserremoteinterface.h" + +class DirBrowser : public Gtk::VBox, public DirBrowserRemoteInterface +#ifdef WIN32 + , public WinDirChangeListener +#endif + { + + private: + + Glib::RefPtr dirTreeModel; + + struct DirTreeColumns : public Gtk::TreeModelColumnRecord { + public: + Gtk::TreeModelColumn filename; + Gtk::TreeModelColumn > icon1; + Gtk::TreeModelColumn > icon2; + Gtk::TreeModelColumn dirname; + #ifdef WIN32 + Gtk::TreeModelColumn > monitor; + #else + Gtk::TreeModelColumn > monitor; + #endif + + DirTreeColumns() { add(icon1); add(icon2); add(filename); add(dirname); add(monitor); } + }; + + DirTreeColumns dtColumns; + Gtk::TreeViewColumn tvc; + Gtk::CellRendererText crt; + Gtk::CellRendererPixbuf crb; + + + Gtk::TreeView *dirtree; + Gtk::ScrolledWindow *scrolledwindow4; + std::vector dllisteners; + + void fillRoot (); + + Glib::RefPtr openfolder; + Glib::RefPtr closedfolder; + Glib::RefPtr icdrom; + Glib::RefPtr ifloppy; + Glib::RefPtr ihdd; + Glib::RefPtr inetwork; + Glib::RefPtr iremovable; + + bool expandSuccess; + + #ifdef WIN32 + int volumes; + public: + void updateVolumes (); + void updateDirTree (const Gtk::TreeModel::iterator& iter); + void updateDirTreeRoot (); + void winDirChanged (); + private: + void addRoot (char letter); + #endif + void addDir (const Gtk::TreeModel::iterator& iter, const Glib::ustring& dirname); + Gtk::TreePath expandToDir (const Glib::ustring& dirName); + void updateDir (const Gtk::TreeModel::iterator& iter); + void notifyListeners (); + + public: + DirBrowser (); + + void fillDirTree (); + void on_sort_column_changed() const; + void row_expanded (const Gtk::TreeModel::iterator& iter, const Gtk::TreeModel::Path& path); + void row_activated (const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* column); + void file_changed (const Glib::RefPtr& file, const Glib::RefPtr& other_file, Gio::FileMonitorEvent event_type, const Gtk::TreeModel::iterator& iter, const Glib::ustring& dirName); + void open (const Glib::ustring& dirName, const Glib::ustring& fileName=""); // goes to dir "dirName" and selects file "fileName" + void addDirSelectionListener (DirSelectionListener* l) { dllisteners.push_back (l); } + void selectDir (Glib::ustring dir); +}; + +#endif diff --git a/rtgui/dirbrowserremoteinterface.h b/rtgui/dirbrowserremoteinterface.h new file mode 100644 index 000000000..e5ae9c847 --- /dev/null +++ b/rtgui/dirbrowserremoteinterface.h @@ -0,0 +1,31 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _DIRBROWSERREMOTEINTERFACE_ +#define _DIRBROWSERREMOTEINTERFACE_ + +#include + +class DirBrowserRemoteInterface { + + public: + virtual void selectDir (Glib::ustring dir) {} +}; + +#endif + diff --git a/rtgui/dirpyrdenoise.cc b/rtgui/dirpyrdenoise.cc new file mode 100644 index 000000000..3c0acbcd2 --- /dev/null +++ b/rtgui/dirpyrdenoise.cc @@ -0,0 +1,1220 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "dirpyrdenoise.h" +#include +#include +#include "edit.h" +#include "guiutils.h" + +using namespace rtengine; +using namespace rtengine::procparams; +extern Options options; + +DirPyrDenoise::DirPyrDenoise () : FoldableToolPanel(this, "dirpyrdenoise", M("TP_DIRPYRDENOISE_LABEL"), true, true), lastenhance(false) { + std::vector milestones; + CurveListener::setMulti(true); + nextnresid=0.; + nexthighresid=0.; + nextchroma=15.; + nextred=0.; + nextblue=0.; + + setEnabledTooltipMarkup(M("TP_DIRPYRDENOISE_ENABLED_TOOLTIP")); + + std::vector defaultCurve; + + Gtk::Frame* lumaFrame = Gtk::manage (new Gtk::Frame (M("TP_DIRPYRDENOISE_LUMAFR")) ); + lumaFrame->set_tooltip_text(M("TP_DIRPYRDENOISE_LUMAFR_TOOLTIP")); + lumaFrame->set_border_width(0); + lumaFrame->set_label_align(0.025, 0.5); + + Gtk::VBox * lumaVBox = Gtk::manage ( new Gtk::VBox()); + lumaVBox->set_border_width(4); + lumaVBox->set_spacing(2); + + + + ctboxL = Gtk::manage (new Gtk::HBox ()); + Gtk::Label* labmL = Gtk::manage (new Gtk::Label (M("TP_DIRPYRDENOISE_LTYPE")+":")); + ctboxL->pack_start (*labmL, Gtk::PACK_SHRINK, 1); + + Lmethod = Gtk::manage (new MyComboBoxText ()); + Lmethod->append_text (M("TP_DIRPYRDENOISE_CUR")); + Lmethod->append_text (M("TP_DIRPYRDENOISE_SLI")); + Lmethod->set_active(0); + Lmethodconn = Lmethod->signal_changed().connect ( sigc::mem_fun(*this, &DirPyrDenoise::LmethodChanged) ); + + luma = Gtk::manage (new Adjuster (M("TP_DIRPYRDENOISE_LUMA"), 0, 100, 0.01, 0)); + Ldetail = Gtk::manage (new Adjuster (M("TP_DIRPYRDENOISE_LDETAIL"), 0, 100, 0.01, 50)); + NoiscurveEditorG = new CurveEditorGroup (options.lastDenoiseCurvesDir, M("TP_DIRPYRDENOISE_LCURVE")); + //curveEditorG = new CurveEditorGroup (options.lastLabCurvesDir); + NoiscurveEditorG->setCurveListener (this); + rtengine::DirPyrDenoiseParams::getDefaultNoisCurve(defaultCurve); + lshape = static_cast(NoiscurveEditorG->addCurve(CT_Flat, "", NULL, false)); + lshape->setIdentityValue(0.); + lshape->setResetCurve(FlatCurveType(defaultCurve.at(0)), defaultCurve); + + lshape->setTooltip(M("TP_DIRPYRDENOISE_CURVEEDITOR_L_TOOLTIP")); + //lshape->setEditID(EUID_Lab_LCurve, BT_SINGLEPLANE_FLOAT); + milestones.push_back( GradientMilestone(0., 0., 0., 0.) ); + milestones.push_back( GradientMilestone(1., 1., 1., 1.) ); + lshape->setBottomBarBgGradient(milestones); + //lshape->setLeftBarBgGradient(milestones); + milestones.push_back( GradientMilestone(0., 0., 0., 0.) ); + milestones.push_back( GradientMilestone(1., 1., 1., 1.) ); + NoiscurveEditorG->curveListComplete(); + NoiscurveEditorG->show(); + + Gtk::Frame* chromaFrame = Gtk::manage (new Gtk::Frame (M("TP_DIRPYRDENOISE_CHROMAFR")) ); + chromaFrame->set_border_width(0); + chromaFrame->set_label_align(0.025, 0.5); + + Gtk::VBox *chromaVBox = Gtk::manage ( new Gtk::VBox()); + chromaVBox->set_spacing(2); + chromaVBox->set_border_width(4); + + autochroma=Gtk::manage (new Gtk::CheckButton (M("TP_DIRPYRDENOISE_AUTO"))); + autochroma->set_active (true); + autochroma->set_tooltip_text (M("TP_DIRPYRDENOISE_AUTO_TOOLTIP")); + + ctboxC = Gtk::manage (new Gtk::HBox ()); + Gtk::Label* labmC = Gtk::manage (new Gtk::Label (M("TP_DIRPYRDENOISE_CTYPE")+":")); + ctboxC->pack_start (*labmC, Gtk::PACK_SHRINK, 1); + ctboxC->set_tooltip_markup (M("TP_DIRPYRDENOISE_CTYPE_TOOLTIP")); + + Cmethod = Gtk::manage (new MyComboBoxText ()); + Cmethod->append_text (M("TP_DIRPYRDENOISE_MAN")); + Cmethod->append_text (M("TP_DIRPYRDENOISE_AUT")); + Cmethod->append_text (M("TP_DIRPYRDENOISE_PON")); + Cmethod->append_text (M("TP_DIRPYRDENOISE_PRE")); + Cmethod->set_active(0); + Cmethodconn = Cmethod->signal_changed().connect ( sigc::mem_fun(*this, &DirPyrDenoise::CmethodChanged) ); + + ctboxC2 = Gtk::manage (new Gtk::HBox ()); + Gtk::Label* labmC2 = Gtk::manage (new Gtk::Label (M("TP_DIRPYRDENOISE_CTYPE")+":")); + ctboxC2->pack_start (*labmC2, Gtk::PACK_SHRINK, 1); + ctboxC2->set_tooltip_markup (M("TP_DIRPYRDENOISE_C2TYPE_TOOLTIP")); + + C2method = Gtk::manage (new MyComboBoxText ()); + C2method->append_text (M("TP_DIRPYRDENOISE_MANU")); + C2method->append_text (M("TP_DIRPYRDENOISE_AUTO")); + C2method->append_text (M("TP_DIRPYRDENOISE_PREV")); + C2method->set_active(0); + C2methodconn = C2method->signal_changed().connect ( sigc::mem_fun(*this, &DirPyrDenoise::C2methodChanged) ); + + + NoiseLabels = Gtk::manage(new Gtk::Label("---", Gtk::ALIGN_CENTER)); + NoiseLabels->set_tooltip_text(M("TP_DIRPYRDENOISE_NRESID_TOOLTIP")); + + TileLabels = Gtk::manage(new Gtk::Label("---", Gtk::ALIGN_CENTER)); + PrevLabels = Gtk::manage(new Gtk::Label("---", Gtk::ALIGN_CENTER)); + + chroma = Gtk::manage (new Adjuster (M("TP_DIRPYRDENOISE_CHROMA"), 0, 100, 0.01, 15)); + redchro = Gtk::manage (new Adjuster (M("TP_DIRPYRDENOISE_RED"), -100, 100, 0.1, 0)); + bluechro = Gtk::manage (new Adjuster (M("TP_DIRPYRDENOISE_BLUE"), -100, 100, 0.1, 0)); + + gamma = Gtk::manage (new Adjuster (M("TP_DIRPYRDENOISE_GAMMA"), 1.0, 3.0, 0.01, 1.7)); + gamma->set_tooltip_text (M("TP_DIRPYRDENOISE_GAMMA_TOOLTIP")); + + + Gtk::HBox* hb1 = Gtk::manage (new Gtk::HBox ()); + hb1->pack_start (*Gtk::manage (new Gtk::Label ( M("TP_DIRPYRDENOISE_METHOD") +": ")),Gtk::PACK_SHRINK, 4); + hb1->set_tooltip_markup (M("TP_DIRPYRDENOISE_METHOD_TOOLTIP")); + + dmethod = Gtk::manage (new MyComboBoxText ()); + dmethod->append_text (M("TP_DIRPYRDENOISE_LAB")); + dmethod->append_text (M("TP_DIRPYRDENOISE_RGB")); + dmethod->set_active(0); + hb1->pack_end (*dmethod, Gtk::PACK_EXPAND_WIDGET, 4); + pack_start( *hb1, Gtk::PACK_SHRINK, 4); + + + dmethodconn = dmethod->signal_changed().connect ( sigc::mem_fun(*this, &DirPyrDenoise::dmethodChanged) ); + + luma->setAdjusterListener (this); + Ldetail->setAdjusterListener (this); + chroma->setAdjusterListener (this); + redchro->setAdjusterListener (this); + bluechro->setAdjusterListener (this); + + CCcurveEditorG = new CurveEditorGroup (options.lastDenoiseCurvesDir, M("TP_DIRPYRDENOISE_CCCURVE")); + CCcurveEditorG->setCurveListener (this); + rtengine::DirPyrDenoiseParams::getDefaultCCCurve(defaultCurve); + ccshape = static_cast(CCcurveEditorG->addCurve(CT_Flat, "", NULL, false)); + ccshape->setIdentityValue(0.); + ccshape->setResetCurve(FlatCurveType(defaultCurve.at(0)), defaultCurve); + + ccshape->setTooltip(M("TP_DIRPYRDENOISE_CURVEEDITOR_CC_TOOLTIP")); + ccshape->setBottomBarColorProvider(this, 2); + + CCcurveEditorG->curveListComplete(); + + + //----------------------------------------- + + gamma->setAdjusterListener (this); + + luma->hide(); + Ldetail->show(); + +// autochroma->show(); + NoiseLabels->show(); + TileLabels->show(); + PrevLabels->show(); + chroma->show(); + redchro->show(); + bluechro->show(); +// perform->show(); + gamma->show(); +// perform->set_active (true); + + enhance = Gtk::manage (new Gtk::CheckButton (M("TP_DIRPYRDENOISE_ENH"))); + enhance->set_active (false); + enhance->set_tooltip_text (M("TP_DIRPYRDENOISE_ENH_TOOLTIP")); + // ---- Median FIltering ---- + + Gtk::Frame* medianFrame = Gtk::manage (new Gtk::Frame ()); + medianFrame->set_border_width(0); + medianFrame->set_label_align(0.025, 0.5); + + Gtk::VBox *medianVBox = Gtk::manage ( new Gtk::VBox()); + medianVBox->set_spacing(2); + medianVBox->set_border_width(4); + + median = Gtk::manage (new Gtk::CheckButton (M("TP_DIRPYRDENOISE_MED")+":")); + median->set_active (true); + median->set_tooltip_text (M("TP_DIRPYRDENOISE_MED_TOOLTIP")); + medianFrame->set_label_widget(*median); + + + Gtk::HSeparator *hsep2 = Gtk::manage (new Gtk::HSeparator()); + hsep2->show (); + + methodmed = Gtk::manage (new MyComboBoxText ()); + methodmed->append_text (M("TP_DIRPYRDENOISE_LM")); + methodmed->append_text (M("TP_DIRPYRDENOISE_ABM")); + methodmed->append_text (M("TP_DIRPYRDENOISE_LPLABM")); + methodmed->append_text (M("TP_DIRPYRDENOISE_LABM")); + methodmed->append_text (M("TP_DIRPYRDENOISE_RGBM")); + methodmed->set_active (0); + methodmed->set_tooltip_text (M("TP_DIRPYRDENOISE_METM_TOOLTIP")); + methodmedconn = methodmed->signal_changed().connect ( sigc::mem_fun(*this, &DirPyrDenoise::methodmedChanged) ); + + rgbmethod = Gtk::manage (new MyComboBoxText ()); + rgbmethod->append_text (M("TP_DIRPYRDENOISE_SOFT")); + rgbmethod->append_text (M("TP_DIRPYRDENOISE_33")); + rgbmethod->append_text (M("TP_DIRPYRDENOISE_55SOFT")); + rgbmethod->set_active (0); + rgbmethod->set_tooltip_text (M("TP_DIRPYRDENOISE_MET_TOOLTIP")); + rgbmethodconn = rgbmethod->signal_changed().connect ( sigc::mem_fun(*this, &DirPyrDenoise::rgbmethodChanged) ); + + + medmethod = Gtk::manage (new MyComboBoxText ()); + medmethod->append_text (M("TP_DIRPYRDENOISE_SOFT")); + medmethod->append_text (M("TP_DIRPYRDENOISE_33")); + medmethod->append_text (M("TP_DIRPYRDENOISE_55SOFT")); + medmethod->append_text (M("TP_DIRPYRDENOISE_55")); + medmethod->append_text (M("TP_DIRPYRDENOISE_77")); + medmethod->append_text (M("TP_DIRPYRDENOISE_99")); + medmethod->set_active (0); + medmethod->set_tooltip_text (M("TP_DIRPYRDENOISE_MET_TOOLTIP")); + medmethodconn = medmethod->signal_changed().connect ( sigc::mem_fun(*this, &DirPyrDenoise::medmethodChanged) ); + + ctboxm = Gtk::manage (new Gtk::HBox ()); + Gtk::Label* labmm = Gtk::manage (new Gtk::Label (M("TP_DIRPYRDENOISE_MEDMETHOD")+":")); + ctboxm->pack_start (*labmm, Gtk::PACK_SHRINK, 1); + + ctbox = Gtk::manage (new Gtk::HBox ()); + Gtk::Label* labm = Gtk::manage (new Gtk::Label (M("TP_DIRPYRDENOISE_MEDTYPE")+":")); + ctbox->pack_start (*labm, Gtk::PACK_SHRINK, 1); + + ctboxrgb = Gtk::manage (new Gtk::HBox ()); + Gtk::Label* labrgb = Gtk::manage (new Gtk::Label (M("TP_DIRPYRDENOISE_MEDTYPE")+":")); + ctboxrgb->pack_start (*labrgb, Gtk::PACK_SHRINK, 1); + + + Gtk::HSeparator *hsep4 = Gtk::manage (new Gtk::HSeparator()); + hsep4->show (); + + Gtk::HBox* hb11 = Gtk::manage (new Gtk::HBox ()); + hb11->pack_start (*Gtk::manage (new Gtk::Label ( M("TP_DIRPYRDENOISE_METHOD11") +": ")),Gtk::PACK_SHRINK, 4); + hb11->set_tooltip_markup (M("TP_DIRPYRDENOISE_METHOD11_TOOLTIP")); + + smethod = Gtk::manage (new MyComboBoxText ()); + smethod->append_text (M("TP_DIRPYRDENOISE_SHAL")); +// smethod->append_text (M("TP_DIRPYRDENOISE_SHBI")); + smethod->append_text (M("TP_DIRPYRDENOISE_SHALBI")); +// smethod->append_text (M("TP_DIRPYRDENOISE_SHALAL")); +// smethod->append_text (M("TP_DIRPYRDENOISE_SHBIBI")); + smethod->set_active(1); + hb11->pack_start (*smethod, Gtk::PACK_EXPAND_WIDGET, 4); + pack_start( *hb11, Gtk::PACK_SHRINK, 4); + smethodconn = smethod->signal_changed().connect ( sigc::mem_fun(*this, &DirPyrDenoise::smethodChanged) ); + + passes = Gtk::manage (new Adjuster (M("TP_DIRPYRDENOISE_PASSES"), 1.0, 3.0, 1., 1.)); + passes->set_tooltip_text (M("TP_DIRPYRDENOISE_PASSES_TOOLTIP")); + passes->setAdjusterListener (this); + passes->show(); + ctboxL->pack_start (*Lmethod); + lumaVBox->pack_start (*ctboxL); + lumaVBox->pack_start (*luma); + lumaVBox->pack_start (*NoiscurveEditorG, Gtk::PACK_SHRINK, 4); + lumaVBox->pack_start (*Ldetail); + lumaFrame->add(*lumaVBox); + pack_start (*lumaFrame); + + ctboxC->pack_start (*Cmethod); + ctboxC2->pack_start (*C2method); + if(options.rtSettings.leveldnautsimpl==1){ + chromaVBox->pack_start (*ctboxC); + } + else { + chromaVBox->pack_start (*ctboxC2); + } + chromaVBox->pack_start (*NoiseLabels); + chromaVBox->pack_start (*TileLabels); + chromaVBox->pack_start (*PrevLabels); + + chromaVBox->pack_start (*chroma); + chromaVBox->pack_start (*redchro); + chromaVBox->pack_start (*bluechro); + chromaVBox->pack_start (*CCcurveEditorG, Gtk::PACK_SHRINK, 4); + chromaFrame->add(*chromaVBox); + pack_start (*chromaFrame); + + + pack_start (*gamma); + //pack_start (*enhance); + pack_start (*hsep4); + +// pack_start( *hb11, Gtk::PACK_SHRINK, 4); + +// pack_start (*hsep2); +// pack_start (*median); + + ctboxm->pack_start (*methodmed); + ctbox->pack_start (*medmethod); + ctboxrgb->pack_start (*rgbmethod); +// pack_start (*ctboxm); +// pack_start (*ctbox); +// pack_start (*ctboxrgb); +// pack_start (*passes,Gtk::PACK_SHRINK, 1); + + medianVBox->pack_start (*ctboxm); + medianVBox->pack_start (*ctbox); + medianVBox->pack_start (*ctboxrgb); + medianVBox->pack_start (*passes); + medianFrame->add(*medianVBox); + + pack_start (*medianFrame); + + +// pack_start (*perform); + enhanConn = enhance->signal_toggled().connect( sigc::mem_fun(*this, &DirPyrDenoise::enhanceChanged) ); + autochromaConn = autochroma->signal_toggled().connect( sigc::mem_fun(*this, &DirPyrDenoise::autochromaChanged) ); + medianConn = median->signal_toggled().connect( sigc::mem_fun(*this, &DirPyrDenoise::medianChanged) ); + ctboxrgb->hide(); + +} + +DirPyrDenoise::~DirPyrDenoise () { + delete NoiscurveEditorG; + delete CCcurveEditorG; + +} +int chromaChangedUI (void* data) { + GThreadLock lock; // All GUI acces from idle_add callbacks or separate thread HAVE to be protected + (static_cast(data))->chromaComputed_ (); + return 0; +} +void DirPyrDenoise::chromaChanged (double autchroma, double autred, double autblue) +{ + nextchroma = autchroma; +// printf("CHROM=%f\n",nextchroma); + nextred=autred; + nextblue=autblue; + g_idle_add (chromaChangedUI, this); +} + +bool DirPyrDenoise::chromaComputed_ () { + + disableListener (); + chroma->setValue (nextchroma); + redchro->setValue (nextred); + bluechro->setValue (nextblue); + enableListener (); + updateNoiseLabel (); + return false; +} +int TilePrevChangedUI (void* data) { + GThreadLock lock; // All GUI acces from idle_add callbacks or separate thread HAVE to be protected + (static_cast(data))->TilePrevComputed_ (); + return 0; +} + + +void DirPyrDenoise::noiseTilePrev (int tileX, int tileY, int prevX, int prevY, int sizeT, int sizeP) +{ + nexttileX=tileX; + nexttileY=tileY; + nextprevX=prevX; + nextprevY=prevY; + nextsizeT=sizeT; + nextsizeP=sizeP; + + g_idle_add (TilePrevChangedUI, this); + + +} +bool DirPyrDenoise::TilePrevComputed_ () { + + disableListener (); + enableListener (); + updateTileLabel (); + updatePrevLabel (); + return false; +} +void DirPyrDenoise::updateTileLabel () { + if (!batchMode) { + float sT; + float nX, nY; + sT=nextsizeT; + nX = nexttileX; + nY = nexttileY; + { + TileLabels->set_text( + Glib::ustring::compose(M("TP_DIRPYRDENOISE_TILELABEL"), + Glib::ustring::format(std::fixed, std::setprecision(0), sT), + Glib::ustring::format(std::fixed, std::setprecision(0), nX), + Glib::ustring::format(std::fixed, std::setprecision(0), nY)) + ); + } + } +} +void DirPyrDenoise::updatePrevLabel () { + if (!batchMode) { + float sP; + float pX, pY; + sP=nextsizeP; + pX = nextprevX; + pY = nextprevY; + { + PrevLabels->set_text( + Glib::ustring::compose(M("TP_DIRPYRDENOISE_PREVLABEL"), + Glib::ustring::format(std::fixed, std::setprecision(0), sP), + Glib::ustring::format(std::fixed, std::setprecision(0), pX), + Glib::ustring::format(std::fixed, std::setprecision(0), pY)) + ); + } + } +} + + +int noiseChangedUI (void* data) { + GThreadLock lock; // All GUI acces from idle_add callbacks or separate thread HAVE to be protected + (static_cast(data))->noiseComputed_ (); + return 0; +} + + +void DirPyrDenoise::noiseChanged (double nresid, double highresid) +{ + nextnresid=nresid; + nexthighresid=highresid; + g_idle_add (noiseChangedUI, this); +} + +bool DirPyrDenoise::noiseComputed_ () { + + disableListener (); + enableListener (); + updateNoiseLabel (); + return false; +} + +void DirPyrDenoise::updateNoiseLabel () { + if (!batchMode) { + float nois, high; + nois = nextnresid; + high= nexthighresid; + if(nois==0.f && high==0.f) NoiseLabels->set_text(M("TP_DIRPYRDENOISE_NOISELABELEMPTY")); + else { + NoiseLabels->set_text( + Glib::ustring::compose(M("TP_DIRPYRDENOISE_NOISELABEL"), + Glib::ustring::format(std::fixed, std::setprecision(0), nois), + Glib::ustring::format(std::fixed, std::setprecision(0), high)) + ); + } + } +} + + + +void DirPyrDenoise::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + dmethodconn.block(true); + Lmethodconn.block(true); + Cmethodconn.block(true); + C2methodconn.block(true); + smethodconn.block(true); + autochromaConn.block(true); + medmethodconn.block(true); + rgbmethodconn.block(true); + methodmedconn.block(true); + + + autochromaChanged (); + dmethod->set_active (0); + if (pp->dirpyrDenoise.dmethod=="Lab") + dmethod->set_active (0); + else if (pp->dirpyrDenoise.dmethod=="RGB") + dmethod->set_active (1); + dmethodChanged (); + + Lmethod->set_active (0); + if (pp->dirpyrDenoise.Lmethod=="CUR") + Lmethod->set_active (0); + else if (pp->dirpyrDenoise.Lmethod=="SLI") + Lmethod->set_active (1); + LmethodChanged(); + + if(options.rtSettings.leveldnautsimpl==1){ + Cmethod->set_active (0); + if (pp->dirpyrDenoise.Cmethod=="MAN") + Cmethod->set_active (0); + else if (pp->dirpyrDenoise.Cmethod=="AUT") + Cmethod->set_active (1); + else if (pp->dirpyrDenoise.Cmethod=="PON") + Cmethod->set_active (2); + else if (pp->dirpyrDenoise.Cmethod=="PRE") + Cmethod->set_active (3); + CmethodChanged(); + } + else { + C2method->set_active (0); + if (pp->dirpyrDenoise.C2method=="MANU") + C2method->set_active (0); + else if (pp->dirpyrDenoise.C2method=="AUTO") + C2method->set_active (1); + else if (pp->dirpyrDenoise.C2method=="PREV") + C2method->set_active (2); + + C2methodChanged(); + } + + smethod->set_active (0); + if (pp->dirpyrDenoise.smethod=="shal") + smethod->set_active (0); +// else if (pp->dirpyrDenoise.smethod=="shbi") +// smethod->set_active (1); + else if (pp->dirpyrDenoise.smethod=="shalbi") + smethod->set_active (1); + // else if (pp->dirpyrDenoise.smethod=="shalal") + // smethod->set_active (3); + // else if (pp->dirpyrDenoise.smethod=="shbibi") + // smethod->set_active (4); + + methodmed->set_active (0); + // if (pp->dirpyrDenoise.methodmed=="none") + // methodmed->set_active (0); + if (pp->dirpyrDenoise.methodmed=="Lonly") + methodmed->set_active (0); + else if (pp->dirpyrDenoise.methodmed=="ab") + methodmed->set_active (1); + else if (pp->dirpyrDenoise.methodmed=="Lpab") + methodmed->set_active (2); + else if (pp->dirpyrDenoise.methodmed=="Lab") + methodmed->set_active (3); + else if (pp->dirpyrDenoise.methodmed=="RGB") + methodmed->set_active (4); + methodmedChanged(); + + medmethod->set_active (0); +// if (pp->dirpyrDenoise.medmethod=="none") +// medmethod->set_active (0); + if (pp->dirpyrDenoise.medmethod=="soft") + medmethod->set_active (0); + else if (pp->dirpyrDenoise.medmethod=="33") + medmethod->set_active (1); + else if (pp->dirpyrDenoise.medmethod=="55soft") + medmethod->set_active (2); + else if (pp->dirpyrDenoise.medmethod=="55") + medmethod->set_active (3); + else if (pp->dirpyrDenoise.medmethod=="77") + medmethod->set_active (4); + else if (pp->dirpyrDenoise.medmethod=="99") + medmethod->set_active (5); + medmethodChanged(); + + rgbmethod->set_active (0); +// if (pp->dirpyrDenoise.medmethod=="none") +// medmethod->set_active (0); + if (pp->dirpyrDenoise.rgbmethod=="soft") + rgbmethod->set_active (0); + else if (pp->dirpyrDenoise.rgbmethod=="33") + rgbmethod->set_active (1); + else if (pp->dirpyrDenoise.rgbmethod=="55soft") + rgbmethod->set_active (2); + rgbmethodChanged(); + + + if (pedited) { + if (!pedited->dirpyrDenoise.dmethod) + dmethod->set_active (2); + if (!pedited->dirpyrDenoise.smethod) + smethod->set_active (2); + if (!pedited->dirpyrDenoise.rgbmethod) + rgbmethod->set_active (2); + if (!pedited->dirpyrDenoise.medmethod) + medmethod->set_active (6); + if (!pedited->dirpyrDenoise.methodmed) + methodmed->set_active (5); + if (!pedited->dirpyrDenoise.Cmethod) + Cmethod->set_active (4); + if (!pedited->dirpyrDenoise.C2method) + C2method->set_active (3); + if (!pedited->dirpyrDenoise.Lmethod) + Lmethod->set_active (2); + + luma->setEditedState (pedited->dirpyrDenoise.luma ? Edited : UnEdited); + Ldetail->setEditedState (pedited->dirpyrDenoise.Ldetail ? Edited : UnEdited); + chroma->setEditedState (pedited->dirpyrDenoise.chroma ? Edited : UnEdited); + redchro->setEditedState (pedited->dirpyrDenoise.redchro ? Edited : UnEdited); + bluechro->setEditedState (pedited->dirpyrDenoise.bluechro ? Edited : UnEdited); + + gamma->setEditedState (pedited->dirpyrDenoise.gamma ? Edited : UnEdited); + passes->setEditedState (pedited->dirpyrDenoise.passes ? Edited : UnEdited); + set_inconsistent (multiImage && !pedited->dirpyrDenoise.enabled); + enhance->set_inconsistent (!pedited->dirpyrDenoise.enhance); + median->set_inconsistent (!pedited->dirpyrDenoise.median); + ccshape->setUnChanged (!pedited->dirpyrDenoise.cccurve); + + // perform->set_inconsistent (!pedited->dirpyrDenoise.perform); + } +// perfconn.block (true); + setEnabled(pp->dirpyrDenoise.enabled); + enhance->set_active (pp->dirpyrDenoise.enhance); + // perform->set_active (pp->dirpyrDenoise.perform); + median->set_active (pp->dirpyrDenoise.median); + autochroma->set_active (pp->dirpyrDenoise.autochroma); + + // perfconn.block (false); + lastmedian = pp->dirpyrDenoise.median; + lastautochroma = pp->dirpyrDenoise.autochroma; + lastenhance = pp->dirpyrDenoise.enhance; +// lastperform = pp->dirpyrDenoise.perform; + luma->setValue (pp->dirpyrDenoise.luma); + Ldetail->setValue (pp->dirpyrDenoise.Ldetail); + chroma->setValue (pp->dirpyrDenoise.chroma); + redchro->setValue (pp->dirpyrDenoise.redchro); + bluechro->setValue (pp->dirpyrDenoise.bluechro); + + gamma->setValue (pp->dirpyrDenoise.gamma); + passes->setValue (pp->dirpyrDenoise.passes); + lshape->setCurve (pp->dirpyrDenoise.lcurve); + ccshape->setCurve (pp->dirpyrDenoise.cccurve); + + autochromaConn.block(false); + + dmethodconn.block(false); + Lmethodconn.block(false); + Cmethodconn.block(false); + C2methodconn.block(false); + smethodconn.block(false); + medmethodconn.block(false); + rgbmethodconn.block(false); + methodmedconn.block(false); + updateNoiseLabel (); + + enableListener (); + +} +void DirPyrDenoise::setEditProvider (EditDataProvider *provider) { + lshape->setEditProvider(provider); + ccshape->setEditProvider(provider); + +} +void DirPyrDenoise::autoOpenCurve () { + lshape->openIfNonlinear(); + ccshape->openIfNonlinear(); +} +void DirPyrDenoise::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->dirpyrDenoise.luma = luma->getValue (); + pp->dirpyrDenoise.Ldetail = Ldetail->getValue (); + pp->dirpyrDenoise.chroma = chroma->getValue (); + pp->dirpyrDenoise.redchro = redchro->getValue (); + pp->dirpyrDenoise.bluechro = bluechro->getValue (); + pp->dirpyrDenoise.gamma = gamma->getValue (); + pp->dirpyrDenoise.passes = passes->getValue (); + pp->dirpyrDenoise.enabled = getEnabled(); + pp->dirpyrDenoise.enhance = enhance->get_active(); +// pp->dirpyrDenoise.perform = perform->get_active(); + pp->dirpyrDenoise.median = median->get_active(); + pp->dirpyrDenoise.autochroma = autochroma->get_active(); + pp->dirpyrDenoise.lcurve = lshape->getCurve (); + pp->dirpyrDenoise.cccurve = ccshape->getCurve (); + + if (pedited) { + pedited->dirpyrDenoise.dmethod = dmethod->get_active_row_number() != 2; + pedited->dirpyrDenoise.Lmethod = Lmethod->get_active_row_number() != 2; + pedited->dirpyrDenoise.Cmethod = Cmethod->get_active_row_number() != 4; + pedited->dirpyrDenoise.C2method = C2method->get_active_row_number() != 3; + pedited->dirpyrDenoise.smethod = smethod->get_active_row_number() != 2; + pedited->dirpyrDenoise.medmethod = medmethod->get_active_row_number() != 6; + pedited->dirpyrDenoise.rgbmethod = rgbmethod->get_active_row_number() != 2; + pedited->dirpyrDenoise.methodmed = methodmed->get_active_row_number() != 5; + pedited->dirpyrDenoise.luma = luma->getEditedState (); + pedited->dirpyrDenoise.Ldetail = Ldetail->getEditedState (); + pedited->dirpyrDenoise.chroma = chroma->getEditedState (); + pedited->dirpyrDenoise.redchro = redchro->getEditedState (); + pedited->dirpyrDenoise.bluechro = bluechro->getEditedState (); + pedited->dirpyrDenoise.gamma = gamma->getEditedState (); + pedited->dirpyrDenoise.passes = passes->getEditedState (); + pedited->dirpyrDenoise.enabled = !get_inconsistent(); + pedited->dirpyrDenoise.enhance = !enhance->get_inconsistent(); + pedited->dirpyrDenoise.median = !median->get_inconsistent(); + pedited->dirpyrDenoise.autochroma = !autochroma->get_inconsistent(); + pedited->dirpyrDenoise.lcurve = !lshape->isUnChanged (); + pedited->dirpyrDenoise.cccurve = !ccshape->isUnChanged (); + + // pedited->dirpyrDenoise.perform = !perform->get_inconsistent(); + } + if (dmethod->get_active_row_number()==0) + pp->dirpyrDenoise.dmethod = "Lab"; + else if (dmethod->get_active_row_number()==1) + pp->dirpyrDenoise.dmethod = "RGB"; + + if (Lmethod->get_active_row_number()==0) + pp->dirpyrDenoise.Lmethod = "CUR"; + else if (Lmethod->get_active_row_number()==1) + pp->dirpyrDenoise.Lmethod = "SLI"; + if(options.rtSettings.leveldnautsimpl==1){ + if (Cmethod->get_active_row_number()==0) + pp->dirpyrDenoise.Cmethod = "MAN"; + else if (Cmethod->get_active_row_number()==1) + pp->dirpyrDenoise.Cmethod = "AUT"; + else if (Cmethod->get_active_row_number()==2) + pp->dirpyrDenoise.Cmethod = "PON"; + else if (Cmethod->get_active_row_number()==3) + pp->dirpyrDenoise.Cmethod = "PRE"; + } + else + { + if (C2method->get_active_row_number()==0) + pp->dirpyrDenoise.C2method = "MANU"; + else if (C2method->get_active_row_number()==1) + pp->dirpyrDenoise.C2method = "AUTO"; + else if (C2method->get_active_row_number()==2) + pp->dirpyrDenoise.C2method = "PREV"; + } + if (smethod->get_active_row_number()==0) + pp->dirpyrDenoise.smethod = "shal"; + // else if (smethod->get_active_row_number()==1) +// pp->dirpyrDenoise.smethod = "shbi"; + else if (smethod->get_active_row_number()==1) + pp->dirpyrDenoise.smethod = "shalbi"; +// else if (smethod->get_active_row_number()==3) +// pp->dirpyrDenoise.smethod = "shalal"; +// else if (smethod->get_active_row_number()==4) +// pp->dirpyrDenoise.smethod = "shbibi"; + + // if (methodmed->get_active_row_number()==0) + // pp->dirpyrDenoise.methodmed = "none"; + if (methodmed->get_active_row_number()==0) + pp->dirpyrDenoise.methodmed = "Lonly"; + else if (methodmed->get_active_row_number()==1) + pp->dirpyrDenoise.methodmed = "ab"; + else if (methodmed->get_active_row_number()==2) + pp->dirpyrDenoise.methodmed = "Lpab"; + else if (methodmed->get_active_row_number()==3) + pp->dirpyrDenoise.methodmed = "Lab"; + else if (methodmed->get_active_row_number()==4) + pp->dirpyrDenoise.methodmed = "RGB"; + + + + // if (medmethod->get_active_row_number()==0) + // pp->dirpyrDenoise.medmethod = "none"; + if (medmethod->get_active_row_number()==0) + pp->dirpyrDenoise.medmethod = "soft"; + else if (medmethod->get_active_row_number()==1) + pp->dirpyrDenoise.medmethod = "33"; + else if (medmethod->get_active_row_number()==2) + pp->dirpyrDenoise.medmethod = "55soft"; + else if (medmethod->get_active_row_number()==3) + pp->dirpyrDenoise.medmethod = "55"; + else if (medmethod->get_active_row_number()==4) + pp->dirpyrDenoise.medmethod = "77"; + else if (medmethod->get_active_row_number()==5) + pp->dirpyrDenoise.medmethod = "99"; + + if (rgbmethod->get_active_row_number()==0) + pp->dirpyrDenoise.rgbmethod = "soft"; + else if (rgbmethod->get_active_row_number()==1) + pp->dirpyrDenoise.rgbmethod = "33"; + else if (rgbmethod->get_active_row_number()==2) + pp->dirpyrDenoise.rgbmethod = "55soft"; + +} + +void DirPyrDenoise::curveChanged (CurveEditor* ce) { + + if (listener && getEnabled()) { + if (ce == lshape) + listener->panelChanged (EvDPDNLCurve, M("HISTORY_CUSTOMCURVE")); + if (ce == ccshape) + listener->panelChanged (EvDPDNCCCurve, M("HISTORY_CUSTOMCURVE")); + } +} + +void DirPyrDenoise::dmethodChanged () { + + if (listener && (multiImage||getEnabled()) ) { + listener->panelChanged (EvDPDNmet, dmethod->get_active_text ()); + } +} +void DirPyrDenoise::LmethodChanged () { + if (!batchMode) { + if(Lmethod->get_active_row_number()==0) { // CUR + luma->hide(); + NoiscurveEditorG->show(); + } + else if(Lmethod->get_active_row_number()==1) { // SLI + luma->show(); + NoiscurveEditorG->hide(); + } + } + if (listener && (multiImage||getEnabled()) ) { + listener->panelChanged (EvDPDNLmet, Lmethod->get_active_text ()); + } +} + +void DirPyrDenoise::CmethodChanged () { + if (!batchMode) { + if(Cmethod->get_active_row_number()==0 ) { //MAN + chroma->show(); + redchro->show(); + bluechro->show(); + chroma->set_sensitive(true); + redchro->set_sensitive(true); + bluechro->set_sensitive(true); + NoiseLabels->show(); + TileLabels->hide(); + PrevLabels->hide(); + + } + else if(Cmethod->get_active_row_number()==1) { // AUT + chroma->show(); + redchro->show(); + bluechro->show(); + NoiseLabels->show(); + TileLabels->hide(); + PrevLabels->hide(); + + chroma->set_sensitive(false); + redchro->set_sensitive(false); + bluechro->set_sensitive(false); + } + else if(Cmethod->get_active_row_number()==2) { // PON + chroma->hide(); + redchro->hide(); + bluechro->hide(); + NoiseLabels->hide(); + TileLabels->hide(); + PrevLabels->hide(); + + chroma->set_sensitive(false); + redchro->set_sensitive(false); + bluechro->set_sensitive(false); + } + else if(Cmethod->get_active_row_number()==3) { // PRE + chroma->show(); + redchro->show(); + bluechro->show(); + NoiseLabels->show(); + TileLabels->show(); + PrevLabels->show(); + + chroma->set_sensitive(false); + redchro->set_sensitive(false); + bluechro->set_sensitive(false); + } + + } + if (listener && (multiImage||getEnabled()) ) { + listener->panelChanged (EvDPDNCmet, Cmethod->get_active_text ()); + } +} + +void DirPyrDenoise::C2methodChanged () { + if (!batchMode) { + if(C2method->get_active_row_number()==0 ) { //MAN + chroma->show(); + redchro->show(); + bluechro->show(); + chroma->set_sensitive(true); + redchro->set_sensitive(true); + bluechro->set_sensitive(true); + NoiseLabels->show(); + TileLabels->hide(); + PrevLabels->hide(); + + } + else if(C2method->get_active_row_number()==1) { // AUTO + chroma->show(); + redchro->show(); + bluechro->show(); + NoiseLabels->show(); + TileLabels->hide(); + PrevLabels->hide(); + + chroma->set_sensitive(false); + redchro->set_sensitive(false); + bluechro->set_sensitive(false); + } + else if(C2method->get_active_row_number()==2) { // PREV + chroma->show(); + redchro->show(); + bluechro->show(); + NoiseLabels->show(); + TileLabels->hide(); + PrevLabels->hide(); + + chroma->set_sensitive(false); + redchro->set_sensitive(false); + bluechro->set_sensitive(false); + } + + + } + if (listener && (multiImage||getEnabled()) ) { + listener->panelChanged (EvDPDNC2met, C2method->get_active_text ()); + } +} + + +void DirPyrDenoise::smethodChanged () { + + if (listener && (multiImage||getEnabled()) ) { + listener->panelChanged (EvDPDNsmet, smethod->get_active_text ()); + } +} + +void DirPyrDenoise::medmethodChanged () { + + + if (listener && (multiImage||getEnabled()) && median->get_active() ) { + listener->panelChanged (EvDPDNmedmet, medmethod->get_active_text ()); + } +} + +void DirPyrDenoise::rgbmethodChanged () { + ctboxrgb->hide(); + if(methodmed->get_active_row_number()==4) ctboxrgb->show(); + if (listener && (multiImage||getEnabled()) && median->get_active()) { + listener->panelChanged (EvDPDNrgbmet, rgbmethod->get_active_text ()); + } +} + + + +void DirPyrDenoise::methodmedChanged () { + if(methodmed->get_active_row_number()==4) {ctboxrgb->show();ctbox->hide();} + else {ctboxrgb->hide();ctbox->show();} + + if (listener && (multiImage||getEnabled()) && median->get_active()) { + listener->panelChanged (EvDPDNmetmed, methodmed->get_active_text ()); + } +} + +void DirPyrDenoise::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + luma->setDefault (defParams->dirpyrDenoise.luma); + Ldetail->setDefault (defParams->dirpyrDenoise.Ldetail); + chroma->setDefault (defParams->dirpyrDenoise.chroma); + redchro->setDefault (defParams->dirpyrDenoise.redchro); + bluechro->setDefault (defParams->dirpyrDenoise.bluechro); + gamma->setDefault (defParams->dirpyrDenoise.gamma); + passes->setDefault (defParams->dirpyrDenoise.passes); + + if (pedited) { + luma->setDefaultEditedState (pedited->dirpyrDenoise.luma ? Edited : UnEdited); + Ldetail->setDefaultEditedState (pedited->dirpyrDenoise.Ldetail ? Edited : UnEdited); + chroma->setDefaultEditedState (pedited->dirpyrDenoise.chroma ? Edited : UnEdited); + redchro->setDefaultEditedState (pedited->dirpyrDenoise.redchro ? Edited : UnEdited); + bluechro->setDefaultEditedState (pedited->dirpyrDenoise.bluechro ? Edited : UnEdited); + gamma->setDefaultEditedState (pedited->dirpyrDenoise.gamma ? Edited : UnEdited); + passes->setDefaultEditedState (pedited->dirpyrDenoise.passes ? Edited : UnEdited); + } + else { + luma->setDefaultEditedState (Irrelevant); + Ldetail->setDefaultEditedState (Irrelevant); + chroma->setDefaultEditedState (Irrelevant); + redchro->setDefaultEditedState (Irrelevant); + bluechro->setDefaultEditedState (Irrelevant); + gamma->setDefaultEditedState (Irrelevant); + passes->setDefaultEditedState (Irrelevant); + } +} + +void DirPyrDenoise::adjusterChanged (Adjuster* a, double newval) { + + Glib::ustring costr; + costr = Glib::ustring::format (std::setw(3), std::fixed, std::setprecision(2), a->getValue()); + + if (listener && getEnabled()) { + if (a==Ldetail) + listener->panelChanged (EvDPDNLdetail, costr); + else if (a==luma) + listener->panelChanged (EvDPDNLuma, costr); + else if (a==chroma) + listener->panelChanged (EvDPDNChroma, costr); + else if (a==redchro) + listener->panelChanged (EvDPDNredchro, costr); + else if (a==bluechro) + listener->panelChanged (EvDPDNbluechro, costr); + else if (a==gamma) + listener->panelChanged (EvDPDNGamma, costr); + else if (a==passes && median->get_active()) + listener->panelChanged (EvDPDNpasses, costr); + } +} + +void DirPyrDenoise::enabledChanged () { + + if (listener) { + if (get_inconsistent()) + listener->panelChanged (EvDPDNEnabled, M("GENERAL_UNCHANGED")); + else if (getEnabled()) + listener->panelChanged (EvDPDNEnabled, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvDPDNEnabled, M("GENERAL_DISABLED")); + } +} + +void DirPyrDenoise::enhanceChanged () { + + if (batchMode) { + if (enhance->get_inconsistent()) { + enhance->set_inconsistent (false); + enhanConn.block (true); + enhance->set_active (false); + enhanConn.block (false); + } + else if (lastenhance) + enhance->set_inconsistent (true); + + lastenhance = enhance->get_active (); + } + + if (listener) { + + if (enhance->get_active ()) + listener->panelChanged (EvDPDNenhance, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvDPDNenhance, M("GENERAL_DISABLED")); + } +} + +void DirPyrDenoise::medianChanged () { + + if (batchMode) { + if (median->get_inconsistent()) { + median->set_inconsistent (false); + medianConn.block (true); + median->set_active (false); + medianConn.block (false); + } + else if (lastmedian) + median->set_inconsistent (true); + + lastmedian = median->get_active (); + } + + if (listener) { + if (median->get_active ()) + { listener->panelChanged (EvDPDNmedian, M("GENERAL_ENABLED")); + } + else + { listener->panelChanged (EvDPDNmedian, M("GENERAL_DISABLED")); + } + + + } +} +void DirPyrDenoise::autochromaChanged () { +// printf("Autochroma\n"); + if (batchMode) { + if (autochroma->get_inconsistent()) { + autochroma->set_inconsistent (false); + autochromaConn.block (true); + autochroma->set_active (false); + autochromaConn.block (false); + } + else if (lastautochroma) + autochroma->set_inconsistent (true); + + lastautochroma = autochroma->get_active (); + } + if (autochroma->get_active ()) + { + chroma->set_sensitive(false); + redchro->set_sensitive(false); + bluechro->set_sensitive(false); + } + else + { + chroma->set_sensitive(true); + redchro->set_sensitive(true); + bluechro->set_sensitive(true); + } + + if (listener) { + if (autochroma->get_active ()) + { listener->panelChanged (EvDPDNautochroma, M("GENERAL_ENABLED")); + // chroma->set_sensitive(false); + // redchro->set_sensitive(false); + // bluechro->set_sensitive(false); + } + else + {listener->panelChanged (EvDPDNautochroma, M("GENERAL_DISABLED")); + //chroma->set_sensitive(true); + //redchro->set_sensitive(true); + //bluechro->set_sensitive(true); + } + + + } +} + + +/* +void DirPyrDenoise::perform_toggled () { + + if (batchMode) { + if (perform->get_inconsistent()) { + perform->set_inconsistent (false); + perfconn.block (true); + perform->set_active (false); + perfconn.block (false); + } + else if (lastperform) + perform->set_inconsistent (true); + + lastperform = perform->get_active (); + } + + if (listener) { + if (perform->get_active ()) + listener->panelChanged (EvDPDNperform, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvDPDNperform, M("GENERAL_DISABLED")); + } +} +*/ + +void DirPyrDenoise::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + luma->showEditedCB (); + Ldetail->showEditedCB (); + chroma->showEditedCB (); + redchro->showEditedCB (); + bluechro->showEditedCB (); + gamma->showEditedCB (); + passes->showEditedCB (); + NoiscurveEditorG->setBatchMode (batchMode); + CCcurveEditorG->setBatchMode (batchMode); + + dmethod->append_text (M("GENERAL_UNCHANGED")); + Lmethod->append_text (M("GENERAL_UNCHANGED")); + Cmethod->append_text (M("GENERAL_UNCHANGED")); + C2method->append_text (M("GENERAL_UNCHANGED")); + smethod->append_text (M("GENERAL_UNCHANGED")); + medmethod->append_text (M("GENERAL_UNCHANGED")); + methodmed->append_text (M("GENERAL_UNCHANGED")); + rgbmethod->append_text (M("GENERAL_UNCHANGED")); + +} + +void DirPyrDenoise::setAdjusterBehavior (bool lumaadd, bool lumdetadd, bool chromaadd, bool chromaredadd, bool chromablueadd, bool gammaadd, bool passesadd) { + + luma->setAddMode(lumaadd); + Ldetail->setAddMode(lumdetadd); + chroma->setAddMode(chromaadd); + redchro->setAddMode(chromaredadd); + bluechro->setAddMode(chromablueadd); + gamma->setAddMode(gammaadd); + passes->setAddMode(passesadd); + +} +void DirPyrDenoise::colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller *caller) { + + float R, G, B; + + if (elemType==ColorCaller::CCET_VERTICAL_BAR) + valY = 0.5; + + if (callerId == 1) { // ch - main curve + + Color::hsv2rgb01(float(valX), float(valY), 0.5f, R, G, B); + } + else if (callerId == 2) { // cc - bottom bar + + float value = (1.f - 0.7f) * float(valX) + 0.7f; + // whole hue range + // Y axis / from 0.15 up to 0.75 (arbitrary values; was 0.45 before) + Color::hsv2rgb01(float(valY), float(valX), value, R, G, B); + } + else if (callerId == 3) { // lc - bottom bar + + float value = (1.f - 0.7f) * float(valX) + 0.7f; + // whole hue range + // Y axis / from 0.15 up to 0.75 (arbitrary values; was 0.45 before) + Color::hsv2rgb01(float(valY), float(valX), value, R, G, B); + } + + else if (callerId == 4) { // LH - bottom bar + Color::hsv2rgb01(float(valX), 0.5f, float(valY), R, G, B); + } + else if (callerId == 5) { // HH - bottom bar + float h = float((valY - 0.5) * 0.3 + valX); + if (h > 1.0f) + h -= 1.0f; + else if (h < 0.0f) + h += 1.0f; + Color::hsv2rgb01(h, 0.5f, 0.5f, R, G, B); + } + caller->ccRed = double(R); + caller->ccGreen = double(G); + caller->ccBlue = double(B); +} + +void DirPyrDenoise::trimValues (rtengine::procparams::ProcParams* pp) { + + luma->trimValue(pp->dirpyrDenoise.luma); + Ldetail->trimValue(pp->dirpyrDenoise.Ldetail); + chroma->trimValue(pp->dirpyrDenoise.chroma); + redchro->trimValue(pp->dirpyrDenoise.redchro); + bluechro->trimValue(pp->dirpyrDenoise.bluechro); + gamma->trimValue(pp->dirpyrDenoise.gamma); + passes->trimValue(pp->dirpyrDenoise.passes); +} diff --git a/rtgui/dirpyrdenoise.h b/rtgui/dirpyrdenoise.h new file mode 100644 index 000000000..ecfb91f37 --- /dev/null +++ b/rtgui/dirpyrdenoise.h @@ -0,0 +1,140 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _DIRPYRDENOISE_H_ +#define _DIRPYRDENOISE_H_ + +#include +#include "adjuster.h" +#include "toolpanel.h" +#include "curveeditor.h" +#include "curveeditorgroup.h" +#include "colorprovider.h" +#include "guiutils.h" +#include "options.h" + +class DirPyrDenoise : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public rtengine::AutoChromaListener, public CurveListener, public ColorProvider { + + protected: + CurveEditorGroup* NoiscurveEditorG; + CurveEditorGroup* CCcurveEditorG; + Adjuster* luma; + Adjuster* Ldetail; + Adjuster* chroma; + Adjuster* redchro; + Adjuster* bluechro; + Adjuster* gamma; + Adjuster* passes; + FlatCurveEditor* lshape; + FlatCurveEditor* ccshape; + + Gtk::CheckButton* enhance; + bool lastenhance; + sigc::connection enhanConn, medianConn, autochromaConn; + Gtk::CheckButton* median; + bool lastmedian; + Gtk::CheckButton* autochroma; + bool lastautochroma; + Gtk::Label* NoiseLabels; + Gtk::Label* TileLabels; + Gtk::Label* PrevLabels; + +// Gtk::CheckButton* perform; +// bool lastperform; +// sigc::connection perfconn; + MyComboBoxText* dmethod; + sigc::connection dmethodconn; + MyComboBoxText* Lmethod; + sigc::connection Lmethodconn; + MyComboBoxText* Cmethod; + sigc::connection Cmethodconn; + MyComboBoxText* C2method; + sigc::connection C2methodconn; + MyComboBoxText* smethod; + sigc::connection smethodconn; + MyComboBoxText* medmethod; + sigc::connection medmethodconn; + Gtk::HBox* ctbox; + MyComboBoxText* methodmed; + sigc::connection methodmedconn; + Gtk::HBox* ctboxm; + MyComboBoxText* rgbmethod; + sigc::connection rgbmethodconn; + Gtk::HBox* ctboxrgb; + double nextchroma; + double nextred; + double nextblue; + double nextnresid; + double nexthighresid; + Gtk::HBox* ctboxL; + Gtk::HBox* ctboxC; + Gtk::HBox* ctboxC2; + int nexttileX; + int nexttileY; + int nextprevX; + int nextprevY; + int nextsizeT; + int nextsizeP; + + public: + + DirPyrDenoise (); + ~DirPyrDenoise (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + void curveChanged (CurveEditor* ce); + void setEditProvider (EditDataProvider *provider); + void autoOpenCurve (); + + void adjusterChanged (Adjuster* a, double newval); + void enabledChanged (); + void enhanceChanged (); + void medianChanged (); + void autochromaChanged (); + void chromaChanged (double autchroma, double autred, double autblue); + bool chromaComputed_ (); + void noiseChanged (double nresid, double highresid); + bool noiseComputed_ (); + void noiseTilePrev (int tileX, int tileY, int prevX, int prevY, int sizeT, int sizeP); + bool TilePrevComputed_ (); + +// void perform_toggled (); + void updateNoiseLabel (); + void LmethodChanged (); + void CmethodChanged (); + void C2methodChanged (); + void updateTileLabel (); + void updatePrevLabel (); + + void dmethodChanged (); + void medmethodChanged (); + void methodmedChanged (); + void rgbmethodChanged (); + void smethodChanged (); + virtual void colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller* caller); + + void setAdjusterBehavior (bool lumaadd, bool lumdetadd, bool chromaadd, bool chromaredadd, bool chromablueadd, bool gammaadd, bool passesadd); + void trimValues (rtengine::procparams::ProcParams* pp); + Glib::ustring getSettingString (); + +}; + +#endif diff --git a/rtgui/dirpyrequalizer.cc b/rtgui/dirpyrequalizer.cc new file mode 100644 index 000000000..d6f888788 --- /dev/null +++ b/rtgui/dirpyrequalizer.cc @@ -0,0 +1,361 @@ +/* + * This file is part of RawTherapee. + * + * 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 . + * + * © 2010 Emil Martinec + */ + +#include "dirpyrequalizer.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +DirPyrEqualizer::DirPyrEqualizer () : FoldableToolPanel(this, "dirpyrequalizer", M("TP_DIRPYREQUALIZER_LABEL"), true, true) { + + std::vector milestones; + + float r, g, b; + Color::hsv2rgb01(0.7500, 0.5, 0.5, r, g, b); milestones.push_back( GradientMilestone(0. , r, g, b) ); // hsv: 0.75 rad: -0.9 + Color::hsv2rgb01(0.8560, 0.5, 0.5, r, g, b); milestones.push_back( GradientMilestone(0.1470, r, g, b) ); // hsv: 0.856 rad: -0.4 + Color::hsv2rgb01(0.9200, 0.5, 0.5, r, g, b); milestones.push_back( GradientMilestone(0.2353, r, g, b) ); // hsv: 0.92 rad: -0.1 + Color::hsv2rgb01(0.9300, 0.5, 0.5, r, g, b); milestones.push_back( GradientMilestone(0.2647, r, g, b) ); // hsv: 0.93 rad: 0 + Color::hsv2rgb01(0.9600, 0.5, 0.5, r, g, b); milestones.push_back( GradientMilestone(0.3380, r, g, b) ); // hsv: 0.96 rad: 0.25 + Color::hsv2rgb01(1.0000, 0.5, 0.5, r, g, b); milestones.push_back( GradientMilestone(0.4412, r, g, b) ); // hsv: 1. rad: 0.6 + Color::hsv2rgb01(0.0675, 0.5, 0.5, r, g, b); milestones.push_back( GradientMilestone(0.6176, r, g, b) ); // hsv: 0.0675 rad: 1.2 + Color::hsv2rgb01(0.0900, 0.5, 0.5, r, g, b); milestones.push_back( GradientMilestone(0.6764, r, g, b) ); // hsv: 0.09 rad: 1.4 + Color::hsv2rgb01(0.1700, 0.5, 0.5, r, g, b); milestones.push_back( GradientMilestone(0.7647, r, g, b) ); // hsv: 0.17 rad: 1.7 + Color::hsv2rgb01(0.2650, 0.5, 0.5, r, g, b); milestones.push_back( GradientMilestone(0.8824, r, g, b) ); // hsv: 0.265 rad: 2.1 + Color::hsv2rgb01(0.3240, 0.5, 0.5, r, g, b); milestones.push_back( GradientMilestone(1. , r, g, b) ); // hsv: 0.324 rad: 2.5 + + setEnabledTooltipMarkup(M("TP_SHARPENING_TOOLTIP")); + + Gtk::HBox * buttonBox1 = Gtk::manage (new Gtk::HBox(true, 10)); + pack_start(*buttonBox1); + + Gtk::Button * lumacontrastMinusButton = Gtk::manage (new Gtk::Button(M("TP_DIRPYREQUALIZER_LUMACONTRAST_MINUS"))); + buttonBox1->pack_start(*lumacontrastMinusButton); + lumacontrastMinusPressedConn = lumacontrastMinusButton->signal_pressed().connect( sigc::mem_fun(*this, &DirPyrEqualizer::lumacontrastMinusPressed)); + + Gtk::Button * lumaneutralButton = Gtk::manage (new Gtk::Button(M("TP_DIRPYREQUALIZER_LUMANEUTRAL"))); + buttonBox1->pack_start(*lumaneutralButton); + lumaneutralPressedConn = lumaneutralButton->signal_pressed().connect( sigc::mem_fun(*this, &DirPyrEqualizer::lumaneutralPressed)); + + Gtk::Button * lumacontrastPlusButton = Gtk::manage (new Gtk::Button(M("TP_DIRPYREQUALIZER_LUMACONTRAST_PLUS"))); + buttonBox1->pack_start(*lumacontrastPlusButton); + lumacontrastPlusPressedConn = lumacontrastPlusButton->signal_pressed().connect( sigc::mem_fun(*this, &DirPyrEqualizer::lumacontrastPlusPressed)); + + buttonBox1->show_all_children(); + + Gtk::HSeparator *separator2 = Gtk::manage (new Gtk::HSeparator()); + pack_start(*separator2, Gtk::PACK_SHRINK, 2); + + for(int i = 0; i < 6; i++) + { + Glib::ustring ss; + ss = Glib::ustring::format(i); + if (i == 0) ss += Glib::ustring::compose(" (%1)", M("TP_DIRPYREQUALIZER_LUMAFINEST")); + else if(i == 5) ss += Glib::ustring::compose(" (%1)", M("TP_DIRPYREQUALIZER_LUMACOARSEST")); + multiplier[i] = Gtk::manage ( new Adjuster (ss, 0, 4, 0.01, 1.0) ); + multiplier[i]->setAdjusterListener(this); + pack_start(*multiplier[i]); + } + + Gtk::HSeparator *separator3 = Gtk::manage (new Gtk::HSeparator()); + pack_start(*separator3, Gtk::PACK_SHRINK, 2); + + threshold = Gtk::manage ( new Adjuster (M("TP_DIRPYREQUALIZER_THRESHOLD"), 0, 1, 0.01, 0.2) ); + threshold->setAdjusterListener(this); + pack_start(*threshold); + + Gtk::HSeparator *separator4 = Gtk::manage (new Gtk::HSeparator()); + pack_start(*separator4, Gtk::PACK_SHRINK, 2); +/* + algoHBox = Gtk::manage (new Gtk::HBox ()); + algoHBox->set_border_width (0); + algoHBox->set_spacing (2); + algoHBox->set_tooltip_markup (M("TP_DIRPYREQUALIZER_ALGO_TOOLTIP")); +*/ +// alLabel = Gtk::manage (new Gtk::Label (M("TP_DIRPYREQUALIZER_ALGO")+":")); +// algoHBox->pack_start (*alLabel, Gtk::PACK_SHRINK); +/* + algo = Gtk::manage (new MyComboBoxText ()); + algo->append_text (M("TP_DIRPYREQUALIZER_ALGO_FI")); + algo->append_text (M("TP_DIRPYREQUALIZER_ALGO_LA")); + algo->set_active (1); +// algoHBox->pack_start (*algo); +// pack_start(*algoHBox); + algoconn = algo->signal_changed().connect ( sigc::mem_fun(*this, &DirPyrEqualizer::algoChanged) ); +*/ + hueskin = Gtk::manage (new ThresholdAdjuster (M("TP_DIRPYREQUALIZER_HUESKIN"), -40., 210., -5., 25., 170., 120., 0, false)); //default (b_l 0, t_l 30, b_r 170, t_r 120); + hueskin->set_tooltip_markup (M("TP_DIRPYREQUALIZER_HUESKIN_TOOLTIP")); + + hueskin->setBgGradient(milestones); + pack_start(*hueskin); + + skinprotect = Gtk::manage ( new Adjuster (M("TP_DIRPYREQUALIZER_SKIN"), -100, 100, 1, 0.) ); + skinprotect->setAdjusterListener(this); + pack_start(*skinprotect); + skinprotect->set_tooltip_markup (M("TP_DIRPYREQUALIZER_SKIN_TOOLTIP")); + + gamutlab = Gtk::manage (new Gtk::CheckButton (M("TP_DIRPYREQUALIZER_ARTIF"))); + gamutlab->set_active (true); + pack_start(*gamutlab); + gamutlabConn = gamutlab->signal_toggled().connect( sigc::mem_fun(*this, &DirPyrEqualizer::gamutlabToggled) ); + gamutlab->set_tooltip_markup (M("TP_DIRPYREQUALIZER_TOOLTIP")); + + hueskin->setAdjusterListener (this); + + show_all_children (); + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +} + +DirPyrEqualizer::~DirPyrEqualizer () { + +} + +void DirPyrEqualizer::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + if (pedited) { + + set_inconsistent (multiImage && !pedited->dirpyrequalizer.enabled); + gamutlab->set_inconsistent (!pedited->dirpyrequalizer.gamutlab); + + for(int i = 0; i < 6; i++) { + multiplier[i]->setEditedState (pedited->dirpyrequalizer.mult[i] ? Edited : UnEdited); + } + threshold->setEditedState (pedited->dirpyrequalizer.threshold ? Edited : UnEdited); + skinprotect->setEditedState (pedited->dirpyrequalizer.skinprotect ? Edited : UnEdited); + hueskin->setEditedState (pedited->dirpyrequalizer.hueskin ? Edited : UnEdited); + } + + setEnabled(pp->dirpyrequalizer.enabled); + +/* + algoconn.block(true); + if (pedited && !pedited->dirpyrequalizer.algo) + algo->set_active (2); + else if (pp->dirpyrequalizer.algo=="FI") + algo->set_active (0); + else if (pp->dirpyrequalizer.algo=="LA") + algo->set_active (1); + algoconn.block(false); + algoChanged(); +*/ + gamutlabConn.block (true); + gamutlab->set_active (pp->dirpyrequalizer.gamutlab); + gamutlabConn.block (false); + lastgamutlab = pp->dirpyrequalizer.gamutlab; + + for (int i = 0; i < 6; i++) { + multiplier[i]->setValue(pp->dirpyrequalizer.mult[i]); + } + threshold->setValue(pp->dirpyrequalizer.threshold); + skinprotect->setValue(pp->dirpyrequalizer.skinprotect); + hueskin->setValue(pp->dirpyrequalizer.hueskin); + + enableListener (); +} + +void DirPyrEqualizer::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->dirpyrequalizer.enabled = getEnabled(); + pp->dirpyrequalizer.gamutlab = gamutlab->get_active (); + pp->dirpyrequalizer.hueskin = hueskin->getValue (); + + for (int i = 0; i < 6; i++) { + pp->dirpyrequalizer.mult[i] = multiplier[i]->getValue(); + } + pp->dirpyrequalizer.threshold = threshold->getValue(); + pp->dirpyrequalizer.skinprotect = skinprotect->getValue(); + + if (pedited) { + + pedited->dirpyrequalizer.enabled = !get_inconsistent(); + pedited->dirpyrequalizer.hueskin = hueskin->getEditedState (); + + for(int i = 0; i < 6; i++) { + pedited->dirpyrequalizer.mult[i] = multiplier[i]->getEditedState(); + } + pedited->dirpyrequalizer.threshold = threshold->getEditedState(); + pedited->dirpyrequalizer.skinprotect = skinprotect->getEditedState(); + // pedited->dirpyrequalizer.algo = algo->get_active_text()!=M("GENERAL_UNCHANGED"); + } +/* if (algo->get_active_row_number()==0) + pp->dirpyrequalizer.algo = "FI"; + else if (algo->get_active_row_number()==1) + pp->dirpyrequalizer.algo = "LA"; + */ +} +/* +void DirPyrEqualizer::algoChanged () { + if (listener && (multiImage||enabled->get_active()) ) { + listener->panelChanged (EvDirPyrEqualizeralg, algo->get_active_text ());} +} +*/ +void DirPyrEqualizer::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + for (int i = 0; i < 6; i++) { + multiplier[i]->setDefault(defParams->dirpyrequalizer.mult[i]); + } + threshold->setDefault(defParams->dirpyrequalizer.threshold); + hueskin->setDefault (defParams->dirpyrequalizer.hueskin); + + if (pedited) { + for (int i = 0; i < 6; i++) { + multiplier[i]->setDefaultEditedState(pedited->dirpyrequalizer.mult[i] ? Edited : UnEdited); + } + threshold->setDefaultEditedState(pedited->dirpyrequalizer.threshold ? Edited : UnEdited); + skinprotect->setDefaultEditedState(pedited->dirpyrequalizer.skinprotect ? Edited : UnEdited); + hueskin->setDefaultEditedState (pedited->dirpyrequalizer.hueskin ? Edited : UnEdited); + } + else { + for (int i = 0; i < 6; i++) { + multiplier[i]->setDefaultEditedState(Irrelevant); + } + threshold->setDefaultEditedState(Irrelevant); + skinprotect->setDefaultEditedState(Irrelevant); + hueskin->setDefaultEditedState (Irrelevant); + } +} + +void DirPyrEqualizer::adjusterChanged (ThresholdAdjuster* a, int newBottomLeft, int newTopLeft, int newBottomRight, int newTopRight) { + if (listener && (multiImage||getEnabled()) ) { + listener->panelChanged (EvDirPyrEqualizerHueskin, hueskin->getHistoryString()); + } +} + + +void DirPyrEqualizer::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + + for (int i = 0; i < 6; i++) { + multiplier[i]->showEditedCB(); + } + threshold->showEditedCB(); + skinprotect->showEditedCB(); + hueskin->showEditedCB (); + // algo->append_text (M("GENERAL_UNCHANGED")); +} + +void DirPyrEqualizer::adjusterChanged (Adjuster* a, double newval) { + + if (listener && getEnabled()) { + if (a == threshold) { + listener->panelChanged (EvDirPyrEqualizerThreshold, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(2), threshold->getValue())) + ); + } + else if (a == skinprotect) { + listener->panelChanged (EvDirPyrEqualizerSkin, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(2), skinprotect->getValue())) + ); + } + else { + listener->panelChanged (EvDirPyrEqualizer, + Glib::ustring::compose("%1, %2, %3, %4, %5, %6", + Glib::ustring::format(std::fixed, std::setprecision(2), multiplier[0]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(2), multiplier[1]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(2), multiplier[2]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(2), multiplier[3]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(2), multiplier[4]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(2), multiplier[5]->getValue())) + ); + } + } +} + +void DirPyrEqualizer::enabledChanged () { + + if (listener) { + if (get_inconsistent()) + listener->panelChanged (EvDirPyrEqlEnabled, M("GENERAL_UNCHANGED")); + else if (getEnabled()) + listener->panelChanged (EvDirPyrEqlEnabled, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvDirPyrEqlEnabled, M("GENERAL_DISABLED")); + } +} + +void DirPyrEqualizer::gamutlabToggled () { + + if (batchMode) { + if (gamutlab->get_inconsistent()) { + gamutlab->set_inconsistent (false); + gamutlabConn.block (true); + gamutlab->set_active (false); + gamutlabConn.block (false); + } + else if (lastgamutlab) + gamutlab->set_inconsistent (true); + + lastgamutlab = gamutlab->get_active (); + } + + if (listener) { + if (gamutlab->get_active ()) + listener->panelChanged (EvDirPyrEqlgamutlab, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvDirPyrEqlgamutlab, M("GENERAL_DISABLED")); + } +} + +void DirPyrEqualizer::lumaneutralPressed () { + + for (int i = 0; i < 6; i++) { + multiplier[i]->setValue(1.0); + adjusterChanged(multiplier[i], 1.0); + } +} + + +void DirPyrEqualizer::lumacontrastPlusPressed () { + + for (int i = 0; i < 6; i++) { + float inc = 0.05 * (6 - i); + multiplier[i]->setValue(multiplier[i]->getValue() + inc); + adjusterChanged(multiplier[i], multiplier[i]->getValue()); + } +} + + +void DirPyrEqualizer::lumacontrastMinusPressed () { + + for (int i = 0; i < 6; i++) { + float inc = -0.05 * (6 - i); + multiplier[i]->setValue(multiplier[i]->getValue() + inc); + adjusterChanged(multiplier[i], multiplier[i]->getValue()); + } +} + +void DirPyrEqualizer::setAdjusterBehavior (bool multiplieradd, bool thresholdadd, bool skinadd) { + + for (int i=0; i<6; i++) + multiplier[i]->setAddMode(multiplieradd); + threshold->setAddMode(thresholdadd); + skinprotect->setAddMode(skinadd); +} + +void DirPyrEqualizer::trimValues (rtengine::procparams::ProcParams* pp) { + + for (int i=0; i<6; i++) + multiplier[i]->trimValue(pp->dirpyrequalizer.mult[i]); + threshold->trimValue(pp->dirpyrequalizer.threshold); + skinprotect->trimValue(pp->dirpyrequalizer.skinprotect); +} diff --git a/rtgui/dirpyrequalizer.h b/rtgui/dirpyrequalizer.h new file mode 100644 index 000000000..3b5227331 --- /dev/null +++ b/rtgui/dirpyrequalizer.h @@ -0,0 +1,73 @@ +/* + * This file is part of RawTherapee. + * + * 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 . + * + * © 2010 Emil Martinec + */ + +#ifndef DIRPYREQUALIZER_H_INCLUDED +#define DIRPYREQUALIZER_H_INCLUDED + +#include +#include "adjuster.h" +#include "toolpanel.h" +#include "thresholdadjuster.h" +#include "colorprovider.h" + +class DirPyrEqualizer : public ToolParamBlock, public ThresholdAdjusterListener, public AdjusterListener, public FoldableToolPanel +{ + +protected: + + Gtk::CheckButton * gamutlab; + Adjuster* multiplier[6]; + Adjuster* threshold; + Adjuster* skinprotect; + ThresholdAdjuster* hueskin; + // MyComboBoxText* algo; + // sigc::connection algoconn; + // Gtk::Label* alLabel; + // Gtk::HBox* algoHBox; + + sigc::connection gamutlabConn; + sigc::connection lumaneutralPressedConn; + sigc::connection lumacontrastPlusPressedConn; + sigc::connection lumacontrastMinusPressedConn; + + bool lastgamutlab; + +public: + + DirPyrEqualizer (); + virtual ~DirPyrEqualizer (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + void setAdjusterBehavior (bool multiplieradd, bool thresholdadd, bool skinadd); + void trimValues (rtengine::procparams::ProcParams* pp); + void adjusterChanged (ThresholdAdjuster* a, int newBottomLeft, int newTopLeft, int newBottomRight, int newTopRight); +// void algoChanged (); + + void adjusterChanged (Adjuster* a, double newval); + void enabledChanged(); + void gamutlabToggled (); + void lumaneutralPressed (); + void lumacontrastPlusPressed (); + void lumacontrastMinusPressed (); +}; + +#endif diff --git a/rtgui/dirselectionlistener.h b/rtgui/dirselectionlistener.h new file mode 100644 index 000000000..2c1eaa0ed --- /dev/null +++ b/rtgui/dirselectionlistener.h @@ -0,0 +1,31 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _DIRSELECTIONLISTENER_ +#define _DIRSELECTIONLISTENER_ + +#include + +class DirSelectionListener { + + public: + virtual ~DirSelectionListener () {} + virtual void dirSelected (const Glib::ustring& dirname, const Glib::ustring& openfile="") {} +}; + +#endif diff --git a/rtgui/distortion.cc b/rtgui/distortion.cc new file mode 100644 index 000000000..79116c7e1 --- /dev/null +++ b/rtgui/distortion.cc @@ -0,0 +1,112 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "distortion.h" +#include +#include "rtimage.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +Distortion::Distortion (): FoldableToolPanel(this, "distortion", M("TP_DISTORTION_LABEL")) { + + rlistener = NULL; + autoDistor = Gtk::manage (new Gtk::Button (M("TP_DISTORTION_AUTO"))); + autoDistor->set_image (*Gtk::manage (new RTImage ("distortion-auto.png"))); + autoDistor->set_tooltip_text (M("TP_DISTORTION_AUTO_TIP")); + idConn = autoDistor->signal_pressed().connect( sigc::mem_fun(*this, &Distortion::idPressed) ); + autoDistor->show(); + pack_start (*autoDistor); + + Gtk::Image* idistL = Gtk::manage (new RTImage ("distortion-pincushion.png")); + Gtk::Image* idistR = Gtk::manage (new RTImage ("distortion-barrel.png")); + + distor = Gtk::manage (new Adjuster (M("TP_DISTORTION_AMOUNT"), -0.5, 0.5, 0.001, 0, idistL, idistR)); + distor->setAdjusterListener (this); + distor->show(); + pack_start (*distor); +} + +void Distortion::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + if (pedited) { + distor->setEditedState (pedited->distortion.amount ? Edited : UnEdited); + } + + distor->setValue (pp->distortion.amount); + + enableListener (); +} + +void Distortion::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->distortion.amount = distor->getValue (); + + if (pedited) { + pedited->distortion.amount = distor->getEditedState (); + } +} + +void Distortion::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + distor->setDefault (defParams->distortion.amount); + + if (pedited) { + distor->setDefaultEditedState (pedited->distortion.amount ? Edited : UnEdited); + } + else { + distor->setDefaultEditedState (Irrelevant); + } +} + +void Distortion::adjusterChanged (Adjuster* a, double newval) { + + if (listener) + listener->panelChanged (EvDISTAmount, Glib::ustring::format (std::setw(4), std::fixed, std::setprecision(3), a->getValue())); +} + +void Distortion::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + if (batchMode) { + autoDistor->set_sensitive(false); + } + distor->showEditedCB (); +} + +void Distortion::idPressed () { + if (!batchMode) { + if (rlistener) { + double new_amount = rlistener->autoDistorRequested(); + distor->setValue(new_amount); + adjusterChanged (distor, new_amount); + } + } +} + +void Distortion::setAdjusterBehavior (bool vadd) { + + distor->setAddMode(vadd); +} + +void Distortion::trimValues (rtengine::procparams::ProcParams* pp) { + + distor->trimValue(pp->distortion.amount); +} diff --git a/rtgui/distortion.h b/rtgui/distortion.h new file mode 100644 index 000000000..447c3c692 --- /dev/null +++ b/rtgui/distortion.h @@ -0,0 +1,51 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _DISTORTION_H_ +#define _DISTORTION_H_ + +#include +#include "adjuster.h" +#include "toolpanel.h" +#include "lensgeomlistener.h" + +class Distortion : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel { + + protected: + Gtk::Button* autoDistor; + Adjuster* distor; + sigc::connection idConn; + LensGeomListener * rlistener; + + public: + + Distortion (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + + void adjusterChanged (Adjuster* a, double newval); + void setAdjusterBehavior (bool vadd); + void trimValues (rtengine::procparams::ProcParams* pp); + void idPressed (); + void setLensGeomListener (LensGeomListener* l) { rlistener = l; } +}; + +#endif diff --git a/rtgui/edit.cc b/rtgui/edit.cc new file mode 100644 index 000000000..6f1344f6e --- /dev/null +++ b/rtgui/edit.cc @@ -0,0 +1,621 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "edit.h" +#include "../rtengine/editbuffer.h" + +void Coord::setFromPolar(PolarCoord polar) { + while (polar.angle < 0.f) polar.angle += 360.f; + while (polar.angle > 360.f) polar.angle -= 360.f; + x = polar.radius * cos(polar.angle/180.f*M_PI); + y = polar.radius * sin(polar.angle/180.f*M_PI); +} + +RGBColor Geometry::getInnerLineColor () { + RGBColor color; + if (flags & AUTO_COLOR) { + if (state == NORMAL) { color.setColor (1., 1., 1.); } // White + else if (state == PRELIGHT) { color.setColor (1., 1., 0.); } // Orange + else if (state == DRAGGED) { color.setColor (1., 0., 0.); } // Red + } + else { color = innerLineColor; } + return color; +} + +RGBColor Geometry::getOuterLineColor () { + RGBColor color; + if (flags & AUTO_COLOR) { + /* + if (state == NORMAL) { color.setColor (0., 0., 0.); } // Black + else if (state == PRELIGHT) { color.setColor (0., 0., 0.); } // Black + else if (state == DRAGGED) { color.setColor (1., 0., 0.); } // Black + */ + color.setColor (0., 0., 0.); // Black + } + else { color = outerLineColor; } + return color; +} + +void Circle::drawOuterGeometry(Cairo::RefPtr &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem) { + if (flags & ACTIVE) { + RGBColor color; + if (flags & AUTO_COLOR) + color = getOuterLineColor(); + else + color = outerLineColor; + + cr->set_source_rgb (color.getR(), color.getG(), color.getB()); + cr->set_line_width( getOuterLineWidth() ); + + Coord center_ = center; + double radius_ = radiusInImageSpace ? coordSystem.scaleValueToScreen(double(radius)) : double(radius); + if (datum == IMAGE) { + coordSystem.imageCoordToScreen(center.x, center.y, center_.x, center_.y); + } + else if (datum == CLICKED_POINT) { + center_ += editBuffer->getDataProvider()->posScreen; + } + else if (datum == CURSOR) { + center_ += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; + } + cr->arc(center_.x+0.5, center_.y+0.5, radius_, 0., 2.*M_PI); + cr->stroke(); + } +} + +void Circle::drawInnerGeometry(Cairo::RefPtr &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem) { + if (flags & ACTIVE) { + RGBColor color; + if (flags & AUTO_COLOR) + color = getInnerLineColor(); + else + color = innerLineColor; + + cr->set_source_rgb (color.getR(), color.getG(), color.getB()); + cr->set_line_width( innerLineWidth ); + + Coord center_ = center; + double radius_ = radiusInImageSpace ? coordSystem.scaleValueToScreen(double(radius)) : double(radius); + if (datum == IMAGE) { + coordSystem.imageCoordToScreen(center.x, center.y, center_.x, center_.y); + } + else if (datum == CLICKED_POINT) { + center_ += editBuffer->getDataProvider()->posScreen; + } + else if (datum == CURSOR) { + center_ += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; + } + if (filled) { + cr->arc(center_.x+0.5, center_.y+0.5, radius_, 0., 2.*M_PI); + if (innerLineWidth > 0.) { + cr->fill_preserve(); + cr->stroke(); + } + else + cr->fill(); + } + else if (innerLineWidth > 0.) { + cr->arc(center_.x+0.5, center_.y+0.5, radius_, 0., 2.*M_PI); + cr->stroke(); + } + } +} + +void Circle::drawToMOChannel (Cairo::RefPtr &cr, Cairo::RefPtr &cr2, unsigned short id, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem) { + if (flags & ACTIVE) { + cr->set_line_width( getMouseOverLineWidth() ); + Coord center_ = center; + double radius_ = radiusInImageSpace ? coordSystem.scaleValueToScreen(double(radius)) : double(radius); + if (datum == IMAGE) { + coordSystem.imageCoordToCropBuffer(center.x, center.y, center_.x, center_.y); + } + else if (datum == CLICKED_POINT) { + center_ += editBuffer->getDataProvider()->posScreen; + } + else if (datum == CURSOR) { + center_ += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; + } + + // drawing the lower byte's value + unsigned short a = (id+1) & 0xFF; + cr->set_source_rgba (0.,0., 0., double(a)/255.); + cr->arc(center_.x+0.5, center_.y+0.5, radius_, 0, 2.*M_PI); + if (filled) { + if (innerLineWidth > 0.) { + cr->fill_preserve(); + cr->stroke(); + } + else + cr->fill(); + } + else + cr->stroke(); + + // drawing the higher byte's value + if (editBuffer->getObjectMode() == OM_65535) { + a = (id+1)>>8; + cr2->set_source_rgba (0.,0., 0., double(a)/255.); + cr2->arc(center_.x+0.5, center_.y+0.5, radius_, 0, 2.*M_PI); + if (filled) { + if (innerLineWidth > 0.) { + cr2->fill_preserve(); + cr2->stroke(); + } + else + cr2->fill(); + } + else + cr2->stroke(); + } + } +} + +void Line::drawOuterGeometry(Cairo::RefPtr &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem) { + if (flags & ACTIVE) { + RGBColor color; + if (flags & AUTO_COLOR) + color = getOuterLineColor(); + else + color = outerLineColor; + + cr->set_source_rgb (color.getR(), color.getG(), color.getB()); + cr->set_line_width( getOuterLineWidth() ); + + Coord begin_ = begin; + Coord end_ = end; + if (datum == IMAGE) { + coordSystem.imageCoordToScreen(begin.x, begin.y, begin_.x, begin_.y); + coordSystem.imageCoordToScreen(end.x, end.y, end_.x, end_.y); + } + else if (datum == CLICKED_POINT) { + begin_ += editBuffer->getDataProvider()->posScreen; + end_ += editBuffer->getDataProvider()->posScreen; + } + else if (datum == CURSOR) { + begin_ += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; + end_ += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; + } + cr->move_to(begin_.x+0.5, begin_.y+0.5); + cr->line_to(end_.x+0.5, end_.y+0.5); + cr->stroke(); + } +} + +void Line::drawInnerGeometry(Cairo::RefPtr &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem) { + if ((flags & ACTIVE) && innerLineWidth > 0.) { + RGBColor color; + if (flags & AUTO_COLOR) + color = getInnerLineColor(); + else + color = innerLineColor; + + cr->set_source_rgb (color.getR(), color.getG(), color.getB()); + cr->set_line_width(innerLineWidth); + + Coord begin_ = begin; + Coord end_ = end; + if (datum == IMAGE) { + coordSystem.imageCoordToScreen(begin.x, begin.y, begin_.x, begin_.y); + coordSystem.imageCoordToScreen(end.x, end.y, end_.x, end_.y); + } + else if (datum == CLICKED_POINT) { + begin_ += editBuffer->getDataProvider()->posScreen; + end_ += editBuffer->getDataProvider()->posScreen; + } + else if (datum == CURSOR) { + begin_ += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; + end_ += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; + } + cr->move_to(begin_.x+0.5, begin_.y+0.5); + cr->line_to(end_.x+0.5, end_.y+0.5); + cr->stroke(); + } +} + +void Line::drawToMOChannel (Cairo::RefPtr &cr, Cairo::RefPtr &cr2, unsigned short id, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem) { + if (flags & ACTIVE) { + cr->set_line_width( getMouseOverLineWidth() ); + Coord begin_ = begin; + Coord end_ = end; + if (datum == IMAGE) { + coordSystem.imageCoordToCropBuffer(begin.x, begin.y, begin_.x, begin_.y); + coordSystem.imageCoordToCropBuffer(end.x, end.y, end_.x, end_.y); + } + else if (datum == CLICKED_POINT) { + begin_ += editBuffer->getDataProvider()->posScreen; + end_ += editBuffer->getDataProvider()->posScreen; + } + else if (datum == CURSOR) { + begin_ += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; + end_ += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; + } + + // drawing the lower byte's value + unsigned short a = (id+1) & 0xFF; + cr->set_source_rgba (0.,0., 0., double(a)/255.); + cr->move_to(begin_.x+0.5, begin_.y+0.5); + cr->line_to(end_.x+0.5, end_.y+0.5); + cr->stroke(); + + // drawing the higher byte's value + if (editBuffer->getObjectMode() == OM_65535) { + a = (id+1)>>8; + cr2->set_source_rgba (0.,0., 0., double(a)/255.); + cr2->move_to(begin_.x+0.5, begin_.y+0.5); + cr2->line_to(end_.x+0.5, end_.y+0.5); + cr2->stroke(); + } + } +} + +void Polyline::drawOuterGeometry(Cairo::RefPtr &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem) { + if ((flags & ACTIVE) && points.size()>1) { + RGBColor color; + if (flags & AUTO_COLOR) + color = getOuterLineColor(); + else + color = outerLineColor; + + cr->set_source_rgb (color.getR(), color.getG(), color.getB()); + cr->set_line_width( getOuterLineWidth() ); + + Coord currPos; + for (unsigned int i=0; igetDataProvider()->posScreen; + else if (datum == CURSOR) currPos += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; + + if (!i) cr->move_to(currPos.x+0.5, currPos.y+0.5); + else cr->line_to(currPos.x+0.5, currPos.y+0.5); + } + if (filled) { + cr->fill_preserve(); + cr->stroke(); + } + else + cr->stroke(); + } +} + +void Polyline::drawInnerGeometry(Cairo::RefPtr &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem) { + if ((flags & ACTIVE) && points.size()>1) { + RGBColor color; + if (flags & AUTO_COLOR) + color = getInnerLineColor(); + else + color = innerLineColor; + + cr->set_source_rgb (color.getR(), color.getG(), color.getB()); + cr->set_line_width( getOuterLineWidth() ); + + if (filled) { + Coord currPos; + for (unsigned int i=0; igetDataProvider()->posScreen; + else if (datum == CURSOR) currPos += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; + + if (!i) cr->move_to(currPos.x+0.5, currPos.y+0.5); + else cr->line_to(currPos.x+0.5, currPos.y+0.5); + } + + if (innerLineWidth > 0.) { + cr->fill_preserve(); + cr->stroke(); + } + else + cr->fill(); + } + else if (innerLineWidth > 0.) { + Coord currPos; + for (unsigned int i=0; igetDataProvider()->posScreen; + else if (datum == CURSOR) currPos += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; + + if (!i) cr->move_to(currPos.x+0.5, currPos.y+0.5); + else cr->line_to(currPos.x+0.5, currPos.y+0.5); + } + cr->stroke(); + } + } +} + +void Polyline::drawToMOChannel (Cairo::RefPtr &cr, Cairo::RefPtr &cr2, unsigned short id, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem) { + if ((flags & ACTIVE) && points.size()>1) { + Coord currPos; + + // drawing the lower byte's value + unsigned short a = (id+1) & 0xFF; + cr->set_source_rgba (0.,0., 0., double(a)/255.); + for (unsigned int i=0; iset_line_width( getOuterLineWidth() ); + currPos = points.at(i); + + if (datum == IMAGE) coordSystem.imageCoordToCropBuffer(points.at(i).x, points.at(i).y, currPos.x, currPos.y); + else if (datum == CLICKED_POINT) currPos += editBuffer->getDataProvider()->posScreen; + else if (datum == CURSOR) currPos += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; + + if (!i) cr->move_to(currPos.x+0.5, currPos.y+0.5); + else cr->line_to(currPos.x+0.5, currPos.y+0.5); + } + if (filled) { + if (innerLineWidth > 0.) { + cr->fill_preserve(); + cr->stroke(); + } + else + cr->fill(); + } + else + cr->stroke(); + + // drawing the higher byte's value + if (editBuffer->getObjectMode() == OM_65535) { + a = (id+1)>>8; + cr2->set_source_rgba (0.,0., 0., double(a)/255.); + for (unsigned int i=0; iset_line_width( getOuterLineWidth() ); + currPos = points.at(i); + + if (datum == IMAGE) coordSystem.imageCoordToCropBuffer(points.at(i).x, points.at(i).y, currPos.x, currPos.y); + else if (datum == CLICKED_POINT) currPos += editBuffer->getDataProvider()->posScreen; + else if (datum == CURSOR) currPos += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; + + if (!i) cr2->move_to(currPos.x+0.5, currPos.y+0.5); + else cr2->line_to(currPos.x+0.5, currPos.y+0.5); + } + if (filled) { + if (innerLineWidth > 0.) { + cr2->fill_preserve(); + cr2->stroke(); + } + else + cr2->fill(); + } + else + cr2->stroke(); + } + } +} + +void Rectangle::setXYWH(int left, int top, int width, int height) { + topLeft.set(left, top); + bottomRight.set(left+width, top+height); +} + +void Rectangle::setXYXY(int left, int top, int right, int bottom) { + topLeft.set(left, top); + bottomRight.set(right, bottom); +} + +void Rectangle::setXYWH(Coord topLeft, Coord widthHeight) { + this->topLeft = topLeft; + this->bottomRight = topLeft + widthHeight; +} + +void Rectangle::setXYXY(Coord topLeft, Coord bottomRight) { + this->topLeft = topLeft; + this->bottomRight = bottomRight; +} + +void Rectangle::drawOuterGeometry (Cairo::RefPtr &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem) { + if ((flags & ACTIVE)) { + RGBColor color; + if (flags & AUTO_COLOR) + color = getOuterLineColor(); + else + color = outerLineColor; + + cr->set_source_rgb (color.getR(), color.getG(), color.getB()); + cr->set_line_width( getOuterLineWidth() ); + + Coord tl, br; + + if (datum == IMAGE) coordSystem.imageCoordToScreen(topLeft.x, topLeft.y, tl.x, tl.y); + else if (datum == CLICKED_POINT) tl = topLeft + editBuffer->getDataProvider()->posScreen; + else if (datum == CURSOR) tl = topLeft +editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; + + if (datum == IMAGE) coordSystem.imageCoordToScreen(bottomRight.x, bottomRight.y, br.x, br.y); + else if (datum == CLICKED_POINT) br = bottomRight + editBuffer->getDataProvider()->posScreen; + else if (datum == CURSOR) br = bottomRight +editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; + + cr->rectangle(tl.x+0.5, tl.y+0.5, br.x-tl.x, br.y-tl.y); + + if (filled) { + cr->fill_preserve(); + cr->stroke(); + } + else + cr->stroke(); + } +} + +void Rectangle::drawInnerGeometry (Cairo::RefPtr &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem) { + if (flags & ACTIVE) { + RGBColor color; + if (flags & AUTO_COLOR) + color = getInnerLineColor(); + else + color = innerLineColor; + + cr->set_source_rgb (color.getR(), color.getG(), color.getB()); + cr->set_line_width( innerLineWidth ); + + Coord tl, br; + if (datum == IMAGE) coordSystem.imageCoordToScreen(topLeft.x, topLeft.y, tl.x, tl.y); + else if (datum == CLICKED_POINT) tl = topLeft + editBuffer->getDataProvider()->posScreen; + else if (datum == CURSOR) tl = topLeft +editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; + + if (datum == IMAGE) coordSystem.imageCoordToScreen(bottomRight.x, bottomRight.y, br.x, br.y); + else if (datum == CLICKED_POINT) br = bottomRight + editBuffer->getDataProvider()->posScreen; + else if (datum == CURSOR) br = bottomRight +editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; + + if (filled) { + cr->rectangle(tl.x+0.5, tl.y+0.5, br.x-tl.x, br.y-tl.y); + if (innerLineWidth > 0.) { + cr->fill_preserve(); + cr->stroke(); + } + else + cr->fill(); + } + else if (innerLineWidth > 0.) { + cr->rectangle(tl.x+0.5, tl.y+0.5, br.x-tl.x, br.y-tl.y); + cr->stroke(); + } + } +} + +void Rectangle::drawToMOChannel (Cairo::RefPtr &cr, Cairo::RefPtr &cr2, unsigned short id, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem) { + if (flags & ACTIVE) { + cr->set_line_width( getMouseOverLineWidth() ); + + Coord tl, br; + if (datum == IMAGE) coordSystem.imageCoordToCropBuffer(topLeft.x, topLeft.y, tl.x, tl.y); + else if (datum == CLICKED_POINT) tl = topLeft + editBuffer->getDataProvider()->posScreen; + else if (datum == CURSOR) tl = topLeft +editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; + + if (datum == IMAGE) coordSystem.imageCoordToCropBuffer(bottomRight.x, bottomRight.y, br.x, br.y); + else if (datum == CLICKED_POINT) br = bottomRight + editBuffer->getDataProvider()->posScreen; + else if (datum == CURSOR) br = bottomRight +editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; + + // drawing the lower byte's value + unsigned short a = (id+1) & 0xFF; + cr->set_source_rgba (0.,0., 0., double(a)/255.); + cr->rectangle(tl.x+0.5, tl.y+0.5, br.x-tl.x, br.y-tl.y); + if (filled) { + if (innerLineWidth > 0.) { + cr->fill_preserve(); + cr->stroke(); + } + else + cr->fill(); + } + else + cr->stroke(); + + // drawing the higher byte's value + if (editBuffer->getObjectMode() == OM_65535) { + a = (id+1)>>8; + cr2->set_source_rgba (0.,0., 0., double(a)/255.); + cr->rectangle(tl.x+0.5, tl.y+0.5, br.x-tl.x, br.y-tl.y); + if (filled) { + if (innerLineWidth > 0.) { + cr2->fill_preserve(); + cr2->stroke(); + } + else + cr2->fill(); + } + else + cr2->stroke(); + } + } +} + +EditSubscriber::EditSubscriber (EditType editType) : ID(EUID_None), editingType(editType), bufferType(BT_SINGLEPLANE_FLOAT), provider(NULL) {} + +void EditSubscriber::setEditProvider(EditDataProvider *provider) { + this->provider = provider; +} + +void EditSubscriber::setEditID(EditUniqueID ID, BufferType buffType) { + this->ID = ID; + bufferType = buffType; +} + +bool EditSubscriber::isCurrentSubscriber() { + //if (provider && provider->getCurrSubscriber()) + // return provider->getCurrSubscriber()->getEditID() == ID; + + if (provider) + return provider->getCurrSubscriber() == this; + + return false; +} + +void EditSubscriber::subscribe() { + if (provider) + provider->subscribe(this); +} + +void EditSubscriber::unsubscribe() { + if (provider) + provider->unsubscribe(); +} + +void EditSubscriber::switchOffEditMode() { + unsubscribe(); +} + +EditUniqueID EditSubscriber::getEditID() { + return ID; +} + +EditType EditSubscriber::getEditingType() { + return editingType; +} + +BufferType EditSubscriber::getEditBufferType() { + return bufferType; +} + + +//-------------------------------------------------------------------------------------------------- + + +EditDataProvider::EditDataProvider() : currSubscriber(NULL), object(0), posScreen(-1,-1), posImage(-1,-1), + deltaScreen(0,0), deltaImage(0,0), deltaPrevScreen(0,0), deltaPrevImage(0,0) { + pipetteVal[0] = pipetteVal[1] = pipetteVal[2] = 0.f; +} + +void EditDataProvider::subscribe(EditSubscriber *subscriber) { + if (currSubscriber) + currSubscriber->switchOffEditMode(); + + currSubscriber = subscriber; +} + +void EditDataProvider::unsubscribe() { + currSubscriber = NULL; +} + +void EditDataProvider::switchOffEditMode() { + if (currSubscriber) + currSubscriber->switchOffEditMode (); +} + +CursorShape EditDataProvider::getCursor(int objectID) { + if (currSubscriber) + currSubscriber->getCursor(objectID); + + return CSOpenHand; +} + +EditSubscriber* EditDataProvider::getCurrSubscriber() { + return currSubscriber; +} + diff --git a/rtgui/edit.h b/rtgui/edit.h new file mode 100644 index 000000000..1e7159384 --- /dev/null +++ b/rtgui/edit.h @@ -0,0 +1,322 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _EDIT_H_ +#define _EDIT_H_ + +#include +#include "../rtengine/imagefloat.h" +#include "editid.h" +#include "cursormanager.h" +#include "../rtengine/rt_math.h" +#include "coord.h" + +class EditDataProvider; + +namespace rtengine { +class EditBuffer; +} + +/** @file + * + * The Edit mechanism is designed to let tools (subscribers) communicate with the preview area (provider). + * Subscribers will be tools that need to create some graphics in the preview area, to let the user interact + * with it in a more user friendly way. + * + * Do not confuse with a _local_ editing, which is another topic implemented in another class. The Edit feature + * is also not supported in batch editing from the File Browser. + * + * Each Edit tool must have a unique ID, that will identify them, and which let the ImProcCoordinator or other + * mechanism act as appropriated. They are all defined in rtgui/editid.h. + * + * ## How does it works? + * + * When a tool is being constructed, unique IDs are affected to the EditSubscribers. Then the EditorPanel class + * will ask all ToolPanel to register the 'after' preview ImageArea object as data provider. The Subscribers + * have now to provide a toggle button to click on to start the Edit listening. When toggling on, the Subscriber + * register itself to the DataProvider, then an event is thrown through the standard ToolPanelListener::panelChanged + * method to update the preview with new graphics to be displayed, and eventually buffers to create and populate. + * + * When the Edit process stops, the Subscriber is removed from the DataProvider, so buffer can be freed up. + * A new ToolPanelListener::panelChanged event is also thrown to update the preview again, without the tool's + * graphical objects. The Edit button is also toggled off (by the user or programmatically). + * + * It means that each Edit buttons toggled on will start an update of the preview which might or might not create + * a new History entry, depending on the event. + * + */ + + +/** @brief Coordinate system where the widgets will be drawn + * + * The EditCoordSystem is used to define a screen and an image coordinate system. + */ +class EditCoordSystem { +public: + virtual ~EditCoordSystem() {} + + /// Convert the widget's DrawingArea (i.e. preview area) coords to the edit buffer coords + virtual void screenCoordToCropBuffer (int phyx, int phyy, int& cropx, int& cropy) =0; + /// Convert the widget's DrawingArea (i.e. preview area) coords to the full image coords + virtual void screenCoordToImage (int phyx, int phyy, int& imgx, int& imgy) =0; + /// Convert the image coords to the widget's DrawingArea (i.e. preview area) coords + virtual void imageCoordToScreen (int imgx, int imgy, int& phyx, int& phyy) =0; + /// Convert the image coords to the edit buffer coords + virtual void imageCoordToCropBuffer (int imgx, int imgy, int& phyx, int& phyy) =0; + /// Convert a size value from the preview's scale to the image's scale + virtual int scaleValueToImage (int value) =0; + /// Convert a size value from the preview's scale to the image's scale + virtual float scaleValueToImage (float value) =0; + /// Convert a size value from the preview's scale to the image's scale + virtual double scaleValueToImage (double value) =0; + /// Convert a size value from the image's scale to the preview's scale + virtual int scaleValueToScreen (int value) =0; + /// Convert a size value from the image's scale to the preview's scale + virtual float scaleValueToScreen (float value) =0; + /// Convert a size value from the image's scale to the preview's scale + virtual double scaleValueToScreen (double value) =0; +}; + +class RGBColor { + double r; + double g; + double b; + +public: + RGBColor () : r(0.), g(0.), b(0.) {} + explicit RGBColor (double r, double g, double b) : r(r), g(g), b(b) {} + explicit RGBColor (char r, char g, char b) : r(double(r)/255.), g(double(g)/255.), b(double(b)/255.) {} + + void setColor(double r, double g, double b) { + this->r = r; + this->g = g; + this->b = b; + } + + void setColor(char r, char g, char b) { + this->r = double(r)/255.; + this->g = double(g)/255.; + this->b = double(b)/255.; + } + + double getR() { return r; } + double getG() { return g; } + double getB() { return b; } +}; + +class Geometry { +public: + enum State { + NORMAL, + PRELIGHT, + DRAGGED + }; + enum Datum { + IMAGE, + CLICKED_POINT, + CURSOR + }; + enum Flags { + ACTIVE = 1<<0, // true if the geometry is active and have to be drawn + AUTO_COLOR = 1<<1, // true if the color depend on the state value, not the color field above + }; + +protected: + RGBColor innerLineColor; + RGBColor outerLineColor; + short flags; + +public: + float innerLineWidth; // ...outerLineWidth = innerLineWidth+2 + Datum datum; + State state; // set by the Subscriber + + Geometry () : innerLineColor(char(255), char(255), char(255)), outerLineColor(char(0), char(0), char(0)), flags(ACTIVE|AUTO_COLOR), innerLineWidth(1.f), datum(IMAGE), state(NORMAL) {} + virtual ~Geometry() {} + + void setInnerLineColor (double r, double g, double b) { innerLineColor.setColor(r, g, b); flags &= ~AUTO_COLOR; } + void setInnerLineColor (char r, char g, char b) { innerLineColor.setColor(r, g, b); flags &= ~AUTO_COLOR; } + RGBColor getInnerLineColor (); + void setOuterLineColor (double r, double g, double b) { outerLineColor.setColor(r, g, b); flags &= ~AUTO_COLOR; } + void setOuterLineColor (char r, char g, char b) { outerLineColor.setColor(r, g, b); flags &= ~AUTO_COLOR; } + RGBColor getOuterLineColor (); + double getOuterLineWidth () { return double(innerLineWidth)+2.; } + double getMouseOverLineWidth () { return getOuterLineWidth()+2.; } + void setAutoColor (bool aColor) { if (aColor) flags |= AUTO_COLOR; else flags &= ~AUTO_COLOR; } + void setActive (bool active) { if (active) flags |= ACTIVE; else flags &= ~ACTIVE; } + + virtual void drawOuterGeometry (Cairo::RefPtr &cr, rtengine::EditBuffer *parent, EditCoordSystem &coordSystem) =0; + virtual void drawInnerGeometry (Cairo::RefPtr &cr, rtengine::EditBuffer *parent, EditCoordSystem &coordSystem) =0; + virtual void drawToMOChannel (Cairo::RefPtr &cr, Cairo::RefPtr &cr2, unsigned short id, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem) =0; +}; + +class Circle : public Geometry { +public: + Coord center; + int radius; + bool filled; + bool radiusInImageSpace; /// If true, the radius depend on the image scale; if false, it is a fixed 'screen' size + + Circle () : center(100,100), radius(10), filled(false), radiusInImageSpace(false) {} + Circle (Coord ¢er, int radius, bool filled=false, bool radiusInImageSpace=false) : center(center), radius(radius), filled(filled), radiusInImageSpace(radiusInImageSpace) {} + Circle (int centerX, int centerY, int radius, bool filled=false, bool radiusInImageSpace=false) : center(centerX, centerY), radius(radius), filled(filled), radiusInImageSpace(radiusInImageSpace) {} + + void drawOuterGeometry (Cairo::RefPtr &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem); + void drawInnerGeometry (Cairo::RefPtr &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem); + void drawToMOChannel (Cairo::RefPtr &cr, Cairo::RefPtr &cr2, unsigned short id, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem); +}; + +class Line : public Geometry { +public: + Coord begin; + Coord end; + + Line () : begin(10,10), end(100,100) {} + Line (Coord &begin, Coord &end) : begin(begin), end(end) {} + Line (int beginX, int beginY, int endX, int endY) : begin(beginX, beginY), end(endX, endY) {} + + void drawOuterGeometry (Cairo::RefPtr &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem); + void drawInnerGeometry (Cairo::RefPtr &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem); + void drawToMOChannel (Cairo::RefPtr &cr, Cairo::RefPtr &cr2, unsigned short id, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem); +}; + +class Polyline : public Geometry { +public: + std::vector points; + bool filled; + + Polyline() : filled(false) {} + + void drawOuterGeometry (Cairo::RefPtr &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem); + void drawInnerGeometry (Cairo::RefPtr &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem); + void drawToMOChannel (Cairo::RefPtr &cr, Cairo::RefPtr &cr2, unsigned short id, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem); +}; + +class Rectangle : public Geometry { +public: + Coord topLeft; + Coord bottomRight; + bool filled; + + Rectangle() : topLeft(0,0), bottomRight(10,10), filled(false) {} + + void setXYWH(int left, int top, int width, int height); + void setXYXY(int left, int top, int right, int bottom); + void setXYWH(Coord topLeft, Coord widthHeight); + void setXYXY(Coord topLeft, Coord bottomRight); + void drawOuterGeometry (Cairo::RefPtr &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem); + void drawInnerGeometry (Cairo::RefPtr &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem); + void drawToMOChannel (Cairo::RefPtr &cr, Cairo::RefPtr &cr2, unsigned short id, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem); +}; + +/// @brief Method for client tools needing Edit information +class EditSubscriber { + +public: + +private: + EditUniqueID ID; /// this will be used in improcfun to locate the data that has to be stored in the buffer; it must be unique in RT + EditType editingType; + BufferType bufferType; + EditDataProvider *provider; + +protected: + std::vector visibleGeometry; + std::vector mouseOverGeometry; + +public: + EditSubscriber (EditType editType); + virtual ~EditSubscriber () {} + + void setEditProvider(EditDataProvider *provider); + EditDataProvider* getEditProvider() { return provider; } + void setEditID(EditUniqueID ID, BufferType buffType); + bool isCurrentSubscriber(); + virtual void subscribe(); + virtual void unsubscribe(); + virtual void switchOffEditMode (); /// Occurs when the user want to stop the editing mode + EditUniqueID getEditID(); + EditType getEditingType(); + BufferType getEditBufferType(); + + /** @brief Get the cursor to be displayed when above handles + @param objectID object currently "hovered" */ + virtual CursorShape getCursor(int objectID) { return CSOpenHand; } + + /** @brief Triggered when the mouse is moving over an object + This method is also triggered when the cursor is moving over the image in ET_PIPETTE mode + @param modifierKey Gtk's event modifier key (GDK_CONTROL_MASK | GDK_SHIFT_MASK | ...) + @param editBuffer buffer to get the pipette values and the from + @return true if the preview has to be redrawn, false otherwise */ + virtual bool mouseOver(int modifierKey) { return false; } + + /** @brief Triggered when mouse button 1 is pressed, together with the CTRL modifier key if the subscriber is of type ET_PIPETTE + @param modifierKey Gtk's event modifier key (GDK_CONTROL_MASK | GDK_SHIFT_MASK | ...) + @return true if the preview has to be redrawn, false otherwise */ + virtual bool button1Pressed(int modifierKey) { return false; } + + /** @brief Triggered when mouse button 1 is released + @return true if the preview has to be redrawn, false otherwise */ + virtual bool button1Released() { return false; } + + /** @brief Triggered when the user is moving while holding down mouse button 1 + @param modifierKey Gtk's event modifier key (GDK_CONTROL_MASK | GDK_SHIFT_MASK | ...) + @return true if the preview has to be redrawn, false otherwise */ + virtual bool drag(int modifierKey) { return false; } + + /** @brief Get the geometry to be shown to the user */ + const std::vector & getVisibleGeometry() { return visibleGeometry; } + + /** @brief Get the geometry to be drawn in the "mouse over" channel, hidden from the user */ + const std::vector & getMouseOverGeometry() { return mouseOverGeometry; } +}; + +/** @brief Class to handle the furniture of data to the subscribers. + * + * It is admitted that only one Subscriber can ask data at a time. If the Subscriber is of type ET_PIPETTE, it will have to + * trigger the usual event so that the image will be reprocessed to compute the buffer of the current subscriber. + */ +class EditDataProvider { + +private: + EditSubscriber *currSubscriber; + +public: + int object; /// ET_OBJECTS mode: Object detected under the cursor, 0 otherwise; ET_PIPETTE mode: 1 if above the image, 0 otherwise + float pipetteVal[3]; /// Current pipette values; if bufferType==BT_SINGLEPLANE_FLOAT, #2 & #3 will be set to 0 + + Coord posScreen; /// Location of the mouse button press, in preview image space + Coord posImage; /// Location of the mouse button press, in the full image space + Coord deltaScreen; /// Delta relative to posScreen + Coord deltaImage; /// Delta relative to posImage + Coord deltaPrevScreen; /// Delta relative to the previous mouse location, in preview image space + Coord deltaPrevImage; /// Delta relative to the previous mouse location, in the full image space + + EditDataProvider(); + virtual ~EditDataProvider() {} + + virtual void subscribe(EditSubscriber *subscriber); + virtual void unsubscribe(); /// Occurs when the subscriber has been switched off first + virtual void switchOffEditMode (); /// Occurs when the user want to stop the editing mode + virtual CursorShape getCursor(int objectID); + int getPipetteRectSize() { return 8; } // TODO: make a GUI + EditSubscriber* getCurrSubscriber(); + virtual void getImageSize (int &w, int&h) =0; +}; + +#endif diff --git a/rtgui/editedstate.h b/rtgui/editedstate.h new file mode 100644 index 000000000..003c2f29f --- /dev/null +++ b/rtgui/editedstate.h @@ -0,0 +1,25 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _EDITEDSTATE_ +#define _EDITEDSTATE_ + +enum EditedState { UnEdited=0, Edited=1, Irrelevant=2 }; + +#endif + diff --git a/rtgui/editenums.h b/rtgui/editenums.h new file mode 100644 index 000000000..e92114b58 --- /dev/null +++ b/rtgui/editenums.h @@ -0,0 +1,27 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _EDITENUMS_ +#define _EDITENUMS_ + +enum ImgEditState {SNormal, SCropMove, SHandMove, SResizeW1, SResizeW2, SResizeH1, SResizeH2, SResizeTL, SResizeTR, SResizeBL, SResizeBR, + SCropSelecting, SRotateSelecting, SCropWinMove, SCropFrameMove, SCropImgMove, SCropWinResize, SObservedMove, SEditDrag}; +enum CursorArea {CropWinButtons, CropToolBar, CropImage, CropBorder, CropTop, CropTopLeft, CropTopRight, CropBottom, CropBottomLeft, + CropBottomRight, CropLeft, CropRight, CropInside, CropResize, CropObserved}; + +#endif diff --git a/rtgui/editid.h b/rtgui/editid.h new file mode 100644 index 000000000..35308f5fa --- /dev/null +++ b/rtgui/editid.h @@ -0,0 +1,71 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _EDITID_H_ +#define _EDITID_H_ + + +/// @brief List of pipette editing operation +enum EditUniqueID { + EUID_None, /// special value (default) + + EUID_ToneCurve1, + EUID_ToneCurve2, + EUID_Lab_LCurve, + EUID_Lab_CCurve, + EUID_Lab_LCCurve, + EUID_Lab_CLCurve, + EUID_Lab_LHCurve, + EUID_Lab_CHCurve, + EUID_Lab_HHCurve, + EUID_Lab_aCurve, + EUID_Lab_bCurve, + EUID_RGB_R, + EUID_RGB_G, + EUID_RGB_B, + EUID_HSV_H, + EUID_HSV_S, + EUID_HSV_V, + EUID_BlackWhiteLuminance, + EUID_BlackWhiteBeforeCurve, + EUID_BlackWhiteAfterCurve, + EUID_WW_HHCurve, + +}; + +/// @brief Editing mechanisms +// TODO: Look out if it has to be a bitfield to allow both mechanisms at a time +enum EditType { + ET_PIPETTE, /// Will trigger dedicated methods; can have a geometry list to be displayed, but without "mouse over" capabilities + ET_OBJECTS /// The objects are geometrical widgets with "mouse over" capabilities +}; + +/// @brief Buffer type for ET_PIPETTE type editing +enum BufferType { + BT_IMAGEFLOAT, + BT_LABIMAGE, + BT_SINGLEPLANE_FLOAT +}; + +/// @brief Number of object to be handled (for optimization purpose) +enum ObjectMode { + OM_255, /// less or equal than 255 objects + OM_65535 /// less or equal than 65535 objects +}; + +#endif diff --git a/rtgui/editorpanel.cc b/rtgui/editorpanel.cc new file mode 100755 index 000000000..0bf960b63 --- /dev/null +++ b/rtgui/editorpanel.cc @@ -0,0 +1,1656 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * Copyright (c) 2010 Oliver Duis + * + * 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 "editorpanel.h" +#include "options.h" +#include "progressconnector.h" +#include "rtwindow.h" +#include "guiutils.h" +#include "procparamchangers.h" +#include "../rtengine/safegtk.h" +#include "../rtengine/imagesource.h" +#include "soundman.h" +#include "rtimage.h" +#include + +using namespace rtengine::procparams; + +EditorPanel::EditorPanel (FilePanel* filePanel) + : realized(false), iHistoryShow(NULL), iHistoryHide(NULL), iTopPanel_1_Show(NULL), iTopPanel_1_Hide(NULL), iRightPanel_1_Show(NULL), iRightPanel_1_Hide(NULL), iBeforeLockON(NULL),iBeforeLockOFF(NULL), beforePreviewHandler(NULL), beforeIarea(NULL), beforeBox(NULL), afterBox(NULL), afterHeaderBox(NULL), parent(NULL), openThm(NULL), ipc(NULL), beforeIpc(NULL), isProcessing(false), catalogPane(NULL) { + + epih = new EditorPanelIdleHelper; + epih->epanel = this; + epih->destroyed = false; + epih->pending = 0; + //rtengine::befaf=true; + processingStartedTime = 0; + firstProcessingDone = false; + + // construct toolpanelcoordinator + tpc = new ToolPanelCoordinator (); + + // build GUI + + // build left side panel + leftbox = new Gtk::VBox (); + leftbox->set_border_width (2); + leftbox->set_size_request(100,250); + + histogramPanel = NULL; + + profilep = Gtk::manage (new ProfilePanel ()); + ppframe = new Gtk::Frame (); + ppframe->add (*profilep); + ppframe->set_label (M("PROFILEPANEL_LABEL")); + //leftbox->pack_start (*ppframe, Gtk::PACK_SHRINK, 4); + + navigator = Gtk::manage (new Navigator ()); + navigator->previewWindow->set_size_request (-1, 150); + leftbox->pack_start (*navigator, Gtk::PACK_SHRINK, 2); + + history = Gtk::manage (new History ()); + leftbox->pack_start (*history); + + leftbox->show_all (); + + // build the middle of the screen + Gtk::VBox* editbox = Gtk::manage (new Gtk::VBox ()); + + info = Gtk::manage (new Gtk::ToggleButton ()); + Gtk::Image* infoimg = Gtk::manage (new RTImage ("info.png")); + info->add (*infoimg); + info->set_relief(Gtk::RELIEF_NONE); + info->set_tooltip_markup (M("MAIN_TOOLTIP_QINFO")); + + beforeAfter = Gtk::manage (new Gtk::ToggleButton ()); + Gtk::Image* beforeAfterIcon = Gtk::manage (new RTImage ("beforeafter.png")); + beforeAfter->add(*beforeAfterIcon); + beforeAfter->set_relief(Gtk::RELIEF_NONE); + beforeAfter->set_tooltip_markup (M("MAIN_TOOLTIP_TOGGLE")); + + iBeforeLockON = new RTImage ("lock-on.png"); + iBeforeLockOFF = new RTImage ("lock-off.png"); + + Gtk::VSeparator* vsept = Gtk::manage (new Gtk::VSeparator ()); + Gtk::VSeparator* vsepz = Gtk::manage (new Gtk::VSeparator ()); + Gtk::VSeparator* vsepi = Gtk::manage (new Gtk::VSeparator ()); + Gtk::VSeparator* vseph = Gtk::manage (new Gtk::VSeparator ()); + + hidehp = Gtk::manage (new Gtk::ToggleButton ()); + + iHistoryShow = new RTImage ("panel-to-right.png"); + iHistoryHide = new RTImage ("panel-to-left.png"); + + hidehp->set_relief(Gtk::RELIEF_NONE); + hidehp->set_active (options.showHistory); + hidehp->set_tooltip_markup (M("MAIN_TOOLTIP_HIDEHP")); + if (options.showHistory){ + hidehp->set_image (*iHistoryHide); + } + else { + hidehp->set_image (*iHistoryShow); + } + + tbTopPanel_1 = NULL; + if (!simpleEditor && filePanel) { + tbTopPanel_1 = new Gtk::ToggleButton (); + iTopPanel_1_Show = new RTImage ("panel-to-bottom.png"); + iTopPanel_1_Hide = new RTImage ("panel-to-top.png"); + tbTopPanel_1->set_relief(Gtk::RELIEF_NONE); + tbTopPanel_1->set_active (true); + tbTopPanel_1->set_tooltip_markup (M("MAIN_TOOLTIP_SHOWHIDETP1")); + tbTopPanel_1->set_image (*iTopPanel_1_Hide); + } + + tbRightPanel_1 = new Gtk::ToggleButton (); + iRightPanel_1_Show = new RTImage ("panel-to-left.png"); + iRightPanel_1_Hide = new RTImage ("panel-to-right.png"); + tbRightPanel_1->set_relief(Gtk::RELIEF_NONE); + tbRightPanel_1->set_active (true); + tbRightPanel_1->set_tooltip_markup (M("MAIN_TOOLTIP_SHOWHIDERP1")); + tbRightPanel_1->set_image (*iRightPanel_1_Hide); + + Gtk::VSeparator* vsepcl = Gtk::manage (new Gtk::VSeparator ()); + Gtk::VSeparator* vsepz2 = Gtk::manage (new Gtk::VSeparator ()); + Gtk::VSeparator* vsepz3 = Gtk::manage (new Gtk::VSeparator ()); + Gtk::VSeparator* vsepz4 = Gtk::manage (new Gtk::VSeparator ()); + + iareapanel = new ImageAreaPanel (); + tpc->setEditProvider(iareapanel->imageArea); + + Gtk::HBox* toolBarPanel = Gtk::manage (new Gtk::HBox ()); + toolBarPanel->pack_start (*hidehp, Gtk::PACK_SHRINK, 1); + toolBarPanel->pack_start (*vseph, Gtk::PACK_SHRINK, 2); + toolBarPanel->pack_start (*info, Gtk::PACK_SHRINK, 1); + toolBarPanel->pack_start (*beforeAfter, Gtk::PACK_SHRINK, 1); + toolBarPanel->pack_start (*vsepi, Gtk::PACK_SHRINK, 2); + toolBarPanel->pack_start (*tpc->getToolBar(), Gtk::PACK_SHRINK, 1); + toolBarPanel->pack_start (*vsept, Gtk::PACK_SHRINK, 2); + + if (tbTopPanel_1) { + toolBarPanel->pack_end (*tbTopPanel_1, Gtk::PACK_SHRINK, 1); + Gtk::VSeparator* vsep1 = Gtk::manage (new Gtk::VSeparator ()); + toolBarPanel->pack_end (*vsep1, Gtk::PACK_SHRINK, 2); + } + toolBarPanel->pack_end (*tpc->coarse, Gtk::PACK_SHRINK, 2); + toolBarPanel->pack_end (*vsepcl, Gtk::PACK_SHRINK, 2); + toolBarPanel->pack_end (*iareapanel->imageArea->indClippedPanel, Gtk::PACK_SHRINK, 0); + toolBarPanel->pack_end (*vsepz, Gtk::PACK_SHRINK, 2); + toolBarPanel->pack_end (*iareapanel->imageArea->previewModePanel, Gtk::PACK_SHRINK, 0); + toolBarPanel->pack_end (*vsepz4, Gtk::PACK_SHRINK, 2); + + afterBox = Gtk::manage (new Gtk::VBox ()); + afterBox->pack_start (*iareapanel); + + beforeAfterBox = Gtk::manage (new Gtk::HBox()); + beforeAfterBox->pack_start (*afterBox); + + editbox->pack_start (*toolBarPanel, Gtk::PACK_SHRINK,0); + editbox->pack_start (*beforeAfterBox); + + // build right side panel + vboxright = new Gtk::VBox (false, 0); + vboxright->set_size_request(100,250); + + vboxright->set_border_width (2); + + vboxright->pack_start (*ppframe, Gtk::PACK_SHRINK, 2); + // main notebook + vboxright->pack_start (*tpc->toolPanelNotebook); + + // Save buttons + Gtk::HBox* iops = Gtk::manage (new Gtk::HBox ()); + + //Gtk::Image *saveButtonImage = Gtk::manage (new Gtk::Image (Gtk::StockID("gtk-save"), Gtk::ICON_SIZE_BUTTON)); + Gtk::Image *saveButtonImage = Gtk::manage (new RTImage ("gtk-save-large.png")); + saveimgas = Gtk::manage (new Gtk::Button ()); + saveimgas->add(*saveButtonImage); + saveimgas->set_tooltip_markup(M("MAIN_BUTTON_SAVE_TOOLTIP")); + + Gtk::Image *queueButtonImage = Gtk::manage (new RTImage ("processing.png")); + queueimg = Gtk::manage (new Gtk::Button ()); + queueimg->add(*queueButtonImage); + queueimg->set_tooltip_markup(M("MAIN_BUTTON_PUTTOQUEUE_TOOLTIP")); + + Gtk::Image *sendToEditorButtonImage = Gtk::manage (new RTImage ("image-editor.png")); + sendtogimp = Gtk::manage (new Gtk::Button ()); + sendtogimp->add(*sendToEditorButtonImage); + sendtogimp->set_tooltip_markup(M("MAIN_BUTTON_SENDTOEDITOR_TOOLTIP")); + + iops->pack_start (*saveimgas, Gtk::PACK_SHRINK); + if(!simpleEditor) + iops->pack_start (*queueimg, Gtk::PACK_SHRINK); + iops->pack_start (*sendtogimp, Gtk::PACK_SHRINK); + + // Status box + statusBox = Gtk::manage (new Gtk::HBox ()); + progressLabel = Gtk::manage (new Gtk::ProgressBar()); + progressLabel->set_fraction(0.0); + //progressLabel->modify_bg( Gtk::STATE_NORMAL,Gdk::Color("grey") ); // Disable, because in single mode this is may be permanent red without processing + + statusBox->pack_start (*progressLabel); + iops->pack_start(*statusBox, Gtk::PACK_SHRINK, 2); + + // tbRightPanel_1 + iops->pack_end (*tbRightPanel_1, Gtk::PACK_SHRINK,0); + + // ShowHideSidePanels + tbShowHideSidePanels = new Gtk::ToggleButton (); + iShowHideSidePanels = new RTImage ("crossed-arrows-out.png"); + iShowHideSidePanels_exit = new RTImage ("crossed-arrows-in.png"); + tbShowHideSidePanels->set_relief(Gtk::RELIEF_NONE); + tbShowHideSidePanels->set_active (false); + tbShowHideSidePanels->set_tooltip_markup (M("MAIN_BUTTON_SHOWHIDESIDEPANELS_TOOLTIP")); + tbShowHideSidePanels->set_image (*iShowHideSidePanels); + iops->pack_end (*tbShowHideSidePanels, Gtk::PACK_SHRINK,0); + iops->pack_end (*vsepz2, Gtk::PACK_SHRINK,1); + + // Zoom panel + iops->pack_end (*iareapanel->imageArea->zoomPanel, Gtk::PACK_SHRINK, 1); + iops->pack_end (*vsepz3, Gtk::PACK_SHRINK, 2); + + navPrev = navNext = navSync = NULL; + if (!simpleEditor && !options.tabbedUI){ + // Navigation buttons + Gtk::Image *navPrevImage = Gtk::manage (new RTImage ("nav-prev.png")); + navPrevImage->set_padding(0,0); + navPrev = Gtk::manage (new Gtk::Button ()); + navPrev->add(*navPrevImage); + navPrev->set_relief(Gtk::RELIEF_NONE); + navPrev->set_tooltip_markup(M("MAIN_BUTTON_NAVPREV_TOOLTIP")); + + Gtk::Image *navNextImage = Gtk::manage (new RTImage ("nav-next.png")); + navNextImage->set_padding(0,0); + navNext = Gtk::manage (new Gtk::Button ()); + navNext->add(*navNextImage); + navNext->set_relief(Gtk::RELIEF_NONE); + navNext->set_tooltip_markup(M("MAIN_BUTTON_NAVNEXT_TOOLTIP")); + + Gtk::Image *navSyncImage = Gtk::manage (new RTImage ("nav-sync.png")); + navSyncImage->set_padding(0,0); + navSync = Gtk::manage (new Gtk::Button ()); + navSync->add(*navSyncImage); + navSync->set_relief(Gtk::RELIEF_NONE); + navSync->set_tooltip_markup(M("MAIN_BUTTON_NAVSYNC_TOOLTIP")); + + iops->pack_end (*Gtk::manage(new Gtk::VSeparator()), Gtk::PACK_SHRINK, 0); + iops->pack_end (*navNext, Gtk::PACK_SHRINK, 0); + iops->pack_end (*navSync, Gtk::PACK_SHRINK, 0); + iops->pack_end (*navPrev, Gtk::PACK_SHRINK, 0); + } + + editbox->pack_start (*Gtk::manage(new Gtk::HSeparator()), Gtk::PACK_SHRINK, 0); + editbox->pack_start (*iops, Gtk::PACK_SHRINK, 0); + editbox->show_all (); + + // build screen + hpanedl = Gtk::manage (new Gtk::HPaned()); + hpanedr = Gtk::manage (new Gtk::HPaned()); + leftbox->reference (); + vboxright->reference (); + if (options.showHistory) { + hpanedl->pack1(*leftbox, false, true); + hpanedl->set_position (options.historyPanelWidth); + } + + + Gtk::VPaned * viewpaned = Gtk::manage (new Gtk::VPaned()); + fPanel = filePanel; + if(filePanel) + { + catalogPane = new Gtk::Paned(); + viewpaned->pack1(*catalogPane, false, true); + } + viewpaned->pack2(*editbox, true, true); + + + Gtk::Frame* vbfr = Gtk::manage (new Gtk::Frame ()); + vbfr->add (*viewpaned); + vbfr->set_size_request(100,250); + hpanedl->pack2(*vbfr, true, true); + + hpanedr->pack1(*hpanedl, true, true); + hpanedr->pack2(*vboxright, false, true); + hpanedl->signal_button_release_event().connect_notify( sigc::mem_fun(*this, &EditorPanel::leftPaneButtonReleased) ); + hpanedr->signal_button_release_event().connect_notify( sigc::mem_fun(*this, &EditorPanel::rightPaneButtonReleased) ); + + pack_start (*hpanedr); + + updateHistogramPosition (0, options.histogramPosition); + + show_all (); +/* + // save as dialog + if (safe_file_test (options.lastSaveAsPath, Glib::FILE_TEST_IS_DIR)) + saveAsDialog = new SaveAsDialog (options.lastSaveAsPath); + else + saveAsDialog = new SaveAsDialog (safe_get_user_picture_dir()); + + saveAsDialog->set_default_size (options.saveAsDialogWidth, options.saveAsDialogHeight); +*/ + // connect listeners + profilep->setProfileChangeListener (tpc); + history->setProfileChangeListener (tpc); + history->setHistoryBeforeLineListener (this); + tpc->addPParamsChangeListener (profilep); + tpc->addPParamsChangeListener (history); + tpc->addPParamsChangeListener (this); + iareapanel->imageArea->setCropGUIListener (tpc->getCropGUIListener()); + iareapanel->imageArea->setPointerMotionListener (navigator); + iareapanel->imageArea->setImageAreaToolListener (tpc); + + // initialize components + info->set_active (options.showInfo); + tpc->readOptions (); + + // connect event handlers + info->signal_toggled().connect( sigc::mem_fun(*this, &EditorPanel::info_toggled) ); + beforeAfter->signal_toggled().connect( sigc::mem_fun(*this, &EditorPanel::beforeAfterToggled) ); + hidehp->signal_toggled().connect( sigc::mem_fun(*this, &EditorPanel::hideHistoryActivated) ); + tbRightPanel_1->signal_toggled().connect( sigc::mem_fun(*this, &EditorPanel::tbRightPanel_1_toggled) ); + saveimgas->signal_pressed().connect( sigc::mem_fun(*this, &EditorPanel::saveAsPressed) ); + queueimg->signal_pressed().connect( sigc::mem_fun(*this, &EditorPanel::queueImgPressed) ); + sendtogimp->signal_pressed().connect( sigc::mem_fun(*this, &EditorPanel::sendToGimpPressed) ); + if(navPrev) + navPrev->signal_pressed().connect( sigc::mem_fun(*this, &EditorPanel::openPreviousEditorImage) ); + if(navNext) + navNext->signal_pressed().connect( sigc::mem_fun(*this, &EditorPanel::openNextEditorImage) ); + if(navSync) + navSync->signal_pressed().connect( sigc::mem_fun(*this, &EditorPanel::syncFileBrowser) ); + ShowHideSidePanelsconn = tbShowHideSidePanels->signal_toggled().connect ( sigc::mem_fun(*this, &EditorPanel::toggleSidePanels), true); + if (tbTopPanel_1) + tbTopPanel_1->signal_toggled().connect( sigc::mem_fun(*this, &EditorPanel::tbTopPanel_1_toggled) ); +} + +EditorPanel::~EditorPanel () { + + history->setHistoryBeforeLineListener (NULL); + // the order is important! + iareapanel->setBeforeAfterViews (NULL, iareapanel); + delete iareapanel; + iareapanel = NULL; + + if (beforeIpc) + beforeIpc->stopProcessing (); + + delete beforeIarea; + beforeIarea = NULL; + + if (beforeIpc){ + beforeIpc->setPreviewImageListener (NULL); + } + delete beforePreviewHandler; + beforePreviewHandler = NULL; + if (beforeIpc) + rtengine::StagedImageProcessor::destroy (beforeIpc); + beforeIpc = NULL; + + close (); + + if (epih->pending) + epih->destroyed = true; + else + delete epih; + + delete tpc; + + delete ppframe; + delete leftbox; + delete vboxright; + //delete saveAsDialog; + if(catalogPane) + delete catalogPane; + + if (iTopPanel_1_Show) delete iTopPanel_1_Show; + if (iTopPanel_1_Hide) delete iTopPanel_1_Hide; + if (iHistoryShow) + delete iHistoryShow; + if (iHistoryHide) + delete iHistoryHide; + if(iBeforeLockON) + delete iBeforeLockON; + if(iBeforeLockOFF) + delete iBeforeLockOFF; + if(iRightPanel_1_Show) + delete iRightPanel_1_Show; + if(iRightPanel_1_Hide) + delete iRightPanel_1_Hide; +} + +void EditorPanel::leftPaneButtonReleased(GdkEventButton *event) { + if (event->button == 1) { + // Button 1 released : it's a resize + options.historyPanelWidth = hpanedl->get_position(); + } + /*else if (event->button == 3) { + }*/ +} + +void EditorPanel::rightPaneButtonReleased(GdkEventButton *event) { + if (event->button == 1) { + int winW, winH; + parent->get_size(winW, winH); + // Button 1 released : it's a resize + options.toolPanelWidth = winW - hpanedr->get_position(); + } + /*else if (event->button == 3) { + }*/ +} + +void EditorPanel::writeOptions() { + if (profilep) + profilep->writeOptions(); + if (tpc) + tpc->writeOptions(); +} + +void EditorPanel::showTopPanel(bool show) { + if (tbTopPanel_1->get_active() != show) + tbTopPanel_1->set_active(show); +} + +void EditorPanel::setAspect () { + int winW, winH; + parent->get_size(winW, winH); + hpanedl->set_position(options.historyPanelWidth); + hpanedr->set_position(winW - options.toolPanelWidth); + // initialize components + if (info->get_active() != options.showInfo) + info->set_active (options.showInfo); +} + +void EditorPanel::on_realize () { + realized = true; + Gtk::VBox::on_realize (); + // This line is needed to avoid autoexpansion of the window :-/ + vboxright->set_size_request (options.toolPanelWidth, -1); + tpc->updateToolState(); +} + +void EditorPanel::open (Thumbnail* tmb, rtengine::InitialImage* isrc) { + + close(); + + isProcessing=true; // prevents closing-on-init + + // initialize everything + openThm = tmb; + openThm->increaseRef (); + + fname=openThm->getFileName(); + lastSaveAsFileName = removeExtension (Glib::path_get_basename (fname)); + + previewHandler = new PreviewHandler (); + previewHandler2 = new PreviewHandler (); + + this->isrc = isrc; + ipc = rtengine::StagedImageProcessor::create (isrc); + ipc->setProgressListener (this); + ipc->setPreviewImageListener (previewHandler); + ipc->setPreviewScale (10); // Important + tpc->initImage (ipc, tmb->getType()==FT_Raw); + ipc->setHistogramListener (this); + +// iarea->fitZoom (); // tell to the editorPanel that the next image has to be fitted to the screen + iareapanel->imageArea->setPreviewHandler (previewHandler); + iareapanel->imageArea->setImProcCoordinator (ipc); + navigator->previewWindow->setPreviewHandler (previewHandler); + navigator->previewWindow->setImageArea (iareapanel->imageArea); + + rtengine::ImageSource* is=isrc->getImageSource(); + is->setProgressListener( this ); + + // try to load the last saved parameters from the cache or from the paramfile file + ProcParams* ldprof = openThm->createProcParamsForUpdate(true,false); // will be freed by initProfile + + // initialize profile + Glib::ustring defProf = openThm->getType()==FT_Raw ? options.defProfRaw : options.defProfImg; + profilep->initProfile (defProf, ldprof); + profilep->setInitialFileName (fname); + + openThm->addThumbnailListener (this); + info_toggled (); + + if (beforeIarea) + { + beforeAfterToggled(); + beforeAfterToggled(); + } + + // If in single tab mode, the main crop window is not constructed the very first time + // since there was no resize event + if (iareapanel->imageArea->mainCropWindow) + { + iareapanel->imageArea->mainCropWindow->cropHandler.newImage(ipc, false); + iareapanel->imageArea->mainCropWindow->initialImageArrived(); + + // In single tab mode, the image is not always updated between switches + // normal redraw don't work, so this is the hard way + // Disabled this with Issue 2435 because it seems to work fine now +// if (!options.tabbedUI && iareapanel->imageArea->mainCropWindow->getZoomFitVal() == 1.0) { +// iareapanel->imageArea->mainCropWindow->cropHandler.update(); +// } + } else { + Gtk::Allocation alloc; + iareapanel->imageArea->on_resized(alloc); + } +} + +void EditorPanel::close () { + if (ipc) + { + saveProfile (); + // close image processor and the current thumbnail + tpc->closeImage (); // this call stops image processing + tpc->writeOptions (); + rtengine::ImageSource* is=isrc->getImageSource(); + is->setProgressListener( NULL ); + + if (ipc) { + ipc->setPreviewImageListener (NULL); + } + + if (beforeIpc){ + beforeIpc->setPreviewImageListener (NULL); + } + + delete previewHandler; + previewHandler= NULL; + + if(iareapanel) + { + iareapanel->imageArea->setPreviewHandler (NULL); + iareapanel->imageArea->setImProcCoordinator (NULL); + } + rtengine::StagedImageProcessor::destroy (ipc); + ipc = NULL; + navigator->previewWindow->setPreviewHandler (NULL); + + // If the file was deleted somewhere, the openThm.descreaseRef delete the object, but we don't know here + if (safe_file_test(fname, Glib::FILE_TEST_EXISTS)) { + openThm->removeThumbnailListener (this); + openThm->decreaseRef (); + } + } +} + +void EditorPanel::saveProfile () { + if (!ipc || !openThm) return; + + // If the file was deleted, do not generate ghost entries + if (safe_file_test(fname, Glib::FILE_TEST_EXISTS)) { + ProcParams params; + ipc->getParams (¶ms); + + // Will call updateCache, which will update both the cached and sidecar files if necessary + openThm->setProcParams (params, NULL, EDITOR); +} +} + +Glib::ustring EditorPanel::getShortName () { + if (openThm) return Glib::path_get_basename (openThm->getFileName ()); + else return ""; +} + +Glib::ustring EditorPanel::getFileName () { + if (openThm) return openThm->getFileName (); + else return ""; +} + +// TODO!!! +void EditorPanel::procParamsChanged (rtengine::procparams::ProcParams* params, rtengine::ProcEvent ev, Glib::ustring descr, ParamsEdited* paramsEdited) { + +// if (ev!=EvPhotoLoaded) +// saveLabel->set_markup (Glib::ustring("") + M("MAIN_BUTTON_SAVE") + ""); +} + +struct spsparams { + bool inProcessing; + EditorPanelIdleHelper* epih; +}; + +int setProgressStateUIThread (void* data) { + + spsparams* p = static_cast(data); + + if (p->epih->destroyed) { + if (p->epih->pending == 1) + delete p->epih; + else + p->epih->pending--; + delete p; + + return 0; + } + + p->epih->epanel->refreshProcessingState (p->inProcessing); + p->epih->pending--; + delete p; + + return 0; +} + +void EditorPanel::setProgressState (bool inProcessing) { + + epih->pending++; + + spsparams* p = new spsparams; + p->inProcessing = inProcessing; + p->epih = epih; + g_idle_add (setProgressStateUIThread, p); +} + +struct spparams { + double val; + Glib::ustring str; + Gtk::ProgressBar *pProgress; +}; + +int setprogressStrUI( void *p ) +{ + GThreadLock lock; // All GUI acces from idle_add callbacks or separate thread HAVE to be protected + spparams *s= static_cast(p); + + if( ! s->str.empty() ) + s->pProgress->set_text( M(s->str) ); + if( s->val >=0 ){ + s->pProgress->set_fraction( s->val ); + if( s->val <1.0 ) + s->pProgress->modify_bg( Gtk::STATE_NORMAL,Gdk::Color("red") ); + else + s->pProgress->modify_bg( Gtk::STATE_NORMAL,Gdk::Color("grey") ); + } + + delete s; + return 0; +} + +void EditorPanel::setProgress (double p) +{ + spparams *s=new spparams; + s->val = p; + s->pProgress = progressLabel; + g_idle_add (setprogressStrUI, s); +} + +void EditorPanel::setProgressStr (Glib::ustring str) +{ + spparams *s=new spparams; + s->str = str; + s->val = -1; + s->pProgress = progressLabel; + g_idle_add (setprogressStrUI, s); +} + +// This is only called from the ThreadUI, so within the gtk thread +void EditorPanel::refreshProcessingState (bool inProcessingP) { + spparams *s=new spparams; + s->pProgress = progressLabel; + + if (inProcessingP) { + if (processingStartedTime==0) processingStartedTime = ::time(NULL); + + s->str = "PROGRESSBAR_PROCESSING"; + s->val = 0.0; + } else { + // Set proc params of thumbnail. It saves it into the cache and updates the file browser. + if (ipc && openThm && tpc->getChangedState()) { + rtengine::procparams::ProcParams pparams; + ipc->getParams (&pparams); + openThm->setProcParams (pparams, NULL, EDITOR, false); + } + + // Ring a sound if it was a long event + if (processingStartedTime!=0) { + time_t curTime= ::time(NULL); + if (::difftime(curTime, processingStartedTime) > options.sndLngEditProcDoneSecs) + SoundManager::playSoundAsync(options.sndLngEditProcDone); + + processingStartedTime = 0; + } + + // Set progress bar "done" + s->str = "PROGRESSBAR_READY"; + s->val = 1.0; + +#ifdef WIN32 + // Maybe accessing "parent", which is a Gtk object, can justify to get the Gtk lock... + if (!firstProcessingDone && static_cast(parent)->getIsFullscreen()) { parent->fullscreen(); } +#endif + firstProcessingDone = true; +} + + isProcessing=inProcessingP; + + setprogressStrUI(s); +} + +struct errparams { + Glib::ustring descr; + Glib::ustring title; + EditorPanelIdleHelper* epih; +}; + +void EditorPanel::displayError (Glib::ustring title, Glib::ustring descr) { + GtkWidget* msgd = gtk_message_dialog_new_with_markup (NULL, + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + "%s", + descr.data()); + gtk_window_set_title((GtkWindow*)msgd, title.data()); + g_signal_connect_swapped (msgd, "response", + G_CALLBACK (gtk_widget_destroy), + msgd); + gtk_widget_show_all (msgd); +} + +int disperrorUI (void* data) { + errparams* p = static_cast(data); + + if (p->epih->destroyed) { + if (p->epih->pending == 1) + delete p->epih; + else + p->epih->pending--; + delete p; + + return 0; + } + + p->epih->epanel->displayError (p->title, p->descr); + p->epih->pending--; + delete p; + + return 0; +} + +void EditorPanel::error (Glib::ustring title, Glib::ustring descr) { + + epih->pending++; + errparams* p = new errparams; + p->descr = descr; + p->title = title; + p->epih = epih; + g_idle_add (disperrorUI, 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(); + if (idata && idata->hasExif()){ + infoString1 = Glib::ustring::compose ("%1 + %2", + Glib::ustring(idata->getMake()+" "+idata->getModel()), + Glib::ustring(idata->getLens())); + + 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(),true)); // maskZeroexpcomp + if (expcomp!=""){ + infoString2 = Glib::ustring::compose("%1 %2EV", + infoString2, + expcomp /*Glib::ustring(idata->expcompToString(idata->getExpComp()))*/); + } + + infoString3 = Glib::ustring::compose ("%1%2", + 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\n%3\n%4",infoString1, infoString2, infoString3, infoString4); + } + else + infoString = M("QINFO_NOEXIF"); + + iareapanel->imageArea->setInfoText (infoString); + iareapanel->imageArea->infoEnabled (info->get_active ()); +} + +void EditorPanel::hideHistoryActivated () { + + removeIfThere (hpanedl, leftbox, false); + if (hidehp->get_active()) + hpanedl->pack1 (*leftbox, false, true); + options.showHistory = hidehp->get_active(); + + if (options.showHistory){ + hidehp->set_image (*iHistoryHide); + } + else { + hidehp->set_image (*iHistoryShow); + } + + tbShowHideSidePanels_managestate(); +} + + +void EditorPanel::tbRightPanel_1_toggled () { +/* + removeIfThere (hpanedr, vboxright, false); + if (tbRightPanel_1->get_active()){ + hpanedr->pack2(*vboxright, false, true); + tbRightPanel_1->set_image (*iRightPanel_1_Hide); + } + else { + tbRightPanel_1->set_image (*iRightPanel_1_Show); + } + tbShowHideSidePanels_managestate(); + */ + if (vboxright){ + if (tbRightPanel_1->get_active()){ + vboxright->show(); + tbRightPanel_1->set_image (*iRightPanel_1_Hide); + } + else{ + vboxright->hide(); + tbRightPanel_1->set_image (*iRightPanel_1_Show); + } + tbShowHideSidePanels_managestate(); + } +} + +void EditorPanel::tbTopPanel_1_visible (bool visible){ + if (!tbTopPanel_1) + return; + + if (visible) + tbTopPanel_1->show(); + else + tbTopPanel_1->hide(); +} + +void EditorPanel::tbTopPanel_1_toggled () { + + if (catalogPane){ // catalogPane does not exist in multitab mode + + if (tbTopPanel_1->get_active()){ + catalogPane->show(); + tbTopPanel_1->set_image (*iTopPanel_1_Hide); + options.editorFilmStripOpened = true; + } + else { + catalogPane->hide(); + tbTopPanel_1->set_image (*iTopPanel_1_Show); + options.editorFilmStripOpened = false; + } + + tbShowHideSidePanels_managestate(); + } +} + +/* + * WARNING: Take care of the simpleEditor value when adding or modifying shortcut keys, + * since handleShortcutKey is now also triggered in simple editor mode + */ +bool EditorPanel::handleShortcutKey (GdkEventKey* event) { + + bool ctrl = event->state & GDK_CONTROL_MASK; + bool shift = event->state & GDK_SHIFT_MASK; + bool alt = event->state & GDK_MOD1_MASK; +#ifdef __WIN32__ + bool altgr = event->state & GDK_MOD2_MASK; +#else + bool altgr = event->state & GDK_MOD5_MASK; +#endif + + // Editor Layout + switch(event->keyval) { + case GDK_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 (alt) tbRightPanel_1->set_active (!tbRightPanel_1->get_active()); // toggle right panel + return true; + break; + case GDK_l: + if (!shift && !alt /*&& !ctrl*/){ + hidehp->set_active (!hidehp->get_active()); // toggle History (left panel) + return true; + } + if (alt && !ctrl){ // toggle right panel + tbRightPanel_1->set_active (!tbRightPanel_1->get_active()); + 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; + } + break; + case GDK_m: // Maximize preview panel: hide top AND right AND history panels + if (!ctrl && !alt) { + toggleSidePanels(); + return true; + } + break; + case GDK_M: // Maximize preview panel: hide top AND right AND history panels AND (fit image preview) + if (!ctrl && !alt) { + toggleSidePanelsZoomFit(); + return true; + } + break; + } +#ifdef __WIN32__ + if (!alt && !ctrl && !altgr && event->hardware_keycode == 0x39 ) { + iareapanel->imageArea->previewModePanel->togglebackColor(); + return true; + } +#else + if (!alt && !ctrl && !altgr && event->hardware_keycode == 0x12 ) { + iareapanel->imageArea->previewModePanel->togglebackColor(); + return true; + } +#endif + if (!alt){ + if (!ctrl) { + // Normal + switch(event->keyval) { + case GDK_bracketright: + tpc->coarse->rotateRight(); + return true; + case GDK_bracketleft: + tpc->coarse->rotateLeft(); + return true; + case GDK_i: + case GDK_I: + info->set_active (!info->get_active()); + return true; + case GDK_B: + beforeAfter->set_active (!beforeAfter->get_active()); + return true; + case GDK_plus: + case GDK_equal: + case GDK_KP_Add: + iareapanel->imageArea->zoomPanel->zoomInClicked(); + return true; + case GDK_minus: + case GDK_underscore: + case GDK_KP_Subtract: + iareapanel->imageArea->zoomPanel->zoomOutClicked(); + return true; + case GDK_z://GDK_1 + iareapanel->imageArea->zoomPanel->zoom11Clicked(); + return true; +/* +#ifndef __WIN32__ + case GDK_9: // toggle background color of the preview + iareapanel->imageArea->previewModePanel->togglebackColor(); + return true; +#endif +*/ + case GDK_r: //preview mode Red + iareapanel->imageArea->previewModePanel->toggleR(); + return true; + case GDK_g: //preview mode Green + iareapanel->imageArea->previewModePanel->toggleG(); + return true; + case GDK_b: //preview mode Blue + iareapanel->imageArea->previewModePanel->toggleB(); + return true; + case GDK_v: //preview mode Luminosity + iareapanel->imageArea->previewModePanel->toggleL(); + return true; + case GDK_F: //preview mode Focus Mask + iareapanel->imageArea->previewModePanel->toggleFocusMask(); + return true; + + case GDK_f: + iareapanel->imageArea->zoomPanel->zoomFitClicked(); + return true; + case GDK_less: + iareapanel->imageArea->indClippedPanel->toggleClipped(true); + return true; + case GDK_greater: + iareapanel->imageArea->indClippedPanel->toggleClipped(false); + return true; + + case GDK_F5: + openThm->openDefaultViewer((event->state & GDK_SHIFT_MASK) ? 2 : 1); + return true; + case GDK_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_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_S: + saveProfile(); + setProgressStr(M("PROGRESSBAR_PROCESSING_PROFILESAVED")); + return true; + case GDK_s: + saveAsPressed(); + return true; + case GDK_b: + if (!simpleEditor) + queueImgPressed(); + return true; + case GDK_e: + sendToGimpPressed(); + return true; + case GDK_z: + history->undo (); + return true; + case GDK_Z: + history->redo (); + return true; + case GDK_F5: + openThm->openDefaultViewer(3); + return true; + } + } //if (!ctrl) + } //if (!alt) + + if (alt){ + switch (event->keyval) { + case GDK_s: + history->addBookmarkPressed (); + setProgressStr(M("PROGRESSBAR_SNAPSHOT_ADDED")); + return true; + case GDK_f: + iareapanel->imageArea->zoomPanel->zoomFitCropClicked(); + return true; + } + } + + if (shift){ + switch (event->keyval) { + case GDK_F3: // open Previous image from Editor's perspective + if (!simpleEditor && fPanel && !fname.empty()){ + EditorPanel::openPreviousEditorImage(); + return true; + } + break; // to avoid gcc complain + case GDK_F4: // open next image from Editor's perspective + if (!simpleEditor && fPanel && !fname.empty()){ + EditorPanel::openNextEditorImage(); + return true; + } + break; // to avoid gcc complain + } + } + + if(tpc->getToolBar() && tpc->getToolBar()->handleShortcutKey(event)) + return true; + if(tpc->handleShortcutKey(event)) + return true; + + if (!simpleEditor && fPanel){ + if (fPanel->handleShortcutKey(event)) + return true; + } + + return false; +} + +void EditorPanel::procParamsChanged (Thumbnail* thm, int whoChangedIt) { + + if (whoChangedIt!=EDITOR) { + PartialProfile pp(true); + pp.set(true); + *(pp.pparams) = openThm->getProcParams(); + tpc->profileChange (&pp, rtengine::EvProfileChangeNotification, M("PROGRESSDLG_PROFILECHANGEDINBROWSER")); + pp.deleteInstance(); + } +} + +bool EditorPanel::idle_saveImage (ProgressConnector *pc, Glib::ustring fname, SaveFormat sf) { + rtengine::IImage16* img = pc->returnValue(); + delete pc; + if( img ) { + setProgressStr(M("GENERAL_SAVE")); setProgress(0.9f); + + ProgressConnector *ld = new ProgressConnector(); + img->setSaveProgressListener (parent->getProgressListener()); + 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)); + 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)); + 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 { + Glib::ustring msg_ = Glib::ustring("") + fname + ": Error during image processing\n"; + Gtk::MessageDialog msgd (*parent, msg_, true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); + msgd.run (); + + saveimgas->set_sensitive(true); + sendtogimp->set_sensitive(true); + isProcessing = false; + + } + rtengine::ImageSource* imgsrc = isrc->getImageSource (); + imgsrc->setProgressListener(this); + return false; +} + +bool EditorPanel::idle_imageSaved(ProgressConnector *pc,rtengine::IImage16* img,Glib::ustring fname, SaveFormat sf){ + img->free (); + + if (! pc->returnValue() ) { + openThm->imageDeveloped (); + // 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 { + error(M("MAIN_MSG_CANNOTSAVE"), fname); + } + + saveimgas->set_sensitive(true); + sendtogimp->set_sensitive(true); + + parent->setProgressStr(""); + parent->setProgress(0.); + + setProgressState(false); + + delete pc; + SoundManager::playSoundAsync(options.sndBatchQueueDone); + isProcessing = false; + return false; +} + +BatchQueueEntry* EditorPanel::createBatchQueueEntry () { + + rtengine::procparams::ProcParams pparams; + ipc->getParams (&pparams); + //rtengine::ProcessingJob* job = rtengine::ProcessingJob::create (ipc->getInitialImage(), pparams); + rtengine::ProcessingJob* job = rtengine::ProcessingJob::create (openThm->getFileName (), openThm->getType()==FT_Raw, pparams); + int fullW=0, fullH=0; + isrc->getImageSource()->getFullSize(fullW, fullH, pparams.coarse.rotate==90 || pparams.coarse.rotate==270 ? TR_R90 : TR_NONE); + int prevh = BatchQueue::calcMaxThumbnailHeight(); + int prevw = int((size_t)fullW * (size_t)prevh / (size_t)fullH); + return new BatchQueueEntry (job, pparams, openThm->getFileName(), prevw, prevh, openThm); +} + + + +void EditorPanel::saveAsPressed () { + if (!ipc || !openThm) return; + bool fnameOK = false; + Glib::ustring fnameOut; + + SaveAsDialog* saveAsDialog; + if (safe_file_test (options.lastSaveAsPath, Glib::FILE_TEST_IS_DIR)) + saveAsDialog = new SaveAsDialog (options.lastSaveAsPath); + else + saveAsDialog = new SaveAsDialog (safe_get_user_picture_dir()); + + saveAsDialog->set_default_size (options.saveAsDialogWidth, options.saveAsDialogHeight); + saveAsDialog->setInitialFileName (lastSaveAsFileName); + saveAsDialog->setImagePath (fname); + + do { + int result = saveAsDialog->run (); + + // The SaveAsDialog ensure that a filename has been specified + fnameOut = saveAsDialog->getFileName (); + + options.lastSaveAsPath = saveAsDialog->getDirectory (); + options.saveAsDialogWidth = saveAsDialog->get_width (); + options.saveAsDialogHeight = saveAsDialog->get_height (); + options.autoSuffix = saveAsDialog->getAutoSuffix (); + options.saveMethodNum = saveAsDialog->getSaveMethodNum (); + lastSaveAsFileName = Glib::path_get_basename (removeExtension (fnameOut)); + SaveFormat sf = saveAsDialog->getFormat (); + options.saveFormat = sf; + options.forceFormatOpts = saveAsDialog->getForceFormatOpts (); + + if (result != Gtk::RESPONSE_OK) + break; + + if (saveAsDialog->getImmediately ()) { + // separate filename and the path to the destination directory + Glib::ustring dstdir = Glib::path_get_dirname (fnameOut); + Glib::ustring dstfname = Glib::path_get_basename (removeExtension(fnameOut)); + Glib::ustring dstext = getExtension (fnameOut); + + if (saveAsDialog->getAutoSuffix()) { + + Glib::ustring fnameTemp; + for (int tries=0; tries<100; tries++) { + if (tries==0) + fnameTemp = Glib::ustring::compose ("%1.%2", Glib::build_filename (dstdir, dstfname), dstext); + else + fnameTemp = Glib::ustring::compose ("%1-%2.%3", Glib::build_filename (dstdir, dstfname), tries, dstext); + + if (!safe_file_test (fnameTemp, Glib::FILE_TEST_EXISTS)) { + fnameOut = fnameTemp; + fnameOK = true; + break; + } + } + } + // check if it exists + if (!fnameOK) { + fnameOK = confirmOverwrite (*saveAsDialog, fnameOut); + } + + if (fnameOK) { + isProcessing = true; + // save image + rtengine::procparams::ProcParams pparams; + ipc->getParams (&pparams); + rtengine::ProcessingJob* job = rtengine::ProcessingJob::create (ipc->getInitialImage(), pparams); + + 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 )); + saveimgas->set_sensitive(false); + sendtogimp->set_sensitive(false); + } + } + else { + BatchQueueEntry* bqe = createBatchQueueEntry (); + bqe->outFileName = fnameOut; + bqe->saveFormat = saveAsDialog->getFormat (); + bqe->forceFormatOpts = saveAsDialog->getForceFormatOpts (); + parent->addBatchQueueJob (bqe, saveAsDialog->getToHeadOfQueue ()); + fnameOK = true; + } + // ask parent to redraw file browser + // ... or does it automatically when the tab is switched to it + } while (!fnameOK); + + saveAsDialog->hide(); +} + +void EditorPanel::queueImgPressed () { + if (!ipc || !openThm) return; + saveProfile (); + parent->addBatchQueueJob (createBatchQueueEntry ()); +} + +void EditorPanel::sendToGimpPressed () { + if (!ipc || !openThm) return; + // develop image + rtengine::procparams::ProcParams pparams; + ipc->getParams (&pparams); + rtengine::ProcessingJob* job = rtengine::ProcessingJob::create (ipc->getInitialImage(), pparams); + 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_sendToGimp ),ld, openThm->getFileName() )); + saveimgas->set_sensitive(false); + sendtogimp->set_sensitive(false); +} + + +void EditorPanel::openPreviousEditorImage() { + if (!simpleEditor && fPanel && !fname.empty()) + fPanel->fileCatalog->openNextPreviousEditorImage(fname, true, NAV_PREVIOUS); +} + +void EditorPanel::openNextEditorImage() { + if (!simpleEditor && fPanel && !fname.empty()) + fPanel->fileCatalog->openNextPreviousEditorImage(fname, true, NAV_NEXT); +} + +void EditorPanel::syncFileBrowser() { // synchronize filebrowser with image in Editor + if (!simpleEditor && fPanel && !fname.empty()) + fPanel->fileCatalog->selectImage(fname, true); +} + +bool EditorPanel::idle_sendToGimp( ProgressConnector *pc, Glib::ustring fname){ + + rtengine::IImage16* img = pc->returnValue(); + delete pc; + if (img) { + // get file name base + Glib::ustring shortname = removeExtension (Glib::path_get_basename (fname)); + Glib::ustring dirname = Glib::get_tmp_dir (); + Glib::ustring fname = Glib::build_filename (dirname, shortname); + + SaveFormat sf; + sf.format = "tif"; + sf.tiffBits = 16; + sf.tiffUncompressed = true; + sf.saveParams = true; + + Glib::ustring fileName = Glib::ustring::compose ("%1.%2", fname, sf.format); + + int tries = 1; + while (safe_file_test (fileName, Glib::FILE_TEST_EXISTS) && tries<1000) { + fileName = Glib::ustring::compose("%1-%2.%3", fname, tries, sf.format); + tries++; + } + if (tries==1000){ + img->free (); + return false; + } + + ProgressConnector *ld = new ProgressConnector(); + img->setSaveProgressListener (parent->getProgressListener()); + ld->startFunc (sigc::bind(sigc::mem_fun(img, &rtengine::IImage16::saveAsTIFF), fileName, sf.tiffBits, sf.tiffUncompressed), + sigc::bind(sigc::mem_fun(*this,&EditorPanel::idle_sentToGimp), ld, img, fileName)); + }else{ + Glib::ustring msg_ = Glib::ustring(" Error during image processing\n"); + Gtk::MessageDialog msgd (*parent, msg_, true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); + msgd.run (); + saveimgas->set_sensitive(true); + sendtogimp->set_sensitive(true); + } + return false; +} + +bool EditorPanel::idle_sentToGimp(ProgressConnector *pc,rtengine::IImage16* img,Glib::ustring filename){ + img->free (); + int errore = pc->returnValue(); + delete pc; + if (!errore) { + saveimgas->set_sensitive(true); + sendtogimp->set_sensitive(true); + parent->setProgressStr(""); + parent->setProgress(0.); + bool success=false; + Glib::ustring cmdLine; + Glib::ustring executable; + // start gimp + if (options.editorToSendTo==1) { +#ifdef WIN32 + executable = Glib::build_filename (Glib::build_filename(options.gimpDir,"bin"), "gimp-win-remote"); + cmdLine = Glib::ustring("\"") + executable + Glib::ustring("\" gimp-2.4.exe ") + Glib::ustring("\"") + filename + Glib::ustring("\""); + if ( safe_file_test(executable, (Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE)) ) { + success = safe_spawn_command_line_async (cmdLine); + } +#elif defined __APPLE__ + cmdLine = Glib::ustring("open -a /Applications/GIMP.app \'") + filename + Glib::ustring("\'"); + success = safe_spawn_command_line_async (cmdLine); + std::cout << cmdLine << std::endl; +#else + cmdLine = Glib::ustring("gimp \"") + filename + Glib::ustring("\""); + success = safe_spawn_command_line_async (cmdLine); + std::cout << cmdLine << std::endl; +#endif + if (!success){ +#ifdef WIN32 + int ver = 12; + while (!success && ver) { + executable = Glib::build_filename (Glib::build_filename(options.gimpDir,"bin"), Glib::ustring::compose(Glib::ustring("gimp-2.%1.exe"),ver)); + if ( safe_file_test(executable, (Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE)) ) { + cmdLine = Glib::ustring("\"") + executable + Glib::ustring("\" \"") + filename + Glib::ustring("\""); + success = safe_spawn_command_line_async (cmdLine); + } + ver--; + } +#elif defined __APPLE__ + cmdLine = Glib::ustring("open -a /Applications/Gimp.app/Contents/Resources/start \'") + filename + Glib::ustring("\'"); + success = safe_spawn_command_line_async (cmdLine); + std::cout << cmdLine << std::endl; +#else + cmdLine = Glib::ustring("gimp-remote \"") + filename + Glib::ustring("\""); + success = safe_spawn_command_line_async (cmdLine); + std::cout << cmdLine << std::endl; +#endif + } + } + else if (options.editorToSendTo==2) { +#ifdef WIN32 + executable = Glib::build_filename(options.psDir,"Photoshop.exe"); + if ( safe_file_test(executable, (Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE)) ) { + cmdLine = Glib::ustring("\"") + executable + Glib::ustring("\" \"") + filename + Glib::ustring("\""); + success = safe_spawn_command_line_async (cmdLine); + } +#else + #ifdef __APPLE__ + cmdLine = Glib::ustring("open -a \'") + Glib::build_filename(options.psDir,"Photoshop.app\' ") + Glib::ustring("\'") + filename + Glib::ustring("\'"); + #else + cmdLine = Glib::ustring("\"") + Glib::build_filename(options.psDir,"Photoshop.exe") + Glib::ustring("\" \"") + filename + Glib::ustring("\""); + #endif + success = safe_spawn_command_line_async (cmdLine); + std::cout << cmdLine << std::endl; +#endif + } + else if (options.editorToSendTo==3) { +#ifdef WIN32 + if ( safe_file_test(options.customEditorProg, (Glib::FILE_TEST_EXISTS|Glib::FILE_TEST_IS_EXECUTABLE)) ) { + cmdLine = Glib::ustring("\"") + options.customEditorProg + Glib::ustring("\" \"") + filename + Glib::ustring("\""); + success = safe_spawn_command_line_async (cmdLine); + } +#else + #ifdef __APPLE__ + cmdLine = options.customEditorProg + Glib::ustring(" \"") + filename + Glib::ustring("\""); + #else + cmdLine = Glib::ustring("\"") + options.customEditorProg + Glib::ustring("\" \"") + filename + Glib::ustring("\""); + #endif + success = safe_spawn_command_line_async (cmdLine); + std::cout << cmdLine << std::endl; +#endif + } + + if (!success) { + Gtk::MessageDialog* msgd = new Gtk::MessageDialog (*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 (); + delete msgd; + } + + } + + return false; +} + +void EditorPanel::historyBeforeLineChanged (const rtengine::procparams::ProcParams& params) { + + if (beforeIpc) { + ProcParams* pparams = beforeIpc->beginUpdateParams (); + *pparams = params; + beforeIpc->endUpdateParams (rtengine::EvProfileChanged); // starts the IPC processing + } +} + +void EditorPanel::beforeAfterToggled () { + + if(!ipc) + return; + + removeIfThere (beforeAfterBox, beforeBox, false); + removeIfThere (afterBox, afterHeaderBox, false); + if (beforeIarea) { + if (beforeIpc) + beforeIpc->stopProcessing (); + iareapanel->setBeforeAfterViews (NULL, iareapanel); + iareapanel->imageArea->iLinkedImageArea = NULL; + delete beforeIarea; + beforeIarea = NULL; + if (beforeIpc) + { beforeIpc->setPreviewImageListener (NULL); + } + delete beforePreviewHandler; + beforePreviewHandler = NULL; + if (beforeIpc) + rtengine::StagedImageProcessor::destroy (beforeIpc); + beforeIpc = NULL; + } + + if (beforeAfter->get_active ()) { + + int errorCode=0; + rtengine::InitialImage *beforeImg = rtengine::InitialImage::load ( isrc->getImageSource ()->getFileName(), openThm->getType()==FT_Raw , &errorCode, NULL); + if( !beforeImg || errorCode ) + return; + + beforeIarea = new ImageAreaPanel (); + + int HeaderBoxHeight = 17; + + beforeLabel = Gtk::manage (new Gtk::Label ()); + beforeLabel->set_markup (Glib::ustring("") + M("GENERAL_BEFORE") + ""); + tbBeforeLock = Gtk::manage (new Gtk::ToggleButton ()); + tbBeforeLock->set_tooltip_markup (M("MAIN_TOOLTIP_BEFOREAFTERLOCK")); + tbBeforeLock->signal_toggled().connect( sigc::mem_fun(*this, &EditorPanel::tbBeforeLock_toggled) ); + beforeHeaderBox = Gtk::manage (new Gtk::HBox ()); + beforeHeaderBox->pack_end (*tbBeforeLock, Gtk::PACK_SHRINK, 2); + beforeHeaderBox->pack_end (*beforeLabel, Gtk::PACK_SHRINK, 2); + beforeHeaderBox->set_size_request(0, HeaderBoxHeight); + + history->blistenerLock ? tbBeforeLock->set_image (*iBeforeLockON):tbBeforeLock->set_image (*iBeforeLockOFF); + tbBeforeLock->set_active(history->blistenerLock); + + beforeBox = Gtk::manage (new Gtk::VBox ()); + beforeBox->pack_start (*beforeHeaderBox, Gtk::PACK_SHRINK, 2); + beforeBox->pack_start (*beforeIarea); + + afterLabel = Gtk::manage (new Gtk::Label ()); + afterLabel->set_markup (Glib::ustring("") + M("GENERAL_AFTER") + ""); + afterHeaderBox = Gtk::manage (new Gtk::HBox ()); + afterHeaderBox->set_size_request(0, HeaderBoxHeight); + afterHeaderBox->pack_end (*afterLabel, Gtk::PACK_SHRINK, 2); + afterBox->pack_start (*afterHeaderBox, Gtk::PACK_SHRINK, 2); + afterBox->reorder_child (*afterHeaderBox, 0); + + beforeAfterBox->pack_start (*beforeBox); + beforeAfterBox->reorder_child (*beforeBox, 0); + beforeAfterBox->show_all (); + + beforePreviewHandler = new PreviewHandler (); + + beforeIpc = rtengine::StagedImageProcessor::create (beforeImg); + beforeIpc->setPreviewScale (10); + beforeIpc->setPreviewImageListener (beforePreviewHandler); + beforeIarea->imageArea->setPreviewHandler (beforePreviewHandler); + beforeIarea->imageArea->setImProcCoordinator (beforeIpc); + + beforeIarea->imageArea->setPreviewModePanel(iareapanel->imageArea->previewModePanel); + beforeIarea->imageArea->setIndicateClippedPanel(iareapanel->imageArea->indClippedPanel); + iareapanel->imageArea->iLinkedImageArea = beforeIarea->imageArea; + + iareapanel->setBeforeAfterViews (beforeIarea, iareapanel); + beforeIarea->setBeforeAfterViews (beforeIarea, iareapanel); + + rtengine::procparams::ProcParams params; + if (history->getBeforeLineParams (params)) + historyBeforeLineChanged (params); + } +} + +void EditorPanel::tbBeforeLock_toggled () { + history->blistenerLock = tbBeforeLock->get_active(); + tbBeforeLock->get_active()? tbBeforeLock->set_image (*iBeforeLockON) : tbBeforeLock->set_image (*iBeforeLockOFF); +} + +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) { + + if (histogramPanel) histogramPanel->histogramChanged (histRed, histGreen, histBlue, histLuma, histRedRaw, histGreenRaw, histBlueRaw, histChroma); + tpc->updateCurveBackgroundHistogram (histToneCurve, histLCurve, histCCurve,/*histCLurve, histLLCurve,*/ histLCAM, histCCAM, histRed, histGreen, histBlue, histLuma); +} + +bool EditorPanel::CheckSidePanelsVisibility() { + if (tbTopPanel_1) { + if(tbTopPanel_1->get_active()==false && tbRightPanel_1->get_active()==false && hidehp->get_active()==false) + return false; + return true; + } + if(tbRightPanel_1->get_active()==false && hidehp->get_active()==false) + return false; + return true; +} +void EditorPanel::toggleSidePanels(){ + // Maximize preview panel: + // toggle top AND right AND history panels + + bool bAllSidePanelsVisible; + bAllSidePanelsVisible= CheckSidePanelsVisibility(); + + if (tbTopPanel_1) + tbTopPanel_1->set_active (!bAllSidePanelsVisible); + tbRightPanel_1->set_active (!bAllSidePanelsVisible); + hidehp->set_active (!bAllSidePanelsVisible); + if (bAllSidePanelsVisible == false) + tbShowHideSidePanels->set_image (*iShowHideSidePanels); + else + tbShowHideSidePanels->set_image (*iShowHideSidePanels_exit); +} + +void EditorPanel::toggleSidePanelsZoomFit() { + toggleSidePanels(); + + // fit image preview + // !!! TODO this does not want to work... seems to have an effect on a subsequent key press + // iarea->imageArea->zoomPanel->zoomFitClicked(); +} + +void EditorPanel::tbShowHideSidePanels_managestate() { + bool bAllSidePanelsVisible; + bAllSidePanelsVisible = CheckSidePanelsVisibility(); + ShowHideSidePanelsconn.block (true); + + tbShowHideSidePanels->set_active (!bAllSidePanelsVisible); + + ShowHideSidePanelsconn.block (false); +} + +void EditorPanel::updateTPVScrollbar (bool hide) { + tpc->updateTPVScrollbar (hide); +} + +void EditorPanel::updateTabsUsesIcons (bool useIcons) { + tpc->updateTabsUsesIcons (useIcons); +} + +void EditorPanel::updateHistogramPosition (int oldPosition, int newPosition) { + + switch (newPosition) { + case 0: + // No histogram + if (!oldPosition) { + // An histogram actually exist, we delete it + if (oldPosition == 1) + removeIfThere(leftbox, histogramPanel, false); + else if (oldPosition == 2) + removeIfThere(vboxright, histogramPanel, false); + delete histogramPanel; + histogramPanel = NULL; + } + // else no need to create it + break; + 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(); + } + histogramPanel->reorder(Gtk::ALIGN_LEFT); + leftbox->reorder_child(*histogramPanel, 0); + break; + 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(); + } + histogramPanel->reorder(Gtk::ALIGN_RIGHT); + vboxright->reorder_child(*histogramPanel, 0); + break; + } + + iareapanel->imageArea->setPointerMotionHListener (histogramPanel); +} diff --git a/rtgui/editorpanel.h b/rtgui/editorpanel.h new file mode 100644 index 000000000..bdeb7b64a --- /dev/null +++ b/rtgui/editorpanel.h @@ -0,0 +1,207 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * Copyright (c) 2010 Oliver Duis + * + * 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 _EDITORPANEL_ +#define _EDITORPANEL_ + +#include +#include "imageareapanel.h" +#include "toolpanelcoord.h" +#include "profilepanel.h" +#include "../rtengine/rtengine.h" +#include "history.h" +#include "histogrampanel.h" +#include "thumbnail.h" +#include "saveasdlg.h" +#include "batchqueueentry.h" +#include "thumbnaillistener.h" +#include "navigator.h" +#include "progressconnector.h" +#include "filepanel.h" + +class EditorPanel; +struct EditorPanelIdleHelper { + EditorPanel* epanel; + bool destroyed; + int pending; +}; + +class RTWindow; +class EditorPanel : public Gtk::VBox, + public PParamsChangeListener, + public rtengine::ProgressListener, + public ThumbnailListener, + public HistoryBeforeLineListener, + public rtengine::HistogramListener { + private: + + Glib::ustring lastSaveAsFileName; + bool realized; + + protected: + Gtk::ProgressBar *progressLabel; + Gtk::ToggleButton* info; + Gtk::ToggleButton* hidehp; + Gtk::ToggleButton* tbShowHideSidePanels; + Gtk::ToggleButton* tbTopPanel_1; + Gtk::ToggleButton* tbRightPanel_1; + Gtk::ToggleButton* tbBeforeLock; + //bool bAllSidePanelsVisible; + Gtk::ToggleButton* beforeAfter; + Gtk::HPaned* hpanedl; + Gtk::HPaned* hpanedr; + Gtk::HBox* statusBox; + Gtk::Image *iHistoryShow, *iHistoryHide; + Gtk::Image *iTopPanel_1_Show, *iTopPanel_1_Hide; + Gtk::Image *iRightPanel_1_Show, *iRightPanel_1_Hide; + Gtk::Image *iShowHideSidePanels; + Gtk::Image *iShowHideSidePanels_exit; + Gtk::Image *iBeforeLockON, *iBeforeLockOFF; + Gtk::VBox *leftbox; + Gtk::VBox *vboxright; + + Gtk::Button* queueimg; + Gtk::Button* saveimgas; + Gtk::Button* sendtogimp; + Gtk::Button* navSync; + Gtk::Button* navNext; + Gtk::Button* navPrev; + + ImageAreaPanel* iareapanel; + PreviewHandler* previewHandler; + PreviewHandler* beforePreviewHandler; // for the before-after view + PreviewHandler* previewHandler2; + Navigator* navigator; + ImageAreaPanel* beforeIarea; // for the before-after view + Gtk::VBox* beforeBox; + Gtk::VBox* afterBox; + Gtk::Label* beforeLabel; + Gtk::Label* afterLabel; + Gtk::HBox* beforeAfterBox; + Gtk::HBox* beforeHeaderBox; + Gtk::HBox* afterHeaderBox; + + Gtk::Frame* ppframe; + ProfilePanel* profilep; + History* history; + HistogramPanel* histogramPanel; + ToolPanelCoordinator* tpc; + RTWindow* parent; + //SaveAsDialog* saveAsDialog; + BatchToolPanelCoordinator* btpCoordinator; + FilePanel* fPanel; + + bool firstProcessingDone; + + Thumbnail* openThm; // may get invalid on external delete event + Glib::ustring fname; // must be saved separately + + rtengine::InitialImage* isrc; + rtengine::StagedImageProcessor* ipc; + rtengine::StagedImageProcessor* beforeIpc; // for the before-after view + + EditorPanelIdleHelper* epih; + + 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_sendToGimp( ProgressConnector *pc, Glib::ustring fname); + bool idle_sentToGimp(ProgressConnector *pc,rtengine::IImage16* img,Glib::ustring filename); + int err; + + time_t processingStartedTime; + + sigc::connection ShowHideSidePanelsconn; + + bool isProcessing; + + + public: + EditorPanel (FilePanel* filePanel = NULL); + virtual ~EditorPanel (); + + void open (Thumbnail* tmb, rtengine::InitialImage* isrc); + void setAspect (); + void on_realize (); + void leftPaneButtonReleased(GdkEventButton *event); + void rightPaneButtonReleased(GdkEventButton *event); + + void setParent (RTWindow* p) { parent = p; } + void writeOptions(); + + void showTopPanel(bool show); + bool isRealized() { return realized; } + // progresslistener interface + void setProgress (double p); + void setProgressStr (Glib::ustring str); + void setProgressState (bool inProcessing); + void error (Glib::ustring title, Glib::ustring descr); + void displayError (Glib::ustring title, Glib::ustring descr); // this is called by error in the gtk thread + void refreshProcessingState (bool inProcessing); // this is called by setProcessingState in the gtk thread + + // PParamsChangeListener interface + void procParamsChanged (rtengine::procparams::ProcParams* params, rtengine::ProcEvent ev, Glib::ustring descr, ParamsEdited* paramsEdited=NULL); + + // thumbnaillistener interface + void procParamsChanged (Thumbnail* thm, int whoChangedIt); + + // HistoryBeforeLineListener + void historyBeforeLineChanged (const rtengine::procparams::ProcParams& params); + + // HistogramListener + void 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); + + // event handlers + void info_toggled (); + void hideHistoryActivated (); + void tbRightPanel_1_toggled (); + void tbTopPanel_1_toggled (); + void beforeAfterToggled (); + void tbBeforeLock_toggled(); + void saveAsPressed (); + void queueImgPressed (); + void sendToGimpPressed (); + void openNextEditorImage (); + void openPreviousEditorImage (); + void syncFileBrowser (); + + void tbTopPanel_1_visible (bool visible); + bool CheckSidePanelsVisibility(); + void tbShowHideSidePanels_managestate(); + void toggleSidePanels(); + void toggleSidePanelsZoomFit(); + + void saveProfile (); + Glib::ustring getShortName (); + Glib::ustring getFileName (); + bool handleShortcutKey (GdkEventKey* event); + + bool getIsProcessing() const { return isProcessing; } + void updateTPVScrollbar (bool hide); + void updateTabsUsesIcons (bool useIcons); + void updateHistogramPosition (int oldPosition, int newPosition); + + Gtk::Paned *catalogPane; +}; + +#endif + diff --git a/rtgui/editwindow.cc b/rtgui/editwindow.cc new file mode 100644 index 000000000..af0e722ac --- /dev/null +++ b/rtgui/editwindow.cc @@ -0,0 +1,243 @@ +/* +* This file is part of RawTherapee. +* +* 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 "editwindow.h" +#include "options.h" +#include "preferences.h" +#include "cursormanager.h" +#include "rtwindow.h" +#include +#include "rtimage.h" +#include "threadutils.h" + +static EditWindow* editWnd = NULL; + +// Check if the system has more than one display and option is set +bool EditWindow::isMultiDisplayEnabled() { + return options.multiDisplayMode>0 && Gdk::Screen::get_default()->get_n_monitors ()>1; +} + +// Should only be created once, auto-creates window on correct display +EditWindow* EditWindow::getInstance(RTWindow* p) +{ + + if (editWnd == NULL) { + static MyMutex smutex_; + MyMutex::MyLock lock(smutex_); + if ( editWnd == 0 ) { + editWnd = new EditWindow(p); + + // Determine the other display and maximize the window on that + const Glib::RefPtr< Gdk::Window >& wnd=p->get_window(); + int monNo=p->get_screen()->get_monitor_at_window (wnd); + + Gdk::Rectangle lMonitorRect; + editWnd->get_screen()->get_monitor_geometry(isMultiDisplayEnabled() ? (monNo==0 ? 1 : 0) : monNo, lMonitorRect); + editWnd->move(lMonitorRect.get_x(), lMonitorRect.get_y()); + editWnd->maximize(); + editWnd->show(); + } else { + editWnd->show_all(); + } + } + + return editWnd; +} + +EditWindow::EditWindow (RTWindow* p) : parent(p) , isFullscreen(false) { + + Glib::ustring fName = "rt-logo.png"; + Glib::ustring fullPath = RTImage::findIconAbsolutePath(fName); + +#ifdef GLIBMM_EXCEPTIONS_ENABLED + try { set_default_icon_from_file (fullPath); + } catch(Glib::Exception& ex) { printf ("%s\n", ex.what().c_str()); } +#else + { std::auto_ptr error; + set_default_icon_from_file (fullPath, error); + } +#endif //GLIBMM_EXCEPTIONS_ENABLED + set_title_decorated(""); + property_allow_shrink() = true; + set_modal(false); + set_resizable(true); + + property_destroy_with_parent().set_value(false); + signal_window_state_event().connect( sigc::mem_fun(*this, &EditWindow::on_window_state_event) ); + + mainNB = Gtk::manage (new Gtk::Notebook ()); + mainNB->set_scrollable (true); + mainNB->signal_switch_page().connect_notify( sigc::mem_fun(*this, &EditWindow::on_mainNB_switch_page) ); + + signal_key_press_event().connect( sigc::mem_fun(*this, &EditWindow::keyPressed) ); + + Gtk::VBox* mainBox = Gtk::manage (new Gtk::VBox ()); + mainBox->pack_start (*mainNB); + + add (*mainBox); + show_all (); +} + +void EditWindow::on_realize () { + Gtk::Window::on_realize (); + + cursorManager.init (get_window()); +} + +bool EditWindow::on_window_state_event(GdkEventWindowState* event) { + if (!event->new_window_state) { + // Window mode + options.windowMaximized = false; + } + else if (event->new_window_state & (GDK_WINDOW_STATE_MAXIMIZED|GDK_WINDOW_STATE_FULLSCREEN)) { + // Fullscreen mode + options.windowMaximized = true; + } + return true; +} + +void EditWindow::on_mainNB_switch_page(GtkNotebookPage* page, guint page_num) { + //if (page_num > 1) { + EditorPanel *ep = static_cast(mainNB->get_nth_page(page_num)); + + if (mainNB->get_n_pages()>1 && page_num<=(filesEdited.size()-1)){ + set_title_decorated(ep->getFileName()); + } + ep->setAspect(); + //} +} + +void EditWindow::addEditorPanel (EditorPanel* ep, const std::string &name) { + ep->setParent (parent); + + // construct closeable tab for the image + Gtk::HBox* hb = Gtk::manage (new Gtk::HBox ()); + hb->pack_start (*Gtk::manage (new RTImage ("rtwindow.png"))); + hb->pack_start (*Gtk::manage (new Gtk::Label (Glib::path_get_basename (name)))); + hb->set_tooltip_markup (name); + Gtk::Button* closeb = Gtk::manage (new Gtk::Button ()); + closeb->set_image (*Gtk::manage(new RTImage ("gtk-close.png"))); + closeb->set_relief (Gtk::RELIEF_NONE); + closeb->set_focus_on_click (false); + // make the button as small as possible + Glib::RefPtr style = Gtk::RcStyle::create (); + style->set_xthickness (0); + style->set_ythickness (0); + + closeb->modify_style (style); + closeb->signal_clicked().connect( sigc::bind (sigc::mem_fun(*this, &EditWindow::remEditorPanel) , ep)); + hb->pack_end (*closeb); + hb->set_spacing (2); + hb->show_all (); + + mainNB->append_page (*ep, *hb); + mainNB->set_current_page (mainNB->page_num (*ep)); + mainNB->set_tab_reorderable (*ep, true); + + set_title_decorated(name); + + epanels[ name ] = ep; + filesEdited.insert ( name ); + parent->fpanel->refreshEditedState (filesEdited); + ep->setAspect(); +} + +void EditWindow::remEditorPanel (EditorPanel* ep) { + if (ep->getIsProcessing()) + return; // Will crash if destroyed while loading + + epanels.erase (ep->getFileName()); + filesEdited.erase (ep->getFileName ()); + parent->fpanel->refreshEditedState (filesEdited); + + mainNB->remove_page (*ep); + if (mainNB->get_n_pages()>0){ + EditorPanel* ep1 = static_cast(mainNB->get_nth_page (mainNB->get_current_page())); + set_title_decorated(ep1->getFileName()); + } + else set_title_decorated(""); + // TODO: save options if wanted +} + +bool EditWindow::selectEditorPanel(const std::string &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); + return true; + } + return false; +} + +bool EditWindow::keyPressed (GdkEventKey* event) { + bool ctrl = event->state & GDK_CONTROL_MASK; + + if(event->keyval == GDK_F11) { + toggleFullscreen(); + return true; + } + else { + if(mainNB->get_n_pages ()>0) { //pass the handling for the editor panels, if there are any + if (event->keyval == GDK_w && ctrl){ //remove editor panel + EditorPanel* ep = static_cast(mainNB->get_nth_page (mainNB->get_current_page())); + remEditorPanel (ep); + return true; + } + else if(mainNB->get_n_pages ()>0){ + EditorPanel* ep = static_cast(mainNB->get_nth_page (mainNB->get_current_page())); + return ep->handleShortcutKey (event); + } + } + return false; + } + +} + +void EditWindow::toggleFullscreen () { + isFullscreen ? unfullscreen() : fullscreen(); + isFullscreen = !isFullscreen; +} + +bool EditWindow::on_delete_event(GdkEventAny* event) { + // Check if any editor is still processing, and do NOT quit if so. Otherwise crashes and inconsistent caches + bool isProcessing=false; + + for ( std::set ::iterator iter = filesEdited.begin(); iter != filesEdited.end() && !isProcessing; iter++ ) { + if (epanels[*iter]->getIsProcessing()) isProcessing=true; + } + + if (isProcessing) + return true; + + for ( std::set ::iterator iter = filesEdited.begin(); iter != filesEdited.end(); iter++ ) + mainNB->remove_page (*epanels[*iter]); + + epanels.clear(); + + filesEdited.clear(); + parent->fpanel->refreshEditedState (filesEdited); + + hide (); + return false; +} + +void EditWindow::set_title_decorated(Glib::ustring fname){ + Glib::ustring subtitle; + if (!fname.empty()) subtitle= " - " + fname; + set_title("RawTherapee "+ M("EDITWINDOW_TITLE") + subtitle); +} diff --git a/rtgui/editwindow.h b/rtgui/editwindow.h new file mode 100644 index 000000000..7b8fb08c7 --- /dev/null +++ b/rtgui/editwindow.h @@ -0,0 +1,59 @@ +/* + * This file is part of RawTherapee. + * + * 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 _EDITWINDOW_ +#define _EDITWINDOW_ + +#include +#include "filepanel.h" +#include "editorpanel.h" +#include + +class EditWindow : public Gtk::Window { + + private: + RTWindow* parent; + + Gtk::Notebook* mainNB; + std::set filesEdited; + std::map epanels; + + bool isFullscreen; + void toggleFullscreen (); + + public: + // Check if the system has more than one display and option is set + static bool isMultiDisplayEnabled(); + + // Should only be created once, auto-creates window on correct display + static EditWindow* getInstance(RTWindow* p); + + EditWindow (RTWindow* p); + + void addEditorPanel (EditorPanel* ep,const std::string &name); + void remEditorPanel (EditorPanel* ep); + bool selectEditorPanel(const std::string &name); + + bool keyPressed (GdkEventKey* event); + bool on_delete_event(GdkEventAny* event); + bool on_window_state_event(GdkEventWindowState* event); + void on_mainNB_switch_page(GtkNotebookPage* page, guint page_num); + void set_title_decorated(Glib::ustring fname); + + void on_realize (); +}; + +#endif diff --git a/rtgui/epd.cc b/rtgui/epd.cc new file mode 100644 index 000000000..34f6a6842 --- /dev/null +++ b/rtgui/epd.cc @@ -0,0 +1,160 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "epd.h" +#include +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +EdgePreservingDecompositionUI::EdgePreservingDecompositionUI () : FoldableToolPanel(this, "epd", M("TP_EPD_LABEL"), true, true) { + + setEnabledTooltipMarkup(M("TP_EPD_TOOLTIP")); + + strength = Gtk::manage(new Adjuster (M("TP_EPD_STRENGTH"), -1.0, 2.0, 0.01, 0.5)); + gamma = Gtk::manage(new Adjuster (M("TP_EPD_GAMMA"), 0.8, 1.5, 0.01, 1.)); + edgeStopping = Gtk::manage(new Adjuster (M("TP_EPD_EDGESTOPPING"), 0.1, 4.0, 0.01, 1.4)); + scale = Gtk::manage(new Adjuster (M("TP_EPD_SCALE"), 0.1, 10.0, 0.01, 0.3)); + reweightingIterates = Gtk::manage(new Adjuster (M("TP_EPD_REWEIGHTINGITERATES"), 0, 9, 1, 0)); + + strength->setAdjusterListener(this); + gamma->setAdjusterListener(this); + edgeStopping->setAdjusterListener(this); + scale->setAdjusterListener(this); + reweightingIterates->setAdjusterListener(this); + + strength->show(); + gamma->show(); + edgeStopping->show(); + scale->show(); + reweightingIterates->show(); + + pack_start(*strength); + pack_start(*gamma); + pack_start(*edgeStopping); + pack_start(*scale); + pack_start(*reweightingIterates); +} + +void EdgePreservingDecompositionUI::read(const ProcParams *pp, const ParamsEdited *pedited){ + disableListener(); + + if(pedited){ + strength->setEditedState(pedited->epd.strength ? Edited : UnEdited); + gamma->setEditedState(pedited->epd.gamma ? Edited : UnEdited); + edgeStopping->setEditedState(pedited->epd.edgeStopping ? Edited : UnEdited); + scale->setEditedState(pedited->epd.scale ? Edited : UnEdited); + reweightingIterates->setEditedState(pedited->epd.reweightingIterates ? Edited : UnEdited); + set_inconsistent(multiImage && !pedited->epd.enabled); + } + + setEnabled(pp->epd.enabled); + strength->set_sensitive (true); + if(pp->wavelet.enabled){ + if(pp->wavelet.tmrs==0) {strength->set_sensitive (true);gamma->set_sensitive (true);} + else {strength->set_sensitive (false);gamma->set_sensitive (false);} + } + strength->setValue(pp->epd.strength); + gamma->setValue(pp->epd.gamma); + edgeStopping->setValue(pp->epd.edgeStopping); + scale->setValue(pp->epd.scale); + reweightingIterates->setValue(pp->epd.reweightingIterates); + + enableListener(); +} + +void EdgePreservingDecompositionUI::write(ProcParams *pp, ParamsEdited *pedited){ + pp->epd.strength = strength->getValue(); + pp->epd.gamma = gamma->getValue(); + pp->epd.edgeStopping = edgeStopping->getValue(); + pp->epd.scale = scale->getValue(); + pp->epd.reweightingIterates = reweightingIterates->getValue(); + pp->epd.enabled = getEnabled(); + strength->set_sensitive (true); + if(pp->wavelet.enabled){ + if(pp->wavelet.tmrs==0) {strength->set_sensitive (true);gamma->set_sensitive (true);} else {strength->set_sensitive (false);gamma->set_sensitive (false);} + } + if(pedited){ + pedited->epd.strength = strength->getEditedState(); + pedited->epd.gamma = gamma->getEditedState(); + pedited->epd.edgeStopping = edgeStopping->getEditedState(); + pedited->epd.scale = scale->getEditedState(); + pedited->epd.reweightingIterates = reweightingIterates->getEditedState(); + pedited->epd.enabled = !get_inconsistent(); + } +} + +void EdgePreservingDecompositionUI::setDefaults(const ProcParams *defParams, const ParamsEdited *pedited){ + strength->setDefault(defParams->epd.strength); + gamma->setDefault(defParams->epd.gamma); + edgeStopping->setDefault(defParams->epd.edgeStopping); + scale->setDefault(defParams->epd.scale); + reweightingIterates->setDefault(defParams->epd.reweightingIterates); + + if(pedited){ + strength->setDefaultEditedState(pedited->epd.strength ? Edited : UnEdited); + gamma->setDefaultEditedState(pedited->epd.gamma ? Edited : UnEdited); + edgeStopping->setDefaultEditedState(pedited->epd.edgeStopping ? Edited : UnEdited); + scale->setDefaultEditedState(pedited->epd.scale ? Edited : UnEdited); + reweightingIterates->setDefaultEditedState(pedited->epd.reweightingIterates ? Edited : UnEdited); + }else{ + strength->setDefaultEditedState(Irrelevant); + gamma->setDefaultEditedState(Irrelevant); + edgeStopping->setDefaultEditedState(Irrelevant); + scale->setDefaultEditedState(Irrelevant); + reweightingIterates->setDefaultEditedState(Irrelevant); + } +} + +void EdgePreservingDecompositionUI::adjusterChanged(Adjuster* a, double newval){ + if(listener && getEnabled()){ + if(a == strength) + listener->panelChanged(EvEPDStrength, Glib::ustring::format(std::setw(2), std::fixed, std::setprecision(2), a->getValue())); + else if(a == gamma) + listener->panelChanged(EvEPDgamma, Glib::ustring::format(std::setw(2), std::fixed, std::setprecision(2), a->getValue())); + else if(a == edgeStopping) + listener->panelChanged(EvEPDEdgeStopping, Glib::ustring::format(std::setw(2), std::fixed, std::setprecision(2), a->getValue())); + else if(a == scale) + listener->panelChanged(EvEPDScale, Glib::ustring::format(std::setw(2), std::fixed, std::setprecision(2), a->getValue())); + else if(a == reweightingIterates) + listener->panelChanged(EvEPDReweightingIterates, Glib::ustring::format((int)a->getValue())); + } +} + +void EdgePreservingDecompositionUI::enabledChanged () { + if (listener) { + if (get_inconsistent()) + listener->panelChanged (EvEPDEnabled, M("GENERAL_UNCHANGED")); + else if (getEnabled()) + listener->panelChanged (EvEPDEnabled, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvEPDEnabled, M("GENERAL_DISABLED")); + } +} + +void EdgePreservingDecompositionUI::setBatchMode(bool batchMode){ + ToolPanel::setBatchMode(batchMode); + + strength->showEditedCB(); + gamma->showEditedCB(); + edgeStopping->showEditedCB(); + scale->showEditedCB(); + reweightingIterates->showEditedCB(); +} + diff --git a/rtgui/epd.h b/rtgui/epd.h new file mode 100644 index 000000000..c0559a10a --- /dev/null +++ b/rtgui/epd.h @@ -0,0 +1,47 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _EPD_H_ +#define _EPD_H_ + +#include +#include "adjuster.h" +#include "toolpanel.h" + +class EdgePreservingDecompositionUI : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel { +protected: + Adjuster *strength; + Adjuster *gamma; + Adjuster *edgeStopping; + Adjuster *scale; + Adjuster *reweightingIterates; + +public: + + EdgePreservingDecompositionUI(); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + + void adjusterChanged (Adjuster* a, double newval); + void enabledChanged (); +}; + +#endif diff --git a/rtgui/exiffiltersettings.cc b/rtgui/exiffiltersettings.cc new file mode 100644 index 000000000..6c47e6b1f --- /dev/null +++ b/rtgui/exiffiltersettings.cc @@ -0,0 +1,48 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "exiffiltersettings.h" + +ExifFilterSettings::ExifFilterSettings () { + + clear (); +} + +void ExifFilterSettings::clear () { + fnumberFrom = 100; + fnumberTo = 0; + shutterFrom = 100; + shutterTo = 0; + isoFrom = 100000000; + isoTo = 0; + focalFrom = 1e8; + focalTo = 0; + lenses.clear (); + cameras.clear (); + expcomp.clear (); + filetypes.clear (); + + filterFNumber = false; + filterShutter = false; + filterFocalLen = false; + filterISO = false; + filterExpComp = false; + filterCamera = false; + filterLens = false; + filterFiletype = false; +} diff --git a/rtgui/exiffiltersettings.h b/rtgui/exiffiltersettings.h new file mode 100644 index 000000000..da049df05 --- /dev/null +++ b/rtgui/exiffiltersettings.h @@ -0,0 +1,55 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _EXIFFILTERSETTINGS_ +#define _EXIFFILTERSETTINGS_ + +#include +#include + +class ExifFilterSettings { + + public: + std::set filetypes; + std::set cameras; + std::set lenses; + std::set expcomp; + double fnumberFrom; + double fnumberTo; + double shutterFrom; + double shutterTo; + double focalFrom; + double focalTo; + int isoFrom; + int isoTo; + + bool filterFNumber; + bool filterShutter; + bool filterFocalLen; + bool filterISO; + bool filterExpComp; + bool filterCamera; + bool filterLens; + bool filterFiletype; + + ExifFilterSettings (); + void clear (); +}; + +#endif + diff --git a/rtgui/exifpanel.cc b/rtgui/exifpanel.cc new file mode 100644 index 000000000..58a46bd42 --- /dev/null +++ b/rtgui/exifpanel.cc @@ -0,0 +1,558 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "exifpanel.h" +#include "../rtengine/safegtk.h" +#include "guiutils.h" +#include "rtimage.h" + +using namespace rtengine; +using namespace rtengine::procparams; +using namespace rtexif; + +ExifPanel::ExifPanel () : idata(NULL) { + + recursiveOp = true; + + 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->get_selection()->set_mode (Gtk::SELECTION_MULTIPLE); + scrolledWindow->set_border_width(2); + 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); + exifTree->set_model (exifTreeModel); + + delicon = safe_create_from_file ("gtk-close.png"); + keepicon = safe_create_from_file ("gtk-apply.png"); + editicon = safe_create_from_file ("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()); + 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); + + render_pb->property_ypad() = 0; + render_txt->property_ypad() = 0; + render_pb->property_yalign() = 0; + render_txt->property_yalign() = 0; + + exifTree->append_column (*viewcol); + + Gtk::TreeView::Column *viewcolv = Gtk::manage(new Gtk::TreeView::Column ("Value")); + Gtk::CellRendererText *render_txtv = Gtk::manage(new Gtk::CellRendererText()); + viewcolv->pack_start (*render_txtv, true); + viewcolv->add_attribute (*render_txtv, "markup", exifColumns.value); + + render_txtv->property_ypad() = 0; + + exifTree->append_column (*viewcolv); + + pack_start (*scrolledWindow); + + Gtk::HBox* buttons1 = Gtk::manage(new Gtk::HBox ()); + Gtk::HBox* buttons2 = Gtk::manage(new Gtk::HBox ()); + + 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")); + buttons1->pack_start (*remove); + + 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")); + buttons1->pack_start (*keep); + + 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")); + buttons1->pack_start (*add); + + 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")); + buttons2->pack_start (*reset); + + 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")); + buttons2->pack_start (*resetAll); + + 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)); + + 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) ); + + show_all (); +} + +ExifPanel::~ExifPanel () { +} + +void ExifPanel::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + changeList = pp->exif; + setImageData (idata); + applyChangeList (); + exifSelectionChanged (); + + enableListener (); +} + +void ExifPanel::write (ProcParams* pp, ParamsEdited* pedited) { + +// updateChangeList (); + pp->exif = changeList; +} + +void ExifPanel::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + defChangeList = defParams->exif; +} + +void ExifPanel::setImageData (const ImageMetaData* id) { + + idata = id; + exifTreeModel->clear (); + + const std::vector& defTags = ExifManager::getDefaultTIFFTags (NULL); + for (size_t i=0; inameToString() == "ImageWidth" || defTags[i]->nameToString() == "ImageHeight" || defTags[i]->nameToString() == "BitsPerSample") + addTag (exifTreeModel->children(), defTags[i]->nameToString(), "?", AC_SYSTEM, false); + else + addTag (exifTreeModel->children(), defTags[i]->nameToString(), defTags[i]->valueToString(), AC_SYSTEM, false); + + if (id && id->getExifData ()) { +// id->getExifData ()->printAll (); + addDirectory (id->getExifData (), exifTreeModel->children()); + } +} + +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)); + row[exifColumns.action] = action; + row[exifColumns.editable] = editable; + row[exifColumns.edited] = false; + row[exifColumns.field_nopango] = field; + row[exifColumns.value_nopango] = value; + row[exifColumns.orig_value] = value; + + if (action==AC_WRITE) + row[exifColumns.icon] = keepicon; + else if (action==AC_DONTWRITE) + row[exifColumns.icon] = delicon; + + if (editable) { + 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) + ""; + } + else { + row[exifColumns.field] = escapeHtmlChars(field); + row[exifColumns.value] = escapeHtmlChars(value); + } + + return row.children(); +} + +void ExifPanel::addDirectory (const TagDirectory* dir, Gtk::TreeModel::Children root) { + + for (int i=0; igetCount(); i++) { + Tag* t = (const_cast(dir))->getTagByIndex (i); + if (t->getAttrib() && t->getAttrib()->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); + } + else + addTag (root, t->nameToString (), t->valueToString (), t->getAttrib() ? (t->getOwnMemory()?t->getAttrib()->action:AC_SYSTEM) : AC_DONTWRITE, t->getAttrib() && t->getAttrib()->editable); + } +} + +void ExifPanel::exifSelectionChanged () { + + Glib::RefPtr selection = exifTree->get_selection(); + std::vector sel = selection->get_selected_rows(); + if (sel.size()>1) { + remove->set_sensitive (1); + keep->set_sensitive (1); + reset->set_sensitive (1); + } + else if (sel.size()==1) { + Gtk::TreeModel::iterator iter = exifTreeModel->get_iter (sel[0]); + if (iter->get_value (exifColumns.action)==AC_SYSTEM) { + remove->set_sensitive (0); + keep->set_sensitive (0); + reset->set_sensitive (0); + } + else if (!iter->children().empty()) { + remove->set_sensitive (1); + keep->set_sensitive (1); + reset->set_sensitive (1); + } + 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) { + keep->set_sensitive (0); + remove->set_sensitive (1); + reset->set_sensitive (1); + } + } + else { + remove->set_sensitive (0); + keep->set_sensitive (0); + reset->set_sensitive (0); + } +} + +void ExifPanel::delIt (Gtk::TreeModel::iterator iter) { + + if (!iter) + return; + + if (iter->get_value (exifColumns.action) != AC_SYSTEM) + iter->set_value (exifColumns.icon, delicon); + if (recursiveOp) + for (Gtk::TreeModel::iterator i=iter->children().begin(); i!=iter->children().end(); i++) + delIt (i); +} + +void ExifPanel::removePressed () { + + std::vector sel = exifTree->get_selection()->get_selected_rows(); + for (size_t i=0; iget_iter (sel[i])); + + exifSelectionChanged (); + updateChangeList (); + notifyListener (); +} + +void ExifPanel::keepIt (Gtk::TreeModel::iterator iter) { + + if (!iter) + return; + + if (iter->get_value (exifColumns.action) != AC_SYSTEM) + iter->set_value (exifColumns.icon, iter->get_value (exifColumns.edited) ? editicon : keepicon); + if (recursiveOp) + for (Gtk::TreeModel::iterator i=iter->children().begin(); i!=iter->children().end(); i++) + keepIt (i); +} + +void ExifPanel::keepPressed () { + + std::vector sel = exifTree->get_selection()->get_selected_rows(); + for (size_t i=0; iget_iter (sel[i])); + + exifSelectionChanged (); + updateChangeList (); + notifyListener (); +} + +/*void ExifPanel::resetIt (Gtk::TreeModel::iterator iter) { + + if (!iter) + return; + + if (iter->get_value (exifColumns.action)!=AC_SYSTEM) + iter->set_value (exifColumns.icon, iter->get_value (exifColumns.action) ? keepicon : delicon); + 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.edited, false); + } + if (iter->get_value (exifColumns.action)==AC_INVALID) + exifTreeModel->erase (iter); + else + if (recursiveOp) + for (Gtk::TreeModel::iterator i=iter->children().begin(); i!=iter->children().end(); i++) + resetIt (i); +}*/ +Gtk::TreeModel::iterator ExifPanel::resetIt (Gtk::TreeModel::iterator iter) { + + if (!iter) + return iter; + + if (iter->get_value (exifColumns.action)!=AC_SYSTEM) + iter->set_value (exifColumns.icon, iter->get_value (exifColumns.action) ? keepicon : delicon); + 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.edited, false); + } + if (iter->get_value (exifColumns.action)==AC_INVALID) { + return exifTreeModel->erase (iter); + } + else + if (recursiveOp) { + Gtk::TreeModel::iterator i = iter->children().begin(); + while (i && i != iter->children().end()) + i = resetIt (i); + } + return ++iter; +} +void ExifPanel::resetPressed () { + + std::vector sel = exifTree->get_selection()->get_selected_rows(); + for (size_t i=0; iget_iter (sel[i])); + + exifSelectionChanged (); + updateChangeList (); + notifyListener (); +} + +void ExifPanel::resetAllPressed () { + + setImageData (idata); + changeList = defChangeList; + applyChangeList (); + exifSelectionChanged (); + notifyListener (); +} + +void ExifPanel::addPressed () { + + Gtk::Dialog* dialog = new Gtk::Dialog (M("EXIFPANEL_ADDTAGDLG_TITLE"), *((Gtk::Window*)get_toplevel()), true, 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")+":"); + MyComboBoxText* tcombo = new MyComboBoxText (); + + tcombo->append_text ("Artist"); + tcombo->append_text ("Copyright"); + tcombo->append_text ("ImageDescription"); + tcombo->append_text ("Exif.UserComment"); + + hb1->pack_start (*tlabel, Gtk::PACK_SHRINK, 4); + hb1->pack_start (*tcombo); + + 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); + + Glib::ustring sel = getSelection (true); + if (sel=="") + tcombo->set_active_text ("Exif.UserComment"); + else { + tcombo->set_active_text (sel); + if (tcombo->get_active ()<0) { + tcombo->append_text (sel); + tcombo->set_active_text (sel); + } + ventry->set_text (getSelectedValue ()); + } + + ventry->set_activates_default (true); + dialog->set_default_response (Gtk::RESPONSE_OK); + dialog->get_vbox()->pack_start (*hb1, Gtk::PACK_SHRINK); + dialog->get_vbox()->pack_start (*hb2, Gtk::PACK_SHRINK, 4); + tlabel->show (); + tcombo->show (); + vlabel->show (); + ventry->show (); + hb1->show (); + hb2->show (); + + if (dialog->run ()== Gtk::RESPONSE_OK) { + editTag (exifTreeModel->children(), tcombo->get_active_text(), ventry->get_text()); + updateChangeList (); + notifyListener (); + } + + delete dialog; + delete tlabel; + delete tcombo; + delete vlabel; + delete ventry; + delete hb1; + delete hb2; +} + +void ExifPanel::editTag (Gtk::TreeModel::Children root, Glib::ustring name, Glib::ustring value) { + + Glib::ustring::size_type dp = name.find_first_of ('.'); + Glib::ustring fseg = name.substr (0,dp); + // look up first segment of the path + Gtk::TreeModel::iterator iter; + for (iter = root.begin(); iter!=root.end(); iter++) + if (iter->get_value (exifColumns.field_nopango) == fseg) + break; + + if (iter==root.end() && value!="#keep" && value!="#delete") { + 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_nopango, value); + iter->set_value (exifColumns.orig_value, value); + 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.field, fseg); + iter->set_value (exifColumns.icon, keepicon); + iter->set_value (exifColumns.orig_value, Glib::ustring(M("EXIFPANEL_SUBDIRECTORY"))); + } + } + + if (dp==Glib::ustring::npos) { + if (value=="#keep" && iter->get_value (exifColumns.action)!=AC_SYSTEM) + iter->set_value (exifColumns.icon, iter->get_value (exifColumns.edited) ? editicon : keepicon); + 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_nopango, value); + iter->set_value (exifColumns.edited, true); + iter->set_value (exifColumns.icon, editicon); + } + } + else + editTag (iter->children(), name.substr (dp+1, Glib::ustring::npos), value); +} + +Glib::ustring ExifPanel::getSelectedValue () { + + Glib::RefPtr selection = exifTree->get_selection(); + std::vector rows = selection->get_selected_rows(); + if (rows.size()!=1) + return ""; + Gtk::TreeModel::iterator iter = exifTreeModel->get_iter (rows[0]); + if (iter) + return iter->get_value (exifColumns.value_nopango); + return ""; +} + +Glib::ustring ExifPanel::getSelection (bool onlyeditable) { + + Glib::RefPtr selection = exifTree->get_selection(); + std::vector rows = selection->get_selected_rows(); + + if (rows.size()!=1) + return ""; + Gtk::TreeModel::iterator iter = exifTreeModel->get_iter (rows[0]); + + Glib::ustring ret = ""; + bool first = true; + bool editable = false; + while (iter) { + if (first) + ret = iter->get_value (exifColumns.field_nopango); + else + ret = iter->get_value (exifColumns.field_nopango) + "." + ret; + editable = iter->get_value (exifColumns.editable); + iter = iter->parent (); + first = false; + } + if (!editable && onlyeditable) + return ""; + return ret; +} + +void ExifPanel::updateChangeList (Gtk::TreeModel::Children root, std::string prefix) { + + if (prefix!="") + prefix = prefix + "."; + + Gtk::TreeModel::iterator iter; + for (iter = root.begin(); iter!=root.end(); iter++) { + if (iter->get_value (exifColumns.edited) == true) + changeList[ prefix+iter->get_value (exifColumns.field_nopango) ] = iter->get_value (exifColumns.value_nopango); + else if (iter->get_value (exifColumns.action) == AC_WRITE && iter->get_value (exifColumns.icon) == delicon) + changeList[ prefix+iter->get_value (exifColumns.field_nopango) ] = "#delete"; + else if (iter->get_value (exifColumns.action) == AC_DONTWRITE && iter->get_value (exifColumns.icon) == keepicon) + changeList[ prefix+iter->get_value (exifColumns.field_nopango) ] = "#keep"; + if (iter->get_value (exifColumns.icon) == keepicon) + updateChangeList (iter->children(), prefix + iter->get_value (exifColumns.field_nopango)); + } +} + +void ExifPanel::updateChangeList () { + + changeList.clear (); + updateChangeList (exifTreeModel->children(), ""); +} + +void ExifPanel::applyChangeList () { + + for (rtengine::procparams::ExifPairs::iterator i=changeList.begin(); i!=changeList.end(); i++) + editTag (exifTreeModel->children(), i->first, i->second); +} + +void ExifPanel::row_activated (const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* column) { + + Gtk::TreeModel::iterator iter = exifTreeModel->get_iter (path); + if (iter) { + if (!iter->children().empty()) + if (exifTree->row_expanded (path)) + exifTree->collapse_row (path); + else + exifTree->expand_row (path, false); + else if (iter->get_value (exifColumns.editable)) + addPressed (); + } +} + + +void ExifPanel::notifyListener () { + + if (listener) + listener->panelChanged (EvExif, M("HISTORY_CHANGED")); +} diff --git a/rtgui/exifpanel.h b/rtgui/exifpanel.h new file mode 100644 index 000000000..1a5513031 --- /dev/null +++ b/rtgui/exifpanel.h @@ -0,0 +1,97 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _EXIFPANEL_ +#define _EXIFPANEL_ + +#include +#include "toolpanel.h" + +class ExifPanel : public Gtk::VBox, public ToolPanel { + + private: + const rtengine::ImageMetaData* idata; + int fullw, fullh, cx, cy, cw, ch; + bool crenabled; + rtengine::procparams::ExifPairs changeList; + rtengine::procparams::ExifPairs defChangeList; + bool recursiveOp; + + class ExifColumns : public Gtk::TreeModelColumnRecord { + public: + Gtk::TreeModelColumn > icon; + Gtk::TreeModelColumn field; + Gtk::TreeModelColumn field_nopango; + Gtk::TreeModelColumn value; + Gtk::TreeModelColumn value_nopango; + Gtk::TreeModelColumn orig_value; + Gtk::TreeModelColumn action; + Gtk::TreeModelColumn editable; + Gtk::TreeModelColumn edited; + + ExifColumns() { add(field); add(value); add(icon); add(action); add(edited); add(field_nopango); add(value_nopango); add(editable); add(orig_value); } + }; + Glib::RefPtr delicon; + Glib::RefPtr keepicon; + Glib::RefPtr editicon; + + ExifColumns exifColumns; + Gtk::TreeView* exifTree; + Gtk::ScrolledWindow* scrolledWindow; + Glib::RefPtr exifTreeModel; + + Gtk::Button* remove; + Gtk::Button* keep; + Gtk::Button* add; + Gtk::Button* reset; + Gtk::Button* resetAll; + + 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); + 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); + Gtk::TreeModel::iterator resetIt (Gtk::TreeModel::iterator iter); + public: + ExifPanel (); + virtual ~ExifPanel (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + + void setImageData (const rtengine::ImageMetaData* id); + + void exifSelectionChanged (); + void removePressed (); + void keepPressed (); + void resetPressed (); + void resetAllPressed (); + void addPressed (); + void row_activated (const Gtk::TreeModel::Path& path, Gtk::TreeViewColumn* column); + + void notifyListener (); + +}; + +#endif diff --git a/rtgui/exportpanel.cc b/rtgui/exportpanel.cc new file mode 100644 index 000000000..7c116b73e --- /dev/null +++ b/rtgui/exportpanel.cc @@ -0,0 +1,422 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * Copyright (c) 2012 Michael Ezra + * + * 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 "exportpanel.h" +#include "multilangmgr.h" +#include "options.h" +#include "rtimage.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +ExportPanel::ExportPanel () : listener (NULL) { + + set_border_width (4); + + /*enabled = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_ENABLE")) ); + 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")) ); + labExportTitle->set_use_markup (true); + labExportTitle->set_tooltip_text (M("EXPORT_INSTRUCTIONS")); + labExportTitle->set_alignment(Gtk::ALIGN_LEFT); + pack_start(*labExportTitle, Gtk::PACK_SHRINK, 4); + + bypass_ALL = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_ALL"))); + 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"))); + + // ---------------------- Bayer sensor frame ----------------------- + + 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); + raw_bayer_method = Gtk::manage (new MyComboBoxText ()); + for( size_t i=0; i< procparams::RAWParams::BayerSensor::numMethods;i++) + raw_bayer_method->append_text(procparams::RAWParams::BayerSensor::methodstring[i]); + + 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"))); + + // ---------------------- Bayer sensor frame ----------------------- + + 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); + raw_xtrans_method = Gtk::manage (new MyComboBoxText ()); + for( size_t i=0; i< procparams::RAWParams::XTransSensor::numMethods;i++) + raw_xtrans_method->append_text(procparams::RAWParams::XTransSensor::methodstring[i]); + + raw_xtrans_method->set_active(0); + hb_raw_xtrans_method->pack_end (*raw_xtrans_method, Gtk::PACK_EXPAND_WIDGET, 4); + + // ---------------------------------------------------------------- + + // start global packing + pack_start(*bypass_ALL , Gtk::PACK_SHRINK, 4); + pack_start(*Gtk::manage(new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 4); + pack_start(*bypass_sharpening , Gtk::PACK_SHRINK, 4); + pack_start(*bypass_sharpenEdge , Gtk::PACK_SHRINK, 4); + pack_start(*bypass_sharpenMicro , Gtk::PACK_SHRINK, 4); + //pack_start(*bypass_lumaDenoise , Gtk::PACK_SHRINK, 4); + //pack_start(*bypass_colorDenoise , Gtk::PACK_SHRINK, 4); + pack_start(*bypass_defringe , Gtk::PACK_SHRINK, 4); + pack_start(*bypass_dirpyrDenoise, Gtk::PACK_SHRINK, 4); + pack_start(*bypass_sh_hq , Gtk::PACK_SHRINK, 4); + pack_start(*bypass_dirpyrequalizer , Gtk::PACK_SHRINK, 4); + pack_start(*bypass_wavelet , 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); + + xtransFrameVBox->pack_start(*hb_raw_xtrans_method, Gtk::PACK_SHRINK, 4); + xtransFrame->add(*xtransFrameVBox); + + pack_start(*bypass_raw_ccSteps , Gtk::PACK_SHRINK, 4); + pack_start(*bypass_raw_ca , Gtk::PACK_SHRINK, 4); + + pack_start(*bypass_raw_df , Gtk::PACK_SHRINK, 4); + pack_start(*bypass_raw_ff , Gtk::PACK_SHRINK, 4); + + 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); + 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 (*MaxWidth); + 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_increments (1,100); + MaxWidth->set_value (options.fastexport_resize_width); + MaxWidth->set_range (32, 3000); + + MaxHeight->set_digits (0); + MaxHeight->set_increments (1,100); + MaxHeight->set_value (options.fastexport_resize_height); + MaxHeight->set_range (32, 3000); + + // Buttons + btnFastExport = Gtk::manage ( new Gtk::Button (M("EXPORT_PUTTOQUEUEFAST")) ); + btnFastExport->set_image (*Gtk::manage (new RTImage ("processing.png"))); + 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); + + + 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_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_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)); + + LoadDefaultSettings(); +} + +/*bool ExportPanel::isEnabled () { + + return enabled->get_active () && is_sensitive(); +}*/ + + +void ExportPanel::FastExportPressed (){ + // options is the container for making these settings available globally. + // Therefore, settings must be saved to options before they are used further + SaveSettingsAsDefault(); + + if (listener) + listener->exportRequested (); +} + +void ExportPanel::SaveSettingsAsDefault(){ + // Save fast export settings to options + options.fastexport_bypass_sharpening = bypass_sharpening->get_active (); + options.fastexport_bypass_sharpenEdge = bypass_sharpenEdge->get_active (); + options.fastexport_bypass_sharpenMicro = bypass_sharpenMicro->get_active (); + //options.fastexport_bypass_lumaDenoise = bypass_lumaDenoise->get_active (); + //options.fastexport_bypass_colorDenoise = bypass_colorDenoise->get_active (); + options.fastexport_bypass_defringe = bypass_defringe->get_active (); + options.fastexport_bypass_dirpyrDenoise = bypass_dirpyrDenoise->get_active (); + options.fastexport_bypass_sh_hq = bypass_sh_hq->get_active (); + options.fastexport_bypass_dirpyrequalizer = bypass_dirpyrequalizer->get_active (); + options.fastexport_bypass_wavelet = bypass_wavelet->get_active (); + //options.fastexport_bypass_raw_bayer_all_enhance = bypass_raw_all_enhance->get_active (); + options.fastexport_bypass_raw_bayer_dcb_iterations = bypass_raw_bayer_dcb_iterations->get_active (); + options.fastexport_bypass_raw_bayer_dcb_enhance = bypass_raw_bayer_dcb_enhance->get_active (); + options.fastexport_bypass_raw_bayer_lmmse_iterations = bypass_raw_bayer_lmmse_iterations->get_active(); + options.fastexport_bypass_raw_bayer_linenoise = bypass_raw_bayer_linenoise->get_active (); + options.fastexport_bypass_raw_bayer_greenthresh = bypass_raw_bayer_greenthresh->get_active (); + options.fastexport_bypass_raw_ccSteps = bypass_raw_ccSteps->get_active (); + options.fastexport_bypass_raw_ca = bypass_raw_ca->get_active (); + options.fastexport_bypass_raw_df = bypass_raw_df->get_active (); + 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) + 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) + options.fastexport_raw_xtrans_method = procparams::RAWParams::XTransSensor::methodstring[currentRow]; + +// options.fastexport_icm_input = icm_input ; +// options.fastexport_icm_working = icm_working ; +// options.fastexport_icm_output = icm_output ; +// options.fastexport_icm_gamma = icm_gamma ; +// options.fastexport_resize_enabled = resize_enabled ; +// options.fastexport_resize_scale = resize_scale ; +// options.fastexport_resize_appliesTo = resize_appliesTo; +// options.fastexport_resize_dataspec = resize_dataspec ; + + options.fastexport_resize_method = "Lanczos"; + options.fastexport_resize_width = MaxWidth->get_value_as_int (); + options.fastexport_resize_height = MaxHeight->get_value_as_int (); +} + +void ExportPanel::LoadDefaultSettings(){ + // Load fast export settings from options + bypass_sharpening->set_active (options.fastexport_bypass_sharpening ); + bypass_sharpenEdge->set_active (options.fastexport_bypass_sharpenEdge ); + bypass_sharpenMicro->set_active (options.fastexport_bypass_sharpenMicro ); + //bypass_lumaDenoise->set_active (options.fastexport_bypass_lumaDenoise ); + //bypass_colorDenoise->set_active (options.fastexport_bypass_colorDenoise ); + bypass_defringe->set_active (options.fastexport_bypass_defringe ); + bypass_dirpyrDenoise->set_active (options.fastexport_bypass_dirpyrDenoise ); + bypass_sh_hq->set_active (options.fastexport_bypass_sh_hq ); + bypass_dirpyrequalizer->set_active (options.fastexport_bypass_dirpyrequalizer ); + bypass_wavelet->set_active (options.fastexport_bypass_wavelet ); + //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_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 ); + bypass_raw_ca->set_active (options.fastexport_bypass_raw_ca ); + bypass_raw_df->set_active (options.fastexport_bypass_raw_df ); + bypass_raw_ff->set_active (options.fastexport_bypass_raw_ff ); + + // Bayer demosaic method + 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); + break; + } + + // X-Trans demosaic method + 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); + break; + } + +// icm_input = options.fastexport_icm_input ; +// icm_working = options.fastexport_icm_working ; +// icm_output = options.fastexport_icm_output ; +// icm_gamma = options.fastexport_icm_gamma ; +// resize_enabled = options.fastexport_resize_enabled ; +// resize_scale = options.fastexport_resize_scale ; +// 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); +} + +void ExportPanel::LoadSettings(){ + // load settings from file +} + +void ExportPanel::SaveSettings(){ + // save settings to file + +} + +void ExportPanel::bypassALL_Toggled(){ + bypass_sharpeningConn.block (true); + bypass_sharpenEdgeConn.block (true); + bypass_sharpenMicroConn.block (true); + //bypass_lumaDenoiseConn.block (true); + //bypass_colorDenoiseConn.block (true); + bypass_defringeConn.block (true); + bypass_dirpyrDenoiseConn.block (true); + bypass_sh_hqConn.block (true); + bypass_dirpyrequalizerConn.block (true); + bypass_waveletConn.block (true); + //bypass_raw_bayer_all_enhanceConn.block (true); + bypass_raw_bayer_dcb_iterationsConn.block (true); + bypass_raw_bayer_dcb_enhanceConn.block (true); + bypass_raw_bayer_lmmse_iterationsConn.block (true); + bypass_raw_bayer_linenoiseConn.block (true); + bypass_raw_bayer_greenthreshConn.block (true); + bypass_raw_ccStepsConn.block (true); + bypass_raw_caConn.block (true); + bypass_raw_dfConn.block (true); + bypass_raw_ffConn.block (true); + + 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_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_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_sharpeningConn.block (false); + bypass_sharpenEdgeConn.block (false); + bypass_sharpenMicroConn.block (false); + //bypass_lumaDenoiseConn.block (false); + //bypass_colorDenoiseConn.block (false); + bypass_defringeConn.block (false); + bypass_dirpyrDenoiseConn.block (false); + bypass_sh_hqConn.block (false); + bypass_dirpyrequalizerConn.block (false); + bypass_waveletConn.block (false); + //bypass_raw_bayer_all_enhanceConn.block (false); + bypass_raw_bayer_dcb_iterationsConn.block (false); + bypass_raw_bayer_dcb_enhanceConn.block (false); + bypass_raw_bayer_lmmse_iterationsConn.block (false); + bypass_raw_bayer_linenoiseConn.block (false); + bypass_raw_bayer_greenthreshConn.block (false); + bypass_raw_ccStepsConn.block (false); + bypass_raw_caConn.block (false); + bypass_raw_dfConn.block (false); + bypass_raw_ffConn.block (false); +} + +/* +fastexport_bypass_sharpening +fastexport_bypass_sharpenEdge +fastexport_bypass_sharpenMicro +fastexport_bypass_lumaDenoise +fastexport_bypass_colorDenoise +fastexport_bypass_defringe +fastexport_bypass_dirpyrDenoise +fastexport_bypass_sh_hq +fastexport_bypass_dirpyrequalizer +fastexport_raw_bayer_method +fastexport_bypass_raw_bayer_all_enhance +fastexport_bypass_raw_bayer_dcb_iterations +fastexport_bypass_raw_bayer_dcb_enhance +fastexport_bypass_raw_bayer_linenoise +fastexport_bypass_raw_bayer_greenthresh +fastexport_raw_xtrans_method +fastexport_bypass_raw_ccSteps +fastexport_bypass_raw_ca +fastexport_bypass_raw_df +fastexport_bypass_raw_ff +fastexport_icm_input +fastexport_icm_working +fastexport_icm_output +fastexport_icm_gamma +fastexport_resize_enabled +fastexport_resize_scale +fastexport_resize_appliesTo +fastexport_resize_method +fastexport_resize_dataspec +fastexport_resize_width +fastexport_resize_height +*/ diff --git a/rtgui/exportpanel.h b/rtgui/exportpanel.h new file mode 100644 index 000000000..bcbd44ea5 --- /dev/null +++ b/rtgui/exportpanel.h @@ -0,0 +1,120 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2012 Gabor Horvath + * Copyright (c) 2012 Michael Ezra + * + * 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 _EXPORTPANEL_ +#define _EXPORTPANEL_ + +#include +#include "guiutils.h" +#include "adjuster.h" + +class ExportPanelListener { + + public: + virtual void exportRequested () {} +}; + +class ExportPanel : public Gtk::VBox { + + protected: + + //Gtk::CheckButton* enabled; + Gtk::CheckButton* bypass_ALL; + Gtk::CheckButton* bypass_sharpenEdge; + Gtk::CheckButton* bypass_sharpenMicro; + Gtk::CheckButton* bypass_sharpening; + //Gtk::CheckButton* bypass_lumaDenoise; + //Gtk::CheckButton* bypass_colorDenoise; + Gtk::CheckButton* bypass_defringe; + Gtk::CheckButton* bypass_dirpyrDenoise; + Gtk::CheckButton* bypass_sh_hq; + +/* icm_input = "(camera)"; + icm_working = "sRGB"; + icm_output = "RT_sRGB"; + icm_gamma = "default"; +*/ + Gtk::CheckButton* bypass_dirpyrequalizer; // also could leave untouched but disable only small radius adjustments + //Gtk::CheckButton* bypass_raw_all_enhance; + Gtk::CheckButton* bypass_wavelet; // also could leave untouched but disable only small radius adjustments + + MyComboBoxText* raw_bayer_method; + + Gtk::CheckButton* bypass_raw_bayer_dcb_iterations; + Gtk::CheckButton* bypass_raw_bayer_dcb_enhance; + Gtk::CheckButton* bypass_raw_bayer_lmmse_iterations; + //Gtk::CheckButton* bypass_raw_bayer_all_enhance; + Gtk::CheckButton* bypass_raw_bayer_linenoise; + Gtk::CheckButton* bypass_raw_bayer_greenthresh; + + Gtk::CheckButton* bypass_raw_ccSteps; + Gtk::CheckButton* bypass_raw_ca; //wraps raw.cared, raw.cablue, raw.ca_autocorrect + Gtk::CheckButton* bypass_raw_df; //wraps raw.dark_frame, raw.df_AutoSelect + Gtk::CheckButton* bypass_raw_ff; //wraps raw.ff_file, raw.ff_AutoSelect + + MyComboBoxText* raw_xtrans_method; + + Gtk::Button* btnFastExport; + Gtk::Button* btnExportLoadSettings; + Gtk::Button* btnExportSaveSettings; + + MySpinButton* MaxWidth; + MySpinButton* MaxHeight; + + sigc::connection enabledconn, bypass_ALLconn, FastExportconn, ExportLoadSettingsconn, ExportSaveSettingsconn; + sigc::connection bypass_sharpeningConn ; + sigc::connection bypass_sharpenEdgeConn ; + sigc::connection bypass_sharpenMicroConn ; + //sigc::connection bypass_lumaDenoiseConn ; + //sigc::connection bypass_colorDenoiseConn ; + sigc::connection bypass_defringeConn ; + sigc::connection bypass_dirpyrDenoiseConn ; + sigc::connection bypass_sh_hqConn ; + sigc::connection bypass_dirpyrequalizerConn ; + sigc::connection bypass_waveletConn ; + //sigc::connection bypass_raw_bayer_all_enhanceConn ; + sigc::connection bypass_raw_bayer_dcb_iterationsConn ; + sigc::connection bypass_raw_bayer_dcb_enhanceConn ; + sigc::connection bypass_raw_bayer_lmmse_iterationsConn; + sigc::connection bypass_raw_bayer_linenoiseConn ; + sigc::connection bypass_raw_bayer_greenthreshConn ; + sigc::connection bypass_raw_ccStepsConn ; + sigc::connection bypass_raw_caConn ; + sigc::connection bypass_raw_dfConn ; + sigc::connection bypass_raw_ffConn ; + + + ExportPanelListener* listener; + + void bypassALL_Toggled(); + void SaveSettingsAsDefault(); + void LoadDefaultSettings(); + void LoadSettings(); + void SaveSettings(); + + public: + ExportPanel (); + + void FastExportPressed (); + //bool isEnabled (); + + void setExportPanelListener (ExportPanelListener* l) { listener = l; } +}; + +#endif diff --git a/rtgui/extprog.cc b/rtgui/extprog.cc new file mode 100644 index 000000000..f399b0b0f --- /dev/null +++ b/rtgui/extprog.cc @@ -0,0 +1,174 @@ +/* +* This file is part of RawTherapee. +* +* Copyright (c) 2012 Oliver Duis +* +* 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 "extprog.h" +#include "multilangmgr.h" +#include "../rtengine/safegtk.h" +#ifdef WIN32 +#include +// for GCC32 +#ifndef _WIN32_IE +#define _WIN32_IE 0x0600 +#endif +#include +#endif +using namespace std; + + +ExtProgAction::ExtProgAction() {} + +ExtProgAction::ExtProgAction(const ExtProgAction* other, int target) + : target(target), filePathEXE(other->filePathEXE), preparams(other->preparams), name(other->name) { } + +Glib::ustring ExtProgAction::GetFullName() { + return name+ " [" + M(Glib::ustring::compose("EXTPROGTARGET_%1", target)) + "]"; +} + +bool ExtProgAction::Execute(std::vector fileNames) { + if (fileNames.empty()) return false; + + // Check if they all exists (maybe not precessed yet) + for (int i=0;i0) cmdLine += " " + preparams; + + for (int i=0;i::iterator it=lActions.begin();it!=lActions.end();it++) delete *it; +} + +// Reads all profiles from the given profiles dir +void ExtProgStore::init () { + MyMutex::MyLock lock(mtx); + + lActions.clear(); + +#ifdef WIN32 + + SearchProg("Photoshop", "Adobe\\Adobe Photoshop CS%1 (64 Bit)\\Photoshop.exe", "Adobe\\Adobe Photoshop CS%1\\Photoshop.exe", 9, false, true); + SearchProg("Photomatix Pro", "PhotomatixPro%1\\PhotomatixPro.exe", "", 9, true, true); + SearchProg("Paint.NET", "Paint.NET\\PaintDotNet.exe", "", 0, false, true); + SearchProg("MS Image Composition Editor", "Microsoft Research\\Image Composite Editor\\ICE.exe", "", 0, false, true); + SearchProg("PTGui", "PTGui\\PTGui.exe", "", 0, false, true); + SearchProg("GeoSetter", "GeoSetter\\GeoSetter.exe", "", 0, true, true); + SearchProg("FastStone Image Viewer", "FastStone Image Viewer\\FSViewer.exe", "", 0, true, true); + SearchProg("FastPictureViewer", "FastPictureViewer\\FastPictureViewer.exe", "", 0, true, true); + + if (!SearchProg("Autopano Giga 3", "Kolor\\Autopano Giga 3.%1\\AutopanoGiga_x64.exe", "Kolor\\Autopano Giga 3.%1\\AutopanoGiga.exe", 15, true, true)){ + if ( !SearchProg("Autopano Pro 3", "Kolor\\Autopano Pro 3.%1\\AutopanoPro_x64.exe", "Kolor\\Autopano Pro 3.%1\\AutopanoPro.exe", 15, true, true)) { + if (!SearchProg("Autopano Giga 2", "Kolor\\Autopano Giga 2.%1\\AutopanoGiga_x64.exe", "Kolor\\Autopano Giga 2.%1\\AutopanoGiga.exe", 6, true, true)) + SearchProg("Autopano Pro 2", "Kolor\\Autopano Pro 2.%1\\AutopanoPro_x64.exe", "Kolor\\Autopano Pro 2.%1\\AutopanoPro.exe", 6, true, true); + } + } + + // DO NOT add obscure little tools here, only widely used programs with proper setup program to have a standard path +#endif + +} + +bool ExtProgStore::SearchProg(Glib::ustring name, Glib::ustring exePath, Glib::ustring exePath86, int maxVer, bool allowRaw, bool allowQueueProcess) { + bool found=false; + +#ifdef WIN32 + // get_user_special_dir crashes on some Windows configurations. + // so we use the safe native functions here + static Glib::ustring progFilesDir,progFilesDirx86; + + if (progFilesDir.empty()) { + WCHAR pathW[MAX_PATH]={0}; char pathA[MAX_PATH]; + + // First prio folder (64bit, otherwise 32bit) + if (SHGetSpecialFolderPathW(NULL,pathW,CSIDL_PROGRAM_FILES,false)) { + char pathA[MAX_PATH]; + WideCharToMultiByte(CP_UTF8,0,pathW,-1,pathA,MAX_PATH,0,0); + progFilesDir=Glib::ustring(pathA); + } + + if (SHGetSpecialFolderPathW(NULL,pathW,CSIDL_PROGRAM_FILESX86,false)) { + WideCharToMultiByte(CP_UTF8,0,pathW,-1,pathA,MAX_PATH,0,0); + progFilesDirx86=Glib::ustring(pathA); + } + } + + if (exePath86.empty()) exePath86=exePath; + + ExtProgAction *pAct=new ExtProgAction(); + pAct->name=name; + pAct->target= (allowRaw?1:2); + + if (maxVer>0) { + for (int verNo=maxVer;verNo>=0;verNo--) { + pAct->filePathEXE=progFilesDir+"\\"+Glib::ustring::compose(exePath,verNo); + if (safe_file_test(pAct->filePathEXE, Glib::FILE_TEST_EXISTS)) break; + + pAct->filePathEXE=progFilesDirx86+"\\"+Glib::ustring::compose(exePath86,verNo); + if (safe_file_test(pAct->filePathEXE, Glib::FILE_TEST_EXISTS)) break; + + pAct->filePathEXE=""; + } + } else { + pAct->filePathEXE=progFilesDir+"\\"+exePath; + if (!safe_file_test(pAct->filePathEXE, Glib::FILE_TEST_EXISTS)) { + + pAct->filePathEXE=progFilesDirx86+"\\"+exePath86; + if (!safe_file_test(pAct->filePathEXE, Glib::FILE_TEST_EXISTS)) pAct->filePathEXE=""; + } + } + + if (pAct->filePathEXE.length()>0){ + lActions.push_back(pAct); + + // Copy for second target + if (allowRaw && allowQueueProcess) lActions.push_back(new ExtProgAction(pAct,2)); + + found=true; + } else delete pAct; +#endif + + return found; +} diff --git a/rtgui/extprog.h b/rtgui/extprog.h new file mode 100644 index 000000000..6401cc09f --- /dev/null +++ b/rtgui/extprog.h @@ -0,0 +1,59 @@ +/* +* This file is part of RawTherapee. +* +* Copyright (c) 2012 Oliver Duis +* +* 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 _EXTPROG_ +#define _EXTPROG_ + +#include +#include +#include "threadutils.h" + +class ExtProgAction { +public: + ExtProgAction(); + ExtProgAction(const ExtProgAction* other, int target); + + Glib::ustring filePathEXE; + Glib::ustring preparams; // after EXE and before file names + Glib::ustring name; // already localized if necessary + int target; // 1=RAW files, 2=batch converted files + + Glib::ustring GetFullName(); // e.g. "Photoshop (RAW)" + + virtual bool Execute(std::vector fileNames); +}; + +// Stores all external programs that could be called by the user +class ExtProgStore { + MyMutex mtx; // covers actions + + bool SearchProg(Glib::ustring name, Glib::ustring exePath, Glib::ustring exePath86, int maxVer, bool allowRaw, bool allowQueueProcess); + +public: + ~ExtProgStore(); + + void init(); // searches computer for installed standard programs + static ExtProgStore* getInstance(); + + std::list lActions; +}; + +#define extProgStore ExtProgStore::getInstance() + +#endif diff --git a/rtgui/favoritbrowser.cc b/rtgui/favoritbrowser.cc new file mode 100644 index 000000000..9b66aad8b --- /dev/null +++ b/rtgui/favoritbrowser.cc @@ -0,0 +1,114 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "multilangmgr.h" +#include "rtimage.h" + +FavoritBrowser::FavoritBrowser () : listener (NULL), lastSelectedDir ("") { + + scrollw = Gtk::manage (new Gtk::ScrolledWindow ()); + scrollw->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC); + + Gtk::Frame* frame = Gtk::manage (new Gtk::Frame ("Favorite Folders")); + frame->add (*scrollw); + + pack_start (*frame); + + treeView = Gtk::manage (new Gtk::TreeView ()); + scrollw->add (*treeView); + + favoritModel = Gtk::ListStore::create (favoritColumns); + treeView->set_model (favoritModel); + treeView->set_headers_visible (false); + + Gtk::TreeView::Column *iviewcol = Gtk::manage (new Gtk::TreeView::Column ("icon")); + Gtk::CellRendererPixbuf *iconCR = Gtk::manage (new Gtk::CellRendererPixbuf()); + iviewcol->pack_start (*iconCR, false); + iviewcol->add_attribute (*iconCR, "gicon", 0); + + treeView->append_column (*iviewcol); + treeView->append_column ("text", favoritColumns.shortdir); + + treeView->set_tooltip_column (2); + treeView->get_selection()->signal_changed().connect(sigc::mem_fun(*this, &FavoritBrowser::selectionChanged)); + + add = Gtk::manage (new Gtk::Button (M("MAIN_FRAME_PLACES_ADD"))); + del = Gtk::manage (new Gtk::Button (M("MAIN_FRAME_PLACES_DEL"))); + add->set_image (*Gtk::manage (new RTImage ("gtk-add.png"))); + del->set_image (*Gtk::manage (new RTImage ("list-remove.png"))); + Gtk::HBox* buttonBox = Gtk::manage (new Gtk::HBox ()); + buttonBox->pack_start (*add); + buttonBox->pack_start (*del); + + pack_start (*buttonBox, Gtk::PACK_SHRINK, 2); + + add->signal_clicked().connect(sigc::mem_fun(*this, &FavoritBrowser::addPressed)); + del->signal_clicked().connect(sigc::mem_fun(*this, &FavoritBrowser::delPressed)); + + show_all (); +} + +void FavoritBrowser::selectionChanged () { + + Glib::RefPtr selection = treeView->get_selection(); + Gtk::TreeModel::iterator iter = selection->get_selected(); + if (iter && listener) + listener->selectDir (iter->get_value (favoritColumns.fulldir)); +} + +void FavoritBrowser::dirSelected (const Glib::ustring& dirname, const Glib::ustring& openfile) { + + lastSelectedDir = dirname; +} + +void FavoritBrowser::addPressed () { + + if (lastSelectedDir=="") + return; + + // check if the dirname is already in the list. If yes, return. + Gtk::TreeModel::iterator iter = favoritModel->children ().begin(); + while (iter != favoritModel->children().end()) { + if (iter->get_value (favoritColumns.fulldir) == lastSelectedDir) + return; + iter++; + } + + Glib::RefPtr hfile = Gio::File::create_for_parse_name (lastSelectedDir); + if (hfile) { + Glib::RefPtr info = hfile->query_info (); + if (info) { + Gtk::TreeModel::Row newrow = *(favoritModel->append()); + newrow[favoritColumns.shortdir] = info->get_display_name (); + newrow[favoritColumns.fulldir] = lastSelectedDir; + newrow[favoritColumns.icon] = info->get_icon (); + } + } +} + +void FavoritBrowser::delPressed () { + + // lookup the selected item in the bookmark + Glib::RefPtr selection = treeView->get_selection(); + Gtk::TreeModel::iterator iter = selection->get_selected(); + + if (iter) + favoritModel->erase (iter); +} + diff --git a/rtgui/favoritbrowser.h b/rtgui/favoritbrowser.h new file mode 100644 index 000000000..36f964bb8 --- /dev/null +++ b/rtgui/favoritbrowser.h @@ -0,0 +1,58 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _FAVORITBROWSER_ +#define _FAVORITBROWSER_ + +#include +#include "dirbrowserremoteinterface.h" +#include "dirselectionlistener.h" + +class FavoritBrowser : public Gtk::VBox, public DirSelectionListener { + + class FavoritColumns : public Gtk::TreeModel::ColumnRecord { + public: + Gtk::TreeModelColumn > icon; + Gtk::TreeModelColumn shortdir; + Gtk::TreeModelColumn fulldir; + FavoritColumns() { add(icon); add(shortdir), add(fulldir); } + }; + + FavoritColumns favoritColumns; + Gtk::ScrolledWindow* scrollw; + Gtk::TreeView* treeView; + Glib::RefPtr favoritModel; + DirBrowserRemoteInterface* listener; + Glib::ustring lastSelectedDir; + Gtk::Button* add; + Gtk::Button* del; + public: + + FavoritBrowser (); + + void setDirBrowserRemoteInterface (DirBrowserRemoteInterface* l) { listener = l; } + void dirSelected (const Glib::ustring& dirname, const Glib::ustring& openfile=""); + + void addPressed (); + void delPressed (); + void selectionChanged (); +}; + +#endif + + diff --git a/rtgui/filebrowser.cc b/rtgui/filebrowser.cc new file mode 100755 index 000000000..e8edc4fb2 --- /dev/null +++ b/rtgui/filebrowser.cc @@ -0,0 +1,1768 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * Copyright (c) 2011 Oliver Duis + * Copyright (c) 2011 Michael Ezra + * + * 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 "filebrowser.h" +#include +#include "options.h" +#include "multilangmgr.h" +#include "clipboard.h" +#include "procparamchangers.h" +#include "batchqueue.h" +#include "../rtengine/dfmanager.h" +#include "../rtengine/ffmanager.h" +#include "rtimage.h" +#include "threadutils.h" + +extern Options options; + +FileBrowser::FileBrowser () + : tbl(NULL),numFiltered(0), partialPasteDlg(M("PARTIALPASTE_DIALOGLABEL")) { + + fbih = new FileBrowserIdleHelper; + fbih->fbrowser = this; + fbih->destroyed = false; + fbih->pending = 0; + + profileStore.addListener(this); + + int p = 0; + pmenu = new Gtk::Menu (); + pmenu->attach (*Gtk::manage(open = new Gtk::MenuItem (M("FILEBROWSER_POPUPOPEN"))), 0, 1, p, p+1); p++; + pmenu->attach (*Gtk::manage(develop = new Gtk::ImageMenuItem (M("FILEBROWSER_POPUPPROCESS"))), 0, 1, p, p+1); p++; + develop->set_image(*Gtk::manage(new RTImage ("processing.png"))); + pmenu->attach (*Gtk::manage(developfast = new Gtk::ImageMenuItem (M("FILEBROWSER_POPUPPROCESSFAST"))), 0, 1, p, p+1); p++; + + pmenu->attach (*Gtk::manage(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++; + pmenu->attach (*Gtk::manage(selall = new Gtk::MenuItem (M("FILEBROWSER_POPUPSELECTALL"))), 0, 1, p, p+1); p++; + + /*********************** + * rank + ***********************/ + if (options.menuGroupRank){ + pmenu->attach (*Gtk::manage(menuRank = new Gtk::MenuItem (M("FILEBROWSER_POPUPRANK"))), 0, 1, p, p+1); p++; + Gtk::Menu* submenuRank = Gtk::manage (new Gtk::Menu ()); + submenuRank->attach (*Gtk::manage(rank[0] = new Gtk::MenuItem (M("FILEBROWSER_POPUPUNRANK"))), 0, 1, p, p+1); p++; + for (int i=1; i<=5; i++){ + submenuRank->attach (*Gtk::manage(rank[i] = new Gtk::MenuItem (M(Glib::ustring::compose("%1%2","FILEBROWSER_POPUPRANK",i)))), 0, 1, p, p+1); p++; + } + submenuRank->show_all (); + menuRank->set_submenu (*submenuRank); + } + else{ + pmenu->attach (*Gtk::manage(rank[0] = new Gtk::MenuItem (M("FILEBROWSER_POPUPUNRANK"))), 0, 1, p, p+1); p++; + for (int i=1; i<=5; i++){ + pmenu->attach (*Gtk::manage(rank[i] = new Gtk::MenuItem (M(Glib::ustring::compose("%1%2","FILEBROWSER_POPUPRANK",i)))), 0, 1, p, p+1); p++; + } + pmenu->attach (*Gtk::manage(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++; + } + + if (!options.menuGroupRank || !options.menuGroupLabel) // separate Rank and Color Labels if either is not grouped + pmenu->attach (*Gtk::manage(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++; + + /*********************** + * color labels + ***********************/ + if (options.menuGroupLabel){ + pmenu->attach (*Gtk::manage(menuLabel = new Gtk::MenuItem (M("FILEBROWSER_POPUPCOLORLABEL"))), 0, 1, p, p+1); p++; + Gtk::Menu* submenuLabel = Gtk::manage (new Gtk::Menu ()); + + for (int i=0; i<=5; i++){ + submenuLabel->attach (*Gtk::manage(colorlabel[i] = new Gtk::ImageMenuItem (M(Glib::ustring::compose("%1%2","FILEBROWSER_POPUPCOLORLABEL",i)))), 0, 1, p, p+1); p++; + } + submenuLabel->show_all (); + menuLabel->set_submenu (*submenuLabel); + } + else{ + for (int i=0; i<=5; i++){ + pmenu->attach (*Gtk::manage(colorlabel[i] = new Gtk::ImageMenuItem (M(Glib::ustring::compose("%1%2","FILEBROWSER_POPUPCOLORLABEL",i)))), 0, 1, p, p+1); p++; + } + } + + //set color label images + colorlabel[0]->set_image(*Gtk::manage(new RTImage ("cglabel0.png"))); + for (int i=1; i<=5; i++){ + colorlabel[i]->set_image(*Gtk::manage(new RTImage (Glib::ustring::compose("%1%2%3","clabel",i,".png")))); + } + + pmenu->attach (*Gtk::manage(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++; + + /*********************** + * external programs + * *********************/ +#if defined(WIN32) && defined(PROTECT_VECTORS) + Gtk::manage(miOpenDefaultViewer=new Gtk::MenuItem (M("FILEBROWSER_OPENDEFAULTVIEWER"))); +#else + miOpenDefaultViewer=NULL; +#endif + + // Build a list of menu items + mMenuExtProgs.clear(); amiExtProg=NULL; + for (std::list::iterator it=extProgStore->lActions.begin();it!=extProgStore->lActions.end();it++) { + ExtProgAction* pAct=*it; + + if (pAct->target==1 || pAct->target==2) mMenuExtProgs[pAct->GetFullName()]=pAct; + } + + // Attach them to menu + if (!mMenuExtProgs.empty() || miOpenDefaultViewer!=NULL) { + amiExtProg=new Gtk::MenuItem*[mMenuExtProgs.size()]; + int itemNo=0; + + if (options.menuGroupExtProg) { + pmenu->attach (*Gtk::manage(menuExtProg = new Gtk::MenuItem (M("FILEBROWSER_EXTPROGMENU"))), 0, 1, p, p+1); p++; + Gtk::Menu* submenuExtProg = Gtk::manage (new Gtk::Menu()); + + if (miOpenDefaultViewer!=NULL) { + submenuExtProg->attach (*miOpenDefaultViewer, 0, 1, p, p+1); p++; + } + + for (std::map::iterator it=mMenuExtProgs.begin();it!=mMenuExtProgs.end();it++,itemNo++) { + submenuExtProg->attach (*Gtk::manage(amiExtProg[itemNo] = new Gtk::MenuItem ((*it).first)), 0, 1, p, p+1); p++; + } + + submenuExtProg->show_all (); + menuExtProg->set_submenu (*submenuExtProg); + } else { + if (miOpenDefaultViewer!=NULL) { + pmenu->attach (*miOpenDefaultViewer, 0, 1, p, p+1); p++; + } + + for (std::map::iterator it=mMenuExtProgs.begin();it!=mMenuExtProgs.end();it++,itemNo++) { + pmenu->attach (*Gtk::manage(amiExtProg[itemNo] = new Gtk::MenuItem ((*it).first)), 0, 1, p, p+1); p++; + } + } + + pmenu->attach (*Gtk::manage(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++; + } + + /*********************** + * File Operations + * *********************/ + if (options.menuGroupFileOperations){ + pmenu->attach (*Gtk::manage(menuFileOperations = new Gtk::MenuItem (M("FILEBROWSER_POPUPFILEOPERATIONS"))), 0, 1, p, p+1); p++; + Gtk::Menu* submenuFileOperations = Gtk::manage (new Gtk::Menu ()); + + submenuFileOperations->attach (*Gtk::manage(trash = new Gtk::MenuItem (M("FILEBROWSER_POPUPTRASH"))), 0, 1, p, p+1); p++; + submenuFileOperations->attach (*Gtk::manage(untrash = new Gtk::MenuItem (M("FILEBROWSER_POPUPUNTRASH"))), 0, 1, p, p+1); p++; + submenuFileOperations->attach (*Gtk::manage(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++; + submenuFileOperations->attach (*Gtk::manage(rename = new Gtk::MenuItem (M("FILEBROWSER_POPUPRENAME"))), 0, 1, p, p+1); p++; + submenuFileOperations->attach (*Gtk::manage(remove = new Gtk::MenuItem (M("FILEBROWSER_POPUPREMOVE"))), 0, 1, p, p+1); p++; + submenuFileOperations->attach (*Gtk::manage(removeInclProc = new Gtk::MenuItem (M("FILEBROWSER_POPUPREMOVEINCLPROC"))), 0, 1, p, p+1); p++; + submenuFileOperations->attach (*Gtk::manage(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++; + submenuFileOperations->attach (*Gtk::manage(copyTo = new Gtk::MenuItem (M("FILEBROWSER_POPUPCOPYTO"))), 0, 1, p, p+1); p++; + submenuFileOperations->attach (*Gtk::manage(moveTo = new Gtk::MenuItem (M("FILEBROWSER_POPUPMOVETO"))), 0, 1, p, p+1); p++; + + submenuFileOperations->show_all (); + menuFileOperations->set_submenu (*submenuFileOperations); + } + else{ + pmenu->attach (*Gtk::manage(trash = new Gtk::MenuItem (M("FILEBROWSER_POPUPTRASH"))), 0, 1, p, p+1); p++; + pmenu->attach (*Gtk::manage(untrash = new Gtk::MenuItem (M("FILEBROWSER_POPUPUNTRASH"))), 0, 1, p, p+1); p++; + pmenu->attach (*Gtk::manage(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++; + pmenu->attach (*Gtk::manage(rename = new Gtk::MenuItem (M("FILEBROWSER_POPUPRENAME"))), 0, 1, p, p+1); p++; + pmenu->attach (*Gtk::manage(remove = new Gtk::MenuItem (M("FILEBROWSER_POPUPREMOVE"))), 0, 1, p, p+1); p++; + pmenu->attach (*Gtk::manage(removeInclProc = new Gtk::MenuItem (M("FILEBROWSER_POPUPREMOVEINCLPROC"))), 0, 1, p, p+1); p++; + pmenu->attach (*Gtk::manage(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++; + pmenu->attach (*Gtk::manage(copyTo = new Gtk::MenuItem (M("FILEBROWSER_POPUPCOPYTO"))), 0, 1, p, p+1); p++; + pmenu->attach (*Gtk::manage(moveTo = new Gtk::MenuItem (M("FILEBROWSER_POPUPMOVETO"))), 0, 1, p, p+1); p++; + } + + pmenu->attach (*Gtk::manage(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++; + + /*********************** + * Profile Operations + * *********************/ + if (options.menuGroupProfileOperations){ + pmenu->attach (*Gtk::manage(menuProfileOperations = new Gtk::ImageMenuItem (M("FILEBROWSER_POPUPPROFILEOPERATIONS"))), 0, 1, p, p+1); p++; + menuProfileOperations->set_image(*Gtk::manage(new RTImage ("logoicon-wind.png"))); + + Gtk::Menu* submenuProfileOperations = Gtk::manage (new Gtk::Menu ()); + + submenuProfileOperations->attach (*Gtk::manage(copyprof = new Gtk::MenuItem (M("FILEBROWSER_COPYPROFILE"))), 0, 1, p, p+1); p++; + submenuProfileOperations->attach (*Gtk::manage(pasteprof = new Gtk::MenuItem (M("FILEBROWSER_PASTEPROFILE"))), 0, 1, p, p+1); p++; + submenuProfileOperations->attach (*Gtk::manage(partpasteprof = new Gtk::MenuItem (M("FILEBROWSER_PARTIALPASTEPROFILE"))), 0, 1, p, p+1); p++; + submenuProfileOperations->attach (*Gtk::manage(applyprof = new Gtk::MenuItem (M("FILEBROWSER_APPLYPROFILE"))), 0, 1, p, p+1); p++; + submenuProfileOperations->attach (*Gtk::manage(applypartprof = new Gtk::MenuItem (M("FILEBROWSER_APPLYPROFILE_PARTIAL"))), 0, 1, p, p+1); p++; + submenuProfileOperations->attach (*Gtk::manage(execcustprof = new Gtk::MenuItem (M("FILEBROWSER_EXEC_CPB"))), 0, 1, p, p+1); p++; + submenuProfileOperations->attach (*Gtk::manage(clearprof = new Gtk::MenuItem (M("FILEBROWSER_CLEARPROFILE"))), 0, 1, p, p+1); p++; + + submenuProfileOperations->show_all (); + menuProfileOperations->set_submenu (*submenuProfileOperations); + } + else{ + pmenu->attach (*Gtk::manage(copyprof = new Gtk::MenuItem (M("FILEBROWSER_COPYPROFILE"))), 0, 1, p, p+1); p++; + pmenu->attach (*Gtk::manage(pasteprof = new Gtk::MenuItem (M("FILEBROWSER_PASTEPROFILE"))), 0, 1, p, p+1); p++; + pmenu->attach (*Gtk::manage(partpasteprof = new Gtk::MenuItem (M("FILEBROWSER_PARTIALPASTEPROFILE"))), 0, 1, p, p+1); p++; + pmenu->attach (*Gtk::manage(applyprof = new Gtk::MenuItem (M("FILEBROWSER_APPLYPROFILE"))), 0, 1, p, p+1); p++; + pmenu->attach (*Gtk::manage(applypartprof = new Gtk::MenuItem (M("FILEBROWSER_APPLYPROFILE_PARTIAL"))), 0, 1, p, p+1); p++; + pmenu->attach (*Gtk::manage(execcustprof = new Gtk::MenuItem (M("FILEBROWSER_EXEC_CPB"))), 0, 1, p, p+1); p++; + pmenu->attach (*Gtk::manage(clearprof = new Gtk::MenuItem (M("FILEBROWSER_CLEARPROFILE"))), 0, 1, p, p+1); p++; + } + + + pmenu->attach (*Gtk::manage(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++; + pmenu->attach (*Gtk::manage(menuDF = new Gtk::MenuItem (M("FILEBROWSER_DARKFRAME"))), 0, 1, p, p+1); p++; + pmenu->attach (*Gtk::manage(menuFF = new Gtk::MenuItem (M("FILEBROWSER_FLATFIELD"))), 0, 1, p, p+1); p++; + + pmenu->attach (*Gtk::manage(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++; + pmenu->attach (*Gtk::manage(cachemenu = new Gtk::MenuItem (M("FILEBROWSER_CACHE"))), 0, 1, p, p+1); p++; + + pmenu->show_all (); + + /*********************** + * Accelerators + * *********************/ + pmaccelgroup = Gtk::AccelGroup::create (); + pmenu->set_accel_group (pmaccelgroup); + selall->add_accelerator ("activate", pmenu->get_accel_group(), GDK_a, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE); + trash->add_accelerator ("activate", pmenu->get_accel_group(), GDK_Delete, (Gdk::ModifierType)0, Gtk::ACCEL_VISIBLE); + untrash->add_accelerator ("activate", pmenu->get_accel_group(), GDK_Delete, Gdk::SHIFT_MASK, Gtk::ACCEL_VISIBLE); + open->add_accelerator ("activate", pmenu->get_accel_group(), GDK_Return, (Gdk::ModifierType)0, Gtk::ACCEL_VISIBLE); + develop->add_accelerator ("activate", pmenu->get_accel_group(), GDK_B, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE); + copyprof->add_accelerator ("activate", pmenu->get_accel_group(), GDK_C, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE); + pasteprof->add_accelerator ("activate", pmenu->get_accel_group(), GDK_V, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE); + partpasteprof->add_accelerator ("activate", pmenu->get_accel_group(), GDK_V, 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)); + for (int i=0; i<6; i++) + rank[i]->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), rank[i])); + for (int i=0; i<6; i++) + colorlabel[i]->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), colorlabel[i])); + + for (int i=0; isignal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), amiExtProg[i])); + + if (miOpenDefaultViewer!=NULL) { + miOpenDefaultViewer->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), miOpenDefaultViewer)); + } + + trash->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), trash)); + untrash->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), untrash)); + develop->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), develop)); + developfast->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), developfast)); + rename->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), rename)); + remove->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), remove)); + removeInclProc->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), removeInclProc)); + selall->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), selall)); + copyTo->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), copyTo)); + moveTo->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), moveTo)); + copyprof->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), copyprof)); + pasteprof->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), pasteprof)); + partpasteprof->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), partpasteprof)); + applyprof->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), applyprof)); + applypartprof->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), applypartprof)); + execcustprof->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), execcustprof)); + 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 (); + for (int i=0; i<=5; i++){ + pmenuColorLabels->attach (*Gtk::manage(colorlabel_pop[i] = new Gtk::ImageMenuItem (M(Glib::ustring::compose("%1%2","FILEBROWSER_POPUPCOLORLABEL",i)))), 0, 1, c, c+1); c++; + } + //set color label images + colorlabel_pop[0]->set_image(*Gtk::manage(new RTImage ("cglabel0.png"))); + for (int i=1; i<=5; i++){ + colorlabel_pop[i]->set_image(*Gtk::manage(new RTImage (Glib::ustring::compose("%1%2%3","clabel",i,".png")))); + } + pmenuColorLabels->show_all (); + + // Has to be located after creation of applyprof and applypartprof + updateProfileList (); + + // Bind to event handlers + for (int i=0; i<=5; i++) + colorlabel_pop[i]->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuColorlabelActivated), colorlabel_pop[i])); +} + +FileBrowser::~FileBrowser () +{ + profileStore.removeListener(this); + delete pmenu; + delete pmenuColorLabels; + delete[] amiExtProg; +} + +void FileBrowser::rightClicked (ThumbBrowserEntryBase* entry) { + + { + #if PROTECT_VECTORS + MYREADERLOCK(l, entryRW); + #endif + + trash->set_sensitive (false); + untrash->set_sensitive (false); + for (size_t i=0; i(selected[i]))->thumbnail->getStage()==1) { + untrash->set_sensitive (true); + break; + } + for (size_t i=0; i(selected[i]))->thumbnail->getStage()==0) { + trash->set_sensitive (true); + break; + } + + pasteprof->set_sensitive (clipboard.hasProcParams()); + partpasteprof->set_sensitive (clipboard.hasProcParams()); + copyprof->set_sensitive (selected.size()==1); + clearprof->set_sensitive (!selected.empty()); + } + + // submenuDF + int p = 0; + Gtk::Menu* submenuDF = Gtk::manage (new Gtk::Menu ()); + submenuDF->attach (*Gtk::manage(selectDF = new Gtk::MenuItem (M("FILEBROWSER_SELECTDARKFRAME"))), 0, 1, p, p+1); p++; + submenuDF->attach (*Gtk::manage(autoDF = new Gtk::MenuItem (M("FILEBROWSER_AUTODARKFRAME"))), 0, 1, p, p+1); p++; + submenuDF->attach (*Gtk::manage(thisIsDF = new Gtk::MenuItem (M("FILEBROWSER_MOVETODARKFDIR"))), 0, 1, p, p+1); p++; + selectDF->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), selectDF)); + autoDF->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), autoDF)); + thisIsDF->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated),thisIsDF )); + submenuDF->show_all (); + menuDF->set_submenu (*submenuDF); + + // submenuFF + p = 0; + Gtk::Menu* submenuFF = Gtk::manage (new Gtk::Menu ()); + submenuFF->attach (*Gtk::manage(selectFF = new Gtk::MenuItem (M("FILEBROWSER_SELECTFLATFIELD"))), 0, 1, p, p+1); p++; + submenuFF->attach (*Gtk::manage(autoFF = new Gtk::MenuItem (M("FILEBROWSER_AUTOFLATFIELD"))), 0, 1, p, p+1); p++; + submenuFF->attach (*Gtk::manage(thisIsFF = new Gtk::MenuItem (M("FILEBROWSER_MOVETOFLATFIELDDIR"))), 0, 1, p, p+1); p++; + selectFF->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), selectFF)); + autoFF->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), autoFF)); + thisIsFF->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated),thisIsFF )); + submenuFF->show_all (); + menuFF->set_submenu (*submenuFF); + + // build cache sub menu + p = 0; + Gtk::Menu* cachesubmenu = Gtk::manage (new Gtk::Menu ()); + cachesubmenu->attach (*Gtk::manage(clearFromCache = new Gtk::MenuItem (M("FILEBROWSER_CACHECLEARFROMPARTIAL"))), 0, 1, p, p+1); p++; + cachesubmenu->attach (*Gtk::manage(clearFromCacheFull = new Gtk::MenuItem (M("FILEBROWSER_CACHECLEARFROMFULL"))), 0, 1, p, p+1); p++; + clearFromCache->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), clearFromCache)); + clearFromCacheFull->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), clearFromCacheFull)); + cachesubmenu->show_all (); + cachemenu->set_submenu (*cachesubmenu); + + pmenu->popup (3, this->eventTime); +} + +void FileBrowser::doubleClicked (ThumbBrowserEntryBase* entry) { + + if (tbl && entry) { + std::vector entries; + entries.push_back ((static_cast(entry))->thumbnail); + tbl->openRequested (entries); + } +} + +struct addparams { + FileBrowserIdleHelper* fbih; + FileBrowserEntry* entry; +}; + +int AddEntryUIThread (void* data) { + + addparams* ap = static_cast(data); + FileBrowserIdleHelper* fbih = ap->fbih; + + if (fbih->destroyed) { + if (fbih->pending == 1) + delete fbih; + else + fbih->pending--; + delete ap->entry; + delete ap; + + return 0; + } + + ap->fbih->fbrowser->addEntry_ (ap->entry); + delete ap; + fbih->pending--; + + return 0; +} + +void FileBrowser::addEntry (FileBrowserEntry* entry) { + + fbih->pending++; + entry->setParent (this); + addparams* ap = new addparams; + ap->fbih = fbih; + ap->entry = entry; + g_idle_add (AddEntryUIThread, ap); +} + +void FileBrowser::addEntry_ (FileBrowserEntry* entry) { + GThreadLock lock; // All GUI acces from idle_add callbacks or separate thread HAVE to be protected + entry->selected = false; + entry->drawable = false; + entry->framed = editedFiles.find (entry->filename)!=editedFiles.end(); + + // add button set to the thumbbrowserentry + entry->addButtonSet (new FileThumbnailButtonSet (entry)); + entry->getThumbButtonSet()->setRank (entry->thumbnail->getRank()); + entry->getThumbButtonSet()->setColorLabel (entry->thumbnail->getColorLabel()); + entry->getThumbButtonSet()->setInTrash (entry->thumbnail->getStage()==1); + entry->getThumbButtonSet()->setButtonListener (this); + entry->resize (getThumbnailHeight()); + + // find place in abc order + { + #if PROTECT_VECTORS + MYWRITERLOCK(l, entryRW); + #endif + + std::vector::iterator i = fd.begin(); + while (i!=fd.end() && *entry < *((FileBrowserEntry*)*i)) + i++; + + fd.insert (i, entry); + + initEntry (entry); + } + redraw (); + + // newly added item might have been already trashed in a previous session + trash_changed().emit(); +} + +FileBrowserEntry* FileBrowser::delEntry (const Glib::ustring& fname) { + #if PROTECT_VECTORS + MYWRITERLOCK(l, entryRW); + #endif + + for (std::vector::iterator i=fd.begin(); i!=fd.end(); i++) + if ((*i)->filename==fname) { + ThumbBrowserEntryBase* entry = *i; + entry->selected = false; + fd.erase (i); + std::vector::iterator j = std::find (selected.begin(), selected.end(), entry); + + #if PROTECT_VECTORS + MYWRITERLOCK_RELEASE(l); + #endif + + if (j!=selected.end()) { + if (checkFilter (*j)) numFiltered--; + selected.erase (j); + notifySelectionListener (); + } + + if (lastClicked==entry) + lastClicked = NULL; + redraw (); + + return (static_cast(entry)); + } + return NULL; +} + +void FileBrowser::close () { + if (fbih->pending) + fbih->destroyed = true; + else + delete fbih; + + fbih = new FileBrowserIdleHelper; + fbih->fbrowser = this; + fbih->destroyed = false; + fbih->pending = 0; + + { + #if PROTECT_VECTORS + MYWRITERLOCK(l, entryRW); + #endif + + selected.clear (); + + #if PROTECT_VECTORS + MYWRITERLOCK_RELEASE(l); // notifySelectionListener will need read access! + #endif + + notifySelectionListener (); + + #if PROTECT_VECTORS + MYWRITERLOCK_ACQUIRE(l); + #endif + + // The listener merges parameters with old values, so delete afterwards + for (size_t i=0; i tbe; + tbe.push_back (static_cast(colorLabel_actionData)); + + for (int i=0; i<6; i++) + if (m==colorlabel_pop[i]) { + colorlabelRequested (tbe, i); + return; + } +} + +void FileBrowser::menuItemActivated (Gtk::MenuItem* m) { + + std::vector mselected; + + { + #if PROTECT_VECTORS + MYREADERLOCK(l, entryRW); + #endif + + for (size_t i=0; i(selected[i])); + } + + + if (!tbl || (m!=selall && mselected.empty()) ) + return; + + for (int i=0; i<6; i++) + if (m==rank[i]) { + rankingRequested (mselected, i); + return; + } + for (int i=0; i<6; i++) + if (m==colorlabel[i]) { + colorlabelRequested (mselected, i); + return; + } + + for (int j=0; jget_label()]; + + // Build vector of all file names + std::vector selFileNames; + for (int i=0; ithumbnail->getFileName(); + + // Maybe batch processed version + if (pAct->target==2) fn = Glib::ustring::compose ("%1.%2", BatchQueue::calcAutoFileNameBase(fn), options.saveFormatBatch.format); + + selFileNames.push_back(fn); + } + + pAct->Execute(selFileNames); + return; + } + } + + if (m==open) + openRequested(mselected); + else if (m==remove) + tbl->deleteRequested (mselected, false); + else if (m==removeInclProc) + tbl->deleteRequested (mselected, true); + else if (m==trash) + toTrashRequested (mselected); + else if (m==untrash) + fromTrashRequested (mselected); + + else if (m==develop) + tbl->developRequested (mselected, false); + else if (m==developfast) + tbl->developRequested (mselected, true); + + else if (m==rename) + tbl->renameRequested (mselected); + else if (m==selall) { + lastClicked = NULL; + { + #if PROTECT_VECTORS + MYWRITERLOCK(l, entryRW); + #endif + + selected.clear (); + for (size_t i=0; iselected = true; + selected.push_back (fd[i]); + } + } + queue_draw (); + notifySelectionListener (); + } + else if( m==copyTo){ + tbl->copyMoveRequested (mselected, false); + } + + else if( m==moveTo){ + tbl->copyMoveRequested (mselected, true); + } + + else if (m==autoDF){ + if (!mselected.empty() && bppcl) + bppcl->beginBatchPParamsChange(mselected.size()); + for (size_t i=0; ithumbnail->getProcParams(); + pp.raw.df_autoselect= true; + pp.raw.dark_frame.clear(); + mselected[i]->thumbnail->setProcParams(pp,NULL,FILEBROWSER,false); + } + if (!mselected.empty() && bppcl) + bppcl->endBatchPParamsChange(); + + }else if (m==selectDF){ + if( !mselected.empty() ){ + rtengine::procparams::ProcParams pp=mselected[0]->thumbnail->getProcParams(); + Gtk::FileChooserDialog fc("Dark Frame",Gtk::FILE_CHOOSER_ACTION_OPEN ); + FileChooserLastFolderPersister persister(&fc, options.lastDarkframeDir); + fc.add_button( Gtk::StockID("gtk-cancel"), Gtk::RESPONSE_CANCEL); + fc.add_button( Gtk::StockID("gtk-apply"), Gtk::RESPONSE_APPLY); + if(!pp.raw.dark_frame.empty()) + fc.set_filename( pp.raw.dark_frame ); + if( fc.run() == Gtk::RESPONSE_APPLY ) { + if (bppcl) + bppcl->beginBatchPParamsChange(mselected.size()); + for (size_t i=0; ithumbnail->getProcParams(); + pp.raw.dark_frame= fc.get_filename(); + pp.raw.df_autoselect= false; + mselected[i]->thumbnail->setProcParams(pp,NULL,FILEBROWSER,false); + } + if (bppcl) + bppcl->endBatchPParamsChange(); + } + } + }else if( m==thisIsDF){ + if( !options.rtSettings.darkFramesPath.empty()) { + if (Gio::File::create_for_path(options.rtSettings.darkFramesPath)->query_exists() ){ + for (size_t i=0; i file = Gio::File::create_for_path ( mselected[i]->filename ); + if( !file )continue; + Glib::ustring destName = options.rtSettings.darkFramesPath+ "/" + file->get_basename(); + Glib::RefPtr dest = Gio::File::create_for_path ( destName ); + file->move( dest ); + } + // Reinit cache + rtengine::dfm.init( options.rtSettings.darkFramesPath ); + } + else { + // Target directory creation failed, we clear the darkFramesPath setting + options.rtSettings.darkFramesPath.clear(); + Glib::ustring msg_ = Glib::ustring::compose (M("MAIN_MSG_PATHDOESNTEXIST"), options.rtSettings.darkFramesPath) + +"\n\n"+M("MAIN_MSG_OPERATIONCANCELLED"); + Gtk::MessageDialog msgd (msg_, true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); + msgd.set_title(M("TP_DARKFRAME_LABEL")); + msgd.run (); + } + } + else { + Glib::ustring msg_ = M("MAIN_MSG_SETPATHFIRST")+"\n\n"+M("MAIN_MSG_OPERATIONCANCELLED"); + Gtk::MessageDialog msgd (msg_, true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); + msgd.set_title(M("TP_DARKFRAME_LABEL")); + msgd.run (); + } + } + else if (m==autoFF){ + if (!mselected.empty() && bppcl) + bppcl->beginBatchPParamsChange(mselected.size()); + for (size_t i=0; ithumbnail->getProcParams(); + pp.raw.ff_AutoSelect= true; + pp.raw.ff_file.clear(); + mselected[i]->thumbnail->setProcParams(pp,NULL,FILEBROWSER,false); + } + if (!mselected.empty() && bppcl) + bppcl->endBatchPParamsChange(); + } + else if (m==selectFF){ + if( !mselected.empty() ){ + rtengine::procparams::ProcParams pp=mselected[0]->thumbnail->getProcParams(); + Gtk::FileChooserDialog fc("Flat Field",Gtk::FILE_CHOOSER_ACTION_OPEN ); + FileChooserLastFolderPersister persister(&fc, options.lastFlatfieldDir); + fc.add_button( Gtk::StockID("gtk-cancel"), Gtk::RESPONSE_CANCEL); + fc.add_button( Gtk::StockID("gtk-apply"), Gtk::RESPONSE_APPLY); + if(!pp.raw.ff_file.empty()) + fc.set_filename( pp.raw.ff_file ); + if( fc.run() == Gtk::RESPONSE_APPLY ) { + if (bppcl) + bppcl->beginBatchPParamsChange(mselected.size()); + for (size_t i=0; ithumbnail->getProcParams(); + pp.raw.ff_file= fc.get_filename(); + pp.raw.ff_AutoSelect= false; + mselected[i]->thumbnail->setProcParams(pp,NULL,FILEBROWSER,false); + } + if (bppcl) + bppcl->endBatchPParamsChange(); + } + } + } + else if( m==thisIsFF){ + if( !options.rtSettings.flatFieldsPath.empty()) { + if (Gio::File::create_for_path(options.rtSettings.flatFieldsPath)->query_exists() ){ + for (size_t i=0; i file = Gio::File::create_for_path ( mselected[i]->filename ); + if( !file )continue; + Glib::ustring destName = options.rtSettings.flatFieldsPath+ "/" + file->get_basename(); + Glib::RefPtr dest = Gio::File::create_for_path ( destName ); + file->move( dest ); + } + // Reinit cache + rtengine::ffm.init( options.rtSettings.flatFieldsPath ); + } + else { + // Target directory creation failed, we clear the flatFieldsPath setting + options.rtSettings.flatFieldsPath.clear(); + Glib::ustring msg_ = Glib::ustring::compose (M("MAIN_MSG_PATHDOESNTEXIST"), options.rtSettings.flatFieldsPath) + +"\n\n"+M("MAIN_MSG_OPERATIONCANCELLED"); + Gtk::MessageDialog msgd (msg_, true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); + msgd.set_title(M("TP_FLATFIELD_LABEL")); + msgd.run (); + } + } + else { + Glib::ustring msg_ = M("MAIN_MSG_SETPATHFIRST")+"\n\n"+M("MAIN_MSG_OPERATIONCANCELLED"); + Gtk::MessageDialog msgd (msg_, true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); + msgd.set_title(M("TP_FLATFIELD_LABEL")); + msgd.run (); + } + } + else if (m==copyprof) + copyProfile (); + else if (m==pasteprof) + pasteProfile (); + else if (m==partpasteprof) + partPasteProfile (); + else if (m==clearprof) { + for (size_t i=0; ithumbnail->clearProcParams (FILEBROWSER); + queue_draw (); + } else if (m==execcustprof) { + if (!mselected.empty() && bppcl) + bppcl->beginBatchPParamsChange(mselected.size()); + for (size_t i=0; ithumbnail->createProcParamsForUpdate (false, true); + + // Empty run to update the thumb + rtengine::procparams::ProcParams params = mselected[i]->thumbnail->getProcParams (); + mselected[i]->thumbnail->setProcParams (params, NULL, FILEBROWSER); + } + if (!mselected.empty() && bppcl) + bppcl->endBatchPParamsChange(); + } else if (m==clearFromCache) { + for (size_t i=0; iclearFromCacheRequested (mselected, false); + //queue_draw (); + } + else if (m==clearFromCacheFull) { + for (size_t i=0; iclearFromCacheRequested (mselected, true); + //queue_draw (); + } else if (miOpenDefaultViewer!=NULL && m==miOpenDefaultViewer) { + openDefaultViewer(1); + } +} + +void FileBrowser::copyProfile () { + #if PROTECT_VECTORS + MYREADERLOCK(l, entryRW); + #endif + + if (selected.size()==1) + clipboard.setProcParams ((static_cast(selected[0]))->thumbnail->getProcParams()); +} + +void FileBrowser::pasteProfile () { + + if (clipboard.hasProcParams()) { + std::vector mselected; + { + #if PROTECT_VECTORS + MYREADERLOCK(l, entryRW); + #endif + + for (unsigned int i=0; i(selected[i])); + } + + if (!tbl || mselected.empty()) + return; + + if (!mselected.empty() && bppcl) + bppcl->beginBatchPParamsChange(mselected.size()); + for (unsigned int i=0; ithumbnail->setProcParams (*pastedPartProf.pparams, pastedPartProf.pedited, FILEBROWSER); + pastedPartProf.deleteInstance(); + } + if (!mselected.empty() && bppcl) + bppcl->endBatchPParamsChange(); + + queue_draw (); + } +} + +void FileBrowser::partPasteProfile () { + + if (clipboard.hasProcParams()) { + + std::vector mselected; + { + #if PROTECT_VECTORS + MYREADERLOCK(l, entryRW); + #endif + + for (unsigned int i=0; i(selected[i])); + } + + if (!tbl || mselected.empty()) + return; + + int i = partialPasteDlg.run (); + if (i == Gtk::RESPONSE_OK) { + + if (!mselected.empty() && bppcl) + bppcl->beginBatchPParamsChange(mselected.size()); + for (unsigned int i=0; ithumbnail->createProcParamsForUpdate(false,false); // this can execute customprofilebuilder to generate param file + rtengine::procparams::PartialProfile cbPartProf = clipboard.getPartialProfile(); + rtengine::procparams::PartialProfile pastedPartProf(&mselected[i]->thumbnail->getProcParams (), NULL); + + // pushing the selected values of the clipboard PartialProfile to the temporary PartialProfile + partialPasteDlg.applyPaste (pastedPartProf.pparams, pastedPartProf.pedited, cbPartProf.pparams, cbPartProf.pedited); + + // applying the temporary PartialProfile to the thumb's ProcParams + mselected[i]->thumbnail->setProcParams (*pastedPartProf.pparams, pastedPartProf.pedited, FILEBROWSER); + pastedPartProf.deleteInstance(); + } + if (!mselected.empty() && bppcl) + bppcl->endBatchPParamsChange(); + + queue_draw (); + } + partialPasteDlg.hide (); + } +} + +void FileBrowser::openDefaultViewer (int destination) { + bool success=true; + + { + #if PROTECT_VECTORS + MYREADERLOCK(l, entryRW); + #endif + + if (selected.size()==1) + success=(static_cast(selected[0]))->thumbnail->openDefaultViewer(destination); + } + + if (!success) { + Gtk::MessageDialog msgd (M("MAIN_MSG_IMAGEUNPROCESSED"), true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); + msgd.run (); + } +} + +bool FileBrowser::keyPressed (GdkEventKey* event) { + bool ctrl = event->state & GDK_CONTROL_MASK; + bool shift = event->state & GDK_SHIFT_MASK; + bool alt = event->state & GDK_MOD1_MASK; + bool altgr = event->state & GDK_MOD2_MASK; + + if ((event->keyval==GDK_C || event->keyval==GDK_c || event->keyval==GDK_Insert) && ctrl) { + copyProfile (); + return true; + } + else if ((event->keyval==GDK_V || event->keyval==GDK_v) && ctrl && !shift) { + pasteProfile (); + return true; + } + else if (event->keyval==GDK_Insert && shift) { + pasteProfile (); + return true; + } + else if ((event->keyval==GDK_V || event->keyval==GDK_v) && ctrl && shift) { + partPasteProfile (); + return true; + } + else if (event->keyval==GDK_Delete && !shift) { + menuItemActivated (trash); + return true; + } + else if (event->keyval==GDK_Delete && shift) { + menuItemActivated (untrash); + return true; + } + else if ((event->keyval==GDK_B || event->keyval==GDK_b) && ctrl) { + menuItemActivated (develop); + return true; + } + else if ((event->keyval==GDK_A || event->keyval==GDK_a) && ctrl) { + menuItemActivated (selall); + return true; + } + else if (event->keyval==GDK_F2 && !ctrl) { + menuItemActivated (rename); + return true; + } + else if (event->keyval==GDK_F3 && !(ctrl || shift || alt)) { // open Previous image from FileBrowser perspective + FileBrowser::openPrevImage (); + return true; + } + else if (event->keyval==GDK_F4 && !(ctrl || shift || alt)) { // open Next image from FileBrowser perspective + FileBrowser::openNextImage (); + return true; + } + else if (event->keyval==GDK_Left) { + selectPrev (1, shift); + return true; + } + else if (event->keyval==GDK_Right) { + selectNext (1, shift); + return true; + } + else if (event->keyval==GDK_Up) { + selectPrev (numOfCols, shift); + return true; + } + else if (event->keyval==GDK_Down) { + selectNext (numOfCols, shift); + return true; + } + else if (event->keyval==GDK_Home) { + selectFirst (shift); + return true; + } + else if (event->keyval==GDK_End) { + selectLast (shift); + return true; + } + else if(event->keyval==GDK_Return || event->keyval==GDK_KP_Enter) { + std::vector mselected; + for (size_t i=0; i(selected[i])); + openRequested(mselected); + } + else if (event->keyval==GDK_F5) { + int dest = 1; + if (event->state & GDK_SHIFT_MASK) + dest = 2; + else if (event->state & GDK_CONTROL_MASK) + dest = 3; + + openDefaultViewer (dest); + return true; + } + else if (event->keyval==GDK_Page_Up) { + scrollPage(GDK_SCROLL_UP); + return true; + } + else if (event->keyval==GDK_Page_Down) { + scrollPage(GDK_SCROLL_DOWN); + return true; + } + +#ifdef __WIN32__ + else if (shift && !ctrl && !alt && !altgr) { // rank + switch(event->hardware_keycode) { + case 0x30: // 0-key + requestRanking (0); + return true; + case 0x31: // 1-key + requestRanking (1); + return true; + case 0x32: // 2-key + requestRanking (2); + return true; + case 0x33: // 3-key + requestRanking (3); + return true; + case 0x34: // 4-key + requestRanking (4); + return true; + case 0x35: // 5-key + requestRanking (5); + return true; + } + } + else if (shift && ctrl && !alt && !altgr) { // color labels + switch(event->hardware_keycode) { + case 0x30: // 0-key + requestColorLabel (0); + return true; + case 0x31: // 1-key + requestColorLabel (1); + return true; + case 0x32: // 2-key + requestColorLabel (2); + return true; + case 0x33: // 3-key + requestColorLabel (3); + return true; + case 0x34: // 4-key + requestColorLabel (4); + return true; + case 0x35: // 5-key + requestColorLabel (5); + return true; + } + } +#else + else if (shift && !ctrl && !alt) { // rank + switch(event->hardware_keycode) { + case 0x13: + requestRanking (0); + return true; + case 0x0a: + requestRanking (1); + return true; + case 0x0b: + requestRanking (2); + return true; + case 0x0c: + requestRanking (3); + return true; + case 0x0d: + requestRanking (4); + return true; + case 0x0e: + requestRanking (5); + return true; + } + } + else if (shift && ctrl && !alt) { // color labels + switch(event->hardware_keycode) { + case 0x13: + requestColorLabel (0); + return true; + case 0x0a: + requestColorLabel (1); + return true; + case 0x0b: + requestColorLabel (2); + return true; + case 0x0c: + requestColorLabel (3); + return true; + case 0x0d: + requestColorLabel (4); + return true; + case 0x0e: + requestColorLabel (5); + return true; + } + } +#endif + + return false; +} + +void FileBrowser::saveThumbnailHeight (int height) { + if (!options.sameThumbSize && getLocation()==THLOC_EDITOR) + options.thumbSizeTab = height; + else + options.thumbSize = height; +} + +int FileBrowser::getThumbnailHeight () { + // The user could have manually forced the option to a too big value + if (!options.sameThumbSize && getLocation()==THLOC_EDITOR) + return std::max(std::min(options.thumbSizeTab, 800), 10); + else + return std::max(std::min(options.thumbSize, 800), 10); +} + +void FileBrowser::applyMenuItemActivated (ProfileStoreLabel *label) { + + #if PROTECT_VECTORS + MYREADERLOCK(l, entryRW); + #endif + + const rtengine::procparams::PartialProfile* partProfile = profileStore.getProfile (label->entry); + if (partProfile->pparams && !selected.empty()) { + if (bppcl) + bppcl->beginBatchPParamsChange(selected.size()); + for (size_t i=0; i(selected[i]))->thumbnail->setProcParams (*partProfile->pparams, partProfile->pedited, FILEBROWSER); + if (bppcl) + bppcl->endBatchPParamsChange(); + queue_draw (); + } +} + +void FileBrowser::applyPartialMenuItemActivated (ProfileStoreLabel *label) { + + { + #if PROTECT_VECTORS + MYREADERLOCK(l, entryRW); + #endif + + if (!tbl || selected.empty()) + return; + } + + const rtengine::procparams::PartialProfile* srcProfiles = profileStore.getProfile (label->entry); + + if (srcProfiles->pparams) { + if (partialPasteDlg.run()==Gtk::RESPONSE_OK) { + + #if PROTECT_VECTORS + MYREADERLOCK(l, entryRW); + #endif + + if (bppcl) + bppcl->beginBatchPParamsChange(selected.size()); + for (size_t i=0; ithumbnail->createProcParamsForUpdate(false, false); // this can execute customprofilebuilder to generate param file + + rtengine::procparams::PartialProfile dstProfile(true); + *dstProfile.pparams = (static_cast(selected[i]))->thumbnail->getProcParams (); + dstProfile.set(true); + partialPasteDlg.applyPaste (dstProfile.pparams, dstProfile.pedited, srcProfiles->pparams, srcProfiles->pedited); + (static_cast(selected[i]))->thumbnail->setProcParams (*dstProfile.pparams, dstProfile.pedited, FILEBROWSER); + dstProfile.deleteInstance(); + } + if (bppcl) + bppcl->endBatchPParamsChange(); + queue_draw (); + } + partialPasteDlg.hide (); + } +} + +void FileBrowser::applyFilter (const BrowserFilter& filter) { + + this->filter = filter; + + // remove items not complying the filter from the selection + bool selchanged = false; + numFiltered=0; + { + #if PROTECT_VECTORS + MYWRITERLOCK(l, entryRW); // Don't make this a writer lock! HOMBRE: Why? 'selected' is modified here + #endif + + for (size_t i=0; iselected ) { + fd[i]->selected = false; + std::vector::iterator j = std::find (selected.begin(), selected.end(), fd[i]); + selected.erase (j); + if (lastClicked==fd[i]) + lastClicked = NULL; + selchanged = true; + } + } + } + + if (selchanged) + notifySelectionListener (); + tbl->filterApplied(); + redraw (); +} + +bool FileBrowser::checkFilter (ThumbBrowserEntryBase* entryb) { // true -> entry complies filter + + FileBrowserEntry* entry = static_cast(entryb); + // return false if basic filter settings are not satisfied + if ((filter.showRanked[entry->thumbnail->getRank()]==false ) || + (filter.showCLabeled[entry->thumbnail->getColorLabel()]==false ) || + + ((entry->thumbnail->hasProcParams() && filter.showEdited[0]) && !filter.showEdited[1]) || + ((!entry->thumbnail->hasProcParams() && filter.showEdited[1])&& !filter.showEdited[0]) || + + ((entry->thumbnail->isRecentlySaved() && filter.showRecentlySaved[0]) && !filter.showRecentlySaved[1]) || + ((!entry->thumbnail->isRecentlySaved() && filter.showRecentlySaved[1]) && !filter.showRecentlySaved[0]) || + + (entry->thumbnail->getStage()==1 && !filter.showTrash) || + (entry->thumbnail->getStage()==0 && !filter.showNotTrash)) + return false; + + // return false is query is not satisfied + if (!filter.queryFileName.empty()){ + // check if image's FileName contains queryFileName (case insensitive) + // TODO should we provide case-sensitive search option via preferences? + Glib::ustring FileName; + FileName = Glib::path_get_basename (entry->thumbnail->getFileName()); + FileName = FileName.uppercase(); + //printf("FileBrowser::checkFilter FileName = '%s'; find() result= %i \n",FileName.c_str(), FileName.find(filter.queryFileName.uppercase())); + + Glib::ustring decodedQueryFileName; + bool MatchEqual; + + // Determine the match mode - check if the first 2 characters are equal to "!=" + if (filter.queryFileName.find("!=")==0){ + decodedQueryFileName = filter.queryFileName.substr (2,filter.queryFileName.length()-2); + MatchEqual = false; + } + else { + decodedQueryFileName = filter.queryFileName; + MatchEqual = true; + } + + // Consider that queryFileName consist of comma separated values (FilterString) + // Evaluate if ANY of these FilterString are contained in the filename + // This will construct OR filter within the filter.queryFileName + int iFilenameMatch=0; + std::vector vFilterStrings = Glib::Regex::split_simple(",", decodedQueryFileName.uppercase()); + for(int i=0; i0) // match is found for at least one of vFilterStrings in FileName + return false; + } + + /*experimental Regex support, this is unlikely to be useful to photographers*/ + //bool matchfound=Glib::Regex::match_simple(filter.queryFileName.uppercase(),FileName); + //if (!matchfound) return false; + } + + // check exif filter + const CacheImageData* cfs = entry->thumbnail->getCacheImageData(); + double tol = 0.01; + double tol2 = 1e-8; + + if (!filter.exifFilterEnabled) + return true; + + Glib::ustring camera(cfs->getCamera()); + + if (!cfs->exifValid) + return (!filter.exifFilter.filterCamera || filter.exifFilter.cameras.count(camera)>0) + && (!filter.exifFilter.filterLens || filter.exifFilter.lenses.count(cfs->lens)>0) + && (!filter.exifFilter.filterFiletype || filter.exifFilter.filetypes.count(cfs->filetype)>0) + && (!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.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) + && (!filter.exifFilter.filterCamera || filter.exifFilter.cameras.count(camera)>0) + && (!filter.exifFilter.filterLens || filter.exifFilter.lenses.count(cfs->lens)>0) + && (!filter.exifFilter.filterFiletype || filter.exifFilter.filetypes.count(cfs->filetype)>0); +} + +void FileBrowser::toTrashRequested (std::vector tbe) { + + for (size_t i=0; ithumbnail->createProcParamsForUpdate(false, false, true); // this can execute customprofilebuilder to generate param file in "flagging" mode + + // no need to notify listeners as item goes to trash, likely to be deleted + + if (tbe[i]->thumbnail->getStage()==1) + continue; + tbe[i]->thumbnail->setStage (1); + if (tbe[i]->getThumbButtonSet()) { + tbe[i]->getThumbButtonSet()->setRank (tbe[i]->thumbnail->getRank()); + tbe[i]->getThumbButtonSet()->setColorLabel (tbe[i]->thumbnail->getColorLabel()); + tbe[i]->getThumbButtonSet()->setInTrash (true); + tbe[i]->thumbnail->updateCache (); // needed to save the colorlabel to disk in the procparam file(s) and the cache image data file + } + } + trash_changed().emit(); + applyFilter (filter); +} + +void FileBrowser::fromTrashRequested (std::vector tbe) { + + for (size_t i=0; ithumbnail->getStage()==0) + continue; + tbe[i]->thumbnail->setStage (0); + if (tbe[i]->getThumbButtonSet()) { + tbe[i]->getThumbButtonSet()->setRank (tbe[i]->thumbnail->getRank()); + tbe[i]->getThumbButtonSet()->setColorLabel (tbe[i]->thumbnail->getColorLabel()); + tbe[i]->getThumbButtonSet()->setInTrash (false); + tbe[i]->thumbnail->updateCache (); // needed to save the colorlabel to disk in the procparam file(s) and the cache image data file + } + } + trash_changed().emit(); + applyFilter (filter); +} + +void FileBrowser::rankingRequested (std::vector tbe, int rank) { + + if (!tbe.empty() && bppcl) + bppcl->beginBatchPParamsChange(tbe.size()); + + for (size_t i=0; ithumbnail->createProcParamsForUpdate(false, false, true); // this can execute customprofilebuilder to generate param file in "flagging" mode + + // notify listeners TODO: should do this ONLY when params changed by customprofilebuilder? + tbe[i]->thumbnail->notifylisterners_procParamsChanged(FILEBROWSER); + + tbe[i]->thumbnail->setRank (rank); + tbe[i]->thumbnail->updateCache (); // needed to save the colorlabel to disk in the procparam file(s) and the cache image data file + //TODO? - should update pparams instead? + + if (tbe[i]->getThumbButtonSet()) + tbe[i]->getThumbButtonSet()->setRank (tbe[i]->thumbnail->getRank()); + } + applyFilter (filter); + + if (!tbe.empty() && bppcl) + bppcl->endBatchPParamsChange(); +} + +void FileBrowser::colorlabelRequested (std::vector tbe, int colorlabel) { + + if (!tbe.empty() && bppcl) + bppcl->beginBatchPParamsChange(tbe.size()); + + for (size_t i=0; ithumbnail->createProcParamsForUpdate(false, false, true); // this can execute customprofilebuilder to generate param file in "flagging" mode + + // notify listeners TODO: should do this ONLY when params changed by customprofilebuilder? + tbe[i]->thumbnail->notifylisterners_procParamsChanged(FILEBROWSER); + + tbe[i]->thumbnail->setColorLabel (colorlabel); + tbe[i]->thumbnail->updateCache(); // needed to save the colorlabel to disk in the procparam file(s) and the cache image data file + //TODO? - should update pparams instead? + if (tbe[i]->getThumbButtonSet()) + tbe[i]->getThumbButtonSet()->setColorLabel (tbe[i]->thumbnail->getColorLabel()); + } + applyFilter (filter); + + if (!tbe.empty() && bppcl) + bppcl->endBatchPParamsChange(); +} + +void FileBrowser::requestRanking(int rank){ + std::vector mselected; + { + #if PROTECT_VECTORS + MYREADERLOCK(l, entryRW); + #endif + for (size_t i=0; i(selected[i])); + } + + rankingRequested (mselected, rank); +} + +void FileBrowser::requestColorLabel(int colorlabel){ + std::vector mselected; + { + #if PROTECT_VECTORS + MYREADERLOCK(l, entryRW); + #endif + for (size_t i=0; i(selected[i])); + } + + colorlabelRequested (mselected, colorlabel); +} + +void FileBrowser::buttonPressed (LWButton* button, int actionCode, void* actionData) { + + if (actionCode>=0 && actionCode<=5) { // rank + std::vector tbe; + tbe.push_back (static_cast(actionData)); + rankingRequested (tbe, actionCode); + } + else if (actionCode==6 && tbl) { // to processing queue + std::vector tbe; + tbe.push_back (static_cast(actionData)); + tbl->developRequested (tbe, false); // not a fast, but a FULL mode + } + else if (actionCode==7) { // to trash / undelete + std::vector tbe; + FileBrowserEntry* entry = static_cast(actionData); + tbe.push_back (entry); + if (entry->thumbnail->getStage()==0) + toTrashRequested (tbe); + else + fromTrashRequested (tbe); + } + else if (actionCode==8 && tbl) { // color label + // show popup menu + colorLabel_actionData = actionData;// this will be reused when pmenuColorLabels is clicked + pmenuColorLabels->popup (3, this->eventTime); + } +} + +void FileBrowser::openNextImage () { + #if PROTECT_VECTORS + MYWRITERLOCK(l, entryRW); + #endif + + if (!fd.empty() && selected.size()>0 && !options.tabbedUI) { + + for (size_t i=0; ithumbnail->getFileName()==fd[i]->filename) {// located 1-st image in current selection + if (ifiltered/*checkFilter (fd[k])*/){ + // clear current selection + for (size_t j=0; jselected = false; + selected.clear (); + + // set new selection + fd[k]->selected = true; + selected.push_back (fd[k]); + //queue_draw (); + + #if PROTECT_VECTORS + MYWRITERLOCK_RELEASE(l); + #endif + + // this will require a read access + notifySelectionListener (); + + #if PROTECT_VECTORS + MYWRITERLOCK_ACQUIRE(l); + #endif + + // scroll to the selected position + double h1, v1; + getScrollPosition(h1,v1); + + double h2=selected[0]->getStartX(); + double v2=selected[0]->getStartY(); + + Thumbnail* thumb = (static_cast(fd[k]))->thumbnail; + int minWidth = get_width()-fd[k]->getMinimalWidth(); + + #if PROTECT_VECTORS + MYWRITERLOCK_RELEASE(l); + #endif + + // scroll only when selected[0] is outside of the displayed bounds + if (h2+minWidth-h1 > get_width()) + setScrollPosition(h2-minWidth,v2); + if (h1>h2) + setScrollPosition(h2,v2); + + // open the selected image + std::vector entries; + entries.push_back (thumb); + tbl->openRequested (entries); + return; + } + } + } + } + } + } +} + +void FileBrowser::openPrevImage () { + #if PROTECT_VECTORS + MYWRITERLOCK(l, entryRW); + #endif + + if (!fd.empty() && selected.size()>0 && !options.tabbedUI) { + + for (size_t i=1; ithumbnail->getFileName()==fd[i]->filename) {// located 1-st image in current selection + if (i>0 && tbl) { + // find the first not-filtered-out (previous) image + for (ssize_t k=(ssize_t)i-1; k>=0; k--){ + if (!fd[k]->filtered/*checkFilter (fd[k])*/){ + // clear current selection + for (size_t j=0; jselected = false; + selected.clear (); + + // set new selection + fd[k]->selected = true; + selected.push_back (fd[k]); + //queue_draw (); + + #if PROTECT_VECTORS + MYWRITERLOCK_RELEASE(l); + #endif + + // this will require a read access + notifySelectionListener (); + + #if PROTECT_VECTORS + MYWRITERLOCK_ACQUIRE(l); + #endif + + // scroll to the selected position + double h1, v1; + getScrollPosition(h1,v1); + + double h2=selected[0]->getStartX(); + double v2=selected[0]->getStartY(); + + Thumbnail* thumb = (static_cast(fd[k]))->thumbnail; + int minWidth = get_width()-fd[k]->getMinimalWidth(); + + #if PROTECT_VECTORS + MYWRITERLOCK_RELEASE(l); + #endif + + // scroll only when selected[0] is outside of the displayed bounds + if (h2+minWidth-h1 > get_width()) + setScrollPosition(h2-minWidth,v2); + if (h1>h2) + setScrollPosition(h2,v2); + + // open the selected image + std::vector entries; + entries.push_back (thumb); + tbl->openRequested (entries); + return; + } + } + } + } + } + } +} + + +void FileBrowser::selectImage (Glib::ustring fname) { + + // need to clear the filter in filecatalog + + #if PROTECT_VECTORS + MYWRITERLOCK(l, entryRW); + #endif + + if (!fd.empty() && !options.tabbedUI) { + for (size_t i=0; ifilename && !fd[i]->filtered) { + // matching file found for sync + + // clear current selection + for (size_t j=0; jselected = false; + selected.clear (); + + // set new selection + fd[i]->selected = true; + selected.push_back (fd[i]); + queue_draw (); + + #if PROTECT_VECTORS + MYWRITERLOCK_RELEASE(l); + #endif + + // this will require a read access + notifySelectionListener (); + + #if PROTECT_VECTORS + MYWRITERLOCK_ACQUIRE(l); + #endif + + // scroll to the selected position + double h=selected[0]->getStartX(); + double v=selected[0]->getStartY(); + + #if PROTECT_VECTORS + MYWRITERLOCK_RELEASE(l); + #endif + + setScrollPosition(h,v); + + return; + } + } + } +} + +void FileBrowser::openNextPreviousEditorImage (Glib::ustring fname, eRTNav nextPrevious) { + + // let FileBrowser acquire Editor's perspective + selectImage (fname); + + // now switch to the requested image + if (nextPrevious==NAV_NEXT) + openNextImage(); + else if (nextPrevious==NAV_PREVIOUS) + openPrevImage(); +} + +int refreshThumbImagesUI (void* data) { + (static_cast(data))->_thumbRearrangementNeeded (); + return 0; +} + +void FileBrowser::_thumbRearrangementNeeded () { + refreshThumbImages (); // arrangeFiles is NOT enough +} + +void FileBrowser::thumbRearrangementNeeded () { + // refreshThumbImagesUI will handle thread safety itself + g_idle_add (refreshThumbImagesUI, this); +} + +void FileBrowser::selectionChanged () { + + notifySelectionListener (); +} + +void FileBrowser::notifySelectionListener () { + + if (tbl) { + #if PROTECT_VECTORS + MYREADERLOCK(l, entryRW); + #endif + + std::vector thm; + for (size_t i=0; i(selected[i]))->thumbnail); + tbl->selectionChanged (thm); + } +} + +void FileBrowser::redrawNeeded (LWButton* button) { + GThreadLock lock; + queue_draw (); +} +FileBrowser::type_trash_changed FileBrowser::trash_changed () { + return m_trash_changed; +} + + +// ExportPanel interface +void FileBrowser::exportRequested (){ + FileBrowser::menuItemActivated(developfast); +} + +void FileBrowser::setExportPanel (ExportPanel* expanel) { + + exportPanel = expanel; + exportPanel->set_sensitive (false); + exportPanel->setExportPanelListener (this); +} + +void FileBrowser::updateProfileList () { + // submenu applmenu + int p = 0; + + const std::vector *profEntries = profileStore.getFileList(); // lock and get a pointer to the profiles' list + + std::map subMenuList; // store the Gtk::Menu that Gtk::MenuItem will have to be attached to + + subMenuList[0] = Gtk::manage (new Gtk::Menu ()); // adding the root submenu + + // iterate the profile store's profile list + for (size_t i=0; isize(); i++) { + // create a new label for the current entry (be it a folder or file) + ProfileStoreLabel *currLabel = Gtk::manage(new ProfileStoreLabel( profEntries->at(i) )); + + // create the MenuItem object + Gtk::MenuItem* mi = Gtk::manage (new Gtk::MenuItem (*currLabel)); + + // create a new Menu object if the entry is a folder and not the root one + if (currLabel->entry->type == PSET_FOLDER) { + // creating the new sub-menu + Gtk::Menu* subMenu = Gtk::manage (new Gtk::Menu ()); + + // add it to the menu list + subMenuList[currLabel->entry->folderId] = subMenu; + + // add it to the parent MenuItem + mi->set_submenu(*subMenu); + } + + // Hombre: ... does parentMenuId sounds like a hack? ... Yes. + int parentMenuId = !options.useBundledProfiles && currLabel->entry->parentFolderId==1 ? 0 : currLabel->entry->parentFolderId; + subMenuList[parentMenuId]->attach (*mi, 0, 1, p, p+1); p++; + if (currLabel->entry->type == PSET_FILE) + mi->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::applyMenuItemActivated), currLabel)); + mi->show (); + } + + if (subMenuList.size() && applyprof) + // TODO: Check that the previous one has been deleted, including all childrens + applyprof->set_submenu (*(subMenuList.at(0))); + + subMenuList.clear(); + subMenuList[0] = Gtk::manage (new Gtk::Menu ()); // adding the root submenu + // keep profEntries list + + // submenu applpartmenu + p = 0; + for (size_t i=0; isize(); i++) { + ProfileStoreLabel *currLabel = Gtk::manage(new ProfileStoreLabel( profEntries->at(i) )); + + Gtk::MenuItem* mi = Gtk::manage (new Gtk::MenuItem (*currLabel)); + + if (currLabel->entry->type == PSET_FOLDER) { + // creating the new sub-menu + Gtk::Menu* subMenu = Gtk::manage (new Gtk::Menu ()); + + // add it to the menu list + subMenuList[currLabel->entry->folderId] = subMenu; + + // add it to the parent MenuItem + mi->set_submenu(*subMenu); + } + // Hombre: ... does parentMenuId sounds like a hack? ... yes. + int parentMenuId = !options.useBundledProfiles && currLabel->entry->parentFolderId==1 ? 0 : currLabel->entry->parentFolderId; + subMenuList[parentMenuId]->attach (*mi, 0, 1, p, p+1); p++; + if (currLabel->entry->type == PSET_FILE) + mi->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::applyPartialMenuItemActivated), currLabel)); + mi->show (); + } + + if (subMenuList.size() && applypartprof) + // TODO: Check that the previous one has been deleted, including all childrens + applypartprof->set_submenu (*(subMenuList.at(0))); + + profileStore.releaseFileList(); + subMenuList.clear(); +} + +void FileBrowser::openRequested( std::vector mselected) { + std::vector entries; + // in Single Editor Mode open only last selected image + size_t openStart = options.tabbedUI ? 0 : ( mselected.size() > 0 ? mselected.size()-1 : 0); + for (size_t i=openStart; ithumbnail); + tbl->openRequested (entries); +} diff --git a/rtgui/filebrowser.h b/rtgui/filebrowser.h new file mode 100644 index 000000000..5ae501fa1 --- /dev/null +++ b/rtgui/filebrowser.h @@ -0,0 +1,197 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _FILEBROWSER_ +#define _FILEBROWSER_ + +#include +#include +#include "thumbbrowserbase.h" +#include "exiffiltersettings.h" +#include "filebrowserentry.h" +#include "browserfilter.h" +#include "pparamschangelistener.h" +#include "partialpastedlg.h" +#include "exportpanel.h" +#include "extprog.h" +#include "profilestore.h" + +class ProfileStoreLabel; +class FileBrowser; +class FileBrowserEntry; +class FileBrowserListener { + + public: + virtual ~FileBrowserListener () {} + virtual void filterApplied () {} + virtual void openRequested (std::vector tbe) {} + virtual void developRequested (std::vector tbe, bool fastmode) {} + virtual void renameRequested (std::vector tbe) {} + virtual void deleteRequested (std::vector tbe, bool inclBatchProcessed) {} + virtual void copyMoveRequested (std::vector tbe, bool moveRequested) {} + virtual void selectionChanged (std::vector tbe) {} + virtual void clearFromCacheRequested(std::vector tbe, bool leavenotrace) {} + virtual bool isInTabMode () { return false; } +}; + +struct FileBrowserIdleHelper { + FileBrowser* fbrowser; + bool destroyed; + int pending; +}; + +/* + * Class handling actions common to all thumbnails of the file browser + */ +class FileBrowser : public ThumbBrowserBase, + public LWButtonListener, + public ExportPanelListener, + public ProfileStoreListener { + + typedef sigc::signal type_trash_changed; + + protected: + + Gtk::MenuItem* rank[6]; + Gtk::ImageMenuItem* colorlabel[6]; + Gtk::MenuItem* trash; + Gtk::MenuItem* untrash; + Gtk::ImageMenuItem* develop; + Gtk::ImageMenuItem* developfast; + Gtk::MenuItem* rename; + Gtk::MenuItem* remove; + Gtk::MenuItem* removeInclProc; + Gtk::MenuItem* open; + Gtk::MenuItem* selall; + Gtk::MenuItem* copyTo; + Gtk::MenuItem* moveTo; + + Gtk::MenuItem* menuRank; + Gtk::MenuItem* menuLabel; + Gtk::MenuItem* menuFileOperations; + Gtk::ImageMenuItem* menuProfileOperations; + Gtk::MenuItem* menuExtProg; + Gtk::MenuItem** amiExtProg; + Gtk::MenuItem* miOpenDefaultViewer; + std::map mMenuExtProgs; // key is menuitem label + + Gtk::MenuItem* menuDF; + Gtk::MenuItem* selectDF; + Gtk::MenuItem* thisIsDF; + Gtk::MenuItem* autoDF; + + Gtk::MenuItem* menuFF; + Gtk::MenuItem* selectFF; + Gtk::MenuItem* thisIsFF; + Gtk::MenuItem* autoFF; + + Gtk::MenuItem* copyprof; + Gtk::MenuItem* pasteprof; + Gtk::MenuItem* partpasteprof; + Gtk::MenuItem* applyprof; + Gtk::MenuItem* applypartprof; + Gtk::MenuItem* execcustprof; + Gtk::MenuItem* clearprof; + Gtk::MenuItem* cachemenu; + Gtk::MenuItem* clearFromCache; + Gtk::MenuItem* clearFromCacheFull; + Gtk::Menu* pmenu; + + Gtk::ImageMenuItem* colorlabel_pop[6]; + Gtk::Menu* pmenuColorLabels; + void* colorLabel_actionData; + void menuColorlabelActivated (Gtk::MenuItem* m); // use only when menu is invoked via FileBrowser::buttonPressed to pass actionData + + Glib::RefPtr pmaccelgroup; + + BatchPParamsChangeListener* bppcl; + FileBrowserListener* tbl; + BrowserFilter filter; + int numFiltered; + PartialPasteDlg partialPasteDlg; + FileBrowserIdleHelper* fbih; + + void toTrashRequested (std::vector tbe); + void fromTrashRequested (std::vector tbe); + void rankingRequested (std::vector tbe, int rank); + void colorlabelRequested (std::vector tbe, int colorlabel); + void requestRanking (int rank); + void requestColorLabel(int colorlabel); + void notifySelectionListener (); + void openRequested( std::vector mselected); + ExportPanel* exportPanel; + + type_trash_changed m_trash_changed; + + public: + + FileBrowser (); + ~FileBrowser (); + + void addEntry (FileBrowserEntry* entry); // can be called from any thread + void addEntry_ (FileBrowserEntry* entry); // this must be executed inside the gtk thread + FileBrowserEntry* delEntry (const Glib::ustring& fname); // return the entry if found here return NULL otherwise + void close (); + + void setBatchPParamsChangeListener (BatchPParamsChangeListener* l) { bppcl = l; } + void setFileBrowserListener (FileBrowserListener* l) { tbl = l; } + + void menuItemActivated (Gtk::MenuItem* m); + void applyMenuItemActivated (ProfileStoreLabel *label); + void applyPartialMenuItemActivated (ProfileStoreLabel *label); + + void applyFilter (const BrowserFilter& filter); + int getNumFiltered(){ return numFiltered;} + + void buttonPressed (LWButton* button, int actionCode, void* actionData); + void redrawNeeded (LWButton* button); + bool checkFilter (ThumbBrowserEntryBase* entry); + void rightClicked (ThumbBrowserEntryBase* entry); + void doubleClicked (ThumbBrowserEntryBase* entry); + bool keyPressed (GdkEventKey* event); + + void saveThumbnailHeight (int height); + int getThumbnailHeight (); + + bool isInTabMode() { return tbl ? tbl->isInTabMode() : false; } + + void openNextImage (); + void openPrevImage (); + void copyProfile (); + void pasteProfile (); + void partPasteProfile (); + void selectImage (Glib::ustring fname); + void openNextPreviousEditorImage (Glib::ustring fname, eRTNav eNextPrevious); + + void openDefaultViewer (int destination); + + void thumbRearrangementNeeded (); + void _thumbRearrangementNeeded (); + + void selectionChanged (); + + void setExportPanel (ExportPanel* expanel); + // exportpanel interface + void exportRequested(); + + void updateProfileList (); + + type_trash_changed trash_changed(); +}; + +#endif diff --git a/rtgui/filebrowserentry.cc b/rtgui/filebrowserentry.cc new file mode 100644 index 000000000..33e948085 --- /dev/null +++ b/rtgui/filebrowserentry.cc @@ -0,0 +1,758 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "filebrowserentry.h" +#include "thumbbrowserbase.h" +#include "cursormanager.h" +#include +#include "guiutils.h" +#include "threadutils.h" +#include "../rtengine/safegtk.h" +#include "inspector.h" + +#include + +#define CROPRESIZEBORDER 4 + +bool FileBrowserEntry::iconsLoaded(false); +Glib::RefPtr FileBrowserEntry::editedIcon; +Glib::RefPtr FileBrowserEntry::recentlySavedIcon; +Glib::RefPtr FileBrowserEntry::enqueuedIcon; + +FileBrowserEntry::FileBrowserEntry (Thumbnail* thm, const Glib::ustring& fname) + : ThumbBrowserEntryBase (fname), wasInside(false), iatlistener(NULL), cropgl(NULL), state(SNormal) { + thumbnail=thm; + + feih = new FileBrowserEntryIdleHelper; + feih->fbentry = this; + feih->destroyed = false; + feih->pending = 0; + + italicstyle = thumbnail->getType() != FT_Raw; + datetimeline = thumbnail->getDateTimeString (); + exifline = thumbnail->getExifString (); + + scale = 1; + + if (!iconsLoaded) { + editedIcon = safe_create_from_file ("edited.png"); + recentlySavedIcon = safe_create_from_file ("recent-save.png"); + enqueuedIcon = safe_create_from_file ("processing.png"); + iconsLoaded = true; + } + + if (thm) + thm->addThumbnailListener (this); +} + +FileBrowserEntry::~FileBrowserEntry () { + + // so jobs arriving now do nothing + if (feih->pending) + { + feih->destroyed = true; + } + else + { + delete feih; + feih = 0; + } + + thumbImageUpdater->removeJobs (this); + if (thumbnail){ + thumbnail->removeThumbnailListener (this); + thumbnail->decreaseRef (); + } +} + +void FileBrowserEntry::refreshThumbnailImage () { + + if (!thumbnail) + return; + + thumbImageUpdater->add (this, &updatepriority, false, this); +} + +void FileBrowserEntry::refreshQuickThumbnailImage () { + + if (!thumbnail) + return; + + // Only make a (slow) processed preview if the picture has been edited at all + bool upgrade_to_processed = (!options.internalThumbIfUntouched || thumbnail->isPParamsValid()); + thumbImageUpdater->add(this, &updatepriority, upgrade_to_processed, this); +} + +void FileBrowserEntry::calcThumbnailSize () { + + if (thumbnail) + thumbnail->getThumbnailSize (prew, preh); +} + +std::vector > FileBrowserEntry::getIconsOnImageArea () { + + std::vector > ret; + + if (!thumbnail) + return ret; + + if (thumbnail->hasProcParams() && editedIcon) + ret.push_back (editedIcon); + if (thumbnail->isRecentlySaved() && recentlySavedIcon) + ret.push_back (recentlySavedIcon); + if (thumbnail->isEnqueued () && enqueuedIcon) + ret.push_back (enqueuedIcon); + + 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 + if (state==SCropSelecting || state==SResizeH1 || state==SResizeH2 || state==SResizeW1 || state==SResizeW2 || state==SResizeTL || state==SResizeTR || state==SResizeBL || state==SResizeBR || state==SCropMove) + drawCrop (c, prex, prey, prew, preh, 0, 0, scale, cropParams, true, false); + else { + rtengine::procparams::CropParams cparams = thumbnail->getProcParams().crop; + if (cparams.enabled && !thumbnail->isQuick()) // Quick thumb have arbitrary sizes, so don't apply the crop + drawCrop (c, prex, prey, prew, preh, 0, 0, scale, cparams, true, false); + } + } +} + +void FileBrowserEntry::getIconSize (int& w, int& h) { + + w = editedIcon->get_width (); + h = editedIcon->get_height (); +} + +FileThumbnailButtonSet* FileBrowserEntry::getThumbButtonSet () { + + return (static_cast(buttonSet)); +} + +void FileBrowserEntry::procParamsChanged (Thumbnail* thm, int whoChangedIt) { + + if ( thumbnail->isQuick() ) + { + refreshQuickThumbnailImage (); + } + else + { + refreshThumbnailImage (); + } +} + +struct tiupdate { + FileBrowserEntryIdleHelper* feih; + rtengine::IImage8* img; + double scale; + rtengine::procparams::CropParams cropParams; +}; + +int updateImageUI (void* data) { + + tiupdate* params = static_cast(data); + FileBrowserEntryIdleHelper* feih = params->feih; + + if (feih->destroyed) { + if (feih->pending == 1) + delete feih; + else + feih->pending--; + params->img->free (); + delete params; + return 0; + } + + feih->fbentry->_updateImage (params->img, params->scale, params->cropParams); + feih->pending--; + + delete params; + + return 0; +} + +void FileBrowserEntry::updateImage (rtengine::IImage8* img, double scale, rtengine::procparams::CropParams cropParams) { + + { + GThreadLock lock; + + if ( feih == 0 || + feih->destroyed ) + { + img->free(); + return; + } + + redrawRequests++; + feih->pending++; + } + + tiupdate* param = new tiupdate (); + param->feih = feih; + param->img = img; + param->scale = scale; + param->cropParams = cropParams; +#if __GNUC__ == 4 && __GNUC_MINOR__ == 8 && defined( WIN32 ) && defined(__x86_64__) + g_idle_add_full (G_PRIORITY_DEFAULT, updateImageUI, param, NULL); +#else + g_idle_add_full (G_PRIORITY_LOW, updateImageUI, param, NULL); +#endif +} + +void FileBrowserEntry::_updateImage (rtengine::IImage8* img, double s, rtengine::procparams::CropParams cropParams) { + + #if PROTECT_VECTORS + MYWRITERLOCK(l, lockRW); + #endif + + redrawRequests--; + scale = s; + this->cropParams = cropParams; + + bool newLandscape = img->getWidth() > img->getHeight(); + bool rotated=false; + + if (preh == img->getHeight ()) { + prew = img->getWidth (); + + GThreadLock lock; + + // Check if image has been rotated since last time + rotated = preview!=NULL && newLandscape!=landscape; + + guint8* temp = preview; + preview = NULL; + delete [] temp; + temp = new guint8 [prew*preh*3]; + memcpy (temp, img->getData(), prew*preh*3); + preview = temp; + updateBackBuffer (); + } + + landscape = newLandscape; + + img->free (); + + if (parent!=NULL) { + if (rotated) + parent->thumbRearrangementNeeded(); + else if (redrawRequests==0) + parent->redrawNeeded (this); + } +} + +bool FileBrowserEntry::motionNotify (int x, int y) { + + bool b = ThumbBrowserEntryBase::motionNotify (x, y); + + int ix = x - startx - ofsX; + int iy = y - starty - ofsY; + + Inspector* inspector = parent->getInspector(); + if (inspector && inspector->isActive() && !parent->isInTabMode()) { + rtengine::Coord2D coord(-1.,-1.); + getPosInImgSpace(x, y, coord); + if (coord.x != -1.) { + if (!wasInside) { + inspector->switchImage(filename); + } + wasInside = true; + inspector->mouseMove(coord, 0); + } + else { + if (wasInside) { + wasInside = false; + rtengine::Coord2D coord(-1,-1); + } + } + } + + if (inside (x,y)) + updateCursor (ix, iy); + + if (state==SRotateSelecting) { + action_x = x; + action_y = y; + parent->redrawNeeded (this); + } + else if (state==SResizeH1 && cropgl) { + int oy = cropParams.y; + cropParams.y = action_y + (y-press_y) / scale; + cropParams.h += oy - cropParams.y; + cropgl->cropHeight1Resized (cropParams.x, cropParams.y, cropParams.w, cropParams.h); + updateBackBuffer (); + parent->redrawNeeded (this); + } + else if (state==SResizeH2 && cropgl) { + cropParams.h = action_y + (y-press_y) / scale; + cropgl->cropHeight2Resized (cropParams.x, cropParams.y, cropParams.w, cropParams.h); + updateBackBuffer (); + parent->redrawNeeded (this); + } + else if (state==SResizeW1 && cropgl) { + int ox = cropParams.x; + cropParams.x = action_x + (x-press_x) / scale; + cropParams.w += ox - cropParams.x; + cropgl->cropWidth1Resized (cropParams.x, cropParams.y, cropParams.w, cropParams.h); + updateBackBuffer (); + parent->redrawNeeded (this); + } + else if (state==SResizeW2 && cropgl) { + cropParams.w = action_x + (x-press_x) / scale; + cropgl->cropWidth2Resized (cropParams.x, cropParams.y, cropParams.w, cropParams.h); + updateBackBuffer (); + parent->redrawNeeded (this); + } + else if (state==SResizeTL && cropgl) { + int ox = cropParams.x; + cropParams.x = action_x + (x-press_x) / scale; + cropParams.w += ox - cropParams.x; + int oy = cropParams.y; + cropParams.y = action_y + (y-press_y) / scale; + cropParams.h += oy - cropParams.y; + cropgl->cropTopLeftResized (cropParams.x, cropParams.y, cropParams.w, cropParams.h); + updateBackBuffer (); + parent->redrawNeeded (this); + } + else if (state==SResizeTR && cropgl) { + cropParams.w = action_x + (x-press_x) / scale; + int oy = cropParams.y; + cropParams.y = action_y + (y-press_y) / scale; + cropParams.h += oy - cropParams.y; + cropgl->cropTopRightResized (cropParams.x, cropParams.y, cropParams.w, cropParams.h); + updateBackBuffer (); + parent->redrawNeeded (this); + } + else if (state==SResizeBL && cropgl) { + int ox = cropParams.x; + cropParams.x = action_x + (x-press_x) / scale; + cropParams.w += ox - cropParams.x; + cropParams.h = action_y + (y-press_y) / scale; + cropgl->cropBottomLeftResized (cropParams.x, cropParams.y, cropParams.w, cropParams.h); + updateBackBuffer (); + parent->redrawNeeded (this); + } + else if (state==SResizeBR && cropgl) { + cropParams.w = action_x + (x-press_x) / scale; + cropParams.h = action_y + (y-press_y) / scale; + cropgl->cropBottomRightResized (cropParams.x, cropParams.y, cropParams.w, cropParams.h); + updateBackBuffer (); + parent->redrawNeeded (this); + } + else if (state==SCropMove && cropgl) { + cropParams.x = action_x + (x-press_x) / scale; + cropParams.y = action_y + (y-press_y) / scale; + cropgl->cropMoved (cropParams.x, cropParams.y, cropParams.w, cropParams.h); + updateBackBuffer (); + parent->redrawNeeded (this); + } + else if (state==SCropSelecting && cropgl) { + int cx1 = press_x, cy1 = press_y; + int cx2 = (ix-prex) / scale, cy2 = (iy-prey) / scale; + cropgl->cropResized (cx1, cy1, cx2, cy2); + if (cx2 > cx1) { + cropParams.x = cx1; + cropParams.w = cx2 - cx1 + 1; + } + else { + cropParams.x = cx2; + cropParams.w = cx1 - cx2 + 1; + } + if (cy2 > cy1) { + cropParams.y = cy1; + cropParams.h = cy2 - cy1 + 1; + } + else { + cropParams.y = cy2; + cropParams.h = cy1 - cy2 + 1; + } + updateBackBuffer (); + parent->redrawNeeded (this); + } + + return b; +} + +bool FileBrowserEntry::pressNotify (int button, int type, int bstate, int x, int y) { + + bool b = ThumbBrowserEntryBase::pressNotify (button, type, bstate, x, y); + + if (!iatlistener || !iatlistener->getToolBar()) + return true; + + ToolMode tm = iatlistener->getToolBar()->getTool (); + int ix = x - startx - ofsX; + int iy = y - starty - ofsY; + if (!b && selected && inside (x,y)) { + if (button==1 && type==GDK_BUTTON_PRESS && state==SNormal) { + if (onArea (CropTopLeft, ix, iy)) { + state = SResizeTL; + press_x = x; + action_x = cropParams.x; + press_y = y; + action_y = cropParams.y; + cropgl = iatlistener->startCropEditing (thumbnail); + b = true; + } + else if (onArea (CropTopRight, ix, iy)) { + state = SResizeTR; + press_x = x; + action_x = cropParams.w; + press_y = y; + action_y = cropParams.y; + cropgl = iatlistener->startCropEditing (thumbnail); + b = true; + } + else if (onArea (CropBottomLeft, ix, iy)) { + state = SResizeBL; + press_x = x; + action_x = cropParams.x; + press_y = y; + action_y = cropParams.h; + cropgl = iatlistener->startCropEditing (thumbnail); + b = true; + } + else if (onArea (CropBottomRight, ix, iy)) { + state = SResizeBR; + press_x = x; + action_x = cropParams.w; + press_y = y; + action_y = cropParams.h; + cropgl = iatlistener->startCropEditing (thumbnail); + b = true; + } + else if (onArea (CropTop, ix, iy)) { + state = SResizeH1; + press_y = y; + action_y = cropParams.y; + cropgl = iatlistener->startCropEditing (thumbnail); + b = true; + } + else if (onArea (CropBottom, ix, iy)) { + state = SResizeH2; + press_y = y; + action_y = cropParams.h; + cropgl = iatlistener->startCropEditing (thumbnail); + b = true; + } + else if (onArea (CropLeft, ix, iy)) { + state = SResizeW1; + press_x = x; + action_x = cropParams.x; + cropgl = iatlistener->startCropEditing (thumbnail); + b = true; + } + else if (onArea (CropRight, ix, iy)) { + state = SResizeW2; + press_x = x; + action_x = cropParams.w; + cropgl = iatlistener->startCropEditing (thumbnail); + b = true; + } + else if ((bstate & GDK_SHIFT_MASK) && onArea (CropInside, ix, iy)) { + state = SCropMove; + press_x = x; + press_y = y; + action_x = cropParams.x; + action_y = cropParams.y; + cropgl = iatlistener->startCropEditing (thumbnail); + b = true; + } + else if (onArea (CropImage, ix, iy)) { + if (tm == TMStraighten) { + state = SRotateSelecting; + press_x = x; + press_y = y; + action_x = x; + action_y = y; + rot_deg = 0; + b = true; + } + else if (tm == TMSpotWB) { + iatlistener->spotWBselected ((ix-prex)/scale, (iy-prey)/scale, thumbnail); + b = true; + } + else if (tm == TMCropSelect) { + cropgl = iatlistener->startCropEditing (thumbnail); + if (cropgl) { + state = SCropSelecting; + press_x = cropParams.x = (ix-prex) / scale; + press_y = cropParams.y = (iy-prey) / scale; + cropParams.w = cropParams.h = 1; + cropgl->cropInit (cropParams.x, cropParams.y, cropParams.w, cropParams.h); + b = true; + } + } + } + } + updateCursor (ix, iy); + } + return b; +} + +bool FileBrowserEntry::releaseNotify (int button, int type, int bstate, int x, int y) { + + bool b = ThumbBrowserEntryBase::releaseNotify (button, type, bstate, x, y); + + int ix = x - startx - ofsX; + int iy = y - starty - ofsY; + if (!b) { + if (state==SRotateSelecting) { + iatlistener->rotateSelectionReady (rot_deg, thumbnail); + if (iatlistener->getToolBar()) iatlistener->getToolBar()->setTool (TMHand); + } + else if (cropgl && (state==SCropSelecting || state==SResizeH1 || state==SResizeH2 || state==SResizeW1 || state==SResizeW2 || state==SResizeTL || state==SResizeTR || state==SResizeBL || state==SResizeBR || state==SCropMove)) { + cropgl->cropManipReady (); + cropgl = NULL; + iatlistener->cropSelectionReady (); + if (iatlistener->getToolBar()) iatlistener->getToolBar()->setTool (TMHand); + } + state = SNormal; + if (parent) + parent->redrawNeeded (this); + updateCursor (ix, iy); + } + + return b; +} + +bool FileBrowserEntry::onArea (CursorArea a, int x, int y) { + + if (!drawable || !preview) + return false; + + int x1 = (x-prex) / scale; + int y1 = (y-prey) / scale; + int cropResizeBorder = CROPRESIZEBORDER / scale; + switch (a) { + case CropImage: + return x>=prex && x=prey && y=cropParams.y-cropResizeBorder && + y1<=cropParams.y+cropResizeBorder && + x1>=cropParams.x-cropResizeBorder && + x1<=cropParams.x+cropResizeBorder; + case CropTopRight: + return cropParams.enabled && + y1>=cropParams.y-cropResizeBorder && + y1<=cropParams.y+cropResizeBorder && + x1>=cropParams.x+cropParams.w-1-cropResizeBorder && + x1<=cropParams.x+cropParams.w-1+cropResizeBorder; + case CropBottomLeft: + return cropParams.enabled && + y1>=cropParams.y+cropParams.h-1-cropResizeBorder && + y1<=cropParams.y+cropParams.h-1+cropResizeBorder && + x1>=cropParams.x-cropResizeBorder && + x1<=cropParams.x+cropResizeBorder; + case CropBottomRight: + return cropParams.enabled && + y1>=cropParams.y+cropParams.h-1-cropResizeBorder && + y1<=cropParams.y+cropParams.h-1+cropResizeBorder && + x1>=cropParams.x+cropParams.w-1-cropResizeBorder && + x1<=cropParams.x+cropParams.w-1+cropResizeBorder; + case CropTop: + return cropParams.enabled && + x1>cropParams.x+cropResizeBorder && + x1cropParams.y-cropResizeBorder && + y1cropParams.x+cropResizeBorder && + x1cropParams.y+cropParams.h-1-cropResizeBorder && + y1cropParams.y+cropResizeBorder && + y1cropParams.x-cropResizeBorder && + x1cropParams.y+cropResizeBorder && + y1cropParams.x+cropParams.w-1-cropResizeBorder && + x1cropParams.y && + y1cropParams.x && + x1getToolBar()) + return; + + ToolMode tm = iatlistener->getToolBar()->getTool (); + Glib::RefPtr w = parent->getDrawingArea ()->get_window(); + + if (!selected) { + cursorManager.setCursor (w, CSArrow); + return; + } + + if (state==SNormal) { + if (tm==TMHand && (onArea (CropTop, x, y) || onArea (CropBottom, x, y))) + cursorManager.setCursor (w, CSResizeHeight); + else if (tm==TMHand && (onArea (CropLeft, x, y) || onArea (CropRight, x, y))) + cursorManager.setCursor (w, CSResizeWidth); + else if (tm==TMHand && (onArea (CropTopLeft, x, y))) + cursorManager.setCursor (w, CSResizeTopLeft); + else if (tm==TMHand && (onArea (CropTopRight, x, y))) + cursorManager.setCursor (w, CSResizeTopRight); + else if (tm==TMHand && (onArea (CropBottomLeft, x, y))) + cursorManager.setCursor (w, CSResizeBottomLeft); + else if (tm==TMHand && (onArea (CropBottomRight, x, y))) + cursorManager.setCursor (w, CSResizeBottomRight); + else if (onArea (CropImage, x, y)) { + if (tm==TMHand) + cursorManager.setCursor (w, CSArrow); + else if (tm==TMSpotWB) + cursorManager.setCursor (w, CSSpotWB); + else if (tm==TMCropSelect) + cursorManager.setCursor (w, CSCropSelect); + else if (tm==TMStraighten) + cursorManager.setCursor (w, CSStraighten); + } + else + cursorManager.setCursor (w, CSArrow); + } + else if (state==SCropSelecting) + cursorManager.setCursor (w, CSCropSelect); + else if (state==SRotateSelecting) + cursorManager.setCursor (w, CSStraighten); + else if (state==SCropMove) + cursorManager.setCursor (w, CSMove); + else if (state==SResizeW1 || state==SResizeW2) + cursorManager.setCursor (w, CSResizeWidth); + else if (state==SResizeH1 || state==SResizeH2) + cursorManager.setCursor (w, CSResizeHeight); + else if (state==SResizeTL) + cursorManager.setCursor (w, CSResizeTopLeft); + else if (state==SResizeTR) + cursorManager.setCursor (w, CSResizeTopRight); + else if (state==SResizeBL) + cursorManager.setCursor (w, CSResizeBottomLeft); + else if (state==SResizeBR) + cursorManager.setCursor (w, CSResizeBottomRight); +} + +void FileBrowserEntry::draw () { + + ThumbBrowserEntryBase::draw (); + if (state==SRotateSelecting) { + Cairo::RefPtr cr = parent->getDrawingArea ()->get_window()->create_cairo_context(); + drawStraightenGuide (cr); + } +} + +void FileBrowserEntry::drawStraightenGuide (Cairo::RefPtr cr) { + + if (action_x!=press_x || action_y!=press_y) { + double arg = (press_x-action_x) / sqrt(double((press_x-action_x)*(press_x-action_x)+(press_y-action_y)*(press_y-action_y))); + double sol1, sol2; + double pi = M_PI; + if (press_y>action_y) { + sol1 = acos(arg)*180/pi; + sol2 = -acos(-arg)*180/pi; + } + else { + sol1 = acos(-arg)*180/pi; + sol2 = -acos(arg)*180/pi; + } + if (fabs(sol1)45) + rot_deg = - 90.0 + rot_deg; + } + else + rot_deg = 0; + + Glib::RefPtr context = parent->getDrawingArea()->get_pango_context () ; + Pango::FontDescription fontd = context->get_font_description (); + fontd.set_weight (Pango::WEIGHT_BOLD); + fontd.set_size (8*Pango::SCALE); + context->set_font_description (fontd); + Glib::RefPtr deglayout = parent->getDrawingArea()->create_pango_layout(Glib::ustring::compose ("%1 deg", Glib::ustring::format(std::setprecision(2), rot_deg))); + + int x1 = press_x; + int y1 = press_y; + int y2 = action_y; + int x2 = action_x; + + if (x2=prew+prex+ofsX+startx) { + y2 = y1 - (double)(y1-y2)*(x1 - (prew+prex+ofsX+startx-1)) / (x1-x2); + x2 = prew+prex+ofsX+startx-1; + } + if (y2=preh+prey+ofsY+starty) { + x2 = x1 - (double)(x1-x2)*(y1 - (preh+prey+ofsY+starty-1)) / (y1-y2); + y2 = preh+prey+ofsY+starty-1; + } + + cr->set_line_width (1.5); + cr->set_source_rgb (1.0, 1.0, 1.0); + cr->move_to (x1, y1); + cr->line_to (x2, y2); + cr->stroke (); + cr->set_source_rgb (0.0, 0.0, 0.0); + std::valarray ds (1); + ds[0] = 4; + cr->set_dash (ds, 0); + cr->move_to (x1, y1); + cr->line_to (x2, y2); + cr->stroke (); + + if (press_x!=action_x && press_y!=action_y) { + cr->set_source_rgb (0.0, 0.0, 0.0); + cr->move_to ((x1+x2)/2+1, (y1+y2)/2+1); + deglayout->add_to_cairo_context (cr); + cr->move_to ((x1+x2)/2+1, (y1+y2)/2-1); + deglayout->add_to_cairo_context (cr); + cr->move_to ((x1+x2)/2-1, (y1+y2)/2+1); + deglayout->add_to_cairo_context (cr); + cr->move_to ((x1+x2)/2+1, (y1+y2)/2+1); + deglayout->add_to_cairo_context (cr); + cr->fill (); + cr->set_source_rgb (1.0, 1.0, 1.0); + cr->move_to ((x1+x2)/2, (y1+y2)/2); + deglayout->add_to_cairo_context (cr); + cr->fill (); + } +} + diff --git a/rtgui/filebrowserentry.h b/rtgui/filebrowserentry.h new file mode 100644 index 000000000..bc52273a0 --- /dev/null +++ b/rtgui/filebrowserentry.h @@ -0,0 +1,96 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _FILEBROWSERENTRY_ +#define _FILEBROWSERENTRY_ + +#include +#include "thumbbrowserentrybase.h" +#include "thumbnail.h" +#include "filethumbnailbuttonset.h" +#include "thumbnaillistener.h" +#include "thumbimageupdater.h" +#include "imageareatoollistener.h" +#include "editenums.h" +#include "../rtengine/rtengine.h" +#include "crophandler.h" + + +class FileBrowserEntry; +struct FileBrowserEntryIdleHelper { + FileBrowserEntry* fbentry; + bool destroyed; + int pending; +}; + +class FileThumbnailButtonSet; +class FileBrowserEntry : public ThumbBrowserEntryBase, + public ThumbnailListener, + public ThumbImageUpdateListener { + + double scale; + static bool iconsLoaded; + bool wasInside; + ImageAreaToolListener* iatlistener; + int press_x, press_y, action_x, action_y; + double rot_deg; + bool landscape; + rtengine::procparams::CropParams cropParams; + CropGUIListener* cropgl; + FileBrowserEntryIdleHelper* feih; + + ImgEditState state; + + bool onArea (CursorArea a, int x, int y); + void updateCursor (int x, int y); + void drawStraightenGuide (Cairo::RefPtr c); + void customBackBufferUpdate (Cairo::RefPtr c); + +public: + + static Glib::RefPtr editedIcon; + static Glib::RefPtr recentlySavedIcon; + static Glib::RefPtr enqueuedIcon; + + FileBrowserEntry (Thumbnail* thm, const Glib::ustring& fname); + ~FileBrowserEntry (); + void draw (); + + void setImageAreaToolListener (ImageAreaToolListener* l) { iatlistener = l; } + + FileThumbnailButtonSet* getThumbButtonSet (); + + void refreshThumbnailImage (); + void refreshQuickThumbnailImage (); + void calcThumbnailSize (); + + virtual std::vector > getIconsOnImageArea (); + virtual void getIconSize (int& w, int& h); + + // thumbnaillistener interface + void procParamsChanged (Thumbnail* thm, int whoChangedIt); + // thumbimageupdatelistener interface + void updateImage (rtengine::IImage8* img, double scale, rtengine::procparams::CropParams cropParams); + void _updateImage (rtengine::IImage8* img, double scale, rtengine::procparams::CropParams cropParams); // inside gtk thread + + virtual bool motionNotify (int x, int y); + virtual bool pressNotify (int button, int type, int bstate, int x, int y); + virtual bool releaseNotify (int button, int type, int bstate, int x, int y); +}; + +#endif diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc new file mode 100644 index 000000000..188f14658 --- /dev/null +++ b/rtgui/filecatalog.cc @@ -0,0 +1,2100 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * Copyright (c) 2011 Michael Ezra + * + * 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 +#include "../rtengine/rt_math.h" + +#include "filecatalog.h" +#include "filepanel.h" +#include "options.h" +#include "cachemanager.h" +#include "multilangmgr.h" +#include "guiutils.h" +#include "renamedlg.h" +#include "thumbimageupdater.h" +#include "../rtengine/safegtk.h" +#include "batchqueue.h" +#include "rtimage.h" + +using namespace std; + +#define CHECKTIME 2000 + +FileCatalog::FileCatalog (CoarsePanel* cp, ToolBar* tb, FilePanel* filepanel) : + filepanel(filepanel), + selectedDirectoryId(1), + listener(NULL), + fslistener(NULL), + dirlistener(NULL), + hasValidCurrentEFS(false), + filterPanel(NULL), + previewsToLoad(0), + previewsLoaded(0), + coarsePanel(cp), + toolBar(tb) + { + + inTabMode=false; + + // construct and initialize thumbnail browsers + fileBrowser = Gtk::manage( new FileBrowser() ); + fileBrowser->setFileBrowserListener (this); + fileBrowser->setArrangement (ThumbBrowserBase::TB_Vertical); + fileBrowser->show (); + + set_size_request(0,250); + // construct trash panel with the extra "empty trash" button + trashButtonBox = Gtk::manage( new Gtk::VBox ); + Gtk::Button* emptyT = Gtk::manage( new Gtk::Button (M("FILEBROWSER_EMPTYTRASH"))); + emptyT->set_tooltip_markup (M("FILEBROWSER_EMPTYTRASHHINT")); + emptyT->set_image (*Gtk::manage(new RTImage ("trash.png"))); + emptyT->signal_pressed().connect (sigc::mem_fun(*this, &FileCatalog::emptyTrash)); + trashButtonBox->pack_start (*emptyT, Gtk::PACK_SHRINK, 4); + emptyT->show (); + trashButtonBox->show (); + + //initialize hbToolBar1 + hbToolBar1 = Gtk::manage(new Gtk::HBox ()); + + //setup BrowsePath + iRefreshWhite = new RTImage("refresh-white.png"); + iRefreshRed = new RTImage("refresh-red.png"); + + BrowsePath = Gtk::manage(new Gtk::Entry ()); + BrowsePath->set_width_chars (50); + BrowsePath->set_tooltip_markup (M("FILEBROWSER_BROWSEPATHHINT")); + Gtk::HBox* hbBrowsePath = Gtk::manage(new Gtk::HBox ()); + buttonBrowsePath = Gtk::manage(new Gtk::Button ()); + buttonBrowsePath->set_image (*iRefreshWhite); + buttonBrowsePath->set_tooltip_markup (M("FILEBROWSER_BROWSEPATHBUTTONHINT")); + buttonBrowsePath->set_relief (Gtk::RELIEF_NONE); + buttonBrowsePath->signal_clicked().connect( sigc::mem_fun(*this, &FileCatalog::buttonBrowsePathPressed) ); + hbBrowsePath->pack_start (*BrowsePath, Gtk::PACK_EXPAND_WIDGET,0); + hbBrowsePath->pack_start (*buttonBrowsePath,Gtk::PACK_SHRINK, 0); + hbToolBar1->pack_start (*hbBrowsePath, Gtk::PACK_EXPAND_WIDGET,0); + + BrowsePath->signal_activate().connect (sigc::mem_fun(*this, &FileCatalog::buttonBrowsePathPressed)); //respond to the Enter key + BrowsePath->signal_key_press_event().connect(sigc::mem_fun(*this, &FileCatalog::BrowsePath_key_pressed)); + + //setup Query + iQueryClear = new RTImage("gtk-close-small.png"); + Gtk::Label* labelQuery = Gtk::manage(new Gtk::Label(M("FILEBROWSER_QUERYLABEL"))); + Query = Gtk::manage(new Gtk::Entry ()); // cannot use Gtk::manage here as FileCatalog::getFilter will fail on Query->get_text() + Query->set_text(""); + Query->set_width_chars (20); // TODO !!! add this value to options? + Query->set_tooltip_markup (M("FILEBROWSER_QUERYHINT")); + Gtk::HBox* hbQuery = Gtk::manage(new Gtk::HBox ()); + buttonQueryClear = Gtk::manage(new Gtk::Button ()); + buttonQueryClear->set_image (*iQueryClear); + buttonQueryClear->set_tooltip_markup (M("FILEBROWSER_QUERYBUTTONHINT")); + buttonQueryClear->set_relief (Gtk::RELIEF_NONE); + buttonQueryClear->signal_clicked().connect( sigc::mem_fun(*this, &FileCatalog::buttonQueryClearPressed) ); + hbQuery->pack_start (*labelQuery,Gtk::PACK_SHRINK, 0); + hbQuery->pack_start (*Query,Gtk::PACK_SHRINK, 0); + hbQuery->pack_start (*buttonQueryClear,Gtk::PACK_SHRINK, 0); + hbToolBar1->pack_start (*hbQuery, Gtk::PACK_SHRINK,0); + + Query->signal_activate().connect (sigc::mem_fun(*this, &FileCatalog::executeQuery)); //respond to the Enter key + Query->signal_key_press_event().connect(sigc::mem_fun(*this, &FileCatalog::Query_key_pressed)); + + // if NOT a single row toolbar + if (!options.FileBrowserToolbarSingleRow) pack_start (*hbToolBar1, Gtk::PACK_SHRINK,0); + + // setup button bar + buttonBar = Gtk::manage( new Gtk::HBox () ); + pack_start (*buttonBar, Gtk::PACK_SHRINK); + + buttonBar->pack_start (*Gtk::manage(new Gtk::VSeparator), Gtk::PACK_SHRINK); + + tbLeftPanel_1 = new Gtk::ToggleButton (); + iLeftPanel_1_Show = new RTImage("panel-to-right.png"); + iLeftPanel_1_Hide = new RTImage("panel-to-left.png"); + + tbLeftPanel_1->set_relief(Gtk::RELIEF_NONE); + tbLeftPanel_1->set_active (true); + tbLeftPanel_1->set_tooltip_markup (M("MAIN_TOOLTIP_SHOWHIDELP1")); + tbLeftPanel_1->set_image (*iLeftPanel_1_Hide); + tbLeftPanel_1->signal_toggled().connect( sigc::mem_fun(*this, &FileCatalog::tbLeftPanel_1_toggled) ); + buttonBar->pack_start (*tbLeftPanel_1, Gtk::PACK_SHRINK); + + buttonBar->pack_start (*(new Gtk::VSeparator), Gtk::PACK_SHRINK); + + + iFilterClear = new RTImage ("filterclear.png"); + igFilterClear = new RTImage ("filter.png"); + bFilterClear = Gtk::manage(new Gtk::ToggleButton ()); + bFilterClear->set_active (true); + bFilterClear->set_image(*iFilterClear);// (*Gtk::manage(new RTImage ("filterclear.png"))); + bFilterClear->set_relief (Gtk::RELIEF_NONE); + bFilterClear->set_tooltip_markup (M("FILEBROWSER_SHOWDIRHINT")); + bFilterClear->signal_button_press_event().connect (sigc::mem_fun(*this, &FileCatalog::capture_event),false); + bCateg[0] = bFilterClear->signal_toggled().connect (sigc::bind(sigc::mem_fun(*this, &FileCatalog::categoryButtonToggled), bFilterClear, true)); + buttonBar->pack_start (*bFilterClear, Gtk::PACK_SHRINK); + buttonBar->pack_start (*Gtk::manage(new Gtk::VSeparator), Gtk::PACK_SHRINK); + + fltrVbox1 = Gtk::manage (new Gtk::VBox()); + fltrRankbox = Gtk::manage (new Gtk::HBox()); + fltrLabelbox = Gtk::manage (new Gtk::HBox()); + + iUnRanked = new RTImage ("ratednot.png"); + igUnRanked = new RTImage ("ratednotg.png"); + bUnRanked = Gtk::manage( new Gtk::ToggleButton () ); + bUnRanked->set_active (false); + bUnRanked->set_image (*igUnRanked); + bUnRanked->set_relief (Gtk::RELIEF_NONE); + bUnRanked->set_tooltip_markup (M("FILEBROWSER_SHOWUNRANKHINT")); + bCateg[1] = bUnRanked->signal_toggled().connect (sigc::bind(sigc::mem_fun(*this, &FileCatalog::categoryButtonToggled), bUnRanked, true)); + fltrRankbox->pack_start (*bUnRanked, Gtk::PACK_SHRINK); + bUnRanked->signal_button_press_event().connect (sigc::mem_fun(*this, &FileCatalog::capture_event),false); + + for (int i=0; i<5; i++) { + iranked[i] = new RTImage ("rated.png"); + igranked[i] = new RTImage ("grayrated.png"); + iranked[i]->show (); + igranked[i]->show (); + bRank[i] = Gtk::manage( new Gtk::ToggleButton () ); + bRank[i]->set_image (*igranked[i]); + bRank[i]->set_relief (Gtk::RELIEF_NONE); + fltrRankbox->pack_start (*bRank[i], Gtk::PACK_SHRINK); + bCateg[i+2] = bRank[i]->signal_toggled().connect (sigc::bind(sigc::mem_fun(*this, &FileCatalog::categoryButtonToggled), bRank[i], true)); + bRank[i]->signal_button_press_event().connect (sigc::mem_fun(*this, &FileCatalog::capture_event),false); + } + + iUnCLabeled = new RTImage ("clabel0.png"); + igUnCLabeled = new RTImage ("cglabel0.png"); + bUnCLabeled = Gtk::manage(new Gtk::ToggleButton ()); + bUnCLabeled->set_active (false); + bUnCLabeled->set_image (*igUnCLabeled); + bUnCLabeled->set_relief (Gtk::RELIEF_NONE); + bUnCLabeled->set_tooltip_markup (M("FILEBROWSER_SHOWUNCOLORHINT")); + bCateg[7] = bUnCLabeled->signal_toggled().connect (sigc::bind(sigc::mem_fun(*this, &FileCatalog::categoryButtonToggled), bUnCLabeled, true)); + fltrLabelbox->pack_start (*bUnCLabeled, Gtk::PACK_SHRINK); + bUnCLabeled->signal_button_press_event().connect (sigc::mem_fun(*this, &FileCatalog::capture_event),false); + + for (int i=0; i<5; i++) { + iCLabeled[i] = new RTImage (Glib::ustring::compose("%1%2%3","clabel",i+1,".png")); + igCLabeled[i] = new RTImage (Glib::ustring::compose("%1%2%3","cglabel",i+1,".png")); + iCLabeled[i]->show (); + igCLabeled[i]->show (); + bCLabel[i] = Gtk::manage(new Gtk::ToggleButton ()); + bCLabel[i]->set_image (*igCLabeled[i]); + bCLabel[i]->set_relief (Gtk::RELIEF_NONE); + fltrLabelbox->pack_start (*bCLabel[i], Gtk::PACK_SHRINK); + bCateg[i+8] = bCLabel[i]->signal_toggled().connect (sigc::bind(sigc::mem_fun(*this, &FileCatalog::categoryButtonToggled), bCLabel[i], true)); + bCLabel[i]->signal_button_press_event().connect (sigc::mem_fun(*this, &FileCatalog::capture_event),false); + } + + fltrVbox1->pack_start (*fltrRankbox, Gtk::PACK_SHRINK,0); + fltrVbox1->pack_start (*fltrLabelbox, Gtk::PACK_SHRINK,0); + buttonBar->pack_start (*fltrVbox1, Gtk::PACK_SHRINK); + + bRank[0]->set_tooltip_markup (M("FILEBROWSER_SHOWRANK1HINT")); + bRank[1]->set_tooltip_markup (M("FILEBROWSER_SHOWRANK2HINT")); + bRank[2]->set_tooltip_markup (M("FILEBROWSER_SHOWRANK3HINT")); + bRank[3]->set_tooltip_markup (M("FILEBROWSER_SHOWRANK4HINT")); + bRank[4]->set_tooltip_markup (M("FILEBROWSER_SHOWRANK5HINT")); + + bCLabel[0]->set_tooltip_markup (M("FILEBROWSER_SHOWCOLORLABEL1HINT")); + bCLabel[1]->set_tooltip_markup (M("FILEBROWSER_SHOWCOLORLABEL2HINT")); + bCLabel[2]->set_tooltip_markup (M("FILEBROWSER_SHOWCOLORLABEL3HINT")); + bCLabel[3]->set_tooltip_markup (M("FILEBROWSER_SHOWCOLORLABEL4HINT")); + bCLabel[4]->set_tooltip_markup (M("FILEBROWSER_SHOWCOLORLABEL5HINT")); + + buttonBar->pack_start (*Gtk::manage(new Gtk::VSeparator), Gtk::PACK_SHRINK); + + fltrVbox2 = Gtk::manage (new Gtk::VBox()); + fltrEditedBox = Gtk::manage (new Gtk::HBox()); + fltrRecentlySavedBox = Gtk::manage (new Gtk::HBox()); + + // bEdited + iEdited[0] = new RTImage ("editednot-small.png"); + igEdited[0] = new RTImage ("editednotg-small.png"); + iEdited[1] = new RTImage ("edited-small.png"); + igEdited[1] = new RTImage ("editedg-small.png"); + for (int i=0; i<2; i++) { + iEdited[i]->show (); + bEdited[i] = Gtk::manage(new Gtk::ToggleButton ()); + bEdited[i]->set_active (false); + bEdited[i]->set_image (*igEdited[i]); + bEdited[i]->set_relief (Gtk::RELIEF_NONE); + fltrEditedBox->pack_start (*bEdited[i], Gtk::PACK_SHRINK); + //13, 14 + bCateg[i+13] = bEdited[i]->signal_toggled().connect (sigc::bind(sigc::mem_fun(*this, &FileCatalog::categoryButtonToggled), bEdited[i], true)); + bEdited[i]->signal_button_press_event().connect (sigc::mem_fun(*this, &FileCatalog::capture_event),false); + } + bEdited[0]->set_tooltip_markup (M("FILEBROWSER_SHOWEDITEDNOTHINT")); + bEdited[1]->set_tooltip_markup (M("FILEBROWSER_SHOWEDITEDHINT")); + + // RecentlySaved + iRecentlySaved[0] = new RTImage ("savednot.png"); + igRecentlySaved[0] = new RTImage ("savednotg.png"); + iRecentlySaved[1] = new RTImage ("saved.png"); + igRecentlySaved[1] = new RTImage ("savedg.png"); + for (int i=0; i<2; i++) { + iRecentlySaved[i]->show (); + bRecentlySaved[i] = Gtk::manage(new Gtk::ToggleButton ()); + bRecentlySaved[i]->set_active (false); + bRecentlySaved[i]->set_image (*igRecentlySaved[i]); + bRecentlySaved[i]->set_relief (Gtk::RELIEF_NONE); + fltrRecentlySavedBox->pack_start (*bRecentlySaved[i], Gtk::PACK_SHRINK); + //15, 16 + bCateg[i+15] = bRecentlySaved[i]->signal_toggled().connect (sigc::bind(sigc::mem_fun(*this, &FileCatalog::categoryButtonToggled), bRecentlySaved[i], true)); + bRecentlySaved[i]->signal_button_press_event().connect (sigc::mem_fun(*this, &FileCatalog::capture_event),false); + } + bRecentlySaved[0]->set_tooltip_markup (M("FILEBROWSER_SHOWRECENTLYSAVEDNOTHINT")); + bRecentlySaved[1]->set_tooltip_markup (M("FILEBROWSER_SHOWRECENTLYSAVEDHINT")); + + fltrVbox2->pack_start (*fltrEditedBox, Gtk::PACK_SHRINK,0); + fltrVbox2->pack_start (*fltrRecentlySavedBox, Gtk::PACK_SHRINK,0); + buttonBar->pack_start (*fltrVbox2, Gtk::PACK_SHRINK); + + buttonBar->pack_start (*Gtk::manage(new Gtk::VSeparator), Gtk::PACK_SHRINK); + + // Trash + iTrashEmpty = new RTImage("trash-show-empty.png") ; + iTrashFull = new RTImage("trash-show-full.png") ; + + bTrash = Gtk::manage( new Gtk::ToggleButton () ); + bTrash->set_image (*iTrashEmpty); + bTrash->set_relief (Gtk::RELIEF_NONE); + bTrash->set_tooltip_markup (M("FILEBROWSER_SHOWTRASHHINT")); + bCateg[17] = bTrash->signal_toggled().connect (sigc::bind(sigc::mem_fun(*this, &FileCatalog::categoryButtonToggled), bTrash, true)); + bTrash->signal_button_press_event().connect (sigc::mem_fun(*this, &FileCatalog::capture_event),false); + + iNotTrash = new RTImage("trash-hide-deleted.png") ; + + bNotTrash = Gtk::manage( new Gtk::ToggleButton () ); + bNotTrash->set_image (*iNotTrash); + bNotTrash->set_relief (Gtk::RELIEF_NONE); + bNotTrash->set_tooltip_markup (M("FILEBROWSER_SHOWNOTTRASHHINT")); + bCateg[18] = bNotTrash->signal_toggled().connect (sigc::bind(sigc::mem_fun(*this, &FileCatalog::categoryButtonToggled), bNotTrash, true)); + bNotTrash->signal_button_press_event().connect (sigc::mem_fun(*this, &FileCatalog::capture_event),false); + + buttonBar->pack_start (*bTrash, Gtk::PACK_SHRINK); + buttonBar->pack_start (*bNotTrash, Gtk::PACK_SHRINK); + buttonBar->pack_start (*Gtk::manage(new Gtk::VSeparator), Gtk::PACK_SHRINK); + fileBrowser->trash_changed().connect( sigc::mem_fun(*this, &FileCatalog::trashChanged) ); + + // 0 - bFilterClear + // 1 - bUnRanked + // 2 - bRank[0] + // 3 - bRank[1] + // 4 - bRank[2] + // 5 - bRank[3] + // 6 - bRank[4] + // 7 - bUnCLabeled + // 8 - bCLabel[0] + // 9 - bCLabel[1] + // 10 - bCLabel[2] + // 11 - bCLabel[3] + // 12 - bCLabel[4] + // 13 - bEdited[0] + // 14 - bEdited[1] + // 15 - bRecentlySaved[0] + // 16 - bRecentlySaved[1] + // 17 - bTrash + // 18 - bNotTrash + + categoryButtons[0] = bFilterClear; + categoryButtons[1] = bUnRanked; + for (int i=0; i<5; i++){ categoryButtons[i+2] = bRank[i];} + categoryButtons[7] = bUnCLabeled; + for (int i=0; i<5; i++){ categoryButtons[i+8] = bCLabel[i];} + for (int i=0; i<2; i++){ categoryButtons[i+13] = bEdited[i];} + for (int i=0; i<2; i++){ categoryButtons[i+15] = bRecentlySaved[i];} + categoryButtons[17] = bTrash; + categoryButtons[18] = bNotTrash; + + exifInfo = Gtk::manage(new Gtk::ToggleButton ()); + exifInfo->set_image (*Gtk::manage(new RTImage ("info.png"))); + exifInfo->set_relief (Gtk::RELIEF_NONE); + exifInfo->set_tooltip_markup (M("FILEBROWSER_SHOWEXIFINFO")); + exifInfo->set_active( options.showFileNames ); + exifInfo->signal_toggled().connect(sigc::mem_fun(*this, &FileCatalog::exifInfoButtonToggled)); + buttonBar->pack_start (*exifInfo, Gtk::PACK_SHRINK); + + // thumbnail zoom + Gtk::HBox* zoomBox = Gtk::manage( new Gtk::HBox () ); + zoomInButton = Gtk::manage( new Gtk::Button () ); + zoomInButton->set_image (*Gtk::manage(new RTImage ("gtk-zoom-in.png"))); + zoomInButton->signal_pressed().connect (sigc::mem_fun(*this, &FileCatalog::zoomIn)); + zoomInButton->set_relief (Gtk::RELIEF_NONE); + zoomInButton->set_tooltip_markup (M("FILEBROWSER_ZOOMINHINT")); + zoomBox->pack_end (*zoomInButton, Gtk::PACK_SHRINK); + zoomOutButton = Gtk::manage( new Gtk::Button () ); + zoomOutButton->set_image (*Gtk::manage(new RTImage ("gtk-zoom-out.png"))); + zoomOutButton->signal_pressed().connect (sigc::mem_fun(*this, &FileCatalog::zoomOut)); + zoomOutButton->set_relief (Gtk::RELIEF_NONE); + zoomOutButton->set_tooltip_markup (M("FILEBROWSER_ZOOMOUTHINT")); + zoomBox->pack_end (*zoomOutButton, Gtk::PACK_SHRINK); + + buttonBar->pack_start (*zoomBox, Gtk::PACK_SHRINK); + buttonBar->pack_start (*Gtk::manage(new Gtk::VSeparator), Gtk::PACK_SHRINK); + + //iRightArrow = new RTImage("right.png"); + //iRightArrow_red = new RTImage("right_red.png"); + + // if it IS a single row toolbar + if (options.FileBrowserToolbarSingleRow) buttonBar->pack_start (*hbToolBar1, Gtk::PACK_EXPAND_WIDGET,0); + + tbRightPanel_1 = new Gtk::ToggleButton (); + iRightPanel_1_Show = new RTImage("panel-to-left.png"); + iRightPanel_1_Hide = new RTImage("panel-to-right.png"); + + tbRightPanel_1->set_relief(Gtk::RELIEF_NONE); + tbRightPanel_1->set_active (true); + tbRightPanel_1->set_tooltip_markup (M("MAIN_TOOLTIP_SHOWHIDERP1")); + tbRightPanel_1->set_image (*iRightPanel_1_Hide); + tbRightPanel_1->signal_toggled().connect( sigc::mem_fun(*this, &FileCatalog::tbRightPanel_1_toggled) ); + buttonBar->pack_end (*tbRightPanel_1, Gtk::PACK_SHRINK); + + buttonBar->pack_end (*coarsePanel, Gtk::PACK_SHRINK); + buttonBar->pack_end (*Gtk::manage(new Gtk::VSeparator), Gtk::PACK_SHRINK, 4); + buttonBar->pack_end (*toolBar, Gtk::PACK_SHRINK); + buttonBar->pack_end (*Gtk::manage(new Gtk::VSeparator), Gtk::PACK_SHRINK, 4); + + // add default panel + hBox = Gtk::manage( new Gtk::HBox () ); + hBox->show (); + hBox->pack_end (*fileBrowser); + fileBrowser->applyFilter (getFilter()); // warning: can call this only after all objects used in getFilter (e.g. Query) are instantiated + //printf("FileCatalog::FileCatalog fileBrowser->applyFilter (getFilter())\n"); + pack_start (*hBox); + + enabled = true; + + lastScrollPos = 0; + for (int i=0; i<18; i++) { + hScrollPos[i] = 0; + vScrollPos[i] = 0; + } + + selectedDirectory = ""; +#ifdef WIN32 + wdMonitor = NULL; +#endif +} + +FileCatalog::~FileCatalog(){ + for (int i=0; i<5; i++) { + delete iranked[i]; + delete igranked[i]; + delete iCLabeled[i]; + delete igCLabeled[i]; + } + for (int i=0; i<2; i++) { + delete iEdited[i]; + delete igEdited[i]; + delete iRecentlySaved[i]; + delete igRecentlySaved[i]; + } + delete iFilterClear; + delete igFilterClear; + delete iUnRanked; + delete igUnRanked; + delete iUnCLabeled; + delete igUnCLabeled; + delete iTrashEmpty; + delete iTrashFull; + delete iRefreshWhite; + delete iRefreshRed; + delete iQueryClear; + delete iLeftPanel_1_Show; + delete iLeftPanel_1_Hide; + delete iRightPanel_1_Show; + delete iRightPanel_1_Hide; +} + +bool FileCatalog::capture_event(GdkEventButton* event){ + // need to record modifiers on the button press, because signal_toggled does not pass the event. + modifierKey = event->state; + return false; +} + +void FileCatalog::exifInfoButtonToggled() +{ + if (inTabMode) + options.filmStripShowFileNames = exifInfo->get_active(); + else + options.showFileNames = exifInfo->get_active(); + fileBrowser->refreshThumbImages (); +} + +void FileCatalog::on_realize() { + + Gtk::VBox::on_realize(); + Pango::FontDescription fontd = get_pango_context()->get_font_description (); + fileBrowser->get_pango_context()->set_font_description (fontd); +// batchQueue->get_pango_context()->set_font_description (fontd); +} + +void FileCatalog::closeDir () { + + if (filterPanel) + filterPanel->set_sensitive (false); + + if (exportPanel) + exportPanel->set_sensitive (false); + +#ifndef WIN32 + if (dirMonitor) + dirMonitor->cancel (); +#else + if (wdMonitor) { + delete wdMonitor; + wdMonitor = NULL; + } +#endif + + // ignore old requests + ++selectedDirectoryId; + + // terminate thumbnail preview loading + previewLoader->removeAllJobs (); + + // terminate thumbnail updater + thumbImageUpdater->removeAllJobs (); + + // remove entries + selectedDirectory = ""; + fileBrowser->close (); + fileNameList.clear (); + + { + MyMutex::MyLock lock(dirEFSMutex); + dirEFS.clear (); + } + hasValidCurrentEFS = false; + redrawAll (); +} + +std::vector FileCatalog::getFileList () { + + std::vector names; + Glib::RefPtr dir = Gio::File::create_for_path (selectedDirectory); + safe_build_file_list (dir, names, selectedDirectory, &(options.parsedExtensions)); +// Issue 2406 std::sort (names.begin(), names.end()); + return names; +} + +void FileCatalog::dirSelected (const Glib::ustring& dirname, const Glib::ustring& openfile) { + + try { + Glib::RefPtr dir = Gio::File::create_for_path (dirname); + + if (!dir) + return; + closeDir (); + previewsToLoad = 0; + previewsLoaded = 0; + // if openfile exists, we have to open it first (it is a command line argument) + if (!openfile.empty()) + addAndOpenFile (openfile); + + selectedDirectory = dir->get_parse_name(); + //printf("FileCatalog::dirSelected selectedDirectory = %s\n",selectedDirectory.c_str()); + BrowsePath->set_text (selectedDirectory); + buttonBrowsePath->set_image (*iRefreshWhite); + fileNameList = getFileList (); + + for (unsigned int i=0; i f = Gio::File::create_for_path(fileNameList[i]); + if (f->get_parse_name() != openfile) // if we opened a file at the beginning don't add it again + checkAndAddFile (f); + } + + _refreshProgressBar (); + if (previewsToLoad == 0) { + filepanel->loadingThumbs(M("PROGRESSBAR_NOIMAGES"),0); + } else { + filepanel->loadingThumbs(M("PROGRESSBAR_LOADINGTHUMBS"),0); + } + +#ifdef WIN32 + wdMonitor = new WinDirMonitor (selectedDirectory, this); +#else + dirMonitor = dir->monitor_directory (); + dirMonitor->signal_changed().connect (sigc::bind(sigc::mem_fun(*this, &FileCatalog::on_dir_changed), false)); +#endif + } + catch (Glib::Exception& ex) { + std::cout << ex.what(); + } +} + +void FileCatalog::enableTabMode(bool enable) { + inTabMode = enable; + + if (enable) { + if (options.showFilmStripToolBar) + showToolBar(); + else + hideToolBar(); + exifInfo->set_active( options.filmStripShowFileNames ); + + } + else { + buttonBar->show(); + hbToolBar1->show(); + exifInfo->set_active( options.showFileNames ); + } + fileBrowser->enableTabMode(inTabMode); + + redrawAll(); +} + +void FileCatalog::_refreshProgressBar () { + // In tab mode, no progress bar at all + // Also mention that this progress bar only measures the FIRST pass (quick thumbnails) + // The second, usually longer pass is done multithreaded down in the single entries and is NOT measured by this + if (!inTabMode) { + GThreadLock lock; // All GUI acces from idle_add callbacks or separate thread HAVE to be protected + + Gtk::Notebook *nb =(Gtk::Notebook *)(filepanel->get_parent()); + Gtk::Box* hbb=NULL; + Gtk::Label *label=NULL; + if( options.mainNBVertical ) + hbb = Gtk::manage (new Gtk::VBox ()); + else + hbb = Gtk::manage (new Gtk::HBox ()); + if (!previewsToLoad ) { + hbb->pack_start (*Gtk::manage (new Gtk::Image (Gtk::Stock::DIRECTORY, Gtk::ICON_SIZE_MENU))); + int filteredCount = min(fileBrowser->getNumFiltered(),previewsLoaded); + + label = Gtk::manage (new Gtk::Label (M("MAIN_FRAME_FILEBROWSER")+ + (filteredCount!=previewsLoaded ? " ["+ Glib::ustring::format(filteredCount)+"/" : " (") + + Glib::ustring::format(previewsLoaded) + + (filteredCount!=previewsLoaded ? "]" : ")"))); + } else { + hbb->pack_start (*Gtk::manage (new Gtk::Image (Gtk::Stock::FIND, Gtk::ICON_SIZE_MENU))); + label = Gtk::manage (new Gtk::Label (M("MAIN_FRAME_FILEBROWSER")+" [" +Glib::ustring::format(std::fixed, std::setprecision(0), std::setw(3), (double)previewsLoaded / previewsToLoad*100 )+"%]" )); + filepanel->loadingThumbs("",(double)previewsLoaded / previewsToLoad); + } + if( options.mainNBVertical ) + label->set_angle(90); + hbb->pack_start (*label); + hbb->set_spacing (2); + hbb->set_tooltip_markup (M("MAIN_FRAME_FILEBROWSER_TOOLTIP")); + hbb->show_all (); + nb->set_tab_label(*filepanel,*hbb); + } +} + +int refreshProgressBarUI (void* data) { + (static_cast(data))->_refreshProgressBar (); + return 0; +} + +void FileCatalog::filterApplied() { + g_idle_add (refreshProgressBarUI, this); +} + + +void FileCatalog::previewReady (int dir_id, FileBrowserEntry* fdn) { + + if ( dir_id != selectedDirectoryId ) + return; + + // put it into the "full directory" browser + fdn->setImageAreaToolListener (iatlistener); + fileBrowser->addEntry (fdn); + + // update exif filter settings (minimal & maximal values of exif tags, cameras, lenses, etc...) + const CacheImageData* cfs = fdn->thumbnail->getCacheImageData(); + + { + MyMutex::MyLock lock(dirEFSMutex); + if (cfs->exifValid) { + if (cfs->fnumber < dirEFS.fnumberFrom) + dirEFS.fnumberFrom = cfs->fnumber; + if (cfs->fnumber > dirEFS.fnumberTo) + dirEFS.fnumberTo = cfs->fnumber; + if (cfs->shutter < dirEFS.shutterFrom) + dirEFS.shutterFrom = cfs->shutter; + if (cfs->shutter > dirEFS.shutterTo) + dirEFS.shutterTo = cfs->shutter; + if (cfs->iso>0 && (int)cfs->iso < dirEFS.isoFrom) + dirEFS.isoFrom = (int)cfs->iso; + if (cfs->iso>0 && (int)cfs->iso > dirEFS.isoTo) + dirEFS.isoTo = (int)cfs->iso; + if (cfs->focalLen < dirEFS.focalFrom) + dirEFS.focalFrom = cfs->focalLen; + if (cfs->focalLen > dirEFS.focalTo) + dirEFS.focalTo = cfs->focalLen; + } + dirEFS.filetypes.insert (cfs->filetype); + dirEFS.cameras.insert (cfs->getCamera()); + dirEFS.lenses.insert (cfs->lens); + dirEFS.expcomp.insert (cfs->expcomp); + } + + previewsLoaded++; + + g_idle_add (refreshProgressBarUI, this); +} + +int prevfinished (void* data) { + (static_cast(data))->previewsFinishedUI (); + return 0; +} + +// Called within GTK UI thread +void FileCatalog::previewsFinishedUI () { + + { + GThreadLock lock; // All GUI acces from idle_add callbacks or separate thread HAVE to be protected + redrawAll (); + previewsToLoad = 0; + + if (filterPanel) { + filterPanel->set_sensitive (true); + if ( !hasValidCurrentEFS ){ + MyMutex::MyLock lock(dirEFSMutex); + currentEFS = dirEFS; + filterPanel->setFilter ( dirEFS,true ); + }else { + filterPanel->setFilter ( currentEFS,false ); + } + } + + if (exportPanel) + exportPanel->set_sensitive (true); + + // restart anything that might have been loaded low quality + fileBrowser->refreshQuickThumbImages(); + fileBrowser->applyFilter (getFilter()); // refresh total image count + _refreshProgressBar(); + } + filepanel->loadingThumbs(M("PROGRESSBAR_READY"),0); + + if (!imageToSelect_fname.empty()){ + fileBrowser->selectImage(imageToSelect_fname); + imageToSelect_fname = ""; + } + + if (!refImageForOpen_fname.empty() && actionNextPrevious!=NAV_NONE){ + fileBrowser->openNextPreviousEditorImage(refImageForOpen_fname,actionNextPrevious); + refImageForOpen_fname = ""; + actionNextPrevious = NAV_NONE; + } +} + +void FileCatalog::previewsFinished (int dir_id) { + + if ( dir_id != selectedDirectoryId ) + { + return; + } + + if (!hasValidCurrentEFS) { + MyMutex::MyLock lock(dirEFSMutex); + currentEFS = dirEFS; + } + + g_idle_add (prevfinished, this); +} + +void FileCatalog::setEnabled (bool e) { + enabled = e; +} + +void FileCatalog::redrawAll () { + fileBrowser->queue_draw (); +} + +void FileCatalog::refreshThumbImages () { + fileBrowser->refreshThumbImages (); +} + +void FileCatalog::refreshHeight () { + int newHeight = fileBrowser->getEffectiveHeight(); + if (newHeight < 5) { // This may occure if there's no thumbnail. + int w, h; + get_size_request(w, h); + newHeight = h; + } + if (hbToolBar1->is_visible() && !options.FileBrowserToolbarSingleRow) + newHeight += hbToolBar1->get_height(); + if (buttonBar->is_visible()) + newHeight += buttonBar->get_height(); + set_size_request(0, newHeight+2); // HOMBRE: yeah, +2, there's always 2 pixels missing... sorry for this dirty hack O:) +} + +void FileCatalog::_openImage (std::vector tmb) { + + if (enabled && listener!=NULL) { + bool continueToLoad=true; + for (size_t i=0; i< tmb.size() && continueToLoad; i++) { + // Open the image here, and stop if in Single Editor mode, or if an image couldn't + // be opened, would it be because the file doesn't exist or because of lack of RAM + if( !(listener->fileSelected (tmb[i])) && !options.tabbedUI ) + continueToLoad = false; + tmb[i]->decreaseRef (); + } + } +} + +struct FCOIParams { + FileCatalog* catalog; + std::vector tmb; +}; + +int openRequestedUI (void* p) { + FCOIParams* params = static_cast(p); + params->catalog->_openImage (params->tmb); + delete params; + + return 0; +} + +void FileCatalog::openRequested (std::vector tmb) { + + FCOIParams* params = new FCOIParams; + params->catalog = this; + params->tmb = tmb; + for (size_t i=0; iincreaseRef (); + g_idle_add (openRequestedUI, params); +} + +void FileCatalog::deleteRequested (std::vector tbe, bool inclBatchProcessed) { + + if (tbe.empty()) + return; + + Gtk::MessageDialog msd (M("FILEBROWSER_DELETEDLGLABEL"), true, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_YES_NO, true); + msd.set_secondary_text(Glib::ustring::compose ( inclBatchProcessed ? M("FILEBROWSER_DELETEDLGMSGINCLPROC") : M("FILEBROWSER_DELETEDLGMSG"), tbe.size()), true); + + if (msd.run()==Gtk::RESPONSE_YES) { + for (unsigned int i=0; ifilename; + // remove from browser + FileBrowserEntry* t = fileBrowser->delEntry (fname); +// t->thumbnail->decreaseRef (); + delete t; + // remove from cache + cacheMgr->deleteEntry (fname); + // delete from file system + safe_g_remove (fname); + // delete paramfile if found + safe_g_remove (Glib::ustring(fname+paramFileExtension)); + safe_g_remove (Glib::ustring(removeExtension(fname)+paramFileExtension)); + // delete .thm file + safe_g_remove (Glib::ustring(removeExtension(fname)+".thm")); + safe_g_remove (Glib::ustring(removeExtension(fname)+".THM")); + + if (inclBatchProcessed) { + Glib::ustring procfName = Glib::ustring::compose ("%1.%2", BatchQueue::calcAutoFileNameBase(fname), options.saveFormatBatch.format); + if (safe_file_test (procfName, Glib::FILE_TEST_EXISTS)) safe_g_remove (procfName); + + // delete paramfile if found + Glib::ustring procfNameParamFile = Glib::ustring::compose ("%1.%2.out%3", BatchQueue::calcAutoFileNameBase(fname), options.saveFormatBatch.format, paramFileExtension); + if (safe_file_test (procfNameParamFile, Glib::FILE_TEST_EXISTS)) safe_g_remove (procfNameParamFile); + } + + previewsLoaded--; + } + + _refreshProgressBar(); + redrawAll (); + } +} + + +void FileCatalog::copyMoveRequested (std::vector tbe, bool moveRequested) { + + if (tbe.empty()) + return; + + + Glib::ustring fc_title; + if (moveRequested) fc_title=M("FILEBROWSER_POPUPMOVETO"); + else fc_title=M("FILEBROWSER_POPUPCOPYTO"); + Gtk::FileChooserDialog fc(fc_title,Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER ); + fc.add_button( Gtk::StockID("gtk-cancel"), Gtk::RESPONSE_CANCEL); + fc.add_button( Gtk::StockID("gtk-ok"), Gtk::RESPONSE_OK); + // open dialog at the 1-st file's path + fc.set_filename(tbe[0]->filename); + //!!! TODO prevent dialog closing on "enter" key press + + bool filecopymovecomplete; + int i_copyindex; + + if( fc.run() == Gtk::RESPONSE_OK ){ + Glib::ustring dest_Dir = fc.get_current_folder(); + + // iterate through selected files + for (unsigned int i=0; ifilename; + Glib::ustring src_Dir = Glib::path_get_dirname(src_fPath); + Glib::RefPtr src_file = Gio::File::create_for_path ( src_fPath ); + if( !src_file ) continue; // if file is missing - skip it + + Glib::ustring fname=src_file->get_basename(); + Glib::ustring fname_noExt = removeExtension(fname); + Glib::ustring fname_Ext = getExtension(fname); + + // construct destination File Paths + Glib::ustring dest_fPath = Glib::build_filename (dest_Dir, fname); + Glib::ustring dest_fPath_param= dest_fPath + paramFileExtension; + + if (moveRequested && (src_Dir==dest_Dir)) continue; + /* comparison of src_Dir and dest_Dir is done per image for compatibility with + possible future use of Collections as source where each file's source path may be different.*/ + + filecopymovecomplete = false; + i_copyindex = 1; + while(!filecopymovecomplete){ + // check for filename conflicts at destination - prevent overwriting (actually RT will crash on overwriting attempt) + if (!safe_file_test(dest_fPath, Glib::FILE_TEST_EXISTS) && !safe_file_test(dest_fPath_param, Glib::FILE_TEST_EXISTS)){ + // copy/move file to destination + Glib::RefPtr dest_file = Gio::File::create_for_path ( dest_fPath ); + if (moveRequested) { + // move file + src_file->move(dest_file); + // re-attach cache files + cacheMgr->renameEntry (src_fPath, tbe[i]->thumbnail->getMD5(), dest_fPath); + // remove from browser + fileBrowser->delEntry (src_fPath); + + previewsLoaded--; + } + else + src_file->copy(dest_file); + + + // attempt to copy/move paramFile only if it exist next to the src + Glib::RefPtr scr_param = Gio::File::create_for_path ( src_fPath + paramFileExtension ); + + if (safe_file_test( src_fPath + paramFileExtension, Glib::FILE_TEST_EXISTS)){ + Glib::RefPtr dest_param = Gio::File::create_for_path ( dest_fPath_param); + // copy/move paramFile to destination + if (moveRequested){ + if (safe_file_test( dest_fPath + paramFileExtension, Glib::FILE_TEST_EXISTS)){ + // profile already got copied to destination from cache after cacheMgr->renameEntry + // delete source profile as cleanup + safe_g_remove (src_fPath + paramFileExtension); + } + else + scr_param->move(dest_param); + } + else + scr_param->copy(dest_param); + } + filecopymovecomplete = true; + } + else{ + // adjust destination fname to avoid conflicts (append "_", preserve extension) + Glib::ustring dest_fname = Glib::ustring::compose("%1%2%3%4%5",fname_noExt,"_",i_copyindex,".",fname_Ext); + // re-construct destination File Paths + dest_fPath = Glib::build_filename (dest_Dir, dest_fname); + dest_fPath_param= dest_fPath + paramFileExtension; + i_copyindex++; + } + }//while + } // i tbe, bool fastmode) { + + if (listener) { + std::vector entries; + + // TODO: (HOMBRE) should we still use parallelization here, now that thumbnails are processed asynchronously...? + //#pragma omp parallel for ordered + for (size_t i=0; ithumbnail; + rtengine::procparams::ProcParams params = th->getProcParams(); + + // if fast mode is selected, override (disable) params + // controlling time and resource consuming tasks + // and also those which effect is not pronounced after reducing the image size + // TODO!!! could expose selections below via preferences + if (fastmode){ + if (options.fastexport_bypass_sharpening ) params.sharpening.enabled = false; + if (options.fastexport_bypass_sharpenEdge ) params.sharpenEdge.enabled = false; + if (options.fastexport_bypass_sharpenMicro ) params.sharpenMicro.enabled = false; + //if (options.fastexport_bypass_lumaDenoise ) params.lumaDenoise.enabled = false; + //if (options.fastexport_bypass_colorDenoise ) params.colorDenoise.enabled = false; + if (options.fastexport_bypass_defringe ) params.defringe.enabled = false; + if (options.fastexport_bypass_dirpyrDenoise ) params.dirpyrDenoise.enabled = false; + if (options.fastexport_bypass_sh_hq ) params.sh.hq = false; + if (options.fastexport_bypass_dirpyrequalizer ) params.dirpyrequalizer.enabled = false; + if (options.fastexport_bypass_wavelet ) params.wavelet.enabled = false; + //if (options.fastexport_bypass_raw_bayer_all_enhance ) params.raw.bayersensor.all_enhance = false; + if (options.fastexport_bypass_raw_bayer_dcb_iterations ) params.raw.bayersensor.dcb_iterations = 0; + if (options.fastexport_bypass_raw_bayer_dcb_enhance ) params.raw.bayersensor.dcb_enhance = false; + if (options.fastexport_bypass_raw_bayer_lmmse_iterations) params.raw.bayersensor.lmmse_iterations = 0; + if (options.fastexport_bypass_raw_bayer_linenoise ) params.raw.bayersensor.linenoise = 0; + if (options.fastexport_bypass_raw_bayer_greenthresh ) params.raw.bayersensor.greenthresh = 0; + if (options.fastexport_bypass_raw_ccSteps ) {params.raw.bayersensor.ccSteps = params.raw.xtranssensor.ccSteps = 0;} + if (options.fastexport_bypass_raw_ca ) {params.raw.ca_autocorrect = false; params.raw.cared=0; params.raw.cablue=0;} + if (options.fastexport_bypass_raw_df ) {params.raw.df_autoselect = false; params.raw.dark_frame="";} + if (options.fastexport_bypass_raw_ff ) {params.raw.ff_AutoSelect = false; params.raw.ff_file="";} + params.raw.bayersensor.method = options.fastexport_raw_bayer_method ; + params.raw.xtranssensor.method = options.fastexport_raw_xtrans_method; + params.icm.input = options.fastexport_icm_input ; + params.icm.working = options.fastexport_icm_working ; + params.icm.output = options.fastexport_icm_output ; + params.icm.gamma = options.fastexport_icm_gamma ; + params.resize.enabled = options.fastexport_resize_enabled ; + params.resize.scale = options.fastexport_resize_scale ; + params.resize.appliesTo = options.fastexport_resize_appliesTo ; + params.resize.method = options.fastexport_resize_method ; + params.resize.dataspec = options.fastexport_resize_dataspec ; + params.resize.width = options.fastexport_resize_width ; + params.resize.height = options.fastexport_resize_height ; + } + + rtengine::ProcessingJob* pjob = rtengine::ProcessingJob::create (fbe->filename, th->getType()==FT_Raw, params); + + int pw; + int ph = BatchQueue::calcMaxThumbnailHeight(); + th->getThumbnailSize (pw, ph); + + // processThumbImage is the processing intensive part, but adding to queue must be ordered + //#pragma omp ordered + //{ + BatchQueueEntry* bqh = new BatchQueueEntry (pjob, params, fbe->filename, pw, ph, th); + entries.push_back(bqh); + //} + } + + listener->addBatchQueueJobs( entries ); + } +} + +void FileCatalog::exportRequested (){ + +} + +void FileCatalog::setExportPanel (ExportPanel* expanel) { + + exportPanel = expanel; + exportPanel->set_sensitive (false); + exportPanel->setExportPanelListener (this); + fileBrowser->setExportPanel(expanel); +} + +void FileCatalog::renameRequested (std::vector tbe) { + + bool success; + + RenameDialog* renameDlg = new RenameDialog ((Gtk::Window*)get_toplevel()); + + for (size_t i=0; iinitName (Glib::path_get_basename (tbe[i]->filename), tbe[i]->thumbnail->getCacheImageData()); + + Glib::ustring ofname = tbe[i]->filename; + Glib::ustring dirName = Glib::path_get_dirname (tbe[i]->filename); + Glib::ustring baseName = Glib::path_get_basename (tbe[i]->filename); + + success = false; + do { + if (renameDlg->run ()== Gtk::RESPONSE_OK) { + Glib::ustring nBaseName = renameDlg->getNewName (); + // if path has directory components, exit + if (Glib::path_get_dirname (nBaseName) != ".") + continue; + // if no extension is given, concatenate the extension of the original file + Glib::ustring ext = getExtension (nBaseName); + if (ext.empty()) + nBaseName += "." + getExtension (baseName); + Glib::ustring nfname = Glib::build_filename (dirName, nBaseName); + + /* check if filename already exists*/ + if (safe_file_test (nfname, Glib::FILE_TEST_EXISTS)) { + Glib::ustring msg_ = Glib::ustring("") + nfname + ": " + M("MAIN_MSG_ALREADYEXISTS") + ""; + Gtk::MessageDialog msgd (msg_, true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); + msgd.run (); + } + else { + success = true; + if (!safe_g_rename (ofname, nfname)) { + cacheMgr->renameEntry (ofname, tbe[i]->thumbnail->getMD5(), nfname); + safe_g_remove(ofname + paramFileExtension); + reparseDirectory (); + } + } + } + else + success = true; + } while (!success); + renameDlg->hide (); + } + delete renameDlg; +/* // ask for new file name + Gtk::Dialog dialog (M("FILEBROWSER_RENAMEDLGLABEL"), *((Gtk::Window*)get_toplevel()), true, true); + + dialog.add_button (Gtk::Stock::OK, Gtk::RESPONSE_OK); + dialog.add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + + Gtk::Label l; + dialog.get_vbox()->pack_start (l, Gtk::PACK_SHRINK); + + Gtk::Entry nfentry; + + dialog.get_vbox()->pack_start (nfentry, Gtk::PACK_SHRINK); + dialog.get_vbox()->show_all (); + + nfentry.set_activates_default (true); + dialog.set_default_response (Gtk::RESPONSE_OK); + + for (int i=0; ifilename; + Glib::ustring dirName = Glib::path_get_dirname (tbe[i]->filename); + Glib::ustring baseName = Glib::path_get_basename (tbe[i]->filename); + + l.set_markup (Glib::ustring("") + Glib::ustring::compose (M("FILEBROWSER_RENAMEDLGMSG"), baseName) + Glib::ustring("")); + nfentry.set_text (baseName); + nfentry.select_region (0, baseName.size()); + + if (dialog.run ()== Gtk::RESPONSE_OK) { + Glib::ustring nBaseName = nfentry.get_text (); + // if path has directory components, exit + if (Glib::path_get_dirname (nBaseName) != ".") + continue; + // if no extension is given, concatenate the extension of the original file + if (nBaseName.find ('.')==nBaseName.npos) { + size_t lastdot = baseName.find_last_of ('.'); + nBaseName += "." + (lastdot!=Glib::ustring::npos ? baseName.substr (lastdot+1) : ""); + } + Glib::ustring nfname = Glib::build_filename (dirName, nBaseName); + if (!safe_g_rename (ofname, nfname)) { + cacheMgr->renameEntry (ofname, tbe[i]->thumbnail->getMD5(), nfname); + // the remaining part (removing old and adding new entry) is done by the directory monitor + reparseDirectory (); +// on_dir_changed (Gio::File::create_for_path (nfname), Gio::File::create_for_path (nfname), Gio::FILE_MONITOR_EVENT_CHANGED, true); + } + } + } + */ +} + +void FileCatalog::clearFromCacheRequested (std::vector tbe, bool leavenotrace) { + + if (tbe.empty()) + return; + + for (unsigned int i=0; ifilename; + // remove from cache + cacheMgr->clearFromCache (fname,leavenotrace); + } +} + +void FileCatalog::categoryButtonToggled (Gtk::ToggleButton* b, bool isMouseClick) { + + //was control key pressed + bool control_down = modifierKey & GDK_CONTROL_MASK; + + //was shift key pressed + bool shift_down = modifierKey & GDK_SHIFT_MASK; + + // The event is process here, we can clear modifierKey now, it'll be set again on the next even + modifierKey = 0; + + const int numCateg = sizeof(bCateg) / sizeof(bCateg[0]); + const int numButtons = sizeof(categoryButtons) / sizeof(categoryButtons[0]); + + for (int i=0; iset_active(!b->get_active()); + + //if both control and shift keys were pressed, do nothing + if (!(control_down && shift_down)) { + + fileBrowser->getScrollPosition (hScrollPos[lastScrollPos], vScrollPos[lastScrollPos]); + + //we look how many stars are already toggled on, if any + int toggled_stars_count=0, buttons=0, start_star=0, toggled_button=0; + + for (int i=0; iget_active()) { + if (i>0 && i<17) { + toggled_stars_count ++; + start_star = i; + } + buttons |= (1 << i); + } + if (categoryButtons[i] == b) toggled_button = i; + } + + // if no modifier key is pressed, + if (!(control_down || shift_down)) { + // if we're deselecting non-trashed + if (toggled_button == 18 && (buttons & (1 << toggled_button))) { + categoryButtons[0]->set_active (true); + for (int i=1; iset_active (false); + } + // if we're deselecting the only star still active + else if (toggled_stars_count == 1 && (buttons & (1 << toggled_button))) { + // activate clear-filters + categoryButtons[0]->set_active (true); + // deactivate the toggled filter + categoryButtons[toggled_button]->set_active (false); + } + // if we're deselecting trash + else if (toggled_button == 17 && (buttons & (1 << toggled_button))) { + categoryButtons[0]->set_active (true); + categoryButtons[17]->set_active (false); + } + else { + // activate the toggled filter, deactivate the rest + for (int i=0; iset_active (i==toggled_button); + } + } + //modifier key allowed only for stars and color labels... + else if (toggled_button>0 && toggled_button<17) { + if (control_down) { + //control is pressed + if (toggled_stars_count == 1 && (buttons & (1 << toggled_button))) { + //we're deselecting the only star still active, so we activate clear-filters + categoryButtons[0]->set_active(true); + //and we deselect the toggled star + categoryButtons[toggled_button]->set_active (false); + } + else if (toggled_stars_count >= 1) { + //we toggle the state of a star (eventually another one than the only one selected) + categoryButtons[toggled_button]->set_active(!categoryButtons[toggled_button]->get_active()); + } + else { + //no star selected + //we deselect the 2 non star filters + if (buttons & 1 ) categoryButtons[0]->set_active(false); + if (buttons & (1 << 17)) categoryButtons[17]->set_active(false); + //and we toggle on the star + categoryButtons[toggled_button]->set_active (true); + } + } + else { + //shift is pressed, only allowed if 0 or 1 star & labels is selected + if (!toggled_stars_count) { + //we deselect the 2 non star filters + if (buttons & 1 ) categoryButtons[0]->set_active(false); + if (buttons & (1 << 7)) categoryButtons[7]->set_active(false); + if (buttons & (1 << 13)) categoryButtons[13]->set_active(false); + if (buttons & (1 << 17)) categoryButtons[17]->set_active(false); + //and we set the start star to 1 (unrated images) + start_star = 1; + //we act as if one star were selected + toggled_stars_count = 1; + } + if (toggled_stars_count == 1) { + int current_star=min(start_star,toggled_button); + int last_star =max(start_star,toggled_button); + //we permute the start and the end star for the next loop + for (; current_star <= last_star; current_star++) { + //we toggle on all the star in the range + if (!(buttons & (1 << current_star))) categoryButtons[current_star]->set_active(true); + } + } + //if more than one star & color label is selected, do nothing + } + } + // ...or non-trashed with Control modifier + else if (toggled_button == 18 && control_down) + { + bNotTrash->set_active (!bNotTrash->get_active ()); + } + + bool active_now, active_before; + + // FilterClear: set the right images + // TODO: swapping FilterClear icon needs more work in categoryButtonToggled + /*active_now = bFilterClear->get_active(); + active_before = buttons & (1 << (0)); // 0 + if ( active_now && !active_before) bFilterClear->set_image (*iFilterClear); + else if (!active_now && active_before) bFilterClear->set_image (*igFilterClear);*/ + + // rank: set the right images + for (int i=0; i<5; i++) { + active_now = bRank[i]->get_active(); + active_before = buttons & (1 << (i+2)); // 2,3,4,5,6 + if ( active_now && !active_before) bRank[i]->set_image (*iranked[i]); + else if (!active_now && active_before) bRank[i]->set_image (*igranked[i]); + } + active_now = bUnRanked->get_active(); + active_before = buttons & (1 << (1)); // 1 + if ( active_now && !active_before) bUnRanked->set_image (*iUnRanked); + else if (!active_now && active_before) bUnRanked->set_image (*igUnRanked); + + // color labels: set the right images + for (int i=0; i<5; i++) { + active_now = bCLabel[i]->get_active(); + active_before = buttons & (1 << (i+8)); // 8,9,10,11,12 + if ( active_now && !active_before) bCLabel[i]->set_image (*iCLabeled[i]); + else if (!active_now && active_before) bCLabel[i]->set_image (*igCLabeled[i]); + } + active_now = bUnCLabeled->get_active(); + active_before = buttons & (1 << (7)); // 7 + if ( active_now && !active_before) bUnCLabeled->set_image (*iUnCLabeled); + else if (!active_now && active_before) bUnCLabeled->set_image (*igUnCLabeled); + + // Edited: set the right images + for (int i=0; i<2; i++) { + active_now = bEdited[i]->get_active(); + active_before = buttons & (1 << (i+13)); //13,14 + if ( active_now && !active_before) bEdited[i]->set_image (*iEdited[i]); + else if (!active_now && active_before) bEdited[i]->set_image (*igEdited[i]); + } + + // RecentlySaved: set the right images + for (int i=0; i<2; i++) { + active_now = bRecentlySaved[i]->get_active(); + active_before = buttons & (1 << (i+15));//15,16 + if ( active_now && !active_before) bRecentlySaved[i]->set_image (*iRecentlySaved[i]); + else if (!active_now && active_before) bRecentlySaved[i]->set_image (*igRecentlySaved[i]); + } + + fileBrowser->applyFilter (getFilter ()); + _refreshProgressBar(); + + //rearrange panels according to the selected filter + removeIfThere (hBox, trashButtonBox); + if (bTrash->get_active ()) + hBox->pack_start (*trashButtonBox, Gtk::PACK_SHRINK, 4); + hBox->queue_draw (); + + fileBrowser->setScrollPosition (hScrollPos[lastScrollPos], vScrollPos[lastScrollPos]); + } + + for (int i=0; iget_active () || bRank[0]->get_active () || bRank[1]->get_active () || bRank[2]->get_active () || bRank[3]->get_active () || bRank[4]->get_active (); + bool anyCLabelFilterActive = bUnCLabeled->get_active () || bCLabel[0]->get_active ()|| bCLabel[1]->get_active ()|| bCLabel[2]->get_active ()|| bCLabel[3]->get_active ()|| bCLabel[4]->get_active (); + bool anyEditedFilterActive = bEdited[0]->get_active() || bEdited[1]->get_active(); + bool anyRecentlySavedFilterActive = bRecentlySaved[0]->get_active() || bRecentlySaved[1]->get_active(); + const bool nonTrashedActive = bNotTrash->get_active(); + /* + * filter is setup in 2 steps + * Step 1: handle individual filters + */ + filter.showRanked[0] = bFilterClear->get_active() || bUnRanked->get_active () || bTrash->get_active () || nonTrashedActive || + anyCLabelFilterActive || anyEditedFilterActive || anyRecentlySavedFilterActive; + + filter.showCLabeled[0] = bFilterClear->get_active() || bUnCLabeled->get_active () || bTrash->get_active () || nonTrashedActive || + anyRankFilterActive || anyEditedFilterActive || anyRecentlySavedFilterActive; + + for (int i=1; i<=5; i++){ + filter.showRanked[i] = bFilterClear->get_active() || bRank[i-1]->get_active () || bTrash->get_active () || nonTrashedActive || + anyCLabelFilterActive || anyEditedFilterActive || anyRecentlySavedFilterActive; + + filter.showCLabeled[i] = bFilterClear->get_active() || bCLabel[i-1]->get_active () || bTrash->get_active () || nonTrashedActive || + anyRankFilterActive || anyEditedFilterActive || anyRecentlySavedFilterActive; + } + + for (int i=0; i<2; i++){ + filter.showEdited[i] = bFilterClear->get_active() || bEdited[i]->get_active () || bTrash->get_active () || nonTrashedActive || + anyRankFilterActive || anyCLabelFilterActive || anyRecentlySavedFilterActive; + + filter.showRecentlySaved[i] = bFilterClear->get_active() || bRecentlySaved[i]->get_active () || bTrash->get_active () || nonTrashedActive || + anyRankFilterActive || anyCLabelFilterActive || anyEditedFilterActive; + } + if( options.rtSettings.verbose ){ + printf ("\n**************** FileCatalog::getFilter *** AFTER STEP 1 \n"); + for (int i=0; i<=5; i++) printf ("filter.showRanked[%i] = %i\n",i,filter.showRanked[i]); + for (int i=0; i<=5; i++) printf ("filter.showCLabeled[%i] = %i\n",i,filter.showCLabeled[i]); + for (int i=0; i<2; i++) printf ("filter.showEdited[%i] = %i\n",i,filter.showEdited[i]); + for (int i=0; i<2; i++) printf ("filter.showRecentlySaved[%i] = %i\n",i,filter.showRecentlySaved[i]); + } + filter.multiselect = false; + + /* + * Step 2 + * handle the case when more than 1 filter is selected. This overrides values set in Step + * if no filters in a group are active, filter.show for each member of that group will be set to true + * otherwise they are set based on UI input + */ + if ((anyRankFilterActive && anyCLabelFilterActive ) || + (anyRankFilterActive && anyEditedFilterActive ) || + (anyRankFilterActive && anyRecentlySavedFilterActive ) || + (anyCLabelFilterActive && anyEditedFilterActive ) || + (anyCLabelFilterActive && anyRecentlySavedFilterActive ) || + (anyEditedFilterActive && anyRecentlySavedFilterActive) || + (nonTrashedActive && (anyRankFilterActive || anyCLabelFilterActive || anyEditedFilterActive || anyRecentlySavedFilterActive))){ + + filter.multiselect = true; + filter.showRanked[0] = anyRankFilterActive?bUnRanked->get_active ():true; + filter.showCLabeled[0] = anyCLabelFilterActive?bUnCLabeled->get_active ():true; + + for (int i=1; i<=5; i++){ + filter.showRanked[i] = anyRankFilterActive?bRank[i-1]->get_active ():true; + filter.showCLabeled[i] = anyCLabelFilterActive?bCLabel[i-1]->get_active ():true; + } + for (int i=0; i<2; i++){ + filter.showEdited[i] = anyEditedFilterActive?bEdited[i]->get_active():true; + filter.showRecentlySaved[i] = anyRecentlySavedFilterActive?bRecentlySaved[i]->get_active():true; + } + if( options.rtSettings.verbose ){ + printf ("\n**************** FileCatalog::getFilter *** AFTER STEP 2 \n"); + for (int i=0; i<=5; i++) printf ("filter.showRanked[%i] = %i\n",i,filter.showRanked[i]); + for (int i=0; i<=5; i++) printf ("filter.showCLabeled[%i] = %i\n",i,filter.showCLabeled[i]); + for (int i=0; i<2; i++) printf ("filter.showEdited[%i] = %i\n",i,filter.showEdited[i]); + for (int i=0; i<2; i++) printf ("filter.showRecentlySaved[%i] = %i\n",i,filter.showRecentlySaved[i]); + printf ("filter.multiselect = %i\n",filter.multiselect); + } + } + + + filter.showTrash = bTrash->get_active () || !bNotTrash->get_active (); + filter.showNotTrash = !bTrash->get_active (); + if (!filterPanel) + filter.exifFilterEnabled = false; + else { + if (!hasValidCurrentEFS) { + MyMutex::MyLock lock(dirEFSMutex); + filter.exifFilter = dirEFS; + } + else + filter.exifFilter = currentEFS; + filter.exifFilterEnabled = filterPanel->isEnabled (); + } + + //TODO add support for more query options. e.g by date, iso, f-number, etc + //TODO could use date:;iso: etc + // default will be filename + + /* // this is for safe execution if getFilter is called before Query object is instantiated + Glib::ustring tempQuery; + tempQuery=""; + if (Query) tempQuery = Query->get_text(); + */ + filter.queryString = Query->get_text(); // full query string from Query Entry + filter.queryFileName = Query->get_text(); // for now Query is only by file name + + return filter; +} + +void FileCatalog::filterChanged () { + //TODO !!! there is too many repetitive and unnecessary executions of + // " fileBrowser->applyFilter (getFilter()); " throughout the code + // this needs further analysis and cleanup + fileBrowser->applyFilter (getFilter()); + _refreshProgressBar(); +} + +void FileCatalog::reparseDirectory () { + + if (selectedDirectory.empty()) + return; + + if (!safe_file_test (selectedDirectory, Glib::FILE_TEST_IS_DIR)) { + closeDir (); + return; + } + + std::vector nfileNameList = getFileList (); + + // check if a thumbnailed file has been deleted + const std::vector& t = fileBrowser->getEntries (); + std::vector fileNamesToDel; + for (size_t i=0; ifilename, Glib::FILE_TEST_EXISTS)) + fileNamesToDel.push_back (t[i]->filename); + for (size_t i=0; idelEntry (fileNamesToDel[i]); + cacheMgr->deleteEntry (fileNamesToDel[i]); + } + + // check if a new file has been added + for (size_t i=0; i(cat))->reparseDirectory (); + return 0; +} + +void FileCatalog::winDirChanged () { + g_idle_add(winDirChangedUITread, this); +} + +#else + +void FileCatalog::on_dir_changed (const Glib::RefPtr& file, const Glib::RefPtr& other_file, Gio::FileMonitorEvent event_type, bool internal) { + + if (options.has_retained_extention(file->get_parse_name()) + && (event_type == Gio::FILE_MONITOR_EVENT_CREATED || event_type == Gio::FILE_MONITOR_EVENT_DELETED || event_type == Gio::FILE_MONITOR_EVENT_CHANGED)) { + if (!internal) { + GThreadLock lock; + reparseDirectory (); + } + else + reparseDirectory (); + } +} + +#endif + +void FileCatalog::checkAndAddFile (Glib::RefPtr file) { + + if (!file ) + return; + if( !file->query_exists()) + return; + Glib::RefPtr info = safe_query_file_info(file); + if (info && info->get_file_type() != Gio::FILE_TYPE_DIRECTORY && (!info->is_hidden() || !options.fbShowHidden)) { + size_t lastdot = info->get_name().find_last_of ('.'); + if (options.is_extention_enabled(lastdot!=Glib::ustring::npos ? info->get_name().substr (lastdot+1) : "")){ + previewLoader->add (selectedDirectoryId,file->get_parse_name(),this); + previewsToLoad++; + } + } +} + +void FileCatalog::addAndOpenFile (const Glib::ustring& fname) { + + Glib::RefPtr file = Gio::File::create_for_path (fname); + if (!file ) + return; + if( !file->query_exists()) + return; + Glib::RefPtr info = safe_query_file_info(file); + if( !info ) + return; + size_t lastdot = info->get_name().find_last_of ('.'); + if (options.is_extention_enabled(lastdot!=Glib::ustring::npos ? info->get_name().substr (lastdot+1) : "")){ + // if supported, load thumbnail first + Thumbnail* tmb = cacheMgr->getEntry (file->get_parse_name()); + if (tmb) { + FileBrowserEntry* entry = new FileBrowserEntry (tmb, file->get_parse_name()); + previewReady (selectedDirectoryId,entry); + // open the file + FCOIParams* params = new FCOIParams; + params->catalog = this; + params->tmb.push_back (tmb); + tmb->increaseRef (); + g_idle_add (openRequestedUI, params); + } + } +} + +void FileCatalog::emptyTrash () { + + const std::vector t = fileBrowser->getEntries (); + std::vector toDel; + for (size_t i=0; i(t[i]))->thumbnail->getStage()==1) + toDel.push_back (static_cast(t[i])); + deleteRequested (toDel, false); + trashChanged(); +} + +bool FileCatalog::trashIsEmpty () { + const std::vector t = fileBrowser->getEntries (); + for (size_t i=0; i(t[i]))->thumbnail->getStage()==1) + return false; + + return true; +} + +void FileCatalog::zoomIn () { + + fileBrowser->zoomIn (); + refreshHeight(); + +} +void FileCatalog::zoomOut () { + + fileBrowser->zoomOut (); + refreshHeight(); + +} +void FileCatalog::refreshEditedState (const std::set& efiles) { + + editedFiles = efiles; + fileBrowser->refreshEditedState (efiles); +} + +void FileCatalog::selectionChanged (std::vector tbe) { + + if (fslistener) + fslistener->selectionChanged (tbe); +} + +// Called within GTK UI thread +void FileCatalog::exifFilterChanged () { + + currentEFS = filterPanel->getFilter (); + hasValidCurrentEFS = true; + fileBrowser->applyFilter (getFilter ()); + _refreshProgressBar(); +} + +void FileCatalog::setFilterPanel (FilterPanel* fpanel) { + + filterPanel = fpanel; + filterPanel->set_sensitive (false); + filterPanel->setFilterPanelListener (this); +} +void FileCatalog::trashChanged () { + if (trashIsEmpty()) { + bTrash->set_image(*iTrashEmpty); + } + else { + bTrash->set_image(*iTrashFull); + } +} + +// Called within GTK UI thread +void FileCatalog::buttonQueryClearPressed () { + Query->set_text(""); + FileCatalog::executeQuery (); +} + +// Called within GTK UI thread +void FileCatalog::executeQuery(){ + // if BrowsePath text was changed, do a full browse; + // otherwise filter only + + if (BrowsePath->get_text()!=selectedDirectory) + buttonBrowsePathPressed (); + else + FileCatalog::filterChanged (); +} + +bool FileCatalog::Query_key_pressed (GdkEventKey *event){ + + bool shift = event->state & GDK_SHIFT_MASK; + + switch (event->keyval) { + case GDK_Escape: + // Clear Query if the Escape character is pressed within it + if (!shift){ + FileCatalog::buttonQueryClearPressed (); + return true; + } + break; + default: + break; + } + return false; +} + +void FileCatalog::updateFBQueryTB (bool singleRow) { + hbToolBar1->reference(); + if (singleRow) { + bool removed = removeIfThere(this, hbToolBar1, false); + if (removed) { + buttonBar->pack_start(*hbToolBar1, Gtk::PACK_EXPAND_WIDGET, 0); + } + } + else { + bool removed = removeIfThere(buttonBar, hbToolBar1, false); + if (removed) { + pack_start(*hbToolBar1, Gtk::PACK_SHRINK, 0); + reorder_child(*hbToolBar1, 0); + } + } + hbToolBar1->unreference(); +} + +void FileCatalog::updateFBToolBarVisibility (bool showFilmStripToolBar){ + if (showFilmStripToolBar) + showToolBar(); + else + hideToolBar(); + refreshHeight(); +} + +void FileCatalog::buttonBrowsePathPressed () { + Glib::ustring BrowsePathValue = BrowsePath->get_text(); + Glib::ustring DecodedPathPrefix=""; + Glib::ustring FirstChar; + + // handle shortcuts in the BrowsePath -- START + // read the 1-st character from the path + FirstChar = BrowsePathValue.substr (0,1); + + if (FirstChar=="~"){ // home directory + DecodedPathPrefix = Glib::get_home_dir(); + } + else if (FirstChar=="!"){ // user's pictures directory + //DecodedPathPrefix = g_get_user_special_dir(G_USER_DIRECTORY_PICTURES); + DecodedPathPrefix = safe_get_user_picture_dir(); + } + + if (!DecodedPathPrefix.empty()){ + BrowsePathValue = Glib::ustring::compose ("%1%2",DecodedPathPrefix,BrowsePathValue.substr (1,BrowsePath->get_text_length()-1)); + BrowsePath->set_text(BrowsePathValue); + } + // handle shortcuts in the BrowsePath -- END + + // validate the path + if (safe_file_test(BrowsePathValue, Glib::FILE_TEST_IS_DIR) && dirlistener){ + dirlistener->selectDir (BrowsePathValue); + } + else + // error, likely path not found: show red arrow + buttonBrowsePath->set_image (*iRefreshRed); +} + +bool FileCatalog::BrowsePath_key_pressed (GdkEventKey *event){ + + bool shift = event->state & GDK_SHIFT_MASK; + + switch (event->keyval) { + case GDK_Escape: + // On Escape character Reset BrowsePath to selectedDirectory + if (!shift){ + BrowsePath->set_text(selectedDirectory); + // place cursor at the end + BrowsePath->select_region(BrowsePath->get_text_length(), BrowsePath->get_text_length()); + return true; + } + break; + default: + break; + } + return false; +} + +void FileCatalog::tbLeftPanel_1_visible (bool visible){ + if (visible) + tbLeftPanel_1->show(); + else + tbLeftPanel_1->hide(); +} +void FileCatalog::tbRightPanel_1_visible (bool visible){ + if (visible) + tbRightPanel_1->show(); + else + tbRightPanel_1->hide(); +} +void FileCatalog::tbLeftPanel_1_toggled () { + removeIfThere (filepanel->dirpaned, filepanel->placespaned, false); + if (tbLeftPanel_1->get_active()){ + filepanel->dirpaned->pack1 (*filepanel->placespaned, false, true); + tbLeftPanel_1->set_image (*iLeftPanel_1_Hide); + options.browserDirPanelOpened = true; + } + else { + tbLeftPanel_1->set_image (*iLeftPanel_1_Show); + options.browserDirPanelOpened = false; + } +} + +void FileCatalog::tbRightPanel_1_toggled () { + if (tbRightPanel_1->get_active()){ + filepanel->rightBox->show(); + tbRightPanel_1->set_image (*iRightPanel_1_Hide); + options.browserToolPanelOpened = true; + } + else{ + filepanel->rightBox->hide(); + tbRightPanel_1->set_image (*iRightPanel_1_Show); + options.browserToolPanelOpened = false; + } +} + +bool FileCatalog::CheckSidePanelsVisibility(){ + if(tbLeftPanel_1->get_active()==false && tbRightPanel_1->get_active()==false) + return false; + else + return true; +} +void FileCatalog::toggleSidePanels(){ + // toggle left AND right panels + + bool bAllSidePanelsVisible; + bAllSidePanelsVisible= CheckSidePanelsVisibility(); + + tbLeftPanel_1->set_active (!bAllSidePanelsVisible); + tbRightPanel_1->set_active (!bAllSidePanelsVisible); +} + +void FileCatalog::toggleLeftPanel() { + tbLeftPanel_1->set_active (!tbLeftPanel_1->get_active()); +} + +void FileCatalog::toggleRightPanel() { + tbRightPanel_1->set_active (!tbRightPanel_1->get_active()); +} + + +void FileCatalog::selectImage (Glib::ustring fname, bool clearFilters) { + + Glib::ustring dirname = Glib::path_get_dirname(fname); + if (!dirname.empty()){ + BrowsePath->set_text(dirname); + + + if (clearFilters){ // clear all filters + Query->set_text(""); + categoryButtonToggled(bFilterClear,false); + // disable exif filters + if (filterPanel->isEnabled()) filterPanel->setEnabled (false); + } + + if (BrowsePath->get_text()!=selectedDirectory){ + // reload or refresh thumbs and select image + buttonBrowsePathPressed (); + // the actual selection of image will be handled asynchronously at the end of FileCatalog::previewsFinishedUI + imageToSelect_fname = fname; + } + else{ + // FileCatalog::filterChanged ();//this will be replaced by queue_draw() in fileBrowser->selectImage + fileBrowser->selectImage(fname); + imageToSelect_fname = ""; + } + } +} + + +void FileCatalog::openNextPreviousEditorImage (Glib::ustring fname, bool clearFilters, eRTNav nextPrevious) { + + Glib::ustring dirname = Glib::path_get_dirname(fname); + if (!dirname.empty()){ + BrowsePath->set_text(dirname); + + + if (clearFilters){ // clear all filters + Query->set_text(""); + categoryButtonToggled(bFilterClear,false); + // disable exif filters + if (filterPanel->isEnabled()) filterPanel->setEnabled (false); + } + + if (BrowsePath->get_text()!=selectedDirectory){ + // reload or refresh thumbs and select image + buttonBrowsePathPressed (); + // the actual selection of image will be handled asynchronously at the end of FileCatalog::previewsFinishedUI + refImageForOpen_fname = fname; + actionNextPrevious = nextPrevious; + } + else{ + // FileCatalog::filterChanged ();//this was replace by queue_draw() in fileBrowser->selectImage + fileBrowser->openNextPreviousEditorImage(fname,nextPrevious); + refImageForOpen_fname = ""; + actionNextPrevious = NAV_NONE; + } + } +} + +bool FileCatalog::handleShortcutKey (GdkEventKey* event) { + + bool ctrl = event->state & GDK_CONTROL_MASK; + bool shift = event->state & GDK_SHIFT_MASK; + bool alt = event->state & GDK_MOD1_MASK; +#ifdef __WIN32__ + bool altgr = event->state & GDK_MOD2_MASK; +#else + bool altgr = event->state & GDK_MOD5_MASK; +#endif + modifierKey = event->state; + + // GUI Layout + switch(event->keyval) { + case GDK_l: + if (!alt)tbLeftPanel_1->set_active (!tbLeftPanel_1->get_active()); // toggle left panel + if (alt && !ctrl) tbRightPanel_1->set_active (!tbRightPanel_1->get_active()); // toggle right panel + if (alt && ctrl) { + tbLeftPanel_1->set_active (!tbLeftPanel_1->get_active()); // toggle left panel + tbRightPanel_1->set_active (!tbRightPanel_1->get_active()); // toggle right panel + } + return true; + case GDK_m: + if (!ctrl && !alt) toggleSidePanels(); + return true; + } + + if (shift){ + switch(event->keyval) { + case GDK_Escape: + BrowsePath->set_text(selectedDirectory); + // set focus on something neutral, this is useful to remove focus from BrowsePath and Query + // when need to execute a shortcut, which otherwise will be typed into those fields + filepanel->grab_focus(); + return true; + } + } + +#ifdef __WIN32__ + if (!alt && !shift && !altgr) { // shift is reserved for ranking + switch(event->hardware_keycode) { + case 0x30: + categoryButtonToggled(bUnRanked,false); + return true; + case 0x31: + categoryButtonToggled(bRank[0],false); + return true; + case 0x32: + categoryButtonToggled(bRank[1],false); + return true; + case 0x33: + categoryButtonToggled(bRank[2],false); + return true; + case 0x34: + categoryButtonToggled(bRank[3],false); + return true; + case 0x35: + categoryButtonToggled(bRank[4],false); + return true; + case 0x36: + categoryButtonToggled(bEdited[0],false); + return true; + case 0x37: + categoryButtonToggled(bEdited[1],false); + return true; + } + } + if (!alt && !shift) { + switch(event->keyval) { + + case GDK_Return: + case GDK_KP_Enter: + if (BrowsePath->is_focus()){ + FileCatalog::buttonBrowsePathPressed (); + return true; + } + break; + } + } + + if (alt && !shift) { // shift is reserved for color labeling + switch(event->hardware_keycode) { + case 0x30: + categoryButtonToggled(bUnCLabeled,false); + return true; + case 0x31: + categoryButtonToggled(bCLabel[0],false); + return true; + case 0x32: + categoryButtonToggled(bCLabel[1],false); + return true; + case 0x33: + categoryButtonToggled(bCLabel[2],false); + return true; + case 0x34: + categoryButtonToggled(bCLabel[3],false); + return true; + case 0x35: + categoryButtonToggled(bCLabel[4],false); + return true; + case 0x36: + categoryButtonToggled(bRecentlySaved[0],false); + return true; + case 0x37: + categoryButtonToggled(bRecentlySaved[1],false); + return true; + } + } +#else + if (!alt && !shift && !altgr) { // shift is reserved for ranking + switch(event->hardware_keycode) { + case 0x13: + categoryButtonToggled(bUnRanked,false); + return true; + case 0x0a: + categoryButtonToggled(bRank[0],false); + return true; + case 0x0b: + categoryButtonToggled(bRank[1],false); + return true; + case 0x0c: + categoryButtonToggled(bRank[2],false); + return true; + case 0x0d: + categoryButtonToggled(bRank[3],false); + return true; + case 0x0e: + categoryButtonToggled(bRank[4],false); + return true; + case 0x0f: + categoryButtonToggled(bEdited[0],false); + return true; + case 0x10: + categoryButtonToggled(bEdited[1],false); + return true; + } + } + if (!alt && !shift) { + switch(event->keyval) { + + case GDK_Return: + case GDK_KP_Enter: + if (BrowsePath->is_focus()){ + FileCatalog::buttonBrowsePathPressed (); + return true; + } + break; + } + } + + if (alt && !shift) { // shift is reserved for color labeling + switch(event->hardware_keycode) { + case 0x13: + categoryButtonToggled(bUnCLabeled,false); + return true; + case 0x0a: + categoryButtonToggled(bCLabel[0],false); + return true; + case 0x0b: + categoryButtonToggled(bCLabel[1],false); + return true; + case 0x0c: + categoryButtonToggled(bCLabel[2],false); + return true; + case 0x0d: + categoryButtonToggled(bCLabel[3],false); + return true; + case 0x0e: + categoryButtonToggled(bCLabel[4],false); + return true; + case 0x0f: + categoryButtonToggled(bRecentlySaved[0],false); + return true; + case 0x10: + categoryButtonToggled(bRecentlySaved[1],false); + return true; + } + } +#endif + if (!ctrl && !alt) { + switch(event->keyval) { + case GDK_d: + case GDK_D: + categoryButtonToggled(bFilterClear,false); + return true; + } + } + + if (!ctrl || (alt && !options.tabbedUI)) { + switch(event->keyval) { + + case GDK_bracketright: + coarsePanel->rotateRight(); + return true; + case GDK_bracketleft: + coarsePanel->rotateLeft(); + return true; + case GDK_i: + case GDK_I: + exifInfo->set_active (!exifInfo->get_active()); + return true; + + case GDK_plus: + case GDK_equal: + zoomIn(); + return true; + case GDK_minus: + case GDK_underscore: + zoomOut(); + return true; + } + } + if (ctrl && !alt) { + switch (event->keyval) { + case GDK_o: + BrowsePath->select_region(0, BrowsePath->get_text_length()); + BrowsePath->grab_focus(); + return true; + case GDK_f: + Query->select_region(0, Query->get_text_length()); + Query->grab_focus(); + return true; + case GDK_t: + case GDK_T: + modifierKey = 0; // HOMBRE: yet another hack.... otherwise the shortcut won't work + categoryButtonToggled(bTrash,false); + return true; + } + } + if (!ctrl && !alt && shift) { + switch (event->keyval) { + case GDK_t: + case GDK_T: + if (inTabMode) { + if (options.showFilmStripToolBar) + hideToolBar(); + else + showToolBar(); + options.showFilmStripToolBar = !options.showFilmStripToolBar; + } + return true; + } + } + if (!ctrl && !alt && !shift) { + switch (event->keyval) { + case GDK_t: + case GDK_T: + if (inTabMode) { + if (options.showFilmStripToolBar) + hideToolBar(); + else + showToolBar(); + options.showFilmStripToolBar = !options.showFilmStripToolBar; + } + refreshHeight(); + return true; + } + } + + if (fileBrowser->keyPressed(event)) + return true; + + return false; +} + +void FileCatalog::showToolBar() { + if (!options.FileBrowserToolbarSingleRow) + hbToolBar1->show(); + buttonBar->show(); +} + +void FileCatalog::hideToolBar() { + if (!options.FileBrowserToolbarSingleRow) + hbToolBar1->hide(); + buttonBar->hide(); +} diff --git a/rtgui/filecatalog.h b/rtgui/filecatalog.h new file mode 100644 index 000000000..a8b4d954f --- /dev/null +++ b/rtgui/filecatalog.h @@ -0,0 +1,273 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _FILECATALOG_ +#define _FILECATALOG_ + +#ifdef WIN32 +#include "windirmonitor.h" +#endif +#include "dirbrowserremoteinterface.h" +#include "dirselectionlistener.h" +#include "filebrowser.h" +#include "exiffiltersettings.h" +#include +#include "fileselectionlistener.h" +#include +#include "fileselectionchangelistener.h" +#include "coarsepanel.h" +#include "toolbar.h" +#include "filterpanel.h" +#include "exportpanel.h" +#include "previewloader.h" +#include "multilangmgr.h" +#include "threadutils.h" + + +class DirEntry { + + public: + Glib::ustring fullName; + + DirEntry (const Glib::ustring& n) : fullName (n) {} + + bool operator< (DirEntry& other) { + return fullName.casefold() < other.fullName.casefold(); + } +}; +class FilePanel; +/* + * Class: + * - handling the list of file (add/remove them) + * - handling the thumbnail toolbar, + * - monitoring the directory (for any change) + */ +class FileCatalog : public Gtk::VBox, + public DirSelectionListener, + public PreviewLoaderListener, + public FilterPanelListener, + public FileBrowserListener, + public ExportPanelListener +#ifdef WIN32 + , public WinDirChangeListener +#endif + { + + private: + FilePanel* filepanel; + Gtk::HBox* hBox; + Glib::ustring selectedDirectory; + int selectedDirectoryId; + bool enabled; + bool inTabMode; // Tab mode has e.g. different progress bar handling + Glib::ustring imageToSelect_fname; + Glib::ustring refImageForOpen_fname; // Next/previous for Editor's perspective + eRTNav actionNextPrevious; + + FileSelectionListener* listener; + FileSelectionChangeListener* fslistener; + ImageAreaToolListener* iatlistener; + DirBrowserRemoteInterface* dirlistener; + + Gtk::HBox* buttonBar; + Gtk::HBox* hbToolBar1; + + Gtk::HBox* fltrRankbox; + Gtk::HBox* fltrLabelbox; + Gtk::VBox* fltrVbox1; + + Gtk::HBox* fltrEditedBox; + Gtk::HBox* fltrRecentlySavedBox; + Gtk::VBox* fltrVbox2; + + Gtk::ToggleButton* tbLeftPanel_1; + Gtk::ToggleButton* tbRightPanel_1; + Gtk::ToggleButton* bFilterClear; + Gtk::ToggleButton* bUnRanked; + Gtk::ToggleButton* bRank[5]; + Gtk::ToggleButton* bUnCLabeled; + Gtk::ToggleButton* bCLabel[5];//color label + Gtk::ToggleButton* bEdited[2]; + Gtk::ToggleButton* bRecentlySaved[2]; + Gtk::ToggleButton* bTrash; + Gtk::ToggleButton* bNotTrash; + Gtk::ToggleButton* categoryButtons[19]; + Gtk::ToggleButton* exifInfo; + sigc::connection bCateg[19]; + Gtk::Image* iFilterClear, *igFilterClear; + Gtk::Image* iranked[5], *igranked[5], *iUnRanked, *igUnRanked; + Gtk::Image* iCLabeled[5], *igCLabeled[5], *iUnCLabeled, *igUnCLabeled; + Gtk::Image* iEdited[2], *igEdited[2]; + Gtk::Image* iRecentlySaved[2], *igRecentlySaved[2]; + Gtk::Image *iTrashEmpty, *iTrashFull; + Gtk::Image *iNotTrash; + Gtk::Image *iRefreshWhite, *iRefreshRed; + Gtk::Image *iLeftPanel_1_Show, *iLeftPanel_1_Hide, *iRightPanel_1_Show, *iRightPanel_1_Hide; + Gtk::Image *iQueryClear; + + Gtk::Entry* BrowsePath; + Gtk::Button* buttonBrowsePath; + + Gtk::Entry* Query; + Gtk::Button* buttonQueryClear; + + double hScrollPos[18]; + double vScrollPos[18]; + int lastScrollPos; + + Gtk::VBox* trashButtonBox; + + Gtk::Button* zoomInButton; + Gtk::Button* zoomOutButton; + + MyMutex dirEFSMutex; + ExifFilterSettings dirEFS; + ExifFilterSettings currentEFS; + bool hasValidCurrentEFS; + + FilterPanel* filterPanel; + ExportPanel* exportPanel; + + int previewsToLoad; + int previewsLoaded; + + + std::vector fileNameList; + std::set editedFiles; + guint modifierKey; // any modifiers held when rank button was pressed + +#ifndef _WIN32 + Glib::RefPtr dirMonitor; +#else + WinDirMonitor* wdMonitor; +#endif + + void addAndOpenFile (const Glib::ustring& fname); + void checkAndAddFile (Glib::RefPtr info); + std::vector getFileList (); + BrowserFilter getFilter (); + void trashChanged (); + + public: + // thumbnail browsers + FileBrowser* fileBrowser; + + CoarsePanel* coarsePanel; + ToolBar* toolBar; + + FileCatalog (CoarsePanel* cp, ToolBar* tb, FilePanel* filepanel); + ~FileCatalog(); + void dirSelected (const Glib::ustring& dirname, const Glib::ustring& openfile=""); + void closeDir (); + void refreshEditedState (const std::set& efiles); + + // previewloaderlistener interface + void previewReady (int dir_id, FileBrowserEntry* fdn); + void previewsFinished (int dir_id); + void previewsFinishedUI (); + void _refreshProgressBar (); + + void setInspector(Inspector* inspector) { if (fileBrowser) fileBrowser->setInspector(inspector); } + void disableInspector() { if (fileBrowser) fileBrowser->disableInspector(); } + void enableInspector() { if (fileBrowser) fileBrowser->enableInspector(); } + + // filterpanel interface + void exifFilterChanged (); + + // exportpanel interface + void exportRequested(); + + Glib::ustring lastSelectedDir () { return selectedDirectory; } + void setEnabled (bool e); // if not enabled, it does not open image + void enableTabMode(bool enable); // sets progress bar + + // accessors for FileBrowser + void redrawAll (); + void refreshThumbImages (); + void refreshHeight (); + + void openRequested (std::vector tbe); + void deleteRequested (std::vector tbe, bool inclBatchProcessed); + void copyMoveRequested (std::vector tbe, bool moveRequested); + void developRequested (std::vector tbe, bool fastmode); + void renameRequested (std::vector tbe); + void clearFromCacheRequested(std::vector tbe, bool leavenotrace); + void selectionChanged (std::vector tbe); + void emptyTrash (); + bool trashIsEmpty (); + + void setFileSelectionListener (FileSelectionListener* l) { listener = l; } + void setFileSelectionChangeListener (FileSelectionChangeListener* l) { fslistener = l; } + void setImageAreaToolListener (ImageAreaToolListener* l) { iatlistener = l; } + void setDirBrowserRemoteInterface (DirBrowserRemoteInterface* l) { dirlistener = l; } + + void setFilterPanel (FilterPanel* fpanel); + void setExportPanel (ExportPanel* expanel); + void exifInfoButtonToggled(); + void categoryButtonToggled (Gtk::ToggleButton* b, bool isMouseClick); + bool capture_event(GdkEventButton* event); + void filterChanged (); + void runFilterDialog (); + + void on_realize(); + void reparseDirectory (); + void _openImage (std::vector tmb); + + void zoomIn (); + void zoomOut (); + + void buttonBrowsePathPressed (); + bool BrowsePath_key_pressed (GdkEventKey *event); + void buttonQueryClearPressed (); + void executeQuery (); + bool Query_key_pressed(GdkEventKey *event); + void updateFBQueryTB (bool singleRow); + void updateFBToolBarVisibility (bool showFilmStripToolBar); + + void tbLeftPanel_1_toggled (); + void tbLeftPanel_1_visible (bool visible); + void tbRightPanel_1_toggled (); + void tbRightPanel_1_visible (bool visible); + + void openNextImage () { fileBrowser->openNextImage(); } + void openPrevImage () { fileBrowser->openPrevImage(); } + void selectImage (Glib::ustring fname, bool clearFilters); + void openNextPreviousEditorImage (Glib::ustring fname, bool clearFilters, eRTNav nextPrevious); + + bool handleShortcutKey (GdkEventKey* event); + + bool isInTabMode() { return inTabMode; } + + bool CheckSidePanelsVisibility(); + void toggleSidePanels(); + void toggleLeftPanel(); + void toggleRightPanel(); + + void showToolBar(); + void hideToolBar(); + void filterApplied(); + +#ifndef _WIN32 + void on_dir_changed (const Glib::RefPtr& file, const Glib::RefPtr& other_file, Gio::FileMonitorEvent event_type, bool internal); +#else + void winDirChanged (); +#endif + +}; + +#endif diff --git a/rtgui/filepanel.cc b/rtgui/filepanel.cc new file mode 100644 index 000000000..f5ab9423a --- /dev/null +++ b/rtgui/filepanel.cc @@ -0,0 +1,351 @@ + +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "filepanel.h" +#include "rtwindow.h" +#include "../rtengine/safegtk.h" +#include "inspector.h" + +int FilePanelInitUI (void* data) { + (static_cast(data))->init (); + return 0; +} + +FilePanel::FilePanel () : parent(NULL) { + + dirpaned = Gtk::manage ( new Gtk::HPaned () ); + dirpaned->set_position (options.dirBrowserWidth); + + dirBrowser = Gtk::manage ( new DirBrowser () ); + placesBrowser = Gtk::manage ( new PlacesBrowser () ); + recentBrowser = Gtk::manage ( new RecentBrowser () ); + + placespaned = Gtk::manage ( new Gtk::VPaned () ); + placespaned->set_size_request(50,100); + placespaned->set_position (options.dirBrowserHeight); + + Gtk::VBox* obox = Gtk::manage (new Gtk::VBox ()); + obox->pack_start (*recentBrowser, Gtk::PACK_SHRINK, 4); + obox->pack_start (*dirBrowser); + + placespaned->pack1 (*placesBrowser, false, true); + placespaned->pack2 (*obox, true, true); + + dirpaned->pack1 (*placespaned, false, true); + + tpc = new BatchToolPanelCoordinator (this); + tpc->removeWbTool(); + fileCatalog = Gtk::manage ( new FileCatalog (tpc->coarse, tpc->getToolBar(),this) ); + ribbonPane = Gtk::manage ( new Gtk::Paned() ); + ribbonPane->add(*fileCatalog); + ribbonPane->set_size_request(50,150); + dirpaned->pack2 (*ribbonPane, true, true); + + placesBrowser->setDirBrowserRemoteInterface (dirBrowser); + recentBrowser->setDirBrowserRemoteInterface (dirBrowser); + dirBrowser->addDirSelectionListener (fileCatalog); + dirBrowser->addDirSelectionListener (recentBrowser); + dirBrowser->addDirSelectionListener (placesBrowser); + dirBrowser->addDirSelectionListener (tpc); + fileCatalog->setFileSelectionListener (this); + fileCatalog->setDirBrowserRemoteInterface (dirBrowser); + + rightBox = Gtk::manage ( new Gtk::HBox () ); + rightBox->set_size_request(50,100); + rightNotebook = Gtk::manage ( new Gtk::Notebook () ); + rightNotebookSwitchConn = rightNotebook->signal_switch_page().connect_notify( sigc::mem_fun(*this, &FilePanel::on_NB_switch_page) ); + //Gtk::VBox* taggingBox = Gtk::manage ( new Gtk::VBox () ); + + history = Gtk::manage ( new History (false) ); + + tpc->addPParamsChangeListener (history); + history->setProfileChangeListener (tpc); + + Gtk::ScrolledWindow* sFilterPanel = Gtk::manage ( new Gtk::ScrolledWindow() ); + filterPanel = Gtk::manage ( new FilterPanel () ); + sFilterPanel->add (*filterPanel); + sFilterPanel->set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC); + + inspectorPanel = new Inspector(); + fileCatalog->setInspector(inspectorPanel); + + Gtk::ScrolledWindow* sExportPanel = Gtk::manage ( new Gtk::ScrolledWindow() ); + exportPanel = Gtk::manage ( new ExportPanel () ); + sExportPanel->add (*exportPanel); + sExportPanel->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + + fileCatalog->setFilterPanel (filterPanel); + fileCatalog->setExportPanel (exportPanel); + fileCatalog->setImageAreaToolListener (tpc); + fileCatalog->fileBrowser->setBatchPParamsChangeListener (tpc); + + //------------------ + + rightNotebook->set_tab_pos (Gtk::POS_LEFT); + + Gtk::Label* devLab = Gtk::manage ( new Gtk::Label (M("MAIN_TAB_DEVELOP")) ); + devLab->set_angle (90); + Gtk::Label* inspectLab = Gtk::manage ( new Gtk::Label (M("MAIN_TAB_INSPECT")) ); + inspectLab->set_angle (90); + Gtk::Label* filtLab = Gtk::manage ( new Gtk::Label (M("MAIN_TAB_FILTER")) ); + filtLab->set_angle (90); + //Gtk::Label* tagLab = Gtk::manage ( new Gtk::Label (M("MAIN_TAB_TAGGING")) ); + //tagLab->set_angle (90); + Gtk::Label* exportLab = Gtk::manage ( new Gtk::Label (M("MAIN_TAB_EXPORT")) ); + exportLab->set_angle (90); + + tpcPaned = Gtk::manage ( new Gtk::VPaned () ); + tpcPaned->pack1 (*tpc->toolPanelNotebook, false, true); + tpcPaned->pack2 (*history, true, true); + + rightNotebook->append_page (*tpcPaned, *devLab); + rightNotebook->append_page (*inspectorPanel, *inspectLab); + rightNotebook->append_page (*sFilterPanel, *filtLab); + //rightNotebook->append_page (*taggingBox, *tagLab); commented out: currently the tab is empty ... + rightNotebook->append_page (*sExportPanel, *exportLab); + + rightBox->pack_start (*rightNotebook); + + pack1(*dirpaned, true, true); + pack2(*rightBox, false, true); + + fileCatalog->setFileSelectionChangeListener (tpc); + + fileCatalog->setFileSelectionListener (this); + g_idle_add (FilePanelInitUI, this); + + show_all (); +} + +FilePanel::~FilePanel () { + rightNotebookSwitchConn.disconnect(); + if (inspectorPanel) + delete inspectorPanel; +} + +void FilePanel::on_realize () { + Gtk::HPaned::on_realize (); + tpc->closeAllTools(); +} + + +void FilePanel::setAspect () { + int winW, winH; + parent->get_size(winW, winH); + placespaned->set_position(options.dirBrowserHeight); + dirpaned->set_position(options.dirBrowserWidth); + tpcPaned->set_position(options.browserToolPanelHeight); + set_position(winW - options.browserToolPanelWidth); + if (!options.browserDirPanelOpened) + fileCatalog->toggleLeftPanel(); + if (!options.browserToolPanelOpened) + fileCatalog->toggleRightPanel(); +} + +void FilePanel::init () { + + GThreadLock lock; // All GUI acces from idle_add callbacks or separate thread HAVE to be protected + dirBrowser->fillDirTree (); + placesBrowser->refreshPlacesList (); + + if (argv1!="" && safe_file_test (argv1, Glib::FILE_TEST_IS_DIR)) + dirBrowser->open (argv1); + else { + if (options.startupDir==STARTUPDIR_HOME) + dirBrowser->open (safe_get_user_picture_dir()); + else if (options.startupDir==STARTUPDIR_CURRENT) + dirBrowser->open (argv0); + else if (options.startupDir==STARTUPDIR_CUSTOM || options.startupDir==STARTUPDIR_LAST) { + if (options.startupPath.length() && safe_file_test(options.startupPath, Glib::FILE_TEST_EXISTS) && safe_file_test(options.startupPath, Glib::FILE_TEST_IS_DIR)) + dirBrowser->open (options.startupPath); + else { + // Fallback option if the path is empty or the folder doesn't exist + dirBrowser->open (safe_get_user_picture_dir()); + } + } + } +} + +void FilePanel::on_NB_switch_page(GtkNotebookPage* page, guint page_num) { + if (page_num == 1) { + // switching the inspector "on" + fileCatalog->enableInspector(); + } + else { + // switching the inspector "off" + fileCatalog->disableInspector(); + } +} + +bool FilePanel::fileSelected (Thumbnail* thm) { + + if (!parent) + return false; + + // Check if it's already open BEFORE loading the file + if (options.tabbedUI && parent->selectEditorPanel(thm->getFileName())) + return true; + + // try to open the file + bool loading = thm->imageLoad( true ); + if( !loading ) return false; + + pendingLoadMutex.lock(); + pendingLoad *pl = new pendingLoad(); + pl->complete = false; + pl->pc = 0; + pl->thm = thm; + pendingLoads.push_back(pl); + pendingLoadMutex.unlock(); + + ProgressConnector *ld = new ProgressConnector(); + ld->startFunc (sigc::bind(sigc::ptr_fun(&rtengine::InitialImage::load), thm->getFileName (), thm->getType()==FT_Raw, &error, parent->getProgressListener()), + sigc::bind(sigc::mem_fun(*this,&FilePanel::imageLoaded), thm, ld) ); + return true; +} +bool FilePanel::imageLoaded( Thumbnail* thm, ProgressConnector *pc ){ + + pendingLoadMutex.lock(); + // find our place in the array and mark the entry as complete + for (unsigned int i = 0; i < pendingLoads.size(); i++) { + if (pendingLoads[i]->thm == thm) { + pendingLoads[i]->pc = pc; + pendingLoads[i]->complete = true; + break; + } + } + // The purpose of the pendingLoads vector is to open tabs in the same order as the loads where initiated. It has no effect on single editor mode. + while (pendingLoads.size() > 0 && pendingLoads.front()->complete) { + pendingLoad *pl = pendingLoads.front(); + if (pl->pc->returnValue()) { + if (options.tabbedUI) { + EditorPanel* epanel; + { + GThreadLock lock; // Acquiring the GUI... not sure that it's necessary, but it shouldn't harm + epanel = Gtk::manage (new EditorPanel ()); + parent->addEditorPanel (epanel,pl->thm->getFileName()); + } + epanel->open(pl->thm, pl->pc->returnValue() ); + if (!(options.multiDisplayMode>0)) + parent->set_title_decorated(pl->thm->getFileName()); + } else { + { + GThreadLock lock; // Acquiring the GUI... not sure that it's necessary, but it shouldn't harm + parent->SetEditorCurrent(); + } + parent->epanel->open(pl->thm, pl->pc->returnValue() ); + parent->set_title_decorated(pl->thm->getFileName()); + } + } else { + Glib::ustring msg_ = Glib::ustring("") + M("MAIN_MSG_CANNOTLOAD") + " \"" + thm->getFileName() + "\" .\n"; + Gtk::MessageDialog msgd (msg_, true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); + msgd.run (); + } + delete pl->pc; + + { + GThreadLock lock; // Acquiring the GUI... not sure that it's necessary, but it shouldn't harm + parent->setProgress(0.); + parent->setProgressStr(""); + } + + pendingLoads.erase(pendingLoads.begin()); + delete pl; + } + pendingLoadMutex.unlock(); + + thm->imageLoad( false ); + + return false; // MUST return false from idle function +} + +void FilePanel::saveOptions () { + + int winW, winH; + parent->get_size(winW, winH); + options.dirBrowserWidth = dirpaned->get_position (); + options.dirBrowserHeight = placespaned->get_position (); + options.browserToolPanelWidth = winW - get_position(); + options.browserToolPanelHeight = tpcPaned->get_position (); + if (options.startupDir==STARTUPDIR_LAST && fileCatalog->lastSelectedDir ()!="") + options.startupPath = fileCatalog->lastSelectedDir (); + fileCatalog->closeDir (); +} + +void FilePanel::open (const Glib::ustring& d) { + + if (safe_file_test (d, Glib::FILE_TEST_IS_DIR)) + dirBrowser->open (d.c_str()); + else if (safe_file_test (d, Glib::FILE_TEST_EXISTS)) + dirBrowser->open (Glib::path_get_dirname(d), Glib::path_get_basename(d)); +} + +bool FilePanel::addBatchQueueJobs ( std::vector &entries ) { + + if (parent) + parent->addBatchQueueJobs (entries); + return true; +} + +void FilePanel::optionsChanged () { + + tpc->optionsChanged (); + fileCatalog->refreshThumbImages (); +} + +bool FilePanel::handleShortcutKey (GdkEventKey* event) { + + bool ctrl = event->state & GDK_CONTROL_MASK; + + if (!ctrl) { + switch(event->keyval) { + } + } + else { + switch (event->keyval) { + } + } + + if(tpc->getToolBar() && tpc->getToolBar()->handleShortcutKey(event)) + return true; + + if(tpc->handleShortcutKey(event)) + return true; + + if(fileCatalog->handleShortcutKey(event)) + return true; + + return false; +} + +void FilePanel::loadingThumbs(Glib::ustring str, double rate) +{ + GThreadLock lock; // All GUI acces from idle_add callbacks or separate thread HAVE to be protected + if( !str.empty()) + parent->setProgressStr(str); + parent->setProgress( rate ); +} + +void FilePanel::updateTPVScrollbar (bool hide) { + tpc->updateTPVScrollbar (hide); +} + +void FilePanel::updateTabsUsesIcons (bool useIcons) { + tpc->updateTabsUsesIcons (useIcons); +} diff --git a/rtgui/filepanel.h b/rtgui/filepanel.h new file mode 100755 index 000000000..834564ba4 --- /dev/null +++ b/rtgui/filepanel.h @@ -0,0 +1,107 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _FILEPANEL_ +#define _FILEPANEL_ + +#include +#include "batchtoolpanelcoord.h" +#include "filecatalog.h" +#include "dirbrowser.h" +#include "fileselectionlistener.h" +#include "placesbrowser.h" +#include "recentbrowser.h" +#include "pparamschangelistener.h" +#include "history.h" +#include "filterpanel.h" +#include "exportpanel.h" +#include "progressconnector.h" + +class RTWindow; +class FilePanel : public Gtk::HPaned, + public FileSelectionListener, + public PParamsChangeListener +{ + + protected: + //DirBrowser* dirBrowser; + PlacesBrowser* placesBrowser; + RecentBrowser* recentBrowser; + // FileCatalog* fileCatalog; // filecatalog is the file browser with the button bar above it + + Inspector* inspectorPanel; + Gtk::VPaned* tpcPaned; + BatchToolPanelCoordinator* tpc; + History* history; + //FilterPanel* filterPanel; + RTWindow* parent; + Gtk::Notebook* rightNotebook; + sigc::connection rightNotebookSwitchConn; + + struct pendingLoad { + bool complete; + ProgressConnector *pc; + Thumbnail *thm; + }; + MyMutex pendingLoadMutex; + std::vector pendingLoads; + + int error; + + void on_NB_switch_page(GtkNotebookPage* page, guint page_num); + + public: + FilePanel (); + ~FilePanel (); + + Gtk::Paned* placespaned; + Gtk::HPaned* dirpaned; + + Gtk::HBox* rightBox; + + DirBrowser* dirBrowser; + FilterPanel* filterPanel; + ExportPanel* exportPanel; + FileCatalog* fileCatalog; + Gtk::Paned *ribbonPane; + + void setParent (RTWindow* p) { parent = p; } + void init (); // dont call it directly, the constructor calls it as idle source + void on_realize (); + void setAspect(); + void open (const Glib::ustring& d); // open a file or a directory + void refreshEditedState (const std::set& efiles) { fileCatalog->refreshEditedState (efiles); } + void loadingThumbs(Glib::ustring str, double rate); + + // call this before closing RT: it saves file browser's related things into options + void saveOptions (); + + // interface fileselectionlistener + bool fileSelected (Thumbnail* thm); + bool addBatchQueueJobs ( std::vector &entries ); + + void optionsChanged (); + bool imageLoaded( Thumbnail* thm, ProgressConnector * ); + + bool handleShortcutKey (GdkEventKey* event); + void updateTPVScrollbar (bool hide); + void updateTabsUsesIcons (bool useIcons); +}; + +#endif + diff --git a/rtgui/fileselectionchangelistener.h b/rtgui/fileselectionchangelistener.h new file mode 100644 index 000000000..c8e0a9a8c --- /dev/null +++ b/rtgui/fileselectionchangelistener.h @@ -0,0 +1,31 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _FILESELECTIONCHANGELISTENER_ +#define _FILESELECTIONCHANGELISTENER_ + +#include "thumbnail.h" + +class FileSelectionChangeListener { + + public: + virtual void selectionChanged (const std::vector& selected) {} +}; + +#endif + diff --git a/rtgui/fileselectionlistener.h b/rtgui/fileselectionlistener.h new file mode 100644 index 000000000..0da740f31 --- /dev/null +++ b/rtgui/fileselectionlistener.h @@ -0,0 +1,33 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _FILESELECTIONLISTENER_ +#define _FILESELECTIONLISTENER_ + +#include "thumbnail.h" +#include "batchqueueentry.h" + +class FileSelectionListener { + + public: + virtual bool fileSelected (Thumbnail* thm) =0; + virtual bool addBatchQueueJobs ( std::vector &entries ) =0; +}; + +#endif + diff --git a/rtgui/filethumbnailbuttonset.cc b/rtgui/filethumbnailbuttonset.cc new file mode 100644 index 000000000..5111017d7 --- /dev/null +++ b/rtgui/filethumbnailbuttonset.cc @@ -0,0 +1,94 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "filethumbnailbuttonset.h" +#include "multilangmgr.h" +#include "../rtengine/safegtk.h" + +extern Glib::ustring argv0; + +bool FileThumbnailButtonSet::iconsLoaded = false; + +Cairo::RefPtr FileThumbnailButtonSet::rankIcon; +Cairo::RefPtr FileThumbnailButtonSet::gRankIcon; +Cairo::RefPtr FileThumbnailButtonSet::unRankIcon; +Cairo::RefPtr FileThumbnailButtonSet::trashIcon; +Cairo::RefPtr FileThumbnailButtonSet::unTrashIcon; +Cairo::RefPtr FileThumbnailButtonSet::processIcon; +Cairo::RefPtr FileThumbnailButtonSet::colorLabelIcon_0; +Cairo::RefPtr FileThumbnailButtonSet::colorLabelIcon_1; +Cairo::RefPtr FileThumbnailButtonSet::colorLabelIcon_2; +Cairo::RefPtr FileThumbnailButtonSet::colorLabelIcon_3; +Cairo::RefPtr FileThumbnailButtonSet::colorLabelIcon_4; +Cairo::RefPtr FileThumbnailButtonSet::colorLabelIcon_5; + +FileThumbnailButtonSet::FileThumbnailButtonSet (FileBrowserEntry* myEntry) { + + if (!iconsLoaded) { + unRankIcon = safe_create_from_png ("ratednotg.png"); + rankIcon = safe_create_from_png ("rated.png"); + gRankIcon = safe_create_from_png ("grayrated.png"); + trashIcon = safe_create_from_png ("trash-thumbnail.png"); + unTrashIcon = safe_create_from_png ("undelete-thumbnail.png"); + processIcon = safe_create_from_png ("processing-thumbnail.png"); + + colorLabelIcon_0 = safe_create_from_png ("cglabel0.png"); //("nocolorlabel.png"); + colorLabelIcon_1 = safe_create_from_png ("clabel1.png"); + colorLabelIcon_2 = safe_create_from_png ("clabel2.png"); + colorLabelIcon_3 = safe_create_from_png ("clabel3.png"); + colorLabelIcon_4 = safe_create_from_png ("clabel4.png"); + colorLabelIcon_5 = safe_create_from_png ("clabel5.png"); + iconsLoaded = true; + } + + add (new LWButton (processIcon, 6, myEntry, LWButton::Left, LWButton::Center, M("FILEBROWSER_POPUPPROCESS"))); + add (new LWButton (unRankIcon, 0, myEntry, LWButton::Left, LWButton::Center, M("FILEBROWSER_UNRANK_TOOLTIP"))); + for (int i=0; i<5; i++) + add (new LWButton (rankIcon, i+1, myEntry, LWButton::Left)); + add (new LWButton (trashIcon, 7, myEntry, LWButton::Right, LWButton::Center, M("FILEBROWSER_POPUPTRASH"))); + + add (new LWButton (colorLabelIcon_0, 8, myEntry, LWButton::Right, LWButton::Center, M("FILEBROWSER_COLORLABEL_TOOLTIP"))); + + buttons[2]->setToolTip (M("FILEBROWSER_RANK1_TOOLTIP")); + buttons[3]->setToolTip (M("FILEBROWSER_RANK2_TOOLTIP")); + buttons[4]->setToolTip (M("FILEBROWSER_RANK3_TOOLTIP")); + buttons[5]->setToolTip (M("FILEBROWSER_RANK4_TOOLTIP")); + buttons[6]->setToolTip (M("FILEBROWSER_RANK5_TOOLTIP")); +} + +void FileThumbnailButtonSet::setRank (int stars) { + + for (int i=1; i<=5; i++) + buttons[i+1]->setIcon (i<=stars ? rankIcon : gRankIcon); +} + +void FileThumbnailButtonSet::setColorLabel (int colorLabel) { + + if (colorLabel==0) buttons[8]->setIcon (colorLabelIcon_0); //transparent label + if (colorLabel==1) buttons[8]->setIcon (colorLabelIcon_1); + if (colorLabel==2) buttons[8]->setIcon (colorLabelIcon_2); + if (colorLabel==3) buttons[8]->setIcon (colorLabelIcon_3); + if (colorLabel==4) buttons[8]->setIcon (colorLabelIcon_4); + if (colorLabel==5) buttons[8]->setIcon (colorLabelIcon_5); +} + +void FileThumbnailButtonSet::setInTrash (bool inTrash) { + + buttons[7]->setIcon (inTrash ? unTrashIcon : trashIcon); + buttons[7]->setToolTip (inTrash ? M("FILEBROWSER_POPUPUNTRASH") : M("FILEBROWSER_POPUPTRASH")); +} diff --git a/rtgui/filethumbnailbuttonset.h b/rtgui/filethumbnailbuttonset.h new file mode 100644 index 000000000..3ba6408f3 --- /dev/null +++ b/rtgui/filethumbnailbuttonset.h @@ -0,0 +1,53 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _FILETHUMBNAILBUTTONSET_ +#define _FILETHUMBNAILBUTTONSET_ + +#include "lwbuttonset.h" +#include +#include "filebrowserentry.h" + +class FileBrowserEntry; +class FileThumbnailButtonSet : public LWButtonSet { + + static bool iconsLoaded; + + public: + static Cairo::RefPtr rankIcon; + static Cairo::RefPtr gRankIcon; + static Cairo::RefPtr unRankIcon; + static Cairo::RefPtr trashIcon; + static Cairo::RefPtr unTrashIcon; + static Cairo::RefPtr processIcon; + + static Cairo::RefPtr colorLabelIcon_0; + static Cairo::RefPtr colorLabelIcon_1; + static Cairo::RefPtr colorLabelIcon_2; + static Cairo::RefPtr colorLabelIcon_3; + static Cairo::RefPtr colorLabelIcon_4; + static Cairo::RefPtr colorLabelIcon_5; + + FileThumbnailButtonSet (FileBrowserEntry* myEntry); + void setRank (int stars); + void setColorLabel (int colorlabel); + void setInTrash (bool inTrash); + +}; + +#endif diff --git a/rtgui/filmsimulation.cc b/rtgui/filmsimulation.cc new file mode 100644 index 000000000..4e63d7058 --- /dev/null +++ b/rtgui/filmsimulation.cc @@ -0,0 +1,264 @@ +#include "filmsimulation.h" +#include "options.h" +#include "../rtengine/clutstore.h" +#include "../rtengine/safegtk.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +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 ); + if ( foundClutsCount == 0 ) + { + pack_start( *Gtk::manage( new Gtk::Label( M("TP_FILMSIMULATION_ZEROCLUTSFOUND") ) ) ); + } + m_clutComboBoxConn = m_clutComboBox->signal_changed().connect( sigc::mem_fun( *this, &FilmSimulation::onClutSelected ) ); + pack_start( *m_clutComboBox ); + + m_strength = Gtk::manage( new Adjuster( M("TP_FILMSIMULATION_STRENGTH"), 0., 100, 1., 100 ) ); + m_strength->setAdjusterListener( this ); + + pack_start( *m_strength, Gtk::PACK_SHRINK, 0 ); + +} + +void FilmSimulation::onClutSelected() +{ + Glib::ustring currentClutFilename = m_clutComboBox->getSelectedClut(); + + if ( getEnabled() && !currentClutFilename.empty() && listener && currentClutFilename != m_oldClutFilename ) + { + Glib::ustring clutName, dummy; + splitClutFilename( currentClutFilename, clutName, dummy, dummy ); + listener->panelChanged( EvFilmSimulationFilename, clutName ); + + m_oldClutFilename = currentClutFilename; + } +} + +void FilmSimulation::enabledChanged () { + + if (listener) { + if (get_inconsistent()) + listener->panelChanged (EvFilmSimulationEnabled, M("GENERAL_UNCHANGED")); + else if (getEnabled()) + listener->panelChanged (EvFilmSimulationEnabled, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvFilmSimulationEnabled, M("GENERAL_DISABLED")); + } +} + +void FilmSimulation::adjusterChanged( Adjuster* a, double newval ) +{ + if (listener && (multiImage||getEnabled()) ) + { + Glib::ustring value = a->getTextValue(); + listener->panelChanged ( EvFilmSimulationStrength, value ); + } +} + +void FilmSimulation::setBatchMode( bool batchMode ) +{ + ToolPanel::setBatchMode( batchMode ); + m_clutComboBox->addUnchangedEntry(); +} + +void FilmSimulation::read( const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited ) +{ + //copypasted from lensprofile.cc & sharpening.cc + disableListener(); + updateDisable( true ); + + setEnabled (pp->filmSimulation.enabled); + if ( !pp->filmSimulation.clutFilename.empty() ) + m_clutComboBox->setSelectedClut( pp->filmSimulation.clutFilename ); + m_strength->setValue( pp->filmSimulation.strength ); + + if (pedited) + { + set_inconsistent (multiImage && !pedited->filmSimulation.enabled); + m_strength->setEditedState (pedited->filmSimulation.strength ? Edited : UnEdited); + if ( !pedited->filmSimulation.clutFilename ) + m_clutComboBox->setSelectedClut("NULL"); + } + if ( !get_inconsistent() && !pp->filmSimulation.enabled ) + { + if (options.clutCacheSize == 1) + clutStore.clearCache(); + } + + updateDisable( false ); + enableListener(); +} + +void FilmSimulation::updateDisable( bool value ) +{ + m_clutComboBoxConn.block( value ); +} + +void FilmSimulation::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pedited ) +{ + if ( pedited ) + { + pedited->filmSimulation.enabled = !get_inconsistent(); + pedited->filmSimulation.strength = m_strength->getEditedState (); + pedited->filmSimulation.clutFilename = m_clutComboBox->getSelectedClut() != "NULL"; + } + + pp->filmSimulation.enabled = getEnabled(); + Glib::ustring clutFName = m_clutComboBox->getSelectedClut(); + if ( clutFName != "NULL" ) // We do not want to set "NULL" in clutFilename, even if "unedited" + pp->filmSimulation.clutFilename = clutFName; + pp->filmSimulation.strength = m_strength->getValue(); +} + +void FilmSimulation::setAdjusterBehavior( bool strength ) +{ + m_strength->setAddMode( strength ); +} + +void FilmSimulation::trimValues( rtengine::procparams::ProcParams* pp ) +{ + pp->filmSimulation.strength = m_strength->trimValue( pp->filmSimulation.strength ); +} + +//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +ClutComboBox::ClutColumns::ClutColumns() +{ + add( label ); + add( clutFilename ); +} + +int ClutComboBox::fillFromDir( Glib::ustring path ) +{ + int result = 0; + if ( !path.empty() ) + { + m_model.clear(); + m_model = Gtk::TreeStore::create( m_columns ); + set_model( m_model ); + result = parseDir( path, 0 ); + pack_start( m_columns.label, false ); + } + return result; +} + +Gtk::TreeIter appendToModel( Glib::RefPtr model, Gtk::TreeModel::Row *parent ) +{ + Gtk::TreeIter result; + if ( parent ) + { + result = model->append( parent->children() ); + + } + else + { + result = model->append(); + } + return result; +} + +int ClutComboBox::parseDir( Glib::ustring path, Gtk::TreeModel::Row *parentRow ) +{ + int result = 0; + if ( path.empty() || !safe_file_test( path, Glib::FILE_TEST_EXISTS ) || !safe_file_test ( path, Glib::FILE_TEST_IS_DIR ) ) + return result; + + Glib::Dir* dir = new Glib::Dir( path ); + + Strings names; + + for( Glib::DirIterator it = dir->begin(); it != dir->end(); ++it ) + { + Glib::ustring current = *it; + if ( current != "." && current != ".." ) + { + names.push_back( current ); + } + } + + std::sort( names.begin(), names.end() ); + + for ( Strings::iterator it = names.begin(); it != names.end(); ++it ) + { + Glib::ustring current = *it; + Glib::ustring fullname = Glib::build_filename( path, current ); + if ( safe_file_test( fullname, Glib::FILE_TEST_IS_DIR ) ) + { + + Gtk::TreeModel::Row newFolderMenu = *appendToModel( m_model, parentRow ); + newFolderMenu[ m_columns.label ] = current; + result += parseDir( fullname, &newFolderMenu ); + } + else + { + Glib::ustring name, extension, profileName; + splitClutFilename( current, name, extension, profileName ); + if ( extension == "tif" || + extension == "TIF" || + extension == "png" || + extension == "PNG" ) + { + Gtk::TreeModel::Row newClut = *appendToModel( m_model, parentRow ); + newClut[ m_columns.label ] = name; + newClut[ m_columns.clutFilename ] = fullname; + ++result; + } + } + } + return result; +} + +Glib::ustring ClutComboBox::getSelectedClut() +{ + Glib::ustring result; + Gtk::TreeModel::iterator current = get_active(); + Gtk::TreeModel::Row row = *current; + if ( row ) + { + result = row[ m_columns.clutFilename ]; + } + return result; +} + +void ClutComboBox::setSelectedClut( Glib::ustring filename ) +{ + if ( !filename.empty() ) + { + Gtk::TreeIter found = findRowByClutFilename( m_model->children(), filename ); + if ( found ) + { + set_active( found ); + } + } +} + +Gtk::TreeIter ClutComboBox::findRowByClutFilename( Gtk::TreeModel::Children childs, Glib::ustring filename ) +{ + Gtk::TreeIter result = childs.end(); + for( Gtk::TreeModel::Children::iterator it = childs.begin(); !result && it != childs.end(); ++it ) + { + Gtk::TreeModel::Row row = *it; + if ( row[ m_columns.clutFilename ] == filename ) + { + result = it; + } + else + { + result = findRowByClutFilename( it->children(), filename ); + } + } + 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 new file mode 100644 index 000000000..4b05342f9 --- /dev/null +++ b/rtgui/filmsimulation.h @@ -0,0 +1,60 @@ +#ifndef FILM_SIMULATION_INCLUDED +#define FILM_SIMULATION_INCLUDED + +#include +#include +#include +#include "toolpanel.h" +#include "guiutils.h" +#include "adjuster.h" + +class ClutComboBox : public MyComboBox +{ +public: + int fillFromDir( Glib::ustring path ); + Glib::ustring getSelectedClut(); + void setSelectedClut( Glib::ustring filename ); + void addUnchangedEntry(); + +private: + class ClutColumns : public Gtk::TreeModel::ColumnRecord + { + public: + Gtk::TreeModelColumn label; + Gtk::TreeModelColumn clutFilename; + ClutColumns(); + }; + + int parseDir( Glib::ustring path, Gtk::TreeModel::Row *parentRow ); + Gtk::TreeIter findRowByClutFilename( Gtk::TreeModel::Children childs, Glib::ustring filename ); + + Glib::RefPtr m_model; + ClutColumns m_columns; +}; + +class FilmSimulation : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel +{ +public: + FilmSimulation(); + + void adjusterChanged( Adjuster* a, double newval ); + void setBatchMode( bool batchMode ); + void read( const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = NULL ); + void write( rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = NULL ); + void setAdjusterBehavior( bool strength ); + void trimValues( rtengine::procparams::ProcParams* pp ); + +private: + void onClutSelected(); + void enabledChanged(); + + void updateDisable( bool value ); + + ClutComboBox *m_clutComboBox; + sigc::connection m_clutComboBoxConn; + Glib::ustring m_oldClutFilename; + + Adjuster *m_strength; +}; + +#endif diff --git a/rtgui/filterpanel.cc b/rtgui/filterpanel.cc new file mode 100644 index 000000000..ab746a9fa --- /dev/null +++ b/rtgui/filterpanel.cc @@ -0,0 +1,330 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "filterpanel.h" +#include "multilangmgr.h" +#include "../rtengine/rtengine.h" +#include "rtimage.h" + +using namespace rtengine; + +FilterPanel::FilterPanel () : listener (NULL) { + + set_border_width (4); + + enabled = Gtk::manage (new Gtk::CheckButton (M("EXIFFILTER_METADATAFILTER"))); + pack_start (*enabled, Gtk::PACK_SHRINK, 2); + pack_start (*Gtk::manage(new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 2); + + enaFNumber = Gtk::manage (new Gtk::CheckButton (M("EXIFFILTER_APERTURE")+":")); + Gtk::VBox* fnvb = Gtk::manage(new Gtk::VBox ()); + Gtk::HBox* fnhb = Gtk::manage(new Gtk::HBox ()); + fnvb->pack_start (*enaFNumber, Gtk::PACK_SHRINK, 0); + fnumberFrom = Gtk::manage(new Gtk::Entry ()); + fnumberTo = Gtk::manage(new Gtk::Entry ()); + fnhb->pack_start (*fnumberFrom, true, true, 2); + fnhb->pack_start (*Gtk::manage(new Gtk::Label(" - ")), false, false, 4); + fnhb->pack_start (*fnumberTo, true, true, 2); + fnvb->pack_start (*fnhb, Gtk::PACK_SHRINK, 0); + pack_start (*fnvb, Gtk::PACK_SHRINK, 4); + + enaShutter = Gtk::manage(new Gtk::CheckButton(M("EXIFFILTER_SHUTTER")+":")); + Gtk::VBox* svb = Gtk::manage(new Gtk::VBox ()); + Gtk::HBox* shb = Gtk::manage(new Gtk::HBox ()); + svb->pack_start (*enaShutter, Gtk::PACK_SHRINK, 0); + shutterFrom = Gtk::manage(new Gtk::Entry ()); + shutterTo = Gtk::manage(new Gtk::Entry ()); + shb->pack_start (*shutterFrom, true, true, 2); + shb->pack_start (*Gtk::manage(new Gtk::Label(" - ")), false, false, 4); + shb->pack_start (*shutterTo, true, true, 2); + svb->pack_start (*shb, Gtk::PACK_SHRINK, 0); + pack_start (*svb, Gtk::PACK_SHRINK, 4); + + enaISO = Gtk::manage(new Gtk::CheckButton(M("EXIFFILTER_ISO")+":")); + Gtk::VBox* ivb = Gtk::manage(new Gtk::VBox ()); + Gtk::HBox* ihb = Gtk::manage(new Gtk::HBox ()); + ivb->pack_start (*enaISO, Gtk::PACK_SHRINK, 0); + isoFrom = Gtk::manage(new Gtk::Entry ()); + isoTo = Gtk::manage(new Gtk::Entry ()); + ihb->pack_start (*isoFrom, true, true, 2); + ihb->pack_start (*Gtk::manage(new Gtk::Label(" - ")), false, false, 4); + ihb->pack_start (*isoTo, true, true, 2); + ivb->pack_start (*ihb, Gtk::PACK_SHRINK, 0); + pack_start (*ivb, Gtk::PACK_SHRINK, 4); + + enaFocalLen = Gtk::manage(new Gtk::CheckButton(M("EXIFFILTER_FOCALLEN")+":")); + Gtk::VBox* fvb = Gtk::manage(new Gtk::VBox ()); + Gtk::HBox* fhb = Gtk::manage(new Gtk::HBox ()); + fvb->pack_start (*enaFocalLen, Gtk::PACK_SHRINK, 0); + focalFrom = Gtk::manage(new Gtk::Entry ()); + focalTo = Gtk::manage(new Gtk::Entry ()); + fhb->pack_start (*focalFrom, true, true, 2); + fhb->pack_start (*Gtk::manage(new Gtk::Label(" - ")), false, false, 4); + fhb->pack_start (*focalTo, true, true, 2); + fvb->pack_start (*fhb, Gtk::PACK_SHRINK, 0); + pack_start (*fvb, Gtk::PACK_SHRINK, 4); + + enaExpComp = Gtk::manage(new Gtk::CheckButton(M("EXIFFILTER_EXPOSURECOMPENSATION")+":")); + Gtk::VBox* evb = Gtk::manage(new Gtk::VBox ()); + evb->pack_start (*enaExpComp, Gtk::PACK_SHRINK, 0); + expcomp = Gtk::manage(new Gtk::ListViewText (1, false, Gtk::SELECTION_MULTIPLE)); + expcomp->set_headers_visible (false); + Gtk::ScrolledWindow* sexpcomp = Gtk::manage(new Gtk::ScrolledWindow()); + sexpcomp->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS); + sexpcomp->set_size_request(-1, 80); + sexpcomp->add(*expcomp); + evb->pack_start (*sexpcomp, Gtk::PACK_SHRINK, 0); + pack_start (*evb, Gtk::PACK_SHRINK, 4); + + enaCamera = Gtk::manage(new Gtk::CheckButton(M("EXIFFILTER_CAMERA")+":")); + Gtk::VBox* cvb = Gtk::manage(new Gtk::VBox ()); + cvb->pack_start (*enaCamera, Gtk::PACK_SHRINK, 0); + camera = Gtk::manage(new Gtk::ListViewText (1, false, Gtk::SELECTION_MULTIPLE)); + camera->set_headers_visible (false); + Gtk::ScrolledWindow* scamera = Gtk::manage(new Gtk::ScrolledWindow()); + scamera->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS); + scamera->set_size_request(-1, 80); + scamera->add(*camera); + cvb->pack_start (*scamera, Gtk::PACK_SHRINK, 0); + pack_start (*cvb, Gtk::PACK_SHRINK, 4); + + enaLens = Gtk::manage(new Gtk::CheckButton(M("EXIFFILTER_LENS")+":")); + Gtk::VBox* lvb = Gtk::manage(new Gtk::VBox ()); + lvb->pack_start (*enaLens, Gtk::PACK_SHRINK, 0); + lens = Gtk::manage(new Gtk::ListViewText (1, false, Gtk::SELECTION_MULTIPLE)); + lens->set_headers_visible (false); + Gtk::ScrolledWindow* slens = Gtk::manage(new Gtk::ScrolledWindow()); + slens->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS); + slens->set_size_request(-1, 80); + slens->add(*lens); + lvb->pack_start (*slens, Gtk::PACK_SHRINK, 0); + pack_start (*lvb, Gtk::PACK_SHRINK, 4); + + enaFiletype = Gtk::manage(new Gtk::CheckButton(M("EXIFFILTER_FILETYPE")+":")); + Gtk::VBox* ftvb = Gtk::manage(new Gtk::VBox ()); + ftvb->pack_start (*enaFiletype, Gtk::PACK_SHRINK, 0); + filetype = Gtk::manage(new Gtk::ListViewText (1, false, Gtk::SELECTION_MULTIPLE)); + filetype->set_headers_visible (false); + Gtk::ScrolledWindow* sfiletype = Gtk::manage(new Gtk::ScrolledWindow()); + sfiletype->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS); + sfiletype->set_size_request(-1, 80); + sfiletype->add(*filetype); + ftvb->pack_start (*sfiletype, Gtk::PACK_SHRINK, 0); + pack_start (*ftvb, 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); + + conns = 0; + sChange[conns++] = fnumberFrom->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged)); + sChange[conns++] = fnumberTo->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged)); + sChange[conns++] = shutterFrom->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged)); + sChange[conns++] = shutterTo->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged)); + sChange[conns++] = isoFrom->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged)); + sChange[conns++] = isoTo->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged)); + sChange[conns++] = focalFrom->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged)); + sChange[conns++] = focalTo->signal_changed().connect (sigc::mem_fun(*this, &FilterPanel::valueChanged)); + sChange[conns++] = expcomp->get_selection()->signal_changed().connect(sigc::mem_fun(*this, &FilterPanel::valueChanged)); + sChange[conns++] = filetype->get_selection()->signal_changed().connect(sigc::mem_fun(*this, &FilterPanel::valueChanged)); + sChange[conns++] = camera->get_selection()->signal_changed().connect(sigc::mem_fun(*this, &FilterPanel::valueChanged)); + sChange[conns++] = lens->get_selection()->signal_changed().connect(sigc::mem_fun(*this, &FilterPanel::valueChanged)); + sChange[conns++] = enaFNumber->signal_toggled().connect( sigc::mem_fun(*this, &FilterPanel::valueChanged) ); + sChange[conns++] = enaShutter->signal_toggled().connect( sigc::mem_fun(*this, &FilterPanel::valueChanged) ); + sChange[conns++] = enaFocalLen->signal_toggled().connect( sigc::mem_fun(*this, &FilterPanel::valueChanged) ); + sChange[conns++] = enaISO->signal_toggled().connect( sigc::mem_fun(*this, &FilterPanel::valueChanged) ); + sChange[conns++] = enaExpComp->signal_toggled().connect( sigc::mem_fun(*this, &FilterPanel::valueChanged) ); + sChange[conns++] = enaCamera->signal_toggled().connect( sigc::mem_fun(*this, &FilterPanel::valueChanged) ); + sChange[conns++] = enaLens->signal_toggled().connect( sigc::mem_fun(*this, &FilterPanel::valueChanged) ); + sChange[conns++] = enabled->signal_toggled().connect( sigc::mem_fun(*this, &FilterPanel::valueChanged) ); + sChange[conns++] = enaFiletype->signal_toggled().connect( sigc::mem_fun(*this, &FilterPanel::valueChanged) ); + + set_size_request (0, -1); + + show_all (); +} + +void FilterPanel::setFilter (ExifFilterSettings& defefs, bool updateLists) { + + + for (int i=0; iset_active (curefs.filterFNumber); + fnumberFrom->set_text (ImageMetaData::apertureToString (defefs.fnumberFrom)); + curefs.fnumberFrom = defefs.fnumberFrom; + fnumberTo->set_text (ImageMetaData::apertureToString (defefs.fnumberTo)); + curefs.fnumberTo = defefs.fnumberTo; + +// enaShutter->set_active (curefs.filterShutter); + shutterFrom->set_text (ImageMetaData::shutterToString (defefs.shutterFrom)); + curefs.shutterFrom = defefs.shutterFrom; + shutterTo->set_text (ImageMetaData::shutterToString (defefs.shutterTo)); + curefs.shutterTo = defefs.shutterTo; + +// enaISO->set_active (curefs.filterISO); + isoFrom->set_text (Glib::ustring::format (defefs.isoFrom)); + curefs.isoFrom = defefs.isoFrom; + isoTo->set_text (Glib::ustring::format (defefs.isoTo)); + curefs.isoTo = defefs.isoTo; + +// enaFocalLen->set_active (curefs.filterFocalLen); + focalFrom->set_text (Glib::ustring::format (defefs.focalFrom)); + curefs.focalFrom = defefs.focalFrom; + focalTo->set_text (Glib::ustring::format (defefs.focalTo)); + curefs.focalTo = defefs.focalTo; + +// enaCompExp->set_active (curefs.filterExpComp); + Glib::RefPtr eselection = expcomp->get_selection (); + +// enaFiletype->set_active (curefs.filterFiletype); + Glib::RefPtr ftselection = filetype->get_selection (); + +// enaCamera->set_active (curefs.filterCamera); + Glib::RefPtr cselection = camera->get_selection (); + +// enaLens->set_active (curefs.filterLens); + Glib::RefPtr lselection = lens->get_selection (); + if( updateLists ){ + expcomp->clear_items(); + curefs.expcomp.clear(); + for (std::set::iterator i = defefs.expcomp.begin(); i!=defefs.expcomp.end(); i++) { + expcomp->append_text (*i); + curefs.expcomp.insert(*i); + } + eselection->select_all(); + + lens->clear_items(); + curefs.lenses.clear(); + for (std::set::iterator i = defefs.lenses.begin(); i!=defefs.lenses.end(); i++) { + lens->append_text (*i); + curefs.lenses.insert(*i); + } + lselection->select_all(); + + camera->clear_items(); + curefs.cameras.clear(); + for (std::set::iterator i = defefs.cameras.begin(); i!=defefs.cameras.end(); i++) { + camera->append_text(*i); + curefs.cameras.insert(*i); + } + cselection->select_all(); + + filetype->clear_items(); + curefs.filetypes.clear(); + for (std::set::iterator i = defefs.filetypes.begin(); i!=defefs.filetypes.end(); i++) { + filetype->append_text(*i); + curefs.filetypes.insert(*i); + } + ftselection->select_all(); + }else{ + for( Gtk::TreeModel::Children::iterator iter = expcomp->get_model()->children().begin(); iter != expcomp->get_model()->children().end();iter++){ + Glib::ustring v; + iter->get_value(0,v); + if( defefs.expcomp.find( v ) != defefs.expcomp.end() ) + eselection->select( iter ); + else + eselection->unselect( iter ); + } + for( Gtk::TreeModel::Children::iterator iter = lens->get_model()->children().begin(); iter != lens->get_model()->children().end();iter++){ + Glib::ustring v; + iter->get_value(0,v); + if( defefs.lenses.find( v ) != defefs.lenses.end() ) + lselection->select( iter ); + else + lselection->unselect( iter ); + } + for( Gtk::TreeModel::Children::iterator iter = camera->get_model()->children().begin(); iter != camera->get_model()->children().end();iter++){ + Glib::ustring v; + iter->get_value(0,v); + if( defefs.cameras.find( v ) != defefs.cameras.end() ) + cselection->select(iter); + else + cselection->unselect(iter); + } + for( Gtk::TreeModel::Children::iterator iter = filetype->get_model()->children().begin(); iter != filetype->get_model()->children().end();iter++){ + Glib::ustring v; + iter->get_value(0,v); + if( defefs.filetypes.find( v ) != defefs.filetypes.end() ) + ftselection->select(iter); + else + ftselection->unselect(iter); + } + } + + curefs = defefs; + + for (int i=0; iget_active () && is_sensitive(); +} + +ExifFilterSettings FilterPanel::getFilter () { + + ExifFilterSettings efs; + efs.fnumberFrom = atof (fnumberFrom->get_text().c_str()); + efs.fnumberTo = atof (fnumberTo->get_text().c_str()); + efs.focalFrom = atof (focalFrom->get_text().c_str()); + 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.filterFNumber = enaFNumber->get_active (); + efs.filterShutter = enaShutter->get_active (); + efs.filterFocalLen = enaFocalLen->get_active (); + efs.filterISO = enaISO->get_active (); + efs.filterExpComp = enaExpComp->get_active (); + efs.filterCamera = enaCamera->get_active (); + efs.filterLens = enaLens->get_active (); + efs.filterFiletype = enaFiletype->get_active (); + + std::vector sel = camera->get_selected (); + for (size_t i=0; iget_text (sel[i])); + + sel = expcomp->get_selected (); + for (size_t i=0; iget_text (sel[i])); + + sel = lens->get_selected (); + for (size_t i=0; iget_text (sel[i])); + + sel = filetype->get_selected (); + for (size_t i=0; iget_text (sel[i])); + + return efs; +} + +// Called within GTK UI thread +void FilterPanel::valueChanged () { + + if (listener) + listener->exifFilterChanged (); +} diff --git a/rtgui/filterpanel.h b/rtgui/filterpanel.h new file mode 100644 index 000000000..3d2303b0c --- /dev/null +++ b/rtgui/filterpanel.h @@ -0,0 +1,75 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _FILTERPANEL_ +#define _FILTERPANEL_ + +#include +#include "exiffiltersettings.h" + +class FilterPanelListener { + + public: + virtual void exifFilterChanged () {} +}; + +class FilterPanel : public Gtk::VBox { + + protected: + Gtk::ListViewText* filetype; + Gtk::ListViewText* camera; + Gtk::ListViewText* lens; + Gtk::ListViewText* expcomp; + Gtk::Entry* fnumberFrom; + Gtk::Entry* fnumberTo; + Gtk::Entry* shutterFrom; + Gtk::Entry* shutterTo; + Gtk::Entry* focalFrom; + Gtk::Entry* focalTo; + Gtk::Entry* isoFrom; + Gtk::Entry* isoTo; + Gtk::CheckButton* enabled; + Gtk::CheckButton* enaFNumber; + Gtk::CheckButton* enaShutter; + Gtk::CheckButton* enaFocalLen; + Gtk::CheckButton* enaISO; + Gtk::CheckButton* enaExpComp; + Gtk::CheckButton* enaCamera; + Gtk::CheckButton* enaLens; + Gtk::CheckButton* enaFiletype; + + int conns; + sigc::connection sChange[22]; + + ExifFilterSettings curefs; + FilterPanelListener* listener; + + public: + FilterPanel (); + + void setFilterPanelListener (FilterPanelListener* l) { listener = l; } + + void setFilter (ExifFilterSettings& defefs, bool updateLists); + ExifFilterSettings getFilter (); + bool isEnabled (); + + void valueChanged (); + void setEnabled(bool enabledState){enabled->set_active(enabledState);} +}; + +#endif diff --git a/rtgui/flatcurveeditorsubgroup.cc b/rtgui/flatcurveeditorsubgroup.cc new file mode 100644 index 000000000..50ec1d1f3 --- /dev/null +++ b/rtgui/flatcurveeditorsubgroup.cc @@ -0,0 +1,544 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "clipboard.h" +#include +#include +#include +#include "guiutils.h" +#include "multilangmgr.h" +#include "guiutils.h" +#include "mycurve.h" +#include "shcselector.h" +#include "adjuster.h" +#include "mycurve.h" +#include "myflatcurve.h" +#include "curveeditor.h" +#include "flatcurveeditorsubgroup.h" + +FlatCurveEditorSubGroup::FlatCurveEditorSubGroup (CurveEditorGroup* prt, Glib::ustring& curveDir) : CurveEditorSubGroup(curveDir) { + + valLinear = (int)FCT_Linear; + valUnchanged = (int)FCT_Unchanged; + parent = prt; + + curveBBoxPos = options.curvebboxpos; + + // ControlPoints curve + CPointsCurveBox = new Gtk::VBox (); + CPointsCurveBox->set_spacing(4); + Gtk::HBox* CPointsCurveAndButtons = Gtk::manage (new Gtk::HBox ()); + CPointsCurveAndButtons->set_spacing(4); + CPointsCurve = Gtk::manage (new MyFlatCurve ()); + CPointsCurve->set_size_request (GRAPH_SIZE+2*RADIUS+1, GRAPH_SIZE+2*RADIUS+1); + CPointsCurve->setType (FCT_MinMaxCPoints); + + Gtk::Box* CPointsbbox; // curvebboxpos 0=above, 1=right, 2=below, 3=left + if (options.curvebboxpos==1 || options.curvebboxpos==3) { + CPointsbbox = Gtk::manage (new Gtk::VBox ()); + } else { + CPointsbbox = Gtk::manage (new Gtk::HBox ()); + } + CPointsbbox->set_spacing(4); + + pasteCPoints = Gtk::manage (new Gtk::Button ()); + pasteCPoints->add (*Gtk::manage (new RTImage ("edit-paste.png"))); + copyCPoints = Gtk::manage (new Gtk::Button ()); + copyCPoints->add (*Gtk::manage (new RTImage ("edit-copy.png"))); + saveCPoints = Gtk::manage (new Gtk::Button ()); + saveCPoints->add (*Gtk::manage (new RTImage ("gtk-save-large.png"))); + loadCPoints = Gtk::manage (new Gtk::Button ()); + loadCPoints->add (*Gtk::manage (new RTImage ("gtk-open.png"))); + editCPoints = Gtk::manage (new Gtk::ToggleButton()); + editPointCPoints = Gtk::manage (new Gtk::ToggleButton ()); + editPointCPoints->add (*Gtk::manage (new RTImage ("gtk-edit.png"))); + editPointCPoints->set_tooltip_text(M("CURVEEDITOR_EDITPOINT_HINT")); + editCPoints->add (*Gtk::manage (new RTImage ("editmodehand.png"))); + editCPoints->set_tooltip_text(M("EDIT_PIPETTE_TOOLTIP")); + editCPoints->hide(); + + CPointsbbox->pack_end (*pasteCPoints, Gtk::PACK_SHRINK, 0); + CPointsbbox->pack_end (*copyCPoints, Gtk::PACK_SHRINK, 0); + CPointsbbox->pack_end (*saveCPoints, Gtk::PACK_SHRINK, 0); + CPointsbbox->pack_end (*loadCPoints, Gtk::PACK_SHRINK, 0); + CPointsbbox->pack_start(*editPointCPoints, Gtk::PACK_SHRINK, 0); + CPointsbbox->pack_start(*editCPoints, Gtk::PACK_SHRINK, 0); + + CPointsCurveAndButtons->pack_start (*CPointsCurve, Gtk::PACK_EXPAND_WIDGET, 0); + CPointsCurveAndButtons->pack_start (*CPointsbbox, Gtk::PACK_SHRINK, 0); + CPointsCurveBox->pack_start (*CPointsCurveAndButtons, Gtk::PACK_EXPAND_WIDGET); + if (options.curvebboxpos==0) { + removeIfThere (CPointsCurveAndButtons, CPointsbbox, false); + CPointsCurveBox->pack_start (*CPointsbbox); + CPointsCurveBox->reorder_child(*CPointsbbox, 0); + } else if (options.curvebboxpos==2) { + removeIfThere (CPointsCurveAndButtons, CPointsbbox, false); + CPointsCurveBox->pack_start (*CPointsbbox); + } else if (options.curvebboxpos==3) { + CPointsCurveAndButtons->reorder_child(*CPointsbbox, 0); + } + + { + std::vector axis; + axis.resize(4); + axis.at(0).setValues(M("CURVEEDITOR_AXIS_IN"), 5, 0.001, 0.01, 0., 1.); + axis.at(1).setValues(M("CURVEEDITOR_AXIS_OUT"), 5, 0.001, 0.01, 0., 1.); + axis.at(2).setValues(M("CURVEEDITOR_AXIS_LEFT_TAN"), 5, 0.01, 0.1, 0., 1.); + axis.at(3).setValues(M("CURVEEDITOR_AXIS_RIGHT_TAN"), 5, 0.01, 0.1, 0., 1.); + CPointsCoordAdjuster = Gtk::manage (new CoordinateAdjuster(CPointsCurve, this, axis)); + CPointsCurveBox->pack_start(*CPointsCoordAdjuster, Gtk::PACK_SHRINK, 0); + if (options.curvebboxpos == 2) + CPointsCurveBox->reorder_child(*CPointsCoordAdjuster, 2); + CPointsCoordAdjuster->show_all(); + } + + CPointsCurveBox->show_all (); + CPointsCoordAdjuster->hide(); + + saveCPoints->signal_clicked().connect( sigc::mem_fun(*this, &FlatCurveEditorSubGroup::savePressed) ); + loadCPoints->signal_clicked().connect( sigc::mem_fun(*this, &FlatCurveEditorSubGroup::loadPressed) ); + copyCPoints->signal_clicked().connect( sigc::mem_fun(*this, &FlatCurveEditorSubGroup::copyPressed) ); + pasteCPoints->signal_clicked().connect( sigc::mem_fun(*this, &FlatCurveEditorSubGroup::pastePressed) ); + editPointCPointsConn = editPointCPoints->signal_toggled().connect( sigc::bind(sigc::mem_fun(*this, &FlatCurveEditorSubGroup::editPointToggled), editPointCPoints) ); + editCPointsConn = editCPoints->signal_toggled().connect( sigc::bind(sigc::mem_fun(*this, &FlatCurveEditorSubGroup::editToggled), editCPoints) ); + + saveCPoints->set_tooltip_text (M("CURVEEDITOR_TOOLTIPSAVE")); + loadCPoints->set_tooltip_text (M("CURVEEDITOR_TOOLTIPLOAD")); + copyCPoints->set_tooltip_text (M("CURVEEDITOR_TOOLTIPCOPY")); + pasteCPoints->set_tooltip_text (M("CURVEEDITOR_TOOLTIPPASTE")); + + CPointsCurve->setCurveListener (parent); // Send the message directly to the parent +} + +FlatCurveEditorSubGroup::~FlatCurveEditorSubGroup() { + delete CPointsCurveBox; +} + +/* + * Add a new curve to the curves list + */ +FlatCurveEditor* FlatCurveEditorSubGroup::addCurve(Glib::ustring curveLabel, bool isPeriodic) { + FlatCurveEditor* newCE = new FlatCurveEditor(curveLabel, parent, this, isPeriodic); + + // Initialization of the new curve + storeCurveValues(newCE, getCurveFromGUI(FCT_MinMaxCPoints)); + return newCE; +} + +void FlatCurveEditorSubGroup::showCoordinateAdjuster(CoordinateProvider *provider) { + if (provider == CPointsCurve) { + if (!editPointCPoints->get_active()) editPointCPoints->set_active(true); + } +} + +void FlatCurveEditorSubGroup::stopNumericalAdjustment() { + CPointsCurve->stopNumericalAdjustment(); +} + + +/* + * Force the resize of the curve editor, if the displayed one is the requested one + */ +void FlatCurveEditorSubGroup::refresh(CurveEditor *curveToRefresh) { + if (curveToRefresh != NULL && curveToRefresh == static_cast(parent->displayedCurve)) { + switch(FlatCurveType(curveToRefresh->curveType->getSelected())) { + case (FCT_MinMaxCPoints): + CPointsCurve->refresh(); + break; + default: // (DCT_Linear, DCT_Unchanged) + // ... do nothing + break; + } + } +} + +/* + * Switch off the edit button + */ +void FlatCurveEditorSubGroup::editModeSwitchedOff () { + // toggling off all edit buttons, even if only one is toggle on + bool prevState = editCPointsConn.block(true); + editCPoints->set_active(false); + CPointsCurve->pipetteMouseOver(NULL, NULL, 0); + CPointsCurve->setDirty(true); + if (!prevState) editCPointsConn.block(false); +} + +void FlatCurveEditorSubGroup::pipetteMouseOver(EditDataProvider *provider, int modifierKey) { + CurveEditor *curveEditor = static_cast(parent->displayedCurve); + switch((FlatCurveType)(curveEditor->curveType->getSelected())) { + case (FCT_MinMaxCPoints): + CPointsCurve->pipetteMouseOver(curveEditor, provider, modifierKey); + CPointsCurve->setDirty(true); + break; + default: // (DCT_Linear, DCT_Unchanged) + // ... do nothing + break; + } +} + +void FlatCurveEditorSubGroup::pipetteButton1Pressed(EditDataProvider *provider, int modifierKey) { + CurveEditor *curveEditor = static_cast(parent->displayedCurve); + switch((FlatCurveType)(curveEditor->curveType->getSelected())) { + case (FCT_MinMaxCPoints): + CPointsCurve->pipetteButton1Pressed(provider, modifierKey); + CPointsCurve->setDirty(true); + break; + default: // (DCT_Linear, DCT_Unchanged) + // ... do nothing + break; + } +} + +void FlatCurveEditorSubGroup::pipetteButton1Released(EditDataProvider *provider) { + CurveEditor *curveEditor = static_cast(parent->displayedCurve); + switch((FlatCurveType)(curveEditor->curveType->getSelected())) { + case (FCT_MinMaxCPoints): + CPointsCurve->pipetteButton1Released(provider); + CPointsCurve->setDirty(true); + break; + default: // (DCT_Linear, DCT_Unchanged) + // ... do nothing + break; + } +} + +void FlatCurveEditorSubGroup::pipetteDrag(EditDataProvider *provider, int modifierKey) { + CurveEditor *curveEditor = static_cast(parent->displayedCurve); + switch((FlatCurveType)(curveEditor->curveType->getSelected())) { + case (FCT_MinMaxCPoints): + CPointsCurve->pipetteDrag(provider, modifierKey); + CPointsCurve->setDirty(true); + break; + default: // (DCT_Linear, DCT_Unchanged) + // ... do nothing + break; + } +} + +/* + * Switch the editor widgets to the currently edited curve + */ +void FlatCurveEditorSubGroup::switchGUI() { + + removeEditor(); + + FlatCurveEditor* dCurve = static_cast(parent->displayedCurve); + + if (dCurve) { + + // Initializing GUI values + repacking the appropriated widget + //dCurve->typeconn.block(true); + + // first we update the colored bar + + ColorProvider *barColorProvider = dCurve->getLeftBarColorProvider(); + std::vector bgGradient = dCurve->getLeftBarBgGradient(); + if (barColorProvider == NULL && bgGradient.size() == 0) { + // dCurve has no left colored bar, so we delete the object + if (leftBar) { + delete leftBar; + leftBar = NULL; + } + } + else { + // dCurve has a ColorProvider or a background gradient defined, so we create/update the object + if (!leftBar) { + leftBar = new ColoredBar(RTO_Bottom2Top); + } + if (barColorProvider) { + bgGradient.clear(); + leftBar->setColorProvider(barColorProvider, dCurve->getLeftBarCallerId()); + leftBar->setBgGradient (bgGradient); + } + else { + leftBar->setColorProvider(NULL, -1); + leftBar->setBgGradient (bgGradient); + } + } + + barColorProvider = dCurve->getBottomBarColorProvider(); + bgGradient = dCurve->getBottomBarBgGradient(); + if (barColorProvider == NULL && bgGradient.size() == 0) { + // dCurve has no bottom colored bar, so we delete the object + if (bottomBar) { + delete bottomBar; + bottomBar = NULL; + } + } + else { + // dCurve ave a ColorProvider or a background gradient defined, so we create/update the object + if (!bottomBar) { + bottomBar = new ColoredBar(RTO_Left2Right); + } + if (barColorProvider) { + bgGradient.clear(); + bottomBar->setColorProvider(barColorProvider, dCurve->getBottomBarCallerId()); + bottomBar->setBgGradient (bgGradient); + } + else { + bottomBar->setColorProvider(NULL, -1); + bottomBar->setBgGradient (bgGradient); + } + } + + switch((FlatCurveType)(dCurve->curveType->getSelected())) { + case (FCT_MinMaxCPoints): + CPointsCurve->setPeriodicity(dCurve->periodic); // Setting Periodicity before setting points + CPointsCurve->setPoints (dCurve->controlPointsCurveEd); + CPointsCurve->setColorProvider(dCurve->getCurveColorProvider(), dCurve->getCurveCallerId()); + CPointsCurve->setColoredBar(leftBar, bottomBar); + CPointsCurve->forceResize(); + updateEditButton(dCurve, editCPoints, editCPointsConn); + parent->pack_start (*CPointsCurveBox); + CPointsCurveBox->check_resize(); + break; + default: // (DCT_Linear, DCT_Unchanged) + // ... do nothing + break; + } + + //dCurve->typeconn.block(false); + } +} + +void FlatCurveEditorSubGroup::savePressed () { + + Glib::ustring fname = outputFile(); + if (fname.size()) { + std::ofstream f (fname.c_str()); + std::vector p; + //std::vector p = customCurve->getPoints (); + + switch (parent->displayedCurve->selected) { + case FCT_MinMaxCPoints: // Control points + p = CPointsCurve->getPoints (); + break; + default: + break; + } + + int ix = 0; + if (p[ix]==(double)(FCT_Linear)) + f << "Linear" << std::endl; + else if (p[ix]==(double)(FCT_MinMaxCPoints)) + f << "ControlPoints" << std::endl; + ix++; + for (unsigned int i=0; i p; + std::string s; + f >> s; + if (s=="Linear") + p.push_back ((double)(FCT_Linear)); + else if (s=="ControlPoints") + p.push_back ((double)(FCT_MinMaxCPoints)); + else return; + double x; + while (f) { + f >> x; + if (f) + p.push_back (x); + } + if (p[0] == (double)(FCT_MinMaxCPoints)) { + CPointsCurve->setPoints (p); + CPointsCurve->queue_draw (); + CPointsCurve->notifyListener (); + } + } + } +} + +void FlatCurveEditorSubGroup::copyPressed () { +// For compatibility use enum FlatCurveType here + + std::vector curve; + + switch (parent->displayedCurve->selected) { + case FCT_MinMaxCPoints: // custom + curve = CPointsCurve->getPoints (); + clipboard.setFlatCurveData (curve,FCT_MinMaxCPoints); + break; + default: // (DCT_Linear, DCT_Unchanged) + // ... do nothing + break; + } +} + +void FlatCurveEditorSubGroup::pastePressed () { +// For compatibility use enum FlatCurveType here + + std::vector curve; + FlatCurveType type; + + type = clipboard.hasFlatCurveData(); + + if (type == (FlatCurveType)parent->displayedCurve->selected) { + curve = clipboard.getFlatCurveData (); + switch (type) { + case FCT_MinMaxCPoints: // min/max control points + CPointsCurve->setPoints (curve); + CPointsCurve->queue_draw (); + CPointsCurve->notifyListener (); + break; + default: // (FCT_Linear, FCT_Unchanged) + // ... do nothing + break; + } + } + return; +} + +void FlatCurveEditorSubGroup::editPointToggled(Gtk::ToggleButton *button) { + if (button->get_active()) + CPointsCoordAdjuster->show(); + else { + CPointsCurve->stopNumericalAdjustment(); + CPointsCoordAdjuster->hide(); + } +} + +void FlatCurveEditorSubGroup::editToggled (Gtk::ToggleButton *button) { + FlatCurveEditor* dCurve = static_cast(parent->displayedCurve); + if (!dCurve) + // should never happen! + return; + + if (button->get_active()) { + dCurve->subscribe(); + CPointsCurve->notifyListener (); + + } + else { + dCurve->unsubscribe(); + } +} + + +/* + * Store the curves of the currently displayed type from the widgets to the CurveEditor object + */ +void FlatCurveEditorSubGroup::storeDisplayedCurve() { + if (parent->displayedCurve) { + switch (parent->displayedCurve->selected) { + /*case (FCT_Parametric): + storeCurveValues(parent->displayedCurve, getCurveFromGUI(FCT_Parametric)); + break;*/ + case (FCT_MinMaxCPoints): + storeCurveValues(parent->displayedCurve, getCurveFromGUI(FCT_MinMaxCPoints)); + break; + default: + break; + } + } +} + +/* + * Restore the histogram to all types from the CurveEditor object to the widgets + */ +void FlatCurveEditorSubGroup::restoreDisplayedHistogram() { + if (parent->displayedCurve) { + //paramCurve->updateBackgroundHistogram (parent->displayedCurve->histogram); + CPointsCurve->updateBackgroundHistogram (parent->displayedCurve->histogram); + } + +} + +void FlatCurveEditorSubGroup::storeCurveValues (CurveEditor* ce, const std::vector& p) { + if (!p.empty()) { + FlatCurveType t = static_cast(p[0]); + + switch (t) { + case (FCT_MinMaxCPoints): + static_cast(ce)->controlPointsCurveEd = p; + break; + default: + break; + } + } +} + +/* + * Called to update the parametric curve graph with new slider values + */ +const std::vector FlatCurveEditorSubGroup::getCurveFromGUI (int type) { + switch ((FlatCurveType)type) { + case (FCT_MinMaxCPoints): + return CPointsCurve->getPoints (); + default: { + // linear and other solutions + std::vector lcurve (1); + lcurve[0] = (double)(FCT_Linear); + return lcurve; + } + } +} + +/* + * Unlink the tree editor widgets from their parent box to hide them + */ +void FlatCurveEditorSubGroup::removeEditor () { + removeIfThere (parent, CPointsCurveBox, false); +} + +bool FlatCurveEditorSubGroup::curveReset(CurveEditor *ce) { + if (!ce) + return false; + + FlatCurveEditor *fce = static_cast(ce); + + switch (FlatCurveType(ce->selected)) { + case (FCT_MinMaxCPoints) : // = Control cage + CPointsCurve->reset (fce->controlPointsResetCurve, fce->getIdentityValue()); + return true; + break; + /*case (FCT_Parametric) : + highlights->resetPressed(); + lights->resetPressed(); + darks->resetPressed(); + shadows->resetPressed(); + shcSelector->reset(); + paramCurve->reset (); + return true; + break;*/ + default: + return false; + break; + } + return true; +} + +/*void FlatCurveEditorSubGroup::updateBackgroundHistogram (CurveEditor* ce) { + CurveEditor* fce = (CurveEditor*)ce; + if (fce==displayedCurve) { + paramCurve->updateBackgroundHistogram (fce->bgHistValid ? fce->histogram : NULL); + customCurve->updateBackgroundHistogram (fce->bgHistValid ? fce->histogram : NULL); + NURBSCurve->updateBackgroundHistogram (fce->bgHistValid ? fce->histogram : NULL); + } +}*/ diff --git a/rtgui/flatcurveeditorsubgroup.h b/rtgui/flatcurveeditorsubgroup.h new file mode 100644 index 000000000..e937dd362 --- /dev/null +++ b/rtgui/flatcurveeditorsubgroup.h @@ -0,0 +1,78 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _FLATCURVEEDITORSUBGROUP_ +#define _FLATCURVEEDITORSUBGROUP_ + +#include +#include "curveeditorgroup.h" + +class FlatCurveEditor; + +class FlatCurveEditorSubGroup: public CurveEditorSubGroup { + + friend class FlatCurveEditor; + +protected: + Gtk::VBox* CPointsCurveBox; + + MyFlatCurve* CPointsCurve; + + CoordinateAdjuster *CPointsCoordAdjuster; + + Gtk::Button* saveCPoints; + Gtk::Button* loadCPoints; + Gtk::Button* copyCPoints; + Gtk::Button* pasteCPoints; + Gtk::ToggleButton* editPointCPoints; + Gtk::ToggleButton* editCPoints; + sigc::connection editCPointsConn, editPointCPointsConn; + +public: + FlatCurveEditorSubGroup(CurveEditorGroup* prt, Glib::ustring& curveDir); + virtual ~FlatCurveEditorSubGroup(); + + FlatCurveEditor* addCurve(Glib::ustring curveLabel = "", bool periodic = true); + //virtual void updateBackgroundHistogram (CurveEditor* ce); + void switchGUI(); + void refresh(CurveEditor *curveToRefresh); + void editModeSwitchedOff(); + void pipetteMouseOver(EditDataProvider *provider, int modifierKey); + void pipetteButton1Pressed(EditDataProvider *provider, int modifierKey); + void pipetteButton1Released(EditDataProvider *provider); + void pipetteDrag(EditDataProvider *provider, int modifierKey); + void showCoordinateAdjuster(CoordinateProvider *provider); + void stopNumericalAdjustment(); + + bool curveReset (CurveEditor *ce); + +protected: + void storeCurveValues (CurveEditor* ce, const std::vector& p); + void storeDisplayedCurve (); + void restoreDisplayedHistogram (); + void savePressed (); + void loadPressed (); + void copyPressed (); + void pastePressed (); + void removeEditor (); + const std::vector getCurveFromGUI (int type); + void editPointToggled(Gtk::ToggleButton *button); + void editToggled (Gtk::ToggleButton *button); +}; + +#endif diff --git a/rtgui/flatfield.cc b/rtgui/flatfield.cc new file mode 100755 index 000000000..901090aea --- /dev/null +++ b/rtgui/flatfield.cc @@ -0,0 +1,380 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "flatfield.h" +#include "options.h" +#include "guiutils.h" +#include "../rtengine/safegtk.h" +#include +#include "rtimage.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +FlatField::FlatField () : FoldableToolPanel(this, "flatfield", M("TP_FLATFIELD_LABEL")) +{ + hbff = Gtk::manage(new Gtk::HBox()); + hbff->set_spacing(2); + flatFieldFile = Gtk::manage(new MyFileChooserButton(M("TP_FLATFIELD_LABEL"), Gtk::FILE_CHOOSER_ACTION_OPEN)); + flatFieldFilePersister.reset(new FileChooserLastFolderPersister(flatFieldFile, options.lastFlatfieldDir)); + ffLabel = Gtk::manage(new Gtk::Label(M("GENERAL_FILE"))); + flatFieldFileReset = Gtk::manage(new Gtk::Button()); + flatFieldFileReset->set_image (*Gtk::manage(new RTImage ("gtk-cancel.png"))); + hbff->pack_start(*ffLabel, Gtk::PACK_SHRINK, 0); + hbff->pack_start(*flatFieldFile); + hbff->pack_start(*flatFieldFileReset, Gtk::PACK_SHRINK, 0); + flatFieldAutoSelect = Gtk::manage(new Gtk::CheckButton((M("TP_FLATFIELD_AUTOSELECT")))); + ffInfo = Gtk::manage(new Gtk::Label("")); + ffInfo->set_alignment(0,0); //left align + flatFieldBlurRadius = Gtk::manage(new Adjuster (M("TP_FLATFIELD_BLURRADIUS"),0,200,2,32)); + flatFieldBlurRadius->setAdjusterListener (this); + if (flatFieldBlurRadius->delay < 1000) flatFieldBlurRadius->delay = 1000; + flatFieldBlurRadius->show(); + + Gtk::HBox* hbffbt = Gtk::manage (new Gtk::HBox ()); + hbffbt->pack_start (*Gtk::manage (new Gtk::Label ( M("TP_FLATFIELD_BLURTYPE") +":"))); + hbffbt->set_spacing(4); + flatFieldBlurType = Gtk::manage (new MyComboBoxText ()); + flatFieldBlurType->append_text(M("TP_FLATFIELD_BT_AREA")); + flatFieldBlurType->append_text(M("TP_FLATFIELD_BT_VERTICAL")); + flatFieldBlurType->append_text(M("TP_FLATFIELD_BT_HORIZONTAL")); + flatFieldBlurType->append_text(M("TP_FLATFIELD_BT_VERTHORIZ")); + flatFieldBlurType->set_active(0); + hbffbt->pack_end (*flatFieldBlurType); + + flatFieldClipControl = Gtk::manage (new Adjuster(M("TP_FLATFIELD_CLIPCONTROL"), 0., 100., 1., 0.)); + flatFieldClipControl->setAdjusterListener(this); + flatFieldClipControl->addAutoButton(""); + if (flatFieldClipControl->delay < 1000) flatFieldClipControl->delay = 1000; + flatFieldClipControl->show(); + flatFieldClipControl->set_tooltip_markup (M("TP_FLATFIELD_CLIPCONTROL_TOOLTIP")); + + pack_start( *hbff, Gtk::PACK_SHRINK, 0); + pack_start( *flatFieldAutoSelect, Gtk::PACK_SHRINK, 0); + pack_start( *ffInfo, Gtk::PACK_SHRINK, 0); + pack_start( *hbffbt, Gtk::PACK_SHRINK, 0); + 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); + 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) ); + lastShortcutPath = ""; + + // Set filename filters + b_filter_asCurrent = false; + Gtk::FileFilter *filter_any = Gtk::manage(new Gtk::FileFilter); + filter_any->add_pattern("*"); + filter_any->set_name(M("FILECHOOSER_FILTER_ANY")); + flatFieldFile->add_filter (*filter_any); + + // filters for all supported non-raw extensions + for (size_t i=0; iadd_pattern("*." + options.parseExtensions[i]); + filter_ff->add_pattern("*." + options.parseExtensions[i].uppercase()); + filter_ff->set_name(options.parseExtensions[i].uppercase()); + flatFieldFile->add_filter (*filter_ff); + //printf("adding filter %s \n",options.parseExtensions[i].uppercase().c_str()); + } + } +} + +void FlatField::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited) +{ + disableListener (); + flatFieldAutoSelectconn.block (true); + flatFieldBlurTypeconn.block (true); + + //flatFieldBlurType + for( size_t i=0; i< procparams::RAWParams::numFlatFileBlurTypes;i++) + if( pp->raw.ff_BlurType == procparams::RAWParams::ff_BlurTypestring[i]){ + flatFieldBlurType->set_active(i); + break; + } + + if (multiImage || pp->raw.ff_BlurType == procparams::RAWParams::ff_BlurTypestring[procparams::RAWParams::area_ff]) + flatFieldClipControl->show(); + else + flatFieldClipControl->hide(); + + flatFieldAutoSelect->set_active (pp->raw.ff_AutoSelect); + flatFieldBlurRadius->setValue (pp->raw.ff_BlurRadius); + flatFieldClipControl->setValue (pp->raw.ff_clipControl); + flatFieldClipControl->setAutoValue (pp->raw.ff_AutoClipControl); + + if(pedited ){ + flatFieldAutoSelect->set_inconsistent (!pedited->raw.ff_AutoSelect); + flatFieldBlurRadius->setEditedState( pedited->raw.ff_BlurRadius ? Edited : UnEdited ); + flatFieldClipControl->setEditedState( pedited->raw.ff_clipControl ? Edited : UnEdited ); + flatFieldClipControl->setAutoInconsistent(multiImage && !pedited->raw.ff_AutoClipControl); + if( !pedited->raw.ff_BlurType ) + flatFieldBlurType->set_active(procparams::RAWParams::numFlatFileBlurTypes); // No name + } + if (safe_file_test (pp->raw.ff_file, Glib::FILE_TEST_EXISTS)) + flatFieldFile->set_filename (pp->raw.ff_file); + else + flatFieldFile_Reset(); + hbff->set_sensitive( !pp->raw.ff_AutoSelect ); + + lastFFAutoSelect = pp->raw.ff_AutoSelect; + lastFFAutoClipCtrl = pp->raw.ff_AutoClipControl; + + if( pp->raw.ff_AutoSelect && ffp && !batchMode){ + // retrieve the auto-selected ff filename + rtengine::RawImage *img = ffp->getFF(); + if( img ){ + ffInfo->set_text( Glib::ustring::compose("%1: f/%2", Glib::path_get_basename(img->get_filename()), img->get_aperture()) ); // !!! need to add focallength in mm and format aperture to ##.# + }else{ + ffInfo->set_text(Glib::ustring(M("TP_PREPROCESS_NO_FOUND"))); + } + } + else ffInfo->set_text(""); + + ffChanged = false; + + flatFieldAutoSelectconn.block (false); + flatFieldBlurTypeconn.block (false); + enableListener (); + + // Add filter with the current file extension if the current file is raw + if (ffp && !batchMode){ + + if (b_filter_asCurrent){ + //First, remove last filter_asCurrent if it was set for a raw file + std::vector filters = flatFieldFile->list_filters(); + flatFieldFile->remove_filter(**(filters.end()-1)); + b_filter_asCurrent = false; + } + + Glib::ustring fname = Glib::path_get_basename(ffp->GetCurrentImageFilePath()); + Glib::ustring filetype; + + if (fname!=""){ + // get image filetype, set filter to the same as current image's filetype + std::string::size_type idx; + idx = fname.rfind('.'); + if(idx != std::string::npos){ + filetype = fname.substr(idx+1); + //exclude non-raw + israw = filetype.uppercase()!="JPG" && filetype.uppercase()!="JPEG" && filetype.uppercase()!="PNG" && filetype.uppercase()!="TIF" && filetype.uppercase()!="TIFF"; + + if (israw) + { + b_filter_asCurrent = true; //prevent re-adding this filter on every pp3 file read + Gtk::FileFilter *filter_asCurrent = Gtk::manage(new Gtk::FileFilter); + filter_asCurrent->add_pattern("*." + filetype); + filter_asCurrent->set_name(M("FILECHOOSER_FILTER_SAME") + " (" + filetype + ")"); + flatFieldFile->add_filter (*filter_asCurrent); + flatFieldFile->set_filter (*filter_asCurrent); + } + } + } + } + +} + +void FlatField::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pedited) +{ + pp->raw.ff_file = flatFieldFile->get_filename(); + pp->raw.ff_AutoSelect = flatFieldAutoSelect->get_active(); + pp->raw.ff_BlurRadius = flatFieldBlurRadius->getIntValue(); + pp->raw.ff_clipControl = flatFieldClipControl->getIntValue(); + pp->raw.ff_AutoClipControl = flatFieldClipControl->getAutoValue(); + + int currentRow = flatFieldBlurType->get_active_row_number(); + if( currentRow>=0 && currentRow < procparams::RAWParams::numFlatFileBlurTypes) + pp->raw.ff_BlurType = procparams::RAWParams::ff_BlurTypestring[currentRow]; + + if (pedited) { + pedited->raw.ff_file = ffChanged; + pedited->raw.ff_AutoSelect = !flatFieldAutoSelect->get_inconsistent(); + pedited->raw.ff_BlurRadius = flatFieldBlurRadius->getEditedState (); + pedited->raw.ff_clipControl = flatFieldClipControl->getEditedState (); + pedited->raw.ff_AutoClipControl = !flatFieldClipControl->getAutoInconsistent(); + pedited->raw.ff_BlurType = flatFieldBlurType->get_active_row_number() != procparams::RAWParams::numFlatFileBlurTypes; + } + +} + +void FlatField::adjusterChanged (Adjuster* a, double newval) +{ + if (listener) { + + Glib::ustring value = a->getTextValue(); + + if (a==flatFieldBlurRadius) + listener->panelChanged (EvFlatFieldBlurRadius, value); + else if (a==flatFieldClipControl) + listener->panelChanged (EvFlatFieldClipControl, value); + } +} + +void FlatField::adjusterAutoToggled (Adjuster* a, bool newval) { + + if (multiImage) { + if (flatFieldClipControl->getAutoInconsistent()) { + flatFieldClipControl->setAutoInconsistent(false); + flatFieldClipControl->setAutoValue(false); + } + else if (lastFFAutoClipCtrl) + flatFieldClipControl->setAutoInconsistent(true); + + lastFFAutoClipCtrl = flatFieldClipControl->getAutoValue(); + + } + + if (listener) { + if(a==flatFieldClipControl) { + if (flatFieldClipControl->getAutoInconsistent()) + listener->panelChanged (EvFlatFieldAutoClipControl, M("GENERAL_UNCHANGED")); + else if (flatFieldClipControl->getAutoValue()) + listener->panelChanged (EvFlatFieldAutoClipControl, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvFlatFieldAutoClipControl, M("GENERAL_DISABLED")); + } + } +} + +void FlatField::setBatchMode(bool batchMode) +{ + ToolPanel::setBatchMode (batchMode); + flatFieldBlurRadius->showEditedCB (); + flatFieldClipControl->showEditedCB (); +} + +void FlatField::setAdjusterBehavior (bool clipctrladd) { + flatFieldClipControl->setAddMode(clipctrladd); +} + +void FlatField::trimValues (rtengine::procparams::ProcParams* pp) { + flatFieldClipControl->trimValue(pp->raw.ff_clipControl); +} + +void FlatField::setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited) +{ + flatFieldBlurRadius->setDefault( defParams->raw.ff_BlurRadius); + flatFieldClipControl->setDefault( defParams->raw.ff_clipControl); + + if (pedited) { + flatFieldBlurRadius->setDefaultEditedState( pedited->raw.ff_BlurRadius ? Edited : UnEdited); + flatFieldClipControl->setDefaultEditedState( pedited->raw.ff_clipControl ? Edited : UnEdited); + } else { + flatFieldBlurRadius->setDefaultEditedState( Irrelevant ); + flatFieldClipControl->setDefaultEditedState( Irrelevant ); + } +} + +void FlatField::flatFieldFileChanged() +{ + ffChanged=true; + if (listener) + listener->panelChanged (EvFlatFieldFile, Glib::path_get_basename(flatFieldFile->get_filename())); +} + +void FlatField::flatFieldFile_Reset() +{ + ffChanged=true; + +// caution: I had to make this hack, because set_current_folder() doesn't work correctly! +// Because szeva doesn't exist since he was committed to happy hunting ground in Issue 316 +// we can use him now for this hack + flatFieldFile->set_filename (options.lastFlatfieldDir + "/szeva"); +// end of the hack + + if (!options.lastFlatfieldDir.empty()) + flatFieldFile->set_current_folder(options.lastFlatfieldDir); + + ffInfo->set_text(""); + if (listener) + listener->panelChanged (EvFlatFieldFile, M("GENERAL_NONE") ); +} + +void FlatField::flatFieldBlurTypeChanged () +{ + int curSelection = flatFieldBlurType->get_active_row_number(); + + Glib::ustring s=""; + if( curSelection>=0 && curSelection < procparams::RAWParams::numFlatFileBlurTypes) + s = flatFieldBlurType->get_active_text(); + + if (multiImage || curSelection == procparams::RAWParams::area_ff) + flatFieldClipControl->show(); + else + flatFieldClipControl->hide(); + + if (listener) + listener->panelChanged (EvFlatFieldBlurType, s); +} + +void FlatField::flatFieldAutoSelectChanged() +{ + if (batchMode) { + if (flatFieldAutoSelect->get_inconsistent()) { + flatFieldAutoSelect->set_inconsistent (false); + flatFieldAutoSelectconn.block (true); + flatFieldAutoSelect->set_active (false); + flatFieldAutoSelectconn.block (false); + } + else if (lastFFAutoSelect) + flatFieldAutoSelect->set_inconsistent (true); + + lastFFAutoSelect = flatFieldAutoSelect->get_active (); + } + hbff->set_sensitive( !flatFieldAutoSelect->get_active() ); + + if( flatFieldAutoSelect->get_active() && ffp && !batchMode){ + // retrieve the auto-selected ff filename + rtengine::RawImage *img = ffp->getFF(); + if( img ){ + ffInfo->set_text( Glib::ustring::compose("%1: f/%2", Glib::path_get_basename(img->get_filename()), img->get_aperture()) ); // !!! need to add focallength in mm and format aperture to ##.# + }else{ + ffInfo->set_text(Glib::ustring(M("TP_PREPROCESS_NO_FOUND"))); + } + } + else{ffInfo->set_text("");} + + if (listener) + listener->panelChanged (EvFlatFieldAutoSelect, flatFieldAutoSelect->get_active()?M("GENERAL_ENABLED"):M("GENERAL_DISABLED")); + +} + +void FlatField::setShortcutPath(Glib::ustring path) +{ + if (path == "") return; +#ifdef WIN32 + // Dirty workaround, waiting for a clean solution by using exceptions! + if (!safe_is_shortcut_dir(path)) +#endif + { + if (lastShortcutPath != "") { + try { + flatFieldFile->remove_shortcut_folder(lastShortcutPath); + } + catch (Glib::Error &err) {} + } + lastShortcutPath = path; + try { + flatFieldFile->add_shortcut_folder(path); + } + catch (Glib::Error &err) {} + } +} diff --git a/rtgui/flatfield.h b/rtgui/flatfield.h new file mode 100755 index 000000000..12f9dacba --- /dev/null +++ b/rtgui/flatfield.h @@ -0,0 +1,81 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _FLATFIELD_H_ +#define _FLATFIELD_H_ + +#include +#include +#include "adjuster.h" +#include "toolpanel.h" +#include "../rtengine/rawimage.h" +#include "guiutils.h" + +class FFProvider { + public: + virtual ~FFProvider() {} + virtual rtengine::RawImage* getFF() = 0; + virtual Glib::ustring GetCurrentImageFilePath() = 0; + // add other info here +}; + +class FlatField : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel { + +protected: + + MyFileChooserButton *flatFieldFile; + std::auto_ptr flatFieldFilePersister; + Gtk::Label *ffLabel; + Gtk::Label *ffInfo; + Gtk::Button *flatFieldFileReset; + Gtk::CheckButton* flatFieldAutoSelect; + Adjuster* flatFieldClipControl; + Adjuster* flatFieldBlurRadius; + MyComboBoxText* flatFieldBlurType; + Gtk::HBox *hbff; + bool ffChanged; + bool lastFFAutoSelect; + bool lastFFAutoClipCtrl; + FFProvider *ffp; + sigc::connection flatFieldFileconn, flatFieldAutoSelectconn, flatFieldBlurTypeconn; + Glib::ustring lastShortcutPath; + bool b_filter_asCurrent; + bool israw; + +public: + + FlatField (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + void setAdjusterBehavior (bool clipctrladd); + void trimValues (rtengine::procparams::ProcParams* pp); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + + void adjusterChanged (Adjuster* a, double newval); + void adjusterAutoToggled (Adjuster* a, bool newval); + void flatFieldFileChanged (); + void flatFieldFile_Reset (); + void flatFieldAutoSelectChanged (); + void flatFieldBlurTypeChanged (); + void setShortcutPath(Glib::ustring path); + void setFFProvider (FFProvider* p) { ffp = p; }; +}; + +#endif diff --git a/rtgui/gradient.cc b/rtgui/gradient.cc new file mode 100644 index 000000000..b9d8ffe12 --- /dev/null +++ b/rtgui/gradient.cc @@ -0,0 +1,509 @@ +/* + * This file is part of RawTherapee. + */ +#include "gradient.h" +#include "rtimage.h" +#include "../rtengine/rt_math.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +Gradient::Gradient () : FoldableToolPanel(this, "gradient", M("TP_GRADIENT_LABEL"), false, true), EditSubscriber(ET_OBJECTS), lastObject(-1), draggedPointOldAngle(-1000.) +{ + + editHBox = Gtk::manage (new Gtk::HBox()); + edit = Gtk::manage (new Gtk::ToggleButton()); + edit->add (*Gtk::manage (new RTImage ("editmodehand.png"))); + edit->set_tooltip_text(M("EDIT_OBJECT_TOOLTIP")); + editConn = edit->signal_toggled().connect( sigc::mem_fun(*this, &Gradient::editToggled) ); + editHBox->pack_start(*edit, Gtk::PACK_SHRINK, 0); + pack_start (*editHBox, Gtk::PACK_SHRINK, 0); + + strength = Gtk::manage (new Adjuster (M("TP_GRADIENT_STRENGTH"), -5, 5, 0.01, 0)); + strength->set_tooltip_text (M("TP_GRADIENT_STRENGTH_TOOLTIP")); + strength->setAdjusterListener (this); + + degree = Gtk::manage (new Adjuster (M("TP_GRADIENT_DEGREE"), -180, 180, 1, 0)); + degree->set_tooltip_text (M("TP_GRADIENT_DEGREE_TOOLTIP")); + degree->setAdjusterListener (this); + + feather = Gtk::manage (new Adjuster (M("TP_GRADIENT_FEATHER"), 0, 100, 1, 25)); + feather->set_tooltip_text (M("TP_GRADIENT_FEATHER_TOOLTIP")); + feather->setAdjusterListener (this); + + centerX = Gtk::manage (new Adjuster (M("TP_GRADIENT_CENTER_X"), -100, 100, 1, 0)); + centerX->set_tooltip_text (M("TP_GRADIENT_CENTER_X_TOOLTIP")); + centerX->setAdjusterListener (this); + + centerY = Gtk::manage (new Adjuster (M("TP_GRADIENT_CENTER_Y"), -100, 100, 1, 0)); + centerY->set_tooltip_text (M("TP_GRADIENT_CENTER_Y_TOOLTIP")); + centerY->setAdjusterListener (this); + + pack_start (*strength, Gtk::PACK_SHRINK, 0); + pack_start (*degree, Gtk::PACK_SHRINK, 0); + pack_start (*feather, Gtk::PACK_SHRINK, 0); + pack_start (*centerX, Gtk::PACK_SHRINK, 0); + pack_start (*centerY, Gtk::PACK_SHRINK, 0); + + // Instantiating the Editing geometry; positions will be initialized later + Line *hLine, *vLine, *featherLine[2]; + Circle *centerCircle; + + // Visible geometry + hLine = new Line(); hLine->innerLineWidth=2; + vLine = new Line(); + hLine->datum = vLine->datum = Geometry::IMAGE; + + featherLine[0] = new Line(); featherLine[0]->innerLineWidth=2; + featherLine[1] = new Line(); featherLine[1]->innerLineWidth=2; + featherLine[0]->datum = featherLine[1]->datum = Geometry::IMAGE; + + centerCircle = new Circle(); + centerCircle->datum = Geometry::IMAGE; + centerCircle->radiusInImageSpace = false; + centerCircle->radius = 6; + centerCircle->filled = true; + + EditSubscriber::visibleGeometry.push_back( hLine ); + EditSubscriber::visibleGeometry.push_back( vLine ); + EditSubscriber::visibleGeometry.push_back( featherLine[0] ); + EditSubscriber::visibleGeometry.push_back( featherLine[1] ); + EditSubscriber::visibleGeometry.push_back( centerCircle ); + + // MouseOver geometry + hLine = new Line(); hLine->innerLineWidth=2; + vLine = new Line(); + hLine->datum = vLine->datum = Geometry::IMAGE; + + featherLine[0] = new Line(); featherLine[0]->innerLineWidth=2; + featherLine[1] = new Line(); featherLine[1]->innerLineWidth=2; + featherLine[0]->datum = featherLine[1]->datum = Geometry::IMAGE; + + centerCircle = new Circle(); + centerCircle->datum = Geometry::IMAGE; + centerCircle->radiusInImageSpace = false; + centerCircle->radius = 30; + centerCircle->filled = true; + + EditSubscriber::mouseOverGeometry.push_back( hLine ); + EditSubscriber::mouseOverGeometry.push_back( vLine ); + EditSubscriber::mouseOverGeometry.push_back( featherLine[0] ); + EditSubscriber::mouseOverGeometry.push_back( featherLine[1] ); + EditSubscriber::mouseOverGeometry.push_back( centerCircle ); + + show_all(); +} + +Gradient::~Gradient() { + for (std::vector::const_iterator i = visibleGeometry.begin(); i != visibleGeometry.end(); ++i) { + delete *i; + } + for (std::vector::const_iterator i = mouseOverGeometry.begin(); i != mouseOverGeometry.end(); ++i) { + delete *i; + } +} + +void Gradient::read (const ProcParams* pp, const ParamsEdited* pedited) +{ + disableListener (); + + if (pedited) { + degree->setEditedState (pedited->gradient.degree ? Edited : UnEdited); + feather->setEditedState (pedited->gradient.feather ? Edited : UnEdited); + strength->setEditedState (pedited->gradient.strength ? Edited : UnEdited); + centerX->setEditedState (pedited->gradient.centerX ? Edited : UnEdited); + centerY->setEditedState (pedited->gradient.centerY ? Edited : UnEdited); + set_inconsistent (multiImage && !pedited->gradient.enabled); + } + + setEnabled(pp->gradient.enabled); + degree->setValue (pp->gradient.degree); + feather->setValue (pp->gradient.feather); + strength->setValue (pp->gradient.strength); + centerX->setValue (pp->gradient.centerX); + centerY->setValue (pp->gradient.centerY); + + updateGeometry (pp->gradient.centerX, pp->gradient.centerY, pp->gradient.feather, pp->gradient.degree); + + enableListener (); +} + +void Gradient::updateGeometry(int centerX_, int centerY_, double feather_, double degree_) { + EditDataProvider* dataProvider = getEditProvider(); + if (dataProvider) { + int imW, imH; + PolarCoord polCoord1, polCoord2; + dataProvider->getImageSize(imW, imH); + double decay = feather_ * sqrt(double(imW)*double(imW)+double(imH)*double(imH)) / 200.; + + Coord origin(imW/2+centerX_*imW/200.f, imH/2+centerY_*imH/200.f); + + Line *currLine; + Circle *currCircle; + // update horizontal line + currLine = static_cast(visibleGeometry.at(0)); + polCoord1.set(1500.f, float(-degree_+180)); currLine->begin.setFromPolar(polCoord1); currLine->begin += origin; + polCoord1.set(1500.f, float(-degree_ )); currLine->end.setFromPolar (polCoord1); currLine->end += origin; + currLine = static_cast(mouseOverGeometry.at(0)); + polCoord1.set(1500.f, float(-degree_+180)); currLine->begin.setFromPolar(polCoord1); currLine->begin += origin; + polCoord1.set(1500.f, float(-degree_ )); currLine->end.setFromPolar (polCoord1); currLine->end += origin; + // update vertical line + currLine = static_cast(visibleGeometry.at(1)); + polCoord1.set( 700.f, float(-degree_+90 )); currLine->begin.setFromPolar(polCoord1); currLine->begin += origin; + polCoord1.set( 700.f, float(-degree_+270)); currLine->end.setFromPolar (polCoord1); currLine->end += origin; + currLine = static_cast(mouseOverGeometry.at(1)); + polCoord1.set( 700.f, float(-degree_+90 )); currLine->begin.setFromPolar(polCoord1); currLine->begin += origin; + polCoord1.set( 700.f, float(-degree_+270)); currLine->end.setFromPolar (polCoord1); currLine->end += origin; + // update upper feather line + currLine = static_cast(visibleGeometry.at(2)); + polCoord2.set(decay, float(-degree_+270)); + polCoord1.set(350.f, float(-degree_+180)); currLine->begin.setFromPolar(polCoord1+polCoord2); currLine->begin += origin; + polCoord1.set(350.f, float(-degree_ )); currLine->end.setFromPolar (polCoord1+polCoord2); currLine->end += origin; + currLine = static_cast(mouseOverGeometry.at(2)); + polCoord1.set(350.f, float(-degree_+180)); currLine->begin.setFromPolar(polCoord1+polCoord2); currLine->begin += origin; + polCoord1.set(350.f, float(-degree_ )); currLine->end.setFromPolar (polCoord1+polCoord2); currLine->end += origin; + // update lower feather line + currLine = static_cast(visibleGeometry.at(3)); + polCoord2.set(decay, float(-degree_+90)); + polCoord1.set(350.f, float(-degree_+180)); currLine->begin.setFromPolar(polCoord1+polCoord2); currLine->begin += origin; + polCoord1.set(350.f, float(-degree_ )); currLine->end.setFromPolar (polCoord1+polCoord2); currLine->end += origin; + currLine = static_cast(mouseOverGeometry.at(3)); + polCoord1.set(350.f, float(-degree_+180)); currLine->begin.setFromPolar(polCoord1+polCoord2); currLine->begin += origin; + polCoord1.set(350.f, float(-degree_ )); currLine->end.setFromPolar (polCoord1+polCoord2); currLine->end += origin; + // update circle's position + currCircle = static_cast(visibleGeometry.at(4)); + currCircle->center = origin; + currCircle = static_cast(mouseOverGeometry.at(4)); + currCircle->center = origin; + } +} + +void Gradient::write (ProcParams* pp, ParamsEdited* pedited) +{ + pp->gradient.degree = degree->getValue (); + pp->gradient.feather = feather->getIntValue (); + pp->gradient.strength = strength->getValue (); + pp->gradient.centerX = centerX->getIntValue (); + pp->gradient.centerY = centerY->getIntValue (); + pp->gradient.enabled = getEnabled(); + + if (pedited) { + pedited->gradient.degree = degree->getEditedState (); + pedited->gradient.feather = feather->getEditedState (); + pedited->gradient.strength = strength->getEditedState (); + pedited->gradient.centerX = centerX->getEditedState (); + pedited->gradient.centerY = centerY->getEditedState (); + pedited->gradient.enabled = !get_inconsistent(); + } +} + +void Gradient::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) +{ + degree->setDefault (defParams->gradient.degree); + feather->setDefault (defParams->gradient.feather); + strength->setDefault (defParams->gradient.strength); + centerX->setDefault (defParams->gradient.centerX); + centerY->setDefault (defParams->gradient.centerY); + + if (pedited) { + degree->setDefaultEditedState (pedited->gradient.degree ? Edited : UnEdited); + feather->setDefaultEditedState (pedited->gradient.feather ? Edited : UnEdited); + strength->setDefaultEditedState (pedited->gradient.strength ? Edited : UnEdited); + centerX->setDefaultEditedState (pedited->gradient.centerX ? Edited : UnEdited); + centerY->setDefaultEditedState (pedited->gradient.centerY ? Edited : UnEdited); + } else { + degree->setDefaultEditedState (Irrelevant); + feather->setDefaultEditedState (Irrelevant); + strength->setDefaultEditedState (Irrelevant); + centerX->setDefaultEditedState (Irrelevant); + centerY->setDefaultEditedState (Irrelevant); + } +} + +void Gradient::adjusterChanged (Adjuster* a, double newval) { + + updateGeometry (int(centerX->getValue()), int(centerY->getValue()), feather->getValue(), degree->getValue()); + + if (listener && getEnabled()) { + + if (a == degree) + listener->panelChanged (EvGradientDegree, degree->getTextValue()); + else if (a == feather) + listener->panelChanged (EvGradientFeather, feather->getTextValue()); + else if (a == strength) + listener->panelChanged (EvGradientStrength, strength->getTextValue()); + else if (a == centerX || a == centerY) + listener->panelChanged (EvGradientCenter, Glib::ustring::compose ("X=%1\nY=%2", centerX->getTextValue(), centerY->getTextValue())); + } +} + +void Gradient::enabledChanged () { + + if (listener) { + if (get_inconsistent()) + listener->panelChanged (EvGradientEnabled, M("GENERAL_UNCHANGED")); + else if (getEnabled()) + listener->panelChanged (EvGradientEnabled, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvGradientEnabled, M("GENERAL_DISABLED")); + } +} + +void Gradient::setAdjusterBehavior (bool degreeadd, bool featheradd, bool strengthadd, bool centeradd) +{ + degree->setAddMode(degreeadd); + feather->setAddMode(featheradd); + strength->setAddMode(strengthadd); + centerX->setAddMode(centeradd); + centerY->setAddMode(centeradd); +} + +void Gradient::trimValues (rtengine::procparams::ProcParams* pp) +{ + degree->trimValue(pp->gradient.degree); + feather->trimValue(pp->gradient.feather); + strength->trimValue(pp->gradient.strength); + centerX->trimValue(pp->gradient.centerX); + centerY->trimValue(pp->gradient.centerY); +} + +void Gradient::setBatchMode (bool batchMode) +{ + editConn.disconnect(); + removeIfThere(this, editHBox, false); + ToolPanel::setBatchMode (batchMode); + degree->showEditedCB (); + feather->showEditedCB (); + strength->showEditedCB (); + centerX->showEditedCB (); + centerY->showEditedCB (); +} + +void Gradient::setEditProvider (EditDataProvider* provider) { + EditSubscriber::setEditProvider(provider); +} + +void Gradient::editToggled () { + if (edit->get_active()) { + subscribe(); + } + else + unsubscribe(); +} + +CursorShape Gradient::getCursor(int objectID) { + switch (objectID) { + case (0): + case (1): + return CSMoveRotate; + case (2): + case (3): + { + int angle = degree->getIntValue(); + if (angle<-135 || (angle>=-45 && angle<=45) || angle>135) + return CSMove1DV; + return CSMove1DH; + } + case (4): + return CSMove2D; + default: + return CSOpenHand; + } +} + +bool Gradient::mouseOver(int modifierKey) { + EditDataProvider* editProvider = getEditProvider(); + if (editProvider && editProvider->object!=lastObject) { + if (lastObject > -1) { + if (lastObject == 2 || lastObject == 3) { + EditSubscriber::visibleGeometry.at(2)->state = Geometry::NORMAL; + EditSubscriber::visibleGeometry.at(3)->state = Geometry::NORMAL; + } + else + EditSubscriber::visibleGeometry.at(lastObject)->state = Geometry::NORMAL; + } + if (editProvider->object > -1) { + if (editProvider->object == 2 || editProvider->object == 3) { + EditSubscriber::visibleGeometry.at(2)->state = Geometry::PRELIGHT; + EditSubscriber::visibleGeometry.at(3)->state = Geometry::PRELIGHT; + } + else + EditSubscriber::visibleGeometry.at(editProvider->object)->state = Geometry::PRELIGHT; + } + lastObject = editProvider->object; + return true; + } + return false; +} + +bool Gradient::button1Pressed(int modifierKey) { + if (!(modifierKey & (GDK_CONTROL_MASK | GDK_CONTROL_MASK))) { + // button press is valid (no modifier key) + PolarCoord pCoord; + EditDataProvider *provider = getEditProvider(); + int imW, imH; + provider->getImageSize(imW, imH); + double halfSizeW = imW/2.; + double halfSizeH = imH/2.; + draggedCenter.set(int(halfSizeW+halfSizeW*(centerX->getValue()/100.)), int(halfSizeH+halfSizeH*(centerY->getValue()/100.))); + + // trick to get the correct angle (clockwise/counter-clockwise) + Coord p1 = draggedCenter; + Coord p2 = provider->posImage; + int p = p1.y; + p1.y = p2.y; + p2.y = p; + + pCoord.setFromCartesian(p1, p2); + draggedPointOldAngle = pCoord.angle; + //printf("\ndraggedPointOldAngle=%.3f\n\n", draggedPointOldAngle); + draggedPointAdjusterAngle = degree->getValue(); + if (lastObject==2 || lastObject==3) { + // Dragging a line to change the angle + PolarCoord draggedPoint; + Coord currPos; + currPos = provider->posImage; + Coord centerPos = draggedCenter; + + double diagonal = sqrt(double(imW)*double(imW)+double(imH)*double(imH)); + + // trick to get the correct angle (clockwise/counter-clockwise) + int p = centerPos.y; + centerPos.y = currPos.y; + currPos.y = p; + + draggedPoint.setFromCartesian(centerPos, currPos); + // compute the projected value of the dragged point + draggedFeatherOffset = draggedPoint.radius * sin((draggedPoint.angle-degree->getValue())/180.*M_PI); + if (lastObject==3) + draggedFeatherOffset = -draggedFeatherOffset; + draggedFeatherOffset -= (feather->getValue() / 200. * diagonal); + } + return false; + } + else { + // this will let this class ignore further drag events + if (lastObject > -1) { // should theoretically always be true + if (lastObject == 2 || lastObject == 3) { + EditSubscriber::visibleGeometry.at(2)->state = Geometry::NORMAL; + EditSubscriber::visibleGeometry.at(3)->state = Geometry::NORMAL; + } + else + EditSubscriber::visibleGeometry.at(lastObject)->state = Geometry::NORMAL; + } + lastObject = -1; + return true; + } +} + +bool Gradient::button1Released() { + draggedPointOldAngle = -1000.; + return true; +} + +bool Gradient::drag(int modifierKey) { + // compute the polar coordinate of the mouse position + EditDataProvider *provider = getEditProvider(); + int imW, imH; + provider->getImageSize(imW, imH); + double halfSizeW = imW/2.; + double halfSizeH = imH/2.; + + if (lastObject==0 || lastObject==1) { + + // Dragging a line to change the angle + PolarCoord draggedPoint; + Coord currPos; + currPos = provider->posImage+provider->deltaImage; + Coord centerPos = draggedCenter; + + // trick to get the correct angle (clockwise/counter-clockwise) + int p = centerPos.y; + centerPos.y = currPos.y; + currPos.y = p; + + draggedPoint.setFromCartesian(centerPos, currPos); + double deltaAngle = draggedPoint.angle - draggedPointOldAngle; + if (deltaAngle>180.) // crossing the boundary (0->360) + deltaAngle -= 360.; + else if (deltaAngle<-180.) // crossing the boundary (360->0) + deltaAngle += 360.; + draggedPointOldAngle = draggedPoint.angle; + + draggedPointAdjusterAngle += deltaAngle; + if (draggedPointAdjusterAngle > 180.) + draggedPointAdjusterAngle = -360. + draggedPointAdjusterAngle; + else if (draggedPointAdjusterAngle < -180.) + draggedPointAdjusterAngle = 360. - draggedPointAdjusterAngle; + //printf("draggedPointOldAngle: %.3f / From %d,%d to %d,%d -> angle = %.3f / ", draggedPointAdjusterAngle, centerPos.x, centerPos.y, currPos.x, currPos.y, draggedPoint.angle); + //printf("currAngle: %.3f = degree: %.3f + deltaAngle: %.3f %s / draggedPointOldAngle: %.3f\n", draggedPointAdjusterAngle, degree->getValue(), deltaAngle, degree->getValue()>180.?">180":degree->getValue()<180.?"<180":"", draggedPointOldAngle); + if (int(draggedPointAdjusterAngle) != degree->getIntValue()) { + degree->setValue(draggedPointAdjusterAngle); + updateGeometry (int(centerX->getValue()), int(centerY->getValue()), feather->getValue(), degree->getValue()); + if (listener) + listener->panelChanged (EvGradientDegree, degree->getTextValue()); + return true; + } + } + else if (lastObject==2 || lastObject==3) { + // Dragging the upper or lower feather bar + PolarCoord draggedPoint; + Coord currPos; + currPos = provider->posImage+provider->deltaImage; + Coord centerPos = draggedCenter; + + double diagonal = sqrt(double(imW)*double(imW)+double(imH)*double(imH)); + + // trick to get the correct angle (clockwise/counter-clockwise) + int p = centerPos.y; + centerPos.y = currPos.y; + currPos.y = p; + + draggedPoint.setFromCartesian(centerPos, currPos); + double currDraggedFeatherOffset = draggedPoint.radius * sin((draggedPoint.angle-degree->getValue())/180.*M_PI); + if (lastObject==2) + // Dragging the upper feather bar + currDraggedFeatherOffset -= draggedFeatherOffset; + else if (lastObject==3) + // Dragging the lower feather bar + currDraggedFeatherOffset = -currDraggedFeatherOffset + draggedFeatherOffset; + currDraggedFeatherOffset = currDraggedFeatherOffset * 200. / diagonal; + + if (int(currDraggedFeatherOffset) != feather->getIntValue()) { + feather->setValue(double(int(currDraggedFeatherOffset))); + updateGeometry (centerX->getValue(), centerY->getValue(), feather->getValue(), degree->getValue()); + if (listener) + listener->panelChanged (EvGradientFeather, feather->getTextValue()); + return true; + } + } + else if (lastObject==4) { + // Dragging the circle to change the center + Coord currPos; + draggedCenter += provider->deltaPrevImage; + currPos = draggedCenter; + currPos.clip(imW, imH); + int newCenterX = int((double(currPos.x)-halfSizeW)/halfSizeW*100.); + int newCenterY = int((double(currPos.y)-halfSizeH)/halfSizeH*100.); + if (newCenterX!=centerX->getIntValue() || newCenterY!=centerY->getIntValue()) { + centerX->setValue(newCenterX); + centerY->setValue(newCenterY); + updateGeometry (newCenterX, newCenterY, feather->getValue(), degree->getValue()); + if (listener) + listener->panelChanged (EvGradientCenter, Glib::ustring::compose ("X=%1\nY=%2", centerX->getTextValue(), centerY->getTextValue())); + return true; + } + } + return false; +} + +void Gradient::switchOffEditMode () { + if (edit->get_active()) { + // switching off the toggle button + bool wasBlocked = editConn.block(true); + edit->set_active(false); + if (!wasBlocked) editConn.block(false); + } + EditSubscriber::switchOffEditMode(); // disconnect +} + diff --git a/rtgui/gradient.h b/rtgui/gradient.h new file mode 100644 index 000000000..e27bebe3b --- /dev/null +++ b/rtgui/gradient.h @@ -0,0 +1,61 @@ +/* + * This file is part of RawTherapee. + */ +#ifndef _GRADIENT_H_ +#define _GRADIENT_H_ + +#include +#include "adjuster.h" +#include "toolpanel.h" +#include "edit.h" + +class Gradient : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public EditSubscriber { + + private: + int lastObject; + + protected: + Gtk::HBox *editHBox; + Gtk::ToggleButton* edit; + Adjuster* degree; + Adjuster* feather; + Adjuster* strength; + Adjuster* centerX; + Adjuster* centerY; + double draggedPointOldAngle; + double draggedPointAdjusterAngle; + double draggedFeatherOffset; + Coord draggedCenter; + sigc::connection editConn; + + void editToggled (); + + public: + + Gradient (); + ~Gradient (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + + void updateGeometry (int centerX_, int centerY_, double feather_, double degree_); + + void adjusterChanged (Adjuster* a, double newval); + void enabledChanged (); + void setAdjusterBehavior (bool degreeadd, bool featheradd, bool strengthadd, bool centeradd); + void trimValues (rtengine::procparams::ProcParams* pp); + + void setEditProvider (EditDataProvider* provider); + + // EditSubscriber interface + CursorShape getCursor(int objectID); + bool mouseOver(int modifierKey); + bool button1Pressed(int modifierKey); + bool button1Released(); + bool drag(int modifierKey); + void switchOffEditMode (); +}; + +#endif diff --git a/rtgui/guiutils.cc b/rtgui/guiutils.cc new file mode 100644 index 000000000..ca5d41cd5 --- /dev/null +++ b/rtgui/guiutils.cc @@ -0,0 +1,1088 @@ +/* + * This file is part of RawTherapee. + * + * + * 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 "../rtengine/rt_math.h" + +#include "guiutils.h" +#include "options.h" +#include "../rtengine/rt_math.h" +#include "../rtengine/utils.h" +#include "../rtengine/safegtk.h" +#include "rtimage.h" +#include "multilangmgr.h" + +#include + +using namespace std; + +#if TRACE_MYRWMUTEX==1 && !defined NDEBUG +unsigned int MyReaderLock::readerLockCounter = 0; +unsigned int MyWriterLock::writerLockCounter = 0; +#endif + +Glib::RefPtr MyExpander::inconsistentPBuf; +Glib::RefPtr MyExpander::enabledPBuf; +Glib::RefPtr MyExpander::disabledPBuf; +Glib::RefPtr MyExpander::openedPBuf; +Glib::RefPtr MyExpander::closedPBuf; + +Glib::ustring escapeHtmlChars(const Glib::ustring &src) { + + // Sources chars to be escaped + static const Glib::ustring srcChar("&<>"); + + // Destination strings, in the same order than the source + static std::vector dstChar(3); + dstChar.at(0) = "&"; + dstChar.at(1) = "<"; + dstChar.at(2) = ">"; + + // Copying the original string, that will be modified + Glib::ustring dst(src); + + // Iterating all chars of the copy of the source string + for (size_t i=0; i list = cont->get_children (); + Glib::ListHandle::iterator i = list.begin (); + for (; i!=list.end() && *i!=w; ++i); + if (i!=list.end()) { + if (increference) + w->reference (); + cont->remove (*w); + return true; + } + else + return false; +} + +void thumbInterp (const unsigned char* src, int sw, int sh, unsigned char* dst, int dw, int dh) { + + if (options.thumbInterp==0) + rtengine::nearestInterp (src, sw, sh, dst, dw, dh); + else if (options.thumbInterp==1) + rtengine::bilinearInterp (src, sw, sh, dst, dw, dh); +} + +Glib::ustring removeExtension (const Glib::ustring& filename) { + + Glib::ustring bname = Glib::path_get_basename(filename); + size_t lastdot = bname.find_last_of ('.'); + size_t lastwhitespace = bname.find_last_of (" \t\f\v\n\r"); + if (lastdot!=bname.npos && (lastwhitespace==bname.npos || lastdot > lastwhitespace)) + return filename.substr (0, filename.size()-(bname.size()-lastdot)); + else + return filename; +} + +Glib::ustring getExtension (const Glib::ustring& filename) { + + Glib::ustring bname = Glib::path_get_basename(filename); + size_t lastdot = bname.find_last_of ('.'); + size_t lastwhitespace = bname.find_last_of (" \t\f\v\n\r"); + if (lastdot!=bname.npos && (lastwhitespace==bname.npos || lastdot > lastwhitespace)) + return filename.substr (filename.size()-(bname.size()-lastdot)+1, filename.npos); + else + return ""; +} + +bool confirmOverwrite (Gtk::Window& parent, const std::string& filename) { + bool safe = true; + if (safe_file_test (filename, Glib::FILE_TEST_EXISTS)) { + Glib::ustring msg_ = Glib::ustring ("\"") + Glib::path_get_basename (filename) + "\": " + + M("MAIN_MSG_ALREADYEXISTS") + "\n" + M("MAIN_MSG_QOVERWRITE"); + Gtk::MessageDialog msgd (parent, msg_, true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_YES_NO, true); + safe = (msgd.run () == Gtk::RESPONSE_YES); + } + return safe; +} + +void writeFailed (Gtk::Window& parent, const std::string& filename) { + Glib::ustring msg_ = Glib::ustring::compose(M("MAIN_MSG_WRITEFAILED"), filename); + Gtk::MessageDialog msgd (parent, msg_, true, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true); + msgd.run (); +} + +void drawCrop (Cairo::RefPtr cr, int imx, int imy, int imw, int imh, int startx, int starty, double scale, const rtengine::procparams::CropParams& cparams, bool drawGuide, bool useBgColor, bool fullImageVisible) { + + cr->set_line_width (0.); + cr->rectangle (imx, imy, imw, imh); + cr->clip (); + + double c1x = (cparams.x-startx)*scale; + double c1y = (cparams.y-starty)*scale; + double c2x = (cparams.x+cparams.w-startx)*scale - (fullImageVisible ? 0.0 : 1.0); + double c2y = (cparams.y+cparams.h-starty)*scale - (fullImageVisible ? 0.0 : 1.0); + // crop overlay color, linked with crop windows background + if (options.bgcolor==0 || !useBgColor) + cr->set_source_rgba (options.cutOverlayBrush[0], options.cutOverlayBrush[1], options.cutOverlayBrush[2], options.cutOverlayBrush[3]); + else if (options.bgcolor==1) + cr->set_source_rgb (0,0,0); + else if (options.bgcolor==2) + cr->set_source_rgb (1,1,1); + + + 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); + cr->rectangle (round(imx+c2x)+0.5, round(imy+c1y)+0.5, round(imw-c2x)+0.5, round(c2y-c1y+1)+0.5); + cr->fill (); + + // rectangle around the cropped area and guides + if (cparams.guide!="None" && drawGuide) { + double rectx1 = round(c1x) + imx + 0.5; + double recty1 = round(c1y) + imy + 0.5; + double rectx2 = round(c2x) + imx + 0.5; + double recty2 = round(c2y) + imy + 0.5; + + if(fullImageVisible) { + rectx2 = min(rectx2, imx+imw-0.5); + recty2 = min(recty2, imy+imh-0.5); + } + + cr->set_line_width (1.0); + cr->set_source_rgba (1.0, 1.0, 1.0, 0.618); + cr->move_to (rectx1, recty1); + cr->line_to (rectx2, recty1); + cr->line_to (rectx2, recty2); + cr->line_to (rectx1, recty2); + cr->line_to (rectx1, recty1); + cr->stroke (); + cr->set_source_rgba (0.0, 0.0, 0.0, 0.618); + std::valarray ds (1); + ds[0] = 4; + cr->set_dash (ds, 0); + cr->move_to (rectx1, recty1); + cr->line_to (rectx2, recty1); + cr->line_to (rectx2, recty2); + cr->line_to (rectx1, recty2); + cr->line_to (rectx1, recty1); + cr->stroke (); + ds.resize (0); + cr->set_dash (ds, 0); + + if (cparams.guide!="Rule of diagonals" && cparams.guide!="Golden Triangle 1" && cparams.guide!="Golden Triangle 2") { + // draw guide lines + std::vector horiz_ratios; + std::vector vert_ratios; + + if (cparams.guide=="Rule of thirds") { + horiz_ratios.push_back (1.0/3.0); + horiz_ratios.push_back (2.0/3.0); + vert_ratios.push_back (1.0/3.0); + vert_ratios.push_back (2.0/3.0); + } + else if (!strncmp(cparams.guide.data(),"Harmonic means",14)) { + horiz_ratios.push_back (1.0-0.618); + horiz_ratios.push_back (0.618); + vert_ratios.push_back (0.618); + vert_ratios.push_back (1.0-0.618); + } + else if (cparams.guide=="Grid") { + // To have even distribution, normalize it a bit + const int longSideNumLines=10; + + int w=rectx2-rectx1, h=recty2-recty1; + if (w>longSideNumLines && h>longSideNumLines) { + if (w>h) { + for (int i=1;iset_source_rgba (1.0, 1.0, 1.0, 0.618); + cr->move_to (rectx1, recty1 + round((recty2-recty1) * horiz_ratios[i])); + cr->line_to (rectx2, recty1 + round((recty2-recty1) * horiz_ratios[i])); + cr->stroke (); + cr->set_source_rgba (0.0, 0.0, 0.0, 0.618); + std::valarray ds (1); + ds[0] = 4; + cr->set_dash (ds, 0); + cr->move_to (rectx1, recty1 + round((recty2-recty1) * horiz_ratios[i])); + cr->line_to (rectx2, recty1 + round((recty2-recty1) * horiz_ratios[i])); + cr->stroke (); + ds.resize (0); + cr->set_dash (ds, 0); + } + // Verticals + for (size_t i=0; iset_source_rgba (1.0, 1.0, 1.0, 0.618); + cr->move_to (rectx1 + round((rectx2-rectx1) * vert_ratios[i]), recty1); + cr->line_to (rectx1 + round((rectx2-rectx1) * vert_ratios[i]), recty2); + cr->stroke (); + cr->set_source_rgba (0.0, 0.0, 0.0, 0.618); + std::valarray ds (1); + ds[0] = 4; + cr->set_dash (ds, 0); + cr->move_to (rectx1 + round((rectx2-rectx1) * vert_ratios[i]), recty1); + cr->line_to (rectx1 + round((rectx2-rectx1) * vert_ratios[i]), recty2); + cr->stroke (); + ds.resize (0); + cr->set_dash (ds, 0); + } + } + else if (cparams.guide=="Rule of diagonals") { + double corners_from[4][2]; + double corners_to[4][2]; + int mindim = min(rectx2-rectx1, recty2-recty1); + corners_from[0][0] = rectx1; + corners_from[0][1] = recty1; + corners_to[0][0] = rectx1 + mindim; + corners_to[0][1] = recty1 + mindim; + corners_from[1][0] = rectx1; + corners_from[1][1] = recty2; + corners_to[1][0] = rectx1 + mindim; + corners_to[1][1] = recty2 - mindim; + corners_from[2][0] = rectx2; + corners_from[2][1] = recty1; + corners_to[2][0] = rectx2 - mindim; + corners_to[2][1] = recty1 + mindim; + corners_from[3][0] = rectx2; + corners_from[3][1] = recty2; + corners_to[3][0] = rectx2 - mindim; + corners_to[3][1] = recty2 - mindim; + for (int i=0; i<4; i++) { + cr->set_source_rgba (1.0, 1.0, 1.0, 0.618); + cr->move_to (corners_from[i][0], corners_from[i][1]); + cr->line_to (corners_to[i][0], corners_to[i][1]); + cr->stroke (); + cr->set_source_rgba (0.0, 0.0, 0.0, 0.618); + std::valarray ds (1); + ds[0] = 4; + cr->set_dash (ds, 0); + cr->move_to (corners_from[i][0], corners_from[i][1]); + cr->line_to (corners_to[i][0], corners_to[i][1]); + cr->stroke (); + ds.resize (0); + cr->set_dash (ds, 0); + } + } else if (cparams.guide=="Golden Triangle 1" || cparams.guide=="Golden Triangle 2") { + // main diagonal + if(cparams.guide=="Golden Triangle 2") { + std::swap(rectx1,rectx2); + } + cr->set_source_rgba (1.0, 1.0, 1.0, 0.618); + cr->move_to (rectx1, recty1); + cr->line_to (rectx2, recty2); + cr->stroke (); + cr->set_source_rgba (0.0, 0.0, 0.0, 0.618); + std::valarray ds (1); + ds[0] = 4; + cr->set_dash (ds, 0); + cr->move_to (rectx1, recty1); + cr->line_to (rectx2, recty2); + cr->stroke (); + ds.resize (0); + cr->set_dash (ds, 0); + + double height = recty2 - recty1; + double width = rectx2 - rectx1; + double d = sqrt(height*height + width*width); + double alpha = asin(width/d); + double beta = asin(height/d); + double a = sin(beta) * height; + double b = sin(alpha) * height; + + double x = (a*b)/height; + double y = height - (b*(d-a))/width; + cr->set_source_rgba (1.0, 1.0, 1.0, 0.618); + cr->move_to (rectx1, recty2); + cr->line_to (rectx1+x, recty1+y); + cr->stroke (); + cr->set_source_rgba (0.0, 0.0, 0.0, 0.618); + ds.resize (1); + ds[0] = 4; + cr->set_dash (ds, 0); + cr->move_to (rectx1, recty2); + cr->line_to (rectx1+x, recty1+y); + cr->stroke (); + ds.resize (0); + cr->set_dash (ds, 0); + + x = width - (a*b)/height; + y = (b*(d-a))/width; + cr->set_source_rgba (1.0, 1.0, 1.0, 0.618); + cr->move_to (rectx2, recty1); + cr->line_to (rectx1+x, recty1+y); + cr->stroke (); + cr->set_source_rgba (0.0, 0.0, 0.0, 0.618); + ds.resize (1); + ds[0] = 4; + cr->set_dash (ds, 0); + cr->move_to (rectx2, recty1); + cr->line_to (rectx1+x, recty1+y); + cr->stroke (); + ds.resize (0); + cr->set_dash (ds, 0); + } + } + cr->reset_clip (); +} + +bool ExpanderBox::on_expose_event(GdkEventExpose* event) { + bool retVal = Gtk::EventBox::on_expose_event(event); + + if (!options.useSystemTheme) { + Glib::RefPtr window = get_window(); + Glib::RefPtr style = get_style (); + Cairo::RefPtr cr = window->create_cairo_context(); + + int x_, y_, w_, h_, foo; + window->get_geometry(x_, y_, w_, h_, foo); + double x = 0.; + double y = 0.; + double w = double(w_); + double h = double(h_); + + cr->set_antialias (Cairo::ANTIALIAS_NONE); + + // draw a frame + cr->set_line_width (1.0); + Gdk::Color c = style->get_fg (Gtk::STATE_NORMAL); + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + cr->move_to(x+0.5, y+0.5); + cr->line_to(x+w, y+0.5); + cr->line_to(x+w, y+h); + cr->line_to(x+0.5, y+h); + cr->line_to(x+0.5, y+0.5); + cr->stroke (); + } + return retVal; +} + +ExpanderBox::ExpanderBox( Gtk::Container *p):pC(p) { + set_name ("ExpanderBox"); + updateStyle(); +} + +void ExpanderBox::on_style_changed (const Glib::RefPtr& style) { + updateStyle(); +} + +void ExpanderBox::updateStyle() { + set_border_width(options.slimUI ? 2 : 8); // Outer space around the tool's frame 2:7 +} + +void ExpanderBox::show_all() { + // ask childs to show themselves, but not us (remain unchanged) + Gtk::Container::show_all_children(true); +} + +void ExpanderBox::showBox() { + Gtk::EventBox::show(); +} + +void ExpanderBox::hideBox() { + Gtk::EventBox::hide(); +} + +void MyExpander::init() { + inconsistentPBuf = Gdk::Pixbuf::create_from_file(RTImage::findIconAbsolutePath("expanderInconsistent.png")); + enabledPBuf = Gdk::Pixbuf::create_from_file(RTImage::findIconAbsolutePath("expanderEnabled.png")); + disabledPBuf = Gdk::Pixbuf::create_from_file(RTImage::findIconAbsolutePath("expanderDisabled.png")); + openedPBuf = Gdk::Pixbuf::create_from_file(RTImage::findIconAbsolutePath("expanderOpened.png")); + closedPBuf = Gdk::Pixbuf::create_from_file(RTImage::findIconAbsolutePath("expanderClosed.png")); +} + +MyExpander::MyExpander(bool useEnabled, Gtk::Widget* titleWidget) : + enabled(false), inconsistent(false), flushEvent(false), expBox(NULL), + child(NULL), headerWidget(NULL), statusImage(NULL), + label(NULL), useEnabled(useEnabled) +{ + set_spacing(options.slimUI ? 0 : 2); + set_name("MyExpander"); + set_can_focus(false); + + headerHBox = Gtk::manage( new Gtk::HBox()); + headerHBox->set_can_focus(false); + + if (useEnabled) { + statusImage = Gtk::manage(new Gtk::Image(disabledPBuf)); + imageEvBox = Gtk::manage(new Gtk::EventBox()); + imageEvBox->add(*statusImage); + imageEvBox->set_above_child(true); + imageEvBox->signal_button_release_event().connect( sigc::mem_fun(this, & MyExpander::on_enabled_change) ); + imageEvBox->signal_enter_notify_event().connect( sigc::mem_fun(this, & MyExpander::on_enter_leave_enable), false ); + imageEvBox->signal_leave_notify_event().connect( sigc::mem_fun(this, & MyExpander::on_enter_leave_enable), false ); + headerHBox->pack_start(*imageEvBox, Gtk::PACK_SHRINK, 0); + } + else { + statusImage = Gtk::manage(new Gtk::Image(openedPBuf)); + headerHBox->pack_start(*statusImage, Gtk::PACK_SHRINK, 0); + } + statusImage->set_can_focus(false); + + if (titleWidget) { + headerHBox->pack_start(*titleWidget, Gtk::PACK_EXPAND_WIDGET, 0); + headerWidget = titleWidget; + } + + titleEvBox = Gtk::manage(new Gtk::EventBox()); + titleEvBox->set_name("MyExpanderTitle"); + titleEvBox->add(*headerHBox); + titleEvBox->set_above_child(false); // this is the key! By making it below the child, they will get the events first. + titleEvBox->set_can_focus(false); + + pack_start(*titleEvBox, Gtk::PACK_EXPAND_WIDGET, 0); + + updateStyle(); + titleEvBox->signal_button_release_event().connect( sigc::mem_fun(this, & MyExpander::on_toggle) ); + titleEvBox->signal_enter_notify_event().connect( sigc::mem_fun(this, & MyExpander::on_enter_leave_title), false); + titleEvBox->signal_leave_notify_event().connect( sigc::mem_fun(this, & MyExpander::on_enter_leave_title), false); +} + +MyExpander::MyExpander(bool useEnabled, Glib::ustring titleLabel) : + enabled(false), inconsistent(false), flushEvent(false), expBox(NULL), + child(NULL), headerWidget(NULL), statusImage(NULL), + label(NULL), useEnabled(useEnabled) +{ + set_spacing(options.slimUI ? 0 : 2); + set_name("MyExpander"); + set_can_focus(false); + + headerHBox = Gtk::manage( new Gtk::HBox()); + headerHBox->set_can_focus(false); + + + if (useEnabled) { + statusImage = Gtk::manage(new Gtk::Image(disabledPBuf)); + imageEvBox = Gtk::manage(new Gtk::EventBox()); + imageEvBox->add(*statusImage); + imageEvBox->set_above_child(true); + imageEvBox->signal_button_release_event().connect( sigc::mem_fun(this, & MyExpander::on_enabled_change) ); + imageEvBox->signal_enter_notify_event().connect( sigc::mem_fun(this, & MyExpander::on_enter_leave_enable), false ); + imageEvBox->signal_leave_notify_event().connect( sigc::mem_fun(this, & MyExpander::on_enter_leave_enable), false ); + headerHBox->pack_start(*imageEvBox, Gtk::PACK_SHRINK, 0); + } + else { + statusImage = Gtk::manage(new Gtk::Image(openedPBuf)); + headerHBox->pack_start(*statusImage, Gtk::PACK_SHRINK, 0); + } + statusImage->set_can_focus(false); + + Glib::ustring str("-"); + if (!titleLabel.empty()) + str = titleLabel; + label = Gtk::manage(new Gtk::Label()); + label->set_alignment(Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER); + label->set_markup(Glib::ustring("") + escapeHtmlChars(titleLabel) + Glib::ustring("")); + headerHBox->pack_start(*label, Gtk::PACK_EXPAND_WIDGET, 0); + + titleEvBox = Gtk::manage(new Gtk::EventBox()); + titleEvBox->set_name("MyExpanderTitle"); + titleEvBox->add(*headerHBox); + titleEvBox->set_above_child(false); // this is the key! By make it below the child, they will get the events first. + titleEvBox->set_can_focus(false); + + pack_start(*titleEvBox, Gtk::PACK_EXPAND_WIDGET, 0); + + updateStyle(); + titleEvBox->signal_button_release_event().connect( sigc::mem_fun(this, & MyExpander::on_toggle)); + titleEvBox->signal_enter_notify_event().connect( sigc::mem_fun(this, & MyExpander::on_enter_leave_title), false); + titleEvBox->signal_leave_notify_event().connect( sigc::mem_fun(this, & MyExpander::on_enter_leave_title), false); +} + +bool MyExpander::on_enter_leave_title (GdkEventCrossing* event) { + if (is_sensitive()) { + if (event->type == GDK_ENTER_NOTIFY) { + titleEvBox->set_state(Gtk::STATE_PRELIGHT); + queue_draw(); + } + else if (event->type == GDK_LEAVE_NOTIFY) { + titleEvBox->set_state(Gtk::STATE_NORMAL); + queue_draw(); + } + } + return true; +} + +bool MyExpander::on_enter_leave_enable (GdkEventCrossing* event) { + if (is_sensitive()) { + if (event->type == GDK_ENTER_NOTIFY) { + imageEvBox->set_state(Gtk::STATE_PRELIGHT); + queue_draw(); + } + else if (event->type == GDK_LEAVE_NOTIFY) { + imageEvBox->set_state(Gtk::STATE_NORMAL); + queue_draw(); + } + } + return true; +} + +void MyExpander::updateStyle() { + headerHBox->set_spacing(options.slimUI ? 2 : 5); + headerHBox->set_border_width(options.slimUI ? 1 : 2); + set_spacing(0); + set_border_width(options.slimUI ? 0 : 1); + if (expBox) expBox->updateStyle(); +} + +void MyExpander::setLabel (Glib::ustring newLabel) { + if (label) + label->set_markup(Glib::ustring("") + escapeHtmlChars(newLabel) + Glib::ustring("")); +} + +void MyExpander::setLabel (Gtk::Widget *newWidget) { + if (headerWidget) { + removeIfThere(headerHBox, headerWidget, false); + headerHBox->pack_start(*newWidget, Gtk::PACK_EXPAND_WIDGET, 0); + } +} + +bool MyExpander::get_inconsistent() { + return inconsistent; +} + +void MyExpander::set_inconsistent(bool isInconsistent) { + if (inconsistent != isInconsistent) { + inconsistent = isInconsistent; + if (useEnabled) { + if (isInconsistent) + statusImage->set(inconsistentPBuf); + else { + if (enabled) + statusImage->set(enabledPBuf); + else + statusImage->set(disabledPBuf); + } + } + + } +} + +bool MyExpander::getUseEnabled() { + return useEnabled; +} + +bool MyExpander::getEnabled() { + return enabled; +} + +void MyExpander::setEnabled(bool isEnabled) { + if (isEnabled != enabled) { + if (useEnabled) { + if (enabled) { + enabled = false; + if (!inconsistent) { + statusImage->set(disabledPBuf); + message.emit(); + } + } + else { + enabled = true; + if (!inconsistent) { + statusImage->set(enabledPBuf); + message.emit(); + } + } + } + } +} + +void MyExpander::setEnabledTooltipMarkup(Glib::ustring tooltipMarkup) { + if (useEnabled) { + statusImage->set_tooltip_markup(tooltipMarkup); + } +} + +void MyExpander::setEnabledTooltipText(Glib::ustring tooltipText) { + if (useEnabled) { + statusImage->set_tooltip_text(tooltipText); + } +} + +void MyExpander::set_expanded( bool expanded ) { + if (!expBox) + return; + + bool isVisible = expBox->is_visible(); + + if (isVisible == expanded) + return; + + if (!useEnabled) { + if (expanded ) + statusImage->set(openedPBuf); + else + statusImage->set(closedPBuf); + } + if (expanded) + expBox->showBox(); + else + expBox->hideBox(); +} + +bool MyExpander::get_expanded() { + return expBox ? expBox->get_visible() : false; +} + +void MyExpander::add (Gtk::Container& widget) { + child = &widget; + expBox = Gtk::manage (new ExpanderBox (child)); + expBox->add (*child); + pack_start(*expBox, Gtk::PACK_SHRINK, 0); + child->show(); + expBox->hideBox(); +} + +bool MyExpander::on_toggle(GdkEventButton* event) { + if (flushEvent) { + flushEvent = false; + return false; + } + + if (!expBox || event->button != 1) + return false; + + bool isVisible = expBox->is_visible(); + if (!useEnabled) { + if (isVisible) + statusImage->set(closedPBuf); + else + statusImage->set(openedPBuf); + } + if (isVisible) + expBox->hideBox(); + else + expBox->showBox(); + return false; +} + +Gtk::Container* MyExpander::getChild() { + return child; +} + +// used to connect a function to the enabled_toggled signal +MyExpander::type_signal_enabled_toggled MyExpander::signal_enabled_toggled() { + return message; +} + +// internal use ; when the user clicks on the toggle button, it calls this method that will emit an enabled_change event +bool MyExpander::on_enabled_change(GdkEventButton* event) { + if (event->button == 1) { + if (enabled) { + enabled = false; + statusImage->set(disabledPBuf); + } + else { + enabled = true; + statusImage->set(enabledPBuf); + } + message.emit(); + flushEvent = true; + } + return false; +} + +/* + * + * Derived class of some widgets to properly handle the scroll wheel ; + * the user has to use the Shift key to be able to change the widget's value, + * otherwise the mouse wheel will scroll the editor's tabs content. + * + */ +MyScrolledWindow::MyScrolledWindow () { + set_size_request(-1,30); +} + +bool MyScrolledWindow::on_scroll_event (GdkEventScroll* event) { + if (!options.hideTPVScrollbar) { + Gtk::ScrolledWindow::on_scroll_event (event); + return true; + } + + Gtk::Adjustment *adjust = get_vadjustment(); + Gtk::VScrollbar *scroll = get_vscrollbar(); + if (adjust && scroll) { + double upper = adjust->get_upper(); + double lower = adjust->get_lower(); + double value = adjust->get_value(); + double step = adjust->get_step_increment(); + double value2 = 0.; + if (event->direction == GDK_SCROLL_DOWN) { + value2 = value+step; + if (value2 > upper) + value2 = upper; + if (value2 != value) { + scroll->set_value(value2); + } + } + else { + value2 = value-step; + if (value2 < lower) + value2 = lower; + if (value2 != value) { + scroll->set_value(value2); + } + } + } + return true; +} + +MyComboBoxText::MyComboBoxText () { + set_size_request(40, -1); +} + +bool MyComboBoxText::on_scroll_event (GdkEventScroll* event) { + + // If Shift is pressed, the widget is modified + if (event->state & GDK_SHIFT_MASK) { + Gtk::ComboBoxText::on_scroll_event(event); + return true; + } + // ... otherwise the scroll event is sent back to an upper level + return false; +} + +MyComboBox::MyComboBox () { + set_size_request(40, -1); +} + +bool MyComboBox::on_scroll_event (GdkEventScroll* event) { + + // If Shift is pressed, the widget is modified + if (event->state & GDK_SHIFT_MASK) { + Gtk::ComboBox::on_scroll_event(event); + return true; + } + // ... otherwise the scroll event is sent back to an upper level + return false; +} + +MySpinButton::MySpinButton () { + Gtk::Border border; + border.bottom = 0; + border.top = 0; + border.left = 3; + border.right = 3; + set_inner_border(border); + set_numeric(true); + set_wrap(false); + set_alignment(Gtk::ALIGN_RIGHT); +} + +void MySpinButton::updateSize() { + double vMin, vMax; + int maxAbs; + unsigned int digits, digits2; + unsigned int maxLen; + + get_range(vMin, vMax); + + digits = get_digits(); + maxAbs = (int)(fmax(fabs(vMin), fabs(vMax))+0.000001); + if (maxAbs==0) + digits2 = 1; + else { + digits2 = (int)(log10(double(maxAbs))+0.000001); + digits2++; + } + maxLen = digits+digits2+(vMin<0?1:0)+(digits>0?1:0); + set_max_length(maxLen); + set_width_chars(maxLen); +} + +bool MySpinButton::on_key_press_event (GdkEventKey* event) { + double vMin, vMax; + get_range(vMin, vMax); + if ( (event->string[0] >= 'a' && event->string[0] <= 'z') + ||(event->string[0] >= 'A' && event->string[0] <= 'Z') + || event->string[0] == '+' || (event->string[0] == '-' && vMin >= 0) + || event->string[0] == '=' || event->string[0] == '_' + ) + return false; + else { + if(event->string[0] == ',') { + event->keyval = GDK_period; + event->string[0] = '.'; + } + return Gtk::Widget::on_key_press_event(event); + } +} + +bool MySpinButton::on_scroll_event (GdkEventScroll* event) { + // If Shift is pressed, the widget is modified + if (event->state & GDK_SHIFT_MASK) { + Gtk::SpinButton::on_scroll_event(event); + return true; + } + // ... otherwise the scroll event is sent back to an upper level + return false; +} + +bool MyHScale::on_scroll_event (GdkEventScroll* event) { + + // If Shift is pressed, the widget is modified + if (event->state & GDK_SHIFT_MASK) { + Gtk::HScale::on_scroll_event(event); + return true; + } + // ... otherwise the scroll event is sent back to an upper level + return false; +} + +bool MyHScale::on_key_press_event (GdkEventKey* event) { + + if ( event->string[0] == '+' || event->string[0] == '-' ) + return false; + else + return Gtk::Widget::on_key_press_event(event); +} + +MyFileChooserButton::MyFileChooserButton (const Glib::ustring& title, Gtk::FileChooserAction action) : Gtk::FileChooserButton(title, action) { + set_size_request(20, -1); +} + +// For an unknown reason (a bug ?), it doesn't work when action = FILE_CHOOSER_ACTION_SELECT_FOLDER ! +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); + return true; + } + // ... otherwise the scroll event is sent back to an upper level + return false; +} + +FileChooserLastFolderPersister::FileChooserLastFolderPersister( + Gtk::FileChooser* chooser, Glib::ustring& folderVariable) : + chooser(chooser), folderVariable(folderVariable) { + assert(chooser != NULL); + + selectionChangedConnetion = chooser->signal_selection_changed().connect( + sigc::mem_fun(*this, + &FileChooserLastFolderPersister::selectionChanged)); + + if (!folderVariable.empty()) { + chooser->set_current_folder(folderVariable); + } + +} + +FileChooserLastFolderPersister::~FileChooserLastFolderPersister() { + +} + +void FileChooserLastFolderPersister::selectionChanged() { + + if (!chooser->get_current_folder().empty()) { + folderVariable = chooser->get_current_folder(); + } + +} + +TextOrIcon::TextOrIcon (Glib::ustring fname, Glib::ustring labelTx, Glib::ustring tooltipTx, TOITypes type) { + + imgIcon = 0; + label = 0; + filename = fname; + labelText = labelTx; + tooltipText = tooltipTx; + + switchTo(type); +} + +TextOrIcon::~TextOrIcon () { + if (imgIcon) delete imgIcon; + if (label) delete label; +} + +void TextOrIcon::switchTo(TOITypes type) { + switch (type) { + case (TOI_ICON): + if (!imgIcon) { + removeIfThere(this, label, false); + delete label; + label = 0; + imgIcon = new RTImage (filename); + pack_start(*imgIcon, Gtk::PACK_SHRINK, 0); + set_tooltip_markup ("" + labelText + "\n" + tooltipText); + } + // do nothing if imgIcon exist, which mean that it is currently being displayed + break; + case(TOI_TEXT): + default: + if (!label) { + removeIfThere(this, imgIcon, false); + delete imgIcon; + imgIcon = 0; + label = new Gtk::Label (labelText, Gtk::ALIGN_CENTER); + pack_start(*label, Gtk::PACK_EXPAND_WIDGET, 0); + set_tooltip_markup (tooltipText); + } + // do nothing if label exist, which mean that it is currently being displayed + break; + } + show_all(); +} + +BackBuffer::BackBuffer() : x(0), y(0), w(0), h(0), offset(0,0), dirty(true) {} + +void BackBuffer::setSrcOffset(int x, int y) { + // values will be clamped when used... + offset.x = x; + offset.y = y; +} + +// Note: newW & newH must be > 0 +bool BackBuffer::setDrawRectangle(Glib::RefPtr window, int newX, int newY, int newW, int newH, bool updateBackBufferSize) { + assert(newW && newH); + + bool newSize = w!=newW || h!=newH; + + x = newX; + y = newY; + w = newW; + h = newH; + + // WARNING: we're assuming that the surface type won't change during all the execution time of RT. I guess it may be wrong when the user change the gfx card display settings!? + if (updateBackBufferSize && newSize && window) { + // allocate a new Surface + surface.clear(); // ... don't know if this is necessary? + surface = Cairo::ImageSurface::create(Cairo::FORMAT_RGB24, w, h); + dirty = true; + } + return dirty; +} + +// Note: newW & newH must be > 0 +bool BackBuffer::setDrawRectangle(Cairo::Format format, int newX, int newY, int newW, int newH, bool updateBackBufferSize) { + assert(!newW && !newH); + + bool newSize = w!=newW || h!=newH; + + x = newX; + y = newY; + w = newW; + h = newH; + + // WARNING: we're assuming that the surface type won't change during all the execution time of RT. I guess it may be wrong when the user change the gfx card display settings!? + if (updateBackBufferSize && newSize) { + // allocate a new Surface + surface.clear(); // ... don't know if this is necessary? + surface = Cairo::ImageSurface::create(format, w, h); + dirty = true; + } + return dirty; +} + +/* + * Copy the backbuffer to a Gdk::Window + */ +void BackBuffer::copySurface(Glib::RefPtr window, GdkRectangle *rectangle) { + if (surface && window) { + // TODO: look out if window can be different on each call, and if not, store a reference to the window + Cairo::RefPtr crSrc = window->create_cairo_context(); + Cairo::RefPtr destSurface = crSrc->get_target(); + + // compute the source offset + int offsetX = rtengine::LIM(offset.x,0, surface->get_width()); + int offsetY = rtengine::LIM(offset.y,0, surface->get_height()); + + // now copy the off-screen Surface to the destination Surface + Cairo::RefPtr crDest = Cairo::Context::create(destSurface); + crDest->set_source(surface, x-offsetX, y-offsetY); + crDest->set_line_width(0.); + if (rectangle) + crDest->rectangle(rectangle->x, rectangle->y, rectangle->width, rectangle->height); + else + crDest->rectangle(x, y, w, h); + crDest->fill(); + } +} + +/* + * Copy the BackBuffer to another BackBuffer + */ +void BackBuffer::copySurface(BackBuffer *destBackBuffer, GdkRectangle *rectangle) { + if (surface && destBackBuffer) { + // compute the source offset + int offsetX = rtengine::LIM(offset.x,0, surface->get_width()); + int offsetY = rtengine::LIM(offset.y,0, surface->get_height()); + + // now copy the off-screen Surface to the destination Surface + Cairo::RefPtr crDest = Cairo::Context::create(destBackBuffer->getSurface()); + crDest->set_source(surface, x-offsetX, y-offsetY); + crDest->set_line_width(0.); + if (rectangle) + crDest->rectangle(rectangle->x, rectangle->y, rectangle->width, rectangle->height); + else + crDest->rectangle(x, y, w, h); + crDest->fill(); + } +} + +/* + * Copy the BackBuffer to another Cairo::Surface + */ +void BackBuffer::copySurface(Cairo::RefPtr destSurface, GdkRectangle *rectangle) { + if (surface && destSurface) { + // compute the source offset + int offsetX = rtengine::LIM(offset.x,0, surface->get_width()); + int offsetY = rtengine::LIM(offset.y,0, surface->get_height()); + + // now copy the off-screen Surface to the destination Surface + Cairo::RefPtr crDest = Cairo::Context::create(destSurface); + crDest->set_source(surface, x-offsetX, y-offsetY); + crDest->set_line_width(0.); + if (rectangle) + crDest->rectangle(rectangle->x, rectangle->y, rectangle->width, rectangle->height); + else + crDest->rectangle(x, y, w, h); + crDest->fill(); + } +} + diff --git a/rtgui/guiutils.h b/rtgui/guiutils.h new file mode 100644 index 000000000..3221ba19b --- /dev/null +++ b/rtgui/guiutils.h @@ -0,0 +1,433 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef __GUI_UTILS_ +#define __GUI_UTILS_ + +#include +#include "../rtengine/rtengine.h" +#include +#include + +Glib::ustring escapeHtmlChars(const Glib::ustring &src); +bool removeIfThere (Gtk::Container* cont, Gtk::Widget* w, bool increference=true); +void thumbInterp (const unsigned char* src, int sw, int sh, unsigned char* dst, int dw, int dh); +Glib::ustring removeExtension (const Glib::ustring& filename); +Glib::ustring getExtension (const Glib::ustring& filename); +bool confirmOverwrite (Gtk::Window& parent, const std::string& filename); +void writeFailed (Gtk::Window& parent, const std::string& filename); +void drawCrop (Cairo::RefPtr cr, int imx, int imy, int imw, int imh, int startx, int starty, double scale, const rtengine::procparams::CropParams& cparams, bool drawGuide = true, bool useBgColor = true, bool fullImageVisible = true); + +/** + * @brief Lock GTK for critical section. + * + * Will unlock on destruction. To use: + * + * + * { + * GThreadLock lock; + * // critical code + * } + * + */ +class GThreadLock +{ +public: + GThreadLock() + { + gdk_threads_enter(); + } + ~GThreadLock() + { + gdk_threads_leave(); + } +}; + +/** + * @brief Unlock GTK critical section. + * + * Will relock on destruction. + */ +class GThreadUnLock +{ +public: + GThreadUnLock() + { + gdk_threads_leave(); + } + ~GThreadUnLock() + { + gdk_threads_enter(); + } +}; + +/** + * @brief Glue box to control visibility of the MyExpender's content ; also handle the frame around it + */ +class ExpanderBox: public Gtk::EventBox +{ +private: + Gtk::Container *pC; + +public: + ExpanderBox( Gtk::Container *p); + ~ExpanderBox( ){ delete pC;} + + void updateStyle(); + + void show() {} + void show_all(); + void hide() {} + void set_visible(bool isVisible=true) {} + + void showBox(); + void hideBox(); + + void on_style_changed (const Glib::RefPtr& style); + bool on_expose_event(GdkEventExpose* event); +}; + +/** + * @brief A custom Expander class, that can handle widgets in the title bar + * + * Custom made expander for responsive widgets in the header. It also handle a "enabled/disabled" property that display + * a different arrow depending on this boolean value. + * + * Warning: once you've instantiated this class with a text label or a widget label, you won't be able to revert to the other solution. + */ +class MyExpander : public Gtk::VBox { +public: + typedef sigc::signal type_signal_enabled_toggled; +private: + type_signal_enabled_toggled message; + static Glib::RefPtr inconsistentPBuf; /// "inconsistent" image, displayed when useEnabled is true ; in this case, nothing will tell that an expander is opened/closed + static Glib::RefPtr enabledPBuf; /// "enabled" image, displayed when useEnabled is true ; in this case, nothing will tell that an expander is opened/closed + static Glib::RefPtr disabledPBuf; /// "disabled" image, displayed when useEnabled is true ; in this case, nothing will tell that an expander is opened/closed + static Glib::RefPtr openedPBuf; /// "opened" image, displayed when useEnabled is false + static Glib::RefPtr closedPBuf; /// "closed" image, displayed when useEnabled is false + bool enabled; /// Enabled feature (default to true) + bool inconsistent; /// True if the enabled button is inconsistent + Gtk::EventBox *titleEvBox; /// EventBox of the title, to get a connector from it + Gtk::HBox *headerHBox; + bool flushEvent; /// Flag to control the weird event mechanism of Gtk (please prove me wrong!) + ExpanderBox* expBox; /// Frame that includes the child and control its visibility + Gtk::EventBox *imageEvBox; /// Enable/Disable or Open/Close arrow event box + + /// Triggered on opened/closed event + bool on_toggle(GdkEventButton* event); + /// Triggered on enabled/disabled change -> will emit a toggle event to the connected objects + bool on_enabled_change(GdkEventButton* event); + /// Used to handle the colored background for the whole Title + bool on_enter_leave_title (GdkEventCrossing* event); + /// Used to handle the colored background for the Enable button + bool on_enter_leave_enable (GdkEventCrossing* event); + /// Update the style of this widget, depending in the "slim" option + void updateStyle(); + + void on_style_changed (const Glib::RefPtr& style) { updateStyle(); } + + + +protected: + Gtk::Container* child; /// Gtk::Contained to display below the expander's title + Gtk::Widget* headerWidget; /// Widget to display in the header, next to the arrow image ; can be NULL if the "string" version of the ctor has been used + Gtk::Image* statusImage; /// Image to display the opened/closed status (if useEnabled is false) of the enabled/disabled status (if useEnabled is true) + Gtk::Label* label; /// Text to display in the header, next to the arrow image ; can be NULL if the "widget" version of the ctor has been used + bool useEnabled; /// Set whether to handle an enabled/disabled feature and display the appropriate images + +public: + + /** @brief Create a custom expander with a simple header made of a label. + * @param useEnabled Set whether to handle an enabled/disabled toggle button and display the appropriate image + * @param titleLabel A string to display in the header. Warning: you won't be able to switch to a widget label. + */ + MyExpander(bool useEnabled, Glib::ustring titleLabel); + + /** Create a custom expander with a a custom - and responsive - widget + * @param useEnabled Set whether to handle an enabled/disabled toggle button and display the appropriate image + * @param titleWidget A widget to display in the header. Warning: you won't be able to switch to a string label. + */ + MyExpander(bool useEnabled, Gtk::Widget* titleWidget); + + /// Initialize the class by loading the images + static void init(); + + Glib::SignalProxy1< bool,GdkEventButton* > signal_button_release_event() { return titleEvBox->signal_button_release_event(); }; + type_signal_enabled_toggled signal_enabled_toggled(); + + /// Set a new label string. If it has been instantiated with a Gtk::Widget, this method will do nothing + void setLabel (Glib::ustring newLabel); + /// Set a new label string. If it has been instantiated with a Gtk::Widget, this method will do nothing + void setLabel (Gtk::Widget *newWidget); + + /// Get whether the enabled option is set (to true or false) or unset (i.e. undefined) + bool get_inconsistent(); + /// Set whether the enabled option is set (to true or false) or unset (i.e. undefined) + void set_inconsistent(bool isInconsistent); + + /// Get whether the enabled button is used or not + bool getUseEnabled(); + /// Get whether the enabled button is on or off + bool getEnabled(); + /// If not inconsistent, set the enabled button to true or false and emit the message if the state is different + /// If inconsistent, set the internal value to true or false, but do not update the image and do not emit the message + void setEnabled(bool isEnabled); + /// Adds a Tooltip to the Enabled button, if it exist ; do nothing otherwise + void setEnabledTooltipMarkup(Glib::ustring tooltipMarkup); + void setEnabledTooltipText(Glib::ustring tooltipText); + + /// Get the header widget. It'll send back the Gtk::Label* if it has been instantiated with a simple text + Gtk::Widget* getLabelWidget() const { return headerWidget ? headerWidget : label; } + + /// Get the widget shown/hidden by the expander + Gtk::Container* getChild(); + + /// Set the collapsed/expanded state of the expander + void set_expanded( bool expanded ); + + /// Get the collapsed/expanded state of the expander + bool get_expanded(); + + /// Add a Gtk::Container for the content of the expander + /// Warning: do not manually Show/Hide the widget, because this parameter is handled by the click on the Expander's title + void add (Gtk::Container& widget); +}; + + +/** + * @brief subclass of Gtk::ScrolledWindow in order to handle the scrollwheel + */ +class MyScrolledWindow : public Gtk::ScrolledWindow { + + bool on_scroll_event (GdkEventScroll* event); + +public: + MyScrolledWindow(); +}; + +/** + * @brief subclass of Gtk::ComboBox in order to handle the scrollwheel + */ +class MyComboBox : public Gtk::ComboBox { + + bool on_scroll_event (GdkEventScroll* event); + +public: + MyComboBox (); +}; + +/** + * @brief subclass of Gtk::ComboBoxText in order to handle the scrollwheel + */ +class MyComboBoxText : public Gtk::ComboBoxText { + + bool on_scroll_event (GdkEventScroll* event); + +public: + MyComboBoxText (); +}; + +/** + * @brief subclass of Gtk::SpinButton in order to handle the scrollwheel + */ +class MySpinButton : public Gtk::SpinButton { + +protected: + bool on_scroll_event (GdkEventScroll* event); + bool on_key_press_event (GdkEventKey* event); + +public: + MySpinButton (); + void updateSize(); +}; + +/** + * @brief subclass of Gtk::HScale in order to handle the scrollwheel + */ +class MyHScale : public Gtk::HScale { + + bool on_scroll_event (GdkEventScroll* event); + bool on_key_press_event (GdkEventKey* event); +}; + +/** + * @brief subclass of Gtk::FileChooserButton in order to handle the scrollwheel + */ +class MyFileChooserButton : public Gtk::FileChooserButton { + +protected: + bool on_scroll_event (GdkEventScroll* event); + +public: + MyFileChooserButton (const Glib::ustring& title, Gtk::FileChooserAction action=Gtk::FILE_CHOOSER_ACTION_OPEN); +}; + +/** + * A class which maintains the last folder for a FileChooserDialog or Button by + * caching it in a a variable (which can be persisted externally). + * Each time the user selects a file or folder, the provided variable is updated + * with the associated folder. The path found in the variable is set in the + * dialog instance at constructions time of this object. + */ +class FileChooserLastFolderPersister: public Glib::Object { +public: + + /** + * Installs this persister on the provided GtkFileChooser instance and + * applies the current folder found in @p folderVariable for the dialog. + * + * @param chooser file chooser to maintain + * @param folderVariable variable storage to use for this dialog + */ + FileChooserLastFolderPersister(Gtk::FileChooser* chooser, Glib::ustring& folderVariable); + + virtual ~FileChooserLastFolderPersister(); + +private: + + /** + * Signal handler for the GtkFileChooser selection action. + */ + void selectionChanged(); + + Gtk::FileChooser* chooser; + Glib::ustring& folderVariable; + sigc::connection selectionChangedConnetion; + +}; + +typedef enum RTUpdatePolicy { + RTUP_STATIC, + RTUP_DYNAMIC +} eUpdatePolicy; + +typedef enum RTOrientation { + RTO_Left2Right, + RTO_Bottom2Top, + RTO_Right2Left, + RTO_Top2Bottom +} eRTOrientation; + +enum TOITypes { + TOI_TEXT, + TOI_ICON +}; + +typedef enum RTNav { + NAV_NONE, + NAV_NEXT, + NAV_PREVIOUS +} eRTNav; + +/** + * @brief Handle the switch between text and image to be displayed in the HBox (to be used in a button/toolpanel) + */ +class TextOrIcon : public Gtk::HBox { + +protected: + Gtk::Image* imgIcon; + Gtk::Label* label; + Glib::ustring filename; + Glib::ustring labelText; + Glib::ustring tooltipText; + +public: + TextOrIcon (Glib::ustring filename, Glib::ustring labelTx, Glib::ustring tooltipTx, TOITypes type); + ~TextOrIcon (); + + void switchTo(TOITypes type); +}; + +/** + * @brief Define a gradient milestone + */ +class GradientMilestone { +public: + double position; + double r; + double g; + double b; + double a; + + GradientMilestone(double _p=0., double _r=0., double _g=0., double _b=0., double _a=0.) { + position = _p; r = _r; g = _g; b = _b; a = _a; + } +}; + +/** + * @brief Handle point coordinates + */ +template +class Point { +public: + T x, y; + Point() { + x = T(0); + y = T(0); + } + + Point(T coordX, T coordY) { + x = coordX; + y = coordY; + } + + void setCoords(T coordX, T coordY) { + x = coordX; + y = coordY; + } +}; + +/** + * @brief Handle backbuffers as automatically as possible + */ +class BackBuffer { + +protected: + int x, y, w, h; // Rectangle where the colored bar has to be drawn + Point offset; // Offset of the source region to draw, relative to the top left corner + Cairo::RefPtr surface; + bool dirty; // mean that the Surface has to be (re)allocated + +public: + BackBuffer(); + + // set the destination drawing rectangle; return true if the dimensions are different + // Note: newW & newH must be > 0 + bool setDrawRectangle(Glib::RefPtr window, int newX, int newY, int newW, int newH, bool updateBackBufferSize=true); + bool setDrawRectangle(Cairo::Format format, int newX, int newY, int newW, int newH, bool updateBackBufferSize=true); + void setSrcOffset(int x, int y); + + void copySurface(Glib::RefPtr window, GdkRectangle *rectangle=NULL); + void copySurface(BackBuffer *destBackBuffer, GdkRectangle *rectangle=NULL); + void copySurface(Cairo::RefPtr destSurface, GdkRectangle *rectangle=NULL); + + void setDirty(bool isDirty) { dirty = isDirty; if (!dirty && !surface) dirty = true; } + bool isDirty() { return dirty; } + // you have to check if the surface is created thanks to surfaceCreated before starting to draw on it + bool surfaceCreated() { return surface; } + Cairo::RefPtr getSurface() { return surface; } + void setSurface(Cairo::RefPtr surf) { surface = surf; } + void deleteSurface() { if (surface) surface.clear(); dirty=true; } + // will let you get a Cairo::Context for Cairo drawing operations + Cairo::RefPtr getContext() { return Cairo::Context::create(surface); } + int getWidth() { return surface ? surface->get_width() : 0; } + int getHeight() { return surface ? surface->get_height() : 0; } +}; + + +#endif diff --git a/rtgui/histogrampanel.cc b/rtgui/histogrampanel.cc new file mode 100644 index 000000000..2c9794f1d --- /dev/null +++ b/rtgui/histogrampanel.cc @@ -0,0 +1,987 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "histogrampanel.h" +#include "multilangmgr.h" +#include "guiutils.h" +#include "options.h" +#include +#include "../rtengine/LUT.h" +#include "rtimage.h" +#include "../rtengine/improccoordinator.h" +#include "../rtengine/color.h" + + +using namespace rtengine; + +extern Glib::ustring argv0; +extern Options options; + + +// +// +// HistogramPanel +HistogramPanel::HistogramPanel () { + + histogramArea = Gtk::manage (new HistogramArea (this)); + histogramRGBArea = Gtk::manage (new HistogramRGBArea ()); + histogramRGBArea->show(); + + gfxVBox = Gtk::manage (new Gtk::VBox (false, 2)); + histogramRGBArea->setParent(gfxVBox); + gfxVBox->pack_start (*histogramArea, Gtk::PACK_EXPAND_WIDGET, 0); + if (options.histogramBar) + gfxVBox->pack_start (*histogramRGBArea, Gtk::PACK_SHRINK, 0); + + redImage = new RTImage ("histRed.png"); + greenImage = new RTImage ("histGreen.png"); + blueImage = new RTImage ("histBlue.png"); + valueImage = new RTImage ("histValue.png"); + chroImage = new RTImage ("histChro.png"); + rawImage = new RTImage ("histRaw.png"); + fullImage = new RTImage ("histFull.png"); + barImage = new RTImage ("histBar.png"); + + redImage_g = new RTImage ("histRedg.png"); + greenImage_g = new RTImage ("histGreeng.png"); + blueImage_g = new RTImage ("histBlueg.png"); + valueImage_g = new RTImage ("histValueg.png"); + chroImage_g = new RTImage ("histChrog.png"); + rawImage_g = new RTImage ("histRawg.png"); + fullImage_g = new RTImage ("histFullg.png"); + barImage_g = new RTImage ("histBarg.png"); + + showRed = Gtk::manage (new Gtk::ToggleButton ()); + showGreen = Gtk::manage (new Gtk::ToggleButton ()); + showBlue = Gtk::manage (new Gtk::ToggleButton ()); + showValue = Gtk::manage (new Gtk::ToggleButton ()); + showChro = Gtk::manage (new Gtk::ToggleButton ()); + showRAW = Gtk::manage (new Gtk::ToggleButton ()); + showFull = Gtk::manage (new Gtk::ToggleButton ()); + showBAR = Gtk::manage (new Gtk::ToggleButton ()); + + showRed->set_name("histButton"); showRed->set_can_focus(false); + showGreen->set_name("histButton"); showGreen->set_can_focus(false); + showBlue->set_name("histButton"); showBlue->set_can_focus(false); + showValue->set_name("histButton"); showValue->set_can_focus(false); + showChro->set_name("histButton"); showChro->set_can_focus(false); + showRAW->set_name("histButton"); showRAW->set_can_focus(false); + showFull->set_name("fullButton"); showFull->set_can_focus(false); + showBAR->set_name("histButton"); showBAR->set_can_focus(false); + + showRed->set_relief (Gtk::RELIEF_NONE); + showGreen->set_relief (Gtk::RELIEF_NONE); + showBlue->set_relief (Gtk::RELIEF_NONE); + showValue->set_relief (Gtk::RELIEF_NONE); + showChro->set_relief (Gtk::RELIEF_NONE); + showRAW->set_relief (Gtk::RELIEF_NONE); + showFull->set_relief (Gtk::RELIEF_NONE); + showBAR->set_relief (Gtk::RELIEF_NONE); + + showRed->set_tooltip_text (M("HISTOGRAM_TOOLTIP_R")); + showGreen->set_tooltip_text (M("HISTOGRAM_TOOLTIP_G")); + showBlue->set_tooltip_text (M("HISTOGRAM_TOOLTIP_B")); + showValue->set_tooltip_text (M("HISTOGRAM_TOOLTIP_L")); + showChro->set_tooltip_text (M("HISTOGRAM_TOOLTIP_CHRO")); + showRAW->set_tooltip_text (M("HISTOGRAM_TOOLTIP_RAW")); + showFull->set_tooltip_text (M("HISTOGRAM_TOOLTIP_FULL")); + showBAR->set_tooltip_text (M("HISTOGRAM_TOOLTIP_BAR")); + + buttonVBox = Gtk::manage (new Gtk::VBox (false, 2)); + showRed->set_active (true); + showGreen->set_active (true); + showBlue->set_active (true); + showValue->set_active (true); + showChro->set_active (false);//unactive by default + + showRAW->set_active (false); + showFull->set_active (!options.histogramFullMode); + showBAR->set_active (options.histogramBar); + + showRed->set_image (showRed->get_active() ? *redImage : *redImage_g); + showGreen->set_image (showGreen->get_active() ? *greenImage : *greenImage_g); + showBlue->set_image (showBlue->get_active() ? *blueImage : *blueImage_g); + showValue->set_image (showValue->get_active() ? *valueImage : *valueImage_g); + showChro->set_image (showChro->get_active() ? *chroImage : *chroImage_g); + showRAW->set_image (showRAW->get_active() ? *rawImage : *rawImage_g); + showFull->set_image (showFull->get_active() ? *fullImage : *fullImage_g); + showBAR->set_image (showBAR->get_active() ? *barImage : *barImage_g); + + showRed->signal_toggled().connect( sigc::mem_fun(*this, &HistogramPanel::red_toggled), showRed ); + showGreen->signal_toggled().connect( sigc::mem_fun(*this, &HistogramPanel::green_toggled), showGreen ); + showBlue->signal_toggled().connect( sigc::mem_fun(*this, &HistogramPanel::blue_toggled), showBlue ); + showValue->signal_toggled().connect( sigc::mem_fun(*this, &HistogramPanel::value_toggled), showValue ); + showChro->signal_toggled().connect( sigc::mem_fun(*this, &HistogramPanel::chro_toggled), showChro ); + showRAW->signal_toggled().connect( sigc::mem_fun(*this, &HistogramPanel::raw_toggled), showRAW ); + showFull->signal_toggled().connect( sigc::mem_fun(*this, &HistogramPanel::full_toggled), showFull ); + showBAR->signal_toggled().connect( sigc::mem_fun(*this, &HistogramPanel::bar_toggled), showBAR ); + + buttonVBox->pack_start (*showRed, Gtk::PACK_SHRINK, 0); + buttonVBox->pack_start (*showGreen, Gtk::PACK_SHRINK, 0); + buttonVBox->pack_start (*showBlue, Gtk::PACK_SHRINK, 0); + buttonVBox->pack_start (*showValue, Gtk::PACK_SHRINK, 0); + buttonVBox->pack_start (*showChro, Gtk::PACK_SHRINK, 0); + buttonVBox->pack_start (*showRAW, Gtk::PACK_SHRINK, 0); + buttonVBox->pack_start (*showFull, Gtk::PACK_SHRINK, 0); + buttonVBox->pack_start (*showBAR, Gtk::PACK_SHRINK, 0); + + // Put the button vbox next to the window's border to be less disturbing + if (options.histogramPosition == 1) { + pack_start (*buttonVBox, Gtk::PACK_SHRINK, 2); + pack_start (*gfxVBox,Gtk::PACK_EXPAND_WIDGET, 2); + } + else { + pack_start (*gfxVBox,Gtk::PACK_EXPAND_WIDGET, 2); + pack_start (*buttonVBox, Gtk::PACK_SHRINK, 2); + } + + show_all (); + + rconn = signal_size_allocate().connect( sigc::mem_fun(*this, &HistogramPanel::resized) ); +} + +HistogramPanel::~HistogramPanel () { + delete redImage; + delete greenImage; + delete blueImage; + delete valueImage; + delete chroImage; + delete rawImage; + delete fullImage; + delete barImage; + + delete redImage_g; + delete greenImage_g; + delete blueImage_g; + delete valueImage_g; + delete chroImage_g; + delete rawImage_g; + delete fullImage_g; + delete barImage_g; + +} + +void HistogramPanel::resized (Gtk::Allocation& req) { + + rconn.block (true); + + int gHeight = req.get_width()/2; + if (gHeight > 150) gHeight = 150; else if (gHeight < 100) gHeight = 100; + int bHeight = req.get_width()/30; + if (bHeight > 10) bHeight = 10; else if (bHeight < 5 ) bHeight = 5; + histogramArea->set_size_request (req.get_width(), gHeight); + histogramRGBArea->set_size_request (req.get_width(), bHeight); + + rconn.block (false); + + histogramArea->renderHistogram (); + histogramArea->queue_draw (); + + if (histogramRGBArea->getFreeze()==true) { + histogramRGBArea->updateFreeze(false); + // set histogramRGBArea invalid; + histogramRGBArea->renderRGBMarks(-1, -1, -1); + // re-set freeze to old state + histogramRGBArea->updateFreeze(true); + histogramRGBArea->queue_draw (); + } + else { + // set histogramRGBArea invalid; + histogramRGBArea->renderRGBMarks(-1, -1, -1); + histogramRGBArea->queue_draw (); + } +} + +void HistogramPanel::red_toggled () { + showRed->set_image(showRed->get_active() ? *redImage : *redImage_g); + rgbv_toggled(); +} +void HistogramPanel::green_toggled () { + showGreen->set_image(showGreen->get_active() ? *greenImage : *greenImage_g); + rgbv_toggled(); +} +void HistogramPanel::blue_toggled () { + showBlue->set_image(showBlue->get_active() ? *blueImage : *blueImage_g); + rgbv_toggled(); +} +void HistogramPanel::value_toggled () { + removeIfThere(showValue, valueImage, false); + removeIfThere(showValue, valueImage_g, false); + showValue->set_image(showValue->get_active() ? *valueImage : *valueImage_g); + rgbv_toggled(); +} +void HistogramPanel::chro_toggled () { + removeIfThere(showChro, chroImage, false); + removeIfThere(showChro, chroImage_g, false); + showChro->set_image(showChro->get_active() ? *chroImage : *chroImage_g); + rgbv_toggled(); +} + +void HistogramPanel::raw_toggled () { + if (showRAW->get_active()) { + showRAW->set_image(*rawImage); + showValue->set_sensitive(false); + showChro->set_sensitive(false); + } + else { + showRAW->set_image(*rawImage_g); + showValue->set_sensitive(true); + showChro->set_sensitive(true); + } + rgbv_toggled(); +} +void HistogramPanel::full_toggled () { + options.histogramFullMode = !showFull->get_active(); + showFull->set_image(showFull->get_active() ? *fullImage : *fullImage_g); + rgbv_toggled(); +} +void HistogramPanel::bar_toggled () { + showBAR->set_image(showBAR->get_active() ? *barImage : *barImage_g); + rgbv_toggled(); +} +void HistogramPanel::rgbv_toggled () { + // Update Display + histogramArea->updateOptions (showRed->get_active(), showGreen->get_active(), showBlue->get_active(), showValue->get_active(), showRAW->get_active(), showFull->get_active(), showChro->get_active()); + histogramArea->queue_draw (); + + histogramRGBArea->updateOptions (showRed->get_active(), showGreen->get_active(), showBlue->get_active(), showValue->get_active(), showRAW->get_active(), showBAR->get_active(), showChro->get_active()); + histogramRGBArea->renderRGBMarks (0,0,0); + histogramArea->queue_draw (); +} + +void HistogramPanel::setHistRGBInvalid () { + // do something to un-show vertical bars + histogramRGBArea->renderRGBMarks(-1, -1, -1); + histogramRGBArea->queue_draw (); +} + +// "Freeze" is not a button, but a RMB-click, so this is not in the RGBV-Toggle method +void HistogramPanel::toggleFreeze () { + if (histogramRGBArea->getFreeze()==true) { + histogramRGBArea->updateFreeze(false); + } + else if (histogramRGBArea->getShow()==true) { + histogramRGBArea->updateFreeze(true); + } + return; +} + +void HistogramPanel::pointerMoved (bool validPos, Glib::ustring profile, Glib::ustring profileW,int x, int y, int r, int g, int b) { + + if (!validPos) { + // do something to un-show vertical bars + histogramRGBArea->renderRGBMarks(-1, -1, -1); + histogramRGBArea->queue_draw (); + } + else { + // do something to show vertical bars + histogramRGBArea->renderRGBMarks(r, g, b, profile, profileW); + histogramRGBArea->queue_draw (); + } +} + +/* + * Move the vertical button bar to the right side + * only allowed values for align are Gtk::ALIGN_LEFT and Gtk::ALIGN_RIGHT + */ +void HistogramPanel::reorder (Gtk::AlignmentEnum align) { + if (align == Gtk::ALIGN_LEFT) + reorder_child(*buttonVBox, 0); + else + reorder_child(*buttonVBox, 1); +} + +// FullModeListener interface: +void HistogramPanel::toggle_button_full () { + showFull->set_active (!showFull->get_active ()); + showFull->set_image(showFull->get_active() ? *fullImage : *fullImage_g); +} + +// +// +// +// HistogramRGBArea +HistogramRGBArea::HistogramRGBArea () ://needChroma unactive by default + frozen(false), valid(false), needRed(true), needGreen(true), needBlue(true), needLuma(true), rawMode(false), showMode(options.histogramBar), barDisplayed(options.histogramBar), needChroma(false){ + + harih = new HistogramRGBAreaIdleHelper; + harih->harea = this; + harih->destroyed = false; + harih->pending = 0; +} + +HistogramRGBArea::~HistogramRGBArea () { + + if (harih->pending) + harih->destroyed = true; + else + delete harih; +} + +bool HistogramRGBArea::getFreeze() { + return(frozen); +} + +bool HistogramRGBArea::getShow() { + return(showMode); +} + +void HistogramRGBArea::updateFreeze (bool f) { + frozen = f; + return; +} + +void HistogramRGBArea::renderRGBMarks (int r, int g, int b, Glib::ustring profile, Glib::ustring profileW) { + + if (!is_realized ()) + return; + + if (frozen) { + return; + } + + // Mostly not necessary, but should be in some case + GThreadLock lock; // All GUI acces from idle_add callbacks or separate thread HAVE to be protected + + Glib::RefPtr window = get_window(); + int winx, winy, winw, winh, wind; + window->get_geometry(winx, winy, winw, winh, wind); + + overlay = Gdk::Pixmap::create (window, winw, winh, -1); + Glib::RefPtr ovrl = Gdk::GC::create(overlay); + + Glib::RefPtr style = get_style (); + + if (!showMode) { + ovrl->set_foreground (style->get_bg (Gtk::STATE_NORMAL)); + overlay->draw_rectangle (ovrl, true, 0, 0, winw, winh); + if (rgbgc_ && overlay) { + window->draw_drawable (rgbgc_, overlay, 0, 0, 0, 0, -1, -1); } + return; } + else { + ovrl->set_foreground (mgray); + overlay->draw_rectangle (ovrl, true, 0, 0, winw, winh); + if (rgbgc_ && overlay) { + window->draw_drawable (rgbgc_, overlay, 0, 0, 0, 0, -1, -1); } + } + + Cairo::RefPtr cr = overlay->create_cairo_context(); + cr->set_line_width (1.0); + + if ( r != -1 && g != -1 && b != -1 ) { + if (needRed) { + // Red + cr->set_source_rgb(1.0, 0.0, 0.0); + cr->move_to((int)(r*(winw/256.0)), 0); + cr->line_to((int)(r*(winw/256.0)), winh-0); + cr->stroke(); + } + if (needGreen) { + // Green + cr->set_source_rgb(0.0, 1.0, 0.0); + cr->move_to((int)(g*(winw/256.0)), 0); + cr->line_to((int)(g*(winw/256.0)), winh-0); + cr->stroke(); + } + if (needBlue) { + // Blue + cr->set_source_rgb(0.0, 0.0, 1.0); + cr->move_to((int)(b*(winw/256.0)), 0); + cr->line_to((int)(b*(winw/256.0)), winh-0); + cr->stroke(); + } + if(needLuma || needChroma) { + float Lab_L,Lab_a,Lab_b; + rgb2lab( profile, profileW, r,g,b,Lab_L,Lab_a,Lab_b); + if (needLuma) { + // Luma + cr->set_source_rgb(1.0, 1.0, 1.0); + cr->move_to((int)((Lab_L)*(winw/100.0)), 0); + cr->line_to((int)((Lab_L)*(winw/100.0)), winh-0); + cr->stroke(); + } + if (needChroma) { + // Chroma + float chromaval = sqrt(Lab_a*Lab_a + Lab_b*Lab_b)/1.8; + // float chromaval = sqrt(Lab_a*Lab_a + Lab_b*Lab_b); + cr->set_source_rgb(0.0, 0.0, 0.0); + cr->move_to((int)(chromaval*(winw/100.0)), 0); + cr->line_to((int)(chromaval*(winw/100.0)), winh-0); + cr->stroke(); + } + } + } +} + +void HistogramRGBArea::rgb2lab (Glib::ustring profile, Glib::ustring profileW, int r, int g, int b, float &LAB_l, float &LAB_a, float &LAB_b) { + double xyz_rgb[3][3]; + const double ep=216.0/24389.0; + const double ka=24389.0/27.0; + + double var_R = r / 255.0; + double var_G = g / 255.0; + double var_B = b / 255.0; + + Glib::ustring profileCalc; + profileCalc="sRGB";//default + if(options.rtSettings.HistogramWorking) profileCalc=profileW;//display working + + else {// if you want display = output space + if (profile=="RT_sRGB" || profile=="RT_sRGB_gBT709" || profile=="RT_sRGB_g10") profileCalc="sRGB"; + if (profile=="ProPhoto" || profile=="RT_Large_gBT709" || profile=="RT_Large_g10" || profile=="RT_Large_gsRGB") profileCalc="ProPhoto"; + if (profile=="AdobeRGB1998" || profile=="RT_Medium_gsRGB") profileCalc="Adobe RGB"; + if (profile=="WideGamutRGB") profileCalc="WideGamut"; + } + if(options.rtSettings.HistogramWorking) {//display working + if (profileW=="sRGB") {//apply sRGB inverse gamma + + if ( var_R > 0.04045 ) + var_R = pow ( ( ( var_R + 0.055 ) / 1.055 ), rtengine::Color::sRGBGammaCurve); + else + var_R = var_R / 12.92; + if ( var_G > 0.04045 ) + var_G = pow ( ( ( var_G + 0.055 ) / 1.055 ), rtengine::Color::sRGBGammaCurve); + else + var_G = var_G / 12.92; + if ( var_B > 0.04045 ) + var_B = pow ( ( ( var_B + 0.055 ) / 1.055 ), rtengine::Color::sRGBGammaCurve); + else + var_B = var_B / 12.92; + } + else + if (profileW=="ProPhoto") {// apply inverse gamma 1.8 + var_R = pow ( var_R, 1.8); + var_G = pow ( var_G, 1.8); + var_B = pow ( var_B, 1.8); + } + else {// apply inverse gamma 2.2 + var_R = pow ( var_R, 2.2); + var_G = pow ( var_G, 2.2); + var_B = pow ( var_B, 2.2); + } + } + else {//display outout profile + + if (profile=="RT_sRGB" || profile=="RT_Large_gsRGB" || profile=="RT_Medium_gsRGB") {//apply sRGB inverse gamma + if ( var_R > 0.04045 ) + var_R = pow ( ( ( var_R + 0.055 ) / 1.055 ), rtengine::Color::sRGBGammaCurve); + else + var_R = var_R / 12.92; + if ( var_G > 0.04045 ) + var_G = pow ( ( ( var_G + 0.055 ) / 1.055 ), rtengine::Color::sRGBGammaCurve); + else + var_G = var_G / 12.92; + if ( var_B > 0.04045 ) + var_B = pow ( ( ( var_B + 0.055 ) / 1.055 ), rtengine::Color::sRGBGammaCurve); + else + var_B = var_B / 12.92; + } + + else if (profile=="RT_sRGB_gBT709" || profile=="RT_Large_gBT709") {// + if ( var_R > 0.0795 ) + var_R = pow ( ( ( var_R + 0.0954 ) / 1.0954 ), 2.2);else var_R=var_R/4.5; + + if ( var_G > 0.0795 ) + var_G = pow ( ( ( var_G + 0.0954 ) / 1.0954 ), 2.2);else var_G=var_G/4.5; + + if ( var_B > 0.0795 ) + var_B = pow ( ( ( var_B + 0.0954 ) / 1.0954 ), 2.2);else var_B=var_B/4.5; + + } + else if (profile=="ProPhoto") {// apply inverse gamma 1.8 + + var_R = pow ( var_R, 1.8); + var_G = pow ( var_G, 1.8); + var_B = pow ( var_B, 1.8); + } + else if (profile=="RT_sRGB_g10" || profile=="RT_Large_g10") {// apply inverse gamma 1.8 + + var_R = pow ( var_R, 1.); + var_G = pow ( var_G, 1.); + var_B = pow ( var_B, 1.); + } + + else {// apply inverse gamma 2.2 + var_R = pow ( var_R, 2.2); + var_G = pow ( var_G, 2.2); + var_B = pow ( var_B, 2.2); + } + } + // TMatrix wprof = rtengine::ICCStore::getInstance()->workingSpaceMatrix (profileW); + + TMatrix wprof = rtengine::ICCStore::getInstance()->workingSpaceMatrix (profileCalc); + + for (int m=0; m<3; m++) + for (int n=0; n<3; n++) { + xyz_rgb[m][n] = wprof[m][n]; + } + + double varxx,varyy,varzz; + double var_X = ( xyz_rgb[0][0]*var_R + xyz_rgb[0][1]*var_G + xyz_rgb[0][2]*var_B ) / Color::D50x; + double var_Y = ( xyz_rgb[1][0]*var_R + xyz_rgb[1][1]*var_G + xyz_rgb[1][2]*var_B ) ; + double var_Z = ( xyz_rgb[2][0]*var_R + xyz_rgb[2][1]*var_G + xyz_rgb[2][2]*var_B ) / Color::D50z; + + varxx = var_X>ep?cbrt(var_X):( ka * var_X + 16.0) / 116.0 ; + varyy = var_Y>ep?cbrt(var_Y):( ka * var_Y + 16.0) / 116.0 ; + varzz = var_Z>ep?cbrt(var_Z):( ka * var_Z + 16.0) / 116.0 ; + LAB_l = ( 116 * varyy ) - 16; + LAB_a = 500 * ( varxx - varyy ); + LAB_b = 200 * ( varyy - varzz ); + +} + + +int histrgbupdate (void* data) { + + HistogramRGBAreaIdleHelper* harih = static_cast(data); + + if (harih->destroyed) { + if (harih->pending == 1) + delete harih; + else + harih->pending--; + return 0; + } + + harih->harea->renderRGBMarks(-1,-1,-1); + harih->harea->queue_draw (); + + harih->pending--; + + return 0; +} + +void HistogramRGBArea::update (int valh, int rh, int gh, int bh) { + + if (valh) { + val=valh; + r=rh; + g=gh; + b=bh; + valid = true; + } + else + valid = false; + + harih->pending++; + g_idle_add (histrgbupdate, harih); +} + +void HistogramRGBArea::updateOptions (bool r, bool g, bool b, bool l, bool raw, bool bar, bool c) { + + needRed = r; + needGreen = g; + needBlue = b; + needLuma = l; + rawMode = raw; + showMode = bar; + needChroma = c; + + // Histogram RGB BAR button logic goes here + + if (bar && !barDisplayed) { + // Toggled on, add (show) the widget + parent->pack_start(*this, Gtk::PACK_SHRINK, 0); + options.histogramBar = true; + barDisplayed = true; + } + else if (!bar && barDisplayed){ + // Toggled off, remove (hide) the widget + removeIfThere(parent, this, false); + options.histogramBar = false; + barDisplayed = false; + // unfreeze + updateFreeze(false); + } + + // Disable (but don't hide it) the bar button when RAW histogram is displayed + if (rawMode) { + showMode = false; + } +} + +void HistogramRGBArea::on_realize () { + + Gtk::DrawingArea::on_realize(); + Glib::RefPtr window = get_window(); + rgbgc_ = Gdk::GC::create(window); + add_events(Gdk::EXPOSURE_MASK | Gdk::BUTTON_PRESS_MASK); + + Glib::RefPtr rgbcolormap = get_default_colormap(); + black = Gdk::Color ("black"); + red = Gdk::Color ("red"); + green = Gdk::Color ("green"); + blue = Gdk::Color ("blue"); + lgray = Gdk::Color ("gray75"); + mgray = Gdk::Color ("gray50"); + dgray = Gdk::Color ("gray25"); + rgbcolormap->alloc_color(black); + rgbcolormap->alloc_color(white); + rgbcolormap->alloc_color(red); + rgbcolormap->alloc_color(green); + rgbcolormap->alloc_color(blue); + rgbcolormap->alloc_color(lgray); + rgbcolormap->alloc_color(mgray); + rgbcolormap->alloc_color(dgray); + +} + +bool HistogramRGBArea::on_expose_event(GdkEventExpose* event) { + + Glib::RefPtr window = get_window(); + + // on_realize & RenderRGBMarks have to be called before + if (rgbgc_ && overlay) { + window->draw_drawable (rgbgc_, overlay, 0, 0, 0, 0, -1, -1); + } + + return true; +} + +bool HistogramRGBArea::on_button_press_event (GdkEventButton* event) { + + if (event->type==GDK_2BUTTON_PRESS && event->button==1) { + // do something. Maybe un-freeze ? + } + return true; +} + +void HistogramRGBArea::on_style_changed (const Glib::RefPtr& style) { + + white = get_style()->get_base(Gtk::STATE_NORMAL); + queue_draw (); +} + +// +// +// +// HistogramArea +HistogramArea::HistogramArea (FullModeListener *fml) : //needChroma unactive by default + valid(false), fullMode(options.histogramFullMode), myFullModeListener(fml), oldwidth(-1), oldheight(-1), needLuma(true), needRed(true), needGreen(true), needBlue(true), rawMode(false), needChroma(false) { + + lhist(256); + rhist(256); + ghist(256); + bhist(256); + chist(256); + + haih = new HistogramAreaIdleHelper; + haih->harea = this; + haih->destroyed = false; + haih->pending = 0; +} + +HistogramArea::~HistogramArea () { + + if (haih->pending) + haih->destroyed = true; + else + delete haih; + +} + +void HistogramArea::updateOptions (bool r, bool g, bool b, bool l, bool raw, bool full, bool c) { + + needRed = r; + needGreen = g; + needBlue = b; + needLuma = l; + rawMode = raw; + fullMode = !full; + needChroma = c; + + renderHistogram (); +} + +int histupdateUI (void* data) { + + HistogramAreaIdleHelper* haih = static_cast(data); + + if (haih->destroyed) { + if (haih->pending == 1) + delete haih; + else + haih->pending--; + + return 0; + } + + haih->harea->renderHistogram (); + haih->harea->queue_draw (); + + haih->pending--; + + return 0; +} + +void HistogramArea::update (LUTu &histRed, LUTu &histGreen, LUTu &histBlue, LUTu &histLuma, LUTu &histRedRaw, LUTu &histGreenRaw, LUTu &histBlueRaw, LUTu &histChroma) { + + if (histRed) { + lhist=histLuma;chist=histChroma; + rhist=histRed; ghist=histGreen; bhist=histBlue; + rhistRaw=histRedRaw; ghistRaw=histGreenRaw; bhistRaw=histBlueRaw; + + valid = true; + } + else + valid = false; + + haih->pending++; + // Can be done outside of the GUI thread + g_idle_add (histupdateUI, haih); +} + +void HistogramArea::renderHistogram () { + + if (!is_realized ()) + return; + + Glib::RefPtr window = get_window(); + int winx, winy, winw, winh, wind; + window->get_geometry(winx, winy, winw, winh, wind); + + backBuffer = Gdk::Pixmap::create (window, winw, winh, -1); + + Glib::RefPtr bgc = Gdk::GC::create(backBuffer); + + bgc->set_foreground (white); + backBuffer->draw_rectangle (bgc, true, 0, 0, winw, winh); + + if (valid) { + // For RAW mode use the other hists + LUTu& rh = rawMode ? rhistRaw : rhist; + LUTu& gh = rawMode ? ghistRaw : ghist; + LUTu& bh = rawMode ? bhistRaw : bhist; + + // make double copies of LUT, one for faster access, another one to scale down the raw histos + LUTu rhchanged(256),ghchanged(256),bhchanged(256); + unsigned int lhisttemp[256],chisttemp[256],rhtemp[256],ghtemp[256],bhtemp[256]; + const int scale = (rawMode ? 8 : 1); + for(int i=0;i<256;i++) { + if(needLuma) + lhisttemp[i] = lhist[i]; + if(needChroma) + chisttemp[i] = chist[i]; + if(needRed) + rhchanged[i] = rhtemp[i] = rh[i] / scale; + if(needGreen) + ghchanged[i] = ghtemp[i] = gh[i] / scale; + if(needBlue) + bhchanged[i] = bhtemp[i] = bh[i] / scale; + } + + // compute height of the full histogram (realheight) and + // does not take into account 0 and 255 values + // them are handled separately + + int fullhistheight = 0; + for (int i=1; i<255; i++) { + if (needLuma && lhisttemp[i]>fullhistheight) + fullhistheight = lhisttemp[i]; + if (needChroma && chisttemp[i]>fullhistheight) + fullhistheight = chisttemp[i]; + if (needRed && rhtemp[i]>fullhistheight) + fullhistheight = rhtemp[i]; + if (needGreen && ghtemp[i]>fullhistheight) + fullhistheight = ghtemp[i]; + if (needBlue && bhtemp[i]>fullhistheight) + fullhistheight = bhtemp[i]; + } + + int realhistheight = fullhistheight; + + // though much faster than before, this still takes a lot of time especially for big files if rawMode is true + if (!fullMode) { + int area = 0; + if(!rawMode) + for (int i=0; ii) || (needChroma && chisttemp[j]>i) || (needRed && rhtemp[j]>i) || (needGreen && ghtemp[j]>i) || (needBlue && bhtemp[j]>i)) + area++; + if ((double)area / (256*(i+1)) < 0.3) { + realhistheight = i; + break; + } + } + else + for (int i=0; ii) || (needGreen && ghtemp[j]>i) || (needBlue && bhtemp[j]>i)) + area++; + if ((double)area / (256*(i+1)) < 0.3) { + realhistheight = i; + break; + } + } + + } + + if (realhistheight cr = backBuffer->create_cairo_context(); + cr->set_antialias (Cairo::ANTIALIAS_SUBPIXEL); + cr->set_line_width (1.0); + + int ui = 0, oi = 0; + + if (needLuma && !rawMode) { + drawCurve(cr, lhist, realhistheight, winw, winh); + cr->set_source_rgb (0.75, 0.75, 0.75); + cr->fill_preserve (); + cr->set_source_rgb (0.5, 0.5, 0.5); + cr->stroke (); + + drawMarks(cr, lhist, realhistheight, winw, ui, oi); + } + if (needChroma && !rawMode) { + drawCurve(cr, chist, realhistheight, winw, winh); + cr->set_source_rgb (0.6, 0.6, 0.6); + // cr->fill_preserve (); + // cr->set_source_rgb (0.2, 0.2, 0.1); + cr->stroke (); + + drawMarks(cr, chist, realhistheight, winw, ui, oi); + } + if (needRed) { + drawCurve(cr, rhchanged, realhistheight, winw, winh); + cr->set_source_rgb (1.0, 0.0, 0.0); + cr->stroke (); + + drawMarks(cr, rhchanged, realhistheight, winw, ui, oi); + } + if (needGreen) { + drawCurve(cr, ghchanged, realhistheight, winw, winh); + cr->set_source_rgb (0.0, 1.0, 0.0); + cr->stroke (); + + drawMarks(cr, ghchanged, realhistheight, winw, ui, oi); + } + if (needBlue) { + drawCurve(cr, bhchanged, realhistheight, winw, winh); + cr->set_source_rgb (0.0, 0.0, 1.0); + cr->stroke (); + + drawMarks(cr, bhchanged, realhistheight, winw, ui, oi); + } + } + + bgc->set_foreground (mgray); + backBuffer->draw_rectangle (bgc, false, 0, 0, winw-1, winh-1); + + bgc->set_line_attributes (1, Gdk::LINE_ON_OFF_DASH, Gdk::CAP_NOT_LAST, Gdk::JOIN_MITER); + + backBuffer->draw_line (bgc, winw/4, 0, winw/4, winh); + backBuffer->draw_line (bgc, 2*winw/4, 0, 2*winw/4, winh); + backBuffer->draw_line (bgc, 3*winw/4, 0, 3*winw/4, winh); + backBuffer->draw_line (bgc, 0, winh/4, winw, winh/4); + backBuffer->draw_line (bgc, 0, 2*winh/4, winw, 2*winh/4); + backBuffer->draw_line (bgc, 0, 3*winh/4, winw, 3*winh/4); + + bgc->set_line_attributes (1, Gdk::LINE_SOLID, Gdk::CAP_NOT_LAST, Gdk::JOIN_MITER); + + oldwidth = winw; + oldheight = winh; +} + +void HistogramArea::on_realize () { + + Gtk::DrawingArea::on_realize(); + Glib::RefPtr window = get_window(); + gc_ = Gdk::GC::create(window); + add_events(Gdk::EXPOSURE_MASK | Gdk::BUTTON_PRESS_MASK); + Glib::RefPtr colormap = get_default_colormap(); + + black = Gdk::Color ("black"); + red = Gdk::Color ("red"); + green = Gdk::Color ("green"); + blue = Gdk::Color ("blue"); + lgray = Gdk::Color ("gray75"); + mgray = Gdk::Color ("gray50"); + dgray = Gdk::Color ("gray25"); + colormap->alloc_color(black); + colormap->alloc_color(white); + colormap->alloc_color(red); + colormap->alloc_color(green); + colormap->alloc_color(blue); + colormap->alloc_color(lgray); + colormap->alloc_color(mgray); + colormap->alloc_color(dgray); + +} + +void HistogramArea::drawCurve(Cairo::RefPtr &cr, + LUTu & data, double scale, int hsize, int vsize) +{ + cr->move_to (0, vsize-1); + for (int i = 0; i < 256; i++) { + double val = data[i] * (double)(vsize-2) / scale; + if (val > vsize - 1) + val = vsize - 1; + cr->line_to ((i/255.0)*(hsize - 1), vsize - 1 - val); + } + cr->line_to (hsize - 1, vsize - 1); +} + +void HistogramArea::drawMarks(Cairo::RefPtr &cr, + LUTu & data, double scale, int hsize, int & ui, int & oi) +{ + int s = 8; + + if(data[0] > scale) { + cr->rectangle(0, (ui++)*s, s, s); + } + if(data[255] > scale) { + cr->rectangle(hsize - s, (oi++)*s, s, s); + } + cr->fill(); +} + +void HistogramArea::on_style_changed (const Glib::RefPtr& style) { + + white = get_style()->get_base(Gtk::STATE_NORMAL); + queue_draw (); +} + +bool HistogramArea::on_expose_event(GdkEventExpose* event) { + + Glib::RefPtr window = get_window(); + + int winx, winy, winw, winh, wind; + window->get_geometry(winx, winy, winw, winh, wind); + + if (winw!=oldwidth && winh!=oldheight) + renderHistogram (); + window->draw_drawable (gc_, backBuffer, 0, 0, 0, 0, -1, -1); + + return true; +} + +bool HistogramArea::on_button_press_event (GdkEventButton* event) { + + if (event->type==GDK_2BUTTON_PRESS && event->button==1) { + fullMode = !fullMode; + options.histogramFullMode = fullMode; + if (myFullModeListener) + myFullModeListener->toggle_button_full (); + renderHistogram (); + queue_draw (); + } + return true; +} + diff --git a/rtgui/histogrampanel.h b/rtgui/histogrampanel.h new file mode 100644 index 000000000..1fd0ec906 --- /dev/null +++ b/rtgui/histogrampanel.h @@ -0,0 +1,228 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _HISTOGRAMPANEL_ +#define _HISTOGRAMPANEL_ + + +#include +#include +#include "../rtengine/LUT.h" +#include "../rtengine/improccoordinator.h" + +#include "pointermotionlistener.h" + +class HistogramArea; +struct HistogramAreaIdleHelper { + HistogramArea* harea; + bool destroyed; + int pending; +}; + +class HistogramRGBArea; +struct HistogramRGBAreaIdleHelper { + HistogramRGBArea* harea; + bool destroyed; + int pending; +}; + +class HistogramRGBArea : public Gtk::DrawingArea { + + typedef const double (*TMatrix)[3]; + + protected: + + Glib::RefPtr rgbgc_; + Glib::RefPtr overlay; + + Gdk::Color black; + Gdk::Color white; + Gdk::Color red; + Gdk::Color green; + Gdk::Color blue; + Gdk::Color lgray; + Gdk::Color mgray; + Gdk::Color dgray; + + int val; + int r; + int g; + int b; + + bool frozen; + bool valid; + + bool needRed; + bool needGreen; + bool needBlue; + bool needLuma; + bool rawMode; + bool showMode; + bool barDisplayed; + bool needChroma; + + Gtk::VBox* parent; + + HistogramRGBAreaIdleHelper* harih; + + public: + + HistogramRGBArea(); + ~HistogramRGBArea(); + + void renderRGBMarks (int r, int g, int b, Glib::ustring profile = "", Glib::ustring profileW = ""); + void updateFreeze (bool f); + bool getFreeze (); + bool getShow (); + void setParent (Gtk::VBox* p) { parent = p; }; + + void update (int val, int rh, int gh, int bh); + void updateOptions (bool r, bool g, bool b, bool l, bool raw, bool show, bool c); + + void on_realize(); + bool on_expose_event(GdkEventExpose* event); + bool on_button_press_event (GdkEventButton* event); + void on_style_changed (const Glib::RefPtr& style); + private: + void rgb2lab (Glib::ustring profile, Glib::ustring profileW,int r, int g, int b, float &LAB_l, float &LAB_a, float &LAB_b); + // Some ... +}; + + +class FullModeListener { + public: + virtual void toggle_button_full () {} +}; + +class HistogramArea : public Gtk::DrawingArea{ + + protected: + + Glib::RefPtr gc_; + Glib::RefPtr backBuffer; + + Gdk::Color black; + Gdk::Color white; + Gdk::Color red; + Gdk::Color green; + Gdk::Color blue; + Gdk::Color lgray; + Gdk::Color mgray; + Gdk::Color dgray; + LUTu lhist, rhist, ghist, bhist, chist; + LUTu lhistRaw, rhistRaw, ghistRaw, bhistRaw; + + bool valid; + bool fullMode; + FullModeListener *myFullModeListener; + int oldwidth, oldheight; + + bool needLuma, needRed, needGreen, needBlue, rawMode, needChroma; + + HistogramAreaIdleHelper* haih; + + public: + + HistogramArea(FullModeListener *fml=NULL); + ~HistogramArea(); + + void renderHistogram (); + void update (LUTu &histRed, LUTu &histGreen, LUTu &histBlue, LUTu &histLuma, LUTu &histRedRaw, LUTu &histGreenRaw, LUTu &histBlueRaw, LUTu &histChroma); + void updateOptions (bool r, bool g, bool b, bool l, bool raw, bool full , bool c); + void on_realize(); + bool on_expose_event(GdkEventExpose* event); + bool on_button_press_event (GdkEventButton* event); + void on_style_changed (const Glib::RefPtr& style); + private: + void drawCurve(Cairo::RefPtr &cr, + LUTu & data, double scale, int hsize, int vsize); + void drawMarks(Cairo::RefPtr &cr, + LUTu & data, double scale, int hsize, int & ui, int & oi); +}; + +class HistogramPanel : public Gtk::HBox, public PointerMotionListener, public FullModeListener { + + protected: + + Gtk::VBox* gfxVBox; + Gtk::VBox* buttonVBox; + HistogramArea* histogramArea; + HistogramRGBArea* histogramRGBArea; + Gtk::ToggleButton* showRed; + Gtk::ToggleButton* showGreen; + Gtk::ToggleButton* showBlue; + Gtk::ToggleButton* showValue; + Gtk::ToggleButton* showRAW; + Gtk::ToggleButton* showFull; + Gtk::ToggleButton* showBAR; + Gtk::ToggleButton* showChro; + + Gtk::Image *redImage; + Gtk::Image *greenImage; + Gtk::Image *blueImage; + Gtk::Image *valueImage; + Gtk::Image *rawImage; + Gtk::Image *fullImage; + Gtk::Image *barImage; + Gtk::Image *chroImage; + + Gtk::Image *redImage_g; + Gtk::Image *greenImage_g; + Gtk::Image *blueImage_g; + Gtk::Image *valueImage_g; + Gtk::Image *rawImage_g; + Gtk::Image *fullImage_g; + Gtk::Image *barImage_g; + Gtk::Image *chroImage_g; + + + sigc::connection rconn; + void setHistInvalid (); + + public: + + HistogramPanel (); + ~HistogramPanel (); + + void histogramChanged (LUTu &histRed, LUTu &histGreen, LUTu &histBlue, LUTu &histLuma, LUTu &histRedRaw, LUTu &histGreenRaw, LUTu &histBlueRaw, LUTu &histChroma) { + histogramArea->update (histRed, histGreen, histBlue, histLuma, histRedRaw, histGreenRaw, histBlueRaw, histChroma); + } + // pointermotionlistener interface + void pointerMoved (bool validPos, Glib::ustring profile, Glib::ustring profileW,int x, int y, int r, int g, int b); + // added pointermotionlistener interface + void toggleFreeze(); + // TODO should be protected + void setHistRGBInvalid (); + + void reorder (Gtk::AlignmentEnum align); + void red_toggled (); + void green_toggled (); + void blue_toggled (); + void value_toggled (); + void raw_toggled (); + void full_toggled (); + void chro_toggled (); + void bar_toggled (); + void rgbv_toggled (); + void resized (Gtk::Allocation& req); + + // fullModeListener interface + void toggle_button_full (); +}; + +#endif diff --git a/rtgui/history.cc b/rtgui/history.cc new file mode 100644 index 000000000..0e58ae5b5 --- /dev/null +++ b/rtgui/history.cc @@ -0,0 +1,340 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "history.h" +#include "multilangmgr.h" +#include "rtimage.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +Glib::ustring eventDescrArray[NUMOFEVENTS]; +extern Glib::ustring argv0; + +History::History (bool bookmarkSupport) : blistener(NULL), tpc (NULL), bmnum (1) { + + blistenerLock = false; // sets default that the Before preview will not be locked + + // fill history event message array + for (int i=0; iset_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC); + + Gtk::Frame* histFrame = Gtk::manage (new Gtk::Frame (M("HISTORY_LABEL"))); + histFrame->add (*hscrollw); + + hTreeView = Gtk::manage (new Gtk::TreeView ()); + hscrollw->add (*hTreeView); + + historyModel = Gtk::ListStore::create (historyColumns); + hTreeView->set_model (historyModel); +// hTreeView->set_headers_visible (false); + + Gtk::CellRendererText *changecrt = Gtk::manage (new Gtk::CellRendererText()); + Gtk::CellRendererText *valuecrt = Gtk::manage (new Gtk::CellRendererText()); + Gtk::TreeView::Column *hviewcol = Gtk::manage (new Gtk::TreeView::Column ("")); + hviewcol->pack_start (*changecrt, true); + hviewcol->add_attribute (changecrt->property_markup (), historyColumns.text); + hviewcol->set_resizable (true); + + Gtk::TreeView::Column *hviewcol2 = Gtk::manage (new Gtk::TreeView::Column ("")); + hviewcol2->pack_start (*valuecrt, true); + hviewcol2->add_attribute (valuecrt->property_markup (), historyColumns.value); + valuecrt->set_property ("xalign", 1.0); + + hTreeView->append_column (*hviewcol); + hTreeView->append_column (*hviewcol2); + + hviewcol2->set_sizing (Gtk::TREE_VIEW_COLUMN_FIXED); + + selchangehist = hTreeView->get_selection()->signal_changed().connect(sigc::mem_fun(*this, &History::historySelectionChanged)); + + // Bookmark List + // ~~~~~~~~~~~~~ + + Gtk::HSeparator* hsepb = Gtk::manage (new Gtk::HSeparator ()); + pack_end (*hsepb, Gtk::PACK_SHRINK, 0); + + Gtk::HBox* ahbox = Gtk::manage (new Gtk::HBox ()); + addBookmark = Gtk::manage (new Gtk::Button (M("HISTORY_NEWSNAPSHOT"))); + addBookmark->set_tooltip_markup (M("HISTORY_NEWSNAPSHOT_TOOLTIP")); + Gtk::Image* addimg = Gtk::manage (new RTImage ("gtk-add.png")); + addBookmark->set_image (*addimg); + ahbox->pack_start (*addBookmark); + + delBookmark = Gtk::manage (new Gtk::Button (M("HISTORY_DELSNAPSHOT"))); + Gtk::Image* delimg = Gtk::manage (new RTImage ("list-remove.png")); + delBookmark->set_image (*delimg); + ahbox->pack_start (*delBookmark); + + bscrollw = Gtk::manage (new Gtk::ScrolledWindow ()); +// bscrollw->set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + bscrollw->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC); + bscrollw->set_size_request (-1, 75); + + Gtk::Frame* bmFrame = Gtk::manage (new Gtk::Frame (M("HISTORY_SNAPSHOTS"))); + Gtk::VBox* bmBox = Gtk::manage (new Gtk::VBox ()); + bmFrame->add (*bmBox); + bmBox->pack_start (*bscrollw, Gtk::PACK_EXPAND_WIDGET, 4); + bmBox->pack_end (*ahbox, Gtk::PACK_SHRINK, 4); + + if (bookmarkSupport){ + historyVPaned = Gtk::manage ( new Gtk::VPaned () ); + historyVPaned->pack1 (*histFrame, true, true); + historyVPaned->pack2 (*bmFrame, false, true); + pack_start(*historyVPaned); + } + else{ + pack_start (*histFrame); + } + + + bTreeView = Gtk::manage (new Gtk::TreeView ()); + bscrollw->add (*bTreeView); + + bookmarkModel = Gtk::ListStore::create (bookmarkColumns); + bTreeView->set_model (bookmarkModel); + bTreeView->set_headers_visible (false); + bTreeView->append_column_editable (M("HISTORY_SNAPSHOTS"), bookmarkColumns.text); + + selchangebm = bTreeView->get_selection()->signal_changed().connect(sigc::mem_fun(*this, &History::bookmarkSelectionChanged)); + + addBookmark->signal_clicked().connect( sigc::mem_fun(*this, &History::addBookmarkPressed) ); + delBookmark->signal_clicked().connect( sigc::mem_fun(*this, &History::delBookmarkPressed) ); + +// hTreeView->set_grid_lines (Gtk::TREE_VIEW_GRID_LINES_HORIZONTAL); + hTreeView->set_grid_lines (Gtk::TREE_VIEW_GRID_LINES_BOTH); + hTreeView->signal_size_allocate().connect( sigc::mem_fun(*this, &History::resized) ); + + hTreeView->set_enable_search(false); + bTreeView->set_enable_search(false); + + show_all_children (); +} + +void History::initHistory () { + + historyModel->clear (); + bookmarkModel->clear (); +} + +void History::clearParamChanges () { + + initHistory (); +} + +void History::historySelectionChanged () { + + Glib::RefPtr selection = hTreeView->get_selection(); + Gtk::TreeModel::iterator iter = selection->get_selected(); + if (iter) { + Gtk::TreeModel::Row row = *iter; + if (row) + bTreeView->get_selection()->unselect_all (); + if (row && tpc) { + ProcParams pparams = row[historyColumns.params]; + ParamsEdited pe(true); + PartialProfile pp(&pparams, &pe); + ParamsEdited paramsEdited = row[historyColumns.paramsEdited]; + tpc->profileChange (&pp, EvHistoryBrowsed, row[historyColumns.text], ¶msEdited); + } + if (blistener && blistenerLock==false) { + Gtk::TreeModel::Path path = historyModel->get_path (iter); + path.prev (); + iter = historyModel->get_iter (path); + if (blistener && iter) + blistener->historyBeforeLineChanged (iter->get_value (historyColumns.params)); + } + } +} + +void History::bookmarkSelectionChanged () { + + Glib::RefPtr selection = bTreeView->get_selection(); + Gtk::TreeModel::iterator iter = selection->get_selected(); + if (iter) { + Gtk::TreeModel::Row row = *iter; + if (row) + hTreeView->get_selection()->unselect_all (); + if (row && tpc) { + ProcParams pparams = row[bookmarkColumns.params]; + ParamsEdited pe(true); + PartialProfile pp(&pparams, &pe); + ParamsEdited paramsEdited = row[bookmarkColumns.paramsEdited]; + tpc->profileChange (&pp, EvBookmarkSelected, row[bookmarkColumns.text], ¶msEdited); + } + } +} + +void History::procParamsChanged (ProcParams* params, ProcEvent ev, Glib::ustring descr, ParamsEdited* paramsEdited) { + + // to prevent recursion, we filter out the events triggered by the history + if (ev==EvHistoryBrowsed) + return; + + selchangehist.block (true); + + if (ev==EvPhotoLoaded) + initHistory (); + // construct formatted list content + Glib::ustring text = Glib::ustring::compose ("%1", eventDescrArray[ev]); + + Glib::RefPtr selection = hTreeView->get_selection(); + Gtk::TreeModel::iterator iter = selection->get_selected(); + // remove all rows after the selection + if (iter) { + iter++; + while (iter) + iter = historyModel->erase (iter); + } + // lookup the last remaining item in the list + int size = historyModel->children().size (); + Gtk::TreeModel::Row row; + if (size>0) + row = historyModel->children()[size-1]; + // 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.chev] = ev; + newrow[historyColumns.params] = *params; + newrow[historyColumns.paramsEdited] = paramsEdited ? *paramsEdited : defParamsEdited; + if (ev!=EvBookmarkSelected) + selection->select (newrow); + if (blistener && row && blistenerLock==false) + blistener->historyBeforeLineChanged (row[historyColumns.params]); + else if (blistener && size==0 && blistenerLock==false) + blistener->historyBeforeLineChanged (newrow[historyColumns.params]); + } + // else just update it + else { + row[historyColumns.realText] = eventDescrArray[ev]; + row[historyColumns.text] = text; + row[historyColumns.value] = descr; + row[historyColumns.chev] = ev; + row[historyColumns.params] = *params; + row[historyColumns.paramsEdited] = paramsEdited ? *paramsEdited : defParamsEdited; + if (ev!=EvBookmarkSelected) + selection->select (row); + } + if (ev!=EvBookmarkSelected) + bTreeView->get_selection()->unselect_all (); + + + if (!selection->get_selected_rows().empty()) { + Gtk::TreeView::Selection::ListHandle_Path selp = selection->get_selected_rows(); + hTreeView->scroll_to_row (*selp.begin()); + } + selchangehist.block (false); +} + +void History::addBookmarkWithText (Glib::ustring text) { + + // lookup the selected item in the history + Glib::RefPtr selection = hTreeView->get_selection(); + Gtk::TreeModel::iterator iter = selection->get_selected(); + Gtk::TreeModel::Row row = *iter; + + if (!row) { + return; + } + + // append new row to bookmarks + Gtk::TreeModel::Row newrow = *(bookmarkModel->append()); + newrow[bookmarkColumns.text] = text; + ProcParams params = row[historyColumns.params]; + newrow[bookmarkColumns.params] = params; + ParamsEdited paramsEdited = row[historyColumns.paramsEdited]; + newrow[bookmarkColumns.paramsEdited] = paramsEdited; +} + +void History::addBookmarkPressed () { + + if (hTreeView->get_selection()->get_selected()) + addBookmarkWithText (Glib::ustring::compose ("%1 %2", M("HISTORY_SNAPSHOT"), bmnum++)); +} + +void History::delBookmarkPressed () { + + // lookup the selected item in the bookmark + Glib::RefPtr selection = bTreeView->get_selection(); + Gtk::TreeModel::iterator iter = selection->get_selected(); + + if (!iter) { + return; + } + // remove selected bookmark + bookmarkModel->erase (iter); + // select last item in history + int size = historyModel->children().size (); + Gtk::TreeModel::Row row = historyModel->children()[size-1]; + hTreeView->get_selection()->select (row); +} + +void History::undo () { + + Glib::RefPtr selection = hTreeView->get_selection(); + Gtk::TreeModel::iterator iter = selection->get_selected(); + + if (iter && iter!=historyModel->children().begin()) + selection->select (--iter); + else if (!iter) { + int size = historyModel->children().size (); + if (size>1) + selection->select (historyModel->children()[size-2]); + } +} + +void History::redo () { + + Glib::RefPtr selection = hTreeView->get_selection(); + Gtk::TreeModel::iterator iter = selection->get_selected(); + + if (iter) { + iter++; + if (iter!=historyModel->children().end()) + selection->select (iter); + } + else { + int size = historyModel->children().size (); + if (size>1) + selection->select (historyModel->children()[size-2]); + } +} + +void History::resized (Gtk::Allocation& req) { +} + +bool History::getBeforeLineParams (rtengine::procparams::ProcParams& params) { + + int size = historyModel->children().size (); + if (size==0 || !blistener) + return false; + + Gtk::TreeModel::Row row; + row = historyModel->children()[size==1 ? 0 : size-2]; + params = row[historyColumns.params]; + return true; +} + diff --git a/rtgui/history.h b/rtgui/history.h new file mode 100644 index 000000000..3400b7ad2 --- /dev/null +++ b/rtgui/history.h @@ -0,0 +1,108 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _HISTORY_ +#define _HISTORY_ + +#include +#include "../rtengine/rtengine.h" +#include "pparamschangelistener.h" +#include "profilechangelistener.h" +#include "paramsedited.h" + +class HistoryBeforeLineListener { + + public: + virtual void historyBeforeLineChanged (const rtengine::procparams::ProcParams& params) {} +}; + +class History : public Gtk::VBox, public PParamsChangeListener { + + public: + + class HistoryColumns : public Gtk::TreeModel::ColumnRecord { + public: + Gtk::TreeModelColumn realText; + Gtk::TreeModelColumn text; + Gtk::TreeModelColumn value; + Gtk::TreeModelColumn params; + Gtk::TreeModelColumn chev; + Gtk::TreeModelColumn paramsEdited; + HistoryColumns() { add(text); add(realText); add(value); add(chev); add(params); add(paramsEdited); } + }; + HistoryColumns historyColumns; + class BookmarkColumns : public Gtk::TreeModel::ColumnRecord { + public: + Gtk::TreeModelColumn text; + Gtk::TreeModelColumn params; + Gtk::TreeModelColumn paramsEdited; + BookmarkColumns() { add(text); add(params); add(paramsEdited); } + }; + BookmarkColumns bookmarkColumns; + + protected: + Gtk::VPaned* historyVPaned; + Gtk::ScrolledWindow* hscrollw; + Gtk::TreeView* hTreeView; + Glib::RefPtr historyModel; + + Gtk::ScrolledWindow* bscrollw; + Gtk::TreeView* bTreeView; + Glib::RefPtr bookmarkModel; + + Gtk::Button* addBookmark; + Gtk::Button* delBookmark; + + sigc::connection selchangehist; + sigc::connection selchangebm; + + HistoryBeforeLineListener * blistener; + ProfileChangeListener* tpc; + ParamsEdited defParamsEdited; + int bmnum; + + public: + + History (bool bookmarkSupport = true); + + void setProfileChangeListener (ProfileChangeListener* tpc_) { tpc = tpc_; } + void setHistoryBeforeLineListener (HistoryBeforeLineListener* bll) { blistener = bll; } + + // pparamschangelistener interface + void procParamsChanged (rtengine::procparams::ProcParams* params, rtengine::ProcEvent ev, Glib::ustring descr, ParamsEdited* paramsEdited=NULL); + void clearParamChanges (); + + void historySelectionChanged (); + void bookmarkSelectionChanged (); + void initHistory (); + + bool getBeforeLineParams (rtengine::procparams::ProcParams& params); + + void addBookmarkWithText (Glib::ustring text); + void addBookmarkPressed (); + void delBookmarkPressed (); + + void resized (Gtk::Allocation& req); + + void undo (); + void redo (); + + bool blistenerLock; +}; + +#endif diff --git a/rtgui/hsvequalizer.cc b/rtgui/hsvequalizer.cc new file mode 100644 index 000000000..ccd9ee8e0 --- /dev/null +++ b/rtgui/hsvequalizer.cc @@ -0,0 +1,179 @@ +/* + * This file is part of RawTherapee. + * + * 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 . + * + * 2010 Ilya Popov + */ + +#include "hsvequalizer.h" +#include "../rtengine/color.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +HSVEqualizer::HSVEqualizer () : FoldableToolPanel(this, "hsvequalizer", M("TP_HSVEQUALIZER_LABEL")) { + + std::vector bottomMilestones; + float R, G, B; + // -0.1 rad < Hue < 1.6 rad + for (int i=0; i<7; i++) { + float x = float(i)*(1.0f/6.0); + Color::hsv2rgb01(x, 0.5f, 0.5f, R, G, B); + bottomMilestones.push_back( GradientMilestone(double(x), double(R), double(G), double(B)) ); + } + + curveEditorG = new CurveEditorGroup (options.lastHsvCurvesDir, M("TP_HSVEQUALIZER_CHANNEL")); + curveEditorG->setCurveListener (this); + + hshape = static_cast(curveEditorG->addCurve(CT_Flat, M("TP_HSVEQUALIZER_HUE"))); + hshape->setEditID(EUID_HSV_H, BT_SINGLEPLANE_FLOAT); + hshape->setBottomBarBgGradient(bottomMilestones); + //hshape->setLeftBarColorProvider(this); Not working yet + hshape->setCurveColorProvider(this, 1); + + sshape = static_cast(curveEditorG->addCurve(CT_Flat, M("TP_HSVEQUALIZER_SAT"))); + sshape->setEditID(EUID_HSV_S, BT_SINGLEPLANE_FLOAT); + sshape->setBottomBarBgGradient(bottomMilestones); + //sshape->setLeftBarColorProvider(this); Not working yet + sshape->setCurveColorProvider(this, 2); + + vshape = static_cast(curveEditorG->addCurve(CT_Flat, M("TP_HSVEQUALIZER_VAL"))); + vshape->setEditID(EUID_HSV_V, BT_SINGLEPLANE_FLOAT); + vshape->setBottomBarBgGradient(bottomMilestones); + //vshape->setLeftBarColorProvider(this); Not working yet + vshape->setCurveColorProvider(this, 3); + + // This will add the reset button at the end of the curveType buttons + curveEditorG->curveListComplete(); + + pack_start (*curveEditorG, Gtk::PACK_SHRINK, 4); + + //curveEditorG->show(); +} + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +HSVEqualizer::~HSVEqualizer () { + delete curveEditorG; +} + + +void HSVEqualizer::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + if (pedited) { + hshape->setUnChanged (!pedited->hsvequalizer.hcurve); + sshape->setUnChanged (!pedited->hsvequalizer.scurve); + vshape->setUnChanged (!pedited->hsvequalizer.vcurve); + } + + hshape->setCurve (pp->hsvequalizer.hcurve); + sshape->setCurve (pp->hsvequalizer.scurve); + vshape->setCurve (pp->hsvequalizer.vcurve); + + enableListener (); +} + +void HSVEqualizer::setEditProvider (EditDataProvider *provider) { + hshape->setEditProvider(provider); + sshape->setEditProvider(provider); + vshape->setEditProvider(provider); +} + +void HSVEqualizer::autoOpenCurve () { + // Open up the first curve if selected + bool active = hshape->openIfNonlinear(); + if (!active) sshape->openIfNonlinear(); + if (!active) vshape->openIfNonlinear(); +} + +void HSVEqualizer::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->hsvequalizer.hcurve = hshape->getCurve (); + pp->hsvequalizer.scurve = sshape->getCurve (); + pp->hsvequalizer.vcurve = vshape->getCurve (); + + if (pedited) { + + pedited->hsvequalizer.hcurve = !hshape->isUnChanged (); + pedited->hsvequalizer.scurve = !sshape->isUnChanged (); + pedited->hsvequalizer.vcurve = !vshape->isUnChanged (); + } +} + +/* + * Curve listener + * + * If more than one curve has been added, the curve listener is automatically + * set to 'multi=true', and send a pointer of the modified curve in a parameter + */ +void HSVEqualizer::curveChanged (CurveEditor* ce) { + + if (listener) { + if (ce == hshape) + listener->panelChanged (EvHSVEqualizerH, M("HISTORY_CUSTOMCURVE")); + if (ce == sshape) + listener->panelChanged (EvHSVEqualizerS, M("HISTORY_CUSTOMCURVE")); + if (ce == vshape) + listener->panelChanged (EvHSVEqualizerV, M("HISTORY_CUSTOMCURVE")); + } +} + +void HSVEqualizer::colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller* caller) { + + float r, g, b; + + if (elemType==ColorCaller::CCET_VERTICAL_BAR) + valY = 0.5; + + if (callerId == 1) { // Hue = f(Hue) + + float h = float((valY - 0.5) * 2. + valX); + if (h > 1.0f) + h -= 1.0f; + else if (h < 0.0f) + h += 1.0f; + Color::hsv2rgb01(h, 0.5f, 0.5f, r, g, b); + caller->ccRed = double(r); + caller->ccGreen = double(g); + caller->ccBlue = double(b); + } + else if (callerId == 2) { // Saturation = f(Hue) + Color::hsv2rgb01(float(valX), float(valY), 0.5f, r, g, b); + caller->ccRed = double(r); + caller->ccGreen = double(g); + caller->ccBlue = double(b); + } + else if (callerId == 3) { // Value = f(Hue) + Color::hsv2rgb01(float(valX), 0.5f, float(valY), r, g, b); + caller->ccRed = double(r); + caller->ccGreen = double(g); + caller->ccBlue = double(b); + } + else { + printf("Error: no curve displayed!\n"); + } + +} + +void HSVEqualizer::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + + curveEditorG->setBatchMode (batchMode); +} diff --git a/rtgui/hsvequalizer.h b/rtgui/hsvequalizer.h new file mode 100644 index 000000000..b35bb1337 --- /dev/null +++ b/rtgui/hsvequalizer.h @@ -0,0 +1,59 @@ +/* + * This file is part of RawTherapee. + * + * 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 . + * + * 2010 Ilya Popov + */ + +#ifndef HSVEQUALIZER_H_INCLUDED +#define HSVEQUALIZER_H_INCLUDED + +#include +#include "adjuster.h" +#include "toolpanel.h" +#include "guiutils.h" +#include "curveeditor.h" +#include "curveeditorgroup.h" +#include "colorprovider.h" + + +class HSVEqualizer : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public CurveListener, public ColorProvider +{ + +protected: + + CurveEditorGroup* curveEditorG; + FlatCurveEditor* hshape; + FlatCurveEditor* sshape; + FlatCurveEditor* vshape; + +public: + + HSVEqualizer (); + virtual ~HSVEqualizer (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void curveChanged (CurveEditor* ce); + //void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + void setEditProvider (EditDataProvider *provider); + void autoOpenCurve (); + virtual void colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller* caller); + + //void adjusterChanged (Adjuster* a, double newval); +}; + +#endif diff --git a/rtgui/iccfromwindows.txt b/rtgui/iccfromwindows.txt new file mode 100644 index 000000000..6e3b29c08 --- /dev/null +++ b/rtgui/iccfromwindows.txt @@ -0,0 +1,21 @@ ++#elif defined G_OS_WIN32 ++ if (config->display_profile_from_gdk) ++ { ++ HDC hdc = GetDC (NULL); ++ ++ if (hdc) ++ { ++ gchar *path; ++ gint32 len = 0; ++ ++ GetICMProfile (hdc, &len, NULL); ++ path = g_new (gchar, len); ++ ++ if (GetICMProfile (hdc, &len, path)) ++ profile = cmsOpenProfileFromFile (path, "r"); ++ ++ g_free (path); ++ ReleaseDC (NULL, hdc); ++ } ++ } + #endif diff --git a/rtgui/icmpanel.cc b/rtgui/icmpanel.cc new file mode 100644 index 000000000..f6f4068ca --- /dev/null +++ b/rtgui/icmpanel.cc @@ -0,0 +1,889 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "icmpanel.h" +#include "options.h" +#include "guiutils.h" +#include "../rtengine/safegtk.h" +#include "../rtengine/iccstore.h" +#include "../rtengine/dcp.h" +#include "rtimage.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +extern Options options; + +ICMPanel::ICMPanel () : FoldableToolPanel(this, "icm", M("TP_ICM_LABEL")), iunchanged(NULL), icmplistener(NULL), lastRefFilename("") { + + isBatchMode = lastToneCurve = lastApplyLookTable = lastApplyBaselineExposureOffset = lastApplyHueSatMap = lastBlendCMSMatrix = lastgamfree = false; + + ipDialog = Gtk::manage (new MyFileChooserButton (M("TP_ICM_INPUTDLGLABEL"), Gtk::FILE_CHOOSER_ACTION_OPEN)); + ipDialog->set_tooltip_text (M("TP_ICM_INPUTCUSTOM_TOOLTIP")); + ipDialogPersister.reset(new FileChooserLastFolderPersister(ipDialog, options.lastIccDir)); + + + // ------------------------------- Input profile + + + Gtk::Frame *iFrame = Gtk::manage (new Gtk::Frame(M("TP_ICM_INPUTPROFILE")) ); + iFrame->set_border_width(0); + iFrame->set_label_align(0.025, 0.5); + + iVBox = Gtk::manage ( new Gtk::VBox()); + iVBox->set_border_width(4); + iVBox->set_spacing(2); + + inone = Gtk::manage (new Gtk::RadioButton (M("TP_ICM_INPUTNONE"))); + inone->set_tooltip_text (M("TP_ICM_INPUTNONE_TOOLTIP")); + iVBox->pack_start (*inone, Gtk::PACK_SHRINK, 2); + + iembedded = Gtk::manage (new Gtk::RadioButton (M("TP_ICM_INPUTEMBEDDED"))); + iembedded->set_tooltip_text (M("TP_ICM_INPUTEMBEDDED_TOOLTIP")); + iVBox->pack_start (*iembedded, Gtk::PACK_SHRINK, 2); + + icamera = Gtk::manage (new Gtk::RadioButton (M("TP_ICM_INPUTCAMERA"))); + icamera->set_tooltip_text (M("TP_ICM_INPUTCAMERA_TOOLTIP")); + iVBox->pack_start (*icamera, Gtk::PACK_SHRINK, 2); + + icameraICC = Gtk::manage (new Gtk::RadioButton (M("TP_ICM_INPUTCAMERAICC"))); + icameraICC->set_tooltip_text (M("TP_ICM_INPUTCAMERAICC_TOOLTIP")); + iVBox->pack_start (*icameraICC, Gtk::PACK_SHRINK, 2); + + ifromfile = Gtk::manage (new Gtk::RadioButton (M("TP_ICM_INPUTCUSTOM")+":")); + Gtk::HBox* ffbox = Gtk::manage (new Gtk::HBox ()); + ifromfile->set_tooltip_text (M("TP_ICM_INPUTCUSTOM_TOOLTIP")); + ffbox->pack_start (*ifromfile, Gtk::PACK_SHRINK); + ffbox->pack_start (*ipDialog); + + iVBox->pack_start (*ffbox, Gtk::PACK_SHRINK, 2); + + opts = icamera->get_group(); + icameraICC->set_group (opts); + iembedded->set_group (opts); + ifromfile->set_group (opts); + inone->set_group (opts); + + Gtk::HBox* hb = Gtk::manage (new Gtk::HBox ()); + hb->show (); + dcpIllLabel = Gtk::manage (new Gtk::Label ("DCP " + M("TP_ICM_DCPILLUMINANT")+":")); + dcpIllLabel->set_tooltip_text (M("TP_ICM_DCPILLUMINANT_TOOLTIP")); + dcpIllLabel->show (); + dcpIll = Gtk::manage (new MyComboBoxText ()); + dcpIll->set_tooltip_text (M("TP_ICM_DCPILLUMINANT_TOOLTIP")); + dcpIll->append_text (M("TP_ICM_DCPILLUMINANT_INTERPOLATED")); + dcpIll->append_text (M("TP_ICM_DCPILLUMINANT") + " 1"); + dcpIll->append_text (M("TP_ICM_DCPILLUMINANT") + " 2"); + dcpIll->show (); + dcpTemperatures[0] = 0; + dcpTemperatures[1] = 0; + ignoreDcpSignal = true; + hb->pack_start(*dcpIllLabel, Gtk::PACK_SHRINK, 4); + hb->pack_start(*dcpIll); + iVBox->pack_start (*hb, Gtk::PACK_SHRINK, 2); + + Gtk::VBox* c1VBox = Gtk::manage ( new Gtk::VBox()); + Gtk::VBox* c2VBox = Gtk::manage ( new Gtk::VBox()); + + ckbToneCurve = Gtk::manage (new Gtk::CheckButton (M("TP_ICM_TONECURVE"))); + ckbToneCurve->set_sensitive (false); + ckbToneCurve->set_tooltip_text (M("TP_ICM_TONECURVE_TOOLTIP")); + c1VBox->pack_start (*ckbToneCurve, Gtk::PACK_SHRINK, 2); + + ckbApplyLookTable = Gtk::manage (new Gtk::CheckButton (M("TP_ICM_APPLYLOOKTABLE"))); + ckbApplyLookTable->set_sensitive (false); + ckbApplyLookTable->set_tooltip_text (M("TP_ICM_APPLYLOOKTABLE_TOOLTIP")); + c1VBox->pack_start (*ckbApplyLookTable, Gtk::PACK_SHRINK, 2); + + ckbApplyHueSatMap = Gtk::manage (new Gtk::CheckButton (M("TP_ICM_APPLYHUESATMAP"))); + ckbApplyHueSatMap->set_sensitive (false); + ckbApplyHueSatMap->set_tooltip_text (M("TP_ICM_APPLYHUESATMAP_TOOLTIP")); + c2VBox->pack_start (*ckbApplyHueSatMap, Gtk::PACK_SHRINK, 2); + + ckbApplyBaselineExposureOffset = Gtk::manage (new Gtk::CheckButton (M("TP_ICM_APPLYBASELINEEXPOSUREOFFSET"))); + ckbApplyBaselineExposureOffset->set_sensitive (false); + ckbApplyBaselineExposureOffset->set_tooltip_text (M("TP_ICM_APPLYBASELINEEXPOSUREOFFSET_TOOLTIP")); + c2VBox->pack_start (*ckbApplyBaselineExposureOffset, Gtk::PACK_SHRINK, 2); + + Gtk::HBox* dcpHBox = Gtk::manage (new Gtk::HBox ()); + dcpHBox->show (); + dcpHBox->pack_start (*c1VBox, Gtk::PACK_EXPAND_WIDGET, 2); + dcpHBox->pack_start (*c2VBox, Gtk::PACK_EXPAND_WIDGET, 2); + iVBox->pack_start (*dcpHBox, Gtk::PACK_SHRINK, 2); + + ckbBlendCMSMatrix = Gtk::manage (new Gtk::CheckButton (M("TP_ICM_BLENDCMSMATRIX"))); + ckbBlendCMSMatrix->set_sensitive (false); + ckbBlendCMSMatrix->set_tooltip_text (M("TP_ICM_BLENDCMSMATRIX_TOOLTIP")); + // blend cms matrix no longer used + //iVBox->pack_start (*ckbBlendCMSMatrix, Gtk::PACK_SHRINK, 2); + + saveRef = Gtk::manage (new Gtk::Button (M("TP_ICM_SAVEREFERENCE"))); + saveRef->set_image (*Gtk::manage (new RTImage ("gtk-save-large.png"))); + saveRef->set_tooltip_markup (M("TP_ICM_SAVEREFERENCE_TOOLTIP")); + iVBox->pack_start (*saveRef, Gtk::PACK_SHRINK, 2); + + iFrame->add(*iVBox); + pack_start (*iFrame, Gtk::PACK_EXPAND_WIDGET, 4); + + + // ---------------------------- Working profile + + + Gtk::Frame *wFrame = Gtk::manage (new Gtk::Frame(M("TP_ICM_WORKINGPROFILE")) ); + wFrame->set_border_width(0); + wFrame->set_label_align(0.025, 0.5); + + Gtk::VBox *wVBox = Gtk::manage ( new Gtk::VBox()); + wVBox->set_border_width(4); + + wnames = Gtk::manage (new MyComboBoxText ()); + wVBox->pack_start (*wnames, Gtk::PACK_SHRINK); + + std::vector wpnames = rtengine::getWorkingProfiles (); + for (size_t i=0; iappend_text (wpnames[i]); + + wnames->set_active (0); + + wFrame->add(*wVBox); + pack_start (*wFrame, Gtk::PACK_EXPAND_WIDGET, 4); + + + // ---------------------------- Output profile + + + Gtk::Frame *oFrame = Gtk::manage (new Gtk::Frame(M("TP_ICM_OUTPUTPROFILE")) ); + oFrame->set_border_width(0); + oFrame->set_label_align(0.025, 0.5); + + Gtk::VBox *oVBox = Gtk::manage ( new Gtk::VBox()); + oVBox->set_border_width(4); + oVBox->set_spacing(2); + + onames = Gtk::manage (new MyComboBoxText ()); + oVBox->pack_start (*onames, Gtk::PACK_SHRINK); + + onames->append_text (M("TP_ICM_NOICM")); + onames->set_active (0); + + std::vector opnames = iccStore->getOutputProfiles (); + for (size_t i=0; iappend_text (opnames[i]); + + onames->set_active (0); + + // Output gamma + + Gtk::HBox* gaHBox = Gtk::manage (new Gtk::HBox ()); + Gtk::Label* galab = Gtk::manage (new Gtk::Label (M("TP_GAMMA_OUTPUT")+":")); + //galab->set_alignment (0.0, 0.5); + + gaHBox->pack_start (*galab, Gtk::PACK_SHRINK, 4); + wgamma = Gtk::manage (new MyComboBoxText ()); + gaHBox->pack_start (*wgamma, Gtk::PACK_EXPAND_WIDGET); + + oVBox->pack_start(*gaHBox, Gtk::PACK_EXPAND_WIDGET,2); + + std::vector wpgamma = rtengine::getGamma (); + for (size_t i=0; iappend_text (wpgamma[i]); + + wgamma->set_active (0); + + Gtk::Frame* fgFrame = Gtk::manage (new Gtk::Frame ()); + + Gtk::VBox *fgVBox = Gtk::manage ( new Gtk::VBox()); + fgVBox->set_spacing(0); + + freegamma = Gtk::manage(new Gtk::CheckButton((M("TP_GAMMA_FREE")))); + freegamma->set_active (false); + fgFrame->set_label_widget(*freegamma); + + gampos = Gtk::manage(new Adjuster (M("TP_GAMMA_CURV"),1,3.5,0.01,2.22)); + gampos->setAdjusterListener (this); + if (gampos->delay < 1000) gampos->delay = 1000; + gampos->show(); + slpos = Gtk::manage(new Adjuster (M("TP_GAMMA_SLOP"),0,15,0.01,4.5)); + slpos->setAdjusterListener (this); + if (slpos->delay < 1000) slpos->delay = 1000; + slpos->show(); + fgVBox->pack_start( *gampos, Gtk::PACK_SHRINK);//gamma + fgVBox->pack_start( *slpos, Gtk::PACK_SHRINK);//slope + + fgFrame->add(*fgVBox); + oVBox->pack_start(*fgFrame, Gtk::PACK_EXPAND_WIDGET,2); + + oFrame->add(*oVBox); + pack_start (*oFrame, Gtk::PACK_EXPAND_WIDGET, 4); + + + // ---------------------------- Output gamma list entries + + + Gtk::FileFilter filter_icc; + filter_icc.set_name(M("FILECHOOSER_FILTER_COLPROF")); + filter_icc.add_pattern("*.dcp"); + filter_icc.add_pattern("*.DCP"); + filter_icc.add_pattern("*.icc"); + filter_icc.add_pattern("*.icm"); + filter_icc.add_pattern("*.ICC"); + filter_icc.add_pattern("*.ICM"); + Gtk::FileFilter filter_iccdng; + filter_iccdng.set_name(M("FILECHOOSER_FILTER_COLPROF") + " + DNG"); + filter_iccdng.add_pattern("*.dcp"); + filter_iccdng.add_pattern("*.DCP"); + filter_iccdng.add_pattern("*.dng"); + filter_iccdng.add_pattern("*.DNG"); + filter_iccdng.add_pattern("*.icc"); + filter_iccdng.add_pattern("*.icm"); + filter_iccdng.add_pattern("*.ICC"); + filter_iccdng.add_pattern("*.ICM"); + Gtk::FileFilter filter_any; + filter_any.set_name(M("FILECHOOSER_FILTER_ANY")); + filter_any.add_pattern("*"); + + ipDialog->add_filter (filter_icc); + ipDialog->add_filter (filter_iccdng); + ipDialog->add_filter (filter_any); + + oldip = ""; + + wnames->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::wpChanged) ); + onames->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::opChanged) ); + wgamma->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::gpChanged) ); + dcpIll->signal_changed().connect( sigc::mem_fun(*this, &ICMPanel::dcpIlluminantChanged) ); + + gamcsconn = freegamma->signal_toggled().connect ( sigc::mem_fun(*this, &ICMPanel::GamChanged)); + tcurveconn = ckbToneCurve->signal_toggled().connect ( sigc::mem_fun(*this, &ICMPanel::toneCurveChanged)); + ltableconn = ckbApplyLookTable->signal_toggled().connect ( sigc::mem_fun(*this, &ICMPanel::applyLookTableChanged)); + beoconn = ckbApplyBaselineExposureOffset->signal_toggled().connect ( sigc::mem_fun(*this, &ICMPanel::applyBaselineExposureOffsetChanged)); + hsmconn = ckbApplyHueSatMap->signal_toggled().connect ( sigc::mem_fun(*this, &ICMPanel::applyHueSatMapChanged)); + blendcmsconn = ckbBlendCMSMatrix->signal_toggled().connect ( sigc::mem_fun(*this, &ICMPanel::blendCMSMatrixChanged)); + + icamera->signal_toggled().connect( sigc::mem_fun(*this, &ICMPanel::ipChanged) ); + icameraICC->signal_toggled().connect( sigc::mem_fun(*this, &ICMPanel::ipChanged) ); + iembedded->signal_toggled().connect( sigc::mem_fun(*this, &ICMPanel::ipChanged) ); + ifromfile->signal_toggled().connect( sigc::mem_fun(*this, &ICMPanel::ipChanged) ); + + ipc = ipDialog->signal_selection_changed().connect( sigc::mem_fun(*this, &ICMPanel::ipSelectionChanged) ); + saveRef->signal_pressed().connect( sigc::mem_fun(*this, &ICMPanel::saveReferencePressed) ); + + show_all (); +} + +void ICMPanel::updateDCP (int dcpIlluminant, Glib::ustring dcp_name) { + + if (isBatchMode) { + ckbToneCurve->set_sensitive (true); + ckbApplyLookTable->set_sensitive (true); + ckbApplyBaselineExposureOffset->set_sensitive (true); + ckbApplyHueSatMap->set_sensitive (true); + dcpIllLabel->set_sensitive (true); + dcpIll->set_sensitive (true); + if (dcpTemperatures[0] != 0 || dcpTemperatures[1] != 0) { + int curr_active = dcpIll->get_active_row_number(); + ignoreDcpSignal = true; + dcpIll->clear_items (); + dcpIll->append_text (M("TP_ICM_DCPILLUMINANT_INTERPOLATED")); + dcpIll->append_text (M("TP_ICM_DCPILLUMINANT") + " 1"); + dcpIll->append_text (M("TP_ICM_DCPILLUMINANT") + " 2"); + dcpIll->append_text (M("GENERAL_UNCHANGED")); + dcpTemperatures[0] = 0; + dcpTemperatures[1] = 0; + dcpIll->set_active (curr_active); + ignoreDcpSignal = false; + } + if (dcpIll->get_active_row_number() == -1 && dcpIlluminant == -1) { + dcpIll->set_active(0); + } else if (dcpIlluminant >= 0 && dcpIlluminant != dcpIll->get_active_row_number()) { + dcpIll->set_active(dcpIlluminant); + } + dcpIll->set_sensitive (true); + dcpIllLabel->set_sensitive (true); + return; + } + ckbToneCurve->set_sensitive (false); + ckbApplyLookTable->set_sensitive (false); + ckbApplyBaselineExposureOffset->set_sensitive (false); + ckbApplyHueSatMap->set_sensitive (false); + dcpIllLabel->set_sensitive (false); + dcpIll->set_sensitive (false); + if (ifromfile->get_active() && dcpStore->isValidDCPFileName(dcp_name)) { + DCPProfile* dcp = dcpStore->getProfile(dcp_name, false); + if (dcp) { + if (dcp->getHasToneCurve()) { + ckbToneCurve->set_sensitive (true); + } + if (dcp->getHasLookTable()) { + ckbApplyLookTable->set_sensitive (true); + } + if (dcp->getHasBaselineExposureOffset()) { + ckbApplyBaselineExposureOffset->set_sensitive (true); + } + if (dcp->getHasHueSatMap()) { + ckbApplyHueSatMap->set_sensitive (true); + } + int i1, i2; + double temp1, temp2; + bool willInterpolate; + dcp->getIlluminants(i1, temp1, i2, temp2, willInterpolate); + if (willInterpolate) { + if (dcpTemperatures[0] != temp1 || dcpTemperatures[1] != temp2) { + char tempstr1[64], tempstr2[64]; + sprintf(tempstr1, "%.0fK", temp1); + sprintf(tempstr2, "%.0fK", temp2); + int curr_active = dcpIll->get_active_row_number(); + ignoreDcpSignal = true; + dcpIll->clear_items (); + dcpIll->append_text (M("TP_ICM_DCPILLUMINANT_INTERPOLATED")); + dcpIll->append_text (tempstr1); + dcpIll->append_text (tempstr2); + dcpTemperatures[0] = temp1; + dcpTemperatures[1] = temp2; + dcpIll->set_active (curr_active); + ignoreDcpSignal = false; + } + if (dcpIlluminant > 2) { + dcpIlluminant = 0; + } + if (dcpIll->get_active_row_number() == -1 && dcpIlluminant == -1) { + ignoreDcpSignal = true; + dcpIll->set_active(0); + ignoreDcpSignal = false; + } else if (dcpIlluminant >= 0 && dcpIlluminant != dcpIll->get_active_row_number()) { + ignoreDcpSignal = true; + dcpIll->set_active(dcpIlluminant); + ignoreDcpSignal = false; + } + dcpIll->set_sensitive (true); + dcpIllLabel->set_sensitive (true); + } else { + if (dcpIll->get_active_row_number() != -1) { + ignoreDcpSignal = true; + dcpIll->set_active(-1); + ignoreDcpSignal = false; + } + } + } + } + if (!dcpIllLabel->get_sensitive() && dcpIll->get_active_row_number() != 0) { + if (dcpTemperatures[0] != 0 || dcpTemperatures[1] != 0) { + int curr_active = dcpIll->get_active_row_number(); + ignoreDcpSignal = true; + dcpIll->clear_items (); + dcpIll->append_text (M("TP_ICM_DCPILLUMINANT_INTERPOLATED")); + dcpIll->append_text (M("TP_ICM_DCPILLUMINANT") + " 1"); + dcpIll->append_text (M("TP_ICM_DCPILLUMINANT") + " 2"); + if (isBatchMode) + dcpIll->append_text (M("GENERAL_UNCHANGED")); + dcpTemperatures[0] = 0; + dcpTemperatures[1] = 0; + dcpIll->set_active (curr_active); + ignoreDcpSignal = false; + } + } +} + +void ICMPanel::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + ipc.block (true); + gamcsconn.block (true); + tcurveconn.block(true); + ltableconn.block(true); + beoconn.block(true); + hsmconn.block(true); + blendcmsconn.block(true); + + if(pp->icm.input.substr(0,5) != "file:" && !ipDialog->get_filename().empty()) + ipDialog->set_filename(pp->icm.input); + + if (pp->icm.input == "(none)") { + inone->set_active (true); + ckbBlendCMSMatrix->set_sensitive (false); + updateDCP(pp->icm.dcpIlluminant, ""); + } + else if (pp->icm.input == "(embedded)" || ((pp->icm.input == "(camera)" || pp->icm.input=="") && icamera->get_state()==Gtk::STATE_INSENSITIVE)) { + iembedded->set_active (true); + ckbBlendCMSMatrix->set_sensitive (false); + updateDCP(pp->icm.dcpIlluminant, ""); + } + else if ((pp->icm.input == "(cameraICC)") && icameraICC->get_state()!=Gtk::STATE_INSENSITIVE) { + icameraICC->set_active (true); + ckbBlendCMSMatrix->set_sensitive (true); + updateDCP(pp->icm.dcpIlluminant, ""); + } + else if ((pp->icm.input == "(cameraICC)") && icamera->get_state()!=Gtk::STATE_INSENSITIVE && icameraICC->get_state()==Gtk::STATE_INSENSITIVE) { + // this is the case when (cameraICC) is instructed by packaged profiles, but ICC file is not found + // therefore falling back UI to explicitly reflect the (camera) option + icamera->set_active (true); + ckbBlendCMSMatrix->set_sensitive (false); + updateDCP(pp->icm.dcpIlluminant, ""); + } + else if ((pp->icm.input == "(cameraICC)") && icamera->get_state()==Gtk::STATE_INSENSITIVE && icameraICC->get_state()==Gtk::STATE_INSENSITIVE) { + // If neither (camera) nor (cameraICC) are available, as is the case when loading a non-raw, activate (embedded). + iembedded->set_active (true); + ckbBlendCMSMatrix->set_sensitive (false); + updateDCP(pp->icm.dcpIlluminant, ""); + } + else if ((pp->icm.input == "(camera)" || pp->icm.input=="") && icamera->get_state()!=Gtk::STATE_INSENSITIVE) { + icamera->set_active (true); + ckbBlendCMSMatrix->set_sensitive (false); + updateDCP(pp->icm.dcpIlluminant, ""); + } + else { + ifromfile->set_active (true); + oldip = pp->icm.input.substr(5); // cut of "file:" + ipDialog->set_filename (pp->icm.input.substr(5)); + ckbBlendCMSMatrix->set_sensitive (true); + updateDCP(pp->icm.dcpIlluminant, pp->icm.input.substr(5)); + } + + wnames->set_active_text (pp->icm.working); + wgamma->set_active_text (pp->icm.gamma); + + if (pp->icm.output==ColorManagementParams::NoICMString) + onames->set_active_text (M("TP_ICM_NOICM")); + else + onames->set_active_text (pp->icm.output); + + if (onames->get_active_row_number()==-1) + onames->set_active_text (M("TP_ICM_NOICM")); + + ckbToneCurve->set_active (pp->icm.toneCurve); + lastToneCurve = pp->icm.toneCurve; + ckbApplyLookTable->set_active (pp->icm.applyLookTable); + lastApplyLookTable = pp->icm.applyLookTable; + ckbApplyBaselineExposureOffset->set_active (pp->icm.applyBaselineExposureOffset); + lastApplyBaselineExposureOffset = pp->icm.applyBaselineExposureOffset; + ckbApplyHueSatMap->set_active (pp->icm.applyHueSatMap); + lastApplyHueSatMap = pp->icm.applyHueSatMap; + + ckbBlendCMSMatrix->set_active (pp->icm.blendCMSMatrix); + lastBlendCMSMatrix = pp->icm.blendCMSMatrix; + + onames->set_sensitive(wgamma->get_active_row_number()==0 || freegamma->get_active()); //"default" + wgamma->set_sensitive(!freegamma->get_active()); + + freegamma->set_active (pp->icm.freegamma); + lastgamfree = pp->icm.freegamma; + + gampos->setValue (pp->icm.gampos); + slpos->setValue (pp->icm.slpos); + + if (pedited) { + iunchanged->set_active (!pedited->icm.input); + ckbToneCurve->set_inconsistent(!pedited->icm.toneCurve); + ckbApplyLookTable->set_inconsistent(!pedited->icm.applyLookTable); + ckbApplyBaselineExposureOffset->set_inconsistent(!pedited->icm.applyBaselineExposureOffset); + ckbApplyHueSatMap->set_inconsistent(!pedited->icm.applyHueSatMap); + ckbBlendCMSMatrix->set_inconsistent(!pedited->icm.blendCMSMatrix); + if (!pedited->icm.working) + wnames->set_active_text(M("GENERAL_UNCHANGED")); + if (!pedited->icm.output) + onames->set_active_text(M("GENERAL_UNCHANGED")); + if (!pedited->icm.dcpIlluminant) + dcpIll->set_active_text(M("GENERAL_UNCHANGED")); + if (!pedited->icm.gamma){ + wgamma->set_active_text(M("GENERAL_UNCHANGED")); + wgamma->set_active_text(M("GENERAL_UNCHANGED")); + } + gampos->setEditedState (pedited->icm.gampos ? Edited : UnEdited); + slpos->setEditedState (pedited->icm.slpos ? Edited : UnEdited); + + } + + blendcmsconn.block(false); + tcurveconn.block(false); + ltableconn.block(false); + beoconn.block(false); + hsmconn.block(false); + gamcsconn.block (false); + ipc.block (false); + + enableListener (); +} + +void ICMPanel::write (ProcParams* pp, ParamsEdited* pedited) { + + if (inone->get_active()) + pp->icm.input = "(none)"; + else if (iembedded->get_active ()) + pp->icm.input = "(embedded)"; + else if (icamera->get_active ()) + pp->icm.input = "(camera)"; + else if (icameraICC->get_active ()) + pp->icm.input = "(cameraICC)"; + else { + if (safe_file_test (ipDialog->get_filename (), Glib::FILE_TEST_EXISTS) && !safe_file_test (ipDialog->get_filename (), Glib::FILE_TEST_IS_DIR)) + pp->icm.input = "file:"+ipDialog->get_filename (); + else + pp->icm.input = ""; // just a directory + + Glib::ustring p=Glib::path_get_dirname(ipDialog->get_filename ()); + } + + pp->icm.working = wnames->get_active_text (); + pp->icm.gamma = wgamma->get_active_text (); + pp->icm.dcpIlluminant = dcpIll->get_active_row_number(); + if (pp->icm.dcpIlluminant < 0) + pp->icm.dcpIlluminant = 0; + + if (onames->get_active_text()==M("TP_ICM_NOICM")) + pp->icm.output = ColorManagementParams::NoICMString; + else + pp->icm.output = onames->get_active_text(); + pp->icm.freegamma = freegamma->get_active(); + + if (ifromfile->get_active() && pp->icm.input.substr(0,5) == "file:" && dcpStore->isValidDCPFileName(pp->icm.input.substr(5))) { + DCPProfile* dcp = dcpStore->getProfile(pp->icm.input.substr(5), false); + if (dcp) { + if (dcp->getHasToneCurve()) { + pp->icm.toneCurve = ckbToneCurve->get_active (); + } + if (dcp->getHasLookTable()) { + pp->icm.applyLookTable = ckbApplyLookTable->get_active (); + } + if (dcp->getHasBaselineExposureOffset()) { + pp->icm.applyBaselineExposureOffset = ckbApplyBaselineExposureOffset->get_active (); + } + if (dcp->getHasHueSatMap()) { + pp->icm.applyHueSatMap = ckbApplyHueSatMap->get_active (); + } + } + } + pp->icm.blendCMSMatrix = ckbBlendCMSMatrix->get_active (); + pp->icm.gampos =(double) gampos->getValue(); + pp->icm.slpos =(double) slpos->getValue(); + + if (pedited) { + pedited->icm.input = !iunchanged->get_active (); + pedited->icm.working = wnames->get_active_text()!=M("GENERAL_UNCHANGED"); + pedited->icm.output = onames->get_active_text()!=M("GENERAL_UNCHANGED"); + pedited->icm.dcpIlluminant = dcpIll->get_active_text()!=M("GENERAL_UNCHANGED"); + pedited->icm.toneCurve = !ckbToneCurve->get_inconsistent (); + pedited->icm.applyLookTable = !ckbApplyLookTable->get_inconsistent (); + pedited->icm.applyBaselineExposureOffset = !ckbApplyBaselineExposureOffset->get_inconsistent (); + pedited->icm.applyHueSatMap = !ckbApplyHueSatMap->get_inconsistent (); + pedited->icm.blendCMSMatrix = !ckbBlendCMSMatrix->get_inconsistent (); + pedited->icm.gamma = wgamma->get_active_text()!=M("GENERAL_UNCHANGED"); + pedited->icm.freegamma =!freegamma->get_inconsistent(); + pedited->icm.gampos = gampos->getEditedState (); + pedited->icm.slpos = slpos->getEditedState (); + } +} + +void ICMPanel::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + gampos->setDefault (defParams->icm.gampos); + slpos->setDefault (defParams->icm.slpos); + + if (pedited) { + gampos->setDefaultEditedState (pedited->icm.gampos ? Edited : UnEdited); + slpos->setDefaultEditedState (pedited->icm.slpos ? Edited : UnEdited); + } + else { + gampos->setDefaultEditedState (Irrelevant); + slpos->setDefaultEditedState (Irrelevant); + } +} + +void ICMPanel::setAdjusterBehavior (bool gammaadd, bool slopeadd) { + gampos->setAddMode (gammaadd); + slpos->setAddMode (slopeadd); +} + +void ICMPanel::adjusterChanged (Adjuster* a, double newval) { + + if (listener && freegamma->get_active()) { + + Glib::ustring costr = Glib::ustring::format (std::setw(3), std::fixed, std::setprecision(2), newval); + + if (a==gampos) + listener->panelChanged (EvGAMPOS, costr); + else if (a==slpos) + listener->panelChanged (EvSLPOS, costr); + } +} + +void ICMPanel::wpChanged () { + + if (listener) + listener->panelChanged (EvWProfile, wnames->get_active_text ()); +} + +void ICMPanel::gpChanged () { + + if (listener) { + listener->panelChanged (EvGAMMA, wgamma->get_active_text ()); + onames->set_sensitive(wgamma->get_active_row_number()==0); //"default" + } +} + +void ICMPanel::dcpIlluminantChanged() { + if (listener && !ignoreDcpSignal) { + listener->panelChanged (EvDCPIlluminant, dcpIll->get_active_text ()); + } +} + +void ICMPanel::toneCurveChanged() { + if (batchMode) { + if (ckbToneCurve->get_inconsistent()) { + ckbToneCurve->set_inconsistent (false); + tcurveconn.block (true); + ckbToneCurve->set_active (false); + tcurveconn.block (false); + } + else if (lastToneCurve) + ckbToneCurve->set_inconsistent (true); + + lastToneCurve = ckbToneCurve->get_active (); + } + + if (listener) + listener->panelChanged (EvDCPToneCurve, ckbToneCurve->get_active() ? M("GENERAL_ENABLED") : M("GENERAL_DISABLED")); +} + +void ICMPanel::applyLookTableChanged() { + if (batchMode) { + if (ckbApplyLookTable->get_inconsistent()) { + ckbApplyLookTable->set_inconsistent (false); + ltableconn.block (true); + ckbApplyLookTable->set_active (false); + ltableconn.block (false); + } + else if (lastApplyLookTable) + ckbApplyLookTable->set_inconsistent (true); + + lastApplyLookTable = ckbApplyLookTable->get_active (); + } + + if (listener) + listener->panelChanged (EvDCPApplyLookTable, ckbApplyLookTable->get_active() ? M("GENERAL_ENABLED") : M("GENERAL_DISABLED")); +} + +void ICMPanel::applyBaselineExposureOffsetChanged() { + if (batchMode) { + if (ckbApplyBaselineExposureOffset->get_inconsistent()) { + ckbApplyBaselineExposureOffset->set_inconsistent (false); + beoconn.block (true); + ckbApplyBaselineExposureOffset->set_active (false); + beoconn.block (false); + } + else if (lastApplyBaselineExposureOffset) + ckbApplyBaselineExposureOffset->set_inconsistent (true); + + lastApplyBaselineExposureOffset = ckbApplyBaselineExposureOffset->get_active (); + } + + if (listener) + listener->panelChanged (EvDCPApplyBaselineExposureOffset, ckbApplyBaselineExposureOffset->get_active() ? M("GENERAL_ENABLED") : M("GENERAL_DISABLED")); +} + +void ICMPanel::applyHueSatMapChanged() { + if (batchMode) { + if (ckbApplyHueSatMap->get_inconsistent()) { + ckbApplyHueSatMap->set_inconsistent (false); + hsmconn.block (true); + ckbApplyHueSatMap->set_active (false); + hsmconn.block (false); + } + else if (lastApplyHueSatMap) + ckbApplyHueSatMap->set_inconsistent (true); + + lastApplyHueSatMap = ckbApplyHueSatMap->get_active (); + } + + if (listener) + listener->panelChanged (EvDCPApplyHueSatMap, ckbApplyHueSatMap->get_active() ? M("GENERAL_ENABLED") : M("GENERAL_DISABLED")); +} + +void ICMPanel::ipChanged () { + + Glib::ustring profname; + if (inone->get_active()) { + profname = "(none)"; + ckbBlendCMSMatrix->set_sensitive(false); + } + else if (iembedded->get_active ()) { + profname = "(embedded)"; + ckbBlendCMSMatrix->set_sensitive(false); + } + else if (icamera->get_active ()) { + profname = "(camera)"; + ckbBlendCMSMatrix->set_sensitive(false); + } + else if (icameraICC->get_active ()) { + profname = "(cameraICC)"; + ckbBlendCMSMatrix->set_sensitive(true); + } + else { + profname = ipDialog->get_filename (); + ckbBlendCMSMatrix->set_sensitive(true); + } + updateDCP(-1, profname); + + if (listener && profname!=oldip) + listener->panelChanged (EvIProfile, profname); + + oldip = profname; +} + +void ICMPanel::blendCMSMatrixChanged() { + if (batchMode) { + if (ckbBlendCMSMatrix->get_inconsistent()) { + ckbBlendCMSMatrix->set_inconsistent (false); + blendcmsconn.block (true); + ckbBlendCMSMatrix->set_active (false); + blendcmsconn.block (false); + } + else if (lastBlendCMSMatrix) + ckbBlendCMSMatrix->set_inconsistent (true); + + lastBlendCMSMatrix = ckbBlendCMSMatrix->get_active (); + } + + if (listener) listener->panelChanged (EvBlendCMSMatrix, ckbBlendCMSMatrix->get_active() ? M("GENERAL_ENABLED") : M("GENERAL_DISABLED")); +} + +void ICMPanel::GamChanged() { + if (batchMode) { + if (freegamma->get_inconsistent()) { + freegamma->set_inconsistent (false); + gamcsconn.block (true); + freegamma->set_active (false); + gamcsconn.block (false); + } + else if (lastgamfree) + freegamma->set_inconsistent (true); + + lastgamfree = freegamma->get_active (); + } + + if (listener) { + if (freegamma->get_active()){ + listener->panelChanged (EvGAMFREE, M("GENERAL_ENABLED")); + onames->set_sensitive(!freegamma->get_active());//disabled choice + wgamma->set_sensitive(!freegamma->get_active()); + } + else { + listener->panelChanged (EvGAMFREE, M("GENERAL_DISABLED")); + onames->set_sensitive(!freegamma->get_active() && wgamma->get_active_row_number()==0); + wgamma->set_sensitive(!freegamma->get_active()); + } + } +} + +void ICMPanel::opChanged () { + + if (listener) + listener->panelChanged (EvOProfile, onames->get_active_text()); +} + +void ICMPanel::setRawMeta (bool raw, const rtengine::ImageData* pMeta) { + + disableListener (); + + icamera->set_active (raw); + iembedded->set_active (!raw); + icamera->set_sensitive (raw); + icameraICC->set_sensitive (raw && (iccStore->getStdProfile(pMeta->getCamera()) != NULL || dcpStore->getStdProfile(pMeta->getCamera()) != NULL)); + iembedded->set_sensitive (!raw); + + enableListener (); +} + +void ICMPanel::ipSelectionChanged() { + + if (ipDialog->get_filename() == "") + return; + + ipChanged(); +} + +void ICMPanel::saveReferencePressed () { + + if (!icmplistener) + return; + Gtk::FileChooserDialog dialog(M("TP_ICM_SAVEREFERENCE"), Gtk::FILE_CHOOSER_ACTION_SAVE); + FileChooserLastFolderPersister persister(&dialog, options.lastProfilingReferenceDir); + dialog.set_current_name (lastRefFilename); + + dialog.add_button(Gtk::StockID("gtk-cancel"), Gtk::RESPONSE_CANCEL); + dialog.add_button(Gtk::StockID("gtk-save"), Gtk::RESPONSE_OK); + + Gtk::CheckButton applyWB(M("TP_ICM_SAVEREFERENCE_APPLYWB")); + applyWB.set_active(true); + Gtk::HBox* hbox = Gtk::manage( new Gtk::HBox() ); + hbox->pack_end(applyWB, Gtk::PACK_SHRINK, 2); + Gtk::VBox *vbox = dialog.get_vbox(); + vbox->pack_end(*hbox, Gtk::PACK_SHRINK, 2); + + Gtk::FileFilter filter_tif; + filter_tif.set_name(M("FILECHOOSER_FILTER_TIFF")); + filter_tif.add_pattern("*.tif"); + filter_tif.add_pattern("*.tiff"); + dialog.add_filter(filter_tif); + + Gtk::FileFilter filter_any; + filter_any.set_name(M("FILECHOOSER_FILTER_ANY")); + filter_any.add_pattern("*"); + dialog.add_filter(filter_any); + + dialog.show_all_children(); + //dialog.set_do_overwrite_confirmation (true); + + bool done = false; + do { + int result = dialog.run(); + if (result != Gtk::RESPONSE_OK) { + done = true; + } else { + std::string fname = dialog.get_filename(); + Glib::ustring ext = getExtension(fname); + if (ext != "tif" && ext != "tiff") + fname += ".tif"; + if (confirmOverwrite(dialog, fname)) { + icmplistener->saveInputICCReference (fname, applyWB.get_active()); + lastRefFilename = Glib::path_get_basename (fname); + done = true; + } + } + } while (!done); + return; +} + +void ICMPanel::setBatchMode (bool batchMode) { + + isBatchMode = true; + ignoreDcpSignal = false; + ToolPanel::setBatchMode (batchMode); + iunchanged = Gtk::manage (new Gtk::RadioButton (M("GENERAL_UNCHANGED"))); + iunchanged->set_group (opts); + iVBox->pack_start (*iunchanged, Gtk::PACK_SHRINK, 4); + iVBox->reorder_child (*iunchanged, 5); + removeIfThere (this, saveRef); + onames->append_text (M("GENERAL_UNCHANGED")); + wnames->append_text (M("GENERAL_UNCHANGED")); + wgamma->append_text (M("GENERAL_UNCHANGED")); + dcpIll->append_text (M("GENERAL_UNCHANGED")); + gampos->showEditedCB (); + slpos->showEditedCB (); +} + diff --git a/rtgui/icmpanel.h b/rtgui/icmpanel.h new file mode 100755 index 000000000..b9e2f5786 --- /dev/null +++ b/rtgui/icmpanel.h @@ -0,0 +1,123 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _ICMPANEL_ +#define _ICMPANEL_ + +#include +#include +#include "adjuster.h" +#include "guiutils.h" + +#include "toolpanel.h" +#include "../rtengine/imagedata.h" + +class ICMPanelListener { + + public: + virtual ~ICMPanelListener() {} + virtual void saveInputICCReference (Glib::ustring fname, bool apply_wb) {} +}; + +class ICMPanel : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel { + + protected: + Adjuster* gampos; + Adjuster* slpos; + bool lastgamfree; + sigc::connection gamcsconn; + //bool freegamma; + bool lastToneCurve; + sigc::connection tcurveconn; + bool lastApplyLookTable; + sigc::connection ltableconn; + bool lastApplyBaselineExposureOffset; + sigc::connection beoconn; + bool lastApplyHueSatMap; + sigc::connection hsmconn; + bool lastBlendCMSMatrix; + bool isBatchMode; + sigc::connection blendcmsconn; + + private: + Gtk::VBox * iVBox; + + Gtk::CheckButton* freegamma; + Gtk::RadioButton* inone; + + Gtk::RadioButton* iembedded; + Gtk::RadioButton* icamera; + Gtk::RadioButton* icameraICC; + Gtk::RadioButton* ifromfile; + Gtk::Label* dcpIllLabel; + MyComboBoxText* dcpIll; + Gtk::CheckButton* ckbToneCurve; + Gtk::CheckButton* ckbApplyLookTable; + Gtk::CheckButton* ckbApplyBaselineExposureOffset; + Gtk::CheckButton* ckbApplyHueSatMap; + Gtk::CheckButton* ckbBlendCMSMatrix; + MyComboBoxText* wnames; + MyComboBoxText* wgamma; + + MyComboBoxText* onames; + Gtk::RadioButton* ofromdir; + Gtk::RadioButton* ofromfile; + Gtk::RadioButton* iunchanged; + MyFileChooserButton* ipDialog; + std::auto_ptr ipDialogPersister; + Gtk::RadioButton::Group opts; + Gtk::Button* saveRef; + sigc::connection ipc; + Glib::ustring oldip; + ICMPanelListener* icmplistener; + + bool ignoreDcpSignal; + double dcpTemperatures[2]; + bool enableLastICCWorkDirChange; + Glib::ustring lastRefFilename; + void updateDCP(int dcpIlluminant, Glib::ustring dcp_name); + public: + ICMPanel (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void adjusterChanged (Adjuster* a, double newval); + void setAdjusterBehavior (bool gammaadd, bool slopeadd); + + void wpChanged (); + void opChanged (); + void ipChanged (); + void gpChanged (); + void GamChanged (); + void ipSelectionChanged (); + void blendCMSMatrixChanged(); + void dcpIlluminantChanged(); + void toneCurveChanged(); + void applyLookTableChanged(); + void applyBaselineExposureOffsetChanged(); + void applyHueSatMapChanged(); + + void setRawMeta (bool raw, const rtengine::ImageData* pMeta); + void saveReferencePressed (); + + void setICMPanelListener (ICMPanelListener* ipl) { icmplistener = ipl; } +}; + +#endif diff --git a/rtgui/ilabel.cc b/rtgui/ilabel.cc new file mode 100644 index 000000000..753eb8346 --- /dev/null +++ b/rtgui/ilabel.cc @@ -0,0 +1,61 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "ilabel.h" + +ILabel::ILabel (Glib::ustring lab) : label(lab) {} + +void ILabel::on_realize() { + + Gtk::DrawingArea::on_realize(); + add_events(Gdk::EXPOSURE_MASK); + + Glib::RefPtr fn = create_pango_layout(label); + fn->set_markup (label); + int labw, labh; + fn->get_pixel_size (labw, labh); + set_size_request (2+labw,2+labh); +} + +bool ILabel::on_expose_event (GdkEventExpose* event) { + + Glib::RefPtr style = get_style (); + Glib::RefPtr window = get_window(); + Glib::RefPtr gc_ = style->get_bg_gc(get_state()); + Cairo::RefPtr cr = window->create_cairo_context(); + + Gdk::Color c = style->get_fg (get_state()); + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + cr->rectangle (0, 0, get_width (), get_height()); + cr->fill (); + + Glib::RefPtr fn = create_pango_layout (label); + fn->set_markup (label); + window->draw_layout(gc_, 1, 1, fn); + + return true; +} + +void ILabel::on_style_changed (const Glib::RefPtr& style) { + + Glib::RefPtr fn = create_pango_layout(label); + fn->set_markup (label); + int labw, labh; + fn->get_pixel_size (labw, labh); + set_size_request (2+labw,2+labh); +} diff --git a/rtgui/ilabel.h b/rtgui/ilabel.h new file mode 100644 index 000000000..b4de52342 --- /dev/null +++ b/rtgui/ilabel.h @@ -0,0 +1,36 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _ILABEL_ +#define _ILABEL_ + +#include + +class ILabel : public Gtk::DrawingArea { + + Glib::ustring label; + + public: + ILabel (Glib::ustring lab); + bool on_expose_event(GdkEventExpose* event); + void on_realize(); + void on_style_changed (const Glib::RefPtr& style); +}; + +#endif + diff --git a/rtgui/imagearea.cc b/rtgui/imagearea.cc new file mode 100644 index 000000000..5a3820350 --- /dev/null +++ b/rtgui/imagearea.cc @@ -0,0 +1,595 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "imagearea.h" +#include +#include +#include "options.h" +#include "multilangmgr.h" +#include "cropwindow.h" +#include "../rtengine/refreshmap.h" +#include "options.h" + +ImageArea::ImageArea (ImageAreaPanel* p) : parent(p), firstOpen(true) { + + infotext = ""; + cropgl = NULL; + pmlistener = NULL; + pmhlistener = NULL; + focusGrabber = NULL; + flawnOverWindow = NULL; + mainCropWindow = NULL; + previewHandler = NULL; + showClippedH = false; + showClippedS = false; + listener = NULL; + + zoomPanel = Gtk::manage (new ZoomPanel (this)); + indClippedPanel = Gtk::manage (new IndicateClippedPanel (this)); + previewModePanel = Gtk::manage (new PreviewModePanel (this)); + + add_events(Gdk::LEAVE_NOTIFY_MASK); + + signal_size_allocate().connect( sigc::mem_fun(*this, &ImageArea::on_resized) ); + + dirty = false; + ipc = NULL; + iLinkedImageArea = NULL; +} + +ImageArea::~ImageArea () { + + for (std::list::iterator i=cropWins.begin(); i!=cropWins.end(); i++) + delete *i; + cropWins.clear (); + + if (mainCropWindow) + delete mainCropWindow; +} + +void ImageArea::on_realize() +{ + Gtk::DrawingArea::on_realize(); + +#if defined (__APPLE__) + // Workaround: disabling POINTER_MOTION_HINT_MASK as for gtk 2.24.22 the get_pointer() function is buggy for quartz and modifier mask is not updated correctly. + // This workaround should be removed when bug is fixed in GTK2 or when migrating to GTK3 + add_events(Gdk::EXPOSURE_MASK | Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::SCROLL_MASK); +#else + add_events(Gdk::EXPOSURE_MASK | Gdk::POINTER_MOTION_MASK | Gdk::POINTER_MOTION_HINT_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::SCROLL_MASK); +#endif + + Cairo::FontOptions cfo; + cfo.set_antialias (Cairo::ANTIALIAS_SUBPIXEL); + get_pango_context ()->set_cairo_font_options (cfo); +} + +void ImageArea::on_resized (Gtk::Allocation& req) { + if (ipc && get_width()>1) { // sometimes on_resize is called in some init state, causing wrong sizes + if (!mainCropWindow) { + mainCropWindow = new CropWindow (this, ipc, false, false); + mainCropWindow->setDecorated (false); + mainCropWindow->setFitZoomEnabled (true); + mainCropWindow->addCropWindowListener (this); + mainCropWindow->setCropGUIListener (cropgl); + mainCropWindow->setPointerMotionListener (pmlistener); + mainCropWindow->setPointerMotionHListener (pmhlistener); + mainCropWindow->setPosition (0, 0); + mainCropWindow->setSize (get_width(), get_height(), false); // this execute the refresh itself + mainCropWindow->enable(); // start processing ! + } + else { + mainCropWindow->setSize (get_width(), get_height()); + } + parent->syncBeforeAfterViews(); + } +} + +void ImageArea::setImProcCoordinator (rtengine::StagedImageProcessor* ipc_) { + if( !ipc_ ){ + focusGrabber = NULL; + std::list::iterator i = cropWins.begin(); + for( ;i!=cropWins.end();i++ ){ + delete *i; + } + cropWins.clear(); + + mainCropWindow->setObservedCropWin (NULL); + } + ipc = ipc_; + +} + +void ImageArea::setPreviewHandler (PreviewHandler* ph) { + + previewHandler = ph; +} + +void ImageArea::on_style_changed (const Glib::RefPtr& style) { + + // TODO: notify all crop windows that the style has been changed + queue_draw (); +} + +void ImageArea::setInfoText (Glib::ustring text) { + + infotext = text; + + Glib::RefPtr context = get_pango_context () ; + Pango::FontDescription fontd = context->get_font_description (); + fontd.set_weight (Pango::WEIGHT_BOLD); + fontd.set_size (9*Pango::SCALE); + context->set_font_description (fontd); + ilayout = create_pango_layout(""); + ilayout->set_markup(text); + int iw, ih; + ilayout->get_pixel_size (iw, ih); + ipixbuf = Gdk::Pixbuf::create (Gdk::COLORSPACE_RGB, true, 8, iw+8, ih+8); + ipixbuf->fill (128); +} + +void ImageArea::infoEnabled (bool e) { + + if (options.showInfo!=e) { + options.showInfo = e; + queue_draw (); + } +} + +CropWindow* ImageArea::getCropWindow (int x, int y) { + + CropWindow* cw = mainCropWindow; + for (std::list::iterator i=cropWins.begin(); i!=cropWins.end(); i++) + if ((*i)->isInside (x, y)) + return *i; + return cw; +} + + +void ImageArea::redraw () { + // dirty prevents multiple updates queued up + if (!dirty) { + dirty = true; + queue_draw (); + } +} + +bool ImageArea::on_expose_event(GdkEventExpose* event) { + dirty = false; + + if (event->count) + return true; + + Glib::RefPtr window = get_window(); + Cairo::RefPtr cr = get_window()->create_cairo_context(); + + if (mainCropWindow) { + //printf("MainCropWindow (%d x %d)\n", window->get_width(), window->get_height()); + mainCropWindow->expose (cr); + } + + if (options.showInfo==true && infotext!="") { + int fnw, fnh; + ilayout->get_pixel_size (fnw, fnh); + window->draw_pixbuf (get_style()->get_base_gc (Gtk::STATE_NORMAL), ipixbuf, 0, 0, 4, 4, fnw+8, fnh+8, Gdk::RGB_DITHER_NONE, 0, 0); + cr->set_source_rgb (1.0, 1.0, 1.0); + cr->move_to (8, 8); + ilayout->add_to_cairo_context (cr); + cr->fill (); + } + + for (std::list::reverse_iterator i=cropWins.rbegin(); i!=cropWins.rend(); i++) + (*i)->expose (cr); + + return true; +} + + +bool ImageArea::on_motion_notify_event (GdkEventMotion* event) { + + if (focusGrabber) + focusGrabber->pointerMoved (event->state, event->x, event->y); + else { + CropWindow* cw = getCropWindow (event->x, event->y); + if (cw) { + if (cw != flawnOverWindow) { + if (flawnOverWindow) + flawnOverWindow->flawnOver(false); + cw->flawnOver(true); + flawnOverWindow = cw; + } + cw->pointerMoved (event->state, event->x, event->y); + } + else if (flawnOverWindow) { + flawnOverWindow->flawnOver(false); + flawnOverWindow = NULL; + } + } + return true; +} + +bool ImageArea::on_button_press_event (GdkEventButton* event) { + + if (focusGrabber) + focusGrabber->buttonPress (event->button, event->type, event->state, event->x, event->y); + else { + CropWindow* cw = getCropWindow (event->x, event->y); + if (cw) + cw->buttonPress (event->button, event->type, event->state, event->x, event->y); + } + return true; +} + +bool ImageArea::on_scroll_event (GdkEventScroll* event) { + + CropWindow* cw = getCropWindow (event->x, event->y); + if (cw) { + int newCenterX = (int)event->x; + int newCenterY = (int)event->y; + if (event->direction==GDK_SCROLL_UP && !cw->isMaxZoom()) { + cw->findCenter (1, newCenterX, newCenterY); + cw->zoomIn (true, newCenterX, newCenterY); + } + else if (!cw->isMinZoom()) { + cw->findCenter (-1, newCenterX, newCenterY); + cw->zoomOut (true, newCenterX, newCenterY); + } + } + return true; +} + +bool ImageArea::on_button_release_event (GdkEventButton* event) { + + if (focusGrabber) + focusGrabber->buttonRelease (event->button, event->type, event->state, event->x, event->y); + else { + CropWindow* cw = getCropWindow (event->x, event->y); + if (cw) { + cw->buttonRelease (event->button, event->type, event->state, event->x, event->y); + } + } + return true; +} + +bool ImageArea::on_leave_notify_event (GdkEventCrossing* event) { + if (flawnOverWindow) { + flawnOverWindow->flawnOver(false); + flawnOverWindow = NULL; + } + if (focusGrabber) { + focusGrabber->flawnOver(false); + focusGrabber->leaveNotify (event); + } + else { + CropWindow* cw = getCropWindow (event->x, event->y); + + if (cw) { + cw->flawnOver(false); + cw->leaveNotify (event); + } + } + return true; +} + +void ImageArea::subscribe(EditSubscriber *subscriber) { + mainCropWindow->cropHandler.setEditSubscriber(subscriber); + for (std::list::iterator i=cropWins.begin(); i!=cropWins.end(); i++) + (*i)->cropHandler.setEditSubscriber(subscriber); + + EditDataProvider::subscribe(subscriber); + + if (listener && listener->getToolBar()) + listener->getToolBar()->startEditMode (); + + if (subscriber->getEditingType() == ET_OBJECTS) { + // In this case, no need to reprocess the image, so we redraw the image to display the geometry + queue_draw(); + } +} + +void ImageArea::unsubscribe() { + bool wasObjectType = false; + EditSubscriber* oldSubscriber = EditDataProvider::getCurrSubscriber(); + if (oldSubscriber && oldSubscriber->getEditingType()==ET_OBJECTS) + wasObjectType = true; + + EditDataProvider::unsubscribe(); + // Ask the Crops to free-up edit mode buffers + mainCropWindow->cropHandler.setEditSubscriber(NULL); + for (std::list::iterator i=cropWins.begin(); i!=cropWins.end(); i++) + (*i)->cropHandler.setEditSubscriber(NULL); + setToolHand(); + + if (listener && listener->getToolBar()) + listener->getToolBar()->stopEditMode (); + + if (wasObjectType) + queue_draw(); +} + +void ImageArea::getImageSize (int &w, int&h) { + if (ipc) { + w = ipc->getFullWidth(); + h = ipc->getFullHeight(); + } + else + w = h = 0; +} + +void ImageArea::grabFocus (CropWindow* cw) { + + focusGrabber = cw; + if (cw && cw!=mainCropWindow) + cropWindowSelected (cw); +} + +void ImageArea::unGrabFocus () { + + focusGrabber = NULL; +} + +void ImageArea::addCropWindow () { + if (!mainCropWindow) + return; // if called but no image is loaded, it would crash + + CropWindow* cw = new CropWindow (this, ipc, true, true); + cw->zoom11(); + cw->setCropGUIListener (cropgl); + cw->setPointerMotionListener (pmlistener); + cw->setPointerMotionHListener (pmhlistener); + int lastWidth = options.detailWindowWidth; + int lastHeight = options.detailWindowHeight; + if (lastWidthgetSize(lastWidth,lastHeight); + } + + cropWins.push_front (cw); + + // Position the new crop window this way: start from top right going down to bottom. When bottom is reached, continue top left going down...... + int N = cropWins.size()-1; + int cropwidth, cropheight; + + if(lastWidth <= 0) { // this is only the case for very first start of RT 4.1 or when options file is deleted + cropwidth = 200; + cropheight = 200; + } else { + cropwidth = lastWidth; + cropheight = lastHeight; + } + + cw->setSize (cropwidth,cropheight); + int x,y; + int maxRows = get_height()/cropheight; + if(maxRows == 0) + maxRows = 1; + + int col = N / maxRows; + if(col % 2) { // from left side + col = col/2; + x = col*cropwidth; + if(x >= get_width() - 50) + x = get_width() - 50; + } + else { // from right side + col /= 2; + col++; + x = get_width() - col * cropwidth; + if(x <= 0) + x = 0; + } + + y = cropheight * (N%maxRows); + cw->setPosition (x, y); + cw->enable(); // start processing! + + int x0,y0,w,h,wc,hc; + mainCropWindow->getCropRectangle(x0,y0,w,h ); + cw->getCropSize(wc,hc); + cw->setCropPosition(x0+w/2-wc/2,y0+h/2-hc/2); + mainCropWindow->setObservedCropWin (cropWins.front()); + + if(cropWins.size()==1) // after first detail window we already have high quality + ipc->startProcessing(M_HIGHQUAL); +} + + +void ImageArea::cropWindowSelected (CropWindow* cw) { + + std::list::iterator i = std::find (cropWins.begin(), cropWins.end(), cw); + if (i!=cropWins.end()) + cropWins.erase (i); + cropWins.push_front (cw); + mainCropWindow->setObservedCropWin (cropWins.front()); +} + +void ImageArea::cropWindowClosed (CropWindow* cw) { + + focusGrabber = NULL; + std::list::iterator i = std::find (cropWins.begin(), cropWins.end(), cw); + if (i!=cropWins.end()) + cropWins.erase (i); + if (!cropWins.empty()) + mainCropWindow->setObservedCropWin (cropWins.front()); + else + mainCropWindow->setObservedCropWin (NULL); + queue_draw (); +} + +void ImageArea::straightenReady (double rotDeg) { + + if (listener) + listener->rotateSelectionReady (rotDeg); +} + +void ImageArea::spotWBSelected (int x, int y) { + + if (listener) + listener->spotWBselected (x, y); +} + +void ImageArea::getScrollImageSize (int& w, int& h) { + + if (mainCropWindow && ipc) { + double z = mainCropWindow->getZoom (); + w = ipc->getFullWidth() * z; + h = ipc->getFullHeight() * z; + } + else + w = h = 0; +} + +void ImageArea::getScrollPosition (int& x, int& y) { + + if (mainCropWindow) { + int cropX, cropY; + mainCropWindow->getCropPosition (cropX, cropY); + x = cropX*mainCropWindow->getZoom (); + y = cropY*mainCropWindow->getZoom (); + } + else + x = y = 0; +} + +void ImageArea::setScrollPosition (int x, int y) { + + if (mainCropWindow) { + mainCropWindow->delCropWindowListener (this); + mainCropWindow->setCropPosition (x/mainCropWindow->getZoom (), y/mainCropWindow->getZoom ()); + mainCropWindow->addCropWindowListener (this); + } +} + +void ImageArea::cropPositionChanged (CropWindow* cw) { + + syncBeforeAfterViews (); +} + +void ImageArea::cropWindowSizeChanged (CropWindow* cw) { + + syncBeforeAfterViews (); +} + +void ImageArea::cropZoomChanged (CropWindow* cw) { + + if (cw==mainCropWindow) { + parent->zoomChanged (); + syncBeforeAfterViews (); + zoomPanel->refreshZoomLabel (); + } +} + +double ImageArea::getZoom () { + + if (mainCropWindow) + return mainCropWindow->getZoom (); + else + return 1.0; +} + +// Called by imageAreaPanel before/after views +void ImageArea::setZoom (double zoom) { + + if (mainCropWindow) + mainCropWindow->setZoom (zoom); + zoomPanel->refreshZoomLabel (); +} + +void ImageArea::initialImageArrived (CropWindow* cw) { + + if (mainCropWindow) { + if(firstOpen || options.prevdemo!=PD_Sidecar || (!options.rememberZoomAndPan) ) { + mainCropWindow->zoomFit (false); + firstOpen = false; + mainCropWindow->cropHandler.getFullImageSize(fullImageWidth,fullImageHeight); + } else { + int w,h; + mainCropWindow->cropHandler.getFullImageSize(w,h); + if(w == fullImageWidth && h == fullImageHeight) { // && mainCropWindow->getZoom() != mainCropWindow->getZoomFitVal()) { + int x,y; + mainCropWindow->getCropPosition(x,y); + mainCropWindow->setCropPosition(x,y, false); + } else { + mainCropWindow->zoomFit (false); + } + fullImageWidth = w; + fullImageHeight = h; + } + } +} + +void ImageArea::syncBeforeAfterViews () { + parent->syncBeforeAfterViews (); +} + +void ImageArea::setCropGUIListener (CropGUIListener* l) { + + cropgl = l; + for (std::list::iterator i=cropWins.begin(); i!=cropWins.end(); i++) + (*i)->setCropGUIListener (cropgl); + if (mainCropWindow) + mainCropWindow->setCropGUIListener (cropgl); +} + +void ImageArea::setPointerMotionListener (PointerMotionListener* pml) { + + pmlistener = pml; + for (std::list::iterator i=cropWins.begin(); i!=cropWins.end(); i++) + (*i)->setPointerMotionListener (pml); + if (mainCropWindow) + mainCropWindow->setPointerMotionListener (pml); +} + +void ImageArea::setPointerMotionHListener (PointerMotionListener* pml) { + + pmhlistener = pml; + for (std::list::iterator i=cropWins.begin(); i!=cropWins.end(); i++) + (*i)->setPointerMotionHListener (pml); + if (mainCropWindow) + mainCropWindow->setPointerMotionHListener (pml); +} + +ToolMode ImageArea::getToolMode () { + + if (listener && listener->getToolBar()) + return listener->getToolBar()->getTool (); + else + return TMHand; +} + +void ImageArea::setToolHand () { + + if (listener && listener->getToolBar()) { + listener->getToolBar()->setTool (TMHand); + } +} + +int ImageArea::getSpotWBRectSize () { + + if (listener) + return listener->getSpotWBRectSize (); + else + return 1; +} diff --git a/rtgui/imagearea.h b/rtgui/imagearea.h new file mode 100644 index 000000000..f8e665cca --- /dev/null +++ b/rtgui/imagearea.h @@ -0,0 +1,138 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef __IMAGEAREA_H__ +#define __IMAGEAREA_H__ + +#include +#include "cropguilistener.h" +#include "imageareapanel.h" +#include "editenums.h" +#include "toolbar.h" +#include "previewhandler.h" +#include "imageareatoollistener.h" +#include "cropwindow.h" +#include "zoompanel.h" +#include "indclippedpanel.h" +#include "previewmodepanel.h" +#include "edit.h" + +class ImageAreaPanel; +class ImageArea : public Gtk::DrawingArea, public CropWindowListener, public EditDataProvider { + + friend class ZoomPanel; + + protected: + + Glib::ustring infotext; + Glib::RefPtr ilayout; + Glib::RefPtr deglayout; + Glib::RefPtr ipixbuf; + bool showClippedH, showClippedS; + + ImageAreaPanel* parent; + + std::list cropWins; + PreviewHandler* previewHandler; + rtengine::StagedImageProcessor* ipc; + + bool dirty; + CropWindow* focusGrabber; + CropGUIListener* cropgl; + PointerMotionListener* pmlistener; + PointerMotionListener* pmhlistener; + ImageAreaToolListener* listener; + + CropWindow* getCropWindow (int x, int y); + bool firstOpen; + int fullImageWidth, fullImageHeight; + public: + CropWindow* mainCropWindow; + CropWindow* flawnOverWindow; + ZoomPanel* zoomPanel; + IndicateClippedPanel* indClippedPanel; + PreviewModePanel* previewModePanel; + ImageArea* iLinkedImageArea; // used to set a reference to the Before image area, which is set when before/after view is enabled + + ImageArea (ImageAreaPanel* p); + ~ImageArea (); + + void setImProcCoordinator (rtengine::StagedImageProcessor* ipc_); + void setPreviewModePanel(PreviewModePanel* previewModePanel_){previewModePanel = previewModePanel_;}; + void setIndicateClippedPanel(IndicateClippedPanel* indClippedPanel_){indClippedPanel = indClippedPanel_;}; + + void getScrollImageSize (int& w, int& h); + void getScrollPosition (int& x, int& y); + void setScrollPosition (int x, int y); // called by the imageareapanel when the scrollbars have been changed + + // enabling and setting text of info area + void setInfoText (Glib::ustring text); + void infoEnabled (bool e); + + // widget base events + void on_realize (); + bool on_expose_event (GdkEventExpose* event); + bool on_motion_notify_event (GdkEventMotion* event); + bool on_button_press_event (GdkEventButton* event); + bool on_button_release_event (GdkEventButton* event); + bool on_scroll_event (GdkEventScroll* event); + bool on_leave_notify_event (GdkEventCrossing* event); + void on_resized (Gtk::Allocation& req); + void on_style_changed (const Glib::RefPtr& style); + void syncBeforeAfterViews (); + + void setCropGUIListener (CropGUIListener* l); + void setPointerMotionListener (PointerMotionListener* pml); + void setPointerMotionHListener (PointerMotionListener* pml); + void setImageAreaToolListener (ImageAreaToolListener* l) { listener = l; } + void setPreviewHandler (PreviewHandler* ph); + PreviewHandler* getPreviewHandler () { return previewHandler; } + + void grabFocus (CropWindow* cw); + void unGrabFocus (); + void addCropWindow (); + void cropWindowSelected (CropWindow* cw); + void cropWindowClosed (CropWindow* cw); + ToolMode getToolMode (); + void setToolHand (); + void straightenReady (double rotDeg); + void spotWBSelected (int x, int y); + int getSpotWBRectSize (); + void redraw (); + + void zoomFit (); + double getZoom (); + void setZoom (double zoom); + + // EditDataProvider interface + void subscribe(EditSubscriber *subscriber); + void unsubscribe(); + void getImageSize (int &w, int&h); + + // CropWindowListener interface + void cropPositionChanged (CropWindow* cw); + void cropWindowSizeChanged (CropWindow* cw); + void cropZoomChanged (CropWindow* cw); + void initialImageArrived (CropWindow* cw) ; + + CropWindow* getMainCropWindow () { return mainCropWindow; } +}; + + + +#endif diff --git a/rtgui/imageareapanel.cc b/rtgui/imageareapanel.cc new file mode 100644 index 000000000..e7c91d5e9 --- /dev/null +++ b/rtgui/imageareapanel.cc @@ -0,0 +1,97 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "imageareapanel.h" + +ImageAreaPanel::ImageAreaPanel () : before(NULL), after(NULL) { + + set_border_width (2); + + imageArea = new ImageArea (this); + + Gtk::HBox* hb1 = Gtk::manage (new Gtk::HBox ()); + Gtk::Frame* frame = Gtk::manage (new Gtk::Frame ()); + + frame->add (*imageArea); + frame->set_shadow_type (Gtk::SHADOW_IN ); + hb1->pack_start (*frame, Gtk::PACK_EXPAND_WIDGET); + + pack_start (*hb1); + frame->show (); + imageArea->show (); + hb1->show (); + +} + +ImageAreaPanel::~ImageAreaPanel () { + + delete imageArea; +} + +void ImageAreaPanel::syncBeforeAfterViews () { + + if (before && this==after) + before->synchronize (); + else if (after && this==before) + after->synchronize (); + + queue_draw (); +} + +void ImageAreaPanel::setBeforeAfterViews (ImageAreaPanel* bef, ImageAreaPanel* aft) { + + before = bef; + after = aft; + syncBeforeAfterViews (); +} + +void ImageAreaPanel::zoomChanged () { + + if (after && this==before) + after->imageArea->setZoom (imageArea->getZoom ()); + else if (before && this==after) + before->imageArea->setZoom (imageArea->getZoom ()); +} + +void ImageAreaPanel::synchronize () { + + if (after && this==before) { + int imgw, imgh, x, y; + after->imageArea->getScrollImageSize (imgw, imgh); + after->imageArea->getScrollPosition (x, y); + if (imgw>0 && imgh>0) { + int bimgw, bimgh; + imageArea->getScrollImageSize (bimgw, bimgh); + imageArea->setScrollPosition (x*bimgw/imgw, y*bimgh/imgh); + imageArea->queue_draw (); + } + } + else if (before && this==after) { + int imgw, imgh, x, y; + before->imageArea->getScrollImageSize (imgw, imgh); + before->imageArea->getScrollPosition (x, y); + if (imgw>0 && imgh>0) { + int bimgw, bimgh; + imageArea->getScrollImageSize (bimgw, bimgh); + imageArea->setScrollPosition (x*bimgw/imgw, y*bimgh/imgh); + imageArea->queue_draw (); + } + } + +} + diff --git a/rtgui/imageareapanel.h b/rtgui/imageareapanel.h new file mode 100644 index 000000000..1b62682a1 --- /dev/null +++ b/rtgui/imageareapanel.h @@ -0,0 +1,45 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _IMAGEAREAPANEL_ +#define _IMAGEAREAPANEL_ + +#include "imagearea.h" + +class ImageArea; +class ImageAreaPanel : public Gtk::VBox { + + protected: + + ImageAreaPanel *before, *after; + + void synchronize (); + + public: + ImageArea* imageArea; + + ImageAreaPanel (); + ~ImageAreaPanel (); + + void zoomChanged (); + + void setBeforeAfterViews (ImageAreaPanel* bef, ImageAreaPanel* aft); + void syncBeforeAfterViews(); +}; + +#endif diff --git a/rtgui/imageareatoollistener.h b/rtgui/imageareatoollistener.h new file mode 100644 index 000000000..cc26c70a8 --- /dev/null +++ b/rtgui/imageareatoollistener.h @@ -0,0 +1,39 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _IMAGEAREATOOLLISTENER_ +#define _IMAGEAREATOOLLISTENER_ + +#include "toolbar.h" +#include "thumbnail.h" +#include "cropguilistener.h" + +class ImageAreaToolListener { + + public: + virtual void spotWBselected (int x, int y, Thumbnail* thm=NULL) {} + virtual int getSpotWBRectSize () { return 8; } + virtual void cropSelectionReady () {} + virtual void rotateSelectionReady (double rotate_deg, Thumbnail* thm=NULL) {} + virtual ToolBar* getToolBar () { return NULL; } + virtual void removeWbTool() =0; + virtual CropGUIListener* startCropEditing (Thumbnail* thm=NULL) { return NULL; } +}; + +#endif + diff --git a/rtgui/impulsedenoise.cc b/rtgui/impulsedenoise.cc new file mode 100644 index 000000000..2979d42f2 --- /dev/null +++ b/rtgui/impulsedenoise.cc @@ -0,0 +1,108 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "impulsedenoise.h" +#include +#include +#include "guiutils.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +ImpulseDenoise::ImpulseDenoise () : FoldableToolPanel(this, "impulsedenoise", M("TP_IMPULSEDENOISE_LABEL"), true, true) { + + thresh = Gtk::manage (new Adjuster (M("TP_IMPULSEDENOISE_THRESH"), 0, 100, 1, 50)); + + pack_start (*thresh); + + thresh->setAdjusterListener (this); + + show_all_children (); +} + +void ImpulseDenoise::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + if (pedited) { + thresh->setEditedState (pedited->impulseDenoise.thresh ? Edited : UnEdited); + set_inconsistent (multiImage && !pedited->impulseDenoise.enabled); + } + + setEnabled(pp->impulseDenoise.enabled); + + thresh->setValue (pp->impulseDenoise.thresh); + + enableListener (); +} + +void ImpulseDenoise::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->impulseDenoise.thresh = thresh->getValue (); + pp->impulseDenoise.enabled = getEnabled(); + + if (pedited) { + pedited->impulseDenoise.thresh = thresh->getEditedState (); + pedited->impulseDenoise.enabled = !get_inconsistent(); + } +} + +void ImpulseDenoise::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + thresh->setDefault (defParams->impulseDenoise.thresh); + + if (pedited) + thresh->setDefaultEditedState (pedited->impulseDenoise.thresh ? Edited : UnEdited); + else + thresh->setDefaultEditedState (Irrelevant); +} + +void ImpulseDenoise::adjusterChanged (Adjuster* a, double newval) { + + if (listener && getEnabled()) { + + listener->panelChanged (EvIDNThresh, Glib::ustring::format (std::setw(2), std::fixed, std::setprecision(1), a->getValue())); + } +} + +void ImpulseDenoise::enabledChanged () { + if (listener) { + if (get_inconsistent()) + listener->panelChanged (EvIDNEnabled, M("GENERAL_UNCHANGED")); + else if (getEnabled()) + listener->panelChanged (EvIDNEnabled, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvIDNEnabled, M("GENERAL_DISABLED")); + } +} + +void ImpulseDenoise::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + thresh->showEditedCB (); +} + +void ImpulseDenoise::setAdjusterBehavior (bool threshadd) { + + thresh->setAddMode(threshadd); +} + +void ImpulseDenoise::trimValues (rtengine::procparams::ProcParams* pp) { + + thresh->trimValue(pp->impulseDenoise.thresh); +} diff --git a/rtgui/impulsedenoise.h b/rtgui/impulsedenoise.h new file mode 100644 index 000000000..7c7cdc48c --- /dev/null +++ b/rtgui/impulsedenoise.h @@ -0,0 +1,48 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _IMPULSEDENOISE_H_ +#define _IMPULSEDENOISE_H_ + +#include +#include "adjuster.h" +#include "toolpanel.h" + +class ImpulseDenoise : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel { + + protected: + Adjuster* thresh; + //Adjuster* edge; + + public: + + ImpulseDenoise (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + + void adjusterChanged (Adjuster* a, double newval); + void enabledChanged (); + + void setAdjusterBehavior (bool threshadd); + void trimValues (rtengine::procparams::ProcParams* pp); +}; + +#endif diff --git a/rtgui/indclippedpanel.cc b/rtgui/indclippedpanel.cc new file mode 100644 index 000000000..a1da0c9b7 --- /dev/null +++ b/rtgui/indclippedpanel.cc @@ -0,0 +1,69 @@ +/* + * This file is part of RawTherapee. + * + * + * 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 "indclippedpanel.h" +#include "options.h" +#include "multilangmgr.h" +#include "imagearea.h" +#include "rtimage.h" + +IndicateClippedPanel::IndicateClippedPanel (ImageArea* ia) : imageArea(ia) { + + Glib::ustring tt; + + 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); + else 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"))); + 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); + else indclippeds->set_tooltip_markup (tt); + + indclippedh->set_active (options.showClippedHighlights); + indclippeds->set_active (options.showClippedShadows); + + pack_start (*indclippedh, Gtk::PACK_SHRINK, 0); + pack_start (*indclippeds, Gtk::PACK_SHRINK, 0); + + indclippedh->signal_toggled().connect( sigc::mem_fun(*this, &IndicateClippedPanel::buttonToggled) ); + indclippeds->signal_toggled().connect( sigc::mem_fun(*this, &IndicateClippedPanel::buttonToggled) ); + + show_all (); +} + +// inverts a toggle programmatically +void IndicateClippedPanel::toggleClipped (bool highlights) { + if (highlights) + indclippedh->set_active(!indclippedh->get_active()); + else + indclippeds->set_active(!indclippeds->get_active()); +} + +void IndicateClippedPanel::buttonToggled () { + imageArea->queue_draw (); + + // this will redraw the linked Before image area + // which is set when before/after view is enabled + if (imageArea->iLinkedImageArea!=NULL) + imageArea->iLinkedImageArea->queue_draw (); +} diff --git a/rtgui/indclippedpanel.h b/rtgui/indclippedpanel.h new file mode 100644 index 000000000..4c9c6a986 --- /dev/null +++ b/rtgui/indclippedpanel.h @@ -0,0 +1,42 @@ +/* + * This file is part of RawTherapee. + * + * + * 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 _INDCLIPPEDPANEL_ +#define _INDCLIPPEDPANEL_ + +#include + +class ImageArea; +class IndicateClippedPanel : public Gtk::HBox { + + protected: + Gtk::ToggleButton* indclippedh; + Gtk::ToggleButton* indclippeds; + ImageArea* imageArea; + + public: + IndicateClippedPanel (ImageArea* ia); + + void buttonToggled (); + + void toggleClipped (bool highlights); // inverts a toggle programmatically + + bool showClippedShadows () { return indclippeds->get_active (); } + bool showClippedHighlights () { return indclippedh->get_active (); } +}; + +#endif diff --git a/rtgui/inspector.cc b/rtgui/inspector.cc new file mode 100644 index 000000000..00ae1f5cb --- /dev/null +++ b/rtgui/inspector.cc @@ -0,0 +1,262 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "inspector.h" +#include "guiutils.h" +#include +#include "cursormanager.h" +#include "guiutils.h" +#include "options.h" +#include "../rtengine/safegtk.h" +#include "../rtengine/previewimage.h" + +extern Options options; + +InspectorBuffer::InspectorBuffer(const Glib::ustring &imagePath) : currTransform(0), fromRaw(false) { + if (!imagePath.empty() && safe_file_test(imagePath, Glib::FILE_TEST_EXISTS) && !safe_file_test(imagePath, Glib::FILE_TEST_IS_DIR)) { + imgPath = imagePath; + + // generate thumbnail image + Glib::ustring ext = getExtension (imagePath); + if (ext=="") { + imgPath.clear(); + return; + } + + rtengine::PreviewImage pi(imagePath, ext, rtengine::PreviewImage::PIM_EmbeddedOrRaw); + Cairo::RefPtr imageSurface = pi.getImage(); + + if (imageSurface) { + imgBuffer.setSurface(imageSurface); + fromRaw = true; + } + else { + imgPath.clear(); + } + } +} + +/* +InspectorBuffer::~InspectorBuffer() { +} +*/ + +int InspectorBuffer::infoFromImage (const Glib::ustring& fname) { + + rtengine::ImageMetaData* idata = rtengine::ImageMetaData::fromFile (fname, NULL); + if (!idata) + return 0; + + int deg = 0; + if (idata->hasExif()) { + if (idata->getOrientation()=="Rotate 90 CW" ) deg = 90; + else if (idata->getOrientation()=="Rotate 180" ) deg = 180; + else if (idata->getOrientation()=="Rotate 270 CW") deg = 270; + } + delete idata; + return deg; +} + +Inspector::Inspector () : currImage(NULL), zoom(0.0), active(false) {} + +Inspector::~Inspector() { + deleteBuffers(); +} + +bool Inspector::on_expose_event (GdkEventExpose* event) { + + Glib::RefPtr win = get_window(); + if (!win) + return false; + + if (!active) { + active = true; + } + + + // cleanup the region + + + if (currImage && currImage->imgBuffer.surfaceCreated()) { + // this will eventually create/update the off-screen pixmap + + // compute the displayed area + Coord availableSize; + Coord topLeft; + Coord displayedSize; + Coord dest(0, 0); + win->get_size(availableSize.x, availableSize.y); + int imW = currImage->imgBuffer.getWidth(); + int imH = currImage->imgBuffer.getHeight(); + + if (imW < availableSize.x) { + // center the image in the available space along X + topLeft.x = 0; + displayedSize.x = availableSize.x; + dest.x = (availableSize.x - imW) / 2; + } + else { + // partial image display + // double clamp + topLeft.x = center.x + availableSize.x/2; + topLeft.x = rtengine::min(topLeft.x, imW); + topLeft.x -= availableSize.x; + topLeft.x = rtengine::max(topLeft.x, 0); + } + + if (imH < availableSize.y) { + // center the image in the available space along Y + topLeft.y = 0; + displayedSize.y = availableSize.y; + dest.y = (availableSize.y - imH) / 2; + } + else { + // partial image display + // double clamp + topLeft.y = center.y + availableSize.y/2; + topLeft.y = rtengine::min(topLeft.y, imH); + topLeft.y -= availableSize.y; + topLeft.y = rtengine::max(topLeft.y, 0); + } + + //printf("center: %d, %d (img: %d, %d) (availableSize: %d, %d) (topLeft: %d, %d)\n", center.x, center.y, imW, imH, availableSize.x, availableSize.y, topLeft.x, topLeft.y); + + // define the destination area + currImage->imgBuffer.setDrawRectangle(win, dest.x, dest.y, rtengine::min(availableSize.x-dest.x, imW), rtengine::min(availableSize.y-dest.y,imH), false); + currImage->imgBuffer.setSrcOffset(topLeft.x, topLeft.y); + + if (!currImage->imgBuffer.surfaceCreated()) { + return false; + } + + // Draw! + + Gdk::Color c; + Cairo::RefPtr cr = win->create_cairo_context(); + Glib::RefPtr style = get_style(); + + // draw the background + c = style->get_bg (Gtk::STATE_NORMAL); + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + cr->set_line_width (0); + cr->rectangle (0, 0, availableSize.x, availableSize.y); + cr->fill (); + + currImage->imgBuffer.copySurface(win); + + // draw the frame + c = style->get_fg (Gtk::STATE_NORMAL); + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + cr->set_line_width (1); + cr->rectangle (0.5, 0.5, availableSize.x-1, availableSize.y-1); + cr->stroke (); + } + return true; +} + +void Inspector::mouseMove (rtengine::Coord2D pos, int transform) { + if (!active) + return; + + if (currImage) + center.set(int(rtengine::LIM01(pos.x)*double(currImage->imgBuffer.getWidth())), int(rtengine::LIM01(pos.y)*double(currImage->imgBuffer.getHeight()))); + else + center.set(0,0); + queue_draw(); +} + +void Inspector::switchImage (const Glib::ustring &fullPath) { + if (!active) + return; + + // we first check the size of the list, it may have been changed in Preference + if (images.size() > size_t(options.maxInspectorBuffers)) { + // deleting the last entries + for (size_t i=images.size()-1; i>size_t(options.maxInspectorBuffers-1); --i) { + delete images.at(i); + images.at(i) = NULL; + } + // resizing down + images.resize(options.maxInspectorBuffers); + } + + if (fullPath.empty()) { + currImage = NULL; + queue_draw(); + return; + } + else { + bool found = false; + for (size_t i=0; iimgPath==fullPath) { + currImage = images.at(i); + + // rolling the list 1 step to the beginning + for (size_t j=i; jimgPath.empty()) { + images.push_back(iBuffer); + currImage = images.at(images.size()-1); + } + else { + currImage = NULL; + } + } + } +} + +void Inspector::deleteBuffers () { + for (size_t i=0; i + * + * 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 _INSPECTOR_ +#define _INSPECTOR_ + +#include +#include "guiutils.h" +#include "coord.h" + +class InspectorBuffer { + private: + int infoFromImage (const Glib::ustring& fname); + + public: + BackBuffer imgBuffer; + Glib::ustring imgPath; + int currTransform; // coarse rotation from RT, not from shot orientation + bool fromRaw; + + InspectorBuffer(const Glib::ustring &imgagePath); + //~InspectorBuffer(); +}; + +class Inspector : public Gtk::DrawingArea { + + private: + Coord center; + std::vector images; + InspectorBuffer* currImage; + double zoom; + bool active; + + bool on_expose_event (GdkEventExpose* event); + void deleteBuffers(); + + public: + Inspector(); + ~Inspector(); + + /** @brief Mouse movement to a new position + * @param pos Location of the mouse, in percentage (i.e. [0;1] range) relative to the full size image ; -1,-1 == out of the image + * @param transform H/V flip and coarse rotation transformation + */ + void mouseMove (rtengine::Coord2D pos, int transform); + + /** @brief A new image is being flown over + * @param fullPath Full path of the image that is being hovered inspect, or an empty string if out of any image. + */ + void switchImage (const Glib::ustring &fullPath); + + /** @brief Set the new coarse rotation transformation + * @param transform A semi-bitfield coarse transformation using #defines from iimage.h + */ + void setTransformation (int transform); + + /** @brief Use this method to flush all image buffer whenever the Inspector panel is hidden + */ + void flushBuffers (); + + /** @brief Set the inspector on/off + * @param state true if to activate the Inspector, false to disable it and flush the buffers + */ + void setActive(bool state); + + /** @brief Get the on/off state + */ + bool isActive() { return active; }; +}; + +#endif diff --git a/rtgui/iptcpanel.cc b/rtgui/iptcpanel.cc new file mode 100644 index 000000000..d87b69000 --- /dev/null +++ b/rtgui/iptcpanel.cc @@ -0,0 +1,591 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "iptcpanel.h" +#include "clipboard.h" +#include "rtimage.h" + +extern Glib::ustring argv0; + +using namespace rtengine; +using namespace rtengine::procparams; + +IPTCPanel::IPTCPanel () { + + set_border_width (2); + + Gtk::Table* iptc = Gtk::manage( new Gtk::Table (27, 2) ); + + int row = 0; + + Gtk::Label* capl = Gtk::manage( new Gtk::Label (M("IPTCPANEL_CAPTION")+":") ); + captionText = Gtk::TextBuffer::create (); + captionView = Gtk::manage( new Gtk::TextView (captionText) ); + Gtk::ScrolledWindow* scrolledWindowc = Gtk::manage( new Gtk::ScrolledWindow() ); + scrolledWindowc->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS); + scrolledWindowc->add(*captionView); + capl->set_tooltip_text (M("IPTCPANEL_CAPTIONHINT")); + captionView->set_tooltip_text (M("IPTCPANEL_CAPTIONHINT")); + captionView->set_size_request(32, 80); + iptc->attach (*capl, 0, 1, row, row+1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + iptc->attach (*scrolledWindowc, 1, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + row++; + + Gtk::Label* capwl = Gtk::manage( new Gtk::Label (M("IPTCPANEL_CAPTIONWRITER")+":") ); + captionWriter = Gtk::manage( new Gtk::Entry () ); + capwl->set_tooltip_text (M("IPTCPANEL_CAPTIONWRITERHINT")); + captionWriter->set_tooltip_text (M("IPTCPANEL_CAPTIONWRITERHINT")); + iptc->attach (*capwl, 0, 1, row, row+1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + iptc->attach (*captionWriter, 1, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + row++; + + Gtk::Label* headl = Gtk::manage( new Gtk::Label (M("IPTCPANEL_HEADLINE")+":") ); + headline = Gtk::manage( new Gtk::Entry () ); + headl->set_tooltip_text (M("IPTCPANEL_HEADLINEHINT")); + headline->set_tooltip_text (M("IPTCPANEL_HEADLINEHINT")); + iptc->attach (*headl, 0, 1, row, row+1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + iptc->attach (*headline, 1, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + row++; + + Gtk::Label* instl = Gtk::manage( new Gtk::Label (M("IPTCPANEL_INSTRUCTIONS")+":") ); + instructions = Gtk::manage( new Gtk::Entry () ); + instl->set_tooltip_text (M("IPTCPANEL_INSTRUCTIONSHINT")); + instructions->set_tooltip_text (M("IPTCPANEL_INSTRUCTIONSHINT")); + iptc->attach (*instl, 0, 1, row, row+1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + iptc->attach (*instructions, 1, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + row++; + + Gtk::HSeparator* hsep1 = Gtk::manage( new Gtk::HSeparator () ); + iptc->attach (*hsep1, 0, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + row++; + + Gtk::Label* keyl = Gtk::manage( new Gtk::Label (M("IPTCPANEL_KEYWORDS")+":")); + keywords = Gtk::manage( new Gtk::ListViewText (1, false, Gtk::SELECTION_MULTIPLE) ); + keywords->set_headers_visible (false); + keywords->set_size_request (50, 80); + Gtk::ScrolledWindow* scrolledWindowkw = Gtk::manage( new Gtk::ScrolledWindow() ); + scrolledWindowkw->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS); + scrolledWindowkw->add(*keywords); + keyword = Gtk::manage( new Gtk::ComboBoxEntryText () ); + keyword->set_size_request (32, -1); + keyl->set_tooltip_text (M("IPTCPANEL_KEYWORDSHINT")); + keywords->set_tooltip_text (M("IPTCPANEL_KEYWORDSHINT")); + keyword->set_tooltip_text (M("IPTCPANEL_KEYWORDSHINT")); + addKW = Gtk::manage( new Gtk::Button () ); + delKW = Gtk::manage( new Gtk::Button () ); + Gtk::Image* addKWImg = Gtk::manage( new RTImage ("list-add-small.png") ); + Gtk::Image* delKWImg = Gtk::manage( new RTImage ("list-remove-red-small.png") ); + addKW->add (*addKWImg); + delKW->add (*delKWImg); + Gtk::HBox* kwhb = Gtk::manage( new Gtk::HBox () ); + kwhb->pack_start (*keyword); + kwhb->pack_start (*addKW, Gtk::PACK_SHRINK, 2); + kwhb->pack_start (*delKW, Gtk::PACK_SHRINK, 2); + iptc->attach (*keyl, 0, 1, row, row+1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + iptc->attach (*kwhb, 1, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + row++; + iptc->attach (*scrolledWindowkw, 0, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + row++; + + Gtk::HSeparator* hsep2 = Gtk::manage( new Gtk::HSeparator () ); + iptc->attach (*hsep2, 0, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + row++; + + Gtk::Label* catl = Gtk::manage( new Gtk::Label (M("IPTCPANEL_CATEGORY")+":") ); + category = Gtk::manage( new Gtk::ComboBoxEntryText () ); + category->set_size_request (32, -1); + catl->set_tooltip_text (M("IPTCPANEL_CATEGORYHINT")); + category->set_tooltip_text (M("IPTCPANEL_CATEGORYHINT")); + Gtk::Label* scl = Gtk::manage( new Gtk::Label (M("IPTCPANEL_SUPPCATEGORIES")+":") ); + suppCategories = Gtk::manage( new Gtk::ListViewText (1, false, Gtk::SELECTION_MULTIPLE) ); + suppCategories->set_headers_visible (false); + suppCategories->set_size_request(50, 80); + Gtk::ScrolledWindow* scrolledWindowsc = Gtk::manage( new Gtk::ScrolledWindow() ); + scrolledWindowsc->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS); + scrolledWindowsc->add(*suppCategories); + suppCategory = Gtk::manage( new Gtk::ComboBoxEntryText () ); + suppCategory->set_size_request (32, -1); + scl->set_tooltip_text (M("IPTCPANEL_SUPPCATEGORIESHINT")); + suppCategories->set_tooltip_text (M("IPTCPANEL_SUPPCATEGORIESHINT")); + suppCategory->set_tooltip_text (M("IPTCPANEL_SUPPCATEGORIESHINT")); + addSC = Gtk::manage( new Gtk::Button () ); + delSC = Gtk::manage( new Gtk::Button () ); + Gtk::Image* addSCImg = Gtk::manage( new RTImage ("list-add-small.png") ); + Gtk::Image* delSCImg = Gtk::manage( new RTImage ("list-remove-red-small.png") ); + addSC->add (*addSCImg); + delSC->add (*delSCImg); + Gtk::HBox* schb = Gtk::manage( new Gtk::HBox () ); + schb->pack_start (*suppCategory); + schb->pack_start (*addSC, Gtk::PACK_SHRINK, 2); + schb->pack_start (*delSC, Gtk::PACK_SHRINK, 2); + iptc->attach (*catl, 0, 1, row, row+1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + iptc->attach (*category, 1, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + row++; + iptc->attach (*scl, 0, 1, row, row+1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + iptc->attach (*schb, 1, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + row++; + iptc->attach (*scrolledWindowsc, 0, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + row++; + + Gtk::HSeparator* hsep3 = Gtk::manage( new Gtk::HSeparator () ); + iptc->attach (*hsep3, 0, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + row++; + + Gtk::Label* authl = Gtk::manage( new Gtk::Label (M("IPTCPANEL_AUTHOR")+":") ); + author = Gtk::manage( new Gtk::Entry () ); + authl->set_tooltip_text (M("IPTCPANEL_CREDITHINT")); + author->set_tooltip_text (M("IPTCPANEL_CREDITHINT")); + iptc->attach (*authl, 0, 1, row, row+1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + iptc->attach (*author, 1, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + row++; + + Gtk::Label* aupl = Gtk::manage( new Gtk::Label (M("IPTCPANEL_AUTHORSPOSITION")+":") ); + authorPos = Gtk::manage( new Gtk::Entry () ); + aupl->set_tooltip_text (M("IPTCPANEL_AUTHORSPOSITIONHINT")); + authorPos->set_tooltip_text (M("IPTCPANEL_AUTHORSPOSITIONHINT")); + iptc->attach (*aupl, 0, 1, row, row+1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + iptc->attach (*authorPos, 1, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + row++; + + Gtk::Label* credl = Gtk::manage( new Gtk::Label (M("IPTCPANEL_CREDIT")+":") ); + credit = Gtk::manage( new Gtk::Entry () ); + credl->set_tooltip_text (M("IPTCPANEL_CREDITHINT")); + credit->set_tooltip_text (M("IPTCPANEL_CREDITHINT")); + iptc->attach (*credl, 0, 1, row, row+1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + iptc->attach (*credit, 1, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + row++; + + Gtk::Label* sourl = Gtk::manage( new Gtk::Label (M("IPTCPANEL_SOURCE")+":") ); + source = Gtk::manage( new Gtk::Entry () ); + sourl->set_tooltip_text (M("IPTCPANEL_SOURCEHINT")); + source->set_tooltip_text (M("IPTCPANEL_SOURCEHINT")); + iptc->attach (*sourl, 0, 1, row, row+1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + iptc->attach (*source, 1, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + row++; + + Gtk::Label* cprl = Gtk::manage( new Gtk::Label (M("IPTCPANEL_COPYRIGHT")+":") ); + copyright = Gtk::manage( new Gtk::Entry () ); + cprl->set_tooltip_text (M("IPTCPANEL_COPYRIGHTHINT")); + copyright->set_tooltip_text (M("IPTCPANEL_COPYRIGHTHINT")); + iptc->attach (*cprl, 0, 1, row, row+1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + iptc->attach (*copyright, 1, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + row++; + + Gtk::HSeparator* hsep4 = Gtk::manage( new Gtk::HSeparator () ); + iptc->attach (*hsep4, 0, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + row++; + + Gtk::Label* cityl = Gtk::manage( new Gtk::Label (M("IPTCPANEL_CITY")+":") ); + city = Gtk::manage( new Gtk::Entry () ); + cityl->set_tooltip_text (M("IPTCPANEL_CITYHINT")); + city->set_tooltip_text (M("IPTCPANEL_CITYHINT")); + iptc->attach (*cityl, 0, 1, row, row+1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + iptc->attach (*city, 1, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + row++; + + Gtk::Label* provl = Gtk::manage( new Gtk::Label (M("IPTCPANEL_PROVINCE")+":") ); + province = Gtk::manage( new Gtk::Entry () ); + provl->set_tooltip_text (M("IPTCPANEL_PROVINCEHINT")); + province->set_tooltip_text (M("IPTCPANEL_PROVINCEHINT")); + iptc->attach (*provl, 0, 1, row, row+1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + iptc->attach (*province, 1, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + row++; + + Gtk::Label* ctrl = Gtk::manage( new Gtk::Label (M("IPTCPANEL_COUNTRY")+":") ); + country = Gtk::manage( new Gtk::Entry () ); + ctrl->set_tooltip_text (M("IPTCPANEL_COUNTRYHINT")); + country->set_tooltip_text (M("IPTCPANEL_COUNTRYHINT")); + iptc->attach (*ctrl, 0, 1, row, row+1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + iptc->attach (*country, 1, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + row++; + + Gtk::Label* titll = Gtk::manage( new Gtk::Label (M("IPTCPANEL_TITLE")+":") ); + title = Gtk::manage( new Gtk::Entry () ); + titll->set_tooltip_text (M("IPTCPANEL_TITLEHINT")); + title->set_tooltip_text (M("IPTCPANEL_TITLEHINT")); + iptc->attach (*titll, 0, 1, row, row+1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + iptc->attach (*title, 1, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + row++; + + Gtk::Label* dcl = Gtk::manage( new Gtk::Label (M("IPTCPANEL_DATECREATED")+":") ); + dateCreated = Gtk::manage( new Gtk::Entry () ); + dcl->set_tooltip_text (M("IPTCPANEL_DATECREATEDHINT")); + dateCreated->set_tooltip_text (M("IPTCPANEL_DATECREATEDHINT")); + iptc->attach (*dcl, 0, 1, row, row+1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + iptc->attach (*dateCreated, 1, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + row++; + + Gtk::Label* trl = Gtk::manage( new Gtk::Label (M("IPTCPANEL_TRANSREFERENCE")+":") ); + transReference = Gtk::manage( new Gtk::Entry () ); + trl->set_tooltip_text (M("IPTCPANEL_TRANSREFERENCEHINT")); + transReference->set_tooltip_text (M("IPTCPANEL_TRANSREFERENCEHINT")); + iptc->attach (*trl, 0, 1, row, row+1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + iptc->attach (*transReference, 1, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + row++; + + Gtk::ScrolledWindow* scrolledWindow = Gtk::manage( new Gtk::ScrolledWindow() ); + scrolledWindow->set_border_width(2); + scrolledWindow->set_shadow_type(Gtk::SHADOW_NONE); + scrolledWindow->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS); + scrolledWindow->property_window_placement().set_value(Gtk::CORNER_TOP_LEFT); + scrolledWindow->add(*iptc); + + pack_start (*scrolledWindow); + + Gtk::HBox* bbox = Gtk::manage( new Gtk::HBox () ); + + reset = Gtk::manage( new Gtk::Button (M("IPTCPANEL_RESET")) ); + reset->set_image (*Gtk::manage(new RTImage ("gtk-undo-ltr.png", "gtk-undo-rtl.png"))); + bbox->pack_start (*reset); + + file = Gtk::manage( new Gtk::Button (M("IPTCPANEL_EMBEDDED")) ); + file->set_image (*Gtk::manage(new RTImage ("gtk-open.png"))); + bbox->pack_start (*file); + + copy = Gtk::manage( new Gtk::Button () ); + copy->set_image (*Gtk::manage(new RTImage ("edit-copy.png"))); + bbox->pack_start (*copy, Gtk::PACK_SHRINK, 0); + + paste = Gtk::manage( new Gtk::Button () ); + paste->set_image (*Gtk::manage(new RTImage ("edit-paste.png"))); + bbox->pack_start (*paste, Gtk::PACK_SHRINK, 0); + + pack_end (*bbox, Gtk::PACK_SHRINK, 2); + + Gtk::Tooltips* toolTip = Gtk::manage( new Gtk::Tooltips () ); + toolTip->set_tip (*reset, M("IPTCPANEL_RESETHINT")); + toolTip->set_tip (*file, M("IPTCPANEL_EMBEDDEDHINT")); + toolTip->set_tip (*copy, M("IPTCPANEL_COPYHINT")); + toolTip->set_tip (*paste, M("IPTCPANEL_PASTEHINT")); + + reset->signal_clicked().connect( sigc::mem_fun(*this, &IPTCPanel::resetClicked) ); + file->signal_clicked().connect( sigc::mem_fun(*this, &IPTCPanel::fileClicked) ); + copy->signal_clicked().connect( sigc::mem_fun(*this, &IPTCPanel::copyClicked) ); + paste->signal_clicked().connect( sigc::mem_fun(*this, &IPTCPanel::pasteClicked) ); + + + addKW->signal_clicked().connect( sigc::mem_fun(*this, &IPTCPanel::addKeyWord) ); + delKW->signal_clicked().connect( sigc::mem_fun(*this, &IPTCPanel::delKeyWord) ); + addSC->signal_clicked().connect( sigc::mem_fun(*this, &IPTCPanel::addSuppCategory) ); + delSC->signal_clicked().connect( sigc::mem_fun(*this, &IPTCPanel::delSuppCategory) ); + keyword->get_entry()->signal_activate().connect( sigc::mem_fun(*this, &IPTCPanel::addKeyWord) ); + suppCategory->get_entry()->signal_activate().connect( sigc::mem_fun(*this, &IPTCPanel::addSuppCategory) ); + + conns[0] = captionText->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); + conns[1] = captionWriter->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); + conns[2] = headline->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); + conns[3] = instructions->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); + conns[4] = category->get_entry()->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); + conns[5] = author->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); + conns[6] = authorPos->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); + conns[7] = credit->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); + conns[8] = source->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); + conns[9] = copyright->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); + conns[10] = city->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); + conns[11] = province->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); + conns[12] = country->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); + conns[13] = title->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); + conns[14] = dateCreated->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); + conns[15] = transReference->signal_changed().connect( sigc::mem_fun(*this, &IPTCPanel::updateChangeList) ); + + category->get_entry()->set_max_length (3); + keyword->get_entry()->set_max_length (64); + captionWriter->set_max_length (32); + instructions->set_max_length (256); + author->set_max_length (32); + authorPos->set_max_length (32); + credit->set_max_length (32); + source->set_max_length (32); + copyright->set_max_length (128); + city->set_max_length (32); + province->set_max_length (32); + country->set_max_length (64); + title->set_max_length (64); + dateCreated->set_max_length (8); + transReference->set_max_length (32); + + show_all (); +} + +void IPTCPanel::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + changeList.clear(); + if (!pp->iptc.empty()) + changeList = pp->iptc; + else + changeList = embeddedData; + applyChangeList (); + enableListener (); +} + +void IPTCPanel::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->iptc = changeList; +} + +void IPTCPanel::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + defChangeList = defParams->iptc; +} + +void IPTCPanel::setImageData (const ImageMetaData* id) { + + if (id) + embeddedData = id->getIPTCData (); + else + embeddedData.clear (); + + file->set_sensitive (!embeddedData.empty()); +} + +void IPTCPanel::notifyListener () { + + if (listener) + listener->panelChanged (EvIPTC, M("HISTORY_CHANGED")); +} + +void IPTCPanel::addKeyWord () { + + keyword->get_entry()->select_region (0, keyword->get_entry()->get_text().size()); + + for (unsigned int i=0; isize(); i++) + if (keywords->get_text (i) == keyword->get_entry()->get_text()) + return; + + keywords->append_text (keyword->get_entry()->get_text()); + keyword->prepend_text (keyword->get_entry()->get_text()); + std::vector items; + for (Gtk::TreeModel::iterator i = keyword->get_model()->children().begin(); i!=keyword->get_model()->children().end(); i++) { + Glib::ustring s; + i->get_value (0, s); + items.push_back (s); + } + keyword->clear_items (); + for (unsigned int i=0; i<10 && iappend_text (items[i]); + keywords->scroll_to_row (keywords->get_model()->get_path(--keywords->get_model()->children().end())); + + updateChangeList (); +} + +void IPTCPanel::delKeyWord () { + + std::vector selection = keywords->get_selected (); + if (!selection.empty()) { + std::vector keep; + for (unsigned int i=0; isize(); i++) + if (std::find (selection.begin(), selection.end(), i) == selection.end()) + keep.push_back (keywords->get_text (i)); + keywords->clear_items (); + for (unsigned int i=0; iappend_text (keep[i]); + } + + updateChangeList (); +} + +void IPTCPanel::addSuppCategory () { + + for (unsigned int i=0; isize(); i++) + if (suppCategories->get_text (i) == suppCategory->get_entry()->get_text()) + return; + + suppCategories->append_text (suppCategory->get_entry()->get_text()); + suppCategory->prepend_text (suppCategory->get_entry()->get_text()); + std::vector items; + for (Gtk::TreeModel::iterator i = suppCategory->get_model()->children().begin(); i!=suppCategory->get_model()->children().end(); i++) { + Glib::ustring s; + i->get_value (0, s); + items.push_back (s); + } + suppCategory->clear_items (); + for (unsigned int i=0; i<10 && iappend_text (items[i]); + suppCategories->scroll_to_row (suppCategories->get_model()->get_path(--suppCategories->get_model()->children().end())); + suppCategory->get_entry()->select_region (0, suppCategory->get_entry()->get_text().size()); + + updateChangeList (); +} + +void IPTCPanel::delSuppCategory () { + + std::vector selection = suppCategories->get_selected (); + if (!selection.empty()) { + std::vector keep; + for (unsigned int i=0; isize(); i++) + if (std::find (selection.begin(), selection.end(), i) == selection.end()) + keep.push_back (suppCategories->get_text (i)); + suppCategories->clear_items (); + for (unsigned int i=0; iappend_text (keep[i]); + } + + updateChangeList (); +} + +void IPTCPanel::updateChangeList () { + + changeList.clear (); + changeList["Caption" ].push_back (captionText->get_text ()); + changeList["CaptionWriter" ].push_back (captionWriter->get_text ()); + changeList["Headline" ].push_back (headline->get_text ()); + changeList["Instructions" ].push_back (instructions->get_text ()); + + for (unsigned int i=0; isize(); i++) + changeList["Keywords" ].push_back (keywords->get_text (i)); + + changeList["Category" ].push_back (category->get_entry()->get_text ()); + + for (unsigned int i=0; isize(); i++) + changeList["SupplementalCategories"].push_back (suppCategories->get_text (i)); + + changeList["Author" ].push_back (author->get_text ()); + changeList["AuthorsPosition"].push_back (authorPos->get_text ()); + changeList["Credit" ].push_back (credit->get_text ()); + changeList["Source" ].push_back (source->get_text ()); + changeList["Copyright" ].push_back (copyright->get_text ()); + changeList["City" ].push_back (city->get_text ()); + changeList["Province" ].push_back (province->get_text ()); + changeList["Country" ].push_back (country->get_text ()); + changeList["Title" ].push_back (title->get_text ()); + changeList["DateCreated" ].push_back (dateCreated->get_text ()); + changeList["TransReference" ].push_back (transReference->get_text ()); + + notifyListener (); +} + +void IPTCPanel::applyChangeList () { + + for (int i=0; i<16; i++) + conns[i].block (true); + + captionText->set_text (""); + captionWriter->set_text (""); + headline->set_text (""); + instructions->set_text (""); + keywords->clear_items (); + category->get_entry()->set_text (""); + suppCategories->clear_items (); + author->set_text (""); + authorPos->set_text (""); + credit->set_text (""); + source->set_text (""); + copyright->set_text (""); + city->set_text (""); + province->set_text (""); + country->set_text (""); + title->set_text (""); + dateCreated->set_text (""); + transReference->set_text (""); + keyword->get_entry()->set_text (""); + suppCategory->get_entry()->set_text (""); + + for (rtengine::procparams::IPTCPairs::iterator i=changeList.begin(); i!=changeList.end(); i++) { + if (i->first == "Caption" && !i->second.empty()) + captionText->set_text (i->second.at(0)); + else if (i->first == "CaptionWriter" && !i->second.empty()) + captionWriter->set_text (i->second.at(0)); + else if (i->first == "Headline" && !i->second.empty()) + headline->set_text (i->second.at(0)); + else if (i->first == "Instructions" && !i->second.empty()) + instructions->set_text (i->second.at(0)); + else if (i->first == "Keywords") + for (unsigned int j=0; jsecond.size(); j++) + keywords->append_text (i->second.at(j)); + else if (i->first == "Category" && !i->second.empty()) + category->get_entry()->set_text (i->second.at(0)); + else if (i->first == "SupplementalCategories") + for (unsigned int j=0; jsecond.size(); j++) + suppCategories->append_text (i->second.at(j)); + else if (i->first == "Author" && !i->second.empty()) + author->set_text (i->second.at(0)); + else if (i->first == "AuthorsPosition" && !i->second.empty()) + authorPos->set_text (i->second.at(0)); + else if (i->first == "Credit" && !i->second.empty()) + credit->set_text (i->second.at(0)); + else if (i->first == "Source" && !i->second.empty()) + source->set_text (i->second.at(0)); + else if (i->first == "Copyright" && !i->second.empty()) + copyright->set_text (i->second.at(0)); + else if (i->first == "City" && !i->second.empty()) + city->set_text (i->second.at(0)); + else if (i->first == "Province" && !i->second.empty()) + province->set_text (i->second.at(0)); + else if (i->first == "Country" && !i->second.empty()) + country->set_text (i->second.at(0)); + else if (i->first == "Title" && !i->second.empty()) + title->set_text (i->second.at(0)); + else if (i->first == "DateCreated" && !i->second.empty()) + dateCreated->set_text (i->second.at(0)); + else if (i->first == "TransReference" && !i->second.empty()) + transReference->set_text (i->second.at(0)); +} + + for (int i=0; i<16; i++) + conns[i].block (false); +} + +void IPTCPanel::resetClicked () { + + disableListener (); + changeList = defChangeList; + applyChangeList (); + enableListener (); + notifyListener (); +} + +void IPTCPanel::fileClicked () { + + disableListener (); + changeList = embeddedData; + applyChangeList (); + enableListener (); + notifyListener (); +} + +void IPTCPanel::copyClicked () { + + clipboard.setIPTC (changeList); +} + +void IPTCPanel::pasteClicked () { + + disableListener (); + changeList = clipboard.getIPTC (); + applyChangeList (); + enableListener (); + notifyListener (); +} diff --git a/rtgui/iptcpanel.h b/rtgui/iptcpanel.h new file mode 100644 index 000000000..128bf3018 --- /dev/null +++ b/rtgui/iptcpanel.h @@ -0,0 +1,92 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _IPTCPANEL_ +#define _IPTCPANEL_ + +#include +#include "toolpanel.h" +#include "guiutils.h" + +class IPTCPanel : public Gtk::VBox, public ToolPanel { + + private: + rtengine::procparams::IPTCPairs changeList; + rtengine::procparams::IPTCPairs defChangeList; + rtengine::procparams::IPTCPairs embeddedData; + + Gtk::TextView* captionView; + Glib::RefPtr captionText; + Gtk::Entry* captionWriter; + Gtk::Entry* headline; + Gtk::Entry* instructions; + Gtk::ComboBoxEntryText* keyword; + Gtk::ListViewText* keywords; + Gtk::Button* addKW; + Gtk::Button* delKW; + Gtk::ComboBoxEntryText* category; + Gtk::ComboBoxEntryText* suppCategory; + Gtk::ListViewText* suppCategories; + Gtk::Button* addSC; + Gtk::Button* delSC; + + Gtk::Entry* author; + Gtk::Entry* authorPos; + Gtk::Entry* credit; + Gtk::Entry* source; + Gtk::Entry* copyright; + Gtk::Entry* city; + Gtk::Entry* province; + Gtk::Entry* country; + Gtk::Entry* title; + Gtk::Entry* dateCreated; + Gtk::Entry* transReference; + + Gtk::Button* reset; + Gtk::Button* file; + Gtk::Button* copy; + Gtk::Button* paste; + + sigc::connection conns[16]; + + void applyChangeList (); + void updateChangeList (); + + public: + IPTCPanel (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + + void setImageData (const rtengine::ImageMetaData* id); + + void notifyListener (); + + void addKeyWord (); + void delKeyWord (); + void addSuppCategory (); + void delSuppCategory (); + + void resetClicked (); + void fileClicked (); + void copyClicked (); + void pasteClicked (); +}; + +#endif diff --git a/rtgui/labcurve.cc b/rtgui/labcurve.cc new file mode 100644 index 000000000..64a42a968 --- /dev/null +++ b/rtgui/labcurve.cc @@ -0,0 +1,579 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "labcurve.h" +#include +#include "../rtengine/improcfun.h" +#include "edit.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +LCurve::LCurve () : FoldableToolPanel(this, "labcurves", M("TP_LABCURVE_LABEL")) { + + std::vector milestones; + + brightness = Gtk::manage (new Adjuster (M("TP_LABCURVE_BRIGHTNESS"), -100., 100., 1., 0.)); + contrast = Gtk::manage (new Adjuster (M("TP_LABCURVE_CONTRAST"), -100., 100., 1., 0.)); + chromaticity = Gtk::manage (new Adjuster (M("TP_LABCURVE_CHROMATICITY"), -100., 100., 1., 0.)); + chromaticity->set_tooltip_markup(M("TP_LABCURVE_CHROMA_TOOLTIP")); + + pack_start (*brightness); + brightness->show (); + + pack_start (*contrast); + contrast->show (); + + pack_start (*chromaticity); + chromaticity->show (); + + brightness->setAdjusterListener (this); + contrast->setAdjusterListener (this); + chromaticity->setAdjusterListener (this); + + //%%%%%%%%%%%%%%%%%% + Gtk::HSeparator *hsep2 = Gtk::manage (new Gtk::HSeparator()); + hsep2->show (); + pack_start (*hsep2, Gtk::PACK_EXPAND_WIDGET, 4); + + avoidcolorshift = Gtk::manage (new Gtk::CheckButton (M("TP_LABCURVE_AVOIDCOLORSHIFT"))); + avoidcolorshift->set_tooltip_text (M("TP_LABCURVE_AVOIDCOLORSHIFT_TOOLTIP")); + pack_start (*avoidcolorshift, Gtk::PACK_SHRINK, 4); + + lcredsk = Gtk::manage (new Gtk::CheckButton (M("TP_LABCURVE_LCREDSK"))); + lcredsk->set_tooltip_markup (M("TP_LABCURVE_LCREDSK_TIP")); + pack_start (*lcredsk); + + rstprotection = Gtk::manage ( new Adjuster (M("TP_LABCURVE_RSTPROTECTION"), 0., 100., 0.1, 0.) ); + pack_start (*rstprotection); + rstprotection->show (); + + rstprotection->setAdjusterListener (this); + rstprotection->set_tooltip_text (M("TP_LABCURVE_RSTPRO_TOOLTIP")); + + acconn = avoidcolorshift->signal_toggled().connect( sigc::mem_fun(*this, &LCurve::avoidcolorshift_toggled) ); + lcconn = lcredsk->signal_toggled().connect( sigc::mem_fun(*this, &LCurve::lcredsk_toggled) ); + + //%%%%%%%%%%%%%%%%%%% + + Gtk::HSeparator *hsep3 = Gtk::manage (new Gtk::HSeparator()); + hsep3->show (); + pack_start (*hsep3, Gtk::PACK_EXPAND_WIDGET, 4); + + curveEditorG = new CurveEditorGroup (options.lastLabCurvesDir); + curveEditorG->setCurveListener (this); + + lshape = static_cast(curveEditorG->addCurve(CT_Diagonal, "L*")); + lshape->setTooltip(M("TP_LABCURVE_CURVEEDITOR_LL_TOOLTIP")); + lshape->setEditID(EUID_Lab_LCurve, BT_SINGLEPLANE_FLOAT); + + ashape = static_cast(curveEditorG->addCurve(CT_Diagonal, "a*")); + ashape->setEditID(EUID_Lab_aCurve, BT_SINGLEPLANE_FLOAT); + + ashape->setRangeLabels( + M("TP_LABCURVE_CURVEEDITOR_A_RANGE1"), M("TP_LABCURVE_CURVEEDITOR_A_RANGE2"), + M("TP_LABCURVE_CURVEEDITOR_A_RANGE3"), M("TP_LABCURVE_CURVEEDITOR_A_RANGE4") + ); + //from green to magenta + milestones.clear(); + milestones.push_back( GradientMilestone(0., 0., 1., 0.) ); + milestones.push_back( GradientMilestone(1., 1., 0., 1.) ); + ashape->setBottomBarBgGradient(milestones); + ashape->setLeftBarBgGradient(milestones); + milestones.clear(); + + bshape = static_cast(curveEditorG->addCurve(CT_Diagonal, "b*")); + bshape->setRangeLabels( + M("TP_LABCURVE_CURVEEDITOR_B_RANGE1"), M("TP_LABCURVE_CURVEEDITOR_B_RANGE2"), + M("TP_LABCURVE_CURVEEDITOR_B_RANGE3"), M("TP_LABCURVE_CURVEEDITOR_B_RANGE4") + ); + bshape->setEditID(EUID_Lab_bCurve, BT_SINGLEPLANE_FLOAT); + + //from blue to yellow + milestones.clear(); + milestones.push_back( GradientMilestone(0., 0., 0., 1.) ); + milestones.push_back( GradientMilestone(1., 1., 1., 0.) ); + bshape->setBottomBarBgGradient(milestones); + bshape->setLeftBarBgGradient(milestones); + milestones.clear(); + + curveEditorG->newLine(); // ------------------------------------------------ second line + + lhshape = static_cast(curveEditorG->addCurve(CT_Flat, M("TP_LABCURVE_CURVEEDITOR_LH"))); + lhshape->setTooltip(M("TP_LABCURVE_CURVEEDITOR_LH_TOOLTIP")); + lhshape->setCurveColorProvider(this, 4); + lhshape->setEditID(EUID_Lab_LHCurve, BT_SINGLEPLANE_FLOAT); + + + chshape = static_cast(curveEditorG->addCurve(CT_Flat, M("TP_LABCURVE_CURVEEDITOR_CH"))); + chshape->setTooltip(M("TP_LABCURVE_CURVEEDITOR_CH_TOOLTIP")); + chshape->setCurveColorProvider(this, 1); + chshape->setEditID(EUID_Lab_CHCurve, BT_SINGLEPLANE_FLOAT); + + + hhshape = static_cast(curveEditorG->addCurve(CT_Flat, M("TP_LABCURVE_CURVEEDITOR_HH"))); + hhshape->setTooltip(M("TP_LABCURVE_CURVEEDITOR_HH_TOOLTIP")); + hhshape->setCurveColorProvider(this, 5); + hhshape->setEditID(EUID_Lab_HHCurve, BT_SINGLEPLANE_FLOAT); + + curveEditorG->newLine(); // ------------------------------------------------ 3rd line + + ccshape = static_cast(curveEditorG->addCurve(CT_Diagonal, M("TP_LABCURVE_CURVEEDITOR_CC"))); + ccshape->setTooltip(M("TP_LABCURVE_CURVEEDITOR_CC_TOOLTIP")); + ccshape->setEditID(EUID_Lab_CCurve, BT_SINGLEPLANE_FLOAT); + ccshape->setRangeLabels( + M("TP_LABCURVE_CURVEEDITOR_CC_RANGE1"), M("TP_LABCURVE_CURVEEDITOR_CC_RANGE2"), + M("TP_LABCURVE_CURVEEDITOR_CC_RANGE3"), M("TP_LABCURVE_CURVEEDITOR_CC_RANGE4") + ); + + ccshape->setBottomBarColorProvider(this, 2); + ccshape->setLeftBarColorProvider(this, 2); + ccshape->setRangeDefaultMilestones(0.05, 0.2, 0.58); + + lcshape = static_cast(curveEditorG->addCurve(CT_Diagonal, M("TP_LABCURVE_CURVEEDITOR_LC"))); + lcshape->setTooltip(M("TP_LABCURVE_CURVEEDITOR_LC_TOOLTIP")); + lcshape->setEditID(EUID_Lab_LCCurve, BT_SINGLEPLANE_FLOAT); + + // left and bottom bar uses the same caller id because the will display the same content + lcshape->setBottomBarColorProvider(this, 2); + lcshape->setRangeLabels( + M("TP_LABCURVE_CURVEEDITOR_CC_RANGE1"), M("TP_LABCURVE_CURVEEDITOR_CC_RANGE2"), + M("TP_LABCURVE_CURVEEDITOR_CC_RANGE3"), M("TP_LABCURVE_CURVEEDITOR_CC_RANGE4") + ); + lcshape->setRangeDefaultMilestones(0.05, 0.2, 0.58); + + clshape = static_cast(curveEditorG->addCurve(CT_Diagonal, M("TP_LABCURVE_CURVEEDITOR_CL"))); + clshape->setTooltip(M("TP_LABCURVE_CURVEEDITOR_CL_TOOLTIP")); + clshape->setEditID(EUID_Lab_CLCurve, BT_SINGLEPLANE_FLOAT); + + clshape->setLeftBarColorProvider(this, 2); + clshape->setRangeDefaultMilestones(0.25, 0.5, 0.75); + milestones.push_back( GradientMilestone(0., 0., 0., 0.) ); + milestones.push_back( GradientMilestone(1., 1., 1., 1.) ); + + clshape->setBottomBarBgGradient(milestones); + + + // Setting the gradient milestones + + // from black to white + milestones.push_back( GradientMilestone(0., 0., 0., 0.) ); + milestones.push_back( GradientMilestone(1., 1., 1., 1.) ); + lshape->setBottomBarBgGradient(milestones); + lshape->setLeftBarBgGradient(milestones); + milestones.push_back( GradientMilestone(0., 0., 0., 0.) ); + milestones.push_back( GradientMilestone(1., 1., 1., 1.) ); + lcshape->setRangeDefaultMilestones(0.05, 0.2, 0.58); + + lcshape->setBottomBarBgGradient(milestones); + + milestones.at(0).r = milestones.at(0).g = milestones.at(0).b = 0.1; + milestones.at(1).r = milestones.at(1).g = milestones.at(1).b = 0.8; + lcshape->setLeftBarBgGradient(milestones); + + // whole hue range + milestones.clear(); + for (int i=0; i<7; i++) { + float R, G, B; + float x = float(i)*(1.0f/6.0); + Color::hsv2rgb01(x, 0.5f, 0.5f, R, G, B); + milestones.push_back( GradientMilestone(double(x), double(R), double(G), double(B)) ); + } + chshape->setBottomBarBgGradient(milestones); + lhshape->setBottomBarBgGradient(milestones); + hhshape->setBottomBarBgGradient(milestones); + + + // This will add the reset button at the end of the curveType buttons + curveEditorG->curveListComplete(); + + pack_start (*curveEditorG, Gtk::PACK_SHRINK, 4); + +} + +LCurve::~LCurve () { + delete curveEditorG; +} + +void LCurve::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + if (pedited) { + brightness->setEditedState (pedited->labCurve.brightness ? Edited : UnEdited); + contrast->setEditedState (pedited->labCurve.contrast ? Edited : UnEdited); + chromaticity->setEditedState (pedited->labCurve.chromaticity ? Edited : UnEdited); + + //%%%%%%%%%%%%%%%%%%%%%% + rstprotection->setEditedState (pedited->labCurve.rstprotection ? Edited : UnEdited); + avoidcolorshift->set_inconsistent (!pedited->labCurve.avoidcolorshift); + lcredsk->set_inconsistent (!pedited->labCurve.lcredsk); + + //%%%%%%%%%%%%%%%%%%%%%% + + lshape->setUnChanged (!pedited->labCurve.lcurve); + ashape->setUnChanged (!pedited->labCurve.acurve); + bshape->setUnChanged (!pedited->labCurve.bcurve); + ccshape->setUnChanged (!pedited->labCurve.cccurve); + chshape->setUnChanged (!pedited->labCurve.chcurve); + lhshape->setUnChanged (!pedited->labCurve.lhcurve); + hhshape->setUnChanged (!pedited->labCurve.hhcurve); + lcshape->setUnChanged (!pedited->labCurve.lccurve); + clshape->setUnChanged (!pedited->labCurve.clcurve); + } + + brightness->setValue (pp->labCurve.brightness); + contrast->setValue (pp->labCurve.contrast); + chromaticity->setValue (pp->labCurve.chromaticity); + adjusterChanged(chromaticity, pp->labCurve.chromaticity); // To update the GUI sensitiveness + + //%%%%%%%%%%%%%%%%%%%%%% + rstprotection->setValue (pp->labCurve.rstprotection); + + bwtconn.block (true); + acconn.block (true); + lcconn.block (true); + avoidcolorshift->set_active (pp->labCurve.avoidcolorshift); + lcredsk->set_active (pp->labCurve.lcredsk); + + bwtconn.block (false); + acconn.block (false); + lcconn.block (false); + + lastACVal = pp->labCurve.avoidcolorshift; + lastLCVal = pp->labCurve.lcredsk; + //%%%%%%%%%%%%%%%%%%%%%% + + lshape->setCurve (pp->labCurve.lcurve); + ashape->setCurve (pp->labCurve.acurve); + bshape->setCurve (pp->labCurve.bcurve); + ccshape->setCurve (pp->labCurve.cccurve); + chshape->setCurve (pp->labCurve.chcurve); + lhshape->setCurve (pp->labCurve.lhcurve); + hhshape->setCurve (pp->labCurve.hhcurve); + lcshape->setCurve (pp->labCurve.lccurve); + clshape->setCurve (pp->labCurve.clcurve); + + queue_draw(); + + enableListener (); +} + +void LCurve::autoOpenCurve () { + // Open up the first curve if selected + bool active = lshape->openIfNonlinear(); + if (!active) ashape->openIfNonlinear(); + if (!active) bshape->openIfNonlinear(); + if (!active) ccshape->openIfNonlinear(); + if (!active) chshape->openIfNonlinear(); + if (!active) lhshape->openIfNonlinear(); + if (!active) hhshape->openIfNonlinear(); + if (!active) lcshape->openIfNonlinear(); + if (!active) clshape->openIfNonlinear(); +} + +void LCurve::setEditProvider (EditDataProvider *provider) { + lshape->setEditProvider(provider); + ccshape->setEditProvider(provider); + lcshape->setEditProvider(provider); + clshape->setEditProvider(provider); + lhshape->setEditProvider(provider); + chshape->setEditProvider(provider); + hhshape->setEditProvider(provider); + ashape->setEditProvider(provider); + bshape->setEditProvider(provider); + +} + + +void LCurve::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->labCurve.brightness = brightness->getValue (); + pp->labCurve.contrast = (int)contrast->getValue (); + pp->labCurve.chromaticity = (int)chromaticity->getValue (); + + //%%%%%%%%%%%%%%%%%%%%%% + pp->labCurve.avoidcolorshift = avoidcolorshift->get_active (); + pp->labCurve.lcredsk = lcredsk->get_active (); + + pp->labCurve.rstprotection = rstprotection->getValue (); + //%%%%%%%%%%%%%%%%%%%%%% + + pp->labCurve.lcurve = lshape->getCurve (); + pp->labCurve.acurve = ashape->getCurve (); + pp->labCurve.bcurve = bshape->getCurve (); + pp->labCurve.cccurve = ccshape->getCurve (); + pp->labCurve.chcurve = chshape->getCurve (); + pp->labCurve.lhcurve = lhshape->getCurve (); + pp->labCurve.hhcurve = hhshape->getCurve (); + pp->labCurve.lccurve = lcshape->getCurve (); + pp->labCurve.clcurve = clshape->getCurve (); + + if (pedited) { + pedited->labCurve.brightness = brightness->getEditedState (); + pedited->labCurve.contrast = contrast->getEditedState (); + pedited->labCurve.chromaticity = chromaticity->getEditedState (); + + //%%%%%%%%%%%%%%%%%%%%%% + pedited->labCurve.avoidcolorshift = !avoidcolorshift->get_inconsistent(); + pedited->labCurve.lcredsk = !lcredsk->get_inconsistent(); + + pedited->labCurve.rstprotection = rstprotection->getEditedState (); + //%%%%%%%%%%%%%%%%%%%%%% + + pedited->labCurve.lcurve = !lshape->isUnChanged (); + pedited->labCurve.acurve = !ashape->isUnChanged (); + pedited->labCurve.bcurve = !bshape->isUnChanged (); + pedited->labCurve.cccurve = !ccshape->isUnChanged (); + pedited->labCurve.chcurve = !chshape->isUnChanged (); + pedited->labCurve.lhcurve = !lhshape->isUnChanged (); + pedited->labCurve.hhcurve = !hhshape->isUnChanged (); + pedited->labCurve.lccurve = !lcshape->isUnChanged (); + pedited->labCurve.clcurve = !clshape->isUnChanged (); + } +} + +void LCurve::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + brightness->setDefault (defParams->labCurve.brightness); + contrast->setDefault (defParams->labCurve.contrast); + chromaticity->setDefault (defParams->labCurve.chromaticity); + rstprotection->setDefault (defParams->labCurve.rstprotection); + + if (pedited) { + brightness->setDefaultEditedState (pedited->labCurve.brightness ? Edited : UnEdited); + contrast->setDefaultEditedState (pedited->labCurve.contrast ? Edited : UnEdited); + chromaticity->setDefaultEditedState (pedited->labCurve.chromaticity ? Edited : UnEdited); + rstprotection->setDefaultEditedState (pedited->labCurve.rstprotection ? Edited : UnEdited); + + } + else { + brightness->setDefaultEditedState (Irrelevant); + contrast->setDefaultEditedState (Irrelevant); + chromaticity->setDefaultEditedState (Irrelevant); + rstprotection->setDefaultEditedState (Irrelevant); + } +} + +//%%%%%%%%%%%%%%%%%%%%%% +//Color shift control changed +void LCurve::avoidcolorshift_toggled () { + + if (batchMode) { + if (avoidcolorshift->get_inconsistent()) { + avoidcolorshift->set_inconsistent (false); + acconn.block (true); + avoidcolorshift->set_active (false); + acconn.block (false); + } + else if (lastACVal) + avoidcolorshift->set_inconsistent (true); + + lastACVal = avoidcolorshift->get_active (); + } + + if (listener) { + if (avoidcolorshift->get_active ()) + listener->panelChanged (EvLAvoidColorShift, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvLAvoidColorShift, M("GENERAL_DISABLED")); + } +} + +void LCurve::lcredsk_toggled () { + + if (batchMode) { + if (lcredsk->get_inconsistent()) { + lcredsk->set_inconsistent (false); + lcconn.block (true); + lcredsk->set_active (false); + lcconn.block (false); + } + else if (lastLCVal) + lcredsk->set_inconsistent (true); + + lastLCVal = lcredsk->get_active (); + } + else { + lcshape->refresh(); + } + + if (listener) { + if (lcredsk->get_active ()) + listener->panelChanged (EvLLCredsk, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvLLCredsk, M("GENERAL_DISABLED")); + } +} + +//%%%%%%%%%%%%%%%%%%%%%% + +/* + * Curve listener + * + * If more than one curve has been added, the curve listener is automatically + * set to 'multi=true', and send a pointer of the modified curve in a parameter + */ +void LCurve::curveChanged (CurveEditor* ce) { + + if (listener) { + if (ce == lshape) + listener->panelChanged (EvLLCurve, M("HISTORY_CUSTOMCURVE")); + if (ce == ashape) + listener->panelChanged (EvLaCurve, M("HISTORY_CUSTOMCURVE")); + if (ce == bshape) + listener->panelChanged (EvLbCurve, M("HISTORY_CUSTOMCURVE")); + if (ce == ccshape) + listener->panelChanged (EvLCCCurve, M("HISTORY_CUSTOMCURVE")); + if (ce == chshape) + listener->panelChanged (EvLCHCurve, M("HISTORY_CUSTOMCURVE")); + if (ce == lhshape) + listener->panelChanged (EvLLHCurve, M("HISTORY_CUSTOMCURVE")); + if (ce == hhshape) + listener->panelChanged (EvLHHCurve, M("HISTORY_CUSTOMCURVE")); + if (ce == lcshape) + listener->panelChanged (EvLLCCurve, M("HISTORY_CUSTOMCURVE")); + if (ce == clshape) + listener->panelChanged (EvLCLCurve, M("HISTORY_CUSTOMCURVE")); + } +} + +void LCurve::adjusterChanged (Adjuster* a, double newval) { + + Glib::ustring costr; + if (a==brightness) + costr = Glib::ustring::format (std::setw(3), std::fixed, std::setprecision(2), a->getValue()); + else if (a==rstprotection) + costr = Glib::ustring::format (std::setw(3), std::fixed, std::setprecision(1), a->getValue()); + else + costr = Glib::ustring::format ((int)a->getValue()); + + if (a==brightness) { + if (listener) listener->panelChanged (EvLBrightness, costr); + } + else if (a==contrast) { + if (listener) listener->panelChanged (EvLContrast, costr); + } + else if (a==rstprotection) { + if (listener) listener->panelChanged (EvLRSTProtection, costr); + } + else if (a==chromaticity) { + if (multiImage) { + //if chromaticity==-100 (lowest value), we enter the B&W mode and avoid color shift and rstprotection has no effect + rstprotection->set_sensitive( true ); + avoidcolorshift->set_sensitive( true ); + lcredsk->set_sensitive( true ); + } + else { + //if chromaticity==-100 (lowest value), we enter the B&W mode and avoid color shift and rstprotection has no effect + rstprotection->set_sensitive( int(newval)> -100 );//no reason for grey rstprotection + avoidcolorshift->set_sensitive( int(newval)> -100 ); + lcredsk->set_sensitive( int(newval)> -100 ); + } + if (listener) listener->panelChanged (EvLSaturation, costr); + } +} + +void LCurve::colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller *caller) { + + float R, G, B; + + if (elemType==ColorCaller::CCET_VERTICAL_BAR) + valY = 0.5; + + if (callerId == 1) { // ch - main curve + + Color::hsv2rgb01(float(valX), float(valY), 0.5f, R, G, B); + } + else if (callerId == 2) { // cc - bottom bar + + float value = (1.f - 0.7f) * float(valX) + 0.7f; + // whole hue range + // Y axis / from 0.15 up to 0.75 (arbitrary values; was 0.45 before) + Color::hsv2rgb01(float(valY), float(valX), value, R, G, B); + } + else if (callerId == 3) { // lc - bottom bar + + float value = (1.f - 0.7f) * float(valX) + 0.7f; + if (lcredsk->get_active()) { + // skin range + // -0.1 rad < Hue < 1.6 rad + // Y axis / from 0.92 up to 0.14056 + float hue = (1.14056f - 0.92f) * float(valY) + 0.92f; + if (hue > 1.0f) hue -= 1.0f; + // Y axis / from 0.15 up to 0.75 (arbitrary values; was 0.45 before) + Color::hsv2rgb01(hue, float(valX), value, R, G, B); + } + else { + // whole hue range + // Y axis / from 0.15 up to 0.75 (arbitrary values; was 0.45 before) + Color::hsv2rgb01(float(valY), float(valX), value, R, G, B); + } + } + else if (callerId == 4) { // LH - bottom bar + Color::hsv2rgb01(float(valX), 0.5f, float(valY), R, G, B); + } + else if (callerId == 5) { // HH - bottom bar + float h = float((valY - 0.5) * 0.3 + valX); + if (h > 1.0f) + h -= 1.0f; + else if (h < 0.0f) + h += 1.0f; + Color::hsv2rgb01(h, 0.5f, 0.5f, R, G, B); + } + caller->ccRed = double(R); + caller->ccGreen = double(G); + caller->ccBlue = double(B); +} + +void LCurve::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + brightness->showEditedCB (); + contrast->showEditedCB (); + chromaticity->showEditedCB (); + rstprotection->showEditedCB (); + + curveEditorG->setBatchMode (batchMode); + lcshape->setBottomBarColorProvider(NULL, -1); + lcshape->setLeftBarColorProvider(NULL, -1); +} + + +void LCurve::updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve, LUTu & histCCurve,/* LUTu & histCLurve, LUTu & histLLCurve,*/ LUTu & histLCAM, LUTu & histCCAM, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma){ + + lshape->updateBackgroundHistogram (histLCurve); + ccshape->updateBackgroundHistogram (histCCurve); +// clshape->updateBackgroundHistogram (histCLurve); +// lcshape->updateBackgroundHistogram (histLLCurve); + +} + +void LCurve::setAdjusterBehavior (bool bradd, bool contradd, bool satadd) { + + brightness->setAddMode(bradd); + contrast->setAddMode(contradd); + chromaticity->setAddMode(satadd); +} + +void LCurve::trimValues (rtengine::procparams::ProcParams* pp) { + + brightness->trimValue(pp->labCurve.brightness); + contrast->trimValue(pp->labCurve.contrast); + chromaticity->trimValue(pp->labCurve.chromaticity); +} diff --git a/rtgui/labcurve.h b/rtgui/labcurve.h new file mode 100644 index 000000000..573a6b587 --- /dev/null +++ b/rtgui/labcurve.h @@ -0,0 +1,81 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _LABCURVE_H_ +#define _LABCURVE_H_ + +#include +#include "adjuster.h" +#include "toolpanel.h" +#include "curveeditor.h" +#include "curveeditorgroup.h" +#include "colorprovider.h" + +class LCurve : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public CurveListener, public ColorProvider { + + protected: + CurveEditorGroup* curveEditorG; + Adjuster* brightness; + Adjuster* contrast; + Adjuster* chromaticity; + DiagonalCurveEditor* lshape; + DiagonalCurveEditor* ashape; + DiagonalCurveEditor* bshape; + DiagonalCurveEditor* ccshape; + DiagonalCurveEditor* lcshape; + FlatCurveEditor* chshape; + FlatCurveEditor* lhshape; + FlatCurveEditor* hhshape; + + DiagonalCurveEditor* clshape; + + //%%%%%%%%%%%%%%%% + Gtk::CheckButton* avoidcolorshift; + Gtk::CheckButton* lcredsk; + + Adjuster* rstprotection; + sigc::connection bwtconn, acconn, lcconn; + bool lastACVal, lastLCVal; + + //%%%%%%%%%%%%%%%% + + public: + + LCurve (); + ~LCurve (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + void autoOpenCurve (); + void setEditProvider (EditDataProvider *provider); + void setAdjusterBehavior (bool bradd, bool contradd, bool satadd); + void trimValues (rtengine::procparams::ProcParams* pp); + + void curveChanged (CurveEditor* ce); + void adjusterChanged (Adjuster* a, double newval); + void avoidcolorshift_toggled (); + void lcredsk_toggled(); + + void updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve, LUTu & histCCurve,/* LUTu & histCLurve, LUTu & histLLCurve,*/ LUTu & histLCAM, LUTu & histCCAM, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma); + + virtual void colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller* caller); +}; + +#endif diff --git a/rtgui/lensgeom.cc b/rtgui/lensgeom.cc new file mode 100644 index 000000000..168044197 --- /dev/null +++ b/rtgui/lensgeom.cc @@ -0,0 +1,105 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "lensgeom.h" +#include "guiutils.h" +#include "rtimage.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +LensGeometry::LensGeometry () : FoldableToolPanel(this, "lensgeom", M("TP_LENSGEOM_LABEL")), rlistener(NULL) { + + fill = Gtk::manage (new Gtk::CheckButton (M("TP_LENSGEOM_FILL"))); + pack_start (*fill); + + autoCrop = Gtk::manage (new Gtk::Button (M("TP_LENSGEOM_AUTOCROP"))); + autoCrop->set_image (*Gtk::manage (new RTImage ("crop-auto.png"))); + pack_start (*autoCrop, Gtk::PACK_SHRINK, 2); + + packBox = Gtk::manage (new ToolParamBlock ()); + pack_start (*packBox); + + autoCrop->signal_pressed().connect( sigc::mem_fun(*this, &LensGeometry::autoCropPressed) ); + fillConn = fill->signal_toggled().connect( sigc::mem_fun(*this, &LensGeometry::fillPressed) ); + + fill->set_active (true); + show_all (); +} + +void LensGeometry::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + if (pedited) + fill->set_inconsistent (!pedited->commonTrans.autofill); + + fillConn.block (true); + fill->set_active (pp->commonTrans.autofill); + fillConn.block (false); + autoCrop->set_sensitive (!pp->commonTrans.autofill); + + lastFill = pp->commonTrans.autofill; + + enableListener (); +} + +void LensGeometry::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->commonTrans.autofill = fill->get_active (); + + if (pedited) + pedited->commonTrans.autofill = !fill->get_inconsistent(); +} + +void LensGeometry::autoCropPressed () { + + if (rlistener) + rlistener->autoCropRequested (); +} + +void LensGeometry::fillPressed () { + + if (batchMode) { + if (fill->get_inconsistent()) { + fill->set_inconsistent (false); + fillConn.block (true); + fill->set_active (false); + fillConn.block (false); + } + else if (lastFill) + fill->set_inconsistent (true); + + lastFill = fill->get_active (); + } + else + autoCrop->set_sensitive (!fill->get_active()); + + if (listener) { + if (fill->get_active ()) + listener->panelChanged (EvTransAutoFill, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvTransAutoFill, M("GENERAL_DISABLED")); + } +} + +void LensGeometry::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + removeIfThere (this, autoCrop); +} diff --git a/rtgui/lensgeom.h b/rtgui/lensgeom.h new file mode 100644 index 000000000..84d64e816 --- /dev/null +++ b/rtgui/lensgeom.h @@ -0,0 +1,51 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _LENSGEOM_H_ +#define _LENSGEOM_H_ + +#include +#include "toolpanel.h" +#include "lensgeomlistener.h" + +class LensGeometry : public ToolParamBlock, public FoldableToolPanel { + + protected: + Gtk::Button* autoCrop; + LensGeomListener* rlistener; + Gtk::CheckButton* fill; + bool lastFill; + sigc::connection fillConn; + ToolParamBlock* packBox; + + public: + + LensGeometry (); + + Gtk::Box* getPackBox () { return packBox; } + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + + void fillPressed (); + void autoCropPressed (); + void setLensGeomListener (LensGeomListener* l) { rlistener = l; } +}; + +#endif diff --git a/rtgui/lensgeomlistener.h b/rtgui/lensgeomlistener.h new file mode 100644 index 000000000..6b7f79f98 --- /dev/null +++ b/rtgui/lensgeomlistener.h @@ -0,0 +1,30 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _LENSGEOMLISTENER_H_ +#define _LENSGEOMLISTENER_H_ + +class LensGeomListener { + + public: + virtual void straightenRequested ()=0; + virtual void autoCropRequested ()=0; + virtual double autoDistorRequested ()=0; +}; + +#endif diff --git a/rtgui/lensprofile.cc b/rtgui/lensprofile.cc new file mode 100644 index 000000000..703db4afc --- /dev/null +++ b/rtgui/lensprofile.cc @@ -0,0 +1,178 @@ +/* +* This file is part of RawTherapee. +* +* Copyright (c) 2012 Oliver Duis +* +* 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 "lensprofile.h" +#include "guiutils.h" +#include "../rtengine/safegtk.h" +#include "../rtengine/lcp.h" +#include +#include "rtimage.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +LensProfilePanel::LensProfilePanel () : FoldableToolPanel(this, "lensprof", M("TP_LENSPROFILE_LABEL")) +{ + hbLCPFile = Gtk::manage(new Gtk::HBox()); + + lLCPFileHead = Gtk::manage(new Gtk::Label(M("GENERAL_FILE"))); + hbLCPFile->pack_start(*lLCPFileHead, Gtk::PACK_SHRINK, 4); + + fcbLCPFile = Gtk::manage(new MyFileChooserButton(M("TP_LENSPROFILE_LABEL"), Gtk::FILE_CHOOSER_ACTION_OPEN)); + + Gtk::FileFilter filterLCP; + filterLCP.set_name(M("FILECHOOSER_FILTER_LCP")); + filterLCP.add_pattern("*.lcp"); + filterLCP.add_pattern("*.LCP"); + fcbLCPFile->add_filter(filterLCP); + + Glib::ustring defDir=lcpStore->getDefaultCommonDirectory(); + if (!defDir.empty()) { +#ifdef WIN32 + fcbLCPFile->set_show_hidden(true); // ProgramData is hidden on Windows +#endif + fcbLCPFile->set_current_folder(defDir); + } + + 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"))); + pack_start (*ckbUseDist, Gtk::PACK_SHRINK, 4); + ckbUseVign = Gtk::manage (new Gtk::CheckButton (M("TP_LENSPROFILE_USEVIGN"))); + pack_start (*ckbUseVign, Gtk::PACK_SHRINK, 4); + 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); + 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) ); + + allowFocusDep=true; +} + +void LensProfilePanel::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited) +{ + disableListener (); + + if (!pp->lensProf.lcpFile.empty() && lcpStore->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_filename(""); + fcbLCPFile->set_current_folder(lastFolder); + } + updateDisabled(false); + } + + ckbUseDist->set_active (pp->lensProf.useDist); + ckbUseVign->set_active (pp->lensProf.useVign && isRaw); + ckbUseCA->set_active (pp->lensProf.useCA && isRaw); + + lcpFileChanged=useDistChanged=useVignChanged=useCAChanged=false; + + enableListener (); +} + +void LensProfilePanel::setRawMeta(bool raw, const rtengine::ImageMetaData* pMeta) { + if (!raw || pMeta->getFocusDist()<=0) { + disableListener(); + + // CA is very focus layer dependend, otherwise it might even worsen things + allowFocusDep=false; + ckbUseCA->set_active(false); + ckbUseCA->set_sensitive(false); + + enableListener(); + } + isRaw=raw; +} + +void LensProfilePanel::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pedited) +{ + if (lcpStore->isValidLCPFileName(fcbLCPFile->get_filename())) + pp->lensProf.lcpFile = fcbLCPFile->get_filename(); + else + pp->lensProf.lcpFile = ""; + + pp->lensProf.useDist = ckbUseDist->get_active(); + pp->lensProf.useVign = ckbUseVign->get_active(); + pp->lensProf.useCA = ckbUseCA->get_active(); + + if (pedited) { + pedited->lensProf.lcpFile = lcpFileChanged; + pedited->lensProf.useDist = useDistChanged; + pedited->lensProf.useVign = useVignChanged; + pedited->lensProf.useCA = useCAChanged; + } +} + +void LensProfilePanel::onLCPFileChanged() +{ + lcpFileChanged=true; + updateDisabled(lcpStore->isValidLCPFileName(fcbLCPFile->get_filename())); + + if (listener) + 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; + if (listener) listener->panelChanged (EvLCPUseDist, ckbUseDist->get_active() ? M("GENERAL_ENABLED") : M("GENERAL_DISABLED")); +} +void LensProfilePanel::onUseVignChanged() +{ + useVignChanged=true; + if (listener) listener->panelChanged (EvLCPUseVign, ckbUseVign->get_active() ? M("GENERAL_ENABLED") : M("GENERAL_DISABLED")); +} +void LensProfilePanel::onUseCAChanged() +{ + useCAChanged=true; + if (listener) listener->panelChanged (EvLCPUseCA, ckbUseCA->get_active() ? M("GENERAL_ENABLED") : M("GENERAL_DISABLED")); +} + +void LensProfilePanel::updateDisabled(bool enable) { + ckbUseDist->set_sensitive(enable); + ckbUseVign->set_sensitive(enable && isRaw); + ckbUseCA->set_sensitive(enable && allowFocusDep); +} diff --git a/rtgui/lensprofile.h b/rtgui/lensprofile.h new file mode 100644 index 000000000..8aedb1aa6 --- /dev/null +++ b/rtgui/lensprofile.h @@ -0,0 +1,56 @@ +/* +* This file is part of RawTherapee. +* +* Copyright (c) 2012 Oliver Duis +* +* 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 _LENSPROFILE_H_ +#define _LENSPROFILE_H_ + +#include +#include "toolpanel.h" +#include "guiutils.h" + +class LensProfilePanel : public ToolParamBlock, public FoldableToolPanel { + +protected: + + MyFileChooserButton *fcbLCPFile; + Gtk::CheckButton *ckbUseDist, *ckbUseVign, *ckbUseCA; + Gtk::HBox *hbLCPFile; + Gtk::Button *btnReset; + Gtk::Label *lLCPFileHead; + bool lcpFileChanged,useDistChanged,useVignChanged,useCAChanged; + sigc::connection conLCPFile, conUseDist, conUseVign, conUseCA; + void updateDisabled(bool enable); + bool allowFocusDep; + bool isRaw; + +public: + + LensProfilePanel (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setRawMeta (bool raw, const rtengine::ImageMetaData* pMeta); + + void onLCPFileChanged (); + void onLCPFileReset (); + void onUseDistChanged(); + void onUseVignChanged(); + void onUseCAChanged(); +}; + +#endif diff --git a/rtgui/lwbutton.cc b/rtgui/lwbutton.cc new file mode 100644 index 000000000..ea4bf182f --- /dev/null +++ b/rtgui/lwbutton.cc @@ -0,0 +1,191 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "lwbutton.h" +#include "guiutils.h" + +LWButton::LWButton (Cairo::RefPtr i, int aCode, void* aData, Alignment ha, Alignment va, Glib::ustring tooltip) + : halign(ha), valign(va), icon(i), state(Normal), listener(NULL), actionCode(aCode), actionData(aData), toolTip(tooltip) { + + if (i) { + w = i->get_width () + 2; + h = i->get_height () + 2; + } + else + w = h = 2; +} + +void LWButton::getSize (int& minw, int& minh) { + + minw = w; + minh = h; +} + +void LWButton::setPosition (int x, int y) { + + xpos = x; + ypos = y; +} + +void LWButton::getPosition (int& x, int& y) { + + x = xpos; + y = ypos; +} + +void LWButton::setIcon (Cairo::RefPtr i) { + + icon = i; + if (i) { + w = i->get_width () + 2; + h = i->get_height () + 2; + } + else + w = h = 2; +} + +Cairo::RefPtr LWButton::getIcon () { + + return icon; +} + +void LWButton::setColors (const Gdk::Color& bg, const Gdk::Color& fg) { + + bgr = bg.get_red_p (); + bgg = bg.get_green_p (); + bgb = bg.get_blue_p (); + fgr = fg.get_red_p (); + fgg = fg.get_green_p (); + fgb = fg.get_blue_p (); +} + +bool LWButton::inside (int x, int y) { + + return x>xpos && xypos && yredrawNeeded (this); + return true; + } + return in; +} + +bool LWButton::pressNotify (int x, int y) { + + bool in = inside (x, y); + State nstate = state; + if (in && (state==Normal || state==Over || state==Pressed_Out)) + nstate = Pressed_In; + else if (!in && state==Pressed_In) + nstate = Normal; + + if (state!=nstate) { + state = nstate; + if (listener) + listener->redrawNeeded (this); + return true; + } + return in; +} + +bool LWButton::releaseNotify (int x, int y) { + + bool in = inside (x, y); + State nstate = state; + bool action = false; + if (in && (state==Pressed_In || state==Pressed_Out)) { + nstate = Over; + action = true; + } + else + nstate = Normal; + + bool ret = action; + if (state!=nstate) { + state = nstate; + if (listener) + listener->redrawNeeded (this); + ret = true; + } + + if (action && listener) + listener->buttonPressed (this, actionCode, actionData); + return ret; +} + +void LWButton::redraw (Cairo::RefPtr context) { + + GThreadLock lock; // All GUI acces from idle_add callbacks or separate thread HAVE to be protected + context->set_line_width (1.0); + context->set_antialias (Cairo::ANTIALIAS_SUBPIXEL); + context->rectangle (xpos+0.5, ypos+0.5, w-1.0, h-1.0); + if (state==Pressed_In) + context->set_source_rgb (fgr, fgg, fgb); + else + context->set_source_rgba (bgr, bgg, bgb, 0); + context->fill_preserve (); + if (state==Over) + context->set_source_rgb (fgr, fgg, fgb); + else + context->set_source_rgba (bgr, bgg, bgb, 0); + context->stroke (); + int dilat = 1; + if (state==Pressed_In) + dilat++; + + if (icon) { + context->set_source (icon, xpos+dilat, ypos+dilat); + context->paint (); + } +} + +void LWButton::getAlignment (Alignment& ha, Alignment& va) { + + ha = halign; + va = valign; +} + +Glib::ustring LWButton::getToolTip (int x, int y) { + + if (inside (x, y)) + return toolTip; + else + return ""; +} + +void LWButton::setToolTip (const Glib::ustring& tooltip) { + + toolTip = tooltip; +} + diff --git a/rtgui/lwbutton.h b/rtgui/lwbutton.h new file mode 100644 index 000000000..b50478abd --- /dev/null +++ b/rtgui/lwbutton.h @@ -0,0 +1,75 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _LWBUTTON_ +#define _LWBUTTON_ + +#include + +class LWButton; +class LWButtonListener { + + public: + virtual ~LWButtonListener () {} + virtual void buttonPressed (LWButton* button, int actionCode, void* actionData) {} + virtual void redrawNeeded (LWButton* button) {} +}; + +class LWButton { + + public: + enum Alignment {Left, Right, Top, Bottom, Center}; + enum State { Normal, Over, Pressed_In, Pressed_Out}; + + private: + int xpos, ypos, w, h; + Alignment halign, valign; + Cairo::RefPtr icon; + double bgr, bgg, bgb; + double fgr, fgg, fgb; + State state; + LWButtonListener* listener; + int actionCode; + void* actionData; + Glib::ustring toolTip; + + public: + LWButton (Cairo::RefPtr i, int aCode, void* aData, Alignment ha=Left, Alignment va=Center, Glib::ustring tooltip=""); + + void getSize (int& minw, int& minh); + void getAlignment (Alignment& ha, Alignment& va); + void setPosition (int x, int y); + void getPosition (int& x, int& y); + bool inside (int x, int y); + void setIcon (Cairo::RefPtr i); + Cairo::RefPtr getIcon (); + void setColors (const Gdk::Color& bg, const Gdk::Color& fg); + void setToolTip (const Glib::ustring& tooltip); + + bool motionNotify (int x, int y); + bool pressNotify (int x, int y); + bool releaseNotify (int x, int y); + + Glib::ustring getToolTip (int x, int y); + + void setButtonListener (LWButtonListener* bl) { listener = bl; } + + void redraw (Cairo::RefPtr context); +}; + +#endif diff --git a/rtgui/lwbuttonset.cc b/rtgui/lwbuttonset.cc new file mode 100644 index 000000000..fea24d41c --- /dev/null +++ b/rtgui/lwbuttonset.cc @@ -0,0 +1,169 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "lwbuttonset.h" + +LWButtonSet::LWButtonSet () : aw(0), ah(0) { +} + +LWButtonSet::~LWButtonSet () { + + for (size_t i=0; igetSize (bw, bh); + w+= bw; + if (bh>h) + h = bh; + } +} + +void LWButtonSet::arrangeButtons (int x, int y, int w, int h) { + + int mw, mh; + getMinimalDimensions (mw, mh); + + if (w<0) + w = mw; + if (h<0) + h = mh; + + int begx = x; + int endx = x+w-1; + for (size_t i=0; igetSize (bw, bh); + buttons[i]->getAlignment (halign, valign); + if (halign == LWButton::Left) { + bx = begx; + begx += bw; + } + else if (halign == LWButton::Right) { + bx = endx-bw; + endx -= bw; + } + if (valign == LWButton::Top) + by = y; + else if (valign == LWButton::Bottom) + by = y+h-bh-1; + else if (valign == LWButton::Center) + by = y+(h-bh)/2; + buttons[i]->setPosition (bx, by); + } + aw = w; + ah = h; + ax = x; + ay = y; +} + +void LWButtonSet::move (int nx, int ny) { + + for (size_t i=0; igetPosition (x, y); + buttons[i]->setPosition (x+nx-ax, y+ny-ay); + } + + ax = nx; + ay = ny; +} + +void LWButtonSet::redraw (Cairo::RefPtr context) { + + for (size_t i=0; iredraw (context); +} + +bool LWButtonSet::motionNotify (int x, int y) { + + bool res = false; + for (size_t i=0; imotionNotify (x, y); + res = res || handled; + } + + return res; +} + +bool LWButtonSet::pressNotify (int x, int y) { + + bool res = false; + for (size_t i=0; ipressNotify (x, y); + res = res || handled; + } + return res; +} + +bool LWButtonSet::releaseNotify (int x, int y) { + + bool res = false; + for (size_t i=0; ireleaseNotify (x, y); + res = res || handled; + } + return res; +} + +bool LWButtonSet::inside (int x, int y) { + + for (size_t i=0; iinside (x, y)) + return true; + return false; +} + +void LWButtonSet::setButtonListener (LWButtonListener* bl) { + + for (size_t i=0; isetButtonListener (bl); +} + +void LWButtonSet::getAllocatedDimensions (int& w, int& h) { + + w = aw; + h = ah; +} + +void LWButtonSet::setColors (const Gdk::Color& bg, const Gdk::Color& fg) { + + for (size_t i=0; isetColors (bg, fg); +} + +Glib::ustring LWButtonSet::getToolTip (int x, int y) { + + for (size_t i=0; igetToolTip (x, y); + if (ttip!="") + return ttip; + } + return ""; +} diff --git a/rtgui/lwbuttonset.h b/rtgui/lwbuttonset.h new file mode 100644 index 000000000..651304c83 --- /dev/null +++ b/rtgui/lwbuttonset.h @@ -0,0 +1,53 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _LWBUTTONSET_ +#define _LWBUTTONSET_ + +#include +#include "lwbutton.h" +#include + +class LWButtonSet { + + protected: + std::vector buttons; + int aw, ah, ax, ay; + public: + LWButtonSet (); + ~LWButtonSet (); + + void add (LWButton* b); + + void getMinimalDimensions (int& w, int& h); + void getAllocatedDimensions (int& w, int& h); + void arrangeButtons (int x, int y, int w, int h); + void setColors (const Gdk::Color& bg, const Gdk::Color& fg); + bool motionNotify (int x, int y); + bool pressNotify (int x, int y); + bool releaseNotify (int x, int y); + void move (int nx, int ny); + bool inside (int x, int y); + + Glib::ustring getToolTip (int x, int y); + + void setButtonListener (LWButtonListener* bl); + void redraw (Cairo::RefPtr context); +}; + +#endif diff --git a/rtgui/main.cc b/rtgui/main.cc new file mode 100644 index 000000000..b8daf5af5 --- /dev/null +++ b/rtgui/main.cc @@ -0,0 +1,702 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +// generated 2004/6/3 19:15:32 CEST by gabor@darkstar.(none) +// using glademm V2.5.0 +// +// newer (non customized) versions of this file go to raw.cc_new + +// This file is for your program, I won't touch it again! + +#ifdef __GNUC__ + #if defined(__FAST_MATH__) + #error Using the -ffast-math CFLAG is known to lead to problems. Disable it to compile RawTherapee. + #endif +#endif + +#include "config.h" +#include +#include +#include +#include +#include "rtwindow.h" +#include +#include +#include +#include "options.h" +#include "soundman.h" +#include "rtimage.h" +#include "version.h" +#include "extprog.h" + +#ifndef WIN32 +#include +#include +#include +#include +#else +#include +#include "conio.h" +#endif + +#include "../rtengine/safegtk.h" + +extern Options options; + +// stores path to data files +Glib::ustring argv0; +Glib::ustring creditsPath; +Glib::ustring licensePath; +Glib::ustring argv1; +bool simpleEditor; +Glib::Thread* mainThread; + + +// This recursive mutex will be used by gdk_threads_enter/leave instead of a simple mutex +#ifdef WIN32 +static Glib::RecMutex myGdkRecMutex; +#else +static Glib::Threads::RecMutex myGdkRecMutex; +#endif + +static void myGdkLockEnter() { myGdkRecMutex.lock(); } +static void myGdkLockLeave() { + // Automatic gdk_flush for non main tread + #if AUTO_GDK_FLUSH + if (Glib::Thread::self() != mainThread) { + gdk_flush(); + } + #endif + myGdkRecMutex.unlock(); +} + +/* Process line command options + * Returns + * 0 if process in batch has executed + * 1 to start GUI (with a dir or file option) + * 2 to start GUI because no files found + * -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 main(int argc, char **argv) +{ + setlocale(LC_ALL,""); + setlocale(LC_NUMERIC, "C"); // to set decimal point to "." + // Uncomment the following line if you want to use the "--g-fatal-warnings" command line flag + //gtk_init (&argc, &argv); + + Glib::thread_init(); + gdk_threads_set_lock_functions(G_CALLBACK(myGdkLockEnter), (G_CALLBACK(myGdkLockLeave))); + gdk_threads_init(); + Gio::init (); + +#ifdef BUILD_BUNDLE + char exname[512] = {0}; + Glib::ustring exePath; + // get the path where the rawtherapee executable is stored + #ifdef WIN32 + WCHAR exnameU[512] = {0}; + GetModuleFileNameW (NULL, exnameU, 512); + WideCharToMultiByte(CP_UTF8,0,exnameU,-1,exname,512,0,0 ); + #else + if (readlink("/proc/self/exe", exname, 512) < 0) { + strncpy(exname, argv[0], 512); + } + #endif + exePath = Glib::path_get_dirname(exname); + + // set paths + if (Glib::path_is_absolute(DATA_SEARCH_PATH)) { + argv0 = DATA_SEARCH_PATH; + } else { + argv0 = Glib::build_filename(exePath, DATA_SEARCH_PATH); + } + if (Glib::path_is_absolute(CREDITS_SEARCH_PATH)) { + creditsPath = CREDITS_SEARCH_PATH; + } else { + creditsPath = Glib::build_filename(exePath, CREDITS_SEARCH_PATH); + } + if (Glib::path_is_absolute(LICENCE_SEARCH_PATH)) { + licensePath = LICENCE_SEARCH_PATH; + } else { + licensePath = Glib::build_filename(exePath, LICENCE_SEARCH_PATH); + } +#else + argv0 = DATA_SEARCH_PATH; + creditsPath = CREDITS_SEARCH_PATH; + licensePath = LICENCE_SEARCH_PATH; +#endif + + mainThread = Glib::Thread::self(); + + if (!Options::load ()) { + 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 (); + return -2; + } + + extProgStore->init(); + SoundManager::init(); + +#ifdef WIN32 + bool consoleOpened = false; + + if (argc>1 || options.rtSettings.verbose){ + if(options.rtSettings.verbose || ( !safe_file_test( safe_filename_to_utf8(argv[1]), Glib::FILE_TEST_EXISTS ) && !safe_file_test( safe_filename_to_utf8(argv[1]), Glib::FILE_TEST_IS_DIR ))) { + 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)) { + // 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;i1 || options.rtSettings.verbose){ + // printing RT's version in all case, particularly useful for the 'verbose' mode, but also for the batch processing + std::cout << "RawTherapee, version " << VERSION << std::endl; + std::cout << "WARNING: closing this window will close RawTherapee!" << std::endl << std::endl; + if (argc>1){ + int ret = processLineParams( argc, argv); + if( ret <= 0 ) + return ret; + } + } +#endif + + if( !options.rtSettings.verbose ) + TIFFSetWarningHandler(NULL); // avoid annoying message boxes + +#ifndef WIN32 + // Move the old path to the new one if the new does not exist + if (safe_file_test(Glib::build_filename(options.rtdir,"cache"), Glib::FILE_TEST_IS_DIR) && !safe_file_test(options.cacheBaseDir, Glib::FILE_TEST_IS_DIR)) + safe_g_rename(Glib::build_filename(options.rtdir,"cache"), options.cacheBaseDir); +#endif + + simpleEditor=false; + if( !argv1.empty() ) + if( safe_file_test(argv1, Glib::FILE_TEST_EXISTS) && !safe_file_test(argv1, Glib::FILE_TEST_IS_DIR)) + simpleEditor = true; + + if (!options.useSystemTheme) + { + std::vector rcfiles; + rcfiles.push_back (argv0+"/themes/"+options.theme+".gtkrc"); + if (options.slimUI) + rcfiles.push_back (argv0+"/themes/slim"); + // Set the font face and size + Gtk::RC::parse_string (Glib::ustring::compose( + "style \"clearlooks-default\" { font_name = \"%1\" }", options.font)); + Gtk::RC::set_default_files (rcfiles); + } + Gtk::Main m(&argc, &argv); + + Glib::ustring icon_path = Glib::build_filename(argv0,"images"); + Glib::RefPtr defaultIconTheme = Gtk::IconTheme::get_default(); + defaultIconTheme->append_search_path(icon_path); + + RTImage::setPaths(options); + MyExpander::init(); // has to stay AFTER RTImage::setPaths + +#ifndef WIN32 + // For an unknown reason, gtkmm 2.22 don't know the gtk-button-images property, while it exists in the documentation... + // Anyway, the problem was Linux only + static Glib::RefPtr settings = Gtk::Settings::get_default(); + if (settings) + settings->property_gtk_button_images().set_value(true); + else + printf("Error: no default settings to update!\n"); +#endif + + gdk_threads_enter (); + RTWindow *rtWindow = new class RTWindow(); + + // 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); + 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); + msgd.run (); + } + + // opening the main window + m.run(*rtWindow); + + gdk_threads_leave (); + delete rtWindow; + rtengine::cleanup(); + +#ifdef WIN32 + if (consoleOpened) { + printf("Press any key to exit RawTherapee\n"); + FlushConsoleInputBuffer(GetStdHandle(STD_INPUT_HANDLE)); + getch(); + } +#endif + + return 0; +} + +void deleteProcParams(std::vector &pparams) { + for (unsigned int i=0; ideleteInstance(); + delete pparams[i]; + pparams[i] = NULL; + } + return; +} + +int processLineParams( int argc, char **argv ) +{ + rtengine::procparams::PartialProfile *rawParams=NULL, *imgParams=NULL; + std::vector inputFiles; + Glib::ustring outputPath = ""; + std::vector processingParams; + bool outputDirectory=false; + bool overwriteFiles=false; + bool sideProcParams=false; + bool copyParamsFile=false; + bool skipIfNoSidecar=false; + bool useDefault=false; + unsigned int sideCarFilePos = 0; + int compression=92; + int subsampling=3; + int bits=-1; + std::string outputType = ""; + unsigned errors=0; + for( int iArg=1; iArgload ( 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 'Y': + overwriteFiles =true; + break; + case 'j': + if (strlen(argv[iArg]) > 2 && argv[iArg][2] == 's') { + if (strlen(argv[iArg])==3) { + std::cerr << "Error: the -js switch requires a mandatory value!" << std::endl; + deleteProcParams(processingParams); + return -3; + } + // looking for the subsampling parameter + sscanf(&argv[iArg][3],"%d",&subsampling); + 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"; + sscanf(&argv[iArg][2],"%d",&compression); + 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': + sscanf(&argv[iArg][2],"%d",&bits); + 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 = ((argv[iArg][2]!='z')?0:1); + break; + case 'n': + outputType = "png"; + compression = -1; + break; + case 'c': // MUST be last option + while( iArg+1 names; + Glib::RefPtr dir = Gio::File::create_for_path ( argv[iArg] ); + safe_build_file_list (dir, names, argv[iArg] ); + for(size_t iFile=0; iFile< names.size(); iFile++ ){ + if( !safe_file_test( names[iFile] , Glib::FILE_TEST_IS_DIR)){ + // skip files without extension and without sidecar files + Glib::ustring s(names[iFile]); + Glib::ustring::size_type ext= s.find_last_of('.'); + if( Glib::ustring::npos == ext ) + continue; + if( ! s.substr(ext).compare( paramFileExtension )) + continue; + inputFiles.push_back( names[iFile] ); + } + } + }else{ + inputFiles.push_back( safe_filename_to_utf8 (argv[iArg]) ); + } + } + 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 << " indicate parameters you can change." << std::endl; + std::cout << "[Square brackets] mean the parameter is not mandatory." << 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; + cout << std::endl; + std::cout << "Usage:" << std::endl; + std::cout << " " << Glib::path_get_basename(argv[0]) << " Start File Browser inside directory." << std::endl; + std::cout << " " << Glib::path_get_basename(argv[0]) << " Start Image Editor with file." << std::endl; + std::cout << " " << Glib::path_get_basename(argv[0]) << " -c

| Convert files in batch with default parameters." << std::endl << std::endl; +#ifdef WIN32 + std::cout << " -w Do not open the Windows console" << std::endl; +#endif + std::cout << "Other options used with -c (-c must be the last option):" << std::endl; + std::cout << Glib::path_get_basename(argv[0]) << " [-o |-O ] [-s|-S] [-p ] [-d] [-j[1-100] [-js<1-3>]|[-b<8|16>] <[-t[z] | [-n]]] [-Y] -c " << std::endl; + std::cout << " -o | Select output file or directory." << std::endl; + std::cout << " -O | Select output file or directory and copy " << pparamsExt << " file into it." << std::endl; + std::cout << " -s Include the " << pparamsExt << " file next to the input file (with the same" << std::endl; + std::cout << " name) to build the image parameters," << std::endl; + std::cout << " e.g. for photo.raw there should be a photo.raw." << pparamsExt << " file in" << std::endl; + std::cout << " the same directory. If the file does not exist, internal" << std::endl; + std::cout << " default (neutral) values (not those in Default." << pparamsExt << ") will be" << std::endl; + std::cout << " used." << std::endl; + std::cout << " -S Like -s but skip if the " << pparamsExt << " file does not exist." << std::endl; + std::cout << " -p Specify " << pparamsExt << " file to be used for all conversions." << std::endl; + std::cout << " You can specify as many -p options as you like (see" << std::endl; + std::cout << " description below)." << std::endl; + std::cout << " -d Use the default raw or non-raw " << pparamsExt << " file 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 (on by default). Optionally add" << std::endl; + std::cout << " compression 1-100 (default value: 92)." << std::endl; + std::cout << " -js<1-3> Specify the JPEG subsampling parameter, where:" << std::endl; + std::cout << " 1 = Best compression: 2x2, 1x1, 1x1 (4:1:1) - default of the JPEG library" << std::endl; + std::cout << " 2 = Widely used normal ratio: 2x1, 1x1, 1x1 (4:2:2)" << std::endl; + std::cout << " 3 = Best quality: 1x1, 1x1, 1x1 (4:4:4)" << std::endl; + std::cout << " -b<8|16> Specify bit depth per channel (only applies to TIFF and PNG output)." << std::endl; + std::cout << " -t[z] Specify output to be TIFF (16-bit if -b8 is not set)." << std::endl; + std::cout << " Uncompressed by default, or ZIP compression with 'z'" << std::endl; + std::cout << " -n Specify output to be compressed PNG (16-bit if -b8 is not set)." << std::endl; + std::cout << " -Y Overwrite output if present." << std::endl<load(profPath==DEFPROFILE_INTERNAL ? DEFPROFILE_INTERNAL : Glib::build_filename(profPath, options.defProfRaw.substr(5) + paramFileExtension))) { + std::cerr << "Error: default raw processing profile not found" << std::endl; + rawParams->deleteInstance(); + delete rawParams; + deleteProcParams(processingParams); + return -3; + } + imgParams = new rtengine::procparams::PartialProfile(true); + profPath = options.findProfilePath(options.defProfImg); + if (options.is_defProfImgMissing() || profPath.empty() || imgParams->load(profPath==DEFPROFILE_INTERNAL ? DEFPROFILE_INTERNAL : Glib::build_filename(profPath, options.defProfImg.substr(5) + paramFileExtension))) { + std::cerr << "Error: default non-raw processing profile not found" << std::endl; + imgParams->deleteInstance(); + delete imgParams; + rawParams->deleteInstance(); + delete rawParams; + deleteProcParams(processingParams); + return -3; + } + } + + 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; + + Glib::ustring inputFile = inputFiles[iFile]; + std::cout << "Processing: " << inputFile << std::endl; + + rtengine::InitialImage* ii=NULL; + rtengine::ProcessingJob* job =NULL; + int errorCode; + bool isRaw=false; + + Glib::ustring outputFile; + if( outputType.empty() ) + outputType = "jpg"; + 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 = outputPath + "/" + s.substr(0,ext) + "." + outputType; + }else{ + Glib::ustring s = outputPath; + Glib::ustring::size_type ext= s.find_last_of('.'); + outputFile = s.substr(0,ext) + "." + outputType; + } + if( inputFile == outputFile){ + std::cerr << "Cannot overwrite: " << inputFile << std::endl; + continue; + } + if( !overwriteFiles && safe_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; + } + + // Load the image + isRaw = true; + Glib::ustring ext = getExtension (inputFile); + if (ext.lowercase()=="jpg" || ext.lowercase()=="jpeg" || ext.lowercase()=="tif" || ext.lowercase()=="tiff" || ext.lowercase()=="png") + isRaw = false; + + ii = rtengine::InitialImage::load ( inputFile, isRaw, &errorCode, NULL ); + if (!ii) { + errors++; + std::cerr << "Error loading file: "<< inputFile << std::endl; + continue; + } + + if (useDefault) { + if (isRaw) { + std::cout << " Merging default raw processing profile" << std::endl; + rawParams->applyTo(¤tParams); + } + else { + std::cout << " Merging default non-raw processing profile" << std::endl; + imgParams->applyTo(¤tParams); + } + } + + bool sideCarFound = false; + unsigned int i=0; + // Iterate the procparams file list in order to build the final ProcParams + do { + if (sideProcParams && i==sideCarFilePos) { + // using the sidecar file + 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( !safe_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; + std::cout << " Merging sidecar procparams" << std::endl; + } + } + if( processingParams.size()>i ) { + std::cout << " Merging procparams #" << i << std::endl; + processingParams[i]->applyTo(¤tParams); + } + i++; + } while (i < processingParams.size()+(sideProcParams?1:0)); + + if( sideProcParams && !sideCarFound && skipIfNoSidecar ){ + delete ii; + errors++; + std::cerr << "Error: no sidecar procparams found for: "<< inputFile << std::endl; + continue; + } + + job = rtengine::ProcessingJob::create (ii, currentParams); + if( !job ){ + errors++; + std::cerr << "Error creating processing for: "<< inputFile << std::endl; + ii->decreaseRef(); + continue; + } + + // Process image + rtengine::IImage16* resultImage = rtengine::processImage (job, errorCode, NULL, options.tunnelMetaData); + if( !resultImage ){ + errors++; + std::cerr << "Error processing: "<< inputFile << std::endl; + 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 ); + else + errorCode = resultImage->saveToFile (outputFile); + + if(errorCode){ + errors++; + std::cerr << "Error saving to: "<< outputFile << std::endl; + }else{ + if( copyParamsFile ){ + Glib::ustring outputProcessingParams = outputFile + paramFileExtension; + currentParams.save( outputProcessingParams ); + } + } + + ii->decreaseRef(); + resultImage->free(); + } + + if (imgParams) { imgParams->deleteInstance(); delete imgParams; } + if (rawParams) { rawParams->deleteInstance(); delete rawParams; } + deleteProcParams(processingParams); + + return errors>0?-2:0; +} + diff --git a/rtgui/mountselectionlistener.h b/rtgui/mountselectionlistener.h new file mode 100644 index 000000000..169d57108 --- /dev/null +++ b/rtgui/mountselectionlistener.h @@ -0,0 +1,30 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _MOUNTSELECTIONLISTENER_ +#define _MOUNTSELECTIONLISTENER_ + +#include + +class MountSelectionListener { + + public: + virtual void mountSelectionChanged (Glib::ustring mountRoot) {} +}; + +#endif diff --git a/rtgui/multilangmgr.cc b/rtgui/multilangmgr.cc new file mode 100755 index 000000000..1bed66dc4 --- /dev/null +++ b/rtgui/multilangmgr.cc @@ -0,0 +1,202 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifdef WIN32 +// Desired auto detect function is Vista+ +#if __GNUC__ == 4 && __GNUC_MINOR__ >= 8 +#define WINVER 0x0600 // switching to WINVER for gcc 4.8.1 support on Winx64 +#else +#define _WIN32_WINNT 0x0600 +#endif +#include +#include +#if __GNUC__ == 4 && __GNUC_MINOR__ >= 8 +#undef WINVER +#else +#undef _WIN32_WINNT +#endif +#endif +#include +#include "multilangmgr.h" +#include +#include "../rtengine/safegtk.h" + +MultiLangMgr langMgr; + +Glib::ustring M (std::string key) { return langMgr.getStr (key); } + +// fb is fallback manager if the first could not be loaded +bool MultiLangMgr::load (Glib::ustring fname, MultiLangMgr* fb) { + FILE *f = safe_g_fopen (fname, "rt"); + + fallBack = fb; + + if (f==NULL) + return false; + + transTable.clear (); + + char* buffer = new char[2048]; + + while (fgets (buffer, 2048, f) != 0) { + // find separator + int seppos = 0; + while (buffer[seppos]!=0 && buffer[seppos]!=';') + seppos++; + // no separator found + if (buffer[seppos]==0) + continue; + // cut the last \n and \r characters + int endpos = strlen(buffer)-1; + while (buffer[endpos]=='\n' || buffer[endpos]=='\r') + endpos--; + buffer[endpos+1] = 0; + // replace "\n" to '\n' + int j = 0; + for (int i=0; i::iterator r; + for (r=transTable.begin (); r!=transTable.end(); r++) + fprintf (f, "%s;%s\n", r->first.c_str(), safe_locale_from_utf8(r->second).c_str()); + + fclose (f); + return true; +} + + +bool MultiLangMgr::isOSLanguageDetectSupported() { +#ifdef WIN32 + #ifdef __MINGW64_VERSION_MAJOR + // Only on Vista or above + return LOBYTE(LOWORD(GetVersion()))>=6; +#else + return false; +#endif +#elif defined(__linux__) || defined(__APPLE__) + return true; +#else + return false; +#endif +} + + +// returns Language name mapped from the currently selected OS language +Glib::ustring MultiLangMgr::getOSUserLanguage() { + Glib::ustring langName = Glib::ustring("default"); + + if (isOSLanguageDetectSupported()) { + +#ifdef WIN32 +// When using old versions of MINGW this is not defined +#ifdef __MINGW64_VERSION_MAJOR + WCHAR langRFCU[64] = {0}; + if (GetUserDefaultLocaleName(langRFCU,64)!=0 && lstrlenW(langRFCU)>=2) { + // convert UNICODE16 to GTK + char langRFC[64]; + WideCharToMultiByte(CP_UTF8,0,langRFCU,-1,langRFC,64,0,0); + Glib::ustring localRFC=Glib::ustring(langRFC); + + langName=TranslateRFC2Language(localRFC); + } +#endif +#elif defined(__linux__) || defined(__APPLE__) + char *tmplocale; + tmplocale = setlocale(LC_CTYPE,""); + setlocale(LC_NUMERIC, "C"); // to set decimal point to "." + if(tmplocale) + langName = TranslateRFC2Language(tmplocale); +#endif + } + return langName; +} + +// Translates RFC standard language code to file name, e.g. "de-DE" to "Deutsch" +Glib::ustring MultiLangMgr::TranslateRFC2Language(Glib::ustring rfcName) { + if (rfcName.length()<2) return Glib::ustring("default"); + + Glib::ustring major=rfcName.substr(0,2).lowercase(); + Glib::ustring minor; + if (rfcName.length()>=5) { + minor=rfcName.substr(3,2).uppercase(); + } + + //printf("Lang: %s - %s\n",major.c_str(),minor.c_str()); + + if (major=="ca") return "Catala"; + if (major=="zh") + return (minor=="CN" || minor=="SG") ? "Chinese (Simplified)" : "Chinese (Traditional)"; + if (major=="cs") return "Czech"; + if (major=="da") return "Dansk"; + if (major=="de") return "Deutsch"; + if (major=="es") return "Espanol"; + if (major=="eu") return "Euskara"; + if (major=="fr") return "Francais"; + if (major=="el") return "Greek"; + if (major=="he") return "Hebrew"; + if (major=="it") return "Italiano"; + if (major=="ja") return "Japanese"; + if (major=="lv") return "Latvian"; + if (major=="hu") return "Magyar"; + if (major=="nl") return "Nederlands"; + if (major=="nn" || major=="nb") return "Norsk BM"; + if (major=="pl") return "Polish"; + if (major=="pt") return "Portugues (Brasil)"; + if (major=="ru") return "Russian"; + if (major=="sr") return "Serbian (Cyrilic Characters)"; + if (major=="sk") return "Slovak"; + if (major=="fi") return "Suomi"; + if (major=="sv") return "Swedish"; + if (major=="tr") return "Turkish"; + + // Don't split en-US, en-GB, etc. since only default english is constantly updated + return "default"; +} + +Glib::ustring MultiLangMgr::getStr (std::string key) { + + std::map::iterator r = transTable.find (key); + if (r!=transTable.end()) + return r->second; + else if (fallBack) + return fallBack->getStr (key); + else + return key; +} diff --git a/rtgui/multilangmgr.h b/rtgui/multilangmgr.h new file mode 100644 index 000000000..7f14e0fac --- /dev/null +++ b/rtgui/multilangmgr.h @@ -0,0 +1,50 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _MULTILANGMGR_ +#define _MULTILANGMGR_ + +#include +#include +#include + +class MultiLangMgr { + + std::map transTable; + MultiLangMgr* fallBack; + + Glib::ustring TranslateRFC2Language(Glib::ustring rfcName); + + public: + MultiLangMgr () : fallBack (NULL) {} + MultiLangMgr (Glib::ustring fname) : fallBack (NULL) { load (fname); } + MultiLangMgr (Glib::ustring fname, MultiLangMgr* fb) : fallBack (NULL) { load (fname, fb); } + + bool load (Glib::ustring fname, MultiLangMgr* fb = NULL); + bool save (Glib::ustring fname); + + bool isOSLanguageDetectSupported(); + Glib::ustring getOSUserLanguage(); + Glib::ustring getStr (std::string key); +}; + +extern MultiLangMgr langMgr; + +Glib::ustring M (std::string key); + +#endif diff --git a/rtgui/mycurve.cc b/rtgui/mycurve.cc new file mode 100644 index 000000000..5301dda62 --- /dev/null +++ b/rtgui/mycurve.cc @@ -0,0 +1,143 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "mycurve.h" +#include "../rtengine/curves.h" +#include +#include + +MyCurve::MyCurve () : pipetteR(-1.f), pipetteG(-1.f), pipetteB(-1.f), pipetteVal(-1.f), listener(NULL) { + + cursor_type = CSArrow; + graphX = get_allocation().get_width() - RADIUS * 2; + graphY = get_allocation().get_height() - RADIUS * 2; + prevGraphW = graphW; + prevGraphH = graphH; + buttonPressed = false; + snapTo = ST_None; + leftBar = NULL; + bottomBar = NULL; + colorProvider = NULL; + sized = RS_Pending; + snapToElmt = -100; + curveIsDirty = true; + edited_point = -1; + + set_extension_events(Gdk::EXTENSION_EVENTS_ALL); +#if defined (__APPLE__) + // Workaround: disabling POINTER_MOTION_HINT_MASK as for gtk 2.24.22 the get_pointer() function is buggy for quartz and modifier mask is not updated correctly. + // This workaround should be removed when bug is fixed in GTK2 or when migrating to GTK3 + add_events(Gdk::EXPOSURE_MASK | Gdk::POINTER_MOTION_MASK | Gdk::ENTER_NOTIFY_MASK | Gdk::LEAVE_NOTIFY_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::BUTTON1_MOTION_MASK); +#else + add_events(Gdk::EXPOSURE_MASK | Gdk::POINTER_MOTION_MASK | Gdk::POINTER_MOTION_HINT_MASK | Gdk::ENTER_NOTIFY_MASK | Gdk::LEAVE_NOTIFY_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::BUTTON1_MOTION_MASK); +#endif + + mcih = new MyCurveIdleHelper; + mcih->myCurve = this; + mcih->destroyed = false; + mcih->pending = 0; +} + +MyCurve::~MyCurve () { + + if (mcih->pending) + mcih->destroyed = true; + else + delete mcih; +} + +int MyCurve::calcDimensions () { + int newRequestedW, newRequestedH; + + newRequestedW = newRequestedH = get_allocation().get_width(); + if (leftBar && !bottomBar) + newRequestedH -= getBarWidth() + CBAR_MARGIN - RADIUS; + if (!leftBar && bottomBar) + newRequestedH += getBarWidth() + CBAR_MARGIN - RADIUS; + + graphW = newRequestedW - RADIUS - (leftBar ? (getBarWidth()+CBAR_MARGIN) : RADIUS); + graphH = newRequestedH - RADIUS - (bottomBar ? (getBarWidth()+CBAR_MARGIN) : RADIUS); + graphX = newRequestedW - RADIUS - graphW; + graphY = RADIUS + graphH; + + return newRequestedH; +} + +void MyCurve::setColoredBar (ColoredBar *left, ColoredBar *bottom) { + leftBar = left; + bottomBar = bottom; +} + +void MyCurve::notifyListener () { + + if (listener) + listener->curveChanged (); +} + +bool MyCurve::snapCoordinateX(double testedVal, double realVal) { + + double dist = realVal - testedVal; + + if (dist < 0.) dist = -dist; + if (dist < snapToMinDistX) { + snapToMinDistX = dist; + snapToValX = testedVal; + return true; + } + return false; +} + +bool MyCurve::snapCoordinateY(double testedVal, double realVal) { + + double dist = realVal - testedVal; + + if (dist < 0.) dist = -dist; + if (dist < snapToMinDistY) { + snapToMinDistY = dist; + snapToValY = testedVal; + return true; + } + return false; +} + +float MyCurve::getVal(LUTf &curve, int x) { + if ((graphW-2) == curve.getSize()) { + return curve[x]; + } + else { + return curve.getVal01(float(x)/(graphW-3)); + } +} + +void MyCurve::on_style_changed (const Glib::RefPtr& style) { + setDirty(true); + queue_draw (); +} + +void MyCurve::refresh() { + if (leftBar != NULL) + leftBar->setDirty(true); + if (bottomBar != NULL) + bottomBar->setDirty(true); + + setDirty(true); + + Glib::RefPtr win = get_window(); + if (win) + win->invalidate(true); +} diff --git a/rtgui/mycurve.h b/rtgui/mycurve.h new file mode 100644 index 000000000..5a20ad190 --- /dev/null +++ b/rtgui/mycurve.h @@ -0,0 +1,149 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _MYCURVE_ +#define _MYCURVE_ + +#include +#include +#include "curvelistener.h" +#include "cursormanager.h" +#include "coloredbar.h" +#include "coordinateadjuster.h" +#include "../rtengine/LUT.h" +#include "guiutils.h" +#include "options.h" + +#define RADIUS 3 /** radius of the control points */ +#define CBAR_WIDTH_STD 13 /** width of the colored bar (border included) for standard themes */ +#define CBAR_WIDTH_SLIM 10 /** width of the colored bar (border included) for slim themes */ +#define CBAR_MARGIN 2 /** spacing between the colored bar and the graph */ +#define SQUARE 2 /** half length of the square shape of the tangent handles */ +#define MIN_DISTANCE 5 /** min distance between control points */ +#define GRAPH_SIZE 200 /** size of the curve editor graphic */ + +/** @brief Flat or Diagonal curve type + For compatibility and simplicity reason, order shouldn't change, and must be identical to the order specified in the curveType widget + */ +enum CurveType { + CT_Flat, + CT_Diagonal +}; + +/** @brief Tells the type of element that the points snaps to + */ +enum SnapToType { + ST_None, /// The point is not snapped + ST_Identity, /// Point snapped to the identity curve + ST_Neighbors /// Point snapped to the neighbor points +}; + +enum ResizeState { + RS_Pending = 1, /// Resize has to occurs + RS_Done = 2, /// Resize has been done + RS_Force = 4 /// Resize has to occurs even without CONFIGURE event +}; + +class MyCurveIdleHelper; +class CurveEditor; + +class MyCurve : public Gtk::DrawingArea, public BackBuffer, public ColorCaller, public CoordinateProvider { + + friend class MyCurveIdleHelper; + + protected: + float pipetteR, pipetteG, pipetteB; /// RGB values from the PipetteDataProvider ; if a channel is set to -1.0f, it is not used + float pipetteVal; /// Effective pipette value, i.e. where to create the point; if a point already exist near this value, it'll be used + + CurveListener* listener; + ColoredBar *leftBar; + ColoredBar *bottomBar; + CursorShape cursor_type; + int graphX, graphY, graphW, graphH; /// position and dimensions of the graphic area, excluding surrounding space for the points of for the colored bar + int prevGraphW, prevGraphH; /// previous inner width and height of the editor + Gdk::ModifierType mod_type; + int cursorX; /// X coordinate in the graph of the cursor + int cursorY; /// Y coordinate in the graph of the cursor + LUTf point; + LUTf upoint; + LUTf lpoint; + bool buttonPressed; + /** + * snapToElmt, which will be used for the Y axis only, must be interpreted like this: + * -100 : no element (default) + * -3 : maximum value + * -2 : identity value + * -1 : minimum value + * [0;1000[ : control point that it's snapped to + * >=1000 : moved control point which snaps to the line made by its previous and next point + */ + int snapToElmt; + bool snapTo; + double snapToMinDistX, snapToMinDistY; + double snapToValX, snapToValY; + MyCurveIdleHelper* mcih; + enum ResizeState sized; + bool curveIsDirty; + + int edited_point; // > -1 when a point is being numerically edited + std::vector editedPos; + + virtual std::vector get_vector (int veclen) = 0; + int getGraphMinSize() { return GRAPH_SIZE + RADIUS + 1; } + bool snapCoordinateX(double testedVal, double realVal); + bool snapCoordinateY(double testedVal, double realVal); + float getVal(LUTf &curve, int x); + + // return value = new requested height + int calcDimensions (); + + public: + MyCurve (); + ~MyCurve (); + + void setCurveListener (CurveListener* cl) { listener = cl; } + void setColoredBar (ColoredBar *left, ColoredBar *bottom); + void notifyListener (); + void updateBackgroundHistogram (LUTu & hist) {return;} ; + void forceResize() { sized = RS_Force; } + void refresh(); + void setCurveDirty () { curveIsDirty = true; } + void on_style_changed (const Glib::RefPtr& style); + virtual std::vector getPoints () = 0; + virtual void setPoints (const std::vector& p) = 0; + virtual bool handleEvents (GdkEvent* event) = 0; + virtual void reset (const std::vector &resetCurve, double identityValue=0.5) = 0; + + virtual void pipetteMouseOver (CurveEditor *ce, EditDataProvider *provider, int modifierKey) =0; + virtual void pipetteButton1Pressed(EditDataProvider *provider, int modifierKey) =0; + virtual void pipetteButton1Released(EditDataProvider *provider) =0; + virtual void pipetteDrag(EditDataProvider *provider, int modifierKey) =0; + + static int getBarWidth() { return options.slimUI ? CBAR_WIDTH_SLIM : CBAR_WIDTH_STD; } +}; + +class MyCurveIdleHelper { + public: + MyCurve* myCurve; + bool destroyed; + int pending; + + void clearPixmap () { myCurve->setDirty(true); } +}; + +#endif diff --git a/rtgui/mydiagonalcurve.cc b/rtgui/mydiagonalcurve.cc new file mode 100644 index 000000000..070459e7b --- /dev/null +++ b/rtgui/mydiagonalcurve.cc @@ -0,0 +1,1347 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "mydiagonalcurve.h" +#include "../rtengine/curves.h" +#include +#include + +MyDiagonalCurve::MyDiagonalCurve () : activeParam(-1), bghistvalid(false) { + + graphW = get_allocation().get_width() - RADIUS * 2; + graphH = get_allocation().get_height() - RADIUS * 2; + prevGraphW = graphW; + prevGraphH = graphH; + grab_point = -1; + lit_point = -1; + buttonPressed = false; + + bghist = new unsigned int[256]; + + editedPos.resize(2); + editedPos.at(0) = editedPos.at(1) = 0.0; + + signal_event().connect( sigc::mem_fun(*this, &MyDiagonalCurve::handleEvents) ); + + curve.type = DCT_Spline; + + curve.x.push_back(0.); + curve.y.push_back(0.); + curve.x.push_back(1.); + curve.y.push_back(1.); +} + +MyDiagonalCurve::~MyDiagonalCurve () { + + delete [] bghist; +} + +std::vector MyDiagonalCurve::get_vector (int veclen) { + + std::vector vector; + vector.resize (veclen); + + if (curve.type != DCT_Parametric) { + // count active points: + double prev =- 1.0; + int active = 0; + int firstact = -1; + for (int i = 0; i < (int)curve.x.size(); ++i) + if (curve.x.at(i) > prev) { + if (firstact < 0) + firstact = i; + prev = curve.x.at(i); + ++active; + } + // handle degenerate case: + if (active < 2) { + double ry; + if (active > 0) + ry = curve.y.at(firstact); + else + ry = 0.0; + if (ry < 0.0) ry = 0.0; + if (ry > 1.0) ry = 1.0; + for (int x = 0; x < veclen; ++x) + vector.at(x) = ry; + return vector; + } + } + + // calculate remaining points + std::vector curveDescr = getPoints (); + rtengine::DiagonalCurve rtcurve(curveDescr, veclen*1.2); + std::vector t; + t.resize (veclen); + for (int i = 0; i < veclen; i++) + t[i] = (double) i / (veclen - 1.0); + rtcurve.getVal (t, vector); + return vector; +} + +void MyDiagonalCurve::get_LUT (LUTf &lut) { + + int size = lut.getSize(); + + if (curve.type != DCT_Parametric) { + // count active points: + double prev =- 1.0; + int active = 0; + int firstact = -1; + for (int i = 0; i < (int)curve.x.size(); ++i) + if (curve.x.at(i) > prev) { + if (firstact < 0) + firstact = i; + prev = curve.x.at(i); + ++active; + } + // handle degenerate case: + if (active < 2) { + double ry; + if (active > 0) + ry = curve.y.at(firstact); + else + ry = 0.0; + if (ry < 0.0) ry = 0.0; + if (ry > 1.0) ry = 1.0; + for (int x = 0; x < size; ++x) + lut[x] = ry; + return; + } + } + + // calculate remaining points + std::vector curveDescr = getPoints (); + rtengine::DiagonalCurve rtcurve(curveDescr, lut.getUpperBound()*1.2); + double t; + double maxVal = double(lut.getUpperBound()); + for (int i = 0; i < size; i++) { + t = double(i) / maxVal; + lut[i] = rtcurve.getVal (t); + } + return; +} + +void MyDiagonalCurve::interpolate () { + + prevGraphW = graphW; + prevGraphH = graphH; + int nbPoints = rtengine::max(graphW-2,201); + point(nbPoints); + get_LUT (point); + upoint.reset(); + lpoint.reset (); + + if (curve.type==DCT_Parametric && activeParam>0) { + double tmp = curve.x.at(activeParam-1); + if (activeParam>=4) { + upoint(nbPoints); + lpoint(nbPoints); + curve.x.at(activeParam-1) = 100; + get_LUT(upoint); + curve.x.at(activeParam-1) = -100; + get_LUT (lpoint); + curve.x.at(activeParam-1) = tmp; + } + } + + curveIsDirty = false; +} + +void MyDiagonalCurve::draw (int handle) { + if (!isDirty()) { + return; + } + + Glib::RefPtr win = get_window(); + if (!surfaceCreated() || !win) + return; + + // re-calculate curve if dimensions changed + int currPointSize = point.getUpperBound(); + if (curveIsDirty || /*prevGraphW != graphW || prevGraphH != graphH ||*/ (currPointSize==200 && (graphW-3>200)) || (currPointSize>200 && (graphW-2<=200 || graphW-3!=currPointSize))) + interpolate (); + currPointSize = point.getUpperBound(); + + Gtk::StateType state = !is_sensitive() ? Gtk::STATE_INSENSITIVE : Gtk::STATE_NORMAL; + + Glib::RefPtr style = get_style (); + Cairo::RefPtr cr = getContext(); + cr->set_line_cap(Cairo::LINE_CAP_SQUARE); + + // clear background + Gdk::Color c = style->get_bg (Gtk::STATE_NORMAL); + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + cr->rectangle (0., 0., double(getWidth()), double(getHeight())); + cr->fill (); + + // histogram in the background + if (bghistvalid) { + // find highest bin + unsigned int valMax = 0; + for (int i=0; i<256; i++) + if (bghist[i]>valMax) + valMax = bghist[i]; + // draw histogram + cr->set_line_width (1.0); + double stepSize = (graphW-3) / 255.0; + cr->move_to ( double(graphX+1), double(graphY-1) ); + c = style->get_fg (Gtk::STATE_INSENSITIVE); + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + for (int i=0; i<256; i++) { + double val = double(bghist[i]) * double(graphH-2) / double(valMax); + /* + if (val>graphH-2) + val = graphH-2; + */ + //if (i>0) + cr->line_to (double(graphX)+1.5+double(i)*stepSize, double(graphY-1)-val); + } + cr->line_to (double(graphX)+1.5+255.*stepSize, double(graphY-1)); + cr->close_path(); + cr->fill (); + } + + // draw the grid lines: + cr->set_line_width (1.0); + c = style->get_dark (state); + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + cr->set_antialias (Cairo::ANTIALIAS_NONE); + for (int i = 0; i <= 10; i++) { + // horizontal lines + cr->move_to (double(graphX)+0.5 , double(graphY) - max(0.5, double(graphH*i/10) - 0.5)); + cr->rel_line_to (double(graphW-1) , 0.); + // vertical lines + cr->move_to (double(graphX) + max(0.5, double(graphW*i/10) - 0.5), double(graphY)); + cr->rel_line_to (0. , double(-graphH+1)); + } + cr->stroke (); + + // draw f(x)=x line + if (snapToElmt == -2) + cr->set_source_rgb (1.0, 0.0, 0.0); + else + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + std::valarray ds (1); + ds[0] = 4; + cr->set_dash (ds, 0); + cr->move_to (double(graphX)+1.5, double(graphY)-1.5); + cr->rel_line_to (double(graphW-3), double(-graphH+3)); + cr->stroke (); + cr->unset_dash (); + + cr->set_antialias (Cairo::ANTIALIAS_SUBPIXEL); + cr->set_line_width (1.0); + + // draw upper and lower bounds + float graphH_ = float(graphH-3); + float graphX_ = float(graphX)+1.5; + float graphY_ = float(graphY)-1.5; + if (curve.type==DCT_Parametric && activeParam>0 && lpoint.getUpperBound()>1 && upoint.getUpperBound()>1) { + cr->set_source_rgba (0.0, 0.0, 0.0, 0.15); + cr->move_to (graphX_, getVal(upoint, 0)*-graphH_+graphY_); + for (int i=1; iline_to (float(i)+graphX_, getVal(upoint, i)*-graphH_+graphY_); + for (int i=graphW-3; i>=0; --i) + cr->line_to (float(i)+graphX_, getVal(lpoint, i)*-graphH_+graphY_); + cr->fill (); + } + + // draw the pipette values + if (pipetteR > -1.f || pipetteG > -1.f || pipetteB > -1.f) { + int n=0; + if (pipetteR > -1.f) ++n; + if (pipetteG > -1.f) ++n; + if (pipetteB > -1.f) ++n; + + if (n > 1) { + if (pipetteR > -1.f) { + cr->set_source_rgba (1., 0., 0., 0.5); // WARNING: assuming that red values are stored in pipetteR, which might not be the case! + cr->move_to (double(graphX)+1.5 + double(graphW-3)*pipetteR, double(graphY)-1.5); + cr->rel_line_to (0, double(-graphH+3)); + cr->stroke (); + } + if (pipetteG > -1.f) { + cr->set_source_rgba (0., 1., 0., 0.5); // WARNING: assuming that green values are stored in pipetteG, which might not be the case! + cr->move_to (double(graphX)+1.5 + double(graphW-3)*pipetteG, double(graphY)-1.5); + cr->rel_line_to (0, double(-graphH+3)); + cr->stroke (); + } + if (pipetteB > -1.f) { + cr->set_source_rgba (0., 0., 1., 0.5); // WARNING: assuming that blue values are stored in pipetteB, which might not be the case! + cr->move_to (double(graphX)+1.5 + double(graphW-3)*pipetteB, double(graphY)-1.5); + cr->rel_line_to (0, double(-graphH+3)); + cr->stroke (); + } + } + if (pipetteVal > -1.f) { + cr->set_line_width (2.); + c = style->get_fg (state); + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + cr->move_to (double(graphX)+1.5 + double(graphW-3)*pipetteVal, double(graphY)-1.5); + cr->rel_line_to (0, double(-graphH+3)); + cr->stroke (); + cr->set_line_width (1.); + } + } + + c = style->get_fg (state); + + // draw the cage of the NURBS curve + if (curve.type==DCT_NURBS) { + unsigned int nbPoints; + std::valarray ch_ds (1); + ch_ds[0] = 2; + cr->set_dash (ch_ds, 0); + cr->set_line_width (0.75); + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + std::vector points = getPoints(); + nbPoints = ((int)points.size()-1)/2; + for (unsigned int i = 1; i < nbPoints; i++) { + int pos = i*2+1; + + double x1 = double(graphX)+1.5 + double(graphW-3)*points[pos-2]; // project (curve.at(i), 0, 1, graphW); + double y1 = double(graphY)-1.5 - double(graphH-3)*points[pos-1]; // project (curve.y.at(i)i], 0, 1, graphH); + double x2 = double(graphX)+0.5 + double(graphW-3)*points[pos]; // project (curve.at(i), 0, 1, graphW); + double y2 = double(graphY)-1.5 - double(graphH-3)*points[pos+1]; // project (curve.y.at(i), 0, 1, graphH); + + // set the color of the line when the point is snapped to the cage + if (curve.x.size() == nbPoints && snapToElmt >= 1000 && ((i == (snapToElmt-1000)) || (i == (snapToElmt-999)))) + cr->set_source_rgb (1.0, 0.0, 0.0); + else + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + cr->move_to (x1, y1); + cr->line_to (x2, y2); + cr->stroke (); + } + cr->unset_dash (); + cr->set_line_width (1.0); + } + + // draw curve + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + cr->move_to (graphX_, getVal(point, 0)*-graphH_+graphY_); + for (int i=1; iline_to (float(i)+graphX_, getVal(point, i)*-graphH_+graphY_); + cr->stroke (); + + // draw the left colored bar + if (leftBar) { + // first the background + int bWidth = getBarWidth(); + BackBuffer *bb = this; + leftBar->setDrawRectangle(win, 1, graphY-graphH+1, bWidth-2, graphH-2); + leftBar->expose(bb); + + // now the border + c = style->get_dark (state); + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + cr->rectangle(0.5, graphY-graphH+0.5, bWidth-1, graphH-1); + cr->stroke(); + } + + // draw the bottom colored bar + if (bottomBar) { + // first the background + int bWidth = getBarWidth(); + BackBuffer *bb = this; + bottomBar->setDrawRectangle(win, graphX+1, graphY+CBAR_MARGIN+1, graphW-2, bWidth-2); + bottomBar->expose(bb); + + // now the border + c = style->get_dark (state); + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + cr->rectangle(graphX+0.5, graphY+CBAR_MARGIN+0.5, graphW-1, bWidth-1 ); + cr->stroke(); + } + + // draw bullets + if (curve.type!=DCT_Parametric) { + c = style->get_fg (state); + for (int i = 0; i < (int)curve.x.size(); ++i) { + if (curve.x.at(i) == -1) continue; + if (snapToElmt >= 1000) { + int pt = snapToElmt-1000; + if (i >= (pt-1) && i <= (pt+1)) + cr->set_source_rgb(1.0, 0.0, 0.0); + else + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + } + else { + if (i == handle || i == snapToElmt || i == edited_point) + cr->set_source_rgb (1.0, 0.0, 0.0); + else + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + } + + double x = double(graphX+1) + double((graphW-2) * curve.x.at(i)); // project (curve.x.at(i), 0, 1, graphW); + double y = double(graphY-1) - double((graphH-2) * curve.y.at(i)); // project (curve.y.at(i), 0, 1, graphH); + + cr->arc (x, y, RADIUS+0.5, 0, 2*M_PI); + cr->fill (); + + if (i == edited_point) { + cr->set_line_width(2.); + cr->arc (x, y, RADIUS+3.5, 0, 2*M_PI); + cr->stroke(); + cr->set_line_width(1.); + } + + } + } + setDirty(false); + queue_draw(); +} + +/*void MyDiagonalCurve::graphSizeRequest (Gtk::Requisition* req) { + req->width = getGraphMinSize(); + // The real height request should take care of the presence of the vertical + // scroll bar and its width + req->height = sized ? getGraphMinSize() : get_allocation().get_width(); +}*/ + +bool MyDiagonalCurve::handleEvents (GdkEvent* event) { + + CursorShape new_type = cursor_type; + + bool retval = false; + int num = (int)curve.x.size(); + + /* graphW and graphH are the size of the graph */ + calcDimensions(); + + if ((graphW < 0) || (graphH < 0)) + return false; + + double minDistanceX = double(MIN_DISTANCE) / double(graphW-1); + double minDistanceY = double(MIN_DISTANCE) / double(graphH-1); + + switch (event->type) { + case Gdk::CONFIGURE: { + // Happen when the the window is resized + if (sized & (RS_Pending | RS_Force)) { + set_size_request(-1, calcDimensions()); + sized = RS_Done; + } + retval = true; + break; + } + case Gdk::EXPOSE: + { + Glib::RefPtr win = get_window(); + if (sized & (RS_Pending | RS_Force)) { + set_size_request(-1, calcDimensions()); + } + sized = RS_Pending; + // setDrawRectangle will allocate the backbuffer Surface + if (setDrawRectangle(win, 0, 0, get_allocation().get_width(), get_allocation().get_height())) { + setDirty(true); + if (prevGraphW > 200 || graphW > 200) + curveIsDirty = true; + } + draw (lit_point); + GdkRectangle *rectangle = &(event->expose.area); + copySurface(win, rectangle); + + retval = true; + break; + } + + case Gdk::BUTTON_PRESS: + snapToElmt = -100; + if (curve.type!=DCT_Parametric) { + if (edited_point == -1) { + if (event->button.button == 1) { + std::vector::iterator itx, ity; + buttonPressed = true; + add_modal_grab (); + + // get the pointer position + getCursorPosition(Gdk::EventType(event->type), event->motion.is_hint!=0, int(event->button.x), int(event->button.y), Gdk::ModifierType(event->button.state)); + findClosestPoint(); + + new_type = CSMove; + if (distanceX > minDistanceX) { + if (mod_type & GDK_CONTROL_MASK) { + clampedY = point.getVal01(clampedX); + } + /* insert a new control point */ + if (num > 0) { + if (clampedX > curve.x.at(closest_point)) + ++closest_point; + } + itx = curve.x.begin(); + ity = curve.y.begin(); + for (int i=0; ibutton.button == 3) { + if (lit_point>-1 && grab_point==-1) { + if (!coordinateAdjuster->is_visible()) + coordinateAdjuster->showMe(this); + + edited_point = lit_point; + std::vector newBoundaries(2); + unsigned int size = curve.x.size(); + if (edited_point == 0) { newBoundaries.at(0).minVal = 0.; newBoundaries.at(0).maxVal = curve.x.at(1); } + else if (edited_point == size-1) { newBoundaries.at(0).minVal = curve.x.at(edited_point-1); newBoundaries.at(0).maxVal = 1.; } + else if (curve.x.size() > 2) { newBoundaries.at(0).minVal = curve.x.at(edited_point-1); newBoundaries.at(0).maxVal = curve.x.at(edited_point+1); } + newBoundaries.at(1).minVal = 0.; newBoundaries.at(1).maxVal = 1.; + editedPos.at(0) = curve.x.at(edited_point); + editedPos.at(1) = curve.y.at(edited_point); + coordinateAdjuster->setPos(editedPos); + coordinateAdjuster->startNumericalAdjustment(newBoundaries); + setDirty(true); + draw (lit_point); + new_type = CSArrow; + retval = true; + } + } + if (buttonPressed) retval = true; + } + else { // if (edited_point > -1) + if (event->button.button == 3) { + // do we edit another point? + if (edited_point>-1 && grab_point==-1) { + /* get the pointer position */ + getCursorPosition(Gdk::EventType(event->type), event->motion.is_hint!=0, int(event->button.x), int(event->button.y), Gdk::ModifierType(event->button.state)); + findClosestPoint(); + if (cursorX>=0 && cursorX<=graphW && cursorY>=0 && cursorY<=graphH) { + if (distanceX <= minDistanceX) { + // the cursor is close to an existing point + lit_point = closest_point; + if (lit_point != edited_point) { + edited_point = lit_point; + curveIsDirty = true; + setDirty(true); + draw (lit_point); + std::vector newBoundaries; + newBoundaries.resize(2); + unsigned int size = curve.x.size(); + if (edited_point == 0) { newBoundaries.at(0).minVal = 0.; newBoundaries.at(0).maxVal = curve.x.at(1); } + else if (edited_point == size-1) { newBoundaries.at(0).minVal = curve.x.at(edited_point-1); newBoundaries.at(0).maxVal = 1.; } + else if (curve.x.size() > 2) { newBoundaries.at(0).minVal = curve.x.at(edited_point-1); newBoundaries.at(0).maxVal = curve.x.at(edited_point+1); } + newBoundaries.at(1).minVal = 0.; newBoundaries.at(1).maxVal = 1.; + retval = true; + editedPos.at(0) = curve.x.at(edited_point); + editedPos.at(1) = curve.y.at(edited_point); + coordinateAdjuster->switchAdjustedPoint(editedPos, newBoundaries); + } + } + else { + // the cursor is inside the graph but away from existing points + new_type = CSPlus; + curveIsDirty = true; + stopNumericalAdjustment(); + } + } + retval = true; + } + } + } + retval = true; + } + break; + + case Gdk::BUTTON_RELEASE: + snapToElmt = -100; + if (curve.type!=DCT_Parametric && edited_point==-1) { + if (buttonPressed && event->button.button == 1) { + std::vector::iterator itx, ity; + int src, dst; + buttonPressed = false; + /* get the pointer position */ + getCursorPosition(Gdk::EventType(event->type), event->motion.is_hint!=0, int(event->button.x), int(event->button.y), Gdk::ModifierType(event->button.state)); + findClosestPoint(); + + remove_modal_grab (); + int previous_lit_point = lit_point; + /* delete inactive points: */ + itx = curve.x.begin(); + ity = curve.y.begin(); + for (src = dst = 0; src < num; ++src) + if (curve.x.at(src) >= 0.0) { + curve.x.at(dst) = curve.x.at(src); + curve.y.at(dst) = curve.y.at(src); + ++dst; + ++itx; + ++ity; + } + if (dst < src) { + curve.x.erase (itx, curve.x.end()); + curve.y.erase (ity, curve.y.end()); + if (curve.x.empty()) { + curve.x.push_back (0); + curve.y.push_back (0); + curveIsDirty = true; + setDirty(true); + draw (lit_point); + } + } + if (distanceX <= minDistanceX) { + new_type = CSMove; + lit_point = closest_point; + } + else { + new_type = CSPlus; + lit_point = -1; + } + if (lit_point != previous_lit_point) { + setDirty(true); + draw (lit_point); + } + grab_point = -1; + retval = true; + notifyListener (); + } + } + break; + + case Gdk::LEAVE_NOTIFY: + // Pointer can LEAVE even when dragging the point, so we don't modify the cursor in this case + // The cursor will have to LEAVE another time after the drag... + if (!buttonPressed) + if (grab_point == -1) { + new_type = CSArrow; + lit_point = -1; + pipetteR = pipetteG = pipetteB = -1.f; + setDirty(true); + draw (lit_point); + } + retval = true; + break; + + case Gdk::MOTION_NOTIFY: + snapToElmt = -100; + if (curve.type == DCT_Linear || curve.type == DCT_Spline || curve.type == DCT_NURBS) { + + snapToMinDistY = snapToMinDistX = 10.; + snapToValY = snapToValX = 0.; + snapToElmt = -100; + + // get the pointer position + getCursorPosition(Gdk::EventType(event->type), event->motion.is_hint!=0, int(event->button.x), int(event->button.y), Gdk::ModifierType(event->button.state)); + + if (grab_point == -1) { + if (edited_point==-1) { + // there's no point currently being moved + int previous_lit_point = lit_point; + findClosestPoint(); + if (cursorX<0 || cursorX>graphW || cursorY<0 || cursorY>graphH) { + // the cursor has left the graph area + new_type = CSArrow; + lit_point = -1; + } + else if (distanceX <= minDistanceX) { + // the cursor is close to an existing point + new_type = CSMove; + lit_point = closest_point; + } + else { + // the cursor is inside the graph but away from existing points + new_type = CSPlus; + lit_point = -1; + } + if (lit_point != previous_lit_point) { + setDirty(true); + draw (lit_point); + if (lit_point > -1) { + editedPos.at(0) = curve.x.at(lit_point); + editedPos.at(1) = curve.y.at(lit_point); + } + coordinateAdjuster->setPos(editedPos); + } + if (lit_point == -1 && new_type == CSPlus) { + editedPos.at(0) = clampedX; + editedPos.at(1) = clampedY; + coordinateAdjuster->setPos(editedPos); + } + } + else { // if (edited_point > -1) + // there's no point currently being moved + int previous_lit_point = lit_point; + findClosestPoint(); + if (distanceX <= minDistanceX) { + // the cursor is close to an existing point + lit_point = closest_point; + } + else { + // the cursor is outside the graph or inside the graph but away from existing points + lit_point = -1; + } + if (lit_point != previous_lit_point) { + setDirty(true); + draw (lit_point); + } + } + } + else { + // a point is being moved + + // bounds of the grabbed point + double leftBound = (grab_point == 0 ) ? 0. : curve.x.at(grab_point-1); + double rightBound = (grab_point == num-1) ? 1. : curve.x.at(grab_point+1); + double const bottomBound = 0.; + double const topBound = 1.; + + double leftDeletionBound = leftBound - minDistanceX; + double rightDeletionBound = rightBound + minDistanceX; + double bottomDeletionBound = bottomBound - minDistanceY; + double topDeletionBound = topBound + minDistanceY; + + // we memorize the previous position of the point, for optimization purpose + double prevPosX = curve.x.at(grab_point); + double prevPosY = curve.y.at(grab_point); + + // we memorize the previous position of the point, for optimization purpose + ugpX += deltaX; + ugpY += deltaY; + + // the unclamped grabbed point is brought back in the range when snapTo is active + if (snapTo) ugpY = CLAMP(ugpY, 0.0, 1.0); + + // handling limitations along X axis + if (ugpX >= rightDeletionBound && (grab_point > 0 && grab_point < (num-1))) { + curve.x.at(grab_point) = -1.; + } + else if (ugpX <= leftDeletionBound && (grab_point > 0 && grab_point < (num-1))) { + curve.x.at(grab_point) = -1.; + } + else + // nextPosX is in bounds + curve.x.at(grab_point) = CLAMP(ugpX, leftBound, rightBound); + + // Handling limitations along Y axis + if (ugpY >= topDeletionBound && grab_point != 0 && grab_point != num-1) { + curve.x.at(grab_point) = -1.; + } + else if (ugpY <= bottomDeletionBound && grab_point != 0 && grab_point != num-1) { + curve.x.at(grab_point) = -1.; + } + else { + // snapping point to specific values + if (snapTo && curve.x.at(grab_point) != -1.) { + if (grab_point > 0 && grab_point < (curve.y.size()-1)) { + double prevX = curve.x.at(grab_point-1); + double prevY = curve.y.at(grab_point-1); + double nextX = curve.x.at(grab_point+1); + double nextY = curve.y.at(grab_point+1); + + double ratio = (curve.x.at(grab_point)-prevX)/(nextX-prevX); + double y = (nextY-prevY) * ratio + prevY; + + if (snapCoordinateY(y, ugpY)) snapToElmt = 1000+grab_point; + } + if (grab_point > 0) { + int prevP = grab_point-1; + if (snapCoordinateY(curve.y.at(prevP), ugpY)) snapToElmt = prevP; + } + if (grab_point < (curve.y.size()-1)) { + int nextP = grab_point+1; + if (snapCoordinateY(curve.y.at(nextP), ugpY)) snapToElmt = nextP; + } + if (snapCoordinateY(1.0, ugpY)) snapToElmt = -3; + if (snapCoordinateY(curve.x.at(grab_point), ugpY)) snapToElmt = -2; + if (snapCoordinateY(0.0, ugpY)) snapToElmt = -1; + + curve.y.at(grab_point) = snapToValY; + } + else { + // nextPosY is in the bounds + curve.y.at(grab_point) = CLAMP(ugpY, 0.0, 1.0); + } + } + + if (curve.x.at(grab_point) != prevPosX || curve.y.at(grab_point) != prevPosY) { + // we recalculate the curve only if we have to + curveIsDirty = true; + setDirty(true); + draw (lit_point); + notifyListener (); + + if (coordinateAdjuster->is_visible()) { + editedPos.at(0) = curve.x.at(grab_point); + editedPos.at(1) = curve.y.at(grab_point); + coordinateAdjuster->setPos(editedPos); + } + } + } + } + + retval = true; + break; + + default: + break; + } + if (new_type != cursor_type) { + cursor_type = new_type; + cursorManager.setCursor(cursor_type); + } + return retval; +} + +CursorShape MyDiagonalCurve::motionNotify(CursorShape type, double minDistanceX, double minDistanceY, int num) { + CursorShape new_type = type; + + return new_type; +} + +void MyDiagonalCurve::pipetteMouseOver (CurveEditor *ce, EditDataProvider *provider, int modifierKey) { + if (!provider) { + // occurs when leaving the preview area -> cleanup the curve editor + pipetteR = pipetteG = pipetteB = -1.f; + lit_point = -1; + return; + } + + pipetteR = provider->pipetteVal[0]; + pipetteG = provider->pipetteVal[1]; + pipetteB = provider->pipetteVal[2]; + pipetteVal = 0.f; + if (listener) { + pipetteVal = listener->blendPipetteValues(ce, pipetteR, pipetteG, pipetteB); + } + else { + int n = 0; + if (pipetteR != -1.f) { + pipetteVal += pipetteR; + ++n; + } + if (pipetteG != -1.f) { + pipetteVal += pipetteG; + ++n; + } + if (pipetteB != -1.f) { + pipetteVal += pipetteB; + ++n; + } + if (n>1) + pipetteVal /= n; + else if (!n) + pipetteVal = -1.f; + } + + /* graphW and graphH are the size of the graph */ + calcDimensions(); + + if ((graphW < 0) || (graphH < 0)) + return; + + double minDistanceX = double(MIN_DISTANCE) / double(graphW-1); + + if (curve.type == DCT_Linear || curve.type == DCT_Spline || curve.type == DCT_NURBS) { + // get the pointer position + getCursorPositionFromCurve(pipetteVal); + + if (edited_point==-1) { + if (grab_point == -1) { + // there's no point currently being moved + int previous_lit_point = lit_point; + findClosestPoint(); + if (cursorX<0 || cursorX>graphW || cursorY<0 || cursorY>graphH) { + // the cursor has left the graph area + lit_point = -1; + } + else if (distanceX <= minDistanceX) { + lit_point = closest_point; + } + else { + lit_point = -1; + } + if (lit_point != previous_lit_point) { + setDirty(true); + draw (lit_point); + } + } + } + else + draw(lit_point); + + if (edited_point==-1) { + editedPos.at(0) = pipetteVal; + editedPos.at(1) = point.getVal01(pipetteVal); + coordinateAdjuster->setPos(editedPos); + } + } +} + + +void MyDiagonalCurve::pipetteButton1Pressed(EditDataProvider *provider, int modifierKey) { + if (edited_point>1) + return; + + int num = (int)curve.x.size(); + + /* graphW and graphH are the size of the graph */ + calcDimensions(); + + double minDistanceX = double(MIN_DISTANCE) / double(graphW-1); + + if ((graphW < 0) || (graphH < 0)) + return; + + snapToElmt = -100; + if (curve.type!=DCT_Parametric) { + std::vector::iterator itx, ity; + buttonPressed = true; + + // get the pointer position + getCursorPositionFromCurve(pipetteVal); + findClosestPoint(); + + if (distanceX > minDistanceX) { + /* insert a new control point */ + if (num > 0) { + if (clampedX > curve.x.at(closest_point)) + ++closest_point; + } + itx = curve.x.begin(); + ity = curve.y.begin(); + for (int i=0; i-1 && grab_point==-1 && coordinateAdjuster->is_visible()) { + std::vector position; + position.resize(2); + position.at(0) = clampedX; + position.at(1) = clampedY; + coordinateAdjuster->setPos(position); + } + + curveIsDirty = true; + setDirty(true); + draw (lit_point); + notifyListener (); + } + grab_point = closest_point; + lit_point = closest_point; + ugpX = curve.x.at(closest_point); + ugpY = curve.y.at(closest_point); + } +} + +void MyDiagonalCurve::pipetteButton1Released(EditDataProvider *provider) { + if (edited_point>1) + return; + + /* graphW and graphH are the size of the graph */ + calcDimensions(); + + double minDistanceX = double(MIN_DISTANCE) / double(graphW-1); + //double minDistanceY = double(MIN_DISTANCE) / double(graphH-1); + + if ((graphW < 0) || (graphH < 0)) + return; + + snapToElmt = -100; + if (curve.type!=DCT_Parametric) { + std::vector::iterator itx, ity; + buttonPressed = false; + /* get the pointer position */ + getCursorPosition(Gdk::EventType(Gdk::BUTTON_RELEASE), false, graphY, 0, Gdk::ModifierType(0)); + findClosestPoint(); + + int previous_lit_point = lit_point; + + if (distanceX <= minDistanceX) { + lit_point = closest_point; + } + else { + lit_point = -1; + } + if (lit_point != previous_lit_point) { + setDirty(true); + draw (lit_point); + } + grab_point = -1; + //notifyListener (); + } +} + +void MyDiagonalCurve::pipetteDrag(EditDataProvider *provider, int modifierKey) { + if (edited_point>-1 || curve.type==DCT_Parametric || graphW<0 || graphH<0) + return; + + snapToMinDistY = snapToMinDistX = 10.; + snapToValY = snapToValX = 0.; + snapToElmt = -100; + + /* graphW and graphH are the size of the graph */ + calcDimensions(); + + getCursorPosition(Gdk::MOTION_NOTIFY, false, cursorX+graphX, graphY-cursorY+provider->deltaPrevScreen.y, Gdk::ModifierType(modifierKey)); + + // we memorize the previous position of the point, for optimization purpose + double prevPosX = curve.x.at(grab_point); + double prevPosY = curve.y.at(grab_point); + + // we memorize the previous position of the point, for optimization purpose + ugpX += deltaX; + ugpY += deltaY; + + // the unclamped grabbed point is brought back in the range + ugpY = CLAMP(ugpY, 0.0, 1.0); + + // snapping point to specific values + if (snapTo && curve.x.at(grab_point) != -1.) { + if (grab_point > 0 && grab_point < (curve.y.size()-1)) { + double prevX = curve.x.at(grab_point-1); + double prevY = curve.y.at(grab_point-1); + double nextX = curve.x.at(grab_point+1); + double nextY = curve.y.at(grab_point+1); + + double ratio = (curve.x.at(grab_point)-prevX)/(nextX-prevX); + double y = (nextY-prevY) * ratio + prevY; + + if (snapCoordinateY(y, ugpY)) snapToElmt = 1000+grab_point; + } + if (grab_point > 0) { + int prevP = grab_point-1; + if (snapCoordinateY(curve.y.at(prevP), ugpY)) snapToElmt = prevP; + } + if (grab_point < (curve.y.size()-1)) { + int nextP = grab_point+1; + if (snapCoordinateY(curve.y.at(nextP), ugpY)) snapToElmt = nextP; + } + if (snapCoordinateY(1.0, ugpY)) snapToElmt = -3; + if (snapCoordinateY(curve.x.at(grab_point), ugpY)) snapToElmt = -2; + if (snapCoordinateY(0.0, ugpY)) snapToElmt = -1; + + curve.y.at(grab_point) = snapToValY; + } + else { + // nextPosY is in the bounds + curve.y.at(grab_point) = ugpY; + } + + if (curve.x.at(grab_point) != prevPosX || curve.y.at(grab_point) != prevPosY) { + // we recalculate the curve only if we have to + curveIsDirty = true; + setDirty(true); + draw (lit_point); + notifyListener (); + + if (lit_point>-1 && coordinateAdjuster->is_visible()) { + std::vector position; + position.resize(2); + position.at(0) = curve.x.at(grab_point); + position.at(1) = curve.y.at(grab_point); + coordinateAdjuster->setPos(position); + } + + } +} + +void MyDiagonalCurve::getCursorPositionFromCurve(float x) { + + // the graph is refreshed only if a new point is created (snaped to a pixel) + clampedX = x; + clampedY = point.getVal01(x); + + cursorX = int(clampedX*float(graphW-3)) + graphX+1.5; + cursorY = graphY - int(clampedY*float(graphH-3)); +} + +// x = cursor position found in the event +void MyDiagonalCurve::getCursorPositionFromCurve(int x) { + + // the graph is refreshed only if a new point is created (snaped to a pixel) + cursorX = x-graphX; + clampedX = (float(cursorX)-1.5) / float(graphW-3); + clampedY = point.getVal01(clampedX); + cursorY = graphY - int(float(1.-clampedY)*float(graphH-3)); +} + +void MyDiagonalCurve::getCursorPosition(Gdk::EventType evType, bool isHint, int evX, int evY, Gdk::ModifierType modifierKey) { + int tx, ty; + int prevCursorX, prevCursorY; + double incrementX = 1. / double(graphW); + double incrementY = 1. / double(graphH); + + // getting the cursor position + switch (evType) { + case (Gdk::MOTION_NOTIFY) : + if (isHint) { + get_window()->get_pointer (tx, ty, mod_type); + } + else { + tx = evX; + ty = evY; + mod_type = modifierKey; + } + break; + case (Gdk::BUTTON_PRESS) : + case (Gdk::BUTTON_RELEASE) : + tx = evX; + ty = evY; + mod_type = modifierKey; + break; + default : + // The cursor position is not available + return; + break; + } + + if (grab_point != -1) { + prevCursorX = cursorX; + prevCursorY = cursorY; + } + cursorX = tx - graphX; + cursorY = graphY - ty; + + snapTo = ST_None; + + // update deltaX/Y if the user drags a point + if (grab_point != -1) { + // set the dragging factor + int control_key = mod_type & GDK_CONTROL_MASK; + int shift_key = mod_type & GDK_SHIFT_MASK; + + // the increment get smaller if modifier key are used, and "snap to" may be enabled + if (control_key) { incrementX *= 0.05; incrementY *= 0.05; } + if (shift_key) { snapTo = true; } + + deltaX = double(cursorX - prevCursorX) * incrementX; + deltaY = double(cursorY - prevCursorY) * incrementY; + } + // otherwise set the position of the new point (modifier keys has no effect here) + else { + double tempCursorX = cursorX * incrementX; + double tempCursorY = cursorY * incrementY; + clampedX = CLAMP (tempCursorX, 0., 1.); // X position of the pointer from the origin of the graph + clampedY = CLAMP (tempCursorY, 0., 1.); // Y position of the pointer from the origin of the graph + } + +} + +void MyDiagonalCurve::findClosestPoint() { + distanceX = 10.0; distanceY = 10.0; + closest_point = -1; + + if (curve.type!=DCT_Parametric) { + for (int i = 0; i < (int)curve.x.size(); i++) { + double dX = curve.x.at(i) - clampedX; + double dY = curve.y.at(i) - clampedY; + double currDistX = dX < 0. ? -dX : dX; //abs (dX); + double currDistY = dY < 0. ? -dY : dY; //abs (dY); + if (currDistX < distanceX) { + distanceX = currDistX; + distanceY = currDistY; + closest_point = i; + } + else if (currDistX == distanceX && currDistY < distanceY) { + // there is more than 1 point for that X coordinate, we select the closest point to the cursor + distanceY = currDistY; + closest_point = i; + } + } + } +} + +std::vector MyDiagonalCurve::getPoints () { + std::vector result; + if (curve.type==DCT_Parametric) { + result.push_back ((double)(DCT_Parametric)); + for (int i=0; i<(int)curve.x.size(); i++) { + result.push_back (curve.x.at(i)); + } + } + else { + // the first value gives the type of the curve + if (curve.type==DCT_Linear) + result.push_back (double(DCT_Linear)); + else if (curve.type==DCT_Spline) + result.push_back (double(DCT_Spline)); + else if (curve.type==DCT_NURBS) + result.push_back (double(DCT_NURBS)); + // then we push all the points coordinate + for (int i=0; i<(int)curve.x.size(); i++) { + if (curve.x.at(i)>=0) { + result.push_back (curve.x.at(i)); + result.push_back (curve.y.at(i)); + } + } + } + return result; +} + +void MyDiagonalCurve::setPoints (const std::vector& p) { + int ix = 0; + stopNumericalAdjustment(); + DiagonalCurveType t = (DiagonalCurveType)p[ix++]; + curve.type = t; + if (t==DCT_Parametric) { + curve.x.clear (); + curve.y.clear (); + for (size_t i=1; i -1); + if (chanIdx == 0) { + curve.x.at(edited_point) = pos; + } + else if (chanIdx == 1) { + curve.y.at(edited_point) = pos; + } + curveIsDirty = true; + setDirty(true); + draw(lit_point); + notifyListener (); +} + +void MyDiagonalCurve::stopNumericalAdjustment() { + if (edited_point>-1) { + edited_point = grab_point = lit_point = -1; + coordinateAdjuster->stopNumericalAdjustment(); + setDirty(true); + draw(lit_point); + } +} + +void MyDiagonalCurve::setType (DiagonalCurveType t) { + + curve.type = t; + setDirty(true); +} + +void MyDiagonalCurve::setActiveParam (int ac) { + + activeParam = ac; + setDirty(true); + queue_draw (); +} + +int diagonalmchistupdateUI (void* data) { + + MyCurveIdleHelper* mcih = static_cast(data); + + if (mcih->destroyed) { + if (mcih->pending == 1) + delete mcih; + else + mcih->pending--; + + return 0; + } + + mcih->clearPixmap (); + mcih->myCurve->queue_draw (); + + mcih->pending--; + + return 0; +} + +void MyDiagonalCurve::updateBackgroundHistogram (LUTu & hist) { + + if (hist) { + //memcpy (bghist, hist, 256*sizeof(unsigned int)); + for (int i=0; i<256; i++) bghist[i]=hist[i]; + //hist = bghist; + bghistvalid = true; + } + else + bghistvalid = false; + + mcih->pending++; + // Can be done outside of the GUI thread + g_idle_add (diagonalmchistupdateUI, mcih); + +} + +void MyDiagonalCurve::reset(const std::vector &resetCurve, double identityValue) { + + stopNumericalAdjustment(); + + if (!resetCurve.empty()) { + setPoints(resetCurve); + return; + } + + switch (curve.type) { + case DCT_Spline : + case DCT_NURBS : + curve.x.resize(2); + curve.y.resize(2); + curve.x.at(0) = 0.; + curve.y.at(0) = 0.; + curve.x.at(1) = 1.; + curve.y.at(1) = 1.; + grab_point = -1; + lit_point = -1; + curveIsDirty = true; + break; + case DCT_Parametric : + curve.x.resize(7); + curve.y.clear(); + // the SHCSelector values doesn't really matter for the identity curve display + curve.x.at(0) = 0.25; + curve.x.at(1) = 0.50; + curve.x.at(2) = 0.75; + curve.x.at(3) = 0.00; + curve.x.at(4) = 0.00; + curve.x.at(5) = 0.00; + curve.x.at(6) = 0.00; + grab_point = -1; // not sure that it's necessary + lit_point = -1; // not sure that it's necessary + curveIsDirty = true; + break; + default: + break; + } + setDirty(true); + draw(-1); +} diff --git a/rtgui/mydiagonalcurve.h b/rtgui/mydiagonalcurve.h new file mode 100644 index 000000000..881a568d1 --- /dev/null +++ b/rtgui/mydiagonalcurve.h @@ -0,0 +1,99 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _MYDIAGONALCURVE_ +#define _MYDIAGONALCURVE_ + +#include +#include +#include "curvelistener.h" +#include "cursormanager.h" +#include "mycurve.h" +#include "../rtengine/LUT.h" + + +// For compatibility and simplicity reason, order shouldn't change, and must be identical to the order specified in the curveType widget +enum DiagonalCurveType { + DCT_Empty = -1, // Also used for identity curves + DCT_Linear, // 0 + DCT_Spline, // 1 + DCT_Parametric, // 2 + DCT_NURBS, // 3 + // Insert new curve type above this line + DCT_Unchanged // Must remain the last of the enum +}; + +class DiagonalCurveDescr { + + public: + DiagonalCurveType type; + std::vector x, y; // in case of parametric curves the curve parameters are stored in vector x. In other cases these vectors store the coordinates of the bullets. +}; + +class MyDiagonalCurve : public MyCurve { + + protected: + DiagonalCurveDescr curve; + int grab_point; // the point that the user is moving by mouse + int closest_point; // the point that is the closest from the cursor + int lit_point; // the point that is lit when the cursor is near it + double clampedX; // clamped grabbed point X coordinates in the [0;1] range + double clampedY; // clamped grabbed point Y coordinates in the [0;1] range + double deltaX; // signed X distance of the cursor between two consecutive MOTION_NOTIFY + double deltaY; // signed Y distance of the cursor between two consecutive MOTION_NOTIFY + double distanceX; // X distance from the cursor to the closest point + double distanceY; // Y distance from the cursor to the closest point + double ugpX; // unclamped grabbed point X coordinate in the graph + double ugpY; // unclamped grabbed point Y coordinate in the graph + int activeParam; + unsigned int* bghist; // histogram values + bool bghistvalid; + + void draw (int handle); + void interpolate (); + void findClosestPoint(); + CursorShape motionNotify(CursorShape type, double minDistanceX, double minDistanceY, int num); + std::vector get_vector (int veclen); + void get_LUT (LUTf &lut); + // Get the cursor position and unclamped position from the curve given an X value ; BEWARE: can be time consuming, use with care + void getCursorPositionFromCurve(float x); + void getCursorPositionFromCurve(int x); + // Get the cursor position and unclamped value depending on cursor's position in the graph + void getCursorPosition(Gdk::EventType evType, bool isHint, int evX, int evY, Gdk::ModifierType modifierKey); + + public: + MyDiagonalCurve (); + ~MyDiagonalCurve (); + std::vector getPoints (); + void setPoints (const std::vector& p); + void setType (DiagonalCurveType t); + bool handleEvents (GdkEvent* event); + void setActiveParam (int ac); + void reset (const std::vector &resetCurve, double identityValue=0.5); + void updateBackgroundHistogram (LUTu & hist); + + void pipetteMouseOver (CurveEditor *ce, EditDataProvider *provider, int modifierKey); + void pipetteButton1Pressed(EditDataProvider *provider, int modifierKey); + void pipetteButton1Released(EditDataProvider *provider); + void pipetteDrag(EditDataProvider *provider, int modifierKey); + + virtual void setPos(double pos, int chanIdx); + virtual void stopNumericalAdjustment(); +}; + +#endif diff --git a/rtgui/myflatcurve.cc b/rtgui/myflatcurve.cc new file mode 100644 index 000000000..77678eb03 --- /dev/null +++ b/rtgui/myflatcurve.cc @@ -0,0 +1,1718 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "myflatcurve.h" +#include "../rtengine/curves.h" +#include +#include + +MyFlatCurve::MyFlatCurve () { + + graphW = get_allocation().get_width() - RADIUS * 2; + graphH = get_allocation().get_height() - RADIUS * 2; + prevGraphW = graphW; + prevGraphH = graphH; + lit_point = -1; + closest_point = 0; + buttonPressed = false; + editedHandle = FCT_EditedHandle_None; + area = FCT_Area_None; + tanHandlesDisplayed = false; + periodic = true; + + //bghist = new unsigned int[256]; + + editedPos.resize(4); + editedPos.at(0) = editedPos.at(1) = editedPos.at(2) = editedPos.at(3) = 0.0; + + signal_event().connect( sigc::mem_fun(*this, &MyFlatCurve::handleEvents) ); + + // By default, we create a curve with 8 control points + curve.type = FCT_MinMaxCPoints; + + defaultCurve(); +} + +/*MyFlatCurve::~MyFlatCurve () { +}*/ + +std::vector MyFlatCurve::get_vector (int veclen) { + + // Create the output variable + std::vector convertedValues; + + // Get the curve control points + std::vector curveDescr = getPoints (); + rtengine::FlatCurve rtcurve(curveDescr, periodic, veclen*1.2 > 5000 ? 5000 : veclen*1.2); + + // Create the sample values that will be converted + std::vector samples; + samples.resize (veclen); + for (int i = 0; i < veclen; i++) + samples.at(i) = (double) i / (veclen - 1.0); + + // Converting the values + rtcurve.getVal (samples, convertedValues); + + // Cleanup and return + return convertedValues; +} + +void MyFlatCurve::get_LUT (LUTf &lut) { + + int size = lut.getSize(); + + // Get the curve control points + std::vector curveDescr = getPoints (); + rtengine::FlatCurve rtcurve(curveDescr, periodic, lut.getUpperBound()*1.2 > 5000 ? 5000 : lut.getUpperBound()*1.2); + + double t; + double maxVal = double(lut.getUpperBound()); + for (int i = 0; i < size; i++) { + t = double(i) / maxVal; + lut[i] = rtcurve.getVal (t); + } + return; +} + +void MyFlatCurve::interpolate () { + + prevGraphW = graphW; + prevGraphH = graphH; + int nbPoints = graphW-2; + point(nbPoints); + get_LUT (point); + upoint.reset (); + lpoint.reset (); + + curveIsDirty = false; +} + +void MyFlatCurve::draw () { + if (!isDirty()) { + return; + } + + Glib::RefPtr win = get_window(); + if (!surfaceCreated() || !win) + return; + + // re-calculate curve if dimensions changed + int currPointSize = point.getUpperBound(); + if (curveIsDirty || /*prevGraphW != graphW || prevGraphH != graphH ||*/ (currPointSize==200 && (graphW-3>200)) || (currPointSize>200 && (graphW-2<=200 || graphW-3!=currPointSize))) + interpolate (); + + double innerW = double(graphW-2); + double innerH = double(graphH-2); + + Gtk::StateType state = !is_sensitive() ? Gtk::STATE_INSENSITIVE : Gtk::STATE_NORMAL; + + Glib::RefPtr style = get_style (); + Cairo::RefPtr cr = getContext(); + cr->set_line_cap(Cairo::LINE_CAP_SQUARE); + + // clear background + Gdk::Color c = style->get_bg (Gtk::STATE_NORMAL); + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + cr->rectangle (0, 0, double(getWidth()), double(getHeight())); + cr->fill (); + + cr->set_line_width (1.0); + + // draw f(x)=0.5 line + c = style->get_dark (state); + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + std::valarray ds (1); + ds[0] = 4; + cr->set_dash (ds, 0); + cr->move_to (double(graphX)+1.5, double(graphY-graphH/2)-0.5); + cr->rel_line_to (double(graphW-3), 0.); + cr->stroke (); + + cr->unset_dash (); + + cr->set_antialias (Cairo::ANTIALIAS_SUBPIXEL); + + cr->set_line_width (1.0); + + // draw the left colored bar + if (leftBar) { + // first the background + int bWidth = getBarWidth(); + BackBuffer *bb = this; + leftBar->setDrawRectangle(win, 1, graphY-graphH+1, bWidth-2, graphH-2); + leftBar->expose(bb); + + // now the border + c = style->get_dark (state); + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + cr->rectangle(0.5, graphY-graphH+0.5, bWidth-1, graphH-1); + cr->stroke(); + } + + // draw the bottom colored bar + if (bottomBar) { + // first the background + int bWidth = getBarWidth(); + BackBuffer *bb = this; + bottomBar->setDrawRectangle(win, graphX+1, graphY+CBAR_MARGIN+1, graphW-2, bWidth-2); + bottomBar->expose(bb); + + // now the border + c = style->get_dark (state); + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + cr->rectangle(graphX+0.5, graphY+CBAR_MARGIN+0.5, graphW-1, bWidth-1 ); + cr->stroke(); + } + + cr->set_line_cap(Cairo::LINE_CAP_BUTT); + + // draw the pipette values + if (pipetteR > -1.f || pipetteG > -1.f || pipetteB > -1.f) { + cr->set_line_width (0.75); + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + int n=0; + if (pipetteR > -1.f) ++n; + if (pipetteG > -1.f) ++n; + if (pipetteB > -1.f) ++n; + + if (n > 1) { + if (pipetteR > -1.f) { + cr->set_source_rgba (1., 0., 0., 0.5); // WARNING: assuming that red values are stored in pipetteR, which might not be the case! + cr->move_to (double(graphX)+1.5 + double(graphW-3)*pipetteR, double(graphY)-1.5); + cr->rel_line_to (0, double(-graphH+3)); + cr->stroke (); + } + if (pipetteG > -1.f) { + cr->set_source_rgba (0., 1., 0., 0.5); // WARNING: assuming that green values are stored in pipetteG, which might not be the case! + cr->move_to (double(graphX)+1.5 + double(graphW-3)*pipetteG, double(graphY)-1.5); + cr->rel_line_to (0, double(-graphH+3)); + cr->stroke (); + } + if (pipetteB > -1.f) { + cr->set_source_rgba (0., 0., 1., 0.5); // WARNING: assuming that blue values are stored in pipetteB, which might not be the case! + cr->move_to (double(graphX)+1.5 + double(graphW-3)*pipetteB, double(graphY)-1.5); + cr->rel_line_to (0, double(-graphH+3)); + cr->stroke (); + } + } + if (pipetteVal > -1.f) { + cr->set_line_width (2.); + c = style->get_fg (state); + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + cr->move_to (double(graphX)+1.5 + double(graphW-3)*pipetteVal, double(graphY)-1.5); + cr->rel_line_to (0, double(-graphH+3)); + cr->stroke (); + cr->set_line_width (1.); + } + } + + // draw the color feedback of the control points + if (colorProvider) { + + //if (curve.type!=FCT_Parametric) + for (int i=0; i<(int)curve.x.size(); ++i) { + + if (curve.x.at(i) != -1.) { + int coloredLineWidth = min( max(75,graphW)/75, 8 ); + + cr->set_line_width (coloredLineWidth); + colorProvider->colorForValue(curve.x.at(i), curve.y.at(i), CCET_VERTICAL_BAR, colorCallerId, this); + cr->set_source_rgb (ccRed, ccGreen, ccBlue); + + if ( i==lit_point && (editedHandle&(FCT_EditedHandle_CPointUD|FCT_EditedHandle_CPoint|FCT_EditedHandle_CPointX)) ) { + cr->set_line_width (2*coloredLineWidth); + } + cr->move_to (double(graphX)+1 + innerW*curve.x.at(i), double(graphY-1)); + cr->rel_line_to (0., -innerH); + cr->stroke (); + cr->set_line_width (coloredLineWidth); + + // draw the lit_point's horizontal line + bool drawHLine = false; + if (edited_point>-1) { + if (i == edited_point) { + cr->set_line_width (2*coloredLineWidth); + drawHLine = true; + } + } + else if (i == lit_point) { + if ( (area&(FCT_Area_H|FCT_Area_V|FCT_Area_Point)) || editedHandle==FCT_EditedHandle_CPointUD) { + if (editedHandle&(FCT_EditedHandle_CPointUD|FCT_EditedHandle_CPoint|FCT_EditedHandle_CPointY)) { + cr->set_line_width (2*coloredLineWidth); + drawHLine = true; + } + } + } + if (drawHLine) { + int point = edited_point>-1 ? edited_point : lit_point; + colorProvider->colorForValue(curve.x.at(i), curve.y.at(i), CCET_HORIZONTAL_BAR, colorCallerId, this); + cr->set_source_rgb (ccRed, ccGreen, ccBlue); + + cr->move_to (double(graphX+1) , double(graphY-1) - innerH*curve.y.at(point)); + cr->rel_line_to (innerW, 0.); + cr->stroke (); + } + } + } + // endif + cr->set_line_width (1.0); + } + else { + cr->set_source_rgb (0.5, 0.0, 0.0); + + if (edited_point>-1 || ((lit_point>-1) && ((area&(FCT_Area_H|FCT_Area_V|FCT_Area_Point)) || editedHandle==FCT_EditedHandle_CPointUD)) ) { + // draw the lit_point's vertical line + if (edited_point>-1 || (editedHandle&(FCT_EditedHandle_CPointUD|FCT_EditedHandle_CPoint|FCT_EditedHandle_CPointY))) { + cr->set_line_width (2.0); + } + int point = edited_point>-1 ? edited_point : lit_point; + cr->move_to (double(graphX)+1 + innerW*curve.x.at(point), double(graphY-1)); + cr->rel_line_to (0., -innerH); + cr->stroke (); + cr->set_line_width (1.0); + + // draw the lit_point's horizontal line + if (editedHandle&(FCT_EditedHandle_CPointUD|FCT_EditedHandle_CPoint|FCT_EditedHandle_CPointY)) { + cr->set_line_width (2.0); + } + cr->move_to (double(graphX+1) , double(graphY-1) - innerH*curve.y.at(point)); + cr->rel_line_to (innerW, 0.); + cr->stroke (); + cr->set_line_width (1.0); + } + } + + cr->set_line_cap(Cairo::LINE_CAP_SQUARE); + + // draw the graph's borders: + c = style->get_dark (state); + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + cr->rectangle(double(graphX)+0.5, double(graphY)-0.5, double(graphW-1), double(-graphH+1)); + cr->stroke (); + + double lineMinLength = 1. / graphW * SQUARE * 0.9; + if (tanHandlesDisplayed && lit_point!=-1 && getHandles(lit_point) && curve.x.at(lit_point)!=-1.) { + double x = double(graphX+1) + innerW*curve.x.at(lit_point); + double y = double(graphY) - innerH*curve.y.at(lit_point); + double x2; + double square; + bool crossingTheFrame; + + // left handle is yellow + // TODO: finding a way to set the left handle color for flat curve editor + cr->set_source_rgb (1.0, 1.0, 0.0); + + // draw tangential vectors + + crossingTheFrame = false; + // We display the line only if it's longer than the handle knot half-size... + if (leftTanX < -0.00001) { + leftTanX += 1.0; + crossingTheFrame = true; + } + x2 = double(graphX+1) + innerW*leftTanX; + if (curve.x.at(lit_point) - leftTanX > lineMinLength || crossingTheFrame) { + // The left tangential vector reappear on the right side + // draw the line + cr->move_to (x, y); + if (crossingTheFrame) { + cr->line_to (double(graphX+1), y); + cr->stroke (); + cr->move_to (double(graphX) + innerW, y); + } + cr->line_to (x2, y); + cr->stroke (); + } + // draw tangential knot + square = area == FCT_Area_LeftTan ? SQUARE*2. : SQUARE; + cr->rectangle(x2-square, y-square, 2.*square, 2.*square); + cr->fill(); + + // right handle is blue + // TODO: finding a way to set the right handle color for flat curve editor + cr->set_source_rgb (0.0, 0.0, 1.0); + + // draw tangential vectors + + crossingTheFrame = false; + // We display the line only if it's longer than the handle knot half-size... + if (rightTanX > 1.00001) { + rightTanX -= 1.0; + crossingTheFrame = true; + } + x2 = double(graphX+1) +innerW*rightTanX; + if (rightTanX - curve.x.at(lit_point) > lineMinLength || crossingTheFrame) { + // The left tangential vector reappear on the right side + // draw the line + cr->move_to (x, y); + if (crossingTheFrame) { + cr->line_to (double(graphX) + innerW, y); + cr->stroke (); + cr->move_to (double(graphX+1), y); + } + cr->line_to (x2, y); + cr->stroke (); + } + // draw tangential knot + square = area == FCT_Area_RightTan ? SQUARE*2. : SQUARE; + cr->rectangle(x2-square, y-square, 2.*square, 2.*square); + cr->fill(); + } + + // draw curve + c = style->get_fg (state); + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + float graphH_ = float(graphH-3); + float graphX_ = float(graphX)+1.5; + float graphY_ = float(graphY)-1.5; + cr->move_to (graphX_, getVal(point, 0)*-graphH_+graphY_); + for (int i=1; iline_to (float(i)+graphX_, getVal(point, i)*-graphH_+graphY_); + cr->stroke (); + + // draw bullets + //if (curve.type!=FCT_Parametric) + for (int i = 0; i < (int)curve.x.size(); ++i) { + if (curve.x.at(i) != -1.) { + if (i == edited_point) + cr->set_source_rgb (1.0, 0.0, 0.0); + else if (i == lit_point) { + if (colorProvider && edited_point==-1) { + colorProvider->colorForValue(curve.x.at(i), curve.y.at(i), CCET_POINT, colorCallerId, this); + cr->set_source_rgb (ccRed, ccGreen, ccBlue); + } + else + cr->set_source_rgb (1.0, 0.0, 0.0); + } + else if (i == snapToElmt || i == edited_point) + cr->set_source_rgb (1.0, 0.0, 0.0); + else if (curve.y.at(i) == 0.5) + cr->set_source_rgb (0.0, 0.5, 0.0); + else + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + + double x = double(graphX+1) + innerW * curve.x.at(i); // project (curve.x.at(i), 0, 1, graphW); + double y = double(graphY-1) - innerH * curve.y.at(i); // project (curve.y.at(i), 0, 1, graphH); + + cr->arc (x, y, (double)RADIUS, 0, 2*M_PI); + cr->fill (); + + if (i == edited_point) { + cr->set_source_rgb (1.0, 0.0, 0.0); + cr->set_line_width(2.); + cr->arc (x, y, RADIUS+3.5, 0, 2*M_PI); + cr->stroke(); + cr->set_line_width(1.); + } + + } + } + // endif + + // draw the left and right tangent handles + if (tanHandlesDisplayed) { + double halfSquareSizeX = minDistanceX/2.; + double halfSquareSizeY = minDistanceY/2.; + + // LEFT handle + + // yellow + cr->set_source_rgb (1.0, 1.0, 0.0); + cr->rectangle(double(graphX+1) + innerW*(leftTanHandle.centerX-halfSquareSizeX), + double(graphY-1) - innerH*(leftTanHandle.centerY+halfSquareSizeY), + innerW*minDistanceX, + innerW*minDistanceY); + cr->fill(); + + // RIGHT handle + + // blue + cr->set_source_rgb (0.0, 0.0, 1.0); + cr->rectangle(double(graphX+1) + innerW*(rightTanHandle.centerX-halfSquareSizeX), + double(graphY-1) - innerH*(rightTanHandle.centerY+halfSquareSizeY), + innerW*minDistanceX, + innerW*minDistanceY); + cr->fill(); + } + + setDirty(false); + queue_draw(); +} + +/* + * Return the X1, X2, Y position of the tangential handles. + */ +bool MyFlatCurve::getHandles(int n) { + int N = curve.x.size(); + double prevX, nextX; + double x, leftTan, rightTan; + + if (n == -1) return false; + + x = curve.x.at(n); + leftTan = curve.leftTangent.at(n); + rightTan = curve.rightTangent.at(n); + + if (!n) { + // first point, the left handle is then computed with the last point's right handle + prevX = curve.x.at(N-1)-1.0; + nextX = curve.x.at(n+1); + } + else if (n == N-1) { + // last point, the right handle is then computed with the first point's left handle + prevX = curve.x.at(n-1); + nextX = curve.x.at(0)+1.0; + } + else { + // last point, the right handle is then computed with the first point's left handle + prevX = curve.x.at(n-1); + nextX = curve.x.at(n+1); + } + + if (leftTan == 0.0) leftTanX = x; + else if (leftTan == 1.0) leftTanX = prevX; + else { + leftTanX = (prevX - x) * leftTan + x; + } + + if (rightTan == 0.0) rightTanX = x; + else if (rightTan == 1.0) rightTanX = nextX; + else { + rightTanX = (nextX - x) * rightTan + x; + } + return true; +} + +bool MyFlatCurve::handleEvents (GdkEvent* event) { + + CursorShape new_type = cursor_type; + std::vector::iterator itx, ity, itlt, itrt; + + snapToElmt = -100; + bool retval = false; + int num = (int)curve.x.size(); + + /* graphW and graphH are the size of the graph */ + calcDimensions(); + + if ((graphW < 0) || (graphH < 0)) + return false; + + minDistanceX = double(MIN_DISTANCE) / double(graphW-1); + minDistanceY = double(MIN_DISTANCE) / double(graphH-1); + + switch (event->type) { + case Gdk::CONFIGURE: { + // Happen when the the window is resized + if (sized & (RS_Pending | RS_Force)) { + set_size_request(-1, calcDimensions()); + sized = RS_Done; + } + retval = true; + break; + } + case Gdk::EXPOSE: + { + Glib::RefPtr win = get_window(); + if (sized & (RS_Pending | RS_Force)) { + set_size_request(-1, calcDimensions()); + } + sized = RS_Pending; + // setDrawRectangle will allocate the backbuffer Surface + if (setDrawRectangle(win, 0, 0, get_allocation().get_width(), get_allocation().get_height())) { + setDirty(true); + if (prevGraphW > 200 || graphW > 200) + curveIsDirty = true; + } + draw (); + GdkRectangle *rectangle = &(event->expose.area); + copySurface(win, rectangle); + + retval = true; + break; + } + + case Gdk::BUTTON_PRESS: + if (edited_point==-1) { //curve.type!=FCT_Parametric) { + if (event->button.button == 1) { + buttonPressed = true; + add_modal_grab (); + + // get the pointer position + getCursorPosition(Gdk::EventType(event->type), event->motion.is_hint!=0, int(event->button.x), int(event->button.y), Gdk::ModifierType(event->button.state)); + getMouseOverArea(); + + // hide the tangent handles + tanHandlesDisplayed = false; + + // Action on BUTTON_PRESS and no edited point + switch (area) { + + case (FCT_Area_Insertion): + new_type = CSMove; + + /* insert a new control point */ + if (num > 0) { + if (clampedX > curve.x.at(closest_point)) + ++closest_point; + } + itx = curve.x.begin(); + ity = curve.y.begin(); + itlt = curve.leftTangent.begin(); + itrt = curve.rightTangent.begin(); + for (int i=0; ibutton.button == 3) { + /* get the pointer position */ + getCursorPosition(Gdk::EventType(event->type), event->motion.is_hint!=0, int(event->button.x), int(event->button.y), Gdk::ModifierType(event->button.state)); + getMouseOverArea(); + if (lit_point>-1 && lit_point!=edited_point) { + if (editedHandle == FCT_EditedHandle_None) { + if (area == FCT_Area_Point || area == FCT_Area_V) { + // the cursor is close to an existing point + if (!coordinateAdjuster->is_visible()) + coordinateAdjuster->showMe(this); + + new_type = CSArrow; + tanHandlesDisplayed = false; + edited_point = lit_point; + setDirty(true); + draw (); + std::vector newBoundaries(4); + unsigned int size = curve.x.size(); + if (edited_point == 0) { newBoundaries.at(0).minVal = 0.; newBoundaries.at(0).maxVal = curve.x.at(1); } + else if (edited_point == size-1) { newBoundaries.at(0).minVal = curve.x.at(edited_point-1); newBoundaries.at(0).maxVal = 1.; } + else if (curve.x.size() > 2) { newBoundaries.at(0).minVal = curve.x.at(edited_point-1); newBoundaries.at(0).maxVal = curve.x.at(edited_point+1); } + newBoundaries.at(1).minVal = 0.; newBoundaries.at(1).maxVal = 1.; + newBoundaries.at(2).minVal = 0.; newBoundaries.at(2).maxVal = 1.; + newBoundaries.at(3).minVal = 0.; newBoundaries.at(3).maxVal = 1.; + retval = true; + editedPos.at(0) = curve.x.at(edited_point); + editedPos.at(1) = curve.y.at(edited_point); + editedPos.at(2) = curve.leftTangent.at(edited_point); + editedPos.at(3) = curve.rightTangent.at(edited_point); + coordinateAdjuster->setPos(editedPos); + coordinateAdjuster->startNumericalAdjustment(newBoundaries); + } + } + } + retval = true; + } + if (buttonPressed) retval = true; + } + else { // if (edited_point > -1) + if (event->button.button == 3) { + // do we edit another point? + /* get the pointer position */ + getCursorPosition(Gdk::EventType(event->type), event->motion.is_hint!=0, int(event->button.x), int(event->button.y), Gdk::ModifierType(event->button.state)); + getMouseOverArea(); + if (area == FCT_Area_Point || area == FCT_Area_V) { + // the cursor is close to an existing point + if (lit_point != edited_point) { + edited_point = lit_point; + setDirty(true); + draw (); + std::vector newBoundaries(4); + unsigned int size = curve.x.size(); + if (edited_point == 0) { newBoundaries.at(0).minVal = 0.; newBoundaries.at(0).maxVal = curve.x.at(1); } + else if (edited_point == size-1) { newBoundaries.at(0).minVal = curve.x.at(edited_point-1); newBoundaries.at(0).maxVal = 1.; } + else if (curve.x.size() > 2) { newBoundaries.at(0).minVal = curve.x.at(edited_point-1); newBoundaries.at(0).maxVal = curve.x.at(edited_point+1); } + newBoundaries.at(1).minVal = 0.; newBoundaries.at(1).maxVal = 1.; + newBoundaries.at(2).minVal = 0.; newBoundaries.at(2).maxVal = 1.; + newBoundaries.at(3).minVal = 0.; newBoundaries.at(3).maxVal = 1.; + editedPos.at(0) = curve.x.at(edited_point); + editedPos.at(1) = curve.y.at(edited_point); + editedPos.at(2) = curve.leftTangent.at(edited_point); + editedPos.at(3) = curve.rightTangent.at(edited_point); + coordinateAdjuster->switchAdjustedPoint(editedPos, newBoundaries); + retval = true; + } + } + else if (area == FCT_Area_Insertion) { + // the cursor is inside the graph but away from existing points + new_type = CSPlus; + curveIsDirty = true; + stopNumericalAdjustment(); + } + } + } + break; + + case Gdk::BUTTON_RELEASE: + if (edited_point==-1) { //curve.type!=FCT_Parametric) { + if (buttonPressed && event->button.button == 1) { + int src, dst; + buttonPressed = false; + remove_modal_grab (); + + // Removing any deleted point if we were previously modifying the point position + if (editedHandle & (FCT_EditedHandle_CPoint|FCT_EditedHandle_CPointX|FCT_EditedHandle_CPointY)) { + /* delete inactive points: */ + itx = curve.x.begin(); + ity = curve.y.begin(); + itlt = curve.leftTangent.begin(); + itrt = curve.rightTangent.begin(); + for (src = dst = 0; src < num; ++src) + if (curve.x.at(src) >= 0.0) { + curve.x.at(dst) = curve.x.at(src); + curve.y.at(dst) = curve.y.at(src); + curve.leftTangent.at(dst) = curve.leftTangent.at(src); + curve.rightTangent.at(dst) = curve.rightTangent.at(src); + ++dst; + ++itx; + ++ity; + ++itlt; + ++itrt; + } + if (dst < src) { + + // curve cleanup + curve.x.erase (itx, curve.x.end()); + curve.y.erase (ity, curve.y.end()); + curve.leftTangent.erase (itlt, curve.leftTangent.end()); + curve.rightTangent.erase (itrt, curve.rightTangent.end()); + if (curve.x.empty()) { + curve.x.push_back (0.5); + curve.y.push_back (0.5); + curve.leftTangent.push_back (0.3); + curve.rightTangent.push_back (0.3); + curveIsDirty = true; + } + } + } + + editedHandle = FCT_EditedHandle_None; + lit_point = -1; + + // get the pointer position + getCursorPosition(Gdk::EventType(event->type), event->motion.is_hint!=0, int(event->button.x), int(event->button.y), Gdk::ModifierType(event->button.state)); + getMouseOverArea(); + + switch (area) { + + case (FCT_Area_Insertion): + new_type = CSArrow; + break; + + case (FCT_Area_Point): + new_type = CSMove; + break; + + case (FCT_Area_H): + new_type = CSResizeHeight; + break; + + case (FCT_Area_V): + new_type = CSMove; + break; + + case (FCT_Area_LeftTan): + new_type = CSEmpty; + break; + + case (FCT_Area_RightTan): + new_type = CSEmpty; + break; + + default: + break; + } + + setDirty(true); + draw (); + retval = true; + //notifyListener (); + } + } + break; + + case Gdk::MOTION_NOTIFY: + if (curve.type == FCT_Linear || curve.type == FCT_MinMaxCPoints) { + + int previous_lit_point = lit_point; + enum MouseOverAreas prevArea = area; + + snapToMinDistY = snapToMinDistX = 10.; + snapToValY = snapToValX = 0.; + snapToElmt = -100; + + // get the pointer position + getCursorPosition(Gdk::EventType(event->type), event->motion.is_hint!=0, int(event->button.x), int(event->button.y), Gdk::ModifierType(event->button.state)); + getMouseOverArea(); + + if (editedHandle == FCT_EditedHandle_CPointUD) { + double dX = deltaX; + double dY = deltaY; + if (dX < 0.) dX = -dX; + if (dY < 0.) dY = -dY; + if (dX > dY) { + editedHandle = FCT_EditedHandle_CPointX; + area = FCT_Area_V; + new_type = CSResizeWidth; + } + else { + editedHandle = FCT_EditedHandle_CPointY; + area = FCT_Area_H; + new_type = CSResizeHeight; + } + } + + switch (editedHandle) { + + case (FCT_EditedHandle_None): { + + if ((lit_point != -1 && previous_lit_point != lit_point) && (area&(FCT_Area_V|FCT_Area_Point)) && edited_point==-1) { + + bool sameSide = false; + + // display the handles + tanHandlesDisplayed = true; + + if (curve.x.at(lit_point) < 3.*minDistanceX) { + // lit_point too near of the left border -> both handles are displayed on the right of the vertical line + rightTanHandle.centerX = leftTanHandle.centerX = curve.x.at(lit_point) + 2.*minDistanceX; + sameSide = true; + } + else if (curve.x.at(lit_point) > 1.-3.*minDistanceX) { + // lit_point too near of the left border -> both handles are displayed on the right of the vertical line + rightTanHandle.centerX = leftTanHandle.centerX = curve.x.at(lit_point) - 2.*minDistanceX; + sameSide = true; + } + else { + leftTanHandle.centerX = curve.x.at(lit_point) - 2.*minDistanceX; + rightTanHandle.centerX = curve.x.at(lit_point) + 2.*minDistanceX; + } + if (sameSide) { + if (clampedY > 1.-2.*minDistanceY) { + // lit_point too near of the top border + leftTanHandle.centerY = 1. - minDistanceY; + rightTanHandle.centerY = 1. - 3.*minDistanceY; + } + else if (clampedY < 2.*minDistanceY) { + // lit_point too near of the bottom border + leftTanHandle.centerY = 3.*minDistanceY; + rightTanHandle.centerY = minDistanceY; + } + else { + leftTanHandle.centerY = clampedY + minDistanceY; + rightTanHandle.centerY = clampedY - minDistanceY; + } + } + else { + if (clampedY > 1.-minDistanceY) { + rightTanHandle.centerY = leftTanHandle.centerY = 1. - minDistanceY; + } + else if (clampedY < minDistanceY) { + rightTanHandle.centerY = leftTanHandle.centerY = minDistanceY; + } + else { + rightTanHandle.centerY = leftTanHandle.centerY = clampedY; + } + } + } + else if (lit_point == -1 || edited_point>-1) { + tanHandlesDisplayed = false; + } + + + if (edited_point==-1) { + switch (area) { + + case (FCT_Area_Insertion): + new_type = CSPlus; + break; + case (FCT_Area_Point): + //new_type = CSMove; + //break; + case (FCT_Area_V): + new_type = CSMove; + break; + case (FCT_Area_H): + new_type = CSResizeHeight; + break; + case (FCT_Area_LeftTan): + new_type = CSMoveLeft; + break; + case (FCT_Area_RightTan): + new_type = CSMoveRight; + break; + case (FCT_Area_None): + default: + new_type = CSArrow; + break; + } + } + + if ((lit_point != previous_lit_point) || (prevArea != area)) { + setDirty(true); + draw (); + } + + if (coordinateAdjuster->is_visible() && edited_point==-1) { + if (lit_point > -1) { + if (lit_point != previous_lit_point) { + editedPos.at(0) = curve.x.at(lit_point); + editedPos.at(1) = curve.y.at(lit_point); + editedPos.at(2) = curve.leftTangent.at(lit_point); + editedPos.at(3) = curve.rightTangent.at(lit_point); + } + coordinateAdjuster->setPos(editedPos); + } + else if (area == FCT_Area_Insertion) { + editedPos.at(0) = clampedX; + editedPos.at(1) = clampedY; + editedPos.at(2) = 0.; + editedPos.at(3) = 0.; + coordinateAdjuster->setPos(editedPos); + } + else { + editedPos.at(0) = editedPos.at(1) = editedPos.at(2) = editedPos.at(3) = 0; + coordinateAdjuster->setPos(editedPos); + } + } + break; + } + + case (FCT_EditedHandle_CPoint): + movePoint(true, true); + if (coordinateAdjuster->is_visible()) { + editedPos.at(0) = curve.x.at(lit_point); + editedPos.at(1) = curve.y.at(lit_point); + coordinateAdjuster->setPos(editedPos); + } + break; + + case (FCT_EditedHandle_CPointX): + movePoint(true, false); + if (coordinateAdjuster->is_visible()) { + editedPos.at(0) = curve.x.at(lit_point); + coordinateAdjuster->setPos(editedPos); + } + break; + + case (FCT_EditedHandle_CPointY): + movePoint(false, true); + if (coordinateAdjuster->is_visible()) { + editedPos.at(1) = curve.y.at(lit_point); + coordinateAdjuster->setPos(editedPos); + } + break; + + case (FCT_EditedHandle_LeftTan): { + double prevValue = curve.leftTangent.at(lit_point); + + ugpX -= deltaX*3; + ugpX = CLAMP(ugpX, 0., 1.); + if (snapTo) { + // since this handle can only move in one direction, we can reuse the snapCoordinateX mechanism + snapCoordinateX(0.0, ugpX); + snapCoordinateX(0.35, ugpX); + snapCoordinateX(0.5, ugpX); + snapCoordinateX(1.0, ugpX); + curve.leftTangent.at(lit_point) = snapToValX; + } + else { + curve.leftTangent.at(lit_point) = ugpX; + } + + if (curve.leftTangent.at(lit_point) != prevValue) { + curveIsDirty = true; + setDirty(true); + draw (); + notifyListener (); + if (coordinateAdjuster->is_visible()) { + editedPos.at(2) = curve.leftTangent.at(lit_point); + coordinateAdjuster->setPos(editedPos); + } + } + break; + } + + case (FCT_EditedHandle_RightTan): { + double prevValue = curve.rightTangent.at(lit_point); + + ugpX += deltaX*3; + ugpX = CLAMP(ugpX, 0., 1.); + if (snapTo) { + // since this handle can only move in one direction, we can reuse the snapCoordinateX mechanism + snapCoordinateX(0.0, ugpX); + snapCoordinateX(0.35, ugpX); + snapCoordinateX(0.5, ugpX); + snapCoordinateX(1.0, ugpX); + curve.rightTangent.at(lit_point) = snapToValX; + } + else { + curve.rightTangent.at(lit_point) = ugpX; + } + + if (curve.rightTangent.at(lit_point) != prevValue) { + curveIsDirty = true; + setDirty(true); + draw (); + notifyListener (); + editedPos.at(3) = curve.rightTangent.at(lit_point); + coordinateAdjuster->setPos(editedPos); + } + break; + } + + // already processed before the "switch" instruction + //case (FCT_EditedHandle_CPointUD): + + default: + break; + } + + if (edited_point==-1) { + if (lit_point == -1) { + editedPos.at(0) = editedPos.at(1) = editedPos.at(2) = editedPos.at(3) = 0; + } + else if (editedPos.at(0) != curve.x.at(lit_point) + || editedPos.at(1) != curve.y.at(lit_point) + || editedPos.at(2) != curve.leftTangent.at(lit_point) + || editedPos.at(3) != curve.rightTangent.at(lit_point)) + { + editedPos.at(0) = curve.x.at(lit_point); + editedPos.at(1) = curve.y.at(lit_point); + editedPos.at(2) = curve.leftTangent.at(lit_point); + editedPos.at(3) = curve.rightTangent.at(lit_point); + coordinateAdjuster->setPos(editedPos); + } + } + } + + retval = true; + break; + + case Gdk::LEAVE_NOTIFY: + // Pointer can LEAVE even when dragging the point, so we don't modify the cursor in this case + // The cursor will have to LEAVE another time after the drag... + if (editedHandle == FCT_EditedHandle_None) { + new_type = CSArrow; + lit_point = -1; + tanHandlesDisplayed = false; + pipetteR = pipetteG = pipetteB = -1.f; + setDirty(true); + draw (); + } + retval = true; + break; + + default: + break; + } + if (new_type != cursor_type) { + cursor_type = new_type; + cursorManager.setCursor(cursor_type); + } + return retval; +} + +void MyFlatCurve::pipetteMouseOver (CurveEditor *ce, EditDataProvider *provider, int modifierKey) { + if (!provider) { + // occurs when leaving the preview area -> cleanup the curve editor + pipetteR = pipetteG = pipetteB = -1.f; + lit_point = -1; + return; + } + + pipetteR = provider->pipetteVal[0]; + pipetteG = provider->pipetteVal[1]; + pipetteB = provider->pipetteVal[2]; + pipetteVal = 0.f; + if (listener) + pipetteVal = listener->blendPipetteValues(ce, pipetteR, pipetteG, pipetteB); + else { + int n = 0; + if (pipetteR != -1.f) { + pipetteVal += pipetteR; + ++n; + } + if (pipetteG != -1.f) { + pipetteVal += pipetteG; + ++n; + } + if (pipetteB != -1.f) { + pipetteVal += pipetteB; + ++n; + } + if (n>1) + pipetteVal /= n; + else if (!n) + pipetteVal = -1.f; + } + + snapToElmt = -100; + + /* graphW and graphH are the size of the graph */ + calcDimensions(); + + if ((graphW < 0) || (graphH < 0)) + return; + + int previous_lit_point = lit_point; + + // hide the handles + tanHandlesDisplayed = false; + + // get the pointer position + int px = graphX + int(float(graphW)*pipetteVal); // WARNING: converting pipetteVal from float to int, precision loss here! + getCursorPosition(Gdk::EventType(Gdk::BUTTON_PRESS), false, px, graphY, Gdk::ModifierType(modifierKey)); + if (edited_point==-1) + getMouseOverArea(); + + if (area==FCT_Area_Point) + area = FCT_Area_V; + + snapToMinDistY = snapToMinDistX = 10.; + snapToValY = snapToValX = 0.; + + if (edited_point==-1) { + if (editedHandle==FCT_EditedHandle_None && lit_point != previous_lit_point) { + setDirty(true); + draw (); + } + } + else + draw(); + + if (edited_point==-1) { + editedPos.at(0) = pipetteVal; + editedPos.at(1) = point.getVal01(pipetteVal); + coordinateAdjuster->setPos(editedPos); + } +} + +void MyFlatCurve::pipetteButton1Pressed(EditDataProvider *provider, int modifierKey) { + if (edited_point>-1) + return; + + buttonPressed = true; + + // get the pointer position + int px = graphX + int(float(graphW)*pipetteVal); // WARNING: converting pipetteVal from float to int, precision loss here! + getCursorPosition(Gdk::EventType(Gdk::BUTTON_PRESS), false, px, graphY, Gdk::ModifierType(modifierKey)); + getMouseOverArea(); + + // hide the tangent handles + tanHandlesDisplayed = false; + + // Action on BUTTON_PRESS and no edited point + switch (area) { + + case (FCT_Area_Insertion): + { + rtengine::FlatCurve rtCurve(getPoints(), 200); + + std::vector::iterator itx, ity, itlt, itrt; + int num = (int)curve.x.size(); + + /* insert a new control point */ + if (num > 0) { + if (clampedX > curve.x.at(closest_point)) + ++closest_point; + } + itx = curve.x.begin(); + ity = curve.y.begin(); + itlt = curve.leftTangent.begin(); + itrt = curve.rightTangent.begin(); + for (int i=0; i-1) + return; + + buttonPressed = false; + remove_modal_grab (); + + editedHandle = FCT_EditedHandle_None; + lit_point = -1; + + // get the pointer position + int px = graphX + int(float(graphW)*pipetteVal); // WARNING: converting pipetteVal from float to int, precision loss here! + getCursorPosition(Gdk::EventType(Gdk::BUTTON_PRESS), false, px, graphY, Gdk::ModifierType(0)); + getMouseOverArea(); + + setDirty(true); + draw (); + //notifyListener (); +} + +void MyFlatCurve::pipetteDrag(EditDataProvider *provider, int modifierKey) { + if (edited_point>-1) + return; + + snapToMinDistY = snapToMinDistX = 10.; + snapToValY = snapToValX = 0.; + snapToElmt = -100; + + // get the pointer position + getCursorPosition(Gdk::MOTION_NOTIFY, false, cursorX+graphX, graphY+provider->deltaScreen.y, Gdk::ModifierType(modifierKey)); + getMouseOverArea(); + + if (editedHandle == FCT_EditedHandle_CPointY) { + movePoint(false, true, true); + } +} + +void MyFlatCurve::movePoint(bool moveX, bool moveY, bool pipetteDrag) { + + // bounds of the grabbed point + double leftBound; + double rightBound; + double const bottomBound = 0.; + double const topBound = 1.; + + // we memorize the previous position of the point, for optimization purpose + double prevPosX = curve.x.at(lit_point); + double prevPosY = curve.y.at(lit_point); + + int nbPoints = (int)curve.x.size(); + + // left and right bound rely on curve periodicity + leftBound = (lit_point == 0 ) ? (periodic && !snapTo ? curve.x.at(nbPoints-1)-1. : 0.) : curve.x.at(lit_point-1); + rightBound = (lit_point == nbPoints-1) ? (periodic && !snapTo ? curve.x.at(0)+1. : 1.) : curve.x.at(lit_point+1); + + double leftDeletionBound = leftBound - minDistanceX; + double rightDeletionBound = rightBound + minDistanceX; + double bottomDeletionBound = bottomBound - minDistanceY; + double topDeletionBound = topBound + minDistanceY; + + if (moveX) { + // we memorize the previous position of the point, for optimization purpose + ugpX += deltaX; + + // handling periodicity (the first and last point can reappear at the other side of the X range) + if (periodic) { + if (snapTo) { + if (lit_point==0) { + snapCoordinateX(0.0, ugpX); + curve.x.at(0) = snapToValX; + } + else if (lit_point==(nbPoints-1)) { + snapCoordinateX(1.0, ugpX); + curve.x.at(nbPoints-1) = snapToValX; + } + } + else if (lit_point==0 && ugpX<0.) { + // the first point has to be placed at the tail of the point list + std::vector::iterator itx, ity, itlt, itrt; + + ugpX += 1.; + leftBound += 1.; + rightBound += 1.; + leftDeletionBound += 1.; + rightDeletionBound += 1.; + + // adding a copy of the first point to the tail of the list + curve.x.push_back(curve.x.at(0)); + curve.y.push_back(curve.y.at(0)); + curve.leftTangent.push_back(curve.leftTangent.at(0)); + curve.rightTangent.push_back(curve.rightTangent.at(0)); + + // deleting the first point + itx = curve.x.begin(); + ity = curve.y.begin(); + itlt = curve.leftTangent.begin(); + itrt = curve.rightTangent.begin(); + + curve.x.erase(itx); + curve.y.erase(ity); + curve.leftTangent.erase(itlt); + curve.rightTangent.erase(itrt); + + lit_point = nbPoints-1; + } + else if (lit_point==(nbPoints-1) && ugpX>1.) { + // the last point has to be placed at the head of the point list + std::vector::iterator itx, ity, itlt, itrt; + + ugpX -= 1.; + leftBound -= 1.; + rightBound -= 1.; + leftDeletionBound -= 1.; + rightDeletionBound -= 1.; + + // adding a copy of the last point to the head of the list + itx = curve.x.begin(); + ity = curve.y.begin(); + itlt = curve.leftTangent.begin(); + itrt = curve.rightTangent.begin(); + + curve.x.insert(itx,0); + curve.y.insert(ity,0); + curve.leftTangent.insert(itlt,0); + curve.rightTangent.insert(itrt,0); + + curve.x.at(0) = curve.x.at(nbPoints); + curve.y.at(0) = curve.y.at(nbPoints); + curve.leftTangent.at(0) = curve.leftTangent.at(nbPoints); + curve.rightTangent.at(0) = curve.rightTangent.at(nbPoints); + + // deleting the last point + curve.x.pop_back(); + curve.y.pop_back(); + curve.leftTangent.pop_back(); + curve.rightTangent.pop_back(); + + lit_point = 0; + } + } + + // handling limitations along X axis + if (ugpX >= rightDeletionBound && nbPoints>2 && !snapTo) { + curve.x.at(lit_point) = -1.; + } + else if (ugpX <= leftDeletionBound && nbPoints>2 && !snapTo) { + curve.x.at(lit_point) = -1.; + } + else + // nextPosX is in bounds + curve.x.at(lit_point) = CLAMP(ugpX, leftBound, rightBound); + } + + if (moveY) { + + // we memorize the previous position of the point, for optimization purpose + ugpY += deltaY; + + // the points stay in the bounds (and can't be deleted) in pipette drag mode + if (pipetteDrag) + ugpY = CLAMP(ugpY, 0.0, 1.0); + + // snapping point to specific values + if (snapTo && curve.x.at(lit_point) != -1) { + + // the unclamped grabbed point is brought back in the range + ugpY = CLAMP(ugpY, 0.0, 1.0); + + if (lit_point == 0) { + int prevP = curve.y.size()-1; + if (snapCoordinateY(curve.y.at(prevP), ugpY)) snapToElmt = prevP; + } + else { + int prevP = lit_point-1; + if (snapCoordinateY(curve.y.at(prevP), ugpY)) snapToElmt = prevP; + } + + if (curve.y.size() > 2) { + if (lit_point == (curve.y.size()-1)) { + if (snapCoordinateY(curve.y.at(0), ugpY)) snapToElmt = 0; + } + else { + int nextP = lit_point+1; + if (snapCoordinateY(curve.y.at(nextP), ugpY)) snapToElmt = nextP; + } + } + if (snapCoordinateY(1.0, ugpY)) snapToElmt = -3; + if (snapCoordinateY(0.5, ugpY)) snapToElmt = -2; + if (snapCoordinateY(0.0, ugpY)) snapToElmt = -1; + + curve.y.at(lit_point) = snapToValY; + } + + // Handling limitations along Y axis + if (ugpY >= topDeletionBound && nbPoints>2) { + if (curve.x.at(lit_point) != -1.) { + deletedPointX = curve.x.at(lit_point); + curve.x.at(lit_point) = -1.; + curve.y.at(lit_point) = ugpY; // This is only to force the redraw of the curve + } + } + else if (ugpY <= bottomDeletionBound && nbPoints>2) { + if (curve.x.at(lit_point) != -1.) { + deletedPointX = curve.x.at(lit_point); + curve.x.at(lit_point) = -1.; + curve.y.at(lit_point) = ugpY; // This is only to force the redraw of the curve + } + } + else { + // nextPosY is in the bounds + if (!snapTo) curve.y.at(lit_point) = CLAMP(ugpY, 0.0, 1.0); + if (!moveX && curve.x.at(lit_point) == -1.) { + // bring back the X value of the point if it reappear + curve.x.at(lit_point) = deletedPointX; + } + } + } + + if (curve.x.at(lit_point) != prevPosX || curve.y.at(lit_point) != prevPosY) { + // we recompute the curve only if we have to + curveIsDirty = true; + setDirty(true); + draw (); + notifyListener (); + } +} + +// Set datas relative to cursor position +void MyFlatCurve::getCursorPosition(Gdk::EventType evType, bool isHint, int evX, int evY, Gdk::ModifierType modifierKey) { + int tx, ty; + int prevCursorX, prevCursorY; + double incrementX = 1. / double(graphW); + double incrementY = 1. / double(graphH); + + switch (evType) { + case (Gdk::MOTION_NOTIFY) : + if (isHint) { + get_window()->get_pointer (tx, ty, mod_type); + } + else { + tx = evX; + ty = evY; + mod_type = modifierKey; + } + break; + case (Gdk::BUTTON_PRESS) : + case (Gdk::BUTTON_RELEASE) : + tx = evX; + ty = evY; + mod_type = modifierKey; + break; + default : + // The cursor position is not available + return; + break; + } + + if (editedHandle != FCT_EditedHandle_None) { + prevCursorX = cursorX; + prevCursorY = cursorY; + } + cursorX = tx - graphX; + cursorY = graphY - ty; + + preciseCursorX = cursorX * incrementX; + preciseCursorY = cursorY * incrementY; + + snapTo = false; + + // update deltaX/Y if the user drags a point + if (editedHandle != FCT_EditedHandle_None) { + // set the dragging factor + int control_key = mod_type & GDK_CONTROL_MASK; + int shift_key = mod_type & GDK_SHIFT_MASK; + + // the increment get smaller if modifier key are used, and "snap to" may be enabled + if (control_key) { incrementX *= 0.05; incrementY *= 0.05; } + if (shift_key) { snapTo = true; } + + deltaX = (double)(cursorX - prevCursorX) * incrementX; + deltaY = (double)(cursorY - prevCursorY) * incrementY; + } + // otherwise set the position of the new point (modifier keys has no effect here) + else { + clampedX = CLAMP (preciseCursorX, 0., 1.); // X position of the pointer from the origin of the graph + clampedY = CLAMP (preciseCursorY, 0., 1.); // Y position of the pointer from the origin of the graph + } + +} + +// Find out the active area under the cursor +void MyFlatCurve::getMouseOverArea () { + + // When dragging an element, editedHandle keep its value + if (editedHandle == FCT_EditedHandle_None) { // && curve.type!=Parametric + + double minDist = 1000; // used to find out the point pointed by the cursor (over it) + double minDistX = 1000; // used to find out the closest point + double dX, dY; + double absDX; + double dist; + bool aboveVLine = false; + + // NB: this function assume that the graph's shape is a square + + // Check if the cursor is over a tangent handle + if (tanHandlesDisplayed) { + + if (preciseCursorX>=(leftTanHandle.centerX-minDistanceX) && preciseCursorX<=(leftTanHandle.centerX+minDistanceX+0.00001) + && preciseCursorY>=(leftTanHandle.centerY-minDistanceY) && preciseCursorY<=(leftTanHandle.centerY+minDistanceY)) { + area = FCT_Area_LeftTan; + return; + } + if (preciseCursorX>=(rightTanHandle.centerX-minDistanceX-0.00001) && preciseCursorX<=(rightTanHandle.centerX+minDistanceX) + && preciseCursorY>=(rightTanHandle.centerY-minDistanceY ) && preciseCursorY<=(rightTanHandle.centerY+minDistanceY)) { + area = FCT_Area_RightTan; + return; + } + } + + area = FCT_Area_None; + closest_point = 0; + lit_point = -1; + + for (int i = 0; i < (int)curve.x.size(); i++) { + if (curve.x.at(i) != -1) { + dX = curve.x.at(i) - preciseCursorX; + absDX = dX>0 ? dX : -dX; + if (absDX < minDistX) { + minDistX = absDX; + closest_point = i; + lit_point = i; + } + if (absDX <= minDistanceX) { + aboveVLine = true; + dY = curve.y.at(i) - preciseCursorY; + dist = sqrt(dX*dX + dY*dY); + if (dist < minDist) { + minDist = dist; + } + } + } + } + + if (minDist <= minDistanceX) { + // the cursor is over the point + area = FCT_Area_Point; + } + else if (aboveVLine) { + area = FCT_Area_V; + } + else { + // Check if the cursor is in an insertion area + lit_point = -1; + if (preciseCursorX>=0.0 && preciseCursorX<=1.0 && preciseCursorY>=0.0 && preciseCursorY<=1.0) + area = FCT_Area_Insertion; + } + } +} + +std::vector MyFlatCurve::getPoints () { + std::vector result; + /*if (curve.type==FCT_Parametric) { + result.push_back ((double)(Parametric)); + for (int i=0; i<(int)curve.x.size(); i++) { + result.push_back (curve.x.at(i)); + } + } + else {*/ + // the first value gives the type of the curve + if (curve.type==FCT_Linear) + result.push_back ((double)(FCT_Linear)); + else if (curve.type==FCT_MinMaxCPoints) + result.push_back ((double)(FCT_MinMaxCPoints)); + // then we push all the points coordinate + for (int i=0; i<(int)curve.x.size(); i++) { + if (curve.x.at(i)>=0) { + result.push_back (curve.x.at(i)); + result.push_back (curve.y.at(i)); + result.push_back (curve.leftTangent.at(i)); + result.push_back (curve.rightTangent.at(i)); + } + } + //} + return result; +} + +void MyFlatCurve::setPoints (const std::vector& p) { + int ix = 0; + stopNumericalAdjustment(); + FlatCurveType t = (FlatCurveType)p[ix++]; + curve.type = t; + if (t==FCT_MinMaxCPoints) { + curve.x.clear (); + curve.y.clear (); + curve.leftTangent.clear(); + curve.rightTangent.clear(); + for (int i=0; i<(int)p.size()/4; i++) { + curve.x.push_back (p[ix++]); + curve.y.push_back (p[ix++]); + curve.leftTangent.push_back (p[ix++]); + curve.rightTangent.push_back (p[ix++]); + } + } + curveIsDirty = true; + setDirty(true); + queue_draw (); +} + +void MyFlatCurve::setPos(double pos, int chanIdx) { + assert (edited_point > -1); + switch (chanIdx) { + case (0): + curve.x.at(edited_point) = pos; + break; + case (1): + curve.y.at(edited_point) = pos; + break; + case (2): + curve.leftTangent.at(edited_point) = pos; + break; + case (3): + curve.rightTangent.at(edited_point) = pos; + break; + } + curveIsDirty = true; + setDirty(true); + draw(); + notifyListener (); +} + +void MyFlatCurve::stopNumericalAdjustment() { + if (edited_point>-1) { + edited_point = lit_point = -1; + area = FCT_Area_None; + coordinateAdjuster->stopNumericalAdjustment(); + setDirty(true); + draw(); + } +} + +void MyFlatCurve::setType (FlatCurveType t) { + + curve.type = t; + setDirty(true); +} + +void MyFlatCurve::reset(const std::vector &resetCurve, double identityValue) { + calcDimensions(); + + stopNumericalAdjustment(); + + // If a resetCurve exist (non empty) + if (!resetCurve.empty()) { + setPoints(resetCurve); + return; + } + + switch (curve.type) { + case FCT_MinMaxCPoints : + defaultCurve(identityValue); + lit_point = -1; + curveIsDirty = true; + break; + //case Parametric : + // Nothing to do (?) + default: + break; + } + setDirty(true); + draw(); +} + +void MyFlatCurve::defaultCurve (double iVal) { + + curve.x.resize(6); + curve.y.resize(6); + curve.leftTangent.resize(6); + curve.rightTangent.resize(6); + + // Point for RGBCMY colors + for (int i=0; i<6; i++) { + curve.x.at(i) = (1./6.)*i; + curve.y.at(i) = iVal; + curve.leftTangent.at(i) = 0.35; + curve.rightTangent.at(i) = 0.35; + } +} diff --git a/rtgui/myflatcurve.h b/rtgui/myflatcurve.h new file mode 100644 index 000000000..6f18f56d1 --- /dev/null +++ b/rtgui/myflatcurve.h @@ -0,0 +1,135 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _MYFLATCURVE_ +#define _MYFLATCURVE_ + +#include +#include +#include "curvelistener.h" +#include "cursormanager.h" +#include "mycurve.h" + +// For compatibility and simplicity reason, order shouldn't change, and must be identical to the order specified in the curveType widget +enum FlatCurveType { + FCT_Empty = -1, // Also used for identity curves + FCT_Linear, // 0 + FCT_MinMaxCPoints, // 1 + //FCT_Parametric, // 2 + // Insert new curve type above this line + FCT_Unchanged // Must remain the last of the enum +}; + +enum MouseOverAreas { + FCT_Area_None = 1<<0, // over a zone that don't have any + FCT_Area_Insertion = 1<<1, // where the user can insert a new point + FCT_Area_Point = 1<<2, // over an existing point + FCT_Area_H = 1<<3, // cursor is on the horizontal line going through the edited control point + FCT_Area_V = 1<<4, // cursor is on the vertical line going through the edited control point + FCT_Area_LeftTan = 1<<5, // in the left tangent edition area + FCT_Area_RightTan = 1<<6 // in the right tangent edition area +}; + +enum EditedHandle { + FCT_EditedHandle_None = 1<<0, + FCT_EditedHandle_CPointUD = 1<<1, // UD stands for Unknown Direction + FCT_EditedHandle_CPoint = 1<<2, + FCT_EditedHandle_CPointX = 1<<3, + FCT_EditedHandle_CPointY = 1<<4, + FCT_EditedHandle_LeftTan = 1<<5, + FCT_EditedHandle_RightTan = 1<<6 +}; + +class FlatCurveDescr { + + public: + FlatCurveType type; + std::vector x, // Range: [0.0 - 1.0] + y, // Range: [0.0 - 1.0], default value = 0.5 + leftTangent, // Range: [0.0 - 1.0], where 1.0 = distance from previous to this point + rightTangent; // Range: [0.0 - 1.0], where 1.0 = distance from this to next point +}; + +class HandlePosition { + + public: + double centerX; + double centerY; +}; + +class MyFlatCurve : public MyCurve { + + protected: + FlatCurveDescr curve; + int closest_point; // the point that is the closest from the cursor + int lit_point; // the point that is lit when the cursor is near it + double clampedX; // clamped grabbed point X coordinates in the [0;1] range + double clampedY; // clamped grabbed point Y coordinates in the [0;1] range + double deltaX; // signed X distance of the cursor between two consecutive MOTION_NOTIFY + double deltaY; // signed Y distance of the cursor between two consecutive MOTION_NOTIFY + double distanceX; // X distance from the cursor to the closest point + double distanceY; // Y distance from the cursor to the closest point + double ugpX; // unclamped grabbed point X coordinate in the graph + double ugpY; // unclamped grabbed point Y coordinate in the graph + double leftTanX; // X position of the left tangent handle + double rightTanX; // X position of the right tangent handle + double preciseCursorX; // X coordinate in the graph of the cursor, as a double value + double preciseCursorY; // Y coordinate in the graph of the cursor, as a double value + double minDistanceX; // X minimal distance before point suppression + double minDistanceY; // Y minimal distance before point suppression + double deletedPointX; // Backup of the X value of the edited point, when deleted while being dragged + HandlePosition leftTanHandle; // XY coordinate if the upper left and bottom right corner of the left tangent handle + HandlePosition rightTanHandle; // XY coordinate if the upper left and bottom right corner of the right tangent handle + bool tanHandlesDisplayed; // True if the tangent handles are displayed + bool periodic; // Flat curves are periodic by default + enum EditedHandle editedHandle; + bool draggingElement; + enum MouseOverAreas area; + + void draw (); + void movePoint(bool moveX, bool moveY, bool pipetteDrag=false); + void defaultCurve (double iVal=0.5); + void interpolate (); + void getCursorPosition(Gdk::EventType evType, bool isHint, int evX, int evY, Gdk::ModifierType modifier); + void getMouseOverArea (); + bool getHandles(int n); + CursorShape motionNotify(CursorShape type, double minDistanceX, double minDistanceY, int num); + std::vector get_vector (int veclen); + void get_LUT (LUTf &lut); + + public: + MyFlatCurve (); + //~MyFlatCurve (); + std::vector getPoints (); + void setPeriodicity (bool isPeriodic) { periodic = isPeriodic; }; + void setPoints (const std::vector& p); + void setType (FlatCurveType t); + bool handleEvents (GdkEvent* event); + void reset (const std::vector &resetCurve, double identityValue=0.5); + //void updateBackgroundHistogram (unsigned int* hist); + + void pipetteMouseOver (CurveEditor *ce, EditDataProvider *provider, int modifierKey); + void pipetteButton1Pressed(EditDataProvider *provider, int modifierKey); + void pipetteButton1Released(EditDataProvider *provider); + void pipetteDrag(EditDataProvider *provider, int modifierKey); + + void setPos(double pos, int chanIdx); + virtual void stopNumericalAdjustment(); +}; + +#endif diff --git a/rtgui/myicon.rc b/rtgui/myicon.rc new file mode 100644 index 000000000..b986cd1b6 --- /dev/null +++ b/rtgui/myicon.rc @@ -0,0 +1 @@ +1 ICON "RT.ico" diff --git a/rtgui/navigator.cc b/rtgui/navigator.cc new file mode 100644 index 000000000..1fd44b9d7 --- /dev/null +++ b/rtgui/navigator.cc @@ -0,0 +1,348 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "navigator.h" +#include "toolpanel.h" +#include "../rtengine/iccmatrices.h" +#include "../rtengine/iccstore.h" +#include "../rtengine/curves.h" +#include "../rtengine/color.h" +#include "../rtengine/rt_math.h" +#include "options.h" + +using namespace rtengine; + +Navigator::Navigator () { + + set_label (M("MAIN_MSG_NAVIGATOR")); + Gtk::VBox* mbox = Gtk::manage (new Gtk::VBox ()); + previewWindow = Gtk::manage (new PreviewWindow ()); + mbox->pack_start (*previewWindow, Gtk::PACK_SHRINK, 2); + position = Gtk::manage (new Gtk::Label ()); + mbox->pack_start (*position, Gtk::PACK_SHRINK, 2); + + //labels + lR = Gtk::manage (new Gtk::Label (M("NAVIGATOR_R"))); + lG = Gtk::manage (new Gtk::Label (M("NAVIGATOR_G"))); + lB = Gtk::manage (new Gtk::Label (M("NAVIGATOR_B"))); + lH = Gtk::manage (new Gtk::Label (M("NAVIGATOR_H"))); + lS = Gtk::manage (new Gtk::Label (M("NAVIGATOR_S"))); + lV = Gtk::manage (new Gtk::Label (M("NAVIGATOR_V"))); + lLAB_A = Gtk::manage (new Gtk::Label (M("NAVIGATOR_LAB_A"))); + lLAB_B = Gtk::manage (new Gtk::Label (M("NAVIGATOR_LAB_B"))); + lLAB_L = Gtk::manage (new Gtk::Label (M("NAVIGATOR_LAB_L"))); + + // left-align labels + lR->set_alignment(Gtk::ALIGN_LEFT); + lG->set_alignment(Gtk::ALIGN_LEFT); + lB->set_alignment(Gtk::ALIGN_LEFT); + lH->set_alignment(Gtk::ALIGN_LEFT); + lS->set_alignment(Gtk::ALIGN_LEFT); + lV->set_alignment(Gtk::ALIGN_LEFT); + lLAB_A->set_alignment(Gtk::ALIGN_LEFT); + lLAB_B->set_alignment(Gtk::ALIGN_LEFT); + lLAB_L->set_alignment(Gtk::ALIGN_LEFT); + + //values + R = Gtk::manage (new Gtk::Label ()); + G = Gtk::manage (new Gtk::Label ()); + B = Gtk::manage (new Gtk::Label ()); + H = Gtk::manage (new Gtk::Label ()); + S = Gtk::manage (new Gtk::Label ()); + V = Gtk::manage (new Gtk::Label ()); + LAB_A = Gtk::manage (new Gtk::Label ()); + LAB_B = Gtk::manage (new Gtk::Label ()); + LAB_L = Gtk::manage (new Gtk::Label ()); + + // right-align values + R->set_alignment(Gtk::ALIGN_RIGHT); + G->set_alignment(Gtk::ALIGN_RIGHT); + B->set_alignment(Gtk::ALIGN_RIGHT); + H->set_alignment(Gtk::ALIGN_RIGHT); + S->set_alignment(Gtk::ALIGN_RIGHT); + V->set_alignment(Gtk::ALIGN_RIGHT); + LAB_A->set_alignment(Gtk::ALIGN_RIGHT); + LAB_B->set_alignment(Gtk::ALIGN_RIGHT); + LAB_L->set_alignment(Gtk::ALIGN_RIGHT); + + // set font family and size + Glib::ustring fontname; + +#ifdef WIN32 + fontname = "Droid Sans Mono Slashed"; // font file is provided in the source tree in rtdata/fonts to be installed by the windows installer +#endif + +#ifdef __linux__ + fontname = "Monospace"; +#endif + +#ifdef __APPLE__ + fontname="Menlo"; +#endif + + if (fontname!=""){ + R->modify_font(Pango::FontDescription(fontname)); + G->modify_font(Pango::FontDescription(fontname)); + B->modify_font(Pango::FontDescription(fontname)); + H->modify_font(Pango::FontDescription(fontname)); + S->modify_font(Pango::FontDescription(fontname)); + V->modify_font(Pango::FontDescription(fontname)); + LAB_A->modify_font(Pango::FontDescription(fontname)); + LAB_B->modify_font(Pango::FontDescription(fontname)); + LAB_L->modify_font(Pango::FontDescription(fontname)); + + lR->modify_font(Pango::FontDescription(fontname)); + lG->modify_font(Pango::FontDescription(fontname)); + lB->modify_font(Pango::FontDescription(fontname)); + lH->modify_font(Pango::FontDescription(fontname)); + lS->modify_font(Pango::FontDescription(fontname)); + lV->modify_font(Pango::FontDescription(fontname)); + lLAB_A->modify_font(Pango::FontDescription(fontname)); + lLAB_B->modify_font(Pango::FontDescription(fontname)); + lLAB_L->modify_font(Pango::FontDescription(fontname)); + + position->modify_font(Pango::FontDescription(fontname)); + } + + // setup the tables + Gtk::Table* table0 = Gtk::manage (new Gtk::Table (1, 3)); //rows, cols The main table container + // let's pack tables1,2-3 into table0 + + + // RGB + Gtk::HBox* hbox1 = Gtk::manage (new Gtk::HBox ()); // container + Gtk::Table* table1 = Gtk::manage (new Gtk::Table (3, 2)); + + table1->attach (*lR, 0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 4, 0); + table1->attach (*R, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK, 0, 0); + + table1->attach (*lG, 0, 1, 1, 2, Gtk::SHRINK, Gtk::SHRINK, 4, 0); + table1->attach (*G, 1, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK, 0, 0); + + table1->attach (*lB, 0, 1, 2, 3, Gtk::SHRINK, Gtk::SHRINK, 4, 0); + table1->attach (*B, 1, 2, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK, 0, 0); + + hbox1->pack_start (*table1, Gtk::PACK_EXPAND_WIDGET, 4); + hbox1->pack_start (*Gtk::manage (new Gtk::VSeparator()), Gtk::PACK_SHRINK, 4); + table0->attach (*hbox1, 0, 1, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK, 0, 0); + + // HSV + Gtk::HBox* hbox2 = Gtk::manage (new Gtk::HBox ()); // container + Gtk::Table* table2 = Gtk::manage (new Gtk::Table (3, 2)); + + table2->attach (*lH, 0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 4, 0); + table2->attach (*H, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK, 0, 0); + + table2->attach (*lS, 0, 1, 1, 2, Gtk::SHRINK, Gtk::SHRINK, 4, 0); + table2->attach (*S, 1, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK, 0, 0); + + table2->attach (*lV, 0, 1, 2, 3, Gtk::SHRINK, Gtk::SHRINK, 4, 0); + table2->attach (*V, 1, 2, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK, 0, 0); + + hbox2->pack_start (*table2, Gtk::PACK_EXPAND_WIDGET, 4); + hbox2->pack_start (*Gtk::manage (new Gtk::VSeparator()), Gtk::PACK_SHRINK, 4); + table0->attach (*hbox2, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK, 0, 0); + + // LAB + Gtk::HBox* hbox3 = Gtk::manage (new Gtk::HBox ()); // container + Gtk::Table* table3 = Gtk::manage (new Gtk::Table (3, 2)); + + table3->attach (*lLAB_L, 0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 4, 0); + table3->attach (*LAB_L, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK, 0, 0); + + table3->attach (*lLAB_A, 0, 1, 1, 2, Gtk::SHRINK, Gtk::SHRINK, 4, 0); + table3->attach (*LAB_A, 1, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK, 0, 0); + + table3->attach (*lLAB_B, 0, 1, 2, 3, Gtk::SHRINK, Gtk::SHRINK, 4, 0); + table3->attach (*LAB_B, 1, 2, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK, 0, 0); + + hbox3->pack_start (*table3, Gtk::PACK_EXPAND_WIDGET, 4); + hbox3->pack_start (*Gtk::manage (new Gtk::HBox()), Gtk::PACK_SHRINK, 2); + table0->attach (*hbox3, 2, 3, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK, 0, 0); + + table0->set_homogeneous(true); // all cells will be the same size as the largest cell. + + mbox->pack_start (*table0, Gtk::PACK_EXPAND_WIDGET, 2); + add (*mbox); + + setInvalid (); + show_all (); +} + +void Navigator::setInvalid (int fullWidth, int fullHeight) { + if (fullWidth>0 && fullHeight>0) + position->set_text (Glib::ustring::compose (M("NAVIGATOR_XY_FULL"),fullWidth,fullHeight)); + else + position->set_text (M("NAVIGATOR_XY_NA")); + + R->set_text (M("NAVIGATOR_NA")); + G->set_text (M("NAVIGATOR_NA")); + B->set_text (M("NAVIGATOR_NA")); + H->set_text (M("NAVIGATOR_NA")); + S->set_text (M("NAVIGATOR_NA")); + V->set_text (M("NAVIGATOR_NA")); + LAB_A->set_text (M("NAVIGATOR_NA")); + LAB_B->set_text (M("NAVIGATOR_NA")); + LAB_L->set_text (M("NAVIGATOR_NA")); +} + +// if !validPos then x/y contain the full image size +void Navigator::pointerMoved (bool validPos, Glib::ustring profile,Glib::ustring profileW, int x, int y, int r, int g, int b) { + + if (!validPos) + setInvalid (x,y); + else { + position->set_text (Glib::ustring::compose ("x: %1, y: %2", x, y)); + + R->set_text (Glib::ustring::format(std::fixed, std::setprecision(1), r*100.f/255.f) + Glib::ustring("%")); + G->set_text (Glib::ustring::format(std::fixed, std::setprecision(1), g*100.f/255.f) + Glib::ustring("%")); + B->set_text (Glib::ustring::format(std::fixed, std::setprecision(1), b*100.f/255.f) + Glib::ustring("%")); + + float h, s, v; + Color::rgb2hsv (r*0xffff/0xff, g*0xffff/0xff, b*0xffff/0xff, h, s, v); + H->set_text (Glib::ustring::format(std::fixed, std::setprecision(1), h*360.f) + Glib::ustring("\xc2\xb0")); + S->set_text (Glib::ustring::format(std::fixed, std::setprecision(1), s*100.f) + Glib::ustring("%")); + V->set_text (Glib::ustring::format(std::fixed, std::setprecision(1), v*100.f) + Glib::ustring("%")); + + float LAB_a, LAB_b, LAB_l; + //rgb2lab (r, g, b, LAB_l, LAB_a, LAB_b); + rgb2lab (profile, profileW, r, g, b, LAB_l, LAB_a, LAB_b); // TODO: Really sure this function works? + LAB_A->set_text (Glib::ustring::format(std::fixed, std::setprecision(1), LAB_a)); + LAB_B->set_text (Glib::ustring::format(std::fixed, std::setprecision(1), LAB_b)); + LAB_L->set_text (Glib::ustring::format(std::fixed, std::setprecision(1), LAB_l)); + } +} + + +void Navigator::rgb2lab (Glib::ustring profile, Glib::ustring profileW, int r, int g, int b, float &LAB_l, float &LAB_a, float &LAB_b) { + double xyz_rgb[3][3]; + const double ep=216.0/24389.0; + const double ka=24389.0/27.0; + + double var_R = r / 255.0; + double var_G = g / 255.0; + double var_B = b / 255.0; + + Glib::ustring profileCalc; + profileCalc="sRGB";//default + if(options.rtSettings.HistogramWorking) profileCalc=profileW;//display working + + else {// if you want display = output space + if (profile=="RT_sRGB" || profile=="RT_sRGB_gBT709" || profile=="RT_sRGB_g10") profileCalc="sRGB"; + if (profile=="ProPhoto" || profile=="RT_Large_gBT709" || profile=="RT_Large_g10" || profile=="RT_Large_gsRGB") profileCalc="ProPhoto"; + if (profile=="AdobeRGB1998" || profile=="RT_Medium_gsRGB") profileCalc="Adobe RGB"; + if (profile=="WideGamutRGB") profileCalc="WideGamut"; + } + if(options.rtSettings.HistogramWorking) {//display working + if (profileW=="sRGB") {//apply sRGB inverse gamma + + if ( var_R > 0.04045 ) + var_R = pow ( ( ( var_R + 0.055 ) / 1.055 ), rtengine::Color::sRGBGammaCurve); + else + var_R = var_R / 12.92; + if ( var_G > 0.04045 ) + var_G = pow ( ( ( var_G + 0.055 ) / 1.055 ), rtengine::Color::sRGBGammaCurve); + else + var_G = var_G / 12.92; + if ( var_B > 0.04045 ) + var_B = pow ( ( ( var_B + 0.055 ) / 1.055 ), rtengine::Color::sRGBGammaCurve); + else + var_B = var_B / 12.92; + } + else + if (profileW=="ProPhoto") {// apply inverse gamma 1.8 + var_R = pow ( var_R, 1.8); + var_G = pow ( var_G, 1.8); + var_B = pow ( var_B, 1.8); + } + else {// apply inverse gamma 2.2 + var_R = pow ( var_R, 2.2); + var_G = pow ( var_G, 2.2); + var_B = pow ( var_B, 2.2); + } + } + else {//display outout profile + + if (profile=="RT_sRGB" || profile=="RT_Large_gsRGB" || profile=="RT_Medium_gsRGB") {//apply sRGB inverse gamma + if ( var_R > 0.04045 ) + var_R = pow ( ( ( var_R + 0.055 ) / 1.055 ), rtengine::Color::sRGBGammaCurve); + else + var_R = var_R / 12.92; + if ( var_G > 0.04045 ) + var_G = pow ( ( ( var_G + 0.055 ) / 1.055 ), rtengine::Color::sRGBGammaCurve); + else + var_G = var_G / 12.92; + if ( var_B > 0.04045 ) + var_B = pow ( ( ( var_B + 0.055 ) / 1.055 ), rtengine::Color::sRGBGammaCurve); + else + var_B = var_B / 12.92; + } + + else if (profile=="RT_sRGB_gBT709" || profile=="RT_Large_gBT709") {// + if ( var_R > 0.0795 ) + var_R = pow ( ( ( var_R + 0.0954 ) / 1.0954 ), 2.2);else var_R=var_R/4.5; + + if ( var_G > 0.0795 ) + var_G = pow ( ( ( var_G + 0.0954 ) / 1.0954 ), 2.2);else var_G=var_G/4.5; + + if ( var_B > 0.0795 ) + var_B = pow ( ( ( var_B + 0.0954 ) / 1.0954 ), 2.2);else var_B=var_B/4.5; + + } + else if (profile=="ProPhoto") {// apply inverse gamma 1.8 + + var_R = pow ( var_R, 1.8); + var_G = pow ( var_G, 1.8); + var_B = pow ( var_B, 1.8); + } + else if (profile=="RT_sRGB_g10" || profile=="RT_Large_g10") {// apply inverse gamma 1.8 + + var_R = pow ( var_R, 1.); + var_G = pow ( var_G, 1.); + var_B = pow ( var_B, 1.); + } + + else {// apply inverse gamma 2.2 + var_R = pow ( var_R, 2.2); + var_G = pow ( var_G, 2.2); + var_B = pow ( var_B, 2.2); + } + } + // TMatrix wprof = rtengine::ICCStore::getInstance()->workingSpaceMatrix (profileW); + + TMatrix wprof = rtengine::ICCStore::getInstance()->workingSpaceMatrix (profileCalc); + + for (int m=0; m<3; m++) + for (int n=0; n<3; n++) { + xyz_rgb[m][n] = wprof[m][n]; + } + + double varxx,varyy,varzz; + double var_X = ( xyz_rgb[0][0]*var_R + xyz_rgb[0][1]*var_G + xyz_rgb[0][2]*var_B ) / Color::D50x; + double var_Y = ( xyz_rgb[1][0]*var_R + xyz_rgb[1][1]*var_G + xyz_rgb[1][2]*var_B ) ; + double var_Z = ( xyz_rgb[2][0]*var_R + xyz_rgb[2][1]*var_G + xyz_rgb[2][2]*var_B ) / Color::D50z; + + varxx = var_X>ep?cbrt(var_X):( ka * var_X + 16.0) / 116.0 ; + varyy = var_Y>ep?cbrt(var_Y):( ka * var_Y + 16.0) / 116.0 ; + varzz = var_Z>ep?cbrt(var_Z):( ka * var_Z + 16.0) / 116.0 ; + LAB_l = ( 116 * varyy ) - 16; + LAB_a = 500 * ( varxx - varyy ); + LAB_b = 200 * ( varyy - varzz ); + +} diff --git a/rtgui/navigator.h b/rtgui/navigator.h new file mode 100644 index 000000000..999e1a3b1 --- /dev/null +++ b/rtgui/navigator.h @@ -0,0 +1,56 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _NAVIGATOR_ +#define _NAVIGATOR_ + +#include +#include "previewwindow.h" +#include "pointermotionlistener.h" +#include "../rtengine/iccstore.h" + +class Navigator : public Gtk::Frame, public PointerMotionListener { + + typedef const double (*TMatrix)[3]; + + protected: + Gtk::Label* position; + Gtk::Label *R, *G, *B; + Gtk::Label *H, *S, *V; + Gtk::Label *LAB_A, *LAB_B, *LAB_L; + + Gtk::Label *lR, *lG, *lB; + Gtk::Label *lH, *lS, *lV; + Gtk::Label *lLAB_A, *lLAB_B, *lLAB_L; + + void rgb2lab (Glib::ustring profile, Glib::ustring profileW, int r, int g, int b, float &LAB_l, float &LAB_a, float &LAB_b); + + void setInvalid (int fullWidth=-1, int fullHeight=-1); + + public: + PreviewWindow* previewWindow; + + Navigator (); + + // pointermotionlistener interface + // void pointerMoved (bool validPos, int x, int y, int r, int g, int b); + void pointerMoved (bool validPos, Glib::ustring profile, Glib::ustring profileW,int x, int y, int r, int g, int b); + +}; + +#endif diff --git a/rtgui/options.cc b/rtgui/options.cc new file mode 100644 index 000000000..4dcbfcd0b --- /dev/null +++ b/rtgui/options.cc @@ -0,0 +1,1502 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "options.h" +#include +#include +#include +#include "multilangmgr.h" +#include "../rtengine/safekeyfile.h" +#include "addsetids.h" +#include "guiutils.h" +#include "../rtengine/safegtk.h" +#include "version.h" + +#ifdef _OPENMP +#include +#endif + + + +#ifdef WIN32 +#include +// for GCC32 +#ifndef _WIN32_IE +#define _WIN32_IE 0x0600 +#endif +#include +#endif + +// User's settings directory, including images' profiles if used +Glib::ustring Options::rtdir; +// User's cached datas' directory +Glib::ustring Options::cacheBaseDir; + +Options options; +Glib::ustring versionString = VERSION; +Glib::ustring versionSuffixString = VERSION_SUFFIX; +Glib::ustring paramFileExtension = ".pp3"; + +Options::Options () { + + defProfRawMissing = false; + defProfImgMissing = false; + setDefaults (); +} + +const char *DefaultLanguage = "English (US)"; + +inline bool Options::checkProfilePath(Glib::ustring &path) { + if (path.empty()) + return false; + + Glib::ustring p = getUserProfilePath(); + if (!p.empty() && safe_file_test (path+paramFileExtension, Glib::FILE_TEST_EXISTS)) + return true; + + p = getGlobalProfilePath(); + if (!p.empty() && safe_file_test (path+paramFileExtension, Glib::FILE_TEST_EXISTS)) + return true; + else + return false; +} + +bool Options::checkDirPath(Glib::ustring &path, Glib::ustring errString) { + if (safe_file_test (path, Glib::FILE_TEST_EXISTS) && safe_file_test (path, Glib::FILE_TEST_IS_DIR)) + return true; + else { + if (!errString.empty()) printf("%s\n", errString.c_str()); + return false; + } +} + +void Options::updatePaths() { + + Glib::ustring tmpPath; + + userProfilePath = ""; + globalProfilePath = ""; + + if (Glib::path_is_absolute(profilePath)) { + // absolute path + if (!checkDirPath (profilePath, "")) { + safe_g_mkdir_with_parents (profilePath, 511); + if (!checkDirPath (profilePath, "")) // had problems with mkdir_with_parents return value on OS X, just check dir again + printf("Error: user's profiles' directory \"%s\" creation failed\n", profilePath.c_str()); + } + if (checkDirPath (profilePath, "Error: the specified user's profiles' path doesn't point to a directory or doesn't exist!\n")) { + if (multiUser) { + userProfilePath = profilePath; + tmpPath = Glib::build_filename(argv0, "profiles"); + if(checkDirPath (tmpPath, "Error: the global's profiles' path doesn't point to a directory or doesn't exist!\n")) { + if (userProfilePath != tmpPath) + globalProfilePath = tmpPath; + } + } + else { + globalProfilePath = profilePath; + } + } + else { + tmpPath = Glib::build_filename(argv0, "profiles"); + if(checkDirPath (tmpPath, "Error: the global's profiles' path doesn't point to a directory or doesn't exist!\n")) { + globalProfilePath = tmpPath; + } + } + } + else { + // relative paths + if (multiUser) { + tmpPath = Glib::build_filename(rtdir, profilePath); + if (!checkDirPath (tmpPath, "")) { + safe_g_mkdir_with_parents (tmpPath, 511); + if (!checkDirPath (tmpPath, "")) + printf("Error: user's profiles' directory \"%s\" creation failed\n", tmpPath.c_str()); + } + if(checkDirPath (tmpPath, "Error: the specified user's profiles' path doesn't point to a directory!\n")) { + userProfilePath = tmpPath; + } + tmpPath = Glib::build_filename(argv0, "profiles"); + if(checkDirPath (tmpPath, "Error: the specified user's profiles' path doesn't point to a directory or doesn't exist!\n")) { + globalProfilePath = tmpPath; + } + } + else { + // common directory + // directory name set in options is ignored, we use the default directory name + tmpPath = Glib::build_filename(argv0, "profiles"); + if(checkDirPath (tmpPath, "Error: no global profiles' directory found!\n")) { + globalProfilePath = tmpPath; + } + } + } + + Glib::ustring preferredPath = getPreferredProfilePath(); + // Paths are updated only if the user or global profile path is set + if (lastRgbCurvesDir.empty() || !safe_file_test (lastRgbCurvesDir, Glib::FILE_TEST_EXISTS) || !safe_file_test (lastRgbCurvesDir, Glib::FILE_TEST_IS_DIR)) + lastRgbCurvesDir = preferredPath; + if (lastLabCurvesDir.empty() || !safe_file_test (lastLabCurvesDir, Glib::FILE_TEST_EXISTS) || !safe_file_test (lastLabCurvesDir, Glib::FILE_TEST_IS_DIR)) + lastLabCurvesDir = preferredPath; + if (lastDenoiseCurvesDir.empty() || !safe_file_test (lastDenoiseCurvesDir, Glib::FILE_TEST_EXISTS) || !safe_file_test (lastDenoiseCurvesDir, Glib::FILE_TEST_IS_DIR)) + lastDenoiseCurvesDir = preferredPath; + if (lastWaveletCurvesDir.empty() || !safe_file_test (lastWaveletCurvesDir, Glib::FILE_TEST_EXISTS) || !safe_file_test (lastWaveletCurvesDir, Glib::FILE_TEST_IS_DIR)) + lastWaveletCurvesDir = preferredPath; + + if (lastPFCurvesDir.empty() || !safe_file_test (lastPFCurvesDir, Glib::FILE_TEST_EXISTS) || !safe_file_test (lastPFCurvesDir, Glib::FILE_TEST_IS_DIR)) + lastPFCurvesDir = preferredPath; + if (lastHsvCurvesDir.empty() || !safe_file_test (lastHsvCurvesDir, Glib::FILE_TEST_EXISTS) || !safe_file_test (lastHsvCurvesDir, Glib::FILE_TEST_IS_DIR)) + lastHsvCurvesDir = preferredPath; + if (lastToneCurvesDir.empty() || !safe_file_test (lastToneCurvesDir, Glib::FILE_TEST_EXISTS) || !safe_file_test (lastToneCurvesDir, Glib::FILE_TEST_IS_DIR)) + lastToneCurvesDir = preferredPath; + if (lastProfilingReferenceDir.empty() || !safe_file_test (lastProfilingReferenceDir, Glib::FILE_TEST_EXISTS) || !safe_file_test (lastProfilingReferenceDir, Glib::FILE_TEST_IS_DIR)) + lastProfilingReferenceDir = preferredPath; + if (lastVibranceCurvesDir.empty() || !safe_file_test (lastVibranceCurvesDir, Glib::FILE_TEST_EXISTS) || !safe_file_test (lastVibranceCurvesDir, Glib::FILE_TEST_IS_DIR)) + lastVibranceCurvesDir = preferredPath; + if (loadSaveProfilePath.empty() || !safe_file_test (loadSaveProfilePath, Glib::FILE_TEST_EXISTS) || !safe_file_test (loadSaveProfilePath, Glib::FILE_TEST_IS_DIR)) + loadSaveProfilePath = preferredPath; + if (lastBWCurvesDir.empty() || !safe_file_test (lastBWCurvesDir, Glib::FILE_TEST_EXISTS) || !safe_file_test (lastBWCurvesDir, Glib::FILE_TEST_IS_DIR)) + lastBWCurvesDir = preferredPath; + +} + +Glib::ustring Options::getPreferredProfilePath() { + if (!userProfilePath.empty()) + return userProfilePath; + else if (!globalProfilePath.empty()) + return globalProfilePath; + else + return ""; +} + +/** @brief Get the absolute path of the given filename or the "Neutral" special value + * + *@param profName path + filename of the procparam to look for. A filename without path can be provided for backward compatibility. + * In this case, this parameter will be update with the new format. + *@return Send back the absolute path of the given filename or "Neutral" if "Neutral" has been set to profName. Implementor will have + * to test for this particular value. If the absolute path is invalid (e.g. the file doesn't exist), it will return an empty string. + */ +Glib::ustring Options::findProfilePath(Glib::ustring &profName) { + if (profName.empty()) + return ""; + + if (profName == DEFPROFILE_INTERNAL) + return profName; + + Glib::ustring p = profName.substr(0, 4); + if (p=="${U}") { + // the path starts by the User virtual path + p = getUserProfilePath(); + Glib::ustring fullPath = Glib::build_filename(p, profName.substr(5) + paramFileExtension); + if (!p.empty() && safe_file_test (fullPath, Glib::FILE_TEST_EXISTS)) + return Glib::path_get_dirname(fullPath); + } + else if (p=="${G}") { + // the path starts by the User virtual path + p = getGlobalProfilePath(); + Glib::ustring fullPath = Glib::build_filename(p, profName.substr(5) + paramFileExtension); + if (!p.empty() && safe_file_test (fullPath, Glib::FILE_TEST_EXISTS)) + return Glib::path_get_dirname(fullPath); + } + else { + // compatibility case -> convert the path to the new format + p = getUserProfilePath(); + Glib::ustring fullPath = Glib::build_filename(p, profName + paramFileExtension); + if (!p.empty() && safe_file_test (fullPath, Glib::FILE_TEST_EXISTS)) { + // update the profile path + profName = Glib::build_filename("${U}", profName); + return Glib::path_get_dirname(fullPath); + } + + p = getGlobalProfilePath(); + fullPath = Glib::build_filename(p, profName + paramFileExtension); + if (!p.empty() && safe_file_test (fullPath, Glib::FILE_TEST_EXISTS)) { + profName = Glib::build_filename("${G}", profName); + return Glib::path_get_dirname(fullPath); + } + } + return ""; + +} + +void Options::setDefaults () { + + font = "sans, 8"; + windowWidth = 1200; + windowHeight = 680; + windowX = 0; + windowY = 0; + windowMaximized = true; + saveAsDialogWidth = 920; + saveAsDialogHeight = 680; + savesParamsAtExit = true; + saveFormat.format = "jpg"; + saveFormat.jpegQuality = 92; + saveFormat.jpegSubSamp = 2; + saveFormat.pngCompression = 6; + saveFormat.pngBits = 8; + saveFormat.tiffBits = 16; + saveFormat.tiffUncompressed = true; + saveFormat.saveParams = true; + + saveFormatBatch.format = "jpg"; + saveFormatBatch.jpegQuality = 92; + saveFormatBatch.jpegSubSamp = 2; + saveFormatBatch.pngCompression = 6; + saveFormatBatch.pngBits = 8; + saveFormatBatch.tiffBits = 16; + saveFormatBatch.tiffUncompressed = true; + saveFormatBatch.saveParams = true; + + savePathTemplate = "%p1/converted/%f"; + savePathFolder = ""; + saveUsePathTemplate = true; + defProfRaw = DEFPROFILE_RAW; + defProfImg = DEFPROFILE_IMG; + dateFormat = "%y-%m-%d"; + adjusterDelay = 0; + startupDir = STARTUPDIR_LAST; + startupPath = ""; + useBundledProfiles = true; + detailWindowWidth = -1; + detailWindowHeight = -1; + dirBrowserWidth = 260; + dirBrowserHeight = 350; + dirBrowserSortType = Gtk::SORT_ASCENDING; + preferencesWidth = 800; + preferencesHeight = 0; + toolPanelWidth = 400; + browserToolPanelWidth = 465; + browserToolPanelHeight = 600; + browserToolPanelOpened = true;; + browserDirPanelOpened = true; + editorFilmStripOpened = true; + historyPanelWidth = 330; + lastScale = 5; + panAccelFactor = 5; + rememberZoomAndPan = true; + lastCropSize = 1; + fbOnlyRaw = false; + fbShowDateTime = true; + fbShowBasicExif = true; + fbShowExpComp = false; + fbShowHidden = false; + fbArrangement = 2; // was 0 + multiUser = true; + profilePath = "profiles"; + loadSaveProfilePath = ""; // will be corrected in load as otherwise construction fails + version = "0.0.0.0"; // temporary value; will be correctly set in RTWindow::on_realize + thumbSize = 240; + thumbSizeTab = 180; + thumbSizeQueue = 160; + sameThumbSize = true; // preferring speed of switch between file browser and single editor tab + showHistory = true; + showFilePanelState = 0; // Not used anymore ; was the thumb strip state + showInfo = true; + cropPPI = 600; + showClippedHighlights = false; + showClippedShadows = false; + highlightThreshold = 253; // was 254 + shadowThreshold = 8; // was 0 + bgcolor = 0; + blinkClipped = false; + language = DefaultLanguage; + languageAutoDetect= langMgr.isOSLanguageDetectSupported(); + lastSaveAsPath = ""; + overwriteOutputFile = false; // if TRUE, existing output JPGs/PNGs are overwritten, instead of adding ..-1.jpg, -2.jpg etc. + theme = "25-Gray-Gray"; + slimUI = false; + useSystemTheme = false; + maxThumbnailHeight = 250; + maxCacheEntries = 20000; + thumbInterp = 1; + autoSuffix = true; + forceFormatOpts = true; + saveMethodNum = 0; // 0->immediate, 1->putToQueuHead, 2->putToQueueTail + saveParamsFile = true; // was false, but saving the procparams files next to the file make more sense when reorganizing file tree than in a cache + saveParamsCache = false; // there's no need to save the procparams files in a cache if saveParamsFile is true + paramsLoadLocation = PLL_Input; // was PLL_Cache + procQueueEnabled = false; + gimpDir = ""; + psDir = ""; + customEditorProg = ""; + editorToSendTo = 1; + liveThumbnails = true; + favoriteDirs.clear(); + tpOpen.clear (); + //crvOpen.clear (); + parseExtensions.clear (); + parseExtensionsEnabled.clear (); + parsedExtensions.clear (); + renameUseTemplates = false; + renameTemplates.clear (); + thumbnailZoomRatios.clear (); + thumbnailZoomRatios.push_back (0.2); + thumbnailZoomRatios.push_back (0.3); + thumbnailZoomRatios.push_back (0.45); + thumbnailZoomRatios.push_back (0.6); + thumbnailZoomRatios.push_back (0.8); + thumbnailZoomRatios.push_back (1.0); + overlayedFileNames = false; + filmStripOverlayedFileNames = false; + internalThumbIfUntouched = true; // if TRUE, only fast, internal preview images are taken if the image is not edited yet + showFileNames = true; + filmStripShowFileNames = false; + tabbedUI = false; + mainNBVertical = true; + multiDisplayMode = 0; + tunnelMetaData = true; + histogramPosition = 1; + histogramBar = true; + histogramFullMode = false; + curvebboxpos = 1; + prevdemo = PD_Sidecar; + rgbDenoiseThreadLimit = 0; +#if defined( _OPENMP ) && defined( __x86_64__ ) + clutCacheSize = omp_get_num_procs(); +#else + clutCacheSize = 1; +#endif + filledProfile = false; + maxInspectorBuffers = 2; // a rather conservative value for low specced systems... + serializeTiffRead = true; + + FileBrowserToolbarSingleRow = false; + hideTPVScrollbar = false; + UseIconNoText = true; + whiteBalanceSpotSize = 8; + showFilmStripToolBar = false; + menuGroupRank = true; + menuGroupLabel = true; + menuGroupFileOperations = true; + menuGroupProfileOperations = true; + menuGroupExtProg = true; + + fastexport_bypass_sharpening = true; + fastexport_bypass_sharpenEdge = true; + fastexport_bypass_sharpenMicro = true; + //fastexport_bypass_lumaDenoise = true; + //fastexport_bypass_colorDenoise = true; + fastexport_bypass_defringe = true; + fastexport_bypass_dirpyrDenoise = true; + fastexport_bypass_sh_hq = true; + fastexport_bypass_dirpyrequalizer = true; + fastexport_bypass_wavelet = true; + fastexport_raw_bayer_method = "fast"; + //fastexport_bypass_raw_bayer_all_enhance = true; + fastexport_bypass_raw_bayer_dcb_iterations = true; + fastexport_bypass_raw_bayer_dcb_enhance = true; + fastexport_bypass_raw_bayer_lmmse_iterations = true; + fastexport_bypass_raw_bayer_linenoise = true; + fastexport_bypass_raw_bayer_greenthresh = true; + fastexport_raw_xtrans_method = "fast"; + fastexport_bypass_raw_ccSteps = true; + fastexport_bypass_raw_ca = true; + fastexport_bypass_raw_df = true; + fastexport_bypass_raw_ff = true; + fastexport_icm_input = "(camera)"; + fastexport_icm_working = "ProPhoto"; + fastexport_icm_output = "RT_sRGB"; + fastexport_icm_gamma = "default"; + fastexport_resize_enabled = true; + fastexport_resize_scale = 1; + fastexport_resize_appliesTo = "Cropped area"; + fastexport_resize_method = "Lanczos"; + fastexport_resize_dataspec = 3; + fastexport_resize_width = 900; + fastexport_resize_height = 900; + + clutsDir = "./cluts"; + + cutOverlayBrush = std::vector (4); + cutOverlayBrush[3] = 0.667; // :-p + + navGuideBrush = std::vector (4); + //default to red + navGuideBrush[0] = 1.0; + navGuideBrush[1] = 0.0; + navGuideBrush[2] = 0.0; + navGuideBrush[3] = 1.0; + + sndEnable=true; + sndLngEditProcDoneSecs=3.0; +#ifdef __linux__ + sndBatchQueueDone = "complete"; + sndLngEditProcDone = "window-attention"; +#endif + + // Reminder: 0 = SET mode, 1 = ADD mode + int babehav[] = { + 0, // ADDSET_TC_EXPCOMP + 0, // ADDSET_TC_BRIGHTNESS + 0, // ADDSET_TC_BLACKLEVEL + 0, // ADDSET_TC_CONTRAST + 0, // ADDSET_SH_HIGHLIGHTS + 0, // ADDSET_SH_SHADOWS + 0, // ADDSET_SH_LOCALCONTRAST + 0, // ADDSET_LC_BRIGHTNESS + 0, // ADDSET_LC_CONTRAST + 0, // ADDSET_SHARP_AMOUNT + 0, // ADDSET_WB_TEMPERATURE + 0, // ADDSET_WB_GREEN + 0, // ADDSET_ROTATE_DEGREE + 0, // ADDSET_DIST_AMOUNT + 0, // ADDSET_PERSPECTIVE + 0, // ADDSET_CA + 0, // ADDSET_VIGN_AMOUNT + 0, // ADDSET_VIGN_RADIUS + 0, // ADDSET_VIGN_STRENGTH + 0, // ADDSET_VIGN_CENTER + 0, // ADDSET_LC_CHROMATICITY + 0, // ADDSET_TC_SATURATION + 0, // ADDSET_TC_HLCOMPAMOUNT + 0, // ADDSET_TC_HLCOMPTHRESH + 0, // ADDSET_TC_SHCOMP + 0, // ADDSET_DIRPYREQ + 0, // ADDSET_DIRPYRDN_LUMA + 0, // ADDSET_DIRPYRDN_LUDET + 0, // ADDSET_DIRPYRDN_CHROMA + 0, // ADDSET_DIRPYRDN_CHROMARED + 0, // ADDSET_DIRPYRDN_CHROMABLUE + 0, // ADDSET_DIRPYRDN_GAMMA + 0, // ADDSET_CHMIXER + 0, // ADDSET_PREPROCESS_GREENEQUIL + 0, // ADDSET_PREPROCESS_LINEDENOISE + 0, // ADDSET_RAWCACORR + 0, // ADDSET_RAWEXPOS_LINEAR + 0, // ADDSET_RAWEXPOS_PRESER + 0, // ADDSET_RAWEXPOS_BLACKS + 0, // ADDSET_SHARPENEDGE_AMOUNT + 0, // ADDSET_SHARPENMICRO_AMOUNT + 0, // ADDSET_SHARPENEDGE_PASS + 0, // ADDSET_SHARPENMICRO_UNIFORMITY + 0, // ADDSET_VIBRANCE_PASTELS + 0, // ADDSET_VIBRANCE_SATURATED + 0, // ADDSET_FREE_OUPUT_GAMMA + 0, // ADDSET_FREE_OUTPUT_SLOPE + 0, // ADDSET_CAT_DEGREE + 0, // ADDSET_CAT_ADAPSCEN + 0, // ADDSET_CAT_ADAPLUM + 0, // ADDSET_CAT_LIGHT + 0, // ADDSET_CAT_RSTPRO + 0, // ADDSET_CAT_BADPIX + 0, // ADDSET_CAT_JLIGHT + 0, // ADDSET_CAT_CHROMA + 0, // ADDSET_CAT_CONTRAST + 0, // ADDSET_CAT_CHROMA_S + 0, // ADDSET_CAT_CHROMA_M + 0, // ADDSET_CAT_HUE + 0, // ADDSET_CAT_BADPIX + 0, // ADDSET_WB_EQUAL + 0, // ADDSET_GRADIENT_DEGREE + 0, // ADDSET_GRADIENT_FEATHER + 0, // ADDSET_GRADIENT_STRENGTH + 0, // ADDSET_GRADIENT_CENTER + 0, // ADDSET_PCVIGNETTE_STRENGTH + 0, // ADDSET_PCVIGNETTE_FEATHER + 0, // ADDSET_PCVIGNETTE_ROUNDNESS + 0, // ADDSET_BLACKWHITE_HUES + 0, // ADDSET_BLACKWHITE_GAMMA + 0, // ADDSET_DIRPYREQ_THRESHOLD + 0, // ADDSET_DIRPYREQ_SKINPROTECT + 0, // ADDSET_COLORTONING_SPLIT + 0, //ADDSET_DIRPYRDN_PASSES + 0, // ADDSET_RAWFFCLIPCONTROL + 0, // ADDSET_FILMSIMULATION_STRENGTH + 0, //ADDSET_WA + 0, //ADDSET_WA_THRESHOLD + 0, //ADDSET_WA_THRESHOLD2 + 0, //ADDSET_WA_THRES + 0, //ADDSET_WA_CHRO + 0, //ADDSET_WA_CHROMA + 0, //ADDSET_WA_CONTRAST + 0, //ADDSET_WA_SKINPROTECT + 0, //ADDSET_WA_RESCHRO + 0, //ADDSET_WA_RESCON + 0, //ADDSET_WA_RESCONH + 0, //ADDSET_WA_THRR + 0, //ADDSET_WA_THRRH + 0, //ADDSET_WA_SKYPROTECT + 0, //ADDSET_WA_EDGRAD + 0, //ADDSET_WA_EDGVAL + 0, //ADDSET_WA_STRENGTH + 0, //ADDSET_WA_EDGEDETECT + 0, //ADDSET_WA_EDGEDETECTTHR + 0, //ADDSET_WA_EDGEDETECTTHR2 + 0, //ADDSET_WA_TMRS + 0, //ADDSET_WA_GAMMA + + }; + baBehav = std::vector (babehav, babehav+ADDSET_PARAM_NUM); + + rtSettings.darkFramesPath = ""; + rtSettings.flatFieldsPath = ""; +#ifdef WIN32 + const gchar* sysRoot = g_getenv("SystemRoot"); // Returns e.g. "c:\Windows" + if (sysRoot!=NULL) + rtSettings.iccDirectory = Glib::ustring(sysRoot) + Glib::ustring("\\System32\\spool\\drivers\\color"); + else + rtSettings.iccDirectory = "C:\\WINDOWS\\System32\\spool\\drivers\\color"; +#elif defined __APPLE__ + rtSettings.iccDirectory = "/library/ColorSync/Profiles/Displays"; +#else + rtSettings.iccDirectory = "/usr/share/color/icc"; +#endif + rtSettings.colorimetricIntent = 1; + rtSettings.viewingdevice=0; + rtSettings.viewingdevicegrey=3; + rtSettings.viewinggreySc=1; + rtSettings.leveldnv=2; + rtSettings.leveldnti=0; + rtSettings.leveldnaut=0; + rtSettings.leveldnliss=0; + rtSettings.leveldnautsimpl=0; + + rtSettings.monitorProfile = ""; + rtSettings.autoMonitorProfile = false; + rtSettings.adobe = "RT_Medium_gsRGB"; // put the name of yours profiles (here windows) + rtSettings.prophoto = "RT_Large_gBT709"; // these names appear in the menu "output profile" + rtSettings.prophoto10 = "RT_Large_g10"; // these names appear in the menu "output profile" + rtSettings.srgb10 = "RT_sRGB_g10"; + rtSettings.widegamut = "WideGamutRGB"; + rtSettings.srgb = "RT_sRGB"; + rtSettings.bruce = "Bruce"; + rtSettings.beta = "BetaRGB"; + rtSettings.best = "BestRGB"; + rtSettings.verbose = false; + rtSettings.gamutICC = true; + rtSettings.gamutLch = true; + rtSettings.amchroma = 40;//between 20 and 140 low values increase effect..and also artefacts, high values reduces + rtSettings.artifact_cbdl = 4.; + rtSettings.level0_cbdl = 0; + rtSettings.level123_cbdl = 30; + rtSettings.bot_left=0; + rtSettings.top_left=10; + rtSettings.top_right=40; + rtSettings.bot_right=75; + rtSettings.ed_detec=3;//between 2 and 10 + rtSettings.ed_detecStr=1.3;//not use + rtSettings.ed_low=15.;//between 5 to 40 + rtSettings.ed_lipinfl=0.8;//between 0.5 to 0.9 + rtSettings.ed_lipampl=1.1;//between 1 and 2 + + + rtSettings.ciecamfloat = true; + rtSettings.protectred = 60; + rtSettings.protectredh = 0.3; + rtSettings.CRI_color =0; + rtSettings.autocielab=true; + rtSettings.denoiselabgamma=2; + rtSettings.HistogramWorking = false; + + rtSettings.daubech = false; + + rtSettings.nrauto = 10;//between 2 and 20 + rtSettings.nrautomax = 40;//between 5 and 100 + rtSettings.nrhigh = 0.45;//between 0.1 and 0.9 + rtSettings.nrwavlevel = 1;//integer between 0 and 2 + + // rtSettings.colortoningab =0.7; +//rtSettings.decaction =0.3; +// rtSettings.ciebadpixgauss=false; + rtSettings.rgbcurveslumamode_gamut=true; + lastIccDir = rtSettings.iccDirectory; + lastDarkframeDir = rtSettings.darkFramesPath; + lastFlatfieldDir = rtSettings.flatFieldsPath; +// rtSettings.bw_complementary = true; + // There is no reasonable default for curves. We can still suppose that they will take place + // in a subdirectory of the user's own ProcParams presets, i.e. in a subdirectory + // of the one pointed to by the "profile" field. + // The following fields will then be initialized when "profile" will have its final value, + // at the end of the "updatePaths" method. + lastRgbCurvesDir = ""; + lastLabCurvesDir = ""; + lastDenoiseCurvesDir = ""; + lastWaveletCurvesDir = ""; + lastPFCurvesDir = ""; + lastHsvCurvesDir = ""; + lastToneCurvesDir = ""; + lastVibranceCurvesDir = ""; + lastProfilingReferenceDir = ""; + lastBWCurvesDir = ""; + maxRecentFolders = 15; +} + +Options* Options::copyFrom (Options* other) { + *this = *other; + return this; +} + +void Options::filterOutParsedExtensions () { + parsedExtensions.clear(); + for (unsigned int i=0; i(keyFile.get_integer ("GUI", "SortType")); + if (keyFile.has_key ("GUI", "PreferencesWidth")) preferencesWidth = keyFile.get_integer ("GUI", "PreferencesWidth"); + if (keyFile.has_key ("GUI", "PreferencesHeight")) preferencesHeight = keyFile.get_integer ("GUI", "PreferencesHeight"); + if (keyFile.has_key ("GUI", "SaveAsDialogWidth")) saveAsDialogWidth = keyFile.get_integer ("GUI", "SaveAsDialogWidth"); + if (keyFile.has_key ("GUI", "SaveAsDialogHeight")) saveAsDialogHeight = keyFile.get_integer ("GUI", "SaveAsDialogHeight"); + if (keyFile.has_key ("GUI", "ToolPanelWidth")) toolPanelWidth = keyFile.get_integer ("GUI", "ToolPanelWidth"); + if (keyFile.has_key ("GUI", "BrowserToolPanelWidth")) browserToolPanelWidth = keyFile.get_integer ("GUI", "BrowserToolPanelWidth"); + if (keyFile.has_key ("GUI", "BrowserToolPanelHeight")) browserToolPanelHeight = keyFile.get_integer ("GUI", "BrowserToolPanelHeight"); + if (keyFile.has_key ("GUI", "BrowserToolPanelOpened")) browserToolPanelOpened = keyFile.get_boolean ("GUI", "BrowserToolPanelOpened"); + if (keyFile.has_key ("GUI", "BrowserDirPanelOpened")) browserDirPanelOpened = keyFile.get_boolean ("GUI", "BrowserDirPanelOpened"); + if (keyFile.has_key ("GUI", "EditorFilmStripOpened")) editorFilmStripOpened = keyFile.get_boolean ("GUI", "EditorFilmStripOpened"); + if (keyFile.has_key ("GUI", "HistoryPanelWidth")) historyPanelWidth = keyFile.get_integer ("GUI", "HistoryPanelWidth"); + if (keyFile.has_key ("GUI", "LastPreviewScale")) lastScale = keyFile.get_integer ("GUI", "LastPreviewScale"); + if (keyFile.has_key ("GUI", "PanAccelFactor")) panAccelFactor = keyFile.get_integer ("GUI", "PanAccelFactor"); + if (keyFile.has_key ("GUI", "RememberZoomAndPan")) rememberZoomAndPan = keyFile.get_boolean ("GUI", "RememberZoomAndPan"); + if (keyFile.has_key ("GUI", "LastCropSize")) lastCropSize = keyFile.get_integer ("GUI", "LastCropSize"); + if (keyFile.has_key ("GUI", "ShowHistory")) showHistory = keyFile.get_boolean ("GUI", "ShowHistory"); + if (keyFile.has_key ("GUI", "ShowFilePanelState")) showFilePanelState= keyFile.get_integer ("GUI", "ShowFilePanelState"); + if (keyFile.has_key ("GUI", "ShowInfo")) showInfo = keyFile.get_boolean ("GUI", "ShowInfo"); + if (keyFile.has_key ("GUI", "MainNBVertical")) mainNBVertical = keyFile.get_boolean ("GUI", "MainNBVertical"); + if (keyFile.has_key ("GUI", "ShowClippedHighlights"))showClippedHighlights = keyFile.get_boolean ("GUI", "ShowClippedHighlights"); + if (keyFile.has_key ("GUI", "ShowClippedShadows")) showClippedShadows= keyFile.get_boolean ("GUI", "ShowClippedShadows"); + if (keyFile.has_key ("GUI", "FrameColor")) bgcolor = keyFile.get_integer ("GUI", "FrameColor"); + if (keyFile.has_key ("GUI", "ProcessingQueueEnbled"))procQueueEnabled = keyFile.get_boolean ("GUI", "ProcessingQueueEnbled"); + if (keyFile.has_key ("GUI", "ToolPanelsExpanded")) tpOpen = keyFile.get_integer_list ("GUI", "ToolPanelsExpanded"); + if (keyFile.has_key ("GUI", "MultiDisplayMode")) multiDisplayMode = keyFile.get_integer ("GUI", "MultiDisplayMode"); + //if (keyFile.has_key ("GUI", "CurvePanelsExpanded")) crvOpen = keyFile.get_integer_list ("GUI", "CurvePanelsExpanded"); + if (keyFile.has_key ("GUI", "CutOverlayBrush")) cutOverlayBrush = keyFile.get_double_list ("GUI", "CutOverlayBrush"); + if (keyFile.has_key ("GUI", "NavGuideBrush")) navGuideBrush = keyFile.get_double_list ("GUI", "NavGuideBrush"); + if (keyFile.has_key ("GUI", "HistogramPosition")) histogramPosition = keyFile.get_integer ("GUI", "HistogramPosition"); + if (keyFile.has_key ("GUI", "HistogramBar")) histogramBar = keyFile.get_boolean ("GUI", "HistogramBar"); + if (keyFile.has_key ("GUI", "HistogramFullMode")) histogramFullMode = keyFile.get_boolean ("GUI", "HistogramFullMode"); + if (keyFile.has_key ("GUI", "ShowFilmStripToolBar")) showFilmStripToolBar = keyFile.get_boolean ("GUI", "ShowFilmStripToolBar"); + if (keyFile.has_key ("GUI", "FileBrowserToolbarSingleRow")) FileBrowserToolbarSingleRow = keyFile.get_boolean ("GUI", "FileBrowserToolbarSingleRow"); + if (keyFile.has_key ("GUI", "HideTPVScrollbar")) hideTPVScrollbar = keyFile.get_boolean ("GUI", "HideTPVScrollbar"); + if (keyFile.has_key ("GUI", "UseIconNoText")) UseIconNoText = keyFile.get_boolean ("GUI", "UseIconNoText"); + if (keyFile.has_key ("GUI", "HistogramWorking")) rtSettings.HistogramWorking = keyFile.get_boolean ("GUI", "HistogramWorking"); + if (keyFile.has_key ("GUI", "CurveBBoxPosition")) curvebboxpos = keyFile.get_integer ("GUI", "CurveBBoxPosition"); +} + +if (keyFile.has_group ("Crop Settings")) { + if (keyFile.has_key ("Crop Settings", "PPI")) cropPPI = keyFile.get_integer ("Crop Settings", "PPI"); +} + +if (keyFile.has_group ("Color Management")) { + if (keyFile.has_key ("Color Management", "ICCDirectory")) rtSettings.iccDirectory = keyFile.get_string ("Color Management", "ICCDirectory"); + if (keyFile.has_key ("Color Management", "MonitorProfile")) rtSettings.monitorProfile = keyFile.get_string ("Color Management", "MonitorProfile"); + if (keyFile.has_key ("Color Management", "AutoMonitorProfile")) rtSettings.autoMonitorProfile = keyFile.get_boolean ("Color Management", "AutoMonitorProfile"); + if (keyFile.has_key ("Color Management", "Autocielab")) rtSettings.autocielab = keyFile.get_boolean ("Color Management", "Autocielab"); + if (keyFile.has_key ("Color Management", "RGBcurvesLumamode_Gamut")) rtSettings.rgbcurveslumamode_gamut = keyFile.get_boolean ("Color Management", "RGBcurvesLumamode_Gamut"); + + if (keyFile.has_key ("Color Management", "Intent")) rtSettings.colorimetricIntent = keyFile.get_integer("Color Management", "Intent"); + if (keyFile.has_key ("Color Management", "CRI")) rtSettings.CRI_color = keyFile.get_integer("Color Management", "CRI"); + if (keyFile.has_key ("Color Management", "DenoiseLabgamma"))rtSettings.denoiselabgamma = keyFile.get_integer("Color Management", "DenoiseLabgamma"); + if (keyFile.has_key ("Color Management", "view")) rtSettings.viewingdevice = keyFile.get_integer("Color Management", "view"); + if (keyFile.has_key ("Color Management", "grey")) 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", "CBDLArtif")) rtSettings.artifact_cbdl = keyFile.get_double("Color Management", "CBDLArtif"); + if (keyFile.has_key ("Color Management", "CBDLlevel0")) rtSettings.level0_cbdl = keyFile.get_double("Color Management", "CBDLlevel0"); + if (keyFile.has_key ("Color Management", "CBDLlevel123")) rtSettings.level123_cbdl = keyFile.get_double("Color Management", "CBDLlevel123"); + // if (keyFile.has_key ("Color Management", "Colortoningab")) rtSettings.colortoningab = keyFile.get_double("Color Management", "Colortoningab"); + // if (keyFile.has_key ("Color Management", "Decaction")) rtSettings.decaction = keyFile.get_double("Color Management", "Decaction"); + + if (keyFile.has_key ("Color Management", "WhiteBalanceSpotSize")) whiteBalanceSpotSize = keyFile.get_integer("Color Management", "WhiteBalanceSpotSize"); + if( keyFile.has_key ("Color Management", "GamutICC")) rtSettings.gamutICC = keyFile.get_boolean("Color Management", "GamutICC"); + // if( keyFile.has_key ("Color Management", "BWcomplement")) rtSettings.bw_complementary = keyFile.get_boolean("Color Management", "BWcomplement"); + if( keyFile.has_key ("Color Management", "Ciecamfloat")) rtSettings.ciecamfloat = keyFile.get_boolean("Color Management", "Ciecamfloat"); + if( keyFile.has_key ("Color Management", "AdobeRGB")) rtSettings.adobe = keyFile.get_string("Color Management", "AdobeRGB"); + if( keyFile.has_key ("Color Management", "ProPhoto")) rtSettings.prophoto = keyFile.get_string("Color Management", "ProPhoto"); + if( keyFile.has_key ("Color Management", "ProPhoto10")) rtSettings.prophoto10 = keyFile.get_string("Color Management", "ProPhoto10"); + if( keyFile.has_key ("Color Management", "WideGamut")) rtSettings.widegamut = keyFile.get_string("Color Management", "WideGamut"); + if( keyFile.has_key ("Color Management", "sRGB")) rtSettings.srgb = keyFile.get_string("Color Management", "sRGB"); + if( keyFile.has_key ("Color Management", "sRGB10")) rtSettings.srgb10 = keyFile.get_string("Color Management", "sRGB10"); + if( keyFile.has_key ("Color Management", "Beta")) rtSettings.beta = keyFile.get_string("Color Management", "Beta"); + if( keyFile.has_key ("Color Management", "Best")) rtSettings.best = keyFile.get_string("Color Management", "Best"); + if( keyFile.has_key ("Color Management", "Bruce")) rtSettings.bruce = keyFile.get_string("Color Management", "Bruce"); + if( keyFile.has_key ("Color Management", "GamutLch")) rtSettings.gamutLch = keyFile.get_boolean("Color Management", "GamutLch"); + if( keyFile.has_key ("Color Management", "ProtectRed")) rtSettings.protectred = keyFile.get_integer("Color Management", "ProtectRed"); + if( keyFile.has_key ("Color Management", "ProtectRedH")) rtSettings.protectredh = keyFile.get_double("Color Management", "ProtectRedH"); + if( keyFile.has_key ("Color Management", "Amountchroma")) rtSettings.amchroma = keyFile.get_integer("Color Management", "Amountchroma"); + + if( keyFile.has_key ("Color Management", "ClutsDirectory")) clutsDir = keyFile.get_string("Color Management", "ClutsDirectory"); +// if( keyFile.has_key ("Color Management", "Ciebadpixgauss")) rtSettings.ciebadpixgauss = keyFile.get_boolean("Color Management", "Ciebadpixgauss"); + +} + +if (keyFile.has_group ("Batch Processing")) { + if (keyFile.has_key ("Batch Processing", "AdjusterBehavior")) baBehav = keyFile.get_integer_list ("Batch Processing", "AdjusterBehavior"); +} + +if (keyFile.has_group ("Sounds")) { + if (keyFile.has_key ("Sounds", "Enable")) sndEnable = keyFile.get_boolean ("Sounds", "Enable"); + if (keyFile.has_key ("Sounds", "BatchQueueDone")) sndBatchQueueDone = keyFile.get_string ("Sounds", "BatchQueueDone"); + if (keyFile.has_key ("Sounds", "LngEditProcDone")) sndLngEditProcDone = keyFile.get_string ("Sounds", "LngEditProcDone"); + if (keyFile.has_key ("Sounds", "LngEditProcDoneSecs")) sndLngEditProcDoneSecs = keyFile.get_double ("Sounds", "LngEditProcDoneSecs"); +} + +if (keyFile.has_group ("Fast Export")) { + if (keyFile.has_key ("Fast Export", "fastexport_bypass_sharpening" )) fastexport_bypass_sharpening = keyFile.get_boolean ("Fast Export", "fastexport_bypass_sharpening" ); + if (keyFile.has_key ("Fast Export", "fastexport_bypass_sharpenEdge" )) fastexport_bypass_sharpenEdge = keyFile.get_boolean ("Fast Export", "fastexport_bypass_sharpenEdge" ); + if (keyFile.has_key ("Fast Export", "fastexport_bypass_sharpenMicro" )) fastexport_bypass_sharpenMicro = keyFile.get_boolean ("Fast Export", "fastexport_bypass_sharpenMicro" ); + //if (keyFile.has_key ("Fast Export", "fastexport_bypass_lumaDenoise" )) fastexport_bypass_lumaDenoise = keyFile.get_boolean ("Fast Export", "fastexport_bypass_lumaDenoise" ); + //if (keyFile.has_key ("Fast Export", "fastexport_bypass_colorDenoise" )) fastexport_bypass_colorDenoise = keyFile.get_boolean ("Fast Export", "fastexport_bypass_colorDenoise" ); + if (keyFile.has_key ("Fast Export", "fastexport_bypass_defringe" )) fastexport_bypass_defringe = keyFile.get_boolean ("Fast Export", "fastexport_bypass_defringe" ); + if (keyFile.has_key ("Fast Export", "fastexport_bypass_dirpyrDenoise" )) fastexport_bypass_dirpyrDenoise = keyFile.get_boolean ("Fast Export", "fastexport_bypass_dirpyrDenoise" ); + if (keyFile.has_key ("Fast Export", "fastexport_bypass_sh_hq" )) fastexport_bypass_sh_hq = keyFile.get_boolean ("Fast Export", "fastexport_bypass_sh_hq" ); + if (keyFile.has_key ("Fast Export", "fastexport_bypass_dirpyrequalizer" )) fastexport_bypass_dirpyrequalizer = keyFile.get_boolean ("Fast Export", "fastexport_bypass_dirpyrequalizer" ); + if (keyFile.has_key ("Fast Export", "fastexport_bypass_wavelet" )) fastexport_bypass_wavelet = keyFile.get_boolean ("Fast Export", "fastexport_bypass_wavelet" ); + if (keyFile.has_key ("Fast Export", "fastexport_raw_dmethod" )) fastexport_raw_bayer_method = keyFile.get_string ("Fast Export", "fastexport_raw_dmethod" ); + if (keyFile.has_key ("Fast Export", "fastexport_raw_bayer_method" )) fastexport_raw_bayer_method = keyFile.get_string ("Fast Export", "fastexport_raw_bayer_method" ); + //if (keyFile.has_key ("Fast Export", "fastexport_bypass_raw_bayer_all_enhance" )) fastexport_bypass_raw_bayer_all_enhance = keyFile.get_boolean ("Fast Export", "fastexport_bypass_raw_all_enhance" ); + if (keyFile.has_key ("Fast Export", "fastexport_bypass_raw_dcb_iterations" )) fastexport_bypass_raw_bayer_dcb_iterations = keyFile.get_boolean ("Fast Export", "fastexport_bypass_raw_dcb_iterations" ); + if (keyFile.has_key ("Fast Export", "fastexport_bypass_raw_bayer_dcb_iterations" )) fastexport_bypass_raw_bayer_dcb_iterations = keyFile.get_boolean ("Fast Export", "fastexport_bypass_raw_bayer_dcb_iterations" ); + if (keyFile.has_key ("Fast Export", "fastexport_bypass_raw_dcb_enhance" )) fastexport_bypass_raw_bayer_dcb_enhance = keyFile.get_boolean ("Fast Export", "fastexport_bypass_raw_dcb_enhance" ); + if (keyFile.has_key ("Fast Export", "fastexport_bypass_raw_bayer_dcb_enhance" )) fastexport_bypass_raw_bayer_dcb_enhance = keyFile.get_boolean ("Fast Export", "fastexport_bypass_raw_bayer_dcb_enhance" ); + if (keyFile.has_key ("Fast Export", "fastexport_bypass_raw_lmmse_iterations" )) fastexport_bypass_raw_bayer_lmmse_iterations = keyFile.get_boolean ("Fast Export", "fastexport_bypass_raw_lmmse_iterations" ); + if (keyFile.has_key ("Fast Export", "fastexport_bypass_raw_bayer_lmmse_iterations")) fastexport_bypass_raw_bayer_lmmse_iterations = keyFile.get_boolean ("Fast Export", "fastexport_bypass_raw_bayer_lmmse_iterations"); + if (keyFile.has_key ("Fast Export", "fastexport_bypass_raw_linenoise" )) fastexport_bypass_raw_bayer_linenoise = keyFile.get_boolean ("Fast Export", "fastexport_bypass_raw_linenoise" ); + if (keyFile.has_key ("Fast Export", "fastexport_bypass_raw_bayer_linenoise" )) fastexport_bypass_raw_bayer_linenoise = keyFile.get_boolean ("Fast Export", "fastexport_bypass_raw_bayer_linenoise" ); + if (keyFile.has_key ("Fast Export", "fastexport_bypass_raw_greenthresh" )) fastexport_bypass_raw_bayer_greenthresh = keyFile.get_boolean ("Fast Export", "fastexport_bypass_raw_greenthresh" ); + if (keyFile.has_key ("Fast Export", "fastexport_bypass_raw_bayer_greenthresh" )) fastexport_bypass_raw_bayer_greenthresh = keyFile.get_boolean ("Fast Export", "fastexport_bypass_raw_bayer_greenthresh" ); + if (keyFile.has_key ("Fast Export", "fastexport_raw_xtrans_method" )) fastexport_raw_xtrans_method = keyFile.get_string ("Fast Export", "fastexport_raw_xtrans_method" ); + if (keyFile.has_key ("Fast Export", "fastexport_bypass_raw_ccSteps" )) fastexport_bypass_raw_ccSteps = keyFile.get_boolean ("Fast Export", "fastexport_bypass_raw_ccSteps" ); + if (keyFile.has_key ("Fast Export", "fastexport_bypass_raw_ca" )) fastexport_bypass_raw_ca = keyFile.get_boolean ("Fast Export", "fastexport_bypass_raw_ca" ); + if (keyFile.has_key ("Fast Export", "fastexport_bypass_raw_df" )) fastexport_bypass_raw_df = keyFile.get_boolean ("Fast Export", "fastexport_bypass_raw_df" ); + if (keyFile.has_key ("Fast Export", "fastexport_bypass_raw_ff" )) fastexport_bypass_raw_ff = keyFile.get_boolean ("Fast Export", "fastexport_bypass_raw_ff" ); + if (keyFile.has_key ("Fast Export", "fastexport_icm_input" )) fastexport_icm_input = keyFile.get_string ("Fast Export", "fastexport_icm_input" ); + if (keyFile.has_key ("Fast Export", "fastexport_icm_working" )) fastexport_icm_working = keyFile.get_string ("Fast Export", "fastexport_icm_working" ); + if (keyFile.has_key ("Fast Export", "fastexport_icm_output" )) fastexport_icm_output = keyFile.get_string ("Fast Export", "fastexport_icm_output" ); + if (keyFile.has_key ("Fast Export", "fastexport_icm_gamma" )) fastexport_icm_gamma = keyFile.get_string ("Fast Export", "fastexport_icm_gamma" ); + if (keyFile.has_key ("Fast Export", "fastexport_resize_enabled" )) fastexport_resize_enabled = keyFile.get_boolean ("Fast Export", "fastexport_resize_enabled" ); + if (keyFile.has_key ("Fast Export", "fastexport_resize_scale" )) fastexport_resize_scale = keyFile.get_double ("Fast Export", "fastexport_resize_scale" ); + if (keyFile.has_key ("Fast Export", "fastexport_resize_appliesTo" )) fastexport_resize_appliesTo = keyFile.get_string ("Fast Export", "fastexport_resize_appliesTo" ); + if (keyFile.has_key ("Fast Export", "fastexport_resize_method" )) fastexport_resize_method = keyFile.get_string ("Fast Export", "fastexport_resize_method" ); + if (keyFile.has_key ("Fast Export", "fastexport_resize_dataspec" )) fastexport_resize_dataspec = keyFile.get_integer ("Fast Export", "fastexport_resize_dataspec" ); + if (keyFile.has_key ("Fast Export", "fastexport_resize_width" )) fastexport_resize_width = keyFile.get_integer ("Fast Export", "fastexport_resize_width" ); + if (keyFile.has_key ("Fast Export", "fastexport_resize_height" )) fastexport_resize_height = keyFile.get_integer ("Fast Export", "fastexport_resize_height" ); +} + +if (keyFile.has_group ("Dialogs")) { + safeDirGet(keyFile, "Dialogs", "LastIccDir", lastIccDir); + safeDirGet(keyFile, "Dialogs", "LastDarkframeDir", lastDarkframeDir); + safeDirGet(keyFile, "Dialogs", "LastFlatfieldDir", lastFlatfieldDir); + safeDirGet(keyFile, "Dialogs", "LastRgbCurvesDir", lastRgbCurvesDir); + safeDirGet(keyFile, "Dialogs", "LastLabCurvesDir", lastLabCurvesDir); + safeDirGet(keyFile, "Dialogs", "LastDenoiseCurvesDir", lastDenoiseCurvesDir); + safeDirGet(keyFile, "Dialogs", "LastWaveletCurvesDir", lastWaveletCurvesDir); + safeDirGet(keyFile, "Dialogs", "LastPFCurvesDir", lastPFCurvesDir); + safeDirGet(keyFile, "Dialogs", "LastHsvCurvesDir", lastHsvCurvesDir); + safeDirGet(keyFile, "Dialogs", "LastBWCurvesDir", lastBWCurvesDir); + + safeDirGet(keyFile, "Dialogs", "LastToneCurvesDir", lastToneCurvesDir); + safeDirGet(keyFile, "Dialogs", "LastVibranceCurvesDir", lastVibranceCurvesDir); + safeDirGet(keyFile, "Dialogs", "LastProfilingReferenceDir", lastProfilingReferenceDir); +} + +// -------------------------------------------------------------------------------------------------------- + + filterOutParsedExtensions (); + + return 0; + + } + } + catch (Glib::Error &err) { + 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()); + } + catch (...) { + if (options.rtSettings.verbose) + printf("Options::readFromFile / Unknown exception while trying to load \"%s\"!\n", fname.c_str()); + } + + return 1; + +} + +bool Options::safeDirGet(const rtengine::SafeKeyFile& keyFile, const Glib::ustring& section, + const Glib::ustring& entryName, Glib::ustring& destination) +{ + if (keyFile.has_key(section, entryName) && !keyFile.get_string(section, entryName).empty()) { + destination = keyFile.get_string(section, entryName); + return true; + } + return false; +} + +int Options::saveToFile (Glib::ustring fname) { + + rtengine::SafeKeyFile keyFile; + keyFile.set_boolean ("General", "TabbedEditor", tabbedUI); + + keyFile.set_boolean ("General", "StoreLastProfile", savesParamsAtExit); + if (startupDir==STARTUPDIR_HOME) + keyFile.set_string ("General", "StartupDirectory", "home"); + else if (startupDir==STARTUPDIR_CURRENT) + keyFile.set_string ("General", "StartupDirectory", "current"); + else if (startupDir==STARTUPDIR_CUSTOM) + keyFile.set_string ("General", "StartupDirectory", "custom"); + else if (startupDir==STARTUPDIR_LAST) + keyFile.set_string ("General", "StartupDirectory", "last"); + keyFile.set_string ("General", "StartupPath", startupPath); + keyFile.set_string ("General", "DateFormat", dateFormat); + keyFile.set_integer ("General", "AdjusterDelay", adjusterDelay); + keyFile.set_boolean ("General", "MultiUser", multiUser); + keyFile.set_string ("General", "Language", language); + keyFile.set_boolean ("General", "LanguageAutoDetect", languageAutoDetect); + keyFile.set_string ("General", "Theme", theme); + keyFile.set_boolean ("General", "SlimUI", slimUI); + keyFile.set_boolean ("General", "UseSystemTheme", useSystemTheme); + keyFile.set_string ("General", "Version", VERSION); + keyFile.set_string ("General", "DarkFramesPath", rtSettings.darkFramesPath); + keyFile.set_string ("General", "FlatFieldsPath", rtSettings.flatFieldsPath); + keyFile.set_boolean ("General", "Verbose", rtSettings.verbose); + keyFile.set_double ("General", "BotLeft", rtSettings.bot_left); + keyFile.set_double ("General", "TopLeft", rtSettings.top_left); + keyFile.set_double ("General", "TopRight", rtSettings.top_right); + keyFile.set_double ("General", "BotRight", rtSettings.bot_right); + keyFile.set_double ("General", "EDdetec", rtSettings.ed_detec); + keyFile.set_double ("General", "EDdetecStr", rtSettings.ed_detecStr); + keyFile.set_double ("General", "EDLow", rtSettings.ed_low); + keyFile.set_double ("General", "EDLipinfl", rtSettings.ed_lipinfl); + keyFile.set_double ("General", "EDLipampl", rtSettings.ed_lipampl); + + + keyFile.set_integer ("External Editor", "EditorKind", editorToSendTo); + keyFile.set_string ("External Editor", "GimpDir", gimpDir); + keyFile.set_string ("External Editor", "PhotoshopDir", psDir); + keyFile.set_string ("External Editor", "CustomEditor", customEditorProg); + + keyFile.set_boolean ("File Browser", "BrowseOnlyRaw", fbOnlyRaw); + keyFile.set_boolean ("File Browser", "BrowserShowsDate", fbShowDateTime); + keyFile.set_boolean ("File Browser", "BrowserShowsExif", fbShowBasicExif); + keyFile.set_boolean ("File Browser", "BrowserShowsExpComp", fbShowExpComp); + keyFile.set_boolean ("File Browser", "BrowserShowsHidden", fbShowHidden); + keyFile.set_integer ("File Browser", "ThumbnailSize", thumbSize); + keyFile.set_integer ("File Browser", "ThumbnailSizeTab", thumbSizeTab); + keyFile.set_integer ("File Browser", "ThumbnailSizeQueue", thumbSizeQueue); + keyFile.set_integer ("File Browser", "SameThumbSize", sameThumbSize); + keyFile.set_integer ("File Browser", "MaxPreviewHeight", maxThumbnailHeight); + keyFile.set_integer ("File Browser", "MaxCacheEntries", maxCacheEntries); + Glib::ArrayHandle pext = parseExtensions; + keyFile.set_string_list ("File Browser", "ParseExtensions", pext); + Glib::ArrayHandle pextena = parseExtensionsEnabled; + keyFile.set_integer_list ("File Browser", "ParseExtensionsEnabled", pextena); + keyFile.set_integer ("File Browser", "ThumbnailArrangement", fbArrangement); + keyFile.set_integer ("File Browser", "ThumbnailInterpolation", thumbInterp); + keyFile.set_boolean ("File Browser", "LiveThumbnails", liveThumbnails); + Glib::ArrayHandle pfav = favoriteDirs; + keyFile.set_string_list ("File Browser", "FavoriteDirs", pfav); + Glib::ArrayHandle pren = renameTemplates; + keyFile.set_string_list ("File Browser", "RenameTemplates", pren); + keyFile.set_boolean ("File Browser", "RenameUseTemplates", renameUseTemplates); + Glib::ArrayHandle ptzoom = thumbnailZoomRatios; + keyFile.set_double_list ("File Browser", "ThumbnailZoomRatios", ptzoom); + keyFile.set_boolean ("File Browser", "OverlayedFileNames", overlayedFileNames); + keyFile.set_boolean ("File Browser", "FilmStripOverlayedFileNames", filmStripOverlayedFileNames); + keyFile.set_boolean ("File Browser", "ShowFileNames", showFileNames ); + keyFile.set_boolean ("File Browser", "FilmStripShowFileNames", filmStripShowFileNames ); + keyFile.set_boolean ("File Browser", "InternalThumbIfUntouched", internalThumbIfUntouched ); + keyFile.set_boolean ("File Browser", "menuGroupRank", menuGroupRank); + keyFile.set_boolean ("File Browser", "menuGroupLabel", menuGroupLabel); + keyFile.set_boolean ("File Browser", "menuGroupFileOperations", menuGroupFileOperations); + keyFile.set_boolean ("File Browser", "menuGroupProfileOperations", menuGroupProfileOperations); + keyFile.set_boolean ("File Browser", "menuGroupExtProg", menuGroupExtProg); + keyFile.set_integer ("File Browser", "MaxRecentFolders", maxRecentFolders); + { + std::vector temp; + temp.reserve(maxRecentFolders); + for(unsigned int i=0;i tpopen = tpOpen; + keyFile.set_integer_list ("GUI", "ToolPanelsExpanded", tpopen); + keyFile.set_integer ("GUI", "MultiDisplayMode", multiDisplayMode); + keyFile.set_double_list ("GUI", "CutOverlayBrush", cutOverlayBrush); + keyFile.set_double_list ("GUI", "NavGuideBrush", navGuideBrush); + keyFile.set_integer ("GUI", "HistogramPosition", histogramPosition); + keyFile.set_boolean ("GUI", "HistogramBar", histogramBar); + keyFile.set_boolean ("GUI", "HistogramFullMode", histogramFullMode); + keyFile.set_boolean ("GUI", "ShowFilmStripToolBar", showFilmStripToolBar); + keyFile.set_boolean ("GUI", "FileBrowserToolbarSingleRow", FileBrowserToolbarSingleRow); + keyFile.set_boolean ("GUI", "HideTPVScrollbar", hideTPVScrollbar); + keyFile.set_boolean ("GUI", "UseIconNoText", UseIconNoText); + keyFile.set_boolean ("GUI", "HistogramWorking", rtSettings.HistogramWorking); + keyFile.set_integer ("GUI", "CurveBBoxPosition", curvebboxpos); + + //Glib::ArrayHandle crvopen = crvOpen; + //keyFile.set_integer_list ("GUI", "CurvePanelsExpanded", crvopen); + + keyFile.set_integer ("Crop Settings", "PPI", cropPPI); + + keyFile.set_string ("Color Management", "ICCDirectory", rtSettings.iccDirectory); + keyFile.set_string ("Color Management", "MonitorProfile", rtSettings.monitorProfile); + keyFile.set_boolean ("Color Management", "AutoMonitorProfile", rtSettings.autoMonitorProfile); + keyFile.set_boolean ("Color Management", "Autocielab", rtSettings.autocielab); + keyFile.set_boolean ("Color Management", "RGBcurvesLumamode_Gamut", rtSettings.rgbcurveslumamode_gamut); + keyFile.set_integer ("Color Management", "Intent", rtSettings.colorimetricIntent); + keyFile.set_integer ("Color Management", "view", rtSettings.viewingdevice); + keyFile.set_integer ("Color Management", "grey", rtSettings.viewingdevicegrey); + keyFile.set_integer ("Color Management", "greySc", rtSettings.viewinggreySc); + + keyFile.set_string ("Color Management", "AdobeRGB", rtSettings.adobe); + keyFile.set_string ("Color Management", "ProPhoto", rtSettings.prophoto); + keyFile.set_string ("Color Management", "ProPhoto10", rtSettings.prophoto10); + keyFile.set_string ("Color Management", "WideGamut", rtSettings.widegamut); + keyFile.set_string ("Color Management", "sRGB", rtSettings.srgb); + keyFile.set_string ("Color Management", "sRGB10", rtSettings.srgb10); + keyFile.set_string ("Color Management", "Beta", rtSettings.beta); + keyFile.set_string ("Color Management", "Best", rtSettings.best); + keyFile.set_string ("Color Management", "Bruce", rtSettings.bruce); + keyFile.set_integer ("Color Management", "WhiteBalanceSpotSize", whiteBalanceSpotSize); + keyFile.set_boolean ("Color Management", "GamutICC", rtSettings.gamutICC); + // keyFile.set_boolean ("Color Management", "BWcomplement", rtSettings.bw_complementary); + keyFile.set_boolean ("Color Management", "Ciecamfloat", rtSettings.ciecamfloat); + keyFile.set_boolean ("Color Management", "GamutLch", rtSettings.gamutLch); + keyFile.set_integer ("Color Management", "ProtectRed", rtSettings.protectred); + keyFile.set_integer ("Color Management", "Amountchroma", rtSettings.amchroma); + keyFile.set_double ("Color Management", "ProtectRedH", rtSettings.protectredh); + keyFile.set_integer ("Color Management", "CRI", rtSettings.CRI_color); + keyFile.set_integer ("Color Management", "DenoiseLabgamma", rtSettings.denoiselabgamma); +// keyFile.set_boolean ("Color Management", "Ciebadpixgauss", rtSettings.ciebadpixgauss); + keyFile.set_double ("Color Management", "CBDLArtif", rtSettings.artifact_cbdl); + keyFile.set_double ("Color Management", "CBDLlevel0", rtSettings.level0_cbdl); + keyFile.set_double ("Color Management", "CBDLlevel123", rtSettings.level123_cbdl); + // keyFile.set_double ("Color Management", "Colortoningab", rtSettings.colortoningab); +// keyFile.set_double ("Color Management", "Decaction", rtSettings.decaction); + keyFile.set_string ("Color Management", "ClutsDirectory", clutsDir); + + + Glib::ArrayHandle bab = baBehav; + keyFile.set_integer_list ("Batch Processing", "AdjusterBehavior", bab); + + keyFile.set_boolean ("Sounds", "Enable", sndEnable); + keyFile.set_string ("Sounds", "BatchQueueDone", sndBatchQueueDone); + keyFile.set_string ("Sounds", "LngEditProcDone", sndLngEditProcDone); + keyFile.set_double ("Sounds", "LngEditProcDoneSecs", sndLngEditProcDoneSecs); + + + keyFile.set_boolean ("Fast Export", "fastexport_bypass_sharpening" , fastexport_bypass_sharpening ); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_sharpenEdge" , fastexport_bypass_sharpenEdge ); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_sharpenMicro" , fastexport_bypass_sharpenMicro ); + //keyFile.set_boolean ("Fast Export", "fastexport_bypass_lumaDenoise" , fastexport_bypass_lumaDenoise ); + //keyFile.set_boolean ("Fast Export", "fastexport_bypass_colorDenoise" , fastexport_bypass_colorDenoise ); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_defringe" , fastexport_bypass_defringe ); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_dirpyrDenoise" , fastexport_bypass_dirpyrDenoise ); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_sh_hq" , fastexport_bypass_sh_hq ); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_dirpyrequalizer" , fastexport_bypass_dirpyrequalizer ); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_wavelet" , fastexport_bypass_wavelet ); + keyFile.set_string ("Fast Export", "fastexport_raw_bayer_method" , fastexport_raw_bayer_method ); + //keyFile.set_boolean ("Fast Export", "fastexport_bypass_bayer_raw_all_enhance" , fastexport_bypass_raw_bayer_all_enhance ); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_bayer_dcb_iterations" , fastexport_bypass_raw_bayer_dcb_iterations ); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_bayer_dcb_enhance" , fastexport_bypass_raw_bayer_dcb_enhance ); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_bayer_lmmse_iterations", fastexport_bypass_raw_bayer_lmmse_iterations); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_bayer_linenoise" , fastexport_bypass_raw_bayer_linenoise ); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_bayer_greenthresh" , fastexport_bypass_raw_bayer_greenthresh ); + keyFile.set_string ("Fast Export", "fastexport_raw_xtrans_method" , fastexport_raw_xtrans_method ); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_ccSteps" , fastexport_bypass_raw_ccSteps ); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_ca" , fastexport_bypass_raw_ca ); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_df" , fastexport_bypass_raw_df ); + keyFile.set_boolean ("Fast Export", "fastexport_bypass_raw_ff" , fastexport_bypass_raw_ff ); + keyFile.set_string ("Fast Export", "fastexport_icm_input" , fastexport_icm_input ); + keyFile.set_string ("Fast Export", "fastexport_icm_working" , fastexport_icm_working ); + keyFile.set_string ("Fast Export", "fastexport_icm_output" , fastexport_icm_output ); + keyFile.set_string ("Fast Export", "fastexport_icm_gamma" , fastexport_icm_gamma ); + keyFile.set_boolean ("Fast Export", "fastexport_resize_enabled" , fastexport_resize_enabled ); + keyFile.set_double ("Fast Export", "fastexport_resize_scale" , fastexport_resize_scale ); + keyFile.set_string ("Fast Export", "fastexport_resize_appliesTo" , fastexport_resize_appliesTo ); + keyFile.set_string ("Fast Export", "fastexport_resize_method" , fastexport_resize_method ); + keyFile.set_integer ("Fast Export", "fastexport_resize_dataspec" , fastexport_resize_dataspec ); + keyFile.set_integer ("Fast Export", "fastexport_resize_width" , fastexport_resize_width ); + keyFile.set_integer ("Fast Export", "fastexport_resize_height" , fastexport_resize_height ); + + keyFile.set_string ("Dialogs", "LastIccDir", lastIccDir); + keyFile.set_string ("Dialogs", "LastDarkframeDir", lastDarkframeDir); + keyFile.set_string ("Dialogs", "LastFlatfieldDir", lastFlatfieldDir); + keyFile.set_string ("Dialogs", "LastRgbCurvesDir", lastRgbCurvesDir); + keyFile.set_string ("Dialogs", "LastLabCurvesDir", lastLabCurvesDir); + keyFile.set_string ("Dialogs", "LastDenoiseCurvesDir", lastDenoiseCurvesDir); + keyFile.set_string ("Dialogs", "LastWaveletCurvesDir", lastWaveletCurvesDir); + keyFile.set_string ("Dialogs", "LastPFCurvesDir", lastPFCurvesDir); + keyFile.set_string ("Dialogs", "LastHsvCurvesDir", lastHsvCurvesDir); + keyFile.set_string ("Dialogs", "LastBWCurvesDir", lastBWCurvesDir); + keyFile.set_string ("Dialogs", "LastToneCurvesDir", lastToneCurvesDir); + keyFile.set_string ("Dialogs", "LastVibranceCurvesDir", lastVibranceCurvesDir); + keyFile.set_string ("Dialogs", "LastProfilingReferenceDir", lastProfilingReferenceDir); + + FILE *f = safe_g_fopen (fname, "wt"); + if (f==NULL) { + if (options.rtSettings.verbose) + printf("Options::saveToFile / Error: unable to open file \"%s\" with write access!\n", fname.c_str()); + return 1; + } + else { + fprintf (f, "%s", keyFile.to_data().c_str()); + fclose (f); + return 0; + } +} + +bool Options::load () { + + // Find the application data path + + const gchar* path; + Glib::ustring dPath; + + path = g_getenv("RT_SETTINGS"); + if (path != NULL) { + rtdir = Glib::ustring(path); + if (!Glib::path_is_absolute(rtdir)) + return false; + } + else { + #ifdef WIN32 + WCHAR pathW[MAX_PATH]={0}; char pathA[MAX_PATH]; + + if (SHGetSpecialFolderPathW(NULL,pathW,CSIDL_LOCAL_APPDATA,false)) { + WideCharToMultiByte(CP_UTF8,0,pathW,-1,pathA,MAX_PATH,0,0); + rtdir = Glib::build_filename(Glib::ustring(pathA), Glib::ustring(CACHEFOLDERNAME)); + } + #else + rtdir = Glib::build_filename(Glib::ustring(g_get_user_config_dir ()), Glib::ustring(CACHEFOLDERNAME)); + #endif + } + + if (options.rtSettings.verbose) + printf("Settings directory (rtdir) = %s\n", rtdir.c_str()); + + // Set the cache folder in RT's base folder + 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")); + + // Modify the path of the cache folder to the one provided in RT_CACHE environment variable + path = g_getenv("RT_CACHE"); + if (path != NULL) { + cacheBaseDir = Glib::ustring(path); + if (!Glib::path_is_absolute(cacheBaseDir)) + return false; + } + // No environment variable provided, so falling back to the multi user mode, is enabled + else if (options.multiUser) { + #ifdef WIN32 + cacheBaseDir = Glib::build_filename(rtdir, "cache"); + #else + cacheBaseDir = Glib::build_filename(Glib::ustring(g_get_user_cache_dir()), Glib::ustring(CACHEFOLDERNAME)); + #endif + } + + // Check if RT is installed in Multi-User mode + 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 && !safe_g_mkdir_with_parents (rtdir, 511)) { + // Save the option file + options.saveToFile (Glib::build_filename(rtdir, "options")); + } + +#ifdef __APPLE__ + // make sure .local/share exists on OS X so we don't get problems with recently-used.xbel + safe_g_mkdir_with_parents (g_get_user_data_dir(), 511); +#endif + } + + if (options.rtSettings.verbose) + printf("Cache directory (cacheBaseDir) = %s\n", cacheBaseDir.c_str()); + + // Update profile's path and recreate it if necessary + options.updatePaths(); + + // Check default Raw and Img procparams existence + if (options.defProfRaw.empty()) + options.defProfRaw = DEFPROFILE_INTERNAL; + else { + Glib::ustring tmpFName = options.findProfilePath(options.defProfRaw); + if (!tmpFName.empty()) { + if (options.rtSettings.verbose) printf("Raws' default profile \"%s\" found\n", options.defProfRaw.c_str()); + } + else { + if (options.rtSettings.verbose) printf("Raws' default profile \"%s\" not found or not set -> using Internal values\n", options.defProfRaw.c_str()); + options.defProfRaw = DEFPROFILE_INTERNAL; + options.defProfRawMissing = true; + } + } + + if (options.defProfImg.empty()) + options.defProfImg = DEFPROFILE_INTERNAL; + else { + Glib::ustring tmpFName = options.findProfilePath(options.defProfImg); + if (!tmpFName.empty()) { + if (options.rtSettings.verbose) printf("Images' default profile \"%s\" found\n", options.defProfImg.c_str()); + } + else { + if (options.rtSettings.verbose) printf("Images' default profile \"%s\" not found or not set -> using Internal values\n", options.defProfImg.c_str()); + options.defProfImg = DEFPROFILE_INTERNAL; + options.defProfImgMissing = true; + } + } + + //We handle languages using a hierarchy of translations. The top of the hierarchy is default. This includes a default translation for all items + // (most likely using simple English). The next level is the language: for instance, English, French, Chinese, etc. This file should contain a + // generic translation for all items which differ from default. Finally there is the locale. This is region-specific items which differ from the + // language file. These files must be name in the format (), where Language is the name of the language which it inherits from, + // and LC is the local code. Some examples of this would be English (US) (American English), French (FR) (Franch French), French (CA) (Canadian + // French), etc. + // + // Each level will only contain the differences between itself and its parent translation. For instance, English (UK) or English (CA) may + // include the translation "HISTORY_MSG_34;Avoid Colour Clipping" where English would translate it as "HISTORY_MSG_34;Avoid Color Clipping" (note + // the difference in the spelling of 'colour'). + // + // It is important that when naming the translation files, that you stick to the format or (). We depend on that to figure + // out which are the parent translations. Furthermore, there must be a file for each locale () -- you cannot have + // 'French (CA)' unless there is a file 'French'. + + Glib::ustring defaultTranslation = argv0 + "/languages/default"; + Glib::ustring languageTranslation = ""; + Glib::ustring localeTranslation = ""; + + if (options.languageAutoDetect) options.language=langMgr.getOSUserLanguage(); + + if (!options.language.empty()){ + std::vector langPortions = Glib::Regex::split_simple(" ", options.language); + if (langPortions.size() >= 1){ + languageTranslation = argv0 + "/languages/" + langPortions.at(0); + } + if (langPortions.size() >= 2){ + localeTranslation = argv0 + "/languages/" + options.language; + } + } + + langMgr.load(localeTranslation, new MultiLangMgr(languageTranslation, new MultiLangMgr(defaultTranslation))); + + rtengine::init (&options.rtSettings, argv0, rtdir); + + return true; +} + +void Options::save () { + + if (options.multiUser==false) { + options.saveToFile (Glib::build_filename(argv0, "options")); + } + else { + options.saveToFile (Glib::build_filename(rtdir, "options")); + } +} + +/* + * return true if fname ends with one of the retained image file extensions + */ +bool Options::has_retained_extention (Glib::ustring fname) { + + Glib::ustring ext = getExtension(fname).lowercase(); + + if (!ext.empty()) { + // there is an extension to the filename + + // look out if it has one of the retained extensions + for (unsigned int i=0; i=(int)parseExtensionsEnabled.size() || parseExtensionsEnabled[j]; + return false; +} diff --git a/rtgui/options.h b/rtgui/options.h new file mode 100644 index 000000000..cde759862 --- /dev/null +++ b/rtgui/options.h @@ -0,0 +1,323 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _OPTIONS_ +#define _OPTIONS_ + +#include +#include "../rtengine/rtengine.h" + +#define STARTUPDIR_CURRENT 0 +#define STARTUPDIR_HOME 1 +#define STARTUPDIR_CUSTOM 2 +#define STARTUPDIR_LAST 3 + +// Default bundled profile name to use for Raw images +#ifdef WIN32 +#define DEFPROFILE_RAW "${G}\\Default" +#else +#define DEFPROFILE_RAW "${G}/Default" +#endif +// Default bundled profile name to use for Standard images +#define DEFPROFILE_IMG "Neutral" +// Profile name to use for internal values' profile +#define DEFPROFILE_INTERNAL "Neutral" + +class SaveFormat { + + public: + Glib::ustring format; + int pngBits; + int pngCompression; + int jpegQuality; + int jpegSubSamp; // 1=best compression, 3=best quality + int tiffBits; + bool tiffUncompressed; + bool saveParams; + SaveFormat () : format("jpg"), pngBits(8), pngCompression(6), jpegQuality(90), jpegSubSamp(2), tiffBits(8), tiffUncompressed(true), saveParams(true) {}; +}; + +enum ThFileType {FT_Invalid=-1, FT_None=0, FT_Raw=1, FT_Jpeg=2, FT_Tiff=3, FT_Png=4, FT_Custom=5, FT_Tiff16=6, FT_Png16=7, FT_Custom16=8}; +enum PPLoadLocation {PLL_Cache=0, PLL_Input=1}; +enum CPBKeyType {CPBKT_TID=0, CPBKT_NAME=1, CPBKT_TID_NAME=2}; +enum prevdemo_t {PD_Sidecar=1, PD_Fast=0}; + +namespace rtengine { + class SafeKeyFile; +} + +class Options { + + private: + bool defProfRawMissing; + bool defProfImgMissing; + Glib::ustring userProfilePath; + Glib::ustring globalProfilePath; + 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); + /** + * Safely reads a directory from the configuration file and only applies it + * to the provided destination variable if there is a non-empty string in + * the configuration. + * + * @param keyFile file to read configuration from + * @param section name of the section in the configuration file + * @param entryName name of the entry in the configuration file + * @param destination destination variable to store to + * @return @c true if @p destination was changed + */ + bool safeDirGet(const rtengine::SafeKeyFile& keyFile, const Glib::ustring& section, + const Glib::ustring& entryName, Glib::ustring& destination); + + public: + bool savesParamsAtExit; + SaveFormat saveFormat,saveFormatBatch; + Glib::ustring savePathTemplate; + Glib::ustring savePathFolder; + bool saveUsePathTemplate; + Glib::ustring defProfRaw; + Glib::ustring defProfImg; + Glib::ustring dateFormat; + int adjusterDelay; + int startupDir; + Gtk::SortType dirBrowserSortType; + Glib::ustring startupPath; + Glib::ustring profilePath; // can be an absolute or relative path; depending on this value, bundled profiles may not be found + bool useBundledProfiles; // only used if multiUser == true + Glib::ustring loadSaveProfilePath; + Glib::ustring lastSaveAsPath; + int saveAsDialogWidth; + int saveAsDialogHeight; + int toolPanelWidth; + int browserToolPanelWidth; + int browserToolPanelHeight; + bool browserToolPanelOpened; + bool browserDirPanelOpened; + bool editorFilmStripOpened; + int historyPanelWidth; + Glib::ustring font; + int windowWidth; + int windowHeight; + int windowX; + int windowY; + bool windowMaximized; + int detailWindowWidth; + int detailWindowHeight; + int dirBrowserWidth; + int dirBrowserHeight; + int preferencesWidth; + int preferencesHeight; + int lastScale; + int panAccelFactor; + int lastCropSize; + bool fbOnlyRaw; + bool fbShowDateTime; + bool fbShowBasicExif; + bool fbShowExpComp; + bool fbShowHidden; + int fbArrangement; + bool multiUser; + static Glib::ustring rtdir; + Glib::ustring version; + int thumbSize,thumbSizeTab, thumbSizeQueue; + bool sameThumbSize; // Will use only one thumb size for the file browser and the single editor tab, and avoid recomputing them + bool showHistory; + int showFilePanelState; // 0: normal, 1: maximized, 2: normal, 3: hidden + bool showInfo; + bool mainNBVertical; // main notebook vertical tabs? + int cropPPI; + bool showClippedHighlights; + bool showClippedShadows; + int highlightThreshold; + int shadowThreshold; + bool blinkClipped; + int bgcolor; + Glib::ustring language; + bool languageAutoDetect; + Glib::ustring theme; + bool slimUI; + bool useSystemTheme; + static Glib::ustring cacheBaseDir; + bool autoSuffix; + bool forceFormatOpts; + int saveMethodNum; + bool saveParamsFile; + bool saveParamsCache; + PPLoadLocation paramsLoadLocation; + bool procQueueEnabled; + Glib::ustring gimpDir; + Glib::ustring psDir; + Glib::ustring customEditorProg; + Glib::ustring CPBPath; // Custom Profile Builder's path + CPBKeyType CPBKeys; // Custom Profile Builder's key type + int editorToSendTo; + int maxThumbnailHeight; + std::size_t maxCacheEntries; + ThFileType thumbnailFormat; + int thumbInterp; // 0: nearest, 1: bilinear + bool liveThumbnails; + std::vector parseExtensions; // List containing all extensions type + std::vector parseExtensionsEnabled; // List of bool to retain extension or not + std::vector parsedExtensions; // List containing all retained extensions (lowercase) + std::vector tpOpen; + //std::vector crvOpen; + std::vector baBehav; + rtengine::Settings rtSettings; + + std::vector favoriteDirs; + std::vector renameTemplates; + bool renameUseTemplates; + bool internalThumbIfUntouched; + bool overwriteOutputFile; + + std::vector thumbnailZoomRatios; + bool overlayedFileNames; + bool filmStripOverlayedFileNames; + bool showFileNames; + bool filmStripShowFileNames; + bool tabbedUI; + int previewSizeTab,previewSizeBrowser; + bool rememberZoomAndPan; + int multiDisplayMode; // 0=none, 1=Edit panels on other display + std::vector cutOverlayBrush; // Red;Green;Blue;Alpha , all ranging 0..1 + std::vector navGuideBrush; // Red;Green;Blue;Alpha , all ranging 0..1 + + Glib::ustring sndBatchQueueDone; + Glib::ustring sndLngEditProcDone; + double sndLngEditProcDoneSecs; // Minimum processing time seconds till the sound is played + bool sndEnable; + + bool tunnelMetaData; // Pass through IPTC and XMP unchanged + int histogramPosition; // 0=disabled, 1=left pane, 2=right pane + //int histogramWorking; // 0=disabled, 1=left pane, 2=right pane + bool histogramBar; + bool histogramFullMode; + bool showProfileSelector; + bool FileBrowserToolbarSingleRow; + bool hideTPVScrollbar; + bool UseIconNoText; + int whiteBalanceSpotSize; + int curvebboxpos; // 0=above, 1=right, 2=below, 3=left + + bool showFilmStripToolBar; + + // Performance options + Glib::ustring clutsDir; + int rgbDenoiseThreadLimit; // maximum number of threads for the denoising tool ; 0 = use the maximum available + int maxInspectorBuffers; // maximum number of buffers (i.e. images) for the Inspector feature + int clutCacheSize; + bool filledProfile; // Used as reminder for the ProfilePanel "mode" + prevdemo_t prevdemo; // Demosaicing method used for the <100% preview + bool serializeTiffRead; + + bool menuGroupRank; + bool menuGroupLabel; + bool menuGroupFileOperations; + bool menuGroupProfileOperations; + bool menuGroupExtProg; + + // fast export options + bool fastexport_bypass_sharpening; + bool fastexport_bypass_sharpenEdge; + bool fastexport_bypass_sharpenMicro; + //bool fastexport_bypass_lumaDenoise; + //bool fastexport_bypass_colorDenoise; + bool fastexport_bypass_defringe; + bool fastexport_bypass_dirpyrDenoise; + bool fastexport_bypass_sh_hq; + bool fastexport_bypass_dirpyrequalizer; + bool fastexport_bypass_wavelet; + Glib::ustring fastexport_raw_bayer_method; + //bool fastexport_bypass_raw_bayer_all_enhance; + bool fastexport_bypass_raw_bayer_dcb_iterations; + bool fastexport_bypass_raw_bayer_dcb_enhance; + bool fastexport_bypass_raw_bayer_lmmse_iterations; + bool fastexport_bypass_raw_bayer_linenoise; + bool fastexport_bypass_raw_bayer_greenthresh; + Glib::ustring fastexport_raw_xtrans_method; + bool fastexport_bypass_raw_ccSteps; + bool fastexport_bypass_raw_ca; + bool fastexport_bypass_raw_df; + bool fastexport_bypass_raw_ff; + Glib::ustring fastexport_icm_input; + Glib::ustring fastexport_icm_working; + Glib::ustring fastexport_icm_output; + Glib::ustring fastexport_icm_gamma; + bool fastexport_resize_enabled; + double fastexport_resize_scale; + Glib::ustring fastexport_resize_appliesTo; + Glib::ustring fastexport_resize_method; + int fastexport_resize_dataspec; + int fastexport_resize_width; + int fastexport_resize_height; + + // Dialog settings + Glib::ustring lastIccDir; + Glib::ustring lastDarkframeDir; + Glib::ustring lastFlatfieldDir; + Glib::ustring lastRgbCurvesDir; + Glib::ustring lastLabCurvesDir; + Glib::ustring lastDenoiseCurvesDir; + Glib::ustring lastWaveletCurvesDir; + Glib::ustring lastPFCurvesDir; + Glib::ustring lastHsvCurvesDir; + Glib::ustring lastToneCurvesDir; + Glib::ustring lastColorToningCurvesDir; + Glib::ustring lastVibranceCurvesDir; + Glib::ustring lastProfilingReferenceDir; + Glib::ustring lastBWCurvesDir; + + size_t maxRecentFolders; // max. number of recent folders stored in options file + std::vector recentFolders; // List containing all recent folders + + + Options (); + + Options* copyFrom (Options* other); + void filterOutParsedExtensions (); + void setDefaults (); + int readFromFile (Glib::ustring fname); + int saveToFile (Glib::ustring fname); + static bool load (); + static void save (); + + // if multiUser=false, send back the global profile path + Glib::ustring getPreferredProfilePath(); + Glib::ustring getUserProfilePath() { return userProfilePath; } + Glib::ustring getGlobalProfilePath() { return globalProfilePath; } + Glib::ustring findProfilePath(Glib::ustring &profName); + bool has_retained_extention (Glib::ustring fname); + bool is_extention_enabled(Glib::ustring ext); + bool is_defProfRawMissing() { return defProfRawMissing; } + bool is_defProfImgMissing() { return defProfImgMissing; } + void setDefProfRawMissing(bool value) { defProfRawMissing = value; } + void setDefProfImgMissing(bool value) { defProfImgMissing = value; } +}; + +extern Options options; +extern Glib::ustring argv0; +extern Glib::ustring argv1; +extern bool simpleEditor; +extern Glib::ustring versionString; +extern Glib::ustring versionSuffixString; +extern Glib::ustring paramFileExtension; + +#endif diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc new file mode 100644 index 000000000..debc66216 --- /dev/null +++ b/rtgui/paramsedited.cc @@ -0,0 +1,1345 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "paramsedited.h" +#include +#include "options.h" +#include "addsetids.h" + +ParamsEdited::ParamsEdited (bool value) { + + set (value); +} + +void ParamsEdited::set (bool v) { + + general.rank = v; + general.colorlabel = v; + general.intrash = v; + toneCurve.curve = v; + toneCurve.curve2 = v; + toneCurve.curveMode = v; + toneCurve.curveMode2 = v; + toneCurve.brightness = v; + toneCurve.black = v; + toneCurve.contrast = v; + toneCurve.saturation = v; + toneCurve.shcompr = v; + toneCurve.hlcompr = v; + toneCurve.hlcomprthresh = v; + toneCurve.autoexp = v; + toneCurve.clip = v; + toneCurve.expcomp = v; + toneCurve.hrenabled = v; + toneCurve.method = v; + labCurve.lcurve = v; + labCurve.acurve = v; + labCurve.bcurve = v; + labCurve.cccurve = v; + labCurve.chcurve = v; + labCurve.lhcurve = v; + labCurve.hhcurve = v; + labCurve.lccurve = v; + labCurve.clcurve = v; + labCurve.brightness = v; + labCurve.contrast = v; + labCurve.chromaticity = v; + labCurve.avoidcolorshift = v; + labCurve.rstprotection = v; + labCurve.lcredsk = v; + rgbCurves.lumamode = v; + rgbCurves.rcurve = v; + rgbCurves.gcurve = v; + rgbCurves.bcurve = v; + colorToning.enabled = v; + colorToning.autosat = v; + colorToning.opacityCurve = v; + colorToning.colorCurve = v; + colorToning.satprotectionthreshold = v; + colorToning.saturatedopacity = v; + colorToning.strength = v; + colorToning.shadowsColSat = v; + colorToning.hlColSat = v; + colorToning.balance = v; + colorToning.clcurve = v; + colorToning.method = v; + colorToning.twocolor = v; + colorToning.cl2curve = v; + colorToning.redlow = v; + colorToning.greenlow = v; + colorToning.bluelow = v; + colorToning.satlow = v; + colorToning.sathigh = v; + colorToning.redmed = v; + colorToning.greenmed = v; + colorToning.bluemed = v; + colorToning.redhigh = v; + colorToning.greenhigh = v; + colorToning.bluehigh = v; + colorToning.lumamode = v; + + sharpening.enabled = v; + sharpening.radius = v; + sharpening.amount = v; + sharpening.threshold = v; + sharpening.edgesonly = v; + sharpening.edges_radius = v; + sharpening.edges_tolerance = v; + sharpening.halocontrol = v; + sharpening.halocontrol_amount = v; + sharpening.method = v; + sharpening.deconvamount = v; + sharpening.deconvradius = v; + sharpening.deconviter = v; + sharpening.deconvdamping = v; + prsharpening.enabled = v; + prsharpening.radius = v; + prsharpening.amount = v; + prsharpening.threshold = v; + prsharpening.edgesonly = v; + prsharpening.edges_radius = v; + prsharpening.edges_tolerance = v; + prsharpening.halocontrol = v; + prsharpening.halocontrol_amount = v; + prsharpening.method = v; + prsharpening.deconvamount = v; + prsharpening.deconvradius = v; + prsharpening.deconviter = v; + prsharpening.deconvdamping = v; + sharpenEdge.enabled = v; + sharpenEdge.passes = v; + sharpenEdge.amount = v; + sharpenEdge.threechannels = v; + sharpenMicro.enabled = v; + sharpenMicro.matrix = v; + sharpenMicro.amount = v; + sharpenMicro.uniformity = v; + vibrance.enabled = v; + vibrance.pastels = v; + vibrance.saturated = v; + vibrance.psthreshold = v; + vibrance.protectskins = v; + vibrance.avoidcolorshift = v; + vibrance.pastsattog = v; + vibrance.skintonescurve = v; + colorappearance.enabled = v; + colorappearance.degree = v; + colorappearance.autodegree = v; + colorappearance.surround = v; + colorappearance.adapscen = v; + colorappearance.autoadapscen = v; + colorappearance.adaplum = v; + colorappearance.badpixsl = v; + colorappearance.wbmodel = v; + colorappearance.algo = v; + + colorappearance.jlight = v; + colorappearance.qbright = v; + colorappearance.chroma = v; + colorappearance.schroma = v; + colorappearance.mchroma = v; + colorappearance.contrast = v; + colorappearance.qcontrast = v; + colorappearance.colorh = v; + colorappearance.rstprotection = v; + colorappearance.surrsource = v; + colorappearance.gamut = v; +// colorappearance.badpix = v; + colorappearance.datacie = v; + colorappearance.tonecie = v; +// colorappearance.sharpcie = v; + colorappearance.curve = v; + colorappearance.curve2 = v; + colorappearance.curve3 = v; + colorappearance.curveMode = v; + colorappearance.curveMode2 = v; + colorappearance.curveMode3 = v; + + //colorBoost.amount = v; + //colorBoost.avoidclip = v; + //colorBoost.enable_saturationlimiter = v; + //colorBoost.saturationlimit = v; + wb.method = v; + wb.green = v; + wb.temperature = v; + wb.equal = v; + //colorShift.a = v; + //colorShift.b = v; + //lumaDenoise.enabled = v; + //lumaDenoise.radius = v; + //lumaDenoise.edgetolerance = v; + //colorDenoise.enabled = v; + //colorDenoise.amount = v; + defringe.enabled = v; + defringe.radius = v; + defringe.threshold = v; + defringe.huecurve = v; + impulseDenoise.enabled = v; + impulseDenoise.thresh = v; + dirpyrDenoise.enabled = v; + dirpyrDenoise.enhance = v; +// dirpyrDenoise.perform = v; + dirpyrDenoise.lcurve = v; + dirpyrDenoise.cccurve = v; + dirpyrDenoise.median = v; + dirpyrDenoise.autochroma = v; + dirpyrDenoise.luma = v; + dirpyrDenoise.Ldetail = v; + dirpyrDenoise.chroma = v; + dirpyrDenoise.redchro = v; + dirpyrDenoise.bluechro = v; + dirpyrDenoise.gamma = v; + dirpyrDenoise.passes = v; + dirpyrDenoise.dmethod = v; + dirpyrDenoise.Lmethod = v; + dirpyrDenoise.Cmethod = v; + dirpyrDenoise.C2method = v; + dirpyrDenoise.smethod = v; + dirpyrDenoise.medmethod = v; + dirpyrDenoise.methodmed = v; + dirpyrDenoise.rgbmethod = v; + epd.enabled = v; + epd.strength = v; + epd.gamma = v; + epd.edgeStopping = v; + epd.scale = v; + epd.reweightingIterates = v; + sh.enabled = v; + sh.hq = v; + sh.highlights = v; + sh.htonalwidth = v; + sh.shadows = v; + sh.stonalwidth = v; + sh.localcontrast = v; + sh.radius = v; + crop.enabled = v; + crop.x = v; + crop.y = v; + crop.w = v; + crop.h = v; + crop.fixratio = v; + crop.ratio = v; + crop.orientation = v; + crop.guide = v; + coarse.rotate = v; + coarse.hflip = v; + coarse.vflip = v; + commonTrans.autofill = v; + rotate.degree = v; + distortion.amount = v; + lensProf.lcpFile = v; + lensProf.useDist = v; + lensProf.useVign = v; + lensProf.useCA = v; + perspective.horizontal = v; + perspective.vertical = v; + gradient.enabled = v; + gradient.degree = v; + gradient.feather = v; + gradient.strength = v; + gradient.centerX = v; + gradient.centerY = v; + pcvignette.enabled = v; + pcvignette.strength = v; + pcvignette.feather = v; + pcvignette.roundness = v; + cacorrection.red = v; + cacorrection.blue = v; + vignetting.amount = v; + vignetting.radius = v; + vignetting.strength = v; + vignetting.centerX = v; + vignetting.centerY = v; + chmixer.red[0] = v; + chmixer.red[1] = v; + chmixer.red[2] = v; + chmixer.green[0] = v; + chmixer.green[1] = v; + chmixer.green[2] = v; + chmixer.blue[0] = v; + chmixer.blue[1] = v; + chmixer.blue[2] = v; + blackwhite.enabled = v; + blackwhite.enabledcc = v; + blackwhite.mixerRed = v; + blackwhite.mixerOrange = v; + blackwhite.mixerYellow = v; + blackwhite.mixerGreen = v; + blackwhite.mixerCyan = v; + blackwhite.mixerBlue = v; + blackwhite.mixerMagenta = v; + blackwhite.mixerPurple = v; + blackwhite.gammaRed = v; + blackwhite.gammaGreen = v; + blackwhite.gammaBlue = v; + blackwhite.filter = v; + blackwhite.setting = v; + blackwhite.method = v; + blackwhite.luminanceCurve = v; + blackwhite.beforeCurve = v; + blackwhite.beforeCurveMode = v; + blackwhite.afterCurve = v; + blackwhite.afterCurveMode = v; + blackwhite.autoc = v; + blackwhite.algo = v; + + + resize.scale = v; + resize.appliesTo = v; + resize.method = v; + resize.dataspec = v; + resize.width = v; + resize.height = v; + resize.enabled = v; + icm.input = v; + icm.toneCurve = v; + icm.blendCMSMatrix = v; + icm.dcpIlluminant = v; + icm.working = v; + icm.output = v; + icm.gamma = v; + icm.freegamma = v; + icm.gampos = v; + icm.slpos = v; + raw.bayersensor.method = v; + raw.bayersensor.ccSteps = v; + raw.bayersensor.exBlack0 = v; + raw.bayersensor.exBlack1 = v; + raw.bayersensor.exBlack2 = v; + raw.bayersensor.exBlack3 = v; + raw.bayersensor.exTwoGreen=v; + raw.bayersensor.dcbIterations = v; + raw.bayersensor.dcbEnhance = v; + //raw.bayersensor.allEnhance = v; + raw.bayersensor.lmmseIterations = v; + raw.bayersensor.greenEq = v; + raw.bayersensor.linenoise = v; + raw.xtranssensor.method = v; + raw.xtranssensor.ccSteps = v; + raw.xtranssensor.exBlackRed= v; + raw.xtranssensor.exBlackGreen = v; + raw.xtranssensor.exBlackBlue = v; + raw.caCorrection = v; + raw.caBlue = v; + raw.caRed = v; + raw.hotPixelFilter = v; + raw.deadPixelFilter = v; + raw.hotDeadPixelThresh = v; + raw.darkFrame = v; + raw.dfAuto = v; + raw.ff_file = v; + raw.ff_AutoSelect = v; + raw.ff_BlurRadius = v; + raw.ff_BlurType = v; + raw.ff_AutoClipControl = v; + raw.ff_clipControl = v; + raw.exPos = v; + raw.exPreser = v; + wavelet.enabled = v; + wavelet.strength = v; + wavelet.balance = v; + wavelet.iter = v; + wavelet.median = v; + wavelet.medianlev = v; + wavelet.linkedg = v; + wavelet.cbenab = v; + wavelet.greenhigh = v; + wavelet.greenmed = v; + wavelet.greenlow = v; + wavelet.bluehigh = v; + wavelet.bluemed = v; + wavelet.bluelow = v; + wavelet.lipst = v; + wavelet.Medgreinf = v; + wavelet.avoid = v; + wavelet.tmr = v; + wavelet.Lmethod = v; + wavelet.CLmethod = v; + wavelet.Backmethod = v; + wavelet.Tilesmethod = v; + wavelet.daubcoeffmethod = v; + wavelet.CHmethod = v; + wavelet.CHSLmethod = v; + wavelet.EDmethod = v; + wavelet.BAmethod = v; + wavelet.TMmethod = v; + wavelet.HSmethod = v; + wavelet.Dirmethod = v; + wavelet.rescon = v; + wavelet.resconH = v; + wavelet.reschro = v; + wavelet.tmrs = v; + wavelet.gamma = v; + wavelet.sup = v; + wavelet.sky = v; + wavelet.thres = v; + wavelet.threshold = v; + wavelet.threshold2 = v; + wavelet.edgedetect = v; + wavelet.edgedetectthr = v; + wavelet.edgedetectthr2 = v; + wavelet.chroma = v; + wavelet.chro = v; + wavelet.contrast = v; + wavelet.edgrad = v; + wavelet.edgval = v; + wavelet.edgthresh = v; + wavelet.thr = v; + wavelet.thrH = v; + wavelet.skinprotect = v; + wavelet.hueskin = v; + wavelet.hueskin2 = v; + wavelet.hllev = v; + wavelet.bllev = v; + wavelet.edgcont = v; + wavelet.level0noise = v; + wavelet.level1noise = v; + wavelet.level2noise = v; + wavelet.ccwcurve = v; + wavelet.opacityCurveRG = v; + wavelet.opacityCurveBY = v; + wavelet.opacityCurveW = v; + wavelet.opacityCurveWL = v; + wavelet.hhcurve = v; + wavelet.Chcurve = v; + wavelet.wavclCurve = v; + + wavelet.pastlev = v; + wavelet.satlev = v; + + for(int i = 0; i < 9; i++) { + wavelet.c[i] = v; + } + for(int i = 0; i < 9; i++) { + wavelet.ch[i] = v; + } + + dirpyrequalizer.enabled = v; + dirpyrequalizer.gamutlab = v; + for(int i = 0; i < 6; i++) { + dirpyrequalizer.mult[i] = v; + } + dirpyrequalizer.threshold = v; + dirpyrequalizer.skinprotect = v; + dirpyrequalizer.hueskin = v; + //dirpyrequalizer.algo = v; + hsvequalizer.hcurve = v; + hsvequalizer.scurve = v; + hsvequalizer.vcurve = v; + filmSimulation.enabled = v; + filmSimulation.clutFilename = v; + filmSimulation.strength = v; + + exif = v; + iptc = v; +} + +using namespace rtengine; +using namespace rtengine::procparams; + +void ParamsEdited::initFrom (const std::vector& src) { + + set (true); + if (src.empty()) + return; + + const ProcParams& p = src[0]; + for (size_t i=1; ifirst] = i->second; + } + + // IPTC changes are added to the existing ones + if (iptc) + for (procparams::IPTCPairs::const_iterator i=mods.iptc.begin(); i!=mods.iptc.end(); i++) { + toEdit.iptc[i->first] = i->second; + } +} + +bool RAWParamsEdited::BayerSensor::isUnchanged() const { + return method && ccSteps && dcbIterations && dcbEnhance && lmmseIterations/*&& allEnhance*/ && greenEq + && linenoise && exBlack0 && exBlack1 && exBlack2 && exBlack3 && exTwoGreen; +} + +bool RAWParamsEdited::XTransSensor::isUnchanged() const { + return method && ccSteps && exBlackRed && exBlackGreen && exBlackBlue; +} + +bool RAWParamsEdited::isUnchanged() const { + return bayersensor.isUnchanged() && xtranssensor.isUnchanged() && caCorrection && caRed && caBlue && hotPixelFilter && deadPixelFilter && hotDeadPixelThresh && darkFrame + && dfAuto && ff_file && ff_AutoSelect && ff_BlurRadius && ff_BlurType && exPos && exPreser && ff_AutoClipControl && ff_clipControl; +} + +bool LensProfParamsEdited::isUnchanged() const { + return lcpFile; +} diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h new file mode 100644 index 000000000..0aaf0cd99 --- /dev/null +++ b/rtgui/paramsedited.h @@ -0,0 +1,699 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _PARAMEDITED_H_ +#define _PARAMEDITED_H_ + +#include +#include +#include "../rtengine/procparams.h" +#include "../rtengine/rtengine.h" + +class GeneralParamsEdited { + + public: + bool rank; + bool colorlabel; + bool intrash; +}; + +class ToneCurveParamsEdited { + + public: + bool curve; + bool curve2; + bool curveMode; + bool curveMode2; + bool brightness; + bool black; + bool contrast; + bool saturation; + bool shcompr; + bool hlcompr; + bool hlcomprthresh; + bool autoexp; + bool clip; + bool expcomp; + bool hrenabled; + bool method; +}; + +class LCurveParamsEdited { + public: + bool brightness; + bool contrast; + bool chromaticity; + bool avoidcolorshift; + bool rstprotection; + bool lcurve; + bool acurve; + bool bcurve; + bool lcredsk; + bool cccurve; + bool chcurve; + bool lhcurve; + bool hhcurve; + bool lccurve; + bool clcurve; + + bool enabled; + bool method; +}; + +class RGBCurvesParamsEdited { + + public: + bool lumamode; + bool rcurve; + bool gcurve; + bool bcurve; +}; + +class ColorToningEdited { + + public: + bool enabled; + bool opacityCurve; + bool colorCurve; + bool clcurve; + bool method; + bool autosat; + bool satprotectionthreshold; + bool saturatedopacity; + bool strength; + bool shadowsColSat; + bool hlColSat; + bool balance; + bool twocolor; + bool cl2curve; + bool redlow; + bool greenlow; + bool bluelow; + bool redmed; + bool greenmed; + bool bluemed; + bool redhigh; + bool greenhigh; + bool bluehigh; + bool satlow; + bool sathigh; + bool lumamode; +}; + +class SharpenEdgeParamsEdited { + + public : + bool enabled; + bool passes; + bool amount; + bool threechannels; +}; + +class SharpenMicroParamsEdited { + public : + bool enabled; + bool matrix; + bool amount; + bool uniformity; + +}; + +class SharpeningParamsEdited { + + public: + bool enabled; + bool radius; + bool amount; + bool threshold; + bool edgesonly; + bool edges_radius; + bool edges_tolerance; + bool halocontrol; + bool halocontrol_amount; + + bool method; + bool deconvamount; + bool deconvradius; + bool deconviter; + bool deconvdamping; +}; + +class VibranceParamsEdited { + + public: + bool enabled; + bool pastels; + bool saturated; + bool psthreshold; + bool protectskins; + bool avoidcolorshift; + bool pastsattog; + bool skintonescurve; +}; + +/*class ColorBoostParamsEdited { + + public: + bool amount; + bool avoidclip; + bool enable_saturationlimiter; + bool rstprotection; +};*/ + +class WBParamsEdited { + + public: + bool method; + bool temperature; + bool green; + bool equal; +}; + +/*class ColorShiftParamsEdited { + + public: + bool a; + bool b; +};*/ + +/*class LumaDenoiseParamsEdited { + + public: + bool enabled; + bool radius; + bool edgetolerance; +};*/ + +/*class ColorDenoiseParamsEdited { + + public: + bool enabled; + bool amount; +};*/ + +class DefringeParamsEdited { + +public: + bool enabled; + bool radius; + bool threshold; + bool huecurve; +}; + +class ImpulseDenoiseParamsEdited { + +public: + bool enabled; + bool thresh; +}; + +class ColorAppearanceParamsEdited { + +public: + bool curve; + bool curve2; + bool curve3; + bool curveMode; + bool curveMode2; + bool curveMode3; + bool enabled; + bool degree; + bool autodegree; + bool autoadapscen; + bool surround; + bool adapscen; + bool adaplum; + bool badpixsl; + bool wbmodel; + bool algo; + bool jlight; + bool qbright; + bool chroma; + bool schroma; + bool mchroma; + bool contrast; + bool qcontrast; + bool colorh; + bool rstprotection; + bool surrsource; + bool gamut; +// bool badpix; + bool datacie; + bool tonecie; +// bool sharpcie; +}; + +class DirPyrDenoiseParamsEdited { + +public: + bool enabled; + bool enhance; + bool median; + bool autochroma; + bool Ldetail; + bool luma; + bool chroma; + bool redchro; + bool bluechro; + bool gamma; + bool lcurve; + bool cccurve; + +// bool perform; + bool dmethod; + bool Lmethod; + bool Cmethod; + bool C2method; + bool smethod; + bool medmethod; + bool methodmed; + bool rgbmethod; + bool passes; + +}; + +class EPDParamsEdited{ +public: + bool enabled; + bool strength; + bool gamma; + bool edgeStopping; + bool scale; + bool reweightingIterates; +}; + + +class SHParamsEdited { + + public: + bool enabled; + bool hq; + bool highlights; + bool htonalwidth; + bool shadows; + bool stonalwidth; + bool localcontrast; + bool radius; +}; + +class CropParamsEdited { + + public: + bool enabled; + bool x; + bool y; + bool w; + bool h; + bool fixratio; + bool ratio; + bool orientation; + bool guide; +}; + +class CoarseTransformParamsEdited { + + public: + bool rotate; + bool hflip; + bool vflip; +}; + +class CommonTransformParamsEdited { + + public: + bool autofill; +}; + +class RotateParamsEdited { + + public: + bool degree; +}; + +class DistortionParamsEdited { + + public: + bool amount; +}; + +class LensProfParamsEdited { + public: + bool lcpFile,useDist,useVign,useCA; + + bool isUnchanged() const; +}; + +class PerspectiveParamsEdited { + + public: + bool horizontal; + bool vertical; +}; + +class GradientParamsEdited { + + public: + bool enabled; + bool degree; + bool feather; + bool strength; + bool centerX; + bool centerY; +}; + +class PCVignetteParamsEdited { + + public: + bool enabled; + bool strength; + bool feather; + bool roundness; +}; + +class VignettingParamsEdited { + + public: + bool amount; + bool radius; + bool strength; + bool centerX; + bool centerY; +}; + +class ChannelMixerParamsEdited { + + public: + bool red[3]; + bool green[3]; + bool blue[3]; + +}; +class BlackWhiteParamsEdited { + + public: + bool enabledcc; + bool enabled; + bool method; + bool filter; + bool setting; + bool mixerRed; + bool mixerOrange; + bool mixerYellow; + bool mixerGreen; + bool mixerCyan; + bool mixerBlue; + bool mixerMagenta; + bool mixerPurple; + bool gammaRed; + bool gammaGreen; + bool gammaBlue; + bool luminanceCurve; + bool beforeCurve; + bool beforeCurveMode; + bool afterCurve; + bool afterCurveMode; + bool autoc; + bool algo; + +}; + +class CACorrParamsEdited { + + public: + bool red; + bool blue; +}; +/* +class HRecParamsEdited { + + public: + bool enabled; + bool method; +}; +*/ +class ResizeParamsEdited { + + public: + bool scale; + bool appliesTo; + bool method; + bool dataspec; + bool width; + bool height; + bool enabled; +}; + +class ColorManagementParamsEdited { + + public: + bool input; + bool toneCurve; + bool applyLookTable; + bool applyBaselineExposureOffset; + bool applyHueSatMap; + bool blendCMSMatrix; + bool dcpIlluminant; + bool working; + bool output; + bool gamma; + bool gampos; + bool slpos; + bool gamfree; + bool freegamma; +}; +class WaveletParamsEdited { + + public: + bool enabled; + bool strength; + bool balance; + bool iter; + bool median; + bool medianlev; + bool linkedg; + bool cbenab; + bool lipst; + bool Medgreinf; + bool avoid; + bool tmr; + bool c[9]; + bool ch[9]; + bool Lmethod; + bool CHmethod; + bool CHSLmethod; + bool EDmethod; + bool BAmethod; + bool TMmethod; + bool HSmethod; + bool CLmethod; + bool Backmethod; + bool Tilesmethod; + bool daubcoeffmethod; + bool Dirmethod; + bool rescon; + bool resconH; + bool reschro; + bool tmrs; + bool gamma; + bool sup; + bool sky; + bool thres; + bool threshold; + bool threshold2; + bool edgedetect; + bool edgedetectthr; + bool edgedetectthr2; + bool chro; + bool chroma; + bool contrast; + bool edgrad; + bool edgval; + bool edgthresh; + bool thr; + bool thrH; + bool skinprotect; + bool hueskin; + bool hueskin2; + bool hllev; + bool bllev; + bool edgcont; + bool level0noise; + bool level1noise; + bool level2noise; + bool ccwcurve; + bool opacityCurveBY; + bool opacityCurveRG; + bool opacityCurveW; + bool opacityCurveWL; + bool hhcurve; + bool Chcurve; + bool pastlev; + bool satlev; + bool wavclCurve; + bool greenlow; + bool bluelow; + bool greenmed; + bool bluemed; + bool greenhigh; + bool bluehigh; + +}; + +class DirPyrEqualizerParamsEdited { + + public: + bool enabled; + bool gamutlab; + bool mult[6]; + + bool threshold; + bool skinprotect; + bool hueskin; + // bool algo; +}; + +class HSVEqualizerParamsEdited { + + public: + bool hcurve; + bool scurve; + bool vcurve; +}; + +class FilmSimulationParamsEdited { +public: + bool enabled; + bool clutFilename; + bool strength; +}; + +class RAWParamsEdited { + + public: + class BayerSensor { + + public: + bool method; + bool ccSteps; + bool exBlack0; + bool exBlack1; + bool exBlack2; + bool exBlack3; + bool exTwoGreen; + bool dcbIterations; + bool dcbEnhance; + bool lmmseIterations; + //bool allEnhance; + bool greenEq; + bool linenoise; + + bool isUnchanged() const; + }; + + class XTransSensor { + + public: + bool method; + bool ccSteps; + bool exBlackRed; + bool exBlackGreen; + bool exBlackBlue; + + bool isUnchanged() const; + }; + + BayerSensor bayersensor; + XTransSensor xtranssensor; + + bool caCorrection; + bool caRed; + bool caBlue; + bool hotPixelFilter; + bool deadPixelFilter; + bool hotDeadPixelThresh; + bool darkFrame; + bool dfAuto; + bool ff_file; + bool ff_AutoSelect; + bool ff_BlurRadius; + bool ff_BlurType; + bool ff_AutoClipControl; + bool ff_clipControl; + bool exPos; + bool exPreser; + + bool isUnchanged() const; +}; + +class ParamsEdited { + + public: + GeneralParamsEdited general; + ToneCurveParamsEdited toneCurve; + LCurveParamsEdited labCurve; + RGBCurvesParamsEdited rgbCurves; + ColorToningEdited colorToning; + SharpeningParamsEdited sharpening; + SharpeningParamsEdited prsharpening; + SharpenEdgeParamsEdited sharpenEdge; + SharpenMicroParamsEdited sharpenMicro; + VibranceParamsEdited vibrance; + ColorAppearanceParamsEdited colorappearance; + //ColorBoostParamsEdited colorBoost; + WBParamsEdited wb; + //ColorShiftParamsEdited colorShift; + //LumaDenoiseParamsEdited lumaDenoise; + //ColorDenoiseParamsEdited colorDenoise; + DefringeParamsEdited defringe; + DirPyrDenoiseParamsEdited dirpyrDenoise; + EPDParamsEdited epd; + ImpulseDenoiseParamsEdited impulseDenoise; + SHParamsEdited sh; + CropParamsEdited crop; + CoarseTransformParamsEdited coarse; + CommonTransformParamsEdited commonTrans; + RotateParamsEdited rotate; + DistortionParamsEdited distortion; + LensProfParamsEdited lensProf; + PerspectiveParamsEdited perspective; + GradientParamsEdited gradient; + PCVignetteParamsEdited pcvignette; + CACorrParamsEdited cacorrection; + VignettingParamsEdited vignetting; + ChannelMixerParamsEdited chmixer; + BlackWhiteParamsEdited blackwhite; + ResizeParamsEdited resize; + ColorManagementParamsEdited icm; + RAWParamsEdited raw; + DirPyrEqualizerParamsEdited dirpyrequalizer; + WaveletParamsEdited wavelet; + HSVEqualizerParamsEdited hsvequalizer; + FilmSimulationParamsEdited filmSimulation; + bool exif; + bool iptc; + + ParamsEdited (bool value=false); + + void set (bool v); + void initFrom (const std::vector& src); + void combine (rtengine::procparams::ProcParams& toEdit, const rtengine::procparams::ProcParams& mods, bool forceSet); + + bool operator== (const ParamsEdited& other); + bool operator!= (const ParamsEdited& other); +}; +#endif diff --git a/rtgui/partialpastedlg.cc b/rtgui/partialpastedlg.cc new file mode 100644 index 000000000..16b5e3bb7 --- /dev/null +++ b/rtgui/partialpastedlg.cc @@ -0,0 +1,747 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "partialpastedlg.h" +#include "multilangmgr.h" +#include "paramsedited.h" + +PartialPasteDlg::PartialPasteDlg (Glib::ustring title) { + + set_modal (true); + set_title (title); + set_default_size(700, 600); + + everything = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_EVERYTHING"))); + everything ->set_name("partialPasteHeader"); + + basic = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_BASICGROUP"))); + basic ->set_name("partialPasteHeader"); + detail = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_DETAILGROUP"))); + detail ->set_name("partialPasteHeader"); + color = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_COLORGROUP"))); + color ->set_name("partialPasteHeader"); + lens = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_LENSGROUP"))); + lens ->set_name("partialPasteHeader"); + composition = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_COMPOSITIONGROUP"))); + composition ->set_name("partialPasteHeader"); + meta = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_METAGROUP"))); + meta ->set_name("partialPasteHeader"); + raw = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAWGROUP"))); + raw ->set_name("partialPasteHeader"); + wav = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_WAVELETGROUP"))); + wav ->set_name("partialPasteHeader"); + + // options in basic: + wb = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_WHITEBALANCE"))); + 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"))); + pcvignette = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_PCVIGNETTE"))); + gradient = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_GRADIENT"))); + labcurve = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_LABCURVE"))); + colorappearance= Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_COLORAPP"))); + + // options in detail: + sharpen = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_SHARPENING"))); + sharpenedge = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_SHARPENEDGE"))); + sharpenmicro = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_SHARPENMICRO"))); + impden = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_IMPULSEDENOISE"))); + dirpyreq = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_DIRPYREQUALIZER"))); + defringe = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_DEFRINGE"))); + + // options in wavelet: + wavelet = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_EQUALIZER"))); //TODO - rename to wavelet + + // options in color: + icm = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_ICMSETTINGS"))); + //gam = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_ICMGAMMA"))); + vibrance = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_VIBRANCE"))); + chmixer = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_CHANNELMIXER"))); + blackwhite = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_CHANNELMIXERBW"))); + dirpyrden = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_DIRPYRDENOISE"))); + hsveq = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_HSVEQUALIZER"))); + filmSimulation = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_FILMSIMULATION")) ); + rgbcurves = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RGBCURVES"))); + colortoning = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_COLORTONING"))); + + // options in lens: + distortion = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_DISTORTION"))); + cacorr = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_CACORRECTION"))); + vignetting = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_VIGNETTING"))); + lcp = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_LENSPROFILE"))); + + // options in composition: + coarserot = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_COARSETRANS"))); + finerot = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_ROTATION"))); + crop = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_CROP"))); + resize = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RESIZE"))); + perspective = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_PERSPECTIVE"))); + commonTrans = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_COMMONTRANSFORMPARAMS"))); + + // options in meta: + exifch = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_EXIFCHANGES"))); + iptc = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_IPTCINFO"))); + + // options in raw: + raw_expos = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAWEXPOS_LINEAR"))); + raw_preser = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAWEXPOS_PRESER"))); + raw_black = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAWEXPOS_BLACK"))); + raw_ca_autocorrect = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAWCACORR_AUTO"))); + raw_cared = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAWCACORR_CARED"))); + raw_cablue = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAWCACORR_CABLUE"))); + raw_hotpix_filt = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_PREPROCESS_HOTPIXFILT"))); + raw_deadpix_filt = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_PREPROCESS_DEADPIXFILT"))); + raw_linenoise = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_PREPROCESS_LINEDENOISE"))); + raw_greenthresh = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_PREPROCESS_GREENEQUIL"))); + raw_method = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAW_DMETHOD"))); + raw_ccSteps = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAW_FALSECOLOR"))); + raw_dcb_iterations = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAW_DCBITERATIONS"))); + raw_dcb_enhance = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAW_DCBENHANCE"))); + //raw_all_enhance = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAW_ALLENHANCE"))); + raw_lmmse_iterations= Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAW_LMMSEITERATIONS"))); + + df_file = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_DARKFRAMEFILE"))); + df_AutoSelect = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_DARKFRAMEAUTOSELECT"))); + ff_file = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_FLATFIELDFILE"))); + ff_AutoSelect = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_FLATFIELDAUTOSELECT"))); + ff_BlurRadius = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_FLATFIELDBLURRADIUS"))); + ff_BlurType = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_FLATFIELDBLURTYPE"))); + ff_ClipControl = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_FLATFIELDCLIPCONTROL"))); + + Gtk::VBox* vboxes[8]; + Gtk::HSeparator* hseps[8]; + for (int i=0; i<8; i++) { + vboxes[i] = Gtk::manage (new Gtk::VBox ()); + vboxes[i]->set_border_width (6); + hseps[i] = Gtk::manage (new Gtk::HSeparator ()); + hseps[i]->set_name("partialPasteHeaderSep"); + } + //BASIC + vboxes[0]->pack_start (*basic, Gtk::PACK_SHRINK, 2); + vboxes[0]->pack_start (*hseps[0], Gtk::PACK_SHRINK, 2); + vboxes[0]->pack_start (*wb, Gtk::PACK_SHRINK, 2); + 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 (*pcvignette, Gtk::PACK_SHRINK, 2); + vboxes[0]->pack_start (*gradient, Gtk::PACK_SHRINK, 2); + vboxes[0]->pack_start (*labcurve, Gtk::PACK_SHRINK, 2); + vboxes[0]->pack_start (*colorappearance, Gtk::PACK_SHRINK, 2); + + //DETAIL + vboxes[1]->pack_start (*detail, Gtk::PACK_SHRINK, 2); + vboxes[1]->pack_start (*hseps[1], Gtk::PACK_SHRINK, 2); + vboxes[1]->pack_start (*sharpen, Gtk::PACK_SHRINK, 2); + vboxes[1]->pack_start (*sharpenedge, Gtk::PACK_SHRINK, 2); + vboxes[1]->pack_start (*sharpenmicro, Gtk::PACK_SHRINK, 2); + vboxes[1]->pack_start (*impden, Gtk::PACK_SHRINK, 2); + vboxes[1]->pack_start (*dirpyrden, Gtk::PACK_SHRINK, 2); + vboxes[1]->pack_start (*defringe, Gtk::PACK_SHRINK, 2); + vboxes[1]->pack_start (*dirpyreq, Gtk::PACK_SHRINK, 2); + + //COLOR + vboxes[2]->pack_start (*color, Gtk::PACK_SHRINK, 2); + vboxes[2]->pack_start (*hseps[2], Gtk::PACK_SHRINK, 2); + vboxes[2]->pack_start (*icm, Gtk::PACK_SHRINK, 2); + //vboxes[2]->pack_start (*gam, Gtk::PACK_SHRINK, 2); + vboxes[2]->pack_start (*vibrance, Gtk::PACK_SHRINK, 2); + vboxes[2]->pack_start (*chmixer, Gtk::PACK_SHRINK, 2); + vboxes[2]->pack_start (*blackwhite, Gtk::PACK_SHRINK, 2); + vboxes[2]->pack_start (*hsveq, Gtk::PACK_SHRINK, 2); + vboxes[2]->pack_start (*filmSimulation, Gtk::PACK_SHRINK, 2); + vboxes[2]->pack_start (*rgbcurves, Gtk::PACK_SHRINK, 2); + vboxes[2]->pack_start (*colortoning, Gtk::PACK_SHRINK, 2); + + //LENS + vboxes[3]->pack_start (*lens, Gtk::PACK_SHRINK, 2); + vboxes[3]->pack_start (*hseps[3], Gtk::PACK_SHRINK, 2); + vboxes[3]->pack_start (*distortion, Gtk::PACK_SHRINK, 2); + vboxes[3]->pack_start (*cacorr, Gtk::PACK_SHRINK, 2); + vboxes[3]->pack_start (*vignetting, Gtk::PACK_SHRINK, 2); + vboxes[3]->pack_start (*lcp, Gtk::PACK_SHRINK, 2); + + //COMPOSITION + vboxes[4]->pack_start (*composition, Gtk::PACK_SHRINK, 2); + vboxes[4]->pack_start (*hseps[4], Gtk::PACK_SHRINK, 2); + vboxes[4]->pack_start (*coarserot, Gtk::PACK_SHRINK, 2); + vboxes[4]->pack_start (*finerot, Gtk::PACK_SHRINK, 2); + vboxes[4]->pack_start (*crop, Gtk::PACK_SHRINK, 2); + vboxes[4]->pack_start (*resize, Gtk::PACK_SHRINK, 2); + vboxes[4]->pack_start (*perspective, Gtk::PACK_SHRINK, 2); + vboxes[4]->pack_start (*commonTrans, Gtk::PACK_SHRINK, 2); + + //WAVELET + vboxes[5]->pack_start (*wav, Gtk::PACK_SHRINK, 2); + vboxes[5]->pack_start (*hseps[5], Gtk::PACK_SHRINK, 2); + vboxes[5]->pack_start (*wavelet, Gtk::PACK_SHRINK, 2); + + //RAW + vboxes[6]->pack_start (*raw, Gtk::PACK_SHRINK, 2); + vboxes[6]->pack_start (*hseps[6], Gtk::PACK_SHRINK, 2); + vboxes[6]->pack_start (*raw_method, Gtk::PACK_SHRINK, 2); + vboxes[6]->pack_start (*raw_ccSteps, Gtk::PACK_SHRINK, 2); + vboxes[6]->pack_start (*raw_dcb_iterations, Gtk::PACK_SHRINK, 2); + vboxes[6]->pack_start (*raw_dcb_enhance, Gtk::PACK_SHRINK, 2); + vboxes[6]->pack_start (*raw_lmmse_iterations, Gtk::PACK_SHRINK, 2); + //vboxes[6]->pack_start (*raw_all_enhance, Gtk::PACK_SHRINK, 2); + vboxes[6]->pack_start (*Gtk::manage (new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 0); + vboxes[6]->pack_start (*raw_linenoise, Gtk::PACK_SHRINK, 2); + vboxes[6]->pack_start (*raw_greenthresh, Gtk::PACK_SHRINK, 2); + vboxes[6]->pack_start (*raw_hotpix_filt, Gtk::PACK_SHRINK, 2); + vboxes[6]->pack_start (*raw_deadpix_filt, Gtk::PACK_SHRINK, 2); + vboxes[6]->pack_start (*Gtk::manage (new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 0); + vboxes[6]->pack_start (*raw_expos, Gtk::PACK_SHRINK, 2); + vboxes[6]->pack_start (*raw_preser, Gtk::PACK_SHRINK, 2); + vboxes[6]->pack_start (*raw_black, Gtk::PACK_SHRINK, 2); + vboxes[6]->pack_start (*Gtk::manage (new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 0); + vboxes[6]->pack_start (*df_file, Gtk::PACK_SHRINK, 2); + vboxes[6]->pack_start (*df_AutoSelect, Gtk::PACK_SHRINK, 2); + vboxes[6]->pack_start (*Gtk::manage (new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 0); + vboxes[6]->pack_start (*ff_file, Gtk::PACK_SHRINK, 2); + vboxes[6]->pack_start (*ff_AutoSelect, Gtk::PACK_SHRINK, 2); + vboxes[6]->pack_start (*ff_BlurType, Gtk::PACK_SHRINK, 2); + vboxes[6]->pack_start (*ff_BlurRadius, Gtk::PACK_SHRINK, 2); + vboxes[6]->pack_start (*ff_ClipControl, Gtk::PACK_SHRINK, 2); + vboxes[6]->pack_start (*Gtk::manage (new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 0); + vboxes[6]->pack_start (*raw_ca_autocorrect, Gtk::PACK_SHRINK, 2); + vboxes[6]->pack_start (*raw_cared, Gtk::PACK_SHRINK, 2); + vboxes[6]->pack_start (*raw_cablue, Gtk::PACK_SHRINK, 2); + + //META + vboxes[7]->pack_start (*meta, Gtk::PACK_SHRINK, 2); + vboxes[7]->pack_start (*hseps[7], Gtk::PACK_SHRINK, 2); + vboxes[7]->pack_start (*exifch, Gtk::PACK_SHRINK, 2); + vboxes[7]->pack_start (*iptc, Gtk::PACK_SHRINK, 2); + + Gtk::VBox* vbCol1 = Gtk::manage (new Gtk::VBox ()); + Gtk::VBox* vbCol2 = Gtk::manage (new Gtk::VBox ()); + Gtk::VBox* vbCol3 = Gtk::manage (new Gtk::VBox ()); + + vbCol1->set_border_width (8); + vbCol2->set_border_width (8); + vbCol3->set_border_width (8); + + for (int i=0; i<3; i++) + vbCol1->pack_start (*vboxes[i], Gtk::PACK_SHRINK, 2); + for (int i=3; i<6; i++) + vbCol2->pack_start (*vboxes[i], Gtk::PACK_SHRINK, 2); + for (int i=6; i<8; i++) + vbCol3->pack_start (*vboxes[i], Gtk::PACK_SHRINK, 2); + + Gtk::VBox* vbtop = Gtk::manage (new Gtk::VBox ()); + vbtop->pack_start (*everything, Gtk::PACK_SHRINK, 2); + vbtop->set_border_width (8); + + Gtk::Dialog::get_vbox()->pack_start (*vbtop, Gtk::PACK_SHRINK, 2); // TODO replace with get_content_area() with GTK upgrade + + Gtk::HBox* hbmain = Gtk::manage (new Gtk::HBox ()); + hbmain->pack_start (*vbCol1); + hbmain->pack_start (*(Gtk::manage (new Gtk::VSeparator ()))); + hbmain->pack_start (*vbCol2); + hbmain->pack_start (*(Gtk::manage (new Gtk::VSeparator ()))); + hbmain->pack_start (*vbCol3); + + scrolledwindow = Gtk::manage ( new Gtk::ScrolledWindow() ); + scrolledwindow->set_flags(Gtk::CAN_FOCUS); + scrolledwindow->set_border_width(2); + scrolledwindow->set_shadow_type(Gtk::SHADOW_NONE); + scrolledwindow->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + scrolledwindow->property_window_placement().set_value(Gtk::CORNER_TOP_LEFT); + + scrolledwindow->add(*hbmain); + + Gtk::Dialog::get_vbox()->pack_start (*scrolledwindow, Gtk::PACK_EXPAND_WIDGET, 2);// TODO replace with get_content_area() with GTK upgrade + + hbmain->show(); + scrolledwindow->show (); + + // This can be improved + // there is currently no binding of subsettings to CheckButton 'everything' for its inconsistent status + everythingConn = everything->signal_toggled().connect (sigc::mem_fun(*this, &PartialPasteDlg::everythingToggled)); + basicConn = basic->signal_toggled().connect (sigc::mem_fun(*this, &PartialPasteDlg::basicToggled)); + detailConn = detail->signal_toggled().connect (sigc::mem_fun(*this, &PartialPasteDlg::detailToggled)); + colorConn = color->signal_toggled().connect (sigc::mem_fun(*this, &PartialPasteDlg::colorToggled)); + lensConn = lens->signal_toggled().connect (sigc::mem_fun(*this, &PartialPasteDlg::lensToggled)); + compositionConn = composition->signal_toggled().connect (sigc::mem_fun(*this, &PartialPasteDlg::compositionToggled)); + metaConn = meta->signal_toggled().connect (sigc::mem_fun(*this, &PartialPasteDlg::metaToggled)); + rawConn = raw->signal_toggled().connect (sigc::mem_fun(*this, &PartialPasteDlg::rawToggled)); + wavConn = wav->signal_toggled().connect (sigc::mem_fun(*this, &PartialPasteDlg::wavToggled)); + + wbConn = wb->signal_toggled().connect (sigc::bind (sigc::mem_fun(*basic, &Gtk::CheckButton::set_inconsistent), true)); + 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)); + 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)); + labcurveConn = labcurve->signal_toggled().connect (sigc::bind (sigc::mem_fun(*basic, &Gtk::CheckButton::set_inconsistent), true)); + colorappearanceConn=colorappearance->signal_toggled().connect (sigc::bind (sigc::mem_fun(*basic, &Gtk::CheckButton::set_inconsistent), true)); + + sharpenConn = sharpen->signal_toggled().connect (sigc::bind (sigc::mem_fun(*detail, &Gtk::CheckButton::set_inconsistent), true)); + gradsharpenConn = sharpenedge->signal_toggled().connect (sigc::bind (sigc::mem_fun(*detail, &Gtk::CheckButton::set_inconsistent), true)); + microcontrastConn = sharpenmicro->signal_toggled().connect (sigc::bind (sigc::mem_fun(*detail, &Gtk::CheckButton::set_inconsistent), true)); + impdenConn = impden->signal_toggled().connect (sigc::bind (sigc::mem_fun(*detail, &Gtk::CheckButton::set_inconsistent), true)); + dirpyrdenConn = dirpyrden->signal_toggled().connect (sigc::bind (sigc::mem_fun(*detail, &Gtk::CheckButton::set_inconsistent), true)); + dirpyreqConn = dirpyreq->signal_toggled().connect (sigc::bind (sigc::mem_fun(*detail, &Gtk::CheckButton::set_inconsistent), true)); + defringeConn = defringe->signal_toggled().connect (sigc::bind (sigc::mem_fun(*detail, &Gtk::CheckButton::set_inconsistent), true)); + + waveletConn = wavelet->signal_toggled().connect (sigc::bind (sigc::mem_fun(*wav, &Gtk::CheckButton::set_inconsistent), true)); + + icmConn = icm->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true)); + //gamcsconn = gam->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true)); + vibranceConn = vibrance->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true)); + chmixerConn = chmixer->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true)); + chmixerbwConn = blackwhite->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true)); + hsveqConn = hsveq->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true)); + filmSimulationConn = filmSimulation->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true)); + rgbcurvesConn = rgbcurves->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true)); + colortoningConn = colortoning->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true)); + + distortionConn = distortion->signal_toggled().connect (sigc::bind (sigc::mem_fun(*lens, &Gtk::CheckButton::set_inconsistent), true)); + cacorrConn = cacorr->signal_toggled().connect (sigc::bind (sigc::mem_fun(*lens, &Gtk::CheckButton::set_inconsistent), true)); + vignettingConn = vignetting->signal_toggled().connect (sigc::bind (sigc::mem_fun(*lens, &Gtk::CheckButton::set_inconsistent), true)); + lcpConn = lcp->signal_toggled().connect (sigc::bind (sigc::mem_fun(*lens, &Gtk::CheckButton::set_inconsistent), true)); + + coarserotConn = coarserot->signal_toggled().connect (sigc::bind (sigc::mem_fun(*composition, &Gtk::CheckButton::set_inconsistent), true)); + finerotConn = finerot->signal_toggled().connect (sigc::bind (sigc::mem_fun(*composition, &Gtk::CheckButton::set_inconsistent), true)); + cropConn = crop->signal_toggled().connect (sigc::bind (sigc::mem_fun(*composition, &Gtk::CheckButton::set_inconsistent), true)); + resizeConn = resize->signal_toggled().connect (sigc::bind (sigc::mem_fun(*composition, &Gtk::CheckButton::set_inconsistent), true)); + perspectiveConn = perspective->signal_toggled().connect (sigc::bind (sigc::mem_fun(*composition, &Gtk::CheckButton::set_inconsistent), true)); + commonTransConn = commonTrans->signal_toggled().connect (sigc::bind (sigc::mem_fun(*composition, &Gtk::CheckButton::set_inconsistent), true)); + + exifchConn = exifch->signal_toggled().connect (sigc::bind (sigc::mem_fun(*meta, &Gtk::CheckButton::set_inconsistent), true)); + iptcConn = iptc->signal_toggled().connect (sigc::bind (sigc::mem_fun(*meta, &Gtk::CheckButton::set_inconsistent), true)); + + raw_methodConn = raw_method->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); + raw_ccStepsConn = raw_ccSteps->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); + raw_dcb_iterationsConn = raw_dcb_iterations->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); + raw_dcb_enhanceConn = raw_dcb_enhance->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); + //raw_all_enhanceConn = raw_all_enhance->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); + raw_lmmse_iterationsConn = raw_lmmse_iterations->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); + + raw_exposConn = raw_expos->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); + raw_preserConn = raw_preser->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); + raw_blackConn = raw_black->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); + raw_ca_autocorrectConn = raw_ca_autocorrect->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); + raw_caredConn = raw_cared->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); + raw_cablueConn = raw_cablue->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); + raw_hotpix_filtConn = raw_hotpix_filt->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); + raw_deadpix_filtConn = raw_deadpix_filt->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); + raw_linenoiseConn = raw_linenoise->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); + raw_greenthreshConn = raw_greenthresh->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); + df_fileConn = df_file->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); + df_AutoSelectConn = df_AutoSelect->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); + ff_fileConn = ff_file->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); + ff_AutoSelectConn = ff_AutoSelect->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); + ff_BlurRadiusConn = ff_BlurRadius->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); + ff_BlurTypeConn = ff_BlurType->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); + ff_ClipControlConn = ff_ClipControl->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); + + add_button (Gtk::StockID("gtk-ok"), Gtk::RESPONSE_OK); + add_button (Gtk::StockID("gtk-cancel"), Gtk::RESPONSE_CANCEL); + set_response_sensitive (Gtk::RESPONSE_OK); + set_default_response (Gtk::RESPONSE_OK); + show_all_children (); +} + +void PartialPasteDlg::everythingToggled () { + + basicConn.block (true); + detailConn.block (true); + colorConn.block (true); + lensConn.block (true); + compositionConn.block (true); + metaConn.block (true); + rawConn.block (true); + wavConn.block (true); + + everything->set_inconsistent (false); + + //toggle group headings + basic->set_active(everything->get_active()); + detail->set_active(everything->get_active()); + color->set_active(everything->get_active()); + lens->set_active(everything->get_active()); + composition->set_active(everything->get_active()); + meta->set_active(everything->get_active()); + raw->set_active(everything->get_active()); + wav->set_active(everything->get_active()); + + //toggle group children + PartialPasteDlg::basicToggled (); + PartialPasteDlg::detailToggled (); + PartialPasteDlg::colorToggled (); + PartialPasteDlg::lensToggled (); + PartialPasteDlg::compositionToggled (); + PartialPasteDlg::metaToggled (); + PartialPasteDlg::rawToggled (); + PartialPasteDlg::wavToggled (); + + basicConn.block (false); + detailConn.block (false); + colorConn.block (false); + lensConn.block (false); + compositionConn.block (false); + metaConn.block (false); + rawConn.block (false); + wavConn.block (false); +} + +void PartialPasteDlg::rawToggled () { + + raw_methodConn.block (true); + raw_ccStepsConn.block (true); + raw_dcb_iterationsConn.block (true); + raw_dcb_enhanceConn.block (true); + //raw_all_enhanceConn.block (true); + raw_lmmse_iterationsConn.block (true); + raw_exposConn.block (true); + raw_preserConn.block (true); + raw_blackConn.block (true); + raw_ca_autocorrectConn.block (true); + raw_caredConn.block (true); + raw_cablueConn.block (true); + raw_hotpix_filtConn.block (true); + raw_deadpix_filtConn.block (true); + raw_linenoiseConn.block (true); + raw_greenthreshConn.block (true); + df_fileConn.block (true); + df_AutoSelectConn.block (true); + ff_fileConn.block (true); + ff_AutoSelectConn.block (true); + ff_BlurRadiusConn.block (true); + ff_BlurTypeConn.block (true); + ff_ClipControlConn.block (true); + + raw->set_inconsistent (false); + + raw_method->set_active (raw->get_active ()); + raw_ccSteps->set_active (raw->get_active ()); + raw_dcb_iterations->set_active (raw->get_active ()); + raw_dcb_enhance->set_active (raw->get_active ()); + raw_lmmse_iterations->set_active (raw->get_active ()); + //raw_all_enhance->set_active (raw->get_active ()); + raw_expos->set_active (raw->get_active ()); + raw_preser->set_active (raw->get_active ()); + raw_black->set_active (raw->get_active ()); + raw_ca_autocorrect->set_active (raw->get_active ()); + raw_cared->set_active (raw->get_active ()); + raw_cablue->set_active (raw->get_active ()); + raw_hotpix_filt->set_active (raw->get_active ()); + raw_deadpix_filt->set_active (raw->get_active ()); + raw_linenoise->set_active (raw->get_active ()); + raw_greenthresh->set_active (raw->get_active ()); + df_file->set_active (raw->get_active ()); + df_AutoSelect->set_active (raw->get_active ()); + ff_file->set_active (raw->get_active ()); + ff_AutoSelect->set_active (raw->get_active ()); + ff_BlurRadius->set_active (raw->get_active ()); + ff_BlurType->set_active (raw->get_active ()); + ff_ClipControl->set_active (raw->get_active ()); + + raw_methodConn.block (false); + raw_ccStepsConn.block (false); + raw_dcb_iterationsConn.block (false); + raw_dcb_enhanceConn.block (false); + //raw_all_enhanceConn.block (false); + raw_lmmse_iterationsConn.block (false); + raw_exposConn.block (false); + raw_preserConn.block (false); + raw_blackConn.block (false); + raw_ca_autocorrectConn.block (false); + raw_caredConn.block (false); + raw_cablueConn.block (false); + raw_hotpix_filtConn.block (false); + raw_deadpix_filtConn.block (false); + raw_linenoiseConn.block (false); + raw_greenthreshConn.block (false); + df_fileConn.block (false); + df_AutoSelectConn.block (false); + ff_fileConn.block (false); + ff_AutoSelectConn.block (false); + ff_BlurRadiusConn.block (false); + ff_BlurTypeConn.block (false); + ff_ClipControlConn.block (false); +} + +void PartialPasteDlg::basicToggled () { + + wbConn.block (true); + exposureConn.block (true); + shConn.block (true); + epdConn.block(true); + pcvignetteConn.block (true); + gradientConn.block (true); + labcurveConn.block (true); + colorappearanceConn.block (true); + + basic->set_inconsistent (false); + + wb->set_active (basic->get_active ()); + exposure->set_active (basic->get_active ()); + sh->set_active (basic->get_active ()); + epd->set_active (basic->get_active ()); + pcvignette->set_active (basic->get_active ()); + gradient->set_active (basic->get_active ()); + labcurve->set_active (basic->get_active ()); + colorappearance->set_active (basic->get_active ()); + + wbConn.block (false); + exposureConn.block (false); + shConn.block (false); + epdConn.block (false); + pcvignetteConn.block (false); + gradientConn.block (false); + labcurveConn.block (false); + colorappearanceConn.block (false); +} + +void PartialPasteDlg::detailToggled () { + + sharpenConn.block (true); + gradsharpenConn.block(true); + microcontrastConn.block(true); + impdenConn.block (true); + dirpyrdenConn.block (true); + defringeConn.block (true); + dirpyreqConn.block (true); + + detail->set_inconsistent (false); + + sharpen->set_active (detail->get_active ()); + sharpenedge->set_active (detail->get_active ()); + sharpenmicro->set_active (detail->get_active ()); + impden->set_active (detail->get_active ()); + dirpyrden->set_active (detail->get_active ()); + defringe->set_active (detail->get_active ()); + dirpyreq->set_active (detail->get_active ()); + + sharpenConn.block (false); + gradsharpenConn.block(false); + microcontrastConn.block(false); + impdenConn.block (false); + dirpyrdenConn.block (false); + defringeConn.block (false); + dirpyreqConn.block (false); +} + +void PartialPasteDlg::wavToggled () { + + waveletConn.block (true); + + wav->set_inconsistent (false); + wavelet->set_active (wav->get_active ()); + + waveletConn.block (false); +} + +void PartialPasteDlg::colorToggled () { + + icmConn.block (true); + //gamcsconn.block (true); + vibranceConn.block (true); + chmixerConn.block (true); + chmixerbwConn.block (true); + hsveqConn.block (true); + filmSimulationConn.block (true); + rgbcurvesConn.block (true); + colortoningConn.block (true); + + color->set_inconsistent (false); + icm->set_active (color->get_active ()); + //gam->set_active (color->get_active ()); + vibrance->set_active (color->get_active ()); + chmixer->set_active (color->get_active ()); + blackwhite->set_active (color->get_active ()); + hsveq->set_active (color->get_active ()); + filmSimulation->set_active (color->get_active ()); + rgbcurves->set_active (color->get_active ()); + colortoning->set_active(color->get_active ()); + + icmConn.block (false); + //gamcsconn.block (false); + vibranceConn.block (false); + chmixerbwConn.block (false); + chmixerConn.block (false); + hsveqConn.block (false); + filmSimulationConn.block (false); + rgbcurvesConn.block (false); + colortoningConn.block (false); +} + +void PartialPasteDlg::lensToggled () { + + distortionConn.block (true); + cacorrConn.block (true); + vignettingConn.block (true); + lcpConn.block (true); + + lens->set_inconsistent (false); + + distortion->set_active (lens->get_active ()); + cacorr->set_active (lens->get_active ()); + vignetting->set_active (lens->get_active ()); + lcp->set_active (lens->get_active ()); + + distortionConn.block (false); + cacorrConn.block (false); + vignettingConn.block (false); + lcpConn.block (false); +} + +void PartialPasteDlg::compositionToggled () { + + coarserotConn.block (true); + finerotConn.block (true); + cropConn.block (true); + resizeConn.block (true); + perspectiveConn.block (true); + commonTransConn.block (true); + + composition->set_inconsistent (false); + + coarserot->set_active (composition->get_active ()); + finerot->set_active (composition->get_active ()); + crop->set_active (composition->get_active ()); + resize->set_active (composition->get_active ()); + perspective->set_active (composition->get_active ()); + commonTrans->set_active (composition->get_active ()); + + coarserotConn.block (false); + finerotConn.block (false); + cropConn.block (false); + resizeConn.block (false); + perspectiveConn.block (false); + commonTransConn.block (false); +} + +void PartialPasteDlg::metaToggled () { + + exifchConn.block (true); + iptcConn.block (true); + meta->set_inconsistent (false); + + exifch->set_active (meta->get_active ()); + iptc->set_active (meta->get_active ()); + + exifchConn.block (false); + iptcConn.block (false); +} + + +/* + * Copies the selected items from the source ProcParams+ParamsEdited(optional) + * to the destination ProcParams. + */ +void PartialPasteDlg::applyPaste (rtengine::procparams::ProcParams* dstPP, ParamsEdited* dstPE, const rtengine::procparams::ProcParams* srcPP, const ParamsEdited* srcPE) { + + ParamsEdited falsePE; // falsePE is a workaround to set a group of ParamsEdited to false + ParamsEdited filterPE(true); // Contains the initial information about the loaded values + if (srcPE) { + filterPE = *srcPE; + } + + // the general section is always ignored, whichever operation we use the PartialPaste for + filterPE.general = falsePE.general; + + + // Now we filter out the filter depending on the checked items + if (!wb->get_active ()) filterPE.wb = falsePE.wb; + if (!exposure->get_active ()) filterPE.toneCurve = falsePE.toneCurve; + if (!sh->get_active ()) filterPE.sh = falsePE.sh; + if (!epd->get_active ()) filterPE.epd = falsePE.epd; + if (!pcvignette->get_active ()) filterPE.pcvignette = falsePE.pcvignette; + if (!gradient->get_active ()) filterPE.gradient = falsePE.gradient; + if (!labcurve->get_active ()) filterPE.labCurve = falsePE.labCurve; + if (!colorappearance->get_active ()) filterPE.colorappearance= falsePE.colorappearance; + + if (!sharpen->get_active ()) filterPE.sharpening = falsePE.sharpening; + if (!sharpenedge->get_active ()) filterPE.sharpenEdge = falsePE.sharpenEdge; + if (!sharpenmicro->get_active()) filterPE.sharpenMicro = falsePE.sharpenMicro; + if (!impden->get_active ()) filterPE.impulseDenoise = falsePE.impulseDenoise; + if (!dirpyreq->get_active ()) filterPE.dirpyrequalizer = falsePE.dirpyrequalizer; + if (!defringe->get_active ()) filterPE.defringe = falsePE.defringe; + if (!dirpyrden->get_active ()) filterPE.dirpyrDenoise = falsePE.dirpyrDenoise; + + if (!wavelet->get_active ()) filterPE.wavelet = falsePE.wavelet; + + if (!icm->get_active ()) filterPE.icm = falsePE.icm; + if (!vibrance->get_active ()) filterPE.vibrance = falsePE.vibrance; + if (!chmixer->get_active ()) filterPE.chmixer = falsePE.chmixer; + if (!blackwhite->get_active ()) filterPE.blackwhite = falsePE.blackwhite; + if (!hsveq->get_active ()) filterPE.hsvequalizer = falsePE.hsvequalizer; + if (!filmSimulation->get_active ()) filterPE.filmSimulation = falsePE.filmSimulation; + if (!rgbcurves->get_active ()) filterPE.rgbCurves = falsePE.rgbCurves; + if (!colortoning->get_active ()) filterPE.colorToning = falsePE.colorToning; + + if (!distortion->get_active ()) filterPE.distortion = falsePE.distortion; + if (!cacorr->get_active ()) filterPE.cacorrection = falsePE.cacorrection; + if (!vignetting->get_active ()) filterPE.vignetting = falsePE.vignetting; + if (!lcp->get_active ()) filterPE.lensProf = falsePE.lensProf; + + if (!coarserot->get_active ()) filterPE.coarse = falsePE.coarse; + if (!finerot->get_active ()) filterPE.rotate = falsePE.rotate; + if (!crop->get_active ()) filterPE.crop = falsePE.crop; + if (!resize->get_active ()) filterPE.resize = falsePE.resize; + if (!perspective->get_active ()) filterPE.perspective = falsePE.perspective; + if (!commonTrans->get_active ()) filterPE.commonTrans = falsePE.commonTrans; + + if (!exifch->get_active ()) filterPE.exif = falsePE.exif; + if (!iptc->get_active ()) filterPE.iptc = falsePE.iptc; + + if (!raw_method->get_active ()) { filterPE.raw.bayersensor.method = falsePE.raw.bayersensor.method; + filterPE.raw.xtranssensor.method = falsePE.raw.xtranssensor.method; } + if (!raw_ccSteps->get_active ()) { filterPE.raw.bayersensor.ccSteps = falsePE.raw.bayersensor.ccSteps; + filterPE.raw.xtranssensor.ccSteps = falsePE.raw.xtranssensor.ccSteps; } + if (!raw_dcb_iterations->get_active ()) filterPE.raw.bayersensor.dcbIterations = falsePE.raw.bayersensor.dcbIterations; + if (!raw_dcb_enhance->get_active ()) filterPE.raw.bayersensor.dcbEnhance = falsePE.raw.bayersensor.dcbEnhance; + //if (!raw_all_enhance->get_active ()) filterPE.raw.bayersensor.allEnhance = falsePE.raw.bayersensor.allEnhance; + if (!raw_lmmse_iterations->get_active ()) filterPE.raw.bayersensor.lmmseIterations = falsePE.raw.bayersensor.lmmseIterations; + if (!raw_black->get_active ()) { filterPE.raw.bayersensor.exBlack0 = falsePE.raw.bayersensor.exBlack0; + filterPE.raw.bayersensor.exBlack1 = falsePE.raw.bayersensor.exBlack1; + filterPE.raw.bayersensor.exBlack2 = falsePE.raw.bayersensor.exBlack2; + filterPE.raw.bayersensor.exBlack3 = falsePE.raw.bayersensor.exBlack3; + filterPE.raw.bayersensor.exTwoGreen = falsePE.raw.bayersensor.exTwoGreen; + filterPE.raw.xtranssensor.exBlackRed = falsePE.raw.xtranssensor.exBlackRed; + filterPE.raw.xtranssensor.exBlackGreen = falsePE.raw.xtranssensor.exBlackGreen; + filterPE.raw.xtranssensor.exBlackBlue = falsePE.raw.xtranssensor.exBlackBlue; } + if (!raw_linenoise->get_active ()) filterPE.raw.bayersensor.linenoise = falsePE.raw.bayersensor.linenoise; + if (!raw_greenthresh->get_active ()) filterPE.raw.bayersensor.greenEq = falsePE.raw.bayersensor.greenEq; + if (!raw_expos->get_active ()) filterPE.raw.exPos = falsePE.raw.exPos; + if (!raw_preser->get_active ()) filterPE.raw.exPreser = falsePE.raw.exPreser; + if (!raw_ca_autocorrect->get_active ()) filterPE.raw.caCorrection = falsePE.raw.caCorrection; + if (!raw_cared->get_active ()) filterPE.raw.caRed = falsePE.raw.caRed; + if (!raw_cablue->get_active ()) filterPE.raw.caBlue = falsePE.raw.caBlue; + if (!raw_hotpix_filt->get_active ()) { filterPE.raw.hotPixelFilter = falsePE.raw.hotPixelFilter; } + if (!raw_deadpix_filt->get_active ()) { filterPE.raw.deadPixelFilter = falsePE.raw.deadPixelFilter; } + if (!raw_deadpix_filt->get_active () && !raw_hotpix_filt->get_active ()) + filterPE.raw.hotDeadPixelThresh = falsePE.raw.hotDeadPixelThresh; + if (!df_file->get_active ()) filterPE.raw.darkFrame = falsePE.raw.darkFrame; + if (!df_AutoSelect->get_active ()) filterPE.raw.dfAuto = falsePE.raw.dfAuto; + if (!ff_file->get_active ()) filterPE.raw.ff_file = falsePE.raw.ff_file; + if (!ff_AutoSelect->get_active ()) filterPE.raw.ff_AutoSelect = falsePE.raw.ff_AutoSelect; + if (!ff_BlurRadius->get_active ()) filterPE.raw.ff_BlurRadius = falsePE.raw.ff_BlurRadius; + if (!ff_BlurType->get_active ()) filterPE.raw.ff_BlurType = falsePE.raw.ff_BlurType; + if (!ff_ClipControl->get_active ()) { filterPE.raw.ff_clipControl = falsePE.raw.ff_clipControl; + filterPE.raw.ff_AutoClipControl = falsePE.raw.ff_AutoClipControl; } + + if (dstPE) *dstPE = filterPE; + + // Apply the filter! + filterPE.combine(*dstPP, *srcPP, true); +} + diff --git a/rtgui/partialpastedlg.h b/rtgui/partialpastedlg.h new file mode 100644 index 000000000..e337a14a2 --- /dev/null +++ b/rtgui/partialpastedlg.h @@ -0,0 +1,150 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _PARTIALPASTEDLG_ +#define _PARTIALPASTEDLG_ + +#include +#include "../rtengine/rtengine.h" + +class PartialPasteDlg : public Gtk::Dialog { + + public: + + Gtk::ScrolledWindow *scrolledwindow; + + Gtk::CheckButton* everything; + + // main groups: + Gtk::CheckButton* basic; + Gtk::CheckButton* detail; + Gtk::CheckButton* color; + Gtk::CheckButton* lens; + Gtk::CheckButton* composition; + Gtk::CheckButton* meta; + Gtk::CheckButton* raw; + Gtk::CheckButton* wav; + + // options in basic: + Gtk::CheckButton* wb; + Gtk::CheckButton* exposure; + Gtk::CheckButton* sh; + Gtk::CheckButton* epd; + Gtk::CheckButton* pcvignette; + Gtk::CheckButton* gradient; + Gtk::CheckButton* labcurve; + Gtk::CheckButton* colorappearance; + + // options in detail: + Gtk::CheckButton* sharpen; + Gtk::CheckButton* sharpenedge; + Gtk::CheckButton* sharpenmicro; + Gtk::CheckButton* impden; + //Gtk::CheckButton* waveq; + Gtk::CheckButton* dirpyrden; + Gtk::CheckButton* defringe; + Gtk::CheckButton* dirpyreq; + + // options in wavelet + Gtk::CheckButton* wavelet; + + // options in color: + Gtk::CheckButton* icm; + Gtk::CheckButton* gam; + Gtk::CheckButton* vibrance; + Gtk::CheckButton* chmixer; + Gtk::CheckButton* blackwhite; + Gtk::CheckButton* hsveq; + Gtk::CheckButton* filmSimulation; + Gtk::CheckButton* rgbcurves; + Gtk::CheckButton* colortoning; + + // options in lens: + Gtk::CheckButton* distortion; + Gtk::CheckButton* cacorr; + Gtk::CheckButton* vignetting; + Gtk::CheckButton* lcp; + + // options in composition: + Gtk::CheckButton* coarserot; + Gtk::CheckButton* finerot; + Gtk::CheckButton* crop; + Gtk::CheckButton* resize; + Gtk::CheckButton* perspective; + Gtk::CheckButton* commonTrans; + + // options in meta: + Gtk::CheckButton* exifch; + Gtk::CheckButton* iptc; + + + // options in raw: + Gtk::CheckButton* raw_expos; + Gtk::CheckButton* raw_preser; + Gtk::CheckButton* raw_black; + Gtk::CheckButton* raw_ca_autocorrect; + Gtk::CheckButton* raw_cared; + Gtk::CheckButton* raw_cablue; + Gtk::CheckButton* raw_hotpix_filt; + Gtk::CheckButton* raw_deadpix_filt; + Gtk::CheckButton* raw_linenoise; + Gtk::CheckButton* raw_greenthresh; + Gtk::CheckButton* raw_method; + Gtk::CheckButton* raw_ccSteps; + Gtk::CheckButton* raw_dcb_iterations; + Gtk::CheckButton* raw_dcb_enhance; + //Gtk::CheckButton* raw_all_enhance; + Gtk::CheckButton* raw_lmmse_iterations; + + Gtk::CheckButton* df_file; + Gtk::CheckButton* df_AutoSelect; + Gtk::CheckButton* ff_file; + Gtk::CheckButton* ff_AutoSelect; + Gtk::CheckButton* ff_BlurRadius; + Gtk::CheckButton* ff_BlurType; + Gtk::CheckButton* ff_ClipControl; + + 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; + sigc::connection vibranceConn, chmixerConn, hsveqConn, rgbcurvesConn, chmixerbwConn, colortoningConn, filmSimulationConn; + sigc::connection distortionConn, cacorrConn, vignettingConn, lcpConn; + sigc::connection coarserotConn, finerotConn, cropConn, resizeConn, perspectiveConn, commonTransConn; + sigc::connection exifchConn, iptcConn, icmConn, gamcsconn; + sigc::connection df_fileConn, df_AutoSelectConn, ff_fileConn, ff_AutoSelectConn, ff_BlurRadiusConn, ff_BlurTypeConn, ff_ClipControlConn; + sigc::connection raw_caredConn, raw_cablueConn, raw_ca_autocorrectConn, raw_hotpix_filtConn, raw_deadpix_filtConn, raw_linenoiseConn, raw_greenthreshConn, raw_ccStepsConn, raw_methodConn, raw_dcb_iterationsConn, raw_lmmse_iterationsConn, raw_dcb_enhanceConn, raw_exposConn, raw_preserConn, raw_blackConn; //,raw_all_enhanceConn + + public: + PartialPasteDlg (Glib::ustring title); + + void applyPaste (rtengine::procparams::ProcParams* dstPP, ParamsEdited* dstPE, const rtengine::procparams::ProcParams* srcPP, const ParamsEdited* srcPE=NULL); + + void everythingToggled (); + void basicToggled (); + void detailToggled (); + void colorToggled (); + void lensToggled (); + void compositionToggled (); + void metaToggled (); + void rawToggled (); + void wavToggled (); +}; + +#endif + diff --git a/rtgui/pcvignette.cc b/rtgui/pcvignette.cc new file mode 100644 index 000000000..67e6ae3c6 --- /dev/null +++ b/rtgui/pcvignette.cc @@ -0,0 +1,125 @@ +/* + * This file is part of RawTherapee. + */ +#include "pcvignette.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +PCVignette::PCVignette () : FoldableToolPanel(this, "pcvignette", M("TP_PCVIGNETTE_LABEL"), false, true) +{ + strength = Gtk::manage (new Adjuster (M("TP_PCVIGNETTE_STRENGTH"), -6, 6, 0.01, 0)); + strength->set_tooltip_text (M("TP_PCVIGNETTE_STRENGTH_TOOLTIP")); + strength->setAdjusterListener (this); + + feather = Gtk::manage (new Adjuster (M("TP_PCVIGNETTE_FEATHER"), 0, 100, 1, 50)); + feather->set_tooltip_text (M("TP_PCVIGNETTE_FEATHER_TOOLTIP")); + feather->setAdjusterListener (this); + + roundness = Gtk::manage (new Adjuster (M("TP_PCVIGNETTE_ROUNDNESS"), 0, 100, 1, 50)); + roundness->set_tooltip_text (M("TP_PCVIGNETTE_ROUNDNESS_TOOLTIP")); + roundness->setAdjusterListener (this); + + pack_start (*strength); + pack_start (*feather); + pack_start (*roundness); + + show_all(); +} + +void PCVignette::read (const ProcParams* pp, const ParamsEdited* pedited) +{ + disableListener (); + + if (pedited) { + strength->setEditedState (pedited->pcvignette.strength ? Edited : UnEdited); + feather->setEditedState (pedited->pcvignette.feather ? Edited : UnEdited); + roundness->setEditedState (pedited->pcvignette.roundness ? Edited : UnEdited); + set_inconsistent (multiImage && !pedited->pcvignette.enabled); + } + + setEnabled(pp->pcvignette.enabled); + strength->setValue (pp->pcvignette.strength); + feather->setValue (pp->pcvignette.feather); + roundness->setValue (pp->pcvignette.roundness); + + enableListener (); +} + +void PCVignette::write (ProcParams* pp, ParamsEdited* pedited) +{ + pp->pcvignette.strength = strength->getValue (); + pp->pcvignette.feather = feather->getIntValue (); + pp->pcvignette.roundness = roundness->getIntValue (); + pp->pcvignette.enabled = getEnabled(); + + if (pedited) { + pedited->pcvignette.strength = strength->getEditedState (); + pedited->pcvignette.feather = feather->getEditedState (); + pedited->pcvignette.roundness = roundness->getEditedState (); + pedited->pcvignette.enabled = !get_inconsistent(); + } +} + +void PCVignette::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) +{ + strength->setDefault (defParams->pcvignette.strength); + feather->setDefault (defParams->pcvignette.feather); + roundness->setDefault (defParams->pcvignette.roundness); + + if (pedited) { + strength->setDefaultEditedState (pedited->pcvignette.strength ? Edited : UnEdited); + feather->setDefaultEditedState (pedited->pcvignette.feather ? Edited : UnEdited); + roundness->setDefaultEditedState (pedited->pcvignette.roundness ? Edited : UnEdited); + } else { + strength->setDefaultEditedState (Irrelevant); + feather->setDefaultEditedState (Irrelevant); + roundness->setDefaultEditedState (Irrelevant); + } +} + +void PCVignette::adjusterChanged (Adjuster* a, double newval) { + + if (listener && getEnabled()) { + if (a == strength) + listener->panelChanged (EvPCVignetteStrength, strength->getTextValue()); + else if (a == feather) + listener->panelChanged (EvPCVignetteFeather, feather->getTextValue()); + else if (a == roundness) + listener->panelChanged (EvPCVignetteRoundness, roundness->getTextValue()); + } +} + +void PCVignette::enabledChanged () { + + if (listener) { + if (get_inconsistent()) + listener->panelChanged (EvPCVignetteEnabled, M("GENERAL_UNCHANGED")); + else if (getEnabled()) + listener->panelChanged (EvPCVignetteEnabled, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvPCVignetteEnabled, M("GENERAL_DISABLED")); + } +} + +void PCVignette::setAdjusterBehavior (bool strengthadd, bool featheradd, bool roundnessadd) +{ + strength->setAddMode(strengthadd); + feather->setAddMode(featheradd); + roundness->setAddMode(roundnessadd); +} + +void PCVignette::trimValues (rtengine::procparams::ProcParams* pp) +{ + strength->trimValue(pp->pcvignette.strength); + feather->trimValue(pp->pcvignette.feather); + roundness->trimValue(pp->pcvignette.roundness); +} + +void PCVignette::setBatchMode (bool batchMode) +{ + ToolPanel::setBatchMode (batchMode); + strength->showEditedCB (); + feather->showEditedCB (); + roundness->showEditedCB (); +} diff --git a/rtgui/pcvignette.h b/rtgui/pcvignette.h new file mode 100644 index 000000000..c71e5c32a --- /dev/null +++ b/rtgui/pcvignette.h @@ -0,0 +1,33 @@ +/* + * This file is part of RawTherapee. + */ +#ifndef _PCVIGNETTE_H_ +#define _PCVIGNETTE_H_ + +#include +#include "adjuster.h" +#include "toolpanel.h" + +class PCVignette : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel { + + protected: + Adjuster* strength; + Adjuster* feather; + Adjuster* roundness; + + public: + + PCVignette (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + + void adjusterChanged (Adjuster* a, double newval); + void enabledChanged (); + void setAdjusterBehavior (bool strengthadd, bool featheradd, bool roundnessadd); + void trimValues (rtengine::procparams::ProcParams* pp); +}; + +#endif diff --git a/rtgui/perspective.cc b/rtgui/perspective.cc new file mode 100644 index 000000000..1ae6a33ba --- /dev/null +++ b/rtgui/perspective.cc @@ -0,0 +1,108 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "perspective.h" +#include "rtimage.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +PerspCorrection::PerspCorrection () : FoldableToolPanel(this, "perspective", M("TP_PERSPECTIVE_LABEL")) { + + Gtk::Image* ipersHL = Gtk::manage (new RTImage ("perspective-h1.png")); + Gtk::Image* ipersHR = Gtk::manage (new RTImage ("perspective-h2.png")); + Gtk::Image* ipersVL = Gtk::manage (new RTImage ("perspective-v1.png")); + Gtk::Image* ipersVR = Gtk::manage (new RTImage ("perspective-v2.png")); + + horiz = Gtk::manage (new Adjuster (M("TP_PERSPECTIVE_HORIZONTAL"), -100, 100, 0.1, 0, ipersHL, ipersHR)); + horiz->setAdjusterListener (this); + + vert = Gtk::manage (new Adjuster (M("TP_PERSPECTIVE_VERTICAL"), -100, 100, 0.1, 0, ipersVL, ipersVR)); + vert->setAdjusterListener (this); + + pack_start (*horiz); + pack_start (*vert); + + show_all(); +} + +void PerspCorrection::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + if (pedited) { + horiz->setEditedState (pedited->perspective.horizontal ? Edited : UnEdited); + vert->setEditedState (pedited->perspective.vertical ? Edited : UnEdited); + } + + horiz->setValue (pp->perspective.horizontal); + vert->setValue (pp->perspective.vertical); + + enableListener (); +} + +void PerspCorrection::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->perspective.horizontal = horiz->getValue (); + pp->perspective.vertical = vert->getValue (); + + if (pedited) { + pedited->perspective.horizontal = horiz->getEditedState (); + pedited->perspective.vertical = vert->getEditedState (); + } +} + +void PerspCorrection::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + horiz->setDefault (defParams->perspective.horizontal); + vert->setDefault (defParams->perspective.vertical); + + if (pedited) { + horiz->setDefaultEditedState (pedited->perspective.horizontal ? Edited : UnEdited); + vert->setDefaultEditedState (pedited->perspective.vertical ? Edited : UnEdited); + } + else { + horiz->setDefaultEditedState (Irrelevant); + vert->setDefaultEditedState (Irrelevant); + } +} + +void PerspCorrection::adjusterChanged (Adjuster* a, double newval) { + + if (listener) + listener->panelChanged (EvPerspCorr, Glib::ustring::compose ("%1=%3\n%2=%4", M("TP_PERSPECTIVE_HORIZONTAL"), M("TP_PERSPECTIVE_VERTICAL"), horiz->getValue(), vert->getValue())); +} + +void PerspCorrection::setAdjusterBehavior (bool badd) { + + horiz->setAddMode(badd); + vert->setAddMode(badd); +} + +void PerspCorrection::trimValues (rtengine::procparams::ProcParams* pp) { + + horiz->trimValue(pp->perspective.horizontal); + vert->trimValue(pp->perspective.vertical); +} + +void PerspCorrection::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + horiz->showEditedCB (); + vert->showEditedCB (); +} diff --git a/rtgui/perspective.h b/rtgui/perspective.h new file mode 100644 index 000000000..35876e14b --- /dev/null +++ b/rtgui/perspective.h @@ -0,0 +1,46 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _PERSPECTIVE_PANEL_H_ +#define _PERSPECTIVE_PANEL_H_ + +#include +#include "adjuster.h" +#include "toolpanel.h" + +class PerspCorrection : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel { + + protected: + Adjuster* horiz; + Adjuster* vert; + + public: + + PerspCorrection (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + + void adjusterChanged (Adjuster* a, double newval); + void setAdjusterBehavior (bool badd); + void trimValues (rtengine::procparams::ProcParams* pp); +}; + +#endif diff --git a/rtgui/placesbrowser.cc b/rtgui/placesbrowser.cc new file mode 100644 index 000000000..a2dc33bfe --- /dev/null +++ b/rtgui/placesbrowser.cc @@ -0,0 +1,309 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "placesbrowser.h" +#include "options.h" +#include "toolpanel.h" +#include "../rtengine/safegtk.h" +#include "guiutils.h" +#include "rtimage.h" + +PlacesBrowser::PlacesBrowser () : listener (NULL) { + + scrollw = Gtk::manage (new Gtk::ScrolledWindow ()); + scrollw->set_policy (Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC); + pack_start (*scrollw); + + add = Gtk::manage (new Gtk::Button (M("MAIN_FRAME_PLACES_ADD"))); + del = Gtk::manage (new Gtk::Button (M("MAIN_FRAME_PLACES_DEL"))); + add->set_image (*Gtk::manage (new RTImage ("gtk-add.png"))); + del->set_image (*Gtk::manage (new RTImage ("list-remove.png"))); + Gtk::HBox* buttonBox = Gtk::manage (new Gtk::HBox ()); + buttonBox->pack_start (*add); + buttonBox->pack_start (*del); + + pack_start (*buttonBox, Gtk::PACK_SHRINK, 2); + + treeView = Gtk::manage (new Gtk::TreeView ()); + treeView->unset_flags (Gtk::CAN_FOCUS); + scrollw->add (*treeView); + + placesModel = Gtk::ListStore::create (placesColumns); + treeView->set_model (placesModel); + treeView->set_headers_visible (true); + + Gtk::TreeView::Column *iviewcol = Gtk::manage (new Gtk::TreeView::Column (M("MAIN_FRAME_PLACES"))); + Gtk::CellRendererPixbuf *iconCR = Gtk::manage (new Gtk::CellRendererPixbuf()); + Gtk::CellRendererText *labelCR = Gtk::manage (new Gtk::CellRendererText()); + iviewcol->pack_start (*iconCR, false); + iviewcol->pack_start (*labelCR, true); + iviewcol->add_attribute (*iconCR, "gicon", 0); + iviewcol->add_attribute (*labelCR, "text", placesColumns.label); + treeView->append_column (*iviewcol); + + treeView->set_row_separator_func (sigc::mem_fun(*this, &PlacesBrowser::rowSeparatorFunc)); + + vm = Gio::VolumeMonitor::get(); + + vm->signal_mount_changed().connect (sigc::mem_fun(*this, &PlacesBrowser::mountChanged)); + vm->signal_mount_added().connect (sigc::mem_fun(*this, &PlacesBrowser::mountChanged)); + vm->signal_mount_removed().connect (sigc::mem_fun(*this, &PlacesBrowser::mountChanged)); + vm->signal_volume_changed().connect (sigc::mem_fun(*this, &PlacesBrowser::volumeChanged)); + vm->signal_volume_added().connect (sigc::mem_fun(*this, &PlacesBrowser::volumeChanged)); + vm->signal_volume_removed().connect (sigc::mem_fun(*this, &PlacesBrowser::volumeChanged)); + vm->signal_drive_connected().connect (sigc::mem_fun(*this, &PlacesBrowser::driveChanged)); + vm->signal_drive_disconnected().connect (sigc::mem_fun(*this, &PlacesBrowser::driveChanged)); + vm->signal_drive_changed().connect (sigc::mem_fun(*this, &PlacesBrowser::driveChanged)); + + treeView->get_selection()->signal_changed().connect(sigc::mem_fun(*this, &PlacesBrowser::selectionChanged)); + add->signal_clicked().connect(sigc::mem_fun(*this, &PlacesBrowser::addPressed)); + del->signal_clicked().connect(sigc::mem_fun(*this, &PlacesBrowser::delPressed)); + + show_all (); +} + +// For drive letter comparison +bool compareMountByRoot (Glib::RefPtr a,Glib::RefPtr b) { + return a->get_root()->get_parse_name() < b->get_root()->get_parse_name(); +} + +void PlacesBrowser::refreshPlacesList () { + + placesModel->clear (); + + // append home directory + Glib::RefPtr hfile = Gio::File::create_for_path (safe_get_user_home_dir()); // Will send back "My documents" on Windows now, which has no restricted access + if (hfile && hfile->query_exists()) { + try { + Glib::RefPtr info = safe_query_file_info (hfile); + if (info) { + Gtk::TreeModel::Row newrow = *(placesModel->append()); + newrow[placesColumns.label] = info->get_display_name (); + newrow[placesColumns.icon] = info->get_icon (); + newrow[placesColumns.root] = hfile->get_parse_name (); + newrow[placesColumns.type] = 4; + newrow[placesColumns.rowSeparator] = false; + } + } catch (Gio::Error&) { /* This will be thrown if the path doesn't exist */ } + } + + // append pictures directory + hfile = Gio::File::create_for_path (safe_get_user_picture_dir()); + if (hfile && hfile->query_exists()) { + try { + Glib::RefPtr info = safe_query_file_info (hfile); + if (info) { + Gtk::TreeModel::Row newrow = *(placesModel->append()); + newrow[placesColumns.label] = info->get_display_name (); + newrow[placesColumns.icon] = info->get_icon (); + newrow[placesColumns.root] = hfile->get_parse_name (); + newrow[placesColumns.type] = 4; + newrow[placesColumns.rowSeparator] = false; + } + } catch (Gio::Error&) { /* This will be thrown if the path doesn't exist */ } + } + + if (!placesModel->children().empty()) { + Gtk::TreeModel::Row newrow = *(placesModel->append()); + newrow[placesColumns.rowSeparator] = true; + } + + // scan all drives + std::vector > drives = vm->get_connected_drives (); + for (size_t j=0; j > volumes = drives[j]->get_volumes (); + if (volumes.empty()) { + Gtk::TreeModel::Row newrow = *(placesModel->append()); + newrow[placesColumns.label] = drives[j]->get_name (); + newrow[placesColumns.icon] = drives[j]->get_icon (); + newrow[placesColumns.root] = ""; + newrow[placesColumns.type] = 3; + newrow[placesColumns.rowSeparator] = false; + } + for (size_t i=0; i mount = volumes[i]->get_mount (); + if (mount) { // placesed volumes + Gtk::TreeModel::Row newrow = *(placesModel->append()); + newrow[placesColumns.label] = mount->get_name (); + newrow[placesColumns.icon] = mount->get_icon (); + newrow[placesColumns.root] = mount->get_root ()->get_parse_name (); + newrow[placesColumns.type] = 1; + newrow[placesColumns.rowSeparator] = false; + } + else { // unplacesed volumes + Gtk::TreeModel::Row newrow = *(placesModel->append()); + newrow[placesColumns.label] = volumes[i]->get_name (); + newrow[placesColumns.icon] = volumes[i]->get_icon (); + newrow[placesColumns.root] = ""; + newrow[placesColumns.type] = 2; + newrow[placesColumns.rowSeparator] = false; + } + } + } + + // volumes not belonging to drives + std::vector > volumes = vm->get_volumes (); + for (size_t i=0; iget_drive ()) { + Glib::RefPtr mount = volumes[i]->get_mount (); + if (mount) { // placesed volumes + Gtk::TreeModel::Row newrow = *(placesModel->append()); + newrow[placesColumns.label] = mount->get_name (); + newrow[placesColumns.icon] = mount->get_icon (); + newrow[placesColumns.root] = mount->get_root ()->get_parse_name (); + newrow[placesColumns.type] = 1; + newrow[placesColumns.rowSeparator] = false; + } + else { // unplacesed volumes + Gtk::TreeModel::Row newrow = *(placesModel->append()); + newrow[placesColumns.label] = volumes[i]->get_name (); + newrow[placesColumns.icon] = volumes[i]->get_icon (); + newrow[placesColumns.root] = ""; + newrow[placesColumns.type] = 2; + newrow[placesColumns.rowSeparator] = false; + } + } + } + + // places not belonging to volumes + // (Drives in Windows) + std::vector > mounts = vm->get_mounts (); + +#ifdef WIN32 + // on Windows, it's usual to sort by drive letter, not by name + std::sort (mounts.begin(), mounts.end(), compareMountByRoot); +#endif + + for (size_t i=0; iget_volume ()) { + Gtk::TreeModel::Row newrow = *(placesModel->append()); + newrow[placesColumns.label] = mounts[i]->get_name (); + newrow[placesColumns.icon] = mounts[i]->get_icon (); + newrow[placesColumns.root] = mounts[i]->get_root ()->get_parse_name (); + newrow[placesColumns.type] = 1; + newrow[placesColumns.rowSeparator] = false; + } + } + // append favorites + if (!placesModel->children().empty()) { + Gtk::TreeModel::Row newrow = *(placesModel->append()); + newrow[placesColumns.rowSeparator] = true; + } + for (size_t i=0; i hfile = Gio::File::create_for_path (options.favoriteDirs[i]); + if (hfile && hfile->query_exists()) { + Glib::RefPtr info = safe_query_file_info (hfile); + if (info) { + Gtk::TreeModel::Row newrow = *(placesModel->append()); + newrow[placesColumns.label] = info->get_display_name (); + newrow[placesColumns.icon] = info->get_icon (); + newrow[placesColumns.root] = hfile->get_parse_name (); + newrow[placesColumns.type] = 5; + newrow[placesColumns.rowSeparator] = false; + } + } + } +} + +bool PlacesBrowser::rowSeparatorFunc (const Glib::RefPtr& model, const Gtk::TreeModel::iterator& iter) { + + return iter->get_value (placesColumns.rowSeparator); +} + +void PlacesBrowser::mountChanged (const Glib::RefPtr& m) { + GThreadLock lock; + refreshPlacesList (); +} + +void PlacesBrowser::volumeChanged (const Glib::RefPtr& m) { + GThreadLock lock; + refreshPlacesList (); +} + +void PlacesBrowser::driveChanged (const Glib::RefPtr& m) { + GThreadLock lock; + refreshPlacesList (); +} + +void PlacesBrowser::selectionChanged () { + + Glib::RefPtr selection = treeView->get_selection(); + Gtk::TreeModel::iterator iter = selection->get_selected(); + if (iter) { + if (iter->get_value (placesColumns.type)==2) { + std::vector > volumes = vm->get_volumes (); + for (size_t i=0; iget_name () == iter->get_value (placesColumns.label)) { + volumes[i]->mount (); + break; + } + } + else if (iter->get_value (placesColumns.type)==3) { + std::vector > drives = vm->get_connected_drives (); + for (size_t i=0; iget_name () == iter->get_value (placesColumns.label)) { + drives[i]->poll_for_media (); + break; + } + } + else if (listener) + listener->selectDir (iter->get_value (placesColumns.root)); + } +} + +void PlacesBrowser::dirSelected (const Glib::ustring& dirname, const Glib::ustring& openfile) { + + lastSelectedDir = dirname; +} + +void PlacesBrowser::addPressed () { + + if (lastSelectedDir=="") + return; + + // check if the dirname is already in the list. If yes, return. + for (size_t i=0; i hfile = Gio::File::create_for_path (lastSelectedDir); + if (hfile && hfile->query_exists()) { + Glib::RefPtr info = safe_query_file_info (hfile); + if (info) { + options.favoriteDirs.push_back (hfile->get_parse_name ()); + refreshPlacesList (); + } + } +} + +void PlacesBrowser::delPressed () { + + // lookup the selected item in the bookmark + Glib::RefPtr selection = treeView->get_selection(); + Gtk::TreeModel::iterator iter = selection->get_selected(); + + if (iter && iter->get_value (placesColumns.type)==5) { + std::vector::iterator i = std::find (options.favoriteDirs.begin(), options.favoriteDirs.end(), iter->get_value (placesColumns.root)); + if (i != options.favoriteDirs.end()) + options.favoriteDirs.erase (i); + } + + refreshPlacesList (); +} + diff --git a/rtgui/placesbrowser.h b/rtgui/placesbrowser.h new file mode 100644 index 000000000..95a2f9ca5 --- /dev/null +++ b/rtgui/placesbrowser.h @@ -0,0 +1,68 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _PLACESBROWSER_ +#define _PLACESBROWSER_ + +#include +#include +#include "dirbrowserremoteinterface.h" +#include "dirselectionlistener.h" +#include "multilangmgr.h" + +class PlacesBrowser : public Gtk::VBox, public DirSelectionListener { + + class PlacesColumns : public Gtk::TreeModel::ColumnRecord { + public: + Gtk::TreeModelColumn > icon; + Gtk::TreeModelColumn label; + Gtk::TreeModelColumn root; + Gtk::TreeModelColumn type; + Gtk::TreeModelColumn rowSeparator; + PlacesColumns() { add(icon); add(label); add(root); add(type); add(rowSeparator); } + }; + PlacesColumns placesColumns; + Gtk::ScrolledWindow* scrollw; + Gtk::TreeView* treeView; + Glib::RefPtr placesModel; + Glib::RefPtr vm; + DirBrowserRemoteInterface* listener; + Glib::ustring lastSelectedDir; + Gtk::Button* add; + Gtk::Button* del; + + public: + + PlacesBrowser (); + + void setDirBrowserRemoteInterface (DirBrowserRemoteInterface* l) { listener = l; } + void dirSelected (const Glib::ustring& dirname, const Glib::ustring& openfile=""); + + void refreshPlacesList (); + void mountChanged (const Glib::RefPtr& m); + void volumeChanged (const Glib::RefPtr& v); + void driveChanged (const Glib::RefPtr& d); + bool rowSeparatorFunc (const Glib::RefPtr& model, const Gtk::TreeModel::iterator& iter); + void selectionChanged (); + void addPressed (); + void delPressed (); +}; + +#endif + + diff --git a/rtgui/pointermotionlistener.h b/rtgui/pointermotionlistener.h new file mode 100644 index 000000000..422b25551 --- /dev/null +++ b/rtgui/pointermotionlistener.h @@ -0,0 +1,30 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _POINTERMOTIONLISTENER_ +#define _POINTERMOTIONLISTENER_ + +class PointerMotionListener { + + public: +// virtual void pointerMoved (bool validPos, int x, int y, int r, int g, int b) {} + virtual void pointerMoved (bool validPos, Glib::ustring profile, Glib::ustring profileW,int x, int y, int r, int g, int b) {} + virtual void toggleFreeze () {} +}; + +#endif diff --git a/rtgui/popupbutton.cc b/rtgui/popupbutton.cc new file mode 100644 index 000000000..6db2879fd --- /dev/null +++ b/rtgui/popupbutton.cc @@ -0,0 +1,39 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + * + * Class created by Jean-Christophe FRISCH, aka 'Hombre' + */ + +#include "popupbutton.h" + +/* + * PopUpButton::PopUpButton (const Glib::ustring& label, bool imgRight) + * + * Creates a button with a contextual menu where you can select an item that the button content will reflect + * + * Parameters: + * label = label displayed in the button + */ +PopUpButton::PopUpButton (const Glib::ustring& label) : Gtk::Button(), PopUpCommon(this, label) { } + +void PopUpButton::show() { + PopUpCommon::show(); +} +void PopUpButton::set_tooltip_text (const Glib::ustring &text) { + PopUpCommon::set_tooltip_text (text); +} diff --git a/rtgui/popupbutton.h b/rtgui/popupbutton.h new file mode 100644 index 000000000..6239c4a40 --- /dev/null +++ b/rtgui/popupbutton.h @@ -0,0 +1,35 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + * + * Class created by Jean-Christophe FRISCH, aka 'Hombre' + */ +#ifndef _POPUPBUTTON_ +#define _POPUPBUTTON_ + +#include +#include "popupcommon.h" + +class PopUpButton : public Gtk::Button, public PopUpCommon { + +public: + PopUpButton (const Glib::ustring& label = ""); + void show (); + void set_tooltip_text (const Glib::ustring &text); +}; + +#endif diff --git a/rtgui/popupcommon.cc b/rtgui/popupcommon.cc new file mode 100644 index 000000000..9c0ee4d66 --- /dev/null +++ b/rtgui/popupcommon.cc @@ -0,0 +1,159 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + * + * Class created by Jean-Christophe FRISCH, aka 'Hombre' + */ + +#include "multilangmgr.h" +#include "popupcommon.h" +#include "../rtengine/safegtk.h" +#include "rtimage.h" + +PopUpCommon::PopUpCommon (Gtk::Button* thisButton, const Glib::ustring& label) { + button = thisButton; + hasMenu = false; + imageContainer = Gtk::manage( new Gtk::HBox(false, 0)); + button->set_relief (Gtk::RELIEF_NORMAL); + button->set_border_width (0); + button->add(*imageContainer); + if (label.size()) { + Gtk::Label* buttonLabel = Gtk::manage ( new Gtk::Label(label + " ") ); + imageContainer->pack_start(*buttonLabel, Gtk::PACK_SHRINK, 0); + } + // Create the global container and put the button in it + buttonGroup = Gtk::manage( new Gtk::HBox(false, 0)); + buttonGroup->pack_start(*button, Gtk::PACK_EXPAND_WIDGET, 0); + // Create the list entry + imageFilenames.clear(); + images.clear(); + sItems.clear(); + items.clear(); + selected = -1; // -1 : means that the button is invalid + menu = 0; + buttonImage = 0; + buttonHint = ""; +} + +PopUpCommon::~PopUpCommon () { + for (std::vector::iterator i = images.begin(); i != images.end(); ++i) + { + delete *i; + } + for (std::vector::iterator i = items.begin(); i != items.end(); ++i) + { + delete *i; + } + if (menu) delete menu; + if (buttonImage) delete buttonImage; + delete buttonGroup; +} + +PopUpCommon::type_signal_changed PopUpCommon::signal_changed() { + return message; +} + +bool PopUpCommon::addEntry (Glib::ustring fileName, Glib::ustring label) { + bool added = false; + if ( label.size() ) { + imageFilenames.push_back(fileName); + sItems.push_back(label); + // Create the image + RTImage* newImage = new RTImage(fileName); + images.push_back(newImage); + int currPos = (int)images.size(); + // Create the menu item + Gtk::ImageMenuItem* newItem = new Gtk::ImageMenuItem (*newImage, label); + items.push_back(newItem); + if (selected == -1) { + // Create the menu on the first item + menu = new Gtk::Menu (); + // Create the image for the button + buttonImage = new RTImage(fileName); + // Use the first image by default + imageContainer->pack_start(*buttonImage,Gtk::PACK_EXPAND_WIDGET); + selected = 0; + } + // When there is at least 1 choice, we add the arrow button + if (images.size() == 1) { + Gtk::Button* arrowButton = Gtk::manage( new Gtk::Button() ); + RTImage* arrowImage = Gtk::manage( new RTImage("popuparrow.png") ); + arrowButton->add(*arrowImage); //menuSymbol); + arrowButton->set_relief (Gtk::RELIEF_NONE); + arrowButton->set_border_width (0); + buttonGroup->pack_start(*arrowButton,Gtk::PACK_SHRINK, 0); + arrowButton->signal_button_release_event().connect_notify( sigc::mem_fun(*this, &PopUpCommon::showMenu) ); + hasMenu = true; + } + newItem->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &PopUpCommon::entrySelected), currPos-1)); + menu->attach (*newItem, 0, 1, currPos-1, currPos); + // The item has been created + added = true; + } + return added; +} + +// TODO: 'PopUpCommon::removeEntry' method to be created... + +void PopUpCommon::entrySelected (int i) { + if (setSelected((unsigned int)i)) + // Emit a a signal if the selected item has changed + message.emit(selected); +} + +/* + * Set the button image with the selected item + */ +bool PopUpCommon::setSelected (int entryNum) { + if (entryNum < 0 || entryNum > ((int)images.size()-1) || (int)entryNum == selected) + return false; + else { + // Maybe we could do something better than loading the image file each time the selection is changed !? + buttonImage->changeImage(imageFilenames.at(entryNum)); + selected = entryNum; + setButtonHint(); + return true; + } +} + +void PopUpCommon::show() { + menu->reposition(); + setButtonHint(); + menu->show_all(); + buttonGroup->show_all(); +} + +void PopUpCommon::setButtonHint() { + Glib::ustring hint; + if (!buttonHint.empty()) { + hint = buttonHint; + if (selected > -1) + hint += " "; + } + if (selected > -1) + hint += sItems.at(selected); + button->set_tooltip_markup(hint); +} + +void PopUpCommon::showMenu(GdkEventButton* event) { + if (event->button == 1) menu->popup(event->button, event->time); +} + +void PopUpCommon::set_tooltip_text (const Glib::ustring &text) { + buttonHint = text; + setButtonHint(); +} diff --git a/rtgui/popupcommon.h b/rtgui/popupcommon.h new file mode 100644 index 000000000..eba9e1ea3 --- /dev/null +++ b/rtgui/popupcommon.h @@ -0,0 +1,70 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + * + * Class created by Jean-Christophe FRISCH, aka 'Hombre' + */ +#ifndef _POPUPCOMMON_ +#define _POPUPCOMMON_ + + +#include +#include +#include "rtimage.h" + + +class PopUpCommon { + +public: + typedef sigc::signal type_signal_changed; + type_signal_changed signal_changed(); + Gtk::HBox* buttonGroup; // this is the widget to be packed + + PopUpCommon (Gtk::Button* button, const Glib::ustring& label = ""); + virtual ~PopUpCommon (); + bool addEntry (Glib::ustring fileName, Glib::ustring label); + bool setSelected (int entryNum); + int getSelected () { return selected; } + void setButtonHint(); + void show (); + void set_tooltip_text (const Glib::ustring &text); + +private: + type_signal_changed message; + + /* + TODO: MenuItem::get_label() doesn't return any string, or an empty string !? + That's why we store entries strings in sItems, but it would be nice to get ride of it... + */ + std::vector sItems; + std::vector imageFilenames; + std::vector images; + std::vector items; + Glib::ustring buttonHint; + RTImage* buttonImage; + Gtk::HBox* imageContainer; + Gtk::Menu* menu; + Gtk::Button* button; + int selected; + bool hasMenu; + + void showMenu(GdkEventButton* event); + void entrySelected (int i); + +}; + +#endif diff --git a/rtgui/popuptogglebutton.cc b/rtgui/popuptogglebutton.cc new file mode 100644 index 000000000..7bdf9ef51 --- /dev/null +++ b/rtgui/popuptogglebutton.cc @@ -0,0 +1,39 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + * + * Class created by Jean-Christophe FRISCH, aka 'Hombre' + */ + +#include "popuptogglebutton.h" + +/* + * PopUpToggleButton::PopUpToggleButton (const Glib::ustring& label, bool imgRight) + * + * Creates a toggle button with a contextual menu where you can select an item that the button content will reflect + * + * Parameters: + * label = label displayed in the button + */ +PopUpToggleButton::PopUpToggleButton (const Glib::ustring& label) : Gtk::ToggleButton(), PopUpCommon(this, label) { } + +void PopUpToggleButton::show() { + PopUpCommon::show(); +} +void PopUpToggleButton::set_tooltip_text (const Glib::ustring &text) { + PopUpCommon::set_tooltip_text (text); +} diff --git a/rtgui/popuptogglebutton.h b/rtgui/popuptogglebutton.h new file mode 100644 index 000000000..762c88926 --- /dev/null +++ b/rtgui/popuptogglebutton.h @@ -0,0 +1,35 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + * + * Class created by Jean-Christophe FRISCH, aka 'Hombre' + */ +#ifndef _POPUPTOGGLEBUTTON_ +#define _POPUPTOGGLEBUTTON_ + +#include "popupbutton.h" +#include "popupcommon.h" + +class PopUpToggleButton : public Gtk::ToggleButton, public PopUpCommon { + +public: + PopUpToggleButton (const Glib::ustring& label = ""); + void show (); + void set_tooltip_text (const Glib::ustring &text); +}; + +#endif diff --git a/rtgui/pparamschangelistener.h b/rtgui/pparamschangelistener.h new file mode 100644 index 000000000..10eff09a5 --- /dev/null +++ b/rtgui/pparamschangelistener.h @@ -0,0 +1,43 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _PPARAMSCHANGELISTENER_ +#define _PPARAMSCHANGELISTENER_ + +#include "../rtengine/rtengine.h" +#include +#include "paramsedited.h" + +class PParamsChangeListener { + + public: + virtual ~PParamsChangeListener() {} + virtual void procParamsChanged (rtengine::procparams::ProcParams* params, rtengine::ProcEvent ev, Glib::ustring descr, ParamsEdited* paramsEdited=NULL) {} + virtual void clearParamChanges () {} +}; + +class BatchPParamsChangeListener { + + public: + virtual ~BatchPParamsChangeListener() {} + virtual void beginBatchPParamsChange(int numberOfEntries) {} + virtual void endBatchPParamsChange() {} +}; + +#endif + diff --git a/rtgui/ppversion.h b/rtgui/ppversion.h new file mode 100644 index 000000000..587b4204f --- /dev/null +++ b/rtgui/ppversion.h @@ -0,0 +1,43 @@ +#ifndef _PPVERSION_ +#define _PPVERSION_ + +// This number has to be incremented whenever the PP3 file format is modified or the behaviour of a tool changes +#define PPVERSION 324 +#define PPVERSION_AEXP 301 //value of PPVERSION when auto exposure algorithm was modified + +/* + Log of version changes + 323 2015-10-05 + [Exposure] Added 'Luminance' tone curve mode + 322 2015-01-31 + [Wavelet] new tool using wavelet levels + 321 2014-08-17 + [Film Simulation] new tool using HALDCLUT files + 320 2014-07-02 (yes, same version number... this is an error due to a wrong version number set in comment of previous change) + New [RAW Bayer] and [RAW X-Trans] sections, with some parameters transfered from [RAW] to [RAW Bayer] + 320 2014-03-29 + [ColorToning] new tool for color toning + 319 2014-02-11 + Hue skin for Contrast by detail levels + 318 2014-02-10 + Vignetting Correction bug makes hard transitions for positive Amount values, Issue 2241 + 317 2014-01-19 + changes to behaviour of LC curve, Issue 2209 + 315 2013-12-12 + add LH et HH curve to lab mode + 313 2013-11-19 + add CL curve to lab mode + 312 2013-11-08 + added numerous changes to [channel mixer] + 311 2013-11-07 + [Gradient] new tool (gradient/graduated filter + [PCVignette] new tool (vignette filter) + 310 2013-09-16 + Defringing /Threshold - changed calculation, issue 1801 + 307 2013-03-16 + [Perspective] Horizontal and Vertical changed from int to double + added [Directional Pyramid Denoising] Method, Redchro, Bluechro + added [RGB Curves] LumaMode + */ + +#endif diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc new file mode 100644 index 000000000..26ba14c35 --- /dev/null +++ b/rtgui/preferences.cc @@ -0,0 +1,2048 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath , Oliver Duis + * + * 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 "preferences.h" +#include "multilangmgr.h" +#include "splash.h" +#include "cachemanager.h" +#include "addsetids.h" +#include "../rtengine/dfmanager.h" +#include "../rtengine/ffmanager.h" +#include +#include "../rtengine/safegtk.h" +#include "rtimage.h" +#ifdef _OPENMP +#include +#endif + +extern Options options; +extern Glib::ustring argv0; + +Preferences::Preferences (RTWindow *rtwindow) : rprofiles(NULL), iprofiles(NULL), parent(rtwindow) { + + splash = NULL; + + set_title (M("MAIN_BUTTON_PREFERENCES")); + + moptions.copyFrom (&options); + oldSlimUI = options.slimUI; + + /* + * Do not increase height, since it's not visible on e.g. smaller netbook screens + * Default height is about 620 pixels actually, that's why we do not set the height anymore + * Netbook users will most certainly set a smaller font and use the "slimUI" mode, + * so they'll be able to shrink the pref window and close it. + */ + set_size_request (650, -1); + set_default_size (options.preferencesWidth, options.preferencesHeight); + set_border_width(4); + + Gtk::VBox* mainvb = get_vbox (); + mainvb->set_spacing(8); + set_has_separator (false); + + Gtk::Notebook* nb = Gtk::manage (new Gtk::Notebook ()); + mainvb->pack_start (*nb); + + Gtk::HBox* buttonpanel = Gtk::manage (new Gtk::HBox ()); + buttonpanel->set_spacing(8); + mainvb->pack_start (*buttonpanel, Gtk::PACK_SHRINK, 0); + + Gtk::Button* about = Gtk::manage (new Gtk::Button (M("GENERAL_ABOUT"))); + Gtk::Button* ok = Gtk::manage (new Gtk::Button (M("GENERAL_OK"))); + Gtk::Button* cancel = Gtk::manage (new Gtk::Button (M("GENERAL_CANCEL"))); + + about->set_image (*Gtk::manage(new RTImage ("rt-logo.png"))); + ok->set_image (*Gtk::manage(new RTImage ("gtk-apply.png"))); + cancel->set_image (*Gtk::manage(new RTImage ("gtk-cancel.png"))); + + + about->signal_clicked().connect( sigc::mem_fun(*this, &Preferences::aboutPressed) ); + ok->signal_clicked().connect( sigc::mem_fun(*this, &Preferences::okPressed) ); + cancel->signal_clicked().connect( sigc::mem_fun(*this, &Preferences::cancelPressed) ); + + buttonpanel->pack_start (*about, Gtk::PACK_SHRINK, 0); + buttonpanel->pack_end (*ok, Gtk::PACK_SHRINK, 0); + buttonpanel->pack_end (*cancel, Gtk::PACK_SHRINK, 0); + nb->append_page (*getGeneralPanel(), M("PREFERENCES_TAB_GENERAL")); + nb->append_page (*getProcParamsPanel(), M("PREFERENCES_TAB_IMPROC")); + nb->append_page (*getFileBrowserPanel(), M("PREFERENCES_TAB_BROWSER")); + nb->append_page (*getColorManagementPanel(),M("PREFERENCES_TAB_COLORMGR")); + nb->append_page (*getBatchProcPanel(), M("PREFERENCES_BATCH_PROCESSING")); + nb->append_page (*getPerformancePanel(), M("PREFERENCES_TAB_PERFORMANCE")); + // Sounds only on Windows and Linux +#if defined(WIN32) || defined(__linux__) + nb->append_page (*getSoundPanel(), M("PREFERENCES_TAB_SOUND")); +#endif + nb->set_current_page (0); + + profileStore.addListener(this); + + fillPreferences (); + + show_all_children (); + set_modal (true); +} + + +Preferences::~Preferences () { + + profileStore.removeListener(this); + options.preferencesWidth = get_width(); + options.preferencesHeight = get_height(); +} + +Gtk::Widget* Preferences::getBatchProcPanel () { + + Gtk::VBox* mvbpp = Gtk::manage (new Gtk::VBox ()); + mvbpp->set_border_width(4); + + Gtk::ScrolledWindow* behscrollw = Gtk::manage (new Gtk::ScrolledWindow ()); + behscrollw->set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); + behscrollw->set_border_width(8); + behscrollw->set_size_request(-1, 60); + Gtk::VBox* vbbeh = Gtk::manage( new Gtk::VBox () ); + vbbeh->pack_start (*behscrollw, Gtk::PACK_EXPAND_WIDGET); + Gtk::Frame* behFrame = Gtk::manage (new Gtk::Frame (M("PREFERENCES_BEHAVIOR"))); + behFrame->add (*vbbeh); + //mvbpp->pack_start (*behFrame); + mvbpp->pack_start (*behFrame, Gtk::PACK_EXPAND_WIDGET, 4); + Gtk::TreeView* behTreeView = Gtk::manage (new Gtk::TreeView ()); + behscrollw->add (*behTreeView); + + behModel = Gtk::TreeStore::create (behavColumns); + behTreeView->set_model (behModel); + + behTreeView->append_column (M("PREFERENCES_PROPERTY"), behavColumns.label); + behTreeView->append_column_editable (M("PREFERENCES_ADD"), behavColumns.badd); + behTreeView->append_column_editable (M("PREFERENCES_SET"), behavColumns.bset); + + Gtk::CellRendererToggle* cr_add = static_cast (behTreeView->get_column (1)->get_first_cell_renderer()); + Gtk::CellRendererToggle* cr_set = static_cast (behTreeView->get_column (2)->get_first_cell_renderer()); + + cr_add->set_radio (true); + cr_add->set_property("xalign", 0.0f); + sigc::connection addc = cr_add->signal_toggled().connect (sigc::mem_fun (*this, &Preferences::behAddRadioToggled)); + cr_set->set_radio (true); + cr_set->set_property("xalign", 0.0f); + sigc::connection setc = cr_set->signal_toggled().connect (sigc::mem_fun (*this, &Preferences::behSetRadioToggled)); + + behTreeView->get_column (1)->add_attribute (*cr_add, "visible", behavColumns.visible); + behTreeView->get_column (1)->set_sizing(Gtk::TREE_VIEW_COLUMN_FIXED); + behTreeView->get_column (1)->set_fixed_width (50); + behTreeView->get_column (2)->add_attribute (*cr_set, "visible", behavColumns.visible); + behTreeView->get_column (2)->set_sizing(Gtk::TREE_VIEW_COLUMN_FIXED); + behTreeView->get_column (2)->set_fixed_width (50); + + // fill model + Gtk::TreeModel::iterator mi, ci; + + /* + * The TRUE/FALSE values of appendBehavList are replaced by the one defined in options.cc, + */ + mi = behModel->append (); + mi->set_value (behavColumns.label, M("TP_EXPOSURE_LABEL")); + appendBehavList (mi, M("TP_EXPOSURE_EXPCOMP"), ADDSET_TC_EXPCOMP, false); + appendBehavList (mi, M("TP_EXPOSURE_COMPRHIGHLIGHTS"), ADDSET_TC_HLCOMPAMOUNT, false); + appendBehavList (mi, M("TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD"), ADDSET_TC_HLCOMPTHRESH, false); + appendBehavList (mi, M("TP_EXPOSURE_BLACKLEVEL"), ADDSET_TC_BLACKLEVEL, false); + appendBehavList (mi, M("TP_EXPOSURE_COMPRSHADOWS"), ADDSET_TC_SHCOMP, false); + appendBehavList (mi, M("TP_EXPOSURE_BRIGHTNESS"), ADDSET_TC_BRIGHTNESS, false); + 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_SHADOWSHLIGHTS_LABEL")); + appendBehavList (mi, M("TP_SHADOWSHLIGHTS_HIGHLIGHTS"), ADDSET_SH_HIGHLIGHTS, false); + appendBehavList (mi, M("TP_SHADOWSHLIGHTS_SHADOWS"), ADDSET_SH_SHADOWS, false); + appendBehavList (mi, M("TP_SHADOWSHLIGHTS_LOCALCONTR"), ADDSET_SH_LOCALCONTRAST, false); + + mi = behModel->append (); + mi->set_value (behavColumns.label, M("TP_LABCURVE_LABEL")); + appendBehavList (mi, M("TP_LABCURVE_BRIGHTNESS"), ADDSET_LC_BRIGHTNESS, false); + appendBehavList (mi, M("TP_LABCURVE_CONTRAST"), ADDSET_LC_CONTRAST, false); + appendBehavList (mi, M("TP_LABCURVE_CHROMATICITY"), ADDSET_LC_CHROMATICITY, false); + + mi = behModel->append (); + mi->set_value (behavColumns.label, M("TP_SHARPENING_LABEL")); + appendBehavList (mi, M("TP_SHARPENING_AMOUNT"), ADDSET_SHARP_AMOUNT, false); + + mi = behModel->append (); + mi->set_value (behavColumns.label, M("TP_SHARPENEDGE_LABEL")); + appendBehavList (mi, M("TP_SHARPENEDGE_PASSES"), ADDSET_SHARPENEDGE_PASS, false); + appendBehavList (mi, M("TP_SHARPENEDGE_AMOUNT"), ADDSET_SHARPENEDGE_AMOUNT, false); + + mi = behModel->append (); + mi->set_value (behavColumns.label, M("TP_SHARPENMICRO_LABEL")); + appendBehavList (mi, M("TP_SHARPENMICRO_AMOUNT"), ADDSET_SHARPENMICRO_AMOUNT, false); + appendBehavList (mi, M("TP_SHARPENMICRO_UNIFORMITY"), ADDSET_SHARPENMICRO_UNIFORMITY, false); + + mi = behModel->append (); + mi->set_value (behavColumns.label, M("TP_DIRPYRDENOISE_LABEL")); + // appendBehavList (mi, M("TP_DIRPYRDENOISE_LUMA")+", "+M("TP_DIRPYRDENOISE_CHROMA"), ADDSET_DIRPYRDN_CHLUM, true); + appendBehavList (mi, M("TP_DIRPYRDENOISE_LUMA"),ADDSET_DIRPYRDN_LUMA, true); + appendBehavList (mi, M("TP_DIRPYRDENOISE_LDETAIL"),ADDSET_DIRPYRDN_LUMDET, true); + appendBehavList (mi, M("TP_DIRPYRDENOISE_CHROMA"), ADDSET_DIRPYRDN_CHROMA, true); + appendBehavList (mi, M("TP_DIRPYRDENOISE_RED"), ADDSET_DIRPYRDN_CHROMARED, true); + appendBehavList (mi, M("TP_DIRPYRDENOISE_BLUE"), ADDSET_DIRPYRDN_CHROMABLUE, true); + appendBehavList (mi, M("TP_DIRPYRDENOISE_GAMMA"), ADDSET_DIRPYRDN_GAMMA, true); + appendBehavList (mi, M("TP_DIRPYRDENOISE_PASSES"), ADDSET_DIRPYRDN_PASSES, true); + + mi = behModel->append (); + mi->set_value (behavColumns.label, M("TP_WBALANCE_LABEL")); + appendBehavList (mi, M("TP_WBALANCE_TEMPERATURE"), ADDSET_WB_TEMPERATURE, true); + appendBehavList (mi, M("TP_WBALANCE_GREEN"), ADDSET_WB_GREEN, true); + appendBehavList (mi, M("TP_WBALANCE_EQBLUERED"), ADDSET_WB_EQUAL, true); + + mi = behModel->append (); + mi->set_value (behavColumns.label, M("TP_COLORAPP_LABEL")); + appendBehavList (mi, M("TP_COLORAPP_CIECAT_DEGREE"),ADDSET_CAT_DEGREE, true); + appendBehavList (mi, M("TP_COLORAPP_ADAPTSCENE"),ADDSET_CAT_ADAPTSCENE, true); + appendBehavList (mi, M("TP_COLORAPP_LIGHT"),ADDSET_CAT_LIGHT, true); + appendBehavList (mi, M("TP_COLORAPP_BRIGHT"),ADDSET_CAT_BRIGHT, true); + appendBehavList (mi, M("TP_COLORAPP_CHROMA"),ADDSET_CAT_CHROMA, true); + appendBehavList (mi, M("TP_COLORAPP_RSTPRO"),ADDSET_CAT_RSTPRO, true); + appendBehavList (mi, M("TP_COLORAPP_CONTRAST"),ADDSET_CAT_CONTRAST, true); + appendBehavList (mi, M("TP_COLORAPP_CONTRAST_Q"),ADDSET_CAT_CONTRAST_Q, true); + appendBehavList (mi, M("TP_COLORAPP_CHROMA_S"),ADDSET_CAT_CHROMA_S, true); + appendBehavList (mi, M("TP_COLORAPP_CHROMA_M"),ADDSET_CAT_CHROMA_M, true); + appendBehavList (mi, M("TP_COLORAPP_HUE"),ADDSET_CAT_HUE, true); + appendBehavList (mi, M("TP_COLORAPP_ADAPTVIEWING"),ADDSET_CAT_ADAPTVIEWING, true); + appendBehavList (mi, M("TP_COLORAPP_BADPIXSL"),ADDSET_CAT_BADPIX, true); + + mi = behModel->append (); + mi->set_value (behavColumns.label, M("TP_VIBRANCE_LABEL")); + appendBehavList (mi, M("TP_VIBRANCE_PASTELS"), ADDSET_VIBRANCE_PASTELS, false); + appendBehavList (mi, M("TP_VIBRANCE_SATURATED"), ADDSET_VIBRANCE_SATURATED, false); + + mi = behModel->append (); + mi->set_value (behavColumns.label, M("TP_GAMMA_OUTPUT")); + appendBehavList (mi, M("TP_GAMMA_CURV"), ADDSET_FREE_OUPUT_GAMMA, false); + appendBehavList (mi, M("TP_GAMMA_SLOP"), ADDSET_FREE_OUTPUT_SLOPE, false); + + mi = behModel->append (); + mi->set_value (behavColumns.label, M("TP_CHMIXER_LABEL")); + appendBehavList (mi, M("TP_CHMIXER_RED")+", "+M("TP_CHMIXER_GREEN")+", "+M("TP_CHMIXER_BLUE"), ADDSET_CHMIXER, false); + + mi = behModel->append (); + mi->set_value (behavColumns.label, M("TP_BWMIX_LABEL")); + appendBehavList (mi, M("TP_BWMIX_MIXC"), ADDSET_BLACKWHITE_HUES, false); + appendBehavList (mi, M("TP_BWMIX_GAMMA"), ADDSET_BLACKWHITE_GAMMA, false); + + mi = behModel->append (); + mi->set_value( behavColumns.label, M("TP_FILMSIMULATION_LABEL") ); + appendBehavList( mi, M( "TP_FILMSIMULATION_STRENGTH" ), ADDSET_FILMSIMULATION_STRENGTH, true ); + + mi = behModel->append (); + mi->set_value (behavColumns.label, M("TP_COLORTONING_LABEL")); + appendBehavList (mi, M("TP_COLORTONING_SPLITCOCO"),ADDSET_COLORTONING_SPLIT , true); + appendBehavList (mi, M("TP_COLORTONING_SATURATIONTHRESHOLD"),ADDSET_COLORTONING_SATTHRESHOLD , true); + appendBehavList (mi, M("TP_COLORTONING_SATURATEDOPACITY"),ADDSET_COLORTONING_SATOPACITY , true); + appendBehavList (mi, M("TP_COLORTONING_BALANCE"),ADDSET_COLORTONING_BALANCE , true); + appendBehavList (mi, M("TP_COLORTONING_STRENGTH"),ADDSET_COLORTONING_STRENGTH , true); + + mi = behModel->append (); + 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_DISTORTION_LABEL")); + appendBehavList (mi, M("TP_DISTORTION_AMOUNT"), ADDSET_DIST_AMOUNT, false); + + mi = behModel->append (); + mi->set_value (behavColumns.label, M("TP_PERSPECTIVE_LABEL")); + appendBehavList (mi, M("TP_PERSPECTIVE_HORIZONTAL")+", "+M("TP_PERSPECTIVE_VERTICAL"), ADDSET_PERSPECTIVE, false); + + mi = behModel->append (); + mi->set_value (behavColumns.label, M("TP_GRADIENT_LABEL")); + appendBehavList (mi, M("TP_GRADIENT_DEGREE"), ADDSET_GRADIENT_DEGREE, false); + appendBehavList (mi, M("TP_GRADIENT_FEATHER"), ADDSET_GRADIENT_FEATHER, false); + appendBehavList (mi, M("TP_GRADIENT_STRENGTH"), ADDSET_GRADIENT_STRENGTH, false); + appendBehavList (mi, M("TP_GRADIENT_CENTER_X")+", "+M("TP_GRADIENT_CENTER_Y"), ADDSET_GRADIENT_CENTER, false); + + mi = behModel->append (); + mi->set_value (behavColumns.label, M("TP_PCVIGNETTE_LABEL")); + appendBehavList (mi, M("TP_PCVIGNETTE_STRENGTH"), ADDSET_PCVIGNETTE_STRENGTH, false); + appendBehavList (mi, M("TP_PCVIGNETTE_FEATHER"), ADDSET_PCVIGNETTE_FEATHER, false); + appendBehavList (mi, M("TP_PCVIGNETTE_ROUNDNESS"), ADDSET_PCVIGNETTE_ROUNDNESS, false); + + mi = behModel->append (); + mi->set_value (behavColumns.label, M("TP_CACORRECTION_LABEL")); + appendBehavList (mi, M("TP_CACORRECTION_BLUE")+", "+M("TP_CACORRECTION_RED"), ADDSET_CA, true); + + mi = behModel->append (); + mi->set_value (behavColumns.label, M("TP_VIGNETTING_LABEL")); + appendBehavList (mi, M("TP_VIGNETTING_AMOUNT"), ADDSET_VIGN_AMOUNT, false); + appendBehavList (mi, M("TP_VIGNETTING_RADIUS"), ADDSET_VIGN_RADIUS, false); + appendBehavList (mi, M("TP_VIGNETTING_STRENGTH"), ADDSET_VIGN_STRENGTH, false); + appendBehavList (mi, M("TP_VIGNETTING_CENTER_X")+", "+M("TP_VIGNETTING_CENTER_Y"), ADDSET_VIGN_CENTER, false); + + mi = behModel->append (); + mi->set_value (behavColumns.label, M("TP_DIRPYREQUALIZER_LABEL")); + appendBehavList (mi, M("TP_EXPOSURE_CONTRAST"), ADDSET_DIRPYREQ, true); + appendBehavList (mi, M("TP_DIRPYREQUALIZER_THRESHOLD"), ADDSET_DIRPYREQ_THRESHOLD, true); + appendBehavList (mi, M("TP_DIRPYREQUALIZER_SKIN"), ADDSET_DIRPYREQ_SKINPROTECT, true); + + 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); + appendBehavList (mi, M("TP_WAVELET_CHR"), ADDSET_WA_CHROMA, true); + appendBehavList (mi, M("TP_WAVELET_SKIN"), ADDSET_WA_SKINPROTECT, true); + appendBehavList (mi, M("TP_WAVELET_EDRAD"), ADDSET_WA_EDGRAD, true); + appendBehavList (mi, M("TP_WAVELET_EDVAL"), ADDSET_WA_EDGVAL, true); + appendBehavList (mi, M("TP_WAVELET_RESCON"), ADDSET_WA_RESCON, true); + appendBehavList (mi, M("TP_WAVELET_THR"), ADDSET_WA_THRR, true); + appendBehavList (mi, M("TP_WAVELET_RESCONH"), ADDSET_WA_RESCONH, true); + appendBehavList (mi, M("TP_WAVELET_THRH"), ADDSET_WA_THRRH, true); + appendBehavList (mi, M("TP_WAVELET_RESCHRO"), ADDSET_WA_RESCHRO, true); + appendBehavList (mi, M("TP_WAVELET_TMSTRENGTH"), ADDSET_WA_TMRS, true); + appendBehavList (mi, M("TP_WAVELET_SKY"), ADDSET_WA_SKYPROTECT, true); + appendBehavList (mi, M("TP_WAVELET_CONTRA"), ADDSET_WA_CONTRAST, true); + appendBehavList (mi, M("TP_WAVELET_STRENGTH"), ADDSET_WA_STRENGTH, true); + appendBehavList (mi, M("TP_WAVELET_COMPGAMMA"), ADDSET_WA_GAMMA, true); + appendBehavList (mi, M("TP_WAVELET_EDGEDETECT"), ADDSET_WA_EDGEDETECT, true); + appendBehavList (mi, M("TP_WAVELET_EDGEDETECTTHR"), ADDSET_WA_EDGEDETECTTHR, true); + appendBehavList (mi, M("TP_WAVELET_EDGEDETECTTHR2"), ADDSET_WA_EDGEDETECTTHR2, true); + + mi = behModel->append (); + mi->set_value (behavColumns.label, M("TP_PREPROCESS_LABEL")); + appendBehavList (mi, M("TP_PREPROCESS_GREENEQUIL"), ADDSET_PREPROCESS_GREENEQUIL, false); + appendBehavList (mi, M("TP_PREPROCESS_LINEDENOISE"), ADDSET_PREPROCESS_LINEDENOISE, true); + + mi = behModel->append (); + mi->set_value (behavColumns.label, M("TP_EXPOS_WHITEPOINT_LABEL")); + appendBehavList (mi, M("TP_RAWEXPOS_LINEAR"), ADDSET_RAWEXPOS_LINEAR, false); + appendBehavList (mi, M("TP_RAWEXPOS_PRESER"), ADDSET_RAWEXPOS_PRESER, false); + + mi = behModel->append (); + mi->set_value (behavColumns.label, M("TP_RAWEXPOS_BLACKS")); + appendBehavList (mi, M("TP_RAWEXPOS_RGB"), ADDSET_RAWEXPOS_BLACKS, false); + + mi = behModel->append (); + mi->set_value (behavColumns.label, M("TP_FLATFIELD_LABEL")); + appendBehavList (mi, M("TP_FLATFIELD_CLIPCONTROL"), ADDSET_RAWFFCLIPCONTROL, true); + + mi = behModel->append (); + mi->set_value (behavColumns.label, M("TP_CHROMATABERR_LABEL")); + appendBehavList (mi, M("TP_RAWCACORR_CARED")+", "+M("TP_RAWCACORR_CABLUE"), ADDSET_RAWCACORR, true); + + behTreeView->expand_all (); + + behAddAll = Gtk::manage( new Gtk::Button (M("PREFERENCES_BEHADDALL")) ); + behSetAll = Gtk::manage( new Gtk::Button (M("PREFERENCES_BEHSETALL")) ); + behAddAll->set_tooltip_markup (M("PREFERENCES_BEHADDALLHINT")); + behSetAll->set_tooltip_markup (M("PREFERENCES_BEHSETALLHINT")); + + behAddAll->signal_clicked().connect( sigc::mem_fun(*this, &Preferences::behAddAllPressed) ); + behSetAll->signal_clicked().connect( sigc::mem_fun(*this, &Preferences::behSetAllPressed) ); + + Gtk::HBox* buttonpanel1 = Gtk::manage (new Gtk::HBox ()); + //buttonpanel1->set_spacing(8); + buttonpanel1->pack_end (*behSetAll, Gtk::PACK_SHRINK, 4); + buttonpanel1->pack_end (*behAddAll, Gtk::PACK_SHRINK, 4); + vbbeh->pack_start (*buttonpanel1, Gtk::PACK_SHRINK, 4); + + chOverwriteOutputFile = Gtk::manage( new Gtk::CheckButton (M("PREFERENCES_OVERWRITEOUTPUTFILE")) ); + mvbpp->pack_start(*chOverwriteOutputFile, Gtk::PACK_SHRINK, 4); + + return mvbpp; +} + +void Preferences::appendBehavList (Gtk::TreeModel::iterator& parent, Glib::ustring label, int id, bool set) { + + Gtk::TreeModel::iterator ci = behModel->append (parent->children()); + ci->set_value (behavColumns.label, label); + ci->set_value (behavColumns.visible, true); + ci->set_value (behavColumns.badd, !set); + ci->set_value (behavColumns.bset, set); + ci->set_value (behavColumns.addsetid, id); +} + +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); +} + +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); +} + +Gtk::Widget* Preferences::getProcParamsPanel () { + + Gtk::VBox* mvbpp = Gtk::manage (new Gtk::VBox ()); + + Gtk::Frame* fpp = Gtk::manage (new Gtk::Frame (M("PREFERENCES_IMPROCPARAMS"))); + Gtk::VBox* vbpp = Gtk::manage (new Gtk::VBox ()); + vbpp->set_border_width(4); + Gtk::Label* drlab = Gtk::manage (new Gtk::Label (M("PREFERENCES_FORRAW")+":", Gtk::ALIGN_LEFT)); + rprofiles = Gtk::manage (new ProfileStoreComboBox ()); + rprofiles->set_size_request(50, -1); + rpconn = rprofiles->signal_changed().connect( sigc::mem_fun(*this, &Preferences::forRAWComboChanged) ); + Gtk::Label* drimg = Gtk::manage (new Gtk::Label (M("PREFERENCES_FORIMAGE")+":", Gtk::ALIGN_LEFT)); + iprofiles = Gtk::manage (new ProfileStoreComboBox ()); + iprofiles->set_size_request(50, -1); + ipconn = iprofiles->signal_changed().connect( sigc::mem_fun(*this, &Preferences::forImageComboChanged) ); + Gtk::Table* defpt = Gtk::manage (new Gtk::Table (2, 2)); + defpt->attach (*drlab, 0, 1, 0, 1, Gtk::FILL, Gtk::SHRINK, 2, 2); + defpt->attach (*rprofiles, 1, 2, 0, 1, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); + defpt->attach (*drimg, 0, 1, 1, 2, Gtk::FILL, Gtk::SHRINK, 2, 2); + defpt->attach (*iprofiles, 1, 2, 1, 2, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); + vbpp->pack_start (*defpt, Gtk::PACK_SHRINK, 4); + useBundledProfiles = Gtk::manage (new Gtk::CheckButton (M("PREFERENCES_USEBUNDLEDPROFILES"))); + bpconn = useBundledProfiles->signal_clicked().connect ( sigc::mem_fun(*this, &Preferences::bundledProfilesChanged) ); + vbpp->pack_start (*useBundledProfiles, Gtk::PACK_SHRINK, 4); + fpp->add (*vbpp); + mvbpp->pack_start (*fpp, Gtk::PACK_SHRINK, 4); + + // Custom profile builder box + Gtk::Frame* cpfrm = Gtk::manage( new Gtk::Frame (M("PREFERENCES_CUSTPROFBUILD")) ); + Gtk::Label* cplab = Gtk::manage( new Gtk::Label (M("PREFERENCES_CUSTPROFBUILDPATH")+":", Gtk::ALIGN_LEFT) ); + txtCustProfBuilderPath = Gtk::manage( new Gtk::Entry () ); + txtCustProfBuilderPath->set_tooltip_markup (M("PREFERENCES_CUSTPROFBUILDHINT")); + Gtk::Label* cpltypelab = Gtk::manage( new Gtk::Label (M("PREFERENCES_CUSTPROFBUILDKEYFORMAT")+":", Gtk::ALIGN_LEFT) ); + custProfBuilderLabelType = Gtk::manage (new Gtk::ComboBoxText ()); + custProfBuilderLabelType->append_text (M("PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID")); + custProfBuilderLabelType->append_text (M("PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME")); + custProfBuilderLabelType->append_text (M("PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID") + "_" + M("PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME")); + Gtk::Table* cpbt = Gtk::manage (new Gtk::Table (2, 2)); + cpbt->set_border_width(4); + cpbt->attach (*cplab, 0, 1, 0, 1, Gtk::FILL, Gtk::SHRINK, 2, 2); + cpbt->attach (*txtCustProfBuilderPath, 1, 2, 0, 1, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); + cpbt->attach (*cpltypelab, 0, 1, 1, 2, Gtk::FILL, Gtk::SHRINK, 2, 2); + cpbt->attach (*custProfBuilderLabelType, 1, 2, 1, 2, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); + cpfrm->add (*cpbt); + mvbpp->pack_start (*cpfrm, Gtk::PACK_SHRINK, 4); + + Gtk::Frame* fdp = Gtk::manage (new Gtk::Frame (M("PREFERENCES_PROFILEHANDLING"))); + Gtk::VBox* vbdp = Gtk::manage (new Gtk::VBox ()); + vbdp->set_border_width (4); + saveParamsFile = Gtk::manage (new Gtk::CheckButton (M("PREFERENCES_PROFILESAVEINPUT"))); + vbdp->pack_start (*saveParamsFile, Gtk::PACK_SHRINK, 4); + saveParamsCache = Gtk::manage (new Gtk::CheckButton (M("PREFERENCES_PROFILESAVECACHE"))); + vbdp->pack_start (*saveParamsCache, Gtk::PACK_SHRINK, 4); + Gtk::Label* lplab = Gtk::manage (new Gtk::Label (M("PREFERENCES_PROFILELOADPR")+":")); + loadParamsPreference = Gtk::manage (new Gtk::ComboBoxText ()); + loadParamsPreference->append_text (M("PREFERENCES_PROFILEPRCACHE")); + loadParamsPreference->append_text (M("PREFERENCES_PROFILEPRFILE")); + Gtk::HBox* hb41 = Gtk::manage (new Gtk::HBox ()); + hb41->pack_start (*lplab, Gtk::PACK_SHRINK, 0); + hb41->pack_start (*loadParamsPreference, Gtk::PACK_EXPAND_WIDGET, 0); + hb41->set_spacing(4); + vbdp->pack_start (*hb41, Gtk::PACK_EXPAND_WIDGET, 4); + 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)); + 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); + 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); + mvbpp->set_border_width (4); + + //dfconn = darkFrameDir->signal_file_set().connect ( sigc::mem_fun(*this, &Preferences::darkFrameChanged), true); + dfconn = darkFrameDir->signal_current_folder_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); + 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); + mvbpp->set_border_width (4); + + //ffconn = flatFieldDir->signal_file_set().connect ( sigc::mem_fun(*this, &Preferences::flatFieldChanged), true); + ffconn = flatFieldDir->signal_current_folder_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") + ":")); + 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 ); + clutsDirBox->set_border_width( 4 ); + clutsDirFrame->add( *clutsDirBox ); + mvbpp->pack_start( *clutsDirFrame, Gtk::PACK_SHRINK, 4 ); + + 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"))); + vbmd->pack_start (*ckbTunnelMetaData, Gtk::PACK_SHRINK, 4); + fmd->add (*vbmd); + mvbpp->pack_start (*fmd, Gtk::PACK_SHRINK, 4); + + return mvbpp; +} + +Gtk::Widget* Preferences::getPerformancePanel () { + Gtk::VBox* mainContainer = Gtk::manage( new Gtk::VBox () ); + mainContainer->set_border_width (4); + mainContainer->set_spacing(4); + + Gtk::Frame* fprevdemo = Gtk::manage (new Gtk::Frame (M("PREFERENCES_PREVDEMO"))); + Gtk::HBox* hbprevdemo = Gtk::manage (new Gtk::HBox (false, 4)); + Gtk::Label* lprevdemo = Gtk::manage (new Gtk::Label (M("PREFERENCES_PREVDEMO_LABEL"))); + cprevdemo = Gtk::manage (new Gtk::ComboBoxText ()); + cprevdemo->append_text (M("PREFERENCES_PREVDEMO_FAST")); + cprevdemo->append_text (M("PREFERENCES_PREVDEMO_SIDECAR")); + cprevdemo->set_active (1); + hbprevdemo->pack_start (*lprevdemo, Gtk::PACK_SHRINK); + hbprevdemo->pack_start (*cprevdemo); + fprevdemo->add (*hbprevdemo); + hbprevdemo->set_border_width(4); + mainContainer->pack_start (*fprevdemo, Gtk::PACK_SHRINK, 4); + + Gtk::Frame* ftiffserialize = Gtk::manage (new Gtk::Frame (M("PREFERENCES_SERIALIZE_TIFF_READ"))); + Gtk::HBox* htiffserialize = Gtk::manage (new Gtk::HBox (false, 4)); + ctiffserialize = Gtk::manage( new Gtk::CheckButton (M("PREFERENCES_SERIALIZE_TIFF_READ_LABEL")) ); + ctiffserialize->set_tooltip_text(M("PREFERENCES_SERIALIZE_TIFF_READ_TOOLTIP")); + htiffserialize->pack_start (*ctiffserialize); + ftiffserialize->add (*htiffserialize); + htiffserialize->set_border_width(4); + mainContainer->pack_start (*ftiffserialize, Gtk::PACK_SHRINK, 4); + + Gtk::Frame* fclut = Gtk::manage( new Gtk::Frame (M("PREFERENCES_CLUTSCACHE")) ); + Gtk::HBox* clutCacheSizeHB = Gtk::manage( new Gtk::HBox () ); + clutCacheSizeHB->set_border_width(4); + clutCacheSizeHB->set_spacing(4); + Gtk::Label* CLUTLl = Gtk::manage( new Gtk::Label (M("PREFERENCES_CLUTSCACHE_LABEL") + ":", Gtk::ALIGN_LEFT)); + clutCacheSizeSB = Gtk::manage( new Gtk::SpinButton () ); + clutCacheSizeSB->set_digits (0); + clutCacheSizeSB->set_increments (1, 5); + clutCacheSizeSB->set_max_length(2); // Will this be sufficient? :) +#ifdef _OPENMP + clutCacheSizeSB->set_range (1, 2*omp_get_num_procs()); +#else + clutCacheSizeSB->set_range (1, 8); +#endif + clutCacheSizeHB->pack_start (*CLUTLl, Gtk::PACK_SHRINK, 0); + clutCacheSizeHB->pack_end (*clutCacheSizeSB, Gtk::PACK_SHRINK, 0); + fclut->add (*clutCacheSizeHB); + mainContainer->pack_start (*fclut, Gtk::PACK_SHRINK, 4); + + Gtk::Frame* finspect = Gtk::manage( new Gtk::Frame (M("PREFERENCES_INSPECT_LABEL")) ); + Gtk::HBox* maxIBuffersHB = Gtk::manage( new Gtk::HBox () ); + maxIBuffersHB->set_border_width(4); + maxIBuffersHB->set_spacing(4); + maxIBuffersHB->set_tooltip_text(M("PREFERENCES_INSPECT_MAXBUFFERS_TOOLTIP")); + Gtk::Label* maxIBufferLbl = Gtk::manage( new Gtk::Label (M("PREFERENCES_INSPECT_MAXBUFFERS_LABEL") + ":", Gtk::ALIGN_LEFT)); + maxInspectorBuffersSB = Gtk::manage( new Gtk::SpinButton () ); + maxInspectorBuffersSB->set_digits (0); + maxInspectorBuffersSB->set_increments (1, 5); + maxInspectorBuffersSB->set_max_length(2); + maxInspectorBuffersSB->set_range (1, 12); // ... we have to set a limit, 12 seem to be enough even for systems with tons of RAM + maxIBuffersHB->pack_start (*maxIBufferLbl, Gtk::PACK_SHRINK, 0); + maxIBuffersHB->pack_end (*maxInspectorBuffersSB, Gtk::PACK_SHRINK, 0); + finspect->add(*maxIBuffersHB); + mainContainer->pack_start(*finspect, Gtk::PACK_SHRINK, 4); + + Gtk::Frame* fdenoise = Gtk::manage( new Gtk::Frame (M("PREFERENCES_NOISE")) ); + Gtk::VBox* vbdenoise = Gtk::manage( new Gtk::VBox (Gtk::PACK_SHRINK, 4) ); + vbdenoise->set_border_width (4); + + Gtk::Label* lreloadneeded2 = Gtk::manage (new Gtk::Label (M("PREFERENCES_IMG_RELOAD_NEEDED"), Gtk::ALIGN_LEFT)); + Gtk::HBox* threadLimitHB = Gtk::manage (new Gtk::HBox (Gtk::PACK_SHRINK, 4)); + threadLimitHB->set_tooltip_text(M("PREFERENCES_RGBDTL_TOOLTIP")); + Gtk::Label* RGBDTLl = Gtk::manage( new Gtk::Label (M("PREFERENCES_RGBDTL_LABEL") + ":", Gtk::ALIGN_LEFT)); + rgbDenoiseTreadLimitSB = Gtk::manage( new Gtk::SpinButton () ); + rgbDenoiseTreadLimitSB->set_digits (0); + rgbDenoiseTreadLimitSB->set_increments (1, 5); + rgbDenoiseTreadLimitSB->set_max_length(2); // Will this be sufficient? :) + int maxThreadNumber = 10; +#ifdef _OPENMP + maxThreadNumber = omp_get_max_threads(); +#endif + rgbDenoiseTreadLimitSB->set_range (0, maxThreadNumber); + threadLimitHB->pack_start (*RGBDTLl, Gtk::PACK_SHRINK, 2); + threadLimitHB->pack_end (*rgbDenoiseTreadLimitSB, Gtk::PACK_SHRINK, 2); + + Gtk::Label* dnlab = Gtk::manage (new Gtk::Label (M("PREFERENCES_LEVDN")+":", Gtk::ALIGN_LEFT)); + Gtk::Label* dnautlab = Gtk::manage (new Gtk::Label (M("PREFERENCES_LEVAUTDN")+":", Gtk::ALIGN_LEFT)); + Gtk::Label* dnautsimpllab = Gtk::manage (new Gtk::Label (M("PREFERENCES_SIMPLAUT")+":", Gtk::ALIGN_LEFT)); + Gtk::Label* dntilab = Gtk::manage (new Gtk::Label (M("PREFERENCES_TINB")+":", Gtk::ALIGN_LEFT)); + Gtk::Label* dnwavlab = Gtk::manage (new Gtk::Label (M("PREFERENCES_WAVLEV")+":", Gtk::ALIGN_LEFT)); + Gtk::Label* dnlisslab = Gtk::manage (new Gtk::Label (M("PREFERENCES_LISS")+":", Gtk::ALIGN_LEFT)); + + dnv = Gtk::manage (new Gtk::ComboBoxText ()); + dnv->append_text (M("PREFERENCES_MIN")); + dnv->append_text (M("PREFERENCES_SMA")); + dnv->append_text (M("PREFERENCES_MED")); + dnv->append_text (M("PREFERENCES_MAX")); + dnaut = Gtk::manage (new Gtk::ComboBoxText ()); + dnaut->append_text (M("PREFERENCES_AUTLOW")); + dnaut->append_text (M("PREFERENCES_AUTSTD")); + + dnautsimpl = Gtk::manage (new Gtk::ComboBoxText ()); + dnautsimpl->append_text (M("PREFERENCES_STDAUT")); + dnautsimpl->append_text (M("PREFERENCES_EXPAUT")); + + dnliss = Gtk::manage (new Gtk::ComboBoxText ()); + dnliss->append_text (M("PREFERENCES_AUTLISVLOW"));//very low + dnliss->append_text (M("PREFERENCES_AUTLISLOW"));//low + dnliss->append_text (M("PREFERENCES_AUTLISSTD"));//med + dnliss->append_text (M("PREFERENCES_AUTLISMAX"));//max + + dnti = Gtk::manage (new Gtk::ComboBoxText ()); + dnti->append_text (M("PREFERENCES_TISTD")); + dnti->append_text (M("PREFERENCES_TIMAX")); + + dnwavlev = Gtk::manage (new Gtk::ComboBoxText ()); + dnwavlev->append_text (M("PREFERENCES_WLZER")); + dnwavlev->append_text (M("PREFERENCES_WLONE")); + dnwavlev->append_text (M("PREFERENCES_WLTWO")); + + Gtk::Table* colon = Gtk::manage (new Gtk::Table (6, 2)); + colon->attach (*dnlab, 0, 1, 0, 1, Gtk::FILL, Gtk::SHRINK, 2, 2); + colon->attach (*dnv, 1, 2, 0, 1, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); + colon->attach (*dnautlab, 0, 1, 1, 2, Gtk::FILL, Gtk::SHRINK, 2, 2); + colon->attach (*dnaut, 1, 2, 1, 2, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); + colon->attach (*dnautsimpllab, 0, 1, 2, 3, Gtk::FILL, Gtk::SHRINK, 2, 2); + colon->attach (*dnautsimpl, 1, 2, 2, 3, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); + colon->attach (*dnlisslab, 0, 1, 3, 4, Gtk::FILL, Gtk::SHRINK, 2, 2); + colon->attach (*dnliss, 1, 2, 3, 4, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); + colon->attach (*dntilab, 0, 1, 4, 5, Gtk::FILL, Gtk::SHRINK, 2, 2); + colon->attach (*dnti, 1, 2, 4, 5, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); + colon->attach (*dnwavlab, 0, 1, 5, 6, Gtk::FILL, Gtk::SHRINK, 2, 2); + colon->attach (*dnwavlev, 1, 2, 5, 6, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); + + vbdenoise->pack_start (*lreloadneeded2, Gtk::PACK_SHRINK); + vbdenoise->pack_start (*colon, Gtk::PACK_SHRINK); + vbdenoise->pack_start(*threadLimitHB, Gtk::PACK_SHRINK); + // <--- To be hard-coded and removed once tested + cbdaubech = Gtk::manage (new Gtk::CheckButton (M("PREFERENCES_DAUB_LABEL"), Gtk::ALIGN_LEFT)); + cbdaubech->set_tooltip_markup (M("PREFERENCES_DAUB_TOOLTIP")); + // vbdenoise->pack_start (*cbdaubech, Gtk::PACK_SHRINK); + // ---> + fdenoise->add (*vbdenoise); + mainContainer->pack_start (*fdenoise, Gtk::PACK_SHRINK, 4); + + return mainContainer; +} + +Gtk::Widget* Preferences::getColorManagementPanel () { + + Gtk::VBox* mvbcm = Gtk::manage (new Gtk::VBox ()); + mvbcm->set_border_width (4); + + Gtk::Label* intlab = Gtk::manage (new Gtk::Label (M("PREFERENCES_CMETRICINTENT")+":", Gtk::ALIGN_LEFT)); + intent = Gtk::manage (new Gtk::ComboBoxText ()); + intent->append_text (M("PREFERENCES_INTENT_PERCEPTUAL")); + intent->append_text (M("PREFERENCES_INTENT_RELATIVE")); + intent->append_text (M("PREFERENCES_INTENT_SATURATION")); + intent->append_text (M("PREFERENCES_INTENT_ABSOLUTE")); + + iccDir = Gtk::manage (new Gtk::FileChooserButton (M("PREFERENCES_ICCDIR"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); + Gtk::Label* pdlabel = Gtk::manage (new Gtk::Label (M("PREFERENCES_ICCDIR")+":", Gtk::ALIGN_LEFT)); + + Gtk::FileFilter monProfileFilter_colprof; + monProfileFilter_colprof.set_name(M("FILECHOOSER_FILTER_COLPROF")); + monProfileFilter_colprof.add_pattern("*.icc"); + monProfileFilter_colprof.add_pattern("*.ICC"); + monProfileFilter_colprof.add_pattern("*.icm"); + monProfileFilter_colprof.add_pattern("*.ICM"); + Gtk::FileFilter monProfileFilter_any; + monProfileFilter_any.set_name(M("FILECHOOSER_FILTER_ANY")); + monProfileFilter_any.add_pattern("*"); + + monProfile = Gtk::manage (new Gtk::FileChooserButton (M("PREFERENCES_MONITORICC"), Gtk::FILE_CHOOSER_ACTION_OPEN)); + monProfile->add_filter (monProfileFilter_colprof); + monProfile->add_filter (monProfileFilter_any); + Gtk::Label* mplabel = Gtk::manage (new Gtk::Label (M("PREFERENCES_MONITORICC")+":", Gtk::ALIGN_LEFT)); + +#if defined(WIN32) // Auto-detection not implemented for Linux, see issue 851 + cbAutoMonProfile = Gtk::manage (new Gtk::CheckButton (M("PREFERENCES_AUTOMONPROFILE"))); + autoMonProfileConn = cbAutoMonProfile->signal_toggled().connect (sigc::mem_fun(*this, &Preferences::autoMonProfileToggled)); +#endif + + Gtk::Table* colt = Gtk::manage (new Gtk::Table (3, 2)); + colt->attach (*intlab, 0, 1, 0, 1, Gtk::FILL, Gtk::SHRINK, 2, 2); + colt->attach (*intent, 1, 2, 0, 1, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); + colt->attach (*pdlabel, 0, 1, 1, 2, Gtk::FILL, Gtk::SHRINK, 2, 2); + colt->attach (*iccDir, 1, 2, 1, 2, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); +#if !defined(__APPLE__) // monitor profile not supported on apple + colt->attach (*mplabel, 0, 1, 2, 3, Gtk::FILL, Gtk::SHRINK, 2, 2); + colt->attach (*monProfile, 1, 2, 2, 3, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); +#if defined(WIN32) + colt->attach (*cbAutoMonProfile, 1, 2, 3, 4, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); +#endif +#endif + mvbcm->pack_start (*colt, Gtk::PACK_SHRINK, 4); + +#if defined(WIN32) + autoMonProfileToggled(); +#endif + + Gtk::VBox* vbdp = Gtk::manage (new Gtk::VBox ()); + vbdp->set_border_width (4); + Gtk::Label* viewlab = Gtk::manage (new Gtk::Label (M("PREFERENCES_VIEW")+":", Gtk::ALIGN_LEFT)); + + view = Gtk::manage (new Gtk::ComboBoxText ()); + view->append_text (M("PREFERENCES_D50")); + view->append_text (M("PREFERENCES_D55")); + view->append_text (M("PREFERENCES_D60")); + view->append_text (M("PREFERENCES_D65")); + view->append_text (M("PREFERENCES_BLACKBODY")); + view->append_text (M("PREFERENCES_FLUOF2")); + view->append_text (M("PREFERENCES_FLUOF7")); + view->append_text (M("PREFERENCES_FLUOF11")); + + Gtk::Label* greylab = Gtk::manage (new Gtk::Label (M("PREFERENCES_GREY")+":", Gtk::ALIGN_LEFT)); + grey = Gtk::manage (new Gtk::ComboBoxText ()); + grey->append_text (M("PREFERENCES_GREY05")); + grey->append_text (M("PREFERENCES_GREY10")); + grey->append_text (M("PREFERENCES_GREY15")); + grey->append_text (M("PREFERENCES_GREY18")); + grey->append_text (M("PREFERENCES_GREY23")); + grey->append_text (M("PREFERENCES_GREY30")); + grey->append_text (M("PREFERENCES_GREY40")); + + Gtk::Label* greySclab = Gtk::manage (new Gtk::Label (M("PREFERENCES_GREYSC")+":", Gtk::ALIGN_LEFT)); + greySc = Gtk::manage (new Gtk::ComboBoxText ()); + greySc->append_text (M("PREFERENCES_GREYSCA")); + greySc->append_text (M("PREFERENCES_GREYSC18")); + + Gtk::Frame* fcielab = Gtk::manage( new Gtk::Frame (M("PREFERENCES_CIEART_FRAME")) ); + Gtk::VBox* vbcielab = Gtk::manage( new Gtk::VBox () ); + vbcielab->set_border_width (4); + + Gtk::Label* lreloadneeded1 = Gtk::manage (new Gtk::Label (M("PREFERENCES_IMG_RELOAD_NEEDED"), Gtk::ALIGN_LEFT)); + Gtk::Table* colo = Gtk::manage (new Gtk::Table (4, 2)); + colo->attach (*viewlab, 0, 1, 0, 1, Gtk::FILL, Gtk::SHRINK, 2, 2); + colo->attach (*view, 1, 2, 0, 1, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); + colo->attach (*greylab, 0, 1, 1, 2, Gtk::FILL, Gtk::SHRINK, 2, 2); + colo->attach (*grey, 1, 2, 1, 2, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); + colo->attach (*greySclab, 0, 1, 2, 3, Gtk::FILL, Gtk::SHRINK, 2, 2); + colo->attach (*greySc, 1, 2, 2, 3, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); + cbciecamfloat = Gtk::manage (new Gtk::CheckButton (M("PREFERENCES_CIEART_LABEL"))); + colo->attach (*cbciecamfloat, 0, 1, 3, 4, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2); + cbciecamfloat->set_tooltip_markup (M("PREFERENCES_CIEART_TOOLTIP")); + vbcielab->pack_start (*lreloadneeded1, Gtk::PACK_SHRINK, 4); + vbcielab->pack_start (*colo, Gtk::PACK_EXPAND_WIDGET, 4); + fcielab->add (*vbcielab); + + mvbcm->pack_start (*fcielab, Gtk::PACK_SHRINK, 4); + + return mvbcm; +} + +Gtk::Widget* Preferences::getGeneralPanel () { + + Gtk::VBox* mvbsd = Gtk::manage( new Gtk::VBox () ); + + Gtk::Frame* fworklflow = Gtk::manage (new Gtk::Frame (M("PREFERENCES_WORKFLOW"))); + Gtk::VBox* vbworkflow = Gtk::manage (new Gtk::VBox (false, 4)); + vbworkflow->set_border_width (4); + + Gtk::HBox* hbworkflow = Gtk::manage (new Gtk::HBox (false, 4)); + Gtk::Label* flayoutlab = Gtk::manage (new Gtk::Label (M("PREFERENCES_EDITORLAYOUT")+":")); + editorLayout = Gtk::manage (new Gtk::ComboBoxText ()); + editorLayout->append_text (M("PREFERENCES_SINGLETAB")); + editorLayout->append_text (M("PREFERENCES_SINGLETABVERTAB")); + editorLayout->append_text (M("PREFERENCES_MULTITAB")); + editorLayout->append_text (M("PREFERENCES_MULTITABDUALMON")); + editorLayout->set_active (2); + editorLayout->signal_changed().connect (sigc::mem_fun(*this, &Preferences::layoutComboChanged)); + layoutComboChanged(); // update the tooltip + hbworkflow->pack_start (*flayoutlab, Gtk::PACK_SHRINK); + hbworkflow->pack_start (*editorLayout); + Gtk::Label* lNextStart = Gtk::manage( new Gtk::Label (Glib::ustring("(") + M("PREFERENCES_APPLNEXTSTARTUP") + ")") ); + hbworkflow->pack_end (*lNextStart, Gtk::PACK_SHRINK); + vbworkflow->pack_start (*hbworkflow, Gtk::PACK_SHRINK); + + Gtk::HBox* curveBBoxPosHB = Gtk::manage (new Gtk::HBox (false, 4)); + Gtk::Label* curveBBoxPosL = Gtk::manage (new Gtk::Label (M("PREFERENCES_CURVEBBOXPOS")+":")); + Gtk::Label* curveBBoxPosRestartL = Gtk::manage (new Gtk::Label (Glib::ustring("(") + M("PREFERENCES_APPLNEXTSTARTUP") + ")")); + curveBBoxPosC = Gtk::manage (new Gtk::ComboBoxText ()); + curveBBoxPosC->append_text (M("PREFERENCES_CURVEBBOXPOS_ABOVE")); + curveBBoxPosC->append_text (M("PREFERENCES_CURVEBBOXPOS_RIGHT")); + curveBBoxPosC->append_text (M("PREFERENCES_CURVEBBOXPOS_BELOW")); + curveBBoxPosC->append_text (M("PREFERENCES_CURVEBBOXPOS_LEFT")); + curveBBoxPosC->set_active (1); + curveBBoxPosHB->pack_start (*curveBBoxPosL, Gtk::PACK_SHRINK); + curveBBoxPosHB->pack_start (*curveBBoxPosC); + curveBBoxPosHB->pack_start (*curveBBoxPosRestartL, Gtk::PACK_SHRINK); + vbworkflow->pack_start (*curveBBoxPosHB, Gtk::PACK_SHRINK); + + Gtk::HBox* hbworkflow2 = Gtk::manage( new Gtk::HBox () ); + ckbHistogramPositionLeft = Gtk::manage( new Gtk::CheckButton (M("PREFERENCES_HISTOGRAMPOSITIONLEFT")) ); + hbworkflow2->pack_start (*ckbHistogramPositionLeft); + ckbHistogramWorking = Gtk::manage( new Gtk::CheckButton (M("PREFERENCES_HISTOGRAMWORKING")) ); + ckbHistogramWorking->set_tooltip_markup (M("PREFERENCES_HISTOGRAM_TOOLTIP")); + hbworkflow2->pack_start (*ckbHistogramWorking); + vbworkflow->pack_start (*hbworkflow2, Gtk::PACK_SHRINK); + + Gtk::HBox* hbworkflow3 = Gtk::manage( new Gtk::HBox () ); + ckbFileBrowserToolbarSingleRow = Gtk::manage( new Gtk::CheckButton (M("PREFERENCES_FILEBROWSERTOOLBARSINGLEROW")) ); + ckbShowFilmStripToolBar = Gtk::manage( new Gtk::CheckButton (M("PREFERENCES_SHOWFILMSTRIPTOOLBAR")) ); + hbworkflow3->pack_start (*ckbFileBrowserToolbarSingleRow); + hbworkflow3->pack_start (*ckbShowFilmStripToolBar); + vbworkflow->pack_start (*hbworkflow3, Gtk::PACK_SHRINK); + + Gtk::HBox* hbworkflow4 = Gtk::manage( new Gtk::HBox (false, 4) ); + Gtk::Label* hb4label = Gtk::manage( new Gtk::Label (M("PREFERENCES_TP_LABEL")) ); + hbworkflow4->pack_start (*hb4label, Gtk::PACK_SHRINK); + ckbHideTPVScrollbar = Gtk::manage( new Gtk::CheckButton (M("PREFERENCES_TP_VSCROLLBAR")) ); + hbworkflow4->pack_start (*ckbHideTPVScrollbar, Gtk::PACK_SHRINK); + ckbUseIconNoText = Gtk::manage( new Gtk::CheckButton (M("PREFERENCES_TP_USEICONORTEXT")) ); + hbworkflow4->pack_start (*ckbUseIconNoText, Gtk::PACK_SHRINK); + vbworkflow->pack_start (*hbworkflow4, Gtk::PACK_SHRINK); + + fworklflow->add (*vbworkflow); + mvbsd->pack_start (*fworklflow, Gtk::PACK_SHRINK); + + Gtk::Frame* flang = Gtk::manage( new Gtk::Frame (M("PREFERENCES_DEFAULTLANG")) ); + Gtk::HBox* hblang = Gtk::manage( new Gtk::HBox () ); + hblang->set_border_width (4); + + ckbLangAutoDetect = Gtk::manage( new Gtk::CheckButton (M("PREFERENCES_LANGAUTODETECT")) ); + + Gtk::Label* langlab = Gtk::manage( new Gtk::Label (M("PREFERENCES_SELECTLANG")+":") ); + languages = Gtk::manage( new Gtk::ComboBoxText () ); + + std::vector langs; + parseDir (argv0 + "/languages", langs, ""); + for (size_t i=0; iappend_text (langs[i]); + } + } + + Gtk::Label* langw = Gtk::manage( new Gtk::Label (Glib::ustring(" (") + M("PREFERENCES_APPLNEXTSTARTUP") + ")") ); + hblang->pack_start (*ckbLangAutoDetect, Gtk::PACK_SHRINK, 4); + hblang->pack_start (*langlab, Gtk::PACK_SHRINK, 8); + hblang->pack_start (*languages); + hblang->pack_end (*langw, Gtk::PACK_SHRINK, 4); + flang->add (*hblang); + mvbsd->pack_start (*flang, Gtk::PACK_SHRINK, 4); + + langAutoDetectConn = ckbLangAutoDetect->signal_toggled().connect (sigc::mem_fun(*this, &Preferences::langAutoDetectToggled)); + + Gtk::Frame* ftheme = Gtk::manage( new Gtk::Frame (M("PREFERENCES_DEFAULTTHEME")) ); + Gtk::VBox* vbftheme = Gtk::manage( new Gtk::VBox () ); + vbftheme->set_border_width(4); + vbftheme->set_spacing(4); + Gtk::HBox* hbUseSystemTheme = Gtk::manage( new Gtk::HBox () ); + hbUseSystemTheme->set_spacing(4); + chUseSystemTheme = Gtk::manage( new Gtk::CheckButton (M("PREFERENCES_USESYSTEMTHEME")) ); + Gtk::Label* useNextStart = Gtk::manage( new Gtk::Label (Glib::ustring("(") + M("PREFERENCES_APPLNEXTSTARTUP") + ")") ); + + Gtk::Label* cutOverlayLabel = Gtk::manage( new Gtk::Label (M("PREFERENCES_CUTOVERLAYBRUSH") + ":") ); + butCropCol= Gtk::manage( new Gtk::ColorButton() ); + butCropCol->set_use_alpha(true); + + Gtk::Label* navGuideLabel = Gtk::manage( new Gtk::Label (M("PREFERENCES_NAVGUIDEBRUSH") + ":") ); + butNavGuideCol= Gtk::manage( new Gtk::ColorButton() ); + butNavGuideCol->set_use_alpha(true); + + slimUI = Gtk::manage( new Gtk::CheckButton (M("PREFERENCES_SLIMUI")) ); + hbUseSystemTheme->pack_start(*chUseSystemTheme, Gtk::PACK_SHRINK); + hbUseSystemTheme->pack_start (*useNextStart, Gtk::PACK_SHRINK, 0); + hbUseSystemTheme->pack_end(*slimUI, Gtk::PACK_SHRINK, 0); + vbftheme->pack_start(*hbUseSystemTheme, Gtk::PACK_SHRINK, 0); + + + hbtheme = Gtk::manage( new Gtk::HBox () ); + hbtheme->set_spacing (4); + Gtk::Label* themelab = Gtk::manage( new Gtk::Label (M("PREFERENCES_SELECTTHEME")+":") ); + theme = Gtk::manage( new Gtk::ComboBoxText () ); + + theme->set_active (0); + std::vector themes; + parseDir (argv0 + "/themes", themes, ".gtkrc"); + for (size_t i=0; iappend_text (themes[i]); + + Gtk::Label* fontlab = Gtk::manage( new Gtk::Label (M("PREFERENCES_SELECTFONT")+":") ); + fontbutton = Gtk::manage( new Gtk::FontButton ()); + fontbutton->set_use_size(true); + fontbutton->set_font_name(options.font); + + hbtheme->pack_start (*themelab, Gtk::PACK_SHRINK, 0); + hbtheme->pack_start (*theme); + hbtheme->pack_start (*fontlab, Gtk::PACK_SHRINK, 0); + hbtheme->pack_start (*fontbutton); + vbftheme->pack_start(*hbtheme, Gtk::PACK_SHRINK, 0); + + + Gtk::HBox* hbcolorchooser = Gtk::manage( new Gtk::HBox () ); + hbcolorchooser->set_spacing(4); + + hbcolorchooser->pack_start (*cutOverlayLabel, Gtk::PACK_SHRINK, 0); + hbcolorchooser->pack_start (*butCropCol, Gtk::PACK_SHRINK, 0); + hbcolorchooser->pack_end (*butNavGuideCol, Gtk::PACK_SHRINK, 0); + hbcolorchooser->pack_end (*navGuideLabel, Gtk::PACK_SHRINK, 0); + vbftheme->pack_start(*hbcolorchooser, Gtk::PACK_SHRINK, 0); + + + ftheme->add (*vbftheme); + mvbsd->pack_start (*ftheme, Gtk::PACK_SHRINK, 0); + +//----- + + Gtk::HBox* hbcd = Gtk::manage( new Gtk::HBox (true) ); + hbcd->set_spacing(4); + + Gtk::Frame* frl = Gtk::manage( new Gtk::Frame (M("PREFERENCES_CLIPPINGIND"))); + Gtk::VBox* vbrl = Gtk::manage( new Gtk::VBox () ); + vbrl->set_border_width(4); + vbrl->set_spacing (4); + + Gtk::HBox* vbhl = Gtk::manage( new Gtk::HBox () ); + vbhl->set_spacing(4); + Gtk::Label* hll = Gtk::manage( new Gtk::Label (M("PREFERENCES_HLTHRESHOLD")+": ")); + hlThresh = Gtk::manage( new Gtk::SpinButton () ); + hlThresh->set_digits (0); + hlThresh->set_increments (1, 10); + hlThresh->set_range (0, 255); + vbhl->pack_start (*hll, Gtk::PACK_SHRINK, 0); + vbhl->pack_end (*hlThresh, Gtk::PACK_SHRINK, 0); + + vbrl->pack_start (*vbhl, Gtk::PACK_SHRINK, 0); + + Gtk::HBox* vbsh = Gtk::manage( new Gtk::HBox () ); + vbsh->set_spacing (4); + Gtk::Label* shl = Gtk::manage( new Gtk::Label (M("PREFERENCES_SHTHRESHOLD")+": ") ); + shThresh = Gtk::manage( new Gtk::SpinButton () ); + shThresh->show (); + shThresh->set_digits (0); + shThresh->set_increments (1, 10); + shThresh->set_range (0, 255); + vbsh->pack_start (*shl, Gtk::PACK_SHRINK, 0); + vbsh->pack_end (*shThresh, Gtk::PACK_SHRINK, 0); + vbrl->pack_start (*vbsh, Gtk::PACK_SHRINK, 0); + + frl->add (*vbrl); + hbcd->pack_start (*frl, true, true, 0); + + //--- + + Gtk::Frame* navigationFrame = Gtk::manage( new Gtk::Frame (M("PREFERENCES_NAVIGATIONFRAME")) ); + Gtk::VBox* navigationVBox = Gtk::manage( new Gtk::VBox () ); + navigationVBox->set_border_width(4); + + Gtk::HBox* panFactorHBox = Gtk::manage( new Gtk::HBox () ); + Gtk::Label* panFactorLabel = Gtk::manage( new Gtk::Label (M("PREFERENCES_PANFACTORLABEL") + ":", Gtk::ALIGN_LEFT)); + panFactor = Gtk::manage( new Gtk::SpinButton () ); + panFactor->set_digits (0); + panFactor->set_increments (1, 5); + panFactor->set_range (1, 10); + panFactorHBox->pack_start (*panFactorLabel); + panFactorHBox->pack_end (*panFactor, Gtk::PACK_SHRINK); + + rememberZoomPanCheckbutton = Gtk::manage( new Gtk::CheckButton (M("PREFERENCES_REMEMBERZOOMPAN")) ); + rememberZoomPanCheckbutton->set_tooltip_text(M("PREFERENCES_REMEMBERZOOMPAN_TOOLTIP")); + + navigationVBox->pack_start (*panFactorHBox, Gtk::PACK_SHRINK); + navigationVBox->pack_start (*rememberZoomPanCheckbutton, Gtk::PACK_SHRINK); + navigationFrame->add (*navigationVBox); + + hbcd->pack_start (*navigationFrame); + mvbsd->pack_start (*hbcd, Gtk::PACK_SHRINK, 0); + +//----- + + Gtk::Frame* fdg = Gtk::manage( new Gtk::Frame (M("PREFERENCES_EXTERNALEDITOR")) ); + Gtk::VBox* dgvb = Gtk::manage( new Gtk::VBox () ); + + Gtk::HBox* hb7c = Gtk::manage( new Gtk::HBox () ); + edOther = Gtk::manage( new Gtk::RadioButton (M("PREFERENCES_EDITORCMDLINE")+":")); + hb7c->pack_start (*edOther, Gtk::PACK_SHRINK,4); + editorToSendTo = Gtk::manage( new Gtk::Entry () ); + hb7c->pack_start (*editorToSendTo); + Gtk::RadioButton::Group ge = edOther->get_group(); + +#ifdef __APPLE__ + Gtk::HBox* hb7 = Gtk::manage( new Gtk::HBox () ); + edGimp = Gtk::manage( new Gtk::RadioButton ("GIMP") ); + hb7->pack_start (*edGimp, Gtk::PACK_SHRINK,4); + dgvb->pack_start (*hb7, Gtk::PACK_SHRINK, 4); + edGimp->set_group (ge); + + Gtk::HBox* hb7b = Gtk::manage( new Gtk::HBox () ); + edPS = Gtk::manage( new Gtk::RadioButton (M("PREFERENCES_PSPATH")+":")); + hb7b->pack_start (*edPS, Gtk::PACK_SHRINK,4); + psDir = Gtk::manage( new Gtk::FileChooserButton (M("PREFERENCES_PSPATH"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER) ); + hb7b->pack_start (*psDir); + dgvb->pack_start (*hb7b, Gtk::PACK_SHRINK, 4); + edPS->set_group (ge); +#elif defined WIN32 + Gtk::HBox* hb7 = Gtk::manage( new Gtk::HBox () ); + edGimp = Gtk::manage( new Gtk::RadioButton (M("PREFERENCES_GIMPPATH")+":") ); + hb7->pack_start (*edGimp, Gtk::PACK_SHRINK,4); + gimpDir = Gtk::manage( new Gtk::FileChooserButton (M("PREFERENCES_GIMPPATH"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER) ); + hb7->pack_start (*gimpDir); + dgvb->pack_start (*hb7, Gtk::PACK_SHRINK, 4); + edGimp->set_group (ge); + + Gtk::HBox* hb7b = Gtk::manage( new Gtk::HBox ()); + edPS = Gtk::manage( new Gtk::RadioButton (M("PREFERENCES_PSPATH")+":") ); + hb7b->pack_start (*edPS, Gtk::PACK_SHRINK,4); + psDir = Gtk::manage( new Gtk::FileChooserButton (M("PREFERENCES_PSPATH"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER) ); + hb7b->pack_start (*psDir); + dgvb->pack_start (*hb7b, Gtk::PACK_SHRINK, 4); + edPS->set_group (ge); +#else + Gtk::HBox* hb7 = Gtk::manage( new Gtk::HBox () ); + edGimp = Gtk::manage( new Gtk::RadioButton ("GIMP") ); + hb7->pack_start (*edGimp, Gtk::PACK_SHRINK,4); + dgvb->pack_start (*hb7, Gtk::PACK_SHRINK, 4); + edGimp->set_group (ge); +#endif + + dgvb->pack_start (*hb7c, Gtk::PACK_SHRINK, 4); + dgvb->set_border_width (4); + fdg->add (*dgvb); + mvbsd->pack_start (*fdg, Gtk::PACK_SHRINK, 4); + + + mvbsd->set_border_width (4); + + tconn = theme->signal_changed().connect( sigc::mem_fun(*this, &Preferences::themeChanged) ); + sconn = slimUI->signal_clicked().connect( sigc::mem_fun(*this, &Preferences::themeChanged) ); + fconn = fontbutton->signal_font_set().connect( sigc::mem_fun(*this, &Preferences::fontChanged) ); + usethcon = chUseSystemTheme->signal_clicked ().connect( sigc::mem_fun(*this, &Preferences::useThemeChanged) ); + + return mvbsd; +} + +Gtk::Widget* Preferences::getFileBrowserPanel () { + + Gtk::VBox* mvbfb = Gtk::manage( new Gtk::VBox () ); + mvbfb->set_border_width (4); + + Gtk::Frame* fsd = Gtk::manage( new Gtk::Frame (M("PREFERENCES_STARTUPIMDIR")) ); + + sdcurrent = Gtk::manage( new Gtk::RadioButton (M("PREFERENCES_DIRSOFTWARE")) ); + sdlast = Gtk::manage( new Gtk::RadioButton (M("PREFERENCES_DIRLAST")) ); + sdhome = Gtk::manage( new Gtk::RadioButton (M("PREFERENCES_DIRHOME")) ); + sdother = Gtk::manage( new Gtk::RadioButton (M("PREFERENCES_DIROTHER")+": ") ); + startupdir = Gtk::manage( new Gtk::Entry () ); + + Gtk::Button* sdselect = Gtk::manage( new Gtk::Button ("") ); + sdselect->set_image (*Gtk::manage(new RTImage ("gtk-open.png"))); + + Gtk::RadioButton::Group opts = sdcurrent->get_group(); + sdlast->set_group (opts); + sdhome->set_group (opts); + sdother->set_group (opts); + + Gtk::VBox* vbsd = Gtk::manage( new Gtk::VBox () ); + vbsd->pack_start (*sdcurrent, Gtk::PACK_SHRINK,0); + vbsd->pack_start (*sdlast, Gtk::PACK_SHRINK,0); + vbsd->pack_start (*sdhome, Gtk::PACK_SHRINK,0); + Gtk::HBox* otherbox = Gtk::manage( new Gtk::HBox () ); + otherbox->pack_start (*sdother, Gtk::PACK_SHRINK); + otherbox->pack_start (*startupdir); + otherbox->pack_end (*sdselect, Gtk::PACK_SHRINK, 4); + vbsd->pack_start (*otherbox, Gtk::PACK_SHRINK, 0); + vbsd->set_border_width (4); + + fsd->add (*vbsd); + mvbfb->pack_start (*fsd, Gtk::PACK_SHRINK, 4); + + sdselect->signal_clicked().connect( sigc::mem_fun(*this, &Preferences::selectStartupDir) ); + +//--- + + + Gtk::Frame* fro = Gtk::manage( new Gtk::Frame (M("PREFERENCES_FBROWSEROPTS")) ); + showDateTime = Gtk::manage( new Gtk::CheckButton (M("PREFERENCES_SHOWDATETIME")) ); + showBasicExif = Gtk::manage( new Gtk::CheckButton (M("PREFERENCES_SHOWBASICEXIF")) ); + showExpComp = Gtk::manage( new Gtk::CheckButton (M("PREFERENCES_SHOWEXPOSURECOMPENSATION")) ); + Gtk::VBox* vbro = Gtk::manage( new Gtk::VBox () ); + Gtk::HBox* hbro1 = Gtk::manage( new Gtk::HBox () ); + Gtk::HBox* hbro0 = Gtk::manage( new Gtk::HBox () ); + overlayedFileNames = Gtk::manage( new Gtk::CheckButton (M("PREFERENCES_OVERLAY_FILENAMES")) ); + filmStripOverlayedFileNames = Gtk::manage( new Gtk::CheckButton (M("PREFERENCES_OVERLAY_FILENAMES_FILMSTRIP")) ); + sameThumbSize = Gtk::manage( new Gtk::CheckButton (M("PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT")) ); + sameThumbSize->set_tooltip_text(M("PREFERENCES_FSTRIP_SAME_THUMB_HEIGHT_HINT")); + ckbInternalThumbIfUntouched = Gtk::manage( new Gtk::CheckButton (M("PREFERENCES_INTERNALTHUMBIFUNTOUCHED"))); + + vbro->set_border_width (4); + vbro->pack_start (*showDateTime, Gtk::PACK_SHRINK, 0); + Gtk::Label* dflab = Gtk::manage( new Gtk::Label (M("PREFERENCES_DATEFORMAT")+":", Gtk::ALIGN_LEFT)); + dateformat = Gtk::manage( new Gtk::Entry () ); + dateformat->set_tooltip_markup (M("PREFERENCES_DATEFORMATHINT")); + dflab->set_tooltip_markup (M("PREFERENCES_DATEFORMATHINT")); + hbro0->pack_start (*dflab, Gtk::PACK_SHRINK, 4); + hbro0->pack_start (*dateformat, Gtk::PACK_SHRINK, 0); + + vbro->pack_start (*hbro0, Gtk::PACK_SHRINK, 0); + hbro1->pack_start (*showBasicExif, Gtk::PACK_SHRINK, 0); + hbro1->pack_start (*showExpComp, Gtk::PACK_SHRINK, 4); + vbro->pack_start (*hbro1, Gtk::PACK_SHRINK, 0); + vbro->pack_start (*overlayedFileNames, Gtk::PACK_SHRINK, 0); + vbro->pack_start (*filmStripOverlayedFileNames, Gtk::PACK_SHRINK, 0); + vbro->pack_start (*sameThumbSize, Gtk::PACK_SHRINK, 0); + vbro->pack_start (*ckbInternalThumbIfUntouched, Gtk::PACK_SHRINK, 0); + + Gtk::HBox* hbrecent = Gtk::manage( new Gtk::HBox () ); + Gtk::Label* labrecent = Gtk::manage( new Gtk::Label (M("PREFERENCES_MAXRECENTFOLDERS")+":") ); + maxRecentFolders = Gtk::manage( new Gtk::SpinButton () ); + hbrecent->pack_start (*labrecent, Gtk::PACK_SHRINK, 4); + hbrecent->pack_start (*maxRecentFolders, Gtk::PACK_SHRINK, 4); + maxRecentFolders->set_digits (0); + maxRecentFolders->set_increments (1, 5); + maxRecentFolders->set_range (1, 25); + vbro->pack_start (*hbrecent, Gtk::PACK_SHRINK, 4); + + fro->add (*vbro); + + + Gtk::Frame* frmnu = Gtk::manage( new Gtk::Frame (M("PREFERENCES_MENUOPTIONS")) ); + ckbmenuGroupRank = Gtk::manage( new Gtk::CheckButton (M("PREFERENCES_MENUGROUPRANK")) ); + ckbmenuGroupLabel = Gtk::manage( new Gtk::CheckButton (M("PREFERENCES_MENUGROUPLABEL")) ); + ckbmenuGroupFileOperations = Gtk::manage( new Gtk::CheckButton (M("PREFERENCES_MENUGROUPFILEOPERATIONS")) ); + ckbmenuGroupProfileOperations = Gtk::manage( new Gtk::CheckButton (M("PREFERENCES_MENUGROUPPROFILEOPERATIONS")) ); + ckbmenuGroupExtProg = Gtk::manage( new Gtk::CheckButton (M("PREFERENCES_MENUGROUPEXTPROGS")) ); + Gtk::VBox* vbmnu = Gtk::manage( new Gtk::VBox () ); + + vbmnu->set_border_width (4); + vbmnu->pack_start (*ckbmenuGroupRank, Gtk::PACK_SHRINK, 0); + vbmnu->pack_start (*ckbmenuGroupLabel, Gtk::PACK_SHRINK, 0); + vbmnu->pack_start (*ckbmenuGroupFileOperations, Gtk::PACK_SHRINK, 0); + vbmnu->pack_start (*ckbmenuGroupProfileOperations, Gtk::PACK_SHRINK, 0); + vbmnu->pack_start (*ckbmenuGroupExtProg, Gtk::PACK_SHRINK, 0); + + frmnu->add (*vbmnu); + + + Gtk::Frame* fre = Gtk::manage( new Gtk::Frame (M("PREFERENCES_PARSEDEXT")) ); + Gtk::VBox* vbre = Gtk::manage( new Gtk::VBox () ); + vbre->set_border_width (4); + Gtk::HBox* hb0 = Gtk::manage( new Gtk::HBox () ); + Gtk::Label* elab = Gtk::manage( new Gtk::Label (M("PREFERENCES_PARSEDEXTADD")+":") ); + hb0->pack_start (*elab, Gtk::PACK_SHRINK, 4); + extension = Gtk::manage( new Gtk::Entry () ); + extension->set_width_chars(5); + hb0->pack_start (*extension); + addExt = Gtk::manage( new Gtk::Button () ); + delExt = Gtk::manage( new Gtk::Button () ); + addExt->set_tooltip_text (M("PREFERENCES_PARSEDEXTADDHINT")); + delExt->set_tooltip_text (M("PREFERENCES_PARSEDEXTDELHINT")); + Gtk::Image* addExtImg = Gtk::manage( new RTImage ("list-add-small.png") ); + Gtk::Image* delExtImg = Gtk::manage( new RTImage ("list-remove-red-small.png") ); + addExt->add (*addExtImg); + delExt->add (*delExtImg); + hb0->pack_end (*delExt, Gtk::PACK_SHRINK, 4); + hb0->pack_end (*addExt, Gtk::PACK_SHRINK, 4); + extensions = Gtk::manage( new Gtk::TreeView () ); + Gtk::ScrolledWindow* hscrollw = Gtk::manage( new Gtk::ScrolledWindow () ); + hscrollw->set_policy (Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS); + hscrollw->add (*extensions); + extensionModel = Gtk::ListStore::create (extensionColumns); + extensions->set_model (extensionModel); + extensions->append_column_editable("Enabled", extensionColumns.enabled); + extensions->append_column("Extension", extensionColumns.ext); + extensions->set_headers_visible (false); + vbre->pack_start (*hscrollw); + vbre->pack_start (*hb0, Gtk::PACK_SHRINK, 4); + + fre->add (*vbre); + + Gtk::Frame* frc = Gtk::manage( new Gtk::Frame (M("PREFERENCES_CACHEOPTS")) ); + Gtk::VBox* vbc = Gtk::manage( new Gtk::VBox () ); + frc->add (*vbc); + vbc->set_border_width (4); + + Gtk::HBox* hb3 = Gtk::manage( new Gtk::HBox () ); + Gtk::Label* chlab = Gtk::manage( new Gtk::Label (M("PREFERENCES_CACHETHUMBHEIGHT")+":") ); + maxThumbSize = Gtk::manage( new Gtk::SpinButton () ); + hb3->pack_start (*chlab, Gtk::PACK_SHRINK, 4); + hb3->pack_start (*maxThumbSize, Gtk::PACK_SHRINK, 4); + + maxThumbSize->set_digits (0); + maxThumbSize->set_increments (1, 10); + maxThumbSize->set_range (40, 800); + vbc->pack_start (*hb3, Gtk::PACK_SHRINK, 4); + + Gtk::HBox* hb4 = Gtk::manage( new Gtk::HBox () ); + Gtk::Label* celab = Gtk::manage( new Gtk::Label (M("PREFERENCES_CACHEMAXENTRIES")+":") ); + maxCacheEntries = Gtk::manage( new Gtk::SpinButton () ); + hb4->pack_start (*celab, Gtk::PACK_SHRINK, 4); + hb4->pack_start (*maxCacheEntries, Gtk::PACK_SHRINK, 4); + + maxCacheEntries->set_digits (0); + maxCacheEntries->set_increments (1, 10); + maxCacheEntries->set_range (10, 100000); + vbc->pack_start (*hb4, Gtk::PACK_SHRINK, 4); + + Gtk::HBox* hb5 = Gtk::manage( new Gtk::HBox () ); + clearThumbnails = Gtk::manage( new Gtk::Button (M("PREFERENCES_CACHECLEARTHUMBS")) ); + clearProfiles = Gtk::manage( new Gtk::Button (M("PREFERENCES_CACHECLEARPROFILES")) ); + clearAll = Gtk::manage( new Gtk::Button (M("PREFERENCES_CACHECLEARALL")) ); + hb5->pack_start (*clearThumbnails, Gtk::PACK_SHRINK, 4); + hb5->pack_start (*clearProfiles, Gtk::PACK_SHRINK, 4); + hb5->pack_start (*clearAll, Gtk::PACK_SHRINK, 4); + vbc->pack_start (*hb5, Gtk::PACK_SHRINK, 4); + + Gtk::HBox* hb6 = Gtk::manage( new Gtk::HBox () ); + Gtk::VBox* vb6 = Gtk::manage( new Gtk::VBox () ); + + vb6->pack_start (*fro); + vb6->pack_start (*frmnu); + vb6->pack_end (*frc); + hb6->pack_start (*vb6); + hb6->pack_start (*fre); + hb6->set_spacing(4); + + mvbfb->pack_start (*hb6, Gtk::PACK_SHRINK, 4); + +// mvbfb->pack_start (*fro, Gtk::PACK_SHRINK, 4); +// mvbfb->pack_start (*fre); +// mvbfb->pack_start (*frc, Gtk::PACK_SHRINK, 4); + + addExt->signal_clicked().connect( sigc::mem_fun(*this, &Preferences::addExtPressed) ); + delExt->signal_clicked().connect( sigc::mem_fun(*this, &Preferences::delExtPressed) ); + extension->signal_activate().connect( sigc::mem_fun(*this, &Preferences::addExtPressed) ); + clearThumbnails->signal_clicked().connect( sigc::mem_fun(*this, &Preferences::clearThumbImagesPressed) ); + clearProfiles->signal_clicked().connect( sigc::mem_fun(*this, &Preferences::clearProfilesPressed) ); + clearAll->signal_clicked().connect( sigc::mem_fun(*this, &Preferences::clearAllPressed) ); + + return mvbfb; +} + +Gtk::Widget* Preferences::getSoundPanel () { + Gtk::VBox* pSnd = new Gtk::VBox (); + + ckbSndEnable = Gtk::manage( new Gtk::CheckButton (M("GENERAL_ENABLE"))); + sndEnableConn = ckbSndEnable->signal_toggled().connect (sigc::mem_fun(*this, &Preferences::sndEnableToggled)); + + pSnd->pack_start (*ckbSndEnable, Gtk::PACK_SHRINK, 4); + + Gtk::HBox* hblSndHelp = Gtk::manage (new Gtk::HBox ()); + Gtk::Label* lSndHelp = Gtk::manage (new Gtk::Label (M("PREFERENCES_SND_HELP"))); + hblSndHelp->pack_start (*lSndHelp, Gtk::PACK_SHRINK, 4); + pSnd->pack_start (*hblSndHelp, Gtk::PACK_SHRINK, 4); + + // BatchQueueDone + Gtk::HBox* pBatchQueueDone = Gtk::manage( new Gtk::HBox() ); + + Gtk::Label* lSndBatchQueueDone = Gtk::manage (new Gtk::Label (M("PREFERENCES_SND_BATCHQUEUEDONE") + Glib::ustring(":"))); + pBatchQueueDone->pack_start (*lSndBatchQueueDone, Gtk::PACK_SHRINK, 4); + + txtSndBatchQueueDone = Gtk::manage (new Gtk::Entry()); + pBatchQueueDone->pack_end (*txtSndBatchQueueDone, Gtk::PACK_EXPAND_WIDGET, 4); + + pSnd->pack_start (*pBatchQueueDone, Gtk::PACK_SHRINK, 4); + + // LngEditProcDone + Gtk::HBox* pSndLngEditProcDone = Gtk::manage( new Gtk::HBox() ); + + Gtk::Label* lSndLngEditProcDone = Gtk::manage (new Gtk::Label (M("PREFERENCES_SND_LNGEDITPROCDONE") + Glib::ustring(":"))); + pSndLngEditProcDone->pack_start (*lSndLngEditProcDone, Gtk::PACK_SHRINK, 4); + + txtSndLngEditProcDone = Gtk::manage (new Gtk::Entry()); + pSndLngEditProcDone->pack_start (*txtSndLngEditProcDone, Gtk::PACK_EXPAND_WIDGET, 4); + + Gtk::Label* lSndLngEditProcDoneSecs = Gtk::manage (new Gtk::Label (M("PREFERENCES_SND_TRESHOLDSECS") + Glib::ustring(":"))); + pSndLngEditProcDone->pack_start (*lSndLngEditProcDoneSecs, Gtk::PACK_SHRINK, 12); + + spbSndLngEditProcDoneSecs = Gtk::manage( new Gtk::SpinButton () ); + spbSndLngEditProcDoneSecs->set_digits (1); + spbSndLngEditProcDoneSecs->set_increments (0.5, 1); + spbSndLngEditProcDoneSecs->set_range (0, 10); + pSndLngEditProcDone->pack_end (*spbSndLngEditProcDoneSecs, Gtk::PACK_SHRINK, 4); + + pSnd->pack_start (*pSndLngEditProcDone, Gtk::PACK_SHRINK, 4); + + pSnd->set_border_width (4); + + sndEnableToggled(); + + return pSnd; +} + +void Preferences::parseDir (Glib::ustring dirname, std::vector& items, Glib::ustring ext) { + + if (dirname.empty()) + return; + + // process directory + Glib::Dir* dir = NULL; + try { + dir = new Glib::Dir (dirname); + } + catch (const Glib::Error& e) { + return; + } + for (Glib::DirIterator i = dir->begin(); i!=dir->end(); ++i) { + Glib::ustring fname = Glib::build_filename(dirname, *i); + Glib::ustring sname = *i; + // ignore directories + if (!safe_file_test (fname, Glib::FILE_TEST_IS_DIR) && sname.size() >= ext.size() && sname.substr (sname.size()-ext.size(), ext.size()).casefold() == ext) + items.push_back (sname.substr(0,sname.size()-ext.size())); + } + std::sort(items.begin(), items.end()); + delete dir; +} + +void Preferences::storePreferences () { + + // With the new mechanism, we can't be sure of the availability of the DEFPROFILE_RAW & DEFPROFILE_IMG profiles, + // because useBundledProfiles may be false. We're now using DEFPROFILE_INTERNAL instead, which is always available. + moptions.defProfRaw = rprofiles->getFullPathFromActiveRow(); + if (moptions.defProfRaw.empty()) moptions.defProfRaw = DEFPROFILE_INTERNAL; + moptions.defProfImg = iprofiles->getFullPathFromActiveRow(); + if (moptions.defProfImg.empty()) moptions.defProfImg = DEFPROFILE_INTERNAL; + + moptions.dateFormat = dateformat->get_text(); + moptions.panAccelFactor = (int)panFactor->get_value(); + moptions.rememberZoomAndPan = rememberZoomPanCheckbutton->get_active(); + moptions.fbShowDateTime = showDateTime->get_active (); + moptions.fbShowBasicExif = showBasicExif->get_active (); + moptions.fbShowExpComp = showExpComp->get_active (); + moptions.menuGroupRank = ckbmenuGroupRank->get_active(); + moptions.menuGroupLabel = ckbmenuGroupLabel->get_active(); + moptions.menuGroupFileOperations = ckbmenuGroupFileOperations->get_active(); + moptions.menuGroupProfileOperations = ckbmenuGroupProfileOperations->get_active(); + moptions.menuGroupExtProg = ckbmenuGroupExtProg->get_active(); + moptions.highlightThreshold = (int)hlThresh->get_value (); + moptions.shadowThreshold = (int)shThresh->get_value (); + moptions.language = languages->get_active_text (); + moptions.languageAutoDetect = ckbLangAutoDetect->get_active (); + moptions.theme = theme->get_active_text (); + moptions.slimUI = slimUI->get_active (); + moptions.useSystemTheme = chUseSystemTheme->get_active (); + + Gdk::Color cropCol=butCropCol->get_color(); + moptions.cutOverlayBrush[0]=cropCol.get_red_p(); + moptions.cutOverlayBrush[1]=cropCol.get_green_p(); + moptions.cutOverlayBrush[2]=cropCol.get_blue_p(); + moptions.cutOverlayBrush[3]=butCropCol->get_alpha()/65535.0; + + Gdk::Color NavGuideCol=butNavGuideCol->get_color(); + moptions.navGuideBrush[0]=NavGuideCol.get_red_p(); + moptions.navGuideBrush[1]=NavGuideCol.get_green_p(); + moptions.navGuideBrush[2]=NavGuideCol.get_blue_p(); + moptions.navGuideBrush[3]=butNavGuideCol->get_alpha()/65535.0; + + moptions.font = fontbutton->get_font_name(); +#ifdef WIN32 + moptions.gimpDir = gimpDir->get_filename (); + moptions.psDir = psDir->get_filename (); +#elif defined __APPLE__ + moptions.psDir = psDir->get_filename (); +#endif + moptions.customEditorProg = editorToSendTo->get_text (); + if (edGimp->get_active ()) + moptions.editorToSendTo = 1; +#ifdef WIN32 + else if (edPS->get_active ()) + moptions.editorToSendTo = 2; +#elif defined __APPLE__ + else if (edPS->get_active ()) + moptions.editorToSendTo = 2; +#endif + else if (edOther->get_active ()) + moptions.editorToSendTo = 3; + + moptions.CPBPath = txtCustProfBuilderPath->get_text(); + moptions.CPBKeys = CPBKeyType(custProfBuilderLabelType->get_active_row_number()); + + moptions.rtSettings.monitorProfile = monProfile->get_filename (); +#if defined(WIN32) + moptions.rtSettings.autoMonitorProfile = cbAutoMonProfile->get_active (); +#endif + moptions.rtSettings.iccDirectory = iccDir->get_filename (); + moptions.rtSettings.colorimetricIntent = intent->get_active_row_number (); + moptions.rtSettings.viewingdevice = view->get_active_row_number (); + moptions.rtSettings.viewingdevicegrey = grey->get_active_row_number (); + moptions.rtSettings.viewinggreySc = greySc->get_active_row_number (); + // moptions.rtSettings.autocielab = cbAutocielab->get_active (); + moptions.rtSettings.ciecamfloat = cbciecamfloat->get_active (); + moptions.rtSettings.HistogramWorking = ckbHistogramWorking->get_active (); + moptions.rtSettings.leveldnv = dnv->get_active_row_number (); + moptions.rtSettings.leveldnti = dnti->get_active_row_number (); + moptions.rtSettings.leveldnliss = dnliss->get_active_row_number (); + moptions.rtSettings.leveldnaut = dnaut->get_active_row_number (); + moptions.rtSettings.nrwavlevel = dnwavlev->get_active_row_number (); + moptions.rtSettings.leveldnautsimpl = dnautsimpl->get_active_row_number (); + moptions.rtSettings.daubech = cbdaubech->get_active (); + + moptions.prevdemo = (prevdemo_t)cprevdemo->get_active_row_number (); + moptions.serializeTiffRead = ctiffserialize->get_active(); + if (sdcurrent->get_active ()) + moptions.startupDir = STARTUPDIR_CURRENT; + else if (sdhome->get_active ()) + moptions.startupDir = STARTUPDIR_HOME; + else if (sdlast->get_active ()) + moptions.startupDir = STARTUPDIR_LAST; + else if (sdother->get_active ()) { + moptions.startupDir = STARTUPDIR_CUSTOM; + moptions.startupPath = startupdir->get_text(); + } + + moptions.parseExtensions.clear (); + moptions.parseExtensionsEnabled.clear (); + Gtk::TreeNodeChildren c = extensionModel->children (); + for (size_t i=0; iget_value(); + moptions.maxThumbnailHeight = (int)maxThumbSize->get_value (); + moptions.maxCacheEntries = (int)maxCacheEntries->get_value (); + moptions.overlayedFileNames = overlayedFileNames->get_active (); + moptions.filmStripOverlayedFileNames = filmStripOverlayedFileNames->get_active(); + moptions.sameThumbSize = sameThumbSize->get_active(); + moptions.internalThumbIfUntouched = ckbInternalThumbIfUntouched->get_active (); + + moptions.saveParamsFile = saveParamsFile->get_active (); + moptions.saveParamsCache = saveParamsCache->get_active (); + moptions.paramsLoadLocation = (PPLoadLocation)loadParamsPreference->get_active_row_number (); + moptions.useBundledProfiles = useBundledProfiles->get_active (); + + moptions.tunnelMetaData = ckbTunnelMetaData->get_active (); + + moptions.rtSettings.darkFramesPath = darkFrameDir->get_filename(); + moptions.rtSettings.flatFieldsPath = flatFieldDir->get_filename(); + + moptions.clutsDir = clutsDir->get_filename(); + + moptions.baBehav.resize (ADDSET_PARAM_NUM); + for (Gtk::TreeIter sections=behModel->children().begin(); sections!=behModel->children().end(); sections++) + for (Gtk::TreeIter adjs=sections->children().begin(); adjs!=sections->children().end(); adjs++) + moptions.baBehav[adjs->get_value (behavColumns.addsetid)] = adjs->get_value (behavColumns.badd); + + int editorMode=editorLayout->get_active_row_number(); + moptions.tabbedUI = (editorMode>1); + moptions.multiDisplayMode = editorMode==3 ? 1:0; + moptions.mainNBVertical = editorMode==1; + + moptions.curvebboxpos = curveBBoxPosC->get_active_row_number(); + moptions.histogramPosition = ckbHistogramPositionLeft->get_active() ? 1 : 2; + moptions.FileBrowserToolbarSingleRow = ckbFileBrowserToolbarSingleRow->get_active(); + moptions.showFilmStripToolBar = ckbShowFilmStripToolBar->get_active(); + moptions.hideTPVScrollbar = ckbHideTPVScrollbar->get_active(); + moptions.overwriteOutputFile = chOverwriteOutputFile->get_active (); + moptions.UseIconNoText = ckbUseIconNoText->get_active(); + + moptions.rgbDenoiseThreadLimit = rgbDenoiseTreadLimitSB->get_value_as_int(); + moptions.clutCacheSize = clutCacheSizeSB->get_value_as_int(); + moptions.maxInspectorBuffers = maxInspectorBuffersSB->get_value_as_int(); + + // Sounds only on Windows and Linux +#if defined(WIN32) || defined(__linux__) + moptions.sndEnable = ckbSndEnable->get_active (); + moptions.sndBatchQueueDone = txtSndBatchQueueDone->get_text (); + moptions.sndLngEditProcDone = txtSndLngEditProcDone->get_text (); + moptions.sndLngEditProcDoneSecs = spbSndLngEditProcDoneSecs->get_value (); +#endif +} + +void Preferences::fillPreferences () { + + tconn.block (true); + sconn.block (true); + dfconn.block (true); + ffconn.block (true); + rpconn.block(true); + ipconn.block(true); + bpconn.block(true); + + rprofiles->setActiveRowFromFullPath (moptions.defProfRaw); + forRAWComboChanged(); // update the tooltip + iprofiles->setActiveRowFromFullPath (moptions.defProfImg); + forImageComboChanged(); // update the tooltip + dateformat->set_text (moptions.dateFormat); + panFactor->set_value (moptions.panAccelFactor); + rememberZoomPanCheckbutton->set_active (moptions.rememberZoomAndPan); + ctiffserialize->set_active(moptions.serializeTiffRead); +#if !defined(__APPLE__) // monitor profile not supported on apple + if (safe_file_test (moptions.rtSettings.monitorProfile, Glib::FILE_TEST_EXISTS)) + monProfile->set_filename (moptions.rtSettings.monitorProfile); + if (moptions.rtSettings.monitorProfile.empty()) + monProfile->set_current_folder (moptions.rtSettings.iccDirectory); +#if defined(WIN32) + cbAutoMonProfile->set_active(moptions.rtSettings.autoMonitorProfile); +#endif +#endif + + if (Glib::file_test (moptions.rtSettings.iccDirectory, Glib::FILE_TEST_IS_DIR)) + iccDir->set_current_folder (moptions.rtSettings.iccDirectory); + intent->set_active (moptions.rtSettings.colorimetricIntent); + view->set_active (moptions.rtSettings.viewingdevice); + grey->set_active (moptions.rtSettings.viewingdevicegrey); + greySc->set_active (moptions.rtSettings.viewinggreySc); + dnv->set_active (moptions.rtSettings.leveldnv); + dnti->set_active (moptions.rtSettings.leveldnti); + dnliss->set_active (moptions.rtSettings.leveldnliss); + dnaut->set_active (moptions.rtSettings.leveldnaut); + dnautsimpl->set_active (moptions.rtSettings.leveldnautsimpl); + dnwavlev->set_active (moptions.rtSettings.nrwavlevel); + cprevdemo->set_active (moptions.prevdemo); + cbdaubech->set_active (moptions.rtSettings.daubech); + +// cbAutocielab->set_active (moptions.rtSettings.autocielab); + cbciecamfloat->set_active (moptions.rtSettings.ciecamfloat); + ckbHistogramWorking->set_active (moptions.rtSettings.HistogramWorking); + languages->set_active_text (moptions.language); + ckbLangAutoDetect->set_active (moptions.languageAutoDetect); + theme->set_active_text (moptions.theme); + slimUI->set_active(moptions.slimUI); + chUseSystemTheme->set_active(moptions.useSystemTheme); + + Gdk::Color cropCol; + cropCol.set_rgb_p(moptions.cutOverlayBrush[0],moptions.cutOverlayBrush[1],moptions.cutOverlayBrush[2]); + butCropCol->set_color(cropCol); + butCropCol->set_alpha ( (unsigned short)(moptions.cutOverlayBrush[3]*65535.0)); + + Gdk::Color NavGuideCol; + NavGuideCol.set_rgb_p(moptions.navGuideBrush[0],moptions.navGuideBrush[1],moptions.navGuideBrush[2]); + butNavGuideCol->set_color(NavGuideCol); + butNavGuideCol->set_alpha ( (unsigned short)(moptions.navGuideBrush[3]*65535.0)); + + fontbutton->set_font_name(moptions.font); + showDateTime->set_active (moptions.fbShowDateTime); + showBasicExif->set_active (moptions.fbShowBasicExif); + showExpComp->set_active (moptions.fbShowExpComp); + ckbmenuGroupRank->set_active(moptions.menuGroupRank); + ckbmenuGroupLabel->set_active(moptions.menuGroupLabel); + ckbmenuGroupFileOperations->set_active(moptions.menuGroupFileOperations); + ckbmenuGroupProfileOperations->set_active(moptions.menuGroupProfileOperations); + ckbmenuGroupExtProg->set_active(moptions.menuGroupExtProg); + + hlThresh->set_value (moptions.highlightThreshold); + shThresh->set_value (moptions.shadowThreshold); + + edGimp->set_active (moptions.editorToSendTo==1); + edOther->set_active (moptions.editorToSendTo==3); +#ifdef WIN32 + edPS->set_active (moptions.editorToSendTo==2); + if (safe_file_test (moptions.gimpDir, Glib::FILE_TEST_IS_DIR)) + gimpDir->set_current_folder (moptions.gimpDir); + if (safe_file_test (moptions.psDir, Glib::FILE_TEST_IS_DIR)) + psDir->set_current_folder (moptions.psDir); +#elif defined __APPLE__ + edPS->set_active (moptions.editorToSendTo==2); + if (safe_file_test (moptions.psDir, Glib::FILE_TEST_IS_DIR)) + psDir->set_current_folder (moptions.psDir); +#endif + editorToSendTo->set_text (moptions.customEditorProg); + + txtCustProfBuilderPath->set_text(moptions.CPBPath); + custProfBuilderLabelType->set_active(moptions.CPBKeys); + + + if (moptions.startupDir==STARTUPDIR_CURRENT) + sdcurrent->set_active (); + else if (moptions.startupDir==STARTUPDIR_LAST) + sdlast->set_active (); + else if (moptions.startupDir==STARTUPDIR_HOME) + sdhome->set_active (); + else if (moptions.startupDir==STARTUPDIR_CUSTOM) { + sdother->set_active (); + startupdir->set_text (moptions.startupPath); + } + + extensionModel->clear (); + for (size_t i=0; iappend()); + row[extensionColumns.enabled] = moptions.parseExtensionsEnabled[i]; + row[extensionColumns.ext] = moptions.parseExtensions[i]; + } + + maxThumbSize->set_value (moptions.maxThumbnailHeight); + maxRecentFolders->set_value(moptions.maxRecentFolders); + maxCacheEntries->set_value (moptions.maxCacheEntries); + overlayedFileNames->set_active (moptions.overlayedFileNames); + filmStripOverlayedFileNames->set_active(moptions.filmStripOverlayedFileNames); + sameThumbSize->set_active(moptions.sameThumbSize); + ckbInternalThumbIfUntouched->set_active(moptions.internalThumbIfUntouched); + + saveParamsFile->set_active (moptions.saveParamsFile); + saveParamsCache->set_active (moptions.saveParamsCache); + loadParamsPreference->set_active (moptions.paramsLoadLocation); + useBundledProfiles->set_active (moptions.useBundledProfiles); + + ckbTunnelMetaData->set_active (moptions.tunnelMetaData); + + if (!moptions.tabbedUI) + editorLayout->set_active(moptions.mainNBVertical ? 1 : 0); + else + editorLayout->set_active(moptions.multiDisplayMode ? 3 : 2); + + curveBBoxPosC->set_active(moptions.curvebboxpos); + ckbHistogramPositionLeft->set_active(moptions.histogramPosition==1); + // ckbHistogramWorking->set_active(moptions.histogramWorking==1); + ckbFileBrowserToolbarSingleRow->set_active(moptions.FileBrowserToolbarSingleRow); + ckbShowFilmStripToolBar->set_active(moptions.showFilmStripToolBar); + ckbHideTPVScrollbar->set_active(moptions.hideTPVScrollbar); + ckbUseIconNoText->set_active(moptions.UseIconNoText); + + rgbDenoiseTreadLimitSB->set_value(moptions.rgbDenoiseThreadLimit); + clutCacheSizeSB->set_value(moptions.clutCacheSize); + maxInspectorBuffersSB->set_value(moptions.maxInspectorBuffers); + + darkFrameDir->set_current_folder( moptions.rtSettings.darkFramesPath ); + darkFrameChanged (); + + flatFieldDir->set_current_folder( moptions.rtSettings.flatFieldsPath ); + flatFieldChanged (); + + clutsDir->set_current_folder( moptions.clutsDir ); + + addc.block (true); + setc.block (true); + if (moptions.baBehav.size() == ADDSET_PARAM_NUM) { + for (size_t i=0; ichildren().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; + } + } + addc.block (false); + setc.block (false); + tconn.block (false); + sconn.block (false); + dfconn.block (false); + ffconn.block (false); + rpconn.block(true); + ipconn.block(true); + bpconn.block(false); + + chOverwriteOutputFile->set_active (moptions.overwriteOutputFile); + + // Sounds only on Windows and Linux +#if defined(WIN32) || defined(__linux__) + ckbSndEnable->set_active (moptions.sndEnable); + txtSndBatchQueueDone->set_text (moptions.sndBatchQueueDone); + txtSndLngEditProcDone->set_text (moptions.sndLngEditProcDone); + spbSndLngEditProcDoneSecs->set_value (moptions.sndLngEditProcDoneSecs); +#endif +} + +/* +void Preferences::loadPressed () { + + moptions.copyFrom (&options); + fillPreferences (); +} + +void Preferences::savePressed () { + + storePreferences (); + options.copyFrom (&moptions); + Options::save (); +} +*/ + +#if defined(WIN32) +void Preferences::autoMonProfileToggled () { + monProfile->set_sensitive(!cbAutoMonProfile->get_active()); +} +#endif +/* +void Preferences::autocielabToggled () { +// cbAutocielab->set_sensitive(cbAutocielab->get_active()); +} +*/ +void Preferences::sndEnableToggled () { + txtSndBatchQueueDone->set_sensitive(ckbSndEnable->get_active()); + txtSndLngEditProcDone->set_sensitive(ckbSndEnable->get_active()); + spbSndLngEditProcDoneSecs->set_sensitive(ckbSndEnable->get_active()); +} + +void Preferences::langAutoDetectToggled () { + languages->set_sensitive(!ckbLangAutoDetect->get_active()); +} + +void Preferences::okPressed () { + + storePreferences (); + workflowUpdate(); + options.copyFrom (&moptions); + options.filterOutParsedExtensions(); + Options::save (); + hide (); +} + +void Preferences::cancelPressed () { + + bool currentSlimState = options.slimUI; + options.slimUI = oldSlimUI; + + // set the initial theme back + if (theme->get_active_text()!=options.theme || options.slimUI!=currentSlimState) { + RTImage::setPaths(options); + RTImage::updateImages(); + switchThemeTo(options.theme, options.slimUI); + } + + // set the initial font back + if (fontbutton->get_font_name() != options.font) + switchFontTo(options.font); + + // update the profileStore + if (useBundledProfiles->get_active () != options.useBundledProfiles) { + // we have to rescan with the old value; + bpconn.block(true); + useBundledProfiles->set_active (false); + bundledProfilesChanged(); + bpconn.block(false); + } + + hide (); +} + +void Preferences::selectStartupDir () { + + Gtk::FileChooserDialog dialog(M("PREFERENCES_DIRSELECTDLG"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER); +// dialog.set_transient_for(*this); + + //Add response buttons the the dialog: + dialog.add_button(Gtk::StockID("gtk-cancel"), Gtk::RESPONSE_CANCEL); + dialog.add_button(Gtk::StockID("gtk-open"), Gtk::RESPONSE_OK); + + int result = dialog.run(); + + if (result==Gtk::RESPONSE_OK) + startupdir->set_text (dialog.get_filename()); +} + +void Preferences::aboutPressed () { + + splash = new Splash (*this); + splash->set_transient_for (*this); + splash->signal_delete_event().connect( sigc::mem_fun(*this, &Preferences::splashClosed) ); + splash->show (); +} + +void Preferences::themeChanged () { + + moptions.theme = theme->get_active_text (); + moptions.useSystemTheme = chUseSystemTheme->get_active (); + RTImage::setPaths(moptions); + RTImage::updateImages(); + switchThemeTo(theme->get_active_text (), slimUI->get_active()); +} + +void Preferences::forRAWComboChanged () { + if (!rprofiles) + return; + const ProfileStoreEntry *selectedEntry = rprofiles->getSelectedEntry(); + if (!selectedEntry) + return; + + if (selectedEntry->type == PSET_FOLDER) { + rpconn.block(true); + rprofiles->set_active(currRawRow); + rpconn.block(false); + } + else + currRawRow = rprofiles->get_active(); + + rprofiles->set_tooltip_text(selectedEntry->label); +} + +void Preferences::forImageComboChanged () { + if (!iprofiles) + return; + const ProfileStoreEntry *selectedEntry = iprofiles->getSelectedEntry(); + if (!selectedEntry) + return; + + if (selectedEntry->type == PSET_FOLDER) { + ipconn.block(true); + iprofiles->set_active(currImgRow); + ipconn.block(false); + } + else + currImgRow = rprofiles->get_active(); + iprofiles->set_tooltip_text(iprofiles->getSelectedEntry()->label); +} + +void Preferences::layoutComboChanged () { + editorLayout->set_tooltip_text(editorLayout->get_active_text()); +} + +void Preferences::bundledProfilesChanged () { + rpconn.block (true); + ipconn.block (true); + + // parseProfiles does use options.useBundledProfiles, so we temporarily change its value + bool currValue = options.useBundledProfiles; + options.useBundledProfiles = useBundledProfiles->get_active (); + + // rescan the file's tree + profileStore.parseProfiles(); // This will call Preferences::updateProfileList in return + + // restoring back the old value + options.useBundledProfiles = currValue; + + ipconn.block (false); + rpconn.block (false); +} + +void Preferences::storeCurrentValue() { + // TODO: Find a way to get and restore the current selection; the following line can't work anymore + storedValueRaw = rprofiles->getFullPathFromActiveRow(); + storedValueImg = iprofiles->getFullPathFromActiveRow(); +} + +void Preferences::updateProfileList() { + rprofiles->updateProfileList(); + iprofiles->updateProfileList(); +} + +void Preferences::restoreValue() { + if (!rprofiles->setActiveRowFromFullPath(storedValueRaw)) { + moptions.defProfRaw = DEFPROFILE_INTERNAL; + rpconn.block(true); + rprofiles->setInternalEntry(); + rpconn.block(false); + } + currRawRow = rprofiles->get_active(); + + if (!iprofiles->setActiveRowFromFullPath(storedValueImg)) { + moptions.defProfImg = DEFPROFILE_INTERNAL; + ipconn.block(true); + iprofiles->setInternalEntry(); + ipconn.block(false); + } + currImgRow = iprofiles->get_active(); + + storedValueRaw = ""; + storedValueImg = ""; +} + +void Preferences::fontChanged () { + + switchFontTo(fontbutton->get_font_name()); +} + +void Preferences::switchThemeTo(Glib::ustring newTheme, bool slimInterface) { + + std::vector files; + files.push_back (argv0+"/themes/"+newTheme+".gtkrc"); + + options.slimUI = slimInterface; + + if (slimInterface) + files.push_back (argv0+"/themes/slim"); + Gtk::RC::set_default_files (files); + +#ifndef WIN32 + // For an unknown reason, gtkmm 2.22 don't know the gtk-button-images property, while it exists in the documentation... + // Anyway, the problem was Linux only + static Glib::RefPtr settings = Gtk::Settings::get_default(); + if (settings) + settings->property_gtk_button_images().set_value(true); + else + printf("Error: no default settings to update!\n"); +#endif + + Gtk::RC::reparse_all (Gtk::Settings::get_default()); + GdkEventClient event = { GDK_CLIENT_EVENT, NULL, TRUE, gdk_atom_intern("_GTK_READ_RCFILES", FALSE), 8 }; + gdk_event_send_clientmessage_toall ((GdkEvent*)&event); +} + +void Preferences::workflowUpdate (){ + + if(moptions.tabbedUI != options.tabbedUI) { + parent->MoveFileBrowserToMain(); + parent->CloseOpenEditors(); + parent->SetMainCurrent(); + if(moptions.tabbedUI){ + parent->epanel->hide_all(); + parent->set_title_decorated(""); + } + else{ + parent->epanel->show_all(); + parent->set_title_decorated(parent->epanel->getFileName()); + } + } + if(moptions.hideTPVScrollbar != options.hideTPVScrollbar) { + // Update the tool panels + parent->updateTPVScrollbar (moptions.hideTPVScrollbar); + } + if(moptions.UseIconNoText != options.UseIconNoText) { + // Update the tool's tab titles + parent->updateTabsUsesIcons(moptions.UseIconNoText); + } + if(moptions.FileBrowserToolbarSingleRow != options.FileBrowserToolbarSingleRow) { + // Update the position of the Query toolbar + parent->updateFBQueryTB(moptions.FileBrowserToolbarSingleRow); + } + if(moptions.showFilmStripToolBar != options.showFilmStripToolBar) { + // Update the visibility of FB toolbar + parent->updateFBToolBarVisibility(moptions.showFilmStripToolBar); + } + if(moptions.histogramPosition != options.histogramPosition) { + // Update the position of the Histogram + parent->updateHistogramPosition(options.histogramPosition, moptions.histogramPosition); + } + +} + +void Preferences::switchFontTo(Glib::ustring newFont) { + + Gtk::RC::parse_string (Glib::ustring::compose( + "style \"clearlooks-default\" { font_name = \"%1\" }", newFont)); + Gtk::RC::reparse_all (Gtk::Settings::get_default()); + GdkEventClient event = { GDK_CLIENT_EVENT, NULL, TRUE, gdk_atom_intern("_GTK_READ_RCFILES", FALSE), 8 }; + gdk_event_send_clientmessage_toall ((GdkEvent*)&event); +} + +void Preferences::useThemeChanged(){ + + if(!chUseSystemTheme->get_active()){ + hbtheme->set_sensitive(true); + fontbutton->set_sensitive(true); + } + else{ + hbtheme->set_sensitive(false); + fontbutton->set_sensitive(false); + } +} + +void Preferences::addExtPressed () { + + Gtk::TreeNodeChildren c = extensionModel->children (); + for (size_t i=0; iget_text ()) + return; + + Gtk::TreeRow row = *(extensionModel->append()); + + row[extensionColumns.enabled] = true; + row[extensionColumns.ext] = extension->get_text (); +} + +void Preferences::delExtPressed () { + + extensionModel->erase (extensions->get_selection()->get_selected ()); +} + +void Preferences::clearProfilesPressed () { + + cacheMgr->clearProfiles (); +} + +void Preferences::clearThumbImagesPressed () { + + cacheMgr->clearThumbImages (); +} + +void Preferences::clearAllPressed () { + + cacheMgr->clearAll (); +} + +void Preferences::darkFrameChanged () +{ + //Glib::ustring s(darkFrameDir->get_filename()); + Glib::ustring s(darkFrameDir->get_current_folder()); + //if( s.compare( rtengine::dfm.getPathname()) !=0 ){ + rtengine::dfm.init( s ); + updateDFinfos(); + //} +} + +void Preferences::flatFieldChanged () +{ + //Glib::ustring s(flatFieldDir->get_filename()); + Glib::ustring s(flatFieldDir->get_current_folder()); + //if( s.compare( rtengine::ffm.getPathname()) !=0 ){ + rtengine::ffm.init( s ); + updateFFinfos(); + //} +} + +void Preferences::updateDFinfos() +{ + int t1,t2; + rtengine::dfm.getStat(t1,t2); + Glib::ustring s = Glib::ustring::compose("%1: %2 %3, %4 %5", M("PREFERENCES_DARKFRAMEFOUND"), t1, M("PREFERENCES_DARKFRAMESHOTS"), t2, M("PREFERENCES_DARKFRAMETEMPLATES")); + dfLabel->set_text(s); +} + +void Preferences::updateFFinfos() +{ + int t1,t2; + rtengine::ffm.getStat(t1,t2); + Glib::ustring s = Glib::ustring::compose("%1: %2 %3, %4 %5", M("PREFERENCES_FLATFIELDFOUND"), t1, M("PREFERENCES_FLATFIELDSHOTS"), t2, M("PREFERENCES_FLATFIELDTEMPLATES")); + ffLabel->set_text(s); +} + +bool Preferences::splashClosed(GdkEventAny* event) { + delete splash; + splash = NULL; + return true; +} + +void Preferences::behAddAllPressed () { + + if (moptions.baBehav.size() == ADDSET_PARAM_NUM) { + for (size_t i=0; ichildren().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; + } + } +} + +void Preferences::behSetAllPressed () { + + if (moptions.baBehav.size() == ADDSET_PARAM_NUM) { + for (size_t i=0; ichildren().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; + } + } +} diff --git a/rtgui/preferences.h b/rtgui/preferences.h new file mode 100644 index 000000000..a81dec5a4 --- /dev/null +++ b/rtgui/preferences.h @@ -0,0 +1,250 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef __PREFERENCES_H__ +#define __PREFERENCES_H__ + +#include +#include "adjuster.h" +#include "options.h" +#include +#include "rtwindow.h" + +class Preferences : public Gtk::Dialog, public ProfileStoreListener { + + class ExtensionColumns : public Gtk::TreeModel::ColumnRecord { + public: + Gtk::TreeModelColumn enabled; + Gtk::TreeModelColumn ext; + ExtensionColumns() { add(enabled); add(ext); } + }; + ExtensionColumns extensionColumns; + Glib::RefPtr extensionModel; + + + class BehavColumns : public Gtk::TreeModel::ColumnRecord { + public: + Gtk::TreeModelColumn label; + Gtk::TreeModelColumn badd; + Gtk::TreeModelColumn bset; + Gtk::TreeModelColumn visible; + Gtk::TreeModelColumn addsetid; + BehavColumns() { add(label); add(badd); add(bset); add(visible); add(addsetid); } + }; + Glib::RefPtr behModel; + BehavColumns behavColumns; + + + protected: + Splash* splash; + ProfileStoreComboBox* rprofiles; + Gtk::TreeIter currRawRow; // :) + ProfileStoreComboBox* iprofiles; + Gtk::TreeIter currImgRow; + Gtk::ComboBoxText* languages; + Gtk::CheckButton* ckbLangAutoDetect; + Gtk::Entry* dateformat; + Gtk::Entry* startupdir; + Gtk::RadioButton* sdcurrent; + Gtk::RadioButton* sdlast; + Gtk::RadioButton* sdhome; + Gtk::RadioButton* sdother; + Gtk::FileChooserButton* gimpDir; + Gtk::FileChooserButton* psDir; + Gtk::Entry* editorToSendTo; + Gtk::RadioButton* edGimp; + Gtk::RadioButton* edPS; + Gtk::RadioButton* edOther; + Gtk::FileChooserButton* darkFrameDir; + Gtk::FileChooserButton* flatFieldDir; + Gtk::FileChooserButton* clutsDir; + Gtk::Label *dfLabel; + Gtk::Label *ffLabel; + + Gtk::CheckButton* showDateTime; + Gtk::CheckButton* showBasicExif; + Gtk::CheckButton* showExpComp; + + Gtk::FileChooserButton* iccDir; + Gtk::FileChooserButton* monProfile; + Gtk::CheckButton* cbAutoMonProfile; + //Gtk::CheckButton* cbAutocielab; + Gtk::CheckButton* cbciecamfloat; + Gtk::CheckButton* cbdaubech; + Gtk::SpinButton* hlThresh; + Gtk::SpinButton* shThresh; + + Gtk::SpinButton* panFactor; + Gtk::CheckButton* rememberZoomPanCheckbutton; + + Gtk::ComboBoxText* intent; + Gtk::ComboBoxText* view; + Gtk::ComboBoxText* grey; + Gtk::ComboBoxText* greySc; + Gtk::ComboBoxText* dnv; + Gtk::ComboBoxText* dnti; + Gtk::ComboBoxText* dnaut; + Gtk::ComboBoxText* dnautsimpl; + Gtk::ComboBoxText* dnwavlev; + Gtk::ComboBoxText* dnliss; + + Gtk::Frame* waveletFrame; + Gtk::HBox* waveletTileSizeHBox; + Gtk::Label* waveletTileSizeLabel; + Gtk::ComboBoxText* waveletTileSizeCombo; + + Gtk::ComboBoxText* cprevdemo; + Gtk::CheckButton* ctiffserialize; + Gtk::ComboBoxText* curveBBoxPosC; + + Gtk::ComboBoxText* theme; + Gtk::CheckButton* slimUI; + Gtk::HBox* hbtheme; + Gtk::CheckButton* chUseSystemTheme; + Gtk::FontButton* fontbutton; + Gtk::ColorButton* butCropCol; + Gtk::ColorButton* butNavGuideCol; + + Gtk::SpinButton* maxThumbSize; + Gtk::SpinButton* maxCacheEntries; + Gtk::SpinButton* maxRecentFolders; + Gtk::Button* clearThumbnails; + Gtk::Button* clearProfiles; + Gtk::Button* clearAll; + Gtk::Entry* extension; + Gtk::TreeView* extensions; + Gtk::Button* addExt; + Gtk::Button* delExt; + Gtk::CheckButton* overlayedFileNames; + Gtk::CheckButton* filmStripOverlayedFileNames; + Gtk::CheckButton* sameThumbSize; + + Gtk::SpinButton* rgbDenoiseTreadLimitSB; + Gtk::SpinButton* clutCacheSizeSB; + Gtk::SpinButton* maxInspectorBuffersSB; + + Gtk::CheckButton* ckbmenuGroupRank; + Gtk::CheckButton* ckbmenuGroupLabel; + Gtk::CheckButton* ckbmenuGroupFileOperations; + Gtk::CheckButton* ckbmenuGroupProfileOperations; + Gtk::CheckButton* ckbmenuGroupExtProg; + + Gtk::Button* behAddAll; + Gtk::Button* behSetAll; + Gtk::CheckButton* chOverwriteOutputFile; + + Gtk::CheckButton* saveParamsFile; + Gtk::CheckButton* saveParamsCache; + Gtk::CheckButton* useBundledProfiles; + Gtk::ComboBoxText* loadParamsPreference; + Gtk::ComboBoxText* editorLayout; + RTWindow* parent; + + Gtk::CheckButton* ckbSndEnable; + Gtk::Entry* txtSndBatchQueueDone; + Gtk::Entry* txtSndLngEditProcDone; + Gtk::SpinButton* spbSndLngEditProcDoneSecs; + + Gtk::CheckButton* ckbTunnelMetaData; + Gtk::CheckButton* ckbInternalThumbIfUntouched; + + Gtk::Entry* txtCustProfBuilderPath; + Gtk::ComboBoxText* custProfBuilderLabelType; + + Gtk::CheckButton* ckbHistogramPositionLeft; + Gtk::CheckButton* ckbHistogramWorking; + Gtk::CheckButton* ckbFileBrowserToolbarSingleRow; + Gtk::CheckButton* ckbShowFilmStripToolBar; + Gtk::CheckButton* ckbHideTPVScrollbar; + Gtk::CheckButton* ckbUseIconNoText; + + Glib::ustring storedValueRaw; + Glib::ustring storedValueImg; + + Options moptions; + sigc::connection tconn, sconn, fconn, usethcon, addc, setc, dfconn, ffconn, bpconn, rpconn, ipconn; + sigc::connection autoMonProfileConn, sndEnableConn, langAutoDetectConn, autocielabConn; + Glib::ustring initialTheme; + Glib::ustring initialFont; + + bool oldSlimUI; + + void fillPreferences (); + void storePreferences (); + void parseDir (Glib::ustring dirname, std::vector& items, Glib::ustring ext); + void updateDFinfos (); + void updateFFinfos (); + void workflowUpdate(); + void themeChanged (); + void useThemeChanged(); + void fontChanged (); + void forRAWComboChanged (); + void forImageComboChanged (); + void layoutComboChanged (); + void bundledProfilesChanged(); + void switchThemeTo (Glib::ustring newTheme, bool slimInterface); + void switchFontTo (Glib::ustring newFont); + bool splashClosed(GdkEventAny* event); + + void appendBehavList (Gtk::TreeModel::iterator& parent, Glib::ustring label, int id, bool set); + + Gtk::Widget* getProcParamsPanel (); + Gtk::Widget* getColorManagementPanel (); + Gtk::Widget* getFileBrowserPanel (); + Gtk::Widget* getGeneralPanel (); + Gtk::Widget* getBatchProcPanel (); + Gtk::Widget* getPerformancePanel (); + Gtk::Widget* getSoundPanel (); + + public: + Preferences (RTWindow *rtwindow); + ~Preferences (); + + void savePressed (); + void loadPressed (); + void okPressed (); + void cancelPressed (); + void aboutPressed (); + void autoMonProfileToggled (); + void sndEnableToggled (); + void langAutoDetectToggled (); + void autocielabToggled (); + + void selectStartupDir (); + void addExtPressed (); + void delExtPressed (); + void darkFrameChanged (); + void flatFieldChanged (); + void clearProfilesPressed (); + void clearThumbImagesPressed (); + void clearAllPressed (); + + void behAddRadioToggled (const Glib::ustring& path); + void behSetRadioToggled (const Glib::ustring& path); + void behAddAllPressed (); + void behSetAllPressed (); + + virtual void storeCurrentValue(); + virtual void updateProfileList(); + virtual void restoreValue(); + +// void selectICCProfileDir (); +// void selectMonitorProfile (); +}; + +#endif diff --git a/rtgui/preprocess.cc b/rtgui/preprocess.cc new file mode 100644 index 000000000..187946740 --- /dev/null +++ b/rtgui/preprocess.cc @@ -0,0 +1,127 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "preprocess.h" +#include "guiutils.h" +#include "../rtengine/safegtk.h" +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +PreProcess::PreProcess () : FoldableToolPanel(this, "preprocess", M("TP_PREPROCESS_LABEL"), true) +{ + + Gtk::HBox* hotdeadPixel = Gtk::manage( new Gtk::HBox () ); + hotdeadPixel->set_spacing(4); + hotPixel = Gtk::manage(new Gtk::CheckButton((M("TP_PREPROCESS_HOTPIXFILT")))); + deadPixel = Gtk::manage(new Gtk::CheckButton((M("TP_PREPROCESS_DEADPIXFILT")))); + + hotPixel->set_tooltip_markup (M("TP_PREPROCESS_HOTPIXFILT_TOOLTIP")); + deadPixel->set_tooltip_markup (M("TP_PREPROCESS_DEADPIXFILT_TOOLTIP")); + + hotdeadPixel->pack_start( *hotPixel, Gtk::PACK_SHRINK); + hotdeadPixel->pack_start( *deadPixel, Gtk::PACK_SHRINK, 0); + pack_start(*hotdeadPixel, Gtk::PACK_SHRINK, 0); + hdThreshold = Gtk::manage (new Adjuster (M("TP_RAW_HD"),20,200,2,100)); + hdThreshold->set_tooltip_markup (M("TP_RAW_HD_TOOLTIP")); + hdThreshold->setAdjusterListener (this); + if (hdThreshold->delay < 1000) hdThreshold->delay = 1000; + hdThreshold->show(); + pack_start( *hdThreshold, Gtk::PACK_SHRINK, 4); + +// hotdeadPixel->show(); + hpixelconn = hotPixel->signal_toggled().connect ( sigc::mem_fun(*this, &PreProcess::hotPixelChanged), true); + dpixelconn = deadPixel->signal_toggled().connect ( sigc::mem_fun(*this, &PreProcess::deadPixelChanged), true); +} + +void PreProcess::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited) +{ + disableListener (); + hpixelconn.block (true); + dpixelconn.block (true); + if(pedited ){ + hotPixel->set_inconsistent (!pedited->raw.hotPixelFilter); + deadPixel->set_inconsistent (!pedited->raw.deadPixelFilter); + } + + lastHot = pp->raw.hotPixelFilter; + lastDead = pp->raw.deadPixelFilter; + hotPixel->set_active (pp->raw.hotPixelFilter); + deadPixel->set_active (pp->raw.deadPixelFilter); + hdThreshold->setValue (pp->raw.hotdeadpix_thresh); + hpixelconn.block (false); + dpixelconn.block (false); + enableListener (); +} + +void PreProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pedited) +{ + pp->raw.hotPixelFilter = hotPixel->get_active(); + pp->raw.deadPixelFilter = deadPixel->get_active(); + pp->raw.hotdeadpix_thresh = hdThreshold->getIntValue(); + if (pedited) { + pedited->raw.hotDeadPixelThresh = hdThreshold->getEditedState (); + pedited->raw.hotPixelFilter = !hotPixel->get_inconsistent(); + pedited->raw.deadPixelFilter = !deadPixel->get_inconsistent(); + } +} + +void PreProcess::adjusterChanged (Adjuster* a, double newval) +{ + if (listener) { + if (a == hdThreshold) + listener->panelChanged (EvPreProcessHotDeadThresh, a->getTextValue() ); + } +} + +void PreProcess::hotPixelChanged () +{ + if (batchMode) { + if (hotPixel->get_inconsistent()) { + hotPixel->set_inconsistent (false); + hpixelconn.block (true); + hotPixel->set_active (false); + hpixelconn.block (false); + } + else if (lastHot) + hotPixel->set_inconsistent (true); + + lastHot = hotPixel->get_active (); + } + if (listener) + listener->panelChanged (EvPreProcessHotPixel, hotPixel->get_active()?M("GENERAL_ENABLED"):M("GENERAL_DISABLED")); +} + +void PreProcess::deadPixelChanged () +{ + if (batchMode) { + if (deadPixel->get_inconsistent()) { + deadPixel->set_inconsistent (false); + dpixelconn.block (true); + deadPixel->set_active (false); + dpixelconn.block (false); + } + else if (lastDead) + deadPixel->set_inconsistent (true); + + lastDead = deadPixel->get_active (); + } + if (listener) + listener->panelChanged (EvPreProcessDeadPixel, deadPixel->get_active()?M("GENERAL_ENABLED"):M("GENERAL_DISABLED")); +} diff --git a/rtgui/preprocess.h b/rtgui/preprocess.h new file mode 100644 index 000000000..10d942c44 --- /dev/null +++ b/rtgui/preprocess.h @@ -0,0 +1,57 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _PREPROCESS_H_ +#define _PREPROCESS_H_ + +#include +//#include "adjuster.h" +#include "toolpanel.h" +#include "adjuster.h" +#include "guiutils.h" +#include "../rtengine/rawimage.h" + +class PreProcess : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel { + + protected: + Gtk::CheckButton* hotPixel; + Gtk::CheckButton* deadPixel; + bool lastHot,lastDead; + sigc::connection hpixelconn; + sigc::connection dpixelconn; + Adjuster* hdThreshold; + public: + + PreProcess (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + //void setBatchMode (bool batchMode); + //void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + + void hotPixelChanged(); + void deadPixelChanged(); + void adjusterChanged (Adjuster* a, double newval); + + + //void adjusterChanged (Adjuster* a, double newval); + //void setAdjusterBehavior (bool linedenoiseadd, bool greenequiladd); + //void trimValues (rtengine::procparams::ProcParams* pp); +}; + +#endif diff --git a/rtgui/previewhandler.cc b/rtgui/previewhandler.cc new file mode 100644 index 000000000..42b48b879 --- /dev/null +++ b/rtgui/previewhandler.cc @@ -0,0 +1,225 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "previewhandler.h" +#include +#include "../rtengine/rtengine.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +PreviewHandler::PreviewHandler () : image(NULL), previewScale(1.) { + + pih = new PreviewHandlerIdleHelper; + pih->phandler = this; + pih->destroyed = false; + pih->pending = 0; +} + +PreviewHandler::~PreviewHandler () { + + if (pih->pending) + pih->destroyed = true; + else + delete pih; +} + +//----------------previewimagelistener functions-------------------- + +struct iaimgpar { + IImage8* image; + PreviewHandlerIdleHelper* pih; + double scale; + CropParams cp; +}; + +int setImageUI (void* data) { + iaimgpar* iap = static_cast(data); + PreviewHandlerIdleHelper* pih = iap->pih; + + if (pih->destroyed) { + if (pih->pending == 1) + delete pih; + else + pih->pending--; + delete iap; + + return 0; + } + + if (pih->phandler->image) { + IImage8* oldImg = pih->phandler->image; + oldImg->getMutex().lock (); + pih->phandler->image = iap->image; + oldImg->getMutex().unlock (); + } + else + pih->phandler->image = iap->image; + + pih->phandler->cropParams = iap->cp; + pih->phandler->previewScale = iap->scale; + pih->pending--; + delete iap; + + return 0; +} + +void PreviewHandler::setImage (rtengine::IImage8* i, double scale, rtengine::procparams::CropParams cp) { + + pih->pending++; + + iaimgpar* iap = new iaimgpar; + iap->image = i; + iap->pih = pih; + iap->scale = scale; + iap->cp = cp; + + g_idle_add (setImageUI, iap); +} + + +int delImageUI (void* data) { + + iaimgpar* iap = static_cast(data); + PreviewHandlerIdleHelper* pih = iap->pih; + + if (pih->destroyed) { + if (pih->pending == 1) + delete pih; + else + pih->pending--; + delete iap; + + return 0; + } + + if (pih->phandler->image) { + IImage8* oldImg = pih->phandler->image; + oldImg->getMutex().lock (); + pih->phandler->image = NULL; + oldImg->getMutex().unlock (); + } + iap->image->free (); + pih->phandler->previewImgMutex.lock (); + pih->phandler->previewImg.clear (); + pih->phandler->previewImgMutex.unlock (); + + pih->pending--; + delete iap; + + return 0; +} + +void PreviewHandler::delImage (IImage8* i) { + + pih->pending++; + + iaimgpar* iap = new iaimgpar; + iap->image = i; + iap->pih = pih; + + g_idle_add (delImageUI, iap); +} + +int imageReadyUI (void* data) { + + iaimgpar* iap = static_cast(data); + PreviewHandlerIdleHelper* pih = iap->pih; + + if (pih->destroyed) { + if (pih->pending == 1) + delete pih; + else + pih->pending--; + delete iap; + + return 0; + } + + pih->phandler->previewImgMutex.lock (); + pih->phandler->previewImg = Gdk::Pixbuf::create_from_data (pih->phandler->image->getData(), Gdk::COLORSPACE_RGB, false, 8, pih->phandler->image->getWidth(), pih->phandler->image->getHeight(), 3*pih->phandler->image->getWidth()); + pih->phandler->previewImgMutex.unlock (); + pih->phandler->cropParams = iap->cp; + pih->phandler->previewImageChanged (); + pih->pending--; + delete iap; + + return 0; +} + +void PreviewHandler::imageReady (CropParams cp) { + + pih->pending++; + iaimgpar* iap = new iaimgpar; + iap->pih = pih; + iap->cp = cp; + g_idle_add (imageReadyUI, iap); +} + +Glib::RefPtr PreviewHandler::getRoughImage (int x, int y, int w, int h, double zoom) { + MyMutex::MyLock lock(previewImgMutex); + + Glib::RefPtr resPixbuf; + + if (previewImg) { + double totalZoom = zoom*previewScale; + if (w>previewImg->get_width()*totalZoom) + w = image->getWidth()*totalZoom; + if (h>previewImg->get_height()*totalZoom) + h = image->getHeight()*totalZoom; + int ix = x*zoom; + int iy = y*zoom; + if (ix<0) + ix = 0; + if (iy<0) + iy = 0; + if ((ix+w)/totalZoom>previewImg->get_width()) + ix = previewImg->get_width()*totalZoom - w; + if ((iy+h)/totalZoom>previewImg->get_height()) + iy = previewImg->get_height()*totalZoom - h; + + resPixbuf = Gdk::Pixbuf::create (Gdk::COLORSPACE_RGB, false, 8, w, h); + previewImg->scale (resPixbuf, 0, 0, w, h, -ix, -iy, totalZoom, totalZoom, Gdk::INTERP_NEAREST); + } + + return resPixbuf; +} + +Glib::RefPtr PreviewHandler::getRoughImage (int desiredW, int desiredH, double& zoom_) { + MyMutex::MyLock lock(previewImgMutex); + + Glib::RefPtr resPixbuf; + + if (previewImg) { + double zoom1 = (double)max(desiredW,20) / previewImg->get_width(); // too small values lead to extremely increased processing time in scale function, Issue 2783 + double zoom2 = (double)max(desiredH,20) / previewImg->get_height(); // "" + double zoom = zoom1getWidth()*zoom, image->getHeight()*zoom); + previewImg->scale (resPixbuf, 0, 0, previewImg->get_width()*zoom, previewImg->get_height()*zoom, 0, 0, zoom, zoom, Gdk::INTERP_BILINEAR); + zoom_ = zoom / previewScale; + } + + return resPixbuf; +} + +void PreviewHandler::previewImageChanged () { + + for (std::list::iterator i=listeners.begin(); i!=listeners.end(); i++) + (*i)->previewImageChanged (); +} diff --git a/rtgui/previewhandler.h b/rtgui/previewhandler.h new file mode 100644 index 000000000..8eaa0b3d7 --- /dev/null +++ b/rtgui/previewhandler.h @@ -0,0 +1,77 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _PREVIEWHANDLER_ +#define _PREVIEWHANDLER_ + +#include "../rtengine/rtengine.h" +#include "threadutils.h" +#include +#include + +class PreviewListener { + + public: + virtual ~PreviewListener () {} + virtual void previewImageChanged () {} +}; + +class PreviewHandler; +struct PreviewHandlerIdleHelper { + PreviewHandler* phandler; + bool destroyed; + int pending; +}; + +class PreviewHandler : public rtengine::PreviewImageListener { + + friend int setImageUI (void* data); + friend int delImageUI (void* data); + friend int imageReadyUI (void* data); + + protected: + rtengine::IImage8* image; + rtengine::procparams::CropParams cropParams; + double previewScale; + PreviewHandlerIdleHelper* pih; + std::list listeners; + MyMutex previewImgMutex; + Glib::RefPtr previewImg; + + public: + + PreviewHandler (); + virtual ~PreviewHandler (); + + void addPreviewImageListener (PreviewListener* l) { listeners.push_back (l); } + + // previewimagelistener + void setImage (rtengine::IImage8* img, double scale, rtengine::procparams::CropParams cp); + void delImage (rtengine::IImage8* img); + void imageReady (rtengine::procparams::CropParams cp); + + // this function is called when a new preview image arrives from rtengine + void previewImageChanged (); + + // with this function it is possible to ask for a rough approximation of a (possibly zoomed) crop of the image + Glib::RefPtr getRoughImage (int x, int y, int w, int h, double zoom); + Glib::RefPtr getRoughImage (int desiredW, int desiredH, double& zoom); + rtengine::procparams::CropParams getCropParams () { return cropParams; } +}; + +#endif diff --git a/rtgui/previewloader.cc b/rtgui/previewloader.cc new file mode 100755 index 000000000..0942f84ac --- /dev/null +++ b/rtgui/previewloader.cc @@ -0,0 +1,211 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "previewloader.h" +#include "guiutils.h" +#include "threadutils.h" +#include "../rtengine/safegtk.h" + +#ifdef _OPENMP +#include +#endif + +#define DEBUG(format,args...) +//#define DEBUG(format,args...) printf("PreviewLoader::%s: " format "\n", __FUNCTION__, ## args) + +class PreviewLoader::Impl +{ +public: + struct Job + { + Job(int dir_id, const Glib::ustring& dir_entry, PreviewLoaderListener* listener): + dir_id_(dir_id), + dir_entry_(dir_entry), + listener_(listener) + {} + + Job(): + dir_id_(0), + listener_(0) + {} + + int dir_id_; + Glib::ustring dir_entry_; + PreviewLoaderListener* listener_; + }; +/* Issue 2406 + struct OutputJob + { + bool complete; + int dir_id; + PreviewLoaderListener* listener; + FileBrowserEntry* fdn; + }; +*/ + struct JobCompare + { + bool operator()(const Job& lhs, const Job& rhs) + { + if ( lhs.dir_id_ == rhs.dir_id_ ) + { + return lhs.dir_entry_ < rhs.dir_entry_; + } + return lhs.dir_id_ < rhs.dir_id_; + } + }; + + typedef std::set JobSet; + + Impl():nConcurrentThreads(0) + { + int threadCount=2; + #ifdef _OPENMP + threadCount=omp_get_num_procs(); + #endif + + threadPool_=new Glib::ThreadPool(threadCount,0); + } + + Glib::ThreadPool* threadPool_; + MyMutex mutex_; + JobSet jobs_; + gint nConcurrentThreads; +// Issue 2406 std::vector output_; + + void processNextJob() + { + Job j; +// Issue 2406 OutputJob *oj; + { + MyMutex::MyLock lock(mutex_); + + // nothing to do; could be jobs have been removed + if ( jobs_.empty() ) + { + DEBUG("processing: nothing to do"); + return; + } + + // copy and remove front job + j = *jobs_.begin(); + jobs_.erase(jobs_.begin()); + DEBUG("processing %s",j.dir_entry_.c_str()); + DEBUG("%d job(s) remaining",jobs_.size()); +/* Issue 2406 + oj = new OutputJob(); + oj->complete = false; + oj->dir_id = j.dir_id_; + oj->listener = j.listener_; + oj->fdn = 0; + output_.push_back(oj); +*/ + } + + g_atomic_int_inc (&nConcurrentThreads); // to detect when last thread in pool has run out + + // unlock and do processing; will relock on block exit, then call listener + // if something got +// Issue 2406 FileBrowserEntry* fdn = 0; + try { + Thumbnail* tmb = 0; + { + if (safe_file_test(j.dir_entry_, Glib::FILE_TEST_EXISTS)) + { + tmb = cacheMgr->getEntry(j.dir_entry_); + } + } + if ( tmb ) + { + j.listener_->previewReady(j.dir_id_,new FileBrowserEntry(tmb,j.dir_entry_)); +// Issue 2406 fdn = new FileBrowserEntry(tmb,j.dir_entry_); + } + + } catch (Glib::Error &e){} catch(...){} +/* Issue 2406 + { + // the purpose of the output_ vector is to deliver the previewReady() calls in the same + // order as we got the jobs from the jobs_ queue. + MyMutex::MyLock lock(mutex_); + oj->fdn = fdn; + oj->complete = true; + while (output_.size() > 0 && output_.front()->complete) { + oj = output_.front(); + if (oj->fdn) { + oj->listener->previewReady(oj->dir_id,oj->fdn); + } + output_.erase(output_.begin()); + delete oj; + } + } +*/ + bool last = g_atomic_int_dec_and_test (&nConcurrentThreads); + + // signal at end + if (last && jobs_.empty()) j.listener_->previewsFinished(j.dir_id_); + } +}; + +PreviewLoader::PreviewLoader(): + impl_(new Impl()) +{ +} + +PreviewLoader* PreviewLoader::getInstance(void) +{ + // this will not be deleted... + static PreviewLoader* instance_ = NULL; + if ( instance_ == NULL ) + { + static MyMutex smutex_; + MyMutex::MyLock lock(smutex_); + + if ( instance_ == NULL ) instance_ = new PreviewLoader(); + } + + return instance_; +} + +void PreviewLoader::add(int dir_id, const Glib::ustring& dir_entry, PreviewLoaderListener* l) +{ + // somebody listening? + if ( l != 0 ) + { + { + MyMutex::MyLock lock(impl_->mutex_); + + // create a new job and append to queue + DEBUG("saving job %s",dir_entry.c_str()); + impl_->jobs_.insert(Impl::Job(dir_id,dir_entry,l)); + } + + // queue a run request + DEBUG("adding run request %s",dir_entry.c_str()); + impl_->threadPool_->push(sigc::mem_fun(*impl_, &PreviewLoader::Impl::processNextJob)); + } +} + +void PreviewLoader::removeAllJobs(void) +{ + DEBUG("stop %d",impl_->nConcurrentThreads); + MyMutex::MyLock lock(impl_->mutex_); + impl_->jobs_.clear(); +} + + diff --git a/rtgui/previewloader.h b/rtgui/previewloader.h new file mode 100644 index 000000000..09892825c --- /dev/null +++ b/rtgui/previewloader.h @@ -0,0 +1,93 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _PREVIEWLOADER_ +#define _PREVIEWLOADER_ + +#include +#include +#include "filebrowserentry.h" + +class PreviewLoaderListener +{ +public: + + /** + * @brief a preview is ready + * + * @param dir_id directory ID this is for + * @param fd entry + */ + virtual void previewReady (int dir_id, FileBrowserEntry* fd) {} + + /** + * @brief all previews have finished loading + */ + virtual void previewsFinished (int dir_id_) {} +}; + +class PreviewLoader +{ + public: + + /** + * @brief Singleton entry point. + * + * @note expects to be called inside gtk thread lock + * + * @return Pointer to thumbnail image updater. + */ + static PreviewLoader* getInstance(void); + + /** + * @brief Add an thumbnail image update request. + * + * Code will add the request to the queue and, if needed, start a pool + * thread to process it. + * + * @param dir_id directory we're looking at + * @param dir_entry entry in it + * @param l listener + */ + void add(int dir_id, const Glib::ustring& dir_entry, PreviewLoaderListener* l); + + /** + * @brief Stop processing and remove all jobs. + * + * Will not return till all jobs have completed. + * + * @note expects to be called inside gtk thread lock + */ + void removeAllJobs(void); + + private: + + PreviewLoader(); + + class Impl; + Impl* impl_; +}; + +/** + * @brief Singleton boiler plate. + * + * To use: \c previewLoader->start() , + */ +#define previewLoader PreviewLoader::getInstance() + +#endif diff --git a/rtgui/previewmodepanel.cc b/rtgui/previewmodepanel.cc new file mode 100644 index 000000000..10225c22d --- /dev/null +++ b/rtgui/previewmodepanel.cc @@ -0,0 +1,253 @@ +/* + * This file is part of RawTherapee. + * + * + * 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 "previewmodepanel.h" +#include "options.h" +#include "multilangmgr.h" +#include "imagearea.h" +#include "rtimage.h" + +PreviewModePanel::PreviewModePanel (ImageArea* ia) : imageArea(ia) { + + iR = new RTImage ("previewmodeR-on.png"); + 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"); + + 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"); + + backColor0 = Gtk::manage (new Gtk::ToggleButton ()); + backColor0->set_relief(Gtk::RELIEF_NONE); + backColor0->set_tooltip_markup (M("MAIN_TOOLTIP_BACKCOLOR0")); + backColor0->set_image(options.bgcolor==0?*iBC0:*igBC0); + + backColor1 = Gtk::manage (new Gtk::ToggleButton ()); + backColor1->set_relief(Gtk::RELIEF_NONE); + backColor1->set_tooltip_markup (M("MAIN_TOOLTIP_BACKCOLOR1")); + backColor1->set_image(options.bgcolor==1?*iBC1:*igBC1); + + backColor2 = Gtk::manage (new Gtk::ToggleButton ()); + backColor2->set_relief(Gtk::RELIEF_NONE); + backColor2->set_tooltip_markup (M("MAIN_TOOLTIP_BACKCOLOR2")); + backColor2->set_image(options.bgcolor==2?*iBC2:*igBC2); + + previewR = Gtk::manage (new Gtk::ToggleButton ()); + previewR->set_relief(Gtk::RELIEF_NONE); + previewR->set_tooltip_markup (M("MAIN_TOOLTIP_PREVIEWR")); + previewR->set_image(*igR); + + previewG = Gtk::manage (new Gtk::ToggleButton ()); + previewG->set_relief(Gtk::RELIEF_NONE); + previewG->set_tooltip_markup (M("MAIN_TOOLTIP_PREVIEWG")); + previewG->set_image(*igG); + + previewB = Gtk::manage (new Gtk::ToggleButton ()); + previewB->set_relief(Gtk::RELIEF_NONE); + previewB->set_tooltip_markup (M("MAIN_TOOLTIP_PREVIEWB")); + previewB->set_image(*igB); + + previewL = Gtk::manage (new Gtk::ToggleButton ()); + previewL->set_relief(Gtk::RELIEF_NONE); + 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?true:false); + backColor1->set_active (options.bgcolor==1?true:false); + backColor2->set_active (options.bgcolor==2?true:false); + + vbbackColor = Gtk::manage (new Gtk::VBox ()); + vbbackColor->set_border_width (0); + 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 (*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) ); + + //show_all (); +} + +PreviewModePanel::~PreviewModePanel (){ + delete iR; + delete iG; + delete iB; + delete iL; + delete iF; + delete iBC0; + delete iBC1; + delete iBC2; + delete igR; + delete igG; + delete igB; + delete igL; + delete igF; + delete igBC0; + delete igBC1; + delete igBC2; +} +//toggle Functions below are for shortcuts +void PreviewModePanel::toggleR () { + previewR->set_active(!previewR->get_active()); +} +void PreviewModePanel::toggleG () { + previewG->set_active(!previewG->get_active()); +} +void PreviewModePanel::toggleB () { + previewB->set_active(!previewB->get_active()); +} +void PreviewModePanel::toggleL () { + previewL->set_active(!previewL->get_active()); +} +void PreviewModePanel::toggleFocusMask () { + previewFocusMask->set_active(!previewFocusMask->get_active()); +} + +void PreviewModePanel::togglebackColor0 () { + backColor0->set_active(!backColor0->get_active()); +} +void PreviewModePanel::togglebackColor1 () { + backColor1->set_active(!backColor1->get_active()); +} +void PreviewModePanel::togglebackColor2 () { + backColor2->set_active(!backColor2->get_active()); +} + +void PreviewModePanel::buttonToggled (Gtk::ToggleButton* tbpreview) { + + connR.block(true); + 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 + if (tbpreview!=previewR) previewR->set_active(false); + if (tbpreview!=previewG) previewG->set_active(false); + if (tbpreview!=previewB) previewB->set_active(false); + if (tbpreview!=previewL) 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 (); + + // this will redraw the linked Before image area + // which is set when before/after view is enabled + if (imageArea->iLinkedImageArea!=NULL) + imageArea->iLinkedImageArea->queue_draw (); +} + +int PreviewModePanel::GetbackColor(){ + int backColor; + if (backColor0->get_active ()) backColor=0; + if (backColor1->get_active ()) backColor=1; + if (backColor2->get_active ()) backColor=2; + + return backColor; +} + +void PreviewModePanel::togglebackColor(){ + int backColor = GetbackColor(); + if(backColor == 0) + togglebackColor1(); + else if(backColor == 1) + togglebackColor2(); + else + togglebackColor0(); +} + +void PreviewModePanel::buttonToggled_backColor (Gtk::ToggleButton* tbbackColor) { + + connbackColor0.block(true); + connbackColor1.block(true); + connbackColor2.block(true); + + // control the state of the buttons + // Exactly 1 button at a time must remain pressed + if (tbbackColor==backColor0 && !backColor0->get_active()) backColor0->set_active(true); + if (tbbackColor==backColor1 && !backColor1->get_active()) backColor1->set_active(true); + if (tbbackColor==backColor2 && !backColor2->get_active()) backColor2->set_active(true); + + if (tbbackColor!=backColor0) backColor0->set_active(false); + if (tbbackColor!=backColor1) backColor1->set_active(false); + if (tbbackColor!=backColor2) backColor2->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); + + connbackColor0.block(false); + connbackColor1.block(false); + connbackColor2.block(false); + + //TODO not sure if queue_draw is necessary, but will need to reach to backColor of the Before view + imageArea->queue_draw (); + + // this will redraw the linked Before image area + // which is set when before/after view is enabled + if (imageArea->iLinkedImageArea!=NULL) + imageArea->iLinkedImageArea->queue_draw (); +} diff --git a/rtgui/previewmodepanel.h b/rtgui/previewmodepanel.h new file mode 100644 index 000000000..38292c95d --- /dev/null +++ b/rtgui/previewmodepanel.h @@ -0,0 +1,76 @@ +/* + * This file is part of RawTherapee. + * + * + * 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 _PREVIEWMODEPANEL_ +#define _PREVIEWMODEPANEL_ + +#include +#include "adjuster.h"//dev + +class ImageArea; +class PreviewModePanel : public Gtk::HBox { + + protected: + Gtk::ToggleButton* previewR; + Gtk::ToggleButton* previewG; + Gtk::ToggleButton* previewB; + Gtk::ToggleButton* previewL; + Gtk::ToggleButton* previewFocusMask; + Gtk::ToggleButton* backColor0; + Gtk::ToggleButton* backColor1; + Gtk::ToggleButton* backColor2; + Gtk::VBox* vbbackColor; + 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; + + public: + PreviewModePanel (ImageArea* ia); + ~PreviewModePanel(); + + void toggleR (); + void toggleG (); + void toggleB (); + void toggleL (); + void toggleFocusMask (); + void togglebackColor0(); + void togglebackColor1(); + void togglebackColor2(); + void togglebackColor(); + + sigc::connection connR, connB, connG, connL, connFocusMask, connbackColor0, connbackColor1, connbackColor2; + + void buttonToggled(Gtk::ToggleButton* tbpreview); + void buttonToggled_backColor(Gtk::ToggleButton* tbbackColor); + + bool showR () { return previewR->get_active (); } + bool showG () { return previewG->get_active (); } + bool showB () { return previewB->get_active (); } + bool showL () { return previewL->get_active (); } + bool showFocusMask () { return previewFocusMask->get_active (); } + int GetbackColor(); + +}; + +#endif diff --git a/rtgui/previewwindow.cc b/rtgui/previewwindow.cc new file mode 100644 index 000000000..6038bb018 --- /dev/null +++ b/rtgui/previewwindow.cc @@ -0,0 +1,221 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "previewwindow.h" +#include "guiutils.h" +#include "imagearea.h" +#include "cursormanager.h" + +PreviewWindow::PreviewWindow () : previewHandler(NULL), mainCropWin(NULL), imageArea(NULL), imgX(0), imgY(0), imgW(0), imgH(0), zoom(0.0), isMoving(false), needsUpdate(false) { + + rconn = signal_size_allocate().connect( sigc::mem_fun(*this, &PreviewWindow::on_resized) ); +} + +void PreviewWindow::on_realize () { + + Gtk::DrawingArea::on_realize (); + add_events(Gdk::EXPOSURE_MASK | Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::SCROLL_MASK); +} + +void PreviewWindow::getObservedFrameArea (int& x, int& y, int& w, int& h) { + + if (mainCropWin) { + int cropX, cropY, cropW, cropH; + mainCropWin->getCropRectangle (cropX, cropY, cropW, cropH); + // translate it to screen coordinates + x = imgX + round(cropX*zoom); + y = imgY + round(cropY*zoom); + w = round(cropW * zoom); + h = round(cropH * zoom); + } +} + +void PreviewWindow::updatePreviewImage () { + + int W = get_width(), H = get_height(); + Glib::RefPtr wind = get_window(); + if( ! wind ) { + needsUpdate = true; + return; + } + backBuffer = Gdk::Pixmap::create (wind, W, H, -1); + backBuffer->draw_rectangle (get_style()->get_base_gc(Gtk::STATE_NORMAL), true, 0, 0, W, H); + if (previewHandler) { + Glib::RefPtr resPixbuf = previewHandler->getRoughImage (W, H, zoom); + if (resPixbuf) { + imgW = resPixbuf->get_width(); + imgH = resPixbuf->get_height(); + imgX = (W-imgW)/2; + imgY = (H-imgH)/2; + backBuffer->draw_pixbuf (get_style()->get_base_gc(Gtk::STATE_NORMAL), resPixbuf, 0, 0, imgX, imgY, -1, -1, Gdk::RGB_DITHER_NONE, 0, 0); + Cairo::RefPtr cr = backBuffer->create_cairo_context(); + if (previewHandler->getCropParams().enabled) + drawCrop (cr, imgX, imgY, imgW, imgH, 0, 0, zoom, previewHandler->getCropParams(), true, false); + } + } +} + +void PreviewWindow::setPreviewHandler (PreviewHandler* ph) { + + previewHandler = ph; + if (previewHandler) + previewHandler->addPreviewImageListener (this); +} + +void PreviewWindow::on_resized (Gtk::Allocation& req) { + + updatePreviewImage (); + queue_draw (); +} + +bool PreviewWindow::on_expose_event (GdkEventExpose* event) { + + if (backBuffer) { + Glib::RefPtr window = get_window(); + + int bufferW, bufferH; + backBuffer->get_size (bufferW, bufferH); + + if (!mainCropWin && imageArea) { + mainCropWin = imageArea->getMainCropWindow (); + if (mainCropWin) + mainCropWin->addCropWindowListener (this); + } + + if ((get_width()!=bufferW && get_height()!=bufferH) || needsUpdate) { + needsUpdate = false; + updatePreviewImage (); + } + window->draw_drawable (get_style()->get_base_gc(Gtk::STATE_NORMAL), backBuffer, 0, 0, 0, 0, -1, -1); + + if (mainCropWin && zoom > 0.0) { + if(mainCropWin->getZoom() > mainCropWin->cropHandler.getFitZoom()) { + Cairo::RefPtr cr = get_window()->create_cairo_context(); + int x, y, w, h; + getObservedFrameArea (x, y, w, h); + double rectX = x + 0.5; + double rectY = y + 0.5; + double rectW = std::min(w, (int)(imgW - (x-imgX) - 1)); + double rectH = std::min(h, (int)(imgH - (y-imgY) - 1)); + + // draw a black "shadow" line + cr->set_source_rgba (0.0, 0.0, 0.0, 0.65); + cr->set_line_width (1); + cr->rectangle (rectX+1., rectY+1, rectW, rectH); + cr->stroke (); + + // draw a "frame" line. Color of frame line can be set in preferences + cr->set_source_rgba(options.navGuideBrush[0], options.navGuideBrush[1], options.navGuideBrush[2], options.navGuideBrush[3]); //( 1.0, 1.0, 1.0, 1.0); + cr->rectangle (rectX, rectY, rectW, rectH); + cr->stroke (); + } + } + } + return true; +} + +void PreviewWindow::previewImageChanged () { + + updatePreviewImage (); + queue_draw (); +} + +void PreviewWindow::setImageArea (ImageArea* ia) { + + imageArea = ia; + mainCropWin = ia->getMainCropWindow (); + if (mainCropWin) + mainCropWin->addCropWindowListener (this); +} + +void PreviewWindow::cropPositionChanged (CropWindow* w) { + + queue_draw (); +} + +void PreviewWindow::cropWindowSizeChanged (CropWindow* w) { + + queue_draw (); +} + +void PreviewWindow::cropZoomChanged (CropWindow* w) { + + queue_draw (); +} + +bool PreviewWindow::on_motion_notify_event (GdkEventMotion* event) { + + if (!mainCropWin) + return true; + + if(mainCropWin->getZoom() > mainCropWin->cropHandler.getFitZoom()) { + int x, y, w, h; + getObservedFrameArea (x, y, w, h); + bool inside = event->x > x-6 && event->x < x+w-1+6 && event->y > y-6 && event->y < y+h-1+6; + bool moreInside = event->x > x+6 && event->x < x+w-1-6 && event->y > y+6 && event->y < y+h-1-6; + + if (isMoving) + mainCropWin->remoteMove ((event->x - press_x)/zoom, (event->y - press_y)/zoom); + else if (inside && !moreInside) + cursorManager.setCursor (get_window(), CSClosedHand); + else + cursorManager.setCursor (get_window(), CSArrow); + } + return true; +} + +bool PreviewWindow::on_button_press_event (GdkEventButton* event) { + + if (!mainCropWin) + return true; + + if(mainCropWin->getZoom() > mainCropWin->cropHandler.getFitZoom()) { + int x, y, w, h; + getObservedFrameArea (x, y, w, h); + bool inside = event->x > x-6 && event->x < x+w-1+6 && event->y > y-6 && event->y < y+h-1+6; + bool moreInside = event->x > x+6 && event->x < x+w-1-6 && event->y > y+6 && event->y < y+h-1-6; + + if (!isMoving) { + isMoving = true; + if (!inside || moreInside) { + mainCropWin->remoteMove ((event->x - (x+w/2))/zoom, (event->y - (y+h/2))/zoom); + press_x = x+w/2; + press_y = y+h/2; + } + else { + press_x = event->x; + press_y = event->y; + } + cursorManager.setCursor (get_window(), CSClosedHand); + } + } + return true; +} + +bool PreviewWindow::on_button_release_event (GdkEventButton* event) { + + if (!mainCropWin) + return true; + + if (isMoving) { + isMoving = false; + cursorManager.setCursor (get_window(), CSArrow); + mainCropWin->remoteMoveReady (); + } + return true; +} diff --git a/rtgui/previewwindow.h b/rtgui/previewwindow.h new file mode 100644 index 000000000..bedfc3abf --- /dev/null +++ b/rtgui/previewwindow.h @@ -0,0 +1,65 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _PREVIEWWINDOW_ +#define _PREVIEWWINDOW_ + +#include +#include "previewhandler.h" +#include "cropwindow.h" + +class PreviewWindow : public Gtk::DrawingArea, public PreviewListener, public CropWindowListener { + + private: + Glib::RefPtr backBuffer; + PreviewHandler* previewHandler; + sigc::connection rconn; + CropWindow* mainCropWin; + ImageArea* imageArea; + int imgX, imgY, imgW, imgH; + double zoom; + int press_x, press_y; + bool isMoving; + bool needsUpdate; + + void updatePreviewImage (); + void getObservedFrameArea (int& x, int& y, int& w, int& h); + + public: + PreviewWindow (); + + void setPreviewHandler (PreviewHandler* ph); + void setImageArea (ImageArea* ia); + + void on_realize (); + void on_resized (Gtk::Allocation& req); + bool on_expose_event (GdkEventExpose* event); + bool on_motion_notify_event (GdkEventMotion* event); + bool on_button_press_event (GdkEventButton* event); + bool on_button_release_event(GdkEventButton* event); + + // PreviewListener interface + void previewImageChanged (); + + // CropWindowListener interface + void cropPositionChanged (CropWindow* w); + void cropWindowSizeChanged (CropWindow* w); + void cropZoomChanged (CropWindow* w); +}; + +#endif diff --git a/rtgui/procparamchangers.h b/rtgui/procparamchangers.h new file mode 100644 index 000000000..759babefc --- /dev/null +++ b/rtgui/procparamchangers.h @@ -0,0 +1,24 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#define UNKNOWN -1 +#define FILEBROWSER 1 +#define EDITOR 2 +#define BATCHEDITOR 3 +#define CACHEMGR 4 +#define SAFETYUPDATE 5 diff --git a/rtgui/profilechangelistener.h b/rtgui/profilechangelistener.h new file mode 100644 index 000000000..b2673391a --- /dev/null +++ b/rtgui/profilechangelistener.h @@ -0,0 +1,43 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _PROFILECHANGELISTENER_ +#define _PROFILECHANGELISTENER_ + +#include "../rtengine/rtengine.h" +#include + +class ProfileChangeListener { + + public: + virtual ~ProfileChangeListener() {} + virtual void profileChange (const rtengine::procparams::PartialProfile* nparams, rtengine::ProcEvent event, const Glib::ustring& descr, const ParamsEdited* paramsEdited=NULL) {} + virtual void setDefaults (rtengine::procparams::ProcParams* defparams) {} +}; + +class BatchProfileChangeListener { + + public: + virtual ~BatchProfileChangeListener() {} + virtual void beginBatchProfileChange(int numberOfEntries) {} + virtual void endBatchProfileChange() {} +}; + + +#endif + diff --git a/rtgui/profilepanel.cc b/rtgui/profilepanel.cc new file mode 100644 index 000000000..d043892be --- /dev/null +++ b/rtgui/profilepanel.cc @@ -0,0 +1,700 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "profilepanel.h" +#include "options.h" +#include "profilestore.h" +#include "clipboard.h" +#include "multilangmgr.h" +#include "../rtengine/safegtk.h" +#include "rtimage.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +PartialPasteDlg* ProfilePanel::partialProfileDlg; + + +void ProfilePanel::init () { + partialProfileDlg = new PartialPasteDlg("Foo"); +} + +void ProfilePanel::cleanup () { + delete partialProfileDlg; +} + +ProfilePanel::ProfilePanel (bool readOnly) : storedPProfile(NULL), lastFilename(""), imagePath("") { + + tpc = NULL; + + profileFillModeOnImage = new RTImage("profile-filled.png"); + profileFillModeOffImage = new RTImage("profile-partial.png"); + fillMode = Gtk::manage (new Gtk::ToggleButton()); + fillMode->set_active(options.filledProfile); + fillMode->add( options.filledProfile ? *profileFillModeOnImage : *profileFillModeOffImage ); + fillMode->signal_toggled().connect ( sigc::mem_fun(*this, &ProfilePanel::profileFillModeToggled) ); + fillMode->set_tooltip_text(M("PROFILEPANEL_MODE_TIP")); + + // Create the Combobox + profiles = Gtk::manage (new ProfileStoreComboBox ()); + + Gtk::HBox* hbox = Gtk::manage (new Gtk::HBox ()); + hbox->show (); +// pack_start (*profiles, Gtk::PACK_SHRINK, 4); + + pack_start (*hbox, Gtk::PACK_SHRINK, 4); + + load = Gtk::manage (new Gtk::Button ()); + load->add (*Gtk::manage (new RTImage ("gtk-open.png"))); + if (!readOnly) save = Gtk::manage (new Gtk::Button ()); + if (!readOnly) save->add (*Gtk::manage (new RTImage ("gtk-save-large.png"))); + if (!readOnly) copy = Gtk::manage (new Gtk::Button ()); + if (!readOnly) copy->add (*Gtk::manage (new RTImage ("edit-copy.png"))); + paste = Gtk::manage (new Gtk::Button ()); + paste->add (*Gtk::manage (new RTImage ("edit-paste.png"))); + + hbox->pack_start (*fillMode, Gtk::PACK_SHRINK, 1); + hbox->pack_start (*profiles); + hbox->pack_start (*load, Gtk::PACK_SHRINK, 1); + if (!readOnly) hbox->pack_start (*save, Gtk::PACK_SHRINK, 1); + hbox->pack_start (*copy, Gtk::PACK_SHRINK, 1); + if (!readOnly) hbox->pack_start (*paste, Gtk::PACK_SHRINK, 1); + + load->signal_button_release_event().connect_notify( sigc::mem_fun(*this, &ProfilePanel::load_clicked) ); + if (!readOnly) save->signal_button_release_event().connect_notify( sigc::mem_fun(*this, &ProfilePanel::save_clicked) ); + if (!readOnly) copy->signal_button_release_event().connect_notify( sigc::mem_fun(*this, &ProfilePanel::copy_clicked) ); + paste->signal_button_release_event().connect_notify( sigc::mem_fun(*this, &ProfilePanel::paste_clicked) ); + + custom = NULL; + lastsaved = NULL; + dontupdate = false; + + profileStore.addListener(this); + + changeconn = profiles->signal_changed().connect( sigc::mem_fun(*this, &ProfilePanel::selection_changed) ); + + load->set_tooltip_markup (M("PROFILEPANEL_TOOLTIPLOAD")); + if (!readOnly) save->set_tooltip_markup (M("PROFILEPANEL_TOOLTIPSAVE")); + if (!readOnly) copy->set_tooltip_markup (M("PROFILEPANEL_TOOLTIPCOPY")); + paste->set_tooltip_markup (M("PROFILEPANEL_TOOLTIPPASTE")); + + show_all_children (); +} + +ProfilePanel::~ProfilePanel () { + + profileStore.removeListener(this); + if (custom) { custom->deleteInstance(); delete custom; } + if (lastsaved) { lastsaved->deleteInstance(); delete lastsaved; } + delete profileFillModeOnImage; + delete profileFillModeOffImage; +} + +bool ProfilePanel::isCustomSelected() { + if (profiles->getCurrentLabel() == Glib::ustring ("(" + M("PROFILEPANEL_PCUSTOM") + ")")) + return true; + return false; +} + +bool ProfilePanel::isLastSavedSelected() { + if (profiles->getCurrentLabel() == Glib::ustring ("(" + M("PROFILEPANEL_PLASTSAVED") + ")")) + return true; + return false; +} + +Gtk::TreeIter ProfilePanel::getCustomRow() { + Gtk::TreeIter row; + if (custom) + row = profiles->getRowFromLabel(Glib::ustring ("(" + M("PROFILEPANEL_PCUSTOM") + ")")); + return row; +} + +Gtk::TreeIter ProfilePanel::getLastSavedRow() { + Gtk::TreeIter row; + if (lastsaved) { + row = profiles->getRowFromLabel(Glib::ustring ("(" + M("PROFILEPANEL_PLASTSAVED") + ")")); + } + return row; +} + +Gtk::TreeIter ProfilePanel::addCustomRow() { + const ProfileStoreEntry *customPSE = new ProfileStoreEntry(Glib::ustring ("(" + M("PROFILEPANEL_PCUSTOM") + ")"), PSET_FILE, 0, 0); + Gtk::TreeIter newEntry = profiles->addRow(customPSE); + return newEntry; +} + +Gtk::TreeIter ProfilePanel::addLastSavedRow() { + const ProfileStoreEntry *lastSavedPSE = new ProfileStoreEntry(Glib::ustring ("(" + M("PROFILEPANEL_PLASTSAVED") + ")"), PSET_FILE, 0, 0); + Gtk::TreeIter newEntry = profiles->addRow(lastSavedPSE); + return newEntry; +} + +void ProfilePanel::storeCurrentValue () { + // TODO: Find a way to get and restore the current selection; the following line can't work anymore + storedValue = profiles->getFullPathFromActiveRow(); + if (!isCustomSelected() && !isLastSavedSelected()) { + // storing the current entry's procparams, if not "Custom" or "LastSaved" + + // for now, the storedPProfile has default internal values + const ProfileStoreEntry *entry = profiles->getSelectedEntry(); + const PartialProfile *currProfile; + if (entry && (currProfile = profileStore.getProfile(entry))!=NULL) { + // now storedPProfile has the current entry's values + storedPProfile = new PartialProfile(currProfile->pparams, currProfile->pedited, true); + } + else + storedPProfile = new PartialProfile(true); + } +} + +/* Get the ProfileStore's entry list and recreate the combobox entries + * If you want want to update the ProfileStore list itself (rescan the dir tree), use its "parseProfiles" method instead + */ +void ProfilePanel::updateProfileList () { + + bool ccPrevState = changeconn.block(true); + + // rescan file tree + profiles->updateProfileList(); + + if (custom) + addCustomRow(); + + if (lastsaved) + addLastSavedRow(); + + changeconn.block (ccPrevState); +} + +void ProfilePanel::restoreValue () { + bool ccPrevState = changeconn.block(true); + + if (!profiles->setActiveRowFromFullPath(storedValue) && storedPProfile) { + if (custom) delete custom; + custom = new PartialProfile (storedPProfile->pparams, storedPProfile->pedited, true); + Gtk::TreeIter custRow = getCustomRow(); + if (custRow) + profiles->set_active(custRow); + else + profiles->set_active (addCustomRow()); + } + + currRow = profiles->get_active(); + + changeconn.block (ccPrevState); + + storedValue = ""; + + if (storedPProfile) { + storedPProfile->deleteInstance(); + delete storedPProfile; + storedPProfile = NULL; + } +} + +void ProfilePanel::save_clicked (GdkEventButton* event) { + + if (event->button != 1) + return; + + Gtk::FileChooserDialog dialog(M("PROFILEPANEL_SAVEDLGLABEL"), Gtk::FILE_CHOOSER_ACTION_SAVE); + FileChooserLastFolderPersister persister( &dialog, options.loadSaveProfilePath ); + dialog.set_current_name (lastFilename); + + //Add the user's default (or global if multiuser=false) profile path to the Shortcut list +#ifdef WIN32 + // Dirty workaround, waiting for a clean solution by using exceptions! + if (!safe_is_shortcut_dir(options.getPreferredProfilePath())) +#endif + try { + dialog.add_shortcut_folder(options.getPreferredProfilePath()); + } + catch (Glib::Error &err) {} + //Add the image's path to the Shortcut list +#ifdef WIN32 + // Dirty workaround, waiting for a clean solution by using exceptions! + if (!safe_is_shortcut_dir(imagePath)) +#endif + try { + dialog.add_shortcut_folder(imagePath); + } + catch (Glib::Error &err) {} + + //Add response buttons the the dialog: + dialog.add_button(Gtk::StockID("gtk-cancel"), Gtk::RESPONSE_CANCEL); + dialog.add_button(Gtk::StockID("gtk-save"), Gtk::RESPONSE_OK); + + //Add filters, so that only certain file types can be selected: + + Gtk::FileFilter filter_pp; + filter_pp.set_name(M("FILECHOOSER_FILTER_PP")); + filter_pp.add_pattern("*"+paramFileExtension); + dialog.add_filter(filter_pp); + + Gtk::FileFilter filter_any; + filter_any.set_name(M("FILECHOOSER_FILTER_ANY")); + filter_any.add_pattern("*"); + dialog.add_filter(filter_any); + +// dialog.set_do_overwrite_confirmation (true); + + bool done = false; + do { + if (dialog.run()==Gtk::RESPONSE_OK) { + + std::string fname = dialog.get_filename(); + Glib::ustring ext = getExtension (fname); + + if (("." + ext) != paramFileExtension) + fname += paramFileExtension; + + if (!confirmOverwrite (dialog, fname)) + continue; + + lastFilename = Glib::path_get_basename (fname); + + const PartialProfile* toSave; + if (isCustomSelected()) + toSave = custom; + else if (isLastSavedSelected()) + toSave = lastsaved; + else { + const ProfileStoreEntry* entry = profiles->getSelectedEntry(); + toSave = entry ? profileStore.getProfile (profiles->getSelectedEntry()) : NULL; + } + + if (toSave) { + if (event->state & Gdk::CONTROL_MASK) { + // opening the partial paste dialog window + partialProfileDlg->set_title(M("PROFILEPANEL_SAVEPPASTE")); + int i = partialProfileDlg->run(); + partialProfileDlg->hide(); + if (i != Gtk::RESPONSE_OK) + return; + + // saving the partial profile + PartialProfile ppTemp(true); + partialProfileDlg->applyPaste (ppTemp.pparams, ppTemp.pedited, toSave->pparams, toSave->pedited); + int retCode = ppTemp.pparams->save (fname, "", true, ppTemp.pedited); + ppTemp.deleteInstance(); + if (retCode) + writeFailed(dialog, fname); + else { + done=true; + bool ccPrevState = changeconn.block(true); + profileStore.parseProfiles(); + changeconn.block (ccPrevState); + } + } + else { + // saving a full profile + int retCode = toSave->pparams->save (fname); + if (retCode) + writeFailed(dialog, fname); + else { + done=true; + bool ccPrevState = changeconn.block(true); + profileStore.parseProfiles(); + changeconn.block (ccPrevState); + } + } + } + else done = true; + } + else done = true; + } while (!done); + return; +} + +/* + * Copy the actual full profile to the clipboard + */ +void ProfilePanel::copy_clicked (GdkEventButton* event) { + + if (event->button != 1) + return; + + const PartialProfile* toSave; + if (isCustomSelected()) + toSave = custom; + else if (isLastSavedSelected()) + toSave = lastsaved; + else { + const ProfileStoreEntry* entry = profiles->getSelectedEntry(); + toSave = entry ? profileStore.getProfile (entry) : NULL; + } + + // toSave has to be a complete procparams + if (toSave) { + if (event->state & Gdk::CONTROL_MASK) { + // opening the partial paste dialog window + partialProfileDlg->set_title(M("PROFILEPANEL_COPYPPASTE")); + int i = partialProfileDlg->run(); + partialProfileDlg->hide(); + if (i != Gtk::RESPONSE_OK) + return; + + // saving a partial profile + PartialProfile ppTemp(true); + partialProfileDlg->applyPaste (ppTemp.pparams, ppTemp.pedited, toSave->pparams, toSave->pedited); + clipboard.setPartialProfile(ppTemp); + ppTemp.deleteInstance(); + } + else + clipboard.setProcParams (*toSave->pparams); + } + return; +} + +/* + * Load a potentially partial profile + */ +void ProfilePanel::load_clicked (GdkEventButton* event) { + + if (event->button != 1) + return; + + Gtk::FileChooserDialog dialog(M("PROFILEPANEL_LOADDLGLABEL"), Gtk::FILE_CHOOSER_ACTION_OPEN); + FileChooserLastFolderPersister persister( &dialog, options.loadSaveProfilePath ); + + //Add the user's default (or global if multiuser=false) profile path to the Shortcut list +#ifdef WIN32 + // Dirty workaround, waiting for a clean solution by using exceptions! + if (!safe_is_shortcut_dir(options.getPreferredProfilePath())) +#endif + try { + dialog.add_shortcut_folder(options.getPreferredProfilePath()); + } + catch (Glib::Error &err) {} + + //Add the image's path to the Shortcut list +#ifdef WIN32 + // Dirty workaround, waiting for a clean solution by using exceptions! + if (!safe_is_shortcut_dir(imagePath)) +#endif + try { + dialog.add_shortcut_folder(imagePath); + } + catch (Glib::Error &err) {} + + //Add response buttons the the dialog: + dialog.add_button(Gtk::StockID("gtk-cancel"), Gtk::RESPONSE_CANCEL); + dialog.add_button(Gtk::StockID("gtk-open"), Gtk::RESPONSE_OK); + + //Add filters, so that only certain file types can be selected: + + Gtk::FileFilter filter_pp; + filter_pp.set_name(M("FILECHOOSER_FILTER_PP")); + filter_pp.add_pattern("*"+paramFileExtension); + dialog.add_filter(filter_pp); + + Gtk::FileFilter filter_any; + filter_any.set_name(M("FILECHOOSER_FILTER_ANY")); + filter_any.add_pattern("*"); + dialog.add_filter(filter_any); + + int result = dialog.run(); + dialog.hide(); + + if (result==Gtk::RESPONSE_OK) { + Glib::ustring fname = dialog.get_filename(); + + if (event->state & Gdk::CONTROL_MASK) { + // opening the partial paste dialog window + partialProfileDlg->set_title(M("PROFILEPANEL_LOADPPASTE")); + int i = partialProfileDlg->run(); + partialProfileDlg->hide(); + if (i != Gtk::RESPONSE_OK) + return; + } + bool customCreated = false; + if (!custom) { + custom = new PartialProfile (true); + customCreated = true; + } + + ProcParams pp; + ParamsEdited pe; + int err = pp.load (fname, &pe); + if (!err) { + if (!customCreated && fillMode->get_active()) + custom->pparams->setDefaults(); + custom->set(true); + + bool prevState = changeconn.block(true); + Gtk::TreeIter newEntry = addCustomRow(); + profiles->set_active (newEntry); + currRow = profiles->get_active(); + changeconn.block(prevState); + + // Now we have procparams initialized to default if fillMode is on + // and paramsedited initialized to default in all cases + + if (event->state & Gdk::CONTROL_MASK) + // custom.pparams = loadedFile.pparams filtered by ( loadedFile.pedited & partialPaste.pedited ) + partialProfileDlg->applyPaste (custom->pparams, !fillMode->get_active()?custom->pedited:NULL, &pp, &pe); + else { + // custom.pparams = loadedFile.pparams filtered by ( loadedFile.pedited ) + pe.combine(*custom->pparams, pp, true); + if (!fillMode->get_active()) + *custom->pedited = pe; + } + + changeTo (custom, M("PROFILEPANEL_PFILE")); + } + else if (customCreated) { + // we delete custom + custom->deleteInstance(); + delete custom; custom = NULL; + } + } + return; +} + +/* + * Paste a full profile from the clipboard + */ +void ProfilePanel::paste_clicked (GdkEventButton* event) { + + if (event->button != 1) + return; + if (!clipboard.hasProcParams()) + return; + + if (event->state & Gdk::CONTROL_MASK) { + partialProfileDlg->set_title(M("PROFILEPANEL_PASTEPPASTE")); + int i = partialProfileDlg->run(); + partialProfileDlg->hide(); + if (i != Gtk::RESPONSE_OK) + return; + } + + bool prevState = changeconn.block(true); + + if (!custom) { + custom = new PartialProfile (true); + if (isLastSavedSelected()) { + *custom->pparams = *lastsaved->pparams; + } + else { + const ProfileStoreEntry* entry = profiles->getSelectedEntry(); + if (entry) { + const PartialProfile* partProfile = profileStore.getProfile (entry); + *custom->pparams = *partProfile->pparams; + } + } + profiles->set_active (addCustomRow()); + currRow = profiles->get_active(); + } + else { + if (fillMode->get_active()) + custom->pparams->setDefaults(); + profiles->set_active(getCustomRow()); + currRow = profiles->get_active(); + } + custom->pedited->set(true); + + changeconn.block(prevState); + + // Now we have procparams initialized to default if fillMode is on + // and paramsedited initialized to default in all cases + + ProcParams pp = clipboard.getProcParams (); + if (clipboard.hasPEdited()) { + ParamsEdited pe = clipboard.getParamsEdited(); + if (event->state & Gdk::CONTROL_MASK) + // custom.pparams = clipboard.pparams filtered by ( clipboard.pedited & partialPaste.pedited ) + partialProfileDlg->applyPaste (custom->pparams, !fillMode->get_active()?custom->pedited:NULL, &pp, &pe); + else { + // custom.pparams = clipboard.pparams filtered by ( clipboard.pedited ) + pe.combine(*custom->pparams, pp, true); + if (!fillMode->get_active()) + *custom->pedited = pe; + } + } + else { + if (event->state & Gdk::CONTROL_MASK) + // custom.pparams = clipboard.pparams filtered by ( partialPaste.pedited ) + partialProfileDlg->applyPaste (custom->pparams, NULL, &pp, NULL); + else { + // custom.pparams = clipboard.pparams non filtered + *custom->pparams = pp; + } + } + + changeTo (custom, M("HISTORY_FROMCLIPBOARD")); + return; +} + +void ProfilePanel::changeTo (const PartialProfile* newpp, Glib::ustring profname) { + + if (!newpp) + return; + + if (tpc) + tpc->profileChange (newpp, EvProfileChanged, profname); +} + +void ProfilePanel::selection_changed () { + + if (isCustomSelected()) { + if (!dontupdate) + changeTo (custom, Glib::ustring ("(" + M("PROFILEPANEL_PCUSTOM") + ")")); + } + else if (isLastSavedSelected()) + changeTo (lastsaved, Glib::ustring ("(" + M("PROFILEPANEL_PLASTSAVED") + ")")); + else { + const ProfileStoreEntry *pse = profiles->getSelectedEntry(); + if (pse->type == PSET_FOLDER) { + // this entry is invalid, restoring the old value + bool ccPrevState = changeconn.block(true); + profiles->set_active(currRow); + changeconn.block(ccPrevState); + dontupdate = false; + return; + } + else + currRow = profiles->get_active(); + + const PartialProfile* s = profileStore.getProfile (pse); + if (s) { + if (fillMode->get_active() && s->pedited) { + ParamsEdited pe(true); + PartialProfile s2(s->pparams, &pe, false); + changeTo (&s2, pse->label+"+"); + } + else + changeTo (s, pse->label); + } + } + dontupdate = false; +} + +void ProfilePanel::procParamsChanged (rtengine::procparams::ProcParams* p, rtengine::ProcEvent ev, Glib::ustring descr, ParamsEdited* paramsEdited) { + + // to prevent recursion, filter out the events caused by the profilepanel + if (ev==EvProfileChanged || ev==EvPhotoLoaded) + return; + + if (!isCustomSelected()) { + dontupdate = true; + if (!custom) { + custom = new PartialProfile (true); + custom->set(true); + profiles->set_active (addCustomRow()); + currRow = profiles->get_active(); + } + else { + profiles->set_active(getCustomRow()); + currRow = profiles->get_active(); + } + } + *custom->pparams = *p; +} + +/** @brief Initialize the Profile panel with a default profile, overridden by the last saved profile if provided + * + * The file tree has already been created on object's construction. We add here the Custom, LastSaved and/or Internal item. + * + * @param profileFullPath full path of the profile; must start by the virtual root (${G} or ${U}, and without suffix + * @param lastSaved pointer to the last saved ProcParam; may be NULL + */ +void ProfilePanel::initProfile (const Glib::ustring& profileFullPath, ProcParams* lastSaved) { + + const ProfileStoreEntry *pse = NULL; + const PartialProfile *defprofile = NULL; + + bool ccPrevState = changeconn.block(true); + + if (custom) { + custom->deleteInstance(); + delete custom; custom = NULL; + } + + if (lastsaved) { + lastsaved->deleteInstance(); + delete lastsaved; lastsaved = NULL; + } + if (lastSaved) { + ParamsEdited* pe = new ParamsEdited(true); + // copying the provided last saved profile to ProfilePanel::lastsaved + lastsaved = new PartialProfile(lastSaved, pe); + } + + // update the content of the combobox; will add 'custom' and 'lastSaved' if necessary + updateProfileList(); + + Gtk::TreeIter lasSavedEntry; + // adding the Last Saved combobox entry, if needed + if (lastsaved) { + defprofile = lastsaved; + lasSavedEntry = getLastSavedRow(); + } + + if (!(pse = profileStore.findEntryFromFullPath(profileFullPath))) { + // entry not found, pse = the Internal ProfileStoreEntry + pse = profileStore.getInternalDefaultPSE(); + } + + defprofile = profileStore.getProfile (pse); + + // selecting the "Internal" entry + profiles->setInternalEntry (); + currRow = profiles->get_active(); + + if (lastsaved) { + if (lasSavedEntry) profiles->set_active (lasSavedEntry); + currRow = profiles->get_active(); + if (tpc) { + tpc->setDefaults (lastsaved->pparams); + tpc->profileChange (lastsaved, EvPhotoLoaded, profiles->getSelectedEntry()->label); + } + } + else { + if (pse) { + profiles->setActiveRowFromEntry(pse); + currRow = profiles->get_active(); + } + if (tpc) { + tpc->setDefaults (defprofile->pparams); + tpc->profileChange (defprofile, EvPhotoLoaded, profiles->getSelectedEntry()->label); + } + } + changeconn.block (ccPrevState); +} + +void ProfilePanel::setInitialFileName (const Glib::ustring& filename) { + lastFilename = Glib::path_get_basename(filename) + paramFileExtension; + imagePath = Glib::path_get_dirname(filename); +} + +void ProfilePanel::profileFillModeToggled() { + if (fillMode->get_active()) { + // The button is pressed, we'll use the profileFillModeOnImage + fillMode->set_image(*profileFillModeOnImage); + } + else { + // The button is released, we'll use the profileFillModeOffImage + fillMode->set_image(*profileFillModeOffImage); + } +} + +void ProfilePanel::writeOptions() { + options.filledProfile = fillMode->get_active(); +} + diff --git a/rtgui/profilepanel.h b/rtgui/profilepanel.h new file mode 100644 index 000000000..b8e6b0a77 --- /dev/null +++ b/rtgui/profilepanel.h @@ -0,0 +1,97 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _PROFILEPANEL_ +#define _PROFILEPANEL_ + +#include +#include +#include "../rtengine/rtengine.h" +#include "pparamschangelistener.h" +#include "profilechangelistener.h" +#include "profilestore.h" +#include "partialpastedlg.h" +#include "guiutils.h" +#include "rtimage.h" + +class ProfilePanel : public Gtk::VBox, public PParamsChangeListener, public ProfileStoreListener { + + private: + + rtengine::procparams::PartialProfile* storedPProfile; + Glib::ustring storedValue; + Glib::ustring lastFilename; + Glib::ustring imagePath; + RTImage *profileFillModeOnImage; + RTImage *profileFillModeOffImage; + Gtk::ToggleButton* fillMode; + Gtk::TreeIter currRow; + + void profileFillModeToggled (); + bool isCustomSelected (); + bool isLastSavedSelected (); + Gtk::TreeIter getCustomRow (); + Gtk::TreeIter getLastSavedRow (); + Gtk::TreeIter addCustomRow (); + Gtk::TreeIter addLastSavedRow (); + + protected: + + static PartialPasteDlg* partialProfileDlg; + Gtk::Button* save; + Gtk::Button* load; + Gtk::Button* copy; + Gtk::Button* paste; + ProfileStoreComboBox* profiles; + rtengine::procparams::PartialProfile* custom; + rtengine::procparams::PartialProfile* lastsaved; + ProfileChangeListener* tpc; + bool dontupdate; + sigc::connection changeconn; + + void changeTo (const rtengine::procparams::PartialProfile* newpp, Glib::ustring profname); + + public: + + ProfilePanel (bool readOnly=false); + virtual ~ProfilePanel (); + + void setProfileChangeListener (ProfileChangeListener* ppl) { tpc = ppl; } + + static void init (); + static void cleanup (); + void storeCurrentValue(); + void updateProfileList (); + void restoreValue(); + + void initProfile (const Glib::ustring& profileFullPath, rtengine::procparams::ProcParams* lastSaved); + void setInitialFileName (const Glib::ustring& filename); + + // PParamsChangeListener interface + void procParamsChanged (rtengine::procparams::ProcParams* params, rtengine::ProcEvent ev, Glib::ustring descr, ParamsEdited* paramsEdited=NULL); + + // gui callbacks + void save_clicked (GdkEventButton* event); + void load_clicked (GdkEventButton* event); + void copy_clicked (GdkEventButton* event); + void paste_clicked (GdkEventButton* event); + void selection_changed (); + void writeOptions(); +}; + +#endif diff --git a/rtgui/profilestore.cc b/rtgui/profilestore.cc new file mode 100644 index 000000000..a2e4b0419 --- /dev/null +++ b/rtgui/profilestore.cc @@ -0,0 +1,693 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "profilestore.h" +#include "options.h" +#include "toolpanel.h" +#include "guiutils.h" +#include "../rtengine/safegtk.h" + +ProfileStore profileStore; + +using namespace rtengine; +using namespace rtengine::procparams; + +ProfileStore::ProfileStore () : parseMutex(NULL), storeState(STORESTATE_NOTINITIALIZED), internalDefaultProfile(NULL), internalDefaultEntry(NULL) { + internalDefaultProfile = new AutoPartialProfile(); + internalDefaultProfile->set(true); +} + +bool ProfileStore::init () { + if (storeState == STORESTATE_DELETED) + return false; + if (storeState == STORESTATE_NOTINITIALIZED) { + storeState = STORESTATE_BEINGINITIALIZED; + parseMutex = new MyMutex(); + _parseProfiles (); + storeState = STORESTATE_INITIALIZED; + } + return true; +} + +ProfileStore::~ProfileStore () { + + if (storeState == STORESTATE_NOTINITIALIZED) + return; + + // This lock prevent object's suppression while scanning the directories + storeState = STORESTATE_DELETED; + MyMutex::MyLock lock(*parseMutex); + + clearProfileList (); + partProfiles.clear (); + clearFileList(); + delete internalDefaultProfile; + lock.release(); + delete parseMutex; + parseMutex = NULL; +} + +/* + * Public method to parse the profiles' directories + * Since there's a race condition in the multithreaded environment on this object, + * parseProfiles may need to ask for initialization of this object, and then will + * ask a mutex lock on it, has it been initialized by this call or not + * + * This method will scan the directory tree again and update the profile list. When finished, + * the listeners will be called in order to update with the new list + */ +void ProfileStore::parseProfiles () { + + if (!init()) + // I don't even know if this situation can occur + return; + + for (std::list::iterator i=listeners.begin(); i!=listeners.end(); ++i) + (*i)->storeCurrentValue(); + + { + MyMutex::MyLock lock(*parseMutex); + + _parseProfiles (); + } + + for (std::list::iterator i=listeners.begin(); i!=listeners.end(); ++i) { + (*i)->updateProfileList(); + (*i)->restoreValue(); + } +} + +void ProfileStore::_parseProfiles () { + + // Acquire the GUI, since the tree model can interact with combobox + GThreadLock threadLock; + + // clear loaded profiles + folders.clear(); + clearFileList(); + clearProfileList (); + + folders.push_back("<<< ROOT >>>"); // Fake path, so parentFolderId == 0 will be used to attach a ProfileStoreEntry to the root container, not sub-menu + + Glib::ustring p1 = options.getUserProfilePath(); + Glib::ustring p2 = options.getGlobalProfilePath(); + bool displayLevel0 = options.useBundledProfiles && !p1.empty() && !p2.empty() && p1 != p2; + + Glib::ustring virtualPath("${U}"); + Glib::ustring currDir("${U}"); + parseDir (p1, virtualPath, currDir, 0, 0, displayLevel0); + if (displayLevel0) { + virtualPath = "${G}"; + currDir = "${G}"; + parseDir (p2, virtualPath, currDir, 0, 0, displayLevel0); + } + + // sort profiles + std::sort(entries.begin(), entries.end(), SortProfiles() ); + + // entries and partProfiles are empty, but the entry and profiles already exist (they have survived to clearFileList and clearProfileList) + if (!internalDefaultEntry) + internalDefaultEntry = new ProfileStoreEntry(Glib::ustring("(") + M("PROFILEPANEL_PINTERNAL") + Glib::ustring(")"), PSET_FILE, 0, 0); + entries.push_back(internalDefaultEntry); + partProfiles[internalDefaultEntry] = internalDefaultProfile; + + + // Check if the default profiles has been found. + if (findEntryFromFullPathU(options.defProfRaw) == NULL) { + options.setDefProfRawMissing(true); + if (options.rtSettings.verbose) + printf("WARNING: Default profile \"%s\" for raw images not found!\n", options.defProfRaw.c_str()); + } + if (findEntryFromFullPathU(options.defProfImg) == NULL) { + options.setDefProfImgMissing(true); + if (options.rtSettings.verbose) + printf("WARNING: Default profile \"%s\" for standard images not found!\n", options.defProfImg.c_str()); + } +} + +/// @return Returns true if some files has been found (directories are ignored) +bool ProfileStore::parseDir (Glib::ustring& realPath, Glib::ustring& virtualPath, Glib::ustring& currDir, unsigned int parentId, unsigned char level, bool displayLevel0) { + + bool fileFound = false; + unsigned int folder = 0; // folder's own Id + + // reload the available profiles from the profile dir + if (!realPath.empty() && safe_file_test(realPath, Glib::FILE_TEST_EXISTS) && safe_file_test (realPath, Glib::FILE_TEST_IS_DIR)) { + + // add this entry to the folder list + folders.push_back(virtualPath); + folder = (unsigned int)(folders.size())-1; + + if (level>0 || displayLevel0) { + // replace the virtual folder name by a localized text + if (currDir == "${U}") + currDir = M("PROFILEPANEL_MYPROFILES"); + else if (currDir == "${G}") + currDir = M("PROFILEPANEL_GLOBALPROFILES"); + + // add this localized text to the file list + entries.push_back( new ProfileStoreEntry(currDir, PSET_FOLDER, parentId, folder) ); + } + + // walking through the directory + Glib::Dir* dir = NULL; + dir = new Glib::Dir (realPath); + for (Glib::DirIterator i = dir->begin(); i!=dir->end(); ++i) { + currDir = *i; + if (currDir == "." || currDir == "..") + continue; + + Glib::ustring fname = Glib::build_filename(realPath, currDir); + if (safe_file_test (fname, Glib::FILE_TEST_IS_DIR)) { + Glib::ustring vp(Glib::build_filename(virtualPath, currDir)); + Glib::ustring rp(Glib::build_filename(realPath, currDir)); + fileFound = parseDir (rp, vp, currDir, folder, level+1, 0); + } + else { + size_t lastdot = currDir.find_last_of ('.'); + if (lastdot!=Glib::ustring::npos && lastdot<=currDir.size()-4 && !currDir.casefold().compare (lastdot, 4, paramFileExtension)) { + // file found + if( options.rtSettings.verbose ) + printf ("Processing file %s...", fname.c_str()); + + Glib::ustring name = currDir.substr(0,lastdot); + + // create the partial profile + AutoPartialProfile *pProf = new AutoPartialProfile(); + int res = pProf->load (fname); + if (!res && pProf->pparams->ppVersion>=220) { + fileFound = true; + + if( options.rtSettings.verbose ) + printf ("OK\n"); + + // adding this file to the list + ProfileStoreEntry* filePSE = new ProfileStoreEntry(name, PSET_FILE, folder, 0); + entries.push_back(filePSE); + + // map the partial profile + partProfiles[filePSE] = pProf; + //partProfiles.insert( std::pair (filePSE, pProf) ); + } + else if( options.rtSettings.verbose ) { + printf ("failed!\n"); + } + } + } + } + delete dir; + } + + if (!fileFound && (level>0 || displayLevel0)) { + // no files found in this level, we delete the subdirectory entry + folders.pop_back(); + entries.pop_back(); + } + + return fileFound; +} + +int ProfileStore::findFolderId(const Glib::ustring &path) { + for (std::vector::iterator i=folders.begin(); i!=folders.end(); i++) { + if (*i == path) { + return i - folders.begin(); + } + } + return -1; +} + +/** @brief Return the ProfileStoreEntry object that match the given file and path + * + * @param fullPath Path of the file; the filename may end by the standard extension, + * but have to begin with a virtual location ( ${G} or ${U} ) + * Will return null on invalid path or if the entry can't be found + */ +const ProfileStoreEntry* ProfileStore::findEntryFromFullPathU(Glib::ustring path) { + + if (path.empty()) + return NULL; + + if (path == DEFPROFILE_INTERNAL) + return internalDefaultEntry; + + size_t lastdot = path.find_last_of ('.'); + if (lastdot!=Glib::ustring::npos && lastdot<=path.size()-4 && !path.casefold().compare (lastdot, 4, paramFileExtension)) + // removing the extension + path = path.substr(0,lastdot); + + // dir separator may come from options file and may be \ or /, we convert them to G_DIR_SEPARATOR_S + if (path.size() > 4 && (path[4] == '/' || path[4] == '\\')) + path = path.substr(0,4) + G_DIR_SEPARATOR_S + path.substr(5); + + // removing the filename + Glib::ustring fName = Glib::path_get_basename(path); + if (!fName.empty()) { + path = path.substr(0, path.length()-fName.length()); + } + else { + // path is malformed, returning NULL; + return NULL; + } + + path = Glib::path_get_dirname(path); + + // 1. find the path in the folder list + int parentFolderId = findFolderId(path); + + if (parentFolderId == -1) { + return NULL; + } + + // 2. find the entry that match the given filename and parentFolderId + for (std::vector::iterator i=entries.begin(); i!=entries.end(); i++) { + if (((*i)->parentFolderId)==parentFolderId && (*i)->label==fName) + return *i; + } + return NULL; +} + +/** Protected version of findEntryFromFullPathU */ +const ProfileStoreEntry* ProfileStore::findEntryFromFullPath(Glib::ustring path) { + MyMutex::MyLock lock(*parseMutex); + return findEntryFromFullPathU(path); +} + +const PartialProfile* ProfileStore::getProfile (Glib::ustring path) { + + if (!init()) + // I don't even know if this situation can occur + return NULL; + + const ProfileStoreEntry *pse = findEntryFromFullPath(path); + if (!pse) + return NULL; + + return getProfile(pse); +} + +const PartialProfile* ProfileStore::getProfile (const ProfileStoreEntry* entry) { + + if (!init()) + // I don't even know if this situation can occur + return NULL; + + MyMutex::MyLock lock(*parseMutex); + + if (entry == internalDefaultEntry) + return internalDefaultProfile; + + std::map::iterator iter = partProfiles.find(entry); + if (iter != partProfiles.end()) { + return iter->second; + } + else { + // This shouldn't happen! + #ifndef NDEBUG + printf("WARNING! Profile not found!\n"); + #endif + return NULL; + } +} + +/** @brief Get a pointer to the profile's vector list + * + * This method grants you unique access to the vector list through Mutex locking. + * When you're done with the file list, you MUST call the releaseFileList method to release the lock. + */ +const std::vector* ProfileStore::getFileList () { + /*if (!init()) { + // I don't even know if this situation can occur + return NULL; + }*/ + + parseMutex->lock(); + + return &entries; +} + +void ProfileStore::releaseFileList() { + parseMutex->unlock(); +} + +/* + * Send back a pointer to the default procparams for raw or standard images. + * If the profile doesn't already exist in the profile list, + * it will add it with default internal values, so this method never fails + */ +const ProcParams* ProfileStore::getDefaultProcParams (bool isRaw) { + + if (!init()) + // I don't even know if this situation can occur + return NULL; + //Note: the mutex is locked in getProfile, called below + + const PartialProfile* pProf = getProfile (isRaw ? options.defProfRaw : options.defProfImg); + + if (!pProf) pProf = internalDefaultProfile; + + return pProf->pparams; +} + +/* + * Send back a pointer to the default partial profile for raw or standard images. + * If it doesn't already exist in the profile list, it will add it with default internal values, + * so this method will never fails + */ +const PartialProfile* ProfileStore::getDefaultPartialProfile (bool isRaw) { + + if (!init()) + // I don't even know if this situation can occur + return NULL; + //Note: the mutex is locked in getProfile, called below + + const PartialProfile* pProf = getProfile (isRaw ? options.defProfRaw : options.defProfImg); + + if (!pProf) pProf = internalDefaultProfile; + + return pProf; +} + +const Glib::ustring ProfileStore::getPathFromId(int folderId) { + return folders.at(folderId); +} + + +void ProfileStore::clearFileList() { + for (std::vector::iterator i=entries.begin(); i!=entries.end(); ++i) + if (*i != internalDefaultEntry) delete *i; + entries.clear(); +} + +void ProfileStore::clearProfileList() { + for (std::map::iterator i=partProfiles.begin(); i!=partProfiles.end(); ++i) + if (i->second != internalDefaultProfile) delete i->second; + partProfiles.clear(); +} + +void ProfileStore::addListener(ProfileStoreListener *listener) { + listeners.push_back(listener); +} + +void ProfileStore::removeListener(ProfileStoreListener *listener) { + listeners.remove(listener); +} + +void ProfileStore::dumpFolderList() { + printf("Folder list:\n------------\n"); + for (unsigned int i=0; ilabel = label; + this->type = type; + parentFolderId = parentFolder; + folderId = folder; +} + +ProfileStoreLabel::ProfileStoreLabel(const ProfileStoreEntry *entry) : Gtk::Label(entry->label), entry(entry) { + set_alignment(0, 0.5); + show(); +} + +ProfileStoreComboBox::ProfileStoreComboBox () { + updateProfileList(); +} + +Glib::ustring ProfileStoreComboBox::getCurrentLabel() { + Glib::ustring currLabel; + Gtk::TreeModel::iterator currRow = get_active(); + + if (currRow) { + const ProfileStoreEntry *currEntry = (*currRow)[methodColumns.profileStoreEntry]; + return currEntry->label; + } + return currLabel; +} + +const ProfileStoreEntry* ProfileStoreComboBox::getSelectedEntry() { + Gtk::TreeModel::iterator currRow_ = get_active(); + Gtk::TreeModel::Row currRow = *currRow_; + if (currRow) + return currRow[methodColumns.profileStoreEntry]; + else + return NULL; +} + +/** @brief Recursive method to update the combobox entries */ +void ProfileStoreComboBox::refreshProfileList_ (Gtk::TreeModel::Row *parentRow, int parentFolderId, bool initial, const std::vector *entryList) { + for (std::vector::const_iterator i=entryList->begin(); i!=entryList->end(); i++) { + if ((*i)->parentFolderId == parentFolderId) { // filtering the entry of the same folder + if ((*i)->type == PSET_FOLDER) { + Glib::ustring folderPath( profileStore.getPathFromId((*i)->folderId) ); + if (options.useBundledProfiles || ((folderPath != "${G}" ) && (folderPath != "${U}" ))) { + // creating the new submenu + Gtk::TreeModel::Row newSubMenu; + if (initial) { + newSubMenu = *(refTreeModel->append()); + } + else { + newSubMenu = *(refTreeModel->append(parentRow->children())); + } + + // creating and assigning the custom Label object + newSubMenu[methodColumns.label] = (*i)->label; + newSubMenu[methodColumns.profileStoreEntry] = *i; + + refreshProfileList_ (&newSubMenu, (*i)->folderId, false, entryList); + } + else + refreshProfileList_ (parentRow, (*i)->folderId, true, entryList); + } + else { + Gtk::TreeModel::Row newItem; + // creating a menu entry + if (initial) + newItem = *(refTreeModel->append()); + else + newItem = *(refTreeModel->append(parentRow->children())); + newItem[methodColumns.label] = (*i)->label; + newItem[methodColumns.profileStoreEntry] = *i; + } + } + } +} + +/** @brief Get the ProfileStore's entry list and recreate the combobox entries. + * If you want to update the ProfileStore list itself (rescan the dir tree), use the "ProfileStore::parseProfiles" method instead + * + * This method has to be called by the ProfileStoreListener having a ProfileStoreComboBox. + */ +void ProfileStoreComboBox::updateProfileList () { + + // clear items + clear(); + refTreeModel.clear(); + // Create the Tree model + refTreeModel = Gtk::TreeStore::create(methodColumns); + // Assign the model to the Combobox + set_model(refTreeModel); + + + // this will lock the profilestore's entry list too + const std::vector *entryList = profileStore.getFileList(); + + Gtk::TreeModel::Row root; + //profileStore.dumpFolderList(); + refreshProfileList_ (&root, entryList->at(0)->parentFolderId, true, entryList); + + if (entryList->at(0)->parentFolderId != 0) { + // special case for the Internal default entry + addRow(profileStore.getInternalDefaultPSE()); + } + + // releasing the profilestore's entry list mutex + profileStore.releaseFileList(); + + pack_start(methodColumns.label, false); +} + +Gtk::TreeIter ProfileStoreComboBox::findRowFromEntry_ (Gtk::TreeModel::Children childs, const ProfileStoreEntry *pse) { + Gtk::TreeModel::Row row; + Gtk::TreeIter rowInSubLevel; + for(Gtk::TreeModel::Children::iterator iter = childs.begin(); iter != childs.end(); ++iter) { + row = *iter; + // Hombre: is there a smarter way of knowing if this row has childs? + const ProfileStoreEntry *pse_ = row[methodColumns.profileStoreEntry]; + if (pse_->type == PSET_FOLDER) { + rowInSubLevel = findRowFromEntry_ (iter->children(), pse); + if (rowInSubLevel) { + // entry found + return rowInSubLevel; + } + } + else if (pse_ == pse) { + // entry found + return iter; + } + } + return childs.end(); +} + +Gtk::TreeIter ProfileStoreComboBox::findRowFromEntry (const ProfileStoreEntry *pse) { + Gtk::TreeModel::Children childs = refTreeModel->children(); + if (pse) { + Gtk::TreeIter row = findRowFromEntry_ (childs, pse); + return row; + } + return childs.end(); +} + +Gtk::TreeIter ProfileStoreComboBox::findRowFromFullPath_ (Gtk::TreeModel::Children childs, int parentFolderId, Glib::ustring &name) { + Gtk::TreeModel::Row row; + Gtk::TreeIter rowInSubLevel; + for(Gtk::TreeModel::Children::iterator iter = childs.begin(); iter != childs.end(); ++iter) { + row = *iter; + // Hombre: is there a smarter way of knowing if this row has childs? + const ProfileStoreEntry *pse = row[methodColumns.profileStoreEntry]; + if (pse->type == PSET_FOLDER) { + rowInSubLevel = findRowFromFullPath_ (iter->children(), parentFolderId, name); + if (rowInSubLevel) { + // entry found + return rowInSubLevel; + } + } + else if (parentFolderId==pse->parentFolderId && name==pse->label) { + // entry found + return iter; + } + } + return childs.end(); +} + +Gtk::TreeIter ProfileStoreComboBox::findRowFromFullPath (Glib::ustring path) { + Gtk::TreeIter row; + + if (path.empty()) + return row; + + if (path == DEFPROFILE_INTERNAL) { + row = findRowFromEntry(profileStore.getInternalDefaultPSE()); + return row; + } + + // removing the filename + Glib::ustring fName = Glib::path_get_basename(path); + if (!fName.empty()) { + path = path.substr(0, path.length()-fName.length()); + } + else { + // path is malformed; + return row; + } + + path = Glib::path_get_dirname(path); + int parentFolderId = profileStore.findFolderId(path); + + // 1. find the path in the folder list + if (parentFolderId != -1) + row = findRowFromFullPath_ (refTreeModel->children(), parentFolderId, fName); + + return row; +} + +/** @brief Get the absolute full path of the active row entry. + * @return The absolute full path of the active row entry, or the "Internal" keyword, + * or an empty string if the ComboBox is in an invalid state + */ +Glib::ustring ProfileStoreComboBox::getFullPathFromActiveRow() { + Glib::ustring path; + Gtk::TreeModel::iterator currRowI = get_active(); + if (!currRowI) + return path; + + Gtk::TreeModel::Row currRow = *currRowI; + + if (currRow) { + + const ProfileStoreEntry *currEntry = currRow[methodColumns.profileStoreEntry]; + if (!currEntry) + return path; + + if (currEntry == profileStore.getInternalDefaultPSE()) + return Glib::ustring(DEFPROFILE_INTERNAL); + + path = Glib::build_filename(profileStore.getPathFromId(currEntry->parentFolderId), currEntry->label); + } + return path; +} + +bool ProfileStoreComboBox::setActiveRowFromFullPath(Glib::ustring path) { + if (!path.empty()) { + Gtk::TreeIter row = findRowFromFullPath(path); + if (row) { + set_active(row); + return true; + } + } + return false; +} + +bool ProfileStoreComboBox::setActiveRowFromEntry(const ProfileStoreEntry *pse) { + if (pse) { + Gtk::TreeIter row = findRowFromEntry(pse); + if (row) { + set_active(row); + return true; + } + } + return false; +} + +bool ProfileStoreComboBox::setInternalEntry () { + return setActiveRowFromEntry(profileStore.getInternalDefaultPSE()); +} + +/** @brief Get the row from the first level of the tree that match the provided name */ +Gtk::TreeIter ProfileStoreComboBox::getRowFromLabel(Glib::ustring name) { + Gtk::TreeIter row; + Gtk::TreeModel::Children childs = refTreeModel->children(); + if (!name.empty()) { + Gtk::TreeModel::Row currRow; + for(Gtk::TreeModel::Children::iterator iter = childs.begin(); iter != childs.end(); ++iter) { + currRow = *iter; + const ProfileStoreEntry *pse = currRow[methodColumns.profileStoreEntry]; + if (pse->label == name) { + return currRow; + } + } + } + return childs.end(); + //return refTreeModel->get_iter(""); // is this fast? We want to send back a null, anvalid or end() iterator object here +} + +/** @brief Add a new row to the first level of the tree */ +Gtk::TreeIter ProfileStoreComboBox::addRow(const ProfileStoreEntry *profileStoreEntry) { + Gtk::TreeIter newEntry = refTreeModel->append(); + Gtk::TreeModel::Row row = *newEntry; + row[methodColumns.label] = profileStoreEntry->label; + row[methodColumns.profileStoreEntry] = profileStoreEntry; + return newEntry; +} + diff --git a/rtgui/profilestore.h b/rtgui/profilestore.h new file mode 100644 index 000000000..bd9c019fb --- /dev/null +++ b/rtgui/profilestore.h @@ -0,0 +1,228 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _PROFILESTORE_ +#define _PROFILESTORE_ + +#include +#include +#include "../rtengine/rtengine.h" +#include "threadutils.h" +#include "paramsedited.h" +#include "guiutils.h" +#include + + +/** @brief This will implement callback functions for the ProfileStore + * + */ +class ProfileStoreListener { + + public: + virtual ~ProfileStoreListener() {} + + /** @brief Called whenever the current value has to be stored before update. */ + virtual void storeCurrentValue() {} + /** @brief Called whenever the file list has been updated and the content of the listener has to be updated. */ + virtual void updateProfileList() =0; + /** @brief Called whenever the profile list has changed and the old value have to be restored (if possible). */ + virtual void restoreValue() {} +}; + +/// @brief ProfileStoreEntry type (folder or file) +typedef enum PSE_TYPE { + PSET_FOLDER, + PSET_FILE +} PSEType; + + +/** + * @brief Entry of the profiles store, consisting of a type (folder/file) & label. + * + * Will be used as key element in the name / PartialProfile mapping + */ +class ProfileStoreEntry { + + public: + + Glib::ustring label; /// Label to be used in menu or combobox = profile's filename + PSEType type; /// either PSET_FOLDER or PSET_FILE + unsigned short parentFolderId; /// index of the element's path in the folder list; id == 0 is reserved + unsigned short folderId; /// index of the folder's own path in the folder list; will be null for file entries + + /** @brief Create a new ProfileStoreLabel with null values, that will have to be set later with setValues or the copy operator + */ + ProfileStoreEntry(); + + /** @brief Create a new ProfileStoreLabel with values + * @param label Label to be used in menu or combobox; also used as profile's filename + * @param type either PSET_FOLDER or PSET_FILE + * @param parentFolder index of the elements's path in the folder list + * @param folder index of the folder's own path in the folder list + */ + ProfileStoreEntry(Glib::ustring label, PSEType type, unsigned short parentFolder, unsigned short folder); + + /** @brief Set the values of the object after its instantiation + * @param label Label to be used in menu or combobox; also used as profile's filename + * @param type either PSET_FOLDER or PSET_FILE + * @param parentFolder index of the elements's path in the folder list + * @param folder index of the folder's own path in the folder list + */ + void setValues(Glib::ustring label, PSEType type, unsigned short parentFolder, unsigned short folder); +}; + + +/** + * @brief subclass of Gtk::Label with extra fields for Combobox and Menu, to link with a ProfileStoreEntry + */ +class ProfileStoreLabel : public Gtk::Label { + + public: + const ProfileStoreEntry *entry; + +#ifndef NDEBUG + ProfileStoreLabel() : Gtk::Label("*** error ***"), entry(NULL) {} +#else + ProfileStoreLabel() : Gtk::Label(""), entry(NULL) {} +#endif + + /** @brief Create a new ProfileStoreLabel + * + * @param entry Pointer to the ProfileStoreEntry object, be it a directory or a file + */ + ProfileStoreLabel(const ProfileStoreEntry *entry); + ProfileStoreLabel (const ProfileStoreLabel &other); +}; + + +/** @brief Store the profiles bundled with RawTharapee and created by the user. + * + * This store can be queried by the GUI to display a Tree of the profiles available + * in the user's and system's profile directory and subdirectories. + */ +class ProfileStore { + + typedef enum { + STORESTATE_NOTINITIALIZED, + STORESTATE_BEINGINITIALIZED, + STORESTATE_INITIALIZED, + STORESTATE_DELETED + } StoreState; + + private: + struct SortProfiles { + bool operator ()(const ProfileStoreEntry* const a1, const ProfileStoreEntry* const a2) { + return a1->parentFolderId == a2->parentFolderId ? a1->label < a2->label : a1->parentFolderId < a2->parentFolderId; + } + }; + + MyMutex *parseMutex; + StoreState storeState; + rtengine::procparams::AutoPartialProfile *internalDefaultProfile; + ProfileStoreEntry *internalDefaultEntry; + + /** Alphabetically ordered list of folder and files through Gtk::Label sub-class; + * ready to be used in Menu and Combobox + * The first element (#0) will be a fake path so ProfileStoreEntry can be attached to the root container */ + std::vector folders; + + /** Alphabetically ordered list of folder and files through Gtk::Label derived class; + * ready to be used in Menu and Combobox */ + std::vector entries; + + /** List of PartialProfiles from the indexed files */ + std::map partProfiles; + + /** List of the client of this store */ + std::list listeners; + + /** @brief Method to recursively parse a profile folder with a level depth arbitrarily limited to 3 + * + * @param realPath current full path of the scanned directory ; e.g.: ~/MyProfiles/ + * @param virtualPath current full path that will be saved in "options" ; must start with either ${U} or ${G}, + * standing for User's and Global's (RT) profile folder, respectively + * @param currDir name of the directory to scan; it's the last element of the virtualPath + * @param parentId path entry of the parent folder + * @param level current level of the directory tree + * @param displayLevel0 if true, level 0 is created in order to have a User's and Bundled profiles separation (i.e. 2 root directories are expected) + * if false, only one root directory is expected + */ + bool parseDir (Glib::ustring& realPath, Glib::ustring& virtualPath, Glib::ustring& currDir, unsigned int parentId, unsigned char level, bool displayLevel0); + void _parseProfiles (); + void clearFileList (); + void clearProfileList (); + const ProfileStoreEntry* findEntryFromFullPathU(Glib::ustring path); + + public: + + ProfileStore(); + ~ProfileStore(); + bool init (); + void parseProfiles (); + int findFolderId(const Glib::ustring &path); + const ProfileStoreEntry* findEntryFromFullPath(Glib::ustring path); + const rtengine::procparams::PartialProfile* getProfile (Glib::ustring path); + const rtengine::procparams::PartialProfile* getProfile (const ProfileStoreEntry* entry); + const std::vector* getFileList (); + void releaseFileList (); + const rtengine::procparams::ProcParams* getDefaultProcParams (bool isRaw); + const rtengine::procparams::PartialProfile* getDefaultPartialProfile (bool isRaw); + const Glib::ustring getPathFromId(int folderId); + const ProfileStoreEntry* getInternalDefaultPSE() { return internalDefaultEntry; } + + void addListener(ProfileStoreListener *listener); + void removeListener(ProfileStoreListener *listener); + + void dumpFolderList(); + +}; + +class ProfileStoreComboBox : public MyComboBox { + + protected: + class MethodColumns : public Gtk::TreeModel::ColumnRecord { + public: + Gtk::TreeModelColumn label; + Gtk::TreeModelColumn profileStoreEntry; + MethodColumns() { add(label); add(profileStoreEntry); } + }; + + Glib::RefPtr refTreeModel; + MethodColumns methodColumns; + void refreshProfileList_ (Gtk::TreeModel::Row *parentRow, int parentFolderId, bool initial, const std::vector *entryList); + Gtk::TreeIter findRowFromEntry_ (Gtk::TreeModel::Children childs, const ProfileStoreEntry *pse); + Gtk::TreeIter findRowFromFullPath_(Gtk::TreeModel::Children childs, int parentFolderId, Glib::ustring &name); + + public: + ProfileStoreComboBox(); + void updateProfileList(); + Glib::ustring getCurrentLabel(); + const ProfileStoreEntry* getSelectedEntry(); + Gtk::TreeIter findRowFromEntry (const ProfileStoreEntry *pse); + Gtk::TreeIter findRowFromFullPath (Glib::ustring path); + Glib::ustring getFullPathFromActiveRow (); + bool setActiveRowFromFullPath (Glib::ustring oldPath); + bool setActiveRowFromEntry (const ProfileStoreEntry *pse); + bool setInternalEntry (); + Gtk::TreeIter getRowFromLabel(Glib::ustring name); + Gtk::TreeIter addRow(const ProfileStoreEntry *profileStoreEntry); +}; + +extern ProfileStore profileStore; + +#endif diff --git a/rtgui/progressconnector.h b/rtgui/progressconnector.h new file mode 100644 index 000000000..791119aa2 --- /dev/null +++ b/rtgui/progressconnector.h @@ -0,0 +1,99 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _PROGRESSCONNECTOR_ +#define _PROGRESSCONNECTOR_ + +#include +#include +#include "../rtengine/rtengine.h" +#include "guiutils.h" + +#undef THREAD_PRIORITY_NORMAL + +class PLDBridge : public rtengine::ProgressListener { + + rtengine::ProgressListener* pl; + + public: + PLDBridge ( rtengine::ProgressListener* pb) + : pl(pb) {} + + // ProgressListener interface + void setProgress (double p) { + GThreadLock lock; + pl->setProgress(p); + } + void setProgressStr (Glib::ustring str) { + GThreadLock lock; + Glib::ustring progrstr; + progrstr = M(str); + pl->setProgressStr(progrstr); + } + + void setProgressState (bool inProcessing){ + GThreadLock lock; + pl->setProgressState(inProcessing); + } + + void error (Glib::ustring descr){ + GThreadLock lock; + pl->error(descr); + } +}; + +template +class ProgressConnector { + + sigc::signal0 opStart; + sigc::signal0 opEnd; + T retval; + Glib::Thread *workThread; + + static int emitEndSignalUI (void* data) { + + sigc::signal0* opEnd = (sigc::signal0*) data; + int r = opEnd->emit (); + delete opEnd; + + return r; + } + + void workingThread () { + retval = opStart.emit (); + g_idle_add (ProgressConnector::emitEndSignalUI, new sigc::signal0 (opEnd)); + workThread = 0; + } + + public: + + ProgressConnector ():workThread( 0 ) { } + + void startFunc (const sigc::slot0& startHandler, const sigc::slot0& endHandler ) { + if( !workThread ){ + opStart.connect (startHandler); + opEnd.connect (endHandler); + workThread = Glib::Thread::create(sigc::mem_fun(*this, &ProgressConnector::workingThread), 0, true, true, Glib::THREAD_PRIORITY_NORMAL); + } + } + + T returnValue(){ + return retval; + } +}; +#endif diff --git a/rtgui/prsharpening.cc b/rtgui/prsharpening.cc new file mode 100644 index 000000000..1334ce06f --- /dev/null +++ b/rtgui/prsharpening.cc @@ -0,0 +1,483 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "prsharpening.h" +#include +#include "guiutils.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +PrSharpening::PrSharpening () : FoldableToolPanel(this, "prsharpening", M("TP_PRSHARPENING_LABEL"), false, true) +{ + + std::vector milestones; + milestones.push_back( GradientMilestone(0.0, 0.0, 0.0, 0.0) ); + milestones.push_back( GradientMilestone(1.0, 1.0, 1.0, 1.0) ); + + //setEnabledTooltipMarkup(M("TP_PRSHARPENING_TOOLTIP")); + + Gtk::HBox* hb = Gtk::manage (new Gtk::HBox ()); + hb->set_border_width (4); + hb->show (); + Gtk::Label* ml = Gtk::manage (new Gtk::Label (M("TP_SHARPENING_METHOD") + ":")); + ml->show (); + method = Gtk::manage (new MyComboBoxText ()); + method->append_text (M("TP_SHARPENING_USM")); + method->append_text (M("TP_SHARPENING_RLD")); + method->show (); + hb->pack_start(*ml, Gtk::PACK_SHRINK, 4); + hb->pack_start(*method); + pack_start (*hb); + + rld = new Gtk::VBox (); + dradius = Gtk::manage (new Adjuster (M("TP_SHARPENING_EDRADIUS"), 0.5, 2.5, 0.01, 0.75)); + damount = Gtk::manage (new Adjuster (M("TP_SHARPENING_RLD_AMOUNT"), 0.0, 100, 1, 75)); + ddamping = Gtk::manage (new Adjuster (M("TP_SHARPENING_RLD_DAMPING"), 0, 100, 1, 20)); + diter = Gtk::manage (new Adjuster (M("TP_SHARPENING_RLD_ITERATIONS"), 5, 100, 1, 30)); + rld->pack_start (*dradius); + rld->pack_start (*damount); + rld->pack_start (*ddamping); + rld->pack_start (*diter); + dradius->show (); + damount->show (); + ddamping->show (); + diter->show (); + rld->show (); + + usm = new Gtk::VBox (); + usm->show (); + + Gtk::HSeparator *hsep6a = Gtk::manage (new Gtk::HSeparator()); + amount = Gtk::manage (new Adjuster (M("TP_SHARPENING_AMOUNT"), 1, 1000, 1, 200)); + radius = Gtk::manage (new Adjuster (M("TP_SHARPENING_RADIUS"), 0.3, 3, 0.01, 0.5)); + threshold = Gtk::manage (new ThresholdAdjuster (M("TP_SHARPENING_THRESHOLD"), 0., 2000., 20., 80., 2000., 1200., 0, false)); + threshold->setAdjusterListener (this); + threshold->setBgGradient(milestones); + pack_start(*hsep6a, Gtk::PACK_SHRINK, 2); + + pack_start (*usm); + + usm->pack_start(*radius); + usm->pack_start(*amount); + usm->pack_start(*threshold); + hsep6a->show (); + radius->show (); + amount->show (); + threshold->show (); + + Gtk::HSeparator *hsep6 = Gtk::manage (new Gtk::HSeparator()); + edgesonly = Gtk::manage (new Gtk::CheckButton (M("TP_SHARPENING_ONLYEDGES"))); + edgesonly->set_active (false); + edgebox = new Gtk::VBox (); + eradius = Gtk::manage (new Adjuster (M("TP_SHARPENING_EDRADIUS"), 0.5, 2.5, 0.1, 1.9)); + etolerance = Gtk::manage (new Adjuster (M("TP_SHARPENING_EDTOLERANCE"), 10, 10000, 100, 1000)); + usm->pack_start(*hsep6, Gtk::PACK_SHRINK, 2); + usm->pack_start(*edgesonly); + edgebox->pack_start(*eradius); + edgebox->pack_start(*etolerance); + edgebox->show (); + edgebin = Gtk::manage (new Gtk::VBox ()); + usm->pack_start (*edgebin); + edgebin->show (); + hsep6->show(); + edgesonly->show(); + eradius->show(); + etolerance->show(); + + Gtk::HSeparator *hsep6b = Gtk::manage (new Gtk::HSeparator()); + halocontrol = Gtk::manage (new Gtk::CheckButton (M("TP_SHARPENING_HALOCONTROL"))); + halocontrol->set_active (false); + hcbox = new Gtk::VBox (); + hcamount = Gtk::manage (new Adjuster (M("TP_SHARPENING_HCAMOUNT"), 1, 100, 1, 75)); + usm->pack_start(*hsep6b, Gtk::PACK_SHRINK, 2); + usm->pack_start(*halocontrol); + hcbox->pack_start(*hcamount); + hcbox->show (); + hcbin = Gtk::manage (new Gtk::VBox ()); + usm->pack_start (*hcbin); + hcbin->show (); + hsep6b->show (); + halocontrol->show (); + hcamount->show (); + + dradius->setAdjusterListener (this); + damount->setAdjusterListener (this); + ddamping->setAdjusterListener (this); + diter->setAdjusterListener (this); + radius->setAdjusterListener (this); + amount->setAdjusterListener (this); + eradius->setAdjusterListener (this); + etolerance->setAdjusterListener (this); + hcamount->setAdjusterListener (this); + + edgebox->reference (); + hcbox->reference (); + usm->reference (); + rld->reference (); + + eonlyConn = edgesonly->signal_toggled().connect( sigc::mem_fun(*this, &PrSharpening::edgesonly_toggled) ); + hcConn = halocontrol->signal_toggled().connect( sigc::mem_fun(*this, &PrSharpening::halocontrol_toggled) ); + method->signal_changed().connect( sigc::mem_fun(*this, &PrSharpening::method_changed) ); +} + +PrSharpening::~PrSharpening () +{ + + delete usm; + delete rld; + delete edgebox; + delete hcbox; +} + + +void PrSharpening::read (const ProcParams* pp, const ParamsEdited* pedited) +{ + + disableListener (); + + if (pedited) { + amount->setEditedState (pedited->prsharpening.amount ? Edited : UnEdited); + radius->setEditedState (pedited->prsharpening.radius ? Edited : UnEdited); + threshold->setEditedState (pedited->prsharpening.threshold ? Edited : UnEdited); + eradius->setEditedState (pedited->prsharpening.edges_radius ? Edited : UnEdited); + etolerance->setEditedState (pedited->prsharpening.edges_tolerance ? Edited : UnEdited); + hcamount->setEditedState (pedited->prsharpening.halocontrol_amount ? Edited : UnEdited); + damount->setEditedState (pedited->prsharpening.deconvamount ? Edited : UnEdited); + dradius->setEditedState (pedited->prsharpening.deconvradius ? Edited : UnEdited); + diter->setEditedState (pedited->prsharpening.deconviter ? Edited : UnEdited); + ddamping->setEditedState (pedited->prsharpening.deconvdamping ? Edited : UnEdited); + + halocontrol->set_inconsistent (multiImage && !pedited->prsharpening.halocontrol); + edgesonly->set_inconsistent (multiImage && !pedited->prsharpening.edgesonly); + set_inconsistent (multiImage && !pedited->prsharpening.enabled); + } + + setEnabled (pp->prsharpening.enabled); + + eonlyConn.block (true); + edgesonly->set_active (pp->prsharpening.edgesonly); + eonlyConn.block (false); + lastEdgesOnly = pp->prsharpening.edgesonly; + + hcConn.block (true); + halocontrol->set_active (pp->prsharpening.halocontrol); + hcConn.block (false); + lastHaloControl = pp->prsharpening.halocontrol; + + amount->setValue (pp->prsharpening.amount); + radius->setValue (pp->prsharpening.radius); + threshold->setValue(pp->prsharpening.threshold); + eradius->setValue (pp->prsharpening.edges_radius); + etolerance->setValue (pp->prsharpening.edges_tolerance); + hcamount->setValue (pp->prsharpening.halocontrol_amount); + + dradius->setValue (pp->prsharpening.deconvradius); + damount->setValue (pp->prsharpening.deconvamount); + diter->setValue (pp->prsharpening.deconviter); + ddamping->setValue (pp->prsharpening.deconvdamping); + + if (!batchMode) { + removeIfThere (edgebin, edgebox, false); + + if (edgesonly->get_active ()) { + edgebin->pack_start (*edgebox); + } + + removeIfThere (hcbin, hcbox, false); + + if (halocontrol->get_active ()) { + hcbin->pack_start (*hcbox); + } + + } + + if (pedited && !pedited->prsharpening.method) { + method->set_active (2); + } else if (pp->prsharpening.method == "usm") { + method->set_active (0); + } else if (pp->prsharpening.method == "rld") { + method->set_active (1); + } + + enableListener (); +} + +void PrSharpening::write (ProcParams* pp, ParamsEdited* pedited) +{ + + pp->prsharpening.amount = (int)amount->getValue(); + pp->prsharpening.enabled = getEnabled (); + pp->prsharpening.radius = radius->getValue (); + pp->prsharpening.threshold = threshold->getValue (); + pp->prsharpening.edgesonly = edgesonly->get_active (); + pp->prsharpening.edges_radius = eradius->getValue (); + pp->prsharpening.edges_tolerance = (int)etolerance->getValue (); + pp->prsharpening.halocontrol = halocontrol->get_active (); + pp->prsharpening.halocontrol_amount = (int)hcamount->getValue (); + pp->prsharpening.deconvradius = dradius->getValue (); + pp->prsharpening.deconviter = (int)diter->getValue (); + pp->prsharpening.deconvamount = (int)damount->getValue (); + pp->prsharpening.deconvdamping = (int)ddamping->getValue (); + + if (method->get_active_row_number() == 0) { + pp->prsharpening.method = "usm"; + } else if (method->get_active_row_number() == 1) { + pp->prsharpening.method = "rld"; + } + + 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.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(); + } +} + +void PrSharpening::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) +{ + + amount->setDefault (defParams->prsharpening.amount); + radius->setDefault (defParams->prsharpening.radius); + threshold->setDefault (defParams->prsharpening.threshold); + eradius->setDefault (defParams->prsharpening.edges_radius); + etolerance->setDefault (defParams->prsharpening.edges_tolerance); + hcamount->setDefault (defParams->prsharpening.halocontrol_amount); + damount->setDefault (defParams->prsharpening.deconvamount); + dradius->setDefault (defParams->prsharpening.deconvradius); + diter->setDefault (defParams->prsharpening.deconviter); + ddamping->setDefault (defParams->prsharpening.deconvdamping); + + if (pedited) { + amount->setDefaultEditedState (pedited->prsharpening.amount ? Edited : UnEdited); + radius->setDefaultEditedState (pedited->prsharpening.radius ? Edited : UnEdited); + threshold->setDefaultEditedState (pedited->prsharpening.threshold ? Edited : UnEdited); + eradius->setDefaultEditedState (pedited->prsharpening.edges_radius ? Edited : UnEdited); + etolerance->setDefaultEditedState (pedited->prsharpening.edges_tolerance ? Edited : UnEdited); + hcamount->setDefaultEditedState (pedited->prsharpening.halocontrol_amount ? Edited : UnEdited); + damount->setDefaultEditedState (pedited->prsharpening.deconvamount ? Edited : UnEdited); + dradius->setDefaultEditedState (pedited->prsharpening.deconvradius ? Edited : UnEdited); + diter->setDefaultEditedState (pedited->prsharpening.deconviter ? Edited : UnEdited); + ddamping->setDefaultEditedState (pedited->prsharpening.deconvdamping ? Edited : UnEdited); + } else { + amount->setDefaultEditedState (Irrelevant); + radius->setDefaultEditedState (Irrelevant); + threshold->setDefaultEditedState (Irrelevant); + eradius->setDefaultEditedState (Irrelevant); + etolerance->setDefaultEditedState (Irrelevant); + hcamount->setDefaultEditedState (Irrelevant); + damount->setDefaultEditedState (Irrelevant); + dradius->setDefaultEditedState (Irrelevant); + diter->setDefaultEditedState (Irrelevant); + ddamping->setDefaultEditedState (Irrelevant); + } +} + +void PrSharpening::adjusterChanged (Adjuster* a, double newval) +{ + + if (listener && (multiImage || getEnabled()) ) { + + Glib::ustring costr; + + if (a == radius || a == dradius) { + costr = Glib::ustring::format (std::setw(3), std::fixed, std::setprecision(2), a->getValue()); + } else if (a == eradius) { + costr = Glib::ustring::format (std::setw(2), std::fixed, std::setprecision(1), a->getValue()); + } else { + costr = Glib::ustring::format ((int)a->getValue()); + } + + if (a == amount) { + listener->panelChanged (EvPrShrAmount, costr); + } else if (a == radius) { + listener->panelChanged (EvPrShrRadius, costr); + } else if (a == eradius) { + listener->panelChanged (EvPrShrEdgeRadius, costr); + } else if (a == etolerance) { + listener->panelChanged (EvPrShrEdgeTolerance, costr); + } else if (a == hcamount) { + listener->panelChanged (EvPrShrHaloAmount, costr); + } else if (a == dradius) { + listener->panelChanged (EvPrShrDRadius, costr); + } else if (a == damount) { + listener->panelChanged (EvPrShrDAmount, costr); + } else if (a == ddamping) { + listener->panelChanged (EvPrShrDDamping, costr); + } else if (a == diter) { + listener->panelChanged (EvPrShrDIterations, costr); + } + } +} + +void PrSharpening::enabledChanged () +{ + + if (listener) { + if (get_inconsistent()) { + listener->panelChanged (EvPrShrEnabled, M("GENERAL_UNCHANGED")); + } else if (getEnabled()) { + listener->panelChanged (EvPrShrEnabled, M("GENERAL_ENABLED")); + } else { + listener->panelChanged (EvPrShrEnabled, M("GENERAL_DISABLED")); + } + } +} + +void PrSharpening::edgesonly_toggled () +{ + + if (multiImage) { + if (edgesonly->get_inconsistent()) { + edgesonly->set_inconsistent (false); + eonlyConn.block (true); + edgesonly->set_active (false); + eonlyConn.block (false); + } else if (lastEdgesOnly) { + edgesonly->set_inconsistent (true); + } + + lastEdgesOnly = edgesonly->get_active (); + } + + if (!batchMode) { + removeIfThere (edgebin, edgebox, false); + + if (edgesonly->get_active ()) { + edgebin->pack_start (*edgebox); + } + } + + if (listener && (multiImage || getEnabled()) ) { + if (edgesonly->get_inconsistent()) { + listener->panelChanged (EvPrShrEdgeOnly, M("GENERAL_INITIALVALUES")); + } else if (edgesonly->get_active ()) { + listener->panelChanged (EvPrShrEdgeOnly, M("GENERAL_ENABLED")); + } else { + listener->panelChanged (EvPrShrEdgeOnly, M("GENERAL_DISABLED")); + } + } +} + +void PrSharpening::halocontrol_toggled () +{ + + if (multiImage) { + if (halocontrol->get_inconsistent()) { + halocontrol->set_inconsistent (false); + hcConn.block (true); + halocontrol->set_active (false); + hcConn.block (false); + } else if (lastHaloControl) { + halocontrol->set_inconsistent (true); + } + + lastHaloControl = halocontrol->get_active (); + } + + if (!batchMode) { + removeIfThere (hcbin, hcbox, false); + + if (halocontrol->get_active ()) { + hcbin->pack_start (*hcbox); + } + } + + if (listener && (multiImage || getEnabled()) ) { + if (halocontrol->get_inconsistent()) { + listener->panelChanged (EvPrShrHaloControl, M("GENERAL_INITIALVALUES")); + } else if (halocontrol->get_active ()) { + listener->panelChanged (EvPrShrHaloControl, M("GENERAL_ENABLED")); + } else { + listener->panelChanged (EvPrShrHaloControl, M("GENERAL_DISABLED")); + } + } +} + +void PrSharpening::method_changed () +{ + + 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 (listener && (multiImage || getEnabled()) ) { + listener->panelChanged (EvPrShrMethod, method->get_active_text ()); + } + +} + +void PrSharpening::adjusterChanged (ThresholdAdjuster* a, int newBottomL, int newTopL, int newBottomR, int newTopR) { + if (listener && (multiImage||getEnabled()) ) { + if(a==threshold) { + listener->panelChanged (EvPrShrThresh,threshold->getHistoryString()); + } + } +} + +void PrSharpening::setBatchMode (bool batchMode) +{ + + ToolPanel::setBatchMode (batchMode); + + removeIfThere (hcbin, hcbox, false); + hcbin->pack_start (*hcbox); + removeIfThere (edgebin, edgebox, false); + edgebin->pack_start (*edgebox); + + radius->showEditedCB (); + amount->showEditedCB (); + threshold->showEditedCB (); + eradius->showEditedCB (); + etolerance->showEditedCB (); + hcamount->showEditedCB (); + dradius->showEditedCB (); + damount->showEditedCB (); + ddamping->showEditedCB (); + diter->showEditedCB (); + method->append_text (M("GENERAL_UNCHANGED")); +} + +void PrSharpening::setAdjusterBehavior (bool amountadd) +{ + + amount->setAddMode(amountadd); + damount->setAddMode(amountadd); +} + +void PrSharpening::trimValues (rtengine::procparams::ProcParams* pp) +{ + + amount->trimValue(pp->prsharpening.amount); + damount->trimValue(pp->prsharpening.deconvamount); +} diff --git a/rtgui/prsharpening.h b/rtgui/prsharpening.h new file mode 100644 index 000000000..c0739b818 --- /dev/null +++ b/rtgui/prsharpening.h @@ -0,0 +1,77 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _PRSHARPENING_H_ +#define _PRSHARPENING_H_ + +#include +#include "adjuster.h" +#include "thresholdadjuster.h" +#include "toolpanel.h" + +class PrSharpening : public ToolParamBlock, public ThresholdAdjusterListener, public AdjusterListener, public FoldableToolPanel +{ + +protected: + MyComboBoxText* method; + Adjuster* dradius; + Adjuster* damount; + Adjuster* ddamping; + Adjuster* diter; + Gtk::VBox* usm; + Gtk::VBox* rld; + + Adjuster* radius; + Adjuster* amount; + Adjuster* eradius; + Adjuster* etolerance; + Adjuster* hcamount; + Gtk::VBox* edgebin; + Gtk::VBox* hcbin; + Gtk::VBox* edgebox; + Gtk::VBox* hcbox; + ThresholdAdjuster* threshold; + Gtk::CheckButton* edgesonly; + bool lastEdgesOnly; + sigc::connection eonlyConn; + Gtk::CheckButton* halocontrol; + bool lastHaloControl; + sigc::connection hcConn; + +public: + + PrSharpening (); + virtual ~PrSharpening (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited = NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = NULL); + void setBatchMode (bool batchMode); + + void adjusterChanged (Adjuster* a, double newval); + void enabledChanged (); + void edgesonly_toggled (); + void halocontrol_toggled (); + void method_changed (); + void adjusterChanged (ThresholdAdjuster* a, int newBottomL, int newTopL, int newBottomR, int newTopR); + + void setAdjusterBehavior (bool amountadd); + void trimValues (rtengine::procparams::ProcParams* pp); +}; + +#endif diff --git a/rtgui/quickzoomlistener.h b/rtgui/quickzoomlistener.h new file mode 100644 index 000000000..4cbaad8fc --- /dev/null +++ b/rtgui/quickzoomlistener.h @@ -0,0 +1,34 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _QZLISTENER_ +#define _QZLISTENER_ + +class QuickZoomListener { + + public: + + virtual void increaseZoom () {} + virtual void decreaseZoom () {} + virtual void quickZoom () {} + virtual void increaseCropZoom () {} + virtual void decreaseCropZoom () {} + virtual void quickCropZoom () {} +}; + +#endif diff --git a/rtgui/rawcacorrection.cc b/rtgui/rawcacorrection.cc new file mode 100644 index 000000000..b54e92449 --- /dev/null +++ b/rtgui/rawcacorrection.cc @@ -0,0 +1,177 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "rawcacorrection.h" +#include "guiutils.h" +#include "../rtengine/safegtk.h" +#include +#include "rtimage.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +RAWCACorr::RAWCACorr () : FoldableToolPanel(this, "rawcacorrection", M("TP_CHROMATABERR_LABEL")) +{ + Gtk::Image* icaredL = Gtk::manage (new RTImage ("ajd-ca-red1.png")); + Gtk::Image* icaredR = Gtk::manage (new RTImage ("ajd-ca-red2.png")); + Gtk::Image* icablueL = Gtk::manage (new RTImage ("ajd-ca-blue1.png")); + Gtk::Image* icablueR = Gtk::manage (new RTImage ("ajd-ca-blue2.png")); + + caAutocorrect = Gtk::manage(new Gtk::CheckButton((M("TP_RAWCACORR_AUTO")))); + caRed = Gtk::manage(new Adjuster (M("TP_RAWCACORR_CARED"),-4.0,4.0,0.1,0,icaredL,icaredR)); + caRed->setAdjusterListener (this); + if (caRed->delay < 1000) caRed->delay = 1000; + caRed->show(); + caBlue = Gtk::manage(new Adjuster (M("TP_RAWCACORR_CABLUE"),-4.0,4.0,0.1,0,icablueL,icablueR)); + caBlue->setAdjusterListener (this); + if (caBlue->delay < 1000) caBlue->delay = 1000; + caBlue->show(); + + pack_start( *caAutocorrect, Gtk::PACK_SHRINK, 4); + pack_start( *caRed, Gtk::PACK_SHRINK, 4); + pack_start( *caBlue, Gtk::PACK_SHRINK, 4); + + caacsconn = caAutocorrect->signal_toggled().connect ( sigc::mem_fun(*this, &RAWCACorr::caCorrectionChanged), true); +} + +void RAWCACorr::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited) +{ + disableListener (); + caacsconn.block (true); + + if(pedited ){ + caAutocorrect->set_inconsistent(!pedited->raw.caCorrection); + caRed->setEditedState( pedited->raw.caRed ? Edited : UnEdited ); + caBlue->setEditedState( pedited->raw.caBlue ? Edited : UnEdited ); + } + + lastCA = pp->raw.ca_autocorrect; + + // disable Red and Blue sliders when caAutocorrect is enabled + caRed->set_sensitive(!pp->raw.ca_autocorrect); + caBlue->set_sensitive(!pp->raw.ca_autocorrect); + + caAutocorrect->set_active(pp->raw.ca_autocorrect); + caRed->setValue (pp->raw.cared); + caBlue->setValue (pp->raw.cablue); + + caacsconn.block (false); + enableListener (); +} + +void RAWCACorr::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pedited) +{ + pp->raw.ca_autocorrect = caAutocorrect->get_active(); + pp->raw.cared = caRed->getValue(); + pp->raw.cablue = caBlue->getValue(); + + if (pedited) { + pedited->raw.caCorrection = !caAutocorrect->get_inconsistent(); + pedited->raw.caRed = caRed->getEditedState (); + pedited->raw.caBlue = caBlue->getEditedState (); + } + +} + +void RAWCACorr::adjusterChanged (Adjuster* a, double newval) +{ + if (listener) { + + Glib::ustring value = a->getTextValue(); + + if (a == caRed) + listener->panelChanged (EvPreProcessCARed, value ); + else if (a == caBlue) + listener->panelChanged (EvPreProcessCABlue, value ); + } +} + +void RAWCACorr::setBatchMode(bool batchMode) +{ + ToolPanel::setBatchMode (batchMode); + caRed->showEditedCB (); + caBlue->showEditedCB (); +} + +void RAWCACorr::setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited) +{ + caRed->setDefault( defParams->raw.cared); + caBlue->setDefault( defParams->raw.cablue); + + if (pedited) { + caRed->setDefaultEditedState( pedited->raw.caRed ? Edited : UnEdited); + caBlue->setDefaultEditedState( pedited->raw.caBlue ? Edited : UnEdited); + } else { + caRed->setDefaultEditedState( Irrelevant ); + caBlue->setDefaultEditedState( Irrelevant ); + } +} + +void RAWCACorr::caCorrectionChanged() +{ + if (batchMode) { + if (caAutocorrect->get_inconsistent()) { + caAutocorrect->set_inconsistent (false); + caacsconn.block (true); + caAutocorrect->set_active (false); + caacsconn.block (false); + } + else if (lastCA) + caAutocorrect->set_inconsistent (true); + + lastCA = caAutocorrect->get_active (); + + } + /*else { + // For non batch mode, we disable the red and blue slider if caAutocorrect is true + if (caAutocorrect->get_active ()) { + caRed->set_sensitive(false); + caBlue->set_sensitive(false); + } + else { + caRed->set_sensitive(true); + caBlue->set_sensitive(true); + } + }*/ + + // disable Red and Blue sliders when caAutocorrect is enabled + caRed->set_sensitive(!caAutocorrect->get_active ()); + caBlue->set_sensitive(!caAutocorrect->get_active ()); + if (caAutocorrect->get_active ()){ + // set caRed and caBlue to 0 as RawImageSource::CA_correct_RT uses this as + // a condition for auto-CA correction. Alternative would be to change + // RawImageSource::CA_correct_RT and pass it ca_autocorrect value + caRed->setValue(0); + caBlue->setValue(0); + } + + if (listener) + listener->panelChanged (EvPreProcessAutoCA, caAutocorrect->get_active()?M("GENERAL_ENABLED"):M("GENERAL_DISABLED")); +} + +void RAWCACorr::setAdjusterBehavior (bool caadd) { + + caRed->setAddMode(caadd); + caBlue->setAddMode(caadd); +} + +void RAWCACorr::trimValues (rtengine::procparams::ProcParams* pp) { + + caRed->trimValue(pp->raw.cared); + caBlue->trimValue(pp->raw.cablue); +} diff --git a/rtgui/rawcacorrection.h b/rtgui/rawcacorrection.h new file mode 100644 index 000000000..aa4d854dc --- /dev/null +++ b/rtgui/rawcacorrection.h @@ -0,0 +1,51 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _RAWCACORRECTION_H_ +#define _RAWCACORRECTION_H_ + +#include +#include "adjuster.h" +#include "toolpanel.h" +#include "../rtengine/rawimage.h" + +class RAWCACorr : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel { + +protected: + Gtk::CheckButton* caAutocorrect; + Adjuster* caRed; + Adjuster* caBlue; + bool lastCA; + sigc::connection caacsconn; + +public: + + RAWCACorr (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setAdjusterBehavior (bool caadd); + void trimValues (rtengine::procparams::ProcParams* pp); + + void adjusterChanged (Adjuster* a, double newval); + void caCorrectionChanged (); +}; + +#endif diff --git a/rtgui/rawexposure.cc b/rtgui/rawexposure.cc new file mode 100644 index 000000000..46d83fe60 --- /dev/null +++ b/rtgui/rawexposure.cc @@ -0,0 +1,113 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "rawexposure.h" +#include "guiutils.h" +#include "../rtengine/safegtk.h" +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +RAWExposure::RAWExposure () : FoldableToolPanel(this, "rawexposure", M("TP_EXPOS_WHITEPOINT_LABEL")) +{ + PexPos = Gtk::manage(new Adjuster (M("TP_RAWEXPOS_LINEAR"),0.1,16.0,0.01,1)); + PexPos->setAdjusterListener (this); + if (PexPos->delay < 1000) PexPos->delay = 1000; + PexPos->show(); + PexPreser = Gtk::manage(new Adjuster (M("TP_RAWEXPOS_PRESER"),0,2.5,0.1,0)); + PexPreser->setAdjusterListener (this); + if (PexPreser->delay < 1000) PexPreser->delay = 1000; + PexPreser->show(); + + pack_start( *PexPos, Gtk::PACK_SHRINK, 4);//exposi + // raw highlight exposure setting is obsolete, removing from GUI + //pack_start( *PexPreser, Gtk::PACK_SHRINK, 4); +} + +void RAWExposure::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited) +{ + disableListener (); + + if(pedited ){ + PexPos->setEditedState( pedited->raw.exPos ? Edited : UnEdited ); + PexPreser->setEditedState( pedited->raw.exPreser ? Edited : UnEdited ); + } + + PexPos->setValue (pp->raw.expos); + PexPreser->setValue (pp->raw.preser);//exposi + + enableListener (); +} + +void RAWExposure::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pedited) +{ + pp->raw.expos = PexPos->getValue(); + pp->raw.preser = PexPreser->getValue();//exposi + + if (pedited) { + pedited->raw.exPos = PexPos->getEditedState (); + pedited->raw.exPreser = PexPreser->getEditedState ();//exposi + } + +} + +void RAWExposure::adjusterChanged (Adjuster* a, double newval) +{ + if (listener) { + Glib::ustring value = a->getTextValue(); + + if (a == PexPos ) + listener->panelChanged (EvPreProcessExpCorrLinear, value ); + else if (a == PexPreser && ABS(PexPos->getValue()-1.0)>0.0001) // update takes long, only do it if it would have an effect + listener->panelChanged (EvPreProcessExpCorrPH, value ); + } +} + +void RAWExposure::setBatchMode(bool batchMode) +{ + ToolPanel::setBatchMode (batchMode); + PexPos->showEditedCB (); + PexPreser->showEditedCB ();//exposure +} + +void RAWExposure::setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited) +{ + PexPos->setDefault( defParams->raw.expos); + PexPreser->setDefault( defParams->raw.preser); + + if (pedited) { + PexPos->setDefaultEditedState( pedited->raw.exPos ? Edited : UnEdited); + PexPreser->setDefaultEditedState( pedited->raw.exPreser ? Edited : UnEdited); + } else { + PexPos->setDefaultEditedState( Irrelevant ); + PexPreser->setDefaultEditedState( Irrelevant ); + } +} + +void RAWExposure::setAdjusterBehavior (bool pexposadd, bool pexpreseradd) { + + PexPos->setAddMode(pexposadd); + PexPreser->setAddMode(pexpreseradd); +} + +void RAWExposure::trimValues (rtengine::procparams::ProcParams* pp) { + + PexPos->trimValue(pp->raw.expos); + PexPreser->trimValue(pp->raw.preser); +} diff --git a/rtgui/rawexposure.h b/rtgui/rawexposure.h new file mode 100644 index 000000000..16e0aa741 --- /dev/null +++ b/rtgui/rawexposure.h @@ -0,0 +1,48 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _RAWEXPOSURE_H_ +#define _RAWEXPOSURE_H_ + +#include +#include "adjuster.h" +#include "toolpanel.h" +#include "../rtengine/rawimage.h" + +class RAWExposure : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel { + +protected: + Adjuster* PexPos; + Adjuster* PexPreser; + +private: +// Gtk::CheckButton* PextwoGreen; +public: + + RAWExposure (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void adjusterChanged (Adjuster* a, double newval); + void setAdjusterBehavior (bool pexposadd, bool pexpreseradd); + void trimValues (rtengine::procparams::ProcParams* pp); +}; + +#endif diff --git a/rtgui/rawprocess.cc b/rtgui/rawprocess.cc new file mode 100644 index 000000000..0522f8e24 --- /dev/null +++ b/rtgui/rawprocess.cc @@ -0,0 +1,272 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "rawprocess.h" +#include "options.h" +#include "guiutils.h" +using namespace rtengine; +using namespace rtengine::procparams; + +RawProcess::RawProcess () : FoldableToolPanel(this) +{ + Gtk::HBox* hb1 = Gtk::manage (new Gtk::HBox ()); + hb1->pack_start (*Gtk::manage (new Gtk::Label ( M("TP_RAW_DMETHOD") +": ")),Gtk::PACK_SHRINK, 4); + dmethod = Gtk::manage (new MyComboBoxText ()); + for( size_t i=0; iappend_text(procparams::RAWParams::methodstring[i]); + + dmethod->set_active(0); + hb1->set_tooltip_markup (M("TP_RAW_DMETHOD_TOOLTIP")); + + hb1->pack_end (*dmethod, Gtk::PACK_EXPAND_WIDGET, 4); + pack_start( *hb1, Gtk::PACK_SHRINK, 4); + + dcbOptions = Gtk::manage (new Gtk::VBox ()); + dcbOptions->set_border_width(4); + + dcbIterations = Gtk::manage (new Adjuster (M("TP_RAW_DCBITERATIONS"),0,5,1,2)); + dcbIterations->setAdjusterListener (this); + if (dcbIterations->delay < 1000) dcbIterations->delay = 1000; + dcbIterations->show(); + dcbEnhance = Gtk::manage (new Gtk::CheckButton(M("TP_RAW_DCBENHANCE"))); + dcbOptions->pack_start(*dcbIterations); + dcbOptions->pack_start(*dcbEnhance); + pack_start( *dcbOptions, Gtk::PACK_SHRINK, 4); + + lmmseOptions = Gtk::manage (new Gtk::VBox ()); + lmmseOptions->set_border_width(4); + + lmmseIterations = Gtk::manage (new Adjuster (M("TP_RAW_LMMSEITERATIONS"),0,6,1,2)); + lmmseIterations->setAdjusterListener (this); + lmmseIterations->set_tooltip_markup (M("TP_RAW_LMMSE_TOOLTIP")); + + if (lmmseIterations->delay < 1000) lmmseIterations->delay = 1000; + lmmseIterations->show(); + lmmseOptions->pack_start(*lmmseIterations); + pack_start( *lmmseOptions, Gtk::PACK_SHRINK, 4); + + pack_start( *Gtk::manage( new Gtk::HSeparator()), Gtk::PACK_SHRINK, 0 ); + ccSteps = Gtk::manage (new Adjuster (M("TP_RAW_FALSECOLOR"),0,5,1,0 )); + ccSteps->setAdjusterListener (this); + if (ccSteps->delay < 1000) ccSteps->delay = 1000; + ccSteps->show(); + pack_start( *ccSteps, Gtk::PACK_SHRINK, 4); + + //pack_start( *Gtk::manage( new Gtk::HSeparator()), Gtk::PACK_SHRINK, 0 ); + //allOptions = Gtk::manage (new Gtk::VBox ()); + //allOptions->set_border_width(2); + //allEnhance = Gtk::manage (new Gtk::CheckButton(M("TP_RAW_ALLENHANCE"))); + //allOptions->pack_start(*allEnhance); + //pack_start( *allOptions, Gtk::PACK_SHRINK, 4); + + methodconn = dmethod->signal_changed().connect( sigc::mem_fun(*this, &RawProcess::methodChanged) ); + dcbEnhconn = dcbEnhance->signal_toggled().connect ( sigc::mem_fun(*this, &RawProcess::dcbEnhanceChanged), true); + //allEnhconn = allEnhance->signal_toggled().connect ( sigc::mem_fun(*this, &RawProcess::allEnhanceChanged), true); +} + + +void RawProcess::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited) +{ + disableListener (); + methodconn.block (true); + dcbEnhconn.block (true); + //allEnhconn.block (true); + + dmethod->set_active(procparams::RAWParams::numMethods); + for( size_t i=0; i< procparams::RAWParams::numMethods;i++) + if( pp->raw.dmethod == procparams::RAWParams::methodstring[i]){ + dmethod->set_active(i); + oldSelection = i; + break; + } + + if(pedited ){ + ccSteps->setEditedState (pedited->raw.ccSteps ? Edited : UnEdited); + dcbIterations->setEditedState ( pedited->raw.dcbIterations ? Edited : UnEdited); + dcbEnhance->set_inconsistent(!pedited->raw.dcbEnhance); + //allEnhance->set_inconsistent(!pedited->raw.allEnhance); + lmmseIterations->setEditedState ( pedited->raw.lmmseIterations ? Edited : UnEdited); + + if( !pedited->raw.dmethod ) + dmethod->set_active(procparams::RAWParams::numMethods); // No name + } + + //allEnhance->set_active(pp->raw.all_enhance); + + dcbIterations->setValue (pp->raw.dcb_iterations); + dcbEnhance->set_active(pp->raw.dcb_enhance); + ccSteps->setValue (pp->raw.ccSteps); + if (pp->raw.dmethod == procparams::RAWParams::methodstring[procparams::RAWParams::dcb] || + dmethod->get_active_row_number() == procparams::RAWParams::numMethods) + dcbOptions->show(); + else + dcbOptions->hide(); + + lmmseIterations->setValue (pp->raw.lmmse_iterations); + if (pp->raw.dmethod == procparams::RAWParams::methodstring[procparams::RAWParams::lmmse] || + dmethod->get_active_row_number() == procparams::RAWParams::numMethods) + lmmseOptions->show(); + else + lmmseOptions->hide(); + + // Flase color suppression is applied to all demozaicing method, so don't hide anything + /*if (pp->raw.dmethod == procparams::RAWParams::methodstring[procparams::RAWParams::eahd] || + pp->raw.dmethod == procparams::RAWParams::methodstring[procparams::RAWParams::hphd] || + pp->raw.dmethod == procparams::RAWParams::methodstring[procparams::RAWParams::vng4]) + ccSteps->show(); + else + ccSteps->hide();*/ + + lastDCBen = pp->raw.dcb_enhance; + //lastALLen = pp->raw.all_enhance; + + methodconn.block (false); + dcbEnhconn.block (false); + //allEnhconn.block (false); + + enableListener (); +} + +void RawProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pedited) +{ + pp->raw.ccSteps = ccSteps->getIntValue(); + pp->raw.dcb_iterations = dcbIterations->getIntValue(); + pp->raw.dcb_enhance = dcbEnhance->get_active(); + //pp->raw.all_enhance = allEnhance->get_active(); + pp->raw.lmmse_iterations = lmmseIterations->getIntValue(); + + int currentRow = dmethod->get_active_row_number(); + if( currentRow>=0 && currentRow < procparams::RAWParams::numMethods) + pp->raw.dmethod = procparams::RAWParams::methodstring[currentRow]; + + if (pedited) { + pedited->raw.ccSteps = ccSteps->getEditedState (); + pedited->raw.dmethod = dmethod->get_active_row_number() != procparams::RAWParams::numMethods; + pedited->raw.dcbIterations = dcbIterations->getEditedState (); + pedited->raw.dcbEnhance = !dcbEnhance->get_inconsistent(); + //pedited->raw.allEnhance = !allEnhance->get_inconsistent(); + pedited->raw.lmmseIterations = lmmseIterations->getEditedState (); + + } +} + +void RawProcess::setBatchMode(bool batchMode) +{ + dmethod->append_text (M("GENERAL_UNCHANGED")); + dmethod->set_active(procparams::RAWParams::numMethods); // No name + dcbOptions->hide(); + lmmseOptions->hide(); + ToolPanel::setBatchMode (batchMode); + ccSteps->showEditedCB (); + dcbIterations->showEditedCB (); + lmmseIterations->showEditedCB (); + +} + +void RawProcess::setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited) +{ + dcbIterations->setDefault( defParams->raw.dcb_iterations); + lmmseIterations->setDefault( defParams->raw.lmmse_iterations); + ccSteps->setDefault (defParams->raw.ccSteps); + if (pedited) { + dcbIterations->setDefaultEditedState( pedited->raw.dcbIterations ? Edited : UnEdited); + lmmseIterations->setDefaultEditedState( pedited->raw.lmmseIterations ? Edited : UnEdited); + ccSteps->setDefaultEditedState(pedited->raw.ccSteps ? Edited : UnEdited); + }else{ + dcbIterations->setDefaultEditedState( Irrelevant ); + lmmseIterations->setDefaultEditedState( Irrelevant ); + ccSteps->setDefaultEditedState(Irrelevant ); + } +} + +void RawProcess::adjusterChanged (Adjuster* a, double newval) +{ + if (listener) { + if (a == dcbIterations) + listener->panelChanged (EvDemosaicDCBIter, a->getTextValue() ); + else if (a == ccSteps) + listener->panelChanged (EvDemosaicFalseColorIter, a->getTextValue() ); + else if (a == lmmseIterations) + listener->panelChanged (EvDemosaicLMMSEIter, a->getTextValue() ); + + } +} + +void RawProcess::methodChanged () +{ + int curSelection = dmethod->get_active_row_number(); + if ( curSelection == procparams::RAWParams::dcb){ + dcbOptions->show(); + }else{ + dcbOptions->hide(); + } + if ( curSelection == procparams::RAWParams::lmmse){ + lmmseOptions->show(); + }else{ + lmmseOptions->hide(); + } + + Glib::ustring methodName=""; + bool ppreq = false; + if( curSelection>=0 && curSelection < procparams::RAWParams::numMethods) { + methodName = procparams::RAWParams::methodstring[curSelection]; + if (curSelection == procparams::RAWParams::mono || oldSelection == procparams::RAWParams::mono) { + ppreq = true; + } + } + oldSelection = curSelection; + + if (listener) + listener->panelChanged (ppreq ? EvDemosaicMethodPreProc : EvDemosaicMethod, methodName); +} + +void RawProcess::dcbEnhanceChanged () +{ + if (batchMode) { + if (dcbEnhance->get_inconsistent()) { + dcbEnhance->set_inconsistent (false); + dcbEnhconn.block (true); + dcbEnhance->set_active (false); + dcbEnhconn.block (false); + } + else if (lastDCBen) + dcbEnhance->set_inconsistent (true); + + lastDCBen = dcbEnhance->get_active (); + } + if (listener) + listener->panelChanged (EvDemosaicDCBEnhanced, dcbEnhance->get_active()?M("GENERAL_ENABLED"):M("GENERAL_DISABLED")); +} + +/*void RawProcess::allEnhanceChanged () +{ + if (batchMode) { + if (allEnhance->get_inconsistent()) { + allEnhance->set_inconsistent (false); + allEnhconn.block (true); + allEnhance->set_active (false); + allEnhconn.block (false); + } + else if (lastALLen) + allEnhance->set_inconsistent (true); + + lastALLen = allEnhance->get_active (); + } + if (listener) + listener->panelChanged (EvDemosaicALLEnhanced, allEnhance->get_active()?M("GENERAL_ENABLED"):M("GENERAL_DISABLED")); +}*/ diff --git a/rtgui/rawprocess.h b/rtgui/rawprocess.h new file mode 100644 index 000000000..f88c7bdc0 --- /dev/null +++ b/rtgui/rawprocess.h @@ -0,0 +1,63 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _RAWPROCESS_H_ +#define _RAWPROCESS_H_ + +#include +#include "adjuster.h" +#include "guiutils.h" +#include "toolpanel.h" + + +class RawProcess : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel{ + + protected: + + MyComboBoxText* dmethod; + Gtk::Label* methodl; + Adjuster* ccSteps; + Gtk::VBox *dcbOptions; + Adjuster* dcbIterations; + Gtk::CheckButton* dcbEnhance; + //Gtk::VBox *allOptions; + //Gtk::CheckButton* allEnhance; + Gtk::VBox *lmmseOptions; + Adjuster* lmmseIterations; + + bool lastDCBen; + int oldSelection; + //bool lastALLen; + sigc::connection methodconn,dcbEnhconn; //,allEnhconn; + public: + + RawProcess (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + + void methodChanged (); + void adjusterChanged (Adjuster* a, double newval); + void dcbEnhanceChanged(); + //void allEnhanceChanged(); + +}; + +#endif diff --git a/rtgui/recentbrowser.cc b/rtgui/recentbrowser.cc new file mode 100644 index 000000000..8d0abde1c --- /dev/null +++ b/rtgui/recentbrowser.cc @@ -0,0 +1,77 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "recentbrowser.h" +#include "multilangmgr.h" +#include "options.h" + +using namespace rtengine; + +RecentBrowser::RecentBrowser () : listener (NULL) { + + recentDirs = Gtk::manage (new MyComboBoxText ()); + + Gtk::Frame* frame = Gtk::manage (new Gtk::Frame (M("MAIN_FRAME_RECENT"))); + frame->add (*recentDirs); + for(size_t i=0;iappend_text (options.recentFolders[i]); + } + + pack_start (*frame, Gtk::PACK_SHRINK, 4); + + conn = recentDirs->signal_changed().connect(sigc::mem_fun(*this, &RecentBrowser::selectionChanged)); + + show_all (); +} + +void RecentBrowser::selectionChanged () { + + Glib::ustring sel = recentDirs->get_active_text (); + if (sel!="" && listener) + listener->selectDir (sel); +} + +void RecentBrowser::dirSelected (const Glib::ustring& dirname, const Glib::ustring& openfile) { + + size_t numFolders = options.recentFolders.size(); + if(numFolders>0) { // search entry and move to top if it exists + size_t i; + for(i=0;i0) { + if(iremove_text (dirname); + recentDirs->prepend_text (dirname); + recentDirs->set_active_text (dirname); + + conn.block (false); +} + diff --git a/rtgui/recentbrowser.h b/rtgui/recentbrowser.h new file mode 100644 index 000000000..dc309945b --- /dev/null +++ b/rtgui/recentbrowser.h @@ -0,0 +1,46 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _RECENTBROWSER_ +#define _RECENTBROWSER_ + +#include +#include "dirbrowserremoteinterface.h" +#include "dirselectionlistener.h" +#include "multilangmgr.h" +#include "guiutils.h" + +class RecentBrowser : public Gtk::VBox, public DirSelectionListener { + + Gtk::ComboBoxText* recentDirs; + sigc::connection conn; + DirBrowserRemoteInterface* listener; + + public: + + RecentBrowser (); + + void setDirBrowserRemoteInterface (DirBrowserRemoteInterface* l) { listener = l; } + + void selectionChanged (); + void dirSelected (const Glib::ustring& dirname, const Glib::ustring& openfile=""); +}; + +#endif + + diff --git a/rtgui/recentselectionlistener.h b/rtgui/recentselectionlistener.h new file mode 100644 index 000000000..f1765cb7c --- /dev/null +++ b/rtgui/recentselectionlistener.h @@ -0,0 +1,30 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _RECENTSELECTIONLISTENER_ +#define _RECENTSELECTIONLISTENER_ + +#include + +class RecentSelectionListener { + + public: + virtual void recentSelected (Glib::ustring recentdir) {} +}; + +#endif diff --git a/rtgui/renamedlg.cc b/rtgui/renamedlg.cc new file mode 100644 index 000000000..97883ce03 --- /dev/null +++ b/rtgui/renamedlg.cc @@ -0,0 +1,219 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "renamedlg.h" +#include "multilangmgr.h" +#include "options.h" +#include "rtimage.h" + +RenameDialog::RenameDialog (Gtk::Window* parent) + : Gtk::Dialog (M("FILEBROWSER_RENAMEDLGLABEL"), *parent, true, true), p(parent), imageData(NULL) { + + Gtk::Table* names = Gtk::manage (new Gtk::Table (2, 2)); + Gtk::Label* onlab = Gtk::manage (new Gtk::Label (M("FILEBROWSER_CURRENT_NAME"))); + Gtk::Label* nnlab = Gtk::manage (new Gtk::Label (M("FILEBROWSER_NEW_NAME"))); + oldName = Gtk::manage (new Gtk::Label ("alma")); + newName = Gtk::manage (new Gtk::Entry ()); + + names->attach (*onlab, 0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + names->attach (*oldName, 1, 2, 0, 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + names->attach (*nnlab, 0, 1, 1, 2, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + names->attach (*newName, 1, 2, 1, 2, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + get_vbox()->pack_start (*names, Gtk::PACK_SHRINK, 4); + +// Issue 316 +// Gtk::HBox* tbox = Gtk::manage (new Gtk::HBox()); +// useTmpl = Gtk::manage (new Gtk::CheckButton (M("FILEBROWSER_USETEMPLATE"))); +// templates = Gtk::manage (new MyComboBox ()); +// templateModel = Gtk::ListStore::create (templateColumns); +// templates->set_model (templateModel); +// templates->pack_start (templateColumns.tmplName); + +// tbox->pack_start (*useTmpl, Gtk::PACK_SHRINK, 4); +// tbox->pack_start (*templates); + +// get_vbox()->pack_start (*tbox, Gtk::PACK_SHRINK, 4); + + add_button (Gtk::Stock::OK, Gtk::RESPONSE_OK); + add_button (Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); +// Issue 316 +// all = add_button ("All", RESPONSE_ALL); + + newName->set_activates_default (true); + set_default_response (Gtk::RESPONSE_OK); +// Issue 316 +// fillTemplateList (); + +// templates->set_row_separator_func (sigc::mem_fun(*this, &RenameDialog::rowSeparatorFunc)); +// templates->signal_changed().connect(sigc::mem_fun(*this, &RenameDialog::tmplSelectionChanged)); +// useTmpl->signal_toggled().connect( sigc::mem_fun(*this, &RenameDialog::useTemplToggled) ); + +// useTmpl->set_active (options.renameUseTemplates); + + show_all_children (); +} + +void RenameDialog::initName (const Glib::ustring& iname, const CacheImageData* cid) { + + imageData = cid; + oldName->set_text (iname); + newName->set_text (iname); +// Issue 316 +// if (useTmpl->get_active () && isTemplSelected ()) +// newName->set_text (applyTemplate (iname, cid, getActiveTemplate())); + newName->select_region (0, newName->get_text().size()); +} + +Glib::ustring RenameDialog::getNewName () { + + return newName->get_text (); +} + +void RenameDialog::fillTemplateList () { + + templateModel->clear (); + + for (size_t i=0; iappend (); + iter->set_value (templateColumns.tmplName, options.renameTemplates[i]); + iter->set_value (templateColumns.rowSeparator, false); + } + // append separator and the manage... item + Gtk::TreeModel::iterator iter = templateModel->append (); + iter->set_value (templateColumns.tmplName, Glib::ustring("")); + iter->set_value (templateColumns.rowSeparator, true); + iter = templateModel->append (); + iter->set_value (templateColumns.tmplName, Glib::ustring(M("FILEBROWSER_ADDDELTEMPLATE"))); + iter->set_value (templateColumns.rowSeparator, false); +} + +bool RenameDialog::rowSeparatorFunc (const Glib::RefPtr& model, const Gtk::TreeModel::iterator& iter) { + + return iter->get_value (templateColumns.rowSeparator); +} + +void RenameDialog::useTemplToggled () { + + templates->set_sensitive (useTmpl->get_active ()); + if (useTmpl->get_active () && isTemplSelected ()) { + all->set_sensitive (true); + newName->set_text (applyTemplate (oldName->get_text(), imageData, getActiveTemplate())); + } + else + all->set_sensitive (false); + newName->select_region (0, newName->get_text().size()); +} + +bool RenameDialog::isTemplSelected () { + + Gtk::TreeModel::iterator iter = templates->get_active(); + return iter && iter->get_value (templateColumns.tmplName)!=M("FILEBROWSER_ADDDELTEMPLATE"); +} + +Glib::ustring RenameDialog::getActiveTemplate () { + + Gtk::TreeModel::iterator iter = templates->get_active(); + if (iter && iter->get_value (templateColumns.tmplName)!=M("FILEBROWSER_ADDDELTEMPLATE")) + return iter->get_value (templateColumns.tmplName); + else + return ""; +} + +void RenameDialog::tmplSelectionChanged () { + + Gtk::TreeModel::iterator iter = templates->get_active(); + if (iter && iter->get_value (templateColumns.tmplName)==M("FILEBROWSER_ADDDELTEMPLATE")) { + RenameTemplateEditor* rte = new RenameTemplateEditor (p); + if (rte->run()==Gtk::RESPONSE_OK) { + fillTemplateList (); + } + delete rte; + // show add/del template dialog + } + else + useTemplToggled (); +} + +RenameTemplateEditor::RenameTemplateEditor (Gtk::Window* parent) + : Gtk::Dialog ("Edit rename templates", *parent, true, true) { + + list = Gtk::manage (new Gtk::ListViewText (1, false, Gtk::SELECTION_MULTIPLE)); + list->set_headers_visible (false); + get_vbox ()->pack_start (*list); + + Gtk::HBox* hb = Gtk::manage (new Gtk::HBox ()); + templ = Gtk::manage (new Gtk::Entry ()); + Gtk::Button* add = Gtk::manage (new Gtk::Button ()); + Gtk::Button* del = Gtk::manage (new Gtk::Button ()); + add->add (*Gtk::manage (new RTImage ("list-add-small.png"))); + del->add (*Gtk::manage (new RTImage ("list-remove-red-small.png"))); + hb->pack_start (*templ); + hb->pack_start (*add, Gtk::PACK_SHRINK, 2); + hb->pack_start (*del, Gtk::PACK_SHRINK, 2); + + get_vbox ()->pack_start (*hb, Gtk::PACK_SHRINK, 4); + + add_button (Gtk::Stock::OK, Gtk::RESPONSE_OK); + + refreshTemplateList (); + + add->signal_pressed().connect( sigc::mem_fun(*this, &RenameTemplateEditor::addPressed) ); + del->signal_pressed().connect( sigc::mem_fun(*this, &RenameTemplateEditor::delPressed) ); + + show_all_children (); + + set_size_request (-1, 250); +} + +void RenameTemplateEditor::refreshTemplateList () { + + list->clear_items (); + + for (size_t i=0; iappend_text (options.renameTemplates[i]); +} + +void RenameTemplateEditor::addPressed () { + + if (templ->get_text()!="") { + options.renameTemplates.push_back (templ->get_text ()); + refreshTemplateList (); + templ->set_text(""); + } +} + +void RenameTemplateEditor::delPressed () { + + std::vector sel = list->get_selected (); + for (size_t i=0; iget_text (sel[i]); + std::vector::iterator f = std::find (options.renameTemplates.begin(), options.renameTemplates.end(), toDel); + if (f!=options.renameTemplates.end()) + options.renameTemplates.erase (f); + } + refreshTemplateList (); +} + +Glib::ustring RenameDialog::applyTemplate (const Glib::ustring& oName, const CacheImageData* cid, const Glib::ustring& templ) { + + return Glib::ustring ("szeva"); + +} + + diff --git a/rtgui/renamedlg.h b/rtgui/renamedlg.h new file mode 100644 index 000000000..eb4a83b99 --- /dev/null +++ b/rtgui/renamedlg.h @@ -0,0 +1,84 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _RENAMEDLG_ +#define _RENAMEDLG_ + +#include +#include "cacheimagedata.h" +#include "guiutils.h" + +#define RESPONSE_ALL 100 + +class RenameDialog : public Gtk::Dialog { + + protected: + + class TemplateColumns : public Gtk::TreeModel::ColumnRecord { + public: + Gtk::TreeModelColumn tmplName; + Gtk::TreeModelColumn rowSeparator; + TemplateColumns() { add(tmplName); add(rowSeparator); } + }; + TemplateColumns templateColumns; + Glib::RefPtr templateModel; + + Gtk::Window* p; + Gtk::Label* oldName; + Gtk::Entry* newName; + Gtk::CheckButton* useTmpl; + MyComboBox* templates; + Gtk::Button* all; + const CacheImageData* imageData; + + void fillTemplateList (); + + public: + RenameDialog (Gtk::Window* parent); + + void initName (const Glib::ustring& iname, const CacheImageData* cid); + Glib::ustring getNewName (); + + bool rowSeparatorFunc (const Glib::RefPtr& model, const Gtk::TreeModel::iterator& iter); + void tmplSelectionChanged (); + void useTemplToggled (); + + bool isTemplSelected (); + Glib::ustring getActiveTemplate (); + + static Glib::ustring applyTemplate (const Glib::ustring& oName, const CacheImageData* cid, const Glib::ustring& templ); +}; + +class RenameTemplateEditor : public Gtk::Dialog { + + protected: + Gtk::ListViewText* list; + Gtk::Entry* templ; + + void refreshTemplateList (); + public: + RenameTemplateEditor (Gtk::Window* parent); + + Glib::ustring getSelectedTemplate (); + + void addPressed (); + void delPressed (); +}; + +#endif + diff --git a/rtgui/resize.cc b/rtgui/resize.cc new file mode 100644 index 000000000..58d4c8ac5 --- /dev/null +++ b/rtgui/resize.cc @@ -0,0 +1,615 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "resize.h" +#include "guiutils.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +Resize::Resize () : FoldableToolPanel(this, "resize", M("TP_RESIZE_LABEL"), false, true), maxw(100000), maxh(100000) +{ + + cropw = 0; + croph = 0; + + Gtk::Table* combos = Gtk::manage (new Gtk::Table (2, 2)); + Gtk::Label *label = NULL; + + appliesTo = Gtk::manage (new MyComboBoxText ()); + appliesTo->append_text (M("TP_RESIZE_CROPPEDAREA")); + appliesTo->append_text (M("TP_RESIZE_FULLIMAGE")); + appliesTo->set_active (0); + + label = Gtk::manage (new Gtk::Label (M("TP_RESIZE_APPLIESTO"))); + label->set_alignment(0., 0.); + combos->attach (*label, 0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + combos->attach (*appliesTo, 1, 2, 0, 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + // See Resize::methodChanged() when adding a new method. + method = Gtk::manage (new MyComboBoxText ()); + method->append_text (M("TP_RESIZE_LANCZOS")); + method->append_text (M("TP_RESIZE_NEAREST")); + method->set_active (0); + + label = Gtk::manage (new Gtk::Label (M("TP_RESIZE_METHOD"))); + label->set_alignment(0., 0.); + combos->attach (*label, 0, 1, 1, 2, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + combos->attach (*method, 1, 2, 1, 2, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + spec = Gtk::manage (new MyComboBoxText ()); + spec->append_text (M("TP_RESIZE_SCALE")); + spec->append_text (M("TP_RESIZE_WIDTH")); + spec->append_text (M("TP_RESIZE_HEIGHT")); + spec->append_text (M("TP_RESIZE_FITBOX")); + spec->set_active (0); + + label = Gtk::manage (new Gtk::Label (M("TP_RESIZE_SPECIFY"))); + label->set_alignment(0., 0.); + combos->attach (*label, 0, 1, 2, 3, Gtk::SHRINK, Gtk::SHRINK, 2, 2); + combos->attach (*spec, 1, 2, 2, 3, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2); + + pack_start (*combos, Gtk::PACK_SHRINK, 4); + + scale = new Adjuster (M("TP_RESIZE_SCALE"), 0.01, 4, 0.01, 1.); + scale->setAdjusterListener (this); + + pack_start (*scale, Gtk::PACK_SHRINK, 4); + + sizeBox = Gtk::manage (new Gtk::VBox ()); + + Gtk::HBox* sbox = Gtk::manage (new Gtk::HBox ()); + Gtk::HBox* wbox = Gtk::manage (new Gtk::HBox ()); + Gtk::HBox* hbox = Gtk::manage (new Gtk::HBox ()); + w = Gtk::manage (new MySpinButton ()); + h = Gtk::manage (new MySpinButton ()); + wbox->set_spacing(3); + wbox->pack_start (*Gtk::manage (new Gtk::Label (M("TP_RESIZE_W"))), Gtk::PACK_SHRINK, 0); + wbox->pack_start (*w); + hbox->set_spacing(3); + hbox->pack_start (*Gtk::manage (new Gtk::Label (M("TP_RESIZE_H"))), Gtk::PACK_SHRINK, 0); + hbox->pack_start (*h); + sbox->set_spacing(4); + sbox->pack_start (*wbox); + sbox->pack_start (*hbox); + + sizeBox->pack_start (*sbox, Gtk::PACK_SHRINK, 0); + sizeBox->show_all (); + sizeBox->reference (); + + w->set_digits (0); + w->set_increments (1, 100); + w->set_value (800); + w->set_range (32, 4 * maxw); + + h->set_digits (0); + h->set_increments (1, 100); + h->set_value (600); + h->set_range (32, 4 * maxh); + + wconn = w->signal_value_changed().connect ( sigc::mem_fun(*this, &Resize::entryWChanged), true); + hconn = h->signal_value_changed().connect ( sigc::mem_fun(*this, &Resize::entryHChanged), true); + aconn = appliesTo->signal_changed().connect ( sigc::mem_fun(*this, &Resize::appliesToChanged) ); + method->signal_changed().connect ( sigc::mem_fun(*this, &Resize::methodChanged) ); + sconn = spec->signal_changed().connect ( sigc::mem_fun(*this, &Resize::specChanged) ); + + packBox = Gtk::manage (new ToolParamBlock ()); + pack_end (*packBox); + packBox->hide(); + packBox->set_tooltip_markup (M("TP_PRSHARPENING_TOOLTIP")); + + show_all(); +} + +Resize::~Resize () +{ + + delete scale; + delete sizeBox; +} + +void Resize::read (const ProcParams* pp, const ParamsEdited* pedited) +{ + + disableListener (); + aconn.block (true); + wconn.block (true); + hconn.block (true); + sconn.block (true); + scale->block(true); + + scale->setValue (pp->resize.scale); + w->set_value (pp->resize.width); + h->set_value (pp->resize.height); + setEnabled (pp->resize.enabled); + spec->set_active (pp->resize.dataspec); + updateGUI(); + + appliesTo->set_active (0); + + if (pp->resize.appliesTo == "Cropped area") { + appliesTo->set_active (0); + } else if (pp->resize.appliesTo == "Full image") { + appliesTo->set_active (1); + } + + if (pp->resize.method == "Lanczos") { + method->set_active (0); + } else if (pp->resize.method == "Nearest") { + method->set_active (1); + } else { + method->set_active (0); + } + + wDirty = false; + hDirty = false; + + if (pedited) { + wDirty = pedited->resize.width; + hDirty = pedited->resize.height; + scale->setEditedState (pedited->resize.scale ? Edited : UnEdited); + + if (!pedited->resize.appliesTo) { + appliesTo->set_active (2); + } + + if (!pedited->resize.method) { + method->set_active (3); + } + + if (!pedited->resize.dataspec) { + spec->set_active (4); + } + + set_inconsistent (multiImage && !pedited->resize.enabled); + } + + scale->block(false); + sconn.block (false); + wconn.block (false); + hconn.block (false); + aconn.block (false); + enableListener (); +} + +void Resize::write (ProcParams* pp, ParamsEdited* pedited) +{ + int dataSpec = spec->get_active_row_number(); + + pp->resize.scale = scale->getValue(); + + pp->resize.appliesTo = "Cropped area"; + + if (appliesTo->get_active_row_number() == 0) { + pp->resize.appliesTo = "Cropped area"; + } else if (appliesTo->get_active_row_number() == 1) { + pp->resize.appliesTo = "Full image"; + } + + pp->resize.method = "Lanczos"; + + if (method->get_active_row_number() == 0) { + pp->resize.method = "Lanczos"; + } else if (method->get_active_row_number() == 1) { + pp->resize.method = "Nearest"; + } + + pp->resize.dataspec = dataSpec; + pp->resize.width = w->get_value_as_int (); + pp->resize.height = h->get_value_as_int (); + pp->resize.enabled = getEnabled (); + //printf(" L:%d H:%d\n", pp->resize.width, pp->resize.height); + + if (pedited) { + pedited->resize.enabled = !get_inconsistent(); + pedited->resize.dataspec = dataSpec != 4; + pedited->resize.appliesTo = appliesTo->get_active_row_number() != 2; + pedited->resize.method = method->get_active_row_number() != 3; + + if (pedited->resize.dataspec) { + pedited->resize.scale = scale->getEditedState (); + pedited->resize.width = wDirty; + pedited->resize.height = hDirty; + } else { + pedited->resize.scale = false; + pedited->resize.width = false; + pedited->resize.height = false; + } + } +} + +void Resize::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) +{ + + scale->setDefault (defParams->resize.scale); + + if (pedited) { + scale->setDefaultEditedState (pedited->resize.scale ? Edited : UnEdited); + } else { + scale->setDefaultEditedState (Irrelevant); + } +} + +void Resize::adjusterChanged (Adjuster* a, double newval) +{ + + if (!batchMode) { + wconn.block (true); + hconn.block (true); + h->set_value ((croph && appliesTo->get_active_row_number() == 0 ? croph : maxh) * a->getValue ()); + w->set_value ((cropw && appliesTo->get_active_row_number() == 0 ? cropw : maxw) * a->getValue ()); + wconn.block (false); + hconn.block (false); + } + + if (listener && (getEnabled () || batchMode)) { + listener->panelChanged (EvResizeScale, Glib::ustring::format (std::setw(5), std::fixed, std::setprecision(2), scale->getValue())); + } +} + +int Resize::getComputedWidth() +{ + + if (cropw && appliesTo->get_active_row_number() == 0) + // we use the crop dimensions + { + return (int)((double)(cropw) * (h->get_value() / (double)(croph)) + 0.5); + } else + // we use the image dimensions + { + return (int)((double)(maxw) * (h->get_value() / (double)(maxh)) + 0.5); + } +} + +int Resize::getComputedHeight() +{ + + if (croph && appliesTo->get_active_row_number() == 0) + // we use the crop dimensions + { + return (int)((double)(croph) * (w->get_value() / (double)(cropw)) + 0.5); + } else + // we use the image dimensions + { + return (int)((double)(maxh) * (w->get_value() / (double)(maxw)) + 0.5); + } +} + +void Resize::appliesToChanged () +{ + + //printf("\nPASSAGE EN MODE \"%s\"\n\n", appliesTo->get_active_text().c_str()); + setDimensions(); + + if (listener && (getEnabled () || batchMode)) { + //printf("Appel du listener\n"); + listener->panelChanged (EvResizeAppliesTo, appliesTo->get_active_text()); + } +} + +void Resize::methodChanged () +{ + + if (listener && (getEnabled () || batchMode)) { + listener->panelChanged (EvResizeMethod, method->get_active_text()); + } + + // Post-resize Sharpening assumes the image is in Lab space, and currently Lanczos is the only method which uses that space, and Lanczos is on row 0. + if (method->get_active_row_number() == 0) { + packBox->set_sensitive(true); + } else { + packBox->set_sensitive(false); + } +} + +void Resize::update (bool isCropped, int cw, int ch, int ow, int oh) +{ + + // updating crop values now + if (isCropped) { + cropw = cw; + croph = ch; + } else { + cropw = 0; + croph = 0; + } + + // updating the full image dimensions + if (ow && oh) { + maxw = ow; + maxh = oh; + } + + // updating the GUI synchronously + setDimensions(); +} + +void Resize::sizeChanged (int mw, int mh, int ow, int oh) +{ + + // updating max values now + maxw = ow; + maxh = oh; + + // updating the GUI synchronously + setDimensions(); +} + +void Resize::setDimensions () +{ + + int refw, refh; + + wconn.block (true); + hconn.block (true); + scale->block(true); + + if (appliesTo->get_active_row_number() == 0 && cropw) { + // Applies to Cropped area + refw = cropw; + refh = croph; + } else { + // Applies to Full image or crop is disabled + refw = maxw; + refh = maxh; + } + + GThreadLock lock; + w->set_range (32, 4 * refw); + h->set_range (32, 4 * refh); + + double tmpScale; + + switch (spec->get_active_row_number()) { + case (0): // Scale mode + w->set_value((double)((int)( (double)(refw) * scale->getValue() + 0.5) )); + h->set_value((double)((int)( (double)(refh) * scale->getValue() + 0.5) )); + break; + + case (1): // Width mode + tmpScale = w->get_value() / (double)refw; + scale->setValue (tmpScale); + h->set_value((double)((int)( (double)(refh) * tmpScale + 0.5) )); + break; + + case (2): // Height mode + tmpScale = h->get_value() / (double)refh; + scale->setValue (tmpScale); + w->set_value((double)((int)( (double)(refw) * tmpScale + 0.5) )); + break; + + case (3): { // Bounding box mode + double wSliderValue = w->get_value(); + double hSliderValue = h->get_value(); + + if ( (wSliderValue / hSliderValue) < ((double)refw / (double)refh)) { + tmpScale = wSliderValue / (double)refw; + } else { + tmpScale = hSliderValue / (double)refh; + } + + scale->setValue (tmpScale); + break; + } + + default: + break; + } + + scale->block(false); + wconn.block (false); + hconn.block (false); +} + +void Resize::fitBoxScale() +{ + double tmpScale; + double neww = w->get_value (); + double newh = h->get_value (); + + if (cropw && appliesTo->get_active_row_number() == 0) { + // we use the crop dimensions + if (((double)(cropw) / (double)(croph)) > (neww / newh)) { + // the new scale is given by the image width + tmpScale = neww / (double)(cropw); + } else { + // the new scale is given by the image height + tmpScale = newh / (double)(croph); + } + } else { + // we use the image dimensions + if (((double)(maxw) / (double)(maxh)) > (neww / newh)) { + // the new scale is given by the image width + tmpScale = neww / (double)(maxw); + } else { + // the new scale is given by the image height + tmpScale = newh / (double)(maxh); + } + } + + scale->setValue (tmpScale); +} + +void Resize::entryWChanged () +{ + + wDirty = true; + + // updating width + if (!batchMode) { + if (spec->get_active_row_number() == 3) { + // Fit box mode + fitBoxScale(); + } else { + // Other modes + hconn.block (true); + scale->block (true); + + h->set_value ((double)(getComputedHeight())); + scale->setValue (w->get_value () / (cropw && appliesTo->get_active_row_number() == 0 ? (double)cropw : (double)maxw)); + + scale->block (false); + hconn.block (false); + } + } + + if (listener) { + if (spec->get_active_row_number() == 3) { + notifyBBox(); + } else { + if (getEnabled () || batchMode) { + listener->panelChanged (EvResizeWidth, Glib::ustring::format (w->get_value_as_int())); + } + } + } +} + +void Resize::entryHChanged () +{ + + hDirty = true; + + if (!batchMode && listener) { + if (spec->get_active_row_number() == 3) { + // Fit box mode + fitBoxScale(); + } else { + // Other modes + wconn.block (true); + scale->block (true); + + w->set_value ((double)(getComputedWidth())); + scale->setValue (h->get_value () / (croph && appliesTo->get_active_row_number() == 0 ? (double)croph : (double)maxh)); + + scale->block (false); + wconn.block (false); + } + } + + if (listener) { + if (spec->get_active_row_number() == 3) { + notifyBBox(); + } else { + if (getEnabled () || batchMode) { + listener->panelChanged (EvResizeHeight, Glib::ustring::format (h->get_value_as_int())); + } + } + } +} + +void Resize::specChanged () +{ + + switch (spec->get_active_row_number()) { + case (0): + // Scale mode + scale->sliderChanged (); + break; + + case (1): + // Width mode + w->set_value((double)(getComputedWidth())); + entryWChanged (); + break; + + case (2): + // Height mode + h->set_value((double)(getComputedHeight())); + entryHChanged (); + break; + + case (3): + // Bounding box mode + notifyBBox(); + break; + + default: + break; + } + + updateGUI(); +} + +void Resize::updateGUI () +{ + + removeIfThere (this, scale, false); + removeIfThere (this, sizeBox, false); + + switch (spec->get_active_row_number()) { + case (0): + // Scale mode + pack_start (*scale, Gtk::PACK_SHRINK, 4); + break; + + case (1): + // Width mode + pack_start (*sizeBox, Gtk::PACK_SHRINK, 4); + w->set_sensitive (true); + h->set_sensitive (false); + break; + + case (2): + // Height mode + pack_start (*sizeBox, Gtk::PACK_SHRINK, 4); + w->set_sensitive (false); + h->set_sensitive (true); + break; + + case (3): + // Bounding box mode + pack_start (*sizeBox, Gtk::PACK_SHRINK, 4); + w->set_sensitive (true); + h->set_sensitive (true); + break; + + default: + break; + } +} + +void Resize::notifyBBox() +{ + if (listener && (getEnabled () || batchMode)) { + listener->panelChanged (EvResizeBoundingBox, Glib::ustring::compose("(%1x%2)", (int)w->get_value(), (int)h->get_value() )); + } +} + +void Resize::setBatchMode (bool batchMode) +{ + + method->append_text (M("GENERAL_UNCHANGED")); + spec->append_text (M("GENERAL_UNCHANGED")); + ToolPanel::setBatchMode (batchMode); + scale->showEditedCB (); +} + +void Resize::enabledChanged () +{ + + if (listener) { + if (get_inconsistent()) { + listener->panelChanged (EvResizeEnabled, M("GENERAL_UNCHANGED")); + } else if (getEnabled()) { + listener->panelChanged (EvResizeEnabled, M("GENERAL_ENABLED")); + } else { + listener->panelChanged (EvResizeEnabled, M("GENERAL_DISABLED")); + } + } +} + diff --git a/rtgui/resize.h b/rtgui/resize.h new file mode 100644 index 000000000..54bfb4e4a --- /dev/null +++ b/rtgui/resize.h @@ -0,0 +1,76 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _RESIZE_H_ +#define _RESIZE_H_ + +#include +#include "adjuster.h" +#include "guiutils.h" +#include "toolpanel.h" +#include "guiutils.h" + +class Resize : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public rtengine::SizeListener { + + protected: + Adjuster* scale; + Gtk::VBox* sizeBox; + MyComboBoxText* appliesTo; + MyComboBoxText* method; + MyComboBoxText* spec; + MySpinButton* w; + MySpinButton* h; + int maxw, maxh; + int cropw, croph; + sigc::connection sconn, aconn, wconn, hconn; + bool wDirty, hDirty; + ToolParamBlock* packBox; + + public: + + Resize (); + ~Resize (); + + Gtk::Box* getPackBox () { return packBox; } + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + + void adjusterChanged (Adjuster* a, double newval); + void entryWChanged (); + void entryHChanged (); + void appliesToChanged (); + void methodChanged (); + void specChanged (); + void update (bool isCropped, int cw, int ch, int ow=0, int oh=0); + void setGUIFromCrop (bool isCropped, int cw, int ch); + void sizeChanged (int w, int h, int ow, int oh); + void setDimensions (); + void enabledChanged (); + + private: + void fitBoxScale (); + int getComputedWidth (); + int getComputedHeight (); + void notifyBBox (); + void updateGUI (); +}; + +#endif diff --git a/rtgui/rgbcurves.cc b/rtgui/rgbcurves.cc new file mode 100644 index 000000000..64b4fb93f --- /dev/null +++ b/rtgui/rgbcurves.cc @@ -0,0 +1,180 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "rgbcurves.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +RGBCurves::RGBCurves () : FoldableToolPanel(this, "rgbcurves", M("TP_RGBCURVES_LABEL")) { + + lumamode = Gtk::manage (new Gtk::CheckButton (M("TP_RGBCURVES_LUMAMODE"))); + lumamode->set_tooltip_markup (M("TP_RGBCURVES_LUMAMODE_TOOLTIP")); + lumamode->set_active (false); + lumamode->show (); + pack_start (*lumamode); + + Gtk::HSeparator *hsep1 = Gtk::manage (new Gtk::HSeparator()); + hsep1->show (); + pack_start (*hsep1); + + lumamodeConn = lumamode->signal_toggled().connect( sigc::mem_fun(*this, &RGBCurves::lumamodeChanged) ); + + std::vector milestones; + + curveEditorG = new CurveEditorGroup (options.lastRgbCurvesDir, M("TP_RGBCURVES_CHANNEL")); + curveEditorG->setCurveListener (this); + + Rshape = static_cast(curveEditorG->addCurve(CT_Diagonal, M("TP_RGBCURVES_RED"))); + Rshape->setEditID(EUID_RGB_R, BT_SINGLEPLANE_FLOAT); + milestones.push_back( GradientMilestone(0.0, 0.0, 0.0, 0.0) ); + milestones.push_back( GradientMilestone(1.0, 1.0, 0.0, 0.0) ); + Rshape->setBottomBarBgGradient(milestones); + Rshape->setLeftBarBgGradient(milestones); + + milestones[1].r = 0.0; milestones[1].g = 1.0; + Gshape = static_cast(curveEditorG->addCurve(CT_Diagonal, M("TP_RGBCURVES_GREEN"))); + Gshape->setEditID(EUID_RGB_G, BT_SINGLEPLANE_FLOAT); + Gshape->setBottomBarBgGradient(milestones); + Gshape->setLeftBarBgGradient(milestones); + + milestones[1].g = 0.0; milestones[1].b = 1.0; + Bshape = static_cast(curveEditorG->addCurve(CT_Diagonal, M("TP_RGBCURVES_BLUE"))); + Bshape->setEditID(EUID_RGB_B, BT_SINGLEPLANE_FLOAT); + Bshape->setBottomBarBgGradient(milestones); + Bshape->setLeftBarBgGradient(milestones); + + // This will add the reset button at the end of the curveType buttons + curveEditorG->curveListComplete(); + + pack_start (*curveEditorG, Gtk::PACK_SHRINK, 4); + +} + +RGBCurves::~RGBCurves () { + delete curveEditorG; +} + +void RGBCurves::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + if (pedited) { + Rshape->setUnChanged (!pedited->rgbCurves.rcurve); + Gshape->setUnChanged (!pedited->rgbCurves.gcurve); + Bshape->setUnChanged (!pedited->rgbCurves.bcurve); + lumamode->set_inconsistent (!pedited->rgbCurves.lumamode); + } + + lumamodeConn.block (true); + lumamode->set_active (pp->rgbCurves.lumamode); + lumamodeConn.block (false); + + lastLumamode = pp->rgbCurves.lumamode; + + Rshape->setCurve (pp->rgbCurves.rcurve); + Gshape->setCurve (pp->rgbCurves.gcurve); + Bshape->setCurve (pp->rgbCurves.bcurve); + + enableListener (); +} + +void RGBCurves::setEditProvider (EditDataProvider *provider) { + Rshape->setEditProvider(provider); + Gshape->setEditProvider(provider); + Bshape->setEditProvider(provider); +} + +void RGBCurves::autoOpenCurve () { + // Open up the first curve if selected + bool active = Rshape->openIfNonlinear(); + if (!active) Gshape->openIfNonlinear(); + if (!active) Bshape->openIfNonlinear(); +} + +void RGBCurves::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->rgbCurves.rcurve = Rshape->getCurve (); + pp->rgbCurves.gcurve = Gshape->getCurve (); + pp->rgbCurves.bcurve = Bshape->getCurve (); + pp->rgbCurves.lumamode = lumamode->get_active(); + + if (pedited) { + pedited->rgbCurves.rcurve = !Rshape->isUnChanged (); + pedited->rgbCurves.gcurve = !Gshape->isUnChanged (); + pedited->rgbCurves.bcurve = !Bshape->isUnChanged (); + pedited->rgbCurves.lumamode = !lumamode->get_inconsistent(); + } +} + + +/* + * Curve listener + * + * If more than one curve has been added, the curve listener is automatically + * set to 'multi=true', and send a pointer of the modified curve in a parameter + */ +void RGBCurves::curveChanged (CurveEditor* ce) { + + if (listener) { + if (ce == Rshape) + listener->panelChanged (EvRGBrCurve, M("HISTORY_CUSTOMCURVE")); + if (ce == Gshape) + listener->panelChanged (EvRGBgCurve, M("HISTORY_CUSTOMCURVE")); + if (ce == Bshape) + listener->panelChanged (EvRGBbCurve, M("HISTORY_CUSTOMCURVE")); + } +} + +void RGBCurves::lumamodeChanged () { + + if (batchMode) { + if (lumamode->get_inconsistent()) { + lumamode->set_inconsistent (false); + lumamodeConn.block (true); + lumamode->set_active (false); + lumamodeConn.block (false); + } + else if (lastLumamode) + lumamode->set_inconsistent (true); + + lastLumamode = lumamode->get_active (); + } + + if (listener) { + if (lumamode->get_active ()) + listener->panelChanged (EvRGBrCurveLumamode, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvRGBrCurveLumamode, M("GENERAL_DISABLED")); + } +} + +void RGBCurves::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + curveEditorG->setBatchMode (batchMode); +} + + +void RGBCurves::updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve, LUTu & histCCurve, /*LUTu & histCLurve, LUTu & histLLCurve,*/ LUTu & histLCAM, LUTu & histCCAM, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma) { + + // Rshape->updateBackgroundHistogram (histRed); + // Gshape->updateBackgroundHistogram (histGreen); + // Bshape->updateBackgroundHistogram (histBlue); +} + diff --git a/rtgui/rgbcurves.h b/rtgui/rgbcurves.h new file mode 100644 index 000000000..9d5498705 --- /dev/null +++ b/rtgui/rgbcurves.h @@ -0,0 +1,57 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _RGBCURVES_H_ +#define _RGBCURVES_H_ + +#include +#include "adjuster.h" +#include "toolpanel.h" +#include "curveeditor.h" +#include "curveeditorgroup.h" +#include "colorprovider.h" + +class RGBCurves : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public CurveListener, public ColorProvider { + + protected: + CurveEditorGroup* curveEditorG; + DiagonalCurveEditor* Rshape; + DiagonalCurveEditor* Gshape; + DiagonalCurveEditor* Bshape; + + Gtk::CheckButton* lumamode; + bool lastLumamode; + sigc::connection lumamodeConn; + + public: + + RGBCurves (); + ~RGBCurves (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + void setEditProvider (EditDataProvider *provider); + void autoOpenCurve (); + + void curveChanged (CurveEditor* ce); + void updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve, LUTu & histCCurve, /*LUTu & histCLurve, LUTu & histLLCurve,*/ LUTu & histLCAM, LUTu & histCCAM, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma); + void lumamodeChanged (); +}; + +#endif diff --git a/rtgui/rotate.cc b/rtgui/rotate.cc new file mode 100644 index 000000000..973ec3c3a --- /dev/null +++ b/rtgui/rotate.cc @@ -0,0 +1,113 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "rotate.h" +#include +#include "guiutils.h" +#include "rtimage.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +Rotate::Rotate () : FoldableToolPanel(this, "rotate", M("TP_ROTATE_LABEL")) { + + rlistener = NULL; + + //TODO the action of the rotation slider is counter-intuitive + Gtk::Image* irotateL = Gtk::manage (new RTImage ("rotate-right-2.png")); + Gtk::Image* irotateR = Gtk::manage (new RTImage ("rotate-left-2.png")); + + degree = Gtk::manage (new Adjuster (M("TP_ROTATE_DEGREE"), -45, 45, 0.01, 0, irotateL, irotateR)); + degree->setAdjusterListener (this); + pack_start (*degree); + + selectStraight = Gtk::manage (new Gtk::Button (M("TP_ROTATE_SELECTLINE"))); + Gtk::Image* selimg = Gtk::manage (new RTImage ("straighten-small.png")); + selectStraight->set_image (*selimg); + pack_start (*selectStraight, Gtk::PACK_SHRINK, 2); + + selectStraight->signal_pressed().connect( sigc::mem_fun(*this, &Rotate::selectStraightPressed) ); + + show_all (); +} + +void Rotate::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + if (pedited) + degree->setEditedState (pedited->rotate.degree ? Edited : UnEdited); + + degree->setValue (pp->rotate.degree); + + enableListener (); +} + +void Rotate::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->rotate.degree = degree->getValue (); + + if (pedited) + pedited->rotate.degree = degree->getEditedState (); +} + +void Rotate::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + degree->setDefault (defParams->rotate.degree); + + if (pedited) + degree->setDefaultEditedState (pedited->rotate.degree ? Edited : UnEdited); + else + degree->setDefaultEditedState (Irrelevant); +} + +void Rotate::adjusterChanged (Adjuster* a, double newval) { + + if (listener) + listener->panelChanged (EvROTDegree, Glib::ustring::format (std::setw(3), std::fixed, std::setprecision(2), degree->getValue())); +} + +void Rotate::straighten (double deg) { + + degree->setValue (degree->getValue()+deg); + degree->setEditedState (Edited); + if (listener) + listener->panelChanged (EvROTDegree, Glib::ustring::format (std::setw(3), std::fixed, std::setprecision(2), degree->getValue())); +} + +void Rotate::selectStraightPressed () { + + if (rlistener) + rlistener->straightenRequested (); +} + +void Rotate::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + degree->showEditedCB (); +} + +void Rotate::setAdjusterBehavior (bool rotadd) { + + degree->setAddMode(rotadd); +} + +void Rotate::trimValues (rtengine::procparams::ProcParams* pp) { + + degree->trimValue(pp->rotate.degree); +} diff --git a/rtgui/rotate.h b/rtgui/rotate.h new file mode 100644 index 000000000..e096393e6 --- /dev/null +++ b/rtgui/rotate.h @@ -0,0 +1,52 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _ROTATE_H_ +#define _ROTATE_H_ + +#include +#include "adjuster.h" +#include "toolpanel.h" +#include "lensgeomlistener.h" + +class Rotate : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel { + + protected: + Adjuster* degree; + Gtk::Button* selectStraight; + LensGeomListener* rlistener; + + public: + + Rotate (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + + void straighten (double deg); + + void adjusterChanged (Adjuster* a, double newval); + void setAdjusterBehavior (bool rotadd); + void trimValues (rtengine::procparams::ProcParams* pp); + void selectStraightPressed (); + void setLensGeomListener (LensGeomListener* l) { rlistener = l; } +}; + +#endif diff --git a/rtgui/rtimage.cc b/rtgui/rtimage.cc new file mode 100644 index 000000000..161ee89ec --- /dev/null +++ b/rtgui/rtimage.cc @@ -0,0 +1,149 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath + * Copyright (c) 2011 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 . + */ + +#include "rtimage.h" +#include "../rtengine/safegtk.h" + +extern Glib::ustring argv0; +extern Options options; + +std::vector imagesPaths; +std::map > pixBufMap; // List of image buffers in order to live update them on theme switch and to avoid a lot of file accesses + +/* + * RTImage is a derived class of Gtk::Image, in order to handle theme related iconsets + */ +RTImage::RTImage(Glib::ustring fileName, Glib::ustring rtlFileName) : Gtk::Image() { + Glib::ustring mapKey; + if (rtlFileName.length()) { + if (get_direction() == Gtk::TEXT_DIR_RTL) { + mapKey = rtlFileName; + } else { + mapKey = fileName; + } + } else { + mapKey = fileName; + } + + std::map >::iterator it; + it = pixBufMap.find(mapKey); + if (it != pixBufMap.end()) { + set(it->second); + } else { + Glib::RefPtr tempPixPuf = Gdk::Pixbuf::create_from_file(findIconAbsolutePath(mapKey)); + pixBufMap.insert(std::pair >(mapKey, tempPixPuf)); + set(tempPixPuf); + } +} + +void RTImage::updateImages() { + std::map >::iterator it; + for (it=pixBufMap.begin(); it!=pixBufMap.end(); ++it) { + Glib::ustring fullPath = findIconAbsolutePath(it->first); + it->second = Gdk::Pixbuf::create_from_file(fullPath); + } +} + +// DONE (was TODO: Maybe this could be optimized: in order to avoid looking up for an icon file in the filesystem on each popupmenu selection, maybe we could find a way to copy the image data from another RTImage) +void RTImage::changeImage(Glib::ustring &newImage) { + clear(); + std::map >::iterator it; + it = pixBufMap.find(newImage); + if (it != pixBufMap.end()) { + set(it->second); + } else { + Glib::ustring fullPath = findIconAbsolutePath(newImage); + Glib::RefPtr tempPixPuf = Gdk::Pixbuf::create_from_file(fullPath); + pixBufMap.insert(std::pair >(newImage, tempPixPuf)); + set(tempPixPuf); + } +} + +Glib::ustring RTImage::findIconAbsolutePath(const Glib::ustring &iconFName) { + Glib::ustring path; + for (unsigned int i=0; i + * + * 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 _RTIMAGE_ +#define _RTIMAGE_ + +#include +#include "options.h" + +class RTImage : public Gtk::Image { +public: + RTImage(Glib::ustring fileName, Glib::ustring rtlFileName = ""); + static void setPaths(Options &opt); + static void updateImages(); + void changeImage(Glib::ustring &newImage); + static Glib::ustring findIconAbsolutePath(const Glib::ustring &iconFName); +}; + +#endif diff --git a/rtgui/rtwindow.cc b/rtgui/rtwindow.cc new file mode 100644 index 000000000..4d55a6db6 --- /dev/null +++ b/rtgui/rtwindow.cc @@ -0,0 +1,784 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 Gabor Horvath , Oliver Duis + * + * 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 "rtwindow.h" +#include "options.h" +#include "preferences.h" +#include "cursormanager.h" +#include "rtimage.h" +#include "whitebalance.h" + +#if defined(__APPLE__) +static gboolean +osx_should_quit_cb (GtkosxApplication *app, gpointer data) +{ + RTWindow *rtWin = (RTWindow *)data; + 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); + gtk_main_quit (); +} + +bool RTWindow::osxFileOpenEvent(Glib::ustring path) { + + CacheManager* cm = CacheManager::getInstance(); + Thumbnail* thm= cm->getEntry( path ); + if(thm && fpanel){ + std::vector entries; + entries.push_back(thm); + fpanel->fileCatalog->openRequested(entries); + return true; + } + return false; +} + +static gboolean +osx_open_file_cb (GtkosxApplication *app, gchar *path_, gpointer data) +{ + RTWindow *rtWin = (RTWindow *)data; + if (!argv1.empty()) { + // skip handling if we have a file argument or else we get double open of same file + return false; + } + 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); + } + return rtWin->osxFileOpenEvent(path); +} +#endif // __APPLE__ + +RTWindow::RTWindow () +:mainNB(NULL) +,bpanel(NULL) +,splash(NULL) +,btn_fullscreen(NULL) +,epanel(NULL) +,fpanel(NULL) +{ + + cacheMgr->init (); + WhiteBalance::init(); + ProfilePanel::init(); + + Glib::ustring fName = "rt-logo.png"; + Glib::ustring fullPath = RTImage::findIconAbsolutePath(fName); + +#ifdef GLIBMM_EXCEPTIONS_ENABLED + try { set_default_icon_from_file (fullPath); + } catch(Glib::Exception& ex) { printf ("%s\n", ex.what().c_str()); } +#else + { std::auto_ptr error; + set_default_icon_from_file (fullPath, error); + } +#endif //GLIBMM_EXCEPTIONS_ENABLED + +#if defined(__APPLE__) + { + osxApp = (GtkosxApplication *)g_object_new (GTKOSX_TYPE_APPLICATION, NULL); + gboolean falseval = FALSE; + gboolean trueval = TRUE; + RTWindow *rtWin = this; + g_signal_connect (osxApp, "NSApplicationBlockTermination", G_CALLBACK (osx_should_quit_cb), rtWin); + g_signal_connect (osxApp, "NSApplicationWillTerminate", G_CALLBACK (osx_will_quit_cb), rtWin); + g_signal_connect (osxApp, "NSApplicationOpenFile", G_CALLBACK (osx_open_file_cb), rtWin); + // RT don't have a menu, but we must create a dummy one to get the default OS X app menu working + GtkWidget *menubar; + menubar = gtk_menu_bar_new (); + gtkosx_application_set_menu_bar (osxApp, GTK_MENU_SHELL (menubar)); + gtkosx_application_set_use_quartz_accelerators (osxApp, FALSE); + gtkosx_application_ready (osxApp); + } +#endif + versionStr = "RawTherapee "+versionString; + if (!versionSuffixString.empty()) + versionStr += " "+versionSuffixString; + set_title_decorated(""); + property_allow_shrink() = true; + set_default_size(options.windowWidth, options.windowHeight); + set_modal(false); + set_resizable(true); + if (options.windowMaximized) + maximize(); + else { + unmaximize(); + move(options.windowX,options.windowY); + } + + 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) ); + + if(simpleEditor) + { + epanel = Gtk::manage( new EditorPanel (NULL) ); + epanel->setParent (this); + add (*epanel); + show_all (); + + pldBridge=NULL; // No progress listener + + CacheManager* cm = CacheManager::getInstance(); + Thumbnail* thm= cm->getEntry( argv1 ); + if(thm){ + int error; + rtengine::InitialImage *ii= rtengine::InitialImage::load(argv1,thm->getType() == FT_Raw,&error,NULL); + epanel->open( thm, ii ); + } + } else { + mainNB = Gtk::manage (new Gtk::Notebook ()); + mainNB->set_scrollable (true); + mainNB->signal_switch_page().connect_notify( sigc::mem_fun(*this, &RTWindow::on_mainNB_switch_page) ); + + fpanel = new FilePanel () ; + fpanel->setParent (this); + + // decorate tab + if (options.mainNBVertical) { + mainNB->set_tab_pos (Gtk::POS_LEFT); + + Gtk::VBox* vbf = Gtk::manage (new Gtk::VBox ()); + vbf->pack_start (*Gtk::manage (new Gtk::Image (Gtk::Stock::DIRECTORY, Gtk::ICON_SIZE_MENU))); + Gtk::Label* l= Gtk::manage(new Gtk::Label (Glib::ustring(" ") + M("MAIN_FRAME_FILEBROWSER"))); + l->set_angle (90); + vbf->pack_start (*l); + vbf->set_spacing (2); + vbf->set_tooltip_markup (M("MAIN_FRAME_FILEBROWSER_TOOLTIP")); + vbf->show_all (); + mainNB->append_page (*fpanel, *vbf); + } else { + Gtk::HBox* hbf = Gtk::manage (new Gtk::HBox ()); + hbf->pack_start (*Gtk::manage (new Gtk::Image (Gtk::Stock::DIRECTORY, Gtk::ICON_SIZE_MENU))); + hbf->pack_start (*Gtk::manage (new Gtk::Label (M("MAIN_FRAME_FILEBROWSER")))); + hbf->set_spacing (2); + hbf->set_tooltip_markup (M("MAIN_FRAME_FILEBROWSER_TOOLTIP")); + hbf->show_all (); + mainNB->append_page (*fpanel, *hbf); + } + + bpanel = Gtk::manage ( new BatchQueuePanel (fpanel->fileCatalog) ); + bpanel->setParent (this); + + // decorate tab, the label is unimportant since its updated in batchqueuepanel anyway + Gtk::Label* lbq = Gtk::manage ( new Gtk::Label (M("MAIN_FRAME_BATCHQUEUE")) ); + if (options.mainNBVertical) lbq->set_angle(90); + mainNB->append_page (*bpanel, *lbq); + + // epanel is only for single tab mode + epanel = Gtk::manage ( new EditorPanel (fpanel) ); + epanel->setParent (this); + + // decorate tab + if (options.mainNBVertical) { + Gtk::VBox* vbe = Gtk::manage (new Gtk::VBox ()); + vbe->pack_start (*Gtk::manage (new RTImage ("rt-logo.png"))); + Gtk::Label* l=Gtk::manage (new Gtk::Label( Glib::ustring(" ") + M("MAIN_FRAME_EDITOR") )); + //l->set_markup(Glib::ustring("Editor")); Bold difficult to read + l->set_angle (90); + vbe->pack_start (*l); + vbe->set_spacing (2); + vbe->set_tooltip_markup (M("MAIN_FRAME_EDITOR_TOOLTIP")); + vbe->show_all (); + epanel->tbTopPanel_1_visible(true); //show the toggle Top Panel button + mainNB->append_page (*epanel, *vbe); + } else { + Gtk::HBox* hbe = Gtk::manage (new Gtk::HBox ()); + hbe->pack_start (*Gtk::manage (new RTImage ("rt-logo.png"))); + hbe->pack_start (*Gtk::manage (new Gtk::Label( Glib::ustring(" ") + M("MAIN_FRAME_EDITOR") ))); + hbe->set_spacing (2); + hbe->set_tooltip_markup (M("MAIN_FRAME_EDITOR_TOOLTIP")); + hbe->show_all (); + epanel->tbTopPanel_1_visible(true); //show the toggle Top Panel button + mainNB->append_page (*epanel, *hbe); + } + + mainNB->set_current_page (mainNB->page_num (*fpanel)); + + Gtk::VBox* mainBox = Gtk::manage (new Gtk::VBox ()); + mainBox->pack_start (*mainNB); + + // filling bottom box + iFullscreen = new RTImage ("fullscreen.png"); + iFullscreen_exit = new RTImage ("fullscreen-exit.png"); + + Gtk::LinkButton* rtWeb = Gtk::manage (new Gtk::LinkButton ("http://rawtherapee.com")); + //Gtk::Button* preferences = Gtk::manage (new Gtk::Button (M("MAIN_BUTTON_PREFERENCES")+"...")); + Gtk::Button* preferences = Gtk::manage (new Gtk::Button ()); + 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()); + 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) ); +#if GTKMM_MINOR_VERSION >= 20 + if (options.mainNBVertical) { + Gtk::VBox* bottomVBox = Gtk::manage (new Gtk::VBox ()); + bottomVBox->pack_start (prProgBar, Gtk::PACK_SHRINK, 1); + bottomVBox->pack_end (*preferences, Gtk::PACK_SHRINK, 0); + bottomVBox->pack_end (*btn_fullscreen, Gtk::PACK_EXPAND_WIDGET, 1); + prProgBar.set_orientation(Gtk::PROGRESS_BOTTOM_TO_TOP); + mainNB->set_action_widget( bottomVBox,Gtk::PACK_END); + bottomVBox->show_all(); + }else{ + Gtk::HBox* bottomHBox = Gtk::manage (new Gtk::HBox ()); + bottomHBox->pack_end (*btn_fullscreen, Gtk::PACK_SHRINK, 1); + bottomHBox->pack_end (*preferences, Gtk::PACK_SHRINK, 0); + bottomHBox->pack_start (prProgBar, Gtk::PACK_EXPAND_WIDGET, 1); + mainNB->set_action_widget( bottomHBox,Gtk::PACK_END); + bottomHBox->show_all(); + } +#else + Gtk::HBox* bottomBox = Gtk::manage (new Gtk::HBox ()); + bottomBox->pack_end (*btn_fullscreen, Gtk::PACK_SHRINK, 1); + bottomBox->pack_end (*preferences, Gtk::PACK_SHRINK, 0); + bottomBox->pack_start (prProgBar, Gtk::PACK_EXPAND_WIDGET, 1); + mainBox->pack_start (*bottomBox, Gtk::PACK_SHRINK, 1); +#endif + + pldBridge = new PLDBridge(static_cast(this)); + + Glib::RefPtr style = Gtk::RcStyle::create (); + style->set_xthickness (0); + style->set_ythickness (0); + rtWeb->modify_style (style); + + add (*mainBox); + show_all (); + } + if (!isSingleTabMode()&& !simpleEditor) epanel->hide_all(); +} + +RTWindow::~RTWindow() +{ + if(!simpleEditor) + delete pldBridge; + pldBridge = NULL; +#if defined(__APPLE__) + g_object_unref (osxApp); +#endif + if (fpanel) + delete fpanel; +} + +void RTWindow::findVerNumbers(int* numbers, Glib::ustring versionStr) { + numbers[0] = numbers[1] = numbers[2] = numbers[3] = 0; + int n=0; + for (unsigned int i=0; i= '0' && chr <= '9') { + numbers[n] *= 10; + numbers[n] += (int)(chr - '0'); + } + else { + n++; + if (n>4) { + printf("Error: malformed version string; \"%s\" must follow this format: xx.xx.xx.xx. Admitting it's a developer version...\n", versionStr.c_str()); + // Reseting the already found numbers + numbers[0] = numbers[1] = numbers[2] = numbers[3] = 100; + return; + } + } + } +} + +void RTWindow::on_realize () { + Gtk::Window::on_realize (); + + if( fpanel ) + fpanel->setAspect(); + + cursorManager.init (get_window()); + + // Check if first run of this version, then display the Release Notes text + if (options.version != versionString) { + int prevVerNbr[4]; + int currVerNbr[4]; + findVerNumbers(prevVerNbr, options.version); + findVerNumbers(currVerNbr, versionString); + + // Now we can update the version parameter with the right value + options.version = versionString; + + bool showReleaseNotes = false; + // Check if the current version is newer + if (currVerNbr[0] > prevVerNbr[0]) showReleaseNotes = true; + else if (currVerNbr[1] > prevVerNbr[1]) showReleaseNotes = true; + else if (currVerNbr[2] > prevVerNbr[2]) showReleaseNotes = true; + + if (showReleaseNotes) { + // this is a first run! + 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 = NULL; + } + } + } +} + +bool RTWindow::on_window_state_event(GdkEventWindowState* event) { + + if (!event->new_window_state) { + // Window mode + options.windowMaximized = false; + } + else if (event->new_window_state & (GDK_WINDOW_STATE_MAXIMIZED|GDK_WINDOW_STATE_FULLSCREEN|GDK_WINDOW_STATE_ICONIFIED)) { + // Fullscreen mode, save this mode even when window is iconified (minimized) to allow easier restore, not the best solution though... + options.windowMaximized = true; + } + return true; +} + +void RTWindow::on_mainNB_switch_page(GtkNotebookPage* page, guint 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)); + ep->setAspect(); + + if (!isSingleTabMode()){ + if (filesEdited.size()>0){ + set_title_decorated(ep->getFileName()); + } + } + } else { + // in single tab mode with command line filename epanel does not exist yet + if (isSingleTabMode() && epanel) { + // Save profile on leaving the editor panel + epanel->saveProfile(); + + // Moving the FileBrowser only if the user has switched to the FileBrowser tab + if (mainNB->get_nth_page(page_num)==fpanel) + MoveFileBrowserToMain(); + } + } + } +} + +void RTWindow::addEditorPanel (EditorPanel* ep, const std::string &name) { + if (options.multiDisplayMode>0) { + EditWindow * wndEdit = EditWindow::getInstance(this); + wndEdit->show(); + wndEdit->addEditorPanel(ep,name); + } else { + ep->setParent (this); + + // construct closeable tab for the image + Gtk::HBox* hb = Gtk::manage (new Gtk::HBox ()); + hb->pack_start (*Gtk::manage (new RTImage ("rtwindow.png"))); + hb->pack_start (*Gtk::manage (new Gtk::Label (Glib::path_get_basename (name)))); + hb->set_tooltip_markup (name); + Gtk::Button* closeb = Gtk::manage (new Gtk::Button ()); + closeb->set_image (*Gtk::manage(new RTImage ("gtk-close.png"))); + closeb->set_relief (Gtk::RELIEF_NONE); + closeb->set_focus_on_click (false); + // make the button as small as possible + Glib::RefPtr style = Gtk::RcStyle::create (); + style->set_xthickness (0); + style->set_ythickness (0); + + closeb->modify_style (style); + closeb->signal_clicked().connect( sigc::bind (sigc::mem_fun(*this, &RTWindow::remEditorPanel) , ep)); + hb->pack_end (*closeb); + hb->set_spacing (2); + hb->show_all (); + + mainNB->append_page (*ep, *hb); + //ep->setAspect (); + mainNB->set_current_page (mainNB->page_num (*ep)); + mainNB->set_tab_reorderable (*ep, true); + + set_title_decorated(name); + epanels[ name ] = ep; + filesEdited.insert ( name ); + fpanel->refreshEditedState (filesEdited); + ep->tbTopPanel_1_visible(false); //hide the toggle Top Panel button + } +} + +void RTWindow::remEditorPanel (EditorPanel* ep) { + if (ep->getIsProcessing()) return; // Will crash if destroyed while loading + + if (options.multiDisplayMode>0) { + EditWindow * wndEdit = EditWindow::getInstance(this); + wndEdit->remEditorPanel(ep); + } else { + bool queueHadFocus = (mainNB->get_current_page() == mainNB->page_num (*bpanel)); + epanels.erase (ep->getFileName()); + filesEdited.erase (ep->getFileName ()); + fpanel->refreshEditedState (filesEdited); + + mainNB->remove_page (*ep); + + if (!isEditorPanel(mainNB->get_current_page())){ + if(!queueHadFocus) + mainNB->set_current_page (mainNB->page_num (*fpanel)); + set_title_decorated(""); + } else { + 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) { + if (options.multiDisplayMode>0) { + EditWindow * wndEdit = EditWindow::getInstance(this); + if (wndEdit->selectEditorPanel(name)) { + set_title_decorated(name); + return true; + } + } else { + std::map::iterator iep = epanels.find(name); + + if (iep!=epanels.end()) { + mainNB->set_current_page (mainNB->page_num (*iep->second)); + set_title_decorated(name); + return true; + } + else{ + //set_title_decorated(name); + //printf("RTWindow::selectEditorPanel - plain set\n"); + } + } + + return false; +} + +bool RTWindow::keyPressed (GdkEventKey* event) { + + bool ctrl = event->state & GDK_CONTROL_MASK; + //bool shift = event->state & GDK_SHIFT_MASK; + + bool try_quit = false; +#if defined(__APPLE__) + bool apple_cmd = event->state & GDK_MOD2_MASK; + if (event->keyval == GDK_q && apple_cmd) + try_quit = true; +#else + if (event->keyval == GDK_q && ctrl) + try_quit = true; +#endif + if (try_quit) { + if (!on_delete_event(0)) { + gtk_main_quit(); + } + } + + if(event->keyval == GDK_F11) + toggle_fullscreen(); + + if (simpleEditor) + // in simpleEditor mode, there's no other tab that can handle pressed keys, so we can send the event to editor panel then return + return epanel->handleShortcutKey (event);; + + if (ctrl) { + switch(event->keyval) { + case GDK_F2: // file browser panel + mainNB->set_current_page (mainNB->page_num (*fpanel)); + return true; + case GDK_F3: // batch queue panel + mainNB->set_current_page (mainNB->page_num (*bpanel)); + return true; + case GDK_F4: //single tab mode, editor panel + if (isSingleTabMode() && epanel) { + mainNB->set_current_page (mainNB->page_num (*epanel)); + } + return true; + case GDK_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)) { + return fpanel->handleShortcutKey (event); + } + 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())); + return ep->handleShortcutKey (event); + } + return false; +} + +void RTWindow::addBatchQueueJob (BatchQueueEntry* bqe, bool head) { + + std::vector entries; + entries.push_back(bqe); + bpanel->addBatchQueueJobs (entries, head); + fpanel->queue_draw (); +} + +void RTWindow::addBatchQueueJobs (std::vector &entries) { + + bpanel->addBatchQueueJobs (entries, false); + fpanel->queue_draw (); +} + +bool RTWindow::on_delete_event(GdkEventAny* event) { + + if (on_delete_has_run) { + // on Mac OSX we can get multiple events + return false; + } + // Check if any editor is still processing, and do NOT quit if so. Otherwise crashes and inconsistent caches + bool isProcessing=false; + + if (isSingleTabMode() || simpleEditor) + isProcessing=epanel->getIsProcessing(); + else { + int pageCount=mainNB->get_n_pages(); + + for (int i=0;i(mainNB->get_nth_page(i)))->getIsProcessing(); + } + } + + if (isProcessing) + return true; + + if( fpanel ) + fpanel->saveOptions (); + if( bpanel ) + bpanel->saveOptions (); + + if ((isSingleTabMode() || simpleEditor) && epanel->isRealized()) { + epanel->saveProfile(); + epanel->writeOptions (); + } + 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->writeOptions(); + optionsWritten = true; + } + } + if (!optionsWritten) { + // fallback solution: save the options of the first editor panel + std::map::iterator i=epanels.begin(); + i->second->writeOptions(); + } + } + } + + cacheMgr->closeCache (); // also makes cleanup if too large + WhiteBalance::cleanup(); + ProfilePanel::cleanup(); + + if (!options.windowMaximized) { + options.windowWidth = get_width(); + options.windowHeight = get_height(); + get_position (options.windowX,options.windowY); + } + + Options::save (); + hide(); + on_delete_has_run = true; + return false; +} + +void RTWindow::showPreferences () { + Preferences *pref = new Preferences (this); + pref->run (); + delete pref; + + fpanel->optionsChanged (); +} + +void RTWindow::setProgress (double p) { + prProgBar.set_fraction (p); +} + +void RTWindow::setProgressStr (Glib::ustring str) { + if (!options.mainNBVertical) + prProgBar.set_text ( str ); +} + +void RTWindow::setProgressState (bool inProcessing) { + if (inProcessing) + prProgBar.show(); + else + prProgBar.hide(); + } + +void RTWindow::toggle_fullscreen () { + if (is_fullscreen) { + unfullscreen(); + is_fullscreen = false; + if (btn_fullscreen) { + //btn_fullscreen->set_label(M("MAIN_BUTTON_FULLSCREEN")); + btn_fullscreen->set_tooltip_markup(M("MAIN_BUTTON_FULLSCREEN")); + btn_fullscreen->set_image (*iFullscreen); + } + } else { + fullscreen(); + is_fullscreen = true; + if (btn_fullscreen) { + //btn_fullscreen->set_label(M("MAIN_BUTTON_UNFULLSCREEN")); + btn_fullscreen->set_tooltip_markup(M("MAIN_BUTTON_UNFULLSCREEN")); + btn_fullscreen->set_image (*iFullscreen_exit); + } + } +} + +void RTWindow::error (Glib::ustring descr){ + prProgBar.set_text ( descr ); +} + +void RTWindow::SetEditorCurrent() +{ + mainNB->set_current_page (mainNB->page_num (*epanel)); +} + +void RTWindow::SetMainCurrent() +{ + mainNB->set_current_page (mainNB->page_num (*fpanel)); +} + +void RTWindow::MoveFileBrowserToMain() +{ + 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); + } +} + +void RTWindow::MoveFileBrowserToEditor() +{ + if(epanel->catalogPane->get_children().empty() ) + { + FileCatalog *fCatalog = fpanel->fileCatalog; + fpanel->ribbonPane->remove(*fCatalog); + fCatalog->disableInspector(); + epanel->catalogPane->add(*fCatalog); + epanel->showTopPanel(options.editorFilmStripOpened); + fCatalog->enableTabMode(true); + fCatalog->refreshHeight(); + fCatalog->tbLeftPanel_1_visible(false); + fCatalog->tbRightPanel_1_visible(false); + } +} + +void RTWindow::updateTPVScrollbar (bool hide) { + fpanel->updateTPVScrollbar (hide); + epanel->updateTPVScrollbar (hide); + + std::map::const_iterator itr; + for(itr = epanels.begin(); itr != epanels.end(); ++itr){ + ((*itr).second)->updateTPVScrollbar (hide); + } +} + +void RTWindow::updateTabsUsesIcons (bool useIcons) { + fpanel->updateTabsUsesIcons (useIcons); + epanel->updateTabsUsesIcons (useIcons); + + std::map::const_iterator itr; + for(itr = epanels.begin(); itr != epanels.end(); ++itr){ + ((*itr).second)->updateTabsUsesIcons (useIcons); + } +} + +void RTWindow::updateFBQueryTB (bool singleRow) { + fpanel->fileCatalog->updateFBQueryTB (singleRow); +} + +void RTWindow::updateFBToolBarVisibility (bool showFilmStripToolBar){ + fpanel->fileCatalog->updateFBToolBarVisibility (showFilmStripToolBar); +} + +void RTWindow::updateHistogramPosition (int oldPosition, int newPosition) { + epanel->updateHistogramPosition (oldPosition, newPosition); + + std::map::const_iterator itr; + for(itr = epanels.begin(); itr != epanels.end(); ++itr){ + ((*itr).second)->updateHistogramPosition (oldPosition, newPosition); + } +} + +bool RTWindow::splashClosed(GdkEventAny* event) { + delete splash; + splash = NULL; + return true; +} + +void RTWindow::set_title_decorated(Glib::ustring fname){ + Glib::ustring subtitle; + if (!fname.empty()) subtitle= " - " + fname; + set_title(versionStr + subtitle); +} + +void RTWindow::CloseOpenEditors(){ + std::map::const_iterator itr; + itr = epanels.begin(); + while(itr != epanels.end()) { + remEditorPanel((*itr).second); + itr = epanels.begin(); + } +} + +bool RTWindow::isEditorPanel(Widget* panel) { + return (panel != bpanel) && (panel != fpanel); +} + +bool RTWindow::isEditorPanel(guint pageNum) { + return isEditorPanel(mainNB->get_nth_page(pageNum)); +} diff --git a/rtgui/rtwindow.h b/rtgui/rtwindow.h new file mode 100644 index 000000000..cdd2bf290 --- /dev/null +++ b/rtgui/rtwindow.h @@ -0,0 +1,110 @@ +/* + * This file is part of RawTherapee. + * + * + * 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 _RTWINDOW_ +#define _RTWINDOW_ + +#include +#include "filepanel.h" +#include "editorpanel.h" +#include "batchqueuepanel.h" +#include +#include "progressconnector.h" +#include "editwindow.h" +#include "splash.h" +#if defined(__APPLE__) +#include +#endif + +class RTWindow : public Gtk::Window, public rtengine::ProgressListener{ + + private: + Gtk::Notebook* mainNB; + BatchQueuePanel* bpanel; + std::set filesEdited; + std::map epanels; + + Splash* splash; + Gtk::ProgressBar prProgBar; + PLDBridge* pldBridge; + bool is_fullscreen; + bool on_delete_has_run; + Gtk::Button * btn_fullscreen; + + Gtk::Image *iFullscreen, *iFullscreen_exit; + + bool isSingleTabMode() { return !options.tabbedUI && !(options.multiDisplayMode>0); }; + 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); + + Glib::ustring versionStr; +#if defined(__APPLE__) + GtkosxApplication *osxApp; +#endif + + public: + RTWindow (); + ~RTWindow(); + +#if defined(__APPLE__) + bool osxFileOpenEvent(Glib::ustring path); +#endif + void addEditorPanel (EditorPanel* ep,const std::string &name); + void remEditorPanel (EditorPanel* ep); + bool selectEditorPanel(const std::string &name); + + void addBatchQueueJob (BatchQueueEntry* bqe, bool head=false); + void addBatchQueueJobs (std::vector &entries); + + bool keyPressed (GdkEventKey* event); + bool on_delete_event(GdkEventAny* event); + bool on_window_state_event(GdkEventWindowState* event); + void on_mainNB_switch_page(GtkNotebookPage* page, guint page_num); + + void showPreferences (); + void on_realize (); + void toggle_fullscreen (); + void setProgress (double p); + void setProgressStr (Glib::ustring str); + void setProgressState (bool inProcessing); + void error (Glib::ustring descr); + rtengine::ProgressListener* getProgressListener () { return pldBridge; } + + EditorPanel* epanel; + FilePanel* fpanel; + + void SetEditorCurrent(); + void SetMainCurrent(); + void MoveFileBrowserToEditor(); + void MoveFileBrowserToMain(); + + void updateTPVScrollbar (bool hide); + void updateHistogramPosition (int oldPosition, int newPosition); + void updateTabsUsesIcons (bool useIcons); + void updateFBQueryTB (bool singleRow); + void updateFBToolBarVisibility (bool showFilmStripToolBar); + bool getIsFullscreen() { return is_fullscreen; } + void set_title_decorated(Glib::ustring fname); + void CloseOpenEditors(); +}; + +#endif diff --git a/rtgui/saveasdlg.cc b/rtgui/saveasdlg.cc new file mode 100644 index 000000000..c387f64f9 --- /dev/null +++ b/rtgui/saveasdlg.cc @@ -0,0 +1,290 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "saveasdlg.h" +#include "multilangmgr.h" +#include "guiutils.h" +#include "../rtengine/safegtk.h" +#include "rtimage.h" + +extern Options options; +SaveAsDialog::SaveAsDialog (Glib::ustring initialDir) { + + set_title(M("GENERAL_SAVE")); + + Gtk::VBox* vbox = get_vbox (); + + fchooser = Gtk::manage( new Gtk::FileChooserWidget (Gtk::FILE_CHOOSER_ACTION_SAVE) ); + fchooser->set_current_folder (initialDir); + fchooser->signal_file_activated().connect(sigc::mem_fun(*this,&SaveAsDialog::okPressed)); + + filter_jpg.set_name(M("SAVEDLG_JPGFILTER")); + filter_jpg.add_pattern("*.jpg"); + filter_jpg.add_pattern("*.JPG"); + filter_jpg.add_pattern("*.jpeg"); + filter_jpg.add_pattern("*.JPEG"); + filter_jpg.add_pattern("*.jpe"); + filter_jpg.add_pattern("*.JPE"); + + filter_tif.set_name(M("SAVEDLG_JPGFILTER")); + filter_tif.add_pattern("*.tif"); + filter_tif.add_pattern("*.TIF"); + filter_tif.add_pattern("*.tiff"); + filter_tif.add_pattern("*.TIFF"); + + filter_png.set_name(M("SAVEDLG_JPGFILTER")); + filter_png.add_pattern("*.png"); + filter_png.add_pattern("*.PNG"); + + formatChanged (options.saveFormat.format); + +// Output Options +// ~~~~~~~~~~~~~~ + formatOpts = Gtk::manage( new SaveFormatPanel () ); + formatOpts->init (options.saveFormat); + formatOpts->setListener (this); + +// queue/immediate +// ~~~~~~~~~~~~~~~ + saveMethod[0] = Gtk::manage( new Gtk::RadioButton (M("SAVEDLG_SAVEIMMEDIATELY")) ); + saveMethod[1] = Gtk::manage( new Gtk::RadioButton (M("SAVEDLG_PUTTOQUEUEHEAD")) ); + saveMethod[2] = Gtk::manage( new Gtk::RadioButton (M("SAVEDLG_PUTTOQUEUETAIL")) ); + + Gtk::RadioButton::Group g = saveMethod[0]->get_group(); + saveMethod[1]->set_group (g); + saveMethod[2]->set_group (g); + + if (options.saveMethodNum >= 0 && options.saveMethodNum < 3) + saveMethod[options.saveMethodNum]->set_active (true); + + saveMethod[0]->signal_clicked().connect( sigc::mem_fun(*this, &SaveAsDialog::saveImmediatlyClicked) ); + saveMethod[1]->signal_clicked().connect( sigc::mem_fun(*this, &SaveAsDialog::putToQueueClicked) ); + saveMethod[2]->signal_clicked().connect( sigc::mem_fun(*this, &SaveAsDialog::putToQueueClicked) ); + +// Force output format option +// ~~~~~~~~~~~~~~~~~~~~~~~~~~ + forceFormatOpts = Gtk::manage( new Gtk::CheckButton (M("SAVEDLG_FORCEFORMATOPTS")) ); + forceFormatOpts->set_active(options.forceFormatOpts); + forceFormatOpts->set_sensitive(options.saveMethodNum>0); + forceFormatOpts->signal_clicked().connect( sigc::mem_fun(*this, &SaveAsDialog::forceFmtOptsSwitched) ); + // update sensitivity of the SaveFormatPanel + formatOpts->set_sensitive(options.saveMethodNum==0 || options.forceFormatOpts); + +// Unique filename option +// ~~~~~~~~~~~~~~~~~~~~~~ + autoSuffix = Gtk::manage( new Gtk::CheckButton (M("SAVEDLG_AUTOSUFFIX")) ); + autoSuffix->set_active(options.autoSuffix); + +// buttons +// ~~~~~~~ + Gtk::Button* ok = Gtk::manage( new Gtk::Button (M("GENERAL_OK")) ); + Gtk::Button* cancel = Gtk::manage( new Gtk::Button (M("GENERAL_CANCEL")) ); + + ok->set_image (*Gtk::manage(new RTImage ("gtk-apply.png"))); + cancel->set_image (*Gtk::manage(new RTImage ("gtk-cancel.png"))); + + ok->set_tooltip_markup (M("TP_SAVEDIALOG_OK_TIP")); + + ok->signal_clicked().connect( sigc::mem_fun(*this, &SaveAsDialog::okPressed) ); + cancel->signal_clicked().connect( sigc::mem_fun(*this, &SaveAsDialog::cancelPressed) ); + +// pack everything +// ~~~~~~~~~~~~~~~ + Gtk::VBox* vbox_bottomRight = Gtk::manage(new Gtk::VBox ()); + // There is no queue in simple mode, so no need to choose + if (!simpleEditor) { + vbox_bottomRight->pack_start (*saveMethod[0], Gtk::PACK_SHRINK, 2); + vbox_bottomRight->pack_start (*saveMethod[1], Gtk::PACK_SHRINK, 2); + vbox_bottomRight->pack_start (*saveMethod[2], Gtk::PACK_SHRINK, 2); + vbox_bottomRight->pack_start (*Gtk::manage(new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 5); + } + vbox_bottomRight->pack_start (*forceFormatOpts, Gtk::PACK_SHRINK, 4); + vbox_bottomRight->pack_start (*autoSuffix, Gtk::PACK_SHRINK, 4); + + Gtk::HBox* hbox_bottom = Gtk::manage( new Gtk::HBox() ); + hbox_bottom->pack_start (*formatOpts, Gtk::PACK_SHRINK, 2); + hbox_bottom->pack_start (*Gtk::manage(new Gtk::VSeparator ()), Gtk::PACK_SHRINK, 2); + hbox_bottom->pack_start (*vbox_bottomRight, Gtk::PACK_SHRINK, 2); + + vbox->pack_start (*fchooser); + vbox->pack_start (*hbox_bottom, Gtk::PACK_SHRINK, 2); + + get_action_area()->pack_end (*ok, Gtk::PACK_SHRINK, 4); + get_action_area()->pack_end (*cancel, Gtk::PACK_SHRINK, 4); + + set_border_width (4); + show_all_children (); + + signal_key_press_event().connect( sigc::mem_fun(*this, &SaveAsDialog::keyPressed) ); +} + +void SaveAsDialog::saveImmediatlyClicked () { + forceFormatOpts->set_sensitive(false); + formatOpts->set_sensitive(true); +} + +void SaveAsDialog::putToQueueClicked () { + forceFormatOpts->set_sensitive(true); + formatOpts->set_sensitive(forceFormatOpts->get_active()); +} + +void SaveAsDialog::forceFmtOptsSwitched () { + formatOpts->set_sensitive(forceFormatOpts->get_active()); +} + +bool SaveAsDialog::getForceFormatOpts () { + + return forceFormatOpts->get_active(); +} + +bool SaveAsDialog::getAutoSuffix () { + + return autoSuffix->get_active(); +} + +bool SaveAsDialog::getImmediately () { + + return simpleEditor ? true : saveMethod[0]->get_active (); +} + +bool SaveAsDialog::getToHeadOfQueue () { + + return saveMethod[1]->get_active (); +} + +bool SaveAsDialog::getToTailOfQueue () { + + return saveMethod[2]->get_active (); +} + +int SaveAsDialog::getSaveMethodNum () { + if (simpleEditor) + return 0; + for (int i = 0; i < 3; i++) + if (saveMethod[i]->get_active()) + return i; + return -1; +} + +Glib::ustring SaveAsDialog::getFileName () { + + return fname; +} + +Glib::ustring SaveAsDialog::getDirectory () { + + return fchooser->get_current_folder (); +} + +SaveFormat SaveAsDialog::getFormat () { + + return formatOpts->getFormat (); +} + +void SaveAsDialog::okPressed () { + + fname = fchooser->get_filename(); + + // checking if the filename field is empty. The user have to click Cancel if he don't want to specify a filename + // NB: There seem to be a bug in Gtkmm2.22 / FileChooserWidget : if you suppress the filename entry and + // click on a folder in the list, the filename field is empty but get_filename will return the folder's path :/ + if (!fname.length() || safe_file_test (fname, Glib::FILE_TEST_IS_DIR)) { + Glib::ustring msg_ = Glib::ustring("") + M("MAIN_MSG_EMPTYFILENAME") + ""; + Gtk::MessageDialog msgd (*this, msg_, true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK, true); + msgd.run (); + return; + } + + // resolve extension ambiguities + SaveFormat sf = formatOpts->getFormat (); + Glib::ustring extLower = getExtension (fname).lowercase (); + bool extIsEmpty = (extLower == ""); + bool extIsJpeg = (extLower == "jpg" || extLower == "jpeg" || extLower == "jpe"); + bool extIsTiff = (extLower == "tif" || extLower == "tiff"); + bool extIsPng = (extLower == "png"); + if (extIsEmpty || !(extIsJpeg || extIsTiff || extIsPng)) { + // extension is either empty or unfamiliar. + fname += Glib::ustring (".") + sf.format; + } else if ( !(sf.format == "jpg" && extIsJpeg) + && !(sf.format == "tif" && extIsTiff) + && !(sf.format == "png" && extIsPng ) ) { + // create dialog to warn user that the filename may have two extensions on the end. + Glib::ustring msg_ = Glib::ustring ("") + M("GENERAL_WARNING") + ": " + + M("SAVEDLG_WARNFILENAME") + " \"" + Glib::path_get_basename (fname) + + "." + sf.format + "\""; + Gtk::MessageDialog msgd (*this, msg_, true, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK_CANCEL, true); + if (msgd.run () == Gtk::RESPONSE_OK) + fname += Glib::ustring (".") + sf.format; + else + return; + } + + response (Gtk::RESPONSE_OK); +} + +void SaveAsDialog::cancelPressed () { + + fname = fchooser->get_filename(); + response (Gtk::RESPONSE_CANCEL); +} + +void SaveAsDialog::formatChanged (Glib::ustring f) { + + if (f=="jpg") + fchooser->set_filter (filter_jpg); + else if (f=="png") + fchooser->set_filter (filter_png); + else if (f=="tif") + fchooser->set_filter (filter_tif); +} + +void SaveAsDialog::setInitialFileName (Glib::ustring fname) { + + fchooser->set_current_name(fname); +} + +void SaveAsDialog::setImagePath (Glib::ustring ipath) { + + Glib::ustring path = Glib::path_get_dirname(ipath); + + //Add the image's path to the Shortcut list +#ifdef WIN32 + // Dirty workaround, waiting for a clean solution by using exceptions! + if (!safe_is_shortcut_dir(path)) +#endif + try { + fchooser->add_shortcut_folder(path); + } + catch (Glib::Error &err) {} +} + + +bool SaveAsDialog::keyPressed (GdkEventKey* event) { + + bool ctrl = event->state & GDK_CONTROL_MASK; + + if (ctrl){ + switch(event->keyval) { + case GDK_Return: // Ctrl-Enter equivalent to pressing OK button + case GDK_KP_Enter: + SaveAsDialog::okPressed(); + return true; + } + } + return false; +} diff --git a/rtgui/saveasdlg.h b/rtgui/saveasdlg.h new file mode 100644 index 000000000..7db08b702 --- /dev/null +++ b/rtgui/saveasdlg.h @@ -0,0 +1,69 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _SAVEASDLG_ +#define _SAVEASDLG_ + +#include +#include "adjuster.h" +#include "saveformatpanel.h" +#include "options.h" + +class SaveAsDialog : public Gtk::Dialog, public FormatChangeListener { + + protected: + Gtk::FileChooserWidget* fchooser; + Gtk::CheckButton* autoSuffix; + Gtk::CheckButton* forceFormatOpts; + SaveFormatPanel* formatOpts; + Glib::ustring fname; + Gtk::FileFilter filter_jpg; + Gtk::FileFilter filter_tif; + Gtk::FileFilter filter_png; + Gtk::RadioButton* saveMethod[3]; /* 0 -> immediately + * 1 -> putToQueueHead + * 2 -> putToQueueTail + */ + void forceFmtOptsSwitched (); + void saveImmediatlyClicked (); + void putToQueueClicked (); + + public: + SaveAsDialog (Glib::ustring initialDir); + + Glib::ustring getFileName (); + Glib::ustring getDirectory (); + SaveFormat getFormat (); + bool getForceFormatOpts (); + bool getAutoSuffix (); + bool getImmediately (); + bool getToHeadOfQueue (); + bool getToTailOfQueue (); + int getSaveMethodNum (); + + void setInitialFileName (Glib::ustring iname); + void setImagePath (Glib::ustring ipath); + + void okPressed (); + void cancelPressed (); + void formatChanged (Glib::ustring f); + bool keyPressed (GdkEventKey* event); +}; + + +#endif diff --git a/rtgui/saveformatpanel.cc b/rtgui/saveformatpanel.cc new file mode 100644 index 000000000..e9fba1e2c --- /dev/null +++ b/rtgui/saveformatpanel.cc @@ -0,0 +1,177 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "saveformatpanel.h" +#include "multilangmgr.h" +#include "guiutils.h" + +SaveFormatPanel::SaveFormatPanel () : listener (NULL) { + + jpegqual = new Adjuster (M("SAVEDLG_JPEGQUAL"), 0, 100, 1, 100); + jpegqual->setAdjusterListener (this); + jpegqual->show (); + + jpegSubSampBox = Gtk::manage (new Gtk::HBox ()); + + jpegSubSampHead=Gtk::manage (new Gtk::Label (M("SAVEDLG_SUBSAMP") + Glib::ustring(":")) ); + jpegSubSampHead->show (); + jpegSubSampBox->pack_start (*jpegSubSampHead, Gtk::PACK_SHRINK, 4); + + jpegSubSamp = Gtk::manage (new MyComboBoxText ()); + jpegSubSamp->append_text (M("SAVEDLG_SUBSAMP_1")); + jpegSubSamp->append_text (M("SAVEDLG_SUBSAMP_2")); + jpegSubSamp->append_text (M("SAVEDLG_SUBSAMP_3")); + jpegSubSamp->set_tooltip_text (M("SAVEDLG_SUBSAMP_TOOLTIP")); + jpegSubSamp->set_active (2); + jpegSubSamp->signal_changed().connect( sigc::mem_fun(*this, &SaveFormatPanel::formatChanged) ); + jpegSubSamp->show (); + + jpegSubSampBox->pack_end (*jpegSubSamp); + jpegSubSampBox->show (); + + pngcompr = new Adjuster (M("SAVEDLG_PNGCOMPR"), 0, 6, 1, 6); + pngcompr->setAdjusterListener (this); + pngcompr->show (); + tiffuncompressed = new Gtk::CheckButton (M("SAVEDLG_TIFFUNCOMPRESSED")); + tiffuncompressed->signal_toggled().connect( sigc::mem_fun(*this,&SaveFormatPanel::formatChanged)); + tiffuncompressed->show(); + + Gtk::HBox* hb1 = Gtk::manage (new Gtk::HBox ()); + Gtk::Label* flab = Gtk::manage (new Gtk::Label (M("SAVEDLG_FILEFORMAT")+":")); + hb1->pack_start (*flab, Gtk::PACK_SHRINK,4); + format = Gtk::manage (new MyComboBoxText ()); + format->append_text ("JPEG (8 bit)"); + format->append_text ("TIFF (8 bit)"); + format->append_text ("TIFF (16 bit)"); + format->append_text ("PNG (8 bit)"); + format->append_text ("PNG (16 bit)"); + format->set_active (0); + oformat = 0; + format->signal_changed().connect( sigc::mem_fun(*this, &SaveFormatPanel::formatChanged) ); + hb1->pack_start (*format); + pack_start (*hb1, Gtk::PACK_SHRINK, 4); + + formatopts = Gtk::manage (new Gtk::VBox ()); + formatopts->pack_start (*jpegqual, Gtk::PACK_SHRINK, 4); + formatopts->pack_start (*jpegSubSampBox, Gtk::PACK_SHRINK, 4); + pack_start (*formatopts, Gtk::PACK_SHRINK, 4); + + savespp = Gtk::manage (new Gtk::CheckButton (M("SAVEDLG_SAVESPP"))); + savespp->signal_toggled().connect( sigc::mem_fun(*this,&SaveFormatPanel::formatChanged)); + pack_start (*savespp, Gtk::PACK_SHRINK, 4); + + show_all (); + set_border_width (4); + + fstr[0] = "jpg"; + fstr[1] = "tif"; + fstr[2] = "tif"; + fstr[3] = "png"; + fstr[4] = "png"; +} +SaveFormatPanel::~SaveFormatPanel () +{ + delete jpegqual; + delete pngcompr; + delete tiffuncompressed; +} + +void SaveFormatPanel::init (SaveFormat &sf) { + + FormatChangeListener* tmp = listener; + listener = NULL; + + if (sf.format=="jpg") + format->set_active (0); + else if (sf.format=="png" && sf.pngBits==16) + format->set_active (4); + else if (sf.format=="png" && sf.pngBits==8) + format->set_active (3); + else if (sf.format=="tif" && sf.tiffBits==16) + format->set_active (2); + else if (sf.format=="tif" && sf.tiffBits==8) + format->set_active (1); + + jpegSubSamp->set_active (sf.jpegSubSamp-1); + + pngcompr->setValue (sf.pngCompression); + jpegqual->setValue (sf.jpegQuality); + savespp->set_active (sf.saveParams); + tiffuncompressed->set_active (sf.tiffUncompressed); + listener = tmp; +} + +SaveFormat SaveFormatPanel::getFormat () { + + SaveFormat sf; + + int sel = format->get_active_row_number(); + sf.format = fstr[sel]; + if (sel==4) + sf.pngBits = 16; + else + sf.pngBits = 8; + if (sel==2) + sf.tiffBits = 16; + else + 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(); + sf.saveParams = savespp->get_active (); + return sf; +} + +void SaveFormatPanel::formatChanged () { + + if (oformat==0) { + removeIfThere (formatopts, jpegqual); + removeIfThere (formatopts, jpegSubSampBox); + } else if (oformat==3 || oformat==4) + removeIfThere (formatopts, pngcompr); + else if (oformat==1 || oformat==2) + removeIfThere (formatopts, tiffuncompressed); + + int act = format->get_active_row_number(); + if (act<0 || act>4) + return; + + Glib::ustring fr = fstr[act]; + if (fr=="jpg") { + formatopts->pack_start (*jpegqual, Gtk::PACK_SHRINK,4); + formatopts->pack_start (*jpegSubSampBox, Gtk::PACK_SHRINK,4); + } else if (fr=="png") + formatopts->pack_start (*pngcompr, Gtk::PACK_SHRINK,4); + else if (fr=="tif") + formatopts->pack_start (*tiffuncompressed, Gtk::PACK_SHRINK,4); + + oformat = act; + + if (listener) + listener->formatChanged (fr); +} + +void SaveFormatPanel::adjusterChanged (Adjuster* a, double newval) { + + int act = format->get_active_row_number(); + if (act<0 || act>4) + return; + if (listener) + listener->formatChanged (fstr[act]); +} diff --git a/rtgui/saveformatpanel.h b/rtgui/saveformatpanel.h new file mode 100644 index 000000000..3f21dea97 --- /dev/null +++ b/rtgui/saveformatpanel.h @@ -0,0 +1,64 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef __SAVEFORMATPANEL_H__ +#define __SAVEFORMATPANEL_H__ + +#include +#include "adjuster.h" +#include "guiutils.h" +#include "options.h" + +class FormatChangeListener { + + public: + virtual void formatChanged (Glib::ustring f) {} + +}; + +class SaveFormatPanel : public Gtk::VBox, public AdjusterListener { + + protected: + Adjuster* jpegqual; + Adjuster* pngcompr; + Gtk::CheckButton* tiffuncompressed; + MyComboBoxText* format; + MyComboBoxText* jpegSubSamp; + Gtk::VBox* formatopts; + Gtk::HBox* jpegSubSampBox; + Gtk::Label* jpegSubSampHead; + int oformat; + FormatChangeListener* listener; + Glib::ustring fstr[5]; + Gtk::CheckButton* savespp; + + + public: + + SaveFormatPanel (); + ~SaveFormatPanel (); + void setListener (FormatChangeListener* l) { listener = l; } + + void init (SaveFormat& sf); + SaveFormat getFormat (); + + void formatChanged (); + void adjusterChanged (Adjuster* a, double newval); +}; + +#endif diff --git a/rtgui/sensorbayer.cc b/rtgui/sensorbayer.cc new file mode 100644 index 000000000..759622272 --- /dev/null +++ b/rtgui/sensorbayer.cc @@ -0,0 +1,32 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "sensorbayer.h" +#include "guiutils.h" +#include "rtimage.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +SensorBayer::SensorBayer () : FoldableToolPanel(this, "sensorbayer", M("TP_RAW_SENSOR_BAYER_LABEL")) { + + packBox = Gtk::manage (new ToolParamBlock ()); + pack_start (*packBox); + + show_all (); +} diff --git a/rtgui/sensorbayer.h b/rtgui/sensorbayer.h new file mode 100644 index 000000000..419ac26b9 --- /dev/null +++ b/rtgui/sensorbayer.h @@ -0,0 +1,37 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _SENSORBAYER_H_ +#define _SENSORBAYER_H_ + +#include +#include "toolpanel.h" + +class SensorBayer : public ToolParamBlock, public FoldableToolPanel { + + protected: + ToolParamBlock* packBox; + + public: + + SensorBayer (); + + Gtk::Box* getPackBox () { return packBox; } +}; + +#endif diff --git a/rtgui/sensorxtrans.cc b/rtgui/sensorxtrans.cc new file mode 100644 index 000000000..a06064572 --- /dev/null +++ b/rtgui/sensorxtrans.cc @@ -0,0 +1,32 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "sensorxtrans.h" +#include "guiutils.h" +#include "rtimage.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +SensorXTrans::SensorXTrans () : FoldableToolPanel(this, "sensorxtrans", M("TP_RAW_SENSOR_XTRANS_LABEL")) { + + packBox = Gtk::manage (new ToolParamBlock ()); + pack_start (*packBox); + + show_all (); +} diff --git a/rtgui/sensorxtrans.h b/rtgui/sensorxtrans.h new file mode 100644 index 000000000..80318a901 --- /dev/null +++ b/rtgui/sensorxtrans.h @@ -0,0 +1,37 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _SENSORXTRANS_H_ +#define _SENSORXTRANS_H_ + +#include +#include "toolpanel.h" + +class SensorXTrans : public ToolParamBlock, public FoldableToolPanel { + + protected: + ToolParamBlock* packBox; + + public: + + SensorXTrans (); + + Gtk::Box* getPackBox () { return packBox; } +}; + +#endif diff --git a/rtgui/shadowshighlights.cc b/rtgui/shadowshighlights.cc new file mode 100644 index 000000000..ec672b3aa --- /dev/null +++ b/rtgui/shadowshighlights.cc @@ -0,0 +1,226 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "shadowshighlights.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +ShadowsHighlights::ShadowsHighlights () : FoldableToolPanel(this, "shadowshighlights", M("TP_SHADOWSHLIGHTS_LABEL"), false, true) { + + hq = Gtk::manage (new Gtk::CheckButton (M("TP_SHADOWSHLIGHTS_SHARPMASK"))); + hq->set_active (false); + pack_start (*hq); + hqConn = hq->signal_toggled().connect( sigc::mem_fun(*this, &ShadowsHighlights::hqChanged) ); + + pack_start (*Gtk::manage (new Gtk::HSeparator())); + highlights = Gtk::manage (new Adjuster (M("TP_SHADOWSHLIGHTS_HIGHLIGHTS"), 0, 100, 1, 0)); + h_tonalwidth = Gtk::manage (new Adjuster (M("TP_SHADOWSHLIGHTS_HLTONALW"), 10, 100, 1, 80)); + pack_start (*highlights); + pack_start (*h_tonalwidth); + + pack_start (*Gtk::manage (new Gtk::HSeparator())); + + shadows = Gtk::manage (new Adjuster (M("TP_SHADOWSHLIGHTS_SHADOWS"), 0, 100, 1, 0)); + s_tonalwidth = Gtk::manage (new Adjuster (M("TP_SHADOWSHLIGHTS_SHTONALW"), 10, 100, 1, 80)); + pack_start (*shadows); + pack_start (*s_tonalwidth); + + pack_start (*Gtk::manage (new Gtk::HSeparator())); + + lcontrast = Gtk::manage (new Adjuster (M("TP_SHADOWSHLIGHTS_LOCALCONTR"), 0, 100, 1, 0)); + pack_start (*lcontrast); + + pack_start (*Gtk::manage (new Gtk::HSeparator())); + + radius = Gtk::manage (new Adjuster (M("TP_SHADOWSHLIGHTS_RADIUS"), 5, 100, 1, 30)); + pack_start (*radius); + + radius->setAdjusterListener (this); + highlights->setAdjusterListener (this); + h_tonalwidth->setAdjusterListener (this); + shadows->setAdjusterListener (this); + s_tonalwidth->setAdjusterListener (this); + lcontrast->setAdjusterListener (this); + + show_all_children (); +} + +void ShadowsHighlights::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + if (pedited) { + radius->setEditedState (pedited->sh.radius ? Edited : UnEdited); + lcontrast->setEditedState (pedited->sh.localcontrast ? Edited : UnEdited); + highlights->setEditedState (pedited->sh.highlights ? Edited : UnEdited); + h_tonalwidth->setEditedState (pedited->sh.htonalwidth ? Edited : UnEdited); + shadows->setEditedState (pedited->sh.shadows ? Edited : UnEdited); + s_tonalwidth->setEditedState (pedited->sh.stonalwidth ? Edited : UnEdited); + set_inconsistent (multiImage && !pedited->sh.enabled); + hq->set_inconsistent (!pedited->sh.hq); + } + + setEnabled (pp->sh.enabled); + + hqConn.block (true); + hq->set_active (pp->sh.hq); + hqConn.block (false); + + lastHQ = pp->sh.hq; + + radius->setValue (pp->sh.radius); + lcontrast->setValue (pp->sh.localcontrast); + highlights->setValue (pp->sh.highlights); + h_tonalwidth->setValue (pp->sh.htonalwidth); + shadows->setValue (pp->sh.shadows); + s_tonalwidth->setValue (pp->sh.stonalwidth); + + enableListener (); +} + +void ShadowsHighlights::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->sh.radius = (int)radius->getValue (); + pp->sh.localcontrast = (int)lcontrast->getValue (); + pp->sh.highlights = (int)highlights->getValue (); + pp->sh.htonalwidth = (int)h_tonalwidth->getValue (); + pp->sh.shadows = (int)shadows->getValue (); + pp->sh.stonalwidth = (int)s_tonalwidth->getValue (); + pp->sh.enabled = getEnabled(); + pp->sh.hq = hq->get_active(); + + if (pedited) { + pedited->sh.radius = radius->getEditedState (); + pedited->sh.localcontrast = lcontrast->getEditedState (); + pedited->sh.highlights = highlights->getEditedState (); + pedited->sh.htonalwidth = h_tonalwidth->getEditedState (); + pedited->sh.shadows = shadows->getEditedState (); + pedited->sh.stonalwidth = s_tonalwidth->getEditedState (); + pedited->sh.enabled = !get_inconsistent(); + pedited->sh.hq = !hq->get_inconsistent(); + } +} + +void ShadowsHighlights::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + radius->setDefault (defParams->sh.radius); + lcontrast->setDefault (defParams->sh.localcontrast); + highlights->setDefault (defParams->sh.highlights); + h_tonalwidth->setDefault (defParams->sh.htonalwidth); + shadows->setDefault (defParams->sh.shadows); + s_tonalwidth->setDefault (defParams->sh.stonalwidth); + + if (pedited) { + radius->setDefaultEditedState (pedited->sh.radius ? Edited : UnEdited); + lcontrast->setDefaultEditedState (pedited->sh.localcontrast ? Edited : UnEdited); + highlights->setDefaultEditedState (pedited->sh.highlights ? Edited : UnEdited); + h_tonalwidth->setDefaultEditedState (pedited->sh.htonalwidth ? Edited : UnEdited); + shadows->setDefaultEditedState (pedited->sh.shadows ? Edited : UnEdited); + s_tonalwidth->setDefaultEditedState (pedited->sh.stonalwidth ? Edited : UnEdited); + } + else { + radius->setDefaultEditedState (Irrelevant); + lcontrast->setDefaultEditedState (Irrelevant); + highlights->setDefaultEditedState (Irrelevant); + h_tonalwidth->setDefaultEditedState (Irrelevant); + shadows->setDefaultEditedState (Irrelevant); + s_tonalwidth->setDefaultEditedState (Irrelevant); + } +} + +void ShadowsHighlights::adjusterChanged (Adjuster* a, double newval) { + + if (listener && getEnabled()) { + + Glib::ustring costr = Glib::ustring::format ((int)a->getValue()); + + if (a==highlights) + listener->panelChanged (EvSHHighlights, costr); + else if (a==h_tonalwidth) + listener->panelChanged (EvSHHLTonalW, costr); + else if (a==shadows) + listener->panelChanged (EvSHShadows, costr); + else if (a==s_tonalwidth) + listener->panelChanged (EvSHSHTonalW, costr); + else if (a==radius) + listener->panelChanged (EvSHRadius, costr); + else if (a==lcontrast) + listener->panelChanged (EvSHLContrast, costr); + } +} + +void ShadowsHighlights::enabledChanged () { + + if (listener) { + if (get_inconsistent()) + listener->panelChanged (EvSHEnabled, M("GENERAL_UNCHANGED")); + else if (getEnabled()) + listener->panelChanged (EvSHEnabled, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvSHEnabled, M("GENERAL_DISABLED")); + } +} + +void ShadowsHighlights::hqChanged () { + + if (batchMode) { + if (hq->get_inconsistent()) { + hq->set_inconsistent (false); + hqConn.block (true); + hq->set_active (false); + hqConn.block (false); + } + else if (lastHQ) + hq->set_inconsistent (true); + + lastHQ = hq->get_active (); + } + + if (listener) { + if (hq->get_active()) + listener->panelChanged (EvSHHighQuality, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvSHHighQuality, M("GENERAL_DISABLED")); + } +} + +void ShadowsHighlights::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + radius->showEditedCB (); + lcontrast->showEditedCB (); + highlights->showEditedCB (); + h_tonalwidth->showEditedCB (); + shadows->showEditedCB (); + s_tonalwidth->showEditedCB (); +} + +void ShadowsHighlights::setAdjusterBehavior (bool hadd, bool sadd, bool lcadd) { + + highlights->setAddMode(hadd); + shadows->setAddMode(sadd); + lcontrast->setAddMode(lcadd); +} + +void ShadowsHighlights::trimValues (rtengine::procparams::ProcParams* pp) { + + highlights->trimValue(pp->sh.highlights); + shadows->trimValue(pp->sh.shadows); + lcontrast->trimValue(pp->sh.localcontrast); +} diff --git a/rtgui/shadowshighlights.h b/rtgui/shadowshighlights.h new file mode 100644 index 000000000..9129d1a8c --- /dev/null +++ b/rtgui/shadowshighlights.h @@ -0,0 +1,56 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _SHADOWSHIGHLIGHTS_H_ +#define _SHADOWSHIGHLIGHTS_H_ + +#include +#include "adjuster.h" +#include "toolpanel.h" + +class ShadowsHighlights : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel { + + protected: + Adjuster* highlights; + Adjuster* h_tonalwidth; + Adjuster* shadows; + Adjuster* s_tonalwidth; + Adjuster* lcontrast; + Adjuster* radius; + Gtk::CheckButton* hq; + bool lastHQ; + sigc::connection hqConn; + + public: + + ShadowsHighlights (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + + void adjusterChanged (Adjuster* a, double newval); + void enabledChanged (); + void hqChanged (); + + void setAdjusterBehavior (bool hadd, bool sadd, bool lcadd); + void trimValues (rtengine::procparams::ProcParams* pp); +}; + +#endif diff --git a/rtgui/sharpenedge.cc b/rtgui/sharpenedge.cc new file mode 100644 index 000000000..dd9ed27b7 --- /dev/null +++ b/rtgui/sharpenedge.cc @@ -0,0 +1,161 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "sharpenedge.h" +#include "guiutils.h" +#include "../rtengine/safegtk.h" +#include +#include + +using namespace rtengine; +using namespace rtengine::procparams; + + +SharpenEdge::SharpenEdge () : FoldableToolPanel(this, "sharpenedge", M("TP_SHARPENEDGE_LABEL"), true, true) { + + passes = Gtk::manage(new Adjuster (M("TP_SHARPENEDGE_PASSES"),1,4,1,2)); + passes->setAdjusterListener (this); + if (passes->delay < 1000) passes->delay = 1000; + amount = Gtk::manage(new Adjuster (M("TP_SHARPENEDGE_AMOUNT"),0,100,1,50)); + amount->setAdjusterListener (this); + if (amount->delay < 1000) amount->delay = 1000; + + threechannels = Gtk::manage(new Gtk::CheckButton((M("TP_SHARPENEDGE_THREE"))));// L + a + b + threechannels->set_active (false); + pack_start( *passes, Gtk::PACK_SHRINK, 0);//passes + pack_start( *amount, Gtk::PACK_SHRINK, 0);//amount + pack_start( *threechannels, Gtk::PACK_SHRINK, 0);//one or 3 channels Lab + + show (); + + chanthreeconn = threechannels->signal_toggled().connect( sigc::mem_fun(*this, &SharpenEdge::chanthree_toggled) ); +} + +void SharpenEdge::read(const ProcParams* pp, const ParamsEdited* pedited) { + disableListener (); + + if(pedited ){ + passes->setEditedState (pedited->sharpenEdge.passes ? Edited : UnEdited); + amount->setEditedState (pedited->sharpenEdge.amount ? Edited : UnEdited); + set_inconsistent (multiImage && !pedited->sharpenEdge.enabled); + threechannels->set_inconsistent (!pedited->sharpenEdge.threechannels); + } + + setEnabled(pp->sharpenEdge.enabled); + + chanthreeconn.block (true); + threechannels->set_active (pp->sharpenEdge.threechannels); + chanthreeconn.block (false); + lastchanthree = pp->sharpenEdge.threechannels; + + passes->setValue (pp->sharpenEdge.passes); + amount->setValue (pp->sharpenEdge.amount); + + enableListener (); +} + +void SharpenEdge::write( ProcParams* pp, ParamsEdited* pedited) { + pp->sharpenEdge.enabled = getEnabled(); + pp->sharpenEdge.passes = (int)passes->getValue(); + pp->sharpenEdge.amount = amount->getValue (); + pp->sharpenEdge.threechannels = threechannels->get_active (); + + if (pedited) { + pedited->sharpenEdge.enabled = !get_inconsistent(); + pedited->sharpenEdge.passes = passes->getEditedState (); + pedited->sharpenEdge.amount = amount->getEditedState (); + pedited->sharpenEdge.threechannels = !threechannels->get_inconsistent(); + } + +} + +void SharpenEdge::enabledChanged () { + if (listener) { + if (get_inconsistent()) + listener->panelChanged (EvSharpenEdgeEnabled, M("GENERAL_UNCHANGED")); + else if (getEnabled()) + listener->panelChanged (EvSharpenEdgeEnabled, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvSharpenEdgeEnabled, M("GENERAL_DISABLED")); + } +} + +void SharpenEdge::chanthree_toggled () { + + if (batchMode) { + if (threechannels->get_inconsistent()) { + threechannels->set_inconsistent (false); + chanthreeconn.block (true); + threechannels->set_active (false); + chanthreeconn.block (false); + } + else if (lastchanthree) + threechannels->set_inconsistent (true); + + lastchanthree = threechannels->get_active (); + } + + if (listener && getEnabled()) { + if (threechannels->get_active ()) + listener->panelChanged (EvSharpenEdgeThreechannels, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvSharpenEdgeThreechannels, M("GENERAL_DISABLED")); + } +} + +void SharpenEdge::adjusterChanged (Adjuster* a, double newval) { + if (listener && getEnabled()) { + Glib::ustring value = a->getTextValue(); + + if (a == passes ) + listener->panelChanged (EvSharpenEdgePasses, value ); + else if (a == amount) + listener->panelChanged (EvSharpenEdgeAmount, value ); + } +} + +void SharpenEdge::setBatchMode(bool batchMode) { + passes->showEditedCB (); + amount->showEditedCB (); +} + +void SharpenEdge::setDefaults(const ProcParams* defParams, const ParamsEdited* pedited) { + passes->setDefault (defParams->sharpenEdge.passes); + amount->setDefault (defParams->sharpenEdge.amount); + + if (pedited) { + passes->setDefaultEditedState (pedited->sharpenEdge.passes ? Edited : UnEdited); + amount->setDefaultEditedState (pedited->sharpenEdge.amount ? Edited : UnEdited); + + } else { + passes->setDefaultEditedState (Irrelevant); + amount->setDefaultEditedState (Irrelevant); + + } +} + +void SharpenEdge::setAdjusterBehavior (bool amountadd, bool passadd) { + amount->setAddMode (amountadd); + passes->setAddMode (passadd); +} + +void SharpenEdge::trimValues (ProcParams* pp) { + amount->trimValue (pp->sharpenEdge.amount); + passes->trimValue (pp->sharpenEdge.passes); + +} diff --git a/rtgui/sharpenedge.h b/rtgui/sharpenedge.h new file mode 100644 index 000000000..30856a5ff --- /dev/null +++ b/rtgui/sharpenedge.h @@ -0,0 +1,59 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + * + * + * Manuel Llorens' algorithm of edge sharpening + * + * + */ +#ifndef _SHARPENEDGE_H_ +#define _SHARPENEDGE_H_ + +#include +#include "adjuster.h" +#include "toolpanel.h" + +class SharpenEdge : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel { + +protected: + + Adjuster* passes; + Adjuster* amount; + Gtk::CheckButton* threechannels; + + sigc::connection chanthreeconn; + bool lastchanthree; + +public: + + SharpenEdge (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + void trimValues (rtengine::procparams::ProcParams* pp); + void setAdjusterBehavior (bool amountadd, bool passadd); + void adjusterChanged (Adjuster* a, double newval); + + void enabledChanged (); + void chanthree_toggled (); + +}; + +#endif diff --git a/rtgui/sharpening.cc b/rtgui/sharpening.cc new file mode 100644 index 000000000..b94b13e50 --- /dev/null +++ b/rtgui/sharpening.cc @@ -0,0 +1,452 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "sharpening.h" +#include +#include +#include "guiutils.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +Sharpening::Sharpening () : FoldableToolPanel(this,"sharpening", M("TP_SHARPENING_LABEL"), true, true) { + + std::vector milestones; + milestones.push_back( GradientMilestone(0.0, 0.0, 0.0, 0.0) ); + milestones.push_back( GradientMilestone(1.0, 1.0, 1.0, 1.0) ); + + setEnabledTooltipMarkup(M("TP_SHARPENING_TOOLTIP")); + + Gtk::HBox* hb = Gtk::manage (new Gtk::HBox ()); + hb->set_border_width (4); + hb->show (); + Gtk::Label* ml = Gtk::manage (new Gtk::Label (M("TP_SHARPENING_METHOD")+":")); + ml->show (); + method = Gtk::manage (new MyComboBoxText ()); + method->append_text (M("TP_SHARPENING_USM")); + method->append_text (M("TP_SHARPENING_RLD")); + method->show (); + hb->pack_start(*ml, Gtk::PACK_SHRINK, 4); + hb->pack_start(*method); + pack_start (*hb); + + rld = new Gtk::VBox (); + dradius = Gtk::manage (new Adjuster (M("TP_SHARPENING_EDRADIUS"), 0.5, 2.5, 0.01, 0.75)); + damount = Gtk::manage (new Adjuster (M("TP_SHARPENING_RLD_AMOUNT"), 0.0, 100, 1, 75)); + ddamping = Gtk::manage (new Adjuster (M("TP_SHARPENING_RLD_DAMPING"), 0, 100, 1, 20)); + diter = Gtk::manage (new Adjuster (M("TP_SHARPENING_RLD_ITERATIONS"), 5, 100, 1, 30)); + rld->pack_start (*dradius); + rld->pack_start (*damount); + rld->pack_start (*ddamping); + rld->pack_start (*diter); + dradius->show (); + damount->show (); + ddamping->show (); + diter->show (); + rld->show (); + + usm = new Gtk::VBox (); + usm->show (); + + + Gtk::HSeparator *hsep6a = Gtk::manage (new Gtk::HSeparator()); + amount = Gtk::manage (new Adjuster (M("TP_SHARPENING_AMOUNT"), 1, 1000, 1, 200)); + radius = Gtk::manage (new Adjuster (M("TP_SHARPENING_RADIUS"), 0.3, 3, 0.01, 0.5)); + threshold = Gtk::manage (new ThresholdAdjuster (M("TP_SHARPENING_THRESHOLD"), 0., 2000., 20., 80., 2000., 1200., 0, false)); + threshold->setBgGradient(milestones); + pack_start(*hsep6a, Gtk::PACK_SHRINK, 2); + + pack_start (*usm); + + usm->pack_start(*radius); + usm->pack_start(*amount); + usm->pack_start(*threshold); + hsep6a->show (); + radius->show (); + amount->show (); + threshold->show (); + + Gtk::HSeparator *hsep6 = Gtk::manage (new Gtk::HSeparator()); + edgesonly = Gtk::manage (new Gtk::CheckButton (M("TP_SHARPENING_ONLYEDGES"))); + edgesonly->set_active (false); + edgebox = new Gtk::VBox (); + eradius = Gtk::manage (new Adjuster (M("TP_SHARPENING_EDRADIUS"), 0.5, 2.5, 0.1, 1.9)); + etolerance = Gtk::manage (new Adjuster (M("TP_SHARPENING_EDTOLERANCE"), 10, 10000, 100, 1000)); + usm->pack_start(*hsep6, Gtk::PACK_SHRINK, 2); + usm->pack_start(*edgesonly); + edgebox->pack_start(*eradius); + edgebox->pack_start(*etolerance); + edgebox->show (); + edgebin = Gtk::manage (new Gtk::VBox ()); + usm->pack_start (*edgebin); + edgebin->show (); + hsep6->show(); + edgesonly->show(); + eradius->show(); + etolerance->show(); + + Gtk::HSeparator *hsep6b = Gtk::manage (new Gtk::HSeparator()); + halocontrol = Gtk::manage (new Gtk::CheckButton (M("TP_SHARPENING_HALOCONTROL"))); + halocontrol->set_active (false); + hcbox = new Gtk::VBox (); + hcamount = Gtk::manage (new Adjuster (M("TP_SHARPENING_HCAMOUNT"), 1, 100, 1, 75)); + usm->pack_start(*hsep6b, Gtk::PACK_SHRINK, 2); + usm->pack_start(*halocontrol); + hcbox->pack_start(*hcamount); + hcbox->show (); + hcbin = Gtk::manage (new Gtk::VBox ()); + usm->pack_start (*hcbin); + hcbin->show (); + hsep6b->show (); + halocontrol->show (); + hcamount->show (); + + dradius->setAdjusterListener (this); + damount->setAdjusterListener (this); + ddamping->setAdjusterListener (this); + diter->setAdjusterListener (this); + radius->setAdjusterListener (this); + amount->setAdjusterListener (this); + eradius->setAdjusterListener (this); + etolerance->setAdjusterListener (this); + hcamount->setAdjusterListener (this); + + edgebox->reference (); + hcbox->reference (); + usm->reference (); + rld->reference (); + + eonlyConn = edgesonly->signal_toggled().connect( sigc::mem_fun(*this, &Sharpening::edgesonly_toggled) ); + hcConn = halocontrol->signal_toggled().connect( sigc::mem_fun(*this, &Sharpening::halocontrol_toggled) ); + method->signal_changed().connect( sigc::mem_fun(*this, &Sharpening::method_changed) ); +} + +Sharpening::~Sharpening () { + + delete usm; + delete rld; + delete edgebox; + delete hcbox; +} + + +void Sharpening::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + if (pedited) { + amount->setEditedState (pedited->sharpening.amount ? Edited : UnEdited); + radius->setEditedState (pedited->sharpening.radius ? Edited : UnEdited); + threshold->setEditedState (pedited->sharpening.threshold ? Edited : UnEdited); + eradius->setEditedState (pedited->sharpening.edges_radius ? Edited : UnEdited); + etolerance->setEditedState (pedited->sharpening.edges_tolerance ? Edited : UnEdited); + hcamount->setEditedState (pedited->sharpening.halocontrol_amount ? Edited : UnEdited); + damount->setEditedState (pedited->sharpening.deconvamount ? Edited : UnEdited); + dradius->setEditedState (pedited->sharpening.deconvradius ? Edited : UnEdited); + diter->setEditedState (pedited->sharpening.deconviter ? Edited : UnEdited); + ddamping->setEditedState (pedited->sharpening.deconvdamping ? Edited : UnEdited); + + halocontrol->set_inconsistent (multiImage && !pedited->sharpening.halocontrol); + edgesonly->set_inconsistent (multiImage && !pedited->sharpening.edgesonly); + set_inconsistent (multiImage && !pedited->sharpening.enabled); + } + + setEnabled (pp->sharpening.enabled); + + eonlyConn.block (true); + edgesonly->set_active (pp->sharpening.edgesonly); + eonlyConn.block (false); + lastEdgesOnly = pp->sharpening.edgesonly; + + hcConn.block (true); + halocontrol->set_active (pp->sharpening.halocontrol); + hcConn.block (false); + lastHaloControl = pp->sharpening.halocontrol; + + amount->setValue (pp->sharpening.amount); + radius->setValue (pp->sharpening.radius); + threshold->setValue(pp->sharpening.threshold); + eradius->setValue (pp->sharpening.edges_radius); + etolerance->setValue (pp->sharpening.edges_tolerance); + hcamount->setValue (pp->sharpening.halocontrol_amount); + + dradius->setValue (pp->sharpening.deconvradius); + damount->setValue (pp->sharpening.deconvamount); + diter->setValue (pp->sharpening.deconviter); + ddamping->setValue (pp->sharpening.deconvdamping); + + if (!batchMode) { + removeIfThere (edgebin, edgebox, false); + if (edgesonly->get_active ()) + edgebin->pack_start (*edgebox); + + removeIfThere (hcbin, hcbox, false); + if (halocontrol->get_active ()) + hcbin->pack_start (*hcbox); + + } + if (pedited && !pedited->sharpening.method) + method->set_active (2); + else if (pp->sharpening.method=="usm") + method->set_active (0); + else if (pp->sharpening.method=="rld") + method->set_active (1); + + enableListener (); +} + +void Sharpening::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->sharpening.amount = (int)amount->getValue(); + pp->sharpening.enabled = getEnabled (); + pp->sharpening.radius = radius->getValue (); + pp->sharpening.threshold = threshold->getValue (); + pp->sharpening.edgesonly = edgesonly->get_active (); + pp->sharpening.edges_radius = eradius->getValue (); + pp->sharpening.edges_tolerance = (int)etolerance->getValue (); + pp->sharpening.halocontrol = halocontrol->get_active (); + pp->sharpening.halocontrol_amount = (int)hcamount->getValue (); + pp->sharpening.deconvradius = dradius->getValue (); + pp->sharpening.deconviter = (int)diter->getValue (); + pp->sharpening.deconvamount = (int)damount->getValue (); + pp->sharpening.deconvdamping = (int)ddamping->getValue (); + + if (method->get_active_row_number()==0) + pp->sharpening.method = "usm"; + else if (method->get_active_row_number()==1) + pp->sharpening.method = "rld"; + + if (pedited) { + pedited->sharpening.amount = amount->getEditedState (); + pedited->sharpening.radius = radius->getEditedState (); + pedited->sharpening.threshold = threshold->getEditedState (); + pedited->sharpening.edges_radius = eradius->getEditedState (); + pedited->sharpening.edges_tolerance = etolerance->getEditedState (); + pedited->sharpening.halocontrol_amount = hcamount->getEditedState (); + pedited->sharpening.deconvamount = damount->getEditedState (); + pedited->sharpening.deconvradius = dradius->getEditedState (); + pedited->sharpening.deconviter = diter->getEditedState (); + pedited->sharpening.deconvdamping = ddamping->getEditedState (); + pedited->sharpening.method = method->get_active_row_number()!=2; + pedited->sharpening.halocontrol = !halocontrol->get_inconsistent(); + pedited->sharpening.edgesonly = !edgesonly->get_inconsistent(); + pedited->sharpening.enabled = !get_inconsistent(); + } +} + +void Sharpening::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + amount->setDefault (defParams->sharpening.amount); + radius->setDefault (defParams->sharpening.radius); + threshold->setDefault (defParams->sharpening.threshold); + eradius->setDefault (defParams->sharpening.edges_radius); + etolerance->setDefault (defParams->sharpening.edges_tolerance); + hcamount->setDefault (defParams->sharpening.halocontrol_amount); + damount->setDefault (defParams->sharpening.deconvamount); + dradius->setDefault (defParams->sharpening.deconvradius); + diter->setDefault (defParams->sharpening.deconviter); + ddamping->setDefault (defParams->sharpening.deconvdamping); + + if (pedited) { + amount->setDefaultEditedState (pedited->sharpening.amount ? Edited : UnEdited); + radius->setDefaultEditedState (pedited->sharpening.radius ? Edited : UnEdited); + threshold->setDefaultEditedState (pedited->sharpening.threshold ? Edited : UnEdited); + eradius->setDefaultEditedState (pedited->sharpening.edges_radius ? Edited : UnEdited); + etolerance->setDefaultEditedState (pedited->sharpening.edges_tolerance ? Edited : UnEdited); + hcamount->setDefaultEditedState (pedited->sharpening.halocontrol_amount ? Edited : UnEdited); + damount->setDefaultEditedState (pedited->sharpening.deconvamount ? Edited : UnEdited); + dradius->setDefaultEditedState (pedited->sharpening.deconvradius ? Edited : UnEdited); + diter->setDefaultEditedState (pedited->sharpening.deconviter ? Edited : UnEdited); + ddamping->setDefaultEditedState (pedited->sharpening.deconvdamping ? Edited : UnEdited); + } + else { + amount->setDefaultEditedState (Irrelevant); + radius->setDefaultEditedState (Irrelevant); + threshold->setDefaultEditedState (Irrelevant); + eradius->setDefaultEditedState (Irrelevant); + etolerance->setDefaultEditedState (Irrelevant); + hcamount->setDefaultEditedState (Irrelevant); + damount->setDefaultEditedState (Irrelevant); + dradius->setDefaultEditedState (Irrelevant); + diter->setDefaultEditedState (Irrelevant); + ddamping->setDefaultEditedState (Irrelevant); + } +} + +void Sharpening::adjusterChanged (Adjuster* a, double newval) { + + if (listener && (multiImage||getEnabled()) ) { + + Glib::ustring costr; + if (a==radius || a==dradius) + costr = Glib::ustring::format (std::setw(3), std::fixed, std::setprecision(2), a->getValue()); + else if (a==eradius) + costr = Glib::ustring::format (std::setw(2), std::fixed, std::setprecision(1), a->getValue()); + else + costr = Glib::ustring::format ((int)a->getValue()); + + if (a==amount) + listener->panelChanged (EvShrAmount, costr); + else if (a==radius) + listener->panelChanged (EvShrRadius, costr); + else if (a==eradius) + listener->panelChanged (EvShrEdgeRadius, costr); + else if (a==etolerance) + listener->panelChanged (EvShrEdgeTolerance, costr); + else if (a==hcamount) + listener->panelChanged (EvShrHaloAmount, costr); + else if (a==dradius) + listener->panelChanged (EvShrDRadius, costr); + else if (a==damount) + listener->panelChanged (EvShrDAmount, costr); + else if (a==ddamping) + listener->panelChanged (EvShrDDamping, costr); + else if (a==diter) + listener->panelChanged (EvShrDIterations, costr); + } +} + +//void Sharpening::adjusterChanged (ThresholdAdjuster* a, int newBottomLeft, int newTopLeft, int newBottomRight, int newTopRight) { +void Sharpening::adjusterChanged (ThresholdAdjuster* a, int newBottomLeft, int newTopLeft, int newBottomRight, int newTopRight) { + if (listener && (multiImage||getEnabled()) ) { + listener->panelChanged (EvShrThresh, threshold->getHistoryString()); + } +} + +void Sharpening::enabledChanged () { + + if (listener) { + if (get_inconsistent()) + listener->panelChanged (EvShrEnabled, M("GENERAL_UNCHANGED")); + else if (getEnabled()) + listener->panelChanged (EvShrEnabled, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvShrEnabled, M("GENERAL_DISABLED")); + } +} + +void Sharpening::edgesonly_toggled () { + + if (multiImage) { + if (edgesonly->get_inconsistent()) { + edgesonly->set_inconsistent (false); + eonlyConn.block (true); + edgesonly->set_active (false); + eonlyConn.block (false); + } + else if (lastEdgesOnly) + edgesonly->set_inconsistent (true); + + lastEdgesOnly = edgesonly->get_active (); + } + + if (!batchMode) { + removeIfThere (edgebin, edgebox, false); + if (edgesonly->get_active ()) + edgebin->pack_start (*edgebox); + } + + if (listener && (multiImage||getEnabled()) ) { + if (edgesonly->get_inconsistent()) + listener->panelChanged (EvShrEdgeOnly, M("GENERAL_INITIALVALUES")); + else if (edgesonly->get_active ()) + listener->panelChanged (EvShrEdgeOnly, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvShrEdgeOnly, M("GENERAL_DISABLED")); + } +} + +void Sharpening::halocontrol_toggled () { + + if (multiImage) { + if (halocontrol->get_inconsistent()) { + halocontrol->set_inconsistent (false); + hcConn.block (true); + halocontrol->set_active (false); + hcConn.block (false); + } + else if (lastHaloControl) + halocontrol->set_inconsistent (true); + + lastHaloControl = halocontrol->get_active (); + } + + if (!batchMode) { + removeIfThere (hcbin, hcbox, false); + if (halocontrol->get_active ()) + hcbin->pack_start (*hcbox); + } + + if (listener && (multiImage||getEnabled()) ) { + if (halocontrol->get_inconsistent()) + listener->panelChanged (EvShrHaloControl, M("GENERAL_INITIALVALUES")); + else if (halocontrol->get_active ()) + listener->panelChanged (EvShrHaloControl, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvShrHaloControl, M("GENERAL_DISABLED")); + } +} + +void Sharpening::method_changed () { + + 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 (listener && (multiImage||getEnabled()) ) + listener->panelChanged (EvShrMethod, method->get_active_text ()); + +} + +void Sharpening::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + + removeIfThere (hcbin, hcbox, false); + hcbin->pack_start (*hcbox); + removeIfThere (edgebin, edgebox, false); + edgebin->pack_start (*edgebox); + + radius->showEditedCB (); + amount->showEditedCB (); + threshold->showEditedCB (); + eradius->showEditedCB (); + etolerance->showEditedCB (); + hcamount->showEditedCB (); + dradius->showEditedCB (); + damount->showEditedCB (); + ddamping->showEditedCB (); + diter->showEditedCB (); + method->append_text (M("GENERAL_UNCHANGED")); +} + +void Sharpening::setAdjusterBehavior (bool amountadd) { + + amount->setAddMode(amountadd); + damount->setAddMode(amountadd); +} + +void Sharpening::trimValues (rtengine::procparams::ProcParams* pp) { + + amount->trimValue(pp->sharpening.amount); + damount->trimValue(pp->sharpening.deconvamount); +} diff --git a/rtgui/sharpening.h b/rtgui/sharpening.h new file mode 100644 index 000000000..be2c01ad0 --- /dev/null +++ b/rtgui/sharpening.h @@ -0,0 +1,76 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _SHARPENING_H_ +#define _SHARPENING_H_ + +#include +#include "adjuster.h" +#include "thresholdadjuster.h" +#include "toolpanel.h" + +class Sharpening : public ToolParamBlock, public ThresholdAdjusterListener, public AdjusterListener, public FoldableToolPanel { + + protected: + MyComboBoxText* method; + Adjuster* dradius; + Adjuster* damount; + Adjuster* ddamping; + Adjuster* diter; + Gtk::VBox* usm; + Gtk::VBox* rld; + + Adjuster* radius; + Adjuster* amount; + Adjuster* eradius; + Adjuster* etolerance; + Adjuster* hcamount; + Gtk::VBox* edgebin; + Gtk::VBox* hcbin; + Gtk::VBox* edgebox; + Gtk::VBox* hcbox; + ThresholdAdjuster* threshold; + Gtk::CheckButton* edgesonly; + bool lastEdgesOnly; + sigc::connection eonlyConn; + Gtk::CheckButton* halocontrol; + bool lastHaloControl; + sigc::connection hcConn; + + public: + + Sharpening (); + virtual ~Sharpening (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + + void adjusterChanged (Adjuster* a, double newval); + void adjusterChanged (ThresholdAdjuster* a, int newBottomLeft, int newTopLeft, int newBottomRight, int newTopRight); + void enabledChanged (); + void edgesonly_toggled (); + void halocontrol_toggled (); + void method_changed (); + + void setAdjusterBehavior (bool amountadd); + void trimValues (rtengine::procparams::ProcParams* pp); +}; + +#endif diff --git a/rtgui/sharpenmicro.cc b/rtgui/sharpenmicro.cc new file mode 100644 index 000000000..3577ba217 --- /dev/null +++ b/rtgui/sharpenmicro.cc @@ -0,0 +1,162 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "sharpenmicro.h" +#include "guiutils.h" +#include "../rtengine/safegtk.h" +#include +#include + +using namespace rtengine; +using namespace rtengine::procparams; + + +SharpenMicro::SharpenMicro () : FoldableToolPanel(this, "sharpenmicro", M("TP_SHARPENMICRO_LABEL"), true, true) { + + setEnabledTooltipMarkup(M("TP_SHARPENING_TOOLTIP")); + + amount= Gtk::manage(new Adjuster (M("TP_SHARPENMICRO_AMOUNT"),0,100,1,20)); + amount->setAdjusterListener (this); + if (amount->delay < 1000) amount->delay = 1000; + amount->show(); + uniformity= Gtk::manage(new Adjuster (M("TP_SHARPENMICRO_UNIFORMITY"),0,100,10,50)); + + uniformity->setAdjusterListener (this); + if (uniformity->delay < 1000) uniformity->delay = 1000; + uniformity->show(); + matrix = Gtk::manage (new Gtk::CheckButton (M("TP_SHARPENMICRO_MATRIX"))); + matrix->set_active (true); + pack_start(*matrix, Gtk::PACK_SHRINK, 0); + matrix->show (); + + pack_start( *amount, Gtk::PACK_SHRINK, 0); + pack_start( *uniformity, Gtk::PACK_SHRINK, 0); + + show (); + + matrixconn = matrix->signal_toggled().connect( sigc::mem_fun(*this, &SharpenMicro::matrix_toggled) ); +} + +void SharpenMicro::read(const ProcParams* pp, const ParamsEdited* pedited) { + disableListener (); + + if(pedited ){ + set_inconsistent (multiImage && !pedited->sharpenMicro.enabled); + matrix->set_inconsistent (!pedited->sharpenMicro.matrix); + amount->setEditedState (pedited->sharpenMicro.amount ? Edited : UnEdited); + uniformity->setEditedState (pedited->sharpenMicro.uniformity ? Edited : UnEdited); + } + + setEnabled(pp->sharpenMicro.enabled); + + matrixconn.block (true); + matrix->set_active (pp->sharpenMicro.matrix); + matrixconn.block (false); + lastmatrix = pp->sharpenMicro.matrix; + + amount->setValue (pp->sharpenMicro.amount); + uniformity->setValue (pp->sharpenMicro.uniformity); + + enableListener (); +} + +void SharpenMicro::write( ProcParams* pp, ParamsEdited* pedited) { + pp->sharpenMicro.enabled = getEnabled(); + pp->sharpenMicro.matrix = matrix->get_active (); + pp->sharpenMicro.amount = amount->getValue (); + pp->sharpenMicro.uniformity = uniformity->getValue (); + + if (pedited) { + pedited->sharpenMicro.enabled = !get_inconsistent(); + pedited->sharpenMicro.matrix = !matrix->get_inconsistent(); + pedited->sharpenMicro.amount = amount->getEditedState (); + pedited->sharpenMicro.uniformity = uniformity->getEditedState (); + } +} + +void SharpenMicro::enabledChanged () { + + if (listener) { + if (get_inconsistent()) + listener->panelChanged (EvSharpenMicroEnabled, M("GENERAL_UNCHANGED")); + else if (getEnabled()) + listener->panelChanged (EvSharpenMicroEnabled, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvSharpenMicroEnabled, M("GENERAL_DISABLED")); + } +} + +void SharpenMicro::matrix_toggled () { + if (batchMode) { + if (matrix->get_inconsistent()) { + matrix->set_inconsistent (false); + matrixconn.block (true); + matrix->set_active (false); + matrixconn.block (false); + } + else if (lastmatrix) + matrix->set_inconsistent (true); + + lastmatrix = matrix->get_active (); + } + + if (listener && getEnabled()) { + if (matrix->get_active ()) + listener->panelChanged (EvSharpenMicroMatrix, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvSharpenMicroMatrix, M("GENERAL_DISABLED")); + } +} + +void SharpenMicro::adjusterChanged (Adjuster* a, double newval) { + if (listener && getEnabled()) { + Glib::ustring value = a->getTextValue(); + if (a == amount) + listener->panelChanged (EvSharpenMicroAmount, value ); + else if (a == uniformity) + listener->panelChanged (EvSharpenMicroUniformity, value ); + } +} + +void SharpenMicro::setBatchMode(bool batchMode) { + amount->showEditedCB (); + uniformity->showEditedCB (); +} + +void SharpenMicro::setDefaults(const ProcParams* defParams, const ParamsEdited* pedited) { + amount->setDefault (defParams->sharpenMicro.amount); + uniformity->setDefault (defParams->sharpenMicro.uniformity); + + if (pedited) { + amount->setDefaultEditedState (pedited->sharpenMicro.amount ? Edited : UnEdited); + uniformity->setDefaultEditedState (pedited->sharpenMicro.uniformity ? Edited : UnEdited); + } else { + amount->setDefaultEditedState (Irrelevant); + uniformity->setDefaultEditedState (Irrelevant); + } +} + +void SharpenMicro::setAdjusterBehavior (bool amountadd, bool uniformityadd ) { + amount->setAddMode (amountadd); + uniformity->setAddMode (uniformityadd); +} + +void SharpenMicro::trimValues (ProcParams* pp) { + amount->trimValue (pp->sharpenMicro.amount); + uniformity->trimValue (pp->sharpenMicro.uniformity); +} diff --git a/rtgui/sharpenmicro.h b/rtgui/sharpenmicro.h new file mode 100644 index 000000000..7cf0f0384 --- /dev/null +++ b/rtgui/sharpenmicro.h @@ -0,0 +1,60 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + * + * + * Manuel Llorens' algorithm of micro-contrast sharpening + * + * + */ +#ifndef _SHARPENMICRO_H_ +#define _SHARPENMICRO_H_ + +#include +#include "adjuster.h" +#include "toolpanel.h" + +class SharpenMicro : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel { + +protected: + + Gtk::CheckButton* matrix; + Adjuster* amount; + Adjuster* uniformity; + + sigc::connection matrixconn; + bool lastmatrix; + +public: + + SharpenMicro (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + void trimValues (rtengine::procparams::ProcParams* pp); + void setAdjusterBehavior (bool amountadd, bool uniformityadd ); + void adjusterChanged (Adjuster* a, double newval); + + void enabledChanged (); + void matrix_toggled (); + + +}; + +#endif diff --git a/rtgui/shcselector.cc b/rtgui/shcselector.cc new file mode 100644 index 000000000..6b59db316 --- /dev/null +++ b/rtgui/shcselector.cc @@ -0,0 +1,254 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "shcselector.h" +#include "multilangmgr.h" +#include "mycurve.h" + +SHCSelector::SHCSelector() : ColoredBar(RTO_Left2Right), movingPosition(-1), cl(NULL) { + + positions[0] = defaults[0] = 0.25; + positions[1] = defaults[1] = 0.5; + positions[2] = defaults[2] = 0.75; + leftMargin = RADIUS; + rightMargin = RADIUS; + + // TODO: This is a hack :) ; change this name to a specific one and create a new entry in all gtkrc theme files + set_name("ThresholdSelector"); + set_can_focus(false); + set_size_request (-1, 12); + set_tooltip_text(M("SHCSELECTOR_TOOLTIP")); +} + +void SHCSelector::setMargins(int left, int right) { + leftMargin = left; + rightMargin = right; +} + +void SHCSelector::setDefaults (double spos, double cpos, double hpos) { + defaults[0] = spos; + defaults[1] = cpos; + defaults[2] = hpos; +} + +void SHCSelector::setPositions (double spos, double cpos, double hpos) { + + positions[0] = spos; + positions[1] = cpos; + positions[2] = hpos; + + queue_draw (); +} + +void SHCSelector::getPositions (double& spos, double& cpos, double& hpos) { + + spos = positions[0]; + cpos = positions[1]; + hpos = positions[2]; +} + +void SHCSelector::on_realize() { + + Gtk::DrawingArea::on_realize(); + + add_events(Gdk::EXPOSURE_MASK | Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK); +} + +bool SHCSelector::on_expose_event(GdkEventExpose* event) { + + Gdk::Color c; + Cairo::RefPtr cr = get_window()->create_cairo_context(); + + int w = get_width () - leftMargin - rightMargin; + int h = get_height (); + + wslider = std::max(int(h / 5), 10); + double hwslider = double(wslider)/2.; + + Gtk::StateType state = !is_sensitive() ? Gtk::STATE_INSENSITIVE : Gtk::STATE_NORMAL; + Glib::RefPtr style = get_style(); + + // clear bg + + // set the box's colors + cr->set_line_width (1.0); + cr->set_line_cap(Cairo::LINE_CAP_BUTT); + if (is_sensitive() && canGetColors()) { + // gradient background + Glib::RefPtr win = get_window(); + // this will eventually create/update the off-screen pixmap + setDrawRectangle(win, leftMargin+1, 1, w-2, int(float(h)*5.5f/7.f+0.5f)); + // that we're displaying here + ColoredBar::expose(win); + } + else { + // solid background + c = style->get_bg (state); + if (state==Gtk::STATE_INSENSITIVE) + cr->set_source_rgb (c.get_red_p()*0.96, c.get_green_p()*0.96, c.get_blue_p()*0.96); + else + cr->set_source_rgb (c.get_red_p()*0.85, c.get_green_p()*0.85, c.get_blue_p()*0.85); + + // draw the box's background + cr->rectangle (leftMargin+1, 1, w-2, int(float(h)*5.5f/7.f+0.5f)); + cr->fill(); + } + + // draw the box's borders + cr->set_line_width (1.); + cr->rectangle (leftMargin+0.5, 0.5, w-1, int(float(h)*5.5f/7.f+0.5f)+1); + c = style->get_bg (state); + if (state==Gtk::STATE_INSENSITIVE) + cr->set_source_rgb (c.get_red_p()*0.85, c.get_green_p()*0.85, c.get_blue_p()*0.85); + else + cr->set_source_rgb (c.get_red_p()*0.7, c.get_green_p()*0.7, c.get_blue_p()*0.7); + cr->stroke (); + + // draw sliders + //cr->set_line_width (1.0); + for (int i=0; i<3; i++) { + cr->move_to (leftMargin+0.5+(w-1)*positions[i]+hwslider, double(h)-0.5); + cr->rel_line_to (0., double(-h/3)); + cr->rel_line_to (-hwslider, double(-h/3)); + cr->rel_line_to (-hwslider, double(h/3)); + cr->rel_line_to (0., double(h/3)); + cr->close_path(); + // normal + c = style->get_bg (is_sensitive() ? Gtk::STATE_ACTIVE : Gtk::STATE_INSENSITIVE); + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + cr->fill_preserve (); + c = style->get_bg (state); + if (state==Gtk::STATE_INSENSITIVE) + cr->set_source_rgb (c.get_red_p()*0.85, c.get_green_p()*0.85, c.get_blue_p()*0.85); + else + cr->set_source_rgb (c.get_red_p()*0.7, c.get_green_p()*0.7, c.get_blue_p()*0.7); + cr->stroke (); + } + + // draw text for the slider that is being moved + Glib::RefPtr context = get_pango_context () ; + cr->set_line_width (0.5); + if (movingPosition >= 0) { + int i = movingPosition; + int offset; + int layout_width, layout_height; + Glib::RefPtr layout = create_pango_layout(Glib::ustring::format(std::setprecision(2), positions[i])); + layout->get_pixel_size(layout_width, layout_height); + offset = positions[i] > 0.5 ? -layout_width-1-hwslider : 1+hwslider; + c = style->get_bg (state); + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + + cr->set_line_width(3.); + cr->set_line_join(Cairo::LINE_JOIN_ROUND); + cr->set_line_cap(Cairo::LINE_CAP_ROUND); + + cr->move_to (leftMargin+w*positions[i]+offset, 0.); + layout->add_to_cairo_context (cr); + cr->stroke_preserve(); + c = style->get_fg (Gtk::STATE_PRELIGHT); + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + cr->fill (); + } + return true; +} + +bool SHCSelector::on_button_press_event (GdkEventButton* event) { + + // check if a slider is under the cursor + double w = double(get_width ()-leftMargin-rightMargin); + movingPosition = -1; + for (int i=0; i<3; i++) + if (event->x > double(leftMargin)+w*positions[i]-wslider/2. && event->x < double(leftMargin)+w*positions[i]+wslider/2) { + movingPosition = i; + tmpX = event->x; + tmpPos = positions[i]; + break; + } + queue_draw (); + return true; +} + +bool SHCSelector::on_button_release_event (GdkEventButton* event) { + + if (event->button == 1) { + if (movingPosition >= 0) { + movingPosition = -1; + queue_draw (); + } + } + else if (event->button == 3) { + if (movingPosition >= 0) + movingPosition = -1; + // right mouse button reset the selector to the stored default values + if (reset()) { + // rest has modified the values + if (cl) + cl->shcChanged (); + } + } + return true; +} + +bool SHCSelector::on_motion_notify_event (GdkEventMotion* event) { + + if (movingPosition >= 0) { + int w = get_width (); + positions[movingPosition] = tmpPos + (event->x - tmpX) / w; + if (positions[movingPosition] < 0) + positions[movingPosition] = 0.0; + if (movingPosition > 0 && positions[movingPosition] < positions[movingPosition-1]+wslider/w) + positions[movingPosition] = positions[movingPosition-1]+wslider/w; + if (positions[movingPosition] > 1.0) + positions[movingPosition] = 1.0; + if (movingPosition < 2 && positions[movingPosition] > positions[movingPosition+1]-wslider/w) + positions[movingPosition] = positions[movingPosition+1]-wslider/w; + + if (cl) + cl->shcChanged (); + queue_draw (); + } + return true; +} + +void SHCSelector::styleChanged (const Glib::RefPtr& style) { + + queue_draw (); +} + +bool SHCSelector::reset () { // : movingPosition(-1), cl(NULL) { + if ( positions[0] != defaults[0] || + positions[1] != defaults[1] || + positions[2] != defaults[2] + ) { + + positions[0] = defaults[0]; + positions[1] = defaults[1]; + positions[2] = defaults[2]; + queue_draw (); + return true; + } + return false; +} + +void SHCSelector::refresh() { + setDirty(true); + Glib::RefPtr win = get_window(); + if (win) + win->invalidate(true); +} diff --git a/rtgui/shcselector.h b/rtgui/shcselector.h new file mode 100644 index 000000000..7096d6d23 --- /dev/null +++ b/rtgui/shcselector.h @@ -0,0 +1,73 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _SHCSELECTOR_ +#define _SHCSELECTOR_ + +#include +#include "coloredbar.h" + +class SHCListener { + public: + virtual ~SHCListener() {} + virtual void shcChanged () {} +}; + +class SHCSelector : public Gtk::DrawingArea, public ColoredBar { + + protected: + + int movingPosition; + double tmpX, tmpPos; + + double defaults[3]; + double positions[3]; + double wslider; + + // left margin, essentially a workaround to take care of an eventual right colored bar (e.g. for curves) + int leftMargin; + // right margin, essentially a workaround to take care of an eventual right colored bar + int rightMargin; + + const static int hb = 3; // horizontal border + const static int vb = 2; // vertical border + + SHCListener* cl; + + public: + + SHCSelector(); + + void setSHCListener (SHCListener* l) { cl = l;; } + + void setMargins(int left, int right); + void setDefaults (double spos, double cpos, double hpos); + void setPositions (double spos, double cpos, double hpos); + void getPositions (double& spos, double& cpos, double& hpos); + void on_realize(); + bool on_expose_event(GdkEventExpose* event); + bool on_button_press_event (GdkEventButton* event); + bool on_button_release_event (GdkEventButton* event); + bool on_motion_notify_event (GdkEventMotion* event); + void styleChanged (const Glib::RefPtr& style); + bool reset (); + void refresh(); +}; + +#endif + diff --git a/rtgui/soundman.cc b/rtgui/soundman.cc new file mode 100644 index 000000000..07ff9986d --- /dev/null +++ b/rtgui/soundman.cc @@ -0,0 +1,71 @@ +/* +* This file is part of RawTherapee. +* +* Copyright (c) 2010 Oliver Duis +* +* 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 "soundman.h" +#include "options.h" + +#ifdef WIN32 +#include +#include +#endif + +#ifdef __linux__ +#include +#endif + + +void SoundManager::init() +{ +#ifdef WIN32 +// TODO: On Windows Vista/7 RT should register with the OS sound system, so it can enjoy application specific +// volume, safed, process independent etc. from the start. +// Function call is IAudioClient::Initialize +// Unfortunately MinGW does not support this yet. If audioclient.h is available, add an Init +// called once on program start. + // + // This mitigation plays an empty file on start, so RT is immidiately avaible in the Windows mixer at least + playSoundAsync(Glib::ustring("sounds\\Empty.wav")); +#endif +} + +// Plays a sound in async mode to not block the main thread +// param is either file name or name of the system event on Windows (e.g. "SystemAsterisk" or "SystemDefault"). +void SoundManager::playSoundAsync(const Glib::ustring &sound) +{ + if (sound.empty() || !options.sndEnable) return; + +#ifdef WIN32 + DWORD sndParam=SND_ASYNC | SND_NODEFAULT; + + if (sound.find('.')!=Glib::ustring::npos) { + // contain dot, so it's a filename + sndParam|=SND_FILENAME; + } else { + // no dot, so it's a system event + sndParam|=SND_ALIAS; + } + + wchar_t *wfilename = (wchar_t*)g_utf8_to_utf16 (sound.c_str(), -1, NULL, NULL, NULL); + PlaySoundW(wfilename, NULL, sndParam); + g_free( wfilename ); +#elif defined(__linux__) + ca_context_play(ca_gtk_context_get(), 0, CA_PROP_EVENT_ID, sound.c_str(), CA_PROP_MEDIA_FILENAME, sound.c_str(), NULL); +#endif +} diff --git a/rtgui/soundman.h b/rtgui/soundman.h new file mode 100644 index 000000000..d4cb48b33 --- /dev/null +++ b/rtgui/soundman.h @@ -0,0 +1,32 @@ +/* +* This file is part of RawTherapee. +* +* Copyright (c) 2010 Oliver Duis +* +* 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 _SOUNDMAN_ +#define _SOUNDMAN_ + +#include "../rtengine/safegtk.h" + +class SoundManager { +public: + static void init(); + static void playSoundAsync(const Glib::ustring &sound); +}; + +#endif diff --git a/rtgui/splash.cc b/rtgui/splash.cc new file mode 100644 index 000000000..c6473369d --- /dev/null +++ b/rtgui/splash.cc @@ -0,0 +1,267 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "splash.h" +#include "multilangmgr.h" +#include +#include "../rtengine/safegtk.h" + +extern Glib::ustring argv0; +extern Glib::ustring creditsPath; +extern Glib::ustring licensePath; +extern Glib::ustring versionString; +extern Glib::ustring versionSuffixString; + +SplashImage::SplashImage () { + + pixbuf = safe_create_from_file ("splash.png"); + set_size_request (pixbuf->get_width(), pixbuf->get_height()); +} + +void SplashImage::on_realize () { + + Gtk::DrawingArea::on_realize(); + add_events(Gdk::EXPOSURE_MASK); + + gc_ = Gdk::GC::create (get_window()); + Glib::RefPtr colormap = get_default_colormap(); + Gdk::Color fontc = Gdk::Color ("white"); + colormap->alloc_color (fontc); + gc_->set_foreground (fontc); + +} + +bool SplashImage::on_expose_event (GdkEventExpose* event) { + + Glib::RefPtr window = get_window(); + pixbuf->render_to_drawable (window, gc_, 0, 0, 0, 0, pixbuf->get_width(), pixbuf->get_height(), Gdk::RGB_DITHER_NONE, 0, 0); + + Cairo::FontOptions cfo; + cfo.set_antialias (Cairo::ANTIALIAS_SUBPIXEL); + Glib::RefPtr context = get_pango_context (); + context->set_cairo_font_options (cfo); + Pango::FontDescription fontd = context->get_font_description (); + fontd.set_weight (Pango::WEIGHT_LIGHT); + fontd.set_absolute_size (12*Pango::SCALE); + context->set_font_description (fontd); + Gdk::Color *textColor = new Gdk::Color(); + textColor->set_rgb(0, 0, 0); + gc_->set_foreground(*textColor); + + int w, h; + Glib::ustring versionStr(versionString); + if (!versionSuffixString.empty()) + versionStr += " "+versionSuffixString; + version = create_pango_layout (versionStr); + version->set_markup("" + versionStr + ""); + version->get_pixel_size (w, h); + window->draw_layout(gc_, pixbuf->get_width() - w - 32, pixbuf->get_height() - h - 20, version); + + return true; +} + +Splash::Splash (Gtk::Window& parent) : Gtk::Dialog(M("GENERAL_ABOUT"), parent, true) { + + set_border_width (4); + + releaseNotesSW = NULL; + + nb = Gtk::manage (new Gtk::Notebook ()); + get_vbox()->pack_start (*nb); + + // Add close button to bottom of the notebook + Gtk::Button* closeButton = Gtk::manage (new Gtk::Button (M("GENERAL_CLOSE"))); + closeButton->signal_clicked().connect( sigc::mem_fun(*this, &Splash::closePressed) ); + Gtk::HBox* bottomHBox = Gtk::manage (new Gtk::HBox ()); + bottomHBox->pack_end (*closeButton, Gtk::PACK_SHRINK, 0); + get_vbox()->pack_start (*bottomHBox, Gtk::PACK_SHRINK, 0); + + // Tab 1: the image + splashImage = Gtk::manage(new SplashImage ()); + nb->append_page (*splashImage, M("ABOUT_TAB_SPLASH")); + splashImage->show (); + + // Tab 2: the informations about the current version + std::string buildFileName = Glib::build_filename (creditsPath, "AboutThisBuild.txt"); + if ( safe_file_test(buildFileName, (Glib::FILE_TEST_EXISTS)) ) { + FILE *f = safe_g_fopen (buildFileName, "rt"); + if (f != NULL) { + char* buffer = new char[1024]; + std::ostringstream ostr; + while (fgets (buffer, 1024, f)) + ostr << buffer; + delete [] buffer; + fclose (f); + + Glib::RefPtr textBuffer = Gtk::TextBuffer::create(); + textBuffer->set_text((Glib::ustring)(ostr.str())); + + Gtk::ScrolledWindow *buildSW = Gtk::manage (new Gtk::ScrolledWindow()); + Gtk::TextView *buildTV = Gtk::manage (new Gtk::TextView (textBuffer)); + buildTV->set_editable(false); + buildTV->set_left_margin (10); + buildTV->set_right_margin (5); + buildSW->add(*buildTV); + nb->append_page (*buildSW, M("ABOUT_TAB_BUILD")); + } + } + + // Tab 3: the credits + std::string creditsFileName = Glib::build_filename (creditsPath, "AUTHORS.txt"); + if ( safe_file_test(creditsFileName, (Glib::FILE_TEST_EXISTS)) ) { + FILE *f = safe_g_fopen (creditsFileName, "rt"); + if (f != NULL) { + char* buffer = new char[1024]; + std::ostringstream ostr; + while (fgets (buffer, 1024, f)) + ostr << buffer; + delete [] buffer; + fclose (f); + + Glib::RefPtr textBuffer = Gtk::TextBuffer::create(); + textBuffer->set_text((Glib::ustring)(ostr.str())); + + Gtk::ScrolledWindow *creditsSW = Gtk::manage (new Gtk::ScrolledWindow()); + Gtk::TextView *creditsTV = Gtk::manage (new Gtk::TextView (textBuffer)); + creditsTV->set_left_margin (10); + creditsTV->set_right_margin (5); + creditsTV->set_wrap_mode(Gtk::WRAP_WORD); + creditsTV->set_editable(false); + creditsSW->add(*creditsTV); + nb->append_page (*creditsSW, M("ABOUT_TAB_CREDITS")); + } + } + + // Tab 4: the license + std::string licenseFileName = Glib::build_filename (licensePath, "LICENSE.txt"); + if ( safe_file_test(licenseFileName, (Glib::FILE_TEST_EXISTS)) ) { + FILE *f = safe_g_fopen (licenseFileName, "rt"); + if (f != NULL) { + char* buffer = new char[1024]; + std::ostringstream ostr; + while (fgets (buffer, 1024, f)) + ostr << buffer; + delete [] buffer; + fclose (f); + + Glib::RefPtr textBuffer = Gtk::TextBuffer::create(); + textBuffer->set_text((Glib::ustring)(ostr.str())); + + Gtk::ScrolledWindow *licenseSW = Gtk::manage (new Gtk::ScrolledWindow()); + Gtk::TextView *licenseTV = Gtk::manage (new Gtk::TextView (textBuffer)); + + // set monospace font to enhance readability of formatted text + Pango::FontDescription fdescLicense; + fdescLicense.set_family("monospace"); + fdescLicense.set_absolute_size (11*Pango::SCALE); + licenseTV->modify_font(fdescLicense); + + licenseTV->set_left_margin (10); + licenseTV->set_right_margin (5); + licenseTV->set_editable(false); + licenseSW->add(*licenseTV); + nb->append_page (*licenseSW, M("ABOUT_TAB_LICENSE")); + } + } + + // Tab 5: the Release Notes + std::string releaseNotesFileName = Glib::build_filename (creditsPath, "RELEASE_NOTES.txt"); + if ( safe_file_test(releaseNotesFileName, (Glib::FILE_TEST_EXISTS)) ) { + FILE *f = safe_g_fopen (releaseNotesFileName, "rt"); + if (f != NULL) { + char* buffer = new char[1024]; + std::ostringstream ostr; + while (fgets (buffer, 1024, f)) + ostr << buffer; + delete [] buffer; + fclose (f); + + Glib::RefPtr textBuffer = Gtk::TextBuffer::create(); + textBuffer->set_text((Glib::ustring)(ostr.str())); + + releaseNotesSW = Gtk::manage (new Gtk::ScrolledWindow()); + Gtk::TextView *releaseNotesTV = Gtk::manage (new Gtk::TextView (textBuffer)); + + // set monospace font to enhance readability of formatted text + Pango::FontDescription fdescReleaseNotes; + fdescReleaseNotes.set_family("monospace"); + fdescReleaseNotes.set_absolute_size (11*Pango::SCALE); + releaseNotesTV->modify_font(fdescReleaseNotes); + + + releaseNotesTV->set_left_margin (10); + releaseNotesTV->set_right_margin (3); + releaseNotesTV->set_editable(false); + releaseNotesTV->set_wrap_mode(Gtk::WRAP_WORD); + releaseNotesSW->add(*releaseNotesTV); + nb->append_page (*releaseNotesSW, M("ABOUT_TAB_RELEASENOTES")); + } + } + + + set_position (Gtk::WIN_POS_CENTER); + //add_events(Gdk::BUTTON_RELEASE_MASK); + set_resizable (true); + + nb->set_current_page (0); + + show_all_children (); + set_keep_above (true); +} + +Splash::Splash (Gtk::Window& parent, int maxtime) : Gtk::Dialog(M("GENERAL_ABOUT"), parent, true) { + + splashImage = Gtk::manage(new SplashImage ()); +// add (*splashImage); + get_vbox()->pack_start (*splashImage); + splashImage->show (); + + if (maxtime>0) + Glib::signal_timeout().connect (sigc::mem_fun(*this, &Splash::on_timer), maxtime); + set_position (Gtk::WIN_POS_CENTER); + if (maxtime>0) + set_decorated (false); + add_events(Gdk::BUTTON_RELEASE_MASK); + set_resizable (false); + + set_keep_above (true); +} + +bool Splash::on_timer () { + + hide (); + return false; +} + +/* + * removed as it seem to be too sensitive in some OS +bool Splash::on_button_release_event (GdkEventButton* event) { + + hide (); + return true; +} +*/ + +void Splash::showReleaseNotes() { + if (releaseNotesSW) + nb->set_current_page(nb->page_num(*releaseNotesSW)); +} + +void Splash::closePressed() { + hide(); +} diff --git a/rtgui/splash.h b/rtgui/splash.h new file mode 100644 index 000000000..8d54a58c4 --- /dev/null +++ b/rtgui/splash.h @@ -0,0 +1,56 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef __SPLASH__ +#define __SPLASH__ + +#include + +class SplashImage : public Gtk::DrawingArea { + + private: + Glib::RefPtr gc_; + Glib::RefPtr pixbuf; + Glib::RefPtr version; + + public: + SplashImage (); + void on_realize (); + bool on_expose_event (GdkEventExpose* event); +}; + +//class Splash : public Gtk::Window { +class Splash : public Gtk::Dialog { + + private: + SplashImage* splashImage; + Gtk::Notebook* nb; + Gtk::ScrolledWindow* releaseNotesSW; + + public: + Splash (Gtk::Window& parent, int maxtime); + Splash (Gtk::Window& parent); + + bool hasReleaseNotes() { return releaseNotesSW != NULL; }; + void showReleaseNotes(); + bool on_timer (); + //virtual bool on_button_release_event (GdkEventButton* event); + void closePressed(); +}; + +#endif diff --git a/rtgui/threadutils.h b/rtgui/threadutils.h new file mode 100644 index 000000000..81d2c9917 --- /dev/null +++ b/rtgui/threadutils.h @@ -0,0 +1,619 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ + + +#ifndef _THREADUTILS_ +#define _THREADUTILS_ + +#include +#include // for raise() +#include + +#ifdef WIN32 +#include +#endif + + +#ifdef NDEBUG + // We don't trace mutex + #undef TRACE_MYRWMUTEX + #define TRACE_MYRWMUTEX 0 +#endif + + +// Uncomment this if you want to bypass the CMakeList options and force the values +// Of course, DO NOT COMMIT! + +//#undef PROTECT_VECTORS +//#define PROTECT_VECTORS 1 +//#undef TRACE_MYRWMUTEX +//#define TRACE_MYRWMUTEX 1 +//#undef STRICT_MUTEX +//#define STRICT_MUTEX 1 + +/** + * @brief Custom Mutex to replace Glib::Threads::Mutex, which behave differently on windows (recursive) and linux (non-recursive), by a recursive and "debugable" one + * + * This implementation will behave like a Glib::Threads::RecMutex (STRICT_MUTEX=0) or a Glib::Threads::Mutex (STRICT_MUTEX=1), but in this case, the application will + * crash instead of freezing. + * + * In Debug builds, a printf will let you know that the MyMutex was already locked + * + * The default and recommended mode is STRICT_MUTEX=1 + */ + +#ifdef WIN32 +class MyMutex : public Glib::RecMutex { +#else +class MyMutex : public Glib::Threads::RecMutex { +#endif + +#if STRICT_MUTEX || !defined(NDEBUG) +private: + bool alreadyLocked; +#endif + +public: + class MyLock; + +#if STRICT_MUTEX || !defined(NDEBUG) + MyMutex() : alreadyLocked(false) {} +#else + MyMutex() {} +#endif + + void lock() { + #ifdef WIN32 + Glib::RecMutex::lock(); + #else + Glib::Threads::RecMutex::lock(); + #endif + #if STRICT_MUTEX || !defined(NDEBUG) + if (alreadyLocked) { + #ifndef NDEBUG + std::cout << "Warning: MyMutex already locked!" << std::endl; // breakpoint + #endif + #if STRICT_MUTEX + #ifndef NDEBUG + #ifdef WIN32 + DebugBreak(); + #else + raise(SIGTRAP); + #endif + #else + raise(SIGINT); + #endif + #endif + } + alreadyLocked = true; + #endif + } + + bool trylock() { + #ifdef WIN32 + if (Glib::RecMutex::trylock()) + #else + if (Glib::Threads::RecMutex::trylock()) + #endif + { + #if STRICT_MUTEX || !defined(NDEBUG) + if (alreadyLocked) { + #ifndef NDEBUG + std::cout << "Warning: MyMutex already locked!" << std::endl; // breakpoint + #endif + #if STRICT_MUTEX + #ifndef NDEBUG + #ifdef WIN32 + DebugBreak(); + #else + raise(SIGTRAP); + #endif + #else + raise(SIGINT); + #endif + #endif + } + alreadyLocked = true; + #endif + return true; + } + return false; + } + + // Warning: the base class of MyMutex is RecMutex, but the mutex is said "unlocked" on first occurrence of "unlock", to avoid overhead. + void unlock() { + #if STRICT_MUTEX || !defined(NDEBUG) + alreadyLocked = false; + #endif + #ifdef WIN32 + Glib::RecMutex::unlock(); + #else + Glib::Threads::RecMutex::unlock(); + #endif + } +}; + + +// Class copied from the Glibmm source code, to provide a workaround of the behavior's difference between Linux and Windows +class MyMutex::MyLock { +public: + explicit inline MyLock(MyMutex& mutex) : mutex_ (mutex), locked_ (true) { mutex_.lock(); } +#ifdef WIN32 + inline MyLock(MyMutex& mutex, Glib::NotLock) : mutex_ (mutex), locked_ (false) {} + inline MyLock(MyMutex& mutex, Glib::TryLock) : mutex_ (mutex), locked_ (mutex.trylock()) {} +#else + inline MyLock(MyMutex& mutex, Glib::Threads::NotLock) : mutex_ (mutex), locked_ (false) {} + inline MyLock(MyMutex& mutex, Glib::Threads::TryLock) : mutex_ (mutex), locked_ (mutex.trylock()) {} +#endif + inline ~MyLock() { if(locked_) mutex_.unlock(); } + + inline void acquire() { mutex_.lock(); locked_ = true; } + inline bool try_acquire() { locked_ = mutex_.trylock(); return locked_; } + inline void release() { mutex_.unlock(); locked_ = false; } + inline bool locked() const { return locked_; } + +private: + MyMutex& mutex_; + bool locked_; + + // noncopyable + MyLock(const MyMutex::Lock&); + MyMutex::Lock& operator=(const MyMutex::Lock&); +}; + + +/** + * @brief Custom RWLock with debugging feature, to replace the buggy Glib::RWLock (can have negative reader_count value!) + * + * It may be slower, but thread safe! + */ +class MyRWMutex { +public: +#ifdef WIN32 + Glib::Mutex handlerMutex; // Having a recursive or non-recursive mutex is not important here, so we can use Glib::Mutex + Glib::Cond access; +#else + Glib::Threads::Mutex handlerMutex; // Having a recursive or non-recursive mutex is not important here, so we can use Glib::Threads::Mutex + Glib::Threads::Cond access; +#endif + size_t writerCount; + size_t readerCount; +#if TRACE_MYRWMUTEX + Glib::ustring lastWriterFile; + int lastWriterLine; + // Unfortunately, ownerThread may not be the culprit of a deadlock, it can be another concurrent Reader... + void* ownerThread; + + MyRWMutex() : writerCount(0), readerCount(0), lastWriterLine(0), ownerThread(NULL) {} +#else + MyRWMutex() : writerCount(0), readerCount(0) {} +#endif +}; + +/** + * @brief Custom ReaderLock with debugging feature, to replace the buggy Glib::RWLock (can have negative reader_count value!) + * + */ +class MyReaderLock { + + MyRWMutex& rwMutex; + bool locked; + + #if TRACE_MYRWMUTEX + static unsigned int readerLockCounter; + int locknumber; + +public: + inline MyReaderLock(MyRWMutex& mutex, const char* name, const char* file, const int line) : rwMutex(mutex), locked(false), locknumber(0) + #else +public: + inline MyReaderLock(MyRWMutex& mutex) : rwMutex(mutex) + #endif + + { + // to operate safely + rwMutex.handlerMutex.lock(); + + #if TRACE_MYRWMUTEX + locknumber = readerLockCounter++; + void* thread = Glib::Thread::self(); + std::cout << thread << "/" << locknumber << ":" << name << " / " << file << " : " << line << " - locking - R"; + #endif + + if (!rwMutex.writerCount) { + // There's no writer operating, we can increment the writer count which will lock writers + ++rwMutex.writerCount; + #if TRACE_MYRWMUTEX + std::cout << " ++ new owner"; + #endif + } + else { + // The writer count is non null, but we can be the owner of the writer lock + // It will be the case if the reader count is non null too. + if (!rwMutex.readerCount) { + // the mutex is in real write mode, we're waiting to see it null + #if TRACE_MYRWMUTEX + std::cout << " waiting..." << std::endl << "Current writer owner: " << rwMutex.lastWriterFile << " : " << rwMutex.lastWriterLine << std::endl; + #endif + while (rwMutex.writerCount) + rwMutex.access.wait(rwMutex.handlerMutex); + ++rwMutex.writerCount; + #if TRACE_MYRWMUTEX + rwMutex.lastWriterFile = file; + rwMutex.lastWriterLine = line; + rwMutex.ownerThread = thread; + std::cout << thread << "/" << locknumber << ":" << name << " / " << file << " : " << line << " - locking - R ++ new owner"; + #endif + } + } + // then we can increment the reader count + ++rwMutex.readerCount; + + #if TRACE_MYRWMUTEX + std::cout << " - ReaderCount: " << rwMutex.readerCount << " - WriterCount: " << rwMutex.writerCount << std::endl; + #endif + + rwMutex.handlerMutex.unlock(); + + locked = true; + } + #if TRACE_MYRWMUTEX + // locks the MyRWMutex with Read access if this MyReaderLock has not already locked it, otherwise return safely + inline void acquire(const char* file, const int line) + #else + // locks the MyRWMutex with Read access if this MyReaderLock has not already locked it, otherwise return safely + inline void acquire() + #endif + { + #if TRACE_MYRWMUTEX + void* thread = Glib::Thread::self(); + #endif + if (!locked) { + // to operate safely + rwMutex.handlerMutex.lock(); + + #if TRACE_MYRWMUTEX + std::cout << thread << "/" << locknumber << ":" << file << " : " << line << " - locking - R (lock)"; + #endif + + if (!rwMutex.writerCount) { + // There's no writer operating, we can increment the writer count which will lock writers + ++rwMutex.writerCount; + #if TRACE_MYRWMUTEX + std::cout << " ++ new owner"; + #endif + } + else { + // The writer count is non null, but a reader can be the owner of the writer lock, + // it will be the case if the reader count is non null too. + if (!rwMutex.readerCount) { + // the mutex is in real write mode, we're waiting to see it null + #if TRACE_MYRWMUTEX + std::cout << " waiting..." << std::endl << "Current writer owner: " << rwMutex.lastWriterFile << " : " << rwMutex.lastWriterLine << std::endl; + #endif + while (rwMutex.writerCount) + rwMutex.access.wait(rwMutex.handlerMutex); + ++rwMutex.writerCount; + #if TRACE_MYRWMUTEX + rwMutex.lastWriterFile = file; + rwMutex.lastWriterLine = line; + rwMutex.ownerThread = thread; + std::cout << thread << "/" << locknumber << ":" << file << " : " << line << " - locking - R (lock) ++ new owner"; + #endif + } + } + // then we can increment the reader count + ++rwMutex.readerCount; + + #if TRACE_MYRWMUTEX + std::cout << " - ReaderCount: " << rwMutex.readerCount << " - WriterCount: " << rwMutex.writerCount << std::endl; + #endif + + rwMutex.handlerMutex.unlock(); + + locked = true; + } + #if TRACE_MYRWMUTEX + else std::cout << thread << "/" << locknumber << " / already locked by this object - R (lock)" << std::endl; + #endif + } + inline ~MyReaderLock() { + #if TRACE_MYRWMUTEX + void* thread = Glib::Thread::self(); + #endif + if (locked) { + // to operate safely + rwMutex.handlerMutex.lock(); + + // decrement the writer number first + --rwMutex.readerCount; + + #if TRACE_MYRWMUTEX + std::cout << thread << "/" << locknumber << " / unlocking - R - ReaderCount: " << rwMutex.readerCount; + #endif + + if (!rwMutex.readerCount) { + // no more reader, so we decrement the writer count + --rwMutex.writerCount; + #if TRACE_MYRWMUTEX + rwMutex.lastWriterFile = ""; + rwMutex.lastWriterLine = 0; + rwMutex.ownerThread = NULL; + std::cout << " -- new owner possible!" << " >>> ReaderCount: " << rwMutex.readerCount << " - WriterCount: " << rwMutex.writerCount; + #endif + // and signal the next waiting reader/writer that it's free + rwMutex.access.broadcast(); + } + #if TRACE_MYRWMUTEX + std::cout << std::endl; + #endif + + rwMutex.handlerMutex.unlock(); + } + #if TRACE_MYRWMUTEX + else std::cout << thread << "/" << locknumber << " / already unlocked by this object - R" << std::endl; + #endif + } + #if TRACE_MYRWMUTEX + // releases the MyRWMutex with Write access if this MyWriterLock has already locked it, otherwise return safely + inline void release(const char* file, const int line) + #else + // releases the MyRWMutex with Write access if this MyWriterLock has already locked it, otherwise return safely + inline void release() + #endif + { + #if TRACE_MYRWMUTEX + void* thread = Glib::Thread::self(); + #endif + if (locked) { + // to operate safely + rwMutex.handlerMutex.lock(); + + // decrement the writer number first + --rwMutex.readerCount; + + #if TRACE_MYRWMUTEX + std::cout << thread << "/" << locknumber << " / unlocking - R (release) - ReaderCount: " << rwMutex.readerCount; + #endif + + if (!rwMutex.readerCount) { + // no more reader, so we decrement the writer count + --rwMutex.writerCount; + #if TRACE_MYRWMUTEX + rwMutex.lastWriterFile = ""; + rwMutex.lastWriterLine = 0; + rwMutex.ownerThread = NULL; + std::cout << " -- new owner possible!" << " >>> ReaderCount: " << rwMutex.readerCount << " - WriterCount: " << rwMutex.writerCount; + #endif + // and signal the next waiting reader/writer that it's free + rwMutex.access.broadcast(); + } + #if TRACE_MYRWMUTEX + std::cout << std::endl; + #endif + + rwMutex.handlerMutex.unlock(); + + locked = false; + } + #if TRACE_MYRWMUTEX + else std::cout << thread << "/" << locknumber << " / already unlocked - R (release)" << std::endl; + #endif + } +}; + +/** + * @brief Custom WriterLock with debugging feature, to replace the buggy Glib::RWLock (can have negative reader_count value!) + * + */ +class MyWriterLock { + + MyRWMutex& rwMutex; + bool locked; + + #if TRACE_MYRWMUTEX + static unsigned int writerLockCounter; + int locknumber; +public: + inline MyWriterLock(MyRWMutex& mutex, const char* name, const char* file, const int line) : rwMutex(mutex), locked(false), locknumber(0) + #else +public: + inline MyWriterLock(MyRWMutex& mutex) : rwMutex(mutex) + #endif + { + // to operate safely + rwMutex.handlerMutex.lock(); + + #if TRACE_MYRWMUTEX + locknumber = writerLockCounter++; + void* thread = Glib::Thread::self(); + std::cout << thread << "/" << locknumber << ":" << name << " / " << file << " : " << line << " - locking - W"; + #endif + + if (rwMutex.writerCount) { + // The writer count is non null, so we have to wait for it to be null again + #if TRACE_MYRWMUTEX + std::cout << " waiting..." << std::endl << "Current writer owner: " << rwMutex.lastWriterFile << " : " << rwMutex.lastWriterLine << std::endl; + #endif + while (rwMutex.writerCount) + rwMutex.access.wait(rwMutex.handlerMutex); + #if TRACE_MYRWMUTEX + std::cout << thread << "/" << locknumber << ":" << file << " : " << line << " - locking - W"; + #endif + } + // then we can increment the writer count + ++rwMutex.writerCount; + + #if TRACE_MYRWMUTEX + rwMutex.lastWriterFile = file; + rwMutex.lastWriterLine = line; + rwMutex.ownerThread = thread; + std::cout << " ++ new owner <<< ReaderCount: " << rwMutex.readerCount << " - WriterCount: " << rwMutex.writerCount << std::endl; + #endif + + rwMutex.handlerMutex.unlock(); + + locked = true; + } + #if TRACE_MYRWMUTEX + // locks the MyRWMutex with Read access if this MyReaderLock has not already locked it, otherwise return safely + inline void acquire(const char* file, const int line) + #else + // locks the MyRWMutex with Read access if this MyReaderLock has not already locked it, otherwise return safely + inline void acquire() + #endif + { + #if TRACE_MYRWMUTEX + void* thread = Glib::Thread::self(); + #endif + if (!locked) { + // to operate safely + rwMutex.handlerMutex.lock(); + + #if TRACE_MYRWMUTEX + std::cout << thread << "/" << locknumber << ":" << file << " : " << line << " - locking - W (lock)"; + #endif + + if (rwMutex.writerCount) { + // The writer count is non null, so we have to wait for it to be null again + #if TRACE_MYRWMUTEX + std::cout << " waiting..." << std::endl << "Current writer owner: " << rwMutex.lastWriterFile << " : " << rwMutex.lastWriterLine << std::endl; + #endif + while (rwMutex.writerCount) + rwMutex.access.wait(rwMutex.handlerMutex); + #if TRACE_MYRWMUTEX + std::cout << thread << "/" << locknumber << ":" << file << " : " << line << " - locking - W (lock)"; + #endif + } + // then we can increment the reader count + ++rwMutex.writerCount; + + #if TRACE_MYRWMUTEX + rwMutex.lastWriterFile = file; + rwMutex.lastWriterLine = line; + rwMutex.ownerThread = thread; + std::cout << " ++ new owner <<< ReaderCount: " << rwMutex.readerCount << " - WriterCount: " << rwMutex.writerCount << std::endl; + #endif + + rwMutex.handlerMutex.unlock(); + + locked = true; + } + #if TRACE_MYRWMUTEX + else std::cout << thread << "/" << locknumber << " / already locked by this object - W (lock)" << std::endl; + #endif + } + inline ~MyWriterLock() { + #if TRACE_MYRWMUTEX + void* thread = Glib::Thread::self(); + #endif + if (locked) { + // to operate safely + rwMutex.handlerMutex.lock(); + + // decrement the writer number first + --rwMutex.writerCount; + + #if TRACE_MYRWMUTEX + std::cout << thread << "/" << locknumber << " / unlocking - W"; + #endif + + if (!rwMutex.writerCount) { + #if TRACE_MYRWMUTEX + rwMutex.lastWriterFile = ""; + rwMutex.lastWriterLine = 0; + rwMutex.ownerThread = NULL; + std::cout << " -- new owner possible!"; + #endif + // The writer count is null again, so we can wake up the next writer or reader + rwMutex.access.broadcast(); + } + #if TRACE_MYRWMUTEX + std::cout << " <<< ReaderCount: " << rwMutex.readerCount << " - WriterCount: " << rwMutex.writerCount << std::endl; + #endif + + rwMutex.handlerMutex.unlock(); + } + #if TRACE_MYRWMUTEX + else std::cout << thread << "/" << locknumber << " / already unlocked by this object - W" << std::endl; + #endif + } + #if TRACE_MYRWMUTEX + // releases the MyRWMutex with Write access if this MyWriterLock has already locked it, otherwise return safely + inline void release(const char* file, const int line) + #else + // releases the MyRWMutex with Write access if this MyWriterLock has already locked it, otherwise return safely + inline void release() + #endif + { + #if TRACE_MYRWMUTEX + void* thread = Glib::Thread::self(); + #endif + if (locked) { + // to operate safely + rwMutex.handlerMutex.lock(); + + // decrement the writer number first + --rwMutex.writerCount; + + #if TRACE_MYRWMUTEX + std::cout << thread << "/" << locknumber << " / unlocking - W (release)"; + #endif + + if (!rwMutex.writerCount) { + #if TRACE_MYRWMUTEX + rwMutex.lastWriterFile = ""; + rwMutex.lastWriterLine = 0; + rwMutex.ownerThread = NULL; + std::cout << " -- new owner possible!"; + #endif + // The writer count is null again, so we can wake up the next writer or reader + rwMutex.access.broadcast(); + } + #if TRACE_MYRWMUTEX + std::cout << " <<< ReaderCount: " << rwMutex.readerCount << " - WriterCount: " << rwMutex.writerCount << std::endl; + #endif + + rwMutex.handlerMutex.unlock(); + + locked = false; + } + #if TRACE_MYRWMUTEX + else std::cout << thread << "/" << locknumber << " / already unlocked by this object - W (release)" << std::endl; + #endif + } +}; + +#if TRACE_MYRWMUTEX +#define MYREADERLOCK(ln, e) MyReaderLock ln(e, #e, __FILE__, __LINE__); +#define MYWRITERLOCK(ln, e) MyWriterLock ln(e, #e, __FILE__, __LINE__); +#define MYREADERLOCK_ACQUIRE(ln) ln.acquire(__FILE__, __LINE__); +#define MYWRITERLOCK_ACQUIRE(ln) ln.acquire(__FILE__, __LINE__); +#define MYREADERLOCK_RELEASE(ln) ln.release(__FILE__, __LINE__); +#define MYWRITERLOCK_RELEASE(ln) ln.release(__FILE__, __LINE__); +#else +#define MYREADERLOCK(ln, e) MyReaderLock ln(e); +#define MYWRITERLOCK(ln, e) MyWriterLock ln(e); +#define MYREADERLOCK_ACQUIRE(ln) ln.acquire(); +#define MYWRITERLOCK_ACQUIRE(ln) ln.acquire(); +#define MYREADERLOCK_RELEASE(ln) ln.release(); +#define MYWRITERLOCK_RELEASE(ln) ln.release(); +#endif + +#endif /* _THREADUTILS_ */ diff --git a/rtgui/thresholdadjuster.cc b/rtgui/thresholdadjuster.cc new file mode 100644 index 000000000..bf99a631c --- /dev/null +++ b/rtgui/thresholdadjuster.cc @@ -0,0 +1,348 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "thresholdadjuster.h" +#include +#include +#include "multilangmgr.h" +#include "../rtengine/rtengine.h" +#include "options.h" +#include "guiutils.h" +#include "rtimage.h" + +#define MIN_RESET_BUTTON_HEIGHT 17 + +ThresholdAdjuster::ThresholdAdjuster (Glib::ustring label, + double minValueBottom, double maxValueBottom, double defBottom, Glib::ustring labelBottom, unsigned int precisionBottom, + double minValueTop, double maxValueTop, double defTop, Glib::ustring labelTop, unsigned int precisionTop, + ThresholdCurveProvider* curveProvider, bool editedCheckBox) + : tSelector(minValueBottom, maxValueBottom, defBottom, labelBottom, precisionBottom, minValueTop, maxValueTop, defTop, labelTop, precisionTop, curveProvider) + +{ + initialDefaultVal[ThresholdSelector::TS_BOTTOMLEFT] = defBottom; + initialDefaultVal[ThresholdSelector::TS_TOPLEFT] = defTop; + initialDefaultVal[ThresholdSelector::TS_BOTTOMRIGHT] = 0.; // unused + initialDefaultVal[ThresholdSelector::TS_TOPRIGHT] = 0.; // unused + + initObject (label, editedCheckBox); +} + +ThresholdAdjuster::ThresholdAdjuster (Glib::ustring label, double minValue, double maxValue, double defBottom, + double defTop, unsigned int precision, bool startAtOne, bool editedCheckBox) + : tSelector(minValue, maxValue, defBottom, defTop, precision, startAtOne) +{ + initialDefaultVal[ThresholdSelector::TS_BOTTOMLEFT] = defBottom; + initialDefaultVal[ThresholdSelector::TS_TOPLEFT] = defTop; + initialDefaultVal[ThresholdSelector::TS_BOTTOMRIGHT] = maxValue; + initialDefaultVal[ThresholdSelector::TS_TOPRIGHT] = maxValue; + + initObject (label, editedCheckBox); +} + +ThresholdAdjuster::ThresholdAdjuster (Glib::ustring label, double minValue, double maxValue, + double defBottomLeft, double defTopLeft, double defBottomRight, double defTopRight, + unsigned int precision, bool startAtOne, bool editedCheckBox) + : tSelector(minValue, maxValue, defBottomLeft, defTopLeft, + defBottomRight, defTopRight, precision, startAtOne) +{ + initialDefaultVal[ThresholdSelector::TS_BOTTOMLEFT] = defBottomLeft; + initialDefaultVal[ThresholdSelector::TS_TOPLEFT] = defTopLeft; + initialDefaultVal[ThresholdSelector::TS_BOTTOMRIGHT] = defBottomRight; + initialDefaultVal[ThresholdSelector::TS_TOPRIGHT] = defTopRight; + + initObject (label, editedCheckBox); +} + +void ThresholdAdjuster::initObject (Glib::ustring label, bool editedcb) { + + adjusterListener = NULL; + afterReset = false; + blocked = false; + + addMode = false; + + // TODO: let the user chose the default value of ThresholdAdjuster::delay, for slow machines + delay = options.adjusterDelay; // delay is no more static, so we can set the delay individually (useful for the RAW editor tab) + + set_name("ThresholdAdjuster"); + + hbox = Gtk::manage (new Gtk::HBox ()); + + this->label = Gtk::manage (new Gtk::Label (label, Gtk::ALIGN_LEFT)); + + if (editedcb) { + editedCheckBox = Gtk::manage (new Gtk::CheckButton ()); + editedChange = editedCheckBox->signal_toggled().connect( sigc::mem_fun(*this, &ThresholdAdjuster::editedToggled) ); + hbox->pack_start (*editedCheckBox); + } + else + editedCheckBox = NULL; + + hbox->pack_start (*this->label); + + reset = Gtk::manage (new Gtk::Button ()); + reset->add (*Gtk::manage (new RTImage ("gtk-undo-ltr-small.png", "gtk-undo-rtl-small.png"))); + reset->set_relief (Gtk::RELIEF_NONE); + reset->set_border_width (0); + reset->set_tooltip_text (M("ADJUSTER_RESET_TO_DEFAULT")); + + hbox->pack_end (*reset, Gtk::PACK_SHRINK, 0); + + reset->set_size_request (-1, this->label->get_height() > MIN_RESET_BUTTON_HEIGHT ? this->label->get_height(): MIN_RESET_BUTTON_HEIGHT); + + pack_start (*hbox, false, false); + pack_start (tSelector, false, false); + + editedState = defEditedState = Irrelevant; + + selectorChange = tSelector.signal_value_changed().connect( sigc::mem_fun(*this, &ThresholdAdjuster::selectorChanged) ); + reset->signal_button_release_event().connect_notify( sigc::mem_fun(*this, &ThresholdAdjuster::resetPressed) ); + + show_all (); +} + +ThresholdAdjuster::~ThresholdAdjuster () { + + selectorChange.disconnect(); + delayConnection.block(true); + adjusterListener = NULL; +} + +void ThresholdAdjuster::setDefault (double bottom, double top) { + + selectorChange.block (true); + tSelector.setPositions(shapeValue(bottom), shapeValue(top)); + selectorChange.block (false); +} + +void ThresholdAdjuster::setDefault (double bottomLeft, double topLeft, double bottomRight, double topRight) { + + selectorChange.block (true); + tSelector.setPositions(shapeValue(bottomLeft), shapeValue(topLeft), shapeValue(bottomRight), shapeValue(topRight)); + selectorChange.block (false); +} + +void ThresholdAdjuster::setDefaultEditedState (EditedState eState) { + + defEditedState = eState; +} + +void ThresholdAdjuster::resetPressed (GdkEventButton* event) { + + if (editedState!=Irrelevant) { + editedState = defEditedState; + if (editedCheckBox) { + editedChange.block (true); + editedCheckBox->set_active (defEditedState==Edited); + editedChange.block (false); + } + refreshLabelStyle (); + } + afterReset = true; + if ((event != NULL) && (event->state & GDK_CONTROL_MASK) && (event->button == 1)) + // CTRL pressed : resetting to current default value + tSelector.reset(); + else + // no modifier key or addMode=true : resetting to initial default value + tSelector.setPositions(initialDefaultVal[ThresholdSelector::TS_BOTTOMLEFT], + initialDefaultVal[ThresholdSelector::TS_TOPLEFT], + initialDefaultVal[ThresholdSelector::TS_BOTTOMRIGHT], + initialDefaultVal[ThresholdSelector::TS_TOPRIGHT]); +} + +double ThresholdAdjuster::shapeValue (double a) { + + unsigned int digit = tSelector.getPrecision(); + return round(a*pow(double(10), digit)) / pow(double(10), digit); +} + +void ThresholdAdjuster::selectorChanged () { + + if (delayConnection.connected()) + delayConnection.disconnect (); + + if (delay==0) { + if (adjusterListener && !blocked) + sendToListener (); + } + else + delayConnection = Glib::signal_timeout().connect (sigc::mem_fun(*this, &ThresholdAdjuster::notifyListener), delay); + + if (!afterReset && editedState==UnEdited) { + editedState = Edited; + if (editedCheckBox) { + editedChange.block (true); + editedCheckBox->set_active (true); + editedChange.block (false); + } + refreshLabelStyle (); + } + afterReset = false; +} + +void ThresholdAdjuster::setValue (double bottom, double top) { + + selectorChange.block (true); + tSelector.setPositions(bottom, top); + selectorChange.block (false); + afterReset = false; +} + +void ThresholdAdjuster::setValue (double bottomLeft, double topLeft, double bottomRight, double topRight) { + + selectorChange.block (true); + tSelector.setPositions(bottomLeft, topLeft, bottomRight, topRight); + selectorChange.block (false); + afterReset = false; +} + +void ThresholdAdjuster::getValue (double& bottom, double& top) { + tSelector.getPositions (bottom, top); +} +void ThresholdAdjuster::getValue (double& bottomLeft, double& topLeft, double& bottomRight, double& topRight) { + tSelector.getPositions (bottomLeft, topLeft, bottomRight, topRight); +} +void ThresholdAdjuster::getValue (int& bottom, int& top) { + tSelector.getPositions (bottom, top); +} +void ThresholdAdjuster::getValue (int& bottomLeft, int& topLeft, int& bottomRight, int& topRight) { + tSelector.getPositions (bottomLeft, topLeft, bottomRight, topRight); +} + +void ThresholdAdjuster::getValue (Glib::ustring& bottom, Glib::ustring& top) { + tSelector.getPositions (bottom, top); +} + +void ThresholdAdjuster::getValue (Glib::ustring& bottomLeft, Glib::ustring& topLeft, Glib::ustring& bottomRight, Glib::ustring& topRight) { + tSelector.getPositions (bottomLeft, topLeft, bottomRight, topRight); +} + +bool ThresholdAdjuster::notifyListener () { + + if (adjusterListener!=NULL && !blocked) { + GThreadLock lock; + sendToListener(); + } + return false; +} + +void ThresholdAdjuster::setBgCurveProvider (ThresholdCurveProvider* provider) { + tSelector.setBgCurveProvider(provider); +} + + +void ThresholdAdjuster::setEnabled (bool enabled) { + + tSelector.set_sensitive (enabled); +} + +void ThresholdAdjuster::setEditedState (EditedState eState) { + + if (editedState!=eState) { + if (editedCheckBox) { + editedChange.block (true); + editedCheckBox->set_active (eState==Edited); + editedChange.block (false); + } + editedState = eState; + refreshLabelStyle (); + } +} + +EditedState ThresholdAdjuster::getEditedState () { + + if (editedState!=Irrelevant && editedCheckBox) + editedState = editedCheckBox->get_active () ? Edited : UnEdited; + return editedState; +} + +void ThresholdAdjuster::showEditedCB () { + + if (!editedCheckBox) { + editedCheckBox = Gtk::manage(new Gtk::CheckButton ()); + hbox->pack_start (*editedCheckBox, Gtk::PACK_SHRINK, 2); + hbox->reorder_child (*editedCheckBox, 0); + editedChange = editedCheckBox->signal_toggled().connect( sigc::mem_fun(*this, &ThresholdAdjuster::editedToggled) ); + } +} + +void ThresholdAdjuster::refreshLabelStyle () { + +/* Glib::RefPtr style = label->get_style (); + Pango::FontDescription fd = style->get_font (); + fd.set_weight (editedState==Edited ? Pango::WEIGHT_BOLD : Pango::WEIGHT_NORMAL); + style->set_font (fd); + label->set_style (style); + label->queue_draw ();*/ +} + +void ThresholdAdjuster::editedToggled () { + + if (adjusterListener && !blocked) + sendToListener (); +} + +void ThresholdAdjuster::sendToListener () { + if (tSelector.getPrecision() > 0) { + // if precision is >0, then we assume that the listener is waiting for doubles + rtengine::procparams::Threshold t = tSelector.getPositions(); + if (tSelector.isDouble()){ + adjusterListener->adjusterChanged (this, t.value[0], t.value[1], t.value[2], t.value[3]); + adjusterListener->adjusterChanged2 (this, t.value[0], t.value[1], t.value[2], t.value[3]); + } + else + adjusterListener->adjusterChanged (this, t.value[0], t.value[1]); + } + else { + // if precision is equal to 0, then we assume that the listener is waiting for integers + rtengine::procparams::Threshold t = tSelector.getPositions(); + if (tSelector.isDouble()){ + adjusterListener->adjusterChanged (this, t.value[0], t.value[1], t.value[2], t.value[3]); + adjusterListener->adjusterChanged2 (this, t.value[0], t.value[1], t.value[2], t.value[3]); + } + else + adjusterListener->adjusterChanged (this, t.value[0], t.value[1]); + } +} + +void ThresholdAdjuster::set_tooltip_markup(const Glib::ustring& markup) { + tSelector.set_tooltip_markup(markup); +} + +void ThresholdAdjuster::set_tooltip_text(const Glib::ustring& text) { + tSelector.set_tooltip_text(text); +} + +/* For better readability, this method create the history string of the parameter column, + * so that the parameters list can be read in a more logical way (i.e. corresponding + * to the startAtOne field) + * + * If separatedMode==true, the top slider is assumed to be the primary slider, then the bottom slider as the second one + */ +Glib::ustring ThresholdAdjuster::getHistoryString () { + if (tSelector.isDouble()) { + Glib::ustring bl, tl, br, tr; + tSelector.getPositions(bl, tl, br, tr); + return Glib::ustring::compose(tSelector.isStartAtOne()?"%2, %1, %3, %4":"%1, %2, %4, %3", bl, tl, br, tr); + } + else { + Glib::ustring b, t; + tSelector.getPositions(b, t); + return Glib::ustring::compose(tSelector.isStartAtOne()||separatedMode?"%2, %1":"%1, %2", b, t); + } +} diff --git a/rtgui/thresholdadjuster.h b/rtgui/thresholdadjuster.h new file mode 100644 index 000000000..3967223f1 --- /dev/null +++ b/rtgui/thresholdadjuster.h @@ -0,0 +1,137 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _THRESHOLDADJUSTER_H_ +#define _THRESHOLDADJUSTER_H_ + +#include +#include "editedstate.h" +#include "guiutils.h" +#include "thresholdselector.h" + +class ThresholdAdjuster; + +/* + * TODO: Maybe we could just send back the history string instead of the individual values? + */ +class ThresholdAdjusterListener { + + public: + // to be used by listener that has created a ThresholdAdjuster with with single threshold and precision > 0 + virtual void adjusterChanged (ThresholdAdjuster* a, double newBottom, double newTop) {} + // to be used by listener that has created a ThresholdAdjuster with with double threshold and precision > 0 + virtual void adjusterChanged (ThresholdAdjuster* a, double newBottomLeft, double newTopLeft, double newBottomRight, double newTopRight) {} + // to be used by listener that has created a ThresholdAdjuster with with single threshold and precision == 0 + virtual void adjusterChanged (ThresholdAdjuster* a, int newBottom, int newTop) {} + // to be used by listener that has created a ThresholdAdjuster with with double threshold and precision == 0 + virtual void adjusterChanged (ThresholdAdjuster* a, int newBottomLeft, int newTopLeft, int newBottomRight, int newTopRight) {} + virtual void adjusterChanged2 (ThresholdAdjuster* a, int newBottomL, int newTopL, int newBottomR, int newTopR) {} +}; + + +class ThresholdAdjuster : public Gtk::VBox { + + protected: + Gtk::HBox* hbox; + Gtk::Label* label; + ThresholdSelector tSelector; + //MySpinButton* spin; + Gtk::Button* reset; + ThresholdAdjusterListener* adjusterListener; + sigc::connection delayConnection; + //sigc::connection spinChange; + sigc::connection selectorChange; + sigc::connection editedChange; + bool listenerReady; + double initialDefaultVal[4]; // default value at construction time + EditedState editedState; + EditedState defEditedState; + Gtk::CheckButton* editedCheckBox; + bool afterReset; + bool blocked; + bool addMode; + bool separatedMode; + int delay; + + double shapeValue (double a); + void refreshLabelStyle (); + void initObject (Glib::ustring label, bool editedcb); + void sendToListener (); + + public: + + // Custom Threshold widget with 2 cursors (Top and Bottom) and a custom curve provided by the instanciator, + // each cursor having his own range, default value and precision + ThresholdAdjuster (Glib::ustring label, + double minValueBottom, double maxValueBottom, double defBottom, Glib::ustring labelBottom, unsigned int precisionBottom, + double minValueTop, double maxValueTop, double defTop, Glib::ustring labelTop, unsigned int precisionTop, + ThresholdCurveProvider* curveProvider, bool editedCheckBox=false); + // Simple Threshold widget with 2 linked sliders (0->1 or 1->0) + ThresholdAdjuster (Glib::ustring label, double minValue, double maxValue, double defBottom, + double defTop, unsigned int precision, bool startAtOne, bool editedCheckBox=false); + // Simple Threshold widget with 4 linked sliders by pairs (0->1->0 or 1->0->1) + ThresholdAdjuster (Glib::ustring label, double minValue, double maxValue, double defBottomLeft, + double defTopLeft, double defBottomRight, double defTopRight, unsigned int precision, + bool startAtOne, bool editedCheckBox=false); + + virtual ~ThresholdAdjuster (); + void setAdjusterListener (ThresholdAdjusterListener* alistener) { adjusterListener = alistener; } + + void setBgCurveProvider (ThresholdCurveProvider* provider); + ThresholdSelector* getThresholdSelector() { return &tSelector; }; + + template + rtengine::procparams::Threshold getValue () { + return tSelector.getPositions(); + } + void getValue (double& bottom, double& top); + void getValue (double& bottomLeft, double& topLeft, double& bottomRight, double& topRight); + void getValue (int& bottom, int& top); + void getValue (int& bottomLeft, int& topLeft, int& bottomRight, int& topRight); + void getValue (Glib::ustring& bottom, Glib::ustring& top); + void getValue (Glib::ustring& bottomLeft, Glib::ustring& topLeft, Glib::ustring& bottomRight, Glib::ustring& topRight); + template + void setValue (const rtengine::procparams::Threshold &tValues) { tSelector.setPositions(tValues); } + void setValue (double bottom, double top); + void setValue (double bottomLeft, double topLeft, double bottomRight, double topRight); + void setEnabled (bool enabled); + template + void setDefault (const rtengine::procparams::Threshold &tresh) { tSelector.setDefaults(tresh); } + void setDefault (double defBottom, double defTop); + void setDefault (double defBottomLeft, double defTopLeft, double defBottomRight, double defTopRight); + void setEditedState (EditedState eState); + EditedState getEditedState (); + void setDefaultEditedState (EditedState eState); + void showEditedCB (); + void block(bool isBlocked) { blocked = isBlocked; } + void setBgGradient (const std::vector &milestones) { tSelector.setBgGradient (milestones); } + void setBgColorProvider (ColorProvider *cp, int i) { tSelector.setColorProvider(cp, i); } + void setUpdatePolicy (eUpdatePolicy policy) { tSelector.setUpdatePolicy(policy); } + + //void spinChanged (); + void selectorChanged (); + bool notifyListener (); + void resetPressed (GdkEventButton* event); + void editedToggled (); + Glib::ustring getHistoryString (); + void set_tooltip_markup(const Glib::ustring& markup); + // this set_tooltip_text method is to set_tooltip_markup, and text can contain markups + void set_tooltip_text(const Glib::ustring& text); +}; + +#endif diff --git a/rtgui/thresholdselector.cc b/rtgui/thresholdselector.cc new file mode 100644 index 000000000..b87233fe8 --- /dev/null +++ b/rtgui/thresholdselector.cc @@ -0,0 +1,695 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "thresholdselector.h" +#include "multilangmgr.h" +#include +#include "mycurve.h" + +ThresholdSelector::ThresholdSelector(double minValueBottom, double maxValueBottom, double defBottom, Glib::ustring labelBottom, unsigned int precisionBottom, + double minValueTop, double maxValueTop, double defTop, Glib::ustring labelTop, unsigned int precisionTop, + ThresholdCurveProvider* curveProvider) + : ColoredBar(RTO_Left2Right) +{ + positions[TS_BOTTOMLEFT] = defPos[TS_BOTTOMLEFT] = defBottom; + positions[TS_TOPLEFT] = defPos[TS_TOPLEFT] = defTop; + positions[TS_BOTTOMRIGHT] = defPos[TS_BOTTOMRIGHT] = 0; // unused + positions[TS_TOPRIGHT] = defPos[TS_TOPRIGHT] = 0; // unused + this->precisionTop = precisionTop; + this->precisionBottom = precisionBottom; + doubleThresh = false; + + separatedLabelBottom = labelBottom; + separatedLabelTop = labelTop; + + bgCurveProvider = curveProvider; + separatedSliders = true; + initalEq1 = false; // unused + minValBottom = minValueBottom; + maxValBottom = maxValueBottom; + minValTop = minValueTop; + maxValTop = maxValueTop; + + initValues (); +} + +ThresholdSelector::ThresholdSelector(double minValue, double maxValue, double defBottom, + double defTop, unsigned int precision, bool startAtOne) + : ColoredBar(RTO_Left2Right) +{ + positions[TS_BOTTOMLEFT] = defPos[TS_BOTTOMLEFT] = defBottom; + positions[TS_TOPLEFT] = defPos[TS_TOPLEFT] = defTop; + positions[TS_BOTTOMRIGHT] = defPos[TS_BOTTOMRIGHT] = maxValue; + positions[TS_TOPRIGHT] = defPos[TS_TOPRIGHT] = maxValue; + this->precisionTop = precision; + this->precisionBottom = precision; + doubleThresh = false; + + separatedLabelBottom = ""; + separatedLabelTop = ""; + +#ifndef NDEBUG + if (startAtOne) { + assert (defBottom >= defTop); + assert (defTop >= minValue); + assert (defBottom <= maxValue); + } + else { + assert (defTop >= defBottom); + assert (defBottom >= minValue); + assert (defTop <= maxValue); + } + assert(minValue < maxValue); +#endif + + bgCurveProvider = NULL; + separatedSliders = false; + initalEq1 = startAtOne; + minValTop = minValBottom = minValue; + maxValTop = maxValBottom = maxValue; + + initValues (); + +} + +ThresholdSelector::ThresholdSelector(double minValue, double maxValue, double defBottomLeft, double defTopLeft, + double defBottomRight, double defTopRight, unsigned int precision, bool startAtOne) + : ColoredBar(RTO_Left2Right) +{ + positions[TS_BOTTOMLEFT] = defPos[TS_BOTTOMLEFT] = defBottomLeft; + positions[TS_TOPLEFT] = defPos[TS_TOPLEFT] = defTopLeft; + positions[TS_BOTTOMRIGHT] = defPos[TS_BOTTOMRIGHT] = defBottomRight; + positions[TS_TOPRIGHT] = defPos[TS_TOPRIGHT] = defTopRight; + this->precisionTop = precision; + this->precisionBottom = precision; + doubleThresh = true; + + separatedLabelBottom = ""; + separatedLabelTop = ""; + +#ifndef NDEBUG + if (startAtOne) { + assert (minValue <= defTopLeft); + assert (defTopLeft <= defBottomLeft); + assert (defBottomLeft <= defBottomRight); + assert (defBottomRight <= defTopRight); + assert (defTopRight <= maxValue); + } + else { + assert (minValue <= defBottomLeft); + assert (defBottomLeft <= defTopLeft); + assert (defTopLeft <= defTopRight); + assert (defTopRight <= defBottomRight); + assert (defBottomRight <= maxValue); + } + assert(minValue < maxValue); +#endif + + bgCurveProvider = NULL; + separatedSliders = false; + initalEq1 = startAtOne; + minValTop = minValBottom = minValue; + maxValTop = maxValBottom = maxValue; + + initValues (); +} + +void ThresholdSelector::initValues () { + + updatePolicy = RTUP_STATIC; + additionalTTip = ""; + oldLitCursor = litCursor = TS_UNDEFINED; + movedCursor = TS_UNDEFINED; + secondaryMovedCursor = TS_UNDEFINED; + set_size_request (-1, 30); + add_events(Gdk::LEAVE_NOTIFY_MASK); + set_name("ThresholdSelector"); + set_can_focus(false); + set_app_paintable(true); + setDirty(true); + updateTooltip(); +} + +/* + * Set the position of the sliders without telling it to the listener + */ +void ThresholdSelector::setPositions (double bottom, double top) { + + setPositions(bottom, top, maxValBottom, maxValTop); + if (updatePolicy==RTUP_DYNAMIC) + setDirty(true); +} + +/* + * Set the position of the sliders without telling it to the listener + */ +void ThresholdSelector::setPositions (double bottomLeft, double topLeft, double bottomRight, double topRight) { + + bool different = ( (positions[TS_TOPLEFT] != topLeft) || (positions[TS_TOPRIGHT] != topRight) || + (positions[TS_BOTTOMLEFT] != bottomLeft) || (positions[TS_BOTTOMRIGHT] != bottomRight) ); + positions[TS_BOTTOMLEFT] = bottomLeft; + positions[TS_TOPLEFT] = topLeft; + positions[TS_BOTTOMRIGHT] = bottomRight; + positions[TS_TOPRIGHT] = topRight; + + if (different) { + if (updatePolicy==RTUP_DYNAMIC) + setDirty(true); + sig_val_changed.emit(); + updateTooltip(); + queue_draw (); + } +} + +void ThresholdSelector::setDefaults (double bottom, double top) { + + setDefaults(bottom, top, maxValBottom, maxValTop); +} + +void ThresholdSelector::setDefaults (double bottomLeft, double topLeft, double bottomRight, double topRight) { + + defPos[TS_BOTTOMLEFT] = bottomLeft; + defPos[TS_TOPLEFT] = topLeft; + if (doubleThresh) { + defPos[TS_BOTTOMRIGHT] = bottomRight; + defPos[TS_TOPRIGHT] = topRight; + } +} + +void ThresholdSelector::on_realize() { + + Gtk::DrawingArea::on_realize(); + + add_events(Gdk::EXPOSURE_MASK | Gdk::POINTER_MOTION_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK); +} + +bool ThresholdSelector::on_expose_event(GdkEventExpose* event) { + + Gdk::Color c; + Glib::RefPtr win = get_window(); + Cairo::RefPtr cr = win->create_cairo_context(); + + double positions01[4]; + int w = get_width (); + int h = get_height (); + + wslider = std::max(int(h / 5), 10); + int hwslider = wslider/2; + int iw = w-wslider-2*hb; // inner width (excluding padding for sliders) + + positions01[TS_BOTTOMLEFT] = to01(TS_BOTTOMLEFT); + positions01[TS_TOPLEFT] = to01(TS_TOPLEFT); + positions01[TS_BOTTOMRIGHT] = to01(TS_BOTTOMRIGHT); + positions01[TS_TOPRIGHT] = to01(TS_TOPRIGHT); + + Gtk::StateType state = !is_sensitive() ? Gtk::STATE_INSENSITIVE : Gtk::STATE_NORMAL; + Glib::RefPtr style = get_style(); + + // set the box's colors + cr->set_line_width (1.0); + cr->set_line_cap(Cairo::LINE_CAP_BUTT); + if (is_sensitive() && canGetColors()) { + // gradient background + Glib::RefPtr win = get_window(); + // this will eventually create/update the off-screen Surface + setDrawRectangle(win, hb+hwslider, int(float(h)*1.5f/7.f+0.5f), iw+1, int(float(h)*4.f/7.f+0.5f)); + // that we're displaying here + ColoredBar::expose(win); + } + else { + // solid background + c = style->get_bg (state); + if (state==Gtk::STATE_INSENSITIVE) + cr->set_source_rgb (c.get_red_p()*0.96, c.get_green_p()*0.96, c.get_blue_p()*0.96); + else + cr->set_source_rgb (c.get_red_p()*0.85, c.get_green_p()*0.85, c.get_blue_p()*0.85); + + // draw the box's background + cr->rectangle (hb+hwslider-0.5, double(int(float(h)*1.5f/7.f))+0.5, iw+1, double(int(float(h)*4.f/7.f))); + cr->fill(); + } + + // draw curve + + if (bgCurveProvider) { + double yStart = double(int(float(h)*5.5f/7.f))-0.5; + double yEnd = double(int(float(h)*1.5f/7.f))+1.5; + + std::vector pts = bgCurveProvider->getCurvePoints(this); // the values sent by the provider are not checked (assumed to be correct) + if (pts.size() >= 4) { + std::vector::iterator i=pts.begin(); + double x = *i; i++; + double y = *i; i++; + cr->move_to (hb+hwslider+iw*x+0.5, (yEnd-yStart)*y+yStart); + + for (; iline_to (hb+hwslider+iw*x+0.5, (yEnd-yStart)*y+yStart); + } + } + else { + // Draw a straight line because not enough points has been sent + double yStart = double(int(float(h)*5.5f/7.f))-0.5; + cr->move_to (hb+hwslider+0.5, yStart); + cr->line_to (hb+hwslider+iw+0.5, yStart); + } + + } + else { + if (!separatedSliders) { + double yStart = initalEq1 ? double(int(float(h)*1.5f/7.f))+1.5 : double(int(float(h)*5.5f/7.f))-0.5; + double yEnd = initalEq1 ? double(int(float(h)*5.5f/7.f))-0.5 : double(int(float(h)*1.5f/7.f))+1.5; + ThreshCursorId p[4]; + if (initalEq1) { p[0] = TS_TOPLEFT; p[1] = TS_BOTTOMLEFT; p[2] = TS_BOTTOMRIGHT; p[3] = TS_TOPRIGHT; } + else { p[0] = TS_BOTTOMLEFT; p[1] = TS_TOPLEFT; p[2] = TS_TOPRIGHT; p[3] = TS_BOTTOMRIGHT; } + if (positions[p[1]] > minValTop) // we use minValTop since if this block is executed, it means that we are in a simple Threshold where both bottom and top range are the same + cr->move_to (hb+hwslider, yStart); + else + cr->move_to (hb+hwslider, yEnd); + if (positions[p[0]] > minValTop) + cr->line_to (hb+hwslider+iw*positions01[p[0]]+0.5, yStart); + if (positions[p[1]] > minValTop) + cr->line_to (hb+hwslider+iw*positions01[p[1]]+0.5, yEnd); + cr->line_to (hb+hwslider+iw*positions01[p[2]]+0.5, yEnd); + if (doubleThresh && positions[p[2]] < maxValTop) { + cr->line_to (hb+hwslider+iw*positions01[p[3]]+0.5, yStart); + if (positions[p[3]] < maxValTop) + cr->line_to (hb+hwslider+iw+0.5, yStart); + } + } + } + if (is_sensitive() && bgGradient.size()>1) { + // draw surrounding curve + c = style->get_bg (state); + cr->set_source_rgb (c.get_red_p()*0.85, c.get_green_p()*0.85, c.get_blue_p()*0.85); + cr->set_line_width (5.0); + cr->stroke_preserve(); + } + // draw curve + if (is_sensitive()) { + c = style->get_fg (movedCursor!=TS_UNDEFINED || litCursor!=TS_UNDEFINED ? Gtk::STATE_PRELIGHT : Gtk::STATE_ACTIVE); + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + } + else { + c = style->get_bg (Gtk::STATE_INSENSITIVE); + cr->set_source_rgb (c.get_red_p()*0.85, c.get_green_p()*0.85, c.get_blue_p()*0.85); + } + cr->set_line_width (1.5); + cr->stroke (); + + // draw the box's borders + cr->set_line_width (1.); + cr->rectangle (hb+hwslider-0.5, double(int(float(h)*1.5f/7.f))+0.5, iw+1, double(int(float(h)*4.f/7.f))); + c = style->get_bg (state); + if (state==Gtk::STATE_INSENSITIVE) + cr->set_source_rgb (c.get_red_p()*0.85, c.get_green_p()*0.85, c.get_blue_p()*0.85); + else + cr->set_source_rgb (c.get_red_p()*0.7, c.get_green_p()*0.7, c.get_blue_p()*0.7); + cr->stroke (); + + // draw sliders + //if (!(litCursor == TS_UNDEFINED && movedCursor == TS_UNDEFINED)) { + //cr->set_line_width (1.); + for (int i=0; i<(doubleThresh?4:2); i++) { + double posX = hb+hwslider+iw*positions01[i]+0.5; + double arrowY = i==0 || i==2 ? h-(h*2.5/7.-0.5)-vb : h*2.5/7.-0.5+vb; + double baseY = i==0 || i==2 ? h-0.5-vb : 0.5+vb; + double centerY = (arrowY+baseY)/2.; + cr->move_to (posX, arrowY); + cr->line_to (posX+hwslider, centerY); + cr->line_to (posX+hwslider, baseY); + cr->line_to (posX-hwslider, baseY); + cr->line_to (posX-hwslider, centerY); + cr->close_path(); + if (i==movedCursor) { + // moved (selected) + c = style->get_bg (Gtk::STATE_SELECTED); + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + cr->fill_preserve (); + //c = style->get_dark (Gtk::STATE_SELECTED); + //cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + c = style->get_bg (state); + cr->set_source_rgb (c.get_red_p()*0.55, c.get_green_p()*0.55, c.get_blue_p()*0.55); + cr->stroke (); + } + else if (i==secondaryMovedCursor || (movedCursor==TS_UNDEFINED && i==litCursor)) { + // prelight + c = style->get_bg (Gtk::STATE_PRELIGHT); + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + cr->fill_preserve (); + c = style->get_bg (state); + cr->set_source_rgb (c.get_red_p()*0.55, c.get_green_p()*0.55, c.get_blue_p()*0.55); + cr->stroke (); + } + else { + // normal + c = style->get_bg (is_sensitive() ? Gtk::STATE_ACTIVE : Gtk::STATE_INSENSITIVE); + cr->set_source_rgb (c.get_red_p(), c.get_green_p(), c.get_blue_p()); + cr->fill_preserve (); + c = style->get_bg (state); + if (state==Gtk::STATE_INSENSITIVE) + cr->set_source_rgb (c.get_red_p()*0.85, c.get_green_p()*0.85, c.get_blue_p()*0.85); + else + cr->set_source_rgb (c.get_red_p()*0.7, c.get_green_p()*0.7, c.get_blue_p()*0.7); + cr->stroke (); + } + } + //} + + return true; +} + +bool ThresholdSelector::on_button_press_event (GdkEventButton* event) { + + if (event->button == 1) { + movedCursor = litCursor; + findSecondaryMovedCursor(event->state); + tmpX = event->x; + + queue_draw (); + } + grab_focus(); + return true; +} + +bool ThresholdSelector::on_button_release_event (GdkEventButton* event) { + + if (event->button == 1) { + findLitCursor(event->x, event->y); + movedCursor = TS_UNDEFINED; + secondaryMovedCursor = TS_UNDEFINED; + queue_draw (); + } + return true; +} + +bool ThresholdSelector::on_leave_notify_event (GdkEventCrossing* event) { + if (movedCursor == TS_UNDEFINED) { + litCursor = TS_UNDEFINED; + oldLitCursor = TS_UNDEFINED; + queue_draw(); + } + return true; +} + +bool ThresholdSelector::on_motion_notify_event (GdkEventMotion* event) { + + int w = get_width (); + + findLitCursor(event->x, event->y); + + if (movedCursor != TS_UNDEFINED) { + // user is moving a cursor or two + double minBound, maxBound, dRange; + + findSecondaryMovedCursor(event->state); + + // computing the boundaries + findBoundaries(minBound, maxBound); + + if (movedCursor==TS_BOTTOMLEFT || movedCursor==TS_BOTTOMRIGHT) + dRange = maxValBottom-minValBottom; + else + dRange = maxValTop-minValTop; + double dX = ( (event->x-tmpX)*dRange )/( w-2*hb ); + // slow motion if CTRL is pressed + if (event->state & Gdk::CONTROL_MASK) + dX *= 0.05; + + // get the new X value, inside bounds + double newX = positions[movedCursor] + dX; + + if (newX > maxBound) newX = maxBound; + else if (newX < minBound) newX = minBound; + + // compute the effective dX + dX = newX - positions[movedCursor]; + // set the new position of the moved cursor + positions[movedCursor] = newX; + + // apply the decay to the secondary moved cursor, if necessary + if (secondaryMovedCursor != TS_UNDEFINED) { + positions[secondaryMovedCursor] += dX; + } + + // set the new reference value for the next move + tmpX = event->x; + + // ask to redraw the background + if (updatePolicy==RTUP_DYNAMIC) + setDirty(true); + + // update the tooltip + updateTooltip(); + + sig_val_changed.emit(); + + queue_draw (); + } + else { + if (litCursor != oldLitCursor) + queue_draw (); + oldLitCursor = litCursor; + } + + + return true; +} + +void ThresholdSelector::findLitCursor(int posX, int posY) { + int w = get_width (); + int h = get_height (); + + litCursor = TS_UNDEFINED; + if (posY >=0 && posY <= h/2) { + if (posX > 0 && posX < w) { + litCursor = TS_TOPLEFT; + + if (doubleThresh) { + // we use minValTop since if this block is executed, it means that we are in a simple Threshold where both bottom and top range are the same + double cursorX = (posX-hb)*(maxValTop-minValTop)/(w-2*hb)+minValTop; + + if (cursorX>positions[TS_TOPRIGHT] || abs(cursorX-positions[TS_TOPRIGHT]) < abs(cursorX-positions[TS_TOPLEFT])) + litCursor = TS_TOPRIGHT; + } + } + } + else if (posY > h/2 && posY < h) { + if (posX > 0 && posX < w) { + litCursor = TS_BOTTOMLEFT; + if (doubleThresh) { + // we use minValTop since if this block is executed, it means that we are in a simple Threshold where both bottom and top range are the same + double cursorX = (posX-hb)*(maxValTop-minValTop)/(w-2*hb)+minValTop; + + if (cursorX>positions[TS_BOTTOMRIGHT] || abs(cursorX-positions[TS_BOTTOMRIGHT]) < abs(cursorX-positions[TS_BOTTOMLEFT])) + litCursor = TS_BOTTOMRIGHT; + } + } + } +} + +void ThresholdSelector::findBoundaries(double &min, double &max) { + + switch (movedCursor) { + case (TS_BOTTOMLEFT): + if (separatedSliders) { + if (movedCursor == TS_BOTTOMLEFT) { + min = minValBottom; + max = maxValBottom; + } + else if (movedCursor == TS_TOPLEFT) { + min = minValTop; + max = maxValTop; + } + } + else if (initalEq1) { + min = secondaryMovedCursor == TS_UNDEFINED ? positions[TS_TOPLEFT] : minValTop+(positions[TS_BOTTOMLEFT]-positions[TS_TOPLEFT]); + max = positions[TS_BOTTOMRIGHT]; + } + else { + min = minValTop; + max = secondaryMovedCursor == TS_UNDEFINED ? positions[TS_TOPLEFT] : positions[TS_TOPRIGHT]-(positions[TS_TOPLEFT]-positions[TS_BOTTOMLEFT]); + } + break; + case (TS_TOPLEFT): + if (separatedSliders) { + if (movedCursor == TS_BOTTOMLEFT) { + min = minValBottom; + max = maxValBottom; + } + else if (movedCursor == TS_TOPLEFT) { + min = minValTop; + max = maxValTop; + } + } + else if (initalEq1) { + min = minValTop; + max = secondaryMovedCursor == TS_UNDEFINED ? positions[TS_BOTTOMLEFT] : positions[TS_BOTTOMRIGHT]-(positions[TS_BOTTOMLEFT]-positions[TS_TOPLEFT]); + } + else { + min = secondaryMovedCursor == TS_UNDEFINED ? positions[TS_BOTTOMLEFT] : minValTop+(positions[TS_TOPLEFT]-positions[TS_BOTTOMLEFT]); + max = positions[TS_TOPRIGHT]; + } + break; + case (TS_BOTTOMRIGHT): + if (initalEq1) { + min = positions[TS_BOTTOMLEFT]; + max = secondaryMovedCursor == TS_UNDEFINED ? positions[TS_TOPRIGHT] : maxValTop-(positions[TS_TOPRIGHT]-positions[TS_BOTTOMRIGHT]); + } + else { + min = secondaryMovedCursor == TS_UNDEFINED ? positions[TS_TOPRIGHT] : positions[TS_TOPLEFT]+(positions[TS_BOTTOMRIGHT]-positions[TS_TOPRIGHT]); + max = maxValTop; + } + break; + case (TS_TOPRIGHT): + if (initalEq1) { + min = secondaryMovedCursor == TS_UNDEFINED ? positions[TS_BOTTOMRIGHT] : positions[TS_BOTTOMLEFT]+(positions[TS_TOPRIGHT]-positions[TS_BOTTOMRIGHT]); + max = maxValTop; + } + else { + min = positions[TS_TOPLEFT]; + max = secondaryMovedCursor == TS_UNDEFINED ? positions[TS_BOTTOMRIGHT] : maxValTop-(positions[TS_BOTTOMRIGHT]-positions[TS_TOPRIGHT]); + } + break; + default: + min = minValTop; + max = maxValTop; + break; + } +} + +void ThresholdSelector::findSecondaryMovedCursor(guint state) { + secondaryMovedCursor = TS_UNDEFINED; + if (!separatedSliders && !(state & Gdk::SHIFT_MASK)) { + switch (movedCursor) { + case (TS_BOTTOMLEFT): + secondaryMovedCursor = TS_TOPLEFT; + break; + case (TS_TOPLEFT): + secondaryMovedCursor = TS_BOTTOMLEFT; + break; + case (TS_BOTTOMRIGHT): + secondaryMovedCursor = TS_TOPRIGHT; + break; + case (TS_TOPRIGHT): + secondaryMovedCursor = TS_BOTTOMRIGHT; + break; + default: + secondaryMovedCursor = TS_UNDEFINED; + break; + } + } +} + +void ThresholdSelector::styleChanged (const Glib::RefPtr& style) { + + queue_draw (); +} + +void ThresholdSelector::reset () { + + positions[0] = defPos[0]; + positions[1] = defPos[1]; + positions[2] = defPos[2]; + positions[3] = defPos[3]; + + if (updatePolicy==RTUP_DYNAMIC) + setDirty(true); + + updateTooltip(); + queue_draw (); +} + +double ThresholdSelector::to01(ThreshCursorId cursorId) { + + double rVal; + if (cursorId==TS_BOTTOMLEFT || cursorId==TS_BOTTOMRIGHT) + rVal = (positions[cursorId]-minValBottom)/(maxValBottom-minValBottom); + else + rVal = (positions[cursorId]-minValTop)/(maxValTop-minValTop); + if (rVal < 0.) rVal = 0.; + else if (rVal > 1.) rVal = 1.; + return rVal; +} + +void ThresholdSelector::setBgCurveProvider (ThresholdCurveProvider* provider) { + bgCurveProvider = provider; +} + +void ThresholdSelector::setSeparatedSliders(bool separated) { + separatedSliders = separated; +} + +bool ThresholdSelector::getSeparatedSliders() { + return separatedSliders; +} + +void ThresholdSelector::updateTooltip() { + + Glib::ustring tTip; + if (doubleThresh) { + tTip = Glib::ustring::compose("%1: %2 %3: %4\n%5: %6 %7: %8", + M("THRESHOLDSELECTOR_TL"), Glib::ustring::format(std::fixed, std::setprecision(precisionTop), positions[TS_TOPLEFT]), + M("THRESHOLDSELECTOR_TR"), Glib::ustring::format(std::fixed, std::setprecision(precisionTop), positions[TS_TOPRIGHT]), + M("THRESHOLDSELECTOR_BL"), Glib::ustring::format(std::fixed, std::setprecision(precisionBottom), positions[TS_BOTTOMLEFT]), + M("THRESHOLDSELECTOR_BR"), Glib::ustring::format(std::fixed, std::setprecision(precisionBottom), positions[TS_BOTTOMRIGHT]) + ); + if (!additionalTTip.empty()) + tTip += Glib::ustring::compose("\n\n%1", additionalTTip); + tTip += Glib::ustring::compose("\n\n%1", M("THRESHOLDSELECTOR_HINT")); + } + else if (separatedSliders) { + tTip = Glib::ustring::compose("%1: %2\n%3: %4", + separatedLabelTop, Glib::ustring::format(std::fixed, std::setprecision(precisionTop), positions[TS_TOPLEFT]), + separatedLabelBottom, Glib::ustring::format(std::fixed, std::setprecision(precisionBottom), positions[TS_BOTTOMLEFT]) + ); + if (!additionalTTip.empty()) + tTip += Glib::ustring::compose("\n\n%1", additionalTTip); + } + else { + tTip = Glib::ustring::compose("%1: %2\n%3: %4", + M("THRESHOLDSELECTOR_T"), Glib::ustring::format(std::fixed, std::setprecision(precisionTop), positions[TS_TOPLEFT]), + M("THRESHOLDSELECTOR_B"), Glib::ustring::format(std::fixed, std::setprecision(precisionBottom), positions[TS_BOTTOMLEFT]) + ); + if (!additionalTTip.empty()) + tTip += Glib::ustring::compose("\n\n%1", additionalTTip); + tTip += Glib::ustring::compose("\n\n%1", M("THRESHOLDSELECTOR_HINT")); + } + Gtk::Widget::set_tooltip_markup(tTip); +} + +sigc::signal ThresholdSelector::signal_value_changed() { + return sig_val_changed; +} + +double ThresholdSelector::shapePositionValue (ThreshCursorId cursorId) { + unsigned int precision = (cursorId==TS_BOTTOMLEFT || cursorId==TS_BOTTOMRIGHT) ? precisionBottom : precisionTop; + return round(positions[cursorId]*pow(double(10), precision)) / pow(double(10), precision); +} + +void ThresholdSelector::set_tooltip_markup(const Glib::ustring& markup) { + additionalTTip = markup; + updateTooltip(); +} + +void ThresholdSelector::set_tooltip_text(const Glib::ustring& text) { + additionalTTip = text; + updateTooltip(); +} diff --git a/rtgui/thresholdselector.h b/rtgui/thresholdselector.h new file mode 100644 index 000000000..f4db16e2e --- /dev/null +++ b/rtgui/thresholdselector.h @@ -0,0 +1,220 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _THRESHOLDSELECTOR_ +#define _THRESHOLDSELECTOR_ + +#include "guiutils.h" +#include "../rtengine/procparams.h" +#include "coloredbar.h" +#include + +class ThresholdSelector; + +/* + * This class let the instanciator to provide the background curve + */ +class ThresholdCurveProvider { + public: + virtual ~ThresholdCurveProvider() {}; + /* + * The curve provider has to send back a list of point (at least 2 points) in the [0.0 ; 1.0] range + * for both X and Y axis; X and Y values are streamlined ( X1, Y1, X2, Y2, X3, Y3, ...) + */ + virtual std::vector getCurvePoints(ThresholdSelector* tAdjuster) const = 0; +}; + +/* + * This widget will let you select a linearly variable threshold, creating a ramp up + * if you want to go from a null effect to a full effect + * 0-0-ramp up-1-1 + * or a ramp down if you want the contrary + * 1-1-ramp down-0-0 + * + * You can optionally create a double threshold + * 0-0-ramp up-1-1-ramp down-0-0 + * or + * 1-1-ramp down-0-0-ramp up-1-1 + * + * Please note that the values are related to the cursors, depending on their position + * on the graph. E.g. the "bottomLeft" value is related to the bottom left cursor. + * + * It is also possible to have a threshold with 2 totally independent cursors, each one having his own range, + * man/max/default values and precision. This let developers create their own threshold curve, that they will + * have to provide through the + * + */ +class ThresholdSelector : public Gtk::DrawingArea, public ColoredBar { + + public: + + enum ThreshCursorId { + TS_UNDEFINED=-1, + TS_BOTTOMLEFT, + TS_TOPLEFT, + TS_BOTTOMRIGHT, + TS_TOPRIGHT + }; + + + protected: + + sigc::signal sig_val_changed; + + ThresholdCurveProvider* bgCurveProvider; + + Glib::ustring additionalTTip; + Glib::ustring separatedLabelBottom; // Label for the bottom cursor, displayed if separatedSliders==true only + Glib::ustring separatedLabelTop; // Label for the top cursor, displayed if separatedSliders==true only + bool separatedSliders; // If true, the Top and Bottom sliders are totally separate and can be drag through the full range; for simple threshold only! + bool doubleThresh; // If true: there curve is a double threshold (0 to 1 to 0, or 1 to 0 to 1). + bool initalEq1; // If true: the curve start at 1 (top); if false: the curve start at 0 (bottom) + unsigned int precisionTop; // Decimal number if this object has to handle "double" values, for the Top slider + unsigned int precisionBottom; // Decimal number if this object has to handle "double" values, for the Bottom slider + ThreshCursorId litCursor; + ThreshCursorId oldLitCursor; + double boundary1[2], boundary2[2]; + double tmpX, tmpPos; + + ThreshCursorId movedCursor, secondaryMovedCursor; + double minValTop, maxValTop; + double minValBottom, maxValBottom; + double defPos[4]; + double positions[4]; + unsigned short wslider; + eUpdatePolicy updatePolicy; + + const static int hb = 3; // horizontal border + const static int vb = 2; // vertical border + + void initValues (); + void findLitCursor(int posX, int posY); + void findSecondaryMovedCursor(guint state); + void findBoundaries(double &min, double &max); + double to01(ThreshCursorId cursorId); + void updateTooltip(); + + public: + + sigc::signal signal_value_changed(); + + ThresholdSelector(double minValueBottom, double maxValueBottom, double defBottom, Glib::ustring labelBottom, unsigned int precisionBottom, + double minValueTop, double maxValueTop, double defTop, Glib::ustring labelTop, unsigned int precisionTop, + ThresholdCurveProvider* curveProvider); + ThresholdSelector(double minValue, double maxValue, double defBottom, double defTop, unsigned int precision, bool startAtOne); + ThresholdSelector(double minValue, double maxValue, double defBottomLeft, double defTopLeft, double defBottomRight, double defTopRight, unsigned int precision, bool startAtOne); + + double shapePositionValue (ThreshCursorId cursorId); + template + void setDefaults (const rtengine::procparams::Threshold &t) { + defPos[TS_BOTTOMLEFT] = double(t.value[0]); // should we use shapeValue() ? + defPos[TS_TOPLEFT] = double(t.value[1]); + if (doubleThresh) { + defPos[TS_BOTTOMRIGHT] = double(t.value[2]); + defPos[TS_TOPRIGHT] = double(t.value[3]); + } + } + void setDefaults (double bottom, double top); + void setDefaults (double bottomLeft, double topLeft, double bottomRight, double topRight); + template + void setPositions (const rtengine::procparams::Threshold &tValues) { + positions[TS_BOTTOMLEFT] = static_cast(tValues.value[TS_BOTTOMLEFT]); + positions[TS_TOPLEFT] = static_cast(tValues.value[TS_TOPLEFT]); + if (tValues.isDouble()) { + positions[TS_BOTTOMRIGHT] = static_cast(tValues.value[TS_BOTTOMRIGHT]); + positions[TS_TOPRIGHT] = static_cast(tValues.value[TS_TOPRIGHT]); + } + updateTooltip(); + queue_draw(); + } + void setPositions (double bottom, double top); + void setPositions (double bottomLeft, double topLeft, double bottomRight, double topRight); + + template + rtengine::procparams::Threshold getPositions () { + if (doubleThresh) { + rtengine::procparams::Threshold rThresh( + static_cast(shapePositionValue(TS_BOTTOMLEFT)), + static_cast(shapePositionValue(TS_TOPLEFT)), + static_cast(shapePositionValue(TS_BOTTOMRIGHT)), + static_cast(shapePositionValue(TS_TOPRIGHT)), + initalEq1 + ); + return rThresh; + } + else { + rtengine::procparams::Threshold rThresh( + static_cast(shapePositionValue(TS_BOTTOMLEFT)), + static_cast(shapePositionValue(TS_TOPLEFT)), + initalEq1 + ); + return rThresh; + } + } + + template + void getPositions (T &bottom, T &top) { + bottom = static_cast(shapePositionValue(TS_BOTTOMLEFT)); + top = static_cast(shapePositionValue(TS_TOPLEFT)); + } + + template + void getPositions (T &bottomLeft, T &topLeft, T &bottomRight, T &topRight) { + bottomLeft = static_cast(shapePositionValue(TS_BOTTOMLEFT)); + topLeft = static_cast(shapePositionValue(TS_TOPLEFT)); + bottomRight = static_cast(shapePositionValue(TS_BOTTOMRIGHT)); + topRight = static_cast(shapePositionValue(TS_TOPRIGHT)); + } + + void setSeparatedSliders(bool separated); + bool getSeparatedSliders(); + void setBgCurveProvider (ThresholdCurveProvider* provider); + bool isStartAtOne() { return initalEq1; } + bool isDouble() { return doubleThresh; } + void on_realize (); + bool on_expose_event(GdkEventExpose* event); + bool on_button_press_event (GdkEventButton* event); + bool on_button_release_event (GdkEventButton* event); + bool on_motion_notify_event (GdkEventMotion* event); + bool on_leave_notify_event (GdkEventCrossing* event); + void styleChanged (const Glib::RefPtr& style); + unsigned int getPrecision () { return precisionTop; } + void reset (); + void setUpdatePolicy (eUpdatePolicy policy) { updatePolicy = policy; } + void set_tooltip_markup(const Glib::ustring& markup); + // this set_tooltip_text method is to set_tooltip_markup, and text can contain markups + void set_tooltip_text(const Glib::ustring& text); +}; + +template<> +inline void ThresholdSelector::getPositions (Glib::ustring& bottom, Glib::ustring& top) { + bottom = Glib::ustring::format(std::fixed, std::setprecision(precisionBottom), shapePositionValue(TS_BOTTOMLEFT)); + top = Glib::ustring::format(std::fixed, std::setprecision(precisionTop), shapePositionValue(TS_TOPLEFT)); +} + +template<> +inline void ThresholdSelector::getPositions (Glib::ustring& bottomLeft, Glib::ustring& topLeft, Glib::ustring& bottomRight, Glib::ustring& topRight) { + + bottomLeft = Glib::ustring::format(std::fixed, std::setprecision(precisionBottom), shapePositionValue(TS_BOTTOMLEFT)); + topLeft = Glib::ustring::format(std::fixed, std::setprecision(precisionTop), shapePositionValue(TS_TOPLEFT)); + bottomRight = Glib::ustring::format(std::fixed, std::setprecision(precisionBottom), shapePositionValue(TS_BOTTOMRIGHT)); + topRight = Glib::ustring::format(std::fixed, std::setprecision(precisionTop), shapePositionValue(TS_TOPRIGHT)); +} + +#endif + diff --git a/rtgui/thumbbrowserbase.cc b/rtgui/thumbbrowserbase.cc new file mode 100644 index 000000000..ceb566b22 --- /dev/null +++ b/rtgui/thumbbrowserbase.cc @@ -0,0 +1,1026 @@ +/* + * This file is part of RawTherapee. + * + * 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 "../rtengine/rt_math.h" + +#include "thumbbrowserbase.h" +#include "multilangmgr.h" +#include "options.h" +#include "../rtengine/mytime.h" + +using namespace std; + +ThumbBrowserBase::ThumbBrowserBase () + : lastClicked(NULL), previewHeight(options.thumbSize), numOfCols(1), inspector(NULL), isInspectorActive(false) { + location = THLOC_FILEBROWSER; + inW = -1; inH = -1; + + Gtk::HBox* hb1 = Gtk::manage( new Gtk::HBox () ); + Gtk::HBox* hb2 = Gtk::manage( new Gtk::HBox () ); + Gtk::Frame* frame = Gtk::manage( new Gtk::Frame () ); + frame->add (internal); + frame->set_shadow_type (Gtk::SHADOW_IN ); + hb1->pack_start (*frame); + hb1->pack_end (vscroll, Gtk::PACK_SHRINK, 0); + + pack_start (*hb1); + + hb2->pack_start (hscroll); + + pack_start (*hb2,Gtk::PACK_SHRINK, 0); + + internal.setParent (this); + + show_all (); + + hscroll.set_update_policy (Gtk::UPDATE_CONTINUOUS); + vscroll.set_update_policy (Gtk::UPDATE_CONTINUOUS); + + vscroll.signal_value_changed().connect( sigc::mem_fun(*this, &ThumbBrowserBase::scrollChanged) ); + hscroll.signal_value_changed().connect( sigc::mem_fun(*this, &ThumbBrowserBase::scrollChanged) ); + + internal.signal_size_allocate().connect( sigc::mem_fun(*this, &ThumbBrowserBase::internalAreaResized) ); +} + +void ThumbBrowserBase::scrollChanged () { + { + #if PROTECT_VECTORS + MYWRITERLOCK(l, entryRW); + #endif + + for (size_t i=0; isetOffset ((int)(hscroll.get_value()), (int)(vscroll.get_value())); + } + + internal.setPosition ((int)(hscroll.get_value()), (int)(vscroll.get_value())); + + if (!internal.isDirty()) { + internal.setDirty (); + internal.queue_draw (); + } +} + +void ThumbBrowserBase::scroll (int direction) { + // GUI already acquired when here + if (arrangement==TB_Vertical) + vscroll.set_value (vscroll.get_value() + (direction==GDK_SCROLL_DOWN ? +1 : -1) * vscroll.get_adjustment()->get_step_increment()); + else + hscroll.set_value (hscroll.get_value() + (direction==GDK_SCROLL_DOWN ? +1 : -1) * hscroll.get_adjustment()->get_step_increment()); +} + +void ThumbBrowserBase::scrollPage (int direction) { + // GUI already acquired when here + if (arrangement==TB_Vertical) + vscroll.set_value (vscroll.get_value() + (direction==GDK_SCROLL_DOWN ? +1 : -1) * vscroll.get_adjustment()->get_page_increment()); + else + hscroll.set_value (hscroll.get_value() + (direction==GDK_SCROLL_DOWN ? +1 : -1) * hscroll.get_adjustment()->get_page_increment()); +} + +static void scrollToEntry (double& h, double& v, int iw, int ih, ThumbBrowserEntryBase* entry) { + const int hmin = entry->getX (); + const int hmax = hmin + entry->getEffectiveWidth () - iw; + const int vmin = entry->getY (); + const int vmax = vmin + entry->getEffectiveHeight () - ih; + + if (hmin < 0) + h += hmin; + else if (hmax > 0) + h += hmax; + + if(vmin < 0) + v += vmin; + else if (vmax > 0) + v += vmax; +} + +void ThumbBrowserBase::selectPrev (int distance, bool enlarge) { + double h, v; + getScrollPosition (h, v); + + { + #if PROTECT_VECTORS + MYWRITERLOCK(l, entryRW); + #endif + + if (!selected.empty ()) { + std::vector::iterator front = std::find (fd.begin (), fd.end (), selected.front ()); + std::vector::iterator back = std::find (fd.begin (), fd.end (), selected.back ()); + std::vector::iterator last = std::find (fd.begin (), fd.end (), lastClicked); + + if (front > back) + std::swap(front, back); + + std::vector::iterator& curr = last == front ? front : back; + + // find next thumbnail at filtered distance before current + for (; curr >= fd.begin (); --curr) { + if (!(*curr)->filtered) { + if (distance-- == 0) { + // clear current selection + for (size_t i=0; iselected = false; + redrawNeeded (selected[i]); + } + selected.clear (); + + // make sure the newly selected thumbnail is visible and make it current + scrollToEntry (h, v, internal.get_width (), internal.get_height (), *curr); + lastClicked = *curr; + + // either enlarge current selection or set new selection + if(enlarge) { + // reverse direction if distance is too large + if(front > back) + std::swap(front, back); + + for (; front <= back; ++front) { + if (!(*front)->filtered) { + (*front)->selected = true; + redrawNeeded (*front); + selected.push_back (*front); + } + } + } + else { + (*curr)->selected = true; + redrawNeeded (*curr); + selected.push_back (*curr); + } + + break; + } + } + } + } + + #if PROTECT_VECTORS + MYWRITERLOCK_RELEASE(l); + #endif + selectionChanged (); + } + + setScrollPosition (h, v); +} + +void ThumbBrowserBase::selectNext (int distance, bool enlarge) { + double h, v; + getScrollPosition (h, v); + + { + #if PROTECT_VECTORS + MYWRITERLOCK(l, entryRW); + #endif + + if (!selected.empty ()) { + std::vector::iterator front = std::find (fd.begin (), fd.end (), selected.front ()); + std::vector::iterator back = std::find (fd.begin (), fd.end (), selected.back ()); + std::vector::iterator last = std::find (fd.begin (), fd.end (), lastClicked); + + if (front > back) + std::swap(front, back); + + std::vector::iterator& curr = last == back ? back : front; + + // find next thumbnail at filtered distance after current + for (; curr < fd.end (); ++curr) { + if (!(*curr)->filtered) { + if (distance-- == 0) { + // clear current selection + for (size_t i=0; iselected = false; + redrawNeeded (selected[i]); + } + selected.clear (); + + // make sure the newly selected thumbnail is visible and make it current + scrollToEntry (h, v, internal.get_width (), internal.get_height (), *curr); + lastClicked = *curr; + + // either enlarge current selection or set new selection + if(enlarge) { + // reverse direction if distance is too large + if(front > back) + std::swap(front, back); + + for (; front <= back; ++front) { + if (!(*front)->filtered) { + (*front)->selected = true; + redrawNeeded (*front); + selected.push_back (*front); + } + } + } + else { + (*curr)->selected = true; + redrawNeeded (*curr); + selected.push_back (*curr); + } + + break; + } + } + } + } + + #if PROTECT_VECTORS + MYWRITERLOCK_RELEASE(l); + #endif + selectionChanged (); + } + + setScrollPosition (h, v); +} + +void ThumbBrowserBase::selectFirst (bool enlarge) { + double h, v; + getScrollPosition (h, v); + + { + #if PROTECT_VECTORS + MYWRITERLOCK(l, entryRW); + #endif + + if (!fd.empty ()) { + // find first unfiltered entry + std::vector::iterator first = fd.begin (); + + for (; first < fd.end (); ++first) { + if (!(*first)->filtered) { + break; + } + } + + scrollToEntry (h, v, internal.get_width (), internal.get_height (), *first); + + ThumbBrowserEntryBase* lastEntry = lastClicked; + lastClicked = *first; + + if(selected.empty ()) { + (*first)->selected = true; + redrawNeeded (*first); + selected.push_back (*first); + } + else { + std::vector::iterator back = std::find (fd.begin (), fd.end (), lastEntry ? lastEntry : selected.back ()); + + if (first > back) + std::swap(first, back); + + // clear current selection + for (size_t i=0; iselected = false; + redrawNeeded (selected[i]); + } + selected.clear (); + + // either enlarge current selection or set new selection + for (; first <= back; ++first) { + if (!(*first)->filtered) { + (*first)->selected = true; + redrawNeeded (*first); + selected.push_back (*first); + } + + if (!enlarge) + break; + } + } + } + + #if PROTECT_VECTORS + MYWRITERLOCK_RELEASE(l); + #endif + selectionChanged (); + } + + setScrollPosition (h, v); +} + +void ThumbBrowserBase::selectLast (bool enlarge) { + double h, v; + getScrollPosition (h, v); + + { + #if PROTECT_VECTORS + MYWRITERLOCK(l, entryRW); + #endif + + if (!fd.empty ()) { + // find last unfiltered entry + std::vector::iterator last = fd.end () - 1; + + for (; last >= fd.begin (); --last) { + if (!(*last)->filtered) { + break; + } + } + + scrollToEntry (h, v, internal.get_width (), internal.get_height (), *last); + + ThumbBrowserEntryBase* lastEntry = lastClicked; + lastClicked = *last; + + if(selected.empty()) { + (*last)->selected = true; + redrawNeeded (*last); + selected.push_back (*last); + } + else { + std::vector::iterator front = std::find (fd.begin (), fd.end (), lastEntry ? lastEntry : selected.front ()); + + if (last < front) + std::swap(last, front); + + // clear current selection + for (size_t i=0; iselected = false; + redrawNeeded (selected[i]); + } + selected.clear (); + + // either enlarge current selection or set new selection + for (; front <= last; --last) { + if (!(*last)->filtered) { + (*last)->selected = true; + redrawNeeded (*last); + selected.push_back (*last); + } + + if (!enlarge) + break; + } + + std::reverse(selected.begin (), selected.end ()); + } + } + + #if PROTECT_VECTORS + MYWRITERLOCK_RELEASE(l); + #endif + selectionChanged (); + } + + setScrollPosition (h, v); +} + +void ThumbBrowserBase::resizeThumbnailArea (int w, int h) { + + inW = w; + inH = h; + + if (hscroll.get_value() + internal.get_width() > inW) + hscroll.set_value (inW - internal.get_width()); + if (vscroll.get_value() + internal.get_height() > inH) + vscroll.set_value (inH - internal.get_height()); + + configScrollBars (); +} + +void ThumbBrowserBase::internalAreaResized (Gtk::Allocation& req) { + + if (inW>0 && inH>0) { + configScrollBars (); + redraw (); + } +} + +void ThumbBrowserBase::configScrollBars () { + + // HOMBRE:DELETE ME? + GThreadLock tLock; // Acquire the GUI + + if (inW>0 && inH>0) { + + int iw = internal.get_width (); + int ih = internal.get_height (); + + hscroll.get_adjustment()->set_upper (inW); + vscroll.get_adjustment()->set_upper (inH); + hscroll.get_adjustment()->set_lower (0); + vscroll.get_adjustment()->set_lower (0); + hscroll.get_adjustment()->set_step_increment (32); + vscroll.get_adjustment()->set_step_increment (32); + hscroll.get_adjustment()->set_page_increment (iw); + vscroll.get_adjustment()->set_page_increment (ih); + hscroll.get_adjustment()->set_page_size (iw); + vscroll.get_adjustment()->set_page_size (ih); + + if(iw>=inW) + hscroll.hide(); + else + hscroll.show(); + + if(ih>=inH) + vscroll.hide(); + else + vscroll.show(); + } +} + +void ThumbBrowserBase::arrangeFiles () { + + #if PROTECT_VECTORS + MYREADERLOCK(l, entryRW); + #endif + + // GUI already locked by ::redraw, the only caller of this method for now. + // We could lock it one more time, there's no harm excepted (negligible) speed penalty + //GThreadLock lock; + + int N = fd.size (); + // apply filter + for (int i=0; ifiltered = !checkFilter (fd[i]); + + int rowHeight = 0; + // compute size of the items + for (int i=0; ifiltered && fd[i]->getMinimalHeight() > rowHeight) + rowHeight = fd[i]->getMinimalHeight (); + + if (arrangement==TB_Horizontal) { + numOfCols = 1; + int numOfRows = 1; +// if (rowHeight>0) { +// numOfRows = (internal.get_height()+rowHeight/2)/rowHeight; +// if (numOfRows<1) +// numOfRows = 1; +// } + + int ct = 0; + int currx = 0; int curry = 0; + while (ctgetMinimalWidth() > maxw) + maxw = fd[ct+i]->getMinimalWidth (); + + // arrange items in the column + curry = 0; + for (int i=0; ctfiltered) + fd[ct++]->drawable = false; + if (ctsetPosition (currx, curry, maxw, rowHeight); + fd[ct]->drawable = true; + curry += rowHeight; + } + } + currx += maxw; + } + #if PROTECT_VECTORS + MYREADERLOCK_RELEASE(l); + #endif + // This will require a Writer access + resizeThumbnailArea (currx, numOfRows*rowHeight); + } + else { + int availWidth = internal.get_width(); + // initial number of columns + numOfCols = 0; + int colsWidth = 0; + for (int i=0; ifiltered && colsWidth + fd[i]->getMinimalWidth() <= availWidth) { + colsWidth += fd[numOfCols]->getMinimalWidth (); + numOfCols++; + } + if (numOfCols<1) + numOfCols = 1; + std::vector colWidths; + for (; numOfCols>0; numOfCols--) { + // compute column widths + colWidths.resize (numOfCols); + for (int i=0; ifiltered && fd[i]->getMinimalWidth() > colWidths[j%numOfCols]) + colWidths[j%numOfCols] = fd[i]->getMinimalWidth (); + if (!fd[i]->filtered) + j++; + } + // if not wider than the space available, arrange it and we are ready + colsWidth = 0; + for (int i=0; ifiltered) + fd[ct++]->drawable = false; + if (ctsetPosition (currx, curry, colWidths[i%numOfCols], rowHeight); + fd[ct]->drawable = true; + currx += colWidths[i%numOfCols]; + } + } + if (currx>0) // there were thumbnails placed in the row + curry += rowHeight; + } + #if PROTECT_VECTORS + MYREADERLOCK_RELEASE(l); + #endif + // This will require a Writer access + resizeThumbnailArea (colsWidth, curry); + } +} + +void ThumbBrowserBase::disableInspector() { + if (inspector) + inspector->setActive(false); +} + +void ThumbBrowserBase::enableInspector() { + if (inspector) + inspector->setActive(true); +} + +void ThumbBrowserBase::Internal::on_realize() { + // Gtk signals automatically acquire the GUI (i.e. this method is enclosed by gdk_thread_enter and gdk_thread_leave) + Cairo::FontOptions cfo; + cfo.set_antialias (Cairo::ANTIALIAS_SUBPIXEL); + get_pango_context()->set_cairo_font_options (cfo); + + Gtk::DrawingArea::on_realize(); + Glib::RefPtr window = get_window(); + set_flags (Gtk::CAN_FOCUS); + add_events(Gdk::EXPOSURE_MASK | Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::POINTER_MOTION_MASK | Gdk::SCROLL_MASK | Gdk::KEY_PRESS_MASK); + gc_ = Gdk::GC::create(window); + set_has_tooltip (true); + signal_query_tooltip().connect( sigc::mem_fun(*this, &ThumbBrowserBase::Internal::on_query_tooltip) ); +} + +bool ThumbBrowserBase::Internal::on_query_tooltip (int x, int y, bool keyboard_tooltip, const Glib::RefPtr& tooltip) { + // Gtk signals automatically acquire the GUI (i.e. this method is enclosed by gdk_thread_enter and gdk_thread_leave) + Glib::ustring ttip = ""; + + { + #if PROTECT_VECTORS + MYREADERLOCK(l, parent->entryRW); + #endif + + for (size_t i=0; ifd.size(); i++) + if (parent->fd[i]->drawable && parent->fd[i]->inside (x, y)) { + ttip = parent->fd[i]->getToolTip (x, y); + break; + } + } + if (ttip!="") { + tooltip->set_markup (ttip); + return true; + } + else + return false; +} + +void ThumbBrowserBase::on_style_changed (const Glib::RefPtr& style) { + // GUI will be acquired by refreshThumbImages + refreshThumbImages (); +} + +ThumbBrowserBase::Internal::Internal () : ofsX(0), ofsY(0), parent(NULL), dirty(true) { +} + +void ThumbBrowserBase::Internal::setParent (ThumbBrowserBase* p) { + parent = p; +} + +void ThumbBrowserBase::Internal::setPosition (int x, int y) { + ofsX = x; + ofsY = y; +} + +bool ThumbBrowserBase::Internal::on_key_press_event (GdkEventKey* event) { + // Gtk signals automatically acquire the GUI (i.e. this method is enclosed by gdk_thread_enter and gdk_thread_leave) + return parent->keyPressed (event); +} + +bool ThumbBrowserBase::Internal::on_button_press_event (GdkEventButton* event) { + // Gtk signals automatically acquire the GUI (i.e. this method is enclosed by gdk_thread_enter and gdk_thread_leave) + grab_focus (); + + parent->eventTime = event->time; + + parent->buttonPressed ((int)event->x, (int)event->y, event->button, event->type, event->state, 0, 0, get_width(), get_height()); + Glib::RefPtr window = get_window(); + + GdkRectangle rect; + rect.x = 0; + rect.y = 0; + window->get_size (rect.width, rect.height); + + gdk_window_invalidate_rect (window->gobj(), &rect, true); + gdk_window_process_updates (window->gobj(), true); + + return true; +} + +void ThumbBrowserBase::buttonPressed (int x, int y, int button, GdkEventType type, int state, int clx, int cly, int clw, int clh) { + // GUI already acquired + + ThumbBrowserEntryBase* fileDescr = NULL; + bool handled = false; + + { + #if PROTECT_VECTORS + MYREADERLOCK(l, entryRW); + #endif + for (size_t i=0; idrawable) { + if (fd[i]->inside (x, y) && fd[i]->insideWindow (clx, cly, clw, clh)) + fileDescr = fd[i]; + bool b = fd[i]->pressNotify (button, type, state, x, y); + handled = handled || b; + } + } + + if (handled || (fileDescr && fileDescr->processing)) + return; + + { + #if PROTECT_VECTORS + MYWRITERLOCK(l, entryRW); + #endif + + if (selected.size()==1 && type==GDK_2BUTTON_PRESS && button==1) + doubleClicked (selected[0]); + else if (button==1 && type==GDK_BUTTON_PRESS) { + if (fileDescr && (state & GDK_SHIFT_MASK)) { + if (selected.empty()) { + selected.push_back (fileDescr); + fileDescr->selected = true; + lastClicked = fileDescr; + #if PROTECT_VECTORS + MYWRITERLOCK_RELEASE(l); + #endif + selectionChanged (); + } + else { + // find the start and the end of the selection interval + size_t startx = fd.size()-1; + if (lastClicked) { + for (; startx>0; startx--) + if (fd[startx]==lastClicked) + break; + } + else { + for (; startx>0; startx--) + if (fd[startx]==selected[0]) + break; + } + size_t endx = 0; + for (; endxselected = false; + selected.clear (); + // select thumbnails in the interval + for (size_t i=startx; i<=endx; i++) { + if (!fd[i]->filtered) { + fd[i]->selected = true; + selected.push_back (fd[i]); + } + } + lastClicked = fileDescr; + #if PROTECT_VECTORS + MYWRITERLOCK_RELEASE(l); + #endif + selectionChanged (); + } + } + else if (fileDescr && (state & GDK_CONTROL_MASK)) { + std::vector::iterator i = std::find (selected.begin(), selected.end(), fileDescr); + if (i!=selected.end()) { + (*i)->selected = false; + selected.erase (i); + } + else { + selected.push_back (fileDescr); + fileDescr->selected = true; + } + lastClicked = fileDescr; + #if PROTECT_VECTORS + MYWRITERLOCK_RELEASE(l); + #endif + selectionChanged (); + } + else { + for (size_t i=0; iselected = false; + selected.clear (); + if (fileDescr) { + selected.push_back (fileDescr); + fileDescr->selected = true; + } + lastClicked = fileDescr; + #if PROTECT_VECTORS + MYWRITERLOCK_RELEASE(l); + #endif + selectionChanged (); + } + } + else if (fileDescr && button==3 && type==GDK_BUTTON_PRESS) { + if (!fileDescr->selected) { + for (size_t i=0; iselected = false; + selected.clear (); + fileDescr->selected = true; + selected.push_back (fileDescr); + lastClicked = fileDescr; + #if PROTECT_VECTORS + MYWRITERLOCK_RELEASE(l); + #endif + selectionChanged (); + } + #if PROTECT_VECTORS + MYWRITERLOCK_RELEASE(l); + #endif + rightClicked (fileDescr); + } + } // end of MYWRITERLOCK(l, entryRW); + +} + +bool ThumbBrowserBase::Internal::on_expose_event(GdkEventExpose* event) { + // Gtk signals automatically acquire the GUI (i.e. this method is enclosed by gdk_thread_enter and gdk_thread_leave) + + dirty = false; + + Glib::RefPtr window = get_window(); + + int w = get_width(); + int h = get_height(); + + window->clear(); + // draw thumbnails + Glib::RefPtr context = get_pango_context (); + context->set_font_description (get_style()->get_font()); + + { + #if PROTECT_VECTORS + MYWRITERLOCK(l, parent->entryRW); + #endif + + for (size_t i=0; ifd.size() && !dirty; i++) { // if dirty meanwhile, cancel and wait for next redraw + if (!parent->fd[i]->drawable || !parent->fd[i]->insideWindow (0, 0, w, h)) + parent->fd[i]->updatepriority = false; + else { + parent->fd[i]->updatepriority = true; + parent->fd[i]->draw (); + } + } + } + + return true; +} + +bool ThumbBrowserBase::Internal::on_button_release_event (GdkEventButton* event) { + // Gtk signals automatically acquire the GUI (i.e. this method is enclosed by gdk_thread_enter and gdk_thread_leave) + int w = get_width(); + int h = get_height(); + + #if PROTECT_VECTORS + MYREADERLOCK(l, parent->entryRW); + #endif + + for (size_t i=0; ifd.size(); i++) + if (parent->fd[i]->drawable && parent->fd[i]->insideWindow (0, 0, w, h)) { + ThumbBrowserEntryBase* tbe = parent->fd[i]; + #if PROTECT_VECTORS + MYREADERLOCK_RELEASE(l); + #endif + // This will require a Writer access... + tbe->releaseNotify (event->button, event->type, event->state, (int)event->x, (int)event->y); + #if PROTECT_VECTORS + MYREADERLOCK_ACQUIRE(l); + #endif + } + return true; +} + +bool ThumbBrowserBase::Internal::on_motion_notify_event (GdkEventMotion* event) { + // Gtk signals automatically acquire the GUI (i.e. this method is enclosed by gdk_thread_enter and gdk_thread_leave) + int w = get_width(); + int h = get_height(); + + #if PROTECT_VECTORS + MYREADERLOCK(l, parent->entryRW); + #endif + + for (size_t i=0; ifd.size(); i++) + if (parent->fd[i]->drawable && parent->fd[i]->insideWindow (0, 0, w, h)) { + /*#if PROTECT_VECTORS + MYREADERLOCK_RELEASE(l); // motionNotify calls the queue, which locks + #endif*/ + parent->fd[i]->motionNotify ((int)event->x, (int)event->y); + } + return true; +} + +bool ThumbBrowserBase::Internal::on_scroll_event (GdkEventScroll* event) { + // Gtk signals automatically acquire the GUI (i.e. this method is enclosed by gdk_thread_enter and gdk_thread_leave) + + parent->scroll (event->direction); + return true; +} + + +void ThumbBrowserBase::redraw () { + + GThreadLock lock; + arrangeFiles (); + queue_draw (); +} + +void ThumbBrowserBase::zoomChanged (bool zoomIn) { + + int newHeight=0; + int optThumbSize=getThumbnailHeight(); + if (zoomIn) + for (size_t i=0; i optThumbSize) + break; + } + else + for (size_t i=options.thumbnailZoomRatios.size()-1; i>0; i--) { + newHeight = (int)(options.thumbnailZoomRatios[i] * getMaxThumbnailHeight()); + if (newHeight < optThumbSize) + break; + } + previewHeight = newHeight; + + saveThumbnailHeight(newHeight); + + { + #if PROTECT_VECTORS + MYWRITERLOCK(l, entryRW); + #endif + + for (size_t i=0; iresize (previewHeight); + } + + redraw (); +#ifdef WIN32 + gdk_window_process_updates (get_window()->gobj(), true); +#endif +} + +void ThumbBrowserBase::refreshThumbImages () { + + int previewHeight = getThumbnailHeight(); + { + #if PROTECT_VECTORS + MYWRITERLOCK(l, entryRW); + #endif + + for (size_t i=0; iresize (previewHeight); + } + + redraw (); +} + +void ThumbBrowserBase::refreshQuickThumbImages () { + #if PROTECT_VECTORS + MYWRITERLOCK(l, entryRW); + #endif + + for (size_t i=0; irefreshQuickThumbnailImage (); +} + +void ThumbBrowserBase::refreshEditedState (const std::set& efiles) { + + editedFiles = efiles; + { + #if PROTECT_VECTORS + MYREADERLOCK(l, entryRW); + #endif + + for (size_t i=0; iframed = editedFiles.find (fd[i]->filename)!=editedFiles.end(); + } + + queue_draw (); +} + +void ThumbBrowserBase::setArrangement (Arrangement a) { + + arrangement = a; + redraw (); +} + +void ThumbBrowserBase::enableTabMode(bool enable) { + location = enable ? THLOC_EDITOR : THLOC_FILEBROWSER; + arrangement = enable ? ThumbBrowserBase::TB_Horizontal : ThumbBrowserBase::TB_Vertical; + + if ((!options.sameThumbSize && (options.thumbSizeTab!=options.thumbSize)) || (options.showFileNames || options.filmStripShowFileNames)) { + #if PROTECT_VECTORS + MYWRITERLOCK(l, entryRW); + #endif + + for (size_t i=0; iresize (getThumbnailHeight()); + } + + redraw (); + + // Scroll to selected position if going into ribbon mode or back + // Tab mode is horizontal, file browser is vertical + { + #if PROTECT_VECTORS + MYREADERLOCK(l, entryRW); + #endif + + if (!selected.empty()) { + if (enable) { + double h=selected[0]->getStartX(); + #if PROTECT_VECTORS + MYREADERLOCK_RELEASE(l); + #endif + hscroll.set_value (min(h, hscroll.get_adjustment()->get_upper())); + } else { + double v=selected[0]->getStartY(); + #if PROTECT_VECTORS + MYREADERLOCK_RELEASE(l); + #endif + vscroll.set_value (min(v, vscroll.get_adjustment()->get_upper())); + } + } + } +} + +void ThumbBrowserBase::initEntry (ThumbBrowserEntryBase* entry) { + entry->setOffset ((int)(hscroll.get_value()), (int)(vscroll.get_value())); +} + +void ThumbBrowserBase::getScrollPosition (double& h, double& v) { + h = hscroll.get_value (); + v = vscroll.get_value (); +} + +void ThumbBrowserBase::setScrollPosition (double h, double v) { + hscroll.set_value (h>hscroll.get_adjustment()->get_upper() ? hscroll.get_adjustment()->get_upper() : h); + vscroll.set_value (v>vscroll.get_adjustment()->get_upper() ? vscroll.get_adjustment()->get_upper() : v); +} + +// needed for auto-height in single tab +int ThumbBrowserBase::getEffectiveHeight() { + int h=hscroll.get_height() + 2; // have 2 pixels rounding error for scroll bars to appear + + #if PROTECT_VECTORS + MYREADERLOCK(l, entryRW); + #endif + + // Filtered items do not change in size, so take a non-filtered + for (size_t i=0;ifiltered) { + h+=fd[i]->getEffectiveHeight(); + break; + } + + return h; +} + +void ThumbBrowserBase::redrawNeeded (ThumbBrowserEntryBase* entry) { + + // HOMBRE:DELETE ME? + GThreadLock tLock; // Acquire the GUI + + if (entry->insideWindow (0, 0, internal.get_width(), internal.get_height())) { + if (!internal.isDirty ()) { + internal.setDirty (); + internal.queue_draw (); + } + } +} + + diff --git a/rtgui/thumbbrowserbase.h b/rtgui/thumbbrowserbase.h new file mode 100644 index 000000000..046afda22 --- /dev/null +++ b/rtgui/thumbbrowserbase.h @@ -0,0 +1,159 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _THUMBNAILBROWSERBASE_ +#define _THUMBNAILBROWSERBASE_ + +#include +#include "thumbbrowserentrybase.h" +#include +#include "options.h" +#include "guiutils.h" +#include "inspector.h" + +/* + * Class handling the list of ThumbBrowserEntry objects and their position in it's allocated space + */ +class ThumbBrowserBase : public Gtk::VBox { + + class Internal : public Gtk::DrawingArea { + + Glib::RefPtr gc_; + int ofsX, ofsY; + ThumbBrowserBase* parent; + bool dirty; + public: + Internal (); + void setParent (ThumbBrowserBase* p); + void on_realize(); + bool on_expose_event(GdkEventExpose* event); + bool on_button_press_event (GdkEventButton* event); + bool on_button_release_event (GdkEventButton* event); + bool on_motion_notify_event (GdkEventMotion* event); + bool on_scroll_event (GdkEventScroll* event); + bool on_key_press_event (GdkEventKey* event); + bool on_query_tooltip (int x, int y, bool keyboard_tooltip, const Glib::RefPtr& tooltip); + void setPosition (int x, int y); + + void setDirty () { dirty = true; } + bool isDirty () { return dirty; } + }; + + public: + + enum eLocation { + THLOC_BATCHQUEUE, + THLOC_FILEBROWSER, + THLOC_EDITOR + } location; + + protected: + virtual int getMaxThumbnailHeight() const { return options.maxThumbnailHeight; } // Differs between batch and file + virtual void saveThumbnailHeight (int height)=0; + virtual int getThumbnailHeight ()=0; + + Internal internal; + Gtk::HScrollbar hscroll; + Gtk::VScrollbar vscroll; + + int inW, inH; + + Inspector *inspector; + bool isInspectorActive; + + + void resizeThumbnailArea (int w, int h); + void internalAreaResized (Gtk::Allocation& req); + void buttonPressed (int x, int y, int button, GdkEventType type, int state, int clx, int cly, int clw, int clh); + + public: + + void setInspector(Inspector* inspector) { this->inspector = inspector; } + Inspector* getInspector() { return inspector; } + void disableInspector(); + void enableInspector(); + enum Arrangement {TB_Horizontal, TB_Vertical}; + void configScrollBars (); + void scrollChanged (); + void scroll (int direction); + void scrollPage (int direction); + + void selectPrev (int distance, bool enlarge); + void selectNext (int distance, bool enlarge); + void selectFirst (bool enlarge); + void selectLast (bool enlarge); + + virtual bool isInTabMode() { return false; } + + eLocation getLocation() { return location; } + + protected: + + int eventTime; + + MyRWMutex entryRW; // Locks access to following 'fd' AND 'selected' + std::vector fd; + std::vector selected; + ThumbBrowserEntryBase* lastClicked; + + int previewHeight; + int numOfCols; + + Arrangement arrangement; + + std::set editedFiles; + + void arrangeFiles (); + void zoomChanged (bool zoomIn); + + public: + + ThumbBrowserBase (); + + void zoomIn () { zoomChanged (true); } + void zoomOut () { zoomChanged (false); } + int getEffectiveHeight (); + + const std::vector& getEntries () { return fd; } + void on_style_changed (const Glib::RefPtr& style); + void redraw (); // arrange files and draw area + void refreshThumbImages (); // refresh thumbnail sizes, re-generate thumbnail images, arrange and draw + void refreshQuickThumbImages (); // refresh thumbnail sizes, re-generate thumbnail images, arrange and draw + void refreshEditedState (const std::set& efiles); + + void initEntry (ThumbBrowserEntryBase* entry); + + void getScrollPosition (double& h, double& v); + void setScrollPosition (double h, double v); + + void setArrangement (Arrangement a); + void enableTabMode(bool enable); // set both thumb sizes and arrangements + + virtual bool checkFilter (ThumbBrowserEntryBase* entry) { return true; } + virtual void rightClicked (ThumbBrowserEntryBase* entry) {} + virtual void doubleClicked (ThumbBrowserEntryBase* entry) {} + virtual bool keyPressed (GdkEventKey* event) {return true;} + virtual void selectionChanged () {} + + virtual void redrawNeeded (ThumbBrowserEntryBase* entry); + virtual void thumbRearrangementNeeded () {} + + Gtk::Widget* getDrawingArea () { return &internal; } +}; + +#endif diff --git a/rtgui/thumbbrowserentry.cc b/rtgui/thumbbrowserentry.cc new file mode 100644 index 000000000..7703e9775 --- /dev/null +++ b/rtgui/thumbbrowserentry.cc @@ -0,0 +1,58 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 + +FileBrowserEntry::FileBrowserEntry (Thumbnail* thm, const Glib::ustring& fname) + : ThumbBrowserEntryBase (fname), thumbnail(thm) { + + previewOwner = false; + italicstyle = thumbnail->getType() != FT_Raw; + datetimeline = thumbnail->getDateTimeString (); + exifline = thumbnail->getExifString (); +} + +void ThumbBrowserEntry::obtainThumbnailSize () { + + if (thumbnail) + thumbnail->getThumbnailSize (prew, preh); +} +Glib::RefPtr ThumbBrowserEntry::editedIcon; +Glib::RefPtr ThumbBrowserEntry::recentlySavedIcon; +Glib::RefPtr ThumbBrowserEntry::enqueuedIcon; +std::vector > ThumbBrowserEntry::getIconsOnImageArea () { + + std::vector > ret; + + if (!thumbnail) + return ret; + + if (thumbnail->hasProcParams() && editedIcon) + ret.push_back (editedIcon); + if (thumbnail->isRecentlySaved() && recentlySavedIcon) + ret.push_back (recentlySavedIcon); + if (thumbnail->isEnqueued () && enqueuedIcon) + ret.push_back (enqueuedIcon); + + return ret; +} + +ThumbnailButtonSet* ThumbBrowserEntry::getThumbButtonSet () { + + return (ThumbnailButtonSet*)buttonSet; +} diff --git a/rtgui/thumbbrowserentrybase.cc b/rtgui/thumbbrowserentrybase.cc new file mode 100644 index 000000000..59d669c4f --- /dev/null +++ b/rtgui/thumbbrowserentrybase.cc @@ -0,0 +1,512 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "thumbbrowserentrybase.h" +#include "thumbbrowserbase.h" +#include "options.h" +#include "../rtengine/mytime.h" + +ThumbBrowserEntryBase::ThumbBrowserEntryBase (const Glib::ustring& fname) + : fnlabw(0), fnlabh(0), dtlabw(0), dtlabh(0), exlabw(0), exlabh(0), prew(0), preh(0), + prex(0), prey(0), upperMargin(6), borderWidth(1), textGap(6), sideMargin(8), lowerMargin(8), + preview(NULL), dispname(Glib::path_get_basename (fname)), buttonSet(NULL), width(0), height(0), + exp_width(0), exp_height(0), startx(0), starty(0), ofsX(0), ofsY(0), redrawRequests(0), + parent(NULL), bbSelected(false), bbFramed(false), bbPreview(NULL), + thumbnail(NULL), filename(fname), shortname(dispname), exifline(""), datetimeline(""), + selected(false), drawable(false), filtered(false), framed(false), processing(false), italicstyle(false), + edited(false), recentlysaved(false), updatepriority(false), withFilename(WFNAME_NONE) {} + +ThumbBrowserEntryBase::~ThumbBrowserEntryBase () { + + if (preview) delete [] preview; + delete buttonSet; +} + +void ThumbBrowserEntryBase::addButtonSet (LWButtonSet* bs) { + + buttonSet = bs; +} + +void ThumbBrowserEntryBase::updateBackBuffer () { + + if (!parent) + return; + + Gtk::Widget* w = parent->getDrawingArea (); + + Glib::RefPtr win = w->get_window(); + if (!win) + // Nothing to draw on, so we return + return; + + backBuffer = Gdk::Pixmap::create (win, exp_width, exp_height); + + // If thumbnail is hidden by a filter drawing to it will crash + int backbuffer_w=0, backbuffer_h=0; + backBuffer->get_size(backbuffer_w, backbuffer_h); + // if either with or height is zero then return early + if (backbuffer_w * backbuffer_h == 0) return; + + bbSelected = selected; + bbFramed = framed; + bbPreview = preview; + + Glib::RefPtr gc_ = Gdk::GC::create (backBuffer); + + Gdk::Color textn = w->get_style()->get_text(Gtk::STATE_NORMAL); + Gdk::Color texts = w->get_style()->get_text(Gtk::STATE_SELECTED); + Gdk::Color bgn = w->get_style()->get_bg(Gtk::STATE_NORMAL); + Gdk::Color bgs = w->get_style()->get_bg(Gtk::STATE_SELECTED); + + // clear area, draw frames and background + gc_->set_foreground (bgn); + gc_->set_background (bgn); + backBuffer->draw_rectangle (gc_, true, 0, 0, exp_width, exp_height); + Cairo::RefPtr cr = backBuffer->create_cairo_context(); + drawFrame (cr, bgs, bgn); + + // calculate height of button set + int bsHeight = 0; + if (buttonSet) { + int tmp; + buttonSet->getAllocatedDimensions (tmp, bsHeight); + } + + // draw preview frame + //backBuffer->draw_rectangle (gc_, false, (exp_width-prew)/2, upperMargin+bsHeight, prew+1, preh+1); + // draw thumbnail image + if (preview) { + prex = borderWidth + (exp_width-prew)/2; + prey = upperMargin+bsHeight+borderWidth; + backBuffer->draw_rgb_image (gc_, prex, prey, prew, preh, Gdk::RGB_DITHER_NONE, preview, prew*3); + } + + customBackBufferUpdate (cr); + + // draw icons onto the thumbnail area + bbIcons = getIconsOnImageArea (); + + int infow, infoh; + getTextSizes (infow, infoh); + + int iofs_x = 4, iofs_y = 4; + int igap = 2; + int istartx = prex; + int istarty = prey; + + if ((parent->getLocation()!=ThumbBrowserBase::THLOC_EDITOR && options.showFileNames && options.overlayedFileNames) + || (parent->getLocation()==ThumbBrowserBase::THLOC_EDITOR && options.filmStripShowFileNames && options.filmStripOverlayedFileNames)) { + cr->begin_new_path (); + cr->rectangle (istartx, istarty, prew, fnlabh+dtlabh+exlabh+2*iofs_y); + if ((texts.get_red_p()+texts.get_green_p()+texts.get_blue_p())/3 > 0.5) + cr->set_source_rgba (0, 0, 0, 0.5); + else + cr->set_source_rgba (1, 1, 1, 0.5); + cr->fill (); + } + + istartx += iofs_x; + istarty += iofs_y; + + if (!bbIcons.empty()) { + int iwidth = 0; + int iheight = 0; + for (size_t i=0; iget_width() + (i>0 ? igap : 0); + if (bbIcons[i]->get_height() > iheight) + iheight = bbIcons[i]->get_height(); + } + if ((parent->getLocation()!=ThumbBrowserBase::THLOC_EDITOR && (!options.showFileNames || !options.overlayedFileNames)) + || (parent->getLocation()==ThumbBrowserBase::THLOC_EDITOR && (!options.filmStripShowFileNames || !options.filmStripOverlayedFileNames))) { + // Draw the transparent black background around icons + cr->begin_new_path (); + cr->move_to(istartx-igap, istarty); + cr->rel_line_to(igap, -igap); + cr->rel_line_to(iwidth, 0); + cr->rel_line_to(igap, igap); + cr->rel_line_to(0, iheight); + cr->rel_line_to(-igap, igap); + cr->rel_line_to(-iwidth, 0); + cr->rel_line_to(-igap, -igap); + cr->rel_line_to(0, -iheight); + cr->set_source_rgba (0, 0, 0, 0.6); + cr->fill (); + } + for (size_t i=0; idraw_pixbuf (gc_, bbIcons[i], 0, 0, istartx, istarty, bbIcons[i]->get_width(), bbIcons[i]->get_height(), Gdk::RGB_DITHER_NONE, 0, 0); + istartx += bbIcons[i]->get_width() + igap; + } + } + + if ( ( (parent->getLocation()!=ThumbBrowserBase::THLOC_EDITOR && options.showFileNames) + || (parent->getLocation()==ThumbBrowserBase::THLOC_EDITOR && options.filmStripShowFileNames)) + && withFilename>WFNAME_NONE) + { + int textposx_fn, textposx_ex, textposx_dt, textposy, textw; + if (! ((parent->getLocation()!=ThumbBrowserBase::THLOC_EDITOR && options.overlayedFileNames) + || (parent->getLocation()==ThumbBrowserBase::THLOC_EDITOR && options.filmStripOverlayedFileNames)) ) + { + textposx_fn = exp_width/2 - fnlabw/2; + if (textposx_fn<0) textposx_fn = 0; + textposx_ex = exp_width/2 - exlabw/2; + if (textposx_ex<0) textposx_ex = 0; + textposx_dt = exp_width/2 - dtlabw/2; + if (textposx_dt<0) textposx_dt = 0; + textposy = upperMargin + bsHeight + 2*borderWidth + preh + borderWidth + textGap; + textw = exp_width - 2*textGap; + gc_->set_foreground (selected ? texts : textn); + } + else { + textposx_fn = istartx; + textposx_ex = istartx; + textposx_dt = istartx; + textposy = istarty; + textw = prew - (istartx - prex); + gc_->set_foreground (texts); + } + + // draw file name + Glib::RefPtr context = w->get_pango_context () ; + Pango::FontDescription fontd = context->get_font_description (); + fontd.set_weight (Pango::WEIGHT_BOLD); + if (italicstyle) + fontd.set_style (Pango::STYLE_ITALIC); + else + fontd.set_style (Pango::STYLE_NORMAL); + + context->set_font_description (fontd); + Glib::RefPtr fn = w->create_pango_layout (dispname); + fn->set_width (textw*Pango::SCALE); + fn->set_ellipsize (Pango::ELLIPSIZE_MIDDLE); + backBuffer->draw_layout(gc_, textposx_fn, textposy, fn); + + fontd.set_weight (Pango::WEIGHT_NORMAL); + fontd.set_style (Pango::STYLE_NORMAL); + context->set_font_description (fontd); + + if (withFilename==WFNAME_FULL) { + // draw date/time label + int tpos = fnlabh; + if (options.fbShowDateTime && datetimeline!="") { + fn = w->create_pango_layout (datetimeline); + fn->set_width (textw*Pango::SCALE); + fn->set_ellipsize (Pango::ELLIPSIZE_MIDDLE); + backBuffer->draw_layout(gc_, textposx_dt, textposy + tpos, fn); + tpos += dtlabh; + } + // draw basic exif info + if (options.fbShowBasicExif && exifline!="") { + fn = w->create_pango_layout (exifline); + fn->set_width (textw*Pango::SCALE); + fn->set_ellipsize (Pango::ELLIPSIZE_MIDDLE); + backBuffer->draw_layout (gc_, textposx_ex, textposy + tpos, fn); + tpos += exlabh; + } + } + } +} + +void ThumbBrowserEntryBase::getTextSizes (int& infow, int& infoh) { + + if (!parent) + return; + + Gtk::Widget* w = parent->getDrawingArea (); + + // calculate dimensions of the text based fields + dispname = shortname; + + Glib::RefPtr context = w->get_pango_context () ; + context->set_font_description (w->get_style()->get_font()); + + // filename: + Pango::FontDescription fontd = context->get_font_description (); + fontd.set_weight (Pango::WEIGHT_BOLD); + context->set_font_description (fontd); + Glib::RefPtr fn = w->create_pango_layout(shortname); + fn->get_pixel_size (fnlabw, fnlabh); + + // calculate cummulated height of all info fields + infoh = fnlabh; + infow = 0; + + if (withFilename==WFNAME_FULL) { + // datetime + fontd.set_weight (Pango::WEIGHT_NORMAL); + context->set_font_description (fontd); + fn = w->create_pango_layout (datetimeline); + fn->get_pixel_size (dtlabw, dtlabh); + + // basic exif data + fn = w->create_pango_layout (exifline); + fn->get_pixel_size (exlabw, exlabh); + + // add date/tile size: + if (options.fbShowDateTime) { + infoh += dtlabh; + if (dtlabw + 2*sideMargin > infow) + infow = dtlabw + 2*sideMargin; + } + else { + dtlabw = dtlabh = 0; + } + if (options.fbShowBasicExif) { + infoh += exlabh; + if (exlabw + 2*sideMargin > infow) + infow = exlabw + 2*sideMargin; + } + else { + exlabw = exlabh = 0; + } + } + else { + dtlabw = dtlabh = exlabw = exlabh = 0; + } +} + +void ThumbBrowserEntryBase::resize (int h) { + + #if PROTECT_VECTORS + MYWRITERLOCK(l, lockRW); + #endif + + height = h; + int old_preh = preh, old_width = width; + + // dimensions of the button set + int bsw=0, bsh=0; + if (buttonSet) + buttonSet->getMinimalDimensions (bsw, bsh); + + if (parent->getLocation() == ThumbBrowserBase::THLOC_FILEBROWSER) { + if (options.showFileNames) + withFilename = WFNAME_FULL; + else + withFilename = WFNAME_NONE; + } + else if (parent->getLocation() == ThumbBrowserBase::THLOC_BATCHQUEUE) { + withFilename = WFNAME_REDUCED; + } + else { + if (options.filmStripShowFileNames) + withFilename = WFNAME_REDUCED; + else + withFilename = WFNAME_NONE; + } + + // calculate the height remaining for the thumbnail image + preh = height - upperMargin - 2*borderWidth - lowerMargin - bsh; + int infow=0; + int infoh=0; + if ( (parent->getLocation()!=ThumbBrowserBase::THLOC_EDITOR && options.showFileNames && !options.overlayedFileNames) + || (parent->getLocation()==ThumbBrowserBase::THLOC_EDITOR && options.filmStripShowFileNames && !options.filmStripOverlayedFileNames)) + { + // dimensions of the info text + getTextSizes (infow, infoh); + infoh += textGap; + //preh -= infoh; + height += infoh; + } + // Minimum size for thumbs + if (preh<24){ + preh=24; + height = preh + (upperMargin + 2*borderWidth + lowerMargin)+ bsh + infoh; + } + + calcThumbnailSize (); // recalculates prew + + width = prew + 2*sideMargin + 2*borderWidth; + if ( (parent->getLocation()!=ThumbBrowserBase::THLOC_EDITOR && options.showFileNames && !options.overlayedFileNames) + || (parent->getLocation()==ThumbBrowserBase::THLOC_EDITOR && options.filmStripShowFileNames && !options.filmStripOverlayedFileNames)) + { + width = prew + 2*sideMargin + 2*borderWidth; + if (width cr, const Gdk::Color& bg, const Gdk::Color& fg) { + + int radius = 8; + if (selected || framed) { + cr->set_antialias (Cairo::ANTIALIAS_SUBPIXEL); + cr->move_to (radius, 0); + cr->arc (exp_width-1-radius, radius, radius, -M_PI/2, 0); + cr->arc (exp_width-1-radius, exp_height-1-radius, radius, 0, M_PI/2); + cr->arc (radius, exp_height-1-radius, radius, M_PI/2, M_PI); + cr->arc (radius, radius, radius, M_PI, -M_PI/2); + cr->close_path (); + if (selected) { + cr->set_source_rgb (bg.get_red_p(), bg.get_green_p(), bg.get_blue_p()); + cr->fill_preserve (); + } + cr->set_source_rgb (bg.get_red_p()*2/3, bg.get_green_p()*2/3, bg.get_blue_p()*2/3); + cr->set_line_width (1.0); + cr->stroke (); + + } + + if (framed) { + cr->set_antialias (Cairo::ANTIALIAS_SUBPIXEL); + cr->move_to (+2+0.5+radius, +2+0.5); + cr->arc (-2+0.5+exp_width-1-radius, +2+0.5+radius, radius, -M_PI/2, 0); + cr->arc (-2+0.5+exp_width-1-radius, -2+0.5+exp_height-1-radius, radius, 0, M_PI/2); + cr->arc (+2+0.5+radius, -2+exp_height-1-radius, radius, M_PI/2, M_PI); + cr->arc (+2+0.5+radius, +2+radius, radius, M_PI, -M_PI/2); + cr->close_path (); + cr->set_source_rgb (fg.get_red_p(), fg.get_green_p(), fg.get_blue_p()); + cr->set_line_width (2.0); + cr->stroke (); + } +} + +void ThumbBrowserEntryBase::draw () { + + if (!drawable || !parent) + return; + + #if PROTECT_VECTORS + MYREADERLOCK(l, lockRW); // No resizes, position moves etc. inbetween + #endif + + int bbWidth, bbHeight; + if (backBuffer) + backBuffer->get_size (bbWidth, bbHeight); + + if (!backBuffer || selected!=bbSelected || framed!=bbFramed || preview!=bbPreview + || exp_width!=bbWidth || exp_height!=bbHeight || getIconsOnImageArea ()!=bbIcons) + updateBackBuffer (); + + Gtk::Widget* w = parent->getDrawingArea (); + + Glib::RefPtr gc_ = Gdk::GC::create (w->get_window()); + + // Gdk::Color textn = w->get_style()->get_text(Gtk::STATE_NORMAL); + // Gdk::Color texts = w->get_style()->get_text(Gtk::STATE_SELECTED); + Gdk::Color bgn = w->get_style()->get_bg(Gtk::STATE_NORMAL); + Gdk::Color bgs = w->get_style()->get_bg(Gtk::STATE_SELECTED); + + w->get_window()->draw_drawable (gc_, backBuffer, 0, 0, startx + ofsX, starty + ofsY); + + // check icon set changes!!! + +// drawProgressBar (window, gc_, selected ? texts : textn, selected ? bgs : bgn, ofsX+startx, exp_width, ofsY+starty + upperMargin+bsHeight+borderWidth+preh+borderWidth+textGap+tpos, fnlabh); + + // redraw button set above the thumbnail + if (buttonSet) { + buttonSet->setColors (selected ? bgs : bgn, selected ? bgn : bgs); + Cairo::RefPtr cc = w->get_window()->create_cairo_context(); + buttonSet->redraw (cc); + } +} + +void ThumbBrowserEntryBase::setPosition (int x, int y, int w, int h) { + + #if PROTECT_VECTORS + MYWRITERLOCK(l, lockRW); + #endif + + exp_width = w; + exp_height = h; + startx = x; + starty = y; + + if (buttonSet) + buttonSet->arrangeButtons (ofsX+x+sideMargin, ofsY+y+upperMargin, w-2*sideMargin, -1); +} + +void ThumbBrowserEntryBase::setOffset (int x, int y) { + + #if PROTECT_VECTORS + MYWRITERLOCK(l, lockRW); + #endif + + ofsX = -x; + ofsY = -y; + + if (buttonSet) + buttonSet->move (ofsX+startx+sideMargin, ofsY+starty+upperMargin); +} + +bool ThumbBrowserEntryBase::inside (int x, int y) { + + return x>ofsX+startx && xofsY+starty && y=prex && x<=prex+prew && y>=prey && y<=prey+preh) { + coord.x = double(x-prex)/double(prew); + coord.y = double(y-prey)/double(preh); + } + } +} + +bool ThumbBrowserEntryBase::insideWindow (int x, int y, int w, int h) { + + return !(ofsX+startx>x+w || ofsX+startx+exp_widthy+h || ofsY+starty+exp_heightmotionNotify (x, y) : false; +} + +bool ThumbBrowserEntryBase::pressNotify (int button, int type, int bstate, int x, int y) { + + return buttonSet ? buttonSet->pressNotify (x, y) : false; +} + +bool ThumbBrowserEntryBase::releaseNotify (int button, int type, int bstate, int x, int y) { + + return buttonSet ? buttonSet->releaseNotify (x, y) : false; +} + +Glib::ustring ThumbBrowserEntryBase::getToolTip (int x, int y) { + Glib::ustring tooltip = ""; + + if (buttonSet) tooltip = buttonSet->getToolTip (x, y); + + // if the fileinfo is not shown anyway, make a tooltip with the info + if (withFilename + * + * 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 _THUMBNAILBROWSERENTRYBASE_ +#define _THUMBNAILBROWSERENTRYBASE_ + +#include +#include "lwbuttonset.h" +#include "thumbnail.h" +#include "threadutils.h" + +class ThumbBrowserBase; +class ThumbBrowserEntryBase { + +public: + enum eWithFilename { + WFNAME_NONE, + WFNAME_REDUCED, + WFNAME_FULL + }; + +protected: + int fnlabw, fnlabh; // dimensions of the filename label + int dtlabw, dtlabh; // dimensions of the date/time label + int exlabw, exlabh; // dimensions of the exif label + int prew; // width of the thumbnail + int preh; // height of the thumbnail + int prex; + int prey; + + int upperMargin; + int borderWidth; + int textGap; + int sideMargin; + int lowerMargin; + + + MyRWMutex lockRW; // Locks access to all image thumb changing actions + + guint8* preview; // holds the preview image. used in updateBackBuffer. TODO Olli: Make a cache to reduce mem significantly + + Glib::ustring dispname; + + LWButtonSet* buttonSet; + + int width; // minimal width + int height; // minimal height +// set by arrangeFiles() of thumbbrowser + int exp_width; // arranged width (backbuffer dimensions) + int exp_height; // arranged height + int startx; // x coord. in the widget + int starty; // y coord. in the widget + + int ofsX, ofsY; // offset due to the scrolling of the parent + + int redrawRequests; + + ThumbBrowserBase* parent; + + Glib::RefPtr backBuffer; + bool bbSelected, bbFramed; + guint8* bbPreview; + std::vector > bbIcons; + + void drawFrame (Cairo::RefPtr cr, const Gdk::Color& bg, const Gdk::Color& fg); + void getTextSizes (int& w, int& h); + + // called during updateBackBuffer for custom overlays + virtual void customBackBufferUpdate (Cairo::RefPtr c) {} + + public: + + Thumbnail* thumbnail; + +// thumbnail preview properties: + Glib::ustring filename; + Glib::ustring shortname; + Glib::ustring exifline; + Glib::ustring datetimeline; + +// misc attributes + bool selected; + bool drawable; + bool filtered; + bool framed; + bool processing; + bool italicstyle; + bool edited; + bool recentlysaved; + bool updatepriority; + eWithFilename withFilename; + + ThumbBrowserEntryBase (const Glib::ustring& fname); + virtual ~ThumbBrowserEntryBase (); + + void setParent (ThumbBrowserBase* l) { parent = l; } + + void updateBackBuffer (); + void resize (int h); + virtual void draw (); + + void addButtonSet (LWButtonSet* bs); + int getMinimalHeight () { return height; } + int getMinimalWidth () { return width; } + + int getEffectiveWidth () const { return exp_width; } + int getEffectiveHeight () const { return exp_height; } + int getPreviewHeight () const { return preh; } + int getStartX () const { return startx; } + int getStartY () const { return starty; } + int getX () const { return ofsX+startx; } + int getY () const { return ofsY+starty; } + + bool inside (int x, int y); + void getPosInImgSpace (int x, int y, rtengine::Coord2D &coord); + bool insideWindow (int x, int y, int w, int h); + void setPosition (int x, int y, int w, int h); + void setOffset (int x, int y); + + bool operator< (ThumbBrowserEntryBase& other) { return shortname.casefold()>other.shortname.casefold(); } + + virtual void refreshThumbnailImage () {} + virtual void refreshQuickThumbnailImage () {} + virtual void calcThumbnailSize () {} + + virtual void drawProgressBar (Glib::RefPtr win, Glib::RefPtr gc, const Gdk::Color& foregr, const Gdk::Color& backgr, int x, int w, int y, int h) {} + + virtual std::vector > getIconsOnImageArea () { std::vector > r; return r; } + virtual void getIconSize (int& w, int& h) { w=0; h=0; } + + virtual bool motionNotify (int x, int y); + virtual bool pressNotify (int button, int type, int bstate, int x, int y); + virtual bool releaseNotify (int button, int type, int bstate, int x, int y); + virtual Glib::ustring getToolTip (int x, int y); +}; + +#endif diff --git a/rtgui/thumbimageupdater.cc b/rtgui/thumbimageupdater.cc new file mode 100644 index 000000000..03ae89da3 --- /dev/null +++ b/rtgui/thumbimageupdater.cc @@ -0,0 +1,323 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "thumbimageupdater.h" +#include +#include "guiutils.h" +#include "threadutils.h" + +#ifdef _OPENMP +#include +#endif + +#define DEBUG(format,args...) +//#define DEBUG(format,args...) printf("ThumbImageUpdate::%s: " format "\n", __FUNCTION__, ## args) + +class +ThumbImageUpdater::Impl +{ +public: + + struct Job + { + Job(ThumbBrowserEntryBase* tbe, bool* priority, bool upgrade, + ThumbImageUpdateListener* listener): + tbe_(tbe), + /*pparams_(pparams), + height_(height), */ + priority_(priority), + upgrade_(upgrade), + listener_(listener) + {} + + Job(): + tbe_(0), + priority_(NULL), + upgrade_(false), + listener_(0) + {} + + ThumbBrowserEntryBase* tbe_; + /*rtengine::procparams::ProcParams pparams_; + int height_;*/ + bool* priority_; + bool upgrade_; + ThumbImageUpdateListener* listener_; + }; + + typedef std::list JobList; + + Impl(): + active_(0), + inactive_waiting_(false) + { + int threadCount = 1; +#if !(__GNUC__ == 4 && __GNUC_MINOR__ == 8 && defined( WIN32 ) && defined(__x86_64__)) + // See Issue 2431 for explanation + #ifdef _OPENMP + threadCount = omp_get_num_procs(); + #endif +#endif + + threadPool_=new Glib::ThreadPool(threadCount,0); + } + + Glib::ThreadPool* threadPool_; + + // Need to be a Glib::Threads::Mutex because used in a Glib::Threads::Cond object... + // This is the only exceptions in RT so far, MyMutex is used everywhere else + #ifdef WIN32 + Glib::Mutex mutex_; + #else + Glib::Threads::Mutex mutex_; + #endif + + JobList jobs_; + + unsigned int active_; + + bool inactive_waiting_; + + #ifdef WIN32 + Glib::Cond inactive_; + #else + Glib::Threads::Cond inactive_; + #endif + + void + processNextJob() + { + Job j; + + { + #ifdef WIN32 + Glib::Mutex::Lock lock(mutex_); + #else + Glib::Threads::Mutex::Lock lock(mutex_); + #endif + + // nothing to do; could be jobs have been removed + if ( jobs_.empty() ) + { + DEBUG("processing: nothing to do (%d)",jobs_.empty()); + return; + } + + JobList::iterator i; + + // see if any priority jobs exist + for ( i = jobs_.begin(); i != jobs_.end(); ++i) + { + if ( *(i->priority_) ) + { + DEBUG("processing(priority) %s",i->tbe_->thumbnail->getFileName().c_str()); + break; + } + } + + // see if any none upgrade jobs exist + if ( i == jobs_.end() ) + { + for ( i = jobs_.begin(); i != jobs_.end(); ++i) + { + if ( !i->upgrade_ ) + { + DEBUG("processing(not-upgrade) %s",i->tbe_->thumbnail->getFileName().c_str()); + break; + } + } + } + + // if none, then use first + if ( i == jobs_.end() ) + { + i = jobs_.begin(); + DEBUG("processing(first) %s",i->tbe_->thumbnail->getFileName().c_str()); + } + + // copy found job + j = *i; + + // remove so not run again + jobs_.erase(i); + DEBUG("%d job(s) remaining", int(jobs_.size()) ); + + ++active_; + } + + // unlock and do processing; will relock on block exit, then call listener + double scale = 1.0; + rtengine::IImage8* img = 0; + Thumbnail* thm=j.tbe_->thumbnail; + + if ( j.upgrade_ ) + { + if ( thm->isQuick() ) + { + img = thm->upgradeThumbImage(thm->getProcParams(), j.tbe_->getPreviewHeight(), scale); + } + } + else + { + img = thm->processThumbImage(thm->getProcParams(), j.tbe_->getPreviewHeight(), scale); + } + + if (img) + { + DEBUG("pushing image %s",thm->getFileName().c_str()); + j.listener_->updateImage(img, scale, thm->getProcParams().crop); + } + + { + #ifdef WIN32 + Glib::Mutex::Lock lock(mutex_); + #else + Glib::Threads::Mutex::Lock lock(mutex_); + #endif + + + if ( --active_ == 0 && + inactive_waiting_ ) + { + inactive_waiting_ = false; + inactive_.signal(); + } + } + } +}; + +ThumbImageUpdater* +ThumbImageUpdater::getInstance(void) +{ + // this will not be deleted... + static ThumbImageUpdater* instance_ = 0; + if ( instance_ == 0 ) + { + instance_ = new ThumbImageUpdater(); + } + return instance_; +} + +ThumbImageUpdater::ThumbImageUpdater(): + impl_(new Impl()) +{ +} + +void +ThumbImageUpdater::add(ThumbBrowserEntryBase* tbe, bool* priority, bool upgrade, ThumbImageUpdateListener* l) +{ + // nobody listening? + if ( l == 0 ) + { + return; + } + + #ifdef WIN32 + Glib::Mutex::Lock lock(impl_->mutex_); + #else + Glib::Threads::Mutex::Lock lock(impl_->mutex_); + #endif + + // look up if an older version is in the queue + Impl::JobList::iterator i(impl_->jobs_.begin()); + for ( ; i != impl_->jobs_.end(); ++i ) + { + if ( i->tbe_ == tbe && + i->listener_ == l && + i->upgrade_ == upgrade ) + { + DEBUG("updating job %s",tbe->shortname.c_str()); + // we have one, update queue entry, will be picked up by thread when processed + /*i->pparams_ = params; + i->height_ = height; */ + i->priority_ = priority; + return; + } + } + + // create a new job and append to queue + DEBUG("queing job %s",tbe->shortname.c_str()); + impl_->jobs_.push_back(Impl::Job(tbe,priority,upgrade,l)); + + DEBUG("adding run request %s",tbe->shortname.c_str()); + impl_->threadPool_->push(sigc::mem_fun(*impl_, &ThumbImageUpdater::Impl::processNextJob)); +} + + +void +ThumbImageUpdater::removeJobs(ThumbImageUpdateListener* listener) +{ + DEBUG("removeJobs(%p)",listener); + + #ifdef WIN32 + Glib::Mutex::Lock lock(impl_->mutex_); + #else + Glib::Threads::Mutex::Lock lock(impl_->mutex_); + #endif + + for( Impl::JobList::iterator i(impl_->jobs_.begin()); i != impl_->jobs_.end(); ) + { + if (i->listener_ == listener) + { + DEBUG("erasing specific job"); + Impl::JobList::iterator e(i++); + impl_->jobs_.erase(e); + } + else + { + ++i; + } + } + + while ( impl_->active_ != 0 ) + { + // XXX this is nasty... it would be nicer if we weren't called with + // this lock held + GThreadUnLock unlock; + DEBUG("waiting for running jobs1"); + impl_->inactive_waiting_ = true; + impl_->inactive_.wait(impl_->mutex_); + } +} + +void +ThumbImageUpdater::removeAllJobs(void) +{ + DEBUG("stop"); + + #ifdef WIN32 + Glib::Mutex::Lock lock(impl_->mutex_); + #else + Glib::Threads::Mutex::Lock lock(impl_->mutex_); + #endif + + impl_->jobs_.clear(); + + while ( impl_->active_ != 0 ) + { + // XXX this is nasty... it would be nicer if we weren't called with + // this lock held + GThreadUnLock unlock; + DEBUG("waiting for running jobs2"); + impl_->inactive_waiting_ = true; + impl_->inactive_.wait(impl_->mutex_); + } +} + diff --git a/rtgui/thumbimageupdater.h b/rtgui/thumbimageupdater.h new file mode 100644 index 000000000..fa459b1ad --- /dev/null +++ b/rtgui/thumbimageupdater.h @@ -0,0 +1,100 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _THUMBIMAGEUPDATER_ +#define _THUMBIMAGEUPDATER_ + +#include +#include "../rtengine/rtengine.h" +#include "thumbbrowserentrybase.h" +#include + +class ThumbImageUpdateListener { + +public: + + /** + * @brief Called when thumbnail image is update + * + * @param img new thumbnail image + * @param scale scale (??) + * @param cropParams how it was cropped (??) + * + * @note no locks are held when called back + */ + virtual void updateImage (rtengine::IImage8* img, double scale, rtengine::procparams::CropParams cropParams) {} +}; + +class ThumbImageUpdater { + + public: + + /** + * @brief Singleton entry point. + * + * @return Pointer to thumbnail image updater. + */ + static ThumbImageUpdater* getInstance(void); + + /** + * @brief Add an thumbnail image update request. + * + * Code will add the request to the queue and, if needed, start a pool + * thread to process it. + * + * @param t thumbnail + * @param params processing params (?) + * @param height how big + * @param priority if \c true then run as soon as possible + * @param l listener waiting on update + */ + void add(ThumbBrowserEntryBase* tbe, bool* priority, bool upgrade, ThumbImageUpdateListener* l); + + /** + * @brief Remove jobs associated with listener \c l. + * + * Jobs being processed will be finished. Will not return till all jobs for + * \c l have been completed. + * + * @param listener jobs associated with this will be stopped + */ + void removeJobs(ThumbImageUpdateListener* listener); + + /** + * @brief Stop processing and remove all jobs. + * + * Will not return till all running jobs have completed. + */ + void removeAllJobs(void); + + private: + + ThumbImageUpdater(); + + class Impl; + Impl* impl_; +}; + +/** + * @brief Singleton boiler plate. + * + * To use: \c thumbImageUpdater->start() , + */ +#define thumbImageUpdater ThumbImageUpdater::getInstance() + +#endif diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc new file mode 100644 index 000000000..3de27c54a --- /dev/null +++ b/rtgui/thumbnail.cc @@ -0,0 +1,920 @@ +/* + * This file is part of RawTherapee. + * + * + * 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 "multilangmgr.h" +#include "thumbnail.h" +#include +#include +#include "options.h" +#include "../rtengine/mytime.h" +#include +#include +#include +#include "../rtengine/imagedata.h" +#include +#include "guiutils.h" +#include "profilestore.h" +#include "batchqueue.h" +#include "../rtengine/safegtk.h" + +using namespace rtengine::procparams; + +Thumbnail::Thumbnail (CacheManager* cm, const Glib::ustring& fname, CacheImageData* cf) + : fname(fname), cfs(*cf), cachemgr(cm), ref(1), enqueueNumber(0), tpp(NULL), + pparamsValid(false), needsReProcessing(true),imageLoading(false), lastImg(NULL), + lastW(0), lastH(0), lastScale(0), initial_(false) +{ + + loadProcParams (); + + // should be safe to use the unprotected version of loadThumbnail, since we are in the constructor + _loadThumbnail (); + generateExifDateTimeStrings (); + + if (cfs.rankOld >= 0){ + // rank and inTrash were found in cache (old style), move them over to pparams + + // try to load the last saved parameters from the cache or from the paramfile file + createProcParamsForUpdate(false, false); // this can execute customprofilebuilder to generate param file + + // TODO? should we call notifylisterners_procParamsChanged here? + + setRank(cfs.rankOld); + setStage(cfs.inTrashOld); + } + + delete tpp; + tpp = 0; +} + +Thumbnail::Thumbnail (CacheManager* cm, const Glib::ustring& fname, const std::string& md5) + : fname(fname), cachemgr(cm), ref(1), enqueueNumber(0), tpp(NULL), pparamsValid(false), + needsReProcessing(true),imageLoading(false), lastImg(NULL), + initial_(true) +{ + + + cfs.md5 = md5; + loadProcParams (); + _generateThumbnailImage (); + cfs.recentlySaved = false; + + initial_ = false; + + delete tpp; + tpp = 0; +} + +void Thumbnail::_generateThumbnailImage () { + + // delete everything loaded into memory + delete tpp; + tpp = NULL; + delete [] lastImg; + lastImg = NULL; + tw = -1; + th = options.maxThumbnailHeight; + imgRatio = -1.; + + // generate thumbnail image + Glib::ustring ext = getExtension (fname); + if (ext=="") + return; + cfs.supported = false; + cfs.exifValid = false; + cfs.timeValid = false; + + if (ext.lowercase()=="jpg" || ext.lowercase()=="jpeg") { + infoFromImage (fname); + tpp = rtengine::Thumbnail::loadFromImage (fname, tw, th, 1, pparams.wb.equal); + if (tpp) + cfs.format = FT_Jpeg; + } + else if (ext.lowercase()=="png") { + tpp = rtengine::Thumbnail::loadFromImage (fname, tw, th, 1, pparams.wb.equal); + if (tpp) + cfs.format = FT_Png; + } + else if (ext.lowercase()=="tif" || ext.lowercase()=="tiff") { + infoFromImage (fname); + tpp = rtengine::Thumbnail::loadFromImage (fname, tw, th, 1, pparams.wb.equal); + if (tpp) + cfs.format = FT_Tiff; + } + else { + // RAW works like this: + // 1. if we are here it's because we aren't in the cache so load the JPG + // image out of the RAW. Mark as "quick". + // 2. if we don't find that then just grab the real image. + bool quick = false; + rtengine::RawMetaDataLocation ri; + if ( initial_ && options.internalThumbIfUntouched) + { + quick = true; + tpp = rtengine::Thumbnail::loadQuickFromRaw (fname, ri, tw, th, 1, TRUE); + } + if ( tpp == NULL ) + { + quick = false; + tpp = rtengine::Thumbnail::loadFromRaw (fname, ri, tw, th, 1, pparams.wb.equal, TRUE); + } + if (tpp) { + cfs.format = FT_Raw; + cfs.thumbImgType = quick ? CacheImageData::QUICK_THUMBNAIL : CacheImageData::FULL_THUMBNAIL; + infoFromImage (fname, &ri); + } + } + + if (tpp) + { + tpp->getAutoWBMultipliers(cfs.redAWBMul, cfs.greenAWBMul, cfs.blueAWBMul); + _saveThumbnail (); + cfs.supported = true; + needsReProcessing = true; + + cfs.save (getCacheFileName ("data")+".txt"); + + generateExifDateTimeStrings (); + } +} + +bool Thumbnail::isSupported () { + return cfs.supported; +} + +const ProcParams& Thumbnail::getProcParams () { + MyMutex::MyLock lock(mutex); + return getProcParamsU(); +} + +// Unprotected version of getProcParams, when +const ProcParams& Thumbnail::getProcParamsU () { + if (pparamsValid) + return pparams; + else { + pparams = *(profileStore.getDefaultProcParams (getType()==FT_Raw)); + if (pparams.wb.method=="Camera") { + double ct; + getCamWB (ct, pparams.wb.green); + pparams.wb.temperature = ct; + } + else if (pparams.wb.method=="Auto") { + double ct; + getAutoWB (ct, pparams.wb.green, pparams.wb.equal); + pparams.wb.temperature = ct; + } + } + return pparams; // there is no valid pp to return, but we have to return something +} + +/** @brief Create default params on demand and returns a new updatable object + * + * The loaded profile may be partial, but it return a complete ProcParams (i.e. without ParamsEdited) + * + * @param returnParams Ask to return a pointer to a ProcParams object if true + * @param forceCPB True if the Custom Profile Builder has to be invoked, False if the CPB has to be invoked if the profile doesn't + * exist yet. It depends on other conditions too + * @param flaggingMode True if the ProcParams will be created because the file browser is being flagging an image + * (rang, to trash, color labels). This parameter is passed to the CPB. + * + * @return Return a pointer to a ProcPamas structure to be updated if returnParams is true and if everything went fine, NULL otherwise. + */ +rtengine::procparams::ProcParams* Thumbnail::createProcParamsForUpdate(bool returnParams, bool forceCPB, bool flaggingMode) { + + static int index=0; // Will act as unique identifier during the session + + // try to load the last saved parameters from the cache or from the paramfile file + ProcParams* ldprof = NULL; + + Glib::ustring defProf = getType()==FT_Raw ? options.defProfRaw : options.defProfImg; + + const CacheImageData* cfs=getCacheImageData(); + Glib::ustring defaultPparamsPath = options.findProfilePath(defProf); + if (!options.CPBPath.empty() && !defaultPparamsPath.empty() && (!hasProcParams() || forceCPB) && cfs && cfs->exifValid) { + // First generate the communication file, with general values and EXIF metadata + rtengine::ImageMetaData* imageMetaData; + if (getType()==FT_Raw) { + rtengine::RawMetaDataLocation metaData = rtengine::Thumbnail::loadMetaDataFromRaw(fname); + imageMetaData = rtengine::ImageMetaData::fromFile (fname, &metaData); + } + else + imageMetaData = rtengine::ImageMetaData::fromFile (fname, NULL); + + Glib::ustring tmpFileName( Glib::build_filename(options.cacheBaseDir, Glib::ustring::compose("CPB_temp_%1.txt", index++)) ); + + const rtexif::TagDirectory* exifDir=NULL; + if (imageMetaData && (exifDir = imageMetaData->getExifData())) { + Glib::ustring outFName; + if (options.paramsLoadLocation==PLL_Input) + outFName = fname+paramFileExtension; + else + outFName = getCacheFileName("profiles")+paramFileExtension; + exifDir->CPBDump(tmpFileName, fname, outFName, + defaultPparamsPath == DEFPROFILE_INTERNAL ? DEFPROFILE_INTERNAL : Glib::build_filename(defaultPparamsPath, Glib::path_get_basename(defProf) + paramFileExtension), + cfs, + flaggingMode); + } + + // For the filename etc. do NOT use streams, since they are not UTF8 safe + Glib::ustring cmdLine = options.CPBPath + Glib::ustring(" \"") + tmpFileName + Glib::ustring("\""); + + if (options.rtSettings.verbose) + printf("Custom profile builder's command line: %s\n", Glib::ustring(cmdLine).c_str()); + bool success = safe_spawn_command_line_sync (cmdLine); + + // Now they SHOULD be there (and potentially "partial"), so try to load them and store it as a full procparam + if (success) loadProcParams(); + + if (safe_file_test(tmpFileName, Glib::FILE_TEST_EXISTS )) safe_g_remove (tmpFileName); + + if (imageMetaData) delete imageMetaData; + } + + if (returnParams && hasProcParams()) { + ldprof = new ProcParams (); + *ldprof = getProcParams (); + } + + return ldprof; +} + +void Thumbnail::notifylisterners_procParamsChanged(int whoChangedIt){ + for (size_t i=0; iprocParamsChanged (this, whoChangedIt); +} + +/* + * Load the procparams from the cache or from the sidecar file (priority set in + * the Preferences). + * + * The result is a complete ProcParams with default values merged with the values + * from the default Raw or Image ProcParams, then with the values from the loaded + * ProcParams (sidecar or cache file). + */ +void Thumbnail::loadProcParams () { + MyMutex::MyLock lock(mutex); + + pparamsValid = false; + pparams.setDefaults(); + const PartialProfile *defaultPP = profileStore.getDefaultPartialProfile(getType()==FT_Raw); + defaultPP->applyTo(&pparams); + + if (options.paramsLoadLocation==PLL_Input) { + // try to load it from params file next to the image file + int ppres = pparams.load (fname + paramFileExtension); + pparamsValid = !ppres && pparams.ppVersion>=220; + // if no success, try to load the cached version of the procparams + if (!pparamsValid) + pparamsValid = !pparams.load (getCacheFileName ("profiles")+paramFileExtension); + } + else { + // try to load it from cache + pparamsValid = !pparams.load (getCacheFileName ("profiles")+paramFileExtension); + // if no success, try to load it from params file next to the image file + if (!pparamsValid) { + int ppres = pparams.load (fname + paramFileExtension); + pparamsValid = !ppres && pparams.ppVersion>=220; + } + } +} + +void Thumbnail::clearProcParams (int whoClearedIt) { + +/* Clarification on current "clear profile" functionality: + a. if rank/colorlabel/inTrash are NOT set, + the "clear profile" will delete the pp3 file (as before). + + b. if any of the rank/colorlabel/inTrash ARE set, + the "clear profile" will lead to execution of ProcParams::setDefaults + (the CPB is NOT called) to set the params values and will preserve + rank/colorlabel/inTrash in the param file. */ + + { + MyMutex::MyLock lock(mutex); + + // preserve rank, colorlabel and inTrash across clear + int rank = getRank(); + int colorlabel = getColorLabel(); + int inTrash = getStage(); + + + cfs.recentlySaved = false; + pparamsValid = false; + needsReProcessing = true; + + //TODO: run though customprofilebuilder? + // probably not as this is the only option to set param values to default + + // reset the params to defaults + pparams.setDefaults(); + + // and restore rank and inTrash + setRank(rank); + setColorLabel(colorlabel); + setStage(inTrash); + + // params could get validated by rank/inTrash values restored above + if (pparamsValid) + { + updateCache(); + } + else + { + // remove param file from cache + Glib::ustring fname_ = getCacheFileName ("profiles")+paramFileExtension; + if (safe_file_test (fname_, Glib::FILE_TEST_EXISTS)) + safe_g_remove (fname_); + // remove param file located next to the file +// fname_ = removeExtension(fname) + paramFileExtension; + fname_ = fname + paramFileExtension; + if (safe_file_test(fname_, Glib::FILE_TEST_EXISTS)) + safe_g_remove (fname_); + fname_ = removeExtension(fname) + paramFileExtension; + if (safe_file_test (fname_, Glib::FILE_TEST_EXISTS)) + safe_g_remove (fname_); + + if (cfs.format == FT_Raw && options.internalThumbIfUntouched && cfs.thumbImgType != CacheImageData::QUICK_THUMBNAIL) { + // regenerate thumbnail, ie load the quick thumb again. For the rare formats not supporting quick thumbs this will + // be a bit slow as a new full thumbnail will be generated unnecessarily, but currently there is no way to pre-check + // if the format supports quick thumbs. + initial_ = true; + _generateThumbnailImage(); + initial_ = false; + } + } + + } // end of mutex lock + + for (size_t i=0; iprocParamsChanged (this, whoClearedIt); +} + +bool Thumbnail::hasProcParams () { + + return pparamsValid; +} + +void Thumbnail::setProcParams (const ProcParams& pp, ParamsEdited* pe, int whoChangedIt, bool updateCacheNow) { + + { + MyMutex::MyLock lock(mutex); + + if (pparams.sharpening.threshold.isDouble() != pp.sharpening.threshold.isDouble()) + printf("WARNING: Sharpening different!\n"); + if (pparams.vibrance.psthreshold.isDouble() != pp.vibrance.psthreshold.isDouble()) + printf("WARNING: Vibrance different!\n"); + + if (pparams!=pp) + cfs.recentlySaved = false; + + // do not update rank, colorlabel and inTrash + int rank = getRank(); + int colorlabel = getColorLabel(); + int inTrash = getStage(); + + if (pe) { + pe->combine(pparams, pp, true); + } + else pparams = pp; + pparamsValid = true; + needsReProcessing = true; + + setRank(rank); + setColorLabel(colorlabel); + setStage(inTrash); + + if (updateCacheNow) + updateCache (); + + } // end of mutex lock + + for (size_t i=0; iprocParamsChanged (this, whoChangedIt); +} + +bool Thumbnail::isRecentlySaved () { + + return cfs.recentlySaved; +} + +void Thumbnail::imageDeveloped () { + + cfs.recentlySaved = true; + cfs.save (getCacheFileName ("data")+".txt"); + if (options.saveParamsCache) + pparams.save (getCacheFileName ("profiles")+paramFileExtension); +} + +void Thumbnail::imageEnqueued () { + + enqueueNumber++; +} + +void Thumbnail::imageRemovedFromQueue () { + + enqueueNumber--; +} + +bool Thumbnail::isEnqueued () { + + return enqueueNumber > 0; +} + +void Thumbnail::increaseRef () +{ + MyMutex::MyLock lock(mutex); + ++ref; +} + +void Thumbnail::decreaseRef () +{ + { + MyMutex::MyLock lock(mutex); + if ( ref == 0 ) + { + return; + } + if ( --ref != 0 ) + { + return; + } + } + cachemgr->closeThumbnail (this); +} + +void Thumbnail::getThumbnailSize (int &w, int &h, const rtengine::procparams::ProcParams *pparams) { + int tw_ = tw; + int th_ = th; + float imgRatio_ = imgRatio; + + if (pparams) { + int ppCoarse = pparams->coarse.rotate; + if (ppCoarse >= 180) ppCoarse -= 180; + + int thisCoarse = this->pparams.coarse.rotate; + if (thisCoarse >= 180) thisCoarse -= 180; + + if (thisCoarse != ppCoarse) { + // different orientation -> swapping width & height + int tmp = th_; + th_ = tw_; + tw_ = tmp; + if (imgRatio_ >= 0.0001f) + imgRatio_ = 1.f/imgRatio_; + } + } + + if (imgRatio_ > 0.) + w = (int)(imgRatio_ * (float)h); + else + w = tw_ * h / th_; +} + +void Thumbnail::getFinalSize (const rtengine::procparams::ProcParams& pparams, int& w, int& h) { + MyMutex::MyLock lock(mutex); + + // WARNING: When downscaled, the ratio have loosed a lot of precision, so we can't get back the exact initial dimensions + double fw = lastW*lastScale; + double fh = lastH*lastScale; + + if (pparams.coarse.rotate==90 || pparams.coarse.rotate==270) { + fh = lastW*lastScale; + fw = lastH*lastScale; + } + if (!pparams.resize.enabled) { + w = fw; + h = fh; + } + else { + w = (int)(fw+0.5); + h = (int)(fh+0.5); + } +} + + +rtengine::IImage8* Thumbnail::processThumbImage (const rtengine::procparams::ProcParams& pparams, int h, double& scale) { + + MyMutex::MyLock lock(mutex); + + if ( tpp == 0 ) { + _loadThumbnail(); + if ( tpp == 0 ) + return 0; + } + + rtengine::IImage8* image = 0; + + 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); + } + 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 ); + } + + tpp->getDimensions(lastW,lastH,lastScale); + + delete tpp; + tpp = 0; + return image; +} + +rtengine::IImage8* Thumbnail::upgradeThumbImage (const rtengine::procparams::ProcParams& pparams, int h, double& scale) { + + MyMutex::MyLock lock(mutex); + + if ( cfs.thumbImgType != CacheImageData::QUICK_THUMBNAIL ) + { + return 0; + } + + _generateThumbnailImage(); + if ( tpp == 0 ) + { + return 0; + } + + 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 ); + tpp->getDimensions(lastW,lastH,lastScale); + + delete tpp; + tpp = 0; + return image; +} + +void Thumbnail::generateExifDateTimeStrings () { + + exifString = ""; + dateTimeString = ""; + + if (!cfs.exifValid) + 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)); + + 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 + std::string dateFormat = options.dateFormat; + std::ostringstream ostr; + bool spec = false; + for (size_t i=0; ihasExif()) { + 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(); + + if (idata->getOrientation()=="Rotate 90 CW") { + deg = 90; + } + else if (idata->getOrientation()=="Rotate 180") { + deg = 180; + } + else if (idata->getOrientation()=="Rotate 270 CW") { + deg = 270; + } + } + else { + cfs.lens = "Unknown"; + cfs.camMake = "Unknown"; + cfs.camModel = "Unknown"; + } + // get image filetype + std::string::size_type idx; + idx = fname.rfind('.'); + if(idx != std::string::npos){cfs.filetype = fname.substr(idx+1);} + else {cfs.filetype="";} + + delete idata; + return deg; +} + +/* + * Read all thumbnail's data from the cache; build and save them if doesn't exist - NON PROTECTED + * This includes: + * - image's bitmap (*.rtti) + * - auto exposure's histogram (full thumbnail only) + * - embedded profile (full thumbnail only) + * - LiveThumbData section of the data file + */ +void Thumbnail::_loadThumbnail(bool firstTrial) { + + needsReProcessing = true; + tw = -1; + th = options.maxThumbnailHeight; + delete tpp; + tpp = new rtengine::Thumbnail (); + tpp->isRaw = (cfs.format == (int) FT_Raw); + + // load supplementary data + bool succ = tpp->readData (getCacheFileName ("data")+".txt"); + + if (succ) + tpp->getAutoWBMultipliers(cfs.redAWBMul, cfs.greenAWBMul, cfs.blueAWBMul); + + // thumbnail image + succ = succ && tpp->readImage (getCacheFileName ("images")); + + if (!succ && firstTrial) { + _generateThumbnailImage (); + if (cfs.supported && firstTrial) + _loadThumbnail (false); + + if (tpp==NULL) return; + } + else if (!succ) { + delete tpp; + tpp = NULL; + return; + } + + if ( cfs.thumbImgType == CacheImageData::FULL_THUMBNAIL ) { + // load aehistogram + tpp->readAEHistogram (getCacheFileName ("aehistograms")); + + // load embedded profile + tpp->readEmbProfile (getCacheFileName ("embprofiles")+".icc"); + + tpp->init (); + } + + if (!initial_ && tpp) tw = tpp->getImageWidth (getProcParamsU(), th, imgRatio); // this might return 0 if image was just building +} + +/* + * Read all thumbnail's data from the cache; build and save them if doesn't exist - MUTEX PROTECTED + * This includes: + * - image's bitmap (*.rtti) + * - auto exposure's histogram (full thumbnail only) + * - embedded profile (full thumbnail only) + * - LiveThumbData section of the data file + */ +void Thumbnail::loadThumbnail (bool firstTrial) { + MyMutex::MyLock lock(mutex); + _loadThumbnail(firstTrial); +} + +/* + * Save thumbnail's data to the cache - NON PROTECTED + * This includes: + * - image's bitmap (*.rtti) + * - auto exposure's histogram (full thumbnail only) + * - embedded profile (full thumbnail only) + * - LiveThumbData section of the data file + */ +void Thumbnail::_saveThumbnail () { + + if (!tpp) + return; + + if (safe_g_remove (getCacheFileName ("images")+".rtti") == -1) { + // No file deleted, so we try to deleted obsolete files, if any + safe_g_remove (getCacheFileName ("images")+".cust"); + safe_g_remove (getCacheFileName ("images")+".cust16"); + safe_g_remove (getCacheFileName ("images")+".jpg"); + } + + // save thumbnail image + tpp->writeImage (getCacheFileName ("images"), 1); + + // save aehistogram + tpp->writeAEHistogram (getCacheFileName ("aehistograms")); + + // save embedded profile + tpp->writeEmbProfile (getCacheFileName ("embprofiles")+".icc"); + + // save supplementary data + tpp->writeData (getCacheFileName ("data")+".txt"); +} + +/* + * Save thumbnail's data to the cache - MUTEX PROTECTED + * This includes: + * - image's bitmap (*.rtti) + * - auto exposure's histogram (full thumbnail only) + * - embedded profile (full thumbnail only) + * - LiveThumbData section of the data file + */ +void Thumbnail::saveThumbnail () +{ + MyMutex::MyLock lock(mutex); + _saveThumbnail(); +} + +/* + * Update the cached files + * - updatePParams==true (default) : write the procparams file (sidecar or cache, depending on the options) + * - updateCacheImageData==true (default) : write the CacheImageData values in the cache folder, + * i.e. some General, DateTime, ExifInfo, File info and ExtraRawInfo, + */ +void Thumbnail::updateCache (bool updatePParams, bool updateCacheImageData) { + + if (updatePParams && pparamsValid) { + pparams.save ( + options.saveParamsFile ? fname + paramFileExtension : "", + options.saveParamsCache ? getCacheFileName ("profiles")+paramFileExtension : "", + true + ); + } + if (updateCacheImageData) + cfs.save (getCacheFileName ("data")+".txt"); +} + +Thumbnail::~Thumbnail () { + mutex.lock(); + + delete [] lastImg; + delete tpp; + mutex.unlock(); +} + +Glib::ustring Thumbnail::getCacheFileName (Glib::ustring subdir) { + + return cachemgr->getCacheFileName (subdir, fname, cfs.md5); +} + +void Thumbnail::setFileName (const Glib::ustring fn) { + + fname = fn; + cfs.md5 = cachemgr->getMD5 (fname); +} + +void Thumbnail::addThumbnailListener (ThumbnailListener* tnl) { + + increaseRef(); + listeners.push_back (tnl); +} + +void Thumbnail::removeThumbnailListener (ThumbnailListener* tnl) { + + std::vector::iterator f = std::find (listeners.begin(), listeners.end(), tnl); + if (f!=listeners.end()) { + listeners.erase (f); + decreaseRef(); + } +} + +// Calculates the standard filename for the automatically named batch result +// and opens it in OS default viewer +// destination: 1=Batch conf. file; 2=batch out dir; 3=RAW dir +// Return: Success? +bool Thumbnail::openDefaultViewer(int destination) { + +#ifdef WIN32 + Glib::ustring openFName; + + if (destination==1) { + openFName = Glib::ustring::compose ("%1.%2", BatchQueue::calcAutoFileNameBase(fname), options.saveFormatBatch.format); + if (safe_file_test (openFName, Glib::FILE_TEST_EXISTS)) { + wchar_t *wfilename = (wchar_t*)g_utf8_to_utf16 (openFName.c_str(), -1, NULL, NULL, NULL); + ShellExecuteW(NULL, L"open", wfilename, NULL, NULL, SW_SHOWMAXIMIZED ); + g_free(wfilename); + } else { + printf("%s not found\n",openFName.data()); + return false; + } + } else { + openFName = destination == 3 ? fname + : Glib::ustring::compose ("%1.%2", BatchQueue::calcAutoFileNameBase(fname), options.saveFormatBatch.format); + + printf("Opening %s\n", openFName.c_str()); + + if (safe_file_test (openFName, Glib::FILE_TEST_EXISTS)) { + // Output file exists, so open explorer and select output file + wchar_t* org=(wchar_t*)g_utf8_to_utf16 (Glib::ustring::compose("/select,\"%1\"", openFName).c_str(), -1, NULL, NULL, NULL); + wchar_t* par=new wchar_t[wcslen(org)+1]; + wcscpy(par, org); + + // In this case the / disturbs + wchar_t* p = par+1; // skip the first backslash + while (*p!=0) { + if (*p==L'/') *p=L'\\'; + p++; + } + + ShellExecuteW(NULL, L"open", L"explorer.exe", par, NULL, SW_SHOWNORMAL ); + + delete[] par; + g_free(org); + } else if (safe_file_test (Glib::path_get_dirname(openFName), Glib::FILE_TEST_EXISTS)) { + // Out file does not exist, but directory + wchar_t *wfilename = (wchar_t*)g_utf8_to_utf16 (Glib::path_get_dirname(openFName).c_str(), -1, NULL, NULL, NULL); + ShellExecuteW(NULL, L"explore", wfilename, NULL, NULL, SW_SHOWNORMAL ); + g_free(wfilename); + } else { + printf("File and dir not found\n"); + return false; + } + } + + return true; + +#else + // TODO: Add more OSes here + printf("Automatic opening not supported on this OS\n"); + return false; +#endif + +} + +bool Thumbnail::imageLoad(bool loading) +{ + MyMutex::MyLock lock(mutex); + bool previous = imageLoading; + if( loading && !previous ){ + imageLoading = true; + return true; + }else if( !loading ) + imageLoading = false; + return false; +} diff --git a/rtgui/thumbnail.h b/rtgui/thumbnail.h new file mode 100644 index 000000000..183f4b195 --- /dev/null +++ b/rtgui/thumbnail.h @@ -0,0 +1,151 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _THUMBNAIL_ +#define _THUMBNAIL_ + +#include +#include +#include "cachemanager.h" +#include "options.h" +#include "../rtengine/rtengine.h" +#include "../rtengine/rtthumbnail.h" +#include "cacheimagedata.h" +#include "thumbnaillistener.h" +#include "threadutils.h" + +class CacheManager; +class Thumbnail { + + MyMutex mutex; + + Glib::ustring fname; // file name corresponding to the thumbnail + CacheImageData cfs; // cache entry corresponding to the thumbnail + CacheManager* cachemgr; // parent + int ref; // variable for reference counting + int enqueueNumber; // the number of instances in the batch queue corresponding to this thumbnail + + // if the thumbnail is in processed mode, this class holds its data: + rtengine::Thumbnail* tpp; + int tw, th; // dimensions of timgdata (it stores tpp->width and tpp->height in processed mode for simplicity) + float imgRatio; // hack to avoid rounding error +// double scale; // portion of the sizes of the processed thumbnail image and the full scale image + + rtengine::procparams::ProcParams pparams; + bool pparamsValid; + bool pparamsSet; + bool needsReProcessing; + bool imageLoading; + + // these are the data of the result image of the last getthumbnailimage call (for caching purposes) + unsigned char* lastImg; + int lastW; + int lastH; + double lastScale; + + // exif & date/time strings + Glib::ustring exifString; + Glib::ustring dateTimeString; + + bool initial_; + + // vector of listeners + std::vector listeners; + + void _loadThumbnail (bool firstTrial=true); + void _saveThumbnail (); + void _generateThumbnailImage (); + int infoFromImage (const Glib::ustring& fname, rtengine::RawMetaDataLocation* rml=NULL); + void loadThumbnail (bool firstTrial=true); + void generateExifDateTimeStrings (); + + Glib::ustring getCacheFileName (Glib::ustring subdir); + + public: + Thumbnail (CacheManager* cm, const Glib::ustring& fname, CacheImageData* cf); + Thumbnail (CacheManager* cm, const Glib::ustring& fname, const std::string& md5); + ~Thumbnail (); + + bool hasProcParams (); + const rtengine::procparams::ProcParams& getProcParams (); + const rtengine::procparams::ProcParams& getProcParamsU (); // Unprotected version + + // Use this to create params on demand for update ; if flaggingMode=true, the procparams is created for a file being flagged (inTrash, rank, colorLabel) + rtengine::procparams::ProcParams* createProcParamsForUpdate (bool returnParams, bool forceCPB, bool flaggingMode=false); + + void setProcParams (const rtengine::procparams::ProcParams& pp, ParamsEdited* pe=NULL, int whoChangedIt=-1, bool updateCacheNow=true); + void clearProcParams (int whoClearedIt=-1); + void loadProcParams (); + + void notifylisterners_procParamsChanged(int whoChangedIt); + + bool isQuick() { return cfs.thumbImgType == CacheImageData::QUICK_THUMBNAIL; } + bool isPParamsValid() { return pparamsValid; } + bool isRecentlySaved (); + void imageDeveloped (); + void imageEnqueued (); + void imageRemovedFromQueue (); + bool isEnqueued (); + +// 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); + rtengine::IImage8* upgradeThumbImage (const rtengine::procparams::ProcParams& pparams, int h, double& scale); + void getThumbnailSize (int &w, int &h, const rtengine::procparams::ProcParams *pparams=NULL); + void getFinalSize (const rtengine::procparams::ProcParams& pparams, int& w, int& h); + + const Glib::ustring& getExifString (); + const Glib::ustring& getDateTimeString (); + void getCamWB (double& temp, double& green) { if (tpp) tpp->getCamWB (temp, green); else temp = green = -1.0; } + void getAutoWB (double& temp, double& green, double equal); + void getSpotWB (int x, int y, int rect, double& temp, double& green) { if (tpp) tpp->getSpotWB (getProcParams(), x, y, rect, temp, green); else temp = green = -1.0; } + void applyAutoExp (rtengine::procparams::ProcParams& pparams) { if (tpp) tpp->applyAutoExp (pparams); } + + ThFileType getType (); + Glib::ustring getFileName () { return fname; } + void setFileName (const Glib::ustring fn); + + bool isSupported (); + + const CacheImageData* getCacheImageData() { return &cfs; } + std::string getMD5 () { return cfs.md5; } + + int getRank () { return pparams.rank; } + void setRank (int rank) { if (pparams.rank != rank) { pparams.rank = rank; pparamsValid = true; } } + + int getColorLabel () { return pparams.colorlabel; } + void setColorLabel (int colorlabel) { if (pparams.colorlabel != colorlabel) { pparams.colorlabel = colorlabel; pparamsValid = true; } } + + int getStage () { return pparams.inTrash; } + void setStage (int stage) { if (pparams.inTrash != stage) { pparams.inTrash = stage; pparamsValid = true; } } + + void addThumbnailListener (ThumbnailListener* tnl); + void removeThumbnailListener (ThumbnailListener* tnl); + + void increaseRef (); + void decreaseRef (); + + void updateCache (bool updatePParams = true, bool updateCacheImageData = true); + void saveThumbnail (); + + bool openDefaultViewer(int destination); + bool imageLoad(bool loading); +}; + + +#endif + diff --git a/rtgui/thumbnailbrowser.h b/rtgui/thumbnailbrowser.h new file mode 100644 index 000000000..4b3c27078 --- /dev/null +++ b/rtgui/thumbnailbrowser.h @@ -0,0 +1,95 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _THUMBNAILBROWSER_ +#define _THUMBNAILBROWSER_ + +#include +#include "thumbnail.h" +#include "filecatalog.h" + +class ThumbBrowserEntry { + +public: +// set by arrangeFiles(): + int width; // minimal width + int height; // minimal height + int exp_width; // ararnged width + int startx; // x coord. in the widget + int starty; // y coord. in the widget +// thumbnail preview properties: + int prew; // width of the thumbnail + int preh; // height of the thumbnail + guint8* preview; +// file and directory attributes: + Glib::ustring filename; + Glib::ustring shortname; + Glib::ustring dirname; +// the associated thumbnail instance: + Thumbnail* thumbnail; + + ThumbBrowserEntry (Thumbnail* thm, Glib::ustring fname, Glib::ustring sname, Glib::ustring dname, int h) + : thumbnail(thm), filename(fname), shortname(sname), dirname(dname), preh(h) { + preview = thumbnail ? (guint8*) thumbnail->getThumbnailImage (prew, preh) : NULL; + } + + bool operator< (FileDescr& other) { + return shortname>other.shortname; + } +}; + +class ThumbBrowser : public Gtk::DrawingArea { + + protected: + int dx, dy, w, h; + + Glib::RefPtr gc_; + Gdk::Color black; + Gdk::Color white; + Gdk::Color blue; + Gdk::Color bluew; + + std::vector fd; + std::vector selected; + + int rowHeight; + int numOfRows; + + ThumbBrowserListener* tbl; + + void arrangeFiles (int rows); + + public: + + ThumbBrowser (); + + void addEntry (ThumbBrowserEntry* entry); + void setThumbBrowserListener (ThumbBrowserListener* l) { tbl = l; } + + virtual void on_realize(); + virtual bool on_expose_event(GdkEventExpose* event); + virtual bool on_button_press_event (GdkEventButton* event); + virtual bool on_button_release_event (GdkEventButton* event); + virtual void previewReady (FileDescr* fdn); + + void resized (Gtk::Allocation& req); + void redraw (); + void styleChanged (const Glib::RefPtr& style); +}; + +#endif diff --git a/rtgui/thumbnaillistener.h b/rtgui/thumbnaillistener.h new file mode 100644 index 000000000..1a2bae1aa --- /dev/null +++ b/rtgui/thumbnaillistener.h @@ -0,0 +1,34 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _THUMBNAILLISTENER_ +#define _THUMBNAILLISTENER_ + +#include "thumbnail.h" + +class Thumbnail; +class ThumbnailListener { + + public: + + virtual void procParamsChanged (Thumbnail* thm, int whoChangedIt) {} + +}; + +#endif + diff --git a/rtgui/tonecurve.cc b/rtgui/tonecurve.cc new file mode 100644 index 000000000..61ee388d4 --- /dev/null +++ b/rtgui/tonecurve.cc @@ -0,0 +1,746 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "tonecurve.h" +#include "adjuster.h" +#include +#include +#include "ppversion.h" +#include "edit.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +ToneCurve::ToneCurve () : FoldableToolPanel(this, "tonecurve", M("TP_EXPOSURE_LABEL")) { + + CurveListener::setMulti(true); + + std::vector bottomMilestones; + bottomMilestones.push_back( GradientMilestone(0., 0., 0., 0.) ); + bottomMilestones.push_back( GradientMilestone(1., 1., 1., 1.) ); + +//----------- Auto Levels ---------------------------------- + abox = Gtk::manage (new Gtk::HBox ()); + abox->set_border_width (2); + abox->set_spacing (10); + + autolevels = Gtk::manage (new Gtk::ToggleButton (M("TP_EXPOSURE_AUTOLEVELS"))); + autolevels->set_tooltip_markup (M("TP_EXPOSURE_AUTOLEVELS_TIP")); + autoconn = autolevels->signal_toggled().connect( sigc::mem_fun(*this, &ToneCurve::autolevels_toggled) ); + + lclip = Gtk::manage (new Gtk::Label (M("TP_EXPOSURE_CLIP"))); + lclip->set_tooltip_text (M("TP_EXPOSURE_CLIP_TIP")); + + sclip = Gtk::manage (new MySpinButton ()); + sclip->set_range (0.0, 0.99); + sclip->set_increments (0.01, 0.10); + sclip->set_value (0.02); + sclip->set_digits (2); + sclip->signal_value_changed().connect( sigc::mem_fun(*this, &ToneCurve::clip_changed) ); + + neutral = Gtk::manage (new Gtk::Button (M("TP_NEUTRAL"))); + neutral->set_tooltip_text (M("TP_NEUTRAL_TIP")); + neutralconn = neutral->signal_pressed().connect( sigc::mem_fun(*this, &ToneCurve::neutral_pressed) ); + neutral->show(); + + abox->pack_start (*autolevels, true, true, 0); + // pack_end is used for these controls as autolevels is replaceable using pack_start in batchmode + abox->pack_end (*neutral, true, true, 0); + abox->pack_end (*sclip, false, false, 0); + abox->pack_end (*lclip, false, false, 0); + pack_start (*abox); + +//-------------- Highlight Reconstruction ----------------- + pack_start (*Gtk::manage (new Gtk::HSeparator())); + + hrenabled = Gtk::manage (new Gtk::CheckButton (M("TP_HLREC_LABEL"))); + hrenabled->set_active (false); + hrenabled->set_tooltip_markup (M("TP_HLREC_ENA_TOOLTIP")); + pack_start (*hrenabled); + + method = Gtk::manage (new MyComboBoxText ()); + method->append_text (M("TP_HLREC_LUMINANCE")); + method->append_text (M("TP_HLREC_CIELAB")); + method->append_text (M("TP_HLREC_COLOR")); + method->append_text (M("TP_HLREC_BLEND")); + + method->set_active (0); + hlrbox = Gtk::manage (new Gtk::HBox ()); + Gtk::Label* lab = Gtk::manage (new Gtk::Label (M("TP_HLREC_METHOD"))); + hlrbox->pack_start (*lab, Gtk::PACK_SHRINK, 4); + hlrbox->pack_start (*method); + pack_start (*hlrbox); + + enaconn = hrenabled->signal_toggled().connect( sigc::mem_fun(*this, &ToneCurve::hrenabledChanged) ); + methconn = method->signal_changed().connect ( sigc::mem_fun(*this, &ToneCurve::methodChanged) ); + + //----------- Exposure Compensation --------------------- + pack_start (*Gtk::manage (new Gtk::HSeparator())); + + expcomp = Gtk::manage (new Adjuster (M("TP_EXPOSURE_EXPCOMP"), -5, 12, 0.05, 0)); + pack_start (*expcomp); + + //----------- Highlight recovery & threshold ------------- + hlcompr = Gtk::manage (new Adjuster (M("TP_EXPOSURE_COMPRHIGHLIGHTS"), 0, 500, 1, 0)); + pack_start (*hlcompr); + hlcomprthresh = Gtk::manage (new Adjuster (M("TP_EXPOSURE_COMPRHIGHLIGHTSTHRESHOLD"), 0, 100, 1, 33)); + pack_start (*hlcomprthresh); + +//----------- Black Level & Compression ------------------- + black = Gtk::manage (new Adjuster (M("TP_EXPOSURE_BLACKLEVEL"), -16384, 32768, 50, 0)); + pack_start (*black); + shcompr = Gtk::manage (new Adjuster (M("TP_EXPOSURE_COMPRSHADOWS"), 0, 100, 1, 50)); + pack_start (*shcompr); + + pack_start (*Gtk::manage (new Gtk::HSeparator())); + +//---------Brightness / Contrast ------------------------- + brightness = Gtk::manage (new Adjuster (M("TP_EXPOSURE_BRIGHTNESS"), -100, 100, 1, 0)); + pack_start (*brightness); + contrast = Gtk::manage (new Adjuster (M("TP_EXPOSURE_CONTRAST"), -100, 100, 1, 0)); + pack_start (*contrast); + saturation = Gtk::manage (new Adjuster (M("TP_EXPOSURE_SATURATION"), -100, 100, 1, 0)); + pack_start (*saturation); + +//----------- Curve 1 ------------------------------ + pack_start (*Gtk::manage (new Gtk::HSeparator())); + + toneCurveMode = Gtk::manage (new MyComboBoxText ()); + toneCurveMode->append_text (M("TP_EXPOSURE_TCMODE_STANDARD")); + toneCurveMode->append_text (M("TP_EXPOSURE_TCMODE_WEIGHTEDSTD")); + toneCurveMode->append_text (M("TP_EXPOSURE_TCMODE_FILMLIKE")); + toneCurveMode->append_text (M("TP_EXPOSURE_TCMODE_SATANDVALBLENDING")); + toneCurveMode->append_text (M("TP_EXPOSURE_TCMODE_LUMINANCE")); + toneCurveMode->set_active (0); + toneCurveMode->set_tooltip_text(M("TP_EXPOSURE_TCMODE_LABEL1")); + + curveEditorG = new CurveEditorGroup (options.lastToneCurvesDir, M("TP_EXPOSURE_CURVEEDITOR1")); + curveEditorG->setCurveListener (this); + + shape = static_cast(curveEditorG->addCurve(CT_Diagonal, "", toneCurveMode)); + shape->setEditID(EUID_ToneCurve1, BT_IMAGEFLOAT); + shape->setBottomBarBgGradient(bottomMilestones); + shape->setLeftBarBgGradient(bottomMilestones); + + // This will add the reset button at the end of the curveType buttons + curveEditorG->curveListComplete(); + + pack_start( *curveEditorG, Gtk::PACK_SHRINK, 2); + + tcmodeconn = toneCurveMode->signal_changed().connect( sigc::mem_fun(*this, &ToneCurve::curveMode1Changed), true ); + +//----------- Curve 2 ------------------------------ + + toneCurveMode2 = Gtk::manage (new MyComboBoxText ()); + toneCurveMode2->append_text (M("TP_EXPOSURE_TCMODE_STANDARD")); + toneCurveMode2->append_text (M("TP_EXPOSURE_TCMODE_WEIGHTEDSTD")); + toneCurveMode2->append_text (M("TP_EXPOSURE_TCMODE_FILMLIKE")); + toneCurveMode2->append_text (M("TP_EXPOSURE_TCMODE_SATANDVALBLENDING")); + toneCurveMode2->append_text (M("TP_EXPOSURE_TCMODE_LUMINANCE")); + toneCurveMode2->set_active (0); + toneCurveMode2->set_tooltip_text(M("TP_EXPOSURE_TCMODE_LABEL2")); + + curveEditorG2 = new CurveEditorGroup (options.lastToneCurvesDir, M("TP_EXPOSURE_CURVEEDITOR2")); + curveEditorG2->setCurveListener (this); + + shape2 = static_cast(curveEditorG2->addCurve(CT_Diagonal, "", toneCurveMode2)); + shape2->setEditID(EUID_ToneCurve2, BT_IMAGEFLOAT); + shape2->setBottomBarBgGradient(bottomMilestones); + shape2->setLeftBarBgGradient(bottomMilestones); + + // This will add the reset button at the end of the curveType buttons + curveEditorG2->curveListComplete(); + curveEditorG2->setTooltip(M("TP_EXPOSURE_CURVEEDITOR2_TOOLTIP")); + + pack_start( *curveEditorG2, Gtk::PACK_SHRINK, 2); + + tcmode2conn = toneCurveMode2->signal_changed().connect( sigc::mem_fun(*this, &ToneCurve::curveMode2Changed), true ); + +// --------- Set Up Listeners ------------- + expcomp->setAdjusterListener (this); + brightness->setAdjusterListener (this); + black->setAdjusterListener (this); + hlcompr->setAdjusterListener (this); + hlcomprthresh->setAdjusterListener (this); + shcompr->setAdjusterListener (this); + contrast->setAdjusterListener (this); + saturation->setAdjusterListener (this); +} + +ToneCurve::~ToneCurve () { + delete curveEditorG; + delete curveEditorG2; +} + +void ToneCurve::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + tcmodeconn.block(true); + tcmode2conn.block(true); + autoconn.block (true); + + autolevels->set_active (pp->toneCurve.autoexp); + lastAuto = pp->toneCurve.autoexp; + sclip->set_value (pp->toneCurve.clip); + + expcomp->setValue (pp->toneCurve.expcomp); + black->setValue (pp->toneCurve.black); + hlcompr->setValue (pp->toneCurve.hlcompr); + hlcomprthresh->setValue (pp->toneCurve.hlcomprthresh); + shcompr->setValue (pp->toneCurve.shcompr); + if (!black->getAddMode()) shcompr->set_sensitive(!((int)black->getValue ()==0)); //at black=0 shcompr value has no effect + brightness->setValue (pp->toneCurve.brightness); + contrast->setValue (pp->toneCurve.contrast); + saturation->setValue (pp->toneCurve.saturation); + shape->setCurve (pp->toneCurve.curve); + shape2->setCurve (pp->toneCurve.curve2); + + toneCurveMode->set_active(pp->toneCurve.curveMode); + toneCurveMode2->set_active(pp->toneCurve.curveMode2); + + if (pedited) { + expcomp->setEditedState (pedited->toneCurve.expcomp ? Edited : UnEdited); + black->setEditedState (pedited->toneCurve.black ? Edited : UnEdited); + hlcompr->setEditedState (pedited->toneCurve.hlcompr ? Edited : UnEdited); + hlcomprthresh->setEditedState (pedited->toneCurve.hlcomprthresh ? Edited : UnEdited); + shcompr->setEditedState (pedited->toneCurve.shcompr ? Edited : UnEdited); + brightness->setEditedState (pedited->toneCurve.brightness ? Edited : UnEdited); + contrast->setEditedState (pedited->toneCurve.contrast ? Edited : UnEdited); + saturation->setEditedState (pedited->toneCurve.saturation ? Edited : UnEdited); + autolevels->set_inconsistent (!pedited->toneCurve.autoexp); + clipDirty = pedited->toneCurve.clip; + shape->setUnChanged (!pedited->toneCurve.curve); + shape2->setUnChanged (!pedited->toneCurve.curve2); + if (!pedited->toneCurve.curveMode) { + toneCurveMode->set_active(5); + } + if (!pedited->toneCurve.curveMode2) { + toneCurveMode2->set_active(5); + } + } + if (pedited) + hrenabled->set_inconsistent (!pedited->toneCurve.hrenabled); + enaconn.block (true); + hrenabled->set_active (pp->toneCurve.hrenabled); + enaconn.block (false); + + if (pedited && !pedited->toneCurve.method) + method->set_active (4); + else if (pp->toneCurve.method=="Luminance") + method->set_active (0); + else if (pp->toneCurve.method=="CIELab blending") + method->set_active (1); + else if (pp->toneCurve.method=="Color") + method->set_active (2); + else if (pp->toneCurve.method=="Blend") + method->set_active (3); + + if (!batchMode) { + if (hrenabled->get_active()) + hlrbox->show(); + else + hlrbox->hide(); + } + lasthrEnabled = pp->toneCurve.hrenabled; + + autoconn.block (false); + tcmode2conn.block(false); + tcmodeconn.block(false); + + enableListener (); +} + +void ToneCurve::autoOpenCurve () { + shape->openIfNonlinear(); + shape2->openIfNonlinear(); +} + +void ToneCurve::setEditProvider (EditDataProvider *provider) { + shape->setEditProvider(provider); + shape2->setEditProvider(provider); +} + +void ToneCurve::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->toneCurve.autoexp = autolevels->get_active(); + pp->toneCurve.clip = sclip->get_value (); + pp->toneCurve.expcomp = expcomp->getValue (); + pp->toneCurve.black = (int)black->getValue (); + pp->toneCurve.hlcompr = (int)hlcompr->getValue (); + pp->toneCurve.hlcomprthresh = (int)hlcomprthresh->getValue (); + pp->toneCurve.shcompr = (int)shcompr->getValue (); + pp->toneCurve.brightness = (int)brightness->getValue (); + pp->toneCurve.contrast = (int)contrast->getValue (); + pp->toneCurve.saturation = (int)saturation->getValue (); + pp->toneCurve.curve = shape->getCurve (); + pp->toneCurve.curve2 = shape2->getCurve (); + + int tcMode = toneCurveMode->get_active_row_number(); + if (tcMode == 0) pp->toneCurve.curveMode = ToneCurveParams::TC_MODE_STD; + else if (tcMode == 1) pp->toneCurve.curveMode = ToneCurveParams::TC_MODE_WEIGHTEDSTD; + else if (tcMode == 2) pp->toneCurve.curveMode = ToneCurveParams::TC_MODE_FILMLIKE; + else if (tcMode == 3) pp->toneCurve.curveMode = ToneCurveParams::TC_MODE_SATANDVALBLENDING; + else if (tcMode == 4) pp->toneCurve.curveMode = ToneCurveParams::TC_MODE_LUMINANCE; + + tcMode = toneCurveMode2->get_active_row_number(); + if (tcMode == 0) pp->toneCurve.curveMode2 = ToneCurveParams::TC_MODE_STD; + else if (tcMode == 1) pp->toneCurve.curveMode2 = ToneCurveParams::TC_MODE_WEIGHTEDSTD; + else if (tcMode == 2) pp->toneCurve.curveMode2 = ToneCurveParams::TC_MODE_FILMLIKE; + else if (tcMode == 3) pp->toneCurve.curveMode2 = ToneCurveParams::TC_MODE_SATANDVALBLENDING; + else if (tcMode == 4) pp->toneCurve.curveMode2 = ToneCurveParams::TC_MODE_LUMINANCE; + + if (pedited) { + pedited->toneCurve.expcomp = expcomp->getEditedState (); + pedited->toneCurve.black = black->getEditedState (); + pedited->toneCurve.hlcompr = hlcompr->getEditedState (); + pedited->toneCurve.hlcomprthresh = hlcomprthresh->getEditedState (); + pedited->toneCurve.shcompr = shcompr->getEditedState (); + pedited->toneCurve.brightness = brightness->getEditedState (); + pedited->toneCurve.contrast = contrast->getEditedState (); + pedited->toneCurve.saturation = saturation->getEditedState (); + pedited->toneCurve.autoexp = !autolevels->get_inconsistent(); + pedited->toneCurve.clip = clipDirty; + pedited->toneCurve.curve = !shape->isUnChanged (); + pedited->toneCurve.curve2 = !shape2->isUnChanged (); + pedited->toneCurve.curveMode = toneCurveMode->get_active_row_number() != 5; + pedited->toneCurve.curveMode2 = toneCurveMode2->get_active_row_number() != 5; + } + if (pedited) { + pedited->toneCurve.method = method->get_active_row_number()!=4; + pedited->toneCurve.hrenabled = !hrenabled->get_inconsistent(); + } + + pp->toneCurve.hrenabled = hrenabled->get_active(); + if (method->get_active_row_number()==0) + pp->toneCurve.method = "Luminance"; + else if (method->get_active_row_number()==1) + pp->toneCurve.method = "CIELab blending"; + else if (method->get_active_row_number()==2) + pp->toneCurve.method = "Color"; + else if (method->get_active_row_number()==3) + pp->toneCurve.method = "Blend"; +} + +void ToneCurve::hrenabledChanged () { + + if (multiImage) { + if (hrenabled->get_inconsistent()) { + hrenabled->set_inconsistent (false); + enaconn.block (true); + hrenabled->set_active (false); + enaconn.block (false); + } + else if (lasthrEnabled) + hrenabled->set_inconsistent (true); + + lasthrEnabled = hrenabled->get_active (); + } + + if (!batchMode) { + if (hrenabled->get_active()) + hlrbox->show(); + else + hlrbox->hide(); + } + + if (listener) { + // Switch off auto exposure if user changes enabled manually + if (autolevels->get_active() ) { + autoconn.block(true); + autolevels->set_active (false); + autoconn.block(false); + autolevels->set_inconsistent (false); + } + if (hrenabled->get_active ()) + listener->panelChanged (EvHREnabled, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvHREnabled, M("GENERAL_DISABLED")); + } +} +void ToneCurve::methodChanged () { + + if (listener) { + if (hrenabled->get_active ()) + listener->panelChanged (EvHRMethod, method->get_active_text ()); + } +} +void ToneCurve::setRaw (bool raw) { + + disableListener (); + method->set_sensitive (raw); + hrenabled->set_sensitive (raw); + enableListener (); +} + + +void ToneCurve::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + expcomp->setDefault (defParams->toneCurve.expcomp); + brightness->setDefault (defParams->toneCurve.brightness); + black->setDefault (defParams->toneCurve.black); + hlcompr->setDefault (defParams->toneCurve.hlcompr); + hlcomprthresh->setDefault (defParams->toneCurve.hlcomprthresh); + shcompr->setDefault (defParams->toneCurve.shcompr); + contrast->setDefault (defParams->toneCurve.contrast); + saturation->setDefault (defParams->toneCurve.saturation); + + if (pedited) { + expcomp->setDefaultEditedState (pedited->toneCurve.expcomp ? Edited : UnEdited); + black->setDefaultEditedState (pedited->toneCurve.black ? Edited : UnEdited); + hlcompr->setDefaultEditedState (pedited->toneCurve.hlcompr ? Edited : UnEdited); + hlcomprthresh->setDefaultEditedState (pedited->toneCurve.hlcomprthresh ? Edited : UnEdited); + shcompr->setDefaultEditedState (pedited->toneCurve.shcompr ? Edited : UnEdited); + brightness->setDefaultEditedState (pedited->toneCurve.brightness ? Edited : UnEdited); + contrast->setDefaultEditedState (pedited->toneCurve.contrast ? Edited : UnEdited); + saturation->setDefaultEditedState (pedited->toneCurve.saturation ? Edited : UnEdited); + } + else { + expcomp->setDefaultEditedState (Irrelevant); + black->setDefaultEditedState (Irrelevant); + hlcompr->setDefaultEditedState (Irrelevant); + hlcomprthresh->setDefaultEditedState (Irrelevant); + shcompr->setDefaultEditedState (Irrelevant); + brightness->setDefaultEditedState (Irrelevant); + contrast->setDefaultEditedState (Irrelevant); + saturation->setDefaultEditedState (Irrelevant); + } +} + +void ToneCurve::curveChanged (CurveEditor* ce) { + + if (listener) { + if (ce == shape) + listener->panelChanged (EvToneCurve1, M("HISTORY_CUSTOMCURVE")); + else if (ce == shape2) + listener->panelChanged (EvToneCurve2, M("HISTORY_CUSTOMCURVE")); + } +} + +void ToneCurve::curveMode1Changed () { + //if (listener) listener->panelChanged (EvToneCurveMode, toneCurveMode->get_active_text()); + if (listener) Glib::signal_idle().connect (sigc::mem_fun(*this, &ToneCurve::curveMode1Changed_)); +} + +bool ToneCurve::curveMode1Changed_ () { + if (listener) listener->panelChanged (EvToneCurveMode1, toneCurveMode->get_active_text()); + return false; +} + +void ToneCurve::curveMode2Changed () { + //if (listener) listener->panelChanged (EvToneCurveMode, toneCurveMode->get_active_text()); + if (listener) Glib::signal_idle().connect (sigc::mem_fun(*this, &ToneCurve::curveMode2Changed_)); +} + +bool ToneCurve::curveMode2Changed_ () { + if (listener) listener->panelChanged (EvToneCurveMode2, toneCurveMode2->get_active_text()); + return false; +} + +float ToneCurve::blendPipetteValues(CurveEditor *ce, float chan1, float chan2, float chan3) { + // assuming that all the channels are used... + if (ce == shape) { + if (toneCurveMode->get_active_row_number() == 4) + return chan1*0.2126729f + chan2*0.7151521f + chan3*0.0721750f; + } + else if (ce == shape2) { + if (toneCurveMode2->get_active_row_number() == 4) + return chan1*0.2126729f + chan2*0.7151521f + chan3*0.0721750f; + } + return CurveListener::blendPipetteValues(ce, chan1, chan2, chan3); +} + +void ToneCurve::adjusterChanged (Adjuster* a, double newval) { + + // Switch off auto exposure if user changes sliders manually + if (autolevels->get_active() && (a==expcomp || a==brightness || a==contrast || a==black || a==hlcompr || a==hlcomprthresh)) { + autoconn.block(true); + autolevels->set_active (false); + autoconn.block(false); + autolevels->set_inconsistent (false); + } + + if (!listener) + return; + + Glib::ustring costr; + if (a==expcomp) + costr = Glib::ustring::format (std::setw(3), std::fixed, std::setprecision(2), a->getValue()); + else + costr = Glib::ustring::format ((int)a->getValue()); + + if (a==expcomp) + listener->panelChanged (EvExpComp, costr); + else if (a==brightness) + listener->panelChanged (EvBrightness, costr); + else if (a==black){ + listener->panelChanged (EvBlack, costr); + if (!black->getAddMode()) shcompr->set_sensitive(!((int)black->getValue ()==0)); //at black=0 shcompr value has no effect + } + else if (a==contrast) + listener->panelChanged (EvContrast, costr); + else if (a==saturation) + listener->panelChanged (EvSaturation, costr); + else if (a==hlcompr) + listener->panelChanged (EvHLCompr, costr); + else if (a==hlcomprthresh) + listener->panelChanged (EvHLComprThreshold, costr); + else if (a==shcompr) + listener->panelChanged (EvSHCompr, costr); +} + +void ToneCurve::neutral_pressed () { +// This method deselects auto levels and HL reconstruction auto +// and sets neutral values to params in exposure panel + + if (batchMode) { + autolevels->set_inconsistent (false); + autoconn.block (true); + autolevels->set_active (false); + autoconn.block (false); + + lastAuto = autolevels->get_active (); + } + else { //!batchMode + autolevels->set_active (false); + autolevels->set_inconsistent (false); + } + + expcomp->setValue(0); + hlcompr->setValue(0); + hlcomprthresh->setValue(0); + brightness->setValue(0); + black->setValue(0); + shcompr->setValue(50); + enaconn.block (true); + hrenabled->set_active (false); + enaconn.block (false); + if (!batchMode) + hlrbox->hide(); + if (!black->getAddMode()) shcompr->set_sensitive(!((int)black->getValue ()==0)); //at black=0 shcompr value has no effect + contrast->setValue(0); + //saturation->setValue(0); + + listener->panelChanged (EvNeutralExp, M("GENERAL_ENABLED")); +} +void ToneCurve::autolevels_toggled () { + + if (batchMode) { + if (autolevels->get_inconsistent()) { + autolevels->set_inconsistent (false); + autoconn.block (true); + autolevels->set_active (false); + autoconn.block (false); + } + else if (lastAuto) + autolevels->set_inconsistent (true); + + lastAuto = autolevels->get_active (); + + expcomp->setEditedState (UnEdited); + brightness->setEditedState (UnEdited); + contrast->setEditedState (UnEdited); + black->setEditedState (UnEdited); + hlcompr->setEditedState (UnEdited); + hlcomprthresh->setEditedState (UnEdited); + if (expcomp->getAddMode()) + expcomp->setValue (0); + if (brightness->getAddMode()) + brightness->setValue (0); + if (contrast->getAddMode()) + contrast->setValue (0); + if (black->getAddMode()) + black->setValue (0); + if (hlcompr->getAddMode()) + hlcompr->setValue (0); + if (hlcomprthresh->getAddMode()) + hlcomprthresh->setValue (0); + + if (listener) { + if (!autolevels->get_inconsistent()) { + if (autolevels->get_active ()) + listener->panelChanged (EvAutoExp, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvFixedExp, M("GENERAL_DISABLED")); + } + } + } + else if (/* !batchMode && */ listener) { + if (autolevels->get_active()) { + listener->panelChanged (EvAutoExp, M("GENERAL_ENABLED")); + waitForAutoExp (); + if (!black->getAddMode()) shcompr->set_sensitive(!((int)black->getValue ()==0)); //at black=0 shcompr value has no effect + } + else { + listener->panelChanged (EvFixedExp, M("GENERAL_DISABLED")); + } + } +} + +void ToneCurve::clip_changed () { + + clipDirty = true; + if (autolevels->get_active() && listener) + Glib::signal_idle().connect (sigc::mem_fun(*this, &ToneCurve::clip_changed_)); +} + +bool ToneCurve::clip_changed_ () { + + if (listener) { + listener->panelChanged (EvClip, Glib::ustring::format (std::setprecision(5), sclip->get_value())); + if (!batchMode) + waitForAutoExp (); + } + return false; +} + +void ToneCurve::waitForAutoExp () { + + sclip->set_sensitive (false); + expcomp->setEnabled (false); + brightness->setEnabled (false); + contrast->setEnabled (false); + black->setEnabled (false); + hlcompr->setEnabled (false); + hlcomprthresh->setEnabled (false); + shcompr->setEnabled (false); + contrast->setEnabled (false); + saturation->setEnabled (false); + curveEditorG->set_sensitive (false); + toneCurveMode->set_sensitive (false); + curveEditorG2->set_sensitive (false); + toneCurveMode2->set_sensitive (false); + hrenabled->set_sensitive(false); + method->set_sensitive(false); +} + +int autoExpChangedUI (void* data) { + (static_cast(data))->autoExpComputed_ (); + return 0; +} + +void ToneCurve::autoExpChanged (double expcomp, int bright, int contr, int black, int hlcompr, int hlcomprthresh, bool hlrecons) { + + nextBlack = black; + nextExpcomp = expcomp; + nextBrightness = bright; + nextContrast = contr; + nextHlcompr = hlcompr; + nextHlcomprthresh = hlcomprthresh; + nextHLRecons = hlrecons; + g_idle_add (autoExpChangedUI, this); +} + +void ToneCurve::enableAll () { + + sclip->set_sensitive (true); + expcomp->setEnabled (true); + brightness->setEnabled (true); + black->setEnabled (true); + hlcompr->setEnabled (true); + hlcomprthresh->setEnabled (true); + shcompr->setEnabled (true); + contrast->setEnabled (true); + saturation->setEnabled (true); + curveEditorG->set_sensitive (true); + toneCurveMode->set_sensitive (true); + curveEditorG2->set_sensitive (true); + toneCurveMode2->set_sensitive (true); + hrenabled->set_sensitive(true); + method->set_sensitive(true); +} + +bool ToneCurve::autoExpComputed_ () { + + GThreadLock lock; // All GUI acces from idle_add callbacks or separate thread HAVE to be protected + disableListener (); + enableAll (); + expcomp->setValue (nextExpcomp); + brightness->setValue (nextBrightness); + contrast->setValue (nextContrast); + black->setValue (nextBlack); + hlcompr->setValue (nextHlcompr); + hlcomprthresh->setValue (nextHlcomprthresh); + enaconn.block (true); + hrenabled->set_active (nextHLRecons); + enaconn.block (false); + if (nextHLRecons) + hlrbox->show(); + else if (!batchMode) + hlrbox->hide(); + if (!black->getAddMode()) shcompr->set_sensitive(!((int)black->getValue ()==0)); //at black=0 shcompr value has no effect + enableListener (); + + return false; +} + +void ToneCurve::setBatchMode (bool batchMode) { + ToolPanel::setBatchMode (batchMode); + method->append_text (M("GENERAL_UNCHANGED")); + + removeIfThere (abox, autolevels, false); + autolevels = Gtk::manage (new Gtk::CheckButton (M("TP_EXPOSURE_AUTOLEVELS"))); + autolevels->set_tooltip_markup (M("TP_EXPOSURE_AUTOLEVELS_TIP")); + autoconn = autolevels->signal_toggled().connect( sigc::mem_fun(*this, &ToneCurve::autolevels_toggled) ); + abox->pack_start (*autolevels); + + ToolPanel::setBatchMode (batchMode); + expcomp->showEditedCB (); + black->showEditedCB (); + hlcompr->showEditedCB (); + hlcomprthresh->showEditedCB (); + shcompr->showEditedCB (); + brightness->showEditedCB (); + contrast->showEditedCB (); + saturation->showEditedCB (); + + toneCurveMode->append_text (M("GENERAL_UNCHANGED")); + toneCurveMode2->append_text (M("GENERAL_UNCHANGED")); + + curveEditorG->setBatchMode (batchMode); + curveEditorG2->setBatchMode (batchMode); +} + +void ToneCurve::setAdjusterBehavior (bool expadd, bool hlcompadd, bool hlcompthreshadd, bool bradd, bool blackadd, bool shcompadd, bool contradd, bool satadd) { + + expcomp->setAddMode(expadd); + hlcompr->setAddMode(hlcompadd); + hlcomprthresh->setAddMode(hlcompthreshadd); + brightness->setAddMode(bradd); + black->setAddMode(blackadd); + shcompr->setAddMode(shcompadd); + contrast->setAddMode(contradd); + saturation->setAddMode(satadd); +} + +void ToneCurve::trimValues (rtengine::procparams::ProcParams* pp) { + + expcomp->trimValue(pp->toneCurve.expcomp); + hlcompr->trimValue(pp->toneCurve.hlcompr); + hlcomprthresh->trimValue(pp->toneCurve.hlcomprthresh); + brightness->trimValue(pp->toneCurve.brightness); + black->trimValue(pp->toneCurve.black); + shcompr->trimValue(pp->toneCurve.shcompr); + contrast->trimValue(pp->toneCurve.contrast); + saturation->trimValue(pp->toneCurve.saturation); +} + +void ToneCurve::updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve, LUTu & histCCurve, /*LUTu & histCLurve, LUTu & histLLCurve,*/ LUTu & histLCAM, LUTu & histCCAM, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma) { + + shape->updateBackgroundHistogram (histToneCurve); +} diff --git a/rtgui/tonecurve.h b/rtgui/tonecurve.h new file mode 100644 index 000000000..3a6c7afe3 --- /dev/null +++ b/rtgui/tonecurve.h @@ -0,0 +1,114 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _TONECURVE_H_ +#define _TONECURVE_H_ + +#include +#include "adjuster.h" +#include "toolpanel.h" +#include "curveeditor.h" +#include "curveeditorgroup.h" +#include "mycurve.h" +#include "guiutils.h" + +class ToneCurve : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public rtengine::AutoExpListener,public CurveListener { + + protected: + // from HLRecovery + Gtk::CheckButton* hrenabled; + MyComboBoxText* method; + sigc::connection methconn; + sigc::connection enaconn; + bool lasthrEnabled; + + Gtk::HBox* abox; + Gtk::HBox* hlrbox; + + Gtk::ToggleButton* autolevels; + Gtk::Label* lclip; + MySpinButton* sclip; + Gtk::Button* neutral; + Adjuster* expcomp; + Adjuster* brightness; + Adjuster* black; + Adjuster* hlcompr; + Adjuster* hlcomprthresh; + Adjuster* shcompr; + Adjuster* contrast; + Adjuster* saturation; + MyComboBoxText* toneCurveMode; + MyComboBoxText* toneCurveMode2; + + bool clipDirty, lastAuto; + sigc::connection autoconn, neutralconn, tcmodeconn, tcmode2conn; + CurveEditorGroup* curveEditorG; + CurveEditorGroup* curveEditorG2; + DiagonalCurveEditor* shape; + DiagonalCurveEditor* shape2; + + // used temporarily in eventing + double nextExpcomp; + int nextBrightness; + int nextContrast; + int nextBlack; + int nextHlcompr; + int nextHlcomprthresh; + bool nextHLRecons; + + public: + + ToneCurve (); + ~ToneCurve (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + void setAdjusterBehavior (bool expadd, bool hlcompadd, bool hlcompthreshadd, bool bradd, bool blackadd, bool shcompadd, bool contradd, bool satadd); + void trimValues (rtengine::procparams::ProcParams* pp); + void autoOpenCurve (); + void setEditProvider (EditDataProvider *provider); + + virtual float blendPipetteValues (CurveEditor *ce, float chan1, float chan2, float chan3); + + void adjusterChanged (Adjuster* a, double newval); + void neutral_pressed (); + void autolevels_toggled (); + void clip_changed (); + bool clip_changed_ (); + void waitForAutoExp (); + void autoExpChanged (double expcomp, int bright, int contr, int black, int hlcompr, int hlcomprthresh, bool hlrecons); + bool autoExpComputed_ (); + void enableAll (); + void curveChanged (CurveEditor* ce); + void curveMode1Changed (); + bool curveMode1Changed_ (); + void curveMode2Changed (); + bool curveMode2Changed_ (); + void expandCurve (bool isExpanded); + bool isCurveExpanded (); + void updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve, LUTu & histCCurve,/* LUTu & histCLurve, LUTu & histLLCurve,*/ LUTu & histLCAM, LUTu & histCCAM, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma); + + void setRaw (bool raw); + + void hrenabledChanged (); + void methodChanged (); +}; + +#endif diff --git a/rtgui/toolbar.cc b/rtgui/toolbar.cc new file mode 100644 index 000000000..627670dd9 --- /dev/null +++ b/rtgui/toolbar.cc @@ -0,0 +1,294 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "toolbar.h" +#include "multilangmgr.h" +#include "guiutils.h" + +ToolBar::ToolBar () : listener (NULL) { + + editingMode = false; + + handimg = Gtk::manage (new RTImage ("openhand.png")); + handimg->reference(); + editinghandimg = Gtk::manage (new RTImage ("editmodehand.png")); + editinghandimg->reference(); + + handTool = Gtk::manage (new Gtk::ToggleButton ()); + handTool->add (*handimg); + handimg->show (); + handTool->set_relief(Gtk::RELIEF_NONE); + handTool->show (); + + pack_start (*handTool); + + wbTool = Gtk::manage (new Gtk::ToggleButton ()); + Gtk::Image* wbimg = Gtk::manage (new RTImage ("gtk-color-picker.png")); + wbTool->add (*wbimg); + wbimg->show (); + wbTool->set_relief(Gtk::RELIEF_NONE); + wbTool->show (); + + pack_start (*wbTool); + + cropTool = Gtk::manage (new Gtk::ToggleButton ()); + Gtk::Image* cropimg = Gtk::manage (new RTImage ("crop.png")); + cropTool->add (*cropimg); + cropimg->show (); + cropTool->set_relief(Gtk::RELIEF_NONE); + cropTool->show (); + + pack_start (*cropTool); + + straTool = Gtk::manage (new Gtk::ToggleButton ()); + Gtk::Image* straimg = Gtk::manage (new RTImage ("straighten.png")); + straTool->add (*straimg); + straimg->show (); + straTool->set_relief(Gtk::RELIEF_NONE); + straTool->show (); + + pack_start (*straTool); + + + handTool->set_active (true); + current = TMHand; + + handConn = handTool->signal_toggled().connect( sigc::mem_fun(*this, &ToolBar::hand_pressed)); + wbConn = wbTool->signal_toggled().connect( sigc::mem_fun(*this, &ToolBar::wb_pressed)); + cropConn = cropTool->signal_toggled().connect( sigc::mem_fun(*this, &ToolBar::crop_pressed)); + straConn = straTool->signal_toggled().connect( sigc::mem_fun(*this, &ToolBar::stra_pressed)); + + handTool->set_tooltip_markup (M("TOOLBAR_TOOLTIP_HAND")); + wbTool->set_tooltip_markup (M("TOOLBAR_TOOLTIP_WB")); + cropTool->set_tooltip_markup (M("TOOLBAR_TOOLTIP_CROP")); + straTool->set_tooltip_markup (M("TOOLBAR_TOOLTIP_STRAIGHTEN")); +} + +ToolBar::~ToolBar () { + handimg->unreference(); + editinghandimg->unreference(); + +} +// +// Selects the desired tool without notifying the listener +// +void ToolBar::setTool (ToolMode tool) { + + handConn.block (true); + cropConn.block (true); + if (wbTool) wbConn.block (true); + straConn.block (true); + + bool stopEdit = tool==TMHand && handTool->get_active() && editingMode; + + handTool->set_active (false); + if (wbTool) wbTool->set_active (false); + cropTool->set_active (false); + straTool->set_active (false); + + if (tool==TMHand){ + handTool->set_active (true); + handTool->grab_focus(); // switch focus to the handTool button + } + else if (tool==TMSpotWB) { + if (wbTool) wbTool->set_active (true); + } + else if (tool==TMCropSelect) + cropTool->set_active (true); + else if (tool==TMStraighten) + straTool->set_active (true); + + current = tool; + + handConn.block (false); + cropConn.block (false); + if (wbTool) wbConn.block (false); + straConn.block (false); + + if (stopEdit) { + stopEditMode(); + if (listener) + listener->editModeSwitchedOff(); + } +} + +void ToolBar::startEditMode() { + if (!editingMode) { + handTool->set_active(true); // will call hand_pressed, with editingMode=false + editingMode = true; + handTool->set_image(*editinghandimg); + } + #ifndef NDEBUG + else + printf("Editing mode already active!\n"); + #endif +} + +void ToolBar::stopEditMode() { + if (editingMode) { + editingMode = false; + /* WARNING: Should we toggle the Hand button on? + * This method can be called while another tool is active, e.g. if the user toggle off + * the Subscriber's Edit button. For now, we keep that other tool active. If one want to + * switch to the Hand tool, uncommenting the following line should suffice (not tested). + * + * handTool->set_active(true); + */ + handTool->set_image(*handimg); + } +} + +void ToolBar::hand_pressed () { + + handConn.block (true); + cropConn.block (true); + if (wbTool) wbConn.block (true); + straConn.block (true); + if (current!=TMHand) { + if (wbTool) wbTool->set_active (false); + cropTool->set_active (false); + straTool->set_active (false); + current = TMHand; + } + else { + if (editingMode) + stopEditMode(); + if (listener) + listener->editModeSwitchedOff (); + } + handTool->set_active (true); + handConn.block (false); + cropConn.block (false); + if (wbTool) wbConn.block (false); + straConn.block (false); + + if (listener) + listener->toolSelected (TMHand); +} + +void ToolBar::wb_pressed () { + + handConn.block (true); + cropConn.block (true); + if (wbTool) wbConn.block (true); + straConn.block (true); + if (current!=TMSpotWB) { + handTool->set_active (false); + cropTool->set_active (false); + straTool->set_active (false); + current = TMSpotWB; + } + if (wbTool) wbTool->set_active (true); + handConn.block (false); + cropConn.block (false); + if (wbTool) wbConn.block (false); + straConn.block (false); + + if (listener) + listener->toolSelected (TMSpotWB); +} + +void ToolBar::crop_pressed () { + + handConn.block (true); + cropConn.block (true); + if (wbTool) wbConn.block (true); + straConn.block (true); + if (current!=TMCropSelect) { + handTool->set_active (false); + if (wbTool) wbTool->set_active (false); + straTool->set_active (false); + current = TMCropSelect; + } + cropTool->set_active (true); + handConn.block (false); + cropConn.block (false); + wbConn.block (false); + straConn.block (false); + + if (listener) + listener->toolSelected (TMCropSelect); +} + +void ToolBar::stra_pressed () { + + handConn.block (true); + cropConn.block (true); + if (wbTool) wbConn.block (true); + straConn.block (true); + if (current!=TMStraighten) { + handTool->set_active (false); + if (wbTool) wbTool->set_active (false); + cropTool->set_active (false); + current = TMStraighten; + } + straTool->set_active (true); + handConn.block (false); + cropConn.block (false); + if (wbTool) wbConn.block (false); + straConn.block (false); + + if (listener) + listener->toolSelected (TMStraighten); +} + +bool ToolBar::handleShortcutKey (GdkEventKey* event) { + + bool ctrl = event->state & GDK_CONTROL_MASK; + //bool shift = event->state & GDK_SHIFT_MASK; + bool alt = event->state & GDK_MOD1_MASK; + + if (!ctrl && !alt) { + switch(event->keyval) { + case GDK_w: + case GDK_W: + if(wbTool){ + wb_pressed (); + return true; + } + return false; + case GDK_c: + case GDK_C: + crop_pressed (); + return true; + case GDK_s: + case GDK_S: + stra_pressed (); + return true; + case GDK_h: + case GDK_H: + hand_pressed (); + return true; + } + } + else { + switch (event->keyval) { + } + } + + return false; +} + +void ToolBar::removeWbTool() { + if (wbTool) { + wbConn.disconnect(); + removeIfThere(this, wbTool, false); + wbTool = NULL; + } +} + diff --git a/rtgui/toolbar.h b/rtgui/toolbar.h new file mode 100644 index 000000000..3ec50d65a --- /dev/null +++ b/rtgui/toolbar.h @@ -0,0 +1,76 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef __TOOLBAR_H__ +#define __TOOLBAR_H__ + +#include +#include "toolenum.h" +#include "rtimage.h" + +class ToolBarListener { + + public: + virtual ~ToolBarListener() {} + /// Callback when a tool is selected + virtual void toolSelected (ToolMode tool) {} + + /// Callback when the Edit mode is stopped + virtual void editModeSwitchedOff () {} +}; + +class ToolBar : public Gtk::HBox { + private: + RTImage* handimg; + RTImage* editinghandimg; + + protected: + Gtk::ToggleButton* handTool; + Gtk::ToggleButton* wbTool; + Gtk::ToggleButton* cropTool; + Gtk::ToggleButton* straTool; + ToolBarListener* listener; + ToolMode current; + bool editingMode; // true if the cursor is being used to remotely edit tool's values + sigc::connection handConn; + sigc::connection wbConn; + sigc::connection cropConn; + sigc::connection straConn; + + public: + ToolBar (); + ~ToolBar (); + + void setTool (ToolMode tool); + ToolMode getTool () { return current; } + + void setToolBarListener (ToolBarListener* tpl) { listener = tpl; } + + void startEditMode(); + void stopEditMode(); + + void hand_pressed (); + void wb_pressed (); + void crop_pressed (); + void stra_pressed (); + + bool handleShortcutKey (GdkEventKey* event); + void removeWbTool(); +}; + +#endif diff --git a/rtgui/toolenum.h b/rtgui/toolenum.h new file mode 100644 index 000000000..b07d63ec3 --- /dev/null +++ b/rtgui/toolenum.h @@ -0,0 +1,24 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _TOOLENUM_ +#define _TOOLENUM_ + +enum ToolMode {TMHand=0, TMSpotWB=1, TMCropSelect=2, TMStraighten=3}; + +#endif diff --git a/rtgui/toolpanel.cc b/rtgui/toolpanel.cc new file mode 100644 index 000000000..db8e10d00 --- /dev/null +++ b/rtgui/toolpanel.cc @@ -0,0 +1,151 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "toolpanel.h" +#include "toolpanelcoord.h" +#include "guiutils.h" + +using namespace rtengine::procparams; + + +ToolVBox::ToolVBox() { + updateStyle(); +} + +void ToolVBox::updateStyle() { + if (options.slimUI) { + set_spacing(1); // Vertical space between tools + set_border_width(1); // Space separating the tab's frame and the tools + } + else { + set_spacing(2); // Vertical space between tools + set_border_width(1); // Space separating the tab's frame and the tools 3 + } +} + +void ToolVBox::on_style_changed (const Glib::RefPtr& style) { + updateStyle(); +} + +ToolParamBlock::ToolParamBlock() { + updateStyle(); +} + +void ToolParamBlock::updateStyle() { + if (options.slimUI) { + set_spacing(2); // Vertical space between parameters in a single tool + set_border_width(6); // Space separating the parameters of a tool and its surrounding frame 6 + } + else { + set_spacing(4); // Vertical space between parameters in a single tool + set_border_width(8); // Space separating the parameters of a tool and its surrounding frame 8 + } +} + +void ToolParamBlock::on_style_changed (const Glib::RefPtr& style) { + updateStyle(); +} + +FoldableToolPanel::FoldableToolPanel(Gtk::Box* content, Glib::ustring toolName, Glib::ustring UILabel, bool need11, bool useEnabled) : ToolPanel(toolName, need11), parentContainer(NULL), exp(NULL), lastEnabled(true) +{ + if (!content) + return; + +// exp->set_border_width (5); +// exp->set_use_markup (true); + if (need11) { + Gtk::HBox *titleHBox = Gtk::manage(new Gtk::HBox()); + + Gtk::Label *label = Gtk::manage(new Gtk::Label()); + label->set_markup(Glib::ustring("") + escapeHtmlChars(UILabel) + Glib::ustring("")); + label->set_alignment(Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER); + titleHBox->pack_start(*label, Gtk::PACK_EXPAND_WIDGET, 0); + + RTImage *image = Gtk::manage (new RTImage("zoom-100-identifier.png")); + image->set_tooltip_text(M("TP_GENERAL_11SCALE_TOOLTIP")); + titleHBox->pack_end(*image, Gtk::PACK_SHRINK, 0); + + exp = Gtk::manage (new MyExpander (useEnabled, titleHBox)); + } + else { + exp = Gtk::manage (new MyExpander (useEnabled, UILabel)); + } + exp->signal_button_release_event().connect_notify( sigc::mem_fun(this, &FoldableToolPanel::foldThemAll) ); + enaConn = signal_enabled_toggled().connect( sigc::mem_fun(*this, &FoldableToolPanel::enabled_toggled) ); + + exp->add (*content); + exp->show (); +} + +void FoldableToolPanel::foldThemAll (GdkEventButton* event) { + if (event->button == 3) { + if (listener) + (static_cast(listener))->foldAllButOne( parentContainer, this); + else + (static_cast(tmp))->foldAllButOne( parentContainer, this); + } +} + +void FoldableToolPanel::enabled_toggled() { + if (multiImage) { + if (exp->get_inconsistent()) { + exp->set_inconsistent (false); + enaConn.block (true); + exp->setEnabled (false); + enaConn.block (false); + } + else if (lastEnabled) + exp->set_inconsistent (true); + + lastEnabled = exp->getEnabled(); + } + enabledChanged(); +} + +bool FoldableToolPanel::get_inconsistent() { + return exp->get_inconsistent(); +} + +void FoldableToolPanel::set_inconsistent(bool isInconsistent) { + exp->set_inconsistent(isInconsistent); +} + +bool FoldableToolPanel::getEnabled() { + return exp->getEnabled(); +} + +// do not emit the enabled_toggled event +void FoldableToolPanel::setEnabled(bool isEnabled) { + enaConn.block (true); + exp->setEnabled(isEnabled); + lastEnabled = isEnabled; + enaConn.block (false); +} + +void FoldableToolPanel::setEnabledTooltipMarkup(Glib::ustring tooltipMarkup) { + if (exp) + exp->set_tooltip_markup(tooltipMarkup); +} + +void FoldableToolPanel::setEnabledTooltipText(Glib::ustring tooltipText) { + if (exp) + exp->set_tooltip_text(tooltipText); +} + + + diff --git a/rtgui/toolpanel.h b/rtgui/toolpanel.h new file mode 100644 index 000000000..cf2dad030 --- /dev/null +++ b/rtgui/toolpanel.h @@ -0,0 +1,141 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef __TOOLPANEL__ +#define __TOOLPANEL__ + +#include +#include +#include "../rtengine/rtengine.h" +#include "../rtengine/procparams.h" +#include "guiutils.h" +#include "multilangmgr.h" +#include "paramsedited.h" +#include "edit.h" + +class ToolPanel; +class FoldableToolPanel; + +class ToolPanelListener { + + public: + + virtual ~ToolPanelListener() {} + virtual void panelChanged (rtengine::ProcEvent event, const Glib::ustring& descr) {} +}; + +/// @brief This class control the space around the group of tools inside a tab, as well as the space separating each tool. */ +class ToolVBox : public Gtk::VBox { + private: + void updateStyle(); + + public: + ToolVBox(); + void on_style_changed (const Glib::RefPtr& style); +}; + +/// @brief This class control the space around a tool's block of parameter. */ +class ToolParamBlock : public Gtk::VBox { + private: + void updateStyle(); + + public: + ToolParamBlock(); + void on_style_changed (const Glib::RefPtr& style); +}; + +class ToolPanel { + + protected: + Glib::ustring toolName; + ToolPanelListener* listener; + ToolPanelListener* tmp; + bool batchMode; // True if the ToolPanel is used in Batch mode + bool multiImage; // True if more than one image are being edited at the same time (also imply that batchMode=true), false otherwise + bool need100Percent; + + public: + + ToolPanel (Glib::ustring toolName="", bool need11=false) : toolName(toolName), listener(NULL), tmp(NULL), batchMode(false), multiImage(false), need100Percent(need11) {} + virtual ~ToolPanel() {} + + virtual void setParent (Gtk::Box* parent) {} + virtual Gtk::Box* getParent () { return NULL; } + virtual MyExpander* getExpander () { return NULL; } + virtual void setExpanded (bool expanded) {} + virtual bool getExpanded () { return false; } + void setMultiImage (bool m) { multiImage = m; } + void setListener (ToolPanelListener* tpl) { listener = tpl; } + virtual void setEditProvider (EditDataProvider *provider) {} + virtual void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL) {} + virtual void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL) {} + virtual void trimValues (rtengine::procparams::ProcParams* pp) { return; } + virtual void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL) {} + virtual void autoOpenCurve () {} + + /** @brief Disable the event broadcasting mechanism + * + * @return Return the previous state of the broadcast (true: enabled ; false: disabled) + */ + bool disableListener () { if (tmp==NULL) tmp = listener; bool prevState = listener!=NULL; listener = NULL; return prevState; } + + /** @brief Enable the event broadcasting mechanism + */ + void enableListener () { if (tmp!=NULL) listener = tmp; tmp = NULL; } + + virtual void setBatchMode (bool batchMode) { this->batchMode = batchMode; } + +}; + +class FoldableToolPanel : public ToolPanel { + + protected: + Gtk::Box* parentContainer; + MyExpander* exp; + bool lastEnabled; + sigc::connection enaConn; + void foldThemAll (GdkEventButton* event); + void enabled_toggled(); + + public: + + FoldableToolPanel(Gtk::Box* content, Glib::ustring toolName, Glib::ustring UILabel, bool need11=false, bool useEnabled=false); + + MyExpander* getExpander() { return exp; } + void setExpanded (bool expanded) { if (exp) exp->set_expanded( expanded ); } + bool getExpanded () { if (exp) return exp->get_expanded(); return false; } + void setParent (Gtk::Box* parent) { parentContainer = parent; } + Gtk::Box* getParent () { return parentContainer; } + + virtual void enabledChanged () {} + + bool getUseEnabled () { if (exp) return exp->getUseEnabled(); else return true; } + bool getEnabled(); // related to the enabled/disabled state + void setEnabled(bool isActive); // related to the enabled/disabled state + void setEnabledTooltipMarkup(Glib::ustring tooltipMarkup); + void setEnabledTooltipText(Glib::ustring tooltipText); + bool get_inconsistent(); // related to the enabled/disabled state + void set_inconsistent(bool isInconsistent); // related to the enabled/disabled state + + // Functions that want to receive an enabled/disabled event from this class + // will have to receive it from MyExpander directly, we do not create + // a relaying event + MyExpander::type_signal_enabled_toggled signal_enabled_toggled() { return exp->signal_enabled_toggled(); } +}; + +#endif diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc new file mode 100644 index 000000000..5ccb3488e --- /dev/null +++ b/rtgui/toolpanelcoord.cc @@ -0,0 +1,740 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "multilangmgr.h" +#include "toolpanelcoord.h" +#include "options.h" +#include "../rtengine/imagesource.h" +#include "../rtengine/dfmanager.h" +#include "../rtengine/ffmanager.h" +#include "../rtengine/improcfun.h" +#include "../rtengine/procevents.h" +#include "../rtengine/refreshmap.h" + +using namespace rtengine::procparams; + +ToolPanelCoordinator::ToolPanelCoordinator () : ipc(NULL) { + + exposurePanel = Gtk::manage (new ToolVBox ()); + detailsPanel = Gtk::manage (new ToolVBox ()); + colorPanel = Gtk::manage (new ToolVBox ()); + transformPanel = Gtk::manage (new ToolVBox ()); + rawPanel = Gtk::manage (new ToolVBox ()); + waveletPanel = Gtk::manage (new ToolVBox ()); + + coarse = Gtk::manage (new CoarsePanel ()); + toneCurve = Gtk::manage (new ToneCurve ()); + shadowshighlights = Gtk::manage (new ShadowsHighlights ()); + impulsedenoise = Gtk::manage (new ImpulseDenoise ()); + defringe = Gtk::manage (new Defringe ()); + dirpyrdenoise = Gtk::manage (new DirPyrDenoise ()); + epd = Gtk::manage (new EdgePreservingDecompositionUI ()); + sharpening = Gtk::manage (new Sharpening ()); + sharpenEdge = Gtk::manage (new SharpenEdge ()); + sharpenMicro = Gtk::manage (new SharpenMicro ()); + lcurve = Gtk::manage (new LCurve ()); + rgbcurves = Gtk::manage (new RGBCurves ()); + colortoning = Gtk::manage (new ColorToning ()); + lensgeom = Gtk::manage (new LensGeometry ()); + lensProf = Gtk::manage (new LensProfilePanel ()); + 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 ()); + gradient = Gtk::manage (new Gradient ()); + pcvignette = Gtk::manage (new PCVignette ()); + perspective = Gtk::manage (new PerspCorrection ()); + cacorrection = Gtk::manage (new CACorrection ()); + chmixer = Gtk::manage (new ChMixer ()); + blackwhite = Gtk::manage (new BlackWhite ()); + resize = Gtk::manage (new Resize ()); + 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 ()); + wavelet = Gtk::manage (new Wavelet ()); + dirpyrequalizer = Gtk::manage (new DirPyrEqualizer ()); + hsvequalizer = Gtk::manage (new HSVEqualizer ()); + filmSimulation = Gtk::manage (new FilmSimulation ()); + sensorbayer = Gtk::manage (new SensorBayer ()); + sensorxtrans = Gtk::manage (new SensorXTrans ()); + bayerprocess = Gtk::manage (new BayerProcess ()); + xtransprocess = Gtk::manage (new XTransProcess ()); + bayerpreprocess = Gtk::manage (new BayerPreProcess ()); + preprocess = Gtk::manage (new PreProcess ()); + darkframe = Gtk::manage (new DarkFrame ()); + flatfield = Gtk::manage (new FlatField ()); + rawcacorrection = Gtk::manage (new RAWCACorr ()); + rawexposure = Gtk::manage (new RAWExposure ()); + bayerrawexposure = Gtk::manage (new BayerRAWExposure ()); + xtransrawexposure = Gtk::manage (new XTransRAWExposure ()); + + // 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 + + // X-Trans demozaic methods: "3-pass (best), 1-pass (medium), fast" + // Mettre jour les profils fournis pour inclure les nouvelles section Raw, notamment pour "Default High ISO" + // Valeurs par dfaut: + // Best -> low ISO + // 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, 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, 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); toolPanels.push_back (prsharpening); + addPanel (transformPanel, lensgeom); toolPanels.push_back (lensgeom); + addPanel (lensgeom->getPackBox(), rotate); toolPanels.push_back (rotate); + addPanel (lensgeom->getPackBox(), perspective); toolPanels.push_back (perspective); + addPanel (lensgeom->getPackBox(), lensProf); toolPanels.push_back (lensProf); + addPanel (lensgeom->getPackBox(), distortion); toolPanels.push_back (distortion); + addPanel (lensgeom->getPackBox(), cacorrection); toolPanels.push_back (cacorrection); + addPanel (lensgeom->getPackBox(), vignetting); toolPanels.push_back (vignetting); + addPanel (colorPanel, icm); toolPanels.push_back (icm); + addPanel (rawPanel, sensorbayer); toolPanels.push_back (sensorbayer); + addPanel (sensorbayer->getPackBox(), bayerprocess); toolPanels.push_back (bayerprocess); + addPanel (sensorbayer->getPackBox(), bayerrawexposure); toolPanels.push_back (bayerrawexposure); + addPanel (sensorbayer->getPackBox(), bayerpreprocess); toolPanels.push_back (bayerpreprocess); + addPanel (sensorbayer->getPackBox(), rawcacorrection); toolPanels.push_back (rawcacorrection); + addPanel (rawPanel, sensorxtrans); toolPanels.push_back (sensorxtrans); + addPanel (sensorxtrans->getPackBox(), xtransprocess); toolPanels.push_back (xtransprocess); + addPanel (sensorxtrans->getPackBox(), xtransrawexposure); 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 ()); + toolPanelNotebook = new Gtk::Notebook (); + + 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 ()); + colorPanelSW = Gtk::manage (new MyScrolledWindow ()); + transformPanelSW = Gtk::manage (new MyScrolledWindow ()); + rawPanelSW = Gtk::manage (new MyScrolledWindow ()); + waveletPanelSW = Gtk::manage (new MyScrolledWindow ()); + updateVScrollbars (options.hideTPVScrollbar); + + // 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]->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 (*vbPanelEnd[0],Gtk::PACK_SHRINK,4); + + detailsPanelSW->add (*detailsPanel); + 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 (*vbPanelEnd[2],Gtk::PACK_SHRINK,4); + + waveletPanelSW->add (*waveletPanel); + 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 (*vbPanelEnd[3],Gtk::PACK_SHRINK,4); + + rawPanelSW->add (*rawPanel); + 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)); + + toolPanelNotebook->append_page (*exposurePanelSW, *toiE); + toolPanelNotebook->append_page (*detailsPanelSW, *toiD); + toolPanelNotebook->append_page (*colorPanelSW, *toiC); + toolPanelNotebook->append_page (*waveletPanelSW, *toiW); + toolPanelNotebook->append_page (*transformPanelSW, *toiT); + toolPanelNotebook->append_page (*rawPanelSW, *toiR); + toolPanelNotebook->append_page (*metadataPanel, *toiM); + + toolPanelNotebook->set_current_page (0); + + toolPanelNotebook->set_scrollable (); + toolPanelNotebook->show_all (); + + for (size_t i=0; isetListener (this); + + whitebalance->setWBProvider (this); + whitebalance->setSpotWBListener (this); + darkframe->setDFProvider (this); + flatfield->setFFProvider (this); + lensgeom->setLensGeomListener (this); + rotate->setLensGeomListener (this); + distortion->setLensGeomListener (this); + crop->setCropPanelListener (this); + icm->setICMPanelListener (this); + + toolBar = new ToolBar (); + toolBar->setToolBarListener(this); +} + +void ToolPanelCoordinator::addPanel (Gtk::Box* where, FoldableToolPanel* panel) { + + // no more separator! + /*if (where->children().size()) { + Gtk::HSeparator *hsep = Gtk::manage (new Gtk::HSeparator()); + where->pack_start(*hsep, Gtk::PACK_SHRINK, 0); + hsep->show(); + }*/ + + panel->setParent(where); + + expList.push_back (panel->getExpander()); + where->pack_start(*panel->getExpander(), false, false); +} + +ToolPanelCoordinator::~ToolPanelCoordinator () { + + closeImage (); + + delete toolPanelNotebook; + delete toolBar; +} + +void ToolPanelCoordinator::panelChanged (rtengine::ProcEvent event, const Glib::ustring& descr) { + + if (!ipc) return; + + int changeFlags=refreshmap[(int)event]; + + ProcParams* params = ipc->beginUpdateParams (); + for (size_t i=0; iwrite (params); + + // Compensate rotation on flip + if (event==rtengine::EvCTHFlip || event==rtengine::EvCTVFlip) { + if (fabs(params->rotate.degree)>0.001) { + params->rotate.degree *= -1; + changeFlags |= refreshmap[(int)rtengine::EvROTDegree]; + rotate->read (params); + } + } + + // some transformations make the crop change for convenience + if (event==rtengine::EvCTHFlip) { + crop->hFlipCrop (); + crop->write (params); + } + else if (event==rtengine::EvCTVFlip) { + crop->vFlipCrop (); + crop->write (params); + } + else if (event==rtengine::EvCTRotate) { + crop->rotateCrop (params->coarse.rotate, params->coarse.hflip, params->coarse.vflip); + crop->write (params); + resize->update (params->crop.enabled, params->crop.w, params->crop.h, ipc->getFullWidth(), ipc->getFullHeight()); + resize->write (params); + } + else if (event==rtengine::EvCrop) { + resize->update (params->crop.enabled, params->crop.w, params->crop.h); + resize->write (params); + } + + ipc->endUpdateParams (changeFlags); // starts the IPC processing + + hasChanged = true; + + for (size_t i=0; iprocParamsChanged (params, event, descr); +} + +void ToolPanelCoordinator::profileChange (const PartialProfile *nparams, rtengine::ProcEvent event, const Glib::ustring& descr, const ParamsEdited* paramsEdited) { + + int fw, fh, tr; + + if (!ipc) return; + ProcParams *params = ipc->beginUpdateParams (); + ProcParams *mergedParams = new ProcParams(); + + // Copy the current params as default values for the fusion + *mergedParams = *params; + + // Reset IPTC values when switching procparams from the History + if (event == rtengine::EvHistoryBrowsed) { + mergedParams->iptc.clear(); + mergedParams->exif.clear(); + } + + // And apply the partial profile nparams to 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); + lParams[0]=*params; lParams[1]=*mergedParams; + pe.initFrom (lParams); + + filterRawRefresh = pe.raw.isUnchanged() && pe.lensProf.isUnchanged(); + } + + *params = *mergedParams; + delete mergedParams; + + tr = TR_NONE; + if (params->coarse.rotate==90) tr |= TR_R90; + if (params->coarse.rotate==180) tr |= TR_R180; + if (params->coarse.rotate==270) tr |= TR_R270; + + // trimming overflowing cropped area + rtengine::ImageSource *ii = (rtengine::ImageSource*)ipc->getInitialImage(); + ii->getFullSize (fw, fh, tr); + crop->trim(params, fw, fh); + + // updating the GUI with updated values + for (unsigned int i=0; iread (params); + if (event==rtengine::EvPhotoLoaded || event==rtengine::EvProfileChanged) + toolPanels[i]->autoOpenCurve(); + } + + // start the IPC processing + if (filterRawRefresh) { + ipc->endUpdateParams ( refreshmap[(int)event] & ALLNORAW ); + } else + ipc->endUpdateParams (event); + + hasChanged = event != rtengine::EvProfileChangeNotification; + + for (size_t i=0; iprocParamsChanged (params, event, descr); +} + +void ToolPanelCoordinator::setDefaults (ProcParams* defparams) { + + if (defparams) + for (size_t i=0; isetDefaults (defparams); +} + +CropGUIListener* ToolPanelCoordinator::getCropGUIListener () { + + return crop; +} + +void ToolPanelCoordinator::initImage (rtengine::StagedImageProcessor* ipc_, bool raw) { + + ipc = ipc_; + toneCurve->disableListener (); + toneCurve->enableAll (); + toneCurve->enableListener (); + + const rtengine::ImageMetaData* pMetaData=ipc->getInitialImage()->getMetaData(); + exifpanel->setImageData (pMetaData); + iptcpanel->setImageData (pMetaData); + + if (ipc) { + ipc->setAutoExpListener (toneCurve); + ipc->setAutoCamListener (colorappearance); + ipc->setAutoBWListener (blackwhite); + ipc->setAutoColorTonListener (colortoning); + ipc->setAutoChromaListener (dirpyrdenoise); + ipc->setWaveletListener (wavelet); + + ipc->setSizeListener (crop); + ipc->setSizeListener (resize); + } + flatfield->setShortcutPath(Glib::path_get_dirname(ipc->getInitialImage()->getFileName())); + + icm->setRawMeta (raw, (const rtengine::ImageData*)pMetaData); + lensProf->setRawMeta (raw, pMetaData); + + toneCurve->setRaw (raw); + hasChanged = true; +} + + +void ToolPanelCoordinator::closeImage () { + + if (ipc) { + ipc->stopProcessing (); + ipc = NULL; + } +} + +void ToolPanelCoordinator::closeAllTools() { + + for (size_t i=0; iset_expanded (false); +} + +void ToolPanelCoordinator::openAllTools() { + + for (size_t i=0; iset_expanded (true); +} + +void ToolPanelCoordinator::updateToolState() { + + for (size_t i=0; iset_expanded (options.tpOpen.at(i)); + + size_t sizeWavelet = options.tpOpen.size() - expList.size(); + if(sizeWavelet > 0) { + std::vector temp; + temp.resize(sizeWavelet); + for (size_t i=0; iupdateToolState(temp); + wavelet->setExpanded(true); + } +} + +void ToolPanelCoordinator::readOptions () { + + crop->readOptions (); +} + +void ToolPanelCoordinator::writeOptions () { + + crop->writeOptions (); + options.tpOpen.clear (); + for (size_t i=0; iget_expanded ()); + wavelet->writeOptions(options.tpOpen); +} + + +void ToolPanelCoordinator::cropSelectionReady () { + + toolBar->setTool (TMHand); + + if (!ipc) + return; +} + +void ToolPanelCoordinator::rotateSelectionReady (double rotate_deg, Thumbnail* thm) { + + toolBar->setTool (TMHand); + + if (!ipc) + return; + + if (rotate_deg!=0.0) + rotate->straighten (rotate_deg); +} + +void ToolPanelCoordinator::spotWBselected (int x, int y, Thumbnail* thm) { + + if (!ipc) + return; + +// toolBar->setTool (TOOL_HAND); + int rect=whitebalance->getSize (); + int ww= ipc->getFullWidth(); + int hh= ipc->getFullHeight(); + + if (x-rect>0 && y-rect>0 && x+rectgetSpotWB (x, y, rect, temp, green); + whitebalance->setWB (temp, green); + } +} + + + + +void ToolPanelCoordinator::autoCropRequested () { + + if (!ipc) + return; + + int x1, y1, x2, y2, w, h; + ipc->getAutoCrop (crop->getRatio(), x1, y1, w, h); + x2 = x1 + w - 1; + y2 = y1 + h - 1; + crop->cropInit (x1, y1, w, h); + crop->cropResized (x1, y1, x2, y2); + crop->cropManipReady (); +} + +rtengine::RawImage* ToolPanelCoordinator::getDF() +{ + if (!ipc) + return NULL; + const rtengine::ImageMetaData *imd = ipc->getInitialImage()->getMetaData(); + if(imd){ + int iso = imd->getISOSpeed(); + double shutter = imd->getShutterSpeed(); + 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 NULL; +} + +rtengine::RawImage* ToolPanelCoordinator::getFF() +{ + if (!ipc) + return NULL; + const rtengine::ImageMetaData *imd = ipc->getInitialImage()->getMetaData(); + 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() ); + time_t timestamp = imd->getDateTimeAsTS(); + + return rtengine::ffm.searchFlatField( maker,model,lens,focallength,aperture,timestamp); + } + return NULL; +} + +Glib::ustring ToolPanelCoordinator::GetCurrentImageFilePath() +{ + if (!ipc){ + return ""; + } + return ipc->getInitialImage()->getFileName(); +} + +void ToolPanelCoordinator::straightenRequested () { + + if (!ipc) + return; + + toolBar->setTool (TMStraighten); +} + +double ToolPanelCoordinator::autoDistorRequested () { + if (!ipc) + return 0.0; + return rtengine::ImProcFunctions::getAutoDistor (ipc->getInitialImage()->getFileName(), 400); +} + +void ToolPanelCoordinator::spotWBRequested (int size) { + + if (!ipc) + return; + + toolBar->setTool (TMSpotWB); +} + +void ToolPanelCoordinator::cropSelectRequested () { + + if (!ipc) + return; + + toolBar->setTool (TMCropSelect); +} + +void ToolPanelCoordinator::saveInputICCReference (Glib::ustring fname, bool apply_wb) { + + if (ipc) + ipc->saveInputICCReference (fname, apply_wb); +} + +int ToolPanelCoordinator::getSpotWBRectSize () { + + return whitebalance->getSize (); +} + +void ToolPanelCoordinator::updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve, LUTu & histCCurve, /*LUTu & histCLurve, LUTu & histLLCurve,*/ LUTu & histLCAM, LUTu & histCCAM, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma) { + colorappearance->updateCurveBackgroundHistogram (histToneCurve, histLCurve, histCCurve, /*histCLurve, histLLCurve,*/ histLCAM, histCCAM,histRed, histGreen, histBlue, histLuma); + toneCurve->updateCurveBackgroundHistogram (histToneCurve, histLCurve,histCCurve,/* histCLurve, histLLCurve,*/ histLCAM, histCCAM,histRed, histGreen, histBlue, histLuma); + lcurve->updateCurveBackgroundHistogram (histToneCurve, histLCurve, histCCurve, /*histCLurve, histLLCurve,*/ histLCAM, histCCAM,histRed, histGreen, histBlue, histLuma); + rgbcurves->updateCurveBackgroundHistogram(histToneCurve, histLCurve, histCCurve,/* histCLurve, histLLCurve, */histLCAM, histCCAM,histRed,histGreen, histBlue, histLuma); +} + +void ToolPanelCoordinator::foldAllButOne (Gtk::Box* parent, FoldableToolPanel* openedSection) { + + for (size_t i=0; igetParent() != NULL) { + ToolPanel* currentTP = toolPanels[i]; + 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); + } + else { + if (!currentTP->getExpanded()) + currentTP->setExpanded(true); + } + } + } + } +} + +bool ToolPanelCoordinator::handleShortcutKey (GdkEventKey* event) { + + //bool ctrl = event->state & GDK_CONTROL_MASK; temporarily removed because unused + //bool shift = event->state & GDK_SHIFT_MASK; temporarily removed because unused + bool alt = event->state & GDK_MOD1_MASK; + + if (alt){ + switch(event->keyval) { + case GDK_e: + toolPanelNotebook->set_current_page (toolPanelNotebook->page_num(*exposurePanelSW)); + return true; + case GDK_d: + toolPanelNotebook->set_current_page (toolPanelNotebook->page_num(*detailsPanelSW)); + return true; + case GDK_c: + toolPanelNotebook->set_current_page (toolPanelNotebook->page_num(*colorPanelSW)); + return true; + case GDK_t: + toolPanelNotebook->set_current_page (toolPanelNotebook->page_num(*transformPanelSW)); + return true; + case GDK_r: + toolPanelNotebook->set_current_page (toolPanelNotebook->page_num(*rawPanelSW)); + return true; + case GDK_w: + toolPanelNotebook->set_current_page (toolPanelNotebook->page_num(*waveletPanelSW)); + return true; + case GDK_m: + if (metadataPanel){ + toolPanelNotebook->set_current_page (toolPanelNotebook->page_num(*metadataPanel)); + return true; + } + } + } + return false; +} + +void ToolPanelCoordinator::updateVScrollbars (bool hide) { + GThreadLock lock; // All GUI acces from idle_add callbacks or separate thread HAVE to be protected + Gtk::PolicyType policy = hide ? Gtk::POLICY_NEVER : Gtk::POLICY_AUTOMATIC; + exposurePanelSW->set_policy (Gtk::POLICY_AUTOMATIC, policy); + detailsPanelSW->set_policy (Gtk::POLICY_AUTOMATIC, policy); + colorPanelSW->set_policy (Gtk::POLICY_AUTOMATIC, policy); + transformPanelSW->set_policy (Gtk::POLICY_AUTOMATIC, policy); + rawPanelSW->set_policy (Gtk::POLICY_AUTOMATIC, policy); + waveletPanelSW->set_policy (Gtk::POLICY_AUTOMATIC, policy); +} + +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); + if (toiM) + toiM->switchTo(type); +} + +void ToolPanelCoordinator::updateTPVScrollbar (bool hide) { + updateVScrollbars (hide); +} + +void ToolPanelCoordinator::updateTabsUsesIcons (bool useIcons) { + updateTabsHeader (useIcons); +} + +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 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; + default: + break; + } +} + +void ToolPanelCoordinator::editModeSwitchedOff () { + if (editDataProvider) { + editDataProvider->switchOffEditMode(); + } +} + +void ToolPanelCoordinator::dirSelected (const Glib::ustring& dirname, const Glib::ustring& openfile) { + + flatfield->setShortcutPath(dirname); +} + +void ToolPanelCoordinator::setEditProvider(EditDataProvider *provider) { + editDataProvider = provider; + for (size_t i=0; isetEditProvider(provider); +} diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h new file mode 100644 index 000000000..2ada0556d --- /dev/null +++ b/rtgui/toolpanelcoord.h @@ -0,0 +1,295 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef __TOOLPANELCCORD__ +#define __TOOLPANELCCORD__ + +#include "../rtengine/rtengine.h" +#include "toolpanel.h" +#include +#include "pparamschangelistener.h" +#include "profilechangelistener.h" +#include "imageareatoollistener.h" +#include +#include "whitebalance.h" +#include "coarsepanel.h" +#include "tonecurve.h" +#include "vibrance.h" +#include "colorappearance.h" +#include "shadowshighlights.h" +#include "impulsedenoise.h" +#include "defringe.h" +#include "dirpyrdenoise.h" +#include "epd.h" +#include "sharpening.h" +#include "labcurve.h" +#include "exifpanel.h" +#include "iptcpanel.h" +#include "crop.h" +#include "icmpanel.h" +#include "resize.h" +#include "chmixer.h" +#include "blackwhite.h" +#include "cacorrection.h" +#include "lensprofile.h" +#include "distortion.h" +#include "perspective.h" +#include "rotate.h" +#include "vignetting.h" +#include "gradient.h" +#include "pcvignette.h" +#include "toolbar.h" +#include "lensgeom.h" +#include "lensgeomlistener.h" +#include "dirselectionlistener.h" +#include "wavelet.h" +#include "dirpyrequalizer.h" +#include "hsvequalizer.h" +#include "preprocess.h" +#include "bayerpreprocess.h" +#include "bayerprocess.h" +#include "xtransprocess.h" +#include "darkframe.h" +#include "flatfield.h" +#include "sensorbayer.h" +#include "sensorxtrans.h" +#include "rawcacorrection.h" +#include "rawexposure.h" +#include "bayerrawexposure.h" +#include "xtransrawexposure.h" +#include "sharpenmicro.h" +#include "sharpenedge.h" +#include "rgbcurves.h" +#include "colortoning.h" +#include "filmsimulation.h" +#include "prsharpening.h" +#include "guiutils.h" + +class ImageEditorCoordinator; + +class ToolPanelCoordinator : public ToolPanelListener, + public ToolBarListener, + public ProfileChangeListener, + public WBProvider, + public DFProvider, + public FFProvider, + public LensGeomListener, + public SpotWBListener, + public CropPanelListener, + public ICMPanelListener, + public DirSelectionListener, + public ImageAreaToolListener { + + protected: + + WhiteBalance* whitebalance; + Vignetting* vignetting; + Gradient* gradient; + PCVignette* pcvignette; + LensGeometry* lensgeom; + LensProfilePanel* lensProf; + Rotate* rotate; + Distortion* distortion; + PerspCorrection* perspective; + CACorrection* cacorrection; + ColorAppearance* colorappearance; + Vibrance* vibrance; + ChMixer* chmixer; + BlackWhite* blackwhite; + Resize* resize; + PrSharpening* prsharpening; + ICMPanel* icm; + Crop* crop; + ToneCurve* toneCurve; + ShadowsHighlights* shadowshighlights; + Defringe* defringe; + ImpulseDenoise* impulsedenoise; + DirPyrDenoise* dirpyrdenoise; + EdgePreservingDecompositionUI *epd; + Sharpening* sharpening; + SharpenEdge* sharpenEdge; + SharpenMicro* sharpenMicro; + LCurve* lcurve; + RGBCurves* rgbcurves; + ColorToning* colortoning; + Wavelet * wavelet; + DirPyrEqualizer* dirpyrequalizer; + HSVEqualizer* hsvequalizer; + FilmSimulation *filmSimulation; + SensorBayer * sensorbayer; + SensorXTrans * sensorxtrans; + BayerProcess* bayerprocess; + XTransProcess* xtransprocess; + BayerPreProcess* bayerpreprocess; + PreProcess* preprocess; + DarkFrame* darkframe; + FlatField* flatfield; + RAWCACorr* rawcacorrection; + RAWExposure* rawexposure; + BayerRAWExposure* bayerrawexposure; + XTransRAWExposure* xtransrawexposure; + + std::vector paramcListeners; + + rtengine::StagedImageProcessor* ipc; + + std::vector toolPanels; + ToolVBox* exposurePanel; + ToolVBox* detailsPanel; + ToolVBox* colorPanel; + ToolVBox* transformPanel; + ToolVBox* rawPanel; + ToolVBox* waveletPanel; + Gtk::Notebook* metadataPanel; + ExifPanel* exifpanel; + IPTCPanel* iptcpanel; + ToolBar* toolBar; + + TextOrIcon* toiE; + TextOrIcon* toiD; + TextOrIcon* toiC; + TextOrIcon* toiT; + TextOrIcon* toiR; + TextOrIcon* toiM; + TextOrIcon* toiW; + + Gtk::Label* labelE; + Gtk::Label* labelD; + Gtk::Label* labelC; + Gtk::Label* labelT; + Gtk::Label* labelR; + Gtk::Label* labelM; + + Gtk::Image* imgIconE; + Gtk::Image* imgIconD; + Gtk::Image* imgIconC; + Gtk::Image* imgIconT; + Gtk::Image* imgIconR; + Gtk::Image* imgIconM; + Gtk::Image* imgPanelEnd[6]; + Gtk::VBox* vbPanelEnd[6]; + + Gtk::ScrolledWindow* exposurePanelSW; + Gtk::ScrolledWindow* detailsPanelSW; + Gtk::ScrolledWindow* colorPanelSW; + Gtk::ScrolledWindow* transformPanelSW; + Gtk::ScrolledWindow* rawPanelSW; + Gtk::ScrolledWindow* waveletPanelSW; + + std::vector expList; + + bool hasChanged; + + void addPanel (Gtk::Box* where, FoldableToolPanel* panel); + void foldThemAll (GdkEventButton* event); + void updateVScrollbars (bool hide); + void updateTabsHeader (bool useIcons); + + private: + + EditDataProvider *editDataProvider; + + public: + + CoarsePanel* coarse; + Gtk::Notebook* toolPanelNotebook; + + ToolPanelCoordinator (); + virtual ~ToolPanelCoordinator (); + + bool getChangedState () { return hasChanged; } + void updateCurveBackgroundHistogram (LUTu & histToneCurve, LUTu & histLCurve,LUTu & histCCurve, /*LUTu & histCLurve, LUTu & histLLCurve,*/ LUTu & histLCAM, LUTu & histCCAM, LUTu & histRed, LUTu & histGreen, LUTu & histBlue, LUTu & histLuma); + void foldAllButOne (Gtk::Box* parent, FoldableToolPanel* openedSection); + + // multiple listeners can be added that are notified on changes (typical: profile panel and the history) + void addPParamsChangeListener (PParamsChangeListener* pp) { paramcListeners.push_back (pp); } + + // toolpanellistener interface + void panelChanged (rtengine::ProcEvent event, const Glib::ustring& descr); + + // profilechangelistener interface + void profileChange (const rtengine::procparams::PartialProfile* nparams, rtengine::ProcEvent event, const Glib::ustring& descr, const ParamsEdited* paramsEdited=NULL); + void setDefaults (rtengine::procparams::ProcParams* defparams); + + // DirSelectionListener interface + void dirSelected (const Glib::ustring& dirname, const Glib::ustring& openfile=""); + + // to support the GUI: + CropGUIListener* getCropGUIListener (); // through the CropGUIListener the editor area can notify the "crop" ToolPanel when the crop selection changes + + // init the toolpanelcoordinator with an image & close it + void initImage (rtengine::StagedImageProcessor* ipc_, bool israw); + void closeImage (); + + // update the "expanded" state of the Tools + void updateToolState (); + void openAllTools (); + void closeAllTools (); + // read/write the "expanded" state of the expanders & read/write the crop panel settings (ratio, guide type, etc.) + void readOptions (); + void writeOptions (); + + // wbprovider interface + void getAutoWB (double& temp, double& green, double equal) { + if (ipc) + ipc->getAutoWB (temp, green, equal); + } + void getCamWB (double& temp, double& green) { if (ipc) ipc->getCamWB (temp, green); } + + //DFProvider interface + rtengine::RawImage* getDF(); + + //FFProvider interface + rtengine::RawImage* getFF(); + Glib::ustring GetCurrentImageFilePath(); + + // rotatelistener interface + void straightenRequested (); + void autoCropRequested (); + double autoDistorRequested (); + + // spotwblistener interface + void spotWBRequested (int size); + + // croppanellistener interface + void cropSelectRequested (); + + // icmpanellistener interface + void saveInputICCReference (Glib::ustring fname, bool apply_wb); + + // imageareatoollistener interface + void spotWBselected (int x, int y, Thumbnail* thm=NULL); + void cropSelectionReady (); + void rotateSelectionReady (double rotate_deg, Thumbnail* thm=NULL); + ToolBar* getToolBar () { return toolBar; } + void removeWbTool() { if (toolBar) toolBar->removeWbTool(); } + int getSpotWBRectSize (); + CropGUIListener* startCropEditing (Thumbnail* thm=NULL) { return crop; } + + void updateTPVScrollbar (bool hide); + void updateTabsUsesIcons (bool useIcons); + bool handleShortcutKey (GdkEventKey* event); + + // ToolBarListener interface + void toolSelected (ToolMode tool); + void editModeSwitchedOff (); + + void setEditProvider(EditDataProvider *provider); +}; + +#endif diff --git a/rtgui/version.h.in b/rtgui/version.h.in new file mode 100644 index 000000000..29e7ccbed --- /dev/null +++ b/rtgui/version.h.in @@ -0,0 +1,13 @@ +// This file is automatically generated by the Makefile - DO NOT EDIT! +// You can (should) also tell mercurial to ignore it. + +#ifndef _VERSION_ +#define _VERSION_ + +#define VERSION "${HG_VERSION}" +#define VERSION_SUFFIX "${VERSION_SUFFIX}" +#define TAGDISTANCE ${HG_TAGDISTANCE} +#define CACHEFOLDERNAME "RawTherapee${CACHE_NAME_SUFFIX}" + +#endif + diff --git a/rtgui/vibrance.cc b/rtgui/vibrance.cc new file mode 100644 index 000000000..54fcdbd39 --- /dev/null +++ b/rtgui/vibrance.cc @@ -0,0 +1,365 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "vibrance.h" +#include "../rtengine/color.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +Vibrance::Vibrance () : FoldableToolPanel(this, "vibrance", M("TP_VIBRANCE_LABEL"), false, true) { + + std::vector milestones; + float R, G, B; + // -0.1 rad < Hue < 1.6 rad + Color::hsv2rgb01(0.92f, 0.45f, 0.6f, R, G, B); + milestones.push_back( GradientMilestone(0.0, double(R), double(G), double(B)) ); + Color::hsv2rgb01(0.14056f, 0.45f, 0.6f, R, G, B); + milestones.push_back( GradientMilestone(1.0, double(R), double(G), double(B)) ); + + saturated = Gtk::manage(new Adjuster (M("TP_VIBRANCE_SATURATED"),-100.,100.,1.,0.)); + saturated->setAdjusterListener (this); + saturated->set_sensitive(false); + //if (saturated->delay < 1000) saturated->delay = 1000; + pack_start( *saturated, Gtk::PACK_SHRINK, 0); + + pastels = Gtk::manage(new Adjuster (M("TP_VIBRANCE_PASTELS"),-100.,100.,1.,0.)); + pastels->setAdjusterListener (this); + //if (pastels->delay < 1000) pastels->delay = 1000; + pack_start( *pastels, Gtk::PACK_SHRINK, 0); + + psThreshold = Gtk::manage (new ThresholdAdjuster (M("TP_VIBRANCE_PSTHRESHOLD"), -100., 100., 0., M("TP_VIBRANCE_PSTHRESHOLD_WEIGTHING"), 0, 0., 100., 75., M("TP_VIBRANCE_PSTHRESHOLD_SATTHRESH"), 0, this, false)); + psThreshold->setAdjusterListener (this); + psThreshold->set_tooltip_markup(M("TP_VIBRANCE_PSTHRESHOLD_TOOLTIP")); + psThreshold->set_sensitive(false); + //if (psThreshold->delay < 1000) psThreshold->delay = 1000; + pack_start( *psThreshold, Gtk::PACK_SHRINK, 0); + + protectSkins = Gtk::manage (new Gtk::CheckButton (M("TP_VIBRANCE_PROTECTSKINS"))); + protectSkins->set_active (true); + pack_start(*protectSkins, Gtk::PACK_SHRINK, 0); + + avoidColorShift = Gtk::manage (new Gtk::CheckButton (M("TP_VIBRANCE_AVOIDCOLORSHIFT"))); + avoidColorShift->set_active (true); + pack_start(*avoidColorShift, Gtk::PACK_SHRINK, 0); + + pastSatTog = Gtk::manage (new Gtk::CheckButton (M("TP_VIBRANCE_PASTSATTOG"))); + pastSatTog->set_active (true); + pack_start(*pastSatTog, Gtk::PACK_SHRINK, 0); + + curveEditorGG = new CurveEditorGroup (options.lastVibranceCurvesDir, M("TP_VIBRANCE_CURVEEDITOR_SKINTONES_LABEL")); + curveEditorGG->setCurveListener (this); + + skinTonesCurve = static_cast(curveEditorGG->addCurve(CT_Diagonal, M("TP_VIBRANCE_CURVEEDITOR_SKINTONES"))); + skinTonesCurve->setTooltip(M("TP_VIBRANCE_CURVEEDITOR_SKINTONES_TOOLTIP")); + skinTonesCurve->setBottomBarBgGradient(milestones); + skinTonesCurve->setLeftBarBgGradient(milestones); + skinTonesCurve->setRangeLabels( + M("TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE1"), M("TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE2"), + M("TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE3"), M("TP_VIBRANCE_CURVEEDITOR_SKINTONES_RANGE4") + ); + skinTonesCurve->setRangeDefaultMilestones(0.1, 0.4, 0.85); + curveEditorGG->curveListComplete(); + + pack_start (*curveEditorGG, Gtk::PACK_SHRINK, 4); + + show (); + + pskinsconn = protectSkins->signal_toggled().connect( sigc::mem_fun(*this, &Vibrance::protectskins_toggled) ); + ashiftconn = avoidColorShift->signal_toggled().connect( sigc::mem_fun(*this, &Vibrance::avoidcolorshift_toggled) ); + pastsattogconn = pastSatTog->signal_toggled().connect( sigc::mem_fun(*this, &Vibrance::pastsattog_toggled) ); +} + +Vibrance::~Vibrance () { + delete curveEditorGG; +} + +void Vibrance::read(const ProcParams* pp, const ParamsEdited* pedited) { + disableListener (); + + if(pedited ){ + set_inconsistent (multiImage && !pedited->vibrance.enabled); + pastels->setEditedState (pedited->vibrance.pastels ? Edited : UnEdited); + saturated->setEditedState (pedited->vibrance.saturated ? Edited : UnEdited); + psThreshold->setEditedState (pedited->vibrance.psthreshold ? Edited : UnEdited); + protectSkins->set_inconsistent (!pedited->vibrance.protectskins); + avoidColorShift->set_inconsistent (!pedited->vibrance.avoidcolorshift); + pastSatTog->set_inconsistent (!pedited->vibrance.pastsattog); + skinTonesCurve->setUnChanged (!pedited->vibrance.skintonescurve); + } + + setEnabled (pp->vibrance.enabled); + + pskinsconn.block (true); + protectSkins->set_active (pp->vibrance.protectskins); + pskinsconn.block (false); + lastProtectSkins = pp->vibrance.protectskins; + + ashiftconn.block (true); + avoidColorShift->set_active (pp->vibrance.avoidcolorshift); + ashiftconn.block (false); + lastAvoidColorShift = pp->vibrance.avoidcolorshift; + + pastsattogconn.block (true); + pastSatTog->set_active (pp->vibrance.pastsattog); + pastsattogconn.block (false); + lastPastSatTog = pp->vibrance.pastsattog; + + pastels->setValue (pp->vibrance.pastels); + psThreshold->setValue (pp->vibrance.psthreshold); + + if (lastPastSatTog) { + // Link both slider, so we set saturated and psThresholds unsensitive + psThreshold->set_sensitive(false); + saturated->set_sensitive(false); + saturated->setValue (pp->vibrance.pastels); // Pastels and Saturated are linked + } + else { + // Separate sliders, so we set saturated and psThresholds sensitive again + psThreshold->set_sensitive(true); + saturated->set_sensitive(true); + saturated->setValue (pp->vibrance.saturated); // Pastels and Saturated are separate + } + skinTonesCurve->setCurve (pp->vibrance.skintonescurve); + + enableListener (); +} + +void Vibrance::autoOpenCurve () { + skinTonesCurve->openIfNonlinear(); +} + +void Vibrance::write( ProcParams* pp, ParamsEdited* pedited) { + pp->vibrance.enabled = getEnabled (); + pp->vibrance.pastels = pastels->getIntValue(); + pp->vibrance.saturated = pastSatTog->get_active() ? pp->vibrance.pastels : saturated->getIntValue (); + pp->vibrance.psthreshold = psThreshold->getValue (); + pp->vibrance.protectskins = protectSkins->get_active (); + pp->vibrance.avoidcolorshift = avoidColorShift->get_active (); + pp->vibrance.pastsattog = pastSatTog->get_active (); + pp->vibrance.skintonescurve = skinTonesCurve->getCurve (); + + if (pedited) { + pedited->vibrance.enabled = !get_inconsistent(); + pedited->vibrance.pastels = pastels->getEditedState (); + pedited->vibrance.saturated = saturated->getEditedState (); + pedited->vibrance.psthreshold = psThreshold->getEditedState (); + pedited->vibrance.protectskins = !protectSkins->get_inconsistent(); + pedited->vibrance.avoidcolorshift = !avoidColorShift->get_inconsistent(); + pedited->vibrance.pastsattog = !pastSatTog->get_inconsistent(); + pedited->vibrance.skintonescurve = !skinTonesCurve->isUnChanged (); + } + +} +void Vibrance::curveChanged () { + + if (listener && getEnabled ()) listener->panelChanged (EvVibranceSkinTonesCurve, M("HISTORY_CUSTOMCURVE")); +} + +void Vibrance::enabledChanged () { + if (listener) { + if (get_inconsistent()) + listener->panelChanged (EvVibranceEnabled, M("GENERAL_UNCHANGED")); + if (getEnabled()) + listener->panelChanged (EvVibranceEnabled, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvVibranceEnabled, M("GENERAL_DISABLED")); + } +} + +void Vibrance::protectskins_toggled () { + if (batchMode) { + if (protectSkins->get_inconsistent()) { + protectSkins->set_inconsistent (false); + pskinsconn.block (true); + protectSkins->set_active (false); + pskinsconn.block (false); + } + else if (lastProtectSkins) + protectSkins->set_inconsistent (true); + + lastProtectSkins = protectSkins->get_active (); + } + + if (listener && getEnabled()) { + if (protectSkins->get_active ()) + listener->panelChanged (EvVibranceProtectSkins, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvVibranceProtectSkins, M("GENERAL_DISABLED")); + } +} + +void Vibrance::avoidcolorshift_toggled () { + if (batchMode) { + if (avoidColorShift->get_inconsistent()) { + avoidColorShift->set_inconsistent (false); + ashiftconn.block (true); + avoidColorShift->set_active (false); + ashiftconn.block (false); + } + else if (lastAvoidColorShift) + avoidColorShift->set_inconsistent (true); + + lastAvoidColorShift = avoidColorShift->get_active (); + } + + if (listener && getEnabled()) { + if (avoidColorShift->get_active ()) + listener->panelChanged (EvVibranceAvoidColorShift, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvVibranceAvoidColorShift, M("GENERAL_DISABLED")); + } +} + +void Vibrance::pastsattog_toggled () { + if (batchMode) { + if (pastSatTog->get_inconsistent()) { + pastSatTog->set_inconsistent (false); + pastsattogconn.block (true); + pastSatTog->set_active (false); + pastsattogconn.block (false); + } + else if (lastPastSatTog) + pastSatTog->set_inconsistent (true); + + lastPastSatTog = pastSatTog->get_active (); + } + + if (pastSatTog->get_active()) { + // Link both slider, so we set saturated and psThresholds unsensitive + psThreshold->set_sensitive(false); + saturated->set_sensitive(false); + saturated->setValue (pastels->getValue()); // Pastels and Saturated are linked + } + else { + // Separate sliders, so we set saturated and psThresholds sensitive again + psThreshold->set_sensitive(true); + saturated->set_sensitive(true); + } + + if (listener && getEnabled()) { + if (pastSatTog->get_active ()) { + listener->panelChanged (EvVibrancePastSatTog, M("GENERAL_ENABLED")); + } + else + listener->panelChanged (EvVibrancePastSatTog, M("GENERAL_DISABLED")); + } +} + +void Vibrance::adjusterChanged (Adjuster* a, double newval) { + if (a == pastels && pastSatTog->get_active()) + saturated->setValue (newval); + + if (listener && getEnabled()) { + Glib::ustring value = a->getTextValue(); + + if (a == pastels ) + listener->panelChanged (EvVibrancePastels, value ); + else if (a == saturated && !pastSatTog->get_active()) + listener->panelChanged (EvVibranceSaturated, value ); + } +} + +void Vibrance::adjusterChanged (ThresholdAdjuster* a, int newBottom, int newTop) { + if (listener && getEnabled()) { + listener->panelChanged (EvVibrancePastSatThreshold, psThreshold->getHistoryString()); + } +} + + +void Vibrance::setBatchMode(bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + + pastels->showEditedCB (); + saturated->showEditedCB (); + psThreshold->showEditedCB (); + + curveEditorGG->setBatchMode (batchMode); +} + +void Vibrance::setDefaults(const ProcParams* defParams, const ParamsEdited* pedited) { + pastels->setDefault (defParams->vibrance.pastels); + saturated->setDefault (defParams->vibrance.saturated); + psThreshold->setDefault (defParams->vibrance.psthreshold); + + if (pedited) { + pastels->setDefaultEditedState (pedited->vibrance.pastels ? Edited : UnEdited); + saturated->setDefaultEditedState (pedited->vibrance.saturated ? Edited : UnEdited); + psThreshold->setDefaultEditedState (pedited->vibrance.psthreshold ? Edited : UnEdited); + + } else { + pastels->setDefaultEditedState (Irrelevant); + saturated->setDefaultEditedState (Irrelevant); + psThreshold->setDefaultEditedState (Irrelevant); + } +} + +void Vibrance::setAdjusterBehavior (bool pastelsadd, bool saturatedadd) { + pastels->setAddMode (pastelsadd); + saturated->setAddMode (saturatedadd); +} + +void Vibrance::trimValues (ProcParams* pp) { + pastels->trimValue (pp->vibrance.pastels); + saturated->trimValue (pp->vibrance.saturated); +} + +std::vector Vibrance::getCurvePoints(ThresholdSelector* tAdjuster) const { + std::vector points; + double threshold, transitionWeighting; + tAdjuster->getPositions(transitionWeighting, threshold); // ( range -100;+100, range 0;+100 ) + transitionWeighting /= 100.; // range -1., +1. + threshold /= 100.; // range 0., +1. + + // Initial point + points.push_back(0.); points.push_back(0.); + + double p2 = 3.0*threshold/4.0; // same one than in ipvibrance.cc + double s0 = threshold + (1.0-threshold)/4.0; // same one than in ipvibrance.cc + + // point at the beginning of the first linear transition + points.push_back(p2); points.push_back(0.); + + // Y value of the chroma mean point, calculated to get a straight line between p2 and s0 + double chromaMean = (threshold/4.0) / (s0-p2); + // move chromaMean up or down depending on transitionWeighting + if (transitionWeighting > 0.0) { + // positive values -> give more weight to Saturated + chromaMean = (1.0-chromaMean) * transitionWeighting + chromaMean; + } + else if (transitionWeighting < 0.0) { + // negative values -> give more weight to Pastels + chromaMean = chromaMean * transitionWeighting + chromaMean; + } + + // point at the location of the Top cursor, at the end of the first linear transition and the beginning of the second one + points.push_back(threshold); points.push_back(chromaMean); + + if (threshold < 1.0) { + + // point at the end of the second linear transition + points.push_back(s0); points.push_back(1.0); + + // end point + points.push_back(1.0); points.push_back(1.0); + } + + return points; +} diff --git a/rtgui/vibrance.h b/rtgui/vibrance.h new file mode 100644 index 000000000..4c58f34f5 --- /dev/null +++ b/rtgui/vibrance.h @@ -0,0 +1,76 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _VIBRANCE_ +#define _VIBRANCE_ + +#include +#include "adjuster.h" +#include "thresholdadjuster.h" +#include "curveeditor.h" +#include "curveeditorgroup.h" +#include "toolpanel.h" + +class Vibrance : public ToolParamBlock, public AdjusterListener, public ThresholdCurveProvider, public ThresholdAdjusterListener, + public FoldableToolPanel, public CurveListener +{ + +protected: + CurveEditorGroup* curveEditorGG; + + Adjuster* pastels; + Adjuster* saturated; + ThresholdAdjuster* psThreshold; + Gtk::CheckButton* protectSkins; + Gtk::CheckButton* avoidColorShift; + Gtk::CheckButton* pastSatTog; + DiagonalCurveEditor* skinTonesCurve; + + bool lastProtectSkins; + bool lastAvoidColorShift; + bool lastPastSatTog; + + sigc::connection pskinsconn; + sigc::connection ashiftconn; + sigc::connection pastsattogconn; + +public: + + Vibrance (); + ~Vibrance (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + void trimValues (rtengine::procparams::ProcParams* pp); + void setAdjusterBehavior (bool pastelsadd, bool saturatedadd); + void adjusterChanged (Adjuster* a, double newval); + void adjusterChanged (ThresholdAdjuster* a, int newBottom, int newTop); + void curveChanged (); + void autoOpenCurve (); + + void enabledChanged (); + void protectskins_toggled (); + void avoidcolorshift_toggled (); + void pastsattog_toggled (); + std::vector getCurvePoints(ThresholdSelector* tAdjuster) const; +}; + + +#endif diff --git a/rtgui/vignetting.cc b/rtgui/vignetting.cc new file mode 100644 index 000000000..1d3e84018 --- /dev/null +++ b/rtgui/vignetting.cc @@ -0,0 +1,152 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "vignetting.h" + +using namespace rtengine; +using namespace rtengine::procparams; + +Vignetting::Vignetting () : FoldableToolPanel(this, "vignetting", M("TP_VIGNETTING_LABEL")) { + + amount = Gtk::manage (new Adjuster (M("TP_VIGNETTING_AMOUNT"), -100, 100, 1, 0)); + amount->setAdjusterListener (this); + + radius = Gtk::manage (new Adjuster (M("TP_VIGNETTING_RADIUS"), 0, 100, 1, 50)); + radius->setAdjusterListener (this); + + strength = Gtk::manage (new Adjuster (M("TP_VIGNETTING_STRENGTH"), 1, 100, 1, 1)); + strength->setAdjusterListener (this); + + centerX = Gtk::manage (new Adjuster (M("TP_VIGNETTING_CENTER_X"), -100, 100, 1, 0)); + centerX->setAdjusterListener (this); + + centerY = Gtk::manage (new Adjuster (M("TP_VIGNETTING_CENTER_Y"), -100, 100, 1, 0)); + centerY->setAdjusterListener (this); + + pack_start (*amount); + pack_start (*radius); + pack_start (*strength); + pack_start (*centerX); + pack_start (*centerY); + + show_all(); +} + +void Vignetting::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + if (pedited) { + amount->setEditedState (pedited->vignetting.amount ? Edited : UnEdited); + radius->setEditedState (pedited->vignetting.radius ? Edited : UnEdited); + strength->setEditedState (pedited->vignetting.strength ? Edited : UnEdited); + centerX->setEditedState (pedited->vignetting.centerX ? Edited : UnEdited); + centerY->setEditedState (pedited->vignetting.centerY ? Edited : UnEdited); + } + + amount->setValue (pp->vignetting.amount); + radius->setValue (pp->vignetting.radius); + strength->setValue (pp->vignetting.strength); + centerX->setValue (pp->vignetting.centerX); + centerY->setValue (pp->vignetting.centerY); + + enableListener (); +} + +void Vignetting::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->vignetting.amount = amount->getIntValue (); + pp->vignetting.radius = radius->getIntValue (); + pp->vignetting.strength = strength->getIntValue (); + pp->vignetting.centerX = centerX->getIntValue (); + pp->vignetting.centerY = centerY->getIntValue (); + + if (pedited) { + pedited->vignetting.amount = amount->getEditedState (); + pedited->vignetting.radius = radius->getEditedState (); + pedited->vignetting.strength = strength->getEditedState (); + pedited->vignetting.centerX = centerX->getEditedState (); + pedited->vignetting.centerY = centerY->getEditedState (); + } +} + +void Vignetting::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + amount->setDefault (defParams->vignetting.amount); + radius->setDefault (defParams->vignetting.radius); + strength->setDefault (defParams->vignetting.strength); + centerX->setDefault (defParams->vignetting.centerX); + centerY->setDefault (defParams->vignetting.centerY); + + if (pedited) { + amount->setDefaultEditedState (pedited->vignetting.amount ? Edited : UnEdited); + radius->setDefaultEditedState (pedited->vignetting.radius ? Edited : UnEdited); + strength->setDefaultEditedState (pedited->vignetting.strength ? Edited : UnEdited); + centerX->setDefaultEditedState (pedited->vignetting.centerX ? Edited : UnEdited); + centerY->setDefaultEditedState (pedited->vignetting.centerY ? Edited : UnEdited); + } + else { + amount->setDefaultEditedState (Irrelevant); + radius->setDefaultEditedState (Irrelevant); + strength->setDefaultEditedState (Irrelevant); + centerX->setDefaultEditedState (Irrelevant); + centerY->setDefaultEditedState (Irrelevant); + } +} + +void Vignetting::adjusterChanged (Adjuster* a, double newval) { + + if (listener) { + if (a == amount) + listener->panelChanged (EvVignettingAmount, amount->getTextValue()); + else if (a == radius) + listener->panelChanged (EvVignettingRadius, radius->getTextValue()); + else if (a == strength) + listener->panelChanged (EvVignettingStrenght, strength->getTextValue()); + else if (a == centerX || a == centerY) + listener->panelChanged (EvVignettingCenter, Glib::ustring::compose ("X=%1\nY=%2", centerX->getTextValue(), centerY->getTextValue())); + } +} + +void Vignetting::setAdjusterBehavior (bool amountadd, bool radiusadd, bool strengthadd, bool centeradd) { + + amount->setAddMode(amountadd); + radius->setAddMode(radiusadd); + strength->setAddMode(strengthadd); + centerX->setAddMode(centeradd); + centerY->setAddMode(centeradd); +} + +void Vignetting::trimValues (rtengine::procparams::ProcParams* pp) { + + amount->trimValue(pp->vignetting.amount); + radius->trimValue(pp->vignetting.radius); + strength->trimValue(pp->vignetting.strength); + centerX->trimValue(pp->vignetting.centerX); + centerY->trimValue(pp->vignetting.centerY); +} + +void Vignetting::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + amount->showEditedCB (); + radius->showEditedCB (); + strength->showEditedCB (); + centerX->showEditedCB (); + centerY->showEditedCB (); +} diff --git a/rtgui/vignetting.h b/rtgui/vignetting.h new file mode 100644 index 000000000..a6c22252f --- /dev/null +++ b/rtgui/vignetting.h @@ -0,0 +1,49 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _VIGNETTING_H_ +#define _VIGNETTING_H_ + +#include +#include "adjuster.h" +#include "toolpanel.h" + +class Vignetting : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel { + + protected: + Adjuster* amount; + Adjuster* radius; + Adjuster* strength; + Adjuster* centerX; + Adjuster* centerY; + + public: + + Vignetting (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + + void adjusterChanged (Adjuster* a, double newval); + void setAdjusterBehavior (bool amountadd, bool radiusadd, bool strengthadd, bool centeradd); + void trimValues (rtengine::procparams::ProcParams* pp); +}; + +#endif diff --git a/rtgui/wavelet.cc b/rtgui/wavelet.cc new file mode 100644 index 000000000..9e403386a --- /dev/null +++ b/rtgui/wavelet.cc @@ -0,0 +1,2723 @@ +/* + * This file is part of RawTherapee. + * + * 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 . + * + * 2014 Jacques Desmis + */ + +#include "wavelet.h" +#include +#include "edit.h" +#include "guiutils.h" + +using namespace rtengine; +using namespace rtengine::procparams; +extern Options options; + +Wavelet::Wavelet () : FoldableToolPanel(this, "wavelet", M("TP_WAVELET_LABEL"), true, true) { + std::vector milestones; + CurveListener::setMulti(true); + nextnlevel=7.; + float r, g, b; + //from -PI to +PI (radians) convert to hsv and draw bottombar + Color::hsv2rgb01(0.4199, 0.5, 0.5, r, g, b); milestones.push_back( GradientMilestone(0.0 , r, g, b) ); // hsv: 0.4199 rad: -3.14 + Color::hsv2rgb01(0.5000, 0.5, 0.5, r, g, b); milestones.push_back( GradientMilestone(0.054 , r, g, b) ); // hsv: 0.5 rad: -2.8 + Color::hsv2rgb01(0.6000, 0.5, 0.5, r, g, b); milestones.push_back( GradientMilestone(0.1336, r, g, b) ); // hsv: 0.60 rad: -2.3 + Color::hsv2rgb01(0.7500, 0.5, 0.5, r, g, b); milestones.push_back( GradientMilestone(0.3567, r, g, b) ); // hsv: 0.75 rad: -0.9 + Color::hsv2rgb01(0.8560, 0.5, 0.5, r, g, b); milestones.push_back( GradientMilestone(0.4363, r, g, b) ); // hsv: 0.856 rad: -0.4 + Color::hsv2rgb01(0.9200, 0.5, 0.5, r, g, b); milestones.push_back( GradientMilestone(0.4841, r, g, b) ); // hsv: 0.92 rad: -0.1 + Color::hsv2rgb01(0.9300, 0.5, 0.5, r, g, b); milestones.push_back( GradientMilestone(0.5000, r, g, b) ); // hsv: 0.93 rad: 0 + Color::hsv2rgb01(0.9600, 0.5, 0.5, r, g, b); milestones.push_back( GradientMilestone(0.5366, r, g, b) ); // hsv: 0.96 rad: 0.25 + Color::hsv2rgb01(1.0000, 0.5, 0.5, r, g, b); milestones.push_back( GradientMilestone(0.5955, r, g, b) ); // hsv: 1. rad: 0.6 + Color::hsv2rgb01(0.0675, 0.5, 0.5, r, g, b); milestones.push_back( GradientMilestone(0.6911, r, g, b) ); // hsv: 0.0675 rad: 1.2 + Color::hsv2rgb01(0.0900, 0.5, 0.5, r, g, b); milestones.push_back( GradientMilestone(0.7229, r, g, b) ); // hsv: 0.09 rad: 1.4 + Color::hsv2rgb01(0.1700, 0.5, 0.5, r, g, b); milestones.push_back( GradientMilestone(0.7707, r, g, b) ); // hsv: 0.17 rad: 1.7 + Color::hsv2rgb01(0.2650, 0.5, 0.5, r, g, b); milestones.push_back( GradientMilestone(0.8503, r, g, b) ); // hsv: 0.265 rad: 2.1 + Color::hsv2rgb01(0.3240, 0.5, 0.5, r, g, b); milestones.push_back( GradientMilestone(0.8981, r, g, b) ); // hsv: 0.324 rad: 2.5 + Color::hsv2rgb01(0.4197, 0.5, 0.5, r, g, b); milestones.push_back( GradientMilestone(1. , r, g, b) ); // hsv: 0.419 rad: 3.14 + + std::vector milestones2; + milestones2.push_back( GradientMilestone(0.0, 0.0, 0.0, 0.0) ); + milestones2.push_back( GradientMilestone(1.0, 1.0, 1.0, 1.0) ); + + std::vector defaultCurve; + + expsettings = new MyExpander (false, M("TP_WAVELET_SETTINGS")); + expsettings->signal_button_release_event().connect_notify( sigc::mem_fun(this, &Wavelet::foldAllButSettings) ); + expcontrast = new MyExpander (false, M("TP_WAVELET_LEVF")); + expcontrast->signal_button_release_event().connect_notify( sigc::mem_fun(this, &Wavelet::foldAllButContrast) ); + expchroma = new MyExpander (false, M("TP_WAVELET_LEVCH")); + expchroma->signal_button_release_event().connect_notify( sigc::mem_fun(this, &Wavelet::foldAllButChroma) ); + exptoning = new MyExpander (false,M("TP_WAVELET_TON")); + exptoning->signal_button_release_event().connect_notify( sigc::mem_fun(this, &Wavelet::foldAllButToning) ); + expnoise = new MyExpander (false, M("TP_WAVELET_NOISE")); + expnoise->signal_button_release_event().connect_notify( sigc::mem_fun(this, &Wavelet::foldAllButNoise) ); + expedge = new MyExpander (false, M("TP_WAVELET_EDGE")); + expedge->signal_button_release_event().connect_notify( sigc::mem_fun(this, &Wavelet::foldAllButEdge) ); + expgamut = new MyExpander (false, M("TP_WAVELET_CONTR")); + expgamut->signal_button_release_event().connect_notify( sigc::mem_fun(this, &Wavelet::foldAllButGamut) ); + expresid = new MyExpander (false, M("TP_WAVELET_RESID")); + expresid->signal_button_release_event().connect_notify( sigc::mem_fun(this, &Wavelet::foldAllButResid) ); + expfinal = new MyExpander (false, M("TP_WAVELET_FINAL")); + expfinal->signal_button_release_event().connect_notify( sigc::mem_fun(this, &Wavelet::foldAllButFinal) ); + +// Wavelet Settings + settingsVBox = Gtk::manage (new Gtk::VBox()); + settingsVBox->set_border_width(4); + settingsVBox->set_spacing(2); + + strength = Gtk::manage (new Adjuster (M("TP_WAVELET_STRENGTH"), 0, 100, 1, 100)); + strength->setAdjusterListener (this); + + thres = Gtk::manage (new Adjuster (M("TP_WAVELET_LEVELS"), 3, 9, 1, 7)); + thres->set_tooltip_text (M("TP_WAVELET_LEVELS_TOOLTIP")); + thres->setAdjusterListener (this); + + tilesizeHBox = Gtk::manage (new Gtk::HBox()); + tilesizeLabel = Gtk::manage (new Gtk::Label (M("TP_WAVELET_TILESIZE") + ":")); + //tilesizeLabel->set_alignment(Gtk::ALIGN_START); + Tilesmethod = Gtk::manage (new MyComboBoxText ()); + Tilesmethod->append_text (M("TP_WAVELET_TILESFULL")); + Tilesmethod->append_text (M("TP_WAVELET_TILESBIG")); + Tilesmethod->append_text (M("TP_WAVELET_TILESLIT")); + Tilesmethodconn = Tilesmethod->signal_changed().connect ( sigc::mem_fun(*this, &Wavelet::TilesmethodChanged) ); + Tilesmethod->set_tooltip_text (M("TP_WAVELET_TILES_TOOLTIP")); + tilesizeHBox->pack_start(*tilesizeLabel, Gtk::PACK_SHRINK, 4); + tilesizeHBox->pack_start(*Tilesmethod); + + daubcoeffHBox = Gtk::manage (new Gtk::HBox()); + daubcoeffLabel = Gtk::manage (new Gtk::Label (M("TP_WAVELET_DAUB") + ":")); + daubcoeffmethod = Gtk::manage (new MyComboBoxText ()); + daubcoeffmethod->set_sensitive(true); + daubcoeffmethod->append_text (M("TP_WAVELET_DAUB2")); + daubcoeffmethod->append_text (M("TP_WAVELET_DAUB4")); + daubcoeffmethod->append_text (M("TP_WAVELET_DAUB6")); + daubcoeffmethod->append_text (M("TP_WAVELET_DAUB10")); + daubcoeffmethod->append_text (M("TP_WAVELET_DAUB14")); + daubcoeffmethodconn = daubcoeffmethod->signal_changed().connect ( sigc::mem_fun(*this, &Wavelet::daubcoeffmethodChanged) ); + daubcoeffmethod->set_tooltip_text (M("TP_WAVELET_DAUB_TOOLTIP")); + daubcoeffHBox->pack_start(*daubcoeffLabel, Gtk::PACK_SHRINK, 4); + daubcoeffHBox->pack_start(*daubcoeffmethod); + + backgroundHBox = Gtk::manage (new Gtk::HBox()); + Backmethod = Gtk::manage (new MyComboBoxText ()); + Backmethod->append_text (M("TP_WAVELET_B0")); + Backmethod->append_text (M("TP_WAVELET_B1")); + Backmethod->append_text (M("TP_WAVELET_B2")); + Backmethodconn = Backmethod->signal_changed().connect ( sigc::mem_fun(*this, &Wavelet::BackmethodChanged) ); + backgroundLabel = Gtk::manage (new Gtk::Label (M("TP_WAVELET_BACKGROUND") + ":")); + backgroundHBox->pack_start(*backgroundLabel, Gtk::PACK_SHRINK, 4); + backgroundHBox->pack_start(*Backmethod); + + levdirMainHBox = Gtk::manage (new Gtk::HBox()); + CLmethod = Gtk::manage (new MyComboBoxText ()); + CLmethod->append_text (M("TP_WAVELET_LEVDIR_ONE")); + CLmethod->append_text (M("TP_WAVELET_LEVDIR_INF")); + CLmethod->append_text (M("TP_WAVELET_LEVDIR_SUP")); + CLmethod->append_text (M("TP_WAVELET_LEVDIR_ALL")); + CLmethodconn = CLmethod->signal_changed().connect ( sigc::mem_fun(*this, &Wavelet::CLmethodChanged) ); + levdirMainLabel = Gtk::manage (new Gtk::Label (M("TP_WAVELET_PROC") + ":")); + levdirMainHBox->pack_start(*levdirMainLabel, Gtk::PACK_SHRINK, 4); + levdirMainHBox->pack_start(*CLmethod); //same + + levdirSubHBox = Gtk::manage (new Gtk::HBox()); + Lmethod = Gtk::manage (new MyComboBoxText ()); + Lmethod->set_sensitive(false); + Lmethod->set_sensitive(false); + Lmethod->append_text (M("TP_WAVELET_1")); + Lmethod->append_text (M("TP_WAVELET_2")); + Lmethod->append_text (M("TP_WAVELET_3")); + Lmethod->append_text (M("TP_WAVELET_4")); + Lmethod->append_text (M("TP_WAVELET_5")); + Lmethod->append_text (M("TP_WAVELET_6")); + Lmethod->append_text (M("TP_WAVELET_7")); + Lmethod->append_text (M("TP_WAVELET_8")); + Lmethod->append_text (M("TP_WAVELET_9")); + Lmethod->append_text (M("TP_WAVELET_SUPE")); + Lmethod->append_text (M("TP_WAVELET_RESID")); + Lmethod->set_active(0); + Dirmethod = Gtk::manage (new MyComboBoxText ()); + Dirmethod->set_sensitive(false); + Dirmethod->append_text (M("TP_WAVELET_DONE")); + Dirmethod->append_text (M("TP_WAVELET_DTWO")); + Dirmethod->append_text (M("TP_WAVELET_DTHR")); + Dirmethod->append_text (M("TP_WAVELET_DALL")); + Lmethodconn = Lmethod->signal_changed().connect ( sigc::mem_fun(*this, &Wavelet::LmethodChanged) ); + Dirmethodconn = Dirmethod->signal_changed().connect ( sigc::mem_fun(*this, &Wavelet::DirmethodChanged) ); + levdirSubHBox->pack_start(*Lmethod); + levdirSubHBox->pack_start(*Dirmethod, Gtk::PACK_EXPAND_WIDGET, 2); // same, but 2 not 4? + + settingsVBox->pack_start(*strength); + settingsVBox->pack_start(*thres); + settingsVBox->pack_start(*tilesizeHBox); + settingsVBox->pack_start(*daubcoeffHBox); + settingsVBox->pack_start(*backgroundHBox); + settingsVBox->pack_start(*levdirMainHBox); + settingsVBox->pack_start(*levdirSubHBox); + +// Contrast + Gtk::VBox * levBox = Gtk::manage (new Gtk::VBox()); + levBox->set_border_width(4); + levBox->set_spacing(2); + + Gtk::HBox * buttonBox = Gtk::manage (new Gtk::HBox(true, 10)); + wavLabels = Gtk::manage(new Gtk::Label("---", Gtk::ALIGN_CENTER)); + levBox->pack_start(*buttonBox, Gtk::PACK_SHRINK, 2); + + Gtk::Button * contrastMinusButton = Gtk::manage (new Gtk::Button(M("TP_WAVELET_CONTRAST_MINUS"))); + buttonBox->pack_start(*contrastMinusButton); + contrastMinusPressedConn = contrastMinusButton->signal_pressed().connect( sigc::mem_fun(*this, &Wavelet::contrastMinusPressed)); + + Gtk::Button * neutralButton = Gtk::manage (new Gtk::Button(M("TP_WAVELET_NEUTRAL"))); + buttonBox->pack_start(*neutralButton); + neutralPressedConn = neutralButton->signal_pressed().connect( sigc::mem_fun(*this, &Wavelet::neutralPressed)); + + Gtk::Button * contrastPlusButton = Gtk::manage (new Gtk::Button(M("TP_WAVELET_CONTRAST_PLUS"))); + buttonBox->pack_start(*contrastPlusButton); + contrastPlusPressedConn = contrastPlusButton->signal_pressed().connect( sigc::mem_fun(*this, &Wavelet::contrastPlusPressed)); + + buttonBox->show_all_children(); + + for(int i = 0; i < 9; i++) + { + Glib::ustring ss; + switch( i ){ + case 0: + ss =Glib::ustring::compose( "%1 (%2)",(i+1), M("TP_WAVELET_FINEST"));break; + case 8: + ss =Glib::ustring::compose( "%1 (%2)",(i+1), M("TP_WAVELET_LARGEST"));break; + default: + ss =Glib::ustring::compose( "%1",(i+1)); + } + + correction[i] = Gtk::manage ( new Adjuster (ss, -100, 350, 1, 0) ); + correction[i]->setAdjusterListener(this); + levBox->pack_start(*correction[i]); + } + sup = Gtk::manage (new Adjuster (M("TP_WAVELET_SUPE"), -100, 350, 1, 0)); + levBox->pack_start(*sup); + sup->setAdjusterListener (this); + wavLabels->show(); + levBox->pack_start (*wavLabels); + + contrastSHFrame = Gtk::manage (new Gtk::Frame (M("TP_WAVELET_APPLYTO"))); + contrastSHVBox = Gtk::manage (new Gtk::VBox); + contrastSHVBox->set_border_width(4); + contrastSHVBox->set_spacing(2); + + HSmethod = Gtk::manage (new MyComboBoxText ()); + HSmethod->append_text (M("TP_WAVELET_HS1")); + HSmethod->append_text (M("TP_WAVELET_HS2")); + HSmethodconn = HSmethod->signal_changed().connect ( sigc::mem_fun(*this, &Wavelet::HSmethodChanged) ); + + hllev = Gtk::manage (new ThresholdAdjuster (M("TP_WAVELET_HIGHLIGHT"), 0., 100., 50., 75., 100., 98., 0, false)); + hllev->setAdjusterListener (this); + hllev->setBgGradient(milestones2); + + threshold = Gtk::manage (new Adjuster (M("TP_WAVELET_THRESHOLD"), 1, 9, 1, 5)); + threshold->setAdjusterListener (this); + threshold->set_tooltip_text (M("TP_WAVELET_THRESHOLD_TOOLTIP")); + + bllev = Gtk::manage (new ThresholdAdjuster (M("TP_WAVELET_LOWLIGHT"), 0., 100., 0., 2., 50., 25., 0, false)); + bllev->setAdjusterListener (this); + bllev->setBgGradient(milestones2); + + threshold2 = Gtk::manage (new Adjuster (M("TP_WAVELET_THRESHOLD2"), 1, 9, 1, 4)); + threshold2->setAdjusterListener (this); + threshold2->set_tooltip_text (M("TP_WAVELET_THRESHOLD2_TOOLTIP")); + + contrastSHVBox->pack_start(*HSmethod); //remove 2? + contrastSHVBox->pack_start(*hllev); + contrastSHVBox->pack_start(*threshold); + contrastSHVBox->pack_start(*bllev); + contrastSHVBox->pack_start(*threshold2); + contrastSHFrame->add(*contrastSHVBox); + levBox->pack_start(*contrastSHFrame); + +// Chromaticity + Gtk::VBox * chBox = Gtk::manage (new Gtk::VBox()); + chBox->set_border_width(4); + chBox->set_spacing(2); + + ctboxch = Gtk::manage (new Gtk::HBox ()); + labmch = Gtk::manage (new Gtk::Label (M("TP_WAVELET_CHTYPE")+":")); + ctboxch->pack_start (*labmch, Gtk::PACK_SHRINK, 1); + + CHmethod = Gtk::manage (new MyComboBoxText ()); + CHmethod->append_text (M("TP_WAVELET_CH1")); + CHmethod->append_text (M("TP_WAVELET_CH2")); + CHmethod->append_text (M("TP_WAVELET_CH3")); + CHmethodconn = CHmethod->signal_changed().connect ( sigc::mem_fun(*this, &Wavelet::CHmethodChanged) ); + ctboxch->pack_start(*CHmethod); + chBox->pack_start(*ctboxch); + + ctboxCH = Gtk::manage (new Gtk::HBox ()); + labmC = Gtk::manage (new Gtk::Label (M("TP_WAVELET_CTYPE")+":")); + ctboxCH->pack_start (*labmC, Gtk::PACK_SHRINK, 1); + + CHSLmethod = Gtk::manage (new MyComboBoxText ()); + CHSLmethod->append_text (M("TP_WAVELET_CHSL")); + CHSLmethod->append_text (M("TP_WAVELET_CHCU")); + CHSLmethodconn = CHSLmethod->signal_changed().connect ( sigc::mem_fun(*this, &Wavelet::CHSLmethodChanged) ); + ctboxCH->pack_start(*CHSLmethod); + + Gtk::HSeparator *separatorChromaMethod = Gtk::manage (new Gtk::HSeparator()); + chBox->pack_start(*separatorChromaMethod, Gtk::PACK_SHRINK, 2); + + chroma = Gtk::manage (new Adjuster (M("TP_WAVELET_CHRO"), 1, 9, 1, 5)); + chroma->set_tooltip_text (M("TP_WAVELET_CHRO_TOOLTIP")); + chBox->pack_start(*chroma); + chroma->setAdjusterListener (this); + + satlev = Gtk::manage (new ThresholdAdjuster (M("TP_WAVELET_SAT"), 0., 130., 30., 45., 130., 100., 0, false)); + satlev->setAdjusterListener (this); + satlev->setBgGradient(milestones2); + + pastlev = Gtk::manage (new ThresholdAdjuster (M("TP_WAVELET_PASTEL"), 0., 70., 0., 2., 30., 20., 0, false)); + pastlev->setAdjusterListener (this); + pastlev->setBgGradient(milestones2); + + chBox->pack_start(*pastlev); + chBox->pack_start(*satlev); + + chro = Gtk::manage (new Adjuster (M("TP_WAVELET_CHR"), 0., 100., 1., 0.)); + chro->set_tooltip_text (M("TP_WAVELET_CHR_TOOLTIP")); + chBox->pack_start(*chro); + chro->setAdjusterListener (this); + + Gtk::HBox * buttonchBox = Gtk::manage (new Gtk::HBox(true, 10)); + neutralchButton = Gtk::manage (new Gtk::Button(M("TP_WAVELET_NEUTRAL"))); + neutralchPressedConn = neutralchButton->signal_pressed().connect( sigc::mem_fun(*this, &Wavelet::neutralchPressed)); + separatorNeutral = Gtk::manage (new Gtk::HSeparator()); + chBox->pack_start(*separatorNeutral, Gtk::PACK_SHRINK, 2); + buttonchBox->pack_start(*neutralchButton); + buttonchBox->show_all_children(); + chBox->pack_start(*buttonchBox, Gtk::PACK_SHRINK, 2); + + for(int i = 0; i < 9; i++) + { + Glib::ustring ss; + switch( i ){ + case 0: + ss =Glib::ustring::compose( "%1 (%2)",(i+1), M("TP_WAVELET_FINEST"));break; + case 8: + ss =Glib::ustring::compose( "%1 (%2)",(i+1), M("TP_WAVELET_LARGEST"));break; + default: + ss =Glib::ustring::compose( "%1",(i+1)); + } + + correctionch[i] = Gtk::manage ( new Adjuster (ss, -100, 100, 1, 0) ); + correctionch[i]->setAdjusterListener(this); + chBox->pack_start(*correctionch[i]); + } + +// Toning + Gtk::VBox * tonBox = Gtk::manage (new Gtk::VBox()); + tonBox->set_border_width(4); + tonBox->set_spacing(2); + + opaCurveEditorG = new CurveEditorGroup (options.lastWaveletCurvesDir, M("TP_WAVELET_COLORT")); + opaCurveEditorG->setCurveListener (this); + + rtengine::WaveletParams::getDefaultOpacityCurveRG(defaultCurve); + opacityShapeRG = static_cast(opaCurveEditorG->addCurve(CT_Flat, "", NULL, false)); + opacityShapeRG->setIdentityValue(0.); + opacityShapeRG->setResetCurve(FlatCurveType(defaultCurve.at(0)), defaultCurve); + + opaCurveEditorG->curveListComplete(); + opaCurveEditorG->show(); + + tonBox->pack_start( *opaCurveEditorG, Gtk::PACK_SHRINK, 2); + + opacityCurveEditorG = new CurveEditorGroup (options.lastWaveletCurvesDir, M("TP_WAVELET_OPACITY")); + opacityCurveEditorG->setCurveListener (this); + + rtengine::WaveletParams::getDefaultOpacityCurveBY(defaultCurve); + opacityShapeBY = static_cast(opacityCurveEditorG->addCurve(CT_Flat, "", NULL, false)); + opacityShapeBY->setIdentityValue(0.); + opacityShapeBY->setResetCurve(FlatCurveType(defaultCurve.at(0)), defaultCurve); + + opacityCurveEditorG->curveListComplete(); + opacityCurveEditorG->show(); + + tonBox->pack_start( *opacityCurveEditorG, Gtk::PACK_SHRINK, 2); + +// Denoise and Refine + Gtk::VBox * noiseBox = Gtk::manage (new Gtk::VBox()); + noiseBox->set_border_width(4); + noiseBox->set_spacing(2); + + linkedg = Gtk::manage (new Gtk::CheckButton (M("TP_WAVELET_LINKEDG"))); + linkedg->set_active (true); + linkedgConn = linkedg->signal_toggled().connect( sigc::mem_fun(*this, &Wavelet::linkedgToggled) ); + noiseBox->pack_start(*linkedg); + + level0noise = Gtk::manage (new ThresholdAdjuster (M("TP_WAVELET_LEVZERO"), -30., 100., 0., M("TP_WAVELET_STREN"), 1., 0., 100., 0., M("TP_WAVELET_NOIS"), 1., NULL, false)); + level0noise->setAdjusterListener (this); + level0noise->setUpdatePolicy(RTUP_DYNAMIC); + + level1noise = Gtk::manage (new ThresholdAdjuster (M("TP_WAVELET_LEVONE"), -30., 100., 0., M("TP_WAVELET_STREN"), 1., 0., 100., 0., M("TP_WAVELET_NOIS"), 1., NULL, false)); + level1noise->setAdjusterListener (this); + level1noise->setUpdatePolicy(RTUP_DYNAMIC); + + level2noise = Gtk::manage (new ThresholdAdjuster (M("TP_WAVELET_LEVTWO"), -30., 100., 0., M("TP_WAVELET_STREN"), 1., 0., 100., 0., M("TP_WAVELET_NOIS"), 1., NULL, false)); + level2noise->setAdjusterListener (this); + level2noise->setUpdatePolicy(RTUP_DYNAMIC); + + noiseBox->pack_start( *level0noise, Gtk::PACK_SHRINK, 0); + noiseBox->pack_start( *level1noise, Gtk::PACK_SHRINK, 0); + noiseBox->pack_start( *level2noise, Gtk::PACK_SHRINK, 0); + +// Edge Sharpness + Gtk::VBox * edgBox = Gtk::manage (new Gtk::VBox()); + edgBox->set_border_width(4); + edgBox->set_spacing(2); + + edgval = Gtk::manage ( new Adjuster (M("TP_WAVELET_EDVAL"), 0, 100, 1, 0) ); + edgval->setAdjusterListener(this); + edgBox->pack_start(*edgval); + + edgrad = Gtk::manage ( new Adjuster (M("TP_WAVELET_EDRAD"), 0, 100, 1, 15) ); + edgrad->setAdjusterListener(this); + edgBox->pack_start(*edgrad); + edgrad->set_tooltip_markup (M("TP_WAVELET_EDRAD_TOOLTIP")); + + edgthresh = Gtk::manage (new Adjuster (M("TP_WAVELET_EDGTHRESH"), -50, 100, 1, 10 )); + edgthresh->setAdjusterListener (this); + edgthresh->set_tooltip_markup (M("TP_WAVELET_EDGTHRESH_TOOLTIP")); + edgBox->pack_start (*edgthresh); + + edbox = Gtk::manage (new Gtk::HBox ()); + labmedgr = Gtk::manage (new Gtk::Label (M("TP_WAVELET_MEDGREINF")+":")); + edbox->pack_start (*labmedgr, Gtk::PACK_SHRINK, 1); + + Medgreinf = Gtk::manage (new MyComboBoxText ()); + Medgreinf->append_text (M("TP_WAVELET_RE1")); + Medgreinf->append_text (M("TP_WAVELET_RE2")); + Medgreinf->append_text (M("TP_WAVELET_RE3")); + MedgreinfConn = Medgreinf->signal_changed().connect ( sigc::mem_fun(*this, &Wavelet::MedgreinfChanged) ); + Medgreinf->set_tooltip_markup (M("TP_WAVELET_EDGREINF_TOOLTIP")); + edbox->pack_start(*Medgreinf); + edgBox->pack_start(*edbox); + + Gtk::HSeparator *separatorlc = Gtk::manage (new Gtk::HSeparator()); + edgBox->pack_start(*separatorlc, Gtk::PACK_SHRINK, 2); + + ctboxED = Gtk::manage (new Gtk::HBox ()); + labmED = Gtk::manage (new Gtk::Label (M("TP_WAVELET_EDTYPE")+":")); + ctboxED->pack_start (*labmED, Gtk::PACK_SHRINK, 1); + + EDmethod = Gtk::manage (new MyComboBoxText ()); + EDmethod->append_text (M("TP_WAVELET_EDSL")); + EDmethod->append_text (M("TP_WAVELET_EDCU")); + EDmethodconn = EDmethod->signal_changed().connect ( sigc::mem_fun(*this, &Wavelet::EDmethodChanged) ); + ctboxED->pack_start(*EDmethod); + edgBox->pack_start (*ctboxED); + tr=options.rtSettings.top_right; + br=options.rtSettings.bot_right; + tl=options.rtSettings.top_left; + bl=options.rtSettings.bot_left; + + edgcont = Gtk::manage (new ThresholdAdjuster (M("TP_WAVELET_EDGCONT"), 0., 100., bl, tl, br, tr, 0., false)); + edgcont->setAdjusterListener (this); + edgcont->setBgGradient(milestones2); + edgcont->set_tooltip_markup (M("TP_WAVELET_EDGCONT_TOOLTIP")); + + // <-- Edge Sharpness Local Contrast curve + CCWcurveEditorG = new CurveEditorGroup (options.lastWaveletCurvesDir, M("TP_WAVELET_CCURVE")); + CCWcurveEditorG->setCurveListener (this); + + rtengine::WaveletParams::getDefaultCCWCurve(defaultCurve); + ccshape = static_cast(CCWcurveEditorG->addCurve(CT_Flat, "", NULL, false)); + + ccshape->setIdentityValue(0.); + ccshape->setResetCurve(FlatCurveType(defaultCurve.at(0)), defaultCurve); + ccshape->setTooltip(M("TP_WAVELET_CURVEEDITOR_CC_TOOLTIP")); + + CCWcurveEditorG->curveListComplete(); + CCWcurveEditorG->show(); + // --> + + edgBox->pack_start (*edgcont); + edgBox->pack_start(*CCWcurveEditorG, Gtk::PACK_SHRINK, 4); + + medianlev = Gtk::manage (new Gtk::CheckButton (M("TP_WAVELET_MEDILEV"))); + medianlev->set_active (true); + medianlevConn = medianlev->signal_toggled().connect( sigc::mem_fun(*this, &Wavelet::medianlevToggled) ); + + Gtk::HSeparator *separatored1 = Gtk::manage (new Gtk::HSeparator()); + edgBox->pack_start(*separatored1, Gtk::PACK_SHRINK, 2); + + eddebox = Gtk::manage (new Gtk::HBox ()); + + edgBox->pack_start (*eddebox); + edgBox->pack_start(*medianlev); + + edgedetect = Gtk::manage (new Adjuster (M("TP_WAVELET_EDGEDETECT"), 0, 100, 1, 80)); + edgedetect->setAdjusterListener (this); + edgedetect->set_tooltip_text (M("TP_WAVELET_EDGEDETECT_TOOLTIP")); + edgBox->pack_start(*edgedetect); + + edgedetectthr = Gtk::manage (new Adjuster (M("TP_WAVELET_EDGEDETECTTHR"), 0, 100, 1, 20)); + edgedetectthr->setAdjusterListener (this); + edgedetectthr->set_tooltip_text (M("TP_WAVELET_EDGEDETECTTHR_TOOLTIP")); + edgBox->pack_start(*edgedetectthr); + + + edgedetectthr2 = Gtk::manage (new Adjuster (M("TP_WAVELET_EDGEDETECTTHR2"), -10, 100, 1, 0)); + edgedetectthr2->setAdjusterListener (this); + edgBox->pack_start(*edgedetectthr2); + + lipst = Gtk::manage (new Gtk::CheckButton (M("TP_WAVELET_LIPST"))); + lipst->set_active (true); + lipstConn = lipst->signal_toggled().connect( sigc::mem_fun(*this, &Wavelet::lipstToggled) ); + lipst->set_tooltip_text (M("TP_WAVELET_LIPST_TOOLTIP")); + +// Gamut + Gtk::VBox * conBox = Gtk::manage (new Gtk::VBox()); + conBox->set_border_width(4); + conBox->set_spacing(2); + + median = Gtk::manage (new Gtk::CheckButton (M("TP_WAVELET_MEDI"))); + median->set_active (true); + medianConn = median->signal_toggled().connect( sigc::mem_fun(*this, &Wavelet::medianToggled) ); + conBox->pack_start(*median); + + hueskin = Gtk::manage (new ThresholdAdjuster (M("TP_WAVELET_HUESKIN"), -314., 314., -5., 25., 170., 120., 0, false)); + hueskin->set_tooltip_markup (M("TP_WAVELET_HUESKIN_TOOLTIP")); + + hueskin->setBgGradient(milestones); + conBox->pack_start(*hueskin); + hueskin->setAdjusterListener (this); + + skinprotect = Gtk::manage ( new Adjuster (M("TP_WAVELET_SKIN"), -100, 100, 1, 0.) ); + skinprotect->setAdjusterListener(this); + conBox->pack_start(*skinprotect); + skinprotect->set_tooltip_markup (M("TP_WAVELET_SKIN_TOOLTIP")); + + curveEditorGAM = new CurveEditorGroup (options.lastWaveletCurvesDir); + curveEditorGAM->setCurveListener (this); + + Chshape = static_cast(curveEditorGAM->addCurve(CT_Flat, M("TP_WAVELET_CURVEEDITOR_CH"))); + Chshape->setTooltip(M("TP_WAVELET_CURVEEDITOR_CH_TOOLTIP")); + Chshape->setCurveColorProvider(this, 5); + curveEditorGAM->curveListComplete(); + Chshape->setBottomBarBgGradient(milestones); + + conBox->pack_start (*curveEditorGAM, Gtk::PACK_SHRINK, 4); + + avoid = Gtk::manage (new Gtk::CheckButton (M("TP_WAVELET_AVOID"))); + avoid->set_active (true); + avoidConn = avoid->signal_toggled().connect( sigc::mem_fun(*this, &Wavelet::avoidToggled) ); + conBox->pack_start(*avoid); + +// Residual Image + Gtk::VBox * resBox = Gtk::manage (new Gtk::VBox()); + resBox->set_border_width(4); + resBox->set_spacing(2); + + rescon = Gtk::manage (new Adjuster (M("TP_WAVELET_RESCON"), -100, 100, 1, 0)); + rescon->setAdjusterListener (this); + resBox->pack_start(*rescon, Gtk::PACK_SHRINK); + + thr = Gtk::manage (new Adjuster (M("TP_WAVELET_THR"), 0, 100, 1, 35)); + resBox->pack_start(*thr); + thr->setAdjusterListener (this); + + resconH = Gtk::manage (new Adjuster (M("TP_WAVELET_RESCONH"), -100, 100, 1, 0)); + resconH->setAdjusterListener (this); + resBox->pack_start(*resconH, Gtk::PACK_SHRINK); + + thrH = Gtk::manage (new Adjuster (M("TP_WAVELET_THRH"), 0, 100, 1, 65)); + thrH->setAdjusterListener (this); + resBox->pack_start(*thrH,Gtk::PACK_SHRINK); + + contrast = Gtk::manage (new Adjuster (M("TP_WAVELET_CONTRA"), -100, 100, 1, 0)); + contrast->set_tooltip_text (M("TP_WAVELET_CONTRA_TOOLTIP")); + contrast->setAdjusterListener (this); + resBox->pack_start(*contrast); //keep the possibility to reinstall + + reschro = Gtk::manage (new Adjuster (M("TP_WAVELET_RESCHRO"), -100, 100, 1, 0)); + reschro->setAdjusterListener (this); + resBox->pack_start(*reschro); + + + ctboxTM = Gtk::manage (new Gtk::HBox ()); + labmTM = Gtk::manage (new Gtk::Label (M("TP_WAVELET_TMTYPE")+":")); + ctboxTM->pack_start (*labmTM, Gtk::PACK_SHRINK, 1); + + Gtk::HSeparator *separatorR0 = Gtk::manage (new Gtk::HSeparator()); + resBox->pack_start(*separatorR0, Gtk::PACK_SHRINK, 2); + + TMmethod = Gtk::manage (new MyComboBoxText ()); + TMmethod->append_text (M("TP_WAVELET_COMPCONT")); + TMmethod->append_text (M("TP_WAVELET_COMPTM")); + TMmethodconn = TMmethod->signal_changed().connect ( sigc::mem_fun(*this, &Wavelet::TMmethodChanged) ); + ctboxTM->pack_start(*TMmethod); + resBox->pack_start (*ctboxTM); + + tmrs = Gtk::manage(new Adjuster (M("TP_WAVELET_TMSTRENGTH"), -1.0, 2.0, 0.01, 0.0)); + tmrs->set_tooltip_text (M("TP_WAVELET_TMSTRENGTH_TOOLTIP")); + + resBox->pack_start(*tmrs); + tmrs->setAdjusterListener (this); + + gamma = Gtk::manage(new Adjuster (M("TP_WAVELET_COMPGAMMA"), 0.4, 2.0, 0.01, 1.0)); + gamma->set_tooltip_text (M("TP_WAVELET_COMPGAMMA_TOOLTIP")); + resBox->pack_start(*gamma); + gamma->setAdjusterListener (this); + + Gtk::HSeparator *separatorR1 = Gtk::manage (new Gtk::HSeparator()); + resBox->pack_start(*separatorR1, Gtk::PACK_SHRINK, 2); + + hueskin2 = Gtk::manage (new ThresholdAdjuster (M("TP_WAVELET_HUESKY"), -314., 314., -260., -250, -130., -140., 0, false)); + hueskin2->set_tooltip_markup (M("TP_WAVELET_HUESKY_TOOLTIP")); + hueskin2->setBgGradient(milestones); + resBox->pack_start(*hueskin2); + hueskin2->setAdjusterListener (this); + + sky = Gtk::manage (new Adjuster (M("TP_WAVELET_SKY"), -100., 100.0, 1., 0.)); + sky->set_tooltip_text (M("TP_WAVELET_SKY_TOOLTIP")); + sky->setAdjusterListener (this); + + resBox->pack_start(*sky); + + // whole hue range + milestones.clear(); + for (int i=0; i<7; i++) { + float R, G, B; + float x = float(i)*(1.0f/6.0); + Color::hsv2rgb01(x, 0.5f, 0.5f, R, G, B); + milestones.push_back( GradientMilestone(double(x), double(R), double(G), double(B)) ); + } + + curveEditorRES = new CurveEditorGroup (options.lastWaveletCurvesDir); + curveEditorRES->setCurveListener (this); + + hhshape = static_cast(curveEditorRES->addCurve(CT_Flat, M("TP_WAVELET_CURVEEDITOR_HH"))); + hhshape->setTooltip(M("TP_WAVELET_CURVEEDITOR_HH_TOOLTIP")); + hhshape->setCurveColorProvider(this, 5); + curveEditorRES->curveListComplete(); + hhshape->setBottomBarBgGradient(milestones); + + resBox->pack_start (*curveEditorRES, Gtk::PACK_SHRINK, 4); + + // Toning and Color Balance + Gtk::HSeparator *separatorCB = Gtk::manage (new Gtk::HSeparator()); + + Gtk::VBox *chanMixerHLBox = Gtk::manage (new Gtk::VBox()); + Gtk::VBox *chanMixerMidBox = Gtk::manage (new Gtk::VBox()); + Gtk::VBox *chanMixerShadowsBox = Gtk::manage (new Gtk::VBox()); + + cbenab = Gtk::manage (new Gtk::CheckButton (M("TP_WAVELET_CBENAB"))); + cbenab->set_active (true); + cbenabConn = cbenab->signal_toggled().connect( sigc::mem_fun(*this, &Wavelet::cbenabToggled) ); + cbenab->set_tooltip_text (M("TP_WAVELET_CB_TOOLTIP")); + + Gtk::Image* iblueR = Gtk::manage (new RTImage ("ajd-wb-temp1.png")); + Gtk::Image* iyelL = Gtk::manage (new RTImage ("ajd-wb-temp2.png")); + Gtk::Image* imagL = Gtk::manage (new RTImage ("ajd-wb-green1.png")); + Gtk::Image* igreenR = Gtk::manage (new RTImage ("ajd-wb-green2.png")); + + Gtk::Image* iblueRm = Gtk::manage (new RTImage ("ajd-wb-temp1.png")); + Gtk::Image* iyelLm = Gtk::manage (new RTImage ("ajd-wb-temp2.png")); + Gtk::Image* imagLm = Gtk::manage (new RTImage ("ajd-wb-green1.png")); + Gtk::Image* igreenRm = Gtk::manage (new RTImage ("ajd-wb-green2.png")); + + Gtk::Image* iblueRh = Gtk::manage (new RTImage ("ajd-wb-temp1.png")); + Gtk::Image* iyelLh = Gtk::manage (new RTImage ("ajd-wb-temp2.png")); + Gtk::Image* imagLh = Gtk::manage (new RTImage ("ajd-wb-green1.png")); + Gtk::Image* igreenRh = Gtk::manage (new RTImage ("ajd-wb-green2.png")); + + greenhigh = Gtk::manage (new Adjuster ("", -100., 100., 1., 0., igreenRh, imagLh)); + bluehigh = Gtk::manage (new Adjuster ("", -100., 100., 1., 0., iblueRh, iyelLh)); + + greenmed = Gtk::manage (new Adjuster ("", -100., 100., 1., 0., igreenRm, imagLm)); + bluemed = Gtk::manage (new Adjuster ("", -100., 100., 1., 0. , iblueRm , iyelLm)); + + greenlow = Gtk::manage (new Adjuster ("", -100., 100., 1., 0., igreenR, imagL)); + bluelow = Gtk::manage (new Adjuster ("", -100., 100., 1., 0., iblueR , iyelL)); + + chanMixerHLBox->pack_start (*greenhigh); + chanMixerHLBox->pack_start (*bluehigh); + chanMixerMidBox->pack_start (*greenmed); + chanMixerMidBox->pack_start (*bluemed); + chanMixerShadowsBox->pack_start (*greenlow); + chanMixerShadowsBox->pack_start (*bluelow); + + greenlow->setAdjusterListener (this); + bluelow->setAdjusterListener (this); + greenmed->setAdjusterListener (this); + bluemed->setAdjusterListener (this); + greenhigh->setAdjusterListener (this); + bluehigh->setAdjusterListener (this); + + resBox->pack_start(*separatorCB, Gtk::PACK_SHRINK); + + chanMixerHLFrame = Gtk::manage (new Gtk::Frame(M("TP_COLORTONING_HIGHLIGHT"))); + chanMixerMidFrame = Gtk::manage (new Gtk::Frame(M("TP_COLORTONING_MIDTONES"))); + chanMixerShadowsFrame = Gtk::manage (new Gtk::Frame(M("TP_COLORTONING_SHADOWS"))); + + chanMixerHLFrame->add(*chanMixerHLBox); + chanMixerMidFrame->add(*chanMixerMidBox); + chanMixerShadowsFrame->add(*chanMixerShadowsBox); + resBox->pack_start(*cbenab); + + resBox->pack_start(*chanMixerHLFrame, Gtk::PACK_SHRINK); + resBox->pack_start(*chanMixerMidFrame, Gtk::PACK_SHRINK); + resBox->pack_start(*chanMixerShadowsFrame, Gtk::PACK_SHRINK); + + // Reset sliders + neutrHBox = Gtk::manage (new Gtk::HBox ()); + neutrHBox->set_border_width (2); + + neutral = Gtk::manage (new Gtk::Button (M("TP_COLORTONING_NEUTRAL"))); + RTImage *resetImg = Gtk::manage (new RTImage ("gtk-undo-ltr-small.png", "gtk-undo-rtl-small.png")); + neutral->set_image(*resetImg); + neutral->set_tooltip_text (M("TP_COLORTONING_NEUTRAL_TIP")); + neutralconn = neutral->signal_pressed().connect( sigc::mem_fun(*this, &Wavelet::neutral_pressed) ); + neutral->show(); + neutrHBox->pack_start (*neutral, Gtk::PACK_EXPAND_WIDGET); + + resBox->pack_start (*neutrHBox); + +// Final Touchup + ctboxBA = Gtk::manage (new Gtk::HBox ()); + labmBA = Gtk::manage (new Gtk::Label (M("TP_WAVELET_BATYPE")+":")); + ctboxBA->pack_start (*labmBA, Gtk::PACK_SHRINK, 1); + + BAmethod = Gtk::manage (new MyComboBoxText ()); + BAmethod->append_text (M("TP_WAVELET_BANONE")); + BAmethod->append_text (M("TP_WAVELET_BASLI")); + BAmethod->append_text (M("TP_WAVELET_BACUR")); + BAmethodconn = BAmethod->signal_changed().connect ( sigc::mem_fun(*this, &Wavelet::BAmethodChanged) ); + ctboxBA->pack_start(*BAmethod); + + balance = Gtk::manage (new Adjuster (M("TP_WAVELET_BALANCE"), -30, 100, 1, 0)); + balance->setAdjusterListener (this); + balance->set_tooltip_text (M("TP_WAVELET_BALANCE_TOOLTIP")); + std::vector milestonesW; + + milestonesW.clear(); + milestonesW.push_back( GradientMilestone(0., 0., 0., 0.) ); + milestonesW.push_back( GradientMilestone(1., 1., 1., 1.) ); + + opacityCurveEditorW = new CurveEditorGroup (options.lastWaveletCurvesDir, M("TP_WAVELET_OPACITYW")); + opacityCurveEditorW->setCurveListener (this); + + rtengine::WaveletParams::getDefaultOpacityCurveW(defaultCurve); + opacityShape = static_cast(opacityCurveEditorW->addCurve(CT_Flat, "", NULL, false)); + opacityShape->setIdentityValue(0.); + opacityShape->setResetCurve(FlatCurveType(defaultCurve.at(0)), defaultCurve); + opacityShape->setBottomBarBgGradient(milestonesW); + + // This will add the reset button at the end of the curveType buttons + opacityCurveEditorW->curveListComplete(); + opacityCurveEditorW->show(); + + iter = Gtk::manage (new Adjuster (M("TP_WAVELET_ITER"), -3, 3, 1, 0)); + iter->setAdjusterListener (this); + iter->set_tooltip_text (M("TP_WAVELET_ITER_TOOLTIP")); + + Gtk::HSeparator *separatorbalend = Gtk::manage (new Gtk::HSeparator()); + + opacityCurveEditorWL = new CurveEditorGroup (options.lastWaveletCurvesDir, M("TP_WAVELET_OPACITYWL")); + opacityCurveEditorWL->setCurveListener (this); + + rtengine::WaveletParams::getDefaultOpacityCurveWL(defaultCurve); + opacityShapeWL = static_cast(opacityCurveEditorWL->addCurve(CT_Flat, "", NULL, false)); + opacityShapeWL->setIdentityValue(0.); + opacityShapeWL->setResetCurve(FlatCurveType(defaultCurve.at(0)), defaultCurve); + opacityShapeWL->setTooltip(M("TP_WAVELET_OPACITYWL_TOOLTIP")); + + // This will add the reset button at the end of the curveType buttons + opacityCurveEditorWL->curveListComplete(); + opacityCurveEditorWL->show(); + + curveEditorG = new CurveEditorGroup (options.lastWaveletCurvesDir,M("TP_WAVELET_CONTEDIT")); + curveEditorG->setCurveListener (this); + + clshape = static_cast(curveEditorG->addCurve(CT_Diagonal, M("TP_WAVELET_CURVEEDITOR_CL"))); + clshape->setTooltip(M("TP_WAVELET_CURVEEDITOR_CL_TOOLTIP")); + std::vector milestones22; + + milestones22.push_back( GradientMilestone(0., 0., 0., 0.) ); + milestones22.push_back( GradientMilestone(1., 1., 1., 1.) ); + clshape->setBottomBarBgGradient(milestones22); + clshape->setLeftBarBgGradient(milestones22); + + curveEditorG->curveListComplete(); + + tmr = Gtk::manage (new Gtk::CheckButton (M("TP_WAVELET_BALCHRO"))); + tmr->set_active (true); + tmr->set_tooltip_text (M("TP_WAVELET_BALCHRO_TOOLTIP")); + tmrConn = tmr->signal_toggled().connect( sigc::mem_fun(*this, &Wavelet::tmrToggled) ); + + Gtk::VBox * finalBox = Gtk::manage (new Gtk::VBox()); + finalBox->set_border_width(4); + finalBox->set_spacing(2); + + finalBox->pack_start (*ctboxBA); + finalBox->pack_start(*balance); + + finalBox->pack_start( *opacityCurveEditorW, Gtk::PACK_SHRINK, 2); + + finalBox->pack_start(*iter); + + finalBox->pack_start(*tmr); + finalBox->pack_start(*separatorbalend, Gtk::PACK_SHRINK, 2); + finalBox->pack_start( *opacityCurveEditorWL, Gtk::PACK_SHRINK, 2); + + finalBox->pack_start (*curveEditorG, Gtk::PACK_SHRINK, 4); + +//----------------------------- + expsettings->add(*settingsVBox); + pack_start (*expsettings); + + expcontrast->add(*levBox); + pack_start (*expcontrast); + + expchroma->add(*chBox); + pack_start (*expchroma); + + exptoning->add(*tonBox); + pack_start (*exptoning); + + expnoise->add(*noiseBox); + pack_start (*expnoise); + + expedge->add(*edgBox); + pack_start (*expedge); + + expgamut->add(*conBox); + pack_start (*expgamut); + + expresid->add(*resBox); + pack_start(*expresid); + + expfinal->add(*finalBox); + pack_start(*expfinal); +} + +Wavelet::~Wavelet () { + delete opaCurveEditorG; + delete opacityCurveEditorG; + delete CCWcurveEditorG; + delete curveEditorRES; + delete curveEditorGAM; + delete curveEditorG; + delete opacityCurveEditorW; + delete opacityCurveEditorWL; + +} +int wavChangedUI (void* data) { + GThreadLock lock; // All GUI acces from idle_add callbacks or separate thread HAVE to be protected + (static_cast(data))->wavComputed_ (); + return 0; +} + +void Wavelet::wavChanged (double nlevel) +{ + nextnlevel=nlevel; + g_idle_add (wavChangedUI, this); +} +bool Wavelet::wavComputed_ () { + + disableListener (); + enableListener (); + updatewavLabel (); + return false; +} +void Wavelet::updatewavLabel () { + if (!batchMode) { + float lv; + lv=nextnlevel; + { + wavLabels->set_text( + Glib::ustring::compose(M("TP_WAVELET_LEVLABEL"), + Glib::ustring::format(std::fixed, std::setprecision(0), lv)) + ); + } + } +} +// Will only reset the chanel mixer +void Wavelet::neutral_pressed () { + disableListener(); + greenlow->resetValue(false); + bluelow->resetValue(false); + greenmed->resetValue(false); + bluemed->resetValue(false); + greenhigh->resetValue(false); + bluehigh->resetValue(false); + + enableListener(); + if (listener && getEnabled()) + listener->panelChanged (EvWavNeutral, M("ADJUSTER_RESET_TO_DEFAULT")); +} + +void Wavelet::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + Lmethodconn.block(true); + CLmethodconn.block(true); + Backmethodconn.block(true); + Tilesmethodconn.block(true); + daubcoeffmethodconn.block(true); + Dirmethodconn.block(true); + CHmethodconn.block(true); + CHSLmethodconn.block(true); + EDmethodconn.block(true); + BAmethodconn.block(true); + TMmethodconn.block(true); + HSmethodconn.block(true); + MedgreinfConn.block(true); + cbenabConn.block(true); + HSmethod->set_active (1); + + if (pp->wavelet.HSmethod=="without") + HSmethod->set_active (0); + else if (pp->wavelet.HSmethod=="with") + HSmethod->set_active (1); + HSmethodChanged(); + + CHmethod->set_active (1); + if (pp->wavelet.CHmethod=="without") + CHmethod->set_active (0); + else if (pp->wavelet.CHmethod=="with") + CHmethod->set_active (1); + else if (pp->wavelet.CHmethod=="link") + CHmethod->set_active (2); + CHmethodChanged(); + + Medgreinf->set_active (1); + if (pp->wavelet.Medgreinf=="more") + Medgreinf->set_active (0); + else if (pp->wavelet.Medgreinf=="none") + Medgreinf->set_active (1); + else if (pp->wavelet.Medgreinf=="less") + Medgreinf->set_active (2); + MedgreinfChanged(); + + CHSLmethod->set_active (1); + if (pp->wavelet.CHSLmethod=="SL") + CHSLmethod->set_active (0); + else if (pp->wavelet.CHSLmethod=="CU") + CHSLmethod->set_active (1); + CHSLmethodChanged(); + + EDmethod->set_active (1); + if (pp->wavelet.EDmethod=="SL") + EDmethod->set_active (0); + else if (pp->wavelet.EDmethod=="CU") + EDmethod->set_active (1); + EDmethodChanged(); + + BAmethod->set_active (0); + if (pp->wavelet.BAmethod=="none") + BAmethod->set_active (0); + else if (pp->wavelet.BAmethod=="sli") + BAmethod->set_active (1); + else if (pp->wavelet.BAmethod=="cur") + BAmethod->set_active (2); + BAmethodChanged(); + + TMmethod->set_active (1); + if (pp->wavelet.TMmethod=="cont") + TMmethod->set_active (0); + else if (pp->wavelet.TMmethod=="tm") + TMmethod->set_active (1); + // else if (pp->wavelet.TMmethod=="both") + // TMmethod->set_active (2); + + TMmethodChanged(); + + + Backmethod->set_active (3); + if (pp->wavelet.Backmethod=="black") { + Backmethod->set_active (0); + } + else if (pp->wavelet.Backmethod=="grey") { + Backmethod->set_active (1); + } + else if (pp->wavelet.Backmethod=="resid") { + Backmethod->set_active (2); + } + BackmethodChanged(); + + CLmethod->set_active (3); + if (pp->wavelet.CLmethod=="one") { + CLmethod->set_active (0); + } + else if (pp->wavelet.CLmethod=="inf") { + CLmethod->set_active (1); + } + else if (pp->wavelet.CLmethod=="sup") { + CLmethod->set_active (2); + } + else if (pp->wavelet.CLmethod=="all") { + CLmethod->set_active (3); + } + CLmethodChanged(); + + Tilesmethod->set_active (2); + if (pp->wavelet.Tilesmethod=="full") + Tilesmethod->set_active (0); + else if (pp->wavelet.Tilesmethod=="big") + Tilesmethod->set_active (1); + else if (pp->wavelet.Tilesmethod=="lit") + Tilesmethod->set_active (2); + TilesmethodChanged(); + + daubcoeffmethod->set_active (4); + if (pp->wavelet.daubcoeffmethod=="2_") + daubcoeffmethod->set_active (0); + else if (pp->wavelet.daubcoeffmethod=="4_") + daubcoeffmethod->set_active (1); + else if (pp->wavelet.daubcoeffmethod=="6_") + daubcoeffmethod->set_active (2); + else if (pp->wavelet.daubcoeffmethod=="10_") + daubcoeffmethod->set_active (3); + else if (pp->wavelet.daubcoeffmethod=="14_") + daubcoeffmethod->set_active (4); + daubcoeffmethodChanged(); + + Dirmethod->set_active (3); + if (pp->wavelet.Dirmethod=="one") + Dirmethod->set_active (0); + else if (pp->wavelet.Dirmethod=="two") + Dirmethod->set_active (1); + else if (pp->wavelet.Dirmethod=="thr") + Dirmethod->set_active (2); + else if (pp->wavelet.Dirmethod=="all") + Dirmethod->set_active (3); + DirmethodChanged(); + + int selectedLevel = atoi(pp->wavelet.Lmethod.data())-1; + Lmethod->set_active (selectedLevel == -1 ? 4 :selectedLevel); + + LmethodChanged(); + if (pedited) { + if (!pedited->wavelet.Lmethod) + Lmethod->set_active (8); + if (!pedited->wavelet.CLmethod) + CLmethod->set_active (3); + if (!pedited->wavelet.Backmethod) + Backmethod->set_active (2); + if (!pedited->wavelet.Tilesmethod) + Tilesmethod->set_active (2); + if (!pedited->wavelet.daubcoeffmethod) + daubcoeffmethod->set_active (4); + if (!pedited->wavelet.Dirmethod) + Dirmethod->set_active (3); + if (!pedited->wavelet.CHmethod) + CHmethod->set_active (1); + if (!pedited->wavelet.CHSLmethod) + CHSLmethod->set_active (1); + if (!pedited->wavelet.EDmethod) + EDmethod->set_active (1); + if (!pedited->wavelet.BAmethod) + BAmethod->set_active (1); + if (!pedited->wavelet.TMmethod) + TMmethod->set_active (1); + if (!pedited->wavelet.HSmethod) + HSmethod->set_active (1); + if (!pedited->wavelet.Medgreinf) + Medgreinf->set_active (2); + + set_inconsistent (multiImage && !pedited->wavelet.enabled); + ccshape->setUnChanged (!pedited->wavelet.ccwcurve); + opacityShapeRG->setCurve (pp->wavelet.opacityCurveRG); + opacityShapeBY->setCurve (pp->wavelet.opacityCurveBY); + opacityShape->setCurve (pp->wavelet.opacityCurveW); + opacityShapeWL->setCurve (pp->wavelet.opacityCurveWL); + hhshape->setUnChanged (!pedited->wavelet.hhcurve); + Chshape->setUnChanged (!pedited->wavelet.Chcurve); + clshape->setUnChanged (!pedited->wavelet.wavclCurve); + avoid->set_inconsistent (!pedited->wavelet.avoid); + tmr->set_inconsistent (!pedited->wavelet.tmr); + edgthresh->setEditedState (pedited->wavelet.edgthresh ? Edited : UnEdited); + rescon->setEditedState (pedited->wavelet.rescon ? Edited : UnEdited); + resconH->setEditedState (pedited->wavelet.resconH ? Edited : UnEdited); + reschro->setEditedState (pedited->wavelet.reschro ? Edited : UnEdited); + tmrs->setEditedState (pedited->wavelet.tmrs ? Edited : UnEdited); + gamma->setEditedState (pedited->wavelet.gamma ? Edited : UnEdited); + sup->setEditedState (pedited->wavelet.sup ? Edited : UnEdited); + sky->setEditedState (pedited->wavelet.sky ? Edited : UnEdited); + thres->setEditedState (pedited->wavelet.thres ? Edited : UnEdited); + balance->setEditedState (pedited->wavelet.balance ? Edited : UnEdited); + iter->setEditedState (pedited->wavelet.iter ? Edited : UnEdited); + threshold->setEditedState (pedited->wavelet.threshold ? Edited : UnEdited); + threshold2->setEditedState (pedited->wavelet.threshold2 ? Edited : UnEdited); + edgedetect->setEditedState (pedited->wavelet.edgedetect ? Edited : UnEdited); + edgedetectthr->setEditedState (pedited->wavelet.edgedetectthr ? Edited : UnEdited); + edgedetectthr2->setEditedState (pedited->wavelet.edgedetectthr2 ? Edited : UnEdited); + chroma->setEditedState (pedited->wavelet.chroma ? Edited : UnEdited); + chro->setEditedState (pedited->wavelet.chro ? Edited : UnEdited); + + greenlow->setEditedState (pedited->wavelet.greenlow ? Edited : UnEdited); + bluelow->setEditedState (pedited->wavelet.bluelow ? Edited : UnEdited); + greenmed->setEditedState (pedited->wavelet.greenmed ? Edited : UnEdited); + bluemed->setEditedState (pedited->wavelet.bluemed ? Edited : UnEdited); + greenhigh->setEditedState (pedited->wavelet.greenhigh ? Edited : UnEdited); + bluehigh->setEditedState (pedited->wavelet.bluehigh ? Edited : UnEdited); + + + median->set_inconsistent (!pedited->wavelet.median); + medianlev->set_inconsistent (!pedited->wavelet.medianlev); + linkedg->set_inconsistent (!pedited->wavelet.linkedg); + // edgreinf->set_inconsistent (!pedited->wavelet.edgreinf); + cbenab->set_inconsistent (!pedited->wavelet.cbenab); + lipst->set_inconsistent (!pedited->wavelet.lipst); + contrast->setEditedState (pedited->wavelet.contrast ? Edited : UnEdited); + edgrad->setEditedState (pedited->wavelet.edgrad ? Edited : UnEdited); + edgval->setEditedState (pedited->wavelet.edgval ? Edited : UnEdited); + thr->setEditedState (pedited->wavelet.thr ? Edited : UnEdited); + thrH->setEditedState (pedited->wavelet.thrH ? Edited : UnEdited); + skinprotect->setEditedState (pedited->wavelet.skinprotect ? Edited : UnEdited); + hueskin->setEditedState (pedited->wavelet.hueskin ? Edited : UnEdited); + hueskin2->setEditedState (pedited->wavelet.hueskin2 ? Edited : UnEdited); + hllev->setEditedState (pedited->wavelet.hllev ? Edited : UnEdited); + bllev->setEditedState (pedited->wavelet.bllev ? Edited : UnEdited); + pastlev->setEditedState (pedited->wavelet.pastlev ? Edited : UnEdited); + satlev->setEditedState (pedited->wavelet.satlev ? Edited : UnEdited); + strength->setEditedState(pedited->wavelet.strength ? Edited : UnEdited); + edgcont->setEditedState (pedited->wavelet.edgcont ? Edited : UnEdited); + level0noise->setEditedState (pedited->wavelet.level0noise ? Edited : UnEdited); + level1noise->setEditedState (pedited->wavelet.level1noise ? Edited : UnEdited); + level2noise->setEditedState (pedited->wavelet.level2noise ? Edited : UnEdited); + + for(int i = 0; i < 9; i++) { + correction[i]->setEditedState (pedited->wavelet.c[i] ? Edited : UnEdited); + } + for(int i = 0; i < 9; i++) { + correctionch[i]->setEditedState (pedited->wavelet.ch[i] ? Edited : UnEdited); + } + } + ccshape->setCurve (pp->wavelet.ccwcurve); + opacityShapeRG->setCurve (pp->wavelet.opacityCurveRG); + opacityShapeBY->setCurve (pp->wavelet.opacityCurveBY); + opacityShape->setCurve (pp->wavelet.opacityCurveW); + opacityShapeWL->setCurve (pp->wavelet.opacityCurveWL); + hhshape->setCurve (pp->wavelet.hhcurve); + Chshape->setCurve (pp->wavelet.Chcurve); + clshape->setCurve (pp->wavelet.wavclCurve); + + setEnabled(pp->wavelet.enabled); + avoidConn.block (true); + avoid->set_active (pp->wavelet.avoid); + avoidConn.block (false); + tmrConn.block (true); + tmr->set_active (pp->wavelet.tmr); + tmrConn.block (false); + medianConn.block (true); + median->set_active (pp->wavelet.median); + medianConn.block (false); + medianlevConn.block (true); + medianlev->set_active (pp->wavelet.medianlev); + medianlevConn.block (false); + linkedgConn.block (true); + linkedg->set_active (pp->wavelet.linkedg); + linkedgConn.block (false); + cbenabConn.block (true); + cbenab->set_active (pp->wavelet.cbenab); + cbenabConn.block (false); + + lipstConn.block (true); + lipst->set_active (pp->wavelet.lipst); + lipstConn.block (false); + //edgreinfConn.block (true); + //edgreinf->set_active (pp->wavelet.edgreinf); + //edgreinfConn.block (false); + //lastedgreinf = pp->wavelet.edgreinf; + lastmedian = pp->wavelet.median; + lastmedianlev = pp->wavelet.medianlev; + lastlinkedg = pp->wavelet.linkedg; + lastcbenab = pp->wavelet.cbenab; + lastlipst = pp->wavelet.lipst; + lastavoid = pp->wavelet.avoid; + lasttmr = pp->wavelet.tmr; + rescon->setValue (pp->wavelet.rescon); + resconH->setValue (pp->wavelet.resconH); + reschro->setValue (pp->wavelet.reschro); + tmrs->setValue (pp->wavelet.tmrs); + gamma->setValue (pp->wavelet.gamma); + sup->setValue (pp->wavelet.sup); + sky->setValue (pp->wavelet.sky); + thres->setValue (pp->wavelet.thres); + chroma->setValue (pp->wavelet.chroma); + chro->setValue (pp->wavelet.chro); + contrast->setValue (pp->wavelet.contrast); + edgrad->setValue (pp->wavelet.edgrad); + edgval->setValue (pp->wavelet.edgval); + edgthresh->setValue (pp->wavelet.edgthresh); + thr->setValue (pp->wavelet.thr); + thrH->setValue (pp->wavelet.thrH); + skinprotect->setValue(pp->wavelet.skinprotect); + hueskin->setValue(pp->wavelet.hueskin); + hueskin2->setValue(pp->wavelet.hueskin2); + threshold->setValue(pp->wavelet.threshold); + threshold2->setValue(pp->wavelet.threshold2); + edgedetect->setValue(pp->wavelet.edgedetect); + edgedetectthr->setValue(pp->wavelet.edgedetectthr); + edgedetectthr2->setValue(pp->wavelet.edgedetectthr2); + hllev->setValue(pp->wavelet.hllev); + bllev->setValue(pp->wavelet.bllev); + pastlev->setValue(pp->wavelet.pastlev); + satlev->setValue(pp->wavelet.satlev); + edgcont->setValue(pp->wavelet.edgcont); + + greenlow->setValue (pp->wavelet.greenlow); + bluelow->setValue (pp->wavelet.bluelow); + greenmed->setValue (pp->wavelet.greenmed); + bluemed->setValue (pp->wavelet.bluemed); + greenhigh->setValue (pp->wavelet.greenhigh); + bluehigh->setValue (pp->wavelet.bluehigh); + + level0noise->setValue(pp->wavelet.level0noise); + level1noise->setValue(pp->wavelet.level1noise); + level2noise->setValue(pp->wavelet.level2noise); + strength->setValue(pp->wavelet.strength); + balance->setValue(pp->wavelet.balance); + iter->setValue(pp->wavelet.iter); + for (int i = 0; i < 9; i++) { + correction[i]->setValue(pp->wavelet.c[i]); + } + for (int i = 0; i < 9; i++) { + correctionch[i]->setValue(pp->wavelet.ch[i]); + } + int y; + y=thres->getValue(); + int z; + for(z=y;z<9;z++) correction[z]->hide(); + for(z=0;zshow(); + if (pp->wavelet.CHSLmethod=="SL") { + for(z=y;z<9;z++) correctionch[z]->hide(); + for(z=0;zshow(); + } + float tm; +/* tm=tmrs->getValue(); + if(tm==0.f) tmr->hide(); + else tmr->show(); +*/ + CHmethodChanged(); + CHSLmethodChanged(); + EDmethodChanged(); + BAmethodChanged(); + TMmethodChanged(); + MedgreinfChanged(); + if(z==9) sup->show(); else sup->hide(); + Lmethodconn.block(false); + CLmethodconn.block(false); + Backmethodconn.block(false); + Tilesmethodconn.block(false); + daubcoeffmethodconn.block(false); + CHmethodconn.block(false); + CHSLmethodconn.block(false); + EDmethodconn.block(false); + BAmethodconn.block(false); + TMmethodconn.block(false); + HSmethodconn.block(false); + Dirmethodconn.block(false); + MedgreinfConn.block(false); + + medianlevToggled () ; + linkedgToggled () ; + lipstToggled () ; + cbenabToggled () ; + + enableListener (); +} + +void Wavelet::setEditProvider (EditDataProvider *provider) { + ccshape->setEditProvider(provider); + opacityShapeRG->setEditProvider(provider); + opacityShapeBY->setEditProvider(provider); + opacityShape->setEditProvider(provider); + opacityShapeWL->setEditProvider(provider); + hhshape->setEditProvider(provider); + Chshape->setEditProvider(provider); + clshape->setEditProvider(provider); + +} + +void Wavelet::autoOpenCurve () { + ccshape->openIfNonlinear(); + //opacityShapeRG->openIfNonlinear(); + //opacityShapeBY->openIfNonlinear(); +} + +void Wavelet::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->wavelet.enabled = getEnabled(); + pp->wavelet.avoid = avoid->get_active (); + pp->wavelet.tmr = tmr->get_active (); + pp->wavelet.rescon = rescon->getValue(); + pp->wavelet.resconH = resconH->getValue(); + pp->wavelet.reschro = reschro->getValue(); + pp->wavelet.tmrs = tmrs->getValue(); + pp->wavelet.gamma = gamma->getValue(); + pp->wavelet.sup = sup->getValue(); + pp->wavelet.sky = sky->getValue(); + pp->wavelet.thres = thres->getValue(); + pp->wavelet.chroma = chroma->getValue(); + pp->wavelet.chro = chro->getValue(); + pp->wavelet.median = median->get_active (); + pp->wavelet.medianlev = medianlev->get_active (); + pp->wavelet.linkedg = linkedg->get_active (); + //pp->wavelet.edgreinf = edgreinf->get_active (); + pp->wavelet.cbenab = cbenab->get_active (); + pp->wavelet.lipst = lipst->get_active (); + pp->wavelet.contrast = contrast->getValue(); + pp->wavelet.edgrad = edgrad->getValue(); + pp->wavelet.edgval = edgval->getValue(); + pp->wavelet.edgthresh = edgthresh->getValue(); + pp->wavelet.thr = thr->getValue(); + pp->wavelet.thrH = thrH->getValue(); + pp->wavelet.hueskin = hueskin->getValue (); + pp->wavelet.hueskin2 = hueskin2->getValue (); + pp->wavelet.skinprotect = skinprotect->getValue(); + pp->wavelet.threshold = threshold->getValue(); + pp->wavelet.threshold2 = threshold2->getValue(); + pp->wavelet.edgedetect = edgedetect->getValue(); + pp->wavelet.edgedetectthr = edgedetectthr->getValue(); + pp->wavelet.edgedetectthr2 = edgedetectthr2->getValue(); + pp->wavelet.hllev = hllev->getValue (); + pp->wavelet.bllev = bllev->getValue (); + pp->wavelet.edgcont = edgcont->getValue (); + pp->wavelet.level0noise = level0noise->getValue (); + pp->wavelet.level1noise = level1noise->getValue (); + pp->wavelet.level2noise = level2noise->getValue (); + pp->wavelet.ccwcurve = ccshape->getCurve (); + pp->wavelet.opacityCurveRG = opacityShapeRG->getCurve (); + pp->wavelet.opacityCurveBY = opacityShapeBY->getCurve (); + pp->wavelet.opacityCurveW = opacityShape->getCurve (); + pp->wavelet.opacityCurveWL = opacityShapeWL->getCurve (); + pp->wavelet.hhcurve = hhshape->getCurve (); + pp->wavelet.Chcurve = Chshape->getCurve (); + pp->wavelet.pastlev = pastlev->getValue (); + pp->wavelet.satlev = satlev->getValue (); + pp->wavelet.strength = (int) strength->getValue(); + pp->wavelet.balance = (int) balance->getValue(); + + pp->wavelet.greenlow = greenlow->getValue (); + pp->wavelet.bluelow = bluelow->getValue (); + pp->wavelet.greenmed = greenmed->getValue (); + pp->wavelet.bluemed = bluemed->getValue (); + pp->wavelet.greenhigh = greenhigh->getValue (); + pp->wavelet.bluehigh = bluehigh->getValue (); + + pp->wavelet.iter = (int) iter->getValue(); + pp->wavelet.wavclCurve = clshape->getCurve (); + + for (int i = 0; i < 9; i++) { + pp->wavelet.c[i] = (int) correction[i]->getValue(); + } + for (int i = 0; i < 9; i++) { + pp->wavelet.ch[i] = (int) correctionch[i]->getValue(); + } + + if (pedited) { + pedited->wavelet.enabled = !get_inconsistent(); + pedited->wavelet.avoid = !avoid->get_inconsistent(); + pedited->wavelet.tmr = !tmr->get_inconsistent(); + pedited->wavelet.median = !median->get_inconsistent(); + pedited->wavelet.medianlev = !medianlev->get_inconsistent(); + pedited->wavelet.linkedg = !linkedg->get_inconsistent(); + pedited->wavelet.cbenab = !cbenab->get_inconsistent(); + pedited->wavelet.lipst = !lipst->get_inconsistent(); + pedited->wavelet.Medgreinf = Medgreinf->get_active_row_number() != 2; + pedited->wavelet.Lmethod = Lmethod->get_active_row_number() != 8; + pedited->wavelet.CLmethod = CLmethod->get_active_row_number() != 3; + pedited->wavelet.Backmethod = Backmethod->get_active_row_number() != 2; + pedited->wavelet.Tilesmethod = Tilesmethod->get_active_row_number() != 2; + pedited->wavelet.daubcoeffmethod = daubcoeffmethod->get_active_row_number() != 4; + pedited->wavelet.CHmethod = CHmethod->get_active_row_number() != 2; + pedited->wavelet.CHSLmethod = CHSLmethod->get_active_row_number() != 1; + pedited->wavelet.EDmethod = EDmethod->get_active_row_number() != 1; + pedited->wavelet.BAmethod = BAmethod->get_active_row_number() != 3; + pedited->wavelet.TMmethod = TMmethod->get_active_row_number() != 2; + pedited->wavelet.HSmethod = HSmethod->get_active_row_number() != 1; + pedited->wavelet.Dirmethod = Dirmethod->get_active_row_number() != 3; + pedited->wavelet.edgthresh = edgthresh->getEditedState(); + pedited->wavelet.rescon = rescon->getEditedState(); + pedited->wavelet.resconH = resconH->getEditedState(); + pedited->wavelet.reschro = reschro->getEditedState(); + pedited->wavelet.tmrs = tmrs->getEditedState(); + pedited->wavelet.gamma = gamma->getEditedState(); + pedited->wavelet.sup = sup->getEditedState(); + pedited->wavelet.sky = sky->getEditedState(); + pedited->wavelet.thres = thres->getEditedState(); + pedited->wavelet.threshold = threshold->getEditedState(); + pedited->wavelet.threshold2 = threshold2->getEditedState(); + pedited->wavelet.edgedetect = edgedetect->getEditedState(); + pedited->wavelet.edgedetectthr = edgedetectthr->getEditedState(); + pedited->wavelet.edgedetectthr2 = edgedetectthr2->getEditedState(); + pedited->wavelet.chroma = chroma->getEditedState(); + pedited->wavelet.chro = chro->getEditedState(); + pedited->wavelet.contrast = contrast->getEditedState(); + pedited->wavelet.edgrad = edgrad->getEditedState(); + pedited->wavelet.edgval = edgval->getEditedState(); + pedited->wavelet.thr = thr->getEditedState(); + pedited->wavelet.thrH = thrH->getEditedState(); + pedited->wavelet.hueskin = hueskin->getEditedState (); + pedited->wavelet.hueskin2 = hueskin2->getEditedState (); + pedited->wavelet.skinprotect = skinprotect->getEditedState(); + pedited->wavelet.hllev = hllev->getEditedState (); + pedited->wavelet.ccwcurve = !ccshape->isUnChanged (); + pedited->wavelet.edgcont = edgcont->getEditedState (); + pedited->wavelet.level0noise = level0noise->getEditedState (); + pedited->wavelet.level1noise = level1noise->getEditedState (); + pedited->wavelet.level2noise = level2noise->getEditedState (); + pedited->wavelet.opacityCurveRG = !opacityShapeRG->isUnChanged (); + pedited->wavelet.opacityCurveBY = !opacityShapeBY->isUnChanged (); + pedited->wavelet.opacityCurveW = !opacityShape->isUnChanged (); + pedited->wavelet.opacityCurveWL = !opacityShapeWL->isUnChanged (); + pedited->wavelet.hhcurve = !hhshape->isUnChanged (); + pedited->wavelet.Chcurve = !Chshape->isUnChanged (); + pedited->wavelet.bllev = bllev->getEditedState (); + pedited->wavelet.pastlev = pastlev->getEditedState (); + pedited->wavelet.satlev = satlev->getEditedState (); + pedited->wavelet.strength = strength->getEditedState (); + pedited->wavelet.greenlow = greenlow->getEditedState (); + pedited->wavelet.bluelow = bluelow->getEditedState (); + pedited->wavelet.greenmed = greenmed->getEditedState (); + pedited->wavelet.bluemed = bluemed->getEditedState (); + pedited->wavelet.greenhigh = greenhigh->getEditedState (); + pedited->wavelet.bluehigh = bluehigh->getEditedState (); + + pedited->wavelet.balance = balance->getEditedState (); + pedited->wavelet.iter = iter->getEditedState (); + pedited->wavelet.wavclCurve = !clshape->isUnChanged (); + + for(int i = 0; i < 9; i++) { + pedited->wavelet.c[i] = correction[i]->getEditedState(); + } + for(int i = 0; i < 9; i++) { + pedited->wavelet.ch[i] = correctionch[i]->getEditedState(); + } + + } + if (CHmethod->get_active_row_number()==0) + pp->wavelet.CHmethod = "without"; + else if (CHmethod->get_active_row_number()==1) + pp->wavelet.CHmethod = "with"; + else if (CHmethod->get_active_row_number()==2) + pp->wavelet.CHmethod = "link"; + + if (Medgreinf->get_active_row_number()==0) + pp->wavelet.Medgreinf = "more"; + else if (Medgreinf->get_active_row_number()==1) + pp->wavelet.Medgreinf = "none"; + else if (Medgreinf->get_active_row_number()==2) + pp->wavelet.Medgreinf = "less"; + + if (CHSLmethod->get_active_row_number()==0) + pp->wavelet.CHSLmethod = "SL"; + else if (CHSLmethod->get_active_row_number()==1) + pp->wavelet.CHSLmethod = "CU"; + + if (EDmethod->get_active_row_number()==0) + pp->wavelet.EDmethod = "SL"; + else if (EDmethod->get_active_row_number()==1) + pp->wavelet.EDmethod = "CU"; + + if (BAmethod->get_active_row_number()==0) + pp->wavelet.BAmethod = "none"; + else if (BAmethod->get_active_row_number()==1) + pp->wavelet.BAmethod = "sli"; + else if (BAmethod->get_active_row_number()==2) + pp->wavelet.BAmethod = "cur"; + + if (TMmethod->get_active_row_number()==0) + pp->wavelet.TMmethod = "cont"; + else if (TMmethod->get_active_row_number()==1) + pp->wavelet.TMmethod = "tm"; + // else if (TMmethod->get_active_row_number()==2) + // pp->wavelet.TMmethod = "both"; + + if (HSmethod->get_active_row_number()==0) + pp->wavelet.HSmethod = "without"; + else if (HSmethod->get_active_row_number()==1) + pp->wavelet.HSmethod = "with"; + + if (CLmethod->get_active_row_number()==0) + pp->wavelet.CLmethod = "one"; + else if (CLmethod->get_active_row_number()==1) + pp->wavelet.CLmethod = "inf"; + else if (CLmethod->get_active_row_number()==2) + pp->wavelet.CLmethod = "sup"; + else if (CLmethod->get_active_row_number()==3) + pp->wavelet.CLmethod = "all"; + + if (Backmethod->get_active_row_number()==0) + pp->wavelet.Backmethod = "black"; + else if (Backmethod->get_active_row_number()==1) + pp->wavelet.Backmethod = "grey"; + else if (Backmethod->get_active_row_number()==2) + pp->wavelet.Backmethod = "resid"; + + if (Tilesmethod->get_active_row_number()==0) + pp->wavelet.Tilesmethod = "full"; + else if (Tilesmethod->get_active_row_number()==1) + pp->wavelet.Tilesmethod = "big"; + else if (Tilesmethod->get_active_row_number()==2) + pp->wavelet.Tilesmethod = "lit"; + + if (daubcoeffmethod->get_active_row_number()==0) + pp->wavelet.daubcoeffmethod = "2_"; + else if (daubcoeffmethod->get_active_row_number()==1) + pp->wavelet.daubcoeffmethod = "4_"; + else if (daubcoeffmethod->get_active_row_number()==2) + pp->wavelet.daubcoeffmethod = "6_"; + else if (daubcoeffmethod->get_active_row_number()==3) + pp->wavelet.daubcoeffmethod = "10_"; + else if (daubcoeffmethod->get_active_row_number()==4) + pp->wavelet.daubcoeffmethod = "14_"; + + if (Dirmethod->get_active_row_number()==0) + pp->wavelet.Dirmethod = "one"; + else if (Dirmethod->get_active_row_number()==1) + pp->wavelet.Dirmethod = "two"; + else if (Dirmethod->get_active_row_number()==2) + pp->wavelet.Dirmethod = "thr"; + else if (Dirmethod->get_active_row_number()==3) + pp->wavelet.Dirmethod = "all"; + + char lMethod[3]; // one additional char to avoid buffer overrun if someone increases number of levels > 9 + sprintf(lMethod, "%d", Lmethod->get_active_row_number()+1); + pp->wavelet.Lmethod = lMethod; + + +} +void Wavelet::curveChanged (CurveEditor* ce) { + + if (listener && getEnabled()) { + if (ce == ccshape) + listener->panelChanged (EvWavCCCurve, M("HISTORY_CUSTOMCURVE")); + else if (ce == opacityShapeRG) + listener->panelChanged (EvWavColor, M("HISTORY_CUSTOMCURVE")); + else if (ce == opacityShapeBY) + listener->panelChanged (EvWavOpac, M("HISTORY_CUSTOMCURVE")); + else if (ce == opacityShape) + listener->panelChanged (EvWavopacity, M("HISTORY_CUSTOMCURVE")); + else if (ce == opacityShapeWL) + listener->panelChanged (EvWavopacityWL, M("HISTORY_CUSTOMCURVE")); + else if (ce == hhshape) + listener->panelChanged (EvWavHHCurve, M("HISTORY_CUSTOMCURVE")); + else if (ce == Chshape) + listener->panelChanged (EvWavCHCurve, M("HISTORY_CUSTOMCURVE")); + else if (ce == clshape) + listener->panelChanged (EvWavCLCurve, M("HISTORY_CUSTOMCURVE")); + + } +} + +void Wavelet::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + for (int i = 0; i < 9; i++) { + correction[i]->setDefault(defParams->wavelet.c[i]); + } + for (int i = 0; i < 9; i++) { + correctionch[i]->setDefault(defParams->wavelet.ch[i]); + } + strength->setDefault(defParams->wavelet.strength ); + balance->setDefault(defParams->wavelet.balance ); + iter->setDefault(defParams->wavelet.iter ); + rescon->setDefault (defParams->wavelet.rescon); + resconH->setDefault (defParams->wavelet.resconH); + reschro->setDefault (defParams->wavelet.reschro); + tmrs->setDefault (defParams->wavelet.tmrs); + gamma->setDefault (defParams->wavelet.gamma); + sup->setDefault (defParams->wavelet.sup); + sky->setDefault (defParams->wavelet.sky); + thres->setDefault (defParams->wavelet.thres); + threshold->setDefault (defParams->wavelet.threshold); + threshold2->setDefault (defParams->wavelet.threshold2); + edgedetect->setDefault (defParams->wavelet.edgedetect); + edgedetectthr->setDefault (defParams->wavelet.edgedetectthr); + edgedetectthr2->setDefault (defParams->wavelet.edgedetectthr2); + chroma->setDefault (defParams->wavelet.chroma); + chro->setDefault (defParams->wavelet.chro); + contrast->setDefault (defParams->wavelet.contrast); + edgrad->setDefault (defParams->wavelet.edgrad); + edgval->setDefault (defParams->wavelet.edgval); + edgthresh->setDefault (defParams->wavelet.edgthresh); + thr->setDefault (defParams->wavelet.thr); + thrH->setDefault (defParams->wavelet.thrH); + hueskin->setDefault (defParams->wavelet.hueskin); + hueskin2->setDefault (defParams->wavelet.hueskin2); + hllev->setDefault (defParams->wavelet.hllev); + bllev->setDefault (defParams->wavelet.bllev); + pastlev->setDefault (defParams->wavelet.pastlev); + satlev->setDefault (defParams->wavelet.satlev); + edgcont->setDefault (defParams->wavelet.edgcont); + level0noise->setDefault (defParams->wavelet.level0noise); + level1noise->setDefault (defParams->wavelet.level1noise); + level2noise->setDefault (defParams->wavelet.level2noise); + + greenlow->setDefault (defParams->wavelet.greenlow); + bluelow->setDefault (defParams->wavelet.bluelow); + greenmed->setDefault (defParams->wavelet.greenmed); + bluemed->setDefault (defParams->wavelet.bluemed); + greenhigh->setDefault (defParams->wavelet.greenhigh); + bluehigh->setDefault (defParams->wavelet.bluehigh); + + if (pedited) { + greenlow->setDefaultEditedState (pedited->wavelet.greenlow ? Edited : UnEdited); + bluelow->setDefaultEditedState (pedited->wavelet.bluelow ? Edited : UnEdited); + greenmed->setDefaultEditedState (pedited->wavelet.greenmed ? Edited : UnEdited); + bluemed->setDefaultEditedState (pedited->wavelet.bluemed ? Edited : UnEdited); + greenhigh->setDefaultEditedState (pedited->wavelet.greenhigh ? Edited : UnEdited); + bluehigh->setDefaultEditedState (pedited->wavelet.bluehigh ? Edited : UnEdited); + + rescon->setDefault (defParams->wavelet.rescon); + resconH->setDefault (defParams->wavelet.resconH); + reschro->setDefault (defParams->wavelet.reschro); + tmrs->setDefault (defParams->wavelet.tmrs); + gamma->setDefault (defParams->wavelet.gamma); + sup->setDefault (defParams->wavelet.sup); + sky->setDefaultEditedState(pedited->wavelet.sky ? Edited : UnEdited); + thres->setDefaultEditedState(pedited->wavelet.thres ? Edited : UnEdited); + threshold->setDefaultEditedState(pedited->wavelet.threshold ? Edited : UnEdited); + threshold2->setDefaultEditedState(pedited->wavelet.threshold2 ? Edited : UnEdited); + edgedetect->setDefaultEditedState(pedited->wavelet.edgedetect ? Edited : UnEdited); + edgedetectthr->setDefaultEditedState(pedited->wavelet.edgedetectthr ? Edited : UnEdited); + edgedetectthr2->setDefaultEditedState(pedited->wavelet.edgedetectthr2 ? Edited : UnEdited); + chroma->setDefaultEditedState(pedited->wavelet.chroma ? Edited : UnEdited); + chro->setDefaultEditedState(pedited->wavelet.chro ? Edited : UnEdited); + contrast->setDefaultEditedState(pedited->wavelet.contrast ? Edited : UnEdited); + edgrad->setDefaultEditedState(pedited->wavelet.edgrad ? Edited : UnEdited); + edgval->setDefaultEditedState(pedited->wavelet.edgval ? Edited : UnEdited); + edgthresh->setDefault (defParams->wavelet.edgthresh); + thr->setDefaultEditedState(pedited->wavelet.thr ? Edited : UnEdited); + thrH->setDefaultEditedState(pedited->wavelet.thrH ? Edited : UnEdited); + skinprotect->setDefaultEditedState(pedited->wavelet.skinprotect ? Edited : UnEdited); + hueskin->setDefaultEditedState (pedited->wavelet.hueskin ? Edited : UnEdited); + hueskin2->setDefaultEditedState (pedited->wavelet.hueskin2 ? Edited : UnEdited); + hllev->setDefaultEditedState (pedited->wavelet.hllev ? Edited : UnEdited); + bllev->setDefaultEditedState (pedited->wavelet.bllev ? Edited : UnEdited); + pastlev->setDefaultEditedState (pedited->wavelet.pastlev ? Edited : UnEdited); + satlev->setDefaultEditedState (pedited->wavelet.satlev ? Edited : UnEdited); + edgcont->setDefaultEditedState (pedited->wavelet.edgcont ? Edited : UnEdited); + strength->setDefaultEditedState (pedited->wavelet.strength ? Edited : UnEdited); + balance->setDefaultEditedState (pedited->wavelet.balance ? Edited : UnEdited); + iter->setDefaultEditedState (pedited->wavelet.iter ? Edited : UnEdited); + level0noise->setDefaultEditedState (pedited->wavelet.level0noise ? Edited : UnEdited); + level1noise->setDefaultEditedState (pedited->wavelet.level1noise ? Edited : UnEdited); + level2noise->setDefaultEditedState (pedited->wavelet.level2noise ? Edited : UnEdited); + + for (int i = 0; i < 9; i++) { + correction[i]->setDefaultEditedState(pedited->wavelet.c[i] ? Edited : UnEdited); + } + for (int i = 0; i < 9; i++) { + correctionch[i]->setDefaultEditedState(pedited->wavelet.ch[i] ? Edited : UnEdited); + } + } + else { + rescon->setDefaultEditedState(Irrelevant); + resconH->setDefaultEditedState(Irrelevant); + reschro->setDefaultEditedState(Irrelevant); + tmrs->setDefaultEditedState(Irrelevant); + gamma->setDefaultEditedState(Irrelevant); + sup->setDefaultEditedState(Irrelevant); + sky->setDefaultEditedState(Irrelevant); + thres->setDefaultEditedState(Irrelevant); + threshold->setDefaultEditedState(Irrelevant); + threshold2->setDefaultEditedState(Irrelevant); + edgedetect->setDefaultEditedState(Irrelevant); + edgedetectthr->setDefaultEditedState(Irrelevant); + edgedetectthr2->setDefaultEditedState(Irrelevant); + chroma->setDefaultEditedState(Irrelevant); + chro->setDefaultEditedState(Irrelevant); + contrast->setDefaultEditedState(Irrelevant); + edgrad->setDefaultEditedState(Irrelevant); + edgval->setDefaultEditedState(Irrelevant); + edgthresh->setDefaultEditedState(Irrelevant); + thr->setDefaultEditedState(Irrelevant); + thrH->setDefaultEditedState(Irrelevant); + skinprotect->setDefaultEditedState(Irrelevant); + hueskin->setDefaultEditedState (Irrelevant); + hueskin2->setDefaultEditedState (Irrelevant); + hllev->setDefaultEditedState (Irrelevant); + bllev->setDefaultEditedState (Irrelevant); + edgcont->setDefaultEditedState (Irrelevant); + level0noise->setDefaultEditedState (Irrelevant); + level1noise->setDefaultEditedState (Irrelevant); + level2noise->setDefaultEditedState (Irrelevant); + pastlev->setDefaultEditedState (Irrelevant); + satlev->setDefaultEditedState (Irrelevant); + strength->setDefaultEditedState (Irrelevant); + balance->setDefaultEditedState (Irrelevant); + iter->setDefaultEditedState (Irrelevant); + + for (int i = 0; i < 9; i++) { + correction[i]->setDefaultEditedState(Irrelevant); + } + for (int i = 0; i < 9; i++) { + correctionch[i]->setDefaultEditedState(Irrelevant); + } + + } +} +void Wavelet::adjusterChanged (ThresholdAdjuster* a, double newBottom, double newTop) { + if (listener && getEnabled()) { + if(a==level0noise) { + listener->panelChanged (EvWavlev0nois, + Glib::ustring::compose(Glib::ustring(M("TP_WAVELET_NOIS")+": %1"+"\n"+M("TP_WAVELET_STREN")+": %2"), int(newTop), int(newBottom))); + } + else if(a==level1noise) { + listener->panelChanged (EvWavlev1nois, + Glib::ustring::compose(Glib::ustring(M("TP_WAVELET_NOIS")+": %1"+"\n"+M("TP_WAVELET_STREN")+": %2"), int(newTop), int(newBottom))); + } + else if(a==level2noise) { + listener->panelChanged (EvWavlev2nois, + Glib::ustring::compose(Glib::ustring(M("TP_WAVELET_NOIS")+": %1"+"\n"+M("TP_WAVELET_STREN")+": %2"), int(newTop), int(newBottom))); + } + + } +} + + +void Wavelet::adjusterChanged2 (ThresholdAdjuster* a, int newBottomL, int newTopL, int newBottomR, int newTopR) { + if (listener && (multiImage||getEnabled()) ) { + if(a==hueskin) { + listener->panelChanged (EvWavHueskin,hueskin->getHistoryString()); + } + else if(a==hueskin2) { + listener->panelChanged (EvWavHueskin2,hueskin2->getHistoryString()); + } + else if(a==hllev) { + listener->panelChanged (EvWavlhl,hllev->getHistoryString()); + } + else if(a==bllev) { + listener->panelChanged (EvWavlbl,bllev->getHistoryString()); + } + else if(a==pastlev) { + listener->panelChanged (EvWavpast,pastlev->getHistoryString()); + } + else if(a==satlev) { + listener->panelChanged (EvWavsat,satlev->getHistoryString()); + } + else if(a==edgcont) { + listener->panelChanged (EvWavedgcont,edgcont->getHistoryString()); + } + + } +} +void Wavelet::HSmethodChanged() { + if (!batchMode) { + if(HSmethod->get_active_row_number()==0) {//without + hllev->hide(); + bllev->hide(); + threshold->hide(); + threshold2->hide(); + } + else {//with + hllev->show(); + bllev->show(); + threshold->show(); + threshold2->show(); + } + } + + if (listener && (multiImage||getEnabled()) ) { + listener->panelChanged (EvWavHSmet, HSmethod->get_active_text ()); + } +} + +void Wavelet::CHmethodChanged() { + if (!batchMode) { + if(CHmethod->get_active_row_number()==0) { + CHSLmethod->show(); + pastlev->hide(); + satlev->hide(); + chroma->hide(); + chro->hide(); + labmC->show(); + separatorNeutral->hide(); + neutralchButton->show(); + int y=thres->getValue(); + int z; + for(z=y;z<9;z++) correctionch[z]->hide(); + for(z=0;zshow(); + } else if(CHmethod->get_active_row_number()==1) { + CHSLmethod->show(); + pastlev->show(); + satlev->show(); + chroma->show(); + chro->hide(); + labmC->show(); + separatorNeutral->show(); + neutralchButton->show(); + int y=thres->getValue(); + int z; + for(z=y;z<9;z++) correctionch[z]->hide(); + for(z=0;zshow(); + } else { + chro->show(); + pastlev->hide(); + satlev->hide(); + chroma->hide(); + CHSLmethod->hide(); + labmC->hide(); + separatorNeutral->hide(); + neutralchButton->hide(); + for (int i = 0; i < 9; i++) { + correctionch[i]->hide(); + } + } + } + + if (listener && (multiImage||getEnabled()) ) { + listener->panelChanged (EvWavCHmet, CHmethod->get_active_text ()); + } +} + +void Wavelet::CHSLmethodChanged() { + /* + if (!batchMode) { + if(CHSLmethod->get_active_row_number()==0 && CHmethod->get_active_row_number() != 2) {//SL + //CLVcurveEditorG->hide(); + neutralchButton->show(); + int y=thres->getValue(); + int z; + for(z=y;z<9;z++) correctionch[z]->hide(); + for(z=0;zshow(); + } + else if(CHSLmethod->get_active_row_number()==1) {//CU + //CLVcurveEditorG->show(); + neutralchButton->hide(); + for (int i = 0; i < 9; i++) { + correctionch[i]->hide(); + } + } + } + + if (listener && (multiImage||enabled->get_active()) ) { + listener->panelChanged (EvWavCHSLmet, CHSLmethod->get_active_text ()); + } + */ +} + +void Wavelet::EDmethodChanged() { + if (!batchMode) { + if(EDmethod->get_active_row_number()==0 ) {//SL + CCWcurveEditorG->hide(); + edgcont->show(); + } + else if(EDmethod->get_active_row_number()==1) {//CU + CCWcurveEditorG->show(); + edgcont->hide(); + } + } + if (listener && (multiImage||getEnabled()) ) { + listener->panelChanged (EvWavEDmet, EDmethod->get_active_text ()); + } +} + +void Wavelet::BAmethodChanged() { + if (!batchMode) { + if(BAmethod->get_active_row_number()==0 ) {//none + balance->hide(); + opacityCurveEditorW->hide(); + iter->hide(); + + } + else if(BAmethod->get_active_row_number()==1) {//sli + opacityCurveEditorW->hide(); + balance->show(); + iter->show(); + } + + else if(BAmethod->get_active_row_number()==2) {//CU + opacityCurveEditorW->show(); + balance->hide(); + iter->show(); + + } + + } + if (listener && (multiImage||getEnabled()) ) { + listener->panelChanged (EvWavBAmet, BAmethod->get_active_text ()); + } +} + + +void Wavelet::TMmethodChanged() { + if (!batchMode) { + /* + if(TMmethod->get_active_row_number()==0 ) {// + tmr->hide(); + } + else { + tmr->show(); + } + */ + } + if (listener && (multiImage||getEnabled()) ) { + listener->panelChanged (EvWavTMmet, TMmethod->get_active_text ()); + } +} + +void Wavelet::BackmethodChanged() { + if (!batchMode) { + } + if (listener && (multiImage||getEnabled()) ) { + listener->panelChanged (EvWavBackmet, Backmethod->get_active_text ()); + } +} + + + +void Wavelet::CLmethodChanged() { + if (!batchMode) { + } + if (listener && (multiImage||getEnabled()) ) { + listener->panelChanged (EvWavCLmet, CLmethod->get_active_text ()); + } + if (CLmethod->get_active_row_number()==0) { + CLmethod->set_active (0); + Lmethod->set_sensitive(true); + Dirmethod->set_sensitive(true); + } + else if (CLmethod->get_active_row_number()==1) { + CLmethod->set_active (1); + Lmethod->set_sensitive(true); + Dirmethod->set_sensitive(true); + } + else if (CLmethod->get_active_row_number()==2) { + CLmethod->set_active (2); + Lmethod->set_sensitive(true); + Dirmethod->set_sensitive(true); + } + else if (CLmethod->get_active_row_number()==3) { + CLmethod->set_active (3); + Lmethod->set_sensitive(false); + Dirmethod->set_sensitive(false); + } +} + +void Wavelet::TilesmethodChanged() { + if (!batchMode) { + } + if (listener && (multiImage||getEnabled()) ) { + listener->panelChanged (EvWavTilesmet, Tilesmethod->get_active_text ()); + } +} + +void Wavelet::daubcoeffmethodChanged() { + if (!batchMode) { + } + if (listener && (multiImage||getEnabled()) ) { + listener->panelChanged (EvWavdaubcoeffmet, daubcoeffmethod->get_active_text ()); + } +} + +void Wavelet::MedgreinfChanged() { + if (!batchMode) { + } + if (listener && (multiImage||getEnabled()) ) { + listener->panelChanged (EvWavedgreinf, Medgreinf->get_active_text ()); + } +} + +void Wavelet::DirmethodChanged() { + if (!batchMode) { + } + if (listener && (multiImage||getEnabled()) ) { + listener->panelChanged (EvWavDirmeto, Dirmethod->get_active_text ()); + } +} + +void Wavelet::LmethodChanged() { + if (!batchMode) { + } + if (listener && (multiImage||getEnabled()) ) { + listener->panelChanged (EvWavLmet, Lmethod->get_active_text ()); + } +} + +void Wavelet::setBatchMode (bool batchMode) { + Lmethod->append_text (M("GENERAL_UNCHANGED")); + CLmethod->append_text (M("GENERAL_UNCHANGED")); + Backmethod->append_text (M("GENERAL_UNCHANGED")); + Tilesmethod->append_text (M("GENERAL_UNCHANGED")); + daubcoeffmethod->append_text (M("GENERAL_UNCHANGED")); + CHmethod->append_text (M("GENERAL_UNCHANGED")); + Medgreinf->append_text (M("GENERAL_UNCHANGED")); + CHSLmethod->append_text (M("GENERAL_UNCHANGED")); + EDmethod->append_text (M("GENERAL_UNCHANGED")); + BAmethod->append_text (M("GENERAL_UNCHANGED")); + TMmethod->append_text (M("GENERAL_UNCHANGED")); + HSmethod->append_text (M("GENERAL_UNCHANGED")); + Dirmethod->append_text (M("GENERAL_UNCHANGED")); + CCWcurveEditorG->setBatchMode (batchMode); + opaCurveEditorG->setBatchMode (batchMode); + opacityCurveEditorG->setBatchMode (batchMode); + opacityCurveEditorW->setBatchMode (batchMode); + opacityCurveEditorWL->setBatchMode (batchMode); + curveEditorRES->setBatchMode (batchMode); + curveEditorGAM->setBatchMode (batchMode); + rescon->showEditedCB (); + resconH->showEditedCB (); + reschro->showEditedCB (); + tmrs->showEditedCB (); + gamma->showEditedCB (); + sup->showEditedCB (); + sky->showEditedCB (); + thres->showEditedCB (); + threshold->showEditedCB (); + threshold2->showEditedCB (); + edgedetect->showEditedCB (); + edgedetectthr->showEditedCB (); + edgedetectthr2->showEditedCB (); + chroma->showEditedCB (); + chro->showEditedCB (); + contrast->showEditedCB (); + edgrad->showEditedCB (); + edgval->showEditedCB (); + edgthresh->showEditedCB (); + thr->showEditedCB (); + thrH->showEditedCB (); + skinprotect->showEditedCB(); + hueskin->showEditedCB (); + hueskin2->showEditedCB (); + hllev->showEditedCB (); + bllev->showEditedCB (); + pastlev->showEditedCB (); + satlev->showEditedCB (); + edgcont->showEditedCB (); + strength->showEditedCB (); + balance->showEditedCB (); + iter->showEditedCB (); + level0noise->showEditedCB (); + level1noise->showEditedCB (); + level2noise->showEditedCB (); + + ToolPanel::setBatchMode (batchMode); + + for (int i = 0; i < 9; i++) { + correction[i]->showEditedCB(); + } + for (int i = 0; i < 9; i++) { + correctionch[i]->showEditedCB(); + } +} + +void Wavelet::adjusterChanged (Adjuster* a, double newval) { + if (listener && getEnabled()) { + if (a == edgthresh) { + listener->panelChanged (EvWavtiles, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(0), edgthresh->getValue())) + ); + } + else if (a == rescon ) { + listener->panelChanged (EvWavrescon, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(0), rescon->getValue())) + ); + } + else if (a == resconH ) { + listener->panelChanged (EvWavresconH, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(0), resconH->getValue())) + ); + } + + else if (a == reschro ) { + listener->panelChanged (EvWavreschro, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(0), reschro->getValue())) + ); + } + else if (a == tmrs ) { + float tm; + /* + tm=tmrs->getValue(); + if(tm==0.f) tmr->hide(); + else tmr->show(); + */ + listener->panelChanged (EvWavtmrs, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(0), tmrs->getValue())) + ); + } + else if (a == gamma ) { + float tm; + /* + tm=tmrs->getValue(); + if(tm==0.f) tmr->hide(); + else tmr->show(); + */ + listener->panelChanged (EvWavgamma, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(0), gamma->getValue())) + ); + } + + else if (a == sky ) { + listener->panelChanged (EvWavsky, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(2), sky->getValue())) + ); + } + else if (a == sup ) { + listener->panelChanged (EvWavsup, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(0), sup->getValue())) + ); + } + + else if (a == chroma ) { + listener->panelChanged (EvWavchroma, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(0), chroma->getValue())) + ); + } + else if (a == chro ) { + listener->panelChanged (EvWavchro, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(0), chro->getValue())) + ); + } + else if (a == contrast ) { + listener->panelChanged (EvWavunif, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(0), contrast->getValue())) + ); + } + else if (a == thr ) { + listener->panelChanged (EvWavthr, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(0), thr->getValue())) + ); + } + else if (a == thrH ) { + listener->panelChanged (EvWavthrH, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(0), thrH->getValue())) + ); + } + else if (a == threshold ) { + listener->panelChanged (EvWavThreshold, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(0), threshold->getValue())) + ); + } + else if (a == threshold2 ) { + listener->panelChanged (EvWavThreshold2, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(0), threshold2->getValue())) + ); + } + else if (a == edgedetect ) { + listener->panelChanged (EvWavedgedetect, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(0), edgedetect->getValue())) + ); + } + else if (a == edgedetectthr ) { + listener->panelChanged (EvWavedgedetectthr, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(0), edgedetectthr->getValue())) + ); + } + else if (a == edgedetectthr2 ) { + listener->panelChanged (EvWavedgedetectthr2, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(0), edgedetectthr2->getValue())) + ); + } + + else if (a == edgrad ) { + listener->panelChanged (EvWavedgrad, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(0), edgrad->getValue())) + ); + } + else if (a == edgval ) { + listener->panelChanged (EvWavedgval, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(0), edgval->getValue())) + ); + } + + else if (a == thres ) { + int y; + y=thres->getValue(); + int z; + for(z=y;z<9;z++) correction[z]->hide(); + for(z=0;zshow(); + for(z=y;z<9;z++) correctionch[z]->hide(); + for(z=0;zshow(); + if(z==9) sup->show(); else sup->hide(); + + listener->panelChanged (EvWavthres, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(0), thres->getValue())) + ); + } + else if (a == skinprotect) { + listener->panelChanged (EvWavSkin, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(2), skinprotect->getValue())) + ); + } + + else if (a == strength) { + listener->panelChanged (EvWavStrength, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(2), strength->getValue())) + ); + } + else if (a == balance) { + listener->panelChanged (EvWavbalance, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(2), balance->getValue())) + ); + } + else if (a == iter) { + listener->panelChanged (EvWaviter, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(2), iter->getValue())) + ); + } + else if (a == greenhigh ) { + listener->panelChanged (EvWavgreenhigh, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(0), greenhigh->getValue())) + ); + } + else if (a == bluehigh ) { + listener->panelChanged (EvWavbluehigh, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(0), bluehigh->getValue())) + ); + } + else if (a == greenmed ) { + listener->panelChanged (EvWavgreenmed, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(0), greenmed->getValue())) + ); + } + else if (a == bluemed ) { + listener->panelChanged (EvWavbluemed, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(0), bluemed->getValue())) + ); + } + else if (a == greenlow ) { + listener->panelChanged (EvWavgreenlow, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(0), greenlow->getValue())) + ); + } + else if (a == bluelow ) { + listener->panelChanged (EvWavbluelow, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(0), bluelow->getValue())) + ); + } + + else if (a == correction[0] || a == correction[1] || a == correction[2] || a == correction[3] || a == correction[4] || a == correction[5] || a == correction[6] || a == correction[7] || a == correction[8] ) { + listener->panelChanged (EvWavelet, + Glib::ustring::compose("%1, %2, %3, %4, %5, %6, %7, %8, %9", + Glib::ustring::format(std::fixed, std::setprecision(0), correction[0]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correction[1]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correction[2]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correction[3]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correction[4]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correction[5]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correction[6]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correction[7]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correction[8]->getValue())) + ); + } + else if (a == correctionch[0] || a == correctionch[1] || a == correctionch[2] || a == correctionch[3] || a == correctionch[4] || a == correctionch[5] || a == correctionch[6] || a == correctionch[7] || a == correctionch[8] ) { + listener->panelChanged (EvWaveletch, + Glib::ustring::compose("%1, %2, %3, %4, %5, %6, %7, %8, %9", + Glib::ustring::format(std::fixed, std::setprecision(0), correctionch[0]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correctionch[1]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correctionch[2]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correctionch[3]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correctionch[4]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correctionch[5]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correctionch[6]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correctionch[7]->getValue()), + Glib::ustring::format(std::fixed, std::setprecision(0), correctionch[8]->getValue())) + ); + } + } +} + +void Wavelet::enabledChanged () { + if (!batchMode) { + int y=thres->getValue(); + int z; + for(z=y;z<9;z++) correction[z]->hide(); + for(z=0;zshow(); + if(z==9) sup->show(); else sup->hide(); + + float tm; + /* tm=tmrs->getValue(); + if(tm==0.f) tmr->hide(); + else tmr->show(); + */ + + } + if (listener) { + if (get_inconsistent()) + listener->panelChanged (EvWavEnabled, M("GENERAL_UNCHANGED")); + else if (getEnabled()) + listener->panelChanged (EvWavEnabled, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvWavEnabled, M("GENERAL_DISABLED")); + } +} + +void Wavelet::medianToggled () { + + if (batchMode) { + if (median->get_inconsistent()) { + median->set_inconsistent (false); + medianConn.block (true); + median->set_active (false); + medianConn.block (false); + } + else if (lastmedian) + median->set_inconsistent (true); + + lastmedian = median->get_active (); + } + + if (listener && getEnabled()) { + if (median->get_active ()) + {listener->panelChanged (EvWavmedian, M("GENERAL_ENABLED")); + + } + else { + listener->panelChanged (EvWavmedian, M("GENERAL_DISABLED")); + + } + } +} + +void Wavelet::medianlevToggled () { + + if (batchMode) { + if (medianlev->get_inconsistent()) { + medianlev->set_inconsistent (false); + medianlevConn.block (true); + medianlev->set_active (false); + medianlevConn.block (false); + } + else if (lastmedianlev) + medianlev->set_inconsistent (true); + + lastmedianlev = medianlev->get_active (); + } + if (medianlev->get_active ()){ + edgedetect->show(); + //lipst->show(); + edgedetectthr->show(); + edgedetectthr2->show(); + // if (lipst->get_active ()) edgedetectthr2->show(); + // else edgedetectthr2->hide(); + } + else { + edgedetect->hide(); + //lipst->hide(); + edgedetectthr->hide(); + edgedetectthr2->hide(); + } + + + if (listener && getEnabled()) { + if (medianlev->get_active () ){ + + listener->panelChanged (EvWavmedianlev, M("GENERAL_ENABLED")); + } + else { + + listener->panelChanged (EvWavmedianlev, M("GENERAL_DISABLED")); + } + } +} + +void Wavelet::linkedgToggled () { + + if (batchMode) { + if (linkedg->get_inconsistent()) { + linkedg->set_inconsistent (false); + linkedgConn.block (true); + linkedg->set_active (false); + linkedgConn.block (false); + } + else if (lastlinkedg) + linkedg->set_inconsistent (true); + + lastlinkedg = linkedg->get_active (); + } + + + if (listener && getEnabled()) { + if (linkedg->get_active () ){ + + listener->panelChanged (EvWavlinkedg, M("GENERAL_ENABLED")); + } + else { + + listener->panelChanged (EvWavlinkedg, M("GENERAL_DISABLED")); + } + } +} + +void Wavelet::cbenabToggled () { + if(cbenab->get_active ()) { + chanMixerHLFrame->show(); + chanMixerMidFrame->show(); + chanMixerShadowsFrame->show(); + neutrHBox->show(); + } + else { + chanMixerHLFrame->hide(); + chanMixerMidFrame->hide(); + chanMixerShadowsFrame->hide(); + neutrHBox->hide(); + } + + if (batchMode) { + if (cbenab->get_inconsistent()) { + cbenab->set_inconsistent (false); + cbenabConn.block (true); + cbenab->set_active (false); + cbenabConn.block (false); + } + else if (lastcbenab) + cbenab->set_inconsistent (true); + + lastcbenab = cbenab->get_active (); + } + + + if (listener && getEnabled()) { + if (cbenab->get_active () ){ + + listener->panelChanged (EvWavcbenab, M("GENERAL_ENABLED")); + } + else { + + listener->panelChanged (EvWavcbenab, M("GENERAL_DISABLED")); + } + } + +} + + +void Wavelet::lipstToggled () { + + if (batchMode) { + if (lipst->get_inconsistent()) { + lipst->set_inconsistent (false); + lipstConn.block (true); + lipst->set_active (false); + lipstConn.block (false); + } + else if (lastlipst) + lipst->set_inconsistent (true); + + lastlipst = lipst->get_active (); + } +/* + if (lipst->get_active ()){ + edgedetectthr2->show(); + } + else { + edgedetectthr2->hide(); + } +*/ + if (listener && getEnabled()) { + if (lipst->get_active ()){ + + listener->panelChanged (EvWavlipst, M("GENERAL_ENABLED")); + } + else { + + listener->panelChanged (EvWavlipst, M("GENERAL_DISABLED")); + } + } +} + +/* +void Wavelet::edgreinfToggled () { + + if (batchMode) { + if (edgreinf->get_inconsistent()) { + edgreinf->set_inconsistent (false); + edgreinfConn.block (true); + edgreinf->set_active (false); + edgreinfConn.block (false); + } + else if (lastedgreinf) + edgreinf->set_inconsistent (true); + + lastedgreinf = edgreinf->get_active (); + } + + if (listener) { + if (enabled->get_active ()) + listener->panelChanged (EvWavedgreinf, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvWavedgreinf, M("GENERAL_DISABLED")); + } +} +*/ +void Wavelet::avoidToggled () { + + if (batchMode) { + if (avoid->get_inconsistent()) { + avoid->set_inconsistent (false); + avoidConn.block (true); + avoid->set_active (false); + avoidConn.block (false); + } + else if (lastavoid) + avoid->set_inconsistent (true); + + lastavoid = avoid->get_active (); + } + if (listener && getEnabled ()) { + if (avoid->get_active ()) + listener->panelChanged (EvWavavoid, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvWavavoid, M("GENERAL_DISABLED")); + } +} + +void Wavelet::tmrToggled () { + + if (batchMode) { + if (tmr->get_inconsistent()) { + tmr->set_inconsistent (false); + tmrConn.block (true); + tmr->set_active (false); + tmrConn.block (false); + } + else if (lasttmr) + tmr->set_inconsistent (true); + + lasttmr = tmr->get_active (); + } + if (listener && getEnabled ()) { + if (tmr->get_active ()) + listener->panelChanged (EvWavtmr, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvWavtmr, M("GENERAL_DISABLED")); + } +} + + +void Wavelet::colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller *caller) { + + float R, G, B; + + if (elemType==ColorCaller::CCET_VERTICAL_BAR) + valY = 0.5; + + if (callerId == 1) { // ch - main curve + + Color::hsv2rgb01(float(valX), float(valY), 0.5f, R, G, B); + } +/* else if (callerId == 2) { // cc - bottom bar + + // float value = (1.f - 0.7f) * float(valX) + 0.7f; + float value = (1.f - 0.7f) * float(valX) + 0.7f; + // whole hue range + // Y axis / from 0.15 up to 0.75 (arbitrary values; was 0.45 before) + Color::hsv2rgb01(float(valY), float(valX), value, R, G, B); + } + */ + else if (callerId == 4) { // LH - bottom bar + Color::hsv2rgb01(float(valX), 0.5f, float(valY), R, G, B); + } + else if (callerId == 5) { // HH - bottom bar + float h = float((valY - 0.5) * 0.3 + valX); + if (h > 1.0f) + h -= 1.0f; + else if (h < 0.0f) + h += 1.0f; + Color::hsv2rgb01(h, 0.5f, 0.5f, R, G, B); + } + caller->ccRed = double(R); + caller->ccGreen = double(G); + caller->ccBlue = double(B); +} +void Wavelet::setAdjusterBehavior (bool multiplieradd, bool thresholdadd, bool threshold2add, bool thresadd, bool chroadd,bool chromaadd, bool contrastadd, bool skinadd, bool reschroadd, bool tmrsadd, bool resconadd, bool resconHadd, bool thradd, bool thrHadd, bool skyadd, bool edgradadd, bool edgvaladd, bool strengthadd, bool gammaadd, bool edgedetectadd, bool edgedetectthradd ,bool edgedetectthr2add) { + + for (int i=0; i<9; i++) + correction[i]->setAddMode(multiplieradd); + threshold->setAddMode(thresholdadd); + skinprotect->setAddMode(skinadd); + threshold2->setAddMode(threshold2add); + thres->setAddMode(thresadd); + chro->setAddMode(chroadd); + chroma->setAddMode(chromaadd); + contrast->setAddMode(contrastadd); + rescon->setAddMode(resconadd); + resconH->setAddMode(resconHadd); + reschro->setAddMode(reschroadd); + tmrs->setAddMode(tmrsadd); + thr->setAddMode(thradd); + thrH->setAddMode(thrHadd); + sky->setAddMode(skyadd); + edgrad->setAddMode(edgradadd); + edgval->setAddMode(edgvaladd); + strength->setAddMode(strengthadd); + gamma->setAddMode(gammaadd); + edgedetect->setAddMode(edgedetectadd); + edgedetectthr->setAddMode(edgedetectthradd); + edgedetectthr2->setAddMode(edgedetectthr2add); +} + + +void Wavelet::neutralPressed () { + + for (int i = 0; i < 9; i++) { + correction[i]->setValue(0); + adjusterChanged(correction[i], 0); + } +} + +void Wavelet::neutralchPressed () { + + for (int i = 0; i < 9; i++) { + correctionch[i]->setValue(0); + adjusterChanged(correctionch[i], 0); + } +} + + +void Wavelet::contrastPlusPressed () { + + for (int i = 0; i < 9; i++) { + int inc = 1 * (9 - i); + correction[i]->setValue(correction[i]->getValue() + inc); + adjusterChanged(correction[i], correction[i]->getValue()); + } +} + + +void Wavelet::contrastMinusPressed () { + + for (int i = 0; i < 9; i++) { + int inc = -1 * (9 - i); + correction[i]->setValue(correction[i]->getValue() + inc); + adjusterChanged(correction[i], correction[i]->getValue()); + } +} + +void Wavelet::foldAllButSettings (GdkEventButton* event) { + if (event->button == 3) { + foldAllButOne(expsettings); + } +} + +void Wavelet::foldAllButContrast (GdkEventButton* event) { + if (event->button == 3) { + foldAllButOne(expcontrast); + } +} + +void Wavelet::foldAllButChroma (GdkEventButton* event) { + if (event->button == 3) { + foldAllButOne(expchroma); + } +} + +void Wavelet::foldAllButToning (GdkEventButton* event) { + if (event->button == 3) { + foldAllButOne(exptoning); + } +} + +void Wavelet::foldAllButNoise (GdkEventButton* event) { + if (event->button == 3) { + foldAllButOne(expnoise); + } +} + +void Wavelet::foldAllButEdge (GdkEventButton* event) { + if (event->button == 3) { + foldAllButOne(expedge); + } +} + +void Wavelet::foldAllButGamut (GdkEventButton* event) { + if (event->button == 3) { + foldAllButOne(expgamut); + } +} + +void Wavelet::foldAllButResid (GdkEventButton* event) { + if (event->button == 3) { + foldAllButOne(expresid); + } +} + +void Wavelet::foldAllButFinal (GdkEventButton* event) { + if (event->button == 3) { + foldAllButOne(expfinal); + } +} + +void Wavelet::foldAllButOne (MyExpander * whichOne) { + expsettings->set_expanded(expsettings == whichOne); + expcontrast->set_expanded(expcontrast == whichOne); + expchroma->set_expanded(expchroma == whichOne); + exptoning->set_expanded(exptoning == whichOne); + expnoise->set_expanded(expnoise == whichOne); + expedge->set_expanded(expedge == whichOne); + expgamut->set_expanded(expgamut == whichOne); + expresid->set_expanded(expresid == whichOne); + expfinal->set_expanded(expfinal == whichOne); +} + +void Wavelet::writeOptions(std::vector &tpOpen) { + tpOpen.push_back (expsettings->get_expanded ()); + tpOpen.push_back (expcontrast->get_expanded ()); + tpOpen.push_back (expchroma->get_expanded ()); + tpOpen.push_back (exptoning->get_expanded ()); + tpOpen.push_back (expnoise->get_expanded ()); + tpOpen.push_back (expedge->get_expanded ()); + tpOpen.push_back (expgamut->get_expanded ()); + tpOpen.push_back (expresid->get_expanded ()); + tpOpen.push_back (expfinal->get_expanded ()); +} + +void Wavelet::updateToolState(std::vector &tpOpen) { + if(tpOpen.size() == 9) { + expsettings->set_expanded(tpOpen.at(0)); + expcontrast->set_expanded(tpOpen.at(1)); + expchroma->set_expanded(tpOpen.at(2)); + exptoning->set_expanded(tpOpen.at(3)); + expnoise->set_expanded(tpOpen.at(4)); + expedge->set_expanded(tpOpen.at(5)); + expgamut->set_expanded(tpOpen.at(6)); + expresid->set_expanded(tpOpen.at(7)); + expfinal->set_expanded(tpOpen.at(8)); + } +} + diff --git a/rtgui/wavelet.h b/rtgui/wavelet.h new file mode 100644 index 000000000..28f4ef05c --- /dev/null +++ b/rtgui/wavelet.h @@ -0,0 +1,288 @@ +/* + * This file is part of RawTherapee. + * + * 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 . + * + * 2014 Jacques Desmis + */ + +#ifndef WAVELET_H_INCLUDED +#define WAVELET_H_INCLUDED + +#include +#include "adjuster.h" +#include "toolpanel.h" +#include "curveeditor.h" +#include "curveeditorgroup.h" +#include "thresholdadjuster.h" +#include "colorprovider.h" +#include "guiutils.h" +#include "options.h" + +class Wavelet : public ToolParamBlock, public ThresholdAdjusterListener, public AdjusterListener, public CurveListener, public ColorProvider, public rtengine::WaveletListener, public FoldableToolPanel +{ +protected: + Glib::RefPtr bgTTips; + Glib::RefPtr srTTips; + Glib::RefPtr bgPixbuf; + Glib::RefPtr srPixbuf; + CurveEditorGroup* curveEditorG; + + CurveEditorGroup* CCWcurveEditorG; + CurveEditorGroup* curveEditorRES; + CurveEditorGroup* curveEditorGAM; + Gtk::HSeparator* colorSep; + Gtk::HSeparator* separator3; + Gtk::HSeparator* separatorCB; + Gtk::HSeparator* separatorNeutral; + + CurveEditorGroup* opaCurveEditorG; + FlatCurveEditor* opacityShapeRG; + CurveEditorGroup* opacityCurveEditorG; + FlatCurveEditor* opacityShapeBY; + CurveEditorGroup* opacityCurveEditorW; + CurveEditorGroup* opacityCurveEditorWL; + FlatCurveEditor* opacityShape; + FlatCurveEditor* opacityShapeWL; + FlatCurveEditor* hhshape; + FlatCurveEditor* Chshape; + DiagonalCurveEditor* clshape; + Gtk::VBox* chanMixerBox; + + FlatCurveEditor* ccshape; + Gtk::CheckButton * display; + Gtk::CheckButton * displaylevel; + Gtk::CheckButton * displaychro; + Gtk::CheckButton * displaygam; + Gtk::CheckButton * displayres; + Gtk::CheckButton * median; + Gtk::CheckButton * medianlev; + Gtk::CheckButton * linkedg; + Gtk::CheckButton * cbenab; + Gtk::CheckButton * lipst; + Gtk::CheckButton * avoid; + Gtk::CheckButton * tmr; + + Gtk::Button * neutralchButton; + + Adjuster* correction[9]; + Adjuster* correctionch[9]; + Adjuster* rescon; + Adjuster* resconH; + Adjuster* reschro; + Adjuster* tmrs; + Adjuster* gamma; + Adjuster* sup; + Adjuster* sky; + Adjuster* thres; + Adjuster* chroma; + Adjuster* chro; + Adjuster* contrast; + Adjuster* thr; + Adjuster* thrH; + Adjuster* skinprotect; + Adjuster* edgrad; + Adjuster* edgval; + Adjuster* edgthresh; + Adjuster* strength; + Adjuster* balance; + Adjuster* iter; + Adjuster* greenlow; + Adjuster* bluelow; + Adjuster* greenmed; + Adjuster* bluemed; + Adjuster* greenhigh; + Adjuster* bluehigh; + + ThresholdAdjuster* hueskin; + ThresholdAdjuster* hueskin2; + ThresholdAdjuster* hllev; + ThresholdAdjuster* bllev; + ThresholdAdjuster* pastlev; + ThresholdAdjuster* satlev; + ThresholdAdjuster* edgcont; + ThresholdAdjuster* level0noise; + ThresholdAdjuster* level1noise; + ThresholdAdjuster* level2noise; + + Adjuster* threshold; + Adjuster* threshold2; + Adjuster* edgedetect; + Adjuster* edgedetectthr; + Adjuster* edgedetectthr2; + MyComboBoxText* Lmethod; + sigc::connection Lmethodconn; + MyComboBoxText* CHmethod; + sigc::connection CHmethodconn; + MyComboBoxText* CHSLmethod; + sigc::connection CHSLmethodconn; + MyComboBoxText* EDmethod; + sigc::connection EDmethodconn; + MyComboBoxText* BAmethod; + sigc::connection BAmethodconn; + MyComboBoxText* TMmethod; + sigc::connection TMmethodconn; + MyComboBoxText* HSmethod; + sigc::connection HSmethodconn; + MyComboBoxText* CLmethod; + sigc::connection CLmethodconn; + MyComboBoxText* Backmethod; + sigc::connection Backmethodconn; + MyComboBoxText* Tilesmethod; + sigc::connection Tilesmethodconn; + MyComboBoxText* daubcoeffmethod; + sigc::connection daubcoeffmethodconn; + MyComboBoxText* Dirmethod; + sigc::connection Dirmethodconn; + MyComboBoxText* Medgreinf; + sigc::connection MedgreinfConn; + Gtk::Frame* settingsFrame; + Gtk::Frame* toningFrame; + Gtk::Frame* residualFrame; + Gtk::Frame* dispFrame; + Gtk::Frame* levelFrame; + Gtk::Frame* chromaFrame; + Gtk::Frame* controlFrame; + Gtk::Frame* edgeFrame; + Gtk::Frame* noiseFrame; + Gtk::Frame* contrastSHFrame; + Gtk::Frame* finalFrame; + Gtk::Frame *chanMixerHLFrame; + Gtk::Frame *chanMixerMidFrame; + Gtk::Frame *chanMixerShadowsFrame; + Gtk::Frame *dFrame; + + Gtk::Label* colLabel; + Gtk::Label* interLabel; + Gtk::Label* wavLabels; + Gtk::Label* hsmethodLabel; + Gtk::Label* daubcoeffLabel; + Gtk::Label* ColorBalanceLabel; + Gtk::Label* labmC; + Gtk::Label* labmch; + Gtk::Label* labmED; + Gtk::Label* labmTM; + Gtk::Label* labmBA; + Gtk::Label* labmedgr; + Gtk::Label* labmednois; + MyExpander* expchroma; + MyExpander* expcontrast; + MyExpander* expedge; + MyExpander* expfinal; + MyExpander* expgamut; + MyExpander* expnoise; + MyExpander* expresid; + MyExpander* expsettings; + MyExpander* exptoning; + Gtk::HBox* ctboxCB; + Gtk::HBox* ctboxCH; + Gtk::HBox* ctboxED; + Gtk::HBox* ctboxTM; + Gtk::HBox* hbresid; + Gtk::HBox* backgroundHBox; + Gtk::HBox* daubcoeffHBox; + Gtk::HBox* hsmethodHBox; + Gtk::HBox* levdirMainHBox; + Gtk::HBox* levdirSubHBox; + Gtk::HBox* tilesizeHBox; + + Gtk::HBox* ctboxBA; + Gtk::HBox* ctboxch; + Gtk::HBox* edbox; + Gtk::HBox* ednoisbox; + Gtk::HBox* eddebox; + Gtk::VBox* settingsVBox; + Gtk::VBox* contrastSHVBox; + Gtk::Label* tilesizeLabel; + Gtk::Label* levdirMainLabel; + Gtk::Label* backgroundLabel; + Gtk::Button* neutral; + Gtk::HBox* neutrHBox; + + sigc::connection expConn, medianConn, avoidConn, tmrConn, medianlevConn, linkedgConn, lipstConn, cbenabConn, neutralconn; + sigc::connection neutralPressedConn; + sigc::connection contrastPlusPressedConn; + sigc::connection contrastMinusPressedConn; + sigc::connection neutralchPressedConn; + + bool lastdisplay, lastdisplaygam,lastdisplayres,lastdisplaychro, lastdisplaylevel,lastmedian, lastmedianlev, lastlinkedg, lastavoid, lastlipst, lasttmr, lastcbenab; + int nextnlevel; + double tr; + double br; + double tl; + double bl; + +public: + Wavelet (); + virtual ~Wavelet (); + + bool wavComputed_ (); + void adjusterChanged (ThresholdAdjuster* a, double newBottom, double newTop); + void adjusterChanged (Adjuster* a, double newval); + void adjusterChanged2 (ThresholdAdjuster* a, int newBottomL, int newTopL, int newBottomR, int newTopR); + void autoOpenCurve (); + void curveChanged (CurveEditor* ce); + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void setAdjusterBehavior (bool multiplieradd, bool thresholdadd, bool threshold2add, bool thresadd, bool chroadd,bool chromaadd, bool contrastadd, bool skinadd, bool reschroadd, bool tmrsadd, bool resconadd, bool resconHadd, bool thradd, bool thrHadd, bool skyadd, bool edgradadd, bool edgvaladd, bool strengthadd, bool gammaadd, bool edgedetectadd, bool edgedetectthradd, bool edgedetectthr2add); + void setBatchMode (bool batchMode); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setEditProvider (EditDataProvider *provider); + void updateToolState(std::vector &tpOpen); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void writeOptions(std::vector &tpOpen); + +private: + void foldAllButSettings (GdkEventButton* event); + void foldAllButContrast (GdkEventButton* event); + void foldAllButChroma (GdkEventButton* event); + void foldAllButToning (GdkEventButton* event); + void foldAllButNoise (GdkEventButton* event); + void foldAllButEdge (GdkEventButton* event); + void foldAllButGamut (GdkEventButton* event); + void foldAllButResid (GdkEventButton* event); + void foldAllButFinal (GdkEventButton* event); + void foldAllButOne (MyExpander * whichOne); + + virtual void colorForValue (double valX, double valY, enum ColorCaller::ElemType elemType, int callerId, ColorCaller* caller); + void BAmethodChanged (); + void BackmethodChanged (); + void CHSLmethodChanged (); + void CHmethodChanged (); + void CLmethodChanged (); + void DirmethodChanged (); + void EDmethodChanged (); + void HSmethodChanged (); + void LmethodChanged (); + void MedgreinfChanged (); + void TMmethodChanged (); + void TilesmethodChanged (); + void avoidToggled (); + void cbenabToggled (); + void contrastMinusPressed (); + void contrastPlusPressed (); + void daubcoeffmethodChanged (); + void enabledChanged (); + void linkedgToggled (); + void lipstToggled (); + void medianToggled (); + void medianlevToggled (); + void neutralPressed (); + void neutral_pressed (); + void neutralchPressed (); + void tmrToggled (); + void updatewavLabel (); + void wavChanged (double nlevel); +}; + +#endif diff --git a/rtgui/wbprovider.h b/rtgui/wbprovider.h new file mode 100644 index 000000000..e92013c2b --- /dev/null +++ b/rtgui/wbprovider.h @@ -0,0 +1,32 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _WBPROVIDER_ +#define _WBPROVIDER_ + + +class WBProvider { + + public: + virtual ~WBProvider() {} + virtual void getAutoWB (double& temp, double& green, double equal) {} + virtual void getCamWB (double& temp, double& green) {} + virtual void spotWBRequested (int size) {} +}; + +#endif diff --git a/rtgui/whitebalance.cc b/rtgui/whitebalance.cc new file mode 100755 index 000000000..e15caa38f --- /dev/null +++ b/rtgui/whitebalance.cc @@ -0,0 +1,726 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "whitebalance.h" +#include +#include "rtimage.h" +#include "options.h" +#include "../rtengine/safegtk.h" + +#define MINTEMP 1500 //1200 +#define MAXTEMP 60000 //12000 +#define CENTERTEMP 4750 +#define MINGREEN 0.02 +#define MAXGREEN 5.0 +#define MINEQUAL 0.8 +#define MAXEQUAL 1.5 + +using namespace rtengine; +using namespace rtengine::procparams; + +Glib::RefPtr WhiteBalance::wbPixbufs[rtengine::procparams::WBT_CUSTOM+1]; +/* +Glib::RefPtr WhiteBalance::wbCameraPB, WhiteBalance::wbAutoPB, WhiteBalance::wbSunPB, WhiteBalance::wbTungstenPB, + WhiteBalance::wbCloudyPB, WhiteBalance::wbShadePB, WhiteBalance::wbFluorescentPB, WhiteBalance::wbLampPB, + WhiteBalance::wbFlashPB, WhiteBalance::wbLedPB, WhiteBalance::wbCustomPB; +*/ + +void WhiteBalance::init () { + wbPixbufs[WBT_CAMERA] = safe_create_from_file("wb-camera.png"); + wbPixbufs[WBT_AUTO] = safe_create_from_file("wb-auto.png"); + wbPixbufs[WBT_DAYLIGHT] = safe_create_from_file("wb-sun.png"); + wbPixbufs[WBT_CLOUDY] = safe_create_from_file("wb-cloudy.png"); + wbPixbufs[WBT_SHADE] = safe_create_from_file("wb-shade.png"); + wbPixbufs[WBT_WATER] = safe_create_from_file("wb-water.png"); +// wbPixbufs[WBT_WATER2] = safe_create_from_file("wb-water.png"); + wbPixbufs[WBT_TUNGSTEN] = safe_create_from_file("wb-tungsten.png"); + wbPixbufs[WBT_FLUORESCENT] = safe_create_from_file("wb-fluorescent.png"); + wbPixbufs[WBT_LAMP] = safe_create_from_file("wb-lamp.png"); + wbPixbufs[WBT_FLASH] = safe_create_from_file("wb-flash.png"); + wbPixbufs[WBT_LED] = safe_create_from_file("wb-led.png"); + wbPixbufs[WBT_CUSTOM] = safe_create_from_file("wb-custom.png"); +} + +void WhiteBalance::cleanup () { + for (unsigned int i=0; i MAXTEMP) temp = MAXTEMP; + return temp; +} + +static double wbTemp2Slider(double temp) { + + double sval; + if (temp <= CENTERTEMP) { + sval = ((temp - MINTEMP) / (CENTERTEMP - MINTEMP)) * 5000.0; + } else { + const double slope = (double)(CENTERTEMP - MINTEMP) / (MAXTEMP - CENTERTEMP); + const double y = (temp - CENTERTEMP) / (MAXTEMP - CENTERTEMP); + double x = pow(y, 0.25); // rough guess of x, will be a little lower + double y1; + double k = 0.1; + bool add = true; + // the y=f(x) function is a mess to invert, therefore we have this trial-refinement loop instead. + // from tests, worst case is about 20 iterations, ie no problem + for (;;) { + y1 = x * slope + (1.0 - slope)*pow(x, 4.0); + if (5000 * fabs(y1 - y) < 0.1) break; + if (y1 < y) { + if (!add) k /= 2; + x += k; + add = true; + } else { + if (add) k /= 2; + x -= k; + add = false; + } + } + sval = 5000.0 + x * 5000.0; + } + if (sval < 0) sval = 0; + if (sval > 10000) sval = 10000; + return sval; +} + +WhiteBalance::WhiteBalance () : FoldableToolPanel(this, "whitebalance", M("TP_WBALANCE_LABEL")), wbp(NULL), wblistener(NULL) { + + Gtk::HBox* hbox = Gtk::manage (new Gtk::HBox ()); + hbox->show (); + Gtk::Label* lab = Gtk::manage (new Gtk::Label (M("TP_WBALANCE_METHOD"))); + lab->show (); + + // Create the Tree model + refTreeModel = Gtk::TreeStore::create(methodColumns); + // Create the Combobox + method = Gtk::manage (new MyComboBox ()); + // Assign the model to the Combobox + method->set_model(refTreeModel); + + enum WBTypes oldType = WBParams::wbEntries[0]->type; + enum WBTypes currType; + Gtk::TreeModel::Row row, childrow; + for (unsigned int i=0; itype)) { + // New entry type + if (currType == WBT_FLUORESCENT) { + // Creating the Fluorescent subcategory header + row = *(refTreeModel->append()); + row[methodColumns.colIcon] = wbPixbufs[currType]; + row[methodColumns.colLabel] = M("TP_WBALANCE_FLUO_HEADER"); + row[methodColumns.colId] = i+100; + } + if (currType == WBT_WATER) { + // Creating the under water subcategory header + row = *(refTreeModel->append()); + row[methodColumns.colIcon] = wbPixbufs[currType]; + row[methodColumns.colLabel] = M("TP_WBALANCE_WATER_HEADER"); + row[methodColumns.colId] = i+100; + } + if (currType == WBT_LAMP) { + // Creating the Lamp subcategory header + row = *(refTreeModel->append()); + row[methodColumns.colIcon] = wbPixbufs[currType]; + row[methodColumns.colLabel] = M("TP_WBALANCE_LAMP_HEADER"); + row[methodColumns.colId] = i+100; + } + if (currType == WBT_LED) { + // Creating the LED subcategory header + row = *(refTreeModel->append()); + row[methodColumns.colIcon] = wbPixbufs[currType]; + row[methodColumns.colLabel] = M("TP_WBALANCE_LED_HEADER"); + row[methodColumns.colId] = i+100; + } + if (currType == WBT_FLASH) { + // Creating the Flash subcategory header + row = *(refTreeModel->append()); + row[methodColumns.colIcon] = wbPixbufs[currType]; + row[methodColumns.colLabel] = M("TP_WBALANCE_FLASH_HEADER"); + row[methodColumns.colId] = i+100; + } + } + if (currType == WBT_FLUORESCENT + || currType == WBT_LAMP + || currType == WBT_WATER + || currType == WBT_FLASH + || currType == WBT_LED + ) { + childrow = *(refTreeModel->append(row.children())); + childrow[methodColumns.colIcon] = wbPixbufs[currType]; + childrow[methodColumns.colLabel] = WBParams::wbEntries[i]->GUILabel; + childrow[methodColumns.colId] = i; + } + else { + row = *(refTreeModel->append()); + row[methodColumns.colIcon] = wbPixbufs[currType]; + row[methodColumns.colLabel] = WBParams::wbEntries[i]->GUILabel; + row[methodColumns.colId] = i; + } + oldType = currType; + + custom_green = 1.0; + custom_equal = 1.0; + } + + //Add the model columns to the Combo (which is a kind of view), + //rendering them in the default way: + method->pack_start(methodColumns.colIcon, false); + method->pack_start(methodColumns.colLabel, true); + + method->set_active (0); // Camera + method->show (); + hbox->pack_start (*lab, Gtk::PACK_SHRINK, 4); + hbox->pack_start (*method); + pack_start (*hbox, Gtk::PACK_SHRINK, 4); + opt = 0; + + Gtk::HBox* spotbox = Gtk::manage (new Gtk::HBox ()); + spotbox->show (); + + spotbutton = Gtk::manage (new Gtk::Button (M("TP_WBALANCE_SPOTWB"))); + Gtk::Image* spotimg = Gtk::manage (new RTImage ("gtk-color-picker-small.png")); + spotimg->show (); + spotbutton->set_image (*spotimg); + spotbutton->show (); + + spotbox->pack_start (*spotbutton); + + Gtk::Label* slab = Gtk::manage (new Gtk::Label (M("TP_WBALANCE_SIZE"))); + slab->show (); + + spotsize = Gtk::manage (new MyComboBoxText ()); + spotsize->show (); + spotsize->append_text ("2"); if (options.whiteBalanceSpotSize==2) spotsize->set_active(0); + spotsize->append_text ("4"); if (options.whiteBalanceSpotSize==4) spotsize->set_active(1); + spotsize->append_text ("8"); if (options.whiteBalanceSpotSize==8) spotsize->set_active(2); + spotsize->append_text ("16"); if (options.whiteBalanceSpotSize==16) spotsize->set_active(3); + spotsize->append_text ("32"); if (options.whiteBalanceSpotSize==32) spotsize->set_active(4); + + spotbox->pack_end (*spotsize, Gtk::PACK_EXPAND_WIDGET, 4); + spotbox->pack_end (*slab, Gtk::PACK_SHRINK, 4); + + pack_start (*spotbox, Gtk::PACK_SHRINK, 4); + + Gtk::Image* itempL = Gtk::manage (new RTImage ("ajd-wb-temp1.png")); + Gtk::Image* itempR = Gtk::manage (new RTImage ("ajd-wb-temp2.png")); + Gtk::Image* igreenL = Gtk::manage (new RTImage ("ajd-wb-green1.png")); + Gtk::Image* igreenR = Gtk::manage (new RTImage ("ajd-wb-green2.png")); + Gtk::Image* iblueredL = Gtk::manage (new RTImage ("ajd-wb-bluered1.png")); + Gtk::Image* iblueredR = Gtk::manage (new RTImage ("ajd-wb-bluered2.png")); + + temp = Gtk::manage (new Adjuster (M("TP_WBALANCE_TEMPERATURE"), MINTEMP, MAXTEMP, 5, CENTERTEMP, itempL, itempR, &wbSlider2Temp, &wbTemp2Slider)); + green = Gtk::manage (new Adjuster (M("TP_WBALANCE_GREEN"), MINGREEN, MAXGREEN, 0.001, 1.0, igreenL, igreenR)); + equal = Gtk::manage (new Adjuster (M("TP_WBALANCE_EQBLUERED"), MINEQUAL, MAXEQUAL, 0.001, 1.0, iblueredL, iblueredR)); + cache_customTemp (0); + cache_customGreen (0); + cache_customEqual (0); + equal->set_tooltip_markup (M("TP_WBALANCE_EQBLUERED_TOOLTIP")); + temp->show (); + green->show (); + equal->show (); + + /* Gtk::HBox* boxgreen = Gtk::manage (new Gtk::HBox ()); + boxgreen->show (); + + boxgreen->pack_start(*igreenL); + boxgreen->pack_start(*green); + boxgreen->pack_start(*igreenR);*/ + + pack_start (*temp); + //pack_start (*boxgreen); + pack_start (*green); + pack_start (*equal); + + temp->setAdjusterListener (this); + green->setAdjusterListener (this); + equal->setAdjusterListener (this); + + spotbutton->signal_pressed().connect( sigc::mem_fun(*this, &WhiteBalance::spotPressed) ); + methconn = method->signal_changed().connect( sigc::mem_fun(*this, &WhiteBalance::optChanged) ); + spotsize->signal_changed().connect( sigc::mem_fun(*this, &WhiteBalance::spotSizeChanged) ); +} + +void WhiteBalance::adjusterChanged (Adjuster* a, double newval) { + + int tVal = (int)temp->getValue(); + double gVal = green->getValue(); + double eVal = equal->getValue(); + Gtk::TreeModel::Row row = getActiveMethod(); + if (row == refTreeModel->children().end()) return; + + Glib::ustring colLabel = row[methodColumns.colLabel]; + WBEntry* ppMethod = findWBEntry (row[methodColumns.colLabel], WBLT_GUI); + WBEntry* wbCustom = findWBEntry ("Custom", WBLT_PP); + + if (!ppMethod || (ppMethod->ppLabel!=wbCustom->ppLabel && !(a==equal && ppMethod->type==WBT_AUTO)) ) { + methconn.block(true); + opt = setActiveMethod(wbCustom->GUILabel); + cache_customWB (tVal, gVal); + cache_customEqual(eVal); + methconn.block(false); + } + + //cache custom WB setting to allow its recall + if (a==temp) + cache_customTemp (tVal); + else if (a==green) + cache_customGreen (gVal); + else if (a==equal) { + cache_customEqual (eVal); + // Recomputing AutoWB if it's the current method + if (wbp && ppMethod->type==WBT_AUTO) { + double ctemp=-1.0; double cgreen=-1.0; + wbp->getAutoWB (ctemp, cgreen, eVal); + + if (ctemp != -1.0) { + // Set the automatics temperature value only if in SET mode + if (temp->getEditedState() && !temp->getAddMode() ) temp->setValue (ctemp); + // Set the automatics green value only if in SET mode + if (green->getEditedState() && !green->getAddMode()) green->setValue (cgreen); + } + } + } + + if (listener) { + if (a==temp) + listener->panelChanged (EvWBTemp, Glib::ustring::format ((int)a->getValue())); + else if (a==green) + listener->panelChanged (EvWBGreen, Glib::ustring::format (std::setw(4), std::fixed, std::setprecision(3), a->getValue())); + else if (a==equal) + listener->panelChanged (EvWBequal, Glib::ustring::format (std::setw(4), std::fixed, std::setprecision(3), a->getValue())); + } +} + +void WhiteBalance::optChanged () { + + Gtk::TreeModel::Row row = getActiveMethod(); + if (row == refTreeModel->children().end()) return; + if (row[methodColumns.colId] >= 100) { + // "Header" solutions are trapped ; the combo is then set to the previous value + bool prevState = methconn.block(true); + method->set_active(opt); + methconn.block(prevState); + return; + } + + if (opt != row[methodColumns.colId]) { + + opt = row[methodColumns.colId]; + + if (row[methodColumns.colLabel] == M("GENERAL_UNCHANGED")) { + temp->setEditedState (UnEdited); + green->setEditedState (UnEdited); + equal->setEditedState (UnEdited); + } + else { + int methodId = findWBEntryId (row[methodColumns.colLabel], WBLT_GUI); + WBEntry* currMethod = WBParams::wbEntries[methodId]; + + switch (currMethod->type) { + case WBT_CAMERA: + if (wbp) { + double ctemp, cgreen; + wbp->getCamWB (ctemp, cgreen); + temp->setValue (temp->getAddMode() ? 0.0 : (int)ctemp); + green->setValue (green->getAddMode() ? 0.0 : cgreen); + equal->setValue (equal->getAddMode() ? 0.0 : 1.0); + if (batchMode) { + temp->setEditedState (UnEdited); + green->setEditedState (UnEdited); + equal->setEditedState (UnEdited); + } + } + break; + case WBT_AUTO: + if (wbp) { + if (batchMode) { + temp->setEditedState (UnEdited); + green->setEditedState (UnEdited); + // equal remain as is + } + if (!batchMode || equal->getEditedState()) { + double ctemp, cgreen; + wbp->getAutoWB (ctemp, cgreen, equal->getValue()); + if (ctemp != -1.0) { + temp->setValue (temp->getAddMode() ? 0.0 : (int)ctemp); + green->setValue (green->getAddMode() ? 0.0 : cgreen); + } + } + } + break; + case WBT_CUSTOM: + if (custom_temp>0){ + temp->setValue (temp->getAddMode() ? 0.0 : custom_temp); + green->setValue (green->getAddMode() ? 0.0 : custom_green); + equal->setValue (equal->getAddMode() ? 0.0 : custom_equal); + } else { + cache_customTemp (temp->getValue()); + cache_customGreen (green->getValue()); + cache_customEqual (equal->getValue()); + } + if (batchMode) { + temp->setEditedState (Edited); + green->setEditedState (Edited); + equal->setEditedState (Edited); + } + break; + /* All other solution are the default cases + case WBT_DAYLIGHT: + case WBT_CLOUDY: + case WBT_SHADE: + case WBT_TUNGSTEN: + case WBT_FLUORESCENT: + case WBT_LAMP: + case WBT_FLASH: + case WBT_LED:*/ + default: + // recall custom WB settings if it exists, set to 1.0 otherwise + temp->setValue ( temp->getAddMode() ? 0.0 : (double)(currMethod->temperature)); + green->setValue (green->getAddMode() ? 0.0 : (double)(currMethod->green)); + equal->setValue (equal->getAddMode() ? 0.0 : (double)(currMethod->equal)); + if (batchMode) { + temp->setEditedState (Edited); + green->setEditedState (Edited); + equal->setEditedState (Edited); + } + break; + } + } + + if (listener) + listener->panelChanged (EvWBMethod, row[methodColumns.colLabel]); + } +} + +void WhiteBalance::spotPressed () { + + if (wblistener) + wblistener->spotWBRequested (getSize()); +} + +void WhiteBalance::spotSizeChanged () { + options.whiteBalanceSpotSize=getSize(); + + if (wblistener) + wblistener->spotWBRequested (getSize()); +} + +void WhiteBalance::read (const ProcParams* pp, const ParamsEdited* pedited) { + disableListener (); + + methconn.block (true); + equal->setValue (pp->wb.equal); + + if (pedited) { + // By default, temperature and green are said "UnEdited", but it may change later + temp->setEditedState (UnEdited); + green->setEditedState (UnEdited); + equal->setEditedState (pedited->wb.equal ? Edited : UnEdited); + } + + if (pedited && !pedited->wb.method) { + opt = setActiveMethod(M("GENERAL_UNCHANGED")); + } + else { + WBEntry* wbValues = findWBEntry(pp->wb.method, WBLT_PP); + if (!wbValues) + wbValues = findWBEntry("Camera", WBLT_PP); + + opt = setActiveMethod(wbValues->GUILabel); + + // temperature is reset to the associated temperature, or 0.0 if addMode is set. + switch (wbValues->type) { + case WBT_CUSTOM: + temp->setValue (temp->getAddMode() ? 0.0 : pp->wb.temperature); + green->setValue (green->getAddMode() ? 0.0 : pp->wb.green); + equal->setValue (equal->getAddMode() ? 0.0 : pp->wb.equal); + cache_customTemp (pp->wb.temperature); + cache_customGreen (pp->wb.green); + cache_customEqual (pp->wb.equal); + if (pedited) { + // The user may have changed the temperature and green value + temp->setEditedState (pedited->wb.temperature ? Edited : UnEdited); + green->setEditedState (pedited->wb.green ? Edited : UnEdited); + } + break; + case WBT_CAMERA: + if (wbp) { + double ctemp = -1.0; double cgreen = -1.0; + wbp->getCamWB (ctemp, cgreen); + + if (ctemp != -1.0) { + // Set the camera's temperature value, or 0.0 if in ADD mode + temp->setValue (temp->getAddMode() ? 0.0 : ctemp); + // Set the camera's green value, or 0.0 if in ADD mode + green->setValue (green->getAddMode() ? 0.0 : cgreen); + equal->setValue (equal->getAddMode() ? 0.0 : 1.); + } else { + temp->setValue (temp->getAddMode() ? 0.0 : pp->wb.temperature); + green->setValue (green->getAddMode() ? 0.0 : pp->wb.green); + equal->setValue (equal->getAddMode() ? 0.0 : pp->wb.equal); + } + } + break; + case WBT_AUTO: + // the equalizer's value is restored for the AutoWB + equal->setValue (equal->getAddMode() ? 0.0 : pp->wb.equal); + + // set default values first if in ADD mode, otherwise keep the current ones + if (temp->getAddMode() ) temp->setValue (0.0); + if (green->getAddMode()) green->setValue (0.0); + + // then check for the correct ones, if possible + if (wbp) { + double ctemp=-1.0; double cgreen=-1.0; + wbp->getAutoWB (ctemp, cgreen, pp->wb.equal); + + if (ctemp != -1.0) { + // Set the automatics temperature if in SET mode + if (!pedited || (pedited->wb.temperature && !temp->getAddMode()) ) { + temp->setValue (ctemp); + if (pedited) temp->setEditedState (Edited); + } + // Set the automatics green value if in SET mode + if (!pedited || (pedited->wb.green && !green->getAddMode())) { + green->setValue (cgreen); + if (pedited) green->setEditedState (Edited); + } + } + } + break; + /* + All those types are the "default" case: + case WBT_DAYLIGHT: + case WBT_CLOUDY: + case WBT_SHADE: + case WBT_TUNGSTEN: + case WBT_FLUORESCENT: + case WBT_LAMP: + case WBT_FLASH: + case WBT_LED: + */ + default: + // Set the associated temperature, or 0.0 if in ADD mode + temp->setValue(temp->getAddMode() ? 0.0 : (double)wbValues->temperature); + // Set the stored temperature, or 0.0 if in ADD mode + green->setValue(green->getAddMode() ? 0.0 : pp->wb.green); + equal->setValue(equal->getAddMode() ? 0.0 : pp->wb.equal); + + // The user may have changed the green value even for predefined WB values + if (pedited) { + green->setEditedState (pedited->wb.green ? Edited : UnEdited); + equal->setEditedState (pedited->wb.equal ? Edited : UnEdited); + } + //cache_customGreen (pp->wb.green); + break; + } + } + methconn.block (false); + enableListener (); +} + +void WhiteBalance::write (ProcParams* pp, ParamsEdited* pedited) { + + Gtk::TreeModel::Row row = getActiveMethod(); + + if (pedited) { + pedited->wb.temperature = temp->getEditedState (); + pedited->wb.green = green->getEditedState (); + pedited->wb.equal = equal->getEditedState (); + pedited->wb.method = row[methodColumns.colLabel]!=M("GENERAL_UNCHANGED"); + } + + WBEntry* ppMethod = findWBEntry (row[methodColumns.colLabel], WBLT_GUI); + + if (ppMethod) + pp->wb.method = ppMethod->ppLabel; + pp->wb.temperature = temp->getIntValue (); + pp->wb.green = green->getValue (); + pp->wb.equal = equal->getValue (); +} + +void WhiteBalance::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + equal->setDefault (defParams->wb.equal); + + if (wbp && defParams->wb.method == "Camera") { + double ctemp; double cgreen; + wbp->getCamWB (ctemp, cgreen); + // FIXME: Seems to be always -1.0, called too early? Broken! + if (ctemp != -1.0) { + temp->setDefault (temp->getAddMode() ? 0 : (int)ctemp); + green->setDefault (green->getAddMode() ? 0 : cgreen); + } + } + else if (wbp && defParams->wb.method == "Auto") { + // this setDefaults method is called too early ; the wbp has been set, + // but wbp is not ready to provide! + double ctemp; double cgreen; + wbp->getAutoWB (ctemp, cgreen, defParams->wb.equal); + if (ctemp != -1.0) { + temp->setDefault (temp->getAddMode() ? 0 : (int)ctemp); + green->setDefault (green->getAddMode() ? 0 : cgreen); + } + else { + // 6504 & 1.0 = same values as in ProcParams::setDefaults + temp->setDefault (temp->getAddMode() ? 0 : 6504); + green->setDefault (green->getAddMode() ? 0 : 1.0); + } + } + else { + temp->setDefault (defParams->wb.temperature); + green->setDefault (defParams->wb.green); + } + if (pedited) { + temp->setDefaultEditedState (pedited->wb.temperature ? Edited : UnEdited); + green->setDefaultEditedState (pedited->wb.green ? Edited : UnEdited); + equal->setDefaultEditedState (pedited->wb.equal ? Edited : UnEdited); + } + else { + temp->setDefaultEditedState (Irrelevant); + green->setDefaultEditedState (Irrelevant); + equal->setDefaultEditedState (Irrelevant); + } +} + +void WhiteBalance::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + temp->showEditedCB (); + green->showEditedCB (); + equal->showEditedCB (); + Gtk::TreeModel::Row row = *(refTreeModel->append()); + row[methodColumns.colId] = WBParams::wbEntries.size(); + row[methodColumns.colLabel] = M("GENERAL_UNCHANGED"); + +} + +int WhiteBalance::getSize () { + + return atoi(spotsize->get_active_text().c_str()); +} + +void WhiteBalance::setWB (int vtemp, double vgreen) { + + methconn.block(true); + WBEntry *wbValues = findWBEntry("Custom", WBLT_PP); + temp->setValue (vtemp); + green->setValue (vgreen); + opt = setActiveMethod(wbValues->GUILabel); + cache_customWB (vtemp,vgreen); // sequence in which this call is made is important; must be before "method->set_active (2);" + cache_customEqual(equal->getValue()); + temp->setEditedState (Edited); + green->setEditedState (Edited); + methconn.block(false); + + if (listener) + listener->panelChanged (EvWBTemp, Glib::ustring::compose("%1, %2", (int)temp->getValue(), Glib::ustring::format (std::setw(4), std::fixed, std::setprecision(3), green->getValue()))); +} + +void WhiteBalance::setAdjusterBehavior (bool tempadd, bool greenadd, bool equaladd) { + + temp->setAddMode(tempadd); + green->setAddMode(greenadd); + equal->setAddMode(equaladd); +} + +void WhiteBalance::trimValues (rtengine::procparams::ProcParams* pp) { + + temp->trimValue(pp->wb.temperature); + green->trimValue(pp->wb.green); + equal->trimValue(pp->wb.equal); +} + +inline void WhiteBalance::cache_customTemp(int temp) { + custom_temp = temp; +} + +void WhiteBalance::cache_customGreen(double green) { + custom_green = green; +} +void WhiteBalance::cache_customEqual(double equal) { + custom_equal = equal; +} + +void WhiteBalance::cache_customWB(int temp, double green) { + cache_customTemp (temp); + cache_customGreen (green); +} + +int WhiteBalance::findWBEntryId (Glib::ustring label, enum WB_LabelType lblType) { + for (unsigned int i=0; iGUILabel : WBParams::wbEntries[i]->ppLabel)) + return i; + } + return -1; +} + +WBEntry* WhiteBalance::findWBEntry (Glib::ustring label, enum WB_LabelType lblType) { + for (unsigned int i=0; iGUILabel : WBParams::wbEntries[i]->ppLabel)) + return WBParams::wbEntries[i]; + } + return NULL; +} + +int WhiteBalance::_setActiveMethod(Glib::ustring &label, Gtk::TreeModel::Children &children) { + int found = -1; + for(Gtk::TreeModel::Children::iterator iter = children.begin(); iter != children.end() && found==-1; ++iter) { + Gtk::TreeModel::Row row = *iter; + if (row[methodColumns.colLabel] == label) { + method->set_active(iter); + found = method->get_active_row_number(); + } + if (found !=-1) + return found; + + Gtk::TreeModel::Children childs = row.children(); + if (childs.size()) { + found = _setActiveMethod(label, childs); + if (found !=-1) + return found; + } + } + // Entry not found + return -1; +} + +int WhiteBalance::setActiveMethod(Glib::ustring label) { + Gtk::TreeModel::Children children = refTreeModel->children(); + return _setActiveMethod(label, children); +} + +inline Gtk::TreeRow WhiteBalance::getActiveMethod () { + return *(method->get_active()); +} diff --git a/rtgui/whitebalance.h b/rtgui/whitebalance.h new file mode 100644 index 000000000..39ad5ffe2 --- /dev/null +++ b/rtgui/whitebalance.h @@ -0,0 +1,107 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _WB_H_ +#define _WB_H_ + +#include +#include "toolpanel.h" +#include "adjuster.h" +#include "guiutils.h" +#include "wbprovider.h" +#include "../rtengine/procparams.h" + +class SpotWBListener { + + public: + virtual void spotWBRequested (int size) {} +}; + +class WhiteBalance : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel { + + enum WB_LabelType { + WBLT_GUI, + WBLT_PP + }; + + protected: + class MethodColumns : public Gtk::TreeModel::ColumnRecord { + public: + Gtk::TreeModelColumn< Glib::RefPtr > colIcon; + Gtk::TreeModelColumn colLabel; + Gtk::TreeModelColumn colId; + MethodColumns() { add(colIcon); add(colLabel); add(colId); } + }; + + static Glib::RefPtr wbPixbufs[rtengine::procparams::WBT_CUSTOM+1]; + Glib::RefPtr refTreeModel; + MethodColumns methodColumns; + MyComboBox* method; + MyComboBoxText* spotsize; + Adjuster* temp; + Adjuster* green; + Adjuster* equal; + + Gtk::Button* spotbutton; + int opt; + double nextTemp; + double nextGreen; + WBProvider *wbp; // pointer to a ToolPanelCoordinator object, or its subclass BatchToolPanelCoordinator + SpotWBListener* wblistener; + sigc::connection methconn; + int custom_temp; + double custom_green; + double custom_equal; + void cache_customWB (int temp, double green); //cache custom WB setting to allow its recall + void cache_customTemp (int temp); //cache Temperature only to allow its recall + void cache_customGreen (double green); //cache Green only to allow its recall + void cache_customEqual (double equal); //cache Equal only to allow its recall + + int setActiveMethod (Glib::ustring label); + int _setActiveMethod (Glib::ustring &label, Gtk::TreeModel::Children &children); + + Gtk::TreeModel::Row getActiveMethod (); + int findWBEntryId (Glib::ustring label, enum WB_LabelType lblType=WBLT_GUI); + rtengine::procparams::WBEntry* findWBEntry (Glib::ustring label, enum WB_LabelType lblType=WBLT_GUI); + + public: + + WhiteBalance (); + ~WhiteBalance () {}; + + static void init (); + static void cleanup (); + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + + void optChanged (); + void spotPressed (); + void spotSizeChanged (); + void adjusterChanged (Adjuster* a, double newval); + int getSize (); + void setWBProvider (WBProvider* p) { wbp = p; } + void setSpotWBListener (SpotWBListener* l) { wblistener = l; } + void setWB (int temp, double green); + + void setAdjusterBehavior (bool tempadd, bool greenadd, bool equaladd); + void trimValues (rtengine::procparams::ProcParams* pp); +}; + +#endif diff --git a/rtgui/windirmonitor.cc b/rtgui/windirmonitor.cc new file mode 100644 index 000000000..66dbefd3b --- /dev/null +++ b/rtgui/windirmonitor.cc @@ -0,0 +1,101 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "windirmonitor.h" +#include "options.h" + +static void CALLBACK current_directory_monitor_callback (DWORD error, DWORD nBytes, LPOVERLAPPED lpOverlapped) { + DWORD dwOffset = 0; + FILE_NOTIFY_INFORMATION* pInfo = NULL; + + WinDirMonitor::MonitorData* monData = (WinDirMonitor::MonitorData*)lpOverlapped; + if (!nBytes) { + delete monData; + return; + } + + bool notify = false; + // Analysis of the modifications. Let only parsed file extensions emit a notify, not PP3 changes + do { + // Get a pointer to the first change record... + pInfo = (FILE_NOTIFY_INFORMATION*) &monData->file_notify_buffer[dwOffset]; + + char fnameC[(MAX_PATH+1)*2] = {0}; + int strLen = WideCharToMultiByte(CP_UTF8,0,pInfo->FileName,pInfo->FileNameLength/sizeof(WCHAR),fnameC,sizeof(fnameC),0,0); + fnameC[strLen] = 0; + Glib::ustring fname = fnameC; + + if (options.has_retained_extention(fname)) + notify = true; + + // More than one change may happen at the same time. Load the next change and continue... + dwOffset += pInfo->NextEntryOffset; + } while (!notify && pInfo->NextEntryOffset != 0); + + // ReadDirectoryChangesW sometimes emits multiple events per change (one for each change type) + // To make sure it's not flooding update, this gets filtered. + DWORD curTick = GetTickCount(); + if (notify && monData->listener && (curTick-monData->lastTimeUpdateTick)>500) { + monData->lastTimeUpdateTick = curTick; + monData->listener->winDirChanged (); + } + + ReadDirectoryChangesW (monData->hDirectory, + monData->file_notify_buffer, + monData->buffer_allocated_bytes, + FALSE, + FILE_NOTIFY_CHANGE_FILE_NAME | + FILE_NOTIFY_CHANGE_DIR_NAME | + FILE_NOTIFY_CHANGE_LAST_WRITE, + &monData->buffer_filled_bytes, + &monData->overlapped, + current_directory_monitor_callback); +} + +WinDirMonitor::WinDirMonitor (Glib::ustring dirName, WinDirChangeListener* listener) : monData(NULL) { + wchar_t* wdirname = (wchar_t*)g_utf8_to_utf16 (dirName.c_str(), -1, NULL, NULL, NULL); + HANDLE hDirectory = CreateFileW (wdirname, FILE_LIST_DIRECTORY,FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, NULL); + g_free (wdirname); + + if (hDirectory != INVALID_HANDLE_VALUE) { + + monData = new MonitorData (); + monData->listener = listener; + monData->buffer_allocated_bytes = 32768; + monData->file_notify_buffer = new char [monData->buffer_allocated_bytes]; + monData->hDirectory = hDirectory; + monData->lastTimeUpdateTick = GetTickCount(); + + ReadDirectoryChangesW (monData->hDirectory, + monData->file_notify_buffer, + monData->buffer_allocated_bytes, + FALSE, + FILE_NOTIFY_CHANGE_FILE_NAME | + FILE_NOTIFY_CHANGE_DIR_NAME | + FILE_NOTIFY_CHANGE_LAST_WRITE, + &monData->buffer_filled_bytes, + &monData->overlapped, + current_directory_monitor_callback); + } +} + +WinDirMonitor::~WinDirMonitor () { + + if (monData && monData->hDirectory != INVALID_HANDLE_VALUE) + CloseHandle (monData->hDirectory); +} diff --git a/rtgui/windirmonitor.h b/rtgui/windirmonitor.h new file mode 100644 index 000000000..ddef88135 --- /dev/null +++ b/rtgui/windirmonitor.h @@ -0,0 +1,54 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _WINDIRMONITOR_ +#define _WINDIRMONITOR_ + +#include +#include + +class WinDirChangeListener { + + public: + virtual void winDirChanged () {} +}; + +class WinDirMonitor : public Glib::Object { + + public: + struct MonitorData { + OVERLAPPED overlapped; + DWORD buffer_allocated_bytes; + char *file_notify_buffer; + DWORD buffer_filled_bytes; + HANDLE hDirectory; + WinDirChangeListener* listener; + int bigyo; + DWORD lastTimeUpdateTick; // for filtering multiple updates events + }; + + private: + MonitorData* monData; + + public: + WinDirMonitor (Glib::ustring dirName, WinDirChangeListener* listener); + ~WinDirMonitor (); +}; + +#endif + diff --git a/rtgui/xtransprocess.cc b/rtgui/xtransprocess.cc new file mode 100644 index 000000000..2cd3a8057 --- /dev/null +++ b/rtgui/xtransprocess.cc @@ -0,0 +1,132 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "xtransprocess.h" +#include "options.h" +#include "guiutils.h" +using namespace rtengine; +using namespace rtengine::procparams; + +XTransProcess::XTransProcess () : FoldableToolPanel(this, "xtransprocess", M("TP_RAW_LABEL"), true) +{ + Gtk::HBox* hb1 = Gtk::manage (new Gtk::HBox ()); + hb1->pack_start (*Gtk::manage (new Gtk::Label ( M("TP_RAW_DMETHOD") +": ")),Gtk::PACK_SHRINK, 4); + method = Gtk::manage (new MyComboBoxText ()); + for( size_t i=0; iappend_text(procparams::RAWParams::XTransSensor::methodstring[i]); + + method->set_active(0); + hb1->set_tooltip_markup (M("TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP")); + + hb1->pack_end (*method, Gtk::PACK_EXPAND_WIDGET, 4); + pack_start( *hb1, Gtk::PACK_SHRINK, 4); + + pack_start( *Gtk::manage( new Gtk::HSeparator()), Gtk::PACK_SHRINK, 0 ); + ccSteps = Gtk::manage (new Adjuster (M("TP_RAW_FALSECOLOR"),0,5,1,0 )); + ccSteps->setAdjusterListener (this); + if (ccSteps->delay < 1000) ccSteps->delay = 1000; + ccSteps->show(); + pack_start( *ccSteps, Gtk::PACK_SHRINK, 4); + + methodconn = method->signal_changed().connect( sigc::mem_fun(*this, &XTransProcess::methodChanged) ); +} + + +void XTransProcess::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited) +{ + disableListener (); + methodconn.block (true); + + method->set_active(procparams::RAWParams::XTransSensor::numMethods); + for( size_t i=0; i< procparams::RAWParams::XTransSensor::numMethods; i++) + if( pp->raw.xtranssensor.method == procparams::RAWParams::XTransSensor::methodstring[i]) { + method->set_active(i); + oldSelection = i; + break; + } + + if(pedited ){ + ccSteps->setEditedState (pedited->raw.xtranssensor.ccSteps ? Edited : UnEdited); + if( !pedited->raw.xtranssensor.method ) + method->set_active(procparams::RAWParams::XTransSensor::numMethods); // No name + } + + ccSteps->setValue (pp->raw.xtranssensor.ccSteps); + + methodconn.block (false); + + enableListener (); +} + +void XTransProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pedited) +{ + pp->raw.xtranssensor.ccSteps = ccSteps->getIntValue(); + + int currentRow = method->get_active_row_number(); + if( currentRow>=0 && currentRow < procparams::RAWParams::XTransSensor::numMethods) + pp->raw.xtranssensor.method = procparams::RAWParams::XTransSensor::methodstring[currentRow]; + + if (pedited) { + pedited->raw.xtranssensor.method = method->get_active_row_number() != procparams::RAWParams::XTransSensor::numMethods; + pedited->raw.xtranssensor.ccSteps = ccSteps->getEditedState (); + } +} + +void XTransProcess::setBatchMode(bool batchMode) +{ + method->append_text (M("GENERAL_UNCHANGED")); + method->set_active(procparams::RAWParams::XTransSensor::numMethods); // No name + ToolPanel::setBatchMode (batchMode); + ccSteps->showEditedCB (); +} + +void XTransProcess::setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited) +{ + ccSteps->setDefault (defParams->raw.xtranssensor.ccSteps); + if (pedited) { + ccSteps->setDefaultEditedState(pedited->raw.xtranssensor.ccSteps ? Edited : UnEdited); + }else{ + ccSteps->setDefaultEditedState(Irrelevant ); + } +} + +void XTransProcess::adjusterChanged (Adjuster* a, double newval) +{ + if (listener) { + if (a == ccSteps) + listener->panelChanged (EvDemosaicFalseColorIter, a->getTextValue() ); + } +} + +void XTransProcess::methodChanged () +{ + int curSelection = method->get_active_row_number(); + + Glib::ustring methodName=""; + bool ppreq = false; + if( curSelection>=0 && curSelection < procparams::RAWParams::XTransSensor::numMethods) { + methodName = procparams::RAWParams::XTransSensor::methodstring[curSelection]; + if (curSelection == procparams::RAWParams::XTransSensor::mono || oldSelection == procparams::RAWParams::XTransSensor::mono) { + ppreq = true; + } + } + oldSelection = curSelection; + + if (listener) + listener->panelChanged (ppreq ? EvDemosaicMethodPreProc : EvDemosaicMethod, methodName); +} diff --git a/rtgui/xtransprocess.h b/rtgui/xtransprocess.h new file mode 100644 index 000000000..ad83ffaad --- /dev/null +++ b/rtgui/xtransprocess.h @@ -0,0 +1,51 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _XTRANSPROCESS_H_ +#define _XTRANSPROCESS_H_ + +#include +#include "adjuster.h" +#include "guiutils.h" +#include "toolpanel.h" + + +class XTransProcess : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel{ + + protected: + + MyComboBoxText* method; + Adjuster* ccSteps; + + int oldSelection; + sigc::connection methodconn; + + public: + + XTransProcess (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + + void methodChanged (); + void adjusterChanged (Adjuster* a, double newval); +}; + +#endif diff --git a/rtgui/xtransrawexposure.cc b/rtgui/xtransrawexposure.cc new file mode 100644 index 000000000..458647ac1 --- /dev/null +++ b/rtgui/xtransrawexposure.cc @@ -0,0 +1,131 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "xtransrawexposure.h" +#include "guiutils.h" +#include "../rtengine/safegtk.h" +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +XTransRAWExposure::XTransRAWExposure () : FoldableToolPanel(this, "xtransrawexposure", M("TP_EXPOS_BLACKPOINT_LABEL")) +{ + PexBlackRed = Gtk::manage(new Adjuster (M("TP_RAWEXPOS_BLACK_RED"),-2048,2048,0.1,0));//black level + PexBlackRed->setAdjusterListener (this); + if (PexBlackRed->delay < 1000) PexBlackRed->delay = 1000; + PexBlackRed->show(); + PexBlackGreen = Gtk::manage(new Adjuster (M("TP_RAWEXPOS_BLACK_GREEN"),-2048,2048,0.1,0));//black level + PexBlackGreen->setAdjusterListener (this); + if (PexBlackGreen->delay < 1000) PexBlackGreen->delay = 1000; + PexBlackGreen->show(); + PexBlackBlue = Gtk::manage(new Adjuster (M("TP_RAWEXPOS_BLACK_BLUE"),-2048,2048,0.1,0));//black level + PexBlackBlue->setAdjusterListener (this); + if (PexBlackBlue->delay < 1000) PexBlackBlue->delay = 1000; + PexBlackBlue->show(); + + pack_start( *PexBlackRed, Gtk::PACK_SHRINK, 0);//black + pack_start( *PexBlackGreen, Gtk::PACK_SHRINK, 0);//black + pack_start( *PexBlackBlue, Gtk::PACK_SHRINK, 0);//black +} + +void XTransRAWExposure::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited) +{ + disableListener (); + + if(pedited ){ + PexBlackRed->setEditedState( pedited->raw.xtranssensor.exBlackRed ? Edited : UnEdited ); + PexBlackGreen->setEditedState( pedited->raw.xtranssensor.exBlackGreen ? Edited : UnEdited ); + PexBlackBlue->setEditedState( pedited->raw.xtranssensor.exBlackBlue ? Edited : UnEdited ); + } + + PexBlackRed->setValue (pp->raw.xtranssensor.blackred);//black + PexBlackGreen->setValue (pp->raw.xtranssensor.blackgreen);//black + PexBlackBlue->setValue (pp->raw.xtranssensor.blackblue);//black + + enableListener (); +} + +void XTransRAWExposure::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pedited) +{ + pp->raw.xtranssensor.blackred = PexBlackRed->getValue();// black + pp->raw.xtranssensor.blackgreen = PexBlackGreen->getValue();// black + pp->raw.xtranssensor.blackblue = PexBlackBlue->getValue();// black + + if (pedited) { + pedited->raw.xtranssensor.exBlackRed = PexBlackRed->getEditedState ();//black + pedited->raw.xtranssensor.exBlackGreen = PexBlackGreen->getEditedState ();//black + pedited->raw.xtranssensor.exBlackBlue = PexBlackBlue->getEditedState ();//black + } + +} + +void XTransRAWExposure::adjusterChanged (Adjuster* a, double newval) +{ + if (listener) { + Glib::ustring value = a->getTextValue(); + if (a == PexBlackRed) + listener->panelChanged (EvPreProcessExpBlackRed, value); + else if (a == PexBlackGreen) + listener->panelChanged (EvPreProcessExpBlackGreen, value); + else if (a == PexBlackBlue) + listener->panelChanged (EvPreProcessExpBlackBlue, value); + } +} + +void XTransRAWExposure::setBatchMode(bool batchMode) +{ + ToolPanel::setBatchMode (batchMode); + PexBlackRed->showEditedCB ();//black + PexBlackGreen->showEditedCB ();//black + PexBlackBlue->showEditedCB ();//black + +} + +void XTransRAWExposure::setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited) +{ + PexBlackRed->setDefault( defParams->raw.xtranssensor.blackred); + PexBlackGreen->setDefault( defParams->raw.xtranssensor.blackgreen); + PexBlackBlue->setDefault( defParams->raw.xtranssensor.blackblue); + + if (pedited) { + PexBlackRed->setDefaultEditedState( pedited->raw.xtranssensor.exBlackRed ? Edited : UnEdited); + PexBlackGreen->setDefaultEditedState( pedited->raw.xtranssensor.exBlackGreen ? Edited : UnEdited); + PexBlackBlue->setDefaultEditedState( pedited->raw.xtranssensor.exBlackBlue ? Edited : UnEdited); + + } else { + PexBlackRed->setDefaultEditedState( Irrelevant ); + PexBlackGreen->setDefaultEditedState( Irrelevant ); + PexBlackBlue->setDefaultEditedState( Irrelevant ); + + } +} + +void XTransRAWExposure::setAdjusterBehavior (bool pexblackadd) { + + PexBlackRed->setAddMode(pexblackadd); + PexBlackGreen->setAddMode(pexblackadd); + PexBlackBlue->setAddMode(pexblackadd); +} + +void XTransRAWExposure::trimValues (rtengine::procparams::ProcParams* pp) { + + PexBlackRed->trimValue(pp->raw.xtranssensor.blackred); + PexBlackGreen->trimValue(pp->raw.xtranssensor.blackgreen); + PexBlackBlue->trimValue(pp->raw.xtranssensor.blackblue); +} diff --git a/rtgui/xtransrawexposure.h b/rtgui/xtransrawexposure.h new file mode 100644 index 000000000..80f803406 --- /dev/null +++ b/rtgui/xtransrawexposure.h @@ -0,0 +1,49 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 . + */ +#ifndef _XTRANSRAWEXPOSURE_H_ +#define _XTRANSRAWEXPOSURE_H_ + +#include +#include "adjuster.h" +#include "toolpanel.h" +#include "../rtengine/rawimage.h" + +class XTransRAWExposure : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel { + +protected: + Adjuster* PexBlackRed; + Adjuster* PexBlackGreen; + Adjuster* PexBlackBlue; + +private: +// Gtk::CheckButton* PextwoGreen; +public: + + XTransRAWExposure (); + + void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL); + void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); + void setBatchMode (bool batchMode); + void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); + void adjusterChanged (Adjuster* a, double newval); + void setAdjusterBehavior (bool pexblackadd); + void trimValues (rtengine::procparams::ProcParams* pp); +}; + +#endif diff --git a/rtgui/zoompanel.cc b/rtgui/zoompanel.cc new file mode 100644 index 000000000..3596cc588 --- /dev/null +++ b/rtgui/zoompanel.cc @@ -0,0 +1,135 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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 "zoompanel.h" +#include "multilangmgr.h" +#include "imagearea.h" +#include "rtimage.h" + +ZoomPanel::ZoomPanel (ImageArea* iarea) : iarea(iarea) { + + set_border_width (0); + + Gtk::Image* imageOut = Gtk::manage (new RTImage ("gtk-zoom-out.png")); + imageOut->set_padding(0,0); + Gtk::Image* imageIn = Gtk::manage (new RTImage ("gtk-zoom-in.png")); + imageIn->set_padding(0,0); + Gtk::Image* image11 =Gtk::manage ( new RTImage ("gtk-zoom-100.png")); + image11->set_padding(0,0); + Gtk::Image* imageFit = Gtk::manage (new RTImage ("gtk-zoom-fit.png")); + imageFit->set_padding(0,0); + Gtk::Image* imageFitCrop = Gtk::manage (new RTImage ("gtk-zoom-crop.png")); + imageFit->set_padding(0,0); + + zoomOut = Gtk::manage (new Gtk::Button()); + zoomOut->add (*imageOut); + zoomOut->set_relief(Gtk::RELIEF_NONE); + zoomIn = Gtk::manage (new Gtk::Button()); + zoomIn->add (*imageIn); + zoomIn->set_relief(Gtk::RELIEF_NONE); + zoomFit = Gtk::manage (new Gtk::Button()); + zoomFit->add (*imageFit); + zoomFit->set_relief(Gtk::RELIEF_NONE); + zoomFitCrop = Gtk::manage (new Gtk::Button()); + zoomFitCrop->add (*imageFitCrop); + zoomFitCrop->set_relief(Gtk::RELIEF_NONE); + zoom11 = Gtk::manage (new Gtk::Button()); + zoom11->add (*image11); + zoom11->set_relief(Gtk::RELIEF_NONE); + + pack_start (*zoomOut, Gtk::PACK_SHRINK, 0); + pack_start (*zoomIn, Gtk::PACK_SHRINK, 0); + pack_start (*zoomFit, Gtk::PACK_SHRINK, 0); + pack_start (*zoomFitCrop, Gtk::PACK_SHRINK, 0); + pack_start (*zoom11, Gtk::PACK_SHRINK, 0); + + zoomLabel = Gtk::manage (new Gtk::Label ()); + pack_start (*zoomLabel, Gtk::PACK_SHRINK, 4); + + Gtk::Image* imageCrop = Gtk::manage (new RTImage ("new-detail-window.png")); + imageCrop->set_padding(0,0); + newCrop = Gtk::manage (new Gtk::Button()); + newCrop->add (*imageCrop); + newCrop->set_relief(Gtk::RELIEF_NONE); + pack_start (*newCrop, Gtk::PACK_SHRINK, 4); + + show_all_children (); + + zoomIn->signal_clicked().connect ( sigc::mem_fun(*this, &ZoomPanel::zoomInClicked) ); + zoomOut->signal_clicked().connect( sigc::mem_fun(*this, &ZoomPanel::zoomOutClicked) ); + zoomFit->signal_clicked().connect( sigc::mem_fun(*this, &ZoomPanel::zoomFitClicked) ); + zoomFitCrop->signal_clicked().connect( sigc::mem_fun(*this, &ZoomPanel::zoomFitCropClicked) ); + zoom11->signal_clicked().connect ( sigc::mem_fun(*this, &ZoomPanel::zoom11Clicked) ); + newCrop->signal_clicked().connect ( sigc::mem_fun(*this, &ZoomPanel::newCropClicked) ); + + zoomIn->set_tooltip_markup (M("ZOOMPANEL_ZOOMIN")); + zoomOut->set_tooltip_markup (M("ZOOMPANEL_ZOOMOUT")); + zoom11->set_tooltip_markup (M("ZOOMPANEL_ZOOM100")); + zoomFit->set_tooltip_markup (M("ZOOMPANEL_ZOOMFITSCREEN")); + zoomFitCrop->set_tooltip_markup (M("ZOOMPANEL_ZOOMFITCROPSCREEN")); + newCrop->set_tooltip_markup (M("ZOOMPANEL_NEWCROPWINDOW")); + + zoomLabel->set_text (M("ZOOMPANEL_100")); +} + +void ZoomPanel::zoomInClicked () { + + if (iarea->mainCropWindow) + iarea->mainCropWindow->zoomIn (); +} + +void ZoomPanel::zoomOutClicked () { + + if (iarea->mainCropWindow) + iarea->mainCropWindow->zoomOut (); +} + +void ZoomPanel::zoomFitClicked () { + + if (iarea->mainCropWindow) + iarea->mainCropWindow->zoomFit (); +} + +void ZoomPanel::zoomFitCropClicked () { + + if (iarea->mainCropWindow) + iarea->mainCropWindow->zoomFitCrop (); +} + +void ZoomPanel::zoom11Clicked () { + + if (iarea->mainCropWindow) + iarea->mainCropWindow->zoom11 (); +} + +void ZoomPanel::refreshZoomLabel () { + + if (iarea->mainCropWindow) { + int z = (int)(iarea->mainCropWindow->getZoom () * 100); + if (z<100) { + zoomLabel->set_text (Glib::ustring::compose(" %1%%", z)); + } else { + zoomLabel->set_text (Glib::ustring::compose("%1%%", z)); + } + } +} + +void ZoomPanel::newCropClicked () { + + iarea->addCropWindow (); +} diff --git a/rtgui/zoompanel.h b/rtgui/zoompanel.h new file mode 100644 index 000000000..cbc46b52b --- /dev/null +++ b/rtgui/zoompanel.h @@ -0,0 +1,52 @@ +/* + * This file is part of RawTherapee. + * + * Copyright (c) 2004-2010 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. + *l + * You should have received a copy of the GNU General Public License + * along with RawTherapee. If not, see . + */ +#ifndef _ZOOMPANEL_ +#define _ZOOMPANEL_ + +#include + +class ImageArea; +class ZoomPanel : public Gtk::HBox { + + protected: + + Gtk::Button* zoomOut; + Gtk::Button* zoomIn; + Gtk::Button* zoomFit; + Gtk::Button* zoomFitCrop; + Gtk::Button* zoom11; + Gtk::Button* newCrop; + Gtk::Label* zoomLabel; + ImageArea* iarea; + + public: + + ZoomPanel (ImageArea* iarea); + + void zoomInClicked (); + void zoomOutClicked (); + void zoomFitClicked (); + void zoomFitCropClicked (); + void zoom11Clicked (); + void newCropClicked (); + void refreshZoomLabel (); +}; + +#endif + diff --git a/tools/RTProfileBuilderSample.cs b/tools/RTProfileBuilderSample.cs new file mode 100644 index 000000000..8bfede8d0 --- /dev/null +++ b/tools/RTProfileBuilderSample.cs @@ -0,0 +1,293 @@ +#region Usings +using System; +using System.Text; +using System.IO; +using System.Globalization; +using System.Diagnostics; +using System.Configuration; +using System.Collections; +using System.Collections.Specialized; +#endregion + +// *** Raw Therapee sample Custom Profile builder (version 2013-08-12) *** +// +// +// WARNING: The command line parameters has changed since this file has been created by Oduis. The new mechanism involves a +// temporary communication file (.ini style) to provide system parameters and metadata read by RawTherapee. This script has +// to be updated by some C# developer in order to work. +// +// +// WARNING: PP3 format may change in the future versions! If this happens there will probably be no automatic migration path, +// you'll have to adjust on your own. This is a sample, and therefore not supported by the RT team (just by oduis) +// +// +// How to use: +// 1. Modify the GetCorrectedSettings function below according to your needs. +// 2. Download and install Microsoft .Net Runtime (latest version is 4.0 as of writing), if it's not already on your machine. +// You can get it for free via Windows Update or from microsoft.com. No need for Visual Studio etc. +// 3. Open a command line and compile this CS-File using the C# 32bit compiler. It is usually installed somewhere here: +// C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe +// Call csc.exe (C#-Compiler) with your .CS file as parameter like this (one big line): +// +// C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc +// /r:C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.dll +// /r:C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Configuration.dll +// RTProfileBuilderSample.cs +// +// (On most machines it already works with "C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc RTProfileBuilderSample.cs") +// CSC will compile it and emit an EXE. +// 4. Open your RT options files and find the entry [Profiles]/CustomProfileBuilder +// 5. Enter the path to your newly built exe here. On Windows, don't forget double slashes (e.g. "C:\\MyDir\\Mybuilder.exe") +// And you're done! The EXE is only called on opening the image editor and there is no PP3 already +// +// If you want to use EXIFTOOL to gather more details information to build queries: +// 1. Download exiftool.exe from http://www.sno.phy.queensu.ca/~phil/exiftool/ +// 2. Rename it to exiftool.exe (NOT exiftool(-k).. or something!) +// 3. Copy the RTProfilerBuilder.exe.config next to your own EXE. If you renamed it, rename config to "(Yourname).exe.config" +// 4. Open the config with notepad (it's an XML file). Set ExifToolPath to your downloaded and renamed exe +// +// If you want to know what parameters are available, call "exiftool.exe -tab -short" +// +// This description is for Windows. The C# code does not use anything fancy, will probably work with MONO on Linux/OSX, too + +namespace RTProfilerBuilder { + /// Main class. Mostly change GetCorrectedSettings. + class RTProfileBuilder { + + /// Adds the Nikkor zoom distortion correction profile. + /// First array is list of focal lengths, second array is the RT setting that should correct the + /// distortion for the corresponding focal length. Values between these values are automatically interpolated. + /// The focal length values must already be ordered. The number of sample points is not limited. + static DistortionCorrectProf distNikkor24120f4 = new DistortionCorrectProf( + new double[] { 24, 28, 35, 50, 70, 85, 120 }, + new double[] { -0.1, -0.063, -0.012, 0.018, 0.034, 0.04, 0.048 } + ); + + + /// This is your personalisation function + /// Full EXIF from EXIFTOOL (if configured). + /// Entry, like "Sharpening/Radius" + /// Current value (from default file) + /// FNumberExposure in seconds + /// Focal length in MMISO value + /// Lens from EXIFCamera from EXIF + /// The value to be written. Simply take the current value if you have nothing to touch. + static string GetCorrectedSetting(NameValueCollection exif, string sectionEntry, string value, + double fNumber, double exposureSecs, double focalLength, long iso, string lens, string camera) { + + string s; + + // We don't do anything to the value if it's not our camera + if (camera.EndsWith("NIKON D700", StringComparison.InvariantCultureIgnoreCase) && lens.Contains("24.0-120.0 mm f/4.0")) { + switch (sectionEntry) { + // Here is the place to adjust your settings + // Pretty simple: "SectionName/EntryName" in options file + + case "Vignetting Correction/Amount": + value = (fNumber < 8 && focalLength < 30) ? "30" : "0"; + break; + + case "RAW/CA": + value = ToBool(fNumber < 11); // Means "Enabled if fnumber<11, otherwise disabled" + break; + + case "Impulse Denoising/Enabled": + value = ToBool(iso >= 3200); + break; + + case "HLRecovery/Enabled": + value = ToBool(iso >= 1600); // Dynamic range decreases, so we'll probably need it + break; + + case "Color Boost/Amount": + if (iso >= 6400) value = "0"; // Colors will get poppy anyway... + break; + + case "Distortion/Amount": + // we already checked in the IF upstairs that this is "our" lens + value = distNikkor24120f4.GetDistortionAmount(focalLength); + break; + + // Add other parameters here. Mention this is case sensitive! + + default: break; // we don't touch values we don't care about + } + } // end if camera=xxx + + + // This is for camera independend settings + switch (sectionEntry) { + // These are parsed from EXIFTOOL and XMP in DNG (see http://en.wikipedia.org/wiki/Extensible_Metadata_Platform) + case "IPTC/City": + s = exif.Get("City"); + if (!String.IsNullOrEmpty(s)) value = s; + break; + + case "IPTC/Country": + s = exif.Get("Country"); + if (!String.IsNullOrEmpty(s)) value = s; + break; + + case "IPTC/Caption": + case "IPTC/Title": + s = exif.Get("Headline"); + if (!String.IsNullOrEmpty(s)) value = s; + break; + + // Add other parameters here. Mention this is case sensitive! + + default: break; // we don't touch values we don't care about + } + return value; + } + + #region * Main and Helpers + static string ToBool(bool condition) { return condition ? "true" : "false"; } + static string ToFloat(float f) { return f.ToString(CultureInfo.InvariantCulture); } + + /// Reads default file and parses it. No need to touch it for your personal settings. + /// Command line args + /// 0 on all OK. + static int Main(string[] args) { + int exitCode = 0; + + try { + #region Parse input parameters + int argNo = 0; + + // Name of raw/JPG to process + string sourceFile = args[argNo++]; + + // What the user selected as his base profile + string defaultProfileFilePath = args[argNo++]; + + // Cache directory, for any logging file + string cachePath = args[argNo++]; + + + // True if the image is only being flagged as inTrash, rank or colorLabel but still need valid PP3 - actually not used by this script + bool forFlaggingPurpose = bool.Parse(args[argNo++], CultureInfo.InvariantCulture); + + // Note that old C++ has no automatic number globalization + double fNumber = double.Parse(args[argNo++], CultureInfo.InvariantCulture); + double exposureSecs = double.Parse(args[argNo++], CultureInfo.InvariantCulture); + double focalLength = double.Parse(args[argNo++], CultureInfo.InvariantCulture); + long iso = long.Parse(args[argNo++], CultureInfo.InvariantCulture); + + string lens = args[argNo++]; + string cameraMake = args[argNo++]; + string cameraModel = args[argNo++]; + string camera = cameraMake + " " + cameraModel; + #endregion + + // Read default file as basis + string[] lines = File.ReadAllLines(defaultProfileFilePath); + + NameValueCollection nvEXIF = ParseFullExifData(sourceFile); + + // File should be Windows ANSI + using (TextWriter tw = new StreamWriter(sourceFile + ".pp3", false, new UTF8Encoding(false))) { + string section = ""; + + foreach (string line in lines) { + string l = line.Trim(); + if (!String.IsNullOrEmpty(line)) { + + if (l.StartsWith("[")) + section = l.Trim(new char[] { '[', ']' }); + else if (char.IsLetterOrDigit(l[0]) && l.Contains("=")) { + int valPos = l.IndexOf("=") + 1; + + string newValue = GetCorrectedSetting(nvEXIF, section + "/" + l.Substring(0, valPos - 1), l.Substring(valPos).Trim(), + fNumber, exposureSecs, focalLength, iso, lens, camera); + + // Merge in new value + l = l.Substring(0, valPos) + (newValue ?? ""); + } + } + + tw.WriteLine(l); + } + } + + } catch (Exception ex) { + Console.WriteLine("Error: " + ex.ToString()); // can be seen in the RT console window + + exitCode = 1; + } + + return exitCode; + } + + + static NameValueCollection ParseFullExifData(string filePath) { + NameValueCollection nv = new NameValueCollection(); + + string exifToolPath = ConfigurationManager.AppSettings["ExifToolPath"]; + if (!String.IsNullOrEmpty(exifToolPath)) { + ProcessStartInfo psi = new ProcessStartInfo(exifToolPath, "\"" + filePath + "\" -tab -short"); + psi.CreateNoWindow = false; + psi.UseShellExecute = false; + psi.StandardOutputEncoding = System.Text.Encoding.UTF8; + psi.RedirectStandardOutput = true; + + Process p = Process.Start(psi); + + using (StreamReader sr = p.StandardOutput) { + while (!sr.EndOfStream) { + string line = sr.ReadLine(); + if (line.Contains("\t")) { + string[] split = line.Split('\t'); + nv.Add(split[0], split[1]); + } + } + } + + p.WaitForExit(); + } + + return nv; + } + + #endregion + } + + #region DistortionCorrectProf + /// Holds a distortion correction profile for one lens. Uses sample points (focal length vs. dist. correction) as input. + class DistortionCorrectProf { + double[] adFocLen, adCorrect; + + /// Parses array to internal structure + /// Focal lengths + /// Correction factors + public DistortionCorrectProf(double[] focLen, double[] correct) { + if (focLen == null || correct == null || focLen.Length != correct.Length || focLen.Length < 2) + throw new Exception("DistortionCorrectProf inputs must be valid and of the same lenghts, at least 2 points"); + + adFocLen = focLen; adCorrect = correct; + + for (int i = 0; i < adFocLen.Length - 1; i++) + if (adFocLen[i] >= adFocLen[i + 1]) throw new Exception("The distortion correction focal length points must be ordered!"); + } + + /// Calculates regession value of RT distortion amount for the given focal length. + /// Input focal length. + /// Distortion in RT format. + public string GetDistortionAmount(double focalLength) { + // if it's out of area (which should just happing with e.g. rounding errors), return flat defaults. + if (focalLength <= adFocLen[0]) return adCorrect[0].ToString("G", CultureInfo.InvariantCulture); + if (focalLength >= adFocLen[adFocLen.Length - 1]) return adCorrect[adFocLen.Length - 1].ToString("G", CultureInfo.InvariantCulture); + + for (int i = 0; i < adFocLen.Length - 1; i++) { + if (focalLength >= adFocLen[i] && focalLength < adFocLen[i + 1]) { + // from the sample curves taken so far, it it safe to take a simple linear interpolation here + double corr = adCorrect[i] + (adCorrect[i + 1] - adCorrect[i]) * (focalLength - adFocLen[i]) / (adFocLen[i + 1] - adFocLen[i]); + return corr.ToString("G3", CultureInfo.InvariantCulture); + } + } + + return ""; // should never happen + } + } + #endregion +} diff --git a/tools/RTProfileBuilderSample.exe.config b/tools/RTProfileBuilderSample.exe.config new file mode 100644 index 000000000..2dbb6b973 --- /dev/null +++ b/tools/RTProfileBuilderSample.exe.config @@ -0,0 +1,8 @@ + + + + + + + diff --git a/tools/benchmarkRT b/tools/benchmarkRT new file mode 100755 index 000000000..ed5950543 --- /dev/null +++ b/tools/benchmarkRT @@ -0,0 +1,269 @@ +#!/usr/bin/env bash +# Use this Bash script to test RT processing speed. +# Written by DrSlony +# v1 2012-02-10 +# v2 2013-02-15 +# v3 2013-03-04 +# v4 2013-03-07 +# v5 2013-03-23 +# www.rawtherapee.com + +revision="tip" +inFile='http://rawtherapee.com/shared/test_images/colorspace_flowers.pef' +sidecarDefault=("Neutral.pp3" "Default.pp3") +buildType="release" +branch="default" +rtExe="rawtherapee" +repo="${HOME}/rawtherapee" +OPTIND=1 # Reset in case getopts has been used previously in the shell. +outFileFormat="-t" +tmpDir="/tmp/rawtherapee-benchmark" +runs=5 +echo + +howto() { + fold -s < - Input file name with complete path. This can be a file on your + hard drive or a url. The url must start with "http". The default + behavior if you do not use -i is to download a test file from + $inFile + + -s -s -s - Input sidecar file name(s) with full + paths. You can specify '-s ' zero or more times. To + specify multiple processing profiles, you must precede each + file path with '-s'. The processing profile can be a file on + your hard drive or a url. Only one url is handled, so if you + want to use multiple processing profiles, download them first. + The default behaviour if you do not use -s is to use the + "Neutral" profile. + +Examples: + Run the default benchmark (recommended) + ./benchmarkRT + + Run a benchmark using your own image file, a RawTherpee executable in a + custom directory, and multiple processing profiles: + ./benchmarkRT -i /tmp/kittens.raw -s /tmp/kittens.raw.pp3 -s /tmp/kittens_tonemapped.raw.pp3 -s /tmp/kittens_denoised.raw.pp3 + +Further help: + If you need further help, discover bugs or want to request new functionality + rn this script, then tell us in the forum or on IRC: + http://rawtherapee.com/forum/ + http://webchat.freenode.net/?randomnick=1&channels=rawtherapee&prompt=1 + +END +} + +download () { + local retries=10 + while [[ $retries -ne 0 ]]; do + wget --progress=dot:binary --continue --trust-server-names --tries=5 --timestamping "$1" 2>&1 | sed "s/^/\t/" + return=${PIPESTATUS[0]} + ((retries--)) + if [[ $return -eq 0 ]]; then # I don't trust wget to only exit with 0 if it downloaded the file succesfully, so I check. + if [[ -f "`basename "$1"`" ]]; then + break + fi + fi + printf "%s\n\n" "Failed to download \"$1\"" "Retrying: " + sleep 1s + done + if [[ $retries -eq 0 ]]; then + printf "%s\n" "Tried to download \"$1\" 10 times but failed. Exiting." + exit 1 + fi +} + +while getopts "ae:h?i:s:" opt; do + case "$opt" in + a) testAllTools=1 + ;; + e) customExeDir="${OPTARG%/}" + ;; + h|\?) + howto + exit 0 + ;; + i) inFile="$OPTARG" + ;; + s) sidecarCustom+=("$OPTARG") + ;; + esac +done + +shift $((OPTIND-1)) + +[ "$1" = "--" ] && shift + +inFileName="`basename "${inFile}"`" +if [[ ! -e "${tmpDir}" ]]; then + if [[ ! -w /tmp ]]; then + printf "Error: /tmp is not writable.\n" + exit 1 + fi + mkdir "$tmpDir" +fi + +trap 'rm -rv "${tmpDir}"; exit 1' HUP INT QUIT ABRT TERM + +cd "$tmpDir" + +if [[ ${inFile} = http* ]]; then # if inFile is a url and if we haven't downloaded it already, then download it + [[ ! -e "${tmpDir}/${inFileName}" ]] && { + printf "%s\n\n" "${inFileName} not found in ${tmpDir}, downloading it." + [[ ! -w /tmp ]] && { printf "Error: /tmp is not writable.\n"; exit 1; } + [[ ! -e "$tmpDir" ]] && mkdir "$tmpDir" + cd "$tmpDir" + download "$inFile" + echo + } +else # otherwise if inFile is not a url, check if it exists + [[ ! -e "${inFile}" ]] && { # if it doesnt exist, choke + printf "%s\n" "You specified" "-i ${inFile}" "but that file does not exist." + exit 1 + } + cp "${inFile}" "${tmpDir}/${inFileName}" +fi + +rtExeDirs=("${customExeDir}" "$HOME/rt_${branch}_${buildType}" "$HOME/rt_${branch}_${buildType}_patched" "$HOME/rawtherapee/") +for rtExeDir in "${rtExeDirs[@]}"; do + if [[ -x "${rtExeDir}/${rtExe}" ]]; then + printf "%s\n" "Using RawTherapee executable:" "${rtExeDir}/${rtExe}" + break + fi +done + +if [[ ! -x "${rtExeDir}/${rtExe}" ]]; then + printf "%s\n" "Could not find the RawTherapee executable:" "${rtExeDir}/${rtExe}" "Re-run this script using the -e flag." + exit 0 +fi + +if [[ $testAllTools -ne 1 ]]; then + if [[ -n "${sidecarCustom}" ]]; then # if sidecarCustom was specified + if [[ ${sidecarCustom} = http* ]]; then # and if sidecarCustom starts with an http + if [[ ! -e "${tmpDir}/$/{sidecarCustom##*/}" ]]; then # and if sidecarCustom hasn't been previously downloaded, then download it + printf "${sidecarCustom} not found in ${tmpDir}, downloading it.\n" + download "$sidecarCustom" + fi + else # else if sidecarCustom does not start with an http + for sidecarFile in "${sidecarCustom[@]}"; do + [[ ! -e "${sidecarFile}" ]] && { # then check if it exists + printf "You specified \"-s ${sidecarFile}\" but it does not exist. Make sure you wrote a full, absolute path, e.g.:" " -s /tmp/kittens_denoise.raw.pp3" + exit 1 + } + done + unset sidecarFiles + sidecarDir="" + sidecarFiles=("${sidecarCustom[@]}") + fi + else # if sidecarCustom was not specified, find the default ones + for sidecar in "${sidecarDefault[@]}"; do + if [[ -f "${rtExeDir}/profiles/${sidecar}" ]]; then + sidecarDir="${rtExeDir}/profiles/" + elif [[ -f "${tmpDir}/${sidecar}" ]]; then + sidecarDir="${tmpDir}/" + else + printf "%s\n" "" "Could not find \"${sidecar}\" in \"${rtExeDir}/profiles/\" where it was expected to be." "Downloading the latest \"${sidecar}\" from the repository." "" + download "https://rawtherapee.googlecode.com/hg/rtdata/profiles/${sidecar}" + sidecarDir="${tmpDir}/" + fi + done + if [[ "${sidecarDir}" = "${tmpDir}/" ]]; then + printf "%s\n" "Beware that the downloaded processing profiles might not be entirely compatible with the RawTherapee version you're testing. For authentic and consistent results, make sure that the PP3 files match this RawTherapee version. You can use the -p flag to point benchmarkRT to the correct PP3 file(s)." | fold -s + fi + sidecarFiles=("${sidecarDefault[@]}") + fi +else + unset sidecarFiles avgTable + sidecarDir="${tmpDir}/" + tools=("Auto Exposure;Exposure;Auto=true" "Sharpening - Unsharp Mask;Sharpening;Enabled=true;Method=usm" "Sharpening - RL Deconvolution;Sharpening;Enabled=true;Method=rld" "Vibrance;Vibrance;Enabled=true" "Edges;SharpenEdge;Enabled=true" "Microcontrast;SharpenMicro;Enabled=true" "CIECAM02;Color appearance;Enabled=true" "Impulse Noise Reduction;Impulse Denoising;Enabled=true" "Defringe;Defringing;Enabled=true" "Noise Reduction;Directional Pyramid Denoising;Enabled=true" "Tone Mapping;EPD;Enabled=true" "Shadows/Highlights;Shadows & Highlights;Enabled=true" "Contrast by Detail Levels;Directional Pyramid Equalizer;Enabled=true" "Raw Chromatic Aberration;RAW;CA=true") + for i in "${!tools[@]}"; do + IFS=";" read toolNameHuman tool key1 key2 key3 <<< "${tools[$i]}" + i=`printf "%02d\n" "$i"` + printf "%s\n" "[${tool}]" "$key1" "$key2" "$key3" > "${sidecarDir}/${i} - ${tool}.pp3" + sidecarFiles+=("${i} - ${tool}.pp3;${toolNameHuman}") + done +fi + +printf "%s\n" "" "--------------------------------------------------------------------------------" "" "Benchmark of RawTherapee" +printf "%s\n" "`uname -srvmpio`" "" +hash cpufreq-info 2>/dev/null && cpufreq-info -mo +printf "%s\n" "" + +if [[ ! -f "${rtExeDir}/AboutThisBuild.txt" ]]; then + printf "%s\n" "[Could not find ${rtExeDir}/AboutThisBuild.txt]" "" +else + cat "${rtExeDir}/AboutThisBuild.txt" +fi + +printf "%s\n" "Photo: ${tmpDir}/${inFileName}" +for sidecar in "${sidecarFiles[@]}"; do + if [[ $testAllTools -eq 1 ]]; then + IFS=";" read sidecar toolNameHuman <<< "${sidecar}" + fi + printf "%s\n" "Sidecar: ${sidecarDir}${sidecar}" +done +echo + +declare -A avgTable +unset benchmark total sidecar sorted +for s in "${!sidecarFiles[@]}"; do + IFS=";" read sidecar toolNameHuman <<< "${sidecarFiles[s]}" + unset benchmark + for (( i=1; i<=${runs}; i++ )); do + runTime="$( { time "${rtExeDir}/${rtExe}" -o /dev/null -p "${sidecarDir}${sidecar}" "$outFileFormat" -Y -c "${tmpDir}/${inFileName}"; } 2>&1 | grep ^real; )" +# runTime=real 0m4.751s + runTime=${runTime#*[[:blank:]]} +# runTime=0m4.751s + minOnly=${runTime%m*} + secOnly=${runTime#*m}; secOnly=${secOnly%s*} + t="$( printf "%s\n" "scale=3; $secOnly+$minOnly*60" | bc )" +# t=4.751 +## t="$(( $RANDOM %20 )).$(( $RANDOM %999 ))" +# benchmark stores time array of each run, gets reset after each PP3 + benchmark+=("$t") +# total stores time array of each run, doesnt get reset, adds up total afterwards + total+=("$t") + i=`printf "%02d\n" "$i"` + if [[ $testAllTools -eq 1 ]]; then + printf "%*b" "-50" "Benchmark ${i} \"${toolNameHuman}\"" "7" "${benchmark[$i - 1]}" "" "\n" | sed 's/ /../g' + else + printf "%*b" "-50" "Benchmark ${i} \"${sidecar##*/}\"" "7" "${benchmark[$i - 1]}" "" "\n" | sed 's/ /../g' + fi + done + avg=$( { printf "%s" "scale=3; ("; IFS="+"; printf "%s" "${benchmark[*]}"; printf "%s\n" ") / ${#benchmark[@]}"; } | bc ); + if [[ $testAllTools -eq 1 ]]; then + printf "%*b" "-50" "Benchmark \"${toolNameHuman}\" average" "7" "${avg}" "" "\n\n" | sed 's/ /../g' + avgTable+=(["${toolNameHuman}"]="$avg") + else + printf "%*b" "-50" "Benchmark \"${sidecar##*/}\" average" "7" "${avg}" "" "\n\n" | sed 's/ /../g' + avgTable+=(["${sidecar}"]="$avg") + fi +done + +printf "%*b" "-50" "Benchmark total" "7" "`IFS=+; bc -l <<< "${total[*]}"`" "" "\n\n" | sed 's/ /../g' + +# Associative arrays don't return in alphanumerical order, must be sorted manually +IFS=$'\n' sorted=($(sort <<<"${!avgTable[*]}")); + +printf "%s\n" "Average times for each tool:" +for x in "${sorted[@]}"; do + printf "%*b" "-50" "${x}" "7" "${avgTable[$x]}" "" "\n" | sed 's/ /../g' +done diff --git a/tools/buildRT b/tools/buildRT new file mode 100755 index 000000000..ca7756358 --- /dev/null +++ b/tools/buildRT @@ -0,0 +1,442 @@ +#!/usr/bin/env bash +# Written by DrSlony +# buildRT version 4.3, 2015-03-11 +# Please report bugs or enhancements to http://code.google.com/p/rawtherapee/issues/list +# www.rawtherapee.com +# www.londonlight.org + +head -n 4 $0 | tail -n 2 | sed $'1s/.\+/\E[1m&\E[0m/' +echo + +if [[ $UID -eq 0 ]]; then + printf "%s\n" "Do not run this script as root!" "Aborting" + exit 1 +fi + +alert () { + case "$alert_type" in + notify-send) notify-send "RawTherapee" "$1" ;; + kdialog) kdialog --title "RawTherapee" --passivepopup "$(printf "%b\n" "$1")" ;; + zenity) zenity --notification --text="$(printf "%b\n" "$1")" ;; + xmessage) xmessage -nearmouse "$(printf "%b\n" "$1")" ;; + none) printf "%b\n" "" "Compilation complete:" "$1" ;; +esac +} + +#--- Set some variables +unset choiceNumber choiceNumbers buildType buildTypes list branch branches repo +version="4.3" +movetoPatched="" +repo="${HOME}/rawtherapee" +procTarget=2 + +while getopts "bc:fnp:s:t:uvh?-" opt; do + case "${opt}" in + b) patched="yes" + movetoPatched="_patched" + printf "%s\n" "Buildonly flag detected, will not hg pull or update" ;; + c) dCacheNameSuffix="$OPTARG" + dCacheNameSuffix=${dCacheNameSuffix//[^\.\-_a-zA-Z0-9]/}; + forceCmake="yes" + printf "%s\n" "Cache and config name suffix: $dCacheNameSuffix" ;; + f) forceCmake="yes" + printf "%s\n" "Will forcefully re-run CMake" ;; + n) noomp="-DOPTION_OMP=OFF" + forceCmake="yes" + printf "%s\n" "OpenMP disabled" ;; + p) procTarget="$OPTARG" + if [[ $procTarget -lt 1 || $procTarget -gt 9 ]]; then + printf "%s\n" "Invalid processor target value." "Use a value from 1 to 9, e.g." "./buildRT -p 1" "See ProcessorTargets.cmake" "Aborting" + exit 1 + forceCmake="yes" + fi ;; + s) movetoPatched="_${OPTARG//[^\.\-_a-zA-Z0-9]/}" + printf "%s\n" "Suffix of destination build dir: ${movetoPatched}" ;; + t) titleSuffix="${OPTARG//[^\.\-\:\ \+_a-zA-Z0-9]/}" + forceCmake="yes" + printf "%s\n" "Titlebar version suffix: ${titleSuffix}" ;; + u) gcVer="$(curl "http://rawtherapee.googlecode.com/hg/tools/buildRT" 2>/dev/null | grep "^#.*[vV]ersion.*")" || { echo "\"curl\" program not found, please install it first."; exit 1; } + gcVer="${gcVer##*[[:alpha:]] }" + gcVer="${gcVer%%,*}" + latestVer="$(printf "%s\n" "$version" "$gcVer" | sort -rV | head -n 1)" + if [[ $version = $latestVer ]]; then + printf "%s\n" "You are using the latest version of buildRT, $version" + exit 0 + else + printf "%s\n" "You are using version $version but version $gcVer is available on Google Code." "You can download the Google Code version from this URL:" " https://rawtherapee.googlecode.com/hg/tools/buildRT" "Replace it with this script, and remember to run \"chmod +x buildRT\"" + exit 0 + fi ;; + v) verbose=yes + printf "%s\n" "Verbose mode, I will spam your screen with warnings" ;; + h|\?|-) printf "%s\n" "Usage:" "" " $0 [-b] [-c ] [-f] [-n] [-p <1-9>] [-s ] [-t \"\"] [-v]" "" + printf "%s\n" \ + " -b" \ + "Build-only mode. buildRT uses \"hg update -C default\" to update your source code repository to the newest revision, however doing so might destroy any uncommitted or unpushed changes you made or any patches you applied. With the -b flag the script will not update the source code, so that you can easily compile RawTherapee with whatever patches you manually applied. buildRT should automatically detect if you modified the source code, but you can use this flag to force build-only mode." "Generally when compiling patched RT versions you want to keep the cache and config folders separate, so consider using \"-b -c _testing\"" "" \ + " -c " \ + "Specify a suffix to the cache and config directory names. Only alphanumerics, periods, dashes and underscores are valid. The default value is \"4\", which will result in your build of RawTherapee storing the cache in \"${HOME}/.cache/RawTherapee4\" and config in \"${HOME}/.config/RawTherapee4\". For example, use \"-c _testing\" if you want to test older or patched versions of RawTherapee without potentially damaging your \"real\" cache and config files." "" \ + " -f" \ + "Force CMake to re-run." "" \ + " -n" \ + "Disable OpenMP." "" \ + " -p <1-9>" \ + "Set which processor target to use. Takes a single digit from 1 to 9. The default is 2. See ProcessorTargets.cmake" "" \ + " -s " \ + "Suffix of destination build directory, so that if you have applied a patch, say \"dustremoval-1.patch\", and want to have RawTherapee compiled to a folder whose name ends with \"_dustremoval1\", you would set \"-s dustremoval1\" (the underscore is automated)." "" \ + " -t \"\"" \ + "Suffix displayed next to the RawTherapee version in the window titlebar. It is recommended that you include the changeset of the newest public commit (the one you would see if you cloned the repository anew) so it is clear which commit you applied the patches to. E.g.:" "-t \": ee72ddbcfd4e + dustremoval-1.patch + mustafa ibrahim\"" "" \ + " -u" \ + "Check for an update of buildRT on Google Code." "" \ + " -v" \ + "Make compilation verbose, so you see all compiler warnings." | fold -s + exit 0 ;; +esac +done +shift $((OPTIND-1)) +[ "$1" = "--" ] && shift + +printf "%s\n" "Repository: ${repo}" +printf "%s\n" "Processor target: ${procTarget}" + +if [[ -z $verbose ]]; then + Wcflags="-Wno-unused-result -Wno-aggressive-loop-optimizations" +fi + +cpuCount="$(grep -c 'processor' /proc/cpuinfo)" +# We can assume that if grep returns more than 32 lines (CPUs), or nothing at all, something's wrong +if (( cpuCount < 1 || cpuCount > 32 )); then + cpuCount="1" +fi +printf "%s\n" "CPU count: ${cpuCount}" + +# Zenity --notification is broken in <=3.8.0, removed Zenity support for now. +# elif hash zenity 2>/dev/null; then alert_type="zenity" +if hash notify-send 2>/dev/null; then alert_type="notify-send" +elif hash kdialog 2>/dev/null; then alert_type="kdialog" +elif hash xmessage 2>/dev/null; then alert_type="xmessage" +else alert_type="none" +fi + +# list from http://linuxmafia.com/faq/Admin/release-files.html +distributions=( +"Annvix /etc/annvix-release" +"Arch /etc/arch-release" +"Arklinux /etc/arklinux-release" +"Aurox /etc/aurox-release" +"BlackCat /etc/blackcat-release" +"Cobalt /etc/cobalt-release" +"Conectiva /etc/conectiva-release" +"Debian /etc/debian_version" +"Fedora /etc/fedora-release" +"Gentoo /etc/gentoo-release" +"Immunix /etc/immunix-release" +"Knoppix knoppix_version" +"Linux-From-Scratch /etc/lfs-release" +"Linux-PPC /etc/linuxppc-release" +"Mandrake /etc/mandrake-release" +"Mandriva_Mandrake /etc/mandriva-release /etc/mandrake-release /etc/mandrakelinux-release" +"Mint /etc/linuxmint/info" +"MkLinux /etc/mklinux-release" +"Novell /etc/nld-release" +"PLD /etc/pld-release" +"RedHat /etc/redhat-release" +"CentOS /etc/centos-release" +"Slackware /etc/slackware-version" +"SME /etc/e-smith-release" +"Solaris /etc/release" +"SunJDS /etc/sun-release" +"SUSE /etc/SuSE-release" +"TinySofa /etc/tinysofa-release" +"TurboLinux /etc/turbolinux-release" +"Ubuntu /etc/lsb-release" +"UltraPenguin /etc/ultrapenguin-release" +"United /etc/UnitedLinux-release" +"VA-Linux /etc/va-release" +"YellowDog /etc/yellowdog-release" +) +for element in "${distributions[@]}"; do + read distro loc1 loc2 loc3 <<< "$element" + for loc in $loc1 $loc2 $loc3 + do + # distribution=${distro} because if none of the elements match, distro will =YellowDog (last item in the list) + # add "break 2;" to the end if we really want to, but Ubuntu gets detected as Debian first, then as Ubuntu, + # so we might want to not break the loop. + [[ -e "$loc" ]] && distribution=${distro} + [[ "$distribution" = Gentoo ]] && break 2 + done +done +if [[ -z ${distribution} ]]; then + printf "%s\n" "" "Could not automatically detect your distribution. Please enter your distribution's name below followed immediately by the version, without any spaces or punctuation marks, and hit enter to confirm, e.g. \"Ubuntu1310\", \"Mint15\" or \"OpenSUSE123\"" | fold -s + read distribution + #sanitize + distribution=${distribution//[^a-zA-Z0-9]/} +fi +printf "%s\n" "Distribution: ${distribution}"; + +bits="$(uname -m)" || { printf "%s\n" "Is your system a 32-bit or 64-bit one?" "Enter 32 or 64 and hit enter: "; read bits; bits=${bits//[^0-9]/}; } +if [[ $bits = *64* ]]; then + bits=64 +else + bits=32 +fi +printf "%s\n" "System: ${bits}-bit" "" + +#--- Check script dependencies +hash hg 2>/dev/null || { echo >&2 "Mercurial not found, install Mercurial first and then re-run this script."; exit 1; } + +#--- Clone and/or pull +if [[ ! -d "${repo}" ]]; then + printf "%s\n" "${repo} not found, cloning from GoogleCode..." + hg clone https://rawtherapee.googlecode.com/hg/ "${repo}" + cd "${repo}" || exit 1 + hg parents --template '\nRepository state:\n Branch: {branch}\n RawTherapee-{latesttag}.{latesttagdistance}\n Changeset: {rev}:{node|short}\n Latest tag: {latesttag}\n\n' + alert "Repository cloned succesfully. What would you like to do next?" + printf "%b" "Repository cloned succesfully.\n" "Press 'q' to quit or any other key to continue... " + read -r -n 1 + echo + [[ $REPLY = q || $REPLY = Q ]] && { printf "%s\n" "Quitting." ""; exit 0; } +fi +cd "${repo}" || exit 1 + +#--- Update or decide what to do if user edited the source code (e.g. by applying a patch) +# "hg outgoing" takes time, so skip if buildonly +if [[ -z $patched ]]; then + uncommitted="$(hg status | sed "s/^/\t/")" + unpushed="$(hg outgoing -q | sed "s/^/\t/" || echo "Could not check for unpushed changes (check your internet connection), but continuing anyway.")" +fi +if [[ -z $uncommitted && -z $unpushed && -z $patched ]]; then + hg pull || echo "Could not \"hg pull\" (check your internet connection), but continuing anyway." + hg update -C default + echo +elif [[ -z $patched ]]; then + printf "%s\n" "" "Warning! There are uncommitted or unpushed changes in the repository!" "Uncommitted:" "$uncommitted" "Unpushed:" "$unpushed" "" "This means that you edited the source code (e.g. applied a patch). If the script proceeds to update the repository, those changes you made to the source code might be lost. Your choices are to force the update and possibly lose the changes, not to update and to compile RT as-is, or to abort the script." | fold -s + read -r -p "[f]orce update, [c]ompile as-is, or [a]bort? " fca + case $fca in + f|F) hg pull || echo "Could not \"hg pull\" (check your internet connection), but continuing anyway." + hg update -C default + echo ;; + c|C) printf "%s\n" "Retaining edited source code and compiling RT as-is." "" + patched="yes" + if [[ -z $movetoPatched ]]; then + movetoPatched="_patched" + fi ;; + *) printf "%s\n" "User aborted" "" + exit 0 ;; + esac +else + printf "%s\n" "Retaining edited source code and compiling RT as-is." "" + if [[ -z $movetoPatched ]]; then + movetoPatched="_patched" + fi +fi +hg parents --template 'Repository state:\n Branch: {branch}\n RawTherapee-{latesttag}.{latesttagdistance}\n Changeset: {rev}:{node|short}\n Latest tag: {latesttag}\n\n' + +#--- Print the menu +branches=() +if [[ -z $patched ]]; then + while read -r branch; do + branches+=("$branch") + done < <(hg branches -aq | sort -f) +else + branches="$(hg branch)" +fi + +# Make the menu list +list=("0" "[abort]" "[exit]") +num="1" +buildTypes=("release" "debug") +for branch in "${branches[@]}"; do + for buildType in "${buildTypes[@]}"; do + list+=("$num" "${branch}" "${buildType}") + ((num++)) + done +done + +printf "%s\n" "---------------------------------------------" +printf "%s\t%s\t%s\n" "#" "Branch" "Build Type" "${list[@]}" | column -t -s $'\t' -c 3 | sed $'1s/.\+/\E[1m&\E[0m/' +printf "%s\n" "---------------------------------------------" "" "Enter your choices, each number separated by a single space, e.g. 3 4" "If you don't know which option to choose, then choose the \"default\" branch, \"release\" build type." "" | fold -s + +# make sure choices are valid +checkChoices () { + choiceNumbers="${choiceNumbers//[^0-9 ]/}" + # all choiceNumbers must exist in listNums, else ask again + for choiceNumber in "${choiceNumbers[@]}"; do + if [[ "${choiceNumber}" = 0 ]]; then + exit 0; + fi + found=0 + # for each num in list[@] + for (( o=3 ; o<${#list[@]} ; ((o+=3)) )); do + if [[ "${list[$o]}" = ${choiceNumber} ]]; then + found=1; + fi + done + # if one of the numbers the user typed arent in the list, break the loop and ask for input again + if [[ $found = 0 ]]; then + [[ -n ${choiceNumbers[@]} ]] && printf '%s\n' "Invalid choices, try again." + return 1; + fi + done +} + +# keep repeating read until choices are valid +until checkChoices; do + read -r -p "Your choices: " -a choiceNumbers +done +printf "%s\n" "" "---------------------------------------------" "" + +#--- Compile the chosen builds +for choiceNumber in "${choiceNumbers[@]}"; do + if [[ $choiceNumber = 0 ]]; then + printf "%s\n" "User exited." + exit 0; + fi + # ${array[@]:offset:length} + # choiceNumber*3 to get the human menu choice to match the correct array index, and then +1 so we offset to branch and buildType, not #. + IFS=$'\t' read -r branch buildType < <(printf "%s\t%s\n" "${list[@]:$(($((choiceNumber*3))+1)):2}") + # extra safety check + if [[ -z "$branch" ]] || [[ -z "$buildType" ]]; then + print '%s\n' "Something went wrong with the selection, \"branch\" or \"buildType\" empty." "Aborting" + exit 1 + fi + # This seems useless "$branch != default" + # if [[ -z $patched && $branch != default ]]; then + if [[ -z $patched ]]; then + printf "%s\n" "Updating to branch $branch" + hg update -C "$branch" || exit 1 + fi + echo + printf "%-15b %b\n" "\E[1mWill compile\E[0m:" "" "\tChoice number:" "$choiceNumber" "\tBranch:" "$branch" "\tBuild type:" "$buildType" "\tTarget:" "$procTarget" "" + rev="$(hg parents --template {rev})" + + [[ -d "${HOME}/rt_${branch}_${buildType}${movetoPatched}" ]] && { + printf "%s\n" "Found old build directory ${HOME}/rt_${branch}_${buildType}${movetoPatched}" "To proceed you must either delete it, or choose a suffix for the destination folder for this build." + read -r -p "[d]elete old build, [r]ename this build destination folder, or [a]bort " + echo + case $REPLY in + d|D) rm -rf "${HOME}/rt_${branch}_${buildType}${movetoPatched}" || exit 1 ;; + r|R) printf "%s\n" "The build will be saved to \"${HOME}/rt_${branch}_${buildType}_X\" where \"X\" will be replaced with whatever suffix you choose next. Only alphanumerics, dashes, underscores and periods are valid." | fold -s + read -r -p "Suffix: " + movetoPatched="_${REPLY//[^\.\-_a-zA-Z0-9]/}" + printf "%s\n" "Build will be compiled to \"${HOME}/rt_${branch}_${buildType}${movetoPatched}\"" ;; + a|A) printf "%s\n" "Cannot proceed if old build directory exists." "Remove it or rename it, then re-run this script." "Aborting" + exit 0 ;; + *) printf "%s\n" "Unknown response \"$REPLY\"" + exit 1 ;; + esac + } + + cd "${repo}" || exit 1 + + verLatesttag="$(hg parents --template '{latesttag}')" + verLatesttagdistance="$(hg parents --template '{latesttagdistance}')" + [[ -z $dCacheNameSuffix ]] && dCacheNameSuffix="${verLatesttag%%.*}" + + # need to rerun cmake if buildtype changed + if [[ -e build/CMakeCache.txt ]]; then + previousBuildType="$(grep 'CMAKE_BUILD_TYPE:STRING=' build/CMakeCache.txt)" + previousBuildType="${previousBuildType##*=}" + fi + if [[ ! -e build/CMakeCache.txt || $previousBuildType != "$buildType" ]]; then + forceCmake="yes" + fi + + if [[ ! -d "${repo}/build" || $forceCmake = yes ]]; then + # Clean up leftovers from previous successful or failed builds + [[ -d "${repo}/${buildType}" ]] && { printf "%s\n" "Found old build directory \"${repo}/$buildType\". Removing it."; rm -rf "${repo}/${buildType}"; } + [[ -d "${repo}/rawtherapee" ]] && { printf "%s\n" "Found old build directory \"${repo}/rawtherapee\". Removing it."; rm -rf "${repo}/rawtherapee"; } + [[ -d "${repo}/build" ]] && { printf "%s\n" "Found old build directory \"${repo}/build\". Removing it."; rm -rf "${repo}/build"; } + printf "%s\n" "" "Cleaning out old CMake files" + make clean || { printf "%s\n" "Error while running \"make clean\", aborting." "Easiest solution: delete ${repo} and re-run buildRT."; exit 1; } + ./clean.sh || { printf "%s\n" "Error while running \"./clean.sh\", aborting." "Easiest solution: delete ${repo} and re-run buildRT."; exit 1; } + mkdir "${repo}/build" || exit 1 + + # As of changeset 1930:067e362c6f28 on Mon Jun 25 2012, revision number 1930, RT supports and encourages out-of-source builds. + if (( rev < 1930 )); then + cmake \ + -DCMAKE_BUILD_TYPE="$buildType" \ + -DPROC_TARGET_NUMBER="$procTarget" \ + -DCMAKE_C_FLAGS="-pipe" \ + -DCMAKE_CXX_FLAGS="$CMAKE_C_FLAGS $Wcflags" \ + "$noomp" \ + -DCMAKE_INSTALL_PREFIX="build" \ + -DBUILD_BUNDLE="ON" \ + -DBINDIR="." \ + -DDATADIR="." \ + -DCACHE_NAME_SUFFIX="$dCacheNameSuffix" \ + || { echo "Error during cmake, exiting."; exit 1; } + else + cd "${repo}/build" + cmake \ + -DCMAKE_BUILD_TYPE="$buildType" \ + -DPROC_TARGET_NUMBER="$procTarget" \ + -DCMAKE_C_FLAGS="-pipe" \ + -DCMAKE_CXX_FLAGS="$CMAKE_C_FLAGS $Wcflags" \ + "$noomp" \ + -DCMAKE_INSTALL_PREFIX="build" \ + -DBUILD_BUNDLE="ON" \ + -DBINDIR="." \ + -DDATADIR="." \ + -DCACHE_NAME_SUFFIX="$dCacheNameSuffix" \ + -DVERSION_SUFFIX="$titleSuffix" \ + ../ \ + || { echo "Error during cmake, exiting."; exit 1; } + fi + fi + echo + + if (( rev >= 1930 )); then + cd "${repo}/build" || exit 1 + fi + + printf "%s\n" "" "Starting compilation:" + time { make -j${cpuCount} install; } || { printf "%s\n" "" "Error during make, exiting."; exit 1; } + printf "%-15b %b\n" "" "" "RawTherapee compiled:" "" "\tChoice number:" "$choiceNumber" "\tBranch:" "$branch" "\tBuild type:" "$buildType" "\tTarget:" "$procTarget" "\tCache:" "${HOME}/.cache/RawTherapee${dCacheNameSuffix}" "\tConfig:" "${HOME}/.config/RawTherapee${dCacheNameSuffix}" "" "" + + # RT used to build into various places over the years. + # We want to end up with the build in a folder called "/build/rawtherapee" regardless of which old version you compile, and then to zip it, so we move dirs around: + if (( rev < 1930 )); then + if [[ -d "${repo}/${buildType}" ]]; then + printf "%s\n" "Moving \"${repo}/${buildType}\" to \"${repo}/build/rawtherapee\"" + mv "${repo}/${buildType}" "${repo}/build/rawtherapee" + elif [[ -d "${repo}/rawtherapee" ]]; then + printf "%s\n" "Moving \"${repo}/rawtherapee\" to \"${repo}/build/rawtherapee\"" + mv "${repo}/rawtherapee" "${repo}/build/rawtherapee" + elif [[ ! -d "${repo}/build" ]]; then + { printf "%s\n" "Could not find the \"build\" directory containing the compiled RawTherapee in ${repo}" "Please notify DrSlony in the forum:" "http://rawtherapee.com/forum/viewtopic.php?f=10&t=3001#p22213" "" "Exiting"; exit 1; } + fi + elif [[ -d "${repo}/build/${buildType}" ]]; then + printf "%s\n" "Moving \"${repo}/build/${buildType}\" to \"${repo}/build/rawtherapee\"" + mv "${repo}/build/${buildType}" "${repo}/build/rawtherapee" + fi + + echo + cd "${repo}/build" + # ${repo}/build/AboutThisBuild.txt doesn't exist with older versions + # Put "AboutThisBuild.txt" alongside the "rawtherapee" dir for the zip so that the website can extract the needed info when uploading the build (no other reason) + if [[ ! -e AboutThisBuild.txt ]]; then + cp "rawtherapee/AboutThisBuild.txt" AboutThisBuild.txt || { printf "%s\n" "Could not copy ${repo}/build/rawtherapee/AboutThisBuild.txt to ${repo}/build/AboutThisBuild.txt, exiting."; exit 1; } + fi + + cat AboutThisBuild.txt || { printf "%s\n" "${repo}/build/AboutThisBuild.txt not found, exiting."; exit 1; } + + if [[ -z $patched ]]; then + printf "%s\n" "Zipping the compiled RawTherapee dir \"${repo}/build/rawtherapee\" and putting it in \"/tmp/RawTherapee_${branch}_${distribution}_${bits}_${verLatesttag}.${verLatesttagdistance}_${buildType}.zip\"" + [[ -e "/tmp/RawTherapee_${branch}_${distribution}_${bits}_${verLatesttag}.${verLatesttagdistance}_${buildType}.zip" ]] && { rm "/tmp/RawTherapee_${branch}_${distribution}_${bits}_${verLatesttag}.${verLatesttagdistance}_${buildType}.zip" || exit 1; } + zip -Xrq "/tmp/RawTherapee_${branch}_${distribution}_${bits}_${verLatesttag}.${verLatesttagdistance}_${buildType}.zip" AboutThisBuild.txt rawtherapee + fi + + # Now that the zip is ready, the build can be moved to ~/rt__<_patched> + printf "%s\n" "" "Moving \"${repo}/build/rawtherapee\" to \"${HOME}/rt_${branch}_${buildType}${movetoPatched}\"" + mv "${repo}/build/rawtherapee" "${HOME}/rt_${branch}_${buildType}${movetoPatched}" || { printf "%s\n" "" "Could not move \"${repo}/build/rawtherapee\" to \"${HOME}/rt_${branch}_${buildType}${movetoPatched}\", exiting."; exit 1; } + + printf "%-15b %b\n" "" "" "Build ready:" "" "\tChoice number:" "$choiceNumber" "\tBranch:" "$branch" "\tBuild type:" "$buildType" "\tTarget:" "$procTarget" + printf "%b\n" "" "\E[1mTo run RawTherapee\E[0m, fire up a terminal and type:" "~/rt_${branch}_${buildType}${movetoPatched}/rawtherapee" "" "------------------------------------------" + alert "RawTherapee-${verLatesttag}.${verLatesttagdistance} ready.\nChoice number ${choiceNumber}, branch: ${branch}, type: ${buildType}, target: ${procTarget}" +done + +# builds=( /tmp/RawTherapee* ); for f in ${builds[@]}; do echo ${f#/tmp/}; done +if [[ -z $patched ]]; then + printf "%s\n" "RawTherapee zipped builds ready in /tmp" + ls -lh /tmp/RawTherapee* +fi +printf "%s\n" "" "Finished building all chosen versions of RawTherapee" diff --git a/tools/buildRT.bat b/tools/buildRT.bat new file mode 100644 index 000000000..451d2f29a --- /dev/null +++ b/tools/buildRT.bat @@ -0,0 +1,50 @@ +@echo off +REM 2013-05-14 version 1 + +SET RT_BUILD_TYPE=Release +SET RT_CACHE_VER=4.0.11 +SET PATH=%PATH%;C:\gtkmm64\bin;C:\MinGW64\bin;C:\CMake\bin;%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;C:\Program Files\TortoiseHg\ +SET RT_SOURCECODE_PATH=C:\rtrepo +SET RT_BUILD_PATH=C:\rtrepo\build +SET RT_SSE_SUPPORT= + +IF EXIST "%RT_BUILD_PATH%" (SET /P clean="Start from scratch? [y/n] ") +IF %clean%==y (GOTO rmbuild) +GOTO continue + +:rmbuild +rmdir /S/Q "%RT_BUILD_PATH%" +GOTO continue + +:continue +ECHO. +SET +ECHO. +mkdir "%RT_BUILD_PATH%" && cd %RT_BUILD_PATH% +SET /P target="Make a 32-bit or 64-bit build? [32/64] " +IF %target%==32 (GOTO cmake32) +IF %target%==64 (GOTO cmake64) +ECHO Invalid choice +GOTO end + +:cmake32 +SET /P sse="Compile with SSE support? (Default is no) [y/n] " +IF %sse%==y (SET RT_SSE_SUPPORT="-msse") +ECHO. +cmake -DCMAKE_BUILD_TYPE=%RT_BUILD_TYPE% -DCMAKE_C_FLAGS="-O2 -m32 %RT_SSE_SUPPORT%" -DCMAKE_SHARED_LINKER_FLAGS="-m32" -DCMAKE_EXE_LINKER_FLAGS="-m32" -DCMAKE_RC_FLAGS="-F pe-i386" -DCMAKE_CXX_FLAGS="%CMAKE_C_FLAGS%" -DBUILD_BUNDLE:BOOL="1" -DCACHE_NAME_SUFFIX:STRING="%RT_CACHE_VER%" -G "MinGW Makefiles" -DPROC_TARGET_NUMBER:STRING=2 -C%RT_SOURCECODE_PATH%\win.cmake %RT_SOURCECODE_PATH% +GOTO compile + +:cmake64 +ECHO. +SET /P sse="Compile with SSE support? (Default is yes) [y/n] " +IF %sse%==n (SET RT_SSE_SUPPORT="-mno-sse") +ECHO. +cmake -DCMAKE_BUILD_TYPE=%RT_BUILD_TYPE% -DCMAKE_C_FLAGS="-O2 %RT_SSE_SUPPORT%" -DCMAKE_CXX_FLAGS="%CMAKE_C_FLAGS%" -DBUILD_BUNDLE:BOOL="1" -DCACHE_NAME_SUFFIX:STRING="%RT_CACHE_VER%" -G "MinGW Makefiles" -DPROC_TARGET_NUMBER:STRING=2 -C%RT_SOURCECODE_PATH%\win.cmake %RT_SOURCECODE_PATH% +GOTO compile + +:compile +mingw32-make.exe "MAKE=mingw32-make -j%NUMBER_OF_PROCESSORS%" -j%NUMBER_OF_PROCESSORS% install +GOTO end + +:end +cd \ diff --git a/tools/compareRT b/tools/compareRT new file mode 100755 index 000000000..cca18bee6 --- /dev/null +++ b/tools/compareRT @@ -0,0 +1,59 @@ +#!/usr/bin/env bash +# +# compareRT version 1.0, 2014-01-24 +# compareRT version 1.1, 2015-02-24 +# Processes all images in the current dir with two different +# RawTherapee versions and tests for differences. +# +# Run this script from the dir with the images you want to test. +# Make sure the PP3 you set below is in the same dir. +# Don't worry about non-image files. +# Each dir specified in rtDirs and the outDir must end with / +# +# CC-BY-SA 3.0 DrSlony + +unset rtDirs outDir pp3 imgs v i c + +#--- Edit these as needed. +rtDirs=("$HOME/rt_default_release/" "$HOME/rt_default_release_patched/") +pp3="foo.pp3" +outDir="/tmp/compareRT/" +#--- + +while IFS=$'\n' read f; do + imgs+=("$f") +done < <(find . -maxdepth 1 -type f -not -iname "*.txt" -not -iname "*.pp3" | sed "s_./__" | sort) + +abort () { + printf "%s\n" "" "Aborted" + exit 1 +} +trap 'abort' HUP INT QUIT ABRT TERM + +mkdir -p "$outDir" || exit 1 + +i=0 +for rtDir in "${rtDirs[@]}"; do + c=1 + pp3name=${pp3%.*} + pp3name=${pp3name#*/} + v+=("$(grep "Changeset:.*" "${rtDir}/AboutThisBuild.txt" | sed "s/Changeset: //")") + printf "%s\n" "Developing images using RawTherapee changeset ${v[$i]} - ${rtDir}" + for img in "${imgs[@]}"; do + printf "%s" "${c}/${#imgs[@]} - " + "${rtDir}rawtherapee" -o "${outDir}${img%.*}_${v[i]}_${pp3%.*}.tif" -p "${pp3}" -t -Y -c "$img" | grep Processing + ((c++)) + done + ((i++)) + echo +done +printf "%s\n" "Comparing images" +hash compare 2>/dev/null || { printf "%s\n" "\"compare\" not found." "Install imagemagick (or graphicsmagick if it has \"compare\"), then re-run this script."; exit 1; } +n=1 +for img in "${imgs[@]}"; do + printf "%s\n" "${n}/${c} - ${img}" + compare -quiet "${outDir}${img%.*}_${v[0]}_${pp3%.*}.tif" "${outDir}${img%.*}_${v[1]}_${pp3%.*}.tif" "${outDir}${img%.*}_compare.tif" + ((n++)) +done + +printf "%s\n" "" "${v[0]} is ${rtDirs[0]}" "${v[1]} is ${rtDirs[1]}" "Finished" diff --git a/tools/coordinate_system.svg b/tools/coordinate_system.svg new file mode 100644 index 000000000..73227e6ac --- /dev/null +++ b/tools/coordinate_system.svg @@ -0,0 +1,525 @@ + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + imgAreaW + imgAreaH + + + + leftBorder + + + + + + upperBorder + + + Requested processing image size (including processing borders) + Allocated processing image size (including possible processing border) + + Allocated pixbuf size for display (no extra border here!) + + + + + + + + + imgX + imgY + + + + + xpos + + + + ypos + + + imgX + + + + + imgY + + + + + CropWindow (mainCropWindow) + CropWindow + + diff --git a/tools/generateDirtyFiles b/tools/generateDirtyFiles new file mode 100755 index 000000000..28b95514b --- /dev/null +++ b/tools/generateDirtyFiles @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +# Search files for keywords, then do something to the files which don't match + +# Path to the RawTherapee repository +pushd $HOME/rawtherapee >/dev/null +unset uses match m u +# Key to search for, e.g. an include +IFS=" " read -a match <<< $(grep -rni iomanip rt* | cut -d ":" -f1 | sort -uV) +# Keys to search for which should be used by the one above, e.g. the functions given by the include +IFS=" " read -a uses <<< $(egrep -si "setiosflags|resetiosflags|setbase|setfill|setprecision|setw|get_money|put_money|get_time|put_time" rtgui/* rtengine/* rtexif/* | sed 's/ / /g' | cut -d ":" -f 1 | sort -Vu) +for m in ${match[@]}; do + for u in ${uses[@]}; do + if [[ $m == $u ]]; then + godmode=true; + fi + done + if [[ $godmode != true ]]; then +# Do something to the files which match the first key but not the second bunch of keys, e.g. remove the include from the files which don't use any of the functions it provides. + echo "$m to be cleaned" + sed -i '/#include /d' "$m" + fi + unset godmode +done +popd >/dev/null diff --git a/tools/generateReleaseInfo b/tools/generateReleaseInfo new file mode 100755 index 000000000..4b3d8f427 --- /dev/null +++ b/tools/generateReleaseInfo @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +hgBranch="`hg branch`" +hgLatesttag="`hg parents --template '{latesttag}'`" +hgLatesttagdistance="`hg parents --template '{latesttagdistance}'`" +hgChangeset="`hg parents --template '{node|short}'`" + +echo "set(HG_BRANCH $hgBranch) +set(HG_VERSION $hgLatesttag.$hgLatesttagdistance) +set(HG_CHANGESET $hgChangeset) +set(HG_TAGDISTANCE $hgLatesttagdistance)" > ReleaseInfo.cmake + diff --git a/tools/generateReleaseInfo.bat b/tools/generateReleaseInfo.bat new file mode 100644 index 000000000..a8ac1289e --- /dev/null +++ b/tools/generateReleaseInfo.bat @@ -0,0 +1,11 @@ +@echo off +for /f "tokens=*" %%a in ('hg branch') do @set hgBranch=%%a +for /f "tokens=*" %%a in ('hg parents --template "{latesttag}"') do @set hgLatesttag=%%a +for /f "tokens=*" %%a in ('hg parents --template "{latesttagdistance}"') do @set hgLatesttagdistance=%%a +for /f "tokens=*" %%a in ('hg parents --template "{node|short}"') do @set hgChangeset=%%a + +echo set(HG_BRANCH %hgBranch%) > ReleaseInfo.cmake +echo set(HG_VERSION %hgLatesttag%.%hgLatesttagdistance%) >> ReleaseInfo.cmake +echo set(HG_CHANGESET %hgChangeset%) >> ReleaseInfo.cmake +echo set(HG_TAGDISTANCE %hgLatesttagdistance%) >> ReleaseInfo.cmake + diff --git a/tools/generateSourceTarball b/tools/generateSourceTarball new file mode 100755 index 000000000..eb4688037 --- /dev/null +++ b/tools/generateSourceTarball @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +if [[ ! "$1" ]]; then + printf "%s\n" "Usage: $0 " "Example: $0 4.0.10" + exit +fi + +hg update "$1" +tools/generateReleaseInfo +mkdir rawtherapee-"$1" +mv ReleaseInfo.cmake rawtherapee-"$1" +hg archive -X ".hg*" -X "rtgui/config.h" -X "rtgui/version.h" -X "rtdata/rawtherapee.desktop" rawtherapee-"$1".tar +tar -rf rawtherapee-"$1".tar rawtherapee-"$1"/ReleaseInfo.cmake +xz -z -9e rawtherapee-"$1".tar +rm -r rawtherapee-"$1" +hg update diff --git a/tools/generateTranslationDiffs b/tools/generateTranslationDiffs new file mode 100755 index 000000000..437919117 --- /dev/null +++ b/tools/generateTranslationDiffs @@ -0,0 +1,123 @@ +#!/usr/bin/env bash + +# This script iterates through interface translation files, +# moves comments to the front, puts translated strings next, +# and finally looks for untranslated/missing strings by matching +# against "default" which it then adds to the translation, each +# line prepended by "!". +# +# Developers should run it from the project root after receiving +# a translation file from a translator: +# cp /tmp/new_japanese_translation rtdata/languages/Japanese +# ./tools/generateTranslationDiffs "Japanese" +# +# Running the script without an argument iterates through all files. +# +# Locale files are generated automatically: +# - English (UK) +# - Polish (Latin Characters) + +tmp=temp_file +if [[ -w $tmp ]]; then + rm -v "$tmp" +fi + +abort () { + printf "%s\n" "" "Aborting" + rm -v "$tmp" + exit 1 +} + +trap 'abort' HUP INT QUIT ABRT TERM + + +cd "rtdata/languages" || { printf "%s\n" "You must run this script from the root of the project."; exit 1; } +# Build array of all interface translation files, or use user-specified ones only +unset langFiles +if [[ $# = 0 ]]; then + while read -r; do + langFiles+=("$REPLY") + done < <(find . -not -iname "default" -not -iname "LICENSE" -not -iname "README" -not -iname "*.sh" -not -iname ".*" -not -iname "$tmp" -not -iname "English (UK)" -not -iname "Polish (Latin Characters)" | sort) +else + langFiles=("$@") + for langFile in "${langFiles[@]}"; do + if [[ ! -w $langFile ]]; then + printf "%s\n" "File \"$langFile\" not found or not writable." "" + exit 1 + fi + done +fi + +getComments () { + grep -E "^#.+" "$1" | sort -Vu +} + +getChanged () { + grep -Ev '^(!|#|$)' "$1" | sort -Vu +} + +getUnchanged () { + grep -E "^\!.+" "$1" | sort -Vu +} + +# First thing, fix default, so move comments to front, then strip the rest of any "!" and duplicates. +dos2unix default 2>/dev/null +getComments default > "$tmp" +getChanged default >> "$tmp" +mv "$tmp" "default" + +i=1 +printf "%s\n" "Digging through ${#langFiles[@]} file(s). This may take a while." +ttot1="$(date +%s)" +for file in "${langFiles[@]}"; do + t1="$(date +%s)" + printf "%02d - ${file#.*/}" "$i" + dos2unix "$file" 2>/dev/null + unset trLines newLines + # Fill trLines with translated text + trLines+=("$(getChanged "$file")") + + # KEY;String + # Match "default" keys with those in current translation file. If no match, add !KEY;String + while read -r 'defLine'; do + if [[ ! "${trLines[@]}" =~ "${defLine%%;*}" ]]; then + newLines+=("!${defLine}") + fi + done < <(getChanged default) + + # Form final translation file + if [[ -n "$(getComments "$file")" ]]; then + printf "%s\n" "$(getComments "$file")" "" >> "$tmp" + fi + if [[ -n "${trLines[@]}" ]]; then + printf "%s\n" "${trLines[@]}" "" >> "$tmp" + fi + if [[ -n "${newLines[@]}" ]]; then + printf "%s\n" "!!!!!!!!!!!!!!!!!!!!!!!!!" "! Untranslated keys follow; remove the ! prefix after an entry is translated." "!!!!!!!!!!!!!!!!!!!!!!!!!" "" "${newLines[@]}" >> "$tmp" + fi + mv "$tmp" "$file" + t2="$(date +%s)" + tt=$((t2-t1)) + printf "%s\n" " - took $tt seconds" + ((i++)) +done + +case "${langFiles[@]}" in + *"./English (US)"*) printf "%s\n" "Creating English (UK) file" + getComments "English (US)" > "English (UK)" + grep -Ei ".+;.*(color|behavior|center).*" default | \ + sed -e '/^#/d' -e 'h;s/^[^;]*;//; s/olor/olour/g; x;s/;.*//;G;s/\n/;/' \ + -e 'h;s/^[^;]*;//; s/ehavior/ehaviour/g; x;s/;.*//;G;s/\n/;/' \ + -e 'h;s/^[^;]*;//; s/center/centre/g; x;s/;.*//;G;s/\n/;/' \ + -e 'h;s/^[^;]*;//; s/Center/Centre/g; x;s/;.*//;G;s/\n/;/' >> English\ \(UK\) + grep -Evi ".+;.*(color|behavior|center).*" "English (US)" | grep -Ev "^#" >> "English (UK)" + ;;& + *"./Polish"*) printf "%s\n" "Creating Polish (Latin Characters) file" + sed 'y/ĄĆĘŁŃÓŚŹŻąćęłńóśźż/ACELNOSZZacelnoszz/' < Polish > "Polish (Latin Characters)" + ;;& +esac +ttot2="$(date +%s)" +ttot=$((ttot2-ttot1)) +tsec=$((ttot%60)) +tmin=$((ttot/60)) +printf "%s\n" "Finished updating ${#langFiles[@]} files." "Total time: ${tmin}m ${tsec}s" diff --git a/tools/generateUnusedKeys b/tools/generateUnusedKeys new file mode 100755 index 000000000..484da3667 --- /dev/null +++ b/tools/generateUnusedKeys @@ -0,0 +1,162 @@ +#!/usr/bin/env bash + +# This Bash4 script checks whether each key in "default" is used in +# a .cc or .h file. Those that are not are printed to screen, and the +# user is asked if they should be deleted from all language files. +# +# Keys in commented-out sections are treated as if they weren't there. +# The following comment styles are handled: +# // key +# /* key +# key */ + +# It does not handle dynamically built keys: +# HISTORY_MSG_ +# EXTPROGTARGET_ +# FILEBROWSER_POPUPRANK +# FILEBROWSER_POPUPCOLORLABEL +# +# The script can also clean up already-translated files by removing keys which +# do not exist in default. +# +# Run the script from the project root: +# ./tools/generateUnusedKeys +# +# Doublecheck the deletion before committing. +# Run ./tools/generateTranslationDiffs before and after running this script. +# +# Blame DrSlony +# Please report bugs or enhancements to http://code.google.com/p/rawtherapee/issues/list + +tmp=temp_file +if [[ -w $tmp ]]; then + rm -v "$tmp" +fi + +abort () { + printf '%s\n' "" "Aborted" "Removing leftover files:" + [[ -e "$tmp" ]] && rm "$tmp" + rm -v --interactive=once sed* + exit 1 +} + +trap 'abort' HUP INT QUIT ABRT TERM + +cd "rtdata/languages" || { printf '%s\n' "You must run this script from the root of the project."; exit 1; } +# Build array of all interface translation files, or use user-specified ones only +unset langFiles +if [[ $# = 0 ]]; then + while read -r; do + langFiles+=("$REPLY") + done < <(find . -not -iname "LICENSE" -not -iname "README" -not -iname "*.sh" -not -iname ".*" -not -iname "$tmp" | sort) +else + langFiles=("$@") + for langFile in "${langFiles[@]}"; do + if [[ ! -w $langFile ]]; then + printf '%s\n' "File \"$langFile\" not found or not writable." "" + exit 1 + fi + done +fi + +dos2unix default 2>/dev/null + +t1="$(date +%s)" +printf '%s\n' 'Matching keys in "default" against .cc and .h files' 'Unmatched keys follow:' +unset delLines +while read -r 'defLine'; do + grep -Ir --include=\*.{cc,h} --exclude-dir="klt" "${defLine%%;*}" ../../* | grep -Ev "//.*${defLine%%;*}|/\*.*${defLine%%;*}|${defLine%%;*}.*\*/" &>/dev/null + if [[ $? = 1 ]]; then + printf ' %s\n' "${defLine%%;*}" + delLines+=("${defLine%%;*}") + fi +done < <(grep -Ev "^(#|$)|HISTORY_MSG_" "default" | sed -e "s/EXTPROGTARGET_[0-9]*/EXTPROGTARGET_/" -e "s/FILEBROWSER_POPUPCOLORLABEL[0-9]*/FILEBROWSER_POPUPCOLORLABEL/" -e "s/FILEBROWSER_POPUPRANK[0-9]*/FILEBROWSER_POPUPRANK/" | sort -Vu) +# The grep/sed line above lists keys to ignore. Exit status 1 (failure) means +# key not found in code, destined for deletion. The piped grep in the loop +# checks the initial match for known comment markers // /* and */ +# Sometimes a key is first found in a comment, and then the same key is found +# in active code, therefore -m1 (stop reading after 1st match) cannot be used. +# To remove comment support, remove the piped grep and set first grep flags to +# -Irl -m1 +# Dynamically built keys like HISTORY_MSG_1 can't be grepped in the code, +# so it renames KEY_1-KEY_9 to KEY_ so that they can be grepped and therefore ignored. +# The piped grep in the loop +t2="$(date +%s)" +tt=$((t2-t1)) +printf '%s\n' "" "Scan took $tt seconds" "" "Double-checking the code for matched keys:" + +for delLine in "${delLines[@]}"; do + printf '%s\n' "$delLine" + grep -Ir --include=\*.{cc,h} --exclude-dir="klt" "${delLine}" ../../* +done +echo + +read -r -p 'Write results to "unmatched"? [y/n] ' +if [[ $REPLY = y || $REPLY = Y ]]; then + printf '%s\n' "${delLines[@]}" > unmatched +fi +printf '%s\n' "" + +read -r -p "Delete ${#delLines[@]} keys from all ${#langFiles[@]} interface language files? [y/n] " +if [[ $REPLY = y || $REPLY = Y ]]; then + printf '%s\n' "Removing keys from:" + i=1 + ttot1="$(date +%s)" + for file in "${langFiles[@]}"; do + printf "%02d - ${file#.*/}" "$i" + t1="$(date +%s)" + for key in "${delLines[@]}"; do + sed -i "/.\?$key/d" "$file" + done + t2="$(date +%s)" + tt=$((t2-t1)) + printf '%s\n' " - took $tt seconds" + ((i++)) + done + ttot2="$(date +%s)" + ttot=$((ttot2-ttot1)) + tsec=$((ttot%60)) + tmin=$((ttot/60)) + printf '%s\n' "Finished updating ${#langFiles[@]} files." "Total time: ${tmin}m ${tsec}s" +fi + +printf '%s\n' "" "The above cleaned up \"default\" from keys not found in the code and then it removed the same keys from the translation files. However if the translation files contain keys which were not in \"default\" then they would remain (because it would take too long to scan the source code for each key in each translation). Since at this point \"default\" is good as gold, it's most time efficient then to match each interface translation file against it and remove all keys not found in it." "" | fold -s +read -r -p "Match ${#langFiles[@]} interface translation files against \"default\" and delete unmatched keys? [y/n] " +if [[ $REPLY = y || $REPLY = Y ]]; then + printf '%s\n' "Removing keys from:" + i=1 + ttot1="$(date +%s)" + for file in "${langFiles[@]}"; do + printf "%02d - ${file#.*/}" "$i" + t1="$(date +%s)" + unset delLines + # Read line by line + while read -r line; do + # If line starts with a real key, not a comment or empty line + if [[ $line =~ ^[A-Z0-9_]+\; ]]; then + # then get the key part + key="${line%%;*}" + # quietly check whether it exists in default + grep -Irq "$key" default + # and if match fails, put it on the kill list + if [[ $? = 1 ]]; then + delLines+=("${key}") + fi + fi + done < "$file" + # kill szeva + for key in "${delLines[@]}"; do + sed -i "/.\?$key/d" "$file" + done + t2="$(date +%s)" + tt=$((t2-t1)) + printf '%s\n' " - took $tt seconds" + ((i++)) + done + ttot2="$(date +%s)" + ttot=$((ttot2-ttot1)) + tsec=$((ttot%60)) + tmin=$((ttot/60)) + printf '%s\n' "Finished updating ${#langFiles[@]} files." "Total time: ${tmin}m ${tsec}s" +fi + diff --git a/tools/source_icons/README b/tools/source_icons/README new file mode 100644 index 000000000..826b58b2b --- /dev/null +++ b/tools/source_icons/README @@ -0,0 +1,32 @@ +The repository tools/source_icons contains source icons (in SVG format) and the script to generate PNG icons for both Dark and Light themes. + +tools/source_icons/scalable +--------------------------- +- Contains icons in SVG format. +- A sidecar *.file for each *.svg file. +- The sidecar *.file has the following format: + -> Fields are separated by a comma. + -> The first field defines the PNG filename to be created. + -> The second field indicates either the width (e.g. w22) or the height (e.g. h16) in pixels for the PNG file. + -> The third field is optional. It indicates the icon category (e.g. actions, devices, places). If not indicated, the icon is assumed to belong to "actions". + +tools/source_icons/script +------------------------- +- The main script which creates the icons is make_all_icon_theme.bash +- Launch: + ./make_all_icon_theme.bash /path/to/new/svg/icons/ /tmp/png +- An archive with all the icons will be created in /tmp/png + +Guidelines for icon name +------------------------ +- Use stock item names when prebuilt icons exist (e.g. gtk-open.png). See http://developer.gnome.org/gtk/2.24/gtk-Stock-Items.html +- Use "-" to separate words (e.g. panel-to-left.png) +- Avoid the use of the icon's size as a suffix in the filename (colour.png and not colour-24.png). If needed, use the suffix -large or -small (gtk-close-small.png). + +How to easily work with new icons +--------------------------------- +1- Have a dir which contains only the new SVG files +2- Creates a .file for each .svg (change "w22" and "actions" as needed, explained above): + for f in *.svg; do printf "%s\n" "${f%%.*}.png,w22,actions" > "${f%%.*}.file"; done +3- Makes the PNG icons (you need to run the script from it's containing dir): + cd ~/rawtherapee/tools/source_icons/script && ./make_all_icon_theme.bash /path/to/new/svg/icons/ /tmp/png diff --git a/tools/source_icons/scalable/PanelEnding.file b/tools/source_icons/scalable/PanelEnding.file new file mode 100644 index 000000000..70f44222b --- /dev/null +++ b/tools/source_icons/scalable/PanelEnding.file @@ -0,0 +1 @@ +PanelEnding.png,h28,actions diff --git a/tools/source_icons/scalable/PanelEnding.svg b/tools/source_icons/scalable/PanelEnding.svg new file mode 100644 index 000000000..18d756b8c --- /dev/null +++ b/tools/source_icons/scalable/PanelEnding.svg @@ -0,0 +1,801 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Created by potrace 1.8, written by Peter Selinger 2001-2007 + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/beforeafter.file b/tools/source_icons/scalable/beforeafter.file new file mode 100644 index 000000000..dc6d27251 --- /dev/null +++ b/tools/source_icons/scalable/beforeafter.file @@ -0,0 +1 @@ +beforeafter.png,w22,actions diff --git a/tools/source_icons/scalable/beforeafter.svg b/tools/source_icons/scalable/beforeafter.svg new file mode 100644 index 000000000..0e45b9d06 --- /dev/null +++ b/tools/source_icons/scalable/beforeafter.svg @@ -0,0 +1,532 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/cglabel0.file b/tools/source_icons/scalable/cglabel0.file new file mode 100644 index 000000000..a8b3d6f7e --- /dev/null +++ b/tools/source_icons/scalable/cglabel0.file @@ -0,0 +1 @@ +cglabel0.png,h10,actions diff --git a/tools/source_icons/scalable/cglabel0.svg b/tools/source_icons/scalable/cglabel0.svg new file mode 100644 index 000000000..cbb4ee903 --- /dev/null +++ b/tools/source_icons/scalable/cglabel0.svg @@ -0,0 +1,624 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/cglabel1.file b/tools/source_icons/scalable/cglabel1.file new file mode 100644 index 000000000..82cf9fad5 --- /dev/null +++ b/tools/source_icons/scalable/cglabel1.file @@ -0,0 +1 @@ +cglabel1.png,h10,actions diff --git a/tools/source_icons/scalable/cglabel1.svg b/tools/source_icons/scalable/cglabel1.svg new file mode 100644 index 000000000..96172577c --- /dev/null +++ b/tools/source_icons/scalable/cglabel1.svg @@ -0,0 +1,623 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/cglabel2.file b/tools/source_icons/scalable/cglabel2.file new file mode 100644 index 000000000..c7b1dc8a3 --- /dev/null +++ b/tools/source_icons/scalable/cglabel2.file @@ -0,0 +1 @@ +cglabel2.png,h10,actions diff --git a/tools/source_icons/scalable/cglabel2.svg b/tools/source_icons/scalable/cglabel2.svg new file mode 100644 index 000000000..eb5fc9a08 --- /dev/null +++ b/tools/source_icons/scalable/cglabel2.svg @@ -0,0 +1,630 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/cglabel3.file b/tools/source_icons/scalable/cglabel3.file new file mode 100644 index 000000000..5c5bd5eb5 --- /dev/null +++ b/tools/source_icons/scalable/cglabel3.file @@ -0,0 +1 @@ +cglabel3.png,h10,actions diff --git a/tools/source_icons/scalable/cglabel3.svg b/tools/source_icons/scalable/cglabel3.svg new file mode 100644 index 000000000..5e9b6a72c --- /dev/null +++ b/tools/source_icons/scalable/cglabel3.svg @@ -0,0 +1,623 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/cglabel4.file b/tools/source_icons/scalable/cglabel4.file new file mode 100644 index 000000000..ce7c74532 --- /dev/null +++ b/tools/source_icons/scalable/cglabel4.file @@ -0,0 +1 @@ +cglabel4.png,h10,actions diff --git a/tools/source_icons/scalable/cglabel4.svg b/tools/source_icons/scalable/cglabel4.svg new file mode 100644 index 000000000..8f98c5284 --- /dev/null +++ b/tools/source_icons/scalable/cglabel4.svg @@ -0,0 +1,623 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/cglabel5.file b/tools/source_icons/scalable/cglabel5.file new file mode 100644 index 000000000..f0a6a447b --- /dev/null +++ b/tools/source_icons/scalable/cglabel5.file @@ -0,0 +1 @@ +cglabel5.png,h10,actions diff --git a/tools/source_icons/scalable/cglabel5.svg b/tools/source_icons/scalable/cglabel5.svg new file mode 100644 index 000000000..829d41604 --- /dev/null +++ b/tools/source_icons/scalable/cglabel5.svg @@ -0,0 +1,623 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/clabel0.file b/tools/source_icons/scalable/clabel0.file new file mode 100644 index 000000000..05789c9b6 --- /dev/null +++ b/tools/source_icons/scalable/clabel0.file @@ -0,0 +1 @@ +clabel0.png,h10,actions diff --git a/tools/source_icons/scalable/clabel0.svg b/tools/source_icons/scalable/clabel0.svg new file mode 100644 index 000000000..4aef0c70c --- /dev/null +++ b/tools/source_icons/scalable/clabel0.svg @@ -0,0 +1,625 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/clabel1.file b/tools/source_icons/scalable/clabel1.file new file mode 100644 index 000000000..ee2bd7652 --- /dev/null +++ b/tools/source_icons/scalable/clabel1.file @@ -0,0 +1 @@ +clabel1.png,h10,actions diff --git a/tools/source_icons/scalable/clabel1.svg b/tools/source_icons/scalable/clabel1.svg new file mode 100644 index 000000000..5b7046f05 --- /dev/null +++ b/tools/source_icons/scalable/clabel1.svg @@ -0,0 +1,681 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/clabel2.file b/tools/source_icons/scalable/clabel2.file new file mode 100644 index 000000000..fe6f470ff --- /dev/null +++ b/tools/source_icons/scalable/clabel2.file @@ -0,0 +1 @@ +clabel2.png,h10,actions diff --git a/tools/source_icons/scalable/clabel2.svg b/tools/source_icons/scalable/clabel2.svg new file mode 100644 index 000000000..fa363f6a3 --- /dev/null +++ b/tools/source_icons/scalable/clabel2.svg @@ -0,0 +1,681 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/clabel3.file b/tools/source_icons/scalable/clabel3.file new file mode 100644 index 000000000..e80189869 --- /dev/null +++ b/tools/source_icons/scalable/clabel3.file @@ -0,0 +1 @@ +clabel3.png,h10,actions diff --git a/tools/source_icons/scalable/clabel3.svg b/tools/source_icons/scalable/clabel3.svg new file mode 100644 index 000000000..311083bd6 --- /dev/null +++ b/tools/source_icons/scalable/clabel3.svg @@ -0,0 +1,681 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/clabel4.file b/tools/source_icons/scalable/clabel4.file new file mode 100644 index 000000000..b15df7ca9 --- /dev/null +++ b/tools/source_icons/scalable/clabel4.file @@ -0,0 +1 @@ +clabel4.png,h10,actions diff --git a/tools/source_icons/scalable/clabel4.svg b/tools/source_icons/scalable/clabel4.svg new file mode 100644 index 000000000..e18b8dc54 --- /dev/null +++ b/tools/source_icons/scalable/clabel4.svg @@ -0,0 +1,681 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/clabel5.file b/tools/source_icons/scalable/clabel5.file new file mode 100644 index 000000000..317abad4b --- /dev/null +++ b/tools/source_icons/scalable/clabel5.file @@ -0,0 +1 @@ +clabel5.png,h10,actions diff --git a/tools/source_icons/scalable/clabel5.svg b/tools/source_icons/scalable/clabel5.svg new file mode 100644 index 000000000..986911fa8 --- /dev/null +++ b/tools/source_icons/scalable/clabel5.svg @@ -0,0 +1,681 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/closedhand.file b/tools/source_icons/scalable/closedhand.file new file mode 100644 index 000000000..d1f705e03 --- /dev/null +++ b/tools/source_icons/scalable/closedhand.file @@ -0,0 +1 @@ +closedhand.png,w22,actions diff --git a/tools/source_icons/scalable/closedhand.svg b/tools/source_icons/scalable/closedhand.svg new file mode 100644 index 000000000..e6d9727f5 --- /dev/null +++ b/tools/source_icons/scalable/closedhand.svg @@ -0,0 +1,1317 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/tools/source_icons/scalable/colour.file b/tools/source_icons/scalable/colour.file new file mode 100644 index 000000000..ca546e7bc --- /dev/null +++ b/tools/source_icons/scalable/colour.file @@ -0,0 +1 @@ +colour.png,w24,actions diff --git a/tools/source_icons/scalable/colour.svg b/tools/source_icons/scalable/colour.svg new file mode 100644 index 000000000..27b160e49 --- /dev/null +++ b/tools/source_icons/scalable/colour.svg @@ -0,0 +1,855 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/crop-auto.file b/tools/source_icons/scalable/crop-auto.file new file mode 100644 index 000000000..d642c35b1 --- /dev/null +++ b/tools/source_icons/scalable/crop-auto.file @@ -0,0 +1 @@ +crop-auto.png,h18,actions diff --git a/tools/source_icons/scalable/crop-auto.svg b/tools/source_icons/scalable/crop-auto.svg new file mode 100644 index 000000000..9aab86fa9 --- /dev/null +++ b/tools/source_icons/scalable/crop-auto.svg @@ -0,0 +1,464 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/crop.file b/tools/source_icons/scalable/crop.file new file mode 100644 index 000000000..d0dbe770f --- /dev/null +++ b/tools/source_icons/scalable/crop.file @@ -0,0 +1 @@ +crop.png,w22,actions diff --git a/tools/source_icons/scalable/crop.svg b/tools/source_icons/scalable/crop.svg new file mode 100644 index 000000000..c25a302d0 --- /dev/null +++ b/tools/source_icons/scalable/crop.svg @@ -0,0 +1,361 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/crossCursor.svg b/tools/source_icons/scalable/crossCursor.svg new file mode 100644 index 000000000..3ae8ab282 --- /dev/null +++ b/tools/source_icons/scalable/crossCursor.svg @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/tools/source_icons/scalable/crossed-arrows-in.file b/tools/source_icons/scalable/crossed-arrows-in.file new file mode 100644 index 000000000..8405de976 --- /dev/null +++ b/tools/source_icons/scalable/crossed-arrows-in.file @@ -0,0 +1 @@ +crossed-arrows-in.png,w22,actions diff --git a/tools/source_icons/scalable/crossed-arrows-in.svg b/tools/source_icons/scalable/crossed-arrows-in.svg new file mode 100644 index 000000000..56c346d18 --- /dev/null +++ b/tools/source_icons/scalable/crossed-arrows-in.svg @@ -0,0 +1,424 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/crossed-arrows-out.file b/tools/source_icons/scalable/crossed-arrows-out.file new file mode 100644 index 000000000..efb263648 --- /dev/null +++ b/tools/source_icons/scalable/crossed-arrows-out.file @@ -0,0 +1 @@ +crossed-arrows-out.png,w22,actions diff --git a/tools/source_icons/scalable/crossed-arrows-out.svg b/tools/source_icons/scalable/crossed-arrows-out.svg new file mode 100644 index 000000000..dd9269923 --- /dev/null +++ b/tools/source_icons/scalable/crossed-arrows-out.svg @@ -0,0 +1,470 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/curveType-NURBS.file b/tools/source_icons/scalable/curveType-NURBS.file new file mode 100644 index 000000000..e283505d8 --- /dev/null +++ b/tools/source_icons/scalable/curveType-NURBS.file @@ -0,0 +1 @@ +curveType-NURBS.png,w18,actions diff --git a/tools/source_icons/scalable/curveType-NURBS.svg b/tools/source_icons/scalable/curveType-NURBS.svg new file mode 100644 index 000000000..3a8624355 --- /dev/null +++ b/tools/source_icons/scalable/curveType-NURBS.svg @@ -0,0 +1,630 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/curveType-controlPoints.file b/tools/source_icons/scalable/curveType-controlPoints.file new file mode 100644 index 000000000..5a904de85 --- /dev/null +++ b/tools/source_icons/scalable/curveType-controlPoints.file @@ -0,0 +1 @@ +curveType-controlPoints.png,w18,actions diff --git a/tools/source_icons/scalable/curveType-controlPoints.svg b/tools/source_icons/scalable/curveType-controlPoints.svg new file mode 100644 index 000000000..6e5e1f6ec --- /dev/null +++ b/tools/source_icons/scalable/curveType-controlPoints.svg @@ -0,0 +1,773 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/curveType-flatLinear.file b/tools/source_icons/scalable/curveType-flatLinear.file new file mode 100644 index 000000000..f4bfb52f9 --- /dev/null +++ b/tools/source_icons/scalable/curveType-flatLinear.file @@ -0,0 +1 @@ +curveType-flatLinear.png,w18,actions diff --git a/tools/source_icons/scalable/curveType-flatLinear.svg b/tools/source_icons/scalable/curveType-flatLinear.svg new file mode 100644 index 000000000..e4923d637 --- /dev/null +++ b/tools/source_icons/scalable/curveType-flatLinear.svg @@ -0,0 +1,777 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/curveType-linear.file b/tools/source_icons/scalable/curveType-linear.file new file mode 100644 index 000000000..adceccc33 --- /dev/null +++ b/tools/source_icons/scalable/curveType-linear.file @@ -0,0 +1 @@ +curveType-linear.png,w18,actions diff --git a/tools/source_icons/scalable/curveType-linear.svg b/tools/source_icons/scalable/curveType-linear.svg new file mode 100644 index 000000000..8ae43977c --- /dev/null +++ b/tools/source_icons/scalable/curveType-linear.svg @@ -0,0 +1,583 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/curveType-parametric.file b/tools/source_icons/scalable/curveType-parametric.file new file mode 100644 index 000000000..f7cc51e7b --- /dev/null +++ b/tools/source_icons/scalable/curveType-parametric.file @@ -0,0 +1 @@ +curveType-parametric.png,w18,actions diff --git a/tools/source_icons/scalable/curveType-parametric.svg b/tools/source_icons/scalable/curveType-parametric.svg new file mode 100644 index 000000000..2d11b90da --- /dev/null +++ b/tools/source_icons/scalable/curveType-parametric.svg @@ -0,0 +1,595 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/curveType-spline.file b/tools/source_icons/scalable/curveType-spline.file new file mode 100644 index 000000000..4c64e10c9 --- /dev/null +++ b/tools/source_icons/scalable/curveType-spline.file @@ -0,0 +1 @@ +curveType-spline.png,w18,actions diff --git a/tools/source_icons/scalable/curveType-spline.svg b/tools/source_icons/scalable/curveType-spline.svg new file mode 100644 index 000000000..a24b7ae9c --- /dev/null +++ b/tools/source_icons/scalable/curveType-spline.svg @@ -0,0 +1,629 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/detail.file b/tools/source_icons/scalable/detail.file new file mode 100644 index 000000000..a82843776 --- /dev/null +++ b/tools/source_icons/scalable/detail.file @@ -0,0 +1 @@ +detail.png,w24,actions diff --git a/tools/source_icons/scalable/detail.svg b/tools/source_icons/scalable/detail.svg new file mode 100644 index 000000000..7910c1492 --- /dev/null +++ b/tools/source_icons/scalable/detail.svg @@ -0,0 +1,5185 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/distorsion.file b/tools/source_icons/scalable/distorsion.file new file mode 100644 index 000000000..881efa97a --- /dev/null +++ b/tools/source_icons/scalable/distorsion.file @@ -0,0 +1 @@ +distorsion.png,w22,actions diff --git a/tools/source_icons/scalable/distorsion.svg b/tools/source_icons/scalable/distorsion.svg new file mode 100644 index 000000000..3be8206b3 --- /dev/null +++ b/tools/source_icons/scalable/distorsion.svg @@ -0,0 +1,1056 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/distortion-auto.file b/tools/source_icons/scalable/distortion-auto.file new file mode 100644 index 000000000..06f4a0745 --- /dev/null +++ b/tools/source_icons/scalable/distortion-auto.file @@ -0,0 +1 @@ +distortion-auto.png,h18,actions diff --git a/tools/source_icons/scalable/distortion-auto.svg b/tools/source_icons/scalable/distortion-auto.svg new file mode 100644 index 000000000..a36ee2f34 --- /dev/null +++ b/tools/source_icons/scalable/distortion-auto.svg @@ -0,0 +1,1068 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/distortion-barrel.file b/tools/source_icons/scalable/distortion-barrel.file new file mode 100644 index 000000000..555f27f5d --- /dev/null +++ b/tools/source_icons/scalable/distortion-barrel.file @@ -0,0 +1 @@ +distortion-barrel.png,w22,actions diff --git a/tools/source_icons/scalable/distortion-barrel.svg b/tools/source_icons/scalable/distortion-barrel.svg new file mode 100644 index 000000000..fe76c60c3 --- /dev/null +++ b/tools/source_icons/scalable/distortion-barrel.svg @@ -0,0 +1,1150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/distortion-pincushion.file b/tools/source_icons/scalable/distortion-pincushion.file new file mode 100644 index 000000000..56807fba7 --- /dev/null +++ b/tools/source_icons/scalable/distortion-pincushion.file @@ -0,0 +1 @@ +distortion-pincushion.png,w22,actions diff --git a/tools/source_icons/scalable/distortion-pincushion.svg b/tools/source_icons/scalable/distortion-pincushion.svg new file mode 100644 index 000000000..0a5efed14 --- /dev/null +++ b/tools/source_icons/scalable/distortion-pincushion.svg @@ -0,0 +1,1149 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/distortion.file b/tools/source_icons/scalable/distortion.file new file mode 100644 index 000000000..46b17a564 --- /dev/null +++ b/tools/source_icons/scalable/distortion.file @@ -0,0 +1 @@ +distortion.png,w22,actions diff --git a/tools/source_icons/scalable/distortion.svg b/tools/source_icons/scalable/distortion.svg new file mode 100644 index 000000000..3be8206b3 --- /dev/null +++ b/tools/source_icons/scalable/distortion.svg @@ -0,0 +1,1056 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/document-open-recent.file b/tools/source_icons/scalable/document-open-recent.file new file mode 100644 index 000000000..2eb27f8b5 --- /dev/null +++ b/tools/source_icons/scalable/document-open-recent.file @@ -0,0 +1 @@ +document-open-recent.png,h18,actions diff --git a/tools/source_icons/scalable/document-open-recent.svg b/tools/source_icons/scalable/document-open-recent.svg new file mode 100644 index 000000000..978b28c3f --- /dev/null +++ b/tools/source_icons/scalable/document-open-recent.svg @@ -0,0 +1,1643 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/drive-harddisk.file b/tools/source_icons/scalable/drive-harddisk.file new file mode 100644 index 000000000..b50693e40 --- /dev/null +++ b/tools/source_icons/scalable/drive-harddisk.file @@ -0,0 +1,4 @@ +drive-harddisk.png,h18,devices +computer.png,h18,devices +media-flash.png,h18,devices +media-tape.png,h18,devices diff --git a/tools/source_icons/scalable/drive-harddisk.svg b/tools/source_icons/scalable/drive-harddisk.svg new file mode 100644 index 000000000..f548c5671 --- /dev/null +++ b/tools/source_icons/scalable/drive-harddisk.svg @@ -0,0 +1,2582 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/drive-optical.file b/tools/source_icons/scalable/drive-optical.file new file mode 100644 index 000000000..3054e2a2e --- /dev/null +++ b/tools/source_icons/scalable/drive-optical.file @@ -0,0 +1,5 @@ +gtk-cdrom.png,h18,devices +media-optical.png,h18,devices +drive-optical.png,h18,devices +media-optical-bd.png,h18,devices +media-optical-dvd.png,h18,devices diff --git a/tools/source_icons/scalable/drive-optical.svg b/tools/source_icons/scalable/drive-optical.svg new file mode 100644 index 000000000..b27e6d194 --- /dev/null +++ b/tools/source_icons/scalable/drive-optical.svg @@ -0,0 +1,1388 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/edited.file b/tools/source_icons/scalable/edited.file new file mode 100644 index 000000000..95b77b754 --- /dev/null +++ b/tools/source_icons/scalable/edited.file @@ -0,0 +1,2 @@ +edited.png,w18,actions +edited-small.png,h10,actions diff --git a/tools/source_icons/scalable/edited.svg b/tools/source_icons/scalable/edited.svg new file mode 100644 index 000000000..0126b05d8 --- /dev/null +++ b/tools/source_icons/scalable/edited.svg @@ -0,0 +1,785 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/editedg.file b/tools/source_icons/scalable/editedg.file new file mode 100644 index 000000000..49951f9b9 --- /dev/null +++ b/tools/source_icons/scalable/editedg.file @@ -0,0 +1 @@ +editedg-small.png,h10,actions diff --git a/tools/source_icons/scalable/editedg.svg b/tools/source_icons/scalable/editedg.svg new file mode 100644 index 000000000..578ecfa7e --- /dev/null +++ b/tools/source_icons/scalable/editedg.svg @@ -0,0 +1,753 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/editednot.file b/tools/source_icons/scalable/editednot.file new file mode 100644 index 000000000..d4d663433 --- /dev/null +++ b/tools/source_icons/scalable/editednot.file @@ -0,0 +1 @@ +editednot-small.png,h10,actions diff --git a/tools/source_icons/scalable/editednot.svg b/tools/source_icons/scalable/editednot.svg new file mode 100644 index 000000000..c286de2dc --- /dev/null +++ b/tools/source_icons/scalable/editednot.svg @@ -0,0 +1,761 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/editednotg.file b/tools/source_icons/scalable/editednotg.file new file mode 100644 index 000000000..4e6ac8b28 --- /dev/null +++ b/tools/source_icons/scalable/editednotg.file @@ -0,0 +1 @@ +editednotg-small.png,h10,actions diff --git a/tools/source_icons/scalable/editednotg.svg b/tools/source_icons/scalable/editednotg.svg new file mode 100644 index 000000000..6c51de9cf --- /dev/null +++ b/tools/source_icons/scalable/editednotg.svg @@ -0,0 +1,893 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/editmodehand.file b/tools/source_icons/scalable/editmodehand.file new file mode 100644 index 000000000..93df595c9 --- /dev/null +++ b/tools/source_icons/scalable/editmodehand.file @@ -0,0 +1 @@ +editmodehand.png,w22,actions diff --git a/tools/source_icons/scalable/editmodehand.svg b/tools/source_icons/scalable/editmodehand.svg new file mode 100644 index 000000000..9a9898e68 --- /dev/null +++ b/tools/source_icons/scalable/editmodehand.svg @@ -0,0 +1,581 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/tools/source_icons/scalable/expanderClosed.file b/tools/source_icons/scalable/expanderClosed.file new file mode 100644 index 000000000..039041106 --- /dev/null +++ b/tools/source_icons/scalable/expanderClosed.file @@ -0,0 +1 @@ +expanderClosed.png,w18,actions diff --git a/tools/source_icons/scalable/expanderClosed.svg b/tools/source_icons/scalable/expanderClosed.svg new file mode 100644 index 000000000..ca47969f8 --- /dev/null +++ b/tools/source_icons/scalable/expanderClosed.svg @@ -0,0 +1,738 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/expanderDisabled.file b/tools/source_icons/scalable/expanderDisabled.file new file mode 100644 index 000000000..e2cc81d31 --- /dev/null +++ b/tools/source_icons/scalable/expanderDisabled.file @@ -0,0 +1 @@ +expanderDisabled.png,w18,actions diff --git a/tools/source_icons/scalable/expanderDisabled.svg b/tools/source_icons/scalable/expanderDisabled.svg new file mode 100644 index 000000000..1826d71f7 --- /dev/null +++ b/tools/source_icons/scalable/expanderDisabled.svg @@ -0,0 +1,634 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/expanderEnabled.file b/tools/source_icons/scalable/expanderEnabled.file new file mode 100644 index 000000000..790e109da --- /dev/null +++ b/tools/source_icons/scalable/expanderEnabled.file @@ -0,0 +1 @@ +expanderEnabled.png,w18,actions diff --git a/tools/source_icons/scalable/expanderEnabled.svg b/tools/source_icons/scalable/expanderEnabled.svg new file mode 100644 index 000000000..1407ca335 --- /dev/null +++ b/tools/source_icons/scalable/expanderEnabled.svg @@ -0,0 +1,698 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/expanderInconsistent.file b/tools/source_icons/scalable/expanderInconsistent.file new file mode 100644 index 000000000..0ce1f9a2e --- /dev/null +++ b/tools/source_icons/scalable/expanderInconsistent.file @@ -0,0 +1 @@ +expanderInconsistent.png,w18,actions diff --git a/tools/source_icons/scalable/expanderInconsistent.svg b/tools/source_icons/scalable/expanderInconsistent.svg new file mode 100644 index 000000000..167b86b66 --- /dev/null +++ b/tools/source_icons/scalable/expanderInconsistent.svg @@ -0,0 +1,1243 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/expanderOpened.file b/tools/source_icons/scalable/expanderOpened.file new file mode 100644 index 000000000..c2175efad --- /dev/null +++ b/tools/source_icons/scalable/expanderOpened.file @@ -0,0 +1 @@ +expanderOpened.png,w18,actions diff --git a/tools/source_icons/scalable/expanderOpened.svg b/tools/source_icons/scalable/expanderOpened.svg new file mode 100644 index 000000000..c00fe2d85 --- /dev/null +++ b/tools/source_icons/scalable/expanderOpened.svg @@ -0,0 +1,748 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/exposure.file b/tools/source_icons/scalable/exposure.file new file mode 100644 index 000000000..0d166322a --- /dev/null +++ b/tools/source_icons/scalable/exposure.file @@ -0,0 +1 @@ +exposure.png,w24,actions diff --git a/tools/source_icons/scalable/exposure.svg b/tools/source_icons/scalable/exposure.svg new file mode 100644 index 000000000..e1a029520 --- /dev/null +++ b/tools/source_icons/scalable/exposure.svg @@ -0,0 +1,668 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/filter.file b/tools/source_icons/scalable/filter.file new file mode 100644 index 000000000..06d8465ab --- /dev/null +++ b/tools/source_icons/scalable/filter.file @@ -0,0 +1 @@ +filter.png,w22,actions diff --git a/tools/source_icons/scalable/filter.svg b/tools/source_icons/scalable/filter.svg new file mode 100644 index 000000000..c29442938 --- /dev/null +++ b/tools/source_icons/scalable/filter.svg @@ -0,0 +1,1198 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/filterclear.file b/tools/source_icons/scalable/filterclear.file new file mode 100644 index 000000000..00636c71c --- /dev/null +++ b/tools/source_icons/scalable/filterclear.file @@ -0,0 +1 @@ +filterclear.png,w22,actions diff --git a/tools/source_icons/scalable/filterclear.svg b/tools/source_icons/scalable/filterclear.svg new file mode 100644 index 000000000..367c0de73 --- /dev/null +++ b/tools/source_icons/scalable/filterclear.svg @@ -0,0 +1,1263 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/grayrated.file b/tools/source_icons/scalable/grayrated.file new file mode 100644 index 000000000..5b2be3e7f --- /dev/null +++ b/tools/source_icons/scalable/grayrated.file @@ -0,0 +1 @@ +grayrated.png,h10,actions diff --git a/tools/source_icons/scalable/grayrated.svg b/tools/source_icons/scalable/grayrated.svg new file mode 100644 index 000000000..66eb88a7b --- /dev/null +++ b/tools/source_icons/scalable/grayrated.svg @@ -0,0 +1,645 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/gtk-add.file b/tools/source_icons/scalable/gtk-add.file new file mode 100644 index 000000000..24df258a3 --- /dev/null +++ b/tools/source_icons/scalable/gtk-add.file @@ -0,0 +1,3 @@ +list-add.png,w16,actions +gtk-add.png,w16,actions +list-add-small.png,w12,actions diff --git a/tools/source_icons/scalable/gtk-add.svg b/tools/source_icons/scalable/gtk-add.svg new file mode 100644 index 000000000..16cc1a352 --- /dev/null +++ b/tools/source_icons/scalable/gtk-add.svg @@ -0,0 +1,636 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/gtk-apply.file b/tools/source_icons/scalable/gtk-apply.file new file mode 100644 index 000000000..a319cbc75 --- /dev/null +++ b/tools/source_icons/scalable/gtk-apply.file @@ -0,0 +1,2 @@ +gtk-apply.png,w16,actions +gtk-ok.png,w16,actions diff --git a/tools/source_icons/scalable/gtk-apply.svg b/tools/source_icons/scalable/gtk-apply.svg new file mode 100644 index 000000000..c3e79f8a1 --- /dev/null +++ b/tools/source_icons/scalable/gtk-apply.svg @@ -0,0 +1,760 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/gtk-cancel.file b/tools/source_icons/scalable/gtk-cancel.file new file mode 100644 index 000000000..92d2ea411 --- /dev/null +++ b/tools/source_icons/scalable/gtk-cancel.file @@ -0,0 +1 @@ +gtk-cancel.png.old,h16,actions diff --git a/tools/source_icons/scalable/gtk-cancel.svg b/tools/source_icons/scalable/gtk-cancel.svg new file mode 100644 index 000000000..8c4529dd7 --- /dev/null +++ b/tools/source_icons/scalable/gtk-cancel.svg @@ -0,0 +1,705 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/gtk-close.file b/tools/source_icons/scalable/gtk-close.file new file mode 100644 index 000000000..bc92ba643 --- /dev/null +++ b/tools/source_icons/scalable/gtk-close.file @@ -0,0 +1,3 @@ +gtk-close.png,w16,actions +gtk-close-small.png,h13,actions +gtk-cancel.png,h16,actions diff --git a/tools/source_icons/scalable/gtk-close.svg b/tools/source_icons/scalable/gtk-close.svg new file mode 100644 index 000000000..0cb1d4711 --- /dev/null +++ b/tools/source_icons/scalable/gtk-close.svg @@ -0,0 +1,636 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/gtk-color-picker.file b/tools/source_icons/scalable/gtk-color-picker.file new file mode 100644 index 000000000..d17a0648a --- /dev/null +++ b/tools/source_icons/scalable/gtk-color-picker.file @@ -0,0 +1,2 @@ +gtk-color-picker.png,w22,actions +gtk-color-picker-small.png,h18,actions diff --git a/tools/source_icons/scalable/gtk-color-picker.svg b/tools/source_icons/scalable/gtk-color-picker.svg new file mode 100644 index 000000000..5a0591bb0 --- /dev/null +++ b/tools/source_icons/scalable/gtk-color-picker.svg @@ -0,0 +1,4834 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/gtk-copy.file b/tools/source_icons/scalable/gtk-copy.file new file mode 100644 index 000000000..6c4bec508 --- /dev/null +++ b/tools/source_icons/scalable/gtk-copy.file @@ -0,0 +1,2 @@ +edit-copy.png,w22,actions +gtk-copy.png,w22,actions diff --git a/tools/source_icons/scalable/gtk-copy.svg b/tools/source_icons/scalable/gtk-copy.svg new file mode 100644 index 000000000..e3dafc549 --- /dev/null +++ b/tools/source_icons/scalable/gtk-copy.svg @@ -0,0 +1,727 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/gtk-delete.file b/tools/source_icons/scalable/gtk-delete.file new file mode 100644 index 000000000..c73446d0a --- /dev/null +++ b/tools/source_icons/scalable/gtk-delete.file @@ -0,0 +1,2 @@ +trash.png,w22,actions +trash-show-empty.png,w22,actions diff --git a/tools/source_icons/scalable/gtk-delete.svg b/tools/source_icons/scalable/gtk-delete.svg new file mode 100644 index 000000000..c3f85b1d9 --- /dev/null +++ b/tools/source_icons/scalable/gtk-delete.svg @@ -0,0 +1,862 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/gtk-directory.file b/tools/source_icons/scalable/gtk-directory.file new file mode 100644 index 000000000..85e55324b --- /dev/null +++ b/tools/source_icons/scalable/gtk-directory.file @@ -0,0 +1,2 @@ +folder.png,h18,places +gtk-directory.png,h18,places diff --git a/tools/source_icons/scalable/gtk-directory.svg b/tools/source_icons/scalable/gtk-directory.svg new file mode 100644 index 000000000..493ed2f3c --- /dev/null +++ b/tools/source_icons/scalable/gtk-directory.svg @@ -0,0 +1,1586 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/gtk-edit.file b/tools/source_icons/scalable/gtk-edit.file new file mode 100644 index 000000000..4dcec3be2 --- /dev/null +++ b/tools/source_icons/scalable/gtk-edit.file @@ -0,0 +1 @@ +gtk-edit.png,h18,actions diff --git a/tools/source_icons/scalable/gtk-edit.svg b/tools/source_icons/scalable/gtk-edit.svg new file mode 100644 index 000000000..2ec58e4e7 --- /dev/null +++ b/tools/source_icons/scalable/gtk-edit.svg @@ -0,0 +1,681 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/gtk-execute.file b/tools/source_icons/scalable/gtk-execute.file new file mode 100644 index 000000000..d7c02b31d --- /dev/null +++ b/tools/source_icons/scalable/gtk-execute.file @@ -0,0 +1 @@ +processing.png,w20,actions diff --git a/tools/source_icons/scalable/gtk-execute.svg b/tools/source_icons/scalable/gtk-execute.svg new file mode 100644 index 000000000..f54159c69 --- /dev/null +++ b/tools/source_icons/scalable/gtk-execute.svg @@ -0,0 +1,409 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/gtk-file.file b/tools/source_icons/scalable/gtk-file.file new file mode 100644 index 000000000..a50463a1d --- /dev/null +++ b/tools/source_icons/scalable/gtk-file.file @@ -0,0 +1 @@ +rtwindow.png,w20,actions diff --git a/tools/source_icons/scalable/gtk-file.svg b/tools/source_icons/scalable/gtk-file.svg new file mode 100644 index 000000000..76bc44c89 --- /dev/null +++ b/tools/source_icons/scalable/gtk-file.svg @@ -0,0 +1,2735 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/gtk-find.file b/tools/source_icons/scalable/gtk-find.file new file mode 100644 index 000000000..2ca2b36a0 --- /dev/null +++ b/tools/source_icons/scalable/gtk-find.file @@ -0,0 +1,2 @@ +gtk-find.png,h18,actions +edit-find.png,h18,actions diff --git a/tools/source_icons/scalable/gtk-find.svg b/tools/source_icons/scalable/gtk-find.svg new file mode 100644 index 000000000..70fe453ea --- /dev/null +++ b/tools/source_icons/scalable/gtk-find.svg @@ -0,0 +1,580 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/gtk-fullscreen.file b/tools/source_icons/scalable/gtk-fullscreen.file new file mode 100644 index 000000000..320e0e84b --- /dev/null +++ b/tools/source_icons/scalable/gtk-fullscreen.file @@ -0,0 +1 @@ +fullscreen.png,w22,actions diff --git a/tools/source_icons/scalable/gtk-fullscreen.svg b/tools/source_icons/scalable/gtk-fullscreen.svg new file mode 100644 index 000000000..3b24a0741 --- /dev/null +++ b/tools/source_icons/scalable/gtk-fullscreen.svg @@ -0,0 +1,310 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/gtk-goto-first.file b/tools/source_icons/scalable/gtk-goto-first.file new file mode 100644 index 000000000..bad72d8a0 --- /dev/null +++ b/tools/source_icons/scalable/gtk-goto-first.file @@ -0,0 +1 @@ +toleftend.png,h16,actions diff --git a/tools/source_icons/scalable/gtk-goto-first.svg b/tools/source_icons/scalable/gtk-goto-first.svg new file mode 100644 index 000000000..281180ba0 --- /dev/null +++ b/tools/source_icons/scalable/gtk-goto-first.svg @@ -0,0 +1,605 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/gtk-goto-last.file b/tools/source_icons/scalable/gtk-goto-last.file new file mode 100644 index 000000000..aace4f459 --- /dev/null +++ b/tools/source_icons/scalable/gtk-goto-last.file @@ -0,0 +1 @@ +torightend.png,h16,actions diff --git a/tools/source_icons/scalable/gtk-goto-last.svg b/tools/source_icons/scalable/gtk-goto-last.svg new file mode 100644 index 000000000..9149f5477 --- /dev/null +++ b/tools/source_icons/scalable/gtk-goto-last.svg @@ -0,0 +1,605 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/gtk-leave-fullscreen.file b/tools/source_icons/scalable/gtk-leave-fullscreen.file new file mode 100644 index 000000000..1880eacae --- /dev/null +++ b/tools/source_icons/scalable/gtk-leave-fullscreen.file @@ -0,0 +1 @@ +fullscreen-exit.png,w22,actions diff --git a/tools/source_icons/scalable/gtk-leave-fullscreen.svg b/tools/source_icons/scalable/gtk-leave-fullscreen.svg new file mode 100644 index 000000000..a28049fde --- /dev/null +++ b/tools/source_icons/scalable/gtk-leave-fullscreen.svg @@ -0,0 +1,360 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/gtk-media-play.file b/tools/source_icons/scalable/gtk-media-play.file new file mode 100644 index 000000000..8d32e77c6 --- /dev/null +++ b/tools/source_icons/scalable/gtk-media-play.file @@ -0,0 +1 @@ +gtk-media-play.png,w13,actions diff --git a/tools/source_icons/scalable/gtk-media-play.svg b/tools/source_icons/scalable/gtk-media-play.svg new file mode 100644 index 000000000..105ceaa57 --- /dev/null +++ b/tools/source_icons/scalable/gtk-media-play.svg @@ -0,0 +1,604 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/gtk-media-stop.file b/tools/source_icons/scalable/gtk-media-stop.file new file mode 100644 index 000000000..db36b568b --- /dev/null +++ b/tools/source_icons/scalable/gtk-media-stop.file @@ -0,0 +1 @@ +gtk-media-stop.png,w13,actions diff --git a/tools/source_icons/scalable/gtk-media-stop.svg b/tools/source_icons/scalable/gtk-media-stop.svg new file mode 100644 index 000000000..e70bb5e60 --- /dev/null +++ b/tools/source_icons/scalable/gtk-media-stop.svg @@ -0,0 +1,661 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/gtk-open.file b/tools/source_icons/scalable/gtk-open.file new file mode 100644 index 000000000..ee4eb5b7f --- /dev/null +++ b/tools/source_icons/scalable/gtk-open.file @@ -0,0 +1,2 @@ +gtk-open.png,h18,actions +document-open.png,h18,actions diff --git a/tools/source_icons/scalable/gtk-open.svg b/tools/source_icons/scalable/gtk-open.svg new file mode 100644 index 000000000..9101e96ca --- /dev/null +++ b/tools/source_icons/scalable/gtk-open.svg @@ -0,0 +1,2007 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/gtk-paste.file b/tools/source_icons/scalable/gtk-paste.file new file mode 100644 index 000000000..78b7b677c --- /dev/null +++ b/tools/source_icons/scalable/gtk-paste.file @@ -0,0 +1,2 @@ +edit-paste.png,w22,actions +gtk-paste.png,w22,actions diff --git a/tools/source_icons/scalable/gtk-paste.svg b/tools/source_icons/scalable/gtk-paste.svg new file mode 100644 index 000000000..c1844a849 --- /dev/null +++ b/tools/source_icons/scalable/gtk-paste.svg @@ -0,0 +1,1599 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/gtk-preferences.file b/tools/source_icons/scalable/gtk-preferences.file new file mode 100644 index 000000000..aca57191b --- /dev/null +++ b/tools/source_icons/scalable/gtk-preferences.file @@ -0,0 +1 @@ +gtk-preferences.png,w22,actions diff --git a/tools/source_icons/scalable/gtk-preferences.svg b/tools/source_icons/scalable/gtk-preferences.svg new file mode 100644 index 000000000..1e45e94f3 --- /dev/null +++ b/tools/source_icons/scalable/gtk-preferences.svg @@ -0,0 +1,2516 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/gtk-remove-red.file b/tools/source_icons/scalable/gtk-remove-red.file new file mode 100644 index 000000000..0e8243c23 --- /dev/null +++ b/tools/source_icons/scalable/gtk-remove-red.file @@ -0,0 +1 @@ +list-remove-red-small.png,w12,actions diff --git a/tools/source_icons/scalable/gtk-remove-red.svg b/tools/source_icons/scalable/gtk-remove-red.svg new file mode 100644 index 000000000..c06356bbf --- /dev/null +++ b/tools/source_icons/scalable/gtk-remove-red.svg @@ -0,0 +1,663 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/gtk-remove.file b/tools/source_icons/scalable/gtk-remove.file new file mode 100644 index 000000000..46f4b8ff3 --- /dev/null +++ b/tools/source_icons/scalable/gtk-remove.file @@ -0,0 +1,2 @@ +list-remove.png,w16,actions +gtk-remove.png,w16,actions diff --git a/tools/source_icons/scalable/gtk-remove.svg b/tools/source_icons/scalable/gtk-remove.svg new file mode 100644 index 000000000..344e2f922 --- /dev/null +++ b/tools/source_icons/scalable/gtk-remove.svg @@ -0,0 +1,663 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/gtk-save.file b/tools/source_icons/scalable/gtk-save.file new file mode 100644 index 000000000..14e20f87d --- /dev/null +++ b/tools/source_icons/scalable/gtk-save.file @@ -0,0 +1,2 @@ +gtk-save-large.png,w22,actions +gtk-save.png,h18,actions diff --git a/tools/source_icons/scalable/gtk-save.svg b/tools/source_icons/scalable/gtk-save.svg new file mode 100644 index 000000000..ced16de85 --- /dev/null +++ b/tools/source_icons/scalable/gtk-save.svg @@ -0,0 +1,2807 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/gtk-undo-rtl.file b/tools/source_icons/scalable/gtk-undo-rtl.file new file mode 100644 index 000000000..2ab2af327 --- /dev/null +++ b/tools/source_icons/scalable/gtk-undo-rtl.file @@ -0,0 +1,2 @@ +gtk-undo-rtl.png,h16,actions +gtk-undo-rtl-small.png,h11,actions diff --git a/tools/source_icons/scalable/gtk-undo-rtl.svg b/tools/source_icons/scalable/gtk-undo-rtl.svg new file mode 100644 index 000000000..be883d98b --- /dev/null +++ b/tools/source_icons/scalable/gtk-undo-rtl.svg @@ -0,0 +1,732 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/gtk-undo.file b/tools/source_icons/scalable/gtk-undo.file new file mode 100644 index 000000000..527c94db9 --- /dev/null +++ b/tools/source_icons/scalable/gtk-undo.file @@ -0,0 +1,2 @@ +gtk-undo-ltr.png,h16,actions +gtk-undo-ltr-small.png,h11,actions diff --git a/tools/source_icons/scalable/gtk-undo.svg b/tools/source_icons/scalable/gtk-undo.svg new file mode 100644 index 000000000..af5ae1a36 --- /dev/null +++ b/tools/source_icons/scalable/gtk-undo.svg @@ -0,0 +1,665 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/gtk-undoall-ltr.file b/tools/source_icons/scalable/gtk-undoall-ltr.file new file mode 100644 index 000000000..bdd6db95a --- /dev/null +++ b/tools/source_icons/scalable/gtk-undoall-ltr.file @@ -0,0 +1 @@ +gtk-undoall-ltr.png,w16,actions diff --git a/tools/source_icons/scalable/gtk-undoall-ltr.svg b/tools/source_icons/scalable/gtk-undoall-ltr.svg new file mode 100644 index 000000000..fef739619 --- /dev/null +++ b/tools/source_icons/scalable/gtk-undoall-ltr.svg @@ -0,0 +1,1170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/gtk-undoall-rtl.file b/tools/source_icons/scalable/gtk-undoall-rtl.file new file mode 100644 index 000000000..f42fa476e --- /dev/null +++ b/tools/source_icons/scalable/gtk-undoall-rtl.file @@ -0,0 +1 @@ +gtk-undoall-rtl.png,w16,actions diff --git a/tools/source_icons/scalable/gtk-undoall-rtl.svg b/tools/source_icons/scalable/gtk-undoall-rtl.svg new file mode 100644 index 000000000..7228b7e89 --- /dev/null +++ b/tools/source_icons/scalable/gtk-undoall-rtl.svg @@ -0,0 +1,1170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/gtk-zoom-100-small.file b/tools/source_icons/scalable/gtk-zoom-100-small.file new file mode 100644 index 000000000..b78fca5ae --- /dev/null +++ b/tools/source_icons/scalable/gtk-zoom-100-small.file @@ -0,0 +1 @@ +gtk-zoom-100-small.png,w16,actions diff --git a/tools/source_icons/scalable/gtk-zoom-100-small.svg b/tools/source_icons/scalable/gtk-zoom-100-small.svg new file mode 100644 index 000000000..cce49706f --- /dev/null +++ b/tools/source_icons/scalable/gtk-zoom-100-small.svg @@ -0,0 +1,623 @@ + + + + + gtk-zoom-100 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + gtk-zoom-100 + + http://www.rawtherapee.com/ + 2013-04-10 + + + DrSlony + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/gtk-zoom-100.file b/tools/source_icons/scalable/gtk-zoom-100.file new file mode 100644 index 000000000..d2b450253 --- /dev/null +++ b/tools/source_icons/scalable/gtk-zoom-100.file @@ -0,0 +1 @@ +gtk-zoom-100.png,w22,actions diff --git a/tools/source_icons/scalable/gtk-zoom-100.svg b/tools/source_icons/scalable/gtk-zoom-100.svg new file mode 100644 index 000000000..cce49706f --- /dev/null +++ b/tools/source_icons/scalable/gtk-zoom-100.svg @@ -0,0 +1,623 @@ + + + + + gtk-zoom-100 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + gtk-zoom-100 + + http://www.rawtherapee.com/ + 2013-04-10 + + + DrSlony + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/gtk-zoom-crop.file b/tools/source_icons/scalable/gtk-zoom-crop.file new file mode 100644 index 000000000..9d79868b9 --- /dev/null +++ b/tools/source_icons/scalable/gtk-zoom-crop.file @@ -0,0 +1 @@ +gtk-zoom-crop.png,w22,actions diff --git a/tools/source_icons/scalable/gtk-zoom-crop.svg b/tools/source_icons/scalable/gtk-zoom-crop.svg new file mode 100644 index 000000000..7ed5d51c2 --- /dev/null +++ b/tools/source_icons/scalable/gtk-zoom-crop.svg @@ -0,0 +1,512 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/gtk-zoom-fit.file b/tools/source_icons/scalable/gtk-zoom-fit.file new file mode 100644 index 000000000..a82764c69 --- /dev/null +++ b/tools/source_icons/scalable/gtk-zoom-fit.file @@ -0,0 +1 @@ +gtk-zoom-fit.png,w22,actions diff --git a/tools/source_icons/scalable/gtk-zoom-fit.svg b/tools/source_icons/scalable/gtk-zoom-fit.svg new file mode 100644 index 000000000..95b81e1d6 --- /dev/null +++ b/tools/source_icons/scalable/gtk-zoom-fit.svg @@ -0,0 +1,509 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/gtk-zoom-in-small.file b/tools/source_icons/scalable/gtk-zoom-in-small.file new file mode 100644 index 000000000..a15fb60de --- /dev/null +++ b/tools/source_icons/scalable/gtk-zoom-in-small.file @@ -0,0 +1 @@ +gtk-zoom-in-small.png,w16,actions diff --git a/tools/source_icons/scalable/gtk-zoom-in-small.svg b/tools/source_icons/scalable/gtk-zoom-in-small.svg new file mode 100644 index 000000000..bbc50a171 --- /dev/null +++ b/tools/source_icons/scalable/gtk-zoom-in-small.svg @@ -0,0 +1,521 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/gtk-zoom-in.file b/tools/source_icons/scalable/gtk-zoom-in.file new file mode 100644 index 000000000..2bb454228 --- /dev/null +++ b/tools/source_icons/scalable/gtk-zoom-in.file @@ -0,0 +1 @@ +gtk-zoom-in.png,w22,actions diff --git a/tools/source_icons/scalable/gtk-zoom-in.svg b/tools/source_icons/scalable/gtk-zoom-in.svg new file mode 100644 index 000000000..bbc50a171 --- /dev/null +++ b/tools/source_icons/scalable/gtk-zoom-in.svg @@ -0,0 +1,521 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/gtk-zoom-out-small.file b/tools/source_icons/scalable/gtk-zoom-out-small.file new file mode 100644 index 000000000..08a4ba843 --- /dev/null +++ b/tools/source_icons/scalable/gtk-zoom-out-small.file @@ -0,0 +1 @@ +gtk-zoom-out-small.png,w16,actions diff --git a/tools/source_icons/scalable/gtk-zoom-out-small.svg b/tools/source_icons/scalable/gtk-zoom-out-small.svg new file mode 100644 index 000000000..8ca1e951b --- /dev/null +++ b/tools/source_icons/scalable/gtk-zoom-out-small.svg @@ -0,0 +1,558 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/gtk-zoom-out.file b/tools/source_icons/scalable/gtk-zoom-out.file new file mode 100644 index 000000000..5427894ff --- /dev/null +++ b/tools/source_icons/scalable/gtk-zoom-out.file @@ -0,0 +1 @@ +gtk-zoom-out.png,w22,actions diff --git a/tools/source_icons/scalable/gtk-zoom-out.svg b/tools/source_icons/scalable/gtk-zoom-out.svg new file mode 100644 index 000000000..8ca1e951b --- /dev/null +++ b/tools/source_icons/scalable/gtk-zoom-out.svg @@ -0,0 +1,558 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/histBar.file b/tools/source_icons/scalable/histBar.file new file mode 100644 index 000000000..3ede85b7a --- /dev/null +++ b/tools/source_icons/scalable/histBar.file @@ -0,0 +1 @@ +histBar.png,w10,actions diff --git a/tools/source_icons/scalable/histBar.svg b/tools/source_icons/scalable/histBar.svg new file mode 100644 index 000000000..2bb232311 --- /dev/null +++ b/tools/source_icons/scalable/histBar.svg @@ -0,0 +1,587 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/histBarg.file b/tools/source_icons/scalable/histBarg.file new file mode 100644 index 000000000..31c8b58f5 --- /dev/null +++ b/tools/source_icons/scalable/histBarg.file @@ -0,0 +1 @@ +histBarg.png,w10,actions diff --git a/tools/source_icons/scalable/histBarg.svg b/tools/source_icons/scalable/histBarg.svg new file mode 100644 index 000000000..a1cec3797 --- /dev/null +++ b/tools/source_icons/scalable/histBarg.svg @@ -0,0 +1,555 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/histBlue.file b/tools/source_icons/scalable/histBlue.file new file mode 100644 index 000000000..6efe5f403 --- /dev/null +++ b/tools/source_icons/scalable/histBlue.file @@ -0,0 +1 @@ +histBlue.png,w10,actions diff --git a/tools/source_icons/scalable/histBlue.svg b/tools/source_icons/scalable/histBlue.svg new file mode 100644 index 000000000..129c708e9 --- /dev/null +++ b/tools/source_icons/scalable/histBlue.svg @@ -0,0 +1,494 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/histBlueg.file b/tools/source_icons/scalable/histBlueg.file new file mode 100644 index 000000000..8a1a0e6ee --- /dev/null +++ b/tools/source_icons/scalable/histBlueg.file @@ -0,0 +1 @@ +histBlueg.png,w10,actions diff --git a/tools/source_icons/scalable/histBlueg.svg b/tools/source_icons/scalable/histBlueg.svg new file mode 100644 index 000000000..ab0b32804 --- /dev/null +++ b/tools/source_icons/scalable/histBlueg.svg @@ -0,0 +1,494 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/histFull.file b/tools/source_icons/scalable/histFull.file new file mode 100644 index 000000000..f1577e57d --- /dev/null +++ b/tools/source_icons/scalable/histFull.file @@ -0,0 +1 @@ +histFull.png,w10,actions diff --git a/tools/source_icons/scalable/histFull.svg b/tools/source_icons/scalable/histFull.svg new file mode 100644 index 000000000..46336770d --- /dev/null +++ b/tools/source_icons/scalable/histFull.svg @@ -0,0 +1,534 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/tools/source_icons/scalable/histFullg.file b/tools/source_icons/scalable/histFullg.file new file mode 100644 index 000000000..b011c3a49 --- /dev/null +++ b/tools/source_icons/scalable/histFullg.file @@ -0,0 +1 @@ +histFullg.png,w10,actions diff --git a/tools/source_icons/scalable/histFullg.svg b/tools/source_icons/scalable/histFullg.svg new file mode 100644 index 000000000..37765aaff --- /dev/null +++ b/tools/source_icons/scalable/histFullg.svg @@ -0,0 +1,534 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/tools/source_icons/scalable/histGreen.file b/tools/source_icons/scalable/histGreen.file new file mode 100644 index 000000000..a2699dfd3 --- /dev/null +++ b/tools/source_icons/scalable/histGreen.file @@ -0,0 +1 @@ +histGreen.png,w10,actions diff --git a/tools/source_icons/scalable/histGreen.svg b/tools/source_icons/scalable/histGreen.svg new file mode 100644 index 000000000..0c8babc4d --- /dev/null +++ b/tools/source_icons/scalable/histGreen.svg @@ -0,0 +1,494 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/histGreeng.file b/tools/source_icons/scalable/histGreeng.file new file mode 100644 index 000000000..793be799d --- /dev/null +++ b/tools/source_icons/scalable/histGreeng.file @@ -0,0 +1 @@ +histGreeng.png,w10,actions diff --git a/tools/source_icons/scalable/histGreeng.svg b/tools/source_icons/scalable/histGreeng.svg new file mode 100644 index 000000000..c85a8d412 --- /dev/null +++ b/tools/source_icons/scalable/histGreeng.svg @@ -0,0 +1,494 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/histRaw.file b/tools/source_icons/scalable/histRaw.file new file mode 100644 index 000000000..b0b56e108 --- /dev/null +++ b/tools/source_icons/scalable/histRaw.file @@ -0,0 +1 @@ +histRaw.png,w10,actions diff --git a/tools/source_icons/scalable/histRaw.svg b/tools/source_icons/scalable/histRaw.svg new file mode 100644 index 000000000..73fa612ce --- /dev/null +++ b/tools/source_icons/scalable/histRaw.svg @@ -0,0 +1,632 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/histRawg.file b/tools/source_icons/scalable/histRawg.file new file mode 100644 index 000000000..3b526f92e --- /dev/null +++ b/tools/source_icons/scalable/histRawg.file @@ -0,0 +1 @@ +histRawg.png,w10,actions diff --git a/tools/source_icons/scalable/histRawg.svg b/tools/source_icons/scalable/histRawg.svg new file mode 100644 index 000000000..69fac8f10 --- /dev/null +++ b/tools/source_icons/scalable/histRawg.svg @@ -0,0 +1,615 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/histRed.file b/tools/source_icons/scalable/histRed.file new file mode 100644 index 000000000..7517b28d3 --- /dev/null +++ b/tools/source_icons/scalable/histRed.file @@ -0,0 +1 @@ +histRed.png,w10,actions diff --git a/tools/source_icons/scalable/histRed.svg b/tools/source_icons/scalable/histRed.svg new file mode 100644 index 000000000..fdff14a74 --- /dev/null +++ b/tools/source_icons/scalable/histRed.svg @@ -0,0 +1,494 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/histRedg.file b/tools/source_icons/scalable/histRedg.file new file mode 100644 index 000000000..03cc3e79a --- /dev/null +++ b/tools/source_icons/scalable/histRedg.file @@ -0,0 +1 @@ +histRedg.png,w10,actions diff --git a/tools/source_icons/scalable/histRedg.svg b/tools/source_icons/scalable/histRedg.svg new file mode 100644 index 000000000..c25dba5c2 --- /dev/null +++ b/tools/source_icons/scalable/histRedg.svg @@ -0,0 +1,494 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/histValue.file b/tools/source_icons/scalable/histValue.file new file mode 100644 index 000000000..077c9b761 --- /dev/null +++ b/tools/source_icons/scalable/histValue.file @@ -0,0 +1 @@ +histValue.png,w10,actions diff --git a/tools/source_icons/scalable/histValue.svg b/tools/source_icons/scalable/histValue.svg new file mode 100644 index 000000000..b82f4da01 --- /dev/null +++ b/tools/source_icons/scalable/histValue.svg @@ -0,0 +1,494 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/histValueg.file b/tools/source_icons/scalable/histValueg.file new file mode 100644 index 000000000..37c61fe32 --- /dev/null +++ b/tools/source_icons/scalable/histValueg.file @@ -0,0 +1 @@ +histValueg.png,w10,actions diff --git a/tools/source_icons/scalable/histValueg.svg b/tools/source_icons/scalable/histValueg.svg new file mode 100644 index 000000000..ffc0daaf8 --- /dev/null +++ b/tools/source_icons/scalable/histValueg.svg @@ -0,0 +1,494 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/histogramButtons.svg b/tools/source_icons/scalable/histogramButtons.svg new file mode 100644 index 000000000..231b6dd94 --- /dev/null +++ b/tools/source_icons/scalable/histogramButtons.svg @@ -0,0 +1,273 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/image-editor.file b/tools/source_icons/scalable/image-editor.file new file mode 100644 index 000000000..c1853f678 --- /dev/null +++ b/tools/source_icons/scalable/image-editor.file @@ -0,0 +1 @@ +image-editor.png,w22,actions diff --git a/tools/source_icons/scalable/image-editor.svg b/tools/source_icons/scalable/image-editor.svg new file mode 100644 index 000000000..220138a9a --- /dev/null +++ b/tools/source_icons/scalable/image-editor.svg @@ -0,0 +1,2652 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/info.file b/tools/source_icons/scalable/info.file new file mode 100644 index 000000000..ede775c5b --- /dev/null +++ b/tools/source_icons/scalable/info.file @@ -0,0 +1 @@ +info.png,w22,actions diff --git a/tools/source_icons/scalable/info.svg b/tools/source_icons/scalable/info.svg new file mode 100644 index 000000000..e25fca2f0 --- /dev/null +++ b/tools/source_icons/scalable/info.svg @@ -0,0 +1,454 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/lock-off.file b/tools/source_icons/scalable/lock-off.file new file mode 100644 index 000000000..38ddabc0d --- /dev/null +++ b/tools/source_icons/scalable/lock-off.file @@ -0,0 +1 @@ +lock-off.png,h10,actions diff --git a/tools/source_icons/scalable/lock-off.svg b/tools/source_icons/scalable/lock-off.svg new file mode 100644 index 000000000..caeeed555 --- /dev/null +++ b/tools/source_icons/scalable/lock-off.svg @@ -0,0 +1,916 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/lock-on.file b/tools/source_icons/scalable/lock-on.file new file mode 100644 index 000000000..ba7eef7a3 --- /dev/null +++ b/tools/source_icons/scalable/lock-on.file @@ -0,0 +1 @@ +lock-on.png,h10,actions diff --git a/tools/source_icons/scalable/lock-on.svg b/tools/source_icons/scalable/lock-on.svg new file mode 100644 index 000000000..8d841a0cd --- /dev/null +++ b/tools/source_icons/scalable/lock-on.svg @@ -0,0 +1,777 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/media-floppy.file b/tools/source_icons/scalable/media-floppy.file new file mode 100644 index 000000000..1ffa70b86 --- /dev/null +++ b/tools/source_icons/scalable/media-floppy.file @@ -0,0 +1,2 @@ +media-floppy.png,h18,devices +drive-removable-media.png,h18,devices diff --git a/tools/source_icons/scalable/media-floppy.svg b/tools/source_icons/scalable/media-floppy.svg new file mode 100644 index 000000000..9032f9041 --- /dev/null +++ b/tools/source_icons/scalable/media-floppy.svg @@ -0,0 +1,661 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/media-usb.file b/tools/source_icons/scalable/media-usb.file new file mode 100644 index 000000000..3012badee --- /dev/null +++ b/tools/source_icons/scalable/media-usb.file @@ -0,0 +1 @@ +media-usb.png,h18,actions diff --git a/tools/source_icons/scalable/media-usb.svg b/tools/source_icons/scalable/media-usb.svg new file mode 100644 index 000000000..e9b36285c --- /dev/null +++ b/tools/source_icons/scalable/media-usb.svg @@ -0,0 +1,2590 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/meta.file b/tools/source_icons/scalable/meta.file new file mode 100644 index 000000000..8e432502e --- /dev/null +++ b/tools/source_icons/scalable/meta.file @@ -0,0 +1 @@ +meta.png,w24,actions diff --git a/tools/source_icons/scalable/meta.svg b/tools/source_icons/scalable/meta.svg new file mode 100644 index 000000000..a4ac324dc --- /dev/null +++ b/tools/source_icons/scalable/meta.svg @@ -0,0 +1,657 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + META + + + + + + + diff --git a/tools/source_icons/scalable/move-1D-h.svg b/tools/source_icons/scalable/move-1D-h.svg new file mode 100644 index 000000000..64514eed1 --- /dev/null +++ b/tools/source_icons/scalable/move-1D-h.svg @@ -0,0 +1,297 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/move-1D-v.svg b/tools/source_icons/scalable/move-1D-v.svg new file mode 100644 index 000000000..24b49a7de --- /dev/null +++ b/tools/source_icons/scalable/move-1D-v.svg @@ -0,0 +1,297 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/move-2D.svg b/tools/source_icons/scalable/move-2D.svg new file mode 100644 index 000000000..bb0eece8f --- /dev/null +++ b/tools/source_icons/scalable/move-2D.svg @@ -0,0 +1,297 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/nav-next.file b/tools/source_icons/scalable/nav-next.file new file mode 100644 index 000000000..fc7568def --- /dev/null +++ b/tools/source_icons/scalable/nav-next.file @@ -0,0 +1 @@ +nav-next.png,w19,actions diff --git a/tools/source_icons/scalable/nav-next.svg b/tools/source_icons/scalable/nav-next.svg new file mode 100644 index 000000000..123f334d9 --- /dev/null +++ b/tools/source_icons/scalable/nav-next.svg @@ -0,0 +1,649 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/tools/source_icons/scalable/nav-prev.file b/tools/source_icons/scalable/nav-prev.file new file mode 100644 index 000000000..ea876f7fb --- /dev/null +++ b/tools/source_icons/scalable/nav-prev.file @@ -0,0 +1 @@ +nav-prev.png,w19,actions diff --git a/tools/source_icons/scalable/nav-prev.svg b/tools/source_icons/scalable/nav-prev.svg new file mode 100644 index 000000000..4112c31fb --- /dev/null +++ b/tools/source_icons/scalable/nav-prev.svg @@ -0,0 +1,649 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/tools/source_icons/scalable/nav-sync.file b/tools/source_icons/scalable/nav-sync.file new file mode 100644 index 000000000..92c643323 --- /dev/null +++ b/tools/source_icons/scalable/nav-sync.file @@ -0,0 +1 @@ +nav-sync.png,w14,actions diff --git a/tools/source_icons/scalable/nav-sync.svg b/tools/source_icons/scalable/nav-sync.svg new file mode 100644 index 000000000..420e2c335 --- /dev/null +++ b/tools/source_icons/scalable/nav-sync.svg @@ -0,0 +1,833 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/new-detail-window.file b/tools/source_icons/scalable/new-detail-window.file new file mode 100644 index 000000000..d4ee2bf2c --- /dev/null +++ b/tools/source_icons/scalable/new-detail-window.file @@ -0,0 +1 @@ +new-detail-window.png,w22,actions diff --git a/tools/source_icons/scalable/new-detail-window.svg b/tools/source_icons/scalable/new-detail-window.svg new file mode 100644 index 000000000..5241e38d9 --- /dev/null +++ b/tools/source_icons/scalable/new-detail-window.svg @@ -0,0 +1,500 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/openhand.file b/tools/source_icons/scalable/openhand.file new file mode 100644 index 000000000..2a05645a0 --- /dev/null +++ b/tools/source_icons/scalable/openhand.file @@ -0,0 +1 @@ +openhand.png,w22,actions diff --git a/tools/source_icons/scalable/openhand.svg b/tools/source_icons/scalable/openhand.svg new file mode 100644 index 000000000..9fd47c0df --- /dev/null +++ b/tools/source_icons/scalable/openhand.svg @@ -0,0 +1,760 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/tools/source_icons/scalable/panel-to-bottom.file b/tools/source_icons/scalable/panel-to-bottom.file new file mode 100644 index 000000000..2474ef833 --- /dev/null +++ b/tools/source_icons/scalable/panel-to-bottom.file @@ -0,0 +1 @@ +panel-to-bottom.png,w22,actions diff --git a/tools/source_icons/scalable/panel-to-bottom.svg b/tools/source_icons/scalable/panel-to-bottom.svg new file mode 100644 index 000000000..03d4ba020 --- /dev/null +++ b/tools/source_icons/scalable/panel-to-bottom.svg @@ -0,0 +1,802 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/panel-to-left.file b/tools/source_icons/scalable/panel-to-left.file new file mode 100644 index 000000000..f730a3c74 --- /dev/null +++ b/tools/source_icons/scalable/panel-to-left.file @@ -0,0 +1 @@ +panel-to-left.png,h22,actions diff --git a/tools/source_icons/scalable/panel-to-left.svg b/tools/source_icons/scalable/panel-to-left.svg new file mode 100644 index 000000000..3483477b3 --- /dev/null +++ b/tools/source_icons/scalable/panel-to-left.svg @@ -0,0 +1,794 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/panel-to-right.file b/tools/source_icons/scalable/panel-to-right.file new file mode 100644 index 000000000..9ae79460a --- /dev/null +++ b/tools/source_icons/scalable/panel-to-right.file @@ -0,0 +1 @@ +panel-to-right.png,h22,actions diff --git a/tools/source_icons/scalable/panel-to-right.svg b/tools/source_icons/scalable/panel-to-right.svg new file mode 100644 index 000000000..5a999fc47 --- /dev/null +++ b/tools/source_icons/scalable/panel-to-right.svg @@ -0,0 +1,812 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/panel-to-top.file b/tools/source_icons/scalable/panel-to-top.file new file mode 100644 index 000000000..b9eee13ad --- /dev/null +++ b/tools/source_icons/scalable/panel-to-top.file @@ -0,0 +1 @@ +panel-to-top.png,w22,actions diff --git a/tools/source_icons/scalable/panel-to-top.svg b/tools/source_icons/scalable/panel-to-top.svg new file mode 100644 index 000000000..12e513aa0 --- /dev/null +++ b/tools/source_icons/scalable/panel-to-top.svg @@ -0,0 +1,784 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/perspective-h1.file b/tools/source_icons/scalable/perspective-h1.file new file mode 100644 index 000000000..f6f27cad6 --- /dev/null +++ b/tools/source_icons/scalable/perspective-h1.file @@ -0,0 +1 @@ +perspective-h1.png,w22,actions diff --git a/tools/source_icons/scalable/perspective-h1.svg b/tools/source_icons/scalable/perspective-h1.svg new file mode 100644 index 000000000..5a5a9e33e --- /dev/null +++ b/tools/source_icons/scalable/perspective-h1.svg @@ -0,0 +1,1133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/perspective-h2.file b/tools/source_icons/scalable/perspective-h2.file new file mode 100644 index 000000000..60cc690af --- /dev/null +++ b/tools/source_icons/scalable/perspective-h2.file @@ -0,0 +1 @@ +perspective-h2.png,w22,actions diff --git a/tools/source_icons/scalable/perspective-h2.svg b/tools/source_icons/scalable/perspective-h2.svg new file mode 100644 index 000000000..a36956151 --- /dev/null +++ b/tools/source_icons/scalable/perspective-h2.svg @@ -0,0 +1,1133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/perspective-v1.file b/tools/source_icons/scalable/perspective-v1.file new file mode 100644 index 000000000..cbc05fec6 --- /dev/null +++ b/tools/source_icons/scalable/perspective-v1.file @@ -0,0 +1 @@ +perspective-v1.png,w22,actions diff --git a/tools/source_icons/scalable/perspective-v1.svg b/tools/source_icons/scalable/perspective-v1.svg new file mode 100644 index 000000000..712447c2a --- /dev/null +++ b/tools/source_icons/scalable/perspective-v1.svg @@ -0,0 +1,1138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/perspective-v2.file b/tools/source_icons/scalable/perspective-v2.file new file mode 100644 index 000000000..c4ade9f63 --- /dev/null +++ b/tools/source_icons/scalable/perspective-v2.file @@ -0,0 +1 @@ +perspective-v2.png,w22,actions diff --git a/tools/source_icons/scalable/perspective-v2.svg b/tools/source_icons/scalable/perspective-v2.svg new file mode 100644 index 000000000..8842e9c41 --- /dev/null +++ b/tools/source_icons/scalable/perspective-v2.svg @@ -0,0 +1,1140 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/popuparrow.file b/tools/source_icons/scalable/popuparrow.file new file mode 100644 index 000000000..1a3ca3ffc --- /dev/null +++ b/tools/source_icons/scalable/popuparrow.file @@ -0,0 +1 @@ +popuparrow.png,h6,actions diff --git a/tools/source_icons/scalable/popuparrow.svg b/tools/source_icons/scalable/popuparrow.svg new file mode 100644 index 000000000..3328dbfb4 --- /dev/null +++ b/tools/source_icons/scalable/popuparrow.svg @@ -0,0 +1,355 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/processing-pause.file b/tools/source_icons/scalable/processing-pause.file new file mode 100644 index 000000000..bf82fdf73 --- /dev/null +++ b/tools/source_icons/scalable/processing-pause.file @@ -0,0 +1 @@ +processing-pause.png,w20,actions diff --git a/tools/source_icons/scalable/processing-pause.svg b/tools/source_icons/scalable/processing-pause.svg new file mode 100644 index 000000000..caeb85d0c --- /dev/null +++ b/tools/source_icons/scalable/processing-pause.svg @@ -0,0 +1,463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/processing-play.file b/tools/source_icons/scalable/processing-play.file new file mode 100644 index 000000000..e8904e6d8 --- /dev/null +++ b/tools/source_icons/scalable/processing-play.file @@ -0,0 +1 @@ +processing-play.png,w20,actions diff --git a/tools/source_icons/scalable/processing-play.svg b/tools/source_icons/scalable/processing-play.svg new file mode 100644 index 000000000..cbe2e2cd8 --- /dev/null +++ b/tools/source_icons/scalable/processing-play.svg @@ -0,0 +1,435 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/processing-thumbnail.file b/tools/source_icons/scalable/processing-thumbnail.file new file mode 100644 index 000000000..659697271 --- /dev/null +++ b/tools/source_icons/scalable/processing-thumbnail.file @@ -0,0 +1 @@ +processing-thumbnail.png,w18,actions diff --git a/tools/source_icons/scalable/processing-thumbnail.svg b/tools/source_icons/scalable/processing-thumbnail.svg new file mode 100644 index 000000000..8865df7e6 --- /dev/null +++ b/tools/source_icons/scalable/processing-thumbnail.svg @@ -0,0 +1,391 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/profile-filled.file b/tools/source_icons/scalable/profile-filled.file new file mode 100644 index 000000000..ce6a2f593 --- /dev/null +++ b/tools/source_icons/scalable/profile-filled.file @@ -0,0 +1 @@ +profile-filled.png,w22,actions diff --git a/tools/source_icons/scalable/profile-filled.svg b/tools/source_icons/scalable/profile-filled.svg new file mode 100644 index 000000000..fadc80267 --- /dev/null +++ b/tools/source_icons/scalable/profile-filled.svg @@ -0,0 +1,746 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/profile-partial.file b/tools/source_icons/scalable/profile-partial.file new file mode 100644 index 000000000..d5e11fcf0 --- /dev/null +++ b/tools/source_icons/scalable/profile-partial.file @@ -0,0 +1 @@ +profile-partial.png,w22,actions diff --git a/tools/source_icons/scalable/profile-partial.svg b/tools/source_icons/scalable/profile-partial.svg new file mode 100644 index 000000000..d379fc471 --- /dev/null +++ b/tools/source_icons/scalable/profile-partial.svg @@ -0,0 +1,732 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/rated.file b/tools/source_icons/scalable/rated.file new file mode 100644 index 000000000..60b4b9533 --- /dev/null +++ b/tools/source_icons/scalable/rated.file @@ -0,0 +1 @@ +rated.png,h10,actions diff --git a/tools/source_icons/scalable/rated.svg b/tools/source_icons/scalable/rated.svg new file mode 100644 index 000000000..19af9b20a --- /dev/null +++ b/tools/source_icons/scalable/rated.svg @@ -0,0 +1,715 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/ratednot.file b/tools/source_icons/scalable/ratednot.file new file mode 100644 index 000000000..bdf5b1eb7 --- /dev/null +++ b/tools/source_icons/scalable/ratednot.file @@ -0,0 +1 @@ +ratednot.png,h10,actions diff --git a/tools/source_icons/scalable/ratednot.svg b/tools/source_icons/scalable/ratednot.svg new file mode 100644 index 000000000..9c4d76156 --- /dev/null +++ b/tools/source_icons/scalable/ratednot.svg @@ -0,0 +1,823 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/ratednotg.file b/tools/source_icons/scalable/ratednotg.file new file mode 100644 index 000000000..dc700605b --- /dev/null +++ b/tools/source_icons/scalable/ratednotg.file @@ -0,0 +1 @@ +ratednotg.png,h10,actions diff --git a/tools/source_icons/scalable/ratednotg.svg b/tools/source_icons/scalable/ratednotg.svg new file mode 100644 index 000000000..8400f97bc --- /dev/null +++ b/tools/source_icons/scalable/ratednotg.svg @@ -0,0 +1,647 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/raw.file b/tools/source_icons/scalable/raw.file new file mode 100644 index 000000000..e7f88a039 --- /dev/null +++ b/tools/source_icons/scalable/raw.file @@ -0,0 +1 @@ +raw.png,w24,actions diff --git a/tools/source_icons/scalable/raw.svg b/tools/source_icons/scalable/raw.svg new file mode 100644 index 000000000..4073fbebc --- /dev/null +++ b/tools/source_icons/scalable/raw.svg @@ -0,0 +1,245 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/refresh-red.file b/tools/source_icons/scalable/refresh-red.file new file mode 100644 index 000000000..eb462aafe --- /dev/null +++ b/tools/source_icons/scalable/refresh-red.file @@ -0,0 +1 @@ +refresh-red.png,h13,actions diff --git a/tools/source_icons/scalable/refresh-red.svg b/tools/source_icons/scalable/refresh-red.svg new file mode 100644 index 000000000..d6bdb4b4d --- /dev/null +++ b/tools/source_icons/scalable/refresh-red.svg @@ -0,0 +1,1256 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/refresh-white.file b/tools/source_icons/scalable/refresh-white.file new file mode 100644 index 000000000..6195fa3fa --- /dev/null +++ b/tools/source_icons/scalable/refresh-white.file @@ -0,0 +1 @@ +refresh-white.png,h13,actions diff --git a/tools/source_icons/scalable/refresh-white.svg b/tools/source_icons/scalable/refresh-white.svg new file mode 100644 index 000000000..1b1f45b14 --- /dev/null +++ b/tools/source_icons/scalable/refresh-white.svg @@ -0,0 +1,1256 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/rotate-left-1.file b/tools/source_icons/scalable/rotate-left-1.file new file mode 100644 index 000000000..01069fb5b --- /dev/null +++ b/tools/source_icons/scalable/rotate-left-1.file @@ -0,0 +1 @@ +rotate-left-1.png,w22,actions diff --git a/tools/source_icons/scalable/rotate-left-1.svg b/tools/source_icons/scalable/rotate-left-1.svg new file mode 100644 index 000000000..19b6420ae --- /dev/null +++ b/tools/source_icons/scalable/rotate-left-1.svg @@ -0,0 +1,1519 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/rotate-left-2.file b/tools/source_icons/scalable/rotate-left-2.file new file mode 100644 index 000000000..7ddcc8294 --- /dev/null +++ b/tools/source_icons/scalable/rotate-left-2.file @@ -0,0 +1 @@ +rotate-left-2.png,w22,actions diff --git a/tools/source_icons/scalable/rotate-left-2.svg b/tools/source_icons/scalable/rotate-left-2.svg new file mode 100644 index 000000000..598912692 --- /dev/null +++ b/tools/source_icons/scalable/rotate-left-2.svg @@ -0,0 +1,1519 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/rotate-left-3.file b/tools/source_icons/scalable/rotate-left-3.file new file mode 100644 index 000000000..ff5463291 --- /dev/null +++ b/tools/source_icons/scalable/rotate-left-3.file @@ -0,0 +1 @@ +rotate-left-3.png,w22,actions diff --git a/tools/source_icons/scalable/rotate-left-3.svg b/tools/source_icons/scalable/rotate-left-3.svg new file mode 100644 index 000000000..e398a61e4 --- /dev/null +++ b/tools/source_icons/scalable/rotate-left-3.svg @@ -0,0 +1,1519 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/rotate-left.file b/tools/source_icons/scalable/rotate-left.file new file mode 100644 index 000000000..69b2f2e74 --- /dev/null +++ b/tools/source_icons/scalable/rotate-left.file @@ -0,0 +1 @@ +rotate-left.png,w22,actions diff --git a/tools/source_icons/scalable/rotate-left.svg b/tools/source_icons/scalable/rotate-left.svg new file mode 100644 index 000000000..b0617a931 --- /dev/null +++ b/tools/source_icons/scalable/rotate-left.svg @@ -0,0 +1,1144 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/tools/source_icons/scalable/rotate-move.svg b/tools/source_icons/scalable/rotate-move.svg new file mode 100644 index 000000000..362803b65 --- /dev/null +++ b/tools/source_icons/scalable/rotate-move.svg @@ -0,0 +1,301 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/rotate-right-1.file b/tools/source_icons/scalable/rotate-right-1.file new file mode 100644 index 000000000..bddb3b975 --- /dev/null +++ b/tools/source_icons/scalable/rotate-right-1.file @@ -0,0 +1 @@ +rotate-right-1.png,w22,actions diff --git a/tools/source_icons/scalable/rotate-right-1.svg b/tools/source_icons/scalable/rotate-right-1.svg new file mode 100644 index 000000000..e485389ee --- /dev/null +++ b/tools/source_icons/scalable/rotate-right-1.svg @@ -0,0 +1,1519 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/rotate-right-2.file b/tools/source_icons/scalable/rotate-right-2.file new file mode 100644 index 000000000..e5e421457 --- /dev/null +++ b/tools/source_icons/scalable/rotate-right-2.file @@ -0,0 +1 @@ +rotate-right-2.png,w22,actions diff --git a/tools/source_icons/scalable/rotate-right-2.svg b/tools/source_icons/scalable/rotate-right-2.svg new file mode 100644 index 000000000..476c8d814 --- /dev/null +++ b/tools/source_icons/scalable/rotate-right-2.svg @@ -0,0 +1,1438 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/rotate-right-3.file b/tools/source_icons/scalable/rotate-right-3.file new file mode 100644 index 000000000..64c38a7e9 --- /dev/null +++ b/tools/source_icons/scalable/rotate-right-3.file @@ -0,0 +1 @@ +rotate-right-3.png,w22,actions diff --git a/tools/source_icons/scalable/rotate-right-3.svg b/tools/source_icons/scalable/rotate-right-3.svg new file mode 100644 index 000000000..7bef3af43 --- /dev/null +++ b/tools/source_icons/scalable/rotate-right-3.svg @@ -0,0 +1,1438 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/rotate-right.file b/tools/source_icons/scalable/rotate-right.file new file mode 100644 index 000000000..123a579c0 --- /dev/null +++ b/tools/source_icons/scalable/rotate-right.file @@ -0,0 +1 @@ +rotate-right.png,w22,actions diff --git a/tools/source_icons/scalable/rotate-right.svg b/tools/source_icons/scalable/rotate-right.svg new file mode 100644 index 000000000..c5702309f --- /dev/null +++ b/tools/source_icons/scalable/rotate-right.svg @@ -0,0 +1,1123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/tools/source_icons/scalable/stock-flip-horizontal.file b/tools/source_icons/scalable/stock-flip-horizontal.file new file mode 100644 index 000000000..a95ee3be7 --- /dev/null +++ b/tools/source_icons/scalable/stock-flip-horizontal.file @@ -0,0 +1 @@ +stock-flip-horizontal.png,w22,actions diff --git a/tools/source_icons/scalable/stock-flip-horizontal.svg b/tools/source_icons/scalable/stock-flip-horizontal.svg new file mode 100644 index 000000000..0dc568256 --- /dev/null +++ b/tools/source_icons/scalable/stock-flip-horizontal.svg @@ -0,0 +1,1443 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/stock-flip-vertical.file b/tools/source_icons/scalable/stock-flip-vertical.file new file mode 100644 index 000000000..303ccb427 --- /dev/null +++ b/tools/source_icons/scalable/stock-flip-vertical.file @@ -0,0 +1 @@ +stock-flip-vertical.png,w22,actions diff --git a/tools/source_icons/scalable/stock-flip-vertical.svg b/tools/source_icons/scalable/stock-flip-vertical.svg new file mode 100644 index 000000000..42bcdd8b6 --- /dev/null +++ b/tools/source_icons/scalable/stock-flip-vertical.svg @@ -0,0 +1,1305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/stock-rotate-270.file b/tools/source_icons/scalable/stock-rotate-270.file new file mode 100644 index 000000000..e7b884876 --- /dev/null +++ b/tools/source_icons/scalable/stock-rotate-270.file @@ -0,0 +1 @@ +stock-rotate-270.png,w22,actions diff --git a/tools/source_icons/scalable/stock-rotate-270.svg b/tools/source_icons/scalable/stock-rotate-270.svg new file mode 100644 index 000000000..473a2d28a --- /dev/null +++ b/tools/source_icons/scalable/stock-rotate-270.svg @@ -0,0 +1,823 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/stock-rotate-90.file b/tools/source_icons/scalable/stock-rotate-90.file new file mode 100644 index 000000000..26aa135e8 --- /dev/null +++ b/tools/source_icons/scalable/stock-rotate-90.file @@ -0,0 +1 @@ +stock-rotate-90.png,w22,actions diff --git a/tools/source_icons/scalable/stock-rotate-90.svg b/tools/source_icons/scalable/stock-rotate-90.svg new file mode 100644 index 000000000..15570f7a3 --- /dev/null +++ b/tools/source_icons/scalable/stock-rotate-90.svg @@ -0,0 +1,869 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/straighten.file b/tools/source_icons/scalable/straighten.file new file mode 100644 index 000000000..7e9790c65 --- /dev/null +++ b/tools/source_icons/scalable/straighten.file @@ -0,0 +1,2 @@ +straighten.png,w22,actions +straighten-small.png,h18,actions diff --git a/tools/source_icons/scalable/straighten.svg b/tools/source_icons/scalable/straighten.svg new file mode 100644 index 000000000..53701dc8c --- /dev/null +++ b/tools/source_icons/scalable/straighten.svg @@ -0,0 +1,1258 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/transform.file b/tools/source_icons/scalable/transform.file new file mode 100644 index 000000000..c9239c7f6 --- /dev/null +++ b/tools/source_icons/scalable/transform.file @@ -0,0 +1 @@ +transform.png,w24,actions diff --git a/tools/source_icons/scalable/transform.svg b/tools/source_icons/scalable/transform.svg new file mode 100644 index 000000000..4d7c50c8b --- /dev/null +++ b/tools/source_icons/scalable/transform.svg @@ -0,0 +1,1354 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/trash-hide-deleted.file b/tools/source_icons/scalable/trash-hide-deleted.file new file mode 100644 index 000000000..660b4fffa --- /dev/null +++ b/tools/source_icons/scalable/trash-hide-deleted.file @@ -0,0 +1 @@ +trash-hide-deleted.png,w22,actions diff --git a/tools/source_icons/scalable/trash-hide-deleted.svg b/tools/source_icons/scalable/trash-hide-deleted.svg new file mode 100644 index 000000000..8272d1c77 --- /dev/null +++ b/tools/source_icons/scalable/trash-hide-deleted.svg @@ -0,0 +1,182 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/trash-show-full.file b/tools/source_icons/scalable/trash-show-full.file new file mode 100644 index 000000000..48fbc21c1 --- /dev/null +++ b/tools/source_icons/scalable/trash-show-full.file @@ -0,0 +1 @@ +trash-show-full.png,w22,actions diff --git a/tools/source_icons/scalable/trash-show-full.svg b/tools/source_icons/scalable/trash-show-full.svg new file mode 100644 index 000000000..62a0414bd --- /dev/null +++ b/tools/source_icons/scalable/trash-show-full.svg @@ -0,0 +1,1622 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/trash-thumbnail.file b/tools/source_icons/scalable/trash-thumbnail.file new file mode 100644 index 000000000..753cf836b --- /dev/null +++ b/tools/source_icons/scalable/trash-thumbnail.file @@ -0,0 +1 @@ +trash-thumbnail.png,w18,actions diff --git a/tools/source_icons/scalable/trash-thumbnail.svg b/tools/source_icons/scalable/trash-thumbnail.svg new file mode 100644 index 000000000..11c515022 --- /dev/null +++ b/tools/source_icons/scalable/trash-thumbnail.svg @@ -0,0 +1,862 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/undelete-rtl.file b/tools/source_icons/scalable/undelete-rtl.file new file mode 100644 index 000000000..2fd8e06ad --- /dev/null +++ b/tools/source_icons/scalable/undelete-rtl.file @@ -0,0 +1 @@ +undelete-rtl.png,w22,actions diff --git a/tools/source_icons/scalable/undelete-rtl.svg b/tools/source_icons/scalable/undelete-rtl.svg new file mode 100644 index 000000000..74ea4560c --- /dev/null +++ b/tools/source_icons/scalable/undelete-rtl.svg @@ -0,0 +1,1829 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/undelete-thumbnail-rtl.file b/tools/source_icons/scalable/undelete-thumbnail-rtl.file new file mode 100644 index 000000000..a4a344684 --- /dev/null +++ b/tools/source_icons/scalable/undelete-thumbnail-rtl.file @@ -0,0 +1 @@ +undelete-thumbnail-rtl.png,w18,actions diff --git a/tools/source_icons/scalable/undelete-thumbnail-rtl.svg b/tools/source_icons/scalable/undelete-thumbnail-rtl.svg new file mode 100644 index 000000000..2f5a0ba1c --- /dev/null +++ b/tools/source_icons/scalable/undelete-thumbnail-rtl.svg @@ -0,0 +1,1829 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/undelete-thumbnail.file b/tools/source_icons/scalable/undelete-thumbnail.file new file mode 100644 index 000000000..a8cabf8f7 --- /dev/null +++ b/tools/source_icons/scalable/undelete-thumbnail.file @@ -0,0 +1 @@ +undelete-thumbnail.png,w18,actions diff --git a/tools/source_icons/scalable/undelete-thumbnail.svg b/tools/source_icons/scalable/undelete-thumbnail.svg new file mode 100644 index 000000000..b88fd56f5 --- /dev/null +++ b/tools/source_icons/scalable/undelete-thumbnail.svg @@ -0,0 +1,1921 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/undelete.file b/tools/source_icons/scalable/undelete.file new file mode 100644 index 000000000..d9bb900eb --- /dev/null +++ b/tools/source_icons/scalable/undelete.file @@ -0,0 +1 @@ +undelete.png,w22,actions diff --git a/tools/source_icons/scalable/undelete.svg b/tools/source_icons/scalable/undelete.svg new file mode 100644 index 000000000..29eca9d8b --- /dev/null +++ b/tools/source_icons/scalable/undelete.svg @@ -0,0 +1,1965 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/user-desktop.file b/tools/source_icons/scalable/user-desktop.file new file mode 100644 index 000000000..f3dff9653 --- /dev/null +++ b/tools/source_icons/scalable/user-desktop.file @@ -0,0 +1 @@ +user-desktop.png,h18,places diff --git a/tools/source_icons/scalable/user-desktop.svg b/tools/source_icons/scalable/user-desktop.svg new file mode 100644 index 000000000..b0b6a98dc --- /dev/null +++ b/tools/source_icons/scalable/user-desktop.svg @@ -0,0 +1,996 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/user-home.file b/tools/source_icons/scalable/user-home.file new file mode 100644 index 000000000..d48b964f1 --- /dev/null +++ b/tools/source_icons/scalable/user-home.file @@ -0,0 +1 @@ +user-home.png,h18,places diff --git a/tools/source_icons/scalable/user-home.svg b/tools/source_icons/scalable/user-home.svg new file mode 100644 index 000000000..011b8ecff --- /dev/null +++ b/tools/source_icons/scalable/user-home.svg @@ -0,0 +1,1591 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/warnhl.file b/tools/source_icons/scalable/warnhl.file new file mode 100644 index 000000000..4ea34e6f8 --- /dev/null +++ b/tools/source_icons/scalable/warnhl.file @@ -0,0 +1 @@ +warnhl.png,w22,actions diff --git a/tools/source_icons/scalable/warnhl.svg b/tools/source_icons/scalable/warnhl.svg new file mode 100644 index 000000000..c0e7f9046 --- /dev/null +++ b/tools/source_icons/scalable/warnhl.svg @@ -0,0 +1,657 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/warnsh.file b/tools/source_icons/scalable/warnsh.file new file mode 100644 index 000000000..2d2640c79 --- /dev/null +++ b/tools/source_icons/scalable/warnsh.file @@ -0,0 +1 @@ +warnsh.png,w22,actions diff --git a/tools/source_icons/scalable/warnsh.svg b/tools/source_icons/scalable/warnsh.svg new file mode 100644 index 000000000..7fb944327 --- /dev/null +++ b/tools/source_icons/scalable/warnsh.svg @@ -0,0 +1,427 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/wavelet.file b/tools/source_icons/scalable/wavelet.file new file mode 100644 index 000000000..1edeedbae --- /dev/null +++ b/tools/source_icons/scalable/wavelet.file @@ -0,0 +1 @@ +wavelet.png,w22,actions diff --git a/tools/source_icons/scalable/wavelet.svg b/tools/source_icons/scalable/wavelet.svg new file mode 100644 index 000000000..0e410b511 --- /dev/null +++ b/tools/source_icons/scalable/wavelet.svg @@ -0,0 +1,127 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/wb-auto.file b/tools/source_icons/scalable/wb-auto.file new file mode 100644 index 000000000..4fef61d4b --- /dev/null +++ b/tools/source_icons/scalable/wb-auto.file @@ -0,0 +1 @@ +wb-auto.png,w22,actions diff --git a/tools/source_icons/scalable/wb-auto.svg b/tools/source_icons/scalable/wb-auto.svg new file mode 100644 index 000000000..59b8799a2 --- /dev/null +++ b/tools/source_icons/scalable/wb-auto.svg @@ -0,0 +1,638 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/tools/source_icons/scalable/wb-camera.file b/tools/source_icons/scalable/wb-camera.file new file mode 100644 index 000000000..63d394942 --- /dev/null +++ b/tools/source_icons/scalable/wb-camera.file @@ -0,0 +1 @@ +wb-camera.png,w22,actions diff --git a/tools/source_icons/scalable/wb-camera.svg b/tools/source_icons/scalable/wb-camera.svg new file mode 100644 index 000000000..119b4a9a6 --- /dev/null +++ b/tools/source_icons/scalable/wb-camera.svg @@ -0,0 +1,650 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + diff --git a/tools/source_icons/scalable/wb-cloudy.file b/tools/source_icons/scalable/wb-cloudy.file new file mode 100644 index 000000000..30319caf0 --- /dev/null +++ b/tools/source_icons/scalable/wb-cloudy.file @@ -0,0 +1 @@ +wb-cloudy.png,w22,actions diff --git a/tools/source_icons/scalable/wb-cloudy.svg b/tools/source_icons/scalable/wb-cloudy.svg new file mode 100644 index 000000000..1929d5c93 --- /dev/null +++ b/tools/source_icons/scalable/wb-cloudy.svg @@ -0,0 +1,640 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/tools/source_icons/scalable/wb-custom.file b/tools/source_icons/scalable/wb-custom.file new file mode 100644 index 000000000..debc0f4b8 --- /dev/null +++ b/tools/source_icons/scalable/wb-custom.file @@ -0,0 +1 @@ +wb-custom.png,w22,actions diff --git a/tools/source_icons/scalable/wb-custom.svg b/tools/source_icons/scalable/wb-custom.svg new file mode 100644 index 000000000..c0334549f --- /dev/null +++ b/tools/source_icons/scalable/wb-custom.svg @@ -0,0 +1,655 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/wb-flash.file b/tools/source_icons/scalable/wb-flash.file new file mode 100644 index 000000000..c5872302d --- /dev/null +++ b/tools/source_icons/scalable/wb-flash.file @@ -0,0 +1 @@ +wb-flash.png,w22,actions diff --git a/tools/source_icons/scalable/wb-flash.svg b/tools/source_icons/scalable/wb-flash.svg new file mode 100644 index 000000000..b2ee41891 --- /dev/null +++ b/tools/source_icons/scalable/wb-flash.svg @@ -0,0 +1,639 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/tools/source_icons/scalable/wb-fluorescent.file b/tools/source_icons/scalable/wb-fluorescent.file new file mode 100644 index 000000000..7b8d464d4 --- /dev/null +++ b/tools/source_icons/scalable/wb-fluorescent.file @@ -0,0 +1 @@ +wb-fluorescent.png,w22,actions diff --git a/tools/source_icons/scalable/wb-fluorescent.svg b/tools/source_icons/scalable/wb-fluorescent.svg new file mode 100644 index 000000000..439fe43be --- /dev/null +++ b/tools/source_icons/scalable/wb-fluorescent.svg @@ -0,0 +1,697 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/wb-lamp.file b/tools/source_icons/scalable/wb-lamp.file new file mode 100644 index 000000000..4862cafb4 --- /dev/null +++ b/tools/source_icons/scalable/wb-lamp.file @@ -0,0 +1 @@ +wb-lamp.png,w22,actions diff --git a/tools/source_icons/scalable/wb-lamp.svg b/tools/source_icons/scalable/wb-lamp.svg new file mode 100644 index 000000000..bf1e45350 --- /dev/null +++ b/tools/source_icons/scalable/wb-lamp.svg @@ -0,0 +1,1330 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/wb-led.file b/tools/source_icons/scalable/wb-led.file new file mode 100644 index 000000000..5083da16d --- /dev/null +++ b/tools/source_icons/scalable/wb-led.file @@ -0,0 +1 @@ +wb-led.png,w22,actions diff --git a/tools/source_icons/scalable/wb-led.svg b/tools/source_icons/scalable/wb-led.svg new file mode 100644 index 000000000..a6048bf01 --- /dev/null +++ b/tools/source_icons/scalable/wb-led.svg @@ -0,0 +1,737 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/wb-shade.file b/tools/source_icons/scalable/wb-shade.file new file mode 100644 index 000000000..9068faeed --- /dev/null +++ b/tools/source_icons/scalable/wb-shade.file @@ -0,0 +1 @@ +wb-shade.png,w22,actions diff --git a/tools/source_icons/scalable/wb-shade.svg b/tools/source_icons/scalable/wb-shade.svg new file mode 100644 index 000000000..871321180 --- /dev/null +++ b/tools/source_icons/scalable/wb-shade.svg @@ -0,0 +1,694 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/wb-sun.file b/tools/source_icons/scalable/wb-sun.file new file mode 100644 index 000000000..e2906963c --- /dev/null +++ b/tools/source_icons/scalable/wb-sun.file @@ -0,0 +1 @@ +wb-sun.png,w22,actions diff --git a/tools/source_icons/scalable/wb-sun.svg b/tools/source_icons/scalable/wb-sun.svg new file mode 100644 index 000000000..222177600 --- /dev/null +++ b/tools/source_icons/scalable/wb-sun.svg @@ -0,0 +1,724 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/wb-tungsten.file b/tools/source_icons/scalable/wb-tungsten.file new file mode 100644 index 000000000..dc1989f4c --- /dev/null +++ b/tools/source_icons/scalable/wb-tungsten.file @@ -0,0 +1 @@ +wb-tungsten.png,w22,actions diff --git a/tools/source_icons/scalable/wb-tungsten.svg b/tools/source_icons/scalable/wb-tungsten.svg new file mode 100644 index 000000000..5d172c203 --- /dev/null +++ b/tools/source_icons/scalable/wb-tungsten.svg @@ -0,0 +1,697 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/scalable/wb-water.file b/tools/source_icons/scalable/wb-water.file new file mode 100644 index 000000000..14ce25494 --- /dev/null +++ b/tools/source_icons/scalable/wb-water.file @@ -0,0 +1 @@ +wb-water.png,w22,actions diff --git a/tools/source_icons/scalable/wb-water.svg b/tools/source_icons/scalable/wb-water.svg new file mode 100644 index 000000000..d3e2ecde7 --- /dev/null +++ b/tools/source_icons/scalable/wb-water.svg @@ -0,0 +1,642 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/tools/source_icons/scalable/zoom-100-identifier.file b/tools/source_icons/scalable/zoom-100-identifier.file new file mode 100644 index 000000000..b88690fb1 --- /dev/null +++ b/tools/source_icons/scalable/zoom-100-identifier.file @@ -0,0 +1 @@ +zoom-100-identifier.png,w12,actions diff --git a/tools/source_icons/scalable/zoom-100-identifier.svg b/tools/source_icons/scalable/zoom-100-identifier.svg new file mode 100644 index 000000000..d9b8112ff --- /dev/null +++ b/tools/source_icons/scalable/zoom-100-identifier.svg @@ -0,0 +1,665 @@ + + + + + gtk-zoom-100 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + gtk-zoom-100 + + http://www.rawtherapee.com/ + 2013-04-10 + + + DrSlony + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/source_icons/script/change_colour.bash b/tools/source_icons/script/change_colour.bash new file mode 100755 index 000000000..a3e63d22f --- /dev/null +++ b/tools/source_icons/script/change_colour.bash @@ -0,0 +1,52 @@ +#! /bin/bash + +### arg1 : this script takes as input a directory which +### contains the svg files for the icon set. +### arg2: it creates in the output directory the svg files +### for the desired colour +### arg3: the colour name (in hexadecimal) to be used for the icon +### arg4: the colour name (in hexadecimal) to be used for the gradient + +DIR_IN=$1 +DIR_OUT=$2 +COLOUR_BG=$3 + +OPACITY=0.85 + + +if [ $# -lt 3 ] +then + echo "Usage: $(basename $0) {input svg directory} {output svg directory} {colour name (hexadecimal)}" + exit 0 +fi + +if [ $# -eq 4 ] +then + COLOUR_GRADIENT=$4 +else + COLOUR_GRADIENT="#ffffff" +fi + +### ORIGINAL = #2a7fff +### PURPLE = #843382 +### GRAY 60% = #666666 +### DARK THEME = #D2D2D2 +### LIGHT THEME = #252525 + + +ORIGINAL="#2a7fff" ### it is the default colour which has been used to develop the gold standard icon set +for SVG in $(ls $DIR_IN/*.svg) +do +# sed -e "s/$ORIGINAL/$COLOUR_BG/g" $SVG > $DIR_OUT/$(basename $SVG) + + sed -e "s/style=\"opacity:0.69.*;fill:$ORIGINAL/style=\"opacity:$OPACITY;fill:$COLOUR_BG/g" -e "s/style=\"opacity:0.7*;fill:$ORIGINAL/style=\"opacity:$OPACITY;fill:$COLOUR_BG/g" -e "s/$ORIGINAL/$COLOUR_BG/g" -e "s/style=\"stop-color:\#ffffff;/style=\"stop-color:$COLOUR_GRADIENT;/g" $SVG > $DIR_OUT/$(basename $SVG) + + + FILE_NAME=${SVG%.svg} + FILE=$FILE_NAME.file + cp $FILE $DIR_OUT + +done + + +#cp $DIR_IN/index.theme $DIR_OUT diff --git a/tools/source_icons/script/make_all_icon_theme.bash b/tools/source_icons/script/make_all_icon_theme.bash new file mode 100755 index 000000000..4047bf7a9 --- /dev/null +++ b/tools/source_icons/script/make_all_icon_theme.bash @@ -0,0 +1,78 @@ +#! /bin/bash + +### arg1 : this script takes as input a directory which +### contains the svg files for the gold standard icon set. +### arg2: it creates in the output directory the png files + +### make_all_icon_theme.bash tools/icons_source/scalable /tmp/png + +DIR_IN=$1 +DIR_OUT=$2 + + +if [ $# -lt 2 ] +then + echo "Usage: $(basename $0) {input svg directory} {output directory}" + exit 0 +fi + + +if [ ! -d $DIR_OUT ] +then + mkdir $DIR_OUT +else + rm -r $DIR_OUT/* +fi + +if [ ! -d $DIR_OUT/Dark ] +then + mkdir $DIR_OUT/Dark +fi + +if [ ! -d $DIR_OUT/Light ] +then + mkdir $DIR_OUT/Light +fi + + +rm -r $DIR_OUT/Dark/* +rm -r $DIR_OUT/Light/* + +### make all icon with generic option +./make_icon_theme.bash $DIR_IN $DIR_OUT/Dark "#BBBBBB" "#FFFFFF" +./make_icon_theme.bash $DIR_IN $DIR_OUT/Light "#252525" "#7D7D7D" + +### make custom icon with specific option +if [ ! -d $DIR_OUT/Light/tmp ] +then + mkdir $DIR_OUT/Light/tmp +fi + +if [ ! -d $DIR_OUT/Dark/tmp ] +then + mkdir $DIR_OUT/Dark/tmp +fi + +cp $DIR_IN/closedhand.* $DIR_OUT/Dark/tmp +cp $DIR_IN/closedhand.* $DIR_OUT/Light/tmp + +./make_icon_theme.bash $DIR_OUT/Dark/tmp $DIR_OUT/Dark "#BBBBBB" "#000000" +./make_icon_theme.bash $DIR_OUT/Light/tmp $DIR_OUT/Light "#252525" "#FFFFFF" + +DIR_TMP=/tmp/icons + +if [ ! -d $DIR_TMP ] +then + mkdir $DIR_TMP +fi + +cp -r $DIR_OUT/* $DIR_TMP +mv $DIR_TMP/Dark/*.png $DIR_TMP/Dark/actions +mv $DIR_TMP/Light/*.png $DIR_TMP/Light/actions +/bin/rm -r $DIR_TMP/Dark/*.file $DIR_TMP/Dark/tmp +/bin/rm -r $DIR_TMP/Light/*.file $DIR_TMP/Light/tmp + +cd /tmp +tar cvf iconsets.tar icons +bzip2 iconsets.tar +mv iconsets.tar.bz2 $DIR_OUT diff --git a/tools/source_icons/script/make_icon_theme.bash b/tools/source_icons/script/make_icon_theme.bash new file mode 100755 index 000000000..f20f53af9 --- /dev/null +++ b/tools/source_icons/script/make_icon_theme.bash @@ -0,0 +1,39 @@ +#! /bin/bash + +### arg1 : this script takes as input a directory which +### contains the svg files for the gold standard icon set. +### arg2: it creates in the output directory the png files +### for the desired size +### arg3: the colour name (in hexadecimal) to be used + + +### Light Theme +### ./make_icon_theme.bash ../svg/ /tmp/png/ "#252525" "#7D7D7D" + +### Dark Theme +### ./make_icon_theme.bash ../svg/ /tmp/png/ "#D2D2D2" "#FFFFFF" + + +DIR_IN=$1 +DIR_OUT=$2 +COLOUR_BG=$3 +COLOUR_GRADIENT=$4 + +if [ $# -lt 3 ] +then + echo "Usage: $(basename $0) {input svg directory} {output directory} {background colour name (hexadecimal)} {option: gradient colour name (hexadecimal)}" + exit 0 +fi + + +if [ $# -eq 4 ] +then +./change_colour.bash $DIR_IN $DIR_OUT $COLOUR_BG $COLOUR_GRADIENT +else +./change_colour.bash $DIR_IN $DIR_OUT $COLOUR_BG +fi +./svg2png.bash $DIR_OUT $DIR_OUT $WIDTH +rm $DIR_OUT/*.svg + + + diff --git a/tools/source_icons/script/svg2png.bash b/tools/source_icons/script/svg2png.bash new file mode 100755 index 000000000..2e9c4bb5a --- /dev/null +++ b/tools/source_icons/script/svg2png.bash @@ -0,0 +1,64 @@ +#! /bin/bash + +### arg1 : this script takes as input a directory which +### contains the svg files for the gold standard icon set. +### arg2: it creates in the output directory the png files +### for the desired size + + +DIR_IN=$1 +DIR_OUT=$2 + +DIR_TMP=/tmp + +if [ $# -ne 2 ] +then + echo "Usage: $(basename $0) {input svg directory} {output directory} {width (in pixel)}" + exit 0 +fi + +if [ ! -d $DIR_OUT/actions ] +then + mkdir $DIR_OUT/actions +fi + +if [ ! -d $DIR_OUT/devices ] +then + mkdir $DIR_OUT/devices +fi + +if [ ! -d $DIR_OUT/places ] +then + mkdir $DIR_OUT/places +fi + + + +for SVG in $(ls $DIR_IN/*.svg) +do + echo $SVG + + FILE=$(basename $SVG) + FILE_NAME=${FILE%.svg} + FILE=$FILE_NAME.file + + if [ -f $DIR_TMP/$FILE_NAME.bash ] + then + rm $DIR_TMP/$FILE_NAME.bash + fi + + echo "#! /bin/bash" > $DIR_TMP/$FILE_NAME.bash + if [[ $OSTYPE == msys || $OSTYPE == MSYS ]]; then + awk -v s="$SVG" -v d="$DIR_OUT" -F, '{print "\"/c/Program Files (x86)/Inkscape/inkscape.exe\" " s " --export-png=" d "/" $1 " -" $2}' $DIR_IN/$FILE >> $DIR_TMP/$FILE_NAME.bash + else + awk -v s="$SVG" -v d="$DIR_OUT" -F, '{print "inkscape " s " --export-png=" d "/" $1 " -" $2}' $DIR_IN/$FILE >> $DIR_TMP/$FILE_NAME.bash + fi + + awk -v s="$SVG" -v d="$DIR_OUT" -F, '{print "mv " d "/" $1 " " d "/" $3}' $DIR_IN/$FILE >> $DIR_TMP/$FILE_NAME.bash + + chmod +x $DIR_TMP/$FILE_NAME.bash + $DIR_TMP/$FILE_NAME.bash + + rm $DIR_TMP/$FILE_NAME.bash + +done diff --git a/win.cmake b/win.cmake new file mode 100644 index 000000000..b4bbc66a2 --- /dev/null +++ b/win.cmake @@ -0,0 +1,53 @@ +# Use the 'Debug' build type to have a non optimized, with debugging information, with a console executable +# Use the 'Release' build type to have an optimized, without debugging information, console free executable +# Use the 'RelWithDebInfo' build type to have an optimized, without debugging information, with a console executable +# Use the 'MinSizeRel' build type to have the smallest possible, without debugging information, console free executable +#set(CMAKE_BUILD_TYPE Release CACHE STRING "Between: None Debug Release RelWithDebInfo MinSizeRel.") + +set(CMAKE_INSTALL_PREFIX ./Builds/${CMAKE_BUILD_TYPE} CACHE PATH "Libraries installation path") +set(DATADIR . CACHE PATH "Datas installation path") +set(BINDIR . CACHE PATH "Binaries installation path") +set(LIBDIR . CACHE PATH "Libraries installation path") +set(DOCDIR ./doc CACHE PATH "Documentation installation path") +set(CREDITSDIR . CACHE PATH "Credit file installation path") +set(LICENCEDIR . CACHE PATH "Licence file installation path") + +set(BUILD_SHARED OFF CACHE BOOL "Should RT generate shared libraries") +set(OPTION_OMP ON CACHE BOOL "Use OpenMP to speedup the preview and batch processing") +# set WITH_MYFILE_MMAP to OFF if you experience crash with thumbnail creation (it should be slower, but more reliable) +set(WITH_MYFILE_MMAP ON CACHE BOOL "Use the MMAP mechanism to speedup thumbnail creations") + +set(CACHE_NAME_SUFFIX "" CACHE STRING "RawTherapee's cache folder suffix (leave empty to use the default suffix, i.e. latesttag)") + +# This line will let you chose the target number, and the associated processor +set(PROC_TARGET_NUMBER 0 CACHE STRING "Target Processor") + +# To add a version suffix (text) after the standard version number, e.g. for patched builds +set(VERSION_SUFFIX "" CACHE STRING "For patched builds, use this string to add a version suffix (text); KEEP EMPTY FOR RELEASE BULDS") + +# If you want to force the target processor name when PROC_TARGET_NUMBER = 0 or 2, +# uncomment the next line and replace labelWithoutQuotes by its value +#set (PROC_LABEL labelWithoutQuotes CACHE STRING "Target Processor label") + +# Important: MinGW-w64 user may need to specify the -m32 or -m64 flag in CMAKE_CXX_FLAGS, +# CMAKE_C_FLAGS and CMAKE_EXE_LINKER_FLAGS to select between 32/64bit build +set(CMAKE_CXX_FLAGS "-mwin32 -mthreads" CACHE STRING "Compiler options for C++ source files") +set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g2" CACHE STRING "Compiler options for C++ source files and Debug target") +set(CMAKE_CXX_FLAGS_RELEASE "-mwindows -DNDEBUG -O2" CACHE STRING "Compiler options for C++ source files and Release target") +set(CMAKE_CXX_FLAGS_MINSIZEREL "-mwindows -DNDEBUG -Os" CACHE STRING "Compiler options for C++ source files and MinSizeRel target") +set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g" CACHE STRING "Compiler options for C++ source files and RelWithDebInfo target") + +# Uncomment the next line and set the right value to override the default value (special compiling flags for RTEngine) +#set(RTENGINE_CXX_FLAGS "-funroll-loops" CACHE STRING "Special compilation flags for RTEngine") + +set(CMAKE_C_FLAGS "-mwin32 -mthreads" CACHE STRING "Compiler options for C source files") +set(CMAKE_C_FLAGS_DEBUG "-O0 -g2" CACHE STRING "Compiler options for C source files and Debug target") +set(CMAKE_C_FLAGS_RELEASE "-mwindows -DNDEBUG -O2" CACHE STRING "Compiler options for C source files and Release target") +set(CMAKE_C_FLAGS_MINSIZEREL "-mwindows -DNDEBUG -Os" CACHE STRING "Compiler options for C source files and MinSizeRel target") +set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -g" CACHE STRING "Compiler options for C source files and RelWithDebInfo target") + +set(CMAKE_EXE_LINKER_FLAGS "-mwin32 -mthreads -static-libgcc -Wl,--large-address-aware,--verbose" CACHE STRING "Linker options") +set(CMAKE_EXE_LINKER_FLAGS_DEBUG "-O0" CACHE STRING "Linkage options for the Debug target") +set(CMAKE_EXE_LINKER_FLAGS_RELEASE "-mwindows -s -O2" CACHE STRING "Linkage options for the Release target") +set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "-mwindows -s -Os" CACHE STRING "Linkage options for the MinSizeRel target") +set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "-s -O2" CACHE STRING "Linkage options for the RelWithDebInfo target")